From f424b0ac943176327d154b2c0d86efa699570cd5 Mon Sep 17 00:00:00 2001 From: Davide Garberi Date: Thu, 22 Aug 2019 02:27:05 +0200 Subject: [PATCH 001/226] drivers: platform: Add support for Xiaomi SM8150 platform Change-Id: I3bbfd60dfa0dea0abf080d35fd3d6d14dec6e094 Signed-off-by: firebird11 --- drivers/platform/Kconfig | 2 ++ drivers/platform/xiaomi/Kconfig | 54 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 drivers/platform/xiaomi/Kconfig diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig index e29f6c2ad1b7..ad9aeefe95fd 100644 --- a/drivers/platform/Kconfig +++ b/drivers/platform/Kconfig @@ -10,3 +10,5 @@ source "drivers/platform/goldfish/Kconfig" source "drivers/platform/chrome/Kconfig" source "drivers/platform/msm/Kconfig" + +source "drivers/platform/xiaomi/Kconfig" diff --git a/drivers/platform/xiaomi/Kconfig b/drivers/platform/xiaomi/Kconfig new file mode 100644 index 000000000000..5ff3df1d020a --- /dev/null +++ b/drivers/platform/xiaomi/Kconfig @@ -0,0 +1,54 @@ +# Xiaomi configuration options + +config MACH_XIAOMI + bool "Xiaomi device" + depends on ARCH_QCOM + help + Support for Xiaomi products + +config MACH_XIAOMI_SM8150 + bool "Xiaomi SM8150" + depends on ARCH_QCOM + select MACH_XIAOMI + help + Support for Xiaomi SM8150 devices + +menu "Xiaomi board selection" + +config MACH_XIAOMI_ANDROMEDA + bool "Xiaomi andromeda board" + select MACH_XIAOMI_SM8150 + help + Support for Mi MIX 3 5G + +config MACH_XIAOMI_CEPHEUS + bool "Xiaomi cepheus board" + select MACH_XIAOMI_SM8150 + help + Support for Mi 9 + +config MACH_XIAOMI_CRUX + bool "Xiaomi crux board" + select MACH_XIAOMI_SM8150 + help + Support for Mi 9 Pro 5G + +config MACH_XIAOMI_NABU + bool "Xiaomi nabu board" + select MACH_XIAOMI_SM8150 + help + Support for Xiaomi Pad 5 + +config MACH_XIAOMI_RAPHAEL + bool "Xiaomi raphael board" + select MACH_XIAOMI_SM8150 + help + Support for Redmi K20 Pro/Mi 9T Pro + +config MACH_XIAOMI_VAYU + bool "Xiaomi vayu board" + select MACH_XIAOMI_SM8150 + help + Support for POCO X3 Pro + +endmenu From f33e2eb1674dd4b52db7089333f6ae6c7a4c4d21 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 02:13:59 +0200 Subject: [PATCH 002/226] arch: arm64: configs: xiaomi: Initial config fragments Change-Id: I8a757f09beede0238c7ac53627382a4c81d54509 Signed-off-by: firebird11 --- arch/arm64/configs/vendor/xiaomi/andromeda.config | 0 arch/arm64/configs/vendor/xiaomi/cepheus.config | 0 arch/arm64/configs/vendor/xiaomi/crux.config | 0 arch/arm64/configs/vendor/xiaomi/nabu.config | 0 arch/arm64/configs/vendor/xiaomi/raphael.config | 0 arch/arm64/configs/vendor/xiaomi/sm8150-common.config | 0 arch/arm64/configs/vendor/xiaomi/vayu.config | 0 7 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 arch/arm64/configs/vendor/xiaomi/andromeda.config create mode 100644 arch/arm64/configs/vendor/xiaomi/cepheus.config create mode 100644 arch/arm64/configs/vendor/xiaomi/crux.config create mode 100644 arch/arm64/configs/vendor/xiaomi/nabu.config create mode 100644 arch/arm64/configs/vendor/xiaomi/raphael.config create mode 100644 arch/arm64/configs/vendor/xiaomi/sm8150-common.config create mode 100644 arch/arm64/configs/vendor/xiaomi/vayu.config diff --git a/arch/arm64/configs/vendor/xiaomi/andromeda.config b/arch/arm64/configs/vendor/xiaomi/andromeda.config new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/arch/arm64/configs/vendor/xiaomi/cepheus.config b/arch/arm64/configs/vendor/xiaomi/cepheus.config new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/arch/arm64/configs/vendor/xiaomi/crux.config b/arch/arm64/configs/vendor/xiaomi/crux.config new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/arch/arm64/configs/vendor/xiaomi/nabu.config b/arch/arm64/configs/vendor/xiaomi/nabu.config new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/arch/arm64/configs/vendor/xiaomi/raphael.config b/arch/arm64/configs/vendor/xiaomi/raphael.config new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/arch/arm64/configs/vendor/xiaomi/sm8150-common.config b/arch/arm64/configs/vendor/xiaomi/sm8150-common.config new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/arch/arm64/configs/vendor/xiaomi/vayu.config b/arch/arm64/configs/vendor/xiaomi/vayu.config new file mode 100644 index 000000000000..e69de29bb2d1 From f78f55fb209e2fe7292ce9303cd2d0fd9b27fab3 Mon Sep 17 00:00:00 2001 From: Davide Garberi Date: Sat, 29 Feb 2020 11:15:26 +0100 Subject: [PATCH 003/226] arch: arm64: configs: xiaomi: Enable CONFIG_BUILD_ARM64_DT_OVERLAY Change-Id: I25959ef7eec025a5506cb6de863c09555a1dd4ce Signed-off-by: firebird11 --- arch/arm64/configs/vendor/xiaomi/sm8150-common.config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/vendor/xiaomi/sm8150-common.config b/arch/arm64/configs/vendor/xiaomi/sm8150-common.config index e69de29bb2d1..420bd53feb26 100644 --- a/arch/arm64/configs/vendor/xiaomi/sm8150-common.config +++ b/arch/arm64/configs/vendor/xiaomi/sm8150-common.config @@ -0,0 +1,2 @@ +# DTBO +CONFIG_BUILD_ARM64_DT_OVERLAY=y From 06fdd6356748b63f4fd162390970baefa2a1502b Mon Sep 17 00:00:00 2001 From: Luca Stefani Date: Sat, 1 Aug 2020 08:52:53 +0200 Subject: [PATCH 004/226] arch: arm64: configs: xiaomi: Enable QCACLD Change-Id: I22b3d3adf31c95a91275d0c795403b4097201430 Signed-off-by: firebird11 --- arch/arm64/configs/vendor/xiaomi/sm8150-common.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/vendor/xiaomi/sm8150-common.config b/arch/arm64/configs/vendor/xiaomi/sm8150-common.config index 420bd53feb26..53dd505736a2 100644 --- a/arch/arm64/configs/vendor/xiaomi/sm8150-common.config +++ b/arch/arm64/configs/vendor/xiaomi/sm8150-common.config @@ -1,2 +1,5 @@ # DTBO CONFIG_BUILD_ARM64_DT_OVERLAY=y + +# QCACLD +CONFIG_QCA_CLD_WLAN=y From 4e6baa35700aa7647a2a3649bf3dd29f08b8dc2f Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 02:18:19 +0200 Subject: [PATCH 005/226] arch: arm64: configs: xiaomi: Enable exFAT Change-Id: Ib7eb7141986625b0d01f989ae00493ddc3c4a9b8 Signed-off-by: firebird11 --- arch/arm64/configs/vendor/xiaomi/sm8150-common.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/vendor/xiaomi/sm8150-common.config b/arch/arm64/configs/vendor/xiaomi/sm8150-common.config index 53dd505736a2..06a15cb7c89e 100644 --- a/arch/arm64/configs/vendor/xiaomi/sm8150-common.config +++ b/arch/arm64/configs/vendor/xiaomi/sm8150-common.config @@ -3,3 +3,6 @@ CONFIG_BUILD_ARM64_DT_OVERLAY=y # QCACLD CONFIG_QCA_CLD_WLAN=y + +# exFAT +CONFIG_EXFAT_FS=y From fa961314ddaaac6dd88f2e5c46a1ce2047a1574c Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Thu, 25 Apr 2024 00:50:18 +0200 Subject: [PATCH 006/226] arch: arm64: configs: xiaomi: Enable EROFS Change-Id: If2d1802f013ea3a549868b2f280d4f4b63ed49f2 Signed-off-by: firebird11 --- arch/arm64/configs/vendor/xiaomi/sm8150-common.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/vendor/xiaomi/sm8150-common.config b/arch/arm64/configs/vendor/xiaomi/sm8150-common.config index 06a15cb7c89e..78436de13ed3 100644 --- a/arch/arm64/configs/vendor/xiaomi/sm8150-common.config +++ b/arch/arm64/configs/vendor/xiaomi/sm8150-common.config @@ -6,3 +6,6 @@ CONFIG_QCA_CLD_WLAN=y # exFAT CONFIG_EXFAT_FS=y + +# EROFS +CONFIG_EROFS_FS=y From 04fd3b5018729dab7aedd4d6fc8efab93cc065ad Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 6 Nov 2023 00:56:55 +0100 Subject: [PATCH 007/226] arch: arm64: configs: xiaomi: Enable device-specific platform Change-Id: Iadb079c5f1d654226276dd1d316e324968fa1e92 Signed-off-by: firebird11 --- arch/arm64/configs/vendor/xiaomi/andromeda.config | 2 ++ arch/arm64/configs/vendor/xiaomi/cepheus.config | 2 ++ arch/arm64/configs/vendor/xiaomi/crux.config | 2 ++ arch/arm64/configs/vendor/xiaomi/nabu.config | 2 ++ arch/arm64/configs/vendor/xiaomi/raphael.config | 2 ++ arch/arm64/configs/vendor/xiaomi/vayu.config | 2 ++ 6 files changed, 12 insertions(+) diff --git a/arch/arm64/configs/vendor/xiaomi/andromeda.config b/arch/arm64/configs/vendor/xiaomi/andromeda.config index e69de29bb2d1..6981d04735d1 100644 --- a/arch/arm64/configs/vendor/xiaomi/andromeda.config +++ b/arch/arm64/configs/vendor/xiaomi/andromeda.config @@ -0,0 +1,2 @@ +# Platform +CONFIG_MACH_XIAOMI_ANDROMEDA=y diff --git a/arch/arm64/configs/vendor/xiaomi/cepheus.config b/arch/arm64/configs/vendor/xiaomi/cepheus.config index e69de29bb2d1..b237760c457f 100644 --- a/arch/arm64/configs/vendor/xiaomi/cepheus.config +++ b/arch/arm64/configs/vendor/xiaomi/cepheus.config @@ -0,0 +1,2 @@ +# Platform +CONFIG_MACH_XIAOMI_CEPHEUS=y diff --git a/arch/arm64/configs/vendor/xiaomi/crux.config b/arch/arm64/configs/vendor/xiaomi/crux.config index e69de29bb2d1..0611ff82cdd4 100644 --- a/arch/arm64/configs/vendor/xiaomi/crux.config +++ b/arch/arm64/configs/vendor/xiaomi/crux.config @@ -0,0 +1,2 @@ +# Platform +CONFIG_MACH_XIAOMI_CRUX=y diff --git a/arch/arm64/configs/vendor/xiaomi/nabu.config b/arch/arm64/configs/vendor/xiaomi/nabu.config index e69de29bb2d1..39bd6a435189 100644 --- a/arch/arm64/configs/vendor/xiaomi/nabu.config +++ b/arch/arm64/configs/vendor/xiaomi/nabu.config @@ -0,0 +1,2 @@ +# Platform +CONFIG_MACH_XIAOMI_NABU=y diff --git a/arch/arm64/configs/vendor/xiaomi/raphael.config b/arch/arm64/configs/vendor/xiaomi/raphael.config index e69de29bb2d1..89de85dcf84d 100644 --- a/arch/arm64/configs/vendor/xiaomi/raphael.config +++ b/arch/arm64/configs/vendor/xiaomi/raphael.config @@ -0,0 +1,2 @@ +# Platform +CONFIG_MACH_XIAOMI_RAPHAEL=y diff --git a/arch/arm64/configs/vendor/xiaomi/vayu.config b/arch/arm64/configs/vendor/xiaomi/vayu.config index e69de29bb2d1..96c16e9b2cf6 100644 --- a/arch/arm64/configs/vendor/xiaomi/vayu.config +++ b/arch/arm64/configs/vendor/xiaomi/vayu.config @@ -0,0 +1,2 @@ +# Platform +CONFIG_MACH_XIAOMI_VAYU=y From 0d7aae768df3a5a07ab7c610d81086d77a6ea27d Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 4 Jul 2022 17:15:29 +0200 Subject: [PATCH 008/226] arch: arm64: boot: dts: qcom: Import overlayed dts * From cepheus-q-oss + vayu-r-oss + nabu-r-oss Change-Id: I6774472882f5d402718724ae6c78b3605fd293c0 Signed-off-by: firebird11 --- arch/arm64/boot/dts/qcom/Makefile | 39 + .../dts/qcom/andromeda-sm8150-overlay.dts | 34 + .../dts/qcom/andromeda-sm8150-p1-overlay.dts | 36 + .../qcom/andromeda-sm8150-p1_1-overlay.dts | 36 + .../dts/qcom/andromeda-sm8150-p2-overlay.dts | 36 + .../qcom/andromeda-sm8150-p2_1-overlay.dts | 36 + .../qcom/andromeda-sm8150-p2_2-overlay.dts | 36 + .../qcom/andromeda-sm8150-p2_21-overlay.dts | 36 + .../qcom/andromeda-sm8150-p2_22-overlay.dts | 36 + .../boot/dts/qcom/cepheus-sm8150-overlay.dts | 29 + .../boot/dts/qcom/crux-sm8150-overlay.dts | 33 + .../boot/dts/qcom/nabu-sm8150-overlay.dts | 29 + arch/arm64/boot/dts/qcom/pm8150l.dtsi | 12 +- .../boot/dts/qcom/raphael-sm8150-overlay.dts | 29 + .../boot/dts/qcom/sm8150-sde-display.dtsi | 2 +- arch/arm64/boot/dts/qcom/sm8150-v2-xiaomi.dts | 23 + arch/arm64/boot/dts/qcom/sm8150-xiaomi.dts | 23 + .../arm64/boot/dts/qcom/sm8150p-v2-xiaomi.dts | 23 + arch/arm64/boot/dts/qcom/sm8150p-xiaomi.dts | 23 + .../boot/dts/qcom/vayu-sm8150-overlay.dts | 29 + .../dts/qcom/xiaomi/base/sm8150-audio.dtsi | 13 + .../dts/qcom/xiaomi/base/sm8150-camera.dtsi | 23 + .../dts/qcom/xiaomi/base/sm8150-pcie.dtsi | 5 + .../dts/qcom/xiaomi/base/sm8150-pinctrl.dtsi | 148 ++ .../qcom/xiaomi/base/sm8150-regulator.dtsi | 5 + .../boot/dts/qcom/xiaomi/base/sm8150.dtsi | 87 + .../boot/dts/qcom/xiaomi/base/trusty.dtsi | 28 + .../andromeda/andromeda-audio-overlay.dtsi | 76 + .../andromeda/andromeda-pinctrl-p1.dtsi | 125 ++ .../andromeda/andromeda-pinctrl-p1_1.dtsi | 2 + .../andromeda/andromeda-pinctrl-p2.dtsi | 2 + .../andromeda/andromeda-pinctrl-p2_1.dtsi | 2 + .../andromeda/andromeda-pinctrl-p2_2.dtsi | 2 + .../andromeda/andromeda-pinctrl-p2_21.dtsi | 2 + .../andromeda/andromeda-pinctrl-p2_22.dtsi | 2 + .../overlay/andromeda/andromeda-pinctrl.dtsi | 534 +++++ .../andromeda-sm8150-camera-sensor.dtsi | 494 ++++ .../andromeda/andromeda-sm8150-p1.dtsi | 39 + .../andromeda/andromeda-sm8150-p1_1.dtsi | 9 + .../andromeda/andromeda-sm8150-p2.dtsi | 6 + .../andromeda/andromeda-sm8150-p2_1.dtsi | 6 + .../andromeda/andromeda-sm8150-p2_2.dtsi | 6 + .../andromeda/andromeda-sm8150-p2_21.dtsi | 6 + .../andromeda/andromeda-sm8150-p2_22.dtsi | 6 + .../overlay/andromeda/andromeda-sm8150.dtsi | 659 ++++++ .../cepheus/cepheus-audio-overlay.dtsi | 76 + .../overlay/cepheus/cepheus-pinctrl.dtsi | 539 +++++ .../cepheus-sm8150-camera-sensor-mtp.dtsi | 532 +++++ .../overlay/cepheus/cepheus-sm8150.dtsi | 697 ++++++ .../batterydata-E5G-coslight-3700mah.dtsi | 136 ++ .../battery/batterydata-F1-atl-3300mah.dtsi | 156 ++ .../batterydata-F1-coslight-3300mah.dtsi | 156 ++ .../battery/batterydata-F11-gyu-4000mah.dtsi | 159 ++ .../battery/batterydata-F11-sun-4000mah.dtsi | 159 ++ .../fg-gen4-batterydata-alium-3600mah.dtsi | 160 ++ ...fg-gen4-batterydata-alium-3600mah_E5G.dtsi | 158 ++ ...gen4-batterydata-nabu-sunwoda-8720mah.dtsi | 153 ++ .../fg-gen4-batterydata-vayu-NVT-5160mah.dtsi | 153 ++ ...gen4-batterydata-vayu-sunwoda-5160mah.dtsi | 153 ++ .../dsi-panel-j20s-36-02-0a-lcd-dsc-vid.dtsi | 334 +++ .../dsi-panel-j20s-42-02-0b-lcd-dsc-vid.dtsi | 318 +++ .../display/dsi-panel-k82-36-02-0b-video.dtsi | 367 +++ .../display/dsi-panel-k82-42-02-0a-video.dtsi | 381 ++++ .../dsi-panel-samsung-fhd-ea8076-cmd.dtsi | 253 +++ .../dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi | 254 +++ ...dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi | 254 +++ ...i-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi | 254 +++ ...dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi | 254 +++ .../dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi | 277 +++ .../display/dsi-panel-ss-fhd-ea8076-cmd.dtsi | 242 ++ .../dsi-panel-ss-fhd-ea8076-global-cmd.dtsi | 242 ++ .../dsi-panel-ss-notch-fhd-ea8074-cmd.dtsi | 163 ++ .../dsi-panel-tianma-fhd-nt36672a-video.dtsi | 387 ++++ ...dsi-panel-visionox-fhd-r66456-f11-cmd.dtsi | 167 ++ .../qcom/xiaomi/overlay/common/pm8150.dtsi | 35 + .../qcom/xiaomi/overlay/common/pm8150b.dtsi | 33 + .../qcom/xiaomi/overlay/common/pm8150l.dtsi | 59 + .../overlay/common/sm8150-audio-overlay.dtsi | 57 + .../overlay/common/sm8150-pmic-overlay.dtsi | 28 + .../overlay/common/sm8150-sde-display.dtsi | 532 +++++ .../qcom/xiaomi/overlay/common/smb1390.dtsi | 15 + .../common/xiaomi-sdx50-sm8150-common.dtsi | 407 ++++ .../overlay/common/xiaomi-sm8150-common.dtsi | 527 +++++ .../overlay/crux/crux-audio-overlay.dtsi | 74 + .../xiaomi/overlay/crux/crux-pinctrl.dtsi | 796 +++++++ .../crux/crux-sm8150-camera-sensor-mtp.dtsi | 537 +++++ .../qcom/xiaomi/overlay/crux/crux-sm8150.dtsi | 1004 +++++++++ .../overlay/nabu/nabu-audio-overlay.dtsi | 51 + .../xiaomi/overlay/nabu/nabu-pinctrl.dtsi | 904 ++++++++ .../nabu/nabu-sm8150-camera-sensor-mtp.dtsi | 244 ++ .../qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi | 1275 +++++++++++ .../raphael/raphael-audio-overlay.dtsi | 39 + .../overlay/raphael/raphael-pinctrl.dtsi | 608 +++++ .../raphael/raphael-sm8150-camera-sensor.dtsi | 483 ++++ .../overlay/raphael/raphael-sm8150.dtsi | 736 ++++++ .../overlay/vayu/vayu-audio-overlay.dtsi | 48 + .../xiaomi/overlay/vayu/vayu-pinctrl.dtsi | 617 +++++ .../vayu/vayu-sm8150-camera-sensor-mtp.dtsi | 507 +++++ .../qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi | 1979 +++++++++++++++++ include/uapi/linux/input-event-codes.h | 6 + 100 files changed, 21995 insertions(+), 7 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/andromeda-sm8150-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/andromeda-sm8150-p1-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/andromeda-sm8150-p1_1-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/andromeda-sm8150-p2-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_1-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_2-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_21-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_22-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/cepheus-sm8150-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/crux-sm8150-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/nabu-sm8150-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/raphael-sm8150-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/sm8150-v2-xiaomi.dts create mode 100644 arch/arm64/boot/dts/qcom/sm8150-xiaomi.dts create mode 100644 arch/arm64/boot/dts/qcom/sm8150p-v2-xiaomi.dts create mode 100644 arch/arm64/boot/dts/qcom/sm8150p-xiaomi.dts create mode 100644 arch/arm64/boot/dts/qcom/vayu-sm8150-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-audio.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-camera.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-pcie.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-pinctrl.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-regulator.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/base/sm8150.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/base/trusty.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p1.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p1_1.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_1.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_2.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_21.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_22.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-camera-sensor.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p1.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p1_1.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_1.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_2.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_21.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_22.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-audio-overlay.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-pinctrl.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-sm8150-camera-sensor-mtp.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-sm8150.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-E5G-coslight-3700mah.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F1-atl-3300mah.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F1-coslight-3300mah.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F11-gyu-4000mah.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F11-sun-4000mah.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-alium-3600mah.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-alium-3600mah_E5G.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-nabu-sunwoda-8720mah.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-vayu-NVT-5160mah.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-vayu-sunwoda-5160mah.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-j20s-36-02-0a-lcd-dsc-vid.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-j20s-42-02-0b-lcd-dsc-vid.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-36-02-0b-video.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-42-02-0a-video.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-cmd.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-notch-fhd-ea8074-cmd.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-tianma-fhd-nt36672a-video.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-visionox-fhd-r66456-f11-cmd.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/pm8150.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/pm8150b.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/pm8150l.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/sm8150-audio-overlay.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/sm8150-pmic-overlay.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/sm8150-sde-display.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/smb1390.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/xiaomi-sdx50-sm8150-common.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/xiaomi-sm8150-common.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-audio-overlay.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-pinctrl.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-sm8150-camera-sensor-mtp.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-sm8150.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-audio-overlay.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-pinctrl.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150-camera-sensor-mtp.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-audio-overlay.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-pinctrl.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-sm8150-camera-sensor.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-sm8150.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-audio-overlay.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-pinctrl.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150-camera-sensor-mtp.dtsi create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 4d75cff64e43..af8661d62c1f 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -1,4 +1,41 @@ # SPDX-License-Identifier: GPL-2.0 +ifeq ($(CONFIG_MACH_XIAOMI),y) + +ifeq ($(CONFIG_MACH_XIAOMI_SM8150),y) +ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y) + dtbo-$(CONFIG_ARCH_SM8150) += \ + andromeda-sm8150-overlay.dtbo \ + andromeda-sm8150-p1-overlay.dtbo \ + andromeda-sm8150-p1_1-overlay.dtbo \ + andromeda-sm8150-p2-overlay.dtbo \ + andromeda-sm8150-p2_1-overlay.dtbo \ + andromeda-sm8150-p2_2-overlay.dtbo \ + andromeda-sm8150-p2_21-overlay.dtbo \ + andromeda-sm8150-p2_22-overlay.dtbo \ + cepheus-sm8150-overlay.dtbo \ + crux-sm8150-overlay.dtbo \ + nabu-sm8150-overlay.dtbo \ + raphael-sm8150-overlay.dtbo \ + vayu-sm8150-overlay.dtbo + +andromeda-sm8150-overlay.dtbo-base := sm8150-xiaomi.dtb sm8150-v2-xiaomi.dtb sm8150p-xiaomi.dtb sm8150p-v2-xiaomi.dtb +andromeda-sm8150-p1-overlay.dtbo-base := sm8150-xiaomi.dtb sm8150-v2-xiaomi.dtb sm8150p-xiaomi.dtb sm8150p-v2-xiaomi.dtb +andromeda-sm8150-p1_1-overlay.dtbo-base := sm8150-xiaomi.dtb sm8150-v2-xiaomi.dtb sm8150p-xiaomi.dtb sm8150p-v2-xiaomi.dtb +andromeda-sm8150-p2-overlay.dtbo-base := sm8150-xiaomi.dtb sm8150-v2-xiaomi.dtb sm8150p-xiaomi.dtb sm8150p-v2-xiaomi.dtb +andromeda-sm8150-p2_1-overlay.dtbo-base := sm8150-xiaomi.dtb sm8150-v2-xiaomi.dtb sm8150p-xiaomi.dtb sm8150p-v2-xiaomi.dtb +andromeda-sm8150-p2_2-overlay.dtbo-base := sm8150-xiaomi.dtb sm8150-v2-xiaomi.dtb sm8150p-xiaomi.dtb sm8150p-v2-xiaomi.dtb +andromeda-sm8150-p2_21-overlay.dtbo-base := sm8150-xiaomi.dtb sm8150-v2-xiaomi.dtb sm8150p-xiaomi.dtb sm8150p-v2-xiaomi.dtb +andromeda-sm8150-p2_22-overlay.dtbo-base := sm8150-xiaomi.dtb sm8150-v2-xiaomi.dtb sm8150p-xiaomi.dtb sm8150p-v2-xiaomi.dtb +cepheus-sm8150-overlay.dtbo-base := sm8150-xiaomi.dtb sm8150-v2-xiaomi.dtb sm8150p-xiaomi.dtb sm8150p-v2-xiaomi.dtb +crux-sm8150-overlay.dtbo-base := sm8150-xiaomi.dtb sm8150-v2-xiaomi.dtb sm8150p-xiaomi.dtb sm8150p-v2-xiaomi.dtb +nabu-sm8150-overlay.dtbo-base := sm8150-xiaomi.dtb sm8150-v2-xiaomi.dtb sm8150p-xiaomi.dtb sm8150p-v2-xiaomi.dtb +raphael-sm8150-overlay.dtbo-base := sm8150-xiaomi.dtb sm8150-v2-xiaomi.dtb sm8150p-xiaomi.dtb sm8150p-v2-xiaomi.dtb +vayu-sm8150-overlay.dtbo-base := sm8150-xiaomi.dtb sm8150-v2-xiaomi.dtb sm8150p-xiaomi.dtb sm8150p-v2-xiaomi.dtb +endif # CONFIG_BUILD_ARM64_DT_OVERLAY +endif # CONFIG_MACH_XIAOMI_SM8150 + +else # CONFIG_MACH_XIAOMI + ifeq ($(TARGET_BOARD_TYPE),auto) ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y) dtbo-$(CONFIG_ARCH_SM8150) += \ @@ -588,6 +625,8 @@ endif endif +endif # CONFIG_MACH_XIAOMI + ifeq ($(CONFIG_ARM64),y) always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/qcom/andromeda-sm8150-overlay.dts b/arch/arm64/boot/dts/qcom/andromeda-sm8150-overlay.dts new file mode 100644 index 000000000000..3ad6b24cf95d --- /dev/null +++ b/arch/arm64/boot/dts/qcom/andromeda-sm8150-overlay.dts @@ -0,0 +1,34 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +#include "xiaomi/overlay/andromeda/andromeda-sm8150.dtsi" +#include "xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi" + +#include "sdx5xm-external-soc.dtsi" +#include "sm8150-sdx50m.dtsi" + +/ { + model = "SDX50M ANDROMEDA"; + compatible = "qcom,sm8150-mtp", "qcom,sm8150", "qcom,mtp"; + qcom,board-id = <0x27 0x1>; + +}; + diff --git a/arch/arm64/boot/dts/qcom/andromeda-sm8150-p1-overlay.dts b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p1-overlay.dts new file mode 100644 index 000000000000..4babe5db12c5 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p1-overlay.dts @@ -0,0 +1,36 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +#include "xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi" + +#include "xiaomi/overlay/andromeda/andromeda-sm8150-p1.dtsi" +#include "xiaomi/overlay/andromeda/andromeda-pinctrl-p1.dtsi" + +#include "sdx5xm-external-soc.dtsi" +#include "sm8150-sdx50m.dtsi" + +/ { + model = "SDX50M ANDROMEDA"; + compatible = "qcom,sm8150-mtp", "qcom,sm8150", "qcom,mtp"; + qcom,board-id = <0x28 0x1>; + +}; + diff --git a/arch/arm64/boot/dts/qcom/andromeda-sm8150-p1_1-overlay.dts b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p1_1-overlay.dts new file mode 100644 index 000000000000..dc4947679af7 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p1_1-overlay.dts @@ -0,0 +1,36 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +#include "xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi" + +#include "xiaomi/overlay/andromeda/andromeda-sm8150-p1_1.dtsi" +#include "xiaomi/overlay/andromeda/andromeda-pinctrl-p1_1.dtsi" + +#include "sdx5xm-external-soc.dtsi" +#include "sm8150-sdx50m.dtsi" + +/ { + model = "SDX50M ANDROMEDA"; + compatible = "qcom,sm8150-mtp", "qcom,sm8150", "qcom,mtp"; + qcom,board-id = <0x2b 0x1>; + +}; + diff --git a/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2-overlay.dts b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2-overlay.dts new file mode 100644 index 000000000000..3ba628d2b6f7 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2-overlay.dts @@ -0,0 +1,36 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +#include "xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi" + +#include "xiaomi/overlay/andromeda/andromeda-sm8150-p2.dtsi" +#include "xiaomi/overlay/andromeda/andromeda-pinctrl-p2.dtsi" + +#include "sdx5xm-external-soc.dtsi" +#include "sm8150-sdx50m.dtsi" + +/ { + model = "SDX50M ANDROMEDA"; + compatible = "qcom,sm8150-mtp", "qcom,sm8150", "qcom,mtp"; + qcom,board-id = <0x29 0x1>; + +}; + diff --git a/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_1-overlay.dts b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_1-overlay.dts new file mode 100644 index 000000000000..f28dab8c4852 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_1-overlay.dts @@ -0,0 +1,36 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +#include "xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi" + +#include "xiaomi/overlay/andromeda/andromeda-sm8150-p2_1.dtsi" +#include "xiaomi/overlay/andromeda/andromeda-pinctrl-p2_1.dtsi" + +#include "sdx5xm-external-soc.dtsi" +#include "sm8150-sdx50m.dtsi" + +/ { + model = "SDX50M ANDROMEDA"; + compatible = "qcom,sm8150-mtp", "qcom,sm8150", "qcom,mtp"; + qcom,board-id = <0x2c 0x1>; + +}; + diff --git a/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_2-overlay.dts b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_2-overlay.dts new file mode 100644 index 000000000000..f94584c4f4c0 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_2-overlay.dts @@ -0,0 +1,36 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +#include "xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi" + +#include "xiaomi/overlay/andromeda/andromeda-sm8150-p2_2.dtsi" +#include "xiaomi/overlay/andromeda/andromeda-pinctrl-p2_2.dtsi" + +#include "sdx5xm-external-soc.dtsi" +#include "sm8150-sdx50m.dtsi" + +/ { + model = "SDX50M ANDROMEDA"; + compatible = "qcom,sm8150-mtp", "qcom,sm8150", "qcom,mtp"; + qcom,board-id = <0x2d 0x1>; + +}; + diff --git a/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_21-overlay.dts b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_21-overlay.dts new file mode 100644 index 000000000000..5155ccfa4a7a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_21-overlay.dts @@ -0,0 +1,36 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +#include "xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi" + +#include "xiaomi/overlay/andromeda/andromeda-sm8150-p2_21.dtsi" +#include "xiaomi/overlay/andromeda/andromeda-pinctrl-p2_21.dtsi" + +#include "sdx5xm-external-soc.dtsi" +#include "sm8150-sdx50m.dtsi" + +/ { + model = "SDX50M ANDROMEDA"; + compatible = "qcom,sm8150-mtp", "qcom,sm8150", "qcom,mtp"; + qcom,board-id = <0x2e 0x1>; + +}; + diff --git a/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_22-overlay.dts b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_22-overlay.dts new file mode 100644 index 000000000000..38aa96ec0a75 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/andromeda-sm8150-p2_22-overlay.dts @@ -0,0 +1,36 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +#include "xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi" + +#include "xiaomi/overlay/andromeda/andromeda-sm8150-p2_22.dtsi" +#include "xiaomi/overlay/andromeda/andromeda-pinctrl-p2_22.dtsi" + +#include "sdx5xm-external-soc.dtsi" +#include "sm8150-sdx50m.dtsi" + +/ { + model = "SDX50M ANDROMEDA"; + compatible = "qcom,sm8150-mtp", "qcom,sm8150", "qcom,mtp"; + qcom,board-id = <0x2f 0x1>; + +}; + diff --git a/arch/arm64/boot/dts/qcom/cepheus-sm8150-overlay.dts b/arch/arm64/boot/dts/qcom/cepheus-sm8150-overlay.dts new file mode 100644 index 000000000000..a3b5361e657b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/cepheus-sm8150-overlay.dts @@ -0,0 +1,29 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +#include "xiaomi/overlay/cepheus/cepheus-sm8150.dtsi" +#include "xiaomi/overlay/cepheus/cepheus-audio-overlay.dtsi" + +/ { + model = "CEPHEUS"; + compatible = "qcom,sm8150-cdp", "qcom,sm8150", "qcom,cdp"; + qcom,board-id = <37 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/crux-sm8150-overlay.dts b/arch/arm64/boot/dts/qcom/crux-sm8150-overlay.dts new file mode 100644 index 000000000000..a27fdcd6d6c5 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/crux-sm8150-overlay.dts @@ -0,0 +1,33 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +#include "xiaomi/overlay/crux/crux-sm8150.dtsi" +#include "xiaomi/overlay/crux/crux-audio-overlay.dtsi" +#include "sdx5xm-external-soc.dtsi" +#include "sm8150-sdx50m.dtsi" + +/ { + model = "SDX50M CRUX"; + compatible = "qcom,sm8150-mtp", "qcom,sm8150", "qcom,mtp"; + qcom,board-id = <0x2B 0x1>; + +}; + diff --git a/arch/arm64/boot/dts/qcom/nabu-sm8150-overlay.dts b/arch/arm64/boot/dts/qcom/nabu-sm8150-overlay.dts new file mode 100644 index 000000000000..bb0eb37e5217 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/nabu-sm8150-overlay.dts @@ -0,0 +1,29 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +#include "xiaomi/overlay/nabu/nabu-sm8150.dtsi" +#include "xiaomi/overlay/nabu/nabu-audio-overlay.dtsi" + +/ { + model = "NABU"; + compatible = "qcom,sm8150-cdp", "qcom,sm8150", "qcom,cdp"; + qcom,board-id = <48 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/pm8150l.dtsi b/arch/arm64/boot/dts/qcom/pm8150l.dtsi index 3586af695f4f..b764ca015f11 100644 --- a/arch/arm64/boot/dts/qcom/pm8150l.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8150l.dtsi @@ -334,7 +334,7 @@ qcom,num-lpg-channels = <3>; qcom,lut-patterns = <0 10 20 30 40 50 60 70 80 90 100 90 80 70 60 50 40 30 20 10 0>; - lpg1 { + pwm_lpg1: lpg1 { qcom,lpg-chan-id = <1>; qcom,ramp-step-ms = <100>; qcom,ramp-pause-hi-count = <2>; @@ -345,7 +345,7 @@ qcom,ramp-pattern-repeat; }; - lpg2 { + pwm_lpg2: lpg2 { qcom,lpg-chan-id = <2>; qcom,ramp-step-ms = <100>; qcom,ramp-pause-hi-count = <2>; @@ -356,7 +356,7 @@ qcom,ramp-pattern-repeat; }; - lpg3 { + pwm_lpg3: lpg3 { qcom,lpg-chan-id = <3>; qcom,ramp-step-ms = <100>; qcom,ramp-pause-hi-count = <2>; @@ -379,19 +379,19 @@ pm8150l_rgb_led: qcom,leds@d000 { compatible = "qcom,tri-led"; reg = <0xd000 0x100>; - red { + red_led: red { label = "red"; pwms = <&pm8150l_lpg 0 1000000>; led-sources = <0>; linux,default-trigger = "timer"; }; - green { + green_led: green { label = "green"; pwms = <&pm8150l_lpg 1 1000000>; led-sources = <1>; linux,default-trigger = "timer"; }; - blue { + blue_led: blue { label = "blue"; pwms = <&pm8150l_lpg 2 1000000>; led-sources = <2>; diff --git a/arch/arm64/boot/dts/qcom/raphael-sm8150-overlay.dts b/arch/arm64/boot/dts/qcom/raphael-sm8150-overlay.dts new file mode 100644 index 000000000000..e3b35255216d --- /dev/null +++ b/arch/arm64/boot/dts/qcom/raphael-sm8150-overlay.dts @@ -0,0 +1,29 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +#include "xiaomi/overlay/raphael/raphael-sm8150.dtsi" +#include "xiaomi/overlay/raphael/raphael-audio-overlay.dtsi" + +/ { + model = "RAPHAEL"; + compatible = "qcom,sm8150-cdp", "qcom,sm8150", "qcom,cdp"; + qcom,board-id = <40 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/sm8150-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sde-display.dtsi index ddcd25ac1273..9e82bea8c132 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-sde-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-sde-display.dtsi @@ -561,7 +561,7 @@ &sde_dp { qcom,dp-usbpd-detection = <&pm8150b_pdphy>; qcom,ext-disp = <&ext_disp>; - qcom,dp-aux-switch = <&fsa4480>; + /* qcom,dp-aux-switch = <&fsa4480>; */ qcom,usbplug-cc-gpio = <&tlmm 38 0>; diff --git a/arch/arm64/boot/dts/qcom/sm8150-v2-xiaomi.dts b/arch/arm64/boot/dts/qcom/sm8150-v2-xiaomi.dts new file mode 100644 index 000000000000..47c6db4cffeb --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sm8150-v2-xiaomi.dts @@ -0,0 +1,23 @@ +/* Copyright (c) 2018, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; + +#include "sm8150-v2.dtsi" +#include "xiaomi/base/sm8150.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SM8150 v2 SoC"; + compatible = "qcom,sm8150"; + qcom,pmic-name = "PM8150"; + qcom,board-id = <0 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/sm8150-xiaomi.dts b/arch/arm64/boot/dts/qcom/sm8150-xiaomi.dts new file mode 100644 index 000000000000..b804a396c922 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sm8150-xiaomi.dts @@ -0,0 +1,23 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; + +#include "sm8150.dtsi" +#include "xiaomi/base/sm8150.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SM8150 v1 SoC"; + compatible = "qcom,sm8150"; + qcom,pmic-name = "PM8150"; + qcom,board-id = <0 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/sm8150p-v2-xiaomi.dts b/arch/arm64/boot/dts/qcom/sm8150p-v2-xiaomi.dts new file mode 100644 index 000000000000..470042197d16 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sm8150p-v2-xiaomi.dts @@ -0,0 +1,23 @@ +/* Copyright (c) 2018, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; + +#include "sm8150p-v2.dtsi" +#include "xiaomi/base/sm8150.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SM8150P v2 SoC"; + compatible = "qcom,sm8150p"; + qcom,pmic-name = "PM8150"; + qcom,board-id = <0 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/sm8150p-xiaomi.dts b/arch/arm64/boot/dts/qcom/sm8150p-xiaomi.dts new file mode 100644 index 000000000000..f7d46f5dd1bf --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sm8150p-xiaomi.dts @@ -0,0 +1,23 @@ +/* Copyright (c) 2018, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; + +#include "sm8150p.dtsi" +#include "xiaomi/base/sm8150.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SM8150P v1 SoC"; + compatible = "qcom,sm8150p"; + qcom,pmic-name = "PM8150"; + qcom,board-id = <0 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/vayu-sm8150-overlay.dts b/arch/arm64/boot/dts/qcom/vayu-sm8150-overlay.dts new file mode 100644 index 000000000000..0e0129d3d871 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/vayu-sm8150-overlay.dts @@ -0,0 +1,29 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include +#include + +#include "xiaomi/overlay/vayu/vayu-sm8150.dtsi" +#include "xiaomi/overlay/vayu/vayu-audio-overlay.dtsi" + +/ { + model = "VAYU"; + compatible = "qcom,sm8150-cdp", "qcom,sm8150", "qcom,cdp"; + qcom,board-id = <47 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-audio.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-audio.dtsi new file mode 100644 index 000000000000..b923803e5fb0 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-audio.dtsi @@ -0,0 +1,13 @@ +&snd_934x { + qcom,msm-mbhc-usbc-audio-supported = <1>; +}; + +&snd_934x { + /delete-property/ fsa4480-i2c-handle; +}; + +/* +&fsa4480 { + reg = <0x42>; +}; +*/ diff --git a/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-camera.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-camera.dtsi new file mode 100644 index 000000000000..34705a761b0d --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-camera.dtsi @@ -0,0 +1,23 @@ +&i2c_freq_100Khz_cci0 { + hw-scl-stretch-en = <1>; +}; + +&i2c_freq_400Khz_cci0 { + hw-scl-stretch-en = <1>; +}; + +&i2c_freq_custom_cci0 { + hw-scl-stretch-en = <0>; +}; + +&i2c_freq_100Khz_cci1 { + hw-scl-stretch-en = <1>; +}; + +&i2c_freq_400Khz_cci1 { + hw-scl-stretch-en = <1>; +}; + +&i2c_freq_custom_cci1 { + hw-scl-stretch-en = <0>; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-pcie.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-pcie.dtsi new file mode 100644 index 000000000000..137b831ca704 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-pcie.dtsi @@ -0,0 +1,5 @@ +&pcie0 { + pinctrl-0 = <&pcie0_clkreq_default>; + /delete-property/ perst-gpio; + /delete-property/ wake-gpio; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-pinctrl.dtsi new file mode 100644 index 000000000000..444d383a00a3 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-pinctrl.dtsi @@ -0,0 +1,148 @@ +&ts_int_suspend { + config { + input-enable; + }; +}; + +&ts_reset_suspend { + config { + /delete-property/ bias-pull-down; + bias-disable; + output-low; + }; +}; + +/delete-node/ &pcie0_perst_default; +/delete-node/ &pcie0_wake_default; + +&nfc_enable_active { + mux { + pins = "gpio41", "gpio48"; + }; + + config { + pins = "gpio41", "gpio48"; + }; +}; + +&nfc_enable_suspend { + mux { + pins = "gpio41", "gpio48"; + }; + + config { + pins = "gpio41", "gpio48"; + }; +}; + +&quat_aux_pcm_sleep { + mux { + function = "func2"; + }; +}; + +&quat_aux_pcm_active { + mux { + function = "func2"; + }; +}; + +&quat_aux_pcm_din_sleep { + mux { + function = "func2"; + }; +}; + +&quat_aux_pcm_din_active { + mux { + function = "func2"; + }; +}; + +&quat_aux_pcm_dout_sleep { + mux { + function = "func2"; + }; +}; + +&quat_aux_pcm_dout_active { + mux { + function = "func2"; + }; +}; + +&tlmm { + tert_tdm { + cs35l41_int_default: cs35l41_int_default { + mux { + pins = "gpio10"; + function = "gpio"; + }; + config { + pins = "gpio10"; + bias-pull-up; + drive-strength = <8>; + input-enable; + }; + }; + }; +}; + +&tlmm { + /* USB C analog configuration */ + wcd_usbc_analog_en1 { + wcd_usbc_analog_en1_idle: wcd_usbc_ana_en1_idle { + mux { + pins = "gpio35"; + function = "gpio"; + }; + config { + pins = "gpio35"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + wcd_usbc_analog_en1_active: wcd_usbc_ana_en1_active { + mux { + pins = "gpio35"; + function = "gpio"; + }; + config { + pins = "gpio35"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + + wcd_usbc_analog_en2 { + wcd_usbc_analog_en2_idle: wcd_usbc_ana_en2_idle { + mux { + pins = "gpio58"; + function = "gpio"; + }; + config { + pins = "gpio58"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + wcd_usbc_analog_en2_active: wcd_usbc_ana_en2_active { + mux { + pins = "gpio58"; + function = "gpio"; + }; + config { + pins = "gpio58"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-regulator.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-regulator.dtsi new file mode 100644 index 000000000000..6aedd1ecfa4b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-regulator.dtsi @@ -0,0 +1,5 @@ +&pm8150_l13 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + qcom,init-voltage = <3000000>; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150.dtsi new file mode 100644 index 000000000000..bf0f93ebbec2 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150.dtsi @@ -0,0 +1,87 @@ +/ { + aliases { + spi1 = &qupv3_se1_spi; + }; +}; + +&shared_meta { + parts = "vbmeta,boot,system,vendor,dtbo"; +}; + +&android_q_fstab { + odm { + status = "disabled"; + }; + vendor { + fsmgr_flags = "wait,avb"; + }; +}; + +&reserved_memory { + xbl_dump_mem: xbl_dump_mem { + no-map; + reg = <0x0 0x85d00000 0x0 0x100000>; + }; +}; + +&pil_adsp_mem { + reg = <0x0 0x8be00000 0x0 0x2200000>; +}; + +&pil_modem_mem { + reg = <0x0 0x8e000000 0x0 0x9600000>; +}; + +&pil_video_mem { + reg = <0x0 0x97600000 0x0 0x500000>; +}; + +&pil_slpi_mem { + reg = <0x0 0x97b00000 0x0 0x1400000>; +}; + +&pil_ipa_fw_mem { + reg = <0x0 0x98f00000 0x0 0x10000>; +}; + +&pil_ipa_gsi_mem { + reg = <0x0 0x98f10000 0x0 0x5000>; +}; + +&pil_gpu_mem { + reg = <0x0 0x98f15000 0x0 0x2000>; +}; + +&pil_spss_mem { + reg = <0x0 0x99000000 0x0 0x100000>; +}; + +&pil_cdsp_mem { + reg = <0x0 0x99100000 0x0 0x1400000>; +}; + +&disp_rdump_memory { + status = "disabled"; +}; + +#include "trusty.dtsi" + +&qcom_seecom { + reg = <0x87900000 0x3E00000>; +}; + +&qcom_smcinvoke { + reg = <0x87900000 0x3E00000>; +}; + +&soc { + qcom,rmtfs_sharedmem@0 { + reg = <0x0 0x300000>; + }; +}; + +#include "sm8150-audio.dtsi" +#include "sm8150-camera.dtsi" +#include "sm8150-pcie.dtsi" +#include "sm8150-pinctrl.dtsi" +#include "sm8150-regulator.dtsi" diff --git a/arch/arm64/boot/dts/qcom/xiaomi/base/trusty.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/base/trusty.dtsi new file mode 100644 index 000000000000..5d054de89e9f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/base/trusty.dtsi @@ -0,0 +1,28 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +&soc { + trusty { + #size-cells = <0x2>; + #address-cells = <0x2>; + ranges; + compatible = "android,trusty-smc-v1"; + log { + compatible = "android,trusty-log-v1"; + }; + virtio { + compatible = "android,trusty-virtio-v1"; + }; + }; + +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi new file mode 100644 index 000000000000..a243e7d415ae --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include "../common/sm8150-audio-overlay.dtsi" + + +&snd_934x { + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "MADINPUT", "MCLK", + "hifi amp", "LINEOUT1", + "hifi amp", "LINEOUT2", + "MIC BIAS2", "Headset Mic", + "AMIC2_EXT_0", "MIC BIAS2", + "MIC BIAS4", "ANCLeft Headset Mic", + "AMIC2_EXT_1", "MIC BIAS4", + "MIC BIAS1", "ANCRight Headset Mic", + "AMIC3", "MIC BIAS1", + "AMIC4", "MIC BIAS1", + "MIC BIAS1", "ANCRight Headset Mic", + "AMIC1", "MIC BIAS4", + "MIC BIAS4", "ANCLeft Headset Mic"; + + qcom,uart-audio-sw-gpio = <&sbu_uart_en>; + qcom,adc2-switch-gpio = <&adc2_switch_gpio>; + qcom,msm-mbhc-usbc-audio-supported = <1>; + qcom,fsa4476-gpio-support = <1>; + qcom,usbc-analog-en1-gpio = <&wcd_usbc_analog_en1_gpio>; + qcom,usbc-analog-en2-gpio = <&tlmm 35 0>; + + pinctrl-names = "quat_mi2s_enable", "quat_mi2s_disable", + "quat_tdm_enable", "quat_tdm_disable", + "aud_active", "aud_sleep"; + pinctrl-0 = <&quat_mi2s_active &quat_mi2s_sd0_active &quat_mi2s_sd1_active>; + pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_sd0_sleep &quat_mi2s_sd1_sleep>; + pinctrl-2 = <&quat_tdm_active &quat_tdm_dout_active>; + pinctrl-3 = <&quat_tdm_sleep &quat_tdm_dout_sleep>; + pinctrl-4 = <&wcd_usbc_analog_en2_active>; + pinctrl-5 = <&wcd_usbc_analog_en2_idle>; +}; + +&soc { + sbu_uart_en: msm_cdc_pinctrl@25 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&sbu_uart_en_active>; + pinctrl-1 = <&sbu_uart_en_idle>; + }; + + adc2_switch_gpio: msm_cdc_pinctrl@130 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&adc2_switch_gpio_active>; + pinctrl-1 = <&adc2_switch_gpio_idle>; + }; + + wcd_usbc_analog_en1_gpio: msm_cdc_pinctrl@152 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&wcd_usbc_analog_en1_active>; + pinctrl-1 = <&wcd_usbc_analog_en1_idle>; + }; + +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p1.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p1.dtsi new file mode 100644 index 000000000000..8608642bee99 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p1.dtsi @@ -0,0 +1,125 @@ +/*for E5 5G pinctrl*/ + +&tlmm { + + nfc { + nfc_int_active { + /* active state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_int_suspend { + /* sleep state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_active { + /* active state */ + mux { + /* 41: NFC ENABLE 42:ESE Enable */ + pins = "gpio36", "gpio48"; + function = "gpio"; + }; + + config { + pins = "gpio36", "gpio48"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_suspend { + /* sleep state */ + mux { + /* 41: NFC ENABLE 42:ESE Enable */ + pins = "gpio36", "gpio48"; + function = "gpio"; + }; + + config { + pins = "gpio36", "gpio48"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + + nfc_clk_req_active { + /* active state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_clk_req_suspend { + /* sleep state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + }; + ai_key_ctrl { + ai_key_active { + mux { + pins = "gpio41"; + function = "gpio"; + }; + config { + pins = "gpio41"; + drive-strength = <2>; + bias-pull-up; + input-enable; + }; + + }; + + ai_key_idle { + mux { + pins = "gpio41"; + function = "gpio"; + }; + config { + pins = "gpio41"; + drive-strength = <2>; + bias-pull-up; + input-enable; + }; + }; + }; + +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p1_1.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p1_1.dtsi new file mode 100644 index 000000000000..b7a31e8b2aae --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p1_1.dtsi @@ -0,0 +1,2 @@ +/*for E5 5G pinctrl*/ +#include "andromeda-pinctrl-p1.dtsi" diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2.dtsi new file mode 100644 index 000000000000..549da08e5a9b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2.dtsi @@ -0,0 +1,2 @@ +/*for E5 5G pinctrl*/ +#include "andromeda-pinctrl-p1_1.dtsi" diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_1.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_1.dtsi new file mode 100644 index 000000000000..b81dd3abfcd4 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_1.dtsi @@ -0,0 +1,2 @@ +/*for E5 5G pinctrl*/ +#include "andromeda-pinctrl-p2.dtsi" diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_2.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_2.dtsi new file mode 100644 index 000000000000..b81dd3abfcd4 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_2.dtsi @@ -0,0 +1,2 @@ +/*for E5 5G pinctrl*/ +#include "andromeda-pinctrl-p2.dtsi" diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_21.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_21.dtsi new file mode 100644 index 000000000000..b81dd3abfcd4 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_21.dtsi @@ -0,0 +1,2 @@ +/*for E5 5G pinctrl*/ +#include "andromeda-pinctrl-p2.dtsi" diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_22.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_22.dtsi new file mode 100644 index 000000000000..b81dd3abfcd4 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl-p2_22.dtsi @@ -0,0 +1,2 @@ +/*for E5 5G pinctrl*/ +#include "andromeda-pinctrl-p2.dtsi" diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl.dtsi new file mode 100644 index 000000000000..6bf9122c3e6c --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl.dtsi @@ -0,0 +1,534 @@ +/*for E5 5G pinctrl*/ + +&tlmm { + + /* GPIO_119 : FP_RESET_N */ + msm_gpio_119: msm_gpio_119 { + mux { + pins = "gpio119"; + function = "gpio"; + }; + + config { + pins = "gpio119"; + drive-strength = <2>; + bias-disable; + output-low; + }; + }; + + /* GPIO_119 : FP_RESET_N, state device active*/ + msm_gpio_119_output_high: msm_gpio_119_output_high { + mux { + pins = "gpio119"; + function = "gpio"; + }; + + config { + pins = "gpio119"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + + cam_sensor_active_wide: cam_sensor_active_wide { + /* WIDE RESET DVDDEN AVDDEN 1.8AVDDEN */ + mux { + pins = "gpio28", "gpio21"; + function = "gpio"; + }; + + config { + pins = "gpio28", "gpio21"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_wide: cam_sensor_suspend_wide { + /* WIDE RESET DVDDEN AVDDEN 1.8AVDDEN */ + mux { + pins = "gpio28", "gpio21"; + function = "gpio"; + }; + + config { + pins = "gpio28", "gpio21"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_active_tele: cam_sensor_active_tele { + /* TELE RESET DVDDEN AVDDEN */ + mux { + pins = "gpio30", "gpio29"; + function = "gpio"; + }; + + config { + pins = "gpio30", "gpio29"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_tele: cam_sensor_suspend_tele { + /* TELE RESET DVDDEN AVDDEN */ + mux { + pins = "gpio30", "gpio29"; + function = "gpio"; + }; + + config { + pins = "gpio30", "gpio29"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_active_front: cam_sensor_active_front { + /* FRONT RESET DVDDEN, AVDDEN */ + mux { + pins = "gpio12", "gpio32"; + function = "gpio"; + }; + + config { + pins = "gpio12", "gpio32"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_front: cam_sensor_suspend_front { + /* FRONT RESET DVDDEN, AVDDEN */ + mux { + pins = "gpio12", "gpio32"; + function = "gpio"; + }; + + config { + pins = "gpio12", "gpio32"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_active_ultra: cam_sensor_active_ultra { + /* ULTRA RESET DVDDEN AVDDEN */ + mux { + pins = "gpio23", "gpio33"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio33"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_ultra: cam_sensor_suspend_ultra { + /* ULTRA RESET DVDDEN AVDDEN */ + mux { + pins = "gpio23", "gpio33"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio33"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_actuator_wide_en: cam_actuator_wide_en { + mux { + pins = "gpio26"; + function = "gpio"; + }; + + config { + pins = "gpio26"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_actuator_tele_en: cam_actuator_tele_en { + mux { + pins = "gpio31"; + function = "gpio"; + }; + + config { + pins = "gpio31"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_viodd_en: cam_sensor_viodd_en { + mux { + pins = "gpio34"; + function = "gpio"; + }; + + config { + pins = "gpio34"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + adc2_switch_gpio_ctrl { + adc2_switch_gpio_idle: adc2_switch_idle { + mux { + pins = "gpio130"; + function = "gpio"; + }; + config { + pins = "gpio130"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + adc2_switch_gpio_active: adc2_switch_active { + mux { + pins = "gpio130"; + function = "gpio"; + }; + config { + pins = "gpio130"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + + sbu_uart_en_ctrl { + sbu_uart_en_idle: uart_audio_en_idle { + mux { + pins = "gpio25"; + function = "gpio"; + }; + config { + pins = "gpio25"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + sbu_uart_en_active: uart_audio_en_active { + mux { + pins = "gpio25"; + function = "gpio"; + }; + config { + pins = "gpio25"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + + nfc { + nfc_int_active: nfc_int_active { + /* active state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_int_suspend: nfc_int_suspend { + /* sleep state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_active: nfc_enable_active { + /* active state */ + mux { + /* 41: NFC ENABLE 42:ESE Enable */ + pins = "gpio41", "gpio48"; + function = "gpio"; + }; + + config { + pins = "gpio41", "gpio48"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_suspend: nfc_enable_suspend { + /* sleep state */ + mux { + /* 41: NFC ENABLE 42:ESE Enable */ + pins = "gpio41", "gpio48"; + function = "gpio"; + }; + + config { + pins = "gpio41", "gpio48"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + + nfc_clk_req_active: nfc_clk_req_active { + /* active state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_clk_req_suspend: nfc_clk_req_suspend { + /* sleep state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + }; + + ai_key_ctrl { + ai_key_active_default: ai_key_active { + mux { + pins = "gpio36"; + function = "gpio"; + }; + config { + pins = "gpio36"; + drive-strength = <2>; + bias-pull-up; + input-enable; + }; + + }; + + ai_key_idle_default: ai_key_idle { + mux { + pins = "gpio36"; + function = "gpio"; + }; + config { + pins = "gpio36"; + drive-strength = <2>; + bias-pull-up; + input-enable; + }; + }; + }; + + wcd_usbc_analog_en1 { + wcd_usbc_analog_en1_idle: wcd_usbc_ana_en1_idle { + mux { + pins = "gpio152"; + function = "gpio"; + }; + config { + pins = "gpio152"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + wcd_usbc_analog_en1_active: wcd_usbc_ana_en1_active { + mux { + pins = "gpio152"; + function = "gpio"; + }; + config { + pins = "gpio152"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + + wcd_usbc_analog_en2 { + wcd_usbc_analog_en2_idle: wcd_usbc_ana_en2_idle { + mux { + pins = "gpio35"; + function = "gpio"; + }; + config { + pins = "gpio35"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + wcd_usbc_analog_en2_active: wcd_usbc_ana_en2_active { + mux { + pins = "gpio35"; + function = "gpio"; + }; + config { + pins = "gpio35"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + +}; + +&cam_sensor_mclk0_active { + /* MCLK0 */ + mux { + pins = "gpio13"; + function = "cam_mclk"; + }; + + config { + pins = "gpio13"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk0_suspend { + /* MCLK0 */ + mux { + pins = "gpio13"; + function = "cam_mclk"; + }; + + config { + pins = "gpio13"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk1_active { + /* MCLK1 */ + mux { + pins = "gpio14"; + function = "cam_mclk"; + }; + + config { + pins = "gpio14"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk1_suspend { + /* MCLK1 */ + mux { + pins = "gpio14"; + function = "cam_mclk"; + }; + + config { + pins = "gpio14"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk2_active { + /* MCLK2 */ + mux { + pins = "gpio15"; + function = "cam_mclk"; + }; + + config { + pins = "gpio15"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk2_suspend { + /* MCLK2 */ + mux { + pins = "gpio15"; + function = "cam_mclk"; + }; + + config { + pins = "gpio15"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk3_active { + /* MCLK3 */ + mux { + pins = "gpio16"; + function = "cam_mclk"; + }; + + config { + pins = "gpio16"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk3_suspend { + /* MCLK3 */ + mux { + pins = "gpio16"; + function = "cam_mclk"; + }; + + config { + pins = "gpio16"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; \ No newline at end of file diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-camera-sensor.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-camera-sensor.dtsi new file mode 100644 index 000000000000..964a7597f8b8 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-camera-sensor.dtsi @@ -0,0 +1,494 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +&pm8150l_switch0 { + label = "switch"; + qcom,led-name = "led:switch_0"; + qcom,led-mask = <3>; + qcom,default-led-trigger = "switch0_trigger"; +}; + +&pm8150l_switch1 { + label = "switch"; + qcom,led-name = "led:switch_1"; + qcom,led-mask = <4>; + com,default-led-trigger = "switch1_trigger"; +}; + +&soc { + led_flash_rear: qcom,camera-flash@0 { + cell-index = <0>; + reg = <0x00 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch0>; + status = "ok"; + }; + + led_flash_rear_aux: qcom,camera-flash@1 { + cell-index = <1>; + reg = <0x01 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch0>; + status = "ok"; + }; + + led_flash_front: qcom,camera-flash@2 { + cell-index = <2>; + reg = <0x02 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash2>; + torch-source = <&pm8150l_torch2>; + switch-source = <&pm8150l_switch1>; + status = "ok"; + }; + + led_flash_front_aux: qcom,camera-flash@3 { + cell-index = <3>; + reg = <0x03 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash2>; + torch-source = <&pm8150l_torch2>; + switch-source = <&pm8150l_switch1>; + status = "ok"; + }; + + wide_actuator_regulator: gpio-regulator@0 { + compatible = "regulator-fixed"; + reg = <0x00 0x00>; + regulator-name = "actuator_regulator"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <100>; + enable-active-high; + gpio = <&tlmm 26 0>; + pinctrl-names = "default"; + pinctrl-0 = <&cam_actuator_wide_en>; + vin-supply = <&pm8150l_bob>; + }; + + tele_actuator_regulator: gpio-regulator@1 { + compatible = "regulator-fixed"; + reg = <0x01 0x00>; + regulator-name = "actuator_regulator"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <100>; + enable-active-high; + gpio = <&tlmm 31 0>; + pinctrl-names = "default"; + pinctrl-0 = <&cam_actuator_tele_en>; + vin-supply = <&pm8150l_bob>; + }; + + camera_viodd_ldo: gpio-regulator@2 { + compatible = "regulator-fixed"; + reg = <0x02 0x00>; + regulator-name = "camera_viodd_ldo"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&tlmm 34 0>; + pinctrl-names = "default"; + pinctrl-0 = <&cam_sensor_viodd_en>; + vin-supply = <&pm8150_s4>; + }; + + camera_ois_regulator: gpio-regulator@3 { + compatible = "regulator-fixed"; + reg = <0x03 0x00>; + regulator-name = "camera_ois_regulator"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <100>; + enable-active-high; + gpio = <&tlmm 24 0>; + vin-supply = <&pm8150_s4>; + }; +}; + +&cam_cci1 { + cell-index = <1>; + compatible = "qcom,cci"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +}; + +&cam_cci0 { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + status = "ok"; + }; + + actuator_rear: qcom,actuator@0 { + cell-index = <0>; + reg = <0x0>; + compatible = "qcom,actuator"; + cci-master = <0>; + cam_vaf-supply = <&wide_actuator_regulator>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + actuator_rear_aux: qcom,actuator@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,actuator"; + cci-master = <1>; + cam_vaf-supply = <&tele_actuator_regulator>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + ois_rear: qcom,ois@0 { + cell-index = <0>; + reg = <0x0>; + compatible = "qcom,ois"; + cci-master = <0>; + cam_vaf-supply = <&camera_ois_regulator>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + status = "ok"; + }; + + + eeprom_rear: qcom,eeprom@0 { + cell-index = <0>; + reg = <0>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&camera_viodd_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <1000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_wide>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_wide>; + gpios = <&tlmm 13 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK0"; + + sensor-mode = <0>; + cci-master = <0>; + cci-device = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + eeprom_rear_aux: qcom,eeprom@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&camera_viodd_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <1000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_tele>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_tele>; + gpios = <&tlmm 13 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK0"; + + sensor-mode = <0>; + cci-master = <0>; + cci-device = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + eeprom_front: qcom,eeprom@2 { + cell-index = <2>; + reg = <0x2>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&camera_viodd_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 0 >; + rgltr-max-voltage = <1800000 0 >; + rgltr-load-current = <1000 0 >; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_front>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_front>; + gpios = <&tlmm 15 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK2"; + cci-device = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + eeprom_front_aux: qcom,eeprom@3 { + cell-index = <3>; + reg = <0x03>; + compatible = "qcom,eeprom"; + slave-addr = <0xA2>; + i2c-freq-mode = <1>; + cam_vio-supply = <&camera_viodd_ldo>; + regulator-names = "cam_vio","cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <1000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_ultra>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_ultra>; + gpios = <&tlmm 16 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK3"; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + qcom,cam-sensor@0 { + cell-index = <0>; + compatible = "qcom,cam-sensor"; + reg = <0x0>; + csiphy-sd-index = <0>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + led-flash-src = <&led_flash_rear>; + actuator-src = <&actuator_rear>; + eeprom-src = <&eeprom_rear>; + ois-src = <&ois_rear>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150l_s8>; + cam_clk-supply = <&titan_top_gdsc>; + cam_v_custom1-supply = <&pm8150_l17>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk", "cam_v_custom1"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 3008000 1352000 0 2856000>; + rgltr-max-voltage = <1800000 4000000 1352000 0 3008000>; + rgltr-load-current = <1000 80000 1200000 0 10000>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_wide>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_wide>; + gpios = <&tlmm 13 0>, + <&tlmm 28 0>, + <&tlmm 21 0>; + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET_W", + "CAM_VDD0_EN"; + sensor-mode = <0>; + cci-master = <0>; + cci-device = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + qcom,cam-sensor@1 { + cell-index = <1>; + compatible = "qcom,cam-sensor"; + reg = <0x1>; + csiphy-sd-index = <1>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + actuator-src = <&actuator_rear_aux>; + led-flash-src = <&led_flash_rear_aux>; + eeprom-src = <&eeprom_rear_aux>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150l_s8>; + cam_clk-supply = <&titan_top_gdsc>; + cam_v_custom1-supply = <&pm8150_l17>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk", "cam_v_custom1"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 3008000 1352000 0 2856000>; + rgltr-max-voltage = <1800000 4000000 1352000 0 3008000>; + rgltr-load-current = <1000 80000 1200000 0 1000>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_tele>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_tele>; + gpios = <&tlmm 14 0>, + <&tlmm 30 0>, + <&tlmm 29 0>; + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET_T", + "CAM_VDD1_EN"; + sensor-mode = <0>; + cci-master = <1>; + cci-device = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + qcom,cam-sensor@2 { + cell-index = <2>; + compatible = "qcom,cam-sensor"; + reg = <0x02>; + csiphy-sd-index = <2>; + sensor-position-roll = <270>; + sensor-position-pitch = <0>; + sensor-position-yaw = <0>; + led-flash-src = <&led_flash_front>; + eeprom-src = <&eeprom_front>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150l_s8>; + cam_clk-supply = <&titan_top_gdsc>; + cam_v_custom1-supply = <&pm8150_l17>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk", "cam_v_custom1"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 3008000 1352000 0 2856000>; + rgltr-max-voltage = <1800000 4000000 1352000 0 3008000>; + rgltr-load-current = <1000 80000 1200000 0 1000>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_front>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_front>; + gpios = <&tlmm 15 0>, + <&tlmm 12 0>, + <&tlmm 32 0>; + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET_F", + "CAM_VDD2_EN"; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + qcom,cam-sensor@3 { + cell-index = <3>; + compatible = "qcom,cam-sensor"; + reg = <0x03>; + csiphy-sd-index = <3>; + sensor-position-roll = <270>; + sensor-position-pitch = <0>; + sensor-position-yaw = <0>; + led-flash-src = <&led_flash_front_aux>; + eeprom-src = <&eeprom_front_aux>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150l_bob>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 3008000 0>; + rgltr-max-voltage = <1800000 4000000 0>; + rgltr-load-current = <1000 80000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_ultra>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_ultra>; + + gpios = <&tlmm 16 0>, + <&tlmm 23 0>, + <&tlmm 33 0>; + gpio-standby = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK3", + "CAM_PWD_U", + "CAM_VDD3_EN"; + sensor-mode = <0>; + cci-master = <0>; + cci-device = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; +}; + + diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p1.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p1.dtsi new file mode 100644 index 000000000000..075fad8a0371 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p1.dtsi @@ -0,0 +1,39 @@ +/* +this file is for attribution only of andromeda +And public attribution of xiaomi platforms(like E5 5G and so and) +*/ + +#include "andromeda-sm8150.dtsi" +&soc { + gpio_keys { + pinctrl-0 = <&ai_key_active_default>; + ai_key { + label = "ai_key"; + gpios = <&tlmm 41 GPIO_ACTIVE_LOW>; + linux,input-type = <1>; + linux,code = ; + gpio-key,wakeup; + debounce-interval = <39>; + }; + }; +}; +&qupv3_se9_i2c { + status = "ok"; + nq@28 { + compatible = "qcom,nq-nci"; + reg = <0x28>; + qcom,nq-irq = <&tlmm 47 0x00>; + qcom,nq-ven = <&tlmm 36 0x00>; + qcom,nq-firm = <&tlmm 48 0x00>; + qcom,nq-clkreq = <&tlmm 113 0x00>; + //qcom,nq-esepwr = <&tlmm 42 0x00>; + interrupt-parent = <&tlmm>; + interrupts = <47 0>; + interrupt-names = "nfc_irq"; + pinctrl-names = "nfc_active", "nfc_suspend"; + pinctrl-0 = <&nfc_int_active &nfc_enable_active + &nfc_clk_req_active>; + pinctrl-1 = <&nfc_int_suspend &nfc_enable_suspend + &nfc_clk_req_suspend>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p1_1.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p1_1.dtsi new file mode 100644 index 000000000000..3c441a515ab5 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p1_1.dtsi @@ -0,0 +1,9 @@ +/* +this file is for attribution only of andromeda +And public attribution of xiaomi platforms(like E5 5G and so and) +*/ + +#include "andromeda-sm8150-p1.dtsi" +&dsi_samsung_fhd_ea8076_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_external_supply>; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2.dtsi new file mode 100644 index 000000000000..5e907d4f7f5a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2.dtsi @@ -0,0 +1,6 @@ +/* +this file is for attribution only of andromeda +And public attribution of xiaomi platforms(like E5 5G and so and) +*/ + +#include "andromeda-sm8150-p1_1.dtsi" diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_1.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_1.dtsi new file mode 100644 index 000000000000..d6ab8778539f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_1.dtsi @@ -0,0 +1,6 @@ +/* +this file is for attribution only of andromeda +And public attribution of xiaomi platforms(like E5 5G and so and) +*/ + +#include "andromeda-sm8150-p2.dtsi" diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_2.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_2.dtsi new file mode 100644 index 000000000000..d6ab8778539f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_2.dtsi @@ -0,0 +1,6 @@ +/* +this file is for attribution only of andromeda +And public attribution of xiaomi platforms(like E5 5G and so and) +*/ + +#include "andromeda-sm8150-p2.dtsi" diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_21.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_21.dtsi new file mode 100644 index 000000000000..d6ab8778539f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_21.dtsi @@ -0,0 +1,6 @@ +/* +this file is for attribution only of andromeda +And public attribution of xiaomi platforms(like E5 5G and so and) +*/ + +#include "andromeda-sm8150-p2.dtsi" diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_22.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_22.dtsi new file mode 100644 index 000000000000..d6ab8778539f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150-p2_22.dtsi @@ -0,0 +1,6 @@ +/* +this file is for attribution only of andromeda +And public attribution of xiaomi platforms(like E5 5G and so and) +*/ + +#include "andromeda-sm8150-p2.dtsi" diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150.dtsi new file mode 100644 index 000000000000..c5cb203bf7b5 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-sm8150.dtsi @@ -0,0 +1,659 @@ +/* +this file is for attribution only of andromeda +And public attribution of xiaomi platforms(like E5 5G and so and) +*/ + +#include "andromeda-pinctrl.dtsi" +#include "../common/xiaomi-sdx50-sm8150-common.dtsi" + +#include "andromeda-sm8150-camera-sensor.dtsi" + +&soc { + touch_vddio_vreg: touch_vddio_vreg { + compatible = "regulator-fixed"; + regulator-name = "disp_vddio_vreg"; + startup-delay-us = <4000>; + enable-active-high; + regulator-boot-on; + gpio = <&tlmm 37 0>; + }; + vdd_boost_vreg: vdd_boost_vreg { + compatible = "regulator-fixed"; + regulator-name = "vdd_boost_vreg"; + startup-delay-us = <4000>; + enable-active-high; + regulator-always-on; + gpio = <&pm8150b_gpios 5 0>; + }; + disp_vci_vreg: disp_vci_vreg { + compatible = "regulator-fixed"; + regulator-name = "disp_vci_vreg"; + start-delay-us = <4000>; + enable-active-high; + regulator-boot-on; + gpio = <&tlmm 7 0>; + }; + + fp_vdd_vreg: fp_vdd_vreg { + compatible = "regulator-fixed"; + regulator-name = "fp_vdd_vreg"; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&tlmm 92 0>; + regulator-always-on; + }; + fingerprint_fpc { + status = "ok"; + compatible = "fpc,fpc1020"; + interrupt-parent = <&tlmm>; + interrupts = <118 0x0>; + fpc,gpio_irq = <&tlmm 118 0x0>; + /* fpc,enable-on-boot; */ + /* fpc,enable-wakeup; */ + + pinctrl-names = "fpc1020_reset_reset", + "fpc1020_reset_active"; + + pinctrl-0 = <&msm_gpio_119>; + pinctrl-1 = <&msm_gpio_119_output_high>; + }; + pcie0: qcom,pcie@1c00000 { + status = "disabled"; + }; + + gpio_keys { + pinctrl-0 = <&ai_key_active_default>; + ai_key { + label = "ai_key"; + gpios = <&tlmm 36 GPIO_ACTIVE_LOW>; + linux,input-type = <1>; + linux,code = ; + gpio-key,wakeup; + debounce-interval = <39>; + }; + }; + +}; + +&sde_dsi { + vcie-supply = <&disp_vci_vreg>; +}; + +&pm8150l_lpg { + qcom,lut-patterns = <0 1 1 1 1 0>; +}; + +&pwm_lpg1 { + qcom,lpg-chan-id = <1>; + qcom,ramp-step-ms = <400>; + qcom,ramp-pause-hi-count = <0>; + qcom,ramp-pause-lo-count = <0>; + qcom,ramp-low-index = <0>; + qcom,ramp-high-index = <5>; + qcom,ramp-from-low-to-high; + qcom,ramp-pattern-repeat; +}; + +&red_led { + label = "white"; +}; + +&green_led { + status = "disabled"; +}; + +&blue_led { + status = "disabled"; +}; + +&qcom_qbt1000 { + status = "disabled"; +}; + +&qcom_seecom { + reg = <0x87900000 0x3E00000>; +}; + +&qcom_smcinvoke { + reg = <0x87900000 0x3E00000>; +}; + +&qupv3_se4_i2c { + status = "ok"; + + fsa4480@43 { + status = "disabled"; + }; +}; + +&qupv3_se8_i2c { + status = "ok"; + /*smart PA*/ + tas2557@4c{ + compatible = "ti,tas2557"; + reg = <0x4c>; + ti,cdc-reset-gpio = <&tlmm 59 0>; + ti,irq-gpio = <&tlmm 115 0>; + ti,i2s-bits = <16>; + ti,bypass-tmax = <0>; + }; +}; + +&qupv3_se17_i2c { + status = "ok"; + fts@49 { + compatible = "st,fts"; + reg = <0x49>; + interrupt-parent = <&tlmm>; + interrupts = <122 0x2008>; + pinctrl-names = "pmx_ts_active", "pmx_ts_suspend"; + pinctrl-0 = <&ts_active>; + pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; + vdd-supply = <&pm8150l_l1>; + avdd-supply = <&touch_vddio_vreg>; + fts,pwr-reg-name = "avdd"; + fts,bus-reg-name = "vdd"; + fts,irq-gpio = <&tlmm 122 0x2008>; + fts,irq-gpio-name = "fts_irq"; + fts,reset-gpio-enable; + fts,reset-gpio = <&tlmm 54 0x00>; + fts,reset-gpio-name = "fts_rst"; + fts,irq-flags = <0x2008>; /* IRQF_ONESHOT | IRQF_TRIGGER_LOW */ + fts,x-max = <1080>; + fts,y-max = <2340>; + fts,default-fw-name = "st_fts_e5.ftb"; + fts,config-array-size = <1>; + fts,dump-click-count; + fts,disable-fw-update; + fts,touch-up-threshold-min = <40>; + fts,touch-up-threshold-max = <120>; + fts,touch-up-threshold-def = <80>; + fts,touch-tolerance-min = <5>; + fts,touch-tolerance-max = <35>; + fts,touch-tolerance-def = <25>; + fts,touch-wgh-min-def = <1>; + fts,touch-wgh-min-max = <15>; + fts,touch-wgh-min-min = <0>; + fts,touch-wgh-max-def = <5>; + fts,touch-wgh-max-max = <15>; + fts,touch-wgh-max-min = <0>; + fts,touch-wgh-step-def = <1>; + fts,touch-wgh-step-max = <2>; + fts,touch-wgh-step-min = <0>; + fts,edgefilter-leftrigt-def = <45>; + fts,edgefilter-topbottom-def = <0>; + fts,edgefilter-top-ingamemode = <0>; + fts,edgefilter-bottom-ingamemode = <0>; + fts,edgefilter-area-step1 = <100>; + fts,edgefilter-area-step2 = <170>; + fts,edgefilter-area-step3 = <250>; + fts,cfg_0 { + fts,tp-vendor = <0x52>; + fts,fw-name = "st_fts_e5.ftb"; + fts,limit-name = "stm_fts_production_limits.csv"; + fts,clicknum-file-name = "fts+sdc"; + }; + }; +}; + +&vendor { + mtp_batterydata: qcom,battery-data { + qcom,batt-id-range-pct = <15>; + #include "../common/battery/batterydata-E5G-coslight-3700mah.dtsi" + #include "../common/battery/fg-gen4-batterydata-alium-3600mah_E5G.dtsi" + }; +}; + +&pm8150b_fg { + qcom,battery-data = <&mtp_batterydata>; + qcom,rapid-soc-dec-en; + qcom,fg-sys-term-current = <(-300)>; + qcom,fg-cutoff-voltage = <3400>; + qcom,fg-cutoff-current = <200>; + qcom,fg-empty-voltage = <3100>; + qcom,fg-batt-temp-delta = <6>; + qcom,fg-force-load-profile; + /* ESR fast calibration */ + qcom,fg-esr-timer-chg-fast = <0 7>; + qcom,fg-esr-timer-dischg-fast = <0 7>; + qcom,fg-esr-timer-chg-slow = <0 96>; + qcom,fg-esr-timer-dischg-slow = <0 96>; + qcom,fg-esr-cal-soc-thresh = <26 230>; + qcom,fg-esr-cal-temp-thresh = <10 40>; +}; + +&pm8150b_charger { + qcom,sec-charger-config = <1>; + qcom,usb-icl-ua = <2800000>; + qcom,fcc-max-ua = <3700000>; + qcom,fv-max-uv = <4450000>; + qcom,auto-recharge-soc = <99>; + qcom,chg-term-src = <1>; + qcom,chg-term-current-ma = <(-220)>; + qcom,thermal-mitigation = <3000000 2800000 2600000 2400000 2200000 2100000 2000000 + 1800000 1600000 1500000 1400000 1200000 1000000 900000 + 800000 500000>; + qcom,thermal-mitigation-icl + = <2800000 2700000 2600000 2400000 2200000 2100000 2000000 + 1800000 1800000 1800000 1700000 1600000 1500000 1300000 + 1000000 750000>; + qcom,thermal-mitigation-dcp + = <1800000 1800000 1800000 1800000 1800000 1800000 1800000 + 1800000 1800000 1700000 1600000 1400000 1200000 1100000 + 1100000 1000000>; + qcom,thermal-mitigation-qc2 + = <1500000 1500000 1500000 1500000 1450000 1400000 1350000 + 1300000 1150000 1100000 1000000 900000 850000 750000 + 650000 500000>; + qcom,thermal-fcc-qc3-normal + = <3200000 3000000 2800000 2600000 2500000 2400000 2300000 + 2200000 2100000 1800000 1600000 1400000 1200000 1000000 + 750000 750000>; + qcom,thermal-fcc-qc3-cp + = <3600000 3500000 3400000 3300000 3200000 3200000 3200000 + 3200000 3200000 2800000 2400000 2200000 2000000 1300000 + 750000 700000>; + qcom,thermal-fcc-qc3-classb-cp + = <3700000 3700000 3700000 3700000 3700000 3700000 3700000 + 3700000 3700000 3600000 3400000 3200000 3000000 2200000 + 2000000 700000>; + qcom,thermal-mitigation-pd-base + = <3000000 2800000 2600000 2400000 2200000 2000000 1800000 + 1600000 1600000 1400000 1200000 1100000 1050000 1000000 + 950000 500000>; + qcom,thermal-fcc-pps-cp + = <3700000 3700000 3700000 3700000 3700000 3700000 3700000 + 3700000 3700000 3600000 3400000 3200000 3000000 2200000 + 2000000 700000>; + io-channels = <&pm8150b_vadc ADC_MID_CHG_DIV6>, + <&pm8150b_vadc ADC_USB_IN_V_16>, + <&pm8150b_vadc ADC_USB_IN_I>, + <&pm8150b_vadc ADC_SBUx>, + <&pm8150b_vadc ADC_VPH_PWR>, + <&pm8150b_vadc ADC_CHG_TEMP>; + io-channel-names = "mid_voltage", + "usb_in_voltage", + "usb_in_current", + "sbux_res", + "vph_voltage", + "chg_temp"; + qcom,battery-data = <&mtp_batterydata>; + dpdm-supply = <&usb2_phy0>; + qcom,distinguish-qc-class-ab; + qcom,lpd-disable; + qcom,sw-jeita-enable; + qcom,wd-bark-time-secs = <16>; +}; + +&ext_5v_boost { + status = "ok"; +}; + +&pm8150b_pdphy { + vbus-supply = <&ext_5v_boost>; +}; + +&usb0 { + dwc3@a600000 { + usb-phy = <&usb2_phy0>, <&usb_nop_phy>; + maximum-speed = "high-speed"; + }; +}; + +&usb2_phy0 { + qcom,param-override-seq = + <0x33 0x70 + 0x2c 0x74>; +}; + +&usb_qmp_dp_phy { + status = "disabled"; +}; + +&usb1 { + extcon = <&extcon_usb1>; + status = "disabled"; +}; + +&usb2_phy1 { + status = "disabled"; +}; + +&usb_qmp_phy { + status = "disabled"; +}; + +&pm8150b_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + wp_therm { + reg = ; + label = "wp_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + vcoin { + reg = ; + label = "vcoin"; + qcom,pre-scaling = <1 3>; + }; + + conn_therm { + reg = ; + label = "conn_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + chg_sbux { + reg = ; + label = "chg_sbux"; + qcom,pre-scaling = <1 3>; + }; + + mid_chg_div6 { + reg = ; + label = "chg_mid"; + qcom,pre-scaling = <1 6>; + }; + + usb_in_i_uv { + reg = ; + label = "usb_in_i_uv"; + qcom,pre-scaling = <1 1>; + }; + + usb_in_v_div_16 { + reg = ; + label = "usb_in_v_div_16"; + qcom,pre-scaling = <1 16>; + }; +}; + +&pm8150_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + vcoin { + reg = ; + label = "vcoin"; + qcom,pre-scaling = <1 3>; + }; + + xo_therm { + reg = ; + label = "xo_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + quiet_therm { + reg = ; + label = "quiet_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + pa_therm0 { + reg = ; + label = "pa_therm0"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm8150l_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + cam_therm0 { + reg = ; + label = "cam_therm0"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + cam_therm1 { + reg = ; + label = "cam_therm1"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + pa_therm1 { + reg = ; + label = "pa_therm1"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm8150b_adc_tm { + wp_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm8150_adc_tm { + xo_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + quiet_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + pa_therm0 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm8150l_adc_tm { + cam_therm0 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + cam_therm1 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + pa_therm1 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&thermal_zones { + wp_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150b_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + xo_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_XO_THERM_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + quiet_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + pa_therm0 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_AMUX_THM2_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + cam_therm0 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + cam_therm1 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM2_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + pa_therm1 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM3_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; +}; + +&pm8150b_haptics { + qcom,vmax-mv = <2800>; + qcom,play-rate-us = <5102>; + + wf_0 { + /* CLICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_1 { + /* DOUBLE CLICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 3e]; + qcom,wf-brake-pattern = [03 01 01 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_2 { + /* TICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 3e]; + qcom,wf-brake-pattern = [03 01 01 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_3 { + /* THUD */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_4 { + /* POP */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_5 { + /* HEAVY CLICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 7e 7e]; + qcom,wf-brake-pattern = [03 03 01 00]; + qcom,wf-play-rate-us = <5102>; + }; +}; + +&ufshc_mem { + vdd-hba-supply = <&ufs_phy_gdsc>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm8150_l10>; + vcc-voltage-level = <2950000 2960000>; + vccq2-supply = <&pm8150_s4>; + vcc-max-microamp = <750000>; + vccq2-max-microamp = <750000>; + + qcom,vddp-ref-clk-supply = <&pm8150_l9>; + qcom,vddp-ref-clk-max-microamp = <100>; + + status = "ok"; +}; + diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-audio-overlay.dtsi new file mode 100644 index 000000000000..7877060e5e35 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-audio-overlay.dtsi @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include "../common/sm8150-audio-overlay.dtsi" + +&snd_934x { + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "MADINPUT", "MCLK", + "hifi amp", "LINEOUT1", + "hifi amp", "LINEOUT2", + "AMIC2_EXT_0", "MIC BIAS2", + "MIC BIAS2", "Headset Mic", + "AMIC2_EXT_1", "MIC BIAS1", + "MIC BIAS1", "Headset Mic2", + "AMIC3", "MIC BIAS3", + "MIC BIAS3", "ANCRight Headset Mic", + "AMIC1", "MIC BIAS1", + "MIC BIAS1", "ANCLeft Headset Mic", + "AMIC4", "MIC BIAS3", + "MIC BIAS3", "ANCRight Headset Mic", + "AMIC5", "MIC BIAS4", + "MIC BIAS4", "Analog Mic5"; + + qcom,uart-audio-sw-gpio = <&sbu_uart_en>; + qcom,adc2-switch-gpio = <&adc2_switch_gpio>; + qcom,msm-mbhc-usbc-audio-supported = <1>; + qcom,fsa4476-gpio-support = <1>; + qcom,usbc-analog-en1-gpio = <&wcd_usbc_analog_en1_gpio>; + qcom,usbc-analog-en2-gpio = <&tlmm 58 0>; + + pinctrl-names = "quat_mi2s_enable", "quat_mi2s_disable", + "quat_tdm_enable", "quat_tdm_disable", + "aud_active", "aud_sleep"; + pinctrl-0 = <&quat_mi2s_active &quat_mi2s_sd0_active &quat_mi2s_sd1_active>; + pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_sd0_sleep &quat_mi2s_sd1_sleep>; + pinctrl-2 = <&quat_tdm_active &quat_tdm_dout_active>; + pinctrl-3 = <&quat_tdm_sleep &quat_tdm_dout_sleep>; + pinctrl-4 = <&wcd_usbc_analog_en2_active>; + pinctrl-5 = <&wcd_usbc_analog_en2_idle>; +}; + +&soc { + sbu_uart_en: msm_cdc_pinctrl@25 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&sbu_uart_en_active>; + pinctrl-1 = <&sbu_uart_en_idle>; + }; + + adc2_switch_gpio: msm_cdc_pinctrl@142 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&adc2_switch_gpio_active>; + pinctrl-1 = <&adc2_switch_gpio_idle>; + }; + + wcd_usbc_analog_en1_gpio: msm_cdc_pinctrl@49 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&wcd_usbc_analog_en1_active>; + pinctrl-1 = <&wcd_usbc_analog_en1_idle>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-pinctrl.dtsi new file mode 100644 index 000000000000..7aeb99e672df --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-pinctrl.dtsi @@ -0,0 +1,539 @@ +/*for xiaomi pinctrl*/ +&tlmm { + pmx_ts_active { + ts_active: ts_active { + mux { + pins = "gpio122", "gpio12"; + function = "gpio"; + }; + config { + pins = "gpio122", "gpio12"; + drive-strength = <8>; + bias-pull-up; + }; + }; + }; + + pmx_ts_int_suspend { + ts_int_suspend: ts_int_suspend { + mux { + pins = "gpio122"; + function = "gpio"; + }; + config { + pins = "gpio122"; + drive-strength = <2>; + bias-pull-down; + input-enable; + }; + }; + }; + + pmx_ts_reset_suspend { + ts_reset_suspend: ts_reset_suspend { + mux { + pins = "gpio12"; + function = "gpio"; + }; + config { + pins = "gpio12"; + drive-strength = <2>; + bias-disable; + output-low; + }; + }; + }; + + idt { + idt_int_active: idt_int_active { + /* active state */ + mux { + /* GPIO 78 idt Read Interrupt */ + pins = "gpio90"; + function = "gpio"; + }; + + config { + pins = "gpio90"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + idt_int_suspend: idt_int_suspend { + /* sleep state */ + mux { + /* GPIO 78 idt Read Interrupt */ + pins = "gpio90"; + function = "gpio"; + }; + + config { + pins = "gpio90"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + idt_enable_active: idt_enable_active { + /* active state */ + mux { + /* GPIO 36 idt enable pin */ + pins = "gpio104"; + function = "gpio"; + }; + + config { + pins = "gpio104"; + drive-strength = <2>; + bias-disable; + bias-pull-down; + output-low; + }; + }; + + idt_enable_suspend: idt_enable_suspend { + /* sleep state */ + mux { + /* GPIO 36 idt enable pin */ + pins = "gpio104"; + function = "gpio"; + }; + + config { + pins = "gpio104"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + adc2_switch_gpio_ctrl { + adc2_switch_gpio_idle: adc2_switch_idle { + mux { + pins = "gpio142"; + function = "gpio"; + }; + config { + pins = "gpio142"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + adc2_switch_gpio_active: adc2_switch_active { + mux { + pins = "gpio142"; + function = "gpio"; + }; + config { + pins = "gpio142"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + + sbu_uart_en_ctrl { + sbu_uart_en_idle: uart_audio_en_idle { + mux { + pins = "gpio25"; + function = "gpio"; + }; + config { + pins = "gpio25"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + sbu_uart_en_active: uart_audio_en_active { + mux { + pins = "gpio25"; + function = "gpio"; + }; + config { + pins = "gpio25"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + + ai_key_ctrl { + ai_key_active_default: ai_key_active { + mux { + pins = "gpio97"; + function = "gpio"; + }; + config { + pins = "gpio97"; + drive-strength = <2>; + bias-pull-up; + input-enable; + }; + + }; + + ai_key_idle_default: ai_key_idle { + mux { + pins = "gpio97"; + function = "gpio"; + }; + config { + pins = "gpio97"; + drive-strength = <2>; + bias-pull-up; + input-enable; + }; + }; + }; + + pcie1 { + pcie1_wake_default: pcie1_wake_default { + mux { + pins = "gpio114"; + function = "gpio"; + }; + + config { + pins = "gpio114"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + nfc { + nfc_int_active: nfc_int_active { + /* active state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_int_suspend: nfc_int_suspend { + /* sleep state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_active: nfc_enable_active { + /* active state */ + mux { + /* 41: NFC ENABLE 42:ESE Enable */ + pins = "gpio48", "gpio103"; + function = "gpio"; + }; + + config { + pins = "gpio48", "gpio103"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_suspend: nfc_enable_suspend { + /* sleep state */ + mux { + /* 41: NFC ENABLE 42:ESE Enable */ + pins = "gpio48", "gpio103"; + function = "gpio"; + }; + + config { + pins = "gpio48", "gpio103"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + + nfc_clk_req_active: nfc_clk_req_active { + /* active state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_clk_req_suspend: nfc_clk_req_suspend { + /* sleep state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + }; + +}; +//camera voltage start +&cam_sensor_mclk0_active { + /* MCLK0 */ + mux { + pins = "gpio13"; + function = "cam_mclk"; + }; + + config { + pins = "gpio13"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk0_suspend { + /* MCLK0 */ + mux { + pins = "gpio13"; + function = "cam_mclk"; + }; + + config { + pins = "gpio13"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk1_active { + /* MCLK1 */ + mux { + pins = "gpio14"; + function = "cam_mclk"; + }; + + config { + pins = "gpio14"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk1_suspend { + /* MCLK1 */ + mux { + pins = "gpio14"; + function = "cam_mclk"; + }; + + config { + pins = "gpio14"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk2_active { + /* MCLK2 */ + mux { + pins = "gpio15"; + function = "cam_mclk"; + }; + + config { + pins = "gpio15"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk2_suspend { + /* MCLK2 */ + mux { + pins = "gpio15"; + function = "cam_mclk"; + }; + + config { + pins = "gpio15"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk3_active { + /* MCLK3 */ + mux { + pins = "gpio16"; + function = "cam_mclk"; + }; + + config { + pins = "gpio16"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk3_suspend { + /* MCLK3 */ + mux { + pins = "gpio16"; + function = "cam_mclk"; + }; + + config { + pins = "gpio16"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_active_rear { + /* RESET REAR2 */ + mux { + pins = "gpio30", "gpio59"; + function = "gpio"; + }; + + config { + pins = "gpio30", "gpio59"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_rear { + /* RESET REAR2 */ + mux { + pins = "gpio30", "gpio59"; + function = "gpio"; + }; + + config { + pins = "gpio30", "gpio59"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +&cam_sensor_active_rear_aux { + /* RESET REARAUX, VANA REARAUX */ + mux { + pins = "gpio23", "gpio29"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio29"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_rear_aux { + /* RESET REARAUX, VANA REARAUX */ + mux { + pins = "gpio23", "gpio29"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio29"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +&cam_sensor_active_front { + /* RESET FRONT, VANA FRONT*/ + mux { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio54","gpio118"; + function = "gpio"; + }; + + config { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio54","gpio118"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_front { + /* RESET FRONT, VANA FRONT*/ + mux { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio54","gpio118"; + function = "gpio"; + }; + + config { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio54","gpio118"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +&cam_sensor_active_iris { + /* RESET ULTRA, VANA VDIG ULTRA*/ + mux { + pins = "gpio28","gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio28","gpio94"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_iris { + /* RESET ULTRA, VANA VDIG ULTRA*/ + mux { + pins = "gpio28","gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio28","gpio94"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +//camera voltage end diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-sm8150-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-sm8150-camera-sensor-mtp.dtsi new file mode 100644 index 000000000000..3f716ecc360a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-sm8150-camera-sensor-mtp.dtsi @@ -0,0 +1,532 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +&soc { + led_flash_rear: qcom,camera-flash@0 { + cell-index = <0>; + reg = <0x00 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch2>; + status = "ok"; + }; + + led_flash_rear_aux1: qcom,camera-flash@1 { + cell-index = <1>; + reg = <0x01 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch2>; + status = "ok"; + }; + + led_flash_front: qcom,camera-flash@2 { + cell-index = <2>; + reg = <0x02 0x00>; + compatible = "qcom,camera-flash"; + wled-flash-support; + flash-source = <&wled_flash>; + torch-source = <&wled_torch>; + switch-source = <&wled_switch>; + status = "ok"; + }; + + led_flash_rear_aux2: qcom,camera-flash@3 { + cell-index = <3>; + reg = <0x03 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch2>; + status = "ok"; + }; + + camera_viodd_ldo: gpio-regulator@0 { + compatible = "regulator-fixed"; + reg = <0x00 0x00>; + regulator-name = "camera_viodd_ldo"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&tlmm 132 0>; + vin-supply = <&pm8150_s4>; + }; + + actuator_rear_regulator: gpio-regulator@1 { + compatible = "regulator-fixed"; + reg = <0x01 0x00>; + regulator-name = "actuator_rear_regulator"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&tlmm 24 0>; + vin-supply = <&pm8150l_bob>; + }; + + actuator_rear_aux_ldo: gpio-regulator@2 { + compatible = "regulator-fixed"; + reg = <0x02 0x00>; + regulator-name = "actuator_rear_aux_ldo"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&tlmm 152 0>; + vin-supply = <&pm8150l_bob>; + }; + + actuator_ultra_ldo: gpio-regulator@3 { + compatible = "regulator-fixed"; + reg = <0x03 0x00>; + regulator-name = "actuator_ultra_ldo"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&tlmm 95 0>; + vin-supply = <&pm8150l_bob>; + }; +}; + +&cam_cci1 { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + status = "ok"; + }; + + actuator_rear: qcom,actuator@0 { + cell-index = <0>; + reg = <0x0>; + compatible = "qcom,actuator"; + cci-device = <0>; + cci-master = <1>; + cam_vaf-supply = <&actuator_rear_regulator>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + actuator_rear_aux: qcom,actuator@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,actuator"; + cci-device = <1>; + cci-master = <1>; + cam_vaf-supply = <&actuator_rear_aux_ldo>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + actuator_front: qcom,actuator@2 { + cell-index = <2>; + reg = <0x2>; + compatible = "qcom,actuator"; + cci-master = <1>; + cam_vaf-supply = <&actuator_rear_aux_ldo>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + actuator_ultra_rear: qcom,actuator@3 { + cell-index = <3>; + reg = <0x3>; + compatible = "qcom,actuator"; + cci-master = <0>; + cam_vaf-supply = <&actuator_ultra_ldo>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + eeprom_rear: qcom,eeprom@0 { + cell-index = <0>; + reg = <0>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150_s5>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 1904000 2856000 0>; + rgltr-max-voltage = <1800000 2040000 3008000 0>; + rgltr-load-current = <180000 112000 519000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rear>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rear>; + gpios = <&tlmm 14 0>, + <&tlmm 30 0>, + <&tlmm 59 0>; + gpio-reset = <1>; + gpio-vdig = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VDIG0"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + eeprom_rear_aux: qcom,eeprom@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150_s5>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 1904000 2856000 0>; + rgltr-max-voltage = <1800000 2040000 3008000 0>; + rgltr-load-current = <180000 112000 519000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rear>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rear>; + gpios = <&tlmm 14 0>, + <&tlmm 30 0>, + <&tlmm 59 0>; + gpio-reset = <1>; + gpio-vdig = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VDIG0"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + eeprom_rear_ultra: qcom,eeprom@3 { + cell-index = <3>; + reg = <0x3>; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0xa0>; + qcom,num-blocks = <1>; + qcom,page0 = <0 0 0 0 0 0 >; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,mem0 = <8192 0x0 2 0 1 0>; + qcom,cam-power-seq-type = "cam_vio"; + qcom,cam-power-seq-val = <1>; + qcom,cam-power-seq-cfg-val = <1>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk";//, "cam_bob"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 3008000 2856000 0>; + rgltr-max-voltage = <1800000 4000000 3000000 0>; + rgltr-load-current = <180000 2000000 300000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_iris>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_iris>; + gpios = <&tlmm 13 0>,//mclk + <&tlmm 28 0>,//reset + <&tlmm 94 0>;//vana,vdig + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK3", + "CAM_RESET3", + "CAM_VDIG3"; + sensor-position = <0>; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + eeprom_front: qcom,eeprom@2 { + cell-index = <2>; + reg = <0x2>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk";//, "cam_bob"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 3008000 3000000 0>; + rgltr-max-voltage = <1800000 4000000 3000000 0>; + rgltr-load-current = <180000 2000000 30000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_front>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_front>; + gpios = <&tlmm 15 0>,//mclk + <&tlmm 54 0>,//reset + //<&tlmm 132 0>,//vio + <&tlmm 118 0>;//vana,vidg + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2"; + sensor-position = <1>; + sensor-mode = <0>; + cci-device = <1>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + qcom,cam-sensor@0 { + cell-index = <0>; + compatible = "qcom,cam-sensor"; + reg = <0x0>; + csiphy-sd-index = <1>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + led-flash-src = <&led_flash_rear>; + actuator-src = <&actuator_rear>; + eeprom-src = <&eeprom_rear>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150_s5>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 1904000 2856000 0>; + rgltr-max-voltage = <1800000 2040000 3008000 0>; + rgltr-load-current = <180000 112000 519000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rear>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rear>; + gpios = <&tlmm 14 0>, + <&tlmm 30 0>, + <&tlmm 59 0>; + gpio-reset = <1>; + gpio-vdig = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VDIG0"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + + qcom,cam-sensor@1 { + cell-index = <1>; + compatible = "qcom,cam-sensor"; + reg = <0x1>; + csiphy-sd-index = <3>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + actuator-src = <&actuator_rear_aux>; + led-flash-src = <&led_flash_rear_aux1>; + eeprom-src = <&eeprom_rear_aux>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vdig-supply = <&pm8150_l17>; + cam_vana-supply = <&pm8150l_bob>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk";//, "cam_bob"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 3008000 3000000 0>; + rgltr-max-voltage = <1800000 4000000 3000000 0>; + rgltr-load-current = <180000 2000000 300000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_rear_aux>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_rear_aux>; + gpios = <&tlmm 16 0>,//mclk + <&tlmm 23 0>,//reset + <&tlmm 29 0>;//vana,vdig + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_VANA1"; + sensor-mode = <0>; + cci-device = <1>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + + qcom,cam-sensor@2 { + cell-index = <2>; + compatible = "qcom,cam-sensor"; + reg = <0x02>; + csiphy-sd-index = <2>; + sensor-position-roll = <270>; + sensor-position-pitch = <0>; + sensor-position-yaw = <0>; + eeprom-src = <&eeprom_front>; + actuator-src = <&actuator_front>; + //led-flash-src = <&led_flash_front>; + cam_vio-supply = <&camera_viodd_ldo>; + //cam_bob-supply = <&pm8150l_bob>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk";//, "cam_bob"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 3008000 3000000 0>; + rgltr-max-voltage = <1800000 4000000 3000000 0>; + rgltr-load-current = <180000 2000000 30000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_front>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_front>; + gpios = <&tlmm 15 0>,//mclk + <&tlmm 54 0>,//reset + //<&tlmm 132 0>,//vio + <&tlmm 118 0>;//vana,vidg + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_VANA2"; + sensor-mode = <0>; + cci-device = <1>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + +qcom,cam-sensor@3 { + cell-index = <3>; + compatible = "qcom,cam-sensor"; + reg = <0x03>; + csiphy-sd-index = <0>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + actuator-src = <&actuator_ultra_rear>; + eeprom-src = <&eeprom_rear_ultra>; + led-flash-src = <&led_flash_rear_aux2>; + cam_vio-supply = <&camera_viodd_ldo>; + //cam_bob-supply = <&pm8150l_bob>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk";//, "cam_bob"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 3008000 2856000 0>; + rgltr-max-voltage = <1800000 4000000 3000000 0>; + rgltr-load-current = <180000 2000000 300000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_iris>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_iris>; + gpios = <&tlmm 13 0>,//mclk + <&tlmm 28 0>,//reset + <&tlmm 94 0>;//vana,vdig + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK3", + "CAM_RESET3", + "CAM_VDIG3"; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; +}; + + diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-sm8150.dtsi new file mode 100644 index 000000000000..5a3a024b5cff --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-sm8150.dtsi @@ -0,0 +1,697 @@ +/* +this file is for attribution only of cepheus +And public attribution of xiaomi platforms(like F1 and so and) +*/ +#include "cepheus-pinctrl.dtsi" +#include "../common/xiaomi-sm8150-common.dtsi" +#include "cepheus-sm8150-camera-sensor-mtp.dtsi" + +#include "../common/smb1390.dtsi" + +&vendor { + mtp_batterydata: qcom,battery-data { + qcom,batt-id-range-pct = <15>; + #include "../common/battery/batterydata-F1-atl-3300mah.dtsi" + #include "../common/battery/batterydata-F1-coslight-3300mah.dtsi" + #include "../common/battery/fg-gen4-batterydata-alium-3600mah.dtsi" + }; +}; + +&pm8150b_fg { + qcom,battery-data = <&mtp_batterydata>; + qcom,rapid-soc-dec-en; + qcom,fg-sys-term-current = <(-400)>; + qcom,fg-cutoff-voltage = <3400>; + qcom,fg-cutoff-current = <200>; + qcom,fg-empty-voltage = <3100>; + qcom,fg-batt-temp-delta = <6>; + qcom,fg-force-load-profile; + /* ESR fast calibration */ + qcom,fg-esr-timer-chg-fast = <0 7>; + qcom,fg-esr-timer-dischg-fast = <0 7>; + qcom,fg-esr-timer-chg-slow = <0 96>; + qcom,fg-esr-timer-dischg-slow = <0 96>; + qcom,fg-esr-cal-soc-thresh = <26 230>; + qcom,fg-esr-cal-temp-thresh = <10 40>; +}; + +&pm8150b_charger { + qcom,sec-charger-config = <1>; + qcom,usb-icl-ua = <2800000>; + qcom,fcc-max-ua = <4800000>; + qcom,fv-max-uv = <4400000>; + qcom,dc-icl-ua = <1000000>; + qcom,auto-recharge-soc = <99>; + qcom,chg-term-src = <1>; + qcom,chg-term-current-ma = <(-220)>; + qcom,thermal-mitigation = <3000000 2800000 2600000 2400000 2200000 2100000 2000000 + 1800000 1600000 1500000 1400000 1200000 1000000 900000 + 800000 500000>; + qcom,thermal-mitigation-icl + = <2800000 2700000 2600000 2400000 2400000 2400000 2400000 + 2400000 2400000 2100000 1900000 1700000 1500000 1300000 + 1000000 750000>; + qcom,thermal-mitigation-dcp + = <1800000 1800000 1800000 1800000 1800000 1800000 1800000 + 1800000 1800000 1700000 1600000 1400000 1200000 1100000 + 1100000 1000000>; + qcom,thermal-mitigation-qc2 + = <1500000 1500000 1500000 1500000 1450000 1400000 1350000 + 1300000 1300000 1200000 1000000 900000 850000 750000 + 650000 500000>; + qcom,thermal-fcc-qc3-normal + = <3200000 3000000 2800000 2600000 2500000 2400000 2300000 + 2200000 2100000 1800000 1600000 1400000 1200000 1000000 + 750000 750000>; + qcom,thermal-fcc-qc3-cp + = <3600000 3600000 3600000 3600000 3200000 3200000 3200000 + 3200000 3100000 2800000 2400000 2200000 2000000 1300000 + 750000 700000>; + qcom,thermal-fcc-qc3-classb-cp + = <4800000 4700000 4600000 4500000 4400000 4200000 4200000 + 4200000 4000000 3600000 3400000 3200000 3000000 2200000 + 1000000 700000>; + qcom,thermal-mitigation-pd-base + = <3000000 2800000 2600000 2500000 2500000 2500000 2500000 + 2500000 2500000 2400000 2200000 2000000 1600000 1300000 + 1000000 500000>; + qcom,thermal-fcc-pps-cp + = <4800000 4700000 4600000 4500000 4400000 4200000 4200000 + 4200000 4000000 3600000 3400000 3200000 3000000 2200000 + 1000000 750000>; + qcom,thermal-mitigation-dc + = <2100000 2000000 1800000 1600000 1400000 1200000 1100000 + 1000000 900000 800000 700000 600000 500000 400000 + 300000 200000>; + qcom,thermal-mitigation-epp + = <1200000 1200000 1200000 1100000 1100000 1000000 1000000 + 1000000 900000 700000 700000 600000 500000 400000 + 300000 200000>; + qcom,thermal-mitigation-bpp-qc3 + = <1400000 1300000 1200000 1200000 1100000 1000000 900000 + 800000 700000 700000 700000 600000 500000 400000 + 300000 200000>; + qcom,thermal-mitigation-bpp-qc2 + = <1100000 1100000 1100000 1100000 1100000 1000000 1000000 + 1000000 700000 700000 700000 600000 500000 400000 + 300000 200000>; + qcom,thermal-mitigation-bpp + = <800000 800000 800000 800000 800000 800000 800000 + 800000 800000 700000 700000 600000 500000 400000 + 300000 200000>; + + io-channels = <&pm8150b_vadc ADC_MID_CHG_DIV6>, + <&pm8150b_vadc ADC_USB_IN_V_16>, + <&pm8150b_vadc ADC_USB_IN_I>, + <&pm8150b_vadc ADC_SBUx>, + <&pm8150b_vadc ADC_VPH_PWR>, + <&pm8150b_vadc ADC_CHG_TEMP>; + io-channel-names = "mid_voltage", + "usb_in_voltage", + "usb_in_current", + "sbux_res", + "vph_voltage", + "chg_temp"; + qcom,battery-data = <&mtp_batterydata>; + dpdm-supply = <&usb2_phy0>; + qcom,distinguish-qc-class-ab; + qcom,lpd-disable; + qcom,sw-jeita-enable; + qcom,wd-bark-time-secs = <16>; + qcom,support-wireless; + qcom,dynamic-fv-enable; +}; + +&ext_5v_boost { + status = "ok"; +}; + +&pm8150b_pdphy { + vbus-supply = <&ext_5v_boost>; +}; + +&qupv3_se4_i2c { + status = "ok"; + tas2557@4c { + compatible = "ti,tas2557"; + reg = <0x4c>; + //ti,cdc-reset-gpio = <&tlmm 59 0>; + ti,irq-gpio = <&tlmm 60 0>; + ti,i2s-bits = <16>; + ti,bypass-tmax = <0>; + }; + + fsa4480@43 { + status = "disabled"; + }; + + cs35l41@40 { + #sound-dai-cells = <1>; + compatible = "cirrus,cs35l41"; + cs,cdc-reset-gpio = <&tlmm 89 0x01>; + reg = <0x40>; + pinctrl-names = "cs35l41_irq_default"; + pinctrl-0 = <&cs35l41_int_default>; + interrupt-parent = <&tlmm>; + interrupts = <10 8>; + + cirrus,temp-warn_threshold = <3>; + cirrus,boost-peak-milliamp = <4000>; + cirrus,boost-ind-nanohenry = <1000>; + cirrus,boost-cap-microfarad = <15>; + cirrus,gpio-config2 { + cirrus,gpio-src-select = <0x4>; + cirrus,gpio-output-enable; + }; + }; + +}; + +&smb1390 { + pinctrl-names = "default"; + pinctrl-0 = <&smb_stat_default>; + status = "ok"; +}; + +&smb1390_charger { + io-channels = <&pm8150b_vadc ADC_AMUX_THM2>; + io-channel-names = "cp_die_temp"; + status = "ok"; +}; + +&usb0 { + dwc3@a600000 { + usb-phy = <&usb2_phy0>, <&usb_nop_phy>; + maximum-speed = "high-speed"; + }; +}; + +&usb2_phy0 { + qcom,param-override-seq = + <0x84 0x70 + 0x2c 0x74>; +}; + +&usb_qmp_dp_phy { + status = "disabled"; +}; + +&usb1 { + extcon = <&extcon_usb1>; + status = "disabled"; +}; + +&usb2_phy1 { + status = "disabled"; +}; + +&usb_qmp_phy { + status = "disabled"; +}; + +&soc { + touch_vddio_vreg: touch_vddio_vreg { + compatible = "regulator-fixed"; + regulator-name = "disp_vddio_vreg"; + startup-delay-us = <4000>; + enable-active-high; + regulator-boot-on; + gpio = <&tlmm 84 0>; + }; + + vdd_boost_vreg: vdd_boost_vreg { + compatible = "regulator-fixed"; + regulator-name = "vdd_boost_vreg"; + startup-delay-us = <4000>; + enable-active-high; + regulator-always-on; + gpio = <&pm8150b_gpios 5 0>; + }; + + disp_vci_vreg: disp_vci_vreg { + compatible = "regulator-fixed"; + regulator-name = "disp_vci_vreg"; + start-delay-us = <4000>; + enable-active-high; + regulator-boot-on; + gpio = <&tlmm 21 0>; + }; + + fingerprint_goodix { + compatible = "goodix,fingerprint"; + goodix,gpio-reset = <&tlmm 37 0x0>; + goodix,gpio-irq = <&tlmm 120 0x0>; + fp-gpio-pwr = <&tlmm 125 0>; + status = "ok"; + }; + + gpio_keys { + pinctrl-0 = <&ai_key_active_default>; + ai_key { + label = "ai_key"; + gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; + linux,input-type = <1>; + linux,code = ; + gpio-key,wakeup; + debounce-interval = <39>; + gpio-key,level-trigger; + }; + }; + + xiaomi_touch { + compatible = "xiaomi-touch"; + status = "ok"; + touch,name = "xiaomi-touch"; + }; +}; + +&qupv3_se17_i2c { + status = "ok"; + fts@49 { + compatible = "st,fts"; + reg = <0x49>; + interrupt-parent = <&tlmm>; + interrupts = <122 0x2008>; + pinctrl-names = "pmx_ts_active", "pmx_ts_suspend"; + pinctrl-0 = <&ts_active>; + pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; + vdd-supply = <&touch_vddio_vreg>; + avdd-supply = <&pm8150l_l1>; + fts,pwr-reg-name = "avdd"; + fts,bus-reg-name = "vdd"; + fts,irq-gpio = <&tlmm 122 0x2008>; + fts,irq-gpio-name = "fts_irq"; + fts,reset-gpio-enable; + fts,reset-gpio = <&tlmm 12 0x00>; + fts,reset-gpio-name = "fts_rst"; + fts,irq-flags = <0x2008>; /* IRQF_ONESHOT | IRQF_TRIGGER_LOW */ + fts,x-max = <1080>; + fts,y-max = <2340>; + fts,default-fw-name = "st_fts_f1.ftb"; + fts,config-array-size = <1>; + fts,dump-click-count; + fts,cfg_0 { + fts,tp-vendor = <0x48>; + fts,fw-name = "st_fts_f1.ftb"; + fts,limit-name = "stm_fts_production_limits.csv"; + fts,clicknum-file-name = "fts+sdc"; + }; + }; +}; + +&qupv3_se4_i2c { + status = "ok"; + idtp9220: idtp9220@3b { + compatible = "idt,p9220"; + reg = <0x3b>; + idt,irq = <&tlmm 90 0x00>; + idt,enable = <&tlmm 104 0x00>; + idt,wpc-det = <&pm8150b_gpios 7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default", "idt_active", "idt_suspend"; + pinctrl-0 = <&power_good_default>; + pinctrl-1 = <&idt_int_active &idt_enable_active>; + pinctrl-2 = <&idt_int_suspend &idt_enable_suspend>; + }; +}; + + +&qupv3_se1_spi { + status = "ok"; + irled@0 { + compatible = "ir-spi"; + reg = <0x0>; + status = "ok"; + spi-max-frequency = <19200000>; + }; +}; + +&pm8150l_lpg { + qcom,lut-patterns = <0 1 2 3 4 5 7 9 11 13 15 + 13 11 9 7 5 4 3 2 1 0>; +}; + +&pwm_lpg1 { + qcom,lpg-chan-id = <1>; + qcom,ramp-step-ms = <100>; + qcom,ramp-pause-hi-count = <2>; + qcom,ramp-pause-lo-count = <2>; + qcom,ramp-low-index = <0>; + qcom,ramp-high-index = <20>; + qcom,ramp-from-low-to-high; + qcom,ramp-pattern-repeat; +}; + +&red_led { + label = "white"; +}; + +&green_led { + status = "disabled"; +}; + +&blue_led { + status = "disabled"; +}; + +&sde_dsi { + vcie-supply = <&disp_vci_vreg>; +}; + +&dsi_samsung_fhd_ea8076_f1mp_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_external_supply>; +}; + +&dsi_samsung_fhd_ea8076_f1p2_2_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_external_supply>; +}; + +&dsi_samsung_fhd_ea8076_f1p2_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_external_supply>; +}; + +&pm8150b_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + wp_therm { + reg = ; + label = "wp_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + vcoin { + reg = ; + label = "vcoin"; + qcom,pre-scaling = <1 3>; + }; + + conn_therm { + reg = ; + label = "conn_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + chg_sbux { + reg = ; + label = "chg_sbux"; + qcom,pre-scaling = <1 3>; + }; + + mid_chg_div6 { + reg = ; + label = "chg_mid"; + qcom,pre-scaling = <1 6>; + }; + + usb_in_i_uv { + reg = ; + label = "usb_in_i_uv"; + qcom,pre-scaling = <1 1>; + }; + + usb_in_v_div_16 { + reg = ; + label = "usb_in_v_div_16"; + qcom,pre-scaling = <1 16>; + }; +}; + +&pm8150_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + vcoin { + reg = ; + label = "vcoin"; + qcom,pre-scaling = <1 3>; + }; + + xo_therm { + reg = ; + label = "xo_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + quiet_therm { + reg = ; + label = "quiet_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + pa_therm0 { + reg = ; + label = "pa_therm0"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm8150l_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + cam_therm0 { + reg = ; + label = "cam_therm0"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + cam_therm1 { + reg = ; + label = "cam_therm1"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + pa_therm1 { + reg = ; + label = "pa_therm1"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm8150b_adc_tm { + wp_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm8150_adc_tm { + xo_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + quiet_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + pa_therm0 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm8150l_adc_tm { + cam_therm0 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + cam_therm1 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + pa_therm1 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&thermal_zones { + wp_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150b_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + xo_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_XO_THERM_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + quiet_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + pa_therm0 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_AMUX_THM2_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + cam_therm0 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + cam_therm1 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM2_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + pa_therm1 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM3_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; +}; + +&pm8150b_haptics { + qcom,vmax-mv = <2800>; + qcom,play-rate-us = <5102>; + + wf_0 { + /* CLICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_1 { + /* DOUBLE CLICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 3e]; + qcom,wf-brake-pattern = [03 01 01 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_2 { + /* TICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 3e]; + qcom,wf-brake-pattern = [03 01 01 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_3 { + /* THUD */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_4 { + /* POP */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_5 { + /* HEAVY CLICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 7e 7e]; + qcom,wf-brake-pattern = [03 03 01 00]; + qcom,wf-play-rate-us = <5102>; + }; +}; + +&soc { + ssc_sensors: qcom,msm-ssc-sensors { + compatible = "qcom,msm-ssc-sensors"; + status = "ok"; + qcom,firmware-name = "slpi_cp"; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-E5G-coslight-3700mah.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-E5G-coslight-3700mah.dtsi new file mode 100644 index 000000000000..ff2a37519ffd --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-E5G-coslight-3700mah.dtsi @@ -0,0 +1,136 @@ + +qcom,3811462_xiaomi_bm3gcos_3700mah_slave_jan3rd2019 { + qcom,profile-revision = <24>; + /* #3811462_Xiaomi_BM3Gcos_3700mAh_Slave_Jan3rd2019*/ + qcom,fastchg-current-ma = <3700>; + qcom,jeita-fcc-ranges = <0 50 370000 + 51 100 1110000 + 101 150 1850000 + 151 450 3700000 + 451 580 1850000>; + qcom,jeita-fv-ranges = <0 50 4450000 + 51 100 4450000 + 101 150 4450000 + 151 450 4450000 + 451 580 4100000>; + qcom,max-voltage-uv = <4450000>; + qcom,fg-cc-cv-threshold-mv = <4440>; + qcom,nom-batt-capacity-mah = <3800>; + qcom,batt-id-kohm = <100>; + qcom,battery-beta = <4250>; + qcom,therm-room-temp = <100000>; + qcom,battery-type = "e5g_cos"; + qcom,therm-coefficients = <0x2318 0xd0c 0xdaf7 0xc556 0x848d>; + qcom,therm-center-offset = <0x70>; + qcom,therm-pull-up = <100>; + qcom,rslow-normal-coeffs = <0x4a 0x15 0x95 0x12>; + qcom,rslow-low-coeffs = <0x9f 0x06 0x70 0x1a>; + qcom,checksum = <0xB9FD>; + qcom,gui-version = "PM855GUI - 1.0.0.13"; + qcom,fg-profile-data = [ + 09 00 99 EA + EF ED 05 F2 + B6 07 00 00 + 69 BD 45 83 + 01 80 15 8C + 8C 80 09 80 + 13 00 4A 15 + 95 12 1B 06 + EB F3 CE 07 + 32 00 76 EA + 01 E4 5B DA + D1 02 95 E5 + 67 BD 1E 2A + 26 0B 64 D3 + 60 00 4C 00 + 4F 00 43 00 + 2F 00 31 00 + 35 00 3E 00 + 40 00 48 00 + 43 00 60 00 + 42 00 4F 00 + 58 00 52 00 + 4F 00 9C 00 + 6C 64 5B 00 + 5E 00 74 00 + 60 F0 57 00 + 5F 00 83 10 + 67 10 67 00 + AD 20 76 40 + 68 60 64 09 + 71 00 D8 00 + C3 1E 6D 0E + C1 03 23 04 + 82 1C 36 0B + 8E 0D F4 22 + E4 1A 5B 42 + 23 5C 46 02 + 5A 11 33 1F + ED 05 61 0A + 6C FE C8 1C + 49 FA 24 05 + 69 03 2B 17 + FE 23 76 44 + 26 52 6A 13 + 40 1F F7 ED + 4C E2 0F ED + DE 1C 4D E3 + FB 04 C5 BB + A7 17 66 83 + 37 85 1F A3 + 7C A8 09 80 + 54 FA BF 0D + 8F FA 91 04 + 00 00 D7 D5 + 66 EA 02 10 + 5D E2 7B CC + 41 01 0F F0 + BF BC 91 03 + CD 04 E6 00 + CE 07 32 00 + 81 01 A3 02 + 2F 05 29 02 + F7 02 F3 05 + C3 06 AA 02 + F0 03 50 00 + 3F 00 41 00 + 40 64 40 00 + 3D 08 40 10 + 3C 08 3F 00 + 54 00 79 08 + 5C 08 48 00 + 58 28 58 50 + 61 70 6F 07 + 4F 00 57 00 + 57 08 67 00 + FF 00 57 00 + 51 10 5F 10 + 61 00 78 28 + 91 48 5D 58 + 5D 0D 50 00 + 5B 00 FF 08 + D8 00 B5 22 + 03 05 BD 12 + A2 15 3F 1D + 60 22 F4 4C + 6D 5B 93 18 + D0 03 03 04 + D6 02 7D 0E + 3F 0A 43 20 + D8 04 34 03 + 96 05 D3 1C + 04 03 E9 05 + 58 02 74 18 + 0A 02 AF 05 + A5 03 6B 00 + A0 1F 54 05 + 16 03 80 05 + A6 1C 56 03 + 7F 05 03 03 + 7E 18 C6 03 + F2 05 1D 03 + 5F 00 88 01 + C0 00 FA 00 + 67 0F 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F1-atl-3300mah.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F1-atl-3300mah.dtsi new file mode 100644 index 000000000000..e749822f0db0 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F1-atl-3300mah.dtsi @@ -0,0 +1,156 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +qcom,scud { + qcom,profile-revision = <24>; + /* #3675702_Xiaomi_F1sun_3300mAh_averaged_MasterSlave_Oct22nd2018*/ + qcom,fastchg-current-ma = <4800>; + qcom,jeita-fcc-ranges = <0 50 300000 + 51 100 1600000 + 101 150 3200000 + 151 450 4800000 + 451 580 1600000>; + qcom,jeita-fv-ranges = <0 50 4400000 + 51 100 4400000 + 101 150 4400000 + 151 450 4400000 + 451 580 4100000>; + qcom,step-chg-ranges = <3600000 4200000 3000000 + 4201000 4300000 3000000 + 4301000 4340000 2500000>; + qcom,dynamic-fv-ranges = <0 100 4400000 + 101 200 4380000 + 201 300 4360000 + 301 400 4340000 + 401 500 4340000>; + qcom,max-voltage-uv = <4400000>; + qcom,fg-cc-cv-threshold-mv = <4390>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,batt-id-kohm = <68>; + qcom,battery-beta = <4250>; + qcom,therm-room-temp = <100000>; + qcom,battery-type = "f1_atl"; + qcom,therm-coefficients = <0x2318 0xd0c 0xdaf7 0xc556 0x848d>; + qcom,therm-center-offset = <0x70>; + qcom,therm-pull-up = <100>; + qcom,rslow-normal-coeffs = <0x85 0x01 0x71 0x13>; + qcom,rslow-low-coeffs = <0xc6 0x15 0x65 0x02>; + qcom,checksum = <0xBE6A>; + qcom,gui-version = "PM855GUI - 1.0.0.10"; + qcom,fg-profile-data = [ + A9 1F 09 EA + 30 D4 F1 DA + 38 D5 00 00 + 5A BD 85 8A + FA 87 7F A4 + 75 92 06 81 + 1B FC 85 01 + 71 13 39 FC + 86 01 CE 1F + 32 0A 5D EB + DA ED B1 D4 + 2D 0A 69 D4 + 27 BD E8 1A + AB FB 8F BA + 60 00 4E FC + 47 FD 44 F4 + 33 33 30 10 + 35 0B 43 00 + 40 01 43 00 + 43 00 60 00 + 37 00 3C 00 + 46 00 40 00 + 39 00 76 00 + 5C 64 46 00 + 3F 00 3D 08 + 60 00 4C 00 + 49 00 57 10 + 4D 10 47 00 + 86 28 5E 48 + 4F 60 46 0D + 4E 00 D8 F8 + FE 1F 0C 0D + D4 FA 17 06 + 89 1C 32 0B + C5 0D 67 2A + 18 17 85 42 + 1E 5D 45 02 + 6C 10 36 1F + 09 04 31 0A + 25 FD DD 1C + 05 02 A3 05 + BE 02 3F 17 + 1C 22 05 44 + 91 52 70 12 + 60 1F DE E5 + 4D CA E9 A4 + E5 1C 7D C9 + 8C 05 08 BB + 1C 17 D9 8B + BF 84 BF 93 + 83 A0 09 80 + D3 03 01 05 + 21 FC 8D FA + 00 F8 59 D5 + FF EA F6 07 + DD F3 10 CD + 92 18 16 F0 + 2F D7 26 02 + 57 05 2B 02 + CE 01 32 00 + 15 03 28 03 + D9 05 44 07 + 43 02 94 04 + 55 03 8F 05 + 51 03 49 00 + 3A 00 42 00 + 43 64 48 00 + 4C 00 42 08 + 49 00 4A 00 + 49 00 3B 10 + 3A 10 3A 00 + 4A 20 4C 48 + 56 58 64 0E + 42 00 4D 00 + 58 08 61 00 + 50 00 3F 00 + 3F 10 4F 10 + 4C 00 5B 20 + 6D 40 48 58 + 54 0F 59 00 + 50 00 31 08 + D8 00 9F 20 + C9 04 F1 0A + ED 0D D7 1C + 19 23 F5 45 + 17 52 71 18 + D6 03 FA 05 + F6 02 73 12 + 3F 0A DC 1F + 6D 05 A4 02 + 1C 06 C0 1C + 0E 03 EC 05 + 44 02 7A 18 + 81 03 8E 04 + 5B 02 6A 00 + 2D 20 03 05 + FC 02 C3 05 + E3 1C 1C 02 + BA 05 80 02 + 92 18 EF 02 + 90 05 CD 02 + 7C 00 3B 01 + C0 00 FA 00 + BB 0C 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F1-coslight-3300mah.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F1-coslight-3300mah.dtsi new file mode 100644 index 000000000000..6af436c42516 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F1-coslight-3300mah.dtsi @@ -0,0 +1,156 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +qcom,coslight { + qcom,profile-revision = <24>; + /* #3675676_Xiaomi_F1cos_3300mAh_averaged_MasterSlave_Oct22nd2018*/ + qcom,fastchg-current-ma = <4800>; + qcom,jeita-fcc-ranges = <0 50 300000 + 51 100 1600000 + 101 150 3200000 + 151 450 4800000 + 451 580 1600000>; + qcom,jeita-fv-ranges = <0 50 4400000 + 51 100 4400000 + 101 150 4400000 + 151 450 4400000 + 451 580 4100000>; + qcom,step-chg-ranges = <3600000 4200000 3000000 + 4201000 4300000 3000000 + 4301000 4340000 2500000>; + qcom,dynamic-fv-ranges = <0 100 4400000 + 101 200 4380000 + 201 300 4360000 + 301 400 4340000 + 401 500 4340000>; + qcom,max-voltage-uv = <4400000>; + qcom,fg-cc-cv-threshold-mv = <4390>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,batt-id-kohm = <100>; + qcom,battery-beta = <4250>; + qcom,therm-room-temp = <100000>; + qcom,battery-type = "f1_cos"; + qcom,therm-coefficients = <0x2318 0xd0c 0xdaf7 0xc556 0x848d>; + qcom,therm-center-offset = <0x70>; + qcom,therm-pull-up = <100>; + qcom,rslow-normal-coeffs = <0xe4 0x04 0x3a 0x12>; + qcom,rslow-low-coeffs = <0x21 0x15 0x15 0x06>; + qcom,checksum = <0xC822>; + qcom,gui-version = "PM855GUI - 1.0.0.10"; + qcom,fg-profile-data = [ + A9 1F 6C EA + 8F E5 33 EA + 8C E5 00 00 + C4 BC AC 8A + FC 87 EC 82 + 71 87 10 80 + 20 FC E4 04 + 3A 12 C9 04 + 0F 02 CE 1F + 32 0A FB EB + 65 ED 6E DC + F6 0A FA DC + 38 C5 3A 12 + 84 02 D1 D3 + 60 00 36 FC + 3D FD 3E F4 + 38 33 30 10 + 33 0B 37 00 + 3F 01 47 00 + 4D 00 60 00 + 36 00 3B 00 + 3D 00 38 00 + 35 00 6A 00 + 4D 64 42 00 + 3F F8 42 00 + 60 F0 55 00 + 5E 00 84 08 + 64 08 5D 00 + BB 20 7D 40 + 67 58 60 10 + 6C 00 D8 F8 + 05 1F EF 04 + 76 EB 6A 04 + D2 1C 6D 0A + F9 0C 5E 2B + 96 18 55 4B + CD 5C 20 02 + 6A 0F 86 1E + E3 05 A8 02 + 42 04 C5 1C + 78 02 9C 04 + FD 03 AC 17 + 1E 22 D0 45 + 19 5B 5F 11 + AB 1E C3 EE + FC CA 59 C7 + DE 1C A1 C9 + E4 04 AA BB + 92 17 D8 93 + 78 84 37 A2 + 78 A0 09 80 + 46 02 82 04 + 66 05 FF FB + 00 F8 68 DC + 06 EA F3 FF + 77 E3 FA C4 + 15 18 16 00 + 0E E7 FE 02 + F3 05 CB 02 + CE 01 32 00 + 15 03 CA 02 + D1 05 5B 03 + 27 04 F4 03 + 9D 03 94 02 + D2 05 54 00 + 3F 00 40 00 + 44 64 47 00 + 46 E8 47 F8 + 49 E8 48 00 + 4A 00 45 10 + 4F 10 3E 00 + 49 28 4B 48 + 53 58 62 0D + 40 00 4E F8 + 52 00 58 F8 + 4D 00 47 00 + 43 10 54 10 + 52 00 66 28 + 7E 48 4D 60 + 5D 0D 5E 00 + 50 F8 36 00 + D8 F0 A7 1E + 12 04 6F 0A + 87 0A E3 1C + 43 23 A7 45 + 95 5A 8C 18 + 08 02 B3 05 + 9E 03 5A 10 + 3F 0A 6B 1F + 33 04 E7 03 + D7 05 B6 1C + 4B 03 A7 05 + 92 02 6D 18 + 15 02 8D 05 + 00 02 64 00 + 05 1F EF 04 + 76 03 6A 04 + D2 1C 6D 02 + F9 04 5E 03 + 96 18 55 03 + CD 04 20 02 + 6A 00 56 01 + C0 00 FA 00 + F0 0C 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F11-gyu-4000mah.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F11-gyu-4000mah.dtsi new file mode 100644 index 000000000000..ec564aafcb64 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F11-gyu-4000mah.dtsi @@ -0,0 +1,159 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +qcom,gyu{ + qcom,profile-revision = <24>; + /* #3927828_Xiaomi_F11gyu_4000mAh_averaged_MasterSlave_2019*/ + qcom,fastchg-current-ma = <5100>; + qcom,jeita-fcc-ranges = <0 50 390000 + 51 100 1100000 + 101 150 2700000 + 151 450 5100000 + 451 580 1900000>; + qcom,jeita-fv-ranges = <0 50 4400000 + 51 100 4400000 + 101 150 4400000 + 151 450 4400000 + 451 580 4100000>; + qcom,step-chg-ranges = <3000000 3100000 1000000 + 3101000 3200000 1000000 + 3201000 3300000 1000000 + 3301000 4200000 5100000 + 4201000 4400000 4000000>; + qcom,dynamic-fv-ranges = <0 100 4400000 + 101 200 4380000 + 201 300 4360000 + 301 400 4340000 + 401 500 4340000>; + qcom,max-voltage-uv = <4400000>; + qcom,fg-cc-cv-threshold-mv = <4390>; + qcom,nom-batt-capacity-mah = <4000>; + qcom,batt-id-kohm = <100>; + qcom,battery-beta = <4250>; + qcom,therm-room-temp = <100000>; + qcom,battery-type = "f11_gyu"; + qcom,therm-coefficients = <0x2318 0xd0c 0xdaf7 0xc556 0x848d>; + qcom,therm-center-offset = <0x70>; + qcom,therm-pull-up = <100>; + qcom,rslow-normal-coeffs = <0x12 0x0c 0x6a 0x02>; + qcom,rslow-low-coeffs = <0x4e 0x15 0x4a 0x06>; + qcom,checksum = <0xD688>; + qcom,gui-version = "PM855GUI - 1.0.0.13"; + qcom,fg-profile-data = [ + 09 00 46 00 + 2D DC 99 E3 + FB E5 00 00 + 7C BD 24 8A + FC 87 02 8D + E7 82 FD 87 + 22 00 12 0C + 6A 02 58 05 + A1 FB CE 07 + 32 00 5F EB + DF ED 2F CD + C1 02 4D D3 + 36 AB 44 1A + E7 FA 52 BD + 60 00 39 00 + 3F 00 41 00 + 39 00 34 00 + 35 00 3B 00 + 43 00 4F 00 + 5A 00 60 00 + 3C 00 3F 00 + 3D 00 36 00 + 33 00 5C 00 + 4D 64 43 00 + 43 00 41 08 + 60 00 52 00 + 4F 00 5B 10 + 4E 10 44 00 + 85 28 60 48 + 52 60 4C 0B + 4B 00 D8 00 + C9 1F 69 0D + 60 02 AD 06 + 82 1C 35 0B + C5 0D 5C 22 + 13 17 F0 42 + 0B 54 A9 03 + 6C 12 36 1F + F4 FD 40 0A + 85 FE D8 1C + 1A 02 65 05 + 0B 0B 17 18 + 4D 23 2A 45 + 59 53 6D 12 + 12 1F 39 EC + 24 CA 2F C5 + D6 1C B4 C9 + 97 04 0B BA + BF 17 81 8B + F9 84 95 93 + 77 A0 09 80 + 16 FA 6D 04 + 24 02 05 02 + 00 F8 4C DD + C5 EA F8 FF + 07 E2 C2 BD + 78 18 16 F8 + B3 D5 38 02 + 85 06 1C 01 + CE 07 32 00 + 07 03 79 02 + 06 05 41 03 + 26 02 4F 04 + 63 02 89 02 + CD 05 53 00 + 3F 00 40 00 + 42 64 45 00 + 46 F8 47 00 + 49 00 47 00 + 49 00 41 08 + 4F 08 3F 00 + 46 20 49 48 + 50 58 5D 0E + 40 00 46 00 + 4E 08 56 F8 + 49 00 46 00 + 3B 10 48 10 + 4B 00 5C 28 + 6C 48 48 58 + 53 0D 4D 00 + 47 00 33 08 + D8 F8 8D 1F + 8F 04 56 0B + 35 0F F6 1C + CD 22 69 44 + AF 5B 96 18 + ED 03 D8 05 + 45 03 6E 0F + 3F 0A E4 1F + 64 05 A5 02 + 3F 04 BB 1C + 38 03 BC 05 + 7A 02 7F 18 + 0F 02 94 05 + F4 03 68 00 + 97 1F 99 05 + 99 02 31 04 + C2 1C A8 02 + 92 04 D5 03 + 96 18 66 03 + A4 04 4D 02 + 6B 00 58 01 + C0 00 FA 00 + A9 0F 00 00 + ]; +}; + diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F11-sun-4000mah.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F11-sun-4000mah.dtsi new file mode 100644 index 000000000000..b446defee8ec --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/batterydata-F11-sun-4000mah.dtsi @@ -0,0 +1,159 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +qcom,sun { + qcom,profile-revision = <24>; + /* #3827828_Xiaomi_F11sun_4000mAh_averaged_MasterSlave_Jan23rd2019*/ + qcom,fastchg-current-ma = <5100>; + qcom,jeita-fcc-ranges = <0 50 390000 + 51 100 1100000 + 101 150 2700000 + 151 450 5100000 + 451 580 1900000>; + qcom,jeita-fv-ranges = <0 50 4400000 + 51 100 4400000 + 101 150 4400000 + 151 450 4400000 + 451 580 4100000>; + qcom,step-chg-ranges = <3000000 3100000 1000000 + 3101000 3200000 1000000 + 3201000 3300000 1000000 + 3301000 4200000 5100000 + 4201000 4400000 4000000>; + qcom,dynamic-fv-ranges = <0 100 4400000 + 101 200 4380000 + 201 300 4360000 + 301 400 4340000 + 401 500 4340000>; + qcom,max-voltage-uv = <4400000>; + qcom,fg-cc-cv-threshold-mv = <4390>; + qcom,nom-batt-capacity-mah = <4000>; + qcom,batt-id-kohm = <68>; + qcom,battery-beta = <4250>; + qcom,therm-room-temp = <100000>; + qcom,battery-type = "f11_sun"; + qcom,therm-coefficients = <0x2318 0xd0c 0xdaf7 0xc556 0x848d>; + qcom,therm-center-offset = <0x70>; + qcom,therm-pull-up = <100>; + qcom,rslow-normal-coeffs = <0xae 0xe3 0x0e 0x13>; + qcom,rslow-low-coeffs = <0x58 0x15 0x1a 0xec>; + qcom,checksum = <0x585A>; + qcom,gui-version = "PM855GUI - 1.0.0.13"; + qcom,fg-profile-data = [ + 09 00 D1 E3 + 5B D4 39 DB + 83 D4 00 00 + F8 BD A8 83 + FB 87 01 A5 + 2A 9A 91 80 + 1D 00 AE E3 + 0E 13 FE 05 + 0C 02 CE 07 + 32 00 89 00 + 92 ED 75 E5 + EC 03 96 E4 + 7F C5 A6 13 + 1E 02 45 D2 + 60 00 44 00 + 42 00 42 00 + 38 00 32 00 + 37 00 3F 00 + 3F 00 43 00 + 45 00 60 00 + 31 00 35 00 + 3F 00 3A 00 + 34 00 63 00 + 52 64 42 00 + 3C 00 3C 08 + 60 F8 51 00 + 4B 00 53 10 + 44 10 40 00 + 70 28 54 48 + 4A 60 46 0D + 43 00 D8 00 + BC 1F 69 0D + 7E 02 E7 FC + 8C 1C 29 03 + CB 0D 62 22 + 95 17 4E 42 + 5F 55 12 02 + 6A 13 C5 1F + 68 05 9C 02 + 33 F6 EA 1C + 7B 03 72 04 + 0F 0A 81 17 + 71 23 42 45 + FF 52 7E 12 + A5 1E AF E6 + 68 CB 07 CC + D4 1C B9 D1 + 9C 04 0A B2 + D1 17 74 83 + 05 85 87 83 + 72 A0 09 80 + A4 03 9B FD + 7A FD 90 FA + 00 00 18 CC + 8B EB FB EF + EE E2 E0 C4 + B5 18 17 F0 + 92 D7 8D 03 + FB 05 5B 02 + CE 07 32 00 + 7F 01 46 05 + C4 05 C1 02 + B6 03 E6 05 + 48 03 1A 03 + 07 05 49 00 + 3D 00 43 00 + 44 64 49 00 + 4B 00 43 08 + 4A F8 49 00 + 48 00 3E 10 + 3E 10 39 00 + 44 28 47 48 + 51 60 5D 0D + 3E 00 49 00 + 4F 08 50 F8 + 3C 00 3F 00 + 39 10 45 10 + 45 00 57 20 + 62 40 45 58 + 4F 0F 45 00 + 39 F8 23 08 + D8 F8 F2 1F + 94 05 5B 0A + ED 0C C4 1C + 66 23 A2 45 + 80 52 65 18 + 20 02 80 05 + 0A 02 69 10 + 3F 0A D1 1F + 88 05 89 02 + 71 04 C1 1C + 0C 03 F4 05 + 36 02 7A 18 + 9E 03 51 04 + 9B 02 6A 00 + 4E 1F 0D 04 + 3F 02 DF 04 + C0 1C 9C 02 + C4 04 97 03 + 90 18 36 03 + 06 05 D4 03 + 6B 00 43 01 + C0 00 FA 00 + 8B 0F 00 00 + ]; +}; + diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-alium-3600mah.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-alium-3600mah.dtsi new file mode 100644 index 000000000000..cf398ae46599 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-alium-3600mah.dtsi @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2018-2019, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + + +qcom,alium_860_89032_0000_3600mah_averaged_masterslave_sep24th2018 { + /* #Alium_860_89032_0000_3600mAh_averaged_MasterSlave_Sept24th2018*/ + qcom,max-voltage-uv = <4400000>; + qcom,fastchg-current-ma = <4800>; + qcom,jeita-fcc-ranges = <0 50 300000 + 51 100 1600000 + 101 150 3200000 + 151 450 4800000 + 451 580 1600000>; + qcom,jeita-fv-ranges = <0 50 4400000 + 51 100 4400000 + 101 150 4400000 + 151 450 4400000 + 451 580 4100000>; + qcom,step-chg-ranges = <3600000 4200000 3000000 + 4201000 4300000 3000000 + 4301000 4340000 2500000>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,batt-id-kohm = <300>; + /* COLD = 0 DegC, HOT = 45 DegC */ + /* qcom,jeita-hard-thresholds = <0x58cd 0x20b8>; */ + /* COOL = 10 DegC, WARM = 40 DegC */ + /* qcom,jeita-soft-thresholds = <0x4ccc 0x25e3>; */ + /* COLD hys = 13 DegC, WARM hys = 37 DegC */ + /*qcom,jeita-soft-hys-thresholds = <0x48d4 0x2943>; + qcom,jeita-soft-fcc-ua = <2500000 2500000>; + qcom,jeita-soft-fv-uv = <4250000 4250000>;*/ + qcom,ocv-based-step-chg; + qcom,battery-beta = <4250>; + qcom,therm-room-temp = <100000>; + qcom,fg-cc-cv-threshold-mv = <4390>; + qcom,battery-type = "itech_3000mah"; + qcom,therm-coefficients = <0x2318 0xd0c 0xdaf7 0xc556 0x848d>; + qcom,therm-center-offset = <0x70>; + qcom,therm-pull-up = <100>; + qcom,rslow-normal-coeffs = <0xdf 0x02 0x77 0x1a>; + qcom,rslow-low-coeffs = <0x51 0x04 0xd0 0x13>; + qcom,checksum = <0x1538>; + qcom,gui-version = "PM855GUI - 1.0.0.10"; + qcom,fg-profile-data = [ + 09 00 C7 EA + C4 DC 8E E2 + 3A DD 00 00 + 15 BC A5 8A + 02 80 D1 92 + AB 9D 47 80 + 10 00 DF 02 + 77 1A 85 EC + E1 FD CE 07 + 32 00 75 EB + AA ED F3 CD + 0C 0A 7A E4 + ED C5 40 1B + D0 02 1F CA + FF 00 52 00 + 4D 00 4A 00 + 3C 00 35 00 + 38 00 39 00 + 48 00 43 00 + 3F 00 FF 00 + 38 00 40 00 + 46 00 50 00 + 45 00 5C 00 + 7E 64 60 00 + 50 08 50 10 + FF 00 6A 00 + 5F 00 63 00 + 6E 00 60 00 + 7D 20 96 40 + 75 50 6B 13 + 63 00 D8 00 + 14 22 7E 0D + 21 02 AA 04 + ED 1C D4 09 + 64 0C D3 23 + A4 18 D3 42 + B5 55 91 02 + 90 12 2A 1F + 02 06 1F 0A + A3 06 AE 1C + 8D 02 96 04 + D2 03 D1 17 + 51 23 3F 45 + 28 53 69 14 + 93 20 8E EC + 18 CB C8 C5 + DB 1C 7B C9 + 7C 05 E6 C2 + B9 17 2C 93 + 87 85 A2 92 + 91 A8 09 80 + 92 F2 1A 0D + F4 FC 5E EB + 00 F8 FB ED + 15 E2 F6 0F + 75 02 72 05 + 49 01 10 00 + FA E5 E2 03 + 8D 05 85 02 + CE 07 32 00 + 23 03 46 02 + 9C 04 03 02 + 48 07 0A 00 + BA 03 97 02 + 65 05 50 00 + 3A 00 41 00 + 43 64 45 00 + 45 10 45 18 + 46 08 44 00 + 47 00 3A 08 + 4B 08 37 00 + 47 20 4E 40 + 54 58 60 10 + 57 00 5F 00 + 57 08 55 00 + 4B 00 50 00 + 3E 08 52 08 + 52 00 5C 20 + 6F 40 7D 58 + 67 10 63 00 + 69 08 4F 10 + D8 00 8C 2A + DB 04 28 02 + AD 04 0B 1D + 50 22 A7 45 + 0D 52 A2 18 + 74 03 AD 04 + 35 02 AE 13 + 3F 0A 5A 20 + DD 04 F1 02 + D8 05 C7 1C + DD 02 3D 04 + EB 03 97 18 + 52 03 D5 04 + 19 02 72 00 + 14 22 7E 05 + 21 02 AA 04 + ED 1C D4 01 + 64 04 D3 03 + A4 18 D3 02 + B5 05 91 02 + 90 00 7C 01 + C0 00 FA 00 + 04 0E 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-alium-3600mah_E5G.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-alium-3600mah_E5G.dtsi new file mode 100644 index 000000000000..f4dd321ba524 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-alium-3600mah_E5G.dtsi @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + + +qcom,alium_860_89032_0000_3600mah_averaged_masterslave_sep24th2018 { + /* #Alium_860_89032_0000_3600mAh_averaged_MasterSlave_Sept24th2018*/ + qcom,max-voltage-uv = <4450000>; + qcom,fastchg-current-ma = <3700>; + qcom,jeita-fcc-ranges = <0 50 370000 + 51 100 1110000 + 101 150 1850000 + 151 450 3700000 + 451 580 1850000>; + qcom,jeita-fv-ranges = <0 50 4450000 + 51 100 4450000 + 101 150 4450000 + 151 450 4450000 + 451 580 4100000>; + qcom,nom-batt-capacity-mah = <3800>; + qcom,batt-id-kohm = <100>; + /* COLD = 0 DegC, HOT = 45 DegC */ + /* qcom,jeita-hard-thresholds = <0x58cd 0x20b8>; */ + /* COOL = 10 DegC, WARM = 40 DegC */ + /* qcom,jeita-soft-thresholds = <0x4ccc 0x25e3>; */ + /* COLD hys = 13 DegC, WARM hys = 37 DegC */ + /*qcom,jeita-soft-hys-thresholds = <0x48d4 0x2943>; + qcom,jeita-soft-fcc-ua = <2500000 2500000>; + qcom,jeita-soft-fv-uv = <4250000 4250000>;*/ + qcom,ocv-based-step-chg; + qcom,battery-beta = <4250>; + qcom,therm-room-temp = <100000>; + qcom,fg-cc-cv-threshold-mv = <4440>; + qcom,battery-type = "itech_3700mah"; + qcom,therm-coefficients = <0x2318 0xd0c 0xdaf7 0xc556 0x848d>; + qcom,therm-center-offset = <0x70>; + qcom,therm-pull-up = <100>; + qcom,rslow-normal-coeffs = <0xdf 0x02 0x77 0x1a>; + qcom,rslow-low-coeffs = <0x51 0x04 0xd0 0x13>; + qcom,checksum = <0x1538>; + qcom,gui-version = "PM855GUI - 1.0.0.10"; + qcom,fg-profile-data = [ + 09 00 C7 EA + C4 DC 8E E2 + 3A DD 00 00 + 15 BC A5 8A + 02 80 D1 92 + AB 9D 47 80 + 10 00 DF 02 + 77 1A 85 EC + E1 FD CE 07 + 32 00 75 EB + AA ED F3 CD + 0C 0A 7A E4 + ED C5 40 1B + D0 02 1F CA + FF 00 52 00 + 4D 00 4A 00 + 3C 00 35 00 + 38 00 39 00 + 48 00 43 00 + 3F 00 FF 00 + 38 00 40 00 + 46 00 50 00 + 45 00 5C 00 + 7E 64 60 00 + 50 08 50 10 + FF 00 6A 00 + 5F 00 63 00 + 6E 00 60 00 + 7D 20 96 40 + 75 50 6B 13 + 63 00 D8 00 + 14 22 7E 0D + 21 02 AA 04 + ED 1C D4 09 + 64 0C D3 23 + A4 18 D3 42 + B5 55 91 02 + 90 12 2A 1F + 02 06 1F 0A + A3 06 AE 1C + 8D 02 96 04 + D2 03 D1 17 + 51 23 3F 45 + 28 53 69 14 + 93 20 8E EC + 18 CB C8 C5 + DB 1C 7B C9 + 7C 05 E6 C2 + B9 17 2C 93 + 87 85 A2 92 + 91 A8 09 80 + 92 F2 1A 0D + F4 FC 5E EB + 00 F8 FB ED + 15 E2 F6 0F + 75 02 72 05 + 49 01 10 00 + FA E5 E2 03 + 8D 05 85 02 + CE 07 32 00 + 23 03 46 02 + 9C 04 03 02 + 48 07 0A 00 + BA 03 97 02 + 65 05 50 00 + 3A 00 41 00 + 43 64 45 00 + 45 10 45 18 + 46 08 44 00 + 47 00 3A 08 + 4B 08 37 00 + 47 20 4E 40 + 54 58 60 10 + 57 00 5F 00 + 57 08 55 00 + 4B 00 50 00 + 3E 08 52 08 + 52 00 5C 20 + 6F 40 7D 58 + 67 10 63 00 + 69 08 4F 10 + D8 00 8C 2A + DB 04 28 02 + AD 04 0B 1D + 50 22 A7 45 + 0D 52 A2 18 + 74 03 AD 04 + 35 02 AE 13 + 3F 0A 5A 20 + DD 04 F1 02 + D8 05 C7 1C + DD 02 3D 04 + EB 03 97 18 + 52 03 D5 04 + 19 02 72 00 + 14 22 7E 05 + 21 02 AA 04 + ED 1C D4 01 + 64 04 D3 03 + A4 18 D3 02 + B5 05 91 02 + 90 00 7C 01 + C0 00 FA 00 + 04 0E 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-nabu-sunwoda-8720mah.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-nabu-sunwoda-8720mah.dtsi new file mode 100644 index 000000000000..c152f8ed1934 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-nabu-sunwoda-8720mah.dtsi @@ -0,0 +1,153 @@ +qcom,5119583_xiaomi_k82_p86120aa1_8720mah_averaged_masterslave_apr8th2021 { + qcom,profile-revision = <24>; + /* #5119583_XIAOMI_K82_8720mAH_averaged_MasterSlave_Apr8th2021*/ + qcom,max-voltage-uv = <4480000>; + qcom,fastchg-current-ma = <5900>; + qcom,jeita-fcc-ranges = <(-100) 0 820000 + 1 50 820000 + 51 100 2500000 + 101 150 5964000 + 151 480 5900000 + 481 590 4260000>; + qcom,jeita-fv-ranges = <(-100) 0 4450000 + 1 50 4450000 + 51 100 4450000 + 101 150 4450000 + 151 480 4480000 + 481 600 4100000>; +// qcom,step-chg-ranges = <3001000 4150000 6000000 +// 4150001 4230000 6000000 +// 4230001 4350000 6000000 +// 4350001 4400000 6000000 +// 4400001 4430000 6000000 +// 4430001 4480000 4000000>; +// qcom,taper-fcc; + qcom,jeita-too-hot = <590>; + qcom,jeita-too-cold = <(-100)>; + qcom,jeita-warm-th= <480>; + qcom,jeita-cool-th= <150>; + qcom,use-bq-pump; + mi,six-pin-battery; + qcom,ffc-low-temp-term-current-ma = <(-1278)>; + qcom,ffc-high-temp-term-current-ma = <(-1363)>; + qcom,fg-cc-cv-threshold-mv = <4450>; + qcom,fg-ffc-cc-cv-threshold-mv = <4480>; + qcom,nom-batt-capacity-mah = <8720>; + qcom,batt-id-kohm = <10>; + qcom,battery-beta = <3800>; + qcom,therm-room-temp = <100000>; + qcom,battery-type = "K82_sunwoda_8720mah"; + qcom,therm-coefficients = <0x2319 0xcb5 0xdb70 0xc48e 0x856b>; + qcom,therm-center-offset = <0x70>; + qcom,therm-pull-up = <100>; + qcom,rslow-normal-coeffs = <0x33 0xfc 0xe8 0x12>; + qcom,rslow-low-coeffs = <0x36 0x05 0xc4 0x12>; + qcom,checksum = <0xBEEA>; + qcom,gui-version = "PM855GUI - 1.0.0.14"; + qcom,fg-profile-data = [ + 09 00 9B DB + 1B D5 75 DA + 68 D5 00 00 + 99 B5 42 83 + FA 87 1E 93 + 02 8D EA 87 + 18 00 33 FC + E8 12 C5 04 + 50 02 CE 07 + 32 00 11 EA + BB E4 48 E3 + 5E 0B B5 E2 + 1D AC 12 22 + C9 FA 3A CC + 60 00 40 00 + 3F 00 38 00 + 2C 00 2D 00 + 3A 00 46 00 + 41 00 46 00 + 3E 00 60 00 + 44 00 3B 00 + 4B 00 47 00 + 3D 00 8C 00 + 59 64 4B 00 + 49 00 4C 08 + 60 00 4C 00 + 4F 00 6F 10 + 5E 10 57 00 + A3 28 6B 48 + 5B 60 54 0C + 58 00 D8 08 + 06 20 B1 14 + 6F 0B 51 FD + 4B 1C AE 03 + 5B 05 F7 2A + B6 17 51 42 + 2A 5D 68 02 + 66 12 54 23 + AD 0C DE 12 + 9D 0D F3 1C + 21 FB 58 FD + 50 03 FE 16 + 09 2A 76 44 + 18 5A 95 11 + 9E 24 29 DC + 21 C3 72 C5 + F3 1C 97 AA + FB 04 2D B2 + 0A 17 12 82 + 4A 84 43 8A + A4 90 09 80 + 48 03 13 05 + 87 02 D7 05 + 00 00 FB CD + 78 E2 FC 07 + 17 EA 39 CD + 1D 18 15 08 + 80 ED 35 03 + 76 05 A7 01 + CE 07 32 00 + 9E 01 EE 05 + 5C 05 1C 03 + D4 05 0E 02 + BD 03 9D 02 + C6 05 48 00 + 39 00 42 00 + 44 64 45 00 + 49 00 40 08 + 40 00 44 00 + 44 00 3B 10 + 3F 10 3F 00 + 53 28 54 48 + 57 58 62 0D + 43 00 48 00 + 52 08 54 00 + 43 00 47 00 + 49 10 59 10 + 51 00 5F 20 + 75 40 49 58 + 56 0F 5D 00 + 4C 08 31 10 + D8 08 FC 20 + 54 FC 6D 03 + 67 0D C7 1C + 62 23 C5 45 + 4B 52 63 18 + 0F 02 AC 05 + A9 03 72 12 + 3F 0A 6B 20 + 93 04 89 03 + 20 05 BE 1C + 3C 03 C0 05 + 85 02 77 18 + A0 03 51 04 + 9A 02 6A 00 + 35 22 4D 05 + 7A 02 EB 05 + FB 1C AF 03 + 82 04 0B 02 + 86 18 17 03 + 59 05 23 03 + 8A 00 92 00 + C0 00 FA 00 + F0 21 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-vayu-NVT-5160mah.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-vayu-NVT-5160mah.dtsi new file mode 100644 index 000000000000..732853672c91 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-vayu-NVT-5160mah.dtsi @@ -0,0 +1,153 @@ +qcom,xiaomi_j20s_nvt_5160mah_averaged_masterslave_aug26th2019 { + qcom,profile-revision = <24>; + /* #4174016_Xiaomi_J20S_5160mAh_averaged_MasterSlave_Aug26th2019*/ + qcom,max-voltage-uv = <4475000>; + qcom,fastchg-current-ma = <5900>; + qcom,jeita-fcc-ranges = <(-100) 0 500000 + 1 50 1000000 + 51 100 2500000 + 101 150 4000000 + 151 450 5900000 + 451 580 2500000>; + qcom,jeita-fv-ranges = <(-100) 0 4450000 + 1 50 4450000 + 51 100 4450000 + 101 150 4450000 + 151 450 4475000 + 451 600 4100000>; + qcom,step-chg-ranges = <3001000 4150000 5900000 + 4150001 4230000 5900000 + 4230001 4350000 5400000 + 4350001 4400000 5400000 + 4400001 4430000 5400000 + 4430001 4475000 4000000>; + qcom,taper-fcc; + qcom,jeita-too-hot = <590>; + qcom,jeita-too-cold = <(-100)>; + qcom,jeita-warm-th= <450>; + qcom,jeita-cool-th= <150>; + qcom,use-bq-pump; + mi,six-pin-battery; + qcom,ffc-low-temp-term-current-ma = <(-723)>; + qcom,ffc-high-temp-term-current-ma = <(-774)>; + qcom,fg-cc-cv-threshold-mv = <4440>; + qcom,fg-ffc-cc-cv-threshold-mv = <4490>; + qcom,nom-batt-capacity-mah = <5160>; + qcom,batt-id-kohm = <100>; + qcom,battery-beta = <4250>; + qcom,therm-room-temp = <100000>; + qcom,battery-type = "J20S_nvt_5160mah"; + qcom,therm-coefficients = <0x2318 0xd0c 0xdaf7 0xc556 0x848d>; + qcom,therm-center-offset = <0x70>; + qcom,therm-pull-up = <100>; + qcom,rslow-normal-coeffs = <0x3c 0x05 0x2a 0x0b>; + qcom,rslow-low-coeffs = <0xe7 0x00 0x6a 0x12>; + qcom,checksum = <0x65B6>; + qcom,gui-version = "PM855GUI - 1.0.0.14"; + qcom,fg-profile-data = [ + 09 00 6B E2 + D8 DD C7 DB + FD DD 00 00 + FD B4 92 83 + FA 87 9C 80 + 06 8D 19 80 + 20 00 3C 05 + 2A 0B BF 04 + 44 02 CE 07 + 32 00 6C EA + 29 E4 A4 DB + C8 03 54 DD + 9F 86 4B 23 + 4D 0A 88 D5 + 60 00 41 00 + 45 00 3D 00 + 2E 00 30 00 + 39 00 43 00 + 40 00 44 00 + 3D 00 60 00 + 39 00 36 00 + 47 00 40 00 + 3A 00 79 00 + 52 64 45 00 + 46 00 47 10 + 60 00 47 00 + 4C 08 71 10 + 5C 10 53 00 + 99 28 6A 48 + 5B 60 53 0C + 4E 00 D8 08 + 7D 20 0B 14 + 03 0A AD FC + 36 1C 0D 02 + F5 0C 66 23 + FA 17 3F 42 + 28 5D 83 02 + 66 11 41 22 + 2B 0D 96 12 + D2 05 F0 1C + 6B 03 B5 04 + 05 02 B4 17 + CD 23 83 44 + 2F 5A 8A 11 + 0C 21 DE E5 + 15 C2 8D AC + E2 1C A2 C1 + 2C 05 92 B3 + 63 17 DF 83 + 8C 84 1A A2 + 87 A0 09 80 + 3C 02 5B 04 + 1C 05 54 FB + 00 00 5C BD + FC E2 FC 07 + 1D E2 D3 C5 + 10 18 19 00 + A7 E6 33 03 + 9A 05 1F 03 + CE 07 32 00 + 96 01 BE 05 + 0F 05 27 03 + 67 04 6E 03 + AE 02 2B 03 + 38 05 55 00 + 3A 00 42 00 + 44 64 46 00 + 4C 00 42 08 + 43 00 46 00 + 47 08 3B 10 + 43 10 3E 00 + 52 28 54 50 + 5A 68 64 0A + 47 00 4C 00 + 56 10 55 00 + 46 00 4B 00 + 45 10 59 10 + 52 00 62 20 + 77 40 4C 58 + 59 0E 5B 00 + 50 08 2E 10 + D8 08 83 20 + B0 04 4E 0B + 6B 0D 9F 1C + 02 22 0F 45 + 34 53 23 18 + D1 02 D7 05 + 4D 02 66 11 + 3F 0A D1 20 + 08 04 02 02 + 9E 04 C4 1C + 33 03 C8 05 + 7B 02 86 18 + B6 03 18 04 + DB 02 6C 00 + 04 22 59 05 + 7E 02 DD 05 + F3 1C 02 02 + F2 05 61 02 + 98 18 34 03 + 17 05 A4 03 + 85 00 C2 00 + C0 00 FA 00 + 64 14 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-vayu-sunwoda-5160mah.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-vayu-sunwoda-5160mah.dtsi new file mode 100644 index 000000000000..165a4be41364 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/battery/fg-gen4-batterydata-vayu-sunwoda-5160mah.dtsi @@ -0,0 +1,153 @@ +qcom,xiaomi_j20s_sunwoda_5160mah_averaged_masterslave_aug26th2019 { + qcom,profile-revision = <24>; + /* #4174016_Xiaomi_J20S_5160mAh_averaged_MasterSlave_Aug26th2019*/ + qcom,max-voltage-uv = <4475000>; + qcom,fastchg-current-ma = <5900>; + qcom,jeita-fcc-ranges = <(-100) 0 500000 + 1 50 1000000 + 51 100 2500000 + 101 150 4000000 + 151 450 5900000 + 451 580 2500000>; + qcom,jeita-fv-ranges = <(-100) 0 4450000 + 1 50 4450000 + 51 100 4450000 + 101 150 4450000 + 151 450 4475000 + 451 600 4100000>; + qcom,step-chg-ranges = <3001000 4150000 5900000 + 4150001 4230000 5900000 + 4230001 4350000 5400000 + 4350001 4400000 5400000 + 4400001 4430000 5400000 + 4430001 4475000 4000000>; + qcom,taper-fcc; + qcom,jeita-too-hot = <590>; + qcom,jeita-too-cold = <(-100)>; + qcom,jeita-warm-th= <450>; + qcom,jeita-cool-th= <150>; + qcom,use-bq-pump; + mi,six-pin-battery; + qcom,ffc-low-temp-term-current-ma = <(-723)>; + qcom,ffc-high-temp-term-current-ma = <(-774)>; + qcom,fg-cc-cv-threshold-mv = <4440>; + qcom,fg-ffc-cc-cv-threshold-mv = <4490>; + qcom,nom-batt-capacity-mah = <5160>; + qcom,batt-id-kohm = <100>; + qcom,battery-beta = <4250>; + qcom,therm-room-temp = <100000>; + qcom,battery-type = "J20S_sunwoda_5160mah"; + qcom,therm-coefficients = <0x2318 0xd0c 0xdaf7 0xc556 0x848d>; + qcom,therm-center-offset = <0x70>; + qcom,therm-pull-up = <100>; + qcom,rslow-normal-coeffs = <0x71 0x04 0x9c 0x12>; + qcom,rslow-low-coeffs = <0x9d 0x15 0x4c 0x02>; + qcom,checksum = <0x7304>; + qcom,gui-version = "PM855GUI - 1.0.0.14"; + qcom,fg-profile-data = [ + 09 00 8B E2 + 99 D4 2B DB + 9D D4 00 00 + 95 B4 2D 83 + FD 87 E3 9D + 61 86 4B 80 + 24 00 71 04 + 9C 12 05 FC + EE F3 CE 07 + 32 00 B1 EA + FC ED 33 DA + 2E 12 37 DB + 8B BC 31 12 + E8 01 63 C5 + 60 00 49 00 + 4B 00 48 00 + 31 00 2F 00 + 37 00 40 00 + 3E 00 43 00 + 38 00 60 00 + 35 00 3B 00 + 4D 00 44 00 + 3A 00 71 00 + 57 64 49 00 + 44 08 40 10 + 60 08 47 00 + 43 08 58 10 + 55 10 45 00 + 8B 28 62 48 + 4E 60 44 0C + 41 00 D8 08 + 16 21 97 15 + 60 0A F9 FD + 1A 1C 20 02 + DF 04 70 23 + 0E 17 A9 42 + 9D 54 FF 02 + 69 15 B0 23 + 63 0C 28 13 + 48 05 F3 1C + 15 03 66 05 + 5F 03 EA 16 + 8C 23 5D 45 + AD 52 93 14 + 22 21 C4 E5 + 35 C2 3A B4 + D6 1C A9 C9 + 27 05 A1 B3 + 49 17 70 8B + 53 85 D9 9A + 86 A0 09 80 + 77 FA 99 FC + 29 FC 27 F2 + 00 F8 42 DC + 29 E2 FA F7 + B1 E2 77 BD + 44 18 1A 00 + 6D D4 D9 03 + 11 05 C3 02 + CE 07 32 00 + 01 03 C7 02 + 68 04 86 02 + 87 02 E1 05 + 38 02 43 01 + 69 04 46 00 + 38 00 44 00 + 44 64 48 00 + 4F 08 46 10 + 46 00 47 00 + 46 00 41 08 + 41 10 3D 00 + 53 20 52 40 + 5D 58 69 0F + 48 00 52 08 + 5E 10 62 00 + 4E 00 44 00 + 42 10 54 10 + 4B 00 5E 20 + 75 40 46 50 + 56 10 5E 00 + 5A 08 3B 10 + D8 08 3E 22 + 5A FD 5D 02 + 1E 0C C9 1C + 26 23 02 44 + 08 52 66 18 + 98 03 77 04 + 6B 02 7C 13 + 3F 0A CD 20 + F7 05 19 02 + 5E 04 A6 1C + 74 03 8E 05 + C0 02 65 18 + 4F 03 F7 04 + E4 03 6A 00 + EF 22 CB 04 + F1 02 67 05 + EB 1C E7 03 + 3E 04 34 02 + 89 18 E4 02 + A8 05 A0 02 + 8A 00 BF 00 + C0 00 FA 00 + 22 14 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-j20s-36-02-0a-lcd-dsc-vid.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-j20s-36-02-0a-lcd-dsc-vid.dtsi new file mode 100644 index 000000000000..7caf6f84bcac --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-j20s-36-02-0a-lcd-dsc-vid.dtsi @@ -0,0 +1,334 @@ +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&mdss_mdp { + dsi_j20s_36_02_0a_video: qcom,mdss_dsi_j20s_36_02_0a_dsc_video { + qcom,mdss-dsi-panel-name = "xiaomi 36 02 0a video mode dsc dsi panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "xiaomi 36 02 0a VIDEO PANEL"; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-brightness-max-level = <4095>; + qcom,ulps-enabled; + qcom,mdss-dsi-reset-sequence = <1 5>, <0 1>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <70>; + qcom,mdss-pan-physical-height-dimension = <154>; + qcom,mdss-dsi-tx-eot-append; + qcom,bl-update-flag = "delay_until_first_frame"; + qcom,disp-panel-offon-mode-enabled; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 + 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4200000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + + qcom,esd-err-irq-gpio = <&tlmm 5 0x2002>; + /* qcom,mdss-dsi-qsync-min-refresh-rate = <60>; */ + qcom,mdss-dsi-pan-enable-dynamic-fps; + qcom,mdss-dsi-pan-fps-update = + "dfps_immediate_porch_mode_vfp"; + qcom,dsi-supported-dfps-list = <120 90 60 50 48 30>; + + qcom,dispparam-enabled; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-framerate = <120>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2400>; + qcom,mdss-dsi-h-pulse-width = <12>; + qcom,mdss-dsi-h-back-porch = <40>; + qcom,mdss-dsi-h-front-porch = <67>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-v-back-porch = <30>; + qcom,mdss-dsi-v-front-porch = <33>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + + qcom,mdss-dsi-on-command = [ + /* DDIC Initical Code */ + 15 00 00 00 00 00 02 FF 24 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 4D 02 + 15 00 00 00 00 00 02 4E 30 + 15 00 00 00 00 00 02 4F 30 + 15 00 00 00 00 00 02 53 30 + 15 00 00 00 00 00 02 7A 01 + 15 00 00 00 00 00 02 7B 8C + 15 00 00 00 00 00 02 7D 05 + 15 00 00 00 00 00 02 80 05 + 15 00 00 00 00 00 02 81 05 + 15 00 00 00 00 00 02 A0 0C + 15 00 00 00 00 00 02 A2 0C + 15 00 00 00 00 00 02 A3 01 + 15 00 00 00 00 00 02 A4 05 + 15 00 00 00 00 00 02 A5 05 + 15 00 00 00 00 00 02 C4 80 + 15 00 00 00 00 00 02 C6 C0 + 15 01 00 00 00 00 02 E9 02 + 15 00 00 00 00 00 02 FF 25 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 DA 00 + 15 00 00 00 00 00 02 E0 00 + 15 01 00 00 00 00 02 F1 04 + 15 00 00 00 00 00 02 FF 2B + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 B7 08 + 15 00 00 00 00 00 02 B8 1A + 15 01 00 00 00 00 02 C0 04 + 15 00 00 00 00 00 02 FF F0 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 1C 01 + 15 01 00 00 00 00 02 33 01 + /* CABC Setting */ + 15 00 00 00 00 00 02 FF 23 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 00 80 + 15 00 00 00 00 00 02 01 84 + 15 00 00 00 00 00 02 05 2D + 15 00 00 00 00 00 02 06 00 + 15 00 00 00 00 00 02 07 00 + 15 00 00 00 00 00 02 08 01 + 15 00 00 00 00 00 02 09 45 + 15 00 00 00 00 00 02 11 01 + 15 00 00 00 00 00 02 12 95 + 15 00 00 00 00 00 02 15 68 + 15 00 00 00 00 00 02 16 0B + 15 00 00 00 00 00 02 29 0A + 15 00 00 00 00 00 02 30 FF + 15 00 00 00 00 00 02 31 FE + 15 00 00 00 00 00 02 32 FD + 15 00 00 00 00 00 02 33 FB + 15 00 00 00 00 00 02 34 F8 + 15 00 00 00 00 00 02 35 F5 + 15 00 00 00 00 00 02 36 F3 + 15 00 00 00 00 00 02 37 F2 + 15 00 00 00 00 00 02 38 F2 + 15 00 00 00 00 00 02 39 F2 + 15 00 00 00 00 00 02 3A EF + 15 00 00 00 00 00 02 3B EC + 15 00 00 00 00 00 02 3D E9 + 15 00 00 00 00 00 02 3F E5 + 15 00 00 00 00 00 02 40 E5 + 15 00 00 00 00 00 02 41 E5 + 15 00 00 00 00 00 02 2A 13 + 15 00 00 00 00 00 02 45 FF + 15 00 00 00 00 00 02 46 F4 + 15 00 00 00 00 00 02 47 E7 + 15 00 00 00 00 00 02 48 DA + 15 00 00 00 00 00 02 49 CD + 15 00 00 00 00 00 02 4A C0 + 15 00 00 00 00 00 02 4B B3 + 15 00 00 00 00 00 02 4C B2 + 15 00 00 00 00 00 02 4D B2 + 15 00 00 00 00 00 02 4E B2 + 15 00 00 00 00 00 02 4F 99 + 15 00 00 00 00 00 02 50 80 + 15 00 00 00 00 00 02 51 68 + 15 00 00 00 00 00 02 52 66 + 15 00 00 00 00 00 02 53 66 + 15 00 00 00 00 00 02 54 66 + 15 00 00 00 00 00 02 2B 0E + 15 00 00 00 00 00 02 58 FF + 15 00 00 00 00 00 02 59 FB + 15 00 00 00 00 00 02 5A F7 + 15 00 00 00 00 00 02 5B F3 + 15 00 00 00 00 00 02 5C EF + 15 00 00 00 00 00 02 5D E3 + 15 00 00 00 00 00 02 5E DA + 15 00 00 00 00 00 02 5F D8 + 15 00 00 00 00 00 02 60 D8 + 15 00 00 00 00 00 02 61 D8 + 15 00 00 00 00 00 02 62 CB + 15 00 00 00 00 00 02 63 BF + 15 00 00 00 00 00 02 64 B3 + 15 00 00 00 00 00 02 65 B2 + 15 00 00 00 00 00 02 66 B2 + 15 01 00 00 00 00 02 67 B2 + /* ESD Setting */ + 15 00 00 00 00 00 02 FF 27 + 15 00 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 40 20 + 15 00 00 00 00 00 02 FF 10 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 C0 03 + 39 00 00 00 00 00 03 51 0D B5 + 15 01 00 00 00 00 02 53 24 + 15 00 00 00 00 00 02 FF 10 + 15 01 00 00 46 00 02 11 00 + 15 01 00 00 00 00 02 29 00 + 15 00 00 00 00 00 02 FF 27 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 3F 01 + 15 00 00 00 00 00 02 43 08 + 15 00 00 00 00 00 02 40 25 + 15 01 00 00 00 00 02 FF 10]; + qcom,mdss-dsi-post-off-command = [ + 15 00 00 00 00 00 02 FF 27 + 15 00 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 3F 00 + 15 00 00 00 00 00 02 FF 10 + 05 00 00 00 00 00 02 28 00 + 05 01 00 00 46 00 02 10 00]; + qcom,mdss-dsi-displayoff-command = [05 01 00 00 20 00 02 28 00]; + qcom,mdss-dsi-displayon-command = [05 01 00 00 14 00 02 29 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-post-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-displayoff-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-displayon-command-state = "dsi_hs_mode"; + + + qcom,mdss-dsi-dispparam-cabcuion-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 01 + ]; + qcom,mdss-dsi-dispparam-cabcstillon-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 02 + ]; + qcom,mdss-dsi-dispparam-cabcmovieon-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 03 + ]; + qcom,mdss-dsi-dispparam-cabcoff-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 00 + ]; + qcom,mdss-dsi-dispparam-cabcuion-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-cabcstillon-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-cabcmovieon-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-cabcoff-command-state = "dsi_hs_mode"; + + qcom,mdss-dsi-dispparam-lcd-hbm-l1-on-command = [ + 15 00 00 00 00 00 02 FF 10 + 39 01 00 00 00 00 03 51 0E A0]; + qcom,mdss-dsi-dispparam-lcd-hbm-l1-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-lcd-hbm-l2-on-command = [ + 15 00 00 00 00 00 02 FF 10 + 39 01 00 00 00 00 03 51 FF FF]; + qcom,mdss-dsi-dispparam-lcd-hbm-l2-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-lcd-hbm-off-command = [ + 15 00 00 00 00 00 02 FF 10 + 39 01 00 00 00 00 03 51 0D B5]; + qcom,mdss-dsi-dispparam-lcd-hbm-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-h-sync-pulse = <1>; + qcom,compression-mode = "dsc"; + qcom,mdss-dsc-version = <0x11>; + qcom,mdss-dsc-scr-version = <0x0>; + qcom,mdss-dsc-slice-height = <20>; + qcom,mdss-dsc-slice-width = <540>; + qcom,mdss-dsc-slice-per-pkt = <2>; + qcom,mdss-dsc-bit-per-component = <8>; + qcom,mdss-dsc-bit-per-pixel = <8>; + qcom,mdss-dsc-block-prediction-enable; + }; + }; + }; +}; + +&dsi_j20s_36_02_0a_video { + mi,feature-enabled; + mi,is-tddi-flag; + mi,mdss-panel-on-dimming-delay = <120>; + mi,esd-err-irq-gpio = <&tlmm 24 0x2002>; /* trig-flags: falling-0x0002 rasing-0x0001*/ + mi,mdss-dsi-panel-xy-coordinate = <0x6 0x3>; + mi,mdss-dsi-panel-max-luminance = <0x6 0x4>; + mi,mdss-dsi-panel-status-value-ignore; + mi,esd-check-interval = <3000>; + mi,mdss-panel-idle-time = <1100>; + mi,mdss-panel-idle-fps = <50>; + //mi,mdss-dsi-pan-enable-smart-fps; + mi,mdss-dsi-dfps-dec-vfp-list = <20 0 20 0 0 0 + 0 0 0 0 0 0>; + mi,mdss-dsi-dfps-dec-hfp-list = <0 0 0 0 0 0 + 4 0 4 0 0 0>; + mi,mdss-dsi-post-off-msleep = <20>; + + qcom,mdss-dsi-display-timings { + timing@0{ + mi,mdss-dsi-read-lockdown-info-command = [ + 15 00 00 00 00 00 02 FF 21 + 06 01 00 00 00 00 01 F1]; + mi,mdss-dsi-read-lockdown-info-command-state = "dsi_lp_mode"; + + mi,mdss-dsi-cabcuion-command = [ + 15 00 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 01 + ]; + mi,mdss-dsi-cabcuion-command-state = "dsi_hs_mode"; + + mi,mdss-dsi-cabcstillon-command = [ + 15 00 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 02 + ]; + mi,mdss-dsi-cabcstillon-command-state = "dsi_hs_mode"; + + mi,mdss-dsi-cabcmovieon-command = [ + 15 00 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 03 + ]; + mi,mdss-dsi-cabcmovieon-command-state = "dsi_hs_mode"; + + mi,mdss-dsi-cabcoff-command = [ + 15 00 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 00 + ]; + mi,mdss-dsi-cabcoff-command-state = "dsi_hs_mode"; + + mi,mdss-dsi-cabc-dimmming-command = [ + 15 00 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 53 2C + ]; + mi,mdss-dsi-cabc-dimmming-command-state = "dsi_hs_mode"; + + mi,mdss-dsi-xy-coordinate-command = [ + 15 00 00 00 00 00 02 FF 10 + 06 01 00 00 00 00 01 A1]; + mi,mdss-dsi-xy-coordinate-command-state = "dsi_lp_mode"; + + mi,mdss-dsi-max-luminance-write-command = [ + 15 01 00 00 00 00 02 FF 10]; + mi,mdss-dsi-max-luminance-write-command-state = "dsi_lp_mode"; + + mi,mdss-dsi-max-luminance-read-command = [ + 06 01 00 00 00 00 01 A1]; + mi,mdss-dsi-max-luminance-read-command-state = "dsi_lp_mode"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-j20s-42-02-0b-lcd-dsc-vid.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-j20s-42-02-0b-lcd-dsc-vid.dtsi new file mode 100644 index 000000000000..c9421342f92b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-j20s-42-02-0b-lcd-dsc-vid.dtsi @@ -0,0 +1,318 @@ +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&mdss_mdp { + dsi_j20s_42_02_0b_video: qcom,mdss_dsi_j20s_42_02_0b_dsc_video { + qcom,mdss-dsi-panel-name = "xiaomi 42 02 0b video mode dsc dsi panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "xiaomi 42 02 0b VIDEO PANEL"; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-brightness-max-level = <4095>; + qcom,ulps-enabled; + qcom,mdss-dsi-reset-sequence = <1 5>, <0 1>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <70>; + qcom,mdss-pan-physical-height-dimension = <154>; + qcom,mdss-dsi-tx-eot-append; + qcom,bl-update-flag = "delay_until_first_frame"; + qcom,disp-panel-offon-mode-enabled; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 + 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4200000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + + qcom,esd-err-irq-gpio = <&tlmm 5 0x2002>; + /* qcom,mdss-dsi-qsync-min-refresh-rate = <60>; */ + qcom,mdss-dsi-pan-enable-dynamic-fps; + qcom,mdss-dsi-pan-fps-update = + "dfps_immediate_porch_mode_vfp"; + qcom,dsi-supported-dfps-list = <120 90 60 50 48 30>; + + qcom,dispparam-enabled; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-framerate = <120>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2400>; + qcom,mdss-dsi-h-pulse-width = <12>; + qcom,mdss-dsi-h-back-porch = <40>; + qcom,mdss-dsi-h-front-porch = <67>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-v-back-porch = <30>; + qcom,mdss-dsi-v-front-porch = <33>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + + qcom,mdss-dsi-on-command = [ + /* DDIC Initical Code */ + 15 00 00 00 00 00 02 FF 20 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 EE 60 + 15 01 00 00 00 00 02 EF 06 + /* CABC Setting */ + 15 00 00 00 00 00 02 FF 23 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 00 80 + 15 00 00 00 00 00 02 01 84 + 15 00 00 00 00 00 02 05 2D + 15 00 00 00 00 00 02 06 00 + 15 00 00 00 00 00 02 07 00 + 15 00 00 00 00 00 02 08 01 + 15 00 00 00 00 00 02 09 45 + 15 00 00 00 00 00 02 11 01 + 15 00 00 00 00 00 02 12 95 + 15 00 00 00 00 00 02 15 68 + 15 00 00 00 00 00 02 16 0B + 15 00 00 00 00 00 02 29 0A + 15 00 00 00 00 00 02 30 FF + 15 00 00 00 00 00 02 31 FE + 15 00 00 00 00 00 02 32 FD + 15 00 00 00 00 00 02 33 FB + 15 00 00 00 00 00 02 34 F8 + 15 00 00 00 00 00 02 35 F5 + 15 00 00 00 00 00 02 36 F3 + 15 00 00 00 00 00 02 37 F2 + 15 00 00 00 00 00 02 38 F2 + 15 00 00 00 00 00 02 39 F2 + 15 00 00 00 00 00 02 3A EF + 15 00 00 00 00 00 02 3B EC + 15 00 00 00 00 00 02 3D E9 + 15 00 00 00 00 00 02 3F E5 + 15 00 00 00 00 00 02 40 E5 + 15 00 00 00 00 00 02 41 E5 + 15 00 00 00 00 00 02 2A 13 + 15 00 00 00 00 00 02 45 FF + 15 00 00 00 00 00 02 46 F4 + 15 00 00 00 00 00 02 47 E7 + 15 00 00 00 00 00 02 48 DA + 15 00 00 00 00 00 02 49 CD + 15 00 00 00 00 00 02 4A C0 + 15 00 00 00 00 00 02 4B B3 + 15 00 00 00 00 00 02 4C B2 + 15 00 00 00 00 00 02 4D B2 + 15 00 00 00 00 00 02 4E B2 + 15 00 00 00 00 00 02 4F 99 + 15 00 00 00 00 00 02 50 80 + 15 00 00 00 00 00 02 51 68 + 15 00 00 00 00 00 02 52 66 + 15 00 00 00 00 00 02 53 66 + 15 00 00 00 00 00 02 54 66 + 15 00 00 00 00 00 02 2B 0E + 15 00 00 00 00 00 02 58 FF + 15 00 00 00 00 00 02 59 FB + 15 00 00 00 00 00 02 5A F7 + 15 00 00 00 00 00 02 5B F3 + 15 00 00 00 00 00 02 5C EF + 15 00 00 00 00 00 02 5D E3 + 15 00 00 00 00 00 02 5E DA + 15 00 00 00 00 00 02 5F D8 + 15 00 00 00 00 00 02 60 D8 + 15 00 00 00 00 00 02 61 D8 + 15 00 00 00 00 00 02 62 CB + 15 00 00 00 00 00 02 63 BF + 15 00 00 00 00 00 02 64 B3 + 15 00 00 00 00 00 02 65 B2 + 15 00 00 00 00 00 02 66 B2 + 15 01 00 00 00 00 02 67 B2 + + /*decrease MUX EQ for desense*/ + 15 00 00 00 00 00 02 FF 20 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 1F C0 + 15 00 00 00 00 00 02 20 C0 + + 15 00 00 00 00 00 02 FF 25 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 D6 80 + 15 00 00 00 00 00 02 D7 02 + 15 00 00 00 00 00 02 DD 02 + + /* ESD Setting */ + 15 00 00 00 00 00 02 FF 27 + 15 00 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 40 20 + 15 00 00 00 00 00 02 FF 10 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 C0 03 + 39 00 00 00 00 00 03 51 0D B5 + 15 01 00 00 00 00 02 53 24 + 15 00 00 00 00 00 02 FF 10 + 15 01 00 00 46 00 02 11 00 + 15 01 00 00 00 00 02 29 00 + 15 00 00 00 00 00 02 FF 27 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 3F 01 + 15 00 00 00 00 00 02 43 08 + 15 00 00 00 00 00 02 40 25 + 15 01 00 00 00 00 02 FF 10]; + qcom,mdss-dsi-post-off-command = [ + 15 00 00 00 00 00 02 FF 27 + 15 00 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 3F 00 + 15 00 00 00 00 00 02 FF 10 + 05 00 00 00 00 00 02 28 00 + 05 01 00 00 46 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-post-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-displayoff-command = [05 01 00 00 20 00 02 28 00]; + qcom,mdss-dsi-displayon-command = [05 01 00 00 14 00 02 29 00]; + qcom,mdss-dsi-displayoff-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-displayon-command-state = "dsi_hs_mode"; + + + qcom,mdss-dsi-dispparam-cabcuion-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 01 + ]; + qcom,mdss-dsi-dispparam-cabcstillon-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 02 + ]; + qcom,mdss-dsi-dispparam-cabcmovieon-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 03 + ]; + qcom,mdss-dsi-dispparam-cabcoff-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 00 + ]; + qcom,mdss-dsi-dispparam-cabcuion-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-cabcstillon-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-cabcmovieon-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-cabcoff-command-state = "dsi_hs_mode"; + + qcom,mdss-dsi-dispparam-lcd-hbm-l1-on-command = [ + 15 00 00 00 00 00 02 FF 10 + 39 01 00 00 00 00 03 51 0E A0]; + qcom,mdss-dsi-dispparam-lcd-hbm-l1-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-lcd-hbm-l2-on-command = [ + 15 00 00 00 00 00 02 FF 10 + 39 01 00 00 00 00 03 51 FF FF]; + qcom,mdss-dsi-dispparam-lcd-hbm-l2-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-lcd-hbm-off-command = [ + 15 00 00 00 00 00 02 FF 10 + 39 01 00 00 00 00 03 51 0D B5]; + qcom,mdss-dsi-dispparam-lcd-hbm-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-h-sync-pulse = <1>; + qcom,compression-mode = "dsc"; + qcom,mdss-dsc-version = <0x11>; + qcom,mdss-dsc-scr-version = <0x0>; + qcom,mdss-dsc-slice-height = <20>; + qcom,mdss-dsc-slice-width = <540>; + qcom,mdss-dsc-slice-per-pkt = <2>; + qcom,mdss-dsc-bit-per-component = <8>; + qcom,mdss-dsc-bit-per-pixel = <8>; + qcom,mdss-dsc-block-prediction-enable; + }; + }; + }; +}; + +&dsi_j20s_42_02_0b_video { + mi,feature-enabled; + mi,is-tddi-flag; + mi,mdss-panel-on-dimming-delay = <120>; + mi,esd-err-irq-gpio = <&tlmm 24 0x2002>; /* trig-flags: falling-0x0002 rasing-0x0001*/ + mi,mdss-dsi-panel-xy-coordinate = <0x6 0x3>; + mi,mdss-dsi-panel-max-luminance = <0x6 0x4>; + mi,mdss-dsi-panel-status-value-ignore; + mi,esd-check-interval = <3000>; + mi,mdss-panel-idle-time = <1100>; + mi,mdss-panel-idle-fps = <50>; +// mi,mdss-dsi-pan-enable-smart-fps; + mi,mdss-dsi-dfps-dec-vfp-list = <20 0 20 0 0 0 + 0 0 0 0 0 0>; + mi,mdss-dsi-dfps-dec-hfp-list = <0 0 0 0 0 0 + 4 0 4 0 0 0>; + mi,mdss-dsi-post-off-msleep = <20>; + + qcom,mdss-dsi-display-timings { + timing@0{ + mi,mdss-dsi-read-lockdown-info-command = [ + 15 00 00 00 00 00 02 FF 21 + 06 01 00 00 00 00 01 F1]; + mi,mdss-dsi-read-lockdown-info-command-state = "dsi_lp_mode"; + + mi,mdss-dsi-cabcuion-command = [ + 15 00 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 01 + ]; + mi,mdss-dsi-cabcuion-command-state = "dsi_hs_mode"; + + mi,mdss-dsi-cabcstillon-command = [ + 15 00 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 02 + ]; + mi,mdss-dsi-cabcstillon-command-state = "dsi_hs_mode"; + + mi,mdss-dsi-cabcmovieon-command = [ + 15 00 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 03 + ]; + mi,mdss-dsi-cabcmovieon-command-state = "dsi_hs_mode"; + + mi,mdss-dsi-cabcoff-command = [ + 15 00 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 55 00 + ]; + mi,mdss-dsi-cabcoff-command-state = "dsi_hs_mode"; + + mi,mdss-dsi-cabc-dimmming-command = [ + 15 00 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 53 2C + ]; + mi,mdss-dsi-cabc-dimmming-command-state = "dsi_hs_mode"; + + mi,mdss-dsi-xy-coordinate-command = [ + 15 00 00 00 00 00 02 FF 10 + 06 01 00 00 00 00 01 A1]; + mi,mdss-dsi-xy-coordinate-command-state = "dsi_lp_mode"; + + mi,mdss-dsi-max-luminance-write-command = [ + 15 01 00 00 00 00 02 FF 10]; + mi,mdss-dsi-max-luminance-write-command-state = "dsi_lp_mode"; + + mi,mdss-dsi-max-luminance-read-command = [ + 06 01 00 00 00 00 01 A1]; + mi,mdss-dsi-max-luminance-read-command-state = "dsi_lp_mode"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-36-02-0b-video.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-36-02-0b-video.dtsi new file mode 100644 index 000000000000..536baccd575a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-36-02-0b-video.dtsi @@ -0,0 +1,367 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&mdss_mdp { + dsi_k82_36_02_0b_dual_cphy_video: qcom,mdss_dsi_k82_36_02_0b_dual_cphy_video { + qcom,mdss-dsi-panel-name = "xiaomi 36 02 0b video mode dual dsi cphy panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "xiaomi 36 02 0b VIDEO PANEL"; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-reset-sequence = <0 12>, <1 12>, <0 12>, <1 12>; + qcom,mdss-pan-physical-width-dimension = <1474>; + qcom,mdss-pan-physical-height-dimension = <2359>; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-rx-eot-ignore; + qcom,bl-update-flag = "delay_until_first_frame"; + qcom,cmd-sync-wait-broadcast; + qcom,panel-cphy-mode; + qcom,mdss-dsi-cphy-strength; + mi,cphy-esd-check; + mi,is-tddi-flag; + qcom,mdss-dsi-pan-enable-dynamic-fps; + qcom,mdss-dsi-pan-fps-update = + "dfps_immediate_porch_mode_vfp"; + qcom,dsi-supported-dfps-list = <120 60>; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4200000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-framerate = <120>; + qcom,mdss-dsi-panel-width = <800>; // 1600/2 + qcom,mdss-dsi-panel-height = <2560>; + qcom,mdss-dsi-h-pulse-width = <20>; + qcom,mdss-dsi-h-back-porch = <20>; + qcom,mdss-dsi-h-front-porch = <44>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-v-back-porch = <168>; + qcom,mdss-dsi-v-front-porch = <26>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + + qcom,mdss-dsi-on-command= [ + 15 00 00 00 00 00 02 FF 10 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 B9 05 + 15 00 00 00 00 00 02 FF 20 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 18 40 + 15 00 00 00 00 00 02 FF 10 + 15 00 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 B9 02 + /*CABC start*/ + 15 00 00 00 00 00 02 FF 23 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 00 80 + 15 00 00 00 00 00 02 01 84 + 15 00 00 00 00 00 02 05 2D + 15 00 00 00 00 00 02 06 00 + 15 00 00 00 00 00 02 07 00 + 15 00 00 00 00 00 02 08 01 + 15 00 00 00 00 00 02 09 45 + 15 00 00 00 00 00 02 11 02 + 15 00 00 00 00 00 02 12 80 + 15 00 00 00 00 00 02 15 83 + 15 01 00 00 00 00 02 16 0C + 15 00 00 00 00 00 02 29 0A + 15 00 00 00 00 00 02 30 FF + 15 00 00 00 00 00 02 31 FE + 15 00 00 00 00 00 02 32 FD + 15 00 00 00 00 00 02 33 FB + 15 00 00 00 00 00 02 34 F8 + 15 00 00 00 00 00 02 35 F5 + 15 00 00 00 00 00 02 36 F3 + 15 00 00 00 00 00 02 37 F2 + 15 00 00 00 00 00 02 38 F2 + 15 00 00 00 00 00 02 39 F2 + 15 00 00 00 00 00 02 3A EF + 15 00 00 00 00 00 02 3B EC + 15 00 00 00 00 00 02 3D E9 + 15 00 00 00 00 00 02 3F E5 + 15 00 00 00 00 00 02 40 E5 + 15 00 00 00 00 00 02 41 E5 + 15 00 00 00 00 00 02 2A 13 + 15 01 00 00 00 00 02 45 FF + 15 00 00 00 00 00 02 46 F4 + 15 00 00 00 00 00 02 47 E7 + 15 00 00 00 00 00 02 48 DA + 15 00 00 00 00 00 02 49 CD + 15 00 00 00 00 00 02 4A C0 + 15 00 00 00 00 00 02 4B B3 + 15 00 00 00 00 00 02 4C B2 + 15 00 00 00 00 00 02 4D B2 + 15 00 00 00 00 00 02 4E B2 + 15 00 00 00 00 00 02 4F 99 + 15 00 00 00 00 00 02 50 80 + 15 00 00 00 00 00 02 51 68 + 15 00 00 00 00 00 02 52 66 + 15 00 00 00 00 00 02 53 66 + 15 00 00 00 00 00 02 54 66 + 15 01 00 00 00 00 02 2B 0E + 15 00 00 00 00 00 02 58 FF + 15 00 00 00 00 00 02 59 FB + 15 00 00 00 00 00 02 5A F7 + 15 00 00 00 00 00 02 5B F3 + 15 00 00 00 00 00 02 5C EF + 15 00 00 00 00 00 02 5D E3 + 15 00 00 00 00 00 02 5E DA + 15 00 00 00 00 00 02 5F D8 + 15 00 00 00 00 00 02 60 D8 + 15 00 00 00 00 00 02 61 D8 + 15 00 00 00 00 00 02 62 CB + 15 00 00 00 00 00 02 63 BF + 15 00 00 00 00 00 02 64 B3 + 15 00 00 00 00 00 02 65 B2 + 15 00 00 00 00 00 02 66 B2 + 15 01 00 00 00 00 02 67 B2 + /*CABC end*/ + /*ESD start*/ + 15 00 00 00 00 00 02 FF F0 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 84 08 + 15 00 00 00 00 00 02 85 0C + 15 00 00 00 00 00 02 FF 20 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 51 00 + 15 00 00 00 00 00 02 FF 25 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 91 1F + 15 00 00 00 00 00 02 92 0F + 15 00 00 00 00 00 02 93 01 + 15 00 00 00 00 00 02 94 18 + 15 01 00 00 00 00 02 95 03 + 15 00 00 00 00 00 02 96 01 + 15 00 00 00 00 00 02 FF 10 + 15 00 00 00 00 00 02 B0 01 + 15 00 00 00 00 00 02 FF 25 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 19 1F + 15 00 00 00 00 00 02 1B 1B + 15 00 00 00 00 00 02 FF 24 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 B8 28 + 15 00 00 00 00 00 02 FF 27 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 D0 31 + 15 00 00 00 00 00 02 DE 80 + 15 00 00 00 00 00 02 DF 02 + 15 00 00 00 00 00 02 D1 20 + 15 00 00 00 00 00 02 D2 30 + 15 01 00 00 00 00 02 D4 08 + /*ESD end*/ + /*OSC start*/ + 15 00 00 00 00 00 02 FF 26 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 00 81 + 15 00 00 00 00 00 02 01 B0 + 15 00 00 00 00 00 02 FF 22 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 6F 01 + 15 00 00 00 00 00 02 70 11 + 15 00 00 00 00 00 02 73 01 + 15 00 00 00 00 00 02 74 46 + 15 00 00 00 00 00 02 A0 3F + 15 00 00 00 00 00 02 A9 50 + 15 00 00 00 00 00 02 AA 28 + 15 00 00 00 00 00 02 AB 28 + 15 01 00 00 00 00 02 AD 10 + 15 00 00 00 00 00 02 B8 00 + 15 00 00 00 00 00 02 B9 46 + 15 00 00 00 00 00 02 BA 8C + 15 00 00 00 00 00 02 BB 46 + 15 00 00 00 00 00 02 BE 0A + 15 00 00 00 00 00 02 BF 46 + 15 00 00 00 00 00 02 C0 0A + 15 00 00 00 00 00 02 C1 56 + 15 00 00 00 00 00 02 C2 00 + 15 00 00 00 00 00 02 C5 00 + 15 00 00 00 00 00 02 C6 00 + 15 01 00 00 00 00 02 C7 30 + 15 00 00 00 00 00 02 CA 00 + 15 00 00 00 00 00 02 CB 3C + 15 00 00 00 00 00 02 CE 00 + 15 00 00 00 00 00 02 CF 00 + 15 00 00 00 00 00 02 D0 38 + 15 00 00 00 00 00 02 D3 08 + 15 00 00 00 00 00 02 D4 3D + 15 00 00 00 00 00 02 FF 25 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 BC 01 + 15 00 00 00 00 00 02 BD 1C + 15 00 00 00 00 00 02 FF 2A + 15 00 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 9A 03 + /*OSC end*/ + 15 00 00 00 00 00 02 FF D0 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 00 32 + 15 00 00 00 00 00 02 02 FF + 15 00 00 00 00 00 02 09 FF + 15 00 00 00 00 00 02 53 22 + 15 00 00 00 00 00 02 54 02 + 15 00 00 00 00 00 02 1C 99 + 15 00 00 00 00 00 02 1D 09 + 15 00 00 00 00 00 02 FF E0 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 14 60 + 15 00 00 00 00 00 02 16 C0 + 15 00 00 00 00 00 02 4F 02 + 15 01 00 00 00 00 02 FF F0 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 3A 08 + 15 00 00 00 00 00 02 FF 10 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 BB 13 + 39 00 00 00 00 00 06 3B 03 AC 1A 04 04 + 15 00 00 00 00 00 02 35 00 + 39 00 00 00 00 00 03 51 0F FF + 15 01 00 00 00 00 02 53 2C + 05 01 00 00 46 00 02 11 00 + 15 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-off-command = [ + 05 01 00 00 00 00 02 28 00 + 05 01 00 00 46 00 02 10 00]; + qcom,mdss-dsi-displayoff-command = [05 01 00 00 20 00 02 28 00]; + qcom,mdss-dsi-displayon-command = [05 01 00 00 14 00 02 29 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-displayoff-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-displayon-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-pen-120hz-command = [ + 15 00 00 00 00 00 02 FF 2A + 15 00 00 00 00 00 02 23 0D + 15 01 00 00 00 00 02 FF 10]; + qcom,mdss-dsi-dispparam-pen-60hz-command = [ + 15 00 00 00 00 00 02 FF 2A + 15 00 00 00 00 00 02 23 0C + 15 01 00 00 00 00 02 FF 10]; + qcom,mdss-dsi-dispparam-pen-120hz-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-pen-60hz-command-state = "dsi_lp_mode"; + + /* max brightness 85% */ + qcom,mdss-dsi-dispparam-lcd-hbm-l1-on-command = [ + 15 01 00 00 00 00 02 FF 10 + 39 01 00 00 00 00 03 51 0F FF]; + qcom,mdss-dsi-dispparam-lcd-hbm-l1-on-command-state = "dsi_lp_mode"; + /* max brightness 91% */ + qcom,mdss-dsi-dispparam-lcd-hbm-l2-on-command = [ + 15 01 00 00 00 00 02 FF 10 + 39 01 00 00 00 00 03 51 0F FF]; + qcom,mdss-dsi-dispparam-lcd-hbm-l2-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-lcd-hbm-off-command = [ + 15 01 00 00 00 00 02 FF 10 + 39 01 00 00 00 00 03 51 0F FF]; + qcom,mdss-dsi-dispparam-lcd-hbm-off-command-state = "dsi_lp_mode"; + }; + }; + }; +}; + +&dsi_k82_36_02_0b_dual_cphy_video { + qcom,dispparam-enabled; + qcom,mdss-panel-on-dimming-delay = <120>; + qcom,esd-err-irq-gpio = <&tlmm 37 0x2002>; /* trig-flags: falling-0x0002 rasing-0x0001*/ + mi,mdss-dsi-panel-xy-coordinate = <0x3 0x3>; + mi,mdss-dsi-panel-max-luminance = <0x3 0x4>; + qcom,mdss-dsi-display-timings { + timing@0{ + mi,mdss-dsi-read-lockdown-info-command = [ + 15 01 00 00 00 00 02 FF 22 + 06 01 00 00 00 00 01 01 + 06 01 00 00 00 00 01 02 + 06 01 00 00 00 00 01 03 + 06 01 00 00 00 00 01 04 + 06 01 00 00 00 00 01 05 + 06 01 00 00 00 00 01 06 + 06 01 00 00 00 00 01 07 + 06 01 00 00 00 00 01 08]; + mi,mdss-dsi-read-lockdown-info-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-cabcuion-command = [ + 15 01 00 00 00 00 02 55 01 + ]; + qcom,mdss-dsi-dispparam-cabcstillon-command = [ + 15 01 00 00 00 00 02 55 02 + ]; + qcom,mdss-dsi-dispparam-cabcmovieon-command = [ + 15 01 00 00 00 00 02 55 03 + ]; + qcom,mdss-dsi-dispparam-cabcoff-command = [ + 15 01 00 00 00 00 02 55 00 + ]; + qcom,mdss-dsi-dispparam-dimmingon-command = [ + /* CABC DIMMING ON */ + 15 01 00 00 00 00 02 53 2C + ]; + qcom,mdss-dsi-dispparam-dimmingoff-command = [ + 15 01 00 00 00 00 02 53 24 + ]; + + qcom,mdss-dsi-dispparam-cabcuion-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-cabcstillon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-cabcmovieon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-cabcoff-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingoff-command-state = "dsi_lp_mode"; + mi,mdss-dsi-esd-check-read-command = [ + /* esd detect */ + 15 01 00 00 00 00 02 FF 27 + 15 01 00 00 00 00 02 D1 28 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 53 2C + ]; + mi,mdss-dsi-esd-check-read-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-xy-coordinate-command = [ + 15 01 00 00 00 00 02 FF 10 + 06 01 00 00 00 00 01 A1 + ]; + qcom,mdss-dsi-dispparam-xy-coordinate-command-state = "dsi_lp_mode"; + + mi,mdss-dsi-max-luminance-write-command = [ + 15 01 00 00 00 00 02 FF 10]; + mi,mdss-dsi-max-luminance-write-command-state = "dsi_lp_mode"; + mi,mdss-dsi-max-luminance-read-command = [ + 06 01 00 00 00 00 01 A1]; + mi,mdss-dsi-max-luminance-read-command-state = "dsi_lp_mode"; + }; + }; +}; + + diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-42-02-0a-video.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-42-02-0a-video.dtsi new file mode 100644 index 000000000000..22c3e689801b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-42-02-0a-video.dtsi @@ -0,0 +1,381 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&mdss_mdp { + dsi_k82_42_02_0a_dual_cphy_video: qcom,mdss_dsi_k82_42_02_0a_dual_cphy_video { + qcom,mdss-dsi-panel-name = "xiaomi 42 02 0a video mode dual dsi cphy panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "xiaomi 42 02 0a VIDEO PANEL"; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-reset-sequence = <0 12>, <1 12>, <0 12>, <1 12>; + qcom,mdss-pan-physical-width-dimension = <1474>; + qcom,mdss-pan-physical-height-dimension = <2359>; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-rx-eot-ignore; + qcom,bl-update-flag = "delay_until_first_frame"; + qcom,cmd-sync-wait-broadcast; + qcom,panel-cphy-mode; + qcom,mdss-dsi-cphy-strength; + mi,cphy-esd-check; + mi,is-tddi-flag; + qcom,mdss-dsi-pan-enable-dynamic-fps; + qcom,mdss-dsi-pan-fps-update = + "dfps_immediate_porch_mode_vfp"; + qcom,dsi-supported-dfps-list = <120 60>; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4200000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-framerate = <120>; + qcom,mdss-dsi-panel-width = <800>; // 1600/2 + qcom,mdss-dsi-panel-height = <2560>; + qcom,mdss-dsi-h-pulse-width = <20>; + qcom,mdss-dsi-h-back-porch = <20>; + qcom,mdss-dsi-h-front-porch = <44>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-v-back-porch = <168>; + qcom,mdss-dsi-v-front-porch = <26>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + + qcom,mdss-dsi-on-command= [ + 15 00 00 00 00 00 02 FF 10 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 B9 05 + 15 00 00 00 00 00 02 FF 20 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 18 40 + 15 01 00 00 00 00 02 FF 10 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 B9 02 + 15 00 00 00 00 00 02 FF D0 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 02 AF + 15 00 00 00 00 00 02 00 30 + 15 00 00 00 00 00 02 09 EE + 15 00 00 00 00 00 02 1C 99 + 15 01 00 00 00 00 02 1D 09 + 15 00 00 00 00 00 02 FF F0 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 3A 08 + 15 00 00 00 00 00 02 FF E0 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 4F 02 + 15 00 00 00 00 00 02 FF 10 + 15 00 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 35 00 + /* CABC SETTING CFG Start*/ + 15 00 00 00 00 00 02 FF 23 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 00 80 + 15 00 00 00 00 00 02 01 84 + 15 00 00 00 00 00 02 05 2D + 15 00 00 00 00 00 02 06 00 + 15 00 00 00 00 00 02 07 00 + 15 00 00 00 00 00 02 08 01 + 15 00 00 00 00 00 02 09 45 + 15 00 00 00 00 00 02 11 02 + 15 00 00 00 00 00 02 12 80 + 15 00 00 00 00 00 02 15 83 + 15 00 00 00 00 00 02 16 0C + 15 01 00 00 00 00 02 29 0A + 15 00 00 00 00 00 02 30 FF + 15 00 00 00 00 00 02 31 FE + 15 00 00 00 00 00 02 32 FD + 15 00 00 00 00 00 02 33 FB + 15 00 00 00 00 00 02 34 F8 + 15 00 00 00 00 00 02 35 F5 + 15 00 00 00 00 00 02 36 F3 + 15 00 00 00 00 00 02 37 F2 + 15 00 00 00 00 00 02 38 F2 + 15 00 00 00 00 00 02 39 F2 + 15 00 00 00 00 00 02 3A EF + 15 00 00 00 00 00 02 3B EC + 15 00 00 00 00 00 02 3D E9 + 15 00 00 00 00 00 02 3F E5 + 15 00 00 00 00 00 02 40 E5 + 15 01 00 00 00 00 02 41 E5 + 15 00 00 00 00 00 02 2A 13 + 15 00 00 00 00 00 02 45 FF + 15 00 00 00 00 00 02 46 F4 + 15 00 00 00 00 00 02 47 E7 + 15 00 00 00 00 00 02 48 DA + 15 00 00 00 00 00 02 49 CD + 15 00 00 00 00 00 02 4A C0 + 15 00 00 00 00 00 02 4B B3 + 15 00 00 00 00 00 02 4C B2 + 15 00 00 00 00 00 02 4D B2 + 15 00 00 00 00 00 02 4E B2 + 15 00 00 00 00 00 02 4F 99 + 15 00 00 00 00 00 02 50 80 + 15 00 00 00 00 00 02 51 68 + 15 00 00 00 00 00 02 52 66 + 15 00 00 00 00 00 02 53 66 + 15 01 00 00 00 00 02 54 66 + 15 00 00 00 00 00 02 2B 0E + 15 00 00 00 00 00 02 58 FF + 15 00 00 00 00 00 02 59 FB + 15 00 00 00 00 00 02 5A F7 + 15 00 00 00 00 00 02 5B F3 + 15 00 00 00 00 00 02 5C EF + 15 00 00 00 00 00 02 5D E3 + 15 00 00 00 00 00 02 5E DA + 15 00 00 00 00 00 02 5F D8 + 15 00 00 00 00 00 02 60 D8 + 15 00 00 00 00 00 02 61 D8 + 15 00 00 00 00 00 02 62 CB + 15 00 00 00 00 00 02 63 BF + 15 00 00 00 00 00 02 64 B3 + 15 00 00 00 00 00 02 65 B2 + 15 00 00 00 00 00 02 66 B2 + 15 00 00 00 00 00 02 67 B2 + 15 00 00 00 00 00 02 FF 10 + 15 00 00 00 00 00 02 FB 01 + 39 00 00 00 00 00 03 51 0F FF + 15 01 00 00 00 00 02 53 24 + /* CABC SETTING CFG END */ + 15 00 00 00 00 00 02 55 00 + 15 00 00 00 00 00 02 BB 13 + 39 01 00 00 00 00 06 3B 03 AC 1A 04 04 + /* 30HZ pen code Start*/ + 15 00 00 00 00 00 02 FF 2A + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 25 46 + 15 00 00 00 00 00 02 30 46 + 15 00 00 00 00 00 02 39 46 + 15 00 00 00 00 00 02 FF 26 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 01 B0 + 15 00 00 00 00 00 02 19 10 + 15 00 00 00 00 00 02 1A E0 + 15 00 00 00 00 00 02 1B 10 + 15 00 00 00 00 00 02 1C 00 + 15 00 00 00 00 00 02 2A 10 + 15 01 00 00 00 00 02 2B E0 + /* 30HZ pen code END*/ + /* ESD code*/ + 15 01 00 00 00 00 02 FF 26 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 01 B0 + 15 01 00 00 00 00 02 FF F0 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 84 08 + 15 00 00 00 00 00 02 85 0C + 15 01 00 00 00 00 02 FF 20 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 51 00 + 15 01 00 00 00 00 02 FF 25 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 91 1F + 15 00 00 00 00 00 02 92 0F + 15 00 00 00 00 00 02 93 01 + 15 00 00 00 00 00 02 94 18 + 15 00 00 00 00 00 02 95 03 + 15 00 00 00 00 00 02 96 01 + 15 01 00 00 00 00 02 FF 10 + 15 00 00 00 00 00 02 B0 01 + 15 01 00 00 00 00 02 FF 25 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 19 1F + 15 00 00 00 00 00 02 1B 1B + 15 01 00 00 00 00 02 FF 24 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 B8 28 + 15 01 00 00 00 00 02 FF 27 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 D0 31 + 15 00 00 00 00 00 02 DE 80 + 15 00 00 00 00 00 02 DF 02 + 15 00 00 00 00 00 02 D1 20 + 15 01 00 00 00 00 02 D4 08 + 15 00 00 00 00 00 02 FF 26 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 00 81 + 15 00 00 00 00 00 02 01 B0 + 15 01 00 00 00 00 02 FF 22 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 6F 01 + 15 00 00 00 00 00 02 70 11 + 15 00 00 00 00 00 02 73 01 + 15 00 00 00 00 00 02 74 4D + 15 00 00 00 00 00 02 A0 3F + 15 00 00 00 00 00 02 A9 50 + 15 00 00 00 00 00 02 AA 28 + 15 00 00 00 00 00 02 AB 28 + 15 00 00 00 00 00 02 AD 10 + 15 00 00 00 00 00 02 B8 00 + 15 00 00 00 00 00 02 B9 4B + 15 01 00 00 00 00 02 BA 96 + 15 00 00 00 00 00 02 BB 4B + 15 00 00 00 00 00 02 BE 07 + 15 00 00 00 00 00 02 BF 4B + 15 00 00 00 00 00 02 C0 07 + 15 00 00 00 00 00 02 C1 5C + 15 00 00 00 00 00 02 C2 00 + 15 00 00 00 00 00 02 C5 00 + 15 00 00 00 00 00 02 C6 3F + 15 00 00 00 00 00 02 C7 00 + 15 00 00 00 00 00 02 CA 08 + 15 00 00 00 00 00 02 CB 40 + 15 00 00 00 00 00 02 CE 00 + 15 01 00 00 00 00 02 CF 08 + 15 00 00 00 00 00 02 D0 40 + 15 00 00 00 00 00 02 D3 08 + 15 00 00 00 00 00 02 D4 40 + 15 00 00 00 00 00 02 FF 25 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 BC 01 + 15 00 00 00 00 00 02 BD 1C + 15 00 00 00 00 00 02 FF 2A + 15 00 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 9A 03 + 15 01 00 00 00 00 02 FF 10 + 05 01 00 00 46 00 02 11 00 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-off-command = [ + 05 01 00 00 00 00 02 28 00 + 05 01 00 00 46 00 02 10 00]; + qcom,mdss-dsi-displayoff-command = [05 01 00 00 20 00 02 28 00]; + qcom,mdss-dsi-displayon-command = [05 01 00 00 14 00 02 29 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-displayoff-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-displayon-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-pen-120hz-command = [ + 15 00 00 00 00 00 02 FF 2A + 15 00 00 00 00 00 02 23 0D + 15 01 00 00 00 00 02 FF 10]; + qcom,mdss-dsi-dispparam-pen-60hz-command = [ + 15 00 00 00 00 00 02 FF 2A + 15 00 00 00 00 00 02 23 0C + 15 01 00 00 00 00 02 FF 10]; + qcom,mdss-dsi-dispparam-pen-120hz-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-pen-60hz-command-state = "dsi_lp_mode"; + + /* max brightness 85% */ + qcom,mdss-dsi-dispparam-lcd-hbm-l1-on-command = [ + 15 01 00 00 00 00 02 FF 10 + 39 01 00 00 00 00 03 51 0F FF]; + qcom,mdss-dsi-dispparam-lcd-hbm-l1-on-command-state = "dsi_lp_mode"; + /* max brightness 91% */ + qcom,mdss-dsi-dispparam-lcd-hbm-l2-on-command = [ + 15 01 00 00 00 00 02 FF 10 + 39 01 00 00 00 00 03 51 0F FF]; + qcom,mdss-dsi-dispparam-lcd-hbm-l2-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-lcd-hbm-off-command = [ + 15 01 00 00 00 00 02 FF 10 + 39 01 00 00 00 00 03 51 0F FF]; + qcom,mdss-dsi-dispparam-lcd-hbm-off-command-state = "dsi_lp_mode"; + }; + }; + }; +}; + +&dsi_k82_42_02_0a_dual_cphy_video { + qcom,dispparam-enabled; + qcom,mdss-panel-on-dimming-delay = <120>; + qcom,esd-err-irq-gpio = <&tlmm 37 0x2002>; /* trig-flags: falling-0x0002 rasing-0x0001*/ + mi,mdss-dsi-panel-xy-coordinate = <0x3 0x3>; + mi,mdss-dsi-panel-max-luminance = <0x3 0x4>; + qcom,mdss-dsi-display-timings { + timing@0{ + mi,mdss-dsi-read-lockdown-info-command = [ + 15 01 00 00 00 00 02 FF 22 + 06 01 00 00 00 00 01 01 + 06 01 00 00 00 00 01 02 + 06 01 00 00 00 00 01 03 + 06 01 00 00 00 00 01 04 + 06 01 00 00 00 00 01 05 + 06 01 00 00 00 00 01 06 + 06 01 00 00 00 00 01 07 + 06 01 00 00 00 00 01 08]; + mi,mdss-dsi-read-lockdown-info-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-cabcuion-command = [ + 15 01 00 00 00 00 02 55 01 + ]; + qcom,mdss-dsi-dispparam-cabcstillon-command = [ + 15 01 00 00 00 00 02 55 02 + ]; + qcom,mdss-dsi-dispparam-cabcmovieon-command = [ + 15 01 00 00 00 00 02 55 03 + ]; + qcom,mdss-dsi-dispparam-cabcoff-command = [ + 15 01 00 00 00 00 02 55 00 + ]; + qcom,mdss-dsi-dispparam-dimmingon-command = [ + /* CABC DIMMING ON */ + 15 01 00 00 00 00 02 53 2C + ]; + qcom,mdss-dsi-dispparam-dimmingoff-command = [ + 15 01 00 00 00 00 02 53 24 + ]; + + qcom,mdss-dsi-dispparam-cabcuion-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-cabcstillon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-cabcmovieon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-cabcoff-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingoff-command-state = "dsi_lp_mode"; + mi,mdss-dsi-esd-check-read-command = [ + /* esd detect */ + 15 01 00 00 00 00 02 FF 27 + 15 01 00 00 00 00 02 D1 28 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 53 2C + ]; + mi,mdss-dsi-esd-check-read-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-xy-coordinate-command = [ + 15 01 00 00 00 00 02 FF 10 + 06 01 00 00 00 00 01 A1 + ]; + qcom,mdss-dsi-dispparam-xy-coordinate-command-state = "dsi_lp_mode"; + + mi,mdss-dsi-max-luminance-write-command = [ + 15 01 00 00 00 00 02 FF 10]; + mi,mdss-dsi-max-luminance-write-command-state = "dsi_lp_mode"; + mi,mdss-dsi-max-luminance-read-command = [ + 06 01 00 00 00 00 01 A1]; + mi,mdss-dsi-max-luminance-read-command-state = "dsi_lp_mode"; + }; + }; +}; + diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-cmd.dtsi new file mode 100644 index 000000000000..db08ebcd43f0 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-cmd.dtsi @@ -0,0 +1,253 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&soc { + dsi_samsung_fhd_ea8076_cmd: qcom,mdss_dsi_samsung_fhd_ea8076_cmd { + qcom,mdss-dsi-panel-name = "samsung ea8076 fhd cmd dsi panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "SAMSUNG FHD EA8076 CMD PANEL"; + qcom,mdss-dsi-panel-sleepwrmod = <0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,ulps-enabled; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-brightness-max-level = <2047>; + qcom,bl-update-flag = "delay_until_first_frame"; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-dcs-type-ss; + qcom,mdss-dsi-reset-sequence = <0 1>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <68>; + qcom,mdss-pan-physical-height-dimension = <147>; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 + 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4300000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + + qcom,dispparam-enabled; + qcom,mdss-panel-on-dimming-delay = <120>; + qcom,disp-doze-backlight-threshold = <8>; + /* IRQF_ONESHOT | IRQF_TRIGGER_FALLING */ + qcom,esd-err-irq-gpio = <&tlmm 27 0x2002>; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2340>; + qcom,mdss-dsi-h-front-porch = <64>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <20>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <64>; + qcom,mdss-dsi-v-front-porch = <64>; + qcom,mdss-dsi-v-pulse-width = <20>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-panel-clockrate = <1100000000>; + qcom,mdss-dsi-panel-jitter = <0x5 0x1>; + qcom,mdss-dsi-on-command = [ + /* delay 2ms for VCI1 power */ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 FC 5A 5A + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 FF 10 + 39 00 00 00 00 00 02 B0 2F + 39 00 00 00 00 00 02 D1 01 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 03 FC A5 A5 + /* Sleep Out */ + 05 01 00 00 0A 00 02 11 00 + 39 00 00 00 00 00 03 F0 5A 5A + /* TE OUT(Vsync On) */ + 39 00 00 00 00 00 02 35 00 + /* DBV Smooth Transition */ + 39 00 00 00 00 00 03 B7 01 4B + /* Timing set */ + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 03 D9 88 2E + /* Edge Dimming */ + 39 00 00 00 00 00 02 B0 09 + 39 00 00 00 00 00 02 D8 00 + 39 01 00 00 00 00 03 F0 A5 A5 + /* Page Address Set */ + 39 01 00 00 00 00 05 2B 00 00 09 23 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 FC 5A 5A + /* ERR_FG Setting */ + 39 00 00 00 00 00 07 E1 00 00 02 02 42 02 + 39 00 00 00 00 00 07 E2 00 00 00 00 00 00 + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 E1 19 + /* OFC Setting 82.6Mhz*/ + 39 00 00 00 00 00 0C E9 11 55 A6 75 A3 B8 BB 2A 00 1A B8 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 03 FC A5 A5 + /* Brightness Control */ + 39 00 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 51 00 00 + 39 01 00 00 43 00 02 55 00 + /* Display On */ + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-off-command = [ + 05 01 00 00 00 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-doze-hbm-command = [ + /* AOD ON Sequence (Normal To AOD HBM) */ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 00 00 00 01 00 02 53 22 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-doze-lbm-command = [ + /* AOD ON Sequence (Normal To AOD LBM) */ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 00 00 00 00 00 02 53 23 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-nolp-command = [ + /* AOD OFF Sequence (AOD To Normal) */ + 05 01 00 00 22 00 02 28 00 + 39 01 00 00 00 00 02 53 20 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-doze-hbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-doze-lbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-nolp-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-acl-off-command = [39 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-dispparam-acl-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l1-command = [39 01 00 00 00 00 02 55 01];/* 50% */ + qcom,mdss-dsi-dispparam-acl-l1-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l2-command = [39 01 00 00 00 00 02 55 02];/* 40% */ + qcom,mdss-dsi-dispparam-acl-l2-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l3-command = [39 01 00 00 00 00 02 55 03];/* 30% */ + qcom,mdss-dsi-dispparam-acl-l3-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-hbm-off-command = [39 01 00 00 00 00 02 53 28]; + qcom,mdss-dsi-dispparam-hbm-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-on-command = [39 01 00 00 00 00 02 53 E8]; + qcom,mdss-dsi-dispparam-hbm-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 01 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-fod2norm-command = [39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B2 00 40 + 39 00 00 00 00 00 02 B0 04 + 39 00 00 00 00 00 02 B2 80 + 39 00 00 00 00 00 02 F7 03 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod2norm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingon-command = [39 01 00 00 01 00 02 53 28]; + qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingoff-command = [39 01 00 00 01 00 02 53 20]; + qcom,mdss-dsi-dispparam-dimmingoff-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-srgb-on-command = [ + /* CRC Enable + sRGB mode */ + 39 01 00 00 00 00 02 81 90 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 BD 02 00 14 D1 00 04 07 AA 0C EC CB C8 0F DD D9 E4 05 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-srgb-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command = [ + /* CRC Enable + DCI-P3 mode */ + 39 01 00 00 00 00 02 81 91 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 CB 0B 01 0B EC 03 05 08 CF 14 FA FA E7 05 EE EE F2 00 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-off-command = [ + /* CRC Disable (Normal mode) */ + 39 01 00 00 00 00 02 81 00 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Bypass */ + 39 01 00 00 00 00 02 B1 01 + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-h-sync-pulse = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi new file mode 100644 index 000000000000..3c1462365a3c --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi @@ -0,0 +1,254 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&soc { + dsi_samsung_fhd_ea8076_f1_cmd: qcom,mdss_dsi_samsung_fhd_ea8076_f1_cmd { + qcom,mdss-dsi-panel-name = "samsung ea8076 fhd cmd dsi panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "SAMSUNG FHD EA8076 CMD PANEL"; + qcom,mdss-dsi-panel-sleepwrmod = <0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,ulps-enabled; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-brightness-max-level = <2047>; + qcom,bl-update-flag = "delay_until_first_frame"; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-dcs-type-ss; + qcom,mdss-dsi-reset-sequence = <0 1>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <68>; + qcom,mdss-pan-physical-height-dimension = <147>; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 + 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4300000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + + qcom,dispparam-enabled; + qcom,mdss-panel-on-dimming-delay = <200>; + /* IRQF_ONESHOT | IRQF_TRIGGER_FALLING */ + qcom,esd-err-irq-gpio = <&tlmm 5 0x2002>; + + qcom,disp-doze-backlight-threshold = <8>; + qcom,disp-fod-off-dimming-delay = <85>; + + qcom,elvss_dimming_check_enable; + qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command = [39 01 00 00 00 00 02 B0 07]; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2340>; + qcom,mdss-dsi-h-front-porch = <64>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <20>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <64>; + qcom,mdss-dsi-v-front-porch = <64>; + qcom,mdss-dsi-v-pulse-width = <20>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-panel-clockrate = <1100000000>; + qcom,mdss-dsi-panel-jitter = <0x5 0x1>; + qcom,mdss-dsi-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 FC 5A 5A + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 FF 10 + 39 00 00 00 00 00 02 B0 2F + 39 01 00 00 00 00 02 D1 01 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 03 FC A5 A5 + 05 01 00 00 0A 00 02 11 00 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 35 00 + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 06 + 39 00 00 00 00 00 02 B7 10 + 39 01 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 05 2B 00 00 09 23 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 FC 5A 5A + 39 00 00 00 00 00 02 B0 23 + 39 00 00 00 00 00 02 D1 33 + 39 00 00 00 00 00 0C E9 11 55 A6 75 A3 A6 37 BE 00 1A B8 + 39 00 00 00 00 00 0C D9 14 00 00 8F 6E 00 00 8F 2E 6E 34 + 39 00 00 00 00 00 6D C0 31 01 03 00 06 00 00 00 00 00 00 00 00 00 00 00 00 50 00 00 40 3D 00 5E 00 00 00 20 07 20 30 58 00 00 00 00 00 00 E0 0B 75 D8 00 00 00 00 FC 00 00 00 F6 97 0F 6D E6 CD 05 21 8B EC ED ED ED 0D 3F 60 00 67 FD 6D 51 BC DD DD 00 00 07 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 70 2F 00 00 03 2E 3C 20 E0 00 00 00 00 00 06 8C + 39 01 00 00 00 00 02 C0 31 + 39 00 00 00 00 00 07 E1 00 00 02 02 42 02 + 39 00 00 00 00 00 07 E2 00 00 00 00 00 00 + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 E1 19 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 03 FC A5 A5 + 39 00 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 51 00 00 + 39 01 00 00 43 00 02 55 00 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-off-command = [ + 05 01 00 00 00 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-doze-hbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 01 00 02 53 22 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-doze-lbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 00 00 02 53 23 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-nolp-command = [ + 05 01 00 00 22 00 02 28 00 + 39 01 00 00 00 00 02 53 20 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-doze-hbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-doze-lbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-nolp-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-acl-off-command = [39 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-dispparam-acl-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l1-command = [39 01 00 00 00 00 02 55 01];/* 50% */ + qcom,mdss-dsi-dispparam-acl-l1-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l2-command = [39 01 00 00 00 00 02 55 02];/* 40% */ + qcom,mdss-dsi-dispparam-acl-l2-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l3-command = [39 01 00 00 00 00 02 55 03];/* 30% */ + qcom,mdss-dsi-dispparam-acl-l3-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-hbm-off-command = [39 01 00 00 00 00 02 53 28]; + qcom,mdss-dsi-dispparam-hbm-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-on-command = [39 01 00 00 00 00 02 53 E8]; + qcom,mdss-dsi-dispparam-hbm-on-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-dimmingon-command = [39 01 00 00 01 00 02 53 28]; + qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingoff-command = [39 01 00 00 01 00 02 53 20]; + qcom,mdss-dsi-dispparam-dimmingoff-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-srgb-on-command = [ + /* CRC Enable + sRGB mode */ + 39 01 00 00 00 00 02 81 90 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 BD 02 00 14 D1 00 04 07 AA 0C EC CB C8 0F DD D9 E4 05 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-srgb-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command = [ + /* CRC Enable + DCI-P3 mode */ + 39 01 00 00 00 00 02 81 91 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 CB 0B 01 0B EC 03 05 08 CF 14 FA FA E7 05 EE EE F2 00 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-off-command = [ + /* CRC Disable (Normal mode) */ + 39 01 00 00 00 00 02 81 00 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Bypass */ + 39 01 00 00 00 00 02 B1 01 + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi new file mode 100644 index 000000000000..42c7ecc8ea2b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi @@ -0,0 +1,254 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&soc { + dsi_samsung_fhd_ea8076_f1mp_cmd: qcom,mdss_dsi_samsung_fhd_ea8076_f1mp_cmd { + qcom,mdss-dsi-panel-name = "samsung ea8076 fhd cmd dsi panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "SAMSUNG FHD EA8076 CMD PANEL"; + qcom,mdss-dsi-panel-sleepwrmod = <0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,ulps-enabled; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-brightness-max-level = <2047>; + qcom,bl-update-flag = "delay_until_first_frame"; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-dcs-type-ss; + qcom,mdss-dsi-reset-sequence = <0 1>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <68>; + qcom,mdss-pan-physical-height-dimension = <147>; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 + 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4300000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + + qcom,dispparam-enabled; + qcom,mdss-panel-on-dimming-delay = <200>; + /* IRQF_ONESHOT | IRQF_TRIGGER_FALLING */ + qcom,esd-err-irq-gpio = <&tlmm 5 0x2002>; + + qcom,disp-doze-backlight-threshold = <8>; + qcom,disp-fod-off-dimming-delay = <85>; + + qcom,elvss_dimming_check_enable; + qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command = [39 01 00 00 00 00 02 B0 07]; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2340>; + qcom,mdss-dsi-h-front-porch = <64>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <20>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <64>; + qcom,mdss-dsi-v-front-porch = <64>; + qcom,mdss-dsi-v-pulse-width = <20>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-panel-clockrate = <1100000000>; + qcom,mdss-dsi-panel-jitter = <0x5 0x1>; + qcom,mdss-dsi-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 FC 5A 5A + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 FF 10 + 39 00 00 00 00 00 02 B0 2F + 39 01 00 00 00 00 02 D1 01 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 03 FC A5 A5 + 05 01 00 00 0A 00 02 11 00 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 35 00 + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 06 + 39 00 00 00 00 00 02 B7 10 + 39 01 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 05 2B 00 00 09 23 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 FC 5A 5A + 39 00 00 00 00 00 02 B0 23 + 39 00 00 00 00 00 02 D1 33 + 39 00 00 00 00 00 0C E9 11 55 A6 75 A3 A6 37 BE 00 1A B8 + 39 00 00 00 00 00 0C D9 14 00 00 8F 6E 00 00 8F 2E 6E 34 + 39 00 00 00 00 00 6D C0 31 01 03 00 06 00 00 00 00 00 00 00 00 00 00 00 00 50 00 00 40 3D 00 5E 00 00 00 20 07 20 30 58 00 00 00 00 00 00 E0 0B 75 D8 00 00 00 00 FC 00 00 00 F6 97 0F 6D E6 CD 05 21 8B EC ED ED ED 0D 3F 60 00 67 FD 6D 51 BC DD DD 00 00 07 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 70 2F 00 00 03 2E 3C 20 E0 00 00 00 00 00 06 8C + 39 01 00 00 00 00 02 C0 31 + 39 00 00 00 00 00 07 E1 00 00 02 02 42 02 + 39 00 00 00 00 00 07 E2 00 00 00 00 00 00 + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 E1 19 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 03 FC A5 A5 + 39 00 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 51 00 00 + 39 01 00 00 43 00 02 55 00 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-off-command = [ + 05 01 00 00 00 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-doze-hbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 01 00 02 53 22 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-doze-lbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 00 00 02 53 23 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-nolp-command = [ + 05 01 00 00 22 00 02 28 00 + 39 01 00 00 00 00 02 53 20 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-doze-hbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-doze-lbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-nolp-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-acl-off-command = [39 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-dispparam-acl-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l1-command = [39 01 00 00 00 00 02 55 01];/* 50% */ + qcom,mdss-dsi-dispparam-acl-l1-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l2-command = [39 01 00 00 00 00 02 55 02];/* 40% */ + qcom,mdss-dsi-dispparam-acl-l2-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l3-command = [39 01 00 00 00 00 02 55 03];/* 30% */ + qcom,mdss-dsi-dispparam-acl-l3-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-hbm-off-command = [39 01 00 00 00 00 02 53 28]; + qcom,mdss-dsi-dispparam-hbm-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-on-command = [39 01 00 00 00 00 02 53 E8]; + qcom,mdss-dsi-dispparam-hbm-on-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-dimmingon-command = [39 01 00 00 01 00 02 53 28]; + qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingoff-command = [39 01 00 00 01 00 02 53 20]; + qcom,mdss-dsi-dispparam-dimmingoff-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-srgb-on-command = [ + /* CRC Enable + sRGB mode */ + 39 01 00 00 00 00 02 81 90 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 BD 02 00 14 D1 00 04 07 AA 0C EC CB C8 0F DD D9 E4 05 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-srgb-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command = [ + /* CRC Enable + DCI-P3 mode */ + 39 01 00 00 00 00 02 81 91 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 CB 0B 01 0B EC 03 05 08 CF 14 FA FA E7 05 EE EE F2 00 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-off-command = [ + /* CRC Disable (Normal mode) */ + 39 01 00 00 00 00 02 81 00 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Bypass */ + 39 01 00 00 00 00 02 B1 01 + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi new file mode 100644 index 000000000000..437185f1b1a1 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi @@ -0,0 +1,254 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&soc { + dsi_samsung_fhd_ea8076_f1p2_2_cmd: qcom,mdss_dsi_samsung_fhd_ea8076_f1p2_2_cmd { + qcom,mdss-dsi-panel-name = "samsung ea8076 fhd cmd dsi panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "SAMSUNG FHD EA8076 CMD PANEL"; + qcom,mdss-dsi-panel-sleepwrmod = <0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,ulps-enabled; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-brightness-max-level = <2047>; + qcom,bl-update-flag = "delay_until_first_frame"; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-dcs-type-ss; + qcom,mdss-dsi-reset-sequence = <0 1>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <68>; + qcom,mdss-pan-physical-height-dimension = <147>; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 + 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4300000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + + qcom,dispparam-enabled; + qcom,mdss-panel-on-dimming-delay = <200>; + /* IRQF_ONESHOT | IRQF_TRIGGER_FALLING */ + qcom,esd-err-irq-gpio = <&tlmm 5 0x2002>; + + qcom,disp-doze-backlight-threshold = <8>; + qcom,disp-fod-off-dimming-delay = <85>; + + qcom,elvss_dimming_check_enable; + qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command = [39 01 00 00 00 00 02 B0 07]; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2340>; + qcom,mdss-dsi-h-front-porch = <64>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <20>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <64>; + qcom,mdss-dsi-v-front-porch = <64>; + qcom,mdss-dsi-v-pulse-width = <20>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-panel-clockrate = <1100000000>; + qcom,mdss-dsi-panel-jitter = <0x5 0x1>; + qcom,mdss-dsi-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 FC 5A 5A + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 FF 10 + 39 00 00 00 00 00 02 B0 2F + 39 01 00 00 00 00 02 D1 01 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 03 FC A5 A5 + 05 01 00 00 0A 00 02 11 00 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 35 00 + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 06 + 39 00 00 00 00 00 02 B7 10 + 39 01 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 05 2B 00 00 09 23 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 FC 5A 5A + 39 00 00 00 00 00 02 B0 24 + 39 00 00 00 00 00 02 D1 33 + 39 00 00 00 00 00 0C E9 11 55 A6 75 A3 A6 37 BE 00 1A B8 + 39 00 00 00 00 00 0C D9 14 00 00 8F 6E 00 00 8F 2E 6E 34 + 39 00 00 00 00 00 6D C0 31 01 03 00 06 00 00 00 00 00 00 00 00 00 00 00 00 50 00 00 40 3D 00 5E 00 00 00 20 07 20 30 58 00 00 00 00 00 00 E0 0B 75 D8 00 00 00 00 FC 00 00 00 F6 97 0F 6D E6 CD 05 21 8B EC ED ED ED 0D 3F 60 00 67 FD 6D 51 BC DD DD 00 00 07 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 70 2F 00 00 03 2E 3C 20 E0 00 00 00 00 00 06 8C + 39 01 00 00 00 00 02 C0 31 + 39 00 00 00 00 00 07 E1 00 00 02 02 42 02 + 39 00 00 00 00 00 07 E2 00 00 00 00 00 00 + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 E1 19 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 03 FC A5 A5 + 39 00 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 51 00 00 + 39 01 00 00 43 00 02 55 00 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-off-command = [ + 05 01 00 00 00 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-doze-hbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 01 00 02 53 22 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-doze-lbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 00 00 02 53 23 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-nolp-command = [ + 05 01 00 00 22 00 02 28 00 + 39 01 00 00 00 00 02 53 20 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-doze-hbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-doze-lbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-nolp-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-acl-off-command = [39 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-dispparam-acl-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l1-command = [39 01 00 00 00 00 02 55 01];/* 50% */ + qcom,mdss-dsi-dispparam-acl-l1-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l2-command = [39 01 00 00 00 00 02 55 02];/* 40% */ + qcom,mdss-dsi-dispparam-acl-l2-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l3-command = [39 01 00 00 00 00 02 55 03];/* 30% */ + qcom,mdss-dsi-dispparam-acl-l3-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-hbm-off-command = [39 01 00 00 00 00 02 53 28]; + qcom,mdss-dsi-dispparam-hbm-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-on-command = [39 01 00 00 00 00 02 53 E8]; + qcom,mdss-dsi-dispparam-hbm-on-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-dimmingon-command = [39 01 00 00 01 00 02 53 28]; + qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingoff-command = [39 01 00 00 01 00 02 53 20]; + qcom,mdss-dsi-dispparam-dimmingoff-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-srgb-on-command = [ + /* CRC Enable + sRGB mode */ + 39 01 00 00 00 00 02 81 90 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 BD 02 00 14 D1 00 04 07 AA 0C EC CB C8 0F DD D9 E4 05 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-srgb-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command = [ + /* CRC Enable + DCI-P3 mode */ + 39 01 00 00 00 00 02 81 91 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 CB 0B 01 0B EC 03 05 08 CF 14 FA FA E7 05 EE EE F2 00 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-off-command = [ + /* CRC Disable (Normal mode) */ + 39 01 00 00 00 00 02 81 00 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Bypass */ + 39 01 00 00 00 00 02 B1 01 + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi new file mode 100644 index 000000000000..15821d208877 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi @@ -0,0 +1,254 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&soc { + dsi_samsung_fhd_ea8076_f1p2_cmd: qcom,mdss_dsi_samsung_fhd_ea8076_f1p2_cmd { + qcom,mdss-dsi-panel-name = "samsung ea8076 fhd cmd dsi panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "SAMSUNG FHD EA8076 CMD PANEL"; + qcom,mdss-dsi-panel-sleepwrmod = <0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,ulps-enabled; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-brightness-max-level = <2047>; + qcom,bl-update-flag = "delay_until_first_frame"; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-dcs-type-ss; + qcom,mdss-dsi-reset-sequence = <0 1>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <68>; + qcom,mdss-pan-physical-height-dimension = <147>; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 + 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4300000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + + qcom,dispparam-enabled; + qcom,mdss-panel-on-dimming-delay = <200>; + /* IRQF_ONESHOT | IRQF_TRIGGER_FALLING */ + qcom,esd-err-irq-gpio = <&tlmm 5 0x2002>; + + qcom,disp-doze-backlight-threshold = <8>; + qcom,disp-fod-off-dimming-delay = <85>; + + qcom,elvss_dimming_check_enable; + qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command = [39 01 00 00 00 00 02 B0 07]; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2340>; + qcom,mdss-dsi-h-front-porch = <64>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <20>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <64>; + qcom,mdss-dsi-v-front-porch = <64>; + qcom,mdss-dsi-v-pulse-width = <20>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-panel-clockrate = <1100000000>; + qcom,mdss-dsi-panel-jitter = <0x5 0x1>; + qcom,mdss-dsi-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 FC 5A 5A + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 FF 10 + 39 00 00 00 00 00 02 B0 2F + 39 01 00 00 00 00 02 D1 01 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 03 FC A5 A5 + 05 01 00 00 0A 00 02 11 00 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 35 00 + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 06 + 39 00 00 00 00 00 02 B7 10 + 39 01 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 05 2B 00 00 09 23 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 FC 5A 5A + 39 00 00 00 00 00 02 B0 23 + 39 00 00 00 00 00 02 D1 33 + 39 00 00 00 00 00 0C E9 11 55 A6 75 A3 A6 37 BE 00 1A B8 + 39 00 00 00 00 00 0C D9 14 00 00 8F 6E 00 00 8F 2E 6E 34 + 39 00 00 00 00 00 6D C0 31 01 03 00 06 00 00 00 00 00 00 00 00 00 00 00 00 50 00 00 40 3D 00 5E 00 00 00 20 07 20 30 58 00 00 00 00 00 00 E0 0B 75 D8 00 00 00 00 FC 00 00 00 F6 97 0F 6D E6 CD 05 21 8B EC ED ED ED 0D 3F 60 00 67 FD 6D 51 BC DD DD 00 00 07 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 70 2F 00 00 03 2E 3C 20 E0 00 00 00 00 00 06 8C + 39 01 00 00 00 00 02 C0 31 + 39 00 00 00 00 00 07 E1 00 00 02 02 42 02 + 39 00 00 00 00 00 07 E2 00 00 00 00 00 00 + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 E1 19 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 03 FC A5 A5 + 39 00 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 51 00 00 + 39 01 00 00 43 00 02 55 00 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-off-command = [ + 05 01 00 00 00 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-doze-hbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 01 00 02 53 22 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-doze-lbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 00 00 02 53 23 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-nolp-command = [ + 05 01 00 00 22 00 02 28 00 + 39 01 00 00 00 00 02 53 20 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-doze-hbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-doze-lbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-nolp-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-acl-off-command = [39 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-dispparam-acl-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l1-command = [39 01 00 00 00 00 02 55 01];/* 50% */ + qcom,mdss-dsi-dispparam-acl-l1-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l2-command = [39 01 00 00 00 00 02 55 02];/* 40% */ + qcom,mdss-dsi-dispparam-acl-l2-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l3-command = [39 01 00 00 00 00 02 55 03];/* 30% */ + qcom,mdss-dsi-dispparam-acl-l3-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-hbm-off-command = [39 01 00 00 00 00 02 53 28]; + qcom,mdss-dsi-dispparam-hbm-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-on-command = [39 01 00 00 00 00 02 53 E8]; + qcom,mdss-dsi-dispparam-hbm-on-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-dimmingon-command = [39 01 00 00 01 00 02 53 28]; + qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingoff-command = [39 01 00 00 01 00 02 53 20]; + qcom,mdss-dsi-dispparam-dimmingoff-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-srgb-on-command = [ + /* CRC Enable + sRGB mode */ + 39 01 00 00 00 00 02 81 90 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 BD 02 00 14 D1 00 04 07 AA 0C EC CB C8 0F DD D9 E4 05 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-srgb-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command = [ + /* CRC Enable + DCI-P3 mode */ + 39 01 00 00 00 00 02 81 91 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 CB 0B 01 0B EC 03 05 08 CF 14 FA FA E7 05 EE EE F2 00 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-off-command = [ + /* CRC Disable (Normal mode) */ + 39 01 00 00 00 00 02 81 00 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Bypass */ + 39 01 00 00 00 00 02 B1 01 + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi new file mode 100644 index 000000000000..c8b8191aaccb --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi @@ -0,0 +1,277 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&soc { + dsi_samsung_fhd_ea8076_f1s_cmd: qcom,mdss_dsi_samsung_fhd_ea8076_f1s_cmd { + qcom,mdss-dsi-panel-name = "samsung ea8076 fhd cmd dsi panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "SAMSUNG FHD EA8076 CMD PANEL"; + qcom,mdss-dsi-panel-sleepwrmod = <0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,ulps-enabled; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-brightness-max-level = <2047>; + qcom,bl-update-flag = "delay_until_first_frame"; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-dcs-type-ss; + qcom,mdss-dsi-reset-sequence = <0 1>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <68>; + qcom,mdss-pan-physical-height-dimension = <147>; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 + 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4300000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + + qcom,dispparam-enabled; + qcom,mdss-panel-on-dimming-delay = <200>; + qcom,mdss-dsi-panel-dc-threshold = <610>; + /* IRQF_ONESHOT | IRQF_TRIGGER_FALLING */ + qcom,esd-err-irq-gpio = <&tlmm 5 0x2002>; + + qcom,disp-doze-backlight-threshold = <8>; + + qcom,elvss_dimming_check_enable; + qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command = [39 01 00 00 00 00 02 B0 07]; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; + + /* WHITE POINT COMMAND */ + qcom,mdss-dsi-panel-white-point-read-length = <8>; + qcom,mdss-dsi-dispparam-whitepoint-read-command = [06 01 00 01 00 00 01 EF]; + qcom,mdss-dsi-dispparam-whitepoint-read-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2340>; + qcom,mdss-dsi-h-front-porch = <64>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <20>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <64>; + qcom,mdss-dsi-v-front-porch = <88>; + qcom,mdss-dsi-v-pulse-width = <20>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-panel-clockrate = <1110000000>; + qcom,mdss-dsi-panel-jitter = <0x5 0x1>; + qcom,mdss-dsi-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 FC 5A 5A + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 FF 10 + 39 00 00 00 00 00 02 B0 2F + 39 01 00 00 00 00 02 D1 01 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 03 FC A5 A5 + 05 01 00 00 0A 00 02 11 00 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 35 00 + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 06 + 39 00 00 00 00 00 02 B7 10 + 39 01 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 05 2B 00 00 09 23 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 FC 5A 5A + + /* OSC frequency to 91.8M/89.8M */ + 39 00 00 00 00 00 02 B0 23 + 39 00 00 00 00 00 02 D1 2C + /*39 00 00 00 00 00 0C E9 11 55 A6 75 A3 A6 37 BE 00 1A B8*/ + 39 00 00 00 00 00 0C E9 11 55 A6 75 A3 A9 EB 71 00 1A B8 + 39 00 00 00 00 00 0C D9 14 00 00 8F 6E 00 00 8F 2E 6E 34 + 39 00 00 00 00 00 6D C0 31 01 03 00 06 00 00 00 00 00 00 00 00 00 00 00 00 50 00 00 40 3D 00 5E 00 00 00 20 07 20 30 58 00 00 00 00 00 00 E0 0B 75 D8 00 00 00 00 FC 00 00 00 F6 97 0F 6D E6 CD 05 21 8B EC ED ED ED 0D 3F 60 00 67 FD 6D 51 BC DD DD 00 00 07 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 70 2F 00 00 03 2E 3C 20 E0 00 00 00 00 00 06 8C + 39 01 00 00 00 00 02 C0 31 + /* ESD config */ + 39 00 00 00 00 00 07 E1 00 00 02 02 42 02 + 39 00 00 00 00 00 07 E2 00 00 00 00 00 00 + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 E1 19 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 03 FC A5 A5 + 39 00 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 51 00 00 + 39 01 00 00 43 00 02 55 00 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-off-command = [ + 05 01 00 00 00 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-doze-hbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 01 00 02 53 22 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-doze-lbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 00 00 02 53 23 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-nolp-command = [ + 05 01 00 00 22 00 02 28 00 + 39 01 00 00 00 00 02 53 20 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-doze-hbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-doze-lbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-nolp-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-acl-off-command = [39 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-dispparam-acl-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l1-command = [39 01 00 00 00 00 02 55 01];/* 50% */ + qcom,mdss-dsi-dispparam-acl-l1-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l2-command = [39 01 00 00 00 00 02 55 02];/* 40% */ + qcom,mdss-dsi-dispparam-acl-l2-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l3-command = [39 01 00 00 00 00 02 55 03];/* 30% */ + qcom,mdss-dsi-dispparam-acl-l3-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-hbm-off-command = [39 01 00 00 00 00 02 53 28]; + qcom,mdss-dsi-dispparam-hbm-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-on-command = [39 01 00 00 00 00 02 53 E8]; + qcom,mdss-dsi-dispparam-hbm-on-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-dimmingon-command = [39 01 00 00 01 00 02 53 28]; + qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingoff-command = [39 01 00 00 01 00 02 53 20]; + qcom,mdss-dsi-dispparam-dimmingoff-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-srgb-on-command = [ + /* CRC Enable + sRGB mode */ + 39 01 00 00 00 00 02 81 90 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 BD 02 00 14 D1 00 04 07 AA 0C EC CB C8 0F DD D9 E4 05 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-srgb-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command = [ + /* CRC Enable + DCI-P3 mode */ + 39 01 00 00 00 00 02 81 91 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 CB 0B 01 0B EC 03 05 08 CF 14 FA FA E7 05 EE EE F2 00 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-off-command = [ + /* CRC Disable (Normal mode) */ + 39 01 00 00 00 00 02 81 00 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Bypass */ + 39 01 00 00 00 00 02 B1 01 + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-flat-on-command = [ + 39 01 00 00 00 00 03 F0 5A 5A + 39 01 00 00 00 00 1D BE 82 29 00 00 00 30 30 30 40 40 40 4B 4B 4B 50 50 50 5C 4D 89 9B 73 00 33 69 12 7A 70 + 39 01 00 00 00 00 02 F7 01 + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-flat-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-flat-off-command = [ + 39 01 00 00 00 00 03 F0 5A 5A + 39 01 00 00 00 00 1D BE 82 09 00 00 00 30 30 30 40 40 40 4B 4B 4B 50 50 50 5C 4D 89 CB B8 00 33 69 12 7A 70 + 39 01 00 00 00 00 02 F7 01 + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-flat-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi new file mode 100644 index 000000000000..45b9d84193d4 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi @@ -0,0 +1,242 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&soc { + dsi_ss_fhd_ea8076_cmd: qcom,mdss_dsi_ss_fhd_ea8076_cmd { + qcom,mdss-dsi-panel-name = "samsung ea8076 fhd cmd dsi panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "SAMSUNG FHD EA8076 CMD PANEL"; + qcom,mdss-dsi-panel-sleepwrmod = <0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,ulps-enabled; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-brightness-max-level = <2047>; + qcom,bl-update-flag = "delay_until_first_frame"; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-dcs-type-ss; + qcom,mdss-dsi-reset-sequence = <0 1>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <68>; + qcom,mdss-pan-physical-height-dimension = <147>; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 + 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4300000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + + qcom,dispparam-enabled; + qcom,mdss-panel-on-dimming-delay = <120>; + /* IRQF_ONESHOT | IRQF_TRIGGER_FALLING */ + /* trig-flags: falling-0x0002 rasing-0x0001 */ + qcom,esd-err-irq-gpio = <&tlmm 5 0x2002>; + + qcom,disp-doze-backlight-threshold = <8>; + qcom,disp-fod-off-dimming-delay = <85>; + + qcom,elvss_dimming_check_enable; + qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command = [39 01 00 00 00 00 02 B0 07]; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2340>; + qcom,mdss-dsi-h-front-porch = <64>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <20>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <64>; + qcom,mdss-dsi-v-front-porch = <64>; + qcom,mdss-dsi-v-pulse-width = <20>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-panel-clockrate = <1100000000>; + qcom,mdss-dsi-panel-jitter = <0x5 0x1>; + qcom,mdss-dsi-on-command = [ + 05 01 00 00 0A 00 02 11 00 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 35 00 + 39 00 00 00 00 00 03 B7 01 4B + 39 01 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 05 2B 00 00 09 23 + 39 00 00 00 00 00 03 F0 5A 5A /* esd */ + 39 00 00 00 00 00 03 FC 5A 5A + 39 00 00 00 00 00 02 B0 23 //osc + 39 00 00 00 00 00 02 D1 0F + 39 00 00 00 00 00 0C E9 11 55 A6 75 A3 B9 A1 4A 00 1A B8 + 39 00 00 00 00 00 07 E1 00 00 02 02 42 02 + 39 00 00 00 00 00 07 E2 00 00 00 00 00 00 + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 E1 19 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 03 FC A5 A5 + 39 00 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 51 00 00 + 39 01 00 00 43 00 02 55 00 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-off-command = [ + 05 01 00 00 00 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-doze-hbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 01 00 02 53 22 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-doze-lbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 00 00 02 53 23 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-nolp-command = [ + 05 01 00 00 10 00 02 28 00 + 39 01 00 00 00 00 02 53 20 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-doze-hbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-doze-lbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-nolp-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-acl-off-command = [39 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-dispparam-acl-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l1-command = [39 01 00 00 00 00 02 55 01];/* 50% */ + qcom,mdss-dsi-dispparam-acl-l1-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l2-command = [39 01 00 00 00 00 02 55 02];/* 40% */ + qcom,mdss-dsi-dispparam-acl-l2-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l3-command = [39 01 00 00 00 00 02 55 03];/* 30% */ + qcom,mdss-dsi-dispparam-acl-l3-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-hbm-off-command = [39 01 00 00 00 00 02 53 28]; + qcom,mdss-dsi-dispparam-hbm-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-on-command = [39 01 00 00 00 00 02 53 E8]; + qcom,mdss-dsi-dispparam-hbm-on-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-dimmingon-command = [39 01 00 00 01 00 02 53 28]; + qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingoff-command = [39 01 00 00 01 00 02 53 20]; + qcom,mdss-dsi-dispparam-dimmingoff-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-srgb-on-command = [ + /* CRC Enable + sRGB mode */ + 39 01 00 00 00 00 02 81 90 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 BD 02 00 14 D1 00 04 07 AA 0C EC CB C8 0F DD D9 E4 05 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-srgb-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command = [ + /* CRC Enable + DCI-P3 mode */ + 39 01 00 00 00 00 02 81 91 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 D2 0A 05 1A E6 00 04 07 F5 0C DC DB E8 0F DD EE E9 05 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-off-command = [ + /* CRC Disable (Normal mode) */ + 39 01 00 00 00 00 02 81 00 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Bypass */ + 39 01 00 00 00 00 02 B1 01 + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi new file mode 100644 index 000000000000..ffcca35361db --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi @@ -0,0 +1,242 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&soc { + dsi_ss_fhd_ea8076_global_cmd: qcom,mdss_dsi_ss_fhd_ea8076_global_cmd { + qcom,mdss-dsi-panel-name = "samsung ea8076 fhd cmd dsi panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "SAMSUNG FHD EA8076 CMD PANEL"; + qcom,mdss-dsi-panel-sleepwrmod = <0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,ulps-enabled; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-brightness-max-level = <2047>; + qcom,bl-update-flag = "delay_until_first_frame"; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-dcs-type-ss; + qcom,mdss-dsi-reset-sequence = <0 1>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <68>; + qcom,mdss-pan-physical-height-dimension = <147>; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 + 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4300000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + + qcom,dispparam-enabled; + qcom,mdss-panel-on-dimming-delay = <120>; + /* IRQF_ONESHOT | IRQF_TRIGGER_FALLING */ + /* trig-flags: falling-0x0002 rasing-0x0001 */ + qcom,esd-err-irq-gpio = <&tlmm 5 0x2002>; + + qcom,disp-doze-backlight-threshold = <8>; + qcom,disp-fod-off-dimming-delay = <85>; + + qcom,elvss_dimming_check_enable; + qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command = [39 01 00 00 00 00 02 B0 07]; + qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; + qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2340>; + qcom,mdss-dsi-h-front-porch = <64>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <20>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <64>; + qcom,mdss-dsi-v-front-porch = <64>; + qcom,mdss-dsi-v-pulse-width = <27>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-panel-clockrate = <1103000000>; + qcom,mdss-dsi-panel-jitter = <0x5 0x1>; + qcom,mdss-dsi-on-command = [ + 05 01 00 00 0A 00 02 11 00 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 35 00 + 39 00 00 00 00 00 03 B7 01 4B + 39 01 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 05 2B 00 00 09 23 + 39 00 00 00 00 00 03 F0 5A 5A /* esd */ + 39 00 00 00 00 00 03 FC 5A 5A + 39 00 00 00 00 00 02 B0 23 //osc + 39 00 00 00 00 00 02 D1 11 + 39 00 00 00 00 00 0C E9 11 55 A6 75 A3 B9 A1 4A 00 1A B8 + 39 00 00 00 00 00 07 E1 00 00 02 02 42 02 + 39 00 00 00 00 00 07 E2 00 00 00 00 00 00 + 39 00 00 00 00 00 02 B0 0C + 39 00 00 00 00 00 02 E1 19 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 03 FC A5 A5 + 39 00 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 51 00 00 + 39 01 00 00 43 00 02 55 00 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-off-command = [ + 05 01 00 00 00 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-doze-hbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 01 00 02 53 22 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-doze-lbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 D4 8B + 39 00 00 00 00 00 02 B0 A5 + 39 00 00 00 00 00 02 C7 00 + 39 00 00 00 00 00 02 B0 69 + 39 00 00 00 00 00 03 B9 08 8F + 39 01 00 00 00 00 02 53 23 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-nolp-command = [ + 05 01 00 00 10 00 02 28 00 + 39 01 00 00 00 00 02 53 20 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-doze-hbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-doze-lbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-nolp-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-acl-off-command = [39 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-dispparam-acl-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l1-command = [39 01 00 00 00 00 02 55 01];/* 50% */ + qcom,mdss-dsi-dispparam-acl-l1-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l2-command = [39 01 00 00 00 00 02 55 02];/* 40% */ + qcom,mdss-dsi-dispparam-acl-l2-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l3-command = [39 01 00 00 00 00 02 55 03];/* 30% */ + qcom,mdss-dsi-dispparam-acl-l3-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-hbm-off-command = [39 01 00 00 00 00 02 53 28]; + qcom,mdss-dsi-dispparam-hbm-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-on-command = [39 01 00 00 00 00 02 53 E8]; + qcom,mdss-dsi-dispparam-hbm-on-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-dimmingon-command = [39 01 00 00 01 00 02 53 28]; + qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingoff-command = [39 01 00 00 01 00 02 53 20]; + qcom,mdss-dsi-dispparam-dimmingoff-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-srgb-on-command = [ + /* CRC Enable + sRGB mode */ + 39 01 00 00 00 00 02 81 90 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 BD 02 00 14 D1 00 04 07 AA 0C EC CB C8 0F DD D9 E4 05 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-srgb-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command = [ + /* CRC Enable + DCI-P3 mode */ + 39 01 00 00 00 00 02 81 91 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Enable */ + 39 01 00 00 00 00 02 B1 00 + /* Set Offset P2*/ + 39 01 00 00 00 00 02 B0 01 + /* CRC LUT(sRGB mode) */ + 39 01 00 00 00 00 16 B1 AE 0C 05 3F C6 14 05 07 AA 4A DD C8 C3 14 C0 E8 DC 19 FF F4 D9 + /* Set Offset P23*/ + 39 01 00 00 00 00 02 B0 16 + /* CRC LUT(DCI-P3 mode) */ + 39 01 00 00 00 00 16 B1 D2 0A 05 1A E6 00 04 07 F5 0C DC DB E8 0F DD EE E9 05 FF FF FF + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-off-command = [ + /* CRC Disable (Normal mode) */ + 39 01 00 00 00 00 02 81 00 + 39 01 00 00 00 00 03 F0 5A 5A + /* CRC Bypass */ + 39 01 00 00 00 00 02 B1 01 + 39 01 00 00 00 00 03 F0 A5 A5 + ]; + qcom,mdss-dsi-dispparam-crc-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-elvss-dimming-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-notch-fhd-ea8074-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-notch-fhd-ea8074-cmd.dtsi new file mode 100644 index 000000000000..e0041d04d281 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-notch-fhd-ea8074-cmd.dtsi @@ -0,0 +1,163 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&soc { + dsi_ss_notch_fhd_ea8074_cmd: qcom,mdss_dsi_ss_notch_fhd_ea8074_cmd { + qcom,mdss-dsi-panel-name = "ss notch fhd cmd dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-model = "SS NOTCH FHD EA8074 CMD PANEL"; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,ulps-enabled; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-brightness-max-level = <255>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-dcs-type-ss; + qcom,mdss-dsi-reset-sequence = <1 1>, <0 1>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <68>; + qcom,mdss-pan-physical-height-dimension = <142>; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 + 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4300000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + qcom,dispparam-enabled; + qcom,mdss-panel-on-dimming-delay = <120>; + //qcom,esd-err-irq-gpio = <&tlmm 52 0x2002>; /* trig-flags: falling-0x0002 rasing-0x0001*/ + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2248>; + qcom,mdss-dsi-h-front-porch = <56>; + qcom,mdss-dsi-h-back-porch = <56>; + qcom,mdss-dsi-h-pulse-width = <18>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <24>; + qcom,mdss-dsi-v-front-porch = <26>; + qcom,mdss-dsi-v-pulse-width = <12>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-on-command = [ + 05 01 00 00 0a 00 02 11 00 + 39 00 00 00 00 00 05 2B 00 00 08 c7 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 05 + 39 00 00 00 00 00 02 B1 10 + 39 00 00 00 00 00 02 B0 02 + 39 00 00 00 00 00 05 D5 02 17 54 14 + 39 01 00 00 00 00 03 F0 A5 A5 + 39 00 00 00 00 00 02 35 00 + 39 00 00 00 00 00 03 51 00 00 + 39 00 00 00 00 00 02 53 20 + 39 01 00 00 6E 00 02 55 00 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-off-command = [ + 05 01 00 00 00 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-doze-hbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 ef b0 + 39 00 00 00 00 00 02 b0 17 + 39 00 00 00 00 00 04 E3 00 00 00 + 39 01 00 00 01 00 02 53 22 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-doze-lbm-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 ef b0 + 39 00 00 00 00 00 02 b0 17 + 39 00 00 00 00 00 04 E3 00 00 00 + 39 01 00 00 01 00 02 53 23 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-nolp-command = [ + 05 01 00 00 00 00 02 28 00 + 39 00 00 00 00 00 03 51 00 00 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 b0 17 + 39 00 00 00 00 00 04 E3 86 80 01 + 39 00 00 00 00 00 02 53 28 + 39 01 00 00 00 00 03 F0 A5 A5 + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-doze-hbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-doze-lbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-nolp-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-off-command = [39 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-dispparam-acl-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l1-command = [39 01 00 00 00 00 02 55 01];/* 50% */ + qcom,mdss-dsi-dispparam-acl-l1-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l2-command = [39 01 00 00 00 00 02 55 02];/* 40% */ + qcom,mdss-dsi-dispparam-acl-l2-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l3-command = [39 01 00 00 00 00 02 55 03];/* 30% */ + qcom,mdss-dsi-dispparam-acl-l3-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-off-command = [39 01 00 00 00 00 02 53 28]; + qcom,mdss-dsi-dispparam-hbm-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-on-command = [39 01 00 00 00 00 02 53 e8]; + qcom,mdss-dsi-dispparam-hbm-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [39 00 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B2 00 40 + 39 00 00 00 00 00 02 B0 04 + 39 00 00 00 00 00 02 B2 80 + 39 00 00 00 00 00 02 F7 03 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B2 00 10 + 39 00 00 00 00 00 02 B0 04 + 39 00 00 00 00 00 02 B2 00 + 39 00 00 00 00 00 02 F7 03 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 00 00 02 53 e0]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-fod2norm-command = [39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B2 00 40 + 39 00 00 00 00 00 02 B0 04 + 39 00 00 00 00 00 02 B2 80 + 39 00 00 00 00 00 02 F7 03 + 39 01 00 00 00 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod2norm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingon-command = [39 01 00 00 01 00 02 53 28]; + qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-tianma-fhd-nt36672a-video.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-tianma-fhd-nt36672a-video.dtsi new file mode 100644 index 000000000000..be6ecd084189 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-tianma-fhd-nt36672a-video.dtsi @@ -0,0 +1,387 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&soc { + dsi_tianma_fhd_nt36672a_video: qcom,mdss_dsi_tianma_fhd_nt36672a_video { + qcom,mdss-dsi-panel-name = "tianma fhd vide dsi panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "TIANMA FHD NT36672A VIDE PANEL"; + qcom,mdss-dsi-panel-sleepwrmod = <0>; + +// + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0x0>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-brightness-max-level = <255>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-reset-sequence = <0 10>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <68>; + qcom,mdss-pan-physical-height-dimension = <136>; + qcom,cont-splash-enabled; + qcom,mdss-dsi-tx-eot-append; + qcom,esd-err-irq-gpio = <&tlmm 5 0x2001>; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 + 17000 15500 30000 8000 3000>; + qcom,dispparam-enabled; + qcom,mdss-panel-on-dimming-delay = <120>; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2340>; + qcom,mdss-dsi-h-front-porch = <40>; + qcom,mdss-dsi-h-back-porch = <44>;//debug + qcom,mdss-dsi-h-pulse-width = <20>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <8>; + qcom,mdss-dsi-v-front-porch = <15>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + + qcom,mdss-dsi-on-command = [ + /* skin enhancement mode */ + 15 01 00 00 00 00 02 FF 22 + 15 00 00 00 00 00 02 00 40 + 15 00 00 00 00 00 02 01 C0 + 15 00 00 00 00 00 02 02 40 + 15 00 00 00 00 00 02 03 40 + 15 00 00 00 00 00 02 04 40 + 15 00 00 00 00 00 02 05 40 + 15 00 00 00 00 00 02 06 40 + 15 00 00 00 00 00 02 07 40 + 15 00 00 00 00 00 02 08 40 + 15 00 00 00 00 00 02 09 40 + 15 00 00 00 00 00 02 0A 40 + 15 00 00 00 00 00 02 0B 40 + 15 00 00 00 00 00 02 0C 40 + 15 00 00 00 00 00 02 0D 40 + 15 00 00 00 00 00 02 0E 40 + 15 00 00 00 00 00 02 0F 40 + 15 00 00 00 00 00 02 10 40 + 15 00 00 00 00 00 02 11 50 + 15 00 00 00 00 00 02 12 60 + 15 00 00 00 00 00 02 13 70 + 15 00 00 00 00 00 02 14 58 + 15 00 00 00 00 00 02 15 68 + 15 00 00 00 00 00 02 16 78 + 15 01 00 00 00 00 02 17 77 + 15 00 00 00 00 00 02 18 39 + 15 00 00 00 00 00 02 19 2D + 15 00 00 00 00 00 02 1A 2E + 15 00 00 00 00 00 02 1B 32 + 15 00 00 00 00 00 02 1C 37 + 15 00 00 00 00 00 02 1D 3A + 15 00 00 00 00 00 02 1E 40 + 15 00 00 00 00 00 02 1F 40 + 15 00 00 00 00 00 02 20 40 + 15 00 00 00 00 00 02 21 40 + 15 00 00 00 00 00 02 22 40 + 15 00 00 00 00 00 02 23 40 + 15 00 00 00 00 00 02 24 40 + 15 00 00 00 00 00 02 25 40 + 15 00 00 00 00 00 02 26 40 + 15 00 00 00 00 00 02 27 40 + 15 00 00 00 00 00 02 28 40 + 15 00 00 00 00 00 02 2D 00 + 15 00 00 00 00 00 02 2F 40 + 15 00 00 00 00 00 02 30 40 + 15 00 00 00 00 00 02 31 40 + 15 00 00 00 00 00 02 32 40 + 15 00 00 00 00 00 02 33 40 + 15 00 00 00 00 00 02 34 40 + 15 01 00 00 00 00 02 35 40 + 15 00 00 00 00 00 02 36 40 + 15 00 00 00 00 00 02 37 40 + 15 00 00 00 00 00 02 38 40 + 15 00 00 00 00 00 02 39 40 + 15 00 00 00 00 00 02 3A 40 + 15 00 00 00 00 00 02 3B 40 + 15 00 00 00 00 00 02 3D 40 + 15 00 00 00 00 00 02 3F 40 + 15 00 00 00 00 00 02 40 40 + 15 00 00 00 00 00 02 41 40 + 15 00 00 00 00 00 02 42 40 + 15 00 00 00 00 00 02 43 40 + 15 00 00 00 00 00 02 44 40 + 15 00 00 00 00 00 02 45 40 + 15 00 00 00 00 00 02 46 40 + 15 00 00 00 00 00 02 47 40 + 15 00 00 00 00 00 02 48 40 + 15 00 00 00 00 00 02 49 40 + 15 00 00 00 00 00 02 4A 40 + 15 00 00 00 00 00 02 4B 40 + 15 00 00 00 00 00 02 4C 40 + 15 00 00 00 00 00 02 4D 40 + 15 00 00 00 00 00 02 4E 40 + 15 00 00 00 00 00 02 4F 40 + 15 01 00 00 00 00 02 50 40 + 15 00 00 00 00 00 02 51 40 + 15 00 00 00 00 00 02 52 40 + 15 00 00 00 00 00 02 53 01 + 15 00 00 00 00 00 02 54 01 + 15 00 00 00 00 00 02 55 FE + 15 00 00 00 00 00 02 56 77 + 15 00 00 00 00 00 02 58 CD + 15 00 00 00 00 00 02 59 D0 + 15 00 00 00 00 00 02 5A D0 + 15 00 00 00 00 00 02 5B 50 + 15 00 00 00 00 00 02 5C 50 + 15 00 00 00 00 00 02 5D 50 + 15 00 00 00 00 00 02 5E 50 + 15 00 00 00 00 00 02 5F 50 + 15 00 00 00 00 00 02 60 50 + 15 00 00 00 00 00 02 61 50 + 15 00 00 00 00 00 02 62 50 + 15 00 00 00 00 00 02 63 50 + 15 00 00 00 00 00 02 64 50 + 15 00 00 00 00 00 02 65 50 + 15 00 00 00 00 00 02 66 50 + 15 00 00 00 00 00 02 67 50 + 15 00 00 00 00 00 02 68 50 + 15 00 00 00 00 00 02 69 50 + 15 01 00 00 00 00 02 6A 50 + 15 00 00 00 00 00 02 6B 50 + 15 00 00 00 00 00 02 6C 50 + 15 00 00 00 00 00 02 6D 50 + 15 00 00 00 00 00 02 6E 50 + 15 00 00 00 00 00 02 6F 50 + 15 00 00 00 00 00 02 70 07 + 15 00 00 00 00 00 02 71 00 + 15 00 00 00 00 00 02 72 00 + 15 00 00 00 00 00 02 73 00 + 15 00 00 00 00 00 02 74 06 + 15 00 00 00 00 00 02 75 0C + 15 00 00 00 00 00 02 76 03 + 15 00 00 00 00 00 02 77 09 + 15 00 00 00 00 00 02 78 0F + 15 00 00 00 00 00 02 79 68 + 15 00 00 00 00 00 02 7A 88 + 15 00 00 00 00 00 02 7C 80 + 15 00 00 00 00 00 02 7D 80 + 15 00 00 00 00 00 02 7E 80 + 15 00 00 00 00 00 02 7F 00 + 15 00 00 00 00 00 02 80 00 + 15 00 00 00 00 00 02 81 00 + 15 00 00 00 00 00 02 83 01 + 15 00 00 00 00 00 02 84 00 + 15 01 00 00 00 00 02 85 80 + 15 00 00 00 00 00 02 86 80 + 15 00 00 00 00 00 02 87 80 + 15 00 00 00 00 00 02 88 40 + 15 00 00 00 00 00 02 89 91 + 15 00 00 00 00 00 02 8A 98 + 15 00 00 00 00 00 02 8B 80 + 15 00 00 00 00 00 02 8C 80 + 15 00 00 00 00 00 02 8D 80 + 15 00 00 00 00 00 02 8E 80 + 15 00 00 00 00 00 02 8F 80 + 15 00 00 00 00 00 02 90 80 + 15 00 00 00 00 00 02 91 80 + 15 00 00 00 00 00 02 92 80 + 15 00 00 00 00 00 02 93 80 + 15 00 00 00 00 00 02 94 80 + 15 00 00 00 00 00 02 95 80 + 15 00 00 00 00 00 02 96 80 + 15 00 00 00 00 00 02 97 80 + 15 00 00 00 00 00 02 98 80 + 15 00 00 00 00 00 02 99 80 + 15 00 00 00 00 00 02 9A 80 + 15 00 00 00 00 00 02 9B 80 + 15 00 00 00 00 00 02 9C 80 + 15 00 00 00 00 00 02 9D 80 + 15 01 00 00 00 00 02 9E 80 + 15 00 00 00 00 00 02 9F 80 + 15 00 00 00 00 00 02 A0 8A + 15 00 00 00 00 00 02 A2 80 + 15 00 00 00 00 00 02 A6 80 + 15 00 00 00 00 00 02 A7 80 + 15 00 00 00 00 00 02 A9 80 + 15 00 00 00 00 00 02 AA 80 + 15 00 00 00 00 00 02 AB 80 + 15 00 00 00 00 00 02 AC 80 + 15 00 00 00 00 00 02 AD 80 + 15 00 00 00 00 00 02 AE 80 + 15 00 00 00 00 00 02 AF 80 + 15 00 00 00 00 00 02 B7 76 + 15 00 00 00 00 00 02 B8 76 + 15 00 00 00 00 00 02 B9 05 + 15 00 00 00 00 00 02 BA 0D + 15 00 00 00 00 00 02 BB 14 + 15 00 00 00 00 00 02 BC 0F + 15 00 00 00 00 00 02 BD 18 + 15 00 00 00 00 00 02 BE 1F + 15 00 00 00 00 00 02 BF 05 + 15 00 00 00 00 00 02 C0 0D + 15 00 00 00 00 00 02 C1 14 + 15 00 00 00 00 00 02 C2 03 + 15 01 00 00 00 00 02 C3 07 + 15 00 00 00 00 00 02 C4 0A + 15 00 00 00 00 00 02 C5 A0 + 15 00 00 00 00 00 02 C6 55 + 15 00 00 00 00 00 02 C7 FF + 15 00 00 00 00 00 02 C8 39 + 15 00 00 00 00 00 02 C9 44 + 15 00 00 00 00 00 02 CA 12 + 15 00 00 00 00 00 02 CD 80 + 15 00 00 00 00 00 02 DB 80 + 15 00 00 00 00 00 02 DC 80 + 15 00 00 00 00 00 02 DD 80 + 15 00 00 00 00 00 02 E0 80 + 15 00 00 00 00 00 02 E1 80 + 15 00 00 00 00 00 02 E2 80 + 15 00 00 00 00 00 02 E3 80 + 15 00 00 00 00 00 02 E4 80 + 15 00 00 00 00 00 02 E5 40 + 15 00 00 00 00 00 02 E6 40 + 15 00 00 00 00 00 02 E7 40 + 15 00 00 00 00 00 02 E8 40 + 15 00 00 00 00 00 02 E9 40 + 15 00 00 00 00 00 02 EA 40 + 15 00 00 00 00 00 02 EB 40 + 15 00 00 00 00 00 02 EC 40 + 15 00 00 00 00 00 02 ED 40 + 15 00 00 00 00 00 02 EE 40 + 15 00 00 00 00 00 02 EF 40 + 15 00 00 00 00 00 02 F0 40 + 15 00 00 00 00 00 02 F1 40 + 15 00 00 00 00 00 02 F2 40 + 15 00 00 00 00 00 02 F3 40 + 15 00 00 00 00 00 02 F4 40 + 15 00 00 00 00 00 02 F5 40 + 15 00 00 00 00 00 02 F6 40 + 15 01 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 FF 23 + 15 00 00 00 00 00 02 FB 01 + /* dimming enable */ + 15 00 00 00 00 00 02 01 84 + 15 00 00 00 00 00 02 05 2D + 15 00 00 00 00 00 02 06 00 + /* resolution 1080*2246 */ + 15 00 00 00 00 00 02 11 01 + 15 00 00 00 00 00 02 12 7B + 15 00 00 00 00 00 02 15 6F + 15 00 00 00 00 00 02 16 0B + /* UI mode */ + 15 00 00 00 00 00 02 29 0A + 15 00 00 00 00 00 02 30 FF + 15 00 00 00 00 00 02 31 FF + 15 00 00 00 00 00 02 32 FF + 15 00 00 00 00 00 02 33 FF + 15 00 00 00 00 00 02 34 FF + 15 00 00 00 00 00 02 35 FF + 15 00 00 00 00 00 02 36 FF + 15 00 00 00 00 00 02 37 FF + 15 00 00 00 00 00 02 38 FC + 15 01 00 00 00 00 02 39 F8 + 15 00 00 00 00 00 02 3A F4 + 15 00 00 00 00 00 02 3B F1 + 15 00 00 00 00 00 02 3D EE + 15 00 00 00 00 00 02 3F EB + 15 00 00 00 00 00 02 40 E8 + 15 00 00 00 00 00 02 41 E5 + /* STILL mode */ + 15 00 00 00 00 00 02 2A 13 + 15 00 00 00 00 00 02 45 FF + 15 00 00 00 00 00 02 46 FF + 15 00 00 00 00 00 02 47 FF + 15 00 00 00 00 00 02 48 FF + 15 00 00 00 00 00 02 49 FF + 15 00 00 00 00 00 02 4A FF + 15 00 00 00 00 00 02 4B FF + 15 00 00 00 00 00 02 4C FF + 15 00 00 00 00 00 02 4D ED + 15 00 00 00 00 00 02 4E D5 + 15 00 00 00 00 00 02 4F BF + 15 00 00 00 00 00 02 50 A6 + 15 01 00 00 00 00 02 51 96 + 15 00 00 00 00 00 02 52 86 + 15 00 00 00 00 00 02 53 76 + 15 00 00 00 00 00 02 54 66 + /* MOVING mode */ + 15 00 00 00 00 00 02 2B 0E + 15 00 00 00 00 00 02 58 FF + 15 00 00 00 00 00 02 59 FF + 15 00 00 00 00 00 02 5A FF + 15 00 00 00 00 00 02 5B FF + 15 00 00 00 00 00 02 5C FF + 15 00 00 00 00 00 02 5D FF + 15 00 00 00 00 00 02 5E FF + 15 00 00 00 00 00 02 5F FF + 15 00 00 00 00 00 02 60 F6 + 15 00 00 00 00 00 02 61 EA + 15 00 00 00 00 00 02 62 E1 + 15 00 00 00 00 00 02 63 D8 + 15 00 00 00 00 00 02 64 CE + 15 00 00 00 00 00 02 65 C3 + 15 00 00 00 00 00 02 66 BA + 15 01 00 00 00 00 02 67 B3 + 15 01 00 00 00 00 02 FF 25 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 05 04 + 15 01 00 00 00 00 02 FF 26 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 1C AF + 15 01 00 00 00 00 02 FF 10 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 51 FF + 15 00 00 00 00 00 02 53 24 + 15 00 00 00 00 00 02 55 00 + 05 01 00 00 00 00 02 29 00 + 05 01 00 00 46 00 02 11 00 + 15 01 00 00 00 00 02 FF 24 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 C3 01 + 15 00 00 00 00 00 02 C4 55 + 15 00 00 00 00 00 02 C5 55 + 15 01 00 00 00 00 02 FF 10 + ]; + + qcom,mdss-dsi-off-command = [ + 15 01 00 00 00 00 02 FF 24 + 15 00 00 00 00 00 02 FB 01 + 15 00 00 00 00 00 02 C3 00 + 15 01 00 00 00 00 02 FF 10 + 05 01 00 00 00 00 02 28 00 + 05 01 00 00 3C 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <1>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-visionox-fhd-r66456-f11-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-visionox-fhd-r66456-f11-cmd.dtsi new file mode 100644 index 000000000000..d11acb5b345f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-visionox-fhd-r66456-f11-cmd.dtsi @@ -0,0 +1,167 @@ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&soc { + dsi_visionox_fhd_r66456_f11_cmd: qcom,mdss_dsi_visionox_fhd_r66456_f11_cmd { + qcom,mdss-dsi-panel-name = "visionox r66456 fhd cmd dsi panel"; + qcom,mdss-dsi-panel-id = <0>; + qcom,mdss-dsi-panel-model = "VISIONOX FHD R66456 CMD PANEL"; + qcom,mdss-dsi-panel-sleepwrmod = <0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,ulps-enabled; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-brightness-remap; + qcom,mdss-brightness-max-level = <2047>; + qcom,bl-update-flag = "delay_until_first_frame"; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-dcs-type-ss; + qcom,mdss-dsi-reset-sequence = <0 1>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <68>; + qcom,mdss-pan-physical-height-dimension = <147>; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-panel-hdr-enabled; + qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000 + 17000 15500 30000 8000 3000>; + qcom,mdss-dsi-panel-peak-brightness = <4300000>; + qcom,mdss-dsi-panel-blackness-level = <3230>; + + qcom,dispparam-enabled; + qcom,mdss-panel-on-dimming-delay = <120>; + /* IRQF_ONESHOT | IRQF_TRIGGER_FALLING */ + qcom,esd-err-irq-gpio = <&tlmm 5 0x2002>; + + qcom,disp-doze-backlight-threshold = <8>; + qcom,disp-fod-off-dimming-delay = <85>; + + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2340>; + qcom,mdss-dsi-h-front-porch = <64>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <20>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <64>; + qcom,mdss-dsi-v-front-porch = <64>; + qcom,mdss-dsi-v-pulse-width = <20>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-panel-clockrate = <1100000000>; + qcom,mdss-dsi-panel-jitter = <0x5 0x1>; + qcom,mdss-dsi-on-command = [ + 39 01 00 00 00 00 02 B0 00 + 39 00 00 00 00 00 2C BB 59 FF FF FF EF CF AB 87 63 3F 4A 48 46 44 42 40 3E 3C 3A 64 00 FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 02 02 42 00 + 39 00 00 00 00 00 03 D4 00 8D + 39 00 00 00 00 00 02 FA 0F + 39 01 00 00 00 00 02 B0 80 + /* NVM load control */ + 39 00 00 00 00 00 02 E6 00 + /* TE Control*/ + 39 00 00 00 00 00 02 35 00 + /* SET Column Start Adress*/ + 39 00 00 00 00 00 05 2A 00 00 04 37 + /* SET Row Start Adress*/ + 39 00 00 00 00 00 05 2B 00 00 09 23 + /* brightness control */ + 39 00 00 00 00 00 03 51 01 00 + /* sleep out */ + 05 01 00 00 6E 00 02 11 00 + /* display on */ + 05 01 00 00 00 00 02 29 00]; + qcom,mdss-dsi-off-command = [ + 05 01 00 00 00 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 02 88 00 + 39 01 00 00 00 00 02 53 E0]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; + + qcom,mdss-dsi-doze-hbm-command = [ + 39 00 00 00 00 00 03 51 00 FF + 39 01 00 00 00 00 02 88 01]; + qcom,mdss-dsi-doze-lbm-command = [ + 39 00 00 00 00 00 03 51 00 00 + 39 01 00 00 00 00 02 88 01]; + qcom,mdss-dsi-nolp-command = [ + 39 00 00 00 00 00 02 88 00]; + qcom,mdss-dsi-doze-hbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-doze-lbm-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-nolp-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-acl-off-command = [39 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-dispparam-acl-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l1-command = [39 01 00 00 00 00 02 55 01];/* 50% */ + qcom,mdss-dsi-dispparam-acl-l1-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l2-command = [39 01 00 00 00 00 02 55 02];/* 40% */ + qcom,mdss-dsi-dispparam-acl-l2-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-acl-l3-command = [39 01 00 00 00 00 02 55 03];/* 30% */ + qcom,mdss-dsi-dispparam-acl-l3-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-dispparam-hbm-off-command = [39 01 00 00 00 00 02 53 28]; + qcom,mdss-dsi-dispparam-hbm-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-hbm-on-command = [39 01 00 00 00 00 02 53 E8]; + qcom,mdss-dsi-dispparam-hbm-on-command-state = "dsi_lp_mode"; + + + qcom,mdss-dsi-dispparam-dimmingon-command = [39 01 00 00 01 00 02 53 28]; + qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-dimmingoff-command = [39 01 00 00 01 00 02 53 20]; + qcom,mdss-dsi-dispparam-dimmingoff-command-state = "dsi_lp_mode"; + /* + qcom,mdss-dsi-dispparam-crc-srgb-on-command = [ + ]; + qcom,mdss-dsi-dispparam-crc-srgb-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command = [ + ]; + qcom,mdss-dsi-dispparam-crc-dcip3-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-dispparam-crc-off-command = [ + ]; + qcom,mdss-dsi-dispparam-crc-off-command-state = "dsi_lp_mode"; + */ + qcom,mdss-dsi-h-sync-pulse = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/pm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/pm8150.dtsi new file mode 100644 index 000000000000..6b2f14bcefc6 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/pm8150.dtsi @@ -0,0 +1,35 @@ +&spmi_bus { + qcom,pm8150@0 { + qcom,power-on@800 { + interrupts = <0x0 0x8 0x0 IRQ_TYPE_NONE>, + <0x0 0x8 0x1 IRQ_TYPE_NONE>, + <0x0 0x8 0x4 IRQ_TYPE_NONE>, + <0x0 0x8 0x5 IRQ_TYPE_NONE>; + interrupt-names = "kpdpwr", "resin", + "resin-bark", "kpdpwr-resin-bark"; + qcom,pon-dbc-delay = <62500>; + + qcom,pon_1 { + qcom,support-reset = <1>; + qcom,pull-up = <1>; + qcom,s1-timer = <4480>; + qcom,s2-timer = <2000>; + qcom,s2-type = <0x7>; + }; + + qcom,pon_3 { + qcom,pon-type = ; + qcom,support-reset = <1>; + qcom,pull-up = <1>; + qcom,s1-timer = <1352>; + qcom,s2-timer = <2000>; + qcom,s2-type = <0x1>; + qcom,use-bark; + }; + }; + }; +}; + +&pm8150_rtc { + qcom,qpnp-rtc-alarm-pwrup = <1>; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/pm8150b.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/pm8150b.dtsi new file mode 100644 index 000000000000..684a1284886d --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/pm8150b.dtsi @@ -0,0 +1,33 @@ +&pm8150b_gpios { + interrupts = <0x2 0xc0 0 IRQ_TYPE_NONE>, + <0x2 0xc1 0 IRQ_TYPE_NONE>, + <0x2 0xc4 0 IRQ_TYPE_NONE>, + <0x2 0xc5 0 IRQ_TYPE_NONE>, + <0x2 0xc6 0 IRQ_TYPE_NONE>, + <0x2 0xc7 0 IRQ_TYPE_NONE>, + <0x2 0xc8 0 IRQ_TYPE_NONE>, + <0x2 0xc9 0 IRQ_TYPE_NONE>, + <0x2 0xca 0 IRQ_TYPE_NONE>, + <0x2 0xcb 0 IRQ_TYPE_NONE>; + interrupt-names = "pm8150b_gpio1", "pm8150b_gpio2", + "pm8150b_gpio5", "pm8150b_gpio6", + "pm8150b_gpio7", + "pm8150b_gpio8", "pm8150b_gpio9", + "pm8150b_gpio10", "pm8150b_gpio11", + "pm8150b_gpio12"; + qcom,gpios-disallowed = <3 4>; +}; + +&ibat_lvl0 { + temperature = <5500>; +}; + +&ibat_lvl1 { + temperature = <8000>; +}; + +&thermal_zones { + soc { + disable-thermal-zone; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/pm8150l.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/pm8150l.dtsi new file mode 100644 index 000000000000..a0544c78b85e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/pm8150l.dtsi @@ -0,0 +1,59 @@ +&pm8150l_gpios { + interrupts = <0x4 0xc0 0 IRQ_TYPE_NONE>, + <0x4 0xc1 0 IRQ_TYPE_NONE>, + <0x4 0xc2 0 IRQ_TYPE_NONE>, + <0x4 0xc3 0 IRQ_TYPE_NONE>, + <0x4 0xc4 0 IRQ_TYPE_NONE>, + <0x4 0xc5 0 IRQ_TYPE_NONE>, + <0x4 0xc6 0 IRQ_TYPE_NONE>, + <0x4 0xc7 0 IRQ_TYPE_NONE>, + <0x4 0xc8 0 IRQ_TYPE_NONE>, + <0x4 0xc9 0 IRQ_TYPE_NONE>, + <0x4 0xca 0 IRQ_TYPE_NONE>, + <0x4 0xcb 0 IRQ_TYPE_NONE>; + interrupt-names = "pm8150l_gpio1", "pm8150l_gpio2", + "pm8150l_gpio3", "pm8150l_gpio4", + "pm8150l_gpio5", "pm8150l_gpio6", + "pm8150l_gpio7", + "pm8150l_gpio8", "pm8150l_gpio9", + "pm8150l_gpio10", "pm8150l_gpio11", + "pm8150l_gpio12"; + /delete-property/ qcom,gpios-disallowed; +}; + +&pm8150l_adc_tm { + io-channels = <&pm8150l_vadc ADC_AMUX_THM1_PU2>, + <&pm8150l_vadc ADC_AMUX_THM2_PU2>, + <&pm8150l_vadc ADC_GPIO3_PU2>; +}; + +&pm8150l_flash2 { + status = "ok"; +}; + +&pm8150l_torch2 { + status = "ok"; +}; + +&flash_led { + pm8150l_flashlight: qcom,flashlight { + label = "flash"; + qcom,led-name = "flashlight"; + qcom,max-current = <750>; + qcom,default-led-trigger = "flashlight_trigger"; + qcom,id = <3>; + qcom,current-ma = <500>; + qcom,duration-ms = <1280>; + qcom,ires-ua = <12500>; + qcom,hdrm-voltage-mv = <325>; + qcom,hdrm-vol-hi-lo-win-mv = <100>; + }; +}; + +&pm8150l_pwm { + status = "disabled"; +}; + +&red_led { + /delete-property/ linux,default-trigger; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/sm8150-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/sm8150-audio-overlay.dtsi new file mode 100644 index 000000000000..f92cf102314c --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/sm8150-audio-overlay.dtsi @@ -0,0 +1,57 @@ +#include "../../../sm8150-audio-overlay.dtsi" + +&snd_9360 { + status = "disabled"; +}; + +&snd_934x { + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "MADINPUT", "MCLK", + "hifi amp", "LINEOUT1", + "hifi amp", "LINEOUT2", + "AMIC1", "MIC BIAS1", + "AMIC2", "MIC BIAS2", + "MIC BIAS2", "Headset Mic", + "AMIC3", "MIC BIAS3", + "MIC BIAS2", "ANCRight Headset Mic", + "AMIC4", "MIC BIAS2", + "MIC BIAS2", "ANCLeft Headset Mic", + "AMIC5", "MIC BIAS3", + "MIC BIAS3", "Handset Mic", + "DMIC0", "MIC BIAS1", + "MIC BIAS1", "Digital Mic0", + "DMIC1", "MIC BIAS1", + "MIC BIAS1", "Digital Mic1", + "DMIC2", "MIC BIAS3", + "MIC BIAS3", "Digital Mic2", + "DMIC3", "MIC BIAS3", + "MIC BIAS3", "Digital Mic3", + "DMIC4", "MIC BIAS4", + "MIC BIAS4", "Digital Mic4", + "DMIC5", "MIC BIAS4", + "MIC BIAS4", "Digital Mic5", + "SpkrLeft IN", "SPK1 OUT", + "SpkrRight IN", "SPK2 OUT"; + + qcom,msm-mbhc-hphl-swh = <0>; + qcom,msm-mbhc-gnd-swh = <0>; + + qcom,wsa-max-devs = <0>; + + pinctrl-names = "quat_mi2s_enable", "quat_mi2s_disable", + "quat_tdm_enable", "quat_tdm_disable"; + pinctrl-0 = <&quat_mi2s_active &quat_mi2s_sd0_active + &quat_mi2s_sd1_active>; + pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_sd0_sleep + &quat_mi2s_sd1_sleep>; + pinctrl-2 = <&quat_tdm_active &quat_tdm_dout_active>; + pinctrl-3 = <&quat_tdm_sleep &quat_tdm_dout_sleep>; +}; + +&wcd934x_cdc { + qcom,cdc-micbias1-mv = <2700>; + qcom,cdc-micbias3-mv = <2700>; + qcom,cdc-micbias4-mv = <2700>; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/sm8150-pmic-overlay.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/sm8150-pmic-overlay.dtsi new file mode 100644 index 000000000000..28c6e41ad394 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/sm8150-pmic-overlay.dtsi @@ -0,0 +1,28 @@ +#include "../../../sm8150-pmic-overlay.dtsi" + +#include "pm8150.dtsi" +#include "pm8150b.dtsi" +#include "pm8150l.dtsi" + +&pm8150b_gpios { + otg_vbus_boost { + otg_vbus_boost_default: otg_vbus_boost_default { + pins = "gpio12"; + function = "normal"; + output-low; + power-source = <0>; + }; + }; + + power_good { + /*Get the DC Power Good signal*/ + power_good_default: power_good_default { + pins = "gpio7"; + function = "normal"; + qcom,drive-strength = <2>; /* 2 MA */ + bias-disable; /* NO pull */ + power-source = <1>; + input-enable; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/sm8150-sde-display.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/sm8150-sde-display.dtsi new file mode 100644 index 000000000000..be96cd1252af --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/sm8150-sde-display.dtsi @@ -0,0 +1,532 @@ +#include "../../../sm8150-sde-display.dtsi" + +#include "display/dsi-panel-ss-notch-fhd-ea8074-cmd.dtsi" +#include "display/dsi-panel-samsung-fhd-ea8076-cmd.dtsi" +#include "display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi" +#include "display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi" +#include "display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi" +#include "display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi" +#include "display/dsi-panel-tianma-fhd-nt36672a-video.dtsi" +#include "display/dsi-panel-ss-fhd-ea8076-cmd.dtsi" +#include "display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi" +#include "display/dsi-panel-visionox-fhd-r66456-f11-cmd.dtsi" +#include "display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi" +#include "display/dsi-panel-j20s-36-02-0a-lcd-dsc-vid.dtsi" +#include "display/dsi-panel-j20s-42-02-0b-lcd-dsc-vid.dtsi" +#include "display/dsi-panel-k82-42-02-0a-video.dtsi" +#include "display/dsi-panel-k82-36-02-0b-video.dtsi" + +&display_panel_avdd_eldo { + status = "disabled"; +}; + +&soc { + dsi_amoled_panel_pwr_supply: dsi_amoled_panel_pwr_supply { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <62000>; + qcom,supply-disable-load = <80>; + //qcom,supply-post-on-sleep = <20>; + }; + + qcom,panel-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vci"; + qcom,supply-min-voltage = <3000000>; + qcom,supply-max-voltage = <3000000>; + qcom,supply-enable-load = <62000>; + qcom,supply-disable-load = <80>; + qcom,supply-post-on-sleep = <10>; + qcom,supply-pre-off-sleep = <10>; + }; + }; + + dsi_amoled_panel_pwr_external_supply: dsi_amoled_panel_pwr_external_supply { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <62000>; + qcom,supply-disable-load = <80>; + //qcom,supply-post-on-sleep = <20>; + }; + + qcom,panel-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vcie"; + qcom,supply-min-voltage = <3000000>; + qcom,supply-max-voltage = <3000000>; + qcom,supply-enable-load = <62000>; + qcom,supply-disable-load = <80>; + qcom,supply-post-on-sleep = <10>; + qcom,supply-pre-off-sleep = <10>; + }; + }; + + dsi_panel_pwr_supply_k82_vddio: dsi_panel_pwr_supply_k82_vddio { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <62000>; + qcom,supply-disable-load = <80>; + qcom,supply-post-on-sleep = <20>; + qcom,supply-post-off-sleep = <10>; + }; + qcom,panel-supply-entry@1 { + reg = <1>; + qcom,supply-name = "enp"; + qcom,supply-min-voltage = <5500000>; + qcom,supply-max-voltage = <5500000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-pre-on-sleep = <0>; + qcom,supply-pre-off-sleep = <0>; + qcom,supply-post-on-sleep = <10>; + qcom,supply-post-off-sleep = <10>; + }; + qcom,panel-supply-entry@2 { + reg = <2>; + qcom,supply-name = "enn"; + qcom,supply-min-voltage = <5500000>; + qcom,supply-max-voltage = <5500000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-pre-on-sleep = <0>; + qcom,supply-pre-off-sleep = <0>; + qcom,supply-post-on-sleep = <10>; + qcom,supply-post-off-sleep = <10>; + }; + }; +}; + +&soc { + dsi_ss_ea8074_fhd_cmd_display: qcom,dsi-display@24 { + label = "dsi_ss_ea8074_fhd_cmd_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl-num = <0>; + qcom,dsi-phy-num = <0>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0"; + + qcom,dsi-panel = <&dsi_ss_notch_fhd_ea8074_cmd>; + }; + + dsi_samsung_fhd_ea8076_cmd_display: qcom,dsi-display@25 { + label = "dsi_samsung_fhd_ea8076_cmd_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl-num = <0>; + qcom,dsi-phy-num = <0>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0"; + + qcom,dsi-panel = <&dsi_samsung_fhd_ea8076_cmd>; + }; + + dsi_samsung_fhd_ea8076_f1_cmd_display: qcom,dsi-display@26 { + label = "dsi_samsung_fhd_ea8076_f1_cmd_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl-num = <0>; + qcom,dsi-phy-num = <0>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0"; + + qcom,dsi-panel = <&dsi_samsung_fhd_ea8076_f1_cmd>; + }; + + dsi_samsung_fhd_ea8076_f1mp_cmd_display: qcom,dsi-display@27 { + label = "dsi_samsung_fhd_ea8076_f1mp_cmd_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl-num = <0>; + qcom,dsi-phy-num = <0>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0"; + + qcom,dsi-panel = <&dsi_samsung_fhd_ea8076_f1mp_cmd>; + }; + + dsi_samsung_fhd_ea8076_f1p2_2_cmd_display: qcom,dsi-display@28 { + label = "dsi_samsung_fhd_ea8076_f1p2_2_cmd_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl-num = <0>; + qcom,dsi-phy-num = <0>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0"; + + qcom,dsi-panel = <&dsi_samsung_fhd_ea8076_f1p2_2_cmd>; + }; + + dsi_samsung_fhd_ea8076_f1p2_cmd_display: qcom,dsi-display@29 { + label = "dsi_samsung_fhd_ea8076_f1p2_cmd_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl-num = <0>; + qcom,dsi-phy-num = <0>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0"; + + qcom,dsi-panel = <&dsi_samsung_fhd_ea8076_f1p2_cmd>; + }; + + dsi_tianma_fhd_nt36672a_video_display: qcom,dsi-display@30 { + label = "dsi_tianma_fhd_nt36672a_video_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl-num = <0>; + qcom,dsi-phy-num = <0>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0"; + + qcom,dsi-panel = <&dsi_tianma_fhd_nt36672a_video>; + }; + + dsi_ss_fhd_ea8076_cmd_display: qcom,dsi-display@31 { + label = "dsi_ss_fhd_ea8076_cmd_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl-num = <0>; + qcom,dsi-phy-num = <0>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0"; + + qcom,dsi-panel = <&dsi_ss_fhd_ea8076_cmd>; + }; + + dsi_visionox_fhd_r66456_f11_cmd_display: qcom,dsi-display@32 { + label = "dsi_visionox_fhd_r66456_f11_cmd_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl-num = <0>; + qcom,dsi-phy-num = <0>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0"; + + qcom,dsi-panel = <&dsi_visionox_fhd_r66456_f11_cmd>; + }; + + dsi_ss_fhd_ea8076_global_cmd_display: qcom,dsi-display@33 { + label = "dsi_ss_fhd_ea8076_global_cmd_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl-num = <0>; + qcom,dsi-phy-num = <0>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0"; + + qcom,dsi-panel = <&dsi_ss_fhd_ea8076_global_cmd>; + }; + + dsi_samsung_fhd_ea8076_f1s_cmd_display: qcom,dsi-display@34 { + label = "dsi_samsung_fhd_ea8076_f1s_cmd_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl-num = <0>; + qcom,dsi-phy-num = <0>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0"; + + qcom,dsi-panel = <&dsi_samsung_fhd_ea8076_f1s_cmd>; + }; + + dsi_j20s_36_02_0a_video_display: qcom,dsi-display@35{ + label = "dsi_j20s_36_02_0a_video_display"; + qcom,display-type = "primary"; + qcom,dsi-ctrl-num = <0>; + qcom,dsi-phy-num = <0>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0", + "src_byte_clk0", "src_pixel_clk0", + "shadow_byte_clk0", "shadow_pixel_clk0"; + qcom,ulps-enabled; + qcom,dsi-panel = <&dsi_j20s_36_02_0a_video>; + }; + + dsi_j20s_42_02_0b_video_display: qcom,dsi-display@36 { + label = "dsi_j20s_42_02_0b_video_display"; + qcom,display-type = "primary"; + qcom,dsi-ctrl-num = <0>; + qcom,dsi-phy-num = <0>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0", + "src_byte_clk0", "src_pixel_clk0", + "shadow_byte_clk0", "shadow_pixel_clk0"; + qcom,ulps-enabled; + qcom,dsi-panel = <&dsi_j20s_42_02_0b_video>; + }; + + dsi_k82_42_02_0a_dual_cphy_vid_display: qcom,dsi-display@37 { + label = "dsi_k82_42_02_0a_dual_cphy_vid_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl-num = <0 1>; + qcom,dsi-phy-num = <0 1>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0", + "cphy_byte_clk0", "cphy_pixel_clk0"; + + qcom,dsi-panel = <&dsi_k82_42_02_0a_dual_cphy_video>; + }; + + dsi_k82_36_02_0b_dual_cphy_vid_display: qcom,dsi-display@38 { + label = "dsi_k82_36_02_0b_dual_cphy_vid_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl-num = <0 1>; + qcom,dsi-phy-num = <0 1>; + qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0", + "cphy_byte_clk0", "cphy_pixel_clk0"; + + qcom,dsi-panel = <&dsi_k82_36_02_0b_dual_cphy_video>; + }; +}; + +&sde_dsi { + /delete-property/ vdd-supply; + vci-supply = <&pm8150_l13>; + + qcom,dsi-display-list = + <&dsi_sharp_4k_dsc_video_display + &dsi_sharp_4k_dsc_cmd_display + &dsi_sharp_1080_cmd_display + &dsi_dual_sharp_1080_120hz_cmd_display + &dsi_dual_nt35597_truly_video_display + &dsi_dual_nt35597_truly_cmd_display + &dsi_nt35597_truly_dsc_cmd_display + &dsi_nt35597_truly_dsc_video_display + &dsi_sim_vid_display + &dsi_dual_sim_vid_display + &dsi_sim_cmd_display + &dsi_dual_sim_cmd_display + &dsi_sim_dsc_375_cmd_display + &dsi_dual_sim_dsc_375_cmd_display + &dsi_sw43404_amoled_cmd_display + &dsi_nt35695b_truly_fhd_cmd_display + &dsi_nt35695b_truly_fhd_video_display + &dsi_sw43404_amoled_video_display + &dsi_sw43404_amoled_fhd_plus_cmd_display + &dsi_ss_ea8074_fhd_cmd_display + &dsi_samsung_fhd_ea8076_cmd_display + &dsi_samsung_fhd_ea8076_f1_cmd_display + &dsi_samsung_fhd_ea8076_f1mp_cmd_display + &dsi_samsung_fhd_ea8076_f1p2_2_cmd_display + &dsi_samsung_fhd_ea8076_f1p2_cmd_display + &dsi_tianma_fhd_nt36672a_video_display + &dsi_dual_nt36850_truly_cmd_display + &dsi_ss_fhd_ea8076_cmd_display + &dsi_visionox_fhd_r66456_f11_cmd_display + &dsi_ss_fhd_ea8076_global_cmd_display + &dsi_samsung_fhd_ea8076_f1s_cmd_display + &dsi_rm69299_visionox_amoled_vid_display + &dsi_j20s_36_02_0a_video_display + &dsi_j20s_42_02_0b_video_display + &dsi_k82_42_02_0a_dual_cphy_vid_display + &dsi_k82_36_02_0b_dual_cphy_vid_display>; +}; + +&sde_dsi1 { + /delete-property/ vdd-supply; +}; + +/* +&sde_dp { + /delete-property/ qcom,dp-aux-switch; +}; +*/ + +&dsi_ss_notch_fhd_ea8074_cmd { + qcom,mdss-dsi-t-clk-post = <0x19>; + qcom,mdss-dsi-t-clk-pre = <0x1C>; + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-phy-timings = [00 22 08 09 25 23 09 + 09 06 03 04 00 1C 19]; + qcom,display-topology = <1 0 1>; + qcom,default-topology-index = <0>; + }; + }; +}; + +&dsi_samsung_fhd_ea8076_cmd { + qcom,mdss-dsi-t-clk-post = <0x1A>; + qcom,mdss-dsi-t-clk-pre = <0x1E>; + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-phy-timings = [00 24 0A 0A 26 25 09 + 0A 06 03 04 00 1E 1A]; + qcom,display-topology = <1 0 1>; + qcom,default-topology-index = <0>; + }; + }; +}; + +&dsi_samsung_fhd_ea8076_f1_cmd { + qcom,mdss-dsi-t-clk-post = <0x1A>; + qcom,mdss-dsi-t-clk-pre = <0x1E>; + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-phy-timings = [00 24 0A 0A 26 25 09 + 0A 06 03 04 00 1E 1A]; + qcom,display-topology = <1 0 1>; + qcom,default-topology-index = <0>; + }; + }; +}; + +&dsi_samsung_fhd_ea8076_f1mp_cmd { + qcom,mdss-dsi-t-clk-post = <0x1A>; + qcom,mdss-dsi-t-clk-pre = <0x1E>; + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-phy-timings = [00 24 0A 0A 26 25 09 + 0A 06 03 04 00 1E 1A]; + qcom,display-topology = <1 0 1>; + qcom,default-topology-index = <0>; + }; + }; +}; + +&dsi_samsung_fhd_ea8076_f1p2_cmd { + qcom,mdss-dsi-t-clk-post = <0x1A>; + qcom,mdss-dsi-t-clk-pre = <0x1E>; + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-phy-timings = [00 24 0A 0A 26 25 09 + 0A 06 03 04 00 1E 1A]; + qcom,display-topology = <1 0 1>; + qcom,default-topology-index = <0>; + }; + }; +}; + +&dsi_samsung_fhd_ea8076_f1p2_2_cmd { + qcom,mdss-dsi-t-clk-post = <0x1A>; + qcom,mdss-dsi-t-clk-pre = <0x1E>; + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-phy-timings = [00 24 0A 0A 26 25 09 + 0A 06 03 04 00 1E 1A]; + qcom,display-topology = <1 0 1>; + qcom,default-topology-index = <0>; + }; + }; +}; + +&dsi_tianma_fhd_nt36672a_video { + qcom,mdss-dsi-t-clk-post = <0x18>; + qcom,mdss-dsi-t-clk-pre = <0x1B>; + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-phy-timings = [00 21 08 08 25 22 09 + 08 06 03 04 00 1B 18]; + qcom,display-topology = <1 0 1>; + qcom,default-topology-index = <0>; + }; + }; +}; + +&dsi_ss_fhd_ea8076_cmd { + qcom,mdss-dsi-t-clk-post = <0x0F>; + qcom,mdss-dsi-t-clk-pre = <0x37>; + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-phy-timings = [00 24 0A 0A 26 25 09 + 0A 06 03 04 00 1E 1A]; + qcom,display-topology = <1 0 1>; + qcom,default-topology-index = <0>; + }; + }; +}; + +&dsi_visionox_fhd_r66456_f11_cmd { + qcom,mdss-dsi-t-clk-post = <0x0F>; + qcom,mdss-dsi-t-clk-pre = <0x37>; + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-phy-timings = [00 24 0A 0A 26 25 09 + 0A 06 03 04 00 1E 1A]; + qcom,display-topology = <1 0 1>; + qcom,default-topology-index = <0>; + }; + }; +}; + +&dsi_ss_fhd_ea8076_global_cmd { + qcom,mdss-dsi-t-clk-post = <0x1A>; + qcom,mdss-dsi-t-clk-pre = <0x1E>; + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-phy-timings = [00 24 0A 0A 26 24 0A + 0A 06 03 04 00 1E 1A]; + qcom,display-topology = <1 0 1>; + qcom,default-topology-index = <0>; + }; + }; +}; + +&dsi_samsung_fhd_ea8076_f1s_cmd { + qcom,mdss-dsi-t-clk-post = <0x1A>; + qcom,mdss-dsi-t-clk-pre = <0x1E>; + qcom,mdss-dsi-clk-strength = <0xFF>; + qcom,mdss-dsi-display-timings { + timing@0{ + qcom,mdss-dsi-panel-phy-timings = [00 24 0A 0A 26 24 0A + 0A 06 02 04 00 1E 1A]; + qcom,display-topology = <1 0 1>; + qcom,default-topology-index = <0>; + }; + }; +}; + +&dsi_j20s_36_02_0a_video { + qcom,mdss-dsi-t-clk-post = <0x17>; + qcom,mdss-dsi-t-clk-pre = <0x18>; + qcom,mdss-dsi-display-timings { + /* 60 Hz */ + timing@0{ + qcom,mdss-dsi-panel-phy-timings = [00 1C 08 07 23 22 07 + 07 05 02 04 00 18 17]; + qcom,display-topology = <1 1 1>; + qcom,default-topology-index = <0>; + }; + }; +}; + +&dsi_j20s_42_02_0b_video { + qcom,mdss-dsi-t-clk-post = <0x17>; + qcom,mdss-dsi-t-clk-pre = <0x18>; + qcom,mdss-dsi-display-timings { + /* 120 Hz */ + timing@0{ + qcom,mdss-dsi-panel-phy-timings = [00 1C 08 07 23 22 07 + 07 05 02 04 00 18 17]; + qcom,display-topology = <1 1 1>; + qcom,default-topology-index = <0>; + }; + }; +}; + +&dsi_k82_42_02_0a_dual_cphy_video { + qcom,mdss-dsi-display-timings { + timing@0 { + qcom,mdss-dsi-panel-phy-timings = [00 00 00 00 27 2B 0A + 19 0A 02 04 00 00 00]; + qcom,display-topology = <2 0 2>; + qcom,default-topology-index = <0>; + }; + }; +}; +&dsi_k82_36_02_0b_dual_cphy_video { + qcom,mdss-dsi-display-timings { + timing@0 { + qcom,mdss-dsi-panel-phy-timings = [00 00 00 00 27 2B 0A + 19 0A 02 04 00 00 00]; + qcom,display-topology = <2 0 2>; + qcom,default-topology-index = <0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/smb1390.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/smb1390.dtsi new file mode 100644 index 000000000000..471e1db26a75 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/smb1390.dtsi @@ -0,0 +1,15 @@ +&qupv3_se4_i2c { + #include "../../../smb1390.dtsi" +}; + +&smb1390_slave { + interrupt-parent = <&spmi_bus>; + interrupts = <0x2 0xC5 0x0 IRQ_TYPE_LEVEL_LOW>; + interrupt_names = "smb1390_slave"; + interrupt-controller; + #interrupt-cells = <3>; +}; + +&smb1390_slave_charger { + interrupt-parent = <&smb1390_slave>; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/xiaomi-sdx50-sm8150-common.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/xiaomi-sdx50-sm8150-common.dtsi new file mode 100644 index 000000000000..d2eea3d10995 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/xiaomi-sdx50-sm8150-common.dtsi @@ -0,0 +1,407 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include +#include + +#include "sm8150-pmic-overlay.dtsi" +#include "sm8150-sde-display.dtsi" +#include "../../../sm8150-thermal-overlay.dtsi" + +#include "../common/smb1390.dtsi" + +&qupv3_se4_i2c { +#include "../../../smb1355.dtsi" +}; + +&qupv3_se12_2uart { + status = "ok"; +}; + +&vendor { + bluetooth: bt_wcn3990 { + compatible = "qca,wcn3990"; + qca,bt-vdd-core-supply = <&pm8150_l7>; + qca,bt-vdd-pa-supply = <&pm8150l_l2>; + qca,bt-vdd-ldo-supply = <&pm8150l_l11>; + + qca,bt-vdd-core-voltage-level = <1800000 1800000>; + qca,bt-vdd-pa-voltage-level = <1304000 1304000>; + qca,bt-vdd-ldo-voltage-level = <3312000 3312000>; + + qca,bt-vdd-core-current-level = <0>; /* LPM/PFM */ + qca,bt-vdd-pa-current-level = <0>; /* LPM/PFM */ + qca,bt-vdd-ldo-current-level = <0>; /* LPM/PFM */ + }; + + + extcon_usb1: extcon_usb1 { + compatible = "linux,extcon-usb-gpio"; + vbus-gpio = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>; + id-gpio = <&tlmm 101 GPIO_ACTIVE_HIGH>; + vbus-out-gpio = <&pm8150_gpios 9 GPIO_ACTIVE_HIGH>; + + pinctrl-names = "default"; + pinctrl-0 = <&usb2_vbus_det_default + &usb2_id_det_default + &usb2_vbus_boost_default>; + }; +}; + +&qupv3_se13_4uart { + status = "ok"; +}; + +&qupv3_se3_spi { + status = "ok"; +}; + +&qupv3_se4_i2c { + status = "ok"; +}; + +&soc { + gpio_keys { + compatible = "gpio-keys"; + label = "gpio-keys"; + + pinctrl-names = "default"; + pinctrl-0 = <&key_vol_up_default>; + + vol_up { + label = "volume_up"; + gpios = <&pm8150_gpios 6 GPIO_ACTIVE_LOW>; + linux,input-type = <1>; + linux,code = ; + gpio-key,wakeup; + debounce-interval = <15>; + linux,can-disable; + }; + }; + + ext_5v_boost: ext_5v_boost { + compatible = "regulator-fixed"; + status = "disabled"; + regulator-name = "ext_5v_boost"; + gpio = <&pm8150b_gpios 12 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-enable-ramp-delay = <1600>; + + pinctrl-names = "default"; + pinctrl-0 = <&otg_vbus_boost_default>; + }; + + qcom_qbt1000: qcom,qbt1000 { + compatible = "qcom,qbt1000"; + clock-names = "core", "iface"; + clock-frequency = <25000000>; + qcom,ipc-gpio = <&tlmm 118 0>; + pinctrl-names = "default"; + pinctrl-0 = <&key_home_default>; + qcom,finger-detect-gpio = <&pm8150_gpios 1 0>; + }; +}; + +&dsi_sharp_4k_dsc_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_sharp_4k_dsc_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_sim_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_sim_vid { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_sim_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_sim_vid { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_nt35597_truly_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_nt35597_truly_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_sim_dsc_375_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_sim_dsc_375_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_nt35597_truly_dsc_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_nt35597_truly_dsc_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_nt35695b_truly_fhd_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_nt35695b_truly_fhd_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_samsung_fhd_ea8076_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <2047>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + //qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_samsung_fhd_ea8076_f1s_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <2047>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + //qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 11 0>; +}; + +&dsi_samsung_fhd_ea8076_cmd_display { + qcom,dsi-display-active; +}; + +&qupv3_se9_i2c { + status = "ok"; + nq@28 { + compatible = "qcom,nq-nci"; + reg = <0x28>; + qcom,nq-irq = <&tlmm 47 0x00>; + qcom,nq-ven = <&tlmm 41 0x00>; + qcom,nq-firm = <&tlmm 48 0x00>; + qcom,nq-clkreq = <&tlmm 113 0x00>; + //qcom,nq-esepwr = <&tlmm 42 0x00>; + interrupt-parent = <&tlmm>; + interrupts = <47 0>; + interrupt-names = "nfc_irq"; + pinctrl-names = "nfc_active", "nfc_suspend"; + pinctrl-0 = <&nfc_int_active &nfc_enable_active + &nfc_clk_req_active>; + pinctrl-1 = <&nfc_int_suspend &nfc_enable_suspend + &nfc_clk_req_suspend>; + }; +}; + +&ufsphy_mem { + compatible = "qcom,ufs-phy-qmp-v4"; + + vdda-phy-supply = <&pm8150_l5>; + vdda-phy-always-on; + vdda-pll-supply = <&pm8150l_l3>; + vdda-phy-max-microamp = <90200>; + vdda-pll-max-microamp = <19000>; + + status = "ok"; +}; + +&spmi_debug_bus { + status = "ok"; +}; + +&pm8150l_wled { + qcom,string-cfg= <7>; + qcom,leds-per-string = <6>; + status = "ok"; +}; + +&pm8150l_lcdb { + status = "ok"; +}; + +&pm8150b_fg { + qcom,battery-data = <&mtp_batterydata>; + /* ESR fast calibration */ + qcom,fg-esr-timer-chg-fast = <0 7>; + qcom,fg-esr-timer-dischg-fast = <0 7>; + qcom,fg-esr-timer-chg-slow = <0 96>; + qcom,fg-esr-timer-dischg-slow = <0 96>; + qcom,fg-esr-cal-soc-thresh = <26 230>; + qcom,fg-esr-cal-temp-thresh = <10 40>; +}; + +&sdhc_2 { + vdd-supply = <&pm8150l_l9>; + qcom,vdd-voltage-level = <2950000 2960000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8150l_l6>; + qcom,vdd-io-voltage-level = <1808000 2960000>; + qcom,vdd-io-current-level = <200 22000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &storage_cd>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &storage_cd>; + + cd-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; + + status = "ok"; +}; + +&wil6210 { + status = "ok"; +}; + +&mhi_0 { + mhi,fw-name = "debug.mbn"; +}; + +&pm8150b_charger { + qcom,sec-charger-config = <3>; + io-channels = <&pm8150b_vadc ADC_MID_CHG_DIV6>, + <&pm8150b_vadc ADC_USB_IN_I>, + <&pm8150b_vadc ADC_SBUx>, + <&pm8150b_vadc ADC_VPH_PWR>, + <&pm8150b_vadc ADC_CHG_TEMP>; + io-channel-names = "mid_voltage", + "usb_in_current", + "sbux_res", + "vph_voltage", + "chg_temp"; + qcom,battery-data = <&mtp_batterydata>; + qcom,sw-jeita-enable; + qcom,wd-bark-time-secs = <16>; +}; + +&smb1390 { + pinctrl-names = "default"; + pinctrl-0 = <&smb_stat_default>; + status = "ok"; +}; + +&smb1390_charger { + io-channels = <&pm8150b_vadc ADC_AMUX_THM2>; + io-channel-names = "cp_die_temp"; + status = "ok"; +}; + +&usb1 { + extcon = <&extcon_usb1>; + status = "ok"; +}; + +&usb2_phy1 { + status = "ok"; +}; + +&usb_qmp_phy { + status = "ok"; +}; + +&smb1355 { + status = "ok"; +}; + +&smb1355_charger { + io-channels = <&pm8150b_vadc ADC_AMUX_THM2>; + io-channel-names = "charger_temp"; + status = "ok"; +}; + +&reserved_memory { + ramdump_fb_mem: ramdump_fb_region@af000000 { + compatible = "removed-dma-pool"; + no-map; + reg = <0 0xaf000000 0 0x1000000>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/xiaomi-sm8150-common.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/xiaomi-sm8150-common.dtsi new file mode 100644 index 000000000000..9516bb174226 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/xiaomi-sm8150-common.dtsi @@ -0,0 +1,527 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include +#include + +#include "sm8150-pmic-overlay.dtsi" +#include "sm8150-sde-display.dtsi" +#include "../../../sm8150-thermal-overlay.dtsi" + +&qupv3_se12_2uart { + status = "ok"; +}; + +&vendor { + bluetooth: bt_wcn3990 { + compatible = "qca,wcn3990"; + qca,bt-vdd-core-supply = <&pm8150_l7>; + qca,bt-vdd-pa-supply = <&pm8150l_l2>; + qca,bt-vdd-ldo-supply = <&pm8150l_l11>; + + qca,bt-vdd-core-voltage-level = <1800000 1800000>; + qca,bt-vdd-pa-voltage-level = <1304000 1304000>; + qca,bt-vdd-ldo-voltage-level = <3312000 3312000>; + + qca,bt-vdd-core-current-level = <0>; /* LPM/PFM */ + qca,bt-vdd-pa-current-level = <0>; /* LPM/PFM */ + qca,bt-vdd-ldo-current-level = <0>; /* LPM/PFM */ + }; + + extcon_usb1: extcon_usb1 { + compatible = "linux,extcon-usb-gpio"; + vbus-gpio = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>; + id-gpio = <&tlmm 101 GPIO_ACTIVE_HIGH>; + vbus-out-gpio = <&pm8150_gpios 9 GPIO_ACTIVE_HIGH>; + + pinctrl-names = "default"; + pinctrl-0 = <&usb2_vbus_det_default + &usb2_id_det_default + &usb2_vbus_boost_default>; + }; +}; + +&qupv3_se13_4uart { + status = "ok"; +}; + +&qupv3_se3_spi { + status = "ok"; +}; + +&qupv3_se4_i2c { + status = "ok"; +}; + +&soc { + gpio_keys { + compatible = "gpio-keys"; + label = "gpio-keys"; + + pinctrl-names = "default"; + pinctrl-0 = <&key_vol_up_default>; + + vol_up { + label = "volume_up"; + gpios = <&pm8150_gpios 6 GPIO_ACTIVE_LOW>; + linux,input-type = <1>; + linux,code = ; + gpio-key,wakeup; + debounce-interval = <15>; + linux,can-disable; + }; + + }; + + ext_5v_boost: ext_5v_boost { + compatible = "regulator-fixed"; + status = "disabled"; + regulator-name = "ext_5v_boost"; + gpio = <&pm8150b_gpios 12 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-enable-ramp-delay = <1600>; + + pinctrl-names = "default"; + pinctrl-0 = <&otg_vbus_boost_default>; + }; + + qcom,qbt1000 { + compatible = "qcom,qbt1000"; + clock-names = "core", "iface"; + clock-frequency = <25000000>; +/* qcom,ipc-gpio = <&tlmm 118 0>; */ + qcom,finger-detect-gpio = <&pm8150_gpios 1 0>; + status = "disabled"; + }; + + wdog: qcom,wdt@17c10000 { + qcom,bark-time = <20000>; + qcom,pet-time = <15000>; + }; +}; + + +&dsi_sharp_4k_dsc_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_sharp_4k_dsc_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_sim_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_sim_vid { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_sim_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_sim_vid { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_nt35597_truly_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_nt35597_truly_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_sim_dsc_375_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_sim_dsc_375_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_nt35597_truly_dsc_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_nt35597_truly_dsc_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_sharp_1080_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_nt35695b_truly_fhd_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_nt35695b_truly_fhd_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + //qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_ss_notch_fhd_ea8074_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <1023>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + //qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_samsung_fhd_ea8076_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <2047>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + //qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_samsung_fhd_ea8076_f1_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <2047>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + //qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_samsung_fhd_ea8076_f1mp_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <2047>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + //qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_samsung_fhd_ea8076_f1p2_2_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <2047>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + //qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_samsung_fhd_ea8076_f1p2_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <2047>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + //qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_tianma_fhd_nt36672a_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + qcom,panel-mode-gpio = <&tlmm 7 0>; +// qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_ss_fhd_ea8076_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_external_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <2047>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + //qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_ss_fhd_ea8076_global_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_external_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <2047>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + //qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_visionox_fhd_r66456_f11_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_external_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <256>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + //qcom,panel-mode-gpio = <&tlmm 7 0>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_j20s_36_02_0a_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-brightness-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_j20s_42_02_0b_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-brightness-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "single_port"; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_k82_42_02_0a_dual_cphy_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply_k82_vddio>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <2047>; + qcom,mdss-brightness-max-level = <2047>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_k82_36_02_0b_dual_cphy_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply_k82_vddio>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,mdss-dsi-bl-min-level = <2>; + qcom,mdss-dsi-bl-max-level = <2047>; + qcom,mdss-brightness-max-level = <2047>; + qcom,platform-te-gpio = <&tlmm 8 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&qupv3_se9_i2c { + status = "ok"; + nq@28 { + compatible = "qcom,nq-nci"; + reg = <0x28>; + qcom,nq-irq = <&tlmm 47 0x00>; + qcom,nq-ven = <&tlmm 103 0x00>; + qcom,nq-firm = <&tlmm 48 0x00>; + qcom,nq-clkreq = <&tlmm 113 0x00>; + //qcom,nq-esepwr = <&tlmm 42 0x00>; + interrupt-parent = <&tlmm>; + interrupts = <47 0>; + interrupt-names = "nfc_irq"; + pinctrl-names = "nfc_active", "nfc_suspend"; + pinctrl-0 = <&nfc_int_active &nfc_enable_active + &nfc_clk_req_active>; + pinctrl-1 = <&nfc_int_suspend &nfc_enable_suspend + &nfc_clk_req_suspend>; + }; +}; + +&dsi_sim_vid_display { + qcom,dsi-display-active; +}; + +&ufsphy_mem { + compatible = "qcom,ufs-phy-qmp-v4"; + + vdda-phy-supply = <&pm8150_l5>; + vdda-phy-always-on; + vdda-pll-supply = <&pm8150l_l3>; + vdda-phy-max-microamp = <90200>; + vdda-pll-max-microamp = <19000>; + + status = "ok"; +}; + +&ufshc_mem { + vdd-hba-supply = <&ufs_phy_gdsc>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm8150_l10>; + vcc-voltage-level = <2950000 2960000>; + vccq2-supply = <&pm8150_s4>; + vcc-max-microamp = <750000>; + vccq2-max-microamp = <750000>; + + qcom,vddp-ref-clk-supply = <&pm8150_l9>; + qcom,vddp-ref-clk-max-microamp = <100>; + + status = "ok"; +}; + +&sdhc_2 { + vdd-supply = <&pm8150l_l9>; + qcom,vdd-voltage-level = <2950000 2960000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8150l_l6>; + qcom,vdd-io-voltage-level = <1808000 2960000>; + qcom,vdd-io-current-level = <200 22000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &storage_cd>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &storage_cd>; + + cd-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; + + status = "disabled"; +}; + +&spmi_debug_bus { + status = "ok"; +}; + +&pm8150l_wled { + qcom,string-cfg= <7>; + qcom,leds-per-string = <6>; + status = "ok"; +}; + +&pm8150l_lcdb { + status = "ok"; +}; + +&pm8150b_charger { + io-channels = <&pm8150b_vadc ADC_USB_IN_V_16>, + <&pm8150b_vadc ADC_USB_IN_I>, + <&pm8150b_vadc ADC_CHG_TEMP>; + io-channel-names = "usb_in_voltage", + "usb_in_current", + "chg_temp"; +}; + +&wil6210 { + status = "ok"; +}; + +&mhi_0 { + mhi,fw-name = "debug.mbn"; +}; + +&pcie0 { + qcom,no-l1-supported; +}; + +&usb1 { + /*extcon = <&extcon_usb1>;*/ + status = "ok"; +}; + +&usb2_phy1 { + status = "ok"; +}; + +&usb_qmp_phy { + status = "ok"; +}; + +&reserved_memory { + ramdump_fb_mem: ramdump_fb_region@af000000 { + compatible = "removed-dma-pool"; + no-map; + reg = <0 0xaf000000 0 0x1000000>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-audio-overlay.dtsi new file mode 100644 index 000000000000..5d5c471561aa --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-audio-overlay.dtsi @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include "../common/sm8150-audio-overlay.dtsi" + +&snd_934x { + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "MADINPUT", "MCLK", + "hifi amp", "LINEOUT1", + "hifi amp", "LINEOUT2", + "AMIC2", "MIC BIAS2", + "MIC BIAS2", "Headset Mic", + "AMIC3", "MIC BIAS3", + "MIC BIAS3", "ANCRight Headset Mic", + "AMIC1", "MIC BIAS1", + "MIC BIAS1", "ANCLeft Headset Mic", + "AMIC4", "MIC BIAS3", + "MIC BIAS3", "ANCRight Headset Mic", + "AMIC5", "MIC BIAS4", + "MIC BIAS4", "Analog Mic5"; + + qcom,uart-audio-sw-gpio = <&sbu_uart_en>; + /* qcom,adc2-switch-gpio = <&adc2_switch_gpio>; */ + qcom,msm-mbhc-usbc-audio-supported = <1>; + qcom,fsa4476-gpio-support = <1>; + qcom,usbc-analog-en1-gpio = <&wcd_usbc_analog_en1_gpio>; + qcom,usbc-analog-en2-gpio = <&tlmm 32 0>; + + pinctrl-names = "quat_mi2s_enable", "quat_mi2s_disable", + "quat_tdm_enable", "quat_tdm_disable", + "aud_active", "aud_sleep"; + pinctrl-0 = <&quat_mi2s_active &quat_mi2s_sd0_active &quat_mi2s_sd1_active>; + pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_sd0_sleep &quat_mi2s_sd1_sleep>; + pinctrl-2 = <&quat_tdm_active &quat_tdm_dout_active>; + pinctrl-3 = <&quat_tdm_sleep &quat_tdm_dout_sleep>; + pinctrl-4 = <&wcd_usbc_analog_en2_active>; + pinctrl-5 = <&wcd_usbc_analog_en2_idle>; +}; + +&soc { + sbu_uart_en: msm_cdc_pinctrl@25 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&sbu_uart_en_active>; + pinctrl-1 = <&sbu_uart_en_idle>; + }; + + adc2_switch_gpio: msm_cdc_pinctrl@142 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&adc2_switch_gpio_active>; + pinctrl-1 = <&adc2_switch_gpio_idle>; + }; + + wcd_usbc_analog_en1_gpio: msm_cdc_pinctrl@35 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&wcd_usbc_analog_en1_active>; + pinctrl-1 = <&wcd_usbc_analog_en1_idle>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-pinctrl.dtsi new file mode 100644 index 000000000000..4155e541eab1 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-pinctrl.dtsi @@ -0,0 +1,796 @@ +/*for F1X pinctrl*/ + +&tlmm { + pmx_ts_active { + ts_active: ts_active { + mux { + pins = "gpio122", "gpio12", "gpio31"; + function = "gpio"; + }; + config { + pins = "gpio122", "gpio12", "gpio31"; + drive-strength = <8>; + bias-pull-up; + }; + }; + }; + + pmx_ts_int_suspend { + ts_int_suspend: ts_int_suspend { + mux { + pins = "gpio122"; + function = "gpio"; + }; + config { + pins = "gpio122"; + drive-strength = <2>; + bias-pull-down; + input-enable; + }; + }; + }; + + pmx_ts_reset_suspend { + ts_reset_suspend: ts_reset_suspend { + mux { + pins = "gpio12"; + function = "gpio"; + }; + config { + pins = "gpio12"; + drive-strength = <2>; + bias-disable; + output-low; + }; + }; + }; + + /* GPIO_119 : FP_RESET_N */ + msm_gpio_119: msm_gpio_119 { + mux { + pins = "gpio119"; + function = "gpio"; + }; + + config { + pins = "gpio119"; + drive-strength = <2>; + bias-disable; + output-low; + }; + }; + + /* GPIO_119 : FP_RESET_N, state device active*/ + msm_gpio_119_output_high: msm_gpio_119_output_high { + mux { + pins = "gpio119"; + function = "gpio"; + }; + + config { + pins = "gpio119"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + + /* GPIO_6 : AW8697_RESET_N */ + msm_gpio_6: msm_gpio_6 { + mux { + pins = "gpio6"; + function = "gpio"; + }; + + config { + pins = "gpio6"; + drive-strength = <2>; + bias-disable; + output-low; + }; + }; + /* GPIO_6 : AW8697_RESET_N, state device active*/ + msm_gpio_6_output_high: msm_gpio_6_output_high { + mux { + pins = "gpio6"; + function = "gpio"; + }; + + config { + pins = "gpio6"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + /* GPIO_27 : AW8697_INTERRUPT_N */ + msm_gpio_27: msm_gpio_27 { + mux { + pins = "gpio27"; + function = "gpio"; + }; + + config { + pins = "gpio27"; + drive-strength = <2>; + bias-pull-up; + input-enable; + }; + }; + + txon_enable_active: txon_enable_active { + /* active state */ + mux { + pins = "gpio130"; + function = "gpio"; + }; + + config { + pins = "gpio130"; + drive-strength = <2>; + bias-pull-up; + output-high; + }; + }; + + txon_enable_suspend: txon_enable_suspend { + /* sleep state */ + mux { + pins = "gpio130"; + function = "gpio"; + }; + + config { + pins = "gpio130"; + drive-strength = <2>; + bias-disable; + bias-pull-down; + output-low; + }; + }; + nu_int_active: nu_int_active { + /* active state */ + mux { + pins = "gpio90"; + function = "gpio"; + }; + + config { + pins = "gpio90"; + drive-strength = <2>; + bias-pull-up; + input-enable; + }; + }; + + nu_int_suspend: nu_int_suspend { + /* sleep state */ + mux { + pins = "gpio90"; + function = "gpio"; + }; + + config { + pins = "gpio90"; + drive-strength = <2>; + bias-pull-up; + input-enable; + }; + }; + nu_sleep_active: nu_sleep_active { + /* active state */ + mux { + pins = "gpio7"; + function = "gpio"; + }; + + config { + pins = "gpio7"; + drive-strength = <2>; + bias-disable; + bias-pull-down; + output-low; + }; + }; + + nu_sleep_suspend: nu_sleep_suspend { + /* sleep state */ + mux { + pins = "gpio7"; + function = "gpio"; + }; + + config { + pins = "gpio7"; + drive-strength = <2>; + bias-disable; + bias-pull-down; + output-low; + }; + }; + + ln8282_enable_active: ln8282_enable_active { + mux { + pins = "gpio41"; + function = "gpio"; + }; + + config { + pins = "gpio41"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + ln8282_enable_suspend: ln8282_enable_suspend { + mux { + pins = "gpio41"; + function = "gpio"; + }; + + config { + pins = "gpio41"; + drive-strength = <2>; + bias-pull-up; + output-high; + }; + }; + + halo7221_enable_active: halo7221_enable_active { + mux { + pins = "gpio41"; + function = "gpio"; + }; + + config { + pins = "gpio41"; + drive-strength = <2>; + bias-pull-up; + output-high; + }; + }; + halo7221_enable_suspend: halo7221_enable_suspend { + mux { + pins = "gpio41"; + function = "gpio"; + }; + + config { + pins = "gpio41"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + idt { + idt_int_active: idt_int_active { + /* active state */ + mux { + pins = "gpio90"; + function = "gpio"; + }; + + config { + pins = "gpio90"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + idt_int_suspend: idt_int_suspend { + /* sleep state */ + mux { + pins = "gpio90"; + function = "gpio"; + }; + + config { + pins = "gpio90"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + idt_enable_active: idt_enable_active { + /* active state */ + mux { + pins = "gpio7"; + function = "gpio"; + }; + + config { + pins = "gpio7"; + drive-strength = <2>; + bias-disable; + bias-pull-down; + output-low; + }; + }; + + idt_enable_suspend: idt_enable_suspend { + /* sleep state */ + mux { + pins = "gpio7"; + function = "gpio"; + }; + + config { + pins = "gpio7"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + adc2_switch_gpio_ctrl { + adc2_switch_gpio_idle: adc2_switch_idle { + mux { + pins = "gpio134"; + function = "gpio"; + }; + config { + pins = "gpio134"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + adc2_switch_gpio_active: adc2_switch_active { + mux { + pins = "gpio134"; + function = "gpio"; + }; + config { + pins = "gpio134"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + + vbus_disable { + vbus_disable_active: usb_vbus_active { + /* active state */ + mux { + pins = "gpio87"; + function = "gpio"; + }; + + config { + pins = "gpio87"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + output-high; + + }; + }; + + vbus_disable_suspend: usb_vbus_suspend { + mux { + pins = "gpio87"; + function = "gpio"; + }; + + config { + pins = "gpio87"; + drive-strength = <2>; /* 2 MA */ + bias-pull-down; + output-low; + }; + }; + }; + + sbu_uart_en_ctrl { + sbu_uart_en_idle: uart_audio_en_idle { + mux { + pins = "gpio25"; + function = "gpio"; + }; + config { + pins = "gpio25"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + sbu_uart_en_active: uart_audio_en_active { + mux { + pins = "gpio25"; + function = "gpio"; + }; + config { + pins = "gpio25"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + + nfc { + nfc_int_active: nfc_int_active { + /* active state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_int_suspend: nfc_int_suspend { + /* sleep state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_active: nfc_enable_active { + /* active state */ + mux { + /* 36: NFC ENABLE 42:ESE Enable */ + pins = "gpio36", "gpio48"; + function = "gpio"; + }; + + config { + pins = "gpio36", "gpio48"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_suspend: nfc_enable_suspend { + /* sleep state */ + mux { + /* 36: NFC ENABLE 42:ESE Enable */ + pins = "gpio36", "gpio48"; + function = "gpio"; + }; + + config { + pins = "gpio36", "gpio48"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + + nfc_clk_req_active: nfc_clk_req_active { + /* active state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_clk_req_suspend: nfc_clk_req_suspend { + /* sleep state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + }; + + wcd_usbc_analog_en2 { + wcd_usbc_analog_en2_idle: wcd_usbc_ana_en2_idle { + mux { + pins = "gpio32"; + function = "gpio"; + }; + config { + pins = "gpio32"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + wcd_usbc_analog_en2_active: wcd_usbc_ana_en2_active { + mux { + pins = "gpio32"; + function = "gpio"; + }; + config { + pins = "gpio32"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + + sde_dsi_active: sde_dsi_active { + mux { + pins = "gpio11"; + function = "gpio"; + }; + + config { + pins = "gpio11"; + drive-strength = <8>; /* 8 mA */ + bias-disable = <0>; /* no pull */ + }; + }; + sde_dsi_suspend: sde_dsi_suspend { + mux { + pins = "gpio11"; + function = "gpio"; + }; + + config { + pins = "gpio11"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + }; +}; + + +//camera voltage start +&cam_sensor_mclk0_active { + /* MCLK0 */ + mux { + pins = "gpio13"; + function = "cam_mclk"; + }; + + config { + pins = "gpio13"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk0_suspend { + /* MCLK0 */ + mux { + pins = "gpio13"; + function = "cam_mclk"; + }; + + config { + pins = "gpio13"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk1_active { + /* MCLK1 */ + mux { + pins = "gpio14"; + function = "cam_mclk"; + }; + + config { + pins = "gpio14"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk1_suspend { + /* MCLK1 */ + mux { + pins = "gpio14"; + function = "cam_mclk"; + }; + + config { + pins = "gpio14"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk2_active { + /* MCLK2 */ + mux { + pins = "gpio15"; + function = "cam_mclk"; + }; + + config { + pins = "gpio15"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk2_suspend { + /* MCLK2 */ + mux { + pins = "gpio15"; + function = "cam_mclk"; + }; + + config { + pins = "gpio15"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk3_active { + /* MCLK3 */ + mux { + pins = "gpio16"; + function = "cam_mclk"; + }; + + config { + pins = "gpio16"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk3_suspend { + /* MCLK3 */ + mux { + pins = "gpio16"; + function = "cam_mclk"; + }; + + config { + pins = "gpio16"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_active_rear { + /* RESET REAR2 */ + mux { + pins = "gpio30", "gpio59"; + function = "gpio"; + }; + + config { + pins = "gpio30", "gpio59"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_rear { + /* RESET REAR2 */ + mux { + pins = "gpio30", "gpio59"; + function = "gpio"; + }; + + config { + pins = "gpio30", "gpio59"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +&cam_sensor_active_rear_aux { + /* RESET REARAUX, VANA REARAUX */ + mux { + pins = "gpio23", "gpio29"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio29"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_rear_aux { + /* RESET REARAUX, VANA REARAUX */ + mux { + pins = "gpio23", "gpio29"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio29"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +&cam_sensor_active_front { + /* RESET FRONT, VANA FRONT*/ + mux { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio54","gpio118"; + function = "gpio"; + }; + + config { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio54","gpio118"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_front { + /* RESET FRONT, VANA FRONT*/ + mux { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio54","gpio118"; + function = "gpio"; + }; + + config { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio54","gpio118"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +&cam_sensor_active_iris { + /* RESET ULTRA, VANA VDIG ULTRA*/ + mux { + pins = "gpio28","gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio28","gpio94"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_iris { + /* RESET ULTRA, VANA VDIG ULTRA*/ + mux { + pins = "gpio28","gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio28","gpio94"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +//camera voltage end diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-sm8150-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-sm8150-camera-sensor-mtp.dtsi new file mode 100644 index 000000000000..fc4332cb1d7a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-sm8150-camera-sensor-mtp.dtsi @@ -0,0 +1,537 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +&soc { + led_flash_rear: qcom,camera-flash@0 { + cell-index = <0>; + reg = <0x00 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch2>; + status = "ok"; + }; + + led_flash_rear_aux1: qcom,camera-flash@1 { + cell-index = <1>; + reg = <0x01 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch2>; + status = "ok"; + }; + + led_flash_front: qcom,camera-flash@2 { + cell-index = <2>; + reg = <0x02 0x00>; + compatible = "qcom,camera-flash"; + wled-flash-support; + flash-source = <&wled_flash>; + torch-source = <&wled_torch>; + switch-source = <&wled_switch>; + status = "ok"; + }; + + led_flash_rear_aux2: qcom,camera-flash@3 { + cell-index = <3>; + reg = <0x03 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch2>; + status = "ok"; + }; + + camera_viodd_ldo: gpio-regulator@0 { + compatible = "regulator-fixed"; + reg = <0x00 0x00>; + regulator-name = "camera_viodd_ldo"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&tlmm 132 0>; + vin-supply = <&pm8150_s4>; + }; + + actuator_rear_regulator: gpio-regulator@1 { + compatible = "regulator-fixed"; + reg = <0x01 0x00>; + regulator-name = "actuator_rear_regulator"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&tlmm 24 0>; + vin-supply = <&pm8150l_bob>; + }; + + actuator_rear_aux_ldo: gpio-regulator@2 { + compatible = "regulator-fixed"; + reg = <0x02 0x00>; + regulator-name = "actuator_rear_aux_ldo"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&tlmm 152 0>; + vin-supply = <&pm8150l_bob>; + }; + + actuator_ultra_ldo: gpio-regulator@3 { + compatible = "regulator-fixed"; + reg = <0x03 0x00>; + regulator-name = "actuator_ultra_ldo"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&tlmm 95 0>; + vin-supply = <&pm8150l_bob>; + }; +}; + +&cam_cci1 { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + status = "ok"; + }; + + actuator_rear: qcom,actuator@0 { + cell-index = <0>; + reg = <0x0>; + compatible = "qcom,actuator"; + cci-device = <0>; + cci-master = <1>; + cam_vaf-supply = <&actuator_rear_regulator>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + actuator_rear_aux: qcom,actuator@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,actuator"; + cci-device = <1>; + cci-master = <1>; + cam_vaf-supply = <&actuator_rear_aux_ldo>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + actuator_front: qcom,actuator@2 { + cell-index = <2>; + reg = <0x2>; + compatible = "qcom,actuator"; + cci-master = <1>; + cam_vaf-supply = <&actuator_rear_aux_ldo>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + actuator_ultra_rear: qcom,actuator@3 { + cell-index = <3>; + reg = <0x3>; + compatible = "qcom,actuator"; + cci-master = <0>; + cam_vaf-supply = <&actuator_ultra_ldo>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + eeprom_rear: qcom,eeprom@0 { + cell-index = <0>; + reg = <0>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150_s5>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 1904000 2856000 0>; + rgltr-max-voltage = <1800000 2040000 3008000 0>; + rgltr-load-current = <180000 112000 519000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rear>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rear>; + gpios = <&tlmm 14 0>, + <&tlmm 30 0>, + <&tlmm 59 0>; + gpio-reset = <1>; + gpio-vdig = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VDIG0"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + eeprom_rear_aux: qcom,eeprom@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150_s5>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 1904000 2856000 0>; + rgltr-max-voltage = <1800000 2040000 3008000 0>; + rgltr-load-current = <180000 112000 519000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rear>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rear>; + gpios = <&tlmm 14 0>, + <&tlmm 30 0>, + <&tlmm 59 0>; + gpio-reset = <1>; + gpio-vdig = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VDIG0"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + eeprom_rear_ultra: qcom,eeprom@3 { + cell-index = <3>; + reg = <0x3>; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0xa0>; + qcom,num-blocks = <1>; + qcom,page0 = <0 0 0 0 0 0 >; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,mem0 = <8192 0x0 2 0 1 0>; + qcom,cam-power-seq-type = "cam_vio"; + qcom,cam-power-seq-val = <1>; + qcom,cam-power-seq-cfg-val = <1>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 3008000 2856000 0>; + rgltr-max-voltage = <1800000 4000000 3000000 0>; + rgltr-load-current = <180000 2000000 300000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active &cam_sensor_active_iris>; + pinctrl-1 = <&cam_sensor_mclk0_suspend &cam_sensor_suspend_iris>; + gpios = <&tlmm 13 0>,//mclk + <&tlmm 28 0>,//reset + <&tlmm 94 0>;//vana,vdig + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK3", + "CAM_RESET3", + "CAM_VDIG3"; + sensor-position = <0>; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + eeprom_front: qcom,eeprom@2 { + cell-index = <2>; + reg = <0x2>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk";//, "cam_bob"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 3008000 3000000 0>; + rgltr-max-voltage = <1800000 4000000 3000000 0>; + rgltr-load-current = <180000 2000000 30000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_front>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_front>; + gpios = <&tlmm 15 0>,//mclk + <&tlmm 54 0>,//reset + //<&tlmm 132 0>,//vio + <&tlmm 118 0>;//vana,vidg + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2"; + sensor-position = <1>; + sensor-mode = <0>; + cci-device = <1>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + qcom,cam-sensor@0 { + cell-index = <0>; + compatible = "qcom,cam-sensor"; + reg = <0x0>; + csiphy-sd-index = <1>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + led-flash-src = <&led_flash_rear>; + actuator-src = <&actuator_rear>; + eeprom-src = <&eeprom_rear>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150_s5>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 1904000 2856000 0>; + rgltr-max-voltage = <1800000 2040000 3008000 0>; + rgltr-load-current = <180000 112000 519000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rear>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rear>; + gpios = <&tlmm 14 0>, + <&tlmm 30 0>, + <&tlmm 59 0>; + gpio-reset = <1>; + gpio-vdig = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VDIG0"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + + qcom,cam-sensor@1 { + cell-index = <1>; + compatible = "qcom,cam-sensor"; + reg = <0x1>; + csiphy-sd-index = <3>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + actuator-src = <&actuator_rear_aux>; + led-flash-src = <&led_flash_rear_aux1>; + eeprom-src = <&eeprom_rear_aux>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vdig-supply = <&pm8150_l17>; + cam_vana-supply = <&pm8150l_bob>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk";//, "cam_bob"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 3008000 3000000 0>; + rgltr-max-voltage = <1800000 4000000 3000000 0>; + rgltr-load-current = <180000 2000000 300000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_rear_aux>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_rear_aux>; + gpios = <&tlmm 16 0>,//mclk + <&tlmm 23 0>,//reset + <&tlmm 29 0>;//vana,vdig + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_VANA1"; + sensor-mode = <0>; + cci-device = <1>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + + qcom,cam-sensor@2 { + cell-index = <2>; + compatible = "qcom,cam-sensor"; + reg = <0x02>; + csiphy-sd-index = <2>; + sensor-position-roll = <270>; + sensor-position-pitch = <0>; + sensor-position-yaw = <0>; + eeprom-src = <&eeprom_front>; + actuator-src = <&actuator_front>; + //led-flash-src = <&led_flash_front>; + cam_vio-supply = <&camera_viodd_ldo>; + //cam_bob-supply = <&pm8150l_bob>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk";//, "cam_bob"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 3008000 3000000 0>; + rgltr-max-voltage = <1800000 4000000 3000000 0>; + rgltr-load-current = <180000 2000000 30000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_front>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_front>; + gpios = <&tlmm 15 0>,//mclk + <&tlmm 54 0>,//reset + //<&tlmm 132 0>,//vio + <&tlmm 118 0>;//vana,vidg + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_VANA2"; + sensor-mode = <0>; + cci-device = <1>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + +qcom,cam-sensor@3 { + cell-index = <3>; + compatible = "qcom,cam-sensor"; + reg = <0x03>; + csiphy-sd-index = <0>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + actuator-src = <&actuator_ultra_rear>; + eeprom-src = <&eeprom_rear_ultra>; + led-flash-src = <&led_flash_rear_aux2>; + cam_vio-supply = <&camera_viodd_ldo>; + //cam_bob-supply = <&pm8150l_bob>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150_l17>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk";//, "cam_bob"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 3008000 2856000 0>; + rgltr-max-voltage = <1800000 4000000 3000000 0>; + rgltr-load-current = <180000 2000000 300000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_iris>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_iris>; + gpios = <&tlmm 13 0>,//mclk + <&tlmm 28 0>,//reset + <&tlmm 94 0>;//vana,vdig + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK3", + "CAM_RESET3", + "CAM_VDIG3"; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + +}; + +&cam_cci1 { + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cci3_active>; + pinctrl-1 = <&cci3_suspend>; + gpios = <&tlmm 33 0>, + <&tlmm 34 0>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 1>; + gpio-req-tbl-label = "CCI_I2C_DATA3", + "CCI_I2C_CLK3"; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-sm8150.dtsi new file mode 100644 index 000000000000..13907b71874d --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-sm8150.dtsi @@ -0,0 +1,1004 @@ +/* +this file is for attribution only of andromeda +And public attribution of xiaomi platforms(like F1X and so and) +*/ + +#include "crux-pinctrl.dtsi" +#include "../common/xiaomi-sdx50-sm8150-common.dtsi" + +#include "crux-sm8150-camera-sensor-mtp.dtsi" + +&soc { + touch_vddio_vreg: touch_vddio_vreg { + compatible = "regulator-fixed"; + regulator-name = "disp_vddio_vreg"; + startup-delay-us = <4000>; + enable-active-high; + regulator-boot-on; + gpio = <&tlmm 31 0>; + }; + vdd_boost_vreg: vdd_boost_vreg { + compatible = "regulator-fixed"; + regulator-name = "vdd_boost_vreg"; + startup-delay-us = <4000>; + enable-active-high; + regulator-always-on; + gpio = <&pm8150b_gpios 5 0>; + }; + disp_vci_vreg: disp_vci_vreg { + compatible = "regulator-fixed"; + regulator-name = "disp_vci_vreg"; + start-delay-us = <4000>; + enable-active-high; + regulator-boot-on; + gpio = <&tlmm 7 0>; + }; + + fingerprint_goodix { + compatible = "goodix,fingerprint"; + goodix,gpio-reset = <&tlmm 37 0x0>; + goodix,gpio-irq = <&tlmm 120 0x0>; + /* fp-gpio-pwr = <&tlmm 125 0>; */ + status = "ok"; + }; + fp_vdd_vreg: fp_vdd_vreg { + compatible = "regulator-fixed"; + regulator-name = "fp_vdd_vreg"; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&tlmm 125 0>; + regulator-always-on; + }; + fingerprint_fpc { + status = "ok"; + compatible = "fpc,fpc1020"; + interrupt-parent = <&tlmm>; + interrupts = <118 0x0>; + fpc,gpio_irq = <&tlmm 118 0x0>; + /* fpc,enable-on-boot; */ + /* fpc,enable-wakeup; */ + + pinctrl-names = "fpc1020_reset_reset", + "fpc1020_reset_active"; + + pinctrl-0 = <&msm_gpio_119>; + pinctrl-1 = <&msm_gpio_119_output_high>; + }; + pcie0: qcom,pcie@1c00000 { + status = "disabled"; + }; + + disp_vci_vreg_f1x: disp_vci_vreg_f1x { + compatible = "regulator-fixed"; + regulator-name = "disp_vci_vreg"; + start-delay-us = <4000>; + enable-active-high; + regulator-boot-on; + gpio = <&tlmm 21 0>; + }; + xiaomi_touch { + compatible = "xiaomi-touch"; + status = "ok"; + touch,name = "xiaomi-touch"; + }; + thermal_message: thermal-message { + board-sensor = "VIRTUAL-SENSOR"; + }; +}; + +&sde_dsi { + vcie-supply = <&disp_vci_vreg_f1x>; +}; + +&pm8150l_lpg { + qcom,lut-patterns = <0 1 2 3 4 5 7 9 11 13 15 + 13 11 9 7 5 4 3 2 1 0>; +}; + +&pwm_lpg1 { + qcom,lpg-chan-id = <1>; + qcom,ramp-step-ms = <100>; + qcom,ramp-pause-hi-count = <2>; + qcom,ramp-pause-lo-count = <2>; + qcom,ramp-low-index = <0>; + qcom,ramp-high-index = <20>; + qcom,ramp-from-low-to-high; + qcom,ramp-pattern-repeat; +}; + +&red_led { + label = "white"; +}; + +&green_led { + status = "disabled"; +}; + +&blue_led { + status = "disabled"; +}; + +&qcom_qbt1000 { + status = "disabled"; +}; + +&qcom_seecom { + reg = <0x87900000 0x3E00000>; +}; + +&qcom_smcinvoke { + reg = <0x87900000 0x3E00000>; +}; + +&qupv3_se4_i2c { + status = "ok"; + + fsa4480@43 { + status = "disabled"; + }; +}; + +&qupv3_se8_i2c { + status = "ok"; + /*smart PA*/ + tas2557@4c{ + compatible = "ti,tas2557"; + reg = <0x4c>; + //ti,cdc-reset-gpio = <&tlmm 59 0>; + ti,irq-gpio = <&tlmm 115 0>; + ti,i2s-bits = <16>; + ti,bypass-tmax = <0>; + }; +}; + +&qupv3_se17_i2c { + status = "ok"; + fts@49 { + compatible = "st,fts"; + reg = <0x49>; + interrupt-parent = <&tlmm>; + interrupts = <122 0x2008>; + pinctrl-names = "pmx_ts_active", "pmx_ts_suspend"; + pinctrl-0 = <&ts_active>; + pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; + avdd-supply = <&pm8150l_l1>; + vdd-supply = <&touch_vddio_vreg>; + fts,pwr-reg-name = "avdd"; + fts,bus-reg-name = "vdd"; + fts,irq-gpio = <&tlmm 122 0x2008>; + fts,irq-gpio-name = "fts_irq"; + fts,reset-gpio-enable; + fts,reset-gpio = <&tlmm 12 0x00>; + fts,reset-gpio-name = "fts_rst"; + fts,irq-flags = <0x2008>; /* IRQF_ONESHOT | IRQF_TRIGGER_LOW */ + fts,x-max = <1080>; + fts,y-max = <2340>; + fts,default-fw-name = "st_fts_f1x.ftb"; + fts,config-array-size = <1>; + fts,dump-click-count; + fts,touch-up-threshold-min = <40>; + fts,touch-up-threshold-max = <120>; + fts,touch-up-threshold-def = <80>; + fts,touch-tolerance-min = <5>; + fts,touch-tolerance-max = <35>; + fts,touch-tolerance-def = <25>; + fts,edgefilter-leftrigt-def = <45>; + fts,edgefilter-topbottom-def = <0>; + fts,edgefilter-top-ingamemode = <65>; + fts,edgefilter-bottom-ingamemode = <0>; + fts,edgefilter-area-step1 = <100>; + fts,edgefilter-area-step2 = <150>; + fts,edgefilter-area-step3 = <250>; + fts,touch-idletime-min = <0>; + fts,touch-idletime-max = <12750>; + fts,touch-idletime-def = <12450>; + fts,cfg_0 { + fts,tp-vendor = <0x48>; + fts,fw-name = "st_fts_f1x.ftb"; + fts,limit-name = "stm_fts_production_limits.csv"; + fts,clicknum-file-name = "fts+sdc"; + }; + }; + goodix@5d { + compatible = "goodix,gt9885"; + reg = <0x5d>; + status = "ok"; + interrupt-parent = <&tlmm>; + interrupts = <122 0x2800>; + vtouch-source-supply = <&vdd_boost_vreg>; + vtouch-supply = <&touch_vddio_vreg>; + iotouch-supply = <&pm8150l_l1>; + vtouch-load = <600000>; + pinctrl-names = "pmx_ts_active","pmx_ts_suspend"; + pinctrl-0 = <&ts_active>; + pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; + goodix,reset-gpio = <&tlmm 12 0x0>; + goodix,irq-gpio = <&tlmm 122 0x2800>; + goodix,irq-flags = <2>; /* 1:trigger rising, 2:trigger falling;*/ + goodix,panel-max-id = <10>; + goodix,panel-max-x = <1079>; + goodix,panel-max-y = <2339>; + goodix,panel-max-w = <127>; + goodix,panel-max-p = <127>; + goodix,panel-max-fod = <127>; + /* goodix,panel-key-map = <158 172 217>; */ /*KEY_BACK, KEY_HOMEPAGE, KEY_SEARCH*/ + goodix,power-on-delay-us = <300000>; /*300ms*/ + goodix,power-off-delay-us = <5000>; + goodix,cfg-name = "goodix_gt9885_cfg_f1u.bin"; + /* goodix,swap-axis; */ + /* goodix,pen-enable; */ + /* goodix,key-of-pen = <331 332>; */ /*BTN_STYLUS, BTN_STYLUS2*/ + sensor1 { + normal-cfg = [ + ]; + goodix,fw-name = "goodix_gt9885_fw_f1u.bin"; + }; + }; +}; + +&pm8150b_fg { + qcom,battery-data = <&mtp_batterydata>; + qcom,rapid-soc-dec-en; + qcom,fg-sys-term-current = <(-300)>; + qcom,fg-cutoff-voltage = <3400>; + qcom,fg-cutoff-current = <200>; + qcom,fg-empty-voltage = <3100>; + qcom,fg-batt-temp-delta = <6>; + qcom,fg-force-load-profile; + /* ESR fast calibration */ + qcom,fg-esr-timer-chg-fast = <0 7>; + qcom,fg-esr-timer-dischg-fast = <0 7>; + qcom,fg-esr-timer-chg-slow = <0 96>; + qcom,fg-esr-timer-dischg-slow = <0 96>; + qcom,fg-esr-cal-soc-thresh = <26 230>; + qcom,fg-esr-cal-temp-thresh = <10 40>; +}; + +&vendor { + mtp_batterydata: qcom,battery-data { + qcom,batt-id-range-pct = <15>; + #include "../common/battery/batterydata-F1-atl-3300mah.dtsi" + #include "../common/battery/batterydata-F1-coslight-3300mah.dtsi" + #include "../common/battery/fg-gen4-batterydata-alium-3600mah.dtsi" + }; +}; + +&pm8150_gpios { + vbus_disable { + vbus_disable_default: vbus_disable_default { + pins = "gpio10"; + function = "normal"; + output-low; + power-source = <1>; /* 1.8V input supply */ + }; + }; +}; + +&pm8150b_charger { + qcom,cp-mode = <2>; + qcom,sec-charger-config = <1>; + qcom,usb-icl-ua = <4000000>; + qcom,fcc-max-ua = <8000000>; + qcom,fv-max-uv = <4480000>; + qcom,dc-icl-ua = <500000>; + qcom,auto-recharge-vbat-mv = <4380>; + qcom,step-charging-enable; + qcom,sw-jeita-enable; + qcom,chg-term-src = <1>; + qcom,chg-term-current-ma = <(-220)>; + qcom,chg-term-base-current-ma = <50>; + qcom,thermal-mitigation = <3000000 2800000 2600000 2400000 2200000 2100000 2000000 + 1800000 1600000 1500000 1400000 1200000 1000000 900000 + 800000 500000>; + qcom,thermal-mitigation-icl + = <2800000 2700000 2600000 2400000 2400000 2400000 2400000 + 2400000 2400000 2100000 1900000 1700000 1500000 1300000 + 1000000 750000>; + qcom,thermal-mitigation-dcp + = <1800000 1800000 1800000 1800000 1800000 1800000 1800000 + 1800000 1800000 1700000 1600000 1400000 1200000 1100000 + 1100000 1000000>; + qcom,thermal-mitigation-qc2 + = <1500000 1500000 1500000 1500000 1450000 1400000 1350000 + 1300000 1300000 1200000 1000000 900000 850000 750000 + 650000 500000>; + qcom,thermal-fcc-qc3-normal + = <3200000 3000000 2800000 2600000 2500000 2400000 2300000 + 2200000 2100000 1800000 1600000 1400000 1200000 1000000 + 750000 750000>; + qcom,thermal-fcc-qc3-cp + = <3600000 3600000 3600000 3600000 3200000 3200000 3200000 + 3200000 3100000 2800000 2400000 2200000 2000000 1300000 + 750000 700000>; + qcom,thermal-fcc-qc3-classb-cp + = <4800000 4700000 4600000 4500000 4400000 4200000 4200000 + 4200000 4000000 3600000 3400000 3200000 3000000 2200000 + 1000000 700000>; + qcom,thermal-mitigation-pd-base + = <4000000 3600000 3200000 2800000 2800000 2800000 2800000 + 2800000 2800000 2400000 2400000 2000000 1600000 1300000 + 1000000 500000>; + qcom,thermal-fcc-pps-cp + = <8000000 7500000 7000000 6500000 6000000 5500000 5350000 + 4500000 4000000 3500000 3000000 3000000 3000000 2000000 + 1500000 100000>; + qcom,thermal-mitigation-dc + = <3100000 2200000 1800000 1600000 1400000 1200000 1100000 + 1000000 900000 800000 700000 600000 500000 400000 + 300000 200000>; + qcom,thermal-mitigation-epp + = <1200000 1200000 1200000 1100000 1100000 1000000 1000000 + 1000000 900000 700000 700000 600000 500000 400000 + 300000 200000>; + qcom,thermal-mitigation-bpp-qc3 + = <1400000 1300000 1200000 1200000 1100000 1000000 900000 + 800000 700000 700000 700000 600000 500000 400000 + 300000 200000>; + qcom,thermal-mitigation-bpp-qc2 + = <1100000 1100000 1100000 1100000 1100000 1000000 1000000 + 1000000 700000 700000 700000 600000 500000 400000 + 300000 200000>; + qcom,thermal-mitigation-bpp + = <700000 700000 700000 700000 700000 700000 700000 + 700000 700000 600000 600000 500000 400000 300000 + 200000 200000>; + qcom,thermal-mitigation-dc-20w + = <2200000 1400000 1300000 1200000 700000 600000 500000 + 400000 400000 400000 400000 400000 400000 400000 + 400000 400000>; + + io-channels = <&pm8150b_vadc ADC_MID_CHG_DIV6>, + <&pm8150b_vadc ADC_USB_IN_V_16>, + <&pm8150b_vadc ADC_USB_IN_I>, + <&pm8150b_vadc ADC_SBUx>, + <&pm8150b_vadc ADC_VPH_PWR>, + <&pm8150b_vadc ADC_CHG_TEMP>, + <&pm8150b_vadc ADC_AMUX_THM3_PU2>; + + io-channel-names = "mid_voltage", + "usb_in_voltage", + "usb_in_current", + "sbux_res", + "vph_voltage", + "chg_temp", + "conn_therm"; + + qcom,battery-data = <&mtp_batterydata>; + dpdm-supply = <&usb2_phy0>; + qcom,distinguish-qc-class-ab; + qcom,wd-bark-time-secs = <16>; + qcom,support-wireless; + qcom,support-conn-therm; + qcom,support-ext-fg; + + vbus-disable-gpio = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>; + + pinctrl-names = "default"; + pinctrl-0 = <&vbus_disable_default>; +}; + +&smb1390 { + pinctrl-names = "default"; + pinctrl-0 = <&smb_stat_default>; + status = "ok"; +}; + +&smb1390_charger { + io-channels = <&pm8150b_vadc ADC_AMUX_THM2>; + io-channel-names = "smb1390_therm"; + qcom,parallel-output-mode = <2>; + status = "ok"; +}; + +&smb1390_slave { + status = "ok"; +}; + +&smb1390_slave_charger { + status = "ok"; +}; + + + +&ext_5v_boost { + status = "ok"; +}; + +&pm8150b_pdphy { + vbus-supply = <&ext_5v_boost>; + mi,pd_curr_limit = <1>; + mi,pd_max_curr_limit = <4000000>; +}; + +&usb0 { + dwc3@a600000 { + usb-phy = <&usb2_phy0>, <&usb_nop_phy>; + maximum-speed = "high-speed"; + }; +}; + +&usb2_phy0 { + qcom,param-override-seq = + <0x33 0x70 + 0x2c 0x74>; +}; + +&usb_qmp_dp_phy { + status = "disabled"; +}; + +&usb1 { + extcon = <&extcon_usb1>; + status = "disabled"; +}; + +&usb2_phy1 { + status = "disabled"; +}; + +&usb_qmp_phy { + status = "disabled"; +}; + +&pm8150b_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + wp_therm { + reg = ; + label = "wp_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + vcoin { + reg = ; + label = "vcoin"; + qcom,pre-scaling = <1 3>; + }; + + conn_therm { + reg = ; + label = "conn_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + chg_sbux { + reg = ; + label = "chg_sbux"; + qcom,pre-scaling = <1 3>; + }; + + mid_chg_div6 { + reg = ; + label = "chg_mid"; + qcom,pre-scaling = <1 6>; + }; + + usb_in_i_uv { + reg = ; + label = "usb_in_i_uv"; + qcom,pre-scaling = <1 1>; + }; + + usb_in_v_div_16 { + reg = ; + label = "usb_in_v_div_16"; + qcom,pre-scaling = <1 16>; + }; +}; + +&pm8150_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + vcoin { + reg = ; + label = "vcoin"; + qcom,pre-scaling = <1 3>; + }; + + xo_therm { + reg = ; + label = "xo_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + quiet_therm { + reg = ; + label = "quiet_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + pa_therm0 { + reg = ; + label = "pa_therm0"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm8150l_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + cam_therm0 { + reg = ; + label = "cam_therm0"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + cam_therm1 { + reg = ; + label = "cam_therm1"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + pa_therm1 { + reg = ; + label = "pa_therm1"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm8150b_adc_tm { + wp_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm8150_adc_tm { + xo_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + quiet_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + pa_therm0 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm8150l_adc_tm { + cam_therm0 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + cam_therm1 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + pa_therm1 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&thermal_zones { + wp_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150b_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + xo_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_XO_THERM_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + quiet_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + pa_therm0 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_AMUX_THM2_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + cam_therm0 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + cam_therm1 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM2_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + pa_therm1 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM3_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; +}; + +&qupv3_se4_i2c { + status = "ok"; + bq27z561@55 { + compatible = "ti,bq27z561"; + reg = <0x55>; + bq,charge-full-design = <4000000>; + bq,recharge-voltage = <4380>; + bq,soc_decimal_rate = < + 0 38 + 10 35 + 20 33 + 30 33 + 40 33 + 50 33 + 60 33 + 70 30 + 80 25 + 90 20 + 95 10 + 99 5 >; + bq,cold_thermal_seq = < + 1 0 100 1700 + 2 (-300) 0 1000 >; + }; + + fsa4480@43 { + status = "disabled"; + }; + + cs35l41@40 { + #sound-dai-cells = <1>; + compatible = "cirrus,cs35l41"; + cs,cdc-reset-gpio = <&tlmm 89 0x01>; + reg = <0x40>; + pinctrl-names = "cs35l41_irq_default"; + pinctrl-0 = <&cs35l41_int_default>; + interrupt-parent = <&tlmm>; + interrupts = <10 8>; + + cirrus,temp-warn_threshold = <3>; + cirrus,boost-peak-milliamp = <4000>; + cirrus,boost-ind-nanohenry = <1000>; + cirrus,boost-cap-microfarad = <15>; + cirrus,gpio-config2 { + cirrus,gpio-src-select = <0x4>; + cirrus,gpio-output-enable; + }; + /* + VA-supply = <&dummy_vreg>; + VP-supply = <&dummy_vreg>; + interrupt-parent = <&tlmm>; + interrupts = <11 8>; + reset-gpios = <&tlmm 7 0x01>; + VA-supply = <&pm8998_s4>; + VP-supply = <&audio_vsys>; + cirrus,boost-peak-milliamp = <4500>; + cirrus,boost-ind-nanohenry = <1000>; + cirrus,boost-cap-microfarad = <15>; + cirrus,gpio-config2 { + cirrus,gpio-src-select = <0x4>; + cirrus,gpio-output-enable; + }; + */ + }; +}; + +&dsi_samsung_fhd_ea8076_f1s_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_external_supply>; + /* IRQF_ONESHOT | IRQF_TRIGGER_FALLING */ + qcom,esd-err-irq-gpio = <&tlmm 101 0x2002>; +}; + +//&dsi_visionox_fhd_rm692a9_f1u_cmd { +// qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_external_supply>; + /* IRQF_ONESHOT | IRQF_TRIGGER_FALLING */ +// qcom,esd-err-irq-gpio = <&tlmm 101 0x2002>; +//}; + +&qupv3_se1_spi { + status = "ok"; + irled@0 { + compatible = "ir-spi"; + reg = <0x0>; + status = "ok"; + spi-max-frequency = <19200000>; + }; +}; + +&qupv3_se7_i2c { + status = "ok"; + aw8697_haptic@5A { + compatible = "awinic,aw8697_haptic"; + reg = <0x5A>; + reset-gpio = <&tlmm 6 0>; + irq-gpio = <&tlmm 27 0>; + vib_mode = < 0 >; /*mode: RAM mode->0; CONT mode -> 1*/ + vib_f0_pre = < 1700 >; + vib_f0_cali_percen = < 7 >; + vib_cont_drv_lev = < 88 >; + vib_cont_drv_lvl_ov = < 88 >; + vib_cont_td = < 0xf06c >; + vib_cont_zc_thr = < 0x08f8 >; /*hq 0x08F8 */ + vib_cont_num_brk = < 3 >; + vib_f0_coeff = < 260 >; /*Don't modify it 2.604167*/ + vib_f0_trace_parameter = < 9 3 1 31 >; + vib_bemf_config = < 0 0x08 0x03 0xf8 >; + vib_sw_brake = < 0x2c >; + vib_tset = < 0x12 >; + vib_r_spare = < 0x68 >; + vib_bstdbg = < 0x30 0xeb 0xd4 0 0 0 >; + vib_effect_id_boundary = < 10 >; + vib_effect_max = < 170 >; + vib_trig_config = < 0 1 0 1 2 + 0 1 0 1 2 + 0 1 0 1 2 >; + vib_bst_vol_default = < 0x1b >; + vib_bst_vol_ram = < 0x1b >; + vib_bst_vol_rtp = < 0x16 >; + vib_rtp_time = < 20 20 20 20 20 20 20 20 20000 15000 + 15000 20000 25000 15000 30000 25000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 20000 20000 20000 20000 20000 + 20000 20000 20000 20000 20000 >; + pinctrl-names = "aw8697_reset_reset","aw8697_reset_active","aw8697_interrupt_active"; + pinctrl-0 = <&msm_gpio_6>; + pinctrl-1 = <&msm_gpio_6_output_high>; + pinctrl-2 = <&msm_gpio_27>; + status = "ok"; + wf_0 { + /*CLICK*/ + qcom,effect-id = <0>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <20000>; + }; + wf_1 { + /*DOUBLE CLICK*/ + qcom,effect-id = <1>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 3e]; + qcom,wf-brake-pattern = [03 01 00 00]; + qcom,wf-play-rate-us = <20000>; + }; + wf_2 { + /*TICK*/ + qcom,effect-id = <2>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <20000>; + }; + wf_3 { + /*THUD*/ + qcom,effect-id = <3>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <20000>; + }; + wf_4 { + /*POP*/ + qcom,effect-id = <4>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <28000>; + }; + wf_5 { + /*HEAVY CLICK*/ + qcom,effect-id = <5>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 7e 7e]; + qcom,wf-brake-pattern = [03 03 01 00]; + qcom,wf-play-rate-us = <20000>; + }; + wf_6 { + /*id 6*/ + qcom,effect-id = <6>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <20000>; + }; + wf_7 { + /*id 7*/ + qcom,effect-id = <7>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <20000>; + }; + wf_8 { + /*id 8*/ + qcom,effect-id = <8>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <20000>; + }; + wf_9 { + /*id 9*/ + qcom,effect-id = <9>; + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <20000>; + }; + }; + + rx1619@61 { + compatible = "nuvolta,wl_charger_rx1619"; + reg = <0x61>; + rx,irq_gpio = <&tlmm 90 0x00>; + rx,tx_on_gpio = <&tlmm 130 0x00>; + rx,wpc-det = <&pm8150b_gpios 7 GPIO_ACTIVE_HIGH>; + rx,enable = <&tlmm 7 0x00>; + pinctrl-names = "default","nu_active","nu_suspend"; + pinctrl-0 = <&power_good_default>; + pinctrl-1 = <&nu_int_active &txon_enable_active &nu_sleep_active>; + pinctrl-2 = <&nu_int_suspend &txon_enable_suspend &nu_sleep_suspend>; + }; + rx1619@67 { + compatible = "nuvolta,wl_rx1619_trim"; + reg = <0x67>; + }; + ln8282@55 { + compatible = "lionsemi,ln8282"; + reg = <0x55>; + ln,enable = <&tlmm 41 0x00>; + ln,irq = <&tlmm 92 0x00>; + pinctrl-names = "ln8282_active","ln8282_suspend"; + pinctrl-0 = <&ln8282_enable_active>; + pinctrl-1 = <&ln8282_enable_suspend>; + }; + idtp9220: idtp9220@3b { + compatible = "idt,p9220"; + reg = <0x3b>; + idt,irq = <&tlmm 90 0x00>; + idt,enable = <&tlmm 7 0x00>; + idt,reverse-enable = <&tlmm 130 0x00>; + idt,wpc-det = <&pm8150b_gpios 7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default", "idt_active", "idt_suspend"; + pinctrl-0 = <&power_good_default>; + pinctrl-1 = <&idt_int_active &idt_enable_active>; + pinctrl-2 = <&idt_int_suspend &idt_enable_suspend>; + }; + halo7221@1b { + compatible = "halo7221,halo7221_cp"; + reg = <0x1b>; + halo,enable = <&tlmm 41 0x00>; + pinctrl-names = "halo7221_active","halo7221_suspend"; + pinctrl-0 = <&halo7221_enable_active>; + pinctrl-1 = <&halo7221_enable_suspend>; + }; +}; + +&ssc_sensors { + qcom,firmware-name = "slpi_cr"; +}; + +&ufshc_mem { + vdd-hba-supply = <&ufs_phy_gdsc>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm8150_l10>; + vcc-voltage-level = <2504000 2950000>; + vcc-low-voltage-sup; + vccq-supply = <&pm8150_l9>; + vccq2-supply = <&pm8150_s4>; + vcc-max-microamp = <750000>; + vccq-max-microamp = <700000>; + vccq2-max-microamp = <750000>; + + qcom,vddp-ref-clk-supply = <&pm8150_l9>; + qcom,vddp-ref-clk-max-microamp = <100>; + + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-audio-overlay.dtsi new file mode 100644 index 000000000000..859a74896ba7 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-audio-overlay.dtsi @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include "../common/sm8150-audio-overlay.dtsi" + +&snd_934x { + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "MADINPUT", "MCLK", + "hifi amp", "LINEOUT1", + "hifi amp", "LINEOUT2", + "AMIC2", "MIC BIAS2", + "MIC BIAS2", "Headset Mic", + "AMIC1", "MIC BIAS3", + "MIC BIAS3", "ANCRight Headset Mic", + "AMIC3", "MIC BIAS4", + "MIC BIAS4", "Analog Mic5"; + + qcom,wsa-max-devs = <0>; + qcom,msm-mbhc-hphl-swh = <1>; + qcom,msm-mbhc-gnd-swh = <1>; + qcom,msm-mbhc-usbc-audio-supported = <1>; + qcom,msm-mbhc-hs-mic-max-threshold-mv = <2600>; + qcom,msm-mbhc-hs-mic-min-threshold-mv = <50>; + fsa4480-i2c-handle = <&fsa4480>; + pinctrl-names = "quat_mi2s_enable", "quat_mi2s_disable", + "quat_tdm_enable", "quat_tdm_disable"; + pinctrl-0 = <&quat_mi2s_active &quat_mi2s_sd0_active &quat_mi2s_sd1_active>; + pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_sd0_sleep &quat_mi2s_sd1_sleep>; + pinctrl-2 = <&quat_tdm_active &quat_tdm_dout_active &quat_tdm_din_active>; + pinctrl-3 = <&quat_tdm_sleep &quat_tdm_dout_sleep &quat_tdm_din_sleep>; +}; + +&wcd934x_cdc { + qcom,cdc-micbias1-mv = <1800>; + qcom,cdc-micbias2-mv = <2750>; + qcom,cdc-micbias3-mv = <1800>; + qcom,cdc-micbias4-mv = <1800>; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-pinctrl.dtsi new file mode 100644 index 000000000000..9b468dee741c --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-pinctrl.dtsi @@ -0,0 +1,904 @@ +/*for xiaomi pinctrl*/ +&tlmm { + /* display_panel_enp +5V */ + display_panel_enp_default: display_panel_enp_default { + mux { + pins = "gpio114"; + function = "gpio"; + }; + config { + pins = "gpio114"; + drive-strength = <8>; + bias-disable = <0>; + output-high; + }; + }; + + /* display_panel_enn -5V */ + display_panel_enn_default: display_panel_enn_default { + mux { + pins = "gpio115"; + function = "gpio"; + }; + config { + pins = "gpio115"; + drive-strength = <8>; + bias-disable = <0>; + output-high; + }; + }; + + qupv3_se18_spi_pins: qupv3_se18_spi_pins { + qupv3_se18_spi_active: qupv3_se18_spi_active { + mux { + pins = "gpio23", "gpio24", "gpio25"; + function = "qup18"; + }; + + config { + pins = "gpio23", "gpio24", "gpio25"; + drive-strength = <6>; + bias-disable; + }; + }; + + qupv3_se18_spi_sleep: qupv3_se18_spi_sleep { + mux { + pins = "gpio23", "gpio24", "gpio25"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio24", "gpio25"; + drive-strength = <6>; + bias-disable; + }; + }; + }; + + + bq2597x { + bq2597x_master_int_default: bq2597x_master_int_default { + /* active state */ + mux { + /* GPIO 36 is used for bq25970 master ic interrupt usage */ + pins = "gpio36"; + function = "gpio"; + }; + + config { + pins = "gpio36"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + bq2597x_master_int_suspend: bq2597x_master_int_suspend { + /* sleep state */ + mux { + /* GPIO 36 is used for bq25970 master ic interrupt usage */ + pins = "gpio36"; + function = "gpio"; + }; + + config { + pins = "gpio36"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + }; + + onewire_gpio_active: onewire_gpio_active { + mux { + pins = "gpio5"; + function = "gpio"; + }; + + config { + pins = "gpio5"; + drive-strength = <2>; + bias-pull-up; /* No PULL */ + }; + }; + + onewire_gpio_sleep: onewire_gpio_sleep { + mux { + pins = "gpio5"; + function = "gpio"; + }; + + config { + pins = "gpio5"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + onewire_gpio_slave_active: onewire_gpio_slave_active { + mux { + pins = "gpio10"; + function = "gpio"; + }; + + config { + pins = "gpio10"; + drive-strength = <2>; + bias-pull-up; /* No PULL */ + }; + }; + + onewire_gpio_slave_sleep: onewire_gpio_slave_sleep { + mux { + pins = "gpio10"; + function = "gpio"; + }; + + config { + pins = "gpio10"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pmx_ts_active { + ts_active: ts_active { + mux { + pins = "gpio122", "gpio12"; + function = "gpio"; + }; + config { + pins = "gpio122", "gpio12"; + drive-strength = <8>; + bias-pull-up; + }; + }; + }; + + pmx_ts_int_suspend { + ts_int_suspend: ts_int_suspend { + mux { + pins = "gpio122"; + function = "gpio"; + }; + config { + pins = "gpio122"; + drive-strength = <2>; + bias-pull-down; + input-enable; + }; + }; + }; + + pmx_ts_reset_suspend { + ts_reset_suspend: ts_reset_suspend { + mux { + pins = "gpio12"; + function = "gpio"; + }; + config { + pins = "gpio12"; + drive-strength = <2>; + bias-disable; + output-low; + }; + }; + }; + + adc2_switch_gpio_ctrl { + adc2_switch_gpio_idle: adc2_switch_idle { + mux { + pins = "gpio142"; + function = "gpio"; + }; + config { + pins = "gpio142"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + adc2_switch_gpio_active: adc2_switch_active { + mux { + pins = "gpio142"; + function = "gpio"; + }; + config { + pins = "gpio142"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + + hall { + hall_intr3_active: hall_intr3_active { + /* active state */ + mux { + pins = "gpio101"; + function = "gpio"; + }; + + config { + pins = "gpio101"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + hall_intr3_suspend: hall_intr3_suspend { + /* sleep state */ + mux { + pins = "gpio101"; + function = "gpio"; + }; + + config { + pins = "gpio101"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + hall_intr4_active: hall_intr4_active { + /* active state */ + mux { + pins = "gpio134"; + function = "gpio"; + }; + + config { + pins = "gpio134"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + hall_intr4_suspend: hall_intr4_suspend { + /* sleep state */ + mux { + pins = "gpio134"; + function = "gpio"; + }; + + config { + pins = "gpio134"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + }; + + idt { + idt_int_active: idt_int_active { + /* active state */ + mux { + pins = "gpio95"; + function = "gpio"; + }; + + config { + pins = "gpio95"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + idt_int_suspend: idt_int_suspend { + /* sleep state */ + mux { + pins = "gpio95"; + function = "gpio"; + }; + + config { + pins = "gpio95"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + txon_enable_active: txon_enable_active { + /* active state */ + mux { + pins = "gpio3"; + function = "gpio"; + }; + + config { + pins = "gpio3"; + drive-strength = <16>; + bias-disable; + bias-pull-down; + output-low; + }; + }; + + txon_enable_suspend: txon_enable_suspend { + /* sleep state */ + mux { + pins = "gpio3"; + function = "gpio"; + }; + + config { + pins = "gpio3"; + drive-strength = <16>; + bias-disable; + bias-pull-down; + output-low; + }; + }; + + power_good_active: power_good_active { + /* active state */ + mux { + pins = "gpio94"; + function = "gpio"; + }; + config { + pins = "gpio94"; + drive-strength = <2>; /* 2 MA */ + bias-pull-down; + input-enable; + }; + + }; + + power_good_suspend: power_good_suspend { + /* active state */ + mux { + pins = "gpio94"; + function = "gpio"; + }; + config { + pins = "gpio94"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + reverse_booset_enable_active: reverse_booset_enable__active { + /* active state */ + mux { + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <16>; + bias-pull-down; + output-low; + }; + }; + + reverse_booset_enable_suspend: reverse_booset_enable_suspend { + /* sleep state */ + mux { + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <16>; + bias-pull-down; + output-low; + }; + }; + }; + + sbu_uart_en_ctrl { + sbu_uart_en_idle: uart_audio_en_idle { + mux { + pins = "gpio25"; + function = "gpio"; + }; + config { + pins = "gpio25"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + sbu_uart_en_active: uart_audio_en_active { + mux { + pins = "gpio25"; + function = "gpio"; + }; + config { + pins = "gpio25"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + + + pcie1 { + pcie1_wake_default: pcie1_wake_default { + mux { + pins = "gpio114"; + function = "gpio"; + }; + + config { + pins = "gpio114"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + nfc { + nfc_int_active: nfc_int_active { + /* active state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_int_suspend: nfc_int_suspend { + /* sleep state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_active: nfc_enable_active { + /* active state */ + mux { + /* 41: NFC ENABLE 42:ESE Enable */ + pins = "gpio48", "gpio102"; + function = "gpio"; + }; + + config { + pins = "gpio48", "gpio102"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_suspend: nfc_enable_suspend { + /* sleep state */ + mux { + /* 41: NFC ENABLE 42:ESE Enable */ + pins = "gpio48", "gpio102"; + function = "gpio"; + }; + + config { + pins = "gpio48", "gpio102"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + + nfc_clk_req_active: nfc_clk_req_active { + /* active state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_clk_req_suspend: nfc_clk_req_suspend { + /* sleep state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + }; + cam_sensor_active_macro: cam_sensor_active_macro { + /* RESET macro */ + mux { + pins = "gpio27", "gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio27", "gpio94"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_macro: cam_sensor_suspend_macro { + /* RESET MACRO */ + mux { + pins = "gpio27", "gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio27", "gpio94"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + test_mode_ctrl_irq { + ant_sub_ctrl_irq: ant_sub_ctrl_irq { + mux { + pins = "gpio81"; + function = "gpio"; + }; + config { + pins = "gpio81"; + drive-strength = <2>; + bias-pull-up; + input-enable; + }; + }; + ant_top_ctrl_irq: ant_top_ctrl_irq { + mux { + pins = "gpio133"; + function = "gpio"; + }; + config { + pins = "gpio133"; + drive-strength = <2>; + bias-pull-up; + input-enable; + }; + }; + }; + + xiaomi_keyboard_mcu { + xiaomi_keyboard_suspend: xiaomi_keyboard_suspend { + mux { + pins = "gpio4"; + function = "gpio"; + }; + + config { + pins = "gpio4"; + drive-strength = <8>; + bias-pull-down; + }; + }; + + xiaomi_keyboard_active: xiaomi_keyboard_active { + mux { + pins = "gpio4"; + function = "gpio"; + }; + + config { + pins = "gpio4"; + drive-strength = <8>; + bias-pull-up; + }; + }; + }; + +}; + +//camera voltage start +&cam_sensor_mclk0_active { + /* MCLK0 */ + mux { + pins = "gpio13"; + function = "cam_mclk"; + }; + + config { + pins = "gpio13"; + bias-disable; /* No PULL */ + drive-strength = <6>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk0_suspend { + /* MCLK0 */ + mux { + pins = "gpio13"; + function = "cam_mclk"; + }; + + config { + pins = "gpio13"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <6>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk1_active { + /* MCLK1 */ + mux { + pins = "gpio14"; + function = "cam_mclk"; + }; + + config { + pins = "gpio14"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk1_suspend { + /* MCLK1 */ + mux { + pins = "gpio14"; + function = "cam_mclk"; + }; + + config { + pins = "gpio14"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk2_active { + /* MCLK2 */ + mux { + pins = "gpio15"; + function = "cam_mclk"; + }; + + config { + pins = "gpio15"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk2_suspend { + /* MCLK2 */ + mux { + pins = "gpio15"; + function = "cam_mclk"; + }; + + config { + pins = "gpio15"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk3_active { + /* MCLK3 */ + mux { + pins = "gpio16"; + function = "cam_mclk"; + }; + + config { + pins = "gpio16"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk3_suspend { + /* MCLK3 */ + mux { + pins = "gpio16"; + function = "cam_mclk"; + }; + + config { + pins = "gpio16"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_active_rear { + /* RESET REAR2 */ + mux { + pins = "gpio28", "gpio11"; + function = "gpio"; + }; + + config { + pins = "gpio28", "gpio11"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_rear { + /* RESET REAR2 */ + mux { + pins = "gpio28", "gpio11"; + function = "gpio"; + }; + + config { + pins = "gpio28", "gpio11"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +&cam_sensor_active_rear_aux { + /* RESET REARAUX, VANA REARAUX */ + mux { + pins = "gpio23", "gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio94"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_rear_aux { + /* RESET REARAUX, VANA REARAUX */ + mux { + pins = "gpio23", "gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio94"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +&cam_sensor_active_front { + /* RESET FRONT, VANA FRONT*/ + mux { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio30", "gpio31"; + function = "gpio"; + }; + + config { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio30", "gpio31"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_front { + /* RESET FRONT, VANA FRONT*/ + mux { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio30", "gpio31"; + function = "gpio"; + }; + + config { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio30", "gpio31"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +&cam_sensor_active_iris { + /* RESET ULTRA, VANA VDIG ULTRA*/ + mux { + pins = "gpio28","gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio28","gpio94"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_iris { + /* RESET ULTRA, VANA VDIG ULTRA*/ + mux { + pins = "gpio28","gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio28","gpio94"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; +&cam_sensor_active_macro { + /* RESET ULTRA, VANA VDIG ULTRA*/ + mux { + pins = "gpio27","gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio27","gpio94"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_macro { + /* RESET ULTRA, VANA VDIG ULTRA*/ + mux { + pins = "gpio27","gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio27","gpio94"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + + +//camera voltage end + + +&fsa_usbc_ana_en { + mux { + pins = "gpio84"; + function = "gpio"; + }; + + config { + pins = "gpio84"; + drive-strength = <2>; + bias-disable; + output-low; + }; +}; + + + diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150-camera-sensor-mtp.dtsi new file mode 100644 index 000000000000..a1f282917a65 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150-camera-sensor-mtp.dtsi @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ +&cam_cci1 { + status = "disable"; +}; + +&soc { + led_flash_rear: qcom,camera-flash@0 { + cell-index = <0>; + reg = <0x00 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0>; + torch-source = <&pm8150l_torch0>; + switch-source = <&pm8150l_switch0>; + status = "ok"; + }; + + actuator_rear_regulator: gpio-regulator@0 { + compatible = "regulator-fixed"; + reg = <0x00 0x00>; + regulator-name = "actuator_rear_regulator"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&tlmm 29 0>; + vin-supply = <&pm8150l_bob>; + }; + + camera_wide_vdig_ldo: gpio-regulator@1 { + compatible = "regulator-fixed"; + reg = <0x01 0x00>; + regulator-name = "camera_wide_vdig_ldo"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&pm8150l_gpios 3 0>; + vin-supply = <&pm8150_s4>; + }; + + camera_front_vdig_ldo: gpio-regulator@2 { + compatible = "regulator-fixed"; + reg = <0x02 0x00>; + regulator-name = "camera_front_vdig_ldo"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&tlmm 12 0>; + vin-supply = <&pm8150_s4>; + }; +}; + +&cam_cci0 { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + status = "ok"; + }; + + actuator_rear: qcom,actuator@0 { + cell-index = <0>; + reg = <0x0>; + compatible = "qcom,actuator"; + cci-device = <0>; + cci-master = <0>; + cam_vaf-supply = <&actuator_rear_regulator>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + eeprom_rear: qcom,eeprom@0 { + cell-index = <0>; + reg = <0>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pm8150l_l1>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio","cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <1000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_rear>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_rear>; + gpios = <&tlmm 13 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK0"; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + eeprom_front: qcom,eeprom@2 { + cell-index = <2>; + reg = <0x2>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pm8150l_l1>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio","cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <1000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_front>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_front>; + gpios = <&tlmm 14 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK2"; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + //ov13b10 + qcom,cam-sensor@0 { + cell-index = <0>; + compatible = "qcom,cam-sensor"; + reg = <0x0>; + csiphy-sd-index = <0>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + led-flash-src = <&led_flash_rear>; + actuator-src = <&actuator_rear>; + eeprom-src = <&eeprom_rear>; + cam_vio-supply = <&pm8150l_l1>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&camera_wide_vdig_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana","cam_vdig", "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 3008000 1200000 0>; + rgltr-max-voltage = <1800000 4000000 1200000 0>; + rgltr-load-current = <180000 2000000 100000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_rear>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_rear>; + gpios = <&tlmm 13 0>, + <&tlmm 28 0>, + <&tlmm 11 0>; + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VANA0"; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + //ov8856 + qcom,cam-sensor@2 { + cell-index = <2>; + compatible = "qcom,cam-sensor"; + reg = <0x2>; + csiphy-sd-index = <1>; + sensor-position-roll = <270>; + sensor-position-pitch = <0>; + sensor-position-yaw = <0>; + eeprom-src = <&eeprom_front>; + cam_vio-supply = <&pm8150l_l1>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&camera_wide_vdig_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 3008000 1200000 0>; + rgltr-max-voltage = <1800000 4000000 1200000 0>; + rgltr-load-current = <180000 2000000 100000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_front>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_front>; + gpios = <&tlmm 14 0>, + <&tlmm 30 0>, + <&tlmm 31 0>; + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_VANA2"; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; +}; + diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi new file mode 100644 index 000000000000..06be84bc688d --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi @@ -0,0 +1,1275 @@ +/* +this file is for attribution only of vayu +And public attribution of xiaomi platforms(like J20S and so and) +*/ +#include "nabu-pinctrl.dtsi" +#include "../common/xiaomi-sm8150-common.dtsi" +#include "nabu-sm8150-camera-sensor-mtp.dtsi" + +&ufshc_mem { + vcc-voltage-level = <2504000 2950000>; + vcc-low-voltage-sup; + qcom,vccq-parent-supply = <&pm8150l_s8>; + qcom,vccq-parent-max-microamp = <210000>; + vccq-supply = <&pm8150_l9>; + vccq-max-microamp = <700000>; + wb-support; +}; + +#include "../common/smb1390.dtsi" + + + +&pm8150b_fg { + qcom,battery-data = <&nabu_batterydata>; + qcom,rapid-soc-dec-en; + qcom,soc-scale-mode-en; + qcom,five-pin-battery; + qcom,soc-hi-res; + qcom,soc_decimal_rate = < + 0 38 + 10 35 + 20 33 + 30 33 + 40 33 + 50 33 + 60 33 + 70 30 + 80 25 + 90 20 + 95 10 >; + qcom,ki-coeff-low-chg = <315>; + qcom,ki-coeff-med-chg = <183>; + qcom,fg-sys-term-current = <(-500)>; + qcom,fg-ffc-sys-term-current = <(-1530)>; + qcom,fg-cutoff-voltage = <3400>; + qcom,fg-cutoff-current = <200>; + qcom,fg-empty-voltage = <3100>; + qcom,soc-scale-vbatt-mv = <3600>; + qcom,fg-batt-temp-delta = <6>; + qcom,fg-force-load-profile; + qcom,shutdown-delay-enable; + /* ESR fast calibration */ + qcom,fg-esr-timer-chg-fast = <0 7>; + qcom,fg-esr-timer-dischg-fast = <0 96>; + qcom,fg-esr-timer-chg-slow = <0 96>; + qcom,fg-esr-timer-dischg-slow = <0 96>; + qcom,fg-esr-cal-soc-thresh = <26 230>; + qcom,fg-esr-cal-temp-thresh = <10 40>; + qcom,ki-coeff-chg-med-hi-thresh-ma = <1000>; + qcom,ki-coeff-chg-low-med-thresh-ma = <500>; + qcom,ffc-ki-coeff-chg-med-hi-thresh-ma = <3900>; + qcom,ffc-ki-coeff-chg-low-med-thresh-ma = <3500>; +}; + +&pm8150b_charger { + qcom,sec-charger-config = <0>; + qcom,usb-icl-ua = <3000000>; + qcom,fcc-max-ua = <5900000>; + qcom,fv-max-uv = <4470000>; + qcom,non-fcc-fv-max-uv = <4450000>; + //qcom,chg-warm-th= <450>; + //qcom,chg-cool-th= <150>; + qcom,auto-recharge-soc = <99>; + qcom,chg-term-src = <1>; + qcom,chg-term-current-ma = <(-400)>; + mi,use-bq-pump; + qcom,usbpd-phandle = <&pm8150b_pdphy>; + qcom,battery-data = <&nabu_batterydata>; + //mi,six-pin-step-chg-params = <4250000 6000000 + // 4450000 5400000 + // 4480000 4000000>; + //mi,six-pin-step-chg; + //mi,six-pin-soc-th = <45>; + mi,fcc-batt-unverify-ua = <2000000>; + mi,support-ffc; + qcom,support-wireless; + mi,support-qc3p5-without-smb; + qcom,disable-suspend-on-collapse; + qcom,thermal-mitigation = <3000000 2800000 2600000 2400000 2200000 2100000 2000000 + 1800000 1600000 1500000 1400000 1200000 1000000 900000 + 800000 500000>; + qcom,thermal-mitigation-icl + = <2800000 2700000 2600000 2400000 2200000 2100000 2000000 + 1800000 1600000 1500000 1400000 1300000 1200000 1100000 + 950000 750000>; + qcom,thermal-mitigation-dcp + = <1800000 1800000 1800000 1800000 1800000 1800000 1800000 + 1800000 1800000 1700000 1600000 1400000 1200000 1100000 + 1100000 1000000>; + qcom,thermal-mitigation-qc2 + = <1500000 1500000 1500000 1500000 1450000 1400000 1350000 + 1300000 1150000 1100000 1000000 900000 850000 750000 + 650000 500000>; + qcom,thermal-fcc-qc3-normal + = <3200000 3000000 2800000 2600000 2500000 2400000 2300000 + 2200000 2100000 1800000 1600000 1400000 1200000 1000000 + 750000 750000>; + qcom,thermal-fcc-pps-cp + = <6000000 5700000 5475000 5250000 5025000 4800000 4575000 + 4350000 4100000 3500000 3000000 2400000 2000000 1500000 + 1000000 500000>; + qcom,thermal-fcc-qc3-cp + = <4800000 4600000 4400000 4200000 4000000 3800000 3600000 + 3400000 3000000 2600000 2400000 2200000 2000000 1300000 + 1000000 300000>; + qcom,thermal-fcc-qc3-classb-cp + = <5100000 4700000 4300000 4000000 3600000 3500000 3400000 + 3400000 3400000 3200000 2500000 2200000 2000000 1300000 + 1000000 300000>; + qcom,thermal-mitigation-pd-base + = <3000000 2800000 2600000 2400000 2200000 2000000 1800000 + 1600000 1600000 1400000 1200000 1100000 1050000 1000000 + 950000 500000>; + qcom,thermal-mitigation-voice + = <6000000 2200000 2200000 1000000 1000000 800000 800000 + 800000 800000 700000 700000 600000 600000 600000 + 500000 400000>; + + + io-channels = <&pm8150b_vadc ADC_MID_CHG_DIV6>, + <&pm8150b_vadc ADC_USB_IN_V_16>, + <&pm8150b_vadc ADC_USB_IN_I>, + <&pm8150b_vadc ADC_SBUx>, + <&pm8150b_vadc ADC_VPH_PWR>, + <&pm8150b_vadc ADC_CHG_TEMP>; + io-channel-names = "mid_voltage", + "usb_in_voltage", + "usb_in_current", + "sbux_res", + "vph_voltage", + "chg_temp"; +// qcom,battery-data = <&mtp_batterydata>; + dpdm-supply = <&usb2_phy0>; + qcom,distinguish-qc-class-ab; + qcom,lpd-disable; + qcom,sw-jeita-enable; +// qcom,step-charging-enable; + qcom,wd-bark-time-secs = <16>; +}; + +&ext_5v_boost { + status = "disable"; +}; + +&pm8150b_pdphy { + mi,non-qcom-pps-ctrl; +}; + +&qupv3_se4_i2c { + #address-cells = <1>; + #size-cells = <0>; + status = "ok"; + bq25970-standalone@66 { + compatible = "ti,bq2597x-standalone"; + reg = <0x66>; + interrupt-parent = <&tlmm>; + interrupts = <36 0x2002>; + pinctrl-names = "default"; + pinctrl-0 = <&bq2597x_master_int_default &bq2597x_master_int_suspend>; + + /*ti,bq2597x,bat-ovp-disable;*/ + ti,bq2597x,bat-ovp-alarm-disable; + ti,bq2597x,bat-ocp-disable; + ti,bq2597x,bat-ocp-alarm-disable; + ti,bq2597x,bat-ucp-alarm-disable; + ti,bq2597x,bat-ucp-disable; + + /*ti,bq2597x,bus-ovp-alarm-disable; + ti,bq2597x,bus-ocp-disable; + ti,bq2597x,bus-ocp-alarm-disable;*/ + ti,bq2597x,bat-therm-disable; + ti,bq2597x,bus-therm-disable; + ti,bq2597x,die-therm-disable; + + ti,bq2597x,bat-ovp-threshold = <4550>; + ti,bq2597x,bat-ovp-alarm-threshold = <4525>; + //ti,bq2597x,bat-ocp-threshold = <8000>; + //ti,bq2597x,bat-ocp-alarm-threshold = <7500>; + + ti,bq2597x,bus-ovp-threshold = <12000>; + ti,bq2597x,bus-ovp-alarm-threshold = <11000>; + ti,bq2597x,bus-ocp-threshold = <3750>; + ti,bq2597x,bus-ocp-alarm-threshold = <3500>; + + //ti,bq2597x,bat-ucp-alarm-threshold = <2000>; + + ti,bq2597x,bat-therm-threshold = <0x15>;/*4.1%*/ + ti,bq2597x,bus-therm-threshold = <0x15>;/*4.1%*/ + ti,bq2597x,die-therm-threshold = <145>; + + ti,bq2597x,ac-ovp-threshold = <14>; + //ti,bq2597x,sense-resistor-mohm = <2>; + + }; + + ln8000_charger@51 { + compatible = "lionsemi,ln8000"; + reg = <0x51>; + /* bank */ + //irq-gpios = <&tlmm 55 0x2002>; + + //interrupt-parent = <&tlmm>; + //interrupts = <55 0x2002>; + //pinctrl-names = "default"; + //pinctrl-0 = <&bq2597x_int_default &bq2597x_int_suspend>; + ln8000_charger,irq_index = <296>; + /* device configuration */ + ln8000_charger,bat-ovp-threshold = <4560>; + ln8000_charger,bat-ovp-alarm-threshold = <4525>; + ln8000_charger,bus-ovp-threshold = <13000>; + ln8000_charger,bus-ovp-alarm-threshold = <11000>; + ln8000_charger,bus-ocp-threshold = <3750>; + ln8000_charger,bus-ocp-alarm-threshold = <3500>; + ln8000_charger,ntc-alarm-cfg = <226>; + /* protection enable/disable flags + * vbat-ovp-disable + * vbat-reg-disable + * iin-ocp-disable + * iin-reg-disable + * tbus-mon-disable + * tbat-mon-disable + * tdie-prot-disable + * tdie-reg-disable + * revcurr-prot-disable + */ + ln8000_charger,tdie-prot-disable; + ln8000_charger,tbus-mon-disable; + ln8000_charger,tbat-mon-disable; + ln8000_charger,iin-ocp-disable; + ln8000_charger,iin-reg-disable; + ln8000_charger,tdie-reg-disable; + ln8000_charger,vbat-reg-disable; + }; +}; + +&qupv3_se17_i2c { + status = "ok"; + idtp9418: idtp9418@3b { + compatible = "idt,p9418"; + status = "ok"; + reg = <0x3b>; + idt,irq = <&tlmm 95 0x00>; + hall,int3 = <&tlmm 101 0x00>; + hall,int4 = <&tlmm 134 0x00>; + idt,reverse-enable = <&tlmm 3 0x00>; + idt,reverse-booset-enable = <&tlmm 47 0x00>; + idt,wpc-det = <&tlmm 94 GPIO_ACTIVE_HIGH>; + pinctrl-names = "idt_active", "idt_suspend"; + pinctrl-0 = <&idt_int_active &hall_intr3_active &hall_intr4_active &txon_enable_active &power_good_active &reverse_booset_enable_active>; + pinctrl-1 = <&idt_int_suspend &hall_intr3_suspend &hall_intr4_suspend &txon_enable_suspend &power_good_suspend &reverse_booset_enable_suspend>; + }; +}; + +&soc { + cp_qc30 { + compatible = "xiaomi,cp-qc30"; + status = "ok"; + mi,qc3-bat-volt-max = <4420>; + mi,qc3-bat-curr-max = <3600>; + mi,qc3-bus-volt-max = <12000>; + mi,qc3-bus-curr-max = <2100>; + mi,qc3-battery-warm-th = <450>; + mi,use-qcom-gauge; + mi,support-qc3p5-without-smb; + //mi,cp-sec-enable; + }; + + usbpd_pm { + compatible = "xiaomi,usbpd-pm"; + status = "ok"; + mi,pd-bat-volt-max = <4500>; + mi,pd-ffc-bat-volt-max = <4480>; + mi,pd-bat-curr-max = <6000>; + mi,pd-bus-volt-max = <12000>; + mi,pd-bus-curr-max = <3000>; + mi,pd-non-ffc-bat-volt-max = <4450>; + mi,pd-bus-curr-compensate = <0>; + mi,pd-battery-warm-th = <450>; + mi,use-qcom-gauge; + //mi,cp-sec-enable; + }; + + qcom,rmnet-ipa { + status = "disabled"; + }; + + ipa_hw: qcom,ipa@1e00000 { + status = "disabled"; + }; + + onewire_gpio: onewire_gpio { + compatible = "xiaomi,onewire_gpio"; + label = "xm_onewire"; + xiaomi,version = <1>; + xiaomi,ow_gpio = <&tlmm 5 0x00>; + mi,onewire-gpio-cfg-addr = <0x03D05000 0x4>; + xiaomi,gpio_number = <5>; + pinctrl-names = "onewire_active", "onewire_sleep"; + pinctrl-0 = <&onewire_gpio_active>; + pinctrl-1 = <&onewire_gpio_sleep>; + status = "ok"; + }; + + onewire_slave_gpio: onewire_slave_gpio { + compatible = "xiaomi,onewire_slave_gpio"; + label = "xm_slave_onewire"; + xiaomi,version = <1>; + xiaomi,ow_gpio = <&tlmm 10 0x00>; + mi,onewire-gpio-cfg-addr = <0x0390A000 0x4>; + xiaomi,gpio_number = <10>; + pinctrl-names = "onewire_slave_active", "onewire_slave_sleep"; + pinctrl-0 = <&onewire_gpio_slave_active>; + pinctrl-1 = <&onewire_gpio_slave_sleep>; + status = "ok"; + }; + + nabu_batterydata: qcom,battery-data { + qcom,batt-id-range-pct = <15>; + #include "../common/battery/fg-gen4-batterydata-nabu-sunwoda-8720mah.dtsi" + }; + + maxim_ds28e16: maxim_ds28e16 { + compatible = "maxim,ds28e16"; + label = "max_ds28e16"; + maxim,version = <1>; + status = "ok"; + }; + + maxim_ds28e16_slave: maxim_ds28e16_slave { + compatible = "maxim,ds28e16_slave"; + label = "max_ds28e16_slave"; + maxim,version = <1>; + status = "ok"; + }; +}; + +&qupv3_se7_i2c { + status = "ok"; + /*speaker UL*/ + cs35l41@43 { + #sound-dai-cells = <1>; + compatible = "cirrus,cs35l41"; + reset-gpios = <&tlmm 92 0>; + reg = <0x43>; + interrupt-parent = <&tlmm>; + interrupts = <93 8>; + cirrus,temp-warn_threshold = <3>; + cirrus,boost-peak-milliamp = <4000>; + cirrus,boost-ind-nanohenry = <1000>; + cirrus,boost-cap-microfarad = <15>; + cirrus,asp-sdout-hiz = <3>; + cirrus,fast-switch = "TL-music.txt", "TL-voice.txt", "TL-voip.txt", "TL-misc.txt"; + cirrus,gpio-config2 { + cirrus,gpio-src-select = <0x4>; + cirrus,gpio-output-enable; + }; + }; + + /*speaker UR*/ + cs35l41@41 { + #sound-dai-cells = <1>; + compatible = "cirrus,cs35l41"; + reset-gpios = <&tlmm 92 0>; + reg = <0x41>; + interrupt-parent = <&tlmm>; + interrupts = <90 8>; + cirrus,temp-warn_threshold = <3>; + cirrus,boost-peak-milliamp = <4000>; + cirrus,boost-ind-nanohenry = <1000>; + cirrus,boost-cap-microfarad = <15>; + cirrus,asp-sdout-hiz = <3>; + cirrus,fast-switch = "TR-music.txt", "TR-voice.txt", "TR-voip.txt", "TR-misc.txt"; + cirrus,gpio-config2 { + cirrus,gpio-src-select = <0x4>; + cirrus,gpio-output-enable; + }; + }; + + /*speaker DL*/ + cs35l41@42 { + #sound-dai-cells = <1>; + compatible = "cirrus,cs35l41"; + reset-gpios = <&tlmm 92 0>; + reg = <0x42>; + interrupt-parent = <&tlmm>; + interrupts = <91 8>; + cirrus,temp-warn_threshold = <3>; + cirrus,boost-peak-milliamp = <4000>; + cirrus,boost-ind-nanohenry = <1000>; + cirrus,boost-cap-microfarad = <15>; + cirrus,asp-sdout-hiz = <3>; + cirrus,fast-switch = "BL-music.txt", "BL-voice.txt", "BL-voip.txt", "BL-misc.txt"; + cirrus,gpio-config2 { + cirrus,gpio-src-select = <0x4>; + cirrus,gpio-output-enable; + }; + }; + + /*speaker DR*/ + cs35l41@40 { + #sound-dai-cells = <1>; + compatible = "cirrus,cs35l41"; + reset-gpios = <&tlmm 92 0>; + reg = <0x40>; + interrupt-parent = <&tlmm>; + interrupts = <81 8>; + cirrus,temp-warn_threshold = <3>; + cirrus,boost-peak-milliamp = <4000>; + cirrus,boost-ind-nanohenry = <1000>; + cirrus,boost-cap-microfarad = <15>; + cirrus,asp-sdout-hiz = <3>; + cirrus,fast-switch = "BR-music.txt", "BR-voice.txt", "BR-voip.txt", "BR-misc.txt"; + cirrus,gpio-config2 { + cirrus,gpio-src-select = <0x4>; + cirrus,gpio-output-enable; + }; + }; +}; + + + +&smb1390 { + status = "disabled"; +}; + +&smb1390_charger { + status = "disabled"; +}; + +&usb0 { + dwc3@a600000 { + usb-phy = <&usb2_phy0>, <&usb_nop_phy>; + maximum-speed = "high-speed"; + }; +}; + +&usb2_phy0 { + qcom,param-override-seq = + <0x04 0x70 + 0x2c 0x74>; +}; + +&usb_qmp_dp_phy { + status = "disabled"; +}; + +&usb1 { + status = "ok"; + dwc3@a800000 { + dr_mode = "host"; + }; +}; + +&usb2_phy1 { + status = "ok"; +}; + +&usb_qmp_phy { + status = "ok"; +}; + +&soc { + touch_vddio_vreg: touch_vddio_vreg { + compatible = "regulator-fixed"; + regulator-name = "disp_vddio_vreg"; + startup-delay-us = <4000>; + enable-active-high; + regulator-boot-on; + gpio = <&tlmm 100 0>; + }; + + vdd_boost_vreg: vdd_boost_vreg { + compatible = "regulator-fixed"; + regulator-name = "vdd_boost_vreg"; + startup-delay-us = <4000>; + enable-active-high; + regulator-always-on; + gpio = <&pm8150b_gpios 5 0>; + }; + + fingerprint_goodix { + compatible = "goodix,fingerprint"; + goodix,gpio-reset = <&tlmm 37 0x0>; + goodix,gpio-irq = <&tlmm 120 0x0>; + //goodix.gpio_pwr = <&tlmm 125 0x0>; + //fp_vdd_vreg = <&pm8150l_l7>; + status = "ok"; + }; + + + fingerprint_fpc { + compatible = "fpc,fpc1020"; + fpc,gpio_rst = <&tlmm 37 0x0>; + fpc,gpio_irq = <&tlmm 120 0x0>; + pinctrl-names = "fpc1020_reset_reset", + "fpc1020_reset_active", + "fpc1020_irq_active"; + + pinctrl-0 = <&msm_gpio_37>; + pinctrl-1 = <&msm_gpio_37_output_high>; + pinctrl-2 = <&msm_gpio_120>; + status = "ok"; + }; + + + xiaomi_touch { + compatible = "xiaomi-touch"; + status = "ok"; + touch,name = "xiaomi-touch"; + }; + + testing_mode { + compatible = "modem,testing-mode"; + status-gpio = <&tlmm 81 0x00>, + <&tlmm 133 0x00>; + debounce-time = <30>; + pinctrl-names = "default"; + pinctrl-0 = <&ant_sub_ctrl_irq &ant_top_ctrl_irq>; + }; +}; + +&soc { + display_panel_enp: display_gpio_regulator_enp { + compatible = "regulator-fixed"; + regulator-name = "display_panel_enp"; + regulator-min-microvolt = <5500000>; + regulator-max-microvolt = <5500000>; + regulator-enable-ramp-delay = <233>; + gpio = <&tlmm 114 0>; + enable-active-high; + regulator-boot-on; + pinctrl-names = "default"; + pinctrl-0 = <&display_panel_enp_default>; + }; + display_panel_enn: display_gpio_regulator_enn { + compatible = "regulator-fixed"; + regulator-name = "display_panel_enn"; + regulator-min-microvolt = <5500000>; + regulator-max-microvolt = <5500000>; + regulator-enable-ramp-delay = <233>; + gpio = <&tlmm 115 0>; + enable-active-high; + regulator-boot-on; + pinctrl-names = "default"; + pinctrl-0 = <&display_panel_enn_default>; + }; + xiaomi_keyboard { + compatible = "xiaomi,keyboard"; + pinctrl-names = "pm_kb_active", "pm_kb_suspend"; + pinctrl-0 = <&xiaomi_keyboard_active>; + pinctrl-1 = <&xiaomi_keyboard_suspend>; + xiaomi-keyboard,rst-gpio = <&tlmm 49 0x00>; + xiaomi-keyboard,in-irq-gpio = <&tlmm 41 0x2001>; + xiaomi-keyboard,vdd-gpio = <&tlmm 82 0x00>; + status = "ok"; + }; +}; + +/* K82 Backlight Driver SE 11 pin mappings */ +&qupv3_se0_i2c { + status = "ok"; + ktz8866@11 { + compatible = "ktz,ktz8866"; + status = "ok"; + reg = <0x11>; + ktz8866,hwen-gpio = <&tlmm 27 0x00>; + ktz8866,enp-gpio = <&tlmm 114 0x00>; + ktz8866,enn-gpio = <&tlmm 115 0x00>; + }; +}; +&pm8150a_amoled { + status = "disabled"; +}; + +&pm8150l_lcdb { + status = "disabled"; +}; + +&pm8150l_wled { + status = "disabled"; + qcom,string-cfg = <7>; +}; + +&sde_dsi { + enp-supply = <&display_panel_enp>; + enn-supply = <&display_panel_enn>; +}; + +&dsi_k82_42_02_0a_dual_cphy_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply_k82_vddio>; +}; + +&dsi_k82_36_02_0b_dual_cphy_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply_k82_vddio>; +}; + +&red_led { + label = "white"; +}; + +&green_led { + status = "disabled"; +}; + +&blue_led { + status = "disabled"; +}; + +&dsi_k82_42_02_0a_dual_cphy_vid_display { + qcom,dsi-display-active; +}; + +&dsi_sim_vid_display { + /delete-property/ qcom,dsi-display-active; +}; + +/*Touch SPI state init*/ +&qupv3_se18_spi_active { + mux { + pins = "gpio23", "gpio24", "gpio25"; + function = "qup18"; + }; + + config { + pins = "gpio23", "gpio24", "gpio25"; + drive-strength = <6>; + bias-disable; + }; +}; + +&qupv3_se18_spi_sleep { + mux { + pins = "gpio23", "gpio24", "gpio25"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio24", "gpio25"; + drive-strength = <6>; + bias-disable; + }; +}; + +/*IC int pin, rst pin init*/ +&tlmm { + ts_mux { + ts_int_active: ts_int_active { + mux { + pins = "gpio39"; + function = "gpio"; + }; + + config { + pins = "gpio39"; + drive-strength = <16>; + bias-pull-down; + }; + }; +/* + ts_reset_active: ts_reset_active { + mux { + pins = "gpio12"; + function = "gpio"; + }; + + config { + pins = "gpio12"; + drive-strength = <16>; + bias-pull-up; + }; + }; +*/ + ts_cs_active: ts_cs_active { + mux { + pins = "gpio26"; + function = "qup18"; + }; + + config { + pins = "gpio26"; + drive-strength = <6>; + bias-disable; + }; + }; + + ts_cs_suspend: ts_cs_suspend { + mux { + pins = "gpio26"; + function = "gpio"; + }; + + config { + pins = "gpio26"; + drive-strength = <6>; + bias-pull-down; + output-low; + }; + }; + }; +}; + +&ts_int_suspend { + mux { + pins = "gpio39"; + function = "gpio"; + }; + + config { + pins = "gpio39"; + drive-strength = <16>; + bias-disable; + input-enable; + }; +}; + +/* +&ts_reset_suspend { + mux { + pins = "gpio12"; + function = "gpio"; + }; + + config { + pins = "gpio12"; + drive-strength = <16>; + bias-disable; + }; +}; +*/ + +&qupv3_se18_spi { + status = "ok"; + pinctrl-0 = <&qupv3_se18_spi_active>; + pinctrl-1 = <&qupv3_se18_spi_sleep>; + novatek@0 { + compatible = "novatek,NVT-ts-spi"; + reg = <0>; //Same as CS ID + status = "ok"; + + pinctrl-names = "pmx_ts_active", "pmx_ts_suspend"; + pinctrl-0 = <&ts_cs_active>; + pinctrl-1 = <&ts_cs_suspend>; + spi-max-frequency = <9600000>; //4800000,9600000,15000000,19200000 + //novatek,reset-gpio = <&tlmm 75 0x00>; + novatek,irq-gpio = <&tlmm 39 0x2001>; + + novatek,pen-support; + novatek,wgp-stylus; + + /* 523 */ + novatek,swrst-n8-addr = <0x03F0FE>; + novatek,spi-rd-fast-addr = <0x03F310>; + + /* MP */ + novatek,mp-support-dt; + /*new touch faeature default param*/ + novatek,touch-game-param-config1 = <2 2 1 2 1>; + novatek,touch-game-param-config2 = <2 2 2 2 1>; + novatek,touch-game-param-config3 = <2 2 3 2 1>; + + novatek,config-array-size = <2>; + novatek,cfg_0 { + novatek,display-maker = <0x42>; + novatek,fw-name = "novatek_nt36523_fw01.bin"; + novatek,mp-name = "novatek_nt36523_mp01.bin"; + }; + novatek,cfg_1 { + novatek,display-maker = <0x36>; + novatek,fw-name = "novatek_nt36523_fw02.bin"; + novatek,mp-name = "novatek_nt36523_mp02.bin"; + }; + + }; +}; + + +&qupv3_se9_i2c { + status = "ok"; + nq@28 { + compatible = "qcom,nq-nci"; + reg = <0x28>; + qcom,nq-irq = <&tlmm 47 0x00>; + qcom,nq-ven = <&tlmm 102 0x00>; + qcom,nq-firm = <&tlmm 48 0x00>; + qcom,nq-clkreq = <&tlmm 113 0x00>; + //qcom,nq-esepwr = <&tlmm 42 0x00>; + interrupt-parent = <&tlmm>; + interrupts = <47 0>; + interrupt-names = "nfc_irq"; + pinctrl-names = "nfc_active", "nfc_suspend"; + pinctrl-0 = <&nfc_int_active &nfc_enable_active + &nfc_clk_req_active>; + pinctrl-1 = <&nfc_int_suspend &nfc_enable_suspend + &nfc_clk_req_suspend>; + }; +}; + +&qupv3_se1_spi { + status = "ok"; + irled@0 { + compatible = "ir-spi"; + reg = <0x0>; + status = "ok"; + spi-max-frequency = <19200000>; + }; +}; + +&pm8150l_lpg { + qcom,lut-patterns = <0 1 2 3 4 5 7 9 11 13 15 + 13 11 9 7 5 4 3 2 1 0>; +}; + +&pwm_lpg1 { + qcom,lpg-chan-id = <1>; + qcom,ramp-step-ms = <100>; + qcom,ramp-pause-hi-count = <2>; + qcom,ramp-pause-lo-count = <2>; + qcom,ramp-low-index = <0>; + qcom,ramp-high-index = <20>; + qcom,ramp-from-low-to-high; + qcom,ramp-pattern-repeat; +}; + +&pm8150b_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + wp_therm { + reg = ; + label = "wp_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + vcoin { + reg = ; + label = "vcoin"; + qcom,pre-scaling = <1 3>; + }; + + conn_therm { + reg = ; + label = "conn_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + chg_sbux { + reg = ; + label = "chg_sbux"; + qcom,pre-scaling = <1 3>; + }; + + mid_chg_div6 { + reg = ; + label = "chg_mid"; + qcom,pre-scaling = <1 6>; + }; + + usb_in_i_uv { + reg = ; + label = "usb_in_i_uv"; + qcom,pre-scaling = <1 1>; + }; + + usb_in_v_div_16 { + reg = ; + label = "usb_in_v_div_16"; + qcom,pre-scaling = <1 16>; + }; +}; + +&pm8150_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + vcoin { + reg = ; + label = "vcoin"; + qcom,pre-scaling = <1 3>; + }; + + xo_therm { + reg = ; + label = "xo_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + quiet_therm { + reg = ; + label = "quiet_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + pa_therm0 { + reg = ; + label = "pa_therm0"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm8150l_vadc { + pinctrl-names = "default"; + pinctrl-0 = <&pm8150l_backlight_therm_default>; + + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + cam_therm0 { + reg = ; + label = "cam_therm0"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + cam_therm1 { + reg = ; + label = "cam_therm1"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + pa_therm1 { + reg = ; + label = "pa_therm1"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + backlight_therm { + reg = ; + label = "backlight_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm8150l_gpios { + pm8150l_backlight_therm { + pm8150l_backlight_therm_default: pm8150l_backlight_therm_default { + pins = "gpio7"; + bias-high-impedance;/* DISABLE GPIO7 for ADC*/ + }; + }; +}; + +&pm8150b_adc_tm { + wp_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm8150_adc_tm { + xo_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + quiet_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + pa_therm0 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm8150l_adc_tm { + io-channels = <&pm8150l_vadc ADC_AMUX_THM1_PU2>, + <&pm8150l_vadc ADC_AMUX_THM2_PU2>, + <&pm8150l_vadc ADC_GPIO3_PU2>; + + cam_therm0 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + cam_therm1 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + backlight_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&thermal_zones { + modem1_xo {//place close to pm8150b + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150b_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + xo_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_XO_THERM_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + quiet_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + charger_therm0 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_AMUX_THM2_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + flash_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + cpu_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM2_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + backlight_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_GPIO3_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; +}; + +&pm8150b_haptics { + qcom,vmax-mv = <2800>; + qcom,play-rate-us = <5102>; + + wf_0 { + /* CLICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_1 { + /* DOUBLE CLICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 3e]; + qcom,wf-brake-pattern = [03 01 01 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_2 { + /* TICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 3e]; + qcom,wf-brake-pattern = [03 01 01 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_3 { + /* THUD */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_4 { + /* POP */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_5 { + /* HEAVY CLICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 7e 7e]; + qcom,wf-brake-pattern = [03 03 01 00]; + qcom,wf-play-rate-us = <5102>; + }; +}; + +&soc { + ssc_sensors: qcom,msm-ssc-sensors { + compatible = "qcom,msm-ssc-sensors"; + status = "ok"; + qcom,firmware-name = "slpi_nb"; + }; + + gpio_keys { + hall_key { + label = "hall_key"; + gpios = <&tlmm 9 GPIO_ACTIVE_LOW>; + linux,input-type = <5>; + linux,code = <0>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + hall_key1 { + label = "hall_key1"; + gpios = <&tlmm 83 GPIO_ACTIVE_LOW>; + linux,input-type = <5>; + linux,code = <1>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + }; + + + thermal_message: thermal-message { + board-sensor = "VIRTUAL-SENSOR"; + }; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; + status = "ok"; + }; + +&tlmm { + /* GPIO_37 : FP_RESET_N */ + msm_gpio_37: msm_gpio_37 { + mux { + pins = "gpio37"; + function = "gpio"; + }; + + config { + pins = "gpio37"; + drive-strength = <2>; + bias-disable; + output-low; + }; + }; + + /* GPIO_37 : FP_RESET_N, state device active*/ + msm_gpio_37_output_high: msm_gpio_37_output_high { + mux { + pins = "gpio37"; + function = "gpio"; + }; + + config { + pins = "gpio37"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + + /* GPIO_120 : FP_INT_N */ + msm_gpio_120: msm_gpio_120 { + mux { + pins = "gpio120"; + function = "gpio"; + }; + + config { + pins = "gpio120"; + drive-strength = <2>; + bias-pull-down; + }; + }; +}; + +&pm8150l_gpios { + /* WIDE VDIG ENABLE */ + cam_sensor_wide_vdig_enable: cam_sensor_wide_vdig_enable { + pins = "gpio3"; + function = "normal"; + power-source = <0>; + output-low; + }; + + cam_sensor_wide_vdig_disable: cam_sensor_wide_vdig_disable { + pins = "gpio3"; + function = "normal"; + power-source = <0>; + output-low; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-audio-overlay.dtsi new file mode 100644 index 000000000000..68d020d5ddda --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-audio-overlay.dtsi @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include "../common/sm8150-audio-overlay.dtsi" + +&snd_934x { + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "MADINPUT", "MCLK", + "hifi amp", "LINEOUT1", + "hifi amp", "LINEOUT2", + "AMIC2", "MIC BIAS2", + "MIC BIAS2", "Headset Mic", + "AMIC3", "MIC BIAS3", + "MIC BIAS3", "ANCRight Headset Mic", + "AMIC1", "MIC BIAS1", + "MIC BIAS1", "ANCLeft Headset Mic", + "AMIC4", "MIC BIAS1", + "MIC BIAS1", "ANCRight Headset Mic", + "AMIC5", "MIC BIAS4", + "MIC BIAS4", "Analog Mic5"; + + qcom,wsa-max-devs = <0>; + qcom,msm-mbhc-hphl-swh = <1>; + qcom,msm-mbhc-gnd-swh = <1>; + qcom,msm-mbhc-usbc-audio-supported = <0>; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-pinctrl.dtsi new file mode 100644 index 000000000000..09bc52610904 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-pinctrl.dtsi @@ -0,0 +1,608 @@ +/*for xiaomi pinctrl*/ +&tlmm { + idt { + idt_int_active: idt_int_active { + /* active state */ + mux { + /* GPIO 78 idt Read Interrupt */ + pins = "gpio114"; + function = "gpio"; + }; + + config { + pins = "gpio114"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + idt_int_suspend: idt_int_suspend { + /* sleep state */ + mux { + /* GPIO 78 idt Read Interrupt */ + pins = "gpio114"; + function = "gpio"; + }; + + config { + pins = "gpio114"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + idt_enable_active: idt_enable_active { + /* active state */ + mux { + /* GPIO 36 idt enable pin */ + pins = "gpio115"; + function = "gpio"; + }; + + config { + pins = "gpio115"; + drive-strength = <2>; + bias-disable; + bias-pull-down; + output-low; + }; + }; + + idt_enable_suspend: idt_enable_suspend { + /* sleep state */ + mux { + /* GPIO 36 idt enable pin */ + pins = "gpio115"; + function = "gpio"; + }; + + config { + pins = "gpio115"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + fp_mux { + fp_active: fp_active { + mux { + pins = "gpio118"; + function = "gpio"; + }; + config { + pins = "gpio118"; + drive-strength = <8>; + bias-disable; + }; + }; + + fp_suspend: fp_suspend { + mux { + pins = "gpio118"; + function = "gpio"; + }; + config { + pins = "gpio118"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + /* GPIO_37 : FP_RESET_N */ + msm_gpio_37: msm_gpio_37 { + mux { + pins = "gpio37"; + function = "gpio"; + }; + + config { + pins = "gpio37"; + drive-strength = <2>; + bias-disable; + output-low; + }; + }; + + /* GPIO_37 : FP_RESET_N, state device active*/ + msm_gpio_37_output_high: msm_gpio_37_output_high { + mux { + pins = "gpio37"; + function = "gpio"; + }; + + config { + pins = "gpio37"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + + /* GPIO_118 : FP_INT_N */ + msm_gpio_118: msm_gpio_118 { + mux { + pins = "gpio118"; + function = "gpio"; + }; + + config { + pins = "gpio118"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + smartpa_int_active: smartpa_int_active { + /* active state */ + mux { + /* GPIO 141 Interrupt */ + pins = "gpio141"; + function = "gpio"; + }; + + config { + pins = "gpio141"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + smartpa_int_suspend: smartpa_int_suspend { + /* sleep state */ + mux { + /* GPIO 141 Interrupt */ + pins = "gpio141"; + function = "gpio"; + }; + + config { + pins = "gpio141"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + smartpa_enable_active: smartpa_enable_active { + /* active state */ + mux { + /* GPIO 59 rst pin */ + pins = "gpio59"; + function = "gpio"; + }; + + config { + pins = "gpio59"; + drive-strength = <2>; + bias-disable; + bias-pull-down; + output-low; + }; + }; + + smartpa_enable_suspend: smartpa_enable_suspend { + /* sleep state */ + mux { + /* GPIO 59 rst pin */ + pins = "gpio59"; + function = "gpio"; + }; + + config { + pins = "gpio59"; + drive-strength = <2>; + bias-disable; + bias-pull-down; + output-low; + }; + }; + }; + /*touchpanel*/ + pmx_ts_active { + tp_active: tp_active { + mux { + pins = "gpio122", "gpio54"; + function = "gpio"; + }; + config { + pins = "gpio122", "gpio54"; + drive-strength = <16>; + bias-pull-up; + }; + }; + }; + + pmx_ts_int_suspend { + tp_int_suspend: tp_int_suspend { + mux { + pins = "gpio122"; + function = "gpio"; + }; + config { + pins = "gpio122"; + drive-strength = <16>; + input-enable; + slew-rate = <0>; + bias-pull-up = <00>; + }; + }; + }; + + pmx_ts_reset_suspend { + tp_reset_suspend: tp_reset_suspend { + mux { + pins = "gpio54"; + function = "gpio"; + }; + config { + pins = "gpio54"; + drive-strength = <16>; + slew-rate = <1>; + bias-disable; + output-high; + }; + }; + }; + + + akm09970_irq { + akm_irq_active: akm_irq_active { + mux { + pins = "gpio11"; + function = "gpio"; + }; + + config { + pins = "gpio11"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; /* No PULL */ + }; + }; + + akm_irq_suspend: akm_irq_suspend { + mux { + pins = "gpio11"; + function = "gpio"; + }; + + config { + pins = "gpio11"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + }; + + akm09970_reset { + akm_reset_active: akm_reset_active { + mux { + pins = "gpio27"; + function = "gpio"; + }; + + config { + pins = "gpio27"; + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* No PULL */ + output-low; + }; + }; + + akm_reset_suspend: akm_reset_suspend { + mux { + pins = "gpio27"; + function = "gpio"; + }; + + config { + pins = "gpio27"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + }; + + motor_gpio_default: motor_gpio_default { + mux { + pins = "gpio9", "gpio21", "gpio33", "gpio35", "gpio130"; + function = "gpio"; + }; + + config { + pins = "gpio9", "gpio21", "gpio33", "gpio35", "gpio130"; + bias-pull-up; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_active_wide: cam_sensor_active_wide { + /* WIDE RESET DVDDEN */ + mux { + pins = "gpio28", "gpio90"; + function = "gpio"; + }; + + config { + pins = "gpio28", "gpio90"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_wide: cam_sensor_suspend_wide { + /* WIDE RESET DVDDEN AVDDEN 1.8AVDDEN */ + mux { + pins = "gpio28", "gpio90"; + function = "gpio"; + }; + + config { + pins = "gpio28", "gpio90"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_active_tele: cam_sensor_active_tele { + /* TELE RESET DVDDEN */ + mux { + pins = "gpio30", "gpio93"; + function = "gpio"; + }; + + config { + pins = "gpio30", "gpio93"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_tele: cam_sensor_suspend_tele { + /* TELE RESET DVDDEN */ + mux { + pins = "gpio30", "gpio93"; + function = "gpio"; + }; + + config { + pins = "gpio30", "gpio93"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_active_ultra: cam_sensor_active_ultra { + /* ULTRA RESET DVDDEN */ + mux { + pins = "gpio23", "gpio34"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio34"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_ultra: cam_sensor_suspend_ultra { + /* ULTRA RESET DVDDEN */ + mux { + pins = "gpio23", "gpio34"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio34"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_active_front: cam_sensor_active_front { + /* FRONT RESET DVDDEN */ + mux { + pins = "gpio12", "gpio95"; + function = "gpio"; + }; + + config { + pins = "gpio12", "gpio95"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_front: cam_sensor_suspend_front { + /* FRONT RESET DVDDEN */ + mux { + pins = "gpio12", "gpio95"; + function = "gpio"; + }; + + config { + pins = "gpio12", "gpio95"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_actuator_wide_en: cam_actuator_wide_en { + mux { + pins = "gpio83"; + function = "gpio"; + }; + + config { + pins = "gpio83"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_actuator_tele_en: cam_actuator_tele_en { + mux { + pins = "gpio84"; + function = "gpio"; + }; + + config { + pins = "gpio84"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_viodd_en: cam_sensor_viodd_en { + mux { + pins = "gpio97"; + function = "gpio"; + }; + + config { + pins = "gpio97"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + sde_dsi_active: sde_dsi_active { + mux { + pins = "gpio6", "gpio7", "gpio5"; + function = "gpio"; + }; + + config { + pins = "gpio6", "gpio7", "gpio5"; + drive-strength = <8>; /* 8 mA */ + bias-disable = <0>; /* no pull */ + }; + }; + sde_dsi_suspend: sde_dsi_suspend { + mux { + pins = "gpio6", "gpio7", "gpio5"; + function = "gpio"; + }; + + config { + pins = "gpio6", "gpio7", "gpio5"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + + pcie1 { + pcie1_clkreq_default: pcie1_clkreq_default { + mux { + pins = "gpio103"; + function = "gpio"; + }; + + config { + pins = "gpio103"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + nfc { + nfc_int_active: nfc_int_active { + /* active state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_int_suspend: nfc_int_suspend { + /* sleep state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_active: nfc_enable_active { + /* active state */ + mux { + /* 41: NFC ENABLE 42:ESE Enable */ + pins = "gpio48", "gpio103"; + function = "gpio"; + }; + + config { + pins = "gpio48", "gpio103"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_suspend: nfc_enable_suspend { + /* sleep state */ + mux { + /* 41: NFC ENABLE 42:ESE Enable */ + pins = "gpio48", "gpio103"; + function = "gpio"; + }; + + config { + pins = "gpio48", "gpio103"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + + nfc_clk_req_active: nfc_clk_req_active { + /* active state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_clk_req_suspend: nfc_clk_req_suspend { + /* sleep state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-sm8150-camera-sensor.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-sm8150-camera-sensor.dtsi new file mode 100644 index 000000000000..ceb6c189bcaa --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-sm8150-camera-sensor.dtsi @@ -0,0 +1,483 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +&soc { + led_flash_rear: qcom,camera-flash@0 { + cell-index = <0>; + reg = <0x00 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch2>; + status = "ok"; + }; + + led_flash_rear_aux: qcom,camera-flash@1 { + cell-index = <1>; + reg = <0x01 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch2>; + status = "ok"; + }; + + led_flash_rear_aux2: qcom,camera-flash@2 { + cell-index = <2>; + reg = <0x02 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch2>; + status = "ok"; + }; +/* + led_flash_front: qcom,camera-flash@2 { + cell-index = <2>; + reg = <0x02 0x00>; + compatible = "qcom,camera-flash"; + wled-flash-support; + flash-source = <&wled_flash>; + torch-source = <&wled_torch>; + switch-source = <&wled_switch>; + status = "ok"; + }; + + led_flash_iris: qcom,camera-flash@3 { + cell-index = <3>; + reg = <0x03 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash1>; + torch-source = <&pm8150l_torch1>; + switch-source = <&pm8150l_switch0>; + status = "ok"; + };*/ + + wide_actuator_regulator: gpio-regulator@0 { + compatible = "regulator-fixed"; + reg = <0x00 0x00>; + regulator-name = "actuator_regulator"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <100>; + enable-active-high; + gpio = <&tlmm 83 0>; + pinctrl-names = "default"; + pinctrl-0 = <&cam_actuator_wide_en>; + vin-supply = <&pm8150l_bob>; + }; + + tele_actuator_regulator: gpio-regulator@1 { + compatible = "regulator-fixed"; + reg = <0x01 0x00>; + regulator-name = "actuator_regulator"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <100>; + enable-active-high; + gpio = <&tlmm 84 0>; + pinctrl-names = "default"; + pinctrl-0 = <&cam_actuator_tele_en>; + vin-supply = <&pm8150l_bob>; + }; + + camera_viodd_ldo: gpio-regulator@2 { + compatible = "regulator-fixed"; + reg = <0x02 0x00>; + regulator-name = "camera_viodd_ldo"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&tlmm 97 0>; + pinctrl-names = "default"; + pinctrl-0 = <&cam_sensor_viodd_en>; + vin-supply = <&pm8150_s4>; + }; +}; + +&pm8150_l17 { + regulator-min-microvolt = <3100000>; + regulator-max-microvolt = <3100000>; + qcom,init-voltage = <3100000>; +}; + +&cam_cci0 { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + status = "ok"; + }; + + actuator_rear: qcom,actuator@0 { + cell-index = <0>; + reg = <0x0>; + compatible = "qcom,actuator"; + cci-master = <0>; + cam_vaf-supply = <&wide_actuator_regulator>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + actuator_rear_aux: qcom,actuator@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,actuator"; + cci-master = <1>; + cam_vaf-supply = <&tele_actuator_regulator>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + eeprom_rear: qcom,eeprom@0 { + cell-index = <0>; + reg = <0>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vaf-supply = <&wide_actuator_regulator>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vaf", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 2800000 0>; + rgltr-max-voltage = <1800000 2800000 0>; + rgltr-load-current = <1000 1000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_wide>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_wide>; + gpios = <&tlmm 13 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK0"; + sensor-mode = <0>; + cci-master = <0>; + cci-device = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + eeprom_rear_aux: qcom,eeprom@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vaf-supply = <&tele_actuator_regulator>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vaf", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 2800000 0>; + rgltr-max-voltage = <1800000 2800000 0>; + rgltr-load-current = <1000 1000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_tele>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_tele>; + gpios = <&tlmm 14 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK1"; + sensor-mode = <0>; + cci-master = <1>; + cci-device = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + eeprom_front: qcom,eeprom@2 { + cell-index = <2>; + reg = <0x2>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&camera_viodd_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <1000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_front>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_front>; + gpios = <&tlmm 15 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK2"; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + qcom,cam-sensor@0 { + cell-index = <0>; + compatible = "qcom,cam-sensor"; + reg = <0x0>; + csiphy-sd-index = <0>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + led-flash-src = <&led_flash_rear>; + actuator-src = <&actuator_rear>; + eeprom-src = <&eeprom_rear>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150l_s8>; + cam_clk-supply = <&titan_top_gdsc>; + cam_v_custom1-supply = <&pm8150_s5>; + cam_v_custom2-supply = <&pm8150_l17>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk", "cam_v_custom1", "cam_v_custom2"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 3008000 1352000 0 1904000 3100000>; + rgltr-max-voltage = <1800000 4000000 1352000 0 2040000 3100000>; + rgltr-load-current = <1000 80000 1200000 0 10000 1000>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_wide>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_wide>; + gpios = <&tlmm 13 0>, + <&tlmm 28 0>, + <&tlmm 90 0>; + gpio-reset = <1>; + gpio-vdig = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAMW_RESET", + "CAMW_VDIG_EN"; + sensor-mode = <0>; + cci-master = <0>; + cci-device = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + qcom,cam-sensor@1 { + cell-index = <1>; + compatible = "qcom,cam-sensor"; + reg = <0x1>; + csiphy-sd-index = <2>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + actuator-src = <&actuator_rear_aux>; + led-flash-src = <&led_flash_rear_aux>; + eeprom-src = <&eeprom_rear_aux>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150l_s8>; + cam_clk-supply = <&titan_top_gdsc>; + cam_v_custom1-supply = <&pm8150_l17>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk", "cam_v_custom1"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 3008000 1352000 0 3100000>; + rgltr-max-voltage = <1800000 4000000 1352000 0 3100000>; + rgltr-load-current = <1000 80000 1200000 0 1000>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_tele>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_tele>; + gpios = <&tlmm 14 0>, + <&tlmm 30 0>, + <&tlmm 93 0>; + gpio-reset = <1>; + gpio-vdig = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK1", + "CAMT_RESET", + "CAMT_VDIG_EN"; + sensor-mode = <0>; + cci-master = <1>; + cci-device = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + qcom,cam-sensor@2 { + cell-index = <2>; + compatible = "qcom,cam-sensor"; + reg = <0x02>; + csiphy-sd-index = <1>; + sensor-position-roll = <270>; + sensor-position-pitch = <0>; + sensor-position-yaw = <0>; + eeprom-src = <&eeprom_front>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150l_s8>; + cam_clk-supply = <&titan_top_gdsc>; + cam_v_custom1-supply = <&pm8150_l17>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk", "cam_v_custom1"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 3008000 1352000 0 3100000>; + rgltr-max-voltage = <1800000 4000000 1352000 0 3100000>; + rgltr-load-current = <1000 80000 1200000 0 1000>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_front>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_front>; + gpios = <&tlmm 15 0>, + <&tlmm 12 0>, + <&tlmm 95 0>; + gpio-reset = <1>; + gpio-vdig = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAMF_RESET", + "CAMF_VDIG_EN"; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; +}; + +&cam_cci1 { + status = "ok"; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cci2_active>; + pinctrl-1 = <&cci2_suspend>; + gpios = <&tlmm 31 0>, + <&tlmm 32 0>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 1>; + gpio-req-tbl-label = "CCI_I2C_DATA2", + "CCI_I2C_CLK2"; + + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + status = "ok"; + }; + + eeprom_ultra: qcom,eeprom@3 { + cell-index = <3>; + reg = <0x3>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&camera_viodd_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <1000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_ultra>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_ultra>; + + gpios = <&tlmm 16 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK3"; + sensor-mode = <0>; + cci-master = <0>; + cci-device = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + qcom,cam-sensor@3 { + cell-index = <3>; + compatible = "qcom,cam-sensor"; + reg = <0x03>; + csiphy-sd-index = <3>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + led-flash-src = <&led_flash_rear_aux2>; + eeprom-src = <&eeprom_ultra>; + cam_vio-supply = <&camera_viodd_ldo>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150l_s8>; + cam_clk-supply = <&titan_top_gdsc>; + cam_v_custom1-supply = <&pm8150_l17>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk", "cam_v_custom1"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 3008000 1352000 0 3100000>; + rgltr-max-voltage = <1800000 4000000 1352000 0 3100000>; + rgltr-load-current = <1000 80000 1200000 0 1000>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_ultra>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_ultra>; + + gpios = <&tlmm 16 0>, + <&tlmm 23 0>, + <&tlmm 34 0>; + gpio-reset = <1>; + gpio-vdig = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK3", + "CAMU_RESET", + "CAMU_VDIG_EN"; + sensor-mode = <0>; + cci-master = <0>; + cci-device = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-sm8150.dtsi new file mode 100644 index 000000000000..31b245e7c25b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/raphael/raphael-sm8150.dtsi @@ -0,0 +1,736 @@ +/* +this file is for attribution only of davinci +And public attribution of xiaomi platforms(like F1 and so and) +*/ +#include "raphael-pinctrl.dtsi" +#include "../common/xiaomi-sm8150-common.dtsi" + +#include "raphael-sm8150-camera-sensor.dtsi" + +#include "../common/smb1390.dtsi" + + +&vendor { + mtp_batterydata: qcom,battery-data { + qcom,batt-id-range-pct = <15>; + #include "../common/battery/batterydata-F11-sun-4000mah.dtsi" + #include "../common/battery/batterydata-F11-gyu-4000mah.dtsi" + }; +}; + +&pm8150b_fg { + qcom,battery-data = <&mtp_batterydata>; + qcom,rapid-soc-dec-en; + qcom,fg-sys-term-current = <(-300)>; + qcom,fg-cutoff-voltage = <3400>; + qcom,fg-cutoff-current = <200>; + qcom,fg-empty-voltage = <3100>; + qcom,fg-batt-temp-delta = <6>; + qcom,fg-force-load-profile; + qcom,five-pin-battery; + /* ESR fast calibration */ + qcom,fg-esr-timer-chg-fast = <0 7>; + qcom,fg-esr-timer-dischg-fast = <0 7>; + qcom,fg-esr-timer-chg-slow = <0 96>; + qcom,fg-esr-timer-dischg-slow = <0 96>; + qcom,fg-esr-cal-soc-thresh = <26 230>; + qcom,fg-esr-cal-temp-thresh = <10 40>; +}; + +&pm8150b_charger { + qcom,sec-charger-config = <1>; + qcom,usb-icl-ua = <2800000>; + qcom,fcc-max-ua = <5100000>; + qcom,fv-max-uv = <4400000>; + qcom,auto-recharge-soc = <99>; + qcom,chg-term-src = <1>; + qcom,chg-term-current-ma = <(-220)>; + qcom,thermal-mitigation = <3000000 2800000 2600000 2400000 2200000 2100000 2000000 + 1800000 1600000 1500000 1400000 1200000 1000000 900000 + 800000 500000>; + qcom,thermal-mitigation-icl + = <2800000 2700000 2600000 2400000 2400000 2400000 2400000 + 2400000 2400000 2100000 1900000 1700000 1500000 1300000 + 1000000 750000>; + qcom,thermal-mitigation-dcp + = <1800000 1800000 1800000 1800000 1800000 1800000 1800000 + 1800000 1800000 1700000 1600000 1400000 1200000 1100000 + 1100000 1000000>; + qcom,thermal-mitigation-qc2 + = <1500000 1500000 1500000 1500000 1450000 1400000 1350000 + 1300000 1300000 1200000 1000000 900000 850000 750000 + 650000 500000>; + qcom,thermal-fcc-qc3-normal + = <3200000 3000000 2800000 2600000 2500000 2400000 2300000 + 2200000 2100000 1800000 1600000 1400000 1200000 1000000 + 750000 750000>; + qcom,thermal-fcc-qc3-cp + = <3600000 3600000 3600000 3500000 3400000 3300000 3300000 + 3200000 3100000 2800000 2400000 2200000 2000000 1300000 + 1000000 700000>; + qcom,thermal-fcc-qc3-classb-cp + = <5100000 4800000 4600000 4400000 4200000 4000000 4000000 + 4000000 4000000 3600000 3400000 3200000 3000000 2200000 + 1000000 700000>; + qcom,thermal-mitigation-pd-base + = <3000000 2800000 2600000 2500000 2500000 2500000 2500000 + 2500000 2500000 2400000 2200000 2000000 1600000 1300000 + 1000000 500000>; + qcom,thermal-fcc-pps-cp + = <5100000 5000000 4900000 4800000 4600000 4400000 4200000 + 4000000 3800000 3600000 3400000 3200000 3000000 2200000 + 1000000 500000>; + qcom,thermal-mitigation-dc + = <2200000 2000000 1800000 1600000 1400000 1200000 1100000 + 1000000 900000 800000 700000 600000 500000 400000 + 300000 200000>; + qcom,lpd_hwversion + = <43200 53600 100000 121000 232000 300000 562000 900000>; + + io-channels = <&pm8150b_vadc ADC_MID_CHG_DIV6>, + <&pm8150b_vadc ADC_USB_IN_V_16>, + <&pm8150b_vadc ADC_USB_IN_I>, + <&pm8150b_vadc ADC_SBUx>, + <&pm8150b_vadc ADC_VPH_PWR>, + <&pm8150b_vadc ADC_CHG_TEMP>, + <&pm8150l_vadc ADC_GPIO1_PU2>, + <&pm8150l_vadc ADC_GPIO2_PU2>; + + io-channel-names = "mid_voltage", + "usb_in_voltage", + "usb_in_current", + "sbux_res", + "vph_voltage", + "chg_temp", + "hw_version_gpio5", + "project_gpio6"; + + qcom,battery-data = <&mtp_batterydata>; + dpdm-supply = <&usb2_phy0>; + qcom,distinguish-qc-class-ab; + //qcom,lpd-enable; + qcom,lpd-disable; + qcom,sw-jeita-enable; + qcom,step-charging-enable; + qcom,wd-bark-time-secs = <16>; +}; + +&qupv3_se1_i2c { + status = "ok"; + tfa98xx@34 { + compatible = "nxp,tfa98xx"; + reset-gpio = <&tlmm 59 0>; + irq-gpio = <&tlmm 141 0>; + interrupt-parent = <&tlmm>; + interrupts = <141 0>; + interrupt-names = "smartpa_irq"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&smartpa_int_active &smartpa_enable_active>; + pinctrl-1 = <&smartpa_int_suspend &smartpa_enable_suspend>; + reg = <0x34>; + status = "ok"; + }; +}; + +&pm8150l_pwm { + status = "ok"; +}; + +&qupv3_se4_i2c { + status = "ok"; + fsa4480@43 { + status = "disabled"; + }; + + akm09970@c { + compatible = "akm,akm09970"; + reg = <0xC>; + interrupt-parent = <&tlmm>; + interrupts = <120 0>; + akm,gpio-reset = <&tlmm 11 0x00>; + akm,gpio-irq = <&tlmm 27 0x00>; + akm,measure-freq-hz = <100>; + vdd-supply = <&pm8150l_l8>; + + pinctrl-names = "akm09970_gpio_active", "akm09970_gpio_suspend"; + pinctrl-0 = <&akm_irq_active &akm_reset_active>; + pinctrl-1 = <&akm_irq_suspend &akm_reset_suspend>; + status = "ok"; + }; +}; + +&soc { + ti,drv8846@0 { + cell-index = <0>; + reg = <0x00 0x00>; + compatible = "ti,drv8846"; + pwms = <&pm8150l_pwm 1 1000000>; + motor,gpio-mode0 = <&tlmm 21 0x00>; + motor,gpio-mode1 = <&tlmm 33 0x00>; + motor,gpio-sleep = <&tlmm 35 0x00>; + motor,gpio-dir = <&tlmm 9 0x00>; + motor,gpio-pwren = <&tlmm 130 0x00>; + + motor,rampup-pwm-period-ns = <625000>; + motor,rampup-duration-ms = <50>; + motor,high-pwm-period-ns = <52083>; + motor,high-duration-ms = <720>; + motor,rampdown-pwm-period-ns = <625000>; + motor,rampdown-duration-ms = <50>; + motor,step-mode = <2>; + + pinctrl-names = "default"; + pinctrl-0 = <&pwm_out_gpio10_default &motor_gpio_default>; + status = "ok"; + }; + + simtray { + compatible = "xiaomi,simtray-status"; + status-gpio = <&tlmm 112 0x00>; + }; +}; + +&pm8150l_gpios { + pwm_out_gpio10 { + pwm_out_gpio10_default: pwm_out_gpio10_default { + pins = "gpio10"; + function = "func1"; + bias-disable; + power-source = <1>; + output-low; + qcom,drive-strength = <3>; + drive-push-pull; + }; + }; +}; + +&smb1390 { + pinctrl-names = "default"; + pinctrl-0 = <&smb_stat_default>; + status = "ok"; +}; + +&smb1390_charger { + io-channels = <&pm8150b_vadc ADC_AMUX_THM2>; + io-channel-names = "cp_die_temp"; + status = "ok"; +}; + +&usb0 { + dwc3@a600000 { + usb-phy = <&usb2_phy0>, <&usb_nop_phy>; + maximum-speed = "high-speed"; + }; +}; + +&usb2_phy0 { + qcom,param-override-seq = + <0x83 0x70 + 0x2c 0x74>; +}; + +&usb_qmp_dp_phy { + status = "disabled"; +}; + +&usb1 { + extcon = <&extcon_usb1>; + status = "disabled"; +}; + +&usb2_phy1 { + status = "disabled"; +}; + +&usb_qmp_phy { + status = "disabled"; +}; + +&soc { + touch_vddio_vreg: touch_vddio_vreg { + compatible = "regulator-fixed"; + regulator-name = "disp_vddio_vreg"; + startup-delay-us = <4000>; + enable-active-high; + regulator-boot-on; + //gpio = <&tlmm 99 0>; + }; + + vdd_boost_vreg: vdd_boost_vreg { + compatible = "regulator-fixed"; + regulator-name = "vdd_boost_vreg"; + startup-delay-us = <4000>; + enable-active-high; + regulator-always-on; + gpio = <&pm8150b_gpios 5 0>; + }; + + fingerprint_goodix { + compatible = "goodix,fingerprint"; + goodix,gpio-reset = <&tlmm 37 0x0>; + goodix,gpio-irq = <&tlmm 118 0x0>; + fp-gpio-pwr = <&tlmm 125 0>; + status = "ok"; + }; + + xiaomi_touch { + compatible = "xiaomi-touch"; + status = "ok"; + touch,name = "xiaomi-touch"; + }; + + disp_vci_vreg: disp_vci_vreg { + compatible = "regulator-fixed"; + regulator-name = "disp_vci_vreg"; + start-delay-us = <4000>; + enable-active-high; + regulator-boot-on; + gpio = <&tlmm 99 0>; + }; +}; + +&qupv3_se19_i2c { + status = "ok"; + goodix@5d { + compatible = "goodix,gt9889"; + reg = <0x5d>; + status = "ok"; + interrupt-parent = <&tlmm>; + interrupts = <122 0x2800>; + //vtouch-supply = <&pm660l_l8>; + //iotouch-supply = <&pm660_l13>; + vtouch-load = <600000>; + pinctrl-names = "pmx_ts_active","pmx_ts_suspend"; + pinctrl-0 = <&tp_active>; + pinctrl-1 = <&tp_int_suspend &tp_reset_suspend>; + goodix,reset-gpio = <&tlmm 54 0x0>; + goodix,irq-gpio = <&tlmm 122 0x2800>; + goodix,vdd-gpio = <&tlmm 98 0x0>; /* 3v3 */ + goodix,avdd-gpio = <&tlmm 100 0x0>; /* 1v8 */ + goodix,irq-flags = <2>; /* 1:trigger rising, 2:trigger falling;*/ + goodix,panel-max-id = <10>; + goodix,panel-max-x = <1079>; + goodix,panel-max-y = <2339>; + goodix,panel-max-w = <127>; + goodix,panel-max-p = <127>; + goodix,panel-max-fod = <127>; + /* goodix,panel-key-map = <158 172 217>; */ /*KEY_BACK, KEY_HOMEPAGE, KEY_SEARCH*/ + goodix,power-on-delay-us = <300000>; /*300ms*/ + goodix,power-off-delay-us = <5000>; + goodix,cfg-name = "goodix_gt9886_cfg_f11.bin"; + normal-cfg = [ + ]; + /* goodix,swap-axis; */ + /* goodix,pen-enable; */ + /* goodix,key-of-pen = <331 332>; */ /*BTN_STYLUS, BTN_STYLUS2*/ + sensor0 { + goodix,limit-name = "goodix_gt9886_limit_f11_second.tporder"; + goodix,fw-name = "goodix_gt9886_fw_f11.bin"; + goodix,x2x; + goodix,y2y; + }; + sensor1 { + goodix,limit-name = "goodix_gt9886_limit_f11_first.tporder"; + goodix,fw-name = "goodix_gt9886_fw_f11.bin"; + }; + }; +}; + + +&pm8150b_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + wp_therm { + reg = ; + label = "wp_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + vcoin { + reg = ; + label = "vcoin"; + qcom,pre-scaling = <1 3>; + }; + + conn_therm { + reg = ; + label = "conn_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + chg_sbux { + reg = ; + label = "chg_sbux"; + qcom,pre-scaling = <1 3>; + }; + + mid_chg_div6 { + reg = ; + label = "chg_mid"; + qcom,pre-scaling = <1 6>; + }; + + usb_in_i_uv { + reg = ; + label = "usb_in_i_uv"; + qcom,pre-scaling = <1 1>; + }; + + usb_in_v_div_16 { + reg = ; + label = "usb_in_v_div_16"; + qcom,pre-scaling = <1 16>; + }; +}; + +&pm8150_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + vcoin { + reg = ; + label = "vcoin"; + qcom,pre-scaling = <1 3>; + }; + + xo_therm { + reg = ; + label = "xo_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + quiet_therm { + reg = ; + label = "quiet_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + pa_therm0 { + reg = ; + label = "pa_therm0"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm8150l_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + cam_therm0 { + reg = ; + label = "camera_flash_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + cam_therm1 { + reg = ; + label = "skin_msm_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + pa_therm1 { + reg = ; + label = "pa_therm1"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + hw_version_gpio5 { + reg = ; + label = "hw_version_gpio5"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + project_gpio6 { + reg = ; + label = "project_gpio6"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm8150b_adc_tm { + io-channels = <&pm8150b_vadc ADC_AMUX_THM1_PU2>, + <&pm8150b_vadc ADC_AMUX_THM2_PU2>; + wp_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + pm8150b-wp-therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm8150_adc_tm { + xo_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + quiet_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + pa_therm0 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm8150l_adc_tm { + cam_therm0 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + cam_therm1 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + pa_therm1 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&thermal_zones { + wp_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150b_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + xo_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_XO_THERM_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + quiet_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + pa_therm0 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_AMUX_THM2_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + cam_therm0 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + cam_therm1 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM2_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + pa_therm1 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM3_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; +}; + +&pm8150b_haptics { + qcom,actuator-type = "erm"; + qcom,vmax-mv = <3000>; + + wf_0 { + /* CLICK */ + qcom,effect-id = <0>; + qcom,wf-vmax-mv = <3000>; + qcom,wf-pattern = [3e 3e 3e]; + qcom,wf-brake-pattern = [01 00 00 00]; + qcom,lra-auto-resonance-disable; + }; + wf_1 { + /* DOUBLE CLICK */ + qcom,effect-id = <1>; + qcom,wf-vmax-mv = <3000>; + qcom,wf-pattern = [7e 7e 02 02 02 02 02 02]; + qcom,wf-repeat-count = <2>; + qcom,wf-s-repeat-count = <1>; + qcom,lra-auto-resonance-disable; + }; + wf_2 { + /* TICK */ + qcom,effect-id = <2>; + qcom,wf-vmax-mv = <3000>; + qcom,wf-pattern = [7e 7e]; + qcom,lra-auto-resonance-disable; + }; + wf_3 { + /* THUD */ + qcom,effect-id = <3>; + qcom,wf-vmax-mv = <3000>; + qcom,wf-pattern = [7e 7e 7e]; + qcom,lra-auto-resonance-disable; + }; + wf_4 { + /* POP */ + qcom,effect-id = <4>; + qcom,wf-vmax-mv = <3000>; + qcom,wf-pattern = [7e 7e]; + qcom,lra-auto-resonance-disable; + }; + wf_5 { + /* HEAVY CLICK */ + qcom,effect-id = <5>; + qcom,wf-vmax-mv = <3000>; + qcom,wf-pattern = [7e 7e 7e]; + qcom,wf-brake-pattern = [03 00 00 00]; + qcom,lra-auto-resonance-disable; + }; +}; + +&pm8150l_lpg { + qcom,lut-pattern-switch; + qcom,lut-patterns = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 + 12 11 10 9 8 7 6 5 4 3 2 1 0>; + qcom,lut-patterns-camera = <0 1 3 5 8 10 12 15 18 22 26 32 38 44 50 60 72 82 90 96 98 99 100 + 99 98 96 90 82 72 60 50 44 38 32 26 22 18 15 12 10 8 5 3 1 0>; +}; + +&pwm_lpg2 { + qcom,lpg-chan-id = <2>; + qcom,ramp-step-ms = <70>; + qcom,ramp-pause-hi-count = <2>; + qcom,ramp-pause-lo-count = <30>; + qcom,ramp-low-index = <0>; + qcom,ramp-high-index = <26>; + qcom,ramp-from-low-to-high; + qcom,ramp-pattern-repeat; +}; + +&pwm_lpg3 { + qcom,lpg-chan-id = <3>; + qcom,ramp-step-ms = <70>; + qcom,ramp-pause-hi-count = <2>; + qcom,ramp-pause-lo-count = <30>; + qcom,ramp-low-index = <0>; + qcom,ramp-high-index = <26>; + qcom,ramp-from-low-to-high; + qcom,ramp-pattern-repeat; +}; + +&red_led { + status = "disabled"; +}; + +&pm8150l_wled { + qcom,string-cfg= <15>;// if use 2 string, the number is 3 + qcom,leds-per-string = <5>; + status = "ok"; +}; + +&sde_dsi { + vcie-supply = <&disp_vci_vreg>; +}; + +&soc { + ssc_sensors: qcom,msm-ssc-sensors { + compatible = "qcom,msm-ssc-sensors"; + status = "ok"; + qcom,firmware-name = "slpi_rp"; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-audio-overlay.dtsi new file mode 100644 index 000000000000..932345af8fc4 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-audio-overlay.dtsi @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include "../common/sm8150-audio-overlay.dtsi" + +&snd_934x { + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "MADINPUT", "MCLK", + "hifi amp", "LINEOUT1", + "hifi amp", "LINEOUT2", + "AMIC2", "MIC BIAS2", + "MIC BIAS2", "Headset Mic", + "AMIC3", "MIC BIAS3", + "MIC BIAS3", "ANCRight Headset Mic", + "AMIC1", "MIC BIAS1", + "MIC BIAS1", "ANCLeft Headset Mic", + "AMIC4", "MIC BIAS1", + "MIC BIAS1", "ANCRight Headset Mic", + "AMIC5", "MIC BIAS4", + "MIC BIAS4", "Analog Mic5"; + + qcom,wsa-max-devs = <0>; + qcom,msm-mbhc-hphl-swh = <1>; + qcom,msm-mbhc-gnd-swh = <1>; + qcom,msm-mbhc-usbc-audio-supported = <0>; + qcom,msm-mbhc-hs-mic-max-threshold-mv = <2600>; + qcom,msm-mbhc-hs-mic-min-threshold-mv = <50>; +}; + +&wcd934x_cdc { + qcom,cdc-micbias1-mv = <2700>; + qcom,cdc-micbias2-mv = <2700>; + qcom,cdc-micbias3-mv = <2700>; + qcom,cdc-micbias4-mv = <2700>; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-pinctrl.dtsi new file mode 100644 index 000000000000..4909875dcadf --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-pinctrl.dtsi @@ -0,0 +1,617 @@ +/*for xiaomi pinctrl*/ +&tlmm { + qupv3_se17_spi_pins: qupv3_se17_spi_pins { + qupv3_se17_spi_active: qupv3_se17_spi_active { + mux { + pins = "gpio55", "gpio56", "gpio57"; + function = "qup17"; + }; + + config { + pins = "gpio55", "gpio56", "gpio57"; + drive-strength = <6>; + bias-disable; + }; + }; + + qupv3_se17_spi_sleep: qupv3_se17_spi_sleep { + mux { + pins = "gpio55", "gpio56", "gpio57"; + function = "gpio"; + }; + + config { + pins = "gpio55", "gpio56", "gpio57"; + drive-strength = <6>; + bias-disable; + }; + }; + }; + + + bq2597x { + bq2597x_master_int_default: bq2597x_master_int_default { + /* active state */ + mux { + /* GPIO 10 is used for bq25970 master ic interrupt usage */ + pins = "gpio10"; + function = "gpio"; + }; + + config { + pins = "gpio10"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + + bq2597x_master_int_suspend: bq2597x_master_int_suspend { + /* sleep state */ + mux { + /* GPIO 10 is used for bq25970 master ic interrupt usage */ + pins = "gpio10"; + function = "gpio"; + }; + + config { + pins = "gpio10"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + input-enable; + }; + }; + }; + + onewire_gpio_active: onewire_gpio_active { + mux { + pins = "gpio21"; + function = "gpio"; + }; + + config { + pins = "gpio21"; + drive-strength = <2>; + bias-pull-up; /* No PULL */ + }; + }; + + onewire_gpio_sleep: onewire_gpio_sleep { + mux { + pins = "gpio21"; + function = "gpio"; + }; + + config { + pins = "gpio21"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pmx_ts_active { + ts_active: ts_active { + mux { + pins = "gpio122", "gpio12"; + function = "gpio"; + }; + config { + pins = "gpio122", "gpio12"; + drive-strength = <8>; + bias-pull-up; + }; + }; + }; + + pmx_ts_int_suspend { + ts_int_suspend: ts_int_suspend { + mux { + pins = "gpio122"; + function = "gpio"; + }; + config { + pins = "gpio122"; + drive-strength = <2>; + bias-pull-down; + input-enable; + }; + }; + }; + + pmx_ts_reset_suspend { + ts_reset_suspend: ts_reset_suspend { + mux { + pins = "gpio12"; + function = "gpio"; + }; + config { + pins = "gpio12"; + drive-strength = <2>; + bias-disable; + output-low; + }; + }; + }; + + adc2_switch_gpio_ctrl { + adc2_switch_gpio_idle: adc2_switch_idle { + mux { + pins = "gpio142"; + function = "gpio"; + }; + config { + pins = "gpio142"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + adc2_switch_gpio_active: adc2_switch_active { + mux { + pins = "gpio142"; + function = "gpio"; + }; + config { + pins = "gpio142"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + + sbu_uart_en_ctrl { + sbu_uart_en_idle: uart_audio_en_idle { + mux { + pins = "gpio25"; + function = "gpio"; + }; + config { + pins = "gpio25"; + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + sbu_uart_en_active: uart_audio_en_active { + mux { + pins = "gpio25"; + function = "gpio"; + }; + config { + pins = "gpio25"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + }; + + + pcie1 { + pcie1_wake_default: pcie1_wake_default { + mux { + pins = "gpio114"; + function = "gpio"; + }; + + config { + pins = "gpio114"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + nfc { + nfc_int_active: nfc_int_active { + /* active state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_int_suspend: nfc_int_suspend { + /* sleep state */ + mux { + /* GPIO 47 NFC Read Interrupt */ + pins = "gpio47"; + function = "gpio"; + }; + + config { + pins = "gpio47"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_active: nfc_enable_active { + /* active state */ + mux { + /* 41: NFC ENABLE 42:ESE Enable */ + pins = "gpio48", "gpio102"; + function = "gpio"; + }; + + config { + pins = "gpio48", "gpio102"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_enable_suspend: nfc_enable_suspend { + /* sleep state */ + mux { + /* 41: NFC ENABLE 42:ESE Enable */ + pins = "gpio48", "gpio102"; + function = "gpio"; + }; + + config { + pins = "gpio48", "gpio102"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + + nfc_clk_req_active: nfc_clk_req_active { + /* active state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-pull-up; + }; + }; + + nfc_clk_req_suspend: nfc_clk_req_suspend { + /* sleep state */ + mux { + /* 113: NFC CLOCK REQUEST */ + pins = "gpio113"; + function = "gpio"; + }; + + config { + pins = "gpio113"; + drive-strength = <2>; /* 2 MA */ + bias-disable; + }; + }; + }; + cam_sensor_active_macro: cam_sensor_active_macro { + /* RESET macro */ + mux { + pins = "gpio27", "gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio27", "gpio94"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_suspend_macro: cam_sensor_suspend_macro { + /* RESET MACRO */ + mux { + pins = "gpio27", "gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio27", "gpio94"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + test_mode_ctrl_irq { + ant_sub_ctrl_irq: ant_sub_ctrl_irq { + mux { + pins = "gpio81"; + function = "gpio"; + }; + config { + pins = "gpio81"; + drive-strength = <2>; + bias-pull-up; + input-enable; + }; + }; + ant_top_ctrl_irq: ant_top_ctrl_irq { + mux { + pins = "gpio133"; + function = "gpio"; + }; + config { + pins = "gpio133"; + drive-strength = <2>; + bias-pull-up; + input-enable; + }; + }; + }; +}; + +//camera voltage start +&cam_sensor_mclk0_active { + /* MCLK0 */ + mux { + pins = "gpio13"; + function = "cam_mclk"; + }; + + config { + pins = "gpio13"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk0_suspend { + /* MCLK0 */ + mux { + pins = "gpio13"; + function = "cam_mclk"; + }; + + config { + pins = "gpio13"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk1_active { + /* MCLK1 */ + mux { + pins = "gpio14"; + function = "cam_mclk"; + }; + + config { + pins = "gpio14"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk1_suspend { + /* MCLK1 */ + mux { + pins = "gpio14"; + function = "cam_mclk"; + }; + + config { + pins = "gpio14"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk2_active { + /* MCLK2 */ + mux { + pins = "gpio15"; + function = "cam_mclk"; + }; + + config { + pins = "gpio15"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk2_suspend { + /* MCLK2 */ + mux { + pins = "gpio15"; + function = "cam_mclk"; + }; + + config { + pins = "gpio15"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk3_active { + /* MCLK3 */ + mux { + pins = "gpio16"; + function = "cam_mclk"; + }; + + config { + pins = "gpio16"; + bias-disable; /* No PULL */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_mclk3_suspend { + /* MCLK3 */ + mux { + pins = "gpio16"; + function = "cam_mclk"; + }; + + config { + pins = "gpio16"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <4>; /* 2 MA */ + }; +}; + +&cam_sensor_active_rear { + /* RESET REAR2 */ + mux { + pins = "gpio30", "gpio59"; + function = "gpio"; + }; + + config { + pins = "gpio30", "gpio59"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_rear { + /* RESET REAR2 */ + mux { + pins = "gpio30", "gpio59"; + function = "gpio"; + }; + + config { + pins = "gpio30", "gpio59"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +&cam_sensor_active_rear_aux { + /* RESET REARAUX, VANA REARAUX */ + mux { + pins = "gpio23", "gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio94"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_rear_aux { + /* RESET REARAUX, VANA REARAUX */ + mux { + pins = "gpio23", "gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio23", "gpio94"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +&cam_sensor_active_front { + /* RESET FRONT, VANA FRONT*/ + mux { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio54","gpio118"; + function = "gpio"; + }; + + config { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio54","gpio118"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_front { + /* RESET FRONT, VANA FRONT*/ + mux { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio54","gpio118"; + function = "gpio"; + }; + + config { + //pins = "gpio54","gpio132","gpio118"; + pins = "gpio54","gpio118"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +&cam_sensor_active_iris { + /* RESET ULTRA, VANA VDIG ULTRA*/ + mux { + pins = "gpio28","gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio28","gpio94"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_iris { + /* RESET ULTRA, VANA VDIG ULTRA*/ + mux { + pins = "gpio28","gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio28","gpio94"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; +&cam_sensor_active_macro { + /* RESET ULTRA, VANA VDIG ULTRA*/ + mux { + pins = "gpio27","gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio27","gpio94"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_suspend_macro { + /* RESET ULTRA, VANA VDIG ULTRA*/ + mux { + pins = "gpio27","gpio94"; + function = "gpio"; + }; + + config { + pins = "gpio27","gpio94"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; +}; + +//camera voltage end diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150-camera-sensor-mtp.dtsi new file mode 100644 index 000000000000..0919672f22d8 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150-camera-sensor-mtp.dtsi @@ -0,0 +1,507 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +&soc { + led_flash_rear: qcom,camera-flash@0 { + cell-index = <0>; + reg = <0x00 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch2>; + status = "ok"; + }; + + led_flash_rear_aux1: qcom,camera-flash@1 { + cell-index = <1>; + reg = <0x01 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch2>; + status = "ok"; + }; + + led_flash_front: qcom,camera-flash@2 { + cell-index = <2>; + reg = <0x02 0x00>; + compatible = "qcom,camera-flash"; + wled-flash-support; + flash-source = <&wled_flash>; + torch-source = <&wled_torch>; + switch-source = <&wled_switch>; + status = "ok"; + }; + + led_flash_rear_aux2: qcom,camera-flash@3 { + cell-index = <3>; + reg = <0x03 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pm8150l_flash0 &pm8150l_flash1>; + torch-source = <&pm8150l_torch0 &pm8150l_torch1>; + switch-source = <&pm8150l_switch2>; + status = "ok"; + }; + + actuator_rear_regulator: gpio-regulator@1 { + compatible = "regulator-fixed"; + reg = <0x01 0x00>; + regulator-name = "actuator_rear_regulator"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&tlmm 24 0>; + vin-supply = <&pm8150l_bob>; + }; + +}; + +&cam_cci0 { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + status = "ok"; + }; + + actuator_rear: qcom,actuator@0 { + cell-index = <0>; + reg = <0x0>; + compatible = "qcom,actuator"; + cci-device = <0>; + cci-master = <1>; + cam_vaf-supply = <&actuator_rear_regulator>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + eeprom_rear: qcom,eeprom@0 { + cell-index = <0>; + reg = <0>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pm8150l_l1>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio","cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <1000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rear>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rear>; + gpios = <&tlmm 14 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK0"; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + + }; + + eeprom_front: qcom,eeprom@2 { + cell-index = <2>; + reg = <0x2>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pm8150l_l1>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio","cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <1000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_front>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_front>; + gpios = <&tlmm 13 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK2"; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + + }; + //imx582 + qcom,cam-sensor@0 { + cell-index = <0>; + compatible = "qcom,cam-sensor"; + reg = <0x0>; + csiphy-sd-index = <1>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + led-flash-src = <&led_flash_rear>; + actuator-src = <&actuator_rear>; + eeprom-src = <&eeprom_rear>; + cam_vio-supply = <&pm8150l_l1>; + cam_vana-supply = <&pm8150_s5>; + cam_vdig-supply = <&pm8150l_s8>; + cam_clk-supply = <&titan_top_gdsc>; + cam_v_custom2-supply = <&pm8150l_bob>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk", "cam_v_custom2"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 1904000 1352000 0 3008000>; + rgltr-max-voltage = <1800000 2040000 1352000 0 4000000>; + rgltr-load-current = <180000 112000 120000 0 80000>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_active_rear>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_suspend_rear>; + gpios = <&tlmm 14 0>, + <&tlmm 30 0>, + <&tlmm 59 0>; + gpio-reset = <1>; + gpio-vdig = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VDIG0"; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + //s5k3t2 + qcom,cam-sensor@2 { + cell-index = <2>; + compatible = "qcom,cam-sensor"; + reg = <0x2>; + csiphy-sd-index = <2>; + sensor-position-roll = <270>; + sensor-position-pitch = <0>; + sensor-position-yaw = <0>; + eeprom-src = <&eeprom_front>; + cam_vio-supply = <&pm8150l_l1>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150l_s8>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 3008000 1352000 0>; + rgltr-max-voltage = <1800000 4000000 1352000 0>; + rgltr-load-current = <1000 80000 120000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_active_front>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_suspend_front>; + gpios = <&tlmm 13 0>, + <&tlmm 54 0>, + <&tlmm 118 0>; + gpio-reset = <1>; + gpio-vdig = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_VDIG2"; + sensor-mode = <0>; + cci-device = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; +}; + +&cam_cci1 { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + status = "ok"; + }; + + eeprom_rear_aux: qcom,eeprom@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pm8150l_l1>; + cam_vana-supply = <&pm8150l_bob>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 3008000 0>; + rgltr-max-voltage = <1800000 4000000 0>; + rgltr-load-current = <180000 80000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_rear_aux>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_rear_aux>; + gpios = <&tlmm 15 0>, + <&tlmm 23 0>, + <&tlmm 94 0>, + <&tlmm 125 0>; + gpio-reset = <1>; + gpio-vana = <2>; + gpio-standby = <3>; + gpio-req-tbl-num = <0 1 2 3>; + gpio-req-tbl-flags = <1 0 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_VANA1", + "CAM_PWDN1"; + sensor-mode = <0>; + cci-device = <1>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + + }; + + eeprom_rear_ultra: qcom,eeprom@3 { + cell-index = <3>; + reg = <0x3>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pm8150l_l1>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <1000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_iris>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_iris>; + gpios = <&tlmm 16 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK3"; + sensor-mode = <0>; + cci-device = <1>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + eeprom_rear_macro: qcom,eeprom@4 { + cell-index = <4>; + reg = <0x4>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pm8150l_l1>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <180000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_macro>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_macro>; + gpios = <&tlmm 16 0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <1>; + gpio-req-tbl-label = "CAMIF_MCLK4"; + sensor-mode = <0>; + cci-device = <1>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + + //ov02b1b + qcom,cam-sensor@1 { + cell-index = <1>; + compatible = "qcom,cam-sensor"; + reg = <0x1>; + csiphy-sd-index = <3>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_rear_aux>; + cam_vio-supply = <&pm8150l_l1>; + cam_vana-supply = <&pm8150l_bob>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 3008000 0>; + rgltr-max-voltage = <1800000 4000000 0>; + rgltr-load-current = <180000 80000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_active_rear_aux>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_suspend_rear_aux>; + gpios = <&tlmm 15 0>, + <&tlmm 23 0>, + <&tlmm 94 0>, + <&tlmm 125 0>; + gpio-reset = <1>; + gpio-vana = <2>; + gpio-standby = <3>; + gpio-req-tbl-num = <0 1 2 3>; + gpio-req-tbl-flags = <1 0 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_VANA1", + "CAM_PWDN1"; + sensor-mode = <0>; + cci-device = <1>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK2_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + //ov8856 + qcom,cam-sensor@3 { + cell-index = <3>; + compatible = "qcom,cam-sensor"; + reg = <0x3>; + csiphy-sd-index = <0>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_rear_ultra>; + led-flash-src = <&led_flash_rear_aux1>; + cam_vio-supply = <&pm8150l_l1>; + cam_vana-supply = <&pm8150l_bob>; + cam_vdig-supply = <&pm8150l_s8>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 3008000 1352000 0>; + rgltr-max-voltage = <1800000 4000000 1352000 0>; + rgltr-load-current = <1000 80000 12000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_iris>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_iris>; + gpios = <&tlmm 16 0>, + <&tlmm 28 0>, + <&tlmm 94 0>; + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK3", + "CAM_RESET3", + "CAM_VANA3"; + sensor-mode = <0>; + cci-device = <1>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; + //hi259 + qcom,cam-sensor@4 { + cell-index = <4>; + compatible = "qcom,cam-sensor"; + reg = <0x4>; + csiphy-sd-index = <3>; + sensor-position-roll = <90>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_rear_macro>; + led-flash-src = <&led_flash_rear_aux2>; + cam_vio-supply = <&pm8150l_l1>; + cam_vana-supply = <&pm8150l_bob>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_clk"; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000 3008000 0>; + rgltr-max-voltage = <1800000 4000000 0>; + rgltr-load-current = <180000 112000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_active_macro>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_suspend_macro>; + gpios = <&tlmm 16 0>, + <&tlmm 27 0>, + <&tlmm 94 0>, + <&tlmm 84 0>; + gpio-reset = <1>; + gpio-vana = <2>; + gpio-standby = <3>; + gpio-req-tbl-num = <0 1 2 3>; + gpio-req-tbl-flags = <1 0 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK4", + "CAM_RESET4", + "CAM_VANA4", + "CAM_PWDN4"; + sensor-mode = <0>; + cci-device = <1>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <19200000>; + }; +}; + + diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi new file mode 100644 index 000000000000..795454af9060 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi @@ -0,0 +1,1979 @@ +/* +this file is for attribution only of vayu +And public attribution of xiaomi platforms(like J20S and so and) +*/ +#include "vayu-pinctrl.dtsi" +#include "../common/xiaomi-sm8150-common.dtsi" +#include "vayu-sm8150-camera-sensor-mtp.dtsi" + +&ufshc_mem { + vcc-voltage-level = <2504000 2950000>; + vcc-low-voltage-sup; + qcom,vccq-parent-supply = <&pm8150l_s8>; + qcom,vccq-parent-max-microamp = <210000>; + vccq-supply = <&pm8150_l9>; + vccq-max-microamp = <700000>; +}; + +#include "../common/smb1390.dtsi" + + + +&pm8150b_fg { + qcom,battery-data = <&vayu_batterydata>; + qcom,rapid-soc-dec-en; + qcom,soc-scale-mode-en; + qcom,five-pin-battery; + qcom,soc-hi-res; + qcom,soc_decimal_rate = < + 0 38 + 10 35 + 20 33 + 30 33 + 40 33 + 50 33 + 60 33 + 70 30 + 80 25 + 90 20 + 95 10 >; + qcom,ki-coeff-low-chg = <315>; + qcom,ki-coeff-med-chg = <183>; + qcom,fg-sys-term-current = <(-300)>; + qcom,fg-ffc-sys-term-current = <(-1160)>; + qcom,fg-cutoff-voltage = <3400>; + qcom,fg-cutoff-current = <200>; + qcom,fg-empty-voltage = <3100>; + qcom,soc-scale-vbatt-mv = <3600>; + qcom,fg-batt-temp-delta = <6>; + qcom,fg-force-load-profile; + qcom,shutdown-delay-enable; + /* ESR fast calibration */ + qcom,fg-esr-timer-chg-fast = <0 7>; + qcom,fg-esr-timer-dischg-fast = <0 7>; + qcom,fg-esr-timer-chg-slow = <0 96>; + qcom,fg-esr-timer-dischg-slow = <0 96>; + qcom,fg-esr-cal-soc-thresh = <26 230>; + qcom,fg-esr-cal-temp-thresh = <10 40>; + qcom,ki-coeff-chg-med-hi-thresh-ma = <1000>; + qcom,ki-coeff-chg-low-med-thresh-ma = <500>; + qcom,ffc-ki-coeff-chg-med-hi-thresh-ma = <3900>; + qcom,ffc-ki-coeff-chg-low-med-thresh-ma = <3500>; +}; + +&pm8150b_charger { + qcom,sec-charger-config = <0>; + qcom,usb-icl-ua = <3000000>; + qcom,fcc-max-ua = <5900000>; + qcom,fv-max-uv = <4475000>; + qcom,non-fcc-fv-max-uv = <4450000>; + //qcom,chg-warm-th= <450>; + //qcom,chg-cool-th= <150>; + qcom,auto-recharge-soc = <99>; + qcom,chg-term-src = <1>; + qcom,chg-term-current-ma = <(-200)>; + mi,use-bq-pump; + qcom,usbpd-phandle = <&pm8150b_pdphy>; + qcom,battery-data = <&vayu_batterydata>; + //mi,six-pin-step-chg-params = <4250000 6000000 + // 4450000 5400000 + // 4480000 4000000>; + //mi,six-pin-step-chg; + //mi,six-pin-soc-th = <45>; + mi,fcc-batt-unverify-ua = <2000000>; + mi,support-ffc; + qcom,disable-suspend-on-collapse; + qcom,thermal-mitigation = <3000000 2800000 2600000 2400000 2200000 2100000 2000000 + 1800000 1600000 1500000 1400000 1200000 1000000 900000 + 800000 500000>; + qcom,thermal-mitigation-icl + = <2800000 2700000 2600000 2400000 2200000 2100000 2000000 + 2000000 2000000 2000000 2000000 2000000 2000000 2000000 + 2000000 2000000>; + qcom,thermal-mitigation-dcp + = <1800000 1800000 1800000 1800000 1800000 1800000 1800000 + 1800000 1800000 1700000 1600000 1400000 1200000 1100000 + 1100000 1000000>; + qcom,thermal-mitigation-qc2 + = <1500000 1500000 1500000 1500000 1450000 1400000 1350000 + 1300000 1150000 1100000 1000000 900000 850000 750000 + 650000 500000>; + qcom,thermal-fcc-qc3-normal + = <3200000 3000000 2800000 2600000 2500000 2400000 2300000 + 2200000 2100000 1800000 1600000 1400000 1200000 1000000 + 750000 750000>; + qcom,thermal-fcc-qc3-cp + = <3600000 3600000 3600000 3600000 3200000 3200000 3200000 + 3200000 3100000 2800000 2400000 2200000 2000000 1300000 + 750000 300000>; + qcom,thermal-fcc-qc3-classb-cp + = <4800000 4700000 4600000 4500000 4400000 4200000 4200000 + 4200000 4000000 3600000 3400000 3200000 3000000 2200000 + 1000000 300000>; + qcom,thermal-mitigation-pd-base + = <3000000 2800000 2600000 2500000 2500000 2500000 2500000 + 2500000 2500000 2400000 2200000 2000000 1600000 1300000 + 1000000 500000>; + qcom,thermal-fcc-pps-cp + = <4800000 4700000 4600000 4500000 4400000 4200000 4200000 + 4200000 4000000 3600000 3400000 3200000 3000000 2200000 + 1000000 300000>; + qcom,thermal-fcc-pps-bq + = <6000000 5700000 5475000 5250000 5025000 4800000 4575000 + 4350000 4100000 3500000 3000000 2400000 2000000 1500000 + 1000000 500000>; + qcom,thermal-fcc-qc3-cp + = <4800000 4600000 4400000 4200000 4000000 3800000 3600000 + 3400000 3000000 2600000 2400000 2200000 2000000 1300000 + 1000000 300000>; + qcom,thermal-fcc-qc3-classb-cp + = <5100000 4700000 4300000 4000000 3600000 3500000 3400000 + 3400000 3400000 3200000 2500000 2200000 2000000 1300000 + 1000000 300000>; + qcom,thermal-mitigation-pd-base + = <3000000 2800000 2600000 2400000 2200000 2000000 1800000 + 1600000 1600000 1400000 1200000 1100000 1050000 1000000 + 950000 500000>; + qcom,thermal-mitigation-voice + = <6000000 2200000 2200000 1000000 1000000 800000 800000 + 800000 800000 700000 700000 600000 600000 600000 + 500000 400000>; + + + io-channels = <&pm8150b_vadc ADC_MID_CHG_DIV6>, + <&pm8150b_vadc ADC_USB_IN_V_16>, + <&pm8150b_vadc ADC_USB_IN_I>, + <&pm8150b_vadc ADC_SBUx>, + <&pm8150b_vadc ADC_VPH_PWR>, + <&pm8150b_vadc ADC_CHG_TEMP>; + io-channel-names = "mid_voltage", + "usb_in_voltage", + "usb_in_current", + "sbux_res", + "vph_voltage", + "chg_temp"; +// qcom,battery-data = <&mtp_batterydata>; + dpdm-supply = <&usb2_phy0>; + qcom,distinguish-qc-class-ab; + qcom,lpd-disable; + qcom,sw-jeita-enable; + qcom,step-charging-enable; + qcom,wd-bark-time-secs = <16>; +}; + +&ext_5v_boost { + status = "disable"; +}; + +&pm8150b_pdphy { + mi,non-qcom-pps-ctrl; +}; + +&qupv3_se4_i2c { + #address-cells = <1>; + #size-cells = <0>; + status = "ok"; + bq25970-standalone@66 { + compatible = "ti,bq2597x-standalone"; + reg = <0x66>; + interrupt-parent = <&tlmm>; + interrupts = <10 0x2002>; + pinctrl-names = "default"; + pinctrl-0 = <&bq2597x_master_int_default &bq2597x_master_int_suspend>; + + /*ti,bq2597x,bat-ovp-disable;*/ + ti,bq2597x,bat-ovp-alarm-disable; + ti,bq2597x,bat-ocp-disable; + ti,bq2597x,bat-ocp-alarm-disable; + ti,bq2597x,bat-ucp-alarm-disable; + ti,bq2597x,bat-ucp-disable; + + /*ti,bq2597x,bus-ovp-alarm-disable; + ti,bq2597x,bus-ocp-disable; + ti,bq2597x,bus-ocp-alarm-disable;*/ + ti,bq2597x,bat-therm-disable; + ti,bq2597x,bus-therm-disable; + ti,bq2597x,die-therm-disable; + + ti,bq2597x,bat-ovp-threshold = <4550>; + ti,bq2597x,bat-ovp-alarm-threshold = <4525>; + //ti,bq2597x,bat-ocp-threshold = <8000>; + //ti,bq2597x,bat-ocp-alarm-threshold = <7500>; + + ti,bq2597x,bus-ovp-threshold = <12000>; + ti,bq2597x,bus-ovp-alarm-threshold = <11000>; + ti,bq2597x,bus-ocp-threshold = <3750>; + ti,bq2597x,bus-ocp-alarm-threshold = <3500>; + + //ti,bq2597x,bat-ucp-alarm-threshold = <2000>; + + ti,bq2597x,bat-therm-threshold = <0x15>;/*4.1%*/ + ti,bq2597x,bus-therm-threshold = <0x15>;/*4.1%*/ + ti,bq2597x,die-therm-threshold = <145>; + + ti,bq2597x,ac-ovp-threshold = <14>; + //ti,bq2597x,sense-resistor-mohm = <2>; + + }; +}; + +&soc { + cp_qc30 { + compatible = "xiaomi,cp-qc30"; + status = "ok"; + mi,qc3-bat-volt-max = <4420>; + mi,qc3-bat-curr-max = <3600>; + mi,qc3-bus-volt-max = <12000>; + mi,qc3-bus-curr-max = <2100>; + mi,qc3-battery-warm-th = <450>; + mi,use-qcom-gauge; + //mi,cp-sec-enable; + }; + + usbpd_pm { + compatible = "xiaomi,usbpd-pm"; + status = "ok"; + mi,pd-bat-volt-max = <4500>; + mi,pd-ffc-bat-volt-max = <4480>; + mi,pd-bat-curr-max = <6000>; + mi,pd-bus-volt-max = <12000>; + mi,pd-bus-curr-max = <3000>; + mi,pd-non-ffc-bat-volt-max = <4450>; + mi,pd-bus-curr-compensate = <0>; + mi,pd-battery-warm-th = <450>; + mi,use-qcom-gauge; + //mi,cp-sec-enable; + }; + + onewire_gpio: onewire_gpio { + compatible = "xiaomi,onewire_gpio"; + label = "xm_onewire"; + xiaomi,version = <1>; + xiaomi,ow_gpio = <&tlmm 21 0x00>; + mi,onewire-gpio-cfg-addr = <0x03515000 0x4>; + xiaomi,gpio_number = <21>; + pinctrl-names = "onewire_active", "onewire_sleep"; + pinctrl-0 = <&onewire_gpio_active>; + pinctrl-1 = <&onewire_gpio_sleep>; + status = "ok"; + }; + vayu_batterydata: qcom,battery-data { + qcom,batt-id-range-pct = <15>; + #include "../common/battery/fg-gen4-batterydata-vayu-NVT-5160mah.dtsi" + #include "../common/battery/fg-gen4-batterydata-vayu-sunwoda-5160mah.dtsi" + }; + + maxim_ds28e16: maxim_ds28e16 { + compatible = "maxim,ds28e16"; + label = "max_ds28e16"; + maxim,version = <1>; + status = "ok"; + }; + + simtray { + compatible = "xiaomi,simtray-status"; + status-gpio = <&tlmm 112 0x00>; + }; +}; + +&qupv3_se4_i2c { + status = "ok"; + tas2557@4c { + status = "disabled"; + compatible = "ti,tas2557"; + reg = <0x4c>; + //ti,cdc-reset-gpio = <&tlmm 59 0>; + ti,irq-gpio = <&tlmm 60 0>; + ti,i2s-bits = <16>; + ti,bypass-tmax = <0>; + }; + + fsa4480@43 { + status = "disabled"; + }; + + cs35l41@40 { + status = "disabled"; + #sound-dai-cells = <1>; + compatible = "cirrus,cs35l41"; + cs,cdc-reset-gpio = <&tlmm 89 0x01>; + reg = <0x40>; + pinctrl-names = "cs35l41_irq_default"; + pinctrl-0 = <&cs35l41_int_default>; + interrupt-parent = <&tlmm>; + interrupts = <10 8>; + + cirrus,temp-warn_threshold = <3>; + cirrus,boost-peak-milliamp = <4000>; + cirrus,boost-ind-nanohenry = <1000>; + cirrus,boost-cap-microfarad = <15>; + cirrus,gpio-config2 { + cirrus,gpio-src-select = <0x4>; + cirrus,gpio-output-enable; + }; +/* + VA-supply = <&dummy_vreg>; + VP-supply = <&dummy_vreg>; + interrupt-parent = <&tlmm>; + interrupts = <11 8>; + reset-gpios = <&tlmm 7 0x01>; + VA-supply = <&pm8998_s4>; + VP-supply = <&audio_vsys>; + cirrus,boost-peak-milliamp = <4500>; + cirrus,boost-ind-nanohenry = <1000>; + cirrus,boost-cap-microfarad = <15>; + cirrus,gpio-config2 { + cirrus,gpio-src-select = <0x4>; + cirrus,gpio-output-enable; + }; +*/ + }; +}; + +&qupv3_se7_i2c { + status = "ok"; + tas256x:tas256x@4c { + #sound-dai-cells = <0>; + compatible = "ti,tas256x";/*or "ti,tas2564" or "ti,tas256x" */ + reg = <0x4c>;//register tas256x_i2c_driver + ti,left-channel = <0x4d>; //receiver address + ti,right-channel = <0x4c>; //speaker address + ti,channels = <2>; /* channel number */ + ti,reset-gpio = <&tlmm 89 0>; //SPKR_RST1 + ti,reset-gpio2 = <&tlmm 92 0>; //SPKR_RST2 + pinctrl-names = "default"; + //pinctrl-0 = <&reset_stat_default>; + //ti,reset-gpio = <&pm6150l_gpios 8 GPIO_ACTIVE_LOW>; + ti,irq-gpio = <&tlmm 90 0>;//spkr_int1 left + ti,irq-gpio2 = <&tlmm 91 0>;//spkr_int2 right + status = "ok"; + ti,iv-width = <16>; + ti,vbat-mon = <0>; + }; +}; + +&smb1390 { + status = "disabled"; +}; + +&smb1390_charger { + status = "disabled"; +}; + +&usb0 { + dwc3@a600000 { + usb-phy = <&usb2_phy0>, <&usb_nop_phy>; + maximum-speed = "high-speed"; + }; +}; + +&usb2_phy0 { + qcom,param-override-seq = + <0x84 0x70 + 0x2c 0x74>; +}; + +&usb_qmp_dp_phy { + status = "disabled"; +}; + +&usb1 { + extcon = <&extcon_usb1>; + status = "disabled"; +}; + +&usb2_phy1 { + status = "disabled"; +}; + +&usb_qmp_phy { + status = "disabled"; +}; + +&soc { + touch_vddio_vreg: touch_vddio_vreg { + compatible = "regulator-fixed"; + regulator-name = "disp_vddio_vreg"; + startup-delay-us = <4000>; + enable-active-high; + regulator-boot-on; + gpio = <&tlmm 100 0>; + }; + + vdd_boost_vreg: vdd_boost_vreg { + compatible = "regulator-fixed"; + regulator-name = "vdd_boost_vreg"; + startup-delay-us = <4000>; + enable-active-high; + regulator-always-on; + gpio = <&pm8150b_gpios 5 0>; + }; + + disp_vci_vreg: disp_vci_vreg { + compatible = "regulator-fixed"; + regulator-name = "disp_vci_vreg"; + start-delay-us = <4000>; + enable-active-high; + regulator-boot-on; + gpio = <&tlmm 21 0>; + }; + + fingerprint_goodix { + compatible = "goodix,fingerprint"; + goodix,gpio-reset = <&tlmm 37 0x0>; + goodix,gpio-irq = <&tlmm 120 0x0>; + //goodix.gpio_pwr = <&tlmm 125 0x0>; + //fp_vdd_vreg = <&pm8150l_l7>; + status = "ok"; + }; + + + fingerprint_fpc { + compatible = "fpc,fpc1020"; + fpc,gpio_rst = <&tlmm 37 0x0>; + fpc,gpio_irq = <&tlmm 120 0x0>; + pinctrl-names = "fpc1020_reset_reset", + "fpc1020_reset_active", + "fpc1020_irq_active"; + + pinctrl-0 = <&msm_gpio_37>; + pinctrl-1 = <&msm_gpio_37_output_high>; + pinctrl-2 = <&msm_gpio_120>; + status = "ok"; + }; + + + xiaomi_touch { + compatible = "xiaomi-touch"; + status = "ok"; + touch,name = "xiaomi-touch"; + }; + + testing_mode { + compatible = "modem,testing-mode"; + status-gpio = <&tlmm 81 0x00>, + <&tlmm 133 0x00>; + debounce-time = <30>; + pinctrl-names = "default"; + pinctrl-0 = <&ant_sub_ctrl_irq &ant_top_ctrl_irq>; + }; +}; + +/*Touch SPI state init*/ +&qupv3_se17_spi_active { + mux { + pins = "gpio55", "gpio56", "gpio57"; + function = "qup17"; + }; + + config { + pins = "gpio55", "gpio56", "gpio57"; + drive-strength = <6>; + // bias-disable; + bias-pull-down; + }; +}; + +&qupv3_se17_spi_sleep { + mux { + pins = "gpio55", "gpio56", "gpio57"; + function = "gpio"; + }; + + config { + pins = "gpio55", "gpio56", "gpio57"; + drive-strength = <6>; + bias-pull-down; + }; +}; + +&qupv3_se17_spi { + pinctrl-0 = <&qupv3_se17_spi_active>; + pinctrl-1 = <&qupv3_se17_spi_sleep>; +}; + +/*IC int pin, rst pin init*/ +&tlmm { + ts_mux { + ts_int_active: ts_int_active { + mux { + pins = "gpio122"; + function = "gpio"; + }; + + config { + pins = "gpio122"; + drive-strength = <16>; + bias-pull-down; + }; + }; + + ts_reset_active: ts_reset_active { + mux { + pins = "gpio12"; + function = "gpio"; + }; + + config { + pins = "gpio12"; + drive-strength = <16>; + bias-pull-up; + }; + }; + + ts_cs_active: ts_cs_active { + mux { + pins = "gpio58"; + function = "qup17"; + }; + + config { + pins = "gpio58"; + drive-strength = <6>; + bias-disable; + }; + }; + + ts_cs_suspend: ts_cs_suspend { + mux { + pins = "gpio58"; + function = "gpio"; + }; + + config { + pins = "gpio58"; + drive-strength = <6>; + bias-pull-down; + output-low; + }; + }; + }; +}; + +&ts_int_suspend { + mux { + pins = "gpio122"; + function = "gpio"; + }; + + config { + pins = "gpio122"; + drive-strength = <16>; + bias-disable; + input-enable; + }; +}; + +&ts_reset_suspend { + mux { + pins = "gpio12"; + function = "gpio"; + }; + + config { + pins = "gpio12"; + drive-strength = <16>; + bias-disable; + }; +}; + +&qupv3_se17_spi { + status = "ok"; + touch_spi@0 { + compatible = "xiaomi,spi-for-tp"; + reg = <0>; + status = "ok"; + spi-max-frequency = <10000000>; //10M + }; +}; + +/* Novatek device tree node */ +&soc { + ts_novatek { + compatible = "novatek,NVT-ts-spi"; + status = "ok"; + spi-max-frequency = <10000000>; /*4800000,9600000,15000000,19200000 10M*/ + novatek,reset-gpio = <&tlmm 12 0x00>; + novatek,irq-gpio = <&tlmm 122 0x2001>; + pinctrl-names = "pmx_ts_active", "pmx_ts_suspend"; + pinctrl-0 = <&ts_int_active &ts_reset_active &ts_cs_active>; + pinctrl-1 = <&ts_int_suspend &ts_reset_suspend &ts_cs_suspend>; + /* 672 */ + /*novatek,swrst-n8-addr = <0x01F01A>;*/ + /* 672A */ + novatek,swrst-n8-addr = <0x03F0FE>; + novatek,spi-rd-fast-addr = <0x03F310>; + /* MP */ + novatek,mp-support-dt; + novatek,config-array-size = <2>; + novatek,cfg_0 { + novatek,tp-vendor = <0x46>; + novatek,display-maker = <0x36>; + novatek,fw-name = "j20s_novatek_ts_fw01.bin"; + novatek,mp-name = "j20s_novatek_ts_mp01.bin"; + novatek,clicknum-file-name = "nvt+tianma"; + }; + novatek,cfg_1 { + novatek,tp-vendor = <0x53>; + novatek,display-maker = <0x42>; + novatek,fw-name = "j20s_novatek_ts_fw02.bin"; + novatek,mp-name = "j20s_novatek_ts_mp02.bin"; + novatek,clicknum-file-name = "nvt+csot"; + }; + /* for Xiaomi J20S 672C CSOT6.67" module */ + novatek-mp-criteria-594B@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "novatek-mp-criteria-594B"; + /* MP Config */ + IC_X_CFG_SIZE = <18>; + IC_Y_CFG_SIZE = <36>; + IC_KEY_CFG_SIZE = <4>; + X_Channel = <18>; + Y_Channel = <36>; + AIN_X = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17>; + AIN_Y = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 + 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35>; + AIN_KEY = <0 1 2 0xFF>; + /* MP Criteria */ + PS_Config_Lmt_Short_Rawdata_P = < + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008>; + + PS_Config_Lmt_Short_Rawdata_N = < + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000>; + + PS_Config_Lmt_Open_Rawdata_P = < + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120>; + + PS_Config_Lmt_Open_Rawdata_N = < + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511)>; + + PS_Config_Lmt_FW_Rawdata_P = < + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840>; + + PS_Config_Lmt_FW_Rawdata_N = < + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240>; + + PS_Config_Lmt_FW_CC_P = < + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314>; + + PS_Config_Lmt_FW_CC_N = < + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0>; + + PS_Config_Lmt_FW_Diff_P = < + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75>; + + PS_Config_Lmt_FW_Diff_N = < + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75)>; + + PS_Config_Diff_Test_Frame = <50>; + }; + + /* for Xiaomi J20S 672C TM6.67" module */ + novatek-mp-criteria-594A@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "novatek-mp-criteria-594A"; + + /* MP Config */ + IC_X_CFG_SIZE = <16>; + IC_Y_CFG_SIZE = <36>; + IC_KEY_CFG_SIZE = <4>; + X_Channel = <16>; + Y_Channel = <36>; + AIN_X = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>; + AIN_Y = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 + 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35>; + AIN_KEY = <0 1 2 0xFF>; + + /* MP Criteria */ + PS_Config_Lmt_Short_Rawdata_P = < + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 14008 + 14008 14008 14008>; + + PS_Config_Lmt_Short_Rawdata_N = < + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 + 10000 10000 10000>; + + PS_Config_Lmt_Open_Rawdata_P = < + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 5120 + 5120 5120 5120>; + + PS_Config_Lmt_Open_Rawdata_N = < + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) (-511) + (-511) (-511) (-511)>; + + PS_Config_Lmt_FW_Rawdata_P = < + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 3840 + 3840 3840 3840>; + + PS_Config_Lmt_FW_Rawdata_N = < + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 + 240 240 240>; + + PS_Config_Lmt_FW_CC_P = < + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 314 + 314 314 314>; + + PS_Config_Lmt_FW_CC_N = < + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0>; + + PS_Config_Lmt_FW_Diff_P = < + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 + 75 75 75>; + + PS_Config_Lmt_FW_Diff_N = < + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) (-75) + (-75) (-75) (-75)>; + + PS_Config_Diff_Test_Frame = <50>; + }; + }; +}; + +&qupv3_se17_i2c { + status = "ok"; + fts@49 { + compatible = "st,fts"; + reg = <0x49>; + interrupt-parent = <&tlmm>; + interrupts = <122 0x2008>; + pinctrl-names = "pmx_ts_active", "pmx_ts_suspend"; + pinctrl-0 = <&ts_active>; + pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; + vdd-supply = <&touch_vddio_vreg>; + avdd-supply = <&pm8150l_l1>; + fts,pwr-reg-name = "avdd"; + fts,bus-reg-name = "vdd"; + fts,irq-gpio = <&tlmm 122 0x2008>; + fts,irq-gpio-name = "fts_irq"; + fts,reset-gpio-enable; + fts,reset-gpio = <&tlmm 12 0x00>; + fts,reset-gpio-name = "fts_rst"; + fts,irq-flags = <0x2008>; // IRQF_ONESHOT | IRQF_TRIGGER_LOW + fts,x-max = <1080>; + fts,y-max = <2340>; + fts,default-fw-name = "st_fts_f1.ftb"; + fts,config-array-size = <1>; + fts,dump-click-count; + fts,touch-up-threshold-min = <40>; + fts,touch-up-threshold-max = <120>; + fts,touch-up-threshold-def = <80>; + fts,touch-tolerance-min = <5>; + fts,touch-tolerance-max = <35>; + fts,touch-tolerance-def = <25>; + fts,touch-wgh-min-def = <1>; + fts,touch-wgh-min-max = <15>; + fts,touch-wgh-min-min = <0>; + fts,touch-wgh-max-def = <5>; + fts,touch-wgh-max-max = <15>; + fts,touch-wgh-max-min = <0>; + fts,touch-wgh-step-def = <1>; + fts,touch-wgh-step-max = <2>; + fts,touch-wgh-step-min = <0>; + fts,edgefilter-leftrigt-def = <45>; + fts,edgefilter-topbottom-def = <0>; + fts,edgefilter-top-ingamemode = <0>; + fts,edgefilter-bottom-ingamemode = <0>; + fts,edgefilter-area-step1 = <100>; + fts,edgefilter-area-step2 = <170>; + fts,edgefilter-area-step3 = <250>; + fts,cfg_0 { + fts,tp-vendor = <0x48>; + fts,fw-name = "st_fts_f1.ftb"; + fts,limit-name = "stm_fts_production_limits.csv"; + fts,clicknum-file-name = "fts+sdc"; + }; + }; +}; + +&qupv3_se9_i2c { + status = "ok"; + nq@28 { + compatible = "qcom,nq-nci"; + reg = <0x28>; + qcom,nq-irq = <&tlmm 47 0x00>; + qcom,nq-ven = <&tlmm 102 0x00>; + qcom,nq-firm = <&tlmm 48 0x00>; + qcom,nq-clkreq = <&tlmm 113 0x00>; + //qcom,nq-esepwr = <&tlmm 42 0x00>; + interrupt-parent = <&tlmm>; + interrupts = <47 0>; + interrupt-names = "nfc_irq"; + pinctrl-names = "nfc_active", "nfc_suspend"; + pinctrl-0 = <&nfc_int_active &nfc_enable_active + &nfc_clk_req_active>; + pinctrl-1 = <&nfc_int_suspend &nfc_enable_suspend + &nfc_clk_req_suspend>; + }; +}; + +&qupv3_se1_spi { + status = "ok"; + irled@0 { + compatible = "ir-spi"; + reg = <0x0>; + status = "ok"; + spi-max-frequency = <19200000>; + }; +}; + +&pm8150l_lpg { + qcom,lut-patterns = <0 1 2 3 4 5 7 9 11 13 15 + 13 11 9 7 5 4 3 2 1 0>; +}; + +&pwm_lpg1 { + qcom,lpg-chan-id = <1>; + qcom,ramp-step-ms = <100>; + qcom,ramp-pause-hi-count = <2>; + qcom,ramp-pause-lo-count = <2>; + qcom,ramp-low-index = <0>; + qcom,ramp-high-index = <20>; + qcom,ramp-from-low-to-high; + qcom,ramp-pattern-repeat; +}; + +&red_led { + label = "white"; +}; + +&green_led { + status = "disabled"; +}; + +&blue_led { + status = "disabled"; +}; + +&mdss_mdp { + clock-rate = <0 0 0 0 345000000 19200000 300000000 19200000>; +}; + + +&sde_dsi { + vcie-supply = <&disp_vci_vreg>; +}; + +&dsi_samsung_fhd_ea8076_f1mp_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_external_supply>; +}; + +&dsi_samsung_fhd_ea8076_f1p2_2_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_external_supply>; +}; + +&dsi_samsung_fhd_ea8076_f1p2_cmd { + qcom,panel-supply-entries = <&dsi_amoled_panel_pwr_external_supply>; +}; + +&dsi_j20s_36_02_0a_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&dsi_j20s_42_02_0b_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&pm8150l_wled { + status = "okay"; + qcom,string-cfg = <7>; + qcom,ovp = <28000>; + qcom,fs-current-limit = <22500>; + qcom,cabc-sel = <1>; +}; + + +&pm8150b_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + wp_therm { + reg = ; + label = "wp_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + vcoin { + reg = ; + label = "vcoin"; + qcom,pre-scaling = <1 3>; + }; + + conn_therm { + reg = ; + label = "conn_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + chg_sbux { + reg = ; + label = "chg_sbux"; + qcom,pre-scaling = <1 3>; + }; + + mid_chg_div6 { + reg = ; + label = "chg_mid"; + qcom,pre-scaling = <1 6>; + }; + + usb_in_i_uv { + reg = ; + label = "usb_in_i_uv"; + qcom,pre-scaling = <1 1>; + }; + + usb_in_v_div_16 { + reg = ; + label = "usb_in_v_div_16"; + qcom,pre-scaling = <1 16>; + }; +}; + +&pm8150_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + vcoin { + reg = ; + label = "vcoin"; + qcom,pre-scaling = <1 3>; + }; + + xo_therm { + reg = ; + label = "xo_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + quiet_therm { + reg = ; + label = "quiet_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + pa_therm0 { + reg = ; + label = "pa_therm0"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm8150l_vadc { + vph_pwr { + reg = ; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + cam_therm0 { + reg = ; + label = "cam_therm0"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + cam_therm1 { + reg = ; + label = "cam_therm1"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + pa_therm1 { + reg = ; + label = "pa_therm1"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm8150b_adc_tm { + wp_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm8150_adc_tm { + xo_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + quiet_therm { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + pa_therm0 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm8150l_adc_tm { + cam_therm0 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + cam_therm1 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + pa_therm1 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&thermal_zones { + wp_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150b_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + xo_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_XO_THERM_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + quiet_therm { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + pa_therm0 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150_adc_tm ADC_AMUX_THM2_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + cam_therm0 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM1_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + cam_therm1 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM2_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + pa_therm1 { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&pm8150l_adc_tm ADC_AMUX_THM3_PU2>; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; +}; + +&pm8150b_haptics { + qcom,vmax-mv = <2800>; + qcom,play-rate-us = <5102>; + + wf_0 { + /* CLICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_1 { + /* DOUBLE CLICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 3e]; + qcom,wf-brake-pattern = [03 01 01 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_2 { + /* TICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 3e]; + qcom,wf-brake-pattern = [03 01 01 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_3 { + /* THUD */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_4 { + /* POP */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [3e 3e]; + qcom,wf-brake-pattern = [02 01 00 00]; + qcom,wf-play-rate-us = <5102>; + }; + wf_5 { + /* HEAVY CLICK */ + qcom,wf-vmax-mv = <3600>; + qcom,wf-pattern = [7e 7e 7e]; + qcom,wf-brake-pattern = [03 03 01 00]; + qcom,wf-play-rate-us = <5102>; + }; +}; + +&soc { + ssc_sensors: qcom,msm-ssc-sensors { + compatible = "qcom,msm-ssc-sensors"; + status = "ok"; + qcom,firmware-name = "slpi_vy"; + }; + + thermal_message: thermal-message { + board-sensor = "quiet_therm"; + }; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; + status = "ok"; + }; + +&tlmm { + /* GPIO_37 : FP_RESET_N */ + msm_gpio_37: msm_gpio_37 { + mux { + pins = "gpio37"; + function = "gpio"; + }; + + config { + pins = "gpio37"; + drive-strength = <2>; + bias-disable; + output-low; + }; + }; + + /* GPIO_37 : FP_RESET_N, state device active*/ + msm_gpio_37_output_high: msm_gpio_37_output_high { + mux { + pins = "gpio37"; + function = "gpio"; + }; + + config { + pins = "gpio37"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + + /* GPIO_120 : FP_INT_N */ + msm_gpio_120: msm_gpio_120 { + mux { + pins = "gpio120"; + function = "gpio"; + }; + + config { + pins = "gpio120"; + drive-strength = <2>; + bias-pull-down; + }; + }; +}; + diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index 18ae64ebd2c1..dae4dde06926 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h @@ -639,6 +639,12 @@ #define KEY_UNMUTE 0x274 #define KEY_FASTREVERSE 0x275 #define KEY_SLOWREVERSE 0x276 + +/* + * AI KEY + */ +#define KEY_AI 0x2b1 + /* * Control a data application associated with the currently viewed channel, * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.) From 05f3cbfe2170b3b202440433ae9591eab58adb2b Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Thu, 23 Jun 2022 03:27:16 +0200 Subject: [PATCH 009/226] arch: arm64: boot: dts: qcom: xiaomi: Adapt analog USB-C for newer audio drivers Change-Id: Icb4ca6cadf5caed7d79dd04a4291fee98d4dca35 Signed-off-by: firebird11 --- .../boot/dts/qcom/xiaomi/base/sm8150-pinctrl.dtsi | 6 +++--- .../andromeda/andromeda-audio-overlay.dtsi | 15 ++++++++++----- .../overlay/andromeda/andromeda-pinctrl.dtsi | 6 +++--- .../overlay/cepheus/cepheus-audio-overlay.dtsi | 15 ++++++++++----- .../xiaomi/overlay/crux/crux-audio-overlay.dtsi | 15 ++++++++++----- .../qcom/xiaomi/overlay/crux/crux-pinctrl.dtsi | 6 +++--- 6 files changed, 39 insertions(+), 24 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-pinctrl.dtsi index 444d383a00a3..ec7306e17938 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150-pinctrl.dtsi @@ -118,8 +118,8 @@ }; }; - wcd_usbc_analog_en2 { - wcd_usbc_analog_en2_idle: wcd_usbc_ana_en2_idle { + wcd_usbc_analog_en2n { + wcd_usbc_analog_en2n_idle: wcd_usbc_ana_en2n_idle { mux { pins = "gpio58"; function = "gpio"; @@ -132,7 +132,7 @@ }; }; - wcd_usbc_analog_en2_active: wcd_usbc_ana_en2_active { + wcd_usbc_analog_en2n_active: wcd_usbc_ana_en2n_active { mux { pins = "gpio58"; function = "gpio"; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi index a243e7d415ae..b3ea6495be41 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-audio-overlay.dtsi @@ -37,18 +37,16 @@ qcom,adc2-switch-gpio = <&adc2_switch_gpio>; qcom,msm-mbhc-usbc-audio-supported = <1>; qcom,fsa4476-gpio-support = <1>; - qcom,usbc-analog-en1-gpio = <&wcd_usbc_analog_en1_gpio>; + qcom,usbc-analog-en1_gpio = <&wcd_usbc_analog_en1_gpio>; + qcom,usbc-analog-en2_n_gpio = <&wcd_usbc_analog_en2n_gpio>; qcom,usbc-analog-en2-gpio = <&tlmm 35 0>; pinctrl-names = "quat_mi2s_enable", "quat_mi2s_disable", - "quat_tdm_enable", "quat_tdm_disable", - "aud_active", "aud_sleep"; + "quat_tdm_enable", "quat_tdm_disable"; pinctrl-0 = <&quat_mi2s_active &quat_mi2s_sd0_active &quat_mi2s_sd1_active>; pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_sd0_sleep &quat_mi2s_sd1_sleep>; pinctrl-2 = <&quat_tdm_active &quat_tdm_dout_active>; pinctrl-3 = <&quat_tdm_sleep &quat_tdm_dout_sleep>; - pinctrl-4 = <&wcd_usbc_analog_en2_active>; - pinctrl-5 = <&wcd_usbc_analog_en2_idle>; }; &soc { @@ -73,4 +71,11 @@ pinctrl-1 = <&wcd_usbc_analog_en1_idle>; }; + wcd_usbc_analog_en2n_gpio: msm_cdc_pinctrl_usbc_audio_en2 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&wcd_usbc_analog_en2n_active>; + pinctrl-1 = <&wcd_usbc_analog_en2n_idle>; + }; + }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl.dtsi index 6bf9122c3e6c..309558a92cd5 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/andromeda/andromeda-pinctrl.dtsi @@ -391,8 +391,8 @@ }; }; - wcd_usbc_analog_en2 { - wcd_usbc_analog_en2_idle: wcd_usbc_ana_en2_idle { + wcd_usbc_analog_en2n { + wcd_usbc_analog_en2n_idle: wcd_usbc_ana_en2n_idle { mux { pins = "gpio35"; function = "gpio"; @@ -405,7 +405,7 @@ }; }; - wcd_usbc_analog_en2_active: wcd_usbc_ana_en2_active { + wcd_usbc_analog_en2n_active: wcd_usbc_ana_en2n_active { mux { pins = "gpio35"; function = "gpio"; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-audio-overlay.dtsi index 7877060e5e35..d36f44af1498 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-audio-overlay.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-audio-overlay.dtsi @@ -38,18 +38,16 @@ qcom,adc2-switch-gpio = <&adc2_switch_gpio>; qcom,msm-mbhc-usbc-audio-supported = <1>; qcom,fsa4476-gpio-support = <1>; - qcom,usbc-analog-en1-gpio = <&wcd_usbc_analog_en1_gpio>; + qcom,usbc-analog-en1_gpio = <&wcd_usbc_analog_en1_gpio>; + qcom,usbc-analog-en2_n_gpio = <&wcd_usbc_analog_en2n_gpio>; qcom,usbc-analog-en2-gpio = <&tlmm 58 0>; pinctrl-names = "quat_mi2s_enable", "quat_mi2s_disable", - "quat_tdm_enable", "quat_tdm_disable", - "aud_active", "aud_sleep"; + "quat_tdm_enable", "quat_tdm_disable"; pinctrl-0 = <&quat_mi2s_active &quat_mi2s_sd0_active &quat_mi2s_sd1_active>; pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_sd0_sleep &quat_mi2s_sd1_sleep>; pinctrl-2 = <&quat_tdm_active &quat_tdm_dout_active>; pinctrl-3 = <&quat_tdm_sleep &quat_tdm_dout_sleep>; - pinctrl-4 = <&wcd_usbc_analog_en2_active>; - pinctrl-5 = <&wcd_usbc_analog_en2_idle>; }; &soc { @@ -73,4 +71,11 @@ pinctrl-0 = <&wcd_usbc_analog_en1_active>; pinctrl-1 = <&wcd_usbc_analog_en1_idle>; }; + + wcd_usbc_analog_en2n_gpio: msm_cdc_pinctrl_usbc_audio_en2 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&wcd_usbc_analog_en2n_active>; + pinctrl-1 = <&wcd_usbc_analog_en2n_idle>; + }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-audio-overlay.dtsi index 5d5c471561aa..81046219851a 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-audio-overlay.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-audio-overlay.dtsi @@ -36,18 +36,16 @@ /* qcom,adc2-switch-gpio = <&adc2_switch_gpio>; */ qcom,msm-mbhc-usbc-audio-supported = <1>; qcom,fsa4476-gpio-support = <1>; - qcom,usbc-analog-en1-gpio = <&wcd_usbc_analog_en1_gpio>; + qcom,usbc-analog-en1_gpio = <&wcd_usbc_analog_en1_gpio>; + qcom,usbc-analog-en2_n_gpio = <&wcd_usbc_analog_en2n_gpio>; qcom,usbc-analog-en2-gpio = <&tlmm 32 0>; pinctrl-names = "quat_mi2s_enable", "quat_mi2s_disable", - "quat_tdm_enable", "quat_tdm_disable", - "aud_active", "aud_sleep"; + "quat_tdm_enable", "quat_tdm_disable"; pinctrl-0 = <&quat_mi2s_active &quat_mi2s_sd0_active &quat_mi2s_sd1_active>; pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_sd0_sleep &quat_mi2s_sd1_sleep>; pinctrl-2 = <&quat_tdm_active &quat_tdm_dout_active>; pinctrl-3 = <&quat_tdm_sleep &quat_tdm_dout_sleep>; - pinctrl-4 = <&wcd_usbc_analog_en2_active>; - pinctrl-5 = <&wcd_usbc_analog_en2_idle>; }; &soc { @@ -71,4 +69,11 @@ pinctrl-0 = <&wcd_usbc_analog_en1_active>; pinctrl-1 = <&wcd_usbc_analog_en1_idle>; }; + + wcd_usbc_analog_en2n_gpio: msm_cdc_pinctrl_usbc_audio_en2 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&wcd_usbc_analog_en2n_active>; + pinctrl-1 = <&wcd_usbc_analog_en2n_idle>; + }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-pinctrl.dtsi index 4155e541eab1..1106980222e3 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-pinctrl.dtsi @@ -505,8 +505,8 @@ }; }; - wcd_usbc_analog_en2 { - wcd_usbc_analog_en2_idle: wcd_usbc_ana_en2_idle { + wcd_usbc_analog_en2n { + wcd_usbc_analog_en2n_idle: wcd_usbc_ana_en2n_idle { mux { pins = "gpio32"; function = "gpio"; @@ -519,7 +519,7 @@ }; }; - wcd_usbc_analog_en2_active: wcd_usbc_ana_en2_active { + wcd_usbc_analog_en2n_active: wcd_usbc_ana_en2n_active { mux { pins = "gpio32"; function = "gpio"; From 60a7e680f3dcdea262bc91a3f519b6d06c0a6d86 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Sun, 10 Jul 2022 16:09:00 +0200 Subject: [PATCH 010/226] arch: arm64: boot: dts: qcom: xiaomi: vayu: Add ln8000 support * Extracted from stock dtbo Change-Id: I79733a52cddc8bb011ef679bf317babb5055fe0f Signed-off-by: firebird11 --- .../qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi index 795454af9060..b65899889e98 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi @@ -215,6 +215,26 @@ And public attribution of xiaomi platforms(like J20S and so and) //ti,bq2597x,sense-resistor-mohm = <2>; }; + + ln8000_charger@51 { + compatible = "lionsemi,ln8000"; + reg = <0x51>; + ln8000_charger,irq_index = <0x128>; + ln8000_charger,bat-ovp-threshold = <0x11d0>; + ln8000_charger,bat-ovp-alarm-threshold = <0x11ad>; + ln8000_charger,bus-ovp-threshold = <0x32c8>; + ln8000_charger,bus-ovp-alarm-threshold = <0x2af8>; + ln8000_charger,bus-ocp-threshold = <0xea6>; + ln8000_charger,bus-ocp-alarm-threshold = <0xdac>; + ln8000_charger,ntc-alarm-cfg = <0xe2>; + ln8000_charger,tdie-prot-disable; + ln8000_charger,tbus-mon-disable; + ln8000_charger,tbat-mon-disable; + ln8000_charger,iin-ocp-disable; + ln8000_charger,iin-reg-disable; + ln8000_charger,tdie-reg-disable; + ln8000_charger,vbat-reg-disable; + }; }; &soc { From 66e45d6a13d333182229eac31d5629e8403ea6a4 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Tue, 16 Apr 2024 23:53:57 +0200 Subject: [PATCH 011/226] arch: arm64: boot: dts: qcom: xiaomi: nabu: Remove fingerprint bindings nabu doesn't have fingerprint, thanks Xiaomi Change-Id: Ide1fa63add29925e219f7b8c88d0ff225b9b11d4 Signed-off-by: firebird11 --- .../qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi index 06be84bc688d..f31136085341 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi @@ -488,31 +488,6 @@ And public attribution of xiaomi platforms(like J20S and so and) gpio = <&pm8150b_gpios 5 0>; }; - fingerprint_goodix { - compatible = "goodix,fingerprint"; - goodix,gpio-reset = <&tlmm 37 0x0>; - goodix,gpio-irq = <&tlmm 120 0x0>; - //goodix.gpio_pwr = <&tlmm 125 0x0>; - //fp_vdd_vreg = <&pm8150l_l7>; - status = "ok"; - }; - - - fingerprint_fpc { - compatible = "fpc,fpc1020"; - fpc,gpio_rst = <&tlmm 37 0x0>; - fpc,gpio_irq = <&tlmm 120 0x0>; - pinctrl-names = "fpc1020_reset_reset", - "fpc1020_reset_active", - "fpc1020_irq_active"; - - pinctrl-0 = <&msm_gpio_37>; - pinctrl-1 = <&msm_gpio_37_output_high>; - pinctrl-2 = <&msm_gpio_120>; - status = "ok"; - }; - - xiaomi_touch { compatible = "xiaomi-touch"; status = "ok"; From 966750614612ceb6abaab7662eb7b170caeca94c Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 6 Nov 2023 00:58:45 +0100 Subject: [PATCH 012/226] drivers: char: Import Xiaomi changes Change-Id: I25159512098a4af867382e81d03f46b509e3763e Signed-off-by: firebird11 --- drivers/char/adsprpc.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 0957d29a6ee2..0417cf13313e 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -4619,15 +4619,32 @@ static int fastrpc_probe(struct platform_device *pdev) if (range.addr && !of_property_read_bool(dev->of_node, "restrict-access")) { int srcVM[1] = {VMID_HLOS}; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int destVM[4] = {VMID_HLOS, VMID_MSS_MSA, VMID_SSC_Q6, + VMID_ADSP_Q6}; +#else int destVM[3] = {VMID_HLOS, VMID_SSC_Q6, VMID_ADSP_Q6}; +#endif +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int destVMperm[4] = {PERM_READ | PERM_WRITE | PERM_EXEC, +#else int destVMperm[3] = {PERM_READ | PERM_WRITE | PERM_EXEC, +#endif +#ifdef CONFIG_MACH_XIAOMI_SM8150 + PERM_READ | PERM_WRITE | PERM_EXEC, +#endif PERM_READ | PERM_WRITE | PERM_EXEC, PERM_READ | PERM_WRITE | PERM_EXEC, }; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + VERIFY(err, !hyp_assign_phys(range.addr, range.size, + srcVM, 1, destVM, destVMperm, 4)); +#else VERIFY(err, !hyp_assign_phys(range.addr, range.size, srcVM, 1, destVM, destVMperm, 3)); +#endif if (err) goto bail; me->range.addr = range.addr; From 61fa7ef584aacc6a2252f1e4cb688b800ae73b33 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 29 Jan 2024 20:59:38 +0100 Subject: [PATCH 013/226] drivers: clk: qcom: mdss: Import Xiaomi changes Change-Id: I19de141ce55d00ea1af4473025e35e1049ede365 Signed-off-by: firebird11 --- drivers/clk/qcom/mdss/mdss-dsi-pll-7nm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/qcom/mdss/mdss-dsi-pll-7nm.c b/drivers/clk/qcom/mdss/mdss-dsi-pll-7nm.c index dacb68ca8e1f..831db0488804 100644 --- a/drivers/clk/qcom/mdss/mdss-dsi-pll-7nm.c +++ b/drivers/clk/qcom/mdss/mdss-dsi-pll-7nm.c @@ -554,6 +554,12 @@ static void dsi_pll_setup_config(struct dsi_pll_7nm *pll, config->enable_ssc = rsc->ssc_en; config->ssc_center = rsc->ssc_center; +#ifdef CONFIG_MACH_XIAOMI_NABU + if (pll->cphy_enabled) { + config->enable_ssc = false; + } +#endif + if (config->enable_ssc) { if (rsc->ssc_freq) config->ssc_freq = rsc->ssc_freq; From 3699fa68f7f4b025ebe31a32e62df97d13c034ac Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 17:22:59 +0200 Subject: [PATCH 014/226] drivers: cpufreq: Import Xiaomi changes Change-Id: Ic287243d1ea995dc014f1e57f828d2e5ac09f0f9 Signed-off-by: firebird11 --- drivers/cpufreq/cpufreq.c | 6 ++++++ include/linux/cpufreq.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index ea51a776c6ca..a8ef00ab1a07 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2267,6 +2267,12 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_INCOMPATIBLE, new_policy); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* the adjusted frequency should not exceed thermal limit */ + blocking_notifier_call_chain(&cpufreq_policy_notifier_list, + CPUFREQ_THERMAL, new_policy); +#endif + /* * verify the cpu speed can be set within this limit, which might be * different to the first one diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index ed0ff1538049..f1ca2468f8a0 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -429,6 +429,9 @@ static inline void cpufreq_resume(void) {} /* Policy Notifiers */ #define CPUFREQ_ADJUST (0) #define CPUFREQ_NOTIFY (1) +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define CPUFREQ_THERMAL (2) +#endif #define CPUFREQ_INCOMPATIBLE (6) #ifdef CONFIG_CPU_FREQ From 8c14852617c5fb6780d7fe208196f9b5cd43d584 Mon Sep 17 00:00:00 2001 From: Demon000 Date: Mon, 2 Dec 2019 03:49:20 +0100 Subject: [PATCH 015/226] drivers: gpu: drm: msm: extend qcom drm notifier Change-Id: Id266a34b20403a9f3ef445902730f293712bf260 Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_display.c | 15 ++++++++++++++- drivers/gpu/drm/msm/msm_atomic.c | 3 ++- include/linux/msm_drm_notify.h | 5 +++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index 5dc4961d0a8e..893d1c8d47e3 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -19,6 +19,8 @@ #include #include +#include + #include "msm_drv.h" #include "sde_connector.h" #include "msm_mmu.h" @@ -1058,6 +1060,8 @@ int dsi_display_set_power(struct drm_connector *connector, int power_mode, void *disp) { struct dsi_display *display = disp; + struct msm_drm_notifier notify_data; + int event = power_mode; int rc = 0; if (!display || !display->panel) { @@ -1065,17 +1069,26 @@ int dsi_display_set_power(struct drm_connector *connector, return -EINVAL; } + notify_data.data = &event; + switch (power_mode) { case SDE_MODE_DPMS_LP1: + msm_drm_notifier_call_chain(MSM_DRM_EARLY_EVENT_BLANK, ¬ify_data); rc = dsi_panel_set_lp1(display->panel); + msm_drm_notifier_call_chain(MSM_DRM_EVENT_BLANK, ¬ify_data); break; case SDE_MODE_DPMS_LP2: + msm_drm_notifier_call_chain(MSM_DRM_EARLY_EVENT_BLANK, ¬ify_data); rc = dsi_panel_set_lp2(display->panel); + msm_drm_notifier_call_chain(MSM_DRM_EVENT_BLANK, ¬ify_data); break; case SDE_MODE_DPMS_ON: if (display->panel->power_mode == SDE_MODE_DPMS_LP1 || - display->panel->power_mode == SDE_MODE_DPMS_LP2) + display->panel->power_mode == SDE_MODE_DPMS_LP2) { + msm_drm_notifier_call_chain(MSM_DRM_EARLY_EVENT_BLANK, ¬ify_data); rc = dsi_panel_set_nolp(display->panel); + msm_drm_notifier_call_chain(MSM_DRM_EVENT_BLANK, ¬ify_data); + } break; case SDE_MODE_DPMS_OFF: default: diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 39f1e7c3b4c0..d681a20d2080 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -73,11 +73,12 @@ EXPORT_SYMBOL(msm_drm_unregister_client); * @v: notifier data, inculde display id and display blank * event(unblank or power down). */ -static int msm_drm_notifier_call_chain(unsigned long val, void *v) +int msm_drm_notifier_call_chain(unsigned long val, void *v) { return blocking_notifier_call_chain(&msm_drm_notifier_list, val, v); } +EXPORT_SYMBOL(msm_drm_notifier_call_chain); /* block until specified crtcs are no longer pending update, and * atomically mark them as pending update diff --git a/include/linux/msm_drm_notify.h b/include/linux/msm_drm_notify.h index 924ba852c99c..4f9b32662ad5 100644 --- a/include/linux/msm_drm_notify.h +++ b/include/linux/msm_drm_notify.h @@ -23,6 +23,10 @@ enum { /* panel: power on */ MSM_DRM_BLANK_UNBLANK, + MSM_DRM_BLANK_LP1, + MSM_DRM_BLANK_LP2, + MSM_DRM_BLANK_STANDBY, + MSM_DRM_BLANK_SUSPEND, /* panel: power off */ MSM_DRM_BLANK_POWERDOWN, }; @@ -42,4 +46,5 @@ struct msm_drm_notifier { int msm_drm_register_client(struct notifier_block *nb); int msm_drm_unregister_client(struct notifier_block *nb); +int msm_drm_notifier_call_chain(unsigned long val, void *v); #endif From 76417ed2b8997edf713eae3829bf2ba315139fbe Mon Sep 17 00:00:00 2001 From: Demon000 Date: Mon, 8 Jul 2019 01:54:18 +0200 Subject: [PATCH 016/226] drivers: gpu: drm: msm: handle ss dcs type Change-Id: I0a707338911a937afe1bdb4562da1ef102c5a59e Signed-off-by: firebird11 --- drivers/gpu/drm/drm_mipi_dsi.c | 14 ++++++++++++++ drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 9 ++++++++- drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 1 + include/drm/drm_mipi_dsi.h | 2 ++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 4b31f35dcc49..4aa005b5c40c 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -1058,6 +1058,20 @@ int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline) } EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline); +int mipi_dsi_dcs_set_display_brightness_ss(struct mipi_dsi_device *dsi, + u16 brightness) +{ + u8 payload[2] = { brightness >> 8, brightness & 0xff }; + ssize_t err; + + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, + payload, sizeof(payload)); + if (err < 0) + return err; + + return 0; +} + /** * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the * display diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index eb96af4751b1..10ad5fa1164d 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -623,7 +623,11 @@ static int dsi_panel_update_backlight(struct dsi_panel *panel, if (panel->bl_config.bl_inverted_dbv) bl_lvl = (((bl_lvl & 0xff) << 8) | (bl_lvl >> 8)); - rc = mipi_dsi_dcs_set_display_brightness(dsi, bl_lvl); + if (panel->bl_config.dcs_type_ss) + rc = mipi_dsi_dcs_set_display_brightness_ss(dsi, bl_lvl); + else + rc = mipi_dsi_dcs_set_display_brightness(dsi, bl_lvl); + if (rc < 0) pr_err("failed to update dcs backlight:%d\n", bl_lvl); @@ -2272,6 +2276,9 @@ static int dsi_panel_parse_bl_config(struct dsi_panel *panel) panel->bl_config.type = DSI_BACKLIGHT_UNKNOWN; } + panel->bl_config.dcs_type_ss = utils->read_bool(utils->data, + "qcom,mdss-dsi-bl-dcs-type-ss"); + data = utils->get_property(utils->data, "qcom,bl-update-flag", NULL); if (!data) { panel->bl_config.bl_update = BL_UPDATE_NONE; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index 2ed6f0980dea..fcf1ba3db846 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -121,6 +121,7 @@ struct dsi_backlight_config { bool bl_inverted_dbv; int en_gpio; + bool dcs_type_ss; /* PWM params */ struct pwm_device *pwm_bl; bool pwm_enabled; diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index d80635d66bef..1e090439b7a4 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -286,6 +286,8 @@ int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format); int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline); int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, u16 brightness); +int mipi_dsi_dcs_set_display_brightness_ss(struct mipi_dsi_device *dsi, + u16 brightness); int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, u16 *brightness); int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi, From 1a871b690131be9e1f0a3c669ee69123a2633653 Mon Sep 17 00:00:00 2001 From: Demon000 Date: Mon, 8 Jul 2019 01:56:43 +0200 Subject: [PATCH 017/226] drivers: gpu: drm: msm: modify lp11 mode logic Change-Id: I630f67c0d2ec1537ef236fb8363ee84f13e953d4 Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 33 +++++++++++++++++---- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 10ad5fa1164d..63b71103751a 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -447,6 +447,10 @@ static int dsi_panel_power_on(struct dsi_panel *panel) goto error_disable_vregs; } + /* If LP11_INIT is set, skip panel reset here*/ + if (panel->lp11_init) + goto exit; + rc = dsi_panel_reset(panel); if (rc) { pr_err("[%s] failed to reset panel, rc=%d\n", panel->name, rc); @@ -3817,9 +3821,11 @@ int dsi_panel_pre_prepare(struct dsi_panel *panel) mutex_lock(&panel->panel_lock); +#if 0 /* If LP11_INIT is set, panel will be powered up during prepare() */ if (panel->lp11_init) goto error; +#endif rc = dsi_panel_power_on(panel); if (rc) { @@ -3967,12 +3973,19 @@ int dsi_panel_prepare(struct dsi_panel *panel) mutex_lock(&panel->panel_lock); if (panel->lp11_init) { +#if 0 rc = dsi_panel_power_on(panel); if (rc) { pr_err("[%s] panel power on failed, rc=%d\n", panel->name, rc); goto error; } +#endif + rc = dsi_panel_reset(panel); + if (rc) { + pr_err("[%s] failed to reset panel, rc=%d\n", panel->name, rc); + goto error; + } } rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_PRE_ON); @@ -4387,6 +4400,14 @@ int dsi_panel_unprepare(struct dsi_panel *panel) goto error; } + if (!panel->lp11_init) { + rc = dsi_panel_power_off(panel); + if (rc) { + pr_err("[%s] panel power_Off failed, rc=%d\n", + panel->name, rc); + goto error; + } + } error: mutex_unlock(&panel->panel_lock); return rc; @@ -4403,11 +4424,13 @@ int dsi_panel_post_unprepare(struct dsi_panel *panel) mutex_lock(&panel->panel_lock); - rc = dsi_panel_power_off(panel); - if (rc) { - pr_err("[%s] panel power_Off failed, rc=%d\n", - panel->name, rc); - goto error; + if (panel->lp11_init) { + rc = dsi_panel_power_off(panel); + if (rc) { + pr_err("[%s] panel power_Off failed, rc=%d\n", + panel->name, rc); + goto error; + } } error: mutex_unlock(&panel->panel_lock); From 9e8a5f0b3f3cc4eabebc60a254e7e8b7ce2c7a64 Mon Sep 17 00:00:00 2001 From: Demon000 Date: Sun, 5 Apr 2020 22:41:58 +0200 Subject: [PATCH 018/226] drivers: gpu: drm: msm: dsi-staging: create empty attributes group Change-Id: I974643cb245f76e66b208f7e18601cbb3d90ae62 Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_display.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index 893d1c8d47e3..0889cb8f3a7e 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -5044,11 +5044,22 @@ static int dsi_display_validate_split_link(struct dsi_display *display) return rc; } +static struct attribute *display_fs_attrs[] = { + NULL, +}; +static struct attribute_group display_fs_attrs_group = { + .attrs = display_fs_attrs, +}; + static int dsi_display_sysfs_init(struct dsi_display *display) { int rc = 0; struct device *dev = &display->pdev->dev; + rc = sysfs_create_group(&dev->kobj, &display_fs_attrs_group); + if (rc) + pr_err("failed to create display device attributes"); + if (display->panel->panel_mode == DSI_OP_CMD_MODE) rc = sysfs_create_group(&dev->kobj, &dynamic_dsi_clock_fs_attrs_group); From 1762e70bc84785ca4c45b18179eb3f8d5173bcb4 Mon Sep 17 00:00:00 2001 From: Demon000 Date: Thu, 21 May 2020 02:06:33 +0300 Subject: [PATCH 019/226] drivers: gpu: drm: msm: sde: translate zpos property to fod property Change-Id: I7e8562ed3eda675d160d6dabee7e568a1a72e849 Signed-off-by: firebird11 --- drivers/gpu/drm/msm/msm_drv.h | 1 + drivers/gpu/drm/msm/sde/sde_plane.c | 44 +++++++++++++++-------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index f9460152091e..4bf2972595ea 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -103,6 +103,7 @@ enum msm_mdp_plane_property { /* range properties */ PLANE_PROP_ZPOS = PLANE_PROP_BLOBCOUNT, + PLANE_PROP_FOD, PLANE_PROP_ALPHA, PLANE_PROP_COLOR_FILL, PLANE_PROP_H_DECIMATE, diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index 686d50391236..7e6887476cb9 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -3976,6 +3976,7 @@ static int sde_plane_sspp_atomic_update(struct drm_plane *plane, case PLANE_PROP_ALPHA: case PLANE_PROP_INPUT_FENCE: case PLANE_PROP_BLEND_OP: + case PLANE_PROP_FOD: /* no special action required */ break; case PLANE_PROP_FB_TRANSLATION_MODE: @@ -4381,8 +4382,6 @@ static void _sde_plane_install_properties(struct drm_plane *plane, const struct sde_format_extended *format_list; struct sde_kms_info *info; struct sde_plane *psde = to_sde_plane(plane); - int zpos_max = 255; - int zpos_def = 0; char feature_name[256]; if (!plane || !psde) { @@ -4399,24 +4398,11 @@ static void _sde_plane_install_properties(struct drm_plane *plane, psde->catalog = catalog; - if (sde_is_custom_client()) { - if (catalog->mixer_count && - catalog->mixer[0].sblk->maxblendstages) { - zpos_max = catalog->mixer[0].sblk->maxblendstages - 1; - - if (catalog->has_base_layer && - (zpos_max > SDE_STAGE_MAX - 1)) - zpos_max = SDE_STAGE_MAX - 1; - else if (zpos_max > SDE_STAGE_MAX - SDE_STAGE_0 - 1) - zpos_max = SDE_STAGE_MAX - SDE_STAGE_0 - 1; - } - } else if (plane->type != DRM_PLANE_TYPE_PRIMARY) { - /* reserve zpos == 0 for primary planes */ - zpos_def = drm_plane_index(plane) + 1; - } - msm_property_install_range(&psde->property_info, "zpos", - 0x0, 0, zpos_max, zpos_def, PLANE_PROP_ZPOS); + 0x0, 0, INT_MAX, 0, PLANE_PROP_ZPOS); + + msm_property_install_range(&psde->property_info, "fod", + 0x0, 0, INT_MAX, 0, PLANE_PROP_FOD); msm_property_install_range(&psde->property_info, "alpha", 0x0, 0, 255, 255, PLANE_PROP_ALPHA); @@ -4855,6 +4841,8 @@ static int sde_plane_atomic_set_property(struct drm_plane *plane, { struct sde_plane *psde = plane ? to_sde_plane(plane) : NULL; struct sde_plane_state *pstate; + struct drm_property *fod_property; + uint64_t fod_val = 0; int idx, ret = -EINVAL; SDE_DEBUG_PLANE(psde, "\n"); @@ -4865,11 +4853,25 @@ static int sde_plane_atomic_set_property(struct drm_plane *plane, SDE_ERROR_PLANE(psde, "invalid state\n"); } else { pstate = to_sde_plane_state(state); + idx = msm_property_index(&psde->property_info, + property); + if (idx == PLANE_PROP_ZPOS) { + if (val & 0x20000000u) { + val &= ~0x20000000u; + fod_val = 1; + } + + fod_property = psde->property_info. + property_array[PLANE_PROP_FOD]; + ret = msm_property_atomic_set(&psde->property_info, + &pstate->property_state, + fod_property, fod_val); + if (ret) + SDE_ERROR("failed to set fod prop"); + } ret = msm_property_atomic_set(&psde->property_info, &pstate->property_state, property, val); if (!ret) { - idx = msm_property_index(&psde->property_info, - property); switch (idx) { case PLANE_PROP_INPUT_FENCE: _sde_plane_set_input_fence(psde, pstate, val); From 4f39124396486672e7fddde4879bde1c9f60fab9 Mon Sep 17 00:00:00 2001 From: DevriesL Date: Mon, 31 Dec 2018 21:42:21 +0800 Subject: [PATCH 020/226] drivers: gpu: drm: msm: dsi-staging: add get_main_display Change-Id: Id670875adc18659521c424a716cf0ef194f9627f Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_display.c | 7 +++++++ drivers/gpu/drm/msm/dsi-staging/dsi_display.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index 0889cb8f3a7e..3694720b94ed 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -61,6 +61,8 @@ static const struct of_device_id dsi_display_dt_match[] = { {} }; +struct dsi_display *primary_display; + static void dsi_display_mask_ctrl_error_interrupts(struct dsi_display *display, u32 mask, bool enable) { @@ -6435,6 +6437,7 @@ int dsi_display_get_modes(struct dsi_display *display, exit: *out_modes = display->modes; rc = 0; + primary_display = display; error: if (rc) @@ -7828,6 +7831,10 @@ int dsi_display_unprepare(struct dsi_display *display) return rc; } +struct dsi_display *get_main_display(void) { + return primary_display; +} + static int __init dsi_display_register(void) { dsi_phy_drv_register(); diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h index 7bf06a243c5a..694304fd722b 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h @@ -712,4 +712,6 @@ int dsi_display_cont_splash_config(void *display); int dsi_display_get_panel_vfp(void *display, int h_active, int v_active); +struct dsi_display *get_main_display(void); + #endif /* _DSI_DISPLAY_H_ */ From 703edf72133eba9b355890dc03661d62e06c482f Mon Sep 17 00:00:00 2001 From: Demon000 Date: Mon, 25 May 2020 13:21:16 +0200 Subject: [PATCH 021/226] drivers: gpu: drm: msm: dsi-staging: add dsi_panel_get_backlight Change-Id: Ifab7f9b0a7fbe5846c24c611a16cfcb7f29684dc Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 63b71103751a..3fd8f3056dc1 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -689,6 +689,11 @@ static int dsi_panel_update_pwm_backlight(struct dsi_panel *panel, return rc; } +static u32 dsi_panel_get_backlight(struct dsi_panel *panel) +{ + return panel->bl_config.bl_level; +} + int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl) { int rc = 0; From 60eef6e311b231ca65b9c669e07ac0ee43afa821 Mon Sep 17 00:00:00 2001 From: Demon000 Date: Mon, 6 Apr 2020 01:02:05 +0200 Subject: [PATCH 022/226] drivers: gpu: drm: msm: implement fod handling Change-Id: Id29333eb3b5282b25c52ff14492622bd12e1ee79 Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_defs.h | 2 + drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 117 ++++++++++++++++++++ drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 13 +++ drivers/gpu/drm/msm/sde/sde_connector.c | 35 ++++++ drivers/gpu/drm/msm/sde/sde_crtc.c | 87 +++++++++++++++ drivers/gpu/drm/msm/sde/sde_crtc.h | 1 + drivers/gpu/drm/msm/sde/sde_plane.c | 12 ++ drivers/gpu/drm/msm/sde/sde_plane.h | 2 + 8 files changed, 269 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h index 3613e8e1588b..c1817b9612f8 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h @@ -308,6 +308,8 @@ enum dsi_cmd_set_type { DSI_CMD_SET_POST_TIMING_SWITCH, DSI_CMD_SET_QSYNC_ON, DSI_CMD_SET_QSYNC_OFF, + DSI_CMD_SET_DISP_HBM_FOD_ON, + DSI_CMD_SET_DISP_HBM_FOD_OFF, DSI_CMD_SET_MAX }; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 3fd8f3056dc1..896be2ff23b0 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -694,6 +694,53 @@ static u32 dsi_panel_get_backlight(struct dsi_panel *panel) return panel->bl_config.bl_level; } +static u32 interpolate(uint32_t x, uint32_t xa, uint32_t xb, uint32_t ya, uint32_t yb) +{ + return ya - (ya - yb) * (x - xa) / (xb - xa); +} + +u32 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel) +{ + u32 brightness = dsi_panel_get_backlight(panel); + int i; + + if (!panel->fod_dim_lut) + return 0; + + for (i = 0; i < panel->fod_dim_lut_count; i++) + if (panel->fod_dim_lut[i].brightness >= brightness) + break; + + if (i == 0) + return panel->fod_dim_lut[i].alpha; + + if (i == panel->fod_dim_lut_count) + return panel->fod_dim_lut[i - 1].alpha; + + return interpolate(brightness, + panel->fod_dim_lut[i - 1].brightness, panel->fod_dim_lut[i].brightness, + panel->fod_dim_lut[i - 1].alpha, panel->fod_dim_lut[i].alpha); +} + +int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status) +{ + int rc = 0; + + if (status) { + rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_HBM_FOD_ON); + if (rc) + pr_err("[%s] failed to send DSI_CMD_SET_DISP_HBM_FOD_ON cmd, rc=%d\n", + panel->name, rc); + } else { + rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_HBM_FOD_OFF); + if (rc) + pr_err("[%s] failed to send DSI_CMD_SET_DISP_HBM_FOD_OFF cmd, rc=%d\n", + panel->name, rc); + } + + return rc; +} + int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl) { int rc = 0; @@ -1762,6 +1809,8 @@ const char *cmd_set_prop_map[DSI_CMD_SET_MAX] = { "qcom,mdss-dsi-post-mode-switch-on-command", "qcom,mdss-dsi-qsync-on-commands", "qcom,mdss-dsi-qsync-off-commands", + "qcom,mdss-dsi-dispparam-hbm-fod-on-command", + "qcom,mdss-dsi-dispparam-hbm-fod-off-command", }; const char *cmd_set_state_map[DSI_CMD_SET_MAX] = { @@ -1788,6 +1837,8 @@ const char *cmd_set_state_map[DSI_CMD_SET_MAX] = { "qcom,mdss-dsi-post-mode-switch-on-command-state", "qcom,mdss-dsi-qsync-on-commands-state", "qcom,mdss-dsi-qsync-off-commands-state", + "qcom,mdss-dsi-dispparam-hbm-fod-on-command-state", + "qcom,mdss-dsi-dispparam-hbm-fod-off-command-state", }; static int dsi_panel_get_cmd_pkt_count(const char *data, u32 length, u32 *cnt) @@ -2254,6 +2305,68 @@ static int dsi_panel_parse_bl_pwm_config(struct dsi_panel *panel) return rc; } +static int dsi_panel_parse_fod_dim_lut(struct dsi_panel *panel, + struct dsi_parser_utils *utils) +{ + struct brightness_alpha_pair *lut; + u32 *array; + int count; + int len; + int rc; + int i; + + len = utils->count_u32_elems(utils->data, "qcom,disp-fod-dim-lut"); + if (len <= 0 || len % BRIGHTNESS_ALPHA_PAIR_LEN) { + pr_err("[%s] invalid number of elements, rc=%d\n", + panel->name, rc); + rc = -EINVAL; + goto count_fail; + } + + array = kcalloc(len, sizeof(u32), GFP_KERNEL); + if (!array) { + pr_err("[%s] failed to allocate memory, rc=%d\n", + panel->name, rc); + rc = -ENOMEM; + goto alloc_array_fail; + } + + rc = utils->read_u32_array(utils->data, + "qcom,disp-fod-dim-lut", array, len); + if (rc) { + pr_err("[%s] failed to allocate memory, rc=%d\n", + panel->name, rc); + goto read_fail; + } + + count = len / BRIGHTNESS_ALPHA_PAIR_LEN; + lut = kcalloc(count, sizeof(*lut), GFP_KERNEL); + if (!lut) { + rc = -ENOMEM; + goto alloc_lut_fail; + } + + for (i = 0; i < count; i++) { + struct brightness_alpha_pair *pair = &lut[i]; + pair->brightness = array[i * BRIGHTNESS_ALPHA_PAIR_LEN + 0]; + pair->alpha = array[i * BRIGHTNESS_ALPHA_PAIR_LEN + 1]; + } + + panel->fod_dim_lut = lut; + panel->fod_dim_lut_count = count; + +alloc_lut_fail: +read_fail: + kfree(array); +alloc_array_fail: +count_fail: + if (rc) { + panel->fod_dim_lut = NULL; + panel->fod_dim_lut_count = 0; + } + return rc; +} + static int dsi_panel_parse_bl_config(struct dsi_panel *panel) { int rc = 0; @@ -2343,6 +2456,10 @@ static int dsi_panel_parse_bl_config(struct dsi_panel *panel) panel->bl_config.bl_inverted_dbv = utils->read_bool(utils->data, "qcom,mdss-dsi-bl-inverted-dbv"); + rc = dsi_panel_parse_fod_dim_lut(panel, utils); + if (rc) + pr_err("[%s failed to parse fod dim lut\n", panel->name); + if (panel->bl_config.type == DSI_BACKLIGHT_PWM) { rc = dsi_panel_parse_bl_pwm_config(panel); if (rc) { diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index fcf1ba3db846..d36d69006282 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -169,6 +169,12 @@ struct drm_panel_esd_config { u32 groups; }; +#define BRIGHTNESS_ALPHA_PAIR_LEN 2 +struct brightness_alpha_pair { + u32 brightness; + u32 alpha; +}; + struct dsi_panel { const char *name; const char *type; @@ -219,6 +225,9 @@ struct dsi_panel { bool sync_broadcast_en; int power_mode; enum dsi_panel_physical_type panel_type; + + struct brightness_alpha_pair *fod_dim_lut; + u32 fod_dim_lut_count; }; static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel) @@ -339,4 +348,8 @@ int dsi_panel_parse_esd_reg_read_configs(struct dsi_panel *panel); void dsi_panel_ext_bridge_put(struct dsi_panel *panel); +int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status); + +u32 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel); + #endif /* _DSI_PANEL_H_ */ diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c index d0f36c7a00bf..5e909b003f15 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.c +++ b/drivers/gpu/drm/msm/sde/sde_connector.c @@ -583,6 +583,39 @@ static int _sde_connector_update_dirty_properties( return 0; } +void sde_connector_update_fod_hbm(struct drm_connector *connector) +{ + static atomic_t effective_status = ATOMIC_INIT(false); + struct sde_crtc_state *cstate; + struct sde_connector *c_conn; + struct dsi_display *display; + bool status; + + if (!connector) { + SDE_ERROR("invalid connector\n"); + return; + } + + c_conn = to_sde_connector(connector); + if (c_conn->connector_type != DRM_MODE_CONNECTOR_DSI) + return; + + display = (struct dsi_display *) c_conn->display; + + if (!c_conn->encoder || !c_conn->encoder->crtc || + !c_conn->encoder->crtc->state) + return; + + cstate = to_sde_crtc_state(c_conn->encoder->crtc->state); + status = cstate->fod_dim_layer != NULL; + if (atomic_xchg(&effective_status, status) == status) + return; + + mutex_lock(&display->panel->panel_lock); + dsi_panel_set_fod_hbm(display->panel, status); + mutex_unlock(&display->panel->panel_lock); +} + int sde_connector_pre_kickoff(struct drm_connector *connector) { struct sde_connector *c_conn; @@ -616,6 +649,8 @@ int sde_connector_pre_kickoff(struct drm_connector *connector) SDE_EVT32_VERBOSE(connector->base.id); + sde_connector_update_fod_hbm(connector); + rc = c_conn->ops.pre_kickoff(connector, c_conn->display, ¶ms); end: diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index f39c40c86b98..39e8d9605b0c 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -42,6 +42,7 @@ #include "sde_power_handle.h" #include "sde_core_perf.h" #include "sde_trace.h" +#include "dsi_display.h" #define SDE_PSTATES_MAX (SDE_STAGE_MAX * 4) #define SDE_MULTIRECT_PLANE_MAX (SDE_STAGE_MAX * 2) @@ -2187,6 +2188,10 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, for (i = 0; i < cstate->num_dim_layers; i++) _sde_crtc_setup_dim_layer_cfg(crtc, sde_crtc, mixer, &cstate->dim_layer[i]); + + if (cstate->fod_dim_layer) + _sde_crtc_setup_dim_layer_cfg(crtc, sde_crtc, + mixer, cstate->fod_dim_layer); } _sde_crtc_program_lm_output_roi(crtc); @@ -5301,6 +5306,86 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc, return 0; } +static struct sde_hw_dim_layer* sde_crtc_setup_fod_dim_layer( + struct sde_crtc_state *cstate, + uint32_t stage) +{ + struct drm_crtc_state *crtc_state = &cstate->base; + struct drm_display_mode *mode = &crtc_state->adjusted_mode; + struct sde_hw_dim_layer *dim_layer = NULL; + struct dsi_display *display; + struct sde_kms *kms; + uint32_t layer_stage; + uint32_t alpha; + + kms = _sde_crtc_get_kms(crtc_state->crtc); + if (!kms || !kms->catalog) { + SDE_ERROR("Invalid kms\n"); + goto error; + } + + layer_stage = SDE_STAGE_0 + stage; + if (layer_stage >= kms->catalog->mixer[0].sblk->maxblendstages) { + SDE_ERROR("Stage too large %u vs max %u\n", layer_stage, + kms->catalog->mixer[0].sblk->maxblendstages); + goto error; + } + + if (cstate->num_dim_layers == SDE_MAX_DIM_LAYERS) { + SDE_ERROR("Max dim layers reached\n"); + goto error; + } + + display = get_main_display(); + if (!display || !display->panel) { + SDE_ERROR("Invalid primary display\n"); + goto error; + } + + mutex_lock(&display->panel->panel_lock); + alpha = dsi_panel_get_fod_dim_alpha(display->panel); + mutex_unlock(&display->panel->panel_lock); + + dim_layer = &cstate->dim_layer[cstate->num_dim_layers]; + dim_layer->flags = SDE_DRM_DIM_LAYER_INCLUSIVE; + dim_layer->stage = layer_stage; + dim_layer->rect.x = 0; + dim_layer->rect.y = 0; + dim_layer->rect.w = mode->hdisplay; + dim_layer->rect.h = mode->vdisplay; + dim_layer->color_fill = + (struct sde_mdss_color) {0, 0, 0, alpha}; + +error: + return dim_layer; +} + +static void sde_crtc_fod_atomic_check(struct sde_crtc_state *cstate, + struct plane_state *pstates, int cnt) +{ + uint32_t dim_layer_stage; + int plane_idx; + + for (plane_idx = 0; plane_idx < cnt; plane_idx++) + if (sde_plane_is_fod_layer(pstates[plane_idx].drm_pstate)) + break; + + if (plane_idx == cnt) { + cstate->fod_dim_layer = NULL; + } else { + dim_layer_stage = pstates[plane_idx].stage; + cstate->fod_dim_layer = sde_crtc_setup_fod_dim_layer(cstate, + dim_layer_stage); + } + + if (!cstate->fod_dim_layer) + return; + + for (plane_idx = 0; plane_idx < cnt; plane_idx++) + if (pstates[plane_idx].stage >= dim_layer_stage) + pstates[plane_idx].stage++; +} + static int sde_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -5496,6 +5581,8 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc, } } + sde_crtc_fod_atomic_check(cstate, pstates, cnt); + /* assign mixer stages based on sorted zpos property */ if (cnt > 0) sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL); diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h index 0357ab4f4dfe..b4f52df21cc7 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.h +++ b/drivers/gpu/drm/msm/sde/sde_crtc.h @@ -422,6 +422,7 @@ struct sde_crtc_state { uint64_t input_fence_timeout_ns; uint32_t num_dim_layers; struct sde_hw_dim_layer dim_layer[SDE_MAX_DIM_LAYERS]; + struct sde_hw_dim_layer *fod_dim_layer; uint32_t num_ds; uint32_t num_ds_enabled; bool ds_dirty; diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index 7e6887476cb9..5fe08e3afe29 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -4298,6 +4298,18 @@ static void _sde_plane_atomic_disable(struct drm_plane *plane, SDE_SSPP_RECT_SOLO, SDE_SSPP_MULTIRECT_NONE); } +int sde_plane_is_fod_layer(const struct drm_plane_state *drm_state) +{ + struct sde_plane_state *pstate; + + if (!drm_state) + return 0; + + pstate = to_sde_plane_state(drm_state); + + return sde_plane_get_property(pstate, PLANE_PROP_FOD); +} + static void sde_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { diff --git a/drivers/gpu/drm/msm/sde/sde_plane.h b/drivers/gpu/drm/msm/sde/sde_plane.h index b128fb9475cc..bd8b633e2375 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.h +++ b/drivers/gpu/drm/msm/sde/sde_plane.h @@ -398,4 +398,6 @@ void sde_plane_clear_ubwc_error(struct drm_plane *plane); void sde_plane_setup_src_split_order(struct drm_plane *plane, enum sde_sspp_multirect_index rect_mode, bool enable); +int sde_plane_is_fod_layer(const struct drm_plane_state *drm_state); + #endif /* _SDE_PLANE_H_ */ From 4061cecd09ca6ccb72d7db9bc3792575929add41 Mon Sep 17 00:00:00 2001 From: Demon000 Date: Thu, 28 May 2020 23:04:27 +0200 Subject: [PATCH 023/226] drivers: gpu: drm: msm: notify sysfs for fod ui changes Change-Id: I5559a9cfe00af58847e089764452a24c39830e20 Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_display.c | 30 +++++++++++++++++++ drivers/gpu/drm/msm/dsi-staging/dsi_display.h | 4 +++ drivers/gpu/drm/msm/sde/sde_connector.c | 2 ++ 3 files changed, 36 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index 3694720b94ed..63cdcf175538 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -5046,7 +5046,29 @@ static int dsi_display_validate_split_link(struct dsi_display *display) return rc; } +static ssize_t sysfs_fod_ui_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dsi_display *display; + bool status; + + display = dev_get_drvdata(dev); + if (!display) { + pr_err("Invalid display\n"); + return -EINVAL; + } + + status = atomic_read(&display->fod_ui); + + return snprintf(buf, PAGE_SIZE, "%d\n", status); +} + +static DEVICE_ATTR(fod_ui, 0444, + sysfs_fod_ui_read, + NULL); + static struct attribute *display_fs_attrs[] = { + &dev_attr_fod_ui.attr, NULL, }; static struct attribute_group display_fs_attrs_group = { @@ -5082,6 +5104,13 @@ static int dsi_display_sysfs_deinit(struct dsi_display *display) } +void dsi_display_set_fod_ui(struct dsi_display *display, bool status) +{ + struct device *dev = &display->pdev->dev; + atomic_set(&display->fod_ui, status); + sysfs_notify(&dev->kobj, NULL, "fod_ui"); +} + /** * dsi_display_bind - bind dsi device with controlling device * @dev: Pointer to base of platform device @@ -5378,6 +5407,7 @@ static void dsi_display_unbind(struct device *dev, } atomic_set(&display->clkrate_change_pending, 0); + atomic_set(&display->fod_ui, false); (void)dsi_display_sysfs_deinit(display); (void)dsi_display_debugfs_deinit(display); diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h index 694304fd722b..73d8b5ac29dd 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h @@ -281,6 +281,8 @@ struct dsi_display { struct dsi_display_boot_param *boot_disp; u32 te_source; + + atomic_t fod_ui; }; int dsi_display_dev_probe(struct platform_device *pdev); @@ -714,4 +716,6 @@ int dsi_display_get_panel_vfp(void *display, struct dsi_display *get_main_display(void); +void dsi_display_set_fod_ui(struct dsi_display *display, bool status); + #endif /* _DSI_DISPLAY_H_ */ diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c index 5e909b003f15..30a9dbd1d18a 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.c +++ b/drivers/gpu/drm/msm/sde/sde_connector.c @@ -614,6 +614,8 @@ void sde_connector_update_fod_hbm(struct drm_connector *connector) mutex_lock(&display->panel->panel_lock); dsi_panel_set_fod_hbm(display->panel, status); mutex_unlock(&display->panel->panel_lock); + + dsi_display_set_fod_ui(display, status); } int sde_connector_pre_kickoff(struct drm_connector *connector) From 762e0dd6dec664d740b8aafc27b14f0c3464be53 Mon Sep 17 00:00:00 2001 From: Demon000 Date: Mon, 8 Jun 2020 17:16:57 +0200 Subject: [PATCH 024/226] drivers: gpu: drm: msm: dsi-staging: cleanup notifier implementation Change-Id: If60a789b666cd2c5ab767406d2aeabb03f38ba5b Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index 63cdcf175538..d4fc8b2c094c 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -1063,7 +1063,6 @@ int dsi_display_set_power(struct drm_connector *connector, { struct dsi_display *display = disp; struct msm_drm_notifier notify_data; - int event = power_mode; int rc = 0; if (!display || !display->panel) { @@ -1071,7 +1070,8 @@ int dsi_display_set_power(struct drm_connector *connector, return -EINVAL; } - notify_data.data = &event; + notify_data.data = &power_mode; + notify_data.id = MSM_DRM_PRIMARY_DISPLAY; switch (power_mode) { case SDE_MODE_DPMS_LP1: From 67b764adca6da401367347794490b0435361eb89 Mon Sep 17 00:00:00 2001 From: Demon000 Date: Mon, 8 Jun 2020 17:06:19 +0200 Subject: [PATCH 025/226] drivers: gpu: drm: msm: atomic: do not trigger drm notifier Change-Id: I185253d2dab8f4f88b38e95e5ac2332667b6a011 Signed-off-by: firebird11 --- drivers/gpu/drm/msm/msm_atomic.c | 41 ++------------------------------ 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index d681a20d2080..8d00a9652ea9 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -218,8 +218,7 @@ msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) struct drm_connector_state *old_conn_state; struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state; - struct msm_drm_notifier notifier_data; - int i, blank; + int i; SDE_ATRACE_BEGIN("msm_disable"); for_each_connector_in_state(old_state, connector, old_conn_state, i) { @@ -259,14 +258,6 @@ msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) DRM_DEBUG_ATOMIC("disabling [ENCODER:%d:%s]\n", encoder->base.id, encoder->name); - if (connector->state->crtc && - connector->state->crtc->state->active_changed) { - blank = MSM_DRM_BLANK_POWERDOWN; - notifier_data.data = ␣ - notifier_data.id = crtc_idx; - msm_drm_notifier_call_chain(MSM_DRM_EARLY_EVENT_BLANK, - ¬ifier_data); - } /* * Each encoder has at most one connector (since we always steal * it away), so we won't call disable hooks twice. @@ -282,12 +273,6 @@ msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) funcs->dpms(encoder, DRM_MODE_DPMS_OFF); drm_bridge_post_disable(encoder->bridge); - if (connector->state->crtc && - connector->state->crtc->state->active_changed) { - DRM_DEBUG_ATOMIC("Notify blank\n"); - msm_drm_notifier_call_chain(MSM_DRM_EVENT_BLANK, - ¬ifier_data); - } } for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { @@ -428,12 +413,10 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, struct drm_crtc_state *new_crtc_state; struct drm_connector *connector; struct drm_connector_state *new_conn_state; - struct msm_drm_notifier notifier_data; struct msm_drm_private *priv = dev->dev_private; struct msm_kms *kms = priv->kms; int bridge_enable_count = 0; - int i, blank; - bool splash = false; + int i; SDE_ATRACE_BEGIN("msm_enable"); for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, @@ -493,19 +476,6 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n", encoder->base.id, encoder->name); - if (kms && kms->funcs && kms->funcs->check_for_splash) - splash = kms->funcs->check_for_splash(kms); - - if (splash || (connector->state->crtc && - connector->state->crtc->state->active_changed)) { - blank = MSM_DRM_BLANK_UNBLANK; - notifier_data.data = ␣ - notifier_data.id = - connector->state->crtc->index; - DRM_DEBUG_ATOMIC("Notify early unblank\n"); - msm_drm_notifier_call_chain(MSM_DRM_EARLY_EVENT_BLANK, - ¬ifier_data); - } /* * Each encoder has at most one connector (since we always steal * it away), so we won't call enable hooks twice. @@ -554,13 +524,6 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, encoder->base.id, encoder->name); drm_bridge_enable(encoder->bridge); - - if (splash || (connector->state->crtc && - connector->state->crtc->state->active_changed)) { - DRM_DEBUG_ATOMIC("Notify unblank\n"); - msm_drm_notifier_call_chain(MSM_DRM_EVENT_BLANK, - ¬ifier_data); - } } SDE_ATRACE_END("msm_enable"); } From e6ee6bb777835c4760ddf3ef02b80859cf9e2195 Mon Sep 17 00:00:00 2001 From: Demon000 Date: Mon, 8 Jun 2020 17:18:11 +0200 Subject: [PATCH 026/226] drivers: gpu: drm: msm: dsi-staging: trigger drm notifier Change-Id: I225b36292f96eafb0703e3f0701f924f20b186d5 Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_drm.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c index 3e4de45ea5b2..6a1f452dcb0a 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c @@ -14,6 +14,8 @@ #define pr_fmt(fmt) "dsi-drm:[%s] " fmt, __func__ +#include + #include #include @@ -172,6 +174,8 @@ static void dsi_bridge_pre_enable(struct drm_bridge *bridge) { int rc = 0; struct dsi_bridge *c_bridge = to_dsi_bridge(bridge); + struct msm_drm_notifier notify_data; + int power_mode; if (!bridge) { pr_err("Invalid params\n"); @@ -186,6 +190,11 @@ static void dsi_bridge_pre_enable(struct drm_bridge *bridge) if (bridge->encoder->crtc->state->active_changed) atomic_set(&c_bridge->display->panel->esd_recovery_pending, 0); + power_mode = sde_connector_get_lp(c_bridge->display->drm_conn); + notify_data.data = &power_mode; + notify_data.id = MSM_DRM_PRIMARY_DISPLAY; + msm_drm_notifier_call_chain(MSM_DRM_EARLY_EVENT_BLANK, ¬ify_data); + /* By this point mode should have been validated through mode_fixup */ rc = dsi_display_set_mode(c_bridge->display, &(c_bridge->dsi_mode), 0x0); @@ -221,6 +230,8 @@ static void dsi_bridge_pre_enable(struct drm_bridge *bridge) } SDE_ATRACE_END("dsi_display_enable"); + msm_drm_notifier_call_chain(MSM_DRM_EVENT_BLANK, ¬ify_data); + rc = dsi_display_splash_res_cleanup(c_bridge->display); if (rc) pr_err("Continuous splash pipeline cleanup failed, rc=%d\n", @@ -292,12 +303,19 @@ static void dsi_bridge_post_disable(struct drm_bridge *bridge) { int rc = 0; struct dsi_bridge *c_bridge = to_dsi_bridge(bridge); + struct msm_drm_notifier notify_data; + int power_mode; if (!bridge) { pr_err("Invalid params\n"); return; } + power_mode = sde_connector_get_lp(c_bridge->display->drm_conn); + notify_data.data = &power_mode; + notify_data.id = MSM_DRM_PRIMARY_DISPLAY; + msm_drm_notifier_call_chain(MSM_DRM_EARLY_EVENT_BLANK, ¬ify_data); + SDE_ATRACE_BEGIN("dsi_bridge_post_disable"); SDE_ATRACE_BEGIN("dsi_display_disable"); rc = dsi_display_disable(c_bridge->display); @@ -317,6 +335,8 @@ static void dsi_bridge_post_disable(struct drm_bridge *bridge) return; } SDE_ATRACE_END("dsi_bridge_post_disable"); + + msm_drm_notifier_call_chain(MSM_DRM_EVENT_BLANK, ¬ify_data); } static void dsi_bridge_mode_set(struct drm_bridge *bridge, From c13076bcf7ab732cc6d7f17fdb0603975542879c Mon Sep 17 00:00:00 2001 From: Pig Date: Fri, 14 Aug 2020 20:06:43 +0800 Subject: [PATCH 027/226] drivers: gpu: drm: msm: Export FOD_PRESSED_LAYER_ZORDER to uapi Change-Id: I5b25d19fab3a2901948d639c785165e70786f4ab Signed-off-by: firebird11 --- drivers/gpu/drm/msm/sde/sde_plane.c | 4 ++-- include/uapi/drm/sde_drm.h | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index 5fe08e3afe29..285ebf05394b 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -4868,8 +4868,8 @@ static int sde_plane_atomic_set_property(struct drm_plane *plane, idx = msm_property_index(&psde->property_info, property); if (idx == PLANE_PROP_ZPOS) { - if (val & 0x20000000u) { - val &= ~0x20000000u; + if (val & FOD_PRESSED_LAYER_ZORDER) { + val &= ~FOD_PRESSED_LAYER_ZORDER; fod_val = 1; } diff --git a/include/uapi/drm/sde_drm.h b/include/uapi/drm/sde_drm.h index d241a307f4ec..7676aaed21dc 100644 --- a/include/uapi/drm/sde_drm.h +++ b/include/uapi/drm/sde_drm.h @@ -495,4 +495,9 @@ struct sde_drm_roi_misr_v1 { #define SDE_RECOVERY_CAPTURE 1 #define SDE_RECOVERY_HARD_RESET 2 +/** + * sde fod dim layer + */ +#define FOD_PRESSED_LAYER_ZORDER 0x20000000u + #endif /* _SDE_DRM_H_ */ From 5565d2feaaed840e1c45c57b14d41588b30b509d Mon Sep 17 00:00:00 2001 From: GuaiYiHu Date: Thu, 13 Aug 2020 12:25:09 +0800 Subject: [PATCH 028/226] drivers: gpu: drm: msm: sde: Increase sde stage to map zpos changes * Another stage should be added, otherwise fingerprint payment won't work in some apps like Alipay and Jingdong. Change-Id: Ibbd928b6d75c17f9c6c2e8b6f72b2d17aa48eb94 Signed-off-by: firebird11 --- drivers/gpu/drm/msm/sde/sde_hw_mdss.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h index bd3ef45df834..fbbec709a569 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h @@ -174,6 +174,7 @@ enum sde_stage { SDE_STAGE_8, SDE_STAGE_9, SDE_STAGE_10, + SDE_STAGE_11, SDE_STAGE_MAX }; enum sde_dspp { From a8e372c0d914fd136fe0a5d457a7e57512996b3a Mon Sep 17 00:00:00 2001 From: Demon000 Date: Tue, 18 Feb 2020 23:00:01 +0200 Subject: [PATCH 029/226] arch: arm64: boot: dts: qcom: ea8076: move fod hbm commands to their proper place Change-Id: Ia8a6cd27fbf63aeadbe2577cfb56b9d56fe0687c Signed-off-by: firebird11 --- .../dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi | 45 ++++++++++--------- ...dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi | 45 ++++++++++--------- ...i-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi | 45 ++++++++++--------- ...dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi | 45 ++++++++++--------- .../dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi | 45 ++++++++++--------- .../display/dsi-panel-ss-fhd-ea8076-cmd.dtsi | 45 ++++++++++--------- .../dsi-panel-ss-fhd-ea8076-global-cmd.dtsi | 45 ++++++++++--------- 7 files changed, 161 insertions(+), 154 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi index 3c1462365a3c..36343965a01f 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi @@ -72,28 +72,6 @@ qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; qcom,mdss-dsi-display-timings { timing@0{ @@ -248,6 +226,29 @@ 39 01 00 00 01 00 03 F0 A5 A5]; qcom,mdss-dsi-dispparam-elvss-dimming-off-command-state = "dsi_lp_mode"; qcom,mdss-dsi-h-sync-pulse = <0>; + + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi index 42c7ecc8ea2b..76e9564aa8a9 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi @@ -72,28 +72,6 @@ qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; qcom,mdss-dsi-display-timings { timing@0{ @@ -248,6 +226,29 @@ 39 01 00 00 01 00 03 F0 A5 A5]; qcom,mdss-dsi-dispparam-elvss-dimming-off-command-state = "dsi_lp_mode"; qcom,mdss-dsi-h-sync-pulse = <0>; + + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi index 437185f1b1a1..04444e5ac51c 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi @@ -72,28 +72,6 @@ qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; qcom,mdss-dsi-display-timings { timing@0{ @@ -248,6 +226,29 @@ 39 01 00 00 01 00 03 F0 A5 A5]; qcom,mdss-dsi-dispparam-elvss-dimming-off-command-state = "dsi_lp_mode"; qcom,mdss-dsi-h-sync-pulse = <0>; + + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi index 15821d208877..76e961997e9f 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi @@ -72,28 +72,6 @@ qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; qcom,mdss-dsi-display-timings { timing@0{ @@ -248,6 +226,29 @@ 39 01 00 00 01 00 03 F0 A5 A5]; qcom,mdss-dsi-dispparam-elvss-dimming-off-command-state = "dsi_lp_mode"; qcom,mdss-dsi-h-sync-pulse = <0>; + + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi index c8b8191aaccb..d01da4830701 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi @@ -72,28 +72,6 @@ qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; /* WHITE POINT COMMAND */ qcom,mdss-dsi-panel-white-point-read-length = <8>; @@ -271,6 +249,29 @@ ]; qcom,mdss-dsi-dispparam-flat-off-command-state = "dsi_lp_mode"; qcom,mdss-dsi-h-sync-pulse = <0>; + + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi index 45b9d84193d4..582642725c12 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi @@ -73,28 +73,6 @@ qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; qcom,mdss-dsi-display-timings { timing@0{ @@ -236,6 +214,29 @@ 39 01 00 00 01 00 03 F0 A5 A5]; qcom,mdss-dsi-dispparam-elvss-dimming-off-command-state = "dsi_lp_mode"; qcom,mdss-dsi-h-sync-pulse = <0>; + + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi index ffcca35361db..4f66145f9f4c 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi @@ -73,28 +73,6 @@ qcom,mdss-dsi-dispparam-elvss-dimming-offset-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-elvss-dimming-read-command = [06 01 00 01 00 00 01 B7]; qcom,mdss-dsi-dispparam-elvss-dimming-read-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; qcom,mdss-dsi-display-timings { timing@0{ @@ -236,6 +214,29 @@ 39 01 00 00 01 00 03 F0 A5 A5]; qcom,mdss-dsi-dispparam-elvss-dimming-off-command-state = "dsi_lp_mode"; qcom,mdss-dsi-h-sync-pulse = <0>; + + qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ + 39 01 00 00 00 00 02 53 20 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 4B + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 49 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 02 B0 03 + 39 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 02 B0 07 + 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 03 F0 A5 A5 + 39 01 00 00 01 00 02 53 E0 + 39 00 00 00 00 00 03 F0 5A 5A + 39 00 00 00 00 00 03 B7 01 43 + 39 01 00 00 01 00 03 F0 A5 A5]; + qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; }; From c581571d6eb0b75e8c90f3d9915366bb62d1d166 Mon Sep 17 00:00:00 2001 From: Demon000 Date: Tue, 18 Feb 2020 23:03:10 +0200 Subject: [PATCH 030/226] arch: arm64: boot: dts: qcom: ea8076: disable dc dimming during fod hbm commands Change-Id: If7d461b5f0a02118c5307b962a507269e1fdce71 Signed-off-by: firebird11 --- .../common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi | 2 +- .../common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi | 2 +- .../display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi | 2 +- .../common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi | 2 +- .../common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi | 4 ++-- .../overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi | 2 +- .../common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi index 36343965a01f..b0b7d5341540 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi @@ -242,7 +242,7 @@ 39 00 00 00 00 00 02 B0 03 39 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 02 B7 11 39 00 00 00 00 00 03 F0 A5 A5 39 01 00 00 01 00 02 53 E0 39 00 00 00 00 00 03 F0 5A 5A diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi index 76e9564aa8a9..75bf0dd6e661 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi @@ -242,7 +242,7 @@ 39 00 00 00 00 00 02 B0 03 39 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 02 B7 11 39 00 00 00 00 00 03 F0 A5 A5 39 01 00 00 01 00 02 53 E0 39 00 00 00 00 00 03 F0 5A 5A diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi index 04444e5ac51c..9110a4e77e8c 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi @@ -242,7 +242,7 @@ 39 00 00 00 00 00 02 B0 03 39 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 02 B7 11 39 00 00 00 00 00 03 F0 A5 A5 39 01 00 00 01 00 02 53 E0 39 00 00 00 00 00 03 F0 5A 5A diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi index 76e961997e9f..47082c5b33ab 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi @@ -242,7 +242,7 @@ 39 00 00 00 00 00 02 B0 03 39 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 02 B7 11 39 00 00 00 00 00 03 F0 A5 A5 39 01 00 00 01 00 02 53 E0 39 00 00 00 00 00 03 F0 5A 5A diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi index d01da4830701..1ece198956d7 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi @@ -257,7 +257,7 @@ 39 00 00 00 00 00 02 B0 03 39 00 00 00 00 00 02 B7 49 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 02 B7 11 39 01 00 00 01 00 03 F0 A5 A5]; qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ @@ -265,7 +265,7 @@ 39 00 00 00 00 00 02 B0 03 39 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 02 B7 11 39 00 00 00 00 00 03 F0 A5 A5 39 01 00 00 01 00 02 53 E0 39 00 00 00 00 00 03 F0 5A 5A diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi index 582642725c12..fc1deae7f851 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi @@ -230,7 +230,7 @@ 39 00 00 00 00 00 02 B0 03 39 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 02 B7 11 39 00 00 00 00 00 03 F0 A5 A5 39 01 00 00 01 00 02 53 E0 39 00 00 00 00 00 03 F0 5A 5A diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi index 4f66145f9f4c..1c0e690d7696 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi @@ -230,7 +230,7 @@ 39 00 00 00 00 00 02 B0 03 39 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 + 39 00 00 00 00 00 02 B7 11 39 00 00 00 00 00 03 F0 A5 A5 39 01 00 00 01 00 02 53 E0 39 00 00 00 00 00 03 F0 5A 5A From ec6072e824ee7e6da94b2eceeb93a7d67bcb6d07 Mon Sep 17 00:00:00 2001 From: Demon000 Date: Mon, 25 May 2020 13:11:09 +0200 Subject: [PATCH 031/226] arch: arm64: boot: dts: qcom: ea8076: define fod dim lut Change-Id: I760efba8aedc2bd52a77ca6b2c076cfdf23e11b2 Signed-off-by: firebird11 --- .../dsi-panel-samsung-fhd-ea8076-cmd.dtsi | 25 +++++++++++++++++++ .../dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi | 24 ++++++++++++++++++ ...dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi | 24 ++++++++++++++++++ ...i-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi | 24 ++++++++++++++++++ ...dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi | 24 ++++++++++++++++++ .../dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi | 24 ++++++++++++++++++ .../display/dsi-panel-ss-fhd-ea8076-cmd.dtsi | 24 ++++++++++++++++++ .../dsi-panel-ss-fhd-ea8076-global-cmd.dtsi | 24 ++++++++++++++++++ 8 files changed, 193 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-cmd.dtsi index db08ebcd43f0..6978a2fdcc1f 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-cmd.dtsi @@ -61,6 +61,31 @@ qcom,dispparam-enabled; qcom,mdss-panel-on-dimming-delay = <120>; qcom,disp-doze-backlight-threshold = <8>; + qcom,disp-fod-dim-lut = < + /* brightness, alpha */ + 0 0xFF + 4 0xEB + 8 0xEA + 12 0xE9 + 13 0xE8 + 20 0xE5 + 24 0xE3 + 30 0xE0 + 68 0xD0 + 133 0xC0 + 218 0xB0 + 328 0xA0 + 486 0x90 + 642 0x80 + 832 0x70 + 1043 0x60 + 1267 0x50 + 1500 0x40 + 1770 0x30 + 2000 0x24 + 2047 0x21 + >; + /* IRQF_ONESHOT | IRQF_TRIGGER_FALLING */ qcom,esd-err-irq-gpio = <&tlmm 27 0x2002>; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi index b0b7d5341540..e587d934028b 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi @@ -65,6 +65,30 @@ qcom,disp-doze-backlight-threshold = <8>; qcom,disp-fod-off-dimming-delay = <85>; + qcom,disp-fod-dim-lut = < + /* brightness, alpha */ + 0 0xFF + 4 0xEB + 8 0xEA + 12 0xE9 + 13 0xE8 + 20 0xE5 + 24 0xE3 + 30 0xE0 + 68 0xD0 + 133 0xC0 + 218 0xB0 + 328 0xA0 + 486 0x90 + 642 0x80 + 832 0x70 + 1043 0x60 + 1267 0x50 + 1500 0x40 + 1770 0x30 + 2000 0x24 + 2047 0x21 + >; qcom,elvss_dimming_check_enable; qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi index 75bf0dd6e661..db0ab4a29c63 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi @@ -65,6 +65,30 @@ qcom,disp-doze-backlight-threshold = <8>; qcom,disp-fod-off-dimming-delay = <85>; + qcom,disp-fod-dim-lut = < + /* brightness, alpha */ + 0 0xFF + 4 0xEB + 8 0xEA + 12 0xE9 + 13 0xE8 + 20 0xE5 + 24 0xE3 + 30 0xE0 + 68 0xD0 + 133 0xC0 + 218 0xB0 + 328 0xA0 + 486 0x90 + 642 0x80 + 832 0x70 + 1043 0x60 + 1267 0x50 + 1500 0x40 + 1770 0x30 + 2000 0x24 + 2047 0x21 + >; qcom,elvss_dimming_check_enable; qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi index 9110a4e77e8c..c2cc615f2764 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi @@ -65,6 +65,30 @@ qcom,disp-doze-backlight-threshold = <8>; qcom,disp-fod-off-dimming-delay = <85>; + qcom,disp-fod-dim-lut = < + /* brightness, alpha */ + 0 0xFF + 4 0xEB + 8 0xEA + 12 0xE9 + 13 0xE8 + 20 0xE5 + 24 0xE3 + 30 0xE0 + 68 0xD0 + 133 0xC0 + 218 0xB0 + 328 0xA0 + 486 0x90 + 642 0x80 + 832 0x70 + 1043 0x60 + 1267 0x50 + 1500 0x40 + 1770 0x30 + 2000 0x24 + 2047 0x21 + >; qcom,elvss_dimming_check_enable; qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi index 47082c5b33ab..715f89abad99 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi @@ -65,6 +65,30 @@ qcom,disp-doze-backlight-threshold = <8>; qcom,disp-fod-off-dimming-delay = <85>; + qcom,disp-fod-dim-lut = < + /* brightness, alpha */ + 0 0xFF + 4 0xEB + 8 0xEA + 12 0xE9 + 13 0xE8 + 20 0xE5 + 24 0xE3 + 30 0xE0 + 68 0xD0 + 133 0xC0 + 218 0xB0 + 328 0xA0 + 486 0x90 + 642 0x80 + 832 0x70 + 1043 0x60 + 1267 0x50 + 1500 0x40 + 1770 0x30 + 2000 0x24 + 2047 0x21 + >; qcom,elvss_dimming_check_enable; qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi index 1ece198956d7..2bcc28432799 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi @@ -65,6 +65,30 @@ qcom,esd-err-irq-gpio = <&tlmm 5 0x2002>; qcom,disp-doze-backlight-threshold = <8>; + qcom,disp-fod-dim-lut = < + /* brightness, alpha */ + 0 0xFF + 4 0xEB + 8 0xEA + 12 0xE9 + 13 0xE8 + 20 0xE5 + 24 0xE3 + 30 0xE0 + 68 0xD0 + 133 0xC0 + 218 0xB0 + 328 0xA0 + 486 0x90 + 642 0x80 + 832 0x70 + 1043 0x60 + 1267 0x50 + 1500 0x40 + 1770 0x30 + 2000 0x24 + 2047 0x21 + >; qcom,elvss_dimming_check_enable; qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi index fc1deae7f851..cd4a9eacc79f 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi @@ -66,6 +66,30 @@ qcom,disp-doze-backlight-threshold = <8>; qcom,disp-fod-off-dimming-delay = <85>; + qcom,disp-fod-dim-lut = < + /* brightness, alpha */ + 0 0xFF + 4 0xEB + 8 0xEA + 12 0xE9 + 13 0xE8 + 20 0xE5 + 24 0xE3 + 30 0xE0 + 68 0xD0 + 133 0xC0 + 218 0xB0 + 328 0xA0 + 486 0x90 + 642 0x80 + 832 0x70 + 1043 0x60 + 1267 0x50 + 1500 0x40 + 1770 0x30 + 2000 0x24 + 2047 0x21 + >; qcom,elvss_dimming_check_enable; qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi index 1c0e690d7696..d937de2f65d2 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi @@ -66,6 +66,30 @@ qcom,disp-doze-backlight-threshold = <8>; qcom,disp-fod-off-dimming-delay = <85>; + qcom,disp-fod-dim-lut = < + /* brightness, alpha */ + 0 0xFF + 4 0xEB + 8 0xEA + 12 0xE9 + 13 0xE8 + 20 0xE5 + 24 0xE3 + 30 0xE0 + 68 0xD0 + 133 0xC0 + 218 0xB0 + 328 0xA0 + 486 0x90 + 642 0x80 + 832 0x70 + 1043 0x60 + 1267 0x50 + 1500 0x40 + 1770 0x30 + 2000 0x24 + 2047 0x21 + >; qcom,elvss_dimming_check_enable; qcom,mdss-dsi-panel-elvss-dimming-read-length = <1>; From 62cb49dd30b4de3ab5bbf7a7422b148061634c06 Mon Sep 17 00:00:00 2001 From: Demon000 Date: Tue, 26 May 2020 13:01:43 +0200 Subject: [PATCH 032/226] arch: arm64: boot: dts: qcom: ea8076: optimize HBM commands for in-kernel dimming * remove commands not necessary * use short writes where possible * add waits to compensate for the time it takes for the display to react Change-Id: I85aced1022a544c5386f87fcf97fcb97aac1c129 Signed-off-by: firebird11 --- .../dsi-panel-samsung-fhd-ea8076-cmd.dtsi | 22 ++++++------------- .../dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi | 20 ++++------------- ...dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi | 20 ++++------------- ...i-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi | 20 ++++------------- ...dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi | 20 ++++------------- .../dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi | 20 ++++------------- .../display/dsi-panel-ss-fhd-ea8076-cmd.dtsi | 20 ++++------------- .../dsi-panel-ss-fhd-ea8076-global-cmd.dtsi | 20 ++++------------- 8 files changed, 35 insertions(+), 127 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-cmd.dtsi index 6978a2fdcc1f..2ac5ce46c238 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-cmd.dtsi @@ -199,22 +199,14 @@ qcom,mdss-dsi-dispparam-hbm-on-command = [39 01 00 00 00 00 02 53 E8]; qcom,mdss-dsi-dispparam-hbm-on-command-state = "dsi_lp_mode"; qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 01 00 00 01 00 03 F0 A5 A5]; - qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_lp_mode"; + 15 01 00 00 10 00 02 53 20]; + qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 01 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; + 39 00 00 00 00 00 03 F0 5A 5A + 15 00 00 00 00 00 02 B0 03 + 15 00 00 00 00 00 02 B7 C9 + 39 00 00 00 00 00 03 F0 A5 A5 + 15 01 00 00 10 00 02 53 E0]; qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_lp_mode"; qcom,mdss-dsi-dispparam-hbm-fod2norm-command = [39 00 00 00 00 00 03 F0 5A 5A 39 00 00 00 00 00 03 B2 00 40 diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi index e587d934028b..894fb94ffdf7 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1-cmd.dtsi @@ -252,26 +252,14 @@ qcom,mdss-dsi-h-sync-pulse = <0>; qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 20]; qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 11 + 15 00 00 00 00 00 02 B0 03 + 15 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 E0]; qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi index db0ab4a29c63..297b26708ef9 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1mp-cmd.dtsi @@ -252,26 +252,14 @@ qcom,mdss-dsi-h-sync-pulse = <0>; qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 20]; qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 11 + 15 00 00 00 00 00 02 B0 03 + 15 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 E0]; qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi index c2cc615f2764..b9a0a4d5877b 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-2-cmd.dtsi @@ -252,26 +252,14 @@ qcom,mdss-dsi-h-sync-pulse = <0>; qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 20]; qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 11 + 15 00 00 00 00 00 02 B0 03 + 15 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 E0]; qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi index 715f89abad99..e607bdc1e905 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1p2-cmd.dtsi @@ -252,26 +252,14 @@ qcom,mdss-dsi-h-sync-pulse = <0>; qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 20]; qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 11 + 15 00 00 00 00 00 02 B0 03 + 15 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 E0]; qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi index 2bcc28432799..64f128a19cd0 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-samsung-fhd-ea8076-f1s-cmd.dtsi @@ -275,26 +275,14 @@ qcom,mdss-dsi-h-sync-pulse = <0>; qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 11 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 20]; qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 11 + 15 00 00 00 00 00 02 B0 03 + 15 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 E0]; qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi index cd4a9eacc79f..2530a8ddf8af 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-cmd.dtsi @@ -240,26 +240,14 @@ qcom,mdss-dsi-h-sync-pulse = <0>; qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 20]; qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 11 + 15 00 00 00 00 00 02 B0 03 + 15 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 E0]; qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi index d937de2f65d2..67830a12f0c4 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-ss-fhd-ea8076-global-cmd.dtsi @@ -240,26 +240,14 @@ qcom,mdss-dsi-h-sync-pulse = <0>; qcom,mdss-dsi-dispparam-hbm-fod-off-command = [ - 39 01 00 00 00 00 02 53 20 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 4B - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 49 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 91 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 20]; qcom,mdss-dsi-dispparam-hbm-fod-off-command-state = "dsi_hs_mode"; qcom,mdss-dsi-dispparam-hbm-fod-on-command = [ 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 02 B0 03 - 39 00 00 00 00 00 02 B7 C9 - 39 00 00 00 00 00 02 B0 07 - 39 00 00 00 00 00 02 B7 11 + 15 00 00 00 00 00 02 B0 03 + 15 00 00 00 00 00 02 B7 C9 39 00 00 00 00 00 03 F0 A5 A5 - 39 01 00 00 01 00 02 53 E0 - 39 00 00 00 00 00 03 F0 5A 5A - 39 00 00 00 00 00 03 B7 01 43 - 39 01 00 00 01 00 03 F0 A5 A5]; + 15 01 00 00 10 00 02 53 E0]; qcom,mdss-dsi-dispparam-hbm-fod-on-command-state = "dsi_hs_mode"; }; }; From 51e78f94bf95ec8ac0fbe102a2947d1a8ae0588d Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Tue, 16 Apr 2024 01:45:41 +0200 Subject: [PATCH 033/226] drivers: gpu: drm: msm: Add R_EARLY_EVENT_BLANK notification Change-Id: I229a619f169dec96834ba3412e853f8bdc03b7fa Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_drm.c | 8 ++++++++ include/linux/msm_drm_notify.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c index 6a1f452dcb0a..967c48af01df 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c @@ -276,11 +276,19 @@ static void dsi_bridge_disable(struct drm_bridge *bridge) struct dsi_display *display; struct dsi_bridge *c_bridge = to_dsi_bridge(bridge); int private_flags; + struct msm_drm_notifier notify_data; + int power_mode; if (!bridge) { pr_err("Invalid params\n"); return; } + + power_mode = sde_connector_get_lp(c_bridge->display->drm_conn); + notify_data.data = &power_mode; + notify_data.id = MSM_DRM_PRIMARY_DISPLAY; + msm_drm_notifier_call_chain(MSM_DRM_R_EARLY_EVENT_BLANK, ¬ify_data); + display = c_bridge->display; private_flags = diff --git a/include/linux/msm_drm_notify.h b/include/linux/msm_drm_notify.h index 4f9b32662ad5..ab04119ed504 100644 --- a/include/linux/msm_drm_notify.h +++ b/include/linux/msm_drm_notify.h @@ -19,6 +19,8 @@ #define MSM_DRM_EVENT_BLANK 0x01 /* A hardware display blank early change occurred */ #define MSM_DRM_EARLY_EVENT_BLANK 0x02 +/* A hardware display blank early change occurred */ +#define MSM_DRM_R_EARLY_EVENT_BLANK 0x03 enum { /* panel: power on */ From 7510ad3aee7494a4a3f0c68ecdc125ce542b318a Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 24 Apr 2024 19:09:51 +0200 Subject: [PATCH 034/226] drivers: gpu: drm: msm: Add cphy_strength support Change-Id: Ifaf8d2b874f2a7e8399f2b450a1003049e32f5eb Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_defs.h | 1 + drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 2 ++ drivers/gpu/drm/msm/dsi-staging/dsi_phy.c | 1 + drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw.h | 1 + drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c | 8 ++++++++ 5 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h index c1817b9612f8..a5b502ef3cf5 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h @@ -509,6 +509,7 @@ struct dsi_host_common_cfg { bool force_hs_clk_lane; enum dsi_phy_type phy_type; struct dsi_split_link_config split_link; + bool cphy_strength; }; /** diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 896be2ff23b0..5f8f0db6a0d0 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -1278,6 +1278,8 @@ static int dsi_panel_parse_misc_host_config(struct dsi_host_common_cfg *host, "qcom,panel-cphy-mode"); host->phy_type = panel_cphy_mode ? DSI_PHY_TYPE_CPHY : DSI_PHY_TYPE_DPHY; + host->cphy_strength = utils->read_bool(utils->data, + "qcom,mdss-dsi-cphy-strength"); return 0; } diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c index 7444b27c9805..c49c327d61df 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c @@ -925,6 +925,7 @@ int dsi_phy_enable(struct msm_dsi_phy *phy, phy->dst_format = config->common_config.dst_format; phy->cfg.pll_source = pll_source; phy->cfg.bit_clk_rate_hz = config->bit_clk_rate_hz; + phy->cfg.cphy_strength = config->common_config.cphy_strength; /** * If PHY timing parameters are not present in panel dtsi file, diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw.h b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw.h index e1353631361e..ef9876e780ba 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw.h @@ -111,6 +111,7 @@ struct dsi_phy_cfg { bool force_clk_lane_hs; enum dsi_phy_type phy_type; unsigned long bit_clk_rate_hz; + bool cphy_strength; }; struct dsi_phy_hw; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c index f9abd95ce73a..e5339f9c1d0a 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c @@ -188,6 +188,14 @@ static void dsi_phy_hw_cphy_enable(struct dsi_phy_hw *phy, DSI_W32(phy, DSIPHY_CMN_GLBL_RESCODE_OFFSET_BOT_CTRL, 0x3c); DSI_W32(phy, DSIPHY_CMN_GLBL_LPTX_STR_CTRL, 0x55); + if (cfg->cphy_strength) { + DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_0, 0x50); + DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_1, 0x54); + DSI_W32(phy, DSIPHY_CMN_GLBL_RESCODE_OFFSET_TOP_CTRL, 0x1F); + DSI_W32(phy, DSIPHY_CMN_GLBL_RESCODE_OFFSET_BOT_CTRL, 0x1F); + DSI_W32(phy, DSIPHY_CMN_GLBL_RESCODE_OFFSET_MID_CTRL, 0x1F); + } + /* Remove power down from all blocks */ DSI_W32(phy, DSIPHY_CMN_CTRL_0, 0x7f); From 7cbea5efc8838c88074f08f22fa05b85995e334b Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 24 Apr 2024 21:30:29 +0200 Subject: [PATCH 035/226] drivers: gpu: drm: msm: Add CPHY ESD check command support Change-Id: I48691ad19b5376d3fbcf8cb64e2d05bcd3fb9606 Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_defs.h | 1 + drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 50 +++++++++++++++++++++ drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 5 +++ 3 files changed, 56 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h index a5b502ef3cf5..7e2369ef3776 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h @@ -310,6 +310,7 @@ enum dsi_cmd_set_type { DSI_CMD_SET_QSYNC_OFF, DSI_CMD_SET_DISP_HBM_FOD_ON, DSI_CMD_SET_DISP_HBM_FOD_OFF, + DSI_CMD_SET_ESD_CHECK, DSI_CMD_SET_MAX }; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 5f8f0db6a0d0..26bca47e7978 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -23,6 +23,7 @@ #include "dsi_panel.h" #include "dsi_ctrl_hw.h" #include "dsi_parser.h" +#include "dsi_display.h" /** * topology is currently defined by a set of following 3 values: @@ -741,10 +742,30 @@ int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status) return rc; } +int dsi_panel_set_esd_check(struct dsi_panel *panel) { + int rc = 0; + + if (!panel->cphy_esd_check) + return 0; + + if (!panel->panel_initialized) { + pr_debug("[%s] panel not initialized\n", panel->name); + return 0; + } + + rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_ESD_CHECK); + if (rc) + pr_err("[%s] failed to send DSI_CMD_SET_ESD_CHECK cmd, rc=%d\n", + panel->name, rc); + + return rc; +} + int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl) { int rc = 0; struct dsi_backlight_config *bl = &panel->bl_config; + u32 last_backlight = dsi_panel_get_backlight(panel); if (panel->host_config.ext_bridge_num) return 0; @@ -767,6 +788,10 @@ int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl) rc = -ENOTSUPP; } + if (last_backlight == 0 && panel->cphy_esd_check) { + schedule_delayed_work(&panel->esd_work, msecs_to_jiffies(300)); + } + return rc; } @@ -1813,6 +1838,7 @@ const char *cmd_set_prop_map[DSI_CMD_SET_MAX] = { "qcom,mdss-dsi-qsync-off-commands", "qcom,mdss-dsi-dispparam-hbm-fod-on-command", "qcom,mdss-dsi-dispparam-hbm-fod-off-command", + "qcom,mdss-dsi-esd-check-read-command", }; const char *cmd_set_state_map[DSI_CMD_SET_MAX] = { @@ -1841,6 +1867,7 @@ const char *cmd_set_state_map[DSI_CMD_SET_MAX] = { "qcom,mdss-dsi-qsync-off-commands-state", "qcom,mdss-dsi-dispparam-hbm-fod-on-command-state", "qcom,mdss-dsi-dispparam-hbm-fod-off-command-state", + "qcom,mdss-dsi-esd-check-read-command-state", }; static int dsi_panel_get_cmd_pkt_count(const char *data, u32 length, u32 *cnt) @@ -2137,6 +2164,10 @@ static int dsi_panel_parse_misc_features(struct dsi_panel *panel) panel->lp11_init = utils->read_bool(utils->data, "qcom,mdss-dsi-lp11-init"); + + panel->cphy_esd_check = utils->read_bool(utils->data, + "qcom,cphy-esd-check"); + return 0; } @@ -3406,6 +3437,23 @@ static void dsi_panel_update_util(struct dsi_panel *panel, utils->node = panel->panel_of_node; } +static void dsi_panel_esd_enable_delayed_work(struct work_struct *work) +{ + struct dsi_panel *panel = container_of(work, + struct dsi_panel, esd_work.work); + struct dsi_display *display = NULL; + struct mipi_dsi_host *host = panel->host; + + if (host) + display = container_of(host, struct dsi_display, host); + + if (display) { + mutex_lock(&panel->panel_lock); + dsi_panel_set_esd_check(panel); + mutex_unlock(&panel->panel_lock); + } +} + struct dsi_panel *dsi_panel_get(struct device *parent, struct device_node *of_node, struct device_node *parser_node, @@ -3516,6 +3564,8 @@ struct dsi_panel *dsi_panel_get(struct device *parent, if (rc) pr_debug("failed to parse esd config, rc=%d\n", rc); + INIT_DELAYED_WORK(&panel->esd_work, dsi_panel_esd_enable_delayed_work); + panel->power_mode = SDE_MODE_DPMS_OFF; drm_panel_init(&panel->drm_panel); mutex_init(&panel->panel_lock); diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index d36d69006282..8f852bc31315 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -228,6 +228,9 @@ struct dsi_panel { struct brightness_alpha_pair *fod_dim_lut; u32 fod_dim_lut_count; + + bool cphy_esd_check; + struct delayed_work esd_work; }; static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel) @@ -352,4 +355,6 @@ int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status); u32 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel); +int dsi_panel_set_esd_check(struct dsi_panel *panel); + #endif /* _DSI_PANEL_H_ */ From 025fd03371cd83e19dfd9bcbbab6885d3ffb1551 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 24 Apr 2024 21:31:46 +0200 Subject: [PATCH 036/226] arch: arm64: boot: dts: qcom: xiaomi: Rename CPHY ESD check commands Change-Id: I3f48d2693fa51d91364f26d151301a4ebde504a3 Signed-off-by: firebird11 --- .../common/display/dsi-panel-k82-36-02-0b-video.dtsi | 6 +++--- .../common/display/dsi-panel-k82-42-02-0a-video.dtsi | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-36-02-0b-video.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-36-02-0b-video.dtsi index 536baccd575a..b289133bdbe0 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-36-02-0b-video.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-36-02-0b-video.dtsi @@ -48,7 +48,7 @@ qcom,cmd-sync-wait-broadcast; qcom,panel-cphy-mode; qcom,mdss-dsi-cphy-strength; - mi,cphy-esd-check; + qcom,cphy-esd-check; mi,is-tddi-flag; qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = @@ -339,14 +339,14 @@ qcom,mdss-dsi-dispparam-cabcoff-command-state = "dsi_lp_mode"; qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; qcom,mdss-dsi-dispparam-dimmingoff-command-state = "dsi_lp_mode"; - mi,mdss-dsi-esd-check-read-command = [ + qcom,mdss-dsi-esd-check-read-command = [ /* esd detect */ 15 01 00 00 00 00 02 FF 27 15 01 00 00 00 00 02 D1 28 15 01 00 00 00 00 02 FF 10 15 01 00 00 00 00 02 53 2C ]; - mi,mdss-dsi-esd-check-read-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-esd-check-read-command-state = "dsi_lp_mode"; qcom,mdss-dsi-dispparam-xy-coordinate-command = [ 15 01 00 00 00 00 02 FF 10 diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-42-02-0a-video.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-42-02-0a-video.dtsi index 22c3e689801b..4b86cc134fec 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-42-02-0a-video.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-42-02-0a-video.dtsi @@ -48,7 +48,7 @@ qcom,cmd-sync-wait-broadcast; qcom,panel-cphy-mode; qcom,mdss-dsi-cphy-strength; - mi,cphy-esd-check; + qcom,cphy-esd-check; mi,is-tddi-flag; qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = @@ -354,14 +354,14 @@ qcom,mdss-dsi-dispparam-cabcoff-command-state = "dsi_lp_mode"; qcom,mdss-dsi-dispparam-dimmingon-command-state = "dsi_lp_mode"; qcom,mdss-dsi-dispparam-dimmingoff-command-state = "dsi_lp_mode"; - mi,mdss-dsi-esd-check-read-command = [ + qcom,mdss-dsi-esd-check-read-command = [ /* esd detect */ 15 01 00 00 00 00 02 FF 27 15 01 00 00 00 00 02 D1 28 15 01 00 00 00 00 02 FF 10 15 01 00 00 00 00 02 53 2C ]; - mi,mdss-dsi-esd-check-read-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-esd-check-read-command-state = "dsi_lp_mode"; qcom,mdss-dsi-dispparam-xy-coordinate-command = [ 15 01 00 00 00 00 02 FF 10 From e4a4ce2d1762ebbca830ca027696528c347040b1 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 24 Apr 2024 23:51:19 +0200 Subject: [PATCH 037/226] drivers: gpu: drm: msm: Implement pen FPS sync Change-Id: I8ae2f6a201bb00343c6f28a7b0dca493fdc560c8 Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_defs.h | 3 + drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 61 +++++++++++++++++++ drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 5 ++ drivers/gpu/drm/msm/sde/sde_encoder.c | 65 +++++++++++++++++++++ drivers/gpu/drm/msm/sde/sde_encoder.h | 7 +++ 5 files changed, 141 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h index 7e2369ef3776..d93655f8562a 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h @@ -311,6 +311,9 @@ enum dsi_cmd_set_type { DSI_CMD_SET_DISP_HBM_FOD_ON, DSI_CMD_SET_DISP_HBM_FOD_OFF, DSI_CMD_SET_ESD_CHECK, + DSI_CMD_SET_SYNC_PEN_30HZ, + DSI_CMD_SET_SYNC_PEN_60HZ, + DSI_CMD_SET_SYNC_PEN_120HZ, DSI_CMD_SET_MAX }; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 26bca47e7978..cd69ff775c3e 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -761,6 +761,50 @@ int dsi_panel_set_esd_check(struct dsi_panel *panel) { return rc; } +int dsi_panel_sync_pen_fps(struct dsi_panel *panel, + struct dsi_display_mode *adj_mode) +{ + int rc = 0; + u32 refresh_rate; + enum dsi_cmd_set_type sync_pen_cmd_type; + + if (!panel || !adj_mode) { + pr_err("invalid params\n"); + return -EINVAL; + } + + if (!panel->sync_pen_fps) { + pr_warn_once("[%s] sync pen fps called when disabled\n", panel->name); + return 0; + } + + refresh_rate = adj_mode->timing.refresh_rate; + + switch (refresh_rate) { + case 30: + sync_pen_cmd_type = DSI_CMD_SET_SYNC_PEN_30HZ; + break; + case 60: + sync_pen_cmd_type = DSI_CMD_SET_SYNC_PEN_60HZ; + break; + case 120: + sync_pen_cmd_type = DSI_CMD_SET_SYNC_PEN_120HZ; + break; + default: + pr_err("[%s] unsupported refresh rate %d\n", + panel->name, refresh_rate); + return -EINVAL; + break; + } + + rc = dsi_panel_tx_cmd_set(panel, sync_pen_cmd_type); + if (rc) + pr_err("[%s] failed to send DSI_CMD_SET_SYNC_PEN_%dHZ cmd, rc=%d\n", + panel->name, refresh_rate, rc); + + return rc; +} + int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl) { int rc = 0; @@ -1839,6 +1883,9 @@ const char *cmd_set_prop_map[DSI_CMD_SET_MAX] = { "qcom,mdss-dsi-dispparam-hbm-fod-on-command", "qcom,mdss-dsi-dispparam-hbm-fod-off-command", "qcom,mdss-dsi-esd-check-read-command", + "qcom,mdss-dsi-sync-pen-30hz-command", + "qcom,mdss-dsi-sync-pen-60hz-command", + "qcom,mdss-dsi-sync-pen-120hz-command", }; const char *cmd_set_state_map[DSI_CMD_SET_MAX] = { @@ -1868,6 +1915,9 @@ const char *cmd_set_state_map[DSI_CMD_SET_MAX] = { "qcom,mdss-dsi-dispparam-hbm-fod-on-command-state", "qcom,mdss-dsi-dispparam-hbm-fod-off-command-state", "qcom,mdss-dsi-esd-check-read-command-state", + "qcom,mdss-dsi-sync-pen-30hz-command-state", + "qcom,mdss-dsi-sync-pen-60hz-command-state", + "qcom,mdss-dsi-sync-pen-120hz-command-state", }; static int dsi_panel_get_cmd_pkt_count(const char *data, u32 length, u32 *cnt) @@ -2168,6 +2218,9 @@ static int dsi_panel_parse_misc_features(struct dsi_panel *panel) panel->cphy_esd_check = utils->read_bool(utils->data, "qcom,cphy-esd-check"); + panel->sync_pen_fps = utils->read_bool(utils->data, + "qcom,sync-pen-fps"); + return 0; } @@ -4486,6 +4539,14 @@ int dsi_panel_post_enable(struct dsi_panel *panel) goto error; } error: + if (panel->sync_pen_fps) { + rc = dsi_panel_sync_pen_fps(panel, panel->cur_mode); + if (rc) { + pr_err("[%s] failed to update TP fps code setting, rc=%d\n", + panel->name, rc); + } + } + mutex_unlock(&panel->panel_lock); return rc; } diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index 8f852bc31315..aa64c4e753b7 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -231,6 +231,8 @@ struct dsi_panel { bool cphy_esd_check; struct delayed_work esd_work; + + bool sync_pen_fps; }; static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel) @@ -357,4 +359,7 @@ u32 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel); int dsi_panel_set_esd_check(struct dsi_panel *panel); +int dsi_panel_sync_pen_fps(struct dsi_panel *panel, + struct dsi_display_mode *adj_mode); + #endif /* _DSI_PANEL_H_ */ diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c index 0b8daa3b9f01..32fe1f7039b8 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder.c @@ -39,6 +39,7 @@ #include "sde_core_irq.h" #include "sde_hw_top.h" #include "sde_hw_qdss.h" +#include "dsi_drm.h" #define SDE_DEBUG_ENC(e, fmt, ...) SDE_DEBUG("enc%d " fmt,\ (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) @@ -4811,6 +4812,9 @@ void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error) struct sde_encoder_phys *phys; ktime_t wakeup_time; unsigned int i; + struct dsi_bridge *bridge = NULL; + struct dsi_display *dsi_display = NULL; + struct dsi_display_mode adj_mode; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); @@ -4825,6 +4829,22 @@ void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error) if (is_error) _sde_encoder_reset_ctl_hw(drm_enc); + if (sde_enc->disp_info.intf_type == DRM_MODE_CONNECTOR_DSI + && drm_enc->bridge) + bridge = container_of(drm_enc->bridge, struct dsi_bridge, base); + + if (bridge) { + adj_mode = bridge->dsi_mode; + dsi_display = bridge->display; + + if (dsi_display && dsi_display->panel + && dsi_display->panel->sync_pen_fps + && adj_mode.dsi_mode_flags & DSI_MODE_FLAG_VRR) { + mutex_lock(&dsi_display->panel->panel_lock); + sde_encoder_vid_wait_for_active(drm_enc); + } + } + /* All phys encs are ready to go, trigger the kickoff */ _sde_encoder_kickoff_phys(sde_enc); @@ -4842,6 +4862,13 @@ void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error) nsecs_to_jiffies(ktime_to_ns(wakeup_time))); } + if (dsi_display && dsi_display->panel + && dsi_display->panel->sync_pen_fps + && adj_mode.dsi_mode_flags & DSI_MODE_FLAG_VRR) { + dsi_panel_sync_pen_fps(dsi_display->panel, &adj_mode); + mutex_unlock(&dsi_display->panel->panel_lock); + } + SDE_ATRACE_END("encoder_kickoff"); } @@ -5560,6 +5587,44 @@ struct drm_encoder *sde_encoder_init( return sde_encoder_init_with_ops(dev, disp_info, NULL); } +int sde_encoder_vid_wait_for_active( + struct drm_encoder *drm_enc) +{ + struct drm_display_mode mode; + struct sde_encoder_virt *sde_enc = NULL; + u32 ln_cnt, min_ln_cnt, active_mark_region; + u32 i, retry = 15; + + if (!drm_enc) { + SDE_ERROR("invalid encoder\n"); + return -EINVAL; + } + + sde_enc = to_sde_encoder_virt(drm_enc); + + for (i = 0; i < sde_enc->num_phys_encs; i++) { + struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; + + if (!phys || (phys->ops.is_master && !phys->ops.is_master(phys))) + continue; + + mode = phys->cached_mode; + min_ln_cnt = (mode.vtotal - mode.vsync_start) + + (mode.vsync_end - mode.vsync_start); + active_mark_region = mode.vdisplay + min_ln_cnt - mode.vdisplay / 4; + + while (retry) { + ln_cnt = phys->ops.get_line_count(phys); + if ((ln_cnt > min_ln_cnt) && (ln_cnt < active_mark_region)) + return 0; + + udelay(2000); + retry--; + } + } + return -EINVAL; +} + int sde_encoder_wait_for_event(struct drm_encoder *drm_enc, enum msm_event_wait event) { diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.h b/drivers/gpu/drm/msm/sde/sde_encoder.h index eb0415ed5553..5e6c24ca49f0 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.h +++ b/drivers/gpu/drm/msm/sde/sde_encoder.h @@ -355,4 +355,11 @@ int sde_encoder_get_ctlstart_timeout_state(struct drm_encoder *enc); */ void sde_encoder_trigger_early_wakeup(struct drm_encoder *drm_enc); +/** + * sde_encoder_vid_wait_for_active - wait Vactive region for some mark region + * @drm_enc: Pointer to drm encoder structure + * @Return: non zero value if wait timeout occurred + */ +int sde_encoder_vid_wait_for_active(struct drm_encoder *enc); + #endif /* __SDE_ENCODER_H__ */ From b6b94465874c10c1eec8c849f8cf25d113322a5f Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Thu, 25 Apr 2024 00:21:12 +0200 Subject: [PATCH 038/226] arch: arm64: boot: dts: qcom: xiaomi: Adapt pen FPS values Change-Id: I4fe06e4fad2c09685acd89c97a5dda99df558def Signed-off-by: firebird11 --- .../common/display/dsi-panel-k82-36-02-0b-video.dtsi | 9 +++++---- .../common/display/dsi-panel-k82-42-02-0a-video.dtsi | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-36-02-0b-video.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-36-02-0b-video.dtsi index b289133bdbe0..90b7af7b72e0 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-36-02-0b-video.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-36-02-0b-video.dtsi @@ -49,6 +49,7 @@ qcom,panel-cphy-mode; qcom,mdss-dsi-cphy-strength; qcom,cphy-esd-check; + qcom,sync-pen-fps; mi,is-tddi-flag; qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = @@ -264,16 +265,16 @@ qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; qcom,mdss-dsi-displayoff-command-state = "dsi_hs_mode"; qcom,mdss-dsi-displayon-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-pen-120hz-command = [ + qcom,mdss-dsi-sync-pen-120hz-command = [ 15 00 00 00 00 00 02 FF 2A 15 00 00 00 00 00 02 23 0D 15 01 00 00 00 00 02 FF 10]; - qcom,mdss-dsi-dispparam-pen-60hz-command = [ + qcom,mdss-dsi-sync-pen-60hz-command = [ 15 00 00 00 00 00 02 FF 2A 15 00 00 00 00 00 02 23 0C 15 01 00 00 00 00 02 FF 10]; - qcom,mdss-dsi-dispparam-pen-120hz-command-state = "dsi_lp_mode"; - qcom,mdss-dsi-dispparam-pen-60hz-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-sync-pen-120hz-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-sync-pen-60hz-command-state = "dsi_lp_mode"; /* max brightness 85% */ qcom,mdss-dsi-dispparam-lcd-hbm-l1-on-command = [ diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-42-02-0a-video.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-42-02-0a-video.dtsi index 4b86cc134fec..651b814864cf 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-42-02-0a-video.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/display/dsi-panel-k82-42-02-0a-video.dtsi @@ -49,6 +49,7 @@ qcom,panel-cphy-mode; qcom,mdss-dsi-cphy-strength; qcom,cphy-esd-check; + qcom,sync-pen-fps; mi,is-tddi-flag; qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = @@ -279,16 +280,16 @@ qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; qcom,mdss-dsi-displayoff-command-state = "dsi_hs_mode"; qcom,mdss-dsi-displayon-command-state = "dsi_hs_mode"; - qcom,mdss-dsi-dispparam-pen-120hz-command = [ + qcom,mdss-dsi-sync-pen-120hz-command = [ 15 00 00 00 00 00 02 FF 2A 15 00 00 00 00 00 02 23 0D 15 01 00 00 00 00 02 FF 10]; - qcom,mdss-dsi-dispparam-pen-60hz-command = [ + qcom,mdss-dsi-sync-pen-60hz-command = [ 15 00 00 00 00 00 02 FF 2A 15 00 00 00 00 00 02 23 0C 15 01 00 00 00 00 02 FF 10]; - qcom,mdss-dsi-dispparam-pen-120hz-command-state = "dsi_lp_mode"; - qcom,mdss-dsi-dispparam-pen-60hz-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-sync-pen-120hz-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-sync-pen-60hz-command-state = "dsi_lp_mode"; /* max brightness 85% */ qcom,mdss-dsi-dispparam-lcd-hbm-l1-on-command = [ From 50a1b4b1f9e38a08685515db50940b5d6ead6017 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Thu, 25 Apr 2024 00:20:39 +0200 Subject: [PATCH 039/226] drivers: gpu: drm: msm: Import Xiaomi changes * From nabu-r-oss Change-Id: Ic797d9c0534114a8298a260a66e7f7ecdc211e37 Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_defs.h | 3 + drivers/gpu/drm/msm/dsi-staging/dsi_display.c | 44 +- drivers/gpu/drm/msm/dsi-staging/dsi_display.h | 13 + drivers/gpu/drm/msm/dsi-staging/dsi_drm.c | 8 + drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 410 ++++++++++++++++++ drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 47 ++ .../gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c | 5 + drivers/gpu/drm/msm/sde/sde_connector.c | 83 ++++ 8 files changed, 610 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h index d93655f8562a..016be31d2732 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h @@ -314,6 +314,9 @@ enum dsi_cmd_set_type { DSI_CMD_SET_SYNC_PEN_30HZ, DSI_CMD_SET_SYNC_PEN_60HZ, DSI_CMD_SET_SYNC_PEN_120HZ, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + DSI_CMD_SET_MI_READ_LOCKDOWN_INFO, +#endif DSI_CMD_SET_MAX }; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index d4fc8b2c094c..4db608879026 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -245,7 +245,7 @@ int dsi_display_set_backlight(struct drm_connector *connector, return rc; } -static int dsi_display_cmd_engine_enable(struct dsi_display *display) +int dsi_display_cmd_engine_enable(struct dsi_display *display) { int rc = 0; int i; @@ -289,7 +289,7 @@ static int dsi_display_cmd_engine_enable(struct dsi_display *display) return rc; } -static int dsi_display_cmd_engine_disable(struct dsi_display *display) +int dsi_display_cmd_engine_disable(struct dsi_display *display) { int rc = 0; int i; @@ -475,7 +475,7 @@ static void dsi_display_register_te_irq(struct dsi_display *display) } /* Allocate memory for cmd dma tx buffer */ -static int dsi_host_alloc_cmd_tx_buffer(struct dsi_display *display) +int dsi_host_alloc_cmd_tx_buffer(struct dsi_display *display) { int rc = 0, cnt = 0; struct dsi_display_ctrl *display_ctrl; @@ -5544,6 +5544,9 @@ int dsi_display_dev_probe(struct platform_device *pdev) display->pdev = pdev; display->boot_disp = boot_disp; display->dsi_type = dsi_type; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + display->is_first_boot = true; +#endif dsi_display_parse_cmdline_topology(display, index); @@ -7585,6 +7588,17 @@ int dsi_display_enable(struct dsi_display *display) display->panel->panel_initialized = true; pr_debug("cont splash enabled, display enable not required\n"); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (display->panel->is_tddi_flag) { + rc = dsi_panel_lockdowninfo_param_read(display->panel); + if (!rc) { + pr_err("[%s] failed to read lockdowninfo para, rc=%d\n", + display->name, rc); + } + } +#endif + return 0; } @@ -7865,6 +7879,30 @@ struct dsi_display *get_main_display(void) { return primary_display; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int dsi_display_esd_irq_ctrl(struct dsi_display *display, + bool enable) +{ + int ret = 0; + + if (!display) { + pr_err("Invalid parameters\n"); + return -EINVAL; + } + + mutex_lock(&display->display_lock); + + ret = dsi_panel_esd_irq_ctrl(display->panel, enable); + if (ret) + pr_err("[%s] failed to set esd irq, rc=%d\n", + display->name, ret); + + mutex_unlock(&display->display_lock); + + return ret; +} +#endif + static int __init dsi_display_register(void) { dsi_phy_drv_register(); diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h index 73d8b5ac29dd..0331f097321e 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h @@ -202,6 +202,9 @@ struct dsi_display { struct drm_connector *ext_conn; const char *name; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + bool is_first_boot; +#endif const char *display_type; const char *dsi_type; struct list_head list; @@ -718,4 +721,14 @@ struct dsi_display *get_main_display(void); void dsi_display_set_fod_ui(struct dsi_display *display, bool status); +int dsi_display_cmd_engine_enable(struct dsi_display *display); + +int dsi_display_cmd_engine_disable(struct dsi_display *display); + +int dsi_host_alloc_cmd_tx_buffer(struct dsi_display *display); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int dsi_display_esd_irq_ctrl(struct dsi_display *display, bool enable); +#endif + #endif /* _DSI_DISPLAY_H_ */ diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c index 967c48af01df..a78010ebb908 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c @@ -268,6 +268,10 @@ static void dsi_bridge_enable(struct drm_bridge *bridge) sde_connector_schedule_status_work(display->drm_conn, true); } + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + dsi_display_esd_irq_ctrl(display, true); +#endif } static void dsi_bridge_disable(struct drm_bridge *bridge) @@ -291,6 +295,10 @@ static void dsi_bridge_disable(struct drm_bridge *bridge) display = c_bridge->display; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + dsi_display_esd_irq_ctrl(display, false); +#endif + private_flags = bridge->encoder->crtc->state->adjusted_mode.private_flags; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index cd69ff775c3e..450f1ac0a369 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -25,6 +25,10 @@ #include "dsi_parser.h" #include "dsi_display.h" +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#include "../../../../../kernel/irq/internals.h" +#endif + /** * topology is currently defined by a set of following 3 values: * 1. num of layer mixers @@ -436,7 +440,20 @@ static int dsi_panel_power_on(struct dsi_panel *panel) { int rc = 0; +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) rc = dsi_pwr_enable_regulator(&panel->power_info, true); +#else + if (panel->is_tddi_flag) { + if (!panel->tddi_doubleclick_flag || panel->panel_dead_flag) { + rc = dsi_pwr_enable_regulator(&panel->power_info, true); + if (panel->panel_dead_flag) + panel->panel_dead_flag = false; + } + } else { + rc = dsi_pwr_enable_regulator(&panel->power_info, true); + } +#endif + if (rc) { pr_err("[%s] failed to enable vregs, rc=%d\n", panel->name, rc); goto exit; @@ -483,8 +500,20 @@ static int dsi_panel_power_off(struct dsi_panel *panel) if (gpio_is_valid(panel->reset_config.disp_en_gpio)) gpio_set_value(panel->reset_config.disp_en_gpio, 0); +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) if (gpio_is_valid(panel->reset_config.reset_gpio)) gpio_set_value(panel->reset_config.reset_gpio, 0); +#else + if (panel->is_tddi_flag) { + if (!panel->tddi_doubleclick_flag || panel->panel_dead_flag) { + if (gpio_is_valid(panel->reset_config.reset_gpio)) + gpio_set_value(panel->reset_config.reset_gpio, 0); + } + } else { + if (gpio_is_valid(panel->reset_config.reset_gpio)) + gpio_set_value(panel->reset_config.reset_gpio, 0); + } +#endif if (gpio_is_valid(panel->reset_config.lcd_mode_sel_gpio)) gpio_set_value(panel->reset_config.lcd_mode_sel_gpio, 0); @@ -495,9 +524,23 @@ static int dsi_panel_power_off(struct dsi_panel *panel) rc); } +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) rc = dsi_pwr_enable_regulator(&panel->power_info, false); if (rc) pr_err("[%s] failed to enable vregs, rc=%d\n", panel->name, rc); +#else + if (panel->is_tddi_flag) { + if(!panel->tddi_doubleclick_flag || panel->panel_dead_flag) { + rc = dsi_pwr_enable_regulator(&panel->power_info, false); + if (rc) + pr_err("[%s] failed to enable vregs, rc=%d\n", panel->name, rc); + } + } else { + rc = dsi_pwr_enable_regulator(&panel->power_info, false); + if (rc) + pr_err("[%s] failed to enable vregs, rc=%d\n", panel->name, rc); + } +#endif return rc; } @@ -805,6 +848,315 @@ int dsi_panel_sync_pen_fps(struct dsi_panel *panel, return rc; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int dsi_panel_esd_irq_ctrl(struct dsi_panel *panel, + bool enable) +{ + struct drm_panel_esd_config *esd_config; + struct irq_desc *desc; + + if (!panel || !panel->panel_initialized) { + pr_err("[LCD] panel not ready!\n"); + return -EINVAL; + } + + mutex_lock(&panel->panel_lock); + + esd_config = &panel->esd_config; + if (gpio_is_valid(esd_config->esd_err_irq_gpio)) { + if (esd_config->esd_err_irq) { + if (enable) { + desc = irq_to_desc(esd_config->esd_err_irq); + if (!irq_settings_is_level(desc)) + desc->istate &= ~IRQS_PENDING; + enable_irq(esd_config->esd_err_irq); + pr_info("panel esd irq is enable\n"); + } else { + disable_irq_nosync(esd_config->esd_err_irq); + pr_info("panel esd irq is disable\n"); + } + } + } + + mutex_unlock(&panel->panel_lock); + return 0; +} + +static int dsi_panel_get_lockdown_from_cmdline(unsigned char *plockdowninfo) +{ + int ret = -1; + char lockdown_str[40] = {'\0'}; + char *match = (char *) strnstr(saved_command_line, + "msm_drm.panel_lockdown=", + strlen(saved_command_line)); + + if (match && plockdowninfo) { + memcpy(lockdown_str, (match + strlen("msm_drm.panel_lockdown=")), + sizeof(lockdown_str) - 1); + if (sscanf(lockdown_str, "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x", + &plockdowninfo[0], &plockdowninfo[1], &plockdowninfo[2], &plockdowninfo[3], + &plockdowninfo[4], &plockdowninfo[5], &plockdowninfo[6], &plockdowninfo[7]) + != 8) { + pr_err("failed to parse lockdown info from cmdline !\n"); + } else { + pr_info("lockdown info from cmdline = 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x," + "0x%02x,0x%02x,0x%02x", + plockdowninfo[0], plockdowninfo[1], plockdowninfo[2], plockdowninfo[3], + plockdowninfo[4], plockdowninfo[5], plockdowninfo[6], plockdowninfo[7]); + ret = 0; + } + } + return ret; +} + +ssize_t dsi_panel_lockdown_info_read(unsigned char *plockdowninfo) +{ + int rc = 0; + int i = 0; + static int count = 0; + struct dsi_display *primary_display = get_main_display(); + + if (!dsi_panel_get_lockdown_from_cmdline(plockdowninfo)) + return 1; + if (!primary_display || !primary_display->panel || !plockdowninfo) { + pr_err("invalid params\n"); + return -EINVAL; + } + + while (!primary_display->panel->lockdowninfo_read.lockdowninfo_read_done && count < MAX_READ_LOCKDOWN_COUNT) { + pr_debug("[%s][%s] waitting for panel priv_info initialized!\n", __func__, primary_display->panel->name); + msleep_interruptible(1000); + count++; + } + for(i = 0; i < 8; i++) { + pr_info("0x%x", primary_display->panel->lockdowninfo_read.lockdowninfo[i]); + plockdowninfo[i] = primary_display->panel->lockdowninfo_read.lockdowninfo[i]; + } + rc = plockdowninfo[0]; + return rc; +} +EXPORT_SYMBOL(dsi_panel_lockdown_info_read); + +int dsi_panel_lockdowninfo_param_read(struct dsi_panel *panel) +{ + int rc = 0; + int i = 0; + struct dsi_panel_cmd_set *cmd_sets; + struct dsi_read_config ld_read_config; + struct dsi_panel_cmd_set read_cmd_set = {0}; + if (!panel || !panel->cur_mode || !panel->cur_mode->priv_info) { + pr_err("invalid params\n"); + return -EINVAL; + } + + if (!panel->panel_initialized) { + pr_err("panel not initialized\n"); + return -EINVAL; + } + + cmd_sets = &panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_MI_READ_LOCKDOWN_INFO]; + if (cmd_sets->cmds) { + read_cmd_set.cmds = cmd_sets->cmds; + read_cmd_set.count = 1; + read_cmd_set.state = cmd_sets->state; + rc = dsi_panel_write_cmd_set(panel, &read_cmd_set); + if (rc) { + pr_err("[%s] failed to send cmds, rc=%d\n",panel->name, rc); + rc = -EIO; + } + pr_info("[%s]", panel->name); + if (strcmp(panel->name,"xiaomi 42 02 0a video mode dual dsi cphy panel") && + strcmp(panel->name,"xiaomi 36 02 0b video mode dual dsi cphy panel")) { + ld_read_config.enabled= 1; + ld_read_config.cmds_rlen = 8; + ld_read_config.read_cmd = read_cmd_set; + ld_read_config.read_cmd.cmds = &read_cmd_set.cmds[1]; + rc = dsi_panel_read_cmd_set(panel, &ld_read_config); + if (rc <= 0) { + pr_err("[%s] failed to read cmds, rc=%d\n", panel->name, rc); + rc = -EIO; + } + for(i = 0; i < 8; i++) { + pr_info("0x%x", ld_read_config.rbuf[i]); + panel->lockdowninfo_read.lockdowninfo[i] = ld_read_config.rbuf[i]; + } + + if (!strcmp(panel->name,"xiaomi 37 02 0b video mode dsc dsi panel")) { + panel->lockdowninfo_read.lockdowninfo[7] = 0x01; + pr_info("plockdowninfo[7] = 0x%d \n", + panel->lockdowninfo_read.lockdowninfo[7]); + } + panel->lockdowninfo_read.lockdowninfo_read_done = 1; + } else { + for(i = 0; i < 8; i++) { + ld_read_config.enabled= 1; + ld_read_config.cmds_rlen = 1; + ld_read_config.read_cmd = read_cmd_set; + ld_read_config.read_cmd.cmds = &read_cmd_set.cmds[i+1]; + rc = dsi_panel_read_cmd_set(panel, &ld_read_config); + if (rc <= 0) { + pr_err("[%s] failed to read, rc=%d\n", panel->name, rc); + rc = -EIO; + } + + pr_info("0x%x", ld_read_config.rbuf[0]); + panel->lockdowninfo_read.lockdowninfo[i] = ld_read_config.rbuf[0]; + } + panel->lockdowninfo_read.lockdowninfo_read_done = 1; + } + } + + return rc; + +} + +int dsi_panel_write_cmd_set(struct dsi_panel *panel, + struct dsi_panel_cmd_set *cmd_sets) +{ + int rc = 0, i = 0; + ssize_t len; + struct dsi_cmd_desc *cmds; + u32 count; + enum dsi_cmd_set_state state; + struct dsi_display_mode *mode; + const struct mipi_dsi_host_ops *ops = panel->host->ops; + + if (!panel || !panel->cur_mode) + return -EINVAL; + + mode = panel->cur_mode; + + cmds = cmd_sets->cmds; + count = cmd_sets->count; + state = cmd_sets->state; + + if (count == 0) { + pr_debug("[%s] No commands to be sent for state\n", panel->name); + goto error; + } + + for (i = 0; i < count; i++) { + if (state == DSI_CMD_SET_STATE_LP) + cmds->msg.flags |= MIPI_DSI_MSG_USE_LPM; + + if (cmds->last_command) + cmds->msg.flags |= MIPI_DSI_MSG_LASTCOMMAND; + + len = ops->transfer(panel->host, &cmds->msg); + if (len < 0) { + rc = len; + pr_err("failed to set cmds, rc=%d\n", rc); + goto error; + } + if (cmds->post_wait_ms) + usleep_range(cmds->post_wait_ms*1000, + ((cmds->post_wait_ms*1000)+10)); + cmds++; + } +error: + return rc; +} + +int dsi_panel_read_cmd_set(struct dsi_panel *panel, + struct dsi_read_config *read_config) +{ + struct mipi_dsi_host *host; + struct dsi_display *display; + struct dsi_display_ctrl *ctrl; + struct dsi_cmd_desc *cmds; + enum dsi_cmd_set_state state; + int i, rc = 0, count = 0; + u32 flags = 0; + + if (panel == NULL || read_config == NULL) + return -EINVAL; + + host = panel->host; + if (host) { + display = container_of(host, struct dsi_display, host); + if (display == NULL) + return -EINVAL; + } else + return -EINVAL; + + if (!panel->panel_initialized) { + pr_info("Panel not initialized\n"); + return -EINVAL; + } + + if (!read_config->enabled) { + pr_info("read operation was not permitted\n"); + return -EPERM; + } + + dsi_display_clk_ctrl(display->dsi_clk_handle, + DSI_ALL_CLKS, DSI_CLK_ON); + + ctrl = &display->ctrl[display->cmd_master_idx]; + + rc = dsi_display_cmd_engine_enable(display); + if (rc) { + pr_err("cmd engine enable failed\n"); + rc = -EPERM; + goto exit_ctrl; + } + + if (display->tx_cmd_buf == NULL) { + rc = dsi_host_alloc_cmd_tx_buffer(display); + if (rc) { + pr_err("failed to allocate cmd tx buffer memory\n"); + goto exit; + } + } + + count = read_config->read_cmd.count; + cmds = read_config->read_cmd.cmds; + state = read_config->read_cmd.state; + if (count == 0) { + pr_err("No commands to be sent\n"); + goto exit; + } + if (cmds->last_command) { + cmds->msg.flags |= MIPI_DSI_MSG_LASTCOMMAND; + flags |= DSI_CTRL_CMD_LAST_COMMAND; + } + if (state == DSI_CMD_SET_STATE_LP) + cmds->msg.flags |= MIPI_DSI_MSG_USE_LPM; + flags |= (DSI_CTRL_CMD_FETCH_MEMORY | DSI_CTRL_CMD_READ | + DSI_CTRL_CMD_CUSTOM_DMA_SCHED); + + memset(read_config->rbuf, 0x0, sizeof(read_config->rbuf)); + cmds->msg.rx_buf = read_config->rbuf; + cmds->msg.rx_len = read_config->cmds_rlen; + + rc = dsi_ctrl_cmd_transfer(ctrl->ctrl, &(cmds->msg), flags); + if (rc <= 0) { + pr_err("rx cmd transfer failed rc=%d\n", rc); + goto exit; + } + + for (i = 0; i < read_config->cmds_rlen; i++) //debug + pr_info("0x%x ", read_config->rbuf[i]); + pr_info("\n"); + +exit: + dsi_display_cmd_engine_disable(display); +exit_ctrl: + dsi_display_clk_ctrl(display->dsi_clk_handle, + DSI_ALL_CLKS, DSI_CLK_OFF); + + return rc; +} + +void dsi_panel_doubleclick_enable(bool on) +{ + struct dsi_display *primary_display = get_main_display(); + if (primary_display && primary_display->panel) + primary_display->panel->tddi_doubleclick_flag = on; +} +EXPORT_SYMBOL(dsi_panel_doubleclick_enable); +#endif + int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl) { int rc = 0; @@ -1886,6 +2238,9 @@ const char *cmd_set_prop_map[DSI_CMD_SET_MAX] = { "qcom,mdss-dsi-sync-pen-30hz-command", "qcom,mdss-dsi-sync-pen-60hz-command", "qcom,mdss-dsi-sync-pen-120hz-command", +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + "mi,mdss-dsi-read-lockdown-info-command", +#endif }; const char *cmd_set_state_map[DSI_CMD_SET_MAX] = { @@ -1918,6 +2273,9 @@ const char *cmd_set_state_map[DSI_CMD_SET_MAX] = { "qcom,mdss-dsi-sync-pen-30hz-command-state", "qcom,mdss-dsi-sync-pen-60hz-command-state", "qcom,mdss-dsi-sync-pen-120hz-command-state", +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + "mi,mdss-dsi-read-lockdown-info-command-state", +#endif }; static int dsi_panel_get_cmd_pkt_count(const char *data, u32 length, u32 *cnt) @@ -3415,6 +3773,27 @@ static int dsi_panel_parse_esd_config(struct dsi_panel *panel) esd_config = &panel->esd_config; esd_config->status_mode = ESD_MODE_MAX; + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* esd-err-flag method will be prefered */ + esd_config->esd_err_irq_gpio = of_get_named_gpio_flags( + panel->panel_of_node, + "qcom,esd-err-irq-gpio", + 0, + (enum of_gpio_flags *)&(esd_config->esd_err_irq_flags)); + if (gpio_is_valid(esd_config->esd_err_irq_gpio)) { + esd_config->esd_err_irq = gpio_to_irq(esd_config->esd_err_irq_gpio); + rc = gpio_request(esd_config->esd_err_irq_gpio, "esd_err_irq_gpio"); + if (rc) + pr_err("%s: Failed to get esd irq gpio %d (code: %d)", + __func__, esd_config->esd_err_irq_gpio, rc); + else + gpio_direction_input(esd_config->esd_err_irq_gpio); + + return 0; + } +#endif + esd_config->esd_enabled = utils->read_bool(utils->data, "qcom,esd-check-enabled"); @@ -3490,6 +3869,28 @@ static void dsi_panel_update_util(struct dsi_panel *panel, utils->node = panel->panel_of_node; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static int dsi_panel_parse_mi_config(struct dsi_panel *panel, + struct device_node *of_node) +{ + int rc = 0; + struct dsi_parser_utils *utils; + + if (panel == NULL) + return -EINVAL; + + utils = &panel->utils; + + panel->is_tddi_flag = utils->read_bool(of_node, + "mi,is-tddi-flag"); + + panel->panel_dead_flag = false; + panel->tddi_doubleclick_flag = false; + + return rc; +} +#endif + static void dsi_panel_esd_enable_delayed_work(struct work_struct *work) { struct dsi_panel *panel = container_of(work, @@ -3617,6 +4018,12 @@ struct dsi_panel *dsi_panel_get(struct device *parent, if (rc) pr_debug("failed to parse esd config, rc=%d\n", rc); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + rc = dsi_panel_parse_mi_config(panel, of_node); + if (rc) + pr_err("failed to parse mi config, rc=%d\n", rc); +#endif + INIT_DELAYED_WORK(&panel->esd_work, dsi_panel_esd_enable_delayed_work); panel->power_mode = SDE_MODE_DPMS_OFF; @@ -4587,6 +4994,9 @@ int dsi_panel_disable(struct dsi_panel *panel) /* Avoid sending panel off commands when ESD recovery is underway */ if (!atomic_read(&panel->esd_recovery_pending)) { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + panel->panel_initialized = false; +#endif /* * Need to set IBB/AB regulator mode to STANDBY, * if panel is going off from AOD mode. diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index aa64c4e753b7..b8e0aa5b2b0e 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -37,6 +37,11 @@ #define DSI_MODE_MAX 5 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define BUF_LEN_MAX 256 +#define MAX_READ_LOCKDOWN_COUNT 200 +#endif + enum dsi_panel_rotation { DSI_PANEL_ROTATE_NONE = 0, DSI_PANEL_ROTATE_HV_FLIP, @@ -167,6 +172,11 @@ struct drm_panel_esd_config { u8 *return_buf; u8 *status_buf; u32 groups; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int esd_err_irq_gpio; + int esd_err_irq; + int esd_err_irq_flags; +#endif }; #define BRIGHTNESS_ALPHA_PAIR_LEN 2 @@ -175,6 +185,21 @@ struct brightness_alpha_pair { u32 alpha; }; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +struct lockdowninfo_cfg { + u8 lockdowninfo[16]; + bool lockdowninfo_read_done; +}; + +struct dsi_read_config { + bool enabled; + struct dsi_panel_cmd_set read_cmd; + u32 cmds_rlen; + u32 valid_bits; + u8 rbuf[BUF_LEN_MAX]; +}; +#endif + struct dsi_panel { const char *name; const char *type; @@ -233,6 +258,14 @@ struct dsi_panel { struct delayed_work esd_work; bool sync_pen_fps; + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + bool is_tddi_flag; + bool tddi_doubleclick_flag; + bool panel_dead_flag; + + struct lockdowninfo_cfg lockdowninfo_read; +#endif }; static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel) @@ -362,4 +395,18 @@ int dsi_panel_set_esd_check(struct dsi_panel *panel); int dsi_panel_sync_pen_fps(struct dsi_panel *panel, struct dsi_display_mode *adj_mode); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int dsi_panel_esd_irq_ctrl(struct dsi_panel *panel, bool enable); + +ssize_t dsi_panel_lockdown_info_read(unsigned char *plockdowninfo); + +int dsi_panel_write_cmd_set(struct dsi_panel *panel, struct dsi_panel_cmd_set *cmd_sets); + +int dsi_panel_read_cmd_set(struct dsi_panel *panel, struct dsi_read_config *read_config); + +void dsi_panel_doubleclick_enable(bool on); + +int dsi_panel_lockdowninfo_param_read(struct dsi_panel *panel); +#endif + #endif /* _DSI_PANEL_H_ */ diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c index e5339f9c1d0a..873bdea40de5 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c @@ -131,6 +131,9 @@ static void dsi_phy_hw_v4_0_lane_settings(struct dsi_phy_hw *phy, * to the logical data lane 0 */ DSI_W32(phy, DSIPHY_LNX_LPRX_CTRL(i), 0); +#ifdef CONFIG_MACH_XIAOMI_NABU + DSI_W32(phy, DSIPHY_LNX_PIN_SWAP(i), 0x0); +#endif } dsi_phy_hw_v4_0_config_lpcdrx(phy, cfg, true); @@ -140,8 +143,10 @@ static void dsi_phy_hw_v4_0_lane_settings(struct dsi_phy_hw *phy, DSI_W32(phy, DSIPHY_LNX_CFG1(i), cfg->lanecfg.lane[i][1]); DSI_W32(phy, DSIPHY_LNX_CFG2(i), cfg->lanecfg.lane[i][2]); DSI_W32(phy, DSIPHY_LNX_TX_DCTRL(i), tx_dctrl[i]); +#ifndef CONFIG_MACH_XIAOMI_NABU DSI_W32(phy, DSIPHY_LNX_PIN_SWAP(i), (cfg->lane_pnswap >> i) & 0x1); +#endif } } diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c index 30a9dbd1d18a..398fb943a8fc 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.c +++ b/drivers/gpu/drm/msm/sde/sde_connector.c @@ -21,6 +21,9 @@ #include #include "dsi_drm.h" #include "dsi_display.h" +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#include "dsi_panel.h" +#endif #include "sde_crtc.h" #include "sde_rm.h" @@ -758,12 +761,19 @@ void sde_connector_helper_bridge_enable(struct drm_connector *connector) MSM_ENC_TX_COMPLETE); c_conn->allow_bl_update = true; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (!display->is_first_boot && c_conn->bl_device) { +#else if (c_conn->bl_device) { +#endif c_conn->bl_device->props.power = FB_BLANK_UNBLANK; c_conn->bl_device->props.state &= ~BL_CORE_FBBLANK; backlight_update_status(c_conn->bl_device); } c_conn->panel_dead = false; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + display->is_first_boot = false; +#endif } int sde_connector_clk_ctrl(struct drm_connector *connector, bool enable) @@ -1879,10 +1889,65 @@ static int sde_connector_atomic_check(struct drm_connector *connector, return 0; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static irqreturn_t esd_err_irq_handle(int irq, void *data) +{ + struct sde_connector *c_conn = data; + struct drm_event event; + bool panel_on = false; + struct dsi_display *display; + + if (!c_conn && !c_conn->display) { + return IRQ_HANDLED; + } + + display = c_conn->display; + + if (!display || !display->panel) { + SDE_ERROR("invalid display/panel\n"); + return IRQ_HANDLED; + } + + if (gpio_get_value(display->panel->esd_config.esd_err_irq_gpio) && display->panel->cphy_esd_check) { + SDE_ERROR("trigger esd by mistake,return\n"); + return IRQ_HANDLED; + } + + if (c_conn->connector_type == DRM_MODE_CONNECTOR_DSI) { + struct dsi_display * dsi_display = (struct dsi_display *)(c_conn->display); + if (dsi_display && dsi_display->panel) { + panel_on = dsi_display->panel->panel_initialized; + } + + if (atomic_read(&(display->panel->esd_recovery_pending))) { + SDE_ERROR("ESD recovery already pending\n"); + return IRQ_HANDLED; + } + + if (panel_on && (c_conn->panel_dead == false)) { + atomic_set(&display->panel->esd_recovery_pending, 1); + } + } + + if (panel_on && (c_conn->panel_dead == false)) { + c_conn->panel_dead = true; + event.type = DRM_EVENT_PANEL_DEAD; + event.length = sizeof(bool); + msm_mode_object_event_notify(&c_conn->base.base, + c_conn->base.dev, &event, (u8 *)&c_conn->panel_dead); + sde_encoder_display_failure_notification(c_conn->encoder,false); + } + return IRQ_HANDLED; +} +#endif + static void _sde_connector_report_panel_dead(struct sde_connector *conn, bool skip_pre_kickoff) { struct drm_event event; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + struct dsi_display *display = (struct dsi_display *)(conn->display); +#endif if (!conn) return; @@ -1896,6 +1961,9 @@ static void _sde_connector_report_panel_dead(struct sde_connector *conn, return; conn->panel_dead = true; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + display->panel->panel_dead_flag = true; +#endif event.type = DRM_EVENT_PANEL_DEAD; event.length = sizeof(bool); msm_mode_object_event_notify(&conn->base.base, @@ -2315,6 +2383,21 @@ struct drm_connector *sde_connector_init(struct drm_device *dev, sizeof(dsi_display->panel->hdr_props), CONNECTOR_PROP_HDR_INFO); } + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* register esd irq and enable it after panel enabled */ + if (dsi_display && dsi_display->panel && + dsi_display->panel->esd_config.esd_err_irq_gpio > 0) { + rc = request_threaded_irq(dsi_display->panel->esd_config.esd_err_irq, + NULL, esd_err_irq_handle, + dsi_display->panel->esd_config.esd_err_irq_flags, + "esd_err_irq", c_conn); + if (rc < 0) { + pr_err("%s: request irq %d failed\n", __func__, dsi_display->panel->esd_config.esd_err_irq); + dsi_display->panel->esd_config.esd_err_irq = 0; + } + } +#endif } rc = sde_connector_get_info(&c_conn->base, &display_info); From 98e5c79dc77054135f4b6f8a4ece0a72b90a4a8a Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 17:55:11 +0200 Subject: [PATCH 040/226] drivers: Import halls driver * From cepheus-q-oss * Run clang-format on source files Change-Id: I0bb9b2a35997c1ef6a078841b9586b9ee94db9a5 Signed-off-by: firebird11 --- drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/halls/Kconfig | 9 ++ drivers/halls/Makefile | 1 + drivers/halls/halls.c | 311 +++++++++++++++++++++++++++++++++++++++++ include/linux/halls.h | 7 + 6 files changed, 331 insertions(+) create mode 100644 drivers/halls/Kconfig create mode 100644 drivers/halls/Makefile create mode 100644 drivers/halls/halls.c create mode 100644 include/linux/halls.h diff --git a/drivers/Kconfig b/drivers/Kconfig index 43377a3acb97..cfd0d22ebcca 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -225,4 +225,6 @@ source "drivers/sensors/Kconfig" source "drivers/esoc/Kconfig" +source "drivers/halls/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 4a067525bbdc..2f8e36eb37d5 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -188,6 +188,7 @@ obj-$(CONFIG_TEE) += tee/ obj-$(CONFIG_MULTIPLEXER) += mux/ obj-$(CONFIG_SENSORS_SSC) += sensors/ obj-$(CONFIG_ESOC) += esoc/ +obj-$(CONFIG_HALLS) += halls/ # GNSS driver obj-$(CONFIG_GNSS_SIRF) += gnsssirf/ obj-$(CONFIG_GNSS) += gnss/ diff --git a/drivers/halls/Kconfig b/drivers/halls/Kconfig new file mode 100644 index 000000000000..75543568a7b1 --- /dev/null +++ b/drivers/halls/Kconfig @@ -0,0 +1,9 @@ +menu "Halls" + +config HALLS + bool "Halls" + default n + ---help--- + it's to handle hall sensors for slide + +endmenu diff --git a/drivers/halls/Makefile b/drivers/halls/Makefile new file mode 100644 index 000000000000..7c7b3ec68643 --- /dev/null +++ b/drivers/halls/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_HALLS) += halls.o diff --git a/drivers/halls/halls.c b/drivers/halls/halls.c new file mode 100644 index 000000000000..b7060a2b9771 --- /dev/null +++ b/drivers/halls/halls.c @@ -0,0 +1,311 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define HALLS_LOG printk + +#define LOGTAG "halls " +#define DEF_HALLS_DEVICE_NAME "halls" + +#define DEF_HALLS_IOCTRL_READ_HALL_1 1000 +#define DEF_HALLS_IOCTRL_READ_HALL_2 2000 +#define DEF_HALLS_IOCTRL_FLUSH 3000 + +#define DEF_HALLS_IOCTRL_STEUP 4000 +#define DEF_HALLS_IOCTRL_RELEASE 5000 + +#define DEF_HALL_IRQ_1_FIRED "h-1" +#define DEF_HALL_IRQ_2_FIRED "h-2" +#define DEF_HALL_FLUSH "flu" + +#define DEF_HALL_GPIO_1 42 +#define DEF_HALL_GPIO_2 114 + +//extern int elliptic_set_hall_state(int state); + +static int g_gpio_1_irq; +static int g_gpio_2_irq; +static int g_in_firedirq; +static int g_in_end; +static int g_in_flush; + +static int g_in_opencounter; + +struct _hall_device { + struct miscdevice miscdev; + struct delayed_work notify_work; + struct wakeup_source *hall_wakelock; + int hall_status; +}; + +struct _hall_device *g_st_halls; +struct semaphore g_st_semhallirq; + +halls_status_notify halls_status_notify_cb = NULL; + +void halls_register_halls_status_notify(halls_status_notify halls_cb) +{ + halls_status_notify_cb = halls_cb; +} + +void halls_deregister_halls_status_notify(halls_status_notify halls_cb) +{ + halls_status_notify_cb = NULL; +} + +static void hall_notify_work_func(struct work_struct *work) +{ + int iRet1 = 0, iRet2 = 0; + iRet1 = gpio_get_value_cansleep(DEF_HALL_GPIO_1); + iRet2 = gpio_get_value_cansleep(DEF_HALL_GPIO_2); + HALLS_LOG(LOGTAG "g_in_firedirq %d, g_gpio_1_irq %d, g_gpio_2_irq %d", + g_in_firedirq, g_gpio_1_irq, g_gpio_2_irq); + HALLS_LOG(LOGTAG " iRet1 %d iRet2 %d", iRet1, iRet2); + if (iRet1 == 0 && iRet2 == 1) { + g_st_halls->hall_status = 1; + } else if (iRet1 == 1 && iRet2 == 0) { + g_st_halls->hall_status = 0; + } else { + g_st_halls->hall_status = 2; + } + + HALLS_LOG(LOGTAG "hall_notify_work_func notify audio hall_status: %d!", + g_st_halls->hall_status); + //elliptic_set_hall_state(g_st_halls->hall_status); + if (halls_status_notify_cb != NULL) { + halls_status_notify_cb(g_st_halls->hall_status); + } +} + +static irqreturn_t halls_irq_handler(int irqno, void *dev_id) +{ + HALLS_LOG(LOGTAG "Entered halls_irq_handler irqno %d\n", irqno); + __pm_wakeup_event(g_st_halls->hall_wakelock, 20); + g_in_firedirq = irqno; + up(&g_st_semhallirq); + schedule_delayed_work(&g_st_halls->notify_work, 0); + return 0; +} + +static int halls_configurate_input(int in_GPIO, const char *ch_mark) +{ + int iRet = 0; + + iRet = gpio_request(in_GPIO, ch_mark); + if (iRet) + pr_err("%d is being used!\n", in_GPIO); + + iRet = gpio_direction_input(in_GPIO); + if (iRet) + pr_err("Setting hall gpio direction failed! iRet %d\n", iRet); + + return iRet; +} + +static int halls_configurate_irq(int in_GPIO, const char *ch_mark, void *arg, + int *out_irq) +{ + int iRet = 0, in_IRQ = 0; + + in_IRQ = gpio_to_irq(in_GPIO); + *out_irq = in_IRQ; + HALLS_LOG(LOGTAG "in_GPIO %d, IRQ %d\n", in_GPIO, in_IRQ); + iRet = request_irq(in_IRQ, halls_irq_handler, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + ch_mark, arg); + if (iRet) + pr_err("request_irq failed! iRet %d\n", iRet); + irq_set_irq_wake(in_IRQ, 1); + + HALLS_LOG(LOGTAG "request_irq return %d\n", iRet); + return iRet; +} + +static ssize_t halls_read(struct file *file, char __user *buf, size_t count, + loff_t *ppos) +{ + int iRead = 0; + + HALLS_LOG(LOGTAG "Entereed halls_read count %d", (int)count); + if (down_interruptible(&g_st_semhallirq)) { + HALLS_LOG(LOGTAG "down_interruptible failed!"); + } + if (g_in_end == 1) { + HALLS_LOG(LOGTAG "Ending... "); + return -EPERM; + } + HALLS_LOG(LOGTAG "g_in_firedirq %d, g_gpio_1_irq %d, g_gpio_2_irq %d", + g_in_firedirq, g_gpio_1_irq, g_gpio_2_irq); + if (g_in_flush == 1) { + g_in_flush = 0; + iRead = copy_to_user(buf, DEF_HALL_FLUSH, + strlen(DEF_HALL_FLUSH)); + HALLS_LOG(LOGTAG "End of copy_to_user flash... "); + } else if (g_in_firedirq == g_gpio_1_irq) { + iRead = copy_to_user(buf, DEF_HALL_IRQ_1_FIRED, + strlen(DEF_HALL_IRQ_1_FIRED)); + HALLS_LOG(LOGTAG "End of copy_to_user 1... "); + } else if (g_in_firedirq == g_gpio_2_irq) { + iRead = copy_to_user(buf, DEF_HALL_IRQ_2_FIRED, + strlen(DEF_HALL_IRQ_2_FIRED)); + HALLS_LOG(LOGTAG "End of copy_to_user 2... "); + } + return iRead; +} + +long halls_in_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int iRet = 0; + void *p_ReadValue = (void *)arg; + char ch_data[10] = { 0 }; + + HALLS_LOG(LOGTAG "Enter halls_in_ioctl cmd %d", cmd); + switch (cmd) { + case DEF_HALLS_IOCTRL_READ_HALL_1: { + iRet = gpio_get_value_cansleep(DEF_HALL_GPIO_1); + HALLS_LOG(LOGTAG "Read HALL_1 %d", iRet); + snprintf(ch_data, sizeof(ch_data), "%d", iRet); + iRet = copy_to_user(p_ReadValue, ch_data, strlen(ch_data)); + break; + } + case DEF_HALLS_IOCTRL_READ_HALL_2: { + iRet = gpio_get_value_cansleep(DEF_HALL_GPIO_2); + HALLS_LOG(LOGTAG "Read HALL_2 %d", iRet); + snprintf(ch_data, sizeof(ch_data), "%d", iRet); + iRet = copy_to_user(p_ReadValue, ch_data, strlen(ch_data)); + break; + } + case DEF_HALLS_IOCTRL_FLUSH: { + g_in_flush = 1; + up(&g_st_semhallirq); + schedule_delayed_work(&g_st_halls->notify_work, 0); + break; + } + case DEF_HALLS_IOCTRL_STEUP: { + if (g_in_opencounter == 0) { + g_in_end = 0; + sema_init(&g_st_semhallirq, 0); + iRet = halls_configurate_irq(DEF_HALL_GPIO_1, "hall-1", + (void *)g_st_halls, + &g_gpio_1_irq); + if (iRet) + pr_err("halls_configurate_irq failed!%d, iRet %d\n", + DEF_HALL_GPIO_1, iRet); + g_in_firedirq = g_gpio_1_irq; + + iRet = halls_configurate_irq(DEF_HALL_GPIO_2, "hall-2", + (void *)g_st_halls, + &g_gpio_2_irq); + if (iRet) + pr_err("halls_configurate_irq failed! %d iRet %d\n", + DEF_HALL_GPIO_2, iRet); + + HALLS_LOG(LOGTAG "g_gpio_2_irq %d, g_gpio_2_irq %d\n", + g_gpio_1_irq, g_gpio_2_irq); + g_in_opencounter = 1; + } + break; + } + case DEF_HALLS_IOCTRL_RELEASE: { + g_in_end = 1; + up(&g_st_semhallirq); + if (g_gpio_1_irq > 0) + free_irq(g_gpio_1_irq, g_st_halls); + + if (g_gpio_2_irq > 0) + free_irq(g_gpio_2_irq, g_st_halls); + g_in_opencounter = 0; + break; + } + default: + iRet = -1; + } + HALLS_LOG(LOGTAG "read value cmd %d, iRet %d", cmd, iRet); + return iRet; +} + +int halls_flush(struct file *file, fl_owner_t id) +{ + HALLS_LOG(LOGTAG " Entered halls_flush \n"); + return 0; +} + +int halls_open(struct inode *node, struct file *file) +{ + int iRet = 0; + + return iRet; +} + +static const struct file_operations halls_fops = { + .owner = THIS_MODULE, + .read = halls_read, + .unlocked_ioctl = halls_in_ioctl, + .flush = halls_flush, + .open = halls_open, +}; + +static int __init halls_init(void) +{ + int ret; + g_st_halls = kzalloc(sizeof(struct _hall_device), GFP_KERNEL); + if (!g_st_halls) + return -ENOMEM; + g_st_halls->miscdev.fops = &halls_fops; + g_st_halls->miscdev.minor = MISC_DYNAMIC_MINOR; + g_st_halls->miscdev.name = DEF_HALLS_DEVICE_NAME; + ret = misc_register(&g_st_halls->miscdev); + if (ret < 0) { + kfree(g_st_halls); + return ret; + } + ret = halls_configurate_input(DEF_HALL_GPIO_1, "hall-1"); + if (ret) { + pr_err("halls_configurate_input failed!%d, ret %d\n", + DEF_HALL_GPIO_1, ret); + gpio_free(DEF_HALL_GPIO_1); + return ret; + } + ret = halls_configurate_input(DEF_HALL_GPIO_2, "hall-2"); + if (ret) { + pr_err("halls_configurate_input failed! %d ret %d\n", + DEF_HALL_GPIO_2, ret); + gpio_free(DEF_HALL_GPIO_2); + return ret; + } + + g_st_halls->hall_status = 0; + INIT_DELAYED_WORK(&g_st_halls->notify_work, hall_notify_work_func); + + g_st_halls->hall_wakelock = wakeup_source_register("dual_hall_ws"); + if (!g_st_halls->hall_wakelock) { + pr_err("g_st_halls wakeup_source_register failed!\n"); + return ret; + } + + return ret; +} + +device_initcall(halls_init); + +static void __exit halls_exit(void) +{ + gpio_free(DEF_HALL_GPIO_1); + gpio_free(DEF_HALL_GPIO_2); +} + +module_exit(halls_exit); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/halls.h b/include/linux/halls.h new file mode 100644 index 000000000000..f9cf7349bf94 --- /dev/null +++ b/include/linux/halls.h @@ -0,0 +1,7 @@ +#ifndef HALLS_H +#define HALLS_H + +typedef void (*halls_status_notify)(int halls_status); +extern void halls_register_halls_status_notify(halls_status_notify halls_cb); + +#endif /* HALLS_H */ From db9e9b0e4c3134c880667f30382e59558ae03969 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Tue, 16 Apr 2024 03:39:16 +0200 Subject: [PATCH 041/226] drivers: halls: Fix compilation Change-Id: I474a9b983659ec6df30acaafe78c3204d83cc1e3 Signed-off-by: firebird11 --- drivers/halls/halls.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/halls/halls.c b/drivers/halls/halls.c index b7060a2b9771..2169261feb06 100644 --- a/drivers/halls/halls.c +++ b/drivers/halls/halls.c @@ -290,7 +290,8 @@ static int __init halls_init(void) g_st_halls->hall_status = 0; INIT_DELAYED_WORK(&g_st_halls->notify_work, hall_notify_work_func); - g_st_halls->hall_wakelock = wakeup_source_register("dual_hall_ws"); + g_st_halls->hall_wakelock = wakeup_source_register( + g_st_halls->miscdev.this_device, "dual_hall_ws"); if (!g_st_halls->hall_wakelock) { pr_err("g_st_halls wakeup_source_register failed!\n"); return ret; From d1fe373220c285c6d85a5fbf1469fb0ca5957295 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 17:57:23 +0200 Subject: [PATCH 042/226] drivers: iio: adc: Import Xiaomi changes Change-Id: I0a5ef10d57b86f21b4acbf7255826bdbed629cc0 Signed-off-by: firebird11 --- drivers/iio/adc/qcom-spmi-adc5.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c index 4ba747ce108d..36861c2b17f3 100644 --- a/drivers/iio/adc/qcom-spmi-adc5.c +++ b/drivers/iio/adc/qcom-spmi-adc5.c @@ -763,10 +763,17 @@ static const struct adc_channels adc_chans_pmic5[ADC_MAX_CHANNEL] = { SCALE_HW_CALIB_PM5_SMB_TEMP) [ADC_AMUX_THM3] = ADC_CHAN_TEMP("amux_thm3", 1, SCALE_HW_CALIB_PM5_SMB_TEMP) +#ifdef CONFIG_MACH_XIAOMI_SM8150 + [ADC_GPIO1_PU2] = ADC_CHAN_VOLT("gpio1_pu2", 1, + SCALE_HW_CALIB_DEFAULT) + [ADC_GPIO2_PU2] = ADC_CHAN_VOLT("gpio2_pu2", 1, + SCALE_HW_CALIB_DEFAULT) +#else [ADC_GPIO1_PU2] = ADC_CHAN_TEMP("gpio1_pu2", 1, SCALE_HW_CALIB_THERM_100K_PULLUP) [ADC_GPIO2_PU2] = ADC_CHAN_TEMP("gpio2_pu2", 1, SCALE_HW_CALIB_THERM_100K_PULLUP) +#endif [ADC_GPIO3_PU2] = ADC_CHAN_TEMP("gpio3_pu2", 1, SCALE_HW_CALIB_THERM_100K_PULLUP) [ADC_GPIO4_PU2] = ADC_CHAN_TEMP("gpio4_pu2", 1, From 40d855a9c3b7db6f68f0e7637c95038cbb0af259 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 17:58:43 +0200 Subject: [PATCH 043/226] drivers: iio: proximity: Import MIUS driver * From nabu-r-oss * Run clang-format on source files Change-Id: Iefd42f02cac26acb71fe6bd7e1c78dea982b80ee Signed-off-by: firebird11 --- drivers/iio/proximity/Kconfig | 8 + drivers/iio/proximity/Makefile | 1 + drivers/iio/proximity/us_prox.c | 335 ++++++++++++++++++++++++++++++++ 3 files changed, 344 insertions(+) create mode 100644 drivers/iio/proximity/us_prox.c diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig index c03de24d3c51..0a64be17930b 100644 --- a/drivers/iio/proximity/Kconfig +++ b/drivers/iio/proximity/Kconfig @@ -69,4 +69,12 @@ config SRF08 To compile this driver as a module, choose M here: the module will be called srf08. +config US_PROXIMITY + tristate "xiaomi ultrasound proximity sensor" + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + select IIO_BUFFER_CB + select IIO_KFIFO_BUF + select IIO_TRIGGER + endmenu diff --git a/drivers/iio/proximity/Makefile b/drivers/iio/proximity/Makefile index ad6686391f08..6420fb39d232 100644 --- a/drivers/iio/proximity/Makefile +++ b/drivers/iio/proximity/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_LIDAR_LITE_V2) += pulsedlight-lidar-lite-v2.o obj-$(CONFIG_SRF04) += srf04.o obj-$(CONFIG_SRF08) += srf08.o obj-$(CONFIG_SX9500) += sx9500.o +obj-$(CONFIG_US_PROXIMITY) += us_prox.o diff --git a/drivers/iio/proximity/us_prox.c b/drivers/iio/proximity/us_prox.c new file mode 100644 index 000000000000..c6874cb2ecba --- /dev/null +++ b/drivers/iio/proximity/us_prox.c @@ -0,0 +1,335 @@ +/* + * + * Copyright (C) 2018 XiaoMi, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define US_PROX_IIO_NAME "distance" + +static struct us_prox_data *g_us_prox; + +struct us_prox_data { + struct platform_device *pdev; + /* common state */ + struct mutex mutex; + /* for proximity sensor */ + struct iio_dev *prox_idev; + bool prox_enabled; + int raw_data; +}; + +struct us_prox_el_data { + uint16_t data1; + uint16_t data2; + int64_t timestamp; +}; + +#define US_SENSORS_CHANNELS(device_type, mask, index, mod, ch2, s, endian, \ + rbits, sbits, addr) \ + { \ + .type = device_type, .modified = mod, \ + .info_mask_separate = mask, .scan_index = index, \ + .channel2 = ch2, .address = addr, \ + .scan_type = { \ + .sign = s, \ + .realbits = rbits, \ + .shift = sbits - rbits, \ + .storagebits = sbits, \ + .endianness = endian, \ + }, \ + } + +static const struct iio_chan_spec us_proximity_channels[] = { + US_SENSORS_CHANNELS(IIO_PROXIMITY, + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), + 0, 0, IIO_NO_MOD, 'u', IIO_LE, 16, 16, 0), + IIO_CHAN_SOFT_TIMESTAMP(2) +}; + +static int us_buffer_postenable(struct iio_dev *indio_dev) +{ + int ret = 0; + return ret; +} + +static int us_buffer_predisable(struct iio_dev *indio_dev) +{ + int ret = 0; + return ret; +} + +static const struct iio_buffer_setup_ops us_buffer_setup_ops = { + .postenable = us_buffer_postenable, + .predisable = us_buffer_predisable, +}; + +static const struct iio_trigger_ops us_sensor_trigger_ops = { + .owner = THIS_MODULE, +}; + +int us_setup_trigger_sensor(struct iio_dev *indio_dev) +{ + struct iio_trigger *trigger; + int ret; + + trigger = iio_trigger_alloc("%s-dev%d", indio_dev->name, indio_dev->id); + if (!trigger) + return -ENOMEM; + + trigger->dev.parent = indio_dev->dev.parent; + trigger->ops = &us_sensor_trigger_ops; + ret = iio_trigger_register(trigger); + if (ret < 0) + goto exit_free_trigger; + + indio_dev->trig = trigger; + + return 0; + +exit_free_trigger: + iio_trigger_free(trigger); + return ret; +} + +int us_afe_callback(int data) +{ + int ret; + struct us_prox_el_data el_data; + struct timespec ts; + + get_monotonic_boottime(&ts); + el_data.timestamp = timespec_to_ns(&ts); + pr_info("%s: data = %d\n", __func__, data); + + if (!data) + el_data.data1 = 0; + else + el_data.data1 = 5; + + if (g_us_prox) { + ret = iio_push_to_buffers(g_us_prox->prox_idev, + (unsigned char *)&el_data); + if (ret < 0) + pr_err("%s: failed to push us prox data to buffer, err=%d\n", + __func__, ret); + } + + return 0; +} + +EXPORT_SYMBOL(us_afe_callback); + +static ssize_t us_show_dump_output(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct us_prox_data *data; + unsigned long value; + + data = *((struct us_prox_data **)iio_priv(dev_get_drvdata(dev))); + + mutex_lock(&data->mutex); + value = data->raw_data; + mutex_unlock(&data->mutex); + + return scnprintf(buf, PAGE_SIZE, "%lu\n", value); +} + +static ssize_t us_store_dump_output(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + return 0; +} + +static DEVICE_ATTR(dump_output, S_IWUSR | S_IRUGO, us_show_dump_output, + us_store_dump_output); + +static struct attribute *us_prox_attributes[] = { + &dev_attr_dump_output.attr, + NULL, +}; + +static struct attribute_group us_prox_attribute_group = { + .attrs = us_prox_attributes, +}; + +static const struct iio_info us_proximity_info = { + .driver_module = THIS_MODULE, + .attrs = &us_prox_attribute_group, +}; + +static int us_proximity_iio_setup(struct us_prox_data *data) +{ + struct iio_dev *idev; + struct us_prox_data **priv_data; + int ret = 0; + + idev = iio_device_alloc(sizeof(*priv_data)); + if (!idev) { + pr_err("us prox IIO memory alloc fail\n"); + return -ENOMEM; + } + + data->prox_idev = idev; + + idev->channels = us_proximity_channels; + idev->num_channels = ARRAY_SIZE(us_proximity_channels); + idev->dev.parent = &(data->pdev->dev); + idev->info = &us_proximity_info; + idev->name = US_PROX_IIO_NAME; + idev->modes = INDIO_DIRECT_MODE; + + priv_data = iio_priv(idev); + *priv_data = data; + + ret = iio_triggered_buffer_setup(idev, NULL, NULL, + &us_buffer_setup_ops); + if (ret < 0) + goto free_iio_p; + + ret = us_setup_trigger_sensor(idev); + if (ret < 0) + goto free_buffer_p; + + ret = iio_device_register(idev); + if (ret) { + pr_err("Proximity IIO register fail\n"); + goto free_trigger_p; + } + return ret; + +free_trigger_p: + iio_trigger_unregister(idev->trig); + iio_trigger_free(idev->trig); +free_buffer_p: + iio_triggered_buffer_cleanup(idev); +free_iio_p: + data->prox_idev = NULL; + iio_device_free(idev); + return ret; +} + +static int us_proximity_teardown(struct us_prox_data *data) +{ + iio_device_unregister(data->prox_idev); + iio_trigger_unregister(data->prox_idev->trig); + iio_trigger_free(data->prox_idev->trig); + iio_triggered_buffer_cleanup(data->prox_idev); + iio_device_free(data->prox_idev); + + return 0; +} + +static int us_prox_probe(struct platform_device *pdev) +{ + int ret = 0; + struct us_prox_data *us_prox; + + pr_info("%s: start\n", __func__); + + us_prox = kzalloc(sizeof(*us_prox), GFP_KERNEL); + if (!us_prox) + return -ENOMEM; + + us_prox->pdev = pdev; + dev_set_drvdata(&pdev->dev, us_prox); + + g_us_prox = us_prox; + + mutex_init(&us_prox->mutex); + ret = us_proximity_iio_setup(us_prox); + if (ret < 0) { + pr_err("%s: iio setup failed ret = %d\n", __func__, ret); + return ret; + } + + pr_info("%s: end\n", __func__); + return ret; +} + +static int us_prox_remove(struct platform_device *pdev) +{ + struct us_prox_data *us_prox; + + us_prox = dev_get_drvdata(&pdev->dev); + + dev_set_drvdata(&pdev->dev, NULL); + + if (us_prox) { + us_proximity_teardown(us_prox); + kfree(us_prox); + } + + return 0; +} + +static const struct of_device_id dt_match[] = { + { .compatible = "us_prox" }, + {}, +}; + +static struct platform_driver us_prox_driver = { + .probe = us_prox_probe, + .remove = us_prox_remove, + .driver = { + .name = "us_prox", + .of_match_table = dt_match, + }, +}; + +static struct platform_device us_prox_dev = { + .name = "us_prox", + .dev = { + .platform_data = NULL, + }, +}; + +static int __init us_prox_init(void) +{ + platform_device_register(&us_prox_dev); + return platform_driver_register(&us_prox_driver); +} +module_init(us_prox_init); + +static void __exit us_prox_exit(void) +{ + platform_driver_unregister(&us_prox_driver); + platform_device_unregister(&us_prox_dev); +} +module_exit(us_prox_exit); + +MODULE_AUTHOR("xiaomi"); +MODULE_DESCRIPTION("Ultrasound IIO driver"); +MODULE_LICENSE("GPL"); From 00a450be02d44013c453078ed351d9a2eeb599f8 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 18:00:41 +0200 Subject: [PATCH 044/226] drivers: input: fingerprint: Import Xiaomi fingerprint drivers * Run clang-format on source files Change-Id: I6bb929b295b0dd9394e0dc0af674cc0be00422ab Signed-off-by: firebird11 --- drivers/input/Kconfig | 2 + drivers/input/Makefile | 1 + drivers/input/fingerprint/Kconfig | 17 + drivers/input/fingerprint/Makefile | 8 + drivers/input/fingerprint/fpc_tee/Kconfig | 16 + drivers/input/fingerprint/fpc_tee/Makefile | 1 + .../input/fingerprint/fpc_tee/fpc1020_tee.c | 872 +++++++++++++ drivers/input/fingerprint/goodix_ta/Kconfig | 10 + drivers/input/fingerprint/goodix_ta/Makefile | 1 + drivers/input/fingerprint/goodix_ta/gf_spi.c | 1077 +++++++++++++++++ drivers/input/fingerprint/goodix_ta/gf_spi.h | 160 +++ drivers/input/fingerprint/goodix_ta/netlink.c | 97 ++ .../input/fingerprint/goodix_ta/platform.c | 150 +++ 13 files changed, 2412 insertions(+) create mode 100644 drivers/input/fingerprint/Kconfig create mode 100644 drivers/input/fingerprint/Makefile create mode 100644 drivers/input/fingerprint/fpc_tee/Kconfig create mode 100644 drivers/input/fingerprint/fpc_tee/Makefile create mode 100644 drivers/input/fingerprint/fpc_tee/fpc1020_tee.c create mode 100644 drivers/input/fingerprint/goodix_ta/Kconfig create mode 100644 drivers/input/fingerprint/goodix_ta/Makefile create mode 100644 drivers/input/fingerprint/goodix_ta/gf_spi.c create mode 100644 drivers/input/fingerprint/goodix_ta/gf_spi.h create mode 100644 drivers/input/fingerprint/goodix_ta/netlink.c create mode 100644 drivers/input/fingerprint/goodix_ta/platform.c diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 1b748ad70af3..285cae64411f 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -215,6 +215,8 @@ source "drivers/input/sensors/smi130/Kconfig" source "drivers/input/rmi4/Kconfig" +source "drivers/input/fingerprint/Kconfig" + endif menu "Hardware I/O ports" diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 7133c3bc1b04..6d0bf108d536 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_INPUT_JOYSTICK) += joystick/ obj-$(CONFIG_INPUT_TABLET) += tablet/ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ obj-$(CONFIG_INPUT_MISC) += misc/ +obj-$(CONFIG_INPUT_FINGERPRINT) += fingerprint/ obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o obj-$(CONFIG_INPUT_KEYRESET) += keyreset.o diff --git a/drivers/input/fingerprint/Kconfig b/drivers/input/fingerprint/Kconfig new file mode 100644 index 000000000000..785c6066ce6b --- /dev/null +++ b/drivers/input/fingerprint/Kconfig @@ -0,0 +1,17 @@ +# +# Fingerprint driver configuration +# +menuconfig INPUT_FINGERPRINT + bool "Fingerprints" + help + Say Y here, and a list of supported fingerprints will be displayed. + This option doesn't affect the kernel. + + If unsure, say Y. + +if INPUT_FINGERPRINT + +source "drivers/input/fingerprint/goodix_ta/Kconfig" +source "drivers/input/fingerprint/fpc_tee/Kconfig" + +endif diff --git a/drivers/input/fingerprint/Makefile b/drivers/input/fingerprint/Makefile new file mode 100644 index 000000000000..e128700726eb --- /dev/null +++ b/drivers/input/fingerprint/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the fingerprint drivers. +# + +# Each configuration option enables a list of files. + +obj-$(CONFIG_FINGERPRINT_GOODIX_TA) += goodix_ta/ +obj-$(CONFIG_FINGERPRINT_FPC_TEE) += fpc_tee/ diff --git a/drivers/input/fingerprint/fpc_tee/Kconfig b/drivers/input/fingerprint/fpc_tee/Kconfig new file mode 100644 index 000000000000..6cfc23fa0f37 --- /dev/null +++ b/drivers/input/fingerprint/fpc_tee/Kconfig @@ -0,0 +1,16 @@ +config FINGERPRINT_FPC_TEE + tristate "Finger print card fpc" + depends on INPUT_FINGERPRINT + help + Say Y here to enable support for retrieving self-test reports. + + If unsure, say N. + + To compile this driver as a module, choose M here. + +config FINGERPRINT_FPC_SCREEN_NOTIFY + bool "fingerprint get screen status and notify" + default n + depends on FINGERPRINT_FPC_TEE + ---help--- + Say Y here to enable notify screen on/off status. diff --git a/drivers/input/fingerprint/fpc_tee/Makefile b/drivers/input/fingerprint/fpc_tee/Makefile new file mode 100644 index 000000000000..ac8f1bdeb071 --- /dev/null +++ b/drivers/input/fingerprint/fpc_tee/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_FINGERPRINT_FPC_TEE) += fpc1020_tee.o diff --git a/drivers/input/fingerprint/fpc_tee/fpc1020_tee.c b/drivers/input/fingerprint/fpc_tee/fpc1020_tee.c new file mode 100644 index 000000000000..4c192c32d1d9 --- /dev/null +++ b/drivers/input/fingerprint/fpc_tee/fpc1020_tee.c @@ -0,0 +1,872 @@ +/* + * FPC1020 Fingerprint sensor device driver + * + * This driver will control the platform resources that the FPC fingerprint + * sensor needs to operate. The major things are probing the sensor to check + * that it is actually connected and let the Kernel know this and with that also + * enabling and disabling of regulators, controlling GPIOs such as sensor reset + * line, sensor IRQ line. + * + * The driver will expose most of its available functionality in sysfs which + * enables dynamic control of these features from eg. a user space process. + * + * The sensor's IRQ events will be pushed to Kernel's event handling system and + * are exposed in the drivers event node. + * + * This driver will NOT send any commands to the sensor it only controls the + * electrical parts. + * + * + * Copyright (c) 2015 Fingerprint Cards AB + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License Version 2 + * as published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FPC_SCREEN_HOLD_TIME 2000 +#define FPC_TTW_HOLD_TIME 2000 +#define FP_UNLOCK_REJECTION_TIMEOUT (FPC_TTW_HOLD_TIME - 500) + +#define RESET_LOW_SLEEP_MIN_US 5000 +#define RESET_LOW_SLEEP_MAX_US (RESET_LOW_SLEEP_MIN_US + 100) +#define RESET_HIGH_SLEEP1_MIN_US 100 +#define RESET_HIGH_SLEEP1_MAX_US (RESET_HIGH_SLEEP1_MIN_US + 100) +#define RESET_HIGH_SLEEP2_MIN_US 5000 +#define RESET_HIGH_SLEEP2_MAX_US (RESET_HIGH_SLEEP2_MIN_US + 100) +#define PWR_ON_SLEEP_MIN_US 100 +#define PWR_ON_SLEEP_MAX_US (PWR_ON_SLEEP_MIN_US + 900) + +#define NUM_PARAMS_REG_ENABLE_SET 2 + +static const char *const pctl_names[] = { + "fpc1020_reset_reset", + "fpc1020_reset_active", +}; + +struct vreg_config { + char *name; + unsigned long vmin; + unsigned long vmax; + int ua_load; +}; + +static const struct vreg_config const vreg_conf[] = { + { + "vdd_ana", + 1800000UL, + 1800000UL, + 6000, + }, + { + "fp_vdd_vreg", + 3000000UL, + 3000000UL, + 6000, + }, + /* + { + "vcc_spi", + 1800000UL, + 1800000UL, + 10, + }, + { + "vdd_io", + 1800000UL, + 1800000UL, + 6000, + }, + */ +}; + +struct fpc1020_data { + struct device *dev; + + struct pinctrl *fingerprint_pinctrl; + struct pinctrl_state *pinctrl_state[ARRAY_SIZE(pctl_names)]; + struct regulator *vreg[ARRAY_SIZE(vreg_conf)]; + + struct wakeup_source ttw_wl; + struct wakeup_source screen_wl; + int irq_gpio; + int rst_gpio; + struct mutex lock; /* To set/get exported values in sysfs */ + bool prepared; + atomic_t wakeup_enabled; /* Used both in ISR and non-ISR */ + int irqf; + struct notifier_block fb_notifier; + bool fb_black; + bool wait_finger_down; + struct work_struct work; +}; + +static irqreturn_t fpc1020_irq_handler(int irq, void *handle); +static int fpc1020_request_named_gpio(struct fpc1020_data *fpc1020, + const char *label, int *gpio); + +static int vreg_setup(struct fpc1020_data *fpc1020, const char *name, + bool enable) +{ + size_t i; + int rc; + struct regulator *vreg; + struct device *dev = fpc1020->dev; + + for (i = 0; i < ARRAY_SIZE(fpc1020->vreg); i++) { + const char *n = vreg_conf[i].name; + + if (!strncmp(n, name, strlen(n))) + goto found; + } + + dev_err(dev, "Regulator %s not found\n", name); + + return -EINVAL; + +found: + vreg = fpc1020->vreg[i]; + if (enable) { + if (!vreg) { + vreg = regulator_get(dev, name); + if (IS_ERR(vreg)) { + dev_err(dev, "Unable to get %s\n", name); + return PTR_ERR(vreg); + } + } +#if 0 + if (regulator_count_voltages(vreg) > 0) { + rc = regulator_set_voltage(vreg, vreg_conf[i].vmin, + vreg_conf[i].vmax); + if (rc) + dev_err(dev, + "Unable to set voltage on %s, %d\n", + name, rc); + } + + rc = regulator_set_optimum_mode(vreg, vreg_conf[i].ua_load); + if (rc < 0) + dev_err(dev, "Unable to set current on %s, %d\n", + name, rc); +#endif + rc = regulator_enable(vreg); + if (rc) { + dev_err(dev, "error enabling %s: %d\n", name, rc); + regulator_put(vreg); + vreg = NULL; + } + fpc1020->vreg[i] = vreg; + dev_err(dev, "fp_vdd_vreg is enabled!\n"); + } else { + if (vreg) { + if (regulator_is_enabled(vreg)) { + regulator_disable(vreg); + dev_err(dev, "disabled %s\n", name); + } + regulator_put(vreg); + fpc1020->vreg[i] = NULL; + } + rc = 0; + } + + return rc; +} + +/** + * sysfs node for controlling clocks. + * + * This is disabled in platform variant of this driver but kept for + * backwards compatibility. Only prints a debug print that it is + * disabled. + */ +static ssize_t clk_enable_set(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + dev_dbg(dev, "clk_enable sysfs node not enabled in platform driver\n"); + + return count; +} +static DEVICE_ATTR(clk_enable, S_IWUSR, NULL, clk_enable_set); + +/** + * Will try to select the set of pins (GPIOS) defined in a pin control node of + * the device tree named @p name. + * + * The node can contain several eg. GPIOs that is controlled when selecting it. + * The node may activate or deactivate the pins it contains, the action is + * defined in the device tree node itself and not here. The states used + * internally is fetched at probe time. + * + * @see pctl_names + * @see fpc1020_probe + */ +static int select_pin_ctl(struct fpc1020_data *fpc1020, const char *name) +{ + size_t i; + int rc; + struct device *dev = fpc1020->dev; + + for (i = 0; i < ARRAY_SIZE(fpc1020->pinctrl_state); i++) { + const char *n = pctl_names[i]; + + if (!strncmp(n, name, strlen(n))) { + rc = pinctrl_select_state(fpc1020->fingerprint_pinctrl, + fpc1020->pinctrl_state[i]); + if (rc) + dev_err(dev, "cannot select '%s'\n", name); + else + dev_dbg(dev, "Selected '%s'\n", name); + goto exit; + } + } + + rc = -EINVAL; + dev_err(dev, "%s:'%s' not found\n", __func__, name); + +exit: + return rc; +} + +static ssize_t pinctl_set(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + int rc; + + mutex_lock(&fpc1020->lock); + rc = select_pin_ctl(fpc1020, buf); + mutex_unlock(&fpc1020->lock); + + return rc ? rc : count; +} +static DEVICE_ATTR(pinctl_set, S_IWUSR, NULL, pinctl_set); + +static ssize_t regulator_enable_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + int rc = 0; + + if (!strncmp(buf, "e", strlen("e"))) { + mutex_lock(&fpc1020->lock); + rc = vreg_setup(fpc1020, "fp_vdd_vreg", true); + mutex_unlock(&fpc1020->lock); + dev_err(dev, "enable fp_vdd_vreg!, rc = %d\n", rc); + } else if (!strncmp(buf, "d", strlen("d"))) { + mutex_lock(&fpc1020->lock); + rc = vreg_setup(fpc1020, "fp_vdd_vreg", false); + mutex_unlock(&fpc1020->lock); + dev_err(dev, "disable fp_vdd_vreg!, rc = %d\n", rc); + } else { + dev_err(dev, "operation disable!\n"); + rc = 1; + } + + return rc ? rc : count; +} +static DEVICE_ATTR(regulator_enable, S_IWUSR, NULL, regulator_enable_set); + +static int hw_reset(struct fpc1020_data *fpc1020) +{ + int irq_gpio; + struct device *dev = fpc1020->dev; + int rc = select_pin_ctl(fpc1020, "fpc1020_reset_active"); + + if (rc) + goto exit; + usleep_range(RESET_HIGH_SLEEP1_MIN_US, RESET_HIGH_SLEEP1_MAX_US); + + rc = select_pin_ctl(fpc1020, "fpc1020_reset_reset"); + if (rc) + goto exit; + usleep_range(RESET_LOW_SLEEP_MIN_US, RESET_LOW_SLEEP_MAX_US); + + rc = select_pin_ctl(fpc1020, "fpc1020_reset_active"); + if (rc) + goto exit; + usleep_range(RESET_HIGH_SLEEP2_MIN_US, RESET_HIGH_SLEEP2_MAX_US); + + irq_gpio = gpio_get_value(fpc1020->irq_gpio); + dev_info(dev, "IRQ after reset %d\n", irq_gpio); + +exit: + return rc; +} + +static ssize_t hw_reset_set(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc; + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + + if (!strncmp(buf, "reset", strlen("reset"))) { + mutex_lock(&fpc1020->lock); + rc = hw_reset(fpc1020); + mutex_unlock(&fpc1020->lock); + } else { + return -EINVAL; + } + + return rc ? rc : count; +} +static DEVICE_ATTR(hw_reset, S_IWUSR, NULL, hw_reset_set); + +/** + * Will setup GPIOs, and regulators to correctly initialize the touch sensor to + * be ready for work. + * + * In the correct order according to the sensor spec this function will + * enable/disable regulators, and reset line, all to set the sensor in a + * correct power on or off state "electrical" wise. + * + * @see device_prepare_set + * @note This function will not send any commands to the sensor it will only + * control it "electrically". + */ +static int device_prepare(struct fpc1020_data *fpc1020, bool enable) +{ + int rc; + struct device *dev = fpc1020->dev; + + mutex_lock(&fpc1020->lock); + if (enable && !fpc1020->prepared) { + /* + rc = select_pin_ctl(fpc1020, "fpc1020_irq_active"); + if (rc) { + pr_err("irq gpio set active failed\n"); + goto exit; + } + */ + rc = fpc1020_request_named_gpio(fpc1020, "fpc,gpio_irq", + &fpc1020->irq_gpio); + if (rc) { + pr_err("irq gpio request failed\n"); + goto exit; + } + /* + rc = fpc1020_request_named_gpio(fpc1020, "fpc,gpio_rst", + &fpc1020->rst_gpio); + if (rc) { + pr_err("reset gpio request failed\n"); + goto irq_gpio_exit; + } + */ + rc = devm_request_threaded_irq(dev, + gpio_to_irq(fpc1020->irq_gpio), + NULL, fpc1020_irq_handler, + fpc1020->irqf, dev_name(dev), + fpc1020); + if (rc) { + pr_err("could not request irq %d\n", + gpio_to_irq(fpc1020->irq_gpio)); + goto rst_gpio_exit; + } + + dev_dbg(dev, "requested irq %d\n", + gpio_to_irq(fpc1020->irq_gpio)); + + /* Request that the interrupt should be wakeable */ + enable_irq_wake(gpio_to_irq(fpc1020->irq_gpio)); + select_pin_ctl(fpc1020, "fpc1020_reset_reset"); +#if 0 + rc = vreg_setup(fpc1020, "vcc_spi", true); + if (rc) + goto exit; + + rc = vreg_setup(fpc1020, "vdd_io", true); + if (rc) + goto exit_1; +#endif + rc = vreg_setup(fpc1020, "vdd_ana", true); + if (rc) + goto free_irq_exit; + +#ifdef CONFIG_FINGERPRINT_FP_VREG_CONTROL + dev_err(dev, "fp_vdd_reg enabling...\n"); + rc = vreg_setup(fpc1020, "fp_vdd_vreg", true); + if (rc) { + pr_err("fp_vdd_vreg config failed, rc = %d\n", rc); + goto free_irq_exit; + } + dev_err(dev, "fp_vdd_reg enabled success\n"); +#endif + + usleep_range(PWR_ON_SLEEP_MIN_US, PWR_ON_SLEEP_MAX_US); + + /* As we can't control chip select here the other part of the + * sensor driver eg. the TEE driver needs to do a _SOFT_ reset + * on the sensor after power up to be sure that the sensor is + * in a good state after power up. Okeyed by ASIC. */ + + (void)select_pin_ctl(fpc1020, "fpc1020_reset_active"); + hw_reset(fpc1020); + fpc1020->prepared = true; + } else if (!enable && fpc1020->prepared) { + rc = 0; + (void)select_pin_ctl(fpc1020, "fpc1020_reset_reset"); + + usleep_range(PWR_ON_SLEEP_MIN_US, PWR_ON_SLEEP_MAX_US); + + (void)vreg_setup(fpc1020, "vdd_ana", false); +#if 0 +exit_2: + (void)vreg_setup(fpc1020, "vdd_io", false); +exit_1: + (void)vreg_setup(fpc1020, "vcc_spi", false); +#endif +free_irq_exit: + disable_irq(gpio_to_irq(fpc1020->irq_gpio)); + devm_free_irq(dev, gpio_to_irq(fpc1020->irq_gpio), fpc1020); +rst_gpio_exit: + /* + devm_gpio_free(dev, fpc1020->rst_gpio); + */ + devm_gpio_free(dev, fpc1020->irq_gpio); +exit: + fpc1020->prepared = false; + } else { + rc = 0; + } + mutex_unlock(&fpc1020->lock); + + return rc; +} + +/** + * sysfs node to enable/disable (power up/power down) the touch sensor + * + * @see device_prepare + */ +static ssize_t device_prepare_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc; + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + + if (!strncmp(buf, "enable", strlen("enable"))) { + rc = device_prepare(fpc1020, true); + } else if (!strncmp(buf, "disable", strlen("disable"))) { + rc = device_prepare(fpc1020, false); + } else { + return -EINVAL; + } + + return rc ? rc : count; +} +static DEVICE_ATTR(device_prepare, S_IWUSR, NULL, device_prepare_set); + +/** + * sysfs node for controlling whether the driver is allowed + * to wake up the platform on interrupt. + */ +static ssize_t wakeup_enable_set(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + ssize_t ret = count; + + mutex_lock(&fpc1020->lock); + /* + if (!strncmp(buf, "enable", strlen("enable"))) + atomic_set(&fpc1020->wakeup_enabled, 1); + else if (!strncmp(buf, "disable", strlen("disable"))) + atomic_set(&fpc1020->wakeup_enabled, 0); + else + ret = -EINVAL; + */ + mutex_unlock(&fpc1020->lock); + + return ret; +} +static DEVICE_ATTR(wakeup_enable, S_IWUSR, NULL, wakeup_enable_set); + +/** + * sysf node to check the interrupt status of the sensor, the interrupt + * handler should perform sysf_notify to allow userland to poll the node. + */ +static ssize_t irq_get(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + int irq = gpio_get_value(fpc1020->irq_gpio); + + return scnprintf(buf, PAGE_SIZE, "%i\n", irq); +} + +/** + * writing to the irq node will just drop a printk message + * and return success, used for latency measurement. + */ +static ssize_t irq_ack(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + + dev_dbg(fpc1020->dev, "%s\n", __func__); + + return count; +} +static DEVICE_ATTR(irq, S_IRUSR | S_IWUSR, irq_get, irq_ack); + +static ssize_t fingerdown_wait_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + + dev_dbg(fpc1020->dev, "%s\n", __func__); + if (!strncmp(buf, "enable", strlen("enable")) && fpc1020->prepared) + fpc1020->wait_finger_down = true; + else if (!strncmp(buf, "disable", strlen("disable")) && + fpc1020->prepared) + fpc1020->wait_finger_down = false; + else + return -EINVAL; + + return count; +} +static DEVICE_ATTR(fingerdown_wait, S_IWUSR, NULL, fingerdown_wait_set); + +static ssize_t vendor_update(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc; + return rc ? rc : count; +} +static DEVICE_ATTR(vendor, S_IWUSR, NULL, vendor_update); + +static ssize_t irq_enable_set(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc = 0; + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + + if (!strncmp(buf, "1", strlen("1"))) { + mutex_lock(&fpc1020->lock); + enable_irq(gpio_to_irq(fpc1020->irq_gpio)); + mutex_unlock(&fpc1020->lock); + pr_debug("fpc enable irq\n"); + } else if (!strncmp(buf, "0", strlen("0"))) { + mutex_lock(&fpc1020->lock); + disable_irq(gpio_to_irq(fpc1020->irq_gpio)); + mutex_unlock(&fpc1020->lock); + pr_debug("fpc disable irq\n"); + } + + return rc ? rc : count; +} +static DEVICE_ATTR(irq_enable, S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP, NULL, + irq_enable_set); + +static ssize_t screen_status_get(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int retval = 0; + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + + retval = (fpc1020->fb_black == true) ? 0 : 1; + + return scnprintf(buf, PAGE_SIZE, "%d\n", retval); +} +static DEVICE_ATTR(screen_status, S_IRUSR | S_IRGRP, screen_status_get, NULL); + +static ssize_t vreg_op_cnt_set(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + char value[64] = { 0 }; + + snprintf(value, sizeof(value), "%s", buf); + return count; +} +static DEVICE_ATTR(vreg_op_cnt, S_IWUSR, NULL, vreg_op_cnt_set); + +static struct attribute *attributes[] = { + &dev_attr_pinctl_set.attr, + &dev_attr_device_prepare.attr, + &dev_attr_regulator_enable.attr, + &dev_attr_hw_reset.attr, + &dev_attr_wakeup_enable.attr, + &dev_attr_clk_enable.attr, + &dev_attr_irq_enable.attr, + &dev_attr_irq.attr, + &dev_attr_screen_status.attr, + &dev_attr_fingerdown_wait.attr, + &dev_attr_vendor.attr, + &dev_attr_vreg_op_cnt.attr, + NULL, +}; + +static const struct attribute_group attribute_group = { + .attrs = attributes, +}; + +static void notification_work(struct work_struct *work) +{ + pr_debug("%s: unblank\n", __func__); + dsi_bridge_interface_enable(FP_UNLOCK_REJECTION_TIMEOUT); +} + +static irqreturn_t fpc1020_irq_handler(int irq, void *handle) +{ + struct fpc1020_data *fpc1020 = handle; + + dev_dbg(fpc1020->dev, "%s\n", __func__); + + if (atomic_read(&fpc1020->wakeup_enabled)) { + __pm_wakeup_event(&fpc1020->ttw_wl, FPC_TTW_HOLD_TIME); + } + + sysfs_notify(&fpc1020->dev->kobj, NULL, dev_attr_irq.attr.name); + if (fpc1020->wait_finger_down && fpc1020->fb_black && + fpc1020->prepared) { + pr_debug("%s enter\n", __func__); + fpc1020->wait_finger_down = false; + schedule_work(&fpc1020->work); + } + + return IRQ_HANDLED; +} + +static int fpc1020_request_named_gpio(struct fpc1020_data *fpc1020, + const char *label, int *gpio) +{ + struct device *dev = fpc1020->dev; + struct device_node *np = dev->of_node; + int rc = of_get_named_gpio(np, label, 0); + + if (rc < 0) { + dev_err(dev, "failed to get '%s'\n", label); + return rc; + } + *gpio = rc; + + rc = devm_gpio_request(dev, *gpio, label); + if (rc) { + dev_err(dev, "failed to request gpio %d\n", *gpio); + return rc; + } + dev_dbg(dev, "%s %d\n", label, *gpio); + + return 0; +} + +static int fpc_fb_notif_callback(struct notifier_block *nb, unsigned long val, + void *data) +{ + struct fpc1020_data *fpc1020 = + container_of(nb, struct fpc1020_data, fb_notifier); + struct fb_event *evdata = data; + unsigned int blank; + + if (!fpc1020) + return 0; + + if (val != DRM_EVENT_BLANK || fpc1020->prepared == false) + return 0; + + pr_debug("[info] %s value = %d\n", __func__, (int)val); + + if (evdata && evdata->data && val == DRM_EVENT_BLANK) { + blank = *(int *)(evdata->data); + switch (blank) { + case DRM_BLANK_POWERDOWN: + fpc1020->fb_black = true; +#ifdef CONFIG_FINGERPRINT_FPC_SCREEN_NOTIFY + __pm_wakeup_event(&fpc1020->screen_wl, + FPC_SCREEN_HOLD_TIME); + sysfs_notify(&fpc1020->dev->kobj, NULL, + dev_attr_screen_status.attr.name); +#endif + break; + case DRM_BLANK_UNBLANK: + fpc1020->fb_black = false; +#ifdef CONFIG_FINGERPRINT_FPC_SCREEN_NOTIFY + __pm_wakeup_event(&fpc1020->screen_wl, + FPC_SCREEN_HOLD_TIME); + sysfs_notify(&fpc1020->dev->kobj, NULL, + dev_attr_screen_status.attr.name); +#endif + break; + default: + pr_debug("%s defalut\n", __func__); + break; + } + } + return NOTIFY_OK; +} + +static struct notifier_block fpc_notif_block = { + .notifier_call = fpc_fb_notif_callback, +}; + +static int fpc1020_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int rc = 0; + size_t i; + + struct device_node *np = dev->of_node; + struct fpc1020_data *fpc1020 = + devm_kzalloc(dev, sizeof(*fpc1020), GFP_KERNEL); + + if (!fpc1020) { + dev_err(dev, + "failed to allocate memory for struct fpc1020_data\n"); + rc = -ENOMEM; + goto exit; + } + + fpc1020->dev = dev; + platform_set_drvdata(pdev, fpc1020); + + if (!np) { + dev_err(dev, "no of node found\n"); + rc = -EINVAL; + goto exit; + } + + fpc1020->fingerprint_pinctrl = devm_pinctrl_get(dev); + if (IS_ERR(fpc1020->fingerprint_pinctrl)) { + if (PTR_ERR(fpc1020->fingerprint_pinctrl) == -EPROBE_DEFER) { + dev_info(dev, "pinctrl not ready\n"); + rc = -EPROBE_DEFER; + goto exit; + } + dev_err(dev, "Target does not use pinctrl\n"); + fpc1020->fingerprint_pinctrl = NULL; + rc = -EINVAL; + goto exit; + } + + for (i = 0; i < ARRAY_SIZE(fpc1020->pinctrl_state); i++) { + const char *n = pctl_names[i]; + struct pinctrl_state *state = + pinctrl_lookup_state(fpc1020->fingerprint_pinctrl, n); + if (IS_ERR(state)) { + dev_err(dev, "cannot find '%s'\n", n); + rc = -EINVAL; + goto exit; + } + dev_info(dev, "found pin control %s\n", n); + fpc1020->pinctrl_state[i] = state; + } + + atomic_set(&fpc1020->wakeup_enabled, 1); + + fpc1020->irqf = IRQF_TRIGGER_RISING | IRQF_ONESHOT | IRQF_NO_SUSPEND; + /* + if (of_property_read_bool(dev->of_node, "fpc,enable-wakeup")) { + fpc1020->irqf |= IRQF_NO_SUSPEND; + device_init_wakeup(dev, 1); + } + */ + mutex_init(&fpc1020->lock); + + wakeup_source_init(&fpc1020->ttw_wl, "fpc_ttw_wl"); + wakeup_source_init(&fpc1020->screen_wl, "fpc_screen_wl"); + + rc = sysfs_create_group(&dev->kobj, &attribute_group); + if (rc) { + dev_err(dev, "could not create sysfs\n"); + goto exit; + } + + if (of_property_read_bool(dev->of_node, "fpc,enable-on-boot")) { + dev_info(dev, "Enabling hardware\n"); + (void)device_prepare(fpc1020, true); + } + + fpc1020->fb_black = false; + fpc1020->wait_finger_down = false; + INIT_WORK(&fpc1020->work, notification_work); + fpc1020->fb_notifier = fpc_notif_block; + drm_register_client(&fpc1020->fb_notifier); + + dev_info(dev, "%s: ok\n", __func__); + +exit: + return rc; +} + +static int fpc1020_remove(struct platform_device *pdev) +{ + struct fpc1020_data *fpc1020 = platform_get_drvdata(pdev); + + drm_unregister_client(&fpc1020->fb_notifier); + sysfs_remove_group(&pdev->dev.kobj, &attribute_group); + mutex_destroy(&fpc1020->lock); + wakeup_source_trash(&fpc1020->ttw_wl); + wakeup_source_trash(&fpc1020->screen_wl); + (void)vreg_setup(fpc1020, "vdd_ana", false); + /* + (void)vreg_setup(fpc1020, "vdd_io", false); + (void)vreg_setup(fpc1020, "vcc_spi", false); + */ + dev_info(&pdev->dev, "%s\n", __func__); + + return 0; +} + +static struct of_device_id fpc1020_of_match[] = { + { + .compatible = "fpc,fpc1020", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, fpc1020_of_match); + +static struct platform_driver fpc1020_driver = { + .driver = { + .name = "fpc1020", + .owner = THIS_MODULE, + .of_match_table = fpc1020_of_match, + }, + .probe = fpc1020_probe, + .remove = fpc1020_remove, +}; + +static int __init fpc1020_init(void) +{ + int rc = platform_driver_register(&fpc1020_driver); + + if (!rc) + pr_info("%s OK\n", __func__); + else + pr_err("%s %d\n", __func__, rc); + + return rc; +} + +static void __exit fpc1020_exit(void) +{ + pr_info("%s\n", __func__); + platform_driver_unregister(&fpc1020_driver); +} + +module_init(fpc1020_init); +module_exit(fpc1020_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Aleksej Makarov"); +MODULE_AUTHOR("Henrik Tillman "); +MODULE_DESCRIPTION("FPC1020 Fingerprint sensor device driver."); diff --git a/drivers/input/fingerprint/goodix_ta/Kconfig b/drivers/input/fingerprint/goodix_ta/Kconfig new file mode 100644 index 000000000000..34b155459ad3 --- /dev/null +++ b/drivers/input/fingerprint/goodix_ta/Kconfig @@ -0,0 +1,10 @@ +config FINGERPRINT_GOODIX_TA + tristate "Finger print card goodix" + depends on INPUT_FINGERPRINT + help + Say Y here to enable support for retrieving self-test reports. + + If unsure, say N. + + To compile this driver as a module, choose M here. + diff --git a/drivers/input/fingerprint/goodix_ta/Makefile b/drivers/input/fingerprint/goodix_ta/Makefile new file mode 100644 index 000000000000..43929c138f64 --- /dev/null +++ b/drivers/input/fingerprint/goodix_ta/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_FINGERPRINT_GOODIX_TA) += gf_spi.o platform.o netlink.o diff --git a/drivers/input/fingerprint/goodix_ta/gf_spi.c b/drivers/input/fingerprint/goodix_ta/gf_spi.c new file mode 100644 index 000000000000..1812a5ef5de6 --- /dev/null +++ b/drivers/input/fingerprint/goodix_ta/gf_spi.c @@ -0,0 +1,1077 @@ +/* + * TEE driver for goodix fingerprint sensor + * Copyright (C) 2016 Goodix + * Copyright (C) 2019 XiaoMi, Inc. + * + * 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. + */ +#define DEBUG +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#define GOODIX_DRM_INTERFACE_WA + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef GOODIX_DRM_INTERFACE_WA +#include +#endif + +#include "gf_spi.h" + +#if defined(USE_SPI_BUS) +#include +#include +#elif defined(USE_PLATFORM_BUS) +#include +#endif + +#define VER_MAJOR 1 +#define VER_MINOR 2 +#define PATCH_LEVEL 1 + +#define WAKELOCK_HOLD_TIME 2000 /* in ms */ +#define FP_UNLOCK_REJECTION_TIMEOUT (WAKELOCK_HOLD_TIME - 500) + +#define GF_SPIDEV_NAME "goodix,fingerprint" +/*device name after register in charater*/ +#define GF_DEV_NAME "goodix_fp" +#define GF_INPUT_NAME "uinput-goodix" /*"goodix_fp" */ + +#define CHRD_DRIVER_NAME "goodix_fp_spi" +#define CLASS_NAME "goodix_fp" + +#define N_SPI_MINORS 32 /* ... up to 256 */ + +static int SPIDEV_MAJOR; + +static DECLARE_BITMAP(minors, N_SPI_MINORS); +static LIST_HEAD(device_list); +static DEFINE_MUTEX(device_list_lock); +static struct wakeup_source fp_wakelock; +static struct gf_dev gf; + +struct gf_key_map maps[] = { + { EV_KEY, GF_KEY_INPUT_HOME }, + { EV_KEY, GF_KEY_INPUT_MENU }, + { EV_KEY, GF_KEY_INPUT_BACK }, + { EV_KEY, GF_KEY_INPUT_POWER }, +#if defined(SUPPORT_NAV_EVENT) + { EV_KEY, GF_NAV_INPUT_UP }, + { EV_KEY, GF_NAV_INPUT_DOWN }, + { EV_KEY, GF_NAV_INPUT_RIGHT }, + { EV_KEY, GF_NAV_INPUT_LEFT }, + { EV_KEY, GF_KEY_INPUT_CAMERA }, + { EV_KEY, GF_NAV_INPUT_CLICK }, + { EV_KEY, GF_NAV_INPUT_DOUBLE_CLICK }, + { EV_KEY, GF_NAV_INPUT_LONG_PRESS }, + { EV_KEY, GF_NAV_INPUT_HEAVY }, +#endif +}; + +static void gf_enable_irq(struct gf_dev *gf_dev) +{ + if (gf_dev->irq_enabled) { + pr_warn("IRQ has been enabled.\n"); + } else { + enable_irq(gf_dev->irq); + gf_dev->irq_enabled = 1; + } +} + +static void gf_disable_irq(struct gf_dev *gf_dev) +{ + if (gf_dev->irq_enabled) { + gf_dev->irq_enabled = 0; + disable_irq(gf_dev->irq); + } else { + pr_warn("IRQ has been disabled.\n"); + } +} + +#ifdef AP_CONTROL_CLK +static long spi_clk_max_rate(struct clk *clk, unsigned long rate) +{ + long lowest_available, nearest_low, step_size, cur; + long step_direction = -1; + long guess = rate; + int max_steps = 10; + cur = clk_round_rate(clk, rate); + + if (cur == rate) { + return rate; + } + + /* if we got here then: cur > rate */ + lowest_available = clk_round_rate(clk, 0); + + if (lowest_available > rate) { + return -EINVAL; + } + + step_size = (rate - lowest_available) >> 1; + nearest_low = lowest_available; + + while (max_steps-- && step_size) { + guess += step_size * step_direction; + cur = clk_round_rate(clk, guess); + + if ((cur < rate) && (cur > nearest_low)) { + nearest_low = cur; + } + + /* + * if we stepped too far, then start stepping in the other + * direction with half the step size + */ + if (((cur > rate) && (step_direction > 0)) || + ((cur < rate) && (step_direction < 0))) { + step_direction = -step_direction; + step_size >>= 1; + } + } + + return nearest_low; +} + +static void spi_clock_set(struct gf_dev *gf_dev, int speed) +{ + long rate; + int rc; + rate = spi_clk_max_rate(gf_dev->core_clk, speed); + + if (rate < 0) { + pr_debug("%s: no match found for requested clock frequency:%d", + __func__, speed); + return; + } + + rc = clk_set_rate(gf_dev->core_clk, rate); +} + +static int gfspi_ioctl_clk_init(struct gf_dev *data) +{ + pr_debug("%s: enter\n", __func__); + data->clk_enabled = 0; + data->core_clk = clk_get(&data->spi->dev, "core_clk"); + + if (IS_ERR_OR_NULL(data->core_clk)) { + pr_err("%s: fail to get core_clk\n", __func__); + return -EPERM; + } + + data->iface_clk = clk_get(&data->spi->dev, "iface_clk"); + + if (IS_ERR_OR_NULL(data->iface_clk)) { + pr_err("%s: fail to get iface_clk\n", __func__); + clk_put(data->core_clk); + data->core_clk = NULL; + return -ENOENT; + } + + return 0; +} + +static int gfspi_ioctl_clk_enable(struct gf_dev *data) +{ + int err; + pr_debug("%s: enter\n", __func__); + + if (data->clk_enabled) { + return 0; + } + + err = clk_prepare_enable(data->core_clk); + + if (err) { + pr_err("%s: fail to enable core_clk\n", __func__); + return -EPERM; + } + + err = clk_prepare_enable(data->iface_clk); + + if (err) { + pr_err("%s: fail to enable iface_clk\n", __func__); + clk_disable_unprepare(data->core_clk); + return -ENOENT; + } + + data->clk_enabled = 1; + return 0; +} + +static int gfspi_ioctl_clk_disable(struct gf_dev *data) +{ + pr_debug("%s: enter\n", __func__); + + if (!data->clk_enabled) { + return 0; + } + + clk_disable_unprepare(data->core_clk); + clk_disable_unprepare(data->iface_clk); + data->clk_enabled = 0; + return 0; +} + +static int gfspi_ioctl_clk_uninit(struct gf_dev *data) +{ + pr_debug("%s: enter\n", __func__); + + if (data->clk_enabled) { + gfspi_ioctl_clk_disable(data); + } + + if (!IS_ERR_OR_NULL(data->core_clk)) { + clk_put(data->core_clk); + data->core_clk = NULL; + } + + if (!IS_ERR_OR_NULL(data->iface_clk)) { + clk_put(data->iface_clk); + data->iface_clk = NULL; + } + + return 0; +} +#endif + +static void nav_event_input(struct gf_dev *gf_dev, gf_nav_event_t nav_event) +{ + uint32_t nav_input = 0; + + switch (nav_event) { + case GF_NAV_FINGER_DOWN: + pr_debug("%s nav finger down\n", __func__); + break; + + case GF_NAV_FINGER_UP: + pr_debug("%s nav finger up\n", __func__); + break; + + case GF_NAV_DOWN: + nav_input = GF_NAV_INPUT_DOWN; + pr_debug("%s nav down\n", __func__); + break; + + case GF_NAV_UP: + nav_input = GF_NAV_INPUT_UP; + pr_debug("%s nav up\n", __func__); + break; + + case GF_NAV_LEFT: + nav_input = GF_NAV_INPUT_LEFT; + pr_debug("%s nav left\n", __func__); + break; + + case GF_NAV_RIGHT: + nav_input = GF_NAV_INPUT_RIGHT; + pr_debug("%s nav right\n", __func__); + break; + + case GF_NAV_CLICK: + nav_input = GF_NAV_INPUT_CLICK; + pr_debug("%s nav click\n", __func__); + break; + + case GF_NAV_HEAVY: + nav_input = GF_NAV_INPUT_HEAVY; + pr_debug("%s nav heavy\n", __func__); + break; + + case GF_NAV_LONG_PRESS: + nav_input = GF_NAV_INPUT_LONG_PRESS; + pr_debug("%s nav long press\n", __func__); + break; + + case GF_NAV_DOUBLE_CLICK: + nav_input = GF_NAV_INPUT_DOUBLE_CLICK; + pr_debug("%s nav double click\n", __func__); + break; + + default: + pr_warn("%s unknown nav event: %d\n", __func__, nav_event); + break; + } + + if ((nav_event != GF_NAV_FINGER_DOWN) && + (nav_event != GF_NAV_FINGER_UP)) { + input_report_key(gf_dev->input, nav_input, 1); + input_sync(gf_dev->input); + input_report_key(gf_dev->input, nav_input, 0); + input_sync(gf_dev->input); + } +} + +static void gf_kernel_key_input(struct gf_dev *gf_dev, struct gf_key *gf_key) +{ + uint32_t key_input = 0; + + if (GF_KEY_HOME == gf_key->key) { + key_input = GF_KEY_INPUT_HOME; + } else if (GF_KEY_POWER == gf_key->key) { + key_input = GF_KEY_INPUT_POWER; + } else if (GF_KEY_CAMERA == gf_key->key) { + key_input = GF_KEY_INPUT_CAMERA; + } else { + /* add special key define */ + key_input = gf_key->key; + } + + pr_debug("%s: received key event[%d], key=%d, value=%d\n", __func__, + key_input, gf_key->key, gf_key->value); + + if ((GF_KEY_POWER == gf_key->key || GF_KEY_CAMERA == gf_key->key) && + (gf_key->value == 1)) { + input_report_key(gf_dev->input, key_input, 1); + input_sync(gf_dev->input); + input_report_key(gf_dev->input, key_input, 0); + input_sync(gf_dev->input); + } + + if (GF_KEY_HOME == gf_key->key) { + input_report_key(gf_dev->input, key_input, gf_key->value); + input_sync(gf_dev->input); + } +} + +static long gf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct gf_dev *gf_dev = &gf; + struct gf_key gf_key; +#if defined(SUPPORT_NAV_EVENT) + gf_nav_event_t nav_event = GF_NAV_NONE; +#endif + int retval = 0; + u8 netlink_route = NETLINK_TEST; + struct gf_ioc_chip_info info; + + if (_IOC_TYPE(cmd) != GF_IOC_MAGIC) { + return -ENODEV; + } + + if (_IOC_DIR(cmd) & _IOC_READ) { + retval = !access_ok(VERIFY_WRITE, (void __user *)arg, + _IOC_SIZE(cmd)); + } else if (_IOC_DIR(cmd) & _IOC_WRITE) { + retval = !access_ok(VERIFY_READ, (void __user *)arg, + _IOC_SIZE(cmd)); + } + + if (retval) { + return -EFAULT; + } + + if (gf_dev->device_available == 0) { + if ((cmd == GF_IOC_ENABLE_POWER) || + (cmd == GF_IOC_DISABLE_POWER)) { + pr_debug("power cmd\n"); + } else { + pr_debug( + "get cmd %d, but sensor is power off currently.\n", + _IOC_NR(cmd)); + return -ENODEV; + } + } + + switch (cmd) { + case GF_IOC_INIT: + pr_debug("%s GF_IOC_INIT\n", __func__); + + if (copy_to_user((void __user *)arg, (void *)&netlink_route, + sizeof(u8))) { + retval = -EFAULT; + break; + } + + break; + + case GF_IOC_EXIT: + pr_debug("%s GF_IOC_EXIT\n", __func__); + break; + + case GF_IOC_DISABLE_IRQ: + pr_debug("%s GF_IOC_DISABEL_IRQ\n", __func__); + gf_disable_irq(gf_dev); + break; + + case GF_IOC_ENABLE_IRQ: + pr_debug("%s GF_IOC_ENABLE_IRQ\n", __func__); + gf_enable_irq(gf_dev); + break; + + case GF_IOC_RESET: + pr_debug("%s GF_IOC_RESET.\n", __func__); + gf_hw_reset(gf_dev, 3); + break; + + case GF_IOC_INPUT_KEY_EVENT: + if (copy_from_user(&gf_key, (struct gf_key *)arg, + sizeof(struct gf_key))) { + pr_debug( + "Failed to copy input key event from user to kernel\n"); + retval = -EFAULT; + break; + } + + gf_kernel_key_input(gf_dev, &gf_key); + break; +#if defined(SUPPORT_NAV_EVENT) + + case GF_IOC_NAV_EVENT: + pr_debug("%s GF_IOC_NAV_EVENT\n", __func__); + + if (copy_from_user(&nav_event, (gf_nav_event_t *)arg, + sizeof(gf_nav_event_t))) { + pr_debug( + "Failed to copy nav event from user to kernel\n"); + retval = -EFAULT; + break; + } + + nav_event_input(gf_dev, nav_event); + break; +#endif + + case GF_IOC_ENABLE_SPI_CLK: +#ifdef AP_CONTROL_CLK + gfspi_ioctl_clk_enable(gf_dev); +#endif + break; + + case GF_IOC_DISABLE_SPI_CLK: +#ifdef AP_CONTROL_CLK + gfspi_ioctl_clk_disable(gf_dev); +#endif + break; + + case GF_IOC_ENABLE_POWER: + pr_debug("%s GF_IOC_ENABLE_POWER\n", __func__); + + if (gf_dev->device_available == 1) { + pr_debug("Sensor has already powered-on.\n"); + } else { + gf_power_on(gf_dev); + } + + gf_dev->device_available = 1; + break; + + case GF_IOC_DISABLE_POWER: + pr_debug("%s GF_IOC_DISABLE_POWER\n", __func__); + + if (gf_dev->device_available == 0) { + pr_debug("Sensor has already powered-off.\n"); + } else { + gf_power_off(gf_dev); + } + + gf_dev->device_available = 0; + break; + + case GF_IOC_ENTER_SLEEP_MODE: + pr_debug("%s GF_IOC_ENTER_SLEEP_MODE\n", __func__); + break; + + case GF_IOC_GET_FW_INFO: + pr_debug("%s GF_IOC_GET_FW_INFO\n", __func__); + break; + + case GF_IOC_REMOVE: + pr_debug("%s GF_IOC_REMOVE\n", __func__); + break; + + case GF_IOC_CHIP_INFO: + pr_debug("%s GF_IOC_CHIP_INFO\n", __func__); + + if (copy_from_user(&info, (struct gf_ioc_chip_info *)arg, + sizeof(struct gf_ioc_chip_info))) { + retval = -EFAULT; + break; + } + + pr_debug("vendor_id : 0x%x\n", info.vendor_id); + pr_debug("mode : 0x%x\n", info.mode); + pr_debug("operation: 0x%x\n", info.operation); + break; + + default: + pr_warn("unsupport cmd:0x%x\n", cmd); + break; + } + + return retval; +} + +#ifdef CONFIG_COMPAT +static long gf_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + return gf_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); +} +#endif /*CONFIG_COMPAT*/ + +#ifndef GOODIX_DRM_INTERFACE_WA +static void notification_work(struct work_struct *work) +{ + pr_debug("%s unblank\n", __func__); + dsi_bridge_interface_enable(FP_UNLOCK_REJECTION_TIMEOUT); +} +#endif + +static irqreturn_t gf_irq(int irq, void *handle) +{ + struct gf_dev *gf_dev = &gf; +#if defined(GF_NETLINK_ENABLE) + char temp[4] = { 0x0 }; + uint32_t key_input = 0; + temp[0] = GF_NET_EVENT_IRQ; + pr_debug("%s enter\n", __func__); + __pm_wakeup_event(&fp_wakelock, WAKELOCK_HOLD_TIME); + sendnlmsg(temp); + + if ((gf_dev->wait_finger_down == true) && + (gf_dev->device_available == 1) && (gf_dev->fb_black == 1)) { + key_input = KEY_RIGHT; + input_report_key(gf_dev->input, key_input, 1); + input_sync(gf_dev->input); + input_report_key(gf_dev->input, key_input, 0); + input_sync(gf_dev->input); + gf_dev->wait_finger_down = false; + schedule_work(&gf_dev->work); + } + +#elif defined(GF_FASYNC) + struct gf_dev *gf_dev = &gf; + + if (gf_dev->async) { + kill_fasync(&gf_dev->async, SIGIO, POLL_IN); + } + +#endif + return IRQ_HANDLED; +} + +static int gf_open(struct inode *inode, struct file *filp) +{ + struct gf_dev *gf_dev; + int status = -ENXIO; + int rc = 0; + int err = 0; + mutex_lock(&device_list_lock); + list_for_each_entry(gf_dev, &device_list, device_entry) { + if (gf_dev->devt == inode->i_rdev) { + pr_debug("Found\n"); + status = 0; + break; + } + } +#ifdef CONFIG_FINGERPRINT_FP_VREG_CONTROL + pr_info("Try to enable fp_vdd_vreg\n"); + gf_dev->vreg = regulator_get(&gf_dev->spi->dev, "fp_vdd_vreg"); + + if (gf_dev->vreg == NULL) { + dev_err(&gf_dev->spi->dev, + "fp_vdd_vreg regulator get failed!\n"); + mutex_unlock(&device_list_lock); + return -EPERM; + } + + if (regulator_is_enabled(gf_dev->vreg)) { + pr_info("fp_vdd_vreg is already enabled!\n"); + } else { + rc = regulator_enable(gf_dev->vreg); + + if (rc) { + dev_err(&gf_dev->spi->dev, + "error enabling fp_vdd_vreg!\n"); + regulator_put(gf_dev->vreg); + gf_dev->vreg = NULL; + mutex_unlock(&device_list_lock); + return -EPERM; + } + } + + pr_info("fp_vdd_vreg is enabled!\n"); +#endif + + if (status == 0) { + rc = gpio_request(gf_dev->reset_gpio, "goodix_reset"); + + if (rc) { + dev_err(&gf_dev->spi->dev, + "Failed to request RESET GPIO. rc = %d\n", rc); + mutex_unlock(&device_list_lock); + err = -EPERM; + goto open_error1; + } + + gpio_direction_output(gf_dev->reset_gpio, 0); + rc = gpio_request(gf_dev->irq_gpio, "goodix_irq"); + + if (rc) { + dev_err(&gf_dev->spi->dev, + "Failed to request IRQ GPIO. rc = %d\n", rc); + mutex_unlock(&device_list_lock); + err = -EPERM; + goto open_error2; + } + + gpio_direction_input(gf_dev->irq_gpio); + rc = request_threaded_irq(gf_dev->irq, NULL, gf_irq, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "gf", gf_dev); + + if (!rc) { + enable_irq_wake(gf_dev->irq); + gf_dev->irq_enabled = 1; + gf_disable_irq(gf_dev); + } else { + err = -EPERM; + goto open_error3; + } + + gf_dev->users++; + filp->private_data = gf_dev; + nonseekable_open(inode, filp); + pr_debug("Succeed to open device. irq = %d\n", gf_dev->irq); + } else { + pr_debug("No device for minor %d\n", iminor(inode)); + } + + mutex_unlock(&device_list_lock); + return status; +open_error3: + gpio_free(gf_dev->irq_gpio); +open_error2: + gpio_free(gf_dev->reset_gpio); +open_error1: + return err; +} + +#ifdef GF_FASYNC +static int gf_fasync(int fd, struct file *filp, int mode) +{ + struct gf_dev *gf_dev = filp->private_data; + int ret; + ret = fasync_helper(fd, filp, mode, &gf_dev->async); + pr_debug("ret = %d\n", ret); + return ret; +} +#endif + +static int gf_release(struct inode *inode, struct file *filp) +{ + struct gf_dev *gf_dev; + int status = 0; + pr_debug("%s\n", __func__); + mutex_lock(&device_list_lock); + gf_dev = filp->private_data; + filp->private_data = NULL; + /* + *Disable fp_vdd_vreg regulator + */ +#ifdef CONFIG_FINGERPRINT_FP_VREG_CONTROL + pr_info("disable fp_vdd_vreg!\n"); + + if (regulator_is_enabled(gf_dev->vreg)) { + regulator_disable(gf_dev->vreg); + regulator_put(gf_dev->vreg); + gf_dev->vreg = NULL; + } + +#endif + gf_dev->users--; + + if (!gf_dev->users) { + pr_debug("disble_irq. irq = %d\n", gf_dev->irq); + gf_disable_irq(gf_dev); + /*power off the sensor*/ + gf_dev->device_available = 0; + free_irq(gf_dev->irq, gf_dev); + gpio_free(gf_dev->irq_gpio); + gpio_free(gf_dev->reset_gpio); + gf_power_off(gf_dev); + } + + mutex_unlock(&device_list_lock); + return status; +} + +static const struct file_operations gf_fops = { + .owner = THIS_MODULE, + /* REVISIT switch to aio primitives, so that userspace + * gets more complete API coverage. It'll simplify things + * too, except for the locking. + */ + .unlocked_ioctl = gf_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = gf_compat_ioctl, +#endif /*CONFIG_COMPAT*/ + .open = gf_open, + .release = gf_release, +#ifdef GF_FASYNC + .fasync = gf_fasync, +#endif +}; + +#ifndef GOODIX_DRM_INTERFACE_WA +static int goodix_fb_state_chg_callback(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct gf_dev *gf_dev; + struct fb_event *evdata = data; + unsigned int blank; + char temp[4] = { 0x0 }; + + if (val != DRM_EVENT_BLANK) { + return 0; + } + + pr_debug( + "[info] %s go to the goodix_fb_state_chg_callback value = %d\n", + __func__, (int)val); + gf_dev = container_of(nb, struct gf_dev, notifier); + + if (evdata && evdata->data && val == DRM_EVENT_BLANK && gf_dev) { + blank = *(int *)(evdata->data); + + switch (blank) { + case DRM_BLANK_POWERDOWN: + if (gf_dev->device_available == 1) { + gf_dev->fb_black = 1; + gf_dev->wait_finger_down = true; +#if defined(GF_NETLINK_ENABLE) + temp[0] = GF_NET_EVENT_FB_BLACK; + sendnlmsg(temp); +#elif defined(GF_FASYNC) + + if (gf_dev->async) { + kill_fasync(&gf_dev->async, SIGIO, + POLL_IN); + } + +#endif + } + + break; + + case DRM_BLANK_UNBLANK: + if (gf_dev->device_available == 1) { + gf_dev->fb_black = 0; +#if defined(GF_NETLINK_ENABLE) + temp[0] = GF_NET_EVENT_FB_UNBLACK; + sendnlmsg(temp); +#elif defined(GF_FASYNC) + + if (gf_dev->async) { + kill_fasync(&gf_dev->async, SIGIO, + POLL_IN); + } + +#endif + } + + break; + + default: + pr_debug("%s defalut\n", __func__); + break; + } + } + + return NOTIFY_OK; +} + +static struct notifier_block goodix_noti_block = { + .notifier_call = goodix_fb_state_chg_callback, +}; +#endif + +static struct class *gf_class; +#if defined(USE_SPI_BUS) +static int gf_probe(struct spi_device *spi) +#elif defined(USE_PLATFORM_BUS) +static int gf_probe(struct platform_device *pdev) +#endif +{ + struct gf_dev *gf_dev = &gf; + int status = -EINVAL; + unsigned long minor; + int i; + /* Initialize the driver data */ + INIT_LIST_HEAD(&gf_dev->device_entry); +#if defined(USE_SPI_BUS) + gf_dev->spi = spi; +#elif defined(USE_PLATFORM_BUS) + gf_dev->spi = pdev; +#endif + gf_dev->irq_gpio = -EINVAL; + gf_dev->reset_gpio = -EINVAL; + gf_dev->pwr_gpio = -EINVAL; + gf_dev->device_available = 0; + gf_dev->fb_black = 0; + gf_dev->wait_finger_down = false; +#ifndef GOODIX_DRM_INTERFACE_WA + INIT_WORK(&gf_dev->work, notification_work); +#endif + + if (gf_parse_dts(gf_dev)) { + goto error_hw; + } + + /* If we can allocate a minor number, hook up this device. + * Reusing minors is fine so long as udev or mdev is working. + */ + mutex_lock(&device_list_lock); + minor = find_first_zero_bit(minors, N_SPI_MINORS); + + if (minor < N_SPI_MINORS) { + struct device *dev; + gf_dev->devt = MKDEV(SPIDEV_MAJOR, minor); + dev = device_create(gf_class, &gf_dev->spi->dev, gf_dev->devt, + gf_dev, GF_DEV_NAME); + status = IS_ERR(dev) ? PTR_ERR(dev) : 0; + } else { + dev_dbg(&gf_dev->spi->dev, "no minor number available!\n"); + status = -ENODEV; + mutex_unlock(&device_list_lock); + goto error_hw; + } + + if (status == 0) { + set_bit(minor, minors); + list_add(&gf_dev->device_entry, &device_list); + } else { + gf_dev->devt = 0; + } + + mutex_unlock(&device_list_lock); + + if (status == 0) { + /*input device subsystem */ + gf_dev->input = input_allocate_device(); + + if (gf_dev->input == NULL) { + pr_err("%s, failed to allocate input device\n", + __func__); + status = -ENOMEM; + goto error_dev; + } + + for (i = 0; i < ARRAY_SIZE(maps); i++) { + input_set_capability(gf_dev->input, maps[i].type, + maps[i].code); + } + + gf_dev->input->name = GF_INPUT_NAME; + status = input_register_device(gf_dev->input); + + if (status) { + pr_err("failed to register input device\n"); + goto error_input; + } + } + +#ifdef AP_CONTROL_CLK + pr_debug("Get the clk resource.\n"); + + /* Enable spi clock */ + if (gfspi_ioctl_clk_init(gf_dev)) { + goto gfspi_probe_clk_init_failed; + } + + if (gfspi_ioctl_clk_enable(gf_dev)) { + goto gfspi_probe_clk_enable_failed; + } + + spi_clock_set(gf_dev, 1000000); +#endif +#ifndef GOODIX_DRM_INTERFACE_WA + gf_dev->notifier = goodix_noti_block; + drm_register_client(&gf_dev->notifier); +#endif + gf_dev->irq = gf_irq_num(gf_dev); + wakeup_source_init(&fp_wakelock, "fp_wakelock"); + pr_debug("version V%d.%d.%02d\n", VER_MAJOR, VER_MINOR, PATCH_LEVEL); + return status; +#ifdef AP_CONTROL_CLK +gfspi_probe_clk_enable_failed: + gfspi_ioctl_clk_uninit(gf_dev); +gfspi_probe_clk_init_failed: +#endif + input_unregister_device(gf_dev->input); +error_input: + + if (gf_dev->input != NULL) { + input_free_device(gf_dev->input); + } + +error_dev: + + if (gf_dev->devt != 0) { + pr_debug("Err: status = %d\n", status); + mutex_lock(&device_list_lock); + list_del(&gf_dev->device_entry); + device_destroy(gf_class, gf_dev->devt); + clear_bit(MINOR(gf_dev->devt), minors); + mutex_unlock(&device_list_lock); + } + +error_hw: + gf_cleanup(gf_dev); + gf_dev->device_available = 0; + return status; +} + +#if defined(USE_SPI_BUS) +static int gf_remove(struct spi_device *spi) +#elif defined(USE_PLATFORM_BUS) +static int gf_remove(struct platform_device *pdev) +#endif +{ + struct gf_dev *gf_dev = &gf; + wakeup_source_trash(&fp_wakelock); + + /* make sure ops on existing fds can abort cleanly */ + if (gf_dev->irq) { + free_irq(gf_dev->irq, gf_dev); + } + + if (gf_dev->input != NULL) { + input_unregister_device(gf_dev->input); + } + + input_free_device(gf_dev->input); + /* prevent new opens */ + mutex_lock(&device_list_lock); + list_del(&gf_dev->device_entry); + device_destroy(gf_class, gf_dev->devt); + clear_bit(MINOR(gf_dev->devt), minors); + + if (gf_dev->users == 0) { + gf_cleanup(gf_dev); + } + +#ifndef GOODIX_DRM_INTERFACE_WA + drm_unregister_client(&gf_dev->notifier); +#endif + mutex_unlock(&device_list_lock); + return 0; +} + +static struct of_device_id gx_match_table[] = { + { .compatible = GF_SPIDEV_NAME }, + {}, +}; + +#if defined(USE_SPI_BUS) +static struct spi_driver gf_driver = { +#elif defined(USE_PLATFORM_BUS) +static struct platform_driver gf_driver = { +#endif + .driver = { + .name = GF_DEV_NAME, + .owner = THIS_MODULE, + .of_match_table = gx_match_table, + }, + .probe = gf_probe, + .remove = gf_remove, +}; + +static int __init gf_init(void) +{ + int status; + /* Claim our 256 reserved device numbers. Then register a class + * that will key udev/mdev to add/remove /dev nodes. Last, register + * the driver which manages those device numbers. + */ + BUILD_BUG_ON(N_SPI_MINORS > 256); + status = register_chrdev(SPIDEV_MAJOR, CHRD_DRIVER_NAME, &gf_fops); + + if (status < 0) { + pr_warn("Failed to register char device!\n"); + return status; + } + + SPIDEV_MAJOR = status; + gf_class = class_create(THIS_MODULE, CLASS_NAME); + + if (IS_ERR(gf_class)) { + unregister_chrdev(SPIDEV_MAJOR, gf_driver.driver.name); + pr_warn("Failed to create class.\n"); + return PTR_ERR(gf_class); + } + +#if defined(USE_PLATFORM_BUS) + status = platform_driver_register(&gf_driver); +#elif defined(USE_SPI_BUS) + status = spi_register_driver(&gf_driver); +#endif + + if (status < 0) { + class_destroy(gf_class); + unregister_chrdev(SPIDEV_MAJOR, gf_driver.driver.name); + pr_warn("Failed to register SPI driver.\n"); + } + +#ifdef GF_NETLINK_ENABLE + netlink_init(); +#endif + pr_debug("status = 0x%x\n", status); + return 0; +} +module_init(gf_init); + +static void __exit gf_exit(void) +{ +#ifdef GF_NETLINK_ENABLE + netlink_exit(); +#endif +#if defined(USE_PLATFORM_BUS) + platform_driver_unregister(&gf_driver); +#elif defined(USE_SPI_BUS) + spi_unregister_driver(&gf_driver); +#endif + class_destroy(gf_class); + unregister_chrdev(SPIDEV_MAJOR, gf_driver.driver.name); +} +module_exit(gf_exit); + +MODULE_AUTHOR("Jiangtao Yi, "); +MODULE_AUTHOR("Jandy Gou, "); +MODULE_DESCRIPTION("goodix fingerprint sensor device driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/fingerprint/goodix_ta/gf_spi.h b/drivers/input/fingerprint/goodix_ta/gf_spi.h new file mode 100644 index 000000000000..3ea8a55b40fc --- /dev/null +++ b/drivers/input/fingerprint/goodix_ta/gf_spi.h @@ -0,0 +1,160 @@ +/* + * driver definition for sensor driver + * + * Coypright (c) 2017 Goodix + */ +#ifndef __GF_SPI_H +#define __GF_SPI_H + +#include +#include +/**********************************************************/ +enum FP_MODE { + GF_IMAGE_MODE = 0, + GF_KEY_MODE, + GF_SLEEP_MODE, + GF_FF_MODE, + GF_DEBUG_MODE = 0x56 +}; + +#define SUPPORT_NAV_EVENT + +#if defined(SUPPORT_NAV_EVENT) +#define GF_NAV_INPUT_UP KEY_UP +#define GF_NAV_INPUT_DOWN KEY_DOWN +#define GF_NAV_INPUT_LEFT KEY_LEFT +#define GF_NAV_INPUT_RIGHT KEY_RIGHT +#define GF_NAV_INPUT_CLICK KEY_VOLUMEDOWN +#define GF_NAV_INPUT_DOUBLE_CLICK KEY_VOLUMEUP +#define GF_NAV_INPUT_LONG_PRESS KEY_SEARCH +#define GF_NAV_INPUT_HEAVY KEY_CHAT +#endif + +#define GF_KEY_INPUT_HOME KEY_HOME +#define GF_KEY_INPUT_MENU KEY_MENU +#define GF_KEY_INPUT_BACK KEY_BACK +#define GF_KEY_INPUT_POWER KEY_POWER +#define GF_KEY_INPUT_CAMERA KEY_CAMERA + +#if defined(SUPPORT_NAV_EVENT) +typedef enum gf_nav_event { + GF_NAV_NONE = 0, + GF_NAV_FINGER_UP, + GF_NAV_FINGER_DOWN, + GF_NAV_UP, + GF_NAV_DOWN, + GF_NAV_LEFT, + GF_NAV_RIGHT, + GF_NAV_CLICK, + GF_NAV_HEAVY, + GF_NAV_LONG_PRESS, + GF_NAV_DOUBLE_CLICK, +} gf_nav_event_t; +#endif + +typedef enum gf_key_event { + GF_KEY_NONE = 0, + GF_KEY_HOME, + GF_KEY_POWER, + GF_KEY_MENU, + GF_KEY_BACK, + GF_KEY_CAMERA, +} gf_key_event_t; + +struct gf_key { + enum gf_key_event key; + uint32_t value; /* key down = 1, key up = 0 */ +}; + +struct gf_key_map { + unsigned int type; + unsigned int code; +}; + +struct gf_ioc_chip_info { + unsigned char vendor_id; + unsigned char mode; + unsigned char operation; + unsigned char reserved[5]; +}; + +#define GF_IOC_MAGIC 'g' /*define magic number*/ +#define GF_IOC_INIT _IOR(GF_IOC_MAGIC, 0, uint8_t) +#define GF_IOC_EXIT _IO(GF_IOC_MAGIC, 1) +#define GF_IOC_RESET _IO(GF_IOC_MAGIC, 2) +#define GF_IOC_ENABLE_IRQ _IO(GF_IOC_MAGIC, 3) +#define GF_IOC_DISABLE_IRQ _IO(GF_IOC_MAGIC, 4) +#define GF_IOC_ENABLE_SPI_CLK _IOW(GF_IOC_MAGIC, 5, uint32_t) +#define GF_IOC_DISABLE_SPI_CLK _IO(GF_IOC_MAGIC, 6) +#define GF_IOC_ENABLE_POWER _IO(GF_IOC_MAGIC, 7) +#define GF_IOC_DISABLE_POWER _IO(GF_IOC_MAGIC, 8) +#define GF_IOC_INPUT_KEY_EVENT _IOW(GF_IOC_MAGIC, 9, struct gf_key) +#define GF_IOC_ENTER_SLEEP_MODE _IO(GF_IOC_MAGIC, 10) +#define GF_IOC_GET_FW_INFO _IOR(GF_IOC_MAGIC, 11, uint8_t) +#define GF_IOC_REMOVE _IO(GF_IOC_MAGIC, 12) +#define GF_IOC_CHIP_INFO _IOW(GF_IOC_MAGIC, 13, struct gf_ioc_chip_info) + +#if defined(SUPPORT_NAV_EVENT) +#define GF_IOC_NAV_EVENT _IOW(GF_IOC_MAGIC, 14, gf_nav_event_t) +#define GF_IOC_MAXNR 15 /* THIS MACRO IS NOT USED NOW... */ +#else +#define GF_IOC_MAXNR 14 /* THIS MACRO IS NOT USED NOW... */ +#endif + +/*#define AP_CONTROL_CLK 1*/ +#define USE_PLATFORM_BUS 1 +/*#define USE_SPI_BUS 1*/ +/*#define GF_FASYNC 1*/ /*If support fasync mechanism.*/ +#define GF_PW_CTL 1 +#define GF_NETLINK_ENABLE 1 +#define GF_NET_EVENT_IRQ 1 +#define GF_NET_EVENT_FB_BLACK 2 +#define GF_NET_EVENT_FB_UNBLACK 3 +#define NETLINK_TEST 25 + +struct gf_dev { + dev_t devt; + struct list_head device_entry; +#if defined(USE_SPI_BUS) + struct spi_device *spi; +#elif defined(USE_PLATFORM_BUS) + struct platform_device *spi; +#endif + struct clk *core_clk; + struct clk *iface_clk; + + struct input_dev *input; + /* buffer is NULL unless this device is open (users > 0) */ + unsigned users; + signed irq_gpio; + signed reset_gpio; + signed pwr_gpio; + int irq; + int irq_enabled; + int clk_enabled; +#ifdef GF_FASYNC + struct fasync_struct *async; +#endif + struct notifier_block notifier; + char device_available; + char fb_black; + char wait_finger_down; + struct work_struct work; +#ifdef CONFIG_FINGERPRINT_FP_VREG_CONTROL + struct regulator *vreg; +#endif +}; + +int gf_parse_dts(struct gf_dev *gf_dev); +void gf_cleanup(struct gf_dev *gf_dev); + +int gf_power_on(struct gf_dev *gf_dev); +int gf_power_off(struct gf_dev *gf_dev); + +int gf_hw_reset(struct gf_dev *gf_dev, unsigned int delay_ms); +int gf_irq_num(struct gf_dev *gf_dev); + +void sendnlmsg(char *message); +int netlink_init(void); +void netlink_exit(void); +#endif /*__GF_SPI_H*/ diff --git a/drivers/input/fingerprint/goodix_ta/netlink.c b/drivers/input/fingerprint/goodix_ta/netlink.c new file mode 100644 index 000000000000..a38d66b73937 --- /dev/null +++ b/drivers/input/fingerprint/goodix_ta/netlink.c @@ -0,0 +1,97 @@ +/* + * netlink interface + * + * Copyright (c) 2017 Goodix + * Copyright (C) 2019 XiaoMi, Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +#define NETLINK_TEST 25 +#define MAX_MSGSIZE 32 +int stringlength(char *s); +void sendnlmsg(char *message); +static int pid = -1; +struct sock *nl_sk = NULL; + +void sendnlmsg(char *message) +{ + struct sk_buff *skb_1; + struct nlmsghdr *nlh; + int len = NLMSG_SPACE(MAX_MSGSIZE); + int slen = 0; + int ret = 0; + + if (!message || !nl_sk || !pid) { + return; + } + + skb_1 = alloc_skb(len, GFP_KERNEL); + + if (!skb_1) { + pr_err("alloc_skb error\n"); + return; + } + + slen = strlen(message); + nlh = nlmsg_put(skb_1, 0, 0, 0, MAX_MSGSIZE, 0); + NETLINK_CB(skb_1).portid = 0; + NETLINK_CB(skb_1).dst_group = 0; + message[slen] = '\0'; + memcpy(NLMSG_DATA(nlh), message, slen + 1); + ret = netlink_unicast(nl_sk, skb_1, pid, MSG_DONTWAIT); + + if (!ret) { + /*kfree_skb(skb_1);*/ + pr_err("send msg from kernel to usespace failed ret 0x%x\n", + ret); + } +} + +void nl_data_ready(struct sk_buff *__skb) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + char str[100]; + skb = skb_get(__skb); + + if (skb->len >= NLMSG_SPACE(0)) { + nlh = nlmsg_hdr(skb); + memcpy(str, NLMSG_DATA(nlh), sizeof(str)); + pid = nlh->nlmsg_pid; + kfree_skb(skb); + } +} + +int netlink_init(void) +{ + struct netlink_kernel_cfg netlink_cfg; + memset(&netlink_cfg, 0, sizeof(struct netlink_kernel_cfg)); + netlink_cfg.groups = 0; + netlink_cfg.flags = 0; + netlink_cfg.input = nl_data_ready; + netlink_cfg.cb_mutex = NULL; + nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST, &netlink_cfg); + + if (!nl_sk) { + pr_err("create netlink socket error\n"); + return 1; + } + + return 0; +} + +void netlink_exit(void) +{ + if (nl_sk != NULL) { + netlink_kernel_release(nl_sk); + nl_sk = NULL; + } + + pr_info("self module exited\n"); +} diff --git a/drivers/input/fingerprint/goodix_ta/platform.c b/drivers/input/fingerprint/goodix_ta/platform.c new file mode 100644 index 000000000000..b3ae8a663596 --- /dev/null +++ b/drivers/input/fingerprint/goodix_ta/platform.c @@ -0,0 +1,150 @@ +/* + * platform indepent driver interface + * + * Coypritht (c) 2017 Goodix + */ +#define DEBUG +#define pr_fmt(fmt) "gf_platform: " fmt + +#include +#include +#include +#include +#include +#include +#include + +#include "gf_spi.h" + +#if defined(USE_SPI_BUS) +#include +#include +#elif defined(USE_PLATFORM_BUS) +#include +#endif + +int gf_parse_dts(struct gf_dev *gf_dev) +{ +#ifdef GF_PW_CTL + int rc = 0; + /*get pwr resource*/ + gf_dev->pwr_gpio = + of_get_named_gpio(gf_dev->spi->dev.of_node, "fp-gpio-pwr", 0); + + if (!gpio_is_valid(gf_dev->pwr_gpio)) { + pr_info("PWR GPIO is invalid.\n"); + return -1; + } + + rc = gpio_request(gf_dev->pwr_gpio, "goodix_pwr"); + + if (rc) { + dev_err(&gf_dev->spi->dev, + "Failed to request PWR GPIO. rc = %d\n", rc); + return -1; + } + +#endif + /*get reset resource*/ + gf_dev->reset_gpio = of_get_named_gpio(gf_dev->spi->dev.of_node, + "goodix,gpio-reset", 0); + + if (!gpio_is_valid(gf_dev->reset_gpio)) { + pr_info("RESET GPIO is invalid.\n"); + return -EPERM; + } + + /*get irq resourece*/ + gf_dev->irq_gpio = of_get_named_gpio(gf_dev->spi->dev.of_node, + "goodix,gpio-irq", 0); + pr_info("gf::irq_gpio:%d\n", gf_dev->irq_gpio); + + if (!gpio_is_valid(gf_dev->irq_gpio)) { + pr_info("IRQ GPIO is invalid.\n"); + return -EPERM; + } + + return 0; +} + +void gf_cleanup(struct gf_dev *gf_dev) +{ + pr_info("[info] %s\n", __func__); + + if (gpio_is_valid(gf_dev->irq_gpio)) { + gpio_free(gf_dev->irq_gpio); + pr_info("remove irq_gpio success\n"); + } + + if (gpio_is_valid(gf_dev->reset_gpio)) { + gpio_free(gf_dev->reset_gpio); + pr_info("remove reset_gpio success\n"); + } + +#ifdef GF_PW_CTL + + if (gpio_is_valid(gf_dev->pwr_gpio)) { + gpio_free(gf_dev->pwr_gpio); + pr_info("remove pwr_gpio success\n"); + } + +#endif +} + +int gf_power_on(struct gf_dev *gf_dev) +{ + int rc = 0; +#ifdef GF_PW_CTL + + if (gpio_is_valid(gf_dev->pwr_gpio)) { + rc = gpio_direction_output(gf_dev->pwr_gpio, 1); + pr_info("---- power on result: %d----\n", rc); + } else { + pr_info("%s: gpio_is_invalid\n", __func__); + } + +#endif + msleep(10); + return rc; +} + +int gf_power_off(struct gf_dev *gf_dev) +{ + int rc = 0; +#ifdef GF_PW_CTL + + if (gpio_is_valid(gf_dev->pwr_gpio)) { + rc = gpio_direction_output(gf_dev->pwr_gpio, 0); + pr_info("---- power off result: %d----\n", rc); + } else { + pr_info("%s: gpio_is_invalid\n", __func__); + } + +#endif + return rc; +} + +int gf_hw_reset(struct gf_dev *gf_dev, unsigned int delay_ms) +{ + if (gf_dev == NULL) { + pr_info("Input buff is NULL.\n"); + return -EPERM; + } + + gpio_direction_output(gf_dev->reset_gpio, 0); + mdelay(3); + gpio_set_value(gf_dev->reset_gpio, 1); + mdelay(delay_ms); + pr_info("%s\n", __func__); + return 0; +} + +int gf_irq_num(struct gf_dev *gf_dev) +{ + if (gf_dev == NULL) { + pr_info("Input buff is NULL.\n"); + return -EPERM; + } else { + return gpio_to_irq(gf_dev->irq_gpio); + } +} From 4bbd1bfe78f2fe8b02dea08cc768245c6556b745 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 6 Nov 2023 21:41:52 +0100 Subject: [PATCH 045/226] drivers: input: fingerprint: Use MSM DRM notifier Change-Id: I724f3d67254603fe201f63d524584243c4f04884 Signed-off-by: firebird11 --- drivers/input/fingerprint/fpc_tee/fpc1020_tee.c | 14 +++++++------- drivers/input/fingerprint/goodix_ta/gf_spi.c | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/input/fingerprint/fpc_tee/fpc1020_tee.c b/drivers/input/fingerprint/fpc_tee/fpc1020_tee.c index 4c192c32d1d9..af457221f47c 100644 --- a/drivers/input/fingerprint/fpc_tee/fpc1020_tee.c +++ b/drivers/input/fingerprint/fpc_tee/fpc1020_tee.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #define FPC_SCREEN_HOLD_TIME 2000 #define FPC_TTW_HOLD_TIME 2000 @@ -681,15 +681,15 @@ static int fpc_fb_notif_callback(struct notifier_block *nb, unsigned long val, if (!fpc1020) return 0; - if (val != DRM_EVENT_BLANK || fpc1020->prepared == false) + if (val != MSM_DRM_EVENT_BLANK || fpc1020->prepared == false) return 0; pr_debug("[info] %s value = %d\n", __func__, (int)val); - if (evdata && evdata->data && val == DRM_EVENT_BLANK) { + if (evdata && evdata->data && val == MSM_DRM_EVENT_BLANK) { blank = *(int *)(evdata->data); switch (blank) { - case DRM_BLANK_POWERDOWN: + case MSM_DRM_BLANK_POWERDOWN: fpc1020->fb_black = true; #ifdef CONFIG_FINGERPRINT_FPC_SCREEN_NOTIFY __pm_wakeup_event(&fpc1020->screen_wl, @@ -698,7 +698,7 @@ static int fpc_fb_notif_callback(struct notifier_block *nb, unsigned long val, dev_attr_screen_status.attr.name); #endif break; - case DRM_BLANK_UNBLANK: + case MSM_DRM_BLANK_UNBLANK: fpc1020->fb_black = false; #ifdef CONFIG_FINGERPRINT_FPC_SCREEN_NOTIFY __pm_wakeup_event(&fpc1020->screen_wl, @@ -800,7 +800,7 @@ static int fpc1020_probe(struct platform_device *pdev) fpc1020->wait_finger_down = false; INIT_WORK(&fpc1020->work, notification_work); fpc1020->fb_notifier = fpc_notif_block; - drm_register_client(&fpc1020->fb_notifier); + msm_drm_register_client(&fpc1020->fb_notifier); dev_info(dev, "%s: ok\n", __func__); @@ -812,7 +812,7 @@ static int fpc1020_remove(struct platform_device *pdev) { struct fpc1020_data *fpc1020 = platform_get_drvdata(pdev); - drm_unregister_client(&fpc1020->fb_notifier); + msm_drm_unregister_client(&fpc1020->fb_notifier); sysfs_remove_group(&pdev->dev.kobj, &attribute_group); mutex_destroy(&fpc1020->lock); wakeup_source_trash(&fpc1020->ttw_wl); diff --git a/drivers/input/fingerprint/goodix_ta/gf_spi.c b/drivers/input/fingerprint/goodix_ta/gf_spi.c index 1812a5ef5de6..63986a6f3b05 100644 --- a/drivers/input/fingerprint/goodix_ta/gf_spi.c +++ b/drivers/input/fingerprint/goodix_ta/gf_spi.c @@ -47,7 +47,7 @@ #include #include #ifndef GOODIX_DRM_INTERFACE_WA -#include +#include #endif #include "gf_spi.h" @@ -757,7 +757,7 @@ static int goodix_fb_state_chg_callback(struct notifier_block *nb, unsigned int blank; char temp[4] = { 0x0 }; - if (val != DRM_EVENT_BLANK) { + if (val != MSM_DRM_EVENT_BLANK) { return 0; } @@ -766,11 +766,11 @@ static int goodix_fb_state_chg_callback(struct notifier_block *nb, __func__, (int)val); gf_dev = container_of(nb, struct gf_dev, notifier); - if (evdata && evdata->data && val == DRM_EVENT_BLANK && gf_dev) { + if (evdata && evdata->data && val == MSM_DRM_EVENT_BLANK && gf_dev) { blank = *(int *)(evdata->data); switch (blank) { - case DRM_BLANK_POWERDOWN: + case MSM_DRM_BLANK_POWERDOWN: if (gf_dev->device_available == 1) { gf_dev->fb_black = 1; gf_dev->wait_finger_down = true; @@ -789,7 +789,7 @@ static int goodix_fb_state_chg_callback(struct notifier_block *nb, break; - case DRM_BLANK_UNBLANK: + case MSM_DRM_BLANK_UNBLANK: if (gf_dev->device_available == 1) { gf_dev->fb_black = 0; #if defined(GF_NETLINK_ENABLE) @@ -922,7 +922,7 @@ static int gf_probe(struct platform_device *pdev) #endif #ifndef GOODIX_DRM_INTERFACE_WA gf_dev->notifier = goodix_noti_block; - drm_register_client(&gf_dev->notifier); + msm_drm_register_client(&gf_dev->notifier); #endif gf_dev->irq = gf_irq_num(gf_dev); wakeup_source_init(&fp_wakelock, "fp_wakelock"); @@ -987,7 +987,7 @@ static int gf_remove(struct platform_device *pdev) } #ifndef GOODIX_DRM_INTERFACE_WA - drm_unregister_client(&gf_dev->notifier); + msm_drm_unregister_client(&gf_dev->notifier); #endif mutex_unlock(&device_list_lock); return 0; From ae98455b55ad6e7fc48e37a76797d1aced629295 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 6 Nov 2023 21:43:27 +0100 Subject: [PATCH 046/226] drivers: input: fingerprint: Drop calls to dsi_bridge_interface_enable Change-Id: I2cf43d7c7bcdabb08ee03f5e193fe23aac431750 Signed-off-by: firebird11 --- drivers/input/fingerprint/fpc_tee/fpc1020_tee.c | 9 --------- drivers/input/fingerprint/goodix_ta/gf_spi.c | 12 ------------ drivers/input/fingerprint/goodix_ta/gf_spi.h | 1 - 3 files changed, 22 deletions(-) diff --git a/drivers/input/fingerprint/fpc_tee/fpc1020_tee.c b/drivers/input/fingerprint/fpc_tee/fpc1020_tee.c index af457221f47c..79684b15d084 100644 --- a/drivers/input/fingerprint/fpc_tee/fpc1020_tee.c +++ b/drivers/input/fingerprint/fpc_tee/fpc1020_tee.c @@ -114,7 +114,6 @@ struct fpc1020_data { struct notifier_block fb_notifier; bool fb_black; bool wait_finger_down; - struct work_struct work; }; static irqreturn_t fpc1020_irq_handler(int irq, void *handle); @@ -620,12 +619,6 @@ static const struct attribute_group attribute_group = { .attrs = attributes, }; -static void notification_work(struct work_struct *work) -{ - pr_debug("%s: unblank\n", __func__); - dsi_bridge_interface_enable(FP_UNLOCK_REJECTION_TIMEOUT); -} - static irqreturn_t fpc1020_irq_handler(int irq, void *handle) { struct fpc1020_data *fpc1020 = handle; @@ -641,7 +634,6 @@ static irqreturn_t fpc1020_irq_handler(int irq, void *handle) fpc1020->prepared) { pr_debug("%s enter\n", __func__); fpc1020->wait_finger_down = false; - schedule_work(&fpc1020->work); } return IRQ_HANDLED; @@ -798,7 +790,6 @@ static int fpc1020_probe(struct platform_device *pdev) fpc1020->fb_black = false; fpc1020->wait_finger_down = false; - INIT_WORK(&fpc1020->work, notification_work); fpc1020->fb_notifier = fpc_notif_block; msm_drm_register_client(&fpc1020->fb_notifier); diff --git a/drivers/input/fingerprint/goodix_ta/gf_spi.c b/drivers/input/fingerprint/goodix_ta/gf_spi.c index 63986a6f3b05..7e2a64b9fedf 100644 --- a/drivers/input/fingerprint/goodix_ta/gf_spi.c +++ b/drivers/input/fingerprint/goodix_ta/gf_spi.c @@ -544,14 +544,6 @@ static long gf_compat_ioctl(struct file *filp, unsigned int cmd, } #endif /*CONFIG_COMPAT*/ -#ifndef GOODIX_DRM_INTERFACE_WA -static void notification_work(struct work_struct *work) -{ - pr_debug("%s unblank\n", __func__); - dsi_bridge_interface_enable(FP_UNLOCK_REJECTION_TIMEOUT); -} -#endif - static irqreturn_t gf_irq(int irq, void *handle) { struct gf_dev *gf_dev = &gf; @@ -571,7 +563,6 @@ static irqreturn_t gf_irq(int irq, void *handle) input_report_key(gf_dev->input, key_input, 0); input_sync(gf_dev->input); gf_dev->wait_finger_down = false; - schedule_work(&gf_dev->work); } #elif defined(GF_FASYNC) @@ -845,9 +836,6 @@ static int gf_probe(struct platform_device *pdev) gf_dev->device_available = 0; gf_dev->fb_black = 0; gf_dev->wait_finger_down = false; -#ifndef GOODIX_DRM_INTERFACE_WA - INIT_WORK(&gf_dev->work, notification_work); -#endif if (gf_parse_dts(gf_dev)) { goto error_hw; diff --git a/drivers/input/fingerprint/goodix_ta/gf_spi.h b/drivers/input/fingerprint/goodix_ta/gf_spi.h index 3ea8a55b40fc..dde103b345e6 100644 --- a/drivers/input/fingerprint/goodix_ta/gf_spi.h +++ b/drivers/input/fingerprint/goodix_ta/gf_spi.h @@ -139,7 +139,6 @@ struct gf_dev { char device_available; char fb_black; char wait_finger_down; - struct work_struct work; #ifdef CONFIG_FINGERPRINT_FP_VREG_CONTROL struct regulator *vreg; #endif From 8d5049b5c248e1c7e83d42b0f13d618be3335ea0 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Sat, 9 Jul 2022 15:35:51 +0200 Subject: [PATCH 047/226] drivers: input: fingerprint: goodix: Improve wakelock handling * From vayu-r-oss Change-Id: Ie207478a65d1fbcebc014d9b134d77e528d4dc88 Signed-off-by: firebird11 --- drivers/input/fingerprint/goodix_ta/gf_spi.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/input/fingerprint/goodix_ta/gf_spi.c b/drivers/input/fingerprint/goodix_ta/gf_spi.c index 7e2a64b9fedf..7ade4a784936 100644 --- a/drivers/input/fingerprint/goodix_ta/gf_spi.c +++ b/drivers/input/fingerprint/goodix_ta/gf_spi.c @@ -81,7 +81,7 @@ static int SPIDEV_MAJOR; static DECLARE_BITMAP(minors, N_SPI_MINORS); static LIST_HEAD(device_list); static DEFINE_MUTEX(device_list_lock); -static struct wakeup_source fp_wakelock; +static struct wakeup_source *fp_wakelock = NULL; static struct gf_dev gf; struct gf_key_map maps[] = { @@ -552,7 +552,8 @@ static irqreturn_t gf_irq(int irq, void *handle) uint32_t key_input = 0; temp[0] = GF_NET_EVENT_IRQ; pr_debug("%s enter\n", __func__); - __pm_wakeup_event(&fp_wakelock, WAKELOCK_HOLD_TIME); + if (fp_wakelock != NULL) + __pm_wakeup_event(fp_wakelock, WAKELOCK_HOLD_TIME); sendnlmsg(temp); if ((gf_dev->wait_finger_down == true) && @@ -913,9 +914,15 @@ static int gf_probe(struct platform_device *pdev) msm_drm_register_client(&gf_dev->notifier); #endif gf_dev->irq = gf_irq_num(gf_dev); - wakeup_source_init(&fp_wakelock, "fp_wakelock"); + fp_wakelock = wakeup_source_register(&gf_dev->spi->dev, "fp_wakelock"); + if (fp_wakelock == NULL) + goto error_wakelock; pr_debug("version V%d.%d.%02d\n", VER_MAJOR, VER_MINOR, PATCH_LEVEL); return status; + +error_wakelock: + pr_debug("create fp wakelock failed.\n"); + #ifdef AP_CONTROL_CLK gfspi_probe_clk_enable_failed: gfspi_ioctl_clk_uninit(gf_dev); @@ -952,7 +959,8 @@ static int gf_remove(struct platform_device *pdev) #endif { struct gf_dev *gf_dev = &gf; - wakeup_source_trash(&fp_wakelock); + wakeup_source_unregister(fp_wakelock); + fp_wakelock = NULL; /* make sure ops on existing fds can abort cleanly */ if (gf_dev->irq) { From 9882a18f08c236ff01addf5f718ab4545abdc348 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 6 Nov 2023 19:38:05 +0100 Subject: [PATCH 048/226] drivers: input: fingerprint: goodix: Add vayu support * From vayu-r-oss Change-Id: I1507b413477a80c8ca36a702499c7aeb4b7d51c2 Signed-off-by: firebird11 --- drivers/input/fingerprint/goodix_ta/gf_spi.c | 44 ++++++++++++++------ drivers/input/fingerprint/goodix_ta/gf_spi.h | 4 +- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/drivers/input/fingerprint/goodix_ta/gf_spi.c b/drivers/input/fingerprint/goodix_ta/gf_spi.c index 7ade4a784936..0d457eb7ea59 100644 --- a/drivers/input/fingerprint/goodix_ta/gf_spi.c +++ b/drivers/input/fingerprint/goodix_ta/gf_spi.c @@ -49,6 +49,7 @@ #ifndef GOODIX_DRM_INTERFACE_WA #include #endif +#include #include "gf_spi.h" @@ -591,9 +592,11 @@ static int gf_open(struct inode *inode, struct file *filp) break; } } -#ifdef CONFIG_FINGERPRINT_FP_VREG_CONTROL pr_info("Try to enable fp_vdd_vreg\n"); - gf_dev->vreg = regulator_get(&gf_dev->spi->dev, "fp_vdd_vreg"); + if (get_hw_version_platform() == HARDWARE_PLATFORM_VAYU) + gf_dev->vreg = regulator_get(NULL, "pm8150_l17"); + else + gf_dev->vreg = regulator_get(&gf_dev->spi->dev, "fp_vdd_vreg"); if (gf_dev->vreg == NULL) { dev_err(&gf_dev->spi->dev, @@ -605,6 +608,17 @@ static int gf_open(struct inode *inode, struct file *filp) if (regulator_is_enabled(gf_dev->vreg)) { pr_info("fp_vdd_vreg is already enabled!\n"); } else { + if (get_hw_version_platform() == HARDWARE_PLATFORM_VAYU) { + status = regulator_set_voltage(gf_dev->vreg, 3000000, + 3000000); + if (status < 0) { + pr_info("fp_vdd_vreg set voltage failed!\n"); + gf_dev->vreg = NULL; + mutex_unlock(&device_list_lock); + return -EPERM; + } + } + rc = regulator_enable(gf_dev->vreg); if (rc) { @@ -618,10 +632,12 @@ static int gf_open(struct inode *inode, struct file *filp) } pr_info("fp_vdd_vreg is enabled!\n"); -#endif if (status == 0) { - rc = gpio_request(gf_dev->reset_gpio, "goodix_reset"); + if (get_hw_version_platform() == HARDWARE_PLATFORM_VAYU) + rc = gpio_request(gf_dev->reset_gpio, "gpio-reset"); + else + rc = gpio_request(gf_dev->reset_gpio, "goodix_reset"); if (rc) { dev_err(&gf_dev->spi->dev, @@ -632,7 +648,10 @@ static int gf_open(struct inode *inode, struct file *filp) } gpio_direction_output(gf_dev->reset_gpio, 0); - rc = gpio_request(gf_dev->irq_gpio, "goodix_irq"); + if (get_hw_version_platform() == HARDWARE_PLATFORM_VAYU) + rc = gpio_request(gf_dev->irq_gpio, "gpio-irq"); + else + rc = gpio_request(gf_dev->irq_gpio, "goodix_irq"); if (rc) { dev_err(&gf_dev->spi->dev, @@ -696,16 +715,15 @@ static int gf_release(struct inode *inode, struct file *filp) /* *Disable fp_vdd_vreg regulator */ -#ifdef CONFIG_FINGERPRINT_FP_VREG_CONTROL - pr_info("disable fp_vdd_vreg!\n"); + if (get_hw_version_platform() == HARDWARE_PLATFORM_VAYU) { + pr_info("disable fp_vdd_vreg!\n"); - if (regulator_is_enabled(gf_dev->vreg)) { - regulator_disable(gf_dev->vreg); - regulator_put(gf_dev->vreg); - gf_dev->vreg = NULL; + if (regulator_is_enabled(gf_dev->vreg)) { + regulator_disable(gf_dev->vreg); + regulator_put(gf_dev->vreg); + gf_dev->vreg = NULL; + } } - -#endif gf_dev->users--; if (!gf_dev->users) { diff --git a/drivers/input/fingerprint/goodix_ta/gf_spi.h b/drivers/input/fingerprint/goodix_ta/gf_spi.h index dde103b345e6..e9b17f8b19eb 100644 --- a/drivers/input/fingerprint/goodix_ta/gf_spi.h +++ b/drivers/input/fingerprint/goodix_ta/gf_spi.h @@ -105,7 +105,9 @@ struct gf_ioc_chip_info { #define USE_PLATFORM_BUS 1 /*#define USE_SPI_BUS 1*/ /*#define GF_FASYNC 1*/ /*If support fasync mechanism.*/ +#ifndef CONFIG_MACH_XIAOMI_VAYU #define GF_PW_CTL 1 +#endif #define GF_NETLINK_ENABLE 1 #define GF_NET_EVENT_IRQ 1 #define GF_NET_EVENT_FB_BLACK 2 @@ -139,9 +141,7 @@ struct gf_dev { char device_available; char fb_black; char wait_finger_down; -#ifdef CONFIG_FINGERPRINT_FP_VREG_CONTROL struct regulator *vreg; -#endif }; int gf_parse_dts(struct gf_dev *gf_dev); From 8240a39907c75db8e602897719de90bb89d4213e Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 18:02:03 +0200 Subject: [PATCH 049/226] drivers: input: keyboard: Import Xiaomi changes Change-Id: I7bb81d202ac600005bda4d801e62d2d2c5132f88 Signed-off-by: firebird11 --- drivers/input/keyboard/gpio_keys.c | 34 ++++++++++++++++++++++++++++++ include/linux/gpio_keys.h | 3 +++ 2 files changed, 37 insertions(+) diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index e9f0ebf3267a..69e66e3604ae 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -385,6 +385,21 @@ static void gpio_keys_gpio_work_func(struct work_struct *work) struct gpio_button_data *bdata = container_of(work, struct gpio_button_data, work.work); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (bdata->button->level_trigger) { + unsigned int trigger = + irq_get_trigger_type(bdata->irq) & ~IRQF_TRIGGER_MASK; + int state = gpiod_get_value_cansleep(bdata->gpiod); + if (state) + trigger |= IRQF_TRIGGER_HIGH; + else + trigger |= IRQF_TRIGGER_LOW; + + irq_set_irq_type(bdata->irq, trigger); + enable_irq(bdata->irq); + } +#endif + gpio_keys_gpio_report_event(bdata); if (bdata->button->wakeup) @@ -397,11 +412,19 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) BUG_ON(irq != bdata->irq); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (bdata->button->level_trigger) + disable_irq_nosync(bdata->irq); +#endif + if (bdata->button->wakeup) { const struct gpio_keys_button *button = bdata->button; pm_stay_awake(bdata->input->dev.parent); if (bdata->suspended && +#ifdef CONFIG_MACH_XIAOMI_SM8150 + (button->code != KEY_AI) && +#endif (button->type == 0 || button->type == EV_KEY)) { /* * Simulate wakeup key press in case the key has @@ -567,6 +590,12 @@ static int gpio_keys_setup_key(struct platform_device *pdev, isr = gpio_keys_gpio_isr; irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (bdata->button->level_trigger) { + irqflags = gpiod_is_active_low(bdata->gpiod) ? + IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH; + } +#endif } else { if (!button->irq) { @@ -722,6 +751,11 @@ gpio_keys_get_devtree_pdata(struct device *dev) button->can_disable = fwnode_property_read_bool(child, "linux,can-disable"); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + button->level_trigger = + fwnode_property_read_bool(child, "gpio-key,level-trigger"); +#endif + if (fwnode_property_read_u32(child, "debounce-interval", &button->debounce_interval)) button->debounce_interval = 5; diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index d06bf77400f1..cf1bba4e7aae 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -28,6 +28,9 @@ struct gpio_keys_button { int wakeup; int debounce_interval; bool can_disable; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool level_trigger; +#endif int value; unsigned int irq; }; From c81a101f06711e516b02cc0256bf05bdaefef959 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 18:03:45 +0200 Subject: [PATCH 050/226] drivers: input: misc: Import Xiaomi changes Change-Id: I9335d252b98c4e552cc04118a2cf59ec64a9f922 Signed-off-by: firebird11 --- drivers/input/misc/qti-haptics.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/input/misc/qti-haptics.c b/drivers/input/misc/qti-haptics.c index fe2ed14461cb..1eec6ae72dc7 100644 --- a/drivers/input/misc/qti-haptics.c +++ b/drivers/input/misc/qti-haptics.c @@ -1176,7 +1176,11 @@ static int qti_haptics_hw_init(struct qti_hap_chip *chip) addr = REG_HAP_AUTO_RES_CFG; mask = HAP_AUTO_RES_MODE_BIT | HAP_CAL_EOP_EN_BIT | HAP_CAL_PERIOD_MASK; val = config->lra_auto_res_mode << HAP_AUTO_RES_MODE_SHIFT; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + val |= HAP_CAL_EOP_EN_BIT; +#else val |= HAP_CAL_EOP_EN_BIT | HAP_CAL_OPT3_EVERY_8_PERIOD; +#endif rc = qti_haptics_masked_write(chip, addr, mask, val); if (rc < 0) { dev_err(chip->dev, "set AUTO_RES_CFG failed, rc=%d\n", rc); From 061139883b8fa64f39ebec2b257e338a3b7f605b Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 6 Nov 2023 11:02:15 +0100 Subject: [PATCH 051/226] drivers: input: misc: Import aw8697_haptic_xm driver * Run clang-format on source files Change-Id: If9062dbbc2513b29bb4476267c6c5de1c8cc2ad7 Signed-off-by: firebird11 --- drivers/input/misc/Kconfig | 2 + drivers/input/misc/Makefile | 1 + drivers/input/misc/aw8697_haptic_xm/Kconfig | 15 + drivers/input/misc/aw8697_haptic_xm/Makefile | 2 + drivers/input/misc/aw8697_haptic_xm/aw8697.c | 4929 +++++++++++++++++ drivers/input/misc/aw8697_haptic_xm/aw8697.h | 454 ++ .../misc/aw8697_haptic_xm/aw8697_config.h | 117 + .../input/misc/aw8697_haptic_xm/aw8697_reg.h | 539 ++ .../input/misc/aw8697_haptic_xm/ringbuffer.c | 228 + .../input/misc/aw8697_haptic_xm/ringbuffer.h | 36 + 10 files changed, 6323 insertions(+) create mode 100755 drivers/input/misc/aw8697_haptic_xm/Kconfig create mode 100755 drivers/input/misc/aw8697_haptic_xm/Makefile create mode 100644 drivers/input/misc/aw8697_haptic_xm/aw8697.c create mode 100644 drivers/input/misc/aw8697_haptic_xm/aw8697.h create mode 100644 drivers/input/misc/aw8697_haptic_xm/aw8697_config.h create mode 100644 drivers/input/misc/aw8697_haptic_xm/aw8697_reg.h create mode 100644 drivers/input/misc/aw8697_haptic_xm/ringbuffer.c create mode 100644 drivers/input/misc/aw8697_haptic_xm/ringbuffer.h diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index e0c7a6f358df..4ff5b3406b8e 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -889,4 +889,6 @@ config INPUT_HISI_POWERKEY To compile this driver as a module, choose M here: the module will be called hisi_powerkey. +source "drivers/input/misc/aw8697_haptic_xm/Kconfig" + endif diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 137da08f75a8..c790f73d3dd8 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -85,3 +85,4 @@ obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o obj-$(CONFIG_INPUT_YEALINK) += yealink.o obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o +obj-$(CONFIG_INPUT_AW8697_XM_HAPTIC) += aw8697_haptic_xm/ diff --git a/drivers/input/misc/aw8697_haptic_xm/Kconfig b/drivers/input/misc/aw8697_haptic_xm/Kconfig new file mode 100755 index 000000000000..978e396dcc77 --- /dev/null +++ b/drivers/input/misc/aw8697_haptic_xm/Kconfig @@ -0,0 +1,15 @@ +# +# Mediatek AW9233 Driver +# + +config INPUT_AW8697_XM_HAPTIC + tristate "Freescale AW8697 Touchkey" + depends on I2C + help + Say Y here if you have Freescale AW8697 touchkey controller + chip in your system. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called mpr121_touchkey. diff --git a/drivers/input/misc/aw8697_haptic_xm/Makefile b/drivers/input/misc/aw8697_haptic_xm/Makefile new file mode 100755 index 000000000000..4029f8dc9ca1 --- /dev/null +++ b/drivers/input/misc/aw8697_haptic_xm/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_INPUT_AW8697_XM_HAPTIC) += aw8697.o +obj-$(CONFIG_INPUT_AW8697_XM_HAPTIC) += ringbuffer.o diff --git a/drivers/input/misc/aw8697_haptic_xm/aw8697.c b/drivers/input/misc/aw8697_haptic_xm/aw8697.c new file mode 100644 index 000000000000..63b27b37267c --- /dev/null +++ b/drivers/input/misc/aw8697_haptic_xm/aw8697.c @@ -0,0 +1,4929 @@ +/* + * aw8697.c aw8697 haptic module + * + * Version: v1.1.3 + * + * Copyright (c) 2019 AWINIC Technology CO., LTD + * + * Author: Nick Li + * + * 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. + */ + +#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "aw8697_config.h" +#include "aw8697_reg.h" +#include "aw8697.h" +#include "ringbuffer.h" + +/****************************************************** + * + * Marco + * + ******************************************************/ +#define AW8697_I2C_NAME "aw8697_haptic" +#define AW8697_HAPTIC_NAME "aw8697_haptic" + +#define AW8697_VERSION "v1.1.3" + +#define AWINIC_RAM_UPDATE_DELAY + +#define AW_I2C_RETRIES 2 +#define AW_I2C_RETRY_DELAY 2 +#define AW_READ_CHIPID_RETRIES 5 +#define AW_READ_CHIPID_RETRY_DELAY 2 + +#define AW8697_MAX_DSP_START_TRY_COUNT 10 + +#define AW8697_MAX_FIRMWARE_LOAD_CNT 20 + +#define AW8697_MAX_BST_VO 0x1f + +#define OSC_CALIBRATION_T_LENGTH 5100000 +#define PM_QOS_VALUE_VB 400 +struct pm_qos_request pm_qos_req_vb; +/****************************************************** + * + * variable + * + ******************************************************/ +#define AW8697_RTP_NAME_MAX 64 +static char *aw8697_ram_name = "aw8697_haptic.bin"; +#ifdef TEST_RTP +static char aw8697_rtp_name[][AW8697_RTP_NAME_MAX] = { + { "aw8697_rtp_1.bin" }, +}; +#else +static char aw8697_rtp_name[][AW8697_RTP_NAME_MAX] = { + { "aw8697_rtp_1.bin" }, //8 + { "aw8697_rtp_1.bin" }, + { "aw8697_rtp_1.bin" }, + { "aw8697_rtp_1.bin" }, + { "aw8697_rtp_1.bin" }, + { "aw8697_rtp_1.bin" }, + { "aw8697_rtp_1.bin" }, + { "aw8697_rtp_1.bin" }, + { "aw8697_rtp_1.bin" }, + { "aw8697_rtp_1.bin" }, + { "aw8697_rtp_1.bin" }, + //{"aw8697_rtp_1.bin"}, + //{"aw8697_rtp_1.bin"}, + { "AcousticGuitar_RTP.bin" }, //21 + { "Blues_RTP.bin" }, + { "Candy_RTP.bin" }, + { "Carousel_RTP.bin" }, + { "Celesta_RTP.bin" }, + { "Childhood_RTP.bin" }, + { "Country_RTP.bin" }, + { "Cowboy_RTP.bin" }, + { "Echo_RTP.bin" }, + { "Fairyland_RTP.bin" }, + { "Fantasy_RTP.bin" }, + { "Field_Trip_RTP.bin" }, + { "Glee_RTP.bin" }, + { "Glockenspiel_RTP.bin" }, + { "Ice_Latte_RTP.bin" }, + { "Kung_Fu_RTP.bin" }, + { "Leisure_RTP.bin" }, + { "Lollipop_RTP.bin" }, + { "MiMix2_RTP.bin" }, + { "Mi_RTP.bin" }, + { "MiHouse_RTP.bin" }, + { "MiJazz_RTP.bin" }, + { "MiRemix_RTP.bin" }, + { "Mountain_Spring_RTP.bin" }, + { "Orange_RTP.bin" }, + { "Raindrops_RTP.bin" }, + { "Space_Age_RTP.bin" }, + { "ToyRobot_RTP.bin" }, + { "Vigor_RTP.bin" }, + { "Bottle_RTP.bin" }, + { "Bubble_RTP.bin" }, + { "Bullfrog_RTP.bin" }, + { "Burst_RTP.bin" }, + { "Chirp_RTP.bin" }, + { "Clank_RTP.bin" }, + { "Crystal_RTP.bin" }, + { "FadeIn_RTP.bin" }, + { "FadeOut_RTP.bin" }, + { "Flute_RTP.bin" }, + { "Fresh_RTP.bin" }, + { "Frog_RTP.bin" }, + { "Guitar_RTP.bin" }, + { "Harp_RTP.bin" }, + { "IncomingMessage_RTP.bin" }, + { "MessageSent_RTP.bin" }, + { "Moment_RTP.bin" }, + { "NotificationXylophone_RTP.bin" }, + { "Potion_RTP.bin" }, + { "Radar_RTP.bin" }, + { "Spring_RTP.bin" }, + { "Swoosh_RTP.bin" }, //71 + { "Gesture_UpSlide_RTP.bin" }, + { "FOD_Motion_Planet_RTP.bin" }, + { "Charge_Wire_RTP.bin" }, + { "Charge_Wireless_RTP.bin" }, + { "Unlock_Failed_RTP.bin" }, + { "FOD_Motion1_RTP.bin" }, + { "FOD_Motion2_RTP.bin" }, + { "FOD_Motion3_RTP.bin" }, + { "FOD_Motion4_RTP.bin" }, + { "FOD_Motion_Aurora_RTP.bin" }, + { "FaceID_Wrong2_RTP.bin" }, //82 + { "uninstall_animation_rtp.bin" }, + { "uninstall_dialog_rtp.bin" }, + { "screenshot_rtp.bin" }, + { "lockscreen_camera_entry_rtp.bin" }, + { "launcher_edit_rtp.bin" }, + { "launcher_icon_selection_rtp.bin" }, + { "taskcard_remove_rtp.bin" }, + { "task_cleanall_rtp.bin" }, + { "new_iconfolder_rtp.bin" }, + { "notification_remove_rtp.bin" }, + { "notification_cleanall_rtp.bin" }, + { "notification_setting_rtp.bin" }, + { "game_turbo_rtp.bin" }, + { "NFC_card_rtp.bin" }, + { "wakeup_voice_assistant_rtp.bin" }, + { "NFC_card_slow_rtp.bin" }, + { "aw8697_rtp_1.bin" }, //99 + { "aw8697_rtp_1.bin" }, //100 + { "offline_countdown_RTP.bin" }, + { "scene_bomb_injury_RTP.bin" }, + { "scene_bomb_RTP.bin" }, //103 + { "door_open_RTP.bin" }, + { "aw8697_rtp_1.bin" }, + { "scene_step_RTP.bin" }, //106 + { "crawl_RTP.bin" }, + { "scope_on_RTP.bin" }, + { "scope_off_RTP.bin" }, + { "magazine_quick_RTP.bin" }, + { "grenade_RTP.bin" }, + { "scene_getshot_RTP.bin" }, //112 + { "grenade_explosion_RTP.bin" }, + { "punch_RTP.bin" }, + { "pan_RTP.bin" }, + { "bandage_RTP.bin" }, + { "aw8697_rtp_1.bin" }, + { "scene_jump_RTP.bin" }, + { "vehicle_plane_RTP.bin" }, //119 + { "scene_openparachute_RTP.bin" }, //120 + { "scene_closeparachute_RTP.bin" }, //121 + { "vehicle_collision_RTP.bin" }, + { "vehicle_buggy_RTP.bin" }, //123 + { "vehicle_dacia_RTP.bin" }, //124 + { "vehicle_moto_RTP.bin" }, //125 + { "firearms_akm_RTP.bin" }, //126 + { "firearms_m16a4_RTP.bin" }, //127 + { "aw8697_rtp_1.bin" }, + { "firearms_awm_RTP.bin" }, //129 + { "firearms_mini14_RTP.bin" }, //130 + { "firearms_vss_RTP.bin" }, //131 + { "firearms_qbz_RTP.bin" }, //132 + { "firearms_ump9_RTP.bin" }, //133 + { "firearms_dp28_RTP.bin" }, //134 + { "firearms_s1897_RTP.bin" }, //135 + { "aw8697_rtp_1.bin" }, + { "firearms_p18c_RTP.bin" }, //137 + { "aw8697_rtp_1.bin" }, + { "aw8697_rtp_1.bin" }, + { "CFM_KillOne_RTP.bin" }, + { "CFM_Headshot_RTP.bin" }, //141 + { "CFM_MultiKill_RTP.bin" }, + { "CFM_KillOne_Strong_RTP.bin" }, + { "CFM_Headshot_Strong_RTP.bin" }, + { "CFM_MultiKill_Strong_RTP.bin" }, + { "CFM_Weapon_Grenade_Explode_RTP.bin" }, + { "CFM_Weapon_Grenade_KillOne_RTP.bin" }, + { "CFM_ImpactFlesh_Normal_RTP.bin" }, + { "CFM_Weapon_C4_Installed_RTP.bin" }, + { "CFM_Hero_Appear_RTP.bin" }, + { "CFM_UI_Reward_OpenBox_RTP.bin" }, + { "CFM_UI_Reward_Task_RTP.bin" }, + { "CFM_Weapon_BLT_Shoot_RTP.bin" }, //153 + { "Atlantis_RTP.bin" }, + { "DigitalUniverse_RTP.bin" }, + { "Reveries_RTP.bin" }, + { "FOD_Motion_Triang_RTP.bin" }, + { "FOD_Motion_Flare_RTP.bin" }, + { "FOD_Motion_Ripple_RTP.bin" }, + { "FOD_Motion_Spiral_RTP.bin" }, + { "gamebox_launch_rtp.bin" }, // 161 + { "Gesture_Back_Pull_RTP.bin" }, // 162 + { "Gesture_Back_Release_RTP.bin" }, // 163 + { "alert_rtp.bin" }, // 164 + { "feedback_negative_light_rtp.bin" }, // 165 + { "feedback_neutral_rtp.bin" }, // 166 + { "feedback_positive_rtp.bin" }, // 167 + { "fingerprint_record_rtp.bin" }, // 168 + { "lockdown_rtp.bin" }, // 169 + { "sliding_damping_rtp.bin" }, // 170 + { "todo_alldone_rtp.bin" }, // 171 + { "uninstall_animation_icon_rtp.bin" }, // 172 + { "signal_button_highlight_rtp.bin" }, //173 + { "signal_button_negative_rtp.bin" }, + { "signal_button_rtp.bin" }, + { "signal_clock_high_rtp.bin" }, //176 + { "signal_clock_rtp.bin" }, + { "signal_clock_unit_rtp.bin" }, + { "signal_inputbox_rtp.bin" }, + { "signal_key_high_rtp.bin" }, + { "signal_key_unit_rtp.bin" }, //181 + { "signal_list_highlight_rtp.bin" }, + { "signal_list_rtp.bin" }, + { "signal_picker_rtp.bin" }, + { "signal_popup_rtp.bin" }, + { "signal_seekbar_rtp.bin" }, //186 + { "signal_switch_rtp.bin" }, + { "signal_tab_rtp.bin" }, + { "signal_text_rtp.bin" }, + { "signal_transition_light_rtp.bin" }, + { "signal_transition_rtp.bin" }, //191 + { "haptics_video_rtp.bin" }, //192 +}; +#endif +static int CUSTOME_WAVE_ID; +struct aw8697_container *aw8697_rtp; +struct aw8697 *g_aw8697; + +/****************************************************** + * + * functions + * + ******************************************************/ +static void aw8697_interrupt_clear(struct aw8697 *aw8697); +static int aw8697_haptic_trig_enable_config(struct aw8697 *aw8697); + +/****************************************************** + * + * aw8697 i2c write/read + * + ******************************************************/ +static int aw8697_i2c_write(struct aw8697 *aw8697, unsigned char reg_addr, + unsigned char reg_data) +{ + int ret = -1; + unsigned char cnt = 0; + + while (cnt < AW_I2C_RETRIES) { + ret = i2c_smbus_write_byte_data(aw8697->i2c, reg_addr, + reg_data); + if (ret < 0) { + pr_err("%s: i2c_write cnt=%d error=%d\n", __func__, cnt, + ret); + } else { + break; + } + cnt++; + msleep(AW_I2C_RETRY_DELAY); + } + + return ret; +} + +static int aw8697_i2c_read(struct aw8697 *aw8697, unsigned char reg_addr, + unsigned char *reg_data) +{ + int ret = -1; + unsigned char cnt = 0; + + while (cnt < AW_I2C_RETRIES) { + ret = i2c_smbus_read_byte_data(aw8697->i2c, reg_addr); + if (ret < 0) { + pr_err("%s: i2c_read cnt=%d error=%d\n", __func__, cnt, + ret); + } else { + *reg_data = ret; + break; + } + cnt++; + msleep(AW_I2C_RETRY_DELAY); + } + + return ret; +} + +static int aw8697_i2c_write_bits(struct aw8697 *aw8697, unsigned char reg_addr, + unsigned int mask, unsigned char reg_data) +{ + unsigned char reg_val = 0; + + aw8697_i2c_read(aw8697, reg_addr, ®_val); + reg_val &= mask; + reg_val |= reg_data; + aw8697_i2c_write(aw8697, reg_addr, reg_val); + + return 0; +} + +static int aw8697_i2c_writes(struct aw8697 *aw8697, unsigned char reg_addr, + unsigned char *buf, unsigned int len) +{ + int ret = -1; + unsigned char *data; + + data = kmalloc(len + 1, GFP_KERNEL); + if (data == NULL) { + pr_err("%s: can not allocate memory\n", __func__); + return -ENOMEM; + } + + data[0] = reg_addr; + memcpy(&data[1], buf, len); + + ret = i2c_master_send(aw8697->i2c, data, len + 1); + if (ret < 0) { + pr_err("%s: i2c master send error\n", __func__); + } + + kfree(data); + + return ret; +} + +/***************************************************** + * + * ram update + * + *****************************************************/ +static void aw8697_rtp_loaded(const struct firmware *cont, void *context) +{ + struct aw8697 *aw8697 = context; + pr_info("%s enter\n", __func__); + + if (!cont) { + pr_err("%s: failed to read %s\n", __func__, + aw8697_rtp_name[aw8697->rtp_file_num]); + release_firmware(cont); + return; + } + + pr_info("%s: loaded %s - size: %zu\n", __func__, + aw8697_rtp_name[aw8697->rtp_file_num], cont ? cont->size : 0); + + /* aw8697 rtp update */ + aw8697_rtp = vmalloc(cont->size + sizeof(int)); + if (!aw8697_rtp) { + release_firmware(cont); + pr_err("%s: Error allocating memory\n", __func__); + return; + } + aw8697_rtp->len = cont->size; + pr_info("%s: rtp size = %d\n", __func__, aw8697_rtp->len); + memcpy(aw8697_rtp->data, cont->data, cont->size); + release_firmware(cont); + + aw8697->rtp_init = 1; + pr_info("%s: rtp update complete\n", __func__); +} + +static int aw8697_rtp_update(struct aw8697 *aw8697) +{ + pr_info("%s enter\n", __func__); + + return request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, + aw8697_rtp_name[aw8697->rtp_file_num], + aw8697->dev, GFP_KERNEL, aw8697, + aw8697_rtp_loaded); +} + +static void aw8697_container_update(struct aw8697 *aw8697, + struct aw8697_container *aw8697_cont) +{ + int i = 0; + unsigned int shift = 0; + + pr_info("%s enter\n", __func__); + + mutex_lock(&aw8697->lock); + + aw8697->ram.baseaddr_shift = 2; + aw8697->ram.ram_shift = 4; + + /* RAMINIT Enable */ + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_RAMINIT_MASK, + AW8697_BIT_SYSCTRL_RAMINIT_EN); + + /* base addr */ + shift = aw8697->ram.baseaddr_shift; + aw8697->ram.base_addr = + (unsigned int)((aw8697_cont->data[0 + shift] << 8) | + (aw8697_cont->data[1 + shift])); + pr_info("%s: base_addr=0x%4x\n", __func__, aw8697->ram.base_addr); + + aw8697_i2c_write(aw8697, AW8697_REG_BASE_ADDRH, + aw8697_cont->data[0 + shift]); + aw8697_i2c_write(aw8697, AW8697_REG_BASE_ADDRL, + aw8697_cont->data[1 + shift]); + + aw8697_i2c_write(aw8697, AW8697_REG_FIFO_AEH, + (unsigned char)((aw8697->ram.base_addr >> 2) >> 8)); + aw8697_i2c_write(aw8697, AW8697_REG_FIFO_AEL, + (unsigned char)((aw8697->ram.base_addr >> 2) & + 0x00FF)); + aw8697_i2c_write(aw8697, AW8697_REG_FIFO_AFH, + (unsigned char)((aw8697->ram.base_addr - + (aw8697->ram.base_addr >> 2)) >> + 8)); + aw8697_i2c_write(aw8697, AW8697_REG_FIFO_AFL, + (unsigned char)((aw8697->ram.base_addr - + (aw8697->ram.base_addr >> 2)) & + 0x00FF)); + + /* ram */ + shift = aw8697->ram.baseaddr_shift; + aw8697_i2c_write(aw8697, AW8697_REG_RAMADDRH, + aw8697_cont->data[0 + shift]); + aw8697_i2c_write(aw8697, AW8697_REG_RAMADDRL, + aw8697_cont->data[1 + shift]); + shift = aw8697->ram.ram_shift; + for (i = shift; i < aw8697_cont->len; i++) { + aw8697_i2c_write(aw8697, AW8697_REG_RAMDATA, + aw8697_cont->data[i]); + } + + /* RAMINIT Disable */ + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_RAMINIT_MASK, + AW8697_BIT_SYSCTRL_RAMINIT_OFF); + + mutex_unlock(&aw8697->lock); + + pr_info("%s exit\n", __func__); +} + +static void aw8697_ram_loaded(const struct firmware *cont, void *context) +{ + struct aw8697 *aw8697 = context; + struct aw8697_container *aw8697_fw; + int i = 0; + unsigned short check_sum = 0; + + pr_info("%s enter\n", __func__); + + if (!cont) { + pr_err("%s: failed to read %s\n", __func__, aw8697_ram_name); + release_firmware(cont); + return; + } + + pr_info("%s: loaded %s - size: %zu\n", __func__, aw8697_ram_name, + cont ? cont->size : 0); + /* + for(i=0; isize; i++) { + pr_info("%s: addr:0x%04x, data:0x%02x\n", __func__, i, *(cont->data+i)); + } + */ + + /* check sum */ + for (i = 2; i < cont->size; i++) { + check_sum += cont->data[i]; + } + if (check_sum != + (unsigned short)((cont->data[0] << 8) | (cont->data[1]))) { + pr_err("%s: check sum err: check_sum=0x%04x\n", __func__, + check_sum); + return; + } else { + pr_info("%s: check sum pass : 0x%04x\n", __func__, check_sum); + aw8697->ram.check_sum = check_sum; + } + + /* aw8697 ram update */ + aw8697_fw = kzalloc(cont->size + sizeof(int), GFP_KERNEL); + if (!aw8697_fw) { + release_firmware(cont); + pr_err("%s: Error allocating memory\n", __func__); + return; + } + aw8697_fw->len = cont->size; + memcpy(aw8697_fw->data, cont->data, cont->size); + release_firmware(cont); + + aw8697_container_update(aw8697, aw8697_fw); + + aw8697->ram.len = aw8697_fw->len; + + kfree(aw8697_fw); + + aw8697->ram_init = 1; + pr_info("%s: fw update complete\n", __func__); + + aw8697_haptic_trig_enable_config(aw8697); + + aw8697_rtp_update(aw8697); +} + +static int aw8697_ram_update(struct aw8697 *aw8697) +{ + aw8697->ram_init = 0; + aw8697->rtp_init = 0; + return request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, + aw8697_ram_name, aw8697->dev, GFP_KERNEL, + aw8697, aw8697_ram_loaded); +} + +#ifdef AWINIC_RAM_UPDATE_DELAY +static void aw8697_ram_work_routine(struct work_struct *work) +{ + struct aw8697 *aw8697 = + container_of(work, struct aw8697, ram_work.work); + + pr_info("%s enter\n", __func__); + + aw8697_ram_update(aw8697); +} +#endif + +static int aw8697_ram_init(struct aw8697 *aw8697) +{ +#ifdef AWINIC_RAM_UPDATE_DELAY + int ram_timer_val = 5000; + INIT_DELAYED_WORK(&aw8697->ram_work, aw8697_ram_work_routine); + //schedule_delayed_work(&aw8697->ram_work, + //msecs_to_jiffies(ram_timer_val)); + queue_delayed_work(aw8697->work_queue, &aw8697->ram_work, + msecs_to_jiffies(ram_timer_val)); +#else + aw8697_ram_update(aw8697); +#endif + return 0; +} + +/***************************************************** + * + * haptic control + * + *****************************************************/ +static int aw8697_haptic_softreset(struct aw8697 *aw8697) +{ + pr_debug("%s enter\n", __func__); + + aw8697_i2c_write(aw8697, AW8697_REG_ID, 0xAA); + msleep(1); + return 0; +} + +static int aw8697_haptic_active(struct aw8697 *aw8697) +{ + pr_debug("%s enter\n", __func__); + + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_WORK_MODE_MASK, + AW8697_BIT_SYSCTRL_ACTIVE); + aw8697_interrupt_clear(aw8697); + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSINTM, + AW8697_BIT_SYSINTM_UVLO_MASK, + AW8697_BIT_SYSINTM_UVLO_EN); + return 0; +} + +static int aw8697_haptic_play_mode(struct aw8697 *aw8697, + unsigned char play_mode) +{ + pr_debug("%s enter\n", __func__); + + switch (play_mode) { + case AW8697_HAPTIC_STANDBY_MODE: + aw8697->play_mode = AW8697_HAPTIC_STANDBY_MODE; + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSINTM, + AW8697_BIT_SYSINTM_UVLO_MASK, + AW8697_BIT_SYSINTM_UVLO_OFF); + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_WORK_MODE_MASK, + AW8697_BIT_SYSCTRL_STANDBY); + break; + case AW8697_HAPTIC_RAM_MODE: + aw8697->play_mode = AW8697_HAPTIC_RAM_MODE; + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_PLAY_MODE_MASK, + AW8697_BIT_SYSCTRL_PLAY_MODE_RAM); + aw8697_haptic_active(aw8697); + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_BST_MODE_MASK, + AW8697_BIT_SYSCTRL_BST_MODE_BOOST); + break; + case AW8697_HAPTIC_RAM_LOOP_MODE: + aw8697->play_mode = AW8697_HAPTIC_RAM_LOOP_MODE; + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_PLAY_MODE_MASK, + AW8697_BIT_SYSCTRL_PLAY_MODE_RAM); + aw8697_haptic_active(aw8697); + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_BST_MODE_MASK, + AW8697_BIT_SYSCTRL_BST_MODE_BYPASS); + break; + case AW8697_HAPTIC_RTP_MODE: + aw8697->play_mode = AW8697_HAPTIC_RTP_MODE; + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_PLAY_MODE_MASK, + AW8697_BIT_SYSCTRL_PLAY_MODE_RTP); + aw8697_haptic_active(aw8697); + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_BST_MODE_MASK, + AW8697_BIT_SYSCTRL_BST_MODE_BOOST); + break; + case AW8697_HAPTIC_TRIG_MODE: + aw8697->play_mode = AW8697_HAPTIC_TRIG_MODE; + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_PLAY_MODE_MASK, + AW8697_BIT_SYSCTRL_PLAY_MODE_RAM); + aw8697_haptic_active(aw8697); + break; + case AW8697_HAPTIC_CONT_MODE: + aw8697->play_mode = AW8697_HAPTIC_CONT_MODE; + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_PLAY_MODE_MASK, + AW8697_BIT_SYSCTRL_PLAY_MODE_CONT); + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_BST_MODE_MASK, + AW8697_BIT_SYSCTRL_BST_MODE_BYPASS); + aw8697_haptic_active(aw8697); + break; + default: + dev_err(aw8697->dev, "%s: play mode %d err", __func__, + play_mode); + break; + } + return 0; +} + +static int aw8697_haptic_play_go(struct aw8697 *aw8697, bool flag) +{ + if (flag == true) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_GO, AW8697_BIT_GO_MASK, + AW8697_BIT_GO_ENABLE); + } else { + aw8697_i2c_write_bits(aw8697, AW8697_REG_GO, AW8697_BIT_GO_MASK, + AW8697_BIT_GO_DISABLE); + } + return 0; +} + +static int aw8697_haptic_stop_delay(struct aw8697 *aw8697) +{ + unsigned char reg_val = 0; + unsigned int cnt = 100; + + while (cnt--) { + aw8697_i2c_read(aw8697, AW8697_REG_GLB_STATE, ®_val); + if ((reg_val & 0x0f) == 0x00) { + return 0; + } + msleep(2); + pr_debug("%s wait for standby, reg glb_state=0x%02x\n", + __func__, reg_val); + } + pr_err("%s do not enter standby automatically\n", __func__); + + return 0; +} + +static int aw8697_haptic_stop(struct aw8697 *aw8697) +{ + pr_debug("%s enter\n", __func__); + + aw8697_haptic_play_go(aw8697, false); + aw8697_haptic_stop_delay(aw8697); + aw8697_haptic_play_mode(aw8697, AW8697_HAPTIC_STANDBY_MODE); + + return 0; +} + +static int aw8697_haptic_start(struct aw8697 *aw8697) +{ + pr_debug("%s enter\n", __func__); + + aw8697_haptic_play_go(aw8697, true); + + return 0; +} + +static int aw8697_haptic_set_wav_seq(struct aw8697 *aw8697, unsigned char wav, + unsigned char seq) +{ + aw8697_i2c_write(aw8697, AW8697_REG_WAVSEQ1 + wav, seq); + return 0; +} + +static int aw8697_haptic_set_wav_loop(struct aw8697 *aw8697, unsigned char wav, + unsigned char loop) +{ + unsigned char tmp = 0; + + if (wav % 2) { + tmp = loop << 0; + aw8697_i2c_write_bits(aw8697, AW8697_REG_WAVLOOP1 + (wav / 2), + AW8697_BIT_WAVLOOP_SEQNP1_MASK, tmp); + } else { + tmp = loop << 4; + aw8697_i2c_write_bits(aw8697, AW8697_REG_WAVLOOP1 + (wav / 2), + AW8697_BIT_WAVLOOP_SEQN_MASK, tmp); + } + + return 0; +} + +static int aw8697_haptic_set_repeat_wav_seq(struct aw8697 *aw8697, + unsigned char seq) +{ + aw8697_haptic_set_wav_seq(aw8697, 0x00, seq); + aw8697_haptic_set_wav_loop(aw8697, 0x00, + AW8697_BIT_WAVLOOP_INIFINITELY); + + return 0; +} + +static int aw8697_haptic_set_bst_vol(struct aw8697 *aw8697, + unsigned char bst_vol) +{ + if (bst_vol & 0xe0) { + bst_vol = 0x1f; + } + //printk("%s %d --\n", __func__, __LINE__); + aw8697_i2c_write_bits(aw8697, AW8697_REG_BSTDBG4, + AW8697_BIT_BSTDBG4_BSTVOL_MASK, (bst_vol << 1)); + return 0; +} + +static int aw8697_haptic_set_bst_peak_cur(struct aw8697 *aw8697, + unsigned char peak_cur) +{ + peak_cur &= AW8697_BSTCFG_PEAKCUR_LIMIT; + pr_info("%s %d enter\n", __func__, __LINE__); + aw8697_i2c_write_bits(aw8697, AW8697_REG_BSTCFG, + AW8697_BIT_BSTCFG_PEAKCUR_MASK, peak_cur); + return 0; +} + +static int aw8697_haptic_set_gain(struct aw8697 *aw8697, unsigned char gain) +{ + aw8697_i2c_write(aw8697, AW8697_REG_DATDBG, gain); + return 0; +} + +static int aw8697_haptic_set_pwm(struct aw8697 *aw8697, unsigned char mode) +{ + switch (mode) { + case AW8697_PWM_48K: + aw8697_i2c_write_bits(aw8697, AW8697_REG_PWMDBG, + AW8697_BIT_PWMDBG_PWM_MODE_MASK, + AW8697_BIT_PWMDBG_PWM_48K); + break; + case AW8697_PWM_24K: + aw8697_i2c_write_bits(aw8697, AW8697_REG_PWMDBG, + AW8697_BIT_PWMDBG_PWM_MODE_MASK, + AW8697_BIT_PWMDBG_PWM_24K); + break; + case AW8697_PWM_12K: + aw8697_i2c_write_bits(aw8697, AW8697_REG_PWMDBG, + AW8697_BIT_PWMDBG_PWM_MODE_MASK, + AW8697_BIT_PWMDBG_PWM_12K); + break; + default: + break; + } + return 0; +} + +static int aw8697_haptic_play_repeat_seq(struct aw8697 *aw8697, + unsigned char flag) +{ + pr_debug("%s enter\n", __func__); + + if (flag) { + aw8697_haptic_play_mode(aw8697, AW8697_HAPTIC_RAM_LOOP_MODE); + aw8697_haptic_start(aw8697); + } + + return 0; +} + +/***************************************************** + * + * motor protect + * + *****************************************************/ +static int aw8697_haptic_swicth_motorprotect_config(struct aw8697 *aw8697, + unsigned char addr, + unsigned char val) +{ + pr_info("%s enter\n", __func__); + + if (addr == 1) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_DETCTRL, + AW8697_BIT_DETCTRL_PROTECT_MASK, + AW8697_BIT_DETCTRL_PROTECT_SHUTDOWN); + aw8697_i2c_write_bits(aw8697, AW8697_REG_PWMPRC, + AW8697_BIT_PWMPRC_PRC_MASK, + AW8697_BIT_PWMPRC_PRC_ENABLE); + aw8697_i2c_write_bits(aw8697, AW8697_REG_PRLVL, + AW8697_BIT_PRLVL_PR_MASK, + AW8697_BIT_PRLVL_PR_ENABLE); + } else if (addr == 0) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_DETCTRL, + AW8697_BIT_DETCTRL_PROTECT_MASK, + AW8697_BIT_DETCTRL_PROTECT_NO_ACTION); + aw8697_i2c_write_bits(aw8697, AW8697_REG_PWMPRC, + AW8697_BIT_PWMPRC_PRC_MASK, + AW8697_BIT_PWMPRC_PRC_DISABLE); + aw8697_i2c_write_bits(aw8697, AW8697_REG_PRLVL, + AW8697_BIT_PRLVL_PR_MASK, + AW8697_BIT_PRLVL_PR_DISABLE); + } else if (addr == 0x2d) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_PWMPRC, + AW8697_BIT_PWMPRC_PRCTIME_MASK, val); + } else if (addr == 0x3e) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_PRLVL, + AW8697_BIT_PRLVL_PRLVL_MASK, val); + } else if (addr == 0x3f) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_PRTIME, + AW8697_BIT_PRTIME_PRTIME_MASK, val); + } else { + /*nothing to do; */ + } + return 0; +} + +/***************************************************** + * + * offset calibration + * + *****************************************************/ +static int aw8697_haptic_offset_calibration(struct aw8697 *aw8697) +{ + unsigned int cont = 2000; + unsigned char reg_val = 0; + + pr_info("%s enter\n", __func__); + + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_RAMINIT_MASK, + AW8697_BIT_SYSCTRL_RAMINIT_EN); + aw8697_i2c_write_bits(aw8697, AW8697_REG_DETCTRL, + AW8697_BIT_DETCTRL_DIAG_GO_MASK, + AW8697_BIT_DETCTRL_DIAG_GO_ENABLE); + while (1) { + aw8697_i2c_read(aw8697, AW8697_REG_DETCTRL, ®_val); + if ((reg_val & 0x01) == 0 || cont == 0) + break; + cont--; + } + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_RAMINIT_MASK, + AW8697_BIT_SYSCTRL_RAMINIT_OFF); + + return 0; +} + +/***************************************************** + * + * trig config + * + *****************************************************/ + +static int aw8697_haptic_trig_param_init(struct aw8697 *aw8697) +{ + pr_info("%s enter\n", __func__); + + aw8697->trig[0].enable = aw8697->info.trig_config[0][0]; + aw8697->trig[0].default_level = aw8697->info.trig_config[0][1]; + aw8697->trig[0].dual_edge = aw8697->info.trig_config[0][2]; + aw8697->trig[0].frist_seq = aw8697->info.trig_config[0][3]; + aw8697->trig[0].second_seq = aw8697->info.trig_config[0][4]; + + aw8697->trig[1].enable = aw8697->info.trig_config[1][0]; + ; + aw8697->trig[1].default_level = aw8697->info.trig_config[1][1]; + aw8697->trig[1].dual_edge = aw8697->info.trig_config[1][2]; + aw8697->trig[1].frist_seq = aw8697->info.trig_config[1][3]; + aw8697->trig[1].second_seq = aw8697->info.trig_config[1][4]; + + aw8697->trig[2].enable = aw8697->info.trig_config[2][0]; + ; + aw8697->trig[2].default_level = aw8697->info.trig_config[2][1]; + aw8697->trig[2].dual_edge = aw8697->info.trig_config[2][2]; + aw8697->trig[2].frist_seq = aw8697->info.trig_config[2][3]; + aw8697->trig[2].second_seq = aw8697->info.trig_config[2][4]; + + return 0; +} + +static int aw8697_haptic_trig_param_config(struct aw8697 *aw8697) +{ + pr_info("%s enter\n", __func__); + + if (aw8697->trig[0].default_level) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG1, + AW8697_BIT_TRGCFG1_TRG1_POLAR_MASK, + AW8697_BIT_TRGCFG1_TRG1_POLAR_NEG); + } else { + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG1, + AW8697_BIT_TRGCFG1_TRG1_POLAR_MASK, + AW8697_BIT_TRGCFG1_TRG1_POLAR_POS); + } + if (aw8697->trig[1].default_level) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG1, + AW8697_BIT_TRGCFG1_TRG2_POLAR_MASK, + AW8697_BIT_TRGCFG1_TRG2_POLAR_NEG); + } else { + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG1, + AW8697_BIT_TRGCFG1_TRG2_POLAR_MASK, + AW8697_BIT_TRGCFG1_TRG2_POLAR_POS); + } + if (aw8697->trig[2].default_level) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG1, + AW8697_BIT_TRGCFG1_TRG3_POLAR_MASK, + AW8697_BIT_TRGCFG1_TRG3_POLAR_NEG); + } else { + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG1, + AW8697_BIT_TRGCFG1_TRG3_POLAR_MASK, + AW8697_BIT_TRGCFG1_TRG3_POLAR_POS); + } + + if (aw8697->trig[0].dual_edge) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG1, + AW8697_BIT_TRGCFG1_TRG1_EDGE_MASK, + AW8697_BIT_TRGCFG1_TRG1_EDGE_POS_NEG); + } else { + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG1, + AW8697_BIT_TRGCFG1_TRG1_EDGE_MASK, + AW8697_BIT_TRGCFG1_TRG1_EDGE_POS); + } + if (aw8697->trig[1].dual_edge) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG1, + AW8697_BIT_TRGCFG1_TRG2_EDGE_MASK, + AW8697_BIT_TRGCFG1_TRG2_EDGE_POS_NEG); + } else { + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG1, + AW8697_BIT_TRGCFG1_TRG2_EDGE_MASK, + AW8697_BIT_TRGCFG1_TRG2_EDGE_POS); + } + if (aw8697->trig[2].dual_edge) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG1, + AW8697_BIT_TRGCFG1_TRG3_EDGE_MASK, + AW8697_BIT_TRGCFG1_TRG3_EDGE_POS_NEG); + } else { + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG1, + AW8697_BIT_TRGCFG1_TRG3_EDGE_MASK, + AW8697_BIT_TRGCFG1_TRG3_EDGE_POS); + } + + if (aw8697->trig[0].frist_seq) { + aw8697_i2c_write(aw8697, AW8697_REG_TRG1_WAV_P, + aw8697->trig[0].frist_seq); + } + if (aw8697->trig[0].second_seq && aw8697->trig[0].dual_edge) { + aw8697_i2c_write(aw8697, AW8697_REG_TRG1_WAV_N, + aw8697->trig[0].second_seq); + } + if (aw8697->trig[1].frist_seq) { + aw8697_i2c_write(aw8697, AW8697_REG_TRG2_WAV_P, + aw8697->trig[1].frist_seq); + } + if (aw8697->trig[1].second_seq && aw8697->trig[1].dual_edge) { + aw8697_i2c_write(aw8697, AW8697_REG_TRG2_WAV_N, + aw8697->trig[1].second_seq); + } + if (aw8697->trig[2].frist_seq) { + aw8697_i2c_write(aw8697, AW8697_REG_TRG3_WAV_P, + aw8697->trig[1].frist_seq); + } + if (aw8697->trig[2].second_seq && aw8697->trig[2].dual_edge) { + aw8697_i2c_write(aw8697, AW8697_REG_TRG3_WAV_N, + aw8697->trig[1].second_seq); + } + + return 0; +} + +static int aw8697_haptic_trig_enable_config(struct aw8697 *aw8697) +{ + pr_info("%s enter\n", __func__); + + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG2, + AW8697_BIT_TRGCFG2_TRG1_ENABLE_MASK, + aw8697->trig[0].enable); + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG2, + AW8697_BIT_TRGCFG2_TRG2_ENABLE_MASK, + aw8697->trig[1].enable); + aw8697_i2c_write_bits(aw8697, AW8697_REG_TRG_CFG2, + AW8697_BIT_TRGCFG2_TRG3_ENABLE_MASK, + aw8697->trig[2].enable); + + return 0; +} + +static int aw8697_haptic_auto_boost_config(struct aw8697 *aw8697, + unsigned char flag) +{ + aw8697->auto_boost = flag; + if (flag) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_BST_AUTO, + AW8697_BIT_BST_AUTO_BST_AUTOSW_MASK, + AW8697_BIT_BST_AUTO_BST_AUTOMATIC_BOOST); + } else { + aw8697_i2c_write_bits(aw8697, AW8697_REG_BST_AUTO, + AW8697_BIT_BST_AUTO_BST_AUTOSW_MASK, + AW8697_BIT_BST_AUTO_BST_MANUAL_BOOST); + } + return 0; +} + +/***************************************************** + * + * vbat mode + * + *****************************************************/ +static int aw8697_haptic_cont_vbat_mode(struct aw8697 *aw8697, + unsigned char flag) +{ + if (flag == AW8697_HAPTIC_CONT_VBAT_HW_COMP_MODE) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_ADCTEST, + AW8697_BIT_ADCTEST_VBAT_MODE_MASK, + AW8697_BIT_ADCTEST_VBAT_HW_COMP); + } else { + aw8697_i2c_write_bits(aw8697, AW8697_REG_ADCTEST, + AW8697_BIT_ADCTEST_VBAT_MODE_MASK, + AW8697_BIT_ADCTEST_VBAT_SW_COMP); + } + return 0; +} + +static int aw8697_haptic_get_vbat(struct aw8697 *aw8697) +{ + unsigned char reg_val = 0; + unsigned int cont = 2000; + + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_RAMINIT_MASK, + AW8697_BIT_SYSCTRL_RAMINIT_EN); + aw8697_i2c_write_bits(aw8697, AW8697_REG_DETCTRL, + AW8697_BIT_DETCTRL_VBAT_GO_MASK, + AW8697_BIT_DETCTRL_VABT_GO_ENABLE); + + while (1) { + aw8697_i2c_read(aw8697, AW8697_REG_DETCTRL, ®_val); + if ((reg_val & 0x02) == 0 || cont == 0) + break; + cont--; + } + + aw8697_i2c_read(aw8697, AW8697_REG_VBATDET, ®_val); + aw8697->vbat = 6100 * reg_val / 256; + if (aw8697->vbat > AW8697_VBAT_MAX) { + aw8697->vbat = AW8697_VBAT_MAX; + pr_debug("%s vbat max limit = %dmV\n", __func__, aw8697->vbat); + } + if (aw8697->vbat < AW8697_VBAT_MIN) { + aw8697->vbat = AW8697_VBAT_MIN; + pr_debug("%s vbat min limit = %dmV\n", __func__, aw8697->vbat); + } + + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_RAMINIT_MASK, + AW8697_BIT_SYSCTRL_RAMINIT_OFF); + + return 0; +} + +static int aw8697_haptic_ram_vbat_comp(struct aw8697 *aw8697, bool flag) +{ + int temp_gain = 0; + //pr_info("%s %d enter\n", __func__, __LINE__); + if (flag) { + if (aw8697->ram_vbat_comp == + AW8697_HAPTIC_RAM_VBAT_COMP_ENABLE) { + aw8697_haptic_get_vbat(aw8697); + temp_gain = + aw8697->gain * AW8697_VBAT_REFER / aw8697->vbat; + if (temp_gain > + (128 * AW8697_VBAT_REFER / AW8697_VBAT_MIN)) { + temp_gain = 128 * AW8697_VBAT_REFER / + AW8697_VBAT_MIN; + pr_debug("%s gain limit=%d\n", __func__, + temp_gain); + } + aw8697_haptic_set_gain(aw8697, temp_gain); + } else { + aw8697_haptic_set_gain(aw8697, aw8697->gain); + } + } else { + aw8697_haptic_set_gain(aw8697, aw8697->gain); + } + + return 0; +} + +/***************************************************** + * + * f0 + * + *****************************************************/ +static int aw8697_haptic_set_f0_preset(struct aw8697 *aw8697) +{ + unsigned int f0_reg = 0; + + pr_info("%s enter\n", __func__); + + f0_reg = 1000000000 / (aw8697->info.f0_pre * aw8697->info.f0_coeff); + aw8697_i2c_write(aw8697, AW8697_REG_F_PRE_H, + (unsigned char)((f0_reg >> 8) & 0xff)); + aw8697_i2c_write(aw8697, AW8697_REG_F_PRE_L, + (unsigned char)((f0_reg >> 0) & 0xff)); + + return 0; +} + +#ifndef USE_CONT_F0_CALI +static int aw8697_haptic_read_f0(struct aw8697 *aw8697) +{ + int ret = 0; + unsigned char reg_val = 0; + unsigned int f0_reg = 0; + unsigned long f0_tmp = 0; + + pr_info("%s enter\n", __func__); + + ret = aw8697_i2c_read(aw8697, AW8697_REG_F_LRA_F0_H, ®_val); + f0_reg = (reg_val << 8); + ret = aw8697_i2c_read(aw8697, AW8697_REG_F_LRA_F0_L, ®_val); + f0_reg |= (reg_val << 0); + if (!f0_reg) { + pr_info("%s: not get f0_reg value is 0!\n", __func__); + return 0; + } + f0_tmp = 1000000000 / (f0_reg * aw8697->info.f0_coeff); + aw8697->f0 = (unsigned int)f0_tmp; + pr_info("%s f0=%d\n", __func__, aw8697->f0); + + return 0; +} +#endif + +#ifndef USE_CONT_F0_CALI +static int aw8697_haptic_read_cont_f0(struct aw8697 *aw8697) +{ + int ret = 0; + unsigned char reg_val = 0; + unsigned int f0_reg = 0; + unsigned long f0_tmp = 0; + + pr_debug("%s enter\n", __func__); + + ret = aw8697_i2c_read(aw8697, AW8697_REG_F_LRA_CONT_H, ®_val); + f0_reg = (reg_val << 8); + ret = aw8697_i2c_read(aw8697, AW8697_REG_F_LRA_CONT_L, ®_val); + f0_reg |= (reg_val << 0); + if (!f0_reg) { + pr_info("%s: not get f0_reg value is 0!\n", __func__); + return 0; + } + f0_tmp = 1000000000 / (f0_reg * aw8697->info.f0_coeff); + aw8697->cont_f0 = (unsigned int)f0_tmp; + pr_info("%s f0=%d\n", __func__, aw8697->cont_f0); + + return 0; +} +#else +static int aw8697_haptic_read_cont_f0(struct aw8697 *aw8697) +{ + int ret = 0; + unsigned char reg_val = 0; + unsigned int f0_reg = 0; + unsigned long f0_tmp = 0; + + pr_debug("%s enter\n", __func__); + + ret = aw8697_i2c_read(aw8697, AW8697_REG_F_LRA_CONT_H, ®_val); + f0_reg = (reg_val << 8); + ret = aw8697_i2c_read(aw8697, AW8697_REG_F_LRA_CONT_L, ®_val); + f0_reg |= (reg_val << 0); + if (!f0_reg) { + pr_info("%s: not get f0_reg value is 0!\n", __func__); + return 0; + } + f0_tmp = 1000000000 / (f0_reg * aw8697->info.f0_coeff); + aw8697->cont_f0 = (unsigned int)f0_tmp; + aw8697->cont_f0 -= 12; + aw8697->f0 = aw8697->cont_f0; + pr_info("%s f0=%d\n", __func__, aw8697->cont_f0); + + return 0; +} +#endif + +#ifndef USE_CONT_F0_CALI +static int aw8697_haptic_read_beme(struct aw8697 *aw8697) +{ + int ret = 0; + unsigned char reg_val = 0; + pr_info("%s %d enter\n", __func__, __LINE__); + ret = aw8697_i2c_read(aw8697, AW8697_REG_WAIT_VOL_MP, ®_val); + aw8697->max_pos_beme = (reg_val << 0); + ret = aw8697_i2c_read(aw8697, AW8697_REG_WAIT_VOL_MN, ®_val); + aw8697->max_neg_beme = (reg_val << 0); + + pr_info("%s max_pos_beme=%d\n", __func__, aw8697->max_pos_beme); + pr_info("%s max_neg_beme=%d\n", __func__, aw8697->max_neg_beme); + + return 0; +} +#else +static int aw8697_haptic_read_cont_bemf(struct aw8697 *aw8697) +{ + int ret = 0; + unsigned char reg_val = 0; + unsigned int bemf = 0; + + ret = aw8697_i2c_read(aw8697, AW8697_REG_BEMF_VOL_H, ®_val); + bemf |= (reg_val << 8); + ret = aw8697_i2c_read(aw8697, AW8697_REG_BEMF_VOL_L, ®_val); + bemf |= (reg_val << 0); + + pr_info("%s bemf=%d\n", __func__, bemf); + + return 0; +} +#endif + +/***************************************************** + * + * rtp + * + *****************************************************/ +static void aw8697_haptic_set_rtp_aei(struct aw8697 *aw8697, bool flag) +{ + if (flag) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSINTM, + AW8697_BIT_SYSINTM_FF_AE_MASK, + AW8697_BIT_SYSINTM_FF_AE_EN); + } else { + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSINTM, + AW8697_BIT_SYSINTM_FF_AE_MASK, + AW8697_BIT_SYSINTM_FF_AE_OFF); + } +} + +static unsigned char aw8697_haptic_rtp_get_fifo_afi(struct aw8697 *aw8697) +{ + unsigned char ret = 0; + unsigned char reg_val = 0; + + if (aw8697->osc_cali_flag == 1) { + aw8697_i2c_read(aw8697, AW8697_REG_SYSST, ®_val); + reg_val &= AW8697_BIT_SYSST_FF_AFS; + ret = reg_val >> 3; + } else { + aw8697_i2c_read(aw8697, AW8697_REG_SYSINT, ®_val); + reg_val &= AW8697_BIT_SYSINT_FF_AFI; + ret = reg_val >> 3; + } + + return ret; +} + +/***************************************************** + * + * rtp + * + *****************************************************/ +static int aw8697_haptic_rtp_init(struct aw8697 *aw8697) +{ + unsigned int buf_len = 0; + unsigned int period_size = aw8697->ram.base_addr >> 2; + bool rtp_start = true; + pm_qos_add_request(&pm_qos_req_vb, PM_QOS_CPU_DMA_LATENCY, + PM_QOS_VALUE_VB); + aw8697->rtp_cnt = 0; + while ((!aw8697_haptic_rtp_get_fifo_afi(aw8697)) && + (aw8697->play_mode == AW8697_HAPTIC_RTP_MODE) && + !atomic_read(&aw8697->exit_in_rtp_loop)) { + if (aw8697->is_custom_wave == 0) { + if (rtp_start) { + if ((aw8697_rtp->len - aw8697->rtp_cnt) < + aw8697->ram.base_addr) + buf_len = aw8697_rtp->len - + aw8697->rtp_cnt; + else + buf_len = (aw8697->ram.base_addr); + aw8697_i2c_writes( + aw8697, AW8697_REG_RTP_DATA, + &aw8697_rtp->data[aw8697->rtp_cnt], + buf_len); + rtp_start = false; + } else { + if ((aw8697_rtp->len - aw8697->rtp_cnt) < + (aw8697->ram.base_addr >> 2)) { + buf_len = aw8697_rtp->len - + aw8697->rtp_cnt; + } else { + buf_len = (aw8697->ram.base_addr >> 2); + } + aw8697_i2c_writes( + aw8697, AW8697_REG_RTP_DATA, + &aw8697_rtp->data[aw8697->rtp_cnt], + buf_len); + } + aw8697->rtp_cnt += buf_len; + pr_info("%s update rtp_cnt = %d \n", __func__, + aw8697->rtp_cnt); + if (aw8697->rtp_cnt == aw8697_rtp->len) { + aw8697->rtp_cnt = 0; + aw8697_haptic_set_rtp_aei(aw8697, false); + pm_qos_remove_request(&pm_qos_req_vb); + return 0; + } + } else { + buf_len = read_rb(aw8697_rtp->data, period_size); + aw8697_i2c_writes(aw8697, AW8697_REG_RTP_DATA, + aw8697_rtp->data, buf_len); + if (buf_len < period_size) { + pr_info("%s: custom rtp update complete\n", + __func__); + aw8697->rtp_cnt = 0; + aw8697_haptic_set_rtp_aei(aw8697, false); + pm_qos_remove_request(&pm_qos_req_vb); + return 0; + } + } + } + if (aw8697->play_mode == AW8697_HAPTIC_RTP_MODE && + !atomic_read(&aw8697->exit_in_rtp_loop)) { + aw8697_haptic_set_rtp_aei(aw8697, true); + } + pr_info("%s: exit\n", __func__); + pm_qos_remove_request(&pm_qos_req_vb); + return 0; +} + +static int16_t aw8697_haptic_effect_strength(struct aw8697 *aw8697) +{ + pr_debug("%s enter\n", __func__); + pr_debug("%s: aw8697->play.vmax_mv =0x%x\n", __func__, + aw8697->play.vmax_mv); +#if 0 + switch (aw8697->play.vmax_mv) { + case AW8697_LIGHT_MAGNITUDE: + aw8697->level = 0x80; + break; + case AW8697_MEDIUM_MAGNITUDE: + aw8697->level = 0x50; + break; + case AW8697_STRONG_MAGNITUDE: + aw8697->level = 0x30; + break; + default: + break; + } +#else + if (aw8697->play.vmax_mv >= 0x7FFF) + aw8697->level = 0x80; /*128*/ + else if (aw8697->play.vmax_mv <= 0x3FFF) + aw8697->level = 0x1E; /*30*/ + else + aw8697->level = (aw8697->play.vmax_mv - 16383) / 128; + if (aw8697->level < 0x1E) + aw8697->level = 0x1E; /*30*/ +#endif + + pr_info("%s: aw8697->level =0x%x\n", __func__, aw8697->level); + return 0; +} + +static int aw8697_haptic_play_effect_seq(struct aw8697 *aw8697, + unsigned char flag) +{ + if (aw8697->effect_id > aw8697->info.effect_id_boundary) + return 0; + //printk("%s:aw8697->effect_id =%d\n", __func__, aw8697->effect_id); + //printk("%s:aw8697->activate_mode =%d\n", __func__, aw8697->activate_mode); + + if (flag) { + if (aw8697->activate_mode == AW8697_HAPTIC_ACTIVATE_RAM_MODE) { + aw8697_haptic_set_wav_seq(aw8697, 0x00, + (char)aw8697->effect_id + 1); + aw8697_haptic_set_wav_seq(aw8697, 0x01, 0x00); + aw8697_haptic_set_wav_loop(aw8697, 0x00, 0x00); + aw8697_haptic_play_mode(aw8697, AW8697_HAPTIC_RAM_MODE); + if (aw8697->info.bst_vol_ram <= AW8697_MAX_BST_VO) + aw8697_haptic_set_bst_vol( + aw8697, aw8697->info.bst_vol_ram); + else + aw8697_haptic_set_bst_vol(aw8697, aw8697->vmax); + aw8697_haptic_effect_strength(aw8697); + aw8697_haptic_set_gain(aw8697, aw8697->level); + aw8697_haptic_start(aw8697); + } + if (aw8697->activate_mode == + AW8697_HAPTIC_ACTIVATE_RAM_LOOP_MODE) { + aw8697_haptic_set_repeat_wav_seq( + aw8697, (aw8697->info.effect_id_boundary + 1)); + aw8697_haptic_play_repeat_seq(aw8697, true); + } + } + + return 0; +} + +static void aw8697_haptic_upload_lra(struct aw8697 *aw8697, unsigned char flag) +{ + if (flag) { + //printk("%s f0_cali_lra=%d\n", __func__, aw8697->f0_calib_data); + aw8697_i2c_write(aw8697, AW8697_REG_TRIM_LRA, + (char)aw8697->f0_calib_data); + } else { + //printk("%s rtp_cali_lra=%d\n", __func__, aw8697->lra_calib_data); + aw8697_i2c_write(aw8697, AW8697_REG_TRIM_LRA, + (char)aw8697->lra_calib_data); + } +} + +static int aw8697_clock_OSC_trim_calibration(unsigned long int theory_time, + unsigned long int real_time) +{ + unsigned int real_code = 0; + unsigned int LRA_TRIM_CODE = 0; + unsigned int DFT_LRA_TRIM_CODE = 0; + unsigned int Not_need_cali_threshold = + 10; /*0.1 percent not need calibrate*/ + + if (theory_time == real_time) { + pr_info("aw_osctheory_time == real_time:%ld theory_time = %ld not need to cali\n", + real_time, theory_time); + return 0; + } else if (theory_time < real_time) { + if ((real_time - theory_time) > (theory_time / 50)) { + pr_info("aw_osc(real_time - theory_time) > (theory_time/50) not to cali\n"); + return DFT_LRA_TRIM_CODE; + } + + if ((real_time - theory_time) < + (Not_need_cali_threshold * theory_time / 10000)) { + pr_info("aw_oscmicrosecond:%ld theory_time = %ld not need to cali\n", + real_time, theory_time); + return DFT_LRA_TRIM_CODE; + } + + real_code = ((real_time - theory_time) * 4000) / theory_time; + real_code = ((real_code % 10 < 5) ? 0 : 1) + real_code / 10; + real_code = 32 + real_code; + } else if (theory_time > real_time) { + if ((theory_time - real_time) > (theory_time / 50)) { + pr_info("aw_osc((theory_time - real_time) > (theory_time / 50)) not to cali\n"); + return DFT_LRA_TRIM_CODE; + } + if ((theory_time - real_time) < + (Not_need_cali_threshold * theory_time / 10000)) { + pr_info("aw_oscmicrosecond:%ld theory_time = %ld not need to cali\n", + real_time, theory_time); + return DFT_LRA_TRIM_CODE; + } + real_code = ((theory_time - real_time) * 4000) / theory_time; + real_code = ((real_code % 10 < 5) ? 0 : 1) + real_code / 10; + real_code = 32 - real_code; + } + if (real_code > 31) + LRA_TRIM_CODE = real_code - 32; + else + LRA_TRIM_CODE = real_code + 32; + pr_info("aw_oscmicrosecond:%ld theory_time = %ld real_code =0X%02X LRA_TRIM_CODE 0X%02X\n", + real_time, theory_time, real_code, LRA_TRIM_CODE); + + return LRA_TRIM_CODE; +} + +static int aw8697_rtp_trim_lra_calibration(struct aw8697 *aw8697) +{ + unsigned char reg_val = 0; + unsigned int fre_val = 0; + unsigned int theory_time = 0; + unsigned int lra_rtim_code = 0; + + aw8697_i2c_read(aw8697, AW8697_REG_PWMDBG, ®_val); + fre_val = (reg_val & 0x006f) >> 5; + + if (fre_val == 3) + theory_time = (aw8697->rtp_len / 12000) * 1000000; /*12K */ + if (fre_val == 2) + theory_time = (aw8697->rtp_len / 24000) * 1000000; /*24K */ + if (fre_val == 1 || fre_val == 0) + theory_time = (aw8697->rtp_len / 48000) * 1000000; /*48K */ + + printk("microsecond:%ld theory_time = %d\n", aw8697->microsecond, + theory_time); + + lra_rtim_code = aw8697_clock_OSC_trim_calibration(theory_time, + aw8697->microsecond); + if (lra_rtim_code > 0) { + aw8697->lra_calib_data = lra_rtim_code; + aw8697_i2c_write(aw8697, AW8697_REG_TRIM_LRA, + (char)lra_rtim_code); + } + return 0; +} +static unsigned char aw8697_haptic_osc_read_int(struct aw8697 *aw8697) +{ + unsigned char reg_val = 0; + + aw8697_i2c_read(aw8697, AW8697_REG_DBGSTAT, ®_val); + return reg_val; +} + +static int aw8697_rtp_osc_calibration(struct aw8697 *aw8697) +{ + const struct firmware *rtp_file; + int ret = -1; + unsigned int buf_len = 0; + unsigned char osc_int_state = 0; + aw8697->rtp_cnt = 0; + aw8697->timeval_flags = 1; + aw8697->osc_cali_flag = 1; + + pr_info("%s enter\n", __func__); + /* fw loaded */ + ret = request_firmware(&rtp_file, + aw8697_rtp_name[/*aw8697->rtp_file_num*/ 0], + aw8697->dev); + if (ret < 0) { + pr_err("%s: failed to read %s\n", __func__, + aw8697_rtp_name[/*aw8697->rtp_file_num*/ 0]); + return ret; + } + /*awinic add stop,for irq interrupt during calibrate*/ + aw8697_haptic_stop(aw8697); + aw8697->rtp_init = 0; + mutex_lock(&aw8697->rtp_lock); + vfree(aw8697_rtp); + aw8697_rtp = vmalloc(rtp_file->size + sizeof(int)); + if (!aw8697_rtp) { + release_firmware(rtp_file); + mutex_unlock(&aw8697->rtp_lock); + pr_err("%s: error allocating memory\n", __func__); + return -ENOMEM; + } + aw8697_rtp->len = rtp_file->size; + aw8697->rtp_len = rtp_file->size; + pr_info("%s: rtp file [%s] size = %d\n", __func__, + aw8697_rtp_name[/*aw8697->rtp_file_num*/ 0], aw8697_rtp->len); + memcpy(aw8697_rtp->data, rtp_file->data, rtp_file->size); + release_firmware(rtp_file); + mutex_unlock(&aw8697->rtp_lock); + + /* gain */ + aw8697_haptic_ram_vbat_comp(aw8697, false); + + /* rtp mode config */ + aw8697_haptic_play_mode(aw8697, AW8697_HAPTIC_RTP_MODE); + + aw8697_i2c_write_bits(aw8697, AW8697_REG_DBGCTRL, + AW8697_BIT_DBGCTRL_INT_MODE_MASK, + AW8697_BIT_DBGCTRL_INT_MODE_EDGE); + disable_irq(gpio_to_irq(aw8697->irq_gpio)); + /* haptic start */ + aw8697_haptic_start(aw8697); + pm_qos_add_request(&pm_qos_req_vb, PM_QOS_CPU_DMA_LATENCY, + PM_QOS_VALUE_VB); + while (1) { + if (!aw8697_haptic_rtp_get_fifo_afi(aw8697)) { + mutex_lock(&aw8697->rtp_lock); + if ((aw8697_rtp->len - aw8697->rtp_cnt) < + (aw8697->ram.base_addr >> 2)) + buf_len = aw8697_rtp->len - aw8697->rtp_cnt; + else + buf_len = (aw8697->ram.base_addr >> 2); + if (aw8697->rtp_cnt != aw8697_rtp->len) { + if (aw8697->timeval_flags == 1) { + do_gettimeofday(&aw8697->start); + aw8697->timeval_flags = 0; + } + aw8697_i2c_writes( + aw8697, AW8697_REG_RTP_DATA, + &aw8697_rtp->data[aw8697->rtp_cnt], + buf_len); + aw8697->rtp_cnt += buf_len; + } + mutex_unlock(&aw8697->rtp_lock); + } + osc_int_state = aw8697_haptic_osc_read_int(aw8697); + if (osc_int_state & AW8697_BIT_SYSINT_DONEI) { + do_gettimeofday(&aw8697->end); + pr_info("%s vincent playback done aw8697->rtp_cnt= %d \n", + __func__, aw8697->rtp_cnt); + break; + } + + do_gettimeofday(&aw8697->end); + aw8697->microsecond = + (aw8697->end.tv_sec - aw8697->start.tv_sec) * 1000000 + + (aw8697->end.tv_usec - aw8697->start.tv_usec); + if (aw8697->microsecond > OSC_CALIBRATION_T_LENGTH) { + pr_info("%s vincent time out aw8697->rtp_cnt %d osc_int_state %02x\n", + __func__, aw8697->rtp_cnt, osc_int_state); + break; + } + } + pm_qos_remove_request(&pm_qos_req_vb); + enable_irq(gpio_to_irq(aw8697->irq_gpio)); + + aw8697->osc_cali_flag = 0; + aw8697->microsecond = + (aw8697->end.tv_sec - aw8697->start.tv_sec) * 1000000 + + (aw8697->end.tv_usec - aw8697->start.tv_usec); + /*calibration osc*/ + pr_info("%s 2018_microsecond:%ld \n", __func__, aw8697->microsecond); + pr_info("%s exit\n", __func__); + return 0; +} + +static void aw8697_rtp_work_routine(struct work_struct *work) +{ + const struct firmware *rtp_file; + int ret = -1; + struct aw8697 *aw8697 = container_of(work, struct aw8697, rtp_work); + + if ((aw8697->effect_id < aw8697->info.effect_id_boundary) && + (aw8697->effect_id > aw8697->info.effect_max)) + return; + + pr_info("%s: effect_id = %d state=%d activate_mode = %d\n", __func__, + aw8697->effect_id, aw8697->state, aw8697->activate_mode); + mutex_lock(&aw8697->lock); + aw8697_haptic_upload_lra(aw8697, false); + aw8697_haptic_set_rtp_aei(aw8697, false); + aw8697_interrupt_clear(aw8697); + //wait for irq to exit + atomic_set(&aw8697->exit_in_rtp_loop, 1); + while (atomic_read(&aw8697->is_in_rtp_loop)) { + pr_info("%s goint to waiting irq exit\n", __func__); + mutex_unlock(&aw8697->lock); + ret = wait_event_interruptible( + aw8697->wait_q, + atomic_read(&aw8697->is_in_rtp_loop) == 0); + pr_info("%s wakeup \n", __func__); + mutex_lock(&aw8697->lock); + if (ret == -ERESTARTSYS) { + atomic_set(&aw8697->exit_in_rtp_loop, 0); + wake_up_interruptible(&aw8697->stop_wait_q); + mutex_unlock(&aw8697->lock); + pr_err("%s wake up by signal return erro\n", __func__); + return; + } + } + atomic_set(&aw8697->exit_in_rtp_loop, 0); + wake_up_interruptible(&aw8697->stop_wait_q); + //how to force exit this call + if (aw8697->is_custom_wave == 1 && aw8697->state) { + pr_err("%s buffer size %d, availbe size %d \n", __func__, + aw8697->ram.base_addr >> 2, get_rb_avalible_size()); + while (get_rb_avalible_size() < aw8697->ram.base_addr && + !rb_shoule_exit()) { + mutex_unlock(&aw8697->lock); + ret = wait_event_interruptible( + aw8697->stop_wait_q, (get_rb_avalible_size() >= + aw8697->ram.base_addr) || + rb_shoule_exit()); + mutex_lock(&aw8697->lock); + pr_info("%s wakeup \n", __func__); + pr_err("%s after wakeup sbuffer size %d, availbe size %d \n", + __func__, aw8697->ram.base_addr >> 2, + get_rb_avalible_size()); + if (ret == -ERESTARTSYS) { + mutex_unlock(&aw8697->lock); + pr_err("%s wake up by signal return erro\n", + __func__); + return; + } + } + } + aw8697_haptic_stop(aw8697); + + if (aw8697->state) { + pm_stay_awake(aw8697->dev); + if (aw8697->info.bst_vol_ram <= AW8697_MAX_BST_VO) + aw8697_haptic_set_bst_vol(aw8697, + aw8697->info.bst_vol_ram); + else + aw8697_haptic_set_bst_vol(aw8697, aw8697->vmax); + aw8697_haptic_effect_strength(aw8697); + aw8697_haptic_set_gain(aw8697, aw8697->level); + aw8697->rtp_init = 0; + if (aw8697->is_custom_wave == 0) { + aw8697->rtp_file_num = aw8697->effect_id - + aw8697->info.effect_id_boundary; + printk("%s: aw8697->rtp_file_num =%d\n", __func__, + aw8697->rtp_file_num); + if (aw8697->rtp_file_num < 0) + aw8697->rtp_file_num = 0; + if (aw8697->rtp_file_num > + ((sizeof(aw8697_rtp_name) / AW8697_RTP_NAME_MAX) - + 1)) + aw8697->rtp_file_num = + (sizeof(aw8697_rtp_name) / + AW8697_RTP_NAME_MAX) - + 1; + + /* fw loaded */ + ret = request_firmware( + &rtp_file, + aw8697_rtp_name[aw8697->rtp_file_num], + aw8697->dev); + if (ret < 0) { + pr_err("%s: failed to read %s\n", __func__, + aw8697_rtp_name[aw8697->rtp_file_num]); + pm_relax(aw8697->dev); + mutex_unlock(&aw8697->lock); + return; + } + + vfree(aw8697_rtp); + aw8697_rtp = vmalloc(rtp_file->size + sizeof(int)); + if (!aw8697_rtp) { + release_firmware(rtp_file); + pr_err("%s: error allocating memory\n", + __func__); + pm_relax(aw8697->dev); + mutex_unlock(&aw8697->lock); + return; + } + aw8697_rtp->len = rtp_file->size; + pr_info("%s: rtp file [%s] size = %d\n", __func__, + aw8697_rtp_name[aw8697->rtp_file_num], + aw8697_rtp->len); + memcpy(aw8697_rtp->data, rtp_file->data, + rtp_file->size); + release_firmware(rtp_file); + } else { + vfree(aw8697_rtp); + aw8697_rtp = vmalloc(aw8697->ram.base_addr >> 2); + if (!aw8697_rtp) { + pr_err("%s: error allocating memory\n", + __func__); + pm_relax(aw8697->dev); + mutex_unlock(&aw8697->lock); + return; + } + } + aw8697->rtp_init = 1; + + /* rtp mode config */ + aw8697_haptic_play_mode(aw8697, AW8697_HAPTIC_RTP_MODE); + + /* haptic start */ + aw8697_haptic_start(aw8697); + + aw8697_haptic_rtp_init(aw8697); + } else { + aw8697->rtp_cnt = 0; + aw8697->rtp_init = 0; + pm_relax(aw8697->dev); + } + mutex_unlock(&aw8697->lock); +} + +static enum hrtimer_restart +aw8697_haptic_audio_timer_func(struct hrtimer *timer) +{ + struct aw8697 *aw8697 = + container_of(timer, struct aw8697, haptic_audio.timer); + + pr_debug("%s enter\n", __func__); + //schedule_work(&aw8697->haptic_audio.work); + queue_work(aw8697->work_queue, &aw8697->haptic_audio.work); + + hrtimer_start( + &aw8697->haptic_audio.timer, + ktime_set(aw8697->haptic_audio.timer_val / 1000000, + (aw8697->haptic_audio.timer_val % 1000000) * 1000), + HRTIMER_MODE_REL); + return HRTIMER_NORESTART; +} + +static void aw8697_haptic_audio_work_routine(struct work_struct *work) +{ + struct aw8697 *aw8697 = + container_of(work, struct aw8697, haptic_audio.work); + + pr_info("%s enter\n", __func__); + + mutex_lock(&aw8697->haptic_audio.lock); + memcpy(&aw8697->haptic_audio.ctr, + &aw8697->haptic_audio.data[aw8697->haptic_audio.cnt], + sizeof(struct haptic_ctr)); + pr_debug("%s: cnt=%d, cmd=%d, play=%d, wavseq=%d, loop=%d, gain=%d\n", + __func__, aw8697->haptic_audio.cnt, + aw8697->haptic_audio.ctr.cmd, aw8697->haptic_audio.ctr.play, + aw8697->haptic_audio.ctr.wavseq, aw8697->haptic_audio.ctr.loop, + aw8697->haptic_audio.ctr.gain); + mutex_unlock(&aw8697->haptic_audio.lock); + if (AW8697_HAPTIC_CMD_ENABLE == aw8697->haptic_audio.ctr.cmd) { + if (AW8697_HAPTIC_PLAY_ENABLE == + aw8697->haptic_audio.ctr.play) { + pr_info("%s: haptic_audio_play_start\n", __func__); + mutex_lock(&aw8697->lock); + aw8697_haptic_stop(aw8697); + aw8697_haptic_play_mode(aw8697, AW8697_HAPTIC_RAM_MODE); + + aw8697_haptic_set_wav_seq( + aw8697, 0x00, aw8697->haptic_audio.ctr.wavseq); + aw8697_haptic_set_wav_seq(aw8697, 0x01, 0x00); + + aw8697_haptic_set_wav_loop( + aw8697, 0x00, aw8697->haptic_audio.ctr.loop); + + aw8697_haptic_set_gain(aw8697, + aw8697->haptic_audio.ctr.gain); + + aw8697_haptic_start(aw8697); + mutex_unlock(&aw8697->lock); + } else if (AW8697_HAPTIC_PLAY_STOP == + aw8697->haptic_audio.ctr.play) { + mutex_lock(&aw8697->lock); + aw8697_haptic_stop(aw8697); + mutex_unlock(&aw8697->lock); + } else if (AW8697_HAPTIC_PLAY_GAIN == + aw8697->haptic_audio.ctr.play) { + mutex_lock(&aw8697->lock); + aw8697_haptic_set_gain(aw8697, + aw8697->haptic_audio.ctr.gain); + mutex_unlock(&aw8697->lock); + } + mutex_lock(&aw8697->haptic_audio.lock); + memset(&aw8697->haptic_audio.data[aw8697->haptic_audio.cnt], 0, + sizeof(struct haptic_ctr)); + mutex_unlock(&aw8697->haptic_audio.lock); + } + + mutex_lock(&aw8697->haptic_audio.lock); + aw8697->haptic_audio.cnt++; + if (aw8697->haptic_audio.data[aw8697->haptic_audio.cnt].cmd == 0) { + aw8697->haptic_audio.cnt = 0; + pr_debug("%s: haptic play buffer restart\n", __func__); + } + mutex_unlock(&aw8697->haptic_audio.lock); +} + +/***************************************************** + * + * haptic cont + * + *****************************************************/ +static int aw8697_haptic_cont(struct aw8697 *aw8697) +{ + pr_info("%s enter\n", __func__); + + /* work mode */ + aw8697_haptic_play_mode(aw8697, AW8697_HAPTIC_CONT_MODE); + + /* preset f0 */ + aw8697_haptic_set_f0_preset(aw8697); + + /* lpf */ + aw8697_i2c_write_bits(aw8697, AW8697_REG_DATCTRL, + AW8697_BIT_DATCTRL_FC_MASK, + AW8697_BIT_DATCTRL_FC_1000HZ); + aw8697_i2c_write_bits(aw8697, AW8697_REG_DATCTRL, + AW8697_BIT_DATCTRL_LPF_ENABLE_MASK, + AW8697_BIT_DATCTRL_LPF_ENABLE); + + /* cont config */ + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_ZC_DETEC_MASK, + AW8697_BIT_CONT_CTRL_ZC_DETEC_ENABLE); + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_WAIT_PERIOD_MASK, + AW8697_BIT_CONT_CTRL_WAIT_1PERIOD); + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_MODE_MASK, + AW8697_BIT_CONT_CTRL_BY_GO_SIGNAL); + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_EN_CLOSE_MASK, + AW8697_CONT_PLAYBACK_MODE); + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_F0_DETECT_MASK, + AW8697_BIT_CONT_CTRL_F0_DETECT_DISABLE); + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_O2C_MASK, + AW8697_BIT_CONT_CTRL_O2C_DISABLE); + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_AUTO_BRK_MASK, + AW8697_BIT_CONT_CTRL_AUTO_BRK_ENABLE); + + /* TD time */ + aw8697_i2c_write(aw8697, AW8697_REG_TD_H, + (unsigned char)(aw8697->info.cont_td >> 8)); + aw8697_i2c_write(aw8697, AW8697_REG_TD_L, + (unsigned char)(aw8697->info.cont_td >> 0)); + aw8697_i2c_write(aw8697, AW8697_REG_TSET, aw8697->info.tset); + + /* zero cross */ + aw8697_i2c_write(aw8697, AW8697_REG_ZC_THRSH_H, + (unsigned char)(aw8697->info.cont_zc_thr >> 8)); + aw8697_i2c_write(aw8697, AW8697_REG_ZC_THRSH_L, + (unsigned char)(aw8697->info.cont_zc_thr >> 0)); + + aw8697_i2c_write_bits(aw8697, AW8697_REG_BEMF_NUM, + AW8697_BIT_BEMF_NUM_BRK_MASK, + aw8697->info.cont_num_brk); + aw8697_i2c_write(aw8697, AW8697_REG_TIME_NZC, 0x23); // 35*171us=5.985ms + + /* f0 driver level */ + aw8697_i2c_write(aw8697, AW8697_REG_DRV_LVL, aw8697->info.cont_drv_lvl); + aw8697_i2c_write(aw8697, AW8697_REG_DRV_LVL_OV, + aw8697->info.cont_drv_lvl_ov); + + /* cont play go */ + aw8697_haptic_play_go(aw8697, true); + + return 0; +} + +#ifndef USE_CONT_F0_CALI +/***************************************************** + * + * haptic f0 cali + * + *****************************************************/ +static int aw8697_haptic_get_f0(struct aw8697 *aw8697) +{ + int ret = 0; + /*unsigned char i = 0; */ + unsigned char reg_val = 0; + unsigned char f0_pre_num = 0; + unsigned char f0_wait_num = 0; + unsigned char f0_repeat_num = 0; + unsigned char f0_trace_num = 0; + unsigned int t_f0_ms = 0; + unsigned int t_f0_trace_ms = 0; + /*unsigned int f0_cali_cnt = 50; */ + + pr_info("%s enter\n", __func__); + + aw8697->f0 = aw8697->info.f0_pre; + + /* f0 calibrate work mode */ + aw8697_haptic_stop(aw8697); + aw8697_haptic_play_mode(aw8697, AW8697_HAPTIC_CONT_MODE); + + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_EN_CLOSE_MASK, + AW8697_BIT_CONT_CTRL_OPEN_PLAYBACK); + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_F0_DETECT_MASK, + AW8697_BIT_CONT_CTRL_F0_DETECT_ENABLE); + + /* LPF */ + aw8697_i2c_write_bits(aw8697, AW8697_REG_DATCTRL, + AW8697_BIT_DATCTRL_FC_MASK, + AW8697_BIT_DATCTRL_FC_1000HZ); + aw8697_i2c_write_bits(aw8697, AW8697_REG_DATCTRL, + AW8697_BIT_DATCTRL_LPF_ENABLE_MASK, + AW8697_BIT_DATCTRL_LPF_ENABLE); + + /* LRA OSC Source */ + if (aw8697->f0_cali_flag == AW8697_HAPTIC_CALI_F0) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_ANACTRL, + AW8697_BIT_ANACTRL_LRA_SRC_MASK, + AW8697_BIT_ANACTRL_LRA_SRC_REG); + } else { + aw8697_i2c_write_bits(aw8697, AW8697_REG_ANACTRL, + AW8697_BIT_ANACTRL_LRA_SRC_MASK, + AW8697_BIT_ANACTRL_LRA_SRC_EFUSE); + } + + /* preset f0 */ + aw8697_haptic_set_f0_preset(aw8697); + + /* f0 driver level */ + aw8697_i2c_write(aw8697, AW8697_REG_DRV_LVL, aw8697->info.cont_drv_lvl); + + /* f0 trace parameter */ + f0_pre_num = aw8697->info.f0_trace_parameter[0]; + f0_wait_num = aw8697->info.f0_trace_parameter[1]; + f0_repeat_num = aw8697->info.f0_trace_parameter[2]; + f0_trace_num = aw8697->info.f0_trace_parameter[3]; + aw8697_i2c_write(aw8697, AW8697_REG_NUM_F0_1, + (f0_pre_num << 4) | (f0_wait_num << 0)); + aw8697_i2c_write(aw8697, AW8697_REG_NUM_F0_2, (f0_repeat_num << 0)); + aw8697_i2c_write(aw8697, AW8697_REG_NUM_F0_3, (f0_trace_num << 0)); + + /* clear aw8697 interrupt */ + ret = aw8697_i2c_read(aw8697, AW8697_REG_SYSINT, ®_val); + + /* play go and start f0 calibration */ + aw8697_haptic_play_go(aw8697, true); + + /* f0 trace time */ + t_f0_ms = 1000 * 10 / aw8697->info.f0_pre; + t_f0_trace_ms = + t_f0_ms * (f0_pre_num + f0_wait_num + + (f0_trace_num + f0_wait_num) * (f0_repeat_num - 1)) + + 50; + msleep(t_f0_trace_ms); + +#if 0 + for (i = 0; i < f0_cali_cnt; i++) { + mdelay(200); + ret = aw8697_i2c_read(aw8697, AW8697_REG_SYSINT, ®_val); + /* f0 calibrate done */ + if (reg_val & 0x01) { + aw8697_haptic_read_f0(aw8697); + aw8697_haptic_read_beme(aw8697); + break; + } + msleep(200); + pr_info("%s f0 cali sleep 10ms\n", __func__); + } + + if (i == f0_cali_cnt) { + ret = -1; + } else { + ret = 0; + } +#endif + + aw8697_haptic_read_f0(aw8697); + aw8697_haptic_read_beme(aw8697); + /* restore default config */ + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_EN_CLOSE_MASK, + AW8697_CONT_PLAYBACK_MODE); + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_F0_DETECT_MASK, + AW8697_BIT_CONT_CTRL_F0_DETECT_DISABLE); + + return ret; +} +#else +/***************************************************** + * + * haptic cont mode f0 cali + * + *****************************************************/ +static int aw8697_haptic_get_f0(struct aw8697 *aw8697) +{ + int ret = 0; + unsigned char i = 0; + unsigned char reg_val = 0; + unsigned int t_f0_trace_ms = 0; + unsigned int f0_cali_cnt = 50; + + pr_info("%s enter\n", __func__); + + aw8697->f0 = aw8697->info.f0_pre; + + /* f0 calibrate work mode */ + aw8697_haptic_stop(aw8697); + aw8697_haptic_play_mode(aw8697, AW8697_HAPTIC_CONT_MODE); + + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_MODE_MASK, + AW8697_BIT_CONT_CTRL_BY_DRV_TIME); + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_EN_CLOSE_MASK, + AW8697_BIT_CONT_CTRL_OPEN_PLAYBACK); + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_EN_CLOSE_MASK, + AW8697_BIT_CONT_CTRL_CLOSE_PLAYBACK); + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_F0_DETECT_MASK, + AW8697_BIT_CONT_CTRL_F0_DETECT_DISABLE); + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_AUTO_BRK_MASK, + AW8697_BIT_CONT_CTRL_AUTO_BRK_DISABLE); + + /* LPF */ + //aw8697_i2c_write_bits(aw8697, AW8697_REG_DATCTRL, + // AW8697_BIT_DATCTRL_FC_MASK, AW8697_BIT_DATCTRL_FC_1000HZ); + //aw8697_i2c_write_bits(aw8697, AW8697_REG_DATCTRL, + // AW8697_BIT_DATCTRL_LPF_ENABLE_MASK, AW8697_BIT_DATCTRL_LPF_ENABLE); + + /* LRA OSC Source */ + if (aw8697->f0_cali_flag == AW8697_HAPTIC_CALI_F0) { + aw8697_i2c_write_bits(aw8697, AW8697_REG_ANACTRL, + AW8697_BIT_ANACTRL_LRA_SRC_MASK, + AW8697_BIT_ANACTRL_LRA_SRC_REG); + } else { + aw8697_i2c_write_bits(aw8697, AW8697_REG_ANACTRL, + AW8697_BIT_ANACTRL_LRA_SRC_MASK, + AW8697_BIT_ANACTRL_LRA_SRC_EFUSE); + } + + /* f0 driver level */ + aw8697_i2c_write(aw8697, AW8697_REG_DRV_LVL, aw8697->info.cont_drv_lvl); + aw8697_i2c_write(aw8697, AW8697_REG_DRV_LVL_OV, + aw8697->info.cont_drv_lvl_ov); + + /* TD time */ + aw8697_i2c_write(aw8697, AW8697_REG_TD_H, aw8697->info.cont_td >> 8); + aw8697_i2c_write(aw8697, AW8697_REG_TD_L, aw8697->info.cont_td); + aw8697_i2c_write(aw8697, AW8697_REG_TSET, aw8697->info.tset); + + /* drive time */ + aw8697_i2c_write(aw8697, AW8697_REG_DRV_TIME, 0x75); + + /* preset f0 */ + aw8697_haptic_set_f0_preset(aw8697); + + /* clear aw8697 interrupt */ + ret = aw8697_i2c_read(aw8697, AW8697_REG_SYSINT, ®_val); + + /* play go and start f0 calibration */ + aw8697_haptic_play_go(aw8697, true); + + /* f0 trace time */ + t_f0_trace_ms = 0xfe * 684 / 1000; + msleep(t_f0_trace_ms); + + for (i = 0; i < f0_cali_cnt; i++) { + ret = aw8697_i2c_read(aw8697, AW8697_REG_SYSINT, ®_val); + /* f0 calibrate done */ + if (reg_val & 0x01) { + aw8697_haptic_read_cont_f0(aw8697); + aw8697_haptic_read_cont_bemf(aw8697); + break; + } + msleep(10); + pr_info("%s f0 cali sleep 10ms\n", __func__); + } + + if (i == f0_cali_cnt) { + ret = -1; + } else { + ret = 0; + } + + /* restore default config */ + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_EN_CLOSE_MASK, + AW8697_CONT_PLAYBACK_MODE); + aw8697_i2c_write_bits(aw8697, AW8697_REG_CONT_CTRL, + AW8697_BIT_CONT_CTRL_F0_DETECT_MASK, + AW8697_BIT_CONT_CTRL_F0_DETECT_DISABLE); + + return ret; +} +#endif + +static int aw8697_haptic_f0_calibration(struct aw8697 *aw8697) +{ + int ret = 0; + unsigned char reg_val = 0; + unsigned int f0_limit = 0; + char f0_cali_lra = 0; + int f0_cali_step = 0; + + pr_info("%s enter\n", __func__); + + aw8697->f0_cali_flag = AW8697_HAPTIC_CALI_F0; + + aw8697_i2c_write(aw8697, AW8697_REG_TRIM_LRA, 0x00); + if (aw8697_haptic_get_f0(aw8697)) { + pr_err("%s get f0 error, user defafult f0\n", __func__); + } else { + /* max and min limit */ + f0_limit = aw8697->f0; + if (aw8697->f0 * 100 < + aw8697->info.f0_pre * (100 - aw8697->info.f0_cali_percen)) { + f0_limit = aw8697->info.f0_pre; + } + if (aw8697->f0 * 100 > + aw8697->info.f0_pre * (100 + aw8697->info.f0_cali_percen)) { + f0_limit = aw8697->info.f0_pre; + } + + /* calculate cali step */ + f0_cali_step = 100000 * + ((int)f0_limit - (int)aw8697->info.f0_pre) / + ((int)f0_limit * 25); + pr_info("%s line=%d f0_cali_step=%d\n", __func__, __LINE__, + f0_cali_step); + pr_info("%s line=%d f0_limit=%d\n", __func__, __LINE__, + (int)f0_limit); + pr_info("%s line=%d aw8697->info.f0_pre=%d\n", __func__, + __LINE__, (int)aw8697->info.f0_pre); + + if (f0_cali_step >= 0) { /*f0_cali_step >= 0 */ + if (f0_cali_step % 10 >= 5) { + f0_cali_step = f0_cali_step / 10 + 1 + 32; + } else { + f0_cali_step = f0_cali_step / 10 + 32; + } + } else { /*f0_cali_step < 0 */ + if (f0_cali_step % 10 <= -5) { + f0_cali_step = 32 + (f0_cali_step / 10 - 1); + } else { + f0_cali_step = 32 + f0_cali_step / 10; + } + } + + if (f0_cali_step > 31) { + f0_cali_lra = (char)f0_cali_step - 32; + } else { + f0_cali_lra = (char)f0_cali_step + 32; + } + aw8697->f0_calib_data = (int)f0_cali_lra; + printk("%s f0_cali_lra=%d\n", __func__, (int)f0_cali_lra); + + /* update cali step */ + aw8697_i2c_write(aw8697, AW8697_REG_TRIM_LRA, + (char)f0_cali_lra); + aw8697_i2c_read(aw8697, AW8697_REG_TRIM_LRA, ®_val); + pr_info("%s final trim_lra=0x%02x\n", __func__, reg_val); + } + + /* restore default work mode */ + aw8697_haptic_play_mode(aw8697, AW8697_HAPTIC_STANDBY_MODE); + aw8697->play_mode = AW8697_HAPTIC_RAM_MODE; + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_PLAY_MODE_MASK, + AW8697_BIT_SYSCTRL_PLAY_MODE_RAM); + aw8697_haptic_stop(aw8697); + + return ret; +} + +/***************************************************** + * + * haptic fops + * + *****************************************************/ +static int aw8697_file_open(struct inode *inode, struct file *file) +{ + if (!try_module_get(THIS_MODULE)) + return -ENODEV; + pr_info("%s enter\n", __func__); + file->private_data = (void *)g_aw8697; + + return 0; +} + +static int aw8697_file_release(struct inode *inode, struct file *file) +{ + file->private_data = (void *)NULL; + pr_info("%s enter\n", __func__); + module_put(THIS_MODULE); + + return 0; +} + +static long aw8697_file_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct aw8697 *aw8697 = (struct aw8697 *)file->private_data; + + int ret = 0; + pr_info("%s enter\n", __func__); + dev_info(aw8697->dev, "%s: cmd=0x%x, arg=0x%lx\n", __func__, cmd, arg); + + mutex_lock(&aw8697->lock); + + if (_IOC_TYPE(cmd) != AW8697_HAPTIC_IOCTL_MAGIC) { + dev_err(aw8697->dev, "%s: cmd magic err\n", __func__); + return -EINVAL; + } + + switch (cmd) { + default: + dev_err(aw8697->dev, "%s, unknown cmd\n", __func__); + break; + } + + mutex_unlock(&aw8697->lock); + + return ret; +} + +static ssize_t aw8697_file_read(struct file *filp, char *buff, size_t len, + loff_t *offset) +{ + struct aw8697 *aw8697 = (struct aw8697 *)filp->private_data; + int ret = 0; + int i = 0; + unsigned char reg_val = 0; + unsigned char *pbuff = NULL; + pr_info("%s enter\n", __func__); + mutex_lock(&aw8697->lock); + + dev_info(aw8697->dev, "%s: len=%zu\n", __func__, len); + + switch (aw8697->fileops.cmd) { + case AW8697_HAPTIC_CMD_READ_REG: + pbuff = (unsigned char *)kzalloc(len, GFP_KERNEL); + if (pbuff != NULL) { + for (i = 0; i < len; i++) { + aw8697_i2c_read(aw8697, aw8697->fileops.reg + i, + ®_val); + pbuff[i] = reg_val; + } + for (i = 0; i < len; i++) { + dev_info(aw8697->dev, "%s: pbuff[%d]=0x%02x\n", + __func__, i, pbuff[i]); + } + ret = copy_to_user(buff, pbuff, len); + if (ret) { + dev_err(aw8697->dev, "%s: copy to user fail\n", + __func__); + } + kfree(pbuff); + } else { + dev_err(aw8697->dev, "%s: alloc memory fail\n", + __func__); + } + break; + default: + dev_err(aw8697->dev, "%s, unknown cmd %d \n", __func__, + aw8697->fileops.cmd); + break; + } + + mutex_unlock(&aw8697->lock); + + return len; +} + +static ssize_t aw8697_file_write(struct file *filp, const char *buff, + size_t len, loff_t *off) +{ + struct aw8697 *aw8697 = (struct aw8697 *)filp->private_data; + int i = 0; + int ret = 0; + unsigned char *pbuff = NULL; + pr_info("%s enter\n", __func__); + pbuff = (unsigned char *)kzalloc(len, GFP_KERNEL); + if (pbuff == NULL) { + dev_err(aw8697->dev, "%s: alloc memory fail\n", __func__); + return len; + } + ret = copy_from_user(pbuff, buff, len); + if (ret) { + dev_err(aw8697->dev, "%s: copy from user fail\n", __func__); + return len; + } + + for (i = 0; i < len; i++) { + dev_info(aw8697->dev, "%s: pbuff[%d]=0x%02x\n", __func__, i, + pbuff[i]); + } + + mutex_lock(&aw8697->lock); + + aw8697->fileops.cmd = pbuff[0]; + + switch (aw8697->fileops.cmd) { + case AW8697_HAPTIC_CMD_READ_REG: + if (len == 2) { + aw8697->fileops.reg = pbuff[1]; + } else { + dev_err(aw8697->dev, "%s: read cmd len %zu err\n", + __func__, len); + } + break; + case AW8697_HAPTIC_CMD_WRITE_REG: + if (len > 2) { + for (i = 0; i < len - 2; i++) { + dev_info(aw8697->dev, + "%s: write reg0x%02x=0x%02x\n", + __func__, pbuff[1] + i, pbuff[i + 2]); + aw8697_i2c_write(aw8697, pbuff[1] + i, + pbuff[2 + i]); + } + } else { + dev_err(aw8697->dev, "%s: write cmd len %zu err\n", + __func__, len); + } + break; + default: + dev_err(aw8697->dev, "%s, unknown cmd %d \n", __func__, + aw8697->fileops.cmd); + break; + } + + mutex_unlock(&aw8697->lock); + + if (pbuff != NULL) { + kfree(pbuff); + } + return len; +} + +static struct file_operations fops = { + .owner = THIS_MODULE, + .read = aw8697_file_read, + .write = aw8697_file_write, + .unlocked_ioctl = aw8697_file_unlocked_ioctl, + .open = aw8697_file_open, + .release = aw8697_file_release, +}; + +static struct miscdevice aw8697_haptic_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = AW8697_HAPTIC_NAME, + .fops = &fops, +}; + +static int aw8697_haptic_init(struct aw8697 *aw8697) +{ + int ret = 0; + unsigned char i = 0; + unsigned char reg_val = 0; + unsigned char bemf_config = 0; + + pr_info("%s enter\n", __func__); + ret = misc_register(&aw8697_haptic_misc); + if (ret) { + dev_err(aw8697->dev, "%s: misc fail: %d\n", __func__, ret); + return ret; + } + + /* haptic audio */ + aw8697->haptic_audio.delay_val = 1; + aw8697->haptic_audio.timer_val = 21318; + + hrtimer_init(&aw8697->haptic_audio.timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); + aw8697->haptic_audio.timer.function = aw8697_haptic_audio_timer_func; + INIT_WORK(&aw8697->haptic_audio.work, aw8697_haptic_audio_work_routine); + + mutex_init(&aw8697->haptic_audio.lock); + + /* haptic init */ + mutex_lock(&aw8697->lock); + + aw8697->activate_mode = aw8697->info.mode; + aw8697->osc_cali_run = 0; + ret = aw8697_i2c_read(aw8697, AW8697_REG_WAVSEQ1, ®_val); + aw8697->index = reg_val & 0x7F; + ret = aw8697_i2c_read(aw8697, AW8697_REG_DATDBG, ®_val); + aw8697->gain = reg_val & 0xFF; + ret = aw8697_i2c_read(aw8697, AW8697_REG_BSTDBG4, ®_val); + aw8697->vmax = (reg_val >> 1) & 0x1F; + for (i = 0; i < AW8697_SEQUENCER_SIZE; i++) { + ret = aw8697_i2c_read(aw8697, AW8697_REG_WAVSEQ1 + i, ®_val); + aw8697->seq[i] = reg_val; + } + + aw8697_haptic_play_mode(aw8697, AW8697_HAPTIC_STANDBY_MODE); + + aw8697_haptic_set_pwm(aw8697, AW8697_PWM_24K); + + aw8697_i2c_write(aw8697, AW8697_REG_BSTDBG1, aw8697->info.bstdbg[0]); + aw8697_i2c_write(aw8697, AW8697_REG_BSTDBG2, aw8697->info.bstdbg[1]); + aw8697_i2c_write(aw8697, AW8697_REG_BSTDBG3, aw8697->info.bstdbg[2]); + aw8697_i2c_write(aw8697, AW8697_REG_TSET, aw8697->info.tset); + aw8697_i2c_write(aw8697, AW8697_REG_R_SPARE, aw8697->info.r_spare); + + aw8697_i2c_write_bits(aw8697, AW8697_REG_ANADBG, + AW8697_BIT_ANADBG_IOC_MASK, + AW8697_BIT_ANADBG_IOC_4P65A); + + aw8697_haptic_set_bst_peak_cur(aw8697, AW8697_DEFAULT_PEAKCUR); + + aw8697_haptic_swicth_motorprotect_config(aw8697, 0x00, 0x00); + + aw8697_haptic_auto_boost_config(aw8697, false); + + if ((aw8697->info.trig_config[0][0] == 1) || + (aw8697->info.trig_config[1][0] == 1) || + (aw8697->info.trig_config[2][0] == 1)) { + aw8697_haptic_trig_param_init(aw8697); + aw8697_haptic_trig_param_config(aw8697); + } + + aw8697_haptic_offset_calibration(aw8697); + + /* vbat compensation */ + aw8697_haptic_cont_vbat_mode(aw8697, + AW8697_HAPTIC_CONT_VBAT_HW_COMP_MODE); + aw8697->ram_vbat_comp = AW8697_HAPTIC_RAM_VBAT_COMP_ENABLE; + + mutex_unlock(&aw8697->lock); + + /* f0 calibration */ + mutex_lock(&aw8697->lock); +#ifndef USE_CONT_F0_CALI + aw8697_haptic_f0_calibration(aw8697); +#endif + mutex_unlock(&aw8697->lock); + /* beme config */ + bemf_config = aw8697->info.bemf_config[0]; + aw8697_i2c_write(aw8697, AW8697_REG_BEMF_VTHH_H, bemf_config); + bemf_config = aw8697->info.bemf_config[1]; + aw8697_i2c_write(aw8697, AW8697_REG_BEMF_VTHH_L, bemf_config); + bemf_config = aw8697->info.bemf_config[2]; + aw8697_i2c_write(aw8697, AW8697_REG_BEMF_VTHL_H, bemf_config); + bemf_config = aw8697->info.bemf_config[3]; + aw8697_i2c_write(aw8697, AW8697_REG_BEMF_VTHL_L, bemf_config); + return ret; +} + +/***************************************************** + * + * vibrator + * + *****************************************************/ +static enum hrtimer_restart qti_hap_stop_timer(struct hrtimer *timer) +{ + struct aw8697 *aw8697 = container_of(timer, struct aw8697, stop_timer); + int rc; + + pr_info("%s enter\n", __func__); + aw8697->play.length_us = 0; + rc = aw8697_haptic_play_go(aw8697, + false); // qti_haptics_play(aw8697, false); + if (rc < 0) + dev_err(aw8697->dev, "Stop playing failed, rc=%d\n", rc); + + return HRTIMER_NORESTART; +} + +static enum hrtimer_restart qti_hap_disable_timer(struct hrtimer *timer) +{ + struct aw8697 *aw8697 = + container_of(timer, struct aw8697, hap_disable_timer); + int rc; + + pr_info("%s enter\n", __func__); + rc = aw8697_haptic_play_go( + aw8697, false); //qti_haptics_module_en(aw8697, false); + if (rc < 0) + dev_err(aw8697->dev, "Disable haptics module failed, rc=%d\n", + rc); + + return HRTIMER_NORESTART; +} + +static enum hrtimer_restart aw8697_vibrator_timer_func(struct hrtimer *timer) +{ + struct aw8697 *aw8697 = container_of(timer, struct aw8697, timer); + + pr_info("%s enter\n", __func__); + + aw8697->state = 0; + //schedule_work(&aw8697->vibrator_work); + queue_work(aw8697->work_queue, &aw8697->vibrator_work); + + return HRTIMER_NORESTART; +} + +static void aw8697_vibrator_work_routine(struct work_struct *work) +{ + struct aw8697 *aw8697 = + container_of(work, struct aw8697, vibrator_work); + + pr_debug("%s enter\n", __func__); + pr_info("%s: effect_id = %d state=%d activate_mode = %d duration = %d\n", + __func__, aw8697->effect_id, aw8697->state, + aw8697->activate_mode, aw8697->duration); + mutex_lock(&aw8697->lock); + aw8697_haptic_upload_lra(aw8697, true); + aw8697_haptic_stop(aw8697); + if (aw8697->state) { + if (aw8697->activate_mode == AW8697_HAPTIC_ACTIVATE_RAM_MODE) { + aw8697_haptic_ram_vbat_comp(aw8697, false); + aw8697_haptic_play_effect_seq(aw8697, true); + } else if (aw8697->activate_mode == + AW8697_HAPTIC_ACTIVATE_RAM_LOOP_MODE) { + aw8697_haptic_ram_vbat_comp(aw8697, true); + aw8697_haptic_play_effect_seq(aw8697, true); + hrtimer_start( + &aw8697->timer, + ktime_set(aw8697->duration / 1000, + (aw8697->duration % 1000) * 1000000), + HRTIMER_MODE_REL); + } else if (aw8697->activate_mode == + AW8697_HAPTIC_ACTIVATE_CONT_MODE) { + aw8697_haptic_cont(aw8697); + hrtimer_start( + &aw8697->timer, + ktime_set(aw8697->duration / 1000, + (aw8697->duration % 1000) * 1000000), + HRTIMER_MODE_REL); + } else { + /*other mode */ + } + } + mutex_unlock(&aw8697->lock); +} + +static int aw8697_vibrator_init(struct aw8697 *aw8697) +{ + pr_info("%s enter\n", __func__); + + hrtimer_init(&aw8697->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + aw8697->timer.function = aw8697_vibrator_timer_func; + INIT_WORK(&aw8697->vibrator_work, aw8697_vibrator_work_routine); + INIT_WORK(&aw8697->rtp_work, aw8697_rtp_work_routine); + + mutex_init(&aw8697->lock); + atomic_set(&aw8697->is_in_rtp_loop, 0); + atomic_set(&aw8697->exit_in_rtp_loop, 0); + atomic_set(&aw8697->is_in_write_loop, 0); + init_waitqueue_head(&aw8697->wait_q); + init_waitqueue_head(&aw8697->stop_wait_q); + + return 0; +} + +/****************************************************** + * + * irq + * + ******************************************************/ +static void aw8697_interrupt_clear(struct aw8697 *aw8697) +{ + unsigned char reg_val = 0; + aw8697_i2c_read(aw8697, AW8697_REG_SYSINT, ®_val); +} + +static void aw8697_interrupt_setup(struct aw8697 *aw8697) +{ + unsigned char reg_val = 0; + + aw8697_i2c_read(aw8697, AW8697_REG_SYSINT, ®_val); + + /* edge int mode */ + aw8697_i2c_write_bits(aw8697, AW8697_REG_DBGCTRL, + AW8697_BIT_DBGCTRL_INT_MODE_MASK, + AW8697_BIT_DBGCTRL_INT_MODE_EDGE); + + /* int enable */ + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSINTM, + AW8697_BIT_SYSINTM_BSTERR_MASK, + AW8697_BIT_SYSINTM_BSTERR_OFF); + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSINTM, + AW8697_BIT_SYSINTM_OV_MASK, + AW8697_BIT_SYSINTM_OV_EN); + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSINTM, + AW8697_BIT_SYSINTM_UVLO_MASK, + AW8697_BIT_SYSINTM_UVLO_EN); + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSINTM, + AW8697_BIT_SYSINTM_OCD_MASK, + AW8697_BIT_SYSINTM_OCD_EN); + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSINTM, + AW8697_BIT_SYSINTM_OT_MASK, + AW8697_BIT_SYSINTM_OT_EN); +} + +static irqreturn_t aw8697_irq(int irq, void *data) +{ + struct aw8697 *aw8697 = data; + unsigned char reg_val = 0; + unsigned char dbg_val = 0; + unsigned int buf_len = 0; + unsigned period_size = aw8697->ram.base_addr >> 2; + + atomic_set(&aw8697->is_in_rtp_loop, 1); + aw8697_i2c_read(aw8697, AW8697_REG_SYSINT, ®_val); + //pr_info("%s: reg SYSINT=0x%x\n", __func__, reg_val); + aw8697_i2c_read(aw8697, AW8697_REG_DBGSTAT, &dbg_val); + //pr_info("%s: reg DBGSTAT=0x%x\n", __func__, dbg_val); + + if (reg_val & AW8697_BIT_SYSINT_OVI) { + pr_err("%s chip ov int error\n", __func__); + } + if (reg_val & AW8697_BIT_SYSINT_UVLI) { + pr_err("%s chip uvlo int error\n", __func__); + } + if (reg_val & AW8697_BIT_SYSINT_OCDI) { + pr_err("%s chip over current int error\n", __func__); + } + if (reg_val & AW8697_BIT_SYSINT_OTI) { + pr_err("%s chip over temperature int error\n", __func__); + } + if (reg_val & AW8697_BIT_SYSINT_DONEI) { + pr_info("%s chip playback done\n", __func__); + } + + if (reg_val & AW8697_BIT_SYSINT_FF_AEI) { + pr_debug("%s: aw8697 rtp fifo almost empty int\n", __func__); + if (aw8697->rtp_init) { + while ((!aw8697_haptic_rtp_get_fifo_afi(aw8697)) && + (aw8697->play_mode == AW8697_HAPTIC_RTP_MODE) && + !atomic_read(&aw8697->exit_in_rtp_loop)) { + mutex_lock(&aw8697->rtp_lock); + if (!aw8697_rtp) { + pr_info("%s:aw8697_rtp is null break\n", + __func__); + mutex_unlock(&aw8697->rtp_lock); + break; + } + if (aw8697->is_custom_wave == 1) { + buf_len = read_rb(aw8697_rtp->data, + period_size); + aw8697_i2c_writes(aw8697, + AW8697_REG_RTP_DATA, + aw8697_rtp->data, + buf_len); + if (buf_len < period_size) { + pr_info("%s: rtp update complete\n", + __func__); + aw8697_haptic_set_rtp_aei( + aw8697, false); + aw8697->rtp_cnt = 0; + aw8697->rtp_init = 0; + mutex_unlock(&aw8697->rtp_lock); + break; + } + } else { + if ((aw8697_rtp->len - + aw8697->rtp_cnt) < + (aw8697->ram.base_addr >> 2)) { + buf_len = aw8697_rtp->len - + aw8697->rtp_cnt; + } else { + buf_len = + (aw8697->ram.base_addr >> + 2); + } + aw8697_i2c_writes( + aw8697, AW8697_REG_RTP_DATA, + &aw8697_rtp + ->data[aw8697->rtp_cnt], + buf_len); + aw8697->rtp_cnt += buf_len; + pr_debug("%s: rtp_cnt = %d \n", + __func__, aw8697->rtp_cnt); + if (aw8697->rtp_cnt == + aw8697_rtp->len) { + pr_info("%s: rtp update complete\n", + __func__); + aw8697_haptic_set_rtp_aei( + aw8697, false); + aw8697->rtp_cnt = 0; + aw8697->rtp_init = 0; + mutex_unlock(&aw8697->rtp_lock); + break; + } + } + mutex_unlock(&aw8697->rtp_lock); + } + } else { + pr_err("%s: aw8697 rtp init = %d, init error\n", + __func__, aw8697->rtp_init); + } + } + + if (reg_val & AW8697_BIT_SYSINT_FF_AFI) { + pr_debug("%s: aw8697 rtp mode fifo full empty\n", __func__); + } + + if (aw8697->play_mode != AW8697_HAPTIC_RTP_MODE || + atomic_read(&aw8697->exit_in_rtp_loop)) { + aw8697_haptic_set_rtp_aei(aw8697, false); + } + + aw8697_i2c_read(aw8697, AW8697_REG_SYSINT, ®_val); + pr_debug("%s: reg SYSINT=0x%x\n", __func__, reg_val); + aw8697_i2c_read(aw8697, AW8697_REG_SYSST, ®_val); + pr_debug("%s: reg SYSST=0x%x\n", __func__, reg_val); + atomic_set(&aw8697->is_in_rtp_loop, 0); + wake_up_interruptible(&aw8697->wait_q); + pr_debug("%s exit\n", __func__); + return IRQ_HANDLED; +} + +/***************************************************** + * + * device tree + * + *****************************************************/ +static int aw8697_parse_dt(struct device *dev, struct aw8697 *aw8697, + struct device_node *np) +{ + unsigned int val = 0; + unsigned int bstdbg[6]; + unsigned int f0_trace_parameter[4]; + unsigned int bemf_config[4]; + unsigned int rtp_time[175]; + unsigned int trig_config[15]; + struct qti_hap_config *config = &aw8697->config; + struct device_node *child_node; + struct qti_hap_effect *effect; + int rc = 0, tmp, i = 0, j, m; + + printk("%s %d enter\n", __func__, __LINE__); + aw8697->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); + if (aw8697->reset_gpio < 0) { + dev_err(dev, + "%s: no reset gpio provided, will not HW reset device\n", + __func__); + return -EINVAL; + } else { + dev_info(dev, "%s: reset gpio provided ok\n", __func__); + } + aw8697->irq_gpio = of_get_named_gpio(np, "irq-gpio", 0); + if (aw8697->irq_gpio < 0) { + dev_err(dev, "%s: no irq gpio provided.\n", __func__); + } else { + dev_info(dev, "%s: irq gpio provided ok.\n", __func__); + } + + val = of_property_read_u32(np, "vib_mode", &aw8697->info.mode); + if (val != 0) + printk("vib_mode not found\n"); + val = of_property_read_u32(np, "vib_f0_pre", &aw8697->info.f0_pre); + if (val != 0) + printk("vib_f0_pre not found\n"); + val = of_property_read_u32(np, "vib_f0_cali_percen", + &aw8697->info.f0_cali_percen); + if (val != 0) + printk("vib_f0_cali_percen not found\n"); + val = of_property_read_u32(np, "vib_cont_drv_lev", + &aw8697->info.cont_drv_lvl); + if (val != 0) + printk("vib_cont_drv_lev not found\n"); + val = of_property_read_u32(np, "vib_cont_drv_lvl_ov", + &aw8697->info.cont_drv_lvl_ov); + if (val != 0) + printk("vib_cont_drv_lvl_ov not found\n"); + val = of_property_read_u32(np, "vib_cont_td", &aw8697->info.cont_td); + if (val != 0) + printk("vib_cont_td not found\n"); + val = of_property_read_u32(np, "vib_cont_zc_thr", + &aw8697->info.cont_zc_thr); + if (val != 0) + printk("vib_cont_zc_thr not found\n"); + val = of_property_read_u32(np, "vib_cont_num_brk", + &aw8697->info.cont_num_brk); + if (val != 0) + printk("vib_cont_num_brk not found\n"); + val = of_property_read_u32(np, "vib_f0_coeff", &aw8697->info.f0_coeff); + if (val != 0) + printk("vib_f0_coeff not found\n"); + + val = of_property_read_u32(np, "vib_tset", &aw8697->info.tset); + if (val != 0) + printk("%s vib_tset not found\n", __func__); + val = of_property_read_u32(np, "vib_r_spare", &aw8697->info.r_spare); + if (val != 0) + printk("%s vib_r_spare not found\n", __func__); + val = of_property_read_u32_array(np, "vib_bstdbg", bstdbg, + ARRAY_SIZE(bstdbg)); + if (val != 0) + printk("%s vib_bstdbg not found\n", __func__); + memcpy(aw8697->info.bstdbg, bstdbg, sizeof(bstdbg)); + + val = of_property_read_u32_array(np, "vib_f0_trace_parameter", + f0_trace_parameter, + ARRAY_SIZE(f0_trace_parameter)); + if (val != 0) + printk("%s vib_f0_trace_parameter not found\n", __func__); + memcpy(aw8697->info.f0_trace_parameter, f0_trace_parameter, + sizeof(f0_trace_parameter)); + val = of_property_read_u32_array(np, "vib_bemf_config", bemf_config, + ARRAY_SIZE(bemf_config)); + if (val != 0) + printk("%s vib_bemf_config not found\n", __func__); + memcpy(aw8697->info.bemf_config, bemf_config, sizeof(bemf_config)); + + val = of_property_read_u32_array(np, "vib_trig_config", trig_config, + ARRAY_SIZE(trig_config)); + if (val != 0) + printk("%s vib_trig_config not found\n", __func__); + memcpy(aw8697->info.trig_config, trig_config, sizeof(trig_config)); + + val = of_property_read_u32_array(np, "vib_rtp_time", rtp_time, + ARRAY_SIZE(rtp_time)); + if (val != 0) + printk("%s vib_rtp_time not found\n", __func__); + memcpy(aw8697->info.rtp_time, rtp_time, sizeof(rtp_time)); + + val = of_property_read_u32(np, "vib_effect_id_boundary", + &aw8697->info.effect_id_boundary); + if (val != 0) + printk("%s vib_effect_id_boundary not found\n", __func__); + val = of_property_read_u32(np, "vib_effect_max", + &aw8697->info.effect_max); + if (val != 0) + printk("%s vib_effect_max not found\n", __func__); + val = of_property_read_u32(np, "vib_bst_vol_default", + &aw8697->info.bst_vol_default); + if (val != 0) + printk("%s vib_bst_vol_default not found\n", __func__); + val = of_property_read_u32(np, "vib_bst_vol_ram", + &aw8697->info.bst_vol_ram); + if (val != 0) + printk("%s vib_bst_vol_ram not found\n", __func__); + val = of_property_read_u32(np, "vib_bst_vol_rtp", + &aw8697->info.bst_vol_rtp); + if (val != 0) + printk("%s vib_bst_vol_rtp not found\n", __func__); + + config->play_rate_us = HAP_PLAY_RATE_US_DEFAULT; + rc = of_property_read_u32(np, "qcom,play-rate-us", &tmp); + if (!rc) + config->play_rate_us = (tmp >= HAP_PLAY_RATE_US_MAX) ? + HAP_PLAY_RATE_US_MAX : + tmp; + + aw8697->constant.pattern = devm_kcalloc( + aw8697->dev, HAP_WAVEFORM_BUFFER_MAX, sizeof(u8), GFP_KERNEL); + if (!aw8697->constant.pattern) + return -ENOMEM; + + tmp = of_get_available_child_count(np); + aw8697->predefined = devm_kcalloc( + aw8697->dev, tmp, sizeof(*aw8697->predefined), GFP_KERNEL); + if (!aw8697->predefined) + return -ENOMEM; + + aw8697->effects_count = tmp; + printk("%s ---%d aw8697->effects_count=%d\n", __func__, __LINE__, + aw8697->effects_count); + for_each_available_child_of_node(np, child_node) { + printk("%s %d i=%d\n", __func__, __LINE__, i); + effect = &aw8697->predefined[i++]; + printk("%s %d i=%d\n", __func__, __LINE__, i); + rc = of_property_read_u32(child_node, "qcom,effect-id", + &effect->id); + if (rc != 0) { + printk("%s Read qcom,effect-id failed\n", __func__); + } + printk(" 20190420_dt effect_id: %d\n", effect->id); + + printk("%s ---%d \n", __func__, __LINE__); + effect->vmax_mv = config->vmax_mv; + rc = of_property_read_u32(child_node, "qcom,wf-vmax-mv", &tmp); + if (rc != 0) + printk("%s Read qcom,wf-vmax-mv failed !\n", __func__); + else + effect->vmax_mv = tmp; + + printk("%s ---%d effect->vmax_mv =%d \n", __func__, __LINE__, + effect->vmax_mv); + rc = of_property_count_elems_of_size( + child_node, "qcom,wf-pattern", sizeof(u8)); + if (rc < 0) { + printk("%s Count qcom,wf-pattern property failed !\n", + __func__); + } else if (rc == 0) { + printk("%s qcom,wf-pattern has no data\n", __func__); + } + printk("%s ---%d \n", __func__, __LINE__); + + effect->pattern_length = rc; + effect->pattern = devm_kcalloc(aw8697->dev, + effect->pattern_length, + sizeof(u8), GFP_KERNEL); + + rc = of_property_read_u8_array(child_node, "qcom,wf-pattern", + effect->pattern, + effect->pattern_length); + if (rc < 0) { + printk("%s Read qcom,wf-pattern property failed !\n", + __func__); + } + printk("%s %d effect->pattern_length=%d effect->pattern=%d \n", + __func__, __LINE__, effect->pattern_length, + (int)effect->pattern); + + effect->play_rate_us = config->play_rate_us; + rc = of_property_read_u32(child_node, "qcom,wf-play-rate-us", + &tmp); + if (rc < 0) + printk("%s Read qcom,wf-play-rate-us failed !\n", + __func__); + else + effect->play_rate_us = tmp; + printk("%s ---%d effect->play_rate_us=%d \n", __func__, + __LINE__, effect->play_rate_us); + + rc = of_property_read_u32(child_node, "qcom,wf-repeat-count", + &tmp); + if (rc < 0) { + printk("%s Read qcom,wf-repeat-count failed !\n", + __func__); + } else { + for (j = 0; j < ARRAY_SIZE(wf_repeat); j++) + if (tmp <= wf_repeat[j]) + break; + + effect->wf_repeat_n = j; + } + + printk("%s ---%d \n", __func__, __LINE__); + + rc = of_property_read_u32(child_node, "qcom,wf-s-repeat-count", + &tmp); + if (rc < 0) { + printk("%s Read qcom,wf-s-repeat-count failed !\n", + __func__); + } else { + for (j = 0; j < ARRAY_SIZE(wf_s_repeat); j++) + if (tmp <= wf_s_repeat[j]) + break; + + effect->wf_s_repeat_n = j; + } + + printk("%s ---%d \n", __func__, __LINE__); + + effect->lra_auto_res_disable = of_property_read_bool( + child_node, "qcom,lra-auto-resonance-disable"); + + tmp = of_property_count_elems_of_size( + child_node, "qcom,wf-brake-pattern", sizeof(u8)); + if (tmp <= 0) + continue; + + if (tmp > HAP_BRAKE_PATTERN_MAX) { + printk("%s wf-brake-pattern shouldn't be more than %d bytes\n", + __func__, HAP_BRAKE_PATTERN_MAX); + } + + rc = of_property_read_u8_array(child_node, + "qcom,wf-brake-pattern", + effect->brake, tmp); + if (rc < 0) { + printk("%s Failed to get wf-brake-pattern !\n", + __func__); + } + + effect->brake_pattern_length = tmp; + } + + for (j = 0; j < i; j++) { + printk(" 20190420_dt effect_id: %d\n", + aw8697->predefined[j].id); + printk(" 20190420_dt vmax: %d mv\n", + aw8697->predefined[j].vmax_mv); + printk("20190420_dt play_rate: %d us\n", + aw8697->predefined[j].play_rate_us); + for (m = 0; m < aw8697->predefined[j].pattern_length; m++) + printk("20190420_dt pattern[%d]: 0x%x\n", m, + aw8697->predefined[j].pattern[m]); + for (m = 0; m < aw8697->predefined[j].brake_pattern_length; m++) + printk("20190420_dt brake_pattern[%d]: 0x%x\n", m, + aw8697->predefined[j].brake[m]); + printk("20190420_dt brake_en: %d\n", + aw8697->predefined[j].brake_en); + printk("20190420_dt wf_repeat_n: %d\n", + aw8697->predefined[j].wf_repeat_n); + printk("20190420_dt wf_s_repeat_n: %d\n", + aw8697->predefined[j].wf_s_repeat_n); + printk("20190420_dt lra_auto_res_disable: %d\n", + aw8697->predefined[j].lra_auto_res_disable); + } + printk(" 20190420_dt aw8697->effects_count: %d\n", + aw8697->effects_count); + printk(" 20190420_dt aw8697->effect_id_boundary: %d\n", + aw8697->info.effect_id_boundary); + printk(" 20190420_dt aw8697->effect_max: %d\n", + aw8697->info.effect_max); + printk(" 20190420_dt aw8697->info.cont_drv_lvl: %d\n", + aw8697->info.cont_drv_lvl); + printk(" 20190420_dt aw8697->info.cont_drv_lvl_ov: %d\n", + aw8697->info.cont_drv_lvl_ov); + for (i = 0; i < 3; i++) + for (j = 0; j < 5; j++) + printk(" 20190420_dt aw8697->info.trig_config[%d][%d]: %d\n", + i, j, aw8697->info.trig_config[i][j]); + for (i = 0; i < 175; i++) + printk(" 20190420_dt aw8697->info.rtp_time[%d]: %d\n", i, + aw8697->info.rtp_time[i]); + + printk(" 20190420_dt aw8697->info.bst_vol_default: 0x%x\n", + aw8697->info.bst_vol_default); + printk(" 20190420_dt aw8697->info.bst_vol_ram: 0x%x\n", + aw8697->info.bst_vol_ram); + printk(" 20190420_dt aw8697->info.bst_vol_rtp: 0x%x\n", + aw8697->info.bst_vol_rtp); + return 0; +} + +static inline void get_play_length(struct qti_hap_play_info *play, + int *length_us) +{ + struct qti_hap_effect *effect = play->effect; + int tmp; + //printk("%s %d enter\n", __func__, __LINE__); + + tmp = effect->pattern_length * effect->play_rate_us; + tmp *= wf_s_repeat[effect->wf_s_repeat_n]; + tmp *= wf_repeat[effect->wf_repeat_n]; + if (effect->brake_en) + tmp += effect->play_rate_us * effect->brake_pattern_length; + + *length_us = tmp; +} + +static int aw8697_haptics_upload_effect(struct input_dev *dev, + struct ff_effect *effect, + struct ff_effect *old) +{ + struct aw8697 *aw8697 = input_get_drvdata(dev); + struct qti_hap_play_info *play = &aw8697->play; + s16 data[CUSTOM_DATA_LEN]; + ktime_t rem; + s64 time_us; + int ret; + + /*for osc calibration*/ + if (aw8697->osc_cali_run != 0) + return 0; + + if (hrtimer_active(&aw8697->timer)) { + rem = hrtimer_get_remaining(&aw8697->timer); + time_us = ktime_to_us(rem); + printk("waiting for playing clear sequence: %lld us\n", + time_us); + usleep_range(time_us, time_us + 100); + } + pr_debug("%s: effect->type=0x%x,FF_CONSTANT=0x%x,FF_PERIODIC=0x%x\n", + __func__, effect->type, FF_CONSTANT, FF_PERIODIC); + aw8697->effect_type = effect->type; + mutex_lock(&aw8697->lock); + while (atomic_read(&aw8697->exit_in_rtp_loop)) { + pr_info("%s goint to waiting rtp exit\n", __func__); + mutex_unlock(&aw8697->lock); + ret = wait_event_interruptible( + aw8697->stop_wait_q, + atomic_read(&aw8697->exit_in_rtp_loop) == 0); + pr_info("%s wakeup \n", __func__); + if (ret == -ERESTARTSYS) { + mutex_unlock(&aw8697->lock); + pr_err("%s wake up by signal return erro\n", __func__); + return ret; + } + mutex_lock(&aw8697->lock); + } + if (aw8697->effect_type == FF_CONSTANT) { + pr_debug("%s: effect_type is FF_CONSTANT! \n", __func__); + /*cont mode set duration */ + aw8697->duration = effect->replay.length; + aw8697->activate_mode = AW8697_HAPTIC_ACTIVATE_RAM_LOOP_MODE; + aw8697->effect_id = aw8697->info.effect_id_boundary; + + } else if (aw8697->effect_type == FF_PERIODIC) { + if (aw8697->effects_count == 0) { + mutex_unlock(&aw8697->lock); + return -EINVAL; + } + + pr_debug("%s: effect_type is FF_PERIODIC! \n", __func__); + if (copy_from_user(data, effect->u.periodic.custom_data, + sizeof(s16) * CUSTOM_DATA_LEN)) { + mutex_unlock(&aw8697->lock); + return -EFAULT; + } + + aw8697->effect_id = data[0]; + pr_debug("%s: aw8697->effect_id =%d \n", __func__, + aw8697->effect_id); + play->vmax_mv = effect->u.periodic.magnitude; /*vmax level*/ + + if (aw8697->effect_id < 0 || + aw8697->effect_id > aw8697->info.effect_max) { + mutex_unlock(&aw8697->lock); + return 0; + } + aw8697->is_custom_wave = 0; + if (aw8697->effect_id < aw8697->info.effect_id_boundary) { + aw8697->activate_mode = AW8697_HAPTIC_ACTIVATE_RAM_MODE; + pr_debug( + "%s: aw8697->effect_id=%d , aw8697->activate_mode = %d\n", + __func__, aw8697->effect_id, + aw8697->activate_mode); + data[1] = aw8697->predefined[aw8697->effect_id] + .play_rate_us / + 1000000; /*second data*/ + data[2] = aw8697->predefined[aw8697->effect_id] + .play_rate_us / + 1000; /*millisecond data*/ + } + if (aw8697->effect_id >= aw8697->info.effect_id_boundary) { + aw8697->activate_mode = AW8697_HAPTIC_ACTIVATE_RTP_MODE; + pr_debug( + "%s: aw8697->effect_id=%d , aw8697->activate_mode = %d\n", + __func__, aw8697->effect_id, + aw8697->activate_mode); + data[1] = aw8697->info.rtp_time[aw8697->effect_id] / + 1000; /*second data*/ + data[2] = + aw8697->info.rtp_time + [aw8697->effect_id]; /*millisecond data*/ + } + if (aw8697->effect_id == CUSTOME_WAVE_ID) { + aw8697->activate_mode = AW8697_HAPTIC_ACTIVATE_RTP_MODE; + pr_debug( + "%s: aw8697->effect_id=%d , aw8697->activate_mode = %d\n", + __func__, aw8697->effect_id, + aw8697->activate_mode); + data[1] = aw8697->info.rtp_time[aw8697->effect_id] / + 1000; /*second data*/ + data[2] = + aw8697->info.rtp_time + [aw8697->effect_id]; /*millisecond data*/ + aw8697->is_custom_wave = 1; + rb_init(); + } + if (copy_to_user(effect->u.periodic.custom_data, data, + sizeof(s16) * CUSTOM_DATA_LEN)) { + mutex_unlock(&aw8697->lock); + return -EFAULT; + } + + } else { + pr_err("%s Unsupported effect type: %d\n", __func__, + effect->type); + } + mutex_unlock(&aw8697->lock); + return 0; +} + +static int aw8697_haptics_playback(struct input_dev *dev, int effect_id, + int val) +{ + struct aw8697 *aw8697 = input_get_drvdata(dev); + int rc = 0; + + //printk("%s effect_id=%d , val = %d\n", __func__, effect_id, val); + //printk("%s aw8697->effect_id=%d , aw8697->activate_mode = %d\n", + // __func__, aw8697->effect_id, aw8697->activate_mode); + + pr_debug("%s: effect_id=%d , activate_mode = %d val = %d\n", __func__, + aw8697->effect_id, aw8697->activate_mode, val); + /*for osc calibration*/ + if (aw8697->osc_cali_run != 0) + return 0; + + if (val > 0) + aw8697->state = 1; + if (val <= 0) + aw8697->state = 0; + hrtimer_cancel(&aw8697->timer); + + if (aw8697->effect_type == FF_CONSTANT && + aw8697->activate_mode == AW8697_HAPTIC_ACTIVATE_RAM_LOOP_MODE) { + pr_debug("%s: enter cont_mode \n", __func__); + //schedule_work(&aw8697->vibrator_work); + queue_work(aw8697->work_queue, &aw8697->vibrator_work); + } else if (aw8697->effect_type == FF_PERIODIC && + aw8697->activate_mode == AW8697_HAPTIC_ACTIVATE_RAM_MODE) { + pr_debug("%s: enter ram_mode\n", __func__); + //schedule_work(&aw8697->vibrator_work) + queue_work(aw8697->work_queue, &aw8697->vibrator_work); + ; + } else if ((aw8697->effect_type == FF_PERIODIC) && + aw8697->activate_mode == AW8697_HAPTIC_ACTIVATE_RTP_MODE) { + pr_debug("%s: enter rtp_mode\n", __func__); + //schedule_work(&aw8697->rtp_work); + queue_work(aw8697->work_queue, &aw8697->rtp_work); + //if we are in the play mode, force to exit + if (val == 0) { + atomic_set(&aw8697->exit_in_rtp_loop, 1); + rb_force_exit(); + wake_up_interruptible(&aw8697->stop_wait_q); + } + } else { + /*other mode */ + } + + return rc; +} + +static int aw8697_haptics_erase(struct input_dev *dev, int effect_id) +{ + struct aw8697 *aw8697 = input_get_drvdata(dev); + int rc = 0; + + /*for osc calibration*/ + if (aw8697->osc_cali_run != 0) + return 0; + + pr_debug("%s: enter\n", __func__); + aw8697->effect_type = 0; + aw8697->is_custom_wave = 0; + aw8697->duration = 0; + return rc; +} + +static void set_gain(struct work_struct *work) +{ + struct aw8697 *aw8697 = + container_of(work, struct aw8697, set_gain_work); + pr_debug("%s enter set_gain queue work\n", __func__); + + if (aw8697->new_gain >= 0x7FFF) + aw8697->level = 0x80; /*128*/ + else if (aw8697->new_gain <= 0x3FFF) + aw8697->level = 0x1E; /*30*/ + else + aw8697->level = (aw8697->new_gain - 16383) / 128; + + if (aw8697->level < 0x1E) + aw8697->level = 0x1E; /*30*/ + + aw8697_haptic_set_gain(aw8697, aw8697->level); +} + +static void aw8697_haptics_set_gain(struct input_dev *dev, u16 gain) +{ + struct aw8697 *aw8697 = input_get_drvdata(dev); + pr_debug("%s enter\n", __func__); + aw8697->new_gain = gain; + queue_work(aw8697->work_queue, &aw8697->set_gain_work); +} + +static ssize_t aw8697_activate_test_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + + /* For now nothing to show */ + return snprintf(buf, PAGE_SIZE, "%d\n", aw8697->test_val); +} + +static ssize_t aw8697_activate_test_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + ; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + aw8697->test_val = val; + pr_debug("%s: aw8697->test_val=%d\n", __FUNCTION__, aw8697->test_val); + + if (aw8697->test_val == 1) { + printk("%s %d \n", __func__, __LINE__); + aw8697->duration = 3000; + + aw8697->state = 1; + aw8697->activate_mode = AW8697_HAPTIC_ACTIVATE_CONT_MODE; + hrtimer_cancel(&aw8697->timer); + //schedule_work(&aw8697->vibrator_work); + queue_work(aw8697->work_queue, &aw8697->vibrator_work); + } + if (aw8697->test_val == 2) { + printk("%s %d \n", __func__, __LINE__); + mutex_lock(&aw8697->lock); + aw8697_haptic_set_wav_seq(aw8697, 0x00, 0x01); + aw8697_haptic_set_wav_seq(aw8697, 0x01, 0x01); + + /*step 1: choose loop */ + aw8697_haptic_set_wav_loop(aw8697, 0x01, 0x01); + mutex_unlock(&aw8697->lock); + + aw8697->state = 1; + aw8697->activate_mode = AW8697_HAPTIC_ACTIVATE_RAM_MODE; + hrtimer_cancel(&aw8697->timer); + //schedule_work(&aw8697->vibrator_work); + queue_work(aw8697->work_queue, &aw8697->vibrator_work); + } + + if (aw8697->test_val == 3) { /*Ram instead of Cont */ + aw8697->duration = 10000; + + aw8697->state = 1; + aw8697->activate_mode = AW8697_HAPTIC_ACTIVATE_CONT_MODE; + hrtimer_cancel(&aw8697->timer); + //schedule_work(&aw8697->vibrator_work); + queue_work(aw8697->work_queue, &aw8697->vibrator_work); + } + + if (aw8697->test_val == 4) { + mutex_lock(&aw8697->lock); + aw8697_haptic_stop(aw8697); + aw8697_haptic_play_mode(aw8697, AW8697_HAPTIC_RAM_MODE); + + aw8697_haptic_set_wav_seq(aw8697, 0x00, 0x01); + aw8697_haptic_set_wav_seq(aw8697, 0x01, 0x00); + + aw8697_haptic_set_wav_loop(aw8697, 0x01, 0x01); + + if (aw8697->info.bst_vol_ram <= AW8697_MAX_BST_VO) + aw8697_haptic_set_bst_vol(aw8697, + aw8697->info.bst_vol_ram); + else + aw8697_haptic_set_bst_vol(aw8697, aw8697->vmax); + + aw8697->activate_mode = AW8697_HAPTIC_ACTIVATE_RAM_MODE; + aw8697->state = 1; + mutex_unlock(&aw8697->lock); + hrtimer_cancel(&aw8697->timer); + //schedule_work(&aw8697->vibrator_work); + queue_work(aw8697->work_queue, &aw8697->vibrator_work); + } + + return count; +} +#ifdef ENABLE_PIN_CONTROL +static int select_pin_ctl(struct aw8697 *aw8697, const char *name) +{ + size_t i; + int rc; + + for (i = 0; i < ARRAY_SIZE(aw8697->pinctrl_state); i++) { + const char *n = pctl_names[i]; + + if (!strncmp(n, name, strlen(n))) { + rc = pinctrl_select_state(aw8697->aw8697_pinctrl, + aw8697->pinctrl_state[i]); + if (rc) + printk("cannot select '%s'\n", name); + else + printk("Selected '%s'\n", name); + goto exit; + } + } + + rc = -EINVAL; + printk("%s:'%s' not found\n", __func__, name); + +exit: + return rc; +} +static int aw8697_set_interrupt(struct aw8697 *aw8697) +{ + int rc = select_pin_ctl(aw8697, "aw8697_interrupt_active"); + return rc; +} +#endif + +static int aw8697_hw_reset(struct aw8697 *aw8697) +{ +#ifdef ENABLE_PIN_CONTROL + int rc = select_pin_ctl(aw8697, "aw8697_reset_active"); + msleep(5); + rc = select_pin_ctl(aw8697, "aw8697_reset_reset"); + msleep(5); + rc = select_pin_ctl(aw8697, "aw8697_reset_active"); +#endif + if (!aw8697->enable_pin_control) { + if (aw8697 && gpio_is_valid(aw8697->reset_gpio)) { + gpio_set_value_cansleep(aw8697->reset_gpio, 0); + printk("%s pull down1\n", __func__); + msleep(5); + gpio_set_value_cansleep(aw8697->reset_gpio, 1); + printk("%s pull up1\n", __func__); + msleep(5); + } else { + dev_err(aw8697->dev, "%s: failed\n", __func__); + } + } + + return 0; +} + +/***************************************************** + * + * check chip id + * + *****************************************************/ +static int aw8697_read_chipid(struct aw8697 *aw8697) +{ + int ret = -1; + unsigned char cnt = 0; + unsigned char reg = 0; + + while (cnt < AW_READ_CHIPID_RETRIES) { + /* hardware reset */ + aw8697_hw_reset(aw8697); + + ret = aw8697_i2c_read(aw8697, AW8697_REG_ID, ®); + if (ret < 0) { + dev_err(aw8697->dev, + "%s: failed to read register AW8697_REG_ID: %d\n", + __func__, ret); + } + switch (reg) { + case AW8697_CHIPID: + pr_info("%s aw8697 detected\n", __func__); + aw8697->chipid = AW8697_CHIPID; + aw8697_haptic_softreset(aw8697); + return 0; + default: + pr_info("%s unsupported device revision (0x%x)\n", + __func__, reg); + break; + } + cnt++; + + msleep(AW_READ_CHIPID_RETRY_DELAY); + } + + return -EINVAL; +} + +/****************************************************** + * + * sys group attribute: reg + * + ******************************************************/ +static ssize_t aw8697_i2c_reg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + + unsigned int databuf[2] = { 0, 0 }; + + if (2 == sscanf(buf, "%x %x", &databuf[0], &databuf[1])) { + aw8697_i2c_write(aw8697, (unsigned char)databuf[0], + (unsigned char)databuf[1]); + } + + return count; +} + +static ssize_t aw8697_i2c_reg_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + unsigned char i = 0; + unsigned char reg_val = 0; + for (i = 0; i < AW8697_REG_MAX; i++) { + if (!(aw8697_reg_access[i] & REG_RD_ACCESS)) + continue; + aw8697_i2c_read(aw8697, i, ®_val); + len += snprintf(buf + len, PAGE_SIZE - len, + "reg:0x%02x=0x%02x \n", i, reg_val); + } + return len; +} + +static ssize_t aw8697_i2c_ram_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + + unsigned int databuf[1] = { 0 }; + + if (1 == sscanf(buf, "%x", &databuf[0])) { + if (1 == databuf[0]) { + aw8697_ram_update(aw8697); + } + } + + return count; +} + +static ssize_t aw8697_i2c_ram_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + unsigned int i = 0; + unsigned char reg_val = 0; + + aw8697_haptic_stop(aw8697); + /* RAMINIT Enable */ + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_RAMINIT_MASK, + AW8697_BIT_SYSCTRL_RAMINIT_EN); + + aw8697_i2c_write(aw8697, AW8697_REG_RAMADDRH, + (unsigned char)(aw8697->ram.base_addr >> 8)); + aw8697_i2c_write(aw8697, AW8697_REG_RAMADDRL, + (unsigned char)(aw8697->ram.base_addr & 0x00ff)); + len += snprintf(buf + len, PAGE_SIZE - len, "aw8697_haptic_ram:\n"); + for (i = 0; i < aw8697->ram.len; i++) { + aw8697_i2c_read(aw8697, AW8697_REG_RAMDATA, ®_val); + len += snprintf(buf + len, PAGE_SIZE - len, "0x%02x,", reg_val); + } + len += snprintf(buf + len, PAGE_SIZE - len, "\n"); + /* RAMINIT Disable */ + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_RAMINIT_MASK, + AW8697_BIT_SYSCTRL_RAMINIT_OFF); + + return len; +} + +static ssize_t aw8697_duration_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ktime_t time_rem; + s64 time_ms = 0; + + if (hrtimer_active(&aw8697->timer)) { + time_rem = hrtimer_get_remaining(&aw8697->timer); + time_ms = ktime_to_ms(time_rem); + } + + return snprintf(buf, PAGE_SIZE, "%lld\n", time_ms); +} + +static ssize_t aw8697_duration_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + /* setting 0 on duration is NOP for now */ + if (val <= 0) + return count; + + aw8697->duration = val; + + return count; +} + +static ssize_t aw8697_activate_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + + /* For now nothing to show */ + return snprintf(buf, PAGE_SIZE, "%d\n", aw8697->state); +} + +static ssize_t aw8697_activate_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + ; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + if (val != 0 && val != 1) + return count; + + pr_debug("%s: value=%d\n", __FUNCTION__, val); + + mutex_lock(&aw8697->lock); + hrtimer_cancel(&aw8697->timer); + + aw8697->state = val; + + mutex_unlock(&aw8697->lock); + //schedule_work(&aw8697->vibrator_work); + queue_work(aw8697->work_queue, &aw8697->vibrator_work); + + return count; +} + +static ssize_t aw8697_activate_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "activate_mode=%d\n", + aw8697->activate_mode); +} + +static ssize_t aw8697_activate_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + mutex_lock(&aw8697->lock); + aw8697->activate_mode = val; + mutex_unlock(&aw8697->lock); + return count; +} + +static ssize_t aw8697_index_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned char reg_val = 0; + aw8697_i2c_read(aw8697, AW8697_REG_WAVSEQ1, ®_val); + aw8697->index = reg_val; + + return snprintf(buf, PAGE_SIZE, "%d\n", aw8697->index); +} + +static ssize_t aw8697_index_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + pr_debug("%s: value=%d\n", __FUNCTION__, val); + + mutex_lock(&aw8697->lock); + aw8697->index = val; + aw8697_haptic_set_repeat_wav_seq(aw8697, aw8697->index); + mutex_unlock(&aw8697->lock); + return count; +} + +static ssize_t aw8697_vmax_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "0x%02x\n", aw8697->vmax); +} + +static ssize_t aw8697_vmax_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + pr_debug("%s: value=%d\n", __FUNCTION__, val); + + mutex_lock(&aw8697->lock); + aw8697->vmax = val; + aw8697_haptic_set_bst_vol(aw8697, aw8697->vmax); + mutex_unlock(&aw8697->lock); + return count; +} + +static ssize_t aw8697_gain_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + return snprintf(buf, PAGE_SIZE, "0x%02x\n", aw8697->gain); +} + +static ssize_t aw8697_gain_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + pr_debug("%s: value=%d\n", __FUNCTION__, val); + + mutex_lock(&aw8697->lock); + aw8697->gain = val; + aw8697_haptic_set_gain(aw8697, aw8697->gain); + mutex_unlock(&aw8697->lock); + return count; +} + +static ssize_t aw8697_seq_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + size_t count = 0; + unsigned char i = 0; + unsigned char reg_val = 0; + + for (i = 0; i < AW8697_SEQUENCER_SIZE; i++) { + aw8697_i2c_read(aw8697, AW8697_REG_WAVSEQ1 + i, ®_val); + count += snprintf(buf + count, PAGE_SIZE - count, + "seq%d: 0x%02x\n", i + 1, reg_val); + aw8697->seq[i] |= reg_val; + } + return count; +} + +static ssize_t aw8697_seq_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int databuf[2] = { 0, 0 }; + + if (2 == sscanf(buf, "%x %x", &databuf[0], &databuf[1])) { + pr_debug("%s: seq%d=0x%x\n", __FUNCTION__, databuf[0], + databuf[1]); + mutex_lock(&aw8697->lock); + aw8697->seq[databuf[0]] = (unsigned char)databuf[1]; + aw8697_haptic_set_wav_seq(aw8697, (unsigned char)databuf[0], + aw8697->seq[databuf[0]]); + mutex_unlock(&aw8697->lock); + } + return count; +} + +static ssize_t aw8697_loop_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + size_t count = 0; + unsigned char i = 0; + unsigned char reg_val = 0; + + for (i = 0; i < AW8697_SEQUENCER_LOOP_SIZE; i++) { + aw8697_i2c_read(aw8697, AW8697_REG_WAVLOOP1 + i, ®_val); + aw8697->loop[i * 2 + 0] = (reg_val >> 4) & 0x0F; + aw8697->loop[i * 2 + 1] = (reg_val >> 0) & 0x0F; + + count += snprintf(buf + count, PAGE_SIZE - count, + "seq%d loop: 0x%02x\n", i * 2 + 1, + aw8697->loop[i * 2 + 0]); + count += snprintf(buf + count, PAGE_SIZE - count, + "seq%d loop: 0x%02x\n", i * 2 + 2, + aw8697->loop[i * 2 + 1]); + } + return count; +} + +static ssize_t aw8697_loop_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int databuf[2] = { 0, 0 }; + + if (2 == sscanf(buf, "%x %x", &databuf[0], &databuf[1])) { + pr_debug("%s: seq%d loop=0x%x\n", __FUNCTION__, databuf[0], + databuf[1]); + mutex_lock(&aw8697->lock); + aw8697->loop[databuf[0]] = (unsigned char)databuf[1]; + aw8697_haptic_set_wav_loop(aw8697, (unsigned char)databuf[0], + aw8697->loop[databuf[0]]); + mutex_unlock(&aw8697->lock); + } + + return count; +} + +static ssize_t aw8697_rtp_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + len += snprintf(buf + len, PAGE_SIZE - len, "rtp play: %d\n", + aw8697->rtp_cnt); + + return len; +} + +static ssize_t aw8697_rtp_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + aw8697_haptic_stop(aw8697); + aw8697_haptic_set_rtp_aei(aw8697, false); + aw8697_interrupt_clear(aw8697); + if (val < (sizeof(aw8697_rtp_name) / AW8697_RTP_NAME_MAX)) { + aw8697->rtp_file_num = val; + if (val) { + //schedule_work(&aw8697->rtp_work); + queue_work(aw8697->work_queue, &aw8697->rtp_work); + } + } else { + pr_err("%s: rtp_file_num 0x%02x over max value \n", __func__, + aw8697->rtp_file_num); + } + + return count; +} + +static ssize_t aw8697_ram_update_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + //struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + len += snprintf(buf + len, PAGE_SIZE - len, "sram update mode\n"); + return len; +} + +static ssize_t aw8697_ram_update_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + if (val) { + aw8697_ram_update(aw8697); + } + return count; +} + +static ssize_t aw8697_f0_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + + mutex_lock(&aw8697->lock); + aw8697->f0_cali_flag = AW8697_HAPTIC_LRA_F0; + aw8697_haptic_get_f0(aw8697); + mutex_unlock(&aw8697->lock); + len += + //snprintf(buf + len, PAGE_SIZE - len, "aw8697 lra f0 = %d\n", + snprintf(buf + len, PAGE_SIZE - len, "%d\n", aw8697->f0); + return len; +} + +static ssize_t aw8697_f0_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + unsigned int val = 0; + int rc = 0; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + return count; +} + +static ssize_t aw8697_cali_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + mutex_lock(&aw8697->lock); + aw8697->f0_cali_flag = AW8697_HAPTIC_CALI_F0; + aw8697_haptic_get_f0(aw8697); + mutex_unlock(&aw8697->lock); + len += snprintf(buf + len, PAGE_SIZE - len, "aw8697 cali f0 = %d\n", + aw8697->f0); + return len; +} + +static ssize_t aw8697_cali_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + if (val) { + mutex_lock(&aw8697->lock); + aw8697_haptic_f0_calibration(aw8697); + mutex_unlock(&aw8697->lock); + } + return count; +} + +static ssize_t aw8697_cont_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + aw8697_haptic_read_cont_f0(aw8697); + len += snprintf(buf + len, PAGE_SIZE - len, "aw8697 cont f0 = %d\n", + aw8697->cont_f0); + return len; +} + +static ssize_t aw8697_cont_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + aw8697_haptic_stop(aw8697); + if (val) { + aw8697_haptic_cont(aw8697); + } + return count; +} + +static ssize_t aw8697_cont_td_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + len += snprintf(buf + len, PAGE_SIZE - len, + "aw8697 cont delay time = 0x%04x\n", + aw8697->info.cont_td); + return len; +} + +static ssize_t aw8697_cont_td_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int databuf[1] = { 0 }; + if (1 == sscanf(buf, "%x", &databuf[0])) { + aw8697->info.cont_td = databuf[0]; + aw8697_i2c_write(aw8697, AW8697_REG_TD_H, + (unsigned char)(databuf[0] >> 8)); + aw8697_i2c_write(aw8697, AW8697_REG_TD_L, + (unsigned char)(databuf[0] >> 0)); + } + return count; +} + +static ssize_t aw8697_cont_drv_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + len += snprintf(buf + len, PAGE_SIZE - len, + "aw8697 cont drv level = %d\n", + aw8697->info.cont_drv_lvl); + len += snprintf(buf + len, PAGE_SIZE - len, + "aw8697 cont drv level overdrive= %d\n", + aw8697->info.cont_drv_lvl_ov); + return len; +} + +static ssize_t aw8697_cont_drv_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int databuf[2] = { 0, 0 }; + if (2 == sscanf(buf, "%d %d", &databuf[0], &databuf[1])) { + aw8697->info.cont_drv_lvl = databuf[0]; + aw8697_i2c_write(aw8697, AW8697_REG_DRV_LVL, + aw8697->info.cont_drv_lvl); + aw8697->info.cont_drv_lvl_ov = databuf[1]; + aw8697_i2c_write(aw8697, AW8697_REG_DRV_LVL_OV, + aw8697->info.cont_drv_lvl_ov); + } + return count; +} + +static ssize_t aw8697_cont_num_brk_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + len += snprintf(buf + len, PAGE_SIZE - len, + "aw8697 cont break num = %d\n", + aw8697->info.cont_num_brk); + return len; +} + +//return buffer size and availbe size +static ssize_t aw8697_custom_wave_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + len += snprintf(buf + len, PAGE_SIZE - len, "period_size=%d;", + aw8697->ram.base_addr >> 2); + len += snprintf(buf + len, PAGE_SIZE - len, "max_size=%d;free_size=%d;", + get_rb_max_size(), get_rb_free_size()); + len += snprintf(buf + len, PAGE_SIZE - len, "custom_wave_id=%d;", + CUSTOME_WAVE_ID); + return len; +} + +static ssize_t aw8697_custom_wave_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned long buf_len, period_size, offset; + int ret; + period_size = (aw8697->ram.base_addr >> 2); + offset = 0; + pr_debug(" write szie %d, period size %d", count, period_size); + if (count % period_size || count < period_size) + rb_end(); + atomic_set(&aw8697->is_in_write_loop, 1); + + while (count > 0) { + buf_len = min(count, period_size); + ret = write_rb(buf + offset, buf_len); + if (ret < 0) + goto exit; + count -= buf_len; + offset += buf_len; + } + ret = offset; +exit: + atomic_set(&aw8697->is_in_write_loop, 0); + wake_up_interruptible(&aw8697->stop_wait_q); + pr_debug(" return size %d", ret); + return ret; +} + +static ssize_t aw8697_cont_num_brk_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int databuf[1] = { 0 }; + if (1 == sscanf(buf, "%d", &databuf[0])) { + aw8697->info.cont_num_brk = databuf[0]; + if (aw8697->info.cont_num_brk > 7) { + aw8697->info.cont_num_brk = 7; + } + aw8697_i2c_write_bits(aw8697, AW8697_REG_BEMF_NUM, + AW8697_BIT_BEMF_NUM_BRK_MASK, + aw8697->info.cont_num_brk); + } + return count; +} + +static ssize_t aw8697_cont_zc_thr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + len += snprintf(buf + len, PAGE_SIZE - len, + "aw8697 cont zero cross thr = 0x%04x\n", + aw8697->info.cont_zc_thr); + return len; +} + +static ssize_t aw8697_cont_zc_thr_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int databuf[1] = { 0 }; + if (1 == sscanf(buf, "%x", &databuf[0])) { + aw8697->info.cont_zc_thr = databuf[0]; + aw8697_i2c_write(aw8697, AW8697_REG_ZC_THRSH_H, + (unsigned char)(databuf[0] >> 8)); + aw8697_i2c_write(aw8697, AW8697_REG_ZC_THRSH_L, + (unsigned char)(databuf[0] >> 0)); + } + return count; +} + +static ssize_t aw8697_vbat_monitor_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + + mutex_lock(&aw8697->lock); + aw8697_haptic_stop(aw8697); + aw8697_haptic_get_vbat(aw8697); + len += snprintf(buf + len, PAGE_SIZE - len, "vbat=%dmV\n", + aw8697->vbat); + mutex_unlock(&aw8697->lock); + + return len; +} + +static ssize_t aw8697_vbat_monitor_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return count; +} + +static ssize_t aw8697_lra_resistance_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + unsigned char reg_val = 0; + + mutex_lock(&aw8697->lock); + aw8697_haptic_stop(aw8697); + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_RAMINIT_MASK, + AW8697_BIT_SYSCTRL_RAMINIT_EN); + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_BST_MODE_MASK, + AW8697_BIT_SYSCTRL_BST_MODE_BYPASS); + + aw8697_i2c_write_bits(aw8697, AW8697_REG_ANACTRL, + AW8697_BIT_ANACTRL_HD_PD_MASK, + AW8697_BIT_ANACTRL_HD_HZ_EN); + aw8697_i2c_write_bits(aw8697, AW8697_REG_D2SCFG, + AW8697_BIT_D2SCFG_CLK_ADC_MASK, + AW8697_BIT_D2SCFG_CLK_ASC_1P5MHZ); + + aw8697_i2c_write_bits(aw8697, AW8697_REG_DETCTRL, + AW8697_BIT_DETCTRL_RL_OS_MASK, + AW8697_BIT_DETCTRL_RL_DETECT); + aw8697_i2c_write_bits(aw8697, AW8697_REG_DETCTRL, + AW8697_BIT_DETCTRL_DIAG_GO_MASK, + AW8697_BIT_DETCTRL_DIAG_GO_ENABLE); + msleep(3); + aw8697_i2c_read(aw8697, AW8697_REG_RLDET, ®_val); + aw8697->lra = 298 * reg_val; + len += snprintf(buf + len, PAGE_SIZE - len, "%d\n", aw8697->lra); + //snprintf(buf + len, PAGE_SIZE - len, "r_lra=%dmohm\n", aw8697->lra); + + aw8697_i2c_write_bits(aw8697, AW8697_REG_ANACTRL, + AW8697_BIT_ANACTRL_HD_PD_MASK, + AW8697_BIT_ANACTRL_HD_PD_EN); + aw8697_i2c_write_bits(aw8697, AW8697_REG_D2SCFG, + AW8697_BIT_D2SCFG_CLK_ADC_MASK, + AW8697_BIT_D2SCFG_CLK_ASC_6MHZ); + + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_RAMINIT_MASK, + AW8697_BIT_SYSCTRL_RAMINIT_OFF); + aw8697_i2c_write_bits(aw8697, AW8697_REG_SYSCTRL, + AW8697_BIT_SYSCTRL_BST_MODE_MASK, + AW8697_BIT_SYSCTRL_BST_MODE_BOOST); + mutex_unlock(&aw8697->lock); + + return len; +} + +static ssize_t aw8697_lra_resistance_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return count; +} + +static ssize_t aw8697_auto_boost_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + + len += snprintf(buf + len, PAGE_SIZE - len, "auto_boost=%d\n", + aw8697->auto_boost); + + return len; +} + +static ssize_t aw8697_auto_boost_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + mutex_lock(&aw8697->lock); + aw8697_haptic_stop(aw8697); + aw8697_haptic_auto_boost_config(aw8697, val); + mutex_unlock(&aw8697->lock); + + return count; +} + +static ssize_t aw8697_prctmode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + unsigned char reg_val = 0; + + aw8697_i2c_read(aw8697, AW8697_REG_RLDET, ®_val); + + len += snprintf(buf + len, PAGE_SIZE - len, "prctmode=%d\n", + reg_val & 0x20); + return len; +} + +static ssize_t aw8697_prctmode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int databuf[2] = { 0, 0 }; + unsigned int addr = 0; + unsigned int val = 0; + if (2 == sscanf(buf, "%x %x", &databuf[0], &databuf[1])) { + addr = databuf[0]; + val = databuf[1]; + mutex_lock(&aw8697->lock); + aw8697_haptic_swicth_motorprotect_config(aw8697, addr, val); + mutex_unlock(&aw8697->lock); + } + return count; +} + +static ssize_t aw8697_trig_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + unsigned char i = 0; + for (i = 0; i < AW8697_TRIG_NUM; i++) { + len += snprintf( + buf + len, PAGE_SIZE - len, + "trig%d: enable=%d, default_level=%d, dual_edge=%d, frist_seq=%d, second_seq=%d\n", + i + 1, aw8697->trig[i].enable, + aw8697->trig[i].default_level, + aw8697->trig[i].dual_edge, aw8697->trig[i].frist_seq, + aw8697->trig[i].second_seq); + } + + return len; +} + +static ssize_t aw8697_trig_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int databuf[6] = { 0 }; + if (sscanf(buf, "%d %d %d %d %d %d", &databuf[0], &databuf[1], + &databuf[2], &databuf[3], &databuf[4], &databuf[5])) { + pr_debug("%s: %d, %d, %d, %d, %d, %d\n", __func__, databuf[0], + databuf[1], databuf[2], databuf[3], databuf[4], + databuf[5]); + if (databuf[0] > 3) { + databuf[0] = 3; + } + if (databuf[0] > 0) { + databuf[0] -= 1; + } + aw8697->trig[databuf[0]].enable = databuf[1]; + aw8697->trig[databuf[0]].default_level = databuf[2]; + aw8697->trig[databuf[0]].dual_edge = databuf[3]; + aw8697->trig[databuf[0]].frist_seq = databuf[4]; + aw8697->trig[databuf[0]].second_seq = databuf[5]; + mutex_lock(&aw8697->lock); + aw8697_haptic_trig_param_config(aw8697); + aw8697_haptic_trig_enable_config(aw8697); + mutex_unlock(&aw8697->lock); + } + return count; +} + +static ssize_t aw8697_ram_vbat_comp_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + + len += snprintf(buf + len, PAGE_SIZE - len, "ram_vbat_comp=%d\n", + aw8697->ram_vbat_comp); + + return len; +} + +static ssize_t aw8697_ram_vbat_comp_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + mutex_lock(&aw8697->lock); + if (val) { + aw8697->ram_vbat_comp = AW8697_HAPTIC_RAM_VBAT_COMP_ENABLE; + } else { + aw8697->ram_vbat_comp = AW8697_HAPTIC_RAM_VBAT_COMP_DISABLE; + } + mutex_unlock(&aw8697->lock); + + return count; +} + +static ssize_t aw8697_osc_cali_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + + len += snprintf(buf + len, PAGE_SIZE - len, "%d\n", + aw8697->lra_calib_data); + + return len; +} + +static ssize_t aw8697_osc_cali_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + + int rc = 0; + + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + + mutex_lock(&aw8697->lock); + /*osc calibration flag start,Other behaviors are forbidden*/ + aw8697->osc_cali_run = 1; + if (val == 3) { + aw8697_rtp_osc_calibration(aw8697); + aw8697_rtp_trim_lra_calibration(aw8697); + } + if (val == 1) + aw8697_rtp_osc_calibration(aw8697); + + aw8697->osc_cali_run = 0; + /*osc calibration flag end,Other behaviors are permitted*/ + mutex_unlock(&aw8697->lock); + + return count; +} + +static ssize_t aw8697_osc_save_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + + pr_info("%s enter\n", __func__); + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + aw8697->lra_calib_data = val; + pr_info("%s load osa cal: %d\n", __func__, val); + + return count; +} + +static ssize_t aw8697_f0_save_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + ssize_t len = 0; + + len += snprintf(buf + len, PAGE_SIZE - len, "%d\n", + aw8697->f0_calib_data); + + return len; +} + +static ssize_t aw8697_f0_save_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + unsigned int val = 0; + int rc = 0; + + pr_info("%s enter\n", __func__); + rc = kstrtouint(buf, 0, &val); + if (rc < 0) + return rc; + aw8697->f0_calib_data = val; + pr_info("%s load f0 cal: %d\n", __func__, val); + + return count; +} + +static ssize_t aw8697_f0_value_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw8697 *aw8697 = dev_get_drvdata(dev); + return snprintf(buf, PAGE_SIZE, "%d\n", aw8697->f0); +} + +static DEVICE_ATTR(activate_test, S_IWUSR | S_IRUGO, aw8697_activate_test_show, + aw8697_activate_test_store); + +static DEVICE_ATTR(reg, S_IWUSR | S_IRUGO, aw8697_i2c_reg_show, + aw8697_i2c_reg_store); +static DEVICE_ATTR(ram, S_IWUSR | S_IRUGO, aw8697_i2c_ram_show, + aw8697_i2c_ram_store); +static DEVICE_ATTR(duration, S_IWUSR | S_IRUGO, aw8697_duration_show, + aw8697_duration_store); +static DEVICE_ATTR(activate, S_IWUSR | S_IRUGO, aw8697_activate_show, + aw8697_activate_store); +static DEVICE_ATTR(activate_mode, S_IWUSR | S_IRUGO, aw8697_activate_mode_show, + aw8697_activate_mode_store); +static DEVICE_ATTR(index, S_IWUSR | S_IRUGO, aw8697_index_show, + aw8697_index_store); +static DEVICE_ATTR(vmax, S_IWUSR | S_IRUGO, aw8697_vmax_show, + aw8697_vmax_store); +static DEVICE_ATTR(gain, S_IWUSR | S_IRUGO, aw8697_gain_show, + aw8697_gain_store); +static DEVICE_ATTR(seq, S_IWUSR | S_IRUGO, aw8697_seq_show, aw8697_seq_store); +static DEVICE_ATTR(loop, S_IWUSR | S_IRUGO, aw8697_loop_show, + aw8697_loop_store); +static DEVICE_ATTR(rtp, S_IWUSR | S_IRUGO, aw8697_rtp_show, aw8697_rtp_store); +static DEVICE_ATTR(ram_update, S_IWUSR | S_IRUGO, aw8697_ram_update_show, + aw8697_ram_update_store); +static DEVICE_ATTR(f0, S_IWUSR | S_IRUGO, aw8697_f0_show, aw8697_f0_store); +static DEVICE_ATTR(cali, S_IWUSR | S_IRUGO, aw8697_cali_show, + aw8697_cali_store); +static DEVICE_ATTR(cont, S_IWUSR | S_IRUGO, aw8697_cont_show, + aw8697_cont_store); +static DEVICE_ATTR(cont_td, S_IWUSR | S_IRUGO, aw8697_cont_td_show, + aw8697_cont_td_store); +static DEVICE_ATTR(cont_drv, S_IWUSR | S_IRUGO, aw8697_cont_drv_show, + aw8697_cont_drv_store); +static DEVICE_ATTR(cont_num_brk, S_IWUSR | S_IRUGO, aw8697_cont_num_brk_show, + aw8697_cont_num_brk_store); +static DEVICE_ATTR(cont_zc_thr, S_IWUSR | S_IRUGO, aw8697_cont_zc_thr_show, + aw8697_cont_zc_thr_store); +static DEVICE_ATTR(vbat_monitor, S_IWUSR | S_IRUGO, aw8697_vbat_monitor_show, + aw8697_vbat_monitor_store); +static DEVICE_ATTR(lra_resistance, S_IWUSR | S_IRUGO, + aw8697_lra_resistance_show, aw8697_lra_resistance_store); +static DEVICE_ATTR(auto_boost, S_IWUSR | S_IRUGO, aw8697_auto_boost_show, + aw8697_auto_boost_store); +static DEVICE_ATTR(prctmode, S_IWUSR | S_IRUGO, aw8697_prctmode_show, + aw8697_prctmode_store); +static DEVICE_ATTR(trig, S_IWUSR | S_IRUGO, aw8697_trig_show, + aw8697_trig_store); +static DEVICE_ATTR(ram_vbat_comp, S_IWUSR | S_IRUGO, aw8697_ram_vbat_comp_show, + aw8697_ram_vbat_comp_store); +static DEVICE_ATTR(osc_cali, S_IWUSR | S_IRUGO, aw8697_osc_cali_show, + aw8697_osc_cali_store); +static DEVICE_ATTR(f0_save, S_IWUSR | S_IRUGO, aw8697_f0_save_show, + aw8697_f0_save_store); +static DEVICE_ATTR(osc_save, S_IWUSR | S_IRUGO, aw8697_osc_cali_show, + aw8697_osc_save_store); +static DEVICE_ATTR(f0_value, S_IRUGO, aw8697_f0_value_show, NULL); +static DEVICE_ATTR(custom_wave, S_IWUSR | S_IRUGO, aw8697_custom_wave_show, + aw8697_custom_wave_store); + +static struct attribute *aw8697_vibrator_attributes[] = { + &dev_attr_reg.attr, &dev_attr_ram.attr, + &dev_attr_activate_test.attr, &dev_attr_duration.attr, + &dev_attr_activate.attr, &dev_attr_activate_mode.attr, + &dev_attr_index.attr, &dev_attr_vmax.attr, + &dev_attr_gain.attr, &dev_attr_seq.attr, + &dev_attr_loop.attr, &dev_attr_rtp.attr, + &dev_attr_ram_update.attr, &dev_attr_f0.attr, + &dev_attr_cali.attr, &dev_attr_cont.attr, + &dev_attr_cont_td.attr, &dev_attr_cont_drv.attr, + &dev_attr_cont_num_brk.attr, &dev_attr_cont_zc_thr.attr, + &dev_attr_vbat_monitor.attr, &dev_attr_lra_resistance.attr, + &dev_attr_auto_boost.attr, &dev_attr_prctmode.attr, + &dev_attr_trig.attr, &dev_attr_ram_vbat_comp.attr, + &dev_attr_osc_cali.attr, &dev_attr_osc_save.attr, + &dev_attr_f0_save.attr, &dev_attr_f0_value.attr, + &dev_attr_custom_wave.attr, NULL +}; + +static struct attribute_group aw8697_vibrator_attribute_group = { + .attrs = aw8697_vibrator_attributes +}; + +/****************************************************** + * + * i2c driver + * + ******************************************************/ +static int aw8697_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct aw8697 *aw8697; + struct input_dev *input_dev; + int rc = 0, effect_count_max; + struct ff_device *ff; + struct device_node *np = i2c->dev.of_node; + int irq_flags = 0; + int ret = -1; +#ifdef ENABLE_PIN_CONTROL + int i; +#endif + + pr_info("%s enter\n", __func__); + if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) { + dev_err(&i2c->dev, "check_functionality failed\n"); + return -EIO; + } + + aw8697 = devm_kzalloc(&i2c->dev, sizeof(struct aw8697), GFP_KERNEL); + if (aw8697 == NULL) + return -ENOMEM; + + input_dev = devm_input_allocate_device(&i2c->dev); + if (!input_dev) + return -ENOMEM; + + aw8697->dev = &i2c->dev; + aw8697->i2c = i2c; + device_init_wakeup(aw8697->dev, true); + i2c_set_clientdata(i2c, aw8697); + + /* aw8697 rst & int */ + if (np) { + ret = aw8697_parse_dt(&i2c->dev, aw8697, np); + printk("%s ---%d \n", __func__, __LINE__); + if (ret) { + dev_err(&i2c->dev, + "%s: failed to parse device tree node\n", + __func__); + goto err_parse_dt; + } + } else { + aw8697->reset_gpio = -1; + aw8697->irq_gpio = -1; + } + aw8697->enable_pin_control = 0; +#ifdef ENABLE_PIN_CONTROL + aw8697->aw8697_pinctrl = devm_pinctrl_get(&i2c->dev); + if (IS_ERR(aw8697->aw8697_pinctrl)) { + if (PTR_ERR(aw8697->aw8697_pinctrl) == -EPROBE_DEFER) { + printk("pinctrl not ready\n"); + rc = -EPROBE_DEFER; + return rc; + } + printk("Target does not use pinctrl\n"); + aw8697->aw8697_pinctrl = NULL; + rc = -EINVAL; + return rc; + } + for (i = 0; i < ARRAY_SIZE(aw8697->pinctrl_state); i++) { + const char *n = pctl_names[i]; + struct pinctrl_state *state = + pinctrl_lookup_state(aw8697->aw8697_pinctrl, n); + if (IS_ERR(state)) { + printk("cannot find '%s'\n", n); + rc = -EINVAL; + //goto exit; + } + printk("found pin control %s\n", n); + aw8697->pinctrl_state[i] = state; + aw8697->enable_pin_control = 1; + aw8697_set_interrupt(aw8697); + } +#endif + printk("%s ---%d \n", __func__, __LINE__); + if (!aw8697->enable_pin_control) { + if (gpio_is_valid(aw8697->reset_gpio)) { + ret = devm_gpio_request_one(&i2c->dev, + aw8697->reset_gpio, + GPIOF_OUT_INIT_LOW, + "aw8697_rst"); + if (ret) { + dev_err(&i2c->dev, "%s: rst request failed\n", + __func__); + goto err_reset_gpio_request; + } + } + } + + if (gpio_is_valid(aw8697->irq_gpio)) { + ret = devm_gpio_request_one(&i2c->dev, aw8697->irq_gpio, + GPIOF_DIR_IN, "aw8697_int"); + if (ret) { + dev_err(&i2c->dev, "%s: int request failed\n", + __func__); + goto err_irq_gpio_request; + } + } + + ret = aw8697_read_chipid(aw8697); + if (ret < 0) { + dev_err(&i2c->dev, "%s: aw8697_read_chipid failed ret=%d\n", + __func__, ret); + goto err_id; + } + + if (gpio_is_valid(aw8697->irq_gpio) && + !(aw8697->flags & AW8697_FLAG_SKIP_INTERRUPTS)) { + /* register irq handler */ + aw8697_interrupt_setup(aw8697); + irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; + ret = devm_request_threaded_irq(&i2c->dev, + gpio_to_irq(aw8697->irq_gpio), + NULL, aw8697_irq, irq_flags, + "aw8697", aw8697); + if (ret != 0) { + dev_err(&i2c->dev, "%s: failed to request IRQ %d: %d\n", + __func__, gpio_to_irq(aw8697->irq_gpio), ret); + goto err_irq; + } + } else { + dev_info(&i2c->dev, "%s skipping IRQ registration\n", __func__); + /* disable feature support if gpio was invalid */ + aw8697->flags |= AW8697_FLAG_SKIP_INTERRUPTS; + } + + hrtimer_init(&aw8697->stop_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + aw8697->stop_timer.function = qti_hap_stop_timer; + hrtimer_init(&aw8697->hap_disable_timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); + aw8697->hap_disable_timer.function = qti_hap_disable_timer; + + input_dev->name = "aw8697_haptic"; // "qti-haptics"; + input_set_drvdata(input_dev, aw8697); + aw8697->input_dev = input_dev; + input_set_capability(input_dev, EV_FF, FF_CONSTANT); + input_set_capability(input_dev, EV_FF, FF_GAIN); + if (aw8697->effects_count != 0) { + input_set_capability(input_dev, EV_FF, FF_PERIODIC); + input_set_capability(input_dev, EV_FF, FF_CUSTOM); + } + + if (aw8697->effects_count + 1 > FF_EFFECT_COUNT_MAX) + effect_count_max = aw8697->effects_count + 1; + else + effect_count_max = FF_EFFECT_COUNT_MAX; + rc = input_ff_create(input_dev, effect_count_max); + if (rc < 0) { + dev_err(aw8697->dev, "create FF input device failed, rc=%d\n", + rc); + return rc; + } + aw8697->work_queue = + create_singlethread_workqueue("aw8976_vibrator_work_queue"); + if (!aw8697->work_queue) { + dev_err(&i2c->dev, + "%s: Error creating aw8976_vibrator_work_queue\n", + __func__); + goto err_sysfs; + } + INIT_WORK(&aw8697->set_gain_work, set_gain); + aw8697_vibrator_init(aw8697); + aw8697_haptic_init(aw8697); + aw8697_ram_init(aw8697); + + ff = input_dev->ff; + ff->upload = aw8697_haptics_upload_effect; + ff->playback = aw8697_haptics_playback; + ff->erase = aw8697_haptics_erase; + ff->set_gain = aw8697_haptics_set_gain; + rc = input_register_device(input_dev); + if (rc < 0) { + dev_err(aw8697->dev, "register input device failed, rc=%d\n", + rc); + goto destroy_ff; + } + + dev_set_drvdata(&i2c->dev, aw8697); + ret = sysfs_create_group(&i2c->dev.kobj, + &aw8697_vibrator_attribute_group); + if (ret < 0) { + dev_info(&i2c->dev, "%s error creating sysfs attr files\n", + __func__); + goto err_sysfs; + } + + g_aw8697 = aw8697; + ret = create_rb(); + if (ret < 0) { + dev_info(&i2c->dev, "%s error creating ringbuffer\n", __func__); + goto err_rb; + } + + CUSTOME_WAVE_ID = aw8697->info.effect_max; + pr_info("%s probe completed successfully!\n", __func__); + + return 0; + +err_rb: + sysfs_remove_group(&i2c->dev.kobj, &aw8697_vibrator_attribute_group); +err_sysfs: + devm_free_irq(&i2c->dev, gpio_to_irq(aw8697->irq_gpio), aw8697); +destroy_ff: + input_ff_destroy(aw8697->input_dev); +err_irq: +err_id: + if (gpio_is_valid(aw8697->irq_gpio)) + devm_gpio_free(&i2c->dev, aw8697->irq_gpio); +err_irq_gpio_request: + if (gpio_is_valid(aw8697->reset_gpio)) + devm_gpio_free(&i2c->dev, aw8697->reset_gpio); +err_reset_gpio_request: +err_parse_dt: + device_init_wakeup(aw8697->dev, false); + devm_kfree(&i2c->dev, aw8697); + aw8697 = NULL; + return ret; +} + +static int aw8697_i2c_remove(struct i2c_client *i2c) +{ + struct aw8697 *aw8697 = i2c_get_clientdata(i2c); + + pr_info("%s enter\n", __func__); + + sysfs_remove_group(&i2c->dev.kobj, &aw8697_vibrator_attribute_group); + + devm_free_irq(&i2c->dev, gpio_to_irq(aw8697->irq_gpio), aw8697); + + if (gpio_is_valid(aw8697->irq_gpio)) + devm_gpio_free(&i2c->dev, aw8697->irq_gpio); + if (gpio_is_valid(aw8697->reset_gpio)) + devm_gpio_free(&i2c->dev, aw8697->reset_gpio); + if (aw8697 != NULL) { + flush_workqueue(aw8697->work_queue); + destroy_workqueue(aw8697->work_queue); + } + device_init_wakeup(aw8697->dev, false); + release_rb(); + devm_kfree(&i2c->dev, aw8697); + aw8697 = NULL; + + return 0; +} + +static const struct i2c_device_id aw8697_i2c_id[] = { { AW8697_I2C_NAME, 0 }, + {} }; + +MODULE_DEVICE_TABLE(i2c, aw8697_i2c_id); + +static struct of_device_id aw8697_dt_match[] = { + { .compatible = "awinic,aw8697_haptic" }, + {}, +}; + +static struct i2c_driver aw8697_i2c_driver = { + .driver = { + .name = AW8697_I2C_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(aw8697_dt_match), + }, + .probe = aw8697_i2c_probe, + .remove = aw8697_i2c_remove, + .id_table = aw8697_i2c_id, +}; + +static int __init aw8697_i2c_init(void) +{ + int ret = 0; + + pr_info("aw8697 driver version %s\n", AW8697_VERSION); + + ret = i2c_add_driver(&aw8697_i2c_driver); + if (ret) { + pr_err("fail to add aw8697 device into i2c\n"); + return ret; + } + + return 0; +} + +module_init(aw8697_i2c_init); + +static void __exit aw8697_i2c_exit(void) +{ + i2c_del_driver(&aw8697_i2c_driver); +} + +module_exit(aw8697_i2c_exit); + +MODULE_DESCRIPTION("AW8697 Haptic Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/misc/aw8697_haptic_xm/aw8697.h b/drivers/input/misc/aw8697_haptic_xm/aw8697.h new file mode 100644 index 000000000000..444023b954c4 --- /dev/null +++ b/drivers/input/misc/aw8697_haptic_xm/aw8697.h @@ -0,0 +1,454 @@ +#ifndef _AW8697_H_ +#define _AW8697_H_ + +/********************************************************* + * + * kernel version + * + ********************************************************/ +#define INPUT_DEV +//#define TEST_RTP +#define TEST_CONT_TO_RAM +/********************************************************* + * + * aw8697.h + * + ********************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/********************************************************* + * + * marco + * + ********************************************************/ +#define AW8697_CHIPID 0x97 + +#define MAX_I2C_BUFFER_SIZE 65536 + +#define AW8697_SEQUENCER_SIZE 8 +#define AW8697_SEQUENCER_LOOP_SIZE 4 + +#define AW8697_RTP_I2C_SINGLE_MAX_NUM 512 + +#define HAPTIC_MAX_TIMEOUT 10000 + +#define AW8697_VBAT_REFER 4200 +#define AW8697_VBAT_MIN 3000 +#define AW8697_VBAT_MAX 4500 +#define ENABLE_PIN_CONTROL + +#ifdef INPUT_DEV +/* common definitions */ +#define HAP_BRAKE_PATTERN_MAX 4 +#define HAP_WAVEFORM_BUFFER_MAX 8 /*used */ +#define HAP_VMAX_MV_DEFAULT 1800 +#define HAP_VMAX_MV_MAX 3596 +#define HAP_PLAY_RATE_US_DEFAULT 5715 /*used */ +#define HAP_PLAY_RATE_US_MAX 20475 +#define HAP_PLAY_RATE_US_LSB 5 +#define VMAX_MIN_PLAY_TIME_US 20000 +#define HAP_SC_DET_MAX_COUNT 5 +#define HAP_SC_DET_TIME_US 1000000 +#define FF_EFFECT_COUNT_MAX 32 +#define HAP_DISABLE_DELAY_USEC 1000 +#endif +/* + * trig default high level + * ___________ _________________ + * | | + * | | + * |___________| + * first edge + * second edge + * + * + * trig default low level + * ___________ + * | | + * | | + * __________| |_________________ + * first edge + * second edge + */ +/* trig config */ +/*dts config +* default_level -> 1: high level; 0: low level +* dual_edge -> 1: dual edge; 0: first edge +*vib_trig_config = < +* 1 1 1 1 2 +* enable default_level dual_edge first_seq second_seq +* 1 1 2 1 2 +* enable default_level dual_edge first_seq second_seq +* 1 1 3 1 2 +* enable default_level dual_edge first_seq second_seq +*/ +#define AW8697_TRIG_NUM 3 + +enum aw8697_flags { + AW8697_FLAG_NONR = 0, + AW8697_FLAG_SKIP_INTERRUPTS = 1, +}; + +enum aw8697_haptic_read_write { + AW8697_HAPTIC_CMD_READ_REG = 0, + AW8697_HAPTIC_CMD_WRITE_REG = 1, +}; + +enum aw8697_haptic_work_mode { + AW8697_HAPTIC_STANDBY_MODE = 0, + AW8697_HAPTIC_RAM_MODE = 1, + AW8697_HAPTIC_RTP_MODE = 2, + AW8697_HAPTIC_TRIG_MODE = 3, + AW8697_HAPTIC_CONT_MODE = 4, + AW8697_HAPTIC_RAM_LOOP_MODE = 5, +}; + +enum aw8697_haptic_bst_mode { + AW8697_HAPTIC_BYPASS_MODE = 0, + AW8697_HAPTIC_BOOST_MODE = 1, +}; + +enum aw8697_haptic_activate_mode { + AW8697_HAPTIC_ACTIVATE_RAM_MODE = 0, + AW8697_HAPTIC_ACTIVATE_CONT_MODE = 1, + AW8697_HAPTIC_ACTIVATE_RTP_MODE = 2, + AW8697_HAPTIC_ACTIVATE_RAM_LOOP_MODE = 3, +}; + +enum aw8697_haptic_cont_vbat_comp_mode { + AW8697_HAPTIC_CONT_VBAT_SW_COMP_MODE = 0, + AW8697_HAPTIC_CONT_VBAT_HW_COMP_MODE = 1, +}; + +enum aw8697_haptic_ram_vbat_comp_mode { + AW8697_HAPTIC_RAM_VBAT_COMP_DISABLE = 0, + AW8697_HAPTIC_RAM_VBAT_COMP_ENABLE = 1, +}; + +enum aw8697_haptic_f0_flag { + AW8697_HAPTIC_LRA_F0 = 0, + AW8697_HAPTIC_CALI_F0 = 1, +}; + +enum aw8697_haptic_pwm_mode { + AW8697_PWM_48K = 0, + AW8697_PWM_24K = 1, + AW8697_PWM_12K = 2, +}; + +enum aw8697_haptic_play { + AW8697_HAPTIC_PLAY_NULL = 0, + AW8697_HAPTIC_PLAY_ENABLE = 1, + AW8697_HAPTIC_PLAY_STOP = 2, + AW8697_HAPTIC_PLAY_GAIN = 8, +}; + +enum aw8697_haptic_cmd { + AW8697_HAPTIC_CMD_NULL = 0, + AW8697_HAPTIC_CMD_ENABLE = 1, + AW8697_HAPTIC_CMD_STOP = 255, +}; + +enum haptics_custom_effect_param { + CUSTOM_DATA_EFFECT_IDX, + CUSTOM_DATA_TIMEOUT_SEC_IDX, + CUSTOM_DATA_TIMEOUT_MSEC_IDX, + CUSTOM_DATA_LEN, +}; +enum aw8697_haptic_strength { + AW8697_LIGHT_MAGNITUDE = 0x3fff, + AW8697_MEDIUM_MAGNITUDE = 0x5fff, + AW8697_STRONG_MAGNITUDE = 0x7fff, +}; +/********************************************************* + * + * struct + * + ********************************************************/ +struct fileops { + unsigned char cmd; + unsigned char reg; + unsigned char ram_addrh; + unsigned char ram_addrl; +}; + +struct ram { + unsigned int len; + unsigned int check_sum; + unsigned int base_addr; + unsigned char version; + unsigned char ram_shift; + unsigned char baseaddr_shift; +}; + +struct haptic_ctr { + unsigned char cmd; + unsigned char play; + unsigned char wavseq; + unsigned char loop; + unsigned char gain; +}; + +struct haptic_audio { + struct mutex lock; + struct hrtimer timer; + struct work_struct work; + int delay_val; + int timer_val; + unsigned char cnt; + struct haptic_ctr data[256]; + struct haptic_ctr ctr; + unsigned char ori_gain; +}; + +struct trig { + unsigned char enable; + unsigned char default_level; + unsigned char dual_edge; + unsigned char frist_seq; + unsigned char second_seq; +}; + +struct aw8697_dts_info { + unsigned int mode; + unsigned int f0_pre; + unsigned int f0_cali_percen; + unsigned int cont_drv_lvl; + unsigned int cont_drv_lvl_ov; + unsigned int cont_td; + unsigned int cont_zc_thr; + unsigned int cont_num_brk; + unsigned int f0_coeff; + unsigned int f0_trace_parameter[4]; + unsigned int bemf_config[4]; + unsigned int sw_brake; + unsigned int tset; + unsigned int r_spare; + unsigned int bstdbg[6]; + unsigned int parameter1; + unsigned int effect_id_boundary; + unsigned int effect_max; + unsigned int rtp_time[175]; + unsigned int trig_config[3][5]; + unsigned int bst_vol_default; + unsigned int bst_vol_ram; + unsigned int bst_vol_rtp; +}; + +#ifdef INPUT_DEV +enum actutor_type { + ACT_LRA, + ACT_ERM, +}; + +enum lra_res_sig_shape { + RES_SIG_SINE, + RES_SIG_SQUARE, +}; + +enum lra_auto_res_mode { + AUTO_RES_MODE_ZXD, + AUTO_RES_MODE_QWD, +}; + +enum wf_src { + INT_WF_VMAX, + INT_WF_BUFFER, + EXT_WF_AUDIO, + EXT_WF_PWM, +}; + +struct qti_hap_effect { + int id; + u8 *pattern; + int pattern_length; + u16 play_rate_us; + u16 vmax_mv; + u8 wf_repeat_n; + u8 wf_s_repeat_n; + u8 brake[HAP_BRAKE_PATTERN_MAX]; + int brake_pattern_length; + bool brake_en; + bool lra_auto_res_disable; +}; + +struct qti_hap_play_info { + struct qti_hap_effect *effect; + u16 vmax_mv; + int length_us; + int playing_pos; + bool playing_pattern; +}; + +struct qti_hap_config { + enum actutor_type act_type; + enum lra_res_sig_shape lra_shape; + enum lra_auto_res_mode lra_auto_res_mode; + enum wf_src ext_src; + u16 vmax_mv; + u16 play_rate_us; + bool lra_allow_variable_play_rate; + bool use_ext_wf_src; +}; +#endif + +#ifdef ENABLE_PIN_CONTROL +const char *const pctl_names[] = { + "aw8697_reset_reset", + "aw8697_reset_active", + "aw8697_interrupt_active", +}; +#endif +struct aw8697 { + struct i2c_client *i2c; + struct mutex lock; +#ifdef ENABLE_PIN_CONTROL + struct pinctrl *aw8697_pinctrl; + struct pinctrl_state *pinctrl_state[ARRAY_SIZE(pctl_names)]; +#endif + int enable_pin_control; + struct work_struct vibrator_work; + struct work_struct rtp_work; + struct work_struct set_gain_work; + struct delayed_work ram_work; + + struct fileops fileops; + struct ram ram; + + struct timeval start, end; + unsigned int timeval_flags; + unsigned int osc_cali_flag; + unsigned long int microsecond; + unsigned int sys_frequency; + unsigned int rtp_len; + unsigned int lra_calib_data; + unsigned int f0_calib_data; + + int reset_gpio; + int irq_gpio; + + unsigned char hwen_flag; + unsigned char flags; + unsigned char chipid; + + unsigned char play_mode; + + unsigned char activate_mode; + + unsigned char auto_boost; + + int state; + int duration; + int amplitude; + int index; + int vmax; + int gain; + u16 new_gain; + unsigned char level; + + unsigned char seq[AW8697_SEQUENCER_SIZE]; + unsigned char loop[AW8697_SEQUENCER_SIZE]; + + unsigned int rtp_cnt; + unsigned int rtp_file_num; + + unsigned char rtp_init; + unsigned char ram_init; + + unsigned int f0; + unsigned int cont_f0; + unsigned char max_pos_beme; + unsigned char max_neg_beme; + unsigned char f0_cali_flag; + unsigned int osc_cali_run; + + unsigned char ram_vbat_comp; + unsigned int vbat; + unsigned int lra; + + struct trig trig[AW8697_TRIG_NUM]; + + struct haptic_audio haptic_audio; + struct aw8697_dts_info info; + atomic_t is_in_rtp_loop; + atomic_t exit_in_rtp_loop; + atomic_t is_in_write_loop; + wait_queue_head_t wait_q; //wait queue for exit irq mode + wait_queue_head_t stop_wait_q; //wait queue for stop rtp mode + struct workqueue_struct *work_queue; + +#ifdef INPUT_DEV + struct platform_device *pdev; + struct device *dev; + struct regmap *regmap; + struct input_dev *input_dev; + struct pwm_device *pwm_dev; + struct qti_hap_config config; + struct qti_hap_play_info play; + struct qti_hap_effect *predefined; + struct qti_hap_effect constant; + struct regulator *vdd_supply; + struct hrtimer stop_timer; + struct hrtimer hap_disable_timer; + struct hrtimer timer; /*test used ,del */ + struct dentry *hap_debugfs; + struct mutex rtp_lock; + spinlock_t bus_lock; + ktime_t last_sc_time; + int play_irq; + int sc_irq; + int effects_count; + int sc_det_count; + u16 reg_base; + bool perm_disable; + bool play_irq_en; + bool vdd_enabled; + int effect_type; + int effect_id; + int test_val; + int is_custom_wave; +#endif +}; + +struct aw8697_container { + int len; + unsigned char data[]; +}; + +/********************************************************* + * + * ioctl + * + ********************************************************/ +struct aw8697_seq_loop { + unsigned char loop[AW8697_SEQUENCER_SIZE]; +}; + +struct aw8697_que_seq { + unsigned char index[AW8697_SEQUENCER_SIZE]; +}; + +#define AW8697_HAPTIC_IOCTL_MAGIC 'h' + +#define AW8697_HAPTIC_SET_QUE_SEQ \ + _IOWR(AW8697_HAPTIC_IOCTL_MAGIC, 1, struct aw8697_que_seq *) +#define AW8697_HAPTIC_SET_SEQ_LOOP \ + _IOWR(AW8697_HAPTIC_IOCTL_MAGIC, 2, struct aw8697_seq_loop *) +#define AW8697_HAPTIC_PLAY_QUE_SEQ \ + _IOWR(AW8697_HAPTIC_IOCTL_MAGIC, 3, unsigned int) +#define AW8697_HAPTIC_SET_BST_VOL \ + _IOWR(AW8697_HAPTIC_IOCTL_MAGIC, 4, unsigned int) +#define AW8697_HAPTIC_SET_BST_PEAK_CUR \ + _IOWR(AW8697_HAPTIC_IOCTL_MAGIC, 5, unsigned int) +#define AW8697_HAPTIC_SET_GAIN _IOWR(AW8697_HAPTIC_IOCTL_MAGIC, 6, unsigned int) +#define AW8697_HAPTIC_PLAY_REPEAT_SEQ \ + _IOWR(AW8697_HAPTIC_IOCTL_MAGIC, 7, unsigned int) + +#endif diff --git a/drivers/input/misc/aw8697_haptic_xm/aw8697_config.h b/drivers/input/misc/aw8697_haptic_xm/aw8697_config.h new file mode 100644 index 000000000000..ca3119c0d868 --- /dev/null +++ b/drivers/input/misc/aw8697_haptic_xm/aw8697_config.h @@ -0,0 +1,117 @@ +#ifndef __AW8697_CONFIG_H__ +#define __AW8697_CONFIG_H__ + +#define AW8697_BSTCFG_PEAKCUR_LIMIT 0x07 +#define AW8697_DEFAULT_PEAKCUR AW8697_BIT_BSTCFG_PEAKCUR_3P5A + +#define AW8697_CONT_PLAYBACK_MODE AW8697_BIT_CONT_CTRL_CLOSE_PLAYBACK + +/*#define CONFIG_DEBUG_FS*/ + +/*#ifdef INPUT_DEV*/ +#if 1 +/* haptics module register definitions */ +#define REG_HAP_STATUS1 0x0A +#define HAP_SC_DET_BIT BIT(3) +#define HAP_BUSY_BIT BIT(1) + +#define REG_HAP_EN_CTL1 0x46 +#define HAP_EN_BIT BIT(7) + +#define REG_HAP_EN_CTL2 0x48 +#define HAP_AUTO_STANDBY_EN_BIT BIT(1) +#define HAP_BRAKE_EN_BIT BIT(0) + +#define REG_HAP_EN_CTL3 0x4A +#define HAP_HBRIDGE_EN_BIT BIT(7) +#define HAP_PWM_SIGNAL_EN_BIT BIT(6) +#define HAP_ILIM_EN_BIT BIT(5) +#define HAP_ILIM_CC_EN_BIT BIT(4) +#define HAP_AUTO_RES_RBIAS_EN_BIT BIT(3) +#define HAP_DAC_EN_BIT BIT(2) +#define HAP_ZX_HYST_EN_BIT BIT(1) +#define HAP_PWM_CTL_EN_BIT BIT(0) + +#define REG_HAP_AUTO_RES_CTRL 0x4B +#define HAP_AUTO_RES_EN_BIT BIT(7) +#define HAP_SEL_AUTO_RES_PERIOD BIT(6) +#define HAP_AUTO_RES_CNT_ERR_DELTA_MASK GENMASK(5, 4) +#define HAP_AUTO_RES_CNT_ERR_DELTA_SHIFT 4 +#define HAP_AUTO_RES_ERR_RECOVERY_BIT BIT(3) +#define HAP_AUTO_RES_EN_DLY_MASK GENMASK(2, 0) +#define AUTO_RES_CNT_ERR_DELTA(x) (x << HAP_AUTO_RES_CNT_ERR_DELTA_SHIFT) +#define AUTO_RES_EN_DLY(x) x + +#define REG_HAP_CFG1 0x4C +#define REG_HAP_CFG2 0x4D +#define HAP_LRA_RES_TYPE_BIT BIT(0) + +#define REG_HAP_SEL 0x4E +#define HAP_WF_SOURCE_MASK GENMASK(5, 4) +#define HAP_WF_SOURCE_SHIFT 4 +#define HAP_WF_TRIGGER_BIT BIT(0) +#define HAP_WF_SOURCE_VMAX (0 << HAP_WF_SOURCE_SHIFT) +#define HAP_WF_SOURCE_BUFFER (1 << HAP_WF_SOURCE_SHIFT) +#define HAP_WF_SOURCE_AUDIO (2 << HAP_WF_SOURCE_SHIFT) +#define HAP_WF_SOURCE_PWM (3 << HAP_WF_SOURCE_SHIFT) + +#define REG_HAP_AUTO_RES_CFG 0x4F +#define HAP_AUTO_RES_MODE_BIT BIT(7) +#define HAP_AUTO_RES_MODE_SHIFT 7 +#define HAP_AUTO_RES_CAL_DURATON_MASK GENMASK(6, 5) +#define HAP_CAL_EOP_EN_BIT BIT(3) +#define HAP_CAL_PERIOD_MASK GENMASK(2, 0) +#define HAP_CAL_OPT3_EVERY_8_PERIOD 2 + +#define REG_HAP_SLEW_CFG 0x50 +#define REG_HAP_VMAX_CFG 0x51 +#define HAP_VMAX_SIGN_BIT BIT(7) +#define HAP_VMAX_OVD_BIT BIT(6) +#define HAP_VMAX_MV_MASK GENMASK(5, 1) +#define HAP_VMAX_MV_SHIFT 1 +#define HAP_VMAX_MV_LSB 116 + +#define REG_HAP_ILIM_CFG 0x52 +#define HAP_ILIM_SEL_1000MA BIT(1) +#define HAP_ILIM_DEFAULT_SEL HAP_ILIM_SEL_1000MA +#define REG_HAP_SC_DEB_CFG 0x53 +#define REG_HAP_RATE_CFG1 0x54 +#define REG_HAP_RATE_CFG2 0x55 +#define REG_HAP_INTERNAL_PWM 0x56 +#define REG_HAP_EXTERNAL_PWM 0x57 +#define REG_HAP_PWM 0x58 + +#define REG_HAP_SC_CLR 0x59 +#define HAP_SC_CLR_BIT BIT(0) + +#define REG_HAP_ZX_CFG 0x5A +#define HAP_ZX_DET_DEB_MASK GENMASK(2, 0) +#define ZX_DET_DEB_10US 0 +#define ZX_DET_DEB_20US 1 +#define ZX_DET_DEB_40US 2 +#define ZX_DET_DEB_80US 3 + +#define REG_HAP_BRAKE 0x5C +#define HAP_BRAKE_PATTERN_MASK 0x3 +#define HAP_BRAKE_PATTERN_SHIFT 2 + +#define REG_HAP_WF_REPEAT 0x5E +#define HAP_WF_REPEAT_MASK GENMASK(6, 4) +#define HAP_WF_REPEAT_SHIFT 4 +#define HAP_WF_S_REPEAT_MASK GENMASK(1, 0) + +#define REG_HAP_WF_S1 0x60 +#define HAP_WF_SIGN_BIT BIT(7) +#define HAP_WF_OVD_BIT BIT(6) +#define HAP_WF_AMP_BIT GENMASK(5, 1) +#define HAP_WF_AMP_SHIFT 1 + +#define REG_HAP_PLAY 0x70 +#define HAP_PLAY_BIT BIT(7) + +#define REG_HAP_SEC_ACCESS 0xD0 + +static int wf_repeat[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; +static int wf_s_repeat[4] = { 1, 2, 4, 8 }; +#endif +#endif diff --git a/drivers/input/misc/aw8697_haptic_xm/aw8697_reg.h b/drivers/input/misc/aw8697_haptic_xm/aw8697_reg.h new file mode 100644 index 000000000000..09e5424eda6f --- /dev/null +++ b/drivers/input/misc/aw8697_haptic_xm/aw8697_reg.h @@ -0,0 +1,539 @@ +#ifndef _AW8697_REG_H_ +#define _AW8697_REG_H_ + +/******************************************** + * Register List + *******************************************/ +#define AW8697_REG_ID 0x00 +#define AW8697_REG_SYSST 0x01 +#define AW8697_REG_SYSINT 0x02 +#define AW8697_REG_SYSINTM 0x03 +#define AW8697_REG_SYSCTRL 0x04 +#define AW8697_REG_GO 0x05 +#define AW8697_REG_RTP_DATA 0x06 +#define AW8697_REG_WAVSEQ1 0x07 +#define AW8697_REG_WAVSEQ2 0x08 +#define AW8697_REG_WAVSEQ3 0x09 +#define AW8697_REG_WAVSEQ4 0x0a +#define AW8697_REG_WAVSEQ5 0x0b +#define AW8697_REG_WAVSEQ6 0x0c +#define AW8697_REG_WAVSEQ7 0x0d +#define AW8697_REG_WAVSEQ8 0x0e +#define AW8697_REG_WAVLOOP1 0x0f +#define AW8697_REG_WAVLOOP2 0x10 +#define AW8697_REG_WAVLOOP3 0x11 +#define AW8697_REG_WAVLOOP4 0x12 +#define AW8697_REG_MAIN_LOOP 0x13 +#define AW8697_REG_TRG1_WAV_P 0x14 +#define AW8697_REG_TRG2_WAV_P 0x15 +#define AW8697_REG_TRG3_WAV_P 0x16 +#define AW8697_REG_TRG1_WAV_N 0x17 +#define AW8697_REG_TRG2_WAV_N 0x18 +#define AW8697_REG_TRG3_WAV_N 0x19 +#define AW8697_REG_TRG_PRIO 0x1a +#define AW8697_REG_TRG_CFG1 0x1b +#define AW8697_REG_TRG_CFG2 0x1c +#define AW8697_REG_DBGCTRL 0x20 +#define AW8697_REG_BASE_ADDRH 0x21 +#define AW8697_REG_BASE_ADDRL 0x22 +#define AW8697_REG_FIFO_AEH 0x23 +#define AW8697_REG_FIFO_AEL 0x24 +#define AW8697_REG_FIFO_AFH 0x25 +#define AW8697_REG_FIFO_AFL 0x26 +#define AW8697_REG_WAKE_DLY 0x27 +#define AW8697_REG_START_DLY 0x28 +#define AW8697_REG_END_DLY_H 0x29 +#define AW8697_REG_END_DLY_L 0x2a +#define AW8697_REG_DATCTRL 0x2b +#define AW8697_REG_PWMDEL 0x2c +#define AW8697_REG_PWMPRC 0x2d +#define AW8697_REG_PWMDBG 0x2e +#define AW8697_REG_LDOCTRL 0x2f +#define AW8697_REG_DBGSTAT 0x30 +#define AW8697_REG_BSTDBG1 0x31 +#define AW8697_REG_BSTDBG2 0x32 +#define AW8697_REG_BSTDBG3 0x33 +#define AW8697_REG_BSTCFG 0x34 +#define AW8697_REG_ANADBG 0x35 +#define AW8697_REG_ANACTRL 0x36 +#define AW8697_REG_CPDBG 0x37 +#define AW8697_REG_GLBDBG 0x38 +#define AW8697_REG_DATDBG 0x39 +#define AW8697_REG_BSTDBG4 0x3a +#define AW8697_REG_BSTDBG5 0x3b +#define AW8697_REG_BSTDBG6 0x3c +#define AW8697_REG_HDRVDBG 0x3d +#define AW8697_REG_PRLVL 0x3e +#define AW8697_REG_PRTIME 0x3f +#define AW8697_REG_RAMADDRH 0x40 +#define AW8697_REG_RAMADDRL 0x41 +#define AW8697_REG_RAMDATA 0x42 +#define AW8697_REG_GLB_STATE 0x46 +#define AW8697_REG_BST_AUTO 0x47 +#define AW8697_REG_CONT_CTRL 0x48 +#define AW8697_REG_F_PRE_H 0x49 +#define AW8697_REG_F_PRE_L 0x4a +#define AW8697_REG_TD_H 0x4b +#define AW8697_REG_TD_L 0x4c +#define AW8697_REG_TSET 0x4d +#define AW8697_REG_TRIM_LRA 0x5b +#define AW8697_REG_R_SPARE 0x5d +#define AW8697_REG_D2SCFG 0x5e +#define AW8697_REG_DETCTRL 0x5f +#define AW8697_REG_RLDET 0x60 +#define AW8697_REG_OSDET 0x61 +#define AW8697_REG_VBATDET 0x62 +#define AW8697_REG_TESTDET 0x63 +#define AW8697_REG_DETLO 0x64 +#define AW8697_REG_BEMFDBG 0x65 +#define AW8697_REG_ADCTEST 0x66 +#define AW8697_REG_BEMFTEST 0x67 +#define AW8697_REG_F_LRA_F0_H 0x68 +#define AW8697_REG_F_LRA_F0_L 0x69 +#define AW8697_REG_F_LRA_CONT_H 0x6a +#define AW8697_REG_F_LRA_CONT_L 0x6b +#define AW8697_REG_WAIT_VOL_MP 0x6d +#define AW8697_REG_WAIT_VOL_MN 0x6f +#define AW8697_REG_BEMF_VOL_H 0x70 +#define AW8697_REG_BEMF_VOL_L 0x71 +#define AW8697_REG_ZC_THRSH_H 0x72 +#define AW8697_REG_ZC_THRSH_L 0x73 +#define AW8697_REG_BEMF_VTHH_H 0x74 +#define AW8697_REG_BEMF_VTHH_L 0x75 +#define AW8697_REG_BEMF_VTHL_H 0x76 +#define AW8697_REG_BEMF_VTHL_L 0x77 +#define AW8697_REG_BEMF_NUM 0x78 +#define AW8697_REG_DRV_TIME 0x79 +#define AW8697_REG_TIME_NZC 0x7a +#define AW8697_REG_DRV_LVL 0x7b +#define AW8697_REG_DRV_LVL_OV 0x7c +#define AW8697_REG_NUM_F0_1 0x7d +#define AW8697_REG_NUM_F0_2 0x7e +#define AW8697_REG_NUM_F0_3 0x7f + +/******************************************** + * Register Access + *******************************************/ +#define REG_NONE_ACCESS 0 +#define REG_RD_ACCESS (1 << 0) +#define REG_WR_ACCESS (1 << 1) +#define AW8697_REG_MAX 0xff + +const unsigned char aw8697_reg_access[AW8697_REG_MAX] = { + [AW8697_REG_ID] = REG_RD_ACCESS, + [AW8697_REG_SYSST] = REG_RD_ACCESS, + [AW8697_REG_SYSINT] = REG_RD_ACCESS, + [AW8697_REG_SYSINTM] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_SYSCTRL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_GO] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_RTP_DATA] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAVSEQ1] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAVSEQ2] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAVSEQ3] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAVSEQ4] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAVSEQ5] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAVSEQ6] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAVSEQ7] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAVSEQ8] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAVLOOP1] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAVLOOP2] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAVLOOP3] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAVLOOP4] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_MAIN_LOOP] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TRG1_WAV_P] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TRG2_WAV_P] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TRG3_WAV_P] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TRG1_WAV_N] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TRG2_WAV_N] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TRG3_WAV_N] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TRG_PRIO] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TRG_CFG1] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TRG_CFG2] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_DBGCTRL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BASE_ADDRH] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BASE_ADDRL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_FIFO_AEH] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_FIFO_AEL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_FIFO_AFH] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_FIFO_AFL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAKE_DLY] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_START_DLY] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_END_DLY_H] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_END_DLY_L] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_DATCTRL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_PWMDEL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_PWMPRC] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_PWMDBG] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_LDOCTRL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_DBGSTAT] = REG_RD_ACCESS, + [AW8697_REG_BSTDBG1] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BSTDBG2] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BSTDBG3] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BSTCFG] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_ANADBG] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_ANACTRL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_CPDBG] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_GLBDBG] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_DATDBG] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BSTDBG4] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BSTDBG5] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BSTDBG6] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_HDRVDBG] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_PRLVL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_PRTIME] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_RAMADDRH] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_RAMADDRL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_RAMDATA] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_GLB_STATE] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BST_AUTO] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_CONT_CTRL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_F_PRE_H] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_F_PRE_L] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TD_H] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TD_L] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TSET] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TRIM_LRA] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_R_SPARE] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_D2SCFG] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_DETCTRL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_RLDET] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_OSDET] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_VBATDET] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TESTDET] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_DETLO] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BEMFDBG] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_ADCTEST] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BEMFTEST] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_F_LRA_F0_H] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_F_LRA_F0_L] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_F_LRA_CONT_H] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_F_LRA_CONT_L] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAIT_VOL_MP] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_WAIT_VOL_MN] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BEMF_VOL_H] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BEMF_VOL_L] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_ZC_THRSH_H] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_ZC_THRSH_L] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BEMF_VTHH_H] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BEMF_VTHH_L] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BEMF_VTHL_H] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BEMF_VTHL_L] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_BEMF_NUM] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_DRV_TIME] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_TIME_NZC] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_DRV_LVL] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_DRV_LVL_OV] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_NUM_F0_1] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_NUM_F0_2] = REG_RD_ACCESS | REG_WR_ACCESS, + [AW8697_REG_NUM_F0_3] = REG_RD_ACCESS | REG_WR_ACCESS, +}; + +/****************************************************** + * Register Detail + *****************************************************/ +/* SYSST: reg0x01 */ +#define AW8697_BIT_SYSST_BSTERRS (1 << 7) +#define AW8697_BIT_SYSST_OVS (1 << 6) +#define AW8697_BIT_SYSST_UVLS (1 << 5) +#define AW8697_BIT_SYSST_FF_AES (1 << 4) +#define AW8697_BIT_SYSST_FF_AFS (1 << 3) +#define AW8697_BIT_SYSST_OCDS (1 << 2) +#define AW8697_BIT_SYSST_OTS (1 << 1) +#define AW8697_BIT_SYSST_DONES (1 << 0) + +/* SYSINT: reg0x02 */ +#define AW8697_BIT_SYSINT_BSTERRI (1 << 7) +#define AW8697_BIT_SYSINT_OVI (1 << 6) +#define AW8697_BIT_SYSINT_UVLI (1 << 5) +#define AW8697_BIT_SYSINT_FF_AEI (1 << 4) +#define AW8697_BIT_SYSINT_FF_AFI (1 << 3) +#define AW8697_BIT_SYSINT_OCDI (1 << 2) +#define AW8697_BIT_SYSINT_OTI (1 << 1) +#define AW8697_BIT_SYSINT_DONEI (1 << 0) + +/* SYSINTM: reg0x03 */ +#define AW8697_BIT_SYSINTM_BSTERR_MASK (~(1 << 7)) +#define AW8697_BIT_SYSINTM_BSTERR_OFF (1 << 7) +#define AW8697_BIT_SYSINTM_BSTERR_EN (0 << 7) +#define AW8697_BIT_SYSINTM_OV_MASK (~(1 << 6)) +#define AW8697_BIT_SYSINTM_OV_OFF (1 << 6) +#define AW8697_BIT_SYSINTM_OV_EN (0 << 6) +#define AW8697_BIT_SYSINTM_UVLO_MASK (~(1 << 5)) +#define AW8697_BIT_SYSINTM_UVLO_OFF (1 << 5) +#define AW8697_BIT_SYSINTM_UVLO_EN (0 << 5) +#define AW8697_BIT_SYSINTM_FF_AE_MASK (~(1 << 4)) +#define AW8697_BIT_SYSINTM_FF_AE_OFF (1 << 4) +#define AW8697_BIT_SYSINTM_FF_AE_EN (0 << 4) +#define AW8697_BIT_SYSINTM_FF_AF_MASK (~(1 << 3)) +#define AW8697_BIT_SYSINTM_FF_AF_OFF (1 << 3) +#define AW8697_BIT_SYSINTM_FF_AF_EN (0 << 3) +#define AW8697_BIT_SYSINTM_OCD_MASK (~(1 << 2)) +#define AW8697_BIT_SYSINTM_OCD_OFF (1 << 2) +#define AW8697_BIT_SYSINTM_OCD_EN (0 << 2) +#define AW8697_BIT_SYSINTM_OT_MASK (~(1 << 1)) +#define AW8697_BIT_SYSINTM_OT_OFF (1 << 1) +#define AW8697_BIT_SYSINTM_OT_EN (0 << 1) +#define AW8697_BIT_SYSINTM_DONE_MASK (~(1 << 0)) +#define AW8697_BIT_SYSINTM_DONE_OFF (1 << 0) +#define AW8697_BIT_SYSINTM_DONE_EN (0 << 0) + +/* SYSCTRL: reg0x04 */ +#define AW8697_BIT_SYSCTRL_WAVDAT_MODE_MASK (~(3 << 6)) +#define AW8697_BIT_SYSCTRL_WAVDAT_MODE_4X (3 << 6) +#define AW8697_BIT_SYSCTRL_WAVDAT_MODE_2X (0 << 6) +#define AW8697_BIT_SYSCTRL_WAVDAT_MODE_1X (1 << 6) +#define AW8697_BIT_SYSCTRL_RAMINIT_MASK (~(1 << 5)) +#define AW8697_BIT_SYSCTRL_RAMINIT_EN (1 << 5) +#define AW8697_BIT_SYSCTRL_RAMINIT_OFF (0 << 5) +#define AW8697_BIT_SYSCTRL_PLAY_MODE_MASK (~(3 << 2)) +#define AW8697_BIT_SYSCTRL_PLAY_MODE_CONT (2 << 2) +#define AW8697_BIT_SYSCTRL_PLAY_MODE_RTP (1 << 2) +#define AW8697_BIT_SYSCTRL_PLAY_MODE_RAM (0 << 2) +#define AW8697_BIT_SYSCTRL_BST_MODE_MASK (~(1 << 1)) +#define AW8697_BIT_SYSCTRL_BST_MODE_BOOST (1 << 1) +#define AW8697_BIT_SYSCTRL_BST_MODE_BYPASS (0 << 1) +#define AW8697_BIT_SYSCTRL_WORK_MODE_MASK (~(1 << 0)) +#define AW8697_BIT_SYSCTRL_STANDBY (1 << 0) +#define AW8697_BIT_SYSCTRL_ACTIVE (0 << 0) + +/* GO: reg0x05 */ +#define AW8697_BIT_GO_MASK (~(1 << 0)) +#define AW8697_BIT_GO_ENABLE (1 << 0) +#define AW8697_BIT_GO_DISABLE (0 << 0) + +/* WAVSEQ1: reg0x07 */ +#define AW8697_BIT_WAVSEQ1_WAIT (1 << 7) +#define AW8697_BIT_WAVSEQ1_WAV_FRM_SEQ1_MASK (~(127 << 0)) + +/* WAVSEQ2: reg0x08 */ +#define AW8697_BIT_WAVSEQ2_WAIT (1 << 7) +#define AW8697_BIT_WAVSEQ2_WAV_FRM_SEQ2_MASK (~(127 << 0)) + +/* WAVSEQ3: reg0x09 */ +#define AW8697_BIT_WAVSEQ3_WAIT (1 << 7) +#define AW8697_BIT_WAVSEQ3_WAV_FRM_SEQ3_MASK (~(127 << 0)) + +/* WAVSEQ4: reg0x0a */ +#define AW8697_BIT_WAVSEQ4_WAIT (1 << 7) +#define AW8697_BIT_WAVSEQ4_WAV_FRM_SEQ4_MASK (~(127 << 0)) + +/* WAVSEQ5: reg0x0b */ +#define AW8697_BIT_WAVSEQ5_WAIT (1 << 7) +#define AW8697_BIT_WAVSEQ5_WAV_FRM_SEQ5_MASK (~(127 << 0)) + +/* WAVSEQ6: reg0x0c */ +#define AW8697_BIT_WAVSEQ6_WAIT (1 << 7) +#define AW8697_BIT_WAVSEQ6_WAV_FRM_SEQ6_MASK (~(127 << 0)) + +/* WAVSEQ7: reg0x0d */ +#define AW8697_BIT_WAVSEQ7_WAIT (1 << 7) +#define AW8697_BIT_WAVSEQ7_WAV_FRM_SEQ7_MASK (~(127 << 0)) + +/* WAVSEQ8: reg0x0e */ +#define AW8697_BIT_WAVSEQ8_WAIT (1 << 7) +#define AW8697_BIT_WAVSEQ8_WAV_FRM_SEQ8_MASK (~(127 << 0)) + +/* WAVLOOP: */ +#define AW8697_BIT_WAVLOOP_SEQN_MASK (~(15 << 4)) +#define AW8697_BIT_WAVLOOP_SEQNP1_MASK (~(15 << 0)) +#define AW8697_BIT_WAVLOOP_INIFINITELY (15 << 0) + +/* WAVLOOP1: reg0x0f */ +#define AW8697_BIT_WAVLOOP1_SEQ1_MASK (~(15 << 4)) +#define AW8697_BIT_WAVLOOP1_SEQ2_MASK (~(15 << 0)) + +/* WAVLOOP2: reg0x10 */ +#define AW8697_BIT_WAVLOOP2_SEQ3_MASK (~(15 << 4)) +#define AW8697_BIT_WAVLOOP2_SEQ4_MASK (~(15 << 0)) + +/* WAVLOOP3: reg0x11 */ +#define AW8697_BIT_WAVLOOP3_SEQ5_MASK (~(15 << 4)) +#define AW8697_BIT_WAVLOOP3_SEQ6_MASK (~(15 << 0)) + +/* WAVLOOP4: reg0x12 */ +#define AW8697_BIT_WAVLOOP4_SEQ7_MASK (~(15 << 4)) +#define AW8697_BIT_WAVLOOP4_SEQ8_MASK (~(15 << 0)) + +/* PLAYPRIO: reg0x1a */ +#define AW8697_BIT_PLAYPRIO_GO_MASK (~(3 << 6)) +#define AW8697_BIT_PLAYPRIO_TRIG3_MASK (~(3 << 4)) +#define AW8697_BIT_PLAYPRIO_TRIG2_MASK (~(3 << 2)) +#define AW8697_BIT_PLAYPRIO_TRIG1_MASK (~(3 << 0)) + +/* TRGCFG1: reg0x1b */ +#define AW8697_BIT_TRGCFG1_TRG3_POLAR_MASK (~(1 << 5)) +#define AW8697_BIT_TRGCFG1_TRG3_POLAR_NEG (1 << 5) +#define AW8697_BIT_TRGCFG1_TRG3_POLAR_POS (0 << 5) +#define AW8697_BIT_TRGCFG1_TRG3_EDGE_MASK (~(1 << 4)) +#define AW8697_BIT_TRGCFG1_TRG3_EDGE_POS (1 << 4) +#define AW8697_BIT_TRGCFG1_TRG3_EDGE_POS_NEG (0 << 4) +#define AW8697_BIT_TRGCFG1_TRG2_POLAR_MASK (~(1 << 3)) +#define AW8697_BIT_TRGCFG1_TRG2_POLAR_NEG (1 << 3) +#define AW8697_BIT_TRGCFG1_TRG2_POLAR_POS (0 << 3) +#define AW8697_BIT_TRGCFG1_TRG2_EDGE_MASK (~(1 << 2)) +#define AW8697_BIT_TRGCFG1_TRG2_EDGE_POS (1 << 2) +#define AW8697_BIT_TRGCFG1_TRG2_EDGE_POS_NEG (0 << 2) +#define AW8697_BIT_TRGCFG1_TRG1_POLAR_MASK (~(1 << 1)) +#define AW8697_BIT_TRGCFG1_TRG1_POLAR_NEG (1 << 1) +#define AW8697_BIT_TRGCFG1_TRG1_POLAR_POS (0 << 1) +#define AW8697_BIT_TRGCFG1_TRG1_EDGE_MASK (~(1 << 0)) +#define AW8697_BIT_TRGCFG1_TRG1_EDGE_POS (1 << 0) +#define AW8697_BIT_TRGCFG1_TRG1_EDGE_POS_NEG (0 << 0) + +/* TRGCFG2: reg0x1c */ +#define AW8697_BIT_TRGCFG2_TRG3_ENABLE_MASK (~(1 << 2)) +#define AW8697_BIT_TRGCFG2_TRG3_ENABLE (1 << 2) +#define AW8697_BIT_TRGCFG2_TRG3_DISABLE (0 << 2) +#define AW8697_BIT_TRGCFG2_TRG2_ENABLE_MASK (~(1 << 1)) +#define AW8697_BIT_TRGCFG2_TRG2_ENABLE (1 << 1) +#define AW8697_BIT_TRGCFG2_TRG2_DISABLE (0 << 1) +#define AW8697_BIT_TRGCFG2_TRG1_ENABLE_MASK (~(1 << 0)) +#define AW8697_BIT_TRGCFG2_TRG1_ENABLE (1 << 0) +#define AW8697_BIT_TRGCFG2_TRG1_DISABLE (0 << 0) + +/* DBGCTRL: reg0x20 */ +#define AW8697_BIT_DBGCTRL_INT_EDGE_MODE_MASK (~(1 << 3)) +#define AW8697_BIT_DBGCTRL_INT_EDGE_MODE_POS (1 << 3) +#define AW8697_BIT_DBGCTRL_INT_EDGE_MODE_BOTH (0 << 3) +#define AW8697_BIT_DBGCTRL_INT_MODE_MASK (~(1 << 2)) +#define AW8697_BIT_DBGCTRL_INT_MODE_EDGE (1 << 2) +#define AW8697_BIT_DBGCTRL_INT_MODE_LEVEL (0 << 2) + +/* DATCTRL: reg0x2b */ +#define AW8697_BIT_DATCTRL_FC_MASK (~(1 << 6)) +#define AW8697_BIT_DATCTRL_FC_1000HZ (3 << 6) +#define AW8697_BIT_DATCTRL_FC_800HZ (3 << 6) +#define AW8697_BIT_DATCTRL_FC_600HZ (1 << 6) +#define AW8697_BIT_DATCTRL_FC_400HZ (0 << 6) +#define AW8697_BIT_DATCTRL_LPF_ENABLE_MASK (~(1 << 5)) +#define AW8697_BIT_DATCTRL_LPF_ENABLE (1 << 5) +#define AW8697_BIT_DATCTRL_LPF_DISABLE (0 << 5) +#define AW8697_BIT_DATCTRL_WAKEMODE_ENABLE_MASK (~(1 << 0)) +#define AW8697_BIT_DATCTRL_WAKEMODE_ENABLE (1 << 0) +#define AW8697_BIT_DATCTRL_WAKEMODE_DISABLE (0 << 0) + +/* PWMPRC: reg0x2d */ +#define AW8697_BIT_PWMPRC_PRC_MASK (~(1 << 7)) +#define AW8697_BIT_PWMPRC_PRC_ENABLE (1 << 7) +#define AW8697_BIT_PWMPRC_PRC_DISABLE (0 << 7) +#define AW8697_BIT_PWMPRC_PRCTIME_MASK (~(0x7f << 0)) + +/* PWMDBG: reg0x2e */ +#define AW8697_BIT_PWMDBG_PWM_MODE_MASK (~(3 << 5)) +#define AW8697_BIT_PWMDBG_PWM_12K (3 << 5) +#define AW8697_BIT_PWMDBG_PWM_24K (2 << 5) +#define AW8697_BIT_PWMDBG_PWM_48K (0 << 5) + +/* DBGST: reg0x30 */ +#define AW8697_BIT_DBGSTAT_FF_EMPTY (1 << 0) +/* BSTCFG: reg0x34 */ +#define AW8697_BIT_BSTCFG_PEAKCUR_MASK (~(7 << 0)) +#define AW8697_BIT_BSTCFG_PEAKCUR_4A (7 << 0) +#define AW8697_BIT_BSTCFG_PEAKCUR_3P75A (6 << 0) +#define AW8697_BIT_BSTCFG_PEAKCUR_3P5A (5 << 0) +#define AW8697_BIT_BSTCFG_PEAKCUR_3P25A (4 << 0) +#define AW8697_BIT_BSTCFG_PEAKCUR_3A (3 << 0) +#define AW8697_BIT_BSTCFG_PEAKCUR_2P5A (2 << 0) +#define AW8697_BIT_BSTCFG_PEAKCUR_2A (1 << 0) +#define AW8697_BIT_BSTCFG_PEAKCUR_1P5A (0 << 0) + +/* ANADBG: reg0x35 */ +#define AW8697_BIT_ANADBG_IOC_MASK (~(3 << 2)) +#define AW8697_BIT_ANADBG_IOC_4P65A (3 << 2) +#define AW8697_BIT_ANADBG_IOC_4P15A (2 << 2) +#define AW8697_BIT_ANADBG_IOC_3P65A (1 << 2) +#define AW8697_BIT_ANADBG_IOC_3P15A (0 << 2) + +/* ANACTRL: reg0x36 */ +#define AW8697_BIT_ANACTRL_LRA_SRC_MASK (~(1 << 5)) +#define AW8697_BIT_ANACTRL_LRA_SRC_REG (1 << 5) +#define AW8697_BIT_ANACTRL_LRA_SRC_EFUSE (0 << 5) +#define AW8697_BIT_ANACTRL_HD_PD_MASK (~(1 << 3)) +#define AW8697_BIT_ANACTRL_HD_PD_EN (1 << 3) +#define AW8697_BIT_ANACTRL_HD_HZ_EN (0 << 3) + +/* BSTDBG4: reg0x3a */ +#define AW8697_BIT_BSTDBG4_BSTVOL_MASK (~(31 << 1)) + +/* PRLVL: reg0x3e */ +#define AW8697_BIT_PRLVL_PR_MASK (~(1 << 7)) +#define AW8697_BIT_PRLVL_PR_ENABLE (1 << 7) +#define AW8697_BIT_PRLVL_PR_DISABLE (0 << 7) +#define AW8697_BIT_PRLVL_PRLVL_MASK (~(0x7f << 0)) + +/*PRTIME: reg0x3f */ +#define AW8697_BIT_PRTIME_PRTIME_MASK (~(0xff << 0)) + +/* BST_AUTO: reg0x47 */ +#define AW8697_BIT_BST_AUTO_BST_AUTOSW_MASK (~(1 << 2)) +#define AW8697_BIT_BST_AUTO_BST_AUTOMATIC_BOOST (1 << 2) +#define AW8697_BIT_BST_AUTO_BST_MANUAL_BOOST (0 << 2) +#define AW8697_BIT_BST_AUTO_BST_RTP_MASK (~(1 << 1)) +#define AW8697_BIT_BST_AUTO_BST_RTP_ENABLE (1 << 1) +#define AW8697_BIT_BST_AUTO_BST_RTP_DISABLE (0 << 1) +#define AW8697_BIT_BST_AUTO_BST_RAM_MASK (~(1 << 0)) +#define AW8697_BIT_BST_AUTO_BST_RAM_ENABLE (1 << 0) +#define AW8697_BIT_BST_AUTO_BST_RAM_DISABLE (0 << 0) + +/* CONT_CTRL: reg0x48 */ +#define AW8697_BIT_CONT_CTRL_ZC_DETEC_MASK (~(1 << 7)) +#define AW8697_BIT_CONT_CTRL_ZC_DETEC_ENABLE (1 << 7) +#define AW8697_BIT_CONT_CTRL_ZC_DETEC_DISABLE (0 << 7) +#define AW8697_BIT_CONT_CTRL_WAIT_PERIOD_MASK (~(3 << 5)) +#define AW8697_BIT_CONT_CTRL_WAIT_8PERIOD (3 << 5) +#define AW8697_BIT_CONT_CTRL_WAIT_4PERIOD (2 << 5) +#define AW8697_BIT_CONT_CTRL_WAIT_2PERIOD (1 << 5) +#define AW8697_BIT_CONT_CTRL_WAIT_1PERIOD (0 << 5) +#define AW8697_BIT_CONT_CTRL_MODE_MASK (~(1 << 4)) +#define AW8697_BIT_CONT_CTRL_BY_DRV_TIME (1 << 4) +#define AW8697_BIT_CONT_CTRL_BY_GO_SIGNAL (0 << 4) +#define AW8697_BIT_CONT_CTRL_EN_CLOSE_MASK (~(1 << 3)) +#define AW8697_BIT_CONT_CTRL_CLOSE_PLAYBACK (1 << 3) +#define AW8697_BIT_CONT_CTRL_OPEN_PLAYBACK (0 << 3) +#define AW8697_BIT_CONT_CTRL_F0_DETECT_MASK (~(1 << 2)) +#define AW8697_BIT_CONT_CTRL_F0_DETECT_ENABLE (1 << 2) +#define AW8697_BIT_CONT_CTRL_F0_DETECT_DISABLE (0 << 2) +#define AW8697_BIT_CONT_CTRL_O2C_MASK (~(1 << 1)) +#define AW8697_BIT_CONT_CTRL_O2C_ENABLE (1 << 1) +#define AW8697_BIT_CONT_CTRL_O2C_DISABLE (0 << 1) +#define AW8697_BIT_CONT_CTRL_AUTO_BRK_MASK (~(1 << 0)) +#define AW8697_BIT_CONT_CTRL_AUTO_BRK_ENABLE (1 << 0) +#define AW8697_BIT_CONT_CTRL_AUTO_BRK_DISABLE (0 << 0) + +/* D2SCFG: reg0x5e */ +#define AW8697_BIT_D2SCFG_CLK_ADC_MASK (~(7 << 5)) +#define AW8697_BIT_D2SCFG_CLK_ASC_0P09375MHZ (7 << 5) +#define AW8697_BIT_D2SCFG_CLK_ASC_0P1875MHZ (6 << 5) +#define AW8697_BIT_D2SCFG_CLK_ASC_0P375MHZ (5 << 5) +#define AW8697_BIT_D2SCFG_CLK_ASC_0P75MHZ (4 << 5) +#define AW8697_BIT_D2SCFG_CLK_ASC_1P5MHZ (3 << 5) +#define AW8697_BIT_D2SCFG_CLK_ASC_3MHZ (2 << 5) +#define AW8697_BIT_D2SCFG_CLK_ASC_6MHZ (1 << 5) +#define AW8697_BIT_D2SCFG_CLK_ASC_12MHZ (0 << 5) + +/* DETCTRL: reg0x5f */ +#define AW8697_BIT_DETCTRL_RL_OS_MASK (~(1 << 6)) +#define AW8697_BIT_DETCTRL_RL_DETECT (1 << 6) +#define AW8697_BIT_DETCTRL_OS_DETECT (0 << 6) +#define AW8697_BIT_DETCTRL_PROTECT_MASK (~(1 << 5)) +#define AW8697_BIT_DETCTRL_PROTECT_NO_ACTION (1 << 5) +#define AW8697_BIT_DETCTRL_PROTECT_SHUTDOWN (0 << 5) +#define AW8697_BIT_DETCTRL_ADO_SLOT_MODE_MASK (~(1 << 4)) +#define AW8697_BIT_DETCTRL_ADO_SLOT_MODE_ENABLE (1 << 4) +#define AW8697_BIT_DETCTRL_ADO_SLOT_MODE_DISABLE (0 << 4) +#define AW8697_BIT_DETCTRL_VBAT_GO_MASK (~(1 << 1)) +#define AW8697_BIT_DETCTRL_VABT_GO_ENABLE (1 << 1) +#define AW8697_BIT_DETCTRL_VBAT_GO_DISBALE (0 << 1) +#define AW8697_BIT_DETCTRL_DIAG_GO_MASK (~(1 << 0)) +#define AW8697_BIT_DETCTRL_DIAG_GO_ENABLE (1 << 0) +#define AW8697_BIT_DETCTRL_DIAG_GO_DISABLE (0 << 0) + +/* ADCTEST: reg0x66 */ +#define AW8697_BIT_ADCTEST_VBAT_MODE_MASK (~(1 << 6)) +#define AW8697_BIT_ADCTEST_VBAT_HW_COMP (1 << 6) +#define AW8697_BIT_ADCTEST_VBAT_SW_COMP (0 << 6) + +/* BEMF_NUM: reg0x78 */ +#define AW8697_BIT_BEMF_NUM_BRK_MASK (~(15 << 0)) + +#endif diff --git a/drivers/input/misc/aw8697_haptic_xm/ringbuffer.c b/drivers/input/misc/aw8697_haptic_xm/ringbuffer.c new file mode 100644 index 000000000000..9b74ef480a5f --- /dev/null +++ b/drivers/input/misc/aw8697_haptic_xm/ringbuffer.c @@ -0,0 +1,228 @@ +/* +* reader shoule NEVER block !!!, if no data is avaliable, just return zero +* writer will block if there is no space, and wakend up by reader or force exit +* there is 1 writer and 1 reader for each buffer, so no lock is used +* writer shoule read rd_index to check if free size is enought, +* and then fill this buffer update wr_index +* reader shoule read wr_index to check if avaliable size is enought, +* and then read the buffer and update rd_index +* empty: wr_index==rd_index +* full: (wr_index +1) % BUFFER_SIZE == rd_index +* total avaliable size is BUFFER_SIZE -1 +*/ +#define DEBUG +#include +#include "ringbuffer.h" + +#define MIN(x, y) ((x) < (y) ? (x) : (y)) + +#define BUFFER_SIZE (1024 * 8 + 1) + +struct rb { + char *gbuffer; + atomic_t wr_index; + atomic_t rd_index; + atomic_t eof; + volatile int32_t aval_size; // avalibale to write size. + atomic_t buf_condition, exit; + wait_queue_head_t wait_q; +}; + +struct rb *grb; + +int32_t get_free_size(int32_t tail, int32_t head) +{ + if (head == tail) + return BUFFER_SIZE - 1; + else if (head < tail) + return (head + BUFFER_SIZE - 1 - tail); + else + return (head - tail - 1); +} + +int write_rb(const char *data, int32_t size) +{ + int32_t tail = atomic_read(&grb->wr_index); + int32_t head = atomic_read(&grb->rd_index); + int32_t part; + int32_t ret; + + grb->aval_size = get_free_size(tail, head); + + pr_debug("%s: write write index %d, read index %d, free size %d", + __func__, tail, head, grb->aval_size); + + while ((grb->aval_size < size) && (!atomic_read(&grb->exit))) { + pr_debug("%s: no space avaliable", __func__); + pr_info("%s: goint to waiting irq exit\n", __func__); + ret = wait_event_interruptible( + grb->wait_q, atomic_read(&grb->buf_condition) == 1); + if (ret == -ERESTARTSYS) { + pr_err("%s: wake up by signal return erro\n", __func__); + return ret; + } + + atomic_set(&grb->buf_condition, 0); + tail = atomic_read(&grb->wr_index); + head = atomic_read(&grb->rd_index); + grb->aval_size = get_free_size(tail, head); + } + if (atomic_read(&grb->exit) == 1) { + pr_debug("%s: exit write_rb", __func__); + return -EPERM; + } + + part = BUFFER_SIZE - tail; + if (part < size) { + memcpy(grb->gbuffer + tail, data, part); + memcpy(grb->gbuffer, data + part, size - part); + tail = size - part; + } else { + memcpy(grb->gbuffer + tail, data, size); + tail += size; + if (tail >= BUFFER_SIZE) + tail = tail % BUFFER_SIZE; + } + atomic_set(&grb->wr_index, tail); + grb->aval_size = get_free_size(tail, head); + pr_debug( + "%s: after write %d, write index %d, read index %d, aval_size %d", + __func__, size, tail, head, grb->aval_size); + return size; +} + +int read_rb(char *data, int32_t size) +{ + int32_t tail; + int32_t head; + int32_t filled_size; + void *buf; + int32_t read_bytes, part; + buf = data; + + pr_debug("%s: read_rb data:%p, size %d", __func__, data, (int)size); + + tail = atomic_read(&grb->wr_index); + head = atomic_read(&grb->rd_index); + grb->aval_size = get_free_size(tail, head); + filled_size = BUFFER_SIZE - 1 - grb->aval_size; // aready write size. + + pr_debug("%s: write index %d, read index %d, filled size %d", __func__, + tail, head, filled_size); + read_bytes = MIN(size, filled_size); + if (size > filled_size) + pr_debug("%s: buffer underrun , req size %d, filled size %d", + __func__, size, filled_size); + part = BUFFER_SIZE - head; + if (part < read_bytes) { + memcpy(buf, grb->gbuffer + head, part); + memcpy((char *)buf + part, grb->gbuffer, read_bytes - part); + head = read_bytes - part; + } else { + memcpy(buf, grb->gbuffer + head, read_bytes); + head += read_bytes; + if (head >= BUFFER_SIZE) + head = head % BUFFER_SIZE; + } + atomic_set(&grb->rd_index, head); + grb->aval_size = get_free_size(tail, head); + + //add wakeup here + atomic_set(&grb->buf_condition, 1); + wake_up_interruptible(&grb->wait_q); + pr_debug( + "%s: after read %d write index %d, read index %d, aval_size %d", + __func__, read_bytes, tail, head, grb->aval_size); + + return atomic_read(&grb->eof) ? read_bytes : size; +} + +int get_rb_free_size(void) +{ + int32_t tail = atomic_read(&grb->wr_index); + int32_t head = atomic_read(&grb->rd_index); + + grb->aval_size = get_free_size(tail, head); + return grb->aval_size; +} + +int get_rb_avalible_size(void) +{ + return BUFFER_SIZE - 1 - get_rb_free_size(); +} + +int get_rb_max_size(void) +{ + return BUFFER_SIZE - 1; +} + +void rb_force_exit(void) +{ + pr_debug("%s: rb force exit", __func__); + atomic_set(&grb->exit, 1); + atomic_set(&grb->buf_condition, 1); + wake_up_interruptible(&grb->wait_q); +} + +void rb_end(void) +{ + atomic_set(&grb->eof, 1); +} + +int rb_shoule_exit(void) +{ + return atomic_read(&grb->eof) || atomic_read(&grb->exit); +} + +int create_rb(void) +{ + int32_t tail; + int32_t head; + + grb = kzalloc(sizeof(struct rb), GFP_KERNEL); + if (grb == NULL) { + goto err; + } + grb->gbuffer = kzalloc(BUFFER_SIZE, GFP_KERNEL); + if (grb->gbuffer == NULL) { + goto err; + } + + rb_init(); + + init_waitqueue_head(&grb->wait_q); + tail = atomic_read(&grb->wr_index); + head = atomic_read(&grb->rd_index); + grb->aval_size = get_free_size(tail, head); + + return 0; +err: + if (grb) + kfree(grb); + if (grb->gbuffer) + kfree(grb->gbuffer); + return -EPERM; +} + +void rb_init(void) +{ + pr_debug("%s: rb init", __func__); + atomic_set(&grb->wr_index, 0); + atomic_set(&grb->rd_index, 0); + atomic_set(&grb->buf_condition, 0); + atomic_set(&grb->exit, 0); + atomic_set(&grb->eof, 0); +} + +int release_rb(void) +{ + if (grb != NULL) { + if (grb->gbuffer) { + kfree(grb->gbuffer); + grb->gbuffer = NULL; + } + kfree(grb); + grb = NULL; + } + return 0; +} diff --git a/drivers/input/misc/aw8697_haptic_xm/ringbuffer.h b/drivers/input/misc/aw8697_haptic_xm/ringbuffer.h new file mode 100644 index 000000000000..7c097386d935 --- /dev/null +++ b/drivers/input/misc/aw8697_haptic_xm/ringbuffer.h @@ -0,0 +1,36 @@ +/* +* reader shoule NEVER block !!!, if no data is avaliable, just return zero +* writer will block if there is no space, and wakend up by reader or force exit +* there is 1 writer and 1 reader for each buffer, so no lock is used +* writer shoule read rd_index to check if free size is enought, +* and then fill this buffer update wr_index +* reader shoule read wr_index to check if avaliable size is enought, +* and then read the buffer and update rd_index +* empty: wr_index==rd_index +* full: (wr_index +1) % BUFFER_SIZE == rd_index +* total avaliable size is BUFFER_SIZE -1 +*/ + +#ifndef _RINGBUFFER_H_ +#define _RINGBUFFER_H_ + +#include +#include +#include +#include +#include +#include +#include + +int write_rb(const char *data, int32_t size); +int read_rb(char *data, int32_t size); +int get_rb_free_size(void); +int get_rb_max_size(void); +void rb_force_exit(void); +void rb_end(void); +int rb_shoule_exit(void); +int create_rb(void); +void rb_init(void); +int release_rb(void); +int get_rb_avalible_size(void); +#endif From 8ece510d1f5630fe3464c6e34d64051cec08d2ed Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Sun, 28 Jan 2024 18:49:11 +0100 Subject: [PATCH 052/226] drivers: input: misc: Import Xiaomi keyboard driver * From nabu-r-oss * Run clang-format on source files Change-Id: I4dff75188b74114b9849506dc202cbaa61e75a27 Signed-off-by: firebird11 --- drivers/input/misc/Kconfig | 2 + drivers/input/misc/Makefile | 1 + drivers/input/misc/xiaomi_keyboard/Kconfig | 8 + drivers/input/misc/xiaomi_keyboard/Makefile | 1 + .../misc/xiaomi_keyboard/xiaomi_keyboard.c | 651 ++++++++++++++++++ .../misc/xiaomi_keyboard/xiaomi_keyboard.h | 47 ++ 6 files changed, 710 insertions(+) create mode 100644 drivers/input/misc/xiaomi_keyboard/Kconfig create mode 100644 drivers/input/misc/xiaomi_keyboard/Makefile create mode 100644 drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c create mode 100644 drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 4ff5b3406b8e..bd94be97e8ae 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -891,4 +891,6 @@ config INPUT_HISI_POWERKEY source "drivers/input/misc/aw8697_haptic_xm/Kconfig" +source "drivers/input/misc/xiaomi_keyboard/Kconfig" + endif diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index c790f73d3dd8..5659e0306f23 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -86,3 +86,4 @@ obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o obj-$(CONFIG_INPUT_YEALINK) += yealink.o obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o obj-$(CONFIG_INPUT_AW8697_XM_HAPTIC) += aw8697_haptic_xm/ +obj-$(CONFIG_XIAOMI_KEYBOARD) += xiaomi_keyboard/ diff --git a/drivers/input/misc/xiaomi_keyboard/Kconfig b/drivers/input/misc/xiaomi_keyboard/Kconfig new file mode 100644 index 000000000000..bfc4b1d891e5 --- /dev/null +++ b/drivers/input/misc/xiaomi_keyboard/Kconfig @@ -0,0 +1,8 @@ +config XIAOMI_KEYBOARD + bool "xiaomi keyboard control-driver" + depends on INPUT + default n + help + Say Y here, compile xiaomi keyboard control driver. + + If unsure, say N. diff --git a/drivers/input/misc/xiaomi_keyboard/Makefile b/drivers/input/misc/xiaomi_keyboard/Makefile new file mode 100644 index 000000000000..0a00118c658e --- /dev/null +++ b/drivers/input/misc/xiaomi_keyboard/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_XIAOMI_KEYBOARD) += xiaomi_keyboard.o \ No newline at end of file diff --git a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c new file mode 100644 index 000000000000..962771069660 --- /dev/null +++ b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c @@ -0,0 +1,651 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xiaomi_keyboard.h" +#include +#include + +static struct xiaomi_keyboard_data *mdata; + +static void set_keyboard_status(bool on); + +static void xiaomi_keyboard_reset(void) +{ + if (!mdata || !mdata->pdata) { + MI_KB_ERR("reset failed!Invalid Memory\n"); + return; + } + MI_KB_INFO("xiaomi keyboard IC Reset\n"); + gpio_direction_output(mdata->pdata->rst_gpio, 0); + msleep(2); + gpio_direction_output(mdata->pdata->rst_gpio, 1); +} + +static void xiaomi_keyboard_connected_notify(struct device *dev) +{ + sysfs_notify(&dev->kobj, NULL, "xiaomi_keyboard_conn_status"); + MI_KB_INFO("connected status notify\n"); +} + +static ssize_t xiaomi_keyboard_conn_status_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret = 0, value = 1; + MI_KB_INFO("%s enter\n", __func__); + if (!mdata) { + MI_KB_ERR("Invalid driver info\n"); + return ret; + } + + mutex_lock(&mdata->rw_mutex); + value = mdata->keyboard_conn_status; + mutex_unlock(&mdata->rw_mutex); + + return scnprintf(buf, PAGE_SIZE, "%d", value); +} + +static ssize_t xiaomi_keyboard_conn_status_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char *cmd; + cmd = kzalloc(count + 1, GFP_KERNEL); + + if (!cmd) { + MI_KB_ERR("Allocate Meomory Failed\n"); + goto out; + } + memcpy(cmd, buf, count); + + if (!mdata) + goto out; + + if (!strncmp(cmd, "reset", 5)) { + xiaomi_keyboard_reset(); + } else if (!strncmp(cmd, "enable_keyboard", 15)) { + MI_KB_INFO("enable keyboard\n"); + set_keyboard_status(1); + } else if (!strncmp(cmd, "disable_keyboard", 16)) { + MI_KB_INFO("disable keyboard\n"); + set_keyboard_status(0); + } else + MI_KB_ERR("Undefined CMD: %s\n", cmd); +out: + if (cmd) + kfree(cmd); + return count; +} + +DEVICE_ATTR(xiaomi_keyboard_conn_status, (S_IRUGO | S_IWUSR | S_IWGRP), + xiaomi_keyboard_conn_status_show, + xiaomi_keyboard_conn_status_store); + +static irqreturn_t xiaomi_keyboard_irq_func(int irq, void *data) +{ + int value = 0; + MI_KB_INFO("keyboard event: wakeup system\n"); + pm_wakeup_event(&mdata->pdev->dev, 500); + value = gpio_get_value_cansleep(mdata->pdata->in_irq_gpio); + + mutex_lock(&mdata->rw_mutex); + mdata->keyboard_conn_status = !mdata->keyboard_conn_status; + mutex_unlock(&mdata->rw_mutex); + + xiaomi_keyboard_connected_notify(&mdata->pdev->dev); + MI_KB_INFO("keyboard connected status: %d", + mdata->keyboard_conn_status); + return IRQ_HANDLED; +} + +static int xiaomi_keyboard_gpio_config(struct xiaomi_keyboard_platdata *pdata) +{ + int ret = 0; + if (gpio_is_valid(pdata->rst_gpio)) { + ret = gpio_request_one(pdata->rst_gpio, GPIOF_OUT_INIT_LOW, + "kb_rst"); + if (ret) { + MI_KB_ERR( + "Failed to request xiaomi keyboard rst gpio\n"); + goto err_request_rst_gpio; + } + } + + if (gpio_is_valid(pdata->in_irq_gpio)) { + ret = gpio_request_one(pdata->in_irq_gpio, GPIOF_IN, + "kb_in_irq"); + if (ret) { + MI_KB_ERR( + "Failed to request xiaomi keyboard in-irq gpio\n"); + goto err_request_in_irq_gpio; + } + } + + return ret; +err_request_in_irq_gpio: + gpio_free(pdata->rst_gpio); +err_request_rst_gpio: + return ret; +} + +static void +xiaomi_keyboard_gpio_deconfig(struct xiaomi_keyboard_platdata *pdata) +{ + if (gpio_is_valid(pdata->rst_gpio)) + gpio_free(pdata->rst_gpio); + + if (gpio_is_valid(pdata->in_irq_gpio)) + gpio_free(pdata->in_irq_gpio); +} + +static int xiaomi_keyboard_setup_gpio(struct xiaomi_keyboard_platdata *pdata) +{ + int ret = 0; + if (!pdata) { + MI_KB_ERR("xiaomi keyboard platdata is NULL\n"); + return -EINVAL; + } + if (gpio_is_valid(pdata->rst_gpio)) + gpio_direction_output(pdata->rst_gpio, 1); + + mdata->irq = gpio_to_irq(pdata->in_irq_gpio); + if (mdata->irq) { + ret = request_threaded_irq(mdata->irq, NULL, + xiaomi_keyboard_irq_func, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "MiKB-IRQ", mdata); + if (ret != 0) { + MI_KB_ERR("request threaded irq failed\n"); + return ret; + } + } + + return ret; +} + +static int xiaomi_keyboard_resetup_gpio(struct xiaomi_keyboard_platdata *pdata) +{ + int ret = 0; + + if (!mdata || !pdata) { + MI_KB_ERR("mdata or pdata not ready, return!"); + return -EINVAL; + } + + if (gpio_is_valid(pdata->rst_gpio)) + gpio_direction_output(pdata->rst_gpio, 0); + + free_irq(mdata->irq, mdata); + + return ret; +} + +#ifdef CONFIG_OF +static int xiaomi_keyboard_parse_dt(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct xiaomi_keyboard_platdata *pdata; + int ret = 0; + + pdata = mdata->pdata; + + pdata->rst_gpio = of_get_named_gpio_flags( + np, "xiaomi-keyboard,rst-gpio", 0, &pdata->rst_flags); + MI_KB_INFO("xiaomi-kb,reset-gpio=%d\n", pdata->rst_gpio); + + pdata->in_irq_gpio = of_get_named_gpio_flags( + np, "xiaomi-keyboard,in-irq-gpio", 0, &pdata->in_irq_flags); + MI_KB_INFO("xiaomi-kb,in-irq-gpio=%d\n", pdata->in_irq_gpio); + + pdata->vdd_gpio = of_get_named_gpio(np, "xiaomi-keyboard,vdd-gpio", 0); + MI_KB_INFO("xiaomi-kb,vdd-gpio=%d\n", pdata->vdd_gpio); + + return ret; +} +#else +static int xiaomi_keyboard_parse_dt(struct device *dev) +{ + MI_KB_ERR("Xiaomi Keyboard dev is not defined\n"); + return -EINVAL; +} +#endif + +static int xiaomi_keyboard_pinctrl_init(struct device *dev) +{ + int ret = 0; + + mdata->pinctrl = devm_pinctrl_get(dev); + if (IS_ERR_OR_NULL(mdata->pinctrl)) { + MI_KB_ERR("Failed to get pinctrl, please check dts\n"); + ret = PTR_ERR(mdata->pinctrl); + goto err_pinctrl_get; + } + mdata->pins_active = + pinctrl_lookup_state(mdata->pinctrl, "pm_kb_active"); + if (IS_ERR_OR_NULL(mdata->pins_active)) { + MI_KB_ERR("Pin state [active] not found\n"); + ret = PTR_ERR(mdata->pins_active); + goto err_pinctrl_lookup; + } + + mdata->pins_suspend = + pinctrl_lookup_state(mdata->pinctrl, "pm_kb_suspend"); + if (IS_ERR_OR_NULL(mdata->pins_suspend)) { + MI_KB_ERR("Pin state [suspend] not found\n"); + ret = PTR_ERR(mdata->pins_suspend); + goto err_pinctrl_lookup; + } + + return 0; +err_pinctrl_lookup: + if (mdata->pinctrl) { + devm_pinctrl_put(mdata->pinctrl); + } +err_pinctrl_get: + return ret; +} + +static int xiaomi_keyboard_power_on(void) +{ + int ret = 0; + struct xiaomi_keyboard_platdata *pdata; + pdata = mdata->pdata; + MI_KB_INFO("Power On\n"); + if (gpio_is_valid(pdata->vdd_gpio)) { + ret = gpio_request_one(pdata->vdd_gpio, GPIOF_OUT_INIT_HIGH, + "kb_vdd_gpio"); + if (ret) { + MI_KB_ERR( + "Failed to request xiaomi-keyboard-out-irq gpio\n"); + goto err_request_vdd_gpio; + } + } + + gpio_direction_output(pdata->vdd_gpio, 1); +err_request_vdd_gpio: + return ret; +} + +static void xiaomi_keyboard_power_off(void) +{ + struct xiaomi_keyboard_platdata *pdata; + pdata = mdata->pdata; + MI_KB_INFO("Power Off\n"); + if (gpio_is_valid(pdata->vdd_gpio)) { + gpio_direction_output(pdata->vdd_gpio, 0); + gpio_free(pdata->vdd_gpio); + } + return; +} + +static int xiaomi_keyboard_suspend(struct device *dev) +{ + int ret = 0; + MI_KB_INFO("enter\n"); + if (mdata->pinctrl && mdata->pins_suspend) { + ret = (mdata->keyboard_is_enable && mdata->is_usb_exist) ? + 0 : + pinctrl_select_state(mdata->pinctrl, + mdata->pins_suspend); + if (ret < 0) { + MI_KB_ERR("Set suspend pin state error:%d\n", ret); + } + } + MI_KB_INFO("exit\n"); + return ret; +} + +static int xiaomi_keyboard_resume(struct device *dev) +{ + int ret = 0; + MI_KB_INFO("enter\n"); + if (!mdata->keyboard_is_enable) { + MI_KB_INFO("keyboard_is_enable is false, stop resume.\n"); + MI_KB_INFO("exit\n"); + return -1; + } + if (mdata->pinctrl && mdata->pins_active) { + ret = pinctrl_select_state(mdata->pinctrl, mdata->pins_active); + if (ret < 0) { + MI_KB_ERR("Set active pin state error:%d\n", ret); + } + } + MI_KB_INFO("exit\n"); + return ret; +} + +static int xiaomi_keyboard_pm_suspend(struct device *dev) +{ + int ret = 0; + MI_KB_INFO("enter\n"); + enable_irq_wake(mdata->irq); + mdata->dev_pm_suspend = true; + return ret; +} + +static int xiaomi_keyboard_pm_resume(struct device *dev) +{ + int ret = 0; + MI_KB_INFO("enter\n"); + disable_irq_wake(mdata->irq); + mdata->dev_pm_suspend = false; + return ret; +} + +static const struct dev_pm_ops xiaomi_keyboard_pm_ops = { + .suspend = xiaomi_keyboard_pm_suspend, + .resume = xiaomi_keyboard_pm_resume, +}; + +static int keyboard_drm_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct drm_notify_data *evdata = data; + int *blank; + struct xiaomi_keyboard_data *mdata = + container_of(self, struct xiaomi_keyboard_data, drm_notif); + + if (!evdata) + return 0; + + if (evdata->data && mdata) { + blank = evdata->data; + flush_workqueue(mdata->event_wq); + if (event == DRM_EARLY_EVENT_BLANK) { + if (*blank == DRM_BLANK_POWERDOWN) { + MI_KB_ERR("keyboard suspend"); + mdata->is_in_suspend = true; + queue_work(mdata->event_wq, + &mdata->suspend_work); + } + } else if (event == DRM_EVENT_BLANK) { + if (*blank == DRM_BLANK_UNBLANK) { + MI_KB_ERR("keyboard resume"); + mdata->is_in_suspend = false; + flush_workqueue(mdata->event_wq); + queue_work(mdata->event_wq, + &mdata->resume_work); + } + } + } + + return 0; +} + +static void keyboard_resume_work(struct work_struct *work) +{ + struct xiaomi_keyboard_data *mdata = + container_of(work, struct xiaomi_keyboard_data, resume_work); + xiaomi_keyboard_resume(&mdata->pdev->dev); +} + +static void keyboard_suspend_work(struct work_struct *work) +{ + struct xiaomi_keyboard_data *mdata = + container_of(work, struct xiaomi_keyboard_data, resume_work); + xiaomi_keyboard_suspend(&mdata->pdev->dev); +} + +static int kb_power_supply_event(struct notifier_block *nb, unsigned long event, + void *ptr) +{ + struct xiaomi_keyboard_data *mdata = container_of( + nb, struct xiaomi_keyboard_data, power_supply_notifier); + + if (mdata != NULL) + queue_work(mdata->event_wq, &mdata->power_supply_work); + + return 0; +} + +static void kb_power_supply_work(struct work_struct *work) +{ + struct xiaomi_keyboard_data *mdata = container_of( + work, struct xiaomi_keyboard_data, power_supply_work); + int is_usb_exist = 0; + + mutex_lock(&mdata->power_supply_lock); + is_usb_exist = !!power_supply_is_system_supplied(); + if (is_usb_exist != mdata->is_usb_exist) { + mdata->is_usb_exist = is_usb_exist; + MI_KB_INFO("power supply is: %d", mdata->is_usb_exist); + } + mutex_unlock(&mdata->power_supply_lock); +} + +static void set_keyboard_status(bool on) +{ + int ret = 0; + + if (!mdata || !(mdata->pdata)) { + MI_KB_ERR("mdata or pdata not ready, return!"); + return; + } + + if (on && !(mdata->keyboard_is_enable)) { + ret = xiaomi_keyboard_power_on(); + if (ret) { + MI_KB_ERR("Init 3.3V power failed\n"); + return; + } + msleep(1); + ret = xiaomi_keyboard_setup_gpio(mdata->pdata); + if (ret) { + MI_KB_ERR("setup gpio failed\n"); + return; + } + msleep(2); + + if (!mdata->is_in_suspend) { + ret = pinctrl_select_state(mdata->pinctrl, + mdata->pins_active); + if (ret < 0) { + MI_KB_ERR("Set active pin state error:%d\n", + ret); + } + } + mdata->keyboard_is_enable = true; + + } else if (!on && mdata->keyboard_is_enable) { + if (!mdata->is_in_suspend) { + ret = pinctrl_select_state(mdata->pinctrl, + mdata->pins_suspend); + if (ret < 0) { + MI_KB_ERR("Set suspend pin state error:%d\n", + ret); + } + } + + ret = xiaomi_keyboard_resetup_gpio(mdata->pdata); + if (ret < 0) { + MI_KB_ERR("resetup gpio failed\n"); + return; + } + xiaomi_keyboard_power_off(); + mdata->keyboard_is_enable = false; + } else { + MI_KB_INFO("keyboard status do not need change!"); + } +} + +/******************************************************* +Description: + xiami pad keyboard driver probe function. + +return: + Executive outcomes. 0---succeed. negative---failed +*******************************************************/ +static int xiaomi_keyboard_probe(struct platform_device *pdev) +{ + struct xiaomi_keyboard_platdata *pdata; + int ret = 0; + MI_KB_INFO("enter\n"); + mdata = kzalloc(sizeof(struct xiaomi_keyboard_data), GFP_KERNEL); + if (!mdata) { + MI_KB_ERR("Alloc Memory for xiaomi_keyboard_data failed\n"); + return -ENOMEM; + } + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct xiaomi_keyboard_platdata), + GFP_KERNEL); + if (!pdata) { + MI_KB_ERR("Alloc Memory for xiaomi_keyboard_platdata failed\n"); + return -ENOMEM; + } + + mdata->pdev = pdev; + mdata->pdata = pdata; + mutex_init(&mdata->rw_mutex); + mutex_init(&mdata->power_supply_lock); + mdata->is_usb_exist = 0; + + ret = xiaomi_keyboard_parse_dt(&pdev->dev); + if (ret) { + MI_KB_ERR("parse device tree failed\n"); + goto out; + } + + ret = xiaomi_keyboard_pinctrl_init(&pdev->dev); + if (ret) { + MI_KB_ERR("Pinctrl init failed\n"); + goto out; + } + + pdata = mdata->pdata; + ret = xiaomi_keyboard_gpio_config(pdata); + if (ret) { + MI_KB_ERR("set gpio config failed\n"); + goto out; + } + + mdata->dev_pm_suspend = false; + mdata->keyboard_is_enable = false; + mdata->is_in_suspend = false; + + ret = sysfs_create_file(&mdata->pdev->dev.kobj, + &dev_attr_xiaomi_keyboard_conn_status.attr); + if (ret < 0) { + MI_KB_ERR( + "Create sysfs attribute xiaomi_keyboard_conn_status Failed\n"); + goto err_pinctrl_select; + } + + mdata->event_wq = + alloc_workqueue("kb-event-queue", + WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); + if (!mdata->event_wq) { + MI_KB_ERR("Can not create work thread for suspend/resume!!"); + ret = -ENOMEM; + goto err_alloc_work_thread_failed; + } + INIT_WORK(&mdata->resume_work, keyboard_resume_work); + INIT_WORK(&mdata->suspend_work, keyboard_suspend_work); + INIT_WORK(&mdata->power_supply_work, kb_power_supply_work); + + mdata->drm_notif.notifier_call = keyboard_drm_notifier_callback; + ret = drm_register_client(&mdata->drm_notif); + if (ret) { + MI_KB_ERR("register drm_notifier failed. ret=%d\n", ret); + goto err_register_drm_notif_failed; + } + + mdata->power_supply_notifier.notifier_call = kb_power_supply_event; + ret = power_supply_reg_notifier(&mdata->power_supply_notifier); + if (ret) { + MI_KB_ERR("register power_supply_notifier failed. ret=%d\n", + ret); + goto err_register_power_supply_notif_failed; + } + + MI_KB_INFO("Success\n"); + return ret; + +err_register_power_supply_notif_failed: +err_register_drm_notif_failed: + if (drm_unregister_client(&mdata->drm_notif)) + MI_KB_ERR("Error occurred while unregistering drm_notifier\n"); + if (mdata->event_wq) { + destroy_workqueue(mdata->event_wq); + } +err_alloc_work_thread_failed: + sysfs_remove_file(&mdata->pdev->dev.kobj, + &dev_attr_xiaomi_keyboard_conn_status.attr); +err_pinctrl_select: + if (mdata->pinctrl) { + devm_pinctrl_put(mdata->pinctrl); + } + xiaomi_keyboard_gpio_deconfig(pdata); +out: + mutex_destroy(&mdata->rw_mutex); + mutex_destroy(&mdata->power_supply_lock); + if (mdata) { + kfree(mdata); + mdata = NULL; + } + MI_KB_ERR("Failed\n"); + return ret; +} + +static int xiaomi_keyboard_remove(struct platform_device *pdev) +{ + MI_KB_INFO("enter\n"); + drm_unregister_client(&mdata->drm_notif); + destroy_workqueue(mdata->event_wq); + xiaomi_keyboard_gpio_deconfig(mdata->pdata); + sysfs_remove_file(&mdata->pdev->dev.kobj, + &dev_attr_xiaomi_keyboard_conn_status.attr); + xiaomi_keyboard_power_off(); + devm_pinctrl_put(mdata->pinctrl); + xiaomi_keyboard_gpio_deconfig(mdata->pdata); + mutex_destroy(&mdata->rw_mutex); + mutex_destroy(&mdata->power_supply_lock); + if (mdata) { + kfree(mdata); + mdata = NULL; + } + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id xiaomi_keyboard_dt_match[] = { + { .compatible = "xiaomi,keyboard" }, + {}, +}; +MODULE_DEVICE_TABLE(of, xiaomi_keyboard_dt_match); +#endif + +static const struct platform_device_id xiaomi_keyboard_driver_ids[] = { + { + .name = "xiaomi-keyboard", + .driver_data = 0, + }, +}; +MODULE_DEVICE_TABLE(platform, xiaomi_keyboard_driver_ids); + +static struct platform_driver xiaomi_keyboard_driver = { + .probe = xiaomi_keyboard_probe, + .remove = xiaomi_keyboard_remove, + .driver = { + .name = "xiaomi-keyboard", + .of_match_table = of_match_ptr(xiaomi_keyboard_dt_match), + .pm = &xiaomi_keyboard_pm_ops, + }, + .id_table = xiaomi_keyboard_driver_ids, +}; + +module_platform_driver(xiaomi_keyboard_driver); + +MODULE_DESCRIPTION("Xiaomi Keyboard Control-driver"); +MODULE_AUTHOR("Tonghui Wang"); diff --git a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h new file mode 100644 index 000000000000..32bb8c0dcbd4 --- /dev/null +++ b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h @@ -0,0 +1,47 @@ +#ifndef __XIAOMI_KEYBOARD_H +#define __XIAOMI_KEYBOARD_H + +#include +#include +#include +#include +#include +#include + +#define XIAOMI_KB_TAG "xiaomi-keyboard" +#define MI_KB_INFO(fmt, args...) \ + pr_info("[%s] %s %d: " fmt, XIAOMI_KB_TAG, __func__, __LINE__, ##args) +#define MI_KB_ERR(fmt, args...) \ + pr_err("[%s] %s %d: " fmt, XIAOMI_KB_TAG, __func__, __LINE__, ##args) + +struct xiaomi_keyboard_platdata { + u32 rst_gpio; + u32 rst_flags; + u32 in_irq_gpio; + u32 in_irq_flags; + u32 vdd_gpio; +}; + +struct xiaomi_keyboard_data { + struct notifier_block drm_notif; + struct xiaomi_keyboard_platdata *pdata; + bool dev_pm_suspend; + int irq; + struct platform_device *pdev; + struct pinctrl *pinctrl; + struct pinctrl_state *pins_active; + struct pinctrl_state *pins_suspend; + struct workqueue_struct *event_wq; + struct work_struct resume_work; + struct work_struct suspend_work; + int keyboard_conn_status; + struct mutex rw_mutex; + + struct mutex power_supply_lock; + struct work_struct power_supply_work; + struct notifier_block power_supply_notifier; + int is_usb_exist; + bool keyboard_is_enable; + bool is_in_suspend; +}; +#endif From 7f42117985aa0fa6359f2b397b6319b781cc5fbe Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Tue, 16 Apr 2024 02:49:02 +0200 Subject: [PATCH 053/226] drivers: input: misc: xiaomi_keyboard: Use MSM DRM notifier Change-Id: I783972b91a22247f4bfafd955fd42383003952f9 Signed-off-by: firebird11 --- .../misc/xiaomi_keyboard/xiaomi_keyboard.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c index 962771069660..98d41b8eaeb2 100644 --- a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c +++ b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c @@ -13,7 +13,7 @@ #include #include #include "xiaomi_keyboard.h" -#include +#include #include static struct xiaomi_keyboard_data *mdata; @@ -351,7 +351,7 @@ static const struct dev_pm_ops xiaomi_keyboard_pm_ops = { static int keyboard_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data) { - struct drm_notify_data *evdata = data; + struct msm_drm_notifier *evdata = data; int *blank; struct xiaomi_keyboard_data *mdata = container_of(self, struct xiaomi_keyboard_data, drm_notif); @@ -362,15 +362,15 @@ static int keyboard_drm_notifier_callback(struct notifier_block *self, if (evdata->data && mdata) { blank = evdata->data; flush_workqueue(mdata->event_wq); - if (event == DRM_EARLY_EVENT_BLANK) { - if (*blank == DRM_BLANK_POWERDOWN) { + if (event == MSM_DRM_EARLY_EVENT_BLANK) { + if (*blank == MSM_DRM_BLANK_POWERDOWN) { MI_KB_ERR("keyboard suspend"); mdata->is_in_suspend = true; queue_work(mdata->event_wq, &mdata->suspend_work); } - } else if (event == DRM_EVENT_BLANK) { - if (*blank == DRM_BLANK_UNBLANK) { + } else if (event == MSM_DRM_EVENT_BLANK) { + if (*blank == MSM_DRM_BLANK_UNBLANK) { MI_KB_ERR("keyboard resume"); mdata->is_in_suspend = false; flush_workqueue(mdata->event_wq); @@ -555,7 +555,7 @@ static int xiaomi_keyboard_probe(struct platform_device *pdev) INIT_WORK(&mdata->power_supply_work, kb_power_supply_work); mdata->drm_notif.notifier_call = keyboard_drm_notifier_callback; - ret = drm_register_client(&mdata->drm_notif); + ret = msm_drm_register_client(&mdata->drm_notif); if (ret) { MI_KB_ERR("register drm_notifier failed. ret=%d\n", ret); goto err_register_drm_notif_failed; @@ -574,7 +574,7 @@ static int xiaomi_keyboard_probe(struct platform_device *pdev) err_register_power_supply_notif_failed: err_register_drm_notif_failed: - if (drm_unregister_client(&mdata->drm_notif)) + if (msm_drm_unregister_client(&mdata->drm_notif)) MI_KB_ERR("Error occurred while unregistering drm_notifier\n"); if (mdata->event_wq) { destroy_workqueue(mdata->event_wq); @@ -601,7 +601,7 @@ static int xiaomi_keyboard_probe(struct platform_device *pdev) static int xiaomi_keyboard_remove(struct platform_device *pdev) { MI_KB_INFO("enter\n"); - drm_unregister_client(&mdata->drm_notif); + msm_drm_unregister_client(&mdata->drm_notif); destroy_workqueue(mdata->event_wq); xiaomi_keyboard_gpio_deconfig(mdata->pdata); sysfs_remove_file(&mdata->pdev->dev.kobj, From 36a73a61c9cd1ac5c2e32930d4d14aa5bb1d9981 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 11 Oct 2023 15:20:08 +0200 Subject: [PATCH 054/226] firmware: Add FIRMWARE_IN_KERNEL support Change-Id: Id78f5b6bbb4c42fab30abfef2c78354d7f50c46a Signed-off-by: firebird11 --- firmware/Makefile | 61 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/firmware/Makefile b/firmware/Makefile index 30e6b738839e..96b4a8b0a63b 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -10,6 +10,28 @@ fwabs := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir)) fw-external-y := $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE)) +# There are three cases to care about: +# 1. Building kernel with CONFIG_FIRMWARE_IN_KERNEL=y -- $(fw-shipped-y) should +# include the firmware files to include, according to .config +# 2. 'make modules_install', which will install firmware for modules, and +# _also_ for the in-kernel drivers when CONFIG_FIRMWARE_IN_KERNEL=n +# 3. 'make firmware_install', which installs all firmware, unconditionally. + +# For the former two cases we want $(fw-shipped-y) and $(fw-shipped-m) to be +# accurate. In the latter case it doesn't matter -- it'll use $(fw-shipped-all). +# But be aware that the config file might not be included at all. + +fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) + +quiet_cmd_ihex = IHEX $@ + cmd_ihex = $(OBJCOPY) -Iihex -Obinary $< $@ + +quiet_cmd_ihex2fw = IHEX2FW $@ + cmd_ihex2fw = $(objtree)/$(obj)/ihex2fw $< $@ + +quiet_cmd_h16tofw = H16TOFW $@ + cmd_h16tofw = $(objtree)/$(obj)/ihex2fw -w $< $@ + quiet_cmd_fwbin = MK_FW $@ cmd_fwbin = FWNAME="$(patsubst firmware/%.gen.S,%,$@)"; \ FWSTR="$(subst /,_,$(subst .,_,$(subst -,_,$(patsubst \ @@ -42,14 +64,46 @@ wordsize_deps := $(wildcard include/config/64bit.h include/config/32bit.h \ include/config/x86_32.h include/config/x86_64.h \ firmware/Makefile) +$(patsubst %,$(obj)/%.gen.S, $(fw-shipped-y)): %: $(wordsize_deps) + $(call cmd,fwbin,$(patsubst %.gen.S,%,$@)) $(patsubst %,$(obj)/%.gen.S, $(fw-external-y)): %: $(wordsize_deps) \ include/config/extra/firmware/dir.h $(call cmd,fwbin,$(fwabs)/$(patsubst $(obj)/%.gen.S,%,$@)) # The .o files depend on the binaries directly; the .S files don't. +$(patsubst %,$(obj)/%.gen.o, $(fw-shipped-y)): %.gen.o: % $(patsubst %,$(obj)/%.gen.o, $(fw-external-y)): $(obj)/%.gen.o: $(fwdir)/% +# .ihex is used just as a simple way to hold binary files in a source tree +# where binaries are frowned upon. They are directly converted with objcopy. +$(obj)/%: $(obj)/%.ihex + $(call cmd,ihex) + +# Don't depend on ihex2fw if we're installing and it already exists. +# Putting it after | in the dependencies doesn't seem sufficient when +# we're installing after a cross-compile, because ihex2fw has dependencies +# on stuff like /usr/lib/gcc/ppc64-redhat-linux/4.3.0/include/stddef.h and +# thus wants to be rebuilt. Which it can't be, if the prebuilt kernel tree +# is exported read-only for someone to run 'make install'. +ifeq ($(INSTALL):$(wildcard $(obj)/ihex2fw),install:$(obj)/ihex2fw) +ihex2fw_dep := +else +ihex2fw_dep := $(obj)/ihex2fw +endif + +# .HEX is also Intel HEX, but where the offset and length in each record +# is actually meaningful, because the firmware has to be loaded in a certain +# order rather than as a single binary blob. Thus, we convert them into our +# more compact binary representation of ihex records () +$(obj)/%.fw: $(obj)/%.HEX $(ihex2fw_dep) + $(call cmd,ihex2fw) + +# .H16 is our own modified form of Intel HEX, with 16-bit length for records. +$(obj)/%.fw: $(obj)/%.H16 $(ihex2fw_dep) + $(call cmd,h16tofw) + obj-y += $(patsubst %,%.gen.o, $(fw-external-y)) +obj-$(CONFIG_FIRMWARE_IN_KERNEL) += $(patsubst %,%.gen.o, $(fw-shipped-y)) ifeq ($(KBUILD_SRC),) # Makefile.build only creates subdirectories for O= builds, but external @@ -57,8 +111,11 @@ ifeq ($(KBUILD_SRC),) _dummy := $(foreach d,$(addprefix $(obj)/,$(dir $(fw-external-y))), $(shell [ -d $(d) ] || mkdir -p $(d))) endif -targets := $(patsubst $(obj)/%,%, \ - $(shell find $(obj) -name \*.gen.S 2>/dev/null)) +# Remove .S files and binaries created from ihex +# (during 'make clean' .config isn't included so they're all in $(fw-shipped-)) +targets := $(fw-shipped-) $(patsubst $(obj)/%,%, \ + $(shell find $(obj) -name \*.gen.S 2>/dev/null)) + # Without this, built-in.o won't be created when it's empty, and the # final vmlinux link will fail. obj- := dummy From 5fe7f8e8863777cad651c5f33e4a6de5f560b873 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 6 Nov 2023 11:29:49 +0100 Subject: [PATCH 055/226] drivers: input: touchscreen: Import Xiaomi drivers * fts_521 (andromeda, cepheus, crux) - from cepheus-q-oss * goodix_driver_gt9886 (raphael) - from cepheus-q-oss * nt36523 (nabu): From nabu-r-oss * nt36672c (vayu): From vayu-r-oss * Run clang-format on source files Change-Id: Ie9a3a9c4058b9ccd5c1fa3edb66e0860658a35f0 Signed-off-by: firebird11 --- drivers/input/touchscreen/Kconfig | 2 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/xiaomi/Kconfig | 23 + drivers/input/touchscreen/xiaomi/Makefile | 6 + .../input/touchscreen/xiaomi/fts_521/Kconfig | 25 + .../input/touchscreen/xiaomi/fts_521/Makefile | 6 + .../input/touchscreen/xiaomi/fts_521/fts.c | 7514 ++++++++++ .../input/touchscreen/xiaomi/fts_521/fts.h | 397 + .../input/touchscreen/xiaomi/fts_521/fts_fw.h | 8387 +++++++++++ .../xiaomi/fts_521/fts_lib/Makefile | 7 + .../xiaomi/fts_521/fts_lib/ftsCompensation.c | 764 + .../xiaomi/fts_521/fts_lib/ftsCompensation.h | 110 + .../xiaomi/fts_521/fts_lib/ftsCore.c | 1377 ++ .../xiaomi/fts_521/fts_lib/ftsCore.h | 187 + .../xiaomi/fts_521/fts_lib/ftsError.c | 360 + .../xiaomi/fts_521/fts_lib/ftsError.h | 181 + .../xiaomi/fts_521/fts_lib/ftsFlash.c | 1058 ++ .../xiaomi/fts_521/fts_lib/ftsFlash.h | 106 + .../xiaomi/fts_521/fts_lib/ftsFrame.c | 395 + .../xiaomi/fts_521/fts_lib/ftsFrame.h | 92 + .../xiaomi/fts_521/fts_lib/ftsGesture.c | 363 + .../xiaomi/fts_521/fts_lib/ftsGesture.h | 38 + .../xiaomi/fts_521/fts_lib/ftsHardware.h | 217 + .../xiaomi/fts_521/fts_lib/ftsIO.c | 911 ++ .../xiaomi/fts_521/fts_lib/ftsIO.h | 61 + .../xiaomi/fts_521/fts_lib/ftsSoftware.h | 400 + .../xiaomi/fts_521/fts_lib/ftsTest.c | 6342 ++++++++ .../xiaomi/fts_521/fts_lib/ftsTest.h | 304 + .../xiaomi/fts_521/fts_lib/ftsTime.c | 78 + .../xiaomi/fts_521/fts_lib/ftsTime.h | 63 + .../xiaomi/fts_521/fts_lib/ftsTool.c | 639 + .../xiaomi/fts_521/fts_lib/ftsTool.h | 56 + .../touchscreen/xiaomi/fts_521/fts_limits.h | 1412 ++ .../touchscreen/xiaomi/fts_521/fts_proc.c | 2421 +++ .../xiaomi/goodix_driver_gt9886/Kconfig | 45 + .../xiaomi/goodix_driver_gt9886/Makefile | 7 + .../goodix_driver_gt9886/goodix_cfg_bin.c | 674 + .../goodix_driver_gt9886/goodix_cfg_bin.h | 108 + .../goodix_driver_gt9886/goodix_default_fw.h | 6 + .../goodix_driver_gt9886/goodix_gtx8_update.c | 1397 ++ .../goodix_driver_gt9886/goodix_ts_core.c | 2910 ++++ .../goodix_driver_gt9886/goodix_ts_core.h | 788 + .../goodix_driver_gt9886/goodix_ts_gesture.c | 756 + .../goodix_driver_gt9886/goodix_ts_i2c.c | 2230 +++ .../goodix_driver_gt9886/goodix_ts_tools.c | 722 + .../goodix_driver_gt9886/test_core/Makefile | 40 + .../test_core/board_opr_interface.h | 123 + .../test_core/board_opr_interface_kernel.c | 691 + .../goodix_driver_gt9886/test_core/chip_ini.h | 70 + .../goodix_driver_gt9886/test_core/config.h | 81 + .../test_core/crc_decrypt.c | 205 + .../test_core/crc_decrypt.h | 32 + .../test_core/custom_info_def.h | 30 + .../test_core/extra_tp_control.c | 108 + .../test_core/extra_tp_control.h | 26 + .../test_core/generic_func.c | 250 + .../test_core/generic_func.h | 65 + .../test_core/memory_override.c | 126 + .../test_core/mxml-attr.c | 251 + .../test_core/mxml-entity.c | 246 + .../test_core/mxml-file.c | 1626 ++ .../goodix_driver_gt9886/test_core/mxml-get.c | 287 + .../test_core/mxml-index.c | 358 + .../test_core/mxml-node.c | 551 + .../test_core/mxml-private.c | 267 + .../test_core/mxml-private.h | 41 + .../test_core/mxml-search.c | 196 + .../goodix_driver_gt9886/test_core/mxml-set.c | 238 + .../test_core/mxml-string.c | 393 + .../goodix_driver_gt9886/test_core/mxml.h | 317 + .../test_core/normandy_short_test.c | 900 ++ .../test_core/normandy_short_test.h | 56 + .../test_core/public_fun.c | 59 + .../test_core/public_fun.h | 28 + .../goodix_driver_gt9886/test_core/res_inc.h | 167 + .../test_core/save_test_data.c | 355 + .../test_core/save_test_data.h | 43 + .../test_core/simple_mem_manager.h | 33 + .../test_core/simple_mem_manager_mach.c | 105 + .../goodix_driver_gt9886/test_core/strtol.c | 58 + .../test_core/test_item_def.h | 180 + .../test_core/test_item_init.c | 705 + .../test_core/test_item_init.h | 63 + .../test_core/test_order.c | 2531 ++++ .../test_core/test_order.h | 142 + .../test_core/test_param_init.c | 624 + .../test_core/test_param_init.h | 43 + .../test_core/test_proc.c | 260 + .../test_core/test_proc.h | 41 + .../test_core/tp_additional_option.c | 392 + .../test_core/tp_additional_option.h | 186 + .../test_core/tp_additional_option_param.h | 86 + .../test_core/tp_board_flash_alloc.h | 32 + .../test_core/tp_dev_control.c | 568 + .../test_core/tp_dev_control.h | 86 + .../test_core/tp_dev_def.h | 176 + .../test_core/tp_item_permutation.c | 123 + .../test_core/tp_item_permutation.h | 27 + .../test_core/tp_micro_def.h | 64 + .../test_core/tp_normandy_control.c | 692 + .../test_core/tp_normandy_control.h | 52 + .../test_core/tp_open_test.c | 2196 +++ .../test_core/tp_open_test.h | 227 + .../test_core/tp_open_test_param.h | 132 + .../test_core/tp_product_id_def.h | 66 + .../test_core/tp_short_test.c | 460 + .../test_core/tp_short_test.h | 79 + .../test_core/tp_short_test_param.h | 56 + .../tp_test_general_error_code_def.h | 35 + .../test_core/tp_test_item_buf_mem.c | 216 + .../test_core/tp_test_item_buf_mem.h | 22 + .../test_core/tp_test_item_id.h | 86 + .../test_core/tp_test_item_mem.c | 932 ++ .../test_core/tp_test_item_mem.h | 42 + .../test_core/tp_version_test.c | 267 + .../test_core/tp_version_test.h | 57 + .../test_core/tp_version_test_param.h | 51 + .../test_core/user_test_type_def.h | 143 + drivers/input/touchscreen/xiaomi/ndt_core.c | 1380 ++ drivers/input/touchscreen/xiaomi/ndt_core.h | 3 + .../input/touchscreen/xiaomi/nt36523/Kconfig | 11 + .../input/touchscreen/xiaomi/nt36523/Makefile | 9 + .../touchscreen/xiaomi/nt36523/nt36xxx.c | 3992 +++++ .../touchscreen/xiaomi/nt36523/nt36xxx.h | 292 + .../xiaomi/nt36523/nt36xxx_ext_proc.c | 2639 ++++ .../xiaomi/nt36523/nt36xxx_fw_update.c | 1110 ++ .../xiaomi/nt36523/nt36xxx_mem_map.h | 442 + .../xiaomi/nt36523/nt36xxx_mp_ctrlram.c | 4254 ++++++ .../xiaomi/nt36523/nt36xxx_mp_ctrlram.h | 1678 +++ .../input/touchscreen/xiaomi/nt36672c/Kconfig | 15 + .../touchscreen/xiaomi/nt36672c/Makefile | 7 + .../touchscreen/xiaomi/nt36672c/nt36xxx.c | 3347 +++++ .../touchscreen/xiaomi/nt36672c/nt36xxx.h | 269 + .../xiaomi/nt36672c/nt36xxx_ext_proc.c | 737 + .../xiaomi/nt36672c/nt36xxx_fw_update.c | 1184 ++ .../xiaomi/nt36672c/nt36xxx_mem_map.h | 358 + .../xiaomi/nt36672c/nt36xxx_mp_ctrlram.c | 2610 ++++ .../xiaomi/nt36672c/nt36xxx_mp_ctrlram.h | 87 + .../xiaomi/nt36672c/nt36xxx_mp_ctrlram_data.c | 536 + .../input/touchscreen/xiaomi/spi-xiaomi-tp.c | 196 + .../input/touchscreen/xiaomi/spi-xiaomi-tp.h | 52 + firmware/Makefile | 12 + firmware/goodix_gt9886_cfg_f11.bin.ihex | 116 + firmware/goodix_gt9886_fw_f11.bin.ihex | 5522 +++++++ firmware/j20s_novatek_ts_fw01.bin.ihex | 8707 +++++++++++ firmware/j20s_novatek_ts_fw02.bin.ihex | 8707 +++++++++++ firmware/j20s_novatek_ts_mp01.bin.ihex | 8707 +++++++++++ firmware/j20s_novatek_ts_mp02.bin.ihex | 8707 +++++++++++ firmware/ndt_fw.bin.ihex | 1249 ++ firmware/novatek_nt36523_fw01.bin.ihex | 12291 ++++++++++++++++ firmware/novatek_nt36523_fw02.bin.ihex | 12291 ++++++++++++++++ firmware/novatek_nt36523_mp01.bin.ihex | 12291 ++++++++++++++++ firmware/novatek_nt36523_mp02.bin.ihex | 12291 ++++++++++++++++ firmware/novatek_nt36672_f10.fw.ihex | 7426 ++++++++++ firmware/novatek_ts_fw.bin.ihex | 12291 ++++++++++++++++ firmware/novatek_ts_mp.bin.ihex | 12291 ++++++++++++++++ firmware/st_fts.ftb.ihex | 6813 +++++++++ firmware/st_fts_e5.ftb.ihex | 6799 +++++++++ firmware/st_fts_f1.ftb.ihex | 6816 +++++++++ firmware/st_fts_f1x.ftb.ihex | 6360 ++++++++ firmware/st_fts_j2a.ftb.ihex | 7136 +++++++++ firmware/st_fts_j2a_csot.ftb.ihex | 6948 +++++++++ firmware/st_fts_j2a_sdc.ftb.ihex | 7136 +++++++++ include/uapi/linux/input-event-codes.h | 1 + 164 files changed, 260624 insertions(+) create mode 100644 drivers/input/touchscreen/xiaomi/Kconfig create mode 100644 drivers/input/touchscreen/xiaomi/Makefile create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/Kconfig create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/Makefile create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts.c create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_fw.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/Makefile create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCompensation.c create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCompensation.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCore.c create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCore.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsError.c create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsError.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFlash.c create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFlash.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFrame.c create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFrame.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsGesture.c create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsGesture.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsHardware.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsIO.c create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsIO.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsSoftware.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTest.c create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTest.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTime.c create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTime.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTool.c create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTool.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_limits.h create mode 100644 drivers/input/touchscreen/xiaomi/fts_521/fts_proc.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/Kconfig create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/Makefile create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_cfg_bin.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_cfg_bin.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_default_fw.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_gtx8_update.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_gesture.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_i2c.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_tools.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/Makefile create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/board_opr_interface.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/board_opr_interface_kernel.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/chip_ini.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/config.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/crc_decrypt.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/crc_decrypt.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/custom_info_def.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/extra_tp_control.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/extra_tp_control.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/generic_func.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/generic_func.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/memory_override.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-attr.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-entity.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-file.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-get.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-index.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-node.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-private.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-private.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-search.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-set.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-string.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/normandy_short_test.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/normandy_short_test.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/public_fun.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/public_fun.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/res_inc.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/save_test_data.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/save_test_data.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/simple_mem_manager.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/simple_mem_manager_mach.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/strtol.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_item_def.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_item_init.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_item_init.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_order.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_order.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_param_init.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_param_init.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_proc.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_proc.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_additional_option.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_additional_option.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_additional_option_param.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_board_flash_alloc.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_dev_control.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_dev_control.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_dev_def.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_item_permutation.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_item_permutation.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_micro_def.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_normandy_control.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_normandy_control.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_open_test.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_open_test.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_open_test_param.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_product_id_def.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_short_test.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_short_test.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_short_test_param.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_general_error_code_def.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_buf_mem.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_buf_mem.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_id.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_mem.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_mem.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_version_test.c create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_version_test.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_version_test_param.h create mode 100644 drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/user_test_type_def.h create mode 100644 drivers/input/touchscreen/xiaomi/ndt_core.c create mode 100644 drivers/input/touchscreen/xiaomi/ndt_core.h create mode 100644 drivers/input/touchscreen/xiaomi/nt36523/Kconfig create mode 100644 drivers/input/touchscreen/xiaomi/nt36523/Makefile create mode 100644 drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c create mode 100644 drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.h create mode 100644 drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_ext_proc.c create mode 100644 drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_fw_update.c create mode 100644 drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_mem_map.h create mode 100644 drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_mp_ctrlram.c create mode 100644 drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_mp_ctrlram.h create mode 100755 drivers/input/touchscreen/xiaomi/nt36672c/Kconfig create mode 100755 drivers/input/touchscreen/xiaomi/nt36672c/Makefile create mode 100644 drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c create mode 100644 drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.h create mode 100644 drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_ext_proc.c create mode 100644 drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_fw_update.c create mode 100644 drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mem_map.h create mode 100644 drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mp_ctrlram.c create mode 100644 drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mp_ctrlram.h create mode 100644 drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mp_ctrlram_data.c create mode 100644 drivers/input/touchscreen/xiaomi/spi-xiaomi-tp.c create mode 100644 drivers/input/touchscreen/xiaomi/spi-xiaomi-tp.h create mode 100755 firmware/goodix_gt9886_cfg_f11.bin.ihex create mode 100755 firmware/goodix_gt9886_fw_f11.bin.ihex create mode 100644 firmware/j20s_novatek_ts_fw01.bin.ihex create mode 100644 firmware/j20s_novatek_ts_fw02.bin.ihex create mode 100644 firmware/j20s_novatek_ts_mp01.bin.ihex create mode 100644 firmware/j20s_novatek_ts_mp02.bin.ihex create mode 100644 firmware/ndt_fw.bin.ihex create mode 100644 firmware/novatek_nt36523_fw01.bin.ihex create mode 100644 firmware/novatek_nt36523_fw02.bin.ihex create mode 100644 firmware/novatek_nt36523_mp01.bin.ihex create mode 100644 firmware/novatek_nt36523_mp02.bin.ihex create mode 100755 firmware/novatek_nt36672_f10.fw.ihex create mode 100644 firmware/novatek_ts_fw.bin.ihex create mode 100644 firmware/novatek_ts_mp.bin.ihex create mode 100644 firmware/st_fts.ftb.ihex create mode 100644 firmware/st_fts_e5.ftb.ihex create mode 100644 firmware/st_fts_f1.ftb.ihex create mode 100644 firmware/st_fts_f1x.ftb.ihex create mode 100644 firmware/st_fts_j2a.ftb.ihex create mode 100644 firmware/st_fts_j2a_csot.ftb.ihex create mode 100644 firmware/st_fts_j2a_sdc.ftb.ihex diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 4397e53e3cb4..7f85cd5deb14 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -1298,4 +1298,6 @@ config TOUCHSCREEN_RAYDIUM_CHIPSET source "drivers/input/touchscreen/focaltech_touch/Kconfig" +source "drivers/input/touchscreen/xiaomi/Kconfig" + endif diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 49ade9793bbe..17aa95412a5e 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -112,3 +112,4 @@ obj-$(CONFIG_TOUCHSCREEN_RASPBERRYPI_FW) += raspberrypi-ts.o obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5xx.o obj-$(CONFIG_TOUCHSCREEN_ST) += st/ obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_touch/ +obj-y += xiaomi/ diff --git a/drivers/input/touchscreen/xiaomi/Kconfig b/drivers/input/touchscreen/xiaomi/Kconfig new file mode 100644 index 000000000000..20680df186d4 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/Kconfig @@ -0,0 +1,23 @@ +source "drivers/input/touchscreen/xiaomi/fts_521/Kconfig" +source "drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/Kconfig" +source "drivers/input/touchscreen/xiaomi/nt36523/Kconfig" +source "drivers/input/touchscreen/xiaomi/nt36672c/Kconfig" + +config I2C_BY_DMA + bool "I2C BY DMA" + +config SECURE_TOUCH + bool "Secure Touch" + +config INPUT_PRESS_NDT + bool "ndt" + depends on I2C + help + Say Y here if you have a press ic ndt. + +config SPI_XIAOMI_TP + bool + depends on SPI + default y if TOUCHSCREEN_NT36xxx_HOSTDL_SPI + help + Say Y if want use xiaomi touch panel. diff --git a/drivers/input/touchscreen/xiaomi/Makefile b/drivers/input/touchscreen/xiaomi/Makefile new file mode 100644 index 000000000000..1e07625331f5 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_TOUCHSCREEN_ST_FTS_V521) += fts_521/ +obj-$(CONFIG_TOUCHSCREEN_GOODIX_GTX8) += goodix_driver_gt9886/ +obj-$(CONFIG_TOUCHSCREEN_NT36523_HOSTDL_SPI) += nt36523/ +obj-$(CONFIG_TOUCHSCREEN_NT36xxx_HOSTDL_SPI) += nt36672c/ +obj-$(CONFIG_INPUT_PRESS_NDT) += ndt_core.o +obj-$(CONFIG_SPI_XIAOMI_TP) += spi-xiaomi-tp.o diff --git a/drivers/input/touchscreen/xiaomi/fts_521/Kconfig b/drivers/input/touchscreen/xiaomi/fts_521/Kconfig new file mode 100644 index 000000000000..d074d4b66c4e --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/Kconfig @@ -0,0 +1,25 @@ +config TOUCHSCREEN_ST_FTS_V521 + tristate "ST FTS V521 I2C Touchscreen" + depends on I2C + help + Say Y here if you have ST FTS series I2C touchscreen. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + +config FTS_FOD_AREA_REPORT + tristate "FTS FOD area report" + depends on TOUCHSCREEN_ST_FTS_V521 + help + Say Y here to enable fod area report functionality. + + If unsure, say N. + +config TOUCHSCREEN_ST_DEBUG_FS + tristate "St core driver module" + depends on TOUCHSCREEN_ST_FTS_V521 + help + Say Y here to enable touch debugfs functionality. + + If unsure, say N. diff --git a/drivers/input/touchscreen/xiaomi/fts_521/Makefile b/drivers/input/touchscreen/xiaomi/fts_521/Makefile new file mode 100644 index 000000000000..cf21f2190fcc --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the touchscreen drivers. +# + +obj-$(CONFIG_TOUCHSCREEN_ST_FTS_V521) += fts.o fts_proc.o fts_lib/ + diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts.c b/drivers/input/touchscreen/xiaomi/fts_521/fts.c new file mode 100644 index 000000000000..e03e326c2241 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts.c @@ -0,0 +1,7514 @@ +/* + * fts.c + * + * FTS Capacitive touch screen controller (FingerTipS) + * + * Copyright (C) 2016, STMicroelectronics Limited. + * Copyright (C) 2019 XiaoMi, Inc. + * Authors: AMG(Analog Mems Group) + * + * marco.cali@st.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THE PRESENT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, FOR THE SOLE + * PURPOSE TO SUPPORT YOUR APPLICATION DEVELOPMENT. + * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, + * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE + * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING + * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS. + */ + +/*! +* \file fts.c +* \brief It is the main file which contains all the most important functions generally used by a device driver the driver +*/ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SECURE_TOUCH +#include +#include +#include +#endif + +#include +#include +#include + +#include +#ifdef CONFIG_DRM +#include +#endif +#include + +#include +#include +#include +#include + +#ifdef KERNEL_ABOVE_2_6_38 +#include +#endif +#include "../xiaomi/xiaomi_touch.h" +#include "fts.h" +#include "fts_lib/ftsCompensation.h" +#include "fts_lib/ftsCore.h" +#include "fts_lib/ftsIO.h" +#include "fts_lib/ftsError.h" +#include "fts_lib/ftsFlash.h" +#include "fts_lib/ftsFrame.h" +#include "fts_lib/ftsGesture.h" +#include "fts_lib/ftsTest.h" +#include "fts_lib/ftsTime.h" +#include "fts_lib/ftsTool.h" + +/** + * Event handler installer helpers + */ +#define event_id(_e) (EVT_ID_##_e >> 4) +#define handler_name(_h) fts_##_h##_event_handler + +#define install_handler(_i, _evt, _hnd) \ + do { \ + _i->event_dispatch_table[event_id(_evt)] = handler_name(_hnd); \ + } while (0) + +#ifdef KERNEL_ABOVE_2_6_38 +#define TYPE_B_PROTOCOL +#endif + +#define INPUT_EVENT_START 0 +#define INPUT_EVENT_SENSITIVE_MODE_OFF 0 +#define INPUT_EVENT_SENSITIVE_MODE_ON 1 +#define INPUT_EVENT_STYLUS_MODE_OFF 2 +#define INPUT_EVENT_STYLUS_MODE_ON 3 +#define INPUT_EVENT_WAKUP_MODE_OFF 4 +#define INPUT_EVENT_WAKUP_MODE_ON 5 +#define INPUT_EVENT_COVER_MODE_OFF 6 +#define INPUT_EVENT_COVER_MODE_ON 7 +#define INPUT_EVENT_SLIDE_FOR_VOLUME 8 +#define INPUT_EVENT_DOUBLE_TAP_FOR_VOLUME 9 +#define INPUT_EVENT_SINGLE_TAP_FOR_VOLUME 10 +#define INPUT_EVENT_LONG_SINGLE_TAP_FOR_VOLUME 11 +#define INPUT_EVENT_PALM_OFF 12 +#define INPUT_EVENT_PALM_ON 13 +#define INPUT_EVENT_END 13 + +extern SysInfo systemInfo; +extern TestToDo tests; +#ifdef GESTURE_MODE +extern struct mutex gestureMask_mutex; +#endif + +char tag[8] = "[ FTS ]\0"; +/* buffer which store the input device name assigned by the kernel */ +char fts_ts_phys[64]; +/* buffer used to store the command sent from the MP device file node */ +static u32 typeOfComand[CMD_STR_LEN] = { 0 }; + +/* number of parameter passed through the MP device file node */ +static int numberParameters; +#ifdef USE_ONE_FILE_NODE +static int feature_feasibility = ERROR_OP_NOT_ALLOW; +#endif +#ifdef GESTURE_MODE +static u8 mask[GESTURE_MASK_SIZE + 2]; +extern u16 gesture_coordinates_x[GESTURE_MAX_COORDS_PAIRS_REPORT]; +extern u16 gesture_coordinates_y[GESTURE_MAX_COORDS_PAIRS_REPORT]; +extern int gesture_coords_reported; +extern struct mutex gestureMask_mutex; +#endif +/* store the last update of the key mask published by the IC */ +#ifdef PHONE_KEY +static u8 key_mask; +#endif + +extern spinlock_t fts_int; +struct fts_ts_info *fts_info; + +static int fts_init_sensing(struct fts_ts_info *info); +static int fts_mode_handler(struct fts_ts_info *info, int force); +static int fts_chip_initialization(struct fts_ts_info *info, int init_type); +static const char *fts_get_limit(struct fts_ts_info *info); +static irqreturn_t fts_event_handler(int irq, void *ts_info); +extern void lpm_disable_for_input(bool on); +extern void touch_irq_boost(void); + +/** +* Release all the touches in the linux input subsystem +* @param info pointer to fts_ts_info which contains info about the device and its hw setup +*/ +void release_all_touches(struct fts_ts_info *info) +{ + unsigned int type = MT_TOOL_FINGER; + int i; + + for (i = 0; i < TOUCH_ID_MAX; i++) { +#ifdef STYLUS_MODE + if (test_bit(i, &info->stylus_id)) + type = MT_TOOL_PEN; + else + type = MT_TOOL_FINGER; +#endif + info->coor[i][0] = -1; + info->coor[i][1] = -1; + input_mt_slot(info->input_dev, i); + input_mt_report_slot_state(info->input_dev, type, 0); + input_report_abs(info->input_dev, ABS_MT_TRACKING_ID, -1); + } + input_sync(info->input_dev); + info->touch_id = 0; + info->touch_skip = 0; + info->fod_id = 0; +#ifdef STYLUS_MODE + info->stylus_id = 0; +#endif + lpm_disable_for_input(false); +} + +/** + * @defgroup file_nodes Driver File Nodes + * Driver publish a series of file nodes used to provide several utilities to the host and give him access to different API. + * @{ + */ + +/** + * @defgroup device_file_nodes Device File Nodes + * @ingroup file_nodes + * Device File Nodes \n + * There are several file nodes that are associated to the device and which are designed to be used by the host to enable/disable features or trigger some system specific actions \n + * Usually their final path depend on the definition of device tree node of the IC (e.g /sys/devices/soc.0/f9928000.i2c/i2c-6/6-0049) + * @{ + */ +/***************************************** FW UPGGRADE ***************************************************/ + +/** + * File node function to Update firmware from shell \n + * echo path_to_fw X Y > fwupdate perform a fw update \n + * where: \n + * path_to_fw = file name or path of the the FW to burn, if "NULL" the default approach selected in the driver will be used\n + * X = 0/1 to force the FW update whichever fw_version and config_id; 0=perform a fw update only if the fw in the file is newer than the fw in the chip \n + * Y = 0/1 keep the initialization data; 0 = will erase the initialization data from flash, 1 = will keep the initialization data + * the string returned in the shell is made up as follow: \n + * { = start byte \n + * X1X2X3X4 = 4 bytes in HEX format which represent an error code (00000000 no error) \n + * } = end byte + */ +static ssize_t fts_fwupdate_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret, mode[2]; + char path[100]; + struct fts_ts_info *info = dev_get_drvdata(dev); + + /* by default(if not specified by the user) set the force = 0 and keep_cx to 1 */ + mode[0] = 0; + mode[1] = 1; + + /* reading out firmware upgrade parameters */ + sscanf(buf, "%100s %d %d", path, &mode[0], &mode[1]); + logError(1, "%s fts_fwupdate_store: mode = %s \n", tag, path); + + ret = flashProcedure(path, mode[0], mode[1]); + + info->fwupdate_stat = ret; + + if (ret < OK) + logError(1, "%s %s Unable to upgrade firmware! ERROR %08X\n", + tag, __func__, ret); + return count; +} + +static ssize_t fts_fwupdate_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + + /*fwupdate_stat: ERROR code Returned by flashProcedure. */ + return snprintf(buf, PAGE_SIZE, "{ %08X }\n", info->fwupdate_stat); +} + +/***************************************** UTILITIES (current fw_ver/conf_id, active mode, file fw_ver/conf_id) ***************************************************/ +/** +* File node to show on terminal external release version in Little Endian (first the less significant byte) \n +* cat appid show on the terminal external release version of the FW running in the IC +*/ +static ssize_t fts_appid_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int error; + char temp[100] = { + 0x00, + }; + + error = snprintf(buf, PAGE_SIZE, "%s\n", + printHex("EXT Release = ", systemInfo.u8_releaseInfo, + EXTERNAL_RELEASE_INFO_SIZE, temp)); + + return error; +} + +/** + * File node to show on terminal the mode that is active on the IC \n + * cat mode_active to show the bitmask which indicate the modes/features which are running on the IC in a specific instant of time + * the string returned in the shell is made up as follow: \n + * { = start byte \n + * X1 = 1 byte in HEX format which represent the actual running scan mode (@link scan_opt Scan Mode Options @endlink) \n + * X2 = 1 byte in HEX format which represent the bitmask on which is running the actual scan mode \n + * X3X4 = 2 bytes in HEX format which represent a bitmask of the features that are enabled at this moment (@link feat_opt Feature Selection Options @endlink) \n + * } = end byte + * @see fts_mode_handler() + */ +static ssize_t fts_mode_active_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + + logError(1, "%s Current mode active = %08X\n", tag, info->mode); + return snprintf(buf, PAGE_SIZE, "{ %08X }\n", info->mode); +} + +/** + * File node to show the fw_ver and config_id of the FW file + * cat fw_file_test show on the kernel log fw_version and config_id of the FW stored in the fw file/header file + */ +static ssize_t fts_fw_test_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + Firmware fw; + int ret; + char temp[100] = { + 0x00, + }; + struct fts_ts_info *info = dev_get_drvdata(dev); + + fw.data = NULL; + ret = readFwFile(info->board->default_fw_name, &fw, 0); + + if (ret < OK) { + logError(1, "%s Error during reading FW file! ERROR %08X\n", + tag, ret); + } else { + logError(1, "%s %s, size = %d bytes\n", tag, + printHex("EXT Release = ", systemInfo.u8_releaseInfo, + EXTERNAL_RELEASE_INFO_SIZE, temp), + fw.data_size); + } + + kfree(fw.data); + return 0; +} + +/***************************************** FEATURES ***************************************************/ + +/*TODO: edit this function according to the features policy to allow during the screen on/off, following is shown an example but check always with ST for more details*/ +/** + * Check if there is any conflict in enable/disable a particular feature considering the features already enabled and running + * @param info pointer to fts_ts_info which contains info about the device and its hw setup + * @param feature code of the feature that want to be tested + * @return OK if is possible to enable/disable feature, ERROR_OP_NOT_ALLOW in case of any other conflict + */ +int check_feature_feasibility(struct fts_ts_info *info, unsigned int feature) +{ + int res = OK; + + switch (feature) { + case FEAT_SEL_GESTURE: + if (info->cover_enabled == 1) { + res = ERROR_OP_NOT_ALLOW; + logError( + 1, + "%s %s: Feature not allowed when in Cover mode! ERROR %08X \n", + tag, __func__, res); + /*for example here can be placed a code for disabling the cover mode when gesture is activated */ + } + break; + + case FEAT_SEL_GLOVE: + if (info->gesture_enabled == 1) { + res = ERROR_OP_NOT_ALLOW; + logError( + 1, + "%s %s: Feature not allowed when Gestures enabled! ERROR %08X \n", + tag, __func__, res); + /*for example here can be placed a code for disabling the gesture mode when cover is activated (that means that cover mode has an higher priority on gesture mode) */ + } + break; + + default: + logError(1, "%s %s: Feature Allowed! \n", tag, __func__); + } + + return res; +} + +#ifdef USE_ONE_FILE_NODE +/** + * File node to enable some feature + * echo XX 00/01 > feature_enable to enable/disable XX (possible values @link feat_opt Feature Selection Options @endlink) feature \n + * cat feature_enable to show the result of enabling/disabling process \n + * echo 01/00 > feature_enable; cat feature_enable to perform both actions stated before in just one call \n + * the string returned in the shell is made up as follow: \n + * { = start byte \n + * X1X2X3X4 = 4 bytes in HEX format which represent an error code (00000000 = no error) \n + * } = end byte + */ +static ssize_t fts_feature_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + char *p = (char *)buf; + unsigned int temp; + int res = OK; + + if ((count - 2 + 1) / 3 != 1) { + logError( + 1, + "%s fts_feature_enable: Number of parameter wrong! %d > %d \n", + tag, (count - 2 + 1) / 3, 1); + } else { + sscanf(p, "%02X ", &temp); + p += 9; + res = check_feature_feasibility(info, temp); + if (res >= OK) { + switch (temp) { +#ifdef GESTURE_MODE + case FEAT_SEL_GESTURE: + sscanf(p, "%02X ", &info->gesture_enabled); + logError( + 1, + "%s fts_feature_enable: Gesture Enabled = %d \n", + tag, info->gesture_enabled); + break; +#endif + +#ifdef GLOVE_MODE + case FEAT_SEL_GLOVE: + sscanf(p, "%02X ", &info->glove_enabled); + logError( + 1, + "%s fts_feature_enable: Glove Enabled = %d \n", + tag, info->glove_enabled); + + break; +#endif + +#ifdef STYLUS_MODE + case FEAT_SEL_STYLUS: + sscanf(p, "%02X ", &info->stylus_enabled); + logError( + 1, + "%s fts_feature_enable: Stylus Enabled = %d \n", + tag, info->stylus_enabled); + + break; +#endif + +#ifdef COVER_MODE + case FEAT_SEL_COVER: + sscanf(p, "%02X ", &info->cover_enabled); + logError( + 1, + "%s fts_feature_enable: Cover Enabled = %d \n", + tag, info->cover_enabled); + + break; +#endif + +#ifdef CHARGER_MODE + case FEAT_SEL_CHARGER: + sscanf(p, "%02X ", &info->charger_enabled); + logError( + 1, + "%s fts_feature_enable: Charger Enabled = %d \n", + tag, info->charger_enabled); + + break; +#endif + +#ifdef GRIP_MODE + case FEAT_SEL_GRIP: + sscanf(p, "%02X ", &info->grip_enabled); + logError( + 1, + "%s fts_feature_enable: Grip Enabled = %d \n", + tag, info->grip_enabled); + + break; +#endif + default: + logError( + 1, + "%s fts_feature_enable: Feature %08X not valid! ERROR %08X\n", + tag, temp, ERROR_OP_NOT_ALLOW); + res = ERROR_OP_NOT_ALLOW; + } + feature_feasibility = res; + } + if (feature_feasibility >= OK) + feature_feasibility = fts_mode_handler(info, 1); + else { + logError( + 1, + "%s %s: Call echo XX 00/01 > feature_enable with a correct feature value (XX)! ERROR %08X \n", + tag, __func__, res); + } + } + return count; +} + +static ssize_t fts_feature_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int size = (6 * 2) + 1, index = 0; + u8 *all_strbuff = NULL; + int count = 0; + + if (feature_feasibility < OK) { + logError( + 1, + "%s %s: Call before echo XX 00/01 > feature_enable with a correct feature value (XX)! ERROR %08X \n", + tag, __func__, feature_feasibility); + } + + all_strbuff = (u8 *)kzalloc(size, GFP_KERNEL); + if (all_strbuff != NULL) { + index += snprintf(&all_strbuff[index], 13, "{ %08X }", + feature_feasibility); + count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff); + kfree(all_strbuff); + } else { + logError( + 1, + "%s fts_feature_enable_show: Unable to allocate all_strbuff! ERROR %08X\n", + tag, ERROR_ALLOC); + } + + feature_feasibility = ERROR_OP_NOT_ALLOW; + return count; +} +#else + +#ifdef GRIP_MODE +/** + * File node to set the grip mode + * echo 01/00 > grip_mode to enable/disable glove mode \n + * cat grip_mode to show the status of the grip_enabled switch \n + * echo 01/00 > grip_mode; cat grip_mode to enable/disable grip mode and see the switch status in just one call \n + * the string returned in the shell is made up as follow: \n + * { = start byte \n + * X1X2X3X4 = 4 bytes in HEX format which represent the value info->grip_enabled (1 = enabled; 0= disabled) \n + * } = end byte + */ +static ssize_t fts_grip_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int size = (6 * 2) + 1, index = 0; + u8 *all_strbuff = NULL; + int count = 0; + struct fts_ts_info *info = dev_get_drvdata(dev); + + logError(0, "%s %s: grip_enabled = %d \n", tag, __func__, + info->grip_enabled); + + all_strbuff = (u8 *)kzalloc(size, GFP_KERNEL); + if (all_strbuff != NULL) { + index += snprintf(&all_strbuff[index], 13, "{ %08X }", + info->grip_enabled); + + count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff); + kfree(all_strbuff); + } else { + logError(1, + "%s %s: Unable to allocate all_strbuff! ERROR %08X\n", + tag, __func__, ERROR_ALLOC); + } + + return count; +} + +static ssize_t fts_grip_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char *p = (char *)buf; + unsigned int temp; + int res; + struct fts_ts_info *info = dev_get_drvdata(dev); + + /*in case of a different elaboration of the input, just modify this initial part of the code according to customer needs*/ + if ((count + 1) / 3 != 1) { + logError( + 1, + "%s %s: Number of bytes of parameter wrong! %d != %d byte\n", + tag, __func__, (count + 1) / 3, 1); + } else { + sscanf(p, "%02X ", &temp); + p += 3; + /* +*this is a standard code that should be always used when a feature is enabled! +*first step : check if the wanted feature can be enabled +*second step: call fts_mode_handler to actually enable it +*NOTE: Disabling a feature is always allowed by default +*/ + res = check_feature_feasibility(info, FEAT_SEL_GRIP); + if (res >= OK || temp == FEAT_DISABLE) { + info->grip_enabled = temp; + res = fts_mode_handler(info, 1); + if (res < OK) { + logError( + 1, + "%s %s: Error during fts_mode_handler! ERROR %08X\n", + tag, __func__, res); + } + } + } + return count; +} +#endif + +#ifdef CHARGER_MODE +/** + * File node to set the glove mode + * echo XX/00 > charger_mode to value >0 to enable (possible values: @link charger_opt Charger Options @endlink),00 to disable charger mode \n + * cat charger_mode to show the status of the charger_enabled switch \n + * echo 01/00 > charger_mode; cat charger_mode to enable/disable charger mode and see the switch status in just one call \n + * the string returned in the shell is made up as follow: \n + * { = start byte \n + * X1X2X3X4 = 4 bytes in HEX format which represent the value info->charger_enabled (>0 = enabled; 0= disabled) \n + * } = end byte + */ +static ssize_t fts_charger_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int size = (6 * 2) + 1, index = 0; + u8 *all_strbuff = NULL; + int count = 0; + struct fts_ts_info *info = dev_get_drvdata(dev); + + logError(0, "%s %s: charger_enabled = %d \n", tag, __func__, + info->charger_enabled); + + all_strbuff = (u8 *)kzalloc(size, GFP_KERNEL); + if (all_strbuff != NULL) { + index += snprintf(&all_strbuff[index], 13, "{ %08X }", + info->charger_enabled); + count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff); + kfree(all_strbuff); + } else { + logError(1, + "%s %s: Unable to allocate all_strbuff! ERROR %08X\n", + tag, __func__, ERROR_ALLOC); + } + + return count; +} + +static ssize_t fts_charger_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char *p = (char *)buf; + unsigned int temp; + int res; + struct fts_ts_info *info = dev_get_drvdata(dev); + + /*in case of a different elaboration of the input, just modify this initial part of the code according to customer needs*/ + if ((count + 1) / 3 != 1) { + logError( + 1, + "%s %s: Number of bytes of parameter wrong! %d != %d byte\n", + tag, __func__, (count + 1) / 3, 1); + } else { + sscanf(p, "%02X ", &temp); + p += 3; + /* +*this is a standard code that should be always used when a feature is enabled! +*first step : check if the wanted feature can be enabled +*second step: call fts_mode_handler to actually enable it +*NOTE: Disabling a feature is always allowed by default +*/ + res = check_feature_feasibility(info, FEAT_SEL_CHARGER); + if (res >= OK || temp == FEAT_DISABLE) { + info->charger_enabled = temp; + res = fts_mode_handler(info, 1); + if (res < OK) { + logError( + 1, + "%s %s: Error during fts_mode_handler! ERROR %08X\n", + tag, __func__, res); + } + } + } + return count; +} +#endif + +#ifdef GLOVE_MODE +/** + * File node to set the glove mode + * echo 01/00 > glove_mode to enable/disable glove mode \n + * cat glove_mode to show the status of the glove_enabled switch \n + * echo 01/00 > glove_mode; cat glove_mode to enable/disable glove mode and see the switch status in just one call \n + * the string returned in the shell is made up as follow: \n + * { = start byte \n + * X1X2X3X4 = 4 bytes in HEX format which represent the of value info->glove_enabled (1 = enabled; 0= disabled) \n + * } = end byte + */ +static ssize_t fts_glove_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int size = (6 * 2) + 1, index = 0; + u8 *all_strbuff = NULL; + int count = 0; + struct fts_ts_info *info = dev_get_drvdata(dev); + + logError(0, "%s %s: glove_enabled = %d \n", tag, __func__, + info->glove_enabled); + + all_strbuff = (u8 *)kzalloc(size, GFP_KERNEL); + if (all_strbuff != NULL) { + index += snprintf(&all_strbuff[index], 13, "{ %08X }", + info->glove_enabled); + count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff); + kfree(all_strbuff); + } else { + logError(1, + "%s %s: Unable to allocate all_strbuff! ERROR %08X\n", + tag, __func__, ERROR_ALLOC); + } + + return count; +} + +static ssize_t fts_glove_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char *p = (char *)buf; + unsigned int temp; + int res; + struct fts_ts_info *info = dev_get_drvdata(dev); + + /*in case of a different elaboration of the input, just modify this initial part of the code according to customer needs*/ + if ((count + 1) / 3 != 1) { + logError( + 1, + "%s %s: Number of bytes of parameter wrong! %d != %d byte\n", + tag, __func__, (count + 1) / 3, 1); + } else { + sscanf(p, "%02X ", &temp); + p += 3; + /* +*this is a standard code that should be always used when a feature is enabled! +*first step : check if the wanted feature can be enabled +*second step: call fts_mode_handler to actually enable it +*NOTE: Disabling a feature is always allowed by default +*/ + res = check_feature_feasibility(info, FEAT_SEL_GLOVE); + if (res >= OK || temp == FEAT_DISABLE) { + info->glove_enabled = temp; + res = fts_mode_handler(info, 1); + if (res < OK) { + logError( + 1, + "%s %s: Error during fts_mode_handler! ERROR %08X\n", + tag, __func__, res); + } + } + } + + return count; +} +#endif + +#ifdef COVER_MODE +/** + * File node to set the cover mode + * echo 01/00 > cover_mode to enable/disable cover mode \n + * cat cover_mode to show the status of the cover_enabled switch \n + * echo 01/00 > cover_mode; cat cover_mode to enable/disable cover mode and see the switch status in just one call \n + * the string returned in the shell is made up as follow: \n + * { = start byte \n + * X1X2X3X4 = 4 bytes in HEX format which is the value of info->cover_enabled (1 = enabled; 0= disabled)\n + * } = end byte\n + * NOTE: \n + * the cover can be handled also using a notifier, in this case the body of these functions should be copied in the notifier callback + */ +static ssize_t fts_cover_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int size = (6 * 2) + 1, index = 0; + u8 *all_strbuff = NULL; + int count = 0; + struct fts_ts_info *info = dev_get_drvdata(dev); + + logError(0, "%s %s: cover_enabled = %d \n", tag, __func__, + info->cover_enabled); + + all_strbuff = (u8 *)kzalloc(size, GFP_KERNEL); + if (all_strbuff != NULL) { + index += snprintf(&all_strbuff[index], 13, "{ %08X }", + info->cover_enabled); + count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff); + kfree(all_strbuff); + } else { + logError(1, + "%s %s: Unable to allocate all_strbuff! ERROR %08X\n", + tag, __func__, ERROR_ALLOC); + } + + return count; +} + +static ssize_t fts_cover_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char *p = (char *)buf; + unsigned int temp; + int res; + struct fts_ts_info *info = dev_get_drvdata(dev); + + /*in case of a different elaboration of the input, just modify this initial part of the code according to customer needs*/ + if ((count + 1) / 3 != 1) { + logError( + 1, + "%s %s: Number of bytes of parameter wrong! %d != %d byte\n", + tag, __func__, (count + 1) / 3, 1); + } else { + sscanf(p, "%02X ", &temp); + p += 3; + /* +*this is a standard code that should be always used when a feature is enabled! +*first step : check if the wanted feature can be enabled +*second step: call fts_mode_handler to actually enable it +*NOTE: Disabling a feature is always allowed by default +*/ + res = check_feature_feasibility(info, FEAT_SEL_COVER); + if (res >= OK || temp == FEAT_DISABLE) { + info->cover_enabled = temp; + res = fts_mode_handler(info, 1); + if (res < OK) { + logError( + 1, + "%s %s: Error during fts_mode_handler! ERROR %08X\n", + tag, __func__, res); + } + } + } + + return count; +} +#endif + +#ifdef STYLUS_MODE +/** + * File node to enable the stylus report + * echo 01/00 > stylus_mode to enable/disable stylus mode\n + * cat stylus_mode to show the status of the stylus_enabled switch\n + * echo 01/00 > stylus_mode; cat stylus_mode to enable/disable stylus mode and see the switch status in just one call\n + * the string returned in the shell is made up as follow:\n + * { = start byte \n + * X1X2X3X4 = 4 bytes in HEX format which is the value of info->stylus_enabled (1 = enabled; 0= disabled)\n + * } = end byte + */ +static ssize_t fts_stylus_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int size = (6 * 2) + 1, index = 0; + u8 *all_strbuff = NULL; + int count = 0; + struct fts_ts_info *info = dev_get_drvdata(dev); + + logError(0, "%s %s: stylus_enabled = %d \n", tag, __func__, + info->stylus_enabled); + + all_strbuff = (u8 *)kzalloc(size, GFP_KERNEL); + if (all_strbuff != NULL) { + index += snprintf(&all_strbuff[index], 13, "{ %08X }", + info->stylus_enabled); + + count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff); + kfree(all_strbuff); + } else { + logError(1, + "%s %s: Unable to allocate all_strbuff! ERROR %08X\n", + tag, __func__, ERROR_ALLOC); + } + + return count; +} + +static ssize_t fts_stylus_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char *p = (char *)buf; + unsigned int temp; + struct fts_ts_info *info = dev_get_drvdata(dev); + + /*in case of a different elaboration of the input, just modify this initial part of the code according to customer needs*/ + if ((count + 1) / 3 != 1) { + logError( + 1, + "%s %s: Number of bytes of parameter wrong! %d != %d byte\n", + tag, __func__, (count + 1) / 3, 1); + } else { + sscanf(p, "%02X ", &temp); + p += 3; + info->stylus_enabled = temp; + } + return count; +} +#endif + +#endif + +/***************************************** GESTURES ***************************************************/ +#ifdef GESTURE_MODE +#ifdef USE_GESTURE_MASK +/** + * File node used by the host to set the gesture mask to enable or disable + * echo EE X1 X2 ~~ > gesture_mask set the gesture to disable/enable; EE = 00(disable) or 01(enable)\n + * X1 ~~ = gesture mask (example 06 00 ~~ 00 this gesture mask represents the gestures with ID = 1 and 2) can be specified from 1 to GESTURE_MASK_SIZE bytes,\n + * if less than GESTURE_MASK_SIZE bytes are passed as arguments, the omit bytes of the mask maintain the previous settings\n + * if one or more gestures is enabled the driver will automatically enable the gesture mode, If all the gestures are disabled the driver automatically will disable the gesture mode\n + * cat gesture_mask set inside the specified mask and return an error code for the operation \n + * the string returned in the shell is made up as follow:\n + * { = start byte \n + * X1X2X3X4 = 4 bytes in HEX format which represent an error code for enabling the mask (00000000 = no error)\n + * } = end byte \n\n + * if USE_GESTURE_MASK is not define the usage of the function become: \n\n + * echo EE X1 X2 ~~ > gesture_mask set the gesture to disable/enable; EE = 00(disable) or 01(enable)\n + * X1 ~~ = gesture IDs (example 01 02 05 represent the gestures with ID = 1, 2 and 5) there is no limit of the IDs passed as arguments, (@link gesture_opt Gesture IDs @endlink)\n + * if one or more gestures is enabled the driver will automatically enable the gesture mode. If all the gestures are disabled the driver automatically will disable the gesture mode.\n + * cat gesture_mask to show the status of the gesture enabled switch \n + * the string returned in the shell is made up as follow:\n + * { = start byte \n + * X1X2X3X4 = 4 bytes in HEX format which is the value of info->gesture_enabled (1 = enabled; 0= disabled)\n + * } = end byte + */ +static ssize_t fts_gesture_mask_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int size = (6 * 2) + 1, index = 0; + u8 *all_strbuff = NULL; + int count = 0, res, temp; + struct fts_ts_info *info = dev_get_drvdata(dev); + + if (mask[0] == 0) { + res = ERROR_OP_NOT_ALLOW; + logError( + 1, + "%s %s: Call before echo enable/disable xx xx .... > gesture_mask with a correct number of parameters! ERROR %08X \n", + tag, __func__, res); + } else { + if (mask[1] == FEAT_ENABLE || mask[1] == FEAT_DISABLE) + res = updateGestureMask(&mask[2], mask[0], mask[1]); + else + res = ERROR_OP_NOT_ALLOW; + + if (res < OK) { + logError(1, "%s fts_gesture_mask_store: ERROR %08X \n", + tag, res); + } + } + res |= check_feature_feasibility(info, FEAT_SEL_GESTURE); + temp = isAnyGestureActive(); + if (res >= OK || temp == FEAT_DISABLE) { + info->gesture_enabled = temp; + } + + logError(1, "%s fts_gesture_mask_store: Gesture Enabled = %d \n", tag, + info->gesture_enabled); + + all_strbuff = (u8 *)kzalloc(size, GFP_KERNEL); + if (all_strbuff != NULL) { + index += snprintf(&all_strbuff[index], 13, "{ %08X }", res); + + count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff); + kfree(all_strbuff); + } else { + logError( + 1, + "%s fts_gesture_mask_show: Unable to allocate all_strbuff! ERROR %08X\n", + tag, ERROR_ALLOC); + } + + mask[0] = 0; + return count; +} + +static ssize_t fts_gesture_mask_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char *p = (char *)buf; + int n; + unsigned int temp; + + if ((count + 1) / 3 > GESTURE_MASK_SIZE + 1) { + logError( + 1, + "%s fts_gesture_mask_store: Number of bytes of parameter wrong! %d > (enable/disable + %d )\n", + tag, (count + 1) / 3, GESTURE_MASK_SIZE); + mask[0] = 0; + } else { + mask[0] = ((count + 1) / 3) - 1; + for (n = 1; n <= (count + 1) / 3; n++) { + sscanf(p, "%02X ", &temp); + p += 3; + mask[n] = (u8)temp; + logError(0, "%s mask[%d] = %02X \n", tag, n, mask[n]); + } + } + + return count; +} + +#else +/** + * File node used by the host to set the gesture mask to enable or disable + * echo EE X1 X2 ~~ > gesture_mask set the gesture to disable/enable; EE = 00(disable) or 01(enable)\n + * X1 ~ = gesture IDs (example 01 02 05 represent the gestures with ID = 1, 2 and 5) there is no limit of the IDs passed as arguments, (@link gesture_opt Gesture IDs @endlink) \n + * if one or more gestures is enabled the driver will automatically enable the gesture mode, If all the gestures are disabled the driver automatically will disable the gesture mode \n + * cat gesture_mask to show the status of the gesture enabled switch \n + * the string returned in the shell is made up as follow: \n + * { = start byte \n + * X1X2X3X4 = 4 bytes in HEX format which is the value of info->gesture_enabled (1 = enabled; 0= disabled)\n + * } = end byte + */ +static ssize_t fts_gesture_mask_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int size = (6 * 2) + 1, index = 0; + u8 *all_strbuff = NULL; + int count = 0; + struct fts_ts_info *info = dev_get_drvdata(dev); + + logError(0, "%s fts_gesture_mask_show: gesture_enabled = %d \n", tag, + info->gesture_enabled); + + all_strbuff = (u8 *)kzalloc(size, GFP_KERNEL); + if (all_strbuff != NULL) { + index += snprintf(&all_strbuff[index], 13, "{ %08X }", + info->gesture_enabled); + + count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff); + kfree(all_strbuff); + } else { + logError( + 1, + "%s fts_gesture_mask_show: Unable to allocate all_strbuff! ERROR %08X\n", + tag, ERROR_ALLOC); + } + + return count; +} + +static ssize_t fts_gesture_mask_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char *p = (char *)buf; + int n; + unsigned int temp; + int res; + struct fts_ts_info *info = dev_get_drvdata(dev); + + if ((count + 1) / 3 < 2 || (count + 1) / 3 > GESTURE_MASK_SIZE + 1) { + logError( + 1, + "%s fts_gesture_mask_store: Number of bytes of parameter wrong! %d < or > (enable/disable + at least one gestureID or max %d bytes)\n", + tag, (count + 1) / 3, GESTURE_MASK_SIZE); + mask[0] = 0; + } else { + memset(mask, 0, GESTURE_MASK_SIZE + 2); + mask[0] = ((count + 1) / 3) - 1; + sscanf(p, "%02X ", &temp); + p += 3; + mask[1] = (u8)temp; + for (n = 1; n < (count + 1) / 3; n++) { + sscanf(p, "%02X ", &temp); + p += 3; + fromIDtoMask((u8)temp, &mask[2], GESTURE_MASK_SIZE); + } + + for (n = 0; n < GESTURE_MASK_SIZE + 2; n++) { + logError(1, "%s mask[%d] = %02X \n", tag, n, mask[n]); + } + } + + if (mask[0] == 0) { + res = ERROR_OP_NOT_ALLOW; + logError( + 1, + "%s %s: Call before echo enable/disable xx xx .... > gesture_mask with a correct number of parameters! ERROR %08X \n", + tag, __func__, res); + } else { + if (mask[1] == FEAT_ENABLE || mask[1] == FEAT_DISABLE) + res = updateGestureMask(&mask[2], mask[0], mask[1]); + else + res = ERROR_OP_NOT_ALLOW; + + if (res < OK) { + logError(1, "%s fts_gesture_mask_store: ERROR %08X \n", + tag, res); + } + } + + res = check_feature_feasibility(info, FEAT_SEL_GESTURE); + temp = isAnyGestureActive(); + if (res >= OK || temp == FEAT_DISABLE) { + info->gesture_enabled = temp; + } + res = fts_mode_handler(info, 0); + + return count; +} + +#endif + +/** + * File node to read the coordinates of the last gesture drawn by the user \n + * cat gesture_coordinates to obtain the gesture coordinates \n + * the string returned in the shell follow this up as follow: \n + * { = start byte \n + * X1X2X3X4 = 4 bytes in HEX format which represent an error code (00000000 no error) \n + * \n if error code = 00000000 \n + * CC = 1 byte in HEX format number of coords (pair of x,y) returned \n + * XXiYYi ... = XXi 2 bytes in HEX format for x[i] and YYi 2 bytes in HEX format for y[i] (big endian) \n + * \n + * } = end byte + */ +static ssize_t fts_gesture_coordinates_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int size = (6 * 2) + 1, index = 0; + u8 *all_strbuff = NULL; + int count = 0, res, i = 0; + + logError(0, "%s %s: Getting gestures coordinates... \n", tag, __func__); + + if (gesture_coords_reported < OK) { + logError(1, "%s %s: invalid coordinates! ERROR %08X \n", tag, + __func__, gesture_coords_reported); + res = gesture_coords_reported; + } else { + size += gesture_coords_reported * 2 * 4 + 2; + res = OK; + } + + all_strbuff = (u8 *)kzalloc(size, GFP_KERNEL); + if (all_strbuff != NULL) { + snprintf(&all_strbuff[index], 11, "{ %08X", res); + index += 10; + + if (res >= OK) { + snprintf(&all_strbuff[index], 3, "%02X", + gesture_coords_reported); + index += 2; + + for (i = 0; i < gesture_coords_reported; i++) { + snprintf(&all_strbuff[index], 5, "%04X", + gesture_coordinates_x[i]); + index += 4; + snprintf(&all_strbuff[index], 5, "%04X", + gesture_coordinates_y[i]); + index += 4; + } + } + + index += snprintf(&all_strbuff[index], 3, " }"); + + count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff); + kfree(all_strbuff); + logError(0, "%s %s: Getting gestures coordinates FINISHED! \n", + tag, __func__); + + } else { + logError(1, + "%s %s: Unable to allocate all_strbuff! ERROR %08X\n", + tag, ERROR_ALLOC); + } + + return count; +} +#endif + +/***************************************** PRODUCTION TEST ***************************************************/ + +/** + * File node to execute the Mass Production Test or to get data from the IC (raw or ms/ss init data) + * echo cmd > stm_fts_cmd to execute a command \n + * cat stm_fts_cmd to show the result of the command \n + * echo cmd > stm_fts_cmd; cat stm_fts_cmd to execute and show the result in just one call \n + * the string returned in the shell is made up as follow: \n + * { = start byte \n + * X1X2X3X4 = 4 bytes in HEX format which represent an error_code (00000000 = OK)\n + * (optional) data = data coming from the command executed represented as HEX string \n + * Not all the command return additional data \n + * } = end byte + * \n + * Possible commands (cmd): \n + * - 00 = MP Test -> return erro_code \n + * - 01 = ITO Test -> return error_code \n + * - 03 = MS Raw Test -> return error_code \n + * - 04 = MS Init Data Test -> return error_code \n + * - 05 = SS Raw Test -> return error_code \n + * - 06 = SS Init Data Test -> return error_code \n + * - 13 = Read 1 MS Raw Frame -> return additional data: MS frame row after row \n + * - 14 = Read MS Init Data -> return additional data: MS init data row after row \n + * - 15 = Read 1 SS Raw Frame -> return additional data: SS frame, force channels followed by sense channels \n + * - 16 = Read SS Init Data -> return additional data: SS Init data, first IX for force and sense channels and then CX for force and sense channels \n + * - F0 = Perform a system reset -> return error_code \n + * - F1 = Perform a system reset and reenable the sensing and the interrupt + */ +static ssize_t stm_fts_cmd_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + int n; + char *p = (char *)buf; + + memset(typeOfComand, 0, CMD_STR_LEN * sizeof(u32)); + + logError(1, "%s \n", tag); + for (n = 0; n < (count + 1) / 3; n++) { + sscanf(p, "%02X ", &typeOfComand[n]); + p += 3; + logError(1, "%s typeOfComand[%d] = %02X \n", tag, n, + typeOfComand[n]); + } + + numberParameters = n; + logError(1, "%s Number of Parameters = %d \n", tag, numberParameters); + return count; +} + +static ssize_t stm_fts_cmd_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int res, j, doClean = 0, count = 0, index = 0; + char buff[CMD_STR_LEN] = { 0 }; + + int size = (6 * 2) + 1; + int init_type = SPECIAL_PANEL_INIT; + u8 *all_strbuff = NULL; + const char *limit_file_name = NULL; + struct fts_ts_info *info = dev_get_drvdata(dev); + + MutualSenseData compData; + SelfSenseData comData; + MutualSenseFrame frameMS; + SelfSenseFrame frameSS; + + if (numberParameters >= 1) { + res = fts_disableInterrupt(); + if (res < 0) { + logError(0, "%s fts_disableInterrupt: ERROR %08X \n", + tag, res); + res = (res | ERROR_DISABLE_INTER); + goto END; + } +#ifdef CONFIG_DRM + res = drm_unregister_client(&info->notifier); + if (res < 0) { + logError(1, "%s ERROR: unregister notifier failed!\n", + tag); + goto END; + } +#endif + switch (typeOfComand[0]) { + /*ITO TEST */ + case 0x01: + res = production_test_ito(LIMITS_FILE, &tests); + break; + /*PRODUCTION TEST */ + case 0x00: + + if (systemInfo.u8_cfgAfeVer != systemInfo.u8_cxAfeVer) { + res = ERROR_OP_NOT_ALLOW; + logError( + 0, + "%s Miss match in CX version! MP test not allowed with wrong CX memory! ERROR %08X \n", + tag, res); + break; + } + + limit_file_name = fts_get_limit(info); + res = production_test_main(LIMITS_FILE, 1, init_type, + &tests); + break; + /*read mutual raw */ + case 0x13: + logError(0, "%s Get 1 MS Frame \n", tag); + setScanMode(SCAN_MODE_ACTIVE, 0x01); + mdelay(WAIT_FOR_FRESH_FRAMES); + setScanMode(SCAN_MODE_ACTIVE, 0x00); + mdelay(WAIT_AFTER_SENSEOFF); + flushFIFO(); + res = getMSFrame3(MS_RAW, &frameMS); + if (res < 0) { + logError( + 0, + "%s Error while taking the MS frame... ERROR %08X \n", + tag, res); + + } else { + logError(0, "%s The frame size is %d words\n", + tag, res); + size = (res * (sizeof(short) * 2 + 1)) + 10; + res = OK; + print_frame_short( + "MS frame =", + array1dTo2d_short( + frameMS.node_data, + frameMS.node_data_size, + frameMS.header.sense_node), + frameMS.header.force_node, + frameMS.header.sense_node); + } + break; + /*read self raw */ + case 0x15: + logError(0, "%s Get 1 SS Frame \n", tag); + setScanMode(SCAN_MODE_ACTIVE, 0x01); + mdelay(WAIT_FOR_FRESH_FRAMES); + setScanMode(SCAN_MODE_ACTIVE, 0x00); + mdelay(WAIT_AFTER_SENSEOFF); + flushFIFO(); + res = getSSFrame3(SS_RAW, &frameSS); + + if (res < OK) { + logError( + 0, + "%s Error while taking the SS frame... ERROR %08X \n", + tag, res); + + } else { + logError(0, "%s The frame size is %d words\n", + tag, res); + size = (res * (sizeof(short) * 2 + 1)) + 10; + res = OK; + print_frame_short( + "SS force frame =", + array1dTo2d_short( + frameSS.force_data, + frameSS.header.force_node, 1), + frameSS.header.force_node, 1); + print_frame_short( + "SS sense frame =", + array1dTo2d_short( + frameSS.sense_data, + frameSS.header.sense_node, + frameSS.header.sense_node), + 1, frameSS.header.sense_node); + } + + break; + + case 0x14: + logError(0, "%s Get MS Compensation Data \n", tag); + res = readMutualSenseCompensationData(LOAD_CX_MS_TOUCH, + &compData); + + if (res < 0) { + logError( + 0, + "%s Error reading MS compensation data ERROR %08X \n", + tag, res); + } else { + logError( + 0, + "%s MS Compensation Data Reading Finished! \n", + tag); + size = (compData.node_data_size * sizeof(u8)) * + 3 + + 1; + print_frame_i8( + "MS Data (Cx2) =", + array1dTo2d_i8( + compData.node_data, + compData.node_data_size, + compData.header.sense_node), + compData.header.force_node, + compData.header.sense_node); + } + break; + + case 0x16: + logError(0, "%s Get SS Compensation Data... \n", tag); + res = readSelfSenseCompensationData(LOAD_CX_SS_TOUCH, + &comData); + if (res < 0) { + logError( + 0, + "%s Error reading SS compensation data ERROR %08X\n", + tag, res); + } else { + logError( + 0, + "%s SS Compensation Data Reading Finished! \n", + tag); + size = ((comData.header.force_node + + comData.header.sense_node) * + 2 + + 12) * sizeof(u8) * + 2 + + 1; + print_frame_u8( + "SS Data Ix2_fm = ", + array1dTo2d_u8( + comData.ix2_fm, + comData.header.force_node, 1), + comData.header.force_node, 1); + print_frame_i8( + "SS Data Cx2_fm = ", + array1dTo2d_i8( + comData.cx2_fm, + comData.header.force_node, 1), + comData.header.force_node, 1); + print_frame_u8( + "SS Data Ix2_sn = ", + array1dTo2d_u8( + comData.ix2_sn, + comData.header.sense_node, + comData.header.sense_node), + 1, comData.header.sense_node); + print_frame_i8( + "SS Data Cx2_sn = ", + array1dTo2d_i8( + comData.cx2_sn, + comData.header.sense_node, + comData.header.sense_node), + 1, comData.header.sense_node); + } + break; + + case 0x03: + res = fts_system_reset(); + if (res >= OK) + res = production_test_ms_raw(LIMITS_FILE, 1, + &tests); + break; + + case 0x04: + res = fts_system_reset(); + if (res >= OK) + res = production_test_ms_cx(LIMITS_FILE, 1, + &tests); + break; + + case 0x05: + res = fts_system_reset(); + if (res >= OK) + res = production_test_ss_raw(LIMITS_FILE, 1, + &tests); + break; + + case 0x06: + res = fts_system_reset(); + if (res >= OK) + res = production_test_ss_ix_cx(LIMITS_FILE, 1, + &tests); + break; + + case 0xF0: + case 0xF1: + doClean = (int)(typeOfComand[0] & 0x01); + res = cleanUp(doClean); + break; + + default: + logError( + 1, + "%s COMMAND NOT VALID!! Insert a proper value ...\n", + tag); + res = ERROR_OP_NOT_ALLOW; + break; + } + + doClean = fts_mode_handler(info, 1); + if (typeOfComand[0] != 0xF0) + doClean |= fts_enableInterrupt(); + if (doClean < 0) { + logError(0, "%s %s: ERROR %08X \n", tag, __func__, + (doClean | ERROR_ENABLE_INTER)); + } + } else { + logError( + 1, + "%s NO COMMAND SPECIFIED!!! do: 'echo [cmd_code] [args] > stm_fts_cmd' before looking for result!\n", + tag); + res = ERROR_OP_NOT_ALLOW; + } +#ifdef CONFIG_DRM + if (drm_register_client(&info->notifier) < 0) { + logError(1, "%s ERROR: register notifier failed!\n", tag); + } +#endif +END: + all_strbuff = (u8 *)kzalloc(size, GFP_KERNEL); + + if (res >= OK) { + /*all the other cases are already fine printing only the res. */ + switch (typeOfComand[0]) { + case 0x13: + snprintf(all_strbuff, size, "ms_frame\n"); + for (j = 0; j < frameMS.node_data_size; j++) { + if ((j + 1) % frameMS.header.sense_node) + snprintf(buff, sizeof(buff), "%04d ", + frameMS.node_data[j]); + else + snprintf(buff, sizeof(buff), "%04d\n", + frameMS.node_data[j]); + + strlcat(all_strbuff, buff, size); + } + + kfree(frameMS.node_data); + frameMS.node_data = NULL; + break; + + case 0x15: + snprintf(all_strbuff, size, "ss_frame\n"); + for (j = 0; j < frameSS.header.force_node - 1; j++) { + snprintf(buff, sizeof(buff), "%04d ", + frameSS.force_data[j]); + strlcat(all_strbuff, buff, size); + } + + if (j == frameSS.header.force_node - 1) { + snprintf(buff, sizeof(buff), "%04d\n", + frameSS.force_data[j]); + strlcat(all_strbuff, buff, size); + } + + for (j = 0; j < frameSS.header.sense_node - 1; j++) { + snprintf(buff, sizeof(buff), "%04d ", + frameSS.sense_data[j]); + strlcat(all_strbuff, buff, size); + } + + if (j == frameSS.header.sense_node - 1) { + snprintf(buff, sizeof(buff), "%04d\n", + frameSS.sense_data[j]); + strlcat(all_strbuff, buff, size); + } + + kfree(frameSS.force_data); + kfree(frameSS.sense_data); + + break; + + case 0x14: + snprintf(buff, sizeof(buff), "%02X", + (u8)compData.header.force_node); + strlcat(all_strbuff, buff, size); + snprintf(buff, sizeof(buff), "%02X", + (u8)compData.header.sense_node); + strlcat(all_strbuff, buff, size); + snprintf(buff, sizeof(buff), "%02X", compData.cx1); + strlcat(all_strbuff, buff, size); + + for (j = 0; j < compData.node_data_size; j++) { + snprintf(buff, sizeof(buff), "%02X", + *(compData.node_data + j)); + strlcat(all_strbuff, buff, size); + } + + kfree(compData.node_data); + compData.node_data = NULL; + + break; + + case 0x16: + snprintf(buff, sizeof(buff), "%02X", + comData.header.force_node); + strlcat(all_strbuff, buff, size); + snprintf(buff, sizeof(buff), "%02X", + comData.header.sense_node); + strlcat(all_strbuff, buff, size); + snprintf(buff, sizeof(buff), "%02X", comData.f_ix1); + strlcat(all_strbuff, buff, size); + snprintf(buff, sizeof(buff), "%02X", comData.s_ix1); + strlcat(all_strbuff, buff, size); + snprintf(buff, sizeof(buff), "%02X", comData.f_cx1); + strlcat(all_strbuff, buff, size); + snprintf(buff, sizeof(buff), "%02X", comData.s_cx1); + strlcat(all_strbuff, buff, size); + + for (j = 0; j < comData.header.force_node; j++) { + snprintf(buff, sizeof(buff), "%02X", + comData.ix2_fm[j]); + strlcat(all_strbuff, buff, size); + } + + for (j = 0; j < comData.header.sense_node; j++) { + snprintf(buff, sizeof(buff), "%02X", + comData.ix2_sn[j]); + strlcat(all_strbuff, buff, size); + } + + for (j = 0; j < comData.header.force_node; j++) { + snprintf(buff, sizeof(buff), "%02X", + comData.cx2_fm[j]); + strlcat(all_strbuff, buff, size); + } + + for (j = 0; j < comData.header.sense_node; j++) { + snprintf(buff, sizeof(buff), "%02X", + comData.cx2_sn[j]); + strlcat(all_strbuff, buff, size); + } + + kfree(comData.ix2_fm); + kfree(comData.ix2_sn); + kfree(comData.cx2_fm); + kfree(comData.cx2_sn); + + break; + + default: + snprintf(&all_strbuff[index], 11, "{ %08X", res); + index += 10; + snprintf(&all_strbuff[index], 3, " }"); + index += 2; + + break; + } + } else { + snprintf(&all_strbuff[index], 11, "{ %08X", res); + index += 10; + snprintf(&all_strbuff[index], 3, " }"); + index += 2; + } + + count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff); + numberParameters = 0; + kfree(all_strbuff); + + return count; +} + +static ssize_t fts_panel_color_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + return snprintf(buf, PAGE_SIZE, "%c\n", info->lockdown_info[2]); +} + +static ssize_t fts_panel_vendor_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + return snprintf(buf, PAGE_SIZE, "%c\n", info->lockdown_info[6]); +} + +static ssize_t fts_panel_display_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + return snprintf(buf, PAGE_SIZE, "%c\n", info->lockdown_info[1]); +} + +static ssize_t fts_lockdown_info_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + int ret; + ret = fts_get_lockdown_info(info->lockdown_info, info); + + if (ret != OK) { + logError(1, "%s get lockdown info error\n", tag); + return 0; + } + + return snprintf( + buf, PAGE_SIZE, + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", + info->lockdown_info[0], info->lockdown_info[1], + info->lockdown_info[2], info->lockdown_info[3], + info->lockdown_info[4], info->lockdown_info[5], + info->lockdown_info[6], info->lockdown_info[7]); +} + +static ssize_t fts_lockdown_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int n, i, ret; + char *p = (char *)buf; + u8 *typecomand = NULL; + + memset(typeOfComand, 0, CMD_STR_LEN * sizeof(u32)); + logError(1, "%s \n", tag); + for (n = 0; n < (count + 1) / 3; n++) { + sscanf(p, "%02X ", &typeOfComand[n]); + p += 3; + logError(1, "%s command_sequence[%d] = %02X\n", tag, n, + typeOfComand[n]); + } + numberParameters = n; + if (numberParameters < 3) + goto END; + logError(1, "%s %d = %d \n", tag, n, numberParameters); + + typecomand = + (u8 *)kmalloc((numberParameters - 2) * sizeof(u8), GFP_KERNEL); + if (typecomand != NULL) { + for (i = 0; i < numberParameters - 2; i++) { + typecomand[i] = (u8)typeOfComand[i + 2]; + logError(1, "%s typecomand[%d] = %X \n", tag, i, + typecomand[i]); + } + } else { + goto END; + } + + ret = writeLockDownInfo(typecomand, numberParameters - 2, + typeOfComand[0]); + if (ret < 0) { + logError(1, "%s fts_lockdown_store failed\n", tag); + } + kfree(typecomand); +END: + logError(1, "%s Number of Parameters = %d \n", tag, numberParameters); + + return count; +} + +static ssize_t fts_lockdown_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int i, ret; + int size = 0, count = 0; + u8 type; + u8 *temp_buffer = NULL; + + temp_buffer = (u8 *)kmalloc(LOCKDOWN_LENGTH * sizeof(u8), GFP_KERNEL); + if (temp_buffer == NULL || numberParameters < 2) { + count += snprintf(&buf[count], PAGE_SIZE, + "prepare read lockdown failded\n"); + return count; + } + type = typeOfComand[0]; + size = (int)(typeOfComand[1]); + count += snprintf(&buf[count], PAGE_SIZE, "read lock down code:\n"); + ret = readLockDownInfo(temp_buffer, type, size); + if (ret < OK) { + count += snprintf(&buf[count], PAGE_SIZE, + "read lockdown failded\n"); + goto END; + } + for (i = 0; i < size; i++) { + count += snprintf(&buf[count], PAGE_SIZE, "%02X ", + temp_buffer[i]); + } + count += snprintf(&buf[count], PAGE_SIZE, "\n"); + +END: + numberParameters = 0; + kfree(temp_buffer); + return count; +} + +static ssize_t fts_selftest_info_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int res = 0, i = 0, count = 0, force_node = 0, sense_node = 0, pos = 0, + last_pos = 0; + MutualSenseFrame frameMS; + char buff[80]; + struct i2c_client *client = to_i2c_client(dev); + struct fts_ts_info *info = i2c_get_clientdata(client); + + res = fts_disableInterrupt(); + if (res < OK) + goto END; + + setScanMode(SCAN_MODE_ACTIVE, 0x01); + mdelay(WAIT_FOR_FRESH_FRAMES); + setScanMode(SCAN_MODE_ACTIVE, 0x00); + mdelay(WAIT_AFTER_SENSEOFF); + flushFIFO(); + res = getMSFrame3(MS_RAW, &frameMS); + if (res < 0) { + logError(0, + "%s Error while taking the MS frame... ERROR %08X \n", + tag, res); + goto END; + } + fts_mode_handler(info, 1); + + sense_node = frameMS.header.sense_node; + force_node = frameMS.header.force_node; + + for (i = 0; i < RELEASE_INFO_SIZE; i++) { + if (i == 0) { + pos += snprintf(buff + last_pos, PAGE_SIZE, "0x%02x", + systemInfo.u8_releaseInfo[i]); + last_pos = pos; + } else { + pos += snprintf(buff + last_pos, PAGE_SIZE, "%02x", + systemInfo.u8_releaseInfo[i]); + last_pos = pos; + } + } + count = snprintf( + buf, PAGE_SIZE, + "Device address:,0x49\nChip Id:,0x%04x\nFw version:,0x%04x\nConfig version:,0x%04x\nChip serial number:,%s\nForce lines count:,%02d\nSense lines count:,%02d\n\n", + systemInfo.u16_chip0Id, systemInfo.u16_fwVer, + systemInfo.u16_cfgVer, buff, force_node, sense_node); +END: + fts_enableInterrupt(); + return count; +} + +static ssize_t fts_ms_raw_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int res = 0, count = 0, j = 0, sense_node = 0, force_node = 0, pos = 0, + last_pos = 0; + char *all_strbuff = NULL; + struct i2c_client *client = to_i2c_client(dev); + struct fts_ts_info *info = i2c_get_clientdata(client); + MutualSenseFrame frameMS; + + res = fts_disableInterrupt(); + if (res < OK) + goto END; + all_strbuff = vmalloc(PAGE_SIZE); + if (!all_strbuff) { + logError(1, "%s %s alloc all_strbuff fail\n", tag, __func__); + goto END; + } else + memset(all_strbuff, 0, PAGE_SIZE); + + setScanMode(SCAN_MODE_ACTIVE, 0x01); + mdelay(WAIT_FOR_FRESH_FRAMES); + setScanMode(SCAN_MODE_ACTIVE, 0x00); + mdelay(WAIT_AFTER_SENSEOFF); + flushFIFO(); + res = getMSFrame3(MS_RAW, &frameMS); + + fts_mode_handler(info, 1); + sense_node = frameMS.header.sense_node; + force_node = frameMS.header.force_node; + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "MsTouchRaw,%2d,%2d\n ,", force_node, sense_node); + last_pos = pos; + if (res >= OK) { + for (j = 0; j < sense_node; j++) + if ((j + 1) % sense_node) { + pos += snprintf(all_strbuff + last_pos, + PAGE_SIZE, "C%02d,", j); + last_pos = pos; + } else { + pos += snprintf(all_strbuff + last_pos, + PAGE_SIZE, "C%02d\nR00,", j); + last_pos = pos; + } + for (j = 0; j < sense_node * force_node; j++) { + if ((j + 1) % sense_node) { + pos += snprintf(all_strbuff + last_pos, + PAGE_SIZE, "%4d,", + frameMS.node_data[j]); + last_pos = pos; + } else { + if ((j + 1) / sense_node != force_node) + pos += snprintf(all_strbuff + last_pos, + PAGE_SIZE, + "%4d\nR%02d,", + frameMS.node_data[j], + (j + 1) / sense_node); + else + pos += snprintf(all_strbuff + last_pos, + PAGE_SIZE, "%4d\n", + frameMS.node_data[j]); + last_pos = pos; + } + } + if (frameMS.node_data) { + kfree(frameMS.node_data); + frameMS.node_data = NULL; + } + } + + count = snprintf(buf, PAGE_SIZE, "%s\n", all_strbuff); + vfree(all_strbuff); +END: + fts_enableInterrupt(); + return count; +} + +static ssize_t fts_ms_cx_total_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int res = 0, pos = 0, last_pos = 0, count = 0, j = 0, sense_node = 0, + force_node = 0; + char *all_strbuff = NULL; + TotMutualSenseData totCompData; + + res = fts_disableInterrupt(); + if (res < OK) + goto END; + all_strbuff = vmalloc(PAGE_SIZE); + if (!all_strbuff) { + logError(1, "%s %s alloc all_strbuff fail\n", tag, __func__); + goto END; + } else + memset(all_strbuff, 0, PAGE_SIZE); + + res = readTotMutualSenseCompensationData(LOAD_PANEL_CX_TOT_MS_TOUCH, + &totCompData); + if (res >= OK) { + sense_node = totCompData.header.sense_node; + force_node = totCompData.header.force_node; + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "MsTouchTotalCx,%2d,%2d\n ,", force_node, + sense_node); + last_pos = pos; + for (j = 0; j < sense_node; j++) + if ((j + 1) % sense_node) { + pos += snprintf(all_strbuff + last_pos, + PAGE_SIZE, "C%02d,", j); + last_pos = pos; + } else { + pos += snprintf(all_strbuff + last_pos, + PAGE_SIZE, "C%02d\nR00,", j); + last_pos = pos; + } + for (j = 0; j < sense_node * force_node; j++) { + if ((j + 1) % sense_node) { + pos += snprintf(all_strbuff + last_pos, + PAGE_SIZE, "%4d,", + totCompData.node_data[j]); + last_pos = pos; + } else { + if ((j + 1) / sense_node != force_node) + pos += snprintf( + all_strbuff + last_pos, + PAGE_SIZE, "%4d\nR%02d,", + totCompData.node_data[j], + (j + 1) / sense_node); + else + pos += snprintf( + all_strbuff + last_pos, + PAGE_SIZE, "%4d\n", + totCompData.node_data[j]); + last_pos = pos; + } + } + if (totCompData.node_data) { + kfree(totCompData.node_data); + totCompData.node_data = NULL; + } + } + + count = snprintf(buf, PAGE_SIZE, "%s\n", all_strbuff); + vfree(all_strbuff); +END: + fts_enableInterrupt(); + return count; +} + +static ssize_t fts_ss_ix_total_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0, pos = 0, last_pos = 0, count = 0, j = 0, sense_node = 0, + force_node = 0; + char *all_strbuff = NULL; + TotSelfSenseData totCompData; + + ret = fts_disableInterrupt(); + if (ret < OK) + goto END; + all_strbuff = vmalloc(PAGE_SIZE); + if (!all_strbuff) { + logError(1, "%s %s alloc all_strbuff fail\n", tag, __func__); + goto END; + } else { + memset(all_strbuff, 0, PAGE_SIZE); + } + ret = readTotSelfSenseCompensationData(LOAD_PANEL_CX_TOT_SS_TOUCH, + &totCompData); + if (ret < 0) { + logError( + 1, + "%s production_test_data: readTotSelfSenseCompensationData failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + goto END; + } + + sense_node = 1; + force_node = totCompData.header.force_node; + + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SsTouchForceTotalIx,%2d,1\n ,C00\n", force_node); + last_pos = pos; + for (j = 0; j < force_node; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "R%02d,%4d\n", j, totCompData.ix_fm[j]); + last_pos = pos; + } + + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SsTouchForceTotalCx,%2d,1\n ,C00\n", force_node); + last_pos = pos; + for (j = 0; j < force_node; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "R%02d,%4d\n", j, totCompData.cx_fm[j]); + last_pos = pos; + } + + sense_node = totCompData.header.sense_node; + force_node = 1; + + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SsTouchsenseTotalIx,%2d,1\n ,C00\n", sense_node); + last_pos = pos; + for (j = 0; j < sense_node; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "R%02d,%4d\n", j, totCompData.ix_sn[j]); + last_pos = pos; + } + + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SsTouchsenseTotalCx,%2d,1\n ,C00\n", sense_node); + last_pos = pos; + for (j = 0; j < sense_node; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "R%02d,%4d\n", j, totCompData.cx_sn[j]); + last_pos = pos; + } + + if (totCompData.ix_fm != NULL) { + kfree(totCompData.ix_fm); + totCompData.ix_fm = NULL; + } + + if (totCompData.cx_fm != NULL) { + kfree(totCompData.cx_fm); + totCompData.cx_fm = NULL; + } + + if (totCompData.ix_sn != NULL) { + kfree(totCompData.ix_sn); + totCompData.ix_sn = NULL; + } + + if (totCompData.cx_sn != NULL) { + kfree(totCompData.cx_sn); + totCompData.cx_sn = NULL; + } + + count = snprintf(buf, PAGE_SIZE, "%s\n", all_strbuff); + vfree(all_strbuff); +END: + fts_enableInterrupt(); + return count; +} + +static ssize_t fts_ss_raw_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int res = 0, count = 0, j = 0, sense_node = 0, force_node = 0, pos = 0, + last_pos = 0; + char *all_strbuff = NULL; + struct i2c_client *client = to_i2c_client(dev); + struct fts_ts_info *info = i2c_get_clientdata(client); + SelfSenseFrame frameSS; + + res = fts_disableInterrupt(); + if (res < OK) + goto END; + all_strbuff = vmalloc(PAGE_SIZE * 4); + if (!all_strbuff) { + logError(1, "%s %s alloc all_strbuff fail\n", tag, __func__); + goto END; + } else + memset(all_strbuff, 0, PAGE_SIZE); + setScanMode(SCAN_MODE_ACTIVE, 0x01); + mdelay(WAIT_FOR_FRESH_FRAMES); + setScanMode(SCAN_MODE_ACTIVE, 0x00); + mdelay(WAIT_AFTER_SENSEOFF); + flushFIFO(); + res = getSSFrame3(SS_RAW, &frameSS); + + fts_mode_handler(info, 1); + sense_node = frameSS.header.sense_node; + force_node = frameSS.header.force_node; + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SsTouchRaw,%2d,%2d\n", force_node, sense_node); + last_pos = pos; + if (res >= OK) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SS force frame\n ,"); + last_pos = pos; + + for (j = 0; j < frameSS.header.force_node - 1; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d,", frameSS.force_data[j]); + last_pos = pos; + } + + if (j == frameSS.header.force_node - 1) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d\n", frameSS.force_data[j]); + last_pos = pos; + } + + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SS sense frame\n ,"); + last_pos = pos; + + for (j = 0; j < frameSS.header.sense_node - 1; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d,", frameSS.sense_data[j]); + last_pos = pos; + } + + if (j == frameSS.header.sense_node - 1) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d\n", frameSS.sense_data[j]); + last_pos = pos; + } + + if (frameSS.force_data) { + kfree(frameSS.force_data); + frameSS.force_data = NULL; + } + if (frameSS.sense_data) { + kfree(frameSS.sense_data); + frameSS.sense_data = NULL; + } + } + + count = snprintf(buf, PAGE_SIZE, "%s\n", all_strbuff); + vfree(all_strbuff); +END: + fts_enableInterrupt(); + return count; +} + +static ssize_t fts_strength_frame_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + MutualSenseFrame frame; + int res = 0, count = 0, j = 0, size = 0; + char *all_strbuff = NULL; + char buff[CMD_STR_LEN] = { 0 }; + struct i2c_client *client = to_i2c_client(dev); + struct fts_ts_info *info = i2c_get_clientdata(client); + frame.node_data = NULL; + + res = fts_disableInterrupt(); + if (res < OK) + goto END; + + res = getMSFrame3(MS_STRENGTH, &frame); + + if (res < OK) { + logError(1, "%s %s: could not get the frame! ERROR %08X \n", + tag, __func__, res); + goto END; + } + size = (res * 5) + 11; + + /* + flushFIFO(); + */ + fts_mode_handler(info, 1); + all_strbuff = (char *)kmalloc(PAGE_SIZE * sizeof(char), GFP_KERNEL); + + if (all_strbuff != NULL) { + memset(all_strbuff, 0, size); + snprintf(all_strbuff, size, "ms_differ\n"); + if (res >= OK) { + for (j = 0; j < frame.node_data_size; j++) { + if ((j + 1) % frame.header.sense_node) + snprintf(buff, sizeof(buff), "%4d,", + frame.node_data[j]); + else + snprintf(buff, sizeof(buff), "%4d\n", + frame.node_data[j]); + + strlcat(all_strbuff, buff, size); + } + + kfree(frame.node_data); + frame.node_data = NULL; + } + + count = snprintf(buf, PAGE_SIZE, "%s\n", all_strbuff); + kfree(all_strbuff); + } else { + logError(1, + "%s %s: Unable to allocate all_strbuff! ERROR %08X\n", + tag, __func__, ERROR_ALLOC); + } + +END: + fts_enableInterrupt(); + + return count; +} + +int fts_hover_auto_tune(struct fts_ts_info *info) +{ + int res = OK; + u8 sett[2]; + logError(0, "%s start...\n", tag, __func__); + + fts_disableInterrupt(); + + sett[0] = 0x02; + sett[1] = 0x00; + res = writeSysCmd(SYS_CMD_SPECIAL_TUNING, sett, 2); + if (res < OK) { + logError( + 1, + "%s fts_hover_autotune Ioffset tuning 02 00 failed ERROR %08X\n", + tag, (res | ERROR_PROD_TEST_INITIALIZATION)); + return res | ERROR_PROD_TEST_INITIALIZATION; + } + sett[0] = 0x00; + sett[1] = 0x01; + res = writeSysCmd(SYS_CMD_CX_TUNING, sett, 2); + if (res < OK) { + logError( + 1, + "%s fts_hover_autotune autotune hover 00 01 failed ERROR %08X\n", + tag, (res | ERROR_PROD_TEST_INITIALIZATION)); + return res | ERROR_PROD_TEST_INITIALIZATION; + } + sett[0] = 0x06; + res = writeSysCmd(SYS_CMD_SAVE_FLASH, sett, 1); + if (res < OK) { + logError( + 1, + "%s fts_hover_autotune save flash 06 failed ERROR %08X\n", + tag, (res | ERROR_PROD_TEST_INITIALIZATION)); + return res | ERROR_PROD_TEST_INITIALIZATION; + } + logError(0, "%s end...\n", tag, __func__); + + fts_enableInterrupt(); + + return res; +} + +static ssize_t fts_hover_autotune_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + int on; + int ret = 0; + + sscanf(buf, "%u", &on); + logError(1, " %s %s\n", tag, __func__); + if (on) + ret = fts_hover_auto_tune(info); + if (ret < OK) + return -1; + + return count; +} + +static ssize_t fts_hover_raw_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int res = 0, count = 0, j = 0, sense_node = 0, force_node = 0, pos = 0, + last_pos = 0; + char *all_strbuff = NULL; + struct i2c_client *client = to_i2c_client(dev); + struct fts_ts_info *info = i2c_get_clientdata(client); + SelfSenseFrame frameSS; + TotSelfSenseData ssHoverCompData; + u8 hover_cnt[4] = { 0xa8, 0x0b, 0x01, 0x00 }; + + res = fts_disableInterrupt(); + if (res < OK) + goto END; + all_strbuff = vmalloc(PAGE_SIZE * 4); + if (!all_strbuff) { + logError(1, "%s %s alloc all_strbuff fail\n", tag, __func__); + goto END; + } else { + memset(all_strbuff, 0, PAGE_SIZE); + } + res = fts_write_dma_safe(hover_cnt, sizeof(hover_cnt)); + if (res != OK) { + logError(1, "%s hover clear count ERROR = %d\n", tag, res); + goto END; + } + + setScanMode(SCAN_MODE_ACTIVE, 0xFF); + + res = getSSFrame3(SS_HVR_RAW, &frameSS); + + sense_node = frameSS.header.sense_node; + force_node = frameSS.header.force_node; + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SsHoverTouchRaw,%2d,%2d\n", force_node, sense_node); + last_pos = pos; + + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, "TxRaw\n"); + last_pos = pos; + + if (res >= OK) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SS Hover force frame\n ,"); + last_pos = pos; + + for (j = 0; j < frameSS.header.force_node - 1; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d,", frameSS.force_data[j]); + last_pos = pos; + } + + if (j == frameSS.header.force_node - 1) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d\n", frameSS.force_data[j]); + last_pos = pos; + } + + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SS Hover sense frame\n ,"); + last_pos = pos; + + for (j = 0; j < frameSS.header.sense_node - 1; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d,", frameSS.sense_data[j]); + last_pos = pos; + } + + if (j == frameSS.header.sense_node - 1) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d\n", frameSS.sense_data[j]); + last_pos = pos; + } + + if (frameSS.force_data) { + kfree(frameSS.force_data); + frameSS.force_data = NULL; + } + if (frameSS.sense_data) { + kfree(frameSS.sense_data); + frameSS.sense_data = NULL; + } + } + + res = getSSFrame3(SS_HVR_FILTER, &frameSS); + + sense_node = frameSS.header.sense_node; + force_node = frameSS.header.force_node; + + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, "TxFilter\n"); + last_pos = pos; + + if (res >= OK) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SS Hover force frame\n ,"); + last_pos = pos; + + for (j = 0; j < frameSS.header.force_node - 1; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d,", frameSS.force_data[j]); + last_pos = pos; + } + + if (j == frameSS.header.force_node - 1) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d\n", frameSS.force_data[j]); + last_pos = pos; + } + + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SS Hover sense frame\n ,"); + last_pos = pos; + + for (j = 0; j < frameSS.header.sense_node - 1; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d,", frameSS.sense_data[j]); + last_pos = pos; + } + + if (j == frameSS.header.sense_node - 1) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d\n", frameSS.sense_data[j]); + last_pos = pos; + } + + if (frameSS.force_data) { + kfree(frameSS.force_data); + frameSS.force_data = NULL; + } + if (frameSS.sense_data) { + kfree(frameSS.sense_data); + frameSS.sense_data = NULL; + } + } + + res = getSSFrame3(SS_HVR_BASELINE, &frameSS); + + sense_node = frameSS.header.sense_node; + force_node = frameSS.header.force_node; + + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, "TxBaseline\n"); + last_pos = pos; + + if (res >= OK) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SS Hover force frame\n ,"); + last_pos = pos; + + for (j = 0; j < frameSS.header.force_node - 1; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d,", frameSS.force_data[j]); + last_pos = pos; + } + + if (j == frameSS.header.force_node - 1) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d\n", frameSS.force_data[j]); + last_pos = pos; + } + + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SS Hover sense frame\n ,"); + last_pos = pos; + + for (j = 0; j < frameSS.header.sense_node - 1; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d,", frameSS.sense_data[j]); + last_pos = pos; + } + + if (j == frameSS.header.sense_node - 1) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "%04d\n", frameSS.sense_data[j]); + last_pos = pos; + } + + if (frameSS.force_data) { + kfree(frameSS.force_data); + frameSS.force_data = NULL; + } + + if (frameSS.sense_data) { + kfree(frameSS.sense_data); + frameSS.sense_data = NULL; + } + } + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SS Hover IX Data\n ,"); + last_pos = pos; + + res = readTotSelfSenseCompensationData( + STAPI_HOST_DATA_ID_PANEL_CX_SS_HVR, &ssHoverCompData); + + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "SS Hover IX force frame\n ,"); + last_pos = pos; + for (j = 0; j < ssHoverCompData.header.force_node - 1; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, "%04d,", + ssHoverCompData.ix_fm[j]); + last_pos = pos; + } + + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, + "\nSS Hover IX sense frame\n ,"); + last_pos = pos; + + for (j = 0; j < ssHoverCompData.header.sense_node - 1; j++) { + pos += snprintf(all_strbuff + last_pos, PAGE_SIZE, "%04d,", + ssHoverCompData.ix_sn[j]); + last_pos = pos; + } + + if (ssHoverCompData.ix_fm != NULL) + kfree(ssHoverCompData.ix_fm); + if (ssHoverCompData.ix_sn != NULL) + kfree(ssHoverCompData.ix_sn); + if (ssHoverCompData.cx_fm != NULL) + kfree(ssHoverCompData.cx_fm); + if (ssHoverCompData.cx_sn != NULL) + kfree(ssHoverCompData.cx_sn); + + count = snprintf(buf, PAGE_SIZE, "%s\n", all_strbuff); + vfree(all_strbuff); +END: + fts_mode_handler(info, 1); + fts_enableInterrupt(); + return count; +} + +#ifdef CONFIG_FTS_TOUCH_COUNT_DUMP +static ssize_t fts_touch_suspend_notify_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", fts_info->sensor_sleep); +} +#endif + +static ssize_t fts_doze_time_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + + return snprintf(buf, TSP_BUF_SIZE, "%u\n", info->doze_time); +} + +static ssize_t fts_doze_time_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + u8 cmd[4] = { FTS_CMD_CUSTOM, 0x00, 0x00, 0x00 }; + int ret = 0; + u16 reg_val = 0; + struct fts_ts_info *info = dev_get_drvdata(dev); + + pr_info("%s,buf:%s,count:%zu\n", __func__, buf, count); + sscanf(buf, "%u", &info->doze_time); + /*reg value * 10 represents of the num of frames ,one frame is about 8ms, the input value is ms*/ + reg_val = (info->doze_time / 8 - 1) / 10; + cmd[3] = reg_val; + ret = fts_write_dma_safe(cmd, ARRAY_SIZE(cmd)); + if (ret < OK) { + logError(1, "%s %s: write failed...ERROR %08X !\n", tag, + __func__, ret); + return -EPERM; + } + return count; +} + +static ssize_t fts_grip_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + + return snprintf(buf, TSP_BUF_SIZE, "%d\n", info->grip_enabled); +} + +static ssize_t fts_grip_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + u8 cmd[3] = { FTS_CMD_FEATURE, 0x04, 0x01 }; + int ret = 0; + struct fts_ts_info *info = dev_get_drvdata(dev); + + pr_info("%s,buf:%s,count:%zu\n", __func__, buf, count); + sscanf(buf, "%u", &info->grip_enabled); + cmd[2] = info->grip_enabled; + ret = fts_write_dma_safe(cmd, ARRAY_SIZE(cmd)); + if (ret < OK) { + logError(1, "%s %s: write failed...ERROR %08X !\n", tag, + __func__, ret); + return -EPERM; + } + return count; +} + +static ssize_t fts_grip_area_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + + return snprintf(buf, TSP_BUF_SIZE, "%d\n", info->grip_pixel); +} + +static ssize_t fts_grip_area_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + u8 cmd[4] = { FTS_CMD_CUSTOM, 0x01, 0x01, 0x00 }; + int ret = 0; + struct fts_ts_info *info = dev_get_drvdata(dev); + + logError(1, " %s %s,buf:%s,count:%zu\n", tag, __func__, buf, count); + sscanf(buf, "%u", &info->grip_pixel); + cmd[3] = info->grip_pixel; + if (atomic_read(&info->system_is_resetting)) { + logError(1, "%s %s system is resetting ,wait reset done\n", tag, + __func__); + ret = wait_for_completion_timeout(&info->tp_reset_completion, + msecs_to_jiffies(40)); + if (!ret) { + logError( + 1, + "%s %s wait tp reset timeout, wrtie grip area error\n", + tag, __func__); + return count; + } + } + ret = fts_write_dma_safe(cmd, ARRAY_SIZE(cmd)); + if (ret < OK) { + logError(1, "%s %s: write failed...ERROR %08X !\n", tag, + __func__, ret); + return -EPERM; + } + return count; +} +#ifdef CONFIG_FTS_FOD_AREA_REPORT +static ssize_t fts_fod_status_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + + return snprintf(buf, TSP_BUF_SIZE, "%d\n", info->fod_status); +} + +static ssize_t fts_fod_status_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + int res = 0; + u8 gesture_cmd[6] = { 0xA2, 0x03, 0x20, 0x00, 0x00, 0x01 }; + u8 single_only_cmd[4] = { 0xC0, 0x02, 0x00, 0x00 }; + u8 single_double_cmd[4] = { 0xC0, 0x02, 0x01, 0x1E }; + + logError(1, " %s %s buf:%c,count:%zu\n", tag, __func__, buf[0], count); + sscanf(buf, "%u", &info->fod_status); + + mutex_lock(&info->fod_mutex); + if (info->fod_status) { + if (info->fod_status_set) { + logError(1, " %s %s fod status has set\n", tag, + __func__); + } else { + res = fts_write_dma_safe(gesture_cmd, + ARRAY_SIZE(gesture_cmd)); + if (res < OK) + logError( + 1, + "%s %s: enter gesture and longpress failed! ERROR %08X recovery in senseOff...\n", + tag, __func__, res); + + if (info->sensor_sleep) { + logError( + 1, + " %s %s set fod cmd in sensor off status\n", + tag, __func__); + res = setScanMode(SCAN_MODE_LOW_POWER, 0); + if (info->gesture_enabled == 1) { + res = fts_write_dma_safe( + single_double_cmd, + ARRAY_SIZE(single_double_cmd)); + if (res < OK) + logError( + 1, + "%s %s: set single and double tap delay time failed! ERROR %08X\n", + tag, __func__, res); + } else { + res = fts_write_dma_safe( + single_only_cmd, + ARRAY_SIZE(single_only_cmd)); + if (res < OK) + logError( + 1, + "%s %s: set single only delay time failed! ERROR %08X\n", + tag, __func__, res); + } + } + fts_enableInterrupt(); + info->fod_status_set = true; + } + } + mutex_unlock(&info->fod_mutex); + logError(1, " %s %s end\n", tag, __func__); + + return count; +} + +static ssize_t fts_fod_test_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int value = 0; + struct fts_ts_info *info = dev_get_drvdata(dev); + + logError(1, " %s %s,buf:%s,count:%zu\n", tag, __func__, buf, count); + sscanf(buf, "%u", &value); + if (value) { + input_report_key(info->input_dev, BTN_INFO, 1); + input_report_key(info->input_dev, KEY_INFO, 1); + info->fod_pressed = true; + input_sync(info->input_dev); + input_mt_slot(info->input_dev, 0); + input_mt_report_slot_state(info->input_dev, MT_TOOL_FINGER, 1); + input_report_key(info->input_dev, BTN_TOUCH, 1); + input_report_key(info->input_dev, BTN_TOOL_FINGER, 1); + input_report_abs(info->input_dev, ABS_MT_TRACKING_ID, 0); + input_report_abs(info->input_dev, ABS_MT_WIDTH_MINOR, 1); + input_report_abs(info->input_dev, ABS_MT_POSITION_X, CENTER_X); + input_report_abs(info->input_dev, ABS_MT_POSITION_Y, CENTER_Y); + input_sync(info->input_dev); + } else { + input_mt_slot(info->input_dev, 0); + input_report_abs(info->input_dev, ABS_MT_WIDTH_MINOR, 0); + input_mt_report_slot_state(info->input_dev, MT_TOOL_FINGER, 0); + input_report_abs(info->input_dev, ABS_MT_TRACKING_ID, -1); + input_report_key(info->input_dev, BTN_INFO, 0); + input_report_key(info->input_dev, KEY_INFO, 0); + input_sync(info->input_dev); + } + return count; +} +#endif +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE +static ssize_t fts_touchgame_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 get_value[7] = { + 0x0, + }; + u8 get_cmd[2] = { 0xc1, 0x05 }; + u8 grip_rcmd[2] = { 0xc1, 0x08 }; + u8 grip_value[7] = { + 0x0, + }; + int ret; + + ret = fts_writeRead_dma_safe(get_cmd, sizeof(get_cmd) / sizeof(u8), + get_value, sizeof(get_value) / sizeof(u8)); + if (ret < OK) { + logError( + 1, + "%s %s: error while reading touchmode data ERROR %08X\n", + tag, __func__, ret); + } + ret = fts_writeRead_dma_safe(grip_rcmd, sizeof(grip_rcmd) / sizeof(u8), + grip_value, + sizeof(grip_value) / sizeof(u8)); + if (ret < OK) { + logError( + 1, + "%s %s: error while reading edge filter data ERROR %08X\n", + tag, __func__, ret); + } + + return snprintf(buf, PAGE_SIZE, + "game mode:%d,%d,%d,%d,%d,%d,%d\n" + "grip mode:0x%x, 0x%x, 0x%x, %d, %d, %d, %d\n", + get_value[0], get_value[1], get_value[2], get_value[3], + get_value[4], get_value[5], get_value[6], grip_value[0], + grip_value[1], grip_value[2], grip_value[3], + grip_value[4], grip_value[5], grip_value[6]); +} +#endif + +#ifdef CONFIG_SECURE_TOUCH +static void fts_secure_touch_notify(struct fts_ts_info *info) +{ + /*might sleep*/ + sysfs_notify(&info->dev->kobj, NULL, "secure_touch"); + logError(1, "%s %s SECURE_NOTIFY:notify secure_touch\n", tag, __func__); +} + +static int fts_secure_stop(struct fts_ts_info *info, bool block) +{ + struct fts_secure_info *scr_info = info->secure_info; + + logError(1, "%s %s SECURE_STOP: block = %d\n", tag, __func__, + (int)block); + if (atomic_read(&scr_info->st_enabled) == 0) { + logError(1, "%s %s secure touch is already disabled\n", tag, + __func__); + return OK; + } + + atomic_set(&scr_info->st_pending_irqs, -1); + fts_secure_touch_notify(info); + if (block) { + if (wait_for_completion_interruptible( + &scr_info->st_powerdown) == -ERESTARTSYS) { + logError( + 1, + "%s %s SECURE_STOP:st_powerdown be interrupted\n", + tag, __func__); + } else { + logError( + 1, + "%s %s SECURE_STOP:st_powerdown be completed\n", + tag, __func__); + } + } + return OK; +} + +static void fts_secure_work(struct fts_secure_info *scr_info) +{ + struct fts_ts_info *info = (struct fts_ts_info *)scr_info->fts_info; + + fts_secure_touch_notify(info); + atomic_set(&scr_info->st_1st_complete, 1); + if (wait_for_completion_interruptible(&scr_info->st_irq_processed) == + -ERESTARTSYS) { + logError( + 1, + "%s %s SECURE_FILTER:st_irq_processed be interrupted\n", + tag, __func__); + } else { + logError(1, + "%s %s SECURE_FILTER:st_irq_processed be completed\n", + tag, __func__); + } + + fts_enableInterrupt(); + logError(1, "%s %s SECURE_FILTER:enable irq\n", tag, __func__); +} + +static void fts_palm_store_delay(struct fts_secure_info *scr_info) +{ + int ret; + struct fts_ts_info *info = scr_info->fts_info; + + logError(1, "%s %s IN", tag, __func__); + ret = fts_palm_sensor_cmd(scr_info->scr_delay.palm_value); + if (!ret) + info->palm_sensor_changed = true; + logError(1, "%s %s OUT", tag, __func__); +} + +static void fts_flush_delay_task(struct fts_secure_info *scr_info) +{ + if (scr_info->scr_delay.palm_pending) { + fts_palm_store_delay(scr_info); + scr_info->scr_delay.palm_pending = false; + } +} + +static int fts_secure_filter_interrupt(struct fts_ts_info *info) +{ + struct fts_secure_info *scr_info = info->secure_info; + + /*inited and enable first*/ + if (!scr_info->secure_inited || + atomic_read(&scr_info->st_enabled) == 0) { + return -EPERM; + } + + fts_disableInterruptNoSync(); + logError(1, "%s %s SECURE_FILTER:disable irq\n", tag, __func__); + /*check and change irq pending state + *change irq pending here, secure_touch_show, secure_touch_enable_store + *completion st_irq_processed at secure_touch_show, secure_touch_enable_stroe + */ + logError(1, "%s %s SECURE_FILTER:st_pending_irqs = %d\n", tag, __func__, + atomic_read(&scr_info->st_pending_irqs)); + if (atomic_cmpxchg(&scr_info->st_pending_irqs, 0, 1) == 0) { + fts_secure_work(scr_info); + logError(1, "%s %s SECURE_FILTER:secure_work return\n", tag, + __func__); + } + + return 0; +} + +static ssize_t fts_secure_touch_enable_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + struct fts_secure_info *scr_info = info->secure_info; + + logError(1, "%s %s SECURE_TOUCH_ENABLE[R]:st_enabled = %d\n", tag, + __func__, atomic_read(&scr_info->st_enabled)); + return scnprintf(buf, PAGE_SIZE, "%d", + atomic_read(&scr_info->st_enabled)); +} + +/* echo 0 > secure_touch_enable to disable secure touch + * echo 1 > secure_touch_enable to enable secure touch + */ +static ssize_t fts_secure_touch_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long value; + struct fts_ts_info *info = dev_get_drvdata(dev); + struct fts_secure_info *scr_info = info->secure_info; + + atomic_set(&scr_info->st_1st_complete, 0); + logError(1, "%s %s SECURE_TOUCH_ENABLE[W]:st_1st_complete=0\n", tag, + __func__); + logError(1, "%s %s SECURE_TOUCH_ENABLE[W]:parse parameter\n", tag, + __func__); + /*check and get cmd*/ + if (count > 2) + return -EINVAL; + ret = kstrtoul(buf, 10, &value); + if (ret != 0) + return ret; + + if (!scr_info->secure_inited) + return -EIO; + + ret = count; + + logError(1, "%s %s SECURE_TOUCH_ENABLE[W]:st_enabled = %d\n", tag, + __func__, value); + switch (value) { + case 0: + if (atomic_read(&scr_info->st_enabled) == 0) { + logError(1, "%s %s secure touch is already disabled\n", + tag, __func__); + return ret; + } + mutex_lock(&scr_info->palm_lock); + atomic_set(&scr_info->st_enabled, 0); + fts_secure_touch_notify(info); + complete(&scr_info->st_irq_processed); + fts_event_handler(info->client->irq, info); + complete(&scr_info->st_powerdown); + fts_flush_delay_task(scr_info); + mutex_unlock(&scr_info->palm_lock); + logError( + 1, + "%s %s SECURE_TOUCH_ENABLE[W]:disable secure touch successful\n", + tag, __func__); + break; + case 1: + if (atomic_read(&scr_info->st_enabled) == 1) { + logError(1, "%s %s secure touch is already enabled\n", + tag, __func__); + return ret; + } + mutex_lock(&scr_info->palm_lock); + /*wait until finish process all normal irq*/ + synchronize_irq(info->client->irq); + + /*enable secure touch*/ + reinit_completion(&scr_info->st_powerdown); + reinit_completion(&scr_info->st_irq_processed); + atomic_set(&scr_info->st_pending_irqs, 0); + atomic_set(&scr_info->st_enabled, 1); + mutex_unlock(&scr_info->palm_lock); + logError( + 1, + "%s %s SECURE_TOUCH_ENABLE[W]:enable secure touch successful\n", + tag, __func__); + break; + default: + logError(1, "%s %s %d in secure_touch_enable is not support\n", + tag, __func__, value); + break; + } + return ret; +} + +static ssize_t fts_secure_touch_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + struct fts_secure_info *scr_info = info->secure_info; + int value = 0; + + logError(1, "%s %s SECURE_TOUCH[R]:st_1st_complete = %d\n", tag, + __func__, atomic_read(&scr_info->st_1st_complete)); + logError(1, "%s %s SECURE_TOUCH[R]:st_pending_irqs = %d\n", tag, + __func__, atomic_read(&scr_info->st_pending_irqs)); + + if (atomic_read(&scr_info->st_enabled) == 0) { + return -EBADF; + } + + if (atomic_cmpxchg(&scr_info->st_pending_irqs, -1, 0) == -1) + return -EINVAL; + + if (atomic_cmpxchg(&scr_info->st_pending_irqs, 1, 0) == 1) { + value = 1; + } else if (atomic_cmpxchg(&scr_info->st_1st_complete, 1, 0) == 1) { + complete(&scr_info->st_irq_processed); + logError(1, + "%s %s SECURE_TOUCH[R]:comlpetion st_irq_processed\n", + tag, __func__); + } + return scnprintf(buf, PAGE_SIZE, "%d", value); +} +#endif +static DEVICE_ATTR(fts_lockdown, (S_IRUGO | S_IWUSR | S_IWGRP), + fts_lockdown_show, fts_lockdown_store); +static DEVICE_ATTR(fwupdate, (S_IRUGO | S_IWUSR | S_IWGRP), fts_fwupdate_show, + fts_fwupdate_store); +static DEVICE_ATTR(panel_vendor, (S_IRUGO), fts_panel_vendor_show, NULL); +static DEVICE_ATTR(panel_color, (S_IRUGO), fts_panel_color_show, NULL); +static DEVICE_ATTR(panel_display, (S_IRUGO), fts_panel_display_show, NULL); +static DEVICE_ATTR(ms_strength, (S_IRUGO), fts_strength_frame_show, NULL); +static DEVICE_ATTR(lockdown_info, (S_IRUGO), fts_lockdown_info_show, NULL); +static DEVICE_ATTR(appid, (S_IRUGO), fts_appid_show, NULL); +static DEVICE_ATTR(mode_active, (S_IRUGO), fts_mode_active_show, NULL); +static DEVICE_ATTR(fw_file_test, (S_IRUGO), fts_fw_test_show, NULL); +static DEVICE_ATTR(selftest_info, (S_IRUGO), fts_selftest_info_show, NULL); +static DEVICE_ATTR(ms_raw, (S_IRUGO), fts_ms_raw_show, NULL); +static DEVICE_ATTR(ss_raw, (S_IRUGO), fts_ss_raw_show, NULL); +static DEVICE_ATTR(ms_cx_total, (S_IRUGO), fts_ms_cx_total_show, NULL); +static DEVICE_ATTR(ss_ix_total, (S_IRUGO), fts_ss_ix_total_show, NULL); +static DEVICE_ATTR(ss_hover, (S_IRUGO), fts_hover_raw_show, NULL); +static DEVICE_ATTR(stm_fts_cmd, (S_IRUGO | S_IWUSR | S_IWGRP), stm_fts_cmd_show, + stm_fts_cmd_store); +#ifdef USE_ONE_FILE_NODE +static DEVICE_ATTR(feature_enable, (S_IRUGO | S_IWUSR | S_IWGRP), + fts_feature_enable_show, fts_feature_enable_store); +#else + +#ifdef GRIP_MODE +static DEVICE_ATTR(grip_mode, (S_IRUGO | S_IWUSR | S_IWGRP), fts_grip_mode_show, + fts_grip_mode_store); +#endif + +#ifdef CHARGER_MODE +static DEVICE_ATTR(charger_mode, (S_IRUGO | S_IWUSR | S_IWGRP), + fts_charger_mode_show, fts_charger_mode_store); +#endif + +#ifdef GLOVE_MODE +static DEVICE_ATTR(glove_mode, (S_IRUGO | S_IWUSR | S_IWGRP), + fts_glove_mode_show, fts_glove_mode_store); +#endif + +#ifdef COVER_MODE +static DEVICE_ATTR(cover_mode, (S_IRUGO | S_IWUSR | S_IWGRP), + fts_cover_mode_show, fts_cover_mode_store); +#endif + +#ifdef STYLUS_MODE +static DEVICE_ATTR(stylus_mode, (S_IRUGO | S_IWUSR | S_IWGRP), + fts_stylus_mode_show, fts_stylus_mode_store); +#endif + +#endif + +#ifdef GESTURE_MODE +static DEVICE_ATTR(gesture_mask, (S_IRUGO | S_IWUSR | S_IWGRP), + fts_gesture_mask_show, fts_gesture_mask_store); +static DEVICE_ATTR(gesture_coordinates, (S_IRUGO | S_IWUSR | S_IWGRP), + fts_gesture_coordinates_show, NULL); +#endif +static DEVICE_ATTR(doze_time, (S_IRUGO | S_IWUSR | S_IWGRP), fts_doze_time_show, + fts_doze_time_store); +static DEVICE_ATTR(grip_enable, (S_IRUGO | S_IWUSR | S_IWGRP), + fts_grip_enable_show, fts_grip_enable_store); +static DEVICE_ATTR(grip_area, (S_IRUGO | S_IWUSR | S_IWGRP), fts_grip_area_show, + fts_grip_area_store); + +static DEVICE_ATTR(hover_tune, (S_IRUGO | S_IWUSR | S_IWGRP), NULL, + fts_hover_autotune_store); + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE +static DEVICE_ATTR(touchgame, (S_IRUGO | S_IWUSR | S_IWGRP), fts_touchgame_show, + NULL); +#endif +static struct attribute *fts_attr_group[] = { + &dev_attr_fwupdate.attr, + &dev_attr_appid.attr, + &dev_attr_mode_active.attr, + &dev_attr_fw_file_test.attr, + &dev_attr_stm_fts_cmd.attr, +#ifdef USE_ONE_FILE_NODE + &dev_attr_feature_enable.attr, +#else + +#ifdef GRIP_MODE + &dev_attr_grip_mode.attr, +#endif +#ifdef CHARGER_MODE + &dev_attr_charger_mode.attr, +#endif +#ifdef GLOVE_MODE + &dev_attr_glove_mode.attr, +#endif +#ifdef COVER_MODE + &dev_attr_cover_mode.attr, +#endif +#ifdef STYLUS_MODE + &dev_attr_stylus_mode.attr, +#endif +#endif + &dev_attr_fts_lockdown.attr, + &dev_attr_panel_vendor.attr, + &dev_attr_panel_color.attr, + &dev_attr_panel_display.attr, + &dev_attr_lockdown_info.attr, +#ifdef GESTURE_MODE + &dev_attr_gesture_mask.attr, + &dev_attr_gesture_coordinates.attr, +#endif + &dev_attr_selftest_info.attr, + &dev_attr_ms_raw.attr, + &dev_attr_ss_raw.attr, + &dev_attr_ms_cx_total.attr, + &dev_attr_ss_ix_total.attr, + &dev_attr_ms_strength.attr, + &dev_attr_ss_hover.attr, + &dev_attr_hover_tune.attr, + &dev_attr_doze_time.attr, + &dev_attr_grip_enable.attr, + &dev_attr_grip_area.attr, +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + &dev_attr_touchgame.attr, +#endif + NULL, +}; + +#ifdef CONFIG_FTS_TOUCH_COUNT_DUMP +static DEVICE_ATTR(touch_suspend_notify, (S_IRUGO | S_IRGRP), + fts_touch_suspend_notify_show, NULL); +#endif +#ifdef CONFIG_FTS_FOD_AREA_REPORT +static DEVICE_ATTR(fod_status, (S_IRUGO | S_IWUSR | S_IWGRP), + fts_fod_status_show, fts_fod_status_store); + +static DEVICE_ATTR(fod_test, (S_IRUGO | S_IWUSR | S_IWGRP), NULL, + fts_fod_test_store); +#endif + +#ifdef CONFIG_SECURE_TOUCH +DEVICE_ATTR(secure_touch_enable, (S_IRUGO | S_IWUSR | S_IWGRP), + fts_secure_touch_enable_show, fts_secure_touch_enable_store); +DEVICE_ATTR(secure_touch, (S_IRUGO | S_IWUSR | S_IWGRP), fts_secure_touch_show, + NULL); +#endif +/**@}*/ +/**@}*/ + +/** + * @defgroup isr Interrupt Service Routine (Event Handler) + * The most important part of the driver is the ISR (Interrupt Service Routine) called also as Event Handler \n + * As soon as the interrupt pin goes low, fts_interrupt_handler() is called and the chain to read and parse the event read from the FIFO start.\n + * For any different kind of EVT_ID there is a specific event handler which will take the correct action to report the proper info to the host. \n + * The most important events are the one related to touch informations, status update or user report. + * @{ + */ + +/** + * Report to the linux input system the pressure and release of a button handling concurrency + * @param info pointer to fts_ts_info which contains info about the device and its hw setup + * @param key_code button value + */ +void fts_input_report_key(struct fts_ts_info *info, int key_code) +{ + mutex_lock(&info->input_report_mutex); + input_report_key(info->input_dev, key_code, 1); + input_sync(info->input_dev); + input_report_key(info->input_dev, key_code, 0); + input_sync(info->input_dev); + mutex_unlock(&info->input_report_mutex); +} + +/** +* Event Handler for no events (EVT_ID_NOEVENT) +*/ +static void fts_nop_event_handler(struct fts_ts_info *info, + unsigned char *event) +{ + logError( + 1, + "%s %s Doing nothing for event = %02X %02X %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[0], event[1], event[2], event[3], event[4], + event[5], event[6], event[7]); +} + +#ifdef CONFIG_FTS_FOD_AREA_REPORT +static bool fts_is_in_fodarea(int x, int y) +{ + if ((x > FOD_LX && x < FOD_LX + FOD_SIDE) && + (y > FOD_LY && y < FOD_LY + FOD_SIDE)) + return true; + else + return false; +} + +static bool finger_report_flag; + +#endif +/** +* Event handler for enter and motion events (EVT_ID_ENTER_POINT, EVT_ID_MOTION_POINT ) +* report to the linux input system touches with their coordinated and additional informations +*/ +static void fts_enter_pointer_event_handler(struct fts_ts_info *info, + unsigned char *event) +{ + unsigned char touchId; + unsigned int touch_condition = 1, tool = MT_TOOL_FINGER; + int x, y, z, distance; + u8 touchType; + int area_size; +#ifndef CONFIG_FTS_FOD_AREA_REPORT + if (!info->resume_bit) + goto no_report; +#endif + if (info->sensor_sleep) { + logError(1, "%s %s sensor sleep, skip touch down event\n", tag, + __func__); + return; + } + touchType = event[1] & 0x0F; + touchId = (event[1] & 0xF0) >> 4; + + x = (((int)event[3] & 0x0F) << 8) | (event[2]); + y = ((int)event[4] << 4) | ((event[3] & 0xF0) >> 4); + + z = 1; + distance = 0; + + if (event[0] == EVT_ID_MOTION_POINT) { + area_size = (event[5] << 8) | event[6]; + } else { + area_size = 1; + } + + if (x >= info->board->x_max) + x = info->board->x_max; + + if (y >= info->board->y_max) + y = info->board->y_max; +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + info->coor[touchId][0] = x; + info->coor[touchId][1] = y; +/* + if (fts_touchmode_edgefilter(touchId, x, y)) + return; +*/ +#endif + + input_mt_slot(info->input_dev, touchId); + switch (touchType) { +#ifdef STYLUS_MODE + case TOUCH_TYPE_STYLUS: + logError(0, "%s %s : It is a stylus!\n", tag, __func__); + if (info->stylus_enabled == 1) { + tool = MT_TOOL_PEN; + touch_condition = 1; + __set_bit(touchId, &info->stylus_id); + break; + } +#endif + case TOUCH_TYPE_FINGER: + /*logError(0, "%s %s : It is a finger!\n",tag,__func__); */ + case TOUCH_TYPE_GLOVE: + /*logError(0, "%s %s : It is a glove!\n",tag,__func__); */ + case TOUCH_TYPE_PALM: + /*logError(0, "%s %s : It is a palm!\n",tag,__func__); */ + tool = MT_TOOL_FINGER; + touch_condition = 1; + __set_bit(touchId, &info->touch_id); + break; + + case TOUCH_TYPE_HOVER: + tool = MT_TOOL_FINGER; + touch_condition = 0; + z = 0; + __set_bit(touchId, &info->touch_id); + distance = DISTANCE_MAX; + break; + + case TOUCH_TYPE_INVALID: + default: + logError(1, "%s %s : Invalid touch type = %d ! No Report...\n", + tag, __func__, touchType); +#ifndef CONFIG_FTS_FOD_AREA_REPORT + goto no_report; +#endif + } + + input_mt_report_slot_state(info->input_dev, tool, 1); + input_report_key(info->input_dev, BTN_TOUCH, touch_condition); + if (touch_condition) + input_report_key(info->input_dev, BTN_TOOL_FINGER, 1); + + /*input_report_abs(info->input_dev, ABS_MT_TRACKING_ID, touchId); */ + input_report_abs(info->input_dev, ABS_MT_POSITION_X, x); + input_report_abs(info->input_dev, ABS_MT_POSITION_Y, y); + input_report_abs(info->input_dev, ABS_MT_TOUCH_MINOR, z); + input_report_abs(info->input_dev, ABS_MT_DISTANCE, distance); + input_report_abs(info->input_dev, ABS_MT_TOUCH_MAJOR, area_size); +#ifdef CONFIG_FTS_FOD_AREA_REPORT + if (fts_is_in_fodarea(x, y) && !(info->fod_id & ~(1 << touchId))) { + __set_bit(touchId, &info->sleep_finger); + if (info->fod_status) { + info->fod_x = x; + info->fod_y = y; + info->fod_coordinate_update = true; + __set_bit(touchId, &info->fod_id); + input_report_abs(info->input_dev, ABS_MT_WIDTH_MINOR, + info->fod_overlap); + logError(1, "%s %s : FOD Press :%d, fod_id:%08x\n", + tag, __func__, touchId, info->fod_id); + } + } else if (__test_and_clear_bit(touchId, &info->fod_id)) { + input_report_abs(info->input_dev, ABS_MT_WIDTH_MINOR, 0); + input_report_key(info->input_dev, BTN_INFO, 0); + input_report_key(info->input_dev, KEY_INFO, 0); + info->fod_coordinate_update = false; + info->fod_overlap = 0; + logError(1, "%s %s : FOD Release :%d\n", tag, __func__, + touchId); + __clear_bit(touchId, &info->sleep_finger); + } +#endif + input_sync(info->input_dev); + dev_dbg(info->dev, + "%s %s : Event 0x%02x - ID[%d], (x, y, z) = (%3d, %3d, %3d) type = %d, size = %d, overlap:%d\n", + tag, __func__, *event, touchId, x, y, z, touchType, area_size, + info->fod_overlap); + if (event[0] == 0x13) + logError(1, "%s %s : Event 0x%02x - Press ID[%d] type = %d\n", + tag, __func__, event[0], touchId, touchType); + +#ifndef CONFIG_FTS_FOD_AREA_REPORT +no_report: + return; +#endif +} + +/** +* Event handler for leave event (EVT_ID_LEAVE_POINT ) +* Report to the linux input system that one touch left the display +*/ +static void fts_leave_pointer_event_handler(struct fts_ts_info *info, + unsigned char *event) +{ + unsigned char touchId = 0; + unsigned int tool = MT_TOOL_FINGER; + unsigned int touch_condition = 0; + u8 touchType; +#ifdef CONFIG_FTS_FOD_AREA_REPORT + int x, y; + bool fod_up = false; +#endif +#ifdef CONFIG_FTS_FOD_AREA_REPORT + if (event[1] == 0xb5) { + touchType = TOUCH_TYPE_FINGER; + info->sleep_finger = 0; + if (!info->fod_id) { + logError(1, "%s %s : FOD Release without FOD press\n", + tag, __func__); + goto exit; + } + if (info->touch_id) { + logError(1, "%s %s : FOD Release in active mode\n", + tag, __func__); + goto exit; + } + touchId = ffs(info->fod_id) - 1; + info->fod_overlap = 0; + + logError(1, "%s %s : FOD Release :%d, fod_id:%08x\n", tag, + __func__, touchId, info->fod_id); + + __clear_bit(touchId, &info->fod_id); + fod_up = true; + + } else { +#endif + touchType = event[1] & 0x0F; + touchId = (event[1] & 0xF0) >> 4; +#ifdef CONFIG_FTS_FOD_AREA_REPORT + } + x = (event[2] << 4) | (event[4] & 0xF0) >> 4; + y = (event[3] << 4) | (event[4] & 0x0F); +#endif +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + info->coor[touchId][0] = -1; + info->coor[touchId][1] = -1; +/* + if (test_bit(touchId, &info->touch_skip)) { + __clear_bit(touchId, &info->touch_skip); + return; + } +*/ +#endif + input_mt_slot(info->input_dev, touchId); + switch (touchType) { +#ifdef STYLUS_MODE + case TOUCH_TYPE_STYLUS: + logError(0, "%s %s : It is a stylus!\n", tag, __func__); + if (info->stylus_enabled == 1) { + tool = MT_TOOL_PEN; + __clear_bit(touchId, &info->stylus_id); + break; + } +#endif + + case TOUCH_TYPE_FINGER: + /*logError(0, "%s %s : It is a finger!\n",tag,__func__); */ + case TOUCH_TYPE_GLOVE: + /*logError(0, "%s %s : It is a glove!\n",tag,__func__); */ + case TOUCH_TYPE_PALM: + /*logError(0, "%s %s : It is a palm!\n",tag,__func__); */ + tool = MT_TOOL_FINGER; + touch_condition = 0; + __clear_bit(touchId, &info->touch_id); + break; + case TOUCH_TYPE_HOVER: + tool = MT_TOOL_FINGER; + touch_condition = 1; + __clear_bit(touchId, &info->touch_id); + break; + + case TOUCH_TYPE_INVALID: + default: + logError(1, "%s %s : Invalid touch type = %d ! No Report...\n", + tag, __func__, touchType); + return; + } +#ifdef CONFIG_FTS_FOD_AREA_REPORT + __clear_bit(touchId, &info->sleep_finger); + if (__test_and_clear_bit(touchId, &info->fod_id)) { + input_report_abs(info->input_dev, ABS_MT_WIDTH_MINOR, 0); + input_report_key(info->input_dev, BTN_INFO, 0); + input_report_key(info->input_dev, KEY_INFO, 0); + info->fod_coordinate_update = false; + } +#endif + input_mt_report_slot_state(info->input_dev, tool, 0); + if (info->touch_id == 0) { + input_report_key(info->input_dev, BTN_TOUCH, touch_condition); + lpm_disable_for_input(false); + if (!touch_condition) + input_report_key(info->input_dev, BTN_TOOL_FINGER, 0); +#ifdef CONFIG_FTS_FOD_AREA_REPORT + info->fod_pressed = false; + info->fod_overlap = 0; + input_report_key(info->input_dev, BTN_INFO, 0); + input_report_key(info->input_dev, KEY_INFO, 0); + finger_report_flag = false; +#endif + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + wake_up(&info->wait_queue); +#endif + info->touch_skip = 0; + info->sleep_finger = 0; + info->fod_id = 0; + } + input_report_abs(info->input_dev, ABS_MT_TRACKING_ID, -1); +#ifdef CONFIG_FTS_FOD_AREA_REPORT + if (fod_up) + logError(1, "%s %s : Event FOD - release ID[%d] type = %d\n", + tag, __func__, touchId, touchType); + else +#endif + logError(1, + "%s %s : Event 0x%02x - release ID[%d] type = %d\n", + tag, __func__, event[0], touchId, touchType); + + input_sync(info->input_dev); +#ifdef CONFIG_FTS_FOD_AREA_REPORT +exit: +#endif + return; +} + +/* EventId : EVT_ID_MOTION_POINT */ +#define fts_motion_pointer_event_handler fts_enter_pointer_event_handler + +/** +* Event handler for error events (EVT_ID_ERROR) +* Handle unexpected error events implementing recovery strategy and restoring the sensing status that the IC had before the error occured +*/ +static void fts_error_event_handler(struct fts_ts_info *info, + unsigned char *event) +{ + int error = 0; + logError( + 1, + "%s %s Received event %02X %02X %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[0], event[1], event[2], event[3], event[4], + event[5], event[6], event[7]); + + switch (event[1]) { + case EVT_TYPE_ERROR_ESD: { + release_all_touches(info); + + fts_chip_powercycle(info); + + error = fts_system_reset(); + error |= fts_mode_handler(info, 0); + error |= fts_enableInterrupt(); + if (error < OK) { + logError(1, + "%s %s Cannot restore the device ERROR %08X\n", + tag, __func__, error); + } + } break; + case EVT_TYPE_ERROR_WATCHDOG: { + dumpErrorInfo(NULL, 0); + release_all_touches(info); + error = fts_system_reset(); + error |= fts_mode_handler(info, 0); + error |= fts_enableInterrupt(); + if (error < OK) { + logError(1, + "%s %s Cannot reset the device ERROR %08X\n", + tag, __func__, error); + } + } break; + } +} + +/** +* Event handler for controller ready event (EVT_ID_CONTROLLER_READY) +* Handle controller events received after unexpected reset of the IC updating the resets flag and restoring the proper sensing status +*/ +static void fts_controller_ready_event_handler(struct fts_ts_info *info, + unsigned char *event) +{ + int error; + logError( + 1, + "%s %s Received event %02X %02X %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[0], event[1], event[2], event[3], event[4], + event[5], event[6], event[7]); + release_all_touches(info); + setSystemResetedUp(1); + setSystemResetedDown(1); + error = fts_mode_handler(info, 0); + if (error < OK) { + logError(1, + "%s %s Cannot restore the device status ERROR %08X\n", + tag, __func__, error); + } +} + +/** +* Event handler for status events (EVT_ID_STATUS_UPDATE) +* Handle status update events +*/ +static void fts_status_event_handler(struct fts_ts_info *info, + unsigned char *event) +{ + switch (event[1]) { + case EVT_TYPE_STATUS_ECHO: + logError( + 0, + "%s %s Echo event of command = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], event[5], + event[6], event[7]); + break; + + case EVT_TYPE_STATUS_FORCE_CAL: + switch (event[2]) { + case 0x00: + logError( + 1, + "%s %s Continuous frame drop Force cal = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + case 0x01: + logError( + 1, + "%s %s Mutual negative detect Force cal = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + case 0x02: + logError( + 1, + "%s %s Mutual calib deviation Force cal = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + case 0x11: + logError( + 1, + "%s %s SS negative detect Force cal = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + case 0x12: + logError( + 1, + "%s %s SS negative detect Force cal in Low Power mode = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + case 0x13: + logError( + 1, + "%s %s SS negative detect Force cal in Idle mode = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + case 0x20: + logError( + 1, + "%s %s SS invalid Mutual Strength soft Force cal = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + case 0x21: + logError( + 1, + "%s %s SS invalid Self Strength soft Force cal = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + case 0x22: + logError( + 1, + "%s %s SS invalid Self Island soft Force cal = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + case 0x30: + logError( + 1, + "%s %s MS invalid Mutual Strength soft Force cal = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + case 0x31: + logError( + 1, + "%s %s MS invalid Self Strength soft Force cal = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + default: + logError( + 1, + "%s %s Force cal = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + } + break; + + case EVT_TYPE_STATUS_FRAME_DROP: + switch (event[2]) { + case 0x01: + logError( + 1, + "%s %s Frame drop noisy frame = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + case 0x02: + logError( + 1, + "%s %s Frame drop bad R = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + case 0x03: + logError( + 1, + "%s %s Frame drop invalid processing state = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + default: + logError( + 1, + "%s %s Frame drop = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + } + break; + + case EVT_TYPE_STATUS_SS_RAW_SAT: + if (event[2] == 1) + logError( + 1, + "%s %s SS Raw Saturated = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + else + logError( + 1, + "%s %s SS Raw No more Saturated = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; + + case EVT_TYPE_STATUS_WATER: + if (event[2] == 1) + logError( + 1, + "%s %s Enter Water mode = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + else + logError( + 1, + "%s %s Exit Water mode = %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[2], event[3], event[4], + event[5], event[6], event[7]); + break; +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + case EVT_TYPE_STATUS_POCKET: + if (event[0] == 0x43 && event[2] == 0x01) { + update_palm_sensor_value(1); + } else if (event[0] == 0x43 && event[2] == 0x00) { + update_palm_sensor_value(0); + } + break; +#endif + default: + logError( + 1, + "%s %s Received unhandled status event = %02X %02X %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[0], event[1], event[2], event[3], + event[4], event[5], event[6], event[7]); + break; + } +} + +#ifdef PHONE_KEY +/** + * Event handler for status events (EVT_TYPE_USER_KEY) + * Handle keys update events, the third byte of the event is a bitmask where if the bit set means that the corresponding key is pressed. + */ +static void fts_key_event_handler(struct fts_ts_info *info, + unsigned char *event) +{ + logError( + 0, + "%s %s Received event %02X %02X %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[0], event[1], event[2], event[3], event[4], + event[5], event[6], event[7]); + + if (event[0] == EVT_ID_USER_REPORT && event[1] == EVT_TYPE_USER_KEY) { + if ((event[2] & FTS_KEY_0) == 0 && (key_mask & FTS_KEY_0) > 0) { + logError(0, + "%s %s: Button HOME pressed and released! \n", + tag, __func__); + fts_input_report_key(info, KEY_HOMEPAGE); + } + + if ((event[2] & FTS_KEY_1) == 0 && (key_mask & FTS_KEY_1) > 0) { + logError(0, + "%s %s: Button Back pressed and released! \n", + tag, __func__); + fts_input_report_key(info, KEY_BACK); + } + + if ((event[2] & FTS_KEY_2) == 0 && (key_mask & FTS_KEY_2) > 0) { + logError(0, "%s %s: Button Menu pressed! \n", tag, + __func__); + fts_input_report_key(info, KEY_MENU); + } + + key_mask = event[2]; + } else { + logError(1, "%s %s: Invalid event passed as argument! \n", tag, + __func__); + } +} +#endif + +#ifdef GESTURE_MODE +/** + * Event handler for gesture events (EVT_TYPE_USER_GESTURE) + * Handle gesture events and simulate the click on a different button for any gesture detected (@link gesture_opt Gesture IDs @endlink) + */ +static void fts_gesture_event_handler(struct fts_ts_info *info, + unsigned char *event) +{ + int value; + int needCoords = 0; + char ch[64] = { + 0x0, + }; +#ifdef CONFIG_FTS_FOD_AREA_REPORT + int touch_area; + int fod_overlap; + int fod_id = 0; + int x = (event[4] << 8) | (event[3]); + int y = (event[6] << 8) | (event[5]); +#endif + + logError( + 1, + "%s gesture event data: %02X %02X %02X %02X %02X %02X %02X %02X\n", + tag, event[0], event[1], event[2], event[3], event[4], event[5], + event[6], event[7]); + if (event[0] == EVT_ID_USER_REPORT && + event[1] == EVT_TYPE_USER_GESTURE) { + needCoords = 1; +#ifdef CONFIG_FTS_FOD_AREA_REPORT + if (event[2] == GEST_ID_LONG_PRESS && info->fod_status) { + touch_area = (event[9] << 8) | (event[8]); + fod_overlap = (event[11] << 8) | (event[10]); + if ((!info->sensor_sleep && + info->fod_coordinate_update && info->fod_id && + fts_is_in_fodarea(info->fod_x, info->fod_y)) || + (info->sensor_sleep && fts_is_in_fodarea(x, y))) { + if (!finger_report_flag) { + logError( + 1, + "%s %s finger down in the fod area\n", + tag, __func__); + finger_report_flag = true; + } + info->fod_overlap = fod_overlap; + + if ((info->sensor_sleep && + !info->sleep_finger) || + !info->sensor_sleep) { + info->fod_pressed = true; + input_report_key(info->input_dev, + BTN_INFO, 1); + input_report_key(info->input_dev, + KEY_INFO, 1); + input_sync(info->input_dev); + if (info->fod_id) { + fod_id = ffs(info->fod_id) - 1; + if (info->fod_id & + ~(1 << fod_id)) + logError( + 1, + "%s %s multi fingers on fod area:%08x\n", + tag, __func__, + info->fod_id); + } else if (info->sensor_sleep) { + __set_bit(0, &info->fod_id); + } + + if (info->fod_coordinate_update || + info->sensor_sleep) { + input_mt_slot(info->input_dev, + fod_id); + input_mt_report_slot_state( + info->input_dev, + MT_TOOL_FINGER, 1); + input_report_key( + info->input_dev, + BTN_TOUCH, 1); + input_report_key( + info->input_dev, + BTN_TOOL_FINGER, 1); + if (info->sensor_sleep) { + input_report_abs( + info->input_dev, + ABS_MT_POSITION_X, + x); + input_report_abs( + info->input_dev, + ABS_MT_POSITION_Y, + y); + } else { + input_report_abs( + info->input_dev, + ABS_MT_POSITION_X, + info->fod_x); + input_report_abs( + info->input_dev, + ABS_MT_POSITION_Y, + info->fod_y); + info->fod_coordinate_update = + false; + } + input_report_abs( + info->input_dev, + ABS_MT_WIDTH_MAJOR, + touch_area); + input_report_abs( + info->input_dev, + ABS_MT_WIDTH_MINOR, + fod_overlap); + logError( + 1, + "%s %s id:%d, fod_id:%08x, touch_area:%d, overlap:%d,fod report\n", + tag, __func__, fod_id, + info->fod_id, + touch_area, + fod_overlap); + } + input_sync(info->input_dev); + } + } + goto gesture_done; + } else if (event[2] == GEST_ID_SINGTAP && info->fod_status) { + input_report_key(info->input_dev, KEY_GOTO, 1); + input_sync(info->input_dev); + input_report_key(info->input_dev, KEY_GOTO, 0); + input_sync(info->input_dev); + info->sleep_finger = 0; + info->fod_overlap = 0; + info->fod_pressed = false; + goto gesture_done; + } +#endif + switch (event[2]) { + case GEST_ID_DBLTAP: + if (!info->gesture_enabled) + goto gesture_done; + value = KEY_WAKEUP; + logError(0, "%s %s: double tap ! \n", tag, __func__); + info->dbclick_count++; + snprintf(ch, sizeof(ch), "%d", info->dbclick_count); + needCoords = 0; + break; + + case GEST_ID_AT: + value = KEY_WWW; + logError(0, "%s %s: @ ! \n", tag, __func__); + break; + + case GEST_ID_C: + value = KEY_C; + logError(0, "%s %s: C ! \n", tag, __func__); + break; + + case GEST_ID_E: + value = KEY_E; + logError(0, "%s %s: e ! \n", tag, __func__); + break; + + case GEST_ID_F: + value = KEY_F; + logError(0, "%s %s: F ! \n", tag, __func__); + break; + + case GEST_ID_L: + value = KEY_L; + logError(0, "%s %s: L ! \n", tag, __func__); + break; + + case GEST_ID_M: + value = KEY_M; + logError(0, "%s %s: M ! \n", tag, __func__); + break; + + case GEST_ID_O: + value = KEY_O; + logError(0, "%s %s: O ! \n", tag, __func__); + break; + + case GEST_ID_S: + value = KEY_S; + logError(0, "%s %s: S ! \n", tag, __func__); + break; + + case GEST_ID_V: + value = KEY_V; + logError(0, "%s %s: V ! \n", tag, __func__); + break; + + case GEST_ID_W: + value = KEY_W; + logError(0, "%s %s: W ! \n", tag, __func__); + break; + + case GEST_ID_Z: + value = KEY_Z; + logError(0, "%s %s: Z ! \n", tag, __func__); + break; + + case GEST_ID_RIGHT_1F: + value = KEY_RIGHT; + logError(0, "%s %s: -> ! \n", tag, __func__); + break; + + case GEST_ID_LEFT_1F: + value = KEY_LEFT; + logError(0, "%s %s: <- ! \n", tag, __func__); + break; + + case GEST_ID_UP_1F: + value = KEY_UP; + logError(0, "%s %s: UP ! \n", tag, __func__); + break; + + case GEST_ID_DOWN_1F: + value = KEY_DOWN; + logError(0, "%s %s: DOWN ! \n", tag, __func__); + break; + + case GEST_ID_CARET: + value = KEY_APOSTROPHE; + logError(0, "%s %s: ^ ! \n", tag, __func__); + break; + + case GEST_ID_LEFTBRACE: + value = KEY_LEFTBRACE; + logError(0, "%s %s: < ! \n", tag, __func__); + break; + + case GEST_ID_RIGHTBRACE: + value = KEY_RIGHTBRACE; + logError(0, "%s %s: > ! \n", tag, __func__); + break; + + default: + logError(0, "%s %s: No valid GestureID! \n", tag, + __func__); + goto gesture_done; + } + + if (needCoords == 1) + readGestureCoords(event); + + fts_input_report_key(info, value); + +gesture_done: + return; + } else { + logError(1, "%s %s: Invalid event passed as argument! \n", tag, + __func__); + } +} +#endif + +/** + * Event handler for user report events (EVT_ID_USER_REPORT) + * Handle user events reported by the FW due to some interaction triggered by an external user (press keys, perform gestures, etc.) + */ +static void fts_user_report_event_handler(struct fts_ts_info *info, + unsigned char *event) +{ + switch (event[1]) { +#ifdef PHONE_KEY + case EVT_TYPE_USER_KEY: + fts_key_event_handler(info, event); + break; +#endif + + case EVT_TYPE_USER_PROXIMITY: + if (event[2] == 0) { + logError(1, "%s %s No proximity!\n", tag, __func__); + } else { + logError(1, "%s %s Proximity Detected!\n", tag, + __func__); + } + break; + +#ifdef GESTURE_MODE + case EVT_TYPE_USER_GESTURE: + fts_gesture_event_handler(info, event); + break; +#endif +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + case EVT_TYPE_USER_EARDET: + if (event[2] == 0xAA) { + logError(1, "%s %s hover ear enter\n", tag, __func__); + update_p_sensor_value(1); + } else if (event[2] == 0xBB) { + logError(1, "%s %s hover leave\n", tag, __func__); + update_p_sensor_value(0); + } else if (event[2] == 0xCC) { + logError(1, "%s %s hover palm enter\n", tag, __func__); + update_p_sensor_value(2); + } + break; +#endif + default: + logError( + 1, + "%s %s Received unhandled user report event = %02X %02X %02X %02X %02X %02X %02X %02X\n", + tag, __func__, event[0], event[1], event[2], event[3], + event[4], event[5], event[6], event[7]); + break; + } +} + +/* +static void buffDump(unsigned char *buf, unsigned int buflength, char *tag) +{ + unsigned char *tmp, *back; + unsigned int i; + unsigned int to_read; + unsigned int remain = buflength; + unsigned int chunk = 10; + + logError(1, "%s BUFFDUMP IN:", tag); + + tmp = kmalloc(300, GFP_ATOMIC); + if (!tmp) { + logError(1, "alloc tmp=%04d byte failed", 300); + return; + } + back = tmp; + + memcpy(tmp, buf, buflength); + + while (remain > 0) { + if (remain > chunk) { + remain -= chunk; + to_read = chunk; + } else { + to_read = remain; + for (i = to_read; i < chunk; i++) { + tmp[i] = 0xED; + } + remain = 0; + } + + logError(1, "%s %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + tag, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8], tmp[9]); + + tmp += to_read; + } + kfree(back); +} +*/ + +static void fts_ts_sleep_work(struct work_struct *work) +{ + struct fts_ts_info *info = + container_of(work, struct fts_ts_info, sleep_work); + int error = 0, count = 0; + unsigned char regAdd = FIFO_CMD_READALL; + unsigned char data[FIFO_EVENT_SIZE * FIFO_DEPTH] = { 0 }; + unsigned char eventId; + const unsigned char EVENTS_REMAINING_POS = 7; + const unsigned char EVENTS_REMAINING_MASK = 0x1F; + unsigned char events_remaining = 0; + unsigned char *evt_data; + static char pre_id[3]; + event_dispatch_handler_t event_handler; + int r; + fts_disableInterrupt(); + if (info->tp_pm_suspend) { + r = wait_for_completion_timeout(&info->pm_resume_completion, + msecs_to_jiffies(500)); + if (!r) { + logError( + 1, + "%s pm_resume_completion timeout, i2c is closed", + tag); + pm_relax(info->dev); + fts_enableInterrupt(); + lpm_disable_for_input(false); + return; + } else { + logError( + 1, + "%s pm_resume_completion be completed, handling irq", + tag); + } + } + + info->irq_status = true; + error = fts_writeReadU8UX(regAdd, 0, 0, data, FIFO_EVENT_SIZE, + DUMMY_FIFO); + events_remaining = data[EVENTS_REMAINING_POS] & EVENTS_REMAINING_MASK; + events_remaining = (events_remaining > FIFO_DEPTH - 1) ? + FIFO_DEPTH - 1 : + events_remaining; + + /*Drain the rest of the FIFO, up to 31 events*/ + if (error == OK && events_remaining > 0) { + error = fts_writeReadU8UX(regAdd, 0, 0, &data[FIFO_EVENT_SIZE], + FIFO_EVENT_SIZE * events_remaining, + DUMMY_FIFO); + } + if (error != OK) { + logError( + 1, + "Error (%d) while reading from FIFO in fts_event_handler", + error); + } else { + for (count = 0; count < events_remaining + 1; count++) { + evt_data = &data[count * FIFO_EVENT_SIZE]; + if (pre_id[0] == EVT_ID_USER_REPORT && + pre_id[1] == 0x02 && pre_id[2] == 0x18) { + pre_id[0] = 0; + pre_id[1] = 0; + pre_id[2] = 0; + continue; + } + if (evt_data[0] == EVT_ID_NOEVENT) + break; + eventId = evt_data[0] >> 4; + /*Ensure event ID is within bounds*/ + if (eventId < NUM_EVT_ID) { + event_handler = + info->event_dispatch_table[eventId]; + event_handler(info, (evt_data)); + pre_id[0] = evt_data[0]; + pre_id[1] = evt_data[1]; + pre_id[2] = evt_data[2]; + } + } + } + input_sync(info->input_dev); + info->irq_status = false; +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + wake_up(&info->wait_queue); +#endif + pm_relax(info->dev); + fts_enableInterrupt(); + lpm_disable_for_input(false); + return; +} + +/** + * Bottom Half Interrupt Handler function + * This handler is called each time there is at least one new event in the FIFO and the interrupt pin of the IC goes low. + * It will read all the events from the FIFO and dispatch them to the proper event handler according the event ID + */ +static irqreturn_t fts_event_handler(int irq, void *ts_info) +{ + struct fts_ts_info *info = ts_info; + int error = 0, count = 0; + unsigned char regAdd = FIFO_CMD_READALL; + unsigned char data[FIFO_EVENT_SIZE * FIFO_DEPTH] = { 0 }; + unsigned char eventId; + const unsigned char EVENTS_REMAINING_POS = 7; + const unsigned char EVENTS_REMAINING_MASK = 0x1F; + unsigned char events_remaining = 0; + unsigned char *evt_data; + static char pre_id[3]; + event_dispatch_handler_t event_handler; + + if (info->tp_pm_suspend) { + logError(1, "%s device in suspend, schedue to work", tag); + pm_wakeup_event(info->dev, 0); + if (!work_pending(&info->sleep_work)) { + pm_stay_awake(info->dev); + queue_work(info->irq_wq, &info->sleep_work); + } + return IRQ_HANDLED; + } + +#ifdef CONFIG_SECURE_TOUCH + if (!fts_secure_filter_interrupt(info)) { + return IRQ_HANDLED; + } +#endif + lpm_disable_for_input(true); + + info->irq_status = true; + error = fts_writeReadU8UX(regAdd, 0, 0, data, FIFO_EVENT_SIZE, + DUMMY_FIFO); + events_remaining = data[EVENTS_REMAINING_POS] & EVENTS_REMAINING_MASK; + events_remaining = (events_remaining > FIFO_DEPTH - 1) ? + FIFO_DEPTH - 1 : + events_remaining; + + /*Drain the rest of the FIFO, up to 31 events*/ + if (error == OK && events_remaining > 0) { + error = fts_writeReadU8UX(regAdd, 0, 0, &data[FIFO_EVENT_SIZE], + FIFO_EVENT_SIZE * events_remaining, + DUMMY_FIFO); + } + if (error != OK) { + logError( + 1, + "Error (%d) while reading from FIFO in fts_event_handler", + error); + } else { + for (count = 0; count < events_remaining + 1; count++) { + evt_data = &data[count * FIFO_EVENT_SIZE]; + if (pre_id[0] == EVT_ID_USER_REPORT && + pre_id[1] == 0x02 && pre_id[2] == 0x18) { + pre_id[0] = 0; + pre_id[1] = 0; + pre_id[2] = 0; + continue; + } + if (evt_data[0] == EVT_ID_NOEVENT) + break; + eventId = evt_data[0] >> 4; + /*Ensure event ID is within bounds*/ + if (eventId < NUM_EVT_ID) { + event_handler = + info->event_dispatch_table[eventId]; + event_handler(info, (evt_data)); + pre_id[0] = evt_data[0]; + pre_id[1] = evt_data[1]; + pre_id[2] = evt_data[2]; + } + } + } + input_sync(info->input_dev); + info->irq_status = false; + if (!info->touch_id) + lpm_disable_for_input(false); +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + wake_up(&info->wait_queue); +#endif + return IRQ_HANDLED; +} + +/**@}*/ + +static const char *fts_get_config(struct fts_ts_info *info) +{ + struct fts_hw_platform_data *pdata = info->board; + int i = 0, ret = 0; + + ret = fts_get_lockdown_info(info->lockdown_info, info); + + if (ret < OK) { + logError(1, "%s can't read lockdown info", tag); + return pdata->default_fw_name; + } + + ret |= fts_enableInterrupt(); + + for (i = 0; i < pdata->config_array_size; i++) { + if (info->lockdown_info[0] == pdata->config_array[i].tp_vendor) + break; + } + + if (i >= pdata->config_array_size) { + logError(1, "%s can't find right config", tag); + return pdata->default_fw_name; + } + + logError(1, "%s Choose config %d: %s", tag, i, + pdata->config_array[i].fts_cfg_name); + pdata->current_index = i; +#ifdef CONFIG_FTS_TOUCH_COUNT_DUMP + if (pdata->dump_click_count) { + info->current_clicknum_file = + kzalloc(TOUCH_COUNT_FILE_MAXSIZE, GFP_KERNEL); + strlcpy(info->current_clicknum_file, + pdata->config_array[i].clicknum_file_name, + TOUCH_COUNT_FILE_MAXSIZE); + } +#endif + return pdata->config_array[i].fts_cfg_name; +} + +static const char *fts_get_limit(struct fts_ts_info *info) +{ + struct fts_hw_platform_data *pdata = info->board; + int i = 0, ret = 0; + + ret = fts_get_lockdown_info(info->lockdown_info, info); + + if (ret < OK) { + logError(1, "%s can't read lockdown info", tag); + return LIMITS_FILE; + } + + ret |= fts_enableInterrupt(); + + for (i = 0; i < pdata->config_array_size; i++) { + if (info->lockdown_info[0] == pdata->config_array[i].tp_vendor) + break; + } + + if (i >= pdata->config_array_size) { + logError(1, "%s can't find right limit", tag); + return LIMITS_FILE; + } + + logError(1, "%s Choose limit file %d: %s", tag, i, + pdata->config_array[i].fts_limit_name); + pdata->current_index = i; + return pdata->config_array[i].fts_limit_name; +} + +/** +* Implement the fw update and initialization flow of the IC that should be executed at every boot up. +* The function perform a fw update of the IC in case of crc error or a new fw version and then understand if the IC need to be re-initialized again. +* @return OK if success or an error code which specify the type of error encountered +*/ +int fts_fw_update(struct fts_ts_info *info, const char *fw_name, int force) +{ + u8 error_to_search[4] = { EVT_TYPE_ERROR_CRC_CX_HEAD, + EVT_TYPE_ERROR_CRC_CX, + EVT_TYPE_ERROR_CRC_CX_SUB_HEAD, + EVT_TYPE_ERROR_CRC_CX_SUB }; + int retval = 0; + int retval1 = 0; + int ret; + int crc_status = 0; + int error = 0; + int init_type = NO_INIT; +#ifdef PRE_SAVED_METHOD + int keep_cx = 1; +#else + int keep_cx = 0; +#endif + + logError(1, "%s Fw Auto Update is starting... \n", tag); + + ret = fts_crc_check(); + if (ret > OK) { + logError(1, "%s %s: CRC Error or NO FW!\n", tag, __func__); + crc_status = ret; + } else { + crc_status = 0; + logError( + 1, + "%s %s: NO CRC Error or Impossible to read CRC register! \n", + tag, __func__); + } + + if (fw_name == NULL) { + fw_name = fts_get_config(info); + if (fw_name == NULL) + logError(1, "%s not found mached config!", tag); + } + + if (fw_name) { + if (force) + retval = flashProcedure(fw_name, 1, keep_cx); + else + retval = flashProcedure(fw_name, crc_status, keep_cx); + + if ((retval & 0xFF000000) == ERROR_FLASH_PROCEDURE) { + logError( + 1, + "%s %s: firmware update failed and retry! ERROR %08X\n", + tag, __func__, retval); + fts_chip_powercycle(info); + retval1 = flashProcedure(info->board->default_fw_name, + crc_status, keep_cx); + if ((retval1 & 0xFF000000) == ERROR_FLASH_PROCEDURE) { + logError( + 1, + "%s %s: firmware update failed again! ERROR %08X\n", + tag, __func__, retval1); + logError(1, "%s Fw Auto Update Failed!\n", tag); + } + } + } + + logError(1, "%s %s: Verifying if CX CRC Error...\n", tag, __func__, + ret); + ret = fts_system_reset(); + if (ret >= OK) { + ret = pollForErrorType(error_to_search, 4); + if (ret < OK) { + logError(1, "%s %s: No Cx CRC Error Found! \n", tag, + __func__); + logError(1, "%s %s: Verifying if Panel CRC Error... \n", + tag, __func__); + error_to_search[0] = EVT_TYPE_ERROR_CRC_PANEL_HEAD; + error_to_search[1] = EVT_TYPE_ERROR_CRC_PANEL; + ret = pollForErrorType(error_to_search, 2); + if (ret < OK) { + logError(1, + "%s %s: No Panel CRC Error Found! \n", + tag, __func__); + init_type = NO_INIT; + } else { + logError( + 1, + "%s %s: Panel CRC Error FOUND! CRC ERROR = %02X\n", + tag, __func__, ret); + init_type = SPECIAL_PANEL_INIT; + } + } else { + logError( + 1, + "%s %s: Cx CRC Error FOUND! CRC ERROR = %02X\n", + tag, __func__, ret); + + logError( + 1, + "%s %s: Try to recovery with CX in fw file...\n", + tag, __func__, ret); + flashProcedure(info->board->default_fw_name, CRC_CX, 0); + logError(1, "%s %s: Refresh panel init data... \n", tag, + __func__, ret); + } + } else { + logError( + 1, + "%s %s: Error while executing system reset! ERROR %08X\n", + tag, __func__, ret); + } + + if (init_type == NO_INIT) { +#ifdef PRE_SAVED_METHOD + if (systemInfo.u8_cfgAfeVer != systemInfo.u8_cxAfeVer) { + init_type = SPECIAL_FULL_PANEL_INIT; + logError( + 0, + "%s %s: Different CX AFE Ver: %02X != %02X... Execute FULL Panel Init! \n", + tag, __func__, systemInfo.u8_cfgAfeVer, + systemInfo.u8_cxAfeVer); + } else +#endif + + if (systemInfo.u8_cfgAfeVer != + systemInfo.u8_panelCfgAfeVer) { + init_type = SPECIAL_PANEL_INIT; + logError( + 0, + "%s %s: Different Panel AFE Ver: %02X != %02X... Execute Panel Init! \n", + tag, __func__, systemInfo.u8_cfgAfeVer, + systemInfo.u8_panelCfgAfeVer); + } else { + init_type = NO_INIT; + } + } + + if (init_type != NO_INIT) { + error = fts_chip_initialization(info, init_type); + if (error < OK) { + logError( + 1, + "%s %s Cannot initialize the chip ERROR %08X\n", + tag, __func__, error); + } + } + + error = fts_init_sensing(info); + if (error < OK) { + logError( + 1, + "%s Cannot initialize the hardware device ERROR %08X\n", + tag, error); + } + + logError(1, "%s Fw Update Finished! error = %08X\n", tag, error); + return error; +} + +#ifndef FW_UPDATE_ON_PROBE + +/** +* Function called by the delayed workthread executed after the probe in order to perform the fw update flow +* @see fts_fw_update() +*/ +static void fts_fw_update_auto(struct work_struct *work) +{ + struct delayed_work *fwu_work = + container_of(work, struct delayed_work, work); + struct fts_ts_info *info = + container_of(fwu_work, struct fts_ts_info, fwu_work); + fts_fw_update(info, NULL, 0); +} +#endif + +/** +* Execute the initialization of the IC (supporting a retry mechanism), checking also the resulting data +* @see production_test_main() +*/ +static int fts_chip_initialization(struct fts_ts_info *info, int init_type) +{ + int ret2 = 0; + int retry; + int initretrycnt = 0; + + for (retry = 0; retry <= RETRY_INIT_BOOT; retry++) { + ret2 = production_test_initialization(init_type); + if (ret2 == OK) + break; + initretrycnt++; + logError(1, + "%s initialization cycle count = %04d - ERROR %08X \n", + tag, initretrycnt, ret2); + fts_chip_powercycle(info); + } + + if (ret2 < OK) { + logError(1, "%s fts initialization failed 3 times \n", tag); + } + + return ret2; +} + +/** + * @addtogroup isr + * @{ + */ +/** +* Top half Interrupt handler function +* Respond to the interrupt and schedule the bottom half interrupt handler in its work queue +* @see fts_event_handler() +*/ +/* +static irqreturn_t fts_interrupt_handler(int irq, void *handle) +{ + struct fts_ts_info *info = handle; +#ifdef CONFIG_SECURE_TOUCH + if (!fts_secure_filter_interrupt(info)) { + return IRQ_HANDLED; + } +#endif + disable_irq_nosync(info->client->irq); + queue_work(info->event_wq, &info->work); + + return IRQ_HANDLED; +} +*/ +/** +* Initialize the dispatch table with the event handlers for any possible event ID and the interrupt routine behavior (triggered when the IRQ pin is low and associating the top half interrupt handler function). +* @see fts_interrupt_handler() +*/ +static int fts_interrupt_install(struct fts_ts_info *info) +{ + int i, error = 0; + + info->event_dispatch_table = kzalloc( + sizeof(event_dispatch_handler_t) * NUM_EVT_ID, GFP_KERNEL); + + if (!info->event_dispatch_table) { + logError(1, "%s OOM allocating event dispatch table\n", tag); + return -ENOMEM; + } + + for (i = 0; i < NUM_EVT_ID; i++) + info->event_dispatch_table[i] = fts_nop_event_handler; + + install_handler(info, ENTER_POINT, enter_pointer); + install_handler(info, LEAVE_POINT, leave_pointer); + install_handler(info, MOTION_POINT, motion_pointer); + install_handler(info, ERROR, error); + install_handler(info, CONTROLLER_READY, controller_ready); + install_handler(info, STATUS_UPDATE, status); + install_handler(info, USER_REPORT, user_report); + + /* disable interrupts in any case */ + error = fts_disableInterrupt(); + logError(1, "%s Interrupt Mode\n", tag); + if (request_threaded_irq(info->client->irq, NULL, fts_event_handler, + info->board->irq_flags, FTS_TS_DRV_NAME, + info)) { + logError(1, "%s Request irq failed\n", tag); + kfree(info->event_dispatch_table); + error = -EBUSY; + } else { + disable_irq(info->client->irq); + } + + return error; +} + +/** +* Clean the dispatch table and the free the IRQ. +* This function is called when the driver need to be removed +*/ +static void fts_interrupt_uninstall(struct fts_ts_info *info) +{ + fts_disableInterrupt(); + + kfree(info->event_dispatch_table); + + free_irq(info->client->irq, info); +} + +/**@}*/ + +/** +* This function try to attempt to communicate with the IC for the first time during the boot up process in order to acquire the necessary info for the following stages. +* The function execute a system reset, read fundamental info (system info) from the IC and install the interrupt +* @return OK if success or an error code which specify the type of error encountered +*/ +static int fts_init(struct fts_ts_info *info) +{ + int error; + + error = fts_system_reset(); + if (error < OK && isI2cError(error)) { + logError(1, "%s Cannot reset the device! ERROR %08X\n", tag, + error); + return error; + } else { + if (error == (ERROR_TIMEOUT | ERROR_SYSTEM_RESET_FAIL)) { + logError(1, "%s Setting default Sys INFO! \n", tag); + error = defaultSysInfo(0); + } else { + error = readSysInfo(0); + if (error < OK) { + if (!isI2cError(error)) + error = OK; + logError( + 1, + "%s Cannot read Sys Info! ERROR %08X\n", + tag, error); + } + } + } + + return error; +} + +/** +* Execute a power cycle in the IC, toggling the power lines (AVDD and DVDD) +* @param info pointer to fts_ts_info struct which contain information of the regulators +* @return 0 if success or another value if fail +*/ +int fts_chip_powercycle(struct fts_ts_info *info) +{ + int error = 0; + + logError(1, "%s %s: Power Cycle Starting... \n", tag, __func__); + logError(1, "%s %s: Disabling IRQ... \n", tag, __func__); + + fts_disableInterruptNoSync(); + + if (info->vdd_reg) { + error = regulator_disable(info->vdd_reg); + if (error < 0) { + logError(1, "%s %s: Failed to disable DVDD regulator\n", + tag, __func__); + } + } + + if (info->avdd_reg) { + error = regulator_disable(info->avdd_reg); + if (error < 0) { + logError(1, "%s %s: Failed to disable AVDD regulator\n", + tag, __func__); + } + } + + if (info->board->reset_gpio != GPIO_NOT_DEFINED) + gpio_set_value(info->board->reset_gpio, 0); + else + mdelay(300); + + if (info->vdd_reg) { + error = regulator_enable(info->vdd_reg); + if (error < 0) { + logError(1, "%s %s: Failed to enable DVDD regulator\n", + tag, __func__); + } + } + + mdelay(1); + + if (info->avdd_reg) { + error = regulator_enable(info->avdd_reg); + if (error < 0) { + logError(1, "%s %s: Failed to enable AVDD regulator\n", + tag, __func__); + } + } + + mdelay(5); + + if (info->board->reset_gpio != GPIO_NOT_DEFINED) { + mdelay(10); + gpio_set_value(info->board->reset_gpio, 1); + } + + release_all_touches(info); + + logError(1, "%s %s: Power Cycle Finished! ERROR CODE = %08x\n", tag, + __func__, error); + setSystemResetedUp(1); + setSystemResetedDown(1); + return error; +} + +/** + * Complete the boot up process, initializing the sensing of the IC according to the current setting chosen by the host and register the notifier for the suspend/resume actions and the event handler + * @return OK if success or an error code which specify the type of error encountered + */ +static int fts_init_sensing(struct fts_ts_info *info) +{ + int error = 0; +#ifdef CONFIG_DRM + error |= drm_register_client(&info->notifier); +#endif + error |= fts_interrupt_install(info); + error |= fts_mode_handler(info, 0); +#ifdef CONFIG_FTS_FOD_AREA_REPORT + error |= setScanMode(SCAN_MODE_ACTIVE, 0x00); + mdelay(WAIT_AFTER_SENSEOFF); + error |= setScanMode(SCAN_MODE_ACTIVE, 0x01); +#endif + error |= fts_enableInterrupt(); + + if (error < OK) + logError(1, "%s %s Init after Probe error (ERROR = %08X)\n", + tag, __func__, error); + + return error; +} + +/** + * @ingroup mode_section + * @{ + */ +/** + * The function handle the switching of the mode in the IC enabling/disabling the sensing and the features set from the host + * @param info pointer to fts_ts_info which contains info about the device and its hw setup + * @param force if 1, the enabling/disabling command will be send even if the feature was alredy enabled/disabled otherwise it will judge if the feature changed status or the IC had s system reset and therefore the features need to be restored + * @return OK if success or an error code which specify the type of error encountered + */ +static int fts_mode_handler(struct fts_ts_info *info, int force) +{ + int res = OK; + int ret = OK; + u8 settings[4] = { 0 }; +#ifdef CONFIG_FTS_FOD_AREA_REPORT + u8 gesture_cmd[6] = { 0xA2, 0x03, 0x20, 0x00, 0x00, 0x01 }; + u8 single_only_cmd[4] = { 0xC0, 0x02, 0x00, 0x00 }; + u8 single_double_cmd[4] = { 0xC0, 0x02, 0x01, 0x1E }; +#endif +#ifdef CONFIG_FTS_FOD_AREA_REPORT + mutex_lock(&info->fod_mutex); +#endif + info->mode = MODE_NOTHING; + logError(0, "%s %s: Mode Handler starting... \n", tag, __func__); + switch (info->resume_bit) { + case 0: + logError(0, "%s %s: Screen OFF... \n", tag, __func__); + +#ifdef CONFIG_FTS_FOD_AREA_REPORT + if (info->fod_status) { + logError(1, "%s %s: Sense OFF by FOD \n", tag, + __func__); + logError(1, "%s %s,send long press and gesture cmd\n", + tag, __func__); + res = fts_write_dma_safe(gesture_cmd, + ARRAY_SIZE(gesture_cmd)); + if (res < OK) + logError( + 1, + "%s %s: enter gesture and longpress failed! ERROR %08X recovery in senseOff...\n", + tag, __func__, res); + res = setScanMode(SCAN_MODE_LOW_POWER, 0); + res |= ret; + if (info->gesture_enabled == 1) { + res = fts_write_dma_safe( + single_double_cmd, + ARRAY_SIZE(single_double_cmd)); + if (res < OK) + logError( + 1, + "%s %s: set single and double tap delay time failed! ERROR %08X\n", + tag, __func__, res); + } else { + res = fts_write_dma_safe( + single_only_cmd, + ARRAY_SIZE(single_only_cmd)); + if (res < OK) + logError( + 1, + "%s %s: set single only delay time failed! ERROR %08X\n", + tag, __func__, res); + } + info->fod_status_set = true; + } else { +#endif + logError(1, "%s %s: Sense OFF! \n", tag, __func__); + ret = setScanMode(SCAN_MODE_ACTIVE, 0x00); + res |= ret; + + if (info->gesture_enabled == 1) { + logError(1, "%s %s: enter in gesture mode ! \n", + tag, __func__); + res = enterGestureMode(isSystemResettedDown()); + if (res >= OK) { + fromIDtoMask(FEAT_SEL_GESTURE, + (u8 *)&info->mode, + sizeof(info->mode)); + MODE_LOW_POWER(info->mode, 0); + } else { + logError( + 1, + "%s %s: enterGestureMode failed! ERROR %08X recovery in senseOff...\n", + tag, __func__, res); + } + } + info->fod_status_set = false; +#ifdef CONFIG_FTS_FOD_AREA_REPORT + } +#endif + setSystemResetedDown(0); + break; + + case 1: + logError(1, "%s %s: Screen ON... \n", tag, __func__); + +#ifdef GLOVE_MODE + if ((info->glove_enabled == FEAT_ENABLE && + isSystemResettedUp()) || + force == 1) { + logError(0, "%s %s: Glove Mode setting... \n", tag, + __func__); + settings[0] = info->glove_enabled; + ret = setFeatures(FEAT_SEL_GLOVE, settings, 1); + if (ret < OK) { + logError( + 1, + "%s %s: error during setting GLOVE_MODE! ERROR %08X\n", + tag, __func__, ret); + } + res |= ret; + + if (ret >= OK && info->glove_enabled == FEAT_ENABLE) { + fromIDtoMask(FEAT_SEL_GLOVE, (u8 *)&info->mode, + sizeof(info->mode)); + logError(1, "%s %s: GLOVE_MODE Enabled! \n", + tag, __func__); + } else { + logError(1, "%s %s: GLOVE_MODE Disabled! \n", + tag, __func__); + } + } +#endif + +#ifdef COVER_MODE + if ((info->cover_enabled == FEAT_ENABLE && + isSystemResettedUp()) || + force == 1) { + logError(0, "%s %s: Cover Mode setting... \n", tag, + __func__); + settings[0] = info->cover_enabled; + ret = setFeatures(FEAT_SEL_COVER, settings, 1); + if (ret < OK) { + logError( + 1, + "%s %s: error during setting COVER_MODE! ERROR %08X\n", + tag, __func__, ret); + } + res |= ret; + + if (ret >= OK && info->cover_enabled == FEAT_ENABLE) { + fromIDtoMask(FEAT_SEL_COVER, (u8 *)&info->mode, + sizeof(info->mode)); + logError(1, "%s %s: COVER_MODE Enabled! \n", + tag, __func__); + } else { + logError(1, "%s %s: COVER_MODE Disabled! \n", + tag, __func__); + } + } +#endif +#ifdef CHARGER_MODE + if ((info->charger_enabled > 0 && isSystemResettedUp()) || + force == 1) { + logError(0, "%s %s: Charger Mode setting... \n", tag, + __func__); + + settings[0] = info->charger_enabled; + ret = setFeatures(FEAT_SEL_CHARGER, settings, 1); + if (ret < OK) { + logError( + 1, + "%s %s: error during setting CHARGER_MODE! ERROR %08X\n", + tag, __func__, ret); + } + res |= ret; + + if (ret >= OK && info->charger_enabled == FEAT_ENABLE) { + fromIDtoMask(FEAT_SEL_CHARGER, + (u8 *)&info->mode, + sizeof(info->mode)); + logError(1, "%s %s: CHARGER_MODE Enabled! \n", + tag, __func__); + } else { + logError(1, "%s %s: CHARGER_MODE Disabled! \n", + tag, __func__); + } + } +#endif + +#ifdef GRIP_MODE + if ((info->grip_enabled == FEAT_ENABLE && + isSystemResettedUp()) || + force == 1) { + logError(0, "%s %s: Grip Mode setting... \n", tag, + __func__); + settings[0] = info->grip_enabled; + ret = setFeatures(FEAT_SEL_GRIP, settings, 1); + if (ret < OK) { + logError( + 1, + "%s %s: error during setting GRIP_MODE! ERROR %08X\n", + tag, __func__, ret); + } + res |= ret; + + if (ret >= OK && info->grip_enabled == FEAT_ENABLE) { + fromIDtoMask(FEAT_SEL_GRIP, (u8 *)&info->mode, + sizeof(info->mode)); + logError(1, "%s %s: GRIP_MODE Enabled! \n", tag, + __func__); + } else { + logError(1, "%s %s: GRIP_MODE Disabled! \n", + tag, __func__); + } + } +#endif +#ifdef CONFIG_FTS_FOD_AREA_REPORT + if (info->fod_pressed) { + logError(1, "%s %s: Sense OFF \n", tag, __func__); + res |= setScanMode(SCAN_MODE_ACTIVE, 0x00); + logError(1, "%s %s: Sense ON without cal \n", tag, + __func__); + res |= setScanMode(SCAN_MODE_ACTIVE, 0x20); + } else { + logError(1, "%s %s: Sense ON\n", tag, __func__); + res |= setScanMode(SCAN_MODE_ACTIVE, 0x01); + } + info->sensor_scan = true; + if (info->fod_status) { + res = fts_write_dma_safe(gesture_cmd, + ARRAY_SIZE(gesture_cmd)); + if (res < OK) + logError( + 1, + "%s %s: enter gesture and longpress failed! ERROR %08X recovery in senseOff...\n", + tag, __func__, res); + info->fod_status_set = true; + } +#else + settings[0] = 0x01; + logError(1, "%s %s: Sense ON! \n", tag, __func__); + res |= setScanMode(SCAN_MODE_ACTIVE, settings[0]); + info->mode |= (SCAN_MODE_ACTIVE << 24); + MODE_ACTIVE(info->mode, settings[0]); +#endif + setSystemResetedUp(0); + break; + + default: + logError(1, + "%s %s: invalid resume_bit value = %d! ERROR %08X \n", + tag, __func__, info->resume_bit, ERROR_OP_NOT_ALLOW); + res = ERROR_OP_NOT_ALLOW; + } + + logError(0, "%s %s: Mode Handler finished! res = %08X mode = %08X \n", + tag, __func__, res, info->mode); +#ifdef CONFIG_FTS_FOD_AREA_REPORT + mutex_unlock(&info->fod_mutex); +#endif + return res; +} + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE +static struct xiaomi_touch_interface xiaomi_touch_interfaces; + +bool inline fts_touchmode_edgefilter(unsigned int touch_id, int x, int y) +{ + int i; + bool top_half = false; + + const struct fts_hw_platform_data *bdata = fts_info->board; + int filter_size = 0; + + switch (xiaomi_touch_interfaces + .touch_mode[Touch_Edge_Filter][GET_CUR_VALUE]) { + case 0: + filter_size = 0; + break; + case 1: + filter_size = 100; + break; + case 2: + filter_size = 150; + break; + case 3: + filter_size = 250; + break; + default: + filter_size = 0; + logError(1, "%s %s: no support value %08d\n", tag, __func__, + filter_size); + break; + } + + if (!filter_size) + return false; + + if (test_bit(touch_id, &fts_info->touch_skip)) { + logError(1, "%s %s: skip mask finger:%d, %x\n", tag, __func__, + touch_id, fts_info->touch_skip); + return true; + } else if ((x >= 0 && x < filter_size) && + ((y >= 0 && y < filter_size) || + (y > bdata->y_max - filter_size && y < bdata->y_max))) { + if (y >= 0 && y < filter_size) { + top_half = true; + } else { + top_half = false; + } + + for (i = 0; i < TOUCH_ID_MAX; i++) { + if ((i == touch_id) || + (!test_bit(i, &fts_info->touch_id))) + continue; + if ((fts_info->coor[i][1] > (int)(bdata->y_max / 2) && + top_half) || + (fts_info->coor[i][1] < (int)(bdata->y_max / 2) && + fts_info->coor[i][1] >= 0 && !top_half)) { + return false; + } + } + + if (!test_bit(touch_id, &fts_info->touch_id) && + fts_info->touch_id != 0) { + __set_bit(touch_id, &fts_info->touch_skip); + logError( + 1, + "%s %s: skip mask first finger:%d, touch_id:%x, touch_skip:%0x\n", + tag, __func__, touch_id, fts_info->touch_id, + fts_info->touch_skip); + return true; + } + } + + return false; +} + +int fts_read_touchmode_data() +{ + int ret = 0; + u8 get_cmd[2] = { 0xc1, 0x05 }; + u8 get_value[Touch_Mode_NUM] = { + 0x0, + }; + u8 grip_cmd[2] = { 0xc1, 0x08 }; + u8 grip_value[Touch_Mode_NUM] = { + 0x0, + }; + int readBytes = 7; + int i; + ret = fts_writeRead_dma_safe(get_cmd, sizeof(get_cmd) / sizeof(u8), + get_value, readBytes); + if (ret < OK) { + logError( + 1, + "%s %s: error while reading touchmode data ERROR %08X\n", + tag, __func__, ret); + return -1; + } + ret = fts_writeRead_dma_safe(grip_cmd, sizeof(grip_cmd) / sizeof(u8), + grip_value, readBytes); + if (ret < OK) { + logError( + 1, + "%s %s: error while reading edge filter data ERROR %08X\n", + tag, __func__, ret); + return -1; + } + + for (i = 0; i < Touch_Mode_NUM; i++) { + if (i == Touch_Edge_Filter) + xiaomi_touch_interfaces.touch_mode[i][GET_CUR_VALUE] = + grip_value[0]; + else + xiaomi_touch_interfaces.touch_mode[i][GET_CUR_VALUE] = + get_value[i]; + } + + for (i = 0; i < 7; i++) { + xiaomi_touch_interfaces.touch_edge[i] = grip_value[i]; + } + + logError( + 1, + "%s %s: game_mode:%d, active_mode:%d, up_threshold:%d, landlock:%d, wgh:%d, %d, %d\n", + tag, __func__, get_value[0], get_value[1], get_value[2], + get_value[3], get_value[4], get_value[5], get_value[6]); + logError(1, "%s %s: grip:0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", + tag, __func__, grip_value[0], grip_value[1], grip_value[2], + grip_value[3], grip_value[4], grip_value[5], grip_value[6]); + + return ret; +} + +static void fts_init_touchmode_data() +{ + int i; + + /* default value should equl the first initial value */ + for (i = 0; i < Touch_Mode_NUM; i++) { + xiaomi_touch_interfaces.touch_mode[i][GET_DEF_VALUE] = + xiaomi_touch_interfaces.touch_mode[i][GET_CUR_VALUE]; + xiaomi_touch_interfaces.touch_mode[i][SET_CUR_VALUE] = + xiaomi_touch_interfaces.touch_mode[i][GET_CUR_VALUE]; + } + /* Touch Game Mode Switch */ + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_MAX_VALUE] = 1; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_DEF_VALUE] = 0; + + /* Acitve Mode */ + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_MAX_VALUE] = + 1; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_MIN_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_DEF_VALUE] = + 0; + + /* finger hysteresis */ + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_DEF_VALUE] = + 80; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][SET_CUR_VALUE] = + 80; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_CUR_VALUE] = + 80; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_MAX_VALUE] = + 120; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_MIN_VALUE] = + 40; + + /* Tolerance */ + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_DEF_VALUE] = 25; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_MAX_VALUE] = 35; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_MIN_VALUE] = 5; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][SET_CUR_VALUE] = 25; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_CUR_VALUE] = 25; + + /* Wgh Min */ + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Min][GET_DEF_VALUE] = 1; + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Min][GET_CUR_VALUE] = 1; + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Min][SET_CUR_VALUE] = 1; + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Min][GET_MAX_VALUE] = 15; + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Min][GET_MIN_VALUE] = 0; + + /* Wgh Max */ + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Max][GET_DEF_VALUE] = 5; + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Max][GET_CUR_VALUE] = 5; + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Max][SET_CUR_VALUE] = 5; + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Max][GET_MAX_VALUE] = 15; + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Max][GET_MIN_VALUE] = 0; + + /* Wgh Step */ + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Step][GET_DEF_VALUE] = 1; + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Step][GET_CUR_VALUE] = 1; + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Step][SET_CUR_VALUE] = 1; + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Step][GET_MAX_VALUE] = 2; + xiaomi_touch_interfaces.touch_mode[Touch_Wgh_Step][GET_MIN_VALUE] = 0; + + /* edge filter */ + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_MAX_VALUE] = + 3; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_MIN_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_DEF_VALUE] = + 2; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][SET_CUR_VALUE] = + 2; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_CUR_VALUE] = + 2; + + /* Orientation */ + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_MAX_VALUE] = 3; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_DEF_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][SET_CUR_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_CUR_VALUE] = 0; + + for (i = 0; i < Touch_Mode_NUM; i++) { + logError( + 1, + "%s %s: mode:%d, set cur:%d, get cur:%d, def:%d min:%d max:%d\n", + tag, __func__, i, + xiaomi_touch_interfaces.touch_mode[i][SET_CUR_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_CUR_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_DEF_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_MIN_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_MAX_VALUE]); + } + + return; +} +#define EDGE_OF_LEFTRIGHT 45 +#define EDGE_OF_TOPBOTTOM 0 +static void fts_edge_rejection(bool on, int value) +{ + /* the fixed edge_reject is 65 */ + int ret = 0; + u8 edge_of_leftright[4] = { 0xc0, 0x01, 0x00, 0x00 }; + u8 edge_of_topbottom[4] = { 0xc0, 0x01, 0x01, 0x00 }; + + if (on) { + edge_of_topbottom[3] = value; + edge_of_leftright[3] = 0; + } else { + edge_of_leftright[3] = EDGE_OF_LEFTRIGHT; + edge_of_topbottom[3] = EDGE_OF_TOPBOTTOM; + } + + ret = fts_write_dma_safe(edge_of_leftright, + sizeof(edge_of_leftright) / sizeof(u8)); + if (ret < OK) { + logError( + 1, + "%s %s: error while writing edge left/right data ERROR %08X\n", + tag, __func__, ret); + return; + } + + ret = fts_write_dma_safe(edge_of_topbottom, + sizeof(edge_of_topbottom) / sizeof(u8)); + if (ret < OK) { + logError( + 1, + "%s %s: error while writing edge top/bottom data ERROR %08X\n", + tag, __func__, ret); + return; + } + logError(1, "%s %s: on:%d, value:%d\n", tag, __func__, on, value); + + return; +} + +static void fts_update_grip_mode() +{ + int i, ret; + u8 grip_cmd[9] = { + 0xc0, + 0x08, + 0x00, + }; + u8 grip_rcmd[2] = { 0xc1, 0x08 }; + u8 grip_value[7] = { + 0x0, + }; + int temp_value = 0; + bool topbottom_edge_filter = false; + int direction = 0; + + logError(1, "%s %s: value:%d\n", tag, __func__, + xiaomi_touch_interfaces + .touch_mode[Touch_Edge_Filter][SET_CUR_VALUE]); + switch (xiaomi_touch_interfaces + .touch_mode[Touch_Edge_Filter][SET_CUR_VALUE]) { + case 0: + temp_value = 0; + break; + case 1: + temp_value = 100; + break; + case 2: + temp_value = 170; + break; + case 3: + temp_value = 250; + break; + default: + temp_value = 0; + logError(1, "%s %s: no support value %08d\n", tag, __func__, + temp_value); + break; + } + + direction = xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][SET_CUR_VALUE]; + + switch (direction) { + case 0: + case 2: + /* 0 and 180, filter the leftright edge */ + topbottom_edge_filter = false; + xiaomi_touch_interfaces.touch_edge[0] = 0; + xiaomi_touch_interfaces.touch_edge[1] = 0x0f; + xiaomi_touch_interfaces.touch_edge[2] = 0x00; + xiaomi_touch_interfaces.touch_edge[3] = 0; + xiaomi_touch_interfaces.touch_edge[4] = 0; + xiaomi_touch_interfaces.touch_edge[5] = 0; + xiaomi_touch_interfaces.touch_edge[6] = 0; + break; + case 1: + topbottom_edge_filter = true; + xiaomi_touch_interfaces.touch_edge[0] = 1; + xiaomi_touch_interfaces.touch_edge[1] = 0x0f; + xiaomi_touch_interfaces.touch_edge[2] = 0x00; + xiaomi_touch_interfaces.touch_edge[3] = temp_value; + xiaomi_touch_interfaces.touch_edge[4] = temp_value; + xiaomi_touch_interfaces.touch_edge[5] = 0; + xiaomi_touch_interfaces.touch_edge[6] = 0; + break; + case 3: + topbottom_edge_filter = true; + xiaomi_touch_interfaces.touch_edge[0] = 1; + xiaomi_touch_interfaces.touch_edge[1] = 0x0f; + xiaomi_touch_interfaces.touch_edge[2] = 0x00; + xiaomi_touch_interfaces.touch_edge[3] = 0; + xiaomi_touch_interfaces.touch_edge[4] = 0; + xiaomi_touch_interfaces.touch_edge[5] = temp_value; + xiaomi_touch_interfaces.touch_edge[6] = temp_value; + break; + default: + /* Dont't support */ + break; + }; + + if (!xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_CUR_VALUE] || + !topbottom_edge_filter) { + logError(1, "%s %s: touch game mode off or portrait\n", tag, + __func__); + fts_edge_rejection(false, 0); + } else + fts_edge_rejection(true, 0); + + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[Touch_Edge_Filter][SET_CUR_VALUE]; + + for (i = 0; i < 7; i++) { + grip_cmd[2 + i] = (u8)(xiaomi_touch_interfaces.touch_edge[i]); + } + logError( + 1, + "%s %s: write grip:0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", + tag, __func__, grip_cmd[0], grip_cmd[1], grip_cmd[2], + grip_cmd[3], grip_cmd[4], grip_cmd[5], grip_cmd[6], grip_cmd[7], + grip_cmd[8]); + + ret = fts_write_dma_safe(grip_cmd, sizeof(grip_cmd) / sizeof(u8)); + if (ret < OK) { + logError( + 1, + "%s %s: error while writing touchmode data ERROR %08X\n", + tag, __func__, ret); + return; + } + msleep(10); + ret = fts_writeRead_dma_safe(grip_rcmd, sizeof(grip_rcmd) / sizeof(u8), + grip_value, + sizeof(grip_value) / sizeof(u8)); + if (ret < OK) { + logError( + 1, + "%s %s: error while reading edge filter data ERROR %08X\n", + tag, __func__, ret); + return; + } + logError(1, + "%s %s: read grip:0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", + tag, __func__, grip_value[0], grip_value[1], grip_value[2], + grip_value[3], grip_value[4], grip_value[5], grip_value[6]); + + logError(1, "%s %s: grip enable:%d, direction:%d\n", tag, __func__, + grip_value[0], direction); + + return; +} + +static void fts_update_touchmode_data() +{ + bool update = false; + int i, j, ret = 0; + u8 set_cmd[9] = { + 0xc0, + 0x05, + 0, + }; + u8 get_cmd[2] = { 0xc1, 0x05 }; + u8 get_value[7] = { + 0x0, + }; + int temp_value = 0; + + ret = wait_event_interruptible_timeout(fts_info->wait_queue, + !(fts_info->irq_status || + fts_info->touch_id), + msecs_to_jiffies(500)); + + if (ret <= 0) { + logError(1, "%s %s: wait touch finger up timeout\n", tag, + __func__); + return; + } + mutex_lock(&fts_info->cmd_update_mutex); + + for (i = 0; i < Touch_Mode_NUM; i++) { + if (xiaomi_touch_interfaces.touch_mode[i][GET_CUR_VALUE] != + xiaomi_touch_interfaces.touch_mode[i][SET_CUR_VALUE]) { + xiaomi_touch_interfaces.touch_mode[i][GET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[i][SET_CUR_VALUE]; + logError(1, "%s %s: mode:%d changed, value:%d\n", tag, + __func__, i, + xiaomi_touch_interfaces + .touch_mode[i][SET_CUR_VALUE]); + update = true; + } + } + + if (update) { + for (j = 2; j < sizeof(set_cmd) / sizeof(u8); j++) { + if (j - 2 == Touch_UP_THRESHOLD || + j - 2 == Touch_Tolerance) + temp_value = + xiaomi_touch_interfaces + .touch_mode[j - 2] + [GET_MAX_VALUE] - + xiaomi_touch_interfaces + .touch_mode[j - 2] + [GET_CUR_VALUE] + + xiaomi_touch_interfaces + .touch_mode[j - 2] + [GET_MIN_VALUE]; + else + temp_value = + (xiaomi_touch_interfaces + .touch_mode[j - 2] + [GET_CUR_VALUE]); + + set_cmd[j] = (u8)temp_value; + } + logError( + 1, + "%s %s: write game:0x%x, 0x%x, %d, %d, %d, %d, %d, %d, %d\n", + tag, __func__, set_cmd[0], set_cmd[1], set_cmd[2], + set_cmd[3], set_cmd[4], set_cmd[5], set_cmd[6], + set_cmd[7], set_cmd[8]); + + ret = fts_write_dma_safe(set_cmd, sizeof(set_cmd) / sizeof(u8)); + if (ret < OK) { + logError( + 1, + "%s %s: error while writing touchmode data ERROR %08X\n", + tag, __func__, ret); + goto end; + } + + ret = fts_writeRead_dma_safe(get_cmd, + sizeof(get_cmd) / sizeof(u8), + get_value, + sizeof(get_value) / sizeof(u8)); + if (ret < OK) { + logError( + 1, + "%s %s: error while reading touchmode data ERROR %08X\n", + tag, __func__, ret); + goto end; + } + + logError( + 1, + "%s %s: read game:%d, active_mode:%d, up_threshold:%d, landlock:%d, wgh:%d, %d, %d\n", + tag, __func__, get_value[0], get_value[1], get_value[2], + get_value[3], get_value[4], get_value[5], get_value[6]); + fts_update_grip_mode(); + } else { + logError(1, "%s %s: no update\n", tag, __func__); + } + +end: + mutex_unlock(&fts_info->cmd_update_mutex); + return; +} + +static void fts_cmd_update_work(struct work_struct *work) +{ + fts_update_touchmode_data(); + + return; +} + +static int fts_set_cur_value(int mode, int value) +{ + if (mode < Touch_Mode_NUM && mode >= 0) { + xiaomi_touch_interfaces.touch_mode[mode][SET_CUR_VALUE] = value; + + if (xiaomi_touch_interfaces.touch_mode[mode][SET_CUR_VALUE] > + xiaomi_touch_interfaces.touch_mode[mode][GET_MAX_VALUE]) { + xiaomi_touch_interfaces.touch_mode[mode][SET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[mode][GET_MAX_VALUE]; + + } else if (xiaomi_touch_interfaces + .touch_mode[mode][SET_CUR_VALUE] < + xiaomi_touch_interfaces + .touch_mode[mode][GET_MIN_VALUE]) { + xiaomi_touch_interfaces.touch_mode[mode][SET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[mode][GET_MIN_VALUE]; + } + } else { + logError(1, "%s %s, don't support\n", tag, __func__); + } + logError(1, "%s %s, mode:%d, value:%d\n", tag, __func__, mode, value); + + queue_work(fts_info->touch_feature_wq, &fts_info->cmd_update_work); + + return 0; +} + +static int fts_get_mode_value(int mode, int value_type) +{ + int value = -1; + + if (mode < Touch_Mode_NUM && mode >= 0) + value = xiaomi_touch_interfaces.touch_mode[mode][value_type]; + else + logError(1, "%s, %s, don't support\n", tag, __func__); + + return value; +} + +static int fts_get_mode_all(int mode, int *value) +{ + if (mode < Touch_Mode_NUM && mode >= 0) { + value[0] = + xiaomi_touch_interfaces.touch_mode[mode][GET_CUR_VALUE]; + value[1] = + xiaomi_touch_interfaces.touch_mode[mode][GET_DEF_VALUE]; + value[2] = + xiaomi_touch_interfaces.touch_mode[mode][GET_MIN_VALUE]; + value[3] = + xiaomi_touch_interfaces.touch_mode[mode][GET_MAX_VALUE]; + } else { + logError(1, "%s %s, don't support\n", tag, __func__); + } + logError(1, "%s %s, mode:%d, value:%d:%d:%d:%d\n", tag, __func__, mode, + value[0], value[1], value[2], value[3]); + + return 0; +} + +static int fts_reset_mode(int mode) +{ + int i = 0; + + if (mode < Touch_Mode_NUM && mode > 0) { + xiaomi_touch_interfaces.touch_mode[mode][SET_CUR_VALUE] = + xiaomi_touch_interfaces.touch_mode[mode][GET_DEF_VALUE]; + } else if (mode == 0) { + for (i = 0; i < Touch_Mode_NUM; i++) { + xiaomi_touch_interfaces.touch_mode[i][SET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[i][GET_DEF_VALUE]; + } + } else { + logError(1, "%s %s, don't support\n", tag, __func__); + } + + logError(1, "%s %s, mode:%d\n", tag, __func__, mode); + + queue_work(fts_info->event_wq, &fts_info->cmd_update_work); + + return 0; +} + +int fts_p_sensor_cmd(int input) +{ + int ret; + u8 cmd_on[] = { 0xa0, 0x00, 0x05 }; + u8 cmd_off[] = { 0xa0, 0x00, 0x01 }; + u8 hover_on[] = { 0xc0, 0x03, 0x01, 0x00 }; + u8 hover_off[] = { 0xc0, 0x03, 0x00, 0x00 }; + + if (input) { + ret = fts_write_dma_safe(cmd_on, sizeof(cmd_on)); + ret = fts_write_dma_safe(hover_on, sizeof(hover_on)); + } else { + ret = fts_write_dma_safe(cmd_off, sizeof(cmd_off)); + ret = fts_write_dma_safe(hover_off, sizeof(hover_off)); + } + if (ret < OK) { + logError(1, "%s %s: write palm sensor cmd on...ERROR %08X !\n", + tag, __func__, ret); + return -EINVAL; + } + + return 0; +} + +int fts_p_sensor_write(int value) +{ + int ret = 0; + + fts_info->p_sensor_switch = value; + + if (fts_info->sensor_sleep) { + fts_info->p_sensor_changed = false; + return 0; + } + ret = fts_p_sensor_cmd(value); + + if (!ret) + fts_info->p_sensor_changed = true; + + return ret; +} + +int fts_palm_sensor_cmd(int on) +{ + int ret; + u8 cmd_on[] = { 0xc0, 0x07, 0x01 }; + u8 cmd_off[] = { 0xc0, 0x07, 0x00 }; + + if (on) { + ret = fts_write_dma_safe(cmd_on, sizeof(cmd_on)); + } else { + ret = fts_write_dma_safe(cmd_off, sizeof(cmd_off)); + } + + if (ret < OK) { + logError(1, + "%s %s: write anti mis-touch cmd on...ERROR %08X !\n", + tag, __func__, ret); + return -EINVAL; + } + logError(1, "%s %s %d\n", tag, __func__, on); + + return 0; +} + +int fts_palm_sensor_write(int value) +{ + int ret = 0; + struct fts_secure_info *scr_info = fts_info->secure_info; + + fts_info->palm_sensor_switch = value; + + if (fts_info->sensor_sleep) { + fts_info->palm_sensor_changed = false; + return 0; + } + + mutex_lock(&scr_info->palm_lock); + if (atomic_read(&scr_info->st_enabled)) { + if (!scr_info->scr_delay.palm_pending) { + scr_info->scr_delay.palm_value = value; + scr_info->scr_delay.palm_pending = true; + } else { + logError(1, "%s already pending,skip", tag); + } + } else { + ret = fts_palm_sensor_cmd(value); + if (!ret) + fts_info->palm_sensor_changed = true; + } + mutex_unlock(&scr_info->palm_lock); + + return ret; +} +#endif +/** + * Resume work function which perform a system reset, clean all the touches from the linux input system and prepare the ground for enabling the sensing + */ +static void fts_resume_work(struct work_struct *work) +{ + struct fts_ts_info *info; + + info = container_of(work, struct fts_ts_info, resume_work); + fts_disableInterrupt(); +#ifdef CONFIG_SECURE_TOUCH + fts_secure_stop(info, true); +#endif + info->resume_bit = 1; +#ifdef CONFIG_FTS_FOD_AREA_REPORT + if (!info->fod_pressed) { +#endif + fts_system_reset(); + release_all_touches(info); +#ifdef CONFIG_FTS_FOD_AREA_REPORT + } +#endif + info->fod_status_set = false; + fts_mode_handler(info, 0); + info->sensor_sleep = false; + info->sleep_finger = 0; + + fts_enableInterrupt(); +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + if (info->palm_sensor_switch && !info->palm_sensor_changed) { + fts_palm_sensor_cmd(info->palm_sensor_switch); + info->palm_sensor_changed = true; + } +#endif +} + +/** + * Suspend work function which clean all the touches from Linux input system and prepare the ground to disabling the sensing or enter in gesture mode + */ +static void fts_suspend_work(struct work_struct *work) +{ + struct fts_ts_info *info; + + info = container_of(work, struct fts_ts_info, suspend_work); +#ifdef CONFIG_SECURE_TOUCH + fts_secure_stop(info, true); +#endif +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + if (info->palm_sensor_switch) { + logError(1, "%s %s: palm sensor on status, switch to off\n", + tag, __func__); + update_palm_sensor_value(0); + fts_palm_sensor_cmd(0); + info->palm_sensor_switch = false; + } +#endif + fts_disableInterrupt(); + info->resume_bit = 0; + fts_mode_handler(info, 0); + release_all_touches(info); + + info->sensor_sleep = true; + + if (info->gesture_enabled || info->fod_status) + fts_enableInterrupt(); +#ifdef CONFIG_FTS_TOUCH_COUNT_DUMP + sysfs_notify(&fts_info->fts_touch_dev->kobj, NULL, + "touch_suspend_notify"); +#endif + lpm_disable_for_input(false); +} + +#ifdef CONFIG_DRM +/**@}*/ + +/** + * Callback function used to detect the suspend/resume events generated by clicking the power button. + * This function schedule a suspend or resume work according to the event received. + */ +static int fts_drm_state_chg_callback(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct fts_ts_info *info = + container_of(nb, struct fts_ts_info, notifier); + struct drm_notify_data *evdata = data; + unsigned int blank; + + logError(0, "%s %s: fts notifier begin!\n", tag, __func__); + + if (evdata && evdata->data && info) { + blank = *(int *)(evdata->data); + logError(1, "%s %s: val:%lu,blank:%u\n", tag, __func__, val, + blank); + + if (val == DRM_EARLY_EVENT_BLANK && + (blank == DRM_BLANK_POWERDOWN || blank == DRM_BLANK_LP1 || + blank == DRM_BLANK_LP2)) { + if (info->sensor_sleep) + return NOTIFY_OK; + + logError(1, "%s %s: FB_BLANK %s\n", tag, __func__, + blank == DRM_BLANK_POWERDOWN ? "POWER DOWN" : + "LP"); + + flush_workqueue(info->event_wq); + queue_work(info->event_wq, &info->suspend_work); + } else if (val == DRM_EVENT_BLANK && + blank == DRM_BLANK_UNBLANK) { + if (!info->sensor_sleep) + return NOTIFY_OK; + + logError(1, "%s %s: FB_BLANK_UNBLANK\n", tag, __func__); + + flush_workqueue(info->event_wq); + queue_work(info->event_wq, &info->resume_work); + } + } + return NOTIFY_OK; +} + +static struct notifier_block fts_noti_block = { + .notifier_call = fts_drm_state_chg_callback, +}; +#endif + +static int fts_bl_state_chg_callback(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct fts_ts_info *info = + container_of(nb, struct fts_ts_info, bl_notifier); + unsigned int blank; + int ret; + + if (val != BACKLIGHT_UPDATED) + return NOTIFY_OK; + if (data && info) { + blank = *(int *)(data); + logError(1, "%s %s: val:%lu,blank:%u\n", tag, __func__, val, + blank); + flush_workqueue(info->event_wq); + if (blank == BACKLIGHT_OFF && + (info->fod_status_set && !info->sensor_sleep && + !info->touch_id)) { +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + if (info->p_sensor_switch) { + logError(1, + "%s eardet enabled, skip disableirq\n", + tag, __func__); + return NOTIFY_OK; + } +#endif + if (info->sensor_sleep) + return NOTIFY_OK; + logError(1, "%s %s: BL_EVENT_BLANK\n", tag, __func__); + ret = fts_disableInterrupt(); + setScanMode(SCAN_MODE_ACTIVE, 0x00); + info->sensor_scan = false; + flushFIFO(); + release_all_touches(info); + if (ret < OK) + logError(1, + "%s fts_disableInterrupt ERROR %08X\n", + tag, ret | ERROR_ENABLE_INTER); + } else if (blank == BACKLIGHT_ON) { + logError(1, "%s %s: BL_EVENT_UNBLANK\n", tag, __func__); + if (!info->sensor_sleep) { + ret = fts_enableInterrupt(); + if (ret < OK) + logError( + 1, + "%s fts_enableInterrupt ERROR %08X\n", + tag, ret | ERROR_ENABLE_INTER); + if (!info->sensor_scan) + setScanMode(SCAN_MODE_ACTIVE, 0x01); + } + } + } + return NOTIFY_OK; +} + +static struct notifier_block fts_bl_noti_block = { + .notifier_call = fts_bl_state_chg_callback, +}; + +/** + * From the name of the power regulator get/put the actual regulator structs (copying their references into fts_ts_info variable) + * @param info pointer to fts_ts_info which contains info about the device and its hw setup + * @param get if 1, the regulators are get otherwise they are put (released) back to the system + * @return OK if success or an error code which specify the type of error encountered + */ +static int fts_get_reg(struct fts_ts_info *info, bool get) +{ + int retval; + const struct fts_hw_platform_data *bdata = info->board; + + if (!get) { + retval = 0; + goto regulator_put; + } + + if ((bdata->vdd_reg_name != NULL) && (*bdata->vdd_reg_name != 0)) { + info->vdd_reg = regulator_get(info->dev, bdata->vdd_reg_name); + if (IS_ERR(info->vdd_reg)) { + logError(1, "%s %s: Failed to get power regulator\n", + tag, __func__); + retval = PTR_ERR(info->vdd_reg); + goto regulator_put; + } + } + + if ((bdata->avdd_reg_name != NULL) && (*bdata->avdd_reg_name != 0)) { + info->avdd_reg = regulator_get(info->dev, bdata->avdd_reg_name); + if (IS_ERR(info->avdd_reg)) { + logError(1, + "%s %s: Failed to get bus pullup regulator\n", + tag, __func__); + retval = PTR_ERR(info->avdd_reg); + goto regulator_put; + } + } + + return OK; + +regulator_put: + if (info->vdd_reg) { + regulator_put(info->vdd_reg); + info->vdd_reg = NULL; + } + + if (info->avdd_reg) { + regulator_put(info->avdd_reg); + info->avdd_reg = NULL; + } + + return retval; +} + +/** + * Enable or disable the power regulators + * @param info pointer to fts_ts_info which contains info about the device and its hw setup + * @param enable if 1, the power regulators are turned on otherwise they are turned off + * @return OK if success or an error code which specify the type of error encountered + */ +static int fts_enable_reg(struct fts_ts_info *info, bool enable) +{ + int retval; + + if (!enable) { + retval = 0; + goto disable_pwr_reg; + } + + if (info->vdd_reg) { + retval = regulator_enable(info->vdd_reg); + if (retval < 0) { + logError(1, "%s %s: Failed to enable bus regulator\n", + tag, __func__); + goto exit; + } + } + + if (info->avdd_reg) { + retval = regulator_enable(info->avdd_reg); + if (retval < 0) { + logError(1, "%s %s: Failed to enable power regulator\n", + tag, __func__); + goto disable_bus_reg; + } + } + + return OK; + +disable_pwr_reg: + if (info->avdd_reg) + regulator_disable(info->vdd_reg); + +disable_bus_reg: + if (info->vdd_reg) + regulator_disable(info->avdd_reg); + +exit: + return retval; +} + +/** + * Configure a GPIO according to the parameters + * @param gpio gpio number + * @param config if true, the gpio is set up otherwise it is free + * @param dir direction of the gpio, 0 = in, 1 = out + * @param state initial value (if the direction is in, this parameter is ignored) + * return error code + */ +static int fts_gpio_setup(int gpio, bool config, int dir, int state) +{ + int retval = 0; + unsigned char buf[16]; + + if (config) { + snprintf(buf, 16, "fts_gpio_%u\n", gpio); + + retval = gpio_request(gpio, buf); + if (retval) { + logError(1, "%s %s: Failed to get gpio %d (code: %d)", + tag, __func__, gpio, retval); + return retval; + } + + if (dir == 0) + retval = gpio_direction_input(gpio); + else + retval = gpio_direction_output(gpio, state); + if (retval) { + logError(1, "%s %s: Failed to set gpio %d direction", + tag, __func__, gpio); + return retval; + } + } else { + gpio_free(gpio); + } + + return retval; +} + +/** + * Setup the IRQ and RESET (if present) gpios. + * If the Reset Gpio is present it will perform a cycle HIGH-LOW-HIGH in order to assure that the IC has been reset properly + */ +static int fts_set_gpio(struct fts_ts_info *info) +{ + int retval; + struct fts_hw_platform_data *bdata = info->board; + + retval = fts_gpio_setup(bdata->irq_gpio, true, 0, 0); + if (retval < 0) { + logError(1, "%s %s: Failed to configure irq GPIO\n", tag, + __func__); + goto err_gpio_irq; + } + + if (bdata->reset_gpio >= 0) { + retval = fts_gpio_setup(bdata->reset_gpio, true, 1, 0); + if (retval < 0) { + logError(1, "%s %s: Failed to configure reset GPIO\n", + tag, __func__); + goto err_gpio_reset; + } + } + if (bdata->reset_gpio >= 0) { + gpio_set_value(bdata->reset_gpio, 0); + mdelay(10); + gpio_set_value(bdata->reset_gpio, 1); + } + + return OK; + +err_gpio_reset: + fts_gpio_setup(bdata->irq_gpio, false, 0, 0); + bdata->reset_gpio = GPIO_NOT_DEFINED; +err_gpio_irq: + return retval; +} + +static int fts_pinctrl_init(struct fts_ts_info *info) +{ + int retval = 0; + /* Get pinctrl if target uses pinctrl */ + info->ts_pinctrl = devm_pinctrl_get(info->dev); + + if (IS_ERR_OR_NULL(info->ts_pinctrl)) { + retval = PTR_ERR(info->ts_pinctrl); + dev_err(info->dev, "Target does not use pinctrl %d\n", retval); + goto err_pinctrl_get; + } + + info->pinctrl_state_active = + pinctrl_lookup_state(info->ts_pinctrl, PINCTRL_STATE_ACTIVE); + + if (IS_ERR_OR_NULL(info->pinctrl_state_active)) { + retval = PTR_ERR(info->pinctrl_state_active); + dev_err(info->dev, "Can not lookup %s pinstate %d\n", + PINCTRL_STATE_ACTIVE, retval); + goto err_pinctrl_lookup; + } + + info->pinctrl_state_suspend = + pinctrl_lookup_state(info->ts_pinctrl, PINCTRL_STATE_SUSPEND); + + if (IS_ERR_OR_NULL(info->pinctrl_state_suspend)) { + retval = PTR_ERR(info->pinctrl_state_suspend); + dev_dbg(info->dev, "Can not lookup %s pinstate %d\n", + PINCTRL_STATE_SUSPEND, retval); + goto err_pinctrl_lookup; + } + + return 0; +err_pinctrl_lookup: + devm_pinctrl_put(info->ts_pinctrl); +err_pinctrl_get: + info->ts_pinctrl = NULL; + return retval; +} + +/** + * Retrieve and parse the hw information from the device tree node defined in the system. + * the most important information to obtain are: IRQ and RESET gpio numbers, power regulator names + * In the device file node is possible to define additional optional information that can be parsed here. + */ +static int parse_dt(struct device *dev, struct fts_hw_platform_data *bdata) +{ + int retval; + const char *name; + struct device_node *temp, *np = dev->of_node; + struct fts_config_info *config_info; + u32 temp_val; + + bdata->irq_gpio = of_get_named_gpio_flags(np, "fts,irq-gpio", 0, NULL); + + logError(0, "%s irq_gpio = %d\n", tag, bdata->irq_gpio); + + retval = of_property_read_string(np, "fts,pwr-reg-name", &name); + if (retval == -EINVAL) + bdata->vdd_reg_name = NULL; + else if (retval < 0) + return retval; + else { + bdata->vdd_reg_name = name; + logError(0, "%s pwr_reg_name = %s\n", tag, name); + } + + retval = of_property_read_string(np, "fts,bus-reg-name", &name); + if (retval == -EINVAL) + bdata->avdd_reg_name = NULL; + else if (retval < 0) + return retval; + else { + bdata->avdd_reg_name = name; + logError(0, "%s bus_reg_name = %s\n", tag, name); + } + + if (of_property_read_bool(np, "fts,reset-gpio-enable")) { + bdata->reset_gpio = + of_get_named_gpio_flags(np, "fts,reset-gpio", 0, NULL); + logError(0, "%s reset_gpio =%d\n", tag, bdata->reset_gpio); + } else { + bdata->reset_gpio = GPIO_NOT_DEFINED; + } + + retval = of_property_read_u32(np, "fts,irq-flags", &temp_val); + if (retval < 0) + return retval; + else + bdata->irq_flags = temp_val; + retval = of_property_read_u32(np, "fts,x-max", &temp_val); + if (retval < 0) + bdata->x_max = X_AXIS_MAX; + else + bdata->x_max = temp_val; + + retval = of_property_read_u32(np, "fts,y-max", &temp_val); + if (retval < 0) + bdata->y_max = Y_AXIS_MAX; + else + bdata->y_max = temp_val; + retval = of_property_read_string(np, "fts,default-fw-name", + &bdata->default_fw_name); + +#ifdef CONFIG_FTS_TOUCH_COUNT_DUMP + bdata->dump_click_count = + of_property_read_bool(np, "fts,dump-click-count"); +#endif + retval = of_property_read_u32(np, "fts,config-array-size", + (u32 *)&bdata->config_array_size); + + if (retval) { + logError(1, "%s Unable to get array size\n", tag); + return retval; + } + + bdata->config_array = devm_kzalloc( + dev, bdata->config_array_size * sizeof(struct fts_config_info), + GFP_KERNEL); + + if (!bdata->config_array) { + logError(1, "%s Unable to allocate memory\n", tag); + return -ENOMEM; + } + + config_info = bdata->config_array; + for_each_child_of_node(np, temp) { + retval = of_property_read_u32(temp, "fts,tp-vendor", &temp_val); + + if (retval) { + logError(1, "%s Unable to read tp vendor\n", tag); + } else { + config_info->tp_vendor = (u8)temp_val; + logError(1, "%s %s:tp vendor: %u", tag, __func__, + config_info->tp_vendor); + } + retval = of_property_read_u32(temp, "fts,tp-color", &temp_val); + if (retval) { + logError(1, "%s Unable to read tp color\n", tag); + } else { + config_info->tp_color = (u8)temp_val; + logError(1, "%s %s:tp color: %u", tag, __func__, + config_info->tp_color); + } + + retval = of_property_read_u32(temp, "fts,tp-hw-version", + &temp_val); + + if (retval) { + logError(1, "%s Unable to read tp hw version\n", tag); + } else { + config_info->tp_hw_version = (u8)temp_val; + logError(1, "%s %s:tp color: %u", tag, __func__, + config_info->tp_hw_version); + } + + retval = of_property_read_string(temp, "fts,fw-name", + &config_info->fts_cfg_name); + + if (retval && (retval != -EINVAL)) { + logError(1, "%s Unable to read cfg name\n", tag); + } else { + logError(1, "%s %s:fw_name: %s", tag, __func__, + config_info->fts_cfg_name); + } + retval = of_property_read_string(temp, "fts,limit-name", + &config_info->fts_limit_name); + + if (retval && (retval != -EINVAL)) { + logError(1, "%s Unable to read limit name\n", tag); + } else { + logError(1, "%s %s:limit_name: %s", tag, __func__, + config_info->fts_limit_name); + } +#ifdef CONFIG_FTS_TOUCH_COUNT_DUMP + if (bdata->dump_click_count) { + retval = of_property_read_string( + temp, "fts,clicknum-file-name", + &config_info->clicknum_file_name); + if (retval && (retval != -EINVAL)) { + dev_err(dev, + "Unable to read click count file name\n"); + } else + dev_err(dev, "%s\n", + config_info->clicknum_file_name); + } +#endif + + config_info++; + } + return OK; +} + +static void fts_switch_mode_work(struct work_struct *work) +{ + struct fts_mode_switch *ms = + container_of(work, struct fts_mode_switch, switch_mode_work); + + struct fts_ts_info *info = ms->info; + unsigned char value = ms->mode; + static const char *fts_gesture_on = "01 20"; + char *gesture_result; + int size = 6 * 2 + 1; + char ch[16] = { + 0x0, + }; + + logError(1, "%s %s mode:%d\n", tag, __func__, value); + + if (value >= INPUT_EVENT_WAKUP_MODE_OFF && + value <= INPUT_EVENT_WAKUP_MODE_ON) { + info->gesture_enabled = value - INPUT_EVENT_WAKUP_MODE_OFF; + if (info->gesture_enabled) { + gesture_result = (u8 *)kzalloc(size, GFP_KERNEL); + if (gesture_result != NULL) { + fts_gesture_mask_store(info->dev, NULL, + fts_gesture_on, + strlen(fts_gesture_on)); + fts_gesture_mask_show(info->dev, NULL, + gesture_result); + if (strncmp("{ 00000000 }", gesture_result, + size - 1)) + logError( + 1, + "%s %s:store gesture mask error\n", + tag, __func__); + kfree(gesture_result); + gesture_result = NULL; + } + } + snprintf(ch, sizeof(ch), "%s", + (value - INPUT_EVENT_WAKUP_MODE_OFF) ? "enabled" : + "disabled"); + } else if (value >= INPUT_EVENT_COVER_MODE_OFF && + value <= INPUT_EVENT_COVER_MODE_ON) { + info->glove_enabled = value - INPUT_EVENT_COVER_MODE_OFF; + fts_mode_handler(info, 1); + } +#ifdef EDGEHOVER_FOR_VOLUME + if (value >= INPUT_EVENT_SLIDE_FOR_VOLUME && + value <= INPUT_EVENT_LONG_SINGLE_TAP_FOR_VOLUME) { + info->volume_type = value; + if (fts_info->volume_type == + INPUT_EVENT_SINGLE_TAP_FOR_VOLUME) { + fts_info->single_press_time_low = 30; + fts_info->single_press_time_hi = 800; + } else if (fts_info->volume_type == + INPUT_EVENT_LONG_SINGLE_TAP_FOR_VOLUME) { + fts_info->single_press_time_low = 300; + fts_info->single_press_time_hi = 800; + } + } +#endif +#ifdef PHONE_PALM + if (value >= INPUT_EVENT_PALM_OFF && value <= INPUT_EVENT_PALM_ON) + info->palm_enabled = value - INPUT_EVENT_PALM_OFF; +#endif + if (ms != NULL) { + kfree(ms); + ms = NULL; + } +} + +static int fts_input_event(struct input_dev *dev, unsigned int type, + unsigned int code, int value) +{ + struct fts_ts_info *info = input_get_drvdata(dev); + struct fts_mode_switch *ms; + + logError(1, "%s %s:set input event value = %d\n", tag, __func__, value); + + if (!info) { + printk("%s fts_ts_info is NULL\n", __func__); + return 0; + } + + if (type == EV_SYN && code == SYN_CONFIG) { + if (value >= INPUT_EVENT_START && value <= INPUT_EVENT_END) { + ms = (struct fts_mode_switch *)kmalloc( + sizeof(struct fts_mode_switch), GFP_ATOMIC); + + if (ms != NULL) { + ms->info = info; + ms->mode = (unsigned char)value; + INIT_WORK(&ms->switch_mode_work, + fts_switch_mode_work); + schedule_work(&ms->switch_mode_work); + } else { + logError( + 1, + "%s %s:failed in allocating memory for switching mode\n", + tag, __func__); + return -ENOMEM; + } + } else { + logError(1, "%s %s:Invalid event value\n", tag, + __func__); + return -EINVAL; + } + } + + return 0; +} + +static int fts_short_open_test(void) +{ + TestToDo selftests; + int res = -1; + int init_type = SPECIAL_PANEL_INIT; + + memset(&selftests, 0x00, sizeof(TestToDo)); + + /* Hover Test */ + selftests.SelfHoverForceRaw = 0; /* SS Hover Force Raw min/Max test */ + selftests.SelfHoverSenceRaw = 0; /* SS Hover Sence Raw min/Max test */ + selftests.SelfHoverForceIxTotal = + 0; /* SS Hover Total Force Ix min/Max (for each node)* test */ + selftests.SelfHoverSenceIxTotal = 0; + + selftests.MutualRawAdjITO = 0; + selftests.MutualRaw = 0; + selftests.MutualRawEachNode = 1; + selftests.MutualRawGap = 0; + selftests.MutualRawAdj = 0; + selftests.MutualRawLP = 0; + selftests.MutualRawGapLP = 0; + selftests.MutualRawAdjLP = 0; + selftests.MutualCx1 = 0; + selftests.MutualCx2 = 0; + selftests.MutualCx2Adj = 0; + selftests.MutualCxTotal = 0; + selftests.MutualCxTotalAdj = 0; + selftests.MutualCx1LP = 0; + selftests.MutualCx2LP = 0; + selftests.MutualCx2AdjLP = 0; + selftests.MutualCxTotalLP = 0; + selftests.MutualCxTotalAdjLP = 0; +#ifdef PHONE_KEY + selftests.MutualKeyRaw = 0; +#else + selftests.MutualKeyRaw = 0; +#endif + selftests.MutualKeyCx1 = 0; + selftests.MutualKeyCx2 = 0; +#ifdef PHONE_KEY + selftests.MutualKeyCxTotal = 0; +#else + selftests.MutualKeyCxTotal = 0; +#endif + selftests.SelfForceRaw = 1; + selftests.SelfForceRawGap = 0; + selftests.SelfForceRawLP = 0; + selftests.SelfForceRawGapLP = 0; + selftests.SelfForceIx1 = 0; + selftests.SelfForceIx2 = 0; + selftests.SelfForceIx2Adj = 0; + selftests.SelfForceIxTotal = 0; + selftests.SelfForceIxTotalAdj = 0; + selftests.SelfForceCx1 = 0; + selftests.SelfForceCx2 = 0; + selftests.SelfForceCx2Adj = 0; + selftests.SelfForceCxTotal = 0; + selftests.SelfForceCxTotalAdj = 0; + selftests.SelfSenseRaw = 1; + selftests.SelfSenseRawGap = 0; + selftests.SelfSenseRawLP = 0; + selftests.SelfSenseRawGapLP = 0; + selftests.SelfSenseIx1 = 0; + selftests.SelfSenseIx2 = 0; + selftests.SelfSenseIx2Adj = 0; + selftests.SelfSenseIxTotal = 0; + selftests.SelfSenseIxTotalAdj = 0; + selftests.SelfSenseCx1 = 0; + selftests.SelfSenseCx2 = 0; + selftests.SelfSenseCx2Adj = 0; + selftests.SelfSenseCxTotal = 0; + selftests.SelfSenseCxTotalAdj = 0; + + res = fts_disableInterrupt(); + if (res < 0) { + logError(0, "%s fts_disableInterrupt: ERROR %08X \n", tag, res); + res = (res | ERROR_DISABLE_INTER); + goto END; + } + res = production_test_main(LIMITS_FILE, 1, init_type, &selftests); +END: + fts_mode_handler(fts_info, 1); + fts_enableInterrupt(); + if (res == OK) + return FTS_RESULT_PASS; + else + return FTS_RESULT_FAIL; +} + +static int fts_i2c_test(void) +{ + int ret = 0; + u8 data[SYS_INFO_SIZE] = { 0 }; + + logError(0, "%s %s: Reading System Info...\n", tag, __func__); + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, + ADDR_FRAMEBUFFER, data, SYS_INFO_SIZE, + DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError( + 1, + "%s %s: error while reading the system data ERROR %08X\n", + tag, __func__, ret); + return FTS_RESULT_FAIL; + } + + return FTS_RESULT_PASS; +} + +static ssize_t fts_selftest_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + char tmp[5] = { 0 }; + int cnt; + + if (*pos != 0) + return 0; + cnt = snprintf(tmp, sizeof(fts_info->result_type), "%d\n", + fts_info->result_type); + if (copy_to_user(buf, tmp, strlen(tmp))) { + return -EFAULT; + } + *pos += cnt; + return cnt; +} + +static ssize_t fts_selftest_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + int retval = 0; + char tmp[6]; + + if (copy_from_user(tmp, buf, count)) { + retval = -EFAULT; + goto out; + } + + if (!strncmp("short", tmp, 5) || !strncmp("open", tmp, 4)) { + retval = fts_short_open_test(); + } else if (!strncmp("i2c", tmp, 3)) + retval = fts_i2c_test(); + + fts_info->result_type = retval; +out: + if (retval >= 0) + retval = count; + + return retval; +} + +static const struct file_operations fts_selftest_ops = { + .read = fts_selftest_read, + .write = fts_selftest_write, +}; + +static ssize_t fts_datadump_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + int ret = 0, cnt1 = 0, cnt2 = 0, cnt3 = 0; + char *tmp; + + if (*pos != 0) + return 0; + + tmp = vmalloc(PAGE_SIZE * 2); + if (tmp == NULL) + return 0; + else + memset(tmp, 0, PAGE_SIZE * 2); + + cnt1 = fts_strength_frame_show(fts_info->dev, NULL, tmp); + if (cnt1 == 0) { + ret = 0; + goto out; + } + + ret = stm_fts_cmd_store(fts_info->dev, NULL, "13", 2); + if (ret == 0) + goto out; + cnt2 = stm_fts_cmd_show(fts_info->dev, NULL, tmp + cnt1); + if (cnt2 == 0) { + ret = 0; + goto out; + } + + ret = stm_fts_cmd_store(fts_info->dev, NULL, "15", 2); + if (ret == 0) + goto out; + cnt3 = stm_fts_cmd_show(fts_info->dev, NULL, tmp + cnt1 + cnt2); + if (cnt3 == 0) { + ret = 0; + goto out; + } + + if (copy_to_user(buf, tmp, cnt1 + cnt2 + cnt3)) + ret = -EFAULT; + +out: + if (tmp) { + vfree(tmp); + tmp = NULL; + } + *pos += (cnt1 + cnt2 + cnt3); + if (ret <= 0) + return ret; + return cnt1 + cnt2 + cnt3; +} + +static const struct file_operations fts_datadump_ops = { + .read = fts_datadump_read, +}; + +#define TP_INFO_MAX_LENGTH 50 + +static ssize_t fts_fw_version_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + int cnt = 0, ret = 0; + char tmp[TP_INFO_MAX_LENGTH]; + + if (*pos != 0) + return 0; + + cnt = snprintf(tmp, TP_INFO_MAX_LENGTH, "%x.%x\n", systemInfo.u16_fwVer, + systemInfo.u16_cfgVer); + ret = copy_to_user(buf, tmp, cnt); + *pos += cnt; + if (ret != 0) + return 0; + else + return cnt; +} + +static const struct file_operations fts_fw_version_ops = { + .read = fts_fw_version_read, +}; + +static ssize_t fts_lockdown_info_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + int cnt = 0, ret = 0; + char tmp[TP_INFO_MAX_LENGTH]; + + if (*pos != 0) + return 0; + + ret = fts_get_lockdown_info(fts_info->lockdown_info, fts_info); + if (ret != OK) { + logError(1, "%s %s get lockdown info error\n", tag, __func__); + goto out; + } + + cnt = snprintf( + tmp, TP_INFO_MAX_LENGTH, + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", + fts_info->lockdown_info[0], fts_info->lockdown_info[1], + fts_info->lockdown_info[2], fts_info->lockdown_info[3], + fts_info->lockdown_info[4], fts_info->lockdown_info[5], + fts_info->lockdown_info[6], fts_info->lockdown_info[7]); + ret = copy_to_user(buf, tmp, cnt); +out: + *pos += cnt; + if (ret != 0) + return 0; + else + return cnt; +} + +static const struct file_operations fts_lockdown_info_ops = { + .read = fts_lockdown_info_read, +}; + +#ifdef CONFIG_PM +static int fts_pm_suspend(struct device *dev) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + +#ifndef CONFIG_FTS_FOD_AREA_REPORT + if (device_may_wakeup(dev) && info->gesture_enabled) { + logError(1, "%s enable touch irq wake\n", tag); + enable_irq_wake(info->client->irq); + } +#else + enable_irq_wake(info->client->irq); +#endif + info->tp_pm_suspend = true; + reinit_completion(&info->pm_resume_completion); + + return 0; +} + +static int fts_pm_resume(struct device *dev) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + +#ifndef CONFIG_FTS_FOD_AREA_REPORT + if (device_may_wakeup(dev) && info->gesture_enabled) { + logError(1, "%s disable touch irq wake\n", tag); + disable_irq_wake(info->client->irq); + } +#else + disable_irq_wake(info->client->irq); +#endif + info->tp_pm_suspend = false; + complete(&info->pm_resume_completion); + + return 0; +} + +static const struct dev_pm_ops fts_dev_pm_ops = { + .suspend = fts_pm_suspend, + .resume = fts_pm_resume, +}; +#endif + +#ifdef CONFIG_TOUCHSCREEN_ST_DEBUG_FS +static void tpdbg_shutdown(struct fts_ts_info *info, bool sleep) +{ + u8 settings[4] = { 0 }; + info->mode = MODE_NOTHING; + + if (sleep) { + logError(0, "%s %s: Sense OFF! \n", tag, __func__); + setScanMode(SCAN_MODE_ACTIVE, 0x00); + } else { + settings[0] = 0x01; + logError(0, "%s %s: Sense ON! \n", tag, __func__); + setScanMode(SCAN_MODE_ACTIVE, settings[0]); + info->mode |= (SCAN_MODE_ACTIVE << 24); + MODE_ACTIVE(info->mode, settings[0]); + } +} + +static void tpdbg_suspend(struct fts_ts_info *info, bool enable) +{ + if (enable) + queue_work(info->event_wq, &info->suspend_work); + else + queue_work(info->event_wq, &info->resume_work); +} + +static int tpdbg_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + + return 0; +} + +static ssize_t tpdbg_read(struct file *file, char __user *buf, size_t size, + loff_t *ppos) +{ + const char *str = "cmd support as below:\n \ + \necho \"irq-disable\" or \"irq-enable\" to ctrl irq\n \ + \necho \"tp-sd-en\" of \"tp-sd-off\" to ctrl panel in or off sleep mode\n \ + \necho \"tp-suspend-en\" or \"tp-suspend-off\" to ctrl panel in or off suspend status\n"; + + loff_t pos = *ppos; + int len = strlen(str); + + if (pos < 0) + return -EINVAL; + if (pos >= len) + return 0; + + if (copy_to_user(buf, str, len)) + return -EFAULT; + + *ppos = pos + len; + + return len; +} + +static ssize_t tpdbg_write(struct file *file, const char __user *buf, + size_t size, loff_t *ppos) +{ + struct fts_ts_info *info = file->private_data; + char *cmd = kzalloc(size + 1, GFP_KERNEL); + int ret = size; + + if (!cmd) + return -ENOMEM; + + if (copy_from_user(cmd, buf, size)) { + ret = -EFAULT; + goto out; + } + + cmd[size] = '\0'; + + if (!strncmp(cmd, "irq-disable", 11)) + disable_irq(info->client->irq); + else if (!strncmp(cmd, "irq-enable", 10)) + enable_irq(info->client->irq); + else if (!strncmp(cmd, "tp-sd-en", 8)) + tpdbg_shutdown(info, true); + else if (!strncmp(cmd, "tp-sd-off", 9)) + tpdbg_shutdown(info, false); + else if (!strncmp(cmd, "tp-suspend-en", 13)) + tpdbg_suspend(info, true); + else if (!strncmp(cmd, "tp-suspend-off", 14)) + tpdbg_suspend(info, false); +out: + kfree(cmd); + + return ret; +} + +static int tpdbg_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + + return 0; +} + +static const struct file_operations tpdbg_operations = { + .owner = THIS_MODULE, + .open = tpdbg_open, + .read = tpdbg_read, + .write = tpdbg_write, + .release = tpdbg_release, +}; +#endif + +#ifdef CONFIG_SECURE_TOUCH +int fts_secure_init(struct fts_ts_info *info) +{ + int ret; + struct fts_secure_info *scr_info = + kmalloc(sizeof(*scr_info), GFP_KERNEL); + if (!scr_info) { + logError(1, "%s %s alloc fts_secure_info failed\n", tag, + __func__); + return -ENOMEM; + } + + logError(1, "%s fts_secure_init\n", tag); + + mutex_init(&scr_info->palm_lock); + + init_completion(&scr_info->st_powerdown); + init_completion(&scr_info->st_irq_processed); + + atomic_set(&scr_info->st_enabled, 0); + atomic_set(&scr_info->st_pending_irqs, 0); + + info->secure_info = scr_info; + + ret = sysfs_create_file(&info->dev->kobj, + &dev_attr_secure_touch_enable.attr); + if (ret < 0) { + logError( + 1, + "%s %s create sysfs attribute secure_touch_enable failed\n", + tag, __func__); + goto err; + } + + ret = sysfs_create_file(&info->dev->kobj, &dev_attr_secure_touch.attr); + if (ret < 0) { + logError(1, + "%s %s create sysfs attribute secure_touch failed\n", + tag, __func__); + goto err; + } + + scr_info->fts_info = info; + scr_info->secure_inited = true; + + return 0; + +err: + kfree(scr_info); + info->secure_info = NULL; + return ret; +} + +void fts_secure_remove(struct fts_ts_info *info) +{ + struct fts_secure_info *scr_info = info->secure_info; + + sysfs_remove_file(&info->dev->kobj, &dev_attr_secure_touch_enable.attr); + sysfs_remove_file(&info->dev->kobj, &dev_attr_secure_touch.attr); + kfree(scr_info); +} + +#endif + +/** + * Probe function, called when the driver it is matched with a device with the same name compatible name + * This function allocate, initialize and define all the most important function and flow that are used by the driver to operate with the IC. + * It allocates device variables, initialize queues and schedule works, registers the IRQ handler, suspend/resume callbacks, registers the device to the linux input subsystem etc. + */ +#ifdef I2C_INTERFACE +static int fts_probe(struct i2c_client *client, const struct i2c_device_id *idp) +{ +#else +static int fts_probe(struct spi_device *client) +{ +#endif + + struct fts_ts_info *info = NULL; + int error = 0; + struct device_node *dp = client->dev.of_node; + int retval; + int skip_5_1 = 0; + u16 bus_type; + u8 *tp_maker; + + logError(1, "%s %s: driver ver: %s\n", tag, __func__, + FTS_TS_DRV_VERSION); + +#ifdef I2C_INTERFACE + logError(0, "%s I2C interface... \n", tag); + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + logError(1, "%s Unsupported I2C functionality\n", tag); + error = -EIO; + goto ProbeErrorExit_0; + } + + logError(0, "%s i2c address: %x \n", tag, client->addr); + bus_type = BUS_I2C; +#else + logError(0, "%s SPI interface... \n", tag); + client->mode = SPI_MODE_0; +#ifndef SPI4_WIRE + client->mode |= SPI_3WIRE; +#endif + client->max_speed_hz = SPI_CLOCK_FREQ; + client->bits_per_word = 8; + if (spi_setup(client) < 0) { + logError(1, "%s Unsupported SPI functionality\n", tag); + error = -EIO; + goto ProbeErrorExit_0; + } + bus_type = BUS_SPI; +#endif + + logError(0, "%s SET Device driver INFO: \n", tag); + + info = kzalloc(sizeof(struct fts_ts_info), GFP_KERNEL); + if (!info) { + logError( + 1, + "%s Out of memory... Impossible to allocate struct info!\n", + tag); + error = -ENOMEM; + goto ProbeErrorExit_0; + } + + fts_info = info; + info->client = client; + info->dev = &info->client->dev; + dev_set_drvdata(info->dev, info); + + if (dp) { + info->board = devm_kzalloc(&client->dev, + sizeof(struct fts_hw_platform_data), + GFP_KERNEL); + if (!info->board) { + logError(1, "%s ERROR:info.board kzalloc failed \n", + tag); + error = -ENOMEM; + goto ProbeErrorExit_1; + } + parse_dt(&client->dev, info->board); + } + + logError(0, "%s SET Regulators: \n", tag); + retval = fts_get_reg(info, true); + if (retval < 0) { + logError(1, "%s ERROR: %s: Failed to get regulators\n", tag, + __func__); + error = retval; + goto ProbeErrorExit_1; + } + + retval = fts_enable_reg(info, true); + if (retval < 0) { + logError(1, "%s %s: ERROR Failed to enable regulators\n", tag, + __func__); + error = retval; + goto ProbeErrorExit_2; + } + + logError(0, "%s SET GPIOS: \n", tag); + retval = fts_set_gpio(info); + if (retval < 0) { + logError(1, "%s %s: ERROR Failed to set up GPIO's\n", tag, + __func__); + error = retval; + goto ProbeErrorExit_2; + } + + error = fts_pinctrl_init(info); + + if (!error && info->ts_pinctrl) { + error = pinctrl_select_state(info->ts_pinctrl, + info->pinctrl_state_active); + + if (error < 0) { + dev_err(&client->dev, + "%s: Failed to select %s pinstate %d\n", + __func__, PINCTRL_STATE_ACTIVE, error); + } + } else { + dev_err(&client->dev, "%s: Failed to init pinctrl\n", __func__); + } + + info->client->irq = gpio_to_irq(info->board->irq_gpio); + + logError(0, "%s SET Event Handler: \n", tag); + + info->event_wq = + alloc_workqueue("fts-event-queue", + WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); + if (!info->event_wq) { + logError(1, "%s ERROR: Cannot create work thread\n", tag); + error = -ENOMEM; + goto ProbeErrorExit_4; + } + + info->irq_wq = alloc_workqueue( + "fts-irq-queue", WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); + if (!info->irq_wq) { + logError(1, "%s ERROR: Cannot create irq work thread\n", tag); + error = -ENOMEM; + goto ProbeErrorExit_4; + } + + INIT_WORK(&info->resume_work, fts_resume_work); + INIT_WORK(&info->suspend_work, fts_suspend_work); + INIT_WORK(&info->sleep_work, fts_ts_sleep_work); + init_completion(&info->tp_reset_completion); +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + init_waitqueue_head(&info->wait_queue); +#endif + logError(0, "%s SET Input Device Property: \n", tag); + info->dev = &info->client->dev; + info->input_dev = input_allocate_device(); + if (!info->input_dev) { + logError(1, "%s ERROR: No such input device defined! \n", tag); + error = -ENODEV; + goto ProbeErrorExit_5; + } + info->input_dev->dev.parent = &client->dev; + info->input_dev->name = FTS_TS_DRV_NAME; + snprintf(fts_ts_phys, sizeof(fts_ts_phys), "%s/input0", + info->input_dev->name); + info->input_dev->phys = fts_ts_phys; + info->input_dev->id.bustype = bus_type; + info->input_dev->id.vendor = 0x0001; + info->input_dev->id.product = 0x0002; + info->input_dev->id.version = 0x0100; + info->input_dev->event = fts_input_event; + input_set_drvdata(info->input_dev, info); + + __set_bit(EV_SYN, info->input_dev->evbit); + __set_bit(EV_KEY, info->input_dev->evbit); + __set_bit(EV_ABS, info->input_dev->evbit); + __set_bit(BTN_TOUCH, info->input_dev->keybit); + __set_bit(BTN_TOOL_FINGER, info->input_dev->keybit); + /*__set_bit(BTN_TOOL_PEN, info->input_dev->keybit);*/ + + input_mt_init_slots(info->input_dev, TOUCH_ID_MAX, INPUT_MT_DIRECT); + + /*input_mt_init_slots(info->input_dev, TOUCH_ID_MAX); */ + + input_set_abs_params(info->input_dev, ABS_MT_POSITION_X, X_AXIS_MIN, + info->board->x_max - 1, 0, 0); + input_set_abs_params(info->input_dev, ABS_MT_POSITION_Y, Y_AXIS_MIN, + info->board->y_max - 1, 0, 0); + input_set_abs_params(info->input_dev, ABS_MT_TOUCH_MAJOR, AREA_MIN, + AREA_MAX, 0, 0); + input_set_abs_params(info->input_dev, ABS_MT_TOUCH_MINOR, AREA_MIN, + AREA_MAX, 0, 0); + input_set_abs_params(info->input_dev, ABS_MT_WIDTH_MINOR, AREA_MIN, + AREA_MAX, 0, 0); + input_set_abs_params(info->input_dev, ABS_MT_WIDTH_MAJOR, AREA_MIN, + AREA_MAX, 0, 0); + +#ifdef CONFIG_FTS_FOD_AREA_REPORT + /*input_set_abs_params(info->input_dev, ABS_MT_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0);*/ +#endif + input_set_abs_params(info->input_dev, ABS_MT_DISTANCE, DISTANCE_MIN, + DISTANCE_MAX, 0, 0); + +#ifdef GESTURE_MODE + input_set_capability(info->input_dev, EV_KEY, KEY_WAKEUP); + + input_set_capability(info->input_dev, EV_KEY, KEY_M); + input_set_capability(info->input_dev, EV_KEY, KEY_O); + input_set_capability(info->input_dev, EV_KEY, KEY_E); + input_set_capability(info->input_dev, EV_KEY, KEY_W); + input_set_capability(info->input_dev, EV_KEY, KEY_C); + input_set_capability(info->input_dev, EV_KEY, KEY_L); + input_set_capability(info->input_dev, EV_KEY, KEY_F); + input_set_capability(info->input_dev, EV_KEY, KEY_V); + input_set_capability(info->input_dev, EV_KEY, KEY_S); + input_set_capability(info->input_dev, EV_KEY, KEY_Z); + input_set_capability(info->input_dev, EV_KEY, KEY_WWW); + + input_set_capability(info->input_dev, EV_KEY, KEY_LEFT); + input_set_capability(info->input_dev, EV_KEY, KEY_RIGHT); + input_set_capability(info->input_dev, EV_KEY, KEY_UP); + input_set_capability(info->input_dev, EV_KEY, KEY_DOWN); + + input_set_capability(info->input_dev, EV_KEY, KEY_F1); + input_set_capability(info->input_dev, EV_KEY, KEY_F2); + input_set_capability(info->input_dev, EV_KEY, KEY_F3); + input_set_capability(info->input_dev, EV_KEY, KEY_F4); + input_set_capability(info->input_dev, EV_KEY, KEY_F5); + + input_set_capability(info->input_dev, EV_KEY, KEY_LEFTBRACE); + input_set_capability(info->input_dev, EV_KEY, KEY_RIGHTBRACE); +#endif + +#ifdef PHONE_KEY + /*KEY associated to the touch screen buttons */ + input_set_capability(info->input_dev, EV_KEY, KEY_HOMEPAGE); + input_set_capability(info->input_dev, EV_KEY, KEY_BACK); + input_set_capability(info->input_dev, EV_KEY, KEY_MENU); +#endif +#ifdef CONFIG_FTS_FOD_AREA_REPORT + input_set_capability(info->input_dev, EV_KEY, BTN_INFO); + input_set_capability(info->input_dev, EV_KEY, KEY_INFO); + input_set_capability(info->input_dev, EV_KEY, KEY_GOTO); +#endif + mutex_init(&(info->input_report_mutex)); +#ifdef GESTURE_MODE + mutex_init(&gestureMask_mutex); +#endif + + spin_lock_init(&fts_int); + + /* register the multi-touch input device */ + error = input_register_device(info->input_dev); + if (error) { + logError(1, "%s ERROR: No such input device\n", tag); + error = -ENODEV; + goto ProbeErrorExit_5_1; + } + + skip_5_1 = 1; + /* track slots */ + info->touch_id = 0; +#ifdef STYLUS_MODE + info->stylus_id = 0; +#endif + + /* init feature switches (by default all the features are disable, if one feature want to be enabled from the start, set the corresponding value to 1) */ + info->gesture_enabled = 0; + info->glove_enabled = 0; + info->charger_enabled = 0; + info->cover_enabled = 0; + info->grip_enabled = 0; + info->grip_pixel_def = 30; + info->grip_pixel = info->grip_pixel_def; + + info->resume_bit = 1; + info->lockdown_is_ok = false; +#ifdef CONFIG_DRM + info->notifier = fts_noti_block; +#endif + info->bl_notifier = fts_bl_noti_block; + logError(0, "%s Init Core Lib: \n", tag); + initCore(info); + /* init hardware device */ + logError(0, "%s Device Initialization: \n", tag); + error = fts_init(info); + if (error < OK) { + logError(1, "%s Cannot initialize the device ERROR %08X\n", tag, + error); + error = -ENODEV; + goto ProbeErrorExit_6; + } + +#ifdef CONFIG_SECURE_TOUCH + logError(1, "%s %s create secure touch file...\n", tag, __func__); + error = fts_secure_init(info); + if (error < 0) { + logError(1, "%s %s init secure touch failed\n", tag, __func__); + goto ProbeErrorExit_7; + } + logError(1, "%s %s create secure touch file successful\n", tag, + __func__); + fts_secure_stop(info, 1); +#endif + +#ifdef CONFIG_I2C_BY_DMA + /*dma buf init*/ + info->dma_buf = (struct fts_dma_buf *)kzalloc(sizeof(*info->dma_buf), + GFP_KERNEL); + if (!info->dma_buf) { + logError(1, "%s %s:ERROR alloc mem failed!", tag, __func__); + goto ProbeErrorExit_7; + } + mutex_init(&info->dma_buf->dmaBufLock); + info->dma_buf->rdBuf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!info->dma_buf->rdBuf) { + logError(1, "%s %s:ERROR alloc mem failed!", tag, __func__); + goto ProbeErrorExit_7; + } + info->dma_buf->wrBuf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!info->dma_buf->wrBuf) { + logError(1, "%s %s:ERROR alloc mem failed!", tag, __func__); + goto ProbeErrorExit_7; + } +#endif + + error = fts_get_lockdown_info(info->lockdown_info, info); + + if (error < OK) + logError(1, "%s can't get lockdown info", tag); + else { + logError( + 1, + "%s Lockdown:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", + tag, info->lockdown_info[0], info->lockdown_info[1], + info->lockdown_info[2], info->lockdown_info[3], + info->lockdown_info[4], info->lockdown_info[5], + info->lockdown_info[6], info->lockdown_info[7]); + info->lockdown_is_ok = true; + } + +#ifdef FW_UPDATE_ON_PROBE + logError(1, "%s FW Update and Sensing Initialization: \n", tag); + error = fts_fw_update(info, NULL, 0); + if (error < OK) { + logError(1, + "%s Cannot execute fw upgrade the device ERROR %08X\n", + tag, error); + error = -ENODEV; + goto ProbeErrorExit_7; + } +#else + logError(0, "%s SET Auto Fw Update: \n", tag); + info->fwu_workqueue = alloc_workqueue( + "fts-fwu-queue", WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); + if (!info->fwu_workqueue) { + logError(1, "%s ERROR: Cannot create fwu work thread\n", tag); + goto ProbeErrorExit_7; + } + INIT_DELAYED_WORK(&info->fwu_work, fts_fw_update_auto); +#endif + info->sensor_scan = true; + + logError(0, "%s SET Device File Nodes: \n", tag); + /* sysfs stuff */ + info->attrs.attrs = fts_attr_group; + error = sysfs_create_group(&client->dev.kobj, &info->attrs); + if (error) { + logError(1, "%s ERROR: Cannot create sysfs structure!\n", tag); + error = -ENODEV; + goto ProbeErrorExit_7; + } + + error = fts_proc_init(); + if (error < OK) + logError(1, "%s Error: can not create /proc file! \n", tag); + info->dbclick_count = 0; + + tp_maker = kzalloc(20, GFP_KERNEL); + if (tp_maker == NULL) + logError(1, "%s fail to alloc vendor name memory\n", tag); + else { + kfree(tp_maker); + tp_maker = NULL; + } + device_init_wakeup(&client->dev, 1); + init_completion(&info->pm_resume_completion); +/* + if (backlight_register_notifier(&info->bl_notifier) < 0) { + logError(1, "%s register bl_notifier failed!\n", tag); + } +*/ +#ifdef CONFIG_TOUCHSCREEN_ST_DEBUG_FS + info->debugfs = debugfs_create_dir("tp_debug", NULL); + if (info->debugfs) { + debugfs_create_file("switch_state", 0660, info->debugfs, info, + &tpdbg_operations); + } +#endif + + if (info->fts_tp_class == NULL) +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + info->fts_tp_class = get_xiaomi_touch_class(); +#else + info->fts_tp_class = class_create(THIS_MODULE, "touch"); +#endif + info->fts_touch_dev = + device_create(info->fts_tp_class, NULL, 0x49, info, "tp_dev"); + + if (IS_ERR(info->fts_touch_dev)) { + logError(1, + "%s ERROR: Failed to create device for the sysfs!\n", + tag); + goto ProbeErrorExit_8; + } + + dev_set_drvdata(info->fts_touch_dev, info); +#ifdef CONFIG_FTS_TOUCH_COUNT_DUMP + error = sysfs_create_file(&info->fts_touch_dev->kobj, + &dev_attr_touch_suspend_notify.attr); + + if (error) { + logError(1, "%s ERROR: Failed to create sysfs group!\n", tag); + goto ProbeErrorExit_8; + } +#endif +#ifdef CONFIG_FTS_FOD_AREA_REPORT + mutex_init(&(info->fod_mutex)); + + error = sysfs_create_file(&info->fts_touch_dev->kobj, + &dev_attr_fod_status.attr); + if (error) { + logError(1, + "%s ERROR: Failed to create fod_status sysfs group!\n", + tag); + } + error = sysfs_create_file(&info->fts_touch_dev->kobj, + &dev_attr_fod_test.attr); + if (error) { + logError(1, + "%s ERROR: Failed to create fod_test sysfs group!\n", + tag); + } +#endif + info->tp_lockdown_info_proc = proc_create("tp_lockdown_info", 0444, + NULL, &fts_lockdown_info_ops); + info->tp_selftest_proc = + proc_create("tp_selftest", 0644, NULL, &fts_selftest_ops); + info->tp_data_dump_proc = + proc_create("tp_data_dump", 0444, NULL, &fts_datadump_ops); + info->tp_fw_version_proc = + proc_create("tp_fw_version", 0444, NULL, &fts_fw_version_ops); + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + info->touch_feature_wq = + alloc_workqueue("fts-touch-feature", + WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); + if (!info->touch_feature_wq) { + logError(1, + "%s ERROR: Cannot create touch feature work thread\n", + tag); + goto ProbeErrorExit_8; + } + INIT_WORK(&info->cmd_update_work, fts_cmd_update_work); + mutex_init(&info->cmd_update_mutex); + memset(&xiaomi_touch_interfaces, 0x00, + sizeof(struct xiaomi_touch_interface)); + xiaomi_touch_interfaces.getModeValue = fts_get_mode_value; + xiaomi_touch_interfaces.setModeValue = fts_set_cur_value; + xiaomi_touch_interfaces.resetMode = fts_reset_mode; + xiaomi_touch_interfaces.getModeAll = fts_get_mode_all; + xiaomi_touch_interfaces.p_sensor_write = fts_palm_sensor_write; + xiaomi_touch_interfaces.palm_sensor_write = fts_palm_sensor_write; + xiaomitouch_register_modedata(&xiaomi_touch_interfaces); + fts_read_touchmode_data(); + fts_init_touchmode_data(); +#endif +#ifndef FW_UPDATE_ON_PROBE + queue_delayed_work(info->fwu_workqueue, &info->fwu_work, + msecs_to_jiffies(EXP_FN_WORK_DELAY_MS)); +#endif + + logError(1, "%s Probe Finished! \n", tag); + return OK; +#ifdef CONFIG_FTS_TOUCH_COUNT_DUMP +ProbeErrorExit_8: + device_destroy(info->fts_tp_class, 0x49); + class_destroy(info->fts_tp_class); + info->fts_tp_class = NULL; +#endif +ProbeErrorExit_7: +#ifdef CONFIG_SECURE_TOUCH + fts_secure_remove(info); +#endif +#ifdef CONFIG_I2C_BY_DMA + if (info->dma_buf) + kfree(info->dma_buf); + if (info->dma_buf->rdBuf) + kfree(info->dma_buf->rdBuf); + if (info->dma_buf->wrBuf) + kfree(info->dma_buf->wrBuf); +#endif +#ifdef CONFIG_DRM + drm_unregister_client(&info->notifier); +#endif + +ProbeErrorExit_6: + input_unregister_device(info->input_dev); + +ProbeErrorExit_5_1: + if (skip_5_1 != 1) + input_free_device(info->input_dev); + +ProbeErrorExit_5: + destroy_workqueue(info->event_wq); + +ProbeErrorExit_4: + fts_enable_reg(info, false); + +ProbeErrorExit_2: + fts_get_reg(info, false); + +ProbeErrorExit_1: + kfree(info); + +ProbeErrorExit_0: + logError(1, "%s Probe Failed!\n", tag); + + return error; +} + +/** + * Clear and free all the resources associated to the driver. + * This function is called when the driver need to be removed. + */ +#ifdef I2C_INTERFACE +static int fts_remove(struct i2c_client *client) +{ +#else +static int fts_remove(struct spi_device *client) +{ +#endif + + struct fts_ts_info *info = dev_get_drvdata(&(client->dev)); + + fts_proc_remove(); + /* sysfs stuff */ + sysfs_remove_group(&client->dev.kobj, &info->attrs); + /* remove interrupt and event handlers */ + fts_interrupt_uninstall(info); + /*backlight_unregister_notifier(&info->bl_notifier);*/ +#ifdef CONFIG_DRM + drm_unregister_client(&info->notifier); +#endif + + /* unregister the device */ + input_unregister_device(info->input_dev); + + /* Remove the work thread */ + destroy_workqueue(info->event_wq); +#ifndef FW_UPDATE_ON_PROBE + destroy_workqueue(info->fwu_workqueue); +#endif +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + destroy_workqueue(info->touch_feature_wq); +#endif +#ifdef CONFIG_FTS_TOUCH_COUNT_DUMP + if (info->board->dump_click_count && !info->current_clicknum_file) { + kfree(info->current_clicknum_file); + info->current_clicknum_file = NULL; + } + sysfs_remove_file(&info->fts_touch_dev->kobj, + &dev_attr_touch_suspend_notify.attr); + device_destroy(info->fts_tp_class, DCHIP_ID_0); + class_destroy(info->fts_tp_class); + info->fts_tp_class = NULL; +#endif + + fts_enable_reg(info, false); + fts_get_reg(info, false); + fts_info = NULL; +#ifdef CONFIG_SECURE_TOUCH + fts_secure_remove(info); +#endif + /* free all */ + kfree(info); + + return OK; +} + +/** +* Struct which contains the compatible names that need to match with the definition of the device in the device tree node +*/ +static struct of_device_id fts_of_match_table[] = { + { + .compatible = "st,fts", + }, + {}, +}; + +#ifdef I2C_INTERFACE +static const struct i2c_device_id fts_device_id[] = { { FTS_TS_DRV_NAME, 0 }, + {} }; + +static struct i2c_driver fts_i2c_driver = { + .driver = { + .name = FTS_TS_DRV_NAME, + .of_match_table = fts_of_match_table, +#ifdef CONFIG_PM + .pm = &fts_dev_pm_ops, +#endif + }, + .probe = fts_probe, + .remove = fts_remove, + .id_table = fts_device_id, +}; +#else +static struct spi_driver fts_spi_driver = { + .driver = { + .name = FTS_TS_DRV_NAME, + .of_match_table = fts_of_match_table, + .owner = THIS_MODULE, + }, + .probe = fts_probe, + .remove = fts_remove, +}; +#endif + +static int __init fts_driver_init(void) +{ +#ifdef I2C_INTERFACE + return i2c_add_driver(&fts_i2c_driver); +#else + return spi_register_driver(&fts_spi_driver); +#endif +} + +static void __exit fts_driver_exit(void) +{ +#ifdef I2C_INTERFACE + i2c_del_driver(&fts_i2c_driver); +#else + spi_unregister_driver(&fts_spi_driver); +#endif +} + +MODULE_DESCRIPTION("STMicroelectronics MultiTouch IC Driver"); +MODULE_AUTHOR("STMicroelectronics"); +MODULE_LICENSE("GPL"); + +late_initcall(fts_driver_init); +module_exit(fts_driver_exit); diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts.h b/drivers/input/touchscreen/xiaomi/fts_521/fts.h new file mode 100644 index 000000000000..0e5522d2e7b8 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts.h @@ -0,0 +1,397 @@ +/* + * fts.c + * + * FTS Capacitive touch screen controller (FingerTipS) + * + * Copyright (C) 2017, STMicroelectronics + * Copyright (C) 2019 XiaoMi, Inc. + * Authors: AMG(Analog Mems Group) + * + * marco.cali@st.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THE PRESENT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, FOR THE SOLE + * PURPOSE TO SUPPORT YOUR APPLICATION DEVELOPMENT. + * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, + * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE + * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING + * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS. + */ + +/*! +* \file fts.h +* \brief Contains all the definitions and structs used generally by the driver +*/ + +#ifndef _LINUX_FTS_I2C_H_ +#define _LINUX_FTS_I2C_H_ + +#include +#include +#include +#include +#include "fts_lib/ftsSoftware.h" +#include "fts_lib/ftsHardware.h" +#include +/****************** CONFIGURATION SECTION ******************/ +/** @defgroup conf_section Driver Configuration Section +* Settings of the driver code in order to suit the HW set up and the application behavior +* @{ +*/ + +/**** CODE CONFIGURATION ****/ +#define FTS_TS_DRV_NAME "fts" /*driver name*/ +#define FTS_TS_DRV_VERSION "5.2.4" /*driver version string format*/ +#define FTS_TS_DRV_VER 0x05020400 /*driver version u32 format*/ + +#define PINCTRL_STATE_ACTIVE "pmx_ts_active" +#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend" +#define PINCTRL_STATE_RELEASE "pmx_ts_release" + +#define DRIVER_TEST + +#define PRE_SAVED_METHOD + +/*#define FW_H_FILE*/ +#define FW_UPDATE_ON_PROBE +#ifdef FW_H_FILE +#define FW_SIZE_NAME myArray_size +#define FW_ARRAY_NAME myArray +#endif + +/*#define LIMITS_H_FILE*/ +#ifdef LIMITS_H_FILE +#define LIMITS_SIZE_NAME myArray2_size +#define LIMITS_ARRAY_NAME myArray2 +#endif + +/*#define USE_ONE_FILE_NODE*/ + +#ifndef FW_UPDATE_ON_PROBE +#define EXP_FN_WORK_DELAY_MS 1000 +#endif + +/**** END ****/ + +/**** FEATURES USED IN THE IC ****/ + +/*#define PHONE_KEY*/ + +#define GESTURE_MODE +#ifdef GESTURE_MODE +#define USE_GESTURE_MASK +#endif + +#define CHARGER_MODE + +#define GLOVE_MODE + +#define COVER_MODE + +#define STYLUS_MODE + +/**** END ****/ + +/**** PANEL SPECIFICATION ****/ +#define X_AXIS_MAX 1080 +#define X_AXIS_MIN 0 +#define Y_AXIS_MAX 2340 +#define Y_AXIS_MIN 0 + +#define PRESSURE_MIN 0 +#ifdef CONFIG_INPUT_PRESS_NDT +#define PRESSURE_MAX 2048 +#else +#define PRESSURE_MAX 127 +#endif + +#define DISTANCE_MIN 0 +#define DISTANCE_MAX 127 + +#define TOUCH_ID_MAX 10 + +#define AREA_MIN PRESSURE_MIN +#define AREA_MAX PRESSURE_MAX +/**** END ****/ +/**@}*/ +/*********************************************************/ + +/* + * Configuration mode + * + * bitmask which can assume the value defined as features in ftsSoftware.h or the following values + */ + +/** @defgroup mode_section IC Status Mode +* Bitmask which keeps track of the features and working mode enabled in the IC. +* The meaning of the the LSB of the bitmask must be interpreted considering that the value defined in @link feat_opt Feature Selection Option @endlink correspond to the position of the corresponding bit in the mask +* @{ +*/ +#define MODE_NOTHING 0x00000000 +#define MODE_ACTIVE(_mask, _sett) \ + do { \ + _mask |= (SCAN_MODE_ACTIVE << 24) | (_sett << 16); \ + } while (0) +#define MODE_LOW_POWER(_mask, _sett) \ + do { \ + _mask |= (SCAN_MODE_LOW_POWER << 24) | (_sett << 16); \ + } while (0) +/** @}*/ + +#define CMD_STR_LEN 32 + +#define TSP_BUF_SIZE PAGE_SIZE + +#define CONFIG_FTS_TOUCH_COUNT_DUMP + +#ifdef CONFIG_FTS_TOUCH_COUNT_DUMP +#define TOUCH_COUNT_FILE_MAXSIZE 50 +#endif + +/** + * Struct which contains information about the HW platform and set up + */ +#define FTS_LOCKDOWN_SIZE 8 +#define FTS_RESULT_INVALID 0 +#define FTS_RESULT_PASS 2 +#define FTS_RESULT_FAIL 1 + +struct fts_config_info { + u8 tp_vendor; + u8 tp_color; + u8 tp_hw_version; + const char *fts_cfg_name; + const char *fts_limit_name; +#ifdef CONFIG_FTS_TOUCH_COUNT_DUMP + const char *clicknum_file_name; +#endif +}; + +struct fts_hw_platform_data { + int (*power)(bool on); + int irq_gpio; + int reset_gpio; + unsigned long irq_flags; + unsigned int x_max; + unsigned int y_max; + const char *vdd_reg_name; + const char *avdd_reg_name; + const char *default_fw_name; + size_t config_array_size; + struct fts_config_info *config_array; + int current_index; +#ifdef PHONE_KEY + size_t nbuttons; + int *key_code; +#endif +#ifdef CONFIG_FTS_TOUCH_COUNT_DUMP + bool dump_click_count; +#endif + unsigned long keystates; +}; + +/* + * Forward declaration + */ +struct fts_ts_info; +extern char tag[8]; + +/* + * Dispatch event handler + */ +typedef void (*event_dispatch_handler_t)(struct fts_ts_info *info, + unsigned char *data); + +#ifdef CONFIG_SECURE_TOUCH +struct fts_secure_delay { + bool palm_pending; + int palm_value; +}; + +struct fts_secure_info { + bool secure_inited; + atomic_t st_1st_complete; + atomic_t st_enabled; + atomic_t st_pending_irqs; + struct completion st_irq_processed; + struct completion st_powerdown; + struct fts_secure_delay scr_delay; + struct mutex palm_lock; + void *fts_info; +}; +#endif + +#ifdef CONFIG_I2C_BY_DMA +struct fts_dma_buf { + struct mutex dmaBufLock; + u8 *rdBuf; + u8 *wrBuf; +}; +#endif + +/** + * FTS capacitive touch screen device information + * - dev Pointer to the structure device \n + * - client client structure \n + * - input_dev Input device structure \n + * - work Work thread \n + * - event_wq Event queue for work thread \n + * - event_dispatch_table Event dispatch table handlers \n + * - attrs SysFS attributes \n + * - mode Device operating mode (bitmask) \n + * - touch_id Bitmask for touch id (mapped to input slots) \n + * - stylus_id Bitmask for tracking the stylus touches (mapped using the touchId) \n + * - timer Timer when operating in polling mode \n + * - power Power on/off routine \n + * - board HW info retrieved from device tree \n + * - vdd_reg DVDD power regulator \n + * - avdd_reg AVDD power regulator \n + * - resume_bit Indicate if screen off/on \n + * - fwupdate_stat Store the result of a fw update triggered by the host \n + * - notifier Used for be notified from a suspend/resume event \n + * - sensor_sleep true suspend was called, false resume was called \n + * - wakelock Wake Lock struct \n + * - input_report_mutex mutex for handling the pressure of keys \n + * - series_of_switches to store the enabling status of a particular feature from the host \n + */ +struct fts_ts_info { + struct device *dev; +#ifdef I2C_INTERFACE + struct i2c_client *client; +#else + struct spi_device *client; +#endif + struct input_dev *input_dev; + + struct work_struct work; + struct work_struct suspend_work; + struct work_struct resume_work; + struct work_struct cmd_update_work; + struct work_struct sleep_work; + struct workqueue_struct *event_wq; + struct workqueue_struct *irq_wq; + struct workqueue_struct *touch_feature_wq; + +#ifndef FW_UPDATE_ON_PROBE + struct delayed_work fwu_work; + struct workqueue_struct *fwu_workqueue; +#endif + event_dispatch_handler_t *event_dispatch_table; + + struct attribute_group attrs; + + unsigned int mode; + unsigned long touch_id; + unsigned long sleep_finger; + unsigned long touch_skip; + int coor[TOUCH_ID_MAX][2]; +#ifdef STYLUS_MODE + unsigned long stylus_id; +#endif + struct fts_hw_platform_data *board; + struct regulator *vdd_reg; + struct regulator *avdd_reg; + + int resume_bit; + int fwupdate_stat; + + struct notifier_block notifier; + struct notifier_block bl_notifier; + bool sensor_sleep; + bool sensor_scan; + struct pinctrl *ts_pinctrl; + struct pinctrl_state *pinctrl_state_active; + struct pinctrl_state *pinctrl_state_suspend; + u8 lockdown_info[FTS_LOCKDOWN_SIZE]; + int result_type; + struct proc_dir_entry *tp_selftest_proc; + struct proc_dir_entry *tp_data_dump_proc; + struct proc_dir_entry *tp_fw_version_proc; + struct proc_dir_entry *tp_lockdown_info_proc; + + /* input lock */ + struct mutex input_report_mutex; + int gesture_enabled; + int glove_enabled; + int charger_enabled; + int stylus_enabled; + int cover_enabled; + unsigned int grip_enabled; + unsigned int grip_pixel; + unsigned int doze_time; + unsigned int grip_pixel_def; + unsigned int doze_time_def; +#ifdef CONFIG_TOUCHSCREEN_ST_DEBUG_FS + struct dentry *debugfs; +#endif + int dbclick_count; +#ifdef CONFIG_FTS_TOUCH_COUNT_DUMP + struct class *fts_tp_class; + struct device *fts_touch_dev; + char *current_clicknum_file; +#endif +#ifdef CONFIG_SECURE_TOUCH + struct fts_secure_info *secure_info; +#endif +#ifdef CONFIG_I2C_BY_DMA + struct fts_dma_buf *dma_buf; +#endif + bool lockdown_is_ok; + bool irq_status; + wait_queue_head_t wait_queue; + struct completion tp_reset_completion; + atomic_t system_is_resetting; + unsigned int fod_status; + unsigned int fod_overlap; + unsigned long fod_id; + unsigned long fod_x; + unsigned long fod_y; + struct mutex fod_mutex; + struct mutex cmd_update_mutex; + bool fod_coordinate_update; + bool fod_status_set; + bool fod_pressed; + bool p_sensor_changed; + bool p_sensor_switch; + bool palm_sensor_changed; + bool palm_sensor_switch; + bool tp_pm_suspend; + struct completion pm_resume_completion; +}; + +struct fts_mode_switch { + struct fts_ts_info *info; + unsigned char mode; + struct work_struct switch_mode_work; +}; + +int fts_chip_powercycle(struct fts_ts_info *info); +extern int input_register_notifier_client(struct notifier_block *nb); +extern int input_unregister_notifier_client(struct notifier_block *nb); + +extern int fts_proc_init(void); +extern int fts_proc_remove(void); +#ifdef CONFIG_FTS_FOD_AREA_REPORT +#define CENTER_X 540 +#define CENTER_Y 2005 +#define CIRCLE_R 87 +#define FOD_LX 420 +#define FOD_LY 1885 +#define FOD_SIDE 242 +bool fts_is_infod(void); +void fts_get_pointer(int *touch_flag, int *x, int *y); +#endif +void fts_restore_regvalues(void); + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE +int fts_palm_sensor_cmd(int input); +int fts_p_sensor_cmd(int input); +bool fts_touchmode_edgefilter(unsigned int touch_id, int x, int y); +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_fw.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_fw.h new file mode 100644 index 000000000000..01d095959445 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_fw.h @@ -0,0 +1,8387 @@ +/*! +* \file fts_fw.h +* \brief Contains the size and the byte array of the fw file to burn into the IC +*/ +#ifndef FTS_FW_H +#define FTS_FW_H +/*This is an auto generated header file*/ +/*--->Remember to change the name of the two variables!<---*/ +const uint32_t myArray_size = 100476; + +const uint8_t myArray[] = { + 0x55, 0xAA, 0x55, 0xAA, 0x01, 0x00, 0x00, 0x00, 0x36, 0x39, 0x00, 0x00, + 0x33, 0xA2, 0x00, 0x00, 0x33, 0xA2, 0x00, 0x00, 0xA1, 0x00, 0xA1, 0x00, + 0xA1, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x7D, 0x01, 0x00, + 0x50, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF3, 0xB0, 0x4F, 0xDA, 0x69, 0xDA, 0x63, 0x91, 0x79, 0x5F, 0x00, 0x00, + 0x96, 0x25, 0x9C, 0x6E, 0x86, 0xA0, 0xFF, 0xFF, 0x00, 0x04, 0x10, 0x00, + 0xB5, 0x02, 0x00, 0x00, 0x0D, 0x03, 0x00, 0x00, 0x27, 0x03, 0x00, 0x00, + 0x41, 0x03, 0x00, 0x00, 0x5B, 0x03, 0x00, 0x00, 0x75, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x85, 0x6E, 0x01, 0x00, 0x8D, 0x6E, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x8F, 0x03, 0x00, 0x00, 0x95, 0x6E, 0x01, 0x00, + 0x9D, 0x6E, 0x01, 0x00, 0xAB, 0x6E, 0x01, 0x00, 0xB9, 0x6E, 0x01, 0x00, + 0xC7, 0x6E, 0x01, 0x00, 0xD5, 0x6E, 0x01, 0x00, 0xE3, 0x6E, 0x01, 0x00, + 0xF1, 0x6E, 0x01, 0x00, 0xFF, 0x6E, 0x01, 0x00, 0x0D, 0x6F, 0x01, 0x00, + 0x9D, 0x03, 0x00, 0x00, 0x1B, 0x6F, 0x01, 0x00, 0x29, 0x6F, 0x01, 0x00, + 0x37, 0x6F, 0x01, 0x00, 0x3F, 0x6F, 0x01, 0x00, 0x47, 0x6F, 0x01, 0x00, + 0x4F, 0x6F, 0x01, 0x00, 0x5D, 0x6F, 0x01, 0x00, 0x65, 0x6F, 0x01, 0x00, + 0x6D, 0x6F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x6F, 0x01, 0x00, + 0x7D, 0x6F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x6F, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0xA2, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x02, 0xF8, 0x00, 0xF0, 0x68, 0xF8, + 0x0A, 0xA0, 0x90, 0xE8, 0x00, 0x0C, 0x82, 0x44, 0x83, 0x44, 0xAA, 0xF1, + 0x01, 0x07, 0xDA, 0x45, 0x01, 0xD1, 0x00, 0xF0, 0x5D, 0xF8, 0xAF, 0xF2, + 0x09, 0x0E, 0xBA, 0xE8, 0x0F, 0x00, 0x13, 0xF0, 0x01, 0x0F, 0x18, 0xBF, + 0xFB, 0x1A, 0x43, 0xF0, 0x01, 0x03, 0x18, 0x47, 0x1C, 0x7C, 0x01, 0x00, + 0x4C, 0x7C, 0x01, 0x00, 0x0A, 0x44, 0x4F, 0xF0, 0x00, 0x0C, 0x10, 0xF8, + 0x01, 0x3B, 0x13, 0xF0, 0x07, 0x04, 0x08, 0xBF, 0x10, 0xF8, 0x01, 0x4B, + 0x1D, 0x11, 0x08, 0xBF, 0x10, 0xF8, 0x01, 0x5B, 0x64, 0x1E, 0x05, 0xD0, + 0x10, 0xF8, 0x01, 0x6B, 0x64, 0x1E, 0x01, 0xF8, 0x01, 0x6B, 0xF9, 0xD1, + 0x13, 0xF0, 0x08, 0x0F, 0x1E, 0xBF, 0x10, 0xF8, 0x01, 0x4B, 0xAD, 0x1C, + 0x0C, 0x1B, 0x09, 0xD1, 0x6D, 0x1E, 0x58, 0xBF, 0x01, 0xF8, 0x01, 0xCB, + 0xFA, 0xD5, 0x05, 0xE0, 0x14, 0xF8, 0x01, 0x6B, 0x01, 0xF8, 0x01, 0x6B, + 0x6D, 0x1E, 0xF9, 0xD5, 0x91, 0x42, 0xD6, 0xD3, 0x70, 0x47, 0x00, 0x00, + 0x10, 0x3A, 0x24, 0xBF, 0x78, 0xC8, 0x78, 0xC1, 0xFA, 0xD8, 0x52, 0x07, + 0x24, 0xBF, 0x30, 0xC8, 0x30, 0xC1, 0x44, 0xBF, 0x04, 0x68, 0x0C, 0x60, + 0x70, 0x47, 0x00, 0x00, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, + 0x10, 0x3A, 0x28, 0xBF, 0x78, 0xC1, 0xFB, 0xD8, 0x52, 0x07, 0x28, 0xBF, + 0x30, 0xC1, 0x48, 0xBF, 0x0B, 0x60, 0x70, 0x47, 0x1F, 0xB5, 0x1F, 0xBD, + 0x10, 0xB5, 0x10, 0xBD, 0xDF, 0xF8, 0x0C, 0xD0, 0xFF, 0xF7, 0xF8, 0xFF, + 0x16, 0xF0, 0xE4, 0xFE, 0x17, 0xF0, 0x69, 0xF8, 0x00, 0x04, 0x10, 0x00, + 0x03, 0xB4, 0xFF, 0xF7, 0xF1, 0xFF, 0x03, 0xBC, 0x17, 0xF0, 0x68, 0xF8, + 0x0A, 0x48, 0x4F, 0xF0, 0xFF, 0x01, 0x01, 0x70, 0x4F, 0xF0, 0x00, 0x00, + 0x80, 0xF3, 0x11, 0x88, 0x4F, 0xF0, 0x00, 0x00, 0x80, 0xF3, 0x09, 0x88, + 0x05, 0x48, 0x4F, 0xF0, 0x02, 0x01, 0x01, 0x70, 0x62, 0xB6, 0x04, 0x48, + 0x4F, 0xF0, 0x80, 0x51, 0x01, 0x60, 0x70, 0x47, 0x22, 0xED, 0x00, 0xE0, + 0x00, 0x04, 0x10, 0x00, 0x04, 0xED, 0x00, 0xE0, 0x02, 0x48, 0x4F, 0xF0, + 0x80, 0x51, 0x01, 0x60, 0x70, 0x47, 0x00, 0x00, 0x04, 0xED, 0x00, 0xE0, + 0x4F, 0xF0, 0x20, 0x00, 0x80, 0xF3, 0x11, 0x88, 0xEF, 0xF3, 0x09, 0x80, + 0x98, 0xB1, 0x12, 0x48, 0x00, 0x68, 0x12, 0x49, 0x09, 0x68, 0x88, 0x42, + 0x17, 0xD0, 0xEF, 0xF3, 0x09, 0x80, 0x0E, 0x49, 0x09, 0x68, 0x20, 0xE9, + 0xF0, 0x0F, 0x88, 0x60, 0x00, 0xB5, 0x0B, 0x48, 0x00, 0x68, 0x00, 0xF0, + 0x2F, 0xF9, 0x5D, 0xF8, 0x04, 0xEB, 0x08, 0x48, 0x08, 0x49, 0x0A, 0x68, + 0x02, 0x60, 0x00, 0x68, 0x81, 0x68, 0xB1, 0xE8, 0xF0, 0x0F, 0x81, 0xF3, + 0x09, 0x88, 0x4E, 0xF0, 0x04, 0x0E, 0x4F, 0xF0, 0x00, 0x00, 0x80, 0xF3, + 0x11, 0x88, 0x70, 0x47, 0x04, 0x04, 0x10, 0x00, 0x08, 0x04, 0x10, 0x00, + 0xEF, 0xF3, 0x11, 0x80, 0x4F, 0xF0, 0x20, 0x01, 0x81, 0xF3, 0x11, 0x88, + 0x70, 0x47, 0x00, 0x00, 0x4F, 0xF0, 0x00, 0x00, 0x80, 0xF3, 0x11, 0x88, + 0x70, 0x47, 0x00, 0x00, 0x62, 0xB6, 0x70, 0x47, 0x72, 0xB6, 0x70, 0x47, + 0x40, 0x1E, 0xFD, 0xD1, 0x70, 0x47, 0x00, 0x00, 0x40, 0xBA, 0x70, 0x47, + 0xC0, 0xBA, 0x70, 0x47, 0x12, 0x48, 0x13, 0x49, 0xA1, 0xEB, 0x00, 0x01, + 0x4F, 0xF0, 0x20, 0x03, 0x91, 0xFB, 0xF3, 0xF2, 0x02, 0xFB, 0x13, 0x11, + 0x4F, 0xF0, 0xCC, 0x33, 0x4F, 0xF0, 0xCC, 0x34, 0x4F, 0xF0, 0xCC, 0x35, + 0x4F, 0xF0, 0xCC, 0x36, 0x4F, 0xF0, 0xCC, 0x37, 0x4F, 0xF0, 0xCC, 0x38, + 0x4F, 0xF0, 0xCC, 0x39, 0x4F, 0xF0, 0xCC, 0x3A, 0xA0, 0xE8, 0xF8, 0x07, + 0x01, 0x3A, 0xFB, 0xD1, 0x19, 0xB1, 0x40, 0xF8, 0x04, 0xAB, 0x04, 0x39, + 0xFB, 0xD1, 0x03, 0x48, 0x00, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x04, 0x10, 0x00, 0xE1, 0x00, 0x00, 0x00, 0x1E, 0xF0, 0x04, 0x0F, + 0x0C, 0xBF, 0xEF, 0xF3, 0x08, 0x80, 0xEF, 0xF3, 0x09, 0x80, 0x4F, 0xF0, + 0x01, 0x01, 0x4F, 0xF0, 0x00, 0x02, 0x12, 0xF0, 0xBB, 0xB8, 0x1E, 0xF0, + 0x04, 0x0F, 0x0C, 0xBF, 0xEF, 0xF3, 0x08, 0x80, 0xEF, 0xF3, 0x09, 0x80, + 0x4F, 0xF0, 0x02, 0x01, 0x4F, 0xF0, 0x00, 0x02, 0x12, 0xF0, 0xAE, 0xB8, + 0x1E, 0xF0, 0x04, 0x0F, 0x0C, 0xBF, 0xEF, 0xF3, 0x08, 0x80, 0xEF, 0xF3, + 0x09, 0x80, 0x4F, 0xF0, 0x03, 0x01, 0x4F, 0xF0, 0x00, 0x02, 0x12, 0xF0, + 0xA1, 0xB8, 0x1E, 0xF0, 0x04, 0x0F, 0x0C, 0xBF, 0xEF, 0xF3, 0x08, 0x80, + 0xEF, 0xF3, 0x09, 0x80, 0x4F, 0xF0, 0x04, 0x01, 0x4F, 0xF0, 0x00, 0x02, + 0x12, 0xF0, 0x94, 0xB8, 0x1E, 0xF0, 0x04, 0x0F, 0x0C, 0xBF, 0xEF, 0xF3, + 0x08, 0x80, 0xEF, 0xF3, 0x09, 0x80, 0x4F, 0xF0, 0x05, 0x01, 0x4F, 0xF0, + 0x00, 0x02, 0x12, 0xF0, 0x87, 0xB8, 0x00, 0xB5, 0x16, 0xF0, 0x72, 0xFD, + 0x5D, 0xF8, 0x04, 0xEB, 0xFF, 0xF7, 0x42, 0xBF, 0x1E, 0xF0, 0x04, 0x0F, + 0x0C, 0xBF, 0xEF, 0xF3, 0x08, 0x80, 0xEF, 0xF3, 0x09, 0x80, 0x4F, 0xF0, + 0x06, 0x01, 0x4F, 0xF0, 0x00, 0x02, 0x12, 0xF0, 0x73, 0xB8, 0x00, 0x00, + 0x19, 0x49, 0x10, 0xB5, 0x01, 0x20, 0x08, 0x70, 0x18, 0x49, 0x00, 0x20, + 0x08, 0x60, 0x18, 0x49, 0x08, 0x60, 0x18, 0x49, 0x08, 0x60, 0x18, 0x49, + 0x08, 0x60, 0x00, 0xF0, 0xBF, 0xF9, 0x00, 0xF0, 0x59, 0xF9, 0x00, 0xF0, + 0x7D, 0xF8, 0x00, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x11, 0x48, 0x00, 0xF0, + 0x38, 0xF9, 0x0F, 0x49, 0x08, 0x60, 0x0D, 0x49, 0x09, 0x68, 0x88, 0x42, + 0x07, 0xD0, 0x0A, 0x48, 0x00, 0x78, 0x02, 0x28, 0x03, 0xD1, 0xBD, 0xE8, + 0x10, 0x40, 0xFF, 0xF7, 0x05, 0xBF, 0x10, 0xBD, 0x10, 0xB5, 0xFF, 0xF7, + 0xEA, 0xFF, 0x04, 0x49, 0x02, 0x20, 0x08, 0x70, 0xFF, 0xF7, 0xE0, 0xFE, + 0x4F, 0xF0, 0xFF, 0x30, 0x10, 0xBD, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, + 0x04, 0x04, 0x10, 0x00, 0x08, 0x04, 0x10, 0x00, 0x0C, 0x04, 0x10, 0x00, + 0x10, 0x04, 0x10, 0x00, 0x70, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0xC1, 0x69, + 0x80, 0x68, 0xCC, 0x22, 0x16, 0xF0, 0xDA, 0xFE, 0xE1, 0x69, 0xA0, 0x68, + 0x08, 0x44, 0x4F, 0xF0, 0x80, 0x71, 0x40, 0xF8, 0x04, 0x1C, 0x21, 0x6A, + 0x40, 0xF8, 0x08, 0x1C, 0x00, 0x21, 0x40, 0xF8, 0x0C, 0x1C, 0x40, 0xF8, + 0x10, 0x1C, 0x40, 0xF8, 0x14, 0x1C, 0x40, 0xF8, 0x18, 0x1C, 0x40, 0xE9, + 0x08, 0x51, 0x4F, 0xF0, 0x0B, 0x31, 0x40, 0xF8, 0x24, 0x1C, 0x4F, 0xF0, + 0x0A, 0x31, 0x40, 0xF8, 0x28, 0x1C, 0x4F, 0xF0, 0x09, 0x31, 0x40, 0xF8, + 0x2C, 0x1C, 0x4F, 0xF0, 0x08, 0x31, 0x40, 0xF8, 0x30, 0x1C, 0x4F, 0xF0, + 0x07, 0x31, 0x40, 0xF8, 0x34, 0x1C, 0x4F, 0xF0, 0x06, 0x31, 0x40, 0xF8, + 0x38, 0x1C, 0x4F, 0xF0, 0x05, 0x31, 0x40, 0xF8, 0x3C, 0x1C, 0x4F, 0xF0, + 0x04, 0x31, 0x40, 0xF8, 0x40, 0x1D, 0x70, 0xBD, 0x81, 0x69, 0x4F, 0xF0, + 0xCC, 0x32, 0x0B, 0x68, 0x93, 0x42, 0x08, 0xD1, 0x4B, 0x68, 0x93, 0x42, + 0x05, 0xD1, 0x8B, 0x68, 0x93, 0x42, 0x02, 0xD1, 0xC9, 0x68, 0x91, 0x42, + 0x02, 0xD0, 0x40, 0x68, 0x12, 0xF0, 0xD9, 0xBB, 0x70, 0x47, 0x00, 0x00, + 0x10, 0xB5, 0xA0, 0x21, 0x49, 0x48, 0x16, 0xF0, 0xB5, 0xFE, 0x00, 0x20, + 0x10, 0xBD, 0x70, 0xB5, 0x05, 0x46, 0x46, 0x48, 0x00, 0xEB, 0x05, 0x14, + 0xFF, 0xF7, 0xC6, 0xFE, 0x06, 0x46, 0x20, 0x78, 0x28, 0xB1, 0x30, 0x46, + 0xFF, 0xF7, 0xC8, 0xFE, 0x6F, 0xF0, 0x01, 0x00, 0x70, 0xBD, 0x03, 0x20, + 0x20, 0x70, 0x00, 0x20, 0x65, 0x60, 0xE0, 0x60, 0x04, 0xF1, 0x08, 0x00, + 0x00, 0xF0, 0x7A, 0xF8, 0x30, 0x46, 0xFF, 0xF7, 0xB9, 0xFE, 0x00, 0x20, + 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x0F, 0x46, 0x36, 0x49, 0x00, 0x25, + 0x01, 0xEB, 0x00, 0x14, 0x2E, 0x46, 0xFF, 0xF7, 0xA5, 0xFE, 0x80, 0x46, + 0xE0, 0x68, 0x38, 0x43, 0xE0, 0x60, 0x04, 0xF1, 0x08, 0x00, 0x07, 0x46, + 0x00, 0xF0, 0x89, 0xF8, 0x0C, 0xE0, 0xE1, 0x68, 0xC2, 0x6A, 0x11, 0x42, + 0x03, 0xD0, 0x00, 0xF0, 0x4F, 0xF9, 0x01, 0x26, 0x00, 0xE0, 0x6D, 0x1C, + 0x29, 0x46, 0x38, 0x46, 0x00, 0xF0, 0x71, 0xF8, 0x00, 0x28, 0xF0, 0xD1, + 0x0E, 0xB1, 0xFF, 0xF7, 0x3A, 0xFF, 0x40, 0x46, 0xFF, 0xF7, 0x8E, 0xFE, + 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x70, 0xB5, 0x0D, 0x46, 0x21, 0x49, + 0x01, 0xEB, 0x00, 0x14, 0xFF, 0xF7, 0x7C, 0xFE, 0xE1, 0x68, 0xA9, 0x43, + 0xE1, 0x60, 0xFF, 0xF7, 0x7F, 0xFE, 0x00, 0x20, 0x70, 0xBD, 0x70, 0xB5, + 0x0C, 0x46, 0x1A, 0x49, 0x01, 0xEB, 0x00, 0x15, 0x00, 0x20, 0x20, 0x60, + 0xFF, 0xF7, 0x6C, 0xFE, 0xE9, 0x68, 0x21, 0x60, 0xFF, 0xF7, 0x70, 0xFE, + 0x00, 0x20, 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x0D, 0x46, 0x12, 0x49, + 0x1E, 0x46, 0x90, 0x46, 0x01, 0xEB, 0x00, 0x14, 0xFF, 0xF7, 0x5C, 0xFE, + 0x07, 0x46, 0x0F, 0x48, 0x00, 0x68, 0xC5, 0x62, 0xE1, 0x68, 0x29, 0x42, + 0x03, 0xD1, 0x04, 0xF1, 0x08, 0x01, 0x00, 0xF0, 0x1D, 0xF9, 0x38, 0x46, + 0xFF, 0xF7, 0x56, 0xFE, 0xFF, 0xF7, 0x4C, 0xFE, 0xE1, 0x68, 0x29, 0x40, + 0x31, 0x60, 0xB8, 0xF1, 0x01, 0x0F, 0x02, 0xD1, 0xE1, 0x68, 0xA9, 0x43, + 0xE1, 0x60, 0xFF, 0xF7, 0x49, 0xFE, 0x00, 0x20, 0xB9, 0xE7, 0x00, 0x00, + 0x0C, 0x08, 0x10, 0x00, 0x04, 0x04, 0x10, 0x00, 0x00, 0x21, 0x01, 0x60, + 0x08, 0x46, 0x70, 0x47, 0x30, 0xB5, 0x0A, 0x68, 0x12, 0xB1, 0x0B, 0x46, + 0x84, 0x6A, 0x09, 0xE0, 0x00, 0x22, 0x08, 0x60, 0xC0, 0xE9, 0x03, 0x21, + 0x0B, 0xE0, 0x00, 0xBF, 0x02, 0xF1, 0x0C, 0x03, 0xD2, 0x68, 0x12, 0xB1, + 0x95, 0x6A, 0xA5, 0x42, 0xF8, 0xDC, 0x1A, 0x68, 0xC0, 0xE9, 0x03, 0x21, + 0x18, 0x60, 0x00, 0x20, 0x30, 0xBD, 0x00, 0x68, 0x00, 0x22, 0x01, 0xE0, + 0xC0, 0x68, 0x52, 0x1C, 0x8A, 0x42, 0x01, 0xD0, 0x00, 0x28, 0xF9, 0xD1, + 0x70, 0x47, 0x00, 0x68, 0x70, 0x47, 0x02, 0x69, 0x0A, 0xB1, 0x11, 0x68, + 0x31, 0xB9, 0x6F, 0xF0, 0x04, 0x00, 0x70, 0x47, 0x01, 0xF1, 0x0C, 0x02, + 0xC9, 0x68, 0x39, 0xB1, 0x81, 0x42, 0xF9, 0xD1, 0xC9, 0x68, 0x11, 0x60, + 0x00, 0x21, 0x01, 0x61, 0x08, 0x46, 0x70, 0x47, 0x6F, 0xF0, 0x03, 0x00, + 0x70, 0x47, 0x00, 0x00, 0x10, 0xB5, 0xC8, 0x21, 0x2E, 0x48, 0x16, 0xF0, + 0xDB, 0xFD, 0x00, 0x20, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, + 0x2A, 0x49, 0x00, 0xEB, 0x85, 0x00, 0x17, 0x46, 0x01, 0xEB, 0x80, 0x04, + 0xFF, 0xF7, 0xE8, 0xFD, 0x06, 0x46, 0x20, 0x78, 0x30, 0xB1, 0x30, 0x46, + 0xFF, 0xF7, 0xEA, 0xFD, 0x6F, 0xF0, 0x01, 0x00, 0xBD, 0xE8, 0xF0, 0x81, + 0x02, 0x20, 0x20, 0x70, 0x00, 0x20, 0x65, 0x60, 0xC4, 0xE9, 0x02, 0x70, + 0x04, 0xF1, 0x10, 0x00, 0xFF, 0xF7, 0x9A, 0xFF, 0x30, 0x46, 0xFF, 0xF7, + 0xD9, 0xFD, 0x00, 0x20, 0xEE, 0xE7, 0x70, 0xB5, 0x19, 0x49, 0x00, 0xEB, + 0x80, 0x00, 0x01, 0xEB, 0x80, 0x04, 0xFF, 0xF7, 0xC7, 0xFD, 0x05, 0x46, + 0xD4, 0xE9, 0x02, 0x01, 0x81, 0x42, 0x05, 0xDB, 0x14, 0x48, 0x04, 0xF1, + 0x10, 0x01, 0x00, 0x68, 0x00, 0xF0, 0x88, 0xF8, 0xE0, 0x68, 0x40, 0x1C, + 0xE0, 0x60, 0x28, 0x46, 0xFF, 0xF7, 0xBE, 0xFD, 0x00, 0x20, 0x70, 0xBD, + 0x70, 0xB5, 0x0C, 0x49, 0x00, 0xEB, 0x80, 0x00, 0x01, 0xEB, 0x80, 0x04, + 0xFF, 0xF7, 0xAC, 0xFD, 0x05, 0x46, 0xE0, 0x68, 0x08, 0xB1, 0x40, 0x1E, + 0xE0, 0x60, 0x04, 0xF1, 0x10, 0x00, 0xFF, 0xF7, 0x90, 0xFF, 0x10, 0xB1, + 0x20, 0x69, 0x00, 0xF0, 0x11, 0xF8, 0x28, 0x46, 0xFF, 0xF7, 0xA4, 0xFD, + 0x00, 0x20, 0x70, 0xBD, 0xAC, 0x08, 0x10, 0x00, 0x04, 0x04, 0x10, 0x00, + 0x10, 0xB5, 0x4F, 0xF4, 0xF0, 0x71, 0x3C, 0x48, 0x16, 0xF0, 0x76, 0xFD, + 0x00, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0x90, 0xF8, 0x24, 0x00, + 0x02, 0x28, 0x0B, 0xD0, 0x20, 0x46, 0xFF, 0xF7, 0x74, 0xFF, 0x02, 0x20, + 0x84, 0xF8, 0x24, 0x00, 0x34, 0x49, 0x20, 0x46, 0xFF, 0xF7, 0x48, 0xFF, + 0xFF, 0xF7, 0x2D, 0xFE, 0x00, 0x20, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x5F, + 0x06, 0x46, 0x0A, 0xA8, 0x06, 0xEB, 0x46, 0x01, 0x90, 0xE8, 0x00, 0x0E, + 0x2B, 0x48, 0x1D, 0x46, 0x00, 0xEB, 0x01, 0x14, 0x90, 0x46, 0x20, 0x78, + 0x18, 0xB1, 0x6F, 0xF0, 0x01, 0x00, 0xBD, 0xE8, 0xF0, 0x9F, 0xFF, 0xF7, + 0x65, 0xFD, 0x07, 0x46, 0x01, 0x20, 0x20, 0x70, 0xC4, 0xF8, 0x14, 0x80, + 0xC4, 0xE9, 0x01, 0x65, 0x04, 0xF1, 0x18, 0x01, 0x00, 0x20, 0x81, 0xE8, + 0x20, 0x06, 0x84, 0xF8, 0x24, 0x00, 0xE0, 0x60, 0x20, 0x61, 0xC4, 0xE9, + 0x0A, 0x80, 0x59, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0x29, 0xFE, 0xA0, 0x60, + 0x20, 0x46, 0xFF, 0xF7, 0xBD, 0xFF, 0x38, 0x46, 0xFF, 0xF7, 0x50, 0xFD, + 0x00, 0x20, 0xDC, 0xE7, 0x10, 0xB5, 0x04, 0x46, 0x90, 0xF8, 0x24, 0x00, + 0x02, 0x28, 0x09, 0xD0, 0x20, 0x46, 0xFF, 0xF7, 0x2C, 0xFF, 0x02, 0x20, + 0x84, 0xF8, 0x24, 0x00, 0x10, 0x49, 0x20, 0x46, 0xFF, 0xF7, 0x00, 0xFF, + 0x00, 0x20, 0x10, 0xBD, 0x70, 0xB5, 0x04, 0x46, 0x90, 0xF8, 0x24, 0x00, + 0x0D, 0x46, 0x02, 0x28, 0x0B, 0xD1, 0x20, 0x46, 0xFF, 0xF7, 0x19, 0xFF, + 0x03, 0x20, 0x84, 0xF8, 0x24, 0x00, 0x29, 0x46, 0x20, 0x46, 0xFF, 0xF7, + 0xED, 0xFE, 0xFF, 0xF7, 0xD2, 0xFD, 0x00, 0x20, 0x70, 0xBD, 0x04, 0x48, + 0x00, 0x68, 0x40, 0x68, 0x70, 0x47, 0x00, 0x00, 0x74, 0x09, 0x10, 0x00, + 0x0C, 0x04, 0x10, 0x00, 0x04, 0x04, 0x10, 0x00, 0xA4, 0x22, 0x4F, 0x49, + 0x16, 0xF0, 0x55, 0xBC, 0x70, 0x47, 0x10, 0xB5, 0x04, 0x46, 0x80, 0x07, + 0x02, 0xD0, 0x02, 0x20, 0x16, 0xF0, 0xA3, 0xF8, 0x4F, 0xF4, 0x80, 0x30, + 0x20, 0x44, 0xC0, 0xF3, 0x4F, 0x00, 0x10, 0xBD, 0x01, 0x46, 0xAC, 0x22, + 0x46, 0x48, 0x16, 0xF0, 0x87, 0xBC, 0x45, 0x4A, 0x5F, 0xF0, 0x00, 0x01, + 0x42, 0xF8, 0x21, 0x00, 0x49, 0x1C, 0x26, 0x29, 0xFA, 0xDB, 0x70, 0x47, + 0x00, 0xF0, 0xF6, 0xBE, 0x00, 0xF0, 0x1B, 0xBF, 0x1D, 0x20, 0x70, 0x47, + 0x26, 0x20, 0x70, 0x47, 0x3D, 0x48, 0x10, 0xB5, 0x00, 0x68, 0x10, 0xB1, + 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x47, 0x00, 0x20, 0x16, 0xF0, 0x7D, 0xF8, + 0x10, 0xBD, 0x01, 0x29, 0x12, 0xD0, 0x02, 0x29, 0x24, 0xD0, 0x03, 0x29, + 0x0E, 0xD0, 0x04, 0x29, 0x1D, 0xD1, 0x01, 0x78, 0x21, 0xF0, 0x12, 0x01, + 0x00, 0xF8, 0x35, 0x1B, 0x01, 0x7E, 0x21, 0xF0, 0x03, 0x01, 0x01, 0x76, + 0xC1, 0x7F, 0x21, 0xF0, 0x80, 0x01, 0x22, 0xE0, 0x02, 0x78, 0x01, 0x29, + 0x42, 0xF0, 0x12, 0x02, 0x02, 0x70, 0x0B, 0xD0, 0x5F, 0xF0, 0x03, 0x02, + 0x10, 0xF8, 0x4D, 0x1F, 0x62, 0xF3, 0x01, 0x01, 0x01, 0x70, 0xC1, 0x79, + 0x41, 0xF0, 0x80, 0x01, 0xC1, 0x71, 0x70, 0x47, 0x01, 0x22, 0xF3, 0xE7, + 0x01, 0x78, 0x21, 0xF0, 0x02, 0x01, 0x41, 0xF0, 0x10, 0x01, 0x00, 0xF8, + 0x35, 0x1B, 0x01, 0x7E, 0x21, 0xF0, 0x03, 0x01, 0x89, 0x1C, 0x01, 0x76, + 0xC1, 0x7F, 0x41, 0xF0, 0x80, 0x01, 0xC1, 0x77, 0x70, 0x47, 0x90, 0xF8, + 0x29, 0x20, 0x02, 0x29, 0x04, 0xD0, 0x03, 0x29, 0x22, 0xF0, 0x40, 0x01, + 0x02, 0xD1, 0x04, 0xE0, 0x42, 0xF0, 0x40, 0x01, 0x21, 0xF0, 0x80, 0x01, + 0x01, 0xE0, 0x41, 0xF0, 0x80, 0x01, 0x80, 0xF8, 0x29, 0x10, 0x70, 0x47, + 0x90, 0xF8, 0x29, 0x20, 0x01, 0x29, 0x04, 0xD0, 0x02, 0x29, 0x07, 0xD0, + 0x22, 0xF0, 0x10, 0x01, 0x01, 0xE0, 0x42, 0xF0, 0x10, 0x01, 0x21, 0xF0, + 0x20, 0x01, 0x01, 0xE0, 0x42, 0xF0, 0x30, 0x01, 0x80, 0xF8, 0x29, 0x10, + 0x70, 0x47, 0xC2, 0x78, 0x00, 0x29, 0x61, 0xF3, 0x03, 0x02, 0xC2, 0x70, + 0x04, 0xD0, 0x10, 0xF8, 0x5E, 0x1F, 0x41, 0xF0, 0x04, 0x01, 0x01, 0x70, + 0x70, 0x47, 0x00, 0x00, 0x48, 0x74, 0x01, 0x00, 0xA4, 0x00, 0x03, 0x20, + 0x18, 0x04, 0x10, 0x00, 0x01, 0xEB, 0x81, 0x01, 0x02, 0xEB, 0xC1, 0x01, + 0x40, 0x5C, 0x01, 0x06, 0x02, 0xD5, 0x00, 0xF0, 0x7F, 0x00, 0x40, 0x42, + 0x70, 0x47, 0x00, 0x2B, 0x04, 0xDA, 0x5B, 0x42, 0xDB, 0xB2, 0x43, 0xF0, + 0x80, 0x03, 0x01, 0xE0, 0x03, 0xF0, 0x7F, 0x03, 0x01, 0xEB, 0x81, 0x01, + 0x02, 0xEB, 0xC1, 0x01, 0x43, 0x54, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x5F, + 0x00, 0x25, 0x17, 0x46, 0x98, 0x46, 0x89, 0x46, 0x83, 0x46, 0x2E, 0x46, + 0x4F, 0xF0, 0x01, 0x0A, 0x0A, 0xFA, 0x05, 0xF0, 0x10, 0xEA, 0x09, 0x0F, + 0x14, 0xD0, 0x00, 0x24, 0x22, 0x46, 0x01, 0x20, 0x00, 0x21, 0x16, 0xF0, + 0x4D, 0xFB, 0x38, 0x40, 0x01, 0xEA, 0x08, 0x01, 0x08, 0x43, 0x05, 0xD0, + 0x00, 0x23, 0x22, 0x46, 0x31, 0x46, 0x58, 0x46, 0xFF, 0xF7, 0xD1, 0xFF, + 0x64, 0x1C, 0x26, 0x2C, 0xEC, 0xDB, 0x76, 0x1C, 0x6D, 0x1C, 0x1D, 0x2D, + 0xE2, 0xDB, 0xBD, 0xE8, 0xF0, 0x9F, 0x40, 0x5C, 0x01, 0x06, 0x02, 0xD5, + 0x00, 0xF0, 0x7F, 0x00, 0x40, 0x42, 0x70, 0x47, 0x00, 0x2A, 0x04, 0xDA, + 0x52, 0x42, 0xD2, 0xB2, 0x42, 0xF0, 0x80, 0x02, 0x01, 0xE0, 0x02, 0xF0, + 0x7F, 0x02, 0x42, 0x54, 0x70, 0x47, 0xF0, 0xB5, 0x00, 0x24, 0x16, 0x46, + 0x0F, 0x46, 0x84, 0x46, 0x23, 0x46, 0x01, 0x25, 0x10, 0xE0, 0x00, 0xBF, + 0x07, 0xEB, 0xE3, 0x00, 0x03, 0xF0, 0x07, 0x02, 0x01, 0x78, 0x05, 0xFA, + 0x02, 0xF0, 0x08, 0x42, 0x05, 0xD0, 0x00, 0x22, 0x19, 0x46, 0x60, 0x46, + 0xFF, 0xF7, 0xDE, 0xFF, 0x64, 0x1C, 0x5B, 0x1C, 0xB4, 0x42, 0xED, 0xDB, + 0xF0, 0xBD, 0x40, 0x5C, 0x70, 0x47, 0x42, 0x54, 0x70, 0x47, 0x00, 0x00, + 0x2D, 0xE9, 0xF0, 0x47, 0x34, 0x4C, 0x54, 0xF8, 0x3C, 0x8F, 0x67, 0x68, + 0xE6, 0x68, 0x25, 0x7C, 0xDF, 0xF8, 0xC8, 0x90, 0x01, 0x21, 0xC9, 0xF8, + 0x00, 0x10, 0x4F, 0xF4, 0x20, 0x70, 0xFF, 0xF7, 0xF9, 0xFB, 0x00, 0x21, + 0xC9, 0xF8, 0x00, 0x10, 0xC4, 0xF8, 0x00, 0x80, 0x67, 0x60, 0xE6, 0x60, + 0x25, 0x74, 0xBD, 0xE8, 0xF0, 0x87, 0x28, 0x48, 0x00, 0x21, 0xC1, 0x63, + 0x01, 0x64, 0x81, 0x64, 0x80, 0xF8, 0x4C, 0x10, 0x70, 0x47, 0x10, 0xB5, + 0x02, 0x46, 0x00, 0x24, 0x4F, 0xF0, 0x01, 0x00, 0x49, 0xB3, 0x00, 0x21, + 0x16, 0xF0, 0xDA, 0xFA, 0x1F, 0x4A, 0x48, 0x32, 0x10, 0x60, 0x11, 0x71, + 0xFF, 0xF7, 0xCE, 0xFF, 0x00, 0x20, 0x00, 0xF0, 0x25, 0xF8, 0x00, 0xB1, + 0x01, 0x24, 0xFF, 0xF7, 0xC7, 0xFF, 0x01, 0x20, 0x00, 0xF0, 0x1E, 0xF8, + 0x08, 0xB1, 0x44, 0xF0, 0x02, 0x04, 0xFF, 0xF7, 0xBF, 0xFF, 0x02, 0x20, + 0x00, 0xF0, 0x16, 0xF8, 0x08, 0xB1, 0x44, 0xF0, 0x04, 0x04, 0xFF, 0xF7, + 0xB7, 0xFF, 0x03, 0x20, 0x00, 0xF0, 0x0E, 0xF8, 0x08, 0xB1, 0x44, 0xF0, + 0x08, 0x04, 0xFF, 0xF7, 0xAF, 0xFF, 0x20, 0x46, 0x10, 0xBD, 0x90, 0x40, + 0x0B, 0x4A, 0x00, 0x21, 0x3C, 0x32, 0xC2, 0xE9, 0x00, 0x01, 0xD5, 0xE7, + 0x40, 0xF0, 0x20, 0x01, 0x07, 0x48, 0x10, 0xB5, 0x80, 0xF8, 0xA3, 0x10, + 0xE5, 0x21, 0x81, 0x71, 0x4F, 0xF4, 0x20, 0x70, 0xFF, 0xF7, 0xA4, 0xFB, + 0x04, 0x48, 0xD0, 0xF8, 0xC0, 0x02, 0xC0, 0xB2, 0x10, 0xBD, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x20, 0x68, 0x14, 0x60, 0x22, 0x00, 0x10, 0x60, 0x22, + 0x01, 0x49, 0x01, 0x20, 0x09, 0x68, 0x08, 0x47, 0x1C, 0x04, 0x10, 0x00, + 0x10, 0xB5, 0xFF, 0xF7, 0x8B, 0xFE, 0x05, 0x49, 0x02, 0x20, 0x08, 0x70, + 0x04, 0x49, 0x00, 0x20, 0x08, 0x60, 0x04, 0x49, 0x09, 0x68, 0xBD, 0xE8, + 0x10, 0x40, 0x08, 0x47, 0x14, 0x04, 0x10, 0x00, 0x18, 0x04, 0x10, 0x00, + 0x1C, 0x04, 0x10, 0x00, 0x37, 0xB5, 0x04, 0x46, 0x37, 0x49, 0x01, 0x98, + 0x15, 0x46, 0x08, 0x40, 0x01, 0x90, 0x04, 0x21, 0x01, 0xA8, 0x00, 0xF0, + 0xFC, 0xFA, 0x01, 0x2D, 0x02, 0xD0, 0x02, 0x2D, 0x04, 0xD0, 0x06, 0xE0, + 0xC0, 0x1C, 0x20, 0xF0, 0x01, 0x00, 0x02, 0xE0, 0xC0, 0x1D, 0x20, 0xF0, + 0x03, 0x00, 0x01, 0x99, 0x44, 0xF8, 0x3C, 0x1F, 0x00, 0x21, 0x61, 0x60, + 0x21, 0x7A, 0x60, 0xF3, 0x06, 0x01, 0x21, 0x72, 0x3E, 0xBD, 0x01, 0x23, + 0x40, 0xF8, 0x3C, 0x3F, 0x00, 0x23, 0x43, 0x60, 0x51, 0x43, 0x02, 0x7A, + 0x61, 0xF3, 0x06, 0x02, 0x02, 0x72, 0x70, 0x47, 0x1F, 0xB5, 0x04, 0x46, + 0x03, 0x99, 0x02, 0xA8, 0x01, 0xF0, 0x3F, 0x01, 0x03, 0x91, 0x08, 0x21, + 0x00, 0xF0, 0xD1, 0xFA, 0xDD, 0xE9, 0x02, 0x12, 0xA1, 0x64, 0x84, 0xF8, + 0x4C, 0x20, 0x14, 0xF8, 0x70, 0x1F, 0x60, 0xF3, 0x05, 0x01, 0x04, 0xF8, + 0x1E, 0x19, 0xE1, 0x7F, 0x60, 0xF3, 0x05, 0x01, 0xE1, 0x77, 0x1F, 0xBD, + 0x08, 0xB5, 0x16, 0xA2, 0x12, 0x68, 0x00, 0x92, 0x1D, 0xF8, 0x01, 0x20, + 0x10, 0xF8, 0x5D, 0x1F, 0x62, 0xF3, 0x01, 0x01, 0x01, 0x70, 0x08, 0xBD, + 0x10, 0xB5, 0x82, 0x79, 0x22, 0xF0, 0x0D, 0x02, 0x42, 0xF0, 0xE0, 0x02, + 0x82, 0x71, 0x0E, 0x4A, 0x11, 0x60, 0x0E, 0x4A, 0x03, 0x21, 0x11, 0x70, + 0x0E, 0x4A, 0x0D, 0x49, 0x11, 0x60, 0x01, 0x46, 0xA4, 0x22, 0x0D, 0x48, + 0x16, 0xF0, 0x4B, 0xFA, 0x0C, 0x49, 0x01, 0x20, 0xC1, 0xF8, 0xC0, 0x00, + 0xBD, 0xE8, 0x10, 0x40, 0x0A, 0x49, 0x4F, 0xF4, 0xFA, 0x70, 0xFF, 0xF7, + 0x07, 0xBE, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x1C, 0x00, 0x01, 0x02, 0x00, + 0x1C, 0x04, 0x10, 0x00, 0x14, 0x04, 0x10, 0x00, 0x81, 0x0B, 0x00, 0x00, + 0x18, 0x04, 0x10, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x60, 0x22, + 0x75, 0x0B, 0x00, 0x00, 0x16, 0x48, 0x01, 0x78, 0x01, 0x29, 0x08, 0xD1, + 0x02, 0x21, 0x01, 0x70, 0x14, 0x48, 0x01, 0x68, 0x19, 0xB1, 0x00, 0x22, + 0x02, 0x60, 0x10, 0x46, 0x08, 0x47, 0x01, 0x20, 0x15, 0xF0, 0x73, 0xBE, + 0x0E, 0x4A, 0x01, 0x21, 0x11, 0x70, 0x0E, 0x49, 0x08, 0x60, 0x0E, 0x49, + 0xE8, 0x20, 0x88, 0x71, 0x0D, 0x49, 0x02, 0x20, 0xFF, 0xF7, 0xD8, 0xBD, + 0x0A, 0x49, 0x08, 0x20, 0x88, 0x71, 0x0B, 0x49, 0x00, 0x20, 0x08, 0x62, + 0x05, 0x49, 0x08, 0x70, 0x05, 0x49, 0x08, 0x60, 0x70, 0x47, 0x03, 0x48, + 0x00, 0x78, 0x00, 0x28, 0x00, 0xD0, 0x01, 0x20, 0x70, 0x47, 0x00, 0x00, + 0x14, 0x04, 0x10, 0x00, 0x20, 0x04, 0x10, 0x00, 0x00, 0x00, 0x03, 0x20, + 0xB1, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x22, 0x53, 0x49, 0x01, 0x20, + 0x09, 0x68, 0x08, 0x47, 0x10, 0xB5, 0xFF, 0xF7, 0xB7, 0xFD, 0x51, 0x49, + 0x02, 0x20, 0x08, 0x70, 0x50, 0x49, 0x00, 0x20, 0x08, 0x60, 0x4D, 0x49, + 0x09, 0x68, 0xBD, 0xE8, 0x10, 0x40, 0x08, 0x47, 0x13, 0xB5, 0x04, 0x46, + 0x4C, 0x49, 0x01, 0x98, 0x08, 0x40, 0x01, 0x90, 0x04, 0x21, 0x01, 0xA8, + 0x00, 0xF0, 0x2F, 0xFA, 0x01, 0x99, 0x44, 0xF8, 0x3C, 0x1F, 0x00, 0x21, + 0x61, 0x60, 0x14, 0xF8, 0x08, 0x1F, 0x60, 0xF3, 0x06, 0x01, 0x04, 0xF8, + 0x11, 0x1B, 0x61, 0x7F, 0x60, 0xF3, 0x05, 0x01, 0x61, 0x77, 0xA1, 0x7F, + 0x60, 0xF3, 0x05, 0x01, 0xA1, 0x77, 0xE0, 0x7F, 0x20, 0xF0, 0x08, 0x00, + 0xE0, 0x77, 0x1C, 0xBD, 0x1F, 0xB5, 0x04, 0x46, 0x03, 0x99, 0x02, 0xA8, + 0x01, 0xF0, 0x3F, 0x01, 0x03, 0x91, 0x08, 0x21, 0x00, 0xF0, 0x0D, 0xFA, + 0xDD, 0xE9, 0x02, 0x12, 0xA1, 0x64, 0x84, 0xF8, 0x4C, 0x20, 0x14, 0xF8, + 0x70, 0x1F, 0x60, 0xF3, 0x05, 0x01, 0x04, 0xF8, 0x1E, 0x19, 0xE1, 0x7F, + 0x60, 0xF3, 0x05, 0x01, 0xE1, 0x77, 0x1F, 0xBD, 0x10, 0xB5, 0x30, 0xA3, + 0x89, 0xB0, 0x1C, 0xCB, 0x8D, 0xE8, 0x1C, 0x00, 0x30, 0xA4, 0x0D, 0xF1, + 0x0C, 0x0C, 0x1C, 0xCC, 0x8C, 0xE8, 0x1C, 0x00, 0x30, 0xA4, 0x0D, 0xF1, + 0x18, 0x0C, 0x1C, 0xCC, 0x8C, 0xE8, 0x1C, 0x00, 0x03, 0xAA, 0x53, 0x5C, + 0x42, 0x7E, 0x63, 0xF3, 0x05, 0x02, 0x42, 0x76, 0x1D, 0xF8, 0x01, 0x30, + 0x02, 0x7E, 0x63, 0xF3, 0x42, 0x02, 0x02, 0x76, 0x06, 0xAA, 0x52, 0x5C, + 0x81, 0x79, 0x62, 0xF3, 0x83, 0x01, 0x81, 0x71, 0x09, 0xB0, 0x10, 0xBD, + 0x1A, 0x49, 0x04, 0x20, 0x08, 0x70, 0x1A, 0x49, 0x24, 0x48, 0x08, 0x60, + 0x24, 0x49, 0x01, 0x20, 0xC1, 0xF8, 0xC0, 0x00, 0x23, 0x49, 0x4F, 0xF4, + 0xFA, 0x70, 0xFF, 0xF7, 0x39, 0xBD, 0x10, 0xB5, 0xB0, 0xF8, 0x56, 0x20, + 0x42, 0xF0, 0x01, 0x02, 0xA0, 0xF8, 0x56, 0x20, 0x82, 0x79, 0x22, 0xF0, + 0x01, 0x02, 0x42, 0xF0, 0xE0, 0x02, 0x82, 0x71, 0x0B, 0x4A, 0x11, 0x60, + 0x0B, 0x4A, 0x04, 0x21, 0x11, 0x70, 0x0B, 0x4A, 0x15, 0x49, 0x11, 0x60, + 0x01, 0x46, 0xA4, 0x22, 0x16, 0x48, 0x16, 0xF0, 0x58, 0xF9, 0x13, 0x49, + 0x01, 0x20, 0xC1, 0xF8, 0xC0, 0x00, 0xBD, 0xE8, 0x10, 0x40, 0x11, 0x49, + 0x4F, 0xF4, 0xFA, 0x70, 0xFF, 0xF7, 0x14, 0xBD, 0x24, 0x04, 0x10, 0x00, + 0x14, 0x04, 0x10, 0x00, 0x18, 0x04, 0x10, 0x00, 0xFF, 0xFF, 0x03, 0x1C, + 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, + 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x00, 0x00, + 0x29, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x60, 0x22, 0x21, 0x0D, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x20, 0x35, 0x49, 0x01, 0x20, 0x08, 0x60, 0x17, 0x22, + 0x41, 0x07, 0x01, 0xF8, 0x27, 0x2F, 0x0B, 0x22, 0x81, 0xF8, 0x41, 0x20, + 0x30, 0x49, 0x18, 0x39, 0x08, 0x60, 0x4F, 0xF0, 0x08, 0x51, 0xC1, 0xF8, + 0xC4, 0x03, 0x2D, 0x4A, 0x00, 0x21, 0xB0, 0x32, 0x11, 0x60, 0x2C, 0x49, + 0x08, 0x60, 0x09, 0x1D, 0x08, 0x60, 0x29, 0x49, 0x94, 0x39, 0x08, 0x60, + 0x70, 0x47, 0x4F, 0xF0, 0x00, 0x50, 0x00, 0x88, 0x70, 0x47, 0x4F, 0xF0, + 0x00, 0x50, 0x80, 0x78, 0x70, 0x47, 0x4F, 0xF0, 0x00, 0x51, 0x88, 0x80, + 0x70, 0x47, 0x21, 0x49, 0x01, 0x20, 0x30, 0x39, 0x08, 0x60, 0x70, 0x47, + 0x4F, 0xF0, 0x00, 0x50, 0x10, 0xF8, 0x22, 0x1F, 0x21, 0xF0, 0x03, 0x01, + 0x01, 0x70, 0x70, 0x47, 0x4F, 0xF0, 0x00, 0x53, 0x03, 0xF8, 0x1F, 0x0F, + 0x59, 0x70, 0x98, 0x78, 0x62, 0xF3, 0x03, 0x00, 0x98, 0x70, 0x70, 0x47, + 0x17, 0x48, 0x00, 0x68, 0x70, 0x47, 0x16, 0x49, 0x08, 0x60, 0x70, 0x47, + 0x10, 0xB5, 0x4F, 0xF0, 0x00, 0x54, 0xE2, 0x7E, 0x22, 0xF0, 0xAF, 0x03, + 0x20, 0x22, 0x02, 0xEA, 0x40, 0x12, 0x1A, 0x43, 0x04, 0x23, 0x03, 0xEA, + 0x80, 0x00, 0x02, 0x43, 0x01, 0xF0, 0x03, 0x00, 0x02, 0x43, 0xE2, 0x76, + 0x10, 0xBD, 0x4F, 0xF0, 0x00, 0x50, 0x90, 0xF8, 0x22, 0x00, 0x10, 0xF0, + 0x03, 0x00, 0x05, 0xD0, 0x01, 0x28, 0x05, 0xD0, 0x02, 0x28, 0x05, 0xD0, + 0x06, 0x48, 0x70, 0x47, 0x06, 0x48, 0x70, 0x47, 0x06, 0x48, 0x70, 0x47, + 0x06, 0x48, 0x70, 0x47, 0xCC, 0x04, 0x00, 0x22, 0x80, 0x1E, 0x00, 0x22, + 0x28, 0x04, 0x10, 0x00, 0x00, 0x12, 0x7A, 0x00, 0x00, 0x90, 0xD0, 0x03, + 0x00, 0x48, 0xE8, 0x01, 0x00, 0x24, 0xF4, 0x00, 0x30, 0xB5, 0x6C, 0x4C, + 0x01, 0x25, 0x25, 0x60, 0xE5, 0x06, 0x03, 0xF0, 0x1F, 0x03, 0x85, 0xF8, + 0x6B, 0x30, 0x00, 0x23, 0x05, 0xE0, 0x00, 0xBF, 0x51, 0xF8, 0x23, 0x50, + 0x40, 0xF8, 0x23, 0x50, 0x5B, 0x1C, 0x93, 0x42, 0xF8, 0xDB, 0x00, 0x20, + 0x20, 0x60, 0x30, 0xBD, 0xF0, 0xB5, 0x06, 0x46, 0x00, 0x20, 0x04, 0x46, + 0xDF, 0xF8, 0x80, 0xC1, 0x14, 0xE0, 0x56, 0xF8, 0x24, 0x70, 0x03, 0x23, + 0xDD, 0x00, 0x47, 0xFA, 0x05, 0xF2, 0x80, 0xEA, 0x02, 0x60, 0x08, 0x25, + 0x00, 0x28, 0x02, 0xDA, 0x8C, 0xEA, 0x40, 0x00, 0x00, 0xE0, 0x40, 0x00, + 0x6D, 0x1E, 0x00, 0x2D, 0xF6, 0xDC, 0x5B, 0x1E, 0xEE, 0xD5, 0x64, 0x1C, + 0x8C, 0x42, 0xE8, 0xDB, 0xF0, 0xBD, 0xF0, 0xB5, 0xB1, 0xB0, 0x07, 0x46, + 0x6D, 0x46, 0x52, 0x4E, 0x01, 0x24, 0xC0, 0x21, 0x28, 0x46, 0x16, 0xF0, + 0x13, 0xF9, 0x00, 0x20, 0x56, 0xF8, 0x20, 0x10, 0x45, 0xF8, 0x20, 0x10, + 0x40, 0x1C, 0x30, 0x28, 0xF8, 0xD3, 0x4C, 0x49, 0x00, 0x98, 0x88, 0x42, + 0x10, 0xD1, 0x02, 0x98, 0x81, 0xB2, 0x05, 0xA8, 0x04, 0x46, 0xFF, 0xF7, + 0xC5, 0xFF, 0x01, 0x99, 0x81, 0x42, 0x06, 0xD1, 0xAC, 0x22, 0x21, 0x46, + 0x38, 0x46, 0x16, 0xF0, 0x9D, 0xF8, 0x00, 0x24, 0x00, 0xE0, 0x03, 0x24, + 0x31, 0xB0, 0x20, 0x46, 0xF0, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x41, 0x4D, + 0x07, 0x46, 0x3F, 0x4E, 0x01, 0x24, 0x4F, 0xF4, 0x58, 0x71, 0x28, 0x46, + 0x16, 0xF0, 0xE8, 0xF8, 0x5F, 0xF0, 0x00, 0x00, 0x56, 0xF8, 0x20, 0x10, + 0x45, 0xF8, 0x20, 0x10, 0x40, 0x1C, 0xD8, 0x28, 0xF8, 0xD3, 0x38, 0x4D, + 0x38, 0x49, 0x28, 0x68, 0x88, 0x42, 0x12, 0xD1, 0x28, 0x89, 0x81, 0xB2, + 0x05, 0xF1, 0x14, 0x00, 0xFF, 0xF7, 0x98, 0xFF, 0x69, 0x68, 0x81, 0x42, + 0x08, 0xD1, 0x4F, 0xF4, 0x52, 0x72, 0x05, 0xF1, 0x18, 0x01, 0x38, 0x46, + 0x16, 0xF0, 0x29, 0xF8, 0x00, 0x24, 0x00, 0xE0, 0x03, 0x24, 0x20, 0x46, + 0xBD, 0xE8, 0xF0, 0x81, 0x70, 0xB5, 0x94, 0xB0, 0x04, 0x46, 0x6D, 0x46, + 0x2A, 0x4E, 0x50, 0x21, 0x28, 0x46, 0x16, 0xF0, 0xBB, 0xF8, 0x00, 0x20, + 0x56, 0xF8, 0x20, 0x10, 0x45, 0xF8, 0x20, 0x10, 0x40, 0x1C, 0x14, 0x28, + 0xF8, 0xD3, 0x25, 0x49, 0x00, 0x98, 0x6F, 0xF0, 0x02, 0x05, 0x88, 0x42, + 0x2E, 0xD1, 0xA8, 0x10, 0x20, 0x60, 0x60, 0x60, 0xA0, 0x60, 0xE0, 0x60, + 0x20, 0x61, 0x02, 0x98, 0x81, 0xB2, 0x05, 0xA8, 0xFF, 0xF7, 0x66, 0xFF, + 0x01, 0x99, 0x81, 0x42, 0x20, 0xD1, 0xBD, 0xF8, 0x38, 0x10, 0x45, 0xF2, + 0xAA, 0x50, 0x81, 0x42, 0x0C, 0xD1, 0x9D, 0xF8, 0x1D, 0x10, 0x21, 0x60, + 0x9D, 0xF8, 0x1C, 0x10, 0x01, 0xF0, 0x0F, 0x01, 0x61, 0x60, 0x9D, 0xF8, + 0x1E, 0x10, 0x01, 0xF0, 0x0F, 0x01, 0xA1, 0x60, 0xBD, 0xF8, 0x3C, 0x10, + 0x81, 0x42, 0x01, 0xD1, 0x08, 0x99, 0xE1, 0x60, 0xBD, 0xF8, 0x40, 0x10, + 0x81, 0x42, 0x01, 0xD1, 0x09, 0x98, 0x20, 0x61, 0x14, 0xB0, 0x70, 0xBD, + 0x25, 0x60, 0x65, 0x60, 0xA5, 0x60, 0xE5, 0x60, 0x25, 0x61, 0xF7, 0xE7, + 0xC4, 0x1B, 0x00, 0x22, 0x1B, 0x00, 0x00, 0x80, 0x48, 0x1D, 0x04, 0x00, + 0xB2, 0x57, 0x0E, 0x70, 0xE8, 0x19, 0x04, 0x00, 0x54, 0x0B, 0x10, 0x00, + 0xA1, 0x46, 0x0D, 0x60, 0xAC, 0x1E, 0x04, 0x00, 0x5C, 0x00, 0x0D, 0x60, + 0xF0, 0xB5, 0x07, 0x46, 0x00, 0x20, 0x03, 0x46, 0x2F, 0x4E, 0x11, 0xE0, + 0x57, 0xF8, 0x23, 0x50, 0x03, 0x22, 0x00, 0xBF, 0x4F, 0xEA, 0xC2, 0x0C, + 0x45, 0xFA, 0x0C, 0xF4, 0x84, 0xEA, 0x20, 0x64, 0xE4, 0xB2, 0x52, 0x1E, + 0x56, 0xF8, 0x24, 0x40, 0x84, 0xEA, 0x00, 0x20, 0xF2, 0xD5, 0x5B, 0x1C, + 0x8B, 0x42, 0xEB, 0xDB, 0xF0, 0xBD, 0x30, 0xB5, 0x02, 0x46, 0x23, 0x4B, + 0x00, 0x20, 0x10, 0x3B, 0x08, 0xE0, 0x54, 0x5C, 0x04, 0xF0, 0x0F, 0x05, + 0x03, 0xEB, 0x14, 0x14, 0x5D, 0x5D, 0x24, 0x78, 0x28, 0x44, 0x20, 0x44, + 0x49, 0x1E, 0xF4, 0xD2, 0x30, 0xBD, 0x10, 0xB5, 0x84, 0x68, 0x03, 0x68, + 0xE4, 0x43, 0xA3, 0x42, 0x0A, 0xD1, 0xC4, 0x68, 0x43, 0x68, 0xE4, 0x43, + 0xA3, 0x42, 0x05, 0xD1, 0x5B, 0x1C, 0x0B, 0x60, 0x00, 0x68, 0x10, 0x60, + 0x01, 0x20, 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, 0x3C, 0xB5, 0x04, 0x46, + 0x00, 0x25, 0x01, 0xAA, 0x69, 0x46, 0xFF, 0xF7, 0xE6, 0xFF, 0x01, 0x28, + 0x09, 0xD1, 0x00, 0x99, 0x04, 0xF1, 0x10, 0x00, 0x09, 0x1F, 0xFF, 0xF7, + 0xB1, 0xFF, 0x01, 0x99, 0x88, 0x42, 0x00, 0xD1, 0x01, 0x25, 0x28, 0x46, + 0x3C, 0xBD, 0x30, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x09, 0x1F, 0x10, 0x30, + 0xFF, 0xF7, 0xA4, 0xFF, 0x6D, 0x1E, 0x65, 0x60, 0xE9, 0x43, 0xE1, 0x60, + 0x20, 0x60, 0xC0, 0x43, 0xA0, 0x60, 0x30, 0xBD, 0xFC, 0x74, 0x01, 0x00, + 0x4F, 0xF0, 0x00, 0x50, 0x00, 0x21, 0x80, 0xF8, 0x3D, 0x10, 0x80, 0xF8, + 0x3E, 0x10, 0x80, 0xF8, 0x3F, 0x10, 0x3F, 0x22, 0x80, 0xF8, 0x32, 0x20, + 0x00, 0xF8, 0x30, 0x1F, 0x02, 0x71, 0x41, 0x71, 0x42, 0x70, 0x01, 0x72, + 0x41, 0x72, 0x81, 0x72, 0xC1, 0x72, 0xC1, 0x71, 0x70, 0x47, 0x28, 0x4A, + 0x10, 0x60, 0x27, 0x48, 0x0C, 0x30, 0x01, 0x60, 0x70, 0x47, 0x30, 0xB5, + 0x01, 0x24, 0x84, 0x40, 0x4F, 0xF0, 0x00, 0x50, 0x00, 0x29, 0x03, 0x9D, + 0x90, 0xF8, 0x32, 0x10, 0xE4, 0xB2, 0x01, 0xD0, 0x21, 0x43, 0x00, 0xE0, + 0xA1, 0x43, 0x80, 0xF8, 0x32, 0x10, 0x90, 0xF8, 0x30, 0x10, 0x0A, 0xB1, + 0x21, 0x43, 0x00, 0xE0, 0xA1, 0x43, 0x80, 0xF8, 0x30, 0x10, 0x90, 0xF8, + 0x34, 0x10, 0x0B, 0xB1, 0x21, 0x43, 0x00, 0xE0, 0xA1, 0x43, 0x80, 0xF8, + 0x34, 0x10, 0x10, 0xF8, 0x35, 0x1F, 0x0D, 0xB1, 0x21, 0x43, 0x00, 0xE0, + 0xA1, 0x43, 0x01, 0x70, 0x30, 0xBD, 0x4F, 0xF0, 0x00, 0x52, 0x06, 0x28, + 0x17, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x03, 0x06, 0x09, 0x0F, 0x17, 0x1A, + 0x12, 0xF8, 0x3D, 0x0F, 0x04, 0xE0, 0x12, 0xF8, 0x3D, 0x0F, 0x07, 0xE0, + 0x12, 0xF8, 0x3E, 0x0F, 0x20, 0xF0, 0x0F, 0x00, 0x08, 0x43, 0x05, 0xE0, + 0x12, 0xF8, 0x3E, 0x0F, 0x20, 0xF0, 0xF0, 0x00, 0x40, 0xEA, 0x01, 0x10, + 0x10, 0x70, 0x70, 0x47, 0x12, 0xF8, 0x3F, 0x0F, 0xF0, 0xE7, 0x12, 0xF8, + 0x3F, 0x0F, 0xF3, 0xE7, 0x38, 0x05, 0x00, 0x22, 0xF0, 0xB5, 0x63, 0x4C, + 0xD0, 0xE9, 0x00, 0x25, 0x01, 0x21, 0xE3, 0x1D, 0x06, 0x7A, 0xFF, 0x27, + 0x48, 0x07, 0x80, 0xF8, 0xE5, 0x70, 0x80, 0xF8, 0xE4, 0x70, 0x00, 0x27, + 0xC0, 0xF8, 0xC0, 0x70, 0xC0, 0xF8, 0xE8, 0x70, 0x80, 0xF8, 0xE1, 0x70, + 0x80, 0xF8, 0xE3, 0x70, 0x8E, 0x46, 0x58, 0xE0, 0x17, 0x78, 0x04, 0xF8, + 0x01, 0x7B, 0x2F, 0x88, 0x23, 0xF8, 0x02, 0x7B, 0xD7, 0x78, 0x01, 0x2F, + 0x02, 0xD0, 0x02, 0x2F, 0x09, 0xD0, 0x10, 0xE0, 0x90, 0xF8, 0xE4, 0x70, + 0x0E, 0xFA, 0x01, 0xFC, 0x27, 0xEA, 0x0C, 0x07, 0x80, 0xF8, 0xE4, 0x70, + 0x07, 0xE0, 0x90, 0xF8, 0xE5, 0x70, 0x0E, 0xFA, 0x01, 0xFC, 0x27, 0xEA, + 0x0C, 0x07, 0x80, 0xF8, 0xE5, 0x70, 0x4F, 0x1E, 0x07, 0xEB, 0x47, 0x0C, + 0x27, 0xF0, 0x01, 0x07, 0xBC, 0x44, 0x57, 0x78, 0x07, 0xF0, 0x07, 0x07, + 0x07, 0xFA, 0x0C, 0xF7, 0xD0, 0xF8, 0xC0, 0xC0, 0x47, 0xEA, 0x0C, 0x07, + 0xC0, 0xF8, 0xC0, 0x70, 0x97, 0x78, 0x4F, 0xEA, 0x81, 0x0C, 0x07, 0xF0, + 0x0F, 0x07, 0xAC, 0xF1, 0x04, 0x0C, 0x07, 0xFA, 0x0C, 0xF7, 0xD0, 0xF8, + 0xE8, 0xC0, 0x47, 0xEA, 0x0C, 0x07, 0xC0, 0xF8, 0xE8, 0x70, 0x17, 0x79, + 0xFF, 0x07, 0x07, 0xD0, 0x90, 0xF8, 0xE1, 0xC0, 0x0E, 0xFA, 0x01, 0xF7, + 0x4C, 0xEA, 0x07, 0x0C, 0x80, 0xF8, 0xE1, 0xC0, 0x17, 0x79, 0xFF, 0x06, + 0x07, 0xD5, 0x90, 0xF8, 0xE3, 0x70, 0x0E, 0xFA, 0x01, 0xFC, 0x47, 0xEA, + 0x0C, 0x07, 0x80, 0xF8, 0xE3, 0x70, 0x49, 0x1C, 0x08, 0x29, 0x04, 0xD2, + 0x52, 0x1D, 0xAD, 0x1C, 0x76, 0x1E, 0x00, 0x2E, 0xA4, 0xD1, 0xD0, 0xF8, + 0xE8, 0x10, 0x41, 0x64, 0xF0, 0xBD, 0xF0, 0xB5, 0x27, 0x4D, 0x28, 0x49, + 0x01, 0x26, 0xEC, 0x1D, 0xC3, 0x79, 0x00, 0x22, 0x07, 0x68, 0x4A, 0x60, + 0x09, 0x04, 0x4F, 0xF0, 0xFF, 0x0E, 0x81, 0xF8, 0xE5, 0xE0, 0x81, 0xF8, + 0xE4, 0x60, 0xC1, 0xF8, 0xC0, 0x20, 0x81, 0xF8, 0xE1, 0x20, 0x81, 0xF8, + 0xE3, 0x20, 0x18, 0xE0, 0x97, 0xF8, 0x00, 0xC0, 0x05, 0xF8, 0x01, 0xCB, + 0xB0, 0xF8, 0x04, 0xC0, 0x24, 0xF8, 0x02, 0xCB, 0x90, 0xF8, 0x06, 0xC0, + 0x4F, 0xEA, 0x86, 0x0E, 0x0C, 0xF0, 0x0F, 0x0C, 0xAE, 0xF1, 0x04, 0x0E, + 0x0C, 0xFA, 0x0E, 0xFC, 0x76, 0x1C, 0x4C, 0xEA, 0x02, 0x02, 0x08, 0x2E, + 0x03, 0xD2, 0x5B, 0x1E, 0x7F, 0x1C, 0x00, 0x2B, 0xE4, 0xD1, 0xC1, 0xF8, + 0xE8, 0x20, 0x4A, 0x64, 0xF0, 0xBD, 0x0D, 0x4A, 0xD2, 0x1D, 0x22, 0xF8, + 0x10, 0x10, 0x70, 0x47, 0x10, 0xB5, 0x04, 0x46, 0x0B, 0x48, 0x00, 0x68, + 0x38, 0xB1, 0xA0, 0x68, 0xFF, 0xF7, 0x46, 0xFF, 0x20, 0x68, 0xBD, 0xE8, + 0x10, 0x40, 0x00, 0xF0, 0x0F, 0xB8, 0xE0, 0x68, 0xFF, 0xF7, 0x3E, 0xFF, + 0x60, 0x68, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0xAB, 0xB8, 0x00, 0x00, + 0xAB, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x22, 0xBC, 0x05, 0x00, 0x22, + 0x10, 0xB5, 0x4F, 0x49, 0x02, 0x68, 0x00, 0x24, 0x8A, 0x60, 0x82, 0x88, + 0x4A, 0x80, 0x03, 0x89, 0x8B, 0x80, 0x0C, 0x70, 0x4F, 0xF0, 0x00, 0x51, + 0xA1, 0xF8, 0x1A, 0x31, 0xA1, 0xF8, 0x1E, 0x21, 0xC0, 0x88, 0xA1, 0xF8, + 0x20, 0x01, 0x47, 0x48, 0x01, 0x21, 0xC0, 0xF8, 0xD8, 0x11, 0xC0, 0xF8, + 0xDC, 0x11, 0xC0, 0xF8, 0xC4, 0x11, 0xC0, 0xF8, 0xCC, 0x11, 0xC0, 0xF8, + 0xD4, 0x11, 0xC0, 0xF8, 0x80, 0x11, 0x72, 0xB6, 0xD0, 0xF8, 0x08, 0x22, + 0x00, 0x2A, 0xFB, 0xD1, 0x41, 0x60, 0x62, 0xB6, 0x10, 0xBD, 0x2D, 0xE9, + 0xF0, 0x41, 0x3B, 0x4C, 0xD4, 0xF8, 0x5C, 0x01, 0x38, 0x4E, 0x25, 0x04, + 0x01, 0x27, 0xB2, 0x68, 0x50, 0xB3, 0xB5, 0xF8, 0x1C, 0x81, 0x5F, 0xEA, + 0x08, 0x00, 0x0F, 0xD0, 0xD4, 0xF8, 0x54, 0x01, 0x10, 0xB9, 0xD4, 0xF8, + 0x00, 0x01, 0x48, 0xB1, 0x41, 0x46, 0x01, 0x20, 0x90, 0x47, 0xC4, 0xF8, + 0xD8, 0x72, 0xD4, 0xF8, 0x54, 0x01, 0x08, 0xB1, 0xC4, 0xF8, 0xD4, 0x72, + 0xB2, 0x68, 0x41, 0x46, 0x02, 0x20, 0x90, 0x47, 0x01, 0x78, 0x02, 0x29, + 0x02, 0xD0, 0x03, 0x29, 0x02, 0xD0, 0x08, 0xE0, 0x41, 0x88, 0x00, 0xE0, + 0x71, 0x88, 0xA5, 0xF8, 0x1E, 0x11, 0x80, 0x88, 0xA5, 0xF8, 0x1A, 0x01, + 0x37, 0x70, 0xC4, 0xF8, 0xDC, 0x72, 0x38, 0xE0, 0xD4, 0xF8, 0x44, 0x01, + 0x80, 0xB1, 0xB5, 0xF8, 0x1C, 0x11, 0x03, 0x20, 0x90, 0x47, 0x30, 0x78, + 0x38, 0xB1, 0x70, 0x88, 0xA5, 0xF8, 0x1E, 0x01, 0xB0, 0x88, 0xA5, 0xF8, + 0x1A, 0x01, 0x00, 0x20, 0x30, 0x70, 0xC4, 0xF8, 0xC4, 0x72, 0x24, 0xE0, + 0xD4, 0xF8, 0x58, 0x01, 0x30, 0xB1, 0xB5, 0xF8, 0x1C, 0x11, 0x01, 0x20, + 0x90, 0x47, 0xC4, 0xF8, 0xD8, 0x72, 0x1A, 0xE0, 0xD4, 0xF8, 0x4C, 0x01, + 0x28, 0xB9, 0xD4, 0xF8, 0x54, 0x01, 0x10, 0xB9, 0xD4, 0xF8, 0x00, 0x01, + 0x88, 0xB1, 0xB5, 0xF8, 0x1C, 0x11, 0x19, 0xB1, 0x01, 0x20, 0x90, 0x47, + 0xC4, 0xF8, 0xD8, 0x72, 0xD4, 0xF8, 0x4C, 0x01, 0x10, 0xB1, 0xC4, 0xF8, + 0xCC, 0x72, 0x04, 0xE0, 0xD4, 0xF8, 0x54, 0x01, 0x08, 0xB1, 0xC4, 0xF8, + 0xD4, 0x72, 0xD4, 0xF8, 0x00, 0x01, 0x00, 0x28, 0x01, 0xD0, 0xC4, 0xF8, + 0x80, 0x72, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, 0x2C, 0x04, 0x10, 0x00, + 0x00, 0x20, 0x00, 0x22, 0xC1, 0x7D, 0x01, 0x29, 0x05, 0xD1, 0x49, 0x07, + 0x11, 0xF8, 0x2D, 0x2F, 0x42, 0xF0, 0x02, 0x02, 0x0A, 0x70, 0x04, 0x49, + 0x02, 0x68, 0x4A, 0x60, 0x42, 0x68, 0x8A, 0x60, 0x80, 0x7D, 0x08, 0x70, + 0x70, 0x47, 0x00, 0x00, 0x38, 0x04, 0x10, 0x00, 0xE9, 0x49, 0x00, 0x20, + 0x08, 0x60, 0x09, 0x1D, 0x08, 0x60, 0x09, 0x1D, 0x08, 0x60, 0x09, 0x1D, + 0x08, 0x60, 0x09, 0x1D, 0x08, 0x60, 0x09, 0x1D, 0x08, 0x60, 0x09, 0x1D, + 0x08, 0x60, 0x09, 0x1D, 0x08, 0x60, 0xE2, 0x49, 0x01, 0x22, 0x0A, 0x60, + 0xE0, 0x49, 0x14, 0x31, 0x08, 0x60, 0x51, 0x07, 0x01, 0xF8, 0x50, 0x0F, + 0xF0, 0x23, 0x4B, 0x70, 0x0F, 0x23, 0x01, 0xF8, 0x05, 0x3C, 0x10, 0x23, + 0x4B, 0x80, 0x8A, 0x80, 0xDA, 0x49, 0x08, 0x60, 0x48, 0x60, 0x88, 0x60, + 0xC8, 0x60, 0x08, 0x61, 0x48, 0x61, 0x88, 0x61, 0xC8, 0x61, 0x08, 0x62, + 0x70, 0x47, 0x70, 0x47, 0xD4, 0x4A, 0x11, 0x60, 0xD1, 0x49, 0x00, 0x22, + 0x0A, 0x60, 0x00, 0xEB, 0xC0, 0x02, 0x02, 0xEB, 0x00, 0x10, 0x4F, 0xF6, + 0xFF, 0x72, 0x02, 0xEA, 0x80, 0x00, 0x4F, 0xF0, 0x00, 0x52, 0xA2, 0xF8, + 0x58, 0x00, 0x01, 0x20, 0x08, 0x60, 0x70, 0x47, 0x4F, 0xF0, 0x00, 0x50, + 0x90, 0xF8, 0x22, 0x00, 0xC0, 0xF3, 0x81, 0x00, 0x28, 0xB1, 0x01, 0x28, + 0x05, 0xD0, 0x02, 0x28, 0x05, 0xD0, 0xC6, 0x48, 0x70, 0x47, 0xC6, 0x48, + 0x70, 0x47, 0xC6, 0x48, 0x70, 0x47, 0xC6, 0x48, 0x70, 0x47, 0x70, 0xB5, + 0x4F, 0xF0, 0x00, 0x54, 0x72, 0xB6, 0x65, 0x69, 0x60, 0x69, 0x40, 0xF0, + 0x04, 0x00, 0x60, 0x61, 0xBA, 0x49, 0x00, 0x20, 0x08, 0x60, 0xB4, 0xF8, + 0x58, 0x10, 0x09, 0xB1, 0xA4, 0xF8, 0x58, 0x00, 0xFF, 0xF7, 0x35, 0xFC, + 0x01, 0x46, 0xFF, 0xF7, 0xD7, 0xFF, 0xB1, 0xFB, 0xF0, 0xF0, 0xFE, 0xF7, + 0xCD, 0xFD, 0x65, 0x61, 0x02, 0x20, 0x00, 0xF0, 0x56, 0xF9, 0x62, 0xB6, + 0x70, 0xBD, 0xB1, 0x48, 0x10, 0xB5, 0x00, 0x21, 0x04, 0x68, 0x01, 0x60, + 0xFF, 0xF7, 0xD9, 0xFF, 0x1C, 0xB1, 0xA4, 0x46, 0xBD, 0xE8, 0x10, 0x40, + 0x60, 0x47, 0x00, 0x20, 0xFF, 0xF7, 0xA9, 0xFF, 0x10, 0xBD, 0xA9, 0x4A, + 0x51, 0x60, 0xA6, 0x49, 0x00, 0x22, 0x09, 0x1D, 0x0A, 0x60, 0x00, 0xEB, + 0xC0, 0x02, 0x02, 0xEB, 0x00, 0x10, 0x4F, 0xF6, 0xFF, 0x72, 0x02, 0xEA, + 0x80, 0x00, 0xCA, 0x06, 0xA2, 0xF8, 0x5A, 0x00, 0x01, 0x20, 0x08, 0x60, + 0x70, 0x47, 0x70, 0xB5, 0x4F, 0xF0, 0x00, 0x54, 0x72, 0xB6, 0x65, 0x69, + 0x60, 0x69, 0x40, 0xF0, 0x08, 0x00, 0x60, 0x61, 0x98, 0x49, 0x00, 0x20, + 0x09, 0x1D, 0x08, 0x60, 0xB4, 0xF8, 0x5A, 0x10, 0x09, 0xB1, 0xA4, 0xF8, + 0x5A, 0x00, 0xFF, 0xF7, 0xF0, 0xFB, 0x01, 0x46, 0xFF, 0xF7, 0x92, 0xFF, + 0xB1, 0xFB, 0xF0, 0xF0, 0xFE, 0xF7, 0x88, 0xFD, 0x65, 0x61, 0x03, 0x20, + 0x00, 0xF0, 0x11, 0xF9, 0x62, 0xB6, 0x70, 0xBD, 0x8E, 0x48, 0x10, 0xB5, + 0x00, 0x21, 0x44, 0x68, 0x41, 0x60, 0xFF, 0xF7, 0xD8, 0xFF, 0x1C, 0xB1, + 0xA4, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x60, 0x47, 0x01, 0x20, 0xFF, 0xF7, + 0x64, 0xFF, 0x10, 0xBD, 0x70, 0xB5, 0x4F, 0xF0, 0x00, 0x54, 0x72, 0xB6, + 0x65, 0x69, 0x60, 0x69, 0x40, 0xF0, 0x10, 0x00, 0x60, 0x61, 0x80, 0x49, + 0x00, 0x20, 0x08, 0x31, 0x08, 0x60, 0xB4, 0xF8, 0x5C, 0x10, 0x09, 0xB1, + 0xA4, 0xF8, 0x5C, 0x00, 0xFF, 0xF7, 0xBF, 0xFB, 0x01, 0x46, 0xFF, 0xF7, + 0x61, 0xFF, 0xB1, 0xFB, 0xF0, 0xF0, 0xFE, 0xF7, 0x57, 0xFD, 0x65, 0x61, + 0x04, 0x20, 0x00, 0xF0, 0xE0, 0xF8, 0x62, 0xB6, 0x70, 0xBD, 0x76, 0x48, + 0x10, 0xB5, 0x00, 0x21, 0x84, 0x68, 0x81, 0x60, 0xFF, 0xF7, 0xD8, 0xFF, + 0x1C, 0xB1, 0xA4, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x60, 0x47, 0x02, 0x20, + 0xFF, 0xF7, 0x33, 0xFF, 0x10, 0xBD, 0x70, 0xB5, 0x4F, 0xF0, 0x00, 0x54, + 0x72, 0xB6, 0x65, 0x69, 0x60, 0x69, 0x40, 0xF0, 0x20, 0x00, 0x60, 0x61, + 0x67, 0x49, 0x00, 0x20, 0x0C, 0x31, 0x08, 0x60, 0xB4, 0xF8, 0x5E, 0x10, + 0x09, 0xB1, 0xA4, 0xF8, 0x5E, 0x00, 0xFF, 0xF7, 0x8E, 0xFB, 0x01, 0x46, + 0xFF, 0xF7, 0x30, 0xFF, 0xB1, 0xFB, 0xF0, 0xF0, 0xFE, 0xF7, 0x26, 0xFD, + 0x65, 0x61, 0x05, 0x20, 0x00, 0xF0, 0xAF, 0xF8, 0x62, 0xB6, 0x70, 0xBD, + 0x5D, 0x48, 0x10, 0xB5, 0x00, 0x21, 0xC4, 0x68, 0xC1, 0x60, 0xFF, 0xF7, + 0xD8, 0xFF, 0x1C, 0xB1, 0xA4, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x60, 0x47, + 0x03, 0x20, 0xFF, 0xF7, 0x02, 0xFF, 0x10, 0xBD, 0x4F, 0xF0, 0x00, 0x50, + 0xB0, 0xF8, 0x60, 0x00, 0x70, 0x47, 0x53, 0x49, 0x10, 0xB5, 0x00, 0x22, + 0x08, 0x69, 0x0A, 0x61, 0x4E, 0x49, 0x10, 0x31, 0x0A, 0x60, 0x10, 0xB1, + 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x47, 0x04, 0x20, 0xFF, 0xF7, 0xED, 0xFE, + 0x10, 0xBD, 0x4B, 0x4A, 0x00, 0x23, 0x51, 0x61, 0x47, 0x49, 0x14, 0x31, + 0x0B, 0x60, 0x12, 0x6A, 0x50, 0x43, 0x4F, 0xF0, 0x00, 0x52, 0x80, 0x09, + 0xA2, 0xF8, 0x62, 0x00, 0x01, 0x20, 0x08, 0x60, 0x70, 0x47, 0x41, 0x49, + 0x00, 0x20, 0x14, 0x31, 0x08, 0x60, 0x70, 0x47, 0x40, 0x49, 0x10, 0xB5, + 0x00, 0x22, 0x48, 0x69, 0x4A, 0x61, 0x3C, 0x49, 0x14, 0x31, 0x0A, 0x60, + 0x10, 0xB1, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x47, 0x05, 0x20, 0xFF, 0xF7, + 0xC8, 0xFE, 0x10, 0xBD, 0x38, 0x49, 0x10, 0xB5, 0x00, 0x22, 0x88, 0x69, + 0x8A, 0x61, 0x34, 0x49, 0x18, 0x31, 0x0A, 0x60, 0x10, 0xB1, 0xBD, 0xE8, + 0x10, 0x40, 0x00, 0x47, 0x06, 0x20, 0xFF, 0xF7, 0xB8, 0xFE, 0x10, 0xBD, + 0x10, 0xB5, 0xFF, 0xF7, 0x0B, 0xFB, 0x4F, 0xF0, 0x00, 0x51, 0x91, 0xF8, + 0x22, 0x20, 0x42, 0xF2, 0x10, 0x73, 0xB0, 0xFB, 0xF3, 0xF0, 0xC2, 0xF3, + 0x81, 0x02, 0x52, 0x1C, 0xD0, 0x40, 0xB1, 0xF8, 0x54, 0x20, 0xC9, 0x6C, + 0x51, 0x43, 0x89, 0x09, 0xB0, 0xFB, 0xF1, 0xF0, 0x10, 0xBD, 0x25, 0x49, + 0xC8, 0x61, 0x22, 0x49, 0x01, 0x20, 0xB8, 0x31, 0x08, 0x60, 0x09, 0x1D, + 0x08, 0x60, 0x70, 0x47, 0x20, 0x48, 0x10, 0xB5, 0x00, 0x22, 0xC1, 0x69, + 0xC2, 0x61, 0x51, 0xB1, 0x1B, 0x48, 0xB8, 0x30, 0x02, 0x60, 0x4F, 0xF0, + 0x00, 0x50, 0xC0, 0x6C, 0xBD, 0xE8, 0x10, 0x40, 0x20, 0xF0, 0x7F, 0x40, + 0x08, 0x47, 0xFF, 0x20, 0xFF, 0xF7, 0x83, 0xFE, 0x10, 0xBD, 0x10, 0xB5, + 0x04, 0x46, 0xFF, 0xF7, 0xD5, 0xFA, 0x4F, 0xF0, 0x00, 0x51, 0x91, 0xF8, + 0x22, 0x10, 0x42, 0xF2, 0x10, 0x72, 0xB0, 0xFB, 0xF2, 0xF0, 0xC1, 0xF3, + 0x81, 0x01, 0x49, 0x1C, 0xC8, 0x40, 0x00, 0x03, 0xB0, 0xFB, 0xF4, 0xF0, + 0x0C, 0x49, 0x08, 0x62, 0x10, 0xBD, 0x4F, 0xF0, 0x00, 0x50, 0x90, 0xF8, + 0x4A, 0x00, 0x00, 0x07, 0x00, 0xD0, 0x01, 0x20, 0x70, 0x47, 0x00, 0xF0, + 0x1F, 0x02, 0x01, 0x21, 0x91, 0x40, 0x40, 0x09, 0x80, 0x00, 0x00, 0xF1, + 0xE0, 0x20, 0xC0, 0xF8, 0x80, 0x12, 0x70, 0x47, 0x40, 0x09, 0x00, 0x22, + 0xC0, 0x04, 0x00, 0x22, 0x44, 0x04, 0x10, 0x00, 0x00, 0x09, 0x3D, 0x00, + 0x00, 0x48, 0xE8, 0x01, 0x00, 0x24, 0xF4, 0x00, 0x00, 0x12, 0x7A, 0x00, + 0x10, 0xB5, 0x01, 0x46, 0x34, 0x22, 0xF6, 0x48, 0x15, 0xF0, 0xCC, 0xFB, + 0x01, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x20, 0xFE, 0xF7, 0x8D, 0xBD, + 0x38, 0xB5, 0x04, 0x46, 0xF1, 0x48, 0xF0, 0x4D, 0x20, 0x60, 0x20, 0x46, + 0x15, 0xF0, 0x03, 0xF8, 0x00, 0x22, 0x6B, 0x46, 0x01, 0x21, 0x10, 0x46, + 0xFE, 0xF7, 0xC8, 0xFD, 0x01, 0x21, 0x00, 0x20, 0xFE, 0xF7, 0xA7, 0xFD, + 0x28, 0x78, 0x00, 0x28, 0x02, 0xD0, 0x10, 0xF0, 0x8A, 0xFD, 0xEC, 0xE7, + 0x38, 0xBD, 0xE7, 0x48, 0x02, 0x68, 0x92, 0xF8, 0xB0, 0x00, 0xC1, 0x07, + 0x0E, 0xD0, 0xE2, 0x49, 0x01, 0x23, 0x34, 0x31, 0x4B, 0x73, 0xC0, 0xF3, + 0xC1, 0x03, 0x02, 0x2B, 0x01, 0xD1, 0x00, 0x23, 0x4B, 0x73, 0x80, 0x07, + 0x02, 0xD5, 0x92, 0xF8, 0xBB, 0x00, 0x08, 0x73, 0x70, 0x47, 0xDC, 0x48, + 0x10, 0xB5, 0x03, 0x68, 0x93, 0xF8, 0xB0, 0x20, 0xD0, 0x07, 0x16, 0xD0, + 0x90, 0x07, 0x14, 0xD5, 0xD8, 0x48, 0x40, 0x78, 0x00, 0x28, 0x10, 0xD1, + 0xD3, 0x48, 0x34, 0x30, 0x00, 0x21, 0x04, 0x7B, 0x0C, 0xB1, 0x41, 0x73, + 0x08, 0xE0, 0x01, 0x24, 0xC2, 0xF3, 0xC1, 0x02, 0x44, 0x73, 0x02, 0x2A, + 0x00, 0xD1, 0x41, 0x73, 0x93, 0xF8, 0xBB, 0x10, 0x01, 0x73, 0x10, 0xBD, + 0x2D, 0xE9, 0xF0, 0x47, 0xDF, 0xF8, 0x2C, 0x83, 0x82, 0x46, 0x01, 0x27, + 0xD8, 0xF8, 0x00, 0x00, 0xCA, 0x4D, 0x90, 0xF8, 0x31, 0x40, 0x10, 0xF8, + 0x30, 0x1F, 0x90, 0xF8, 0x31, 0x00, 0x4C, 0x43, 0x00, 0xF0, 0x03, 0x00, + 0x87, 0x40, 0xA1, 0x00, 0x28, 0x46, 0x15, 0xF0, 0xBD, 0xFB, 0xFF, 0xF7, + 0xB2, 0xFF, 0x00, 0x26, 0xDF, 0xF8, 0xF4, 0x92, 0x15, 0xE0, 0xBC, 0x48, + 0x34, 0x30, 0xFF, 0xF7, 0x91, 0xFF, 0x00, 0x20, 0xD9, 0xF8, 0x08, 0x10, + 0x08, 0xE0, 0x00, 0xBF, 0x55, 0xF8, 0x20, 0x20, 0x31, 0xF9, 0x10, 0x30, + 0x1A, 0x44, 0x45, 0xF8, 0x20, 0x20, 0x40, 0x1C, 0xA0, 0x42, 0xF5, 0xDB, + 0xFF, 0xF7, 0xAF, 0xFF, 0x76, 0x1C, 0xBE, 0x42, 0xE7, 0xDB, 0x40, 0x46, + 0x0A, 0xE0, 0x00, 0xBF, 0x02, 0x68, 0x55, 0xF8, 0x24, 0x10, 0x92, 0xF8, + 0x61, 0x20, 0x02, 0xF0, 0x03, 0x02, 0x11, 0x41, 0x2A, 0xF8, 0x14, 0x10, + 0x64, 0x1E, 0xF3, 0xD2, 0xBD, 0xE8, 0xF0, 0x87, 0x2D, 0xE9, 0xF0, 0x4F, + 0xDF, 0xF8, 0xA0, 0xB2, 0x4F, 0xF0, 0x01, 0x09, 0xA8, 0x4E, 0xDB, 0xF8, + 0x00, 0x00, 0x9F, 0xB0, 0x90, 0xF8, 0x61, 0x10, 0x90, 0xF8, 0x31, 0x40, + 0xC1, 0xF3, 0x81, 0x08, 0x90, 0xF8, 0x30, 0x50, 0x09, 0xFA, 0x08, 0xFA, + 0x60, 0x19, 0x81, 0x00, 0x06, 0xEB, 0x84, 0x07, 0x30, 0x46, 0x15, 0xF0, + 0x73, 0xFB, 0x9A, 0x48, 0x34, 0x30, 0x14, 0xF0, 0x33, 0xFF, 0x98, 0x48, + 0x34, 0x30, 0x80, 0xF8, 0x06, 0x90, 0xDB, 0xF8, 0x00, 0x10, 0x91, 0xF8, + 0x60, 0x20, 0x92, 0x07, 0x01, 0xD5, 0x80, 0xF8, 0x04, 0x90, 0x91, 0xF8, + 0x62, 0x10, 0x01, 0x73, 0xFF, 0xF7, 0x55, 0xFF, 0xDB, 0xF8, 0x00, 0x00, + 0x90, 0xF8, 0x60, 0x00, 0xC0, 0x07, 0x05, 0xD0, 0x8C, 0x48, 0x34, 0x30, + 0xFF, 0xF7, 0x32, 0xFF, 0xFF, 0xF7, 0x5F, 0xFF, 0x00, 0x20, 0x2E, 0xE0, + 0x88, 0x48, 0x34, 0x30, 0xFF, 0xF7, 0x2A, 0xFF, 0xDF, 0xF8, 0x18, 0xB2, + 0x62, 0x00, 0x13, 0xA8, 0xDB, 0xF8, 0x18, 0x10, 0x15, 0xF0, 0xA3, 0xFA, + 0x6A, 0x00, 0x68, 0x46, 0xDB, 0xF8, 0x1C, 0x10, 0x15, 0xF0, 0x9D, 0xFA, + 0x20, 0x46, 0x13, 0xA9, 0x07, 0xE0, 0x00, 0xBF, 0x56, 0xF8, 0x20, 0x20, + 0x31, 0xF9, 0x10, 0x30, 0x1A, 0x44, 0x46, 0xF8, 0x20, 0x20, 0x40, 0x1E, + 0xF6, 0xD2, 0x28, 0x46, 0x69, 0x46, 0x06, 0xE0, 0x57, 0xF8, 0x20, 0x20, + 0x31, 0xF9, 0x10, 0x30, 0x1A, 0x44, 0x47, 0xF8, 0x20, 0x20, 0x40, 0x1E, + 0xF6, 0xD2, 0xFF, 0xF7, 0x30, 0xFF, 0x09, 0xF1, 0x01, 0x00, 0x81, 0x46, + 0x50, 0x45, 0xCD, 0xDB, 0x74, 0x49, 0x05, 0xE0, 0x56, 0xF8, 0x24, 0x00, + 0x40, 0xFA, 0x08, 0xF0, 0x21, 0xF8, 0x14, 0x00, 0x64, 0x1E, 0xF7, 0xD2, + 0x70, 0x49, 0x05, 0xE0, 0x57, 0xF8, 0x25, 0x00, 0x40, 0xFA, 0x08, 0xF0, + 0x21, 0xF8, 0x15, 0x00, 0x6D, 0x1E, 0xF7, 0xD2, 0x1F, 0xB0, 0xBD, 0xE8, + 0xF0, 0x8F, 0x2D, 0xE9, 0xFF, 0x5F, 0xDF, 0xF8, 0x94, 0x81, 0x66, 0x4F, + 0xD8, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0x31, 0x40, 0x90, 0xF8, 0x30, 0x50, + 0x07, 0xEB, 0x84, 0x0A, 0x60, 0x19, 0x81, 0x00, 0x04, 0xFB, 0x05, 0xFB, + 0x0A, 0xEB, 0x85, 0x06, 0x38, 0x46, 0x15, 0xF0, 0xF1, 0xFA, 0x4F, 0xEA, + 0x8B, 0x01, 0x30, 0x46, 0x15, 0xF0, 0xEC, 0xFA, 0x56, 0x48, 0x34, 0x30, + 0x14, 0xF0, 0xAC, 0xFE, 0x54, 0x48, 0x4F, 0xF0, 0x01, 0x09, 0x34, 0x30, + 0x80, 0xF8, 0x06, 0x90, 0x80, 0xF8, 0x04, 0x90, 0xD8, 0xF8, 0x00, 0x10, + 0x91, 0xF8, 0x62, 0x10, 0x01, 0x73, 0xFF, 0xF7, 0xD0, 0xFE, 0xD8, 0xF8, + 0x00, 0x00, 0x90, 0xF8, 0x60, 0x00, 0xC0, 0x07, 0x05, 0xD0, 0x4A, 0x48, + 0x34, 0x30, 0xFF, 0xF7, 0xAD, 0xFE, 0xFF, 0xF7, 0xDA, 0xFE, 0xD8, 0xF8, + 0x00, 0x00, 0x90, 0xF8, 0x61, 0x00, 0xC0, 0xF3, 0x81, 0x01, 0x02, 0x91, + 0x00, 0xF0, 0x03, 0x01, 0x03, 0x91, 0x02, 0x99, 0x48, 0x46, 0x09, 0xFA, + 0x01, 0xF9, 0x03, 0x99, 0x88, 0x40, 0x01, 0x90, 0x00, 0x20, 0x32, 0xE0, + 0x3D, 0x48, 0x34, 0x30, 0xFF, 0xF7, 0x94, 0xFE, 0x3B, 0x48, 0xD0, 0xE9, + 0x06, 0x32, 0x81, 0x68, 0x20, 0x46, 0x06, 0xE0, 0x57, 0xF8, 0x20, 0xC0, + 0x33, 0xF9, 0x10, 0x80, 0xC4, 0x44, 0x47, 0xF8, 0x20, 0xC0, 0x40, 0x1E, + 0xF6, 0xD2, 0x28, 0x46, 0x07, 0xE0, 0x00, 0xBF, 0x5A, 0xF8, 0x20, 0x30, + 0x32, 0xF9, 0x10, 0xC0, 0x9C, 0x44, 0x4A, 0xF8, 0x20, 0xC0, 0x40, 0x1E, + 0xF6, 0xD2, 0xDD, 0xE9, 0x00, 0x02, 0x90, 0x42, 0x0B, 0xDA, 0x58, 0x46, + 0x07, 0xE0, 0x00, 0xBF, 0x56, 0xF8, 0x20, 0x20, 0x31, 0xF9, 0x10, 0x30, + 0x1A, 0x44, 0x46, 0xF8, 0x20, 0x20, 0x40, 0x1E, 0xF6, 0xD2, 0xFF, 0xF7, + 0x96, 0xFE, 0x00, 0x98, 0x40, 0x1C, 0x00, 0x90, 0x48, 0x45, 0xC9, 0xDB, + 0x01, 0x98, 0x48, 0x45, 0x1F, 0xDD, 0x21, 0x48, 0x00, 0x21, 0x34, 0x30, + 0x88, 0x46, 0x81, 0x71, 0x01, 0x99, 0xA1, 0xEB, 0x09, 0x09, 0x14, 0xE0, + 0x1C, 0x48, 0x34, 0x30, 0xFF, 0xF7, 0x52, 0xFE, 0x1A, 0x48, 0x81, 0x68, + 0x58, 0x46, 0x06, 0xE0, 0x56, 0xF8, 0x20, 0x20, 0x31, 0xF9, 0x10, 0x30, + 0x1A, 0x44, 0x46, 0xF8, 0x20, 0x20, 0x40, 0x1E, 0xF6, 0xD2, 0xFF, 0xF7, + 0x72, 0xFE, 0x08, 0xF1, 0x01, 0x08, 0xC1, 0x45, 0xE8, 0xDC, 0x16, 0x49, + 0x06, 0xE0, 0x00, 0xBF, 0x57, 0xF8, 0x24, 0x00, 0x02, 0x9A, 0x10, 0x41, + 0x21, 0xF8, 0x14, 0x00, 0x64, 0x1E, 0xF7, 0xD2, 0x11, 0x49, 0x05, 0xE0, + 0x5A, 0xF8, 0x25, 0x00, 0x02, 0x9A, 0x10, 0x41, 0x21, 0xF8, 0x15, 0x00, + 0x6D, 0x1E, 0xF7, 0xD2, 0x58, 0x46, 0x0D, 0x4A, 0x06, 0xE0, 0x00, 0xBF, + 0x56, 0xF8, 0x20, 0x10, 0x03, 0x9B, 0x19, 0x41, 0x22, 0xF8, 0x10, 0x10, + 0x40, 0x1E, 0xF7, 0xD2, 0xBD, 0xE8, 0xFF, 0x9F, 0xF4, 0x0E, 0x10, 0x00, + 0xF1, 0x19, 0x00, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x74, 0x07, 0x10, 0x00, + 0xD4, 0x56, 0x10, 0x00, 0x7E, 0x4A, 0x01, 0x20, 0xA8, 0x4A, 0x01, 0x20, + 0x42, 0x44, 0x01, 0x20, 0x2D, 0xE9, 0xF8, 0x43, 0x14, 0xF0, 0x53, 0xFE, + 0x00, 0x90, 0x04, 0x21, 0x68, 0x46, 0xFF, 0xF7, 0xDA, 0xF9, 0xDF, 0xF8, + 0xA0, 0x82, 0xC6, 0xB2, 0x01, 0x27, 0xD8, 0xF8, 0x00, 0x00, 0xA6, 0x4C, + 0x90, 0xF8, 0x61, 0x00, 0x80, 0x09, 0x07, 0xFA, 0x00, 0xF5, 0xB1, 0x00, + 0x20, 0x46, 0x15, 0xF0, 0x15, 0xFA, 0xA2, 0x48, 0x14, 0xF0, 0xD6, 0xFD, + 0xA0, 0x48, 0xA0, 0xF1, 0x34, 0x09, 0x87, 0x72, 0x00, 0x27, 0x12, 0xE0, + 0x9D, 0x48, 0xFF, 0xF7, 0xE7, 0xFD, 0x00, 0x20, 0xD9, 0xF8, 0x2C, 0x10, + 0x08, 0xE0, 0x00, 0xBF, 0x54, 0xF8, 0x20, 0x20, 0x31, 0xF9, 0x10, 0x30, + 0x1A, 0x44, 0x44, 0xF8, 0x20, 0x20, 0x40, 0x1C, 0xB0, 0x42, 0xF5, 0xDB, + 0x7F, 0x1C, 0xAF, 0x42, 0xEA, 0xDB, 0x00, 0x20, 0x93, 0x4B, 0xD8, 0xF8, + 0x00, 0x10, 0x08, 0xE0, 0x91, 0xF8, 0x61, 0x50, 0x54, 0xF8, 0x20, 0x20, + 0xAD, 0x09, 0x2A, 0x41, 0x23, 0xF8, 0x10, 0x20, 0x40, 0x1C, 0xB0, 0x42, + 0xF4, 0xDB, 0xBD, 0xE8, 0xF8, 0x83, 0x2D, 0xE9, 0xF0, 0x47, 0x05, 0x46, + 0x00, 0x20, 0xFE, 0xF7, 0x2A, 0xFC, 0x02, 0x20, 0xFE, 0xF7, 0x27, 0xFC, + 0x03, 0x20, 0xFE, 0xF7, 0x24, 0xFC, 0x86, 0x4E, 0x00, 0x20, 0x30, 0x70, + 0x82, 0x48, 0x14, 0xF0, 0x97, 0xFD, 0x84, 0x48, 0x01, 0x24, 0x04, 0x70, + 0x7D, 0x4F, 0xDF, 0xF8, 0x0C, 0x82, 0xDF, 0xF8, 0x0C, 0x92, 0x38, 0x68, + 0x90, 0xF8, 0x60, 0x00, 0x80, 0x07, 0x4F, 0xEA, 0x05, 0x70, 0x0B, 0xD5, + 0x00, 0x28, 0x11, 0xDA, 0xA8, 0x07, 0x09, 0xD5, 0x34, 0x70, 0xFF, 0xF7, + 0xB6, 0xFE, 0x88, 0xF8, 0x00, 0x40, 0x89, 0xF8, 0x00, 0x40, 0x01, 0xE0, + 0x00, 0x28, 0x05, 0xDA, 0x30, 0x78, 0x18, 0xB9, 0xFF, 0xF7, 0x24, 0xFE, + 0x88, 0xF8, 0x00, 0x40, 0x28, 0x06, 0x08, 0xD5, 0x38, 0x68, 0x90, 0xF8, + 0x2F, 0x0A, 0xC0, 0x07, 0x03, 0xD0, 0x72, 0x48, 0x04, 0x70, 0xFF, 0xF7, + 0x77, 0xFF, 0xDF, 0xF8, 0xA8, 0x81, 0xA8, 0x07, 0x11, 0xD5, 0x30, 0x78, + 0xD0, 0xB9, 0x40, 0x46, 0x14, 0xF0, 0x60, 0xFD, 0x88, 0xF8, 0x04, 0x40, + 0x6B, 0x48, 0xFF, 0xF7, 0xC3, 0xFD, 0x6A, 0x48, 0x00, 0xF0, 0x23, 0xF8, + 0x69, 0x49, 0x08, 0x70, 0x89, 0xF8, 0x00, 0x40, 0x0A, 0xE0, 0x68, 0x07, + 0x08, 0xD5, 0x5E, 0x48, 0x14, 0xF0, 0x4E, 0xFD, 0x04, 0x21, 0x88, 0xF8, + 0x04, 0x10, 0x62, 0x48, 0xFF, 0xF7, 0xB0, 0xFD, 0x38, 0x68, 0x90, 0xF8, + 0x61, 0x04, 0x18, 0xB1, 0xE8, 0x06, 0x01, 0xD5, 0x00, 0xF0, 0x5E, 0xF8, + 0x03, 0x20, 0xFE, 0xF7, 0xDF, 0xFB, 0x02, 0x20, 0xFE, 0xF7, 0xDC, 0xFB, + 0xBD, 0xE8, 0xF0, 0x47, 0x00, 0x20, 0xFE, 0xF7, 0xD7, 0xBB, 0x2D, 0xE9, + 0xF0, 0x43, 0x4D, 0x49, 0x4F, 0xF0, 0x00, 0x09, 0xCC, 0x46, 0x0F, 0x68, + 0x4B, 0x46, 0x97, 0xF8, 0x31, 0x20, 0x97, 0xF8, 0x30, 0x60, 0x97, 0xF8, + 0x60, 0x40, 0x02, 0xFB, 0x06, 0xF1, 0x09, 0xB2, 0x64, 0x07, 0x37, 0xD5, + 0x4F, 0x4C, 0x24, 0x68, 0x25, 0x8E, 0x8D, 0x42, 0x32, 0xD1, 0x32, 0x34, + 0x28, 0xE0, 0x35, 0x46, 0x20, 0xE0, 0x00, 0xBF, 0x34, 0xF8, 0x15, 0x10, + 0x30, 0xF8, 0x15, 0x80, 0xA1, 0xEB, 0x08, 0x01, 0x09, 0xB2, 0x00, 0x29, + 0x01, 0xDB, 0x88, 0x46, 0x01, 0xE0, 0xC1, 0xF1, 0x00, 0x08, 0xE0, 0x45, + 0x07, 0xDD, 0x00, 0x29, 0x01, 0xDB, 0x8C, 0x46, 0x01, 0xE0, 0xC1, 0xF1, + 0x00, 0x0C, 0x0F, 0xFA, 0x8C, 0xFC, 0x00, 0x29, 0x00, 0xDA, 0x49, 0x42, + 0xB7, 0xF8, 0x63, 0x80, 0x41, 0x45, 0x01, 0xDD, 0x5B, 0x1C, 0x9B, 0xB2, + 0x6D, 0x1E, 0xDD, 0xD1, 0x04, 0xEB, 0x46, 0x04, 0x00, 0xEB, 0x46, 0x00, + 0x52, 0x1E, 0xD4, 0xD2, 0x97, 0xF8, 0x65, 0x00, 0x98, 0x42, 0x01, 0xD2, + 0x4F, 0xF0, 0x01, 0x09, 0x34, 0x48, 0xA0, 0xF8, 0x00, 0xC0, 0x34, 0x48, + 0x03, 0x80, 0x48, 0x46, 0xBD, 0xE8, 0xF0, 0x83, 0x2D, 0xE9, 0xF0, 0x47, + 0xDF, 0xF8, 0x8C, 0x80, 0x01, 0x21, 0x45, 0x46, 0xD8, 0xF8, 0x00, 0x00, + 0x00, 0xF2, 0x61, 0x40, 0xFF, 0xF7, 0xC7, 0xF8, 0x04, 0x46, 0x28, 0x68, + 0x01, 0x27, 0x1E, 0x4D, 0x90, 0xF8, 0x61, 0x00, 0xC0, 0xF3, 0x01, 0x10, + 0x07, 0xFA, 0x00, 0xF6, 0xA1, 0x00, 0x28, 0x46, 0x15, 0xF0, 0x04, 0xF9, + 0x19, 0x48, 0x14, 0xF0, 0xC5, 0xFC, 0x18, 0x48, 0xA0, 0xF1, 0x34, 0x09, + 0x47, 0x72, 0x00, 0x27, 0x11, 0xE0, 0x15, 0x48, 0xFF, 0xF7, 0xD6, 0xFC, + 0x00, 0x20, 0xD9, 0xF8, 0x14, 0x10, 0x07, 0xE0, 0x55, 0xF8, 0x20, 0x20, + 0x31, 0xF9, 0x10, 0x30, 0x1A, 0x44, 0x45, 0xF8, 0x20, 0x20, 0x40, 0x1C, + 0xA0, 0x42, 0xF5, 0xDB, 0x7F, 0x1C, 0xB7, 0x42, 0xEB, 0xDB, 0x00, 0x20, + 0x16, 0x4B, 0xD8, 0xF8, 0x00, 0x10, 0x09, 0xE0, 0x91, 0xF8, 0x61, 0x60, + 0x55, 0xF8, 0x20, 0x20, 0xC6, 0xF3, 0x01, 0x16, 0x32, 0x41, 0x23, 0xF8, + 0x10, 0x20, 0x40, 0x1C, 0xA0, 0x42, 0xF3, 0xDB, 0x44, 0xE5, 0x00, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0xD4, 0x56, 0x10, 0x00, 0x28, 0x0F, 0x10, 0x00, + 0xFC, 0x4A, 0x01, 0x20, 0x68, 0x04, 0x10, 0x00, 0x78, 0x07, 0x10, 0x00, + 0x7A, 0x07, 0x10, 0x00, 0x79, 0x07, 0x10, 0x00, 0x7C, 0x07, 0x10, 0x00, + 0x42, 0x44, 0x01, 0x20, 0x7D, 0x07, 0x10, 0x00, 0x50, 0x07, 0x10, 0x00, + 0x7E, 0x07, 0x10, 0x00, 0x80, 0x07, 0x10, 0x00, 0xF4, 0x4A, 0x01, 0x20, + 0x10, 0xB5, 0x01, 0x46, 0x34, 0x22, 0xFE, 0x48, 0x15, 0xF0, 0x54, 0xF8, + 0x01, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x20, 0xFE, 0xF7, 0x15, 0xBA, + 0x38, 0xB5, 0x04, 0x46, 0xF9, 0x48, 0xF8, 0x4D, 0x20, 0x60, 0x20, 0x46, + 0x14, 0xF0, 0x8B, 0xFC, 0x00, 0x22, 0x6B, 0x46, 0x01, 0x21, 0x10, 0x46, + 0xFE, 0xF7, 0x50, 0xFA, 0x01, 0x21, 0x00, 0x20, 0xFE, 0xF7, 0x2F, 0xFA, + 0x28, 0x78, 0x00, 0x28, 0x02, 0xD0, 0x10, 0xF0, 0x12, 0xFA, 0xEC, 0xE7, + 0x38, 0xBD, 0x2D, 0xE9, 0xFF, 0x41, 0x00, 0x24, 0xDD, 0xE9, 0x0A, 0x76, + 0x04, 0x21, 0x68, 0x46, 0xFF, 0xF7, 0x3D, 0xF8, 0x05, 0x46, 0x08, 0x21, + 0x02, 0xA8, 0xFF, 0xF7, 0x38, 0xF8, 0x02, 0x46, 0x00, 0x20, 0x6F, 0xF0, + 0x7E, 0x0E, 0x14, 0xE0, 0x00, 0x21, 0x00, 0xFB, 0x02, 0xF3, 0x0D, 0xE0, + 0x07, 0xEB, 0x01, 0x0C, 0x13, 0xF9, 0x0C, 0xC0, 0xB4, 0x44, 0xF4, 0x45, + 0x01, 0xDA, 0x01, 0x24, 0x03, 0xE0, 0xBC, 0xF1, 0x7F, 0x0F, 0x00, 0xDD, + 0x02, 0x24, 0x49, 0x1C, 0x91, 0x42, 0xEF, 0xDB, 0x40, 0x1C, 0xA8, 0x42, + 0xE8, 0xDB, 0x20, 0x46, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x2D, 0xE9, + 0xFF, 0x41, 0x0A, 0xA9, 0x00, 0x24, 0x91, 0xE8, 0xC0, 0x01, 0x04, 0x21, + 0x68, 0x46, 0xFF, 0xF7, 0x0E, 0xF8, 0x05, 0x46, 0x08, 0x21, 0x02, 0xA8, + 0xFF, 0xF7, 0x09, 0xF8, 0x01, 0x46, 0x00, 0x20, 0x08, 0xE0, 0x32, 0x56, + 0xD2, 0x19, 0x01, 0xD5, 0x01, 0x24, 0x02, 0xE0, 0xFF, 0x2A, 0x00, 0xDD, + 0x02, 0x24, 0x40, 0x1C, 0xA8, 0x42, 0xF4, 0xDB, 0x00, 0x20, 0x0A, 0xE0, + 0x2A, 0x18, 0xB2, 0x56, 0x12, 0xEB, 0x08, 0x02, 0x01, 0xD5, 0x01, 0x24, + 0x02, 0xE0, 0xFF, 0x2A, 0x00, 0xDD, 0x02, 0x24, 0x40, 0x1C, 0x88, 0x42, + 0xF2, 0xDB, 0x20, 0x46, 0xCE, 0xE7, 0x2D, 0xE9, 0xF0, 0x4F, 0x8D, 0xB0, + 0x14, 0xF0, 0x51, 0xFC, 0x0C, 0x90, 0x14, 0xF0, 0x50, 0xFC, 0xBD, 0x4E, + 0x04, 0x46, 0x0D, 0x46, 0x30, 0x68, 0x90, 0xF8, 0xE7, 0x00, 0x10, 0xF0, + 0x60, 0x0F, 0x03, 0xD0, 0x0C, 0x98, 0x11, 0xF0, 0x67, 0xF9, 0x0C, 0x90, + 0xDF, 0xF8, 0xD8, 0xA2, 0x01, 0x21, 0xDA, 0xF8, 0x00, 0x00, 0x90, 0xF8, + 0x31, 0x60, 0x90, 0xF8, 0x30, 0x80, 0x06, 0xFB, 0x08, 0xF0, 0x0B, 0x90, + 0x06, 0xA8, 0x0E, 0xF0, 0x42, 0xFC, 0xB0, 0x4F, 0x4F, 0xF0, 0x00, 0x0B, + 0xDF, 0xF8, 0xBC, 0x92, 0x39, 0x68, 0x06, 0x9B, 0x22, 0x46, 0x91, 0xF9, + 0x1B, 0x10, 0xCD, 0xF8, 0x0C, 0xB0, 0xCD, 0xF8, 0x00, 0x90, 0xCD, 0xE9, + 0x01, 0x31, 0x2B, 0x46, 0x0C, 0x98, 0x11, 0xF0, 0xC5, 0xF9, 0x06, 0x9B, + 0x01, 0x20, 0xCD, 0xE9, 0x00, 0x93, 0xCD, 0xE9, 0x02, 0xB0, 0x22, 0x46, + 0x2B, 0x46, 0x0C, 0x98, 0x11, 0xF0, 0xBA, 0xF9, 0x9D, 0x48, 0x34, 0x30, + 0x14, 0xF0, 0xB2, 0xFB, 0x9B, 0x49, 0x05, 0x20, 0x34, 0x31, 0x08, 0x71, + 0x08, 0x46, 0xFF, 0xF7, 0x3D, 0xFF, 0x98, 0x48, 0x02, 0x21, 0x80, 0x68, + 0x00, 0x90, 0x0A, 0xA8, 0x0E, 0xF0, 0x11, 0xFC, 0xDA, 0xF8, 0x00, 0x00, + 0xB0, 0xF9, 0xC2, 0xA1, 0xB0, 0xF9, 0xC4, 0x91, 0x0A, 0xEB, 0x09, 0x01, + 0x49, 0x10, 0x02, 0x91, 0x90, 0xF8, 0xE8, 0x00, 0x80, 0x07, 0x09, 0xD4, + 0xA8, 0xF1, 0x01, 0x00, 0x70, 0x43, 0x00, 0x99, 0x0B, 0x90, 0x43, 0x46, + 0x32, 0x46, 0x08, 0x46, 0x00, 0xF0, 0x76, 0xFB, 0xDD, 0xE9, 0x0A, 0x12, + 0x00, 0x98, 0x11, 0xF0, 0x8C, 0xFF, 0x80, 0x46, 0x02, 0x21, 0x0A, 0xA8, + 0x0E, 0xF0, 0x82, 0xFC, 0x00, 0x26, 0xD0, 0x45, 0x01, 0xDC, 0xC8, 0x45, + 0x09, 0xDA, 0x83, 0x48, 0x02, 0x99, 0x00, 0x68, 0xA8, 0xEB, 0x01, 0x01, + 0xB0, 0xF8, 0xC6, 0x01, 0x91, 0xFB, 0xF0, 0xF0, 0x46, 0xB2, 0x06, 0x98, + 0xCD, 0xE9, 0x00, 0x06, 0x22, 0x46, 0x2B, 0x46, 0x0C, 0x98, 0xFF, 0xF7, + 0x16, 0xFF, 0x01, 0x28, 0x18, 0xD0, 0x02, 0x28, 0x1C, 0xD0, 0x38, 0x68, + 0x79, 0x49, 0x2B, 0x46, 0xC6, 0x76, 0x01, 0x20, 0x06, 0x9A, 0x03, 0x90, + 0x8D, 0xE8, 0x46, 0x00, 0x22, 0x46, 0x0C, 0x98, 0x11, 0xF0, 0x5E, 0xF9, + 0x39, 0x68, 0xA5, 0x20, 0x88, 0x76, 0x01, 0x21, 0x06, 0xA8, 0x0E, 0xF0, + 0x53, 0xFC, 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x39, 0x68, 0x81, 0xF8, + 0x1B, 0xB0, 0x01, 0x21, 0xB0, 0x20, 0x04, 0xE0, 0x39, 0x68, 0xB1, 0x20, + 0x81, 0xF8, 0x1B, 0xB0, 0x01, 0x21, 0x10, 0xF0, 0xEF, 0xF8, 0xE7, 0xE7, + 0x2D, 0xE9, 0xF0, 0x4F, 0x64, 0x4F, 0x8D, 0xB0, 0x38, 0x68, 0x90, 0xF8, + 0x31, 0x60, 0x90, 0xF8, 0x30, 0x80, 0x14, 0xF0, 0x94, 0xFB, 0x0B, 0x90, + 0x14, 0xF0, 0x93, 0xFB, 0x04, 0x46, 0x38, 0x68, 0x0D, 0x46, 0x90, 0xF8, + 0xE7, 0x00, 0x10, 0xF0, 0x60, 0x0F, 0x03, 0xD0, 0x0B, 0x98, 0x11, 0xF0, + 0xAB, 0xF8, 0x0B, 0x90, 0x01, 0x21, 0x04, 0xA8, 0x0E, 0xF0, 0x91, 0xFB, + 0x57, 0x4F, 0x4F, 0xF0, 0x00, 0x0A, 0xDF, 0xF8, 0x60, 0x91, 0x38, 0x68, + 0x04, 0x9B, 0x90, 0xF9, 0x1D, 0x20, 0xCD, 0xF8, 0x0C, 0xA0, 0xCD, 0xF8, + 0x00, 0x90, 0xCD, 0xE9, 0x01, 0x32, 0x22, 0x46, 0x2B, 0x46, 0x0B, 0x98, + 0x11, 0xF0, 0x14, 0xF9, 0x04, 0x9B, 0x01, 0x21, 0xCD, 0xE9, 0x00, 0x93, + 0xCD, 0xE9, 0x02, 0xA1, 0x22, 0x46, 0x2B, 0x46, 0x0B, 0x98, 0x11, 0xF0, + 0x09, 0xF9, 0x45, 0x48, 0x34, 0x30, 0x14, 0xF0, 0x01, 0xFB, 0x43, 0x49, + 0x06, 0x20, 0x34, 0x31, 0x08, 0x71, 0x08, 0x46, 0xFF, 0xF7, 0x8C, 0xFE, + 0x3F, 0x48, 0x02, 0x21, 0x80, 0x68, 0x00, 0x90, 0x0A, 0xA8, 0x0E, 0xF0, + 0x60, 0xFB, 0x3E, 0x48, 0x06, 0xFB, 0x08, 0xFB, 0x00, 0x68, 0xB0, 0xF9, + 0xC8, 0x11, 0xB0, 0xF9, 0xCA, 0x21, 0x11, 0x44, 0x49, 0x10, 0x01, 0x91, + 0x90, 0xF8, 0xE8, 0x00, 0x80, 0x07, 0x09, 0xD4, 0xA8, 0xF1, 0x01, 0x00, + 0x00, 0x99, 0x06, 0xFB, 0x00, 0xFB, 0x43, 0x46, 0x32, 0x46, 0x08, 0x46, + 0x00, 0xF0, 0xC4, 0xFA, 0x5A, 0x46, 0x0A, 0x99, 0x00, 0x98, 0x11, 0xF0, + 0xDA, 0xFE, 0x80, 0x46, 0x02, 0x21, 0x0A, 0xA8, 0x0E, 0xF0, 0xD0, 0xFB, + 0x2C, 0x48, 0x00, 0x26, 0x00, 0x68, 0xB0, 0xF9, 0xC8, 0x21, 0x42, 0x45, + 0x03, 0xDB, 0xB0, 0xF9, 0xCA, 0x21, 0x42, 0x45, 0x07, 0xDD, 0x01, 0x9A, + 0xB0, 0xF8, 0xCC, 0x01, 0xA8, 0xEB, 0x02, 0x01, 0x91, 0xFB, 0xF0, 0xF0, + 0x46, 0xB2, 0x04, 0x98, 0xCD, 0xE9, 0x00, 0x06, 0x22, 0x46, 0x2B, 0x46, + 0x0B, 0x98, 0xFF, 0xF7, 0x60, 0xFE, 0x4F, 0xF4, 0x80, 0x71, 0x01, 0x28, + 0x17, 0xD0, 0x02, 0x28, 0x1A, 0xD0, 0x38, 0x68, 0x2B, 0x46, 0x46, 0x77, + 0x01, 0x20, 0x04, 0x9A, 0xCD, 0xF8, 0x00, 0x90, 0x03, 0x90, 0xCD, 0xE9, + 0x01, 0x26, 0x22, 0x46, 0x0B, 0x98, 0x11, 0xF0, 0xA5, 0xF8, 0x39, 0x68, + 0xA5, 0x20, 0x08, 0x77, 0x01, 0x21, 0x04, 0xA8, 0x0E, 0xF0, 0x9A, 0xFB, + 0x45, 0xE7, 0x3A, 0x68, 0xB0, 0x20, 0x82, 0xF8, 0x1D, 0xA0, 0x03, 0xE0, + 0x3A, 0x68, 0xB1, 0x20, 0x82, 0xF8, 0x1D, 0xA0, 0x10, 0xF0, 0x3A, 0xF8, + 0xEB, 0xE7, 0x2D, 0xE9, 0xF0, 0x4F, 0x87, 0xB0, 0x14, 0xF0, 0xE9, 0xFA, + 0x05, 0x90, 0x14, 0xF0, 0xE8, 0xFA, 0x04, 0x46, 0x0D, 0x46, 0x01, 0x21, + 0x04, 0xA8, 0x0E, 0xF0, 0xEC, 0xFA, 0x4F, 0xF0, 0x00, 0x0A, 0x56, 0x46, + 0x03, 0x4F, 0x0B, 0xE0, 0x38, 0x0F, 0x10, 0x00, 0xE1, 0x20, 0x00, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x50, 0x07, 0x10, 0x00, 0x78, 0x8B, 0x01, 0x20, + 0x08, 0x92, 0x01, 0x20, 0x38, 0x68, 0xDF, 0xF8, 0x2C, 0x94, 0x04, 0x9A, + 0x90, 0xF9, 0x25, 0x10, 0xCD, 0xF8, 0x0C, 0xA0, 0xCD, 0xF8, 0x00, 0x90, + 0xCD, 0xE9, 0x01, 0x21, 0x22, 0x46, 0x2B, 0x46, 0x05, 0x98, 0x11, 0xF0, + 0x61, 0xF8, 0x01, 0x21, 0x04, 0x9A, 0xCD, 0xF8, 0x00, 0x90, 0x03, 0x91, + 0xCD, 0xE9, 0x01, 0x26, 0x22, 0x46, 0x2B, 0x46, 0x05, 0x98, 0x11, 0xF0, + 0x55, 0xF8, 0xFE, 0x48, 0x14, 0xF0, 0x4E, 0xFA, 0xFC, 0x48, 0x02, 0x21, + 0x41, 0x72, 0xFF, 0xF7, 0xDB, 0xFD, 0xFA, 0x48, 0x02, 0x21, 0x34, 0x38, + 0x46, 0x69, 0x06, 0xA8, 0x0E, 0xF0, 0xAF, 0xFA, 0xDF, 0xF8, 0xDC, 0xB3, + 0x01, 0x21, 0xDB, 0xF8, 0x00, 0x00, 0x00, 0xF2, 0x61, 0x40, 0xFE, 0xF7, + 0x2A, 0xFE, 0x02, 0x46, 0x30, 0x46, 0x06, 0x99, 0x11, 0xF0, 0x39, 0xFE, + 0x80, 0x46, 0x02, 0x21, 0x06, 0xA8, 0x0E, 0xF0, 0x2F, 0xFB, 0xDB, 0xF8, + 0x00, 0x10, 0x00, 0x26, 0xB1, 0xF9, 0xDC, 0x21, 0xB1, 0xF9, 0xDE, 0x31, + 0xD0, 0x18, 0x4F, 0xEA, 0x60, 0x0C, 0x90, 0x45, 0x01, 0xDC, 0x98, 0x45, + 0x06, 0xDA, 0xB1, 0xF8, 0xE0, 0x11, 0xA8, 0xEB, 0x0C, 0x00, 0x90, 0xFB, + 0xF1, 0xF0, 0x46, 0xB2, 0x04, 0x98, 0xCD, 0xE9, 0x00, 0x06, 0x22, 0x46, + 0x2B, 0x46, 0x05, 0x98, 0xFF, 0xF7, 0xBD, 0xFD, 0x01, 0x28, 0x1A, 0xD0, + 0x02, 0x28, 0x1E, 0xD0, 0x38, 0x68, 0x2B, 0x46, 0x80, 0xF8, 0x25, 0x60, + 0x01, 0x20, 0x04, 0x9A, 0xCD, 0xF8, 0x00, 0x90, 0x03, 0x90, 0xCD, 0xE9, + 0x01, 0x26, 0x22, 0x46, 0x05, 0x98, 0x11, 0xF0, 0x03, 0xF8, 0x39, 0x68, + 0xA5, 0x20, 0x81, 0xF8, 0x24, 0x00, 0x01, 0x21, 0x04, 0xA8, 0x0E, 0xF0, + 0xF7, 0xFA, 0x07, 0xB0, 0xA2, 0xE6, 0x39, 0x68, 0x81, 0xF8, 0x25, 0xA0, + 0x02, 0x21, 0xB0, 0x20, 0x04, 0xE0, 0x39, 0x68, 0xB1, 0x20, 0x81, 0xF8, + 0x25, 0xA0, 0x02, 0x21, 0x0F, 0xF0, 0x94, 0xFF, 0xE7, 0xE7, 0x2D, 0xE9, + 0xF0, 0x4F, 0xC9, 0x48, 0x89, 0xB0, 0x00, 0x68, 0x90, 0xF8, 0x31, 0x60, + 0x90, 0xF8, 0x30, 0xB0, 0x14, 0xF0, 0x39, 0xFA, 0x07, 0x90, 0x14, 0xF0, + 0x38, 0xFA, 0x04, 0x46, 0x0D, 0x46, 0x01, 0x21, 0x06, 0xA8, 0x0E, 0xF0, + 0x40, 0xFA, 0xDF, 0xF8, 0x04, 0xA3, 0x02, 0xAB, 0x00, 0x27, 0xDA, 0xF8, + 0x00, 0x00, 0x06, 0x9A, 0x90, 0xF9, 0x20, 0x10, 0x90, 0xF9, 0x1F, 0x00, + 0x83, 0xE8, 0x83, 0x00, 0xB7, 0x48, 0x2B, 0x46, 0xA0, 0x30, 0xCD, 0xE9, + 0x00, 0x02, 0x08, 0x90, 0x22, 0x46, 0x07, 0x98, 0x11, 0xF0, 0x0C, 0xF8, + 0x06, 0x99, 0xCD, 0xE9, 0x01, 0x17, 0x01, 0x20, 0xCD, 0xE9, 0x03, 0x70, + 0x08, 0x98, 0x00, 0x90, 0x22, 0x46, 0x2B, 0x46, 0x07, 0x98, 0x10, 0xF0, + 0xFF, 0xFF, 0xAD, 0x48, 0x14, 0xF0, 0xAC, 0xF9, 0xAB, 0x48, 0x03, 0x21, + 0x81, 0x71, 0xFF, 0xF7, 0x39, 0xFD, 0xA9, 0x48, 0x02, 0x21, 0x34, 0x38, + 0xD0, 0xE9, 0x06, 0x70, 0x00, 0x90, 0xA7, 0x48, 0x00, 0x68, 0xB0, 0xF9, + 0xCE, 0x91, 0xB0, 0xF9, 0xD0, 0x81, 0x05, 0xA8, 0x0E, 0xF0, 0x05, 0xFA, + 0x09, 0xEB, 0x08, 0x00, 0x40, 0x10, 0x01, 0x90, 0xA0, 0x48, 0x00, 0x68, + 0x90, 0xF8, 0x34, 0x01, 0x80, 0x07, 0x05, 0xD4, 0x39, 0x46, 0x32, 0x46, + 0x08, 0x46, 0x00, 0xF0, 0x87, 0xF9, 0x76, 0x1E, 0x32, 0x46, 0x38, 0x46, + 0x05, 0x99, 0x11, 0xF0, 0x88, 0xFD, 0x00, 0x27, 0x48, 0x45, 0x01, 0xDC, + 0x40, 0x45, 0x08, 0xDA, 0x01, 0x99, 0x09, 0x1A, 0x94, 0x48, 0x00, 0x68, + 0xB0, 0xF8, 0xD2, 0x01, 0x91, 0xFB, 0xF0, 0xF0, 0x47, 0xB2, 0x91, 0x48, + 0x00, 0x68, 0x90, 0xF8, 0x34, 0x01, 0x80, 0x07, 0x06, 0xD4, 0x00, 0x99, + 0x5A, 0x46, 0x08, 0x46, 0x00, 0xF0, 0x68, 0xF9, 0xAB, 0xF1, 0x01, 0x0B, + 0x5A, 0x46, 0x05, 0x99, 0x00, 0x98, 0x11, 0xF0, 0x68, 0xFD, 0x00, 0x26, + 0x48, 0x45, 0x01, 0xDC, 0x40, 0x45, 0x08, 0xDA, 0x01, 0x99, 0x09, 0x1A, + 0x84, 0x48, 0x00, 0x68, 0xB0, 0xF8, 0xD4, 0x01, 0x91, 0xFB, 0xF0, 0xF0, + 0x46, 0xB2, 0x02, 0x21, 0x05, 0xA8, 0x0E, 0xF0, 0x51, 0xFA, 0x06, 0x98, + 0xCD, 0xE9, 0x00, 0x07, 0x02, 0x96, 0x22, 0x46, 0x2B, 0x46, 0x07, 0x98, + 0xFF, 0xF7, 0x21, 0xFD, 0x01, 0x28, 0x1D, 0xD0, 0x02, 0x28, 0x24, 0xD0, + 0xDA, 0xF8, 0x00, 0x00, 0x22, 0x46, 0x2B, 0x46, 0xC7, 0x77, 0x80, 0xF8, + 0x20, 0x60, 0x01, 0x20, 0x06, 0x99, 0xCD, 0xE9, 0x03, 0x60, 0xCD, 0xE9, + 0x01, 0x17, 0x08, 0x98, 0x00, 0x90, 0x07, 0x98, 0x10, 0xF0, 0x82, 0xFF, + 0xDA, 0xF8, 0x00, 0x00, 0xA5, 0x21, 0x81, 0x77, 0x01, 0x21, 0x06, 0xA8, + 0x0E, 0xF0, 0x2A, 0xFA, 0x09, 0xB0, 0xD5, 0xE5, 0xDA, 0xF8, 0x00, 0x10, + 0x00, 0x20, 0xC8, 0x77, 0x81, 0xF8, 0x20, 0x00, 0x10, 0x21, 0xB2, 0x20, + 0x07, 0xE0, 0xDA, 0xF8, 0x00, 0x10, 0x00, 0x20, 0xC8, 0x77, 0x81, 0xF8, + 0x20, 0x00, 0x10, 0x21, 0xB3, 0x20, 0x0F, 0xF0, 0xC1, 0xFE, 0xE1, 0xE7, + 0x2D, 0xE9, 0xF0, 0x4F, 0x87, 0xB0, 0x14, 0xF0, 0x6C, 0xF9, 0x83, 0x46, + 0x14, 0xF0, 0x6B, 0xF9, 0xDF, 0xF8, 0x70, 0x91, 0x01, 0x21, 0xC8, 0x46, + 0xD9, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0x31, 0x60, 0x05, 0xA8, 0x0E, 0xF0, + 0x6E, 0xF9, 0x58, 0x4D, 0x58, 0x4F, 0x05, 0x9A, 0x28, 0x68, 0x00, 0x24, + 0x23, 0x46, 0x90, 0xF9, 0x23, 0x10, 0x90, 0xF9, 0x22, 0x00, 0x00, 0x97, + 0xCD, 0xE9, 0x01, 0x20, 0xCD, 0xE9, 0x03, 0x14, 0x22, 0x46, 0x58, 0x46, + 0x10, 0xF0, 0x3E, 0xFF, 0x05, 0x99, 0xCD, 0xE9, 0x01, 0x14, 0x4F, 0xF0, + 0x01, 0x0A, 0x00, 0x97, 0xCD, 0xE9, 0x03, 0x4A, 0x00, 0x22, 0x13, 0x46, + 0x58, 0x46, 0x10, 0xF0, 0x31, 0xFF, 0x46, 0x48, 0x14, 0xF0, 0xDE, 0xF8, + 0x44, 0x49, 0x03, 0x20, 0x08, 0x72, 0x08, 0x46, 0xFF, 0xF7, 0x6A, 0xFC, + 0x41, 0x48, 0x02, 0x21, 0x34, 0x38, 0x87, 0x6A, 0x06, 0xA8, 0x0E, 0xF0, + 0x3E, 0xF9, 0xD8, 0xF8, 0x00, 0x00, 0xB0, 0xF9, 0xD6, 0x11, 0xB0, 0xF9, + 0xD8, 0x21, 0x90, 0xF8, 0x84, 0x09, 0x11, 0x44, 0x01, 0xEB, 0xD1, 0x71, + 0x4F, 0xEA, 0x61, 0x08, 0x80, 0x07, 0x05, 0xD4, 0x76, 0x1E, 0x39, 0x46, + 0x32, 0x46, 0x08, 0x46, 0x00, 0xF0, 0xBA, 0xF8, 0x32, 0x46, 0x38, 0x46, + 0x06, 0x99, 0x11, 0xF0, 0xBC, 0xFC, 0xD9, 0xF8, 0x00, 0x10, 0x00, 0x26, + 0x37, 0x46, 0xB1, 0xF9, 0xD6, 0x21, 0x82, 0x42, 0x03, 0xDB, 0xB1, 0xF9, + 0xD8, 0x21, 0x82, 0x42, 0x06, 0xDD, 0xB1, 0xF8, 0xDA, 0x11, 0xA8, 0xEB, + 0x00, 0x00, 0x90, 0xFB, 0xF1, 0xF0, 0x46, 0xB2, 0x02, 0x21, 0x06, 0xA8, + 0x0E, 0xF0, 0xA0, 0xF9, 0x05, 0x98, 0x00, 0x22, 0x8D, 0xE8, 0xC1, 0x00, + 0x13, 0x46, 0x58, 0x46, 0xFF, 0xF7, 0x71, 0xFC, 0x01, 0x28, 0x1A, 0xD0, + 0x02, 0x28, 0x28, 0x68, 0x1E, 0xD0, 0x00, 0xF8, 0x22, 0x6F, 0x00, 0x22, + 0x44, 0x70, 0x20, 0x48, 0x05, 0x99, 0x98, 0x38, 0x8D, 0xE8, 0x43, 0x00, + 0xCD, 0xE9, 0x03, 0x4A, 0x13, 0x46, 0x58, 0x46, 0x10, 0xF0, 0xD4, 0xFE, + 0x29, 0x68, 0xA5, 0x20, 0x81, 0xF8, 0x21, 0x00, 0x01, 0x21, 0x05, 0xA8, + 0x0E, 0xF0, 0x7C, 0xF9, 0x83, 0xE6, 0x28, 0x68, 0x40, 0x21, 0x00, 0xF8, + 0x22, 0x4F, 0x44, 0x70, 0xB2, 0x20, 0x04, 0xE0, 0x00, 0xF8, 0x22, 0x4F, + 0x40, 0x21, 0x44, 0x70, 0xB3, 0x20, 0x0F, 0xF0, 0x19, 0xFE, 0xE7, 0xE7, + 0x70, 0xB5, 0x04, 0x46, 0x00, 0x20, 0xFD, 0xF7, 0xEE, 0xFE, 0x02, 0x20, + 0xFD, 0xF7, 0xEB, 0xFE, 0x0B, 0x49, 0x01, 0x20, 0x08, 0x70, 0x07, 0x4D, + 0x28, 0x68, 0x90, 0xF8, 0xC0, 0x01, 0x20, 0x40, 0xC0, 0x07, 0x01, 0xD0, + 0xFF, 0xF7, 0x5F, 0xFC, 0x28, 0x68, 0x0B, 0xE0, 0x98, 0x98, 0x01, 0x20, + 0x6C, 0x0F, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x50, 0x07, 0x10, 0x00, + 0xD0, 0x99, 0x01, 0x20, 0x78, 0x07, 0x10, 0x00, 0x90, 0xF8, 0xC0, 0x01, + 0x80, 0x07, 0x03, 0xD5, 0xA0, 0x07, 0x01, 0xD5, 0xFF, 0xF7, 0x00, 0xFD, + 0x28, 0x68, 0x90, 0xF8, 0xC0, 0x11, 0xC9, 0x06, 0x06, 0xD5, 0x90, 0xF8, + 0x61, 0x04, 0x18, 0xB1, 0xE0, 0x06, 0x01, 0xD5, 0xFF, 0xF7, 0xA9, 0xFD, + 0x28, 0x68, 0x90, 0xF8, 0xC0, 0x01, 0x40, 0x07, 0x03, 0xD5, 0x60, 0x07, + 0x01, 0xD5, 0xFF, 0xF7, 0x46, 0xFE, 0x28, 0x68, 0x90, 0xF8, 0xC0, 0x01, + 0x00, 0x07, 0x03, 0xD5, 0x20, 0x07, 0x01, 0xD5, 0xFF, 0xF7, 0x10, 0xFF, + 0x00, 0x20, 0xFD, 0xF7, 0xC3, 0xFE, 0x02, 0x20, 0xFD, 0xF7, 0xC0, 0xFE, + 0xE0, 0x07, 0x04, 0xD0, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0x20, 0x01, 0xF0, + 0x75, 0xBA, 0x70, 0xBD, 0xF0, 0xB5, 0x00, 0x26, 0x35, 0x46, 0x0C, 0xE0, + 0x01, 0x24, 0x07, 0xE0, 0x05, 0xFB, 0x03, 0x47, 0x64, 0x1C, 0x31, 0xF8, + 0x17, 0x70, 0x20, 0xF8, 0x16, 0x70, 0x76, 0x1C, 0x9C, 0x42, 0xF5, 0xDB, + 0x6D, 0x1C, 0x95, 0x42, 0xF0, 0xDB, 0xF0, 0xBD, 0x30, 0xB5, 0x00, 0x24, + 0x01, 0x23, 0x05, 0xE0, 0x31, 0xF8, 0x13, 0x50, 0x20, 0xF8, 0x14, 0x50, + 0x5B, 0x1C, 0x64, 0x1C, 0x93, 0x42, 0xF7, 0xDB, 0x30, 0xBD, 0x00, 0x00, + 0x70, 0xB5, 0x7E, 0x4D, 0x4F, 0xF4, 0x25, 0x74, 0x21, 0x46, 0x28, 0x68, + 0xFE, 0xF7, 0x17, 0xFC, 0x00, 0x21, 0x1F, 0x20, 0x0D, 0xF1, 0xFE, 0xF8, + 0x22, 0x46, 0x29, 0x68, 0xBD, 0xE8, 0x70, 0x40, 0x1F, 0x23, 0x77, 0x48, + 0xFE, 0xF7, 0xCA, 0xBA, 0x70, 0xB5, 0x76, 0x4D, 0x40, 0xF2, 0xAF, 0x14, + 0x21, 0x46, 0x28, 0x68, 0xFE, 0xF7, 0x03, 0xFC, 0x00, 0x21, 0x1A, 0x20, + 0x0D, 0xF1, 0xEA, 0xF8, 0x22, 0x46, 0x29, 0x68, 0xBD, 0xE8, 0x70, 0x40, + 0x1A, 0x23, 0x6F, 0x48, 0xFE, 0xF7, 0xB6, 0xBA, 0x2D, 0xE9, 0xF0, 0x41, + 0xDF, 0xF8, 0xB4, 0x81, 0x05, 0x1D, 0x0E, 0x46, 0x29, 0x46, 0x40, 0x46, + 0xFE, 0xF7, 0xED, 0xFB, 0x30, 0x68, 0x6A, 0x4A, 0x00, 0xEB, 0x85, 0x03, + 0x93, 0x42, 0x01, 0xD2, 0x1B, 0x23, 0x13, 0xE0, 0x67, 0x49, 0x8B, 0x42, + 0x13, 0xD2, 0x90, 0x42, 0x0D, 0xD2, 0x44, 0x46, 0x11, 0x1A, 0x8F, 0x08, + 0x90, 0x46, 0x1B, 0x23, 0x3A, 0x46, 0x21, 0x46, 0xFE, 0xF7, 0x96, 0xFA, + 0xEA, 0x1B, 0x04, 0xEB, 0x87, 0x01, 0x1C, 0x23, 0x15, 0xE0, 0x1C, 0x23, + 0x2A, 0x46, 0x41, 0x46, 0x12, 0xE0, 0x5D, 0x4A, 0x93, 0x42, 0x19, 0xD2, + 0x88, 0x42, 0x15, 0xD2, 0x44, 0x46, 0x88, 0x46, 0x09, 0x1A, 0x8F, 0x08, + 0x1C, 0x23, 0x3A, 0x46, 0x21, 0x46, 0xFE, 0xF7, 0x7F, 0xFA, 0xEA, 0x1B, + 0x04, 0xEB, 0x87, 0x01, 0x1D, 0x23, 0x40, 0x46, 0xFE, 0xF7, 0x78, 0xFA, + 0x30, 0x68, 0x00, 0xEB, 0x85, 0x00, 0x30, 0x60, 0xBD, 0xE8, 0xF0, 0x81, + 0x1D, 0x23, 0xDF, 0xE7, 0x90, 0x42, 0x0D, 0xD2, 0x47, 0x46, 0x11, 0x1A, + 0x8C, 0x08, 0x90, 0x46, 0x1D, 0x23, 0x22, 0x46, 0x39, 0x46, 0xFE, 0xF7, + 0x65, 0xFA, 0x2A, 0x1B, 0x07, 0xEB, 0x84, 0x01, 0x1E, 0x23, 0xE4, 0xE7, + 0x1E, 0x23, 0xCD, 0xE7, 0xF8, 0xB5, 0x42, 0x4C, 0x45, 0x48, 0x00, 0x90, + 0x10, 0x34, 0x02, 0x20, 0xFD, 0xF7, 0xF3, 0xFD, 0x00, 0x21, 0x1B, 0x20, + 0x0D, 0xF1, 0x7E, 0xF8, 0x00, 0x21, 0x1C, 0x20, 0x0D, 0xF1, 0x7A, 0xF8, + 0x00, 0x21, 0x1D, 0x20, 0x0D, 0xF1, 0x76, 0xF8, 0x00, 0x21, 0x1E, 0x20, + 0x0D, 0xF1, 0x72, 0xF8, 0x10, 0x21, 0x20, 0x46, 0x14, 0xF0, 0x72, 0xFB, + 0x00, 0x20, 0x20, 0x80, 0xA0, 0x70, 0x2F, 0x4D, 0x01, 0x20, 0xE0, 0x70, + 0x28, 0x68, 0xC1, 0x8A, 0xA1, 0x80, 0x80, 0x8A, 0xE0, 0x80, 0x04, 0x20, + 0x69, 0x46, 0xFF, 0xF7, 0x7D, 0xFF, 0x01, 0x23, 0x00, 0x22, 0x21, 0x46, + 0x10, 0x20, 0x11, 0xF0, 0x37, 0xF8, 0x06, 0x46, 0x69, 0x46, 0xFF, 0xF7, + 0x73, 0xFF, 0x01, 0x23, 0x00, 0x22, 0x21, 0x46, 0x11, 0x20, 0x11, 0xF0, + 0x2D, 0xF8, 0x69, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0x69, 0xFF, 0x28, 0x68, + 0x90, 0xF8, 0x61, 0x04, 0x48, 0xB1, 0x01, 0x23, 0x00, 0x22, 0x21, 0x46, + 0x14, 0x20, 0x11, 0xF0, 0x1F, 0xF8, 0x69, 0x46, 0x30, 0x46, 0xFF, 0xF7, + 0x5B, 0xFF, 0x28, 0x68, 0x90, 0xF8, 0x50, 0x12, 0xC9, 0x07, 0x03, 0xD1, + 0x90, 0xF8, 0x80, 0x02, 0xC0, 0x07, 0x09, 0xD0, 0x01, 0x23, 0x00, 0x22, + 0x21, 0x46, 0x12, 0x20, 0x11, 0xF0, 0x0C, 0xF8, 0x69, 0x46, 0x30, 0x46, + 0xFF, 0xF7, 0x48, 0xFF, 0x01, 0x23, 0x00, 0x22, 0x21, 0x46, 0x13, 0x20, + 0x11, 0xF0, 0x02, 0xF8, 0x69, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0x3E, 0xFF, + 0x28, 0x68, 0x90, 0xF8, 0x2F, 0x0A, 0xC0, 0x07, 0x09, 0xD0, 0x01, 0x23, + 0x00, 0x22, 0x21, 0x46, 0x17, 0x20, 0x10, 0xF0, 0xF3, 0xFF, 0x69, 0x46, + 0x30, 0x46, 0xFF, 0xF7, 0x2F, 0xFF, 0x02, 0x20, 0xFD, 0xF7, 0x9A, 0xFD, + 0xF8, 0xBD, 0x00, 0x00, 0x4C, 0x07, 0x10, 0x00, 0xF0, 0xEF, 0x01, 0x00, + 0x50, 0x07, 0x10, 0x00, 0xF0, 0x9F, 0x01, 0x00, 0xD4, 0x56, 0x10, 0x00, + 0xF0, 0xBF, 0x01, 0x00, 0xF0, 0xCF, 0x01, 0x00, 0xF0, 0xDF, 0x01, 0x00, + 0xF0, 0xAF, 0x01, 0x00, 0x10, 0xB5, 0x01, 0x46, 0x34, 0x22, 0xFE, 0x48, + 0x14, 0xF0, 0xBE, 0xFA, 0x01, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x20, + 0xFD, 0xF7, 0x7F, 0xBC, 0x70, 0xB5, 0x86, 0xB0, 0x06, 0x46, 0x68, 0x46, + 0x13, 0xF0, 0xD2, 0xFE, 0xF7, 0x48, 0x00, 0x90, 0x02, 0x2E, 0x15, 0xD0, + 0x07, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0xF3, 0x4C, 0x68, 0x46, 0x13, 0xF0, + 0xEC, 0xFE, 0x00, 0x22, 0x04, 0xAB, 0x01, 0x21, 0x10, 0x46, 0xFD, 0xF7, + 0xB1, 0xFC, 0x01, 0x21, 0x00, 0x20, 0xFD, 0xF7, 0x90, 0xFC, 0x20, 0x78, + 0x30, 0xB1, 0x0F, 0xF0, 0x74, 0xFC, 0xED, 0xE7, 0x03, 0x20, 0x8D, 0xF8, + 0x09, 0x00, 0xE8, 0xE7, 0xE9, 0x4D, 0x02, 0x2E, 0x09, 0xD0, 0x13, 0xF0, + 0x0C, 0xFF, 0xA8, 0x61, 0x13, 0xF0, 0x0B, 0xFF, 0xC5, 0xE9, 0x10, 0x01, + 0xA0, 0x68, 0x06, 0xB0, 0x70, 0xBD, 0x13, 0xF0, 0x06, 0xFF, 0xA8, 0x61, + 0x13, 0xF0, 0x05, 0xFF, 0xC5, 0xE9, 0x10, 0x01, 0x60, 0x69, 0xF4, 0xE7, + 0x2D, 0xE9, 0xF0, 0x41, 0xDD, 0x4C, 0x01, 0x25, 0x60, 0x38, 0xD4, 0xE9, + 0x10, 0x23, 0xA6, 0x69, 0x09, 0x28, 0x6F, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, + 0x05, 0x0F, 0x1E, 0x28, 0x37, 0x41, 0x50, 0x5A, 0x6A, 0x00, 0x32, 0x46, + 0x00, 0x23, 0x08, 0x46, 0x00, 0xF0, 0x51, 0xFA, 0x85, 0x40, 0x60, 0x68, + 0x05, 0x43, 0x65, 0x60, 0x5E, 0xE0, 0x08, 0x46, 0x00, 0xF0, 0x49, 0xFA, + 0x02, 0x46, 0x01, 0x20, 0x00, 0x21, 0x14, 0xF0, 0xDF, 0xF9, 0xD4, 0xE9, + 0x08, 0x23, 0x10, 0x43, 0x19, 0x43, 0xC4, 0xE9, 0x08, 0x01, 0x4F, 0xE0, + 0x32, 0x46, 0x00, 0x23, 0x08, 0x46, 0x00, 0xF0, 0x38, 0xFA, 0x85, 0x40, + 0xE0, 0x68, 0x05, 0x43, 0xE5, 0x60, 0x45, 0xE0, 0x08, 0x46, 0x00, 0xF0, + 0x30, 0xFA, 0x02, 0x46, 0x01, 0x20, 0x00, 0x21, 0x14, 0xF0, 0xC6, 0xF9, + 0xD4, 0xE9, 0x0C, 0x23, 0x10, 0x43, 0x19, 0x43, 0xC4, 0xE9, 0x0C, 0x01, + 0x36, 0xE0, 0x32, 0x46, 0x00, 0x23, 0x08, 0x46, 0x00, 0xF0, 0x1F, 0xFA, + 0x85, 0x40, 0xA0, 0x68, 0x05, 0x43, 0xA5, 0x60, 0x2C, 0xE0, 0x08, 0x46, + 0x00, 0xF0, 0x17, 0xFA, 0x02, 0x46, 0x01, 0x20, 0x00, 0x21, 0x14, 0xF0, + 0xAD, 0xF9, 0xD4, 0xE9, 0x0A, 0x23, 0x10, 0x43, 0x19, 0x43, 0xC4, 0xE9, + 0x0A, 0x01, 0x1D, 0xE0, 0x32, 0x46, 0x00, 0x23, 0x08, 0x46, 0x00, 0xF0, + 0x06, 0xFA, 0x85, 0x40, 0x20, 0x69, 0x05, 0x43, 0x25, 0x61, 0x13, 0xE0, + 0x08, 0x46, 0x00, 0xF0, 0xFE, 0xF9, 0x01, 0x23, 0x02, 0x46, 0x00, 0x21, + 0x18, 0x46, 0x14, 0xF0, 0x93, 0xF9, 0xD4, 0xE9, 0x0E, 0x23, 0x10, 0x43, + 0x19, 0x43, 0xC4, 0xE9, 0x0E, 0x01, 0x03, 0xE0, 0x60, 0x69, 0x8D, 0x40, + 0x05, 0x43, 0x65, 0x61, 0x20, 0x68, 0x40, 0x1C, 0x20, 0x60, 0xBD, 0xE8, + 0xF0, 0x81, 0x2D, 0xE9, 0xF0, 0x41, 0x17, 0x46, 0x04, 0x46, 0x0D, 0x46, + 0x00, 0x26, 0x09, 0xE0, 0xE0, 0x07, 0x03, 0xD0, 0x31, 0x46, 0x38, 0x46, + 0x0F, 0xF0, 0xBE, 0xFB, 0x76, 0x1C, 0x6D, 0x08, 0x4F, 0xEA, 0x34, 0x04, + 0x54, 0xEA, 0x05, 0x00, 0xF2, 0xD1, 0xE8, 0xE7, 0x70, 0xB5, 0x94, 0x4C, + 0xE1, 0x68, 0x60, 0x68, 0xD4, 0xE9, 0x0C, 0x65, 0x40, 0xEA, 0x01, 0x03, + 0xD4, 0xE9, 0x08, 0x21, 0x29, 0x43, 0x25, 0x69, 0x32, 0x43, 0x9D, 0x43, + 0x25, 0x61, 0xD4, 0xE9, 0x0E, 0x35, 0x93, 0x43, 0x8D, 0x43, 0xC4, 0xE9, + 0x0E, 0x35, 0x21, 0x68, 0x00, 0x29, 0x2C, 0xD0, 0x60, 0x22, 0x00, 0x21, + 0xFF, 0xF7, 0xCF, 0xFF, 0xD4, 0xE9, 0x08, 0x01, 0x61, 0x22, 0xFF, 0xF7, + 0xCA, 0xFF, 0x62, 0x22, 0x00, 0x21, 0xE0, 0x68, 0xFF, 0xF7, 0xC5, 0xFF, + 0xD4, 0xE9, 0x0C, 0x01, 0x63, 0x22, 0xFF, 0xF7, 0xC0, 0xFF, 0x64, 0x22, + 0x00, 0x21, 0xA0, 0x68, 0xFF, 0xF7, 0xBB, 0xFF, 0xD4, 0xE9, 0x0A, 0x01, + 0x65, 0x22, 0xFF, 0xF7, 0xB6, 0xFF, 0x66, 0x22, 0x00, 0x21, 0x20, 0x69, + 0xFF, 0xF7, 0xB1, 0xFF, 0xD4, 0xE9, 0x0E, 0x01, 0x67, 0x22, 0xFF, 0xF7, + 0xAC, 0xFF, 0x60, 0x69, 0xBD, 0xE8, 0x70, 0x40, 0x68, 0x22, 0x00, 0x21, + 0xA5, 0xE7, 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x5F, 0x83, 0x46, 0x4F, 0xF0, + 0x00, 0x0A, 0x13, 0xF0, 0x1A, 0xFE, 0x04, 0x46, 0x13, 0xF0, 0x1B, 0xFE, + 0x40, 0xEA, 0x04, 0x06, 0x13, 0xF0, 0x15, 0xFE, 0x07, 0x46, 0x88, 0x46, + 0x13, 0xF0, 0x15, 0xFE, 0x41, 0xEA, 0x08, 0x05, 0x67, 0x49, 0x40, 0xEA, + 0x07, 0x04, 0x8E, 0x61, 0xC1, 0xE9, 0x10, 0x45, 0xFD, 0xF7, 0x0E, 0xFD, + 0x00, 0xF0, 0xFF, 0x08, 0xFD, 0xF7, 0x0C, 0xFD, 0x00, 0xF0, 0xFF, 0x09, + 0xFD, 0xF7, 0x19, 0xFE, 0x00, 0x27, 0x26, 0xE0, 0x01, 0x20, 0xB8, 0x40, + 0x30, 0x42, 0x21, 0xD0, 0xF8, 0xB2, 0x00, 0x21, 0xFD, 0xF7, 0x17, 0xFE, + 0x41, 0x07, 0x05, 0xD5, 0x5F, 0xEA, 0xCB, 0x61, 0x02, 0xD5, 0x51, 0x46, + 0x62, 0x20, 0x0F, 0xE0, 0xC1, 0x07, 0x05, 0xD0, 0x5F, 0xEA, 0x4B, 0x71, + 0x02, 0xD5, 0x51, 0x46, 0x60, 0x20, 0x07, 0xE0, 0x1B, 0xF0, 0xC0, 0x0F, + 0x06, 0xD0, 0x10, 0xF0, 0x0A, 0x0F, 0x03, 0xD0, 0x51, 0x46, 0x64, 0x20, + 0xFF, 0xF7, 0xDE, 0xFE, 0x0A, 0xF1, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x0A, + 0x7F, 0x1C, 0x47, 0x45, 0xD6, 0xDB, 0xFD, 0xF7, 0xEC, 0xFD, 0x00, 0x27, + 0x3E, 0x46, 0x29, 0xE0, 0x32, 0x46, 0x01, 0x20, 0x00, 0x21, 0x14, 0xF0, + 0xCF, 0xF8, 0x20, 0x40, 0x29, 0x40, 0x08, 0x43, 0x1F, 0xD0, 0xF0, 0xB2, + 0x01, 0x21, 0xFD, 0xF7, 0xE4, 0xFD, 0x41, 0x07, 0x05, 0xD5, 0x5F, 0xEA, + 0x8B, 0x61, 0x02, 0xD5, 0x39, 0x46, 0x63, 0x20, 0x0F, 0xE0, 0xC1, 0x07, + 0x05, 0xD0, 0x5F, 0xEA, 0x0B, 0x71, 0x02, 0xD5, 0x39, 0x46, 0x61, 0x20, + 0x07, 0xE0, 0x1B, 0xF4, 0xC0, 0x7F, 0x06, 0xD0, 0x10, 0xF0, 0x0A, 0x0F, + 0x03, 0xD0, 0x39, 0x46, 0x65, 0x20, 0xFF, 0xF7, 0xAB, 0xFE, 0x7F, 0x1C, + 0xFF, 0xB2, 0x76, 0x1C, 0x4E, 0x45, 0xD3, 0xDD, 0xBD, 0xE8, 0xF0, 0x5F, + 0xFD, 0xF7, 0xB9, 0xBD, 0x30, 0x48, 0x02, 0x68, 0x12, 0xF8, 0xD3, 0x1F, + 0xD0, 0x78, 0x00, 0xF0, 0x1F, 0x00, 0x40, 0x1C, 0x41, 0x43, 0x48, 0x00, + 0xC0, 0xEB, 0x40, 0x20, 0x40, 0x10, 0x70, 0x47, 0x2D, 0xE9, 0xFC, 0x5F, + 0x07, 0x46, 0x00, 0x20, 0xCD, 0xE9, 0x00, 0x00, 0x1C, 0x46, 0x92, 0x46, + 0x0E, 0x46, 0xFF, 0xF7, 0xE7, 0xFF, 0x00, 0xEB, 0x04, 0x08, 0x0C, 0x98, + 0x80, 0x07, 0x50, 0xD5, 0x00, 0x24, 0x4C, 0xE0, 0x4F, 0xF0, 0x00, 0x09, + 0x4F, 0xF0, 0xFF, 0x3B, 0x4D, 0x46, 0x27, 0xE0, 0x05, 0xFB, 0x06, 0x40, + 0x3A, 0xF9, 0x10, 0x20, 0x42, 0x45, 0x20, 0xD2, 0x09, 0xF1, 0x01, 0x09, + 0xBB, 0xF1, 0xFF, 0x3F, 0x00, 0xD1, 0xAB, 0x46, 0x79, 0x1E, 0x8D, 0x42, + 0x17, 0xD1, 0xB9, 0xF1, 0x01, 0x0F, 0x14, 0xD1, 0x71, 0x1E, 0x8C, 0x42, + 0x04, 0xD1, 0x29, 0x46, 0x66, 0x20, 0xFF, 0xF7, 0x63, 0xFE, 0x0C, 0xE0, + 0x0A, 0xEB, 0x40, 0x00, 0xB0, 0xF9, 0x02, 0x20, 0x42, 0x45, 0x04, 0xD3, + 0x2C, 0xB1, 0x30, 0xF9, 0x02, 0x1C, 0x41, 0x45, 0x01, 0xD2, 0x4F, 0xF0, + 0x00, 0x09, 0x6D, 0x1C, 0xBD, 0x42, 0xD5, 0xD3, 0xA7, 0xEB, 0x0B, 0x01, + 0x49, 0x45, 0x17, 0xD8, 0x21, 0x46, 0x67, 0x20, 0xFF, 0xF7, 0x4A, 0xFE, + 0x01, 0x20, 0x22, 0x46, 0x00, 0x21, 0x07, 0xE0, 0x7C, 0x0F, 0x10, 0x00, + 0x0D, 0x2C, 0x00, 0x00, 0x70, 0x04, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x14, 0xF0, 0x3E, 0xF8, 0xDD, 0xE9, 0x00, 0x23, 0x10, 0x43, 0x19, 0x43, + 0xCD, 0xE9, 0x00, 0x01, 0x64, 0x1C, 0xB4, 0x42, 0xB0, 0xD3, 0x0C, 0x98, + 0xC0, 0x07, 0x25, 0xD0, 0x00, 0x25, 0x21, 0xE0, 0x4F, 0xF0, 0x00, 0x09, + 0x4C, 0x46, 0x13, 0xE0, 0x05, 0xFB, 0x06, 0x41, 0x3A, 0xF9, 0x11, 0x10, + 0x41, 0x45, 0x0C, 0xD2, 0x22, 0x46, 0x01, 0x20, 0x00, 0x21, 0x14, 0xF0, + 0x21, 0xF8, 0xDD, 0xE9, 0x00, 0x23, 0x10, 0x40, 0x19, 0x40, 0x08, 0x43, + 0x01, 0xD1, 0x09, 0xF1, 0x01, 0x09, 0x64, 0x1C, 0xB4, 0x42, 0xE9, 0xD3, + 0xB9, 0xF1, 0x00, 0x0F, 0x03, 0xD0, 0x29, 0x46, 0x66, 0x20, 0xFF, 0xF7, + 0x0D, 0xFE, 0x6D, 0x1C, 0xBD, 0x42, 0xDB, 0xD3, 0xBD, 0xE8, 0xFC, 0x9F, + 0x2D, 0xE9, 0xFF, 0x47, 0x04, 0x46, 0x00, 0x20, 0xFD, 0xF7, 0x27, 0xFB, + 0x4C, 0x49, 0x4F, 0xF0, 0x01, 0x09, 0x81, 0xF8, 0x00, 0x90, 0x00, 0xF0, + 0x7D, 0xF8, 0x14, 0xF0, 0x0C, 0x0F, 0x09, 0xD1, 0xE0, 0x06, 0x07, 0xD4, + 0xA0, 0x06, 0x05, 0xD4, 0x60, 0x06, 0x03, 0xD4, 0xE0, 0x05, 0x01, 0xD4, + 0x20, 0x06, 0x02, 0xD5, 0x20, 0x46, 0xFF, 0xF7, 0xC5, 0xFE, 0x42, 0x4E, + 0xA0, 0x07, 0x1C, 0xD0, 0x01, 0x20, 0xFF, 0xF7, 0xAB, 0xFD, 0x05, 0x46, + 0x13, 0xF0, 0xDD, 0xFC, 0x01, 0x90, 0x13, 0xF0, 0xDC, 0xFC, 0xCD, 0xE9, + 0x02, 0x01, 0x04, 0x21, 0x01, 0xA8, 0xFE, 0xF7, 0x68, 0xF8, 0x07, 0x46, + 0x08, 0x21, 0x02, 0xA8, 0xFE, 0xF7, 0x63, 0xF8, 0x01, 0x46, 0x00, 0x94, + 0x30, 0x68, 0x2A, 0x46, 0x90, 0xF8, 0xDA, 0x30, 0x38, 0x46, 0xFF, 0xF7, + 0x37, 0xFF, 0x14, 0xF4, 0xC0, 0x6F, 0x26, 0xD0, 0x30, 0x68, 0x90, 0xF8, + 0x61, 0x04, 0x10, 0xB3, 0x00, 0x25, 0xFF, 0xF7, 0x1F, 0xFF, 0x31, 0x68, + 0xB0, 0x46, 0x91, 0xF8, 0xDB, 0x10, 0x0F, 0x18, 0x02, 0x20, 0xFF, 0xF7, + 0x7F, 0xFD, 0x06, 0x46, 0x5F, 0xF0, 0x00, 0x04, 0xD8, 0xF8, 0x00, 0x00, + 0x90, 0xF8, 0x61, 0x14, 0x09, 0xFA, 0x04, 0xF0, 0x01, 0x42, 0x09, 0xD0, + 0x6D, 0x1C, 0x36, 0xF9, 0x14, 0x00, 0xED, 0xB2, 0xB8, 0x42, 0x03, 0xD2, + 0x29, 0x46, 0x68, 0x20, 0xFF, 0xF7, 0xA4, 0xFD, 0x64, 0x1C, 0x04, 0x2C, + 0xEA, 0xDB, 0xFF, 0xF7, 0x33, 0xFE, 0x04, 0xB0, 0x00, 0x20, 0xBD, 0xE8, + 0xF0, 0x47, 0xFD, 0xF7, 0xD9, 0xBA, 0x2D, 0xE9, 0xF0, 0x41, 0x16, 0x46, + 0x1F, 0x46, 0x80, 0x46, 0x4F, 0xF0, 0xFF, 0x35, 0x00, 0x24, 0x22, 0x46, + 0x01, 0x20, 0x00, 0x21, 0x13, 0xF0, 0x8E, 0xFF, 0x30, 0x40, 0x39, 0x40, + 0x08, 0x43, 0x04, 0xD0, 0x6D, 0x1C, 0x45, 0x45, 0x01, 0xD1, 0x20, 0x46, + 0xFF, 0xE5, 0x64, 0x1C, 0x40, 0x2C, 0xEE, 0xD3, 0x00, 0x20, 0xFA, 0xE5, + 0x0C, 0x48, 0x00, 0x21, 0x01, 0x61, 0x41, 0x60, 0x81, 0x60, 0xC1, 0x60, + 0xC0, 0xE9, 0x0E, 0x11, 0xC0, 0xE9, 0x08, 0x11, 0xC0, 0xE9, 0x0A, 0x11, + 0x41, 0x61, 0x01, 0x60, 0xC0, 0xE9, 0x0C, 0x11, 0x41, 0xF2, 0xC8, 0x11, + 0x04, 0x48, 0x14, 0xF0, 0x43, 0xB8, 0x00, 0x00, 0x78, 0x07, 0x10, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x70, 0x04, 0x10, 0x00, 0x78, 0x8B, 0x01, 0x20, + 0x11, 0x49, 0x08, 0x60, 0x4F, 0xF4, 0x00, 0x51, 0x00, 0x20, 0xFD, 0xF7, + 0x9E, 0xB9, 0x38, 0xB5, 0xAF, 0xF2, 0x13, 0x00, 0xFE, 0xF7, 0xAB, 0xFB, + 0x00, 0x22, 0x4F, 0xF4, 0x00, 0x54, 0x6B, 0x46, 0x21, 0x46, 0x10, 0x46, + 0xFD, 0xF7, 0xDA, 0xF9, 0x21, 0x46, 0x00, 0x20, 0xFD, 0xF7, 0xB9, 0xF9, + 0x06, 0x48, 0xA5, 0x22, 0x01, 0x68, 0x04, 0x48, 0x0A, 0x74, 0x00, 0x68, + 0x20, 0xF0, 0x7F, 0x42, 0x4A, 0x61, 0xFE, 0xF7, 0xB2, 0xFB, 0x38, 0xBD, + 0xB8, 0x04, 0x10, 0x00, 0x50, 0x07, 0x10, 0x00, 0x02, 0x00, 0x04, 0xD0, + 0x01, 0x2A, 0x04, 0xD0, 0x02, 0x28, 0x03, 0xD1, 0x04, 0xE0, 0x01, 0x20, + 0x00, 0xE0, 0x04, 0x20, 0x13, 0xF0, 0x32, 0xBB, 0x01, 0x20, 0x12, 0xF0, + 0xD1, 0xBC, 0x10, 0xB5, 0x01, 0x46, 0x34, 0x22, 0xFA, 0x48, 0x13, 0xF0, + 0xA1, 0xFF, 0x01, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x20, 0xFD, 0xF7, + 0x62, 0xB9, 0x30, 0xB5, 0x85, 0xB0, 0x04, 0x46, 0x68, 0x46, 0x13, 0xF0, + 0xB5, 0xFB, 0xF4, 0x48, 0x00, 0x90, 0xAC, 0xB1, 0x01, 0x2C, 0x15, 0xD0, + 0x02, 0x2C, 0x15, 0xD0, 0x03, 0x2C, 0x31, 0xD1, 0x5F, 0xF0, 0x08, 0x00, + 0x8D, 0xF8, 0x04, 0x00, 0x01, 0x20, 0x8D, 0xF8, 0x0D, 0x00, 0xED, 0x48, + 0x00, 0x68, 0x90, 0xF8, 0xB0, 0x00, 0xC0, 0xF3, 0xC1, 0x00, 0x02, 0x28, + 0x08, 0xD0, 0x0A, 0xE0, 0x05, 0x20, 0xEF, 0xE7, 0x06, 0x20, 0xED, 0xE7, + 0x02, 0x20, 0x8D, 0xF8, 0x09, 0x00, 0xEB, 0xE7, 0x00, 0x20, 0x8D, 0xF8, + 0x0D, 0x00, 0xE1, 0x4D, 0x03, 0x24, 0x68, 0x46, 0x13, 0xF0, 0xB1, 0xFB, + 0x00, 0x22, 0x04, 0xAB, 0x01, 0x21, 0x10, 0x46, 0xFD, 0xF7, 0x76, 0xF9, + 0x01, 0x21, 0x00, 0x20, 0xFD, 0xF7, 0x55, 0xF9, 0x28, 0x78, 0x00, 0x28, + 0x04, 0xD0, 0x0F, 0xF0, 0x38, 0xF9, 0x64, 0x1E, 0x00, 0x2C, 0xEA, 0xDC, + 0x05, 0xB0, 0x30, 0xBD, 0x2D, 0xE9, 0xF1, 0x4F, 0x88, 0xB0, 0x13, 0xF0, + 0xD0, 0xFB, 0x01, 0x90, 0x13, 0xF0, 0xCF, 0xFB, 0x06, 0x46, 0xD2, 0x4C, + 0x08, 0x98, 0x88, 0x46, 0x00, 0x28, 0x20, 0x68, 0x07, 0xD0, 0xB0, 0xF8, + 0x7A, 0x11, 0x08, 0x98, 0xFF, 0xF7, 0x8E, 0xFF, 0x03, 0x90, 0xCD, 0x48, + 0x10, 0xE0, 0x90, 0xF8, 0xE7, 0x00, 0x10, 0xF0, 0x60, 0x0F, 0x03, 0xD0, + 0x01, 0x98, 0x10, 0xF0, 0xDB, 0xF8, 0x01, 0x90, 0x20, 0x68, 0xB0, 0xF8, + 0x72, 0x11, 0x08, 0x98, 0xFF, 0xF7, 0x7C, 0xFF, 0x03, 0x90, 0xC5, 0x48, + 0x02, 0x90, 0x20, 0x20, 0x06, 0x90, 0xBF, 0x48, 0x4F, 0xF0, 0x40, 0x0A, + 0xB8, 0x21, 0xD0, 0x38, 0x13, 0xF0, 0x82, 0xFF, 0x00, 0x20, 0x00, 0x90, + 0x08, 0x98, 0xFF, 0xF7, 0x86, 0xFF, 0xB9, 0x48, 0x00, 0x27, 0xB9, 0x46, + 0x80, 0x68, 0x4F, 0xF0, 0x01, 0x0B, 0x3C, 0x46, 0x05, 0x90, 0x01, 0x20, + 0x01, 0x99, 0xA0, 0x40, 0x08, 0x42, 0x40, 0xD0, 0x00, 0x25, 0x2A, 0x46, + 0x01, 0x20, 0x00, 0x21, 0x13, 0xF0, 0x92, 0xFE, 0x02, 0x46, 0x0B, 0x46, + 0x30, 0x40, 0x01, 0xEA, 0x08, 0x01, 0x08, 0x43, 0x21, 0xD0, 0xAC, 0x48, + 0xD0, 0x38, 0x00, 0xEB, 0xC4, 0x01, 0x04, 0x91, 0xD1, 0xE9, 0x00, 0x01, + 0x8E, 0x46, 0x00, 0xEA, 0x02, 0x0C, 0x19, 0x40, 0x5C, 0xEA, 0x01, 0x0C, + 0x12, 0xD1, 0x05, 0x99, 0x31, 0xF9, 0x17, 0xC0, 0x03, 0x99, 0x8C, 0x45, + 0x06, 0xDC, 0x10, 0x43, 0x04, 0x9A, 0x4E, 0xEA, 0x03, 0x01, 0xC2, 0xE9, + 0x00, 0x01, 0x05, 0xE0, 0x2A, 0x46, 0x49, 0x46, 0x00, 0x9B, 0x02, 0x98, + 0xFD, 0xF7, 0xF9, 0xFA, 0x7F, 0x1C, 0x6D, 0x1C, 0x55, 0x45, 0xCE, 0xDB, + 0x99, 0x48, 0xD0, 0x38, 0x00, 0xEB, 0xC4, 0x01, 0xD1, 0xE9, 0x00, 0x01, + 0x70, 0x40, 0x81, 0xEA, 0x08, 0x01, 0x08, 0x43, 0x01, 0xD0, 0x4F, 0xF0, + 0x00, 0x0B, 0x09, 0xF1, 0x01, 0x09, 0x06, 0x98, 0x64, 0x1C, 0x84, 0x42, + 0xB5, 0xDB, 0xBB, 0xF1, 0x01, 0x0F, 0x04, 0xD0, 0x00, 0x98, 0x40, 0x1C, + 0x00, 0x90, 0x7F, 0x28, 0xA2, 0xDD, 0x09, 0xB0, 0x58, 0x46, 0xBD, 0xE8, + 0xF0, 0x8F, 0x2D, 0xE9, 0xF1, 0x4F, 0x8A, 0xB0, 0x13, 0xF0, 0x3B, 0xFB, + 0x06, 0x90, 0x13, 0xF0, 0x38, 0xFB, 0x00, 0x21, 0xCD, 0xE9, 0x02, 0x01, + 0x0A, 0x98, 0x86, 0x4C, 0x00, 0x28, 0x56, 0xD0, 0x20, 0x68, 0xB0, 0xF8, + 0x7A, 0x11, 0x0A, 0x98, 0xFF, 0xF7, 0xF8, 0xFE, 0x01, 0x90, 0x82, 0x48, + 0x05, 0x90, 0x20, 0x20, 0x09, 0x90, 0x4F, 0xF0, 0x40, 0x0A, 0x04, 0x21, + 0x06, 0xA8, 0xFD, 0xF7, 0xB4, 0xFE, 0x04, 0x46, 0x08, 0x21, 0x02, 0xA8, + 0xFD, 0xF7, 0xAF, 0xFE, 0x44, 0x43, 0x7C, 0x48, 0x00, 0x90, 0x00, 0xF5, + 0xE6, 0x60, 0x21, 0x46, 0x04, 0x90, 0x13, 0xF0, 0xCF, 0xFE, 0x61, 0x00, + 0x00, 0x98, 0x13, 0xF0, 0xCB, 0xFE, 0x71, 0x48, 0xB8, 0x21, 0xD0, 0x38, + 0x13, 0xF0, 0xE8, 0xFE, 0x00, 0x25, 0x0A, 0x98, 0xFF, 0xF7, 0xED, 0xFE, + 0x6C, 0x48, 0x4F, 0xF0, 0x00, 0x09, 0x4C, 0x46, 0x80, 0x68, 0x07, 0x90, + 0x68, 0x42, 0x4F, 0xF0, 0x01, 0x0B, 0x4E, 0x46, 0x08, 0x90, 0x01, 0x20, + 0x06, 0x99, 0xB0, 0x40, 0x08, 0x42, 0x79, 0xD0, 0x00, 0x27, 0x3A, 0x46, + 0x01, 0x20, 0x00, 0x21, 0x13, 0xF0, 0xF6, 0xFD, 0xDD, 0xE9, 0x02, 0x8C, + 0x02, 0x46, 0x0B, 0x46, 0x00, 0xEA, 0x08, 0x00, 0x01, 0xEA, 0x0C, 0x01, + 0x08, 0x43, 0x6A, 0xD0, 0x5C, 0x48, 0xD0, 0x38, 0x00, 0xEB, 0xC6, 0x0C, + 0xDC, 0xE9, 0x00, 0x01, 0x10, 0x40, 0x19, 0x40, 0x08, 0x43, 0x0D, 0xD0, + 0x89, 0xE0, 0x06, 0x98, 0x0F, 0xF0, 0xFC, 0xFF, 0x06, 0x90, 0x20, 0x68, + 0xB0, 0xF8, 0x72, 0x11, 0x0A, 0x98, 0xFF, 0xF7, 0x9D, 0xFE, 0x01, 0x90, + 0x55, 0x48, 0xA3, 0xE7, 0x00, 0x2D, 0x0A, 0xDA, 0x07, 0x98, 0x30, 0xF9, + 0x14, 0x10, 0x01, 0x98, 0x81, 0x42, 0x01, 0xDB, 0x00, 0x21, 0x00, 0xE0, + 0x01, 0x21, 0x04, 0x98, 0x01, 0x55, 0x07, 0x98, 0x01, 0x99, 0x30, 0xF9, + 0x14, 0x00, 0x88, 0x42, 0x2A, 0xDD, 0x04, 0x99, 0x09, 0x5D, 0x11, 0xB1, + 0x01, 0x29, 0x07, 0xD0, 0x63, 0xE0, 0x7F, 0x2D, 0x61, 0xDA, 0x00, 0x99, + 0x6B, 0x1C, 0x21, 0xF8, 0x14, 0x00, 0x4C, 0xE0, 0xDC, 0xE9, 0x00, 0x10, + 0x11, 0x43, 0x18, 0x43, 0xCC, 0xE9, 0x00, 0x10, 0x00, 0x98, 0x30, 0xF9, + 0x14, 0x10, 0x01, 0x98, 0x08, 0x1A, 0x07, 0x99, 0x31, 0xF9, 0x14, 0x20, + 0x01, 0x99, 0xA2, 0xEB, 0x01, 0x01, 0x00, 0xD5, 0x40, 0x42, 0x00, 0x29, + 0x00, 0xDA, 0x49, 0x42, 0x88, 0x42, 0x3A, 0xDC, 0x08, 0x9B, 0x3A, 0x46, + 0x49, 0x46, 0x5B, 0x1C, 0x05, 0x98, 0x31, 0xE0, 0x37, 0xDA, 0x04, 0x99, + 0x09, 0x5D, 0x01, 0x29, 0x01, 0xD0, 0x79, 0xB1, 0x37, 0xE0, 0x08, 0x99, + 0x11, 0xF1, 0x7F, 0x0F, 0x33, 0xDD, 0x00, 0x99, 0x3A, 0x46, 0x21, 0xF8, + 0x14, 0x00, 0x08, 0x9B, 0x49, 0x46, 0x5B, 0x1E, 0x05, 0x98, 0x1D, 0xE0, + 0x3E, 0xE0, 0x29, 0xE0, 0xDC, 0xE9, 0x00, 0x10, 0x11, 0x43, 0x18, 0x43, + 0xCC, 0xE9, 0x00, 0x10, 0x00, 0x98, 0x30, 0xF9, 0x14, 0x10, 0x01, 0x98, + 0x08, 0x1A, 0x07, 0x99, 0x31, 0xF9, 0x14, 0x20, 0x01, 0x99, 0xA2, 0xEB, + 0x01, 0x01, 0x00, 0xD5, 0x40, 0x42, 0x00, 0x29, 0x00, 0xDA, 0x49, 0x42, + 0x88, 0x42, 0x06, 0xDC, 0x6B, 0x1E, 0x3A, 0x46, 0x49, 0x46, 0x05, 0x98, + 0xFD, 0xF7, 0xF1, 0xF9, 0x09, 0xE0, 0x00, 0x98, 0x20, 0xF8, 0x14, 0x20, + 0x05, 0xE0, 0xDC, 0xE9, 0x00, 0x10, 0x11, 0x43, 0x18, 0x43, 0xCC, 0xE9, + 0x00, 0x10, 0x64, 0x1C, 0x7F, 0x1C, 0x57, 0x45, 0xFF, 0xF6, 0x57, 0xAF, + 0x0F, 0x48, 0xD0, 0x38, 0x00, 0xEB, 0xC6, 0x01, 0xD1, 0xE9, 0x00, 0x01, + 0xDD, 0xE9, 0x02, 0x23, 0x50, 0x40, 0x59, 0x40, 0x08, 0x43, 0x01, 0xD0, + 0x4F, 0xF0, 0x00, 0x0B, 0x09, 0xF1, 0x01, 0x09, 0x09, 0x98, 0x76, 0x1C, + 0x86, 0x42, 0xFF, 0xF6, 0x3C, 0xAF, 0x58, 0x46, 0xBB, 0xF1, 0x01, 0x0F, + 0x03, 0xD0, 0x6D, 0x1C, 0x7F, 0x2D, 0x7F, 0xF7, 0x26, 0xAF, 0x0B, 0xB0, + 0xE9, 0xE6, 0x00, 0x00, 0x80, 0x10, 0x10, 0x00, 0x47, 0x32, 0x00, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x08, 0x92, 0x01, 0x20, 0x78, 0x8B, 0x01, 0x20, + 0xD4, 0x56, 0x10, 0x00, 0x2D, 0xE9, 0xF1, 0x4F, 0x96, 0xB0, 0x4F, 0xF0, + 0x00, 0x0A, 0x13, 0xF0, 0x18, 0xFA, 0x0D, 0x90, 0x13, 0xF0, 0x17, 0xFA, + 0xCD, 0xE9, 0x0E, 0x01, 0x16, 0x98, 0x48, 0xB1, 0xFE, 0x48, 0x00, 0x68, + 0xB0, 0xF8, 0x7A, 0x11, 0x16, 0x98, 0xFF, 0xF7, 0xD7, 0xFD, 0x11, 0x90, + 0xFB, 0x48, 0x12, 0xE0, 0xF9, 0x4C, 0x20, 0x68, 0x90, 0xF8, 0xE7, 0x00, + 0x10, 0xF0, 0x60, 0x0F, 0x03, 0xD0, 0x0D, 0x98, 0x0F, 0xF0, 0x22, 0xFF, + 0x0D, 0x90, 0x20, 0x68, 0xB0, 0xF8, 0x72, 0x11, 0x16, 0x98, 0xFF, 0xF7, + 0xC3, 0xFD, 0x11, 0x90, 0xF2, 0x48, 0x01, 0x90, 0x40, 0x20, 0x0A, 0x90, + 0x20, 0x26, 0x04, 0x21, 0x0D, 0xA8, 0xFD, 0xF7, 0x80, 0xFD, 0x0C, 0x90, + 0x08, 0x21, 0x0E, 0xA8, 0xFD, 0xF7, 0x7B, 0xFD, 0x07, 0x90, 0xB8, 0x21, + 0xEB, 0x48, 0x13, 0xF0, 0xC1, 0xFD, 0x01, 0x20, 0x10, 0x90, 0x00, 0x20, + 0x04, 0x46, 0x05, 0x90, 0x22, 0x46, 0x01, 0x20, 0x00, 0x21, 0x13, 0xF0, + 0xDF, 0xFC, 0xDD, 0xE9, 0x0E, 0x23, 0x81, 0x46, 0x8B, 0x46, 0x10, 0x40, + 0x19, 0x40, 0x08, 0x43, 0x78, 0xD0, 0xDE, 0x48, 0x00, 0x68, 0x90, 0xF8, + 0x70, 0x01, 0x40, 0x07, 0x13, 0xD5, 0x05, 0x98, 0x80, 0xB1, 0x00, 0x25, + 0x0B, 0xE0, 0xDD, 0xE9, 0x01, 0x02, 0x29, 0x46, 0xFD, 0xF7, 0x4C, 0xF9, + 0x03, 0x46, 0x22, 0x46, 0x29, 0x46, 0x01, 0x98, 0xFD, 0xF7, 0x51, 0xF9, + 0x6D, 0x1C, 0x0C, 0x98, 0x85, 0x42, 0xF0, 0xDB, 0x02, 0x94, 0x16, 0x98, + 0xFF, 0xF7, 0x9B, 0xFD, 0xD2, 0x48, 0x4F, 0xF0, 0x01, 0x08, 0xD0, 0x30, + 0x00, 0x25, 0x80, 0x68, 0x2F, 0x46, 0x14, 0x90, 0x01, 0x20, 0x0D, 0x99, + 0xB8, 0x40, 0x08, 0x42, 0x45, 0xD0, 0xCC, 0x48, 0x00, 0xEB, 0xC7, 0x01, + 0x15, 0x91, 0xD1, 0xE9, 0x00, 0x01, 0x00, 0xEA, 0x09, 0x00, 0x01, 0xEA, + 0x0B, 0x01, 0x08, 0x43, 0x2E, 0xD1, 0x22, 0x46, 0x29, 0x46, 0x01, 0x98, + 0xFD, 0xF7, 0x20, 0xF9, 0x07, 0x9A, 0x05, 0x99, 0x05, 0xFB, 0x02, 0x12, + 0x14, 0x99, 0x31, 0xF9, 0x12, 0x20, 0x11, 0x99, 0x8A, 0x42, 0x0A, 0xDA, + 0x15, 0x98, 0x15, 0x99, 0xD0, 0xE9, 0x00, 0x20, 0x42, 0xEA, 0x09, 0x02, + 0x40, 0xEA, 0x0B, 0x00, 0xC1, 0xE9, 0x00, 0x20, 0x14, 0xE0, 0x7F, 0x28, + 0x06, 0xDA, 0x43, 0x1C, 0x22, 0x46, 0x29, 0x46, 0x01, 0x98, 0xFD, 0xF7, + 0x0E, 0xF9, 0x0B, 0xE0, 0x15, 0x98, 0x15, 0x9A, 0xD0, 0xE9, 0x00, 0x10, + 0x41, 0xEA, 0x09, 0x01, 0x40, 0xEA, 0x0B, 0x00, 0xC2, 0xE9, 0x00, 0x10, + 0x00, 0x20, 0x10, 0x90, 0x15, 0x99, 0x6D, 0x1C, 0xD1, 0xE9, 0x00, 0x01, + 0x00, 0xEA, 0x09, 0x00, 0x01, 0xEA, 0x0B, 0x01, 0x08, 0x43, 0x00, 0xD1, + 0x80, 0x46, 0x7F, 0x1C, 0xB7, 0x42, 0xB1, 0xDB, 0xB8, 0xF1, 0x00, 0x0F, + 0xA3, 0xD0, 0x05, 0x98, 0x40, 0x1C, 0x05, 0x90, 0x0A, 0x98, 0x64, 0x1C, + 0x84, 0x42, 0xFF, 0xF6, 0x75, 0xAF, 0x00, 0x20, 0xB4, 0xE0, 0x00, 0xBF, + 0x4F, 0xF0, 0x00, 0x08, 0x45, 0x46, 0x2A, 0x46, 0x01, 0x20, 0x00, 0x21, + 0x13, 0xF0, 0x4E, 0xFC, 0xDD, 0xE9, 0x0E, 0x23, 0x83, 0x46, 0x06, 0x91, + 0x10, 0x40, 0x19, 0x40, 0x08, 0x43, 0x6E, 0xD0, 0xB8, 0xF1, 0x00, 0x0F, + 0x01, 0xD1, 0x4F, 0xF0, 0x01, 0x0A, 0x16, 0x98, 0xFF, 0xF7, 0x1F, 0xFD, + 0x94, 0x48, 0x4F, 0xF0, 0x01, 0x09, 0xD0, 0x30, 0x00, 0x27, 0x80, 0x68, + 0x3C, 0x46, 0x14, 0x90, 0x01, 0x20, 0x0D, 0x99, 0xA0, 0x40, 0x08, 0x42, + 0x78, 0xD0, 0xB8, 0xF1, 0x00, 0x0F, 0x0E, 0xDD, 0x2A, 0x46, 0x39, 0x46, + 0x01, 0x98, 0xFD, 0xF7, 0xAD, 0xF8, 0x8A, 0x49, 0x2A, 0x46, 0xB8, 0x31, + 0x09, 0x57, 0x0B, 0x18, 0x39, 0x46, 0x01, 0x98, 0xFD, 0xF7, 0xAF, 0xF8, + 0x65, 0xE0, 0xBA, 0xF1, 0x01, 0x0F, 0x12, 0xD1, 0x2A, 0x46, 0x39, 0x46, + 0x01, 0x98, 0xFD, 0xF7, 0x9B, 0xF8, 0x81, 0x49, 0xB8, 0x31, 0x08, 0x55, + 0x7F, 0x48, 0x00, 0xEB, 0xC4, 0x03, 0xD3, 0xE9, 0x00, 0x01, 0x06, 0x9A, + 0x20, 0xEA, 0x0B, 0x00, 0x91, 0x43, 0xC3, 0xE9, 0x00, 0x01, 0x7A, 0x48, + 0x06, 0x9B, 0x00, 0xEB, 0xC4, 0x00, 0x0C, 0x90, 0xD0, 0xE9, 0x00, 0x10, + 0x01, 0xEA, 0x0B, 0x01, 0x18, 0x40, 0x01, 0x43, 0x39, 0xD1, 0x2A, 0x46, + 0x39, 0x46, 0x01, 0x98, 0xFD, 0xF7, 0x7C, 0xF8, 0x07, 0x9A, 0x14, 0x99, + 0x07, 0xFB, 0x02, 0x82, 0x31, 0xF9, 0x12, 0x20, 0x11, 0x99, 0x8A, 0x42, + 0x0E, 0xDA, 0x0C, 0x99, 0x06, 0x9B, 0xD1, 0xE9, 0x00, 0xC2, 0x4C, 0xEA, + 0x0B, 0x0C, 0x1A, 0x43, 0xC1, 0xE9, 0x00, 0xC2, 0x68, 0x49, 0xB8, 0x31, + 0x0A, 0x5D, 0x80, 0x1A, 0x08, 0x55, 0x1C, 0xE0, 0x7F, 0x28, 0x07, 0xDA, + 0x43, 0x1C, 0x2A, 0x46, 0x39, 0x46, 0x01, 0x98, 0xFD, 0xF7, 0x67, 0xF8, + 0x13, 0xE0, 0x29, 0xE0, 0x0C, 0x99, 0xDD, 0xF8, 0x18, 0xC0, 0x0C, 0x9B, + 0xD1, 0xE9, 0x00, 0x21, 0x42, 0xEA, 0x0B, 0x02, 0x41, 0xEA, 0x0C, 0x01, + 0xC3, 0xE9, 0x00, 0x21, 0x5A, 0x49, 0xB8, 0x31, 0x0A, 0x5D, 0x80, 0x1A, + 0x08, 0x55, 0x00, 0x20, 0x10, 0x90, 0x0C, 0x98, 0x06, 0x9A, 0xD0, 0xE9, + 0x00, 0x10, 0x01, 0xEA, 0x0B, 0x01, 0x10, 0x40, 0x01, 0x43, 0x00, 0xD1, + 0x89, 0x46, 0x7F, 0x1C, 0x64, 0x1C, 0xB4, 0x42, 0xFF, 0xF6, 0x7E, 0xAF, + 0x4F, 0xF0, 0x00, 0x0A, 0xB9, 0xF1, 0x00, 0x0F, 0x3F, 0xF4, 0x6D, 0xAF, + 0x08, 0xF1, 0x01, 0x08, 0x0A, 0x98, 0x6D, 0x1C, 0x85, 0x42, 0xFF, 0xF6, + 0x54, 0xAF, 0x16, 0x98, 0xFF, 0xF7, 0x85, 0xFC, 0x0B, 0x98, 0x40, 0x1C, + 0x0B, 0x90, 0x43, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x70, 0x11, 0x0B, 0x98, + 0xB0, 0xEB, 0x11, 0x1F, 0xFF, 0xF6, 0x42, 0xAF, 0x10, 0x98, 0x17, 0xB0, + 0x4B, 0xE5, 0x2D, 0xE9, 0xF0, 0x4F, 0x8B, 0xB0, 0x13, 0xF0, 0x8D, 0xF8, + 0x09, 0x90, 0x13, 0xF0, 0x8C, 0xF8, 0x8A, 0x46, 0x38, 0x49, 0x81, 0x46, + 0x00, 0x20, 0x0A, 0x68, 0x01, 0x46, 0x16, 0x46, 0x92, 0xF8, 0x61, 0x54, + 0x01, 0x24, 0x02, 0xF2, 0x72, 0x42, 0x00, 0xBF, 0x04, 0xFA, 0x01, 0xF3, + 0x1D, 0x42, 0x03, 0xD0, 0x57, 0x5C, 0x04, 0xFA, 0x07, 0xF3, 0x18, 0x43, + 0x49, 0x1C, 0x04, 0x29, 0xF4, 0xDB, 0x01, 0x90, 0x00, 0x20, 0x00, 0x90, + 0x20, 0x20, 0x08, 0x90, 0x40, 0x20, 0x07, 0x90, 0xB6, 0xF8, 0x82, 0x11, + 0x02, 0x20, 0xFF, 0xF7, 0x2F, 0xFC, 0x03, 0x90, 0x2A, 0x48, 0x05, 0x90, + 0x2A, 0x48, 0x00, 0x21, 0x02, 0x90, 0x01, 0x60, 0x0D, 0x46, 0x41, 0x60, + 0x02, 0x20, 0xFF, 0xF7, 0x3E, 0xFC, 0x24, 0x48, 0x00, 0x24, 0xD0, 0x30, + 0xA3, 0x46, 0x40, 0x69, 0x06, 0x90, 0x01, 0x20, 0x27, 0x46, 0x04, 0x90, + 0x01, 0x20, 0x09, 0x99, 0xB8, 0x40, 0x08, 0x42, 0x63, 0xD0, 0x00, 0x26, + 0x32, 0x46, 0x01, 0x20, 0x00, 0x21, 0x13, 0xF0, 0x49, 0xFB, 0x80, 0x46, + 0x0A, 0x46, 0x00, 0xEA, 0x09, 0x00, 0x01, 0xEA, 0x0A, 0x01, 0x08, 0x43, + 0x4F, 0xD0, 0x16, 0x48, 0x00, 0xEB, 0xC7, 0x01, 0xD1, 0xE9, 0x00, 0x01, + 0x00, 0xEA, 0x08, 0x00, 0x11, 0x40, 0x08, 0x43, 0x44, 0xD1, 0x01, 0x20, + 0x01, 0x99, 0x00, 0xFA, 0x04, 0xF8, 0x18, 0xEA, 0x01, 0x0F, 0x3D, 0xD0, + 0x06, 0x98, 0x30, 0xF9, 0x14, 0x20, 0x03, 0x98, 0x82, 0x42, 0x2C, 0xDC, + 0x00, 0x2D, 0x2A, 0xDD, 0x02, 0x98, 0x30, 0xF9, 0x14, 0x10, 0x03, 0x98, + 0x08, 0x1A, 0x03, 0x99, 0xA2, 0xEB, 0x01, 0x01, 0x00, 0xD5, 0x40, 0x42, + 0x00, 0x29, 0x00, 0xDA, 0x49, 0x42, 0x0B, 0xE0, 0x4C, 0x07, 0x10, 0x00, + 0x08, 0x92, 0x01, 0x20, 0x78, 0x8B, 0x01, 0x20, 0xB0, 0x0F, 0x10, 0x00, + 0x98, 0x98, 0x01, 0x20, 0xD4, 0x56, 0x10, 0x00, 0x88, 0x42, 0x06, 0xDC, + 0x6B, 0x1E, 0x32, 0x46, 0x59, 0x46, 0x05, 0x98, 0xFC, 0xF7, 0x95, 0xFF, + 0x02, 0xE0, 0x02, 0x98, 0x20, 0xF8, 0x14, 0x20, 0x00, 0x99, 0x48, 0xEA, + 0x01, 0x00, 0x00, 0x90, 0x0A, 0xE0, 0x7F, 0x2D, 0x08, 0xDA, 0x02, 0x98, + 0x6B, 0x1C, 0x59, 0x46, 0x20, 0xF8, 0x14, 0x20, 0x32, 0x46, 0x05, 0x98, + 0xFC, 0xF7, 0x81, 0xFF, 0x64, 0x1C, 0x07, 0x98, 0x76, 0x1C, 0x86, 0x42, + 0x9E, 0xDB, 0x0B, 0xF1, 0x01, 0x0B, 0x08, 0x98, 0x7F, 0x1C, 0x87, 0x42, + 0x92, 0xDB, 0xDD, 0xE9, 0x00, 0x01, 0x88, 0x42, 0x05, 0xD0, 0x00, 0x20, + 0x6D, 0x1C, 0x04, 0x90, 0x7F, 0x2D, 0x7F, 0xF7, 0x7D, 0xAF, 0x04, 0x98, + 0xA5, 0xE5, 0x2D, 0xE9, 0xFF, 0x5F, 0x04, 0x46, 0x01, 0x25, 0x12, 0xF0, + 0xD0, 0xFF, 0xCD, 0xE9, 0x02, 0x01, 0xC5, 0x48, 0x40, 0x27, 0x08, 0x21, + 0x00, 0x68, 0x00, 0xF2, 0x02, 0x60, 0x01, 0x90, 0xC2, 0x48, 0x00, 0x90, + 0x02, 0xA8, 0xFD, 0xF7, 0x54, 0xFB, 0x06, 0x46, 0x01, 0x2C, 0x6E, 0xD1, + 0xDD, 0xE9, 0x02, 0x23, 0x29, 0x46, 0x00, 0x98, 0xFC, 0xF7, 0x5C, 0xFF, + 0xDF, 0xF8, 0xF0, 0x92, 0x00, 0x20, 0x09, 0xEB, 0x46, 0x0B, 0x47, 0xF6, + 0xFF, 0x72, 0x6F, 0xF0, 0x7E, 0x01, 0x04, 0xE0, 0x29, 0xF8, 0x10, 0x20, + 0x0B, 0xF8, 0x00, 0x10, 0x40, 0x1C, 0xB0, 0x42, 0xF8, 0xDB, 0x6F, 0xF0, + 0x7F, 0x08, 0x03, 0x20, 0xFF, 0xF7, 0x89, 0xFB, 0xB2, 0x48, 0x00, 0x24, + 0x25, 0x46, 0xD0, 0xF8, 0x08, 0xA0, 0x2A, 0x46, 0x01, 0x20, 0x00, 0x21, + 0x13, 0xF0, 0x9E, 0xFA, 0xDD, 0xE9, 0x02, 0x23, 0x10, 0x40, 0x19, 0x40, + 0x08, 0x43, 0x1D, 0xD0, 0x3A, 0xF9, 0x14, 0x10, 0x39, 0xF9, 0x14, 0x00, + 0x00, 0x29, 0x00, 0xDA, 0x49, 0x42, 0x00, 0x28, 0x00, 0xDA, 0x40, 0x42, + 0x81, 0x42, 0x0A, 0xDA, 0x2A, 0x46, 0x00, 0x21, 0x00, 0x98, 0xFC, 0xF7, + 0x0B, 0xFF, 0x0B, 0xF8, 0x04, 0x00, 0x3A, 0xF8, 0x14, 0x10, 0x29, 0xF8, + 0x14, 0x10, 0x43, 0x46, 0x2A, 0x46, 0x00, 0x21, 0x00, 0x98, 0xFC, 0xF7, + 0x0A, 0xFF, 0x64, 0x1C, 0x6D, 0x1C, 0xBD, 0x42, 0xD3, 0xDB, 0x08, 0xF1, + 0x01, 0x08, 0xB8, 0xF1, 0x7F, 0x0F, 0xC6, 0xDD, 0x00, 0x25, 0x2C, 0x46, + 0x22, 0x46, 0x01, 0x20, 0x00, 0x21, 0x13, 0xF0, 0x6B, 0xFA, 0xDD, 0xE9, + 0x02, 0x23, 0x10, 0x40, 0x19, 0x40, 0x08, 0x43, 0x07, 0xD0, 0x1B, 0xF9, + 0x05, 0x30, 0x22, 0x46, 0x00, 0x21, 0x00, 0x98, 0xFC, 0xF7, 0xED, 0xFE, + 0x6D, 0x1C, 0x64, 0x1C, 0xBC, 0x42, 0xE9, 0xDB, 0xDD, 0xE9, 0x00, 0x10, + 0x26, 0x22, 0x13, 0xF0, 0x8C, 0xFA, 0x00, 0x25, 0xDF, 0xF8, 0x24, 0x82, + 0x2C, 0x46, 0x22, 0x46, 0x01, 0x20, 0x00, 0x21, 0x13, 0xF0, 0x4C, 0xFA, + 0xDD, 0xE9, 0x02, 0x23, 0x10, 0x40, 0x19, 0x40, 0x08, 0x43, 0x07, 0xD0, + 0x22, 0x46, 0x00, 0x21, 0x00, 0x98, 0xFC, 0xF7, 0xC5, 0xFE, 0x28, 0xF8, + 0x15, 0x00, 0x6D, 0x1C, 0x64, 0x1C, 0xBC, 0x42, 0xE9, 0xDB, 0x03, 0x20, + 0xFF, 0xF7, 0x19, 0xFB, 0x7A, 0x48, 0x42, 0x46, 0x81, 0x68, 0x00, 0x20, + 0x06, 0xE0, 0x00, 0xBF, 0x31, 0xF8, 0x10, 0x30, 0x34, 0x18, 0x40, 0x1C, + 0x22, 0xF8, 0x14, 0x30, 0xB0, 0x42, 0xF7, 0xDB, 0xBD, 0xE8, 0xFF, 0x9F, + 0x2D, 0xE9, 0xF0, 0x5F, 0x07, 0x46, 0x01, 0x24, 0x00, 0x20, 0xFC, 0xF7, + 0x44, 0xFD, 0x02, 0x20, 0xFC, 0xF7, 0x41, 0xFD, 0x6F, 0x49, 0x01, 0x20, + 0x08, 0x70, 0x69, 0x4E, 0xF8, 0x07, 0x4F, 0xF0, 0x00, 0x08, 0x4F, 0xF0, + 0xA5, 0x09, 0x09, 0xD0, 0x00, 0xF0, 0x55, 0xF8, 0x10, 0xF0, 0x01, 0x04, + 0x04, 0xD0, 0x30, 0x68, 0x80, 0xF8, 0x1B, 0x80, 0x80, 0xF8, 0x1A, 0x90, + 0xB8, 0x07, 0x09, 0xD5, 0x00, 0xF0, 0x8F, 0xF8, 0x20, 0x40, 0x04, 0x00, + 0x04, 0xD0, 0x30, 0x68, 0x80, 0xF8, 0x1D, 0x80, 0x80, 0xF8, 0x1C, 0x90, + 0xDF, 0xF8, 0x80, 0xA1, 0xDA, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0x61, 0x04, + 0x58, 0xB3, 0xF8, 0x06, 0x29, 0xD5, 0x01, 0x25, 0x12, 0xF0, 0xEF, 0xFE, + 0x83, 0x46, 0x12, 0xF0, 0xEE, 0xFE, 0xDA, 0xF8, 0x00, 0x20, 0x92, 0xF8, + 0x80, 0x21, 0xD2, 0x07, 0x13, 0xD0, 0x02, 0x46, 0x0B, 0x46, 0x59, 0x46, + 0x55, 0x48, 0xFC, 0xF7, 0x81, 0xFE, 0xDA, 0xF8, 0x00, 0x00, 0x90, 0xF8, + 0x80, 0x01, 0xC0, 0x07, 0x07, 0xD0, 0xFF, 0xF7, 0x46, 0xFE, 0x05, 0x00, + 0x03, 0xD1, 0x02, 0x21, 0x74, 0x20, 0x0E, 0xF0, 0x1D, 0xFC, 0x02, 0x20, + 0xFF, 0xF7, 0xB3, 0xFA, 0x2C, 0x40, 0x04, 0xD0, 0x30, 0x68, 0x80, 0xF8, + 0x25, 0x80, 0x80, 0xF8, 0x24, 0x90, 0x00, 0x20, 0xFC, 0xF7, 0x06, 0xFD, + 0x02, 0x20, 0xFC, 0xF7, 0x03, 0xFD, 0xF8, 0x07, 0x02, 0xD0, 0x01, 0x20, + 0x00, 0xF0, 0xBA, 0xF8, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x9F, 0x2D, 0xE9, + 0xF0, 0x41, 0x01, 0x24, 0x12, 0xF0, 0xB1, 0xFE, 0x80, 0x46, 0x12, 0xF0, + 0xB0, 0xFE, 0x3C, 0x4D, 0x06, 0x46, 0x0F, 0x46, 0x28, 0x68, 0x90, 0xF8, + 0xE7, 0x00, 0x10, 0xF0, 0x60, 0x0F, 0x03, 0xD0, 0x40, 0x46, 0x0F, 0xF0, + 0xC7, 0xFB, 0x80, 0x46, 0x28, 0x68, 0x90, 0xF8, 0x70, 0x01, 0xC0, 0x07, + 0x25, 0xD0, 0x32, 0x46, 0x3B, 0x46, 0x41, 0x46, 0x33, 0x48, 0xFC, 0xF7, + 0x3B, 0xFE, 0x28, 0x68, 0x90, 0xF8, 0x70, 0x11, 0xC9, 0x07, 0x1A, 0xD0, + 0x90, 0xF8, 0xE8, 0x10, 0x89, 0x07, 0x03, 0xD4, 0x00, 0x20, 0xFF, 0xF7, + 0x6B, 0xFC, 0x0C, 0xE0, 0x90, 0xF8, 0xE7, 0x00, 0xC0, 0xF3, 0x41, 0x10, + 0x02, 0x28, 0x4F, 0xF0, 0x00, 0x00, 0x02, 0xD3, 0xFF, 0xF7, 0x3F, 0xFB, + 0x01, 0xE0, 0xFF, 0xF7, 0xA7, 0xFA, 0x04, 0x00, 0x03, 0xD1, 0x01, 0x21, + 0x74, 0x20, 0x0E, 0xF0, 0xC5, 0xFB, 0x00, 0x20, 0xFF, 0xF7, 0x5B, 0xFA, + 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x70, 0xB5, 0x01, 0x24, 0x12, 0xF0, + 0x6C, 0xFE, 0x06, 0x46, 0x12, 0xF0, 0x6B, 0xFE, 0x19, 0x4D, 0x2A, 0x68, + 0x92, 0xF8, 0x78, 0x21, 0xD2, 0x07, 0x1B, 0xD0, 0x02, 0x46, 0x0B, 0x46, + 0x31, 0x46, 0x18, 0x48, 0xFC, 0xF7, 0x02, 0xFE, 0x28, 0x68, 0x90, 0xF8, + 0x78, 0x11, 0xC9, 0x07, 0x10, 0xD0, 0x90, 0xF8, 0xE8, 0x00, 0x80, 0x07, + 0x20, 0x46, 0x02, 0xD4, 0xFF, 0xF7, 0x32, 0xFC, 0x01, 0xE0, 0xFF, 0xF7, + 0x79, 0xFA, 0x04, 0x00, 0x04, 0xD1, 0x4F, 0xF4, 0x80, 0x71, 0x74, 0x20, + 0x0E, 0xF0, 0x96, 0xFB, 0x01, 0x20, 0xFF, 0xF7, 0x2C, 0xFA, 0x20, 0x46, + 0x70, 0xBD, 0x00, 0x00, 0x50, 0x07, 0x10, 0x00, 0xE4, 0x9F, 0x01, 0x20, + 0xD4, 0x56, 0x10, 0x00, 0x80, 0x10, 0x10, 0x00, 0x04, 0x4B, 0x01, 0x20, + 0x78, 0x07, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x98, 0x98, 0x01, 0x20, + 0x78, 0x8B, 0x01, 0x20, 0x08, 0x92, 0x01, 0x20, 0x10, 0xB5, 0xFF, 0xF7, + 0xD6, 0xF9, 0x53, 0x20, 0xFF, 0xF7, 0x06, 0xFF, 0x00, 0x28, 0x12, 0xD0, + 0x4F, 0xF4, 0xD6, 0x70, 0x00, 0xF0, 0x7B, 0xFF, 0x00, 0x28, 0x0C, 0xD0, + 0x24, 0x48, 0x25, 0x49, 0x00, 0x68, 0x09, 0x68, 0x90, 0xF8, 0xDE, 0x00, + 0x08, 0x76, 0xFE, 0xF7, 0x45, 0xFE, 0xBD, 0xE8, 0x10, 0x40, 0xFE, 0xF7, + 0xD5, 0xBD, 0x10, 0xBD, 0x10, 0xB5, 0xFF, 0xF7, 0xBA, 0xF9, 0x40, 0xF2, + 0xFF, 0x10, 0xFE, 0xF7, 0x41, 0xFD, 0x1A, 0x48, 0x1A, 0x49, 0x00, 0x68, + 0x09, 0x68, 0x90, 0xF8, 0xDE, 0x00, 0x08, 0x76, 0xBD, 0xE8, 0x10, 0x40, + 0xFE, 0xF7, 0xC2, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x13, 0x49, 0x09, 0x68, + 0x91, 0xF8, 0xC1, 0x21, 0xD2, 0x07, 0x1F, 0xD0, 0x01, 0x28, 0x1D, 0xD1, + 0x10, 0x4F, 0x91, 0xF8, 0x31, 0x20, 0x91, 0xF8, 0x30, 0x10, 0x3D, 0x68, + 0x4A, 0x43, 0x02, 0x20, 0x0D, 0x4E, 0x14, 0xB2, 0x32, 0x35, 0xFD, 0xF7, + 0xE2, 0xFF, 0x03, 0x20, 0xFC, 0xF7, 0x0F, 0xFC, 0x38, 0x68, 0x62, 0x00, + 0x31, 0x46, 0x04, 0x86, 0x28, 0x46, 0x13, 0xF0, 0x1C, 0xF9, 0x03, 0x20, + 0xFC, 0xF7, 0x20, 0xFC, 0xBD, 0xE8, 0xF0, 0x41, 0xFE, 0xF7, 0x9A, 0xBD, + 0xBD, 0xE8, 0xF0, 0x81, 0x4C, 0x07, 0x10, 0x00, 0x50, 0x07, 0x10, 0x00, + 0x42, 0x44, 0x01, 0x20, 0x10, 0xB5, 0x01, 0x46, 0x34, 0x22, 0xFB, 0x48, + 0x13, 0xF0, 0x4C, 0xF9, 0x01, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x20, + 0xFC, 0xF7, 0x0D, 0xBB, 0x30, 0xB5, 0x85, 0xB0, 0x68, 0x46, 0x12, 0xF0, + 0x61, 0xFD, 0xF5, 0x48, 0x02, 0x22, 0x00, 0x78, 0xE0, 0xB1, 0x03, 0x21, + 0x01, 0x28, 0x0D, 0xD0, 0x03, 0x28, 0x0E, 0xD0, 0x02, 0x28, 0x18, 0xD0, + 0x04, 0x22, 0x05, 0x28, 0x0C, 0xD0, 0x04, 0x28, 0x0D, 0xD0, 0x06, 0x28, + 0x0E, 0xD0, 0x07, 0x28, 0x0F, 0xD0, 0x10, 0xE0, 0x8D, 0xF8, 0x06, 0x10, + 0x0D, 0xE0, 0x8D, 0xF8, 0x08, 0x10, 0x0A, 0xE0, 0x8D, 0xF8, 0x0A, 0x20, + 0x07, 0xE0, 0x8D, 0xF8, 0x0A, 0x10, 0x04, 0xE0, 0x8D, 0xF8, 0x06, 0x20, + 0x01, 0xE0, 0x8D, 0xF8, 0x08, 0x20, 0xE3, 0x48, 0x00, 0x90, 0xE3, 0x48, + 0x00, 0x68, 0x90, 0xF8, 0xB0, 0x10, 0xC9, 0x07, 0x0B, 0xD0, 0x01, 0x21, + 0x8D, 0xF8, 0x0D, 0x10, 0x90, 0xF8, 0xB0, 0x00, 0xC0, 0xF3, 0xC1, 0x00, + 0x02, 0x28, 0x02, 0xD1, 0x00, 0x20, 0x8D, 0xF8, 0x0D, 0x00, 0xD7, 0x4D, + 0x03, 0x24, 0x68, 0x46, 0x12, 0xF0, 0x47, 0xFD, 0x00, 0x22, 0x04, 0xAB, + 0x01, 0x21, 0x10, 0x46, 0xFC, 0xF7, 0x0C, 0xFB, 0x01, 0x21, 0x00, 0x20, + 0xFC, 0xF7, 0xEB, 0xFA, 0x28, 0x78, 0x00, 0x28, 0x04, 0xD0, 0x0E, 0xF0, + 0xCE, 0xFA, 0x64, 0x1E, 0x00, 0x2C, 0xEA, 0xDC, 0x05, 0xB0, 0x30, 0xBD, + 0x2D, 0xE9, 0xF0, 0x4F, 0xCA, 0x4E, 0x04, 0x46, 0x87, 0xB0, 0x06, 0x20, + 0x89, 0x46, 0x30, 0x70, 0x12, 0xF0, 0x61, 0xFD, 0x00, 0x21, 0x20, 0x27, + 0xCD, 0xE9, 0x04, 0x01, 0x1D, 0x20, 0xC7, 0x4D, 0x02, 0x90, 0x24, 0xB1, + 0x01, 0x2C, 0x0E, 0xD0, 0x02, 0x2C, 0x21, 0xD0, 0x2F, 0xE0, 0xC4, 0x48, + 0x00, 0x90, 0xDF, 0xF8, 0xF8, 0x82, 0x28, 0x68, 0x08, 0xF1, 0x18, 0x08, + 0xDF, 0xF8, 0x04, 0xA3, 0x00, 0xF5, 0xC5, 0x60, 0x22, 0xE0, 0x12, 0xF0, + 0x48, 0xFD, 0xCD, 0xE9, 0x04, 0x01, 0xBC, 0x48, 0x40, 0x27, 0x20, 0x30, + 0x00, 0x90, 0x28, 0x68, 0xDF, 0xF8, 0xD0, 0x82, 0x00, 0xF2, 0x5E, 0x60, + 0x01, 0x90, 0x26, 0x20, 0x08, 0xF1, 0x1C, 0x08, 0xDF, 0xF8, 0xDC, 0xA2, + 0x02, 0x90, 0x0E, 0xE0, 0x07, 0x20, 0x30, 0x70, 0xB2, 0x48, 0xDF, 0xF8, + 0xB4, 0x82, 0x48, 0x30, 0x00, 0x90, 0x28, 0x68, 0xDF, 0xF8, 0xC8, 0xA2, + 0x08, 0xF1, 0x28, 0x08, 0x00, 0xF2, 0x84, 0x60, 0x01, 0x90, 0x08, 0x21, + 0x04, 0xA8, 0xFD, 0xF7, 0xB4, 0xF8, 0x04, 0x46, 0xB9, 0xF1, 0x01, 0x0F, + 0x74, 0xD1, 0x22, 0x46, 0x04, 0xA9, 0x00, 0x98, 0xFC, 0xF7, 0xF7, 0xFC, + 0xDF, 0xF8, 0xA4, 0xB2, 0x47, 0xF6, 0xFF, 0x71, 0x0B, 0xEB, 0x44, 0x00, + 0x03, 0x90, 0x00, 0x20, 0x6F, 0xF0, 0x7E, 0x02, 0x05, 0xE0, 0x00, 0xBF, + 0x2B, 0xF8, 0x10, 0x10, 0x03, 0x9B, 0x1A, 0x54, 0x40, 0x1C, 0xA0, 0x42, + 0xF8, 0xDB, 0x6F, 0xF0, 0x7F, 0x09, 0x00, 0xBF, 0xFF, 0xF7, 0x3C, 0xFF, + 0xD8, 0xF8, 0x00, 0x00, 0x00, 0x25, 0x2E, 0x46, 0x06, 0x90, 0x2B, 0xE0, + 0x32, 0x46, 0x01, 0x20, 0x00, 0x21, 0x12, 0xF0, 0xFB, 0xFF, 0xDD, 0xE9, + 0x04, 0x23, 0x10, 0x40, 0x19, 0x40, 0x08, 0x43, 0x1D, 0xD0, 0x06, 0x98, + 0x30, 0xF9, 0x15, 0x10, 0x3B, 0xF9, 0x15, 0x00, 0x00, 0x29, 0x00, 0xDA, + 0x49, 0x42, 0x00, 0x28, 0x00, 0xDA, 0x40, 0x42, 0x81, 0x42, 0x0A, 0xDA, + 0x31, 0x46, 0x00, 0x98, 0xFC, 0xF7, 0xAB, 0xFC, 0x03, 0x99, 0x48, 0x55, + 0x06, 0x98, 0x30, 0xF8, 0x15, 0x10, 0x2B, 0xF8, 0x15, 0x10, 0x4A, 0x46, + 0x31, 0x46, 0x00, 0x98, 0xFC, 0xF7, 0xA6, 0xFC, 0x6D, 0x1C, 0xA5, 0x42, + 0x02, 0xD0, 0x76, 0x1C, 0xBE, 0x42, 0xD1, 0xDB, 0x09, 0xF1, 0x01, 0x09, + 0xB9, 0xF1, 0x7F, 0x0F, 0xC4, 0xDD, 0x00, 0x26, 0x35, 0x46, 0x14, 0xE0, + 0x2A, 0x46, 0x01, 0x20, 0x00, 0x21, 0x12, 0xF0, 0xC5, 0xFF, 0xDD, 0xE9, + 0x04, 0x23, 0x10, 0x40, 0x19, 0x40, 0x08, 0x43, 0x06, 0xD0, 0x03, 0x98, + 0x29, 0x46, 0x82, 0x57, 0x00, 0x98, 0xFC, 0xF7, 0x87, 0xFC, 0x76, 0x1C, + 0xA6, 0x42, 0x02, 0xD0, 0x6D, 0x1C, 0xBD, 0x42, 0xE8, 0xDB, 0xDD, 0xE9, + 0x00, 0x10, 0x02, 0x9A, 0x12, 0xF0, 0xE5, 0xFF, 0x00, 0x26, 0x35, 0x46, + 0x14, 0xE0, 0x2A, 0x46, 0x01, 0x20, 0x00, 0x21, 0x12, 0xF0, 0xA6, 0xFF, + 0xDD, 0xE9, 0x04, 0x23, 0x10, 0x40, 0x19, 0x40, 0x08, 0x43, 0x06, 0xD0, + 0x29, 0x46, 0x00, 0x98, 0xFC, 0xF7, 0x63, 0xFC, 0x2A, 0xF8, 0x16, 0x00, + 0x76, 0x1C, 0xA6, 0x42, 0x02, 0xD0, 0x6D, 0x1C, 0xBD, 0x42, 0xE8, 0xDB, + 0xFF, 0xF7, 0xC8, 0xFE, 0x00, 0x20, 0xD8, 0xF8, 0x00, 0x10, 0x05, 0xE0, + 0x31, 0xF8, 0x10, 0x30, 0x25, 0x18, 0x40, 0x1C, 0x2A, 0xF8, 0x15, 0x30, + 0xA0, 0x42, 0xF7, 0xDB, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x70, 0xB5, + 0x55, 0x4C, 0x05, 0x46, 0x20, 0x68, 0x90, 0xF8, 0x88, 0x01, 0xC0, 0x06, + 0x07, 0xD5, 0x29, 0x46, 0x00, 0x20, 0xFF, 0xF7, 0x05, 0xFF, 0x29, 0x46, + 0x01, 0x20, 0xFF, 0xF7, 0x01, 0xFF, 0x20, 0x68, 0x90, 0xF8, 0xA0, 0x01, + 0xC0, 0x06, 0x04, 0xD5, 0x29, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x02, 0x20, + 0xF6, 0xE6, 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x47, 0x45, 0x49, 0x00, 0x25, + 0x2C, 0x46, 0x0E, 0x69, 0xD1, 0xF8, 0x38, 0x30, 0x28, 0x46, 0x01, 0x27, + 0x07, 0xFA, 0x00, 0xF2, 0x32, 0x42, 0x03, 0xD0, 0x1A, 0x5C, 0xAA, 0x42, + 0x00, 0xD9, 0x15, 0x46, 0x40, 0x1C, 0x20, 0x28, 0xF4, 0xD3, 0xD1, 0xE9, + 0x14, 0x78, 0xD1, 0xF8, 0x3C, 0x90, 0x00, 0x26, 0x8A, 0x46, 0x32, 0x46, + 0x01, 0x20, 0x00, 0x21, 0x12, 0xF0, 0x48, 0xFF, 0x38, 0x40, 0x01, 0xEA, + 0x08, 0x01, 0x08, 0x43, 0x04, 0xD0, 0x19, 0xF8, 0x06, 0x00, 0xA0, 0x42, + 0x00, 0xD9, 0x04, 0x46, 0x76, 0x1C, 0x40, 0x2E, 0xED, 0xD3, 0xDA, 0xF8, + 0x48, 0x20, 0x50, 0x46, 0x15, 0x70, 0xDA, 0xF8, 0x4C, 0x10, 0x0C, 0x70, + 0xDA, 0xF8, 0x30, 0x30, 0xDA, 0xF8, 0x28, 0x70, 0xDA, 0xF8, 0x34, 0x60, + 0x1B, 0x78, 0x3F, 0x78, 0x2B, 0x44, 0x3B, 0x44, 0xDA, 0xF8, 0x2C, 0x70, + 0x36, 0x78, 0x3F, 0x78, 0x26, 0x44, 0x3E, 0x44, 0x07, 0x69, 0x6F, 0xB1, + 0xD0, 0xE9, 0x14, 0x7C, 0x57, 0xEA, 0x0C, 0x07, 0x0A, 0xD0, 0xFF, 0x27, + 0xB3, 0x42, 0x13, 0xD2, 0xF3, 0x1A, 0x2B, 0x44, 0xFF, 0x2B, 0x07, 0xD8, + 0x13, 0x70, 0x0B, 0xE0, 0x14, 0x70, 0x09, 0xE0, 0x15, 0x70, 0x0D, 0x70, + 0xBD, 0xE8, 0xF0, 0x87, 0x17, 0x70, 0xC2, 0x69, 0x42, 0xF4, 0x00, 0x72, + 0xCA, 0xF8, 0x1C, 0x20, 0x0C, 0x70, 0xF5, 0xE7, 0x9E, 0x42, 0x0D, 0xD2, + 0x9B, 0x1B, 0x23, 0x44, 0xFF, 0x2B, 0x01, 0xD8, 0x0B, 0x70, 0x05, 0xE0, + 0x0F, 0x70, 0xC1, 0x69, 0x41, 0xF4, 0x00, 0x71, 0xCA, 0xF8, 0x1C, 0x10, + 0x15, 0x70, 0xE5, 0xE7, 0x15, 0x70, 0xEB, 0xE7, 0x2D, 0xE9, 0xF0, 0x41, + 0x1F, 0x46, 0x0D, 0x46, 0x00, 0x2A, 0x34, 0xDD, 0x09, 0x4C, 0x77, 0xB1, + 0xB4, 0xF9, 0x0A, 0x60, 0x11, 0x46, 0x0F, 0xF0, 0xD6, 0xFF, 0xB0, 0x42, + 0x28, 0x78, 0x27, 0xDA, 0xFF, 0x28, 0x1C, 0xD2, 0x40, 0x1C, 0x28, 0x70, + 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x13, 0xE0, 0xB4, 0x10, 0x10, 0x00, + 0xC0, 0x04, 0x10, 0x00, 0xF1, 0x3E, 0x00, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x50, 0x07, 0x10, 0x00, 0x0C, 0xA0, 0x01, 0x20, 0x9C, 0x4B, 0x01, 0x20, + 0xF0, 0x4B, 0x01, 0x20, 0x88, 0x4C, 0x01, 0x20, 0xD4, 0x56, 0x10, 0x00, + 0xB4, 0xF9, 0x08, 0x60, 0xDA, 0xE7, 0xE0, 0x69, 0x1F, 0xB1, 0x40, 0xF0, + 0x02, 0x00, 0xE0, 0x61, 0x05, 0xE0, 0x40, 0xF4, 0x00, 0x60, 0xFA, 0xE7, + 0x08, 0xB1, 0x40, 0x1E, 0x28, 0x70, 0x01, 0x20, 0xD7, 0xE7, 0x2D, 0xE9, + 0xF0, 0x41, 0x1E, 0x46, 0x0D, 0x46, 0x00, 0x2A, 0x1A, 0xDD, 0xFE, 0x4C, + 0x66, 0xB1, 0xB4, 0xF9, 0x0A, 0x70, 0x11, 0x46, 0x0F, 0xF0, 0x99, 0xFF, + 0xB8, 0x42, 0x11, 0xDD, 0x28, 0x78, 0x50, 0xB1, 0x10, 0x28, 0x04, 0xD3, + 0x10, 0x38, 0x03, 0xE0, 0xB4, 0xF9, 0x08, 0x70, 0xF1, 0xE7, 0x00, 0x20, + 0x28, 0x70, 0x00, 0x20, 0xBB, 0xE7, 0xE0, 0x69, 0x26, 0xB1, 0x40, 0xF0, + 0x01, 0x00, 0xE0, 0x61, 0x01, 0x20, 0xB4, 0xE7, 0x40, 0xF4, 0x80, 0x60, + 0xF9, 0xE7, 0x2D, 0xE9, 0xF1, 0x4F, 0x82, 0xB0, 0x00, 0x25, 0xEC, 0x48, + 0x02, 0x9A, 0x2C, 0x46, 0xFF, 0x21, 0x02, 0xB3, 0xD0, 0xF8, 0x30, 0x90, + 0x02, 0x26, 0x4F, 0xF0, 0x18, 0x0B, 0x89, 0xF8, 0x00, 0x10, 0xD0, 0xF8, + 0x34, 0x80, 0x88, 0xF8, 0x00, 0x10, 0xB0, 0xF9, 0x0A, 0x70, 0x31, 0x46, + 0x00, 0x91, 0x41, 0x69, 0x00, 0x29, 0x00, 0xDC, 0x01, 0x25, 0xE0, 0x48, + 0x80, 0x69, 0x00, 0x28, 0x00, 0xDC, 0x01, 0x24, 0xFF, 0xF7, 0x06, 0xFF, + 0xFF, 0xF7, 0xA2, 0xFD, 0x00, 0x98, 0x00, 0xF0, 0xFD, 0xFC, 0x85, 0xB1, + 0x21, 0xE0, 0xD0, 0xF8, 0x28, 0x90, 0x4F, 0xF4, 0x00, 0x66, 0x4F, 0xF0, + 0x18, 0x0B, 0x89, 0xF8, 0x00, 0x10, 0xD0, 0xF8, 0x2C, 0x80, 0x88, 0xF8, + 0x00, 0x10, 0xB0, 0xF9, 0x08, 0x70, 0x01, 0x21, 0xDC, 0xE7, 0xDF, 0xF8, + 0x44, 0xA3, 0x3A, 0x46, 0xDA, 0xF8, 0x20, 0x00, 0xDA, 0xF8, 0x14, 0x10, + 0x00, 0x68, 0x00, 0xF0, 0xF6, 0xFC, 0x01, 0x28, 0x05, 0xD1, 0xDA, 0xF8, + 0x1C, 0x10, 0x31, 0x43, 0x01, 0x25, 0xCA, 0xF8, 0x1C, 0x10, 0x8C, 0xB9, + 0xDF, 0xF8, 0x1C, 0xA3, 0x3A, 0x46, 0xDA, 0xF8, 0x24, 0x00, 0xDA, 0xF8, + 0x18, 0x10, 0x00, 0x68, 0x00, 0xF0, 0xE3, 0xFC, 0x01, 0x28, 0x05, 0xD1, + 0xDA, 0xF8, 0x1C, 0x10, 0x31, 0x43, 0x01, 0x24, 0xCA, 0xF8, 0x1C, 0x10, + 0x0D, 0xB1, 0x00, 0x2C, 0x4E, 0xD1, 0x2F, 0x46, 0x26, 0x46, 0x4F, 0xF0, + 0x17, 0x0A, 0x4F, 0xB9, 0xBA, 0x48, 0x02, 0x9B, 0x01, 0x6A, 0x42, 0x69, + 0x0F, 0x68, 0x49, 0x46, 0x38, 0x46, 0xFF, 0xF7, 0x6A, 0xFF, 0x07, 0x46, + 0x4E, 0xB9, 0xB5, 0x48, 0x02, 0x9B, 0x41, 0x6A, 0x82, 0x69, 0x0E, 0x68, + 0x41, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0x5F, 0xFF, 0x06, 0x46, 0xFF, 0xF7, + 0xAB, 0xFE, 0xFF, 0xF7, 0x47, 0xFD, 0x00, 0x98, 0x00, 0xF0, 0xA2, 0xFC, + 0x07, 0xB1, 0x16, 0xB9, 0xBA, 0xF1, 0x01, 0x0A, 0xDD, 0xD2, 0x2F, 0x46, + 0xA9, 0x4D, 0xAB, 0xF1, 0x01, 0x06, 0x3F, 0xB9, 0x28, 0x6A, 0x02, 0x9B, + 0x49, 0x46, 0x00, 0x68, 0x6A, 0x69, 0xFF, 0xF7, 0x09, 0xFF, 0x07, 0x46, + 0x3C, 0xB9, 0x68, 0x6A, 0x02, 0x9B, 0x41, 0x46, 0x00, 0x68, 0xAA, 0x69, + 0xFF, 0xF7, 0x00, 0xFF, 0x04, 0x46, 0xFF, 0xF7, 0x89, 0xFE, 0xFF, 0xF7, + 0x25, 0xFD, 0x00, 0x98, 0x00, 0xF0, 0x80, 0xFC, 0x07, 0xB1, 0x0C, 0xB9, + 0x76, 0x1E, 0xE2, 0xD2, 0x01, 0x2F, 0x05, 0xD1, 0x01, 0x2C, 0x03, 0xD1, + 0xE8, 0x69, 0x20, 0xF4, 0x00, 0x70, 0xE8, 0x61, 0xBD, 0xE8, 0xFE, 0x8F, + 0x2D, 0xE9, 0xF0, 0x4F, 0x9A, 0x46, 0x91, 0x46, 0x00, 0x22, 0x92, 0x4B, + 0x83, 0x46, 0x14, 0x46, 0xB3, 0xF9, 0x0C, 0x70, 0x10, 0x46, 0x01, 0x23, + 0x90, 0x46, 0x14, 0xE0, 0x09, 0xEB, 0xE4, 0x05, 0x04, 0xF0, 0x07, 0x0C, + 0x2E, 0x78, 0x03, 0xFA, 0x0C, 0xF5, 0x35, 0x42, 0x0A, 0xD0, 0x3B, 0xF9, + 0x12, 0x50, 0xBD, 0x42, 0x03, 0xDC, 0x0A, 0xF8, 0x02, 0x30, 0x01, 0x20, + 0x01, 0xE0, 0x0A, 0xF8, 0x02, 0x80, 0x52, 0x1C, 0x64, 0x1C, 0x8A, 0x42, + 0xE8, 0xDB, 0x32, 0xE6, 0x2D, 0xE9, 0xFF, 0x5F, 0x00, 0x24, 0x4F, 0xF0, + 0x01, 0x08, 0x9A, 0x46, 0x17, 0x46, 0x25, 0x46, 0xDF, 0xF8, 0xF4, 0x91, + 0x46, 0x46, 0xDD, 0xF8, 0x3C, 0xB0, 0x4E, 0xE0, 0x0A, 0xEB, 0xE5, 0x00, + 0x05, 0xF0, 0x07, 0x01, 0x00, 0x78, 0x06, 0xFA, 0x01, 0xF2, 0x02, 0x42, + 0x44, 0xD0, 0x1B, 0xF8, 0x04, 0x00, 0x01, 0x28, 0x3F, 0xD0, 0x00, 0x98, + 0xB9, 0xF9, 0x0C, 0x10, 0x30, 0xF9, 0x14, 0x20, 0x8A, 0x42, 0x1D, 0xDA, + 0x29, 0x46, 0x01, 0x98, 0xFC, 0xF7, 0x87, 0xFA, 0xFF, 0x28, 0x0E, 0xDA, + 0x40, 0x1C, 0xC2, 0xB2, 0x4F, 0xF0, 0x00, 0x08, 0x29, 0x46, 0x01, 0x98, + 0xFC, 0xF7, 0x7F, 0xFA, 0x00, 0x98, 0x30, 0xF8, 0x14, 0x10, 0x0E, 0x98, + 0x20, 0xF8, 0x14, 0x10, 0x23, 0xE0, 0x0B, 0xF8, 0x04, 0x60, 0xD9, 0xF8, + 0x1C, 0x10, 0x41, 0xF0, 0x08, 0x01, 0xC9, 0xF8, 0x1C, 0x10, 0x1A, 0xE0, + 0x0E, 0x98, 0x30, 0xF9, 0x14, 0x00, 0x00, 0x28, 0x13, 0xDD, 0x40, 0x1A, + 0xA2, 0xEB, 0x01, 0x01, 0x00, 0xD5, 0x40, 0x42, 0x00, 0x29, 0x00, 0xDA, + 0x49, 0x42, 0x88, 0x42, 0x09, 0xDC, 0x29, 0x46, 0x01, 0x98, 0xFC, 0xF7, + 0x5A, 0xFA, 0x40, 0x1E, 0xC2, 0xB2, 0x29, 0x46, 0x01, 0x98, 0xFC, 0xF7, + 0x56, 0xFA, 0x0B, 0xF8, 0x04, 0x60, 0x64, 0x1C, 0x6D, 0x1C, 0xBC, 0x42, + 0xAE, 0xDB, 0x40, 0x46, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x9F, 0x2D, 0xE9, + 0xFF, 0x5F, 0x00, 0x24, 0x4F, 0xF0, 0x01, 0x08, 0x9A, 0x46, 0x17, 0x46, + 0x25, 0x46, 0x46, 0x46, 0xDF, 0xF8, 0x2C, 0x91, 0xDD, 0xF8, 0x38, 0xB0, + 0x31, 0xE0, 0x00, 0xBF, 0x0A, 0xEB, 0xE5, 0x00, 0x05, 0xF0, 0x07, 0x02, + 0x01, 0x78, 0x06, 0xFA, 0x02, 0xF0, 0x08, 0x42, 0x26, 0xD0, 0x1B, 0xF8, + 0x04, 0x00, 0x01, 0x28, 0x21, 0xD0, 0x00, 0x98, 0x30, 0xF9, 0x14, 0x10, + 0xB9, 0xF9, 0x0C, 0x00, 0x81, 0x42, 0x1A, 0xDD, 0x29, 0x46, 0x01, 0x98, + 0xFC, 0xF7, 0x23, 0xFA, 0x00, 0x28, 0x0C, 0xDD, 0x4F, 0xF0, 0x00, 0x08, + 0x04, 0x28, 0x01, 0xDB, 0x00, 0x1F, 0x00, 0xE0, 0x00, 0x20, 0xC2, 0xB2, + 0x29, 0x46, 0x01, 0x98, 0xFC, 0xF7, 0x17, 0xFA, 0x07, 0xE0, 0x0B, 0xF8, + 0x04, 0x60, 0xD9, 0xF8, 0x1C, 0x10, 0x41, 0xF0, 0x04, 0x01, 0xC9, 0xF8, + 0x1C, 0x10, 0x64, 0x1C, 0x6D, 0x1C, 0xBC, 0x42, 0xCC, 0xDB, 0x40, 0x46, + 0xB8, 0xE7, 0x2D, 0xE9, 0xF0, 0x4F, 0x93, 0xB0, 0x00, 0x24, 0x25, 0x46, + 0x18, 0x21, 0x0C, 0xA8, 0x12, 0xF0, 0xE0, 0xFD, 0x28, 0x21, 0x02, 0xA8, + 0x12, 0xF0, 0xDC, 0xFD, 0x27, 0x48, 0x41, 0x69, 0x00, 0x29, 0x00, 0xDC, + 0x01, 0x24, 0x82, 0x69, 0x00, 0x2A, 0x00, 0xDC, 0x01, 0x25, 0x23, 0x4A, + 0x81, 0x46, 0x06, 0x46, 0xFF, 0x23, 0x10, 0x32, 0x80, 0x6B, 0x00, 0xF0, + 0xA6, 0xFB, 0x1F, 0x4A, 0xFF, 0x23, 0x50, 0x32, 0xB1, 0x69, 0xF0, 0x6B, + 0x00, 0xF0, 0x9F, 0xFB, 0xFF, 0xF7, 0x82, 0xFD, 0xFF, 0xF7, 0x1E, 0xFC, + 0x04, 0x20, 0x00, 0xF0, 0x79, 0xFB, 0x8C, 0xB1, 0xD9, 0xF8, 0x20, 0x00, + 0x16, 0x4A, 0x4E, 0x46, 0x00, 0x68, 0x0C, 0xAB, 0x10, 0x32, 0xD9, 0xF8, + 0x14, 0x10, 0xFF, 0xF7, 0xFB, 0xFE, 0x01, 0x28, 0x04, 0xD1, 0xF0, 0x69, + 0x01, 0x24, 0x40, 0xF0, 0x08, 0x00, 0xF0, 0x61, 0x8D, 0xB1, 0xD9, 0xF8, + 0x24, 0x00, 0x0D, 0x4A, 0x4E, 0x46, 0x00, 0x68, 0x02, 0xAB, 0x50, 0x32, + 0xD9, 0xF8, 0x18, 0x10, 0xFF, 0xF7, 0xE8, 0xFE, 0x01, 0x28, 0x04, 0xD1, + 0xF0, 0x69, 0x01, 0x25, 0x40, 0xF0, 0x08, 0x00, 0xF0, 0x61, 0x0C, 0xB1, + 0x00, 0x2D, 0x7A, 0xD1, 0x26, 0x46, 0xA8, 0x46, 0x00, 0x27, 0x0D, 0xF1, + 0x30, 0x0B, 0x86, 0xB9, 0x02, 0xE0, 0x00, 0x00, 0xC0, 0x04, 0x10, 0x00, + 0xCD, 0xF8, 0x00, 0xB0, 0xD9, 0xF8, 0x20, 0x00, 0xFE, 0x4B, 0xD9, 0xF8, + 0x14, 0x20, 0x00, 0x68, 0xD9, 0xF8, 0x38, 0x10, 0xFF, 0xF7, 0x51, 0xFF, + 0x06, 0x46, 0xB8, 0xF1, 0x00, 0x0F, 0x0D, 0xD1, 0x02, 0xA8, 0x00, 0x90, + 0xD9, 0xF8, 0x24, 0x10, 0xF6, 0x4B, 0xD9, 0xF8, 0x18, 0x20, 0x08, 0x68, + 0x40, 0x33, 0xD9, 0xF8, 0x3C, 0x10, 0xFF, 0xF7, 0x40, 0xFF, 0x80, 0x46, + 0xFF, 0xF7, 0x2A, 0xFD, 0xFF, 0xF7, 0xC6, 0xFB, 0x04, 0x20, 0x00, 0xF0, + 0x21, 0xFB, 0x16, 0xB1, 0xB8, 0xF1, 0x00, 0x0F, 0x02, 0xD1, 0x7F, 0x1C, + 0x60, 0x2F, 0xCE, 0xDB, 0xDF, 0xF8, 0xAC, 0xA3, 0xD9, 0xF8, 0x14, 0x00, + 0x26, 0x46, 0x41, 0x00, 0x0A, 0xF5, 0xE6, 0x68, 0x4C, 0x46, 0x50, 0x46, + 0x12, 0xF0, 0x30, 0xFD, 0xA0, 0x69, 0x41, 0x00, 0x40, 0x46, 0x12, 0xF0, + 0x2B, 0xFD, 0x00, 0x27, 0xFF, 0xF7, 0xA8, 0xFB, 0x04, 0x20, 0x00, 0xF0, + 0x03, 0xFB, 0x4E, 0xB9, 0xCD, 0xE9, 0x00, 0xAB, 0x20, 0x6A, 0xDD, 0x4B, + 0x62, 0x69, 0x00, 0x68, 0xA1, 0x6B, 0xFF, 0xF7, 0xAD, 0xFE, 0x06, 0x46, + 0x5D, 0xB9, 0x02, 0xA8, 0xCD, 0xE9, 0x00, 0x80, 0x60, 0x6A, 0xD7, 0x4B, + 0xA2, 0x69, 0x00, 0x68, 0x40, 0x33, 0xE1, 0x6B, 0xFF, 0xF7, 0xA0, 0xFE, + 0x05, 0x46, 0xFF, 0xF7, 0xED, 0xFC, 0xFF, 0xF7, 0x89, 0xFB, 0x04, 0x20, + 0x00, 0xF0, 0xE4, 0xFA, 0x06, 0xB1, 0x15, 0xB9, 0x7F, 0x1C, 0x60, 0x2F, + 0xD6, 0xDB, 0x01, 0x2E, 0x07, 0xD1, 0x01, 0x2D, 0x05, 0xD1, 0xE0, 0x69, + 0x81, 0x05, 0x02, 0xD5, 0x20, 0xF4, 0x00, 0x70, 0xE0, 0x61, 0x13, 0xB0, + 0xB9, 0xE4, 0x2D, 0xE9, 0xF0, 0x41, 0x0F, 0x46, 0xC5, 0x49, 0x16, 0x46, + 0x02, 0x46, 0x10, 0x39, 0xDD, 0xE9, 0x06, 0x05, 0xB1, 0xF9, 0x0E, 0xC0, + 0x01, 0x24, 0x62, 0x45, 0x11, 0xDD, 0x1D, 0x68, 0xA0, 0xF1, 0x7F, 0x02, + 0x95, 0x42, 0x07, 0xDD, 0x2A, 0x1A, 0x31, 0x46, 0x38, 0x46, 0x1A, 0x60, + 0xFC, 0xF7, 0xF4, 0xF8, 0x00, 0x24, 0x11, 0xE0, 0xC8, 0x69, 0x40, 0xF0, + 0x40, 0x00, 0xC8, 0x61, 0x0C, 0xE0, 0x01, 0x21, 0x29, 0x70, 0x19, 0x68, + 0xC0, 0xF1, 0x7F, 0x02, 0x91, 0x42, 0x05, 0xDA, 0x0A, 0x18, 0x31, 0x46, + 0x38, 0x46, 0x1A, 0x60, 0xFC, 0xF7, 0xE0, 0xF8, 0x20, 0x46, 0x30, 0xE5, + 0x2D, 0xE9, 0xFF, 0x4F, 0x00, 0x24, 0x85, 0xB0, 0x91, 0x46, 0x06, 0x46, + 0x25, 0x46, 0xA2, 0x46, 0x78, 0xE0, 0x08, 0x98, 0x05, 0xF0, 0x07, 0x03, + 0x00, 0xEB, 0xE5, 0x00, 0x7F, 0x22, 0x01, 0x78, 0x01, 0x20, 0x98, 0x40, + 0x08, 0x42, 0x03, 0x92, 0x6B, 0xD0, 0x29, 0x46, 0x06, 0x98, 0xFC, 0xF7, + 0xC5, 0xF8, 0x00, 0x20, 0x8D, 0xF8, 0x08, 0x00, 0x80, 0x46, 0x4F, 0xF0, + 0x10, 0x0B, 0x00, 0xBF, 0xFF, 0xF7, 0x24, 0xFB, 0x08, 0x20, 0x00, 0xF0, + 0x7F, 0xFA, 0x02, 0xAF, 0xCD, 0xE9, 0x00, 0xB7, 0x36, 0xF9, 0x14, 0x00, + 0x03, 0xAB, 0x2A, 0x46, 0x06, 0x99, 0xFF, 0xF7, 0xA2, 0xFF, 0x20, 0xB9, + 0x08, 0xF1, 0x01, 0x08, 0xB8, 0xF1, 0x18, 0x0F, 0xEA, 0xDB, 0x9D, 0xF8, + 0x08, 0x00, 0xE0, 0xB3, 0x00, 0x20, 0x8D, 0xF8, 0x08, 0x00, 0x80, 0x46, + 0x4F, 0xF0, 0x04, 0x0B, 0xFF, 0xF7, 0x06, 0xFB, 0x08, 0x20, 0x00, 0xF0, + 0x61, 0xFA, 0xCD, 0xE9, 0x00, 0xB7, 0x36, 0xF9, 0x14, 0x00, 0x03, 0xAB, + 0x2A, 0x46, 0x06, 0x99, 0xFF, 0xF7, 0x85, 0xFF, 0x20, 0xB9, 0x08, 0xF1, + 0x01, 0x08, 0xB8, 0xF1, 0x18, 0x0F, 0xEB, 0xDB, 0x9D, 0xF8, 0x08, 0x00, + 0xF8, 0xB1, 0x00, 0x20, 0x8D, 0xF8, 0x08, 0x00, 0x80, 0x46, 0x4F, 0xF0, + 0x01, 0x0B, 0x00, 0xBF, 0xFF, 0xF7, 0xE8, 0xFA, 0x08, 0x20, 0x00, 0xF0, + 0x43, 0xFA, 0xCD, 0xE9, 0x00, 0xB7, 0x36, 0xF9, 0x14, 0x00, 0x03, 0xAB, + 0x2A, 0x46, 0x06, 0x99, 0xFF, 0xF7, 0x67, 0xFF, 0x78, 0xB1, 0x9D, 0xF8, + 0x08, 0x00, 0x01, 0x28, 0x10, 0xD0, 0x03, 0x9A, 0x29, 0x46, 0x52, 0x1E, + 0x03, 0x92, 0x06, 0x98, 0x00, 0xE0, 0x09, 0xE0, 0xFC, 0xF7, 0x66, 0xF8, + 0x0A, 0xF1, 0x01, 0x0A, 0x04, 0xE0, 0x08, 0xF1, 0x01, 0x08, 0xB8, 0xF1, + 0x18, 0x0F, 0xDB, 0xDB, 0x64, 0x1C, 0x6D, 0x1C, 0x4C, 0x45, 0x84, 0xDB, + 0xCA, 0x45, 0x02, 0xD0, 0x00, 0x20, 0x09, 0xB0, 0xCD, 0xE5, 0x01, 0x20, + 0xFB, 0xE7, 0x70, 0xB5, 0x69, 0x4C, 0x01, 0x25, 0x10, 0x3C, 0xA2, 0x69, + 0x00, 0x2A, 0x08, 0xDD, 0x60, 0x6A, 0x04, 0xF1, 0x50, 0x03, 0x61, 0x6C, + 0x00, 0x68, 0xFF, 0xF7, 0x67, 0xFF, 0x00, 0xF0, 0x01, 0x05, 0x62, 0x69, + 0x00, 0x2A, 0x06, 0xDD, 0x20, 0x6A, 0x60, 0x4B, 0x21, 0x6C, 0x00, 0x68, + 0xFF, 0xF7, 0x5C, 0xFF, 0x05, 0x40, 0x28, 0x46, 0x70, 0xBD, 0x70, 0xB5, + 0x5B, 0x4C, 0x00, 0x26, 0x10, 0x3C, 0x05, 0x46, 0xE6, 0x61, 0x01, 0x28, + 0x5B, 0xD0, 0x02, 0x2D, 0x5B, 0xD0, 0x01, 0x20, 0x20, 0x70, 0x60, 0x79, + 0x60, 0xB1, 0x00, 0x23, 0x54, 0x4A, 0x61, 0x69, 0xA0, 0x6B, 0x00, 0xF0, + 0x08, 0xFA, 0x52, 0x4A, 0x00, 0x23, 0x40, 0x32, 0xA1, 0x69, 0xE0, 0x6B, + 0x00, 0xF0, 0x01, 0xFA, 0xA0, 0x79, 0x50, 0xB1, 0x4D, 0x49, 0x62, 0x69, + 0x20, 0x6C, 0xFC, 0xF7, 0x20, 0xF8, 0x4B, 0x49, 0xA2, 0x69, 0x40, 0x31, + 0x60, 0x6C, 0xFC, 0xF7, 0x1A, 0xF8, 0xE0, 0x78, 0x10, 0xB1, 0x00, 0x20, + 0xFF, 0xF7, 0xAB, 0xFC, 0x20, 0x79, 0x60, 0xB1, 0xE0, 0x78, 0x38, 0xB1, + 0x61, 0x78, 0xA0, 0x6A, 0x00, 0xF0, 0xD5, 0xF9, 0x61, 0x78, 0xE0, 0x6A, + 0x00, 0xF0, 0xD1, 0xF9, 0x01, 0x20, 0xFF, 0xF7, 0x9C, 0xFC, 0x60, 0x79, + 0x08, 0xB1, 0xFF, 0xF7, 0x18, 0xFE, 0x01, 0x2D, 0x25, 0xD0, 0x02, 0x2D, + 0x25, 0xD0, 0x26, 0x70, 0xFF, 0xF7, 0x58, 0xFA, 0xA0, 0x79, 0x60, 0xB1, + 0x20, 0x79, 0x38, 0xB1, 0xA1, 0x78, 0x20, 0x6B, 0x00, 0xF0, 0xBB, 0xF9, + 0xA1, 0x78, 0x60, 0x6B, 0x00, 0xF0, 0xB7, 0xF9, 0xE0, 0x79, 0xFF, 0xF7, + 0x8E, 0xFF, 0xFF, 0xF7, 0x47, 0xFA, 0x01, 0x2D, 0x12, 0xD0, 0x02, 0x2D, + 0x12, 0xD0, 0x10, 0x21, 0xE0, 0x69, 0x00, 0xF0, 0xD1, 0xF9, 0xE0, 0x69, + 0x78, 0xB1, 0x00, 0x20, 0x70, 0xBD, 0x03, 0x20, 0xA4, 0xE7, 0x05, 0x20, + 0xA2, 0xE7, 0x02, 0x20, 0x00, 0xE0, 0x04, 0x20, 0x20, 0x70, 0xD7, 0xE7, + 0x40, 0x21, 0xED, 0xE7, 0x4F, 0xF4, 0x00, 0x71, 0xEA, 0xE7, 0x01, 0x20, + 0x70, 0xBD, 0x70, 0xB5, 0x21, 0x4D, 0x0C, 0x46, 0x10, 0x3D, 0x02, 0x28, + 0x26, 0xD0, 0x11, 0xF0, 0xE6, 0xFF, 0x28, 0x61, 0x11, 0xF0, 0xE5, 0xFF, + 0xC5, 0xE9, 0x14, 0x01, 0x04, 0x21, 0x1B, 0x48, 0xFC, 0xF7, 0x71, 0xFB, + 0x68, 0x61, 0x19, 0x48, 0x08, 0x21, 0x40, 0x30, 0xFC, 0xF7, 0x6B, 0xFB, + 0xA8, 0x61, 0x04, 0xF1, 0x90, 0x00, 0xA8, 0x62, 0x40, 0x1C, 0xE8, 0x62, + 0x40, 0x1C, 0x28, 0x63, 0x40, 0x1C, 0x68, 0x63, 0x4B, 0x38, 0xA8, 0x63, + 0x20, 0x30, 0xC5, 0xE9, 0x0F, 0x04, 0x48, 0x38, 0x68, 0x64, 0x74, 0x30, + 0x95, 0x34, 0xC5, 0xE9, 0x12, 0x04, 0x70, 0xBD, 0x11, 0xF0, 0xC7, 0xFF, + 0x28, 0x61, 0x11, 0xF0, 0xC6, 0xFF, 0xD7, 0xE7, 0x10, 0xB5, 0x0A, 0x49, + 0x00, 0x20, 0xFF, 0xF7, 0xC8, 0xFF, 0x06, 0x48, 0x08, 0x49, 0x10, 0x38, + 0x08, 0x4A, 0x01, 0x62, 0x09, 0x1D, 0x41, 0x62, 0x13, 0x68, 0x93, 0xF8, + 0x88, 0x11, 0x11, 0xF0, 0x01, 0x04, 0x09, 0xE0, 0xD0, 0x04, 0x10, 0x00, + 0xD4, 0x56, 0x10, 0x00, 0x38, 0x99, 0x01, 0x20, 0xCC, 0x10, 0x10, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0xC4, 0x70, 0x4F, 0xF0, 0x00, 0x01, 0x04, 0xD0, + 0x83, 0x6A, 0x19, 0x70, 0xC3, 0x6A, 0x19, 0x70, 0x08, 0xE0, 0x84, 0x6A, + 0x93, 0xF8, 0x92, 0x31, 0x23, 0x70, 0x13, 0x68, 0xC4, 0x6A, 0x93, 0xF8, + 0x93, 0x31, 0x23, 0x70, 0x13, 0x68, 0x93, 0xF8, 0x88, 0x41, 0xC4, 0xF3, + 0x40, 0x04, 0x04, 0x71, 0x14, 0xB1, 0x03, 0x6B, 0x19, 0x70, 0x06, 0xE0, + 0x93, 0xF8, 0x94, 0x11, 0x03, 0x6B, 0x19, 0x70, 0x11, 0x68, 0x91, 0xF8, + 0x95, 0x11, 0x43, 0x6B, 0x19, 0x70, 0x11, 0x68, 0x91, 0xF8, 0x88, 0x21, + 0xC2, 0xF3, 0x80, 0x03, 0x43, 0x71, 0xC2, 0xF3, 0xC0, 0x02, 0x82, 0x71, + 0xB1, 0xF8, 0x8A, 0x21, 0x02, 0x81, 0xB1, 0xF8, 0x8C, 0x21, 0x42, 0x81, + 0xB1, 0xF8, 0x8E, 0x21, 0x82, 0x81, 0xB1, 0xF8, 0x90, 0x21, 0xC2, 0x81, + 0x91, 0xF8, 0x96, 0x21, 0x42, 0x70, 0x91, 0xF8, 0x97, 0x21, 0x82, 0x70, + 0x91, 0xF8, 0x34, 0x11, 0xC1, 0xF3, 0x40, 0x01, 0xC1, 0x71, 0xBD, 0xE8, + 0x10, 0x40, 0x00, 0x20, 0xF3, 0xE6, 0x10, 0xB5, 0xAC, 0x49, 0x01, 0x20, + 0xFF, 0xF7, 0x63, 0xFF, 0xAC, 0x48, 0xAB, 0x49, 0x01, 0x62, 0x00, 0x21, + 0xC0, 0xE9, 0x14, 0x11, 0x0A, 0x46, 0x81, 0x61, 0xA9, 0x49, 0x0B, 0x68, + 0x93, 0xF8, 0xA0, 0x41, 0x14, 0xF0, 0x01, 0x04, 0xC4, 0x70, 0x04, 0xD0, + 0x83, 0x6A, 0x1A, 0x70, 0xC3, 0x6A, 0x1A, 0x70, 0x08, 0xE0, 0x84, 0x6A, + 0x93, 0xF8, 0xAA, 0x31, 0x23, 0x70, 0x0B, 0x68, 0xC4, 0x6A, 0x93, 0xF8, + 0xAB, 0x31, 0x23, 0x70, 0x0B, 0x68, 0x93, 0xF8, 0xA0, 0x41, 0xC4, 0xF3, + 0x40, 0x04, 0x04, 0x71, 0x14, 0xB1, 0x03, 0x6B, 0x1A, 0x70, 0x06, 0xE0, + 0x93, 0xF8, 0xAC, 0x21, 0x03, 0x6B, 0x1A, 0x70, 0x0A, 0x68, 0x92, 0xF8, + 0xAD, 0x21, 0x43, 0x6B, 0x1A, 0x70, 0x09, 0x68, 0x91, 0xF8, 0xA0, 0x21, + 0xC2, 0xF3, 0x80, 0x03, 0x43, 0x71, 0xC2, 0xF3, 0xC0, 0x02, 0x82, 0x71, + 0xB1, 0xF8, 0xA2, 0x21, 0x02, 0x81, 0xB1, 0xF8, 0xA4, 0x21, 0x42, 0x81, + 0xB1, 0xF8, 0xA6, 0x21, 0x82, 0x81, 0xB1, 0xF8, 0xA8, 0x21, 0xC2, 0x81, + 0x91, 0xF8, 0xAE, 0x21, 0x42, 0x70, 0x91, 0xF8, 0xAF, 0x21, 0x82, 0x70, + 0x91, 0xF8, 0x84, 0x19, 0xC1, 0xF3, 0x40, 0x01, 0xC1, 0x71, 0xBD, 0xE8, + 0x10, 0x40, 0x01, 0x20, 0x99, 0xE6, 0x80, 0x49, 0x10, 0xB5, 0x98, 0x31, + 0x02, 0x20, 0xFF, 0xF7, 0x08, 0xFF, 0x7E, 0x49, 0x7E, 0x48, 0x09, 0x1D, + 0x01, 0x62, 0x7E, 0x49, 0x0B, 0x68, 0x93, 0xF8, 0xB0, 0x21, 0x12, 0xF0, + 0x01, 0x04, 0xC4, 0x70, 0x4F, 0xF0, 0x00, 0x02, 0x04, 0xD0, 0x83, 0x6A, + 0x1A, 0x70, 0xC3, 0x6A, 0x1A, 0x70, 0x08, 0xE0, 0x84, 0x6A, 0x93, 0xF8, + 0xBA, 0x31, 0x23, 0x70, 0x0B, 0x68, 0xC4, 0x6A, 0x93, 0xF8, 0xBB, 0x31, + 0x23, 0x70, 0x0C, 0x68, 0x94, 0xF8, 0xB0, 0x31, 0xC3, 0xF3, 0x40, 0x03, + 0x03, 0x71, 0x13, 0xB1, 0x03, 0x6B, 0x1A, 0x70, 0x06, 0xE0, 0x03, 0x6B, + 0x94, 0xF8, 0xBC, 0x21, 0x1A, 0x70, 0x0A, 0x68, 0x92, 0xF8, 0xBD, 0x21, + 0x43, 0x6B, 0x1A, 0x70, 0x09, 0x68, 0x91, 0xF8, 0xB0, 0x21, 0xC2, 0xF3, + 0x80, 0x03, 0x43, 0x71, 0xC2, 0xF3, 0xC0, 0x02, 0x82, 0x71, 0xB1, 0xF8, + 0xB2, 0x21, 0x02, 0x81, 0xB1, 0xF8, 0xB4, 0x21, 0x42, 0x81, 0xB1, 0xF8, + 0xB6, 0x21, 0x82, 0x81, 0xB1, 0xF8, 0xB8, 0x21, 0xC2, 0x81, 0x91, 0xF8, + 0xBE, 0x21, 0x42, 0x70, 0x91, 0xF8, 0xBF, 0x11, 0x81, 0x70, 0x01, 0x21, + 0xC1, 0x71, 0xBD, 0xE8, 0x10, 0x40, 0x02, 0x20, 0x43, 0xE6, 0x2D, 0xE9, + 0xF0, 0x41, 0x07, 0x46, 0x01, 0x24, 0x00, 0x20, 0xFB, 0xF7, 0xC9, 0xFC, + 0x02, 0x20, 0xFB, 0xF7, 0xC6, 0xFC, 0x54, 0x49, 0x01, 0x20, 0x08, 0x70, + 0x53, 0x4E, 0x78, 0x07, 0x4F, 0xF0, 0x00, 0x05, 0x4F, 0xF0, 0xA5, 0x08, + 0x0A, 0xD5, 0xFF, 0xF7, 0xD5, 0xFE, 0x10, 0xF0, 0x01, 0x04, 0x05, 0xD0, + 0x30, 0x68, 0xC5, 0x77, 0x80, 0xF8, 0x20, 0x50, 0x80, 0xF8, 0x1E, 0x80, + 0x38, 0x07, 0x0A, 0xD5, 0xFF, 0xF7, 0x2D, 0xFF, 0x20, 0x40, 0x04, 0x00, + 0x05, 0xD0, 0x30, 0x68, 0x00, 0xF8, 0x22, 0x5F, 0x45, 0x70, 0x00, 0xF8, + 0x01, 0x8C, 0x38, 0x06, 0x0A, 0xD5, 0xFF, 0xF7, 0x7A, 0xFF, 0x20, 0x40, + 0x04, 0x00, 0x05, 0xD0, 0x30, 0x68, 0x00, 0xF8, 0x27, 0x5F, 0x45, 0x70, + 0x00, 0xF8, 0x01, 0x8C, 0x02, 0x20, 0xFB, 0xF7, 0xAF, 0xFC, 0x00, 0x20, + 0xFB, 0xF7, 0xAC, 0xFC, 0x20, 0x46, 0x5A, 0xE5, 0x3A, 0x49, 0x4A, 0x78, + 0x02, 0x42, 0x07, 0xD0, 0x08, 0x78, 0xAA, 0x28, 0x04, 0xD1, 0x08, 0x78, + 0xAA, 0x28, 0xFC, 0xD0, 0xAA, 0x20, 0x08, 0x70, 0x70, 0x47, 0x02, 0x78, + 0x8A, 0x42, 0x01, 0xD9, 0x51, 0x1A, 0x00, 0xE0, 0x00, 0x21, 0x01, 0x70, + 0x70, 0x47, 0x10, 0xB5, 0x14, 0x46, 0x0F, 0xF0, 0x42, 0xFA, 0xA0, 0x42, + 0x01, 0xDC, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, 0xF0, 0xB5, + 0x00, 0x25, 0x2C, 0x46, 0x01, 0x26, 0x0C, 0xE0, 0x02, 0xEB, 0xE4, 0x07, + 0x04, 0xF0, 0x07, 0x0C, 0x3F, 0x78, 0x06, 0xFA, 0x0C, 0xFE, 0x1E, 0xEA, + 0x07, 0x0F, 0x01, 0xD0, 0x03, 0x55, 0x6D, 0x1C, 0x64, 0x1C, 0x8D, 0x42, + 0xF0, 0xDB, 0xF0, 0xBD, 0x70, 0xB5, 0x04, 0x46, 0x0D, 0x46, 0xC0, 0x07, + 0x02, 0xD0, 0x83, 0x20, 0x0D, 0xF0, 0x78, 0xFB, 0xA0, 0x07, 0x03, 0xD5, + 0x29, 0x46, 0x84, 0x20, 0x0D, 0xF0, 0x72, 0xFB, 0x60, 0x07, 0x03, 0xD5, + 0x29, 0x46, 0x85, 0x20, 0x0D, 0xF0, 0x6C, 0xFB, 0x20, 0x07, 0x03, 0xD5, + 0x29, 0x46, 0x86, 0x20, 0x0D, 0xF0, 0x66, 0xFB, 0x60, 0x06, 0x03, 0xD5, + 0x29, 0x46, 0x8B, 0x20, 0x0D, 0xF0, 0x60, 0xFB, 0x20, 0x06, 0x03, 0xD5, + 0x29, 0x46, 0x8C, 0x20, 0x0D, 0xF0, 0x5A, 0xFB, 0xE0, 0x05, 0x03, 0xD5, + 0x29, 0x46, 0x87, 0x20, 0x0D, 0xF0, 0x54, 0xFB, 0xA0, 0x05, 0x05, 0xD5, + 0x29, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x88, 0x20, 0x0D, 0xF0, 0x4C, 0xBB, + 0x70, 0xBD, 0x00, 0x00, 0xD0, 0x99, 0x01, 0x20, 0xDC, 0x10, 0x10, 0x00, + 0xC0, 0x04, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x78, 0x07, 0x10, 0x00, + 0x50, 0x07, 0x10, 0x00, 0x08, 0x00, 0x00, 0x20, 0x08, 0xB5, 0x4E, 0x4E, + 0x4E, 0x4D, 0x00, 0x24, 0x00, 0x22, 0x6B, 0x46, 0x31, 0x46, 0x10, 0x46, + 0xFB, 0xF7, 0x76, 0xFB, 0x00, 0x98, 0x81, 0x07, 0x32, 0xD5, 0xFB, 0xF7, + 0xE7, 0xF9, 0x49, 0x48, 0x07, 0x68, 0x04, 0x60, 0xFB, 0xF7, 0xE0, 0xF9, + 0x17, 0xF0, 0x53, 0x0F, 0x02, 0xD0, 0x38, 0x46, 0xFE, 0xF7, 0xB2, 0xFE, + 0x17, 0xF4, 0xD6, 0x7F, 0x02, 0xD0, 0x38, 0x46, 0xFF, 0xF7, 0x27, 0xFF, + 0xB8, 0x05, 0x13, 0xD5, 0x28, 0x68, 0x90, 0xF8, 0x70, 0x01, 0x80, 0x07, + 0x02, 0xD5, 0x01, 0x20, 0xFE, 0xF7, 0xEF, 0xFD, 0x28, 0x68, 0x90, 0xF8, + 0x88, 0x11, 0xC9, 0x06, 0x03, 0xD4, 0x90, 0xF8, 0xA0, 0x01, 0xC0, 0x06, + 0x02, 0xD5, 0x01, 0x20, 0xFF, 0xF7, 0x3B, 0xF9, 0x78, 0x05, 0x05, 0xD5, + 0x00, 0x20, 0xFE, 0xF7, 0xDE, 0xFD, 0x00, 0x20, 0xFF, 0xF7, 0x33, 0xF9, + 0x02, 0x21, 0x58, 0xE0, 0xC1, 0x05, 0x0C, 0xD5, 0xFB, 0xF7, 0xB2, 0xF9, + 0x2F, 0x48, 0x07, 0x68, 0x04, 0x60, 0xFB, 0xF7, 0xAB, 0xF9, 0x38, 0x46, + 0xFC, 0xF7, 0x9B, 0xFF, 0x4F, 0xF4, 0x80, 0x71, 0x49, 0xE0, 0x81, 0x05, + 0x04, 0xD5, 0xFE, 0xF7, 0x46, 0xF9, 0x4F, 0xF4, 0x00, 0x71, 0x42, 0xE0, + 0x41, 0x05, 0x15, 0xD5, 0xFB, 0xF7, 0x9C, 0xF9, 0x25, 0x48, 0x07, 0x68, + 0x04, 0x60, 0xFB, 0xF7, 0x95, 0xF9, 0xF8, 0x07, 0x01, 0xD0, 0xFD, 0xF7, + 0x39, 0xFD, 0xB8, 0x07, 0x01, 0xD5, 0xFD, 0xF7, 0xB5, 0xFD, 0x78, 0x07, + 0x01, 0xD5, 0xFD, 0xF7, 0x45, 0xFD, 0x4F, 0xF4, 0x80, 0x61, 0x2A, 0xE0, + 0x01, 0x06, 0x0B, 0xD5, 0xFB, 0xF7, 0x84, 0xF9, 0x1A, 0x48, 0x07, 0x68, + 0x04, 0x60, 0xFB, 0xF7, 0x7D, 0xF9, 0x38, 0x46, 0xFE, 0xF7, 0x70, 0xF8, + 0x80, 0x21, 0x1C, 0xE0, 0x81, 0x02, 0x0C, 0xD5, 0xFB, 0xF7, 0x76, 0xF9, + 0x14, 0x48, 0x07, 0x68, 0x04, 0x60, 0xFB, 0xF7, 0x6F, 0xF9, 0x38, 0x46, + 0xFD, 0xF7, 0x9C, 0xFC, 0x4F, 0xF4, 0x00, 0x11, 0x0D, 0xE0, 0xC1, 0x04, + 0x04, 0xD5, 0xFE, 0xF7, 0x31, 0xFF, 0x4F, 0xF4, 0x80, 0x51, 0x06, 0xE0, + 0x00, 0x05, 0x7F, 0xF5, 0x6F, 0xAF, 0xFE, 0xF7, 0x45, 0xFF, 0x4F, 0xF4, + 0x00, 0x61, 0x00, 0x20, 0xFB, 0xF7, 0xC7, 0xFA, 0x66, 0xE7, 0x00, 0x00, + 0x83, 0x9F, 0x30, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x58, 0x07, 0x10, 0x00, + 0x54, 0x07, 0x10, 0x00, 0x60, 0x07, 0x10, 0x00, 0x64, 0x07, 0x10, 0x00, + 0x5C, 0x07, 0x10, 0x00, 0x20, 0x48, 0x10, 0xB5, 0x01, 0x68, 0x20, 0x48, + 0x02, 0x68, 0x13, 0x46, 0x92, 0xEA, 0x01, 0x0F, 0x28, 0xD0, 0x1E, 0x4A, + 0xCC, 0x07, 0x12, 0x68, 0x25, 0xD0, 0x92, 0xF8, 0x21, 0x43, 0xE4, 0x07, + 0x02, 0xD0, 0x43, 0xF0, 0x01, 0x03, 0x03, 0x60, 0x8B, 0x07, 0x1F, 0xD5, + 0x92, 0xF8, 0x40, 0x33, 0xDB, 0x07, 0x03, 0xD0, 0x03, 0x68, 0x43, 0xF0, + 0x02, 0x03, 0x03, 0x60, 0x0B, 0x07, 0x19, 0xD5, 0x92, 0xF8, 0x60, 0x33, + 0xDB, 0x07, 0x03, 0xD0, 0x03, 0x68, 0x43, 0xF0, 0x08, 0x03, 0x03, 0x60, + 0x49, 0x06, 0x13, 0xD5, 0x92, 0xF8, 0x60, 0x13, 0xC9, 0x07, 0x03, 0xD0, + 0x01, 0x68, 0x41, 0xF0, 0x40, 0x01, 0x01, 0x60, 0x10, 0xBD, 0x23, 0xF0, + 0x01, 0x03, 0xDC, 0xE7, 0x03, 0x68, 0x23, 0xF0, 0x02, 0x03, 0xE2, 0xE7, + 0x03, 0x68, 0x23, 0xF0, 0x08, 0x03, 0xE8, 0xE7, 0x01, 0x68, 0x21, 0xF0, + 0x40, 0x01, 0xEE, 0xE7, 0x70, 0x07, 0x10, 0x00, 0x48, 0x05, 0x10, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0xDF, 0xF8, 0x60, 0x92, + 0x98, 0x4C, 0x00, 0x25, 0xD9, 0xF8, 0x00, 0x10, 0x91, 0xF8, 0x31, 0x00, + 0x84, 0xF8, 0x30, 0x00, 0x91, 0xF8, 0x30, 0x20, 0x94, 0x49, 0x84, 0xF8, + 0x31, 0x20, 0x50, 0x43, 0x09, 0x78, 0x84, 0xF8, 0x33, 0x10, 0x92, 0x49, + 0x21, 0x60, 0x34, 0x39, 0x06, 0xB2, 0x8B, 0x7B, 0x84, 0xF8, 0x2D, 0x30, + 0x88, 0x46, 0x77, 0x00, 0x0F, 0xE0, 0x2A, 0x46, 0x31, 0x46, 0xD8, 0xF8, + 0x08, 0x00, 0x0E, 0xF0, 0x32, 0xF9, 0x01, 0x46, 0x22, 0x68, 0x06, 0xFB, + 0x05, 0xF0, 0x02, 0xEB, 0x40, 0x00, 0x3A, 0x46, 0x12, 0xF0, 0x09, 0xF8, + 0x6D, 0x1C, 0x94, 0xF8, 0x2D, 0x00, 0xA8, 0x42, 0xEB, 0xDC, 0x84, 0x48, + 0x84, 0x49, 0x00, 0x78, 0x09, 0x78, 0x08, 0x43, 0x40, 0x07, 0x11, 0xD5, + 0x82, 0x48, 0x60, 0x60, 0xD9, 0xF8, 0x00, 0x10, 0x91, 0xF8, 0xF1, 0x11, + 0x89, 0x07, 0x4A, 0x0F, 0x94, 0xF8, 0x31, 0x10, 0x92, 0x1C, 0x4A, 0x43, + 0xD8, 0xF8, 0x10, 0x10, 0xBD, 0xE8, 0xF0, 0x47, 0x11, 0xF0, 0xEB, 0xBF, + 0xBD, 0xE8, 0xF0, 0x87, 0x2D, 0xE9, 0xF8, 0x43, 0x75, 0x48, 0xDF, 0xF8, + 0xD8, 0x81, 0x00, 0x27, 0x05, 0x68, 0xD8, 0xF8, 0x00, 0x00, 0x05, 0x43, + 0x01, 0x20, 0xFB, 0xF7, 0xC8, 0xFA, 0x38, 0x21, 0x6C, 0x48, 0x12, 0xF0, + 0x79, 0xF8, 0xE8, 0x07, 0x06, 0xD0, 0xFF, 0xF7, 0x9D, 0xFF, 0xE8, 0x06, + 0x01, 0xD5, 0x00, 0xF0, 0x9B, 0xF8, 0x01, 0x27, 0x68, 0x4E, 0x66, 0x4C, + 0xA8, 0x07, 0xA6, 0xF1, 0x34, 0x06, 0x0A, 0xD5, 0x69, 0x48, 0xA0, 0x60, + 0x68, 0x49, 0x70, 0x69, 0x89, 0x1E, 0x01, 0x27, 0x02, 0x68, 0x41, 0xF8, + 0x02, 0x2F, 0x40, 0x68, 0x48, 0x60, 0xA8, 0x05, 0x11, 0xD5, 0x62, 0x4F, + 0xCA, 0x3F, 0xA7, 0x61, 0x11, 0xF0, 0x81, 0xFC, 0x00, 0x90, 0x04, 0x21, + 0x68, 0x46, 0xFC, 0xF7, 0x08, 0xF8, 0x84, 0xF8, 0x32, 0x00, 0xF0, 0x6A, + 0x01, 0x68, 0x39, 0x60, 0x40, 0x68, 0x78, 0x60, 0x01, 0x27, 0x5B, 0x48, + 0x00, 0x68, 0xC4, 0xE9, 0x07, 0x05, 0xD8, 0xF8, 0x00, 0x00, 0x60, 0x62, + 0x70, 0x68, 0xA0, 0x62, 0xF0, 0x7B, 0x84, 0xF8, 0x35, 0x00, 0x96, 0xF8, + 0x30, 0x00, 0x55, 0x4E, 0x84, 0xF8, 0x36, 0x00, 0x30, 0x78, 0x84, 0xF8, + 0x2C, 0x00, 0xE8, 0x07, 0x1A, 0xD0, 0xE8, 0x06, 0x18, 0xD5, 0x47, 0x4D, + 0x28, 0x68, 0x90, 0xF8, 0x50, 0x02, 0xC0, 0x07, 0x06, 0xD0, 0x00, 0xF0, + 0xF4, 0xFD, 0x18, 0xB9, 0xE0, 0x69, 0x40, 0xF0, 0x10, 0x00, 0xE0, 0x61, + 0x28, 0x68, 0x90, 0xF8, 0x80, 0x02, 0xC0, 0x07, 0x06, 0xD0, 0x00, 0xF0, + 0xE8, 0xFD, 0x18, 0xB9, 0xE0, 0x69, 0x40, 0xF0, 0x20, 0x00, 0xE0, 0x61, + 0x01, 0x20, 0xFB, 0xF7, 0x7D, 0xFA, 0x00, 0x2F, 0x0C, 0xD0, 0x30, 0x78, + 0x05, 0x28, 0x07, 0xD0, 0x06, 0x28, 0x05, 0xD0, 0x01, 0x21, 0xBD, 0xE8, + 0xF8, 0x43, 0x02, 0x20, 0xFB, 0xF7, 0x75, 0xB9, 0x02, 0x21, 0xF8, 0xE7, + 0xBD, 0xE8, 0xF8, 0x83, 0x3A, 0x48, 0x10, 0xB5, 0x00, 0x78, 0x00, 0x28, + 0x29, 0xD1, 0x31, 0x4C, 0x34, 0x3C, 0xD4, 0xE9, 0x06, 0x01, 0x00, 0xF0, + 0xC7, 0xFD, 0x94, 0xF8, 0x31, 0x10, 0xA0, 0x6A, 0x00, 0xF0, 0xC3, 0xFC, + 0xFF, 0xF7, 0x6A, 0xFF, 0x27, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x60, 0x03, + 0xC1, 0x07, 0x16, 0xD0, 0x81, 0x07, 0x14, 0xD5, 0x00, 0x24, 0x40, 0x09, + 0x12, 0xF0, 0x6C, 0xF8, 0x00, 0xB1, 0x01, 0x24, 0x27, 0x48, 0x80, 0x1E, + 0x01, 0x78, 0x8C, 0x42, 0x09, 0xD0, 0x04, 0x70, 0x0C, 0xB1, 0x08, 0x21, + 0x00, 0xE0, 0x10, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0x03, 0x20, 0xFB, 0xF7, + 0x42, 0xB9, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x17, 0x48, 0x1A, 0x4E, + 0x17, 0x4C, 0x00, 0x68, 0x34, 0x3E, 0x90, 0xF8, 0x31, 0x50, 0x90, 0xF8, + 0x30, 0x70, 0xB1, 0x69, 0x39, 0xB1, 0x18, 0x48, 0x84, 0xF8, 0x30, 0x50, + 0xC2, 0x38, 0x6A, 0x00, 0x20, 0x61, 0x11, 0xF0, 0x20, 0xFF, 0xF1, 0x69, + 0x39, 0xB1, 0x13, 0x48, 0x84, 0xF8, 0x31, 0x70, 0x98, 0x38, 0x7A, 0x00, + 0x60, 0x61, 0x11, 0xF0, 0x16, 0xFF, 0x0D, 0x48, 0x0D, 0x49, 0x00, 0x78, + 0x09, 0x78, 0x08, 0x43, 0x80, 0x06, 0x08, 0xD5, 0x0B, 0x48, 0x4C, 0x38, + 0xE0, 0x60, 0x6A, 0x00, 0x71, 0x6A, 0xBD, 0xE8, 0xF0, 0x41, 0x11, 0xF0, + 0x06, 0xBF, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0xCC, 0x68, 0x10, 0x00, 0x54, 0x05, 0x10, 0x00, 0x1C, 0x11, 0x10, 0x00, + 0x4C, 0x05, 0x10, 0x00, 0x50, 0x05, 0x10, 0x00, 0xCC, 0x07, 0x01, 0x20, + 0x1A, 0x05, 0x10, 0x00, 0x48, 0x05, 0x10, 0x00, 0x40, 0x05, 0x10, 0x00, + 0x41, 0x05, 0x10, 0x00, 0x10, 0xB5, 0x00, 0x24, 0xC1, 0x07, 0x0B, 0xD0, + 0x3F, 0x49, 0x03, 0x24, 0x09, 0x68, 0x91, 0xF8, 0x50, 0x22, 0xD2, 0x07, + 0x03, 0xD1, 0x91, 0xF8, 0x80, 0x12, 0xC9, 0x07, 0x00, 0xD0, 0x0B, 0x24, + 0x82, 0x07, 0x4F, 0xF0, 0x01, 0x01, 0x03, 0xD5, 0x38, 0x4A, 0x44, 0xF0, + 0x10, 0x04, 0x11, 0x70, 0x40, 0x06, 0x03, 0xD5, 0x36, 0x48, 0x44, 0xF0, + 0x80, 0x04, 0x01, 0x70, 0x00, 0x2C, 0x12, 0xD0, 0xFA, 0xF7, 0x96, 0xFF, + 0x33, 0x48, 0x01, 0x68, 0x21, 0x43, 0x01, 0x60, 0xFA, 0xF7, 0x8E, 0xFF, + 0x01, 0x21, 0x05, 0x20, 0x0D, 0xF0, 0xCF, 0xFA, 0xBD, 0xE8, 0x10, 0x40, + 0x4F, 0xF4, 0x80, 0x71, 0x00, 0x20, 0xFB, 0xF7, 0xC6, 0xB8, 0x10, 0xBD, + 0x10, 0xB5, 0x00, 0xF0, 0xDE, 0xFD, 0x02, 0x21, 0x01, 0x20, 0xFB, 0xF7, + 0xEA, 0xF8, 0x01, 0x20, 0xFB, 0xF7, 0x9B, 0xF9, 0x38, 0x21, 0x26, 0x48, + 0x11, 0xF0, 0x4C, 0xFF, 0x24, 0x49, 0x01, 0x20, 0x81, 0xF8, 0x2C, 0x00, + 0xFB, 0xF7, 0xAC, 0xF9, 0x01, 0x21, 0x02, 0x20, 0xFB, 0xF7, 0xAD, 0xF8, + 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x2D, 0xBB, 0x70, 0xB5, 0x1E, 0x48, + 0x1E, 0x4E, 0x05, 0x68, 0x30, 0x68, 0x90, 0xEA, 0x05, 0x04, 0x1F, 0xD0, + 0x35, 0xB1, 0x40, 0xB1, 0x04, 0xEA, 0x05, 0x00, 0xFF, 0xF7, 0xA2, 0xFF, + 0x35, 0x60, 0x70, 0xBD, 0xFF, 0xF7, 0xD2, 0xFF, 0xFA, 0xE7, 0x00, 0xF0, + 0xB0, 0xFD, 0x02, 0x21, 0x01, 0x20, 0xFB, 0xF7, 0xBC, 0xF8, 0x00, 0xF0, + 0xD8, 0xF8, 0x00, 0xF0, 0x08, 0xFB, 0x04, 0xEA, 0x05, 0x00, 0xFF, 0xF7, + 0x8F, 0xFF, 0x00, 0xF0, 0xF1, 0xFA, 0x02, 0x21, 0x01, 0x20, 0xFB, 0xF7, + 0x82, 0xF8, 0xE5, 0xE7, 0x00, 0x2D, 0xE4, 0xD1, 0x0B, 0x48, 0x00, 0x78, + 0x05, 0x28, 0x01, 0xD0, 0x06, 0x28, 0xDE, 0xD1, 0x35, 0x60, 0xBD, 0xE8, + 0x70, 0x40, 0xAF, 0xE7, 0x4C, 0x07, 0x10, 0x00, 0x7B, 0x07, 0x10, 0x00, + 0x7C, 0x07, 0x10, 0x00, 0x54, 0x07, 0x10, 0x00, 0xCC, 0x68, 0x10, 0x00, + 0x6C, 0x07, 0x10, 0x00, 0x44, 0x05, 0x10, 0x00, 0x40, 0x05, 0x10, 0x00, + 0x70, 0xB5, 0xFF, 0x49, 0x00, 0x20, 0x03, 0x46, 0x09, 0x68, 0x91, 0xF8, + 0x40, 0x20, 0xD2, 0x07, 0x38, 0xD0, 0xFC, 0x4A, 0x15, 0x78, 0x02, 0x2D, + 0x16, 0xD0, 0x04, 0x2D, 0x03, 0xD0, 0x05, 0x2D, 0x0F, 0xD0, 0x06, 0x2D, + 0x0D, 0xD0, 0x91, 0xF8, 0x41, 0x20, 0xF7, 0x49, 0x0C, 0x68, 0x64, 0x1C, + 0x0C, 0x60, 0x94, 0x42, 0x26, 0xDD, 0xF5, 0x4A, 0x00, 0x20, 0x14, 0x78, + 0x64, 0xB1, 0x08, 0x60, 0x0C, 0xE0, 0x91, 0xF8, 0x43, 0x20, 0xF0, 0xE7, + 0x91, 0xF8, 0x42, 0x20, 0x91, 0xF8, 0x90, 0x10, 0xC9, 0x06, 0xEA, 0xD5, + 0x01, 0x23, 0xE8, 0xE7, 0x13, 0xB1, 0x01, 0x20, 0x10, 0x70, 0x00, 0xE0, + 0x08, 0x60, 0x05, 0x2D, 0x0F, 0xD0, 0x00, 0xF0, 0x11, 0xF9, 0x04, 0x46, + 0x00, 0xF0, 0x14, 0xF9, 0x04, 0x43, 0x00, 0xF0, 0x1F, 0xF9, 0x04, 0x43, + 0x00, 0xF0, 0x2B, 0xF9, 0x04, 0x43, 0x00, 0xF0, 0x35, 0xF9, 0x20, 0x43, + 0x70, 0xBD, 0x01, 0x20, 0x70, 0xBD, 0x10, 0xB5, 0x01, 0x46, 0x34, 0x22, + 0xDF, 0x48, 0x11, 0xF0, 0x53, 0xFE, 0x01, 0x21, 0xBD, 0xE8, 0x10, 0x40, + 0x08, 0x46, 0xFB, 0xF7, 0x14, 0xB8, 0x2D, 0xE9, 0xFF, 0x41, 0x80, 0x46, + 0xD6, 0x48, 0x00, 0x78, 0x02, 0x28, 0x24, 0xD0, 0x03, 0x28, 0x1E, 0xD0, + 0x04, 0x24, 0xD7, 0x4D, 0xD7, 0x4E, 0x01, 0x27, 0x05, 0x28, 0x20, 0xD0, + 0x06, 0x28, 0x68, 0x46, 0x30, 0xD0, 0x00, 0xF0, 0xB5, 0xF9, 0xD4, 0x48, + 0x00, 0x90, 0xCC, 0x48, 0x00, 0x68, 0x90, 0xF8, 0xB0, 0x00, 0xC0, 0x07, + 0x01, 0xD0, 0x8D, 0xF8, 0x0D, 0x80, 0x68, 0x46, 0x11, 0xF0, 0x71, 0xFA, + 0xCE, 0x49, 0xCF, 0x4A, 0xC9, 0x78, 0x11, 0x70, 0x04, 0xB0, 0xBD, 0xE8, + 0xF0, 0x81, 0x68, 0x46, 0x00, 0xF0, 0x4A, 0xF9, 0xE7, 0xE7, 0x68, 0x46, + 0x00, 0xF0, 0x05, 0xF9, 0xE3, 0xE7, 0x68, 0x46, 0x11, 0xF0, 0x3A, 0xFA, + 0xFF, 0xF7, 0x7A, 0xFF, 0x40, 0x21, 0xC2, 0x07, 0x01, 0xD0, 0x8D, 0xF8, + 0x04, 0x40, 0xC2, 0x06, 0x01, 0xD5, 0x8D, 0xF8, 0x06, 0x70, 0x8D, 0xF8, + 0x08, 0x70, 0x28, 0x60, 0x31, 0x60, 0xD0, 0xE7, 0x00, 0x27, 0x11, 0xF0, + 0x27, 0xFA, 0x8D, 0xF8, 0x04, 0x40, 0x01, 0x20, 0x2F, 0x60, 0x30, 0x60, + 0xC7, 0xE7, 0x10, 0xB5, 0x00, 0xF0, 0xE1, 0xFC, 0x02, 0x21, 0xBD, 0xE8, + 0x10, 0x40, 0x01, 0x20, 0xFA, 0xF7, 0xBF, 0xBF, 0x10, 0xB5, 0x00, 0xF0, + 0xDD, 0xFC, 0x20, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0x20, 0xFA, 0xF7, + 0xB6, 0xBF, 0xAA, 0x49, 0x00, 0x20, 0x08, 0x60, 0x70, 0x47, 0xA8, 0x49, + 0x00, 0x20, 0x08, 0x60, 0x70, 0x47, 0xF8, 0xB5, 0x00, 0x24, 0x20, 0x46, + 0xFB, 0xF7, 0x89, 0xF8, 0x00, 0xF0, 0x32, 0xFA, 0xA1, 0x4E, 0x30, 0x78, + 0x00, 0xF0, 0x93, 0xF9, 0xAF, 0xF2, 0x4D, 0x01, 0x00, 0xF0, 0xB3, 0xFC, + 0x9C, 0x4F, 0xA6, 0x4D, 0x38, 0x68, 0x90, 0xF8, 0xB0, 0x00, 0xC1, 0x07, + 0x09, 0xD0, 0x01, 0x24, 0xC0, 0xF3, 0xC1, 0x01, 0x02, 0x29, 0x00, 0xD1, + 0x00, 0x24, 0x80, 0x07, 0x01, 0xD5, 0x00, 0x20, 0x28, 0x70, 0x20, 0x46, + 0xFF, 0xF7, 0x77, 0xFF, 0x96, 0x4C, 0x01, 0x28, 0x0D, 0xD1, 0x01, 0x21, + 0x6B, 0x46, 0x00, 0x22, 0x08, 0x46, 0xFA, 0xF7, 0xCB, 0xFF, 0x01, 0x21, + 0x08, 0x46, 0xFA, 0xF7, 0xAA, 0xFF, 0x20, 0x78, 0x90, 0xB1, 0x0C, 0xF0, + 0x8E, 0xFF, 0x00, 0x20, 0xFB, 0xF7, 0x72, 0xF8, 0x38, 0x68, 0x90, 0xF8, + 0xB0, 0x10, 0xCA, 0x07, 0x51, 0xD0, 0x89, 0x07, 0x4F, 0xD5, 0x8D, 0x49, + 0x49, 0x78, 0x00, 0x29, 0x4B, 0xD1, 0x29, 0x78, 0x19, 0xB1, 0x28, 0xE0, + 0xFF, 0xF7, 0xF6, 0xFD, 0xEB, 0xE7, 0x32, 0x78, 0x8A, 0x49, 0x02, 0x2A, + 0x02, 0xD1, 0x83, 0x4A, 0x12, 0x68, 0x2A, 0xB1, 0x09, 0x78, 0x49, 0x06, + 0x0B, 0xD5, 0x90, 0xF8, 0xC1, 0x00, 0x0A, 0xE0, 0x09, 0x78, 0x49, 0x06, + 0x02, 0xD5, 0x90, 0xF8, 0xC2, 0x00, 0x04, 0xE0, 0x90, 0xF8, 0xBC, 0x00, + 0x01, 0xE0, 0x90, 0xF8, 0xBB, 0x00, 0xAF, 0xF2, 0xE3, 0x01, 0x00, 0xF0, + 0x68, 0xFC, 0x6B, 0x46, 0x00, 0x22, 0x20, 0x21, 0x01, 0x20, 0xFA, 0xF7, + 0x8D, 0xFF, 0x20, 0x21, 0x01, 0x20, 0xFA, 0xF7, 0x6C, 0xFF, 0x28, 0x78, + 0x00, 0x28, 0x1C, 0xD1, 0xFB, 0xF7, 0x1B, 0xF8, 0x00, 0x20, 0xFF, 0xF7, + 0x24, 0xFF, 0x01, 0x28, 0x0D, 0xD1, 0x01, 0x21, 0x6B, 0x46, 0x00, 0x22, + 0x08, 0x46, 0xFA, 0xF7, 0x79, 0xFF, 0x01, 0x21, 0x08, 0x46, 0xFA, 0xF7, + 0x58, 0xFF, 0x20, 0x78, 0x30, 0xB1, 0x0C, 0xF0, 0x3C, 0xFF, 0xBD, 0xE8, + 0xF8, 0x40, 0x00, 0x20, 0xFB, 0xF7, 0x1E, 0xB8, 0xFF, 0xF7, 0xB0, 0xFD, + 0xF7, 0xE7, 0xF8, 0xBD, 0x67, 0x48, 0x00, 0x78, 0xC0, 0x07, 0x00, 0xD0, + 0x01, 0x20, 0x70, 0x47, 0x64, 0x48, 0x00, 0x78, 0xC0, 0x07, 0x07, 0xD0, + 0x57, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x50, 0x02, 0xC0, 0x07, 0x01, 0xD0, + 0x10, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x5D, 0x48, 0x00, 0x78, + 0xC1, 0x07, 0x51, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x80, 0x02, 0x03, 0xD0, + 0xC1, 0x07, 0x01, 0xD0, 0x10, 0x20, 0x70, 0x47, 0x00, 0xF0, 0x01, 0x00, + 0x70, 0x47, 0x56, 0x48, 0x00, 0x78, 0x80, 0x07, 0x06, 0xD5, 0x49, 0x48, + 0x00, 0x68, 0x90, 0xF8, 0x61, 0x04, 0x08, 0xB1, 0x02, 0x20, 0x70, 0x47, + 0x00, 0x20, 0x70, 0x47, 0x4F, 0x48, 0x00, 0x78, 0x40, 0x06, 0x08, 0xD5, + 0x42, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x2F, 0x0A, 0xC0, 0x07, 0x02, 0xD0, + 0x4F, 0xF4, 0x00, 0x70, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x2D, 0xE9, + 0xF0, 0x41, 0x06, 0x46, 0x00, 0x27, 0x11, 0xF0, 0x33, 0xF9, 0xFF, 0xF7, + 0x73, 0xFE, 0x05, 0x46, 0x43, 0x48, 0x00, 0x78, 0xC0, 0x07, 0x00, 0xD0, + 0x40, 0x27, 0xFF, 0xF7, 0xD4, 0xFF, 0x40, 0xEA, 0x07, 0x04, 0x6D, 0xB1, + 0x33, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x90, 0x00, 0x00, 0x07, 0x07, 0xD5, + 0x00, 0xF0, 0xE4, 0xF8, 0x40, 0xEA, 0x04, 0x07, 0x00, 0xF0, 0xEE, 0xF8, + 0x40, 0xEA, 0x07, 0x04, 0x45, 0xEA, 0x04, 0x07, 0xF8, 0x07, 0x02, 0xD0, + 0x00, 0xF0, 0xF4, 0xF8, 0x30, 0x71, 0x61, 0x07, 0x4F, 0xF0, 0x01, 0x00, + 0x00, 0xD5, 0x70, 0x71, 0xE9, 0x06, 0x00, 0xD5, 0xB0, 0x71, 0x61, 0x06, + 0x00, 0xD5, 0x30, 0x72, 0xA1, 0x06, 0x00, 0xD5, 0xF0, 0x71, 0xB9, 0x07, + 0x00, 0xD5, 0x70, 0x72, 0xA9, 0x05, 0x00, 0xD5, 0xB0, 0x72, 0x24, 0x48, + 0x05, 0x60, 0x24, 0x48, 0x04, 0x60, 0xB0, 0xE6, 0x2D, 0xE9, 0xF0, 0x41, + 0x05, 0x46, 0x11, 0xF0, 0xF3, 0xF8, 0xFF, 0xF7, 0x33, 0xFE, 0x07, 0x46, + 0xFF, 0xF7, 0x76, 0xFF, 0x04, 0x46, 0xFF, 0xF7, 0x79, 0xFF, 0x04, 0x43, + 0xFF, 0xF7, 0x84, 0xFF, 0x04, 0x43, 0x00, 0xF0, 0xAB, 0xF8, 0x04, 0x43, + 0xFF, 0xF7, 0x8D, 0xFF, 0x04, 0x43, 0xFF, 0xF7, 0x97, 0xFF, 0x04, 0x43, + 0x00, 0xF0, 0xB0, 0xF8, 0x40, 0xEA, 0x04, 0x06, 0x47, 0xEA, 0x06, 0x04, + 0xE0, 0x07, 0x02, 0xD0, 0x00, 0xF0, 0xB6, 0xF8, 0x28, 0x71, 0x71, 0x07, + 0x4F, 0xF0, 0x01, 0x00, 0x00, 0xD5, 0x68, 0x71, 0xE1, 0x06, 0x00, 0xD5, + 0xA8, 0x71, 0xB1, 0x06, 0x00, 0xD5, 0xE8, 0x71, 0xA1, 0x07, 0x00, 0xD5, + 0x68, 0x72, 0xA1, 0x05, 0x00, 0xD5, 0xA8, 0x72, 0x06, 0x48, 0x07, 0x60, + 0x06, 0x48, 0x17, 0xE0, 0x4C, 0x07, 0x10, 0x00, 0x40, 0x05, 0x10, 0x00, + 0x24, 0x05, 0x10, 0x00, 0x41, 0x05, 0x10, 0x00, 0xE8, 0x10, 0x10, 0x00, + 0x50, 0x05, 0x10, 0x00, 0x4C, 0x05, 0x10, 0x00, 0xE3, 0x54, 0x00, 0x00, + 0x74, 0x07, 0x10, 0x00, 0x54, 0x05, 0x10, 0x00, 0x78, 0x07, 0x10, 0x00, + 0x44, 0x05, 0x10, 0x00, 0x06, 0x60, 0x5C, 0xE6, 0x2D, 0xE9, 0xF0, 0x41, + 0x05, 0x46, 0x11, 0xF0, 0x9F, 0xF8, 0xFF, 0xF7, 0xDF, 0xFD, 0x06, 0x46, + 0xFF, 0xF7, 0x22, 0xFF, 0x04, 0x46, 0xFF, 0xF7, 0x25, 0xFF, 0x04, 0x43, + 0xFF, 0xF7, 0x30, 0xFF, 0x04, 0x43, 0x00, 0xF0, 0x57, 0xF8, 0x04, 0x43, + 0xFF, 0xF7, 0x39, 0xFF, 0x04, 0x43, 0xFF, 0xF7, 0x43, 0xFF, 0x04, 0x43, + 0x00, 0xF0, 0x5C, 0xF8, 0x40, 0xEA, 0x04, 0x07, 0x46, 0xEA, 0x07, 0x04, + 0xE0, 0x07, 0x02, 0xD0, 0x00, 0xF0, 0x62, 0xF8, 0x28, 0x71, 0x61, 0x07, + 0x4F, 0xF0, 0x01, 0x00, 0x00, 0xD5, 0x68, 0x71, 0xE1, 0x06, 0x00, 0xD5, + 0xA8, 0x71, 0xB9, 0x06, 0x00, 0xD5, 0xE8, 0x71, 0xA1, 0x07, 0x00, 0xD5, + 0x68, 0x72, 0xA1, 0x05, 0x00, 0xD5, 0xA8, 0x72, 0x2E, 0x48, 0x06, 0x60, + 0x2E, 0x48, 0x07, 0x60, 0x21, 0xE6, 0x38, 0xB5, 0x2D, 0x49, 0x80, 0x1E, + 0x05, 0x28, 0x09, 0x68, 0x13, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x03, 0x06, + 0x09, 0x0C, 0x0F, 0x00, 0x91, 0xF8, 0x73, 0x40, 0x0C, 0xE0, 0x91, 0xF8, + 0x72, 0x40, 0x09, 0xE0, 0x91, 0xF8, 0x71, 0x40, 0x06, 0xE0, 0x91, 0xF8, + 0x74, 0x40, 0x03, 0xE0, 0x91, 0xF8, 0x75, 0x40, 0x00, 0xE0, 0x01, 0x24, + 0x00, 0x25, 0x0C, 0xF0, 0x53, 0xFA, 0x00, 0xB1, 0x01, 0x25, 0x69, 0x46, + 0x03, 0x20, 0xFA, 0xF7, 0x26, 0xFE, 0x00, 0x98, 0x00, 0xB9, 0x1D, 0xB1, + 0x14, 0x2C, 0x01, 0xD2, 0x14, 0x24, 0x01, 0xE0, 0x04, 0xB9, 0x01, 0x24, + 0x20, 0x46, 0x38, 0xBD, 0x17, 0x48, 0x00, 0x78, 0xC0, 0x07, 0x07, 0xD0, + 0x14, 0x48, 0x00, 0x68, 0x90, 0xF8, 0xF0, 0x01, 0xC0, 0x07, 0x01, 0xD0, + 0x04, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x10, 0x48, 0x00, 0x78, + 0xC0, 0x07, 0x07, 0xD0, 0x0D, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x10, 0x02, + 0xC0, 0x07, 0x01, 0xD0, 0x20, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, + 0x08, 0x49, 0x01, 0x20, 0x09, 0x68, 0x91, 0xF8, 0xE7, 0x10, 0x09, 0x06, + 0x03, 0xD5, 0x07, 0x48, 0x40, 0x78, 0x08, 0xB1, 0x03, 0x20, 0x70, 0x47, + 0x02, 0x20, 0x70, 0x47, 0x50, 0x05, 0x10, 0x00, 0x4C, 0x05, 0x10, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x44, 0x05, 0x10, 0x00, 0x74, 0x07, 0x10, 0x00, + 0x10, 0xB5, 0x00, 0xF0, 0x8B, 0xF9, 0x00, 0xF0, 0x00, 0xFA, 0x5B, 0x49, + 0x00, 0x20, 0x48, 0x60, 0x5A, 0x49, 0x02, 0x20, 0x08, 0x70, 0x10, 0xBD, + 0x10, 0xB5, 0x00, 0xF0, 0x7F, 0xF9, 0x00, 0xF0, 0xF4, 0xF9, 0x55, 0x49, + 0x00, 0x20, 0x48, 0x60, 0x54, 0x49, 0x03, 0x20, 0x08, 0x70, 0x10, 0xBD, + 0x10, 0xB5, 0x00, 0xF0, 0x73, 0xF9, 0x00, 0xF0, 0xE8, 0xF9, 0x4F, 0x49, + 0x00, 0x20, 0x48, 0x60, 0x4E, 0x49, 0x04, 0x20, 0x08, 0x70, 0x4E, 0x49, + 0x01, 0x20, 0x08, 0x70, 0x4D, 0x49, 0x08, 0x70, 0x10, 0xBD, 0x49, 0x49, + 0x00, 0x20, 0x48, 0x60, 0x70, 0x47, 0x47, 0x49, 0x00, 0x20, 0x48, 0x60, + 0x70, 0x47, 0x45, 0x49, 0x00, 0x20, 0x48, 0x60, 0x44, 0x49, 0x01, 0x20, + 0x08, 0x70, 0x70, 0x47, 0x70, 0xB5, 0x42, 0x4D, 0x00, 0x26, 0x40, 0x4C, + 0x28, 0x78, 0x80, 0x1E, 0x04, 0x28, 0x10, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, + 0x30, 0x1F, 0x02, 0x3E, 0x00, 0xF0, 0x45, 0xF8, 0x01, 0x28, 0x07, 0xD0, + 0x60, 0x68, 0x40, 0x1C, 0x60, 0x60, 0x00, 0xF0, 0x46, 0xF8, 0x01, 0x28, + 0x02, 0xD0, 0x0B, 0xE0, 0x66, 0x60, 0x70, 0xBD, 0x38, 0x48, 0x61, 0x68, + 0x00, 0x68, 0x90, 0xF8, 0x77, 0x00, 0x88, 0x42, 0x02, 0xD2, 0xBD, 0xE8, + 0x70, 0x40, 0xAF, 0xE7, 0x00, 0xF0, 0x47, 0xF8, 0x01, 0x28, 0x0E, 0xD0, + 0x70, 0xBD, 0x00, 0xF0, 0x28, 0xF8, 0x01, 0x28, 0x17, 0xD0, 0x60, 0x68, + 0x40, 0x1C, 0x60, 0x60, 0x00, 0xF0, 0x3B, 0xF8, 0x01, 0x28, 0x02, 0xD0, + 0x00, 0xF0, 0x25, 0xF8, 0x0B, 0xE0, 0xBD, 0xE8, 0x70, 0x40, 0x8D, 0xE7, + 0x00, 0xF0, 0x17, 0xF8, 0x01, 0x28, 0x06, 0xD0, 0x60, 0x68, 0x40, 0x1C, + 0x60, 0x60, 0x00, 0xF0, 0x22, 0xF8, 0x01, 0x28, 0xE2, 0xD0, 0xBD, 0xE8, + 0x70, 0x40, 0x97, 0xE7, 0x00, 0xF0, 0x09, 0xF9, 0x08, 0xB1, 0x21, 0x78, + 0x09, 0xB1, 0x20, 0x70, 0x70, 0xBD, 0x20, 0x70, 0x06, 0x20, 0x28, 0x70, + 0x70, 0xBD, 0x10, 0xB5, 0x00, 0xF0, 0xFD, 0xF8, 0x04, 0x46, 0x0B, 0xF0, + 0x43, 0xFD, 0x20, 0x43, 0x10, 0xBD, 0x18, 0x48, 0x00, 0x68, 0x90, 0xF8, + 0x70, 0x00, 0x80, 0x07, 0x01, 0xD5, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, + 0x70, 0x47, 0x13, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x70, 0x00, 0xC0, 0x07, + 0x00, 0xD0, 0x01, 0x20, 0x70, 0x47, 0x10, 0xB5, 0xFF, 0xF7, 0xF5, 0xFF, + 0x01, 0x28, 0x0F, 0xD1, 0x00, 0xF0, 0x5F, 0xF9, 0x60, 0xB9, 0x0B, 0x48, + 0x06, 0x49, 0x00, 0x68, 0x49, 0x68, 0x90, 0xF8, 0x78, 0x00, 0x00, 0xEB, + 0x80, 0x00, 0xB1, 0xEB, 0x40, 0x0F, 0x01, 0xD9, 0x01, 0x20, 0x10, 0xBD, + 0x00, 0x20, 0x10, 0xBD, 0x28, 0x05, 0x10, 0x00, 0x40, 0x05, 0x10, 0x00, + 0x79, 0x07, 0x10, 0x00, 0x7A, 0x07, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x2D, 0xE9, 0xF0, 0x41, 0x8E, 0x4C, 0x07, 0x46, 0x0E, 0x46, 0x20, 0x68, + 0x00, 0x25, 0x90, 0xF8, 0x98, 0x20, 0x8C, 0x48, 0x0E, 0xF0, 0xBD, 0xFA, + 0x02, 0x00, 0x8B, 0x48, 0x29, 0x46, 0x34, 0xD0, 0x02, 0x78, 0x01, 0x25, + 0x52, 0x1C, 0xD2, 0xB2, 0x02, 0x70, 0x23, 0x68, 0x93, 0xF8, 0x99, 0x30, + 0x93, 0x42, 0x2B, 0xD2, 0x01, 0x70, 0x83, 0x48, 0x76, 0x00, 0x32, 0x46, + 0x39, 0x46, 0x54, 0x38, 0x11, 0xF0, 0xB9, 0xFA, 0x7F, 0x48, 0x32, 0x46, + 0x39, 0x46, 0x2A, 0x38, 0x11, 0xF0, 0xB3, 0xFA, 0x20, 0x68, 0x03, 0x26, + 0x90, 0xF8, 0x50, 0x12, 0xC9, 0x07, 0x03, 0xD1, 0x90, 0xF8, 0x80, 0x02, + 0xC0, 0x07, 0x00, 0xD0, 0x0B, 0x26, 0xFA, 0xF7, 0x71, 0xFB, 0x78, 0x48, + 0x01, 0x68, 0x31, 0x43, 0x01, 0x60, 0xFA, 0xF7, 0x69, 0xFB, 0x20, 0x21, + 0x05, 0x20, 0x0C, 0xF0, 0xAA, 0xFE, 0x4F, 0xF4, 0x80, 0x71, 0x00, 0x20, + 0xFA, 0xF7, 0xA3, 0xFC, 0x00, 0xE0, 0x01, 0x70, 0x28, 0x46, 0xBD, 0xE8, + 0xF0, 0x81, 0x2D, 0xE9, 0xF0, 0x47, 0x88, 0x46, 0x00, 0x28, 0x6B, 0xD0, + 0xDF, 0xF8, 0xB0, 0xA1, 0x00, 0x21, 0x69, 0x4C, 0x9A, 0xF8, 0x00, 0x20, + 0x89, 0x46, 0x02, 0x2A, 0x03, 0xD0, 0x03, 0x2A, 0x01, 0xD0, 0x05, 0x2A, + 0x5D, 0xD1, 0x00, 0x21, 0xB8, 0xF1, 0x00, 0x0F, 0x00, 0xD0, 0x01, 0x21, + 0xA2, 0x88, 0x00, 0xEB, 0x41, 0x00, 0x52, 0x1A, 0x15, 0xB2, 0x07, 0x46, + 0xA2, 0x78, 0x29, 0x46, 0x00, 0xF0, 0x71, 0xF8, 0x5A, 0x4E, 0xA0, 0x70, + 0x30, 0x68, 0x90, 0xF8, 0x90, 0x00, 0x80, 0x07, 0x04, 0xD5, 0x38, 0x46, + 0x29, 0x46, 0xFF, 0xF7, 0x8B, 0xFF, 0x81, 0x46, 0x00, 0x22, 0x01, 0x21, + 0xB8, 0xF1, 0x00, 0x0F, 0x1A, 0xD0, 0x00, 0x27, 0xDF, 0xF8, 0x48, 0xC1, + 0x38, 0x46, 0x36, 0x68, 0x10, 0xE0, 0x00, 0xBF, 0x3C, 0xF9, 0x10, 0x30, + 0x00, 0x2B, 0x00, 0xDA, 0x5B, 0x42, 0xB6, 0xF8, 0x92, 0x80, 0x43, 0x45, + 0x04, 0xDD, 0x96, 0xF8, 0x91, 0x30, 0x7F, 0x1C, 0xBB, 0x42, 0x1B, 0xDD, + 0x40, 0x1C, 0xC0, 0xB2, 0xA8, 0x42, 0xED, 0xDB, 0x11, 0x46, 0x22, 0xE0, + 0x00, 0x23, 0x45, 0x4F, 0x18, 0x46, 0x36, 0x68, 0x0D, 0xE0, 0x00, 0xBF, + 0x37, 0xF9, 0x10, 0xC0, 0xB6, 0xF8, 0x92, 0x80, 0xC4, 0x45, 0x04, 0xDD, + 0x96, 0xF8, 0x91, 0xC0, 0x5B, 0x1C, 0x9C, 0x45, 0x04, 0xDD, 0x40, 0x1C, + 0xC0, 0xB2, 0xA8, 0x42, 0xF0, 0xDB, 0xE7, 0xE7, 0x9A, 0xF8, 0x00, 0x00, + 0x02, 0x28, 0x0B, 0xD0, 0x03, 0x28, 0x09, 0xD0, 0x05, 0x28, 0x04, 0xD1, + 0x60, 0x78, 0x10, 0xB9, 0xB9, 0xF1, 0x00, 0x0F, 0x02, 0xD0, 0x61, 0x70, + 0xBD, 0xE8, 0xF0, 0x87, 0x61, 0x70, 0x00, 0xF0, 0x44, 0xF9, 0xBD, 0xE8, + 0xF0, 0x47, 0x02, 0x21, 0x01, 0x20, 0xFA, 0xF7, 0x22, 0xBC, 0x2F, 0x48, + 0x40, 0x78, 0x70, 0x47, 0x2D, 0x48, 0x00, 0x21, 0x01, 0x22, 0x01, 0x70, + 0x82, 0x70, 0x29, 0x4A, 0x12, 0x68, 0x92, 0xF8, 0x31, 0x20, 0x82, 0x80, + 0x2A, 0x4A, 0x12, 0x78, 0x05, 0x2A, 0x02, 0xD0, 0x06, 0x2A, 0x00, 0xD0, + 0x41, 0x70, 0x70, 0x47, 0xEC, 0xE7, 0x2D, 0xE9, 0xFC, 0x41, 0x80, 0x46, + 0x22, 0x48, 0x14, 0x46, 0x0D, 0x46, 0x40, 0x78, 0x16, 0x46, 0x40, 0xB9, + 0x1E, 0x48, 0x0A, 0x46, 0x7F, 0x23, 0x41, 0x46, 0x54, 0x38, 0x00, 0x94, + 0x0E, 0xF0, 0x22, 0xFA, 0x00, 0x26, 0x19, 0x4F, 0x38, 0x68, 0x90, 0xF8, + 0x90, 0x10, 0xC9, 0x07, 0x00, 0xD0, 0xEC, 0xB1, 0x16, 0x48, 0x6A, 0x00, + 0x41, 0x46, 0x2A, 0x38, 0x11, 0xF0, 0xE1, 0xF9, 0x13, 0x4A, 0x2B, 0x46, + 0x54, 0x3A, 0x02, 0xF1, 0x2A, 0x01, 0x11, 0x48, 0x0E, 0xF0, 0xE5, 0xF9, + 0x38, 0x68, 0x90, 0xF8, 0x90, 0x10, 0x49, 0x07, 0x07, 0xD5, 0x90, 0xF8, + 0x9A, 0x30, 0x23, 0xB1, 0x0B, 0x49, 0x2A, 0x46, 0x08, 0x46, 0x0E, 0xF0, + 0x18, 0xFA, 0x30, 0x46, 0xBD, 0xE8, 0xFC, 0x81, 0xB0, 0xF9, 0x96, 0x10, + 0xCD, 0xE9, 0x00, 0x15, 0x05, 0x4A, 0xB0, 0xF9, 0x94, 0x30, 0x54, 0x3A, + 0x41, 0x46, 0x02, 0xF1, 0x2A, 0x00, 0x0E, 0xF0, 0x4F, 0xF9, 0xD9, 0xE7, + 0x4C, 0x07, 0x10, 0x00, 0x50, 0x09, 0x01, 0x20, 0x30, 0x05, 0x10, 0x00, + 0x54, 0x07, 0x10, 0x00, 0x40, 0x05, 0x10, 0x00, 0x70, 0xB5, 0x00, 0x28, + 0x04, 0x9E, 0x0D, 0xD0, 0x00, 0x24, 0x06, 0xE0, 0x30, 0xF9, 0x11, 0x50, + 0x9D, 0x42, 0x01, 0xDD, 0x95, 0x42, 0x00, 0xDB, 0x64, 0x1C, 0x49, 0x1E, + 0xF6, 0xD2, 0xB4, 0x42, 0x01, 0xDD, 0x01, 0x20, 0x70, 0xBD, 0x00, 0x20, + 0x70, 0xBD, 0x3F, 0x48, 0x00, 0x21, 0x01, 0x70, 0x41, 0x60, 0x70, 0x47, + 0xF9, 0xE7, 0x3C, 0x48, 0x00, 0x78, 0x70, 0x47, 0x2D, 0xE9, 0xF3, 0x4F, + 0xDF, 0xF8, 0xE8, 0xA0, 0x84, 0x46, 0x4F, 0xF0, 0x00, 0x08, 0xDA, 0xF8, + 0x00, 0x00, 0xDF, 0xF8, 0xD8, 0xB0, 0x81, 0xB0, 0x90, 0xF8, 0x80, 0x10, + 0x47, 0x46, 0xC9, 0x07, 0xC1, 0x46, 0x2B, 0xD0, 0x33, 0x49, 0x09, 0x78, + 0x03, 0x29, 0x2D, 0xD0, 0x04, 0x29, 0x2B, 0xD0, 0x05, 0x29, 0x36, 0xD1, + 0xB0, 0xF8, 0x88, 0x60, 0xB0, 0xF8, 0x8A, 0x50, 0x90, 0xF8, 0x87, 0x40, + 0xBC, 0xF1, 0x00, 0x0F, 0x08, 0xD0, 0x00, 0x94, 0x90, 0xF8, 0x31, 0x10, + 0x2B, 0xB2, 0x32, 0xB2, 0x60, 0x46, 0xFF, 0xF7, 0xB7, 0xFF, 0x80, 0x46, + 0x02, 0x98, 0x50, 0xB1, 0x00, 0x94, 0xDA, 0xF8, 0x00, 0x00, 0x2B, 0xB2, + 0x32, 0xB2, 0x90, 0xF8, 0x30, 0x10, 0x02, 0x98, 0xFF, 0xF7, 0xAA, 0xFF, + 0x07, 0x46, 0xB8, 0xF1, 0x01, 0x0F, 0x0E, 0xD0, 0x01, 0x2F, 0x0C, 0xD0, + 0x9B, 0xF8, 0x00, 0x10, 0x58, 0x46, 0x01, 0x29, 0x1D, 0xD0, 0x0A, 0xE0, + 0xB0, 0xF8, 0x82, 0x60, 0xB0, 0xF8, 0x84, 0x50, 0x90, 0xF8, 0x86, 0x40, + 0xD4, 0xE7, 0x9B, 0xF8, 0x00, 0x10, 0x58, 0x46, 0x19, 0xB1, 0xCB, 0xF8, + 0x04, 0x90, 0xBD, 0xE8, 0xFE, 0x8F, 0x41, 0x68, 0x49, 0x1C, 0x41, 0x60, + 0xDA, 0xF8, 0x00, 0x20, 0x92, 0xF8, 0x81, 0x20, 0x8A, 0x42, 0xF4, 0xDA, + 0x01, 0x21, 0x01, 0x70, 0xCB, 0xF8, 0x04, 0x90, 0x0D, 0xE0, 0x41, 0x68, + 0x49, 0x1C, 0x41, 0x60, 0xDA, 0xF8, 0x00, 0x20, 0x92, 0xF8, 0x81, 0x20, + 0x8A, 0x42, 0xE6, 0xDA, 0x80, 0xF8, 0x00, 0x90, 0x00, 0x21, 0xCB, 0xF8, + 0x04, 0x90, 0x03, 0xB0, 0x07, 0x20, 0xBD, 0xE8, 0xF0, 0x4F, 0x0C, 0xF0, + 0x2C, 0xBD, 0x00, 0x00, 0x38, 0x05, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x40, 0x05, 0x10, 0x00, 0x22, 0x49, 0x08, 0xB5, 0x00, 0x20, 0x48, 0x60, + 0x01, 0x22, 0x88, 0x60, 0x0A, 0x70, 0x48, 0x70, 0x1F, 0x49, 0x08, 0x70, + 0x1F, 0x49, 0x08, 0x70, 0xFF, 0xF7, 0x08, 0xFF, 0xFF, 0xF7, 0x70, 0xFF, + 0xFF, 0xF7, 0x5F, 0xFB, 0xFF, 0xF7, 0x8F, 0xFD, 0x6B, 0x46, 0x00, 0x22, + 0x1E, 0x21, 0x01, 0x20, 0xFA, 0xF7, 0x52, 0xFB, 0x00, 0x98, 0x41, 0x07, + 0x03, 0xD5, 0xFF, 0xF7, 0x5B, 0xFA, 0x04, 0x21, 0x08, 0xE0, 0x01, 0x07, + 0x03, 0xD5, 0xFF, 0xF7, 0x73, 0xF8, 0x08, 0x21, 0x02, 0xE0, 0xC1, 0x06, + 0x04, 0xD5, 0x10, 0x21, 0x01, 0x20, 0xFA, 0xF7, 0x22, 0xFB, 0xE5, 0xE7, + 0x80, 0x07, 0xE3, 0xD5, 0x02, 0x21, 0x01, 0x20, 0xFA, 0xF7, 0x1B, 0xFB, + 0xFF, 0xF7, 0x3F, 0xFB, 0xDC, 0xE7, 0x00, 0xEB, 0x80, 0x00, 0x4F, 0xF6, + 0xFF, 0x72, 0x02, 0xEA, 0x40, 0x00, 0xFB, 0xF7, 0xAA, 0xBC, 0xFB, 0xF7, + 0xB8, 0xBC, 0x80, 0xB2, 0xFB, 0xF7, 0xE9, 0xBB, 0xFB, 0xF7, 0xFB, 0xBB, + 0x40, 0x05, 0x10, 0x00, 0x78, 0x07, 0x10, 0x00, 0x7D, 0x07, 0x10, 0x00, + 0x01, 0xF0, 0x41, 0xBA, 0x5E, 0x48, 0x5F, 0x49, 0x00, 0x7E, 0x09, 0x7E, + 0xC8, 0x42, 0x09, 0xD1, 0x5D, 0x48, 0x00, 0x78, 0x80, 0x06, 0x05, 0xD5, + 0x01, 0x23, 0x5C, 0x4A, 0x59, 0x49, 0x58, 0x48, 0x00, 0xF0, 0x00, 0xBD, + 0x70, 0x47, 0x3C, 0xB5, 0x00, 0x23, 0x00, 0x93, 0x01, 0x93, 0x6B, 0x46, + 0x07, 0xE0, 0x44, 0x18, 0x64, 0x78, 0x14, 0xB1, 0x1D, 0x5D, 0x6D, 0x1C, + 0x1D, 0x55, 0x49, 0x1C, 0xC9, 0xB2, 0x91, 0x42, 0xF5, 0xD9, 0x00, 0x20, + 0x01, 0x21, 0x1C, 0x5C, 0x5A, 0x5C, 0xA2, 0x42, 0x00, 0xD9, 0x08, 0x46, + 0x49, 0x1C, 0xC9, 0xB2, 0x06, 0x29, 0xF6, 0xD3, 0x3C, 0xBD, 0x70, 0xB5, + 0x04, 0x46, 0x00, 0x20, 0x08, 0x70, 0x0E, 0x46, 0x10, 0x70, 0x45, 0x48, + 0x45, 0x49, 0x15, 0x46, 0x00, 0x7E, 0x09, 0x7E, 0xC8, 0x42, 0x0B, 0xD0, + 0xE2, 0x78, 0xA1, 0x78, 0x44, 0x48, 0xFF, 0xF7, 0xD2, 0xFF, 0x30, 0x70, + 0x62, 0x78, 0x21, 0x78, 0x42, 0x48, 0xFF, 0xF7, 0xCC, 0xFF, 0x28, 0x70, + 0x70, 0xBD, 0x70, 0xB5, 0x00, 0x24, 0x01, 0x23, 0x05, 0x7E, 0x08, 0xE0, + 0xC6, 0x18, 0x96, 0xF9, 0x12, 0x60, 0x8E, 0x42, 0x02, 0xDB, 0x96, 0x42, + 0x00, 0xDC, 0x64, 0x1C, 0x5B, 0x1C, 0x9D, 0x42, 0xF4, 0xD2, 0x01, 0x2C, + 0x01, 0xDC, 0x01, 0x20, 0x70, 0xBD, 0x00, 0x20, 0x70, 0xBD, 0x2D, 0xE9, + 0xF0, 0x43, 0x99, 0x46, 0x00, 0x23, 0x1F, 0x46, 0x47, 0xF6, 0xFF, 0x76, + 0x4F, 0xF0, 0xFF, 0x3C, 0x01, 0x25, 0x04, 0x7E, 0x0D, 0xE0, 0x00, 0xBF, + 0x00, 0xEB, 0x05, 0x08, 0x98, 0xF9, 0x12, 0x80, 0x88, 0x45, 0x05, 0xDB, + 0x90, 0x45, 0x03, 0xDC, 0x43, 0x19, 0x93, 0xF9, 0x12, 0x30, 0x02, 0xE0, + 0x6D, 0x1C, 0xAC, 0x42, 0xF0, 0xD2, 0x64, 0x1C, 0x0A, 0xE0, 0x05, 0x19, + 0x95, 0xF9, 0x12, 0x50, 0x8D, 0x42, 0x05, 0xDB, 0x95, 0x42, 0x03, 0xDC, + 0x20, 0x44, 0x90, 0xF9, 0x12, 0x70, 0x01, 0xE0, 0x64, 0x1E, 0xF2, 0xD1, + 0xBB, 0x42, 0x09, 0xD1, 0x0A, 0xE0, 0x00, 0xBF, 0x39, 0xF9, 0x13, 0x00, + 0xB0, 0x42, 0x02, 0xDA, 0x06, 0x46, 0x4F, 0xFA, 0x83, 0xFC, 0x5B, 0x1C, + 0xBB, 0x42, 0xF5, 0xDD, 0x60, 0x46, 0xBD, 0xE8, 0xF0, 0x83, 0x2D, 0xE9, + 0xF0, 0x41, 0x17, 0x46, 0x0E, 0x46, 0x04, 0x46, 0xC2, 0x78, 0x81, 0x78, + 0x0E, 0x48, 0xFF, 0xF7, 0xA4, 0xFF, 0x05, 0x00, 0x06, 0xD1, 0xE2, 0x78, + 0xA1, 0x78, 0x11, 0x4B, 0x0A, 0x48, 0xFF, 0xF7, 0xB2, 0xFF, 0x30, 0x70, + 0x62, 0x78, 0x21, 0x78, 0x08, 0x48, 0xFF, 0xF7, 0x96, 0xFF, 0x06, 0x00, + 0x06, 0xD1, 0x62, 0x78, 0x21, 0x78, 0x0B, 0x4B, 0x04, 0x48, 0xFF, 0xF7, + 0xA4, 0xFF, 0x38, 0x70, 0x05, 0xEA, 0x06, 0x00, 0xBD, 0xE8, 0xF0, 0x81, + 0x18, 0x2A, 0x10, 0x00, 0x58, 0x2A, 0x10, 0x00, 0x04, 0x07, 0x10, 0x00, + 0x40, 0x2B, 0x10, 0x00, 0x0A, 0x0C, 0x01, 0x20, 0x21, 0x0C, 0x01, 0x20, + 0x94, 0x0B, 0x01, 0x20, 0xBE, 0x0B, 0x01, 0x20, 0x24, 0x48, 0x00, 0x21, + 0x01, 0x61, 0x41, 0x61, 0x23, 0x48, 0x01, 0x70, 0x01, 0x21, 0x41, 0x70, + 0x70, 0x47, 0x2D, 0xE9, 0xF8, 0x4F, 0x20, 0x4D, 0x82, 0x46, 0x0E, 0x46, + 0x1D, 0x48, 0x69, 0x78, 0x10, 0x30, 0x01, 0x29, 0x0F, 0xD1, 0x1D, 0x49, + 0x09, 0x68, 0x91, 0xF8, 0x40, 0x2A, 0x02, 0xF0, 0x0F, 0x03, 0x03, 0x80, + 0x12, 0x09, 0x42, 0x80, 0x91, 0xF8, 0x41, 0x1A, 0x01, 0xF0, 0x0F, 0x02, + 0x82, 0x80, 0x09, 0x09, 0xC1, 0x80, 0x13, 0x49, 0x00, 0x27, 0x3C, 0x46, + 0x8F, 0x60, 0xCF, 0x60, 0x80, 0x46, 0x89, 0x46, 0x0B, 0xE0, 0x68, 0x78, + 0x00, 0x90, 0x38, 0xF9, 0x14, 0x30, 0x0A, 0xEB, 0x44, 0x01, 0x09, 0xEB, + 0x44, 0x00, 0x01, 0x22, 0x0D, 0xF0, 0xDE, 0xFF, 0x64, 0x1C, 0xB4, 0x42, + 0xF1, 0xDB, 0x6F, 0x70, 0x03, 0x20, 0xFA, 0xF7, 0xAA, 0xFA, 0x06, 0x49, + 0x33, 0x46, 0x08, 0x4A, 0x01, 0xF1, 0x08, 0x00, 0x0D, 0xF0, 0xC3, 0xFF, + 0xBD, 0xE8, 0xF8, 0x4F, 0x03, 0x20, 0xFA, 0xF7, 0xB9, 0xBA, 0x00, 0x00, + 0x7A, 0x09, 0x01, 0x20, 0x55, 0x05, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0xFC, 0x4A, 0x01, 0x20, 0x2D, 0xE9, 0xF0, 0x5F, 0x82, 0x46, 0x5E, 0x48, + 0x99, 0x46, 0x3A, 0xF9, 0x12, 0x30, 0x00, 0x68, 0x01, 0x26, 0x0A, 0x9C, + 0xB0, 0xF9, 0x3E, 0xB2, 0x03, 0xFB, 0x02, 0xF0, 0x35, 0x46, 0x29, 0xE0, + 0x57, 0x1B, 0x7F, 0xB2, 0x00, 0x2F, 0x0F, 0xDB, 0x76, 0xB1, 0x3A, 0xF9, + 0x17, 0xC0, 0xDC, 0x45, 0x09, 0xDD, 0x0A, 0xEB, 0x47, 0x08, 0xB8, 0xF9, + 0x02, 0x80, 0xC4, 0x45, 0x03, 0xDC, 0x0C, 0xFB, 0x07, 0x00, 0x63, 0x44, + 0x00, 0xE0, 0x00, 0x26, 0x57, 0x19, 0x7F, 0xB2, 0x8F, 0x42, 0x0F, 0xDA, + 0x76, 0xB1, 0x3A, 0xF9, 0x17, 0xC0, 0xDC, 0x45, 0x09, 0xDD, 0x0A, 0xEB, + 0x47, 0x08, 0x38, 0xF9, 0x02, 0x8C, 0xC4, 0x45, 0x03, 0xDC, 0x0C, 0xFB, + 0x07, 0x00, 0x63, 0x44, 0x00, 0xE0, 0x00, 0x26, 0x6D, 0x1C, 0xED, 0xB2, + 0x4D, 0x45, 0xD3, 0xD9, 0x49, 0x1E, 0x83, 0xFB, 0x01, 0x23, 0x80, 0xFB, + 0x04, 0x01, 0x10, 0xF0, 0x42, 0xFF, 0x00, 0x28, 0x00, 0xDA, 0x00, 0x20, + 0x61, 0x1E, 0x88, 0x42, 0x00, 0xDD, 0x08, 0x46, 0xBD, 0xE8, 0xF0, 0x9F, + 0x70, 0xB5, 0x00, 0x20, 0x96, 0xB0, 0x04, 0x46, 0x38, 0x4D, 0x34, 0xE0, + 0x22, 0x46, 0x37, 0x49, 0x01, 0xA8, 0x00, 0xF0, 0x35, 0xF8, 0x34, 0x4E, + 0x30, 0x68, 0xB0, 0xF9, 0x34, 0x10, 0x00, 0x91, 0x90, 0xF8, 0x40, 0x32, + 0x32, 0x48, 0x2A, 0x57, 0x01, 0x78, 0x32, 0x48, 0xFF, 0xF7, 0x9C, 0xFF, + 0x13, 0x90, 0x30, 0x68, 0xB0, 0xF9, 0x32, 0x10, 0x00, 0x91, 0x90, 0xF8, + 0x40, 0x32, 0x28, 0x19, 0x90, 0xF9, 0x02, 0x20, 0x2C, 0x48, 0x01, 0x78, + 0x2C, 0x48, 0xFF, 0xF7, 0x8D, 0xFF, 0x14, 0x90, 0x13, 0xA8, 0x07, 0xF0, + 0xB5, 0xF8, 0x14, 0x99, 0xAD, 0xF8, 0x12, 0x10, 0x13, 0x98, 0xAD, 0xF8, + 0x16, 0x10, 0xAD, 0xF8, 0x10, 0x00, 0xAD, 0xF8, 0x14, 0x00, 0x01, 0xA8, + 0x05, 0xF0, 0xB5, 0xFE, 0x01, 0x20, 0x64, 0x1C, 0xE4, 0xB2, 0x29, 0x7A, + 0xA1, 0x42, 0xC7, 0xD8, 0x16, 0xB0, 0x70, 0xBD, 0x70, 0xB5, 0x0E, 0x46, + 0x15, 0x46, 0x04, 0x46, 0x48, 0x21, 0x10, 0xF0, 0xB7, 0xFF, 0x71, 0x19, + 0x08, 0x79, 0x8A, 0x79, 0x50, 0x43, 0x03, 0x22, 0x84, 0xF8, 0x40, 0x20, + 0x18, 0x4A, 0x12, 0x88, 0x52, 0x1C, 0x62, 0x86, 0xA2, 0x8C, 0x42, 0xF0, + 0x20, 0x02, 0xA2, 0x84, 0xE0, 0x84, 0x60, 0x85, 0x42, 0x1C, 0x22, 0x85, + 0x41, 0xF2, 0x88, 0x32, 0xE2, 0x61, 0xA2, 0x61, 0x0A, 0x79, 0x8B, 0x79, + 0xD1, 0x18, 0x00, 0xD1, 0x01, 0x21, 0x42, 0x43, 0x58, 0x43, 0x52, 0x00, + 0x40, 0x00, 0xB2, 0xFB, 0xF1, 0xF2, 0xB0, 0xFB, 0xF1, 0xF0, 0x82, 0x42, + 0x02, 0xD9, 0xE2, 0x85, 0x20, 0x86, 0x70, 0xBD, 0xE0, 0x85, 0x22, 0x86, + 0x70, 0xBD, 0x00, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x0C, 0x2A, 0x10, 0x00, + 0xED, 0x06, 0x10, 0x00, 0x94, 0x0B, 0x01, 0x20, 0xEE, 0x06, 0x10, 0x00, + 0xBE, 0x0B, 0x01, 0x20, 0x8C, 0x06, 0x10, 0x00, 0x2D, 0xE9, 0xF0, 0x47, + 0x00, 0x25, 0x82, 0x46, 0xA6, 0xB0, 0x50, 0x1E, 0xC7, 0xB2, 0x2C, 0x46, + 0x28, 0x46, 0x6B, 0x46, 0x0D, 0xF1, 0x4C, 0x09, 0x12, 0xE0, 0x00, 0xBF, + 0x31, 0xF9, 0x10, 0x60, 0x35, 0x44, 0x46, 0x1C, 0xB4, 0x46, 0x95, 0xFB, + 0xF6, 0xF6, 0x23, 0xF8, 0x10, 0x60, 0x3E, 0x1A, 0x40, 0x1C, 0x31, 0xF9, + 0x16, 0x80, 0x44, 0x44, 0x94, 0xFB, 0xFC, 0xFC, 0x29, 0xF8, 0x16, 0xC0, + 0x90, 0x42, 0xEB, 0xDB, 0x48, 0x46, 0x0C, 0xE0, 0x33, 0xF9, 0x12, 0x40, + 0x30, 0xF9, 0x12, 0x50, 0x2C, 0x44, 0x31, 0xF8, 0x12, 0x50, 0x04, 0xEB, + 0xD4, 0x74, 0xA5, 0xEB, 0x64, 0x04, 0x2A, 0xF8, 0x12, 0x40, 0x52, 0x1E, + 0xF0, 0xD2, 0x26, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x2D, 0xE9, 0xFF, 0x4F, + 0x4F, 0xF0, 0x00, 0x0B, 0xA7, 0xB0, 0xC0, 0xF8, 0x00, 0xB0, 0x81, 0x46, + 0xC0, 0xF8, 0x04, 0xB0, 0x98, 0x46, 0x14, 0x46, 0x5D, 0x46, 0x5E, 0x46, + 0xDA, 0x46, 0x5F, 0x46, 0x28, 0x21, 0x01, 0xA8, 0x10, 0xF0, 0x32, 0xFF, + 0x4C, 0x21, 0x0B, 0xA8, 0x10, 0xF0, 0x2E, 0xFF, 0xCD, 0xF8, 0x00, 0x80, + 0x02, 0x23, 0x22, 0x46, 0x0B, 0xA8, 0x28, 0x99, 0x0D, 0xF0, 0x9E, 0xFE, + 0x8E, 0x49, 0x01, 0x20, 0x02, 0x46, 0x00, 0x23, 0x0D, 0xF1, 0x04, 0x0E, + 0xD1, 0xF8, 0x00, 0x80, 0x17, 0xE0, 0x0B, 0xA9, 0x31, 0xF9, 0x10, 0xC0, + 0xB8, 0xF9, 0x4C, 0x12, 0x8C, 0x45, 0x04, 0xDD, 0x4F, 0xF0, 0x01, 0x0B, + 0x0E, 0xF8, 0x00, 0x20, 0x0A, 0xE0, 0x49, 0x42, 0x8C, 0x45, 0x05, 0xDA, + 0xFF, 0x21, 0x4F, 0xF0, 0x01, 0x0B, 0x0E, 0xF8, 0x00, 0x10, 0x01, 0xE0, + 0x0E, 0xF8, 0x00, 0x30, 0x40, 0x1C, 0xA0, 0x42, 0xE5, 0xDB, 0xBB, 0xF1, + 0x01, 0x0F, 0x42, 0xD1, 0x01, 0x20, 0x71, 0x46, 0x09, 0xE0, 0x0A, 0x5C, + 0x32, 0xB1, 0xC5, 0xB2, 0x08, 0x56, 0x00, 0x28, 0x05, 0xDD, 0x4F, 0xF0, + 0x01, 0x0A, 0x02, 0xE0, 0x40, 0x1C, 0xA0, 0x42, 0xF3, 0xDB, 0x60, 0x1E, + 0x07, 0xE0, 0x0A, 0x5C, 0x2A, 0xB1, 0xC6, 0xB2, 0x08, 0x56, 0x00, 0x28, + 0x03, 0xDA, 0x01, 0x27, 0x01, 0xE0, 0x40, 0x1E, 0xF5, 0xD2, 0xA4, 0xF1, + 0x01, 0x08, 0xBA, 0xF1, 0x00, 0x0F, 0x01, 0xD0, 0x97, 0xB9, 0x02, 0xE0, + 0x4F, 0xF0, 0x01, 0x05, 0x77, 0xB9, 0x08, 0xF0, 0xFF, 0x06, 0x0B, 0xE0, + 0xD9, 0xE9, 0x00, 0x47, 0x2A, 0x46, 0x01, 0x20, 0x00, 0x21, 0x10, 0xF0, + 0xF9, 0xFD, 0x04, 0x43, 0x0F, 0x43, 0xC9, 0xE9, 0x00, 0x47, 0x6D, 0x1C, + 0xB5, 0x42, 0xF1, 0xDD, 0xD9, 0xE9, 0x00, 0x04, 0x40, 0xF0, 0x01, 0x05, + 0x42, 0x46, 0x01, 0x20, 0x00, 0x21, 0x10, 0xF0, 0xE9, 0xFD, 0x05, 0x43, + 0x0C, 0x43, 0xC9, 0xE9, 0x00, 0x54, 0x2B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, + 0x2D, 0xE9, 0xF8, 0x43, 0x05, 0x46, 0x16, 0x46, 0x0F, 0x46, 0x03, 0x20, + 0xFA, 0xF7, 0xFD, 0xF8, 0x55, 0x4C, 0x56, 0x4A, 0x29, 0x46, 0x23, 0x78, + 0x55, 0x48, 0x0D, 0xF0, 0x16, 0xFE, 0x55, 0x4D, 0x53, 0x48, 0x55, 0x4A, + 0x2B, 0x78, 0x39, 0x46, 0x2A, 0x30, 0x0D, 0xF0, 0x0E, 0xFE, 0x03, 0x20, + 0xFA, 0xF7, 0x06, 0xF9, 0xDF, 0xF8, 0x2C, 0x81, 0xD8, 0xF8, 0x00, 0x00, + 0x90, 0xF8, 0xE0, 0x13, 0x89, 0x07, 0x12, 0xD5, 0x90, 0xF8, 0xF4, 0x03, + 0x00, 0x96, 0x00, 0xF0, 0x0F, 0x07, 0x3B, 0x46, 0x22, 0x78, 0x47, 0x49, + 0x49, 0x48, 0x0D, 0xF0, 0x05, 0xFE, 0x45, 0x49, 0x00, 0x96, 0x3B, 0x46, + 0x2A, 0x78, 0x2A, 0x31, 0x46, 0x48, 0x0D, 0xF0, 0xFD, 0xFD, 0x22, 0x78, + 0x40, 0x49, 0x45, 0x48, 0x00, 0xF0, 0x5B, 0xF8, 0x3E, 0x49, 0x2A, 0x78, + 0x2A, 0x31, 0x43, 0x48, 0x00, 0xF0, 0x55, 0xF8, 0x42, 0x4F, 0x00, 0x96, + 0x22, 0x78, 0x3F, 0x49, 0x41, 0x48, 0x3B, 0x68, 0x0D, 0xF0, 0xEA, 0xFD, + 0x00, 0x96, 0x2A, 0x78, 0x3C, 0x49, 0x3F, 0x48, 0x3B, 0x68, 0x0D, 0xF0, + 0xE3, 0xFD, 0xD8, 0xF8, 0x00, 0x00, 0x47, 0x46, 0x90, 0xF8, 0x30, 0x02, + 0xC0, 0x06, 0x0A, 0xD5, 0x22, 0x78, 0x38, 0x49, 0x39, 0x48, 0xFF, 0xF7, + 0xE3, 0xFE, 0x2A, 0x78, 0x36, 0x49, 0x38, 0x48, 0xFF, 0xF7, 0xDE, 0xFE, + 0x0B, 0xE0, 0x20, 0x78, 0x32, 0x49, 0x42, 0x00, 0x33, 0x48, 0x10, 0xF0, + 0xB2, 0xFD, 0x28, 0x78, 0x30, 0x49, 0x42, 0x00, 0x31, 0x48, 0x10, 0xF0, + 0xAC, 0xFD, 0x38, 0x68, 0x90, 0xF8, 0x30, 0x02, 0x80, 0x06, 0x04, 0xD5, + 0x2C, 0x49, 0x22, 0x78, 0x08, 0x46, 0x00, 0xF0, 0x30, 0xF8, 0x38, 0x68, + 0x90, 0xF8, 0x30, 0x02, 0x40, 0x06, 0x04, 0xD5, 0x28, 0x49, 0x2A, 0x78, + 0x08, 0x46, 0x00, 0xF0, 0x26, 0xF8, 0x33, 0x46, 0x22, 0x78, 0x1A, 0x49, + 0x25, 0x48, 0xFF, 0xF7, 0xED, 0xFE, 0x2A, 0x78, 0x01, 0xB0, 0x33, 0x46, + 0xBD, 0xE8, 0xF0, 0x43, 0x15, 0x49, 0x21, 0x48, 0x2A, 0x31, 0x08, 0x30, + 0xE2, 0xE6, 0x20, 0x49, 0x00, 0x20, 0x08, 0x70, 0x70, 0x47, 0x30, 0xB5, + 0x00, 0x23, 0x03, 0x80, 0x01, 0x23, 0x09, 0xE0, 0x00, 0xEB, 0x43, 0x04, + 0x31, 0xF8, 0x13, 0x50, 0x34, 0xF8, 0x02, 0x4C, 0x2C, 0x44, 0x20, 0xF8, + 0x13, 0x40, 0x5B, 0x1C, 0x93, 0x42, 0xF3, 0xDB, 0x30, 0xBD, 0x08, 0xB5, + 0x00, 0x92, 0x04, 0x4A, 0x12, 0x68, 0xB2, 0xF9, 0x4A, 0x32, 0xB2, 0xF9, + 0x48, 0x22, 0x02, 0xF0, 0x78, 0xFA, 0x08, 0xBD, 0x4C, 0x07, 0x10, 0x00, + 0xED, 0x06, 0x10, 0x00, 0x7E, 0x4A, 0x01, 0x20, 0x92, 0x09, 0x01, 0x20, + 0xEE, 0x06, 0x10, 0x00, 0xA8, 0x4A, 0x01, 0x20, 0xC8, 0x2A, 0x10, 0x00, + 0xF2, 0x2A, 0x10, 0x00, 0xA0, 0x0A, 0x01, 0x20, 0xCE, 0x0A, 0x01, 0x20, + 0x9C, 0x06, 0x10, 0x00, 0x1E, 0x0B, 0x01, 0x20, 0x48, 0x0B, 0x01, 0x20, + 0x94, 0x0B, 0x01, 0x20, 0xBE, 0x0B, 0x01, 0x20, 0x50, 0x2B, 0x10, 0x00, + 0xF4, 0x06, 0x10, 0x00, 0x10, 0xB5, 0x40, 0x21, 0xFE, 0x48, 0x10, 0xF0, + 0xE1, 0xFD, 0xFD, 0x48, 0x40, 0x21, 0x40, 0x30, 0x10, 0xF0, 0xDC, 0xFD, + 0xFA, 0x48, 0x00, 0x21, 0x80, 0x30, 0xC0, 0xE9, 0x00, 0x11, 0xC0, 0xE9, + 0x02, 0x11, 0x10, 0x30, 0xC0, 0xE9, 0x00, 0x11, 0xC0, 0xE9, 0x02, 0x11, + 0x10, 0x30, 0xC0, 0xE9, 0x00, 0x11, 0xC0, 0xE9, 0x02, 0x11, 0x08, 0x46, + 0xF2, 0x49, 0x08, 0x60, 0x10, 0xBD, 0x2D, 0xE9, 0xFF, 0x5F, 0x06, 0x46, + 0x89, 0x46, 0xF0, 0x48, 0xF0, 0x49, 0x98, 0x46, 0x00, 0x78, 0x09, 0x68, + 0x14, 0x46, 0x01, 0x28, 0x50, 0xD0, 0xB1, 0xF9, 0x86, 0xA2, 0x91, 0xF8, + 0x88, 0x52, 0xB1, 0xF9, 0x82, 0x72, 0x11, 0x46, 0x48, 0x46, 0x0D, 0xF0, + 0xAE, 0xFD, 0x83, 0x46, 0x21, 0x46, 0x48, 0x46, 0x0D, 0xF0, 0xB4, 0xFD, + 0x00, 0x90, 0x39, 0x46, 0x58, 0x46, 0x0C, 0xF0, 0x91, 0xFD, 0x0F, 0xFA, + 0x80, 0xFB, 0x39, 0x46, 0x00, 0x98, 0x0C, 0xF0, 0x8B, 0xFD, 0x00, 0xB2, + 0xAB, 0xEB, 0x00, 0x00, 0x68, 0x43, 0x64, 0x21, 0x90, 0xFB, 0xF1, 0xF0, + 0x38, 0x44, 0x05, 0xB2, 0xA8, 0xF8, 0x08, 0x50, 0x70, 0x1C, 0x00, 0x21, + 0x03, 0x90, 0xC8, 0xF8, 0x00, 0x10, 0xC8, 0xF8, 0x04, 0x10, 0xB9, 0xF9, + 0x00, 0x00, 0xA8, 0x42, 0x02, 0xDD, 0x03, 0x99, 0x01, 0x20, 0x08, 0x70, + 0x09, 0xEB, 0x44, 0x00, 0x76, 0x1C, 0x30, 0xF9, 0x02, 0x2C, 0x31, 0x19, + 0xAA, 0x42, 0x02, 0xDD, 0x01, 0x22, 0x01, 0xF8, 0x01, 0x2C, 0xB9, 0xF9, + 0x02, 0x30, 0x03, 0xEB, 0x0A, 0x02, 0x12, 0xB2, 0xAB, 0x42, 0x18, 0xDD, + 0xB9, 0xF9, 0x00, 0x30, 0x93, 0x42, 0x03, 0xDD, 0xB9, 0xF9, 0x04, 0x30, + 0x93, 0x42, 0x0A, 0xDC, 0x03, 0x9B, 0x01, 0x22, 0x5A, 0x70, 0x0C, 0xE0, + 0xB1, 0xF9, 0x69, 0xA2, 0x91, 0xF8, 0x64, 0x52, 0xB1, 0xF9, 0x65, 0x72, + 0xAD, 0xE7, 0xD8, 0xF8, 0x00, 0x60, 0x46, 0xF0, 0x02, 0x06, 0xC8, 0xF8, + 0x00, 0x60, 0x30, 0xF9, 0x04, 0x3C, 0xA4, 0xF1, 0x02, 0x0B, 0x03, 0xEB, + 0x0A, 0x02, 0x12, 0xB2, 0xAB, 0x42, 0x16, 0xDD, 0x30, 0xF9, 0x06, 0x3C, + 0x93, 0x42, 0x03, 0xDD, 0x30, 0xF9, 0x02, 0x0C, 0x90, 0x42, 0x03, 0xDC, + 0x01, 0x20, 0x01, 0xF8, 0x02, 0x0C, 0x0A, 0xE0, 0xD8, 0xE9, 0x00, 0x64, + 0x5A, 0x46, 0x01, 0x20, 0x00, 0x21, 0x10, 0xF0, 0x69, 0xFC, 0x06, 0x43, + 0x0C, 0x43, 0xC8, 0xE9, 0x00, 0x64, 0x02, 0x24, 0x58, 0xE0, 0x00, 0xBF, + 0x39, 0xF9, 0x14, 0x00, 0xA8, 0x42, 0x52, 0xDD, 0x09, 0xEB, 0x44, 0x01, + 0x02, 0x91, 0x50, 0x44, 0x31, 0xF9, 0x02, 0x1C, 0x00, 0xB2, 0x81, 0x42, + 0x04, 0xDD, 0x02, 0x9A, 0xB2, 0xF9, 0x02, 0x20, 0x82, 0x42, 0x10, 0xDC, + 0x02, 0x9A, 0x32, 0xF9, 0x04, 0x2C, 0x82, 0x42, 0x04, 0xDD, 0x02, 0x9A, + 0xB2, 0xF9, 0x02, 0x20, 0x82, 0x42, 0x06, 0xDC, 0x81, 0x42, 0x35, 0xDD, + 0x02, 0x99, 0xB1, 0xF9, 0x04, 0x10, 0x81, 0x42, 0x30, 0xDD, 0xD8, 0xE9, + 0x00, 0x67, 0x22, 0x46, 0x01, 0x20, 0x00, 0x21, 0x10, 0xF0, 0x38, 0xFC, + 0xCD, 0xE9, 0x00, 0x01, 0x06, 0x43, 0x0F, 0x43, 0x62, 0x1E, 0x01, 0x20, + 0x00, 0x21, 0xC8, 0xE9, 0x00, 0x67, 0x10, 0xF0, 0x2D, 0xFC, 0x02, 0x46, + 0x0B, 0x46, 0x06, 0xEA, 0x02, 0x00, 0x07, 0xEA, 0x03, 0x01, 0x08, 0x43, + 0x19, 0xD0, 0x02, 0x98, 0x39, 0xF9, 0x14, 0x10, 0x30, 0xF9, 0x02, 0x0C, + 0x81, 0x42, 0x09, 0xDA, 0x96, 0x43, 0x9F, 0x43, 0xC8, 0xE9, 0x00, 0x67, + 0x03, 0x99, 0x01, 0x20, 0x21, 0x44, 0x01, 0xF8, 0x01, 0x0C, 0x08, 0xE0, + 0xDD, 0xE9, 0x00, 0x10, 0x8E, 0x43, 0x87, 0x43, 0xC8, 0xE9, 0x00, 0x67, + 0x03, 0x99, 0x01, 0x20, 0x08, 0x55, 0x64, 0x1C, 0x5C, 0x45, 0xA5, 0xD3, + 0xBD, 0xE8, 0xFF, 0x9F, 0x2D, 0xE9, 0xFF, 0x4F, 0x81, 0xB0, 0x82, 0x46, + 0x00, 0x21, 0x1D, 0x46, 0x19, 0x76, 0x06, 0x20, 0x90, 0x46, 0xC3, 0x1F, + 0x7A, 0x4C, 0x07, 0xE0, 0x00, 0x22, 0x29, 0x18, 0x0A, 0x73, 0x8B, 0x74, + 0x05, 0xEB, 0x40, 0x01, 0x22, 0x88, 0x0A, 0x80, 0x40, 0x1E, 0xF5, 0xD2, + 0x72, 0x48, 0x01, 0x78, 0x72, 0x48, 0x01, 0x29, 0x00, 0x68, 0x06, 0xD0, + 0xB0, 0xF9, 0x84, 0x22, 0x4F, 0xF0, 0x00, 0x0B, 0x59, 0x46, 0x58, 0x46, + 0x16, 0xE0, 0xB0, 0xF9, 0x67, 0x22, 0xF7, 0xE7, 0x0A, 0xEB, 0x00, 0x03, + 0x5C, 0x78, 0x74, 0xB1, 0x1A, 0xF8, 0x00, 0x40, 0x0C, 0xB9, 0x49, 0x1C, + 0xC9, 0xB2, 0x59, 0x70, 0x02, 0x9B, 0x33, 0xF9, 0x10, 0x30, 0x93, 0x42, + 0x03, 0xDD, 0x01, 0x23, 0x8B, 0x40, 0x43, 0xEA, 0x0B, 0x0B, 0x40, 0x1C, + 0x40, 0x45, 0xE9, 0xD3, 0x62, 0x48, 0x00, 0x90, 0x0E, 0x98, 0x4F, 0xF0, + 0x00, 0x09, 0x4C, 0x46, 0xC0, 0xE9, 0x00, 0x99, 0x37, 0xE0, 0x00, 0xBF, + 0x0A, 0xEB, 0x04, 0x00, 0x42, 0x78, 0x8A, 0xB3, 0x01, 0x21, 0x91, 0x40, + 0x11, 0xEA, 0x0B, 0x0F, 0x02, 0xD1, 0x00, 0x21, 0x41, 0x70, 0x29, 0xE0, + 0x1A, 0xF8, 0x04, 0x10, 0x39, 0xB9, 0x09, 0xF1, 0x01, 0x01, 0x01, 0xF0, + 0xFF, 0x09, 0x54, 0x49, 0x00, 0x91, 0x05, 0xF8, 0x19, 0x40, 0x80, 0xF8, + 0x01, 0x90, 0x0E, 0x98, 0x22, 0x46, 0x00, 0x21, 0xD0, 0xE9, 0x00, 0x67, + 0x01, 0x20, 0x10, 0xF0, 0x9F, 0xFB, 0x06, 0x43, 0x0E, 0x98, 0x0F, 0x43, + 0xC0, 0xE9, 0x00, 0x67, 0x05, 0xEB, 0x09, 0x00, 0x01, 0x7B, 0x49, 0x1C, + 0x01, 0x73, 0x05, 0xEB, 0x49, 0x01, 0x4C, 0x70, 0x02, 0x99, 0x00, 0x9A, + 0x31, 0xF9, 0x14, 0x10, 0x91, 0x42, 0x01, 0xDD, 0x00, 0x91, 0x84, 0x74, + 0x64, 0x1C, 0x44, 0x45, 0xC6, 0xD3, 0x85, 0xF8, 0x18, 0x90, 0x05, 0xB0, + 0xBD, 0xE8, 0xF0, 0x8F, 0x2D, 0xE9, 0xF8, 0x4F, 0x0C, 0x46, 0x05, 0x46, + 0x1E, 0x46, 0x91, 0x46, 0x17, 0x21, 0x3C, 0x48, 0x10, 0xF0, 0x2E, 0xFC, + 0x28, 0x21, 0x3B, 0x48, 0x10, 0xF0, 0x2A, 0xFC, 0xDF, 0xF8, 0xE8, 0xA0, + 0x3A, 0x4F, 0x09, 0xF1, 0x08, 0x08, 0x9A, 0xF8, 0x00, 0x10, 0x76, 0xB1, + 0x0A, 0x46, 0x05, 0xF1, 0x20, 0x03, 0x37, 0x49, 0x32, 0x48, 0xFF, 0xF7, + 0x76, 0xFE, 0x04, 0xF1, 0x20, 0x03, 0x3A, 0x78, 0x34, 0x49, 0x30, 0x48, + 0xFF, 0xF7, 0x6F, 0xFE, 0x11, 0xE0, 0x4A, 0x46, 0x2C, 0x48, 0x00, 0xF0, + 0x3D, 0xFA, 0x42, 0x46, 0x39, 0x78, 0x2B, 0x48, 0x00, 0xF0, 0x38, 0xFA, + 0x00, 0x20, 0xC5, 0xE9, 0x08, 0x00, 0xC4, 0xE9, 0x08, 0x00, 0x2C, 0x48, + 0x00, 0x88, 0x28, 0x85, 0x20, 0x85, 0x2B, 0x4E, 0x28, 0x8D, 0x2B, 0x46, + 0x26, 0xF8, 0x11, 0x0F, 0x20, 0x8D, 0x70, 0x80, 0xCD, 0xF8, 0x00, 0x90, + 0x9A, 0xF8, 0x00, 0x20, 0x22, 0x49, 0x1E, 0x48, 0xFF, 0xF7, 0x36, 0xFF, + 0xCD, 0xF8, 0x00, 0x80, 0x23, 0x46, 0x3A, 0x78, 0x1F, 0x49, 0x1B, 0x48, + 0xFF, 0xF7, 0x2E, 0xFF, 0x29, 0x7E, 0x30, 0x79, 0x61, 0xF3, 0x03, 0x00, + 0x30, 0x71, 0x21, 0x7E, 0x61, 0xF3, 0x07, 0x10, 0x30, 0x71, 0xBD, 0xE8, + 0xF8, 0x8F, 0x2D, 0xE9, 0xFF, 0x4F, 0x15, 0x46, 0x04, 0x46, 0xD1, 0xE9, + 0x02, 0x70, 0xD1, 0xE9, 0x00, 0x92, 0x80, 0x46, 0x81, 0xB0, 0x92, 0x46, + 0x4F, 0xF4, 0x66, 0x71, 0x28, 0x46, 0x10, 0xF0, 0xCF, 0xFB, 0x00, 0x20, + 0x01, 0x46, 0x00, 0x90, 0x0E, 0x98, 0x01, 0x60, 0x00, 0x21, 0x28, 0x46, + 0x10, 0xF0, 0xD8, 0xFC, 0x83, 0x46, 0x1B, 0xE0, 0x18, 0x2A, 0x10, 0x00, + 0x58, 0x05, 0x10, 0x00, 0x66, 0x05, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0xFC, 0x78, 0x01, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x0A, 0x0C, 0x01, 0x20, + 0x21, 0x0C, 0x01, 0x20, 0xED, 0x06, 0x10, 0x00, 0xEE, 0x06, 0x10, 0x00, + 0x94, 0x0B, 0x01, 0x20, 0xBE, 0x0B, 0x01, 0x20, 0x68, 0x05, 0x10, 0x00, + 0x0A, 0x44, 0x01, 0x20, 0x00, 0x21, 0x20, 0x46, 0x10, 0xF0, 0xAE, 0xFC, + 0x06, 0x46, 0x00, 0x25, 0x34, 0xE0, 0x2A, 0x46, 0x01, 0x20, 0x00, 0x21, + 0x10, 0xF0, 0xE6, 0xFA, 0x00, 0xEA, 0x09, 0x00, 0x01, 0xEA, 0x0A, 0x01, + 0x08, 0x43, 0x22, 0xD0, 0x00, 0x24, 0x1C, 0xE0, 0x22, 0x46, 0x01, 0x20, + 0x00, 0x21, 0x10, 0xF0, 0xD9, 0xFA, 0x38, 0x40, 0x01, 0xEA, 0x08, 0x01, + 0x08, 0x43, 0x11, 0xD0, 0x36, 0xF9, 0x14, 0x10, 0x04, 0x98, 0x81, 0x42, + 0x0C, 0xDD, 0x01, 0x20, 0x0B, 0xF8, 0x04, 0x00, 0x00, 0x98, 0x40, 0x1C, + 0x00, 0x90, 0x0E, 0x98, 0x36, 0xF9, 0x14, 0x10, 0x00, 0x68, 0x01, 0x44, + 0x0E, 0x98, 0x01, 0x60, 0x64, 0x1C, 0xFE, 0x48, 0x00, 0x78, 0x84, 0x42, + 0xDE, 0xDB, 0xFC, 0x48, 0x0B, 0xF1, 0x28, 0x0B, 0x6D, 0x1C, 0x00, 0x78, + 0x06, 0xEB, 0x40, 0x06, 0xF9, 0x48, 0x00, 0x78, 0x85, 0x42, 0xC6, 0xDB, + 0x00, 0x98, 0x2A, 0xE7, 0x2D, 0xE9, 0xF0, 0x47, 0x0F, 0x46, 0x1C, 0x46, + 0x16, 0x46, 0x99, 0x78, 0x10, 0xF0, 0x62, 0xFC, 0x05, 0x46, 0xA1, 0x78, + 0x38, 0x46, 0x10, 0xF0, 0x63, 0xFC, 0x02, 0x46, 0xEE, 0x48, 0x00, 0x23, + 0xA1, 0x78, 0x90, 0xF8, 0x00, 0x90, 0x94, 0xF8, 0x03, 0xC0, 0x13, 0xE0, + 0x20, 0x78, 0x67, 0x78, 0x09, 0xE0, 0x00, 0xBF, 0x15, 0xF8, 0x00, 0x80, + 0xB0, 0x45, 0x02, 0xD1, 0x32, 0xF9, 0x10, 0x80, 0x43, 0x44, 0x40, 0x1C, + 0xC0, 0xB2, 0x87, 0x42, 0xF4, 0xD2, 0x49, 0x1C, 0x02, 0xEB, 0x49, 0x02, + 0xC9, 0xB2, 0x28, 0x35, 0x8C, 0x45, 0xE9, 0xD2, 0x18, 0x46, 0xBD, 0xE8, + 0xF0, 0x87, 0x2D, 0xE9, 0xF0, 0x4F, 0xDF, 0x48, 0x87, 0xB0, 0xDF, 0xF8, + 0x80, 0x83, 0x06, 0x68, 0x00, 0x20, 0x06, 0xF5, 0x88, 0x74, 0x86, 0xF8, + 0x0E, 0x01, 0xDB, 0x48, 0x01, 0x23, 0x00, 0x22, 0x00, 0x68, 0x30, 0x60, + 0x31, 0x46, 0xD8, 0xF8, 0x00, 0x00, 0x08, 0xF0, 0x85, 0xF8, 0xDF, 0xF8, + 0x60, 0xA3, 0xDF, 0xF8, 0x60, 0x93, 0x4F, 0xF0, 0xFF, 0x37, 0x9A, 0xF8, + 0x00, 0x00, 0x01, 0x28, 0x10, 0xD1, 0xD5, 0x48, 0x00, 0x68, 0x90, 0xF8, + 0x51, 0x02, 0xC0, 0x07, 0x01, 0xD0, 0x02, 0x23, 0x00, 0xE0, 0x01, 0x23, + 0x32, 0x46, 0xD9, 0xF8, 0x00, 0x10, 0xD8, 0xF8, 0x00, 0x00, 0x00, 0xF0, + 0x4D, 0xF9, 0x07, 0x46, 0xCD, 0x49, 0x96, 0xF8, 0x0E, 0x01, 0x48, 0x71, + 0x00, 0x20, 0x01, 0x25, 0x05, 0x90, 0x51, 0xE0, 0x01, 0x20, 0xA8, 0x40, + 0x38, 0x42, 0x4C, 0xD0, 0x06, 0xEB, 0x85, 0x00, 0x03, 0x90, 0x06, 0xEB, + 0x45, 0x00, 0x48, 0x21, 0xB0, 0xF8, 0xB4, 0xB0, 0x20, 0x46, 0x10, 0xF0, + 0x11, 0xFB, 0x03, 0x20, 0x84, 0xF8, 0x40, 0x00, 0xD9, 0xF8, 0x00, 0x00, + 0x60, 0x60, 0xA0, 0x60, 0x84, 0xF8, 0x42, 0x50, 0xA4, 0xF8, 0x2A, 0xB0, + 0xA4, 0xF8, 0x26, 0xB0, 0xE9, 0xB2, 0x23, 0x46, 0x03, 0x9A, 0xD8, 0xF8, + 0x00, 0x00, 0x07, 0xF0, 0x40, 0xF8, 0x9A, 0xF8, 0x00, 0x00, 0x02, 0x28, + 0x10, 0xD1, 0xB7, 0x48, 0x04, 0xA9, 0xEA, 0xB2, 0xB0, 0xF9, 0x00, 0x00, + 0x02, 0x94, 0xCD, 0xE9, 0x00, 0x10, 0xD8, 0xF8, 0x00, 0x10, 0x03, 0x9B, + 0x08, 0x46, 0x07, 0xF0, 0x68, 0xF8, 0xDD, 0xE9, 0x03, 0x01, 0x01, 0x60, + 0xE0, 0x8C, 0xB0, 0xB1, 0xAD, 0x48, 0xB4, 0xF9, 0x32, 0x10, 0xB0, 0xF9, + 0x00, 0x00, 0x81, 0x42, 0x0F, 0xDD, 0x01, 0x20, 0x05, 0x90, 0xE9, 0xB2, + 0x23, 0x46, 0x03, 0x9A, 0xD8, 0xF8, 0x00, 0x00, 0x08, 0xF0, 0x4A, 0xFA, + 0xE9, 0xB2, 0x23, 0x46, 0x03, 0x9A, 0xD8, 0xF8, 0x00, 0x00, 0x06, 0xF0, + 0x91, 0xFF, 0x6D, 0x1C, 0x96, 0xF8, 0x0E, 0x01, 0xA8, 0x42, 0xA9, 0xD2, + 0x05, 0x98, 0x07, 0xB0, 0x6A, 0xE6, 0x9F, 0x49, 0x10, 0xB5, 0x09, 0x78, + 0x00, 0x20, 0x11, 0xB1, 0xFF, 0xF7, 0x67, 0xFF, 0x04, 0xE0, 0x9C, 0x49, + 0x09, 0x7A, 0x09, 0xB1, 0xFF, 0xF7, 0xBC, 0xFA, 0x9A, 0x4A, 0x00, 0x21, + 0x11, 0x70, 0x9A, 0x4A, 0x10, 0x70, 0x9A, 0x48, 0x01, 0x70, 0x10, 0xBD, + 0x10, 0xB5, 0x91, 0x4C, 0x20, 0x68, 0x90, 0xF8, 0x30, 0x12, 0x09, 0x07, + 0x1C, 0xD5, 0x96, 0x49, 0x09, 0x78, 0x11, 0xF0, 0x30, 0x0F, 0x17, 0xD0, + 0xB0, 0xF9, 0x44, 0x12, 0x01, 0x22, 0x93, 0x48, 0x00, 0xF0, 0xEB, 0xFA, + 0x20, 0x68, 0x01, 0x22, 0xB0, 0xF9, 0x46, 0x12, 0x8F, 0x48, 0x10, 0x30, + 0x00, 0xF0, 0xE3, 0xFA, 0x20, 0x68, 0x01, 0x22, 0xB0, 0xF9, 0x42, 0x12, + 0x8B, 0x48, 0xBD, 0xE8, 0x10, 0x40, 0x10, 0x38, 0x00, 0xF0, 0xD9, 0xBA, + 0x88, 0x48, 0x4F, 0xF0, 0xFF, 0x31, 0xC0, 0xE9, 0x00, 0x11, 0xC0, 0xE9, + 0x02, 0x11, 0x10, 0x38, 0xC0, 0xE9, 0x00, 0x11, 0xC0, 0xE9, 0x02, 0x11, + 0x20, 0x30, 0xC0, 0xE9, 0x00, 0x11, 0xC0, 0xE9, 0x02, 0x11, 0x10, 0xBD, + 0x2D, 0xE9, 0xFF, 0x5F, 0x15, 0x46, 0x03, 0x99, 0x91, 0xF8, 0x40, 0x10, + 0x02, 0x29, 0x0C, 0xD0, 0x01, 0x29, 0x0C, 0xD0, 0x7A, 0x49, 0x10, 0x39, + 0x8A, 0x46, 0x4F, 0xF0, 0x00, 0x0B, 0xA9, 0x78, 0x10, 0xF0, 0x5A, 0xFB, + 0x81, 0x46, 0xA8, 0x78, 0x2A, 0xE0, 0x75, 0x49, 0xF4, 0xE7, 0x74, 0x49, + 0x10, 0x31, 0xF1, 0xE7, 0x2C, 0x78, 0x1C, 0xE0, 0x19, 0xF8, 0x04, 0x10, + 0x01, 0x98, 0x81, 0x42, 0x16, 0xD1, 0x01, 0x22, 0xDA, 0xF8, 0x00, 0x00, + 0x02, 0xFA, 0x08, 0xF2, 0x10, 0x40, 0x00, 0x00, 0x24, 0xD0, 0xDA, 0xE9, + 0x02, 0x76, 0x22, 0x46, 0x01, 0x20, 0x00, 0x21, 0x10, 0xF0, 0x74, 0xF9, + 0x07, 0x40, 0x0E, 0x40, 0x37, 0x43, 0x19, 0xD0, 0x0B, 0xF1, 0x01, 0x00, + 0x1F, 0xFA, 0x80, 0xFB, 0x64, 0x1C, 0x68, 0x78, 0xA0, 0x42, 0xDF, 0xDA, + 0x09, 0xF1, 0x28, 0x09, 0x08, 0xF1, 0x01, 0x00, 0xE9, 0x78, 0x80, 0x46, + 0x41, 0x45, 0xD5, 0xDA, 0x03, 0x99, 0x5F, 0xEA, 0x0B, 0x00, 0xA1, 0xF8, + 0x26, 0xB0, 0x00, 0xD0, 0x01, 0x20, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x9F, + 0x00, 0x21, 0x09, 0xF8, 0x04, 0x10, 0xE5, 0xE7, 0x2D, 0xE9, 0xF8, 0x4F, + 0x80, 0x46, 0x4F, 0xF0, 0x00, 0x0B, 0x87, 0x78, 0x90, 0xF8, 0x03, 0xA0, + 0x23, 0xE0, 0x00, 0xBF, 0x52, 0x49, 0x01, 0x22, 0xBA, 0x40, 0x08, 0x68, + 0x98, 0xF8, 0x00, 0x40, 0x10, 0x40, 0x00, 0x90, 0xD1, 0xE9, 0x02, 0x56, + 0x98, 0xF8, 0x01, 0x90, 0x12, 0xE0, 0x00, 0x99, 0x09, 0x00, 0x0E, 0xD0, + 0x22, 0x46, 0x01, 0x20, 0x00, 0x21, 0x10, 0xF0, 0x33, 0xF9, 0x05, 0xEA, + 0x00, 0x02, 0x06, 0xEA, 0x01, 0x00, 0x02, 0x43, 0x03, 0xD0, 0x0B, 0xF1, + 0x01, 0x00, 0x1F, 0xFA, 0x80, 0xFB, 0x64, 0x1C, 0xA1, 0x45, 0xEA, 0xDA, + 0x7F, 0x1C, 0xBA, 0x45, 0xDA, 0xDA, 0xBB, 0xF1, 0x00, 0x0F, 0x01, 0xD0, + 0x01, 0x20, 0xF2, 0xE5, 0x00, 0x20, 0xF0, 0xE5, 0x2D, 0xE9, 0xF0, 0x47, + 0x91, 0x46, 0x45, 0x1C, 0x0C, 0x46, 0x4F, 0xF0, 0x01, 0x08, 0x0C, 0xE0, + 0xD9, 0xE9, 0x00, 0x67, 0x22, 0x46, 0x01, 0x20, 0x00, 0x21, 0x10, 0xF0, + 0x0D, 0xF9, 0x06, 0x40, 0x0F, 0x40, 0x3E, 0x43, 0x01, 0xD0, 0x05, 0xF8, + 0x04, 0x80, 0x64, 0x1E, 0xF0, 0xD2, 0x80, 0xE6, 0x2D, 0xE9, 0xF0, 0x47, + 0x92, 0xF8, 0x0E, 0x41, 0x86, 0xB0, 0x1D, 0x46, 0x17, 0x46, 0x89, 0x46, + 0x82, 0x46, 0xE8, 0x46, 0x05, 0x2C, 0x02, 0xD9, 0x05, 0x24, 0x01, 0x26, + 0x01, 0xE0, 0x01, 0x26, 0x0C, 0xE0, 0x07, 0xEB, 0x86, 0x03, 0x32, 0x46, + 0x49, 0x46, 0x50, 0x46, 0xFF, 0xF7, 0x3C, 0xFE, 0x08, 0xEB, 0x86, 0x01, + 0x76, 0x1C, 0x41, 0xF8, 0x04, 0x0C, 0xF6, 0xB2, 0xA6, 0x42, 0xF0, 0xD9, + 0x00, 0x20, 0x03, 0x46, 0x01, 0x22, 0x40, 0xE0, 0x00, 0x27, 0x4F, 0xF0, + 0x00, 0x46, 0x01, 0x21, 0x0F, 0xE0, 0x00, 0xBF, 0x02, 0xFA, 0x01, 0xFC, + 0x1C, 0xEA, 0x00, 0x0F, 0x07, 0xD1, 0x08, 0xEB, 0x81, 0x0C, 0x5C, 0xF8, + 0x04, 0xCC, 0xB4, 0x45, 0x01, 0xDD, 0x66, 0x46, 0x0F, 0x46, 0x49, 0x1C, + 0xC9, 0xB2, 0xA1, 0x42, 0xEE, 0xD9, 0x02, 0xFA, 0x07, 0xF1, 0x08, 0x43, + 0x5B, 0x1C, 0x23, 0xE0, 0xEE, 0x06, 0x10, 0x00, 0xED, 0x06, 0x10, 0x00, + 0x58, 0x05, 0x10, 0x00, 0x88, 0x06, 0x10, 0x00, 0x50, 0x06, 0x10, 0x00, + 0x66, 0x05, 0x10, 0x00, 0x14, 0x07, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x0A, 0x44, 0x01, 0x20, 0x92, 0x06, 0x10, 0x00, 0x57, 0x05, 0x10, 0x00, + 0x0C, 0x2A, 0x10, 0x00, 0xF6, 0x06, 0x10, 0x00, 0xF7, 0x06, 0x10, 0x00, + 0xF8, 0x06, 0x10, 0x00, 0x04, 0x07, 0x10, 0x00, 0xA8, 0x2A, 0x10, 0x00, + 0x50, 0x2B, 0x10, 0x00, 0xDB, 0xB2, 0xAB, 0x42, 0xBC, 0xD3, 0x06, 0xB0, + 0x17, 0xE6, 0x00, 0x00, 0xA1, 0x4A, 0x10, 0xB5, 0x13, 0x68, 0x00, 0x21, + 0xB3, 0xF8, 0x14, 0x22, 0x82, 0x42, 0x05, 0xDA, 0x93, 0xF8, 0x10, 0x22, + 0x52, 0x07, 0x01, 0xD5, 0x02, 0x21, 0x08, 0xE0, 0xB3, 0xF8, 0x12, 0x22, + 0x82, 0x42, 0x04, 0xDA, 0x93, 0xF8, 0x10, 0x02, 0x80, 0x07, 0x00, 0xD5, + 0x01, 0x21, 0x97, 0x48, 0x97, 0x4C, 0x42, 0x78, 0x91, 0x42, 0x14, 0xD1, + 0xA1, 0x78, 0x91, 0x42, 0x0D, 0xD0, 0x95, 0x4B, 0x1B, 0x78, 0x1A, 0x43, + 0x94, 0x4B, 0x1B, 0x78, 0x1A, 0x43, 0x07, 0xD0, 0x41, 0x68, 0x49, 0x1E, + 0x41, 0x60, 0x00, 0x29, 0x01, 0xDC, 0x40, 0x78, 0xA0, 0x70, 0x10, 0xBD, + 0x41, 0x70, 0x41, 0x68, 0xF7, 0xE7, 0x59, 0xB1, 0x02, 0x29, 0x01, 0xD1, + 0x01, 0x2A, 0x07, 0xD0, 0x93, 0xF8, 0x18, 0x22, 0x42, 0x60, 0x41, 0x70, + 0x00, 0x2A, 0xF0, 0xDC, 0xA1, 0x70, 0x10, 0xBD, 0x93, 0xF8, 0x19, 0x22, + 0xF6, 0xE7, 0x70, 0xB5, 0x85, 0x4A, 0x86, 0x4B, 0x81, 0x4D, 0x16, 0x78, + 0x7E, 0x4A, 0x1C, 0x78, 0x00, 0x21, 0x12, 0x68, 0xAB, 0x78, 0x01, 0x2E, + 0x02, 0xD1, 0x82, 0x4E, 0x36, 0x78, 0x4E, 0xB1, 0xB2, 0xF8, 0x14, 0x62, + 0x86, 0x42, 0x17, 0xDA, 0x92, 0xF8, 0x10, 0x62, 0x76, 0x07, 0x13, 0xD5, + 0x02, 0x21, 0x25, 0xE0, 0xB2, 0xF8, 0x1C, 0x62, 0x86, 0x42, 0x03, 0xDA, + 0x92, 0xF8, 0x10, 0x62, 0x76, 0x07, 0xF5, 0xD4, 0xB2, 0xF8, 0x1A, 0x62, + 0x08, 0xE0, 0x00, 0xBF, 0x92, 0xF8, 0x10, 0x02, 0x80, 0x07, 0x05, 0xD5, + 0x01, 0x21, 0x13, 0xE0, 0xB2, 0xF8, 0x12, 0x62, 0x86, 0x42, 0xF5, 0xDB, + 0x73, 0xB1, 0x6C, 0x48, 0x00, 0x78, 0x01, 0x28, 0x03, 0xD0, 0x6B, 0x48, + 0x00, 0x78, 0x01, 0x28, 0x03, 0xD1, 0x92, 0xF8, 0x10, 0x02, 0x00, 0x07, + 0x01, 0xD5, 0x01, 0x2C, 0x00, 0xD1, 0x19, 0x46, 0x62, 0x48, 0x34, 0xB1, + 0x19, 0xB1, 0x00, 0xBF, 0x92, 0xF8, 0x19, 0x22, 0x42, 0x60, 0xA9, 0x70, + 0x70, 0xBD, 0x00, 0x29, 0xF8, 0xD1, 0x00, 0x2B, 0xF6, 0xD0, 0x44, 0x68, + 0x00, 0x2C, 0xF6, 0xDD, 0x92, 0xF8, 0x10, 0x12, 0x0A, 0x07, 0x59, 0x49, + 0x49, 0x68, 0xA1, 0xF1, 0x01, 0x01, 0x02, 0xD5, 0x5D, 0x4A, 0x12, 0x78, + 0x02, 0xB1, 0x41, 0x60, 0x19, 0x46, 0xE8, 0xE7, 0x52, 0x48, 0x53, 0x49, + 0x00, 0x68, 0x90, 0xF8, 0x10, 0x02, 0xC2, 0x06, 0x4F, 0xF0, 0x00, 0x00, + 0x03, 0xD4, 0x50, 0x4A, 0x90, 0x70, 0x48, 0x70, 0x48, 0x60, 0x08, 0x70, + 0x70, 0x47, 0x10, 0xB5, 0x04, 0x46, 0x4A, 0x48, 0x00, 0x68, 0x90, 0xF8, + 0x10, 0x02, 0xC0, 0x06, 0x20, 0x46, 0x02, 0xD5, 0xFF, 0xF7, 0x89, 0xFF, + 0x01, 0xE0, 0xFF, 0xF7, 0x45, 0xFF, 0x46, 0x48, 0x82, 0x78, 0x4C, 0x48, + 0x41, 0x7B, 0x62, 0xF3, 0x07, 0x11, 0x41, 0x73, 0xA0, 0xF8, 0x2F, 0x40, + 0x10, 0xBD, 0x2D, 0xE9, 0xFC, 0x5F, 0x83, 0x46, 0x47, 0x48, 0x00, 0x25, + 0x0A, 0x46, 0x00, 0x78, 0x2F, 0x46, 0x2C, 0x46, 0x01, 0x28, 0x00, 0xD1, + 0x01, 0x24, 0x44, 0x48, 0x06, 0x78, 0x00, 0x78, 0x41, 0x00, 0x01, 0x2A, + 0x1B, 0xD0, 0xDF, 0xF8, 0xD8, 0x80, 0xDF, 0xF8, 0x04, 0xA1, 0xDF, 0xF8, + 0x04, 0x91, 0xD8, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0x10, 0x22, 0x92, 0x06, + 0x14, 0xD5, 0x32, 0x1B, 0xB0, 0xF9, 0x20, 0x12, 0xCD, 0xE9, 0x00, 0x12, + 0xB0, 0xF9, 0x1E, 0x32, 0x0A, 0xEB, 0x44, 0x02, 0x0B, 0xEB, 0x44, 0x01, + 0x09, 0xEB, 0x44, 0x00, 0x0C, 0xF0, 0x72, 0xFF, 0x09, 0xE0, 0x34, 0x48, + 0x4C, 0x38, 0x10, 0xF0, 0x59, 0xF8, 0x41, 0xE0, 0x0A, 0x46, 0x59, 0x46, + 0x31, 0x48, 0x0F, 0xF0, 0xD4, 0xFF, 0x2F, 0x48, 0x4C, 0x38, 0x34, 0xE0, + 0x3A, 0xF9, 0x14, 0x20, 0x39, 0xF9, 0x14, 0x10, 0x51, 0x1A, 0x00, 0xD5, + 0x49, 0x42, 0xD8, 0xF8, 0x00, 0x30, 0x09, 0xB2, 0x93, 0xF8, 0x10, 0x22, + 0x52, 0x06, 0x0B, 0xD5, 0x20, 0x4A, 0x12, 0x78, 0x01, 0x2A, 0x07, 0xD1, + 0x26, 0x4A, 0x12, 0x78, 0x22, 0xB9, 0xB3, 0xF8, 0x22, 0x22, 0x8A, 0x42, + 0x00, 0xDA, 0x01, 0x27, 0x30, 0xF9, 0x14, 0x20, 0x8A, 0x42, 0x02, 0xDA, + 0x93, 0xF8, 0x16, 0x32, 0x01, 0xE0, 0x93, 0xF8, 0x17, 0x32, 0x5A, 0x43, + 0xC3, 0xF5, 0x80, 0x73, 0x01, 0xFB, 0x03, 0x21, 0xCA, 0x17, 0x01, 0xEB, + 0x12, 0x61, 0x09, 0x12, 0x20, 0xF8, 0x14, 0x10, 0x30, 0xF9, 0x14, 0x10, + 0xA9, 0x42, 0x00, 0xDD, 0x0D, 0x46, 0x64, 0x1C, 0x24, 0xB2, 0xB4, 0x42, + 0xC8, 0xDB, 0x28, 0x46, 0xFF, 0xF7, 0x73, 0xFF, 0x72, 0x00, 0x59, 0x46, + 0x0F, 0x48, 0x0F, 0xF0, 0x92, 0xFF, 0x03, 0x48, 0x07, 0x70, 0xBD, 0xE8, + 0xFC, 0x9F, 0x00, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x5C, 0x05, 0x10, 0x00, + 0x74, 0x07, 0x10, 0x00, 0xF5, 0x06, 0x10, 0x00, 0x64, 0x05, 0x10, 0x00, + 0xF6, 0x06, 0x10, 0x00, 0xFD, 0x06, 0x10, 0x00, 0xF7, 0x06, 0x10, 0x00, + 0xFA, 0x06, 0x10, 0x00, 0x0A, 0x44, 0x01, 0x20, 0xF4, 0x06, 0x10, 0x00, + 0xED, 0x06, 0x10, 0x00, 0x54, 0x0A, 0x01, 0x20, 0xA0, 0x0A, 0x01, 0x20, + 0x74, 0x05, 0x10, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x81, 0x46, 0xDD, 0xE9, + 0x09, 0xB5, 0x01, 0x20, 0x47, 0xF6, 0xFF, 0x77, 0x9A, 0x46, 0x84, 0x46, + 0xFE, 0x43, 0x2C, 0x46, 0x15, 0xE0, 0x00, 0xBF, 0x32, 0xF8, 0x14, 0x30, + 0x31, 0xF8, 0x14, 0x80, 0xA3, 0xEB, 0x08, 0x03, 0x1B, 0xB2, 0xBB, 0x42, + 0x00, 0xDA, 0x1F, 0x46, 0xB3, 0x42, 0x00, 0xDD, 0x1E, 0x46, 0x00, 0x2B, + 0x02, 0xDD, 0x4F, 0xF0, 0x00, 0x0C, 0x02, 0xE0, 0x01, 0xDA, 0x4F, 0xF0, + 0x00, 0x00, 0x64, 0x1E, 0xE8, 0xD2, 0x20, 0xB1, 0xBC, 0xF1, 0x00, 0x0F, + 0x01, 0xD0, 0x00, 0x23, 0x09, 0xE0, 0x50, 0xEA, 0x0C, 0x03, 0x06, 0xD0, + 0x20, 0xB9, 0xBC, 0xF1, 0x00, 0x0F, 0x01, 0xD0, 0x33, 0x46, 0x00, 0xE0, + 0x3B, 0x46, 0x00, 0x27, 0x3C, 0x46, 0x28, 0x46, 0xCB, 0xF1, 0x00, 0x0C, + 0x0E, 0xE0, 0x00, 0xBF, 0x32, 0xF8, 0x10, 0x60, 0x31, 0xF8, 0x10, 0x80, + 0xA6, 0xEB, 0x08, 0x06, 0xF6, 0x1A, 0x36, 0xB2, 0x56, 0x45, 0x03, 0xDA, + 0x66, 0x45, 0x01, 0xDD, 0x37, 0x44, 0x64, 0x1C, 0x40, 0x1E, 0xEF, 0xD2, + 0x04, 0xB9, 0x01, 0x24, 0x97, 0xFB, 0xF4, 0xF0, 0x18, 0x44, 0x04, 0xE0, + 0x31, 0xF8, 0x15, 0x20, 0x02, 0x44, 0x29, 0xF8, 0x15, 0x20, 0x6D, 0x1E, + 0xF8, 0xD2, 0xBD, 0xE8, 0xF0, 0x8F, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, + 0x03, 0x46, 0xFC, 0x48, 0x15, 0x46, 0x0E, 0x46, 0x0A, 0x46, 0x01, 0x78, + 0xFA, 0x48, 0x00, 0xF0, 0x51, 0xFA, 0xFA, 0x48, 0x04, 0xF1, 0x08, 0x03, + 0x1F, 0x46, 0x01, 0x78, 0xF6, 0x48, 0x32, 0x46, 0x2A, 0x30, 0x00, 0xF0, + 0x47, 0xFA, 0x00, 0x2D, 0x07, 0xD0, 0x20, 0x46, 0x10, 0xF0, 0x6C, 0xF8, + 0x38, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x10, 0xF0, 0x67, 0xB8, 0xBD, 0xE8, + 0xF0, 0x81, 0x2D, 0xE9, 0xFC, 0x41, 0x07, 0x46, 0x14, 0x46, 0x88, 0x46, + 0x03, 0x20, 0xF9, 0xF7, 0xD6, 0xF9, 0xEC, 0x4D, 0xE8, 0x4E, 0x00, 0x94, + 0xE8, 0x48, 0x32, 0x78, 0x39, 0x46, 0x76, 0x38, 0x2B, 0x68, 0x0C, 0xF0, + 0xF9, 0xFE, 0x00, 0x94, 0xE5, 0x4C, 0xE4, 0x48, 0x41, 0x46, 0x22, 0x78, + 0x4C, 0x38, 0x2B, 0x68, 0x0C, 0xF0, 0xF0, 0xFE, 0xE3, 0x4D, 0x28, 0x68, + 0x90, 0xF8, 0x30, 0x12, 0xC9, 0x07, 0x1A, 0xD0, 0x32, 0x78, 0xB0, 0xF9, + 0x34, 0x12, 0xCD, 0xE9, 0x00, 0x12, 0xDB, 0x49, 0xB0, 0xF9, 0x32, 0x32, + 0x76, 0x39, 0xDD, 0x4A, 0x08, 0x46, 0xFF, 0xF7, 0x55, 0xFF, 0x28, 0x68, + 0x22, 0x78, 0xB0, 0xF9, 0x38, 0x12, 0xCD, 0xE9, 0x00, 0x12, 0xD4, 0x49, + 0xB0, 0xF9, 0x36, 0x32, 0x4C, 0x39, 0xD7, 0x4A, 0x08, 0x46, 0xFF, 0xF7, + 0x47, 0xFF, 0xD0, 0x49, 0x33, 0x78, 0xD3, 0x4A, 0x76, 0x39, 0xCE, 0x48, + 0x0C, 0xF0, 0xBB, 0xFE, 0xCC, 0x49, 0x23, 0x78, 0x4C, 0x39, 0xD0, 0x4A, + 0x01, 0xF1, 0x76, 0x00, 0x0C, 0xF0, 0xB3, 0xFE, 0x28, 0x68, 0x90, 0xF8, + 0x30, 0x12, 0x8A, 0x07, 0x04, 0xD4, 0xCC, 0x4A, 0x12, 0x78, 0x8A, 0xB1, + 0x49, 0x07, 0x0F, 0xD5, 0xC3, 0x49, 0x90, 0xF8, 0x41, 0x32, 0x32, 0x78, + 0x08, 0x46, 0x0C, 0xF0, 0xE2, 0xFE, 0x28, 0x68, 0xBF, 0x49, 0x22, 0x78, + 0x90, 0xF8, 0x41, 0x32, 0x2A, 0x31, 0x08, 0x46, 0x0C, 0xF0, 0xD9, 0xFE, + 0xBD, 0xE8, 0xFC, 0x41, 0x03, 0x20, 0xF9, 0xF7, 0x8F, 0xB9, 0x70, 0xB5, + 0xBF, 0x4C, 0xC0, 0x49, 0x00, 0x25, 0xA5, 0x70, 0x01, 0x20, 0x08, 0x70, + 0xB8, 0x48, 0x25, 0x70, 0x65, 0x70, 0x00, 0x68, 0xB0, 0xF8, 0x3A, 0x02, + 0xA0, 0x80, 0x00, 0xF0, 0xE3, 0xF9, 0xFF, 0xF7, 0xEE, 0xF8, 0xA5, 0x60, + 0xE5, 0x60, 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x0E, 0x46, 0xB5, 0x49, + 0x07, 0x46, 0xB3, 0x4C, 0x0D, 0x78, 0x00, 0x20, 0x08, 0x70, 0x60, 0x70, + 0x00, 0xF0, 0xD2, 0xF9, 0xB1, 0x48, 0x2A, 0x46, 0x31, 0x46, 0x00, 0x78, + 0x00, 0x28, 0x38, 0x46, 0x02, 0xD0, 0xFF, 0xF7, 0x45, 0xF8, 0x01, 0xE0, + 0xFF, 0xF7, 0x69, 0xFF, 0xAC, 0x48, 0x41, 0x78, 0xA4, 0x48, 0xA9, 0xB1, + 0xA1, 0x78, 0x01, 0x29, 0x12, 0xD0, 0x00, 0x68, 0xB0, 0xF9, 0x3C, 0x12, + 0xA8, 0x4D, 0xA1, 0x80, 0x01, 0x22, 0x28, 0x46, 0xFF, 0xF7, 0x37, 0xFF, + 0xD5, 0xE9, 0x00, 0x01, 0x08, 0x43, 0x09, 0xD0, 0xD5, 0xE9, 0x02, 0x01, + 0x08, 0x43, 0x05, 0xD0, 0x01, 0x20, 0x04, 0xE0, 0x00, 0x68, 0xB0, 0xF9, + 0x3A, 0x12, 0xEB, 0xE7, 0x00, 0x20, 0x20, 0x70, 0x45, 0xE7, 0x2D, 0xE9, + 0xF0, 0x4F, 0x04, 0x46, 0x9C, 0x48, 0xA7, 0xB0, 0x4F, 0xF0, 0x01, 0x09, + 0x01, 0x78, 0x91, 0x48, 0x01, 0x29, 0x00, 0x68, 0x15, 0xD0, 0x92, 0x49, + 0x09, 0x78, 0xA9, 0xB1, 0xB0, 0xF9, 0x54, 0x62, 0x88, 0x48, 0x00, 0x21, + 0x4F, 0xF0, 0x01, 0x0A, 0x00, 0x78, 0x94, 0x4D, 0x40, 0x1E, 0x00, 0xF0, + 0xFF, 0x08, 0x86, 0x48, 0x83, 0x46, 0x03, 0x78, 0x9A, 0x1E, 0x02, 0xF0, + 0xFF, 0x0C, 0x22, 0x46, 0x13, 0xE0, 0xB0, 0xF9, 0x59, 0x62, 0xEB, 0xE7, + 0xB0, 0xF9, 0x52, 0x62, 0xE8, 0xE7, 0x50, 0x46, 0x06, 0xE0, 0x00, 0xBF, + 0x32, 0xF9, 0x10, 0x70, 0xAF, 0x42, 0x00, 0xDD, 0x3D, 0x46, 0x40, 0x1C, + 0x60, 0x45, 0xF7, 0xDD, 0x02, 0xEB, 0x43, 0x02, 0x49, 0x1C, 0x41, 0x45, + 0xEF, 0xDD, 0x5F, 0x46, 0x5A, 0x00, 0x04, 0xEB, 0x43, 0x01, 0x68, 0x46, + 0x0F, 0xF0, 0xFB, 0xFD, 0x80, 0x4A, 0x38, 0x78, 0x6B, 0x46, 0x12, 0x88, + 0x41, 0x42, 0x02, 0xEB, 0x41, 0x01, 0x09, 0xB2, 0x42, 0x00, 0x04, 0xEB, + 0x41, 0x01, 0x03, 0xEB, 0x40, 0x00, 0x0F, 0xF0, 0xEC, 0xFD, 0x38, 0x78, + 0x69, 0x46, 0x42, 0x00, 0x08, 0x46, 0x0C, 0xF0, 0x50, 0xFE, 0x28, 0x1A, + 0x00, 0xB2, 0xB0, 0x42, 0x01, 0xDD, 0x4F, 0xF0, 0x00, 0x09, 0x48, 0x46, + 0x27, 0xB0, 0xC6, 0xE6, 0x2D, 0xE9, 0xF0, 0x4F, 0x71, 0x49, 0x70, 0x4A, + 0x00, 0x27, 0x0C, 0x68, 0xB2, 0xF9, 0x00, 0x20, 0x4F, 0xF0, 0x01, 0x0A, + 0x21, 0x8E, 0x3B, 0x46, 0x91, 0x42, 0x49, 0xD1, 0x62, 0x49, 0x0A, 0x78, + 0x5E, 0x49, 0x0E, 0x68, 0x8A, 0xB1, 0xB6, 0xF9, 0x54, 0x12, 0x00, 0x25, + 0x89, 0x46, 0x57, 0x49, 0x4F, 0xF0, 0x02, 0x0E, 0x09, 0x78, 0x49, 0x1E, + 0x01, 0xF0, 0xFF, 0x0B, 0x55, 0x49, 0x09, 0x78, 0xC9, 0x1E, 0x01, 0xF0, + 0xFF, 0x0C, 0x32, 0x34, 0x2A, 0xE0, 0xB6, 0xF9, 0x52, 0x12, 0xEC, 0xE7, + 0x72, 0x46, 0x1C, 0xE0, 0x34, 0xF8, 0x12, 0x10, 0x30, 0xF8, 0x12, 0x80, + 0xA1, 0xEB, 0x08, 0x01, 0x09, 0xB2, 0x00, 0x29, 0x01, 0xDB, 0x88, 0x46, + 0x01, 0xE0, 0xC1, 0xF1, 0x00, 0x08, 0xB8, 0x45, 0x05, 0xDD, 0x00, 0x29, + 0x01, 0xDB, 0x0F, 0x46, 0x00, 0xE0, 0x4F, 0x42, 0x3F, 0xB2, 0x00, 0x29, + 0x00, 0xDA, 0x49, 0x42, 0x49, 0x45, 0x01, 0xDD, 0x5B, 0x1C, 0x9B, 0xB2, + 0x52, 0x1C, 0x62, 0x45, 0xE0, 0xDD, 0x96, 0xF8, 0x30, 0x10, 0x6D, 0x1C, + 0x04, 0xEB, 0x41, 0x04, 0x00, 0xEB, 0x41, 0x00, 0x5D, 0x45, 0xD5, 0xDD, + 0x96, 0xF8, 0x56, 0x02, 0x98, 0x42, 0x01, 0xD2, 0x4F, 0xF0, 0x00, 0x0A, + 0x47, 0x48, 0x20, 0xF8, 0x33, 0x7F, 0x83, 0x70, 0x50, 0x46, 0x68, 0xE6, + 0x2D, 0xE9, 0xF0, 0x41, 0x06, 0x46, 0x44, 0x48, 0x00, 0x24, 0x00, 0x78, + 0xC0, 0x06, 0x5E, 0xD5, 0x3C, 0x48, 0x36, 0x4D, 0x00, 0x78, 0x88, 0xB1, + 0x40, 0x48, 0x31, 0x4B, 0x34, 0x49, 0x02, 0x68, 0x18, 0x68, 0x08, 0x31, + 0xB0, 0xF8, 0x5D, 0x02, 0x40, 0x42, 0x07, 0xB2, 0x00, 0x20, 0xC8, 0x80, + 0x88, 0x80, 0x08, 0x60, 0x35, 0x48, 0xB0, 0xF9, 0x00, 0x00, 0x29, 0xE0, + 0x2C, 0x48, 0x2C, 0x78, 0x00, 0x78, 0x08, 0xB1, 0x01, 0x29, 0x02, 0xD0, + 0x08, 0x43, 0x02, 0xD0, 0x3B, 0xE0, 0x01, 0x24, 0x3A, 0xE0, 0x00, 0x24, + 0x67, 0xE0, 0x00, 0xBF, 0x32, 0xF9, 0x10, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, + 0x16, 0xDA, 0xB1, 0xF8, 0x04, 0xC0, 0x0C, 0xF1, 0x01, 0x0C, 0xA1, 0xF8, + 0x04, 0xC0, 0x32, 0xF9, 0x10, 0xE0, 0xD1, 0xF8, 0x00, 0xC0, 0xF4, 0x44, + 0xC1, 0xF8, 0x00, 0xC0, 0x32, 0xF9, 0x10, 0xC0, 0xBC, 0x45, 0x05, 0xDA, + 0xB1, 0xF8, 0x06, 0xC0, 0x0C, 0xF1, 0x01, 0x0C, 0xA1, 0xF8, 0x06, 0xC0, + 0x40, 0x1E, 0xE1, 0xD2, 0x08, 0x68, 0x40, 0x42, 0x08, 0x60, 0x15, 0x48, + 0x19, 0x68, 0x08, 0x30, 0x02, 0x68, 0xB1, 0xF8, 0x5F, 0x32, 0x9A, 0x42, + 0x3D, 0xDD, 0xB0, 0xF9, 0x06, 0x00, 0x91, 0xF8, 0x61, 0x12, 0x88, 0x42, + 0x37, 0xDD, 0x1A, 0x48, 0x11, 0x4A, 0xB0, 0xF9, 0x00, 0x10, 0x30, 0x46, + 0x00, 0xF0, 0x20, 0xF9, 0x04, 0x46, 0x6C, 0xB3, 0x00, 0xF0, 0xF2, 0xF8, + 0x2D, 0xE0, 0x3D, 0xE0, 0xED, 0x06, 0x10, 0x00, 0x94, 0x0B, 0x01, 0x20, + 0xEE, 0x06, 0x10, 0x00, 0x9C, 0x06, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x7E, 0x4A, 0x01, 0x20, 0xA8, 0x4A, 0x01, 0x20, 0x74, 0x05, 0x10, 0x00, + 0x64, 0x05, 0x10, 0x00, 0x7A, 0x07, 0x10, 0x00, 0xF4, 0x06, 0x10, 0x00, + 0x74, 0x07, 0x10, 0x00, 0x40, 0x2B, 0x10, 0x00, 0x79, 0x05, 0x10, 0x00, + 0x00, 0x80, 0xFF, 0xFF, 0xFE, 0x06, 0x10, 0x00, 0x50, 0x07, 0x10, 0x00, + 0x0A, 0x44, 0x01, 0x20, 0x04, 0x07, 0x10, 0x00, 0x14, 0x07, 0x10, 0x00, + 0x98, 0x06, 0x10, 0x00, 0xFF, 0xE7, 0x00, 0xF0, 0xD9, 0xF8, 0x51, 0x4E, + 0x28, 0x78, 0x31, 0x78, 0x88, 0x42, 0x06, 0xD0, 0x08, 0xB1, 0x01, 0x21, + 0x00, 0xE0, 0x00, 0x21, 0x06, 0x20, 0x0B, 0xF0, 0xEC, 0xF8, 0x28, 0x78, + 0x30, 0x70, 0x0C, 0xB1, 0x01, 0x20, 0xE4, 0xE5, 0x00, 0x20, 0xE2, 0xE5, + 0x70, 0xB5, 0x03, 0x20, 0xF8, 0xF7, 0xBF, 0xFF, 0x00, 0xF0, 0x48, 0xF8, + 0x04, 0x46, 0x03, 0x20, 0xF8, 0xF7, 0xD4, 0xFF, 0x43, 0x49, 0xC8, 0x7B, + 0x64, 0xF3, 0x05, 0x10, 0xC8, 0x73, 0x42, 0x48, 0x01, 0x78, 0x21, 0xB1, + 0x00, 0x21, 0x01, 0x70, 0x20, 0x46, 0x00, 0xF0, 0x30, 0xF9, 0x3F, 0x4D, + 0x3F, 0x48, 0x21, 0x46, 0x2A, 0x78, 0x00, 0x68, 0xFF, 0xF7, 0x3A, 0xFF, + 0xA8, 0x70, 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x47, 0x1D, 0x46, 0x4F, 0xF0, + 0x00, 0x08, 0xC5, 0xE9, 0x00, 0x88, 0x91, 0x46, 0x82, 0x46, 0x0C, 0x46, + 0x11, 0xE0, 0x00, 0xBF, 0x3A, 0xF9, 0x14, 0x10, 0x49, 0x45, 0x0C, 0xDD, + 0xD5, 0xE9, 0x00, 0x67, 0x4F, 0xF0, 0x01, 0x08, 0x22, 0x46, 0x40, 0x46, + 0x00, 0x21, 0x0F, 0xF0, 0x67, 0xFC, 0x06, 0x43, 0x0F, 0x43, 0xC5, 0xE9, + 0x00, 0x67, 0x64, 0x1E, 0xEC, 0xD2, 0x40, 0x46, 0xBD, 0xE8, 0xF0, 0x87, + 0x2B, 0x48, 0x00, 0x21, 0xC0, 0xE9, 0x00, 0x11, 0xC0, 0xE9, 0x02, 0x11, + 0x08, 0x46, 0x29, 0x49, 0x08, 0x76, 0x29, 0x49, 0x08, 0x76, 0x70, 0x47, + 0x2D, 0xE9, 0xF0, 0x41, 0x27, 0x48, 0x00, 0x78, 0x02, 0x28, 0x35, 0xD9, + 0x26, 0x4E, 0x30, 0x68, 0x90, 0xF8, 0x50, 0x02, 0x41, 0x07, 0x25, 0x48, + 0x00, 0x68, 0x02, 0xD5, 0x24, 0x49, 0x09, 0x78, 0x81, 0xB1, 0xFF, 0xF7, + 0x3C, 0xFE, 0x05, 0x46, 0x30, 0x68, 0x90, 0xF8, 0x50, 0x02, 0x00, 0x07, + 0x21, 0xD5, 0x22, 0x48, 0x1F, 0x4B, 0x20, 0x49, 0x02, 0x78, 0x02, 0x2A, + 0x1B, 0xDB, 0x20, 0x4C, 0x50, 0x1E, 0x08, 0xE0, 0xFF, 0xF7, 0x88, 0xFE, + 0xED, 0xE7, 0x00, 0xBF, 0x33, 0xF9, 0x10, 0x70, 0xA7, 0x42, 0x00, 0xDD, + 0x3C, 0x46, 0x40, 0x1E, 0xF8, 0xD1, 0x98, 0x1C, 0x92, 0x1E, 0x0C, 0xF0, + 0xC2, 0xFC, 0x31, 0x68, 0x20, 0x1A, 0x00, 0xB2, 0xB1, 0xF9, 0x57, 0x12, + 0x88, 0x42, 0x02, 0xDD, 0x35, 0xB1, 0x02, 0x20, 0x59, 0xE5, 0x0D, 0xB1, + 0x00, 0x20, 0x56, 0xE5, 0x01, 0x20, 0x54, 0xE5, 0x03, 0x20, 0x52, 0xE5, + 0x75, 0x05, 0x10, 0x00, 0x0A, 0x44, 0x01, 0x20, 0x78, 0x05, 0x10, 0x00, + 0x64, 0x05, 0x10, 0x00, 0x14, 0x07, 0x10, 0x00, 0x40, 0x2B, 0x10, 0x00, + 0x18, 0x2A, 0x10, 0x00, 0x58, 0x2A, 0x10, 0x00, 0xED, 0x06, 0x10, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x1C, 0x07, 0x10, 0x00, 0x79, 0x05, 0x10, 0x00, + 0xA8, 0x4A, 0x01, 0x20, 0xCE, 0x0A, 0x01, 0x20, 0xEE, 0x06, 0x10, 0x00, + 0x00, 0x80, 0xFF, 0xFF, 0xFE, 0x48, 0x00, 0x21, 0xC1, 0x70, 0x02, 0x78, + 0x00, 0x2A, 0x0E, 0xD1, 0x82, 0x78, 0xFC, 0x4B, 0x52, 0x1C, 0xD2, 0xB2, + 0x82, 0x70, 0x1B, 0x68, 0x93, 0xF8, 0x62, 0x32, 0x03, 0xF0, 0x0F, 0x03, + 0x93, 0x42, 0x02, 0xD2, 0x01, 0x22, 0x02, 0x70, 0x81, 0x70, 0x70, 0x47, + 0xF3, 0x48, 0x00, 0x21, 0x81, 0x70, 0x02, 0x78, 0x00, 0x2A, 0x0C, 0xD0, + 0xC2, 0x78, 0xF1, 0x4B, 0x52, 0x1C, 0xD2, 0xB2, 0xC2, 0x70, 0x1B, 0x68, + 0x93, 0xF8, 0x62, 0x32, 0xB2, 0xEB, 0x13, 0x1F, 0x01, 0xD9, 0x01, 0x70, + 0xC1, 0x70, 0x70, 0x47, 0x2D, 0xE9, 0xF7, 0x4F, 0x86, 0xB0, 0x8A, 0x46, + 0xD2, 0xE9, 0x00, 0x01, 0xCD, 0xE9, 0x00, 0x01, 0xD2, 0xE9, 0x02, 0x01, + 0xCD, 0xE9, 0x04, 0x01, 0x68, 0x46, 0x0F, 0xF0, 0x61, 0xFD, 0x04, 0xA8, + 0x0F, 0xF0, 0x5E, 0xFD, 0xE2, 0x48, 0x00, 0x27, 0xB9, 0x46, 0x06, 0x78, + 0x28, 0xE0, 0xF1, 0xB2, 0x06, 0x98, 0x0F, 0xF0, 0x6B, 0xFD, 0x80, 0x46, + 0xDE, 0x48, 0xDD, 0xE9, 0x04, 0xB1, 0x05, 0x78, 0x01, 0x24, 0x00, 0x98, + 0xB4, 0x40, 0x04, 0x40, 0x02, 0x91, 0x17, 0xE0, 0x38, 0xF9, 0x15, 0x10, + 0x51, 0x45, 0x13, 0xDD, 0x20, 0x00, 0x0F, 0xD0, 0x2A, 0x46, 0x01, 0x20, + 0x00, 0x21, 0x0F, 0xF0, 0x95, 0xFB, 0x02, 0x9A, 0x00, 0xEA, 0x0B, 0x00, + 0x11, 0x40, 0x08, 0x43, 0x04, 0xD0, 0x09, 0xF1, 0x01, 0x00, 0x1F, 0xFA, + 0x80, 0xF9, 0x01, 0xE0, 0x7F, 0x1C, 0xBF, 0xB2, 0x6D, 0x1E, 0xE5, 0xD2, + 0x76, 0x1E, 0xD4, 0xD2, 0xC9, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x5B, 0x12, + 0xB9, 0x42, 0x07, 0xD8, 0x90, 0xF8, 0x5C, 0x12, 0x49, 0x45, 0x03, 0xD3, + 0x01, 0x20, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x20, 0xFA, 0xE7, + 0xC0, 0x48, 0x10, 0xB5, 0x41, 0x78, 0x01, 0x70, 0x00, 0x21, 0x81, 0x70, + 0xC1, 0x70, 0xFF, 0xF7, 0x1A, 0xFD, 0xBD, 0xE8, 0x10, 0x40, 0xFE, 0xF7, + 0x59, 0xBE, 0xBA, 0x48, 0x00, 0x21, 0xBA, 0x4A, 0x01, 0x70, 0x41, 0x70, + 0x12, 0x68, 0x92, 0xF8, 0x50, 0x22, 0x92, 0x07, 0x00, 0xD5, 0x01, 0x21, + 0x41, 0x71, 0x01, 0x71, 0x70, 0x47, 0xB3, 0x49, 0x4A, 0x79, 0x01, 0x2A, + 0x02, 0xD1, 0x00, 0x28, 0x00, 0xD1, 0x48, 0x71, 0x70, 0x47, 0xF0, 0xB5, + 0x00, 0x24, 0x1C, 0x72, 0x04, 0x7E, 0x0D, 0x7E, 0x6C, 0x43, 0x04, 0xF0, + 0xFF, 0x0C, 0x4F, 0xF0, 0xFF, 0x34, 0xE7, 0x07, 0x26, 0x46, 0x00, 0x25, + 0x08, 0xE0, 0x00, 0xBF, 0x52, 0xF8, 0x25, 0xE0, 0xBE, 0x45, 0x01, 0xDD, + 0x77, 0x46, 0x6E, 0xB2, 0x6D, 0x1C, 0xED, 0xB2, 0x65, 0x45, 0xF5, 0xD3, + 0x00, 0x2E, 0x17, 0xDB, 0x01, 0x25, 0x1D, 0x72, 0x0D, 0x7E, 0x96, 0xFB, + 0xF5, 0xF5, 0x6D, 0x1C, 0xED, 0xB2, 0x05, 0x44, 0xAF, 0x7C, 0x1F, 0x70, + 0x2D, 0x7B, 0x1D, 0x71, 0x0D, 0x7E, 0x96, 0xFB, 0xF5, 0xF7, 0x05, 0xFB, + 0x17, 0x65, 0x6D, 0x1C, 0xED, 0xB2, 0x0D, 0x44, 0xAF, 0x7C, 0x9F, 0x70, + 0x2D, 0x7B, 0x9D, 0x71, 0xBC, 0xF1, 0x01, 0x0F, 0x30, 0xD9, 0x95, 0x4D, + 0x2D, 0x68, 0x95, 0xF8, 0x51, 0x52, 0xED, 0x07, 0x2A, 0xD0, 0x25, 0x46, + 0x00, 0x27, 0x3C, 0x46, 0x0A, 0xE0, 0x00, 0xBF, 0x52, 0xF8, 0x24, 0xE0, + 0xBE, 0x45, 0x03, 0xDD, 0xA6, 0x42, 0x01, 0xD0, 0x77, 0x46, 0x65, 0xB2, + 0x64, 0x1C, 0xE4, 0xB2, 0x64, 0x45, 0xF3, 0xD3, 0x00, 0x2D, 0x17, 0xDB, + 0x02, 0x22, 0x1A, 0x72, 0x0A, 0x7E, 0x95, 0xFB, 0xF2, 0xF2, 0x52, 0x1C, + 0xD2, 0xB2, 0x10, 0x44, 0x82, 0x7C, 0x5A, 0x70, 0x00, 0x7B, 0x58, 0x71, + 0x08, 0x7E, 0x95, 0xFB, 0xF0, 0xF2, 0x00, 0xFB, 0x12, 0x50, 0x40, 0x1C, + 0xC0, 0xB2, 0x08, 0x44, 0x81, 0x7C, 0xD9, 0x70, 0x00, 0x7B, 0xD8, 0x71, + 0xF0, 0xBD, 0x2D, 0xE9, 0xFF, 0x47, 0x0F, 0x46, 0x06, 0x46, 0xD2, 0xE9, + 0x00, 0x01, 0xCD, 0xE9, 0x00, 0x01, 0xD2, 0xE9, 0x02, 0x01, 0xCD, 0xE9, + 0x02, 0x01, 0x68, 0x46, 0x0F, 0xF0, 0x84, 0xFC, 0x02, 0xA8, 0x0F, 0xF0, + 0x81, 0xFC, 0x00, 0x25, 0xDF, 0xF8, 0xD0, 0x91, 0xDF, 0xF8, 0xC8, 0x81, + 0x2F, 0xE0, 0x2A, 0x46, 0x01, 0x20, 0x00, 0x21, 0x0F, 0xF0, 0xCC, 0xFA, + 0xDD, 0xE9, 0x00, 0x23, 0x10, 0x40, 0x19, 0x40, 0x08, 0x43, 0x01, 0xD0, + 0x00, 0x24, 0x17, 0xE0, 0x99, 0xF8, 0x00, 0x00, 0x39, 0x46, 0x42, 0x00, + 0x30, 0x46, 0x0F, 0xF0, 0xF4, 0xFA, 0x13, 0xE0, 0x22, 0x46, 0x01, 0x20, + 0x00, 0x21, 0x0F, 0xF0, 0xB7, 0xFA, 0xDD, 0xE9, 0x02, 0x23, 0x10, 0x40, + 0x19, 0x40, 0x08, 0x43, 0x03, 0xD1, 0x37, 0xF8, 0x14, 0x00, 0x26, 0xF8, + 0x14, 0x00, 0x64, 0x1C, 0x99, 0xF8, 0x00, 0x00, 0x84, 0x42, 0xEB, 0xDB, + 0x99, 0xF8, 0x00, 0x00, 0x6D, 0x1C, 0x07, 0xEB, 0x40, 0x07, 0x06, 0xEB, + 0x40, 0x06, 0x98, 0xF8, 0x00, 0x00, 0x85, 0x42, 0xCB, 0xDB, 0xBD, 0xE8, + 0xFF, 0x87, 0x2D, 0xE9, 0xFF, 0x4F, 0x81, 0x46, 0x84, 0x1C, 0x80, 0x78, + 0x81, 0xB0, 0x9A, 0x46, 0x15, 0x46, 0x60, 0xB1, 0x40, 0x1E, 0xC2, 0xB2, + 0x22, 0x70, 0xD5, 0xE9, 0x00, 0x67, 0x01, 0x20, 0x00, 0x21, 0x0F, 0xF0, + 0x89, 0xFA, 0x06, 0x43, 0x0F, 0x43, 0xC5, 0xE9, 0x00, 0x67, 0x4F, 0xF0, + 0x01, 0x08, 0xAA, 0xF1, 0x01, 0x0A, 0x2D, 0xE0, 0x09, 0xEB, 0x48, 0x00, + 0x00, 0xF1, 0x02, 0x0B, 0x82, 0x78, 0x60, 0x78, 0xC1, 0x1C, 0x8A, 0x42, + 0x1F, 0xD9, 0x50, 0x45, 0x0C, 0xDA, 0x40, 0x1C, 0xC2, 0xB2, 0x62, 0x70, + 0xD5, 0xE9, 0x00, 0x76, 0x01, 0x20, 0x00, 0x21, 0x0F, 0xF0, 0x6C, 0xFA, + 0x07, 0x43, 0x0E, 0x43, 0xC5, 0xE9, 0x00, 0x76, 0x9B, 0xF8, 0x00, 0x00, + 0x68, 0xB1, 0x40, 0x1E, 0x8B, 0xF8, 0x00, 0x00, 0x22, 0x78, 0xD5, 0xE9, + 0x00, 0x67, 0x01, 0x20, 0x00, 0x21, 0x0F, 0xF0, 0x5B, 0xFA, 0x06, 0x43, + 0x0F, 0x43, 0xC5, 0xE9, 0x00, 0x67, 0x08, 0xF1, 0x01, 0x00, 0x5C, 0x46, + 0x00, 0xF0, 0xFF, 0x08, 0x99, 0xF8, 0x18, 0x00, 0x40, 0x45, 0xCD, 0xD8, + 0x60, 0x78, 0x50, 0x45, 0x0C, 0xDA, 0x40, 0x1C, 0xC2, 0xB2, 0x62, 0x70, + 0xD5, 0xE9, 0x00, 0x46, 0x01, 0x20, 0x00, 0x21, 0x0F, 0xF0, 0x42, 0xFA, + 0x04, 0x43, 0x0E, 0x43, 0xC5, 0xE9, 0x00, 0x46, 0x01, 0x20, 0x04, 0x46, + 0x00, 0x90, 0x66, 0xE0, 0x02, 0x98, 0x22, 0x46, 0x00, 0x21, 0xD0, 0xE9, + 0x00, 0x67, 0x01, 0x20, 0x0F, 0xF0, 0x32, 0xFA, 0x80, 0x46, 0x8B, 0x46, + 0x06, 0xEA, 0x08, 0x06, 0x07, 0xEA, 0x0B, 0x07, 0x3E, 0x43, 0x27, 0xD0, + 0xD5, 0xE9, 0x00, 0x67, 0x46, 0xEA, 0x08, 0x06, 0x47, 0xEA, 0x0B, 0x07, + 0x62, 0x1E, 0x01, 0x20, 0x00, 0x21, 0xC5, 0xE9, 0x00, 0x67, 0x0F, 0xF0, + 0x1D, 0xFA, 0x06, 0x40, 0x0F, 0x40, 0x3E, 0x43, 0x05, 0xD0, 0x00, 0x99, + 0x09, 0xEB, 0x41, 0x00, 0x41, 0x78, 0x49, 0x1C, 0x41, 0x70, 0xD5, 0xE9, + 0x00, 0x67, 0x62, 0x1C, 0x01, 0x20, 0x00, 0x21, 0x0F, 0xF0, 0x0C, 0xFA, + 0x06, 0x40, 0x0F, 0x40, 0x3E, 0x43, 0x05, 0xD0, 0x00, 0x99, 0x09, 0xEB, + 0x41, 0x01, 0x88, 0x78, 0x40, 0x1E, 0x88, 0x70, 0xD5, 0xE9, 0x00, 0x67, + 0x62, 0x1E, 0x01, 0x20, 0x00, 0x21, 0x0F, 0xF0, 0xFB, 0xF9, 0x30, 0x40, + 0x39, 0x40, 0x08, 0x43, 0x21, 0xD0, 0x58, 0xEA, 0x0B, 0x01, 0x0F, 0xD0, + 0x00, 0x20, 0x07, 0xE0, 0x74, 0x05, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0xED, 0x06, 0x10, 0x00, 0xEE, 0x06, 0x10, 0x00, 0x06, 0x40, 0x07, 0xEA, + 0xE0, 0x77, 0x3E, 0x43, 0x0B, 0xD1, 0x01, 0xE0, 0x01, 0x20, 0xEE, 0xE7, + 0x02, 0x99, 0xD1, 0xE9, 0x00, 0x01, 0x00, 0xEA, 0x08, 0x00, 0x01, 0xEA, + 0x0B, 0x01, 0x08, 0x43, 0x03, 0xD0, 0x00, 0x98, 0x40, 0x1C, 0xC0, 0xB2, + 0x00, 0x90, 0x64, 0x1C, 0xE4, 0xB2, 0x54, 0x45, 0x96, 0xDB, 0x05, 0xB0, + 0x56, 0xE6, 0x2D, 0xE9, 0xFF, 0x5F, 0x05, 0x46, 0xFE, 0x49, 0xDD, 0xF8, + 0x38, 0xB0, 0x00, 0x20, 0x05, 0xEB, 0x40, 0x03, 0x40, 0x1C, 0x0C, 0x88, + 0xC0, 0xB2, 0x1C, 0x80, 0x06, 0x28, 0xF7, 0xD3, 0x00, 0x20, 0x28, 0x73, + 0xF8, 0x48, 0x00, 0x68, 0xB0, 0xF9, 0x6E, 0x82, 0xB2, 0xF9, 0x08, 0x00, + 0x40, 0x45, 0x02, 0xDB, 0xB8, 0xF1, 0x00, 0x0F, 0x00, 0xD1, 0x80, 0x46, + 0x4F, 0xF0, 0x01, 0x0A, 0x00, 0x24, 0x28, 0xE0, 0x03, 0x98, 0x05, 0xEB, + 0x4A, 0x09, 0x22, 0x46, 0xD0, 0xE9, 0x00, 0x67, 0x01, 0x20, 0x00, 0x21, + 0x0F, 0xF0, 0xA4, 0xF9, 0x06, 0x40, 0x0F, 0x40, 0x3E, 0x43, 0x04, 0xD1, + 0x01, 0x98, 0x30, 0xF9, 0x14, 0x10, 0x41, 0x45, 0x0B, 0xDD, 0x99, 0xF8, + 0x00, 0x00, 0xFF, 0x28, 0x04, 0xD1, 0x89, 0xF8, 0x00, 0x40, 0x28, 0x7B, + 0x40, 0x1C, 0x28, 0x73, 0x89, 0xF8, 0x01, 0x40, 0x07, 0xE0, 0x99, 0xF8, + 0x00, 0x00, 0xFF, 0x28, 0x03, 0xD0, 0x0A, 0xF1, 0x01, 0x00, 0x00, 0xF0, + 0xFF, 0x0A, 0x64, 0x1C, 0xE4, 0xB2, 0x5C, 0x45, 0xD4, 0xD3, 0xBD, 0xE8, + 0xFF, 0x9F, 0x2D, 0xE9, 0xFF, 0x4F, 0x85, 0xB0, 0x00, 0x20, 0x05, 0x46, + 0x02, 0x90, 0x04, 0x90, 0xD7, 0x48, 0x9B, 0x46, 0x8A, 0x46, 0x06, 0x68, + 0x01, 0x20, 0x81, 0x46, 0x05, 0x98, 0x01, 0x7E, 0x49, 0x45, 0x7D, 0xD3, + 0x05, 0x98, 0x01, 0x27, 0x10, 0xF8, 0x19, 0x10, 0x40, 0x46, 0x61, 0xF3, + 0x17, 0x40, 0x05, 0x99, 0x01, 0xEB, 0x49, 0x01, 0x49, 0x78, 0x61, 0xF3, + 0x1F, 0x60, 0x80, 0x46, 0x69, 0xE0, 0x00, 0xBF, 0x1A, 0xF8, 0x17, 0x10, + 0x40, 0x46, 0x61, 0xF3, 0x07, 0x00, 0x0A, 0xEB, 0x47, 0x01, 0x01, 0x23, + 0x49, 0x78, 0x61, 0xF3, 0x0F, 0x20, 0x80, 0x46, 0x00, 0x20, 0x86, 0xF8, + 0x0E, 0x01, 0x02, 0x46, 0xC3, 0x48, 0xC6, 0xF8, 0x00, 0x80, 0x44, 0x46, + 0x31, 0x46, 0x00, 0x68, 0x06, 0xF0, 0x62, 0xFF, 0x0B, 0xEB, 0x85, 0x00, + 0x44, 0x66, 0x00, 0x20, 0x4B, 0xF8, 0x25, 0x00, 0x4F, 0xF0, 0x00, 0x40, + 0x01, 0x90, 0x00, 0x20, 0x01, 0x24, 0x03, 0x90, 0x3C, 0xE0, 0x00, 0xBF, + 0x06, 0xEB, 0x44, 0x00, 0xB0, 0xF8, 0xB4, 0x10, 0x07, 0x98, 0x81, 0x42, + 0x2D, 0xD9, 0xB6, 0x48, 0x06, 0xEB, 0x84, 0x03, 0xE2, 0xB2, 0x01, 0x68, + 0xB2, 0x48, 0x00, 0x68, 0xFE, 0xF7, 0x7A, 0xFE, 0x01, 0x99, 0x00, 0x90, + 0x88, 0x42, 0x0F, 0xDD, 0x03, 0x98, 0x48, 0xB1, 0xC1, 0xB2, 0xAD, 0x48, + 0x32, 0x46, 0x00, 0x68, 0x07, 0xF0, 0x2D, 0xF8, 0x02, 0x98, 0x40, 0x1E, + 0xC0, 0xB2, 0x02, 0x90, 0x00, 0x98, 0x01, 0x90, 0x60, 0xB2, 0x03, 0x90, + 0x5B, 0xF8, 0x25, 0x10, 0x00, 0x98, 0x01, 0x44, 0x4B, 0xF8, 0x25, 0x10, + 0x02, 0x98, 0x04, 0x99, 0x40, 0x1C, 0xC0, 0xB2, 0x02, 0x90, 0x01, 0x20, + 0xA8, 0x40, 0x08, 0x43, 0x80, 0xB2, 0x04, 0x90, 0x05, 0xE0, 0x9E, 0x48, + 0xE1, 0xB2, 0x32, 0x46, 0x00, 0x68, 0x07, 0xF0, 0x0E, 0xF8, 0x64, 0x1C, + 0x96, 0xF8, 0x0E, 0x01, 0xA0, 0x42, 0xBF, 0xD2, 0x6D, 0x1C, 0xED, 0xB2, + 0x7F, 0x1C, 0x9A, 0xF8, 0x18, 0x00, 0xB8, 0x42, 0x92, 0xD2, 0x00, 0xE0, + 0x02, 0xE0, 0x09, 0xF1, 0x01, 0x00, 0x78, 0xE7, 0x94, 0x48, 0x04, 0x99, + 0xA0, 0xF8, 0x19, 0x10, 0x02, 0x98, 0x6E, 0xE5, 0x2D, 0xE9, 0xFF, 0x5F, + 0xDF, 0xF8, 0x44, 0x92, 0x91, 0x4E, 0x09, 0xF1, 0x20, 0x00, 0x03, 0x90, + 0x06, 0xF1, 0x20, 0x00, 0x02, 0x90, 0x90, 0x49, 0x8E, 0x48, 0xDF, 0xF8, + 0x40, 0xB2, 0x1E, 0xC9, 0x80, 0xE8, 0x1E, 0x00, 0x8E, 0x49, 0x00, 0x20, + 0x8B, 0xF8, 0x00, 0x00, 0x08, 0x72, 0x82, 0x48, 0x31, 0x7E, 0x00, 0x68, + 0x90, 0xF8, 0x51, 0x02, 0x00, 0xF0, 0x01, 0x08, 0x99, 0xF8, 0x18, 0x00, + 0xC8, 0x42, 0x05, 0xD1, 0x43, 0x46, 0x83, 0x4A, 0x31, 0x46, 0x48, 0x46, + 0xFE, 0xF7, 0x3E, 0xFD, 0x99, 0xF8, 0x18, 0x40, 0x37, 0x7E, 0x04, 0xFB, + 0x07, 0xF0, 0x10, 0xF0, 0xFF, 0x05, 0x77, 0xD0, 0x19, 0x2D, 0x75, 0xD2, + 0x05, 0x2C, 0x73, 0xD8, 0x05, 0x2F, 0x71, 0xD8, 0x79, 0x48, 0xFC, 0x21, + 0x10, 0x30, 0x0F, 0xF0, 0x85, 0xF9, 0x77, 0x48, 0x39, 0x46, 0x10, 0x30, + 0x80, 0xF8, 0xFA, 0x50, 0x20, 0x46, 0x0B, 0xF0, 0x67, 0xF9, 0x00, 0xF0, + 0xFF, 0x0A, 0x72, 0x48, 0x08, 0x30, 0x01, 0x90, 0xB8, 0xF1, 0x00, 0x0F, + 0x0D, 0xD0, 0x73, 0x48, 0x6E, 0x4A, 0x03, 0x99, 0x03, 0x78, 0x48, 0x46, + 0xFF, 0xF7, 0xFB, 0xFD, 0x70, 0x48, 0xDD, 0xE9, 0x01, 0x21, 0x03, 0x78, + 0x30, 0x46, 0xFF, 0xF7, 0xF4, 0xFD, 0x6E, 0x48, 0x00, 0x90, 0x6E, 0x48, + 0x66, 0x49, 0xB0, 0xF9, 0x00, 0x30, 0x60, 0x48, 0x02, 0x68, 0x60, 0x48, + 0x00, 0x68, 0xFE, 0xF7, 0x5A, 0xFD, 0x6A, 0x49, 0x5A, 0x4F, 0x61, 0x4B, + 0x08, 0x60, 0x38, 0x68, 0x10, 0x33, 0x31, 0x46, 0x90, 0xF8, 0x6D, 0x22, + 0x48, 0x46, 0xFF, 0xF7, 0xF6, 0xFE, 0x04, 0x46, 0x38, 0x68, 0x90, 0xF8, + 0x51, 0x02, 0x80, 0x07, 0x28, 0xD5, 0x5D, 0x48, 0xDF, 0xF8, 0x58, 0x81, + 0x56, 0x4F, 0x00, 0x78, 0x08, 0xF1, 0x30, 0x08, 0x00, 0x90, 0x30, 0x37, + 0x54, 0x4B, 0x5D, 0x49, 0x40, 0x46, 0x03, 0x9A, 0xFF, 0xF7, 0x93, 0xFE, + 0x56, 0x48, 0x5B, 0x49, 0x00, 0x78, 0x00, 0x90, 0xDD, 0xE9, 0x01, 0x32, + 0x38, 0x46, 0xFF, 0xF7, 0x8A, 0xFE, 0x4A, 0x48, 0x98, 0xF8, 0x0C, 0x20, + 0x81, 0x7D, 0x62, 0xF3, 0x03, 0x01, 0x81, 0x75, 0x3A, 0x7B, 0x62, 0xF3, + 0x07, 0x11, 0x81, 0x75, 0x47, 0x4A, 0x39, 0x46, 0x10, 0x32, 0x40, 0x46, + 0x00, 0xF0, 0x3A, 0xF8, 0xA2, 0x45, 0x06, 0xD8, 0xAC, 0x42, 0x04, 0xD8, + 0x01, 0x21, 0x8B, 0xF8, 0x00, 0x10, 0x0A, 0xE0, 0x10, 0xE0, 0x00, 0x20, + 0x3F, 0x4A, 0x8B, 0xF8, 0x00, 0x00, 0x41, 0x4B, 0x10, 0x32, 0x31, 0x46, + 0x48, 0x46, 0xFF, 0xF7, 0xE4, 0xFC, 0x38, 0x48, 0x01, 0x7E, 0x6A, 0xF3, + 0x03, 0x01, 0x64, 0xF3, 0x07, 0x11, 0x01, 0x76, 0xA9, 0xE6, 0x10, 0xB5, + 0x01, 0x21, 0x31, 0x48, 0x08, 0xF0, 0x31, 0xFD, 0x02, 0x21, 0x3F, 0x48, + 0x08, 0xF0, 0xD5, 0xFC, 0x04, 0x21, 0x2C, 0x48, 0x08, 0xF0, 0xD1, 0xFC, + 0xFF, 0xF7, 0x36, 0xFF, 0xFE, 0xF7, 0x2D, 0xFE, 0x02, 0x21, 0x39, 0x48, + 0x08, 0xF0, 0xE6, 0xFC, 0x04, 0x21, 0x26, 0x48, 0x08, 0xF0, 0xE2, 0xFC, + 0xBD, 0xE8, 0x10, 0x40, 0x01, 0x21, 0x24, 0x48, 0x08, 0xF0, 0xAA, 0xBD, + 0x2D, 0xE9, 0xF0, 0x47, 0x14, 0x46, 0x0D, 0x46, 0x06, 0x46, 0x00, 0xF0, + 0x8B, 0xF8, 0x30, 0x7B, 0x29, 0x7B, 0x1C, 0x4F, 0x48, 0x43, 0xC5, 0xB2, + 0x01, 0x20, 0x30, 0xE0, 0x00, 0x21, 0x0A, 0x46, 0x94, 0xF8, 0xFA, 0x60, + 0x0C, 0xE0, 0x00, 0xBF, 0x54, 0xF8, 0x22, 0x30, 0x8B, 0x42, 0x06, 0xDD, + 0x04, 0xEB, 0x02, 0x0C, 0x9C, 0xF8, 0xE1, 0xC0, 0x84, 0x45, 0x00, 0xD1, + 0x19, 0x46, 0x52, 0x1C, 0x96, 0x42, 0xF1, 0xD8, 0x3A, 0x68, 0xB2, 0xF8, + 0x70, 0x22, 0x8A, 0x42, 0x15, 0xDA, 0x00, 0x22, 0x0F, 0xE0, 0xA3, 0x18, + 0x93, 0xF8, 0xE1, 0x60, 0x86, 0x42, 0x09, 0xD1, 0x54, 0xF8, 0x22, 0x60, + 0x4F, 0xF0, 0x64, 0x0C, 0x06, 0xFB, 0x0C, 0xF6, 0x96, 0xFB, 0xF1, 0xF6, + 0x83, 0xF8, 0xC8, 0x60, 0x52, 0x1C, 0x94, 0xF8, 0xFA, 0x30, 0x93, 0x42, + 0xEB, 0xD8, 0x40, 0x1C, 0xC0, 0xB2, 0x27, 0xE0, 0xFC, 0x78, 0x01, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x58, 0x05, 0x10, 0x00, 0x50, 0x06, 0x10, 0x00, + 0x14, 0x07, 0x10, 0x00, 0x0A, 0x44, 0x01, 0x20, 0x18, 0x2A, 0x10, 0x00, + 0x58, 0x2A, 0x10, 0x00, 0x60, 0x2B, 0x10, 0x00, 0x40, 0x2B, 0x10, 0x00, + 0x57, 0x05, 0x10, 0x00, 0x0C, 0x2A, 0x10, 0x00, 0xED, 0x06, 0x10, 0x00, + 0xEE, 0x06, 0x10, 0x00, 0x84, 0x06, 0x10, 0x00, 0x92, 0x06, 0x10, 0x00, + 0x7C, 0x06, 0x10, 0x00, 0x94, 0x0B, 0x01, 0x20, 0xBE, 0x0B, 0x01, 0x20, + 0x60, 0x06, 0x10, 0x00, 0xA8, 0x42, 0xA3, 0xD9, 0x00, 0x26, 0x35, 0x46, + 0xB8, 0x46, 0xB1, 0x46, 0xDF, 0xF8, 0xD4, 0xA0, 0x18, 0xE0, 0xD8, 0xF8, + 0x00, 0x00, 0x67, 0x19, 0x97, 0xF8, 0xC8, 0x10, 0x90, 0xF8, 0x72, 0x02, + 0x81, 0x42, 0x0E, 0xD2, 0x04, 0xEB, 0x85, 0x01, 0x00, 0x22, 0x64, 0x31, + 0xDA, 0xF8, 0x00, 0x00, 0x06, 0xF0, 0xCE, 0xFC, 0x44, 0xF8, 0x25, 0x90, + 0x97, 0xF8, 0xC8, 0x00, 0xB0, 0x42, 0x00, 0xD2, 0x06, 0x46, 0x6D, 0x1C, + 0x94, 0xF8, 0xFA, 0x00, 0xA8, 0x42, 0xE2, 0xD8, 0x26, 0x48, 0xC6, 0x75, + 0xBD, 0xE8, 0xF0, 0x87, 0x2D, 0xE9, 0xF8, 0x4F, 0x82, 0x46, 0x01, 0x24, + 0x16, 0x46, 0x0F, 0x46, 0x20, 0x46, 0x9A, 0xF8, 0x0C, 0x10, 0x81, 0x46, + 0x49, 0x45, 0x38, 0xD3, 0x1A, 0xF8, 0x14, 0x00, 0x8D, 0xF8, 0x02, 0x00, + 0x0A, 0xEB, 0x44, 0x00, 0x40, 0x78, 0x8D, 0xF8, 0x03, 0x00, 0x01, 0x20, + 0x26, 0xE0, 0x00, 0xBF, 0x17, 0xF8, 0x14, 0x00, 0x8D, 0xF8, 0x00, 0x00, + 0x07, 0xEB, 0x44, 0x00, 0x00, 0x25, 0x40, 0x78, 0x8D, 0xF8, 0x01, 0x00, + 0x12, 0xE0, 0x00, 0xBF, 0x06, 0xEB, 0x05, 0x0B, 0x9B, 0xF8, 0xE1, 0x00, + 0x58, 0xB9, 0x06, 0xEB, 0x85, 0x01, 0x68, 0x46, 0x64, 0x31, 0x06, 0xF0, + 0x7B, 0xFC, 0x20, 0xB1, 0x8B, 0xF8, 0xE1, 0x40, 0x64, 0x20, 0x8B, 0xF8, + 0xC8, 0x00, 0x6D, 0x1C, 0x96, 0xF8, 0xFA, 0x00, 0xA8, 0x42, 0xE9, 0xD8, + 0x64, 0x1C, 0xE4, 0xB2, 0x08, 0xF1, 0x01, 0x00, 0x39, 0x7B, 0x80, 0x46, + 0x41, 0x45, 0xD5, 0xD2, 0x09, 0xF1, 0x01, 0x00, 0xC1, 0xE7, 0xBD, 0xE8, + 0xF8, 0x8F, 0x00, 0x00, 0x50, 0x06, 0x10, 0x00, 0x0A, 0x44, 0x01, 0x20, + 0x2D, 0xE9, 0xFF, 0x4F, 0xCE, 0x4B, 0x83, 0xB0, 0x1B, 0x68, 0xB3, 0xF9, + 0xC2, 0x42, 0xB3, 0xF9, 0xC4, 0xE2, 0x99, 0xE0, 0x47, 0xF6, 0xFF, 0x76, + 0xF7, 0x43, 0x06, 0x9D, 0x08, 0xE0, 0x00, 0xBF, 0x31, 0xF9, 0x15, 0x30, + 0xB3, 0x42, 0x00, 0xDA, 0x1E, 0x46, 0xBB, 0x42, 0x00, 0xDD, 0x1F, 0x46, + 0x6D, 0x1E, 0xF5, 0xD1, 0xAB, 0x46, 0x00, 0x2F, 0x01, 0xDA, 0xBB, 0x46, + 0x02, 0xE0, 0x00, 0x2E, 0x00, 0xDD, 0xB3, 0x46, 0x00, 0x26, 0x37, 0x46, + 0xB2, 0x46, 0x35, 0x46, 0xB1, 0x46, 0x06, 0x9B, 0x13, 0xE0, 0x00, 0xBF, + 0x31, 0xF9, 0x13, 0x80, 0xA8, 0xEB, 0x0B, 0x0C, 0xA4, 0x45, 0x0C, 0xDA, + 0x0C, 0xEB, 0x04, 0x08, 0xB8, 0xF1, 0x00, 0x0F, 0x07, 0xDD, 0x03, 0xFB, + 0x03, 0x77, 0x03, 0xFB, 0x0C, 0x55, 0x1E, 0x44, 0xE2, 0x44, 0x09, 0xF1, + 0x01, 0x09, 0x5B, 0x1E, 0xEA, 0xD1, 0x07, 0xFB, 0x09, 0xF3, 0x06, 0xFB, + 0x16, 0x33, 0x02, 0x93, 0x05, 0xFB, 0x09, 0xF3, 0x06, 0xFB, 0x1A, 0x33, + 0x07, 0xFB, 0x0A, 0xF7, 0x01, 0x93, 0x05, 0xFB, 0x16, 0x73, 0x4F, 0xF0, + 0x00, 0x0C, 0x00, 0x93, 0x67, 0x46, 0x66, 0x46, 0xE2, 0x46, 0x06, 0x9B, + 0x28, 0xE0, 0xDD, 0xF8, 0x08, 0x80, 0x00, 0x25, 0xB8, 0xF1, 0x00, 0x0F, + 0x0D, 0xD0, 0xDD, 0xE9, 0x00, 0x58, 0x08, 0xFB, 0x03, 0x58, 0x02, 0x9D, + 0x98, 0xFB, 0xF5, 0xF5, 0xA5, 0x42, 0x01, 0xDD, 0x25, 0x46, 0x02, 0xE0, + 0xE5, 0x42, 0x00, 0xD5, 0x65, 0x42, 0x31, 0xF8, 0x13, 0x80, 0x5D, 0x44, + 0xA8, 0xEB, 0x05, 0x05, 0x2D, 0xB2, 0x7F, 0x1C, 0xA9, 0x46, 0xAC, 0x44, + 0x75, 0x45, 0x07, 0xDA, 0x05, 0xEB, 0x0E, 0x08, 0xB8, 0xF1, 0x00, 0x0F, + 0x02, 0xDD, 0x4E, 0x44, 0x0A, 0xF1, 0x01, 0x0A, 0x20, 0xF8, 0x13, 0x90, + 0x5B, 0x1E, 0xD4, 0xD1, 0x9C, 0xFB, 0xF7, 0xF5, 0xBA, 0xF1, 0x00, 0x0F, + 0x01, 0xD1, 0x4F, 0xF0, 0x01, 0x0A, 0x96, 0xFB, 0xFA, 0xF3, 0x00, 0x2D, + 0x01, 0xDB, 0x2F, 0x46, 0x00, 0xE0, 0x6F, 0x42, 0x1E, 0x1E, 0x00, 0xDA, + 0x5E, 0x42, 0xB7, 0xEB, 0x46, 0x0F, 0x00, 0xDD, 0x1D, 0x46, 0x06, 0x9B, + 0x05, 0xE0, 0x00, 0xBF, 0x30, 0xF8, 0x13, 0x60, 0x76, 0x1B, 0x20, 0xF8, + 0x13, 0x60, 0x5B, 0x1E, 0xF8, 0xD1, 0x06, 0x9B, 0x01, 0xEB, 0x43, 0x01, + 0x00, 0xEB, 0x43, 0x00, 0x52, 0x1E, 0xBF, 0xF4, 0x63, 0xAF, 0x07, 0xB0, + 0xBD, 0xE8, 0xF0, 0x8F, 0x2D, 0xE9, 0xF7, 0x4F, 0x79, 0x4D, 0x7A, 0x4C, + 0x7A, 0x4F, 0x28, 0x68, 0x0E, 0x46, 0x90, 0xF8, 0xC0, 0x02, 0xC0, 0x07, + 0x00, 0xD0, 0x3C, 0x68, 0x03, 0x20, 0xF8, 0xF7, 0x9A, 0xF9, 0x77, 0x48, + 0xDF, 0xF8, 0xD4, 0xB1, 0x31, 0x46, 0x02, 0x68, 0xBB, 0xF9, 0x00, 0x30, + 0x20, 0x46, 0x0B, 0xF0, 0xB0, 0xFE, 0x03, 0x20, 0xF8, 0xF7, 0xA8, 0xF9, + 0x28, 0x68, 0xDF, 0xF8, 0xC4, 0xA1, 0x71, 0x4E, 0x90, 0xF8, 0xC0, 0x02, + 0xC0, 0x07, 0x06, 0xD0, 0x9A, 0xF8, 0x00, 0x30, 0x32, 0x78, 0x21, 0x46, + 0x67, 0x48, 0xFF, 0xF7, 0x2B, 0xFF, 0xB9, 0x46, 0x65, 0x4A, 0x33, 0x78, + 0x4F, 0xF0, 0x00, 0x08, 0x54, 0x46, 0x38, 0x68, 0x16, 0xE0, 0x00, 0xBF, + 0xA0, 0xF8, 0x00, 0x80, 0x01, 0x21, 0x09, 0xE0, 0x00, 0xEB, 0x41, 0x07, + 0x32, 0xF8, 0x11, 0xC0, 0x37, 0xF8, 0x02, 0x7C, 0x67, 0x44, 0x20, 0xF8, + 0x11, 0x70, 0x49, 0x1C, 0x27, 0x78, 0xB9, 0x42, 0xF2, 0xDB, 0xF9, 0xB2, + 0x02, 0xEB, 0x41, 0x02, 0x00, 0xEB, 0x41, 0x00, 0x5B, 0x1E, 0xE7, 0xD2, + 0x5B, 0x48, 0x5C, 0x4F, 0x02, 0x9B, 0x02, 0x68, 0xD9, 0xF8, 0x00, 0x10, + 0x38, 0x68, 0x00, 0xF0, 0x73, 0xFA, 0x28, 0x68, 0x90, 0xF8, 0xC0, 0x02, + 0x80, 0x07, 0x06, 0xD5, 0x23, 0x78, 0x32, 0x78, 0x39, 0x68, 0x00, 0x98, + 0x00, 0xF0, 0x1C, 0xF8, 0x06, 0xE0, 0xBB, 0xF9, 0x00, 0x00, 0x39, 0x68, + 0x42, 0x00, 0x00, 0x98, 0x0E, 0xF0, 0x55, 0xFE, 0x28, 0x68, 0x90, 0xF8, + 0xC0, 0x02, 0x00, 0x07, 0x08, 0xD5, 0x00, 0x99, 0x23, 0x78, 0x32, 0x78, + 0x03, 0xB0, 0x08, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0x00, 0xF0, 0x05, 0xBC, + 0xBD, 0xE8, 0xFE, 0x8F, 0x47, 0x49, 0x00, 0x20, 0x08, 0x70, 0x70, 0x47, + 0x2D, 0xE9, 0xF0, 0x4F, 0xA7, 0xB0, 0x1C, 0x46, 0x0D, 0x46, 0x06, 0x46, + 0x17, 0x46, 0xEA, 0x46, 0x0D, 0xF1, 0x4C, 0x0B, 0x3C, 0xE0, 0x00, 0x22, + 0x60, 0x1E, 0x00, 0xF0, 0xFF, 0x09, 0x11, 0x46, 0x10, 0x46, 0x11, 0xE0, + 0x35, 0xF9, 0x10, 0x30, 0x1A, 0x44, 0x43, 0x1C, 0x92, 0xFB, 0xF3, 0xFC, + 0x2A, 0xF8, 0x10, 0xC0, 0xA9, 0xEB, 0x00, 0x0C, 0x40, 0x1C, 0x35, 0xF9, + 0x1C, 0x80, 0x41, 0x44, 0x91, 0xFB, 0xF3, 0xF3, 0x2B, 0xF8, 0x1C, 0x30, + 0xA0, 0x42, 0xEB, 0xDB, 0x20, 0x46, 0x52, 0x46, 0x5B, 0x46, 0x0C, 0xE0, + 0x32, 0xF9, 0x10, 0x10, 0x33, 0xF9, 0x10, 0xC0, 0x61, 0x44, 0x35, 0xF8, + 0x10, 0xC0, 0x01, 0xEB, 0xD1, 0x71, 0xAC, 0xEB, 0x61, 0x01, 0x26, 0xF8, + 0x10, 0x10, 0x40, 0x1E, 0xF0, 0xD2, 0x20, 0x48, 0x00, 0x68, 0x90, 0xF8, + 0xC0, 0x02, 0x40, 0x07, 0x04, 0xD5, 0x31, 0x46, 0x22, 0x46, 0x08, 0x46, + 0x00, 0xF0, 0x08, 0xF8, 0x05, 0xEB, 0x44, 0x05, 0x06, 0xEB, 0x44, 0x06, + 0x7F, 0x1E, 0xC0, 0xD2, 0x27, 0xB0, 0x35, 0xE7, 0xF0, 0xB5, 0x16, 0x4B, + 0x00, 0x26, 0x35, 0x46, 0xD3, 0xF8, 0x00, 0xE0, 0x34, 0x46, 0x13, 0x46, + 0xBE, 0xF9, 0xC6, 0x72, 0xC7, 0xF1, 0x00, 0x0C, 0x06, 0xE0, 0x00, 0xBF, + 0x31, 0xF9, 0x13, 0x70, 0x67, 0x45, 0x01, 0xDA, 0x3E, 0x44, 0x6D, 0x1C, + 0x5B, 0x1E, 0xF7, 0xD2, 0x00, 0x2D, 0x01, 0xDD, 0x96, 0xFB, 0xF5, 0xF4, + 0xBE, 0xF8, 0xC8, 0x32, 0x5E, 0x42, 0xA6, 0x42, 0x00, 0xDD, 0x1C, 0x44, + 0x53, 0x1B, 0x63, 0x43, 0x93, 0xFB, 0xF2, 0xF3, 0x05, 0xE0, 0x00, 0xBF, + 0x31, 0xF8, 0x12, 0x40, 0xE4, 0x1A, 0x20, 0xF8, 0x12, 0x40, 0x52, 0x1E, + 0xF8, 0xD2, 0xF0, 0xBD, 0x4C, 0x07, 0x10, 0x00, 0x4A, 0x0C, 0x01, 0x20, + 0x80, 0x05, 0x10, 0x00, 0xFE, 0x06, 0x10, 0x00, 0x1C, 0x07, 0x10, 0x00, + 0xEE, 0x06, 0x10, 0x00, 0xED, 0x06, 0x10, 0x00, 0x9C, 0x06, 0x10, 0x00, + 0x18, 0x07, 0x10, 0x00, 0xF3, 0x06, 0x10, 0x00, 0x2D, 0xE9, 0xFF, 0x4F, + 0x83, 0xB0, 0x9A, 0x46, 0x17, 0x46, 0x89, 0x46, 0x00, 0x25, 0x4F, 0xF0, + 0xAA, 0x0B, 0xDD, 0xF8, 0x40, 0x80, 0x5B, 0xE0, 0x11, 0x98, 0x05, 0xFB, + 0x00, 0xF6, 0x05, 0xEB, 0x85, 0x00, 0xC4, 0x00, 0x1A, 0xF8, 0x04, 0x00, + 0x08, 0xB9, 0x38, 0x5D, 0xE8, 0xB3, 0x0A, 0xF8, 0x04, 0xB0, 0x39, 0xF9, + 0x16, 0x00, 0x00, 0xF0, 0xC9, 0xF8, 0x29, 0xF8, 0x16, 0x00, 0x38, 0x5D, + 0x98, 0xB3, 0x39, 0x19, 0x01, 0x91, 0x11, 0xF8, 0x28, 0x1C, 0x81, 0x42, + 0x1E, 0xD0, 0xAA, 0x28, 0x1C, 0xD0, 0x01, 0x98, 0x00, 0xF8, 0x28, 0xBC, + 0x11, 0x98, 0x31, 0x1A, 0x03, 0x98, 0x00, 0x91, 0x30, 0xF9, 0x11, 0x00, + 0x00, 0xF0, 0xB2, 0xF8, 0x03, 0x9A, 0x00, 0x99, 0x22, 0xF8, 0x11, 0x00, + 0x0A, 0xEB, 0x04, 0x01, 0x01, 0xF8, 0x28, 0xBC, 0x00, 0x99, 0x39, 0xF9, + 0x11, 0x00, 0x00, 0xF0, 0xA5, 0xF8, 0x00, 0x99, 0x29, 0xF8, 0x11, 0x00, + 0x38, 0x5D, 0x70, 0xB1, 0x01, 0x98, 0x90, 0xF8, 0x28, 0x10, 0x38, 0x5D, + 0x81, 0x42, 0x1A, 0xD0, 0xAA, 0x28, 0x18, 0xD0, 0x01, 0x98, 0x80, 0xF8, + 0x28, 0xB0, 0x11, 0x98, 0x06, 0x44, 0x03, 0x98, 0x00, 0xE0, 0x10, 0xE0, + 0x30, 0xF9, 0x16, 0x00, 0x00, 0xF0, 0x8C, 0xF8, 0x03, 0x99, 0x21, 0xF8, + 0x16, 0x00, 0x0A, 0xEB, 0x04, 0x01, 0x81, 0xF8, 0x28, 0xB0, 0x39, 0xF9, + 0x16, 0x00, 0x00, 0xF0, 0x81, 0xF8, 0x29, 0xF8, 0x16, 0x00, 0x6D, 0x1C, + 0x45, 0x45, 0xA1, 0xD3, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x44, 0x49, + 0x00, 0x20, 0x08, 0x60, 0x70, 0x47, 0x42, 0x49, 0x08, 0x60, 0x70, 0x47, + 0x2D, 0xE9, 0xF0, 0x4F, 0x05, 0x46, 0x40, 0x48, 0x8B, 0xB0, 0x17, 0x46, + 0x00, 0x78, 0x8A, 0x46, 0x00, 0x28, 0x65, 0xD0, 0x3D, 0x48, 0x00, 0x68, + 0x90, 0xF8, 0x00, 0x04, 0x80, 0x07, 0x5F, 0xD5, 0x3B, 0x48, 0x04, 0x90, + 0x3B, 0x48, 0xDF, 0xF8, 0xDC, 0xB0, 0x01, 0x24, 0x90, 0xF8, 0x00, 0x80, + 0xDB, 0xF8, 0x00, 0x90, 0x22, 0xE0, 0x01, 0x20, 0xA0, 0x40, 0x10, 0xEA, + 0x09, 0x0F, 0x1C, 0xD1, 0x35, 0x48, 0x00, 0xEB, 0x84, 0x06, 0x04, 0x98, + 0xB1, 0x78, 0x0E, 0xF0, 0xA9, 0xFE, 0x01, 0x46, 0xB2, 0x78, 0x00, 0x23, + 0x0E, 0xE0, 0x30, 0x78, 0x06, 0xE0, 0x00, 0xBF, 0x11, 0xF8, 0x00, 0xC0, + 0xA4, 0x45, 0x00, 0xD1, 0x0B, 0x54, 0x40, 0x1C, 0x96, 0xF8, 0x01, 0xC0, + 0x84, 0x45, 0xF5, 0xDA, 0x28, 0x31, 0x52, 0x1C, 0xF0, 0x78, 0x90, 0x42, + 0xED, 0xDA, 0x64, 0x1C, 0x44, 0x45, 0xDA, 0xD9, 0xA8, 0x46, 0x05, 0xF1, + 0x02, 0x09, 0x00, 0x21, 0x21, 0x48, 0x0E, 0xF0, 0x89, 0xFE, 0x20, 0x4E, + 0x07, 0x90, 0x00, 0x21, 0x70, 0x1C, 0x0E, 0xF0, 0x83, 0xFE, 0x05, 0xEB, + 0x47, 0x04, 0xA5, 0x1E, 0x3E, 0x44, 0x06, 0x90, 0x70, 0x1E, 0x00, 0x21, + 0x24, 0x1F, 0x0E, 0xF0, 0x79, 0xFE, 0x03, 0x90, 0xB0, 0x1E, 0x00, 0x21, + 0x0E, 0xF0, 0x74, 0xFE, 0xCD, 0xE9, 0x00, 0xA7, 0xDD, 0xE9, 0x06, 0x32, + 0x06, 0x46, 0x49, 0x46, 0x40, 0x46, 0xFF, 0xF7, 0x27, 0xFF, 0xCD, 0xE9, + 0x00, 0xA7, 0x33, 0x46, 0x21, 0x46, 0x28, 0x46, 0x03, 0x9A, 0xFF, 0xF7, + 0x1F, 0xFF, 0x00, 0x20, 0xCB, 0xF8, 0x00, 0x00, 0x0B, 0xB0, 0x84, 0xE7, + 0x09, 0x49, 0x09, 0x68, 0x91, 0xF8, 0x08, 0x24, 0x42, 0x43, 0x64, 0x20, + 0x92, 0xFB, 0xF0, 0xF0, 0xB1, 0xF8, 0x06, 0x24, 0x00, 0xB2, 0x82, 0x42, + 0x01, 0xDA, 0xB1, 0xF9, 0x06, 0x04, 0x70, 0x47, 0x7C, 0x05, 0x10, 0x00, + 0xA4, 0x06, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0xC2, 0x18, 0x01, 0x20, + 0x39, 0x06, 0x10, 0x00, 0x5A, 0x1C, 0x01, 0x20, 0x2D, 0xE9, 0xF0, 0x4F, + 0xFE, 0x4C, 0x80, 0x25, 0xFE, 0x4E, 0x23, 0x68, 0x93, 0xF8, 0x31, 0x10, + 0x93, 0xF8, 0x30, 0x00, 0x01, 0xFB, 0x00, 0xF2, 0x02, 0xE0, 0x00, 0xBF, + 0x26, 0xF8, 0x12, 0x50, 0x52, 0x1E, 0xFB, 0xD2, 0x93, 0xF8, 0xA0, 0x22, + 0xA6, 0x46, 0x12, 0x07, 0x4F, 0xF0, 0x64, 0x08, 0x31, 0xD5, 0x4A, 0x1E, + 0x02, 0xFB, 0x00, 0xFA, 0xDF, 0xF8, 0xC8, 0xB3, 0x03, 0xF5, 0x94, 0x69, + 0x02, 0x46, 0x26, 0xE0, 0x19, 0xF8, 0x02, 0x30, 0x0A, 0xEB, 0x02, 0x04, + 0xDB, 0x01, 0xB3, 0xFB, 0xF8, 0xF3, 0x0B, 0xEB, 0x44, 0x05, 0x0C, 0x46, + 0x19, 0xE0, 0x80, 0x2B, 0x05, 0xDD, 0xC3, 0xF1, 0x80, 0x06, 0x66, 0x43, + 0x96, 0xFB, 0xF1, 0xF6, 0x06, 0xE0, 0xA3, 0xF1, 0x80, 0x06, 0x06, 0xFB, + 0x04, 0xF7, 0x97, 0xFB, 0xF1, 0xF7, 0xF6, 0x1B, 0xB5, 0xF9, 0x00, 0x70, + 0x80, 0x36, 0x77, 0x43, 0xFE, 0x17, 0x07, 0xEB, 0x56, 0x66, 0xF6, 0x11, + 0x2E, 0x80, 0xA5, 0xEB, 0x40, 0x05, 0x64, 0x1E, 0xE3, 0xD2, 0x52, 0x1E, + 0xD6, 0xD2, 0xDE, 0xF8, 0x00, 0x20, 0xF2, 0x46, 0x92, 0xF8, 0xA0, 0x32, + 0xDB, 0x06, 0x2F, 0xD5, 0x02, 0xF5, 0x98, 0x69, 0xD6, 0x4B, 0x4A, 0x1E, + 0x42, 0x43, 0x03, 0xEB, 0x42, 0x05, 0x0A, 0x46, 0x24, 0xE0, 0x00, 0xBF, + 0x19, 0xF8, 0x02, 0x30, 0xDB, 0x01, 0xB3, 0xFB, 0xF8, 0xF6, 0x03, 0x46, + 0x18, 0xE0, 0x80, 0x2E, 0x05, 0xDD, 0xC6, 0xF1, 0x80, 0x04, 0x5C, 0x43, + 0x94, 0xFB, 0xF0, 0xF4, 0x06, 0xE0, 0xA6, 0xF1, 0x80, 0x04, 0x04, 0xFB, + 0x03, 0xF7, 0x97, 0xFB, 0xF0, 0xF7, 0xE4, 0x1B, 0x35, 0xF9, 0x13, 0x70, + 0x80, 0x34, 0x67, 0x43, 0xFC, 0x17, 0x07, 0xEB, 0x54, 0x64, 0xE4, 0x11, + 0x25, 0xF8, 0x13, 0x40, 0x5B, 0x1E, 0xE4, 0xD2, 0xA5, 0xEB, 0x40, 0x05, + 0x52, 0x1E, 0xD9, 0xD2, 0xDA, 0xF8, 0x00, 0x40, 0x94, 0xF8, 0xA1, 0x22, + 0xD2, 0x07, 0x20, 0xD0, 0xBC, 0x4E, 0x00, 0x23, 0x04, 0xF5, 0x9C, 0x64, + 0x19, 0xE0, 0x00, 0xBF, 0x03, 0xFB, 0x00, 0xF2, 0x06, 0xEB, 0x42, 0x07, + 0x00, 0x22, 0x0F, 0xE0, 0xA5, 0x5C, 0xED, 0x01, 0xB5, 0xFB, 0xF8, 0xFC, + 0x37, 0xF9, 0x12, 0x50, 0x05, 0xFB, 0x0C, 0xF5, 0x4F, 0xEA, 0xE5, 0x7C, + 0x05, 0xEB, 0x5C, 0x65, 0xED, 0x11, 0x27, 0xF8, 0x12, 0x50, 0x52, 0x1C, + 0x82, 0x42, 0xED, 0xD3, 0x5B, 0x1C, 0x8B, 0x42, 0xE4, 0xD3, 0xBD, 0xE8, + 0xF0, 0x8F, 0x30, 0xB5, 0x0B, 0xE0, 0x00, 0xBF, 0x31, 0xF9, 0x13, 0x40, + 0x32, 0xF9, 0x13, 0x50, 0x6C, 0x43, 0xE5, 0x17, 0x04, 0xEB, 0x55, 0x64, + 0xE4, 0x11, 0x20, 0xF8, 0x13, 0x40, 0x5B, 0x1E, 0xF2, 0xD2, 0x30, 0xBD, + 0x08, 0xB5, 0x00, 0x93, 0x13, 0x46, 0xA2, 0x4A, 0xB2, 0xF9, 0x00, 0x20, + 0x0B, 0xF0, 0x06, 0xFC, 0x08, 0xBD, 0x2D, 0xE9, 0xF0, 0x5F, 0xDF, 0xF8, + 0x70, 0x92, 0xDF, 0xF8, 0x78, 0xB2, 0xD9, 0xF8, 0x00, 0x10, 0xDB, 0xF8, + 0x00, 0xC0, 0xB1, 0xF9, 0x00, 0x23, 0xB1, 0xF9, 0x22, 0x33, 0xB1, 0xF9, + 0x42, 0x63, 0x5F, 0xEA, 0x8C, 0x70, 0x07, 0xD5, 0x97, 0x48, 0x00, 0x78, + 0x01, 0x28, 0x03, 0xD1, 0xB1, 0xF9, 0x4E, 0x33, 0xB1, 0xF9, 0x50, 0x23, + 0x94, 0x48, 0x47, 0x78, 0x01, 0x2F, 0x7C, 0xD0, 0x02, 0x2F, 0x04, 0xD3, + 0xB1, 0xF8, 0x04, 0x03, 0x08, 0xB1, 0xB1, 0xF9, 0x04, 0x23, 0x90, 0x4D, + 0x28, 0x78, 0x98, 0xB1, 0x91, 0xF8, 0x69, 0x03, 0x64, 0x24, 0x00, 0xFB, + 0x02, 0xF8, 0x98, 0xFB, 0xF4, 0xF8, 0x42, 0x44, 0x00, 0xFB, 0x03, 0xF8, + 0x70, 0x43, 0x98, 0xFB, 0xF4, 0xF8, 0x90, 0xFB, 0xF4, 0xF0, 0x43, 0x44, + 0x30, 0x44, 0x12, 0xB2, 0x1B, 0xB2, 0x06, 0xB2, 0x85, 0x4C, 0xDF, 0xF8, + 0x18, 0xA2, 0xDF, 0xF8, 0x18, 0xE2, 0x22, 0x80, 0xAA, 0xF8, 0x00, 0x30, + 0xAE, 0xF8, 0x00, 0x60, 0x91, 0xF8, 0x02, 0x03, 0xDF, 0xF8, 0x08, 0x92, + 0x10, 0x1A, 0x00, 0xB2, 0xA9, 0xF8, 0x00, 0x00, 0x91, 0xF8, 0x24, 0x83, + 0xA3, 0xEB, 0x08, 0x08, 0x7E, 0x4B, 0xA3, 0xF8, 0x00, 0x80, 0x91, 0xF8, + 0x44, 0x13, 0x76, 0x1A, 0x7C, 0x49, 0x5F, 0xEA, 0xCC, 0x78, 0x0E, 0x80, + 0x01, 0xD0, 0x02, 0x2F, 0x02, 0xD3, 0xAA, 0xF8, 0x00, 0x20, 0x18, 0x80, + 0xDA, 0x46, 0x5F, 0xEA, 0x8C, 0x76, 0x01, 0xD5, 0x02, 0x2F, 0x02, 0xD3, + 0xAE, 0xF8, 0x00, 0x20, 0x08, 0x80, 0xB1, 0xF9, 0x00, 0x20, 0xB3, 0xF9, + 0x00, 0x10, 0xC8, 0x46, 0x4F, 0x46, 0x0A, 0xF0, 0xF1, 0xFB, 0x70, 0x4E, + 0x00, 0xB2, 0x70, 0x4A, 0x30, 0x80, 0x21, 0x88, 0x6F, 0x4B, 0x11, 0x80, + 0xDF, 0xF8, 0x7C, 0x91, 0x39, 0x88, 0x19, 0x80, 0xD9, 0xF8, 0x00, 0x10, + 0x91, 0xF8, 0x00, 0x74, 0xFF, 0x07, 0x10, 0xD0, 0x5F, 0x4F, 0x7F, 0x78, + 0x0F, 0xB1, 0x91, 0xF8, 0x05, 0x74, 0xB1, 0xF8, 0x02, 0xC4, 0x67, 0x44, + 0x17, 0x80, 0x91, 0xF8, 0x04, 0x14, 0x79, 0x1A, 0x09, 0xB2, 0x19, 0x80, + 0x0A, 0xF0, 0xDE, 0xFB, 0x30, 0x80, 0x62, 0x4F, 0x62, 0x4A, 0x20, 0x88, + 0x38, 0x80, 0x10, 0x80, 0x00, 0xE0, 0x0C, 0xE0, 0x60, 0x49, 0xB8, 0xF8, + 0x00, 0x00, 0x08, 0x80, 0xD9, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0x40, 0x34, + 0xDB, 0x07, 0x26, 0xD0, 0x2B, 0x78, 0x6B, 0xB1, 0x23, 0xE0, 0x91, 0xF8, + 0x03, 0x03, 0x10, 0x44, 0x02, 0xB2, 0x91, 0xF8, 0x25, 0x03, 0x18, 0x44, + 0x03, 0xB2, 0x91, 0xF8, 0x45, 0x03, 0x30, 0x44, 0x06, 0xB2, 0x6E, 0xE7, + 0xB0, 0xF8, 0x42, 0x34, 0x13, 0xB1, 0xB0, 0xF8, 0x42, 0x34, 0x3B, 0x80, + 0xB0, 0xF8, 0x44, 0x34, 0x33, 0xB1, 0xB0, 0xF8, 0x44, 0x34, 0x13, 0x80, + 0x90, 0xF8, 0x46, 0x04, 0x18, 0x1A, 0x08, 0x80, 0xB1, 0xF9, 0x00, 0x10, + 0xB6, 0xF9, 0x00, 0x00, 0x0A, 0xF0, 0xA6, 0xFB, 0x30, 0x80, 0x49, 0x4E, + 0x20, 0x88, 0x30, 0x80, 0xD9, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0x20, 0x14, + 0xC9, 0x07, 0x07, 0xD0, 0x29, 0x78, 0x29, 0xB9, 0xB0, 0xF8, 0x21, 0x14, + 0x11, 0xB1, 0xB0, 0xF8, 0x21, 0x14, 0x31, 0x80, 0x9A, 0xF8, 0x00, 0x10, + 0xC9, 0x06, 0x07, 0xD5, 0x3F, 0x49, 0x09, 0x78, 0x21, 0xB1, 0xB0, 0xF8, + 0x6B, 0x12, 0x21, 0x80, 0xA8, 0xF8, 0x00, 0x10, 0x3C, 0x4C, 0xB0, 0xF9, + 0xB2, 0x02, 0x20, 0x80, 0xB7, 0xF9, 0x00, 0x10, 0x0A, 0xF0, 0x80, 0xFB, + 0x00, 0xB2, 0x20, 0x80, 0xB6, 0xF9, 0x00, 0x10, 0x0A, 0xF0, 0x7A, 0xFB, + 0x20, 0x80, 0xBD, 0xE8, 0xF0, 0x9F, 0x2D, 0xE9, 0xFF, 0x4F, 0x8A, 0x46, + 0x81, 0x46, 0x33, 0x49, 0x0D, 0x98, 0x93, 0x46, 0x4A, 0x0C, 0x04, 0x46, + 0x08, 0xE0, 0x00, 0xBF, 0x3A, 0xF9, 0x14, 0x30, 0x93, 0x42, 0x00, 0xDA, + 0x1A, 0x46, 0x8B, 0x42, 0x00, 0xDD, 0x19, 0x46, 0x64, 0x1E, 0xF5, 0xD2, + 0x00, 0x25, 0x00, 0x29, 0x01, 0xDA, 0x0D, 0x46, 0x02, 0xE0, 0x00, 0x2A, + 0x00, 0xDD, 0x15, 0x46, 0x00, 0x23, 0x1C, 0x46, 0x1E, 0x46, 0x19, 0x46, + 0x1F, 0x46, 0x02, 0x46, 0x12, 0xE0, 0x00, 0xBF, 0x3A, 0xF9, 0x12, 0xC0, + 0xAC, 0xEB, 0x05, 0x0C, 0xDC, 0x45, 0x0B, 0xDA, 0x0C, 0xEB, 0x0B, 0x08, + 0xB8, 0xF1, 0x00, 0x0F, 0x06, 0xDD, 0x02, 0xFB, 0x02, 0x44, 0x02, 0xFB, + 0x0C, 0x11, 0x13, 0x44, 0x66, 0x44, 0x7F, 0x1C, 0x52, 0x1E, 0xEB, 0xD2, + 0x04, 0xFB, 0x07, 0xF2, 0x03, 0xFB, 0x13, 0x2E, 0x2E, 0xE0, 0x00, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x86, 0x12, 0x01, 0x20, 0xFE, 0x06, 0x10, 0x00, + 0x04, 0x07, 0x10, 0x00, 0xF9, 0x06, 0x10, 0x00, 0x74, 0x07, 0x10, 0x00, + 0xFD, 0x06, 0x10, 0x00, 0x8C, 0x06, 0x10, 0x00, 0x8E, 0x06, 0x10, 0x00, + 0x90, 0x06, 0x10, 0x00, 0x92, 0x06, 0x10, 0x00, 0x94, 0x06, 0x10, 0x00, + 0x96, 0x06, 0x10, 0x00, 0x98, 0x06, 0x10, 0x00, 0xA0, 0x06, 0x10, 0x00, + 0xA2, 0x06, 0x10, 0x00, 0xA8, 0x06, 0x10, 0x00, 0xAA, 0x06, 0x10, 0x00, + 0xAC, 0x06, 0x10, 0x00, 0xA6, 0x06, 0x10, 0x00, 0x74, 0x05, 0x10, 0x00, + 0x9A, 0x06, 0x10, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x01, 0xFB, 0x07, 0xF2, + 0x03, 0xFB, 0x16, 0x27, 0x74, 0x43, 0x01, 0xFB, 0x13, 0x46, 0x00, 0x24, + 0x21, 0x46, 0x02, 0x46, 0x25, 0xE0, 0x00, 0x23, 0xBE, 0xF1, 0x00, 0x0F, + 0x0F, 0xD0, 0x07, 0xFB, 0x02, 0x6C, 0x9C, 0xFB, 0xFE, 0xF3, 0xDC, 0x46, + 0x5B, 0x45, 0x01, 0xDD, 0x63, 0x46, 0x06, 0xE0, 0xDD, 0xF8, 0x0C, 0xC0, + 0x13, 0xEB, 0x0C, 0x0F, 0x01, 0xD5, 0x03, 0x9B, 0x5B, 0x42, 0x3A, 0xF8, + 0x12, 0xC0, 0x2B, 0x44, 0xAC, 0xEB, 0x03, 0x03, 0xDD, 0xF8, 0x0C, 0xC0, + 0x1B, 0xB2, 0x63, 0x45, 0x05, 0xDA, 0x9C, 0x44, 0xBC, 0xF1, 0x00, 0x0F, + 0x01, 0xDD, 0x1C, 0x44, 0x49, 0x1C, 0x29, 0xF8, 0x12, 0x30, 0x52, 0x1E, + 0xD7, 0xD2, 0x01, 0xB9, 0x01, 0x21, 0x94, 0xFB, 0xF1, 0xF1, 0x04, 0xE0, + 0x39, 0xF8, 0x10, 0x20, 0x52, 0x1A, 0x29, 0xF8, 0x10, 0x20, 0x40, 0x1E, + 0xF8, 0xD2, 0xBD, 0xE8, 0xFF, 0x8F, 0x2D, 0xE9, 0xF8, 0x43, 0x1F, 0x46, + 0xFE, 0x4B, 0x0E, 0x46, 0x05, 0x46, 0x1B, 0x68, 0x14, 0x46, 0xB3, 0xF9, + 0xCA, 0x92, 0xB3, 0xF9, 0xCC, 0x82, 0x0A, 0xE0, 0x43, 0x46, 0x4A, 0x46, + 0x31, 0x46, 0x28, 0x46, 0x00, 0x97, 0xFF, 0xF7, 0x3E, 0xFF, 0x06, 0xEB, + 0x47, 0x06, 0x05, 0xEB, 0x47, 0x05, 0x64, 0x1E, 0xF2, 0xD2, 0xBD, 0xE8, + 0xF8, 0x83, 0x08, 0xE0, 0x30, 0xF9, 0x12, 0x30, 0x00, 0x2B, 0x00, 0xDA, + 0x5B, 0x42, 0x8B, 0x42, 0x01, 0xDD, 0x01, 0x20, 0x70, 0x47, 0x52, 0x1E, + 0xF4, 0xD2, 0x00, 0x20, 0x70, 0x47, 0x05, 0xE0, 0x30, 0xF9, 0x12, 0x30, + 0x8B, 0x42, 0x01, 0xDD, 0x01, 0x20, 0x70, 0x47, 0x52, 0x1E, 0xF7, 0xD2, + 0x00, 0x20, 0x70, 0x47, 0x2D, 0xE9, 0xFC, 0x47, 0x04, 0x46, 0xE5, 0x48, + 0xE5, 0x4F, 0x13, 0x46, 0x02, 0x68, 0x38, 0x68, 0xFF, 0xF7, 0x0E, 0xFE, + 0x03, 0x20, 0xF7, 0xF7, 0xEC, 0xFC, 0xDF, 0xF8, 0x7C, 0x93, 0xDF, 0xF8, + 0x84, 0x83, 0xE1, 0x4D, 0xD9, 0xF8, 0x00, 0x00, 0xE0, 0x4E, 0x90, 0xF8, + 0xA0, 0x02, 0x80, 0x07, 0x15, 0xD5, 0xDF, 0x48, 0xB0, 0xF9, 0x00, 0x20, + 0xDE, 0x48, 0xB0, 0xF9, 0x00, 0x10, 0xDE, 0x48, 0xB0, 0xF9, 0x00, 0x00, + 0x0A, 0xF0, 0x62, 0xFA, 0x03, 0xB2, 0x29, 0x78, 0x30, 0x78, 0xCD, 0xE9, + 0x00, 0x01, 0x39, 0x68, 0xD8, 0xF8, 0x00, 0x20, 0x08, 0x46, 0x00, 0xF0, + 0x3F, 0xF9, 0xD7, 0x48, 0xD8, 0xF8, 0x00, 0x20, 0x39, 0x68, 0xB0, 0xF9, + 0x00, 0x30, 0x20, 0x46, 0x0B, 0xF0, 0xE1, 0xF9, 0x03, 0x20, 0xF7, 0xF7, + 0xD9, 0xFC, 0xD9, 0xF8, 0x00, 0x00, 0x4F, 0x46, 0x90, 0xF8, 0xA0, 0x02, + 0x00, 0x06, 0x05, 0xD5, 0x21, 0x46, 0x2B, 0x78, 0x32, 0x78, 0x08, 0x46, + 0xFF, 0xF7, 0x83, 0xFF, 0x38, 0x68, 0x90, 0xF8, 0xA0, 0x02, 0x40, 0x07, + 0x25, 0xD5, 0x30, 0x78, 0x2E, 0x78, 0x32, 0x46, 0x1F, 0xE0, 0x00, 0x21, + 0x03, 0x46, 0x0C, 0xE0, 0x03, 0xFB, 0x06, 0x27, 0x34, 0xF9, 0x17, 0x50, + 0x00, 0x2D, 0x04, 0xDD, 0x09, 0xB1, 0x8D, 0x42, 0x03, 0xDA, 0x29, 0x46, + 0x01, 0xE0, 0x00, 0x21, 0x43, 0x1C, 0x5B, 0x1E, 0xF0, 0xD2, 0x00, 0x29, + 0x0B, 0xDD, 0x03, 0x46, 0x07, 0xE0, 0x00, 0xBF, 0x03, 0xFB, 0x06, 0x25, + 0x34, 0xF8, 0x15, 0x70, 0x7F, 0x1A, 0x24, 0xF8, 0x15, 0x70, 0x5B, 0x1E, + 0xF6, 0xD2, 0x52, 0x1E, 0xDD, 0xD2, 0xBD, 0xE8, 0xFC, 0x87, 0x2D, 0xE9, + 0xF0, 0x5F, 0x92, 0x46, 0xB3, 0x4A, 0x4F, 0xF0, 0x00, 0x08, 0x8B, 0x46, + 0x15, 0x78, 0x06, 0x46, 0x82, 0xF8, 0x00, 0x80, 0xFF, 0xF7, 0x9F, 0xFD, + 0x02, 0x21, 0xAF, 0x48, 0x07, 0xF0, 0x59, 0xFE, 0xAE, 0x48, 0xAD, 0x4C, + 0x2A, 0x46, 0x00, 0x78, 0x31, 0x46, 0x01, 0x28, 0x20, 0x68, 0x5F, 0xD0, + 0xFF, 0xF7, 0x70, 0xFF, 0x9D, 0x4D, 0xA1, 0x4F, 0xDF, 0xF8, 0x84, 0x92, + 0x28, 0x68, 0x90, 0xF8, 0xA1, 0x02, 0x80, 0x07, 0x06, 0xD5, 0x21, 0x68, + 0x3B, 0x78, 0x99, 0xF8, 0x00, 0x20, 0x08, 0x46, 0x00, 0xF0, 0xDE, 0xF9, + 0x29, 0x68, 0x9E, 0x4E, 0x91, 0xF8, 0xA0, 0x02, 0x02, 0x07, 0x05, 0xD4, + 0xC0, 0x06, 0x03, 0xD4, 0x91, 0xF8, 0xA1, 0x02, 0xC0, 0x07, 0x06, 0xD0, + 0x21, 0x68, 0xB6, 0xF9, 0x00, 0x30, 0x9B, 0x4A, 0x08, 0x46, 0xFF, 0xF7, + 0x54, 0xFD, 0xB6, 0xF9, 0x00, 0x00, 0x21, 0x68, 0x42, 0x00, 0x98, 0x48, + 0x00, 0x68, 0x0E, 0xF0, 0x52, 0xF9, 0x3A, 0x78, 0x99, 0xF8, 0x00, 0x10, + 0x20, 0x68, 0xFF, 0xF7, 0x0D, 0xFC, 0xDF, 0xF8, 0x50, 0x92, 0x99, 0xF8, + 0x00, 0x00, 0x10, 0xF0, 0x30, 0x0F, 0x04, 0xD0, 0x51, 0x46, 0x58, 0x46, + 0x22, 0x68, 0xFE, 0xF7, 0xCD, 0xFA, 0x8F, 0x48, 0x8F, 0x4F, 0x40, 0x78, + 0x02, 0x28, 0x28, 0x68, 0x90, 0xF8, 0xA0, 0x12, 0x4F, 0xEA, 0x81, 0x61, + 0x19, 0xD3, 0x00, 0x29, 0x07, 0xDA, 0x21, 0x68, 0xB0, 0xF9, 0xB0, 0x22, + 0xB6, 0xF9, 0x00, 0x30, 0x08, 0x46, 0x00, 0xF0, 0x3E, 0xF9, 0x28, 0x68, + 0x90, 0xF8, 0xA0, 0x12, 0x49, 0x06, 0x15, 0xD5, 0xB0, 0xF9, 0xAE, 0x32, + 0x83, 0x4A, 0x21, 0x68, 0x38, 0x68, 0x06, 0xF0, 0xF9, 0xFA, 0x14, 0xE0, + 0xFF, 0xF7, 0x60, 0xFA, 0x9E, 0xE7, 0x00, 0x29, 0x08, 0xDA, 0xB0, 0xF9, + 0xB0, 0x22, 0xB6, 0xF9, 0x00, 0x30, 0x21, 0x68, 0x38, 0x68, 0x00, 0xF0, + 0x24, 0xF9, 0x06, 0xE0, 0xB6, 0xF9, 0x00, 0x00, 0x21, 0x68, 0x42, 0x00, + 0x38, 0x68, 0x0E, 0xF0, 0x0A, 0xF9, 0x02, 0x21, 0x6E, 0x48, 0x07, 0xF0, + 0x6B, 0xFE, 0x75, 0x48, 0x00, 0x78, 0x60, 0xB1, 0xD9, 0xF8, 0x00, 0x00, + 0x73, 0x49, 0xC2, 0x06, 0x02, 0xD5, 0x0A, 0x78, 0x01, 0x2A, 0x21, 0xD0, + 0x80, 0x06, 0x02, 0xD5, 0x08, 0x78, 0x02, 0x28, 0x1E, 0xD0, 0x6F, 0x48, + 0xB6, 0xF9, 0x00, 0x20, 0xB0, 0xF9, 0x00, 0x10, 0x38, 0x68, 0xFF, 0xF7, + 0xD6, 0xFE, 0x6C, 0x49, 0x6C, 0x4D, 0xA8, 0xB1, 0x01, 0x20, 0x08, 0x70, + 0x01, 0x46, 0x02, 0x24, 0x6A, 0x48, 0x07, 0xF0, 0xB6, 0xFD, 0x6B, 0x48, + 0x69, 0x4B, 0xB0, 0xF9, 0x00, 0x20, 0x67, 0x48, 0x01, 0x68, 0x38, 0x68, + 0x00, 0xF0, 0xFF, 0xF8, 0x28, 0x60, 0x0E, 0xE0, 0x03, 0x20, 0xE4, 0xE5, + 0x04, 0x20, 0xE2, 0xE5, 0x64, 0x4A, 0xC5, 0xF8, 0x00, 0x80, 0x01, 0x24, + 0xC2, 0xF8, 0x00, 0x80, 0x5F, 0x4A, 0xC2, 0xF8, 0x00, 0x80, 0x81, 0xF8, + 0x00, 0x80, 0x20, 0x46, 0xD5, 0xE5, 0x4E, 0x49, 0x10, 0xB5, 0x00, 0x20, + 0x08, 0x60, 0x57, 0x49, 0x08, 0x70, 0xFF, 0xF7, 0x7B, 0xFA, 0xFF, 0xF7, + 0x78, 0xFB, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x01, 0xB8, 0x07, 0xE4, + 0x3B, 0x48, 0x10, 0xB5, 0x00, 0x68, 0x42, 0x49, 0x40, 0x4B, 0xB0, 0xF8, + 0x00, 0x23, 0x0A, 0x80, 0xB0, 0xF8, 0x22, 0x13, 0x3C, 0x4C, 0x19, 0x80, + 0xB0, 0xF8, 0x42, 0x33, 0x23, 0x80, 0x50, 0x4C, 0x22, 0x80, 0x50, 0x4A, + 0x11, 0x80, 0x50, 0x49, 0x0B, 0x80, 0x4B, 0x49, 0xB0, 0xF8, 0xB2, 0x02, + 0x08, 0x80, 0x10, 0xBD, 0x2D, 0xE9, 0xFF, 0x4F, 0x9B, 0x46, 0xDD, 0xE9, + 0x0D, 0x19, 0x86, 0x46, 0xA5, 0xE0, 0x00, 0xBF, 0x01, 0x9A, 0x01, 0xFB, + 0x09, 0xF0, 0x02, 0xEB, 0x40, 0x04, 0x02, 0x9A, 0x46, 0x4F, 0x02, 0xEB, + 0x40, 0x06, 0x4F, 0xF0, 0x01, 0x0C, 0x0E, 0xEB, 0x40, 0x05, 0x7B, 0x0C, + 0xE2, 0x46, 0x4A, 0x46, 0x15, 0xE0, 0x00, 0xBF, 0x36, 0xF8, 0x12, 0x00, + 0x34, 0xF8, 0x12, 0x80, 0xA0, 0xEB, 0x08, 0x00, 0x00, 0xB2, 0x98, 0x42, + 0x00, 0xDA, 0x03, 0x46, 0xB8, 0x42, 0x00, 0xDD, 0x07, 0x46, 0x00, 0x28, + 0x02, 0xDD, 0x4F, 0xF0, 0x00, 0x0A, 0x02, 0xE0, 0x01, 0xDA, 0x4F, 0xF0, + 0x00, 0x0C, 0x52, 0x1E, 0xE8, 0xD2, 0xBC, 0xF1, 0x00, 0x0F, 0x04, 0xD0, + 0xBA, 0xF1, 0x00, 0x0F, 0x01, 0xD0, 0x00, 0x20, 0x0B, 0xE0, 0x5C, 0xEA, + 0x0A, 0x00, 0x08, 0xD0, 0xBC, 0xF1, 0x00, 0x0F, 0x04, 0xD1, 0xBA, 0xF1, + 0x00, 0x0F, 0x01, 0xD0, 0x38, 0x46, 0x00, 0xE0, 0x18, 0x46, 0x00, 0x27, + 0x3B, 0x46, 0x4A, 0x46, 0xCB, 0xF1, 0x00, 0x0A, 0x10, 0xE0, 0x00, 0xBF, + 0x36, 0xF8, 0x12, 0xC0, 0x34, 0xF8, 0x12, 0x80, 0xAC, 0xEB, 0x08, 0x0C, + 0xAC, 0xEB, 0x00, 0x0C, 0x0F, 0xFA, 0x8C, 0xFC, 0xDC, 0x45, 0x03, 0xDA, + 0xD4, 0x45, 0x01, 0xDD, 0x67, 0x44, 0x5B, 0x1C, 0x52, 0x1E, 0x3F, 0xE0, + 0x4C, 0x07, 0x10, 0x00, 0x9C, 0x06, 0x10, 0x00, 0x18, 0x07, 0x10, 0x00, + 0x1C, 0x07, 0x10, 0x00, 0xEE, 0x06, 0x10, 0x00, 0xED, 0x06, 0x10, 0x00, + 0x90, 0x06, 0x10, 0x00, 0x8E, 0x06, 0x10, 0x00, 0x8C, 0x06, 0x10, 0x00, + 0xFE, 0x06, 0x10, 0x00, 0x79, 0x07, 0x10, 0x00, 0x80, 0x05, 0x10, 0x00, + 0xF3, 0x06, 0x10, 0x00, 0x86, 0x12, 0x01, 0x20, 0x14, 0x07, 0x10, 0x00, + 0x04, 0x07, 0x10, 0x00, 0x74, 0x07, 0x10, 0x00, 0x10, 0x07, 0x10, 0x00, + 0x0E, 0x7A, 0x01, 0x00, 0x64, 0x05, 0x10, 0x00, 0x66, 0x05, 0x10, 0x00, + 0x98, 0x06, 0x10, 0x00, 0xF5, 0x06, 0x10, 0x00, 0x7C, 0x06, 0x10, 0x00, + 0x50, 0x06, 0x10, 0x00, 0x84, 0x06, 0x10, 0x00, 0x9A, 0x06, 0x10, 0x00, + 0x80, 0x06, 0x10, 0x00, 0x92, 0x06, 0x10, 0x00, 0x94, 0x06, 0x10, 0x00, + 0x96, 0x06, 0x10, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xAC, 0xD2, 0x03, 0xB9, + 0x01, 0x23, 0x97, 0xFB, 0xF3, 0xF2, 0x02, 0x44, 0x48, 0x46, 0x04, 0xE0, + 0x34, 0xF8, 0x10, 0x30, 0x13, 0x44, 0x25, 0xF8, 0x10, 0x30, 0x40, 0x1E, + 0xF8, 0xD2, 0x49, 0x1E, 0xBF, 0xF4, 0x58, 0xAF, 0xA9, 0xE5, 0x70, 0xB5, + 0x00, 0x24, 0x26, 0x46, 0x0A, 0xE0, 0x00, 0xBF, 0x31, 0xF9, 0x14, 0x50, + 0x95, 0x42, 0x02, 0xDA, 0x20, 0xF8, 0x14, 0x60, 0x01, 0xE0, 0x20, 0xF8, + 0x14, 0x50, 0x64, 0x1C, 0x9C, 0x42, 0xF3, 0xDB, 0x70, 0xBD, 0x2D, 0xE9, + 0xFF, 0x5F, 0x45, 0x4C, 0x88, 0x46, 0x00, 0x26, 0x07, 0x46, 0x92, 0x46, + 0x35, 0x46, 0x4F, 0xF4, 0x66, 0x71, 0x40, 0x46, 0x26, 0x60, 0x0E, 0xF0, + 0x4D, 0xF8, 0x00, 0x21, 0x40, 0x46, 0x0E, 0xF0, 0x5B, 0xF9, 0x81, 0x46, + 0x00, 0x21, 0x38, 0x46, 0x0E, 0xF0, 0x4E, 0xF9, 0x00, 0x22, 0x3B, 0x4B, + 0x3B, 0x4F, 0x29, 0xE0, 0x00, 0x21, 0x4F, 0xF0, 0x01, 0x0E, 0xDF, 0xF8, + 0xE8, 0xB0, 0x18, 0xE0, 0x30, 0xF9, 0x11, 0x80, 0xD0, 0x45, 0x05, 0xDD, + 0x09, 0xF8, 0x01, 0xE0, 0x30, 0xF9, 0x11, 0xC0, 0x76, 0x1C, 0x65, 0x44, + 0xDB, 0xF8, 0x00, 0xC0, 0x30, 0xF9, 0x11, 0x80, 0xBC, 0xF8, 0x55, 0xC3, + 0xE0, 0x45, 0x05, 0xDD, 0xD4, 0xF8, 0x00, 0xC0, 0x0C, 0xF1, 0x01, 0x0C, + 0xC4, 0xF8, 0x00, 0xC0, 0x49, 0x1C, 0x93, 0xF8, 0x00, 0xC0, 0x61, 0x45, + 0xE2, 0xDB, 0x0C, 0xF0, 0xFF, 0x01, 0x09, 0xF1, 0x28, 0x09, 0x00, 0xEB, + 0x41, 0x00, 0x52, 0x1C, 0x39, 0x78, 0x8A, 0x42, 0xD2, 0xDB, 0x03, 0x98, + 0x05, 0x60, 0x30, 0x46, 0x04, 0xB0, 0x9C, 0xE4, 0x2D, 0xE9, 0xF0, 0x43, + 0x91, 0x46, 0x1C, 0x46, 0x35, 0xE0, 0x21, 0x4D, 0x4F, 0xF0, 0x01, 0x0C, + 0x6A, 0x0C, 0xE0, 0x46, 0x4F, 0x46, 0x11, 0xE0, 0x07, 0xFB, 0x03, 0x46, + 0x31, 0xF9, 0x16, 0x60, 0x96, 0x42, 0x00, 0xDA, 0x32, 0x46, 0xAE, 0x42, + 0x00, 0xDD, 0x35, 0x46, 0x00, 0x2E, 0x02, 0xDD, 0x4F, 0xF0, 0x00, 0x08, + 0x02, 0xE0, 0x01, 0xDA, 0x4F, 0xF0, 0x00, 0x0C, 0x7F, 0x1E, 0xEB, 0xD2, + 0xBC, 0xF1, 0x00, 0x0F, 0x02, 0xD0, 0xB8, 0xF1, 0x00, 0x0F, 0x14, 0xD1, + 0x5C, 0xEA, 0x08, 0x06, 0x11, 0xD0, 0xBC, 0xF1, 0x00, 0x0F, 0x03, 0xD1, + 0xB8, 0xF1, 0x00, 0x0F, 0x00, 0xD0, 0x2A, 0x46, 0x4E, 0x46, 0x06, 0xE0, + 0x06, 0xFB, 0x03, 0x45, 0x31, 0xF8, 0x15, 0x70, 0xBF, 0x1A, 0x20, 0xF8, + 0x15, 0x70, 0x76, 0x1E, 0xF6, 0xD2, 0x64, 0x1E, 0xC7, 0xD2, 0xBD, 0xE8, + 0xF0, 0x83, 0x00, 0x00, 0x80, 0x06, 0x10, 0x00, 0xEE, 0x06, 0x10, 0x00, + 0xED, 0x06, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x00, 0x80, 0xFF, 0xFF, + 0x70, 0x47, 0xA5, 0x4A, 0x30, 0xB4, 0x12, 0x68, 0x92, 0xF8, 0xA4, 0x23, + 0x12, 0x09, 0x80, 0xF8, 0x28, 0x20, 0x0A, 0x68, 0x02, 0x62, 0x4A, 0x68, + 0x42, 0x62, 0xB1, 0xF9, 0x02, 0x20, 0xD3, 0x17, 0x1B, 0x04, 0x43, 0xEA, + 0x12, 0x43, 0x12, 0x04, 0x82, 0x60, 0xC3, 0x60, 0xB1, 0xF9, 0x00, 0x10, + 0xCA, 0x17, 0x12, 0x04, 0x42, 0xEA, 0x11, 0x42, 0x09, 0x04, 0x01, 0x60, + 0x42, 0x60, 0x10, 0x22, 0x01, 0x46, 0x30, 0xBC, 0x10, 0x30, 0x0D, 0xF0, + 0x20, 0xBF, 0x2D, 0xE9, 0xF0, 0x4F, 0x92, 0x4F, 0x81, 0x46, 0x8A, 0x46, + 0x38, 0x68, 0x8F, 0xB0, 0x16, 0x46, 0xB0, 0xF8, 0xA6, 0x13, 0x90, 0xF8, + 0xAA, 0x53, 0x01, 0xFB, 0x01, 0xFB, 0xB0, 0xF8, 0xA8, 0x13, 0x01, 0xFB, + 0x01, 0xF8, 0x0E, 0xF0, 0x5B, 0xF8, 0x00, 0x28, 0x38, 0x68, 0x02, 0xD0, + 0x90, 0xF8, 0xAC, 0x43, 0x01, 0xE0, 0x90, 0xF8, 0xAB, 0x43, 0xAC, 0x42, + 0x00, 0xD2, 0x25, 0x46, 0x00, 0x2E, 0x02, 0xDB, 0x89, 0xF8, 0x28, 0x60, + 0x19, 0xE0, 0x09, 0xF1, 0x24, 0x01, 0x99, 0xF8, 0x28, 0x60, 0x08, 0x1F, + 0x0A, 0xF0, 0x5B, 0xF8, 0x58, 0x45, 0x01, 0xDB, 0x26, 0x46, 0x02, 0xE0, + 0x40, 0x45, 0x00, 0xDC, 0x2E, 0x46, 0x38, 0x68, 0x99, 0xF8, 0x28, 0x10, + 0x90, 0xF8, 0xA4, 0x03, 0x00, 0xF0, 0x0F, 0x02, 0x30, 0x46, 0x0A, 0xF0, + 0x6D, 0xF8, 0x89, 0xF8, 0x28, 0x00, 0x99, 0xF8, 0x28, 0x10, 0x74, 0x48, + 0x00, 0xEB, 0x81, 0x00, 0x01, 0x68, 0xCA, 0x17, 0xCD, 0xE9, 0x07, 0x21, + 0x41, 0x6C, 0xCA, 0x17, 0xCD, 0xE9, 0x04, 0x12, 0xD0, 0xF8, 0xCC, 0x20, + 0xD0, 0xF8, 0x88, 0x50, 0xD4, 0x17, 0x01, 0x94, 0x93, 0x46, 0xDD, 0xE9, + 0x07, 0x21, 0xD9, 0xF8, 0x08, 0x30, 0xD9, 0xF8, 0x0C, 0x40, 0xA3, 0xFB, + 0x01, 0x07, 0x04, 0xFB, 0x01, 0x71, 0x03, 0xFB, 0x02, 0x11, 0xEE, 0x17, + 0x4F, 0xF4, 0x80, 0x32, 0x00, 0x23, 0x0D, 0xF0, 0x98, 0xFE, 0xBA, 0xF9, + 0x02, 0x30, 0xB9, 0xF9, 0x26, 0x20, 0x01, 0x9C, 0x9F, 0x18, 0xA7, 0xFB, + 0x0B, 0x38, 0x4F, 0xEA, 0xE7, 0x7C, 0x0C, 0xFB, 0x0B, 0x82, 0x07, 0xFB, + 0x04, 0x24, 0xB9, 0xF9, 0x22, 0x20, 0xA2, 0xFB, 0x05, 0xC8, 0xD7, 0x17, + 0x07, 0xFB, 0x05, 0x87, 0x13, 0xEB, 0x0C, 0x03, 0x02, 0xFB, 0x06, 0x72, + 0x54, 0x41, 0x1F, 0x1A, 0x64, 0xEB, 0x01, 0x04, 0xDD, 0xE9, 0x04, 0x12, + 0xD9, 0xF8, 0x18, 0x30, 0xD9, 0xF8, 0x1C, 0xC0, 0xA3, 0xFB, 0x01, 0x08, + 0x0C, 0xFB, 0x01, 0x81, 0x03, 0xFB, 0x02, 0x11, 0x4F, 0xF4, 0x80, 0x32, + 0x00, 0x23, 0x0D, 0xF0, 0x6A, 0xFE, 0x38, 0x1A, 0x64, 0xEB, 0x01, 0x04, + 0xCD, 0xE9, 0x0D, 0x04, 0x06, 0x94, 0x0A, 0x90, 0xDD, 0xE9, 0x07, 0x21, + 0xD9, 0xF8, 0x00, 0x30, 0xD9, 0xF8, 0x04, 0x40, 0xA3, 0xFB, 0x01, 0x07, + 0x04, 0xFB, 0x01, 0x71, 0x03, 0xFB, 0x02, 0x11, 0x4F, 0xF4, 0x80, 0x32, + 0x00, 0x23, 0x0D, 0xF0, 0x52, 0xFE, 0xBA, 0xF9, 0x00, 0x30, 0xB9, 0xF9, + 0x24, 0x20, 0x01, 0x9C, 0x13, 0x44, 0xA3, 0xFB, 0x0B, 0xC8, 0xDF, 0x17, + 0x07, 0xFB, 0x0B, 0x82, 0x03, 0xFB, 0x04, 0x27, 0xB9, 0xF9, 0x20, 0x20, + 0xA2, 0xFB, 0x05, 0x48, 0xD3, 0x17, 0x03, 0xFB, 0x05, 0x83, 0x02, 0xFB, + 0x06, 0x32, 0x1C, 0xEB, 0x04, 0x03, 0x57, 0x41, 0x1C, 0x1A, 0x67, 0xEB, + 0x01, 0x07, 0xDD, 0xE9, 0x04, 0x12, 0xD9, 0xF8, 0x10, 0x30, 0xD9, 0xF8, + 0x14, 0x50, 0xA3, 0xFB, 0x01, 0x06, 0x05, 0xFB, 0x01, 0x61, 0x03, 0xFB, + 0x02, 0x11, 0x4F, 0xF4, 0x80, 0x32, 0x00, 0x23, 0x0D, 0xF0, 0x25, 0xFE, + 0x25, 0x1A, 0x67, 0xEB, 0x01, 0x07, 0xCD, 0xE9, 0x0B, 0x57, 0xD9, 0xF8, + 0x20, 0x10, 0xC9, 0xF8, 0x24, 0x10, 0xDA, 0xF8, 0x00, 0x10, 0xC9, 0xF8, + 0x20, 0x10, 0x10, 0x22, 0x49, 0x46, 0x09, 0xF1, 0x10, 0x00, 0x0D, 0xF0, + 0x36, 0xFE, 0x10, 0x22, 0x0B, 0xA9, 0x48, 0x46, 0x0D, 0xF0, 0x31, 0xFE, + 0x0A, 0x98, 0x4F, 0xF4, 0x00, 0x41, 0x06, 0x9C, 0x40, 0x18, 0x44, 0xF1, + 0x00, 0x01, 0x4F, 0xF4, 0x80, 0x32, 0x00, 0x23, 0x0D, 0xF0, 0x01, 0xFE, + 0xAA, 0xF8, 0x02, 0x00, 0x4F, 0xF4, 0x00, 0x40, 0x28, 0x18, 0x47, 0xF1, + 0x00, 0x01, 0x4F, 0xF4, 0x80, 0x32, 0x00, 0x23, 0x0D, 0xF0, 0xF5, 0xFD, + 0xAA, 0xF8, 0x00, 0x00, 0x0F, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x70, 0xB5, + 0x0D, 0x46, 0x04, 0x46, 0x01, 0x46, 0x10, 0x22, 0x10, 0x30, 0x0D, 0xF0, + 0x0C, 0xFE, 0xB5, 0xF9, 0x02, 0x00, 0xC1, 0x17, 0x09, 0x04, 0x41, 0xEA, + 0x10, 0x41, 0x00, 0x04, 0xA0, 0x60, 0xE1, 0x60, 0xB5, 0xF9, 0x00, 0x00, + 0xC1, 0x17, 0x09, 0x04, 0x41, 0xEA, 0x10, 0x41, 0x00, 0x04, 0x20, 0x60, + 0x61, 0x60, 0x70, 0xBD, 0x4C, 0x07, 0x10, 0x00, 0xFE, 0x78, 0x01, 0x00, + 0x70, 0xB5, 0x04, 0x46, 0x00, 0x20, 0x84, 0xF8, 0x42, 0x01, 0x94, 0xF8, + 0x3F, 0x01, 0xF8, 0x4D, 0x0E, 0x46, 0x01, 0x28, 0x0B, 0xD0, 0x0D, 0xF0, + 0x37, 0xFF, 0x00, 0x28, 0x94, 0xF9, 0x4C, 0x01, 0x35, 0xD0, 0xB0, 0x42, + 0x28, 0x68, 0x90, 0xF8, 0x9B, 0x03, 0x1A, 0xD1, 0x11, 0xE0, 0xF1, 0x48, + 0x00, 0x78, 0x58, 0xB1, 0x0D, 0xF0, 0x28, 0xFF, 0x00, 0x28, 0x94, 0xF9, + 0x4C, 0x01, 0x0B, 0xD0, 0xB0, 0x42, 0x28, 0x68, 0x90, 0xF8, 0x4D, 0x03, + 0x03, 0xD0, 0x0A, 0xE0, 0x28, 0x68, 0x90, 0xF8, 0x4B, 0x03, 0x00, 0xF0, + 0x0F, 0x00, 0x05, 0xE0, 0xB0, 0x42, 0x28, 0x68, 0x90, 0xF8, 0x4C, 0x03, + 0xF7, 0xD0, 0x00, 0x09, 0x84, 0xF8, 0x42, 0x01, 0xE3, 0x48, 0x00, 0x78, + 0x48, 0xB1, 0x29, 0x68, 0x94, 0xF8, 0x42, 0x01, 0x91, 0xF8, 0x63, 0x12, + 0x01, 0xF0, 0x0F, 0x01, 0x08, 0x44, 0x84, 0xF8, 0x42, 0x01, 0x20, 0x46, + 0x00, 0xF0, 0x4A, 0xF9, 0x01, 0x28, 0x06, 0xD0, 0x0F, 0xE0, 0xB0, 0x42, + 0x28, 0x68, 0x90, 0xF8, 0x9A, 0x03, 0xE4, 0xD1, 0xDB, 0xE7, 0x29, 0x68, + 0x94, 0xF8, 0x42, 0x01, 0x91, 0xF8, 0x9C, 0x13, 0x01, 0xF0, 0x0F, 0x01, + 0x08, 0x44, 0x84, 0xF8, 0x42, 0x01, 0xD3, 0x48, 0xD3, 0x49, 0x00, 0x78, + 0x09, 0x78, 0x08, 0x43, 0x07, 0xD0, 0x29, 0x68, 0x94, 0xF8, 0x42, 0x01, + 0x91, 0xF8, 0x9D, 0x13, 0x08, 0x44, 0x84, 0xF8, 0x42, 0x01, 0x70, 0xBD, + 0xC9, 0x49, 0x10, 0xB5, 0x0C, 0x78, 0xC7, 0x49, 0x90, 0xF8, 0x42, 0x21, + 0x09, 0x68, 0x91, 0xF8, 0x9A, 0x33, 0x03, 0xF0, 0x0F, 0x03, 0x5C, 0xB1, + 0x91, 0xF8, 0x4C, 0x13, 0x01, 0xF0, 0x0F, 0x01, 0xC9, 0x1A, 0x51, 0x1A, + 0x00, 0x29, 0x00, 0xDC, 0x00, 0x21, 0x80, 0xF8, 0x42, 0x11, 0x10, 0xBD, + 0x91, 0xF8, 0x4B, 0x13, 0xF2, 0xE7, 0xC0, 0x49, 0x00, 0x20, 0x08, 0x70, + 0xBF, 0x49, 0x08, 0x70, 0xB9, 0x49, 0x08, 0x70, 0x70, 0x47, 0x2D, 0xE9, + 0xF0, 0x4F, 0x8B, 0xB0, 0x4F, 0xF0, 0x00, 0x09, 0x00, 0xF5, 0x80, 0x55, + 0x04, 0x46, 0x8D, 0xF8, 0x10, 0x90, 0x8D, 0xF8, 0x14, 0x90, 0xB5, 0xF8, + 0xEC, 0x03, 0xB5, 0x4A, 0x00, 0x04, 0x00, 0x0C, 0x0A, 0xD0, 0x4F, 0xF0, + 0xFF, 0x36, 0x10, 0x78, 0x31, 0x46, 0x4F, 0xF0, 0x00, 0x48, 0x93, 0x46, + 0x4F, 0xF0, 0x01, 0x0A, 0xF8, 0xB9, 0x04, 0xE0, 0x48, 0x46, 0x82, 0xF8, + 0x00, 0x90, 0xAD, 0x49, 0xDE, 0xE0, 0x04, 0xF5, 0x80, 0x52, 0x00, 0x20, + 0x92, 0xF9, 0xF4, 0x73, 0x22, 0xE0, 0x00, 0xBF, 0xD2, 0xF8, 0xEC, 0xC3, + 0x0A, 0xFA, 0x00, 0xF3, 0x1C, 0xEA, 0x03, 0x0F, 0x18, 0xD0, 0x00, 0xEB, + 0x00, 0x13, 0x03, 0xEB, 0x83, 0x03, 0x04, 0xEB, 0x83, 0x03, 0x93, 0xF8, + 0x3E, 0xC1, 0xBC, 0xF1, 0x01, 0x0F, 0x01, 0xD0, 0x31, 0x46, 0x0F, 0xE0, + 0xB3, 0xF8, 0x44, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x06, 0xD0, 0x5B, 0x6B, + 0x93, 0xFB, 0xFC, 0xF3, 0x98, 0x45, 0x01, 0xDA, 0x98, 0x46, 0x01, 0x46, + 0x40, 0x1C, 0x40, 0xB2, 0x87, 0x42, 0xDB, 0xDA, 0x00, 0x27, 0xDF, 0xF8, + 0x40, 0x82, 0x01, 0x91, 0x9D, 0xE0, 0x00, 0xBF, 0xD5, 0xF8, 0xEC, 0x13, + 0x0A, 0xFA, 0x07, 0xF0, 0x01, 0x42, 0x60, 0xD0, 0x07, 0xEB, 0x07, 0x10, + 0x00, 0xEB, 0x80, 0x00, 0x04, 0xEB, 0x80, 0x06, 0x96, 0xF8, 0x3E, 0x01, + 0x01, 0x28, 0x02, 0xD0, 0x05, 0x28, 0x08, 0xD0, 0x10, 0xE0, 0x30, 0x46, + 0x01, 0x99, 0xFF, 0xF7, 0x0D, 0xFF, 0x02, 0x20, 0x86, 0xF8, 0x3E, 0x01, + 0x11, 0xE0, 0x30, 0x46, 0x00, 0xF0, 0xB0, 0xF8, 0x06, 0x20, 0x86, 0xF8, + 0x3E, 0x01, 0x30, 0x46, 0x00, 0xF0, 0x48, 0xF9, 0x96, 0xF8, 0x3E, 0x01, + 0x02, 0x28, 0x04, 0xD0, 0x06, 0x28, 0x32, 0xD0, 0x07, 0x28, 0x3B, 0xD0, + 0x46, 0xE0, 0x96, 0xF8, 0x42, 0x00, 0xC0, 0x07, 0x13, 0xD0, 0x30, 0x46, + 0x00, 0xF0, 0x7E, 0xF8, 0x78, 0xB9, 0xD8, 0xF8, 0x00, 0x10, 0x96, 0xF8, + 0x42, 0x01, 0x91, 0xF8, 0x9C, 0x13, 0x01, 0xF0, 0x0F, 0x01, 0x88, 0x42, + 0x03, 0xD9, 0x40, 0x1A, 0x86, 0xF8, 0x42, 0x01, 0x01, 0xE0, 0x86, 0xF8, + 0x42, 0x91, 0x6E, 0x48, 0x00, 0x78, 0x40, 0xB1, 0x96, 0xF8, 0x42, 0x01, + 0x10, 0xBB, 0xD8, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0x9D, 0x03, 0x86, 0xF8, + 0x42, 0x01, 0x96, 0xF8, 0x42, 0x01, 0xC8, 0xB9, 0x03, 0x20, 0x86, 0xF8, + 0x3E, 0x01, 0x9B, 0xF8, 0x00, 0x00, 0x40, 0x1C, 0x8B, 0xF8, 0x00, 0x00, + 0x2B, 0xE0, 0x96, 0xF8, 0x43, 0x01, 0x18, 0xBB, 0x96, 0xF8, 0x42, 0x00, + 0x80, 0x07, 0x03, 0xD5, 0x07, 0x20, 0x86, 0xF8, 0x3E, 0x01, 0x32, 0xE0, + 0x08, 0x20, 0x86, 0xF8, 0x3E, 0x01, 0x30, 0x46, 0x00, 0xF0, 0xA7, 0xF8, + 0x96, 0xF8, 0x3E, 0x01, 0x02, 0x28, 0x07, 0xD0, 0x06, 0x28, 0x0C, 0xD0, + 0xC0, 0xB2, 0x03, 0x28, 0x11, 0xD0, 0x04, 0x28, 0x0F, 0xD0, 0x20, 0xE0, + 0x96, 0xF8, 0x42, 0x01, 0xE8, 0xB1, 0x40, 0x1E, 0x86, 0xF8, 0x42, 0x01, + 0x19, 0xE0, 0x96, 0xF8, 0x43, 0x01, 0xB0, 0xB1, 0xC0, 0xB2, 0x40, 0x1E, + 0x86, 0xF8, 0x43, 0x01, 0x11, 0xE0, 0x96, 0xF8, 0x3F, 0x01, 0x01, 0x28, + 0x02, 0xD0, 0x03, 0x28, 0x06, 0xD0, 0x0A, 0xE0, 0x9D, 0xF8, 0x14, 0x00, + 0x40, 0x1C, 0x8D, 0xF8, 0x14, 0x00, 0x04, 0xE0, 0x9D, 0xF8, 0x10, 0x00, + 0x40, 0x1C, 0x8D, 0xF8, 0x10, 0x00, 0x7F, 0x1C, 0x7F, 0xB2, 0x95, 0xF9, + 0xF4, 0x03, 0xB8, 0x42, 0xBF, 0xF6, 0x5E, 0xAF, 0x05, 0xAA, 0x04, 0xA9, + 0x20, 0x46, 0x00, 0xF0, 0x87, 0xF8, 0x41, 0x49, 0x9D, 0xF8, 0x10, 0x00, + 0x08, 0x70, 0x9D, 0xF8, 0x14, 0x00, 0x3F, 0x49, 0x08, 0x70, 0x0B, 0xB0, + 0xBD, 0xE8, 0xF0, 0x8F, 0x90, 0xF8, 0x5B, 0x10, 0x90, 0xF8, 0x5A, 0x20, + 0x8A, 0x1A, 0xB0, 0xF8, 0x42, 0x10, 0x52, 0x1C, 0x02, 0x2A, 0x0B, 0xD9, + 0x90, 0xF8, 0x5D, 0x20, 0x90, 0xF8, 0x5C, 0x30, 0x9A, 0x42, 0x05, 0xD1, + 0x41, 0xF0, 0x01, 0x01, 0xA0, 0xF8, 0x42, 0x10, 0x01, 0x20, 0x70, 0x47, + 0x21, 0xF0, 0x01, 0x01, 0xA0, 0xF8, 0x42, 0x10, 0x00, 0x20, 0x70, 0x47, + 0x70, 0xB5, 0x00, 0x25, 0x04, 0x46, 0x80, 0xF8, 0x43, 0x51, 0x0D, 0xF0, + 0x93, 0xFD, 0x01, 0x00, 0x22, 0x48, 0x0C, 0xD0, 0x01, 0x68, 0x01, 0x25, + 0x91, 0xF8, 0x9E, 0x13, 0x5F, 0xEA, 0x11, 0x11, 0x84, 0xF8, 0x43, 0x11, + 0x94, 0xF8, 0x3F, 0x11, 0x01, 0x29, 0x06, 0xD0, 0x0E, 0xE0, 0x01, 0x68, + 0x91, 0xF8, 0x9E, 0x13, 0x01, 0xF0, 0x0F, 0x01, 0xF2, 0xE7, 0x02, 0x68, + 0x94, 0xF8, 0x43, 0x11, 0x92, 0xF8, 0x4B, 0x23, 0x01, 0xEB, 0x12, 0x11, + 0x84, 0xF8, 0x43, 0x11, 0x1D, 0xB9, 0x94, 0xF8, 0x42, 0x10, 0x89, 0x07, + 0x0D, 0xD4, 0x01, 0x68, 0xE2, 0x6A, 0x91, 0xF8, 0x9F, 0x13, 0x01, 0xF0, + 0x0F, 0x03, 0x9A, 0x42, 0x05, 0xD9, 0x94, 0xF8, 0x43, 0x21, 0x02, 0xEB, + 0x11, 0x11, 0x84, 0xF8, 0x43, 0x11, 0x0C, 0x49, 0x09, 0x78, 0x00, 0x29, + 0x08, 0xD0, 0x00, 0x68, 0x94, 0xF8, 0x43, 0x11, 0x90, 0xF8, 0x63, 0x02, + 0x01, 0xEB, 0x10, 0x10, 0x84, 0xF8, 0x43, 0x01, 0x70, 0xBD, 0x08, 0x49, + 0x08, 0x78, 0x00, 0x28, 0x01, 0xD0, 0x40, 0x1E, 0x08, 0x70, 0x70, 0x47, + 0x4C, 0x07, 0x10, 0x00, 0xF9, 0x06, 0x10, 0x00, 0x74, 0x05, 0x10, 0x00, + 0x76, 0x06, 0x10, 0x00, 0x7D, 0x07, 0x10, 0x00, 0xFA, 0x06, 0x10, 0x00, + 0x20, 0x07, 0x10, 0x00, 0xFB, 0x06, 0x10, 0x00, 0xFC, 0x06, 0x10, 0x00, + 0x2D, 0xE9, 0xF0, 0x47, 0x16, 0x46, 0x07, 0x46, 0x0B, 0x78, 0x34, 0x4A, + 0x01, 0x20, 0x23, 0xB9, 0x33, 0x78, 0x13, 0xB1, 0x10, 0x70, 0xBD, 0xE8, + 0xF0, 0x87, 0x00, 0x23, 0x13, 0x70, 0x00, 0x29, 0xF9, 0xD0, 0x31, 0x78, + 0x00, 0x29, 0xF6, 0xD0, 0x00, 0x24, 0x07, 0xF5, 0x80, 0x55, 0x80, 0x46, + 0x4F, 0xF0, 0x02, 0x09, 0x1D, 0xE0, 0x00, 0xBF, 0xD5, 0xF8, 0xEC, 0x13, + 0x08, 0xFA, 0x04, 0xF0, 0x01, 0x42, 0x14, 0xD0, 0x04, 0xEB, 0x04, 0x10, + 0x00, 0xEB, 0x80, 0x00, 0x07, 0xEB, 0x80, 0x00, 0x90, 0xF8, 0x3E, 0x11, + 0x03, 0x29, 0x0A, 0xD1, 0x90, 0xF8, 0x3F, 0x11, 0x01, 0x29, 0x06, 0xD1, + 0x80, 0xF8, 0x3E, 0x91, 0xFF, 0xF7, 0xB3, 0xFF, 0x30, 0x78, 0x40, 0x1E, + 0x30, 0x70, 0x64, 0x1C, 0x64, 0xB2, 0x95, 0xF9, 0xF4, 0x03, 0xA0, 0x42, + 0xDE, 0xDA, 0xCC, 0xE7, 0x2D, 0xE9, 0xF0, 0x41, 0x17, 0x4D, 0x04, 0x46, + 0x28, 0x68, 0x90, 0xF8, 0x81, 0x03, 0xC0, 0x07, 0x24, 0xD0, 0x21, 0x46, + 0x20, 0x1D, 0x09, 0xF0, 0x06, 0xFD, 0x07, 0x46, 0x21, 0x46, 0x04, 0xF1, + 0x20, 0x00, 0x09, 0xF0, 0x00, 0xFD, 0x06, 0x46, 0x0D, 0xF0, 0xE6, 0xFC, + 0x00, 0x28, 0x28, 0x68, 0x05, 0xD0, 0xB0, 0xF8, 0x93, 0x13, 0xB0, 0xF8, + 0x8F, 0x03, 0x49, 0x43, 0x04, 0xE0, 0xB0, 0xF8, 0x91, 0x13, 0xB0, 0xF8, + 0x8D, 0x03, 0x49, 0x43, 0x40, 0x43, 0x86, 0x42, 0x06, 0xDD, 0x8F, 0x42, + 0x04, 0xDD, 0x34, 0xF8, 0x42, 0x0F, 0x40, 0xF0, 0x02, 0x00, 0x20, 0x80, + 0xBD, 0xE8, 0xF0, 0x81, 0xF9, 0x06, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0xF8, 0xB5, 0x15, 0x46, 0x0E, 0x46, 0x04, 0x46, 0x0D, 0xF0, 0xC2, 0xFC, + 0x01, 0x00, 0xF9, 0x48, 0x0B, 0xD0, 0x00, 0x68, 0x90, 0xF8, 0xB4, 0x13, + 0xB0, 0xF8, 0xB7, 0x23, 0x01, 0xF0, 0x0F, 0x03, 0x0C, 0x09, 0xB0, 0xF8, + 0xB5, 0x13, 0x49, 0x43, 0x10, 0xE0, 0x94, 0xF8, 0x3F, 0x11, 0x02, 0x29, + 0x13, 0xD0, 0x00, 0x68, 0x01, 0x29, 0x14, 0xD0, 0x90, 0xF8, 0xB9, 0x13, + 0xB0, 0xF8, 0xC0, 0x23, 0x01, 0xF0, 0x0F, 0x03, 0x0C, 0x09, 0xB0, 0xF8, + 0xBE, 0x13, 0x49, 0x43, 0x52, 0x43, 0x30, 0x46, 0x00, 0x94, 0x09, 0xF0, + 0xC2, 0xFC, 0x2C, 0x60, 0xF8, 0xBD, 0x00, 0x68, 0x90, 0xF8, 0xBA, 0x13, + 0xEC, 0xE7, 0x90, 0xF8, 0xBB, 0x13, 0xB0, 0xF8, 0xC4, 0x23, 0x01, 0xF0, + 0x0F, 0x03, 0x0C, 0x09, 0xB0, 0xF8, 0xC2, 0x13, 0x49, 0x43, 0xE9, 0xE7, + 0x2D, 0xE9, 0xF8, 0x43, 0x04, 0x46, 0x90, 0xF8, 0x3E, 0x01, 0x88, 0x46, + 0x04, 0xF1, 0x78, 0x07, 0x03, 0x28, 0x0B, 0xD0, 0xD9, 0x4E, 0x04, 0x28, + 0x0D, 0xD0, 0x07, 0x28, 0x3B, 0xD0, 0x08, 0x28, 0x37, 0xD1, 0x38, 0x46, + 0xBD, 0xE8, 0xF8, 0x43, 0x00, 0xF0, 0xC5, 0xBB, 0x38, 0x46, 0xBD, 0xE8, + 0xF8, 0x43, 0x00, 0xF0, 0x8E, 0xBB, 0x20, 0x46, 0x0D, 0xF0, 0x83, 0xFC, + 0x18, 0xB1, 0x20, 0x46, 0x0D, 0xF0, 0x7A, 0xFC, 0x1D, 0xE0, 0x04, 0xF1, + 0x0C, 0x01, 0x08, 0x1D, 0x09, 0xF0, 0x7B, 0xFC, 0x01, 0x46, 0x6A, 0x46, + 0x20, 0x46, 0xFF, 0xF7, 0x97, 0xFF, 0x05, 0x46, 0x94, 0xF8, 0x41, 0x01, + 0x80, 0xB9, 0x20, 0x46, 0x0D, 0xF0, 0x6A, 0xFC, 0x10, 0xB1, 0x00, 0x98, + 0x85, 0x42, 0x09, 0xDB, 0x30, 0x68, 0xD4, 0xF8, 0x80, 0x10, 0x90, 0xF8, + 0xBC, 0x03, 0x02, 0x09, 0x28, 0x46, 0x09, 0xF0, 0x85, 0xFC, 0x05, 0x46, + 0x2A, 0x46, 0x41, 0x46, 0x38, 0x46, 0x00, 0xF0, 0x64, 0xFB, 0xC4, 0xF8, + 0x80, 0x50, 0xBD, 0xE8, 0xF8, 0x83, 0x30, 0x68, 0x00, 0x24, 0x90, 0xF8, + 0x81, 0x13, 0x89, 0x07, 0x0A, 0xD5, 0x90, 0xF8, 0xBD, 0x03, 0x00, 0xF0, + 0x0F, 0x04, 0x0D, 0xF0, 0x35, 0xFC, 0x18, 0xB1, 0x30, 0x68, 0x90, 0xF8, + 0xBD, 0x03, 0x04, 0x09, 0x22, 0x46, 0x41, 0x46, 0x38, 0x46, 0xBD, 0xE8, + 0xF8, 0x43, 0x00, 0xF0, 0x60, 0xBB, 0x2D, 0xE9, 0xF0, 0x43, 0xDF, 0xF8, + 0xB0, 0x92, 0x4F, 0xF0, 0x00, 0x0C, 0xB0, 0xF9, 0x02, 0x30, 0xD9, 0xF8, + 0x00, 0x40, 0x67, 0x46, 0x66, 0x46, 0x65, 0x46, 0x00, 0x2B, 0x02, 0xDA, + 0x4F, 0xF0, 0x01, 0x0C, 0x04, 0xE0, 0xB4, 0xF8, 0x32, 0x80, 0x98, 0x45, + 0x00, 0xDA, 0x01, 0x27, 0xB0, 0xF9, 0x00, 0x30, 0x00, 0x2B, 0x01, 0xDA, + 0x01, 0x26, 0x04, 0xE0, 0xB4, 0xF8, 0x34, 0x80, 0x98, 0x45, 0x00, 0xDA, + 0x01, 0x25, 0x00, 0x23, 0xBC, 0xF1, 0x00, 0x0F, 0x02, 0xD0, 0x0E, 0xB1, + 0x43, 0x80, 0x03, 0xE0, 0x4F, 0xB1, 0x26, 0xB1, 0x61, 0x8E, 0x38, 0xE0, + 0x03, 0x80, 0xBD, 0xE8, 0xF0, 0x83, 0x15, 0xB1, 0x62, 0x8E, 0x42, 0x80, + 0x04, 0xE0, 0xBC, 0xF1, 0x00, 0x0F, 0x30, 0xD0, 0x2D, 0xB1, 0x43, 0x80, + 0xD9, 0xF8, 0x00, 0x10, 0x89, 0x8E, 0x01, 0x80, 0xEF, 0xE7, 0xB2, 0xF8, + 0x02, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x24, 0xD0, 0x43, 0x80, 0xB1, 0xF9, + 0x02, 0x40, 0x67, 0x42, 0x2C, 0xE0, 0x00, 0xBF, 0x0C, 0xFB, 0x07, 0xFC, + 0x00, 0x2C, 0x00, 0xDA, 0x64, 0x42, 0x9C, 0xFB, 0xF4, 0xF4, 0x0F, 0x88, + 0x3C, 0x44, 0x04, 0x80, 0x46, 0xB3, 0xB2, 0xF9, 0x00, 0x40, 0x2C, 0xB3, + 0xB1, 0xF9, 0x00, 0x50, 0xB2, 0xF9, 0x02, 0x20, 0x6D, 0x42, 0x00, 0xD5, + 0x6D, 0x42, 0x6A, 0x43, 0x00, 0x2C, 0x00, 0xDA, 0x64, 0x42, 0x92, 0xFB, + 0xF4, 0xF2, 0x49, 0x88, 0x11, 0x44, 0x41, 0x80, 0xC4, 0xE7, 0x00, 0x2F, + 0xE8, 0xD0, 0x57, 0x88, 0x00, 0x2F, 0xE5, 0xD0, 0x64, 0x8E, 0x44, 0x80, + 0xD9, 0xF8, 0x00, 0x40, 0xB1, 0xF9, 0x02, 0x70, 0x64, 0x8E, 0xE7, 0x1B, + 0xB2, 0xF9, 0x02, 0x40, 0xB2, 0xF9, 0x00, 0xC0, 0x00, 0x2F, 0xCD, 0xDA, + 0x7F, 0x42, 0xCB, 0xE7, 0x00, 0x2D, 0xAE, 0xD0, 0xB2, 0xF9, 0x00, 0x30, + 0x00, 0x2B, 0xAA, 0xD0, 0xD9, 0xF8, 0x00, 0x40, 0xB1, 0xF9, 0x00, 0x60, + 0xB2, 0xF9, 0x02, 0x20, 0xA4, 0x8E, 0xA4, 0x1B, 0x00, 0xD5, 0x64, 0x42, + 0x62, 0x43, 0x00, 0x2B, 0x00, 0xDA, 0x5B, 0x42, 0x92, 0xFB, 0xF3, 0xF2, + 0x49, 0x88, 0x11, 0x44, 0x41, 0x80, 0xA1, 0xE7, 0x2D, 0xE9, 0xF0, 0x5F, + 0x04, 0x46, 0x61, 0x48, 0x0D, 0x46, 0x00, 0x21, 0x41, 0x80, 0x01, 0x80, + 0xA0, 0xF1, 0x10, 0x08, 0x28, 0x68, 0xC8, 0xF8, 0x00, 0x00, 0x17, 0x46, + 0x4F, 0xF0, 0x01, 0x0B, 0x46, 0x46, 0x29, 0x46, 0x20, 0x46, 0x00, 0xF0, + 0x67, 0xFF, 0xDF, 0xF8, 0x5C, 0x91, 0x28, 0x68, 0x70, 0x60, 0xD9, 0xF8, + 0x00, 0x00, 0x04, 0xF1, 0x0C, 0x0A, 0x90, 0xF8, 0x80, 0x03, 0x41, 0x07, + 0x22, 0xD5, 0x94, 0xF8, 0x3E, 0x01, 0x04, 0xF1, 0x84, 0x06, 0x02, 0x28, + 0x0A, 0xD0, 0x03, 0x28, 0x08, 0xD0, 0x04, 0x28, 0x0B, 0xD0, 0x06, 0x28, + 0x12, 0xD0, 0x07, 0x28, 0x10, 0xD0, 0x08, 0x28, 0x0E, 0xD0, 0x11, 0xE0, + 0x51, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0xC9, 0xFA, 0x0C, 0xE0, 0x20, 0x46, + 0x00, 0xF0, 0xDD, 0xF9, 0x02, 0x46, 0x29, 0x46, 0x30, 0x46, 0xFF, 0xF7, + 0xE4, 0xFA, 0x03, 0xE0, 0x29, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0xEB, 0xFB, + 0x29, 0x68, 0xC8, 0xF8, 0x08, 0x10, 0xD9, 0xF8, 0x00, 0x00, 0x4E, 0x46, + 0x90, 0xF8, 0x80, 0x03, 0x00, 0x07, 0x09, 0xD5, 0x94, 0xF8, 0x42, 0x00, + 0x10, 0xF0, 0xC8, 0x0F, 0x35, 0xD0, 0x51, 0x46, 0x04, 0xF1, 0xB0, 0x00, + 0x00, 0xF0, 0xF3, 0xFD, 0x29, 0x68, 0xC8, 0xF8, 0x0C, 0x10, 0x30, 0x68, + 0x90, 0xF8, 0x80, 0x13, 0x49, 0x06, 0x0F, 0xD4, 0x90, 0xF8, 0x40, 0x14, + 0x49, 0x06, 0x03, 0xD5, 0x94, 0xF8, 0x42, 0x10, 0x09, 0x07, 0x07, 0xD4, + 0x90, 0xF8, 0x20, 0x04, 0x80, 0x07, 0x07, 0xD5, 0x94, 0xF8, 0x42, 0x00, + 0x00, 0x06, 0x03, 0xD5, 0x29, 0x46, 0x20, 0x46, 0x01, 0xF0, 0xBC, 0xFC, + 0x30, 0x68, 0x90, 0xF8, 0x80, 0x03, 0x80, 0x06, 0x03, 0xD5, 0x29, 0x46, + 0x20, 0x46, 0xFF, 0xF7, 0x89, 0xFE, 0x30, 0x68, 0x90, 0xF8, 0x80, 0x03, + 0x01, 0x07, 0x11, 0xD5, 0xC0, 0x06, 0x0F, 0xD5, 0x94, 0xF8, 0x3E, 0x01, + 0x07, 0x28, 0x05, 0xD0, 0x0A, 0xE0, 0x29, 0x46, 0x20, 0x46, 0x00, 0xF0, + 0xB2, 0xF9, 0xC9, 0xE7, 0x1B, 0x4A, 0x04, 0xF1, 0xF4, 0x01, 0x28, 0x46, + 0xFF, 0xF7, 0xD5, 0xFE, 0x30, 0x68, 0xB0, 0xF9, 0x32, 0x10, 0xB5, 0xF9, + 0x02, 0x00, 0x09, 0xF0, 0xD7, 0xFA, 0x68, 0x80, 0x30, 0x68, 0xB0, 0xF9, + 0x34, 0x10, 0xB5, 0xF9, 0x00, 0x00, 0x09, 0xF0, 0xCF, 0xFA, 0x28, 0x80, + 0x94, 0xF8, 0x3E, 0x01, 0x03, 0x28, 0x06, 0xD0, 0x04, 0x28, 0x08, 0xD0, + 0x07, 0x28, 0x1B, 0xD0, 0x08, 0x28, 0x19, 0xD0, 0x1B, 0xE0, 0x38, 0x88, + 0xA4, 0xF8, 0x50, 0x00, 0x17, 0xE0, 0x30, 0x68, 0x34, 0xF8, 0x50, 0x2F, + 0x90, 0xF8, 0xBC, 0x03, 0x00, 0xF0, 0x0F, 0x01, 0xC1, 0xF1, 0x10, 0x00, + 0x4A, 0x43, 0x39, 0x88, 0x01, 0xFB, 0x00, 0x20, 0x00, 0x09, 0x20, 0x80, + 0x06, 0xE0, 0x00, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x94, 0x05, 0x10, 0x00, + 0xB4, 0xF8, 0x50, 0x00, 0x38, 0x80, 0x58, 0x46, 0xBD, 0xE8, 0xF0, 0x9F, + 0x2D, 0xE9, 0xF3, 0x4F, 0xE4, 0x49, 0x83, 0xB0, 0x4F, 0xF0, 0x00, 0x08, + 0xC1, 0xF8, 0x00, 0x80, 0xE2, 0x49, 0xE3, 0x4D, 0x83, 0x46, 0xC1, 0xF8, + 0x00, 0x80, 0x85, 0xF8, 0x00, 0x80, 0x46, 0x46, 0xDF, 0xF8, 0x80, 0xA3, + 0x4F, 0xF0, 0x01, 0x09, 0x00, 0xF5, 0x80, 0x57, 0x77, 0xE0, 0x00, 0xBF, + 0xD7, 0xF8, 0xEC, 0x13, 0x09, 0xFA, 0x06, 0xF0, 0x01, 0x42, 0x6F, 0xD0, + 0x06, 0xEB, 0x06, 0x10, 0x00, 0xEB, 0x80, 0x01, 0x0B, 0xEB, 0x81, 0x04, + 0x94, 0xF8, 0x3E, 0x01, 0x03, 0x28, 0x05, 0xD0, 0x04, 0x28, 0x03, 0xD0, + 0x07, 0x28, 0x01, 0xD0, 0x08, 0x28, 0x5F, 0xD1, 0xE0, 0x68, 0x00, 0x90, + 0xB4, 0xF8, 0x4E, 0x00, 0xAD, 0xF8, 0x04, 0x00, 0x04, 0xF1, 0x0C, 0x01, + 0xCA, 0x4A, 0x08, 0x1D, 0x00, 0xF0, 0x06, 0xF9, 0x01, 0xAA, 0x69, 0x46, + 0x20, 0x46, 0xFF, 0xF7, 0xF3, 0xFE, 0x02, 0x90, 0xC6, 0x4A, 0x69, 0x46, + 0x04, 0xF1, 0x24, 0x00, 0x00, 0xF0, 0xFA, 0xF8, 0x94, 0xF8, 0x3F, 0x01, + 0x01, 0x28, 0x08, 0xD1, 0xC4, 0x48, 0x00, 0x78, 0x28, 0xB9, 0x94, 0xF8, + 0x3E, 0x01, 0x08, 0x28, 0x01, 0xD0, 0x00, 0x20, 0x02, 0x90, 0xDA, 0xF8, + 0x00, 0x00, 0x90, 0xF8, 0x00, 0x04, 0xC0, 0x07, 0x0E, 0xD0, 0x94, 0xF8, + 0x42, 0x00, 0x40, 0x07, 0x02, 0xD5, 0x00, 0x20, 0x02, 0x90, 0x07, 0xE0, + 0x94, 0xF8, 0x34, 0x01, 0x01, 0x28, 0x03, 0xD1, 0x20, 0x6A, 0x00, 0x90, + 0x84, 0xF8, 0x34, 0x81, 0x94, 0xF8, 0x3F, 0x01, 0x03, 0x28, 0x09, 0xD1, + 0x28, 0x78, 0x40, 0x1C, 0xC0, 0xB2, 0x28, 0x70, 0x94, 0xF8, 0x42, 0x10, + 0x49, 0x07, 0x01, 0xD5, 0x40, 0x1E, 0x28, 0x70, 0x00, 0x98, 0x60, 0x62, + 0xBD, 0xF8, 0x04, 0x00, 0xA4, 0xF8, 0x50, 0x00, 0x02, 0x98, 0x01, 0x28, + 0x0E, 0xD1, 0x00, 0x98, 0xA0, 0x61, 0xBD, 0xF8, 0x04, 0x00, 0xA4, 0xF8, + 0x52, 0x00, 0x04, 0x98, 0x94, 0xF8, 0x4C, 0x21, 0x00, 0x68, 0x09, 0xFA, + 0x02, 0xF1, 0x08, 0x43, 0x04, 0x99, 0x08, 0x60, 0x76, 0x1C, 0x97, 0xF9, + 0xF4, 0x03, 0xB0, 0x42, 0x84, 0xDA, 0xDA, 0xF8, 0x00, 0x00, 0x90, 0xF8, + 0x00, 0x04, 0x00, 0x07, 0x0E, 0xD5, 0x29, 0x78, 0x9D, 0x48, 0x29, 0xB1, + 0x9D, 0x49, 0x09, 0x78, 0x01, 0x29, 0x01, 0xD1, 0x80, 0xF8, 0x00, 0x90, + 0xD7, 0xF8, 0xF0, 0x13, 0x00, 0x29, 0x01, 0xD1, 0x80, 0xF8, 0x00, 0x80, + 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x2D, 0xE9, 0xF0, 0x47, 0x89, 0x46, + 0x06, 0x46, 0x00, 0x27, 0x4F, 0xF0, 0x01, 0x08, 0x00, 0xF5, 0x80, 0x55, + 0x3D, 0xE0, 0x00, 0xBF, 0xD5, 0xF8, 0xEC, 0x13, 0x08, 0xFA, 0x07, 0xF2, + 0x11, 0x42, 0x35, 0xD0, 0x07, 0xEB, 0x07, 0x11, 0x01, 0xEB, 0x81, 0x01, + 0x06, 0xEB, 0x81, 0x04, 0x94, 0xF8, 0x3E, 0x11, 0x03, 0x29, 0x05, 0xD0, + 0x04, 0x29, 0x03, 0xD0, 0x07, 0x29, 0x01, 0xD0, 0x08, 0x29, 0x25, 0xD1, + 0x94, 0xF8, 0x4C, 0x31, 0xD9, 0xF8, 0x00, 0x20, 0x08, 0xFA, 0x03, 0xF0, + 0x02, 0x42, 0x1D, 0xD0, 0x03, 0x29, 0x03, 0xD1, 0x21, 0x46, 0x30, 0x46, + 0x02, 0xF0, 0x7A, 0xF8, 0x94, 0xF9, 0x4D, 0x01, 0x00, 0x28, 0x13, 0xDB, + 0x94, 0xF8, 0x3F, 0x01, 0x00, 0x21, 0x01, 0x28, 0x04, 0xD0, 0x02, 0x28, + 0x04, 0xD0, 0x04, 0x28, 0x04, 0xD0, 0x04, 0xE0, 0x03, 0x21, 0x02, 0xE0, + 0x04, 0x21, 0x00, 0xE0, 0x05, 0x21, 0x84, 0xF8, 0x40, 0x11, 0x20, 0x46, + 0x08, 0xF0, 0x7D, 0xFC, 0x7F, 0x1C, 0x95, 0xF9, 0xF4, 0x03, 0xB8, 0x42, + 0xBE, 0xDA, 0x00, 0x24, 0x47, 0x46, 0x24, 0xE0, 0xD5, 0xF8, 0xEC, 0x03, + 0x07, 0xFA, 0x04, 0xF1, 0x08, 0x42, 0x1D, 0xD0, 0x04, 0xEB, 0x04, 0x10, + 0x00, 0xEB, 0x80, 0x00, 0x06, 0xEB, 0x80, 0x08, 0x98, 0xF8, 0x3E, 0x01, + 0x08, 0x28, 0x13, 0xD1, 0x98, 0xF8, 0x4C, 0x21, 0xD9, 0xF8, 0x00, 0x10, + 0x07, 0xFA, 0x02, 0xF0, 0x01, 0x42, 0x07, 0xD0, 0x98, 0xF9, 0x4D, 0x01, + 0x00, 0x28, 0x03, 0xDB, 0x41, 0x46, 0x30, 0x46, 0x02, 0xF0, 0x55, 0xF8, + 0x41, 0x46, 0x30, 0x46, 0x02, 0xF0, 0x18, 0xF8, 0x64, 0x1C, 0x95, 0xF9, + 0xF4, 0x03, 0xA0, 0x42, 0xD6, 0xDA, 0xBD, 0xE8, 0xF0, 0x87, 0x53, 0x49, + 0x10, 0xB5, 0x00, 0x20, 0x08, 0x60, 0x52, 0x49, 0x08, 0x60, 0xFF, 0xF7, + 0x03, 0xF9, 0x00, 0xF0, 0x2F, 0xFC, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, + 0xAD, 0xB8, 0x38, 0xB5, 0x04, 0x46, 0x00, 0x20, 0x00, 0x90, 0x69, 0x46, + 0x20, 0x46, 0xFF, 0xF7, 0xC5, 0xFE, 0x69, 0x46, 0x20, 0x46, 0xFF, 0xF7, + 0x6C, 0xFF, 0x38, 0xBD, 0x10, 0xB5, 0x14, 0x46, 0x09, 0xF0, 0x97, 0xF9, + 0x21, 0x68, 0x81, 0x42, 0x00, 0xDA, 0x20, 0x60, 0x10, 0xBD, 0x10, 0xB5, + 0x02, 0x46, 0x43, 0x49, 0xB2, 0xF8, 0x42, 0x30, 0x4F, 0xF0, 0xFF, 0x30, + 0x09, 0x68, 0x5C, 0x06, 0x03, 0xD5, 0x91, 0xF8, 0xA5, 0x03, 0x00, 0x09, + 0x10, 0xBD, 0x1C, 0x07, 0x02, 0xD5, 0x91, 0xF8, 0x4F, 0x04, 0x03, 0xE0, + 0x1B, 0x06, 0x04, 0xD5, 0x91, 0xF8, 0x2A, 0x04, 0x00, 0xF0, 0x0F, 0x00, + 0x10, 0xBD, 0x92, 0xF8, 0x3F, 0x21, 0x01, 0x2A, 0x06, 0xD0, 0x39, 0x4A, + 0x12, 0x78, 0x01, 0x2A, 0xF6, 0xD9, 0x91, 0xF9, 0xAA, 0x03, 0x10, 0xBD, + 0x91, 0xF8, 0xA5, 0x03, 0xEE, 0xE7, 0x30, 0xB4, 0x0C, 0x46, 0x90, 0xF8, + 0x3E, 0x11, 0x00, 0xF1, 0xB0, 0x03, 0x03, 0x29, 0x23, 0xD0, 0x04, 0x29, + 0x03, 0xD0, 0x06, 0x29, 0x01, 0xD0, 0x07, 0x29, 0x41, 0xD1, 0x29, 0x4A, + 0x12, 0x68, 0x92, 0xF8, 0x80, 0x23, 0xD2, 0x06, 0x2D, 0xD5, 0x90, 0xF8, + 0x5B, 0x20, 0x90, 0xF8, 0x5A, 0x50, 0x52, 0x1B, 0xC0, 0xF8, 0x24, 0x21, + 0x90, 0xF8, 0x5D, 0x20, 0x90, 0xF8, 0x5C, 0x50, 0x52, 0x1B, 0xC0, 0xF8, + 0x28, 0x21, 0x82, 0x6B, 0xC0, 0xF8, 0x20, 0x21, 0x22, 0x4A, 0x07, 0x29, + 0x12, 0x88, 0xC0, 0xF8, 0x2C, 0x21, 0x06, 0xD0, 0x0F, 0xE0, 0x00, 0xF1, + 0x0C, 0x01, 0x30, 0xBC, 0x18, 0x46, 0x00, 0xF0, 0xDA, 0xBB, 0x90, 0xF8, + 0x31, 0x11, 0x03, 0x29, 0x05, 0xD9, 0x21, 0x46, 0x30, 0xBC, 0x1A, 0x4A, + 0x18, 0x46, 0x00, 0xF0, 0x68, 0xBC, 0x90, 0xF8, 0x31, 0x11, 0x49, 0x1C, + 0x80, 0xF8, 0x31, 0x11, 0x03, 0xE0, 0x90, 0xF8, 0x31, 0x21, 0x03, 0x2A, + 0x04, 0xD9, 0x21, 0x46, 0x30, 0xBC, 0x18, 0x46, 0x00, 0xF0, 0x26, 0xBC, + 0x04, 0x29, 0x04, 0xD0, 0x00, 0x21, 0x80, 0xF8, 0x31, 0x11, 0x30, 0xBC, + 0x70, 0x47, 0x52, 0x1C, 0x80, 0xF8, 0x31, 0x21, 0x21, 0x46, 0x30, 0xBC, + 0x18, 0x46, 0x00, 0xF0, 0x00, 0xBC, 0x00, 0x00, 0x24, 0x07, 0x10, 0x00, + 0x28, 0x07, 0x10, 0x00, 0x20, 0x07, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0xF9, 0x06, 0x10, 0x00, 0xA5, 0x06, 0x10, 0x00, 0xA4, 0x06, 0x10, 0x00, + 0xFA, 0x06, 0x10, 0x00, 0x78, 0x06, 0x10, 0x00, 0x94, 0x05, 0x10, 0x00, + 0x70, 0x47, 0x00, 0xF0, 0x35, 0xB8, 0x7C, 0xB5, 0x04, 0x46, 0x15, 0x46, + 0x0E, 0x46, 0x68, 0x46, 0x00, 0xF0, 0x2E, 0xF8, 0x01, 0x99, 0x2A, 0x46, + 0x60, 0x68, 0x00, 0xF0, 0x3B, 0xF8, 0x60, 0x60, 0x00, 0x99, 0x2A, 0x46, + 0x20, 0x68, 0x00, 0xF0, 0x35, 0xF8, 0x20, 0x60, 0x21, 0x46, 0x30, 0x46, + 0x00, 0xF0, 0x27, 0xF8, 0x7C, 0xBD, 0x7C, 0xB5, 0x04, 0x46, 0x15, 0x46, + 0x0E, 0x46, 0x68, 0x46, 0x00, 0xF0, 0x16, 0xF8, 0x01, 0x99, 0x2A, 0x46, + 0x60, 0x68, 0x00, 0xF0, 0x23, 0xF8, 0x60, 0x60, 0x00, 0x99, 0x2A, 0x46, + 0x20, 0x68, 0x00, 0xF0, 0x1D, 0xF8, 0x20, 0x60, 0x21, 0x46, 0x30, 0x46, + 0x00, 0xF0, 0x0F, 0xF8, 0x7C, 0xBD, 0x0A, 0x46, 0x01, 0x46, 0x10, 0x46, + 0x00, 0xF0, 0x09, 0xB8, 0xB1, 0xF9, 0x02, 0x20, 0x12, 0x02, 0x42, 0x60, + 0xB1, 0xF9, 0x00, 0x10, 0x09, 0x02, 0x01, 0x60, 0x70, 0x47, 0x4A, 0x68, + 0x80, 0x32, 0x12, 0x12, 0x42, 0x80, 0x09, 0x68, 0x80, 0x31, 0x09, 0x12, + 0x01, 0x80, 0x70, 0x47, 0xC2, 0xF1, 0x10, 0x03, 0x50, 0x43, 0x01, 0xFB, + 0x03, 0x00, 0x00, 0x11, 0x70, 0x47, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x41, + 0xFE, 0x4A, 0x12, 0x68, 0x51, 0xB3, 0x51, 0x8E, 0x92, 0xF8, 0x30, 0x30, + 0x82, 0x6F, 0x04, 0x6F, 0xC0, 0x6F, 0x64, 0x26, 0x40, 0x00, 0x00, 0xFB, + 0x02, 0x40, 0x48, 0x43, 0xA0, 0xFB, 0x00, 0x25, 0x00, 0x21, 0x01, 0xFB, + 0x00, 0x55, 0x00, 0xFB, 0x01, 0x51, 0xA2, 0xFB, 0x06, 0x07, 0x00, 0x25, + 0x01, 0xFB, 0x06, 0x71, 0x02, 0xFB, 0x05, 0x11, 0x5C, 0x43, 0x22, 0x46, + 0x2B, 0x46, 0x0C, 0xF0, 0x72, 0xFE, 0x22, 0x46, 0x00, 0x23, 0x0C, 0xF0, + 0x6E, 0xFE, 0xED, 0x4B, 0x00, 0x22, 0x1B, 0x1A, 0x8A, 0x41, 0x01, 0xD2, + 0xEA, 0x48, 0x00, 0x21, 0xBD, 0xE8, 0xF0, 0x81, 0x91, 0x8E, 0x92, 0xF8, + 0x31, 0x30, 0x42, 0x6F, 0xD3, 0xE7, 0x7C, 0xB5, 0x04, 0x46, 0xE6, 0x48, + 0xB4, 0xF9, 0x02, 0x10, 0x00, 0x78, 0x01, 0x28, 0x30, 0xD0, 0xB4, 0xF9, + 0x06, 0x00, 0xB4, 0xF9, 0x0A, 0x20, 0x09, 0x1A, 0x80, 0x1A, 0x08, 0x1A, + 0x01, 0x90, 0xB4, 0xF9, 0x00, 0x10, 0xB4, 0xF9, 0x04, 0x00, 0xB4, 0xF9, + 0x08, 0x20, 0x09, 0x1A, 0x80, 0x1A, 0x08, 0x1A, 0xD8, 0x49, 0x00, 0x90, + 0x20, 0x6C, 0x09, 0x68, 0x01, 0x9B, 0x91, 0xF8, 0xB3, 0x23, 0x50, 0x43, + 0xC2, 0xF1, 0x80, 0x02, 0x53, 0x43, 0xC2, 0x17, 0x00, 0xEB, 0x52, 0x60, + 0x03, 0xEB, 0xE0, 0x10, 0x20, 0x64, 0x91, 0xF8, 0xB3, 0x13, 0xE0, 0x6B, + 0x00, 0x9A, 0x48, 0x43, 0xC1, 0xF1, 0x80, 0x01, 0x4A, 0x43, 0xC1, 0x17, + 0x00, 0xEB, 0x51, 0x60, 0x02, 0xEB, 0xE0, 0x10, 0xE0, 0x63, 0x7C, 0xBD, + 0xB4, 0xF9, 0x46, 0x00, 0xB4, 0xF9, 0x4A, 0x20, 0x09, 0x1A, 0x80, 0x1A, + 0x08, 0x1A, 0x01, 0x90, 0xB4, 0xF9, 0x00, 0x10, 0xB4, 0xF9, 0x44, 0x00, + 0xB4, 0xF9, 0x48, 0x20, 0x09, 0x1A, 0x80, 0x1A, 0x08, 0x1A, 0x00, 0x90, + 0x04, 0xF1, 0x50, 0x00, 0x03, 0x22, 0x69, 0x46, 0x05, 0x46, 0x09, 0xF0, + 0x08, 0xF8, 0x94, 0xF8, 0x80, 0x00, 0x03, 0x28, 0x02, 0xD2, 0x40, 0x1C, + 0x84, 0xF8, 0x80, 0x00, 0xC2, 0xB2, 0x29, 0x46, 0x04, 0xF1, 0x68, 0x00, + 0x00, 0xF0, 0x98, 0xFB, 0x7C, 0xBD, 0x2D, 0xE9, 0xF0, 0x4F, 0x89, 0xB0, + 0x00, 0x26, 0x05, 0x96, 0x06, 0x96, 0x07, 0x96, 0x01, 0x24, 0x0D, 0xF1, + 0x14, 0x08, 0x08, 0x96, 0x02, 0x25, 0xCD, 0xE9, 0x01, 0x48, 0x07, 0x46, + 0xCD, 0xE9, 0x03, 0x54, 0x00, 0xF1, 0x0C, 0x03, 0xAD, 0x48, 0x9B, 0x46, + 0x2A, 0x46, 0x29, 0x46, 0x20, 0x30, 0x00, 0x95, 0x08, 0xF0, 0x70, 0xFF, + 0xDF, 0xF8, 0xA4, 0x92, 0x4F, 0xF4, 0x80, 0x7A, 0x99, 0xF8, 0x00, 0x00, + 0x01, 0x28, 0x48, 0xD0, 0x38, 0x6C, 0x00, 0x90, 0x01, 0x23, 0x02, 0x22, + 0x07, 0xA9, 0x09, 0xF1, 0x08, 0x00, 0x08, 0xF0, 0x36, 0xFF, 0x07, 0xA9, + 0x01, 0x23, 0x02, 0x22, 0x08, 0x46, 0xCD, 0xF8, 0x00, 0xA0, 0x08, 0xF0, + 0x20, 0xFF, 0x02, 0x23, 0x5A, 0x46, 0x07, 0xA9, 0x05, 0xA8, 0x00, 0x94, + 0x08, 0xF0, 0x34, 0xFF, 0x05, 0x96, 0x06, 0x96, 0x07, 0x96, 0x08, 0x96, + 0xCD, 0xE9, 0x01, 0x48, 0xCD, 0xE9, 0x03, 0x54, 0x95, 0x48, 0x07, 0xF1, + 0x14, 0x03, 0x00, 0x95, 0x02, 0x22, 0x1D, 0x46, 0x11, 0x46, 0x20, 0x30, + 0x08, 0xF0, 0x3E, 0xFF, 0x99, 0xF8, 0x00, 0x00, 0x01, 0x28, 0x1F, 0xD0, + 0xF8, 0x6B, 0x00, 0x90, 0x8D, 0x48, 0x01, 0x23, 0x02, 0x22, 0x07, 0xA9, + 0x08, 0x30, 0x08, 0xF0, 0x08, 0xFF, 0x07, 0xA9, 0x01, 0x23, 0x02, 0x22, + 0x08, 0x46, 0xCD, 0xF8, 0x00, 0xA0, 0x08, 0xF0, 0xF2, 0xFE, 0x02, 0x23, + 0x2A, 0x46, 0x07, 0xA9, 0x05, 0xA8, 0x00, 0x94, 0x08, 0xF0, 0x06, 0xFF, + 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xDD, 0xE9, 0x05, 0x01, 0xC7, 0xE9, + 0x03, 0x01, 0xC9, 0xE7, 0xDD, 0xE9, 0x05, 0x01, 0xC7, 0xE9, 0x05, 0x01, + 0xF2, 0xE7, 0x2D, 0xE9, 0xF0, 0x4F, 0x8D, 0xB0, 0x00, 0x26, 0x02, 0x24, + 0x05, 0x96, 0x06, 0x96, 0x07, 0x96, 0x08, 0x96, 0x09, 0x96, 0x0A, 0x96, + 0x0B, 0x96, 0x05, 0xAF, 0x0C, 0x96, 0xCD, 0xE9, 0x01, 0x47, 0x05, 0x46, + 0x73, 0x48, 0x05, 0xF1, 0x1C, 0x03, 0x03, 0x94, 0x04, 0x94, 0x9B, 0x46, + 0x22, 0x46, 0x21, 0x46, 0x20, 0x30, 0x00, 0x94, 0x08, 0xF0, 0xF8, 0xFE, + 0x0D, 0xF1, 0x24, 0x0A, 0xCD, 0xE9, 0x01, 0x4A, 0x6B, 0x4B, 0x02, 0x22, + 0x03, 0x94, 0x04, 0x94, 0x30, 0x33, 0x11, 0x46, 0x05, 0xA8, 0x00, 0x94, + 0x08, 0xF0, 0xEA, 0xFE, 0xDF, 0xF8, 0x98, 0x81, 0x4F, 0xF0, 0x04, 0x09, + 0x98, 0xF8, 0x00, 0x00, 0x01, 0x28, 0x12, 0xD1, 0xE8, 0x6E, 0x02, 0x23, + 0x08, 0xF1, 0x60, 0x01, 0x00, 0x90, 0x1A, 0x46, 0xA1, 0xF1, 0x10, 0x00, + 0x08, 0xF0, 0xAF, 0xFE, 0x02, 0x23, 0x08, 0xF1, 0x60, 0x01, 0x1A, 0x46, + 0x08, 0x46, 0xCD, 0xF8, 0x00, 0x90, 0x08, 0xF0, 0x98, 0xFE, 0x59, 0x49, + 0x02, 0x23, 0x5A, 0x46, 0x60, 0x31, 0x09, 0xA8, 0x00, 0x94, 0x08, 0xF0, + 0xAB, 0xFE, 0x05, 0x96, 0x06, 0x96, 0x07, 0x96, 0x08, 0x96, 0x09, 0x96, + 0x0A, 0x96, 0x0B, 0x96, 0x0C, 0x96, 0xCD, 0xE9, 0x01, 0x47, 0x50, 0x48, + 0x05, 0xF1, 0x2C, 0x03, 0x02, 0x22, 0x03, 0x94, 0x04, 0x94, 0x1E, 0x46, + 0x11, 0x46, 0x20, 0x30, 0x00, 0x94, 0x08, 0xF0, 0xB1, 0xFE, 0xCD, 0xE9, + 0x01, 0x4A, 0x49, 0x4B, 0x02, 0x22, 0x03, 0x94, 0x04, 0x94, 0x30, 0x33, + 0x11, 0x46, 0x05, 0xA8, 0x00, 0x94, 0x08, 0xF0, 0xA5, 0xFE, 0x98, 0xF8, + 0x00, 0x00, 0x01, 0x28, 0x12, 0xD1, 0x42, 0x49, 0xA8, 0x6E, 0x02, 0x23, + 0x60, 0x31, 0x00, 0x90, 0x1A, 0x46, 0xA1, 0xF1, 0x10, 0x00, 0x08, 0xF0, + 0x6E, 0xFE, 0x3D, 0x49, 0x02, 0x23, 0x60, 0x31, 0x1A, 0x46, 0x08, 0x46, + 0xCD, 0xF8, 0x00, 0x90, 0x08, 0xF0, 0x57, 0xFE, 0x38, 0x49, 0x02, 0x23, + 0x32, 0x46, 0x60, 0x31, 0x09, 0xA8, 0x00, 0x94, 0x08, 0xF0, 0x6A, 0xFE, + 0x0D, 0xB0, 0x62, 0xE7, 0x2D, 0xE9, 0xF0, 0x4F, 0x89, 0xB0, 0x00, 0x26, + 0x01, 0x24, 0x05, 0x96, 0x06, 0x96, 0x0D, 0xF1, 0x14, 0x0A, 0x07, 0x96, + 0xCD, 0xE9, 0x01, 0x4A, 0x05, 0x46, 0x00, 0xF1, 0x0C, 0x03, 0x4F, 0xF0, + 0x02, 0x09, 0x2B, 0x48, 0x93, 0x46, 0x0F, 0x46, 0x03, 0x94, 0x98, 0x46, + 0x4A, 0x46, 0x21, 0x46, 0x10, 0x30, 0xCD, 0xF8, 0x00, 0x90, 0x04, 0x94, + 0x08, 0xF0, 0x66, 0xFE, 0xB5, 0xF9, 0x02, 0x00, 0x05, 0x99, 0x01, 0x23, + 0x40, 0x1A, 0x05, 0x90, 0x00, 0x90, 0x02, 0x22, 0x06, 0xA9, 0x38, 0x46, + 0x08, 0xF0, 0x31, 0xFE, 0x64, 0x27, 0x41, 0x46, 0x01, 0x23, 0x02, 0x22, + 0x08, 0x46, 0x00, 0x97, 0x08, 0xF0, 0x29, 0xFE, 0x42, 0x46, 0x02, 0x23, + 0x06, 0xA9, 0x10, 0x46, 0x00, 0x94, 0x08, 0xF0, 0x2F, 0xFE, 0x41, 0x46, + 0x01, 0x23, 0x02, 0x22, 0x08, 0x46, 0x00, 0x97, 0x08, 0xF0, 0x0D, 0xFE, + 0x05, 0x96, 0x06, 0x96, 0x07, 0x96, 0xCD, 0xE9, 0x01, 0x4A, 0x11, 0x48, + 0x05, 0xF1, 0x14, 0x03, 0x03, 0x94, 0x1E, 0x46, 0x02, 0x22, 0x01, 0x21, + 0x10, 0x30, 0xCD, 0xF8, 0x00, 0x90, 0x04, 0x94, 0x08, 0xF0, 0x32, 0xFE, + 0xB5, 0xF9, 0x00, 0x00, 0x05, 0x99, 0x01, 0x23, 0x40, 0x1A, 0x05, 0x90, + 0x00, 0x90, 0x02, 0x22, 0x06, 0xA9, 0x58, 0x46, 0x08, 0xF0, 0xFD, 0xFD, + 0x01, 0x23, 0x31, 0x46, 0x02, 0x22, 0x08, 0x46, 0x00, 0x97, 0x05, 0xE0, + 0x4C, 0x07, 0x10, 0x00, 0x40, 0x42, 0x0F, 0x00, 0x98, 0x05, 0x10, 0x00, + 0x08, 0xF0, 0xEF, 0xFD, 0x32, 0x46, 0x02, 0x23, 0x06, 0xA9, 0x10, 0x46, + 0x00, 0x94, 0x08, 0xF0, 0xF5, 0xFD, 0x31, 0x46, 0x01, 0x23, 0x02, 0x22, + 0x08, 0x46, 0x00, 0x97, 0x08, 0xF0, 0xD3, 0xFD, 0xE6, 0xE6, 0x2D, 0xE9, + 0xF7, 0x4F, 0x8A, 0xB0, 0x00, 0x26, 0x05, 0x96, 0x06, 0x96, 0x07, 0x96, + 0x08, 0x96, 0x01, 0x24, 0x4F, 0xF0, 0x02, 0x09, 0x0D, 0xF1, 0x14, 0x0A, + 0x09, 0x96, 0xCD, 0xE9, 0x01, 0x4A, 0xCD, 0xE9, 0x03, 0x94, 0x07, 0x46, + 0x07, 0xF1, 0x1C, 0x00, 0x4D, 0x46, 0xFD, 0x4B, 0x4A, 0x46, 0x49, 0x46, + 0x80, 0x46, 0xCD, 0xF8, 0x00, 0x90, 0x08, 0xF0, 0xEB, 0xFD, 0x07, 0xA8, + 0xCD, 0xE9, 0x01, 0x50, 0xF7, 0x48, 0xCD, 0xE9, 0x03, 0x45, 0x43, 0x46, + 0x02, 0x22, 0x01, 0x21, 0x08, 0x38, 0x00, 0x95, 0x08, 0xF0, 0xDE, 0xFD, + 0x0D, 0xF1, 0x24, 0x0B, 0xCD, 0xE9, 0x01, 0x4B, 0x03, 0x94, 0xF0, 0x4B, + 0x02, 0x22, 0x01, 0x21, 0x07, 0xA8, 0x00, 0x95, 0x04, 0x94, 0x08, 0xF0, + 0xD1, 0xFD, 0xEC, 0x4D, 0x18, 0x3D, 0x28, 0x78, 0x01, 0x28, 0x04, 0xD1, + 0x01, 0x21, 0x38, 0x46, 0xFF, 0xF7, 0xA8, 0xFD, 0x68, 0x60, 0x09, 0x98, + 0x69, 0x68, 0x4F, 0xF0, 0x64, 0x08, 0x08, 0x44, 0x05, 0xA9, 0x09, 0x90, + 0x01, 0x23, 0x02, 0x22, 0xCD, 0xF8, 0x00, 0x80, 0x08, 0x46, 0x08, 0xF0, + 0x90, 0xFD, 0x09, 0x98, 0x00, 0x90, 0x01, 0x23, 0x02, 0x22, 0x05, 0xA8, + 0x0B, 0x99, 0x08, 0xF0, 0x7A, 0xFD, 0x07, 0x96, 0x08, 0x96, 0x05, 0x96, + 0x06, 0x96, 0x09, 0x96, 0xCD, 0xE9, 0x01, 0x4A, 0xCD, 0xE9, 0x03, 0x94, + 0x4E, 0x46, 0x02, 0x22, 0x07, 0xF1, 0x2C, 0x00, 0xCD, 0xF8, 0x00, 0x90, + 0xD4, 0x4B, 0x11, 0x46, 0x81, 0x46, 0x08, 0xF0, 0x9D, 0xFD, 0x07, 0xA8, + 0xCD, 0xE9, 0x01, 0x60, 0xCD, 0xE9, 0x03, 0x46, 0xCF, 0x48, 0x4B, 0x46, + 0x02, 0x22, 0x01, 0x21, 0x08, 0x38, 0x00, 0x96, 0x08, 0xF0, 0x90, 0xFD, + 0xCD, 0xE9, 0x01, 0x4B, 0x03, 0x94, 0xCA, 0x4B, 0x02, 0x22, 0x01, 0x21, + 0x07, 0xA8, 0x00, 0x96, 0x04, 0x94, 0x08, 0xF0, 0x85, 0xFD, 0x28, 0x78, + 0x01, 0x28, 0x04, 0xD1, 0x00, 0x21, 0x38, 0x46, 0xFF, 0xF7, 0x5E, 0xFD, + 0x68, 0x60, 0x09, 0x98, 0x69, 0x68, 0x01, 0x23, 0x08, 0x44, 0x05, 0xA9, + 0x09, 0x90, 0x02, 0x22, 0xCD, 0xF8, 0x00, 0x80, 0x08, 0x46, 0x08, 0xF0, + 0x48, 0xFD, 0x09, 0x98, 0x00, 0x90, 0x01, 0x23, 0x02, 0x22, 0x05, 0xA8, + 0x0C, 0x99, 0x08, 0xF0, 0x32, 0xFD, 0xE1, 0xE6, 0x2D, 0xE9, 0xF7, 0x4F, + 0x8E, 0xB0, 0x00, 0x25, 0x05, 0x95, 0x06, 0x95, 0x07, 0x95, 0x02, 0x24, + 0x08, 0x95, 0x09, 0x95, 0x0A, 0x95, 0x0B, 0x95, 0x05, 0xAF, 0x0C, 0x95, + 0xCD, 0xE9, 0x01, 0x47, 0x8C, 0x46, 0x4F, 0xF0, 0x01, 0x0A, 0xAE, 0x4B, + 0x06, 0x46, 0x03, 0x94, 0x08, 0x3B, 0x52, 0x46, 0x21, 0x46, 0x60, 0x46, + 0xCD, 0xF8, 0x00, 0xA0, 0x04, 0x94, 0x08, 0xF0, 0x49, 0xFD, 0xA8, 0x48, + 0x05, 0xAA, 0x02, 0x23, 0x11, 0x46, 0x28, 0x30, 0x00, 0x94, 0x08, 0xF0, + 0x33, 0xFD, 0x0D, 0xF1, 0x24, 0x08, 0xCD, 0xE9, 0x01, 0x48, 0x06, 0xF1, + 0x1C, 0x03, 0x02, 0x22, 0x03, 0x94, 0x04, 0x94, 0x9B, 0x46, 0x11, 0x46, + 0x05, 0xA8, 0x00, 0x94, 0x08, 0xF0, 0x32, 0xFD, 0x4F, 0xF0, 0x64, 0x09, + 0x02, 0x23, 0x1A, 0x46, 0x59, 0x46, 0x09, 0xA8, 0xCD, 0xF8, 0x00, 0x90, + 0x08, 0xF0, 0xF1, 0xFC, 0x05, 0x95, 0x06, 0x95, 0x07, 0x95, 0x08, 0x95, + 0x09, 0x95, 0x0A, 0x95, 0x0B, 0x95, 0x0C, 0x95, 0xCD, 0xE9, 0x01, 0x47, + 0x92, 0x4B, 0x03, 0x94, 0x08, 0x3B, 0x01, 0x22, 0x02, 0x21, 0xCD, 0xF8, + 0x00, 0xA0, 0x04, 0x94, 0x10, 0x98, 0x08, 0xF0, 0x13, 0xFD, 0x8D, 0x48, + 0x05, 0xAA, 0x02, 0x23, 0x11, 0x46, 0x28, 0x30, 0x00, 0x94, 0x08, 0xF0, + 0xFD, 0xFC, 0xCD, 0xE9, 0x01, 0x48, 0x03, 0x94, 0x04, 0x94, 0x06, 0xF1, + 0x2C, 0x03, 0x00, 0x94, 0x02, 0x22, 0x1C, 0x46, 0x11, 0x46, 0x05, 0xA8, + 0x08, 0xF0, 0xFE, 0xFC, 0x02, 0x23, 0x1A, 0x46, 0x21, 0x46, 0x09, 0xA8, + 0xCD, 0xF8, 0x00, 0x90, 0x08, 0xF0, 0xBF, 0xFC, 0x11, 0xB0, 0xD2, 0xE5, + 0x38, 0xB5, 0x7E, 0x48, 0x7C, 0x4C, 0x01, 0x68, 0x18, 0x3C, 0x91, 0xF8, + 0x80, 0x03, 0xC0, 0xF3, 0x00, 0x12, 0x22, 0x70, 0xB1, 0xF8, 0xB1, 0x03, + 0x1A, 0xB1, 0x64, 0x21, 0x48, 0x43, 0x0D, 0x46, 0x01, 0xE0, 0xD1, 0xF8, + 0xAD, 0x53, 0x74, 0x49, 0x80, 0x08, 0x02, 0x23, 0x48, 0x31, 0x00, 0x90, + 0x1A, 0x46, 0xA1, 0xF1, 0x10, 0x00, 0x08, 0xF0, 0xAE, 0xFC, 0x65, 0x60, + 0x38, 0xBD, 0xF8, 0xB5, 0x04, 0x46, 0x08, 0x68, 0x20, 0x60, 0x48, 0x68, + 0x60, 0x60, 0x88, 0x68, 0xA0, 0x60, 0x00, 0x25, 0x25, 0x64, 0xE5, 0x63, + 0xB1, 0xF9, 0x02, 0x00, 0xC4, 0xE9, 0x03, 0x05, 0xB1, 0xF9, 0x00, 0x00, + 0xC4, 0xE9, 0x05, 0x05, 0x64, 0x48, 0x18, 0x38, 0x01, 0x78, 0x01, 0x29, + 0x09, 0xD0, 0x60, 0x30, 0x1C, 0x34, 0x0F, 0xC8, 0x0F, 0xC4, 0x84, 0xE8, + 0x0F, 0x00, 0x2C, 0x3C, 0x84, 0xF8, 0x81, 0x50, 0xF8, 0xBD, 0x50, 0x30, + 0x1C, 0x34, 0x0F, 0xC8, 0x0F, 0xC4, 0x5C, 0x4E, 0x0F, 0xC4, 0x30, 0x68, + 0x64, 0x21, 0x02, 0x23, 0xB0, 0xF8, 0xB1, 0x03, 0x1A, 0x46, 0x48, 0x43, + 0x80, 0x08, 0xA4, 0xF1, 0x20, 0x01, 0x00, 0x90, 0x08, 0x46, 0x3C, 0x3C, + 0x08, 0xF0, 0x75, 0xFC, 0x30, 0x68, 0x64, 0x21, 0x02, 0x23, 0xB0, 0xF8, + 0xB1, 0x03, 0x1A, 0x46, 0x48, 0x43, 0x80, 0x08, 0x04, 0xF1, 0x2C, 0x01, + 0x00, 0x90, 0x08, 0x46, 0x08, 0xF0, 0x67, 0xFC, 0x94, 0xE8, 0x07, 0x00, + 0x04, 0xF1, 0x44, 0x03, 0x83, 0xE8, 0x07, 0x00, 0x84, 0xF8, 0x80, 0x50, + 0xD0, 0xE7, 0x10, 0xB5, 0x04, 0x46, 0x03, 0x22, 0x08, 0xF0, 0xDC, 0xFC, + 0x20, 0x46, 0xFF, 0xF7, 0x94, 0xFC, 0xB4, 0xF9, 0x02, 0x00, 0xE0, 0x60, + 0xB4, 0xF9, 0x06, 0x10, 0x40, 0x1A, 0x20, 0x61, 0xB4, 0xF9, 0x00, 0x00, + 0x60, 0x61, 0xB4, 0xF9, 0x04, 0x10, 0x40, 0x1A, 0xA0, 0x61, 0x10, 0xBD, + 0x7F, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x03, 0x22, 0x08, 0xF0, 0xC4, 0xFC, + 0x20, 0x46, 0xFF, 0xF7, 0x7C, 0xFC, 0x20, 0x46, 0xFF, 0xF7, 0xD9, 0xFC, + 0x20, 0x46, 0xFF, 0xF7, 0x4C, 0xFD, 0x00, 0x20, 0x00, 0x90, 0x01, 0x90, + 0x02, 0x90, 0x03, 0x90, 0x02, 0xAA, 0x69, 0x46, 0x20, 0x46, 0xFF, 0xF7, + 0x4E, 0xFE, 0x02, 0xAA, 0x69, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0xCE, 0xFD, + 0x02, 0xAA, 0x69, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0xE5, 0xFE, 0xA0, 0x89, + 0x68, 0x80, 0xA0, 0x8A, 0x28, 0x80, 0x28, 0x48, 0x18, 0x38, 0x00, 0x78, + 0x01, 0x28, 0x05, 0xD1, 0x03, 0x22, 0x29, 0x46, 0x04, 0xF1, 0x44, 0x00, + 0x08, 0xF0, 0x98, 0xFC, 0x7F, 0xBD, 0x2D, 0xE9, 0xF0, 0x47, 0x06, 0x46, + 0x48, 0x88, 0xB6, 0xF8, 0x4A, 0x30, 0x89, 0x46, 0xC0, 0x1A, 0xB6, 0xF8, + 0x46, 0x40, 0x92, 0x46, 0x01, 0xB2, 0xB9, 0xF8, 0x00, 0x00, 0xB6, 0xF8, + 0x48, 0x20, 0xE3, 0x1A, 0x1C, 0xB2, 0x80, 0x1A, 0xB6, 0xF8, 0x44, 0x30, + 0x00, 0xB2, 0x9A, 0x1A, 0x15, 0xB2, 0x0C, 0xB9, 0x00, 0x2D, 0x27, 0xD0, + 0x49, 0x43, 0x00, 0xFB, 0x00, 0x10, 0x64, 0x21, 0x48, 0x43, 0x04, 0xFB, + 0x04, 0xF1, 0x05, 0xFB, 0x05, 0x11, 0xB0, 0xFB, 0xF1, 0xF0, 0x08, 0xF0, + 0xC7, 0xFB, 0x44, 0x43, 0x0A, 0x22, 0x45, 0x43, 0x21, 0xB2, 0x28, 0xB2, + 0x91, 0xFB, 0xF2, 0xF1, 0x90, 0xFB, 0xF2, 0xF0, 0xB6, 0xF8, 0x46, 0x20, + 0x61, 0xF3, 0x1F, 0x48, 0x11, 0x44, 0x61, 0xF3, 0x1F, 0x47, 0xB6, 0xF8, + 0x44, 0x10, 0x60, 0xF3, 0x0F, 0x08, 0x08, 0x44, 0x60, 0xF3, 0x0F, 0x07, + 0xC9, 0xF8, 0x00, 0x70, 0xCA, 0xF8, 0x00, 0x80, 0xBD, 0xE8, 0xF0, 0x87, + 0xB0, 0x05, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0xF0, 0xB5, 0x4F, 0xF0, + 0x00, 0x0C, 0x63, 0x46, 0x65, 0x46, 0x14, 0x46, 0x07, 0xE0, 0x00, 0xBF, + 0x01, 0xEB, 0xC4, 0x06, 0x76, 0x68, 0x35, 0x44, 0x51, 0xF8, 0x34, 0x60, + 0x33, 0x44, 0x64, 0x1E, 0xF6, 0xD2, 0x95, 0xFB, 0xF2, 0xF6, 0x93, 0xFB, + 0xF2, 0xF7, 0xC0, 0xF8, 0x04, 0xC0, 0x15, 0x46, 0x42, 0xF2, 0x10, 0x74, + 0xC0, 0xF8, 0x00, 0xC0, 0x17, 0xE0, 0x00, 0xBF, 0x01, 0xEB, 0xC5, 0x03, + 0x5B, 0x68, 0x9B, 0x1B, 0x5B, 0x43, 0xA3, 0x42, 0x00, 0xDD, 0x23, 0x46, + 0xD0, 0xF8, 0x04, 0xC0, 0x63, 0x44, 0x43, 0x60, 0x51, 0xF8, 0x35, 0x30, + 0xDB, 0x1B, 0x5B, 0x43, 0xA3, 0x42, 0x00, 0xDD, 0x23, 0x46, 0xD0, 0xF8, + 0x00, 0xC0, 0x63, 0x44, 0x03, 0x60, 0x6D, 0x1E, 0xE6, 0xD2, 0x41, 0x68, + 0x64, 0x23, 0x59, 0x43, 0x91, 0xFB, 0xF2, 0xF1, 0x41, 0x60, 0x01, 0x68, + 0x59, 0x43, 0x91, 0xFB, 0xF2, 0xF1, 0x01, 0x60, 0xF0, 0xBD, 0x00, 0x00, + 0x10, 0xB5, 0x14, 0x21, 0x4B, 0x48, 0x0C, 0xF0, 0x6F, 0xFB, 0xF6, 0xF7, + 0xD3, 0xFE, 0x64, 0x21, 0x48, 0x43, 0x48, 0x49, 0x08, 0x60, 0x10, 0xBD, + 0x2D, 0xE9, 0xF0, 0x41, 0xDF, 0xF8, 0x18, 0x81, 0x04, 0x46, 0x0D, 0x46, + 0xD8, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0xA0, 0x13, 0x90, 0xF8, 0x80, 0x03, + 0x01, 0xF0, 0x0F, 0x06, 0xC6, 0xF1, 0x10, 0x07, 0x80, 0x07, 0x0F, 0xD5, + 0xB4, 0xF8, 0x42, 0x00, 0x01, 0x07, 0x0B, 0xD4, 0x00, 0x06, 0x09, 0xD4, + 0x0C, 0xF0, 0xFC, 0xFB, 0x30, 0xB9, 0x3B, 0x48, 0x00, 0x78, 0x18, 0xB9, + 0x3A, 0x48, 0x00, 0x78, 0x01, 0x28, 0x02, 0xD9, 0x00, 0x20, 0x20, 0x63, + 0x18, 0xE0, 0x20, 0x6B, 0x02, 0x28, 0x18, 0xD8, 0x40, 0x1C, 0x20, 0x63, + 0x02, 0x28, 0x07, 0xD9, 0x94, 0xF8, 0x3E, 0x11, 0x04, 0x29, 0x10, 0xD0, + 0x06, 0x29, 0x0E, 0xD0, 0x07, 0x29, 0x0C, 0xD0, 0x02, 0x28, 0x07, 0xD1, + 0xE0, 0x89, 0x61, 0x8A, 0x40, 0x1A, 0x60, 0x85, 0xA0, 0x89, 0x21, 0x8A, + 0x40, 0x1A, 0x20, 0x85, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0xE0, 0x89, + 0x61, 0x8A, 0x22, 0x8A, 0x40, 0x1A, 0x01, 0xB2, 0xA0, 0x89, 0x79, 0x43, + 0x80, 0x1A, 0xB4, 0xF9, 0x2A, 0x20, 0x00, 0xB2, 0x02, 0xFB, 0x06, 0x11, + 0x09, 0x11, 0x61, 0x85, 0xB4, 0xF9, 0x28, 0x10, 0x78, 0x43, 0x01, 0xFB, + 0x06, 0x00, 0x00, 0x11, 0x20, 0x85, 0xF6, 0xF7, 0x2B, 0xFE, 0x1A, 0x4A, + 0x91, 0x89, 0x08, 0x1A, 0x11, 0x7C, 0x01, 0x29, 0x01, 0xD1, 0x51, 0x68, + 0x08, 0x44, 0x00, 0x28, 0x00, 0xDA, 0x00, 0x20, 0x00, 0xEB, 0x80, 0x01, + 0x13, 0x68, 0x49, 0x00, 0xB1, 0xFB, 0xF3, 0xF7, 0xD8, 0xF8, 0x00, 0x60, + 0xB6, 0xF8, 0xA1, 0x13, 0x8F, 0x42, 0x03, 0xD9, 0x59, 0x43, 0x0A, 0x20, + 0xB1, 0xFB, 0xF0, 0xF0, 0xB4, 0xF9, 0x2A, 0x10, 0x96, 0xF8, 0xA3, 0x33, + 0x92, 0x68, 0x59, 0x43, 0x64, 0x26, 0x41, 0x43, 0x72, 0x43, 0xB4, 0xF9, + 0x28, 0x40, 0x91, 0xFB, 0xF2, 0xF1, 0x5C, 0x43, 0x44, 0x43, 0x94, 0xFB, + 0xF2, 0xF0, 0x6A, 0x88, 0x11, 0x44, 0x69, 0x80, 0x29, 0x88, 0x08, 0x44, + 0x28, 0x80, 0x01, 0x20, 0xB1, 0xE7, 0x00, 0x00, 0x6C, 0x2C, 0x10, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x74, 0x05, 0x10, 0x00, 0x20, 0x07, 0x10, 0x00, + 0xB0, 0xF8, 0x44, 0x20, 0xB1, 0xF8, 0x44, 0x30, 0x1A, 0x44, 0xA0, 0xF8, + 0x44, 0x20, 0xB0, 0xF8, 0x46, 0x20, 0xB1, 0xF8, 0x46, 0x30, 0x1A, 0x44, + 0xA0, 0xF8, 0x46, 0x20, 0x42, 0x6B, 0x4B, 0x6B, 0x1A, 0x44, 0x42, 0x63, + 0x82, 0x6B, 0x8B, 0x6B, 0x1A, 0x44, 0x82, 0x63, 0xB1, 0xF9, 0x54, 0x20, + 0xB0, 0xF9, 0x54, 0x30, 0x9A, 0x42, 0x01, 0xDD, 0xA0, 0xF8, 0x54, 0x20, + 0xB1, 0xF9, 0x56, 0x20, 0xB0, 0xF9, 0x56, 0x30, 0x9A, 0x42, 0x01, 0xDD, + 0xA0, 0xF8, 0x56, 0x20, 0x90, 0xF8, 0x46, 0x21, 0x91, 0xF8, 0x46, 0x31, + 0x9A, 0x42, 0x0A, 0xD0, 0x30, 0xF8, 0x48, 0x2F, 0xB1, 0xF8, 0x48, 0x30, + 0x1A, 0x44, 0x20, 0xF8, 0x0C, 0x29, 0xC9, 0x6B, 0x02, 0x68, 0x11, 0x44, + 0x01, 0x60, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x4F, 0x97, 0xB0, 0x80, 0x46, + 0x00, 0xF5, 0x80, 0x50, 0x00, 0x26, 0x11, 0x90, 0xBF, 0xE0, 0x00, 0x20, + 0x08, 0x90, 0x05, 0x90, 0x10, 0x90, 0x12, 0x90, 0x81, 0x46, 0x82, 0x46, + 0x83, 0x46, 0x05, 0x46, 0x07, 0x46, 0x0A, 0x90, 0x0B, 0x90, 0x0C, 0x90, + 0x0D, 0x90, 0x08, 0xEB, 0x86, 0x00, 0x00, 0xF5, 0x80, 0x50, 0x14, 0x90, + 0xD0, 0xF8, 0x68, 0x04, 0x0A, 0xAA, 0x04, 0x46, 0x17, 0xE0, 0x00, 0xBF, + 0x90, 0xF8, 0x46, 0x11, 0x08, 0xEB, 0x01, 0x0C, 0x53, 0x5C, 0x0C, 0xF5, + 0x80, 0x5C, 0x5B, 0x1C, 0xDB, 0xB2, 0x53, 0x54, 0x9C, 0xF8, 0x56, 0xC4, + 0x63, 0x45, 0x06, 0xD1, 0x01, 0x2B, 0x04, 0xD9, 0x01, 0x23, 0x8B, 0x40, + 0x12, 0x99, 0x0B, 0x43, 0x12, 0x93, 0xD0, 0xF8, 0x50, 0x01, 0x00, 0x28, + 0xE6, 0xD1, 0x40, 0xE0, 0x94, 0xF8, 0x46, 0x11, 0x01, 0x20, 0x00, 0xFA, + 0x01, 0xFC, 0x12, 0x99, 0x1C, 0xEA, 0x01, 0x0F, 0x12, 0xD1, 0xA0, 0x6B, + 0xB4, 0xF9, 0x0E, 0x30, 0x05, 0x9A, 0x49, 0x46, 0xC0, 0xFB, 0x03, 0x12, + 0x05, 0x92, 0x89, 0x46, 0xB4, 0xF9, 0x0C, 0x30, 0x51, 0x46, 0x5A, 0x46, + 0xC0, 0xFB, 0x03, 0x12, 0x8A, 0x46, 0x93, 0x46, 0x05, 0x44, 0x19, 0xE0, + 0x08, 0x99, 0x1C, 0xEA, 0x01, 0x0F, 0x15, 0xD1, 0xE0, 0x6B, 0xB4, 0xF9, + 0x1E, 0x30, 0x05, 0x9A, 0x49, 0x46, 0xC0, 0xFB, 0x03, 0x12, 0x05, 0x92, + 0x89, 0x46, 0xB4, 0xF9, 0x1C, 0x30, 0x51, 0x46, 0x5A, 0x46, 0xC0, 0xFB, + 0x03, 0x12, 0x8A, 0x46, 0x08, 0x99, 0x05, 0x44, 0x4C, 0xEA, 0x01, 0x00, + 0x93, 0x46, 0x08, 0x90, 0x20, 0x46, 0x00, 0xF0, 0x98, 0xFB, 0x01, 0x28, + 0x02, 0xD1, 0x10, 0x98, 0x40, 0x1C, 0x10, 0x90, 0xD4, 0xF8, 0x50, 0x41, + 0x7F, 0x1C, 0x00, 0x2C, 0xBC, 0xD1, 0x00, 0x2F, 0x45, 0xDD, 0xE8, 0x17, + 0x04, 0x46, 0x03, 0x46, 0x2A, 0x46, 0x48, 0x46, 0x05, 0x99, 0x0C, 0xF0, + 0x4C, 0xF9, 0xAD, 0xF8, 0x1E, 0x00, 0x2A, 0x46, 0x23, 0x46, 0x50, 0x46, + 0x59, 0x46, 0x0C, 0xF0, 0x44, 0xF9, 0xAD, 0xF8, 0x1C, 0x00, 0x14, 0x98, + 0x4F, 0xF0, 0xFF, 0x37, 0x00, 0x25, 0xD0, 0xF8, 0x68, 0x44, 0x23, 0xE0, + 0x20, 0x46, 0x00, 0xF0, 0x70, 0xFB, 0x01, 0x28, 0x01, 0xD0, 0x10, 0x98, + 0x90, 0xB9, 0x04, 0xF1, 0x10, 0x01, 0x07, 0xA8, 0x08, 0xF0, 0xB9, 0xFA, + 0xB8, 0x42, 0x0B, 0xD2, 0x07, 0x46, 0x3D, 0xB1, 0x29, 0x46, 0x20, 0x46, + 0xFF, 0xF7, 0x1A, 0xFF, 0x29, 0x46, 0x40, 0x46, 0x00, 0xF0, 0x72, 0xFB, + 0x25, 0x46, 0x07, 0xE0, 0x21, 0x46, 0x28, 0x46, 0xFF, 0xF7, 0x10, 0xFF, + 0x21, 0x46, 0x40, 0x46, 0x00, 0xF0, 0x68, 0xFB, 0xD4, 0xF8, 0x50, 0x41, + 0x00, 0x2C, 0xD9, 0xD1, 0x07, 0x98, 0x45, 0xF8, 0x0C, 0x0F, 0xE8, 0x8E, + 0x40, 0xF0, 0x40, 0x00, 0xE8, 0x86, 0x11, 0x98, 0x76, 0x1C, 0x90, 0xF8, + 0xE0, 0x04, 0xB0, 0x42, 0x3F, 0xF7, 0x3B, 0xAF, 0x17, 0xB0, 0xBD, 0xE8, + 0xF0, 0x8F, 0x2D, 0xE9, 0xF7, 0x4F, 0x05, 0x46, 0x0E, 0x46, 0x01, 0xEB, + 0x06, 0x10, 0x00, 0xEB, 0x80, 0x00, 0x82, 0xB0, 0x05, 0xEB, 0x80, 0x0A, + 0x00, 0x24, 0x4F, 0xF0, 0x01, 0x08, 0xDF, 0xF8, 0x98, 0xB5, 0x05, 0xF5, + 0x80, 0x57, 0x7F, 0xE0, 0xD7, 0xF8, 0xEC, 0x23, 0x08, 0xFA, 0x04, 0xF9, + 0x12, 0xEA, 0x09, 0x0F, 0x77, 0xD0, 0xB4, 0x42, 0x75, 0xD0, 0xDB, 0xF8, + 0x08, 0x10, 0x31, 0xF8, 0x16, 0x10, 0x11, 0xEA, 0x09, 0x0F, 0x6E, 0xD1, + 0x04, 0xEB, 0x04, 0x10, 0x00, 0xEB, 0x80, 0x00, 0x05, 0xEB, 0x80, 0x00, + 0x00, 0x90, 0x00, 0xF0, 0x0A, 0xFB, 0x01, 0x28, 0x04, 0xD0, 0x00, 0x98, + 0x00, 0xF0, 0x0B, 0xFB, 0x01, 0x28, 0x5E, 0xD1, 0x00, 0x98, 0x00, 0xF0, + 0xF8, 0xFA, 0xE8, 0xBB, 0x00, 0x99, 0x0A, 0xF1, 0x0C, 0x00, 0x0C, 0x31, + 0x08, 0xF0, 0x51, 0xFA, 0x01, 0x90, 0xDB, 0xF8, 0x08, 0x00, 0x08, 0xFA, + 0x06, 0xF2, 0x30, 0xF8, 0x16, 0x30, 0x43, 0xEA, 0x09, 0x03, 0x20, 0xF8, + 0x16, 0x30, 0x30, 0xF8, 0x14, 0x30, 0x13, 0x43, 0x20, 0xF8, 0x14, 0x30, + 0x50, 0x46, 0xDB, 0xF8, 0x00, 0x90, 0x00, 0xF0, 0xF6, 0xFA, 0x01, 0x28, + 0x04, 0xD1, 0x00, 0x98, 0x00, 0xF0, 0xDF, 0xFA, 0x01, 0x28, 0x1D, 0xD0, + 0x50, 0x46, 0x00, 0xF0, 0xDA, 0xFA, 0x01, 0x28, 0x04, 0xD1, 0x00, 0x98, + 0x00, 0xF0, 0xE7, 0xFA, 0x01, 0x28, 0x13, 0xD0, 0x50, 0x46, 0x00, 0xF0, + 0xD0, 0xFA, 0x01, 0x28, 0x1E, 0xD1, 0x00, 0x98, 0x00, 0xF0, 0xCB, 0xFA, + 0x01, 0x28, 0x19, 0xD1, 0x00, 0x99, 0x9A, 0xF8, 0x42, 0x00, 0x91, 0xF8, + 0x42, 0x10, 0x08, 0x43, 0x80, 0x06, 0x00, 0xE0, 0x1B, 0xE0, 0x0F, 0xD5, + 0xBA, 0xF8, 0x42, 0x00, 0xDB, 0xF8, 0x04, 0x90, 0x40, 0xF0, 0x20, 0x01, + 0xAA, 0xF8, 0x42, 0x10, 0x00, 0x98, 0xB0, 0xF8, 0x42, 0x00, 0x40, 0xF0, + 0x20, 0x01, 0x00, 0x98, 0xA0, 0xF8, 0x42, 0x10, 0x01, 0x98, 0x48, 0x45, + 0x07, 0xD2, 0x41, 0xF2, 0x68, 0x40, 0x51, 0x46, 0x28, 0x44, 0x04, 0x9B, + 0x00, 0x9A, 0x00, 0xF0, 0xD0, 0xFA, 0x64, 0x1C, 0x97, 0xF9, 0xF4, 0x03, + 0xA0, 0x42, 0xBF, 0xF6, 0x7B, 0xAF, 0x05, 0xB0, 0x63, 0xE7, 0x2D, 0xE9, + 0xF8, 0x4F, 0x88, 0x46, 0x06, 0x46, 0x01, 0xEB, 0x08, 0x10, 0x00, 0xEB, + 0x80, 0x00, 0x06, 0xEB, 0x80, 0x04, 0xDF, 0xF8, 0x6C, 0xA4, 0x94, 0xF8, + 0x42, 0x00, 0x4F, 0xF0, 0x04, 0x0B, 0x40, 0x06, 0x4F, 0xF0, 0x01, 0x09, + 0x06, 0xF5, 0x80, 0x55, 0x2E, 0xD5, 0x00, 0x27, 0x04, 0xF1, 0x0C, 0x0B, + 0x24, 0xE0, 0x00, 0xBF, 0xD5, 0xF8, 0xEC, 0x13, 0x09, 0xFA, 0x07, 0xF0, + 0x01, 0x42, 0x1C, 0xD0, 0x47, 0x45, 0x1A, 0xD0, 0x07, 0xEB, 0x07, 0x10, + 0x00, 0xEB, 0x80, 0x00, 0x06, 0xEB, 0x80, 0x00, 0x00, 0x90, 0x00, 0xF0, + 0x70, 0xFA, 0x01, 0x28, 0x0F, 0xD1, 0x00, 0x98, 0x00, 0xF0, 0x63, 0xFA, + 0x58, 0xB9, 0x00, 0x99, 0x58, 0x46, 0x10, 0x31, 0x08, 0xF0, 0xBD, 0xF9, + 0xDA, 0xF8, 0x04, 0x10, 0x88, 0x42, 0x02, 0xD2, 0x04, 0x20, 0x84, 0xF8, + 0x3E, 0x01, 0x7F, 0x1C, 0x95, 0xF9, 0xF4, 0x03, 0xB8, 0x42, 0xD7, 0xDA, + 0xBD, 0xE8, 0xF8, 0x8F, 0xFE, 0x48, 0xE1, 0x6A, 0x00, 0x68, 0x90, 0xF8, + 0x95, 0x03, 0x81, 0x42, 0xF6, 0xD9, 0x00, 0x27, 0x31, 0xE0, 0x00, 0xBF, + 0xD5, 0xF8, 0xEC, 0x13, 0x09, 0xFA, 0x07, 0xF0, 0x01, 0x42, 0x29, 0xD0, + 0x47, 0x45, 0x27, 0xD0, 0x07, 0xEB, 0x07, 0x10, 0x00, 0xEB, 0x80, 0x00, + 0x06, 0xEB, 0x80, 0x00, 0x00, 0x90, 0x00, 0xF0, 0x3C, 0xFA, 0x01, 0x28, + 0x1C, 0xD1, 0x00, 0x98, 0x94, 0xF8, 0x46, 0x11, 0x90, 0xF8, 0x47, 0x01, + 0x81, 0x42, 0x15, 0xD1, 0x00, 0x98, 0x00, 0xF0, 0x28, 0xFA, 0x88, 0xB9, + 0x00, 0x99, 0x04, 0xF1, 0x0C, 0x00, 0x10, 0x31, 0x08, 0xF0, 0x81, 0xF9, + 0xDA, 0xF8, 0x04, 0x10, 0x88, 0x42, 0x07, 0xD2, 0x84, 0xF8, 0x3E, 0xB1, + 0xB4, 0xF8, 0x42, 0x00, 0x40, 0xF0, 0x40, 0x00, 0xA4, 0xF8, 0x42, 0x00, + 0x7F, 0x1C, 0x95, 0xF9, 0xF4, 0x03, 0xB8, 0x42, 0xCA, 0xDA, 0x00, 0x27, + 0x0C, 0x34, 0x26, 0xE0, 0xD5, 0xF8, 0xEC, 0x13, 0x09, 0xFA, 0x07, 0xF0, + 0x01, 0x42, 0x1F, 0xD0, 0x47, 0x45, 0x1D, 0xD0, 0x07, 0xEB, 0x07, 0x10, + 0x00, 0xEB, 0x80, 0x00, 0x06, 0xEB, 0x80, 0x00, 0x83, 0x46, 0x00, 0xF0, + 0x0A, 0xFA, 0x01, 0x28, 0x12, 0xD1, 0x58, 0x46, 0x00, 0xF0, 0xF7, 0xF9, + 0x70, 0xB9, 0x0B, 0xF1, 0x10, 0x01, 0x20, 0x46, 0x08, 0xF0, 0x51, 0xF9, + 0xDA, 0xF8, 0x04, 0x10, 0x88, 0x42, 0x05, 0xD2, 0xBB, 0xF8, 0x42, 0x00, + 0x40, 0xF0, 0x40, 0x01, 0xAB, 0xF8, 0x42, 0x10, 0x7F, 0x1C, 0x95, 0xF9, + 0xF4, 0x03, 0xB8, 0x42, 0xD4, 0xDA, 0x8F, 0xE7, 0x2D, 0xE9, 0xF8, 0x43, + 0x06, 0x46, 0xFF, 0x20, 0x00, 0x25, 0x8D, 0xF8, 0x00, 0x00, 0x01, 0x27, + 0x06, 0xF5, 0x80, 0x54, 0x1A, 0xE0, 0x00, 0xBF, 0x05, 0xEB, 0x05, 0x10, + 0x00, 0xEB, 0x80, 0x00, 0x06, 0xEB, 0x80, 0x08, 0xD4, 0xF8, 0xEC, 0x03, + 0x07, 0xFA, 0x05, 0xF1, 0x08, 0x42, 0x0C, 0xD0, 0x40, 0x46, 0x00, 0xF0, + 0xC6, 0xF9, 0x01, 0x28, 0x07, 0xD0, 0x98, 0xF8, 0x3E, 0x01, 0x05, 0x28, + 0x03, 0xD1, 0x29, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0x28, 0xFF, 0x6D, 0x1C, + 0x94, 0xF9, 0xF4, 0x03, 0xA8, 0x42, 0xE1, 0xDA, 0x00, 0x25, 0x1B, 0xE0, + 0x05, 0xEB, 0x05, 0x10, 0x00, 0xEB, 0x80, 0x00, 0x06, 0xEB, 0x80, 0x08, + 0xD4, 0xF8, 0xEC, 0x03, 0x07, 0xFA, 0x05, 0xF1, 0x08, 0x42, 0x0E, 0xD0, + 0x40, 0x46, 0x00, 0xF0, 0xA6, 0xF9, 0x01, 0x28, 0x09, 0xD0, 0x40, 0x46, + 0x00, 0xF0, 0xAF, 0xF9, 0x01, 0x28, 0x04, 0xD1, 0x6A, 0x46, 0x29, 0x46, + 0x30, 0x46, 0xFF, 0xF7, 0x6C, 0xFE, 0x6D, 0x1C, 0x94, 0xF9, 0xF4, 0x03, + 0xA8, 0x42, 0xDF, 0xDA, 0x00, 0x25, 0xB8, 0x46, 0x21, 0xE0, 0x00, 0xBF, + 0x05, 0xEB, 0x05, 0x10, 0x00, 0xEB, 0x80, 0x00, 0x06, 0xEB, 0x80, 0x07, + 0xD4, 0xF8, 0xEC, 0x13, 0x08, 0xFA, 0x05, 0xF0, 0x01, 0x42, 0x13, 0xD0, + 0x38, 0x46, 0x00, 0xF0, 0x82, 0xF9, 0x01, 0x28, 0x0E, 0xD0, 0x38, 0x46, + 0x00, 0xF0, 0x85, 0xF9, 0x01, 0x28, 0x04, 0xD1, 0x6A, 0x46, 0x29, 0x46, + 0x30, 0x46, 0xFF, 0xF7, 0x48, 0xFE, 0x37, 0xF8, 0x42, 0x0F, 0x20, 0xF0, + 0x20, 0x00, 0x38, 0x80, 0x6D, 0x1C, 0x94, 0xF9, 0xF4, 0x03, 0xA8, 0x42, + 0xDA, 0xDA, 0x9D, 0xF8, 0x00, 0x00, 0x40, 0x1C, 0x84, 0xF8, 0xE0, 0x04, + 0xBD, 0xE8, 0xF8, 0x83, 0x10, 0xB5, 0x04, 0x46, 0x87, 0x48, 0x03, 0x21, + 0x08, 0x30, 0x05, 0xF0, 0xD2, 0xFB, 0x85, 0x48, 0x1E, 0x21, 0x80, 0x68, + 0x0B, 0xF0, 0xD2, 0xFF, 0x41, 0xF2, 0x68, 0x40, 0x7C, 0x21, 0x20, 0x44, + 0x0B, 0xF0, 0xEE, 0xFF, 0x80, 0x48, 0x02, 0x68, 0x80, 0x48, 0xB2, 0xF8, + 0x96, 0x13, 0x00, 0x78, 0x49, 0x43, 0x10, 0xB1, 0xB2, 0xF8, 0x6C, 0x13, + 0x49, 0x43, 0xB2, 0xF8, 0x98, 0x23, 0x02, 0xFB, 0x02, 0x10, 0x78, 0x4A, + 0x11, 0x60, 0x11, 0x1D, 0x08, 0x60, 0x20, 0x46, 0xFF, 0xF7, 0x5C, 0xFF, + 0x20, 0x46, 0xFF, 0xF7, 0x3B, 0xFD, 0x73, 0x48, 0x03, 0x21, 0xBD, 0xE8, + 0x10, 0x40, 0x08, 0x30, 0x05, 0xF0, 0xC4, 0xBB, 0xF0, 0xB4, 0x84, 0x6B, + 0xC2, 0x68, 0x8B, 0x6B, 0xCE, 0x68, 0x17, 0x14, 0x67, 0x43, 0x4F, 0xEA, + 0x26, 0x4C, 0x03, 0xFB, 0x0C, 0x77, 0xE5, 0x18, 0x97, 0xFB, 0xF5, 0xF7, + 0x67, 0xF3, 0x1F, 0x42, 0x17, 0xB2, 0x67, 0x43, 0x34, 0xB2, 0x03, 0xFB, + 0x04, 0x73, 0x93, 0xFB, 0xF5, 0xF3, 0x63, 0xF3, 0x0F, 0x02, 0xC2, 0x60, + 0xF0, 0xBC, 0xDF, 0xE4, 0x62, 0x4A, 0x12, 0x68, 0x92, 0xF8, 0x40, 0x24, + 0x92, 0x06, 0x11, 0xD5, 0x90, 0xF8, 0x49, 0x31, 0x23, 0xB1, 0x91, 0xF8, + 0x49, 0x21, 0x0A, 0xB1, 0x93, 0x42, 0x07, 0xD1, 0x90, 0xF8, 0x4A, 0x01, + 0x30, 0xB1, 0x91, 0xF8, 0x4A, 0x11, 0x19, 0xB1, 0x88, 0x42, 0x01, 0xD0, + 0x00, 0x20, 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x2D, 0xE9, 0xFE, 0x4F, + 0x00, 0xF5, 0x80, 0x54, 0x05, 0x46, 0xD4, 0xF8, 0xF8, 0x13, 0xD4, 0xF8, + 0xEC, 0x03, 0x01, 0x40, 0x00, 0x28, 0xC4, 0xF8, 0xF8, 0x13, 0x4F, 0xF0, + 0x00, 0x00, 0x0C, 0xD0, 0x81, 0x46, 0x0F, 0x21, 0x4E, 0x48, 0x0B, 0xF0, + 0x61, 0xFF, 0x00, 0x26, 0xDF, 0xF8, 0x30, 0xA1, 0x4F, 0xF0, 0x01, 0x08, + 0x41, 0xF2, 0xFC, 0x3B, 0x5A, 0xE0, 0xC4, 0xF8, 0xF8, 0x03, 0xBD, 0xE8, + 0xFE, 0x8F, 0xD4, 0xF8, 0xEC, 0x23, 0x08, 0xFA, 0x06, 0xF1, 0x40, 0x46, + 0x0A, 0x42, 0x4E, 0xD0, 0x06, 0xEB, 0x06, 0x12, 0x02, 0xEB, 0x82, 0x02, + 0x05, 0xEB, 0x82, 0x07, 0x97, 0xF8, 0x40, 0x20, 0x12, 0x06, 0xD4, 0xF8, + 0xF8, 0x23, 0x11, 0xD5, 0x0A, 0x43, 0x05, 0xEB, 0x86, 0x01, 0xC4, 0xF8, + 0xF8, 0x23, 0x01, 0xF5, 0x9C, 0x51, 0xD7, 0xF8, 0x5A, 0x20, 0xCA, 0x67, + 0x97, 0xF8, 0x46, 0x11, 0x88, 0x40, 0x40, 0xEA, 0x09, 0x09, 0x0A, 0xF8, + 0x01, 0x60, 0x30, 0xE0, 0x0A, 0x42, 0x2E, 0xD0, 0x97, 0xF8, 0x3E, 0x21, + 0x06, 0x2A, 0x14, 0xD0, 0x05, 0x2A, 0x12, 0xD0, 0x97, 0xF8, 0x46, 0x11, + 0x08, 0xFA, 0x01, 0xF0, 0x40, 0xEA, 0x09, 0x09, 0x0A, 0xF8, 0x01, 0x60, + 0x05, 0xEB, 0x86, 0x01, 0x01, 0xEB, 0x0B, 0x00, 0x5A, 0x37, 0x39, 0x46, + 0x00, 0x90, 0x03, 0xF0, 0x8F, 0xFB, 0x98, 0xB1, 0x15, 0xE0, 0xB7, 0xF8, + 0x42, 0x00, 0x20, 0xF0, 0x08, 0x00, 0xA7, 0xF8, 0x42, 0x00, 0xD4, 0xF8, + 0xF8, 0x03, 0x88, 0x43, 0xC4, 0xF8, 0xF8, 0x03, 0x22, 0x49, 0x05, 0xEB, + 0x86, 0x00, 0x00, 0xF5, 0x9C, 0x50, 0x09, 0x68, 0xC1, 0x67, 0xE1, 0xE7, + 0x00, 0x98, 0x39, 0x68, 0x01, 0x60, 0x76, 0x1C, 0x94, 0xF9, 0xF4, 0x03, + 0xB0, 0x42, 0xA4, 0xDA, 0x00, 0x27, 0x72, 0xE0, 0xD4, 0xF8, 0xEC, 0x23, + 0x08, 0xFA, 0x07, 0xF1, 0x0A, 0x42, 0x6B, 0xD0, 0xD4, 0xF8, 0xF8, 0x23, + 0x0A, 0x42, 0x67, 0xD1, 0x07, 0xEB, 0x07, 0x11, 0x01, 0xEB, 0x81, 0x01, + 0x05, 0xEB, 0x81, 0x01, 0x00, 0x91, 0x91, 0xF8, 0x3E, 0x11, 0x02, 0x29, + 0x01, 0xD0, 0x01, 0x29, 0x5A, 0xD1, 0x00, 0x99, 0x43, 0x46, 0x91, 0xF8, + 0x46, 0x11, 0x08, 0xFA, 0x01, 0xF0, 0x10, 0xEA, 0x09, 0x0F, 0x23, 0xD0, + 0x1A, 0xF8, 0x01, 0x00, 0xB8, 0x42, 0x4D, 0xD0, 0x00, 0xEB, 0x00, 0x10, + 0x00, 0xEB, 0x80, 0x00, 0x05, 0xEB, 0x80, 0x00, 0x06, 0x46, 0x09, 0xE0, + 0x08, 0x06, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0xFD, 0x06, 0x10, 0x00, + 0x80, 0x2C, 0x10, 0x00, 0x36, 0x7A, 0x01, 0x00, 0x00, 0x99, 0xFF, 0xF7, + 0x2F, 0xFF, 0x01, 0x28, 0x36, 0xD1, 0x30, 0x46, 0x00, 0x99, 0xFF, 0xF7, + 0x0D, 0xFF, 0x28, 0x46, 0x00, 0x99, 0x00, 0xF0, 0xF7, 0xFD, 0x2D, 0xE0, + 0x00, 0x98, 0x98, 0x46, 0x5A, 0x30, 0x00, 0x26, 0x02, 0x90, 0x23, 0xE0, + 0xD4, 0xF8, 0xF8, 0x13, 0x08, 0xFA, 0x06, 0xF0, 0x01, 0x42, 0x1C, 0xD0, + 0x06, 0xEB, 0x06, 0x10, 0x00, 0xEB, 0x80, 0x00, 0x05, 0xEB, 0x80, 0x00, + 0x05, 0xEB, 0x86, 0x01, 0x01, 0x90, 0x59, 0x44, 0x02, 0x98, 0x03, 0xF0, + 0x13, 0xFB, 0x01, 0x28, 0x0D, 0xD1, 0xDD, 0xE9, 0x00, 0x10, 0xFF, 0xF7, + 0x05, 0xFF, 0x01, 0x28, 0x07, 0xD1, 0xDD, 0xE9, 0x00, 0x10, 0xFF, 0xF7, + 0xE3, 0xFE, 0x28, 0x46, 0x00, 0x99, 0x00, 0xF0, 0xCD, 0xFD, 0x76, 0x1C, + 0x94, 0xF9, 0xF4, 0x03, 0xB0, 0x42, 0xD7, 0xDA, 0x7F, 0x1C, 0x94, 0xF9, + 0xF4, 0x03, 0xB8, 0x42, 0x88, 0xDA, 0x28, 0xE7, 0x33, 0x49, 0x00, 0x20, + 0x88, 0x60, 0x0F, 0x21, 0x32, 0x48, 0x0B, 0xF0, 0x79, 0xBE, 0x90, 0xF8, + 0x42, 0x00, 0x40, 0x07, 0x01, 0xD5, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, + 0x70, 0x47, 0x90, 0xF8, 0x3E, 0x01, 0x01, 0x28, 0x00, 0xD0, 0x00, 0x20, + 0x70, 0x47, 0x90, 0xF8, 0x3E, 0x01, 0x02, 0x28, 0x05, 0xD0, 0x03, 0x28, + 0x03, 0xD0, 0x04, 0x28, 0x01, 0xD0, 0x00, 0x20, 0x70, 0x47, 0x01, 0x20, + 0x70, 0x47, 0x10, 0xB5, 0x90, 0xF8, 0x42, 0x10, 0x49, 0x06, 0x03, 0xD5, + 0xFF, 0xF7, 0xED, 0xFF, 0x01, 0x28, 0x00, 0xD0, 0x00, 0x20, 0x10, 0xBD, + 0x91, 0xF8, 0x3E, 0x21, 0x01, 0x2A, 0x08, 0xD0, 0x02, 0x2A, 0x06, 0xD0, + 0x06, 0x20, 0x81, 0xF8, 0x3E, 0x01, 0x00, 0x20, 0x81, 0xF8, 0x43, 0x01, + 0x70, 0x47, 0x00, 0xF0, 0x87, 0xBD, 0xF0, 0xB5, 0x91, 0xF9, 0x4B, 0x61, + 0x93, 0xF9, 0x00, 0x40, 0x92, 0xF9, 0x4B, 0x51, 0x77, 0x1C, 0x02, 0xD0, + 0x6D, 0x1C, 0x15, 0xD0, 0x0B, 0xE0, 0x6E, 0x1C, 0x0B, 0xD0, 0x00, 0xEB, + 0x85, 0x02, 0x00, 0xEB, 0x84, 0x00, 0xD2, 0x6B, 0xC2, 0xF8, 0x50, 0x11, + 0xC1, 0x63, 0x81, 0xF8, 0x4B, 0x41, 0x1C, 0x70, 0xF0, 0xBD, 0x64, 0x1C, + 0x64, 0xB2, 0x40, 0xF8, 0x24, 0x10, 0x81, 0xF8, 0x4B, 0x41, 0x02, 0xE0, + 0x00, 0xEB, 0x86, 0x01, 0xC9, 0x6B, 0x00, 0xEB, 0x84, 0x00, 0xC1, 0xF8, + 0x50, 0x21, 0xC2, 0x63, 0x82, 0xF8, 0x4B, 0x41, 0xEB, 0xE7, 0x00, 0x00, + 0x08, 0x06, 0x10, 0x00, 0x80, 0x2C, 0x10, 0x00, 0xF0, 0xB5, 0x44, 0x88, + 0x4E, 0x88, 0x01, 0x25, 0xA4, 0x1B, 0x24, 0xB2, 0x00, 0x2C, 0x01, 0xDB, + 0x26, 0x46, 0x00, 0xE0, 0x66, 0x42, 0x5E, 0x80, 0x56, 0x42, 0x94, 0x42, + 0x02, 0xDD, 0x44, 0x88, 0xA4, 0x1A, 0x03, 0xE0, 0xB4, 0x42, 0x03, 0xDA, + 0x44, 0x88, 0x14, 0x44, 0x4C, 0x80, 0x00, 0x25, 0x04, 0x88, 0x0F, 0x88, + 0xE4, 0x1B, 0x24, 0xB2, 0x00, 0x2C, 0x01, 0xDB, 0x27, 0x46, 0x00, 0xE0, + 0x67, 0x42, 0x1F, 0x80, 0x94, 0x42, 0x02, 0xDD, 0x00, 0x88, 0x80, 0x1A, + 0x03, 0xE0, 0xB4, 0x42, 0x03, 0xDA, 0x00, 0x88, 0x10, 0x44, 0x08, 0x80, + 0x00, 0x25, 0x28, 0x46, 0xF0, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x96, 0x4D, + 0x0F, 0x46, 0x06, 0x46, 0x81, 0x89, 0x28, 0x68, 0x90, 0x46, 0xF9, 0xB1, + 0x90, 0xF8, 0xC7, 0x43, 0x0B, 0xF0, 0xA8, 0xFE, 0x18, 0xB1, 0x28, 0x68, + 0x90, 0xF8, 0xC9, 0x43, 0x12, 0xE0, 0xB0, 0x7D, 0x02, 0x28, 0x04, 0xD0, + 0x01, 0x28, 0x06, 0xD0, 0x03, 0x28, 0x08, 0xD0, 0x0A, 0xE0, 0x28, 0x68, + 0x90, 0xF8, 0xCE, 0x43, 0x06, 0xE0, 0x28, 0x68, 0x90, 0xF8, 0x51, 0x44, + 0x02, 0xE0, 0x28, 0x68, 0x90, 0xF8, 0x2C, 0x44, 0xB0, 0x89, 0x40, 0x1E, + 0xB0, 0x81, 0x11, 0xE0, 0xB1, 0x7D, 0x90, 0xF8, 0xCB, 0x43, 0x02, 0x29, + 0x04, 0xD0, 0x01, 0x29, 0x05, 0xD0, 0x03, 0x29, 0x06, 0xD0, 0x07, 0xE0, + 0x90, 0xF8, 0xCE, 0x43, 0x04, 0xE0, 0x90, 0xF8, 0x52, 0x44, 0x01, 0xE0, + 0x90, 0xF8, 0x2D, 0x44, 0x29, 0x68, 0xB2, 0x7D, 0x91, 0xF8, 0xCA, 0x03, + 0x02, 0x2A, 0x04, 0xD0, 0x01, 0x2A, 0x05, 0xD0, 0x03, 0x2A, 0x06, 0xD0, + 0x07, 0xE0, 0x91, 0xF8, 0xCD, 0x03, 0x04, 0xE0, 0x91, 0xF8, 0x53, 0x04, + 0x01, 0xE0, 0x91, 0xF8, 0x2E, 0x04, 0x38, 0x80, 0xA8, 0xF8, 0x00, 0x40, + 0xBD, 0xE8, 0xF0, 0x81, 0x2D, 0xE9, 0xF0, 0x4F, 0x00, 0xF1, 0x5E, 0x04, + 0x85, 0xB0, 0x4F, 0xF0, 0x00, 0x0B, 0x84, 0xF8, 0x15, 0xB0, 0xDF, 0xF8, + 0xA4, 0x91, 0x0E, 0x46, 0x80, 0xF8, 0x74, 0xB0, 0x05, 0x46, 0xB0, 0xF8, + 0x42, 0x10, 0x4F, 0xF0, 0x01, 0x08, 0xD9, 0xF8, 0x00, 0x00, 0x4A, 0x06, + 0xC2, 0x46, 0x01, 0xD5, 0x02, 0x21, 0x0F, 0xE0, 0x0A, 0x07, 0x06, 0xD5, + 0x90, 0xF8, 0x40, 0x24, 0x52, 0x06, 0x02, 0xD5, 0x84, 0xF8, 0x16, 0xA0, + 0x07, 0xE0, 0x90, 0xF8, 0x20, 0x24, 0x92, 0x07, 0x03, 0xD5, 0x09, 0x06, + 0x01, 0xD5, 0x03, 0x21, 0xA1, 0x75, 0x95, 0xF8, 0x3E, 0x11, 0x03, 0x29, + 0x09, 0xD0, 0xA2, 0x7C, 0x01, 0x2A, 0x06, 0xD0, 0x04, 0x29, 0x2D, 0xD0, + 0x07, 0x29, 0x2B, 0xD0, 0x08, 0x29, 0x76, 0xD0, 0x9C, 0xE0, 0x90, 0xF8, + 0xC6, 0x73, 0x0B, 0xF0, 0x25, 0xFE, 0x18, 0xB1, 0xD9, 0xF8, 0x00, 0x00, + 0x90, 0xF8, 0xC8, 0x73, 0x95, 0xF8, 0x3E, 0x01, 0x03, 0x28, 0x00, 0xD0, + 0x00, 0x27, 0xA0, 0x7D, 0x01, 0x28, 0x02, 0xD0, 0x03, 0x28, 0x05, 0xD0, + 0x08, 0xE0, 0xD9, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0x50, 0x74, 0x03, 0xE0, + 0xD9, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0x2B, 0x74, 0xA7, 0x81, 0x31, 0x68, + 0x21, 0x60, 0x31, 0x68, 0x61, 0x60, 0x84, 0xF8, 0x14, 0xA0, 0x84, 0xF8, + 0x13, 0xA0, 0x84, 0xF8, 0x12, 0xB0, 0x73, 0xE0, 0x02, 0xAA, 0x01, 0xA9, + 0x20, 0x46, 0xFF, 0xF7, 0x46, 0xFF, 0x03, 0xAB, 0xBD, 0xF9, 0x08, 0x20, + 0x21, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0x10, 0xFF, 0x83, 0x46, 0x04, 0xAB, + 0xBD, 0xF9, 0x04, 0x20, 0x21, 0x1D, 0x30, 0x46, 0xFF, 0xF7, 0x08, 0xFF, + 0x07, 0x46, 0xBB, 0xF1, 0x01, 0x0F, 0x03, 0xD0, 0x20, 0x7D, 0x01, 0x28, + 0x4D, 0xD0, 0x4E, 0xE0, 0xBD, 0xF9, 0x0C, 0x00, 0xBD, 0xF9, 0x0E, 0x10, + 0x81, 0x42, 0x00, 0xDD, 0x08, 0x46, 0xD9, 0xF8, 0x00, 0x10, 0x91, 0xF8, + 0xCC, 0x23, 0x02, 0xF0, 0x0F, 0x03, 0x4F, 0xEA, 0x12, 0x1C, 0xA2, 0x7D, + 0x02, 0x2A, 0x04, 0xD0, 0x01, 0x2A, 0x05, 0xD0, 0x03, 0x2A, 0x06, 0xD0, + 0x0B, 0xE0, 0x91, 0xF8, 0xCF, 0x13, 0x04, 0xE0, 0x91, 0xF8, 0x54, 0x14, + 0x01, 0xE0, 0x91, 0xF8, 0x2F, 0x14, 0x01, 0xF0, 0x0F, 0x03, 0x4F, 0xEA, + 0x11, 0x1C, 0x01, 0x2F, 0x0C, 0xD0, 0xCD, 0xF8, 0x00, 0xC0, 0xBD, 0xF9, + 0x08, 0x20, 0xBD, 0xF9, 0x04, 0x10, 0x07, 0xF0, 0xDC, 0xFD, 0x21, 0x7D, + 0x01, 0x29, 0x0D, 0xD0, 0x18, 0xE0, 0x23, 0xE0, 0xA0, 0x68, 0x30, 0x60, + 0xD9, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0x80, 0x03, 0x00, 0x06, 0x01, 0xD4, + 0x4F, 0xF0, 0x00, 0x08, 0x60, 0x46, 0xEE, 0xE7, 0x95, 0xF8, 0x41, 0x11, + 0x41, 0xB9, 0xD9, 0xF8, 0x00, 0x10, 0x91, 0xF8, 0xBC, 0x13, 0x0A, 0x09, + 0xD4, 0xF8, 0x0E, 0x10, 0x07, 0xF0, 0xD4, 0xFD, 0xC4, 0xF8, 0x0E, 0x00, + 0x01, 0xE0, 0x84, 0xF8, 0x15, 0xA0, 0x84, 0xF8, 0x14, 0xB0, 0xE7, 0x74, + 0xB8, 0xF1, 0x00, 0x0F, 0x02, 0xD1, 0x03, 0xE0, 0xA0, 0x68, 0x30, 0x60, + 0x30, 0x68, 0xA0, 0x60, 0x05, 0xB0, 0x40, 0x46, 0xBD, 0xE8, 0xF0, 0x8F, + 0x4C, 0x07, 0x10, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x17, 0x46, 0x06, 0x46, + 0xDD, 0xE9, 0x06, 0xC2, 0xC8, 0x78, 0x00, 0x25, 0x0C, 0x46, 0x03, 0x28, + 0x30, 0xD2, 0xFE, 0x48, 0xDF, 0xF8, 0xF8, 0xE3, 0x01, 0x68, 0x91, 0xF8, + 0x0A, 0x14, 0xA1, 0x70, 0xDE, 0xF8, 0x04, 0xE0, 0xBE, 0xF1, 0x00, 0x0F, + 0x06, 0xDD, 0xD0, 0xF8, 0x00, 0xE0, 0x9E, 0xF8, 0x0B, 0xE4, 0xA1, 0xEB, + 0x0E, 0x01, 0xA1, 0x70, 0x00, 0x68, 0x71, 0x6B, 0xB0, 0xF8, 0x0C, 0x04, + 0x81, 0x42, 0x15, 0xDD, 0xDB, 0xB2, 0x39, 0x46, 0x60, 0x46, 0x00, 0xF0, + 0xE8, 0xFA, 0xE0, 0x78, 0x40, 0x1C, 0xC0, 0xB2, 0xE0, 0x70, 0x03, 0x28, + 0x06, 0xD0, 0xEE, 0x49, 0xB6, 0xF9, 0x56, 0x00, 0xB1, 0xF9, 0x00, 0x10, + 0x88, 0x42, 0x05, 0xDD, 0x03, 0x20, 0xE0, 0x70, 0x01, 0x25, 0x01, 0xE0, + 0x00, 0x20, 0xE0, 0x70, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x2D, 0xE9, + 0xFC, 0x5F, 0x4F, 0xF0, 0x00, 0x0B, 0x0C, 0x46, 0x81, 0x46, 0x5D, 0x46, + 0x4F, 0xF0, 0x02, 0x0A, 0x01, 0x26, 0x00, 0xF5, 0x80, 0x57, 0x7C, 0xE0, + 0xD7, 0xF8, 0xEC, 0x03, 0x06, 0xFA, 0x05, 0xFE, 0x10, 0xEA, 0x0E, 0x0F, + 0x74, 0xD0, 0x05, 0xEB, 0x05, 0x10, 0x00, 0xEB, 0x80, 0x01, 0x09, 0xEB, + 0x81, 0x00, 0x00, 0xF5, 0x9A, 0x71, 0x90, 0xF8, 0x3E, 0x81, 0xB0, 0xF9, + 0x0E, 0xC0, 0xB8, 0xF1, 0x01, 0x0F, 0x0F, 0xD0, 0xB8, 0xF1, 0x02, 0x0F, + 0x0C, 0xD0, 0x90, 0xF8, 0x42, 0x00, 0x40, 0x07, 0x51, 0xD5, 0xD2, 0x48, + 0xEB, 0xB2, 0x61, 0x46, 0xB0, 0xF9, 0x08, 0x20, 0x20, 0x46, 0x00, 0xF0, + 0xA0, 0xFA, 0x55, 0xE0, 0xCE, 0x4B, 0xB0, 0xF9, 0x54, 0x20, 0xB3, 0xF9, + 0x00, 0x30, 0x9A, 0x42, 0x4E, 0xDB, 0xB8, 0xF1, 0x01, 0x0F, 0x03, 0xD1, + 0x00, 0x22, 0x0A, 0x60, 0x4A, 0x60, 0x0A, 0x81, 0xC6, 0x4A, 0xB2, 0xF9, + 0x00, 0x30, 0x63, 0x45, 0x03, 0xDC, 0xB2, 0xF9, 0x02, 0x30, 0x63, 0x45, + 0x0C, 0xDA, 0xB0, 0xF8, 0x42, 0x30, 0x43, 0xF0, 0x04, 0x03, 0xA0, 0xF8, + 0x42, 0x30, 0xC3, 0x68, 0x4B, 0x60, 0x81, 0xF8, 0x08, 0xA0, 0xB2, 0xF9, + 0x00, 0x20, 0x19, 0xE0, 0xB2, 0xF9, 0x08, 0x30, 0x63, 0x45, 0x03, 0xDC, + 0xB2, 0xF9, 0x0A, 0x30, 0x63, 0x45, 0x19, 0xDA, 0xB0, 0xF8, 0x42, 0x30, + 0x43, 0xF0, 0x04, 0x03, 0xA0, 0xF8, 0x42, 0x30, 0x90, 0xF8, 0x3E, 0x31, + 0x01, 0x2B, 0x02, 0xD0, 0x0B, 0x7A, 0x02, 0x2B, 0x01, 0xD1, 0xC3, 0x68, + 0x4B, 0x60, 0x0E, 0x72, 0xB2, 0xF9, 0x08, 0x20, 0x2B, 0x46, 0xCD, 0xE9, + 0x00, 0x42, 0x62, 0x46, 0xFF, 0xF7, 0x4A, 0xFF, 0x83, 0x46, 0x0F, 0xE0, + 0x00, 0x20, 0x08, 0x72, 0x08, 0xE0, 0xA9, 0x48, 0xB0, 0xF9, 0x08, 0x10, + 0x61, 0x45, 0x07, 0xDA, 0xB0, 0xF9, 0x0A, 0x00, 0x60, 0x45, 0x03, 0xDD, + 0xA0, 0x68, 0x40, 0xEA, 0x0E, 0x00, 0xA0, 0x60, 0x6D, 0x1C, 0x97, 0xF9, + 0xF4, 0x03, 0xA8, 0x42, 0xBF, 0xF4, 0x7E, 0xAF, 0x20, 0x68, 0x61, 0x68, + 0x9C, 0x4A, 0x50, 0xEA, 0x01, 0x03, 0xA3, 0x68, 0x01, 0xD0, 0x23, 0xB1, + 0x04, 0xE0, 0x1B, 0xB1, 0x82, 0xF8, 0x00, 0xA0, 0x00, 0xE0, 0x16, 0x70, + 0x98, 0x4A, 0x18, 0x32, 0x13, 0x68, 0x98, 0x43, 0x20, 0x60, 0x50, 0x68, + 0x81, 0x43, 0x61, 0x60, 0x96, 0x49, 0xA0, 0x68, 0x09, 0x78, 0x08, 0x43, + 0x05, 0xD1, 0x92, 0x49, 0x18, 0x22, 0x18, 0x39, 0x90, 0x48, 0x0B, 0xF0, + 0x8B, 0xFB, 0x58, 0x46, 0xBD, 0xE8, 0xFC, 0x9F, 0x8B, 0x4A, 0x10, 0xB5, + 0x12, 0x78, 0x00, 0x21, 0x01, 0x2A, 0x01, 0xD1, 0x03, 0xB1, 0x01, 0x21, + 0x90, 0xF8, 0x3E, 0x21, 0x04, 0x2A, 0x18, 0xD1, 0x84, 0x4A, 0x12, 0x68, + 0x92, 0xF8, 0x00, 0x34, 0x5B, 0x07, 0x12, 0xD5, 0xB0, 0xF8, 0x4A, 0x30, + 0xB0, 0xF8, 0x4C, 0x40, 0x1B, 0x1B, 0x82, 0x4C, 0xA4, 0x8A, 0xA3, 0x42, + 0x09, 0xDD, 0x90, 0xF8, 0x5B, 0x30, 0x90, 0xF8, 0x5A, 0x00, 0x92, 0xF8, + 0x09, 0x24, 0x18, 0x1A, 0x90, 0x42, 0x00, 0xDD, 0x01, 0x21, 0x08, 0x46, + 0x10, 0xBD, 0x30, 0xB5, 0x79, 0x4D, 0x00, 0x24, 0x18, 0x35, 0x09, 0xB1, + 0x29, 0x68, 0x11, 0xB9, 0x12, 0xB1, 0x69, 0x68, 0x01, 0xB1, 0x01, 0x24, + 0x72, 0x49, 0x09, 0x78, 0x01, 0x29, 0x01, 0xD1, 0x03, 0xB1, 0x01, 0x24, + 0x6E, 0x49, 0x09, 0x68, 0x91, 0xF8, 0x00, 0x24, 0x52, 0x07, 0x16, 0xD5, + 0x90, 0xF8, 0x3E, 0x21, 0x04, 0x2A, 0x12, 0xD1, 0xB0, 0xF8, 0x4A, 0x20, + 0xB0, 0xF8, 0x4C, 0x30, 0xD2, 0x1A, 0x6A, 0x4B, 0x9B, 0x8A, 0x9A, 0x42, + 0x09, 0xDD, 0x90, 0xF8, 0x5B, 0x20, 0x90, 0xF8, 0x5A, 0x00, 0x91, 0xF8, + 0x09, 0x14, 0x10, 0x1A, 0x88, 0x42, 0x00, 0xDD, 0x01, 0x24, 0x20, 0x46, + 0x30, 0xBD, 0x2D, 0xE9, 0xF3, 0x4F, 0x8D, 0xB0, 0x5E, 0x48, 0x00, 0x25, + 0x8B, 0x46, 0x0A, 0x95, 0x01, 0x78, 0x5E, 0x48, 0x18, 0x38, 0x01, 0x29, + 0x06, 0xD1, 0xDB, 0xF8, 0x08, 0x10, 0x19, 0xB1, 0xD0, 0xF8, 0x1C, 0x80, + 0x47, 0x6A, 0x02, 0xE0, 0xD0, 0xF8, 0x18, 0x80, 0x07, 0x6A, 0x0D, 0x9E, + 0x00, 0x24, 0x4F, 0xF0, 0x01, 0x09, 0x06, 0xF5, 0x80, 0x56, 0x0F, 0xE1, + 0x09, 0xFA, 0x04, 0xF0, 0xD6, 0xF8, 0xEC, 0x13, 0x0B, 0x90, 0x01, 0x42, + 0x1A, 0xD0, 0x04, 0xEB, 0x04, 0x10, 0x00, 0xEB, 0x80, 0x01, 0x0D, 0x98, + 0x00, 0xEB, 0x81, 0x0A, 0x9A, 0xF8, 0x42, 0x00, 0x40, 0x07, 0x0F, 0xD5, + 0x0A, 0xF5, 0x9A, 0x70, 0x01, 0x90, 0xBA, 0xF9, 0x0E, 0x00, 0x02, 0x90, + 0x9A, 0xF8, 0x3E, 0x01, 0x01, 0x28, 0x06, 0xD0, 0x02, 0x28, 0x04, 0xD0, + 0x04, 0x28, 0x1F, 0xD0, 0x05, 0x28, 0x7D, 0xD0, 0xEB, 0xE0, 0xDB, 0xF8, + 0x00, 0x10, 0xDB, 0xF8, 0x04, 0x20, 0xDB, 0xF8, 0x08, 0x30, 0x50, 0x46, + 0xFF, 0xF7, 0x60, 0xFF, 0x01, 0x28, 0x02, 0xD1, 0x01, 0x99, 0x81, 0xF8, + 0x01, 0x90, 0xDB, 0xF8, 0x00, 0x10, 0xDB, 0xF8, 0x04, 0x20, 0xDB, 0xF8, + 0x08, 0x30, 0x50, 0x46, 0xFF, 0xF7, 0x79, 0xFF, 0x01, 0x28, 0xE5, 0xD1, + 0x01, 0x99, 0x00, 0x20, 0x88, 0x70, 0xCE, 0xE0, 0xDB, 0xF8, 0x00, 0x10, + 0xDB, 0xF8, 0x04, 0x20, 0xDB, 0xF8, 0x08, 0x30, 0x50, 0x46, 0xFF, 0xF7, + 0x6A, 0xFF, 0x01, 0x28, 0x09, 0xD0, 0x01, 0x98, 0x80, 0x78, 0x48, 0xB1, + 0x01, 0x99, 0x40, 0x1E, 0x10, 0xF0, 0xFF, 0x00, 0x88, 0x70, 0x03, 0xD0, + 0x07, 0xE0, 0x01, 0x99, 0x00, 0x20, 0x88, 0x70, 0x9A, 0xF8, 0x48, 0x11, + 0x09, 0xFA, 0x01, 0xF0, 0x05, 0x43, 0xDB, 0xF8, 0x00, 0x10, 0xDB, 0xF8, + 0x04, 0x20, 0xDB, 0xF8, 0x08, 0x30, 0x50, 0x46, 0xFF, 0xF7, 0x26, 0xFF, + 0x01, 0x28, 0x02, 0xD1, 0x01, 0x99, 0x81, 0xF8, 0x01, 0x90, 0x01, 0x98, + 0xC0, 0x78, 0x03, 0x28, 0x1D, 0xD2, 0x01, 0x99, 0x89, 0x78, 0xD1, 0xB1, + 0x17, 0x49, 0xDA, 0xF8, 0x34, 0x20, 0x09, 0x68, 0xB1, 0xF8, 0x0C, 0x14, + 0x8A, 0x42, 0x0F, 0xDD, 0x40, 0x1C, 0x01, 0x99, 0xC0, 0xB2, 0x03, 0x28, + 0xC8, 0x70, 0x06, 0xD0, 0x12, 0x49, 0xBA, 0xF9, 0x56, 0x00, 0xB1, 0xF9, + 0x00, 0x10, 0x88, 0x42, 0x05, 0xDD, 0x01, 0x20, 0x0A, 0x90, 0x02, 0xE0, + 0x01, 0x99, 0x00, 0x20, 0xC8, 0x70, 0x02, 0x98, 0x0F, 0xFA, 0x88, 0xF2, + 0x82, 0x42, 0x04, 0xDC, 0x02, 0x98, 0x4F, 0xEA, 0x28, 0x41, 0x81, 0x42, + 0x16, 0xDA, 0x01, 0x98, 0x02, 0x21, 0xE3, 0xB2, 0x01, 0x72, 0x01, 0x98, + 0xDA, 0xF8, 0x0C, 0x10, 0x41, 0x60, 0x37, 0xE0, 0x56, 0xE0, 0x00, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x14, 0x06, 0x10, 0x00, 0x8C, 0x06, 0x10, 0x00, + 0xA8, 0x2C, 0x10, 0x00, 0xA0, 0x06, 0x10, 0x00, 0x20, 0x07, 0x10, 0x00, + 0x38, 0xB2, 0x02, 0x99, 0x04, 0x90, 0x88, 0x42, 0x03, 0xDC, 0x02, 0x98, + 0x39, 0x14, 0x81, 0x42, 0x25, 0xDA, 0x01, 0x98, 0x00, 0x7A, 0x02, 0x28, + 0x06, 0xD1, 0x01, 0x99, 0x81, 0xF8, 0x08, 0x90, 0x01, 0x98, 0xDA, 0xF8, + 0x0C, 0x10, 0x41, 0x60, 0x01, 0x98, 0x40, 0x78, 0x80, 0xB9, 0x01, 0x98, + 0x53, 0x46, 0x80, 0x78, 0x00, 0x28, 0x82, 0x48, 0x02, 0x69, 0x04, 0xD0, + 0x01, 0x98, 0x0A, 0xF1, 0x0C, 0x01, 0x00, 0x1D, 0x02, 0xE0, 0x0A, 0xF1, + 0x10, 0x01, 0x08, 0x1F, 0x00, 0xF0, 0xE2, 0xF8, 0x04, 0x9A, 0xE3, 0xB2, + 0x58, 0x46, 0x02, 0x99, 0x00, 0xF0, 0xCF, 0xF8, 0x31, 0xE0, 0xDB, 0xF8, + 0x08, 0x00, 0x0B, 0x99, 0x08, 0x43, 0xCB, 0xF8, 0x08, 0x00, 0x01, 0x98, + 0x80, 0x78, 0x20, 0xB1, 0x01, 0x99, 0x00, 0x22, 0x50, 0x46, 0x09, 0x1D, + 0x03, 0xE0, 0x01, 0x22, 0x0A, 0xF1, 0x0C, 0x01, 0x50, 0x46, 0x00, 0xF0, + 0xA8, 0xF8, 0xBA, 0xF8, 0x42, 0x00, 0x20, 0xF0, 0x04, 0x01, 0xAA, 0xF8, + 0x42, 0x10, 0x16, 0xE0, 0x01, 0x98, 0x00, 0x7A, 0x01, 0x28, 0x12, 0xD1, + 0x01, 0x98, 0x80, 0x78, 0x78, 0xB1, 0x01, 0x99, 0x01, 0x22, 0x50, 0x46, + 0x09, 0x1D, 0x00, 0xF0, 0x94, 0xF8, 0xBA, 0xF8, 0x42, 0x00, 0x20, 0xF0, + 0x04, 0x01, 0xAA, 0xF8, 0x42, 0x10, 0xBA, 0xF8, 0x56, 0x10, 0xAA, 0xF8, + 0x54, 0x10, 0x64, 0x1C, 0x96, 0xF9, 0xF4, 0x03, 0xA0, 0x42, 0xBF, 0xF4, + 0xEB, 0xAE, 0x5D, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x00, 0x04, 0x80, 0x07, + 0x02, 0xD5, 0x28, 0x46, 0xFC, 0xF7, 0x6F, 0xFC, 0x59, 0x48, 0x15, 0xB1, + 0x80, 0xF8, 0x00, 0x90, 0x01, 0xE0, 0x00, 0x21, 0x01, 0x70, 0x0A, 0x98, + 0x0F, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x53, 0x49, 0x0B, 0x68, 0x51, 0x49, + 0x5A, 0x8E, 0x18, 0x39, 0x12, 0x1A, 0x08, 0x80, 0x4A, 0x80, 0x93, 0xF8, + 0x0F, 0x34, 0x18, 0x44, 0x88, 0x80, 0xD0, 0x1A, 0xC8, 0x80, 0x70, 0x47, + 0x4B, 0x49, 0x0B, 0x68, 0x49, 0x49, 0x5A, 0x8E, 0x18, 0x39, 0x12, 0x1A, + 0x08, 0x81, 0x4A, 0x81, 0x93, 0xF8, 0x12, 0x34, 0x18, 0x44, 0x88, 0x81, + 0xD0, 0x1A, 0xC8, 0x81, 0x70, 0x47, 0x10, 0xB5, 0x43, 0x4C, 0x20, 0x68, + 0x90, 0xF8, 0x0E, 0x04, 0xFF, 0xF7, 0xDB, 0xFF, 0x20, 0x68, 0x90, 0xF8, + 0x0E, 0x04, 0xFF, 0xF7, 0xE5, 0xFF, 0x22, 0x68, 0x3C, 0x49, 0x92, 0xF8, + 0x10, 0x04, 0x18, 0x39, 0x40, 0x43, 0x08, 0x61, 0x92, 0xF8, 0x11, 0x04, + 0x88, 0x82, 0x18, 0x22, 0x37, 0x48, 0x0B, 0xF0, 0xB3, 0xF9, 0x38, 0x49, + 0x00, 0x20, 0x35, 0x4A, 0x08, 0x70, 0x37, 0x49, 0x18, 0x3A, 0x48, 0x60, + 0x10, 0x63, 0x50, 0x63, 0x90, 0x63, 0x35, 0x4A, 0x10, 0x70, 0x08, 0x70, + 0x10, 0xBD, 0xFE, 0xB5, 0x00, 0x24, 0x06, 0x46, 0x00, 0x94, 0x01, 0x94, + 0x69, 0x46, 0x02, 0x94, 0xFF, 0xF7, 0x61, 0xFD, 0x05, 0x46, 0x69, 0x46, + 0x30, 0x46, 0xFF, 0xF7, 0x66, 0xFE, 0x40, 0xEA, 0x05, 0x01, 0x2A, 0x48, + 0x01, 0x29, 0x01, 0xD0, 0x41, 0x68, 0x05, 0xE0, 0x25, 0x49, 0x09, 0x68, + 0x91, 0xF8, 0x0A, 0x14, 0x49, 0x1F, 0x41, 0x60, 0x00, 0x29, 0x04, 0xDD, + 0x49, 0x1E, 0x41, 0x60, 0x21, 0x49, 0x09, 0x78, 0x01, 0xB9, 0x44, 0x60, + 0x1D, 0x48, 0x9D, 0xE8, 0x0E, 0x00, 0x18, 0x30, 0x80, 0xE8, 0x0E, 0x00, + 0xFE, 0xBD, 0x02, 0x23, 0x80, 0xF8, 0x3E, 0x31, 0x00, 0x23, 0x80, 0xF8, + 0x42, 0x31, 0x01, 0x2A, 0x05, 0xD0, 0x09, 0x68, 0x01, 0x62, 0x01, 0x21, + 0x80, 0xF8, 0x34, 0x11, 0x70, 0x47, 0x03, 0x22, 0x0C, 0x30, 0x07, 0xF0, + 0x67, 0xBA, 0x10, 0xB5, 0x01, 0x24, 0x9C, 0x40, 0x91, 0x42, 0x03, 0xDA, + 0x01, 0x68, 0x21, 0x43, 0x01, 0x60, 0x10, 0xBD, 0x41, 0x68, 0x21, 0x43, + 0x41, 0x60, 0x10, 0xBD, 0x70, 0xB5, 0x15, 0x46, 0x0A, 0x46, 0x06, 0x46, + 0x01, 0x46, 0x1C, 0x46, 0x10, 0x46, 0x07, 0xF0, 0x74, 0xFA, 0xA8, 0x42, + 0x09, 0xDD, 0x00, 0x22, 0x31, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0xD1, 0xFF, + 0x34, 0xF8, 0x42, 0x0F, 0x20, 0xF0, 0x04, 0x00, 0x20, 0x80, 0x70, 0xBD, + 0xA8, 0x2C, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0xA4, 0x06, 0x10, 0x00, + 0x14, 0x06, 0x10, 0x00, 0xA5, 0x06, 0x10, 0x00, 0x10, 0xB5, 0x41, 0xF2, + 0xE4, 0x41, 0x82, 0x48, 0x0B, 0xF0, 0x92, 0xF9, 0x40, 0xF2, 0x3C, 0x41, + 0x80, 0x48, 0x0B, 0xF0, 0x8D, 0xF9, 0x80, 0x48, 0xFF, 0x21, 0x80, 0xF8, + 0xF4, 0x13, 0x00, 0xF0, 0x95, 0xFC, 0xFF, 0xF7, 0xE3, 0xFA, 0xFF, 0xF7, + 0x5A, 0xFF, 0x00, 0xF0, 0xFB, 0xF8, 0xFD, 0xF7, 0x6A, 0xFB, 0xFE, 0xF7, + 0x8C, 0xF8, 0xBD, 0xE8, 0x10, 0x40, 0xFE, 0xF7, 0x05, 0xBE, 0x70, 0xB5, + 0x76, 0x4D, 0x00, 0x24, 0x72, 0x48, 0xAC, 0x71, 0x00, 0xF0, 0x86, 0xFC, + 0x74, 0x4E, 0x30, 0x68, 0x90, 0xF8, 0x40, 0x04, 0xC1, 0x06, 0x04, 0xD5, + 0xC0, 0x07, 0x02, 0xD0, 0x6C, 0x48, 0xFF, 0xF7, 0xCF, 0xF9, 0x30, 0x68, + 0x90, 0xF8, 0x00, 0x04, 0xC0, 0x07, 0x05, 0xD0, 0x68, 0x48, 0xFF, 0xF7, + 0x5E, 0xFF, 0x67, 0x48, 0x00, 0xF0, 0xD7, 0xF8, 0x65, 0x48, 0xFD, 0xF7, + 0x4C, 0xFB, 0x64, 0x48, 0xFE, 0xF7, 0x73, 0xF8, 0x63, 0x48, 0x80, 0xF8, + 0x38, 0x44, 0x63, 0x48, 0xB0, 0xF8, 0xF8, 0x03, 0xA5, 0xF8, 0x1F, 0x00, + 0x70, 0xBD, 0x70, 0xB5, 0x5E, 0x4D, 0x60, 0x4E, 0x95, 0xF8, 0x38, 0x04, + 0x88, 0xB3, 0xB0, 0x71, 0x29, 0x46, 0x5A, 0x48, 0x00, 0xF0, 0x88, 0xFC, + 0x5C, 0x4C, 0x20, 0x68, 0x90, 0xF8, 0x40, 0x04, 0xC1, 0x06, 0x04, 0xD5, + 0xC0, 0x07, 0x02, 0xD0, 0x54, 0x48, 0xFF, 0xF7, 0x9F, 0xF9, 0x20, 0x68, + 0x90, 0xF8, 0x00, 0x04, 0xC0, 0x07, 0x02, 0xD0, 0x50, 0x48, 0xFF, 0xF7, + 0x2E, 0xFF, 0x20, 0x68, 0x90, 0xF8, 0x80, 0x03, 0xC0, 0x07, 0x02, 0xD0, + 0x4C, 0x48, 0xFF, 0xF7, 0x27, 0xF9, 0x4B, 0x48, 0x00, 0xF0, 0x9F, 0xF8, + 0x49, 0x48, 0xFD, 0xF7, 0x14, 0xFB, 0x48, 0x48, 0xFE, 0xF7, 0x3B, 0xF8, + 0x00, 0x20, 0x85, 0xF8, 0x38, 0x04, 0x47, 0x48, 0xB0, 0xF8, 0xF8, 0x03, + 0xA6, 0xF8, 0x1F, 0x00, 0x70, 0xBD, 0xFF, 0xE7, 0xFF, 0xF7, 0x99, 0xFF, + 0xF5, 0xE7, 0x10, 0xB5, 0x40, 0x4C, 0x01, 0x46, 0x94, 0xF8, 0x38, 0x04, + 0x0F, 0x28, 0x0B, 0xD2, 0x00, 0xEB, 0xC0, 0x00, 0x04, 0xEB, 0xC0, 0x00, + 0x48, 0x22, 0x0B, 0xF0, 0xA7, 0xF8, 0x94, 0xF8, 0x38, 0x04, 0x40, 0x1C, + 0x84, 0xF8, 0x38, 0x04, 0x10, 0xBD, 0x10, 0xB5, 0x00, 0xF5, 0x80, 0x50, + 0x00, 0x21, 0xD0, 0xF8, 0xEC, 0x33, 0x01, 0x22, 0x02, 0xFA, 0x01, 0xF4, + 0x23, 0x42, 0x0B, 0xD1, 0x8A, 0x40, 0x13, 0x43, 0xC0, 0xF8, 0xEC, 0x33, + 0x90, 0xF9, 0xF4, 0x23, 0x8A, 0x42, 0x01, 0xDA, 0x80, 0xF8, 0xF4, 0x13, + 0x48, 0xB2, 0x10, 0xBD, 0x49, 0x1C, 0x0F, 0x29, 0xEC, 0xDB, 0x4F, 0xF0, + 0xFF, 0x30, 0x10, 0xBD, 0x10, 0xB5, 0x00, 0xF5, 0x80, 0x50, 0x91, 0xF8, + 0x4C, 0x41, 0x01, 0x23, 0xD0, 0xF8, 0xEC, 0x23, 0xA3, 0x40, 0x9A, 0x43, + 0xC0, 0xF8, 0xEC, 0x23, 0x00, 0x22, 0x81, 0xF8, 0x3E, 0x21, 0x90, 0xF9, + 0xF4, 0x23, 0x91, 0xF9, 0x4C, 0x11, 0x8A, 0x42, 0x07, 0xD1, 0xD0, 0xF8, + 0xEC, 0x13, 0xB1, 0xFA, 0x81, 0xF1, 0xC1, 0xF1, 0x1F, 0x01, 0x80, 0xF8, + 0xF4, 0x13, 0x10, 0xBD, 0x30, 0xB5, 0x00, 0xF5, 0x80, 0x50, 0x00, 0x22, + 0xD0, 0xF8, 0xF0, 0x43, 0x01, 0x23, 0x00, 0xBF, 0x03, 0xFA, 0x02, 0xF5, + 0x2C, 0x42, 0x06, 0xD1, 0x93, 0x40, 0x1C, 0x43, 0xC0, 0xF8, 0xF0, 0x43, + 0x81, 0xF8, 0x4D, 0x21, 0x30, 0xBD, 0x52, 0x1C, 0x52, 0xB2, 0x0A, 0x2A, + 0xF0, 0xDB, 0xFF, 0x20, 0x81, 0xF8, 0x4D, 0x01, 0x30, 0xBD, 0x10, 0xB5, + 0x00, 0xF5, 0x80, 0x50, 0x91, 0xF8, 0x4D, 0x41, 0x01, 0x23, 0xD0, 0xF8, + 0xF0, 0x23, 0xA3, 0x40, 0x9A, 0x43, 0xC0, 0xF8, 0xF0, 0x23, 0xFF, 0x20, + 0x81, 0xF8, 0x4D, 0x01, 0x10, 0xBD, 0x04, 0x48, 0x70, 0x47, 0x03, 0x48, + 0x90, 0xF8, 0x38, 0x04, 0x70, 0x47, 0x00, 0x00, 0xCC, 0x2C, 0x10, 0x00, + 0xB0, 0x41, 0x10, 0x00, 0xCC, 0x3C, 0x10, 0x00, 0x0A, 0x44, 0x01, 0x20, + 0x4C, 0x07, 0x10, 0x00, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x5F, 0x00, 0x24, + 0x06, 0x46, 0x01, 0x27, 0xDF, 0xF8, 0x0C, 0x81, 0xDF, 0xF8, 0x0C, 0x91, + 0xDF, 0xF8, 0x0C, 0xA1, 0x4F, 0xF0, 0x05, 0x0B, 0x00, 0xF5, 0x80, 0x55, + 0x76, 0xE0, 0x00, 0xBF, 0xD5, 0xF8, 0xEC, 0x03, 0x07, 0xFA, 0x04, 0xF1, + 0x08, 0x42, 0x6D, 0xD0, 0x04, 0xEB, 0x04, 0x10, 0x00, 0xEB, 0x80, 0x00, + 0x06, 0xEB, 0x80, 0x01, 0x91, 0xF8, 0x3E, 0x01, 0x01, 0x28, 0x04, 0xD0, + 0x02, 0x28, 0x02, 0xD0, 0x04, 0x28, 0x3B, 0xD0, 0x5E, 0xE0, 0x91, 0xF8, + 0x3F, 0x01, 0x03, 0x28, 0x06, 0xD0, 0x04, 0x28, 0x04, 0xD0, 0x02, 0x28, + 0x21, 0xD0, 0x01, 0x28, 0x29, 0xD0, 0x53, 0xE0, 0x30, 0x48, 0xB1, 0xF8, + 0x42, 0x20, 0xB0, 0xF9, 0x00, 0x00, 0x53, 0x07, 0x01, 0xD5, 0xB8, 0xF9, + 0x00, 0x00, 0x13, 0x07, 0x02, 0xD5, 0x2C, 0x48, 0xB0, 0xF9, 0x00, 0x00, + 0xB1, 0xF9, 0x54, 0x30, 0x83, 0x42, 0x41, 0xDA, 0xD0, 0x05, 0x06, 0xD5, + 0xB9, 0xF9, 0x00, 0x00, 0x83, 0x42, 0x02, 0xDD, 0x81, 0xF8, 0x3F, 0x71, + 0x38, 0xE0, 0x30, 0x46, 0xFF, 0xF7, 0x56, 0xFF, 0x34, 0xE0, 0x91, 0xF8, + 0x42, 0x20, 0x00, 0x20, 0x52, 0x07, 0x01, 0xD5, 0xB8, 0xF9, 0x00, 0x00, + 0xB1, 0xF9, 0x54, 0x20, 0x03, 0xE0, 0xB1, 0xF9, 0x54, 0x20, 0xB9, 0xF9, + 0x00, 0x00, 0x82, 0x42, 0xEB, 0xDB, 0x23, 0xE0, 0x91, 0xF8, 0x40, 0x00, + 0x10, 0xF0, 0x06, 0x0F, 0x1E, 0xD0, 0x91, 0xF8, 0x42, 0x00, 0x40, 0x07, + 0x1A, 0xD4, 0x17, 0x4A, 0x15, 0x48, 0x12, 0x78, 0xB0, 0xF9, 0x00, 0x00, + 0x01, 0x2A, 0x01, 0xD1, 0xBA, 0xF9, 0x00, 0x00, 0x91, 0xF8, 0x3F, 0x21, + 0x03, 0x2A, 0x02, 0xD0, 0x02, 0x2A, 0x05, 0xD0, 0x0A, 0xE0, 0xB1, 0xF9, + 0x54, 0x20, 0xBA, 0xF9, 0x00, 0x00, 0x01, 0xE0, 0xB1, 0xF9, 0x54, 0x20, + 0x82, 0x42, 0x01, 0xDA, 0x81, 0xF8, 0x3E, 0xB1, 0x64, 0x1C, 0x64, 0xB2, + 0x95, 0xF9, 0xF4, 0x03, 0xA0, 0x42, 0x85, 0xDA, 0xBD, 0xE8, 0xF0, 0x9F, + 0xA0, 0x06, 0x10, 0x00, 0x90, 0x06, 0x10, 0x00, 0x92, 0x06, 0x10, 0x00, + 0x8C, 0x06, 0x10, 0x00, 0xAA, 0x06, 0x10, 0x00, 0x94, 0x06, 0x10, 0x00, + 0xA5, 0x06, 0x10, 0x00, 0x90, 0xF8, 0x40, 0x10, 0x09, 0x06, 0x14, 0xD5, + 0xB0, 0xF8, 0x42, 0x10, 0x0A, 0x07, 0x0C, 0xD4, 0xFE, 0x4A, 0x12, 0x68, + 0x92, 0xF8, 0x40, 0x34, 0x5B, 0x06, 0x06, 0xD5, 0x92, 0xF8, 0x80, 0x23, + 0x52, 0x06, 0x02, 0xD4, 0x01, 0x22, 0x80, 0xF8, 0x70, 0x20, 0x41, 0xF0, + 0x08, 0x01, 0xA0, 0xF8, 0x42, 0x10, 0x70, 0x47, 0xB0, 0xF8, 0x40, 0x10, + 0xC9, 0x05, 0x14, 0xD5, 0xB0, 0xF8, 0x42, 0x10, 0x0A, 0x06, 0x0C, 0xD4, + 0xF1, 0x4A, 0x12, 0x68, 0x92, 0xF8, 0x20, 0x34, 0x9B, 0x07, 0x06, 0xD5, + 0x92, 0xF8, 0x80, 0x23, 0x52, 0x06, 0x02, 0xD4, 0x01, 0x22, 0x80, 0xF8, + 0x70, 0x20, 0x41, 0xF0, 0x80, 0x01, 0xA0, 0xF8, 0x42, 0x10, 0x70, 0x47, + 0x2D, 0xE9, 0xF0, 0x47, 0x82, 0x46, 0x92, 0xF8, 0x40, 0x00, 0x15, 0x46, + 0x0C, 0x46, 0x02, 0x28, 0x01, 0xD1, 0x28, 0x69, 0xE8, 0x60, 0x04, 0xF1, + 0x0C, 0x07, 0x4F, 0xF0, 0x00, 0x08, 0x4F, 0xF0, 0xFF, 0x39, 0x05, 0xF1, + 0x0C, 0x06, 0x63, 0xB3, 0x01, 0x20, 0x84, 0xF8, 0x3E, 0x01, 0x95, 0xF8, + 0x40, 0x00, 0x84, 0xF8, 0x3F, 0x01, 0x84, 0xF8, 0x4D, 0x91, 0x84, 0xF8, + 0x42, 0x81, 0x84, 0xF8, 0x43, 0x81, 0xA4, 0xF8, 0x42, 0x80, 0xC4, 0xF8, + 0x2C, 0x80, 0x84, 0xF8, 0x41, 0x81, 0x84, 0xF8, 0x44, 0x81, 0x95, 0xF8, + 0x42, 0x00, 0x84, 0xF8, 0x47, 0x01, 0x68, 0x8E, 0xA4, 0xF8, 0x56, 0x00, + 0x95, 0xF8, 0x41, 0x00, 0x84, 0xF8, 0x48, 0x01, 0xE8, 0x68, 0x20, 0x62, + 0x03, 0x22, 0x31, 0x46, 0x20, 0x46, 0x07, 0xF0, 0x1D, 0xF8, 0x03, 0x22, + 0x31, 0x46, 0x38, 0x46, 0x07, 0xF0, 0x18, 0xF8, 0x14, 0xE0, 0x11, 0x46, + 0x20, 0x46, 0x00, 0xF0, 0x5F, 0xFB, 0xE0, 0x6A, 0x03, 0x22, 0x40, 0x1C, + 0xE0, 0x62, 0x31, 0x46, 0x20, 0x46, 0x06, 0xF0, 0xFF, 0xFF, 0x03, 0x22, + 0x31, 0x46, 0x38, 0x46, 0x06, 0xF0, 0xFA, 0xFF, 0x94, 0xF8, 0x46, 0x01, + 0x84, 0xF8, 0x47, 0x01, 0x95, 0xF8, 0x40, 0x00, 0x84, 0xF8, 0x3F, 0x01, + 0x95, 0xF8, 0x42, 0x00, 0x84, 0xF8, 0x46, 0x01, 0xE8, 0x8C, 0xA4, 0xF8, + 0x44, 0x00, 0x28, 0x8D, 0xA4, 0xF8, 0x46, 0x00, 0x68, 0x8D, 0xA4, 0xF8, + 0x48, 0x00, 0xE8, 0x8D, 0xA4, 0xF8, 0x4A, 0x00, 0x28, 0x8E, 0xA4, 0xF8, + 0x4C, 0x00, 0x28, 0x8B, 0xA4, 0xF8, 0x4E, 0x00, 0xB5, 0xF9, 0x32, 0x00, + 0xA4, 0xF8, 0x54, 0x00, 0xA9, 0x69, 0x61, 0x63, 0xE9, 0x69, 0xA1, 0x63, + 0x29, 0x6A, 0xE1, 0x63, 0xA9, 0x8E, 0xA4, 0xF8, 0x58, 0x10, 0xA9, 0x8C, + 0xA4, 0xF8, 0x40, 0x10, 0xD5, 0xF8, 0x36, 0x10, 0xC4, 0xF8, 0x5A, 0x10, + 0x69, 0x69, 0xE1, 0x61, 0x95, 0xF8, 0x43, 0x10, 0x84, 0xF8, 0x49, 0x11, + 0x95, 0xF8, 0x44, 0x10, 0x84, 0xF8, 0x4A, 0x11, 0xB4, 0xF9, 0x56, 0x10, + 0x81, 0x42, 0x01, 0xDA, 0xA4, 0xF8, 0x56, 0x00, 0xC4, 0xF8, 0x50, 0x81, + 0x84, 0xF8, 0x4B, 0x91, 0xA8, 0x8C, 0x80, 0x05, 0xB4, 0xF8, 0x42, 0x00, + 0x02, 0xD5, 0x40, 0xF4, 0x80, 0x70, 0x01, 0xE0, 0x20, 0xF4, 0x80, 0x70, + 0xA4, 0xF8, 0x42, 0x00, 0x21, 0x46, 0x50, 0x46, 0x00, 0xF0, 0xD3, 0xFA, + 0x20, 0x46, 0xFF, 0xF7, 0x21, 0xFF, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, + 0x36, 0xE7, 0xF0, 0xB5, 0xB1, 0xF9, 0x02, 0x60, 0xB2, 0xF9, 0x02, 0x50, + 0x78, 0x24, 0x06, 0xFB, 0x05, 0xF7, 0x00, 0x2F, 0x2A, 0xDD, 0xB1, 0xF9, + 0x00, 0x70, 0xB2, 0xF9, 0x00, 0xC0, 0x07, 0xFB, 0x0C, 0xF7, 0x00, 0x2F, + 0x22, 0xDD, 0x76, 0x43, 0x5D, 0x43, 0x96, 0xFB, 0xF5, 0xF5, 0x2D, 0xB2, + 0x45, 0x80, 0xB1, 0xF9, 0x00, 0x10, 0xB2, 0xF9, 0x00, 0x20, 0x49, 0x43, + 0x5A, 0x43, 0x91, 0xFB, 0xF2, 0xF1, 0x0A, 0xB2, 0x02, 0x80, 0x78, 0x2D, + 0x00, 0xDD, 0x44, 0x80, 0xB0, 0xF9, 0x02, 0x30, 0x6F, 0xF0, 0x77, 0x01, + 0x8B, 0x42, 0x00, 0xDA, 0x41, 0x80, 0x78, 0x2A, 0x00, 0xDD, 0x04, 0x80, + 0xB0, 0xF9, 0x00, 0x20, 0x8A, 0x42, 0x00, 0xDA, 0x01, 0x80, 0xF0, 0xBD, + 0x00, 0x21, 0x41, 0x80, 0xFA, 0xE7, 0x2D, 0xE9, 0xFF, 0x4F, 0xDF, 0xF8, + 0xD4, 0x81, 0x0F, 0x46, 0x72, 0x4E, 0xD8, 0xF8, 0x08, 0x10, 0x8F, 0xB0, + 0x00, 0x20, 0x08, 0x60, 0x30, 0x68, 0xB0, 0xF8, 0x82, 0x53, 0x0A, 0xF0, + 0x77, 0xFF, 0x01, 0x28, 0x04, 0xD1, 0x30, 0x68, 0xB0, 0xF8, 0x84, 0x03, + 0x00, 0xB1, 0x05, 0x46, 0x0A, 0xF0, 0x64, 0xFF, 0x80, 0xB1, 0x30, 0x68, + 0x69, 0x49, 0xB0, 0xF8, 0x86, 0x53, 0xB0, 0xF8, 0x8A, 0x03, 0x09, 0x68, + 0x88, 0x42, 0x07, 0xDA, 0x0A, 0xF0, 0x62, 0xFF, 0x01, 0x28, 0x03, 0xD1, + 0x30, 0x68, 0xB0, 0xF8, 0x88, 0x03, 0x05, 0x44, 0xDF, 0xF8, 0x88, 0xB1, + 0x62, 0x48, 0x63, 0x4B, 0xBB, 0xF9, 0x00, 0x20, 0x62, 0x49, 0xDF, 0xF8, + 0x8C, 0xA1, 0x12, 0xB1, 0x01, 0x2A, 0x3E, 0xD0, 0x7B, 0xE0, 0xB0, 0xF9, + 0x00, 0x00, 0xBA, 0xF9, 0x00, 0x20, 0xD1, 0x46, 0x42, 0x43, 0x03, 0xEB, + 0x42, 0x04, 0x42, 0x00, 0x09, 0x68, 0x20, 0x46, 0x0A, 0xF0, 0xE9, 0xFD, + 0xD8, 0xF8, 0x04, 0x20, 0x05, 0x21, 0x92, 0xFB, 0xF1, 0xF3, 0x01, 0xFB, + 0x13, 0x22, 0x41, 0xF6, 0x5A, 0x61, 0x11, 0x44, 0x21, 0x80, 0x55, 0x49, + 0x40, 0x46, 0x49, 0x79, 0x61, 0x80, 0x54, 0x49, 0x09, 0x88, 0xA1, 0x80, + 0x53, 0x49, 0x09, 0x88, 0xE1, 0x80, 0x53, 0x49, 0x09, 0x88, 0x21, 0x81, + 0x52, 0x49, 0x09, 0x88, 0x61, 0x81, 0x52, 0x49, 0x09, 0x88, 0xA1, 0x81, + 0x51, 0x49, 0x09, 0x88, 0xE1, 0x81, 0xB9, 0xF8, 0x00, 0x10, 0x49, 0x1C, + 0x09, 0xB2, 0xA9, 0xF8, 0x00, 0x10, 0x42, 0x68, 0x52, 0x1C, 0xC8, 0xF8, + 0x04, 0x20, 0x05, 0x29, 0x41, 0xDB, 0x00, 0x21, 0xA9, 0xF8, 0x00, 0x10, + 0x3D, 0xE0, 0xBA, 0xF9, 0x00, 0x40, 0x0A, 0x2C, 0x36, 0xDA, 0xB0, 0xF9, + 0x00, 0x00, 0xD1, 0x46, 0x00, 0xFB, 0x04, 0xF2, 0x03, 0xEB, 0x42, 0x04, + 0x42, 0x00, 0x09, 0x68, 0x20, 0x46, 0x0A, 0xF0, 0xA8, 0xFD, 0xD8, 0xF8, + 0x04, 0x20, 0x05, 0x21, 0x92, 0xFB, 0xF1, 0xF3, 0x01, 0xFB, 0x13, 0x22, + 0x41, 0xF6, 0x5A, 0x61, 0x11, 0x44, 0x21, 0x80, 0x34, 0x49, 0x40, 0x46, + 0x49, 0x79, 0x61, 0x80, 0x33, 0x49, 0x09, 0x88, 0xA1, 0x80, 0x33, 0x49, + 0x09, 0x88, 0xE1, 0x80, 0x32, 0x49, 0x09, 0x88, 0x21, 0x81, 0x32, 0x49, + 0x09, 0x88, 0x61, 0x81, 0x31, 0x49, 0x09, 0x88, 0xA1, 0x81, 0x31, 0x49, + 0x09, 0x88, 0xE1, 0x81, 0xB9, 0xF8, 0x00, 0x10, 0x49, 0x1C, 0xA9, 0xF8, + 0x00, 0x10, 0x41, 0x68, 0x49, 0x1C, 0xC8, 0xF8, 0x04, 0x10, 0x02, 0xE0, + 0x02, 0x20, 0xAB, 0xF8, 0x00, 0x00, 0x6D, 0x43, 0x02, 0x95, 0x30, 0x68, + 0x0F, 0x9E, 0x00, 0x25, 0x90, 0xF8, 0x8C, 0x03, 0x04, 0x90, 0x06, 0xF5, + 0x80, 0x56, 0x96, 0xE0, 0x4F, 0xF0, 0x01, 0x09, 0xD6, 0xF8, 0xEC, 0x03, + 0x09, 0xFA, 0x05, 0xF1, 0x08, 0x42, 0x7D, 0xD0, 0x05, 0xEB, 0x05, 0x10, + 0x00, 0xEB, 0x80, 0x01, 0x0F, 0x98, 0x00, 0xEB, 0x81, 0x04, 0x94, 0xF8, + 0x3E, 0x01, 0x07, 0x28, 0x72, 0xD0, 0x21, 0x46, 0x20, 0x1D, 0x06, 0xF0, + 0xBE, 0xFE, 0x00, 0x90, 0xB0, 0xF5, 0x80, 0x5F, 0x08, 0xDD, 0x01, 0x46, + 0xAD, 0x20, 0x06, 0xF0, 0x69, 0xF9, 0xAB, 0xF8, 0x00, 0x90, 0x05, 0x20, + 0xAA, 0xF8, 0x00, 0x00, 0x04, 0x99, 0x00, 0x98, 0x48, 0x43, 0x00, 0xFB, + 0x01, 0xF9, 0x02, 0x99, 0x89, 0x45, 0x1D, 0xE0, 0x4C, 0x07, 0x10, 0x00, + 0x1C, 0x06, 0x10, 0x00, 0x24, 0x07, 0x10, 0x00, 0x84, 0x07, 0x10, 0x00, + 0xFE, 0x06, 0x10, 0x00, 0x20, 0x4D, 0x01, 0x20, 0x10, 0x07, 0x10, 0x00, + 0x82, 0x07, 0x10, 0x00, 0x0A, 0x44, 0x01, 0x20, 0x86, 0x07, 0x10, 0x00, + 0x88, 0x07, 0x10, 0x00, 0x8A, 0x07, 0x10, 0x00, 0x8C, 0x07, 0x10, 0x00, + 0x8E, 0x07, 0x10, 0x00, 0x90, 0x07, 0x10, 0x00, 0x00, 0xDA, 0x89, 0x46, + 0x22, 0x46, 0x21, 0x1D, 0x08, 0xA8, 0x06, 0xF0, 0x7A, 0xFE, 0x22, 0x1D, + 0x11, 0x1D, 0x0A, 0xA8, 0x06, 0xF0, 0x75, 0xFE, 0xBD, 0xF9, 0x20, 0x00, + 0x64, 0x30, 0xC8, 0x28, 0x04, 0xD8, 0xBD, 0xF9, 0x22, 0x00, 0x64, 0x30, + 0xC8, 0x28, 0x01, 0xD9, 0x01, 0x23, 0x00, 0xE0, 0x03, 0x23, 0x0A, 0xAA, + 0x08, 0xA9, 0x09, 0xA8, 0xFF, 0xF7, 0xA1, 0xFE, 0x60, 0x88, 0xBD, 0xF8, + 0x26, 0x10, 0x08, 0x44, 0xAD, 0xF8, 0x2E, 0x00, 0x20, 0x88, 0xBD, 0xF8, + 0x24, 0x10, 0x00, 0x24, 0x08, 0x44, 0xAD, 0xF8, 0x2C, 0x00, 0x1A, 0xE0, + 0x04, 0xEB, 0xC4, 0x00, 0x07, 0xEB, 0xC0, 0x01, 0x0B, 0xA8, 0x0C, 0x31, + 0x06, 0xF0, 0x57, 0xFE, 0x48, 0x45, 0x0E, 0xDA, 0xD8, 0xF8, 0x08, 0x10, + 0x0A, 0x68, 0x02, 0xEB, 0x42, 0x02, 0x00, 0xE0, 0x0D, 0xE0, 0x01, 0xEB, + 0x42, 0x02, 0x50, 0x60, 0x54, 0x72, 0x15, 0x72, 0x08, 0x68, 0x40, 0x1C, + 0x08, 0x60, 0x64, 0x1C, 0xE4, 0xB2, 0x97, 0xF8, 0x38, 0x04, 0xA0, 0x42, + 0xE0, 0xD8, 0x6D, 0x1C, 0x6D, 0xB2, 0x96, 0xF9, 0xF4, 0x03, 0xA8, 0x42, + 0xBF, 0xF6, 0x64, 0xAF, 0xD8, 0xF8, 0x08, 0x00, 0x45, 0x46, 0x01, 0x68, + 0x00, 0x29, 0x78, 0xD0, 0x00, 0xF0, 0xC2, 0xF9, 0x00, 0x26, 0x4F, 0xF0, + 0x04, 0x09, 0xDF, 0xF8, 0xC4, 0xA3, 0x4F, 0xF0, 0x06, 0x0B, 0x6A, 0xE0, + 0x06, 0xEB, 0x46, 0x01, 0x00, 0xEB, 0x41, 0x00, 0x90, 0xF9, 0x08, 0x40, + 0x90, 0xF9, 0x09, 0x30, 0x11, 0x98, 0x02, 0x68, 0x01, 0x20, 0x00, 0xFA, + 0x04, 0xF1, 0x0A, 0x42, 0x5A, 0xD1, 0xDD, 0xF8, 0x48, 0xC0, 0x00, 0xFA, + 0x03, 0xF8, 0xDC, 0xF8, 0x00, 0xC0, 0x1C, 0xEA, 0x08, 0x0F, 0x51, 0xD1, + 0x11, 0x98, 0x0A, 0x43, 0x02, 0x60, 0x12, 0x98, 0x12, 0x99, 0x00, 0x68, + 0x40, 0xEA, 0x08, 0x00, 0x08, 0x60, 0x04, 0xEB, 0x04, 0x10, 0x00, 0xEB, + 0x80, 0x01, 0x0F, 0x98, 0x00, 0xEB, 0x81, 0x04, 0x03, 0xEB, 0xC3, 0x00, + 0x07, 0xEB, 0xC0, 0x02, 0x00, 0x23, 0x21, 0x46, 0x0F, 0x98, 0xFF, 0xF7, + 0x7D, 0xFD, 0x94, 0xF8, 0x3E, 0x01, 0x03, 0x28, 0x04, 0xD0, 0x04, 0x28, + 0x04, 0xD0, 0x06, 0x28, 0x08, 0xD0, 0x2F, 0xE0, 0x01, 0x20, 0x00, 0xE0, + 0x00, 0x20, 0x84, 0xF8, 0x41, 0x01, 0x84, 0xF8, 0x3E, 0x91, 0x27, 0xE0, + 0x84, 0xF8, 0x3E, 0x91, 0x94, 0xF8, 0x40, 0x00, 0x10, 0xF0, 0x06, 0x0F, + 0x20, 0xD0, 0x94, 0xF8, 0x42, 0x00, 0x40, 0x07, 0x1C, 0xD4, 0xCA, 0x49, + 0xC8, 0x48, 0x09, 0x78, 0xB0, 0xF9, 0x00, 0x00, 0x01, 0x29, 0x01, 0xD1, + 0xBA, 0xF9, 0x00, 0x00, 0x94, 0xF8, 0x3F, 0x11, 0x03, 0x29, 0x02, 0xD0, + 0x02, 0x29, 0x09, 0xD0, 0x0C, 0xE0, 0xB4, 0xF9, 0x54, 0x10, 0xBA, 0xF9, + 0x00, 0x00, 0x05, 0xE0, 0x84, 0xF8, 0x3E, 0xB1, 0x04, 0xE0, 0x08, 0xE0, + 0xB4, 0xF9, 0x54, 0x10, 0x81, 0x42, 0xF7, 0xDB, 0x76, 0x1C, 0xA8, 0x68, + 0x01, 0x68, 0xB1, 0x42, 0x90, 0xDC, 0x13, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, + 0xB8, 0x48, 0x00, 0x21, 0x01, 0x70, 0x81, 0x60, 0xC1, 0x60, 0x70, 0x47, + 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x41, 0xF2, 0x38, 0x40, 0x2E, 0x21, + 0x28, 0x44, 0x0A, 0xF0, 0xE3, 0xFC, 0x00, 0x24, 0x05, 0xF5, 0x80, 0x56, + 0x01, 0x27, 0x4F, 0xF0, 0x05, 0x08, 0x1B, 0xE0, 0xD6, 0xF8, 0xEC, 0x03, + 0x07, 0xFA, 0x04, 0xF1, 0x08, 0x42, 0x14, 0xD0, 0x04, 0xEB, 0x04, 0x10, + 0x00, 0xEB, 0x80, 0x00, 0x05, 0xEB, 0x80, 0x01, 0x91, 0xF8, 0x3E, 0x01, + 0x03, 0x28, 0x04, 0xD0, 0x04, 0x28, 0x02, 0xD0, 0x02, 0x28, 0x03, 0xD0, + 0x05, 0xE0, 0x81, 0xF8, 0x3E, 0x81, 0x02, 0xE0, 0x28, 0x46, 0xFF, 0xF7, + 0xE1, 0xFB, 0x64, 0x1C, 0x96, 0xF9, 0xF4, 0x03, 0xA0, 0x42, 0xDF, 0xDA, + 0xBD, 0xE8, 0xF0, 0x81, 0x2D, 0xE9, 0xFC, 0x47, 0x04, 0x46, 0x00, 0x25, + 0x9A, 0x48, 0x0E, 0x46, 0x00, 0x95, 0x01, 0x21, 0x08, 0x30, 0x01, 0x95, + 0x04, 0xF0, 0x87, 0xF8, 0x96, 0x48, 0x05, 0x21, 0x0C, 0x30, 0x04, 0xF0, + 0x82, 0xF8, 0x41, 0xF2, 0x38, 0x40, 0x2E, 0x21, 0x20, 0x44, 0x0A, 0xF0, + 0xA3, 0xFC, 0x91, 0x4F, 0xFF, 0x22, 0x2D, 0x21, 0xF8, 0x68, 0x0A, 0xF0, + 0x73, 0xFC, 0x3D, 0x70, 0x04, 0xF5, 0x80, 0x57, 0x4F, 0xF0, 0x01, 0x08, + 0xD7, 0xF8, 0xEC, 0x03, 0x58, 0xB3, 0x6B, 0x46, 0x01, 0xAA, 0x31, 0x46, + 0x20, 0x46, 0xFF, 0xF7, 0xC0, 0xFD, 0x4F, 0xF0, 0x05, 0x09, 0x1E, 0xE0, + 0xD7, 0xF8, 0xEC, 0x13, 0x08, 0xFA, 0x05, 0xF0, 0x01, 0x42, 0x17, 0xD0, + 0x01, 0x99, 0x08, 0x42, 0x14, 0xD1, 0x05, 0xEB, 0x05, 0x10, 0x00, 0xEB, + 0x80, 0x00, 0x04, 0xEB, 0x80, 0x01, 0x91, 0xF8, 0x3E, 0x01, 0x03, 0x28, + 0x04, 0xD0, 0x04, 0x28, 0x02, 0xD0, 0x02, 0x28, 0x03, 0xD0, 0x05, 0xE0, + 0x81, 0xF8, 0x3E, 0x91, 0x02, 0xE0, 0x20, 0x46, 0xFF, 0xF7, 0x8E, 0xFB, + 0x6D, 0x1C, 0x97, 0xF9, 0xF4, 0x03, 0xA8, 0x42, 0xDC, 0xDA, 0x00, 0x25, + 0x47, 0x46, 0x1A, 0xE0, 0x00, 0x99, 0x07, 0xFA, 0x05, 0xF0, 0x08, 0x42, + 0x14, 0xD1, 0x20, 0x46, 0xFF, 0xF7, 0x61, 0xFB, 0x00, 0x28, 0x0F, 0xDB, + 0x00, 0xEB, 0x00, 0x11, 0x01, 0xEB, 0x81, 0x01, 0x04, 0xEB, 0x81, 0x01, + 0x05, 0xEB, 0xC5, 0x02, 0x81, 0xF8, 0x4C, 0x01, 0x06, 0xEB, 0xC2, 0x02, + 0x01, 0x23, 0x20, 0x46, 0xFF, 0xF7, 0x96, 0xFC, 0x6D, 0x1C, 0x96, 0xF8, + 0x38, 0x04, 0xA8, 0x42, 0xE0, 0xD8, 0x63, 0x48, 0x01, 0x21, 0x08, 0x30, + 0x04, 0xF0, 0x38, 0xF8, 0x60, 0x48, 0x05, 0x21, 0x0C, 0x30, 0x04, 0xF0, + 0x33, 0xF8, 0xBD, 0xE8, 0xFC, 0x87, 0x30, 0xB5, 0x5C, 0x4A, 0x91, 0xF8, + 0x46, 0x51, 0xD4, 0x68, 0x63, 0x5D, 0xFF, 0x2B, 0x05, 0xD1, 0x13, 0x78, + 0x63, 0x55, 0x0F, 0x2B, 0x01, 0xD2, 0x5B, 0x1C, 0x13, 0x70, 0x91, 0xF8, + 0x46, 0x21, 0xA2, 0x5C, 0x81, 0xF8, 0x46, 0x21, 0x00, 0xEB, 0x42, 0x02, + 0x02, 0xF5, 0x80, 0x52, 0x91, 0xF8, 0x4C, 0x51, 0xB2, 0xF8, 0x38, 0x34, + 0x01, 0x24, 0xAC, 0x40, 0x23, 0x43, 0xA2, 0xF8, 0x38, 0x34, 0x91, 0xF8, + 0x46, 0x11, 0x41, 0xF2, 0x56, 0x42, 0x10, 0x44, 0x0A, 0x5C, 0x52, 0x1C, + 0x0A, 0x54, 0x30, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0x91, 0xF8, + 0x40, 0x00, 0x00, 0x26, 0x0D, 0x46, 0x01, 0x28, 0x01, 0xD1, 0x84, 0xF8, + 0x44, 0x61, 0x94, 0xF8, 0x3F, 0x01, 0x43, 0x4F, 0xDF, 0xF8, 0x0C, 0x81, + 0x01, 0x28, 0x1F, 0xD1, 0x95, 0xF8, 0x40, 0x00, 0x03, 0x28, 0x4D, 0xD1, + 0x94, 0xF8, 0x3E, 0x01, 0x02, 0x28, 0x04, 0xD0, 0x03, 0x28, 0x06, 0xD0, + 0x04, 0x28, 0x04, 0xD0, 0x1E, 0xE0, 0x20, 0x46, 0xFC, 0xF7, 0xC0, 0xFD, + 0x0E, 0xE0, 0xD8, 0xF8, 0x00, 0x10, 0x94, 0xF8, 0x44, 0x01, 0x91, 0xF8, + 0x4B, 0x13, 0x01, 0xF0, 0x0F, 0x01, 0x88, 0x42, 0x02, 0xD8, 0x39, 0x78, + 0x01, 0x29, 0x06, 0xD0, 0x84, 0xF8, 0x44, 0x61, 0x95, 0xF8, 0x40, 0x00, + 0x03, 0x28, 0x07, 0xD0, 0x08, 0xE0, 0x40, 0x1C, 0x84, 0xF8, 0x44, 0x01, + 0x01, 0x20, 0x85, 0xF8, 0x40, 0x00, 0x01, 0xE0, 0x84, 0xF8, 0x45, 0x61, + 0x94, 0xF8, 0x3F, 0x01, 0x03, 0x28, 0x1F, 0xD1, 0x95, 0xF8, 0x40, 0x00, + 0x01, 0x28, 0x1B, 0xD1, 0x94, 0xF8, 0x3E, 0x01, 0x04, 0x28, 0x17, 0xD1, + 0x38, 0x78, 0xB0, 0xB9, 0xD8, 0xF8, 0x00, 0x00, 0xB4, 0xF9, 0x56, 0x10, + 0xB0, 0xF8, 0x52, 0x23, 0x91, 0x42, 0x0E, 0xDA, 0x94, 0xF8, 0x45, 0x11, + 0x90, 0xF8, 0x54, 0x03, 0x81, 0x42, 0x07, 0xD2, 0x03, 0x20, 0x85, 0xF8, + 0x40, 0x00, 0x94, 0xF8, 0x45, 0x01, 0x40, 0x1C, 0x84, 0xF8, 0x45, 0x01, + 0xF0, 0xE6, 0x84, 0xF8, 0x45, 0x61, 0xED, 0xE6, 0x7C, 0xB5, 0x00, 0x21, + 0x1C, 0xE0, 0x01, 0xEB, 0x41, 0x03, 0x4A, 0x1C, 0x00, 0xEB, 0x43, 0x03, + 0x12, 0xE0, 0x02, 0xEB, 0x42, 0x04, 0x00, 0xEB, 0x44, 0x04, 0x5E, 0x68, + 0x65, 0x68, 0xAE, 0x42, 0x09, 0xDD, 0x00, 0x96, 0x1E, 0x89, 0xAD, 0xF8, + 0x04, 0x60, 0x5D, 0x60, 0x25, 0x89, 0x1D, 0x81, 0x00, 0x9D, 0x65, 0x60, + 0x26, 0x81, 0x52, 0x1C, 0x04, 0x68, 0x94, 0x42, 0xE9, 0xDC, 0x49, 0x1C, + 0x02, 0x68, 0x8A, 0x42, 0xDF, 0xDC, 0x7C, 0xBD, 0x92, 0x06, 0x10, 0x00, + 0x94, 0x06, 0x10, 0x00, 0xA5, 0x06, 0x10, 0x00, 0x1C, 0x06, 0x10, 0x00, + 0xF9, 0x06, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, + 0x00, 0x22, 0x91, 0x46, 0x15, 0x46, 0x14, 0x46, 0x00, 0x92, 0xFE, 0x4A, + 0xFE, 0x4B, 0x12, 0x68, 0xB3, 0xF9, 0x00, 0xC0, 0xFD, 0x4B, 0x17, 0x8E, + 0x1E, 0x68, 0x67, 0x45, 0x60, 0xD1, 0x86, 0x46, 0xFB, 0x48, 0x02, 0xF1, + 0x32, 0x0A, 0x8B, 0x46, 0x90, 0xF8, 0x00, 0xC0, 0xF9, 0x48, 0x07, 0x78, + 0x4D, 0xE0, 0x3A, 0x46, 0x43, 0xE0, 0x00, 0xBF, 0x3A, 0xF8, 0x12, 0x10, + 0x3E, 0xF8, 0x12, 0x00, 0x3B, 0xF8, 0x12, 0x30, 0x08, 0x1A, 0xC9, 0x1A, + 0x00, 0xB2, 0x0B, 0xB2, 0x00, 0x28, 0x01, 0xDB, 0x01, 0x46, 0x00, 0xE0, + 0x41, 0x42, 0x49, 0x45, 0x06, 0xDD, 0x00, 0x28, 0x01, 0xDB, 0x01, 0x46, + 0x00, 0xE0, 0x41, 0x42, 0x0F, 0xFA, 0x81, 0xF9, 0x19, 0x1A, 0x01, 0xD4, + 0x88, 0x46, 0x01, 0xE0, 0xC1, 0xF1, 0x00, 0x08, 0xA8, 0x45, 0x05, 0xDD, + 0x00, 0x29, 0x01, 0xDB, 0x0D, 0x46, 0x00, 0xE0, 0x4D, 0x42, 0x2D, 0xB2, + 0x00, 0x29, 0x00, 0xDA, 0x49, 0x42, 0xB6, 0xF8, 0xE2, 0x83, 0x41, 0x45, + 0x15, 0xDD, 0x00, 0x2B, 0x00, 0xDA, 0x5B, 0x42, 0x01, 0x1E, 0x00, 0xDA, + 0x41, 0x42, 0x8B, 0x42, 0x02, 0xDD, 0x64, 0x1C, 0xA4, 0xB2, 0x0A, 0xE0, + 0x00, 0x28, 0x00, 0xDA, 0x40, 0x42, 0xB6, 0xF8, 0xE4, 0x13, 0x88, 0x42, + 0x03, 0xDD, 0x4F, 0xF0, 0x00, 0x0C, 0x64, 0x46, 0x01, 0xE0, 0x52, 0x1E, + 0xBA, 0xD1, 0x0A, 0xEB, 0x47, 0x0A, 0x0E, 0xEB, 0x47, 0x0E, 0x0B, 0xEB, + 0x47, 0x0B, 0xBC, 0xF1, 0x01, 0x0C, 0xAE, 0xD2, 0x96, 0xF8, 0xE6, 0x03, + 0xA0, 0x42, 0x01, 0xD2, 0x01, 0x20, 0x00, 0x90, 0x96, 0xF8, 0xE7, 0x13, + 0xCC, 0x48, 0x00, 0x9A, 0x06, 0xF0, 0x71, 0xFB, 0xCB, 0x49, 0x21, 0xF8, + 0x25, 0x5F, 0x21, 0xF8, 0x02, 0x9C, 0x8C, 0x70, 0xBD, 0xE8, 0xF8, 0x8F, + 0x10, 0xB5, 0x0C, 0x46, 0xC3, 0x49, 0x09, 0x78, 0x4A, 0x00, 0x01, 0x46, + 0xC5, 0x48, 0x0A, 0xF0, 0x50, 0xFA, 0xC1, 0x48, 0x21, 0x46, 0x00, 0x78, + 0x42, 0x00, 0xC3, 0x48, 0x0A, 0xF0, 0x49, 0xFA, 0xC2, 0x49, 0x01, 0x20, + 0x08, 0x70, 0x10, 0xBD, 0xB8, 0x49, 0x10, 0xB5, 0xB1, 0xF9, 0x00, 0x10, + 0x4A, 0x00, 0x01, 0x46, 0xBE, 0x48, 0x00, 0x68, 0x0A, 0xF0, 0x3B, 0xFA, + 0xBD, 0x49, 0x01, 0x20, 0x08, 0x70, 0x10, 0xBD, 0x10, 0xB5, 0x01, 0x23, + 0x0A, 0xE0, 0x00, 0xBF, 0x30, 0xF9, 0x13, 0x40, 0x00, 0x2C, 0x00, 0xDA, + 0x64, 0x42, 0x8C, 0x42, 0x01, 0xDD, 0x01, 0x20, 0x10, 0xBD, 0x5B, 0x1C, + 0x93, 0x42, 0xF3, 0xDB, 0x00, 0x20, 0x10, 0xBD, 0x2D, 0xE9, 0xFF, 0x5F, + 0xDF, 0xF8, 0xAC, 0xB2, 0x00, 0x24, 0xAB, 0xF1, 0x01, 0x0B, 0xDF, 0xF8, + 0x98, 0x92, 0xCB, 0xF8, 0x04, 0x40, 0x8B, 0xF8, 0x00, 0x40, 0xD9, 0xF8, + 0x00, 0x00, 0x1F, 0x46, 0x26, 0x46, 0x90, 0xF8, 0xE0, 0x03, 0x25, 0x46, + 0xA0, 0x46, 0xC0, 0x07, 0x0E, 0xD0, 0x03, 0x20, 0xF3, 0xF7, 0xF7, 0xFC, + 0xA4, 0x48, 0x01, 0x68, 0x00, 0x98, 0xFF, 0xF7, 0x2D, 0xFF, 0x04, 0x46, + 0x11, 0x25, 0x03, 0x20, 0xF3, 0xF7, 0x08, 0xFD, 0x00, 0x2C, 0x63, 0xD1, + 0xA0, 0x48, 0x00, 0x78, 0x10, 0xF0, 0x30, 0x0F, 0x5E, 0xD0, 0xFA, 0xF7, + 0x21, 0xFD, 0xD9, 0xF8, 0x00, 0x00, 0xDF, 0xF8, 0x74, 0xA2, 0x90, 0xF8, + 0xE0, 0x03, 0x80, 0x07, 0x0B, 0xD5, 0x9B, 0x4A, 0x9B, 0x49, 0xDA, 0xF8, + 0x00, 0x00, 0x00, 0xF0, 0xFB, 0xF8, 0x04, 0x00, 0x4F, 0xF0, 0x30, 0x05, + 0x4F, 0xF0, 0x01, 0x06, 0x48, 0xD1, 0xD9, 0xF8, 0x00, 0x00, 0x90, 0xF8, + 0xE1, 0x03, 0xC0, 0x07, 0x0B, 0xD0, 0x94, 0x4A, 0x94, 0x49, 0xDA, 0xF8, + 0x00, 0x00, 0x00, 0xF0, 0x7B, 0xF8, 0x04, 0x00, 0x4F, 0xF0, 0x30, 0x05, + 0x4F, 0xF0, 0x01, 0x06, 0x36, 0xD1, 0xD9, 0xF8, 0x00, 0x00, 0x90, 0xF8, + 0xE1, 0x03, 0x80, 0x07, 0x0B, 0xD5, 0x8B, 0x4A, 0x8B, 0x49, 0xDA, 0xF8, + 0x00, 0x00, 0x00, 0xF0, 0xA4, 0xF8, 0x04, 0x00, 0x4F, 0xF0, 0x31, 0x05, + 0x4F, 0xF0, 0x01, 0x06, 0x24, 0xD1, 0x87, 0x48, 0x00, 0x78, 0x01, 0x28, + 0x20, 0xD1, 0x86, 0x48, 0x01, 0x7E, 0x86, 0x48, 0x00, 0x7E, 0x01, 0xFB, + 0x00, 0xF2, 0x19, 0x2A, 0x03, 0xD2, 0x05, 0x29, 0x01, 0xD8, 0x05, 0x28, + 0x02, 0xD9, 0x32, 0x25, 0x01, 0x26, 0x11, 0xE0, 0xD9, 0xF8, 0x00, 0x00, + 0x90, 0xF8, 0xE1, 0x03, 0x40, 0x07, 0x0B, 0xD5, 0x03, 0x20, 0xF3, 0xF7, + 0x90, 0xFC, 0x71, 0x48, 0x7B, 0x4A, 0x00, 0x99, 0x00, 0x68, 0xFA, 0xF7, + 0x7E, 0xFE, 0x03, 0x20, 0xF3, 0xF7, 0xA2, 0xFC, 0x0A, 0xF0, 0x00, 0xFB, + 0x01, 0x46, 0x77, 0x48, 0x01, 0x70, 0x54, 0xB3, 0x6E, 0xB1, 0x87, 0xF8, + 0x00, 0x80, 0x29, 0x46, 0x05, 0x20, 0x05, 0xF0, 0x9C, 0xFD, 0x00, 0x98, + 0xFF, 0xF7, 0x46, 0xFF, 0xDD, 0xE9, 0x01, 0x01, 0xFF, 0xF7, 0x2E, 0xFF, + 0x17, 0xE0, 0x01, 0x20, 0x38, 0x70, 0x8B, 0xF8, 0x00, 0x50, 0xDB, 0xF8, + 0x04, 0x10, 0x41, 0xF0, 0x02, 0x01, 0xCB, 0xF8, 0x04, 0x10, 0xD9, 0xF8, + 0x00, 0x20, 0x92, 0xF8, 0x50, 0x32, 0xDB, 0x07, 0x03, 0xD1, 0x92, 0xF8, + 0x80, 0x22, 0xD2, 0x07, 0x03, 0xD0, 0x41, 0xF0, 0x08, 0x01, 0xCB, 0xF8, + 0x04, 0x10, 0x01, 0x20, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x9F, 0x87, 0xF8, + 0x00, 0x80, 0x00, 0x78, 0xF8, 0xE7, 0x4D, 0x48, 0x00, 0x21, 0x40, 0x1E, + 0x41, 0x60, 0x01, 0x70, 0xA0, 0xF8, 0x01, 0x10, 0xC1, 0x70, 0x70, 0x47, + 0x2D, 0xE9, 0xF7, 0x4F, 0xDF, 0xF8, 0x10, 0x81, 0x93, 0x46, 0x0B, 0x46, + 0xD8, 0xF8, 0x00, 0x00, 0x00, 0x25, 0x2C, 0x46, 0x90, 0xF8, 0xEC, 0x73, + 0xB0, 0xF9, 0xE8, 0x63, 0xB0, 0xF9, 0xEA, 0xA3, 0x3E, 0x48, 0x31, 0x46, + 0x02, 0x78, 0x18, 0x46, 0xFB, 0xF7, 0x21, 0xFF, 0x81, 0x46, 0x3C, 0x48, + 0x31, 0x46, 0x02, 0x78, 0x58, 0x46, 0xFB, 0xF7, 0x1A, 0xFF, 0x01, 0x46, + 0xB9, 0xF1, 0x00, 0x0F, 0x00, 0xD0, 0x51, 0xB9, 0x33, 0x48, 0x51, 0x46, + 0xB0, 0xF9, 0x00, 0x20, 0x00, 0x98, 0x00, 0xF0, 0xBE, 0xF8, 0x04, 0x46, + 0xB8, 0x42, 0x00, 0xD9, 0x01, 0x25, 0xD8, 0xF8, 0x00, 0x00, 0x2A, 0x46, + 0x90, 0xF8, 0xED, 0x13, 0x2F, 0x48, 0x40, 0x1C, 0x06, 0xF0, 0x37, 0xFA, + 0x2E, 0x49, 0x81, 0xF8, 0x31, 0x40, 0xBD, 0xE8, 0xFE, 0x8F, 0x2D, 0xE9, + 0xF0, 0x47, 0x27, 0x4E, 0x89, 0x46, 0x92, 0x46, 0x31, 0x68, 0x24, 0x4A, + 0x00, 0x25, 0x91, 0xF8, 0xF2, 0x73, 0xB1, 0xF9, 0xF0, 0x83, 0x2C, 0x46, + 0xB1, 0xF9, 0xEE, 0x13, 0xB2, 0xF9, 0x00, 0x20, 0xFB, 0xF7, 0xF7, 0xFE, + 0x88, 0xB9, 0x1F, 0x48, 0x41, 0x46, 0x02, 0x78, 0x48, 0x46, 0x00, 0xF0, + 0x92, 0xF8, 0x04, 0x46, 0x1C, 0x48, 0x41, 0x46, 0x02, 0x78, 0x50, 0x46, + 0x00, 0xF0, 0x8B, 0xF8, 0x20, 0x44, 0xC4, 0xB2, 0xBC, 0x42, 0x00, 0xD9, + 0x01, 0x25, 0x30, 0x68, 0x2A, 0x46, 0x90, 0xF8, 0xF3, 0x13, 0x16, 0x48, + 0x80, 0x1C, 0x06, 0xF0, 0x04, 0xFA, 0x15, 0x49, 0x81, 0xF8, 0x32, 0x40, + 0xBD, 0xE8, 0xF0, 0x87, 0x2D, 0xE9, 0xF0, 0x5F, 0x0D, 0x4E, 0x83, 0x46, + 0x0B, 0x46, 0x30, 0x68, 0x20, 0x49, 0x00, 0x25, 0x90, 0xF8, 0xF5, 0x73, + 0xB0, 0xF9, 0xF6, 0xC3, 0xB0, 0xF9, 0xFA, 0x93, 0x09, 0x78, 0x92, 0x46, + 0x2C, 0x46, 0x09, 0xB1, 0xB0, 0xF9, 0xF8, 0xC3, 0x1A, 0x48, 0x00, 0x78, + 0xB0, 0xB3, 0x1A, 0x48, 0x00, 0x78, 0x34, 0xE0, 0x50, 0x07, 0x10, 0x00, + 0xFE, 0x06, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0xED, 0x06, 0x10, 0x00, + 0xEE, 0x06, 0x10, 0x00, 0x2D, 0x06, 0x10, 0x00, 0x0A, 0x44, 0x01, 0x20, + 0x7E, 0x4A, 0x01, 0x20, 0xA8, 0x4A, 0x01, 0x20, 0x7A, 0x07, 0x10, 0x00, + 0x1C, 0x07, 0x10, 0x00, 0x79, 0x07, 0x10, 0x00, 0x04, 0x07, 0x10, 0x00, + 0x10, 0x07, 0x10, 0x00, 0xF2, 0x2A, 0x10, 0x00, 0xC8, 0x2A, 0x10, 0x00, + 0xBE, 0x0B, 0x01, 0x20, 0x94, 0x0B, 0x01, 0x20, 0x66, 0x05, 0x10, 0x00, + 0x18, 0x2A, 0x10, 0x00, 0x58, 0x2A, 0x10, 0x00, 0x60, 0x2B, 0x10, 0x00, + 0x76, 0x06, 0x10, 0x00, 0xF9, 0x06, 0x10, 0x00, 0x74, 0x05, 0x10, 0x00, + 0x64, 0x05, 0x10, 0x00, 0x01, 0xE0, 0x90, 0xB1, 0x1C, 0xE0, 0x1C, 0x48, + 0x61, 0x46, 0x02, 0x78, 0x18, 0x46, 0xFF, 0xF7, 0x61, 0xFE, 0x80, 0x46, + 0x19, 0x48, 0x61, 0x46, 0x02, 0x78, 0x50, 0x46, 0xFF, 0xF7, 0x5A, 0xFE, + 0x01, 0x46, 0xB8, 0xF1, 0x00, 0x0F, 0x00, 0xD0, 0x51, 0xB9, 0x15, 0x48, + 0x49, 0x46, 0xB0, 0xF9, 0x00, 0x20, 0x58, 0x46, 0x00, 0xF0, 0x0F, 0xF8, + 0x04, 0x46, 0xB8, 0x42, 0x00, 0xD9, 0x01, 0x25, 0x30, 0x68, 0x2A, 0x46, + 0x90, 0xF8, 0xFC, 0x13, 0x0E, 0x48, 0x06, 0xF0, 0x8A, 0xF9, 0x0E, 0x49, + 0x81, 0xF8, 0x31, 0x40, 0x09, 0xE7, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x20, + 0x09, 0xE0, 0x00, 0xBF, 0x34, 0xF9, 0x12, 0x30, 0x00, 0x2B, 0x00, 0xDA, + 0x5B, 0x42, 0x8B, 0x42, 0x01, 0xDD, 0x40, 0x1C, 0xC0, 0xB2, 0x52, 0x1E, + 0xF4, 0xD2, 0x10, 0xBD, 0xED, 0x06, 0x10, 0x00, 0xEE, 0x06, 0x10, 0x00, + 0xFE, 0x06, 0x10, 0x00, 0x2E, 0x06, 0x10, 0x00, 0x0A, 0x44, 0x01, 0x20, + 0x2D, 0xE9, 0xFF, 0x4F, 0x87, 0xB0, 0x00, 0x20, 0x81, 0x46, 0x03, 0x90, + 0x02, 0x90, 0x01, 0x90, 0xFF, 0x48, 0x88, 0x46, 0x93, 0x46, 0x00, 0x68, + 0xB0, 0xF8, 0xB0, 0x02, 0x06, 0x90, 0x89, 0x78, 0x50, 0x68, 0x0A, 0xF0, + 0xD1, 0xF9, 0x00, 0x90, 0x98, 0xF8, 0x02, 0x50, 0x98, 0xF8, 0x03, 0x00, + 0x05, 0x90, 0x32, 0xE0, 0x07, 0x98, 0x98, 0xF8, 0x00, 0x40, 0x00, 0xEB, + 0xC5, 0x00, 0x04, 0x90, 0x98, 0xF8, 0x01, 0xA0, 0x1F, 0xE0, 0x04, 0x98, + 0x22, 0x46, 0x00, 0x21, 0xD0, 0xE9, 0x00, 0x67, 0x01, 0x20, 0x09, 0xF0, + 0xF9, 0xFF, 0x06, 0x40, 0x0F, 0x40, 0x3E, 0x43, 0x12, 0xD0, 0x00, 0x98, + 0x06, 0x99, 0x30, 0xF9, 0x14, 0x00, 0x88, 0x42, 0x0C, 0xDD, 0x02, 0x99, + 0x81, 0x44, 0x04, 0xFB, 0x00, 0x11, 0x02, 0x91, 0x01, 0x99, 0x05, 0xFB, + 0x00, 0x10, 0x01, 0x90, 0x03, 0x98, 0x40, 0x1C, 0x80, 0xB2, 0x03, 0x90, + 0x64, 0x1C, 0xA2, 0x45, 0xDD, 0xDA, 0xE2, 0x49, 0x00, 0x98, 0x6D, 0x1C, + 0x09, 0x78, 0x00, 0xEB, 0x41, 0x00, 0x00, 0x90, 0x05, 0x98, 0xA8, 0x42, + 0xCA, 0xDA, 0xDC, 0x48, 0x00, 0x25, 0x04, 0x68, 0x01, 0x98, 0xA1, 0x8E, + 0xC2, 0x17, 0xA1, 0xFB, 0x00, 0x36, 0x05, 0xFB, 0x00, 0x60, 0x01, 0xFB, + 0x02, 0x02, 0x4F, 0xF6, 0xFF, 0x76, 0xA3, 0xFB, 0x06, 0x07, 0x02, 0xFB, + 0x06, 0x72, 0x03, 0xFB, 0x05, 0x21, 0x94, 0xF8, 0x31, 0x30, 0x30, 0x34, + 0x5B, 0x1E, 0x89, 0xFB, 0x03, 0x23, 0x09, 0xF0, 0xCC, 0xFF, 0x72, 0x10, + 0x80, 0x18, 0xB0, 0x46, 0x41, 0xF1, 0x00, 0x01, 0x42, 0x46, 0x00, 0x23, + 0x09, 0xF0, 0xC3, 0xFF, 0x07, 0x46, 0x02, 0x98, 0x61, 0x88, 0xC2, 0x17, + 0xA1, 0xFB, 0x00, 0x36, 0x05, 0xFB, 0x00, 0x60, 0x01, 0xFB, 0x02, 0x01, + 0x42, 0x46, 0xA3, 0xFB, 0x02, 0x06, 0x01, 0xFB, 0x02, 0x61, 0x03, 0xFB, + 0x05, 0x11, 0x23, 0x78, 0x5B, 0x1E, 0x89, 0xFB, 0x03, 0x23, 0x09, 0xF0, + 0xAC, 0xFF, 0x47, 0xF6, 0xFF, 0x72, 0x80, 0x18, 0x41, 0xF1, 0x00, 0x01, + 0x42, 0x46, 0x00, 0x23, 0x09, 0xF0, 0xA3, 0xFF, 0xCB, 0xF8, 0x1C, 0x90, + 0x03, 0x99, 0xAB, 0xF8, 0x28, 0x10, 0x0A, 0x99, 0x48, 0x60, 0x0A, 0x99, + 0x0F, 0x60, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x2D, 0xE9, 0xFF, 0x4F, + 0x81, 0x46, 0xB2, 0x48, 0x00, 0x26, 0x8A, 0x46, 0x00, 0x68, 0x14, 0x46, + 0x95, 0xB0, 0x90, 0xF8, 0x21, 0x03, 0x4F, 0xF6, 0xFF, 0x75, 0x32, 0x46, + 0x31, 0x46, 0x43, 0x07, 0xAA, 0xF1, 0x01, 0x07, 0x4C, 0xD5, 0x00, 0x07, + 0x02, 0xD5, 0x8C, 0xB3, 0xBC, 0x42, 0x48, 0xDA, 0x68, 0x46, 0xD4, 0x46, + 0xA3, 0x46, 0x00, 0x23, 0x08, 0xE0, 0x00, 0xBF, 0x39, 0xF8, 0x13, 0x40, + 0x00, 0xEB, 0x43, 0x08, 0x5B, 0x1C, 0xA8, 0xF8, 0x02, 0x40, 0xDB, 0xB2, + 0x63, 0x45, 0xF5, 0xD3, 0x43, 0x88, 0x03, 0x80, 0x00, 0xEB, 0x4C, 0x04, + 0x30, 0xF8, 0x1C, 0x30, 0x63, 0x80, 0x01, 0x23, 0x10, 0xE0, 0x00, 0xBF, + 0x00, 0xEB, 0x43, 0x04, 0x34, 0xF8, 0x02, 0x8C, 0x64, 0x88, 0x44, 0x44, + 0x30, 0xF8, 0x13, 0x80, 0x04, 0xEB, 0x48, 0x04, 0x09, 0xEB, 0x43, 0x08, + 0x5B, 0x1C, 0x28, 0xF8, 0x02, 0x4C, 0xDB, 0xB2, 0x63, 0x45, 0xED, 0xD9, + 0x93, 0x4B, 0xD8, 0x46, 0x00, 0x20, 0x09, 0xE0, 0x1B, 0xE0, 0x00, 0xBF, + 0x39, 0xF9, 0x10, 0x40, 0x9C, 0x42, 0x01, 0xDD, 0x23, 0x46, 0x80, 0x46, + 0x40, 0x1C, 0xC0, 0xB2, 0x60, 0x45, 0xF5, 0xD3, 0x5F, 0xEA, 0x08, 0x04, + 0x01, 0xD1, 0xBD, 0xF9, 0x00, 0x20, 0xBC, 0x42, 0x04, 0xDB, 0x69, 0x46, + 0x01, 0xEB, 0x4A, 0x00, 0x30, 0xF9, 0x02, 0x1C, 0x1C, 0xB1, 0x09, 0xEB, + 0x44, 0x00, 0x30, 0xF9, 0x02, 0x2C, 0x39, 0xF9, 0x14, 0xA0, 0xBC, 0x42, + 0x03, 0xDA, 0x09, 0xEB, 0x44, 0x00, 0xB0, 0xF9, 0x02, 0x10, 0x10, 0x46, + 0x88, 0x46, 0x8A, 0x42, 0x01, 0xDD, 0x80, 0x46, 0x08, 0x46, 0x8A, 0x1A, + 0xA2, 0xFB, 0x05, 0x1C, 0xD3, 0x17, 0x03, 0xFB, 0x05, 0xC3, 0x02, 0xFB, + 0x06, 0x3C, 0x0A, 0xEB, 0x08, 0x02, 0x40, 0x42, 0x02, 0xEB, 0x40, 0x02, + 0x08, 0x46, 0xD3, 0x17, 0x61, 0x46, 0x09, 0xF0, 0x12, 0xFF, 0xA4, 0xFB, + 0x05, 0x3C, 0x00, 0x22, 0x02, 0xFB, 0x05, 0xC2, 0x04, 0xFB, 0x06, 0x22, + 0x1B, 0x18, 0x4A, 0x41, 0x18, 0x99, 0xA3, 0xFB, 0x01, 0x0C, 0xCC, 0x17, + 0x02, 0xFB, 0x01, 0xC1, 0x03, 0xFB, 0x04, 0x11, 0xFB, 0x17, 0x3A, 0x46, + 0x09, 0xF0, 0xFD, 0xFE, 0x04, 0x46, 0x0F, 0x46, 0x02, 0x22, 0x00, 0x23, + 0x28, 0x46, 0x31, 0x46, 0x09, 0xF0, 0xF5, 0xFE, 0x00, 0x19, 0x79, 0x41, + 0x2A, 0x46, 0x33, 0x46, 0x09, 0xF0, 0xEF, 0xFE, 0x19, 0xB0, 0x53, 0xE7, + 0x2D, 0xE9, 0xFF, 0x4F, 0x9F, 0xB0, 0x00, 0x20, 0x1B, 0x90, 0x16, 0x90, + 0x1C, 0x90, 0x0C, 0x46, 0x90, 0x46, 0x89, 0x78, 0x50, 0x68, 0x0A, 0xF0, + 0x8D, 0xF8, 0x13, 0x90, 0x94, 0xF8, 0x02, 0x90, 0x94, 0xF8, 0x03, 0xB0, + 0x2E, 0xE0, 0x1F, 0x98, 0x25, 0x78, 0x00, 0xEB, 0xC9, 0x00, 0x1D, 0x90, + 0x94, 0xF8, 0x01, 0xA0, 0x1A, 0xE0, 0x1D, 0x98, 0x2A, 0x46, 0x00, 0x21, + 0xD0, 0xE9, 0x00, 0x67, 0x01, 0x20, 0x09, 0xF0, 0xB7, 0xFE, 0x06, 0x40, + 0x0F, 0x40, 0x3E, 0x43, 0x0C, 0xD0, 0x13, 0x98, 0x1C, 0x99, 0x30, 0xF9, + 0x15, 0x00, 0x88, 0x42, 0x06, 0xDD, 0x16, 0x99, 0x08, 0x44, 0x16, 0x90, + 0x1B, 0x98, 0x40, 0x1C, 0x80, 0xB2, 0x1B, 0x90, 0x6D, 0x1C, 0xED, 0xB2, + 0xAA, 0x45, 0xE2, 0xD2, 0x43, 0x49, 0x13, 0x98, 0x09, 0x78, 0x00, 0xEB, + 0x41, 0x00, 0x13, 0x90, 0x09, 0xF1, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x09, + 0xCB, 0x45, 0xCE, 0xD2, 0x16, 0x98, 0xC8, 0xF8, 0x1C, 0x00, 0x1B, 0x98, + 0xA8, 0xF8, 0x28, 0x00, 0x98, 0xF8, 0x3E, 0x70, 0x98, 0xF8, 0x3F, 0x90, + 0x4C, 0x21, 0x68, 0x46, 0x09, 0xF0, 0x60, 0xFF, 0xA1, 0x78, 0xD8, 0xF8, + 0x04, 0x00, 0x0A, 0xF0, 0x43, 0xF8, 0x34, 0x4A, 0xA1, 0x78, 0x6D, 0x46, + 0x12, 0x78, 0x07, 0xE0, 0x30, 0xF8, 0x17, 0x30, 0x25, 0xF8, 0x11, 0x30, + 0x49, 0x1C, 0x00, 0xEB, 0x42, 0x00, 0xC9, 0xB2, 0xE3, 0x78, 0x8B, 0x42, + 0xF4, 0xD2, 0x2B, 0x4E, 0x4A, 0x46, 0x30, 0x68, 0xB0, 0xF9, 0x34, 0x30, + 0x90, 0xF8, 0x31, 0x10, 0x28, 0x46, 0xFF, 0xF7, 0xE5, 0xFE, 0x22, 0x99, + 0x08, 0x60, 0x4C, 0x21, 0x68, 0x46, 0x09, 0xF0, 0x3B, 0xFF, 0x49, 0x46, + 0xD8, 0xF8, 0x04, 0x00, 0x0A, 0xF0, 0x1E, 0xF8, 0x21, 0x78, 0x05, 0xE0, + 0x30, 0xF8, 0x11, 0x20, 0x25, 0xF8, 0x11, 0x20, 0x49, 0x1C, 0xC9, 0xB2, + 0x62, 0x78, 0x8A, 0x42, 0xF6, 0xD2, 0x30, 0x68, 0x3A, 0x46, 0xB0, 0xF9, + 0x32, 0x30, 0x90, 0xF8, 0x30, 0x10, 0x68, 0x46, 0xFF, 0xF7, 0xC6, 0xFE, + 0x22, 0x99, 0x48, 0x60, 0x23, 0xB0, 0xBF, 0xE6, 0x10, 0xB5, 0x14, 0x49, + 0x43, 0x68, 0x00, 0x22, 0x09, 0x68, 0x00, 0x2B, 0x01, 0xDA, 0x42, 0x60, + 0x03, 0xE0, 0x4C, 0x8E, 0xA3, 0x42, 0x00, 0xDD, 0x44, 0x60, 0x03, 0x68, + 0x00, 0x2B, 0x01, 0xDA, 0x02, 0x60, 0x10, 0xBD, 0x89, 0x8E, 0x8B, 0x42, + 0xFB, 0xDD, 0x01, 0x60, 0x10, 0xBD, 0x2D, 0xE9, 0xFF, 0x47, 0x14, 0x46, + 0x88, 0x46, 0x81, 0x46, 0x00, 0x27, 0x01, 0x26, 0x6B, 0x46, 0xFF, 0xF7, + 0x01, 0xFE, 0x07, 0x48, 0x03, 0x4D, 0x00, 0x78, 0x78, 0xB1, 0x28, 0x68, + 0x90, 0xF8, 0x07, 0x05, 0x00, 0x07, 0x07, 0xE0, 0x4C, 0x07, 0x10, 0x00, + 0xEE, 0x06, 0x10, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xA4, 0x06, 0x10, 0x00, + 0x01, 0xD5, 0x04, 0x27, 0x3E, 0x46, 0x94, 0xF8, 0x40, 0x00, 0x03, 0x28, + 0x04, 0xD0, 0x02, 0x28, 0x06, 0xD0, 0x01, 0x28, 0x14, 0xD0, 0x1C, 0xE0, + 0x28, 0x68, 0x06, 0xE0, 0x39, 0x46, 0x15, 0xE0, 0x28, 0x68, 0x90, 0xF8, + 0x21, 0x13, 0x89, 0x07, 0x04, 0xD5, 0x90, 0xF8, 0x07, 0x05, 0xC0, 0x07, + 0xF4, 0xD1, 0x0E, 0xE0, 0x90, 0xF8, 0x07, 0x05, 0x80, 0x07, 0x0A, 0xD5, + 0x31, 0x46, 0x05, 0xE0, 0x28, 0x68, 0x90, 0xF8, 0x07, 0x05, 0x40, 0x07, + 0x03, 0xD5, 0x02, 0x21, 0x68, 0x46, 0x01, 0xF0, 0xC1, 0xFD, 0x68, 0x46, + 0xFF, 0xF7, 0xA2, 0xFF, 0xDD, 0xE9, 0x00, 0x01, 0xCD, 0xE9, 0x02, 0x01, + 0x94, 0xF8, 0x40, 0x00, 0x02, 0x28, 0x41, 0xD1, 0x28, 0x68, 0x90, 0xF8, + 0x21, 0x03, 0x80, 0x07, 0x3C, 0xD5, 0x02, 0xAB, 0x22, 0x46, 0x41, 0x46, + 0x48, 0x46, 0xFF, 0xF7, 0xFB, 0xFE, 0x28, 0x68, 0x90, 0xF8, 0x07, 0x05, + 0x80, 0x07, 0x03, 0xD5, 0x31, 0x46, 0x02, 0xA8, 0x01, 0xF0, 0xA2, 0xFD, + 0x02, 0xA8, 0xFF, 0xF7, 0x83, 0xFF, 0x29, 0x68, 0xE3, 0x69, 0x91, 0xF8, + 0x2D, 0x23, 0x02, 0xF0, 0x0F, 0x00, 0x15, 0x09, 0xB1, 0xF8, 0x2E, 0x23, + 0xB1, 0xF8, 0x30, 0x13, 0x93, 0x42, 0x0D, 0xDD, 0x8B, 0x42, 0x01, 0xDB, + 0x28, 0x46, 0x09, 0xE0, 0x91, 0x42, 0x00, 0xD1, 0x49, 0x1C, 0x9B, 0x1A, + 0x2D, 0x1A, 0x6B, 0x43, 0x89, 0x1A, 0x93, 0xFB, 0xF1, 0xF1, 0x08, 0x44, + 0x01, 0x9A, 0x03, 0x9B, 0xC0, 0xF1, 0x10, 0x01, 0x42, 0x43, 0x03, 0xFB, + 0x01, 0x22, 0x12, 0x11, 0x03, 0x92, 0x00, 0x9A, 0x42, 0x43, 0x02, 0x98, + 0x00, 0xFB, 0x01, 0x20, 0x00, 0x11, 0x02, 0x90, 0x01, 0x98, 0xE0, 0x81, + 0x00, 0x98, 0xA0, 0x81, 0x03, 0x98, 0x60, 0x82, 0x02, 0x98, 0x20, 0x82, + 0x94, 0xF8, 0x24, 0x00, 0xC0, 0x06, 0x01, 0xD4, 0xE0, 0x68, 0x60, 0x61, + 0xBD, 0xE8, 0xFF, 0x87, 0x2D, 0xE9, 0xF0, 0x47, 0x05, 0x46, 0x90, 0xF8, + 0x02, 0x80, 0x0F, 0x46, 0x88, 0x68, 0x14, 0x46, 0x01, 0x26, 0x41, 0x46, + 0x09, 0xF0, 0x42, 0xFF, 0x81, 0x46, 0xA8, 0xF1, 0x01, 0x00, 0xC1, 0xB2, + 0xB8, 0x68, 0x09, 0xF0, 0x3B, 0xFF, 0x29, 0x78, 0x09, 0xEB, 0x41, 0x02, + 0x32, 0xF9, 0x02, 0x2C, 0xA2, 0x42, 0x03, 0xDB, 0x30, 0xF9, 0x11, 0x10, + 0xA1, 0x42, 0x00, 0xDA, 0x00, 0x26, 0x69, 0x78, 0x09, 0xEB, 0x41, 0x02, + 0xB2, 0xF9, 0x02, 0x20, 0xA2, 0x42, 0x03, 0xDB, 0x30, 0xF9, 0x11, 0x00, + 0xA0, 0x42, 0x00, 0xDA, 0x00, 0x26, 0x95, 0xF8, 0x03, 0x80, 0xB8, 0x68, + 0x41, 0x46, 0x09, 0xF0, 0x1D, 0xFF, 0x81, 0x46, 0x08, 0xF1, 0x01, 0x00, + 0xC1, 0xB2, 0xB8, 0x68, 0x09, 0xF0, 0x16, 0xFF, 0x29, 0x78, 0x09, 0xEB, + 0x41, 0x02, 0x32, 0xF9, 0x02, 0x2C, 0xA2, 0x42, 0x03, 0xDB, 0x30, 0xF9, + 0x11, 0x10, 0xA1, 0x42, 0x00, 0xDA, 0x00, 0x26, 0x69, 0x78, 0x09, 0xEB, + 0x41, 0x02, 0xB2, 0xF9, 0x02, 0x20, 0xA2, 0x42, 0x03, 0xDB, 0x30, 0xF9, + 0x11, 0x00, 0xA0, 0x42, 0x00, 0xDA, 0x00, 0x26, 0x30, 0x46, 0xBD, 0xE8, + 0xF0, 0x87, 0x2D, 0xE9, 0xFF, 0x4F, 0x97, 0xB0, 0x99, 0x46, 0x92, 0x46, + 0xFE, 0x48, 0xDF, 0xF8, 0xFC, 0x83, 0x01, 0x22, 0x04, 0x68, 0x51, 0x46, + 0xD8, 0xF8, 0x00, 0x00, 0x01, 0xF0, 0x6E, 0xFA, 0xFB, 0x48, 0x00, 0x68, + 0xB0, 0xF9, 0x4B, 0x14, 0x11, 0x91, 0x90, 0xF8, 0x4A, 0x04, 0x0A, 0x90, + 0xF8, 0x48, 0x9A, 0xF8, 0x02, 0x70, 0x9A, 0xF8, 0x03, 0x60, 0x00, 0x78, + 0x9A, 0xF8, 0x00, 0xB0, 0x9A, 0xF8, 0x01, 0x50, 0x40, 0x1E, 0x87, 0x42, + 0x01, 0xDA, 0x7F, 0x1C, 0xFF, 0xB2, 0x0E, 0xB1, 0x76, 0x1E, 0xF6, 0xB2, + 0xF0, 0x49, 0x09, 0x78, 0x49, 0x1E, 0x8B, 0x45, 0x03, 0xDA, 0x0B, 0xF1, + 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x0B, 0x0D, 0xB1, 0x6D, 0x1E, 0xED, 0xB2, + 0xB8, 0x1E, 0xC1, 0xB2, 0xD9, 0xF8, 0x08, 0x00, 0x09, 0xF0, 0xC0, 0xFE, + 0x0B, 0x90, 0x78, 0x1E, 0xC1, 0xB2, 0xD9, 0xF8, 0x08, 0x00, 0x09, 0xF0, + 0xB9, 0xFE, 0x04, 0x90, 0x39, 0x46, 0xD9, 0xF8, 0x08, 0x00, 0x09, 0xF0, + 0xB3, 0xFE, 0x01, 0x90, 0x78, 0x1C, 0xC1, 0xB2, 0xD9, 0xF8, 0x08, 0x00, + 0x09, 0xF0, 0xAC, 0xFE, 0x02, 0x90, 0xB8, 0x1C, 0xC1, 0xB2, 0xD9, 0xF8, + 0x08, 0x00, 0x09, 0xF0, 0xA5, 0xFE, 0x03, 0x90, 0x39, 0x46, 0x17, 0x98, + 0x09, 0xF0, 0x9A, 0xFE, 0x08, 0x90, 0xD4, 0x48, 0x39, 0x46, 0x00, 0x68, + 0x09, 0xF0, 0xA2, 0xFE, 0x86, 0x46, 0x00, 0x20, 0x7A, 0xB2, 0xD4, 0x4F, + 0x0C, 0x90, 0xB7, 0xE0, 0x4F, 0xFA, 0x8B, 0xF0, 0x94, 0xE0, 0x00, 0x21, + 0x0E, 0xF8, 0x00, 0x10, 0x08, 0x99, 0x18, 0x9B, 0x09, 0x5C, 0x99, 0x42, + 0x75, 0xD1, 0xDF, 0xF8, 0x28, 0xC3, 0x01, 0x9B, 0xDC, 0xF8, 0x00, 0xC0, + 0x33, 0xF9, 0x10, 0x30, 0xBC, 0xF8, 0x4D, 0xC4, 0x63, 0x45, 0x6A, 0xDA, + 0x00, 0x21, 0x14, 0x91, 0x13, 0x91, 0x11, 0x99, 0x19, 0x44, 0x04, 0x9B, + 0x09, 0xB2, 0x33, 0xF9, 0x10, 0x30, 0x10, 0x93, 0x8B, 0x42, 0x06, 0xDD, + 0x02, 0x9B, 0x33, 0xF9, 0x10, 0x30, 0x8B, 0x42, 0x01, 0xDD, 0x01, 0x23, + 0x13, 0x93, 0x01, 0x9B, 0x03, 0xEB, 0x40, 0x03, 0x33, 0xF9, 0x02, 0x8C, + 0x88, 0x45, 0x07, 0xDD, 0xB3, 0xF9, 0x02, 0xC0, 0x8C, 0x45, 0x03, 0xDD, + 0x4F, 0xF0, 0x01, 0x0C, 0xCD, 0xF8, 0x50, 0xC0, 0x01, 0x2A, 0x0F, 0xDD, + 0xDD, 0xF8, 0x2C, 0xC0, 0x3C, 0xF9, 0x10, 0xC0, 0x8C, 0x45, 0x09, 0xDD, + 0xDD, 0xF8, 0x08, 0xC0, 0x3C, 0xF9, 0x10, 0xC0, 0x8C, 0x45, 0x03, 0xDD, + 0x4F, 0xF0, 0x01, 0x0C, 0xCD, 0xF8, 0x4C, 0xC0, 0xDF, 0xF8, 0xAC, 0xC2, + 0x9C, 0xF8, 0x00, 0xC0, 0xAC, 0xF1, 0x02, 0x0C, 0x62, 0x45, 0x0D, 0xDA, + 0xDD, 0xF8, 0x40, 0xC0, 0x8C, 0x45, 0x09, 0xDD, 0xDD, 0xF8, 0x0C, 0xC0, + 0x3C, 0xF9, 0x10, 0xC0, 0x8C, 0x45, 0x03, 0xDD, 0x4F, 0xF0, 0x01, 0x0C, + 0xCD, 0xF8, 0x4C, 0xC0, 0x01, 0x28, 0x0B, 0xDD, 0x33, 0xF9, 0x04, 0xCC, + 0x8C, 0x45, 0x07, 0xDD, 0xB3, 0xF9, 0x02, 0xC0, 0x8C, 0x45, 0x03, 0xDD, + 0x4F, 0xF0, 0x01, 0x0C, 0xCD, 0xF8, 0x50, 0xC0, 0xDF, 0xF8, 0x68, 0xC2, + 0x9C, 0xF8, 0x00, 0xC0, 0xAC, 0xF1, 0x02, 0x0C, 0x60, 0x45, 0x05, 0xDA, + 0x88, 0x45, 0x03, 0xDD, 0xB3, 0xF9, 0x04, 0x30, 0x8B, 0x42, 0x12, 0xDC, + 0x14, 0x99, 0x81, 0xB9, 0x13, 0x99, 0x0D, 0xE0, 0xFF, 0xE7, 0x99, 0xB9, + 0x01, 0x99, 0xB7, 0xF9, 0x00, 0x30, 0x31, 0xF9, 0x10, 0x10, 0x99, 0x42, + 0x0C, 0xDA, 0x8B, 0x49, 0x09, 0x68, 0x91, 0xF8, 0x41, 0x14, 0xC9, 0x07, + 0x31, 0xB1, 0x01, 0x21, 0x0E, 0xF8, 0x00, 0x10, 0x0C, 0x99, 0x49, 0x1C, + 0x89, 0xB2, 0x0C, 0x91, 0x40, 0x1C, 0x40, 0xB2, 0xA8, 0x42, 0x7F, 0xF7, + 0x68, 0xAF, 0x84, 0x48, 0x0B, 0x99, 0x0E, 0xF1, 0x28, 0x0E, 0x00, 0x78, + 0x01, 0xEB, 0x40, 0x01, 0x0B, 0x91, 0x04, 0x99, 0x01, 0xEB, 0x40, 0x01, + 0x04, 0x91, 0x01, 0x99, 0x01, 0xEB, 0x40, 0x01, 0x01, 0x91, 0x02, 0x99, + 0x01, 0xEB, 0x40, 0x01, 0x02, 0x91, 0x03, 0x99, 0x01, 0xEB, 0x40, 0x00, + 0x03, 0x90, 0x08, 0x98, 0x28, 0x30, 0x52, 0x1C, 0x52, 0xB2, 0x08, 0x90, + 0xB2, 0x42, 0x7F, 0xF7, 0x45, 0xAF, 0x0A, 0x99, 0x0C, 0x98, 0x88, 0x42, + 0x2A, 0xD9, 0x00, 0x20, 0x84, 0xF8, 0x0E, 0x01, 0xDA, 0xF8, 0x00, 0x00, + 0x20, 0x60, 0x6C, 0x48, 0x00, 0x23, 0x1A, 0x46, 0x21, 0x46, 0x00, 0x68, + 0x01, 0xF0, 0x22, 0xFA, 0x01, 0x25, 0x17, 0xE0, 0x04, 0xEB, 0x85, 0x00, + 0x06, 0x46, 0x51, 0x46, 0x00, 0xF0, 0x53, 0xF9, 0x70, 0xB1, 0x04, 0xEB, + 0x45, 0x00, 0xB0, 0xF8, 0xB4, 0x10, 0x0A, 0x98, 0x81, 0x42, 0x07, 0xD9, + 0x30, 0x46, 0xB7, 0xF9, 0x00, 0x20, 0x49, 0x46, 0xFF, 0xF7, 0x64, 0xFE, + 0x01, 0x28, 0x06, 0xD0, 0x6D, 0x1C, 0xED, 0xB2, 0x94, 0xF8, 0x0E, 0x01, + 0xA8, 0x42, 0xE3, 0xD2, 0x00, 0x20, 0x1B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, + 0x2D, 0xE9, 0xF8, 0x4F, 0x04, 0x46, 0x55, 0x48, 0xDF, 0xF8, 0x54, 0x81, + 0x91, 0x46, 0x8B, 0x46, 0x05, 0x68, 0x01, 0x22, 0x21, 0x46, 0xD8, 0xF8, + 0x00, 0x00, 0x01, 0xF0, 0x19, 0xF9, 0x00, 0x27, 0xA6, 0x78, 0x4F, 0xF0, + 0x01, 0x0A, 0x1D, 0xE0, 0x31, 0x46, 0xD8, 0xF8, 0x00, 0x00, 0x09, 0xF0, + 0x95, 0xFD, 0x00, 0x90, 0x31, 0x46, 0xDB, 0xF8, 0x08, 0x00, 0x09, 0xF0, + 0x87, 0xFD, 0x01, 0x46, 0x20, 0x78, 0x52, 0x46, 0x09, 0xE0, 0x00, 0xBF, + 0x31, 0xF9, 0x10, 0xC0, 0xCC, 0x45, 0x02, 0xDA, 0x00, 0x9B, 0x01, 0x27, + 0x1A, 0x54, 0x40, 0x1C, 0xC0, 0xB2, 0x63, 0x78, 0x83, 0x42, 0xF3, 0xD2, + 0x76, 0x1C, 0xF6, 0xB2, 0xE0, 0x78, 0xB0, 0x42, 0xDE, 0xD2, 0x01, 0x2F, + 0x2E, 0xD1, 0x00, 0x20, 0x85, 0xF8, 0x0E, 0x01, 0x20, 0x68, 0x28, 0x60, + 0x00, 0x23, 0x1A, 0x46, 0x29, 0x46, 0xD8, 0xF8, 0x00, 0x00, 0x01, 0xF0, + 0xBD, 0xF9, 0x01, 0x26, 0xDF, 0xF8, 0xD8, 0x80, 0x1A, 0xE0, 0x00, 0xBF, + 0x05, 0xEB, 0x86, 0x07, 0x21, 0x46, 0x38, 0x46, 0x00, 0xF0, 0xEB, 0xF8, + 0x80, 0xB1, 0x05, 0xEB, 0x46, 0x00, 0xB0, 0xF8, 0xB4, 0x10, 0xD8, 0xF8, + 0x00, 0x00, 0x90, 0xF8, 0x4A, 0x04, 0x81, 0x42, 0x06, 0xD9, 0x38, 0x46, + 0x4A, 0x46, 0x59, 0x46, 0xFF, 0xF7, 0xFA, 0xFD, 0x01, 0x28, 0x06, 0xD0, + 0x76, 0x1C, 0xF6, 0xB2, 0x95, 0xF8, 0x0E, 0x01, 0xB0, 0x42, 0xE1, 0xD2, + 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x8F, 0x2D, 0xE9, 0xF0, 0x41, 0x23, 0x4D, + 0x0F, 0x46, 0x80, 0x46, 0x29, 0x68, 0x14, 0x46, 0x24, 0x48, 0x1E, 0x46, + 0x9A, 0x69, 0xB1, 0xF8, 0x47, 0x34, 0x00, 0x78, 0x9A, 0x42, 0x10, 0xDC, + 0xF2, 0x8C, 0x04, 0x2A, 0x0D, 0xD9, 0x62, 0x78, 0x23, 0x78, 0x91, 0xF8, + 0x49, 0x14, 0xD2, 0x1A, 0x52, 0x1C, 0x8A, 0x42, 0x05, 0xDC, 0xE2, 0x78, + 0xA3, 0x78, 0xD2, 0x1A, 0x52, 0x1C, 0x8A, 0x42, 0x02, 0xDD, 0x00, 0x20, + 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x28, 0xFB, 0xD1, 0x14, 0x48, 0x31, 0x46, + 0xB0, 0xF9, 0x00, 0x20, 0x20, 0x46, 0xFF, 0xF7, 0x6B, 0xFF, 0x00, 0x28, + 0xF2, 0xD1, 0x29, 0x68, 0x91, 0xF8, 0x40, 0x24, 0x92, 0x07, 0xED, 0xD5, + 0x91, 0xF8, 0xE0, 0x22, 0x52, 0x06, 0x09, 0xD5, 0x0D, 0x4A, 0x52, 0x78, + 0x02, 0xB3, 0xB1, 0xF8, 0xF0, 0x12, 0x0C, 0x4A, 0x49, 0x43, 0x12, 0x68, + 0x8A, 0x42, 0xDF, 0xDC, 0x33, 0x46, 0x22, 0x46, 0x39, 0x46, 0x11, 0xE0, + 0x6C, 0x06, 0x10, 0x00, 0x54, 0x06, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0xED, 0x06, 0x10, 0x00, 0xEE, 0x06, 0x10, 0x00, 0xA8, 0x06, 0x10, 0x00, + 0x34, 0x06, 0x10, 0x00, 0x74, 0x07, 0x10, 0x00, 0x24, 0x07, 0x10, 0x00, + 0x40, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0xE6, 0xE5, 0xB1, 0xF8, 0xEE, 0x12, + 0xDD, 0xE7, 0x2D, 0xE9, 0xFF, 0x4F, 0x81, 0xB0, 0xDF, 0xF8, 0x04, 0xB1, + 0xDD, 0xF8, 0x38, 0x90, 0x5F, 0xEA, 0x03, 0x08, 0x15, 0x46, 0x1C, 0xD4, + 0x2C, 0x78, 0x0B, 0xEB, 0xC8, 0x0A, 0x15, 0xE0, 0x08, 0xF0, 0xFF, 0x01, + 0x01, 0x98, 0x09, 0xF0, 0xD3, 0xFC, 0x00, 0x90, 0xDA, 0xE9, 0x00, 0x67, + 0x22, 0x46, 0x01, 0x20, 0x00, 0x21, 0x09, 0xF0, 0x03, 0xFB, 0x06, 0x40, + 0x0F, 0x40, 0x3E, 0x43, 0x02, 0xD1, 0x00, 0x98, 0x00, 0x21, 0x01, 0x55, + 0x64, 0x1C, 0xE4, 0xB2, 0x68, 0x78, 0xA0, 0x42, 0xE6, 0xD2, 0xB9, 0xF1, + 0x00, 0x00, 0x1E, 0xDB, 0x02, 0x46, 0xAC, 0x78, 0x01, 0x20, 0x00, 0x21, + 0x09, 0xF0, 0xEE, 0xFA, 0x06, 0x46, 0x0F, 0x46, 0x4F, 0xF0, 0x00, 0x08, + 0x10, 0xE0, 0x21, 0x46, 0x01, 0x98, 0x09, 0xF0, 0xAD, 0xFC, 0x0B, 0xEB, + 0xC4, 0x01, 0x02, 0x46, 0xD1, 0xE9, 0x00, 0x01, 0x30, 0x40, 0x39, 0x40, + 0x08, 0x43, 0x01, 0xD1, 0x02, 0xF8, 0x09, 0x80, 0x64, 0x1C, 0xE4, 0xB2, + 0xE8, 0x78, 0xA0, 0x42, 0xEB, 0xD2, 0x05, 0xB0, 0xEA, 0xE6, 0x70, 0xB5, + 0x1E, 0x4B, 0x1D, 0x4A, 0x8C, 0x69, 0x1B, 0x68, 0x12, 0x78, 0xB3, 0xF8, + 0x47, 0x54, 0xAC, 0x42, 0x10, 0xDC, 0xCC, 0x8C, 0x04, 0x2C, 0x0D, 0xD9, + 0x44, 0x78, 0x05, 0x78, 0x93, 0xF8, 0x49, 0x34, 0x64, 0x1B, 0x64, 0x1C, + 0x9C, 0x42, 0x05, 0xDC, 0xC4, 0x78, 0x85, 0x78, 0x64, 0x1B, 0x64, 0x1C, + 0x9C, 0x42, 0x01, 0xDD, 0x00, 0x22, 0x06, 0xE0, 0x2A, 0xB9, 0x11, 0x4A, + 0xB2, 0xF9, 0x00, 0x20, 0xFF, 0xF7, 0xCA, 0xFE, 0x02, 0x46, 0x10, 0x46, + 0x70, 0xBD, 0x02, 0x78, 0x0B, 0x78, 0x9A, 0x42, 0x0B, 0xD9, 0x42, 0x78, + 0x4B, 0x78, 0x9A, 0x42, 0x07, 0xD2, 0x82, 0x78, 0x8B, 0x78, 0x9A, 0x42, + 0x03, 0xD9, 0xC0, 0x78, 0xC9, 0x78, 0x88, 0x42, 0x01, 0xD3, 0x00, 0x20, + 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x00, 0x00, 0x98, 0x46, 0x10, 0x00, + 0x34, 0x06, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x92, 0x06, 0x10, 0x00, + 0x70, 0xB5, 0xFE, 0x4C, 0x00, 0xEB, 0x43, 0x05, 0x04, 0x9E, 0x00, 0xEB, + 0x83, 0x03, 0x86, 0xB1, 0x8E, 0x69, 0xA6, 0x60, 0xCE, 0x8C, 0x66, 0x80, + 0x09, 0x68, 0x61, 0x61, 0xB5, 0xF8, 0xB4, 0x10, 0xA1, 0x80, 0x19, 0x68, + 0xE1, 0x60, 0x90, 0xF8, 0x0E, 0x01, 0x20, 0x70, 0x10, 0x68, 0x20, 0x61, + 0x70, 0xBD, 0xA6, 0x68, 0x8E, 0x61, 0x66, 0x88, 0xCE, 0x84, 0x66, 0x69, + 0x0E, 0x60, 0xA1, 0x88, 0xA5, 0xF8, 0xB4, 0x10, 0xE1, 0x68, 0x19, 0x60, + 0x21, 0x78, 0x80, 0xF8, 0x0E, 0x11, 0x20, 0x69, 0x10, 0x60, 0x70, 0xBD, + 0x2D, 0xE9, 0xF0, 0x47, 0xE9, 0x4D, 0x81, 0x46, 0xE9, 0x4F, 0x28, 0x68, + 0x1C, 0x46, 0x16, 0x46, 0x90, 0xF8, 0x30, 0x02, 0x88, 0x46, 0x00, 0x07, + 0x07, 0xD5, 0x38, 0x78, 0x01, 0x28, 0x04, 0xD0, 0x48, 0x46, 0xF9, 0xF7, + 0xAF, 0xF8, 0x00, 0x28, 0x40, 0xD0, 0x28, 0x68, 0x90, 0xF8, 0x30, 0x02, + 0x00, 0x06, 0x0A, 0xD5, 0x38, 0x78, 0x01, 0x28, 0x07, 0xD0, 0xDE, 0x48, + 0x00, 0x78, 0x20, 0xB1, 0x30, 0x46, 0xF9, 0xF7, 0xF1, 0xF8, 0x00, 0x28, + 0x30, 0xD0, 0xDB, 0x4B, 0x32, 0x46, 0x41, 0x46, 0x48, 0x46, 0x00, 0xF0, + 0x34, 0xFF, 0x00, 0x28, 0x28, 0xD0, 0x94, 0xF8, 0x40, 0x00, 0x03, 0x28, + 0x08, 0xD1, 0x29, 0x68, 0xE0, 0x8C, 0x91, 0xF8, 0x07, 0x13, 0x88, 0x42, + 0x02, 0xD9, 0x04, 0x20, 0x84, 0xF8, 0x40, 0x00, 0x30, 0x68, 0xC4, 0xF8, + 0x36, 0x00, 0x04, 0xF1, 0x44, 0x02, 0x51, 0x1E, 0x30, 0x46, 0xF8, 0xF7, + 0xBE, 0xF9, 0x22, 0x46, 0x31, 0x46, 0xCB, 0x48, 0x00, 0xF0, 0x7A, 0xFD, + 0x31, 0x46, 0xC9, 0x48, 0x00, 0xF0, 0xAC, 0xFE, 0x22, 0x46, 0x31, 0x46, + 0xC6, 0x48, 0xFF, 0xF7, 0xE6, 0xFB, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, + 0xFE, 0xF7, 0xD7, 0xB9, 0xBD, 0xE8, 0xF0, 0x87, 0x2D, 0xE9, 0xF0, 0x41, + 0x0D, 0x46, 0x1F, 0x46, 0x16, 0x46, 0x04, 0x46, 0x48, 0x21, 0x09, 0xF0, + 0xDD, 0xFA, 0x00, 0x20, 0x84, 0xF8, 0x40, 0x00, 0xBC, 0x48, 0x00, 0x68, + 0x60, 0x60, 0xA0, 0x60, 0x06, 0xEB, 0x45, 0x00, 0x84, 0xF8, 0x42, 0x50, + 0x30, 0xF8, 0xB4, 0x1F, 0x61, 0x85, 0x00, 0x88, 0xE0, 0x84, 0x06, 0xEB, + 0x85, 0x00, 0x00, 0x68, 0xC4, 0xF8, 0x3A, 0x00, 0xAE, 0x48, 0x81, 0x69, + 0x21, 0x60, 0x01, 0x21, 0xA9, 0x40, 0x39, 0x42, 0x01, 0xD0, 0x40, 0x6A, + 0x20, 0x60, 0xBD, 0xE8, 0xF0, 0x81, 0x2D, 0xE9, 0xF0, 0x47, 0x89, 0x46, + 0x1C, 0x46, 0x16, 0x46, 0xAC, 0x4D, 0x03, 0xF1, 0x3E, 0x08, 0x91, 0x78, + 0x09, 0xF0, 0x94, 0xFB, 0x07, 0x46, 0xB1, 0x78, 0x60, 0x68, 0x09, 0xF0, + 0x95, 0xFB, 0x02, 0x46, 0x00, 0x20, 0xA0, 0x61, 0xB1, 0x78, 0x1F, 0xE0, + 0x30, 0x78, 0x13, 0xE0, 0x17, 0xF8, 0x00, 0xC0, 0xCC, 0x45, 0x0D, 0xD1, + 0x32, 0xF9, 0x10, 0x30, 0xD4, 0xF8, 0x18, 0xC0, 0xAB, 0x42, 0x9C, 0x44, + 0xC4, 0xF8, 0x18, 0xC0, 0x04, 0xDD, 0x88, 0xF8, 0x00, 0x00, 0x1D, 0x46, + 0x88, 0xF8, 0x01, 0x10, 0x40, 0x1C, 0xC0, 0xB2, 0x73, 0x78, 0x83, 0x42, + 0xE8, 0xD2, 0x99, 0x48, 0x49, 0x1C, 0xC9, 0xB2, 0x00, 0x78, 0x28, 0x37, + 0x02, 0xEB, 0x40, 0x02, 0xF0, 0x78, 0x88, 0x42, 0xDC, 0xD2, 0x65, 0x86, + 0x9A, 0xE7, 0x2D, 0xE9, 0xFF, 0x4F, 0x81, 0xB0, 0x0C, 0x46, 0x1E, 0x46, + 0x99, 0x78, 0xDD, 0xF8, 0x40, 0x80, 0x0E, 0x9D, 0x09, 0xF0, 0x68, 0xFB, + 0x00, 0x90, 0xB1, 0x78, 0x20, 0x46, 0x09, 0xF0, 0x55, 0xFB, 0x83, 0x46, + 0xB1, 0x78, 0xD8, 0xF8, 0x04, 0x00, 0x09, 0xF0, 0x55, 0xFB, 0x81, 0x46, + 0x88, 0x48, 0x4F, 0xF0, 0x00, 0x0A, 0xC8, 0xF8, 0x18, 0xA0, 0x00, 0x68, + 0x28, 0x60, 0xB7, 0x78, 0x42, 0xE0, 0x34, 0x78, 0x32, 0xE0, 0x00, 0xBF, + 0x1B, 0xF8, 0x04, 0x10, 0x03, 0x98, 0x81, 0x42, 0x2A, 0xD1, 0x39, 0xF9, + 0x14, 0x10, 0x0F, 0x98, 0x81, 0x42, 0x22, 0xDD, 0x00, 0x99, 0x03, 0x98, + 0x08, 0x55, 0x29, 0x78, 0x20, 0x46, 0x05, 0xF0, 0x35, 0xFA, 0x28, 0x70, + 0x69, 0x78, 0x20, 0x46, 0x05, 0xF0, 0x34, 0xFA, 0x68, 0x70, 0xA9, 0x78, + 0x38, 0x46, 0x05, 0xF0, 0x2B, 0xFA, 0xA8, 0x70, 0xE9, 0x78, 0x38, 0x46, + 0x05, 0xF0, 0x2A, 0xFA, 0xE8, 0x70, 0x0A, 0xF1, 0x01, 0x00, 0x1F, 0xFA, + 0x80, 0xFA, 0x39, 0xF9, 0x14, 0x00, 0xD8, 0xF8, 0x18, 0x10, 0x01, 0x44, + 0xC8, 0xF8, 0x18, 0x10, 0x02, 0xE0, 0x00, 0x99, 0x00, 0x20, 0x08, 0x55, + 0x64, 0x1C, 0xE4, 0xB2, 0x70, 0x78, 0xA0, 0x42, 0xCA, 0xD2, 0x00, 0x98, + 0x66, 0x49, 0x28, 0x30, 0x00, 0x90, 0x09, 0x78, 0x7F, 0x1C, 0x0B, 0xF1, + 0x28, 0x0B, 0x09, 0xEB, 0x41, 0x09, 0xFF, 0xB2, 0xF0, 0x78, 0xB8, 0x42, + 0xB9, 0xD2, 0xA8, 0xF8, 0x26, 0xA0, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, + 0x2D, 0xE9, 0xFF, 0x41, 0x17, 0x46, 0x0A, 0xAA, 0x80, 0x46, 0x92, 0xE8, + 0x31, 0x00, 0x5C, 0x4A, 0x1E, 0x46, 0xB2, 0xF9, 0x00, 0x20, 0x82, 0x42, + 0x02, 0xDB, 0x00, 0x20, 0x04, 0xB0, 0x48, 0xE7, 0x03, 0xAA, 0xCD, 0xE9, + 0x00, 0x20, 0x02, 0x94, 0x3A, 0x46, 0x40, 0x46, 0xFF, 0xF7, 0x7D, 0xFF, + 0x01, 0x21, 0x28, 0x68, 0xB9, 0x40, 0x08, 0x43, 0x28, 0x60, 0xC4, 0xF8, + 0x00, 0x80, 0xE0, 0x8C, 0x10, 0xB1, 0x03, 0x98, 0x30, 0x60, 0xE8, 0xE7, + 0x01, 0x20, 0xE7, 0xE7, 0x2D, 0xE9, 0xFF, 0x4F, 0x81, 0xB0, 0x90, 0x46, + 0x0E, 0x9C, 0x8B, 0x46, 0x04, 0xEB, 0x88, 0x00, 0x94, 0xF8, 0x0E, 0x71, + 0xDD, 0xF8, 0x40, 0xA0, 0x00, 0x68, 0x1E, 0x46, 0x20, 0x60, 0x01, 0x23, + 0x21, 0x46, 0x58, 0x46, 0x00, 0xF0, 0x20, 0xFF, 0x01, 0x98, 0x58, 0x45, + 0x1F, 0xD0, 0xB5, 0x78, 0x1A, 0xE0, 0x29, 0x46, 0x01, 0x98, 0x09, 0xF0, + 0xC5, 0xFA, 0x81, 0x46, 0x29, 0x46, 0x58, 0x46, 0x09, 0xF0, 0xC0, 0xFA, + 0x01, 0x46, 0x30, 0x78, 0x09, 0xE0, 0x00, 0xBF, 0x19, 0xF8, 0x00, 0x30, + 0x43, 0x45, 0x02, 0xD1, 0x0B, 0x5C, 0x09, 0xF8, 0x00, 0x30, 0x40, 0x1C, + 0xC0, 0xB2, 0x72, 0x78, 0x82, 0x42, 0xF3, 0xD2, 0x6D, 0x1C, 0xED, 0xB2, + 0xF0, 0x78, 0xA8, 0x42, 0xE1, 0xD2, 0x94, 0xF8, 0x0E, 0x01, 0x00, 0x25, + 0x01, 0x21, 0xB8, 0x42, 0x12, 0xD0, 0x11, 0x98, 0x78, 0xB1, 0x7F, 0x1C, + 0xF8, 0xB2, 0x08, 0xE0, 0xDA, 0xF8, 0x00, 0x20, 0x01, 0xFA, 0x00, 0xF3, + 0x1A, 0x43, 0x40, 0x1C, 0xC0, 0xB2, 0xCA, 0xF8, 0x00, 0x20, 0x94, 0xF8, + 0x0E, 0x21, 0x82, 0x42, 0xF2, 0xD2, 0x01, 0x25, 0x00, 0x91, 0x43, 0x46, + 0x52, 0x46, 0x20, 0x46, 0x0F, 0x99, 0xFF, 0xF7, 0x33, 0xFE, 0x28, 0x46, + 0x7D, 0xE7, 0x10, 0xB5, 0x17, 0x4A, 0x20, 0x4C, 0x13, 0x68, 0x64, 0x78, + 0x93, 0xF8, 0x06, 0x23, 0x4C, 0xB1, 0x91, 0xF8, 0x24, 0x10, 0x09, 0x07, + 0x02, 0xD5, 0x93, 0xF8, 0x09, 0x13, 0x01, 0xE0, 0x93, 0xF8, 0x08, 0x13, + 0x0A, 0x44, 0x90, 0x42, 0x01, 0xD9, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x20, + 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x47, 0x1C, 0x46, 0x17, 0x46, 0x88, 0x46, + 0x81, 0x46, 0x01, 0xF0, 0xED, 0xF8, 0x08, 0x4E, 0xE1, 0x8C, 0x30, 0x68, + 0x90, 0xF8, 0x0E, 0x23, 0x91, 0x42, 0x7C, 0xD8, 0x03, 0x21, 0x84, 0xF8, + 0x40, 0x10, 0x90, 0xF8, 0xE0, 0x12, 0x00, 0x25, 0x8A, 0x07, 0x15, 0xE0, + 0x38, 0x06, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x66, 0x05, 0x10, 0x00, + 0xF4, 0x06, 0x10, 0x00, 0xF0, 0x45, 0x10, 0x00, 0x10, 0x07, 0x10, 0x00, + 0x00, 0x80, 0xFF, 0xFF, 0xEE, 0x06, 0x10, 0x00, 0x36, 0x7A, 0x01, 0x00, + 0x9A, 0x06, 0x10, 0x00, 0x74, 0x07, 0x10, 0x00, 0x01, 0xD4, 0x49, 0x07, + 0x00, 0xD5, 0x01, 0x25, 0xFF, 0x4A, 0xB0, 0xF8, 0x0A, 0x13, 0x52, 0x78, + 0x22, 0xB1, 0xFE, 0x4A, 0x12, 0x78, 0x0A, 0xB9, 0xB0, 0xF8, 0x0C, 0x13, + 0xA2, 0x8D, 0x8A, 0x42, 0x02, 0xD2, 0xFB, 0x49, 0x09, 0x78, 0x21, 0xB1, + 0x61, 0x8D, 0x03, 0x29, 0x06, 0xD2, 0x00, 0x25, 0x2C, 0xE0, 0x61, 0x8D, + 0x00, 0x25, 0x03, 0x29, 0xF9, 0xD3, 0x27, 0xE0, 0x35, 0xB3, 0x90, 0xF8, + 0x40, 0x04, 0xC1, 0x07, 0x0D, 0xD0, 0x40, 0x07, 0x0B, 0xD5, 0x21, 0x46, + 0x38, 0x46, 0xFF, 0xF7, 0x80, 0xFD, 0xF0, 0x49, 0x08, 0x70, 0x20, 0xB1, + 0xA0, 0x8C, 0x40, 0xF0, 0x80, 0x00, 0xA0, 0x84, 0xE5, 0xE7, 0x30, 0x68, + 0x90, 0xF8, 0x20, 0x04, 0xC0, 0x07, 0x0F, 0xD0, 0xEA, 0x48, 0xEB, 0x49, + 0xB0, 0xF9, 0x00, 0x00, 0xB1, 0xF9, 0x00, 0x10, 0x88, 0x42, 0x07, 0xDB, + 0x23, 0x46, 0x3A, 0x46, 0x41, 0x46, 0x48, 0x46, 0x02, 0xF0, 0x4D, 0xF9, + 0x01, 0x28, 0x04, 0xD0, 0xA0, 0x8C, 0x10, 0xF4, 0xC0, 0x7F, 0x19, 0xD1, + 0x04, 0xE0, 0xA0, 0x8C, 0x40, 0xF4, 0x80, 0x70, 0xA0, 0x84, 0x13, 0xE0, + 0x95, 0xB1, 0x30, 0x68, 0x90, 0xF8, 0xE0, 0x02, 0xC0, 0x07, 0x03, 0xD0, + 0x21, 0x46, 0x38, 0x46, 0x01, 0xF0, 0x3B, 0xFA, 0x23, 0x46, 0x3A, 0x46, + 0x41, 0x46, 0x48, 0x46, 0x00, 0xE0, 0x0A, 0xE0, 0xBD, 0xE8, 0xF0, 0x47, + 0x01, 0xF0, 0xFD, 0xBF, 0x23, 0x46, 0x3A, 0x46, 0x41, 0x46, 0x48, 0x46, + 0xBD, 0xE8, 0xF0, 0x47, 0xAA, 0xE5, 0x04, 0x20, 0x84, 0xF8, 0x40, 0x00, + 0xF4, 0xE7, 0xD0, 0x48, 0x00, 0x78, 0x80, 0x07, 0x0B, 0xD5, 0xCF, 0x48, + 0xCF, 0x4A, 0x00, 0x68, 0x12, 0x68, 0x90, 0xF8, 0x57, 0x13, 0x91, 0x42, + 0x05, 0xD2, 0x90, 0xF8, 0x40, 0x03, 0x80, 0x07, 0x01, 0xD5, 0x00, 0x20, + 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x91, 0xF8, 0x24, 0x10, 0xC6, 0x4A, + 0xCB, 0x07, 0xC7, 0x49, 0x12, 0x68, 0x09, 0x78, 0x06, 0xD0, 0x11, 0xB1, + 0x92, 0xF8, 0x48, 0x13, 0x05, 0xE0, 0x92, 0xF8, 0x49, 0x13, 0x02, 0xE0, + 0x59, 0xB1, 0x92, 0xF8, 0x46, 0x13, 0xB7, 0x4B, 0x5B, 0x78, 0x13, 0xB1, + 0x92, 0xF8, 0x4A, 0x23, 0x11, 0x44, 0x88, 0x42, 0x04, 0xD9, 0x01, 0x20, + 0x70, 0x47, 0x92, 0xF8, 0x47, 0x13, 0xF2, 0xE7, 0x00, 0x20, 0x70, 0x47, + 0x2D, 0xE9, 0xFF, 0x4F, 0xB8, 0x48, 0xDF, 0xF8, 0xD4, 0x92, 0x87, 0xB0, + 0xB0, 0xF9, 0x00, 0x80, 0xD9, 0xF8, 0x00, 0x00, 0x0C, 0x46, 0x00, 0x26, + 0x90, 0xF8, 0x40, 0x04, 0xDF, 0xF8, 0xCC, 0xB2, 0xC1, 0x07, 0x14, 0x98, + 0x4F, 0xF0, 0x01, 0x07, 0x15, 0x46, 0x07, 0xFA, 0x00, 0xF7, 0xB2, 0x46, + 0x3A, 0xD0, 0xAF, 0x49, 0xA7, 0x4A, 0xB1, 0xF9, 0x00, 0x00, 0xB2, 0xF9, + 0x00, 0x20, 0x90, 0x42, 0x32, 0xDA, 0x2A, 0x68, 0x3A, 0x42, 0x2F, 0xD1, + 0xE2, 0x8C, 0x04, 0x2A, 0x2C, 0xD9, 0x8D, 0xE8, 0x31, 0x00, 0x0A, 0x9B, + 0x14, 0x9A, 0xDB, 0xF8, 0x18, 0x10, 0xDB, 0xF8, 0x24, 0x00, 0xFF, 0xF7, + 0x67, 0xFE, 0x06, 0x00, 0x20, 0xD1, 0x23, 0x46, 0x20, 0x68, 0x0A, 0x9A, + 0x14, 0x99, 0xFF, 0xF7, 0x22, 0xFC, 0x96, 0x49, 0x08, 0x70, 0xA0, 0xB1, + 0x70, 0x1E, 0x8D, 0xF8, 0x10, 0x00, 0x8D, 0xF8, 0x14, 0x00, 0xD9, 0xF8, + 0x00, 0x00, 0x90, 0xF8, 0x41, 0x04, 0x80, 0x07, 0x05, 0xD5, 0x05, 0xAA, + 0x04, 0xA9, 0x0A, 0x98, 0xF7, 0xF7, 0x93, 0xFF, 0xA8, 0xB3, 0xA0, 0x8C, + 0x40, 0xF0, 0x80, 0x00, 0xA0, 0x84, 0x93, 0x48, 0xB0, 0xF9, 0x00, 0x80, + 0xD9, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0x20, 0x04, 0xC0, 0x07, 0x53, 0xD0, + 0x94, 0xF8, 0x24, 0x00, 0x00, 0x06, 0x4F, 0xD4, 0x84, 0x48, 0x85, 0x4A, + 0xB0, 0xF9, 0x00, 0x10, 0xB2, 0xF9, 0x00, 0x20, 0x91, 0x42, 0x47, 0xDA, + 0x81, 0x46, 0x41, 0x45, 0x17, 0xD0, 0x28, 0x68, 0x38, 0x42, 0x07, 0xD0, + 0xCD, 0xF8, 0x00, 0xA0, 0x2A, 0x46, 0x21, 0x46, 0x14, 0x9B, 0x07, 0x98, + 0xFF, 0xF7, 0xD4, 0xFC, 0xB9, 0xF9, 0x00, 0x00, 0x8D, 0xE8, 0x31, 0x00, + 0x0A, 0x9B, 0x14, 0x9A, 0xDB, 0xF8, 0x18, 0x10, 0xDB, 0xF8, 0x24, 0x00, + 0xFF, 0xF7, 0x18, 0xFE, 0x06, 0x46, 0xFE, 0xB1, 0x2A, 0xE0, 0xFF, 0xE7, + 0x7A, 0x49, 0x9D, 0xF9, 0x10, 0x30, 0x01, 0xF8, 0x36, 0x3F, 0x9D, 0xF9, + 0x14, 0x00, 0x48, 0x70, 0x00, 0x90, 0x20, 0x68, 0x0A, 0x9A, 0x07, 0x99, + 0xFF, 0xF7, 0x27, 0xFC, 0x07, 0x98, 0x04, 0xF1, 0x3A, 0x03, 0x8D, 0xE8, + 0x31, 0x04, 0x21, 0x68, 0x14, 0x9A, 0xDB, 0xF8, 0x18, 0x00, 0xFF, 0xF7, + 0x21, 0xFE, 0x00, 0x28, 0xB1, 0xD0, 0x01, 0x20, 0x0B, 0xB0, 0xF3, 0xE5, + 0x23, 0x46, 0x20, 0x68, 0x0A, 0x9A, 0x14, 0x99, 0x02, 0xF0, 0x45, 0xF8, + 0x01, 0x28, 0x03, 0xD1, 0xA0, 0x8C, 0x40, 0xF4, 0x80, 0x70, 0xA0, 0x84, + 0xA0, 0x8C, 0x10, 0xF4, 0xC0, 0x7F, 0x0A, 0xD1, 0x28, 0x68, 0x38, 0x42, + 0x07, 0xD0, 0xCD, 0xF8, 0x00, 0xA0, 0x2A, 0x46, 0x21, 0x46, 0x14, 0x9B, + 0x07, 0x98, 0xFF, 0xF7, 0x8B, 0xFC, 0x30, 0x46, 0xE0, 0xE7, 0x2D, 0xE9, + 0xF0, 0x4F, 0x5D, 0x49, 0x53, 0x48, 0xE7, 0xB0, 0xB1, 0xF9, 0x00, 0x10, + 0xB0, 0xF9, 0x00, 0x00, 0x4F, 0xF0, 0x00, 0x08, 0xCD, 0xE9, 0x62, 0x01, + 0x54, 0x48, 0xC3, 0x46, 0xC1, 0x46, 0x47, 0x46, 0x01, 0x21, 0x1C, 0x30, + 0x02, 0xF0, 0x0D, 0xFC, 0x50, 0x48, 0x01, 0x21, 0x24, 0x30, 0x02, 0xF0, + 0x08, 0xFC, 0x4E, 0x48, 0x02, 0x21, 0x20, 0x30, 0x02, 0xF0, 0x03, 0xFC, + 0x02, 0x21, 0x4F, 0x48, 0x02, 0xF0, 0xA7, 0xFB, 0x04, 0x21, 0x4E, 0x48, + 0x02, 0xF0, 0xA3, 0xFB, 0x47, 0x4C, 0x4F, 0xF4, 0x66, 0x75, 0x29, 0x46, + 0xE0, 0x69, 0x08, 0xF0, 0xA1, 0xFF, 0x29, 0x46, 0x60, 0x6A, 0x08, 0xF0, + 0x9D, 0xFF, 0x48, 0x48, 0xB0, 0xF9, 0x00, 0x00, 0x41, 0x00, 0x20, 0x6A, + 0x08, 0xF0, 0x96, 0xFF, 0x29, 0x46, 0x45, 0x48, 0x08, 0xF0, 0x92, 0xFF, + 0x4F, 0xF0, 0x00, 0x0A, 0x55, 0x46, 0x84, 0xF8, 0x01, 0xA0, 0xF8, 0xF7, + 0xFB, 0xFC, 0xF7, 0xF7, 0x41, 0xFE, 0x40, 0x48, 0x8D, 0xF8, 0x72, 0x51, + 0x01, 0x23, 0x00, 0x68, 0x19, 0x90, 0x00, 0x22, 0x19, 0xA9, 0xA0, 0x69, + 0x00, 0xF0, 0xE2, 0xFC, 0x3B, 0x48, 0x5D, 0x95, 0x00, 0x26, 0xB0, 0xF9, + 0x00, 0x10, 0x2A, 0x48, 0xB0, 0xF9, 0x00, 0x00, 0x04, 0xF0, 0x7C, 0xFF, + 0x00, 0xB2, 0x06, 0x90, 0x9D, 0xF8, 0x72, 0x01, 0x01, 0x28, 0x02, 0xD9, + 0x22, 0x49, 0x81, 0xF8, 0x00, 0xA0, 0x0D, 0xF1, 0x56, 0x00, 0x01, 0x25, + 0x60, 0x90, 0x9B, 0xE1, 0x00, 0x20, 0x01, 0x90, 0x19, 0xA8, 0x00, 0xEB, + 0x85, 0x00, 0x05, 0x90, 0x19, 0xAA, 0x29, 0x46, 0x07, 0xA8, 0x5D, 0x9B, + 0xFF, 0xF7, 0x96, 0xFC, 0x07, 0xAB, 0x29, 0x46, 0x05, 0x9A, 0x07, 0x98, + 0xFF, 0xF7, 0xB9, 0xFC, 0x01, 0x24, 0x2B, 0x46, 0x5D, 0xAA, 0x07, 0xA9, + 0x19, 0xA8, 0x00, 0x94, 0xFF, 0xF7, 0x06, 0xFC, 0x0D, 0xF1, 0x5A, 0x00, + 0x00, 0xF0, 0xFE, 0xFA, 0x78, 0xB1, 0xBD, 0xF8, 0x40, 0x00, 0x40, 0xF0, + 0x01, 0x00, 0xAD, 0xF8, 0x40, 0x00, 0x07, 0xA8, 0x00, 0xF0, 0x41, 0xFC, + 0x28, 0xB1, 0x1C, 0x48, 0x14, 0x49, 0x00, 0x88, 0x08, 0x80, 0x0A, 0x49, + 0x08, 0x80, 0x06, 0x48, 0x00, 0x78, 0x88, 0xB3, 0xBD, 0xF8, 0x40, 0x00, + 0x10, 0xF0, 0x06, 0x0F, 0x30, 0xD1, 0x2C, 0xE0, 0x74, 0x07, 0x10, 0x00, + 0xFD, 0x06, 0x10, 0x00, 0xA4, 0x06, 0x10, 0x00, 0x34, 0x06, 0x10, 0x00, + 0xA6, 0x06, 0x10, 0x00, 0x92, 0x06, 0x10, 0x00, 0x04, 0x07, 0x10, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x80, 0x06, 0x10, 0x00, 0xF9, 0x06, 0x10, 0x00, + 0x9A, 0x06, 0x10, 0x00, 0x38, 0x06, 0x10, 0x00, 0xA8, 0x06, 0x10, 0x00, + 0x0A, 0x44, 0x01, 0x20, 0x94, 0x06, 0x10, 0x00, 0x60, 0x06, 0x10, 0x00, + 0x6C, 0x06, 0x10, 0x00, 0xFE, 0x06, 0x10, 0x00, 0xC2, 0x18, 0x01, 0x20, + 0x88, 0x06, 0x10, 0x00, 0xAC, 0x06, 0x10, 0x00, 0xA2, 0x06, 0x10, 0x00, + 0x02, 0xE0, 0xFE, 0x48, 0x00, 0x68, 0x08, 0x90, 0x05, 0x98, 0x00, 0xF0, + 0xC3, 0xFA, 0x28, 0xB1, 0xBD, 0xF8, 0x40, 0x00, 0x40, 0xF0, 0x08, 0x00, + 0xAD, 0xF8, 0x40, 0x00, 0x01, 0x24, 0x5D, 0x98, 0xAC, 0x40, 0x04, 0x42, + 0x41, 0xD1, 0xF6, 0x48, 0x00, 0x78, 0xC0, 0x07, 0x3D, 0xD0, 0xF5, 0x48, + 0x00, 0x68, 0x90, 0xF8, 0x28, 0x13, 0xF4, 0x48, 0x00, 0x68, 0x81, 0x42, + 0xF3, 0x48, 0x40, 0x78, 0x01, 0xD2, 0x90, 0xBB, 0x01, 0xE0, 0x02, 0x28, + 0x2F, 0xD2, 0xF1, 0x48, 0x5D, 0xAA, 0x07, 0xA9, 0xB0, 0xF9, 0x00, 0x00, + 0x8D, 0xE8, 0x07, 0x00, 0xEE, 0x48, 0x2A, 0x46, 0x05, 0x9B, 0x81, 0x69, + 0x40, 0x6A, 0xFF, 0xF7, 0xD9, 0xFC, 0x01, 0x90, 0xB8, 0xB9, 0x07, 0xAB, + 0x29, 0x46, 0x05, 0x9A, 0x07, 0x98, 0x00, 0xF0, 0xA6, 0xF9, 0x80, 0xB1, + 0x4F, 0xF0, 0x02, 0x0C, 0x8D, 0xF8, 0x5C, 0xC0, 0x29, 0x46, 0x07, 0xAB, + 0x05, 0x9A, 0x07, 0x98, 0xAD, 0xF8, 0x4A, 0xC0, 0xAD, 0xF8, 0x4C, 0xC0, + 0xFF, 0xF7, 0x9C, 0xFB, 0x4F, 0xF0, 0x01, 0x0B, 0xCF, 0xE0, 0x2B, 0x46, + 0x5D, 0xAA, 0x07, 0xA9, 0x19, 0xA8, 0xCD, 0xF8, 0x00, 0xA0, 0xFF, 0xF7, + 0x67, 0xFB, 0xBD, 0xF9, 0x4E, 0x00, 0x06, 0x99, 0x88, 0x42, 0x6A, 0xDD, + 0x00, 0x95, 0x5D, 0xAA, 0x07, 0xA9, 0x19, 0xA8, 0x05, 0x9B, 0xFF, 0xF7, + 0x13, 0xFE, 0x00, 0x28, 0x7E, 0xD1, 0x5D, 0x98, 0x04, 0x42, 0x3A, 0xD1, + 0xBD, 0xF8, 0x40, 0x00, 0x10, 0xF4, 0xC0, 0x7F, 0x35, 0xD1, 0xD0, 0x48, + 0x5D, 0xAA, 0x07, 0xA9, 0xB0, 0xF9, 0x00, 0x00, 0x8D, 0xE8, 0x07, 0x00, + 0xCB, 0x48, 0x2A, 0x46, 0x05, 0x9B, 0x81, 0x69, 0x40, 0x6A, 0xFF, 0xF7, + 0x93, 0xFC, 0x01, 0x90, 0x5D, 0x98, 0x04, 0x42, 0x23, 0xD0, 0xC2, 0x48, + 0xBD, 0xF8, 0x42, 0x20, 0x00, 0x68, 0x90, 0xF8, 0x0E, 0x33, 0x9A, 0x42, + 0x05, 0xD8, 0x90, 0xF8, 0xE0, 0x02, 0x82, 0x07, 0x17, 0xD4, 0x40, 0x07, + 0x15, 0xD4, 0x01, 0x23, 0x5D, 0xAA, 0x07, 0xA9, 0x19, 0xA8, 0x8D, 0xE8, + 0x0F, 0x00, 0xBC, 0x48, 0x2A, 0x46, 0x60, 0x9B, 0x41, 0x6A, 0x80, 0x69, + 0xFF, 0xF7, 0x9A, 0xFC, 0x01, 0x90, 0x01, 0x20, 0x00, 0x90, 0x2B, 0x46, + 0x5D, 0xAA, 0x07, 0xA9, 0x19, 0xA8, 0xFF, 0xF7, 0x1B, 0xFB, 0x01, 0x98, + 0xC8, 0xB9, 0xBD, 0xF8, 0x42, 0x00, 0x07, 0xA9, 0xFF, 0xF7, 0xE3, 0xFC, + 0x98, 0xB1, 0x07, 0xA8, 0x00, 0x90, 0xB1, 0x48, 0x29, 0x46, 0x60, 0x9A, + 0xB0, 0xF9, 0x00, 0x30, 0xAC, 0x48, 0x80, 0x69, 0x00, 0xF0, 0x84, 0xF9, + 0x07, 0xAB, 0x29, 0x46, 0x05, 0x9A, 0x07, 0x98, 0xFF, 0xF7, 0xE9, 0xFC, + 0x4F, 0xF0, 0x01, 0x08, 0x5F, 0xE0, 0x2B, 0x46, 0x5D, 0xAA, 0x07, 0xA9, + 0x19, 0xA8, 0xCD, 0xF8, 0x00, 0xA0, 0xFF, 0xF7, 0xF7, 0xFA, 0xA4, 0x48, + 0xBD, 0xF9, 0x4E, 0x10, 0xB0, 0xF9, 0x00, 0x00, 0x81, 0x42, 0x50, 0xDD, + 0xFF, 0xF7, 0x71, 0xFD, 0xF0, 0xB3, 0x5D, 0x98, 0x04, 0x42, 0x2F, 0xD1, + 0x9D, 0x48, 0x5D, 0xAA, 0x07, 0xA9, 0xB0, 0xF9, 0x00, 0x00, 0x8D, 0xE8, + 0x07, 0x00, 0x98, 0x48, 0x2A, 0x46, 0x05, 0x9B, 0x81, 0x69, 0x40, 0x6A, + 0xFF, 0xF7, 0x2C, 0xFC, 0x01, 0x90, 0x00, 0xE0, 0x52, 0xE0, 0x8F, 0x48, + 0x00, 0x68, 0x90, 0xF8, 0x40, 0x03, 0xC0, 0x06, 0x18, 0xD4, 0x5D, 0x98, + 0x04, 0x42, 0x15, 0xD0, 0x01, 0x23, 0x5D, 0xAA, 0x07, 0xA9, 0x19, 0xA8, + 0x8D, 0xE8, 0x0F, 0x00, 0x8B, 0x48, 0x2A, 0x46, 0x60, 0x9B, 0x41, 0x6A, + 0x80, 0x69, 0xFF, 0xF7, 0x39, 0xFC, 0x01, 0x90, 0x01, 0x20, 0x00, 0x90, + 0x2B, 0x46, 0x5D, 0xAA, 0x07, 0xA9, 0x19, 0xA8, 0xFF, 0xF7, 0xBA, 0xFA, + 0x01, 0x98, 0x80, 0xB9, 0xBD, 0xF8, 0x42, 0x00, 0x07, 0xA9, 0xFF, 0xF7, + 0x4A, 0xFD, 0x50, 0xB1, 0x07, 0xAB, 0x29, 0x46, 0x05, 0x9A, 0x00, 0xE0, + 0x0D, 0xE0, 0x07, 0x98, 0x00, 0xF0, 0x6F, 0xF9, 0x4F, 0xF0, 0x01, 0x09, + 0x07, 0xE0, 0x2B, 0x46, 0x5D, 0xAA, 0x07, 0xA9, 0x19, 0xA8, 0xCD, 0xF8, + 0x00, 0xA0, 0xFF, 0xF7, 0x9F, 0xFA, 0x5D, 0x99, 0x44, 0xEA, 0x01, 0x00, + 0x73, 0x49, 0x5D, 0x90, 0x63, 0x98, 0x08, 0x80, 0x73, 0x49, 0x62, 0x98, + 0x08, 0x80, 0x74, 0x48, 0x01, 0x78, 0x31, 0xB1, 0x9D, 0xF8, 0x72, 0x11, + 0x26, 0x43, 0x01, 0x29, 0x01, 0xD9, 0x80, 0xF8, 0x00, 0xA0, 0xBD, 0xF8, + 0x40, 0x00, 0xC0, 0x05, 0x00, 0xD5, 0x27, 0x43, 0x6D, 0x1C, 0xED, 0xB2, + 0x9D, 0xF8, 0x72, 0x01, 0xA8, 0x42, 0xBF, 0xF4, 0x5F, 0xAE, 0x66, 0x48, + 0x6A, 0x4A, 0x69, 0x4B, 0x41, 0x78, 0xA2, 0xF5, 0x66, 0x70, 0x01, 0xF0, + 0x7A, 0xFC, 0x68, 0x48, 0x9D, 0xF8, 0x72, 0x11, 0x00, 0xF8, 0x05, 0x1F, + 0x68, 0x49, 0x06, 0x83, 0x87, 0x83, 0x65, 0x48, 0x80, 0xF8, 0x00, 0xB0, + 0x64, 0x48, 0x80, 0xF8, 0x00, 0x80, 0x81, 0xF8, 0x00, 0x90, 0x02, 0x21, + 0x63, 0x48, 0x02, 0xF0, 0xC1, 0xF9, 0x04, 0x21, 0x62, 0x48, 0x02, 0xF0, + 0xBD, 0xF9, 0x56, 0x48, 0x01, 0x21, 0x18, 0x30, 0x02, 0xF0, 0x86, 0xFA, + 0x53, 0x48, 0x01, 0x21, 0x1C, 0x30, 0x02, 0xF0, 0x81, 0xFA, 0x51, 0x48, + 0x01, 0x21, 0x24, 0x30, 0x02, 0xF0, 0x7C, 0xFA, 0x4E, 0x48, 0x02, 0x21, + 0x20, 0x30, 0x02, 0xF0, 0x77, 0xFA, 0x67, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, + 0x51, 0x49, 0x00, 0x20, 0x08, 0x70, 0x51, 0x49, 0x08, 0x70, 0x51, 0x49, + 0x08, 0x70, 0x4A, 0x49, 0x08, 0x70, 0xA8, 0x21, 0x49, 0x48, 0x08, 0xF0, + 0xA3, 0xBD, 0x44, 0x49, 0x00, 0x20, 0x4D, 0x4A, 0x08, 0x62, 0x88, 0x61, + 0xC8, 0x61, 0x10, 0x60, 0x4B, 0x4A, 0x10, 0x60, 0x46, 0x4A, 0x10, 0x70, + 0x46, 0x4A, 0x10, 0x70, 0x46, 0x4A, 0x10, 0x70, 0x3F, 0x4A, 0x10, 0x70, + 0x48, 0x70, 0x70, 0x47, 0x3A, 0x49, 0x10, 0xB5, 0x00, 0x20, 0x48, 0x70, + 0x4F, 0xF4, 0x66, 0x71, 0x43, 0x48, 0x08, 0xF0, 0x65, 0xFD, 0x3A, 0x48, + 0xA8, 0x21, 0xA8, 0x38, 0x08, 0xF0, 0x82, 0xFD, 0xBD, 0xE8, 0x10, 0x40, + 0xA8, 0x21, 0x36, 0x48, 0x08, 0xF0, 0x7C, 0xBD, 0x2D, 0xE9, 0xF7, 0x4F, + 0x2F, 0x48, 0x0D, 0x46, 0x41, 0x78, 0x0F, 0x29, 0x01, 0xD2, 0x49, 0x1C, + 0x41, 0x70, 0x01, 0xF0, 0xFF, 0x09, 0x30, 0x49, 0x82, 0xF8, 0x41, 0x90, + 0x01, 0xEB, 0x89, 0x00, 0x29, 0x68, 0x01, 0x60, 0xA9, 0x78, 0x33, 0x48, + 0x08, 0xF0, 0x56, 0xFE, 0x82, 0x46, 0xA8, 0x78, 0x19, 0xE0, 0x00, 0x98, + 0x2C, 0x78, 0x00, 0xEB, 0xC8, 0x0B, 0x0D, 0xE0, 0xDB, 0xE9, 0x00, 0x67, + 0x22, 0x46, 0x01, 0x20, 0x00, 0x21, 0x08, 0xF0, 0x7F, 0xFC, 0x06, 0x40, + 0x0F, 0x40, 0x3E, 0x43, 0x01, 0xD0, 0x0A, 0xF8, 0x04, 0x90, 0x64, 0x1C, + 0x68, 0x78, 0xA0, 0x42, 0xEE, 0xDA, 0x0A, 0xF1, 0x28, 0x0A, 0x08, 0xF1, + 0x01, 0x00, 0xE9, 0x78, 0x80, 0x46, 0x41, 0x45, 0xE1, 0xDA, 0xBD, 0xE8, + 0xFE, 0x8F, 0x2D, 0xE9, 0xF0, 0x41, 0x0F, 0x4C, 0x10, 0x4F, 0xB3, 0xF8, + 0x26, 0xC0, 0x24, 0x68, 0x7F, 0x78, 0x00, 0x26, 0x94, 0xF8, 0x29, 0x53, + 0x17, 0xB1, 0x94, 0xF8, 0x2A, 0x73, 0x3D, 0x44, 0x93, 0xF8, 0x24, 0xE0, + 0x94, 0xF8, 0x2B, 0x73, 0x5F, 0xEA, 0xCE, 0x7E, 0x01, 0xD0, 0x94, 0xF8, + 0x2C, 0x73, 0xAC, 0x45, 0x39, 0xD9, 0xBC, 0x45, 0x37, 0xD8, 0x25, 0xE0, + 0x14, 0x07, 0x10, 0x00, 0x04, 0x07, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x7C, 0x06, 0x10, 0x00, 0x74, 0x07, 0x10, 0x00, 0x94, 0x06, 0x10, 0x00, + 0x38, 0x06, 0x10, 0x00, 0x92, 0x06, 0x10, 0x00, 0x96, 0x06, 0x10, 0x00, + 0x34, 0x06, 0x10, 0x00, 0x98, 0x46, 0x10, 0x00, 0x5A, 0x1C, 0x01, 0x20, + 0x0A, 0x44, 0x01, 0x20, 0xF6, 0x06, 0x10, 0x00, 0xF7, 0x06, 0x10, 0x00, + 0xF8, 0x06, 0x10, 0x00, 0x60, 0x06, 0x10, 0x00, 0x6C, 0x06, 0x10, 0x00, + 0xC2, 0x18, 0x01, 0x20, 0x45, 0x4F, 0xB3, 0xF9, 0x32, 0x50, 0xB7, 0xF9, + 0x00, 0x70, 0xBD, 0x42, 0x09, 0xDD, 0xB4, 0xF8, 0x26, 0x43, 0x9D, 0x69, + 0xA5, 0x42, 0x04, 0xDA, 0x00, 0xF0, 0xDB, 0xFC, 0x01, 0x28, 0x00, 0xD1, + 0x01, 0x26, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x2D, 0xE9, 0xFF, 0x5F, + 0x8B, 0x46, 0x14, 0x46, 0x91, 0x78, 0x0E, 0x9D, 0x08, 0xF0, 0xC6, 0xFD, + 0x06, 0x46, 0xA1, 0x78, 0x68, 0x68, 0x08, 0xF0, 0xC7, 0xFD, 0x07, 0x46, + 0x4F, 0xF0, 0x00, 0x09, 0xFF, 0xF7, 0xF5, 0xFB, 0x00, 0x28, 0x32, 0xD0, + 0x32, 0x49, 0xB5, 0xF9, 0x32, 0x00, 0xB1, 0xF9, 0x00, 0x10, 0x88, 0x42, + 0x2B, 0xDC, 0x30, 0x48, 0xA1, 0x78, 0xE3, 0x78, 0x90, 0xF8, 0x00, 0xA0, + 0x19, 0xE0, 0x20, 0x78, 0x62, 0x78, 0x0F, 0xE0, 0x16, 0xF8, 0x00, 0x80, + 0xD8, 0x45, 0x09, 0xD1, 0x37, 0xF9, 0x10, 0x80, 0xDD, 0xF8, 0x0C, 0xC0, + 0xE0, 0x45, 0x03, 0xDD, 0x09, 0xF1, 0x01, 0x0C, 0x1F, 0xFA, 0x8C, 0xF9, + 0x40, 0x1C, 0xC0, 0xB2, 0x82, 0x42, 0xED, 0xD2, 0x49, 0x1C, 0x07, 0xEB, + 0x4A, 0x07, 0xC9, 0xB2, 0x28, 0x36, 0x8B, 0x42, 0xE3, 0xD2, 0x29, 0x46, + 0x48, 0x46, 0xFF, 0xF7, 0xDA, 0xFB, 0x00, 0x28, 0x03, 0xD0, 0xA8, 0x8C, + 0x40, 0xF4, 0x00, 0x70, 0xA8, 0x84, 0xBD, 0xE8, 0xFF, 0x9F, 0x2D, 0xE9, + 0xF0, 0x41, 0x80, 0x46, 0x01, 0x20, 0x83, 0xF8, 0x40, 0x00, 0x1C, 0x46, + 0x16, 0x46, 0x0F, 0x46, 0x40, 0x46, 0x00, 0xF0, 0x0B, 0xFC, 0x14, 0x4D, + 0x28, 0x68, 0x90, 0xF8, 0x40, 0x03, 0x41, 0x07, 0x04, 0xD5, 0x21, 0x46, + 0x30, 0x46, 0x00, 0xF0, 0xDF, 0xFD, 0x05, 0xE0, 0x00, 0x07, 0x03, 0xD5, + 0x21, 0x46, 0x30, 0x46, 0x00, 0xF0, 0xC7, 0xFD, 0x28, 0x68, 0x23, 0x46, + 0x32, 0x46, 0x90, 0xF8, 0x40, 0x03, 0x39, 0x46, 0xC0, 0x06, 0x40, 0x46, + 0x03, 0xD5, 0xBD, 0xE8, 0xF0, 0x41, 0x01, 0xF0, 0x86, 0xBB, 0xBD, 0xE8, + 0xF0, 0x41, 0xFF, 0xF7, 0x37, 0xB9, 0x00, 0x00, 0x94, 0x06, 0x10, 0x00, + 0x8C, 0x06, 0x10, 0x00, 0xEE, 0x06, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x01, 0x78, 0x59, 0xB1, 0x80, 0x4A, 0x12, 0x78, 0x52, 0x1E, 0x91, 0x42, + 0x06, 0xD0, 0x40, 0x78, 0x20, 0xB1, 0x7E, 0x49, 0x09, 0x78, 0x49, 0x1E, + 0x88, 0x42, 0x01, 0xD1, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, + 0x01, 0x78, 0x29, 0xB1, 0x77, 0x49, 0x42, 0x78, 0x09, 0x78, 0x49, 0x1E, + 0x8A, 0x42, 0x09, 0xD1, 0x81, 0x78, 0x29, 0xB1, 0xC1, 0x78, 0x74, 0x48, + 0x00, 0x78, 0x40, 0x1E, 0x81, 0x42, 0x01, 0xD1, 0x01, 0x20, 0x70, 0x47, + 0x00, 0x20, 0x70, 0x47, 0xF0, 0xB5, 0x70, 0x4D, 0x00, 0x22, 0x05, 0xEB, + 0xC2, 0x06, 0x00, 0x23, 0xC6, 0xE9, 0x00, 0x33, 0x52, 0x1C, 0xD2, 0xB2, + 0x17, 0x2A, 0xF6, 0xD3, 0x8A, 0x78, 0x2C, 0xE0, 0x00, 0xEB, 0xC2, 0x03, + 0xD3, 0xE9, 0x00, 0x76, 0x57, 0xEA, 0x06, 0x03, 0x23, 0xD0, 0x74, 0x08, + 0x4F, 0xEA, 0x37, 0x03, 0x17, 0xEB, 0x07, 0x0E, 0x46, 0xEB, 0x06, 0x0C, + 0x44, 0xEA, 0x0C, 0x04, 0x34, 0x43, 0x43, 0xEA, 0x0E, 0x03, 0x05, 0xEB, + 0xC2, 0x06, 0x3B, 0x43, 0xD6, 0xE9, 0x00, 0x7C, 0x1F, 0x43, 0x4C, 0xEA, + 0x04, 0x0C, 0xC6, 0xE9, 0x00, 0x7C, 0xD6, 0xE9, 0x02, 0x7C, 0x1F, 0x43, + 0x4C, 0xEA, 0x04, 0x0C, 0xC6, 0xE9, 0x02, 0x7C, 0xD6, 0xE9, 0x04, 0x7C, + 0x1F, 0x43, 0x4C, 0xEA, 0x04, 0x0C, 0xC6, 0xE9, 0x04, 0x7C, 0x52, 0x1C, + 0xD2, 0xB2, 0xCB, 0x78, 0x93, 0x42, 0xCF, 0xD2, 0x00, 0x22, 0x50, 0x4B, + 0x0A, 0xE0, 0x00, 0xBF, 0x05, 0xEB, 0xC2, 0x04, 0x00, 0xEB, 0xC2, 0x07, + 0xD4, 0xE9, 0x02, 0x64, 0xC7, 0xE9, 0x00, 0x64, 0x52, 0x1C, 0xD2, 0xB2, + 0x1C, 0x78, 0xA2, 0x42, 0xF2, 0xD3, 0x08, 0x78, 0x08, 0xB1, 0x40, 0x1E, + 0x08, 0x70, 0x45, 0x4A, 0x48, 0x78, 0x12, 0x78, 0x52, 0x1E, 0x90, 0x42, + 0x01, 0xDA, 0x40, 0x1C, 0x48, 0x70, 0x88, 0x78, 0x08, 0xB1, 0x40, 0x1E, + 0x88, 0x70, 0x1A, 0x78, 0xC8, 0x78, 0x52, 0x1E, 0x90, 0x42, 0x01, 0xDA, + 0x40, 0x1C, 0xC8, 0x70, 0xF0, 0xBD, 0x2D, 0xE9, 0xFF, 0x5F, 0x94, 0x78, + 0x16, 0x46, 0x04, 0xEB, 0x84, 0x02, 0x8B, 0x46, 0x00, 0xEB, 0xC2, 0x00, + 0x00, 0x21, 0x00, 0xF1, 0x29, 0x08, 0x20, 0xE0, 0x00, 0x20, 0x81, 0x46, + 0x82, 0x46, 0x35, 0x78, 0x77, 0x78, 0x0F, 0xE0, 0x18, 0xF8, 0x05, 0x20, + 0x5A, 0x45, 0x09, 0xD1, 0x2A, 0x46, 0x01, 0x20, 0x00, 0x21, 0x08, 0xF0, + 0xEB, 0xFA, 0x41, 0xEA, 0x0A, 0x0A, 0x40, 0xEA, 0x09, 0x09, 0x01, 0x21, + 0x6D, 0x1C, 0xED, 0xB2, 0xAF, 0x42, 0xED, 0xD2, 0x03, 0x9B, 0x08, 0xF1, + 0x28, 0x08, 0x03, 0xEB, 0xC4, 0x03, 0x64, 0x1C, 0xC3, 0xE9, 0x00, 0x9A, + 0xE4, 0xB2, 0xF0, 0x78, 0xA0, 0x42, 0xDB, 0xD2, 0x04, 0xB0, 0x08, 0x46, + 0xBD, 0xE8, 0xF0, 0x9F, 0x0A, 0x78, 0x43, 0x78, 0x9A, 0x42, 0x0B, 0xD8, + 0x4A, 0x78, 0x03, 0x78, 0x9A, 0x42, 0x07, 0xD3, 0x8A, 0x78, 0xC3, 0x78, + 0x9A, 0x42, 0x03, 0xD8, 0xC9, 0x78, 0x80, 0x78, 0x81, 0x42, 0x01, 0xD2, + 0x00, 0x20, 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x70, 0xB5, 0x0C, 0x78, + 0x8B, 0x78, 0x4D, 0x78, 0xC9, 0x78, 0x9A, 0xB1, 0x0C, 0xB1, 0x64, 0x1E, + 0xE4, 0xB2, 0x12, 0x4A, 0x12, 0x78, 0x52, 0x1E, 0x95, 0x42, 0x01, 0xDA, + 0x6D, 0x1C, 0xED, 0xB2, 0x0B, 0xB1, 0x5B, 0x1E, 0xDB, 0xB2, 0x0E, 0x4A, + 0x12, 0x78, 0x52, 0x1E, 0x91, 0x42, 0x01, 0xDA, 0x49, 0x1C, 0xC9, 0xB2, + 0x03, 0xEB, 0x83, 0x02, 0x00, 0xEB, 0xC2, 0x02, 0x00, 0x26, 0x29, 0x32, + 0x09, 0xE0, 0x20, 0x46, 0x02, 0xE0, 0x16, 0x54, 0x40, 0x1C, 0xC0, 0xB2, + 0xA8, 0x42, 0xFA, 0xD9, 0x5B, 0x1C, 0xDB, 0xB2, 0x28, 0x32, 0x8B, 0x42, + 0xF3, 0xD9, 0x70, 0xBD, 0xEE, 0x06, 0x10, 0x00, 0xED, 0x06, 0x10, 0x00, + 0x40, 0x47, 0x10, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0xDF, 0xF8, 0xA0, 0x90, + 0x80, 0x46, 0x0C, 0x78, 0x99, 0xF8, 0x00, 0x00, 0x0D, 0x46, 0x80, 0x1E, + 0x01, 0x2C, 0x05, 0xD9, 0x69, 0x78, 0x81, 0x42, 0x02, 0xDA, 0x00, 0x20, + 0xBD, 0xE8, 0xF0, 0x87, 0x02, 0x2C, 0x01, 0xD2, 0x02, 0x27, 0x01, 0xE0, + 0x6F, 0x78, 0xC4, 0xB2, 0x4F, 0xF0, 0x00, 0x0A, 0xA9, 0x78, 0xD8, 0xF8, + 0x08, 0x00, 0x08, 0xF0, 0x2B, 0xFC, 0x06, 0x46, 0xA9, 0x78, 0xD8, 0xF8, + 0x04, 0x00, 0x08, 0xF0, 0x25, 0xFC, 0xAA, 0x78, 0x01, 0x46, 0xED, 0x78, + 0x99, 0xF8, 0x00, 0x30, 0x13, 0xE0, 0x20, 0x46, 0x0A, 0xE0, 0x00, 0xBF, + 0x36, 0xF9, 0x10, 0xC0, 0x31, 0xF9, 0x10, 0x80, 0xC4, 0x45, 0x02, 0xD0, + 0x4F, 0xF0, 0x01, 0x0A, 0x02, 0xE0, 0x40, 0x1C, 0xB8, 0x42, 0xF3, 0xD9, + 0x06, 0xEB, 0x43, 0x06, 0x01, 0xEB, 0x43, 0x01, 0x52, 0x1C, 0x95, 0x42, + 0xE9, 0xD2, 0x50, 0x46, 0xCC, 0xE7, 0x08, 0x49, 0x09, 0x78, 0x49, 0x1E, + 0xCA, 0xB2, 0x90, 0xF8, 0x3E, 0x10, 0x09, 0xB1, 0x91, 0x42, 0x05, 0xD1, + 0x81, 0x8C, 0x41, 0xF0, 0x04, 0x01, 0x81, 0x84, 0x01, 0x20, 0x70, 0x47, + 0x00, 0x20, 0x70, 0x47, 0xEE, 0x06, 0x10, 0x00, 0x30, 0xB5, 0xB0, 0xB1, + 0x88, 0x42, 0x14, 0xD0, 0x02, 0xD2, 0x0A, 0x46, 0x01, 0x46, 0x10, 0x46, + 0xDE, 0x4A, 0x53, 0x68, 0x03, 0xEB, 0x40, 0x03, 0x1C, 0x78, 0x8C, 0x42, + 0x09, 0xD0, 0x5C, 0x78, 0x8C, 0x42, 0x06, 0xD0, 0x95, 0x68, 0x2A, 0x5C, + 0x02, 0x2A, 0x02, 0xD2, 0x54, 0x1C, 0x2C, 0x54, 0x99, 0x54, 0x08, 0x46, + 0x30, 0xBD, 0xF0, 0xB5, 0x03, 0xEB, 0x82, 0x04, 0xA5, 0x78, 0x05, 0xEB, + 0x85, 0x06, 0x00, 0xEB, 0xC6, 0x06, 0xE0, 0x78, 0x28, 0x36, 0xA8, 0x42, + 0x0F, 0xD3, 0x20, 0x78, 0x07, 0xE0, 0x37, 0x18, 0x97, 0xF8, 0x01, 0xC0, + 0x94, 0x45, 0x00, 0xD1, 0x79, 0x70, 0x40, 0x1C, 0xC0, 0xB2, 0x67, 0x78, + 0x87, 0x42, 0xF4, 0xD2, 0x6D, 0x1C, 0xED, 0xB2, 0xEB, 0xE7, 0x03, 0xEB, + 0x81, 0x00, 0x25, 0x68, 0x05, 0x60, 0x03, 0xEB, 0x42, 0x00, 0x03, 0xEB, + 0x41, 0x01, 0x30, 0xF8, 0xB4, 0x2F, 0xA1, 0xF8, 0xB4, 0x20, 0xC2, 0x49, + 0x09, 0x68, 0x21, 0x60, 0x00, 0x21, 0x01, 0x80, 0x93, 0xF8, 0x0E, 0x01, + 0x40, 0x1E, 0x83, 0xF8, 0x0E, 0x01, 0xF0, 0xBD, 0x2D, 0xE9, 0xFF, 0x4F, + 0x88, 0x46, 0x08, 0x46, 0x09, 0x78, 0x8F, 0xB0, 0xFF, 0x29, 0x13, 0xD0, + 0x8A, 0x46, 0xB9, 0x49, 0x42, 0x78, 0x09, 0x78, 0x8A, 0x42, 0x00, 0xD2, + 0x51, 0x1C, 0xCE, 0xB2, 0xB6, 0x49, 0x90, 0xF8, 0x02, 0x90, 0xC0, 0x78, + 0x09, 0x78, 0x88, 0x42, 0x01, 0xD2, 0x40, 0x1C, 0x00, 0xE0, 0x08, 0x46, + 0xC7, 0xB2, 0x04, 0xE0, 0x4F, 0xF0, 0x00, 0x0A, 0x56, 0x46, 0xD1, 0x46, + 0x57, 0x46, 0x11, 0x98, 0x4F, 0xF0, 0x00, 0x0B, 0x08, 0xB1, 0x98, 0xF8, + 0x0E, 0xB1, 0xA8, 0x4A, 0x11, 0x68, 0x01, 0xF1, 0x5A, 0x00, 0xC2, 0xE9, + 0x01, 0x10, 0x02, 0x46, 0x5F, 0xF0, 0x2C, 0x00, 0x00, 0x23, 0x01, 0xF8, + 0x10, 0x00, 0x13, 0x54, 0x40, 0x1E, 0xC0, 0xB2, 0xF8, 0xD2, 0x0B, 0xF1, + 0x01, 0x00, 0x0D, 0x90, 0xC0, 0xB2, 0x06, 0x90, 0x0F, 0x98, 0x09, 0xEB, + 0x89, 0x01, 0x00, 0xEB, 0xC1, 0x05, 0x09, 0xF1, 0x01, 0x00, 0x09, 0x95, + 0x39, 0xE0, 0x00, 0xBF, 0x0A, 0xF1, 0x01, 0x00, 0x0A, 0x95, 0xC4, 0xB2, + 0x28, 0x35, 0x2E, 0xE0, 0x29, 0x19, 0x08, 0x68, 0xE0, 0xB1, 0x28, 0x5D, + 0x38, 0xB3, 0x11, 0xF8, 0x01, 0x1C, 0x00, 0x20, 0x01, 0xB1, 0x08, 0x46, + 0x0A, 0x99, 0x09, 0x5D, 0x09, 0xB1, 0xFF, 0xF7, 0x57, 0xFF, 0x12, 0x99, + 0x61, 0xB1, 0x0A, 0x99, 0x21, 0x44, 0x0E, 0x91, 0x11, 0xF8, 0x01, 0x1C, + 0x09, 0xB1, 0xFF, 0xF7, 0x4D, 0xFF, 0x0E, 0x99, 0x49, 0x78, 0x09, 0xB1, + 0xFF, 0xF7, 0x48, 0xFF, 0x18, 0xB1, 0x0B, 0xE0, 0xE4, 0x1C, 0xE4, 0xB2, + 0x09, 0xE0, 0x06, 0x98, 0x2D, 0x28, 0x03, 0xD2, 0x41, 0x1C, 0xC9, 0xB2, + 0x06, 0x91, 0x01, 0xE0, 0x40, 0x1E, 0xC0, 0xB2, 0x28, 0x55, 0x64, 0x1C, + 0xE4, 0xB2, 0xB4, 0x42, 0xCE, 0xD9, 0x07, 0x98, 0x40, 0x1C, 0xC0, 0xB2, + 0x07, 0x90, 0xB8, 0x42, 0xC2, 0xD9, 0x06, 0x98, 0x00, 0xF0, 0x99, 0xF8, + 0x06, 0x90, 0x0D, 0x98, 0x00, 0x22, 0xC0, 0xB2, 0x77, 0x4C, 0x09, 0xE0, + 0x08, 0xEB, 0x80, 0x03, 0x21, 0x68, 0x19, 0x60, 0x08, 0xEB, 0x40, 0x01, + 0x40, 0x1C, 0xA1, 0xF8, 0xB4, 0x20, 0xC0, 0xB2, 0x06, 0x99, 0x88, 0x42, + 0xF2, 0xD3, 0x09, 0x98, 0x4D, 0x46, 0x28, 0x30, 0x00, 0x90, 0x39, 0xE0, + 0x54, 0x46, 0x30, 0xE0, 0x20, 0x44, 0x01, 0x21, 0x09, 0x58, 0xE9, 0xB3, + 0x41, 0x78, 0x41, 0xB3, 0x68, 0x4A, 0x52, 0x68, 0x12, 0xF8, 0x11, 0x10, + 0x41, 0x70, 0x08, 0xEB, 0x41, 0x00, 0x08, 0xEB, 0x81, 0x09, 0x30, 0xF8, + 0xB4, 0x2F, 0x52, 0x1C, 0x02, 0x80, 0x99, 0xF8, 0x00, 0x10, 0x20, 0x46, + 0x04, 0xF0, 0xEC, 0xF9, 0x89, 0xF8, 0x00, 0x00, 0x99, 0xF8, 0x01, 0x10, + 0x20, 0x46, 0x04, 0xF0, 0xE9, 0xF9, 0x89, 0xF8, 0x01, 0x00, 0x99, 0xF8, + 0x02, 0x10, 0x28, 0x46, 0x04, 0xF0, 0xDE, 0xF9, 0x89, 0xF8, 0x02, 0x00, + 0x99, 0xF8, 0x03, 0x10, 0x28, 0x46, 0x04, 0xF0, 0xDB, 0xF9, 0x89, 0xF8, + 0x03, 0x00, 0x64, 0x1C, 0xE4, 0xB2, 0x00, 0x98, 0xB4, 0x42, 0xCB, 0xD3, + 0x28, 0x30, 0x6D, 0x1C, 0xED, 0xB2, 0x00, 0x90, 0xBD, 0x42, 0xC3, 0xD3, + 0x06, 0x98, 0x40, 0x1E, 0xC2, 0xB2, 0x88, 0xF8, 0x0E, 0x21, 0x11, 0x98, + 0x00, 0x28, 0x00, 0xE0, 0x0B, 0xE0, 0x0D, 0xD0, 0xA2, 0xEB, 0x0B, 0x00, + 0x01, 0x28, 0x09, 0xD1, 0x11, 0x99, 0x0F, 0x98, 0x13, 0xB0, 0x43, 0x46, + 0xBD, 0xE8, 0xF0, 0x4F, 0xDD, 0xE6, 0xE4, 0x1C, 0xE4, 0xB2, 0xDC, 0xE7, + 0x13, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xF0, 0xB5, 0x02, 0xEB, 0x81, 0x03, + 0x00, 0x26, 0x9D, 0x78, 0x18, 0xE0, 0x00, 0xBF, 0x05, 0xEB, 0x85, 0x04, + 0x00, 0xEB, 0xC4, 0x07, 0x1C, 0x78, 0x28, 0x37, 0x0A, 0xE0, 0x00, 0xBF, + 0x07, 0xEB, 0x04, 0x0C, 0x9C, 0xF8, 0x01, 0xE0, 0x8E, 0x45, 0x01, 0xD1, + 0x8C, 0xF8, 0x01, 0x60, 0x64, 0x1C, 0xE4, 0xB2, 0x93, 0xF8, 0x01, 0xC0, + 0xA4, 0x45, 0xF1, 0xD2, 0x6D, 0x1C, 0xED, 0xB2, 0xDC, 0x78, 0xAC, 0x42, + 0xE4, 0xD2, 0x31, 0x48, 0x00, 0x68, 0x18, 0x60, 0x02, 0xEB, 0x41, 0x00, + 0xA0, 0xF8, 0xB4, 0x60, 0xF0, 0xBD, 0x2D, 0xE9, 0xF0, 0x5F, 0x07, 0x46, + 0x00, 0x25, 0xDF, 0xF8, 0xA8, 0xB0, 0x2C, 0xE0, 0xDB, 0xF8, 0x08, 0x10, + 0x4E, 0x5D, 0xDB, 0xF8, 0x04, 0x10, 0x01, 0xEB, 0x45, 0x0A, 0x1A, 0xE0, + 0x0A, 0xEB, 0x06, 0x00, 0x80, 0x46, 0x10, 0xF8, 0x01, 0x1C, 0x10, 0xF8, + 0x02, 0x9C, 0x08, 0x46, 0x00, 0xF0, 0x35, 0xF8, 0x04, 0x46, 0x48, 0x46, + 0x00, 0xF0, 0x31, 0xF8, 0x84, 0x42, 0x02, 0xD2, 0x01, 0x46, 0x20, 0x46, + 0x0C, 0x46, 0xDB, 0xF8, 0x04, 0x10, 0x76, 0x1E, 0xF6, 0xB2, 0x01, 0xF8, + 0x10, 0x40, 0x08, 0xF8, 0x02, 0x4C, 0x01, 0x2E, 0xE2, 0xD8, 0x04, 0xD1, + 0x28, 0x46, 0x00, 0xF0, 0x1E, 0xF8, 0x8A, 0xF8, 0x00, 0x00, 0x6D, 0x1C, + 0xED, 0xB2, 0xBD, 0x42, 0xD0, 0xD3, 0x00, 0x21, 0x08, 0x46, 0xDB, 0xF8, + 0x04, 0x40, 0x0D, 0xE0, 0x04, 0xEB, 0x40, 0x02, 0x13, 0x78, 0x83, 0x42, + 0x03, 0xD1, 0x11, 0x70, 0x49, 0x1C, 0xC9, 0xB2, 0x02, 0xE0, 0x14, 0xF8, + 0x13, 0x30, 0x13, 0x70, 0x40, 0x1C, 0xC0, 0xB2, 0xB8, 0x42, 0xEF, 0xD3, + 0x08, 0x46, 0xBD, 0xE8, 0xF0, 0x9F, 0x05, 0x4A, 0xD2, 0xE9, 0x01, 0x12, + 0x02, 0xE0, 0x00, 0xBF, 0x11, 0xF8, 0x10, 0x00, 0x13, 0x5C, 0x00, 0x2B, + 0xFA, 0xD1, 0x70, 0x47, 0x60, 0x06, 0x10, 0x00, 0x36, 0x7A, 0x01, 0x00, + 0xEE, 0x06, 0x10, 0x00, 0xED, 0x06, 0x10, 0x00, 0xF0, 0xB5, 0xB2, 0xF9, + 0x00, 0x40, 0x06, 0x68, 0xB4, 0x42, 0x02, 0xDD, 0xB3, 0xF9, 0x00, 0x10, + 0x30, 0xE0, 0x02, 0xEB, 0x41, 0x04, 0x34, 0xF9, 0x02, 0x5C, 0xB5, 0x42, + 0x04, 0xDA, 0x03, 0xEB, 0x41, 0x01, 0x31, 0xF9, 0x02, 0x1C, 0x25, 0xE0, + 0x00, 0x25, 0x2C, 0x46, 0x4F, 0x1E, 0x0C, 0xE0, 0x32, 0xF9, 0x14, 0xC0, + 0xB4, 0x45, 0x07, 0xDC, 0x02, 0xEB, 0x44, 0x0C, 0xBC, 0xF9, 0x02, 0xC0, + 0xB4, 0x45, 0x01, 0xDB, 0x25, 0x46, 0x0C, 0x46, 0x64, 0x1C, 0xBC, 0x42, + 0xF0, 0xDB, 0x32, 0xF9, 0x15, 0x40, 0x03, 0xEB, 0x45, 0x01, 0x33, 0xF9, + 0x15, 0x30, 0xB1, 0xF9, 0x02, 0x10, 0x02, 0xEB, 0x45, 0x02, 0x36, 0x1B, + 0xC9, 0x1A, 0xB2, 0xF9, 0x02, 0x20, 0x71, 0x43, 0x12, 0x1B, 0x91, 0xFB, + 0xF2, 0xF1, 0x19, 0x44, 0x01, 0x60, 0xF0, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, + 0x07, 0x46, 0x2A, 0x48, 0x00, 0x68, 0x00, 0xF2, 0x0F, 0x53, 0xE9, 0xB1, + 0x01, 0x29, 0x22, 0xD0, 0x02, 0x29, 0x2C, 0xD0, 0x03, 0x29, 0x31, 0xD0, + 0x04, 0x29, 0x36, 0xD0, 0x00, 0x21, 0x0C, 0x46, 0x0E, 0xEB, 0x01, 0x00, + 0x20, 0x44, 0x64, 0x28, 0x3D, 0xDC, 0x01, 0x29, 0x03, 0xDD, 0x38, 0x1D, + 0x63, 0x46, 0xFF, 0xF7, 0xA7, 0xFF, 0x01, 0x2C, 0x35, 0xDD, 0x38, 0x46, + 0x33, 0x46, 0x2A, 0x46, 0x21, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x9D, 0xE7, + 0x90, 0xF8, 0x08, 0x15, 0x90, 0xF8, 0x09, 0x45, 0x90, 0xF8, 0x0A, 0xE5, + 0x05, 0xE0, 0x90, 0xF8, 0x08, 0x15, 0x90, 0xF8, 0x09, 0x45, 0x90, 0xF8, + 0x0B, 0xE5, 0x9C, 0x46, 0x03, 0xEB, 0x41, 0x06, 0x03, 0xEB, 0x4E, 0x02, + 0x18, 0xE0, 0x90, 0xF8, 0x08, 0x15, 0x90, 0xF8, 0x09, 0x45, 0x90, 0xF8, + 0x0C, 0xE5, 0xF2, 0xE7, 0x90, 0xF8, 0x08, 0x15, 0x90, 0xF8, 0x09, 0x45, + 0x90, 0xF8, 0x0D, 0xE5, 0xEB, 0xE7, 0x90, 0xF8, 0x08, 0x15, 0x90, 0xF8, + 0x09, 0x45, 0x90, 0xF8, 0x0E, 0x05, 0x9C, 0x46, 0x03, 0xEB, 0x41, 0x06, + 0x03, 0xEB, 0x40, 0x02, 0x02, 0xEB, 0x41, 0x05, 0xBC, 0xE7, 0xBD, 0xE8, + 0xF0, 0x81, 0x00, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x30, 0xB5, 0x42, 0x78, + 0x03, 0x78, 0xCD, 0x8C, 0xD2, 0x1A, 0xC3, 0x78, 0x80, 0x78, 0x52, 0x1C, + 0x1B, 0x1A, 0x5B, 0x1C, 0x05, 0xFB, 0x02, 0xF0, 0xD4, 0x18, 0x5D, 0x43, + 0x40, 0x00, 0x6A, 0x00, 0xB0, 0xFB, 0xF4, 0xF0, 0xB2, 0xFB, 0xF4, 0xF2, + 0x90, 0x42, 0x02, 0xD9, 0xC8, 0x85, 0x0A, 0x86, 0x30, 0xBD, 0xCA, 0x85, + 0x08, 0x86, 0x30, 0xBD, 0x2D, 0xE9, 0xFF, 0x4F, 0x00, 0x27, 0x83, 0xB0, + 0x15, 0x46, 0x01, 0x97, 0x00, 0x97, 0x3E, 0x46, 0x3C, 0x46, 0xBB, 0x46, + 0x91, 0x78, 0x08, 0xF0, 0x61, 0xF9, 0x82, 0x46, 0xAB, 0x78, 0x95, 0xF8, + 0x03, 0x90, 0x28, 0xE0, 0x29, 0x78, 0x95, 0xF8, 0x01, 0xC0, 0x8E, 0x46, + 0x1D, 0xE0, 0x00, 0xBF, 0x1A, 0xF8, 0x01, 0x20, 0x04, 0x98, 0x82, 0x42, + 0x15, 0xD1, 0xA1, 0xEB, 0x0E, 0x02, 0x52, 0x1C, 0xDD, 0xF8, 0x00, 0x80, + 0xA9, 0xEB, 0x03, 0x00, 0x02, 0xFB, 0x02, 0x88, 0x40, 0x1C, 0xCD, 0xF8, + 0x00, 0x80, 0xDD, 0xF8, 0x04, 0x80, 0x16, 0x44, 0x02, 0xFB, 0x00, 0x82, + 0x00, 0xFB, 0x00, 0xBB, 0x04, 0x44, 0x7F, 0x1C, 0x01, 0x92, 0x49, 0x1C, + 0xC9, 0xB2, 0x8C, 0x45, 0xE0, 0xD2, 0x5B, 0x1C, 0x0A, 0xF1, 0x28, 0x0A, + 0xDB, 0xB2, 0x99, 0x45, 0xD4, 0xD2, 0x4F, 0xF4, 0x7A, 0x70, 0x70, 0x43, + 0x90, 0xFB, 0xF7, 0xF1, 0x4F, 0xF4, 0x7A, 0x70, 0x60, 0x43, 0x90, 0xFB, + 0xF7, 0xF3, 0x4F, 0xF4, 0x7A, 0x72, 0x01, 0xFB, 0x04, 0xF0, 0x71, 0x43, + 0x90, 0xFB, 0xF2, 0xF7, 0x91, 0xFB, 0xF2, 0xF6, 0x63, 0x43, 0x93, 0xFB, + 0xF2, 0xF3, 0x01, 0x98, 0x00, 0x99, 0xC0, 0x1B, 0x89, 0x1B, 0xAB, 0xEB, + 0x03, 0x02, 0x06, 0x9C, 0x8B, 0x1A, 0x00, 0xD5, 0x5B, 0x42, 0x00, 0x28, + 0x00, 0xDA, 0x40, 0x42, 0x03, 0xEB, 0x40, 0x00, 0x11, 0x44, 0x0A, 0x18, + 0x08, 0x1A, 0x52, 0x10, 0x40, 0x10, 0x4F, 0xF4, 0x7A, 0x71, 0x48, 0x43, + 0x90, 0xFB, 0xF2, 0xF0, 0xC0, 0xF5, 0x7A, 0x70, 0xA0, 0x85, 0x06, 0x99, + 0x07, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0x6E, 0xE7, 0x01, 0x20, + 0x70, 0x47, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x5F, 0x8A, 0x46, 0x0A, 0x9F, + 0x00, 0x25, 0x98, 0x46, 0x14, 0x46, 0x83, 0x46, 0x2E, 0x46, 0x39, 0x46, + 0x08, 0xF0, 0xF0, 0xF8, 0x30, 0xF9, 0x18, 0x00, 0xA0, 0x42, 0x2E, 0xDD, + 0x78, 0x1E, 0x44, 0xB2, 0x7F, 0x1C, 0x27, 0xE0, 0x00, 0x2C, 0x21, 0xDB, + 0xB0, 0x48, 0x00, 0x78, 0x84, 0x42, 0x1D, 0xDA, 0xE1, 0xB2, 0x58, 0x46, + 0x08, 0xF0, 0xDE, 0xF8, 0xAD, 0x49, 0x81, 0x46, 0xA8, 0xF1, 0x01, 0x00, + 0x0A, 0x78, 0x40, 0xB2, 0x08, 0xF1, 0x01, 0x01, 0x0D, 0xE0, 0x00, 0x28, + 0x07, 0xDB, 0x90, 0x42, 0x05, 0xDA, 0x39, 0xF9, 0x10, 0xC0, 0x3A, 0xF9, + 0x15, 0x30, 0x0C, 0xFB, 0x03, 0x66, 0x6D, 0x1C, 0x40, 0x1C, 0xED, 0xB2, + 0x40, 0xB2, 0x88, 0x42, 0xEF, 0xDD, 0x01, 0xE0, 0xED, 0x1C, 0xED, 0xB2, + 0x64, 0x1C, 0x64, 0xB2, 0xBC, 0x42, 0xD5, 0xDD, 0x00, 0xE0, 0x06, 0x46, + 0x01, 0x20, 0x96, 0xFB, 0xF0, 0xF0, 0x00, 0xB2, 0xBD, 0xE8, 0xF0, 0x9F, + 0x2D, 0xE9, 0xFF, 0x4F, 0x83, 0xB0, 0x91, 0x46, 0x10, 0x99, 0x08, 0x78, + 0x00, 0xB1, 0x40, 0x1E, 0xC4, 0xB2, 0x88, 0x78, 0x00, 0xB1, 0x40, 0x1E, + 0xDF, 0xF8, 0x4C, 0xA2, 0xC5, 0xB2, 0x4A, 0x78, 0x9A, 0xF8, 0x00, 0x00, + 0x43, 0x1E, 0x9A, 0x42, 0x01, 0xDA, 0x50, 0x1C, 0x00, 0xE0, 0x40, 0x1E, + 0xDF, 0xF8, 0x30, 0xB2, 0xC6, 0xB2, 0xC9, 0x78, 0x9B, 0xF8, 0x00, 0x00, + 0x42, 0x1E, 0x91, 0x42, 0x01, 0xDA, 0x48, 0x1C, 0x00, 0xE0, 0x40, 0x1E, + 0xC7, 0xB2, 0xCC, 0xB9, 0xA8, 0x46, 0x12, 0xE0, 0x01, 0x46, 0x03, 0x98, + 0x08, 0xF0, 0x98, 0xF8, 0xCD, 0xE9, 0x00, 0x80, 0x23, 0x46, 0x49, 0x46, + 0x06, 0x9A, 0x04, 0x98, 0xFF, 0xF7, 0x86, 0xFF, 0x01, 0x99, 0x21, 0xF8, + 0x14, 0x00, 0x08, 0xF1, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x08, 0x40, 0x46, + 0xB8, 0x45, 0xE9, 0xD9, 0x64, 0x1C, 0xE4, 0xB2, 0x79, 0x48, 0x00, 0x78, + 0x40, 0x1E, 0x86, 0x42, 0x19, 0xD1, 0xA8, 0x46, 0x12, 0xE0, 0x01, 0x46, + 0x03, 0x98, 0x08, 0xF0, 0x79, 0xF8, 0x82, 0x46, 0x33, 0x46, 0xCD, 0xF8, + 0x00, 0x80, 0x49, 0x46, 0x06, 0x9A, 0x04, 0x98, 0xFF, 0xF7, 0x66, 0xFF, + 0x2A, 0xF8, 0x16, 0x00, 0x08, 0xF1, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x08, + 0x40, 0x46, 0xB8, 0x45, 0xE9, 0xD9, 0x76, 0x1E, 0xF6, 0xB2, 0xC5, 0xB9, + 0x29, 0x46, 0x03, 0x98, 0x08, 0xF0, 0x60, 0xF8, 0x82, 0x46, 0xA0, 0x46, + 0x0C, 0xE0, 0x03, 0x46, 0x00, 0x95, 0x49, 0x46, 0x06, 0x9A, 0x04, 0x98, + 0xFF, 0xF7, 0x4C, 0xFF, 0x2A, 0xF8, 0x18, 0x00, 0x08, 0xF1, 0x01, 0x00, + 0x00, 0xF0, 0xFF, 0x08, 0x40, 0x46, 0xB0, 0x45, 0xEF, 0xD9, 0x6D, 0x1C, + 0xED, 0xB2, 0x9B, 0xF8, 0x00, 0x00, 0x40, 0x1E, 0x87, 0x42, 0x18, 0xD1, + 0x39, 0x46, 0x03, 0x98, 0x08, 0xF0, 0x42, 0xF8, 0x82, 0x46, 0xA0, 0x46, + 0x0C, 0xE0, 0x03, 0x46, 0x00, 0x97, 0x49, 0x46, 0x06, 0x9A, 0x04, 0x98, + 0xFF, 0xF7, 0x2E, 0xFF, 0x2A, 0xF8, 0x18, 0x00, 0x08, 0xF1, 0x01, 0x00, + 0x00, 0xF0, 0xFF, 0x08, 0x40, 0x46, 0xB0, 0x45, 0xEF, 0xD9, 0x7F, 0x1E, + 0xFF, 0xB2, 0xB9, 0xF9, 0x12, 0x00, 0x5F, 0xEA, 0x00, 0x0A, 0x64, 0xD1, + 0x4F, 0xF0, 0x01, 0x0A, 0x61, 0xE0, 0x29, 0x46, 0x03, 0x98, 0x08, 0xF0, + 0x21, 0xF8, 0x01, 0x90, 0x68, 0x1E, 0xC1, 0xB2, 0x04, 0x98, 0x08, 0xF0, + 0x0D, 0xF8, 0x00, 0x90, 0x29, 0x46, 0x04, 0x98, 0x08, 0xF0, 0x08, 0xF8, + 0x21, 0x46, 0x4C, 0xE0, 0x30, 0xF9, 0x11, 0x20, 0x06, 0x9B, 0x9A, 0x42, + 0x42, 0xDD, 0x00, 0x9A, 0xB9, 0xF9, 0x00, 0x80, 0x02, 0xEB, 0x41, 0x02, + 0x00, 0x23, 0x32, 0xF9, 0x02, 0xCD, 0x0C, 0xFB, 0x08, 0x33, 0xB2, 0xF9, + 0x02, 0xC0, 0xB9, 0xF9, 0x02, 0x80, 0x0C, 0xFB, 0x08, 0x33, 0xB2, 0xF9, + 0x04, 0xC0, 0xB9, 0xF9, 0x04, 0x80, 0x0C, 0xFB, 0x08, 0x3B, 0x34, 0x4B, + 0xB9, 0xF9, 0x06, 0x80, 0x93, 0xF8, 0x00, 0xE0, 0x02, 0xEB, 0x4E, 0x02, + 0xB2, 0xF9, 0x00, 0xC0, 0x0C, 0xFB, 0x08, 0xB3, 0xB2, 0xF9, 0x02, 0xC0, + 0xB9, 0xF9, 0x08, 0x80, 0x0C, 0xFB, 0x08, 0x33, 0xB2, 0xF9, 0x04, 0xC0, + 0xB9, 0xF9, 0x0A, 0x80, 0x02, 0xEB, 0x4E, 0x02, 0x0C, 0xFB, 0x08, 0x3B, + 0xB2, 0xF9, 0x00, 0xC0, 0xB9, 0xF9, 0x0C, 0x80, 0x0C, 0xFB, 0x08, 0xB3, + 0xB2, 0xF9, 0x02, 0xC0, 0xB9, 0xF9, 0x0E, 0x80, 0x0C, 0xFB, 0x08, 0x33, + 0xB2, 0xF9, 0x04, 0xC0, 0xB9, 0xF9, 0x10, 0x20, 0x0C, 0xFB, 0x02, 0x32, + 0x92, 0xFB, 0xFA, 0xF2, 0x01, 0x9B, 0x23, 0xF8, 0x11, 0x20, 0x49, 0x1C, + 0xC9, 0xB2, 0xB1, 0x42, 0xB0, 0xD9, 0x6D, 0x1C, 0xED, 0xB2, 0xBD, 0x42, + 0x9B, 0xD9, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x1C, 0xB5, 0x17, 0x4C, + 0x24, 0x68, 0x01, 0x94, 0x01, 0xAC, 0x00, 0x94, 0xFF, 0xF7, 0xF2, 0xFE, + 0x1C, 0xBD, 0x38, 0xB5, 0x16, 0x4D, 0x00, 0x90, 0x12, 0x48, 0x0C, 0x46, + 0x12, 0x4A, 0x00, 0x68, 0xB0, 0xF9, 0xE2, 0x32, 0x11, 0x48, 0x01, 0x68, + 0x28, 0x68, 0xFF, 0xF7, 0xE3, 0xFE, 0x28, 0x68, 0xA0, 0x60, 0x38, 0xBD, + 0x38, 0xB5, 0x0E, 0x4D, 0x00, 0x90, 0x0A, 0x48, 0x0C, 0x46, 0x0A, 0x4A, + 0x00, 0x68, 0x14, 0x3A, 0xB0, 0xF9, 0xE2, 0x32, 0x08, 0x48, 0x01, 0x68, + 0x28, 0x68, 0xFF, 0xF7, 0xD1, 0xFE, 0x28, 0x68, 0x60, 0x60, 0x38, 0xBD, + 0xED, 0x06, 0x10, 0x00, 0xEE, 0x06, 0x10, 0x00, 0x88, 0x06, 0x10, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x22, 0x7A, 0x01, 0x00, 0x10, 0x07, 0x10, 0x00, + 0x58, 0x06, 0x10, 0x00, 0x2D, 0xE9, 0xFF, 0x5F, 0x89, 0x46, 0x14, 0x46, + 0x91, 0x78, 0x0F, 0x9D, 0x07, 0xF0, 0x68, 0xFF, 0x82, 0x46, 0xA1, 0x78, + 0xA8, 0x68, 0x07, 0xF0, 0x69, 0xFF, 0x47, 0xF6, 0xFF, 0x76, 0xA7, 0x78, + 0xF5, 0x43, 0xFE, 0x49, 0x94, 0xF8, 0x03, 0x80, 0x91, 0xF8, 0x00, 0xB0, + 0x18, 0xE0, 0x22, 0x78, 0x94, 0xF8, 0x01, 0xC0, 0x0D, 0xE0, 0x00, 0xBF, + 0x1A, 0xF8, 0x02, 0x10, 0x49, 0x45, 0x07, 0xD1, 0x30, 0xF9, 0x12, 0x30, + 0xB3, 0x42, 0x00, 0xDA, 0x1E, 0x46, 0xAB, 0x42, 0x00, 0xDD, 0x1D, 0x46, + 0x52, 0x1C, 0x94, 0x45, 0xF0, 0xD2, 0x0A, 0xF1, 0x28, 0x0A, 0x00, 0xEB, + 0x4B, 0x00, 0x7F, 0x1C, 0xB8, 0x45, 0xE4, 0xD2, 0x03, 0x98, 0x06, 0x80, + 0x0E, 0x98, 0x05, 0x80, 0xBD, 0xE8, 0xFF, 0x9F, 0x2D, 0xE9, 0xFF, 0x4F, + 0xEA, 0x48, 0x85, 0xB0, 0x9A, 0x46, 0x04, 0x68, 0x03, 0xA9, 0xCD, 0xE9, + 0x00, 0x1A, 0xDD, 0xE9, 0x05, 0x01, 0x15, 0x46, 0x04, 0xF5, 0x88, 0x79, + 0x02, 0xAB, 0xFF, 0xF7, 0xB7, 0xFF, 0xE4, 0x48, 0xBD, 0xF9, 0x0C, 0x20, + 0xDF, 0xF8, 0x8C, 0xB3, 0x00, 0x68, 0x5F, 0x46, 0x90, 0xF8, 0xE4, 0x12, + 0xBD, 0xF9, 0x08, 0x00, 0x12, 0x1A, 0x4A, 0x43, 0x64, 0x21, 0x92, 0xFB, + 0xF1, 0xF1, 0x0E, 0x18, 0x01, 0x22, 0x29, 0x46, 0xDB, 0xF8, 0x00, 0x00, + 0xFF, 0xF7, 0x98, 0xFA, 0xD7, 0xF8, 0x00, 0x80, 0xDD, 0xE9, 0x05, 0x07, + 0x31, 0xB2, 0x01, 0x91, 0xA9, 0x78, 0x07, 0xF0, 0x07, 0xFF, 0x06, 0x46, + 0xA9, 0x78, 0x40, 0x46, 0x07, 0xF0, 0x10, 0xFF, 0x00, 0x90, 0xA9, 0x78, + 0xDA, 0xF8, 0x08, 0x00, 0x07, 0xF0, 0x02, 0xFF, 0x01, 0x46, 0xAA, 0x78, + 0x01, 0x23, 0xDF, 0xF8, 0x2C, 0xE3, 0x1D, 0xE0, 0x28, 0x78, 0x0E, 0xE0, + 0x16, 0xF8, 0x00, 0xC0, 0xBC, 0x45, 0x09, 0xD1, 0x31, 0xF9, 0x10, 0x80, + 0xDD, 0xF8, 0x04, 0xC0, 0xE0, 0x45, 0x03, 0xDD, 0xDD, 0xF8, 0x00, 0xC0, + 0x0C, 0xF8, 0x00, 0x30, 0x40, 0x1C, 0x95, 0xF8, 0x01, 0xC0, 0x84, 0x45, + 0xEC, 0xD2, 0x00, 0x98, 0x52, 0x1C, 0x28, 0x30, 0x00, 0x90, 0x9E, 0xF8, + 0x00, 0x00, 0x28, 0x36, 0x01, 0xEB, 0x40, 0x01, 0xE8, 0x78, 0x90, 0x42, + 0xDE, 0xD2, 0x00, 0x20, 0x84, 0xF8, 0x0E, 0x01, 0x28, 0x68, 0x20, 0x60, + 0x01, 0x23, 0x00, 0x22, 0x21, 0x46, 0x5E, 0x46, 0xDB, 0xF8, 0x00, 0x00, + 0xFF, 0xF7, 0x28, 0xFB, 0x94, 0xF8, 0x0E, 0x01, 0x01, 0x28, 0x26, 0xD9, + 0x01, 0x25, 0x1D, 0xE0, 0x48, 0x22, 0x51, 0x46, 0x48, 0x46, 0x07, 0xF0, + 0x7F, 0xFD, 0x04, 0xEB, 0x45, 0x00, 0x04, 0xEB, 0x85, 0x07, 0xB0, 0xF8, + 0xB4, 0x10, 0xA9, 0xF8, 0x26, 0x10, 0x49, 0x46, 0x38, 0x46, 0xFF, 0xF7, + 0x27, 0xFD, 0x3A, 0x46, 0xE9, 0xB2, 0x4B, 0x46, 0x30, 0x68, 0xFE, 0xF7, + 0x0C, 0xFB, 0x3A, 0x46, 0xE9, 0xB2, 0x4B, 0x46, 0x30, 0x68, 0xFE, 0xF7, + 0x85, 0xFA, 0x6D, 0x1C, 0x94, 0xF8, 0x0E, 0x01, 0xA8, 0x42, 0xDD, 0xD2, + 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xDD, 0xE9, 0x05, 0x01, 0x53, 0x46, + 0x2A, 0x46, 0xFE, 0xF7, 0x77, 0xFA, 0xF5, 0xE7, 0x2D, 0xE9, 0xFF, 0x5F, + 0x06, 0x46, 0x9A, 0x48, 0x1D, 0x46, 0x0B, 0x46, 0x00, 0x68, 0xDD, 0xE9, + 0x0F, 0xB4, 0x92, 0x46, 0x98, 0x49, 0xB0, 0xF9, 0xE6, 0x22, 0x00, 0x92, + 0x09, 0x78, 0x11, 0xB1, 0xB0, 0xF9, 0x62, 0x03, 0x00, 0x90, 0x18, 0x46, + 0x0E, 0x99, 0x07, 0xF0, 0x7F, 0xFE, 0x81, 0x46, 0x30, 0x46, 0x0E, 0x99, + 0x07, 0xF0, 0x88, 0xFE, 0x03, 0x90, 0xA0, 0x68, 0x0E, 0x99, 0x07, 0xF0, + 0x7B, 0xFE, 0x2C, 0x78, 0x6D, 0x78, 0x80, 0x46, 0x5C, 0xB9, 0x99, 0xF8, + 0x00, 0x10, 0x51, 0x45, 0x06, 0xD1, 0xB8, 0xF9, 0x00, 0x10, 0x59, 0x45, + 0x02, 0xDD, 0x03, 0x99, 0x01, 0x20, 0x08, 0x70, 0x01, 0x24, 0x81, 0x48, + 0x00, 0x78, 0x40, 0x1E, 0x85, 0x42, 0x54, 0xD1, 0x19, 0xF8, 0x05, 0x10, + 0x51, 0x45, 0x06, 0xD1, 0x38, 0xF9, 0x15, 0x10, 0x59, 0x45, 0x02, 0xDD, + 0x03, 0x99, 0x01, 0x20, 0x48, 0x55, 0x6D, 0x1E, 0xED, 0xB2, 0x46, 0xE0, + 0x19, 0xF8, 0x04, 0x10, 0x51, 0x45, 0x41, 0xD1, 0x38, 0xF9, 0x14, 0x00, + 0x01, 0x90, 0x58, 0x45, 0x3C, 0xDD, 0x00, 0x20, 0x02, 0x90, 0x77, 0x49, + 0x0E, 0x98, 0x22, 0x46, 0x01, 0xEB, 0xC0, 0x00, 0x00, 0x21, 0xD0, 0xE9, + 0x00, 0x67, 0x01, 0x20, 0x07, 0xF0, 0x82, 0xFC, 0x06, 0x40, 0x0F, 0x40, + 0x3E, 0x43, 0x28, 0xD1, 0xDD, 0xE9, 0x00, 0x01, 0x08, 0xEB, 0x44, 0x02, + 0x08, 0x44, 0x32, 0xF9, 0x02, 0x1C, 0x00, 0xB2, 0x81, 0x42, 0x05, 0xDD, + 0xB2, 0xF9, 0x02, 0x30, 0x83, 0x42, 0x01, 0xDD, 0x01, 0x23, 0x02, 0x93, + 0x01, 0x2C, 0x09, 0xD9, 0x32, 0xF9, 0x04, 0x3C, 0x83, 0x42, 0x05, 0xDD, + 0xB2, 0xF9, 0x02, 0x30, 0x83, 0x42, 0x01, 0xDD, 0x01, 0x23, 0x02, 0x93, + 0x5C, 0x4B, 0x1B, 0x78, 0x9B, 0x1E, 0x9C, 0x42, 0x05, 0xD2, 0x81, 0x42, + 0x03, 0xDD, 0xB2, 0xF9, 0x04, 0x10, 0x81, 0x42, 0x04, 0xDC, 0x02, 0x98, + 0x10, 0xB9, 0x03, 0x99, 0x01, 0x20, 0x08, 0x55, 0x64, 0x1C, 0xAC, 0x42, + 0xB6, 0xD9, 0xCD, 0xE6, 0x2D, 0xE9, 0xFF, 0x4F, 0xDF, 0xF8, 0x54, 0xA1, + 0xDF, 0xF8, 0x48, 0x81, 0x9B, 0xB0, 0x8B, 0x46, 0x9A, 0xF8, 0x00, 0x10, + 0x28, 0x9E, 0xD8, 0xF8, 0x00, 0x00, 0x1D, 0x46, 0x11, 0xB1, 0x90, 0xF8, + 0x68, 0x43, 0x01, 0xE0, 0x90, 0xF8, 0xE5, 0x42, 0x4E, 0x4F, 0xAC, 0xB1, + 0x03, 0xA8, 0xCD, 0xE9, 0x00, 0x06, 0x02, 0xAB, 0x2A, 0x46, 0x58, 0x46, + 0x1D, 0x99, 0xFF, 0xF7, 0x79, 0xFE, 0xBD, 0xF9, 0x0C, 0x00, 0xBD, 0xF9, + 0x08, 0x10, 0x40, 0x1A, 0x60, 0x43, 0x64, 0x21, 0x90, 0xFB, 0xF1, 0xF0, + 0x39, 0x88, 0x08, 0x44, 0x00, 0xB2, 0x01, 0xE0, 0xB7, 0xF9, 0x00, 0x00, + 0x42, 0x49, 0x81, 0x46, 0x38, 0x88, 0x08, 0x80, 0x41, 0x49, 0xA1, 0xF8, + 0x00, 0x90, 0xD8, 0xF8, 0x00, 0x00, 0xB0, 0xF9, 0xE6, 0x12, 0x11, 0x91, + 0xB0, 0xF9, 0xE8, 0x12, 0x0C, 0x91, 0x9A, 0xF8, 0x00, 0x10, 0x29, 0xB1, + 0xB0, 0xF9, 0x62, 0x13, 0x11, 0x91, 0xB0, 0xF9, 0x64, 0x03, 0x0C, 0x90, + 0xAC, 0x78, 0x95, 0xF8, 0x03, 0x80, 0x4C, 0xB9, 0xCD, 0xE9, 0x00, 0x49, + 0x02, 0x96, 0x2B, 0x46, 0x59, 0x46, 0x1D, 0x9A, 0x1B, 0x98, 0xFF, 0xF7, + 0x1F, 0xFF, 0x01, 0x24, 0x31, 0x49, 0x09, 0x78, 0x49, 0x1E, 0x88, 0x45, + 0x0D, 0xD1, 0xCD, 0xF8, 0x00, 0x80, 0xCD, 0xE9, 0x01, 0x96, 0x2B, 0x46, + 0x59, 0x46, 0x1D, 0x9A, 0x1B, 0x98, 0xFF, 0xF7, 0x0F, 0xFF, 0xA8, 0xF1, + 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x08, 0xA0, 0x1E, 0xC1, 0xB2, 0xB0, 0x68, + 0x07, 0xF0, 0xA2, 0xFD, 0x0D, 0x90, 0x60, 0x1E, 0xC1, 0xB2, 0xB0, 0x68, + 0x07, 0xF0, 0x9C, 0xFD, 0x03, 0x90, 0x21, 0x46, 0xB0, 0x68, 0x07, 0xF0, + 0x97, 0xFD, 0x02, 0x90, 0x60, 0x1C, 0xC1, 0xB2, 0xB0, 0x68, 0x07, 0xF0, + 0x91, 0xFD, 0x01, 0x90, 0xA0, 0x1C, 0xC1, 0xB2, 0xB0, 0x68, 0x07, 0xF0, + 0x8B, 0xFD, 0x04, 0x90, 0x21, 0x46, 0x58, 0x46, 0x07, 0xF0, 0x80, 0xFD, + 0x83, 0x46, 0x21, 0x46, 0x1B, 0x98, 0x07, 0xF0, 0x89, 0xFD, 0x05, 0x90, + 0x00, 0x20, 0x14, 0x90, 0x01, 0x20, 0x13, 0x90, 0x00, 0x20, 0x12, 0x90, + 0x0A, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x40, 0x14, 0xCA, 0x07, 0x29, 0xD0, + 0x09, 0x07, 0x27, 0xD5, 0x69, 0x78, 0x2A, 0x78, 0x8A, 0x1A, 0x90, 0xF8, + 0x49, 0x14, 0x52, 0x1C, 0x8A, 0x42, 0x1F, 0xDC, 0xEA, 0x78, 0x13, 0xE0, + 0xEE, 0x06, 0x10, 0x00, 0x6C, 0x06, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x54, 0x06, 0x10, 0x00, 0xFD, 0x06, 0x10, 0x00, 0x98, 0x46, 0x10, 0x00, + 0x92, 0x06, 0x10, 0x00, 0x8E, 0x07, 0x10, 0x00, 0x90, 0x07, 0x10, 0x00, + 0xED, 0x06, 0x10, 0x00, 0xAB, 0x78, 0xD2, 0x1A, 0x52, 0x1C, 0x8A, 0x42, + 0x04, 0xDC, 0xB0, 0xF8, 0x47, 0x04, 0xB1, 0x69, 0x81, 0x42, 0x01, 0xDD, + 0x00, 0x20, 0x13, 0x90, 0xA2, 0x46, 0xF1, 0xE0, 0x2C, 0x78, 0xCE, 0xE0, + 0x1B, 0xF8, 0x04, 0x10, 0x1D, 0x98, 0x81, 0x42, 0x6B, 0xD1, 0x00, 0x20, + 0x10, 0x90, 0xFB, 0x49, 0x16, 0x90, 0x15, 0x90, 0x01, 0xEB, 0xCA, 0x00, + 0x22, 0x46, 0xD0, 0xE9, 0x00, 0x67, 0x01, 0x20, 0x00, 0x21, 0x07, 0xF0, + 0x71, 0xFB, 0x06, 0x40, 0x0F, 0x40, 0x3E, 0x43, 0x7E, 0xD1, 0xF4, 0x49, + 0x40, 0xF2, 0xD2, 0x40, 0x08, 0x80, 0x02, 0x98, 0x0C, 0x9A, 0x30, 0xF8, + 0x14, 0x10, 0x11, 0x98, 0x08, 0x44, 0x11, 0x44, 0x03, 0x9A, 0x00, 0xB2, + 0x09, 0xB2, 0x32, 0xF9, 0x14, 0x20, 0x82, 0x42, 0x07, 0xDD, 0x01, 0x9B, + 0x33, 0xF9, 0x14, 0x30, 0x83, 0x42, 0x02, 0xDD, 0x01, 0x23, 0x10, 0x93, + 0x15, 0x93, 0xEC, 0xB3, 0xE7, 0x4B, 0x93, 0xF8, 0x00, 0xE0, 0xAE, 0xF1, + 0x01, 0x03, 0x9C, 0x42, 0x68, 0xD0, 0x02, 0x9B, 0x03, 0xEB, 0x44, 0x0C, + 0x3C, 0xF9, 0x02, 0x6C, 0x86, 0x42, 0x06, 0xDD, 0xBC, 0xF9, 0x02, 0x30, + 0x83, 0x42, 0x02, 0xDD, 0x01, 0x23, 0x10, 0x93, 0x16, 0x93, 0x03, 0x9B, + 0x03, 0xEB, 0x44, 0x03, 0x33, 0xF9, 0x02, 0x7C, 0x8F, 0x42, 0x08, 0xDD, + 0x01, 0x9F, 0x07, 0xEB, 0x44, 0x07, 0xB7, 0xF9, 0x02, 0x70, 0x8F, 0x42, + 0x01, 0xDD, 0x01, 0x27, 0x10, 0x97, 0xB3, 0xF9, 0x02, 0x30, 0x8B, 0x42, + 0x06, 0xDD, 0x01, 0x9B, 0x03, 0xEB, 0x44, 0x03, 0x33, 0xF9, 0x02, 0x3C, + 0x8B, 0x42, 0x41, 0xDC, 0x10, 0x99, 0x59, 0xB9, 0xBA, 0xF1, 0x01, 0x0F, + 0x0F, 0xD9, 0x0D, 0x99, 0x31, 0xF9, 0x14, 0x10, 0x81, 0x42, 0x0A, 0xDD, + 0x01, 0x99, 0x31, 0xF9, 0x14, 0x10, 0x01, 0xE0, 0x30, 0xE0, 0x5B, 0xE0, + 0x81, 0x42, 0x02, 0xDD, 0x01, 0x21, 0x10, 0x91, 0x15, 0x91, 0xC6, 0x4B, + 0x1B, 0x78, 0x9B, 0x1E, 0x9A, 0x45, 0x09, 0xD2, 0x82, 0x42, 0x07, 0xDD, + 0x04, 0x99, 0x31, 0xF9, 0x14, 0x10, 0x81, 0x42, 0x02, 0xDD, 0x01, 0x21, + 0x10, 0x91, 0x15, 0x91, 0x01, 0x2C, 0x0A, 0xD9, 0x3C, 0xF9, 0x04, 0x1C, + 0x81, 0x42, 0x06, 0xDD, 0xBC, 0xF9, 0x02, 0x10, 0x81, 0x42, 0x02, 0xDD, + 0x01, 0x21, 0x10, 0x91, 0x16, 0x91, 0xAE, 0xF1, 0x02, 0x01, 0x00, 0xE0, + 0x17, 0xE0, 0x8C, 0x42, 0x08, 0xD2, 0x86, 0x42, 0x06, 0xDD, 0xBC, 0xF9, + 0x04, 0x10, 0x81, 0x42, 0x02, 0xDD, 0x01, 0x20, 0x16, 0x90, 0x01, 0xE0, + 0x10, 0x98, 0x48, 0xB1, 0xB0, 0x49, 0x41, 0xF2, 0xB3, 0x50, 0x08, 0x80, + 0xAF, 0x48, 0xB0, 0x49, 0x04, 0x80, 0xA1, 0xF8, 0x00, 0xA0, 0x09, 0xE0, + 0x40, 0xB9, 0x02, 0x98, 0x30, 0xF9, 0x14, 0x10, 0x49, 0x45, 0x03, 0xDD, + 0x05, 0x99, 0x01, 0x20, 0x08, 0x55, 0x15, 0xE0, 0x16, 0x98, 0x98, 0xB1, + 0x15, 0x98, 0x88, 0xB1, 0x13, 0x98, 0x78, 0xB1, 0x05, 0x98, 0x01, 0x21, + 0x01, 0x55, 0x12, 0x98, 0x40, 0x1C, 0x80, 0xB2, 0x12, 0x90, 0xA3, 0x48, + 0x00, 0x68, 0x90, 0xF8, 0x4A, 0x14, 0x12, 0x98, 0x81, 0x42, 0x01, 0xD2, + 0x01, 0x20, 0x14, 0x90, 0x64, 0x1C, 0x68, 0x78, 0xA0, 0x42, 0xBF, 0xF4, + 0x2D, 0xAF, 0x97, 0x48, 0x0D, 0x99, 0x0B, 0xF1, 0x28, 0x0B, 0x00, 0x78, + 0x0A, 0xF1, 0x01, 0x0A, 0x01, 0xEB, 0x40, 0x01, 0x0D, 0x91, 0x03, 0x99, + 0x01, 0xEB, 0x40, 0x01, 0x03, 0x91, 0x02, 0x99, 0x01, 0xEB, 0x40, 0x01, + 0x02, 0x91, 0x01, 0x99, 0x01, 0xEB, 0x40, 0x01, 0x01, 0x91, 0x04, 0x99, + 0x01, 0xEB, 0x40, 0x00, 0x04, 0x90, 0x05, 0x98, 0x28, 0x30, 0x05, 0x90, + 0xC2, 0x45, 0x7F, 0xF6, 0x0B, 0xAF, 0x14, 0x98, 0x1F, 0xB0, 0xA8, 0xE5, + 0x2D, 0xE9, 0xF0, 0x47, 0x04, 0x46, 0x91, 0x42, 0x5A, 0xD0, 0x07, 0xD9, + 0x01, 0xEB, 0x02, 0x00, 0xA0, 0xEB, 0x02, 0x01, 0xCA, 0xB2, 0xA0, 0xEB, + 0x02, 0x00, 0xC1, 0xB2, 0x01, 0xEB, 0xC1, 0x00, 0x04, 0xEB, 0xC0, 0x01, + 0x02, 0xEB, 0xC2, 0x00, 0x04, 0xEB, 0xC0, 0x00, 0xB1, 0xF9, 0x32, 0x50, + 0xB0, 0xF9, 0x32, 0x30, 0x81, 0x46, 0x9D, 0x42, 0x00, 0xDA, 0x4B, 0x86, + 0xCB, 0x8C, 0xC5, 0x8C, 0x2B, 0x44, 0xCB, 0x84, 0x0B, 0x8D, 0x05, 0x8D, + 0x2B, 0x44, 0x0B, 0x85, 0x4B, 0x8D, 0x45, 0x8D, 0x2B, 0x44, 0x4B, 0x85, + 0x8B, 0x69, 0x85, 0x69, 0x2B, 0x44, 0x8B, 0x61, 0xC7, 0x69, 0xCE, 0x69, + 0xCB, 0x68, 0xD9, 0xF8, 0x0C, 0x00, 0x4F, 0xEA, 0x23, 0x4C, 0x4F, 0xEA, + 0x20, 0x48, 0x0C, 0xFB, 0x06, 0xFC, 0xF5, 0x19, 0x07, 0xFB, 0x08, 0xCC, + 0x9C, 0xFB, 0xF5, 0xFC, 0x6C, 0xF3, 0x1F, 0x43, 0x0F, 0xFA, 0x83, 0xFC, + 0x0C, 0xFB, 0x06, 0xFC, 0x00, 0xB2, 0x07, 0xFB, 0x00, 0xC0, 0x90, 0xFB, + 0xF5, 0xF0, 0x60, 0xF3, 0x0F, 0x03, 0xCD, 0x61, 0xCB, 0x60, 0x94, 0xF8, + 0x38, 0x04, 0x41, 0x1E, 0x91, 0x42, 0x08, 0xD0, 0x00, 0xEB, 0xC0, 0x00, + 0x04, 0xEB, 0xC0, 0x01, 0x48, 0x46, 0x48, 0x22, 0x48, 0x39, 0x07, 0xF0, + 0xAF, 0xFA, 0x94, 0xF8, 0x38, 0x04, 0x40, 0x1E, 0x84, 0xF8, 0x38, 0x04, + 0xBD, 0xE8, 0xF0, 0x87, 0x2D, 0xE9, 0xFE, 0x4F, 0x07, 0x46, 0x58, 0x48, + 0x8A, 0x46, 0x00, 0x25, 0x01, 0x68, 0xB1, 0xF8, 0xEA, 0x02, 0x00, 0xFB, + 0x00, 0xF9, 0x55, 0x48, 0x00, 0x78, 0x18, 0xB1, 0xB1, 0xF8, 0x66, 0x03, + 0x00, 0xFB, 0x00, 0xF9, 0x54, 0x46, 0x4F, 0xF0, 0x01, 0x0B, 0xB0, 0xE0, + 0x0B, 0xFA, 0x04, 0xF0, 0x26, 0x46, 0x00, 0x90, 0x66, 0xE0, 0x00, 0xBF, + 0x00, 0x99, 0x0B, 0xFA, 0x06, 0xF0, 0x08, 0x42, 0x5F, 0xD0, 0x06, 0xEB, + 0xC6, 0x00, 0x07, 0xEB, 0xC0, 0x00, 0xC2, 0x68, 0x20, 0x46, 0x4D, 0xE0, + 0xB0, 0x42, 0x4A, 0xD0, 0x00, 0xEB, 0xC0, 0x01, 0x07, 0xEB, 0xC1, 0x01, + 0xC9, 0x68, 0x4F, 0xEA, 0x21, 0x4C, 0xAC, 0xEB, 0x22, 0x4C, 0x89, 0x1A, + 0x0F, 0xFA, 0x8C, 0xFC, 0x09, 0xB2, 0x6C, 0xF3, 0x1F, 0x45, 0x61, 0xF3, + 0x0F, 0x05, 0x8E, 0x46, 0x3B, 0x49, 0xCD, 0xF8, 0x04, 0xC0, 0x09, 0x68, + 0x91, 0xF8, 0xE0, 0xC2, 0xCD, 0xF8, 0x08, 0xC0, 0x5F, 0xEA, 0x8C, 0x6C, + 0x0B, 0xD5, 0x91, 0xF8, 0xED, 0x82, 0x0E, 0xFB, 0x08, 0xFC, 0x4F, 0xF0, + 0x64, 0x08, 0x9C, 0xFB, 0xF8, 0xF8, 0x08, 0xEB, 0x0E, 0x0C, 0x6C, 0xF3, + 0x0F, 0x05, 0xDD, 0xF8, 0x08, 0xC0, 0x5F, 0xEA, 0xCC, 0x6C, 0x0C, 0xD5, + 0x91, 0xF8, 0xED, 0x12, 0xDD, 0xF8, 0x04, 0xC0, 0x0C, 0xFB, 0x01, 0xFC, + 0x64, 0x21, 0x9C, 0xFB, 0xF1, 0xFC, 0x01, 0x99, 0x61, 0x44, 0x61, 0xF3, + 0x1F, 0x45, 0x4F, 0xEA, 0x25, 0x4C, 0x0C, 0xFB, 0x0C, 0xFC, 0x29, 0xB2, + 0x01, 0xFB, 0x01, 0xC1, 0x49, 0x45, 0x06, 0xD2, 0xDD, 0xF8, 0x00, 0xC0, + 0x0B, 0xFA, 0x00, 0xF1, 0x41, 0xEA, 0x0C, 0x01, 0x00, 0x91, 0x40, 0x1C, + 0x83, 0x42, 0xAF, 0xD8, 0x04, 0x21, 0x68, 0x46, 0xF1, 0xF7, 0x3D, 0xFA, + 0x01, 0x28, 0x02, 0xD1, 0x00, 0x98, 0x40, 0x00, 0x00, 0x90, 0x76, 0x1C, + 0x97, 0xF8, 0x38, 0x34, 0xB3, 0x42, 0x95, 0xD8, 0x04, 0x21, 0x68, 0x46, + 0xF1, 0xF7, 0x2F, 0xFA, 0x01, 0x28, 0x0B, 0xD0, 0x04, 0x21, 0x68, 0x46, + 0xF1, 0xF7, 0x29, 0xFA, 0x97, 0xF8, 0x38, 0x64, 0xA6, 0xEB, 0x0A, 0x01, + 0x88, 0x42, 0x06, 0xD1, 0x87, 0xF8, 0x38, 0xA4, 0xBD, 0xE8, 0xFE, 0x8F, + 0x64, 0x1C, 0xE4, 0xB2, 0x01, 0xE0, 0x00, 0x99, 0x58, 0x46, 0x00, 0xFA, + 0x04, 0xF2, 0x0A, 0x42, 0xF6, 0xD0, 0xD8, 0x46, 0x1C, 0xE0, 0x00, 0x00, + 0x98, 0x46, 0x10, 0x00, 0x86, 0x07, 0x10, 0x00, 0xEE, 0x06, 0x10, 0x00, + 0xED, 0x06, 0x10, 0x00, 0x88, 0x07, 0x10, 0x00, 0x8A, 0x07, 0x10, 0x00, + 0x8C, 0x07, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0xFD, 0x06, 0x10, 0x00, + 0x00, 0x99, 0x08, 0xFA, 0x06, 0xF0, 0x08, 0x42, 0x04, 0xD0, 0xF2, 0xB2, + 0x21, 0x46, 0x38, 0x46, 0xFF, 0xF7, 0xDC, 0xFE, 0x76, 0x1E, 0xA6, 0x42, + 0xF2, 0xD8, 0x64, 0x1C, 0xE4, 0xB2, 0x97, 0xF8, 0x38, 0x04, 0xA0, 0x42, + 0x3F, 0xF6, 0x4A, 0xAF, 0xCA, 0xE7, 0x2D, 0xE9, 0xFF, 0x4F, 0xFB, 0x48, + 0xFB, 0x4C, 0x93, 0x46, 0x06, 0x68, 0x81, 0xB0, 0x1D, 0x46, 0x06, 0xF5, + 0x88, 0x7A, 0x01, 0x22, 0x59, 0x46, 0x20, 0x68, 0xFE, 0xF7, 0x92, 0xFE, + 0x00, 0x95, 0xDD, 0xE9, 0x01, 0x12, 0x5B, 0x46, 0x20, 0x68, 0xFF, 0xF7, + 0xFB, 0xFC, 0x03, 0x00, 0x4F, 0xF0, 0x01, 0x01, 0x05, 0xD0, 0xF1, 0x48, + 0x01, 0x70, 0xA8, 0x8C, 0x40, 0xF0, 0x80, 0x00, 0xA8, 0x84, 0xEF, 0x48, + 0x00, 0x78, 0x50, 0xB1, 0x4B, 0xB9, 0x95, 0xF8, 0x24, 0x00, 0x10, 0xF0, + 0x06, 0x0F, 0x04, 0xD1, 0x59, 0x46, 0x28, 0x46, 0xFE, 0xF7, 0xA8, 0xFE, + 0x03, 0x46, 0x00, 0x20, 0x86, 0xF8, 0x0E, 0x01, 0xDB, 0xF8, 0x00, 0x00, + 0x30, 0x60, 0xE3, 0x48, 0x00, 0x22, 0x31, 0x46, 0x00, 0x68, 0xFE, 0xF7, + 0x3F, 0xFF, 0x96, 0xF8, 0x0E, 0x01, 0x00, 0x24, 0x01, 0x28, 0x79, 0xD9, + 0xFC, 0xF7, 0x61, 0xF9, 0x81, 0x46, 0xFC, 0xF7, 0x5C, 0xF9, 0x80, 0x46, + 0xDB, 0xF8, 0x00, 0x20, 0xDD, 0xE9, 0x01, 0x01, 0x00, 0x92, 0xDB, 0x4B, + 0x6A, 0x46, 0xFE, 0xF7, 0x0A, 0xFE, 0x60, 0xB1, 0x69, 0x46, 0xD8, 0x48, + 0xFE, 0xF7, 0x9E, 0xFD, 0x2A, 0x46, 0x69, 0x46, 0xD5, 0x48, 0xFD, 0xF7, + 0xD8, 0xFA, 0xE9, 0x68, 0x69, 0x61, 0xE9, 0x69, 0x29, 0x62, 0x01, 0x27, + 0x2F, 0xE0, 0x48, 0x22, 0x29, 0x46, 0x50, 0x46, 0x07, 0xF0, 0x78, 0xF9, + 0xCF, 0x49, 0x06, 0xEB, 0x47, 0x00, 0x09, 0x68, 0xB0, 0xF8, 0xB4, 0x20, + 0x91, 0xF8, 0xEC, 0x12, 0x8A, 0x42, 0x1F, 0xD9, 0xBA, 0xF8, 0x24, 0x10, + 0x41, 0xF0, 0x10, 0x02, 0xAA, 0xF8, 0x24, 0x20, 0xB0, 0xF8, 0xB4, 0x10, + 0xAA, 0xF8, 0x26, 0x10, 0x06, 0xEB, 0x87, 0x00, 0x51, 0x46, 0x00, 0x90, + 0xFF, 0xF7, 0x12, 0xF9, 0xBE, 0x48, 0xF9, 0xB2, 0x53, 0x46, 0x00, 0x9A, + 0x00, 0x68, 0xFD, 0xF7, 0xF6, 0xFE, 0xBB, 0x48, 0xF9, 0xB2, 0x53, 0x46, + 0x00, 0x9A, 0x00, 0x68, 0xFD, 0xF7, 0x6E, 0xFE, 0x64, 0x1C, 0xE4, 0xB2, + 0x7F, 0x1C, 0x96, 0xF8, 0x0E, 0x01, 0xB8, 0x42, 0xCB, 0xD2, 0xB8, 0x4E, + 0x30, 0x68, 0x90, 0xF8, 0xE0, 0x02, 0x00, 0x07, 0x0A, 0xD5, 0x01, 0x2C, + 0x08, 0xD9, 0x49, 0x46, 0x40, 0x46, 0xFF, 0xF7, 0x95, 0xFE, 0xFC, 0xF7, + 0x02, 0xF9, 0xA0, 0xEB, 0x09, 0x00, 0xC4, 0xB2, 0x31, 0x68, 0x91, 0xF8, + 0xE0, 0x02, 0x00, 0x06, 0x13, 0xD5, 0x20, 0x46, 0x0F, 0xE0, 0x00, 0xBF, + 0x09, 0xEB, 0x00, 0x02, 0xD2, 0xB2, 0x02, 0xEB, 0xC2, 0x03, 0x08, 0xEB, + 0xC3, 0x02, 0x91, 0xF8, 0x07, 0x33, 0xD2, 0x8C, 0x9A, 0x42, 0x02, 0xD9, + 0x88, 0xF8, 0x38, 0x94, 0x05, 0xE0, 0x40, 0x1E, 0xEE, 0xD2, 0x01, 0x2C, + 0x0A, 0xD0, 0x00, 0x2C, 0x0E, 0xD1, 0xDD, 0xE9, 0x01, 0x01, 0x05, 0xB0, + 0x2B, 0x46, 0x5A, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0xFD, 0xF7, 0x30, 0xBE, + 0x98, 0xF8, 0x38, 0x04, 0x40, 0x1E, 0x88, 0xF8, 0x38, 0x04, 0xF0, 0xE7, + 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x2D, 0xE9, 0xFF, 0x4F, 0x97, 0x48, + 0x81, 0xB0, 0x00, 0x68, 0x90, 0xF8, 0xE1, 0x02, 0xC0, 0x07, 0xF3, 0xD0, + 0xA8, 0x21, 0x04, 0x98, 0x07, 0xF0, 0x58, 0xF9, 0x01, 0x25, 0x44, 0xE0, + 0x03, 0x98, 0x00, 0xEB, 0x85, 0x00, 0x82, 0x46, 0x84, 0x78, 0x90, 0xF8, + 0x03, 0x90, 0x8E, 0x48, 0x00, 0x78, 0x40, 0x1E, 0x84, 0x42, 0x01, 0xDA, + 0x64, 0x1C, 0xE4, 0xB2, 0xB9, 0xF1, 0x00, 0x0F, 0x03, 0xD0, 0xA9, 0xF1, + 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x09, 0x21, 0x46, 0x01, 0x98, 0x07, 0xF0, + 0x1F, 0xFA, 0x83, 0x46, 0xA0, 0x46, 0x24, 0xE0, 0x03, 0x98, 0x04, 0x99, + 0x10, 0xF8, 0x25, 0x40, 0x01, 0xEB, 0xC8, 0x00, 0x00, 0x90, 0x12, 0xE0, + 0x1B, 0xF8, 0x04, 0x00, 0xA8, 0x42, 0x0C, 0xD1, 0x00, 0x98, 0x22, 0x46, + 0x00, 0x21, 0xD0, 0xE9, 0x00, 0x67, 0x01, 0x20, 0x07, 0xF0, 0x4E, 0xF8, + 0x06, 0x43, 0x00, 0x98, 0x0F, 0x43, 0xC0, 0xE9, 0x00, 0x67, 0x64, 0x1C, + 0xE4, 0xB2, 0x9A, 0xF8, 0x01, 0x00, 0xA0, 0x42, 0xE8, 0xD2, 0x08, 0xF1, + 0x01, 0x00, 0x0B, 0xF1, 0x28, 0x0B, 0x00, 0xF0, 0xFF, 0x08, 0xC8, 0x45, + 0xD8, 0xD9, 0x6D, 0x1C, 0xED, 0xB2, 0x02, 0x98, 0x85, 0x42, 0xB7, 0xD9, + 0x00, 0x21, 0x6D, 0x4E, 0x13, 0xE0, 0x04, 0x98, 0x00, 0xEB, 0xC1, 0x05, + 0x01, 0xF1, 0x01, 0x01, 0xD5, 0xE9, 0x00, 0x32, 0xDC, 0x18, 0x42, 0xEB, + 0x02, 0x00, 0x52, 0x08, 0x4F, 0xEA, 0x33, 0x03, 0x04, 0xEA, 0x03, 0x04, + 0x00, 0xEA, 0x02, 0x00, 0xC5, 0xE9, 0x00, 0x40, 0xC9, 0xB2, 0x30, 0x78, + 0x81, 0x42, 0xE8, 0xD3, 0x8A, 0xE7, 0xF0, 0xB4, 0x60, 0x4D, 0x00, 0x24, + 0x2C, 0x80, 0x60, 0x4D, 0x2C, 0x80, 0x60, 0x4D, 0x2C, 0x80, 0x60, 0x4D, + 0x2C, 0x80, 0x14, 0x68, 0xC3, 0xF8, 0x3A, 0x40, 0x58, 0x4C, 0x25, 0x68, + 0x95, 0xF8, 0xE0, 0x42, 0xA6, 0x07, 0x13, 0xD4, 0x93, 0xF8, 0x40, 0x60, + 0x01, 0x2E, 0x0F, 0xD0, 0x66, 0x07, 0x13, 0xD5, 0x64, 0x06, 0x09, 0xD5, + 0x57, 0x4C, 0x64, 0x78, 0x5C, 0xB1, 0xB5, 0xF8, 0xF0, 0x42, 0x56, 0x4D, + 0x64, 0x43, 0x2D, 0x68, 0xA5, 0x42, 0x07, 0xDC, 0xF0, 0xBC, 0x94, 0xE6, + 0xF0, 0xBC, 0xFF, 0xF7, 0x73, 0xBA, 0xB5, 0xF8, 0xEE, 0x42, 0xF2, 0xE7, + 0xF0, 0xBC, 0xFD, 0xF7, 0x85, 0xBD, 0x2D, 0xE9, 0xFF, 0x4F, 0x94, 0x78, + 0xD7, 0x78, 0x15, 0x78, 0x56, 0x78, 0x81, 0xB0, 0x98, 0x46, 0x82, 0x46, + 0x04, 0xB9, 0x01, 0x24, 0x42, 0x48, 0x00, 0x78, 0x40, 0x1E, 0x87, 0x42, + 0x01, 0xD1, 0x7F, 0x1E, 0xFF, 0xB2, 0x05, 0xB9, 0x01, 0x25, 0xDF, 0xF8, + 0x14, 0xB1, 0x9B, 0xF8, 0x00, 0x00, 0x40, 0x1E, 0x86, 0x42, 0x01, 0xD1, + 0x76, 0x1E, 0xF6, 0xB2, 0x60, 0x1E, 0xC1, 0xB2, 0xD8, 0xF8, 0x08, 0x00, + 0x07, 0xF0, 0x88, 0xF9, 0x00, 0x90, 0x21, 0x46, 0xD8, 0xF8, 0x08, 0x00, + 0x07, 0xF0, 0x82, 0xF9, 0x81, 0x46, 0x60, 0x1C, 0xC1, 0xB2, 0xD8, 0xF8, + 0x08, 0x00, 0x07, 0xF0, 0x7B, 0xF9, 0x80, 0x46, 0x21, 0x46, 0x50, 0x46, + 0x07, 0xF0, 0x70, 0xF9, 0x35, 0xE0, 0x2C, 0x4A, 0x29, 0x46, 0xD2, 0xF8, + 0x00, 0xA0, 0x24, 0xE0, 0x43, 0x5C, 0x02, 0x9A, 0x93, 0x42, 0x1E, 0xD1, + 0x39, 0xF8, 0x11, 0x30, 0x9A, 0xF8, 0x27, 0x24, 0x1A, 0x44, 0x00, 0x9B, + 0x12, 0xB2, 0x03, 0xEB, 0x41, 0x03, 0x33, 0xF9, 0x02, 0xCC, 0x94, 0x45, + 0x05, 0xDD, 0x08, 0xEB, 0x41, 0x0C, 0xBC, 0xF9, 0x02, 0xC0, 0x94, 0x45, + 0x09, 0xDC, 0xB3, 0xF9, 0x02, 0x30, 0x93, 0x42, 0x07, 0xDD, 0x08, 0xEB, + 0x41, 0x03, 0x33, 0xF9, 0x02, 0x3C, 0x93, 0x42, 0x01, 0xDD, 0x01, 0x20, + 0xFC, 0xE6, 0x49, 0x1C, 0xC9, 0xB2, 0xB1, 0x42, 0xD8, 0xD9, 0xCD, 0xF8, + 0x00, 0x90, 0x9B, 0xF8, 0x00, 0x20, 0x64, 0x1C, 0xC1, 0x46, 0x08, 0xEB, + 0x42, 0x08, 0xE4, 0xB2, 0x28, 0x30, 0xBC, 0x42, 0xC7, 0xD9, 0x00, 0x20, + 0xEA, 0xE6, 0x2D, 0xE9, 0xF8, 0x4F, 0x4F, 0xF0, 0x00, 0x0A, 0x89, 0x46, + 0x04, 0x46, 0x01, 0x26, 0x57, 0x46, 0xD0, 0x46, 0x85, 0x78, 0x46, 0xE0, + 0x29, 0x46, 0xD9, 0xF8, 0x08, 0x00, 0x07, 0xF0, 0x2B, 0xF9, 0x02, 0x46, + 0x00, 0x20, 0x21, 0x78, 0x63, 0x78, 0x20, 0xE0, 0x6C, 0x06, 0x10, 0x00, + 0x54, 0x06, 0x10, 0x00, 0x34, 0x06, 0x10, 0x00, 0xA4, 0x06, 0x10, 0x00, + 0xF0, 0x45, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0xED, 0x06, 0x10, 0x00, + 0x86, 0x07, 0x10, 0x00, 0x88, 0x07, 0x10, 0x00, 0x8A, 0x07, 0x10, 0x00, + 0x8C, 0x07, 0x10, 0x00, 0x74, 0x07, 0x10, 0x00, 0x24, 0x07, 0x10, 0x00, + 0xEE, 0x06, 0x10, 0x00, 0x32, 0xF9, 0x11, 0xC0, 0x49, 0x1C, 0x60, 0x44, + 0xC9, 0xB2, 0x8B, 0x42, 0xF8, 0xD2, 0xA1, 0x78, 0x4A, 0x1C, 0xAA, 0x42, + 0x10, 0xD2, 0x46, 0x4A, 0x12, 0x68, 0xB2, 0xF8, 0x28, 0x34, 0x03, 0xEB, + 0x08, 0x02, 0xBA, 0x42, 0x01, 0xDA, 0x82, 0x42, 0x33, 0xDB, 0x89, 0x1C, + 0xA9, 0x42, 0x03, 0xD2, 0x52, 0x45, 0x01, 0xDA, 0x82, 0x42, 0x2C, 0xDB, + 0xBA, 0x46, 0x47, 0x46, 0x6D, 0x1C, 0x80, 0x46, 0xED, 0xB2, 0xE0, 0x78, + 0xA8, 0x42, 0xB5, 0xD2, 0x00, 0x20, 0x00, 0x90, 0x82, 0x46, 0x83, 0x46, + 0x25, 0x78, 0x2E, 0xE0, 0x4F, 0xF0, 0x00, 0x08, 0xA7, 0x78, 0x09, 0xE0, + 0x39, 0x46, 0xD9, 0xF8, 0x08, 0x00, 0x07, 0xF0, 0xD7, 0xF8, 0x30, 0xF9, + 0x15, 0x10, 0x7F, 0x1C, 0x88, 0x44, 0xFF, 0xB2, 0xE0, 0x78, 0xB8, 0x42, + 0xF2, 0xD2, 0x20, 0x78, 0x41, 0x1C, 0xA9, 0x42, 0x13, 0xD2, 0x2C, 0x49, + 0x09, 0x68, 0xB1, 0xF8, 0x28, 0x24, 0x02, 0xEB, 0x0B, 0x01, 0x51, 0x45, + 0x03, 0xDA, 0x41, 0x45, 0x01, 0xDA, 0x00, 0x26, 0x10, 0xE0, 0x80, 0x1C, + 0xA8, 0x42, 0x04, 0xD2, 0x00, 0x98, 0x81, 0x42, 0x01, 0xDA, 0x41, 0x45, + 0xF5, 0xDB, 0xCD, 0xF8, 0x00, 0xA0, 0xDA, 0x46, 0x6D, 0x1C, 0xC3, 0x46, + 0xED, 0xB2, 0x60, 0x78, 0xA8, 0x42, 0xCD, 0xD2, 0x30, 0x46, 0xBD, 0xE8, + 0xF8, 0x8F, 0x2D, 0xE9, 0xF0, 0x41, 0x07, 0x46, 0x98, 0x8C, 0x14, 0x46, + 0x00, 0x26, 0x1D, 0x46, 0xC2, 0x05, 0x02, 0xD5, 0x01, 0x20, 0xBD, 0xE8, + 0xF0, 0x81, 0x00, 0x06, 0x27, 0xD4, 0x15, 0x48, 0xEA, 0x8C, 0x00, 0x68, + 0x90, 0xF8, 0x23, 0x34, 0x9A, 0x42, 0x20, 0xD3, 0xB0, 0xF8, 0x24, 0x34, + 0xAA, 0x69, 0x9A, 0x42, 0x1B, 0xDC, 0x62, 0x78, 0x23, 0x78, 0x90, 0xF8, + 0x26, 0x04, 0xD2, 0x1A, 0x52, 0x1C, 0x82, 0x42, 0x13, 0xDC, 0xE2, 0x78, + 0xA3, 0x78, 0xD2, 0x1A, 0x52, 0x1C, 0x82, 0x42, 0x0D, 0xDC, 0x2B, 0x46, + 0x22, 0x46, 0x38, 0x46, 0xFF, 0xF7, 0xD3, 0xFE, 0x01, 0x28, 0x06, 0xD1, + 0x29, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0x3D, 0xFF, 0x01, 0x28, 0x00, 0xD1, + 0x01, 0x26, 0x30, 0x46, 0xD1, 0xE7, 0x00, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x70, 0x47, 0xF0, 0xB5, 0x99, 0x4B, 0x02, 0x46, 0x0C, 0x46, 0x1F, 0x78, + 0x98, 0x4B, 0x1E, 0x68, 0x98, 0x4B, 0x1D, 0x78, 0x19, 0xE0, 0x2B, 0x46, + 0x11, 0xE0, 0x00, 0xBF, 0x34, 0xF8, 0x13, 0xC0, 0x32, 0xF8, 0x13, 0xE0, + 0xAC, 0xEB, 0x0E, 0x0C, 0xB6, 0xF9, 0x46, 0xE0, 0x0F, 0xFA, 0x8C, 0xFC, + 0x1E, 0xEB, 0x0C, 0x0F, 0x22, 0xD4, 0xB6, 0xF8, 0x48, 0xE0, 0xE6, 0x45, + 0x1E, 0xDB, 0x5B, 0x1E, 0xEC, 0xD1, 0x02, 0xEB, 0x45, 0x02, 0x04, 0xEB, + 0x45, 0x04, 0x7F, 0x1E, 0xE3, 0xD2, 0x96, 0xF8, 0x44, 0x20, 0x89, 0x4B, + 0x02, 0xF0, 0x0F, 0x02, 0xC2, 0xF1, 0x10, 0x04, 0xB3, 0xF9, 0x00, 0x30, + 0x0A, 0xE0, 0x00, 0xBF, 0x31, 0xF9, 0x13, 0x50, 0x30, 0xF9, 0x13, 0x60, + 0x55, 0x43, 0x06, 0xFB, 0x04, 0x55, 0x2D, 0x11, 0x21, 0xF8, 0x13, 0x50, + 0x5B, 0x1E, 0xF3, 0xD2, 0xF0, 0xBD, 0xF0, 0xB5, 0x14, 0x46, 0x05, 0x9F, + 0x0B, 0xE0, 0x00, 0xBF, 0x31, 0xF9, 0x14, 0x50, 0x30, 0xF9, 0x14, 0x60, + 0x05, 0xEB, 0x03, 0x0C, 0xB4, 0x45, 0x19, 0xDB, 0xED, 0x1B, 0xB5, 0x42, + 0x16, 0xDC, 0x64, 0x1E, 0xF2, 0xD1, 0x73, 0x4B, 0x1B, 0x68, 0x93, 0xF8, + 0x45, 0x30, 0x1B, 0x09, 0xC3, 0xF1, 0x10, 0x04, 0x0A, 0xE0, 0x00, 0xBF, + 0x31, 0xF9, 0x12, 0x50, 0x30, 0xF9, 0x12, 0x60, 0x5D, 0x43, 0x06, 0xFB, + 0x04, 0x55, 0x2D, 0x11, 0x21, 0xF8, 0x12, 0x50, 0x52, 0x1E, 0xF3, 0xD2, + 0xF0, 0xBD, 0x2D, 0xE9, 0xF0, 0x43, 0x81, 0x46, 0x66, 0x48, 0x69, 0x4C, + 0x00, 0x68, 0x30, 0xF9, 0x5B, 0x6F, 0xB0, 0xF9, 0x02, 0x70, 0x10, 0xF8, + 0x01, 0x0C, 0x00, 0xF0, 0x0F, 0x03, 0xC3, 0xF1, 0x10, 0x08, 0x00, 0x20, + 0x17, 0xE0, 0x00, 0xBF, 0x34, 0xF9, 0x10, 0x20, 0x39, 0xF9, 0x10, 0x50, + 0x02, 0xEB, 0x06, 0x0C, 0x65, 0x45, 0x0C, 0xDC, 0xA2, 0xEB, 0x07, 0x0C, + 0x65, 0x45, 0x08, 0xDB, 0x5A, 0x43, 0x05, 0xFB, 0x08, 0x22, 0xD5, 0x17, + 0x02, 0xEB, 0x15, 0x72, 0x12, 0x11, 0x24, 0xF8, 0x10, 0x20, 0x40, 0x1C, + 0xC0, 0xB2, 0x88, 0x42, 0xE6, 0xD3, 0xBD, 0xE8, 0xF0, 0x83, 0x2D, 0xE9, + 0xF8, 0x4F, 0x0D, 0x46, 0x04, 0x46, 0x01, 0xF0, 0x7F, 0xF8, 0x00, 0x28, + 0x5B, 0xD1, 0xE8, 0x07, 0x08, 0xD0, 0x50, 0x48, 0x50, 0x49, 0x00, 0x78, + 0x09, 0x68, 0x01, 0x28, 0x20, 0x68, 0x2D, 0xD0, 0x00, 0xF0, 0x53, 0xF8, + 0x47, 0x4E, 0xE8, 0x06, 0x17, 0xD5, 0x30, 0x68, 0xB0, 0xF9, 0x50, 0x10, + 0x00, 0x91, 0x43, 0x49, 0xB0, 0xF9, 0x4E, 0x30, 0x20, 0x69, 0x0A, 0x78, + 0x47, 0x49, 0xFF, 0xF7, 0x88, 0xFF, 0x30, 0x68, 0xB0, 0xF9, 0x54, 0x10, + 0x00, 0x91, 0x3F, 0x49, 0xB0, 0xF9, 0x52, 0x30, 0x60, 0x69, 0x0A, 0x78, + 0x42, 0x49, 0xFF, 0xF7, 0x7C, 0xFF, 0xA8, 0x07, 0x2B, 0xD5, 0x36, 0x68, + 0x41, 0x49, 0xA7, 0x68, 0x96, 0xF8, 0x45, 0x00, 0xDF, 0xF8, 0xF8, 0x90, + 0x00, 0xF0, 0x0F, 0x03, 0xC3, 0xF1, 0x10, 0x0A, 0x00, 0x20, 0xB1, 0xF9, + 0x00, 0xC0, 0x1A, 0xE0, 0xFF, 0xF7, 0x2B, 0xFF, 0xD0, 0xE7, 0x00, 0xBF, + 0x39, 0xF9, 0x10, 0x10, 0xB6, 0xF9, 0x56, 0x80, 0x37, 0xF9, 0x10, 0x20, + 0x88, 0x44, 0x90, 0x45, 0x0B, 0xDB, 0xB6, 0xF9, 0x58, 0x80, 0xA1, 0xEB, + 0x08, 0x08, 0x90, 0x45, 0x05, 0xDC, 0x59, 0x43, 0x02, 0xFB, 0x0A, 0x11, + 0x0A, 0x11, 0x29, 0xF8, 0x10, 0x20, 0x40, 0x1C, 0x00, 0xB2, 0x60, 0x45, + 0xE6, 0xDB, 0xA8, 0x05, 0x05, 0xD5, 0x94, 0xF8, 0x32, 0x10, 0xA0, 0x69, + 0xBD, 0xE8, 0xF8, 0x4F, 0x6D, 0xE7, 0xBD, 0xE8, 0xF8, 0x8F, 0x2D, 0xE9, + 0xF0, 0x43, 0x81, 0x46, 0x26, 0x48, 0x03, 0x78, 0x1B, 0x48, 0x05, 0x2B, + 0x00, 0x68, 0x90, 0xF8, 0x44, 0x20, 0x0C, 0xD0, 0x30, 0xF9, 0x46, 0x5F, + 0x02, 0xF0, 0x0F, 0x03, 0xB0, 0xF9, 0x02, 0x60, 0x17, 0x48, 0xC3, 0xF1, + 0x10, 0x04, 0xB0, 0xF9, 0x00, 0x00, 0x02, 0x46, 0x11, 0xE0, 0x30, 0xF9, + 0x4A, 0x5F, 0x13, 0x09, 0xB0, 0xF9, 0x02, 0x60, 0xF2, 0xE7, 0x00, 0xBF, + 0x31, 0xF9, 0x12, 0x70, 0x39, 0xF9, 0x12, 0xC0, 0x07, 0xEB, 0x05, 0x08, + 0xE0, 0x45, 0x11, 0xDB, 0xBF, 0x1B, 0x67, 0x45, 0x0E, 0xDC, 0x52, 0x1E, + 0xF2, 0xD2, 0x09, 0xE0, 0x31, 0xF9, 0x10, 0x20, 0x39, 0xF9, 0x10, 0x50, + 0x5A, 0x43, 0x05, 0xFB, 0x04, 0x22, 0x12, 0x11, 0x21, 0xF8, 0x10, 0x20, + 0x40, 0x1E, 0xF3, 0xD2, 0x5D, 0xE7, 0x00, 0x00, 0xED, 0x06, 0x10, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0xEE, 0x06, 0x10, 0x00, 0xFE, 0x06, 0x10, 0x00, + 0xFC, 0x4A, 0x01, 0x20, 0xF3, 0x06, 0x10, 0x00, 0x1C, 0x07, 0x10, 0x00, + 0x7E, 0x4A, 0x01, 0x20, 0xA8, 0x4A, 0x01, 0x20, 0xF4, 0x4A, 0x01, 0x20, + 0x00, 0x07, 0x10, 0x00, 0xEC, 0x06, 0x10, 0x00, 0x87, 0x48, 0x00, 0x68, + 0x90, 0xF8, 0x90, 0x02, 0x40, 0x07, 0x07, 0xD5, 0x85, 0x48, 0x86, 0x49, + 0xC0, 0x78, 0x09, 0x78, 0x88, 0x42, 0x01, 0xD0, 0x01, 0x20, 0x70, 0x47, + 0x00, 0x20, 0x70, 0x47, 0x7F, 0x48, 0x10, 0xB5, 0x00, 0x68, 0x90, 0xF8, + 0x90, 0x12, 0x89, 0x07, 0x27, 0xD5, 0x7F, 0x49, 0x0A, 0x78, 0x52, 0x1C, + 0xD2, 0xB2, 0x0A, 0x70, 0x90, 0xF8, 0x92, 0x32, 0x93, 0x42, 0x1E, 0xD2, + 0x00, 0x22, 0x0A, 0x70, 0x90, 0xF8, 0x50, 0x12, 0x03, 0x24, 0xC9, 0x07, + 0x03, 0xD1, 0x90, 0xF8, 0x80, 0x02, 0xC0, 0x07, 0x00, 0xD0, 0x0B, 0x24, + 0xEF, 0xF7, 0x36, 0xFE, 0x74, 0x48, 0x01, 0x68, 0x21, 0x43, 0x01, 0x60, + 0xEF, 0xF7, 0x2E, 0xFE, 0x10, 0x21, 0x05, 0x20, 0x02, 0xF0, 0x6F, 0xF9, + 0xBD, 0xE8, 0x10, 0x40, 0x4F, 0xF4, 0x80, 0x71, 0x00, 0x20, 0xEF, 0xF7, + 0x66, 0xBF, 0x10, 0xBD, 0x68, 0x48, 0x6C, 0x49, 0x4F, 0xF0, 0x00, 0x02, + 0x43, 0x78, 0x09, 0x78, 0x0B, 0x43, 0x67, 0x49, 0x08, 0xD1, 0x4B, 0x78, + 0x5B, 0x1C, 0xDB, 0xB2, 0x4B, 0x70, 0x05, 0x2B, 0x03, 0xD9, 0x01, 0x23, + 0x43, 0x70, 0x83, 0x70, 0x4A, 0x70, 0x70, 0x47, 0x2D, 0xE9, 0xF3, 0x4F, + 0x62, 0x48, 0x00, 0x27, 0xDF, 0xF8, 0x88, 0xA1, 0x90, 0xF8, 0x00, 0x80, + 0x59, 0x48, 0x81, 0xB0, 0x3C, 0x46, 0x00, 0x68, 0xB9, 0x46, 0x90, 0xF8, + 0x90, 0x02, 0xC0, 0x07, 0x1A, 0xD0, 0x00, 0x26, 0x4F, 0xF0, 0x01, 0x0B, + 0x01, 0x9D, 0x12, 0xE0, 0x28, 0x46, 0x02, 0x99, 0x00, 0xF0, 0x32, 0xF8, + 0x10, 0xF0, 0x01, 0x0F, 0x05, 0xD0, 0x0B, 0xFA, 0x06, 0xF0, 0x38, 0x43, + 0x64, 0x1C, 0xC7, 0xB2, 0xE4, 0xB2, 0xBA, 0xF9, 0x00, 0x00, 0x76, 0x1C, + 0x05, 0xEB, 0x40, 0x05, 0x36, 0xB2, 0x46, 0x45, 0xEA, 0xDB, 0x01, 0xE0, + 0x44, 0x46, 0xFF, 0x27, 0x4E, 0x48, 0x07, 0x70, 0x4C, 0xB1, 0x00, 0x94, + 0xBA, 0xF8, 0x00, 0x00, 0x3B, 0x46, 0x82, 0xB2, 0x41, 0x46, 0x01, 0x98, + 0x00, 0xF0, 0x45, 0xF8, 0x07, 0xE0, 0x49, 0x48, 0xB0, 0xF9, 0x00, 0x10, + 0x03, 0x20, 0x02, 0xF0, 0x12, 0xF9, 0x4F, 0xF0, 0x01, 0x09, 0x48, 0x46, + 0xBD, 0xE8, 0xFE, 0x8F, 0x70, 0x47, 0x3D, 0x48, 0x00, 0x21, 0x01, 0x70, + 0x41, 0x70, 0x70, 0x47, 0x70, 0xB5, 0x37, 0x4A, 0x3B, 0x4C, 0x12, 0x68, + 0x24, 0x78, 0xB2, 0xF9, 0x93, 0x32, 0x0C, 0xB1, 0xB2, 0xF9, 0x99, 0x32, + 0x33, 0x4C, 0x64, 0x78, 0x01, 0x2C, 0x02, 0xD0, 0x02, 0x2C, 0x03, 0xD0, + 0x04, 0xE0, 0xB2, 0xF9, 0x95, 0x32, 0x01, 0xE0, 0xB2, 0xF9, 0x97, 0x32, + 0x33, 0x4A, 0x36, 0x4C, 0xB2, 0xF9, 0x00, 0x20, 0x25, 0x78, 0x12, 0xE0, + 0x30, 0xF9, 0x12, 0x40, 0x31, 0xF9, 0x12, 0x60, 0xA4, 0x1B, 0x00, 0xD5, + 0x64, 0x42, 0x24, 0xB2, 0x9C, 0x42, 0x08, 0xDD, 0x92, 0xFB, 0xF5, 0xF6, + 0x05, 0xFB, 0x16, 0x26, 0x1E, 0xB1, 0x2B, 0x48, 0x04, 0x80, 0x00, 0x20, + 0x70, 0xBD, 0x52, 0x1E, 0xEA, 0xD2, 0x01, 0x20, 0x70, 0xBD, 0x2D, 0xE9, + 0xF0, 0x03, 0x06, 0x9F, 0x00, 0x2F, 0x19, 0xD0, 0x01, 0x25, 0x01, 0x2F, + 0x02, 0xD0, 0x14, 0x46, 0xA9, 0x46, 0x2E, 0xE0, 0x00, 0x24, 0x0F, 0xE0, + 0x05, 0xFA, 0x04, 0xF6, 0x1E, 0x42, 0x0A, 0xD0, 0x00, 0x2C, 0x0B, 0xD0, + 0x53, 0x00, 0x62, 0x43, 0xBD, 0xE8, 0xF0, 0x03, 0x00, 0xEB, 0x42, 0x01, + 0x1A, 0x46, 0x06, 0xF0, 0xAA, 0xBC, 0x64, 0x1C, 0x8C, 0x42, 0xED, 0xDB, + 0xBD, 0xE8, 0xF0, 0x03, 0x70, 0x47, 0x00, 0xBF, 0x00, 0x26, 0x00, 0xEB, + 0x44, 0x0C, 0x35, 0x46, 0x0B, 0xE0, 0x00, 0xBF, 0x09, 0xFA, 0x05, 0xF8, + 0x18, 0xEA, 0x03, 0x0F, 0x02, 0xD0, 0xBC, 0xF9, 0x00, 0x80, 0x46, 0x44, + 0x0C, 0xEB, 0x42, 0x0C, 0x6D, 0x1C, 0x8D, 0x42, 0xF2, 0xDB, 0x96, 0xFB, + 0xF7, 0xF5, 0x20, 0xF8, 0x14, 0x50, 0x64, 0x1E, 0xE6, 0xD2, 0xE1, 0xE7, + 0x4C, 0x07, 0x10, 0x00, 0x74, 0x07, 0x10, 0x00, 0xEF, 0x06, 0x10, 0x00, + 0x70, 0x06, 0x10, 0x00, 0x54, 0x07, 0x10, 0x00, 0x74, 0x05, 0x10, 0x00, + 0xF0, 0x06, 0x10, 0x00, 0xFE, 0x06, 0x10, 0x00, 0x75, 0x06, 0x10, 0x00, + 0x7A, 0x06, 0x10, 0x00, 0xEE, 0x06, 0x10, 0x00, 0x10, 0xB5, 0xF6, 0xF7, + 0x3D, 0xFC, 0xF7, 0xF7, 0xC3, 0xF8, 0xBD, 0xE8, 0x10, 0x40, 0xF5, 0xF7, + 0x9F, 0xBB, 0x2D, 0xE9, 0xF0, 0x47, 0x81, 0x46, 0x1F, 0x46, 0x90, 0x46, + 0x0E, 0x46, 0x03, 0x20, 0x08, 0x9D, 0xEF, 0xF7, 0x4C, 0xFF, 0x5C, 0x48, + 0x01, 0x68, 0x48, 0x46, 0xFF, 0xF7, 0x16, 0xFF, 0x04, 0x46, 0x03, 0x20, + 0xEF, 0xF7, 0x5E, 0xFF, 0x64, 0xB1, 0xFF, 0xF7, 0xFB, 0xFE, 0xFF, 0xF7, + 0xC9, 0xFE, 0x31, 0x46, 0x48, 0x46, 0xFF, 0xF7, 0x4F, 0xFF, 0x54, 0x48, + 0x04, 0x70, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x87, 0xFF, 0xF7, 0x49, 0xFF, + 0x16, 0xB1, 0x30, 0x46, 0x00, 0xF0, 0xE8, 0xFC, 0x65, 0xB1, 0x4F, 0x48, + 0x01, 0x78, 0x28, 0x46, 0xF6, 0xF7, 0x31, 0xFC, 0x4D, 0x48, 0x80, 0x78, + 0x20, 0xB1, 0x4D, 0x48, 0x01, 0x68, 0x21, 0xF0, 0x30, 0x01, 0x01, 0x60, + 0x06, 0xF0, 0x6C, 0xFD, 0x05, 0x46, 0xFF, 0xF7, 0x97, 0xFE, 0x50, 0xEA, + 0x05, 0x04, 0xDA, 0xD1, 0x3A, 0x46, 0x41, 0x46, 0x48, 0x46, 0x00, 0xF0, + 0x32, 0xF8, 0x04, 0x46, 0xD3, 0xE7, 0x10, 0xB5, 0xF8, 0xF7, 0x5B, 0xFB, + 0xFD, 0xF7, 0x1F, 0xFF, 0xFB, 0xF7, 0x28, 0xFB, 0xFF, 0xF7, 0xAA, 0xFF, + 0xFF, 0xF7, 0x1D, 0xFF, 0xFC, 0xF7, 0xB3, 0xFA, 0x39, 0x49, 0x00, 0x20, + 0x08, 0x70, 0x48, 0x70, 0x88, 0x80, 0xC8, 0x80, 0x88, 0x70, 0x88, 0x60, + 0xC8, 0x60, 0x08, 0x61, 0x14, 0x31, 0x08, 0x70, 0x88, 0x70, 0x37, 0x48, + 0x00, 0x68, 0x10, 0xF8, 0x30, 0x2F, 0x4A, 0x70, 0x40, 0x78, 0xC8, 0x70, + 0x10, 0xBD, 0x10, 0xB5, 0xF8, 0xF7, 0x47, 0xFB, 0xFD, 0xF7, 0x10, 0xFF, + 0x00, 0xF0, 0x15, 0xFD, 0xF7, 0xF7, 0x5D, 0xF8, 0x2C, 0x48, 0x00, 0x21, + 0x41, 0x70, 0x81, 0x70, 0x10, 0xBD, 0xF8, 0xB5, 0x07, 0x46, 0x00, 0x24, + 0x15, 0x46, 0x0E, 0x46, 0x8D, 0xF8, 0x00, 0x40, 0x02, 0x20, 0xEF, 0xF7, + 0xD8, 0xFE, 0x2A, 0x46, 0x31, 0x46, 0x38, 0x46, 0xF8, 0xF7, 0x4F, 0xFA, + 0x25, 0x49, 0x01, 0x28, 0xCA, 0x78, 0x60, 0xF3, 0x03, 0x02, 0xCA, 0x70, + 0x2A, 0xD0, 0x02, 0x28, 0x2D, 0xD0, 0x03, 0x28, 0x2E, 0xD0, 0x04, 0x28, + 0x00, 0xD0, 0x01, 0x24, 0x6B, 0x46, 0x2A, 0x46, 0x31, 0x46, 0x38, 0x46, + 0xFC, 0xF7, 0xAE, 0xF9, 0x40, 0xEA, 0x04, 0x05, 0x02, 0x20, 0xEF, 0xF7, + 0xD5, 0xFE, 0x9D, 0xF8, 0x00, 0x00, 0x98, 0xB1, 0xEF, 0xF7, 0x94, 0xFC, + 0x17, 0x48, 0x18, 0x4A, 0x01, 0x68, 0x12, 0x68, 0x11, 0x43, 0x01, 0x60, + 0xEF, 0xF7, 0x8A, 0xFC, 0x15, 0x48, 0x01, 0x78, 0x05, 0x20, 0x01, 0xF0, + 0xCA, 0xFF, 0x4F, 0xF4, 0x80, 0x71, 0x00, 0x20, 0xEF, 0xF7, 0xC3, 0xFD, + 0x28, 0x46, 0xF8, 0xBD, 0xFD, 0xF7, 0xA4, 0xFE, 0xFB, 0xF7, 0xD9, 0xFA, + 0xD6, 0xE7, 0xFD, 0xF7, 0x5E, 0xFC, 0x01, 0xE0, 0xF7, 0xF7, 0x47, 0xFB, + 0xFB, 0xF7, 0xFD, 0xFA, 0xCE, 0xE7, 0x00, 0x00, 0x1C, 0x07, 0x10, 0x00, + 0x74, 0x06, 0x10, 0x00, 0x79, 0x07, 0x10, 0x00, 0x74, 0x07, 0x10, 0x00, + 0x04, 0x07, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x0A, 0x44, 0x01, 0x20, + 0x54, 0x07, 0x10, 0x00, 0x30, 0x06, 0x10, 0x00, 0x2C, 0x06, 0x10, 0x00, + 0x06, 0x28, 0x08, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x07, 0x03, 0x03, 0x03, + 0x05, 0x05, 0x01, 0x20, 0x70, 0x47, 0x02, 0x20, 0x70, 0x47, 0x00, 0x20, + 0x70, 0x47, 0x10, 0xB5, 0x04, 0x46, 0x08, 0x46, 0xFF, 0xF7, 0xEE, 0xFF, + 0xA8, 0x4A, 0x01, 0x21, 0x81, 0x40, 0x12, 0x68, 0x11, 0x42, 0x09, 0xD1, + 0x02, 0x28, 0x07, 0xDC, 0xA5, 0x49, 0x51, 0xF8, 0x20, 0x10, 0x21, 0x60, + 0xA4, 0x49, 0x41, 0xF8, 0x20, 0x40, 0x10, 0xBD, 0x00, 0x20, 0x20, 0x60, + 0x21, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x48, 0x20, 0x01, 0xF0, 0x2D, 0xBD, + 0x70, 0xB5, 0x04, 0x46, 0x08, 0x46, 0xFF, 0xF7, 0xD1, 0xFF, 0x00, 0x25, + 0x88, 0xB1, 0x02, 0x28, 0x0F, 0xDC, 0x99, 0x4A, 0x21, 0x68, 0x52, 0xF8, + 0x20, 0x20, 0x91, 0x42, 0x09, 0xD1, 0x95, 0x49, 0x01, 0x22, 0x82, 0x40, + 0x0B, 0x68, 0x93, 0x43, 0x0B, 0x60, 0x94, 0x49, 0x41, 0xF8, 0x20, 0x50, + 0x03, 0xE0, 0x21, 0x46, 0x49, 0x20, 0x01, 0xF0, 0x10, 0xFD, 0x25, 0x60, + 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x01, 0x24, 0x8B, 0x4E, 0x8D, 0x4F, + 0x4F, 0xF0, 0x00, 0x08, 0x25, 0x46, 0x00, 0xBF, 0x31, 0x68, 0x05, 0xFA, + 0x04, 0xF0, 0x08, 0x42, 0x08, 0xD0, 0x81, 0x43, 0x31, 0x60, 0x57, 0xF8, + 0x24, 0x10, 0x4A, 0x20, 0x01, 0xF0, 0xF9, 0xFC, 0x47, 0xF8, 0x24, 0x80, + 0x64, 0x1C, 0x02, 0x2C, 0xEE, 0xDD, 0xBD, 0xE8, 0xF0, 0x81, 0x2D, 0xE9, + 0xF0, 0x41, 0x80, 0x4D, 0x0A, 0x46, 0x00, 0x27, 0x0C, 0x35, 0x7C, 0x4B, + 0x7E, 0x4C, 0x05, 0xF1, 0x14, 0x06, 0x03, 0xF1, 0x08, 0x01, 0x07, 0x60, + 0x01, 0x2A, 0x63, 0xD0, 0x02, 0x2A, 0x39, 0xD0, 0x03, 0x2A, 0x6A, 0xD1, + 0x5F, 0xF0, 0x00, 0x02, 0x11, 0xF8, 0x02, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, + 0x10, 0xD1, 0x01, 0xEB, 0x02, 0x0C, 0x9C, 0xF8, 0x01, 0xE0, 0xBE, 0xF1, + 0x00, 0x0F, 0x09, 0xD1, 0x9C, 0xF8, 0x02, 0xE0, 0xBE, 0xF1, 0x00, 0x0F, + 0x04, 0xD1, 0x9C, 0xF8, 0x03, 0xE0, 0xBE, 0xF1, 0x00, 0x0F, 0x0B, 0xD0, + 0x02, 0xF1, 0x04, 0x0C, 0x52, 0x1C, 0xBC, 0xF1, 0x05, 0x0F, 0xE3, 0xDB, + 0x59, 0x68, 0x04, 0x29, 0x47, 0xD3, 0x01, 0x46, 0x4C, 0x20, 0x48, 0xE0, + 0x73, 0x27, 0x57, 0x43, 0x04, 0xEB, 0xC7, 0x04, 0x04, 0x60, 0x45, 0xF8, + 0x22, 0x40, 0x46, 0xF8, 0x22, 0x00, 0x03, 0x20, 0x88, 0x54, 0x11, 0x44, + 0x48, 0x70, 0x8C, 0xF8, 0x02, 0x00, 0x8C, 0xF8, 0x03, 0x00, 0x58, 0x68, + 0x00, 0x1F, 0x45, 0xE0, 0x5F, 0xF0, 0x00, 0x02, 0x11, 0xF8, 0x02, 0xC0, + 0xBC, 0xF1, 0x00, 0x0F, 0x06, 0xD1, 0x01, 0xEB, 0x02, 0x0C, 0x9C, 0xF8, + 0x01, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x09, 0xD0, 0x02, 0xF1, 0x02, 0x0C, + 0x52, 0x1C, 0xBC, 0xF1, 0x05, 0x0F, 0xED, 0xDB, 0x59, 0x68, 0x02, 0x29, + 0xD1, 0xD2, 0x18, 0xE0, 0x73, 0x27, 0x57, 0x43, 0x04, 0xEB, 0xC7, 0x04, + 0x04, 0x60, 0x45, 0xF8, 0x22, 0x40, 0x46, 0xF8, 0x22, 0x00, 0x02, 0x20, + 0x88, 0x54, 0x11, 0x44, 0x48, 0x70, 0x58, 0x68, 0x80, 0x1E, 0x1D, 0xE0, + 0x5F, 0xF0, 0x04, 0x02, 0x11, 0xF8, 0x02, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, + 0x09, 0xD0, 0x52, 0x1E, 0xF8, 0xD2, 0x00, 0x2F, 0x13, 0xD1, 0x01, 0x46, + 0x4B, 0x20, 0xBD, 0xE8, 0xF0, 0x41, 0x01, 0xF0, 0x6E, 0xBC, 0x73, 0x27, + 0x57, 0x43, 0x04, 0xEB, 0xC7, 0x04, 0x04, 0x60, 0x45, 0xF8, 0x22, 0x40, + 0x46, 0xF8, 0x22, 0x00, 0x01, 0x20, 0x88, 0x54, 0x58, 0x68, 0x40, 0x1E, + 0x58, 0x60, 0x6A, 0xE7, 0xF0, 0xB4, 0x37, 0x4D, 0x34, 0x4C, 0x00, 0x22, + 0x04, 0x23, 0x0C, 0x35, 0x06, 0x68, 0x08, 0x34, 0x55, 0xF8, 0x23, 0x70, + 0xB7, 0x42, 0x14, 0xD1, 0xE7, 0x5C, 0x8F, 0x42, 0x11, 0xD1, 0x5A, 0x1C, + 0x13, 0xD0, 0x00, 0x22, 0x02, 0x60, 0x45, 0xF8, 0x23, 0x20, 0x2D, 0x4D, + 0x20, 0x35, 0x01, 0x29, 0x45, 0xF8, 0x23, 0x20, 0xE2, 0x54, 0x11, 0xD0, + 0x02, 0x29, 0x11, 0xD0, 0x03, 0x29, 0x04, 0xD1, 0x08, 0xE0, 0x5B, 0x1E, + 0xE4, 0xD2, 0x00, 0x2A, 0x08, 0xD1, 0xF0, 0xBC, 0x01, 0x46, 0x4D, 0x20, + 0x01, 0xF0, 0x35, 0xBC, 0xE0, 0x18, 0x42, 0x70, 0x82, 0x70, 0xC2, 0x70, + 0xF0, 0xBC, 0x70, 0x47, 0xE0, 0x18, 0x42, 0x70, 0xFA, 0xE7, 0x2D, 0xE9, + 0xF0, 0x41, 0x1D, 0x4E, 0x1A, 0x4F, 0x0C, 0x36, 0x05, 0x24, 0x06, 0xF1, + 0x14, 0x05, 0x08, 0x37, 0x0D, 0xE0, 0x00, 0xBF, 0x56, 0xF8, 0x24, 0x00, + 0x48, 0xB1, 0x55, 0xF8, 0x24, 0x10, 0x4E, 0x20, 0x01, 0xF0, 0x19, 0xFC, + 0x39, 0x5D, 0x55, 0xF8, 0x24, 0x00, 0xFF, 0xF7, 0xB5, 0xFF, 0x64, 0x1E, + 0xF0, 0xD2, 0x1C, 0xE7, 0x30, 0xB5, 0x0E, 0x4A, 0x01, 0x20, 0x01, 0x46, + 0x0E, 0x4B, 0x10, 0x60, 0x5F, 0xF0, 0x00, 0x00, 0x43, 0xF8, 0x21, 0x00, + 0x49, 0x1C, 0x02, 0x29, 0xFA, 0xDD, 0x05, 0x21, 0x09, 0x4C, 0x51, 0x60, + 0x0C, 0x34, 0x06, 0x4A, 0x04, 0x21, 0x08, 0x32, 0x04, 0xF1, 0x14, 0x03, + 0x44, 0xF8, 0x21, 0x00, 0x50, 0x54, 0x43, 0xF8, 0x21, 0x00, 0x49, 0x1E, + 0xF8, 0xD2, 0x30, 0xBD, 0xB0, 0x06, 0x10, 0x00, 0x3C, 0x7A, 0x01, 0x00, + 0x9C, 0x4E, 0x10, 0x00, 0xD4, 0x56, 0x10, 0x00, 0x73, 0x49, 0x00, 0x20, + 0x74, 0x4B, 0x08, 0x70, 0x72, 0x49, 0x01, 0x22, 0x88, 0x60, 0xC8, 0x60, + 0x08, 0x70, 0x1A, 0x70, 0xC1, 0xF8, 0x01, 0x00, 0x70, 0x47, 0xFE, 0xB5, + 0x6F, 0x4C, 0x6E, 0x4D, 0x70, 0x4F, 0x22, 0x68, 0xB2, 0xF8, 0x7A, 0x14, + 0xAD, 0xF8, 0x04, 0x10, 0xB2, 0xF8, 0x7C, 0x14, 0xAD, 0xF8, 0x06, 0x10, + 0xB2, 0xF8, 0x7E, 0x14, 0xAD, 0xF8, 0x08, 0x10, 0xB2, 0xF8, 0x80, 0x14, + 0xAD, 0xF8, 0x0A, 0x10, 0x66, 0x49, 0x03, 0x68, 0x0B, 0x60, 0x43, 0x68, + 0x4B, 0x60, 0x29, 0x78, 0x00, 0x91, 0x92, 0xF8, 0x82, 0x14, 0xB7, 0xF9, + 0x00, 0x20, 0x01, 0xF0, 0x0F, 0x03, 0x01, 0x46, 0x5F, 0x48, 0x08, 0x30, + 0x03, 0xF0, 0x0C, 0xFA, 0x00, 0x26, 0x2E, 0x70, 0x03, 0x20, 0xEF, 0xF7, + 0xDA, 0xFC, 0x5B, 0x49, 0xB7, 0xF9, 0x00, 0x30, 0x08, 0x31, 0x5B, 0x4A, + 0x01, 0xF1, 0x08, 0x00, 0x03, 0xF0, 0xF1, 0xF9, 0x03, 0x20, 0xEF, 0xF7, + 0xE9, 0xFC, 0x55, 0x48, 0x01, 0xA9, 0x10, 0x30, 0x00, 0xF0, 0x27, 0xF8, + 0x4E, 0x49, 0x4F, 0x4D, 0xC0, 0xB1, 0x01, 0x26, 0x0E, 0x70, 0x21, 0x68, + 0x91, 0xF8, 0x60, 0x14, 0x89, 0x07, 0x12, 0xD5, 0x04, 0x46, 0x00, 0x90, + 0x04, 0x21, 0x68, 0x46, 0xF0, 0xF7, 0x23, 0xFA, 0xC0, 0xB2, 0x01, 0x28, + 0x02, 0xD9, 0xA8, 0x68, 0x10, 0xB1, 0x04, 0x46, 0x20, 0x46, 0x04, 0xE0, + 0x28, 0x78, 0x86, 0x40, 0x34, 0x43, 0xF9, 0xE7, 0x0E, 0x70, 0xA9, 0x68, + 0x00, 0xF0, 0x43, 0xF8, 0xA9, 0x68, 0x88, 0x42, 0x02, 0xD0, 0xA8, 0x60, + 0x01, 0xF0, 0xA4, 0xFD, 0xFE, 0xBD, 0x2D, 0xE9, 0xFC, 0x43, 0x04, 0x46, + 0x00, 0x20, 0x89, 0x46, 0xDF, 0xF8, 0xEC, 0xC0, 0x80, 0x46, 0x6E, 0x46, + 0x00, 0x90, 0x03, 0x46, 0x02, 0x46, 0x01, 0x21, 0xCD, 0xF8, 0x04, 0x00, + 0xDC, 0xF8, 0x00, 0x50, 0x95, 0xF8, 0x61, 0x74, 0x01, 0xFA, 0x02, 0xF5, + 0x2F, 0x42, 0x05, 0xD0, 0x34, 0xF8, 0x13, 0x50, 0x5B, 0x1C, 0x26, 0xF8, + 0x12, 0x50, 0x1B, 0xB2, 0x52, 0x1C, 0x12, 0xB2, 0x04, 0x2A, 0xED, 0xDB, + 0x2F, 0x4B, 0x34, 0x46, 0x00, 0x22, 0x2A, 0x4E, 0xB3, 0xF9, 0x00, 0x50, + 0x0F, 0xE0, 0x00, 0xBF, 0x34, 0xF9, 0x12, 0x30, 0x39, 0xF9, 0x12, 0x70, + 0xBB, 0x42, 0x06, 0xDD, 0x01, 0xFA, 0x02, 0xF7, 0x38, 0x43, 0x43, 0x45, + 0x01, 0xDD, 0x98, 0x46, 0x32, 0x70, 0x52, 0x1C, 0x12, 0xB2, 0xAA, 0x42, + 0xEE, 0xDB, 0xBD, 0xE8, 0xFC, 0x83, 0x2D, 0xE9, 0xF0, 0x43, 0x1D, 0x4F, + 0x89, 0x46, 0x00, 0x22, 0xF9, 0x68, 0x4F, 0xF0, 0x01, 0x08, 0x80, 0xEA, + 0x01, 0x04, 0x1B, 0x49, 0x7B, 0x1C, 0x0D, 0x68, 0x1B, 0x49, 0xB1, 0xF9, + 0x00, 0x60, 0x1B, 0xE0, 0x08, 0xFA, 0x02, 0xF1, 0x21, 0x42, 0x0A, 0xD0, + 0x95, 0xF8, 0x83, 0xC4, 0x01, 0x42, 0x02, 0xD0, 0x0C, 0xF0, 0x0F, 0x0C, + 0x01, 0xE0, 0x4F, 0xEA, 0x1C, 0x1C, 0x03, 0xF8, 0x02, 0xC0, 0x13, 0xF9, + 0x02, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x0D, 0xD0, 0x03, 0xDD, 0xAC, 0xF1, + 0x01, 0x0C, 0x03, 0xF8, 0x02, 0xC0, 0x02, 0xF1, 0x01, 0x02, 0x12, 0xB2, + 0xB2, 0x42, 0xE1, 0xDB, 0xF8, 0x60, 0x48, 0x46, 0xBD, 0xE8, 0xF0, 0x83, + 0x01, 0x42, 0x02, 0xD0, 0x41, 0xEA, 0x09, 0x09, 0xF1, 0xE7, 0x29, 0xEA, + 0x01, 0x09, 0xEE, 0xE7, 0x2C, 0x07, 0x10, 0x00, 0xC0, 0x06, 0x10, 0x00, + 0x7B, 0x07, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x9A, 0x1C, 0x01, 0x20, + 0x00, 0x07, 0x10, 0x00, 0xF4, 0x4A, 0x01, 0x20, 0xF0, 0xB5, 0x06, 0x46, + 0xF8, 0x48, 0x00, 0x24, 0xA7, 0xB0, 0x00, 0x78, 0x0D, 0x46, 0x01, 0x28, + 0x00, 0xD1, 0x01, 0x24, 0x98, 0x21, 0x68, 0x46, 0x06, 0xF0, 0xC4, 0xF9, + 0xF3, 0x4A, 0x00, 0x21, 0x68, 0x46, 0x13, 0x78, 0x11, 0xE0, 0x00, 0xBF, + 0x01, 0xFB, 0x03, 0xF7, 0x22, 0x46, 0x09, 0xE0, 0x07, 0xEB, 0x02, 0x0E, + 0x50, 0xF8, 0x22, 0xC0, 0x36, 0xF9, 0x1E, 0xE0, 0xF4, 0x44, 0x40, 0xF8, + 0x22, 0xC0, 0x52, 0x1C, 0x9A, 0x42, 0xF3, 0xDB, 0x49, 0x1C, 0xA9, 0x42, + 0xEC, 0xDB, 0x21, 0x46, 0x07, 0xE0, 0x00, 0xBF, 0x50, 0xF8, 0x21, 0x20, + 0x92, 0xFB, 0xF5, 0xF2, 0x40, 0xF8, 0x21, 0x20, 0x49, 0x1C, 0x99, 0x42, + 0xF6, 0xDB, 0x00, 0x21, 0x17, 0xE0, 0x00, 0x27, 0x3A, 0x46, 0x0C, 0xE0, + 0x02, 0xFB, 0x03, 0x4C, 0x50, 0xF8, 0x24, 0xE0, 0x36, 0xF9, 0x1C, 0xC0, + 0xBC, 0xEB, 0x0E, 0x0C, 0x01, 0xD5, 0xCC, 0xF1, 0x00, 0x0C, 0x67, 0x44, + 0x52, 0x1C, 0xAA, 0x42, 0xF0, 0xDB, 0x97, 0xFB, 0xF5, 0xF2, 0x8A, 0x42, + 0x00, 0xDD, 0x11, 0x46, 0x64, 0x1C, 0x9C, 0x42, 0xE5, 0xDB, 0xB1, 0xF5, + 0x80, 0x3F, 0x03, 0xDB, 0x4F, 0xF6, 0xFF, 0x70, 0x27, 0xB0, 0xF0, 0xBD, + 0x88, 0xB2, 0xFB, 0xE7, 0xF0, 0xB5, 0xCF, 0x49, 0xCF, 0x4B, 0x09, 0x68, + 0x91, 0xF8, 0xA0, 0x22, 0xD2, 0x07, 0x34, 0xD0, 0xCD, 0x4A, 0x57, 0x78, + 0x4F, 0xB1, 0x91, 0xF8, 0xAB, 0x42, 0xB1, 0xF8, 0xA8, 0x52, 0x04, 0xF0, + 0x0F, 0x02, 0x26, 0x09, 0xB1, 0xF8, 0xA6, 0x42, 0x08, 0xE0, 0x91, 0xF8, + 0xAA, 0x42, 0xB1, 0xF8, 0xA4, 0x52, 0x04, 0xF0, 0x0F, 0x02, 0x26, 0x09, + 0xB1, 0xF8, 0xA2, 0x42, 0xDF, 0xF8, 0x0C, 0xC3, 0x9C, 0xF8, 0x00, 0xC0, + 0xBC, 0xF1, 0x03, 0x0F, 0x06, 0xD1, 0x91, 0xF8, 0xAC, 0x12, 0x0F, 0xB1, + 0x0A, 0x09, 0x01, 0xE0, 0x01, 0xF0, 0x0F, 0x02, 0xA0, 0x42, 0x01, 0xDC, + 0x1A, 0x60, 0xF0, 0xBD, 0xA8, 0x42, 0x01, 0xDB, 0x1E, 0x60, 0xF0, 0xBD, + 0x00, 0x1B, 0xB1, 0x1A, 0x48, 0x43, 0x29, 0x1B, 0x90, 0xFB, 0xF1, 0xF0, + 0x10, 0x44, 0x18, 0x60, 0xF0, 0xBD, 0x00, 0x20, 0xFB, 0xE7, 0xB0, 0x48, + 0xB1, 0x49, 0x00, 0x68, 0x0A, 0x78, 0x00, 0xF5, 0xF9, 0x70, 0x80, 0x5C, + 0xC8, 0x70, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x0F, 0x83, 0x46, 0xAA, 0x48, + 0xDF, 0xF8, 0xAC, 0x92, 0xDF, 0xF8, 0xB0, 0xA2, 0x01, 0x68, 0x99, 0xF8, + 0x00, 0x70, 0x00, 0x20, 0x91, 0xF8, 0x0A, 0x62, 0x91, 0xF8, 0x09, 0x12, + 0x3A, 0xF8, 0x17, 0x40, 0x6F, 0xF0, 0x00, 0x42, 0x4F, 0xEA, 0x11, 0x18, + 0x0B, 0x07, 0x1C, 0xD0, 0x01, 0xF0, 0x0F, 0x05, 0x9E, 0x4B, 0x00, 0x21, + 0x8C, 0x46, 0x1B, 0x68, 0xB4, 0x42, 0x93, 0xF8, 0x08, 0x32, 0x05, 0xDB, + 0xA6, 0x1B, 0x06, 0xFB, 0x08, 0xF6, 0x96, 0xFB, 0xF5, 0xF5, 0x2B, 0x44, + 0x97, 0x4D, 0x99, 0xF8, 0x01, 0x60, 0x2D, 0x68, 0x01, 0x2E, 0x95, 0xF8, + 0xF1, 0x51, 0x06, 0xD0, 0x02, 0x2E, 0x07, 0xD0, 0x05, 0xF0, 0x03, 0x06, + 0x13, 0xE0, 0x01, 0x25, 0xE2, 0xE7, 0xC5, 0xF3, 0x81, 0x06, 0x0E, 0xE0, + 0xC5, 0xF3, 0x01, 0x16, 0x0B, 0xE0, 0x00, 0xBF, 0x3A, 0xF8, 0x1C, 0x50, + 0xAA, 0x42, 0x01, 0xDD, 0x2A, 0x46, 0x60, 0x46, 0xA9, 0x42, 0x00, 0xDA, + 0x29, 0x46, 0x0C, 0xF1, 0x01, 0x0C, 0xB4, 0x45, 0xF2, 0xDD, 0xAB, 0xF8, + 0x00, 0x10, 0xA1, 0x1A, 0x99, 0x42, 0x01, 0xDC, 0xB7, 0x42, 0x04, 0xDD, + 0x89, 0xF8, 0x00, 0x00, 0xBD, 0xE8, 0xF0, 0x0F, 0x9F, 0xE7, 0xBD, 0xE8, + 0xF0, 0x0F, 0x70, 0x47, 0x83, 0x49, 0x10, 0xB5, 0x0B, 0x78, 0x7D, 0x49, + 0x00, 0x22, 0x01, 0x2B, 0x09, 0x68, 0x02, 0xD1, 0x80, 0x4B, 0x1B, 0x78, + 0x4B, 0xB1, 0xB1, 0xF8, 0xFC, 0x31, 0x83, 0x42, 0x18, 0xD2, 0x91, 0xF8, + 0xF0, 0x31, 0x1B, 0x07, 0x14, 0xD5, 0x03, 0x22, 0x25, 0xE0, 0xB1, 0xF8, + 0x02, 0x32, 0x83, 0x42, 0x03, 0xD2, 0x91, 0xF8, 0xF0, 0x31, 0x1B, 0x07, + 0xF5, 0xD4, 0xB1, 0xF8, 0x00, 0x32, 0x83, 0x42, 0x03, 0xD2, 0x91, 0xF8, + 0xF0, 0x31, 0x5B, 0x07, 0x0A, 0xD4, 0xB1, 0xF8, 0xFE, 0x31, 0x0B, 0xE0, + 0xB1, 0xF8, 0xFA, 0x31, 0x83, 0x42, 0x05, 0xD2, 0x91, 0xF8, 0xF0, 0x31, + 0x5B, 0x07, 0x01, 0xD5, 0x02, 0x22, 0x08, 0xE0, 0xB1, 0xF8, 0xF8, 0x31, + 0x83, 0x42, 0x04, 0xD2, 0x91, 0xF8, 0xF0, 0x01, 0x80, 0x07, 0x00, 0xD5, + 0x01, 0x22, 0x65, 0x48, 0x62, 0x4C, 0x14, 0x38, 0x03, 0x78, 0x9A, 0x42, + 0x11, 0xD1, 0x61, 0x78, 0x99, 0x42, 0x1A, 0xD0, 0x63, 0x4A, 0x12, 0x78, + 0x13, 0x43, 0x07, 0xD0, 0x81, 0x68, 0x49, 0x1E, 0x81, 0x60, 0x00, 0x29, + 0x11, 0xDC, 0x00, 0x78, 0x60, 0x70, 0x0E, 0xE0, 0x01, 0x70, 0x81, 0x68, + 0xF7, 0xE7, 0x8A, 0xB1, 0x02, 0x2A, 0x01, 0xD1, 0x01, 0x2B, 0x0D, 0xD0, + 0x91, 0xF8, 0xF6, 0x11, 0x81, 0x60, 0x02, 0x70, 0x00, 0x29, 0x00, 0xDC, + 0x62, 0x70, 0x57, 0x48, 0x62, 0x78, 0x41, 0x7B, 0x62, 0xF3, 0x03, 0x01, + 0x41, 0x73, 0x10, 0xBD, 0x91, 0xF8, 0xF7, 0x11, 0xF0, 0xE7, 0x4A, 0x4A, + 0x12, 0x68, 0x92, 0xF8, 0xF0, 0x21, 0xD2, 0x06, 0x07, 0xD5, 0x42, 0x1A, + 0x00, 0x2A, 0x04, 0xDC, 0xC1, 0xEB, 0xC1, 0x11, 0x08, 0x44, 0xC0, 0xF3, + 0xCF, 0x10, 0x70, 0x47, 0x44, 0x49, 0x00, 0x20, 0x41, 0x4A, 0x48, 0x70, + 0x44, 0x49, 0x14, 0x39, 0x48, 0x60, 0x88, 0x60, 0x08, 0x70, 0x12, 0x68, + 0x92, 0xF8, 0xA0, 0x32, 0xDB, 0x07, 0x03, 0xD0, 0x92, 0xF8, 0xAB, 0x22, + 0x12, 0x09, 0x00, 0xE0, 0x00, 0x22, 0x3A, 0x4B, 0x1A, 0x60, 0xC8, 0x60, + 0x08, 0x61, 0x48, 0x61, 0x88, 0x61, 0x70, 0x47, 0x2D, 0xE9, 0xF8, 0x4F, + 0x00, 0x21, 0xAD, 0xF8, 0x00, 0x10, 0x32, 0x49, 0xDF, 0xF8, 0xD8, 0x90, + 0xDF, 0xF8, 0xD4, 0x80, 0x0D, 0x78, 0x4F, 0xF0, 0x10, 0x0B, 0x2F, 0x01, + 0x06, 0x46, 0x00, 0x24, 0xA9, 0xF1, 0x08, 0x09, 0xA8, 0xF1, 0x14, 0x0A, + 0x10, 0xE0, 0x2A, 0x46, 0x59, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0x5A, 0xFE, + 0x29, 0xF8, 0x14, 0x00, 0x43, 0x46, 0x38, 0xF8, 0x14, 0x10, 0xFF, 0xF7, + 0xB6, 0xFF, 0x23, 0xF8, 0x14, 0x00, 0x06, 0xEB, 0x47, 0x06, 0x64, 0x1C, + 0x9A, 0xF8, 0x01, 0x00, 0x84, 0x42, 0xEA, 0xDD, 0x68, 0x46, 0xFF, 0xF7, + 0xE7, 0xFE, 0x1F, 0x48, 0x20, 0x4D, 0x00, 0x68, 0x90, 0xF8, 0xF0, 0x01, + 0x40, 0x06, 0x02, 0xD5, 0xBD, 0xF8, 0x00, 0x40, 0x02, 0xE0, 0x29, 0x78, + 0x38, 0xF8, 0x11, 0x40, 0x21, 0x48, 0x04, 0x80, 0x20, 0x46, 0xFF, 0xF7, + 0x2F, 0xFF, 0x20, 0x46, 0xFF, 0xF7, 0x8A, 0xFE, 0x29, 0x78, 0x39, 0xF8, + 0x11, 0x00, 0x1B, 0x49, 0xA1, 0xF8, 0x1B, 0x00, 0xBD, 0xE8, 0xF8, 0x8F, + 0x2D, 0xE9, 0xFC, 0x5F, 0x0E, 0x49, 0x4F, 0xF0, 0x00, 0x09, 0x0D, 0x78, + 0x0B, 0x49, 0x09, 0x78, 0x01, 0x29, 0x00, 0xD1, 0x89, 0x46, 0x0F, 0x49, + 0x10, 0x26, 0x14, 0x39, 0x04, 0x46, 0x4A, 0x68, 0x12, 0x48, 0x92, 0xFB, + 0xF6, 0xF3, 0x06, 0xFB, 0x13, 0x22, 0x6A, 0x43, 0x4F, 0x78, 0x4F, 0xEA, + 0x05, 0x1A, 0x00, 0xEB, 0x42, 0x08, 0x83, 0x46, 0x7F, 0x1C, 0x3D, 0xE0, + 0xF3, 0x06, 0x10, 0x00, 0xEE, 0x06, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x9C, 0x06, 0x10, 0x00, 0x74, 0x07, 0x10, 0x00, 0xEC, 0x06, 0x10, 0x00, + 0xE4, 0x06, 0x10, 0x00, 0xF6, 0x06, 0x10, 0x00, 0xF7, 0x06, 0x10, 0x00, + 0xF5, 0x06, 0x10, 0x00, 0x0A, 0x44, 0x01, 0x20, 0x78, 0x06, 0x10, 0x00, + 0xB2, 0x1C, 0x01, 0x20, 0x2A, 0x48, 0x00, 0x68, 0x90, 0xF8, 0xF0, 0x11, + 0x89, 0x06, 0x14, 0xD5, 0x28, 0x49, 0x49, 0x68, 0x00, 0x29, 0x0E, 0xDD, + 0xA5, 0xEB, 0x09, 0x02, 0xB0, 0xF9, 0x06, 0x12, 0xCD, 0xE9, 0x00, 0x12, + 0xB0, 0xF9, 0x04, 0x32, 0x04, 0xEB, 0x49, 0x00, 0x0B, 0xEB, 0x49, 0x02, + 0x01, 0x46, 0x02, 0xF0, 0x9D, 0xFE, 0x0B, 0xEB, 0x4A, 0x0B, 0x6A, 0x00, + 0x21, 0x46, 0x40, 0x46, 0x05, 0xF0, 0x03, 0xFF, 0x04, 0xEB, 0x45, 0x04, + 0x08, 0xEB, 0x4A, 0x08, 0x7F, 0x1E, 0xD9, 0xD2, 0x18, 0x48, 0x4F, 0xF0, + 0xFF, 0x31, 0x01, 0xEB, 0x46, 0x01, 0x42, 0x68, 0x52, 0x1C, 0x42, 0x60, + 0x91, 0x42, 0x00, 0xDA, 0x46, 0x60, 0x40, 0x68, 0xB0, 0x42, 0x03, 0xDB, + 0xBD, 0xE8, 0xFC, 0x5F, 0x11, 0x48, 0x45, 0xE7, 0xBD, 0xE8, 0xFC, 0x9F, + 0x28, 0xE7, 0x10, 0xB5, 0x0C, 0x4C, 0x20, 0x68, 0x90, 0xF8, 0xF1, 0x01, + 0xC0, 0xF3, 0x01, 0x12, 0xC0, 0xF3, 0x81, 0x01, 0x00, 0xF0, 0x03, 0x00, + 0x01, 0xF0, 0x5B, 0xFF, 0x07, 0x49, 0x48, 0x70, 0x20, 0x68, 0x08, 0x49, + 0x90, 0xF8, 0xEC, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x08, 0x70, 0xFF, 0xF7, + 0x36, 0xFE, 0xBD, 0xE8, 0x10, 0x40, 0x0D, 0xE7, 0x4C, 0x07, 0x10, 0x00, + 0xD0, 0x06, 0x10, 0x00, 0xB2, 0x1C, 0x01, 0x20, 0x74, 0x07, 0x10, 0x00, + 0x10, 0xB5, 0xBA, 0x48, 0x00, 0x24, 0x84, 0x61, 0x04, 0x62, 0xC4, 0x61, + 0xFF, 0xF7, 0xB9, 0xFA, 0xFF, 0xF7, 0x6E, 0xFC, 0xB6, 0x48, 0x04, 0x80, + 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x11, 0xB9, 0x10, 0xB5, 0xB4, 0x48, + 0xB1, 0x4C, 0x90, 0xF8, 0x30, 0x10, 0x61, 0x70, 0x90, 0xF8, 0x31, 0x20, + 0xA2, 0x70, 0x51, 0x43, 0x61, 0x82, 0x90, 0xF8, 0x33, 0x10, 0xE1, 0x70, + 0x10, 0xF8, 0x2C, 0x1F, 0x21, 0x70, 0x41, 0x78, 0x21, 0x71, 0x81, 0x78, + 0x61, 0x71, 0xC1, 0x78, 0xA1, 0x71, 0x41, 0x7A, 0xE1, 0x71, 0x80, 0x7A, + 0x20, 0x72, 0xA8, 0x48, 0x60, 0x62, 0x00, 0xF2, 0x3C, 0x60, 0xA0, 0x62, + 0xA0, 0xF6, 0x78, 0x40, 0xE0, 0x62, 0xA5, 0x48, 0x20, 0x63, 0xA5, 0x48, + 0x01, 0x21, 0x00, 0x68, 0x00, 0xF2, 0x61, 0x40, 0xEF, 0xF7, 0xDF, 0xFE, + 0xA0, 0x82, 0x10, 0xBD, 0x9D, 0x48, 0x10, 0xB5, 0x9B, 0x49, 0x90, 0xF8, + 0x2C, 0x00, 0x99, 0x4A, 0x88, 0x70, 0x08, 0x79, 0x53, 0x7A, 0x63, 0xF3, + 0x00, 0x00, 0xD3, 0x7A, 0x63, 0xF3, 0xC3, 0x00, 0x93, 0x7A, 0x63, 0xF3, + 0x82, 0x00, 0x13, 0x7B, 0x63, 0xF3, 0x41, 0x00, 0x97, 0x4B, 0xDB, 0x78, + 0x0B, 0x72, 0x93, 0x7B, 0xCB, 0x71, 0x53, 0x7B, 0xD4, 0x7B, 0x63, 0xF3, + 0x04, 0x10, 0x11, 0xF8, 0x0E, 0x3F, 0x12, 0x7C, 0x64, 0xF3, 0x03, 0x03, + 0x62, 0xF3, 0x07, 0x13, 0x90, 0x4A, 0x01, 0xF8, 0x0B, 0x39, 0x12, 0x78, + 0x81, 0xF8, 0x25, 0x20, 0x8E, 0x4A, 0x12, 0x88, 0xCA, 0x84, 0x8E, 0x4A, + 0x12, 0x78, 0x62, 0xF3, 0xC7, 0x10, 0x48, 0x70, 0x8C, 0x48, 0x00, 0x88, + 0x08, 0x85, 0x8C, 0x48, 0x00, 0x88, 0x48, 0x85, 0x8B, 0x48, 0x02, 0x78, + 0x08, 0x7B, 0x62, 0xF3, 0x03, 0x00, 0x08, 0x73, 0x89, 0x48, 0x02, 0x78, + 0x48, 0x7B, 0x62, 0xF3, 0x00, 0x00, 0x88, 0x4A, 0x12, 0x78, 0x62, 0xF3, + 0x41, 0x00, 0x20, 0xF0, 0x04, 0x00, 0x48, 0x73, 0x10, 0xBD, 0x70, 0xB5, + 0x0D, 0x46, 0x80, 0xEA, 0x05, 0x04, 0xE0, 0x06, 0x01, 0xD5, 0xF6, 0xF7, + 0x89, 0xFA, 0xA0, 0x06, 0x01, 0xD5, 0xF4, 0xF7, 0x65, 0xFD, 0x14, 0xF0, + 0x48, 0x0F, 0x05, 0xD0, 0x6E, 0x48, 0x15, 0xF0, 0x48, 0x01, 0x00, 0xD0, + 0x01, 0x21, 0x41, 0x74, 0x70, 0xBD, 0x70, 0xB5, 0x79, 0x4D, 0x2C, 0x68, + 0x00, 0x2C, 0x0D, 0xD0, 0x68, 0x49, 0xA0, 0xB2, 0x0A, 0x7A, 0xC9, 0x79, + 0x01, 0xF0, 0x44, 0xF9, 0x28, 0x68, 0xA0, 0x43, 0x28, 0x60, 0x03, 0xD1, + 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, 0xB7, 0xB9, 0x70, 0xBD, 0xF8, 0xB5, + 0x00, 0x26, 0x00, 0xF0, 0xC1, 0xFF, 0x01, 0x20, 0xEF, 0xF7, 0xF7, 0xF8, + 0x00, 0xF0, 0x8F, 0xF8, 0x5C, 0x4D, 0x5E, 0x4C, 0x95, 0xF8, 0x20, 0x00, + 0x80, 0x07, 0x02, 0xD5, 0xA0, 0x68, 0xFF, 0xF7, 0xE6, 0xFB, 0x95, 0xF8, + 0x20, 0x00, 0xC0, 0x07, 0x09, 0xD0, 0xE0, 0x68, 0x00, 0x90, 0xD4, 0xE9, + 0x00, 0x01, 0xD4, 0xE9, 0x04, 0x23, 0xFF, 0xF7, 0x8A, 0xF9, 0x06, 0x00, + 0x0A, 0xD1, 0x28, 0x8C, 0x80, 0x05, 0x07, 0xD5, 0x94, 0xF8, 0x32, 0x10, + 0xA0, 0x69, 0xF4, 0xF7, 0xF8, 0xFD, 0xE8, 0x69, 0x18, 0xB9, 0x0C, 0xE0, + 0xE8, 0x69, 0x50, 0xB1, 0x4E, 0xB9, 0x03, 0x20, 0xEF, 0xF7, 0xCD, 0xF8, + 0x4A, 0x48, 0xE9, 0x69, 0xFE, 0xF7, 0x8B, 0xFF, 0x03, 0x20, 0xEF, 0xF7, + 0xE1, 0xF8, 0xFF, 0xF7, 0x51, 0xFF, 0xFF, 0xF7, 0xB0, 0xFF, 0xFF, 0xF7, + 0x6C, 0xFB, 0xFF, 0xF7, 0x88, 0xFA, 0xBD, 0xE8, 0xF8, 0x40, 0x01, 0x20, + 0xEF, 0xF7, 0xD4, 0xB8, 0x3E, 0x48, 0x81, 0x7A, 0x01, 0x29, 0x08, 0xD0, + 0xC1, 0x7A, 0x01, 0x29, 0x05, 0xD0, 0x01, 0x7B, 0x01, 0x29, 0x02, 0xD0, + 0x80, 0x7B, 0x00, 0x28, 0x00, 0xD0, 0x01, 0x20, 0x70, 0x47, 0x08, 0xB5, + 0xFF, 0xF7, 0xF6, 0xFE, 0x6B, 0x46, 0x00, 0x22, 0x03, 0x21, 0x02, 0x20, + 0xEF, 0xF7, 0x0A, 0xF8, 0x00, 0x98, 0xC0, 0x07, 0x05, 0xD0, 0x01, 0x21, + 0x02, 0x20, 0xEE, 0xF7, 0xE6, 0xFF, 0xFF, 0xF7, 0x9A, 0xFF, 0x00, 0x98, + 0x80, 0x07, 0xED, 0xD5, 0x02, 0x21, 0x08, 0x46, 0xEE, 0xF7, 0xDD, 0xFF, + 0xE8, 0xE7, 0x2F, 0x48, 0x10, 0xB5, 0x02, 0x68, 0x28, 0x48, 0x00, 0x24, + 0x92, 0xF8, 0x31, 0x10, 0x41, 0x70, 0x92, 0xF8, 0x30, 0x20, 0x82, 0x70, + 0x51, 0x43, 0x41, 0x82, 0x29, 0x49, 0xC9, 0x78, 0xC1, 0x70, 0x01, 0x21, + 0x01, 0x71, 0x41, 0x71, 0x81, 0x71, 0x01, 0x70, 0x84, 0x82, 0xC4, 0x71, + 0x04, 0x72, 0xC4, 0x73, 0x04, 0x74, 0xFF, 0xF7, 0x62, 0xF9, 0xFF, 0xF7, + 0x5F, 0xFB, 0xFE, 0xF7, 0x9D, 0xFE, 0x43, 0xF6, 0x58, 0x61, 0x29, 0x48, + 0x05, 0xF0, 0xFE, 0xFD, 0x28, 0x48, 0x04, 0x80, 0x28, 0x48, 0x04, 0x80, + 0x10, 0xBD, 0x70, 0xB5, 0x14, 0x4E, 0x16, 0x4D, 0x31, 0x6A, 0x28, 0x6A, + 0x81, 0xEA, 0x00, 0x04, 0x19, 0xB9, 0x10, 0xB1, 0xFF, 0xF7, 0xAA, 0xFE, + 0x11, 0xE0, 0xA0, 0x07, 0x01, 0xD5, 0xFF, 0xF7, 0x43, 0xFB, 0xE0, 0x07, + 0x03, 0xD0, 0xFF, 0xF7, 0x40, 0xF9, 0xFF, 0xF7, 0x7B, 0xFE, 0xE0, 0x06, + 0x01, 0xD5, 0xFF, 0xF7, 0xED, 0xF8, 0xA0, 0x05, 0x01, 0xD5, 0xF4, 0xF7, + 0x61, 0xFD, 0xE9, 0x69, 0xB0, 0x69, 0xFF, 0xF7, 0x1C, 0xFF, 0xE8, 0x69, + 0xB0, 0x61, 0x28, 0x6A, 0x30, 0x62, 0x68, 0x6A, 0xF0, 0x61, 0xBD, 0xE8, + 0x70, 0x40, 0x99, 0xE6, 0xEC, 0x06, 0x10, 0x00, 0x0A, 0x44, 0x01, 0x20, + 0xCC, 0x68, 0x10, 0x00, 0xEE, 0x35, 0x01, 0x20, 0x42, 0x44, 0x01, 0x20, + 0x4C, 0x07, 0x10, 0x00, 0x74, 0x07, 0x10, 0x00, 0x75, 0x06, 0x10, 0x00, + 0x7A, 0x06, 0x10, 0x00, 0x7D, 0x07, 0x10, 0x00, 0x7E, 0x07, 0x10, 0x00, + 0x80, 0x07, 0x10, 0x00, 0x66, 0x05, 0x10, 0x00, 0x64, 0x05, 0x10, 0x00, + 0x74, 0x05, 0x10, 0x00, 0x68, 0x07, 0x10, 0x00, 0x20, 0x4D, 0x01, 0x20, + 0x82, 0x07, 0x10, 0x00, 0x84, 0x07, 0x10, 0x00, 0x0B, 0x4D, 0x00, 0x20, + 0x0B, 0x4C, 0x28, 0x60, 0x28, 0x68, 0x40, 0x1C, 0x28, 0x60, 0xEE, 0xF7, + 0xEB, 0xFD, 0xF0, 0xF7, 0x70, 0xF9, 0x01, 0x28, 0x20, 0x68, 0x06, 0xD0, + 0x40, 0xF0, 0x04, 0x00, 0x20, 0x60, 0xEE, 0xF7, 0xDF, 0xFD, 0x30, 0xBF, + 0xEE, 0xE7, 0x20, 0xF0, 0x04, 0x00, 0xF7, 0xE7, 0x30, 0x07, 0x10, 0x00, + 0x10, 0xED, 0x00, 0xE0, 0x2D, 0xE9, 0xF0, 0x47, 0x1C, 0x4D, 0xDF, 0xF8, + 0x74, 0x90, 0xA8, 0x46, 0x20, 0x21, 0x1A, 0x48, 0x05, 0xF0, 0x82, 0xFD, + 0x18, 0x48, 0x00, 0xF0, 0x53, 0xFB, 0x47, 0x1E, 0xD9, 0xF8, 0x00, 0x00, + 0x98, 0xF8, 0x00, 0x60, 0x08, 0xF1, 0x01, 0x04, 0x90, 0xF8, 0xA0, 0x00, + 0xC0, 0x07, 0x05, 0xD0, 0x3A, 0x46, 0x21, 0x46, 0x30, 0x46, 0x00, 0xF0, + 0x23, 0xF8, 0x28, 0xB9, 0x3A, 0x46, 0x21, 0x46, 0x30, 0x46, 0x00, 0xF0, + 0xD3, 0xF8, 0x18, 0xB1, 0x01, 0x20, 0x29, 0x68, 0x01, 0xF0, 0xF3, 0xF8, + 0x00, 0xF0, 0x50, 0xFB, 0x00, 0x28, 0xD9, 0xD1, 0xBD, 0xE8, 0xF0, 0x87, + 0x38, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0xEE, 0xF7, 0xE6, 0xFE, 0x69, 0x46, + 0x28, 0x46, 0xEE, 0xF7, 0x1C, 0xFF, 0x00, 0x99, 0x21, 0x42, 0xF8, 0xD1, + 0x38, 0xBD, 0x00, 0x00, 0xD0, 0x4E, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x70, 0xB5, 0x0D, 0x46, 0x00, 0x24, 0xA0, 0xF1, 0x10, 0x01, 0x03, 0x29, + 0x01, 0xD8, 0x52, 0x48, 0x05, 0xE0, 0xA0, 0xF1, 0x30, 0x01, 0x0A, 0x29, + 0x06, 0xD8, 0x4F, 0x48, 0x20, 0x30, 0x50, 0xF8, 0x31, 0x30, 0x00, 0xEB, + 0xC1, 0x00, 0x0A, 0xE0, 0x62, 0x28, 0x10, 0xD1, 0x4A, 0x49, 0xA0, 0xF1, + 0x62, 0x00, 0xA1, 0xF1, 0x08, 0x01, 0x51, 0xF8, 0x30, 0x30, 0x01, 0xEB, + 0xC0, 0x00, 0x4F, 0xF0, 0x01, 0x04, 0x40, 0x68, 0x90, 0x42, 0x02, 0xD1, + 0x11, 0x46, 0x28, 0x46, 0x98, 0x47, 0x20, 0x46, 0x70, 0xBD, 0x42, 0x49, + 0x43, 0x20, 0x08, 0x60, 0x04, 0x21, 0x01, 0x20, 0xFF, 0xF7, 0xBE, 0xBF, + 0x3E, 0x49, 0x00, 0x20, 0x08, 0x60, 0x04, 0x21, 0x01, 0x20, 0xFF, 0xF7, + 0xB7, 0xBF, 0xEF, 0xF7, 0x92, 0xBB, 0x10, 0xB5, 0xEE, 0xF7, 0x5C, 0xFD, + 0x39, 0x49, 0x1E, 0x20, 0x08, 0x60, 0xEE, 0xF7, 0x55, 0xFD, 0x02, 0x21, + 0x05, 0x20, 0x01, 0xF0, 0x96, 0xF8, 0xBD, 0xE8, 0x10, 0x40, 0x4F, 0xF4, + 0x80, 0x71, 0x00, 0x20, 0xFF, 0xF7, 0xA2, 0xBF, 0x32, 0x49, 0x02, 0x78, + 0x0A, 0x70, 0x42, 0x78, 0x4A, 0x70, 0x01, 0x78, 0x4B, 0x07, 0x30, 0x49, + 0x0A, 0x68, 0x02, 0xD5, 0x42, 0xF0, 0x04, 0x02, 0x01, 0xE0, 0x22, 0xF0, + 0x04, 0x02, 0x0A, 0x60, 0x02, 0x78, 0x12, 0x07, 0x0A, 0x68, 0x02, 0xD5, + 0x42, 0xF0, 0x02, 0x02, 0x01, 0xE0, 0x22, 0xF0, 0x02, 0x02, 0x0A, 0x60, + 0x02, 0x78, 0xD2, 0x06, 0x0A, 0x68, 0x02, 0xD5, 0x42, 0xF0, 0x01, 0x02, + 0x01, 0xE0, 0x22, 0xF0, 0x01, 0x02, 0x0A, 0x60, 0x00, 0x78, 0x40, 0x06, + 0x02, 0xD5, 0x42, 0xF0, 0x10, 0x00, 0x01, 0xE0, 0x22, 0xF0, 0x10, 0x00, + 0x08, 0x60, 0x08, 0x21, 0x01, 0x20, 0xFF, 0xF7, 0x71, 0xBF, 0x00, 0x78, + 0x28, 0xB1, 0x01, 0x28, 0x05, 0xD1, 0x10, 0x21, 0x01, 0x20, 0xFF, 0xF7, + 0x69, 0xBF, 0x04, 0x21, 0xFA, 0xE7, 0x70, 0x47, 0x02, 0x78, 0x15, 0x48, + 0x01, 0x68, 0x22, 0xB1, 0x01, 0x2A, 0x05, 0xD0, 0x02, 0x2A, 0x08, 0xD1, + 0x0B, 0xE0, 0x21, 0xF0, 0x08, 0x01, 0x01, 0xE0, 0x41, 0xF0, 0x08, 0x01, + 0x21, 0xF0, 0x40, 0x01, 0x01, 0x60, 0x08, 0x21, 0x01, 0x20, 0xFF, 0xF7, + 0x51, 0xBF, 0x21, 0xF0, 0x08, 0x01, 0x41, 0xF0, 0x40, 0x01, 0xF5, 0xE7, + 0x70, 0x47, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47, + 0x70, 0x47, 0x70, 0x47, 0x00, 0xF0, 0x21, 0xBC, 0x50, 0x7A, 0x01, 0x00, + 0x6C, 0x07, 0x10, 0x00, 0x54, 0x07, 0x10, 0x00, 0xF0, 0x4F, 0x10, 0x00, + 0x70, 0x07, 0x10, 0x00, 0x0B, 0x46, 0x10, 0xB5, 0x00, 0x21, 0xA0, 0x38, + 0x09, 0x28, 0x06, 0xD8, 0xF7, 0x49, 0x51, 0xF8, 0x20, 0x40, 0x11, 0x46, + 0x18, 0x46, 0xA0, 0x47, 0x01, 0x46, 0x08, 0x46, 0x10, 0xBD, 0x00, 0x20, + 0x70, 0x47, 0x70, 0xB5, 0x00, 0x23, 0x00, 0x29, 0x11, 0xDD, 0x02, 0x78, + 0x49, 0x1E, 0x03, 0x2A, 0x0D, 0xD2, 0xEE, 0x4D, 0x40, 0x1C, 0x28, 0x35, + 0x55, 0xF8, 0x32, 0x40, 0x05, 0xEB, 0xC2, 0x02, 0x52, 0x68, 0x00, 0x2A, + 0x03, 0xDB, 0x91, 0x42, 0x01, 0xD1, 0xA0, 0x47, 0x03, 0x46, 0x18, 0x46, + 0x70, 0xBD, 0x10, 0xB5, 0x00, 0x78, 0x00, 0x21, 0xC2, 0x07, 0x00, 0xD0, + 0x01, 0x21, 0x82, 0x07, 0x01, 0xD5, 0x41, 0xF0, 0x02, 0x01, 0xC0, 0x06, + 0x01, 0xD5, 0x41, 0xF0, 0x40, 0x01, 0xE0, 0x48, 0x02, 0x68, 0x8A, 0x42, + 0x04, 0xD0, 0x01, 0x60, 0x04, 0x21, 0x01, 0x20, 0xFF, 0xF7, 0xF8, 0xFE, + 0x01, 0x20, 0x10, 0xBD, 0x00, 0x20, 0x70, 0x47, 0x70, 0xB5, 0x00, 0x23, + 0x00, 0x29, 0x0F, 0xDD, 0x02, 0x78, 0x49, 0x1E, 0x05, 0x2A, 0x0B, 0xD2, + 0xD4, 0x4D, 0x40, 0x1C, 0x40, 0x35, 0x55, 0xF8, 0x32, 0x40, 0x05, 0xEB, + 0xC2, 0x02, 0x52, 0x68, 0x91, 0x42, 0x01, 0xD1, 0xA0, 0x47, 0x03, 0x46, + 0x18, 0x46, 0x70, 0xBD, 0x10, 0xB5, 0x00, 0x78, 0xC2, 0x07, 0xCE, 0x48, + 0x01, 0x68, 0x02, 0xD0, 0x41, 0xF0, 0x02, 0x01, 0x01, 0xE0, 0x21, 0xF0, + 0x02, 0x01, 0x01, 0x60, 0x08, 0x21, 0x01, 0x20, 0xFF, 0xF7, 0xCE, 0xFE, + 0x01, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x00, 0x78, 0xC2, 0x07, 0xC5, 0x48, + 0x01, 0x68, 0x02, 0xD0, 0x41, 0xF0, 0x04, 0x01, 0x01, 0xE0, 0x21, 0xF0, + 0x04, 0x01, 0x01, 0x60, 0x08, 0x21, 0x01, 0x20, 0xFF, 0xF7, 0xBC, 0xFE, + 0x01, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x01, 0x78, 0xCB, 0x07, 0xBC, 0x49, + 0x0A, 0x68, 0x02, 0xD0, 0x42, 0xF0, 0x08, 0x02, 0x01, 0xE0, 0x22, 0xF0, + 0x08, 0x02, 0x0A, 0x60, 0x00, 0x78, 0x80, 0x07, 0x02, 0xD5, 0x42, 0xF0, + 0x40, 0x00, 0x01, 0xE0, 0x22, 0xF0, 0x40, 0x00, 0x08, 0x60, 0x08, 0x21, + 0x01, 0x20, 0xFF, 0xF7, 0xA1, 0xFE, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x20, + 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x70, 0xB5, 0x00, 0x23, 0x00, 0x29, + 0x0F, 0xDD, 0x02, 0x78, 0x49, 0x1E, 0x0A, 0x2A, 0x0B, 0xD2, 0xA8, 0x4D, + 0x40, 0x1C, 0x68, 0x35, 0x55, 0xF8, 0x32, 0x40, 0x05, 0xEB, 0xC2, 0x02, + 0x52, 0x68, 0x91, 0x42, 0x01, 0xD1, 0xA0, 0x47, 0x03, 0x46, 0x18, 0x46, + 0x70, 0xBD, 0x01, 0x46, 0x00, 0x20, 0x09, 0x78, 0x04, 0x29, 0x06, 0xD2, + 0x9E, 0x48, 0xB8, 0x30, 0x50, 0xF8, 0x21, 0x20, 0x00, 0x21, 0x08, 0x46, + 0x10, 0x47, 0x70, 0x47, 0x10, 0xB5, 0xEF, 0xF7, 0x52, 0xFA, 0x01, 0x20, + 0x10, 0xBD, 0x10, 0xB5, 0x00, 0xF0, 0x4F, 0xFB, 0x01, 0x20, 0x10, 0xBD, + 0x10, 0xB5, 0x4F, 0xF4, 0x00, 0x61, 0x00, 0x20, 0xFF, 0xF7, 0x68, 0xFE, + 0x01, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x4F, 0xF4, 0x80, 0x51, 0x00, 0x20, + 0xFF, 0xF7, 0x60, 0xFE, 0x01, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x00, 0x78, + 0xC0, 0x07, 0x02, 0xD0, 0x00, 0xF0, 0xD8, 0xFA, 0x01, 0xE0, 0x00, 0xF0, + 0xCC, 0xFA, 0x01, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x00, 0x88, 0x00, 0x24, + 0xC1, 0x07, 0x00, 0xD0, 0x02, 0x24, 0x81, 0x07, 0x01, 0xD5, 0x44, 0xF0, + 0x04, 0x04, 0x41, 0x07, 0x01, 0xD5, 0x44, 0xF0, 0x08, 0x04, 0xC1, 0x06, + 0x01, 0xD5, 0x44, 0xF0, 0x10, 0x04, 0x00, 0x06, 0x01, 0xD5, 0x44, 0xF0, + 0x80, 0x04, 0x94, 0xB1, 0xEE, 0xF7, 0xE4, 0xFB, 0x7E, 0x48, 0x01, 0x68, + 0x21, 0x43, 0x01, 0x60, 0xEE, 0xF7, 0xDC, 0xFB, 0x02, 0x21, 0x05, 0x20, + 0x00, 0xF0, 0x1D, 0xFF, 0x4F, 0xF4, 0x80, 0x71, 0x00, 0x20, 0xFF, 0xF7, + 0x2B, 0xFE, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, 0x10, 0xB5, + 0x00, 0x88, 0x00, 0x24, 0xC1, 0x07, 0x00, 0xD0, 0x01, 0x24, 0x81, 0x07, + 0x01, 0xD5, 0x44, 0xF0, 0x02, 0x04, 0x41, 0x07, 0x01, 0xD5, 0x44, 0xF0, + 0x04, 0x04, 0x01, 0x07, 0x01, 0xD5, 0x44, 0xF0, 0x08, 0x04, 0xC1, 0x05, + 0x01, 0xD5, 0x44, 0xF4, 0x00, 0x74, 0x81, 0x05, 0x01, 0xD5, 0x44, 0xF4, + 0x80, 0x64, 0xC1, 0x06, 0x01, 0xD5, 0x44, 0xF0, 0x10, 0x04, 0x00, 0x06, + 0x01, 0xD5, 0x44, 0xF0, 0x80, 0x04, 0x6C, 0xB1, 0xEE, 0xF7, 0xAC, 0xFB, + 0x63, 0x48, 0x01, 0x68, 0x21, 0x43, 0x01, 0x60, 0xEE, 0xF7, 0xA4, 0xFB, + 0x02, 0x21, 0x00, 0x20, 0xFF, 0xF7, 0xF8, 0xFD, 0x01, 0x20, 0x10, 0xBD, + 0x00, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x00, 0x88, 0x00, 0x24, 0xC1, 0x07, + 0x00, 0xD0, 0x01, 0x24, 0x81, 0x07, 0x01, 0xD5, 0x44, 0xF0, 0x02, 0x04, + 0x41, 0x07, 0x01, 0xD5, 0x44, 0xF0, 0x04, 0x04, 0x01, 0x07, 0x01, 0xD5, + 0x44, 0xF0, 0x08, 0x04, 0xC0, 0x06, 0x01, 0xD5, 0x44, 0xF0, 0x10, 0x04, + 0x74, 0xB1, 0xEE, 0xF7, 0x85, 0xFB, 0x51, 0x48, 0x01, 0x68, 0x21, 0x43, + 0x01, 0x60, 0xEE, 0xF7, 0x7D, 0xFB, 0x4F, 0xF4, 0x00, 0x11, 0x00, 0x20, + 0xFF, 0xF7, 0xD0, 0xFD, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, + 0x10, 0xB5, 0x00, 0x88, 0x00, 0x24, 0xC1, 0x07, 0x00, 0xD0, 0x01, 0x24, + 0x81, 0x07, 0x01, 0xD5, 0x44, 0xF0, 0x02, 0x04, 0x41, 0x07, 0x01, 0xD5, + 0x44, 0xF0, 0x04, 0x04, 0x01, 0x07, 0x01, 0xD5, 0x44, 0xF0, 0x08, 0x04, + 0xC1, 0x06, 0x01, 0xD5, 0x44, 0xF0, 0x10, 0x04, 0x81, 0x06, 0x01, 0xD5, + 0x44, 0xF0, 0x20, 0x04, 0x41, 0x06, 0x01, 0xD5, 0x44, 0xF0, 0x40, 0x04, + 0x01, 0x06, 0x01, 0xD5, 0x44, 0xF0, 0x80, 0x04, 0xC1, 0x05, 0x01, 0xD5, + 0x44, 0xF4, 0x80, 0x74, 0x81, 0x05, 0x01, 0xD5, 0x44, 0xF4, 0x00, 0x74, + 0x40, 0x05, 0x01, 0xD5, 0x44, 0xF4, 0x80, 0x64, 0x6C, 0xB1, 0xEE, 0xF7, + 0x45, 0xFB, 0x32, 0x48, 0x01, 0x68, 0x21, 0x43, 0x01, 0x60, 0xEE, 0xF7, + 0x3D, 0xFB, 0x80, 0x21, 0x00, 0x20, 0xFF, 0xF7, 0x91, 0xFD, 0x01, 0x20, + 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x00, 0x78, 0x00, 0x24, + 0xC1, 0x07, 0x00, 0xD0, 0x01, 0x24, 0x81, 0x07, 0x01, 0xD5, 0x44, 0xF0, + 0x02, 0x04, 0x40, 0x07, 0x01, 0xD5, 0x44, 0xF0, 0x04, 0x04, 0x74, 0xB1, + 0xEE, 0xF7, 0x26, 0xFB, 0x23, 0x48, 0x01, 0x68, 0x21, 0x43, 0x01, 0x60, + 0xEE, 0xF7, 0x1E, 0xFB, 0x4F, 0xF4, 0x80, 0x61, 0x00, 0x20, 0xFF, 0xF7, + 0x71, 0xFD, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, 0x10, 0xB5, + 0x00, 0x78, 0x00, 0x24, 0x31, 0x28, 0x39, 0xD0, 0x10, 0xDC, 0x12, 0x28, + 0x32, 0xD0, 0x06, 0xDC, 0x01, 0x28, 0x1C, 0xD0, 0x10, 0x28, 0x2D, 0xD0, + 0x11, 0x28, 0x31, 0xD1, 0x2A, 0xE0, 0x13, 0x28, 0x28, 0xD0, 0x14, 0x28, + 0x26, 0xD0, 0x30, 0x28, 0x2A, 0xD1, 0x27, 0xE0, 0x51, 0x28, 0x29, 0xD0, + 0x06, 0xDC, 0x32, 0x28, 0x22, 0xD0, 0x33, 0x28, 0x20, 0xD0, 0x50, 0x28, + 0x20, 0xD1, 0x21, 0xE0, 0x52, 0x28, 0x1F, 0xD0, 0x53, 0x28, 0x1D, 0xD0, + 0x54, 0x28, 0x19, 0xD1, 0x1A, 0xE0, 0x00, 0xF0, 0x5B, 0xFC, 0x11, 0xE0, + 0xC8, 0x7A, 0x01, 0x00, 0x6C, 0x07, 0x10, 0x00, 0x70, 0x07, 0x10, 0x00, + 0x54, 0x07, 0x10, 0x00, 0x58, 0x07, 0x10, 0x00, 0x5C, 0x07, 0x10, 0x00, + 0x64, 0x07, 0x10, 0x00, 0x60, 0x07, 0x10, 0x00, 0x00, 0xF0, 0xDC, 0xFC, + 0x01, 0x24, 0x01, 0xE0, 0x00, 0xF0, 0xF8, 0xFC, 0x20, 0x46, 0x10, 0xBD, + 0x00, 0xF0, 0xE2, 0xFC, 0xF6, 0xE7, 0x00, 0x00, 0x08, 0xB5, 0x00, 0xF0, + 0x3B, 0xFC, 0x00, 0xF0, 0xE3, 0xFD, 0x17, 0x4C, 0x6B, 0x46, 0x00, 0x22, + 0x19, 0x21, 0x03, 0x20, 0xEE, 0xF7, 0x4E, 0xFC, 0x00, 0x98, 0xC0, 0x07, + 0x05, 0xD0, 0x01, 0x21, 0x03, 0x20, 0xEE, 0xF7, 0x2A, 0xFC, 0xFF, 0xF7, + 0xE3, 0xFC, 0x00, 0x98, 0x00, 0x07, 0x0B, 0xD5, 0x08, 0x21, 0x03, 0x20, + 0xEE, 0xF7, 0x21, 0xFC, 0x20, 0x68, 0x08, 0x21, 0x40, 0xF0, 0x08, 0x00, + 0x20, 0x60, 0x01, 0x20, 0xFF, 0xF7, 0x02, 0xFD, 0x00, 0x98, 0xC0, 0x06, + 0xDE, 0xD5, 0x10, 0x21, 0x03, 0x20, 0xEE, 0xF7, 0x12, 0xFC, 0x20, 0x68, + 0x08, 0x21, 0x20, 0xF0, 0x08, 0x00, 0x20, 0x60, 0x01, 0x20, 0xFF, 0xF7, + 0xF3, 0xFC, 0xD1, 0xE7, 0x70, 0x07, 0x10, 0x00, 0x1F, 0x48, 0x00, 0x21, + 0x01, 0x70, 0x41, 0x70, 0x81, 0x70, 0x70, 0x47, 0x10, 0xB5, 0x1C, 0x4C, + 0x03, 0x46, 0xA0, 0x78, 0x10, 0x28, 0x14, 0xD2, 0x0F, 0x29, 0x00, 0xD9, + 0x0F, 0x21, 0x19, 0x48, 0x22, 0x78, 0x00, 0xEB, 0x02, 0x10, 0x0A, 0x46, + 0x00, 0xF8, 0x01, 0x1B, 0x19, 0x46, 0x05, 0xF0, 0xB6, 0xF9, 0x20, 0x78, + 0x40, 0x1C, 0x00, 0xF0, 0x0F, 0x00, 0x20, 0x70, 0xA0, 0x78, 0x40, 0x1C, + 0xA0, 0x70, 0x10, 0xBD, 0x70, 0xB5, 0x0E, 0x4C, 0x00, 0x25, 0xA1, 0x78, + 0x91, 0xB1, 0x0D, 0x49, 0x62, 0x78, 0x01, 0xEB, 0x02, 0x11, 0x11, 0xF8, + 0x01, 0x5B, 0x2A, 0x46, 0x05, 0xF0, 0x9F, 0xF9, 0x60, 0x78, 0x40, 0x1C, + 0x00, 0xF0, 0x0F, 0x00, 0x60, 0x70, 0x72, 0xB6, 0xA0, 0x78, 0x40, 0x1E, + 0xA0, 0x70, 0x62, 0xB6, 0x28, 0x46, 0x70, 0xBD, 0x01, 0x48, 0x80, 0x78, + 0x70, 0x47, 0x00, 0x00, 0x34, 0x07, 0x10, 0x00, 0xF0, 0x4E, 0x10, 0x00, + 0x70, 0xB5, 0x14, 0x46, 0x00, 0x20, 0x05, 0xF0, 0xAB, 0xFA, 0x00, 0xF0, + 0x01, 0x05, 0x01, 0x20, 0x05, 0xF0, 0xA6, 0xFA, 0x00, 0xF0, 0x01, 0x00, + 0x45, 0xEA, 0x00, 0x10, 0x20, 0x70, 0x01, 0x20, 0x70, 0xBD, 0x80, 0x20, + 0x10, 0x70, 0x01, 0x20, 0x70, 0x47, 0x10, 0xB5, 0x14, 0x46, 0xEF, 0xF7, + 0x64, 0xF8, 0x53, 0x21, 0x21, 0x70, 0x54, 0x21, 0x61, 0x70, 0x01, 0x0A, + 0xA1, 0x70, 0xE0, 0x70, 0xEF, 0xF7, 0x5F, 0xF8, 0x20, 0x71, 0x05, 0x20, + 0x10, 0xBD, 0x38, 0xB5, 0x14, 0x46, 0x70, 0x4A, 0x13, 0x68, 0x59, 0x8E, + 0x98, 0x8E, 0x93, 0xF8, 0x36, 0x30, 0xDB, 0x07, 0x0A, 0xD0, 0x03, 0x0A, + 0x23, 0x70, 0x60, 0x70, 0x0D, 0x0A, 0xA5, 0x70, 0xE1, 0x70, 0x23, 0x71, + 0x60, 0x71, 0xA5, 0x71, 0xE1, 0x71, 0x09, 0xE0, 0x0B, 0x0A, 0x23, 0x70, + 0x61, 0x70, 0x05, 0x0A, 0xA5, 0x70, 0xE0, 0x70, 0x23, 0x71, 0x61, 0x71, + 0xA5, 0x71, 0xE0, 0x71, 0x10, 0x68, 0x90, 0xF8, 0x31, 0x10, 0x21, 0x72, + 0x10, 0xF8, 0x30, 0x1F, 0x61, 0x72, 0x90, 0xF8, 0x31, 0x04, 0x8D, 0xF8, + 0x00, 0x00, 0x01, 0x21, 0x68, 0x46, 0xEF, 0xF7, 0x8E, 0xF9, 0xA0, 0x72, + 0x0B, 0x20, 0x38, 0xBD, 0xA2, 0x20, 0x10, 0x70, 0x33, 0x20, 0x50, 0x70, + 0x00, 0x20, 0x90, 0x70, 0xD0, 0x70, 0x10, 0x71, 0x50, 0x71, 0x06, 0x20, + 0x70, 0x47, 0x08, 0xB5, 0x02, 0x23, 0x00, 0x93, 0x52, 0x4B, 0x00, 0xF0, + 0x8D, 0xF8, 0x02, 0x20, 0x08, 0xBD, 0x08, 0xB5, 0x01, 0x23, 0x00, 0x93, + 0x4E, 0x4B, 0x9B, 0x1C, 0x00, 0xF0, 0x84, 0xF8, 0x01, 0x20, 0x08, 0xBD, + 0x08, 0xB5, 0x01, 0x23, 0x00, 0x93, 0x4A, 0x4B, 0xDB, 0x1C, 0x00, 0xF0, + 0x7B, 0xF8, 0x01, 0x20, 0x08, 0xBD, 0x08, 0xB5, 0x01, 0x23, 0x00, 0x93, + 0x45, 0x4B, 0x1B, 0x1D, 0x00, 0xF0, 0x72, 0xF8, 0x01, 0x20, 0x08, 0xBD, + 0x08, 0xB5, 0x01, 0x23, 0x00, 0x93, 0x41, 0x4B, 0x5B, 0x1D, 0x00, 0xF0, + 0x69, 0xF8, 0x01, 0x20, 0x08, 0xBD, 0x08, 0xB5, 0x01, 0x23, 0x00, 0x93, + 0x3C, 0x4B, 0x9B, 0x1D, 0x00, 0xF0, 0x60, 0xF8, 0x01, 0x20, 0x08, 0xBD, + 0x08, 0xB5, 0x02, 0x23, 0x00, 0x93, 0x38, 0x4B, 0xDB, 0x1D, 0x00, 0xF0, + 0x57, 0xF8, 0x02, 0x20, 0x08, 0xBD, 0x08, 0xB5, 0x02, 0x23, 0x00, 0x93, + 0x33, 0x4B, 0x09, 0x33, 0x00, 0xF0, 0x4E, 0xF8, 0x02, 0x20, 0x08, 0xBD, + 0x08, 0xB5, 0x01, 0x23, 0x00, 0x93, 0x2F, 0x4B, 0x0B, 0x33, 0x00, 0xF0, + 0x45, 0xF8, 0x01, 0x20, 0x08, 0xBD, 0x08, 0xB5, 0x01, 0x23, 0x00, 0x93, + 0x2A, 0x4B, 0x0C, 0x33, 0x00, 0xF0, 0x3C, 0xF8, 0x01, 0x20, 0x08, 0xBD, + 0x08, 0xB5, 0x01, 0x23, 0x00, 0x93, 0x26, 0x4B, 0x0D, 0x33, 0x00, 0xF0, + 0x33, 0xF8, 0x01, 0x20, 0x08, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x0F, 0x46, + 0x04, 0x46, 0x00, 0x78, 0x49, 0x1E, 0xCE, 0xB2, 0x00, 0x25, 0x63, 0x1C, + 0xA0, 0xF1, 0x20, 0x01, 0x04, 0x29, 0x09, 0xD8, 0x1D, 0x49, 0x01, 0xEB, + 0x80, 0x00, 0x31, 0x46, 0x50, 0xF8, 0x80, 0x4C, 0x18, 0x46, 0xA0, 0x47, + 0x05, 0x46, 0x16, 0xE0, 0xA0, 0xF1, 0x30, 0x01, 0x0B, 0x29, 0x12, 0xD8, + 0x16, 0x49, 0x14, 0x31, 0x01, 0xEB, 0x80, 0x00, 0x31, 0x46, 0x50, 0xF8, + 0xC0, 0x5C, 0x18, 0x46, 0xA8, 0x47, 0x05, 0x46, 0x3E, 0xB1, 0x39, 0x46, + 0x20, 0x46, 0xFF, 0xF7, 0xD5, 0xFE, 0x01, 0x21, 0x03, 0x20, 0xEE, 0xF7, + 0xA6, 0xFA, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x70, 0xB5, 0x1D, 0x46, + 0x04, 0x9C, 0x16, 0x46, 0x39, 0xB1, 0xA1, 0x42, 0x00, 0xD9, 0x21, 0x46, + 0x0A, 0x46, 0x01, 0x46, 0x18, 0x46, 0x05, 0xF0, 0x8A, 0xF8, 0x22, 0x46, + 0x29, 0x46, 0x30, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x05, 0xF0, 0x83, 0xB8, + 0x4C, 0x07, 0x10, 0x00, 0xF0, 0x4F, 0x10, 0x00, 0x90, 0x7B, 0x01, 0x00, + 0x10, 0xB5, 0x4F, 0xF4, 0x86, 0x71, 0x46, 0x48, 0x05, 0xF0, 0x18, 0xF9, + 0x44, 0x49, 0x01, 0x20, 0xC1, 0xF8, 0x04, 0x01, 0x43, 0x49, 0x00, 0x20, + 0x08, 0x70, 0x05, 0xF0, 0xA1, 0xF9, 0x00, 0x21, 0xBD, 0xE8, 0x10, 0x40, + 0x01, 0x20, 0xEF, 0xF7, 0x20, 0xB9, 0x10, 0xB5, 0x72, 0xB6, 0x00, 0x20, + 0x3C, 0x49, 0x08, 0x70, 0x05, 0xF0, 0x94, 0xF9, 0x62, 0xB6, 0x10, 0xBD, + 0x10, 0xB5, 0x72, 0xB6, 0x01, 0x20, 0x38, 0x49, 0x08, 0x70, 0x36, 0x48, + 0xD0, 0xF8, 0x08, 0x01, 0x08, 0xB1, 0x05, 0xF0, 0x2B, 0xF9, 0x62, 0xB6, + 0x10, 0xBD, 0x10, 0xB5, 0x72, 0xB6, 0x31, 0x49, 0xD1, 0xF8, 0x08, 0x31, + 0xD1, 0xF8, 0x00, 0x21, 0x20, 0x2B, 0x07, 0xD2, 0x5B, 0x1C, 0x52, 0x1C, + 0x22, 0xF0, 0x20, 0x02, 0xC1, 0xF8, 0x08, 0x31, 0xC1, 0xF8, 0x00, 0x21, + 0x01, 0xEB, 0xC2, 0x02, 0x03, 0x68, 0x13, 0x60, 0x40, 0x68, 0x50, 0x60, + 0x27, 0x48, 0x00, 0x78, 0x01, 0x28, 0x05, 0xD1, 0xD1, 0xF8, 0x08, 0x01, + 0x01, 0x28, 0x01, 0xD1, 0x05, 0xF0, 0x08, 0xF9, 0x62, 0xB6, 0x10, 0xBD, + 0x20, 0x4A, 0xD2, 0xF8, 0x08, 0x01, 0x00, 0x28, 0x0E, 0xD0, 0xD2, 0xF8, + 0x04, 0x01, 0x02, 0xEB, 0xC0, 0x00, 0xC3, 0x79, 0x23, 0xF0, 0x3F, 0x03, + 0xC3, 0x71, 0x92, 0xF8, 0x08, 0x21, 0x52, 0x1E, 0x02, 0xF0, 0x3F, 0x02, + 0x13, 0x43, 0xC3, 0x71, 0x70, 0x47, 0x10, 0xB5, 0x72, 0xB6, 0x15, 0x48, + 0xD0, 0xF8, 0x08, 0x11, 0x59, 0xB1, 0x49, 0x1E, 0xC0, 0xF8, 0x08, 0x11, + 0xD0, 0xF8, 0x04, 0x21, 0x02, 0xF1, 0x01, 0x02, 0x22, 0xF0, 0x20, 0x02, + 0xC0, 0xF8, 0x04, 0x21, 0x05, 0xD1, 0x0E, 0x48, 0x00, 0x78, 0x01, 0x28, + 0x01, 0xD1, 0x05, 0xF0, 0x35, 0xF9, 0x62, 0xB6, 0x10, 0xBD, 0x10, 0xB5, + 0x72, 0xB6, 0x00, 0x21, 0x07, 0x48, 0xC0, 0xF8, 0x08, 0x11, 0xC0, 0xF8, + 0x00, 0x11, 0x01, 0x21, 0xC0, 0xF8, 0x04, 0x11, 0x04, 0x48, 0x00, 0x78, + 0x01, 0x28, 0x01, 0xD1, 0x05, 0xF0, 0x22, 0xF9, 0x62, 0xB6, 0x10, 0xBD, + 0x68, 0x42, 0x01, 0x20, 0x37, 0x07, 0x10, 0x00, 0x18, 0x49, 0x00, 0x22, + 0x0A, 0x80, 0x4A, 0x80, 0x4F, 0xF4, 0x70, 0x42, 0x8A, 0x80, 0x16, 0x4A, + 0xCA, 0x80, 0x16, 0x4A, 0x0A, 0x81, 0x16, 0x4A, 0xC0, 0xE9, 0x00, 0x21, + 0x05, 0x21, 0x01, 0x72, 0x70, 0x47, 0x1C, 0xB5, 0x12, 0x49, 0xAD, 0xF8, + 0x04, 0x00, 0x02, 0x20, 0x8D, 0xF8, 0x06, 0x00, 0x04, 0x20, 0x09, 0x1F, + 0x8D, 0xF8, 0x07, 0x00, 0x00, 0x91, 0x68, 0x46, 0xEF, 0xF7, 0x4B, 0xF9, + 0x1C, 0xBD, 0x30, 0xB4, 0x03, 0x46, 0x0A, 0x4A, 0x00, 0x20, 0x14, 0x78, + 0x9C, 0x42, 0x02, 0xD1, 0x30, 0xBC, 0xEF, 0xF7, 0x76, 0xB9, 0x40, 0x1C, + 0xC0, 0xB2, 0x52, 0x1D, 0x05, 0x28, 0xF4, 0xD3, 0x30, 0xBC, 0x70, 0x47, + 0xFE, 0x4F, 0x10, 0x00, 0x14, 0xA6, 0x01, 0x20, 0x6C, 0xA2, 0x01, 0x20, + 0xD4, 0x7B, 0x01, 0x00, 0x10, 0xB5, 0x88, 0xB3, 0xA3, 0x49, 0xA4, 0x4A, + 0x09, 0x78, 0x37, 0x29, 0x71, 0xD0, 0x11, 0xDC, 0xA1, 0xF1, 0x20, 0x01, + 0x17, 0x29, 0x2C, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0x6B, 0x6B, 0x6B, 0x6B, + 0x6B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, + 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x00, 0x97, 0x4B, 0x70, 0x29, + 0x5B, 0x78, 0x26, 0xD0, 0x0C, 0xDC, 0x3B, 0x29, 0x57, 0xD0, 0x04, 0xDC, + 0x38, 0x29, 0x54, 0xD0, 0x3A, 0x29, 0x12, 0xD1, 0x51, 0xE0, 0x60, 0x29, + 0x19, 0xD0, 0x61, 0x29, 0x0D, 0xD1, 0x16, 0xE0, 0x73, 0x29, 0x28, 0xD0, + 0x05, 0xDC, 0x71, 0x29, 0x15, 0xD0, 0x72, 0x29, 0x05, 0xD1, 0x14, 0xE0, + 0x0B, 0xE0, 0x85, 0x29, 0x0B, 0xD0, 0x86, 0x29, 0x09, 0xD0, 0xC1, 0xB2, + 0x87, 0x48, 0xFF, 0xF7, 0xA9, 0xFD, 0x01, 0x21, 0x03, 0x20, 0xEE, 0xF7, + 0x7A, 0xF9, 0x00, 0x20, 0x10, 0xBD, 0x02, 0x20, 0x10, 0xBD, 0x93, 0x70, + 0xF9, 0xE7, 0xD3, 0x70, 0xF7, 0xE7, 0x90, 0x78, 0x01, 0x28, 0x08, 0xD0, + 0x00, 0x28, 0xF2, 0xD1, 0x7F, 0x48, 0x81, 0xB2, 0x5F, 0xF0, 0x72, 0x00, + 0xFF, 0xF7, 0x93, 0xFF, 0xEB, 0xE7, 0x7D, 0x48, 0xF7, 0xE7, 0xD0, 0x78, + 0x01, 0x28, 0x05, 0xD0, 0x00, 0x28, 0xE4, 0xD1, 0x7A, 0x48, 0x81, 0xB2, + 0x73, 0x20, 0xF1, 0xE7, 0x79, 0x4C, 0x7A, 0x49, 0x20, 0x68, 0x90, 0xF8, + 0x31, 0x00, 0x42, 0x00, 0x71, 0x48, 0x10, 0x30, 0x04, 0xF0, 0x45, 0xFF, + 0x20, 0x68, 0x10, 0xF8, 0x30, 0x1F, 0x4A, 0x00, 0x6D, 0x49, 0x40, 0x78, + 0x10, 0x31, 0x01, 0xEB, 0x40, 0x00, 0x72, 0x49, 0x04, 0xF0, 0x39, 0xFF, + 0x69, 0x48, 0x10, 0x30, 0xE3, 0xE7, 0xC1, 0xB2, 0x52, 0x68, 0x67, 0x48, + 0xFF, 0xF7, 0x69, 0xFE, 0x6D, 0x49, 0x08, 0x70, 0x01, 0x20, 0x10, 0xBD, + 0x2D, 0xE9, 0xF0, 0x5F, 0xDF, 0xF8, 0x88, 0xB1, 0x62, 0x4E, 0x62, 0x4D, + 0x89, 0x46, 0x07, 0x46, 0x4F, 0xF0, 0x01, 0x0A, 0xAB, 0xF1, 0x10, 0x0B, + 0x08, 0x36, 0x28, 0x78, 0xA8, 0x46, 0x04, 0x46, 0x07, 0x28, 0x76, 0xD2, + 0xDF, 0xE8, 0x00, 0xF0, 0x04, 0x21, 0x25, 0x40, 0x5C, 0x78, 0x8A, 0x00, + 0x01, 0x2F, 0x02, 0xD0, 0x02, 0x2F, 0x0C, 0xD0, 0x6B, 0xE0, 0x48, 0x46, + 0xFF, 0xF7, 0x5E, 0xFF, 0x02, 0x28, 0x02, 0xD0, 0x01, 0x28, 0x02, 0xD0, + 0x63, 0xE0, 0x03, 0x24, 0x61, 0xE0, 0x02, 0x24, 0x5F, 0xE0, 0x68, 0x78, + 0x01, 0x28, 0x04, 0xD0, 0x4D, 0x48, 0x10, 0x21, 0x10, 0x38, 0x04, 0xF0, + 0x7B, 0xFF, 0x54, 0x46, 0x86, 0xF8, 0x00, 0xA0, 0x53, 0xE0, 0x02, 0x2F, + 0x4F, 0xD0, 0x00, 0x24, 0x39, 0xE0, 0x02, 0x2F, 0x1A, 0xD1, 0x4E, 0x4C, + 0x45, 0x48, 0xD8, 0xF8, 0x04, 0x10, 0x22, 0x78, 0x10, 0x38, 0x04, 0xF0, + 0xEA, 0xFE, 0x03, 0x20, 0x30, 0x70, 0x20, 0x78, 0xB0, 0x80, 0x98, 0xF8, + 0x00, 0x00, 0x04, 0x24, 0x88, 0xF8, 0x01, 0x00, 0x88, 0xF8, 0x00, 0x40, + 0x27, 0xE0, 0x00, 0x24, 0x88, 0xF8, 0x01, 0x00, 0x2C, 0x70, 0xB8, 0xE7, + 0x02, 0x2F, 0x02, 0xD0, 0x01, 0x2F, 0xF6, 0xD0, 0x2F, 0xE0, 0xFF, 0xF7, + 0xA3, 0xFE, 0x08, 0x21, 0x28, 0xB1, 0x02, 0x22, 0x32, 0x70, 0x70, 0x80, + 0xB1, 0x80, 0x05, 0x24, 0x25, 0xE0, 0x68, 0x78, 0x06, 0x28, 0x04, 0xD0, + 0x00, 0x22, 0xCB, 0xF8, 0x00, 0x20, 0xCB, 0xF8, 0x04, 0x20, 0x03, 0x20, + 0x30, 0x70, 0xB1, 0x80, 0x06, 0x24, 0x18, 0xE0, 0x02, 0x2F, 0x08, 0xD0, + 0x02, 0x24, 0xC0, 0xB2, 0x88, 0xF8, 0x01, 0x00, 0x2C, 0x70, 0x29, 0x48, + 0x08, 0x30, 0xBD, 0xE8, 0xF0, 0x9F, 0x68, 0x78, 0x04, 0x28, 0x08, 0xD0, + 0x0B, 0xEB, 0x09, 0x00, 0x49, 0x46, 0x10, 0xF8, 0x01, 0x2C, 0x22, 0x48, + 0x10, 0x38, 0x04, 0xF0, 0x1D, 0xFF, 0x86, 0xF8, 0x00, 0xA0, 0xA8, 0x46, + 0x28, 0x78, 0xE7, 0xE7, 0x02, 0x2F, 0x05, 0xD0, 0xB9, 0xF1, 0x08, 0x0F, + 0x93, 0xD1, 0xFF, 0xF7, 0x80, 0xFE, 0x90, 0xE7, 0xFF, 0xF7, 0x7D, 0xFE, + 0x98, 0xF8, 0x00, 0x00, 0x03, 0x24, 0x88, 0xF8, 0x01, 0x00, 0x88, 0xF8, + 0x00, 0x40, 0x6E, 0xE7, 0x02, 0x2F, 0x4F, 0xF0, 0x03, 0x04, 0xAD, 0xD0, + 0xCF, 0xE7, 0x13, 0x49, 0x00, 0x22, 0x0A, 0x70, 0x4A, 0x70, 0x18, 0x4A, + 0x52, 0x1C, 0x4A, 0x60, 0x17, 0x49, 0x01, 0x60, 0x0D, 0x49, 0x10, 0x39, + 0x81, 0x80, 0x10, 0x31, 0xC1, 0x80, 0x10, 0x21, 0x01, 0x81, 0x0E, 0x21, + 0x13, 0x48, 0x04, 0xF0, 0xF5, 0xBE, 0x10, 0xB5, 0x04, 0x46, 0x04, 0xF0, + 0xA5, 0xFF, 0x06, 0x48, 0x21, 0x68, 0x10, 0x38, 0x01, 0x60, 0x61, 0x68, + 0x41, 0x60, 0x0E, 0x48, 0xFF, 0xF7, 0x91, 0xFE, 0xBD, 0xE8, 0x10, 0x40, + 0x04, 0xF0, 0x3C, 0xBF, 0x84, 0x43, 0x01, 0x20, 0x38, 0x07, 0x10, 0x00, + 0x14, 0xA6, 0x01, 0x20, 0xEE, 0x35, 0x01, 0x20, 0x6C, 0xA2, 0x01, 0x20, + 0x4C, 0x07, 0x10, 0x00, 0x94, 0x0B, 0x01, 0x20, 0xBE, 0x0B, 0x01, 0x20, + 0x08, 0x50, 0x10, 0x00, 0xB1, 0x22, 0x01, 0x00, 0xF0, 0x4F, 0x10, 0x00, + 0x74, 0x43, 0x00, 0x00, 0x70, 0xB5, 0x04, 0x4D, 0x38, 0x21, 0x28, 0x46, + 0x2C, 0x88, 0x04, 0xF0, 0xC5, 0xFE, 0x64, 0x1C, 0x2C, 0x80, 0x70, 0xBD, + 0x0A, 0x44, 0x01, 0x20, 0x37, 0x48, 0x00, 0x21, 0x01, 0x60, 0x41, 0x60, + 0x70, 0x47, 0xC0, 0xB2, 0x01, 0x22, 0x00, 0xF0, 0x48, 0xFA, 0xFE, 0xE7, + 0x34, 0x4C, 0x00, 0x25, 0x32, 0x4F, 0xC4, 0xE9, 0x02, 0x25, 0xC4, 0xE9, + 0x00, 0x71, 0x06, 0x46, 0x00, 0x68, 0x20, 0x61, 0x70, 0x68, 0x60, 0x61, + 0xB0, 0x68, 0xA0, 0x61, 0xF0, 0x68, 0xE0, 0x61, 0x30, 0x69, 0x20, 0x62, + 0x70, 0x69, 0x60, 0x62, 0xB0, 0x69, 0xA0, 0x62, 0xF0, 0x69, 0xE0, 0x62, + 0x29, 0x48, 0x90, 0x46, 0x89, 0x46, 0x00, 0x68, 0x20, 0x63, 0x27, 0x48, + 0x10, 0x38, 0x00, 0x68, 0x60, 0x63, 0x25, 0x48, 0x0C, 0x38, 0x00, 0x68, + 0xA0, 0x63, 0x23, 0x48, 0x08, 0x38, 0x00, 0x68, 0xE0, 0x63, 0x21, 0x48, + 0x00, 0x1D, 0x00, 0x68, 0x20, 0x64, 0x1F, 0x48, 0x34, 0x38, 0x00, 0x68, + 0x60, 0x64, 0x1D, 0x48, 0x14, 0x38, 0x00, 0x68, 0xC4, 0xE9, 0x12, 0x05, + 0xEE, 0xF7, 0x9B, 0xF9, 0x20, 0x65, 0xC4, 0xE9, 0x15, 0x65, 0xE5, 0x65, + 0x25, 0x66, 0x65, 0x66, 0xA5, 0x66, 0xE5, 0x66, 0x25, 0x67, 0x65, 0x67, + 0xC4, 0xE9, 0x1E, 0x57, 0x41, 0x46, 0x48, 0x46, 0xFF, 0xF7, 0xB3, 0xFF, + 0x10, 0xB5, 0x04, 0x46, 0xC0, 0xB2, 0x00, 0x22, 0x00, 0xF0, 0xF9, 0xF9, + 0x0F, 0x49, 0x08, 0x68, 0x08, 0x28, 0x03, 0xDA, 0x09, 0x4A, 0x14, 0x54, + 0x40, 0x1C, 0x08, 0x60, 0x10, 0xBD, 0x01, 0x28, 0x06, 0xD0, 0x02, 0x28, + 0x08, 0xD1, 0x00, 0x22, 0x11, 0x46, 0x13, 0x20, 0x00, 0xF0, 0xE7, 0xB9, + 0x00, 0x22, 0x11, 0x46, 0x12, 0x20, 0xF9, 0xE7, 0x70, 0x47, 0x00, 0x00, + 0x70, 0xEF, 0x01, 0x20, 0xAF, 0x05, 0x50, 0xFA, 0x80, 0xEF, 0x01, 0x20, + 0x38, 0xED, 0x00, 0xE0, 0x48, 0x07, 0x10, 0x00, 0x2D, 0xE9, 0xF0, 0x41, + 0x40, 0xF2, 0x02, 0x71, 0xB9, 0x48, 0x04, 0xF0, 0x3F, 0xFE, 0xB8, 0x4C, + 0x01, 0x26, 0x00, 0x25, 0x66, 0x70, 0xA5, 0x80, 0xA5, 0x71, 0x02, 0x20, + 0xE0, 0x71, 0xEE, 0xF7, 0xAC, 0xFC, 0x20, 0x81, 0xEE, 0xF7, 0xA5, 0xFC, + 0x07, 0x02, 0xEE, 0xF7, 0xA2, 0xFC, 0x47, 0xEA, 0x10, 0x20, 0x60, 0x81, + 0x4A, 0xF2, 0x33, 0x20, 0x20, 0x82, 0x30, 0x02, 0x60, 0x82, 0xAD, 0x48, + 0x00, 0x68, 0x41, 0x8A, 0xA1, 0x82, 0x01, 0x8A, 0xE1, 0x82, 0xC1, 0x8A, + 0x21, 0x83, 0x81, 0x8A, 0x61, 0x83, 0x90, 0xF8, 0xDE, 0x10, 0x21, 0x77, + 0xA7, 0x49, 0x09, 0x68, 0x09, 0x7E, 0x61, 0x77, 0x90, 0xF8, 0xA0, 0x10, + 0x01, 0xF0, 0x01, 0x01, 0xA1, 0x77, 0x81, 0x69, 0x21, 0x63, 0xC1, 0x69, + 0x61, 0x63, 0xA5, 0x63, 0xE5, 0x63, 0xA4, 0xF8, 0x40, 0x50, 0x84, 0xF8, + 0x42, 0x50, 0x84, 0xF8, 0x43, 0x60, 0x41, 0x8E, 0xA4, 0xF8, 0x50, 0x10, + 0x81, 0x8E, 0xA4, 0xF8, 0x52, 0x10, 0x90, 0xF8, 0x31, 0x10, 0x84, 0xF8, + 0x54, 0x10, 0x90, 0xF8, 0x30, 0x10, 0x84, 0xF8, 0x55, 0x10, 0x01, 0x21, + 0x00, 0xF2, 0x61, 0x40, 0xEE, 0xF7, 0xC9, 0xFD, 0x84, 0xF8, 0x56, 0x00, + 0x93, 0x48, 0xA4, 0xF8, 0x80, 0x00, 0x93, 0x48, 0xA4, 0xF8, 0x88, 0x00, + 0x92, 0x48, 0xA4, 0xF8, 0x8A, 0x00, 0x92, 0x48, 0xA4, 0xF8, 0x8C, 0x00, + 0x91, 0x48, 0xA4, 0xF8, 0x8E, 0x00, 0x91, 0x48, 0xA4, 0xF8, 0x90, 0x00, + 0x90, 0x48, 0xA4, 0xF8, 0x92, 0x00, 0x90, 0x48, 0xA4, 0xF8, 0x94, 0x00, + 0x8F, 0x48, 0xA4, 0xF8, 0x96, 0x00, 0x8F, 0x48, 0xA4, 0xF8, 0x98, 0x00, + 0x8E, 0x48, 0xA4, 0xF8, 0x9A, 0x00, 0x8E, 0x48, 0xA4, 0xF8, 0x9C, 0x00, + 0x8D, 0x48, 0xA4, 0xF8, 0x9E, 0x00, 0x8D, 0x48, 0xA4, 0xF8, 0xA0, 0x00, + 0x8C, 0x48, 0xA4, 0xF8, 0xA2, 0x00, 0x8C, 0x48, 0xA4, 0xF8, 0xA4, 0x00, + 0x8C, 0x49, 0x8B, 0x48, 0xA4, 0xF8, 0xA6, 0x00, 0x48, 0x88, 0x40, 0x1C, + 0x48, 0x80, 0xA5, 0x22, 0x22, 0x70, 0x66, 0x70, 0x60, 0x80, 0x0E, 0x70, + 0xBD, 0xE8, 0xF0, 0x81, 0x70, 0xB5, 0x85, 0x4C, 0x05, 0x46, 0x00, 0x23, + 0x60, 0x88, 0x6F, 0x49, 0x40, 0x1C, 0x82, 0xB2, 0x62, 0x80, 0x28, 0x46, + 0x01, 0xF0, 0x80, 0xFA, 0x25, 0x70, 0x70, 0xBD, 0x70, 0xB5, 0x05, 0x46, + 0x40, 0xF2, 0x02, 0x71, 0x68, 0x48, 0x04, 0xF0, 0x9D, 0xFD, 0x7B, 0x4C, + 0x66, 0x49, 0x60, 0x88, 0x40, 0x1C, 0x82, 0xB2, 0x62, 0x80, 0x28, 0x46, + 0x01, 0xF0, 0xA6, 0xFA, 0x25, 0x70, 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, + 0x74, 0x4C, 0x05, 0x46, 0x20, 0x78, 0xA8, 0x42, 0x04, 0xD0, 0x40, 0xF2, + 0x02, 0x71, 0x5D, 0x48, 0x04, 0xF0, 0x86, 0xFD, 0x70, 0x49, 0x65, 0x70, + 0x0F, 0x20, 0x08, 0x60, 0x5A, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x61, 0x24, + 0x0A, 0xB1, 0x1F, 0x22, 0x0A, 0x60, 0x56, 0x49, 0x55, 0x4D, 0x10, 0x31, + 0x61, 0x60, 0x38, 0x21, 0x29, 0x71, 0x05, 0xF1, 0x48, 0x03, 0xA3, 0x60, + 0x90, 0xF8, 0x31, 0x20, 0x90, 0xF8, 0x30, 0x60, 0x6A, 0x71, 0x02, 0xFB, + 0x06, 0xF1, 0x03, 0xEB, 0x41, 0x07, 0xAE, 0x71, 0xE7, 0x60, 0xEA, 0x71, + 0x11, 0x44, 0x03, 0xEB, 0x41, 0x02, 0x22, 0x61, 0x31, 0x44, 0x2E, 0x72, + 0x03, 0xEB, 0x41, 0x01, 0x61, 0x61, 0x01, 0x21, 0x00, 0xF2, 0x61, 0x40, + 0xEE, 0xF7, 0x2F, 0xFD, 0x68, 0x72, 0xA1, 0xE7, 0x2D, 0xE9, 0xF0, 0x41, + 0x05, 0x46, 0x56, 0x4C, 0x17, 0x46, 0x88, 0x46, 0xC0, 0x07, 0x04, 0xD0, + 0x38, 0x22, 0x42, 0x49, 0x60, 0x68, 0x04, 0xF0, 0xCA, 0xFC, 0x3E, 0x4E, + 0xA8, 0x07, 0x12, 0xD5, 0x31, 0x68, 0x91, 0xF8, 0x31, 0x00, 0x91, 0xF8, + 0x30, 0x10, 0x48, 0x43, 0x61, 0x78, 0x30, 0x29, 0x3E, 0xD0, 0x31, 0x29, + 0x3E, 0xD0, 0x32, 0x29, 0x42, 0xD0, 0x3B, 0x49, 0xA3, 0x68, 0x42, 0x00, + 0x18, 0x46, 0x04, 0xF0, 0xB4, 0xFC, 0x68, 0x07, 0x0E, 0xD5, 0x30, 0x68, + 0x90, 0xF8, 0x31, 0x20, 0x60, 0x78, 0x30, 0x28, 0x36, 0xD0, 0x31, 0x28, + 0x36, 0xD0, 0x32, 0x28, 0x39, 0xD0, 0x36, 0x49, 0x52, 0x00, 0xE0, 0x68, + 0x04, 0xF0, 0xA3, 0xFC, 0x28, 0x07, 0x0F, 0xD5, 0x30, 0x68, 0x61, 0x78, + 0x90, 0xF8, 0x30, 0x00, 0x30, 0x29, 0x2E, 0xD0, 0x31, 0x29, 0x2E, 0xD0, + 0x32, 0x29, 0x31, 0xD0, 0x31, 0x49, 0x23, 0x69, 0x42, 0x00, 0x18, 0x46, + 0x04, 0xF0, 0x91, 0xFC, 0xE8, 0x06, 0x31, 0xD5, 0x1F, 0x48, 0x42, 0x7A, + 0x60, 0x78, 0x30, 0x28, 0x26, 0xD0, 0x31, 0x28, 0x26, 0xD0, 0x32, 0x28, + 0x26, 0xD0, 0x2D, 0x49, 0x60, 0x69, 0xBD, 0xE8, 0xF0, 0x41, 0x52, 0x00, + 0x04, 0xF0, 0x7F, 0xBC, 0x1B, 0x49, 0xC3, 0xE7, 0x1B, 0x49, 0xB8, 0xF1, + 0x00, 0x0F, 0xBF, 0xD0, 0x2A, 0x49, 0xBD, 0xE7, 0x1A, 0x49, 0xBB, 0xE7, + 0x1A, 0x49, 0xCB, 0xE7, 0x1A, 0x49, 0x00, 0x2F, 0xC8, 0xD0, 0x27, 0x49, + 0xC6, 0xE7, 0x1A, 0x49, 0xC4, 0xE7, 0x1A, 0x49, 0xD3, 0xE7, 0x1A, 0x49, + 0x00, 0x2F, 0xD0, 0xD0, 0x23, 0x49, 0xCE, 0xE7, 0x19, 0x49, 0xCC, 0xE7, + 0x19, 0x49, 0xDB, 0xE7, 0x19, 0x49, 0xD9, 0xE7, 0x1A, 0x49, 0xD7, 0xE7, + 0x26, 0xE7, 0x06, 0x4A, 0xA5, 0x20, 0x10, 0x70, 0x18, 0x48, 0x41, 0x78, + 0x51, 0x70, 0x01, 0x70, 0x41, 0x88, 0x49, 0x1C, 0x41, 0x80, 0x51, 0x80, + 0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x4C, 0x07, 0x10, 0x00, + 0x50, 0x07, 0x10, 0x00, 0x0A, 0x44, 0x01, 0x20, 0x14, 0xA6, 0x01, 0x20, + 0xB2, 0x2F, 0x01, 0x20, 0xEE, 0x35, 0x01, 0x20, 0x42, 0x44, 0x01, 0x20, + 0x04, 0xA3, 0x01, 0x20, 0x1E, 0x0B, 0x01, 0x20, 0x94, 0x0B, 0x01, 0x20, + 0x7E, 0x4A, 0x01, 0x20, 0x2E, 0xA3, 0x01, 0x20, 0x48, 0x0B, 0x01, 0x20, + 0xBE, 0x0B, 0x01, 0x20, 0xA8, 0x4A, 0x01, 0x20, 0xB8, 0xA4, 0x01, 0x20, + 0xA2, 0x1C, 0x01, 0x20, 0xAA, 0x1C, 0x01, 0x20, 0xF4, 0x4A, 0x01, 0x20, + 0x94, 0x07, 0x10, 0x00, 0x68, 0x07, 0x10, 0x00, 0x4A, 0x0C, 0x01, 0x20, + 0x92, 0x09, 0x01, 0x20, 0xBC, 0x09, 0x01, 0x20, 0x1F, 0x48, 0x00, 0x68, + 0x90, 0xF8, 0xA0, 0x00, 0xC0, 0x07, 0x01, 0xD0, 0x00, 0xF0, 0x3A, 0xB8, + 0x00, 0xF0, 0xDC, 0xB8, 0x1A, 0x49, 0x09, 0x68, 0x91, 0xF8, 0xA0, 0x10, + 0xC9, 0x07, 0x02, 0xD0, 0xC0, 0xB2, 0x00, 0xF0, 0x39, 0xB8, 0x01, 0x46, + 0x00, 0x20, 0x00, 0xF0, 0x2C, 0xB9, 0x38, 0xB5, 0x04, 0x46, 0x69, 0x46, + 0x18, 0x30, 0x00, 0xF0, 0xA2, 0xFD, 0x11, 0x48, 0x00, 0x99, 0x00, 0x68, + 0x90, 0xF8, 0xA0, 0x00, 0xC0, 0x07, 0x20, 0x46, 0x02, 0xD0, 0x00, 0xF0, + 0x44, 0xF8, 0x38, 0xBD, 0x00, 0xF0, 0xC6, 0xF8, 0x38, 0xBD, 0x00, 0xF0, + 0x24, 0xB9, 0x09, 0x4B, 0x1B, 0x68, 0x93, 0xF8, 0xA0, 0x30, 0xDB, 0x07, + 0x01, 0xD1, 0x00, 0xF0, 0x3A, 0xB9, 0x70, 0x47, 0x04, 0x4A, 0x12, 0x68, + 0x92, 0xF8, 0xA0, 0x20, 0x52, 0x07, 0x01, 0xD5, 0x00, 0xF0, 0x43, 0xB9, + 0x70, 0x47, 0x00, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x1C, 0xB5, 0x4F, 0x49, + 0xD1, 0xE9, 0x00, 0x01, 0xCD, 0xE9, 0x00, 0x01, 0x68, 0x46, 0xFF, 0xF7, + 0x80, 0xFB, 0x1C, 0xBD, 0x1C, 0xB5, 0x4A, 0x4A, 0xD2, 0xE9, 0x02, 0x12, + 0xCD, 0xE9, 0x00, 0x12, 0x8D, 0xF8, 0x02, 0x00, 0x68, 0x46, 0xFF, 0xF7, + 0x74, 0xFB, 0x1C, 0xBD, 0x88, 0x42, 0x0E, 0xD9, 0x90, 0x42, 0x01, 0xD3, + 0xFF, 0x20, 0x70, 0x47, 0x91, 0x42, 0x08, 0xD0, 0x40, 0x1A, 0xC0, 0xEB, + 0x00, 0x20, 0x51, 0x1A, 0xB0, 0xFB, 0xF1, 0xF0, 0x10, 0xF0, 0xFF, 0x00, + 0xF3, 0xD1, 0x01, 0x20, 0x70, 0x47, 0x7C, 0xB5, 0x05, 0x46, 0x00, 0x20, + 0x00, 0x90, 0x01, 0x90, 0x95, 0xF8, 0x4D, 0x21, 0x9D, 0xF8, 0x00, 0x00, + 0x62, 0xF3, 0x85, 0x00, 0x8D, 0xF8, 0x00, 0x00, 0x95, 0xF8, 0x3E, 0x21, + 0x03, 0x2A, 0x3E, 0xD0, 0x08, 0x2A, 0x40, 0xD0, 0x20, 0xF0, 0xC0, 0x00, + 0x10, 0xF1, 0x80, 0x00, 0x8D, 0xF8, 0x00, 0x00, 0x0A, 0x14, 0x10, 0x09, + 0x8D, 0xF8, 0x01, 0x00, 0x9D, 0xF8, 0x03, 0x00, 0x2C, 0x4E, 0x62, 0xF3, + 0x07, 0x10, 0x0A, 0x09, 0x8D, 0xF8, 0x02, 0x20, 0x61, 0xF3, 0x03, 0x00, + 0x8D, 0xF8, 0x03, 0x00, 0x30, 0x68, 0xB0, 0xF8, 0xA3, 0x20, 0xB0, 0xF8, + 0xA1, 0x10, 0x35, 0xF8, 0x4A, 0x0F, 0xFF, 0xF7, 0xBB, 0xFF, 0x8D, 0xF8, + 0x04, 0x00, 0x30, 0x68, 0xB0, 0xF8, 0xA7, 0x20, 0xB0, 0xF8, 0xA5, 0x10, + 0x68, 0x88, 0xFF, 0xF7, 0xB1, 0xFF, 0x8D, 0xF8, 0x05, 0x00, 0x29, 0x7A, + 0x9D, 0xF8, 0x06, 0x00, 0x61, 0xF3, 0x05, 0x00, 0x8D, 0xF8, 0x06, 0x00, + 0x95, 0xF8, 0xF6, 0x10, 0x09, 0x29, 0x1E, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, + 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x20, 0xF0, + 0xC0, 0x00, 0x40, 0x30, 0xC2, 0xE7, 0x40, 0xF0, 0xC0, 0x00, 0xBF, 0xE7, + 0x00, 0x24, 0x0E, 0xE0, 0x01, 0x24, 0x0C, 0xE0, 0x02, 0x24, 0x0A, 0xE0, + 0x03, 0x24, 0x08, 0xE0, 0x04, 0x24, 0x06, 0xE0, 0x05, 0x24, 0x04, 0xE0, + 0x06, 0x24, 0x02, 0xE0, 0x07, 0x24, 0x00, 0xE0, 0x08, 0x24, 0xA1, 0x08, + 0x61, 0xF3, 0x87, 0x10, 0x8D, 0xF8, 0x06, 0x00, 0x9D, 0xF8, 0x07, 0x00, + 0x64, 0xF3, 0x87, 0x10, 0x8D, 0xF8, 0x07, 0x00, 0x68, 0x46, 0xFF, 0xF7, + 0xEA, 0xFA, 0x7C, 0xBD, 0xF0, 0x7B, 0x01, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x1C, 0xB5, 0x54, 0x49, 0xD1, 0xE9, 0x00, 0x01, 0xCD, 0xE9, 0x00, 0x01, + 0x68, 0x46, 0xFF, 0xF7, 0xDC, 0xFA, 0x1C, 0xBD, 0x1C, 0xB5, 0x4F, 0x4B, + 0xD3, 0xE9, 0x02, 0x23, 0xCD, 0xE9, 0x00, 0x23, 0x90, 0xF8, 0x3E, 0x21, + 0x03, 0x2A, 0x19, 0xD0, 0x08, 0x2A, 0x9D, 0xF8, 0x00, 0x20, 0x22, 0xF0, + 0xF0, 0x02, 0x19, 0xD0, 0x12, 0xF1, 0x20, 0x02, 0x8D, 0xF8, 0x00, 0x20, + 0x90, 0xF8, 0x3F, 0x21, 0x02, 0xF0, 0x0F, 0x02, 0x01, 0x2A, 0x11, 0xD0, + 0x02, 0x2A, 0x15, 0xD0, 0x04, 0x2A, 0x9D, 0xF8, 0x01, 0x20, 0x22, 0xF0, + 0x0F, 0x02, 0x2E, 0xD0, 0x52, 0x1C, 0x12, 0xE0, 0x9D, 0xF8, 0x00, 0x20, + 0x22, 0xF0, 0xF0, 0x02, 0x10, 0x32, 0xE7, 0xE7, 0x30, 0x32, 0xE5, 0xE7, + 0x9D, 0xF8, 0x01, 0x20, 0x22, 0xF0, 0x0F, 0x02, 0x92, 0x1C, 0x04, 0xE0, + 0x9D, 0xF8, 0x01, 0x20, 0x22, 0xF0, 0x0F, 0x02, 0xD2, 0x1C, 0x8D, 0xF8, + 0x01, 0x20, 0x90, 0xF8, 0x4D, 0x01, 0xD2, 0xB2, 0x60, 0xF3, 0x07, 0x12, + 0x8D, 0xF8, 0x01, 0x20, 0xBD, 0xF8, 0x02, 0x00, 0x0A, 0x0C, 0x62, 0xF3, + 0x0B, 0x00, 0xAD, 0xF8, 0x02, 0x00, 0xBD, 0xF8, 0x03, 0x00, 0x61, 0xF3, + 0x0F, 0x10, 0xAD, 0xF8, 0x03, 0x00, 0x68, 0x46, 0xFF, 0xF7, 0x8B, 0xFA, + 0x1C, 0xBD, 0x12, 0x1D, 0xE3, 0xE7, 0x1C, 0xB5, 0x25, 0x4B, 0xD3, 0xE9, + 0x04, 0x23, 0xCD, 0xE9, 0x00, 0x23, 0x8D, 0xF8, 0x01, 0x00, 0xCD, 0xF8, + 0x02, 0x10, 0x68, 0x46, 0xFF, 0xF7, 0x7B, 0xFA, 0x1C, 0xBD, 0x1C, 0xB5, + 0x1F, 0x4A, 0x12, 0x68, 0x92, 0xF8, 0xA0, 0x20, 0x93, 0x07, 0x15, 0xD5, + 0x08, 0x28, 0x13, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x12, 0x04, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x12, 0x06, 0x0B, 0xD5, 0x16, 0x4B, 0xD3, 0xE9, + 0x06, 0x23, 0xCD, 0xE9, 0x00, 0x23, 0x8D, 0xF8, 0x01, 0x00, 0xCD, 0xF8, + 0x02, 0x10, 0x68, 0x46, 0xFF, 0xF7, 0x5D, 0xFA, 0x1C, 0xBD, 0x1C, 0xB5, + 0x0F, 0x4C, 0xD4, 0xE9, 0x08, 0x34, 0xCD, 0xE9, 0x00, 0x34, 0x8D, 0xF8, + 0x01, 0x00, 0xCD, 0xF8, 0x02, 0x10, 0x68, 0x46, 0x12, 0xB1, 0xFF, 0xF7, + 0x2A, 0xFC, 0x1C, 0xBD, 0xFF, 0xF7, 0x4B, 0xFA, 0x1C, 0xBD, 0x1C, 0xB5, + 0x06, 0x4B, 0xD3, 0xE9, 0x0A, 0x23, 0xCD, 0xE9, 0x00, 0x23, 0x8D, 0xF8, + 0x01, 0x00, 0xCD, 0xF8, 0x02, 0x10, 0x68, 0x46, 0xFF, 0xF7, 0x3D, 0xFA, + 0x1C, 0xBD, 0x00, 0x00, 0x08, 0x7C, 0x01, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x2D, 0xE9, 0xFF, 0x41, 0xED, 0xF7, 0xDC, 0xFB, 0x23, 0x4D, 0x00, 0x24, + 0xC4, 0xEB, 0xC4, 0x01, 0x05, 0xEB, 0x81, 0x00, 0x00, 0xF1, 0x0C, 0x03, + 0x02, 0x7E, 0xC8, 0xCB, 0xCD, 0xE9, 0x02, 0x72, 0xCD, 0xE9, 0x00, 0x36, + 0xD0, 0xE9, 0x01, 0x23, 0x55, 0xF8, 0x21, 0x00, 0x00, 0x21, 0xED, 0xF7, + 0xB1, 0xFD, 0x18, 0xB1, 0x21, 0x46, 0x43, 0x20, 0xFF, 0xF7, 0x2F, 0xFC, + 0x64, 0x1C, 0x05, 0x2C, 0xE4, 0xDB, 0x15, 0x4D, 0x00, 0x24, 0x8C, 0x35, + 0x05, 0xEB, 0xC4, 0x00, 0x00, 0x21, 0x42, 0x68, 0x55, 0xF8, 0x34, 0x00, + 0xED, 0xF7, 0x25, 0xFD, 0x18, 0xB1, 0x21, 0x46, 0x44, 0x20, 0xFF, 0xF7, + 0x1C, 0xFC, 0x64, 0x1C, 0x06, 0x2C, 0xEF, 0xDB, 0x0B, 0x4D, 0x00, 0x24, + 0x15, 0xF1, 0xBC, 0x05, 0x00, 0x21, 0x55, 0xF8, 0x24, 0x00, 0xED, 0xF7, + 0x3A, 0xFC, 0x18, 0xB1, 0x21, 0x46, 0x45, 0x20, 0xFF, 0xF7, 0x0B, 0xFC, + 0x64, 0x1C, 0x04, 0x2C, 0xF2, 0xDB, 0xBD, 0xE8, 0xFF, 0x81, 0x01, 0x46, + 0x46, 0x20, 0xFF, 0xF7, 0x02, 0xBC, 0x00, 0x00, 0x38, 0x7C, 0x01, 0x00, + 0x00, 0xF0, 0x1F, 0x03, 0x01, 0x22, 0x9A, 0x40, 0x43, 0x09, 0x9B, 0x00, + 0x03, 0xF1, 0xE0, 0x23, 0xC3, 0xF8, 0x80, 0x22, 0x49, 0x07, 0x09, 0x0E, + 0x00, 0x28, 0x06, 0xDA, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF1, 0xE0, 0x20, + 0x80, 0xF8, 0x14, 0x1D, 0x03, 0xE0, 0x00, 0xF1, 0xE0, 0x20, 0x80, 0xF8, + 0x00, 0x14, 0xC3, 0xF8, 0x00, 0x21, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x41, + 0x64, 0x27, 0x07, 0x26, 0x00, 0x25, 0xFD, 0x4C, 0xFD, 0x48, 0xEE, 0xF7, + 0xF3, 0xF9, 0xFC, 0x48, 0x03, 0x68, 0xD9, 0x1C, 0x3C, 0xD0, 0x42, 0x68, + 0xD1, 0x1C, 0x39, 0xD0, 0x81, 0x68, 0x11, 0xF1, 0x03, 0x0F, 0x35, 0xD0, + 0x00, 0x69, 0x10, 0xF1, 0x03, 0x0F, 0x31, 0xD0, 0xB3, 0xF1, 0xFF, 0x3F, + 0x31, 0xD0, 0x13, 0xF1, 0x02, 0x0F, 0x2E, 0xD0, 0xB2, 0xF1, 0xFF, 0x3F, + 0x2B, 0xD0, 0x12, 0xF1, 0x02, 0x0F, 0x28, 0xD0, 0xB1, 0xF1, 0xFF, 0x3F, + 0x25, 0xD0, 0x11, 0xF1, 0x02, 0x0F, 0x22, 0xD0, 0xB0, 0xF1, 0xFF, 0x3F, + 0x1F, 0xD0, 0x10, 0xF1, 0x02, 0x0F, 0x1C, 0xD0, 0xDF, 0xB2, 0xD6, 0xB2, + 0xCD, 0xB2, 0x04, 0x46, 0x2A, 0x46, 0x31, 0x46, 0x38, 0x46, 0xEE, 0xF7, + 0xF1, 0xF8, 0x20, 0x46, 0xEE, 0xF7, 0xFB, 0xF8, 0xE3, 0x48, 0xEE, 0xF7, + 0x64, 0xF9, 0x03, 0x28, 0x10, 0xD0, 0x01, 0x28, 0x11, 0xD0, 0x02, 0x28, + 0x0F, 0xD0, 0xDF, 0x48, 0x00, 0x68, 0x01, 0x28, 0x10, 0xD0, 0x12, 0xE0, + 0x00, 0x21, 0x24, 0x20, 0x01, 0xE0, 0x00, 0x21, 0x25, 0x20, 0xFF, 0xF7, + 0xDF, 0xFB, 0xE1, 0xE7, 0x00, 0x21, 0x29, 0x20, 0x01, 0xE0, 0x00, 0x21, + 0x2A, 0x20, 0xFF, 0xF7, 0xD7, 0xFB, 0x02, 0xE0, 0xD4, 0x48, 0xED, 0xF7, + 0x7B, 0xFD, 0xD2, 0x48, 0x14, 0x30, 0xEE, 0xF7, 0x6C, 0xF9, 0x04, 0x46, + 0x03, 0x28, 0x04, 0xD0, 0x01, 0x2C, 0x05, 0xD0, 0x02, 0x2C, 0x03, 0xD0, + 0x06, 0xE0, 0x00, 0x21, 0x2B, 0x20, 0x01, 0xE0, 0x00, 0x21, 0x2C, 0x20, + 0xFF, 0xF7, 0xC0, 0xFB, 0x21, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0xC7, 0x48, + 0x14, 0x30, 0x00, 0xF0, 0x81, 0xBF, 0x7C, 0xB5, 0xC6, 0x4E, 0x01, 0xAA, + 0x69, 0x46, 0x30, 0x46, 0xEE, 0xF7, 0x09, 0xFA, 0xC4, 0x4C, 0x40, 0xF2, + 0xBC, 0x65, 0x01, 0x28, 0x02, 0xD0, 0x00, 0x21, 0x22, 0x20, 0x10, 0xE0, + 0x00, 0x98, 0xA0, 0xF5, 0x80, 0x71, 0xAF, 0x39, 0xF7, 0xD1, 0x2A, 0x46, + 0x31, 0x46, 0x20, 0x68, 0x04, 0xF0, 0x8F, 0xF9, 0x20, 0x68, 0xEE, 0xF7, + 0x07, 0xFA, 0x01, 0x28, 0x08, 0xD0, 0x00, 0x21, 0x23, 0x20, 0xFF, 0xF7, + 0x97, 0xFB, 0x29, 0x46, 0x20, 0x68, 0x04, 0xF0, 0x01, 0xFA, 0x7C, 0xBD, + 0xB5, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x70, 0x11, 0x89, 0x07, 0x07, 0xD4, + 0x90, 0xF8, 0x88, 0x11, 0xC9, 0x06, 0x03, 0xD4, 0x90, 0xF8, 0xA0, 0x01, + 0xC0, 0x06, 0xF0, 0xD5, 0x24, 0x68, 0x26, 0x22, 0x04, 0xF2, 0x02, 0x61, + 0xAD, 0x48, 0x04, 0xF0, 0x6C, 0xF9, 0xAC, 0x48, 0x1D, 0x22, 0x04, 0xF5, + 0xC5, 0x61, 0x28, 0x30, 0x04, 0xF0, 0x65, 0xF9, 0xA8, 0x48, 0x26, 0x22, + 0x04, 0xF2, 0x5E, 0x61, 0x48, 0x30, 0x04, 0xF0, 0x5E, 0xF9, 0xA5, 0x48, + 0x1D, 0x22, 0x04, 0xF2, 0x84, 0x61, 0x70, 0x30, 0x04, 0xF0, 0x57, 0xF9, + 0x7C, 0xBD, 0xF8, 0xB5, 0x0D, 0x46, 0x06, 0x46, 0x00, 0x24, 0x6A, 0x46, + 0xEE, 0xF7, 0xB7, 0xF9, 0x01, 0x28, 0x01, 0xD0, 0x01, 0x24, 0x0B, 0xE0, + 0x28, 0x68, 0x31, 0x46, 0x82, 0x00, 0x9B, 0x48, 0x04, 0xF0, 0x8A, 0xF9, + 0x99, 0x48, 0xEE, 0xF7, 0xBD, 0xF9, 0x01, 0x28, 0x00, 0xD0, 0x02, 0x24, + 0x20, 0x46, 0xF8, 0xBD, 0x2D, 0xE9, 0xF8, 0x43, 0x94, 0x4D, 0x95, 0x4F, + 0x10, 0x35, 0x41, 0xF2, 0xC8, 0x11, 0x94, 0x48, 0x04, 0xF0, 0xD4, 0xF9, + 0x69, 0x46, 0x38, 0x46, 0xFF, 0xF7, 0xD9, 0xFF, 0x01, 0x28, 0x05, 0xD0, + 0x02, 0x28, 0x06, 0xD0, 0xE8, 0x78, 0x01, 0x28, 0x0A, 0xD1, 0x05, 0xE0, + 0x00, 0x21, 0xA0, 0x20, 0x2E, 0xE0, 0x00, 0x21, 0xA1, 0x20, 0x2B, 0xE0, + 0xA8, 0x78, 0x08, 0xB9, 0x28, 0x88, 0x10, 0xB1, 0x00, 0x21, 0xA2, 0x20, + 0x24, 0xE0, 0x82, 0x4E, 0xE9, 0x88, 0x30, 0x68, 0x82, 0x8A, 0x91, 0x42, + 0x02, 0xD0, 0x00, 0x21, 0xA3, 0x20, 0x1B, 0xE0, 0xA9, 0x88, 0xC0, 0x8A, + 0x81, 0x42, 0x02, 0xD0, 0x00, 0x21, 0xA4, 0x20, 0x14, 0xE0, 0x00, 0x24, + 0x00, 0x98, 0x69, 0x46, 0x07, 0xEB, 0x80, 0x07, 0x38, 0x46, 0xFF, 0xF7, + 0xAC, 0xFF, 0x78, 0xB1, 0x01, 0x28, 0x03, 0xD0, 0x00, 0x21, 0xA6, 0x20, + 0xFF, 0xF7, 0x0C, 0xFB, 0xE0, 0x07, 0x35, 0xD0, 0xA0, 0x07, 0x35, 0xD4, + 0x11, 0x21, 0xA7, 0x20, 0xFF, 0xF7, 0x04, 0xFB, 0xBD, 0xE8, 0xF8, 0x83, + 0x95, 0xF8, 0x01, 0x80, 0x29, 0x46, 0x40, 0x46, 0x00, 0xF0, 0xDE, 0xFD, + 0xA0, 0xB1, 0xB8, 0xF1, 0x10, 0x0F, 0x14, 0xD0, 0xB8, 0xF1, 0x11, 0x0F, + 0x14, 0xD0, 0xB8, 0xF1, 0x12, 0x0F, 0x14, 0xD0, 0xB8, 0xF1, 0x13, 0x0F, + 0x14, 0xD0, 0xB8, 0xF1, 0x14, 0x0F, 0x14, 0xD0, 0xB8, 0xF1, 0x17, 0x0F, + 0xCE, 0xD1, 0x44, 0xF0, 0x20, 0x04, 0xCB, 0xE7, 0x41, 0x46, 0xA8, 0x20, + 0xD4, 0xE7, 0x44, 0xF0, 0x01, 0x04, 0xC5, 0xE7, 0x44, 0xF0, 0x02, 0x04, + 0xC2, 0xE7, 0x44, 0xF0, 0x08, 0x04, 0xBF, 0xE7, 0x44, 0xF0, 0x10, 0x04, + 0xBC, 0xE7, 0x44, 0xF0, 0x04, 0x04, 0xB9, 0xE7, 0x10, 0x21, 0xCA, 0xE7, + 0x20, 0x07, 0x0A, 0xD4, 0x30, 0x68, 0x90, 0xF8, 0x50, 0x12, 0xC9, 0x07, + 0x03, 0xD1, 0x90, 0xF8, 0x80, 0x02, 0xC0, 0x07, 0x01, 0xD0, 0x12, 0x21, + 0xBD, 0xE7, 0xE0, 0x06, 0x01, 0xD4, 0x13, 0x21, 0xB9, 0xE7, 0x60, 0x07, + 0x05, 0xD4, 0x30, 0x68, 0x90, 0xF8, 0x61, 0x04, 0x08, 0xB1, 0x14, 0x21, + 0xB1, 0xE7, 0xA0, 0x06, 0xB2, 0xD4, 0x30, 0x68, 0x90, 0xF8, 0x2F, 0x0A, + 0xC0, 0x07, 0xAD, 0xD0, 0x17, 0x21, 0xA8, 0xE7, 0x10, 0xB5, 0x8E, 0xB0, + 0xED, 0xF7, 0x66, 0xF9, 0x00, 0x20, 0x01, 0x22, 0x41, 0xB2, 0x01, 0xF0, + 0x1F, 0x03, 0x02, 0xFA, 0x03, 0xF3, 0x49, 0x09, 0x89, 0x00, 0x01, 0xF1, + 0xE0, 0x21, 0xC1, 0xF8, 0x80, 0x31, 0x40, 0x1C, 0x1F, 0x28, 0xF1, 0xDB, + 0xED, 0xF7, 0x52, 0xF9, 0xED, 0xF7, 0x5C, 0xFF, 0xEE, 0xF7, 0x26, 0xF9, + 0x07, 0x21, 0x0A, 0x20, 0xFF, 0xF7, 0x46, 0xFE, 0x07, 0x21, 0x0B, 0x20, + 0xFF, 0xF7, 0x42, 0xFE, 0xFE, 0xF7, 0xFE, 0xFF, 0xFE, 0xF7, 0xAA, 0xFE, + 0x04, 0xA8, 0xFF, 0xF7, 0xEC, 0xF9, 0x0A, 0xA9, 0x07, 0xA8, 0xFF, 0xF7, + 0x89, 0xF8, 0x04, 0xA8, 0x00, 0x90, 0x07, 0xA8, 0x02, 0x90, 0x0A, 0xA8, + 0x03, 0x90, 0x68, 0x46, 0xEE, 0xF7, 0x26, 0xFA, 0x02, 0x21, 0x00, 0x20, + 0xFF, 0xF7, 0x2A, 0xFE, 0xFF, 0xF7, 0x04, 0xF8, 0xFF, 0xF7, 0x20, 0xFA, + 0xFF, 0xF7, 0x40, 0xFE, 0xED, 0xF7, 0x60, 0xFF, 0x28, 0x4C, 0x01, 0xAA, + 0x69, 0x46, 0x20, 0x46, 0xEE, 0xF7, 0xBF, 0xF8, 0x01, 0x28, 0x02, 0xD0, + 0x00, 0x21, 0x20, 0x20, 0x11, 0xE0, 0x00, 0x98, 0xB0, 0xF5, 0x25, 0x7F, + 0xF8, 0xD1, 0x21, 0x46, 0x1B, 0x4C, 0x4F, 0xF4, 0x25, 0x62, 0x20, 0x68, + 0x04, 0xF0, 0x47, 0xF8, 0x20, 0x68, 0xEE, 0xF7, 0xBF, 0xF8, 0x01, 0x28, + 0x03, 0xD0, 0x00, 0x21, 0x21, 0x20, 0xFF, 0xF7, 0x02, 0xFA, 0xFF, 0xF7, + 0x94, 0xFE, 0xFF, 0xF7, 0xFD, 0xFE, 0x00, 0xF0, 0x07, 0xF8, 0x00, 0xF0, + 0x55, 0xF8, 0x0E, 0xB0, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x86, 0xB8, + 0x10, 0xB5, 0xEE, 0xF7, 0xBF, 0xFA, 0x0B, 0x48, 0x00, 0x68, 0x01, 0x7C, + 0xA5, 0x29, 0x1F, 0xD0, 0x4F, 0xF4, 0xFA, 0x40, 0xEE, 0xF7, 0x61, 0xFC, + 0x00, 0x21, 0x28, 0x20, 0xFF, 0xF7, 0x32, 0xFA, 0x19, 0xE0, 0x00, 0x00, + 0x00, 0x90, 0xD0, 0x03, 0x84, 0x7B, 0x10, 0x00, 0xE8, 0x84, 0x10, 0x00, + 0xF0, 0x9F, 0x01, 0x00, 0x50, 0x07, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0xE4, 0x9F, 0x01, 0x20, 0xD4, 0x56, 0x10, 0x00, 0xF0, 0xAF, 0x01, 0x00, + 0x78, 0x8B, 0x01, 0x20, 0xF0, 0xEF, 0x01, 0x00, 0x40, 0x69, 0xEE, 0xF7, + 0x42, 0xFC, 0x04, 0x21, 0x02, 0x20, 0xFF, 0xF7, 0xC7, 0xFD, 0x04, 0x21, + 0x03, 0x20, 0xFF, 0xF7, 0xC3, 0xFD, 0x04, 0x21, 0x08, 0x46, 0xFF, 0xF7, + 0xBF, 0xFD, 0x04, 0x21, 0x05, 0x20, 0xFF, 0xF7, 0xBB, 0xFD, 0x04, 0x21, + 0x06, 0x20, 0xFF, 0xF7, 0xB7, 0xFD, 0x04, 0x21, 0x07, 0x20, 0xFF, 0xF7, + 0xB3, 0xFD, 0x04, 0x21, 0x08, 0x20, 0xFF, 0xF7, 0xAF, 0xFD, 0x01, 0x21, + 0x09, 0x20, 0xFF, 0xF7, 0xAB, 0xFD, 0x04, 0x21, 0xBD, 0xE8, 0x10, 0x40, + 0x0F, 0x20, 0xA5, 0xE5, 0x38, 0xB5, 0x03, 0xF0, 0xFB, 0xFB, 0x03, 0x21, + 0x01, 0x20, 0xFF, 0xF7, 0x9F, 0xFD, 0x28, 0x4C, 0x20, 0x68, 0x90, 0xF8, + 0xB0, 0x10, 0xC9, 0x07, 0x27, 0xD0, 0x00, 0x25, 0x00, 0x95, 0x90, 0xF8, + 0xC0, 0x00, 0x2B, 0x46, 0xC0, 0xF3, 0x02, 0x10, 0x01, 0x22, 0x29, 0x46, + 0xEE, 0xF7, 0x87, 0xF8, 0x20, 0x68, 0x0A, 0x21, 0x90, 0xF8, 0xC0, 0x00, + 0xC0, 0xF3, 0x02, 0x10, 0xEE, 0xF7, 0xA7, 0xF8, 0x00, 0x95, 0x20, 0x68, + 0x00, 0x23, 0x01, 0x22, 0x90, 0xF8, 0xC0, 0x00, 0x19, 0x46, 0x00, 0xF0, + 0x07, 0x00, 0xEE, 0xF7, 0x74, 0xF8, 0x20, 0x68, 0x01, 0x21, 0x90, 0xF8, + 0xC0, 0x00, 0xBD, 0xE8, 0x38, 0x40, 0x00, 0xF0, 0x07, 0x00, 0xEE, 0xF7, + 0x92, 0xB8, 0x38, 0xBD, 0x38, 0xB5, 0x10, 0x4C, 0x20, 0x68, 0x90, 0xF8, + 0x60, 0x03, 0xC1, 0x07, 0x0F, 0xD0, 0x81, 0x07, 0x0D, 0xD5, 0x00, 0x21, + 0x01, 0x23, 0x40, 0x09, 0x1A, 0x46, 0x00, 0x91, 0xEE, 0xF7, 0x59, 0xF8, + 0x20, 0x68, 0x00, 0x21, 0x90, 0xF8, 0x60, 0x03, 0x40, 0x09, 0xEE, 0xF7, + 0x7A, 0xF8, 0x20, 0x68, 0x90, 0xF8, 0x79, 0x00, 0xBD, 0xE8, 0x38, 0x40, + 0x00, 0xF0, 0x03, 0x01, 0xC0, 0x09, 0xED, 0xF7, 0xA5, 0xBE, 0x00, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x88, 0x42, 0x00, 0xD3, 0x08, 0x46, 0x90, 0x42, + 0x00, 0xD3, 0x10, 0x46, 0x70, 0x47, 0x88, 0x42, 0x00, 0xD8, 0x08, 0x46, + 0x90, 0x42, 0x00, 0xD8, 0x10, 0x46, 0x70, 0x47, 0x88, 0x42, 0x00, 0xD3, + 0x08, 0x46, 0x70, 0x47, 0x88, 0x42, 0x00, 0xD8, 0x08, 0x46, 0x70, 0x47, + 0x02, 0x46, 0x00, 0x20, 0x4F, 0xF0, 0x80, 0x41, 0x00, 0xE0, 0x89, 0x08, + 0x91, 0x42, 0xFC, 0xD8, 0x07, 0xE0, 0x43, 0x18, 0x93, 0x42, 0x02, 0xD8, + 0xD2, 0x1A, 0x00, 0xEB, 0x41, 0x00, 0x40, 0x08, 0x89, 0x08, 0x00, 0x29, + 0xF5, 0xD1, 0x82, 0x42, 0x00, 0xD9, 0x40, 0x1C, 0x70, 0x47, 0x10, 0xB5, + 0x5A, 0x43, 0x02, 0x9C, 0x06, 0xE0, 0x00, 0xBF, 0x50, 0xF8, 0x22, 0x30, + 0x93, 0xFB, 0xF4, 0xF3, 0x41, 0xF8, 0x22, 0x30, 0x52, 0x1E, 0xF7, 0xD2, + 0x10, 0xBD, 0x10, 0xB5, 0x5A, 0x43, 0x02, 0x9C, 0x05, 0xE0, 0x00, 0xBF, + 0x50, 0xF8, 0x22, 0x30, 0x63, 0x43, 0x41, 0xF8, 0x22, 0x30, 0x52, 0x1E, + 0xF8, 0xD2, 0x10, 0xBD, 0x30, 0xB5, 0x03, 0x9C, 0x63, 0x43, 0x06, 0xE0, + 0x50, 0xF8, 0x23, 0x40, 0x51, 0xF8, 0x23, 0x50, 0x2C, 0x44, 0x42, 0xF8, + 0x23, 0x40, 0x5B, 0x1E, 0xF6, 0xD2, 0x30, 0xBD, 0x30, 0xB5, 0x03, 0x9C, + 0x63, 0x43, 0x06, 0xE0, 0x50, 0xF8, 0x23, 0x40, 0x51, 0xF8, 0x23, 0x50, + 0x64, 0x1B, 0x42, 0xF8, 0x23, 0x40, 0x5B, 0x1E, 0xF6, 0xD2, 0x30, 0xBD, + 0x2D, 0xE9, 0xF0, 0x4F, 0x83, 0x46, 0xDD, 0xE9, 0x09, 0x06, 0xDD, 0xF8, + 0x34, 0xE0, 0x8A, 0x46, 0x82, 0x42, 0x26, 0xD1, 0x00, 0x20, 0x22, 0xE0, + 0x00, 0xFB, 0x02, 0xF1, 0x0B, 0xEB, 0x81, 0x09, 0x0B, 0x9D, 0x00, 0xFB, + 0x0E, 0xF1, 0x00, 0x24, 0x05, 0xEB, 0x81, 0x05, 0x14, 0xE0, 0x00, 0x21, + 0x0F, 0xE0, 0x00, 0xBF, 0x01, 0xFB, 0x06, 0xF8, 0x03, 0xEB, 0x88, 0x08, + 0x59, 0xF8, 0x21, 0xC0, 0x55, 0xF8, 0x24, 0x70, 0x58, 0xF8, 0x24, 0x80, + 0x49, 0x1C, 0x0C, 0xFB, 0x08, 0x77, 0x45, 0xF8, 0x24, 0x70, 0x91, 0x42, + 0xEE, 0xDB, 0x64, 0x1C, 0xB4, 0x42, 0xE8, 0xDB, 0x40, 0x1C, 0x50, 0x45, + 0xDA, 0xDB, 0xBD, 0xE8, 0xF0, 0x8F, 0x10, 0xB5, 0x00, 0x23, 0x1C, 0x46, + 0x42, 0xB1, 0x02, 0x78, 0x52, 0x1C, 0xD2, 0xB2, 0x02, 0x70, 0x8A, 0x42, + 0x03, 0xD9, 0x04, 0x70, 0x01, 0x23, 0x00, 0xE0, 0x04, 0x70, 0x18, 0x46, + 0x10, 0xBD, 0x30, 0xB5, 0x00, 0x24, 0x01, 0x23, 0x05, 0xE0, 0x0C, 0x44, + 0xE4, 0x1C, 0x04, 0xF0, 0x03, 0x05, 0x64, 0x1B, 0x5B, 0x1C, 0x93, 0x42, + 0xF7, 0xDD, 0x00, 0xEB, 0x44, 0x00, 0x30, 0xBD, 0x88, 0x42, 0x01, 0xDD, + 0x08, 0x46, 0x70, 0x47, 0x00, 0x28, 0xFC, 0xDA, 0x00, 0x20, 0x70, 0x47, + 0x10, 0xB5, 0x04, 0xE0, 0x00, 0xEB, 0x82, 0x03, 0x53, 0xF8, 0x04, 0x4C, + 0x1C, 0x60, 0x52, 0x1E, 0xF8, 0xD1, 0x09, 0x68, 0x01, 0x60, 0x10, 0xBD, + 0x10, 0xB5, 0x03, 0xE0, 0x00, 0xEB, 0x82, 0x03, 0x0C, 0x68, 0x1C, 0x60, + 0x52, 0x1E, 0xF9, 0xD2, 0x10, 0xBD, 0x30, 0xB5, 0x06, 0xE0, 0x00, 0xBF, + 0x00, 0xEB, 0xC2, 0x03, 0x73, 0xE9, 0x02, 0x45, 0xC3, 0xE9, 0x02, 0x45, + 0x52, 0x1E, 0xF7, 0xD1, 0xD1, 0xE9, 0x00, 0x21, 0xC0, 0xE9, 0x00, 0x21, + 0x30, 0xBD, 0x10, 0xB5, 0x53, 0x88, 0x4C, 0x88, 0x1B, 0x1B, 0x43, 0x80, + 0x12, 0x88, 0x09, 0x88, 0x51, 0x1A, 0x01, 0x80, 0x10, 0xBD, 0x08, 0xB5, + 0x0A, 0x46, 0x01, 0x46, 0x68, 0x46, 0xFF, 0xF7, 0xF0, 0xFF, 0xBD, 0xF9, + 0x00, 0x10, 0xBD, 0xF9, 0x02, 0x00, 0x49, 0x43, 0x00, 0xFB, 0x00, 0x10, + 0x08, 0xBD, 0x10, 0xB5, 0x88, 0x42, 0x02, 0x9C, 0x01, 0xDC, 0x20, 0x46, + 0x10, 0xBD, 0x90, 0x42, 0x01, 0xDB, 0x18, 0x46, 0x10, 0xBD, 0x8A, 0x42, + 0x00, 0xD1, 0x52, 0x1C, 0x40, 0x1A, 0xE3, 0x1A, 0x58, 0x43, 0x51, 0x1A, + 0x90, 0xFB, 0xF1, 0xF0, 0x20, 0x1A, 0x10, 0xBD, 0x10, 0xB5, 0x00, 0x2A, + 0x03, 0xD0, 0x43, 0x1A, 0x93, 0x42, 0x01, 0xDD, 0x88, 0x18, 0x10, 0xBD, + 0x54, 0x42, 0xA3, 0x42, 0xFB, 0xDA, 0x88, 0x1A, 0x10, 0xBD, 0x91, 0x42, + 0x01, 0xD1, 0x00, 0xB2, 0x70, 0x47, 0x50, 0x43, 0xB0, 0xFB, 0xF1, 0xF0, + 0x00, 0xB2, 0x90, 0x42, 0xF7, 0xD9, 0x10, 0x46, 0xF5, 0xE7, 0x70, 0xB5, + 0x0B, 0x00, 0x02, 0x46, 0x3D, 0xD0, 0x1F, 0x4C, 0x20, 0x68, 0x46, 0x8E, + 0x85, 0x8E, 0xB2, 0xF9, 0x02, 0x00, 0x31, 0xB2, 0xFF, 0xF7, 0x80, 0xFF, + 0x58, 0x80, 0xB2, 0xF9, 0x00, 0x00, 0x29, 0xB2, 0xFF, 0xF7, 0x7A, 0xFF, + 0x18, 0x80, 0x21, 0x68, 0x91, 0xF8, 0x36, 0x10, 0x49, 0x07, 0x02, 0xD5, + 0x59, 0x88, 0x71, 0x1A, 0x59, 0x80, 0x21, 0x68, 0x91, 0xF8, 0x36, 0x10, + 0x89, 0x07, 0x01, 0xD5, 0x28, 0x1A, 0x18, 0x80, 0x20, 0x68, 0x90, 0xF8, + 0x36, 0x10, 0x09, 0x07, 0x10, 0xD5, 0xB0, 0xF8, 0x37, 0x20, 0xB3, 0xF9, + 0x02, 0x00, 0x31, 0x46, 0xFF, 0xF7, 0xC5, 0xFF, 0x58, 0x80, 0x20, 0x68, + 0x29, 0x46, 0xB0, 0xF8, 0x39, 0x20, 0xB3, 0xF9, 0x00, 0x00, 0xFF, 0xF7, + 0xBC, 0xFF, 0x18, 0x80, 0x20, 0x68, 0x90, 0xF8, 0x36, 0x00, 0xC0, 0x07, + 0x03, 0xD0, 0x58, 0x88, 0x19, 0x88, 0x59, 0x80, 0x18, 0x80, 0x70, 0xBD, + 0x4C, 0x07, 0x10, 0x00, 0x31, 0xB5, 0xED, 0xF7, 0xE1, 0xF9, 0x04, 0x00, + 0x08, 0xD4, 0xDD, 0xF8, 0x00, 0x00, 0x01, 0x22, 0x02, 0xFA, 0x04, 0xF1, + 0x01, 0x42, 0x01, 0xD1, 0x64, 0x1E, 0xF9, 0xD5, 0x04, 0x21, 0x68, 0x46, + 0xED, 0xF7, 0x5D, 0xFE, 0xFE, 0x49, 0xC0, 0xB2, 0x09, 0x68, 0x91, 0xF8, + 0xE7, 0x10, 0xC1, 0xF3, 0x41, 0x11, 0x02, 0x29, 0x0E, 0xD3, 0x10, 0xF0, + 0x03, 0x00, 0x05, 0xD0, 0x01, 0x28, 0x05, 0xD0, 0x02, 0x28, 0x05, 0xD0, + 0x1F, 0x20, 0x0A, 0xE0, 0x0F, 0x20, 0x08, 0xE0, 0x7F, 0x20, 0x06, 0xE0, + 0x3F, 0x20, 0x04, 0xE0, 0xC0, 0x07, 0x01, 0xD0, 0x07, 0x20, 0x00, 0xE0, + 0x03, 0x20, 0x64, 0x1C, 0x00, 0x99, 0xA0, 0x40, 0x08, 0x43, 0x38, 0xBD, + 0x10, 0xB5, 0xEE, 0x4C, 0x50, 0x28, 0x13, 0xD0, 0x09, 0xDC, 0xA0, 0xF1, + 0x10, 0x00, 0x08, 0x28, 0x40, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x0D, 0x20, + 0x20, 0x20, 0x26, 0x3F, 0x3F, 0x39, 0x51, 0x38, 0x07, 0x28, 0x37, 0xD2, + 0xDF, 0xE8, 0x00, 0xF0, 0x17, 0x17, 0x17, 0x1D, 0x36, 0x36, 0x30, 0x00, + 0x03, 0xF0, 0x8D, 0xFA, 0x20, 0x60, 0x03, 0xF0, 0x8C, 0xFA, 0xC4, 0xE9, + 0x04, 0x01, 0xDE, 0x48, 0x00, 0x68, 0x90, 0xF8, 0xE7, 0x00, 0x10, 0xF0, + 0x60, 0x0F, 0x11, 0xD0, 0x20, 0x68, 0xFF, 0xF7, 0xA3, 0xFF, 0x20, 0x60, + 0x0C, 0xE0, 0x03, 0xF0, 0x7A, 0xFA, 0x20, 0x60, 0x03, 0xF0, 0x79, 0xFA, + 0x04, 0xE0, 0x03, 0xF0, 0x78, 0xFA, 0x20, 0x60, 0x03, 0xF0, 0x77, 0xFA, + 0xC4, 0xE9, 0x04, 0x01, 0x04, 0x21, 0xD2, 0x48, 0xED, 0xF7, 0xFF, 0xFD, + 0x60, 0x60, 0xD0, 0x48, 0x08, 0x21, 0x10, 0x30, 0xED, 0xF7, 0xF9, 0xFD, + 0xA0, 0x60, 0x10, 0xBD, 0x03, 0xF0, 0x69, 0xFA, 0x20, 0x60, 0x03, 0xF0, + 0x68, 0xFA, 0xEB, 0xE7, 0x00, 0x20, 0x01, 0x46, 0x20, 0x60, 0xE7, 0xE7, + 0x2D, 0xE9, 0xFF, 0x5F, 0x04, 0x21, 0xDD, 0xE9, 0x0F, 0xAB, 0x68, 0x46, + 0xED, 0xF7, 0xE5, 0xFD, 0x81, 0x46, 0x08, 0x21, 0x02, 0xA8, 0xED, 0xF7, + 0xE0, 0xFD, 0x07, 0x46, 0x00, 0x24, 0x20, 0x46, 0x35, 0xE0, 0x01, 0x20, + 0x00, 0x99, 0x00, 0xFA, 0x08, 0xF0, 0x08, 0x42, 0x2D, 0xD0, 0x00, 0x25, + 0x2E, 0x46, 0x27, 0xE0, 0x32, 0x46, 0x01, 0x20, 0x00, 0x21, 0x03, 0xF0, + 0x41, 0xFD, 0xDD, 0xE9, 0x02, 0x23, 0x10, 0x40, 0x19, 0x40, 0x08, 0x43, + 0x1B, 0xD0, 0x11, 0x98, 0x60, 0xB1, 0x04, 0xFB, 0x07, 0xF0, 0x0A, 0xEB, + 0x05, 0x01, 0x41, 0x56, 0x32, 0x46, 0x01, 0xEB, 0x0B, 0x03, 0x21, 0x46, + 0x0E, 0x98, 0xED, 0xF7, 0xBC, 0xF9, 0x0B, 0xE0, 0x32, 0x46, 0x21, 0x46, + 0x0E, 0x98, 0xED, 0xF7, 0xAB, 0xF9, 0x04, 0xFB, 0x07, 0xF1, 0x0A, 0xEB, + 0x05, 0x02, 0xA0, 0xEB, 0x0B, 0x00, 0x88, 0x54, 0x6D, 0x1C, 0x76, 0x1C, + 0xBD, 0x42, 0xD5, 0xDB, 0x64, 0x1C, 0x08, 0xF1, 0x01, 0x00, 0x80, 0x46, + 0x4C, 0x45, 0xC6, 0xDB, 0xBD, 0xE8, 0xFF, 0x9F, 0x2D, 0xE9, 0xFF, 0x5F, + 0x84, 0xB0, 0x04, 0x21, 0xDD, 0xE9, 0x12, 0xAB, 0x04, 0xA8, 0xED, 0xF7, + 0x98, 0xFD, 0x81, 0x46, 0x08, 0x21, 0x06, 0xA8, 0xED, 0xF7, 0x93, 0xFD, + 0x07, 0x46, 0x00, 0x25, 0x0A, 0xF1, 0x48, 0x00, 0x02, 0x90, 0x20, 0x30, + 0x01, 0x90, 0x48, 0x38, 0x2C, 0x46, 0xA8, 0x46, 0x2E, 0x46, 0x00, 0x90, + 0x31, 0xE0, 0x01, 0x20, 0x04, 0x99, 0x00, 0xFA, 0x08, 0xF0, 0x08, 0x42, + 0x27, 0xD0, 0x16, 0x98, 0x90, 0xB1, 0x1B, 0xF8, 0x05, 0x10, 0x14, 0x98, + 0x08, 0x44, 0xC2, 0xB2, 0x41, 0x46, 0x02, 0x98, 0xED, 0xF7, 0xDF, 0xF9, + 0x05, 0xEB, 0x09, 0x00, 0xC1, 0x19, 0x1B, 0xF9, 0x01, 0x20, 0x41, 0x46, + 0x50, 0x46, 0xED, 0xF7, 0xAD, 0xF9, 0x10, 0xE0, 0x41, 0x46, 0x02, 0x98, + 0xED, 0xF7, 0xCF, 0xF9, 0x14, 0x99, 0x40, 0x1A, 0x0B, 0xF8, 0x05, 0x00, + 0x41, 0x46, 0x50, 0x46, 0xED, 0xF7, 0x99, 0xF9, 0x05, 0xEB, 0x09, 0x01, + 0xCA, 0x19, 0x0B, 0xF8, 0x02, 0x00, 0x6D, 0x1C, 0xED, 0xB2, 0x08, 0xF1, + 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x08, 0x4D, 0x45, 0xCB, 0xDB, 0x38, 0xE0, + 0x32, 0x46, 0x01, 0x20, 0x00, 0x21, 0x03, 0xF0, 0xBF, 0xFC, 0xDD, 0xE9, + 0x06, 0x23, 0x10, 0x40, 0x19, 0x40, 0x08, 0x43, 0x2B, 0xD0, 0x16, 0x98, + 0xA0, 0xB1, 0x04, 0xEB, 0x09, 0x01, 0x15, 0x98, 0x1B, 0xF8, 0x01, 0x10, + 0x08, 0x44, 0xC2, 0xB2, 0x31, 0x46, 0x01, 0x98, 0xED, 0xF7, 0xA3, 0xF9, + 0x04, 0xEB, 0x49, 0x00, 0xC1, 0x19, 0x1B, 0xF9, 0x01, 0x20, 0x31, 0x46, + 0x00, 0x98, 0xED, 0xF7, 0x71, 0xF9, 0x12, 0xE0, 0x31, 0x46, 0x01, 0x98, + 0xED, 0xF7, 0x93, 0xF9, 0x15, 0x99, 0x04, 0xEB, 0x09, 0x02, 0x40, 0x1A, + 0x0B, 0xF8, 0x02, 0x00, 0x31, 0x46, 0x00, 0x98, 0xED, 0xF7, 0x5B, 0xF9, + 0x04, 0xEB, 0x49, 0x01, 0xCA, 0x19, 0x0B, 0xF8, 0x02, 0x00, 0x64, 0x1C, + 0xE4, 0xB2, 0x76, 0x1C, 0xF6, 0xB2, 0xBC, 0x42, 0xC4, 0xDB, 0x08, 0xB0, + 0xBD, 0xE8, 0xF0, 0x9F, 0x2D, 0xE9, 0xFF, 0x5F, 0x04, 0x21, 0xDD, 0xE9, + 0x0E, 0xBA, 0x68, 0x46, 0xED, 0xF7, 0x0B, 0xFD, 0x81, 0x46, 0x08, 0x21, + 0x02, 0xA8, 0xED, 0xF7, 0x06, 0xFD, 0x07, 0x46, 0x00, 0x24, 0x20, 0x46, + 0x24, 0xE0, 0x01, 0x20, 0x00, 0x99, 0x00, 0xFA, 0x08, 0xF0, 0x08, 0x42, + 0x1C, 0xD0, 0x00, 0x25, 0x2E, 0x46, 0x16, 0xE0, 0x32, 0x46, 0x01, 0x20, + 0x00, 0x21, 0x03, 0xF0, 0x67, 0xFC, 0xDD, 0xE9, 0x02, 0x23, 0x10, 0x40, + 0x19, 0x40, 0x08, 0x43, 0x0A, 0xD0, 0x32, 0x46, 0x21, 0x46, 0x58, 0x46, + 0xED, 0xF7, 0xE0, 0xF8, 0x04, 0xFB, 0x07, 0x52, 0x80, 0x00, 0x2A, 0xF8, + 0x12, 0x00, 0x6D, 0x1C, 0x76, 0x1C, 0xBD, 0x42, 0xE6, 0xDB, 0x64, 0x1C, + 0x08, 0xF1, 0x01, 0x00, 0x80, 0x46, 0x4C, 0x45, 0xD7, 0xDB, 0x35, 0xE7, + 0x2D, 0xE9, 0xFF, 0x5F, 0x04, 0x21, 0xDD, 0xE9, 0x0E, 0x9B, 0x68, 0x46, + 0xED, 0xF7, 0xD1, 0xFC, 0x82, 0x46, 0x08, 0x21, 0x02, 0xA8, 0xED, 0xF7, + 0xCC, 0xFC, 0x00, 0x25, 0x80, 0x46, 0x2C, 0x46, 0x2F, 0x46, 0x2E, 0x46, + 0x36, 0xE0, 0x01, 0x20, 0x00, 0x99, 0xB8, 0x40, 0x08, 0x42, 0x2F, 0xD0, + 0x39, 0x46, 0x09, 0xF1, 0x48, 0x00, 0xED, 0xF7, 0x24, 0xF9, 0x2E, 0x49, + 0x99, 0xF8, 0x92, 0x30, 0x09, 0x68, 0x91, 0xF8, 0x43, 0xC1, 0x91, 0xF8, + 0x42, 0x11, 0x0C, 0xF0, 0x0F, 0x02, 0x52, 0x1C, 0x53, 0x43, 0x01, 0x22, + 0x02, 0xEB, 0x1C, 0x1C, 0x00, 0xFB, 0x0C, 0x33, 0x99, 0xF8, 0x90, 0x00, + 0x02, 0xEB, 0x11, 0x11, 0x00, 0xFB, 0x01, 0x30, 0x10, 0x99, 0x19, 0xB9, + 0x4F, 0xF6, 0xFF, 0x71, 0x01, 0xEA, 0x80, 0x00, 0x2B, 0xF8, 0x15, 0x00, + 0x39, 0x46, 0x48, 0x46, 0xED, 0xF7, 0xD3, 0xF8, 0x05, 0xEB, 0x0A, 0x02, + 0x80, 0x00, 0x42, 0x44, 0x6D, 0x1C, 0x2B, 0xF8, 0x12, 0x00, 0xED, 0xB2, + 0x7F, 0x1C, 0xFF, 0xB2, 0x55, 0x45, 0xC6, 0xDB, 0x45, 0xE0, 0x32, 0x46, + 0x01, 0x20, 0x00, 0x21, 0x03, 0xF0, 0xFA, 0xFB, 0xDD, 0xE9, 0x02, 0x23, + 0x10, 0x40, 0x19, 0x40, 0x08, 0x43, 0x38, 0xD0, 0x31, 0x46, 0x09, 0xF1, + 0x68, 0x00, 0xED, 0xF7, 0xE4, 0xF8, 0x0E, 0x49, 0x99, 0xF8, 0x93, 0x50, + 0x09, 0x68, 0x91, 0xF8, 0x48, 0x21, 0x91, 0xF8, 0x47, 0x11, 0x02, 0xF0, + 0x0F, 0x03, 0x5B, 0x1C, 0x5D, 0x43, 0x01, 0x23, 0x03, 0xEB, 0x12, 0x12, + 0x00, 0xFB, 0x02, 0x52, 0x99, 0xF8, 0x91, 0x00, 0x03, 0xEB, 0x11, 0x11, + 0x00, 0xFB, 0x01, 0x20, 0x10, 0x99, 0x49, 0xB9, 0x4F, 0xF6, 0xFF, 0x71, + 0x04, 0xE0, 0x00, 0x00, 0x4C, 0x07, 0x10, 0x00, 0xB0, 0x07, 0x10, 0x00, + 0x01, 0xEA, 0x80, 0x00, 0x04, 0xEB, 0x0A, 0x02, 0x31, 0x46, 0x2B, 0xF8, + 0x12, 0x00, 0x09, 0xF1, 0x20, 0x00, 0xED, 0xF7, 0x8A, 0xF8, 0x04, 0xEB, + 0x4A, 0x02, 0x80, 0x00, 0x42, 0x44, 0x64, 0x1C, 0x2B, 0xF8, 0x12, 0x00, + 0xE4, 0xB2, 0x76, 0x1C, 0xF6, 0xB2, 0x44, 0x45, 0xB7, 0xDB, 0x9F, 0xE6, + 0x2D, 0xE9, 0xF0, 0x43, 0x89, 0x46, 0x00, 0x27, 0x85, 0xB0, 0x90, 0x46, + 0x04, 0x46, 0x3E, 0x46, 0xFC, 0x21, 0x03, 0xF0, 0x61, 0xFC, 0xFE, 0x4D, + 0xB8, 0xF1, 0x01, 0x0F, 0x28, 0x79, 0x20, 0x71, 0x28, 0x7A, 0x60, 0x71, + 0xFB, 0x48, 0x90, 0xF8, 0x52, 0x1E, 0xA1, 0x71, 0x90, 0xF8, 0x53, 0x1E, + 0xE1, 0x71, 0x90, 0xF8, 0x54, 0x1E, 0xA1, 0x72, 0x90, 0xF8, 0x55, 0x1E, + 0xE1, 0x72, 0x90, 0xF8, 0x50, 0x1E, 0x21, 0x73, 0x90, 0xF8, 0x51, 0x0E, + 0x60, 0x73, 0x08, 0xD1, 0xF2, 0x48, 0x00, 0x68, 0x81, 0x7F, 0xA5, 0x29, + 0x03, 0xD1, 0x90, 0xF9, 0x1F, 0x70, 0x90, 0xF9, 0x20, 0x60, 0x04, 0xF1, + 0x10, 0x00, 0xCD, 0xE9, 0x01, 0x07, 0xED, 0x48, 0x00, 0x21, 0x00, 0x90, + 0xCD, 0xE9, 0x03, 0x61, 0xD5, 0xE9, 0x04, 0x23, 0x28, 0x68, 0xFF, 0xF7, + 0x65, 0xFE, 0xA5, 0x20, 0x20, 0x70, 0x12, 0x20, 0x60, 0x70, 0xA4, 0xF8, + 0x02, 0x90, 0xD5, 0xE9, 0x01, 0x01, 0x08, 0x44, 0x13, 0x30, 0x80, 0x08, + 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x2D, 0xE9, 0xF0, 0x43, 0x89, 0x46, + 0x00, 0x27, 0x85, 0xB0, 0x90, 0x46, 0x04, 0x46, 0x3E, 0x46, 0xFC, 0x21, + 0x03, 0xF0, 0x16, 0xFC, 0xD8, 0x4D, 0xB8, 0xF1, 0x01, 0x0F, 0x28, 0x79, + 0x20, 0x71, 0x28, 0x7A, 0x60, 0x71, 0xD6, 0x48, 0x90, 0xF8, 0xEA, 0x1E, + 0xA1, 0x71, 0x90, 0xF8, 0xEB, 0x1E, 0xE1, 0x71, 0x90, 0xF8, 0xEC, 0x1E, + 0xA1, 0x72, 0x90, 0xF8, 0xED, 0x1E, 0xE1, 0x72, 0x90, 0xF8, 0xE8, 0x1E, + 0x21, 0x73, 0x90, 0xF8, 0xE9, 0x0E, 0x60, 0x73, 0x09, 0xD1, 0xCD, 0x48, + 0x00, 0x68, 0x90, 0xF8, 0x21, 0x10, 0xA5, 0x29, 0x03, 0xD1, 0x10, 0xF9, + 0x22, 0x7F, 0x90, 0xF9, 0x01, 0x60, 0x04, 0xF1, 0x10, 0x00, 0xCD, 0xE9, + 0x01, 0x07, 0xC7, 0x48, 0x00, 0x21, 0x98, 0x30, 0x00, 0x90, 0xCD, 0xE9, + 0x03, 0x61, 0xD5, 0xE9, 0x04, 0x23, 0x28, 0x68, 0xFF, 0xF7, 0x18, 0xFE, + 0xA5, 0x20, 0x20, 0x70, 0x13, 0x20, 0x60, 0x70, 0xA4, 0xF8, 0x02, 0x90, + 0xD5, 0xE9, 0x01, 0x01, 0x08, 0x44, 0x13, 0x30, 0x80, 0x08, 0xB1, 0xE7, + 0x2D, 0xE9, 0xF0, 0x43, 0x89, 0x46, 0x00, 0x27, 0x85, 0xB0, 0x90, 0x46, + 0x04, 0x46, 0x3E, 0x46, 0xFC, 0x21, 0x03, 0xF0, 0xCB, 0xFB, 0xB3, 0x4D, + 0xB8, 0xF1, 0x01, 0x0F, 0x28, 0x79, 0x20, 0x71, 0x28, 0x7A, 0x60, 0x71, + 0xB0, 0x48, 0x90, 0xF8, 0x82, 0x1F, 0xA1, 0x71, 0x90, 0xF8, 0x83, 0x1F, + 0xE1, 0x71, 0x90, 0xF8, 0x84, 0x1F, 0xA1, 0x72, 0x90, 0xF8, 0x85, 0x1F, + 0xE1, 0x72, 0x90, 0xF8, 0x80, 0x1F, 0x21, 0x73, 0x90, 0xF8, 0x81, 0x0F, + 0x60, 0x73, 0x09, 0xD1, 0xA7, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x26, 0x10, + 0xA5, 0x29, 0x03, 0xD1, 0x10, 0xF9, 0x27, 0x7F, 0x90, 0xF9, 0x01, 0x60, + 0x04, 0xF1, 0x10, 0x00, 0xCD, 0xE9, 0x01, 0x07, 0xA2, 0x48, 0x00, 0x21, + 0x00, 0x90, 0xCD, 0xE9, 0x03, 0x61, 0xD5, 0xE9, 0x04, 0x23, 0x28, 0x68, + 0xFF, 0xF7, 0xCE, 0xFD, 0xA5, 0x20, 0x20, 0x70, 0x17, 0x20, 0x60, 0x70, + 0xA4, 0xF8, 0x02, 0x90, 0xD5, 0xE9, 0x01, 0x01, 0x08, 0x44, 0x13, 0x30, + 0x80, 0x08, 0x67, 0xE7, 0x2D, 0xE9, 0xFF, 0x41, 0x0D, 0x46, 0x07, 0x46, + 0x00, 0x26, 0xFF, 0xF7, 0x21, 0xFD, 0x01, 0x22, 0x8F, 0x4C, 0x91, 0x49, + 0x10, 0x3F, 0x05, 0xF1, 0x10, 0x00, 0x08, 0x2F, 0x4E, 0xD2, 0xDF, 0xE8, + 0x07, 0xF0, 0x04, 0x15, 0x26, 0x2A, 0x2F, 0x4D, 0x4D, 0x51, 0x2B, 0x79, + 0x66, 0x68, 0xB3, 0x42, 0x2E, 0xD1, 0x6B, 0x79, 0xA5, 0x68, 0xAB, 0x42, + 0x2A, 0xD1, 0x09, 0x68, 0x00, 0x23, 0x8D, 0x7E, 0xA5, 0x2D, 0x01, 0xD1, + 0x91, 0xF9, 0x1B, 0x30, 0x82, 0x49, 0x2D, 0xE0, 0x2B, 0x79, 0x66, 0x68, + 0xB3, 0x42, 0x1D, 0xD1, 0x6B, 0x79, 0xA5, 0x68, 0xAB, 0x42, 0x19, 0xD1, + 0x09, 0x68, 0x00, 0x23, 0x0D, 0x7F, 0xA5, 0x2D, 0x01, 0xD1, 0x91, 0xF9, + 0x1D, 0x30, 0x7E, 0x49, 0x1C, 0xE0, 0x28, 0x46, 0x00, 0xF0, 0x12, 0xF9, + 0x02, 0xE0, 0x28, 0x46, 0x00, 0xF0, 0x49, 0xF9, 0x06, 0x46, 0x1D, 0xE0, + 0x2B, 0x79, 0x66, 0x68, 0xB3, 0x42, 0x03, 0xD1, 0x6B, 0x79, 0xA5, 0x68, + 0xAB, 0x42, 0x01, 0xD0, 0x00, 0x26, 0x13, 0xE0, 0x09, 0x68, 0x00, 0x23, + 0x91, 0xF8, 0x24, 0x50, 0xA5, 0x2D, 0x01, 0xD1, 0x91, 0xF9, 0x25, 0x30, + 0x6D, 0x49, 0xA0, 0x39, 0xCD, 0xE9, 0x00, 0x10, 0xCD, 0xE9, 0x02, 0x32, + 0xD4, 0xE9, 0x04, 0x23, 0x20, 0x68, 0xFF, 0xF7, 0x19, 0xFD, 0x01, 0x26, + 0x30, 0x46, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x28, 0x46, 0x00, 0xF0, + 0x5E, 0xF9, 0xD7, 0xE7, 0x2D, 0xE9, 0xF0, 0x41, 0x1E, 0x46, 0x17, 0x46, + 0x88, 0x46, 0x05, 0x46, 0x00, 0x24, 0xFF, 0xF7, 0xB9, 0xFC, 0x10, 0x3D, + 0x08, 0x2D, 0x11, 0xD2, 0xDF, 0xE8, 0x05, 0xF0, 0x04, 0x0A, 0x12, 0x18, + 0x1E, 0x10, 0x10, 0x24, 0x32, 0x46, 0x39, 0x46, 0x40, 0x46, 0x00, 0xF0, + 0x81, 0xF9, 0x04, 0xE0, 0x32, 0x46, 0x39, 0x46, 0x40, 0x46, 0x00, 0xF0, + 0xAC, 0xF9, 0x04, 0x46, 0x20, 0x46, 0xD9, 0xE7, 0x32, 0x46, 0x39, 0x46, + 0x40, 0x46, 0xFF, 0xF7, 0x95, 0xFE, 0xF6, 0xE7, 0x32, 0x46, 0x39, 0x46, + 0x40, 0x46, 0xFF, 0xF7, 0xDA, 0xFE, 0xF0, 0xE7, 0x32, 0x46, 0x39, 0x46, + 0x40, 0x46, 0x00, 0xF0, 0xC9, 0xF9, 0xEA, 0xE7, 0x32, 0x46, 0x39, 0x46, + 0x40, 0x46, 0xFF, 0xF7, 0x19, 0xFF, 0xE4, 0xE7, 0xFE, 0xB5, 0x17, 0x46, + 0x06, 0x46, 0x0D, 0x46, 0xFF, 0xF7, 0x84, 0xFC, 0x41, 0x48, 0x47, 0x4A, + 0x05, 0xF1, 0x10, 0x04, 0x01, 0x79, 0x29, 0x71, 0x01, 0x7A, 0x69, 0x71, + 0xA6, 0xF1, 0x50, 0x01, 0x08, 0x29, 0x26, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, + 0x04, 0x06, 0x0F, 0x16, 0x2A, 0x25, 0x25, 0x2D, 0x39, 0x49, 0x00, 0xE0, + 0x3C, 0x49, 0xCD, 0xE9, 0x00, 0x14, 0xD0, 0xE9, 0x04, 0x23, 0x00, 0x68, + 0xFF, 0xF7, 0x90, 0xFD, 0x15, 0xE0, 0x11, 0x68, 0x35, 0x4A, 0x91, 0xF8, + 0x42, 0x11, 0x01, 0xF0, 0x01, 0x01, 0x06, 0xE0, 0x11, 0x68, 0x32, 0x4A, + 0x91, 0xF8, 0x92, 0x19, 0x98, 0x32, 0x01, 0xF0, 0x01, 0x01, 0x00, 0x92, + 0xCD, 0xE9, 0x01, 0x41, 0xD0, 0xE9, 0x04, 0x23, 0x00, 0x68, 0xFF, 0xF7, + 0xB3, 0xFD, 0xA5, 0x20, 0x28, 0x70, 0x6E, 0x70, 0x6F, 0x80, 0xFE, 0xBD, + 0x28, 0x49, 0xA0, 0x39, 0xD9, 0xE7, 0x11, 0x68, 0x27, 0x4A, 0x91, 0xF8, + 0x12, 0x1A, 0x01, 0xF0, 0x01, 0x01, 0xE8, 0xE7, 0x2D, 0xE9, 0xF0, 0x41, + 0x0C, 0x46, 0x05, 0x46, 0x4F, 0xF4, 0x29, 0x71, 0x24, 0x48, 0x03, 0xF0, + 0xBF, 0xFA, 0x23, 0x48, 0x00, 0x2C, 0x04, 0x60, 0x57, 0xD1, 0x80, 0x46, + 0x04, 0xEB, 0x84, 0x00, 0xC4, 0xEB, 0xC4, 0x01, 0x05, 0xEB, 0xC0, 0x06, + 0x08, 0xEB, 0x01, 0x17, 0x38, 0x1D, 0x28, 0x22, 0x31, 0x46, 0x03, 0xF0, + 0x0C, 0xFA, 0xC4, 0xEB, 0x04, 0x10, 0x05, 0xEB, 0x80, 0x01, 0x07, 0xF1, + 0x2C, 0x00, 0x20, 0x22, 0x78, 0x31, 0x03, 0xF0, 0x02, 0xFA, 0x06, 0xF5, + 0x96, 0x71, 0x07, 0xF1, 0x4C, 0x00, 0x28, 0x22, 0x03, 0xF0, 0xFB, 0xF9, + 0x64, 0x1C, 0x03, 0x2C, 0xDE, 0xDB, 0x00, 0x24, 0x04, 0xEB, 0x84, 0x00, + 0xC4, 0xEB, 0xC4, 0x02, 0x05, 0xEB, 0xC0, 0x06, 0x08, 0xEB, 0x02, 0x17, + 0x06, 0xF5, 0xD2, 0x71, 0x07, 0xF5, 0xAA, 0x70, 0x28, 0x22, 0x03, 0xF0, + 0xE8, 0xF9, 0xC4, 0xEB, 0x04, 0x10, 0x0F, 0xE0, 0xB0, 0x07, 0x10, 0x00, + 0x78, 0x8B, 0x01, 0x20, 0x50, 0x07, 0x10, 0x00, 0x38, 0x99, 0x01, 0x20, + 0x68, 0x9A, 0x01, 0x20, 0x08, 0x92, 0x01, 0x20, 0x4C, 0x07, 0x10, 0x00, + 0x40, 0x9D, 0x01, 0x20, 0x05, 0xEB, 0x80, 0x01, 0x07, 0xF5, 0xBE, 0x70, + 0x20, 0x22, 0x01, 0xF5, 0x07, 0x71, 0x03, 0xF0, 0xCC, 0xF9, 0x06, 0xF5, + 0x34, 0x71, 0x07, 0xF5, 0xCE, 0x70, 0x28, 0x22, 0x03, 0xF0, 0xC5, 0xF9, + 0x64, 0x1C, 0x03, 0x2C, 0xCA, 0xDB, 0x13, 0xE7, 0x30, 0xB5, 0xA3, 0x49, + 0x02, 0x79, 0x85, 0xB0, 0x4B, 0x68, 0x9A, 0x42, 0x03, 0xD1, 0x42, 0x79, + 0x8B, 0x68, 0x9A, 0x42, 0x02, 0xD0, 0x00, 0x20, 0x05, 0xB0, 0x30, 0xBD, + 0x9D, 0x4A, 0x85, 0x79, 0x00, 0x24, 0x82, 0xF8, 0x52, 0x5E, 0xC5, 0x79, + 0x82, 0xF8, 0x53, 0x5E, 0x85, 0x7A, 0x82, 0xF8, 0x54, 0x5E, 0xC5, 0x7A, + 0x82, 0xF8, 0x55, 0x5E, 0x05, 0x7B, 0x82, 0xF8, 0x50, 0x5E, 0x45, 0x7B, + 0x82, 0xF8, 0x51, 0x5E, 0x94, 0x4A, 0x23, 0x46, 0x12, 0x68, 0x95, 0x7F, + 0xA5, 0x2D, 0x03, 0xD1, 0x92, 0xF9, 0x1F, 0x40, 0x92, 0xF9, 0x20, 0x30, + 0x10, 0x30, 0xCD, 0xE9, 0x01, 0x04, 0x8F, 0x48, 0x01, 0x22, 0x00, 0x90, + 0xCD, 0xE9, 0x03, 0x32, 0xD1, 0xE9, 0x04, 0x23, 0x08, 0x68, 0xFF, 0xF7, + 0x3D, 0xFC, 0x01, 0x20, 0xD0, 0xE7, 0x30, 0xB5, 0x85, 0x49, 0x02, 0x79, + 0x85, 0xB0, 0x4B, 0x68, 0x9A, 0x42, 0x03, 0xD1, 0x42, 0x79, 0x8B, 0x68, + 0x9A, 0x42, 0x01, 0xD0, 0x00, 0x20, 0xC3, 0xE7, 0x80, 0x4A, 0x85, 0x79, + 0x00, 0x24, 0x82, 0xF8, 0xEA, 0x5E, 0xC5, 0x79, 0x82, 0xF8, 0xEB, 0x5E, + 0x85, 0x7A, 0x82, 0xF8, 0xEC, 0x5E, 0xC5, 0x7A, 0x82, 0xF8, 0xED, 0x5E, + 0x05, 0x7B, 0x82, 0xF8, 0xE8, 0x5E, 0x45, 0x7B, 0x82, 0xF8, 0xE9, 0x5E, + 0x77, 0x4A, 0x23, 0x46, 0x12, 0x68, 0x92, 0xF8, 0x21, 0x50, 0xA5, 0x2D, + 0x03, 0xD1, 0x12, 0xF9, 0x22, 0x4F, 0x92, 0xF9, 0x01, 0x30, 0x10, 0x30, + 0xCD, 0xE9, 0x01, 0x04, 0x71, 0x48, 0x01, 0x22, 0x98, 0x30, 0x00, 0x90, + 0xCD, 0xE9, 0x03, 0x32, 0xD1, 0xE9, 0x04, 0x23, 0x08, 0x68, 0xFF, 0xF7, + 0x01, 0xFC, 0x01, 0x20, 0x94, 0xE7, 0x30, 0xB5, 0x67, 0x49, 0x02, 0x79, + 0x85, 0xB0, 0x4B, 0x68, 0x9A, 0x42, 0x03, 0xD1, 0x42, 0x79, 0x8B, 0x68, + 0x9A, 0x42, 0x01, 0xD0, 0x00, 0x20, 0x87, 0xE7, 0x62, 0x4A, 0x85, 0x79, + 0x00, 0x24, 0x82, 0xF8, 0x82, 0x5F, 0xC5, 0x79, 0x82, 0xF8, 0x83, 0x5F, + 0x85, 0x7A, 0x82, 0xF8, 0x84, 0x5F, 0xC5, 0x7A, 0x82, 0xF8, 0x85, 0x5F, + 0x05, 0x7B, 0x82, 0xF8, 0x80, 0x5F, 0x45, 0x7B, 0x82, 0xF8, 0x81, 0x5F, + 0x59, 0x4A, 0x23, 0x46, 0x12, 0x68, 0x92, 0xF8, 0x26, 0x50, 0xA5, 0x2D, + 0x03, 0xD1, 0x12, 0xF9, 0x27, 0x4F, 0x92, 0xF9, 0x01, 0x30, 0x10, 0x30, + 0xCD, 0xE9, 0x01, 0x04, 0x54, 0x48, 0x01, 0x22, 0x00, 0x90, 0xCD, 0xE9, + 0x03, 0x32, 0xD1, 0xE9, 0x04, 0x23, 0x08, 0x68, 0xFF, 0xF7, 0xC6, 0xFB, + 0x01, 0x20, 0x59, 0xE7, 0x2D, 0xE9, 0xFF, 0x41, 0x0F, 0x46, 0x15, 0x46, + 0x04, 0x46, 0x00, 0x26, 0x40, 0xF2, 0x7A, 0x31, 0x03, 0xF0, 0x84, 0xF9, + 0x45, 0x48, 0x01, 0x2D, 0x01, 0x79, 0x21, 0x71, 0x01, 0x7A, 0x61, 0x71, + 0x06, 0xD1, 0x44, 0x49, 0x09, 0x68, 0x8A, 0x7E, 0xA5, 0x2A, 0x01, 0xD1, + 0x91, 0xF9, 0x1B, 0x60, 0x00, 0x22, 0x04, 0xF1, 0x10, 0x01, 0x3E, 0x4B, + 0xCD, 0xE9, 0x00, 0x31, 0xCD, 0xE9, 0x02, 0x62, 0x05, 0x46, 0x00, 0x68, + 0xD5, 0xE9, 0x04, 0x23, 0xFF, 0xF7, 0x52, 0xFB, 0xA5, 0x20, 0x20, 0x70, + 0x10, 0x20, 0x60, 0x70, 0x67, 0x80, 0xD5, 0xE9, 0x01, 0x01, 0x48, 0x43, + 0x13, 0x30, 0x80, 0x08, 0x2F, 0xE6, 0x2D, 0xE9, 0xFF, 0x41, 0x0F, 0x46, + 0x15, 0x46, 0x04, 0x46, 0x00, 0x26, 0x40, 0xF2, 0x7A, 0x31, 0x03, 0xF0, + 0x53, 0xF9, 0x2D, 0x48, 0x01, 0x2D, 0x01, 0x79, 0x21, 0x71, 0x01, 0x7A, + 0x61, 0x71, 0x06, 0xD1, 0x2B, 0x49, 0x09, 0x68, 0x0A, 0x7F, 0xA5, 0x2A, + 0x01, 0xD1, 0x91, 0xF9, 0x1D, 0x60, 0x00, 0x23, 0x04, 0xF1, 0x10, 0x01, + 0x29, 0x4A, 0xCD, 0xE9, 0x00, 0x21, 0xCD, 0xE9, 0x02, 0x63, 0x05, 0x46, + 0x00, 0x68, 0xD5, 0xE9, 0x04, 0x23, 0xFF, 0xF7, 0x21, 0xFB, 0xA5, 0x20, + 0x20, 0x70, 0x11, 0x20, 0x60, 0x70, 0x67, 0x80, 0xD5, 0xE9, 0x01, 0x01, + 0x48, 0x43, 0x13, 0x30, 0x80, 0x08, 0xFE, 0xE5, 0x2D, 0xE9, 0xFF, 0x41, + 0x0F, 0x46, 0x15, 0x46, 0x04, 0x46, 0x00, 0x26, 0x40, 0xF2, 0x7A, 0x31, + 0x03, 0xF0, 0x22, 0xF9, 0x14, 0x48, 0x01, 0x2D, 0x01, 0x79, 0x21, 0x71, + 0x01, 0x7A, 0x61, 0x71, 0x07, 0xD1, 0x13, 0x49, 0x09, 0x68, 0x91, 0xF8, + 0x24, 0x20, 0xA5, 0x2A, 0x01, 0xD1, 0x91, 0xF9, 0x25, 0x60, 0x10, 0x4A, + 0x00, 0x23, 0x04, 0xF1, 0x10, 0x01, 0xA0, 0x3A, 0xCD, 0xE9, 0x00, 0x21, + 0xCD, 0xE9, 0x02, 0x63, 0x05, 0x46, 0x00, 0x68, 0xD5, 0xE9, 0x04, 0x23, + 0xFF, 0xF7, 0xEE, 0xFA, 0xA5, 0x20, 0x20, 0x70, 0x14, 0x20, 0x60, 0x70, + 0x67, 0x80, 0xD5, 0xE9, 0x01, 0x01, 0x48, 0x43, 0x13, 0x30, 0x80, 0x08, + 0xCB, 0xE5, 0x00, 0x00, 0xB0, 0x07, 0x10, 0x00, 0x78, 0x8B, 0x01, 0x20, + 0x50, 0x07, 0x10, 0x00, 0x38, 0x99, 0x01, 0x20, 0x68, 0x9A, 0x01, 0x20, + 0x08, 0x92, 0x01, 0x20, 0x2D, 0xE9, 0xF0, 0x4F, 0x47, 0xF6, 0xFF, 0x77, + 0xDD, 0xE9, 0x09, 0xB5, 0x81, 0x46, 0xFE, 0x43, 0x01, 0x20, 0x9A, 0x46, + 0x84, 0x46, 0x2C, 0x46, 0x15, 0xE0, 0x00, 0xBF, 0x32, 0xF8, 0x14, 0x30, + 0x31, 0xF8, 0x14, 0x80, 0xA3, 0xEB, 0x08, 0x03, 0x1B, 0xB2, 0xBB, 0x42, + 0x00, 0xDA, 0x1F, 0x46, 0xB3, 0x42, 0x00, 0xDD, 0x1E, 0x46, 0x00, 0x2B, + 0x02, 0xDD, 0x4F, 0xF0, 0x00, 0x0C, 0x02, 0xE0, 0x01, 0xDA, 0x4F, 0xF0, + 0x00, 0x00, 0x64, 0x1E, 0xE8, 0xD2, 0x20, 0xB1, 0xBC, 0xF1, 0x00, 0x0F, + 0x01, 0xD0, 0x00, 0x23, 0x09, 0xE0, 0x50, 0xEA, 0x0C, 0x03, 0x06, 0xD0, + 0x20, 0xB9, 0xBC, 0xF1, 0x00, 0x0F, 0x01, 0xD0, 0x33, 0x46, 0x00, 0xE0, + 0x3B, 0x46, 0x00, 0x27, 0x3C, 0x46, 0x28, 0x46, 0xCB, 0xF1, 0x00, 0x0C, + 0x0E, 0xE0, 0x00, 0xBF, 0x32, 0xF8, 0x10, 0x60, 0x31, 0xF8, 0x10, 0x80, + 0xA6, 0xEB, 0x08, 0x06, 0xF6, 0x1A, 0x36, 0xB2, 0x56, 0x45, 0x03, 0xDA, + 0x66, 0x45, 0x01, 0xDD, 0x37, 0x44, 0x64, 0x1C, 0x40, 0x1E, 0xEF, 0xD2, + 0x04, 0xB9, 0x01, 0x24, 0x97, 0xFB, 0xF4, 0xF0, 0x18, 0x44, 0x04, 0xE0, + 0x31, 0xF8, 0x15, 0x20, 0x02, 0x44, 0x29, 0xF8, 0x15, 0x20, 0x6D, 0x1E, + 0xF8, 0xD2, 0xBD, 0xE8, 0xF0, 0x8F, 0xF0, 0xB5, 0x00, 0x23, 0x06, 0x46, + 0x1D, 0x46, 0x18, 0x46, 0x0E, 0xE0, 0x00, 0xBF, 0x36, 0xF9, 0x11, 0x40, + 0x00, 0x2C, 0x01, 0xDB, 0x27, 0x46, 0x00, 0xE0, 0x67, 0x42, 0x97, 0x42, + 0x04, 0xDD, 0x00, 0x2C, 0x01, 0xDD, 0x25, 0x44, 0x00, 0xE0, 0x23, 0x44, + 0x49, 0x1E, 0xEF, 0xD2, 0x00, 0x2B, 0x00, 0xDA, 0x5B, 0x42, 0xAB, 0x42, + 0x00, 0xDD, 0x01, 0x20, 0xF0, 0xBD, 0x30, 0xB5, 0x07, 0xE0, 0x00, 0xBF, + 0x32, 0xF8, 0x13, 0x40, 0x31, 0xF8, 0x13, 0x50, 0x64, 0x1B, 0x20, 0xF8, + 0x13, 0x40, 0x5B, 0x1E, 0xF6, 0xD2, 0x30, 0xBD, 0xF0, 0xB4, 0x04, 0x9C, + 0x1C, 0xB9, 0x13, 0xB1, 0xC3, 0xF1, 0x10, 0x04, 0x0E, 0xE0, 0xF0, 0xBC, + 0x52, 0x00, 0x02, 0xF0, 0xDC, 0xBF, 0x00, 0xBF, 0x30, 0xF9, 0x12, 0x50, + 0x31, 0xF9, 0x12, 0x60, 0x5D, 0x43, 0x06, 0xFB, 0x04, 0x55, 0x2D, 0x11, + 0x20, 0xF8, 0x12, 0x50, 0x52, 0x1E, 0xF3, 0xD2, 0xF0, 0xBC, 0x70, 0x47, + 0xF0, 0xB4, 0x04, 0x9C, 0x1C, 0xB9, 0x13, 0xB1, 0xC3, 0xF1, 0x80, 0x04, + 0x0E, 0xE0, 0xF0, 0xBC, 0x52, 0x00, 0x02, 0xF0, 0xC2, 0xBF, 0x00, 0xBF, + 0x30, 0xF9, 0x12, 0x50, 0x31, 0xF9, 0x12, 0x60, 0x5D, 0x43, 0x06, 0xFB, + 0x04, 0x55, 0xED, 0x11, 0x20, 0xF8, 0x12, 0x50, 0x52, 0x1E, 0xF3, 0xD2, + 0xE4, 0xE7, 0xF0, 0xB5, 0x00, 0x2B, 0x19, 0xD0, 0x14, 0x46, 0x15, 0xE0, + 0x00, 0x27, 0x3E, 0x46, 0xE5, 0x1A, 0x04, 0xEB, 0x03, 0x0C, 0x08, 0xE0, + 0x00, 0x2D, 0x05, 0xDB, 0x95, 0x42, 0x03, 0xDA, 0x31, 0xF9, 0x15, 0xE0, + 0x76, 0x1C, 0x77, 0x44, 0x6D, 0x1C, 0xAC, 0x45, 0xF4, 0xDA, 0x1E, 0xB1, + 0x97, 0xFB, 0xF6, 0xF5, 0x20, 0xF8, 0x14, 0x50, 0x64, 0x1E, 0xE7, 0xD2, + 0xF0, 0xBD, 0x70, 0xB5, 0x0C, 0x46, 0x15, 0x46, 0xA0, 0x42, 0x04, 0xD0, + 0x01, 0x46, 0x6A, 0x00, 0x20, 0x46, 0x02, 0xF0, 0x8C, 0xFF, 0x00, 0x20, + 0x17, 0xE0, 0x01, 0x46, 0x42, 0x1C, 0x07, 0xE0, 0x34, 0xF9, 0x12, 0x60, + 0x34, 0xF9, 0x11, 0x30, 0x9E, 0x42, 0x00, 0xDA, 0x11, 0x46, 0x52, 0x1C, + 0xAA, 0x42, 0xF5, 0xD3, 0x88, 0x42, 0x07, 0xD0, 0x34, 0xF8, 0x10, 0x20, + 0x34, 0xF8, 0x11, 0x30, 0x24, 0xF8, 0x10, 0x30, 0x24, 0xF8, 0x11, 0x20, + 0x40, 0x1C, 0xB0, 0xEB, 0x55, 0x0F, 0xE4, 0xD9, 0xE9, 0x07, 0x25, 0xF0, + 0x01, 0x00, 0x01, 0xD0, 0x20, 0x5E, 0x70, 0xBD, 0x21, 0x5E, 0x20, 0x44, + 0x30, 0xF9, 0x02, 0x0C, 0x08, 0x44, 0x40, 0x10, 0x70, 0xBD, 0x03, 0x46, + 0x00, 0x20, 0x04, 0xE0, 0x33, 0xF9, 0x11, 0x20, 0x82, 0x42, 0x00, 0xDD, + 0x10, 0x46, 0x49, 0x1E, 0xF8, 0xD2, 0x70, 0x47, 0x03, 0x46, 0x47, 0xF6, + 0xFF, 0x70, 0x04, 0xE0, 0x33, 0xF9, 0x11, 0x20, 0x82, 0x42, 0x00, 0xDA, + 0x10, 0x46, 0x49, 0x1E, 0xF8, 0xD2, 0x00, 0x28, 0x00, 0xDA, 0x00, 0x20, + 0x70, 0x47, 0x02, 0x46, 0xB0, 0xF9, 0x00, 0x00, 0x05, 0xE0, 0x00, 0xBF, + 0x32, 0xF9, 0x11, 0x30, 0x83, 0x42, 0x00, 0xDD, 0x18, 0x46, 0x49, 0x1E, + 0xF8, 0xD2, 0x70, 0x47, 0x70, 0xB5, 0x05, 0x00, 0x03, 0xD0, 0xBD, 0xE8, + 0x70, 0x40, 0x02, 0xF0, 0xE4, 0xBB, 0xFE, 0x4C, 0x21, 0x46, 0x60, 0x78, + 0x09, 0x79, 0x30, 0xB1, 0x0A, 0x46, 0xFC, 0x49, 0x01, 0xF1, 0x98, 0x00, + 0x02, 0xF0, 0x04, 0xFC, 0x0B, 0xE0, 0x20, 0x78, 0x02, 0xF0, 0x42, 0xFD, + 0x21, 0x79, 0x4A, 0x00, 0xF6, 0x49, 0x01, 0xEB, 0x40, 0x01, 0xF5, 0x48, + 0x98, 0x30, 0x02, 0xF0, 0x1C, 0xFF, 0xA0, 0x78, 0xF3, 0x4E, 0x28, 0xB1, + 0xF1, 0x48, 0x21, 0x79, 0x98, 0x30, 0x02, 0xF0, 0x2F, 0xFD, 0x01, 0xE0, + 0xEE, 0x48, 0x98, 0x30, 0xB0, 0x62, 0xE0, 0x78, 0x86, 0xF8, 0x31, 0x00, + 0x28, 0x46, 0xD2, 0xE7, 0x2D, 0xE9, 0xF0, 0x47, 0xDF, 0xF8, 0xAC, 0xA3, + 0x01, 0x27, 0xB8, 0x46, 0xDA, 0xF8, 0x00, 0x00, 0x00, 0xF2, 0x5E, 0x64, + 0x90, 0xF8, 0xA6, 0x19, 0x90, 0xF8, 0xA2, 0x59, 0x01, 0xF0, 0x1F, 0x06, + 0x90, 0xF8, 0xA3, 0x19, 0x01, 0xF0, 0x0F, 0x09, 0x90, 0xF8, 0x82, 0x19, + 0x89, 0x06, 0x09, 0xD5, 0x90, 0xF8, 0x58, 0x16, 0x90, 0xF8, 0x59, 0x06, + 0x0A, 0x22, 0x04, 0xEB, 0x40, 0x00, 0x02, 0xF0, 0x09, 0xFC, 0x07, 0x46, + 0xDA, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0x82, 0x19, 0x49, 0x06, 0x09, 0xD5, + 0x90, 0xF8, 0x68, 0x18, 0x90, 0xF8, 0x69, 0x08, 0x0A, 0x22, 0x04, 0xEB, + 0x40, 0x00, 0x02, 0xF0, 0xF9, 0xFB, 0x80, 0x46, 0x4F, 0xF4, 0x80, 0x70, + 0x85, 0x42, 0x00, 0xD9, 0x05, 0x46, 0x1F, 0x2E, 0x00, 0xD9, 0x1F, 0x26, + 0x76, 0x1C, 0x75, 0x43, 0x09, 0xF1, 0x01, 0x00, 0x45, 0x43, 0xC5, 0xEB, + 0x45, 0x20, 0x78, 0x43, 0x00, 0xFB, 0x08, 0xF0, 0xC0, 0x13, 0xB0, 0xFA, + 0x80, 0xF0, 0xC0, 0xF1, 0x20, 0x00, 0xC0, 0xB2, 0xBD, 0xE8, 0xF0, 0x87, + 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0xEC, 0xF7, 0x61, 0xFA, 0xC2, 0x48, + 0xEC, 0xF7, 0x63, 0xFA, 0xA4, 0xF8, 0x76, 0x00, 0x02, 0xF0, 0xB2, 0xFB, + 0x01, 0x46, 0x20, 0x46, 0xEC, 0xF7, 0xCC, 0xFC, 0x02, 0xF0, 0xB0, 0xFB, + 0x02, 0x46, 0x0B, 0x46, 0x20, 0x46, 0xEC, 0xF7, 0xE7, 0xFC, 0x20, 0x46, + 0x02, 0xF0, 0xE2, 0xFC, 0xB9, 0x4D, 0xB4, 0xF8, 0x56, 0x10, 0x28, 0x68, + 0xB0, 0xF8, 0xBE, 0x20, 0x62, 0xF3, 0x09, 0x01, 0xA4, 0xF8, 0x56, 0x10, + 0x90, 0xF8, 0xBD, 0x00, 0x94, 0xF8, 0x55, 0x10, 0x60, 0xF3, 0x03, 0x01, + 0x84, 0xF8, 0x55, 0x10, 0x04, 0x21, 0x20, 0x46, 0xEC, 0xF7, 0x69, 0xFA, + 0x28, 0x68, 0x90, 0xF8, 0xA2, 0x09, 0xA0, 0x70, 0x28, 0x68, 0x21, 0x8E, + 0xB0, 0xF8, 0xA7, 0x29, 0x62, 0xF3, 0x08, 0x01, 0x21, 0x86, 0x90, 0xF8, + 0xA3, 0x09, 0x00, 0xF0, 0x0F, 0x01, 0x20, 0x46, 0xEC, 0xF7, 0xB7, 0xFA, + 0x28, 0x68, 0x34, 0xF8, 0x1A, 0x1F, 0xB0, 0xF8, 0x8E, 0x29, 0x62, 0xF3, + 0x0B, 0x01, 0x24, 0xF8, 0x12, 0x19, 0xB0, 0xF8, 0x8C, 0x29, 0x21, 0x89, + 0x62, 0xF3, 0x0B, 0x01, 0x21, 0x81, 0xB0, 0xF8, 0x8A, 0x29, 0xA1, 0x88, + 0x62, 0xF3, 0x0B, 0x01, 0xA1, 0x80, 0x90, 0xF8, 0xA4, 0x29, 0xA1, 0x7A, + 0x62, 0xF3, 0x01, 0x01, 0xA1, 0x72, 0x90, 0xF8, 0xA4, 0x29, 0x92, 0x08, + 0x62, 0xF3, 0x87, 0x11, 0xA1, 0x72, 0x90, 0xF8, 0x82, 0x19, 0x14, 0xF8, + 0x01, 0x2C, 0x61, 0xF3, 0x00, 0x02, 0x04, 0xF8, 0x01, 0x2C, 0x90, 0xF8, + 0x85, 0x09, 0x60, 0x70, 0x90, 0x48, 0x90, 0xF8, 0xE8, 0x1E, 0xA1, 0x75, + 0x90, 0xF8, 0xE9, 0x1E, 0x21, 0x77, 0x90, 0xF8, 0xEA, 0x1E, 0xE1, 0x75, + 0x90, 0xF8, 0xEB, 0x1E, 0x61, 0x77, 0x90, 0xF8, 0xEC, 0x1E, 0x21, 0x76, + 0x90, 0xF8, 0xED, 0x0E, 0xA0, 0x77, 0x88, 0x48, 0xEC, 0xF7, 0xE7, 0xF9, + 0xA4, 0xF8, 0x78, 0x00, 0x85, 0x48, 0x20, 0x30, 0xEC, 0xF7, 0xE1, 0xF9, + 0xA4, 0xF8, 0x7C, 0x00, 0x28, 0x68, 0x26, 0x7D, 0x90, 0xF8, 0x92, 0x19, + 0x09, 0x09, 0x61, 0xF3, 0x07, 0x16, 0x26, 0x75, 0x90, 0xF8, 0x97, 0x19, + 0x0A, 0x09, 0xA1, 0x7E, 0x62, 0xF3, 0x07, 0x11, 0xA1, 0x76, 0x90, 0xF8, + 0x93, 0x29, 0x63, 0x7D, 0x62, 0xF3, 0x03, 0x03, 0x63, 0x75, 0x90, 0xF8, + 0x98, 0x79, 0xE2, 0x7E, 0x67, 0xF3, 0x03, 0x02, 0xE2, 0x76, 0x90, 0xF8, + 0x93, 0x79, 0x3F, 0x09, 0x67, 0xF3, 0x07, 0x13, 0x63, 0x75, 0x90, 0xF8, + 0x98, 0x39, 0x1B, 0x09, 0x63, 0xF3, 0x07, 0x12, 0xE2, 0x76, 0x90, 0xF8, + 0x92, 0x29, 0x62, 0xF3, 0x00, 0x06, 0x26, 0x75, 0x90, 0xF8, 0x97, 0x29, + 0x62, 0xF3, 0x00, 0x01, 0xA1, 0x76, 0x90, 0xF8, 0x87, 0x09, 0x01, 0x09, + 0xE0, 0x78, 0x61, 0xF3, 0x03, 0x00, 0xE0, 0x70, 0x66, 0x48, 0x48, 0x38, + 0xEC, 0xF7, 0xA3, 0xF9, 0xA4, 0xF8, 0x76, 0x00, 0x63, 0x48, 0x28, 0x38, + 0xEC, 0xF7, 0x9D, 0xF9, 0xA4, 0xF8, 0x7A, 0x00, 0x29, 0x68, 0x91, 0xF8, + 0x84, 0x09, 0xC2, 0x08, 0x14, 0xF8, 0x1F, 0x0F, 0x62, 0xF3, 0x83, 0x00, + 0x20, 0x70, 0x91, 0xF8, 0x84, 0x29, 0x52, 0x08, 0x62, 0xF3, 0x00, 0x00, + 0x20, 0x70, 0x91, 0xF8, 0x84, 0x29, 0x92, 0x08, 0x62, 0xF3, 0x41, 0x00, + 0x04, 0xF8, 0x27, 0x09, 0x91, 0xF8, 0x83, 0x09, 0xC0, 0xF3, 0x81, 0x01, + 0x20, 0x46, 0xEC, 0xF7, 0xF9, 0xF9, 0x28, 0x68, 0x90, 0xF8, 0x83, 0x09, + 0x01, 0x09, 0x14, 0xF8, 0x28, 0x0F, 0x61, 0xF3, 0x04, 0x10, 0x20, 0x70, + 0x4E, 0x48, 0xEC, 0xF7, 0x72, 0xF9, 0xA4, 0xF8, 0x60, 0x00, 0x4C, 0x48, + 0x20, 0x30, 0xEC, 0xF7, 0x6C, 0xF9, 0xA4, 0xF8, 0x62, 0x00, 0x28, 0x68, + 0x90, 0xF8, 0x82, 0x19, 0xCA, 0x08, 0xE1, 0x7A, 0x62, 0xF3, 0x45, 0x11, + 0xE1, 0x72, 0x90, 0xF8, 0x83, 0x09, 0x41, 0x08, 0x20, 0x78, 0x61, 0xF3, + 0x45, 0x10, 0x04, 0xF8, 0x28, 0x09, 0x20, 0x46, 0x02, 0xF0, 0x8D, 0xFB, + 0x28, 0x68, 0x90, 0xF8, 0x86, 0x09, 0x81, 0x09, 0x20, 0x46, 0xEC, 0xF7, + 0xB8, 0xF9, 0x14, 0xF8, 0x32, 0x0F, 0x20, 0xF0, 0x0F, 0x00, 0x0A, 0x30, + 0x20, 0xF0, 0xF0, 0x00, 0xA0, 0x30, 0x04, 0xF8, 0x1C, 0x09, 0x29, 0x68, + 0x91, 0xF8, 0x82, 0x09, 0x82, 0x09, 0x60, 0x7F, 0x62, 0xF3, 0x00, 0x00, + 0x60, 0x77, 0x91, 0xF8, 0x82, 0x29, 0x52, 0x09, 0x62, 0xF3, 0x41, 0x00, + 0x60, 0x77, 0x91, 0xF8, 0x88, 0x29, 0x62, 0xF3, 0x82, 0x00, 0x60, 0x77, + 0x91, 0xF8, 0xA5, 0x09, 0xE2, 0x7D, 0x60, 0xF3, 0x04, 0x02, 0xE2, 0x75, + 0x91, 0xF8, 0xA6, 0x09, 0xA1, 0x7D, 0x60, 0xF3, 0x04, 0x01, 0x23, 0x48, + 0xA1, 0x75, 0x08, 0x38, 0x94, 0xF8, 0x49, 0x10, 0x40, 0x78, 0x60, 0xF3, + 0x04, 0x01, 0x23, 0x48, 0x84, 0xF8, 0x49, 0x10, 0xE8, 0x30, 0xEC, 0xF7, + 0x1A, 0xF9, 0xA4, 0xF8, 0x64, 0x00, 0x28, 0x68, 0x21, 0x8B, 0xB0, 0xF8, + 0x90, 0x29, 0x62, 0xF3, 0x0B, 0x01, 0x21, 0x83, 0x90, 0xF8, 0x86, 0x19, + 0xCA, 0x08, 0x94, 0xF8, 0x22, 0x10, 0x62, 0xF3, 0x02, 0x01, 0x84, 0xF8, + 0x22, 0x10, 0x10, 0xF8, 0xE0, 0x1F, 0x22, 0x7D, 0x61, 0xF3, 0x03, 0x02, + 0x22, 0x75, 0x10, 0xF8, 0xE0, 0x1B, 0x0A, 0x09, 0x61, 0x7D, 0x62, 0xF3, + 0x03, 0x01, 0x61, 0x75, 0x90, 0xF8, 0xC7, 0x17, 0xE2, 0x7C, 0x61, 0xF3, + 0x02, 0x02, 0xE2, 0x74, 0x90, 0xF8, 0xC2, 0x17, 0xCA, 0x09, 0xA1, 0x7F, + 0x62, 0xF3, 0x00, 0x01, 0xA1, 0x77, 0x94, 0xF8, 0x49, 0x10, 0x41, 0xF0, + 0x20, 0x01, 0x84, 0xF8, 0x49, 0x10, 0x90, 0xF8, 0xC4, 0x27, 0xD2, 0x09, + 0x0E, 0xE0, 0x00, 0x00, 0xC8, 0x07, 0x10, 0x00, 0x7C, 0xA0, 0x01, 0x20, + 0xB4, 0x84, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x78, 0x8B, 0x01, 0x20, + 0x18, 0x9A, 0x01, 0x20, 0x48, 0xBF, 0x01, 0x20, 0x62, 0xF3, 0xC7, 0x11, + 0x84, 0xF8, 0x49, 0x10, 0xB0, 0xF8, 0xDC, 0x27, 0xB4, 0xF8, 0x4A, 0x10, + 0x62, 0xF3, 0x08, 0x01, 0xA4, 0xF8, 0x4A, 0x10, 0x00, 0x21, 0xE1, 0x64, + 0x90, 0xF8, 0xC7, 0x17, 0xCA, 0x08, 0x61, 0x7F, 0x62, 0xF3, 0xC3, 0x01, + 0x61, 0x77, 0x90, 0xF8, 0xC2, 0x27, 0x12, 0x09, 0x62, 0xF3, 0x04, 0x11, + 0x61, 0x77, 0x90, 0xF8, 0xE5, 0x17, 0x4A, 0x09, 0x14, 0xF8, 0x0E, 0x1C, + 0x62, 0xF3, 0x06, 0x11, 0x04, 0xF8, 0x0E, 0x1C, 0x90, 0xF8, 0xC3, 0x17, + 0x4A, 0x09, 0xA1, 0x78, 0x62, 0xF3, 0xC3, 0x01, 0xA1, 0x70, 0x90, 0xF8, + 0xC2, 0x27, 0x52, 0x08, 0x62, 0xF3, 0x04, 0x11, 0xA1, 0x70, 0x90, 0xF8, + 0xC4, 0x07, 0x80, 0x09, 0x60, 0xF3, 0x86, 0x11, 0xA1, 0x70, 0xBD, 0xE8, + 0xF0, 0x81, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0x6A, 0x4D, 0x01, 0x20, + 0x01, 0x29, 0xA8, 0x70, 0x08, 0xD0, 0x00, 0x26, 0x68, 0x4F, 0x02, 0x29, + 0x08, 0xD0, 0x03, 0x29, 0x14, 0xD0, 0x04, 0x29, 0x2C, 0xD1, 0x3C, 0xE0, + 0x20, 0x46, 0x00, 0xF0, 0xC0, 0xF8, 0x27, 0xE0, 0x63, 0x48, 0xFF, 0xF7, + 0x19, 0xFE, 0x20, 0x46, 0x00, 0xF0, 0xB9, 0xF8, 0xB8, 0x78, 0x94, 0xF8, + 0x5F, 0x10, 0x60, 0xF3, 0x04, 0x01, 0x84, 0xF8, 0x5F, 0x10, 0x14, 0xE0, + 0x5C, 0x48, 0xFF, 0xF7, 0x0B, 0xFE, 0x20, 0x46, 0x00, 0xF0, 0xAB, 0xF8, + 0xF8, 0x78, 0x94, 0xF8, 0x5F, 0x10, 0x60, 0xF3, 0x04, 0x01, 0x84, 0xF8, + 0x5F, 0x10, 0x94, 0xF8, 0x27, 0x00, 0x20, 0xF0, 0x02, 0x00, 0x40, 0xF0, + 0x01, 0x00, 0x84, 0xF8, 0x27, 0x00, 0x00, 0x21, 0x20, 0x46, 0xEC, 0xF7, + 0xEE, 0xF8, 0xAE, 0x70, 0x20, 0x46, 0x02, 0xF0, 0xD9, 0xFA, 0x94, 0xF8, + 0x27, 0x00, 0x40, 0xF3, 0x00, 0x00, 0x40, 0x1C, 0xE8, 0x70, 0x4C, 0x48, + 0x00, 0x68, 0x90, 0xF8, 0x83, 0x09, 0xC0, 0xF3, 0x80, 0x10, 0x68, 0x70, + 0xAF, 0xE7, 0x20, 0x46, 0x00, 0xF0, 0x83, 0xF8, 0x14, 0xF8, 0x37, 0x0F, + 0x40, 0xF0, 0x10, 0x00, 0x04, 0xF8, 0x1F, 0x09, 0xE0, 0x7E, 0x20, 0xF0, + 0x23, 0x00, 0xE0, 0x76, 0x34, 0xF8, 0x0C, 0x0C, 0x6F, 0xF3, 0x0B, 0x00, + 0x10, 0x30, 0x24, 0xF8, 0x0C, 0x0C, 0x34, 0xF8, 0x08, 0x0C, 0x6F, 0xF3, + 0x0B, 0x00, 0x40, 0x30, 0x24, 0xF8, 0x08, 0x0C, 0x08, 0x20, 0x04, 0xF8, + 0x16, 0x0C, 0x94, 0xF8, 0x47, 0x00, 0x20, 0xF0, 0x1F, 0x00, 0x84, 0xF8, + 0x47, 0x00, 0x34, 0xF8, 0x18, 0x0F, 0x6F, 0xF3, 0x08, 0x00, 0x24, 0xF8, + 0x03, 0x0B, 0x20, 0x78, 0x40, 0xF0, 0x0C, 0x00, 0x04, 0xF8, 0x0B, 0x09, + 0x20, 0x78, 0x40, 0xF0, 0x20, 0x00, 0x04, 0xF8, 0x28, 0x09, 0xB8, 0xE7, + 0x38, 0xB5, 0x02, 0xF0, 0x69, 0xF9, 0x00, 0x90, 0x04, 0x21, 0x68, 0x46, + 0xEC, 0xF7, 0xBB, 0xFC, 0x26, 0x49, 0x27, 0x4D, 0x08, 0x71, 0x00, 0x20, + 0x28, 0x60, 0x28, 0x71, 0x01, 0x24, 0xE0, 0xB2, 0xFF, 0xF7, 0x50, 0xFD, + 0x28, 0x55, 0x64, 0x1C, 0x05, 0x2C, 0xF8, 0xDB, 0x21, 0x48, 0xFF, 0xF7, + 0x95, 0xFD, 0x38, 0xBD, 0x30, 0xB5, 0x01, 0x7A, 0xA9, 0xB0, 0x79, 0xB3, + 0x68, 0x46, 0xFF, 0xF7, 0x5C, 0xFF, 0x9D, 0xF8, 0x12, 0x00, 0x00, 0xF0, + 0x03, 0x00, 0x02, 0xF0, 0xB7, 0xF9, 0x1A, 0x4C, 0x20, 0x68, 0x00, 0xF2, + 0x5E, 0x63, 0x00, 0xF6, 0x6E, 0x05, 0x90, 0xF8, 0x58, 0x16, 0x90, 0xF8, + 0x59, 0x06, 0x03, 0xEB, 0x40, 0x00, 0x02, 0xF0, 0x7A, 0xF9, 0x20, 0x68, + 0x90, 0xF8, 0x68, 0x18, 0x90, 0xF8, 0x69, 0x08, 0x05, 0xEB, 0x40, 0x00, + 0x02, 0xF0, 0x88, 0xF9, 0x0B, 0x48, 0x41, 0x78, 0x01, 0xB1, 0x02, 0x21, + 0x01, 0x70, 0xC9, 0xB2, 0x68, 0x46, 0xEC, 0xF7, 0x7F, 0xFA, 0x0B, 0x49, + 0x68, 0x46, 0xEC, 0xF7, 0xB0, 0xFA, 0x00, 0x20, 0x29, 0xB0, 0x30, 0xBD, + 0xFF, 0xE7, 0x01, 0x20, 0xFA, 0xE7, 0xA4, 0x22, 0x03, 0x49, 0x02, 0xF0, + 0x18, 0xBC, 0x00, 0x00, 0xC8, 0x07, 0x10, 0x00, 0x74, 0xA0, 0x01, 0x20, + 0xE0, 0x7E, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x95, 0x42, 0x01, 0x00, + 0x10, 0xB5, 0x04, 0x00, 0x03, 0xD0, 0xBD, 0xE8, 0x10, 0x40, 0x02, 0xF0, + 0xB6, 0xB8, 0xFE, 0x48, 0x02, 0x46, 0x81, 0x78, 0x52, 0x78, 0x29, 0xB1, + 0xFC, 0x49, 0xA1, 0xF1, 0x0A, 0x00, 0x02, 0xF0, 0xD7, 0xF8, 0x0B, 0xE0, + 0x03, 0x78, 0x00, 0x21, 0x01, 0x2B, 0x00, 0xD8, 0x11, 0x46, 0xF7, 0x48, + 0x52, 0x00, 0x00, 0xEB, 0x41, 0x01, 0x0A, 0x38, 0x02, 0xF0, 0xEF, 0xFB, + 0xF3, 0x48, 0xF4, 0x49, 0x0A, 0x38, 0xC8, 0x62, 0x20, 0x46, 0xDE, 0xE7, + 0x2D, 0xE9, 0xF0, 0x47, 0xDF, 0xF8, 0xC4, 0xA3, 0x01, 0x27, 0xB8, 0x46, + 0xDA, 0xF8, 0x00, 0x00, 0x00, 0xF2, 0x5E, 0x64, 0x90, 0xF8, 0x22, 0x1A, + 0x90, 0xF8, 0x1E, 0x5A, 0x01, 0xF0, 0x1F, 0x06, 0x90, 0xF8, 0x1F, 0x1A, + 0x01, 0xF0, 0x0F, 0x09, 0x90, 0xF8, 0x02, 0x1A, 0x89, 0x06, 0x09, 0xD5, + 0x90, 0xF8, 0x5C, 0x16, 0x90, 0xF8, 0x5D, 0x06, 0x0A, 0x22, 0x04, 0xEB, + 0x40, 0x00, 0x02, 0xF0, 0xE7, 0xF8, 0x07, 0x46, 0xDA, 0xF8, 0x00, 0x00, + 0x90, 0xF8, 0x02, 0x1A, 0x49, 0x06, 0x09, 0xD5, 0x90, 0xF8, 0x6C, 0x18, + 0x90, 0xF8, 0x6D, 0x08, 0x0A, 0x22, 0x04, 0xEB, 0x40, 0x00, 0x02, 0xF0, + 0xD7, 0xF8, 0x80, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0x85, 0x42, 0x00, 0xD9, + 0x05, 0x46, 0x1F, 0x2E, 0x00, 0xD9, 0x1F, 0x26, 0x76, 0x1C, 0x75, 0x43, + 0x09, 0xF1, 0x01, 0x00, 0x45, 0x43, 0xC5, 0xEB, 0x45, 0x20, 0x78, 0x43, + 0x00, 0xFB, 0x08, 0xF0, 0xC0, 0x13, 0xB0, 0xFA, 0x80, 0xF0, 0xC0, 0xF1, + 0x20, 0x00, 0xC0, 0xB2, 0xBD, 0xE8, 0xF0, 0x87, 0x2D, 0xE9, 0xF0, 0x41, + 0x04, 0x46, 0xEB, 0xF7, 0x3F, 0xFF, 0xC8, 0x48, 0xEB, 0xF7, 0x41, 0xFF, + 0xA4, 0xF8, 0x76, 0x00, 0x02, 0xF0, 0xA5, 0xF8, 0x01, 0x46, 0x20, 0x46, + 0xEC, 0xF7, 0xAA, 0xF9, 0x02, 0xF0, 0xA4, 0xF8, 0x02, 0x46, 0x0B, 0x46, + 0x20, 0x46, 0xEC, 0xF7, 0xC5, 0xF9, 0x04, 0x21, 0x20, 0x46, 0xEB, 0xF7, + 0x5C, 0xFF, 0xBF, 0x4D, 0x28, 0x68, 0x90, 0xF8, 0x1E, 0x0A, 0xA0, 0x70, + 0x28, 0x68, 0x21, 0x8E, 0xB0, 0xF8, 0x23, 0x2A, 0x62, 0xF3, 0x08, 0x01, + 0x21, 0x86, 0x90, 0xF8, 0x1F, 0x0A, 0x00, 0xF0, 0x0F, 0x01, 0x20, 0x46, + 0xEB, 0xF7, 0xA9, 0xFF, 0x28, 0x68, 0x34, 0xF8, 0x1A, 0x1F, 0xB0, 0xF8, + 0x0E, 0x2A, 0x62, 0xF3, 0x0B, 0x01, 0x24, 0xF8, 0x12, 0x19, 0xB0, 0xF8, + 0x0C, 0x2A, 0x21, 0x89, 0x62, 0xF3, 0x0B, 0x01, 0x21, 0x81, 0xB0, 0xF8, + 0x0A, 0x2A, 0xA1, 0x88, 0x62, 0xF3, 0x0B, 0x01, 0xA1, 0x80, 0x90, 0xF8, + 0x20, 0x2A, 0xA1, 0x7A, 0x62, 0xF3, 0x01, 0x01, 0xA1, 0x72, 0x90, 0xF8, + 0x20, 0x2A, 0x92, 0x08, 0x62, 0xF3, 0x87, 0x11, 0xA1, 0x72, 0x90, 0xF8, + 0x02, 0x1A, 0x14, 0xF8, 0x01, 0x2C, 0x61, 0xF3, 0x00, 0x02, 0x04, 0xF8, + 0x01, 0x2C, 0x90, 0xF8, 0x05, 0x0A, 0x60, 0x70, 0xA0, 0x48, 0x90, 0xF8, + 0x80, 0x1F, 0xA1, 0x75, 0x90, 0xF8, 0x81, 0x1F, 0x21, 0x77, 0x90, 0xF8, + 0x82, 0x1F, 0xE1, 0x75, 0x90, 0xF8, 0x83, 0x1F, 0x61, 0x77, 0x90, 0xF8, + 0x84, 0x1F, 0x21, 0x76, 0x90, 0xF8, 0x85, 0x0F, 0xA0, 0x77, 0x98, 0x48, + 0xEB, 0xF7, 0xD9, 0xFE, 0xA4, 0xF8, 0x78, 0x00, 0x95, 0x48, 0x20, 0x30, + 0xEB, 0xF7, 0xD3, 0xFE, 0xA4, 0xF8, 0x7C, 0x00, 0x28, 0x68, 0x23, 0x7D, + 0x90, 0xF8, 0x12, 0x1A, 0x09, 0x09, 0x61, 0xF3, 0x07, 0x13, 0x23, 0x75, + 0x90, 0xF8, 0x17, 0x1A, 0xA6, 0x7E, 0x09, 0x09, 0x61, 0xF3, 0x07, 0x16, + 0xA6, 0x76, 0x90, 0xF8, 0x13, 0x1A, 0x62, 0x7D, 0x61, 0xF3, 0x03, 0x02, + 0x62, 0x75, 0x90, 0xF8, 0x18, 0x7A, 0xE1, 0x7E, 0x67, 0xF3, 0x03, 0x01, + 0xE1, 0x76, 0x90, 0xF8, 0x13, 0x7A, 0x3F, 0x09, 0x67, 0xF3, 0x07, 0x12, + 0x62, 0x75, 0x90, 0xF8, 0x18, 0x2A, 0x12, 0x09, 0x62, 0xF3, 0x07, 0x11, + 0xE1, 0x76, 0x90, 0xF8, 0x12, 0x1A, 0x61, 0xF3, 0x00, 0x03, 0x23, 0x75, + 0x90, 0xF8, 0x17, 0x1A, 0x61, 0xF3, 0x00, 0x06, 0xA6, 0x76, 0x90, 0xF8, + 0x07, 0x0A, 0x01, 0x09, 0xE0, 0x78, 0x61, 0xF3, 0x03, 0x00, 0xE0, 0x70, + 0x76, 0x48, 0x48, 0x38, 0xEB, 0xF7, 0x95, 0xFE, 0xA4, 0xF8, 0x76, 0x00, + 0x73, 0x48, 0x28, 0x38, 0xEB, 0xF7, 0x8F, 0xFE, 0xA4, 0xF8, 0x7A, 0x00, + 0x28, 0x68, 0x90, 0xF8, 0x04, 0x1A, 0xCA, 0x08, 0x14, 0xF8, 0x1F, 0x1F, + 0x62, 0xF3, 0x83, 0x01, 0x41, 0xF0, 0x01, 0x01, 0x21, 0x70, 0x90, 0xF8, + 0x04, 0x2A, 0x92, 0x08, 0x62, 0xF3, 0x41, 0x01, 0x04, 0xF8, 0x27, 0x19, + 0x90, 0xF8, 0x03, 0x0A, 0xC0, 0xF3, 0x81, 0x01, 0x20, 0x46, 0xEB, 0xF7, + 0xEF, 0xFE, 0x28, 0x68, 0x90, 0xF8, 0x03, 0x0A, 0x01, 0x09, 0x14, 0xF8, + 0x28, 0x0F, 0x61, 0xF3, 0x04, 0x10, 0x20, 0x70, 0x60, 0x48, 0xEB, 0xF7, + 0x68, 0xFE, 0xA4, 0xF8, 0x60, 0x00, 0x5E, 0x48, 0x20, 0x30, 0xEB, 0xF7, + 0x62, 0xFE, 0xA4, 0xF8, 0x62, 0x00, 0x28, 0x68, 0x90, 0xF8, 0x02, 0x1A, + 0xCA, 0x08, 0xE1, 0x7A, 0x62, 0xF3, 0x45, 0x11, 0xE1, 0x72, 0x90, 0xF8, + 0x03, 0x0A, 0x41, 0x08, 0x20, 0x78, 0x61, 0xF3, 0x45, 0x10, 0x04, 0xF8, + 0x28, 0x09, 0x20, 0x46, 0x02, 0xF0, 0x4A, 0xF8, 0x28, 0x68, 0x90, 0xF8, + 0x06, 0x0A, 0x81, 0x09, 0x20, 0x46, 0xEB, 0xF7, 0xAE, 0xFE, 0x14, 0xF8, + 0x32, 0x0F, 0x20, 0xF0, 0x0F, 0x00, 0x0A, 0x30, 0x20, 0xF0, 0xF0, 0x00, + 0xA0, 0x30, 0x04, 0xF8, 0x1C, 0x09, 0x29, 0x68, 0x91, 0xF8, 0x02, 0x0A, + 0x82, 0x09, 0x60, 0x7F, 0x62, 0xF3, 0x00, 0x00, 0x60, 0x77, 0x91, 0xF8, + 0x02, 0x2A, 0x52, 0x09, 0x62, 0xF3, 0x41, 0x00, 0x60, 0x77, 0x91, 0xF8, + 0x08, 0x2A, 0x62, 0xF3, 0x82, 0x00, 0x60, 0x77, 0x91, 0xF8, 0x21, 0x0A, + 0xE2, 0x7D, 0x60, 0xF3, 0x04, 0x02, 0xE2, 0x75, 0x91, 0xF8, 0x22, 0x0A, + 0xA1, 0x7D, 0x60, 0xF3, 0x04, 0x01, 0x35, 0x48, 0xA1, 0x75, 0x10, 0x38, + 0x94, 0xF8, 0x49, 0x10, 0x40, 0x78, 0x60, 0xF3, 0x04, 0x01, 0x35, 0x48, + 0x84, 0xF8, 0x49, 0x10, 0x50, 0x30, 0xEB, 0xF7, 0x10, 0xFE, 0xA4, 0xF8, + 0x64, 0x00, 0x28, 0x68, 0x34, 0xF8, 0x18, 0x1F, 0xB0, 0xF8, 0x10, 0x2A, + 0x62, 0xF3, 0x0B, 0x01, 0x24, 0xF8, 0x0A, 0x1B, 0x90, 0xF8, 0x06, 0x1A, + 0xCA, 0x08, 0x21, 0x78, 0x62, 0xF3, 0x02, 0x01, 0x04, 0xF8, 0x0E, 0x19, + 0x10, 0xF8, 0xE0, 0x1F, 0x22, 0x78, 0x61, 0xF3, 0x03, 0x02, 0x04, 0xF8, + 0x01, 0x2B, 0x01, 0x78, 0x0A, 0x09, 0x21, 0x78, 0x62, 0xF3, 0x03, 0x01, + 0x04, 0xF8, 0x02, 0x19, 0x90, 0xF8, 0x27, 0x19, 0x22, 0x78, 0x61, 0xF3, + 0x02, 0x02, 0x04, 0xF8, 0x0B, 0x2B, 0x90, 0xF8, 0x22, 0x19, 0xCA, 0x09, + 0x21, 0x78, 0x62, 0xF3, 0x00, 0x01, 0x04, 0xF8, 0x0E, 0x1B, 0x14, 0xF8, + 0x1D, 0x1F, 0x41, 0xF0, 0x20, 0x01, 0x21, 0x70, 0x90, 0xF8, 0x24, 0x29, + 0xD2, 0x09, 0x62, 0xF3, 0xC7, 0x11, 0x04, 0xF8, 0x01, 0x1B, 0xB0, 0xF8, + 0x3C, 0x29, 0x21, 0x88, 0x62, 0xF3, 0x08, 0x01, 0x24, 0xF8, 0x02, 0x1B, + 0x00, 0x21, 0x44, 0xF8, 0x2F, 0x19, 0x90, 0xF8, 0x27, 0x19, 0xCA, 0x08, + 0x21, 0x78, 0x62, 0xF3, 0xC3, 0x01, 0x21, 0x70, 0x90, 0xF8, 0x22, 0x29, + 0x12, 0x09, 0x62, 0xF3, 0x04, 0x11, 0x04, 0xF8, 0x0C, 0x19, 0x14, 0xF8, + 0x1F, 0x19, 0x21, 0xF0, 0x10, 0x01, 0xE1, 0x77, 0x0E, 0xE0, 0x00, 0x00, + 0xCD, 0x07, 0x10, 0x00, 0x70, 0xA1, 0x01, 0x20, 0xB4, 0x84, 0x10, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x78, 0x8B, 0x01, 0x20, 0xB0, 0x9A, 0x01, 0x20, + 0x48, 0xBF, 0x01, 0x20, 0x90, 0xF8, 0x41, 0x19, 0x4A, 0x09, 0x21, 0x78, + 0x62, 0xF3, 0x06, 0x11, 0x21, 0x70, 0x90, 0xF8, 0x23, 0x19, 0x4A, 0x09, + 0x21, 0x7C, 0x62, 0xF3, 0xC3, 0x01, 0x21, 0x74, 0x90, 0xF8, 0x22, 0x29, + 0x52, 0x08, 0x62, 0xF3, 0x04, 0x11, 0x21, 0x74, 0x90, 0xF8, 0x24, 0x09, + 0x80, 0x09, 0x60, 0xF3, 0x86, 0x11, 0x21, 0x74, 0xBD, 0xE8, 0xF0, 0x81, + 0xF8, 0xB5, 0x01, 0xF0, 0xF0, 0xFE, 0x00, 0x90, 0x04, 0x21, 0x68, 0x46, + 0xEC, 0xF7, 0x2D, 0xFA, 0x45, 0x4E, 0x46, 0x4D, 0x70, 0x70, 0x00, 0x20, + 0x28, 0x60, 0x28, 0x71, 0x01, 0x24, 0xE0, 0xB2, 0xFF, 0xF7, 0xE4, 0xFD, + 0x28, 0x55, 0x64, 0x1C, 0x05, 0x2C, 0xF8, 0xDB, 0x40, 0x48, 0xFF, 0xF7, + 0x29, 0xFE, 0x40, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x03, 0x0A, 0xC0, 0xF3, + 0x80, 0x10, 0xB0, 0x70, 0xF8, 0xBD, 0x30, 0xB5, 0x81, 0x7A, 0xA9, 0xB0, + 0x79, 0xB3, 0x68, 0x46, 0x00, 0xF0, 0x30, 0xF8, 0x9D, 0xF8, 0x12, 0x00, + 0x00, 0xF0, 0x03, 0x00, 0x01, 0xF0, 0x22, 0xFF, 0x35, 0x4C, 0x20, 0x68, + 0x00, 0xF2, 0x5E, 0x63, 0x00, 0xF6, 0x6E, 0x05, 0x90, 0xF8, 0x5C, 0x16, + 0x90, 0xF8, 0x5D, 0x06, 0x03, 0xEB, 0x40, 0x00, 0x01, 0xF0, 0xE5, 0xFE, + 0x20, 0x68, 0x90, 0xF8, 0x6C, 0x18, 0x90, 0xF8, 0x6D, 0x08, 0x05, 0xEB, + 0x40, 0x00, 0x01, 0xF0, 0xF3, 0xFE, 0x27, 0x48, 0x81, 0x78, 0x01, 0xB1, + 0x02, 0x21, 0x01, 0x70, 0xC9, 0xB2, 0x68, 0x46, 0xEB, 0xF7, 0xEA, 0xFF, + 0x26, 0x49, 0x68, 0x46, 0xEC, 0xF7, 0x1B, 0xF8, 0x00, 0x20, 0x29, 0xB0, + 0x30, 0xBD, 0xFF, 0xE7, 0x01, 0x20, 0xFA, 0xE7, 0x70, 0xB5, 0x01, 0x29, + 0x20, 0xD0, 0x1D, 0x4D, 0x03, 0x29, 0x21, 0xD0, 0x04, 0x29, 0x2E, 0xD1, + 0x04, 0x46, 0x1B, 0x48, 0xFF, 0xF7, 0xDE, 0xFD, 0x20, 0x46, 0x00, 0xF0, + 0x29, 0xF8, 0x28, 0x79, 0x94, 0xF8, 0x5F, 0x10, 0x60, 0xF3, 0x04, 0x01, + 0x84, 0xF8, 0x5F, 0x10, 0x94, 0xF8, 0x27, 0x00, 0x20, 0xF0, 0x02, 0x00, + 0x40, 0xF0, 0x01, 0x00, 0x84, 0xF8, 0x27, 0x00, 0x20, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x00, 0x21, 0xEB, 0xF7, 0x9D, 0xBD, 0xBD, 0xE8, 0x70, 0x40, + 0x00, 0xF0, 0x10, 0xB8, 0x04, 0x46, 0x0B, 0x48, 0xFF, 0xF7, 0xBE, 0xFD, + 0x20, 0x46, 0x00, 0xF0, 0x09, 0xF8, 0xE8, 0x78, 0x94, 0xF8, 0x5F, 0x10, + 0x60, 0xF3, 0x04, 0x01, 0x84, 0xF8, 0x5F, 0x10, 0xE6, 0xE7, 0x70, 0xBD, + 0xA4, 0x22, 0x03, 0x49, 0x02, 0xF0, 0x4B, 0xB9, 0xCD, 0x07, 0x10, 0x00, + 0x60, 0xA1, 0x01, 0x20, 0x84, 0x7F, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0xF1, 0x48, 0x01, 0x00, 0x10, 0xB5, 0x04, 0x00, 0x03, 0xD0, 0xBD, 0xE8, + 0x10, 0x40, 0x01, 0xF0, 0xEA, 0xBD, 0x23, 0x48, 0x23, 0x49, 0x00, 0x78, + 0x42, 0x00, 0x01, 0xEB, 0x40, 0x01, 0x21, 0x48, 0x98, 0x30, 0x02, 0xF0, + 0x30, 0xF9, 0x1F, 0x48, 0x1F, 0x49, 0x98, 0x30, 0x48, 0x62, 0x20, 0x46, + 0xEB, 0xE7, 0x38, 0xB5, 0x01, 0xF0, 0x26, 0xFE, 0x00, 0x90, 0x04, 0x21, + 0x68, 0x46, 0xEC, 0xF7, 0x78, 0xF9, 0x17, 0x49, 0x19, 0x4C, 0x08, 0x70, + 0x20, 0x46, 0x00, 0xF0, 0x19, 0xFB, 0x18, 0x48, 0x01, 0x68, 0xA0, 0x7C, + 0x91, 0xF8, 0x50, 0x21, 0x62, 0xF3, 0x01, 0x00, 0xA0, 0x74, 0x91, 0xF8, + 0x50, 0x11, 0x89, 0x08, 0x61, 0xF3, 0x87, 0x10, 0xA0, 0x74, 0x38, 0xBD, + 0x10, 0xB5, 0x0F, 0x4C, 0xC0, 0x79, 0x98, 0xB1, 0x20, 0x46, 0x01, 0xF0, + 0x2F, 0xFF, 0xA0, 0x7C, 0x00, 0xF0, 0x03, 0x00, 0x01, 0xF0, 0x72, 0xFE, + 0x00, 0xF0, 0x8D, 0xFB, 0x04, 0x21, 0x20, 0x46, 0xEB, 0xF7, 0x54, 0xFF, + 0x08, 0x49, 0x20, 0x46, 0xEB, 0xF7, 0x85, 0xFF, 0x00, 0x20, 0x10, 0xBD, + 0x01, 0x20, 0x10, 0xBD, 0xD0, 0x07, 0x10, 0x00, 0x80, 0xA1, 0x01, 0x20, + 0xB4, 0x84, 0x10, 0x00, 0x28, 0x80, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0x89, 0x4E, 0x01, 0x00, 0xFE, 0x49, 0xC8, 0x68, 0x40, 0x1C, 0xC8, 0x60, + 0x02, 0x28, 0x03, 0xD2, 0xFC, 0x49, 0x51, 0xF8, 0x20, 0x00, 0x00, 0x47, + 0x00, 0x20, 0x01, 0xF0, 0x8A, 0xBD, 0x00, 0x28, 0x01, 0xD1, 0xEB, 0xF7, + 0x55, 0xBF, 0x70, 0x47, 0xF5, 0x49, 0x10, 0xB5, 0x0A, 0x79, 0x01, 0x20, + 0x52, 0x1C, 0xD2, 0xB2, 0x0A, 0x71, 0x0B, 0x7A, 0x9A, 0x42, 0x0A, 0xD8, + 0x48, 0x7A, 0x48, 0xB1, 0xEB, 0xF7, 0xB6, 0xFE, 0x03, 0x20, 0xEB, 0xF7, + 0x91, 0xF9, 0xEF, 0x48, 0xEB, 0xF7, 0xA4, 0xFE, 0x00, 0x20, 0x10, 0xBD, + 0xEB, 0xF7, 0x3C, 0xFF, 0xFA, 0xE7, 0x70, 0xB5, 0x18, 0xB1, 0xBD, 0xE8, + 0x70, 0x40, 0x01, 0xF0, 0x66, 0xBD, 0xE6, 0x4C, 0x20, 0x7A, 0x08, 0xB1, + 0xE7, 0x4D, 0x01, 0xE0, 0xE6, 0x4D, 0x76, 0x3D, 0xA0, 0x78, 0xE6, 0x49, + 0x82, 0x00, 0x01, 0xF5, 0xAE, 0x70, 0x02, 0xF0, 0xED, 0xF8, 0x60, 0x79, + 0x28, 0xB1, 0xA2, 0x78, 0xE1, 0x49, 0x28, 0x46, 0x01, 0xF0, 0x7C, 0xFD, + 0x0C, 0xE0, 0xA1, 0x78, 0x60, 0x78, 0x01, 0xF0, 0xB9, 0xFE, 0xA1, 0x78, + 0xC0, 0xB2, 0x4A, 0x00, 0xDB, 0x49, 0x01, 0xEB, 0x40, 0x01, 0x28, 0x46, + 0x02, 0xF0, 0x93, 0xF8, 0xD7, 0x48, 0x23, 0x79, 0xA2, 0x78, 0x29, 0x46, + 0x76, 0x38, 0x01, 0xF0, 0x77, 0xFD, 0xFF, 0xF7, 0xB5, 0xFF, 0x00, 0x28, + 0x15, 0xD0, 0xA0, 0x79, 0xD3, 0x4D, 0x01, 0x28, 0x0B, 0xD0, 0xD0, 0x48, + 0x76, 0x38, 0xA8, 0x61, 0xE0, 0x79, 0x85, 0xF8, 0x30, 0x00, 0x20, 0x79, + 0x85, 0xF8, 0x20, 0x00, 0xBD, 0xE8, 0x70, 0x40, 0x90, 0xE7, 0xCA, 0x48, + 0xA1, 0x78, 0x76, 0x38, 0x01, 0xF0, 0x8E, 0xFE, 0xEF, 0xE7, 0x70, 0xBD, + 0x70, 0xB5, 0x18, 0xB1, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, 0x1B, 0xBD, + 0xC0, 0x4C, 0x20, 0x7A, 0x08, 0xB1, 0xC2, 0x4D, 0x01, 0xE0, 0xC1, 0x4D, + 0x4C, 0x3D, 0xE0, 0x78, 0xC0, 0x49, 0x82, 0x00, 0x01, 0xF5, 0xD8, 0x70, + 0x02, 0xF0, 0xA2, 0xF8, 0x60, 0x79, 0x28, 0xB1, 0xE2, 0x78, 0xBC, 0x49, + 0x28, 0x46, 0x01, 0xF0, 0x31, 0xFD, 0x0C, 0xE0, 0xE1, 0x78, 0x60, 0x78, + 0x01, 0xF0, 0x74, 0xFE, 0xE1, 0x78, 0xC0, 0xB2, 0x4A, 0x00, 0xB6, 0x49, + 0x01, 0xEB, 0x40, 0x01, 0x28, 0x46, 0x02, 0xF0, 0x48, 0xF8, 0xB2, 0x48, + 0x23, 0x79, 0xE2, 0x78, 0x29, 0x46, 0x4C, 0x38, 0x01, 0xF0, 0x2C, 0xFD, + 0xFF, 0xF7, 0x6A, 0xFF, 0x00, 0x28, 0x15, 0xD0, 0xA0, 0x79, 0xAE, 0x4D, + 0x01, 0x28, 0x0B, 0xD0, 0xAA, 0x48, 0x4C, 0x38, 0xE8, 0x61, 0xE0, 0x79, + 0x85, 0xF8, 0x30, 0x00, 0x20, 0x79, 0x85, 0xF8, 0x21, 0x00, 0xBD, 0xE8, + 0x70, 0x40, 0x45, 0xE7, 0xA4, 0x48, 0xE1, 0x78, 0x4C, 0x38, 0x01, 0xF0, + 0x44, 0xFE, 0xEF, 0xE7, 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x5F, 0xA3, 0x48, + 0x01, 0x27, 0xB8, 0x46, 0x00, 0x68, 0x00, 0xF2, 0x5E, 0x64, 0x90, 0xF8, + 0x33, 0x11, 0x90, 0xF8, 0x4E, 0x51, 0xC1, 0xF3, 0x80, 0x1B, 0x90, 0xF8, + 0x55, 0x11, 0x01, 0xF0, 0x03, 0x0A, 0x90, 0xF8, 0x52, 0x11, 0x01, 0xF0, + 0x1F, 0x06, 0x90, 0xF8, 0x4F, 0x11, 0x01, 0xF0, 0x0F, 0x09, 0x90, 0xF8, + 0x32, 0x11, 0x89, 0x06, 0x09, 0xD5, 0x90, 0xF8, 0x56, 0x16, 0x90, 0xF8, + 0x57, 0x06, 0x0A, 0x22, 0x04, 0xEB, 0x40, 0x00, 0x01, 0xF0, 0x1E, 0xFD, + 0x07, 0x46, 0x90, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x32, 0x11, 0x49, 0x06, + 0x09, 0xD5, 0x90, 0xF8, 0x66, 0x18, 0x90, 0xF8, 0x67, 0x08, 0x0A, 0x22, + 0x04, 0xEB, 0x40, 0x00, 0x01, 0xF0, 0x0E, 0xFD, 0x80, 0x46, 0x4F, 0xF4, + 0x80, 0x70, 0x85, 0x42, 0x00, 0xD9, 0x05, 0x46, 0x1F, 0x2E, 0x00, 0xD9, + 0x1F, 0x26, 0x76, 0x1C, 0x75, 0x43, 0x09, 0xF1, 0x01, 0x00, 0x45, 0x43, + 0xC5, 0xEB, 0x45, 0x20, 0x78, 0x43, 0x00, 0xFB, 0x08, 0xF0, 0x0A, 0xF1, + 0x01, 0x01, 0x48, 0x43, 0x0B, 0xF1, 0x01, 0x01, 0x48, 0x43, 0xC0, 0x13, + 0xB0, 0xFA, 0x80, 0xF0, 0xC0, 0xF1, 0x20, 0x00, 0xC0, 0xB2, 0xBD, 0xE8, + 0xF0, 0x9F, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0xEB, 0xF7, 0x70, 0xFB, + 0x73, 0x48, 0xEB, 0xF7, 0x72, 0xFB, 0xA4, 0xF8, 0x76, 0x00, 0x01, 0xF0, + 0xC1, 0xFC, 0x01, 0x46, 0x20, 0x46, 0xEB, 0xF7, 0xDB, 0xFD, 0x01, 0xF0, + 0xBF, 0xFC, 0x02, 0x46, 0x0B, 0x46, 0x20, 0x46, 0xEB, 0xF7, 0xF6, 0xFD, + 0x20, 0x46, 0x01, 0xF0, 0xF1, 0xFD, 0x6B, 0x4D, 0xB4, 0xF8, 0x56, 0x10, + 0x28, 0x68, 0xB0, 0xF8, 0xBE, 0x20, 0x62, 0xF3, 0x09, 0x01, 0xA4, 0xF8, + 0x56, 0x10, 0x90, 0xF8, 0xBD, 0x10, 0x94, 0xF8, 0x55, 0x00, 0x61, 0xF3, + 0x03, 0x00, 0x84, 0xF8, 0x55, 0x00, 0x04, 0x21, 0x20, 0x46, 0xEB, 0xF7, + 0x78, 0xFB, 0x28, 0x68, 0x90, 0xF8, 0x4E, 0x01, 0xA0, 0x70, 0x28, 0x68, + 0x21, 0x8E, 0xB0, 0xF8, 0x53, 0x21, 0x62, 0xF3, 0x08, 0x01, 0x21, 0x86, + 0x90, 0xF8, 0x4F, 0x01, 0x00, 0xF0, 0x0F, 0x01, 0x20, 0x46, 0xEB, 0xF7, + 0xC6, 0xFB, 0x28, 0x68, 0x34, 0xF8, 0x1A, 0x1F, 0xB0, 0xF8, 0x3E, 0x21, + 0x62, 0xF3, 0x0B, 0x01, 0x24, 0xF8, 0x12, 0x19, 0xB0, 0xF8, 0x3C, 0x21, + 0x21, 0x89, 0x62, 0xF3, 0x0B, 0x01, 0x21, 0x81, 0xB0, 0xF8, 0x3A, 0x21, + 0xA1, 0x88, 0x62, 0xF3, 0x0B, 0x01, 0xA1, 0x80, 0x90, 0xF8, 0x50, 0x21, + 0xA1, 0x7A, 0x62, 0xF3, 0x01, 0x01, 0xA1, 0x72, 0x90, 0xF8, 0x50, 0x21, + 0x92, 0x08, 0x62, 0xF3, 0x87, 0x11, 0xA1, 0x72, 0x90, 0xF8, 0x32, 0x11, + 0x14, 0xF8, 0x01, 0x2C, 0x61, 0xF3, 0x00, 0x02, 0x04, 0xF8, 0x01, 0x2C, + 0x90, 0xF8, 0x35, 0x01, 0x60, 0x70, 0x42, 0x48, 0x90, 0xF8, 0x50, 0x1E, + 0xA1, 0x75, 0x90, 0xF8, 0x51, 0x1E, 0x21, 0x77, 0x90, 0xF8, 0x52, 0x1E, + 0xE1, 0x75, 0x90, 0xF8, 0x53, 0x1E, 0x61, 0x77, 0x90, 0xF8, 0x54, 0x1E, + 0x21, 0x76, 0x90, 0xF8, 0x55, 0x0E, 0xA0, 0x77, 0x39, 0x48, 0xEB, 0xF7, + 0xF6, 0xFA, 0xA4, 0xF8, 0x78, 0x00, 0x37, 0x48, 0x20, 0x30, 0xEB, 0xF7, + 0xF0, 0xFA, 0xA4, 0xF8, 0x7C, 0x00, 0x28, 0x68, 0x90, 0xF8, 0x42, 0x11, + 0x0A, 0x09, 0x21, 0x7D, 0x62, 0xF3, 0x07, 0x11, 0x21, 0x75, 0x90, 0xF8, + 0x47, 0x21, 0xA3, 0x7E, 0x12, 0x09, 0x62, 0xF3, 0x07, 0x13, 0xA3, 0x76, + 0x90, 0xF8, 0x43, 0x61, 0x62, 0x7D, 0x66, 0xF3, 0x03, 0x02, 0x62, 0x75, + 0x90, 0xF8, 0x48, 0x71, 0xE6, 0x7E, 0x67, 0xF3, 0x03, 0x06, 0xE6, 0x76, + 0x90, 0xF8, 0x43, 0x71, 0x3F, 0x09, 0x67, 0xF3, 0x07, 0x12, 0x62, 0x75, + 0x90, 0xF8, 0x48, 0x21, 0x12, 0x09, 0x62, 0xF3, 0x07, 0x16, 0xE6, 0x76, + 0x90, 0xF8, 0x42, 0x21, 0x62, 0xF3, 0x00, 0x01, 0x21, 0x75, 0x90, 0xF8, + 0x47, 0x11, 0x61, 0xF3, 0x00, 0x03, 0xA3, 0x76, 0x90, 0xF8, 0x37, 0x01, + 0x01, 0x09, 0xE0, 0x78, 0x61, 0xF3, 0x03, 0x00, 0xE0, 0x70, 0x18, 0x48, + 0x48, 0x38, 0xEB, 0xF7, 0xB2, 0xFA, 0xA4, 0xF8, 0x76, 0x00, 0x15, 0x48, + 0x28, 0x38, 0xEB, 0xF7, 0xAC, 0xFA, 0xA4, 0xF8, 0x7A, 0x00, 0x29, 0x68, + 0x91, 0xF8, 0x34, 0x01, 0xC2, 0x08, 0x14, 0xF8, 0x1F, 0x0F, 0x62, 0xF3, + 0x83, 0x00, 0x20, 0x70, 0x91, 0xF8, 0x34, 0x21, 0x52, 0x08, 0x62, 0xF3, + 0x00, 0x00, 0x20, 0x70, 0x91, 0xF8, 0x34, 0x21, 0x92, 0x08, 0x62, 0xF3, + 0x41, 0x00, 0x11, 0xE0, 0xD4, 0x07, 0x10, 0x00, 0x04, 0x7D, 0x01, 0x00, + 0x57, 0x4F, 0x01, 0x00, 0x7A, 0xA3, 0x01, 0x20, 0x6C, 0xA2, 0x01, 0x20, + 0xB4, 0x84, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x78, 0x8B, 0x01, 0x20, + 0x80, 0x99, 0x01, 0x20, 0x04, 0xF8, 0x27, 0x09, 0x91, 0xF8, 0x33, 0x01, + 0xC0, 0xF3, 0x81, 0x01, 0x20, 0x46, 0xEB, 0xF7, 0xF5, 0xFA, 0x28, 0x68, + 0x90, 0xF8, 0x33, 0x01, 0x01, 0x09, 0x14, 0xF8, 0x28, 0x0F, 0x61, 0xF3, + 0x04, 0x10, 0x20, 0x70, 0xF8, 0x48, 0xEB, 0xF7, 0x6E, 0xFA, 0xA4, 0xF8, + 0x60, 0x00, 0xF6, 0x48, 0x20, 0x30, 0xEB, 0xF7, 0x68, 0xFA, 0xA4, 0xF8, + 0x62, 0x00, 0x28, 0x68, 0x90, 0xF8, 0x32, 0x11, 0xCA, 0x08, 0xE1, 0x7A, + 0x62, 0xF3, 0x45, 0x11, 0xE1, 0x72, 0x90, 0xF8, 0x33, 0x01, 0x41, 0x08, + 0x20, 0x78, 0x61, 0xF3, 0x45, 0x10, 0x04, 0xF8, 0x28, 0x09, 0x20, 0x46, + 0x01, 0xF0, 0x50, 0xFC, 0x28, 0x68, 0x90, 0xF8, 0x36, 0x01, 0x81, 0x09, + 0x20, 0x46, 0xEB, 0xF7, 0xB4, 0xFA, 0x14, 0xF8, 0x32, 0x0F, 0x20, 0xF0, + 0x0F, 0x00, 0x0A, 0x30, 0x20, 0xF0, 0xF0, 0x00, 0xA0, 0x30, 0x04, 0xF8, + 0x1C, 0x09, 0x29, 0x68, 0x91, 0xF8, 0x32, 0x01, 0x82, 0x09, 0x60, 0x7F, + 0x62, 0xF3, 0x00, 0x00, 0x60, 0x77, 0x91, 0xF8, 0x32, 0x21, 0x52, 0x09, + 0x62, 0xF3, 0x41, 0x00, 0x60, 0x77, 0x91, 0xF8, 0x38, 0x21, 0x62, 0xF3, + 0x82, 0x00, 0x60, 0x77, 0x91, 0xF8, 0x51, 0x01, 0xE2, 0x7D, 0x60, 0xF3, + 0x04, 0x02, 0xE2, 0x75, 0x91, 0xF8, 0x52, 0x01, 0xA1, 0x7D, 0x60, 0xF3, + 0x04, 0x01, 0xD3, 0x48, 0xA1, 0x75, 0x94, 0xF8, 0x49, 0x10, 0x40, 0x78, + 0x60, 0xF3, 0x04, 0x01, 0x84, 0xF8, 0x49, 0x10, 0xCF, 0x48, 0xEB, 0xF7, + 0x18, 0xFA, 0xA4, 0xF8, 0x64, 0x00, 0x28, 0x68, 0x21, 0x8B, 0xB0, 0xF8, + 0x40, 0x21, 0x62, 0xF3, 0x0B, 0x01, 0x21, 0x83, 0x90, 0xF8, 0x36, 0x11, + 0xCA, 0x08, 0x94, 0xF8, 0x22, 0x10, 0x62, 0xF3, 0x02, 0x01, 0x84, 0xF8, + 0x22, 0x10, 0x10, 0xF8, 0xE0, 0x1F, 0x22, 0x7D, 0x61, 0xF3, 0x03, 0x02, + 0x22, 0x75, 0x10, 0xF8, 0x52, 0x1B, 0x0A, 0x09, 0x61, 0x7D, 0x62, 0xF3, + 0x03, 0x01, 0x61, 0x75, 0x42, 0x79, 0xE1, 0x7C, 0x62, 0xF3, 0x02, 0x01, + 0xE1, 0x74, 0x01, 0x78, 0xCA, 0x09, 0xA1, 0x7F, 0x62, 0xF3, 0x00, 0x01, + 0xA1, 0x77, 0x94, 0xF8, 0x49, 0x10, 0x41, 0xF0, 0x20, 0x01, 0x84, 0xF8, + 0x49, 0x10, 0x82, 0x78, 0xD2, 0x09, 0x62, 0xF3, 0xC7, 0x11, 0x84, 0xF8, + 0x49, 0x10, 0x42, 0x8B, 0xB4, 0xF8, 0x4A, 0x10, 0x62, 0xF3, 0x08, 0x01, + 0xA4, 0xF8, 0x4A, 0x10, 0x00, 0x21, 0xE1, 0x64, 0x41, 0x79, 0xCA, 0x08, + 0x61, 0x7F, 0x62, 0xF3, 0xC3, 0x01, 0x61, 0x77, 0x02, 0x78, 0x12, 0x09, + 0x62, 0xF3, 0x04, 0x11, 0x61, 0x77, 0xC1, 0x7F, 0x4A, 0x09, 0x14, 0xF8, + 0x0E, 0x1C, 0x62, 0xF3, 0x06, 0x11, 0x04, 0xF8, 0x0E, 0x1C, 0x41, 0x78, + 0x4A, 0x09, 0xA1, 0x78, 0x62, 0xF3, 0xC3, 0x01, 0xA1, 0x70, 0x02, 0x78, + 0x52, 0x08, 0x62, 0xF3, 0x04, 0x11, 0xA1, 0x70, 0x82, 0x78, 0x92, 0x09, + 0x62, 0xF3, 0x86, 0x11, 0xA1, 0x70, 0x40, 0x78, 0x9D, 0x49, 0xC0, 0xF3, + 0x80, 0x10, 0x48, 0x71, 0xBD, 0xE8, 0xF0, 0x81, 0xA4, 0x22, 0x9B, 0x49, + 0x01, 0xF0, 0xFF, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x97, 0x4D, 0x00, 0x26, + 0x01, 0x27, 0x2E, 0x71, 0x2E, 0x72, 0xAF, 0x71, 0x0C, 0x46, 0x6E, 0x72, + 0x01, 0x28, 0x07, 0xD0, 0x90, 0x4F, 0x02, 0x28, 0x2C, 0xD0, 0x03, 0x28, + 0x14, 0xD0, 0x04, 0x28, 0x3A, 0xD1, 0x43, 0xE0, 0x08, 0x46, 0xFF, 0xF7, + 0xE5, 0xFF, 0x8F, 0x48, 0x01, 0x68, 0x91, 0xF8, 0x38, 0x01, 0x42, 0x06, + 0x30, 0xD5, 0x91, 0xF8, 0x55, 0x11, 0x00, 0x06, 0x01, 0xF0, 0x03, 0x01, + 0x29, 0x72, 0x29, 0xD5, 0x6F, 0x72, 0x27, 0xE0, 0x86, 0x48, 0xFF, 0xF7, + 0x08, 0xFE, 0x20, 0x46, 0xFF, 0xF7, 0xD0, 0xFF, 0xF8, 0x78, 0x94, 0xF8, + 0x5F, 0x10, 0x60, 0xF3, 0x04, 0x01, 0x84, 0xF8, 0x5F, 0x10, 0x94, 0xF8, + 0x27, 0x00, 0x20, 0xF0, 0x02, 0x00, 0x40, 0xF0, 0x01, 0x00, 0x84, 0xF8, + 0x27, 0x00, 0x0C, 0xE0, 0x7B, 0x48, 0xFF, 0xF7, 0xF2, 0xFD, 0x20, 0x46, + 0xFF, 0xF7, 0xBA, 0xFF, 0xB8, 0x78, 0x94, 0xF8, 0x5F, 0x10, 0x60, 0xF3, + 0x04, 0x01, 0x84, 0xF8, 0x5F, 0x10, 0x00, 0x21, 0x20, 0x46, 0xEB, 0xF7, + 0xEC, 0xF9, 0xAE, 0x71, 0x20, 0x46, 0x01, 0xF0, 0xD7, 0xFB, 0x94, 0xF8, + 0x27, 0x00, 0x40, 0xF3, 0x00, 0x00, 0x40, 0x1C, 0xE8, 0x71, 0xA1, 0xE7, + 0x08, 0x46, 0xFF, 0xF7, 0xA1, 0xFF, 0x14, 0xF8, 0x37, 0x0F, 0x40, 0xF0, + 0x10, 0x00, 0x04, 0xF8, 0x1F, 0x09, 0xE0, 0x7E, 0x20, 0xF0, 0x23, 0x00, + 0xE0, 0x76, 0x34, 0xF8, 0x0C, 0x0C, 0x6F, 0xF3, 0x0B, 0x00, 0x10, 0x30, + 0x24, 0xF8, 0x0C, 0x0C, 0x34, 0xF8, 0x08, 0x0C, 0x6F, 0xF3, 0x0B, 0x00, + 0x40, 0x30, 0x24, 0xF8, 0x08, 0x0C, 0x08, 0x20, 0x04, 0xF8, 0x16, 0x0C, + 0x94, 0xF8, 0x47, 0x00, 0x20, 0xF0, 0x1F, 0x00, 0x84, 0xF8, 0x47, 0x00, + 0x34, 0xF8, 0x18, 0x0F, 0x6F, 0xF3, 0x08, 0x00, 0x24, 0xF8, 0x03, 0x0B, + 0x20, 0x78, 0x40, 0xF0, 0x0C, 0x00, 0x04, 0xF8, 0x0B, 0x09, 0x20, 0x78, + 0x40, 0xF0, 0x20, 0x00, 0x04, 0xF8, 0x28, 0x09, 0xBF, 0xE7, 0x70, 0xB5, + 0x53, 0x4D, 0x28, 0x68, 0x00, 0xF2, 0x5E, 0x62, 0x00, 0xF6, 0x6E, 0x04, + 0x90, 0xF8, 0x56, 0x16, 0x90, 0xF8, 0x57, 0x06, 0x02, 0xEB, 0x40, 0x00, + 0x01, 0xF0, 0xA5, 0xFA, 0x28, 0x68, 0x90, 0xF8, 0x66, 0x18, 0x90, 0xF8, + 0x67, 0x08, 0x04, 0xEB, 0x40, 0x00, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, + 0xB1, 0xBA, 0x70, 0xB5, 0x44, 0x4D, 0x45, 0x4C, 0x68, 0x79, 0xA4, 0x34, + 0x00, 0xB1, 0x02, 0x20, 0x68, 0x70, 0x21, 0x46, 0x28, 0x78, 0xFF, 0xF7, + 0x4D, 0xFF, 0x41, 0x48, 0x01, 0x68, 0xA0, 0x7C, 0x91, 0xF8, 0x50, 0x21, + 0x62, 0xF3, 0x01, 0x00, 0xA0, 0x74, 0x91, 0xF8, 0x50, 0x11, 0x89, 0x08, + 0x61, 0xF3, 0x87, 0x10, 0xA0, 0x74, 0x69, 0x78, 0x20, 0x46, 0xEB, 0xF7, + 0x93, 0xFB, 0xA0, 0x7C, 0x00, 0xF0, 0x03, 0x00, 0x01, 0xF0, 0xA6, 0xFA, + 0xFF, 0xF7, 0xC1, 0xFF, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x34, 0x49, + 0xEB, 0xF7, 0xBB, 0xBB, 0x70, 0xB5, 0x2F, 0x4D, 0x2F, 0x4C, 0x68, 0x79, + 0xA4, 0x34, 0x08, 0xB1, 0x03, 0x20, 0x00, 0xE0, 0x01, 0x20, 0x68, 0x70, + 0x21, 0x46, 0x28, 0x78, 0xFF, 0xF7, 0x20, 0xFF, 0x2A, 0x48, 0x01, 0x68, + 0x91, 0xF8, 0x50, 0x01, 0x02, 0x09, 0xA0, 0x7C, 0x62, 0xF3, 0x01, 0x00, + 0xA0, 0x74, 0x91, 0xF8, 0x50, 0x11, 0x89, 0x09, 0x61, 0xF3, 0x87, 0x10, + 0xA0, 0x74, 0x69, 0x78, 0x20, 0x46, 0xEB, 0xF7, 0x65, 0xFB, 0xA0, 0x7C, + 0x00, 0xF0, 0x03, 0x00, 0x01, 0xF0, 0x78, 0xFA, 0xFF, 0xF7, 0x93, 0xFF, + 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x1E, 0x49, 0xEB, 0xF7, 0x8D, 0xBB, + 0x7F, 0xB5, 0x01, 0xF0, 0xFB, 0xF9, 0x01, 0x90, 0x01, 0xF0, 0xFC, 0xF9, + 0xCD, 0xE9, 0x02, 0x01, 0x04, 0x21, 0x01, 0xA8, 0xEB, 0xF7, 0x49, 0xFD, + 0x12, 0x4C, 0x08, 0x21, 0xA0, 0x70, 0x02, 0xA8, 0xEB, 0xF7, 0x43, 0xFD, + 0xE0, 0x70, 0x0D, 0x4D, 0x01, 0x24, 0xE0, 0xB2, 0xFF, 0xF7, 0xC1, 0xFC, + 0x28, 0x55, 0x64, 0x1C, 0x05, 0x2C, 0xF8, 0xDB, 0x0B, 0x48, 0xFF, 0xF7, + 0x12, 0xFD, 0x7F, 0xBD, 0x10, 0xB5, 0x80, 0x79, 0xC0, 0xB1, 0x07, 0x49, + 0x08, 0x70, 0x4F, 0xF0, 0xFF, 0x30, 0xC8, 0x60, 0xFF, 0xF7, 0xEE, 0xFB, + 0x00, 0x20, 0x10, 0xBD, 0x48, 0xBF, 0x01, 0x20, 0x64, 0xA2, 0x01, 0x20, + 0x00, 0x9B, 0x01, 0x20, 0xD4, 0x07, 0x10, 0x00, 0xCC, 0x80, 0x10, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x93, 0x4F, 0x01, 0x00, 0x29, 0x50, 0x01, 0x00, + 0x01, 0x20, 0xEC, 0xE7, 0x2D, 0xE9, 0xF0, 0x47, 0xF9, 0x49, 0x02, 0x46, + 0x01, 0x27, 0x08, 0x68, 0xB8, 0x46, 0x00, 0xF2, 0x5E, 0x64, 0x02, 0x2A, + 0x01, 0xD0, 0x03, 0x2A, 0x3C, 0xD0, 0x89, 0x46, 0x90, 0xF8, 0x23, 0x11, + 0x90, 0xF8, 0x1F, 0x61, 0x01, 0xF0, 0x1F, 0x05, 0x90, 0xF8, 0x12, 0x11, + 0x89, 0x06, 0x09, 0xD5, 0x90, 0xF8, 0x5A, 0x16, 0x90, 0xF8, 0x5B, 0x06, + 0x0A, 0x22, 0x04, 0xEB, 0x40, 0x00, 0x01, 0xF0, 0xBF, 0xF9, 0x07, 0x46, + 0xD9, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0x12, 0x11, 0x49, 0x06, 0x09, 0xD5, + 0x90, 0xF8, 0x6A, 0x18, 0x90, 0xF8, 0x6B, 0x08, 0x0A, 0x22, 0x04, 0xEB, + 0x40, 0x00, 0x01, 0xF0, 0xAF, 0xF9, 0x80, 0x46, 0x4F, 0xF4, 0x80, 0x70, + 0x86, 0x42, 0x00, 0xD9, 0x06, 0x46, 0x1F, 0x2D, 0x00, 0xD9, 0x1F, 0x25, + 0x6D, 0x1C, 0x6E, 0x43, 0x70, 0x00, 0xC0, 0xEB, 0x40, 0x20, 0x78, 0x43, + 0x00, 0xFB, 0x08, 0xF0, 0xC0, 0x13, 0xB0, 0xFA, 0x80, 0xF0, 0xC0, 0xF1, + 0x20, 0x00, 0xC0, 0xB2, 0xBD, 0xE8, 0xF0, 0x87, 0x10, 0xF8, 0xD3, 0x6F, + 0x00, 0x79, 0x00, 0xF0, 0x1F, 0x05, 0xE1, 0xE7, 0x70, 0xB5, 0x05, 0x00, + 0x03, 0xD0, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, 0x1A, 0xB9, 0xD0, 0x48, + 0xD0, 0x4E, 0x00, 0x78, 0x01, 0x28, 0x01, 0xD0, 0xCF, 0x48, 0x16, 0xE0, + 0xCB, 0x4C, 0xCE, 0x49, 0x22, 0x68, 0xA1, 0xF1, 0x08, 0x00, 0x02, 0xF2, + 0x72, 0x42, 0x00, 0xF0, 0xD1, 0xF9, 0x22, 0x68, 0x92, 0xF8, 0x60, 0x04, + 0xC0, 0x07, 0x06, 0xD0, 0xC7, 0x49, 0x02, 0xF2, 0x76, 0x42, 0xA1, 0xF1, + 0x08, 0x00, 0x00, 0xF0, 0xC5, 0xF9, 0xC4, 0x48, 0x08, 0x38, 0x70, 0x61, + 0x28, 0x46, 0xDA, 0xE7, 0x70, 0xB5, 0x04, 0x46, 0xEA, 0xF7, 0xEC, 0xFF, + 0xBF, 0x48, 0xEA, 0xF7, 0xEE, 0xFF, 0xA4, 0xF8, 0x76, 0x00, 0x01, 0xF0, + 0x3D, 0xF9, 0x01, 0x46, 0x00, 0x22, 0x20, 0x46, 0xEB, 0xF7, 0x88, 0xF9, + 0x01, 0xF0, 0x3A, 0xF9, 0x02, 0x46, 0x0B, 0x46, 0x20, 0x46, 0xEB, 0xF7, + 0xAD, 0xF9, 0xA0, 0x79, 0x00, 0x21, 0x20, 0xF0, 0x02, 0x00, 0xA0, 0x71, + 0x94, 0xF8, 0x6F, 0x00, 0x20, 0xF0, 0x07, 0x00, 0x84, 0xF8, 0x6F, 0x00, + 0x94, 0xF8, 0x6E, 0x00, 0x20, 0xF0, 0x0F, 0x00, 0x84, 0xF8, 0x6E, 0x00, + 0x20, 0x46, 0xEB, 0xF7, 0xB3, 0xF9, 0x94, 0xF8, 0x5E, 0x00, 0x20, 0xF0, + 0x01, 0x00, 0x84, 0xF8, 0x5E, 0x00, 0x20, 0x46, 0x01, 0xF0, 0x52, 0xFA, + 0x04, 0x21, 0x20, 0x46, 0xEA, 0xF7, 0xEB, 0xFF, 0xA2, 0x4D, 0x28, 0x68, + 0x90, 0xF8, 0x1F, 0x01, 0xA0, 0x70, 0x28, 0x68, 0x21, 0x8E, 0xB0, 0xF8, + 0x24, 0x21, 0x62, 0xF3, 0x08, 0x01, 0x21, 0x86, 0x90, 0xF8, 0x20, 0x01, + 0x00, 0xF0, 0x0F, 0x01, 0x20, 0x46, 0xEB, 0xF7, 0x38, 0xF8, 0x28, 0x68, + 0x62, 0x7D, 0x90, 0xF8, 0x16, 0x11, 0x61, 0xF3, 0x03, 0x02, 0x62, 0x75, + 0xB0, 0xF8, 0x19, 0x21, 0x21, 0x8A, 0x62, 0xF3, 0x0B, 0x01, 0x21, 0x82, + 0x90, 0xF8, 0x21, 0x11, 0xA2, 0x7D, 0x61, 0xF3, 0x03, 0x02, 0xA2, 0x75, + 0xB0, 0xF8, 0x1B, 0x21, 0xA1, 0x89, 0x62, 0xF3, 0x0B, 0x01, 0xA1, 0x81, + 0x90, 0xF8, 0x20, 0x11, 0x0A, 0x09, 0xA1, 0x7C, 0x62, 0xF3, 0x01, 0x01, + 0xA1, 0x74, 0x90, 0xF8, 0x20, 0x21, 0x92, 0x09, 0x62, 0xF3, 0x87, 0x11, + 0xA1, 0x74, 0x90, 0xF8, 0x12, 0x11, 0xE2, 0x79, 0x61, 0xF3, 0x00, 0x02, + 0xE2, 0x71, 0x90, 0xF8, 0x15, 0x11, 0x61, 0x72, 0x90, 0xF8, 0x18, 0x01, + 0x01, 0x09, 0xE0, 0x7A, 0x61, 0xF3, 0x03, 0x00, 0xE0, 0x72, 0x82, 0x48, + 0xEA, 0xF7, 0x71, 0xFF, 0xA4, 0xF8, 0x7C, 0x00, 0x29, 0x68, 0x91, 0xF8, + 0x14, 0x01, 0xC2, 0x08, 0x94, 0xF8, 0x27, 0x00, 0x62, 0xF3, 0x83, 0x00, + 0x20, 0xF0, 0x02, 0x00, 0x40, 0xF0, 0x01, 0x00, 0x84, 0xF8, 0x27, 0x00, + 0x91, 0xF8, 0x13, 0x01, 0xC0, 0xF3, 0x81, 0x01, 0x20, 0x46, 0xEA, 0xF7, + 0xD5, 0xFF, 0x28, 0x68, 0x90, 0xF8, 0x13, 0x01, 0x01, 0x09, 0x14, 0xF8, + 0x28, 0x0F, 0x61, 0xF3, 0x04, 0x10, 0x20, 0x70, 0x71, 0x48, 0xEA, 0xF7, + 0x4E, 0xFF, 0xA4, 0xF8, 0x5E, 0x00, 0x28, 0x68, 0x90, 0xF8, 0x12, 0x11, + 0xCA, 0x08, 0xE1, 0x7A, 0x62, 0xF3, 0x45, 0x11, 0xE1, 0x72, 0x90, 0xF8, + 0x13, 0x01, 0x41, 0x08, 0x20, 0x78, 0x61, 0xF3, 0x45, 0x10, 0x04, 0xF8, + 0x28, 0x09, 0x20, 0x46, 0x01, 0xF0, 0x10, 0xF9, 0x28, 0x68, 0x90, 0xF8, + 0x18, 0x01, 0xC0, 0xF3, 0x81, 0x01, 0x20, 0x46, 0xEA, 0xF7, 0x99, 0xFF, + 0x14, 0xF8, 0x32, 0x0F, 0x20, 0xF0, 0x0F, 0x00, 0x0A, 0x30, 0x20, 0xF0, + 0xF0, 0x00, 0xA0, 0x30, 0x04, 0xF8, 0x0A, 0x09, 0x29, 0x68, 0x91, 0xF8, + 0x12, 0x01, 0x82, 0x09, 0xE0, 0x7A, 0x62, 0xF3, 0x00, 0x00, 0xE0, 0x72, + 0x91, 0xF8, 0x12, 0x21, 0x52, 0x09, 0x62, 0xF3, 0x41, 0x00, 0xE0, 0x72, + 0x91, 0xF8, 0x17, 0x21, 0xD2, 0x09, 0x62, 0xF3, 0x82, 0x00, 0xE0, 0x72, + 0x91, 0xF8, 0x22, 0x01, 0x62, 0x79, 0x60, 0xF3, 0x04, 0x02, 0x62, 0x71, + 0x91, 0xF8, 0x23, 0x01, 0x21, 0x79, 0x60, 0xF3, 0x04, 0x01, 0x4B, 0x48, + 0x21, 0x71, 0x0C, 0x38, 0x41, 0x78, 0x94, 0xF8, 0x37, 0x00, 0x61, 0xF3, + 0x04, 0x00, 0x84, 0xF8, 0x37, 0x00, 0x49, 0x48, 0xEA, 0xF7, 0xFB, 0xFE, + 0xA4, 0xF8, 0x52, 0x00, 0x28, 0x68, 0xE1, 0x88, 0xB0, 0xF8, 0x1D, 0x21, + 0x62, 0xF3, 0x0B, 0x01, 0xE1, 0x80, 0x90, 0xF8, 0x17, 0x11, 0xCA, 0x08, + 0x21, 0x7C, 0x62, 0xF3, 0x02, 0x01, 0x21, 0x74, 0x10, 0xF8, 0xDF, 0x2F, + 0xA1, 0x78, 0x62, 0xF3, 0x03, 0x01, 0xA1, 0x70, 0x10, 0xF8, 0x19, 0x1B, + 0x0A, 0x09, 0xE1, 0x78, 0x62, 0xF3, 0x03, 0x01, 0xE1, 0x70, 0x81, 0x7F, + 0x0A, 0x09, 0x61, 0x78, 0x62, 0xF3, 0x02, 0x01, 0x61, 0x70, 0x01, 0x7F, + 0x8A, 0x09, 0x21, 0x78, 0x62, 0xF3, 0x00, 0x01, 0x21, 0x70, 0x81, 0x7E, + 0xCA, 0x09, 0x21, 0x7B, 0x62, 0xF3, 0x00, 0x01, 0x21, 0x73, 0x94, 0xF8, + 0x37, 0x10, 0x41, 0xF0, 0x20, 0x01, 0x84, 0xF8, 0x37, 0x10, 0x21, 0x8F, + 0x6F, 0xF3, 0x08, 0x01, 0x01, 0xF5, 0x80, 0x71, 0x21, 0x87, 0x00, 0x21, + 0xC4, 0xF8, 0x3A, 0x10, 0xC1, 0x7F, 0x8A, 0x09, 0xE1, 0x7A, 0x62, 0xF3, + 0xC3, 0x01, 0xE1, 0x72, 0x80, 0x7E, 0x00, 0x09, 0x60, 0xF3, 0x04, 0x11, + 0xE1, 0x72, 0x70, 0xBD, 0x70, 0xB5, 0x1F, 0x4D, 0x00, 0x20, 0x0C, 0x3D, + 0x01, 0x24, 0x28, 0x60, 0xE0, 0xB2, 0xFF, 0xF7, 0x3B, 0xFE, 0x28, 0x55, + 0x64, 0x1C, 0x04, 0x2C, 0xF8, 0xDB, 0xBD, 0xE8, 0x70, 0x40, 0x1C, 0x48, + 0xAA, 0xE6, 0x70, 0xB5, 0x41, 0x7A, 0xAA, 0xB0, 0x59, 0xB1, 0x13, 0x4D, + 0x01, 0x20, 0x6C, 0x46, 0x28, 0x70, 0x01, 0x29, 0x08, 0xD0, 0x00, 0x26, + 0x02, 0x29, 0x09, 0xD0, 0x03, 0x29, 0x2D, 0xD1, 0x28, 0xE0, 0x01, 0x20, + 0x2A, 0xB0, 0x70, 0xBD, 0x20, 0x46, 0x00, 0xF0, 0x60, 0xF8, 0x25, 0xE0, + 0x20, 0x46, 0x00, 0xF0, 0x5C, 0xF8, 0x0A, 0x48, 0x9D, 0xF8, 0x5F, 0x10, + 0x0C, 0x38, 0x80, 0x78, 0x60, 0xF3, 0x04, 0x01, 0x8D, 0xF8, 0x5F, 0x10, + 0x00, 0x21, 0x20, 0x46, 0xEA, 0xF7, 0x07, 0xFF, 0x13, 0xE0, 0x00, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0xE4, 0x07, 0x10, 0x00, 0xB4, 0x84, 0x10, 0x00, + 0xC0, 0xA4, 0x01, 0x20, 0x98, 0x98, 0x01, 0x20, 0x20, 0xBF, 0x01, 0x20, + 0x00, 0x9B, 0x01, 0x20, 0x14, 0x82, 0x10, 0x00, 0x20, 0x46, 0x00, 0xF0, + 0x3E, 0xF8, 0x2E, 0x70, 0x20, 0x46, 0x01, 0xF0, 0xDD, 0xF8, 0x9D, 0xF8, + 0x12, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x01, 0xF0, 0x1F, 0xF8, 0x37, 0x4C, + 0x20, 0x68, 0x00, 0xF2, 0x5E, 0x63, 0x00, 0xF6, 0x6E, 0x05, 0x90, 0xF8, + 0x5A, 0x16, 0x90, 0xF8, 0x5B, 0x06, 0x03, 0xEB, 0x40, 0x00, 0x00, 0xF0, + 0xE2, 0xFF, 0x20, 0x68, 0x90, 0xF8, 0x6A, 0x18, 0x90, 0xF8, 0x6B, 0x08, + 0x05, 0xEB, 0x40, 0x00, 0x00, 0xF0, 0xF0, 0xFF, 0x2C, 0x49, 0x68, 0x46, + 0xEB, 0xF7, 0x34, 0xF8, 0x00, 0x20, 0xAD, 0xE7, 0x40, 0xF2, 0xFF, 0x10, + 0xC1, 0xEB, 0x41, 0x21, 0x91, 0xFB, 0xF0, 0xF0, 0x00, 0x20, 0x70, 0x47, + 0x10, 0xB5, 0x00, 0x23, 0xD4, 0x5C, 0x31, 0xF8, 0x14, 0x40, 0x20, 0xF8, + 0x13, 0x40, 0x5B, 0x1C, 0x04, 0x2B, 0xF7, 0xDB, 0x10, 0xBD, 0xA4, 0x22, + 0x20, 0x49, 0x01, 0xF0, 0x7A, 0xBA, 0x70, 0xB5, 0x04, 0x46, 0x00, 0xF0, + 0x6A, 0xFB, 0x1E, 0x48, 0xEA, 0xF7, 0x1F, 0xFE, 0xA4, 0xF8, 0x76, 0x00, + 0x00, 0xF0, 0x77, 0xFF, 0x17, 0x4D, 0x01, 0x46, 0x28, 0x68, 0x90, 0xF8, + 0xC9, 0x00, 0xC0, 0xF3, 0x41, 0x12, 0x20, 0x46, 0xEA, 0xF7, 0xB4, 0xFF, + 0x00, 0xF0, 0x70, 0xFF, 0x02, 0x46, 0x0B, 0x46, 0x20, 0x46, 0xEA, 0xF7, + 0xD9, 0xFF, 0x13, 0x48, 0xEA, 0xF7, 0x07, 0xFE, 0xA4, 0xF8, 0x7C, 0x00, + 0x0F, 0x48, 0x0C, 0x38, 0xC1, 0x78, 0x14, 0xF8, 0x5F, 0x0F, 0x61, 0xF3, + 0x04, 0x00, 0x20, 0x70, 0x29, 0x68, 0x00, 0xF0, 0x1F, 0x00, 0x11, 0xF8, + 0xD3, 0x2F, 0xC9, 0x78, 0x01, 0xF0, 0x1F, 0x01, 0x49, 0x1C, 0xC1, 0xEB, + 0x41, 0x21, 0x49, 0x00, 0x4A, 0x43, 0xC2, 0x40, 0x50, 0x08, 0xC4, 0xF8, + 0x03, 0x00, 0x70, 0xBD, 0x4C, 0x07, 0x10, 0x00, 0x29, 0x58, 0x01, 0x00, + 0x14, 0x82, 0x10, 0x00, 0xC0, 0xA4, 0x01, 0x20, 0x98, 0x98, 0x01, 0x20, + 0x10, 0xB9, 0x66, 0x4A, 0x64, 0x49, 0x11, 0x61, 0x00, 0xF0, 0xDF, 0xBE, + 0x70, 0xB5, 0x64, 0x4D, 0x04, 0x46, 0x28, 0x68, 0x90, 0xF8, 0xF1, 0x01, + 0xC0, 0xF3, 0x01, 0x12, 0xC0, 0xF3, 0x81, 0x01, 0x00, 0xF0, 0x03, 0x00, + 0xFD, 0xF7, 0xA1, 0xFA, 0x40, 0x1C, 0xC6, 0xB2, 0x20, 0x46, 0x00, 0xF0, + 0x71, 0xFC, 0x59, 0x48, 0xEA, 0xF7, 0xC5, 0xFD, 0xA4, 0xF8, 0x76, 0x00, + 0x00, 0x22, 0x31, 0x46, 0x20, 0x46, 0xEA, 0xF7, 0x82, 0xFF, 0xA0, 0x79, + 0x40, 0xF0, 0x02, 0x00, 0xA0, 0x71, 0x94, 0xF8, 0x6F, 0x00, 0x66, 0xF3, + 0x02, 0x00, 0x84, 0xF8, 0x6F, 0x00, 0x94, 0xF8, 0x6E, 0x00, 0x20, 0xF0, + 0x0F, 0x00, 0x84, 0xF8, 0x6E, 0x00, 0x29, 0x68, 0xA0, 0x7C, 0x91, 0xF8, + 0x08, 0x21, 0x62, 0xF3, 0x01, 0x00, 0xA0, 0x74, 0x91, 0xF8, 0x08, 0x21, + 0x92, 0x08, 0x62, 0xF3, 0x87, 0x10, 0xA0, 0x74, 0xA0, 0x89, 0x6F, 0xF3, + 0x0B, 0x00, 0xA0, 0x81, 0x91, 0xF8, 0x07, 0x01, 0xA0, 0x70, 0x94, 0xF8, + 0x5E, 0x00, 0x00, 0x21, 0x20, 0xF0, 0x01, 0x00, 0x84, 0xF8, 0x5E, 0x00, + 0x20, 0x46, 0xEA, 0xF7, 0x1E, 0xFE, 0x28, 0x68, 0x90, 0xF8, 0xF2, 0x11, + 0x84, 0xF8, 0x66, 0x10, 0x90, 0xF8, 0xF3, 0x11, 0x84, 0xF8, 0x68, 0x10, + 0x90, 0xF8, 0xF4, 0x11, 0x84, 0xF8, 0x6A, 0x10, 0x90, 0xF8, 0xF5, 0x01, + 0x84, 0xF8, 0x6C, 0x00, 0x34, 0x48, 0x94, 0xF8, 0x5F, 0x10, 0x00, 0x1F, + 0x40, 0x78, 0x60, 0xF3, 0x04, 0x01, 0x84, 0xF8, 0x5F, 0x10, 0x20, 0x46, + 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x48, 0xBF, 0x10, 0xB5, 0x2D, 0x4C, + 0x00, 0x20, 0x24, 0x1F, 0x20, 0x80, 0x01, 0x20, 0x00, 0xF0, 0x32, 0xF8, + 0x60, 0x70, 0xBD, 0xE8, 0x10, 0x40, 0x2B, 0x48, 0x88, 0xE7, 0x2D, 0xE9, + 0xF0, 0x41, 0x29, 0x4E, 0x40, 0x79, 0x28, 0xB3, 0x30, 0x46, 0x00, 0xF0, + 0xD9, 0xFF, 0xB0, 0x7C, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xF0, 0x1C, 0xFF, + 0x22, 0x4F, 0x3C, 0x68, 0x04, 0xF2, 0x5E, 0x60, 0x94, 0xF8, 0x51, 0x26, + 0x04, 0xF6, 0x6E, 0x05, 0x94, 0xF8, 0x50, 0x16, 0x00, 0xEB, 0x42, 0x00, + 0x00, 0xF0, 0xDF, 0xFE, 0x38, 0x68, 0x90, 0xF8, 0x60, 0x18, 0x90, 0xF8, + 0x61, 0x08, 0x05, 0xEB, 0x40, 0x00, 0x00, 0xF0, 0xED, 0xFE, 0x19, 0x49, + 0x30, 0x46, 0xEA, 0xF7, 0x31, 0xFF, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, + 0x01, 0x20, 0xFB, 0xE7, 0x12, 0x48, 0x4F, 0xF4, 0x80, 0x73, 0x02, 0x68, + 0x92, 0xF8, 0xF5, 0x10, 0x92, 0xF8, 0x07, 0x01, 0x92, 0xF8, 0xF2, 0x20, + 0x01, 0xF0, 0x1F, 0x01, 0x02, 0xF0, 0x0F, 0x02, 0x98, 0x42, 0x00, 0xD9, + 0x18, 0x46, 0x1F, 0x29, 0x00, 0xD9, 0x1F, 0x21, 0x49, 0x1C, 0x48, 0x43, + 0x40, 0x00, 0x52, 0x1C, 0x50, 0x43, 0xC0, 0xEB, 0x40, 0x20, 0xC0, 0x13, + 0xB0, 0xFA, 0x80, 0xF0, 0xC0, 0xF1, 0x20, 0x00, 0xC0, 0xB2, 0x70, 0x47, + 0xE4, 0xA4, 0x01, 0x20, 0xB4, 0x84, 0x10, 0x00, 0x4C, 0x07, 0x10, 0x00, + 0xB8, 0x82, 0x10, 0x00, 0xA1, 0x5C, 0x01, 0x00, 0x2D, 0xE9, 0xF0, 0x47, + 0xFE, 0x49, 0x4F, 0xF0, 0x01, 0x08, 0x00, 0x27, 0x0A, 0x68, 0x80, 0x1E, + 0x02, 0xF2, 0x5E, 0x64, 0xC1, 0x46, 0x06, 0x28, 0x52, 0xD2, 0xDF, 0xE8, + 0x00, 0xF0, 0x51, 0x09, 0x2D, 0x51, 0x2D, 0x03, 0x12, 0xF8, 0xD3, 0x6F, + 0x10, 0x79, 0x00, 0xF0, 0x1F, 0x05, 0x70, 0xE0, 0x92, 0xF8, 0xF5, 0x00, + 0x92, 0xF8, 0x01, 0x61, 0x00, 0xF0, 0x1F, 0x05, 0x92, 0xF8, 0xF2, 0x00, + 0x8A, 0x46, 0x00, 0xF0, 0x0F, 0x07, 0x92, 0xF8, 0xE6, 0x00, 0x80, 0x06, + 0x09, 0xD5, 0x92, 0xF8, 0x53, 0x06, 0x92, 0xF8, 0x52, 0x16, 0x04, 0xEB, + 0x40, 0x00, 0x0A, 0x22, 0x00, 0xF0, 0x4E, 0xFE, 0x80, 0x46, 0xDA, 0xF8, + 0x00, 0x00, 0x90, 0xF8, 0xE6, 0x10, 0x49, 0x06, 0x51, 0xD5, 0x90, 0xF8, + 0x62, 0x18, 0x90, 0xF8, 0x63, 0x08, 0x46, 0xE0, 0x92, 0xF8, 0xFC, 0x00, + 0x92, 0xF8, 0xF8, 0x60, 0x00, 0xF0, 0x1F, 0x05, 0x92, 0xF8, 0xF9, 0x00, + 0x8A, 0x46, 0x00, 0xF0, 0x0F, 0x07, 0x92, 0xF8, 0xE6, 0x00, 0x80, 0x06, + 0x09, 0xD5, 0x92, 0xF8, 0x55, 0x06, 0x92, 0xF8, 0x54, 0x16, 0x04, 0xEB, + 0x40, 0x00, 0x0A, 0x22, 0x00, 0xF0, 0x2A, 0xFE, 0x80, 0x46, 0xDA, 0xF8, + 0x00, 0x00, 0x90, 0xF8, 0xE6, 0x10, 0x49, 0x06, 0x2D, 0xD5, 0x90, 0xF8, + 0x64, 0x18, 0x90, 0xF8, 0x65, 0x08, 0x22, 0xE0, 0x92, 0xF8, 0xF5, 0x00, + 0x92, 0xF8, 0xF1, 0x60, 0x00, 0xF0, 0x1F, 0x05, 0x92, 0xF8, 0xF2, 0x00, + 0x8A, 0x46, 0x00, 0xF0, 0x0F, 0x07, 0x92, 0xF8, 0xE6, 0x00, 0x80, 0x06, + 0x09, 0xD5, 0x92, 0xF8, 0x51, 0x06, 0x92, 0xF8, 0x50, 0x16, 0x04, 0xEB, + 0x40, 0x00, 0x0A, 0x22, 0x00, 0xF0, 0x06, 0xFE, 0x80, 0x46, 0xDA, 0xF8, + 0x00, 0x00, 0x90, 0xF8, 0xE6, 0x10, 0x49, 0x06, 0x09, 0xD5, 0x90, 0xF8, + 0x60, 0x18, 0x90, 0xF8, 0x61, 0x08, 0x0A, 0x22, 0x04, 0xEB, 0x40, 0x00, + 0x00, 0xF0, 0xF6, 0xFD, 0x81, 0x46, 0x4F, 0xF4, 0x80, 0x70, 0x86, 0x42, + 0x00, 0xD9, 0x06, 0x46, 0x1F, 0x2D, 0x00, 0xD9, 0x1F, 0x25, 0x6D, 0x1C, + 0x6E, 0x43, 0x70, 0x00, 0x7F, 0x1C, 0x78, 0x43, 0xC0, 0xEB, 0x40, 0x20, + 0x00, 0xFB, 0x08, 0xF0, 0x00, 0xFB, 0x09, 0xF0, 0xC0, 0x13, 0xB0, 0xFA, + 0x80, 0xF0, 0xC0, 0xF1, 0x20, 0x00, 0xC0, 0xB2, 0xBD, 0xE8, 0xF0, 0x87, + 0x70, 0xB5, 0x06, 0x00, 0x03, 0xD0, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, + 0x64, 0xBD, 0x00, 0xF0, 0x18, 0xF8, 0x01, 0x28, 0x14, 0xD1, 0xA9, 0x4D, + 0xA9, 0x4C, 0x28, 0x78, 0x01, 0x28, 0x09, 0xD0, 0xA8, 0x48, 0xA0, 0x60, + 0x68, 0x78, 0xE0, 0x73, 0xE8, 0x78, 0xA0, 0x73, 0xE8, 0x88, 0xA0, 0x81, + 0x30, 0x46, 0xE8, 0xE7, 0x6A, 0x79, 0x29, 0x79, 0xA2, 0x48, 0x00, 0xF0, + 0xB6, 0xFE, 0xF0, 0xE7, 0x70, 0xBD, 0x9E, 0x4B, 0x10, 0xB5, 0xD9, 0x78, + 0x9F, 0x4C, 0x49, 0x1C, 0xCA, 0xB2, 0xDA, 0x70, 0x99, 0x78, 0x01, 0x20, + 0x8A, 0x42, 0x1B, 0xD8, 0x19, 0x79, 0x58, 0x79, 0x41, 0x43, 0x99, 0x48, + 0xFD, 0xF7, 0xA9, 0xF9, 0xEA, 0xF7, 0x33, 0xFC, 0xA4, 0xF8, 0x76, 0x00, + 0x92, 0x48, 0x00, 0x68, 0x90, 0xF8, 0xB0, 0x00, 0xC0, 0x07, 0x06, 0xD0, + 0x94, 0xF8, 0x4D, 0x00, 0x20, 0xF0, 0x03, 0x00, 0x80, 0x1C, 0x84, 0xF8, + 0x4D, 0x00, 0x91, 0x49, 0x20, 0x46, 0xEA, 0xF7, 0x15, 0xFE, 0x00, 0x20, + 0x10, 0xBD, 0x70, 0xB5, 0x04, 0x46, 0xEA, 0xF7, 0x15, 0xFC, 0x8A, 0x48, + 0xEA, 0xF7, 0x17, 0xFC, 0xA4, 0xF8, 0x76, 0x00, 0x00, 0xF0, 0x66, 0xFD, + 0x83, 0x4D, 0x01, 0x46, 0x28, 0x68, 0x90, 0xF8, 0xE7, 0x00, 0xC0, 0xF3, + 0x41, 0x12, 0x20, 0x46, 0xEA, 0xF7, 0xAC, 0xFD, 0x00, 0xF0, 0x5E, 0xFD, + 0x02, 0x46, 0x0B, 0x46, 0x20, 0x46, 0xEA, 0xF7, 0xD1, 0xFD, 0xA0, 0x79, + 0x20, 0xF0, 0x02, 0x00, 0xA0, 0x71, 0x94, 0xF8, 0x6F, 0x00, 0x20, 0xF0, + 0x07, 0x00, 0x84, 0xF8, 0x6F, 0x00, 0x94, 0xF8, 0x6E, 0x00, 0x20, 0xF0, + 0x0F, 0x00, 0x84, 0xF8, 0x6E, 0x00, 0x28, 0x68, 0x90, 0xF8, 0xE7, 0x00, + 0xC0, 0xF3, 0x41, 0x11, 0x20, 0x46, 0xEA, 0xF7, 0xD3, 0xFD, 0x28, 0x68, + 0x90, 0xF8, 0xE7, 0x00, 0x10, 0xF0, 0x60, 0x0F, 0x94, 0xF8, 0x5E, 0x00, + 0x7E, 0xD0, 0x40, 0xF0, 0x01, 0x00, 0x00, 0xBF, 0x84, 0xF8, 0x5E, 0x00, + 0x20, 0x46, 0x00, 0xF0, 0x6B, 0xFE, 0x04, 0x21, 0x20, 0x46, 0xEA, 0xF7, + 0x04, 0xFC, 0x28, 0x68, 0x90, 0xF8, 0xF1, 0x00, 0xA0, 0x70, 0x28, 0x68, + 0x21, 0x8E, 0xB0, 0xF8, 0xF6, 0x20, 0x62, 0xF3, 0x08, 0x01, 0x21, 0x86, + 0x90, 0xF8, 0xF2, 0x00, 0x00, 0xF0, 0x0F, 0x01, 0x20, 0x46, 0xEA, 0xF7, + 0x52, 0xFC, 0x28, 0x68, 0x62, 0x7D, 0x90, 0xF8, 0xEA, 0x10, 0x61, 0xF3, + 0x03, 0x02, 0x62, 0x75, 0xB0, 0xF8, 0xED, 0x20, 0x21, 0x8A, 0x62, 0xF3, + 0x0B, 0x01, 0x21, 0x82, 0x90, 0xF8, 0xF3, 0x10, 0xA2, 0x7D, 0x61, 0xF3, + 0x03, 0x02, 0xA2, 0x75, 0x10, 0xF8, 0xF2, 0x1F, 0x0A, 0x09, 0xA1, 0x7C, + 0x62, 0xF3, 0x01, 0x01, 0xA1, 0x74, 0x10, 0xF8, 0x0C, 0x29, 0x92, 0x09, + 0x62, 0xF3, 0x87, 0x11, 0xA1, 0x74, 0x01, 0x78, 0xE2, 0x79, 0x61, 0xF3, + 0x00, 0x02, 0xE2, 0x71, 0xC1, 0x78, 0x61, 0x72, 0x80, 0x79, 0x01, 0x09, + 0xE0, 0x7A, 0x61, 0xF3, 0x03, 0x00, 0xE0, 0x72, 0x4B, 0x48, 0xEA, 0xF7, + 0x94, 0xFB, 0xA4, 0xF8, 0x7C, 0x00, 0x29, 0x68, 0x11, 0xF8, 0xE8, 0x0F, + 0xC2, 0x08, 0x94, 0xF8, 0x27, 0x00, 0x62, 0xF3, 0x83, 0x00, 0x84, 0xF8, + 0x27, 0x00, 0x11, 0xF8, 0x01, 0x29, 0x52, 0x08, 0x62, 0xF3, 0x00, 0x00, + 0x84, 0xF8, 0x27, 0x00, 0x4A, 0x78, 0x92, 0x08, 0x62, 0xF3, 0x41, 0x00, + 0x84, 0xF8, 0x27, 0x00, 0x08, 0x78, 0xC0, 0xF3, 0x81, 0x01, 0x20, 0x46, + 0xEA, 0xF7, 0xF0, 0xFB, 0x28, 0x68, 0x90, 0xF8, 0xE7, 0x00, 0x01, 0x09, + 0x14, 0xF8, 0x28, 0x0F, 0x61, 0xF3, 0x04, 0x10, 0x20, 0x70, 0x37, 0x48, + 0xEA, 0xF7, 0x69, 0xFB, 0xA4, 0xF8, 0x5E, 0x00, 0x28, 0x68, 0x10, 0xF8, + 0xE6, 0x1F, 0x00, 0xE0, 0xA6, 0xE0, 0xCA, 0x08, 0xE1, 0x7A, 0x62, 0xF3, + 0x45, 0x11, 0xE1, 0x72, 0x40, 0x78, 0x41, 0x08, 0x20, 0x78, 0x61, 0xF3, + 0x45, 0x10, 0x04, 0xF8, 0x28, 0x09, 0x20, 0x46, 0x00, 0xF0, 0x2A, 0xFD, + 0x28, 0x68, 0x90, 0xF8, 0xEC, 0x00, 0xC0, 0xF3, 0x81, 0x01, 0x20, 0x46, + 0xEA, 0xF7, 0xB3, 0xFB, 0x14, 0xF8, 0x32, 0x0F, 0x20, 0xF0, 0x0F, 0x00, + 0x0A, 0x30, 0x20, 0xF0, 0xF0, 0x00, 0xA0, 0x30, 0x04, 0xF8, 0x0A, 0x09, + 0x29, 0x68, 0x11, 0xF8, 0xE6, 0x0F, 0x82, 0x09, 0xE0, 0x7A, 0x62, 0xF3, + 0x00, 0x00, 0xE0, 0x72, 0x0A, 0x78, 0x52, 0x09, 0x62, 0xF3, 0x41, 0x00, + 0xE0, 0x72, 0x4A, 0x79, 0xD2, 0x09, 0x62, 0xF3, 0x82, 0x00, 0xE0, 0x72, + 0x88, 0x7B, 0x62, 0x79, 0x60, 0xF3, 0x04, 0x02, 0x62, 0x71, 0xC9, 0x7B, + 0x20, 0x79, 0x61, 0xF3, 0x04, 0x00, 0x20, 0x71, 0x14, 0x48, 0x94, 0xF8, + 0x37, 0x10, 0x40, 0x78, 0x60, 0xF3, 0x04, 0x01, 0x84, 0xF8, 0x37, 0x10, + 0x11, 0x48, 0xEA, 0xF7, 0x1A, 0xFB, 0xA4, 0xF8, 0x52, 0x00, 0x28, 0x68, + 0xE1, 0x88, 0xB0, 0xF8, 0xEF, 0x20, 0x62, 0xF3, 0x0B, 0x01, 0xE1, 0x80, + 0x90, 0xF8, 0xEB, 0x10, 0xCA, 0x08, 0x21, 0x7C, 0x14, 0xE0, 0x00, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0xE6, 0x07, 0x10, 0x00, 0xB4, 0x84, 0x10, 0x00, + 0x14, 0xA6, 0x01, 0x20, 0x00, 0x84, 0x10, 0x00, 0x95, 0x5F, 0x01, 0x00, + 0x78, 0x8B, 0x01, 0x20, 0x20, 0xBF, 0x01, 0x20, 0x16, 0xBF, 0x01, 0x20, + 0x00, 0x9B, 0x01, 0x20, 0x62, 0xF3, 0x02, 0x01, 0x21, 0x74, 0x10, 0xF8, + 0xDF, 0x1F, 0xA2, 0x78, 0x61, 0xF3, 0x03, 0x02, 0xA2, 0x70, 0x01, 0x78, + 0x0A, 0x09, 0xE1, 0x78, 0x62, 0xF3, 0x03, 0x01, 0xE1, 0x70, 0xC1, 0x7A, + 0x0A, 0x09, 0x61, 0x78, 0x62, 0xF3, 0x02, 0x01, 0x61, 0x70, 0x41, 0x7A, + 0x8A, 0x09, 0x21, 0x78, 0x62, 0xF3, 0x00, 0x01, 0x21, 0x70, 0xC1, 0x79, + 0xCA, 0x09, 0x21, 0x7B, 0x62, 0xF3, 0x00, 0x01, 0x21, 0x73, 0x94, 0xF8, + 0x37, 0x10, 0x41, 0xF0, 0x20, 0x01, 0x84, 0xF8, 0x37, 0x10, 0x21, 0x8F, + 0x6F, 0xF3, 0x08, 0x01, 0x01, 0xF5, 0x80, 0x71, 0x21, 0x87, 0x00, 0x21, + 0xC4, 0xF8, 0x3A, 0x10, 0x01, 0x7B, 0x8A, 0x09, 0xE1, 0x7A, 0x62, 0xF3, + 0xC3, 0x01, 0xE1, 0x72, 0xC0, 0x79, 0x00, 0x09, 0x60, 0xF3, 0x04, 0x11, + 0xE1, 0x72, 0x70, 0xBD, 0x20, 0xF0, 0x01, 0x00, 0xD8, 0xE6, 0x70, 0xB5, + 0x04, 0x46, 0xEA, 0xF7, 0xAF, 0xFA, 0xFD, 0x48, 0xEA, 0xF7, 0xB1, 0xFA, + 0xA4, 0xF8, 0x76, 0x00, 0x00, 0xF0, 0x00, 0xFC, 0xFA, 0x4D, 0x01, 0x46, + 0x28, 0x68, 0x90, 0xF8, 0xC9, 0x00, 0xC0, 0xF3, 0x41, 0x12, 0x20, 0x46, + 0xEA, 0xF7, 0x46, 0xFC, 0x00, 0xF0, 0xF8, 0xFB, 0x02, 0x46, 0x0B, 0x46, + 0x20, 0x46, 0xEA, 0xF7, 0x6B, 0xFC, 0xA0, 0x79, 0x20, 0xF0, 0x02, 0x00, + 0xA0, 0x71, 0x94, 0xF8, 0x6F, 0x00, 0x20, 0xF0, 0x07, 0x00, 0x84, 0xF8, + 0x6F, 0x00, 0x94, 0xF8, 0x6E, 0x00, 0x20, 0xF0, 0x0F, 0x00, 0x84, 0xF8, + 0x6E, 0x00, 0x28, 0x68, 0x90, 0xF8, 0xC9, 0x00, 0xC0, 0xF3, 0x41, 0x11, + 0x20, 0x46, 0xEA, 0xF7, 0x6D, 0xFC, 0x28, 0x68, 0x90, 0xF8, 0xC9, 0x00, + 0x10, 0xF0, 0x60, 0x0F, 0x94, 0xF8, 0x5E, 0x00, 0x7E, 0xD0, 0x40, 0xF0, + 0x01, 0x00, 0x00, 0xBF, 0x84, 0xF8, 0x5E, 0x00, 0x20, 0x46, 0x00, 0xF0, + 0x05, 0xFD, 0x28, 0x68, 0x90, 0xF8, 0xD3, 0x00, 0xA0, 0x70, 0x28, 0x68, + 0x21, 0x8E, 0xB0, 0xF8, 0xD8, 0x20, 0x62, 0xF3, 0x08, 0x01, 0x21, 0x86, + 0x90, 0xF8, 0xD4, 0x00, 0x00, 0xF0, 0x0F, 0x01, 0x20, 0x46, 0xEA, 0xF7, + 0xF0, 0xFA, 0x28, 0x68, 0x62, 0x7D, 0x90, 0xF8, 0xCC, 0x10, 0x61, 0xF3, + 0x03, 0x02, 0x62, 0x75, 0xB0, 0xF8, 0xCF, 0x20, 0x21, 0x8A, 0x62, 0xF3, + 0x0B, 0x01, 0x21, 0x82, 0x90, 0xF8, 0xD5, 0x10, 0xA2, 0x7D, 0x61, 0xF3, + 0x03, 0x02, 0xA2, 0x75, 0x90, 0xF8, 0xF2, 0x21, 0xA1, 0x89, 0x62, 0xF3, + 0x0B, 0x01, 0xA1, 0x81, 0x10, 0xF8, 0xD4, 0x1F, 0x0A, 0x09, 0xA1, 0x7C, + 0x62, 0xF3, 0x01, 0x01, 0xA1, 0x74, 0x10, 0xF8, 0x0C, 0x29, 0x92, 0x09, + 0x62, 0xF3, 0x87, 0x11, 0xA1, 0x74, 0x01, 0x78, 0xE2, 0x79, 0x61, 0xF3, + 0x00, 0x02, 0xE2, 0x71, 0xC1, 0x78, 0x61, 0x72, 0x80, 0x79, 0x01, 0x09, + 0xE0, 0x7A, 0x61, 0xF3, 0x03, 0x00, 0xE0, 0x72, 0xBC, 0x48, 0xEA, 0xF7, + 0x2C, 0xFA, 0xA4, 0xF8, 0x7C, 0x00, 0x29, 0x68, 0x11, 0xF8, 0xCA, 0x0F, + 0xC2, 0x08, 0x94, 0xF8, 0x27, 0x00, 0x62, 0xF3, 0x83, 0x00, 0x84, 0xF8, + 0x27, 0x00, 0x11, 0xF8, 0x01, 0x29, 0x52, 0x08, 0x62, 0xF3, 0x00, 0x00, + 0x84, 0xF8, 0x27, 0x00, 0x4A, 0x78, 0x92, 0x08, 0x62, 0xF3, 0x41, 0x00, + 0x84, 0xF8, 0x27, 0x00, 0x08, 0x78, 0xC0, 0xF3, 0x81, 0x01, 0x20, 0x46, + 0xEA, 0xF7, 0x88, 0xFA, 0x28, 0x68, 0x90, 0xF8, 0xC9, 0x00, 0x01, 0x09, + 0x14, 0xF8, 0x28, 0x0F, 0x61, 0xF3, 0x04, 0x10, 0x20, 0x70, 0xA8, 0x48, + 0xEA, 0xF7, 0x01, 0xFA, 0xA4, 0xF8, 0x5E, 0x00, 0x28, 0x68, 0x00, 0xE0, + 0xA1, 0xE0, 0x10, 0xF8, 0xC8, 0x1F, 0xCA, 0x08, 0xE1, 0x7A, 0x62, 0xF3, + 0x45, 0x11, 0xE1, 0x72, 0x40, 0x78, 0x41, 0x08, 0x20, 0x78, 0x61, 0xF3, + 0x45, 0x10, 0x04, 0xF8, 0x28, 0x09, 0x20, 0x46, 0x00, 0xF0, 0xC2, 0xFB, + 0x28, 0x68, 0x90, 0xF8, 0xCE, 0x00, 0xC0, 0xF3, 0x81, 0x01, 0x20, 0x46, + 0xEA, 0xF7, 0x4B, 0xFA, 0x14, 0xF8, 0x32, 0x0F, 0x20, 0xF0, 0x0F, 0x00, + 0x0A, 0x30, 0x20, 0xF0, 0xF0, 0x00, 0xA0, 0x30, 0x04, 0xF8, 0x0A, 0x09, + 0x29, 0x68, 0x11, 0xF8, 0xC8, 0x0F, 0x82, 0x09, 0xE0, 0x7A, 0x62, 0xF3, + 0x00, 0x00, 0xE0, 0x72, 0x0A, 0x78, 0x52, 0x09, 0x62, 0xF3, 0x41, 0x00, + 0xE0, 0x72, 0x4A, 0x79, 0xD2, 0x09, 0x62, 0xF3, 0x82, 0x00, 0xE0, 0x72, + 0x88, 0x7B, 0x62, 0x79, 0x60, 0xF3, 0x04, 0x02, 0x62, 0x71, 0xC8, 0x7B, + 0x21, 0x79, 0x60, 0xF3, 0x04, 0x01, 0x86, 0x48, 0x21, 0x71, 0x94, 0xF8, + 0x37, 0x10, 0x40, 0x78, 0x60, 0xF3, 0x04, 0x01, 0x84, 0xF8, 0x37, 0x10, + 0x82, 0x48, 0xEA, 0xF7, 0xB2, 0xF9, 0xA4, 0xF8, 0x52, 0x00, 0x28, 0x68, + 0xE1, 0x88, 0xB0, 0xF8, 0xD1, 0x20, 0x62, 0xF3, 0x0B, 0x01, 0xE1, 0x80, + 0x10, 0xF8, 0xCD, 0x1F, 0xCA, 0x08, 0x21, 0x7C, 0x62, 0xF3, 0x02, 0x01, + 0x21, 0x74, 0x10, 0xF8, 0x12, 0x1F, 0xA2, 0x78, 0x61, 0xF3, 0x03, 0x02, + 0xA2, 0x70, 0x10, 0xF8, 0x17, 0x19, 0x0A, 0x09, 0xE1, 0x78, 0x62, 0xF3, + 0x03, 0x01, 0xE1, 0x70, 0x01, 0x79, 0x0A, 0x09, 0x61, 0x78, 0x62, 0xF3, + 0x02, 0x01, 0x61, 0x70, 0x81, 0x78, 0x8A, 0x09, 0x21, 0x78, 0x62, 0xF3, + 0x00, 0x01, 0x21, 0x70, 0x01, 0x78, 0xCA, 0x09, 0x21, 0x7B, 0x62, 0xF3, + 0x00, 0x01, 0x21, 0x73, 0x01, 0x79, 0xCA, 0x09, 0x94, 0xF8, 0x37, 0x10, + 0x62, 0xF3, 0x45, 0x11, 0x84, 0xF8, 0x37, 0x10, 0x22, 0x8F, 0x01, 0xF0, + 0x1F, 0x01, 0x6F, 0xF3, 0x08, 0x02, 0x02, 0xF5, 0x80, 0x72, 0x22, 0x87, + 0x83, 0x7B, 0xC2, 0x7A, 0x03, 0xF0, 0x1F, 0x03, 0x5B, 0x1C, 0xC3, 0xEB, + 0x43, 0x23, 0x5B, 0x00, 0x5A, 0x43, 0xCA, 0x40, 0x51, 0x08, 0xC4, 0xF8, + 0x3A, 0x10, 0x41, 0x79, 0x8A, 0x09, 0xE1, 0x7A, 0x62, 0xF3, 0xC3, 0x01, + 0xE1, 0x72, 0x00, 0x78, 0x00, 0x09, 0x60, 0xF3, 0x04, 0x11, 0xE1, 0x72, + 0x70, 0xBD, 0x20, 0xF0, 0x01, 0x00, 0xDD, 0xE6, 0x10, 0xB5, 0x04, 0x46, + 0xA4, 0x22, 0x53, 0x49, 0x00, 0xF0, 0xA5, 0xFD, 0x52, 0x48, 0xC1, 0x78, + 0xA0, 0x89, 0x61, 0xF3, 0x0B, 0x00, 0xA0, 0x81, 0x10, 0xBD, 0x70, 0xB5, + 0x04, 0x46, 0xFF, 0xF7, 0xEF, 0xFF, 0x00, 0xF0, 0x97, 0xFA, 0x01, 0x46, + 0x00, 0x22, 0x20, 0x46, 0xEA, 0xF7, 0xE2, 0xFA, 0x4A, 0x48, 0xEA, 0xF7, + 0x3C, 0xF9, 0x42, 0x4D, 0xA4, 0xF8, 0x7C, 0x00, 0x28, 0x68, 0x90, 0xF8, + 0xF8, 0x00, 0xA0, 0x70, 0x28, 0x68, 0x90, 0xF8, 0xF9, 0x00, 0x00, 0xF0, + 0x0F, 0x01, 0x20, 0x46, 0xEA, 0xF7, 0xBB, 0xF9, 0x28, 0x68, 0x10, 0xF8, + 0xF9, 0x1F, 0x0A, 0x09, 0xA1, 0x7C, 0x62, 0xF3, 0x01, 0x01, 0xA1, 0x74, + 0x02, 0x78, 0x92, 0x09, 0x62, 0xF3, 0x87, 0x11, 0xA1, 0x74, 0x81, 0x78, + 0x94, 0xF8, 0x2D, 0x20, 0x61, 0xF3, 0x04, 0x02, 0x84, 0xF8, 0x2D, 0x20, + 0xC1, 0x78, 0x94, 0xF8, 0x2C, 0x20, 0x61, 0xF3, 0x04, 0x02, 0x84, 0xF8, + 0x2C, 0x20, 0x40, 0x78, 0xA1, 0x7D, 0x60, 0xF3, 0x03, 0x01, 0xA1, 0x75, + 0x00, 0x21, 0x20, 0x46, 0xEA, 0xF7, 0xF2, 0xFA, 0x14, 0xF8, 0x5E, 0x0F, + 0x20, 0xF0, 0x01, 0x00, 0x04, 0xF8, 0x01, 0x0B, 0x28, 0x48, 0x21, 0x78, + 0x00, 0x79, 0x60, 0xF3, 0x04, 0x01, 0x04, 0xF8, 0x2F, 0x19, 0x28, 0x68, + 0xB0, 0xF8, 0xFD, 0x10, 0x20, 0x88, 0x61, 0xF3, 0x08, 0x00, 0x20, 0x80, + 0x70, 0xBD, 0x70, 0xB5, 0x1D, 0x4E, 0x03, 0x28, 0x34, 0x68, 0x04, 0xF2, + 0x5E, 0x62, 0x04, 0xF6, 0x6E, 0x05, 0x15, 0xD0, 0x04, 0x28, 0x21, 0xD0, + 0x94, 0xF8, 0x51, 0x06, 0x94, 0xF8, 0x50, 0x16, 0x02, 0xEB, 0x40, 0x00, + 0x00, 0xF0, 0x77, 0xFA, 0x30, 0x68, 0x90, 0xF8, 0x60, 0x18, 0x90, 0xF8, + 0x61, 0x08, 0x00, 0xBF, 0x05, 0xEB, 0x40, 0x00, 0xBD, 0xE8, 0x70, 0x40, + 0x00, 0xF0, 0x82, 0xBA, 0x94, 0xF8, 0x53, 0x06, 0x94, 0xF8, 0x52, 0x16, + 0x02, 0xEB, 0x40, 0x00, 0x00, 0xF0, 0x63, 0xFA, 0x30, 0x68, 0x90, 0xF8, + 0x62, 0x18, 0x90, 0xF8, 0x63, 0x08, 0xEB, 0xE7, 0x94, 0xF8, 0x55, 0x06, + 0x94, 0xF8, 0x54, 0x16, 0x02, 0xEB, 0x40, 0x00, 0x00, 0xF0, 0x55, 0xFA, + 0x30, 0x68, 0x90, 0xF8, 0x64, 0x18, 0x90, 0xF8, 0x65, 0x08, 0xDD, 0xE7, + 0x14, 0xA6, 0x01, 0x20, 0x4C, 0x07, 0x10, 0x00, 0x78, 0x8B, 0x01, 0x20, + 0x20, 0xBF, 0x01, 0x20, 0x16, 0xBF, 0x01, 0x20, 0x00, 0x9B, 0x01, 0x20, + 0x5C, 0x83, 0x10, 0x00, 0x74, 0x07, 0x10, 0x00, 0x08, 0x92, 0x01, 0x20, + 0x2D, 0xE9, 0xF0, 0x47, 0x85, 0x4D, 0x4F, 0xF0, 0x01, 0x09, 0x00, 0x26, + 0x85, 0xF8, 0x00, 0x90, 0xAE, 0x70, 0x83, 0x4F, 0xDF, 0xF8, 0x0C, 0x82, + 0x04, 0x46, 0xEE, 0x70, 0x09, 0x29, 0x66, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, + 0x65, 0x05, 0x09, 0x18, 0x44, 0x2F, 0x48, 0x5E, 0x62, 0x00, 0x20, 0x46, + 0xFF, 0xF7, 0x36, 0xFF, 0x5B, 0xE0, 0x20, 0x46, 0xFF, 0xF7, 0x32, 0xFF, + 0xB8, 0x78, 0x94, 0xF8, 0x5F, 0x10, 0x60, 0xF3, 0x04, 0x01, 0x84, 0xF8, + 0x5F, 0x10, 0xD8, 0xF8, 0x00, 0x00, 0x90, 0xF8, 0xFF, 0x00, 0x12, 0xE0, + 0x20, 0x46, 0xFF, 0xF7, 0x23, 0xFF, 0xD8, 0xF8, 0x00, 0x10, 0x91, 0xF8, + 0x01, 0x11, 0xA1, 0x70, 0xF9, 0x78, 0x94, 0xF8, 0x5F, 0x20, 0x61, 0xF3, + 0x04, 0x02, 0x84, 0xF8, 0x5F, 0x20, 0xD8, 0xF8, 0x00, 0x00, 0x90, 0xF8, + 0x00, 0x01, 0x00, 0xF0, 0x03, 0x00, 0xA8, 0x70, 0x35, 0xE0, 0x20, 0x46, + 0xFF, 0xF7, 0x0C, 0xFF, 0x00, 0x21, 0x20, 0x46, 0xEA, 0xF7, 0xED, 0xF8, + 0x94, 0xF8, 0x5E, 0x00, 0x20, 0xF0, 0x01, 0x00, 0x84, 0xF8, 0x5E, 0x00, + 0x78, 0x79, 0x94, 0xF8, 0x5F, 0x10, 0x60, 0xF3, 0x04, 0x01, 0x84, 0xF8, + 0x5F, 0x10, 0x17, 0xE0, 0x20, 0x46, 0xFF, 0xF7, 0x04, 0xFF, 0x1C, 0xE0, + 0x20, 0x46, 0xFF, 0xF7, 0x00, 0xFF, 0x00, 0x21, 0x20, 0x46, 0xEA, 0xF7, + 0xD4, 0xF8, 0xB8, 0x79, 0x94, 0xF8, 0x5F, 0x10, 0x60, 0xF3, 0x04, 0x01, + 0x84, 0xF8, 0x5F, 0x10, 0x94, 0xF8, 0x5E, 0x00, 0x20, 0xF0, 0x01, 0x00, + 0x84, 0xF8, 0x5E, 0x00, 0x2E, 0x70, 0x06, 0xE0, 0x20, 0x46, 0xFF, 0xF7, + 0x7C, 0xFD, 0xF9, 0xE7, 0x20, 0x46, 0x00, 0xF0, 0x59, 0xF8, 0x20, 0x46, + 0x00, 0xF0, 0xAA, 0xFA, 0x94, 0xF8, 0x27, 0x00, 0xC0, 0x07, 0x01, 0xD0, + 0x6E, 0x70, 0x01, 0xE0, 0x85, 0xF8, 0x01, 0x90, 0xA0, 0x89, 0xC0, 0xF3, + 0x0B, 0x00, 0xE8, 0x80, 0xBD, 0xE8, 0xF0, 0x87, 0x7F, 0xB5, 0x00, 0xF0, + 0x6F, 0xF9, 0x01, 0x90, 0x00, 0xF0, 0x70, 0xF9, 0xCD, 0xE9, 0x02, 0x01, + 0x04, 0x21, 0x01, 0xA8, 0xEA, 0xF7, 0xBD, 0xFC, 0x3C, 0x4C, 0x08, 0x21, + 0x20, 0x71, 0x02, 0xA8, 0xEA, 0xF7, 0xB7, 0xFC, 0x60, 0x71, 0x3A, 0x48, + 0x00, 0x21, 0x80, 0x1E, 0x38, 0x4D, 0x40, 0xF8, 0x02, 0x1F, 0x01, 0x24, + 0x41, 0x60, 0x01, 0x72, 0xE0, 0xB2, 0xFF, 0xF7, 0xF5, 0xFA, 0x28, 0x55, + 0x64, 0x1C, 0x09, 0x2C, 0xF8, 0xDB, 0x34, 0x48, 0xFF, 0xF7, 0xDB, 0xFB, + 0x7F, 0xBD, 0x70, 0xB5, 0x31, 0x4D, 0x04, 0x79, 0xA4, 0x35, 0x8C, 0xB1, + 0x21, 0x46, 0x28, 0x46, 0xFF, 0xF7, 0x48, 0xFF, 0xA8, 0x7C, 0x00, 0xF0, + 0x03, 0x00, 0x00, 0xF0, 0xAF, 0xF9, 0x20, 0x46, 0xFF, 0xF7, 0xF3, 0xFE, + 0x2A, 0x49, 0x28, 0x46, 0xEA, 0xF7, 0xD8, 0xF9, 0x00, 0x20, 0x70, 0xBD, + 0x01, 0x20, 0x70, 0xBD, 0x40, 0xF2, 0xFF, 0x10, 0xC1, 0xEB, 0x41, 0x21, + 0x91, 0xFB, 0xF0, 0xF0, 0x00, 0x20, 0x70, 0x47, 0x10, 0xB5, 0x04, 0x46, + 0xFF, 0xF7, 0x7C, 0xFE, 0x94, 0xF8, 0x37, 0x00, 0x40, 0xF0, 0x10, 0x00, + 0x84, 0xF8, 0x37, 0x00, 0xA1, 0x89, 0x94, 0xF8, 0x33, 0x00, 0x6F, 0xF3, + 0x0B, 0x01, 0x10, 0x31, 0xA1, 0x81, 0x21, 0x8A, 0x20, 0xF0, 0x23, 0x00, + 0x6F, 0xF3, 0x0B, 0x01, 0x40, 0x31, 0x21, 0x82, 0x08, 0x21, 0xA1, 0x70, + 0x94, 0xF8, 0x5F, 0x10, 0x40, 0xF0, 0x0C, 0x00, 0x21, 0xF0, 0x1F, 0x01, + 0x84, 0xF8, 0x5F, 0x10, 0x21, 0x8E, 0x6F, 0xF3, 0x08, 0x01, 0x21, 0x86, + 0x84, 0xF8, 0x33, 0x00, 0x0C, 0x48, 0x01, 0x21, 0x00, 0x68, 0x90, 0xF8, + 0xE7, 0x00, 0xC0, 0xF3, 0x41, 0x12, 0x20, 0x46, 0xEA, 0xF7, 0x48, 0xF9, + 0x94, 0xF8, 0x28, 0x00, 0x40, 0xF0, 0x20, 0x00, 0x84, 0xF8, 0x28, 0x00, + 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x71, 0xB9, 0x00, 0x00, + 0xE6, 0x07, 0x10, 0x00, 0x16, 0xBF, 0x01, 0x20, 0x4C, 0x07, 0x10, 0x00, + 0x5C, 0x83, 0x10, 0x00, 0x95, 0x5F, 0x01, 0x00, 0x70, 0xB5, 0x00, 0xF0, + 0x72, 0xFA, 0xFF, 0xF7, 0x6B, 0xFF, 0xFF, 0xF7, 0x17, 0xFA, 0xFF, 0xF7, + 0xD5, 0xF8, 0xFE, 0xF7, 0xD9, 0xFE, 0xFE, 0xF7, 0xF7, 0xF9, 0xFD, 0xF7, + 0x67, 0xFF, 0xFE, 0xF7, 0xA8, 0xFA, 0x50, 0x48, 0x00, 0x25, 0x70, 0x21, + 0x45, 0x60, 0x4F, 0x48, 0x00, 0xF0, 0x6C, 0xFC, 0x4E, 0x48, 0x04, 0x68, + 0x94, 0xF8, 0xE7, 0x00, 0xC0, 0x06, 0x05, 0xD5, 0x28, 0x22, 0x04, 0xF5, + 0x0F, 0x61, 0x49, 0x48, 0x00, 0xF0, 0xBF, 0xFB, 0x94, 0xF8, 0x33, 0x01, + 0xC0, 0x06, 0x0D, 0xD5, 0x45, 0x48, 0x20, 0x22, 0x04, 0xF6, 0x16, 0x11, + 0x28, 0x30, 0x00, 0xF0, 0xB4, 0xFB, 0x42, 0x48, 0x28, 0x22, 0x04, 0xF6, + 0x3F, 0x11, 0x48, 0x30, 0x00, 0xF0, 0xAD, 0xFB, 0x40, 0x48, 0x05, 0x70, + 0x70, 0xBD, 0x38, 0xB1, 0x01, 0x28, 0x07, 0xD0, 0x02, 0x28, 0x07, 0xD0, + 0x17, 0x20, 0x00, 0x21, 0xFB, 0xF7, 0x65, 0xBD, 0x14, 0x20, 0xFA, 0xE7, + 0x15, 0x20, 0xF8, 0xE7, 0x16, 0x20, 0xF6, 0xE7, 0x00, 0x21, 0x01, 0x60, + 0x41, 0x60, 0x81, 0x60, 0xC1, 0x60, 0x70, 0x47, 0x70, 0xB5, 0x31, 0x4C, + 0x34, 0x4D, 0x20, 0x68, 0x09, 0xE0, 0x00, 0xBF, 0x55, 0xF8, 0x20, 0x10, + 0x32, 0x48, 0x88, 0x47, 0x00, 0x28, 0x11, 0xD0, 0x20, 0x68, 0x40, 0x1C, + 0x20, 0x60, 0x09, 0x28, 0xF4, 0xD3, 0x60, 0x68, 0x2D, 0x49, 0x40, 0x1C, + 0x10, 0x31, 0x00, 0x22, 0x60, 0x60, 0x0A, 0x70, 0x48, 0x60, 0x2A, 0x48, + 0x01, 0x68, 0x10, 0x30, 0x88, 0x47, 0x01, 0x20, 0x70, 0xBD, 0x70, 0xB5, + 0x04, 0x46, 0x00, 0x79, 0x00, 0x25, 0x60, 0xB9, 0xE0, 0x79, 0x50, 0xB9, + 0xA0, 0x79, 0x40, 0xB9, 0x20, 0x7A, 0x30, 0xB9, 0x60, 0x79, 0x20, 0xB9, + 0x60, 0x7A, 0x10, 0xB9, 0xA0, 0x7A, 0x00, 0x28, 0x12, 0xD0, 0x1E, 0x48, + 0x34, 0x21, 0x10, 0x30, 0x00, 0xF0, 0x00, 0xFC, 0x94, 0xE8, 0x4E, 0x00, + 0x1A, 0x48, 0x80, 0xE8, 0x4E, 0x00, 0x14, 0x48, 0x16, 0x49, 0x05, 0x60, + 0x60, 0x7B, 0x08, 0x70, 0x16, 0x48, 0xFF, 0xF7, 0xBD, 0xFF, 0x01, 0x20, + 0x70, 0xBD, 0x0F, 0x49, 0x50, 0xB1, 0x4A, 0x68, 0x52, 0x1C, 0x4A, 0x60, + 0x11, 0x49, 0x10, 0x31, 0x08, 0x70, 0x10, 0x48, 0x4A, 0x60, 0x01, 0x68, + 0x10, 0x30, 0x08, 0x47, 0x08, 0x68, 0x40, 0x1C, 0x08, 0x60, 0x0C, 0x48, + 0xA8, 0xE7, 0x00, 0xF0, 0x3B, 0xB8, 0x00, 0xF0, 0x3D, 0xB8, 0x00, 0xF0, + 0x40, 0xB8, 0x00, 0xF0, 0x43, 0xB8, 0x00, 0xF0, 0x48, 0xB8, 0x00, 0xF0, + 0x4B, 0xB8, 0x00, 0x00, 0xF0, 0x07, 0x10, 0x00, 0x20, 0xBF, 0x01, 0x20, + 0x4C, 0x07, 0x10, 0x00, 0xF9, 0x07, 0x10, 0x00, 0x0C, 0x7D, 0x01, 0x00, + 0xA4, 0x84, 0x10, 0x00, 0x70, 0xB5, 0x00, 0x23, 0x14, 0x46, 0x08, 0xE0, + 0x31, 0xF8, 0x13, 0x50, 0x31, 0xF8, 0x14, 0x60, 0x35, 0x44, 0x20, 0xF8, + 0x13, 0x50, 0x5B, 0x1C, 0x64, 0x1C, 0x93, 0x42, 0xF4, 0xDB, 0x70, 0xBD, + 0x30, 0xB4, 0x00, 0x24, 0x43, 0xB9, 0x0B, 0xE0, 0x30, 0xF8, 0x14, 0x30, + 0x31, 0xF8, 0x14, 0x50, 0x2B, 0x44, 0x20, 0xF8, 0x14, 0x30, 0x64, 0x1C, + 0x94, 0x42, 0xF5, 0xDB, 0x30, 0xBC, 0x70, 0x47, 0x30, 0xBC, 0x52, 0x00, + 0x00, 0xF0, 0x01, 0xBB, 0xBF, 0x48, 0x00, 0x68, 0x80, 0x6A, 0x70, 0x47, + 0xBD, 0x48, 0x00, 0x68, 0x41, 0x6A, 0x00, 0x6A, 0x70, 0x47, 0xBB, 0x48, + 0x00, 0x68, 0xD0, 0xF8, 0x6A, 0x04, 0x70, 0x47, 0xB8, 0x48, 0x00, 0x68, + 0xD0, 0xF8, 0x66, 0x14, 0xD0, 0xF8, 0x62, 0x04, 0x70, 0x47, 0xB5, 0x48, + 0x00, 0x68, 0xD0, 0xF8, 0x38, 0x0A, 0x70, 0x47, 0xB2, 0x48, 0x00, 0x68, + 0x00, 0xF5, 0x23, 0x60, 0x03, 0xC8, 0x70, 0x47, 0xF0, 0xB5, 0x00, 0x24, + 0x25, 0x46, 0xAF, 0x4E, 0x4F, 0xF4, 0x00, 0x67, 0x14, 0xE0, 0x00, 0xBF, + 0x30, 0xF8, 0x15, 0x30, 0xC3, 0xF3, 0x0B, 0x03, 0x5F, 0xEA, 0xD3, 0x2C, + 0x00, 0xD0, 0x33, 0x43, 0x00, 0x2B, 0x00, 0xDA, 0x5B, 0x42, 0x9C, 0x42, + 0x00, 0xDA, 0x9C, 0xB2, 0xBC, 0x42, 0x02, 0xD3, 0x40, 0xF2, 0xFF, 0x74, + 0x02, 0xE0, 0x6D, 0x1C, 0x8D, 0x42, 0xE9, 0xDB, 0xD4, 0x40, 0x01, 0x20, + 0xA0, 0x40, 0x80, 0xB2, 0xF0, 0xBD, 0x30, 0xB5, 0xA0, 0x4B, 0x9F, 0x4C, + 0x5A, 0x68, 0x82, 0x42, 0x02, 0xD1, 0xDA, 0x68, 0x8A, 0x42, 0x0A, 0xD0, + 0x00, 0x22, 0x06, 0xE0, 0x30, 0xF8, 0x12, 0x50, 0xC5, 0xF3, 0x0B, 0x05, + 0x24, 0xF8, 0x12, 0x50, 0x52, 0x1C, 0x8A, 0x42, 0xF6, 0xDB, 0xD9, 0x60, + 0x58, 0x60, 0x30, 0xBD, 0x30, 0xB5, 0x95, 0x4B, 0x95, 0x4C, 0x9A, 0x68, + 0x82, 0x42, 0x02, 0xD1, 0x1A, 0x69, 0x8A, 0x42, 0x0D, 0xD0, 0x00, 0x22, + 0x07, 0xE0, 0x00, 0xBF, 0x30, 0xF8, 0x12, 0x50, 0xC5, 0xF3, 0x0B, 0x05, + 0x24, 0xF8, 0x12, 0x50, 0x52, 0x1C, 0x8A, 0x42, 0xF6, 0xDB, 0x19, 0x61, + 0x98, 0x60, 0x30, 0xBD, 0x70, 0xB5, 0x04, 0x46, 0x8A, 0x48, 0x01, 0x68, + 0x02, 0x29, 0x0A, 0xD1, 0x86, 0x4D, 0x29, 0x78, 0x8C, 0x42, 0x06, 0xD0, + 0x00, 0xEB, 0x84, 0x00, 0xD0, 0xF8, 0x9C, 0x00, 0xE9, 0xF7, 0x3D, 0xFE, + 0x2C, 0x70, 0x70, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0x90, 0xF8, 0x28, 0x00, + 0x80, 0x06, 0x1B, 0xD5, 0x7A, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x70, 0x01, + 0x80, 0x07, 0x01, 0xD5, 0x7D, 0x48, 0x0F, 0xE0, 0x7D, 0x49, 0x08, 0x68, + 0x00, 0x28, 0x0F, 0xD1, 0xA0, 0x7C, 0x94, 0xF8, 0x27, 0x20, 0x80, 0x09, + 0xC0, 0xEB, 0xC0, 0x00, 0x12, 0xF0, 0x01, 0x0F, 0x01, 0xEB, 0x00, 0x10, + 0x05, 0xD0, 0x00, 0x1D, 0xE9, 0xF7, 0x09, 0xFE, 0xA4, 0xF8, 0x8C, 0x00, + 0x10, 0xBD, 0x00, 0xF5, 0xAA, 0x70, 0xF7, 0xE7, 0x70, 0xB5, 0x04, 0x46, + 0x90, 0xF8, 0x28, 0x00, 0x80, 0x06, 0x28, 0xD5, 0x67, 0x48, 0x00, 0x68, + 0x90, 0xF8, 0x88, 0x01, 0xC0, 0x06, 0x08, 0xD5, 0x6A, 0x48, 0x28, 0x30, + 0xE9, 0xF7, 0xF3, 0xFD, 0x24, 0xF8, 0x8E, 0x0F, 0x67, 0x48, 0x48, 0x30, + 0x16, 0xE0, 0x67, 0x48, 0x01, 0x68, 0x00, 0x29, 0x15, 0xD1, 0xA1, 0x7C, + 0x94, 0xF8, 0x27, 0x20, 0x89, 0x09, 0xC1, 0xEB, 0xC1, 0x01, 0x12, 0xF0, + 0x01, 0x0F, 0x00, 0xEB, 0x01, 0x15, 0x0B, 0xD0, 0x05, 0xF1, 0x2C, 0x00, + 0xE9, 0xF7, 0xDB, 0xFD, 0x24, 0xF8, 0x8E, 0x0F, 0x05, 0xF1, 0x4C, 0x00, + 0xE9, 0xF7, 0xD5, 0xFD, 0x60, 0x80, 0x70, 0xBD, 0x05, 0xF5, 0xBE, 0x70, + 0xE9, 0xF7, 0xCF, 0xFD, 0x24, 0xF8, 0x8E, 0x0F, 0x05, 0xF5, 0xCE, 0x70, + 0xF2, 0xE7, 0x70, 0xB5, 0x04, 0x46, 0x90, 0xF8, 0x28, 0x00, 0x80, 0x06, + 0x0B, 0xD5, 0x4B, 0x48, 0x00, 0x68, 0x90, 0xF8, 0x88, 0x01, 0xC0, 0x06, + 0x06, 0xD5, 0x4E, 0x48, 0x70, 0x30, 0xE9, 0xF7, 0xBA, 0xFD, 0xA4, 0xF8, + 0x8E, 0x00, 0x70, 0xBD, 0x4B, 0x48, 0x01, 0x68, 0x00, 0x29, 0xFA, 0xD1, + 0xA1, 0x7C, 0x94, 0xF8, 0x27, 0x20, 0x89, 0x09, 0xC1, 0xEB, 0xC1, 0x01, + 0x12, 0xF0, 0x01, 0x0F, 0x00, 0xEB, 0x01, 0x15, 0x0C, 0xD0, 0x05, 0xF1, + 0x2C, 0x00, 0xE9, 0xF7, 0xA4, 0xFD, 0x24, 0xF8, 0x8E, 0x0F, 0x05, 0xF1, + 0x4C, 0x00, 0x00, 0xBF, 0xE9, 0xF7, 0x9D, 0xFD, 0x60, 0x80, 0x70, 0xBD, + 0x05, 0xF5, 0xBE, 0x70, 0xE9, 0xF7, 0x97, 0xFD, 0x24, 0xF8, 0x8E, 0x0F, + 0x05, 0xF5, 0xCE, 0x70, 0xF2, 0xE7, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47, + 0x02, 0x00, 0x4F, 0xF0, 0x00, 0x00, 0x00, 0xD1, 0x08, 0x46, 0x70, 0x47, + 0x02, 0x46, 0x00, 0x20, 0x01, 0x2A, 0x00, 0xD1, 0x08, 0x46, 0x70, 0x47, + 0x2A, 0x49, 0x10, 0xB5, 0x09, 0x68, 0x91, 0xF8, 0xB0, 0x10, 0xCA, 0x07, + 0x08, 0xD0, 0x2A, 0x4C, 0x62, 0x78, 0x01, 0x2A, 0x05, 0xD0, 0x02, 0x21, + 0xE9, 0xF7, 0xA3, 0xFD, 0x00, 0x20, 0x60, 0x70, 0x10, 0xBD, 0xC1, 0xF3, + 0xC1, 0x01, 0xF7, 0xE7, 0x20, 0x49, 0x0A, 0x68, 0x92, 0xF8, 0xB0, 0x20, + 0x93, 0x09, 0x10, 0xF8, 0x3E, 0x2B, 0x63, 0xF3, 0x82, 0x02, 0x00, 0xF8, + 0x3E, 0x2C, 0x0B, 0x68, 0x93, 0xF8, 0xB0, 0x30, 0x5B, 0x09, 0x63, 0xF3, + 0x45, 0x12, 0x00, 0xF8, 0x3E, 0x2C, 0x09, 0x68, 0xB1, 0xF8, 0xB7, 0x20, + 0x02, 0x82, 0x91, 0xF8, 0xB6, 0x20, 0x83, 0x7F, 0x62, 0xF3, 0x07, 0x13, + 0x83, 0x77, 0x91, 0xF8, 0xB3, 0x20, 0x13, 0x09, 0x02, 0x7D, 0x63, 0xF3, + 0x06, 0x12, 0x02, 0x75, 0x31, 0xF8, 0xB1, 0x3F, 0x02, 0x8B, 0x63, 0xF3, + 0x09, 0x02, 0x02, 0x83, 0x11, 0xF8, 0x01, 0x2C, 0x93, 0x08, 0x82, 0x7D, + 0x63, 0xF3, 0x86, 0x12, 0x82, 0x75, 0x8A, 0x78, 0xC3, 0x7D, 0x62, 0xF3, + 0x03, 0x03, 0xC3, 0x75, 0xB1, 0xF8, 0x03, 0x30, 0xB0, 0xF8, 0x1B, 0x20, + 0x63, 0xF3, 0x08, 0x02, 0xA0, 0xF8, 0x1B, 0x20, 0x09, 0x89, 0x41, 0x82, + 0x70, 0x47, 0x00, 0x00, 0x4C, 0x07, 0x10, 0x00, 0x00, 0xF0, 0xFF, 0xFF, + 0x00, 0x9B, 0x01, 0x20, 0xF8, 0x07, 0x10, 0x00, 0x00, 0x9D, 0x01, 0x20, + 0xE8, 0x84, 0x10, 0x00, 0xE4, 0x9F, 0x01, 0x20, 0x40, 0x9D, 0x01, 0x20, + 0x00, 0x20, 0xFF, 0xF7, 0x1E, 0xBE, 0x70, 0x47, 0x10, 0xB5, 0xE9, 0xF7, + 0x64, 0xFF, 0x08, 0xB1, 0x01, 0x20, 0x10, 0xBD, 0x0B, 0x48, 0xE9, 0xF7, + 0x47, 0xFF, 0x00, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0x09, 0x48, + 0x00, 0x68, 0x90, 0xF8, 0x70, 0x00, 0x40, 0x07, 0x01, 0xD5, 0xE9, 0xF7, + 0x47, 0xFF, 0x20, 0x7B, 0x20, 0xB1, 0x05, 0x49, 0xEA, 0xF7, 0x12, 0xFC, + 0x00, 0x20, 0x10, 0xBD, 0x01, 0x20, 0x10, 0xBD, 0x6B, 0x6A, 0x01, 0x00, + 0x4C, 0x07, 0x10, 0x00, 0x29, 0x6E, 0x01, 0x00, 0x43, 0x48, 0x01, 0x68, + 0x21, 0xF0, 0x04, 0x01, 0x01, 0x60, 0x70, 0x47, 0x00, 0xB5, 0xFF, 0xF7, + 0xF7, 0xFF, 0x00, 0xBD, 0x00, 0xB5, 0xFF, 0xF7, 0xF3, 0xFF, 0x00, 0xBD, + 0x00, 0xB5, 0xFF, 0xF7, 0xEF, 0xFF, 0x00, 0xBD, 0x10, 0xB5, 0xFF, 0xF7, + 0xEB, 0xFF, 0xBD, 0xE8, 0x10, 0x40, 0xEA, 0xF7, 0x32, 0xBB, 0x10, 0xB5, + 0xFF, 0xF7, 0xE4, 0xFF, 0xBD, 0xE8, 0x10, 0x40, 0xE9, 0xF7, 0xF8, 0xBC, + 0x10, 0xB5, 0xFF, 0xF7, 0xDD, 0xFF, 0xBD, 0xE8, 0x10, 0x40, 0xEA, 0xF7, + 0x28, 0xBC, 0x10, 0xB5, 0xFF, 0xF7, 0xD6, 0xFF, 0xBD, 0xE8, 0x10, 0x40, + 0xEA, 0xF7, 0x66, 0xBC, 0x10, 0xB5, 0xFF, 0xF7, 0xCF, 0xFF, 0xBD, 0xE8, + 0x10, 0x40, 0xEA, 0xF7, 0x90, 0xBC, 0x10, 0xB5, 0xFF, 0xF7, 0xC8, 0xFF, + 0xBD, 0xE8, 0x10, 0x40, 0xEA, 0xF7, 0xBA, 0xBC, 0x10, 0xB5, 0xFF, 0xF7, + 0xC1, 0xFF, 0xBD, 0xE8, 0x10, 0x40, 0xEA, 0xF7, 0xC8, 0xBC, 0x10, 0xB5, + 0xFF, 0xF7, 0xBA, 0xFF, 0xBD, 0xE8, 0x10, 0x40, 0xEA, 0xF7, 0xE6, 0xBC, + 0x10, 0xB5, 0xFF, 0xF7, 0xB3, 0xFF, 0xBD, 0xE8, 0x10, 0x40, 0xEA, 0xF7, + 0xEF, 0xBC, 0x10, 0xB5, 0xFF, 0xF7, 0xAC, 0xFF, 0xBD, 0xE8, 0x10, 0x40, + 0x00, 0xF0, 0xF2, 0xB9, 0x10, 0xB5, 0xFF, 0xF7, 0xA5, 0xFF, 0xBD, 0xE8, + 0x10, 0x40, 0x00, 0xF0, 0xC7, 0xB9, 0x00, 0xB5, 0xFF, 0xF7, 0x9E, 0xFF, + 0x00, 0xBD, 0x00, 0xB5, 0xFF, 0xF7, 0x9A, 0xFF, 0x00, 0xBD, 0x00, 0xB5, + 0xFF, 0xF7, 0x96, 0xFF, 0x00, 0xBD, 0x10, 0xB5, 0xFF, 0xF7, 0x92, 0xFF, + 0xBD, 0xE8, 0x10, 0x40, 0xEA, 0xF7, 0xFE, 0xBC, 0x00, 0xB5, 0xFF, 0xF7, + 0x8B, 0xFF, 0x00, 0xBD, 0x00, 0xB5, 0xFF, 0xF7, 0x87, 0xFF, 0x00, 0xBD, + 0x00, 0xB5, 0xFF, 0xF7, 0x83, 0xFF, 0x00, 0xBD, 0x00, 0xB5, 0xFF, 0xF7, + 0x7F, 0xFF, 0x00, 0xBD, 0x00, 0xB5, 0xFF, 0xF7, 0x7B, 0xFF, 0x00, 0xBD, + 0x70, 0x47, 0x00, 0x00, 0x10, 0xED, 0x00, 0xE0, 0x10, 0xB5, 0x4A, 0xF2, + 0x33, 0x20, 0xE9, 0xF7, 0xB4, 0xFF, 0xFC, 0xF7, 0x19, 0xF8, 0xFB, 0xF7, + 0x2D, 0xFE, 0xE9, 0xF7, 0x33, 0xFA, 0x00, 0x21, 0x47, 0x20, 0xFB, 0xF7, + 0x74, 0xFA, 0x01, 0x20, 0x10, 0xBD, 0x53, 0xEA, 0x02, 0x0C, 0x00, 0xF0, + 0x69, 0x80, 0x2D, 0xE9, 0xF0, 0x4B, 0x4F, 0xF0, 0x00, 0x06, 0x00, 0x2B, + 0x1F, 0xBF, 0xB3, 0xFA, 0x83, 0xF5, 0x03, 0xFA, 0x05, 0xF4, 0x24, 0xFA, + 0x05, 0xF6, 0x5E, 0x40, 0x12, 0xBF, 0x16, 0x43, 0xB2, 0xFA, 0x82, 0xF5, + 0x02, 0xFA, 0x05, 0xF4, 0xC5, 0xF1, 0x20, 0x05, 0x1E, 0xBF, 0x22, 0xFA, + 0x05, 0xFC, 0x44, 0xEA, 0x0C, 0x04, 0x20, 0x35, 0x56, 0xEA, 0x04, 0x4C, + 0x4F, 0xEA, 0x14, 0x44, 0x18, 0xBF, 0x64, 0x1C, 0x4F, 0xF0, 0x00, 0x08, + 0x4F, 0xF0, 0x00, 0x09, 0x90, 0x42, 0x71, 0xEB, 0x03, 0x0C, 0x39, 0xD3, + 0x00, 0x29, 0x19, 0xBF, 0xB1, 0xFA, 0x81, 0xF7, 0x01, 0xFA, 0x07, 0xF6, + 0xB0, 0xFA, 0x80, 0xF7, 0x00, 0xFA, 0x07, 0xF6, 0xC7, 0xF1, 0x20, 0x07, + 0x1E, 0xBF, 0x20, 0xFA, 0x07, 0xFC, 0x46, 0xEA, 0x0C, 0x06, 0x20, 0x37, + 0xB6, 0xFB, 0xF4, 0xFC, 0xA7, 0xEB, 0x05, 0x07, 0x10, 0x3F, 0x07, 0xF0, + 0x1F, 0x0B, 0xCB, 0xF1, 0x20, 0x06, 0x0C, 0xFA, 0x0B, 0xFB, 0x2C, 0xFA, + 0x06, 0xF6, 0x44, 0xBF, 0xB3, 0x46, 0x00, 0x26, 0x20, 0x2F, 0xA4, 0xBF, + 0x5E, 0x46, 0x4F, 0xF0, 0x00, 0x0B, 0x5B, 0xEA, 0x06, 0x0C, 0x08, 0xBF, + 0x4F, 0xF0, 0x01, 0x0B, 0x19, 0xEB, 0x0B, 0x09, 0xAB, 0xFB, 0x02, 0x7C, + 0x48, 0xEB, 0x06, 0x08, 0xC0, 0x1B, 0x06, 0xFB, 0x02, 0xCC, 0x0B, 0xFB, + 0x03, 0xCC, 0x71, 0xEB, 0x0C, 0x01, 0xC1, 0xE7, 0x0B, 0x46, 0x02, 0x46, + 0x41, 0x46, 0x48, 0x46, 0xBD, 0xE8, 0xF0, 0x8B, 0x13, 0xB5, 0x4F, 0xF0, + 0x00, 0x00, 0x4F, 0xF0, 0x00, 0x01, 0xAF, 0xF3, 0x00, 0x80, 0xBD, 0xE8, + 0x1C, 0x40, 0x70, 0x47, 0xB2, 0xF1, 0x20, 0x03, 0x0A, 0xD5, 0xC2, 0xF1, + 0x20, 0x03, 0x01, 0xFA, 0x02, 0xF1, 0x20, 0xFA, 0x03, 0xF3, 0x00, 0xFA, + 0x02, 0xF0, 0x41, 0xEA, 0x03, 0x01, 0x70, 0x47, 0x00, 0xFA, 0x03, 0xF1, + 0x4F, 0xF0, 0x00, 0x00, 0x70, 0x47, 0x10, 0xB5, 0x4C, 0x10, 0x84, 0xEA, + 0x53, 0x04, 0x04, 0xD5, 0x40, 0x42, 0xC1, 0xF1, 0x00, 0x01, 0x38, 0xBF, + 0x49, 0x1E, 0x1B, 0x42, 0x04, 0xD5, 0x52, 0x42, 0xC3, 0xF1, 0x00, 0x03, + 0x38, 0xBF, 0x5B, 0x1E, 0xFF, 0xF7, 0x63, 0xFF, 0x14, 0xF0, 0x80, 0x4F, + 0x04, 0xD0, 0x40, 0x42, 0xC1, 0xF1, 0x00, 0x01, 0x38, 0xBF, 0x49, 0x1E, + 0x14, 0xF0, 0x00, 0x4F, 0x04, 0xD0, 0x52, 0x42, 0xC3, 0xF1, 0x00, 0x03, + 0x38, 0xBF, 0x5B, 0x1E, 0x10, 0xBD, 0x03, 0x2A, 0x40, 0xF2, 0x30, 0x80, + 0x10, 0xF0, 0x03, 0x0C, 0x00, 0xF0, 0x15, 0x80, 0x11, 0xF8, 0x01, 0x3B, + 0xBC, 0xF1, 0x02, 0x0F, 0x62, 0x44, 0x98, 0xBF, 0x11, 0xF8, 0x01, 0xCB, + 0x00, 0xF8, 0x01, 0x3B, 0x38, 0xBF, 0x11, 0xF8, 0x01, 0x3B, 0xA2, 0xF1, + 0x04, 0x02, 0x98, 0xBF, 0x00, 0xF8, 0x01, 0xCB, 0x38, 0xBF, 0x00, 0xF8, + 0x01, 0x3B, 0x11, 0xF0, 0x03, 0x03, 0x00, 0xF0, 0x25, 0x80, 0x08, 0x3A, + 0xC0, 0xF0, 0x08, 0x80, 0x51, 0xF8, 0x04, 0x3B, 0x08, 0x3A, 0x51, 0xF8, + 0x04, 0xCB, 0xA0, 0xE8, 0x08, 0x10, 0xF5, 0xE7, 0x12, 0x1D, 0x5C, 0xBF, + 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, 0xAF, 0xF3, 0x00, 0x80, + 0xD2, 0x07, 0x24, 0xBF, 0x11, 0xF8, 0x01, 0x3B, 0x11, 0xF8, 0x01, 0xCB, + 0x48, 0xBF, 0x11, 0xF8, 0x01, 0x2B, 0x24, 0xBF, 0x00, 0xF8, 0x01, 0x3B, + 0x00, 0xF8, 0x01, 0xCB, 0x48, 0xBF, 0x00, 0xF8, 0x01, 0x2B, 0x70, 0x47, + 0x10, 0xB5, 0x20, 0x3A, 0xC0, 0xF0, 0x0B, 0x80, 0xB1, 0xE8, 0x18, 0x50, + 0x20, 0x3A, 0xA0, 0xE8, 0x18, 0x50, 0xB1, 0xE8, 0x18, 0x50, 0xA0, 0xE8, + 0x18, 0x50, 0xBF, 0xF4, 0xF5, 0xAF, 0x5F, 0xEA, 0x02, 0x7C, 0x24, 0xBF, + 0xB1, 0xE8, 0x18, 0x50, 0xA0, 0xE8, 0x18, 0x50, 0x44, 0xBF, 0x18, 0xC9, + 0x18, 0xC0, 0xBD, 0xE8, 0x10, 0x40, 0x5F, 0xEA, 0x82, 0x7C, 0x24, 0xBF, + 0x51, 0xF8, 0x04, 0x3B, 0x40, 0xF8, 0x04, 0x3B, 0x08, 0xBF, 0x70, 0x47, + 0xD2, 0x07, 0x28, 0xBF, 0x31, 0xF8, 0x02, 0x3B, 0x48, 0xBF, 0x11, 0xF8, + 0x01, 0x2B, 0x28, 0xBF, 0x20, 0xF8, 0x02, 0x3B, 0x48, 0xBF, 0x00, 0xF8, + 0x01, 0x2B, 0x70, 0x47, 0x02, 0xF0, 0xFF, 0x03, 0x43, 0xEA, 0x03, 0x22, + 0x42, 0xEA, 0x02, 0x42, 0x00, 0xF0, 0x02, 0xB8, 0x4F, 0xF0, 0x00, 0x02, + 0x04, 0x29, 0xC0, 0xF0, 0x12, 0x80, 0x10, 0xF0, 0x03, 0x0C, 0x00, 0xF0, + 0x1B, 0x80, 0xCC, 0xF1, 0x04, 0x0C, 0xBC, 0xF1, 0x02, 0x0F, 0x18, 0xBF, + 0x00, 0xF8, 0x01, 0x2B, 0xA8, 0xBF, 0x20, 0xF8, 0x02, 0x2B, 0xA1, 0xEB, + 0x0C, 0x01, 0x00, 0xF0, 0x0D, 0xB8, 0x5F, 0xEA, 0xC1, 0x7C, 0x24, 0xBF, + 0x00, 0xF8, 0x01, 0x2B, 0x00, 0xF8, 0x01, 0x2B, 0x48, 0xBF, 0x00, 0xF8, + 0x01, 0x2B, 0x70, 0x47, 0x4F, 0xF0, 0x00, 0x02, 0x00, 0xB5, 0x13, 0x46, + 0x94, 0x46, 0x96, 0x46, 0x20, 0x39, 0x22, 0xBF, 0xA0, 0xE8, 0x0C, 0x50, + 0xA0, 0xE8, 0x0C, 0x50, 0xB1, 0xF1, 0x20, 0x01, 0xBF, 0xF4, 0xF7, 0xAF, + 0x09, 0x07, 0x28, 0xBF, 0xA0, 0xE8, 0x0C, 0x50, 0x48, 0xBF, 0x0C, 0xC0, + 0x5D, 0xF8, 0x04, 0xEB, 0x89, 0x00, 0x28, 0xBF, 0x40, 0xF8, 0x04, 0x2B, + 0x08, 0xBF, 0x70, 0x47, 0x48, 0xBF, 0x20, 0xF8, 0x02, 0x2B, 0x11, 0xF0, + 0x80, 0x4F, 0x18, 0xBF, 0x00, 0xF8, 0x01, 0x2B, 0x70, 0x47, 0x04, 0x46, + 0xAF, 0xF3, 0x00, 0x80, 0x20, 0x46, 0xE8, 0xF7, 0x93, 0xFF, 0x00, 0x00, + 0x01, 0x49, 0x18, 0x20, 0xAB, 0xBE, 0xFE, 0xE7, 0x26, 0x00, 0x02, 0x00, + 0x70, 0x47, 0x00, 0x00, 0x01, 0x49, 0x00, 0x20, 0x08, 0x60, 0x70, 0x47, + 0x3C, 0x05, 0x00, 0x22, 0x2D, 0xE9, 0xF0, 0x41, 0x00, 0x24, 0x01, 0x27, + 0xDF, 0xF8, 0x38, 0x80, 0x5F, 0xEA, 0x47, 0x75, 0x07, 0xFA, 0x04, 0xF0, + 0xC6, 0xB2, 0x95, 0xF8, 0x2F, 0x00, 0x30, 0x42, 0x0C, 0xD0, 0x95, 0xF8, + 0x39, 0x00, 0x30, 0x42, 0x08, 0xD0, 0x58, 0xF8, 0x24, 0x00, 0x00, 0xB1, + 0x80, 0x47, 0x95, 0xF8, 0x2F, 0x00, 0xB0, 0x43, 0x85, 0xF8, 0x2F, 0x00, + 0x64, 0x1C, 0x06, 0x2C, 0xE8, 0xDB, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, + 0xD4, 0x0E, 0x10, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x00, 0x24, 0x01, 0x27, + 0xDF, 0xF8, 0x38, 0x80, 0x5F, 0xEA, 0x47, 0x75, 0x07, 0xFA, 0x04, 0xF0, + 0xC6, 0xB2, 0x95, 0xF8, 0x2E, 0x00, 0x30, 0x42, 0x0C, 0xD0, 0x95, 0xF8, + 0x38, 0x00, 0x30, 0x42, 0x08, 0xD0, 0x58, 0xF8, 0x24, 0x00, 0x00, 0xB1, + 0x80, 0x47, 0x95, 0xF8, 0x2E, 0x00, 0xB0, 0x43, 0x85, 0xF8, 0x2E, 0x00, + 0x64, 0x1C, 0x06, 0x2C, 0xE8, 0xDB, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, + 0xB4, 0x0E, 0x10, 0x00, 0x01, 0x21, 0x81, 0x40, 0xC8, 0xB2, 0x4F, 0xF0, + 0x00, 0x51, 0x91, 0xF8, 0x33, 0x10, 0x01, 0x42, 0x01, 0xD0, 0x01, 0x20, + 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x01, 0x49, 0x01, 0x20, + 0x08, 0x60, 0x70, 0x47, 0x3C, 0x05, 0x00, 0x22, 0x07, 0x48, 0x41, 0x78, + 0x49, 0xB1, 0x80, 0x78, 0x38, 0xB1, 0x06, 0x48, 0x00, 0x78, 0x01, 0x28, + 0x03, 0xD1, 0x05, 0x48, 0x00, 0x78, 0x01, 0x28, 0x00, 0xD0, 0x00, 0x20, + 0x70, 0x47, 0x00, 0x00, 0x74, 0x07, 0x10, 0x00, 0xFD, 0x06, 0x10, 0x00, + 0x5C, 0x05, 0x10, 0x00, 0x03, 0x48, 0x41, 0x78, 0x11, 0xB9, 0x80, 0x78, + 0x00, 0x28, 0x00, 0xD0, 0x01, 0x20, 0x70, 0x47, 0x74, 0x07, 0x10, 0x00, + 0x01, 0x48, 0x00, 0x78, 0x70, 0x47, 0x00, 0x00, 0x74, 0x06, 0x10, 0x00, + 0xC0, 0x6E, 0x70, 0x47, 0x90, 0xF8, 0x73, 0x00, 0x70, 0x47, 0x90, 0xF8, + 0x72, 0x00, 0x70, 0x47, 0x04, 0x48, 0x41, 0x78, 0x82, 0x78, 0x00, 0x78, + 0x11, 0x44, 0x08, 0x18, 0x00, 0xD0, 0x01, 0x20, 0x70, 0x47, 0x00, 0x00, + 0x2D, 0x06, 0x10, 0x00, 0x70, 0xB5, 0xD0, 0xE9, 0x00, 0x21, 0x4C, 0x08, + 0x4F, 0xEA, 0x32, 0x03, 0x96, 0x18, 0x41, 0xEB, 0x01, 0x05, 0x33, 0x43, + 0x2C, 0x43, 0x13, 0x43, 0x0C, 0x43, 0xC0, 0xE9, 0x00, 0x34, 0x70, 0xBD, + 0x01, 0xEB, 0x81, 0x01, 0x00, 0xEB, 0xC1, 0x00, 0x29, 0x30, 0x70, 0x47, + 0x02, 0x4A, 0x12, 0x78, 0x51, 0x43, 0x00, 0xEB, 0x41, 0x00, 0x70, 0x47, + 0xEE, 0x06, 0x10, 0x00, 0x01, 0xEB, 0x81, 0x01, 0x00, 0xEB, 0xC1, 0x00, + 0x29, 0x30, 0x70, 0x47, 0x02, 0x4A, 0x12, 0x78, 0x51, 0x43, 0x00, 0xEB, + 0x41, 0x00, 0x70, 0x47, 0xEE, 0x06, 0x10, 0x00, 0x00, 0x04, 0x40, 0x00, + 0x10, 0x21, 0x00, 0x00, 0x00, 0x1F, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x01, 0x00, 0x00, 0x04, 0x06, 0x00, 0x08, 0x02, 0x50, 0x00, + 0x60, 0x02, 0x0C, 0x0C, 0x00, 0x00, 0x60, 0x02, 0x0C, 0x30, 0x0C, 0x1A, + 0x31, 0x10, 0x0F, 0x0F, 0x00, 0x00, 0x2F, 0x00, 0x01, 0x00, 0xAA, 0x2C, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x02, 0x01, 0x80, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x07, 0x01, + 0x26, 0x26, 0x12, 0x12, 0x11, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x3C, + 0x20, 0x3D, 0xD0, 0x41, 0xEC, 0x41, 0x08, 0x42, 0x1C, 0x42, 0x30, 0x42, + 0x44, 0x42, 0x60, 0x42, 0x74, 0x42, 0x88, 0x42, 0xA4, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03, + 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x1B, 0x00, 0x00, 0x80, 0x2D, 0x00, 0x00, 0x80, 0x36, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x00, 0x80, 0x5A, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, + 0x77, 0x00, 0x00, 0x80, 0x99, 0x00, 0x00, 0x80, 0x82, 0x00, 0x00, 0x00, + 0xB4, 0x00, 0x00, 0x00, 0xAF, 0x00, 0x00, 0x80, 0xD8, 0x00, 0x00, 0x00, + 0xC3, 0x00, 0x00, 0x80, 0xF5, 0x00, 0x00, 0x80, 0xEE, 0x00, 0x00, 0x00, + 0x29, 0x01, 0x00, 0x80, 0x32, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, + 0x1F, 0x01, 0x00, 0x80, 0x68, 0x01, 0x00, 0x00, 0x73, 0x01, 0x00, 0x80, + 0x45, 0x01, 0x00, 0x80, 0x5E, 0x01, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, + 0xAB, 0x01, 0x00, 0x80, 0x9D, 0x01, 0x00, 0x80, 0x86, 0x01, 0x00, 0x00, + 0xF1, 0x01, 0x00, 0x80, 0xEA, 0x01, 0x00, 0x00, 0xDC, 0x01, 0x00, 0x00, + 0xC7, 0x01, 0x00, 0x80, 0x49, 0x02, 0x00, 0x80, 0x52, 0x02, 0x00, 0x00, + 0x64, 0x02, 0x00, 0x00, 0x7F, 0x02, 0x00, 0x80, 0x08, 0x02, 0x00, 0x00, + 0x13, 0x02, 0x00, 0x80, 0x25, 0x02, 0x00, 0x80, 0x3E, 0x02, 0x00, 0x00, + 0xD0, 0x02, 0x00, 0x00, 0xCB, 0x02, 0x00, 0x80, 0xFD, 0x02, 0x00, 0x80, + 0xE6, 0x02, 0x00, 0x00, 0x91, 0x02, 0x00, 0x80, 0x8A, 0x02, 0x00, 0x00, + 0xBC, 0x02, 0x00, 0x00, 0xA7, 0x02, 0x00, 0x80, 0x60, 0x03, 0x00, 0x00, + 0x7B, 0x03, 0x00, 0x80, 0x4D, 0x03, 0x00, 0x80, 0x56, 0x03, 0x00, 0x00, + 0x21, 0x03, 0x00, 0x80, 0x3A, 0x03, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, + 0x17, 0x03, 0x00, 0x80, 0xF9, 0x03, 0x00, 0x80, 0xE2, 0x03, 0x00, 0x00, + 0xD4, 0x03, 0x00, 0x00, 0xCF, 0x03, 0x00, 0x80, 0xB8, 0x03, 0x00, 0x00, + 0xA3, 0x03, 0x00, 0x80, 0x95, 0x03, 0x00, 0x80, 0x8E, 0x03, 0x00, 0x00, + 0x89, 0x04, 0x00, 0x80, 0x92, 0x04, 0x00, 0x00, 0xA4, 0x04, 0x00, 0x00, + 0xBF, 0x04, 0x00, 0x80, 0xC8, 0x04, 0x00, 0x00, 0xD3, 0x04, 0x00, 0x80, + 0xE5, 0x04, 0x00, 0x80, 0xFE, 0x04, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, + 0x0B, 0x04, 0x00, 0x80, 0x3D, 0x04, 0x00, 0x80, 0x26, 0x04, 0x00, 0x00, + 0x51, 0x04, 0x00, 0x80, 0x4A, 0x04, 0x00, 0x00, 0x7C, 0x04, 0x00, 0x00, + 0x67, 0x04, 0x00, 0x80, 0xA0, 0x05, 0x00, 0x00, 0xBB, 0x05, 0x00, 0x80, + 0x8D, 0x05, 0x00, 0x80, 0x96, 0x05, 0x00, 0x00, 0xE1, 0x05, 0x00, 0x80, + 0xFA, 0x05, 0x00, 0x00, 0xCC, 0x05, 0x00, 0x00, 0xD7, 0x05, 0x00, 0x80, + 0x39, 0x05, 0x00, 0x80, 0x22, 0x05, 0x00, 0x00, 0x14, 0x05, 0x00, 0x00, + 0x0F, 0x05, 0x00, 0x80, 0x78, 0x05, 0x00, 0x00, 0x63, 0x05, 0x00, 0x80, + 0x55, 0x05, 0x00, 0x80, 0x4E, 0x05, 0x00, 0x00, 0xC0, 0x06, 0x00, 0x00, + 0xDB, 0x06, 0x00, 0x80, 0xED, 0x06, 0x00, 0x80, 0xF6, 0x06, 0x00, 0x00, + 0x81, 0x06, 0x00, 0x80, 0x9A, 0x06, 0x00, 0x00, 0xAC, 0x06, 0x00, 0x00, + 0xB7, 0x06, 0x00, 0x80, 0x59, 0x06, 0x00, 0x80, 0x42, 0x06, 0x00, 0x00, + 0x74, 0x06, 0x00, 0x00, 0x6F, 0x06, 0x00, 0x80, 0x18, 0x06, 0x00, 0x00, + 0x03, 0x06, 0x00, 0x80, 0x35, 0x06, 0x00, 0x80, 0x2E, 0x06, 0x00, 0x00, + 0xE9, 0x07, 0x00, 0x80, 0xF2, 0x07, 0x00, 0x00, 0xC4, 0x07, 0x00, 0x00, + 0xDF, 0x07, 0x00, 0x80, 0xA8, 0x07, 0x00, 0x00, 0xB3, 0x07, 0x00, 0x80, + 0x85, 0x07, 0x00, 0x80, 0x9E, 0x07, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, + 0x6B, 0x07, 0x00, 0x80, 0x5D, 0x07, 0x00, 0x80, 0x46, 0x07, 0x00, 0x00, + 0x31, 0x07, 0x00, 0x80, 0x2A, 0x07, 0x00, 0x00, 0x1C, 0x07, 0x00, 0x00, + 0x07, 0x07, 0x00, 0x80, 0x09, 0x09, 0x00, 0x80, 0x12, 0x09, 0x00, 0x00, + 0x24, 0x09, 0x00, 0x00, 0x3F, 0x09, 0x00, 0x80, 0x48, 0x09, 0x00, 0x00, + 0x53, 0x09, 0x00, 0x80, 0x65, 0x09, 0x00, 0x80, 0x7E, 0x09, 0x00, 0x00, + 0x90, 0x09, 0x00, 0x00, 0x8B, 0x09, 0x00, 0x80, 0xBD, 0x09, 0x00, 0x80, + 0xA6, 0x09, 0x00, 0x00, 0xD1, 0x09, 0x00, 0x80, 0xCA, 0x09, 0x00, 0x00, + 0xFC, 0x09, 0x00, 0x00, 0xE7, 0x09, 0x00, 0x80, 0x20, 0x08, 0x00, 0x00, + 0x3B, 0x08, 0x00, 0x80, 0x0D, 0x08, 0x00, 0x80, 0x16, 0x08, 0x00, 0x00, + 0x61, 0x08, 0x00, 0x80, 0x7A, 0x08, 0x00, 0x00, 0x4C, 0x08, 0x00, 0x00, + 0x57, 0x08, 0x00, 0x80, 0xB9, 0x08, 0x00, 0x80, 0xA2, 0x08, 0x00, 0x00, + 0x94, 0x08, 0x00, 0x00, 0x8F, 0x08, 0x00, 0x80, 0xF8, 0x08, 0x00, 0x00, + 0xE3, 0x08, 0x00, 0x80, 0xD5, 0x08, 0x00, 0x80, 0xCE, 0x08, 0x00, 0x00, + 0x40, 0x0B, 0x00, 0x00, 0x5B, 0x0B, 0x00, 0x80, 0x6D, 0x0B, 0x00, 0x80, + 0x76, 0x0B, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x80, 0x1A, 0x0B, 0x00, 0x00, + 0x2C, 0x0B, 0x00, 0x00, 0x37, 0x0B, 0x00, 0x80, 0xD9, 0x0B, 0x00, 0x80, + 0xC2, 0x0B, 0x00, 0x00, 0xF4, 0x0B, 0x00, 0x00, 0xEF, 0x0B, 0x00, 0x80, + 0x98, 0x0B, 0x00, 0x00, 0x83, 0x0B, 0x00, 0x80, 0xB5, 0x0B, 0x00, 0x80, + 0xAE, 0x0B, 0x00, 0x00, 0x69, 0x0A, 0x00, 0x80, 0x72, 0x0A, 0x00, 0x00, + 0x44, 0x0A, 0x00, 0x00, 0x5F, 0x0A, 0x00, 0x80, 0x28, 0x0A, 0x00, 0x00, + 0x33, 0x0A, 0x00, 0x80, 0x05, 0x0A, 0x00, 0x80, 0x1E, 0x0A, 0x00, 0x00, + 0xF0, 0x0A, 0x00, 0x00, 0xEB, 0x0A, 0x00, 0x80, 0xDD, 0x0A, 0x00, 0x80, + 0xC6, 0x0A, 0x00, 0x00, 0xB1, 0x0A, 0x00, 0x80, 0xAA, 0x0A, 0x00, 0x00, + 0x9C, 0x0A, 0x00, 0x00, 0x87, 0x0A, 0x00, 0x80, 0x80, 0x0D, 0x00, 0x00, + 0x9B, 0x0D, 0x00, 0x80, 0xAD, 0x0D, 0x00, 0x80, 0xB6, 0x0D, 0x00, 0x00, + 0xC1, 0x0D, 0x00, 0x80, 0xDA, 0x0D, 0x00, 0x00, 0xEC, 0x0D, 0x00, 0x00, + 0xF7, 0x0D, 0x00, 0x80, 0x19, 0x0D, 0x00, 0x80, 0x02, 0x0D, 0x00, 0x00, + 0x34, 0x0D, 0x00, 0x00, 0x2F, 0x0D, 0x00, 0x80, 0x58, 0x0D, 0x00, 0x00, + 0x43, 0x0D, 0x00, 0x80, 0x75, 0x0D, 0x00, 0x80, 0x6E, 0x0D, 0x00, 0x00, + 0xA9, 0x0C, 0x00, 0x80, 0xB2, 0x0C, 0x00, 0x00, 0x84, 0x0C, 0x00, 0x00, + 0x9F, 0x0C, 0x00, 0x80, 0xE8, 0x0C, 0x00, 0x00, 0xF3, 0x0C, 0x00, 0x80, + 0xC5, 0x0C, 0x00, 0x80, 0xDE, 0x0C, 0x00, 0x00, 0x30, 0x0C, 0x00, 0x00, + 0x2B, 0x0C, 0x00, 0x80, 0x1D, 0x0C, 0x00, 0x80, 0x06, 0x0C, 0x00, 0x00, + 0x71, 0x0C, 0x00, 0x80, 0x6A, 0x0C, 0x00, 0x00, 0x5C, 0x0C, 0x00, 0x00, + 0x47, 0x0C, 0x00, 0x80, 0xC9, 0x0F, 0x00, 0x80, 0xD2, 0x0F, 0x00, 0x00, + 0xE4, 0x0F, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x80, 0x88, 0x0F, 0x00, 0x00, + 0x93, 0x0F, 0x00, 0x80, 0xA5, 0x0F, 0x00, 0x80, 0xBE, 0x0F, 0x00, 0x00, + 0x50, 0x0F, 0x00, 0x00, 0x4B, 0x0F, 0x00, 0x80, 0x7D, 0x0F, 0x00, 0x80, + 0x66, 0x0F, 0x00, 0x00, 0x11, 0x0F, 0x00, 0x80, 0x0A, 0x0F, 0x00, 0x00, + 0x3C, 0x0F, 0x00, 0x00, 0x27, 0x0F, 0x00, 0x80, 0xE0, 0x0E, 0x00, 0x00, + 0xFB, 0x0E, 0x00, 0x80, 0xCD, 0x0E, 0x00, 0x80, 0xD6, 0x0E, 0x00, 0x00, + 0xA1, 0x0E, 0x00, 0x80, 0xBA, 0x0E, 0x00, 0x00, 0x8C, 0x0E, 0x00, 0x00, + 0x97, 0x0E, 0x00, 0x80, 0x79, 0x0E, 0x00, 0x80, 0x62, 0x0E, 0x00, 0x00, + 0x54, 0x0E, 0x00, 0x00, 0x4F, 0x0E, 0x00, 0x80, 0x38, 0x0E, 0x00, 0x00, + 0x23, 0x0E, 0x00, 0x80, 0x15, 0x0E, 0x00, 0x80, 0x0E, 0x0E, 0x00, 0x00, + 0xFF, 0x00, 0xBE, 0x94, 0xFE, 0xFF, 0x27, 0xC4, 0xFE, 0xFF, 0x59, 0xF2, + 0xFE, 0xFF, 0x6B, 0x1F, 0xFF, 0xFF, 0x81, 0x4B, 0xFF, 0xFF, 0xC5, 0x76, + 0xFF, 0xFF, 0x67, 0xA1, 0xFF, 0xFF, 0x97, 0xCB, 0xFF, 0xFF, 0x88, 0xF5, + 0xFF, 0xFF, 0x6C, 0x1F, 0x00, 0x00, 0x76, 0x49, 0x00, 0x00, 0xD9, 0x73, + 0x00, 0x00, 0xC6, 0x9E, 0x00, 0x00, 0x6D, 0xCA, 0x00, 0x00, 0xFC, 0xF6, + 0x00, 0x00, 0x9A, 0x24, 0x01, 0x00, 0x66, 0x53, 0x01, 0x00, 0xA3, 0x8D, + 0x00, 0x00, 0x71, 0x74, 0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0xA2, 0x4F, + 0x00, 0x00, 0xC8, 0x42, 0x00, 0x00, 0x0C, 0x39, 0x00, 0x00, 0x21, 0x32, + 0x00, 0x00, 0xD2, 0x2D, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x9B, 0x2C, + 0x00, 0x00, 0xA9, 0x2F, 0x00, 0x00, 0x40, 0x35, 0x00, 0x00, 0x8B, 0x3D, + 0x00, 0x00, 0xCB, 0x48, 0x00, 0x00, 0x59, 0x57, 0x00, 0x00, 0xAD, 0x69, + 0x00, 0x00, 0x65, 0x80, 0x00, 0x00, 0x30, 0x11, 0x00, 0x00, 0x4C, 0x1C, + 0x00, 0x00, 0x2D, 0x29, 0x00, 0x00, 0x86, 0x37, 0x00, 0x00, 0x24, 0x47, + 0x00, 0x00, 0xE8, 0x57, 0x00, 0x00, 0xC4, 0x69, 0x00, 0x00, 0xB5, 0x7C, + 0x00, 0x00, 0xC4, 0x90, 0x00, 0x00, 0x03, 0xA6, 0x00, 0x00, 0x8F, 0xBC, + 0x00, 0x00, 0x8C, 0xD4, 0x00, 0x00, 0x29, 0xEE, 0x00, 0x00, 0x9C, 0x09, + 0x01, 0x00, 0x2B, 0x27, 0x01, 0x00, 0x24, 0x47, 0x01, 0x00, 0xE6, 0x69, + 0x01, 0x00, 0x98, 0x08, 0x00, 0x00, 0x26, 0x0E, 0x00, 0x00, 0x97, 0x14, + 0x00, 0x00, 0xC3, 0x1B, 0x00, 0x00, 0x92, 0x23, 0x00, 0x00, 0xF4, 0x2B, + 0x00, 0x00, 0xE2, 0x34, 0x00, 0x00, 0x5A, 0x3E, 0x00, 0x00, 0x62, 0x48, + 0x00, 0x00, 0x02, 0x53, 0x00, 0x00, 0x48, 0x5E, 0x00, 0x00, 0x46, 0x6A, + 0x00, 0x00, 0x14, 0x77, 0x00, 0x00, 0xCE, 0x84, 0x00, 0x00, 0x95, 0x93, + 0x00, 0x00, 0x92, 0xA3, 0x00, 0x00, 0xF3, 0xB4, 0x00, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x10, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0C, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF8, 0x47, 0x10, 0x00, 0x44, 0x4D, 0x10, 0x00, 0xC5, 0x18, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC3, 0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD1, 0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0x17, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE3, 0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x18, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x6B, 0x18, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x81, 0x18, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xB5, 0x18, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xB7, 0x18, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xB9, 0x18, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xBB, 0x18, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0xBD, 0x18, 0x01, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xBF, 0x18, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xC1, 0x18, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC3, 0x18, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x01, 0x00, 0xFB, 0x18, 0x01, 0x00, + 0x65, 0x19, 0x01, 0x00, 0xFB, 0x18, 0x01, 0x00, 0x17, 0x1A, 0x01, 0x00, + 0xFB, 0x18, 0x01, 0x00, 0xFB, 0x18, 0x01, 0x00, 0xFB, 0x18, 0x01, 0x00, + 0xFB, 0x18, 0x01, 0x00, 0xFB, 0x18, 0x01, 0x00, 0x2F, 0x19, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xFB, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x19, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x91, 0x19, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xB5, 0x19, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xD9, 0x19, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x1A, 0x01, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x13, 0x1A, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x43, 0x1A, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x91, 0x1A, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xA7, 0x1A, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0xFF, 0x1A, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0xB5, 0x1B, 0x01, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x33, 0x1C, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x73, 0x1C, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x1B, 0x01, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xFB, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFB, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x1A, 0x01, 0x00, + 0x67, 0x1A, 0x01, 0x00, 0x71, 0x1A, 0x01, 0x00, 0x81, 0x1A, 0x01, 0x00, + 0xF5, 0x1D, 0x01, 0x00, 0x17, 0x1E, 0x01, 0x00, 0x1F, 0x1E, 0x01, 0x00, + 0x3F, 0x1E, 0x01, 0x00, 0xA1, 0x1E, 0x01, 0x00, 0xB7, 0x1E, 0x01, 0x00, + 0xC7, 0x1E, 0x01, 0x00, 0xD9, 0x1E, 0x01, 0x00, 0xEB, 0x1E, 0x01, 0x00, + 0xFD, 0x1E, 0x01, 0x00, 0x0F, 0x1F, 0x01, 0x00, 0x21, 0x1F, 0x01, 0x00, + 0x33, 0x1F, 0x01, 0x00, 0x45, 0x1F, 0x01, 0x00, 0x57, 0x1F, 0x01, 0x00, + 0x69, 0x1F, 0x01, 0x00, 0x85, 0x86, 0x60, 0x61, 0xD0, 0x02, 0x0F, 0x01, + 0x00, 0xA6, 0x02, 0x0F, 0x01, 0x00, 0xA8, 0x02, 0x0B, 0x03, 0x00, 0x72, + 0x00, 0x0B, 0x01, 0x00, 0x73, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x49, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x69, 0x10, 0x00, + 0x00, 0x04, 0x00, 0x00, 0xB5, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x6D, 0x10, 0x00, 0x00, 0x04, 0x00, 0x00, 0xDD, 0x5E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x04, 0x71, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x8F, 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x79, 0x10, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x01, 0x1D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x04, 0x7B, 0x10, 0x00, 0x80, 0x00, 0x00, 0x00, 0xB9, 0x16, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xB1, 0x56, 0x01, 0x00, 0x5B, 0x56, 0x01, 0x00, 0x31, 0x6E, 0x01, 0x00, + 0x23, 0x5B, 0x01, 0x00, 0x65, 0x48, 0x01, 0x00, 0x9B, 0x5D, 0x01, 0x00, + 0x8F, 0x4D, 0x01, 0x00, 0x73, 0x68, 0x01, 0x00, 0xF1, 0x4E, 0x01, 0x00, + 0x4D, 0x57, 0x01, 0x00, 0x47, 0x6E, 0x01, 0x00, 0x60, 0x7D, 0x01, 0x00, + 0x00, 0x04, 0x10, 0x00, 0x0C, 0x04, 0x00, 0x00, 0x1C, 0x01, 0x00, 0x00, + 0x98, 0x7D, 0x01, 0x00, 0x00, 0xFC, 0x10, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x78, 0x01, 0x00, 0x00, 0x98, 0x7D, 0x01, 0x00, 0x0C, 0x08, 0x10, 0x00, + 0x88, 0x7D, 0x00, 0x00, 0x94, 0x01, 0x00, 0x00, 0x01, 0x29, 0x04, 0xFF, + 0x90, 0xD0, 0x03, 0x01, 0x71, 0x14, 0x90, 0x5F, 0x01, 0x32, 0x01, 0x32, + 0x02, 0x29, 0x08, 0x41, 0xA9, 0x08, 0x09, 0x1A, 0x0C, 0xB2, 0x64, 0x29, + 0x0C, 0x69, 0x48, 0x29, 0x04, 0x0A, 0x11, 0x04, 0x10, 0x01, 0xFF, 0x01, + 0x46, 0x07, 0xA5, 0xF0, 0x01, 0x20, 0x18, 0x50, 0x10, 0xAA, 0xFF, 0x0C, + 0x59, 0x01, 0x00, 0x00, 0x30, 0xB5, 0x72, 0xB6, 0x01, 0x24, 0x0C, 0x4D, + 0x2C, 0x60, 0x0C, 0x4B, 0x00, 0x22, 0x89, 0xB1, 0xC3, 0xF8, 0x00, 0x40, + 0x4F, 0xF0, 0x00, 0x51, 0x00, 0xF0, 0x1F, 0x00, 0x81, 0xF8, 0x6A, 0x00, + 0x06, 0x48, 0x1C, 0x38, 0x04, 0x60, 0x01, 0x68, 0x00, 0x29, 0xFC, 0xD1, + 0x1A, 0x60, 0x2A, 0x60, 0x62, 0xB6, 0x30, 0xBD, 0x1A, 0x60, 0xED, 0xE7, + 0xC0, 0x1B, 0x00, 0x22, 0x78, 0x0D, 0x00, 0x22, 0xD5, 0xA1, 0xA1, 0x0A, + 0x93, 0x02, 0x00, 0x00, 0x2A, 0x5E, 0x5E, 0xF5, 0x6C, 0xFD, 0xFF, 0xFF, + 0xA1, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x0F, 0xFF, 0x09, + 0x9F, 0x05, 0x09, 0xFF, 0x09, 0x9F, 0x05, 0x1D, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x20, 0x40, 0x50, 0xAA, 0x99, 0xC8, 0x00, 0xC8, 0x00, 0xC8, 0x00, + 0xC8, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x70, 0x00, + 0x70, 0x00, 0x08, 0xB0, 0x00, 0xB0, 0x00, 0x00, 0x07, 0xAA, 0x38, 0xC8, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x08, 0x09, 0x0A, 0x14, 0x0A, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x13, 0xE8, 0x03, + 0x64, 0x00, 0x64, 0x00, 0xD0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x00, 0x02, 0x08, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x41, 0x01, 0x08, 0x00, 0x13, 0x0C, 0x41, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x81, 0x06, 0x52, 0x4F, 0x04, 0xD8, 0x10, 0x50, + 0x00, 0x2F, 0x00, 0x08, 0xB0, 0x06, 0x03, 0x03, 0x00, 0x00, 0xBB, 0xBB, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE9, 0xA6, + 0x5E, 0x1F, 0x04, 0xD8, 0x18, 0x40, 0x00, 0x08, 0x00, 0x20, 0x50, 0x06, + 0x07, 0x00, 0x00, 0x00, 0x20, 0x50, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x16, 0x50, 0x4F, 0x04, 0x18, + 0x00, 0x30, 0x00, 0x06, 0x00, 0x2F, 0x00, 0x40, 0x10, 0x06, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA9, 0x26, 0x9A, 0x1F, 0x98, 0x18, 0x01, 0x01, 0x30, 0x00, + 0x60, 0x00, 0x60, 0x00, 0x2F, 0x00, 0x21, 0x01, 0x00, 0x00, 0x1F, 0x21, + 0x01, 0x00, 0x00, 0x1F, 0x00, 0x01, 0x20, 0x00, 0x99, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x0B, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0x1A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0x1A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x1A, 0x00, 0x00, 0x02, 0x00, + 0x01, 0x01, 0x64, 0x00, 0x64, 0x00, 0xD0, 0x00, 0x80, 0x0C, 0xF0, 0x0A, + 0xD0, 0x00, 0x00, 0x15, 0x00, 0x12, 0x50, 0x01, 0x50, 0x01, 0x00, 0x15, + 0x00, 0x12, 0x50, 0x01, 0x80, 0x0C, 0xF0, 0x0A, 0xD0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x0F, 0x00, 0x06, 0x0A, 0x0F, 0x02, 0x64, 0x90, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, + 0x14, 0x14, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x64, 0x90, 0x01, 0x90, 0x01, 0x80, 0x00, + 0x80, 0x00, 0xF4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x64, 0x00, 0x80, 0x01, 0x64, 0x00, + 0x80, 0x01, 0x96, 0x00, 0x64, 0x00, 0x20, 0x00, 0x02, 0x00, 0x96, 0x00, + 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x05, 0x01, 0xF4, 0x01, 0x2C, 0x01, 0x02, 0xFF, 0x7F, 0xFF, 0x7F, 0x02, + 0x32, 0x64, 0x00, 0x00, 0x02, 0x02, 0xA2, 0x30, 0x29, 0x64, 0x00, 0x64, + 0x00, 0xC8, 0x00, 0x58, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x64, 0x00, 0x32, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x02, 0x10, 0x00, + 0x20, 0x00, 0x18, 0x00, 0x00, 0x01, 0x62, 0x84, 0x40, 0x01, 0x20, 0x00, + 0x10, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x20, 0x00, 0x40, 0x2C, 0x7D, 0x00, 0x2C, 0x01, 0x64, 0x00, + 0x00, 0x0A, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x64, 0x00, + 0x2C, 0x01, 0x00, 0x20, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x5A, 0x00, 0x14, 0x00, 0x01, 0x03, 0x01, 0x0A, 0x00, 0x10, + 0x11, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50, 0x00, + 0x70, 0x00, 0x32, 0x00, 0x40, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x64, 0x00, 0x0A, 0x64, 0x00, 0x64, 0x00, 0x0E, 0x00, 0x05, + 0x00, 0x10, 0xC2, 0x00, 0x32, 0x00, 0x20, 0x31, 0x0F, 0x02, 0x20, 0x1F, + 0x00, 0x0A, 0x00, 0x14, 0x92, 0x11, 0x15, 0x00, 0x13, 0x00, 0x02, 0x10, + 0x0A, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x10, 0xE8, 0x10, 0x00, 0x40, + 0x00, 0x62, 0x94, 0x94, 0x28, 0xF4, 0x0A, 0x00, 0x18, 0x00, 0x10, 0x00, + 0x30, 0x00, 0x05, 0x14, 0x05, 0x20, 0x03, 0x10, 0xD8, 0x05, 0x32, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0xC8, 0x00, 0xC8, 0x00, 0x0A, 0x0A, + 0x20, 0x00, 0x64, 0x00, 0x01, 0x03, 0x64, 0x00, 0x64, 0x00, 0x01, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x32, 0x1A, + 0xFA, 0x00, 0x0A, 0x05, 0x20, 0x0A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x14, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0x03, 0x50, 0x00, 0x2C, 0x01, 0x32, 0xFF, + 0x7F, 0x0B, 0x01, 0x32, 0x00, 0x20, 0x03, 0x00, 0x0A, 0x20, 0x14, 0x05, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x02, 0x03, 0x04, 0x00, 0x01, + 0x02, 0x03, 0x50, 0x01, 0x50, 0x01, 0x50, 0x01, 0x50, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x7D, 0x6E, 0x67, + 0x65, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x65, 0x67, 0x6E, + 0x7D, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x13, 0x22, 0x22, 0x22, 0x00, 0x00, 0x0F, 0x00, 0x28, 0x00, 0x3C, + 0x00, 0x50, 0x00, 0xA0, 0x00, 0x40, 0x01, 0xE0, 0x01, 0xD0, 0x02, 0xBF, + 0x03, 0x5F, 0x04, 0xFF, 0x04, 0x4F, 0x05, 0x63, 0x05, 0x77, 0x05, 0x90, + 0x05, 0x0F, 0x00, 0x28, 0x00, 0x3C, 0x00, 0x50, 0x00, 0xA0, 0x00, 0x40, + 0x01, 0xE0, 0x01, 0xD0, 0x02, 0xC0, 0x03, 0x00, 0x05, 0x3F, 0x06, 0x2F, + 0x07, 0x1F, 0x08, 0xBF, 0x08, 0x5F, 0x09, 0xAF, 0x09, 0xC3, 0x09, 0xD7, + 0x09, 0xF5, 0x09, 0x00, 0x00, 0x0A, 0x00, 0x19, 0x00, 0x28, 0x00, 0x6C, + 0x00, 0x27, 0x01, 0xD1, 0x01, 0xD0, 0x02, 0xC6, 0x03, 0x72, 0x04, 0x21, + 0x05, 0x69, 0x05, 0x86, 0x05, 0x95, 0x05, 0x9F, 0x05, 0x00, 0x00, 0x0F, + 0x00, 0x1C, 0x00, 0x28, 0x00, 0x78, 0x00, 0x1C, 0x01, 0xC6, 0x01, 0xBE, + 0x02, 0xAE, 0x03, 0x00, 0x05, 0x4F, 0x06, 0x44, 0x07, 0x39, 0x08, 0xDE, + 0x08, 0x8A, 0x09, 0xD8, 0x09, 0xE3, 0x09, 0xF1, 0x09, 0xFF, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x64, 0x80, + 0x10, 0xE5, 0x00, 0x00, 0x64, 0x80, 0x40, 0x00, 0x80, 0x00, 0xC0, 0x00, + 0x00, 0x01, 0x40, 0x01, 0x80, 0x01, 0xC0, 0x01, 0x00, 0x02, 0x40, 0x02, + 0x80, 0x02, 0xC0, 0x02, 0x00, 0x03, 0x40, 0x03, 0x80, 0x03, 0xC0, 0x03, + 0x00, 0x04, 0x3F, 0x04, 0x7F, 0x04, 0xBF, 0x04, 0xFF, 0x04, 0x3F, 0x05, + 0x7F, 0x05, 0xBF, 0x05, 0xFF, 0x05, 0x3F, 0x06, 0x7F, 0x06, 0xBF, 0x06, + 0xFF, 0x06, 0x3F, 0x07, 0x7F, 0x07, 0xBF, 0x07, 0xFF, 0x07, 0xFF, 0x07, + 0xBF, 0x07, 0x7F, 0x07, 0x3F, 0x07, 0xFF, 0x06, 0xBF, 0x06, 0x7F, 0x06, + 0x3F, 0x06, 0xFF, 0x05, 0xBF, 0x05, 0x7F, 0x05, 0x3F, 0x05, 0xFF, 0x04, + 0xBF, 0x04, 0x7F, 0x04, 0x3F, 0x04, 0x00, 0x04, 0xC0, 0x03, 0x80, 0x03, + 0x40, 0x03, 0x00, 0x03, 0xC0, 0x02, 0x80, 0x02, 0x40, 0x02, 0x00, 0x02, + 0xC0, 0x01, 0x80, 0x01, 0x40, 0x01, 0x00, 0x01, 0xC0, 0x00, 0x80, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x40, 0x00, 0x60, 0x00, 0x80, 0x00, 0xA0, 0x00, 0xC0, 0x00, 0xE0, 0x00, + 0x00, 0x01, 0x00, 0x01, 0xE0, 0x00, 0xC0, 0x00, 0xA0, 0x00, 0x80, 0x00, + 0x60, 0x00, 0x40, 0x00, 0x20, 0x00, 0x14, 0x05, 0x14, 0x05, 0x14, 0x05, + 0x14, 0x05, 0x14, 0x05, 0x14, 0x05, 0x14, 0x05, 0x14, 0x05, 0x14, 0x05, + 0x14, 0x05, 0x14, 0x05, 0x14, 0x05, 0x14, 0x05, 0x14, 0x05, 0x14, 0x05, + 0x14, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, + 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, + 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, + 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCD, 0x00, + 0xCD, 0x00, 0xCD, 0x00, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x07, 0x08, 0x0C, 0x0D, 0x0F, + 0x0F, 0x0F, 0x0E, 0x0E, 0x0E, 0x0D, 0x0D, 0x0D, 0x0A, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x64, 0x9A, 0x1F, 0x18, 0x18, + 0x01, 0x01, 0x30, 0x00, 0x60, 0x00, 0x60, 0x00, 0x2F, 0x00, 0x21, 0x01, + 0x00, 0x00, 0x1F, 0x20, 0x01, 0x00, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x98, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x46, 0x50, 0x10, + 0x10, 0xB0, 0x20, 0xFF, 0xD0, 0x00, 0x06, 0x14, 0x14, 0x2A, 0x3A, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x6E, 0x6E, + 0x47, 0x1A, 0x38, 0x00, 0x00, 0x00, 0x01, 0x0F, 0x1E, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA9, 0x24, 0x94, 0x1F, 0x18, 0x18, 0x01, 0x00, 0x25, 0x00, + 0x25, 0x00, 0x50, 0x00, 0x24, 0x00, 0x70, 0x01, 0x00, 0x00, 0x1F, 0x80, + 0x01, 0x00, 0x00, 0x1F, 0x00, 0x01, 0x10, 0x00, 0x55, 0x00, 0x00, 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, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x75, 0x6A, 0xB0, +}; + +#endif diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/Makefile b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/Makefile new file mode 100644 index 000000000000..ca95cb0289ed --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the FTS touchscreen driver. +# + + +obj-$(CONFIG_TOUCHSCREEN_ST_FTS_V521) += ftsCompensation.o ftsCore.o ftsError.o ftsFrame.o ftsIO.o ftsTest.o ftsTime.o ftsTool.o ftsFlash.o ftsGesture.o + diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCompensation.c b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCompensation.c new file mode 100644 index 000000000000..a4622fc5907b --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCompensation.c @@ -0,0 +1,764 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS functions for getting Initialization Data * +* * +************************************************************************** +************************************************************************** + +*/ +/*! +* \file ftsCompensation.c +* \brief Contains all the function to work with Initialization Data +*/ + +#include "ftsCompensation.h" +#include "ftsCore.h" +#include "ftsError.h" +#include "ftsFrame.h" +#include "ftsHardware.h" +#include "ftsIO.h" +#include "ftsSoftware.h" +#include "ftsTime.h" +#include "ftsTool.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** +* Request to the FW to load the specified Initialization Data +* @param type type of Initialization data to load @link load_opt Load Host Data Option @endlink +* @return OK if success or an error code which specify the type of error encountered +*/ +int requestCompensationData(u8 type) +{ + int ret = ERROR_OP_NOT_ALLOW; + int retry = 0; + + logError(0, "%s %s: Requesting compensation data... \n", tag, __func__, + retry + 1); + while (retry < RETRY_COMP_DATA_READ) { + ret = writeSysCmd(SYS_CMD_LOAD_DATA, &type, 1); + if (ret < OK) { + logError(1, "%s %s: failed at %d attemp! \n", tag, + __func__, retry + 1); + retry += 1; + } else { + logError( + 0, + "%s %s: Request Compensation data FINISHED! \n", + tag, __func__); + return OK; + } + } + + logError(1, "%s %s: Requesting compensation data... ERROR %08X \n", tag, + __func__, ret | ERROR_REQU_COMP_DATA); + return ret | ERROR_REQU_COMP_DATA; +} + +/** +* Read Initialization Data Header and check that the type loaded match with the one previously requested +* @param type type of Initialization data requested @link load_opt Load Host Data Option @endlink +* @param header pointer to DataHeader variable which will contain the header +* @param address pointer to a variable which will contain the updated address to the next data +* @return OK if success or an error code which specify the type of error encountered +*/ +int readCompensationDataHeader(u8 type, DataHeader *header, u64 *address) +{ + u64 offset = ADDR_FRAMEBUFFER; + u8 data[COMP_DATA_HEADER]; + int ret; + + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, offset, data, + COMP_DATA_HEADER, DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError(1, + "%s %s: error while reading data header ERROR %08X \n", + tag, __func__, ret); + return ret; + } + + logError(0, "%s Read Data Header done! \n", tag); + + if (data[0] != HEADER_SIGNATURE) { + logError( + 1, + "%s %s: The Header Signature was wrong! %02X != %02X ERROR %08X \n", + tag, __func__, data[0], HEADER_SIGNATURE, + ERROR_WRONG_DATA_SIGN); + return ERROR_WRONG_DATA_SIGN; + } + + if (data[1] != type) { + logError(1, "%s %s: Wrong type found! %02X!=%02X ERROR %08X\n", + tag, __func__, data[1], type, ERROR_DIFF_DATA_TYPE); + return ERROR_DIFF_DATA_TYPE; + } + + logError(0, "%s Type = %02X of Compensation data OK! \n", tag, type); + + header->type = type; + + *address = offset + COMP_DATA_HEADER; + + return OK; +} + +/** +* Read MS Global Initialization data from the buffer such as Cx1 +* @param address pointer to a variable which contain the address from where to read the data and will contain the updated address to the next data +* @param global pointer to MutualSenseData variable which will contain the MS initialization data +* @return OK if success or an error code which specify the type of error encountered +*/ +int readMutualSenseGlobalData(u64 *address, MutualSenseData *global) +{ + u8 data[COMP_DATA_GLOBAL]; + int ret; + + logError(0, "%s Address for Global data= %04X \n", tag, *address); + + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, *address, data, + COMP_DATA_GLOBAL, DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError(1, "%s %s: error while reading info data ERROR %08X\n", + tag, __func__, ret); + return ret; + } + logError(0, "%s Global data Read !\n", tag); + + global->header.force_node = data[0]; + global->header.sense_node = data[1]; + global->cx1 = data[2]; + + logError(0, "%s force_len = %d sense_len = %d CX1 = %d \n", tag, + global->header.force_node, global->header.sense_node, + global->cx1); + + *address += COMP_DATA_GLOBAL; + return OK; +} + +/** +* Read MS Initialization data for each node from the buffer +* @param address a variable which contain the address from where to read the data +* @param node pointer to MutualSenseData variable which will contain the MS initialization data +* @return OK if success or an error code which specify the type of error encountered +*/ +int readMutualSenseNodeData(u64 address, MutualSenseData *node) +{ + int ret; + int size = node->header.force_node * node->header.sense_node; + + logError(0, "%s Address for Node data = %04X \n", tag, address); + + node->node_data = (i8 *)kmalloc(size * (sizeof(i8)), GFP_KERNEL); + + if (node->node_data == NULL) { + logError(1, "%s %s: can not allocate node_data... ERROR %08X", + tag, __func__, ERROR_ALLOC); + return ERROR_ALLOC; + } + + logError(0, "%s Node Data to read %d bytes \n", tag, size); + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, address, + node->node_data, size, DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError(1, + "%s %s: error while reading node data ERROR %08X \n", + tag, __func__, ret); + kfree(node->node_data); + node->node_data = NULL; + return ret; + } + node->node_data_size = size; + + logError(0, "%s Read node data OK! \n", tag); + + return size; +} + +/** +* Perform all the steps to read the necessary info for MS Initialization data from the buffer and store it in a MutualSenseData variable +* @param type type of MS Initialization data to read @link load_opt Load Host Data Option @endlink +* @param data pointer to MutualSenseData variable which will contain the MS initialization data +* @return OK if success or an error code which specify the type of error encountered +*/ +int readMutualSenseCompensationData(u8 type, MutualSenseData *data) +{ + int ret; + u64 address; + data->node_data = NULL; + + if (!(type == LOAD_CX_MS_TOUCH || type == LOAD_CX_MS_LOW_POWER || + type == LOAD_CX_MS_KEY || type == LOAD_CX_MS_FORCE)) { + logError( + 1, + "%s %s: Choose a MS type of compensation data ERROR %08X\n", + tag, __func__, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + ret = requestCompensationData(type); + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, + ERROR_REQU_COMP_DATA); + return (ret | ERROR_REQU_COMP_DATA); + } + + ret = readCompensationDataHeader(type, &(data->header), &address); + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, + ERROR_COMP_DATA_HEADER); + return (ret | ERROR_COMP_DATA_HEADER); + } + + ret = readMutualSenseGlobalData(&address, data); + if (ret < 0) { + logError(1, "%s %s: ERROR %08X \n", tag, __func__, + ERROR_COMP_DATA_GLOBAL); + return (ret | ERROR_COMP_DATA_GLOBAL); + } + + ret = readMutualSenseNodeData(address, data); + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, + ERROR_COMP_DATA_NODE); + return (ret | ERROR_COMP_DATA_NODE); + } + + return OK; +} + +/** +* Read SS Global Initialization data from the buffer such as Ix1/Cx1 for force and sense +* @param address pointer to a variable which contain the address from where to read the data and will contain the updated address to the next data +* @param global pointer to MutualSenseData variable which will contain the SS initialization data +* @return OK if success or an error code which specify the type of error encountered +*/ +int readSelfSenseGlobalData(u64 *address, SelfSenseData *global) +{ + int ret; + u8 data[COMP_DATA_GLOBAL]; + + logError(0, "%s Address for Global data= %04X \n", tag, *address); + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, *address, data, + COMP_DATA_GLOBAL, DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError(1, + "%s %s: error while reading the data... ERROR %08X \n", + tag, __func__, ret); + return ret; + } + + logError(0, "%s Global data Read !\n", tag); + + global->header.force_node = data[0]; + global->header.sense_node = data[1]; + global->f_ix1 = data[2]; + global->s_ix1 = data[3]; + global->f_cx1 = (i8)data[4]; + global->s_cx1 = (i8)data[5]; + global->f_max_n = data[6]; + global->s_max_n = data[7]; + + logError( + 0, + "%s force_len = %d sense_len = %d f_ix1 = %d s_ix1 = %d f_cx1 = %d s_cx1 = %d \n", + tag, global->header.force_node, global->header.sense_node, + global->f_ix1, global->s_ix1, global->f_cx1, global->s_cx1); + logError(0, "%s max_n = %d s_max_n = %d \n", tag, global->f_max_n, + global->s_max_n); + + *address += COMP_DATA_GLOBAL; + + return OK; +} + +/** +* Read SS Initialization data for each node of force and sense channels from the buffer +* @param address a variable which contain the address from where to read the data +* @param node pointer to SelfSenseData variable which will contain the SS initialization data +* @return OK if success or an error code which specify the type of error encountered +*/ +int readSelfSenseNodeData(u64 address, SelfSenseData *node) +{ + int size = node->header.force_node * 2 + node->header.sense_node * 2; + u8 data[size]; + int ret; + + node->ix2_fm = (u8 *)kmalloc(node->header.force_node * (sizeof(u8)), + GFP_KERNEL); + if (node->ix2_fm == NULL) { + logError( + 1, + "%s %s: can not allocate memory for ix2_fm... ERROR %08X", + tag, __func__, ERROR_ALLOC); + return ERROR_ALLOC; + } + + node->cx2_fm = (i8 *)kmalloc(node->header.force_node * (sizeof(i8)), + GFP_KERNEL); + if (node->cx2_fm == NULL) { + logError( + 1, + "%s %s: can not allocate memory for cx2_fm ... ERROR %08X", + tag, __func__, ERROR_ALLOC); + kfree(node->ix2_fm); + return ERROR_ALLOC; + } + node->ix2_sn = (u8 *)kmalloc(node->header.sense_node * (sizeof(u8)), + GFP_KERNEL); + if (node->ix2_sn == NULL) { + logError(1, + "%s %s: can not allocate memory for ix2_sn ERROR %08X", + tag, __func__, ERROR_ALLOC); + kfree(node->ix2_fm); + kfree(node->cx2_fm); + return ERROR_ALLOC; + } + node->cx2_sn = (i8 *)kmalloc(node->header.sense_node * (sizeof(i8)), + GFP_KERNEL); + if (node->cx2_sn == NULL) { + logError(1, + "%s %s: can not allocate memory for cx2_sn ERROR %08X", + tag, __func__, ERROR_ALLOC); + kfree(node->ix2_fm); + kfree(node->cx2_fm); + kfree(node->ix2_sn); + return ERROR_ALLOC; + } + + logError(0, "%s Address for Node data = %02X \n", tag, address); + + logError(0, "%s Node Data to read %d bytes \n", tag, size); + + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, address, data, + size, DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError(1, "%s %s: error while reading data... ERROR %08X\n", + tag, ret); + kfree(node->ix2_fm); + kfree(node->cx2_fm); + kfree(node->ix2_sn); + kfree(node->cx2_sn); + return ret; + } + + logError(0, "%s Read node data ok! \n", tag); + + memcpy(node->ix2_fm, data, node->header.force_node); + memcpy(node->ix2_sn, &data[node->header.force_node], + node->header.sense_node); + memcpy(node->cx2_fm, + &data[node->header.force_node + node->header.sense_node], + node->header.force_node); + memcpy(node->cx2_sn, + &data[node->header.force_node * 2 + node->header.sense_node], + node->header.sense_node); + + return OK; +} + +/** +* Perform all the steps to read the necessary info for SS Initialization data from the buffer and store it in a SelfSenseData variable +* @param type type of SS Initialization data to read @link load_opt Load Host Data Option @endlink +* @param data pointer to SelfSenseData variable which will contain the SS initialization data +* @return OK if success or an error code which specify the type of error encountered +*/ +int readSelfSenseCompensationData(u8 type, SelfSenseData *data) +{ + int ret; + u64 address; + + data->ix2_fm = NULL; + data->cx2_fm = NULL; + data->ix2_sn = NULL; + data->cx2_sn = NULL; + + if (!(type == LOAD_CX_SS_TOUCH || type == LOAD_CX_SS_TOUCH_IDLE || + type == LOAD_CX_SS_KEY || type == LOAD_CX_SS_FORCE)) { + logError( + 1, + "%s %s: Choose a SS type of compensation data ERROR %08X\n", + tag, __func__, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + ret = requestCompensationData(type); + if (ret < 0) { + logError(1, + "%s %s: error while requesting data... ERROR %08X\n", + tag, __func__, ERROR_REQU_COMP_DATA); + return (ret | ERROR_REQU_COMP_DATA); + } + + ret = readCompensationDataHeader(type, &(data->header), &address); + if (ret < 0) { + logError( + 1, + "%s %s: error while reading data header... ERROR %08X\n", + tag, __func__, ERROR_COMP_DATA_HEADER); + return (ret | ERROR_COMP_DATA_HEADER); + } + + ret = readSelfSenseGlobalData(&address, data); + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, + ERROR_COMP_DATA_GLOBAL); + return (ret | ERROR_COMP_DATA_GLOBAL); + } + + ret = readSelfSenseNodeData(address, data); + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, + ERROR_COMP_DATA_NODE); + return (ret | ERROR_COMP_DATA_NODE); + } + + return OK; +} + +/** +* Read TOT MS Global Initialization data from the buffer such as number of force and sense channels +* @param address pointer to a variable which contain the address from where to read the data and will contain the updated address to the next data +* @param global pointer to a variable which will contain the TOT MS initialization data +* @return OK if success or an error code which specify the type of error encountered +*/ +int readTotMutualSenseGlobalData(u64 *address, TotMutualSenseData *global) +{ + int ret; + u8 data[COMP_DATA_GLOBAL]; + + logError(0, "%s Address for Global data= %04X \n", tag, *address); + + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, *address, data, + COMP_DATA_GLOBAL, DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError(1, "%s %s: error while reading info data ERROR %08X\n", + tag, __func__, ret); + return ret; + } + logError(0, "%s Global data Read !\n", tag); + + global->header.force_node = data[0]; + global->header.sense_node = data[1]; + + logError(0, "%s force_len = %d sense_len = %d \n", tag, + global->header.force_node, global->header.sense_node); + + *address += COMP_DATA_GLOBAL; + return OK; +} + +/** +* Read TOT MS Initialization data for each node from the buffer +* @param address a variable which contain the address from where to read the data +* @param node pointer to MutualSenseData variable which will contain the TOT MS initialization data +* @return OK if success or an error code which specify the type of error encountered +*/ +int readTotMutualSenseNodeData(u64 address, TotMutualSenseData *node) +{ + int ret, i; + int size = node->header.force_node * node->header.sense_node; + int toRead = size * sizeof(u16); + u8 data[toRead]; + + logError(0, "%s Address for Node data = %04X \n", tag, address); + + node->node_data = (short *)kmalloc(size * (sizeof(short)), GFP_KERNEL); + + if (node->node_data == NULL) { + logError(1, "%s %s: can not allocate node_data... ERROR %08X", + tag, __func__, ERROR_ALLOC); + return ERROR_ALLOC; + } + + logError(0, "%s Node Data to read %d bytes \n", tag, size); + + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, address, data, + toRead, DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError(1, + "%s %s: error while reading node data ERROR %08X \n", + tag, __func__, ret); + kfree(node->node_data); + node->node_data = NULL; + return ret; + } + node->node_data_size = size; + + for (i = 0; i < size; i++) { + node->node_data[i] = ((short)data[i * 2 + 1]) << 8 | + data[i * 2]; + } + + logError(0, "%s Read node data OK! \n", tag); + + return size; +} + +/** +* Perform all the steps to read the necessary info for TOT MS Initialization data from the buffer and store it in a TotMutualSenseData variable +* @param type type of TOT MS Initialization data to read @link load_opt Load Host Data Option @endlink +* @param data pointer to a variable which will contain the TOT MS initialization data +* @return OK if success or an error code which specify the type of error encountered +*/ +int readTotMutualSenseCompensationData(u8 type, TotMutualSenseData *data) +{ + int ret; + u64 address; + data->node_data = NULL; + + if (!(type == LOAD_PANEL_CX_TOT_MS_TOUCH || + type == LOAD_PANEL_CX_TOT_MS_LOW_POWER || + type == LOAD_PANEL_CX_TOT_MS_KEY || + type == LOAD_PANEL_CX_TOT_MS_FORCE)) { + logError( + 1, + "%s %s: Choose a TOT MS type of compensation data ERROR %08X\n", + tag, __func__, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + ret = requestCompensationData(type); + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, + ERROR_REQU_COMP_DATA); + return (ret | ERROR_REQU_COMP_DATA); + } + + ret = readCompensationDataHeader(type, &(data->header), &address); + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, + ERROR_COMP_DATA_HEADER); + return (ret | ERROR_COMP_DATA_HEADER); + } + + ret = readTotMutualSenseGlobalData(&address, data); + if (ret < 0) { + logError(1, "%s %s: ERROR %08X \n", tag, __func__, + ERROR_COMP_DATA_GLOBAL); + return (ret | ERROR_COMP_DATA_GLOBAL); + } + + ret = readTotMutualSenseNodeData(address, data); + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, + ERROR_COMP_DATA_NODE); + return (ret | ERROR_COMP_DATA_NODE); + } + + return OK; +} + +/** +* Read TOT SS Global Initialization data from the buffer such as number of force and sense channels +* @param address pointer to a variable which contain the address from where to read the data and will contain the updated address to the next data +* @param global pointer to a variable which will contain the TOT SS initialization data +* @return OK if success or an error code which specify the type of error encountered +*/ +int readTotSelfSenseGlobalData(u64 *address, TotSelfSenseData *global) +{ + int ret; + u8 data[COMP_DATA_GLOBAL]; + + logError(0, "%s Address for Global data= %04X \n", tag, *address); + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, *address, data, + COMP_DATA_GLOBAL, DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError(1, + "%s %s: error while reading the data... ERROR %08X \n", + tag, __func__, ret); + return ret; + } + + logError(0, "%s Global data Read !\n", tag); + + global->header.force_node = data[0]; + global->header.sense_node = data[1]; + + logError(0, "%s force_len = %d sense_len = %d \n", tag, + global->header.force_node, global->header.sense_node); + + *address += COMP_DATA_GLOBAL; + + return OK; +} + +/** +* Read TOT SS Global Initialization data from the buffer such as number of force and sense channels +* @param address pointer to a variable which contain the address from where to read the data and will contain the updated address to the next data +* @param node pointer to a variable which will contain the TOT SS initialization data +* @return OK if success or an error code which specify the type of error encountered +*/ +int readTotSelfSenseNodeData(u64 address, TotSelfSenseData *node) +{ + int size = node->header.force_node * 2 + node->header.sense_node * 2; + int toRead = size * 2; + u8 data[toRead]; + int ret, i, j = 0; + + node->ix_fm = (u16 *)kmalloc(node->header.force_node * (sizeof(u16)), + GFP_KERNEL); + if (node->ix_fm == NULL) { + logError( + 1, + "%s %s: can not allocate memory for ix2_fm... ERROR %08X", + tag, __func__, ERROR_ALLOC); + return ERROR_ALLOC; + } + + node->cx_fm = (short *)kmalloc( + node->header.force_node * (sizeof(short)), GFP_KERNEL); + if (node->cx_fm == NULL) { + logError( + 1, + "%s %s: can not allocate memory for cx2_fm ... ERROR %08X", + tag, __func__, ERROR_ALLOC); + kfree(node->ix_fm); + return ERROR_ALLOC; + } + node->ix_sn = (u16 *)kmalloc(node->header.sense_node * (sizeof(u16)), + GFP_KERNEL); + if (node->ix_sn == NULL) { + logError(1, + "%s %s: can not allocate memory for ix2_sn ERROR %08X", + tag, __func__, ERROR_ALLOC); + kfree(node->ix_fm); + kfree(node->cx_fm); + return ERROR_ALLOC; + } + node->cx_sn = (short *)kmalloc( + node->header.sense_node * (sizeof(short)), GFP_KERNEL); + if (node->cx_sn == NULL) { + logError(1, + "%s %s: can not allocate memory for cx2_sn ERROR %08X", + tag, __func__, ERROR_ALLOC); + kfree(node->ix_fm); + kfree(node->cx_fm); + kfree(node->ix_sn); + return ERROR_ALLOC; + } + + logError(0, "%s Address for Node data = %02X \n", tag, address); + + logError(0, "%s Node Data to read %d bytes \n", tag, size); + + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, address, data, + toRead, DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError(1, "%s %s: error while reading data... ERROR %08X\n", + tag, ret); + kfree(node->ix_fm); + kfree(node->cx_fm); + kfree(node->ix_sn); + kfree(node->cx_sn); + return ret; + } + + logError(0, "%s Read node data ok! \n", tag); + + j = 0; + for (i = 0; i < node->header.force_node; i++) { + node->ix_fm[i] = ((u16)data[j + 1]) << 8 | data[j]; + j += 2; + } + + for (i = 0; i < node->header.sense_node; i++) { + node->ix_sn[i] = ((u16)data[j + 1]) << 8 | data[j]; + j += 2; + } + + for (i = 0; i < node->header.force_node; i++) { + node->cx_fm[i] = ((short)data[j + 1]) << 8 | data[j]; + j += 2; + } + + for (i = 0; i < node->header.sense_node; i++) { + node->cx_sn[i] = ((short)data[j + 1]) << 8 | data[j]; + j += 2; + } + + if (j != toRead) { + logError(1, "%s %s: parsed a wrong number of bytes %d!=%d \n", + tag, __func__, j, toRead); + } + + return OK; +} + +/** +* Perform all the steps to read the necessary info for TOT SS Initialization data from the buffer and store it in a TotSelfSenseData variable +* @param type type of TOT MS Initialization data to read @link load_opt Load Host Data Option @endlink +* @param data pointer to a variable which will contain the TOT MS initialization data +* @return OK if success or an error code which specify the type of error encountered +*/ +int readTotSelfSenseCompensationData(u8 type, TotSelfSenseData *data) +{ + int ret; + u64 address; + + data->ix_fm = NULL; + data->cx_fm = NULL; + data->ix_sn = NULL; + data->cx_sn = NULL; + + if (!(type == LOAD_PANEL_CX_TOT_SS_TOUCH || + type == LOAD_PANEL_CX_TOT_SS_TOUCH_IDLE || + type == LOAD_PANEL_CX_TOT_SS_KEY || + type == LOAD_PANEL_CX_TOT_SS_FORCE || + type == STAPI_HOST_DATA_ID_PANEL_CX_SS_HVR)) { + logError( + 1, + "%s %s: Choose a TOT SS type of compensation data ERROR %08X\n", + tag, __func__, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + ret = requestCompensationData(type); + if (ret < 0) { + logError(1, + "%s %s: error while requesting data... ERROR %08X\n", + tag, __func__, ERROR_REQU_COMP_DATA); + return (ret | ERROR_REQU_COMP_DATA); + } + + ret = readCompensationDataHeader(type, &(data->header), &address); + if (ret < 0) { + logError( + 1, + "%s %s: error while reading data header... ERROR %08X\n", + tag, __func__, ERROR_COMP_DATA_HEADER); + return (ret | ERROR_COMP_DATA_HEADER); + } + + ret = readTotSelfSenseGlobalData(&address, data); + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, + ERROR_COMP_DATA_GLOBAL); + return (ret | ERROR_COMP_DATA_GLOBAL); + } + + ret = readTotSelfSenseNodeData(address, data); + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, + ERROR_COMP_DATA_NODE); + return (ret | ERROR_COMP_DATA_NODE); + } + + return OK; +} diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCompensation.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCompensation.h new file mode 100644 index 000000000000..83276fbde63a --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCompensation.h @@ -0,0 +1,110 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS functions for getting Initialization Data * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsCompensation.h +* \brief Contains all the definitions and structs to work with Initialization Data +*/ + +#ifndef FTS_COMPENSATION_H +#define FTS_COMPENSATION_H + +#include "ftsCore.h" +#include "ftsSoftware.h" + +#define RETRY_COMP_DATA_READ 2 + +/*Bytes dimension of Compensation Data Format*/ + +#define COMP_DATA_HEADER DATA_HEADER +#define COMP_DATA_GLOBAL (16 - COMP_DATA_HEADER) + +#define HEADER_SIGNATURE 0xA5 + +/** +* Struct which contains the general info about Frames and Initialization Data +*/ +typedef struct { + int force_node; /*Number of Force Channels in the frame/Initialization data*/ + int sense_node; /*Number of Sense Channels in the frame/Initialization data*/ + int type; /*Type of frame/Initialization data*/ +} DataHeader; + +/** +* Struct which contains the MS Initialization data +*/ +typedef struct { + DataHeader header; /*Header*/ + i8 cx1; /*Cx1 value (can be negative))*/ + i8 *node_data; /*Pointer to an array of bytes which contains the CX2 data (can be negative)*/ + int node_data_size; /*size of the data*/ +} MutualSenseData; + +/** +* Struct which contains the SS Initialization data +*/ +typedef struct { + DataHeader header; /*Header*/ + u8 f_ix1; /*IX1 Force*/ + u8 s_ix1; /*IX1 Sense*/ + i8 f_cx1; /*CX1 Force (can be negative)*/ + i8 s_cx1; /*< CX1 Sense (can be negative)*/ + u8 f_max_n; /*Force MaxN*/ + u8 s_max_n; /*Sense MaxN*/ + + u8 *ix2_fm; /*pointer to an array of bytes which contains Force Ix2 data node*/ + u8 *ix2_sn; /*pointer to an array of bytes which contains Sense Ix2 data node*/ + i8 *cx2_fm; /*pointer to an array of bytes which contains Force Cx2 data node (can be negative)*/ + i8 *cx2_sn; /*pointer to an array of bytes which contains Sense Cx2 data node (can be negative))*/ + +} SelfSenseData; + +/** +* Struct which contains the TOT MS Initialization data +*/ +typedef struct { + DataHeader header; /*Header*/ + short *node_data; /*pointer to an array of ushort which contains TOT MS Initialization data*/ + int node_data_size; /*size of data*/ +} TotMutualSenseData; + +/** +* Struct which contains the TOT SS Initialization data +*/ +typedef struct { + DataHeader header; /*Header*/ + + u16 *ix_fm; /*pointer to an array of ushort which contains TOT SS IX Force data*/ + u16 *ix_sn; /*pointer to an array of ushort which contains TOT SS IX Sense data*/ + short *cx_fm; /*pointer to an array of ushort which contains TOT SS CX Force data (can be negative)*/ + short *cx_sn; /*pointer to an array of ushort which contains TOT SS CX Sense data (can be negative)*/ + +} TotSelfSenseData; + +int requestCompensationData(u8 type); +int readCompensationDataHeader(u8 type, DataHeader *header, u64 *address); +int readMutualSenseGlobalData(u64 *address, MutualSenseData *global); +int readMutualSenseNodeData(u64 address, MutualSenseData *node); +int readMutualSenseCompensationData(u8 type, MutualSenseData *data); +int readSelfSenseGlobalData(u64 *address, SelfSenseData *global); +int readSelfSenseNodeData(u64 address, SelfSenseData *node); +int readSelfSenseCompensationData(u8 type, SelfSenseData *data); +int readToTMutualSenseGlobalData(u64 *address, TotMutualSenseData *global); +int readToTMutualSenseNodeData(u64 address, TotMutualSenseData *node); +int readTotMutualSenseCompensationData(u8 type, TotMutualSenseData *data); +int readTotSelfSenseGlobalData(u64 *address, TotSelfSenseData *global); +int readTotSelfSenseNodeData(u64 address, TotSelfSenseData *node); +int readTotSelfSenseCompensationData(u8 type, TotSelfSenseData *data); +#endif diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCore.c b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCore.c new file mode 100644 index 000000000000..c035aec07dc3 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCore.c @@ -0,0 +1,1377 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS Core functions * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsCore.c +* \brief Contains the implementation of the Core functions +*/ + +#include +#include +#include +#include +#include +#include "ftsCompensation.h" +#include "ftsCore.h" +#include "ftsError.h" +#include "ftsIO.h" +#include "ftsTest.h" +#include "ftsTime.h" +#include "ftsTool.h" + +extern struct fts_ts_info *fts_info; +/** @addtogroup system_info +* @{ +*/ +SysInfo systemInfo; /*Global System Info variable, accessible in all the driver*/ +/** @}*/ + +static int reset_gpio = + GPIO_NOT_DEFINED; /*gpio number of the rest pin, the value is GPIO_NOT_DEFINED if the reset pin is not connected*/ +static int + system_reseted_up; /*flag checked during resume to understand if there was a system reset and restore the proper state*/ +static int + system_reseted_down; /*flag checked during suspend to understand if there was a system reset and restore the proper state*/ +static int + disable_irq_count; /*count the number of call to disable_irq, start with 1 because at the boot IRQ are already disabled*/ +spinlock_t fts_int; /*spinlock to controll the access to the disable_irq_counter*/ + +/** +* Initialize core variables of the library. Must be called during the probe before any other lib function +* @param info pointer to fts_ts_info which contains info about the device and its hw setup +* @return OK if success or an error code which specify the type of error encountered +*/ +int initCore(struct fts_ts_info *info) +{ + int ret = OK; + logError(0, "%s %s: Initialization of the Core... \n", tag, __func__); + ret |= openChannel(info->client); + ret |= resetErrorList(); + ret |= initTestToDo(); + setResetGpio(info->board->reset_gpio); + if (ret < OK) { + logError(0, "%s %s: Initialization Core ERROR %08X! \n", tag, + __func__, ret); + } else { + logError(0, "%s %s: Initialization Finished! \n", tag, + __func__); + } + return ret; +} + +/** +* Set the reset_gpio variable with the actual gpio number of the board link to the reset pin +* @param gpio gpio number link to the reset pin of the IC +*/ +void setResetGpio(int gpio) +{ + reset_gpio = gpio; + logError(0, "%s setResetGpio: reset_gpio = %d\n", tag, reset_gpio); +} + +/** +* Perform a system reset of the IC. +* If the reset pin is associated to a gpio, the function execute an hw reset (toggling of reset pin) otherwise send an hw command to the IC +* @return OK if success or an error code which specify the type of error encountered +*/ +int fts_system_reset(void) +{ + u8 readData[FIFO_EVENT_SIZE]; + int event_to_search; + int res = -1; + int i; + u8 data[1] = { SYSTEM_RESET_VALUE }; + event_to_search = (int)EVT_ID_CONTROLLER_READY; + + logError(1, "%s System resetting...\n", tag); + if (fts_info) { + reinit_completion(&fts_info->tp_reset_completion); + atomic_set(&fts_info->system_is_resetting, 1); + } + for (i = 0; i < RETRY_SYSTEM_RESET && res < 0; i++) { + resetErrorList(); + fts_disableInterruptNoSync(); + + if (reset_gpio == GPIO_NOT_DEFINED) { + res = fts_writeU8UX(FTS_CMD_HW_REG_W, ADDR_SIZE_HW_REG, + ADDR_SYSTEM_RESET, data, + ARRAY_SIZE(data)); + } else { + gpio_set_value(reset_gpio, 0); + mdelay(10); + gpio_set_value(reset_gpio, 1); + res = OK; + } + if (res < OK) { + logError(1, "%s fts_system_reset: ERROR %08X\n", tag, + ERROR_BUS_W); + } else { + res = pollForEvent(&event_to_search, 1, readData, + GENERAL_TIMEOUT); + if (res < OK) { + logError(1, "%s fts_system_reset: ERROR %08X\n", + tag, res); + } + } + } + if (fts_info) { + complete(&fts_info->tp_reset_completion); + atomic_set(&fts_info->system_is_resetting, 0); + } + if (res < OK) { + logError( + 1, + "%s fts_system_reset...failed after 3 attempts: ERROR %08X\n", + tag, (res | ERROR_SYSTEM_RESET_FAIL)); + return (res | ERROR_SYSTEM_RESET_FAIL); + } else { + logError(1, "%s System reset DONE!\n", tag); + system_reseted_down = 1; + system_reseted_up = 1; + return OK; + } +} + +/** +* Return the value of system_resetted_down. +* @return the flag value: 0 if not set, 1 if set +*/ +int isSystemResettedDown(void) +{ + return system_reseted_down; +} + +/** +* Return the value of system_resetted_up. +* @return the flag value: 0 if not set, 1 if set +*/ +int isSystemResettedUp(void) +{ + return system_reseted_up; +} + +/** +* Set the value of system_reseted_down flag +* @param val value to write in the flag +*/ +void setSystemResetedDown(int val) +{ + system_reseted_down = val; +} + +/** +* Set the value of system_reseted_up flag +* @param val value to write in the flag +*/ +void setSystemResetedUp(int val) +{ + system_reseted_up = val; +} + +/** @addtogroup events_group + * @{ + */ + +/** +* Poll the FIFO looking for a specified event within a timeout. Support a retry mechanism. +* @param event_to_search pointer to an array of int where each element correspond to a byte of the event to find. If the element of the array has value -1, the byte of the event, in the same position of the element is ignored. +* @param event_bytes size of event_to_search +* @param readData pointer to an array of byte which will contain the event found +* @param time_to_wait time to wait before going in timeout +* @return OK if success or an error code which specify the type of error encountered +*/ +int pollForEvent(int *event_to_search, int event_bytes, u8 *readData, + int time_to_wait) +{ + int i, find, retry, count_err; + int time_to_count; + int err_handling = OK; + StopWatch clock; + + u8 cmd[1] = { FIFO_CMD_READONE }; + char temp[128] = { 0 }; + + find = 0; + retry = 0; + count_err = 0; + time_to_count = time_to_wait / TIMEOUT_RESOLUTION; + + startStopWatch(&clock); + while (find != 1 && retry < time_to_count && + fts_writeReadU8UX(cmd[0], 0, 0, readData, FIFO_EVENT_SIZE, + DUMMY_FIFO) >= OK) { + if (readData[0] == EVT_ID_ERROR) { + logError(1, "%s %s\n", tag, + printHex("ERROR EVENT = ", readData, + FIFO_EVENT_SIZE, temp)); + memset(temp, 0, 128); + count_err++; + err_handling = errorHandler(readData, FIFO_EVENT_SIZE); + if ((err_handling & 0xF0FF0000) == + ERROR_HANDLER_STOP_PROC) { + logError( + 0, + "%s pollForEvent: forced to be stopped! ERROR %08X\n", + tag, err_handling); + return err_handling; + } + } else { + if (readData[0] != EVT_ID_NOEVENT) { + logError(0, "%s %s\n", tag, + printHex("READ EVENT = ", readData, + FIFO_EVENT_SIZE, temp)); + memset(temp, 0, 128); + } + if (readData[0] == EVT_ID_CONTROLLER_READY && + event_to_search[0] != EVT_ID_CONTROLLER_READY) { + logError( + 0, + "%s pollForEvent: Unmanned Controller Ready Event! Setting reset flags...\n", + tag); + setSystemResetedUp(1); + setSystemResetedDown(1); + } + } + + find = 1; + + for (i = 0; i < event_bytes; i++) { + if (event_to_search[i] != -1 && + (int)readData[i] != event_to_search[i]) { + find = 0; + break; + } + } + + retry++; + mdelay(TIMEOUT_RESOLUTION); + } + stopStopWatch(&clock); + if ((retry >= time_to_count) && find != 1) { + logError(1, "%s pollForEvent: ERROR %02X \n", tag, + ERROR_TIMEOUT); + return ERROR_TIMEOUT; + } else if (find == 1) { + logError(0, "%s %s\n", tag, + printHex("FOUND EVENT = ", readData, FIFO_EVENT_SIZE, + temp)); + memset(temp, 0, 128); + logError( + 0, + "%s Event found in %d ms (%d iterations)! Number of errors found = %d \n", + tag, elapsedMillisecond(&clock), retry, count_err); + return count_err; + } else { + logError(1, "%s pollForEvent: ERROR %08X \n", tag, ERROR_BUS_R); + return ERROR_BUS_R; + } +} + +/** @}*/ + +/** +* Check that the FW sent the echo even after a command was sent +* @param cmd pointer to an array of byte which contain the command previously sent +* @param size size of cmd +* @return OK if success or an error code which specify the type of error encountered +*/ +int checkEcho(u8 *cmd, int size) +{ + int ret, i; + int event_to_search[FIFO_EVENT_SIZE]; + u8 readData[FIFO_EVENT_SIZE]; + + if (size < 1) { + logError(1, "%s checkEcho: Error Size = %d not valid! \n", tag, + size, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } else { + if ((size + 3) > FIFO_EVENT_SIZE) + size = FIFO_EVENT_SIZE - 3; + + event_to_search[0] = EVT_ID_STATUS_UPDATE; + event_to_search[1] = EVT_TYPE_STATUS_ECHO; + for (i = 2; i < size + 2; i++) { + event_to_search[i] = cmd[i - 2]; + } + ret = pollForEvent(event_to_search, size + 2, readData, + TIMEOUT_ECHO); + if (ret < OK) { + logError( + 1, + "%s checkEcho: Echo Event not found! ERROR %08X\n", + tag, ret); + return (ret | ERROR_CHECK_ECHO_FAIL); + } else if (ret > OK) { + logError( + 1, + "%s checkEcho: Echo Event found but with some error events before! num_error = %d \n", + tag, ret); + return ERROR_CHECK_ECHO_FAIL; + } + + logError(0, "%s ECHO OK!\n", tag); + return ret; + } +} + +/** @addtogroup scan_mode +* @{ +*/ +/** +* Set a scan mode in the IC +* @param mode scan mode to set; possible values @link scan_opt Scan Mode Option @endlink +* @param settings option for the selected scan mode (for example @link active_bitmask Active Mode Bitmask @endlink) +* @return OK if success or an error code which specify the type of error encountered +*/ +int setScanMode(u8 mode, u8 settings) +{ + u8 cmd[3] = { FTS_CMD_SCAN_MODE, mode, settings }; + int ret, size = 3; + + logError(0, "%s %s: Setting scan mode: mode = %02X settings = %02X !\n", + tag, __func__, mode, settings); + if (mode == SCAN_MODE_LOW_POWER) + size = 2; + ret = fts_write_dma_safe(cmd, size); + if (ret < OK) { + logError(1, "%s %s: write failed...ERROR %08X !\n", tag, + __func__, ret); + return ret | ERROR_SET_SCAN_MODE_FAIL; + } + logError(0, "%s %s: Setting scan mode OK!\n", tag, __func__); + return OK; +} + +/** @}*/ + +/** @addtogroup feat_sel +* @{ +*/ +/** +* Set a feature and its option in the IC +* @param feat feature to set; possible values @link feat_opt Feature Selection Option @endlink +* @param settings pointer to an array of byte which store the options for the selected feature (for example the gesture mask to activate @link gesture_opt Gesture IDs @endlink) +* @param size in bytes of settings +* @return OK if success or an error code which specify the type of error encountered +*/ +int setFeatures(u8 feat, u8 *settings, int size) +{ + u8 cmd[2 + size]; + int i = 0; + int ret; + logError(0, "%s %s: Setting feature: feat = %02X !\n", tag, __func__, + feat); + cmd[0] = FTS_CMD_FEATURE; + cmd[1] = feat; + logError(0, "%s %s: Settings = ", tag, __func__); + for (i = 0; i < size; i++) { + cmd[2 + i] = settings[i]; + logError(0, "%02X ", settings[i]); + } + logError(0, "\n"); + ret = fts_write_dma_safe(cmd, 2 + size); + if (ret < OK) { + logError(1, "%s %s: write failed...ERROR %08X !\n", tag, + __func__, ret); + return ret | ERROR_SET_FEATURE_FAIL; + } + logError(0, "%s %s: Setting feature OK!\n", tag, __func__); + return OK; +} + +/** @}*/ + +/** @addtogroup sys_cmd +* @{ +*/ +/** +* Write a system command to the IC +* @param sys_cmd System Command to execute; possible values @link sys_opt System Command Option @endlink +* @param sett settings option for the selected system command (@link sys_special_opt Special Command Option @endlink, @link ito_opt ITO Test Option @endlink, @link load_opt Load Host Data Option @endlink) +* @param size in bytes of settings +* @return OK if success or an error code which specify the type of error encountered +*/ +int writeSysCmd(u8 sys_cmd, u8 *sett, int size) +{ + u8 *cmd = NULL; + int ret; + + cmd = (u8 *)kzalloc(sizeof(u8) * size + 2, GFP_KERNEL); + if (!cmd) { + ret = ERROR_ALLOC; + goto end; + } + + cmd[0] = FTS_CMD_SYSTEM; + cmd[1] = sys_cmd; + + logError(0, "%s %s: Command = %02X %02X ", tag, __func__, cmd[0], + cmd[1]); + for (ret = 0; ret < size; ret++) { + cmd[2 + ret] = sett[ret]; + logError(0, "%02X ", cmd[2 + ret]); + } + logError(0, "\n%s %s: Writing Sys command...\n", tag, __func__); + if (sys_cmd != SYS_CMD_LOAD_DATA) { + ret = fts_writeFwCmd(cmd, 2 + size); + } else { + if (size >= 1) { + ret = requestSyncFrame(sett[0]); + } else { + logError(1, "%s %s: No setting argument! ERROR %08X\n", + tag, __func__, ERROR_OP_NOT_ALLOW); + ret = ERROR_OP_NOT_ALLOW; + goto end; + } + } + if (ret < OK) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, ret); + } else + logError(0, "%s %s: FINISHED! \n", tag, __func__); + +end: + if (cmd) + kfree(cmd); + return ret; +} + +/** @}*/ + +/** @addtogroup system_info +* @{ +*/ +/** +* Initialize the System Info Struct with default values according to the error found during the reading +* @param i2cError 1 if there was an I2C error while reading the System Info data from memory, other value if another error occurred +* @return OK if success or an error code which specify the type of error encountered +*/ +int defaultSysInfo(int i2cError) +{ + int i; + logError(0, "%s Setting default System Info... \n", tag); + + if (i2cError == 1) { + systemInfo.u16_fwVer = 0xFFFF; + systemInfo.u16_cfgProgectId = 0xFFFF; + for (i = 0; i < RELEASE_INFO_SIZE; i++) { + systemInfo.u8_releaseInfo[i] = 0xFF; + } + systemInfo.u16_cxVer = 0xFFFF; + } else { + systemInfo.u16_fwVer = 0x0000; + systemInfo.u16_cfgProgectId = 0x0000; + for (i = 0; i < RELEASE_INFO_SIZE; i++) { + systemInfo.u8_releaseInfo[i] = 0x00; + } + systemInfo.u16_cxVer = 0x0000; + } + + systemInfo.u8_scrRxLen = 0; + systemInfo.u8_scrTxLen = 0; + + logError(0, "%s default System Info DONE! \n", tag); + return OK; +} + +/** +* Read the System Info data from memory. System Info is loaded automatically after every system reset. +* @param request if 1, will be asked to the FW to reload the data, otherwise attempt to read it directly from memory +* @return OK if success or an error code which specify the type of error encountered +*/ +int readSysInfo(int request) +{ + int ret, i, index = 0; + u8 sett = LOAD_SYS_INFO; + u8 data[SYS_INFO_SIZE] = { 0 }; + char temp[256] = { 0 }; + + if (request == 1) { + logError(0, "%s %s: Requesting System Info...\n", tag, + __func__); + + ret = writeSysCmd(SYS_CMD_LOAD_DATA, &sett, 1); + if (ret < OK) { + logError( + 1, + "%s %s: error while writing the sys cmd ERROR %08X\n", + tag, __func__, ret); + goto FAIL; + } + } + + logError(0, "%s %s: Reading System Info...\n", tag, __func__); + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, + ADDR_FRAMEBUFFER, data, SYS_INFO_SIZE, + DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError( + 1, + "%s %s: error while reading the system data ERROR %08X\n", + tag, __func__, ret); + goto FAIL; + } + + logError(0, "%s %s: Parsing System Info...\n", tag, __func__); + + if (data[0] != HEADER_SIGNATURE) { + logError( + 1, + "%s %s: The Header Signature is wrong! sign: %02X != %02X ERROR %08X\n", + tag, __func__, data[0], HEADER_SIGNATURE, + ERROR_WRONG_DATA_SIGN); + ret = ERROR_WRONG_DATA_SIGN; + goto FAIL; + } + + if (data[1] != LOAD_SYS_INFO) { + logError( + 1, + "%s %s: The Data ID is wrong! ids: %02X != %02X ERROR %08X \n", + tag, __func__, data[3], LOAD_SYS_INFO, + ERROR_DIFF_DATA_TYPE); + ret = ERROR_DIFF_DATA_TYPE; + goto FAIL; + } + + index += 4; + u8ToU16(&data[index], &systemInfo.u16_apiVer_rev); + index += 2; + systemInfo.u8_apiVer_minor = data[index++]; + systemInfo.u8_apiVer_major = data[index++]; + u8ToU16(&data[index], &systemInfo.u16_chip0Ver); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_chip0Id); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_chip1Ver); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_chip1Id); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_fwVer); + index += 2; + logError(1, "%s FW VER = %04X \n", tag, systemInfo.u16_fwVer); + + u8ToU16(&data[index], &systemInfo.u16_svnRev); + index += 2; + logError(1, "%s SVN REV = %04X \n", tag, systemInfo.u16_svnRev); + u8ToU16(&data[index], &systemInfo.u16_cfgVer); + index += 2; + logError(1, "%s CONFIG VER = %04X \n", tag, systemInfo.u16_cfgVer); + u8ToU16(&data[index], &systemInfo.u16_cfgProgectId); + index += 2; + logError(1, "%s CONFIG PROJECT ID = %04X \n", tag, + systemInfo.u16_cfgProgectId); + u8ToU16(&data[index], &systemInfo.u16_cxVer); + index += 2; + logError(1, "%s CX VER = %04X \n", tag, systemInfo.u16_cxVer); + u8ToU16(&data[index], &systemInfo.u16_cxProjectId); + index += 2; + logError(1, "%s CX PROJECT ID = %04X \n", tag, + systemInfo.u16_cxProjectId); + systemInfo.u8_cfgAfeVer = data[index++]; + systemInfo.u8_cxAfeVer = data[index++]; + systemInfo.u8_panelCfgAfeVer = data[index++]; + logError(1, "%s AFE VER: CFG = %02X - CX = %02X - PANEL = %02X \n", tag, + systemInfo.u8_cfgAfeVer, systemInfo.u8_cxAfeVer, + systemInfo.u8_panelCfgAfeVer); + systemInfo.u8_protocol = data[index++]; + logError(0, "%s Protocol = %02X \n", tag, systemInfo.u8_protocol); + + for (i = 0; i < DIE_INFO_SIZE; i++) { + systemInfo.u8_dieInfo[i] = data[index++]; + } + logError(0, "%s %s \n", tag, + printHex("Die Info = ", systemInfo.u8_dieInfo, DIE_INFO_SIZE, + temp)); + memset(temp, 0, 256); + + for (i = 0; i < RELEASE_INFO_SIZE; i++) { + systemInfo.u8_releaseInfo[i] = data[index++]; + } + + logError(1, "%s %s \n", tag, + printHex("Release Info = ", systemInfo.u8_releaseInfo, + RELEASE_INFO_SIZE, temp)); + memset(temp, 0, 256); + + u8ToU32(&data[index], &systemInfo.u32_fwCrc); + index += 4; + u8ToU32(&data[index], &systemInfo.u32_cfgCrc); + + index += 4; + + index += 8; + + u8ToU16(&data[index], &systemInfo.u16_scrResX); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_scrResY); + index += 2; + logError(0, "%s Screen Resolution = %d x %d \n", tag, + systemInfo.u16_scrResX, systemInfo.u16_scrResY); + systemInfo.u8_scrTxLen = data[index++]; + logError(0, "%s TX Len = %d \n", tag, systemInfo.u8_scrTxLen); + systemInfo.u8_scrRxLen = data[index++]; + logError(0, "%s RX Len = %d \n", tag, systemInfo.u8_scrRxLen); + systemInfo.u8_keyLen = data[index++]; + logError(0, "%s Key Len = %d \n", tag, systemInfo.u8_keyLen); + systemInfo.u8_forceLen = data[index++]; + logError(0, "%s Force Len = %d \n", tag, systemInfo.u8_forceLen); + + index += 40; + + u8ToU16(&data[index], &systemInfo.u16_dbgInfoAddr); + index += 2; + + index += 6; + + u8ToU16(&data[index], &systemInfo.u16_msTchRawAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_msTchFilterAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_msTchStrenAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_msTchBaselineAddr); + index += 2; + + u8ToU16(&data[index], &systemInfo.u16_ssTchTxRawAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssTchTxFilterAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssTchTxStrenAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssTchTxBaselineAddr); + index += 2; + + u8ToU16(&data[index], &systemInfo.u16_ssTchRxRawAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssTchRxFilterAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssTchRxStrenAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssTchRxBaselineAddr); + index += 2; + + u8ToU16(&data[index], &systemInfo.u16_keyRawAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_keyFilterAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_keyStrenAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_keyBaselineAddr); + index += 2; + + u8ToU16(&data[index], &systemInfo.u16_frcRawAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_frcFilterAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_frcStrenAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_frcBaselineAddr); + index += 2; + + u8ToU16(&data[index], &systemInfo.u16_ssHvrTxRawAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssHvrTxFilterAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssHvrTxStrenAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssHvrTxBaselineAddr); + index += 2; + + u8ToU16(&data[index], &systemInfo.u16_ssHvrRxRawAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssHvrRxFilterAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssHvrRxStrenAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssHvrRxBaselineAddr); + index += 2; + + u8ToU16(&data[index], &systemInfo.u16_ssPrxTxRawAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssPrxTxFilterAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssPrxTxStrenAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssPrxTxBaselineAddr); + index += 2; + + u8ToU16(&data[index], &systemInfo.u16_ssPrxRxRawAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssPrxRxFilterAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssPrxRxStrenAddr); + index += 2; + u8ToU16(&data[index], &systemInfo.u16_ssPrxRxBaselineAddr); + index += 2; + + logError(0, "%s Parsed %d bytes! \n", tag, index); + + if (index != SYS_INFO_SIZE) { + logError(1, "%s %s: index = %d different from %d ERROR %08X\n", + tag, __func__, index, SYS_INFO_SIZE, + ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + logError(0, "%s System Info Read DONE!\n", tag); + return OK; + +FAIL: + defaultSysInfo(isI2cError(ret)); + return ret; +} + +/** @}*/ + +/** + * Read data from the Config Memory + * @param offset Starting address in the Config Memory of data to read + * @param outBuf pointer of a byte array which contain the bytes to read + * @param len number of bytes to read + * @return OK if success or an error code which specify the type of error encountered + */ +int readConfig(u16 offset, u8 *outBuf, int len) +{ + int ret; + u64 final_address = offset + ADDR_CONFIG_OFFSET; + + logError(0, "%s %s: Starting to read config memory at %08X ...", tag, + __func__, final_address); + ret = fts_writeReadU8UX(FTS_CMD_CONFIG_R, BITS_16, final_address, + outBuf, len, DUMMY_CONFIG); + if (ret < OK) { + logError( + 1, + "%s %s: Impossible to read Config Memory... ERROR %08X!", + tag, __func__, ret); + return ret; + } + + logError(0, "%s %s: Read config memory FINISHED!", tag, __func__); + return OK; +} + +/** + * Disable the interrupt so the ISR of the driver can not be called + * @return OK if success or an error code which specify the type of error encountered + */ +int fts_disableInterrupt(void) +{ + if (getClient() != NULL) { + logError(0, "%s Number of disable = %d \n", tag, + disable_irq_count); + if (disable_irq_count == 0) { + logError(0, "%s Excecuting Disable... \n", tag); + disable_irq(getClient()->irq); + disable_irq_count++; + logError(1, "%s Interrupt Disabled!\n", tag); + } + return OK; + } else { + logError(1, "%s %s: Impossible get client irq... ERROR %08X\n", + tag, __func__, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } +} + +/** + * Disable the interrupt async so the ISR of the driver can not be called + * @return OK if success or an error code which specify the type of error encountered + */ +int fts_disableInterruptNoSync(void) +{ + if (getClient() != NULL) { + spin_lock_irq(&fts_int); + logError(0, "%s Number of disable = %d \n", tag, + disable_irq_count); + if (disable_irq_count == 0) { + logError(0, "%s Executing Disable... \n", tag); + disable_irq_nosync(getClient()->irq); + disable_irq_count++; + } + + spin_unlock_irq(&fts_int); + logError(0, "%s Interrupt No Sync Disabled!\n", tag); + return OK; + } else { + logError(1, "%s %s: Impossible get client irq... ERROR %08X\n", + tag, __func__, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } +} + +/** + * Reset the disable_irq count + * @return OK + */ +int fts_resetDisableIrqCount(void) +{ + disable_irq_count = 0; + return OK; +} + +/** + * Enable the interrupt so the ISR of the driver can be called + * @return OK if success or an error code which specify the type of error encountered + */ +int fts_enableInterrupt(void) +{ + if (getClient() != NULL) { + logError(0, "%s Number of re-enable = %d \n", tag, + disable_irq_count); + while (disable_irq_count > 0) { + logError(0, "%s Excecuting Enable... \n", tag); + enable_irq(getClient()->irq); + disable_irq_count--; + logError(1, "%s Interrupt Enabled!\n", tag); + } + return OK; + } else { + logError(1, "%s %s: Impossible get client irq... ERROR %08X\n", + tag, __func__, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } +} + +/** +* Check if there is a crc error in the IC which prevent the fw to run. +* @return OK if no CRC error, or a number >OK according the CRC error found +*/ +int fts_crc_check(void) +{ + u8 val; + u8 crc_status; + int res; + u8 error_to_search[6] = { + EVT_TYPE_ERROR_CRC_CFG_HEAD, EVT_TYPE_ERROR_CRC_CFG, + EVT_TYPE_ERROR_CRC_CX, EVT_TYPE_ERROR_CRC_CX_HEAD, + EVT_TYPE_ERROR_CRC_CX_SUB, EVT_TYPE_ERROR_CRC_CX_SUB_HEAD + }; + + res = fts_writeReadU8UX(FTS_CMD_HW_REG_R, ADDR_SIZE_HW_REG, ADDR_CRC, + &val, 1, DUMMY_HW_REG); + if (res < OK) { + logError(1, "%s %s Cannot read crc status ERROR %08X\n", tag, + __func__, res); + return res; + } + + crc_status = val & CRC_MASK; + if (crc_status != OK) { + logError(1, "%s %s CRC ERROR = %02X \n", tag, __func__, + crc_status); + return CRC_CODE; + } + + logError(1, "%s %s: Verifying if Config CRC Error...\n", tag, __func__); + res = fts_system_reset(); + if (res >= OK) { + res = pollForErrorType(error_to_search, 2); + if (res < OK) { + logError(1, "%s %s: No Config CRC Error Found! \n", tag, + __func__); + logError(1, "%s %s: Verifying if Cx CRC Error...\n", + tag, __func__); + res = pollForErrorType(&error_to_search[2], 4); + if (res < OK) { + logError(1, "%s %s: No Cx CRC Error Found! \n", + tag, __func__); + return OK; + } else { + logError( + 1, + "%s %s: Cx CRC Error found! CRC ERROR = %02X\n", + tag, __func__, res); + return CRC_CX; + } + } else { + logError( + 1, + "%s %s: Config CRC Error found! CRC ERROR = %02X\n", + tag, __func__, res); + return CRC_CONFIG; + } + } else { + logError( + 1, + "%s %s: Error while executing system reset! ERROR %08X\n", + tag, __func__, res); + return res; + } + + return OK; +} + +/** + * Request a host data and use the sync method to understand when the FW load it + * @param type the type ID of host data to load (@link load_opt Load Host Data Option @endlink) + * @return OK if success or an error code which specify the type of error encountered + */ +int requestSyncFrame(u8 type) +{ + u8 request[3] = { FTS_CMD_SYSTEM, SYS_CMD_LOAD_DATA, type }; + u8 readData[DATA_HEADER] = { 0 }; + int ret, retry = 0, retry2 = 0, time_to_count; + int count, new_count; + + logError(0, "%s %s: Starting to get a sync frame...\n", tag, __func__); + + while (retry2 < RETRY_MAX_REQU_DATA) { + logError(0, "%s %s: Reading count...\n", tag, __func__); + + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, + ADDR_FRAMEBUFFER, readData, DATA_HEADER, + DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError( + 0, + "%s %s: Error while reading count! ERROR %08X \n", + tag, __func__, ret | ERROR_REQU_DATA); + ret |= ERROR_REQU_DATA; + retry2++; + continue; + } + + if (readData[0] != HEADER_SIGNATURE) { + logError( + 1, + "%s %s: Invalid Signature while reading count! ERROR %08X \n", + tag, __func__, ret | ERROR_REQU_DATA); + ret |= ERROR_REQU_DATA; + retry2++; + continue; + } + + count = (readData[3] << 8) | readData[2]; + new_count = count; + logError(0, "%s %s: Base count = %d\n", tag, __func__, count); + + logError(0, "%s %s: Requesting frame %02X attempt = %d \n", + tag, __func__, type, retry2 + 1); + ret = fts_write_dma_safe(request, ARRAY_SIZE(request)); + if (ret >= OK) { + logError(0, "%s %s: Polling for new count... \n", tag, + __func__); + time_to_count = TIMEOUT_REQU_DATA / TIMEOUT_RESOLUTION; + while (count == new_count && retry < time_to_count) { + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, + BITS_16, + ADDR_FRAMEBUFFER, + readData, DATA_HEADER, + DUMMY_FRAMEBUFFER); + if (ret >= OK && + readData[0] == HEADER_SIGNATURE) { + new_count = ((readData[3] << 8) | + readData[2]); + } else { + logError( + 0, + "%s %s: invalid Signature or can not read count... ERROR %08X \n", + tag, __func__, ret); + } + retry++; + mdelay(TIMEOUT_RESOLUTION); + } + + if (count == new_count) { + logError( + 1, + "%s %s: New count not received! ERROR %08X \n", + tag, __func__, + ERROR_TIMEOUT | ERROR_REQU_DATA); + ret = ERROR_TIMEOUT | ERROR_REQU_DATA; + } else { + logError( + 0, + "%s %s: New count found! count = %d! Frame ready! \n", + tag, __func__, new_count); + return OK; + } + } + retry2++; + } + logError(1, "%s %s: Request Data failed! ERROR %08X \n", tag, __func__, + ret); + return ret; +} + +int calculateCRC8(u8 *u8_srcBuff, int size, u8 *crc) +{ + u8 u8_remainder; + u8 bit; + int i = 0; + u8_remainder = 0x00; + + logError(0, "%s %s: Start CRC computing...\n", tag, __func__); + if (size != 0 && u8_srcBuff != NULL) { + for (i = 0; i < size; i++) { + u8_remainder ^= u8_srcBuff[i]; + for (bit = 8; bit > 0; --bit) { + if (u8_remainder & (0x1 << 7)) { + u8_remainder = (u8_remainder << 1) ^ + 0x9B; + } else { + u8_remainder = (u8_remainder << 1); + } + } + } + *crc = u8_remainder; + logError(0, "%s %s: CRC value = %02X\n", tag, __func__, *crc); + return OK; + } else { + logError( + 1, + "%s %s: Arguments passed not valid! Data pointer = NULL or size = 0 (%d) ERROR %08X\n", + tag, __func__, size, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } +} + +int writeLockDownInfo(u8 *data, int size, u8 lock_id) +{ + int ret, i; + u8 crc_data = 0; + u8 crc_head = 0; + u8 cmd_lockdown_prepare[8] = { + LOCKDOWN_SIGNATURE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + u8 cmd_lockdown_crc[4] = { 0x00 }; + u8 lockdown_save[3] = { 0xA4, 0x00, 0x04 }; + u8 *temp = NULL; + u8 error_to_search[4] = { EVT_TYPE_ERROR_LOCKDOWN_FLASH, + EVT_TYPE_ERROR_LOCKDOWN_CRC, + EVT_TYPE_ERROR_LOCKDOWN_NO_DATA, + EVT_TYPE_ERROR_LOCKDOWN_WRITE_FULL }; + + logError(0, "%s %s:enter", tag, __func__); + if (lock_id < 0x70 || lock_id > 0x77 || size <= 0 || + size > LOCKDOWN_LENGTH - 20) { + logError(1, + "%s %s the lock id type is:%02X size:%d not support\n", + tag, __func__, lock_id, size); + return ERROR_LOCKDOWN_CODE; + } + + temp = printHex_data("Lockdown Code = ", data, size); + if (temp != NULL) { + logError(1, "%s: %s", __func__, temp); + kfree(temp); + } + + logError(0, "%s: Writing Lockdown code into the IC ...\n", __func__); + fts_disableInterrupt(); + for (i = 0; i < 3; i++) { + cmd_lockdown_prepare[1] = lock_id; + ret = calculateCRC8(data, size, &crc_data); + if (ret < OK) { + logError( + 1, + "%s %s: Unable to compute data CRC.. ERROR %08X\n", + tag, __func__, ret); + ret = (ret | ERROR_LOCKDOWN_CODE); + continue; + } + logError(0, "%s %s: Get the data CRC value:%02X\n", tag, + __func__, crc_data); + ret = fts_writeU8UX(LOCKDOWN_WRITEREAD_CMD, BITS_16, + ADDR_LOCKDOWN, cmd_lockdown_prepare, + ARRAY_SIZE(cmd_lockdown_prepare)); + if (ret < OK) { + logError( + 1, + "%s %s: Unable to write Lockdown data prepare at %d iteration.. ERROR %08X\n", + tag, __func__, i, ret); + ret = (ret | ERROR_LOCKDOWN_CODE); + continue; + } + logError(0, "%s %s: Compute 8bit header CRC...\n", tag, + __func__); + + cmd_lockdown_crc[0] = (u8)size; + cmd_lockdown_crc[1] = crc_data; + cmd_lockdown_crc[2] = lock_id; + ret = calculateCRC8(cmd_lockdown_crc, 3, &crc_head); + if (ret < OK) { + logError( + 1, + "%s %s: Unable to compute head CRC.. ERROR %08X\n", + tag, __func__, ret); + ret = (ret | ERROR_LOCKDOWN_CODE); + continue; + } + cmd_lockdown_crc[3] = crc_head; + logError(0, "%s %s: Get the header CRC value:%02X\n", tag, + __func__, crc_head); + + ret = fts_writeU8UX(LOCKDOWN_WRITEREAD_CMD, BITS_16, + ADDR_LOCKDOWN + LOCKDOWN_DATA_OFFSET - + LOCKDOWN_HEAD_LENGTH, + cmd_lockdown_crc, + ARRAY_SIZE(cmd_lockdown_crc)); + if (ret < OK) { + logError( + 1, + "%s %s: Unable to write Lockdown head at %d iteration.. ERROR %08X\n", + tag, __func__, i, ret); + ret = (ret | ERROR_LOCKDOWN_CODE); + continue; + } + mdelay(10); + ret = fts_writeU8UX(LOCKDOWN_WRITEREAD_CMD, BITS_16, + ADDR_LOCKDOWN + LOCKDOWN_DATA_OFFSET, data, + size); + if (ret < OK) { + logError( + 1, + "%s %s: Unable to write Lockdown head at %d iteration.. ERROR %08X\n", + tag, __func__, i, ret); + ret = (ret | ERROR_LOCKDOWN_CODE); + continue; + } + mdelay(10); + ret = fts_write_dma_safe(lockdown_save, 3); + mdelay(5); + ret = checkEcho(lockdown_save, 3); + if (ret < OK) { + logError(1, "%s No Echo received.. ERROR %08X !\n", tag, + ret); + continue; + } else { + logError(1, "%s Echo FOUND... OK!\n", tag, ret); + ret = pollForErrorType(error_to_search, 4); + if (ret < OK) { + logError(1, "%s %s: No Error Found! \n", tag, + __func__); + ret = OK; + } else { + logError( + 1, + "%s %s: have error when write lockdown ERROR = %02X\n", + tag, __func__, ret); + ret = ERROR_LOCKDOWN_CODE; + } + break; + } + } + if (ret < OK) + logError(1, "%s %s end, write lockdown failed\n", tag, __func__, + ret); + else + logError(1, "%s %s end, write lockdown success\n", tag, + __func__, ret); + + fts_enableInterrupt(); + return ret; +} + +int readLockDownInfo(u8 *lockData, u8 lock_id, int size) +{ + int ret = 0, i; + int loaded_cnt = 0; + int loaded_cnt_after = 0; + u8 *temp = NULL; + char *datatemp = NULL; + u8 cmd_lockdown[3] = { 0xA4, 0x06, 0x00 }; + + logError(0, "%s %s:enter", tag, __func__); + if (lock_id < 0x70 || lock_id > 0x77 || size <= 0 || + size > LOCKDOWN_LENGTH - 20) { + logError(1, "%s the lock id type is:%02X not support\n", tag, + lock_id); + return ERROR_LOCKDOWN_CODE; + } + + temp = (u8 *)kmalloc(LOCKDOWN_LENGTH * sizeof(u8), GFP_KERNEL); + if (temp == NULL) { + logError(1, "FTS temp alloc memory failed \n"); + return -ENOMEM; + } + memset(temp, 0, LOCKDOWN_LENGTH * sizeof(u8)); + + fts_disableInterrupt(); + for (i = 0; i < 3; i++) { + ret = fts_writeReadU8UX(LOCKDOWN_WRITEREAD_CMD, BITS_16, + ADDR_LOCKDOWN, temp, + LOCKDOWN_HEAD_LENGTH, DUMMY_CONFIG); + if (ret < OK) { + logError( + 1, + "%s %s: error while reading data ERROR %08X \n", + tag, __func__, ret); + goto END; + } + loaded_cnt = (int)((temp[3] & 0xFF) << 8) + (temp[2] & 0xFF); + cmd_lockdown[2] = lock_id; + fts_write_dma_safe(cmd_lockdown, 3); + mdelay(10); + ret = checkEcho(cmd_lockdown, 3); + if (ret < OK) { + logError(1, "%s No Echo received.. ERROR %08X !\n", tag, + ret); + continue; + } else { + logError(1, "%s Echo FOUND... OK!\n", tag, ret); + } + ret = fts_writeReadU8UX(LOCKDOWN_WRITEREAD_CMD, BITS_16, + ADDR_LOCKDOWN, temp, + size + LOCKDOWN_DATA_OFFSET, + DUMMY_CONFIG); + if (ret < OK) { + logError( + 1, + "%s %s: error while reading data ERROR %08X \n", + tag, __func__, ret); + goto END; + } + + loaded_cnt_after = + (int)((temp[3] & 0xFF) << 8) + (temp[2] & 0xFF); + if (temp[4] == EVT_TYPE_ERROR_LOCKDOWN_FLASH || + temp[4] == EVT_TYPE_ERROR_LOCKDOWN_NO_DATA) { + logError( + 1, + "%s %s: can not read the lockdown code ERROR type:%02X\n", + tag, __func__, temp[4]); + ret = ERROR_LOCKDOWN_CODE; + goto END; + } + + logError( + 1, + "%s %s signature:%02X id:%02X %02X beforecnt:%d,aftercnt:%d\n", + tag, __func__, temp[0], temp[1], lock_id, loaded_cnt, + loaded_cnt_after); + if (loaded_cnt_after == loaded_cnt + 1) { + ret = OK; + memcpy(lockData, &temp[LOCKDOWN_DATA_OFFSET], size); + break; + } + } + + datatemp = printHex_data("Lockdown Code = ", lockData, size); + if (datatemp != NULL) { + logError(1, "%s %s", tag, datatemp); + kfree(datatemp); + } + +END: + fts_enableInterrupt(); + kfree(temp); + return ret; +} + +int fts_get_lockdown_info(u8 *lockData, struct fts_ts_info *info) +{ + int ret = 0, i; + int loaded_cnt = 0; + u8 lock_id = FTS_CMD_LOCKDOWN_ID; + int size = FTS_LOCKDOWN_SIZE; + int loaded_cnt_after = 0; + u8 *temp = NULL; + u8 cmd_lockdown[3] = { 0xA4, 0x06, 0x00 }; + char *datatemp = NULL; + + if (info == NULL) + return ERROR_LOCKDOWN_CODE; + if (info->lockdown_is_ok) { + logError(1, "%s %s aleady get,skip\n", tag, __func__); + return OK; + } + logError(0, "%s %s:enter", tag, __func__); + if (lock_id < 0x70 || lock_id > 0x77) { + logError(1, "%s the lock id type is not support\n", tag); + return ERROR_LOCKDOWN_CODE; + } + + temp = (u8 *)kmalloc(1024 * sizeof(u8), GFP_KERNEL); + if (temp == NULL) { + logError(1, "FTS temp alloc memory failed \n"); + return -ENOMEM; + } + memset(temp, 0, 1024 * sizeof(u8)); + + fts_disableInterrupt(); + + for (i = 0; i < LOCKDOWN_CODE_RETRY; i++) { + ret = fts_writeReadU8UX(LOCKDOWN_WRITEREAD_CMD, BITS_16, + ADDR_LOCKDOWN, temp, + LOCKDOWN_HEAD_LENGTH, DUMMY_CONFIG); + if (ret < OK) { + logError( + 1, + "%s %s: error while reading data ERROR %08X \n", + tag, __func__, ret); + goto END; + } + loaded_cnt = (int)((temp[3] & 0xFF) << 8) + (temp[2] & 0xFF); + cmd_lockdown[2] = lock_id; + fts_write_dma_safe(cmd_lockdown, 3); + mdelay(10); + ret = checkEcho(cmd_lockdown, 3); + if (ret < OK) { + logError(1, "%s No Echo received.. ERROR %08X !\n", tag, + ret); + continue; + } else { + logError(1, "%s Echo FOUND... OK!\n", tag, ret); + } + ret = fts_writeReadU8UX(LOCKDOWN_WRITEREAD_CMD, BITS_16, + ADDR_LOCKDOWN, temp, + size + LOCKDOWN_DATA_OFFSET, + DUMMY_CONFIG); + if (ret < OK) { + logError( + 1, + "%s %s: error while reading data ERROR %08X \n", + tag, __func__, ret); + goto END; + } + + loaded_cnt_after = + (int)((temp[3] & 0xFF) << 8) + (temp[2] & 0xFF); + if (temp[4] == EVT_TYPE_ERROR_LOCKDOWN_FLASH || + temp[4] == EVT_TYPE_ERROR_LOCKDOWN_NO_DATA) { + logError( + 1, + "%s %s: can not read the lockdown code ERROR type:%02X\n", + tag, __func__, temp[4]); + ret = ERROR_LOCKDOWN_CODE; + goto END; + } + + logError( + 1, + "%s %s signature:%02X id:%02X %02X beforecnt:%d,aftercnt:%d\n", + tag, __func__, temp[0], temp[1], lock_id, loaded_cnt, + loaded_cnt_after); + if (loaded_cnt_after == loaded_cnt + 1) { + ret = OK; + memcpy(lockData, &temp[LOCKDOWN_DATA_OFFSET], size); + break; + } + } + + datatemp = printHex_data("Lockdown Code = ", lockData, size); + if (datatemp != NULL) { + logError(0, "%s %s", tag, datatemp); + kfree(datatemp); + } + +END: + fts_enableInterrupt(); + kfree(temp); + return ret; +} diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCore.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCore.h new file mode 100644 index 000000000000..1e09174e4523 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsCore.h @@ -0,0 +1,187 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS Core definitions * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsCore.h +* \brief Contains all the definitions and structs of Core functionalities +*/ + +#ifndef FTS_CORE_H +#define FTS_CORE_H + +#include "ftsHardware.h" +#include "ftsSoftware.h" +#include "../fts.h" + +/*HW DATA*/ +#define GPIO_NOT_DEFINED \ + -1 /*value assumed by reset_gpio when the reset pin of the IC is not connected*/ + +#define ADDR_SIZE_HW_REG \ + BITS_32 /*value of AddrSize for Hw register in FTI @see AddrSize*/ + +#define DATA_HEADER \ + 4 /*size in byte of the header loaded with the data in the frambuffer*/ +#define LOCKDOWN_CODE_RETRY 2 +/** + * Type of CRC errors + */ +typedef enum { + CRC_CODE = 1, /*CRC in the code section*/ + CRC_CONFIG = 2, /*CRC in the config section*/ + CRC_CX = 3, /*CRC in the cx section*/ + CRC_PANEL = 4 /*CRC in the panel section*/ +} CRC_Error; + +/*CHIP INFO*/ +/** @defgroup system_info System Info +* System Info Data collect the most important informations about hw and fw +* @{ +*/ +#define SYS_INFO_SIZE 208 /*Size in bytes of System Info data*/ +#define DIE_INFO_SIZE 16 /*num bytes of die info*/ +#define EXTERNAL_RELEASE_INFO_SIZE 8 /*num bytes of external release in config*/ +#define RELEASE_INFO_SIZE \ + (EXTERNAL_RELEASE_INFO_SIZE + \ + 8) /*num bytes of release info in sys info (first bytes are external release)*/ +/** @}*/ + +/*RETRY MECHANISM*/ +#define RETRY_MAX_REQU_DATA \ + 2 /*Max number of attemps performed when requesting data*/ +#define RETRY_SYSTEM_RESET 3 /*Max number of attemps performed to reset the IC*/ + +/*LOCKDOWN INFO*/ +#define LOCKDOWN_LENGTH 384 +#define LOCKDOWN_HEAD_LENGTH 4 +#define LOCKDOWN_DATA_OFFSET 20 +#define LOCKDOWN_SIGNATURE 0x5A +#define ADDR_LOCKDOWN ((u64)0x0000000000000000) +#define LOCKDOWN_WRITEREAD_CMD 0xA6 + +/** @addtogroup system_info +* @{ +*/ + +/** + * Struct which contains fundamental informations about the chip and its configuration + */ +typedef struct { + u16 u16_apiVer_rev; /*API revision version*/ + u8 u8_apiVer_minor; /*API minor version*/ + u8 u8_apiVer_major; /*API major version*/ + u16 u16_chip0Ver; /*Dev0 version*/ + u16 u16_chip0Id; /*Dev0 ID*/ + u16 u16_chip1Ver; /*Dev1 version*/ + u16 u16_chip1Id; /*Dev1 ID*/ + u16 u16_fwVer; /*Fw version*/ + u16 u16_svnRev; /*SVN Revision*/ + u16 u16_cfgVer; /*Config Version*/ + u16 u16_cfgProgectId; /*Config Project ID*/ + u16 u16_cxVer; /*Cx Version*/ + u16 u16_cxProjectId; /*Cx Project ID*/ + u8 u8_cfgAfeVer; /*AFE version in Config*/ + u8 u8_cxAfeVer; /*AFE version in CX*/ + u8 u8_panelCfgAfeVer; /*AFE version in PanelMem*/ + u8 u8_protocol; /*Touch Report Protocol*/ + u8 u8_dieInfo[DIE_INFO_SIZE]; /*Die information*/ + u8 u8_releaseInfo[RELEASE_INFO_SIZE]; /*Release information*/ + u32 u32_fwCrc; /*Crc of FW*/ + u32 u32_cfgCrc; /*Crc of config*/ + + u16 u16_scrResX; /*X resolution on main screen*/ + u16 u16_scrResY; /*Y resolution on main screen*/ + u8 u8_scrTxLen; /*Tx length*/ + u8 u8_scrRxLen; /*Rx length*/ + u8 u8_keyLen; /*Key Len*/ + u8 u8_forceLen; /*Force Len*/ + + u16 u16_dbgInfoAddr; /*Offset of debug Info structure*/ + + u16 u16_msTchRawAddr; /*Offset of MS touch raw frame*/ + u16 u16_msTchFilterAddr; /*Offset of MS touch filter frame*/ + u16 u16_msTchStrenAddr; /*Offset of MS touch strength frame*/ + u16 u16_msTchBaselineAddr; /*Offset of MS touch baseline frame*/ + + u16 u16_ssTchTxRawAddr; /*Offset of SS touch force raw frame*/ + u16 u16_ssTchTxFilterAddr; /*Offset of SS touch force filter frame*/ + u16 u16_ssTchTxStrenAddr; /*Offset of SS touch force strength frame*/ + u16 u16_ssTchTxBaselineAddr; /*Offset of SS touch force baseline frame*/ + + u16 u16_ssTchRxRawAddr; /*Offset of SS touch sense raw frame*/ + u16 u16_ssTchRxFilterAddr; /*Offset of SS touch sense filter frame*/ + u16 u16_ssTchRxStrenAddr; /*Offset of SS touch sense strength frame*/ + u16 u16_ssTchRxBaselineAddr; /*Offset of SS touch sense baseline frame*/ + + u16 u16_keyRawAddr; /*Offset of key raw frame*/ + u16 u16_keyFilterAddr; /*Offset of key filter frame*/ + u16 u16_keyStrenAddr; /*Offset of key strength frame*/ + u16 u16_keyBaselineAddr; /*Offset of key baseline frame*/ + + u16 u16_frcRawAddr; /*Offset of force touch raw frame*/ + u16 u16_frcFilterAddr; /*Offset of force touch filter frame*/ + u16 u16_frcStrenAddr; /*Offset of force touch strength frame*/ + u16 u16_frcBaselineAddr; /*Offset of force touch baseline frame*/ + + u16 u16_ssHvrTxRawAddr; /*Offset of SS hover Force raw frame*/ + u16 u16_ssHvrTxFilterAddr; /*Offset of SS hover Force filter frame*/ + u16 u16_ssHvrTxStrenAddr; /*Offset of SS hover Force strength frame*/ + u16 u16_ssHvrTxBaselineAddr; /*Offset of SS hover Force baseline frame*/ + + u16 u16_ssHvrRxRawAddr; /*Offset of SS hover Sense raw frame*/ + u16 u16_ssHvrRxFilterAddr; /*Offset of SS hover Sense filter frame*/ + u16 u16_ssHvrRxStrenAddr; /*Offset of SS hover Sense strength frame*/ + u16 u16_ssHvrRxBaselineAddr; /*Offset of SS hover Sense baseline frame*/ + + u16 u16_ssPrxTxRawAddr; /*Offset of SS proximity force raw frame*/ + u16 u16_ssPrxTxFilterAddr; /*Offset of SS proximity force filter frame*/ + u16 u16_ssPrxTxStrenAddr; /*Offset of SS proximity force strength frame*/ + u16 u16_ssPrxTxBaselineAddr; /*Offset of SS proximity force baseline frame*/ + + u16 u16_ssPrxRxRawAddr; /*Offset of SS proximity sense raw frame*/ + u16 u16_ssPrxRxFilterAddr; /*Offset of SS proximity sense filter frame*/ + u16 u16_ssPrxRxStrenAddr; /*Offset of SS proximity sense strength frame*/ + u16 u16_ssPrxRxBaselineAddr; /*Offset of SS proximity sense baseline frame*/ +} SysInfo; + +/** @}*/ + +int initCore(struct fts_ts_info *info); +void setResetGpio(int gpio); +int fts_system_reset(void); +int isSystemResettedUp(void); +int isSystemResettedDown(void); +void setSystemResetedUp(int val); +void setSystemResetedDown(int val); +int pollForEvent(int *event_to_search, int event_bytes, u8 *readData, + int time_to_wait); +int checkEcho(u8 *cmd, int size); +int setScanMode(u8 mode, u8 settings); +int setFeatures(u8 feat, u8 *settings, int size); +int defaultSysInfo(int i2cError); +int writeSysCmd(u8 sys_cmd, u8 *sett, int size); +int readSysInfo(int request); +int readConfig(u16 offset, u8 *outBuf, int len); +int fts_disableInterrupt(void); +int fts_disableInterruptNoSync(void); +int fts_resetDisableIrqCount(void); +int fts_enableInterrupt(void); +int fts_crc_check(void); +int requestSyncFrame(u8 type); +int fts_get_lockdown_info(u8 *lockData, struct fts_ts_info *info); +int writeLockDownInfo(u8 *data, int size, u8 lock_id); +int readLockDownInfo(u8 *lockData, u8 lock_id, int size); + +#endif /* FTS_CORE_H */ diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsError.c b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsError.c new file mode 100644 index 000000000000..5bd34cc26fd5 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsError.c @@ -0,0 +1,360 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS error/info kernel log reporting * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsError.c +* \brief Contains all the function which handle with Error conditions +*/ + +#include +#include +#include +#include +#include + +#include "../fts.h" +#include "ftsCore.h" +#include "ftsError.h" +#include "ftsIO.h" +#include "ftsTool.h" +#include "ftsCompensation.h" + +static ErrorList errors; + +/** +* Print messages in the kernel log +* @param force if 1, the log is printed always otherwise only if DEBUG is defined, the log will be printed +* @param msg string containing the message to print +* @param ... additional parameters that are used in msg according the format of printf +*/ +void logError(int force, const char *msg, ...) +{ + if (force == 1 +#ifdef DEBUG + || 1 +#endif + ) { + va_list args; + va_start(args, msg); + vprintk(msg, args); + va_end(args); + } +} + +/** +* Check if an error code is related to an I2C failure +* @param error error code to check +* @return 1 if the first level error code is I2C related otherwise 0 +*/ +int isI2cError(int error) +{ + if (((error & 0x000000FF) >= (ERROR_BUS_R & 0x000000FF)) && + ((error & 0x000000FF) <= (ERROR_BUS_O & 0x000000FF))) + return 1; + else + return 0; +} + +/** + * Dump in the kernel log some debug info in case of FW hang + * @param outBuf (optional)pointer to bytes array where to copy the debug info, if NULL the data will just printed on the kernel log + * @param size dimension in bytes of outBuf, if > ERROR_DUMP_ROW_SIZE*ERROR_DUMP_COL_SIZE, only the first ERROR_DUMP_ROW_SIZE*ERROR_DUMP_COL_SIZE bytes will be copied + * @return OK if success or an error code which specify the type of error encountered + */ +int dumpErrorInfo(u8 *outBuf, int size) +{ + int ret, i; + u8 data[ERROR_DUMP_ROW_SIZE * ERROR_DUMP_COL_SIZE] = { 0 }; + u32 sign = 0; + + logError(0, "%s %s: Starting dump of error info...\n", tag, __func__); + + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, ADDR_ERROR_DUMP, + data, ERROR_DUMP_ROW_SIZE * ERROR_DUMP_COL_SIZE, + DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError(1, "%s %s: reading data ERROR %08X\n", tag, __func__, + ret); + return ret; + } else { + if (outBuf != NULL) { + sign = size > ERROR_DUMP_ROW_SIZE * + ERROR_DUMP_COL_SIZE ? + ERROR_DUMP_ROW_SIZE * + ERROR_DUMP_COL_SIZE : + size; + memcpy(outBuf, data, sign); + logError(0, + "%s %s: error info copied in the buffer! \n", + tag, __func__); + } + logError(1, "%s %s: Error Info = \n", tag, __func__); + u8ToU32(data, &sign); + if (sign != ERROR_DUMP_SIGNATURE) + logError( + 1, + "%s %s: Wrong Error Signature! Data may be invalid! \n", + tag, __func__); + else + logError( + 1, + "%s %s: Error Signature OK! Data are valid! \n", + tag, __func__); + + for (i = 0; i < ERROR_DUMP_ROW_SIZE * ERROR_DUMP_COL_SIZE; + i++) { + if (i % ERROR_DUMP_COL_SIZE == 0) { + logError(1, KERN_ERR "\n%s %s: %d) ", tag, + __func__, i / ERROR_DUMP_COL_SIZE); + } + logError(1, "%02X ", data[i]); + } + logError(1, "\n"); + + logError(0, "%s %s: dump of error info FINISHED!\n", tag, + __func__); + return OK; + } +} + +/** +* Implement recovery strategies to be used when an error event is found while polling the FIFO +* @param event error event found during the polling +* @param size size of event +* @return OK if the error event doesn't require any action or the recovery strategy doesn't have any impact in the possible procedure that trigger the error, otherwise return an error code which specify the kind of error encountered. If ERROR_HANDLER_STOP_PROC the calling function must stop! +*/ +int errorHandler(u8 *event, int size) +{ + int res = OK; + struct fts_ts_info *info = NULL; + + if (getDev() != NULL) + info = dev_get_drvdata(getDev()); + + if (info != NULL && event != NULL && size > 1 && + event[0] == EVT_ID_ERROR) { + logError(0, "%s errorHandler: Starting handling...\n", tag); + addErrorIntoList(event, size); + switch (event[1]) { + case EVT_TYPE_ERROR_ESD: + res = fts_chip_powercycle(info); + if (res < OK) { + logError( + 1, + "%s errorHandler: Error performing powercycle ERROR %08X\n", + tag, res); + } + + res = fts_system_reset(); + if (res < OK) { + logError( + 1, + "%s errorHandler: Cannot reset the device ERROR %08X\n", + tag, res); + } + res = (ERROR_HANDLER_STOP_PROC | res); + break; + + case EVT_TYPE_ERROR_WATCHDOG: + dumpErrorInfo(NULL, 0); + res = fts_system_reset(); + if (res < OK) { + logError( + 1, + "%s errorHandler: Cannot reset the device ERROR %08X\n", + tag, res); + } + res = (ERROR_HANDLER_STOP_PROC | res); + break; + + case EVT_TYPE_ERROR_ITO_FORCETOGND: + logError(1, "%s errorHandler: Force Short to GND!\n", + tag); + break; + case EVT_TYPE_ERROR_ITO_SENSETOGND: + logError(1, "%s errorHandler: Sense short to GND! \n", + tag); + break; + case EVT_TYPE_ERROR_ITO_FORCETOVDD: + logError(1, "%s errorHandler: Force short to VDD!\n", + tag); + break; + case EVT_TYPE_ERROR_ITO_SENSETOVDD: + logError(1, "%s errorHandler: Sense short to VDD!\n", + tag); + break; + case EVT_TYPE_ERROR_ITO_FORCE_P2P: + logError(1, + "%s errorHandler: Force Pin to Pin Short!\n", + tag); + break; + case EVT_TYPE_ERROR_ITO_SENSE_P2P: + logError(1, + "%s errorHandler: Sense Pin to Pin Short!\n", + tag); + break; + case EVT_TYPE_ERROR_ITO_FORCEOPEN: + logError(1, "%s errorHandler: Force Open !\n", tag); + break; + case EVT_TYPE_ERROR_ITO_SENSEOPEN: + logError(1, "%s errorHandler: Sense Open !\n", tag); + break; + case EVT_TYPE_ERROR_ITO_KEYOPEN: + logError(1, "%s errorHandler: Key Open !\n", tag); + break; + + default: + logError(0, "%s errorHandler: No Action taken! \n", + tag); + break; + } + logError(0, "%s errorHandler: handling Finished! res = %08X\n", + tag, res); + return res; + } else { + logError( + 1, + "%s errorHandler: event Null or not correct size! ERROR %08X \n", + tag, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } +} + +/** +* Add an error event into the Error List +* @param event error event to add +* @param size size of event +* @return OK +*/ +int addErrorIntoList(u8 *event, int size) +{ + int i = 0; + + logError(0, "%s Adding error in to ErrorList... \n", tag); + + memcpy(&errors.list[errors.last_index * FIFO_EVENT_SIZE], event, size); + i = FIFO_EVENT_SIZE - size; + if (i > 0) { + logError(0, + "%s Filling last %d bytes of the event with zero...\n", + tag, i); + memset(&errors.list[errors.last_index * FIFO_EVENT_SIZE + size], + 0, i); + } + logError(0, "%s Adding error in to ErrorList... FINISHED!\n", tag); + + errors.count += 1; + if (errors.count > FIFO_DEPTH) + logError( + 1, + "%s ErrorList is going in overflow... the first %d event(s) were override!\n", + tag, errors.count - FIFO_DEPTH); + errors.last_index = (errors.last_index + 1) % FIFO_DEPTH; + + return OK; +} + +/** +* Reset the Error List setting the count and last_index to 0. +* @return OK +*/ +int resetErrorList(void) +{ + errors.count = 0; + errors.last_index = 0; + memset(errors.list, 0, FIFO_DEPTH * FIFO_EVENT_SIZE); + return OK; +} + +/** +* Get the number of error events copied into the Error List +* @return the number of error events into the Error List +*/ +int getErrorListCount(void) +{ + if (errors.count > FIFO_DEPTH) + return FIFO_DEPTH; + else + return errors.count; +} + +/** +* Scroll the Error List looking for the event specified +* @param event_to_search event_to_search pointer to an array of int where each element correspond to a byte of the event to find. If the element of the array has value -1, the byte of the event, in the same position of the element is ignored. +* @param event_bytes size of event_to_search +* @return a value >=0 if the event is found which represent the index of the Error List where the event is located otherwise an error code +*/ +int pollErrorList(int *event_to_search, int event_bytes) +{ + int i = 0, j = 0, find = 0; + int count = getErrorListCount(); + + logError(0, "%s Starting to poll ErrorList... \n", tag); + while (find != 1 && i < count) { + find = 1; + for (j = 0; j < event_bytes; j++) { + if (event_to_search[i] != -1 && + (int)errors.list[i * FIFO_EVENT_SIZE + j] != + event_to_search[i]) { + find = 0; + break; + } + } + i++; + } + if (find == 1) { + logError(1, "%s Error Found into ErrorList! \n", tag); + return i - 1; + } else { + logError(0, "%s Error Not Found into ErrorList! ERROR %08X \n", + tag, ERROR_TIMEOUT); + return ERROR_TIMEOUT; + } +} + +/** +* Poll the Error List looking for any error types passed in the arguments. Return at the first match! +* @param list pointer to a list of error types to look for +* @param size size of list +* @return error type found if success or ERROR_TIMEOUT +*/ +int pollForErrorType(u8 *list, int size) +{ + int i = 0, j = 0, find = 0; + int count = getErrorListCount(); + + logError(0, "%s %s: Starting to poll ErrorList... count = %d \n", tag, + __func__, count); + while (find != 1 && i < count) { + for (j = 0; j < size; j++) { + if (list[j] == errors.list[i * FIFO_EVENT_SIZE + 1]) { + find = 1; + break; + } + } + i++; + } + if (find == 1) { + logError(1, "%s %s: Error Type %02X into ErrorList! \n", tag, + __func__, list[j]); + return list[j]; + } else { + logError( + 0, + "%s %s: Error Type Not Found into ErrorList! ERROR %08X \n", + tag, __func__, ERROR_TIMEOUT); + return ERROR_TIMEOUT; + } +} diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsError.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsError.h new file mode 100644 index 000000000000..6f84dca97bad --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsError.h @@ -0,0 +1,181 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS error/info kernel log reporting * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsError.h +* \brief Contains all the definitions and structs which refer to Error conditions +*/ + +#ifndef FTS_ERROR_H +#define FTS_ERROR_H + +#include "ftsHardware.h" +#include "ftsSoftware.h" + +/** @defgroup error_codes Error Codes + * Error codes that can be reported by the driver functions. + * An error code is made up by 4 bytes, each byte indicate a logic error level.\n + * From the LSB to the MSB, the logic level increase going from a low level error (I2C,TIMEOUT) to an high level error (flashing procedure fail, production test fail etc) + * @{ + */ + +/*FIRST LEVEL ERROR CODE*/ +/** @defgroup first_level First Level Error Code +* @ingroup error_codes +* Errors related to low level operation which are not under control of driver, such as: communication protocol (I2C/SPI), timeout, file operations ... +* @{ +*/ +#define OK ((int)0x00000000) /*No ERROR*/ +#define ERROR_ALLOC ((int)0x80000001) /*allocation of memory failed*/ +#define ERROR_BUS_R ((int)0x80000002) /*i2c/spi read failed*/ +#define ERROR_BUS_W ((int)0x80000003) /*i2c/spi write failed*/ +#define ERROR_BUS_WR ((int)0x80000004) /*i2c/spi write/read failed*/ +#define ERROR_BUS_O ((int)0x80000005) /*error during opening an i2c device*/ +#define ERROR_OP_NOT_ALLOW ((int)0x80000006) /*operation not allowed*/ +#define ERROR_TIMEOUT \ + ((int)0x80000007) /*timeout expired! exceed the max number of retries or the max waiting time*/ +#define ERROR_FILE_NOT_FOUND \ + ((int)0x80000008) /*the file that i want to open is not found*/ +#define ERROR_FILE_PARSE ((int)0x80000009) /*error during parsing the file*/ +#define ERROR_FILE_READ ((int)0x8000000A) /*error during reading the file*/ +#define ERROR_LABEL_NOT_FOUND ((int)0x8000000B) /*label not found*/ +#define ERROR_FW_NO_UPDATE \ + ((int)0x8000000C) /*fw in the chip newer than the one in the memmh*/ +#define ERROR_FLASH_UNKNOWN ((int)0x8000000D) /*flash status busy or unknown*/ +/** @}*/ + +/*SECOND LEVEL ERROR CODE */ +/** @defgroup second_level Second Level Error Code +* @ingroup error_codes +* Errors related to simple logic operations in the IC which require one command or which are part of a more complex procedure +* @{ +*/ +#define ERROR_DISABLE_INTER \ + ((int)0x80000200) /*unable to disable the interrupt*/ +#define ERROR_ENABLE_INTER ((int)0x80000300) /*unable to activate the interrup*/ +#define ERROR_READ_CONFIG ((int)0x80000400) /*failed to read config memory*/ +#define ERROR_GET_OFFSET \ + ((int)0x80000500) /*unable to read an offset from memory*/ +#define ERROR_GET_FRAME_DATA \ + ((int)0x80000600) /*unable to retrieve the data of a required frame*/ +#define ERROR_DIFF_DATA_TYPE \ + ((int)0x80000700) /*FW answers with an event that has a different address respect the request done*/ +#define ERROR_WRONG_DATA_SIGN \ + ((int)0x80000800) /*the signature of the host data is not HEADER_SIGNATURE*/ +#define ERROR_SET_SCAN_MODE_FAIL \ + ((int)0x80000900) /*setting the scanning mode failed (sense on/off etc...)*/ +#define ERROR_SET_FEATURE_FAIL \ + ((int)0x80000A00) /*setting a specific feature failed*/ +#define ERROR_SYSTEM_RESET_FAIL \ + ((int)0x80000B00) /*the comand SYSTEM RESET failed*/ +#define ERROR_FLASH_NOT_READY \ + ((int)0x80000C00) /*flash status not ready within a timeout*/ +#define ERROR_FW_VER_READ \ + ((int)0x80000D00) /*unable to retrieve fw_vers or the config_id*/ +#define ERROR_GESTURE_ENABLE_FAIL \ + ((int)0x80000E00) /*unable to enable/disable the gesture*/ +#define ERROR_GESTURE_START_ADD \ + ((int)0x80000F00) /*unable to start to add custom gesture*/ +#define ERROR_GESTURE_FINISH_ADD \ + ((int)0x80001000) /*unable to finish to add custom gesture*/ +#define ERROR_GESTURE_DATA_ADD \ + ((int)0x80001100) /*unable to add custom gesture data*/ +#define ERROR_GESTURE_REMOVE \ + ((int)0x80001200) /*unable to remove custom gesture data*/ +#define ERROR_FEATURE_ENABLE_DISABLE \ + ((int)0x80001300) /*unable to enable/disable a feature mode in the IC*/ +#define ERROR_NOISE_PARAMETERS \ + ((int)0x80001400) /*unable to set/read noise parameter in the IC*/ +#define ERROR_CH_LEN \ + ((int)0x80001500) /*unable to retrieve the force and/or sense length*/ +/** @}*/ + +/*THIRD LEVEL ERROR CODE */ +/** @defgroup third_level Third Level Error Code +* @ingroup error_codes +* Errors related to logic operations in the IC which require more commands/steps or which are part of a more complex procedure +* @{ +*/ +#define ERROR_REQU_COMP_DATA \ + ((int)0x80010000) /*compensation data request failed*/ +#define ERROR_REQU_DATA ((int)0x80020000) /*data request failed*/ +#define ERROR_COMP_DATA_HEADER \ + ((int)0x80030000) /*unable to retrieve the compensation data header*/ +#define ERROR_COMP_DATA_GLOBAL \ + ((int)0x80040000) /*unable to retrieve the global compensation data*/ +#define ERROR_COMP_DATA_NODE \ + ((int)0x80050000) /*unable to retrieve the compensation data for each node*/ +#define ERROR_TEST_CHECK_FAIL \ + ((int)0x80060000) /*check of production limits or of fw answers failed*/ +#define ERROR_MEMH_READ ((int)0x80070000) /*memh reading failed*/ +#define ERROR_FLASH_BURN_FAILED ((int)0x80080000) /*flash burn failed*/ +#define ERROR_MS_TUNING ((int)0x80090000) /*ms tuning failed*/ +#define ERROR_SS_TUNING ((int)0x800A0000) /*ss tuning failed*/ +#define ERROR_LP_TIMER_TUNING ((int)0x800B0000) /*lp timer calibration failed*/ +#define ERROR_SAVE_CX_TUNING ((int)0x800C0000) /*save cx data to flash failed*/ +#define ERROR_HANDLER_STOP_PROC \ + ((int)0x800D0000) /*stop the poll of the FIFO if particular errors are found*/ +#define ERROR_CHECK_ECHO_FAIL \ + ((int)0x800E0000) /*unable to retrieve echo event*/ +#define ERROR_GET_FRAME ((int)0x800F0000) /*unable to get frame*/ +/** @}*/ + +/*FOURTH LEVEL ERROR CODE*/ +/** @defgroup fourth_level Fourth Level Error Code +* @ingroup error_codes +* Errors related to the highest logic operations in the IC which have an important impact on the driver flow or which require several commands and steps to be executed +* @{ +*/ +#define ERROR_PROD_TEST_DATA ((int)0x81000000) /*production data test failed*/ +#define ERROR_FLASH_PROCEDURE ((int)0x82000000) /*fw update procedure failed*/ +#define ERROR_PROD_TEST_ITO ((int)0x83000000) /*production ito test failed*/ +#define ERROR_PROD_TEST_INITIALIZATION \ + ((int)0x84000000) /*production initialization test failed*/ +#define ERROR_GET_INIT_STATUS \ + ((int)0x85000000) /*mismatch of the MS or SS tuning_version*/ +#define ERROR_LOCKDOWN_CODE \ + ((int)0x80001600) /*unable to write/rewrite/read lockdown code in the IC*/ + +#define EVT_TYPE_ERROR_LOCKDOWN_FLASH \ + 0x30 /*FW shall not proceed with any flash write/read*/ +#define EVT_TYPE_ERROR_LOCKDOWN_CRC \ + 0x31 /*FW shall discard the record and do not write to flash*/ +#define EVT_TYPE_ERROR_LOCKDOWN_NO_DATA \ + 0x32 /*No data of this type exisitng in flash*/ +#define EVT_TYPE_ERROR_LOCKDOWN_WRITE_FULL \ + 0x33 /*FW shall not write this new record to flash*/ +/** @}*/ + +/** +* Struct which store an ordered list of the errors events encountered during the polling of a FIFO. +* The max number of error events that can be stored is equal to FIFO_DEPTH +*/ +typedef struct { + u8 list[FIFO_DEPTH * + FIFO_EVENT_SIZE]; /*byte array which contains the series of error events encountered from the last reset of the list.*/ + int count; /*number of error events stored in the list*/ + int last_index; /*index of the list where will be stored the next error event. Subtract -1 to have the index of the last error event!*/ +} ErrorList; + +void logError(int force, const char *msg, ...); +int isI2cError(int error); +int dumpErrorInfo(u8 *outBuf, int size); +int errorHandler(u8 *event, int size); +int addErrorIntoList(u8 *event, int size); +int getErrorListCount(void); +int resetErrorList(void); +int pollErrorList(int *event_to_search, int event_bytes); +int pollForErrorType(u8 *list, int size); +#endif diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFlash.c b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFlash.c new file mode 100644 index 000000000000..05e2a22853ba --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFlash.c @@ -0,0 +1,1058 @@ +/* + + ************************************************************************** + ** STMicroelectronics ** + ************************************************************************** + ** marco.cali@st.com ** + ************************************************************************** + * * + * FTS API for Flashing the IC * + * * + ************************************************************************** + ************************************************************************** + + */ + +/*! +* \file ftsFlash.c +* \brief Contains all the functions to handle the FW update process +*/ + +#include "ftsCore.h" +#include "ftsCompensation.h" +#include "ftsError.h" +#include "ftsFlash.h" +#include "ftsFrame.h" +#include "ftsIO.h" +#include "ftsSoftware.h" +#include "ftsTest.h" +#include "ftsTime.h" +#include "ftsTool.h" +#include "../fts.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef FW_H_FILE +#include "../fts_fw.h" +#endif + +extern SysInfo systemInfo; +extern struct fts_ts_info *fts_info; + +/** + * Read the fw version and config id from the chip + * @param fw_vers pointer to the variable which will contains the fw version + * @param config_id pointer to the variable which will contains the config id + * @return OK if success or an error code which specify the type of error encountered + */ +int getFirmwareVersion(u16 *fw_vers, u16 *config_id) +{ + u8 fwvers[DCHIP_FW_VER_BYTE]; + u8 confid[CONFIG_ID_BYTE]; + int res; + + res = fts_writeReadU8UX(FTS_CMD_HW_REG_R, ADDR_SIZE_HW_REG, + ADDR_DCHIP_FW_VER, fwvers, DCHIP_FW_VER_BYTE, + DUMMY_HW_REG); + if (res < OK) { + logError( + 1, + "%s getFirmwareVersion: unable to read fw_version ERROR %08X\n", + tag, ERROR_FW_VER_READ); + return (res | ERROR_FW_VER_READ); + } + + u8ToU16(fwvers, fw_vers); + if (*fw_vers != 0) { + res = readConfig(ADDR_CONFIG_ID, confid, CONFIG_ID_BYTE); + if (res < OK) { + logError( + 1, + "%s getFirmwareVersion: unable to read config_id ERROR %08X\n", + tag, ERROR_FW_VER_READ); + return (res | ERROR_FW_VER_READ); + } + u8ToU16(confid, config_id); + } else { + *config_id = 0x0000; + } + + logError(0, "%s FW VERS = %04X\n", tag, *fw_vers); + logError(0, "%s CONFIG ID = %04X\n", tag, *config_id); + return OK; +} + +/** +* Retrieve the actual FW data from the system (bin file or header file) +* @param pathToFile name of FW file to load or "NULL" if the FW data should be loaded by a .h file +* @param data pointer to the pointer which will contains the FW data +* @param size pointer to a variable which will contain the size of the loaded data +* @return OK if success or an error code which specify the type of error encountered +*/ +int getFWdata(const char *pathToFile, u8 **data, int *size) +{ + const struct firmware *fw = NULL; + struct device *dev = NULL; + int res, from = 0; + char *path = (char *)pathToFile; + + logError(1, "%s getFWdata starting ...\n", tag); + if (strncmp(pathToFile, "NULL", 4) == 0) { + from = 1; + path = (char *)fts_info->board->default_fw_name; + } + switch (from) { +#ifdef FW_H_FILE + case 1: + logError(1, "%s Read FW from .h file!\n", tag); + *size = FW_SIZE_NAME; + *data = (u8 *)kmalloc((*size) * sizeof(u8), GFP_KERNEL); + if (*data == NULL) { + logError( + 1, + "%s getFWdata: Impossible to allocate memory! ERROR %08X\n", + tag, ERROR_ALLOC); + return ERROR_ALLOC; + } + memcpy(*data, (u8 *)FW_ARRAY_NAME, (*size)); + + break; +#endif + default: + logError(1, "%s Read FW from BIN file %s !\n", tag, path); + dev = getDev(); + + if (dev != NULL) { + res = request_firmware(&fw, path, dev); + if (res == 0) { + *size = fw->size; + *data = (u8 *)kmalloc((*size) * sizeof(u8), + GFP_KERNEL); + if (*data == NULL) { + logError( + 1, + "%s getFWdata: Impossible to allocate memory! ERROR %08X\n", + tag, ERROR_ALLOC); + release_firmware(fw); + return ERROR_ALLOC; + } + memcpy(*data, (u8 *)fw->data, (*size)); + release_firmware(fw); + } else { + logError( + 1, + "%s getFWdata: No File found! ERROR %08X\n", + tag, ERROR_FILE_NOT_FOUND); + return ERROR_FILE_NOT_FOUND; + } + + } else { + logError(1, + "%s getFWdata: No device found! ERROR %08X\n", + tag, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + } + + logError(1, "%s getFWdata Finished!\n", tag); + return OK; +} + +/** +* Perform all the steps to read the FW that should be burnt in the IC from the system and parse it in order to fill a Firmware struct with the relevant info +* @param path name of FW file to load or "NULL" if the FW data should be loaded by a .h file +* @param fw pointer to a Firmware variable which will contains the FW data and info +* @param keep_cx if 1, the CX area will be loaded otherwise will be skipped +* @return OK if success or an error code which specify the type of error encountered +*/ +int readFwFile(const char *path, Firmware *fw, int keep_cx) +{ + int res; + int orig_size; + u8 *orig_data = NULL; + + res = getFWdata(path, &orig_data, &orig_size); + if (res < OK) { + logError( + 1, + "%s readFwFile: impossible retrieve FW... ERROR %08X\n", + tag, ERROR_MEMH_READ); + return (res | ERROR_MEMH_READ); + } + res = parseBinFile(orig_data, orig_size, fw, keep_cx); + if (res < OK) { + logError(1, "%s readFwFile: impossible parse ERROR %08X\n", tag, + ERROR_MEMH_READ); + return (res | ERROR_MEMH_READ); + } + + return OK; +} + +/** +* Perform all the steps necessary to burn the FW into the IC +* @param path name of FW file to load or "NULL" if the FW data should be loaded by a .h file +* @param force if 1, the flashing procedure will be forced and executed regardless the additional info, otherwise the FW in the file will be burnt only if it is newer than the one running in the IC +* @param keep_cx if 1, the CX area will be loaded and burnt otherwise will be skipped and the area will be untouched +* @return OK if success or an error code which specify the type of error encountered +*/ +int flashProcedure(const char *path, int force, int keep_cx) +{ + Firmware fw; + int res; + + fw.data = NULL; + logError(0, "%s Reading Fw file... \n", tag); + res = readFwFile(path, &fw, keep_cx); + if (res < OK) { + logError(1, "%s flashProcedure: ERROR %08X \n", tag, + (res | ERROR_FLASH_PROCEDURE)); + kfree(fw.data); + return (res | ERROR_FLASH_PROCEDURE); + } + logError(0, "%s Fw file read COMPLETED! \n", tag); + + logError(0, "%s Starting flashing procedure... \n", tag); + res = flash_burn(fw, force, keep_cx); + if (res < OK && res != (ERROR_FW_NO_UPDATE | ERROR_FLASH_BURN_FAILED)) { + logError(1, "%s flashProcedure: ERROR %08X \n", tag, + ERROR_FLASH_PROCEDURE); + kfree(fw.data); + return (res | ERROR_FLASH_PROCEDURE); + } + logError(0, "%s flashing procedure Finished!\n", tag); + kfree(fw.data); + + return res; +} + +/** +* Poll the Flash Status Registers after the execution of a command to check if the Flash becomes ready within a timeout +* @param type register to check according to the previous command sent +* @return OK if success or an error code which specify the type of error encountered +*/ +int wait_for_flash_ready(u8 type) +{ + u8 cmd[5] = { FTS_CMD_HW_REG_R, 0x20, 0x00, 0x00, type }; + + u8 readData[2] = { 0 }; + int i, res = -1; + + logError(0, "%s Waiting for flash ready ... \n", tag); + for (i = 0; i < FLASH_RETRY_COUNT && res != 0; i++) { + res = fts_writeRead_dma_safe(cmd, ARRAY_SIZE(cmd), readData, 2); + if (res < OK) { + logError(1, "%s wait_for_flash_ready: ERROR % 08X\n", + tag, ERROR_BUS_W); + } else { +#ifdef I2C_INTERFACE + res = readData[0] & 0x80; +#else + res = readData[1] & 0x80; +#endif + + logError(0, "%s flash status = %d \n", tag, res); + } + mdelay(FLASH_WAIT_BEFORE_RETRY); + } + + if (i == FLASH_RETRY_COUNT && res != 0) { + logError(1, "%s Wait for flash TIMEOUT! ERROR %08X \n", tag, + ERROR_TIMEOUT); + return ERROR_TIMEOUT; + } + + logError(0, "%s Flash READY! \n", tag); + return OK; +} + +/** + * Put the M3 in hold + * @return OK if success or an error code which specify the type of error encountered + */ +int hold_m3(void) +{ + int ret; + u8 cmd[1] = { 0x01 }; + + logError(0, "%s Command m3 hold... \n", tag); + ret = fts_writeU8UX(FTS_CMD_HW_REG_W, ADDR_SIZE_HW_REG, + ADDR_SYSTEM_RESET, cmd, 1); + if (ret < OK) { + logError(1, "%s hold_m3: ERROR %08X\n", tag, ret); + return ret; + } + logError(0, "%s Hold M3 DONE! \n", tag); + +#if !defined(I2C_INTERFACE) && defined(SPI4_WIRE) + logError(0, "%s Setting SPI4 mode... \n", tag); + cmd[0] = 0x10; + ret = fts_writeU8UX(FTS_CMD_HW_REG_W, ADDR_SIZE_HW_REG, + ADDR_GPIO_DIRECTION, cmd, 1); + if (ret < OK) { + logError(1, "%s hold_m3: can not set gpio dir ERROR %08X\n", + tag, ret); + return ret; + } + + cmd[0] = 0x02; + ret = fts_writeU8UX(FTS_CMD_HW_REG_W, ADDR_SIZE_HW_REG, + ADDR_GPIO_PULLUP, cmd, 1); + if (ret < OK) { + logError(1, "%s hold_m3: can not set gpio pull-up ERROR %08X\n", + tag, ret); + return ret; + } + + cmd[0] = 0x07; + ret = fts_writeU8UX(FTS_CMD_HW_REG_W, ADDR_SIZE_HW_REG, + ADDR_GPIO_CONFIG_REG2, cmd, 1); + if (ret < OK) { + logError(1, "%s hold_m3: can not set gpio config ERROR %08X\n", + tag, ret); + return ret; + } + + cmd[0] = 0x30; + ret = fts_writeU8UX(FTS_CMD_HW_REG_W, ADDR_SIZE_HW_REG, + ADDR_GPIO_CONFIG_REG0, cmd, 1); + if (ret < OK) { + logError(1, "%s hold_m3: can not set gpio config ERROR %08X\n", + tag, ret); + return ret; + } + + cmd[0] = SPI4_MASK; + ret = fts_writeU8UX(FTS_CMD_HW_REG_W, ADDR_SIZE_HW_REG, ADDR_ICR, cmd, + 1); + if (ret < OK) { + logError(1, "%s hold_m3: can not set spi4 mode ERROR %08X\n", + tag, ret); + return ret; + } + mdelay(1); +#endif + + return OK; +} + +/** +* Parse the raw data read from a FW file in order to fill properly the fields of a Firmware variable +* @param fw_data raw FW data loaded from system +* @param fw_size size of fw_data +* @param fwData pointer to a Firmware variable which will contain the processed data +* @param keep_cx if 1, the CX area will be loaded and burnt otherwise will be skipped and the area will be untouched +* @return OK if success or an error code which specify the type of error encountered +*/ +int parseBinFile(u8 *fw_data, int fw_size, Firmware *fwData, int keep_cx) +{ + int dimension, index = 0; + u32 temp; + int res, i; + + if (fw_size < FW_HEADER_SIZE + FW_BYTES_ALLIGN || fw_data == NULL) { + logError( + 1, + "%s parseBinFile: Read only %d instead of %d... ERROR %08X\n", + tag, fw_size, FW_HEADER_SIZE + FW_BYTES_ALLIGN, + ERROR_FILE_PARSE); + res = ERROR_FILE_PARSE; + goto END; + } else { + u8ToU32(&fw_data[index], &temp); + if (temp != FW_HEADER_SIGNATURE) { + logError( + 1, + "%s parseBinFile: Wrong Signature %08X ... ERROR %08X\n", + tag, temp, ERROR_FILE_PARSE); + res = ERROR_FILE_PARSE; + goto END; + } + logError(0, "%s parseBinFile: Fw Signature OK!\n", tag); + index += FW_BYTES_ALLIGN; + u8ToU32(&fw_data[index], &temp); + if (temp != FW_FTB_VER) { + logError( + 1, + "%s parseBinFile: Wrong ftb_version %08X ... ERROR %08X\n", + tag, temp, ERROR_FILE_PARSE); + res = ERROR_FILE_PARSE; + goto END; + } + logError(0, "%s parseBinFile: ftb_version OK!\n", tag); + index += FW_BYTES_ALLIGN; + if (fw_data[index] != DCHIP_ID_0 || + fw_data[index + 1] != DCHIP_ID_1) { + logError( + 1, + "%s parseBinFile: Wrong target %02X != %02X %02X != %02X ... ERROR %08X\n", + tag, fw_data[index], DCHIP_ID_0, + fw_data[index + 1], DCHIP_ID_1, + ERROR_FILE_PARSE); + res = ERROR_FILE_PARSE; + goto END; + } + index += FW_BYTES_ALLIGN; + u8ToU32(&fw_data[index], &temp); + logError(1, "%s parseBinFile: FILE SVN REV = %08X\n", tag, + temp); + + index += FW_BYTES_ALLIGN; + u8ToU32(&fw_data[index], &temp); + fwData->fw_ver = temp; + logError(1, "%s parseBinFile: FILE Fw Version = %04X\n", tag, + fwData->fw_ver); + + index += FW_BYTES_ALLIGN; + u8ToU32(&fw_data[index], &temp); + fwData->config_id = temp; + logError(1, "%s parseBinFile: FILE Config Project ID = %08X\n", + tag, temp); + + index += FW_BYTES_ALLIGN; + u8ToU32(&fw_data[index], &temp); + logError(1, "%s parseBinFile: FILE Config Version = %08X\n", + tag, temp); + + index += FW_BYTES_ALLIGN * 2; + + index += FW_BYTES_ALLIGN; + logError(1, "%s parseBinFile: File External Release = ", tag); + for (i = 0; i < EXTERNAL_RELEASE_INFO_SIZE; i++) { + fwData->externalRelease[i] = fw_data[index++]; + logError(1, "%02X ", fwData->externalRelease[i]); + } + logError(1, "\n"); + + u8ToU32(&fw_data[index], &temp); + fwData->sec0_size = temp; + logError(1, "%s parseBinFile: sec0_size = %08X (%d bytes)\n", + tag, fwData->sec0_size, fwData->sec0_size); + + index += FW_BYTES_ALLIGN; + u8ToU32(&fw_data[index], &temp); + fwData->sec1_size = temp; + logError(1, "%s parseBinFile: sec1_size = %08X (%d bytes)\n", + tag, fwData->sec1_size, fwData->sec1_size); + + index += FW_BYTES_ALLIGN; + u8ToU32(&fw_data[index], &temp); + fwData->sec2_size = temp; + logError(1, "%s parseBinFile: sec2_size = %08X (%d bytes) \n", + tag, fwData->sec2_size, fwData->sec2_size); + + index += FW_BYTES_ALLIGN; + u8ToU32(&fw_data[index], &temp); + fwData->sec3_size = temp; + logError(1, "%s parseBinFile: sec3_size = %08X (%d bytes) \n", + tag, fwData->sec3_size, fwData->sec3_size); + + index += FW_BYTES_ALLIGN; + + dimension = fwData->sec0_size + fwData->sec1_size + + fwData->sec2_size + fwData->sec3_size; + temp = fw_size; + + if (dimension + FW_HEADER_SIZE + FW_BYTES_ALLIGN != temp) { + logError( + 1, + "%s parseBinFile: Read only %d instead of %d... ERROR %08X\n", + tag, fw_size, + dimension + FW_HEADER_SIZE + FW_BYTES_ALLIGN, + ERROR_FILE_PARSE); + res = ERROR_FILE_PARSE; + goto END; + } + + fwData->data = + (u8 *)kmalloc(dimension * sizeof(u8), GFP_KERNEL); + if (fwData->data == NULL) { + logError(1, "%s parseBinFile: ERROR %08X\n", tag, + ERROR_ALLOC); + res = ERROR_ALLOC; + goto END; + } + + index += FW_BYTES_ALLIGN; + memcpy(fwData->data, &fw_data[index], dimension); + if (fwData->sec2_size != 0) { + u8ToU16(&fwData->data[fwData->sec0_size + + fwData->sec1_size + FW_CX_VERSION], + &fwData->cx_ver); + + } else { + logError( + 1, + "%s parseBinFile: Initialize cx_ver to default value! \n", + tag); + fwData->cx_ver = systemInfo.u16_cxVer; + } + + logError(1, "%s parseBinFile: CX Version = %04X \n", tag, + fwData->cx_ver); + + fwData->data_size = dimension; + + logError(0, "%s READ FW DONE %d bytes!\n", tag, + fwData->data_size); + res = OK; + goto END; + } + +END: + kfree(fw_data); + return res; +} + +/** + * Enable UVLO and Auto Power Down Mode + * @return OK if success or an error code which specify the type of error + */ +int flash_enable_uvlo_autopowerdown(void) +{ + u8 cmd[6] = { FTS_CMD_HW_REG_W, + 0x20, + 0x00, + 0x00, + FLASH_UVLO_ENABLE_CODE0, + FLASH_UVLO_ENABLE_CODE1 }; + u8 cmd1[6] = { FTS_CMD_HW_REG_W, + 0x20, + 0x00, + 0x00, + FLASH_AUTOPOWERDOWN_ENABLE_CODE0, + FLASH_AUTOPOWERDOWN_ENABLE_CODE1 }; + logError(0, "%s Command enable uvlo ...\n", tag); + if (fts_write_dma_safe(cmd, ARRAY_SIZE(cmd)) < OK) { + logError(1, "%s flash_enable_uvlo_autopowerdown: ERROR %08X\n", + tag, ERROR_BUS_W); + return ERROR_BUS_W; + } + if (fts_write_dma_safe(cmd1, ARRAY_SIZE(cmd1)) < OK) { + logError(1, "%s flash_enable_uvlo_autopowerdown: ERROR %08X\n", + tag, ERROR_BUS_W); + return ERROR_BUS_W; + } + logError(0, "%s Enable uvlo and flash auto power down DONE!\n", tag); + return OK; +} +/** + * Unlock the flash to be programmed + * @return OK if success or an error code which specify the type of error + */ +int flash_unlock(void) +{ + u8 cmd[6] = { FTS_CMD_HW_REG_W, 0x20, 0x00, 0x00, FLASH_UNLOCK_CODE0, + FLASH_UNLOCK_CODE1 }; + + u8 cmd1[6] = { FTS_CMD_HW_REG_W, 0x20, 0x00, 0x00, FLASH_UNLOCK_CODE2, + FLASH_UNLOCK_CODE3 }; + + logError(0, "%s Command unlock ...\n", tag); + if (fts_write_dma_safe(cmd, ARRAY_SIZE(cmd)) < OK) { + logError(1, "%s flash_unlock: ERROR %08X\n", tag, ERROR_BUS_W); + return ERROR_BUS_W; + } + + if (fts_write_dma_safe(cmd1, ARRAY_SIZE(cmd1)) < OK) { + logError(1, "%s Command unlock: ERROR %08X\n", tag, + ERROR_BUS_W); + return ERROR_BUS_W; + } + logError(0, "%s Unlock flash DONE!\n", tag); + + return OK; +} + +/** +* Unlock the flash to be erased +* @return OK if success or an error code which specify the type of error encountered +*/ +int flash_erase_unlock(void) +{ + u8 cmd[6] = { FTS_CMD_HW_REG_W, + 0x20, + 0x00, + 0x00, + FLASH_ERASE_UNLOCK_CODE0, + FLASH_ERASE_UNLOCK_CODE1 }; + + logError(0, "%s Try to erase unlock flash... \n", tag); + + logError(0, "%s Command erase unlock ... \n", tag); + if (fts_write_dma_safe(cmd, ARRAY_SIZE(cmd)) < 0) { + logError(1, "%s flash_erase_unlock: ERROR %08X\n", tag, + ERROR_BUS_W); + return ERROR_BUS_W; + } + + logError(0, "%s Erase Unlock flash DONE! \n", tag); + + return OK; +} + +/** +* Erase the full flash +* @return OK if success or an error code which specify the type of error encountered +*/ +int flash_full_erase(void) +{ + int status; + + u8 cmd1[6] = { FTS_CMD_HW_REG_W, 0x20, 0x00, 0x00, + FLASH_ERASE_CODE0 + 1, 0x00 }; + u8 cmd[6] = { FTS_CMD_HW_REG_W, 0x20, 0x00, 0x00, FLASH_ERASE_CODE0, + FLASH_ERASE_CODE1 }; + + if (fts_write_dma_safe(cmd1, ARRAY_SIZE(cmd1)) < OK) { + logError(1, "%s flash_erase_page_by_page: ERROR %08X\n", tag, + ERROR_BUS_W); + return ERROR_BUS_W; + } + + logError(0, "%s Command full erase sent ... \n", tag); + if (fts_write_dma_safe(cmd, ARRAY_SIZE(cmd)) < OK) { + logError(1, "%s flash_full_erase: ERROR %08X\n", tag, + ERROR_BUS_W); + return ERROR_BUS_W; + } + + status = wait_for_flash_ready(FLASH_ERASE_CODE0); + + if (status != OK) { + logError(1, "%s flash_full_erase: ERROR %08X\n", tag, + ERROR_FLASH_NOT_READY); + return (status | ERROR_FLASH_NOT_READY); + } + + logError(0, "%s Full Erase flash DONE! \n", tag); + + return OK; +} + +/** +* Erase the flash page by page, giving the possibility to skip the CX area and maintain therefore its value +* @param keep_cx if SKIP_PANEL_INIT the Panel Init pages will be skipped, if > SKIP_PANEL_CX_INIT Cx and Panel Init pages otherwise all the pages will be deleted +* @return OK if success or an error code which specify the type of error encountered +*/ +int flash_erase_page_by_page(ErasePage keep_cx) +{ + u8 status, i = 0; + u8 cmd1[6] = { FTS_CMD_HW_REG_W, 0x20, 0x00, 0x00, + FLASH_ERASE_CODE0 + 1, 0x00 }; + u8 cmd[6] = { FTS_CMD_HW_REG_W, 0x20, 0x00, 0x00, + FLASH_ERASE_CODE0, 0xA0 }; + u8 cmd2[9] = { + FTS_CMD_HW_REG_W, 0x20, 0x00, 0x01, 0x28, 0xFF, 0xFF, 0xFF, 0xFF + }; + u8 mask[4] = { 0 }; + + for (i = FLASH_CX_PAGE_START; + i <= FLASH_CX_PAGE_END && keep_cx >= SKIP_PANEL_CX_INIT; i++) { + logError(0, "%s Skipping erase CX page %d! \n", tag, i); + fromIDtoMask(i, mask, 4); + } + + for (i = FLASH_PANEL_PAGE_START; + i <= FLASH_PANEL_PAGE_END && keep_cx >= SKIP_PANEL_INIT; i++) { + logError(0, "%s Skipping erase Panel Init page %d! \n", tag, i); + fromIDtoMask(i, mask, 4); + } + + logError(0, "%s Setting the page mask = ", tag, i); + for (i = 0; i < 4; i++) { + cmd2[5 + i] = cmd2[5 + i] & (~mask[i]); + logError(0, "%02X ", cmd2[5 + i]); + } + + logError(0, "\n%s Writing page mask... \n", tag); + if (fts_write_dma_safe(cmd2, ARRAY_SIZE(cmd2)) < OK) { + logError(1, + "%s flash_erase_page_by_page: Page mask ERROR %08X\n", + tag, ERROR_BUS_W); + return ERROR_BUS_W; + } + + if (fts_write_dma_safe(cmd1, ARRAY_SIZE(cmd1)) < OK) { + logError( + 1, + "%s flash_erase_page_by_page: Disable info ERROR %08X\n", + tag, ERROR_BUS_W); + return ERROR_BUS_W; + } + + logError(0, "%s Command erase pages sent ... \n", tag); + if (fts_write_dma_safe(cmd, ARRAY_SIZE(cmd)) < OK) { + logError(1, "%s flash_erase_page_by_page: Erase ERROR %08X\n", + tag, ERROR_BUS_W); + return ERROR_BUS_W; + } + + status = wait_for_flash_ready(FLASH_ERASE_CODE0); + + if (status != OK) { + logError(1, "%s flash_erase_page_by_page: ERROR % 08X\n", tag, + ERROR_FLASH_NOT_READY); + return (status | ERROR_FLASH_NOT_READY); + } + + logError(0, "%s Erase flash page by page DONE! \n", tag); + + return OK; +} + +/** +* Start the DMA procedure which actually transfer and burn the data loaded from memory into the Flash +* @return OK if success or an error code which specify the type of error encountered +*/ +int start_flash_dma(void) +{ + int status; + u8 cmd[12] = { FLASH_CMD_WRITE_REGISTER, + 0x20, + 0x00, + 0x00, + 0x6B, + 0x00, + 0x40, + 0x42, + 0x0F, + 0x00, + 0x00, + FLASH_DMA_CODE1 }; + + logError(0, "%s Command flash DMA ... \n", tag); + if (fts_write_dma_safe(cmd, ARRAY_SIZE(cmd)) < OK) { + logError(1, "%s start_flash_dma: ERROR %08X\n", tag, + ERROR_BUS_W); + return ERROR_BUS_W; + } + + status = wait_for_flash_ready(FLASH_DMA_CODE0); + + if (status != OK) { + logError(1, "%s start_flash_dma: ERROR %08X\n", tag, + ERROR_FLASH_NOT_READY); + return (status | ERROR_FLASH_NOT_READY); + } + + logError(0, "%s flash DMA DONE! \n", tag); + + return OK; +} + +/** +* Copy the FW data that should be burnt in the Flash into the memory and then the DMA will take care about burning it into the Flash +* @param address address in memory where to copy the data, possible values are FLASH_ADDR_CODE, FLASH_ADDR_CONFIG, FLASH_ADDR_CX +* @param data pointer to an array of byte which contain the data that should be copied into the memory +* @param size size of data +* @return OK if success or an error code which specify the type of error encountered +*/ +int fillFlash(u32 address, u8 *data, int size) +{ + int remaining = size, index = 0; + int toWrite = 0; + int byteBlock = 0; + int wheel = 0; + u32 addr = 0; + int res; + int delta; + u8 *buff = NULL; + u8 buff2[12] = { 0 }; + + buff = (u8 *)kmalloc((DMA_CHUNK + 5) * sizeof(u8), GFP_KERNEL); + if (buff == NULL) { + logError(1, "%s fillFlash: ERROR %08X\n", tag, ERROR_ALLOC); + return ERROR_ALLOC; + } + + while (remaining > 0) { + byteBlock = 0; + + addr = 0x00100000; + + while (byteBlock < FLASH_CHUNK && remaining > 0) { + index = 0; + if (remaining >= DMA_CHUNK) { + if ((byteBlock + DMA_CHUNK) <= FLASH_CHUNK) { + toWrite = DMA_CHUNK; + remaining -= DMA_CHUNK; + byteBlock += DMA_CHUNK; + } else { + delta = FLASH_CHUNK - byteBlock; + toWrite = delta; + remaining -= delta; + byteBlock += delta; + } + } else { + if ((byteBlock + remaining) <= FLASH_CHUNK) { + toWrite = remaining; + byteBlock += remaining; + remaining = 0; + + } else { + delta = FLASH_CHUNK - byteBlock; + toWrite = delta; + remaining -= delta; + byteBlock += delta; + } + } + + buff[index++] = FTS_CMD_HW_REG_W; + buff[index++] = (u8)((addr & 0xFF000000) >> 24); + buff[index++] = (u8)((addr & 0x00FF0000) >> 16); + buff[index++] = (u8)((addr & 0x0000FF00) >> 8); + buff[index++] = (u8)(addr & 0x000000FF); + + memcpy(&buff[index], data, toWrite); + if (fts_write_dma_safe(buff, index + toWrite) < OK) { + logError(1, "%s fillFlash: ERROR %08X\n", tag, + ERROR_BUS_W); + kfree(buff); + return ERROR_BUS_W; + } + addr += toWrite; + data += toWrite; + } + + byteBlock = byteBlock / 4 - 1; + index = 0; + + buff2[index++] = FLASH_CMD_WRITE_REGISTER; + buff2[index++] = 0x20; + buff2[index++] = 0x00; + buff2[index++] = 0x00; + buff2[index++] = FLASH_DMA_CONFIG; + buff2[index++] = 0x00; + buff2[index++] = 0x00; + + addr = address + ((wheel * FLASH_CHUNK) / 4); + buff2[index++] = (u8)((addr & 0x000000FF)); + buff2[index++] = (u8)((addr & 0x0000FF00) >> 8); + buff2[index++] = (u8)(byteBlock & 0x000000FF); + buff2[index++] = (u8)((byteBlock & 0x0000FF00) >> 8); + buff2[index++] = 0x00; + + logError( + 0, + "%s DMA Command = %02X , address = %02X %02X, words = %02X %02X \n", + tag, buff2[0], buff2[8], buff2[7], buff2[10], buff2[9]); + + if (fts_write_dma_safe(buff2, index) < OK) { + logError( + 1, + "%s Error during filling Flash! ERROR %08X \n", + tag, ERROR_BUS_W); + kfree(buff); + return ERROR_BUS_W; + } + + res = start_flash_dma(); + if (res < OK) { + logError( + 1, + "%s Error during flashing DMA! ERROR %08X \n", + tag, res); + kfree(buff); + return res; + } + wheel++; + } + kfree(buff); + return OK; +} + +/** +* Execute the procedure to burn a FW in FTM4/FTI IC +* @param fw structure which contain the FW to be burnt +* @param force_burn if >0, the flashing procedure will be forced and executed regardless the additional info, otherwise the FW in the file will be burnt only if it is newer than the one running in the IC +* @param keep_cx if 1, the function preserve the CX/Panel Init area otherwise will be cleared +* @return OK if success or an error code which specify the type of error encountered +*/ +int flash_burn(Firmware fw, int force_burn, int keep_cx) +{ + int res; + + if (!force_burn) { + if (systemInfo.u16_fwVer != fw.fw_ver) + goto start; + for (res = EXTERNAL_RELEASE_INFO_SIZE - 1; res >= 0; res--) { + if (fw.externalRelease[res] != + systemInfo.u8_releaseInfo[res]) + goto start; + } + logError( + 1, + "%s flash_burn: Firmware in the chip newer or equal to the one to burn! NO UPDATE ERROR %08X \n", + tag, ERROR_FW_NO_UPDATE); + return (ERROR_FW_NO_UPDATE | ERROR_FLASH_BURN_FAILED); + } else { + if (force_burn == CRC_CX && fw.sec2_size == 0) { + for (res = EXTERNAL_RELEASE_INFO_SIZE - 1; res >= 0; + res--) { + if (fw.externalRelease[res] > + systemInfo.u8_releaseInfo[res]) + force_burn = 0; + goto start; + } + logError( + 1, + "%s flash_burn: CRC in CX but fw does not contain CX data! NO UPDATE ERROR %08X \n", + tag, ERROR_FW_NO_UPDATE); + return (ERROR_FW_NO_UPDATE | ERROR_FLASH_BURN_FAILED); + } + } + +start: + logError(0, "%s Programming Procedure for flashing started: \n\n", tag); + + logError(0, "%s 1) SYSTEM RESET: \n", tag); + res = fts_system_reset(); + if (res < 0) { + logError(1, "%s system reset FAILED!\n", tag); + if (res != (ERROR_SYSTEM_RESET_FAIL | ERROR_TIMEOUT)) + return (res | ERROR_FLASH_BURN_FAILED); + } else + logError(0, "%s system reset COMPLETED!\n\n", tag); + msleep(30); /* required by hw during flash procedure */ + logError(0, "%s 2) HOLD M3 : \n", tag); + res = hold_m3(); + if (res < OK) { + logError(1, "%s hold_m3 FAILED!\n", tag); + return (res | ERROR_FLASH_BURN_FAILED); + } else + logError(0, "%s hold_m3 COMPLETED!\n\n", tag); + + logError(0, "%s 3) ENABLE UVLO AND AUTO POWER DOWN MODE :\n", tag); + res = flash_enable_uvlo_autopowerdown(); + if (res < OK) { + logError(1, "%s flash_enable_uvlo_autopowerdown FAILED!\n", + tag); + return res | ERROR_FLASH_BURN_FAILED; + } else + logError(0, + "%s flash_enable_uvlo_autopowerdown COMPLETED!\n\n", + tag); + logError(0, "%s 4) FLASH UNLOCK: \n", tag); + res = flash_unlock(); + if (res < OK) { + logError(1, "%s flash unlock FAILED! ERROR %08X\n", tag, + ERROR_FLASH_BURN_FAILED); + return (res | ERROR_FLASH_BURN_FAILED); + } else { + logError(0, "%s flash unlock COMPLETED!\n\n", tag); + } + + logError(0, "%s 5) FLASH ERASE UNLOCK: \n", tag); + res = flash_erase_unlock(); + if (res < 0) { + logError(1, "%s flash unlock FAILED! ERROR %08X\n", tag, + ERROR_FLASH_BURN_FAILED); + return (res | ERROR_FLASH_BURN_FAILED); + } else { + logError(0, "%s flash unlock COMPLETED!\n\n", tag); + } + + logError(0, "%s 6) FLASH ERASE: \n", tag); + if (keep_cx > 0) { + if (fw.sec2_size != 0 && force_burn == CRC_CX) + res = flash_erase_page_by_page(SKIP_PANEL_INIT); + else + res = flash_erase_page_by_page(SKIP_PANEL_CX_INIT); + } else { + res = flash_erase_page_by_page(SKIP_PANEL_INIT); + if (fw.sec2_size == 0) + logError( + 1, + "%s WARNING!!! Erasing CX memory but no CX in fw file! touch will not work right after fw update! \n", + tag); + } + + if (res < OK) { + logError(1, "%s flash erase FAILED! ERROR %08X\n", tag, + ERROR_FLASH_BURN_FAILED); + return (res | ERROR_FLASH_BURN_FAILED); + } else { + logError(0, "%s flash erase COMPLETED!\n\n", tag); + } + + logError(0, "%s 7) LOAD PROGRAM: \n", tag); + res = fillFlash(FLASH_ADDR_CODE, &fw.data[0], fw.sec0_size); + if (res < OK) { + logError(1, "%s load program ERROR %08X\n", tag, + ERROR_FLASH_BURN_FAILED); + return (res | ERROR_FLASH_BURN_FAILED); + } + logError(1, "%s load program DONE!\n", tag); + + logError(0, "%s 8) LOAD CONFIG: \n", tag); + res = fillFlash(FLASH_ADDR_CONFIG, &(fw.data[fw.sec0_size]), + fw.sec1_size); + if (res < OK) { + logError(1, "%s load config ERROR %08X\n", tag, + ERROR_FLASH_BURN_FAILED); + return (res | ERROR_FLASH_BURN_FAILED); + } + logError(1, "%s load config DONE!\n", tag); + + if (fw.sec2_size != 0) { + if ((force_burn == CRC_CX) || (keep_cx <= 0)) { + logError(0, "%s 8.1) LOAD CX: \n", tag); + res = fillFlash(FLASH_ADDR_CX, + &(fw.data[fw.sec0_size + fw.sec1_size]), + fw.sec2_size); + if (res < OK) { + logError(1, "%s load cx ERROR %08X\n", tag, + ERROR_FLASH_BURN_FAILED); + return (res | ERROR_FLASH_BURN_FAILED); + } + logError(1, "%s load cx DONE!\n", tag); + } + } + + logError(0, "%s Flash burn COMPLETED!\n\n", tag); + + logError(0, "%s 9) SYSTEM RESET: \n", tag); + res = fts_system_reset(); + if (res < 0) { + logError(1, "%s system reset FAILED! ERROR %08X\n", tag, + ERROR_FLASH_BURN_FAILED); + return (res | ERROR_FLASH_BURN_FAILED); + } + logError(0, "%s system reset COMPLETED!\n\n", tag); + + logError(0, "%s 10) FINAL CHECK: \n", tag); + res = readSysInfo(0); + if (res < 0) { + logError( + 1, + "%s flash_burn: Unable to retrieve Chip INFO! ERROR %08X\n", + tag, ERROR_FLASH_BURN_FAILED); + return (res | ERROR_FLASH_BURN_FAILED); + } + + for (res = 0; res < EXTERNAL_RELEASE_INFO_SIZE; res++) { + if (fw.externalRelease[res] != systemInfo.u8_releaseInfo[res]) { + logError( + 1, + "%s Firmware in the chip different from the one that was burn! \n", + tag); + return ERROR_FLASH_BURN_FAILED; + } + } + + logError(0, "%s Final check OK! \n", tag); + + return OK; +} diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFlash.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFlash.h new file mode 100644 index 000000000000..30742af22080 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFlash.h @@ -0,0 +1,106 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS API for Flashing the IC * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsFlash.h +* \brief Contains all the definitions and structs to handle the FW update process +*/ + +#ifndef FTS_FLASH_H +#define FTS_FLASH_H + +#include "ftsSoftware.h" + +/*Flash possible status*/ +#define FLASH_READY 0 /*value to indicate that the flash is ready*/ +#define FLASH_BUSY 1 /*value to indicate that the flash is busy*/ +#define FLASH_UNKNOWN -1 /*value to indicate an unknown status of the flash*/ + +#define FLASH_STATUS_BYTES \ + 1 /*number of bytes to check for read the flash status*/ + +/*Flash timing parameters*/ +#define FLASH_RETRY_COUNT 200 /*number of attemps to read the flash status*/ +#define FLASH_WAIT_BEFORE_RETRY \ + 50 /*time to wait in ms between one status reading and another*/ + +#ifdef FW_H_FILE +#define PATH_FILE_FW "NULL" +#else +#define PATH_FILE_FW "st_fts.ftb" /*new FW bin file name*/ +#endif + +#define FLASH_CHUNK \ + (64 * \ + 1024) /*Max number of bytes that the DMA can burn on the flash in one shot in FTI*/ +#define DMA_CHUNK \ + 32 /*Max number of bytes that can be written in I2C to the DMA*/ + +/** + * Define which kind of erase page by page should be performed + */ +typedef enum { + ERASE_ALL = 0, /*erase all the pages*/ + SKIP_PANEL_INIT = 1, /*skip erase Panel Init Pages*/ + SKIP_PANEL_CX_INIT = 2 /*skip erase Panel Init and CX Pages*/ +} ErasePage; + +/** @addtogroup fw_file + * @{ + */ + +/** +* Struct which contains information and data of the FW that should be burnt into the IC +*/ +typedef struct { + u8 *data; /*pointer to an array of bytes which represent the FW data*/ + u16 fw_ver; /*FW version of the FW file*/ + u16 config_id; /*Config ID of the FW file*/ + u16 cx_ver; /*Cx version of the FW file*/ + u8 externalRelease + [EXTERNAL_RELEASE_INFO_SIZE]; /*External Release Info of the FW file*/ + int data_size; /*dimension of data (the actual data to be burnt)*/ + u32 sec0_size; /*dimension of section 0 (FW) in .ftb file*/ + u32 sec1_size; /*dimension of section 1 (Config) in .ftb file*/ + u32 sec2_size; /*dimension of section 2 (Cx) in .ftb file*/ + u32 sec3_size; /*dimension of section 3 (TBD) in .ftb file*/ + +} Firmware; + +/** @}*/ + +/** @addtogroup flash_command + * @{ + */ + +int wait_for_flash_ready(u8 type); +int hold_m3(void); +int flash_erase_unlock(void); +int flash_full_erase(void); +int flash_erase_page_by_page(ErasePage keep_cx); +int start_flash_dma(void); +int fillFlash(u32 address, u8 *data, int size); + +int flash_unlock(void); +int getFirmwareVersion(u16 *fw_vers, u16 *config_id); +int getFWdata(const char *pathToFile, u8 **data, int *size); +int parseBinFile(u8 *fw_data, int fw_size, Firmware *fw, int keep_cx); +int readFwFile(const char *path, Firmware *fw, int keep_cx); +int flash_burn(Firmware fw, int force_burn, int keep_cx); +int flashProcedure(const char *path, int force, int keep_cx); +int flash_enable_uvlo_autopowerdown(void); +#endif + +/** @}*/ diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFrame.c b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFrame.c new file mode 100644 index 000000000000..b9ec5a42b058 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFrame.c @@ -0,0 +1,395 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS functions for getting frames * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsFrame.c +* \brief Contains all the functions to work with frames +*/ + +#include "ftsCompensation.h" +#include "ftsCore.h" +#include "ftsError.h" +#include "ftsFrame.h" +#include "ftsHardware.h" +#include "ftsIO.h" +#include "ftsSoftware.h" +#include "ftsTool.h" +#include "ftsTime.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern SysInfo systemInfo; + +/** + * Read the channels lengths from the config memory + * @return OK if success or an error code which specify the type of error encountered + */ +int getChannelsLength(void) +{ + int ret; + u8 data[2]; + + if (data == NULL) { + logError(1, "%s getChannelsLength: ERROR %08X\n", tag, + ERROR_ALLOC); + return ERROR_ALLOC; + } + + ret = readConfig(ADDR_CONFIG_SENSE_LEN, data, 2); + if (ret < OK) { + logError(1, "%s getChannelsLength: ERROR %08X\n", tag, ret); + + return ret; + } + + systemInfo.u8_scrRxLen = (int)data[0]; + systemInfo.u8_scrTxLen = (int)data[1]; + + logError(0, "%s Force_len = %d Sense_Len = %d \n", tag, + systemInfo.u8_scrTxLen, systemInfo.u8_scrRxLen); + + return OK; +} + +/** +* Read and pack the frame data related to the nodes +* @param address address in memory when the frame data node start +* @param size amount of data to read +* @param frame pointer to an array of bytes which will contain the frame node data +* @return OK if success or an error code which specify the type of error encountered +*/ +int getFrameData(u16 address, int size, short *frame) +{ + int i, j, ret; + u8 *data = (u8 *)kmalloc(size * sizeof(u8), GFP_KERNEL); + if (data == NULL) { + logError(1, "%s getFrameData: ERROR %08X\n", tag, ERROR_ALLOC); + return ERROR_ALLOC; + } + + ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, address, data, + size, DUMMY_FRAMEBUFFER); + if (ret < OK) { + logError(1, "%s getFrameData: ERROR %08X\n", tag, ERROR_BUS_R); + kfree(data); + return ERROR_BUS_R; + } + j = 0; + for (i = 0; i < size; i += 2) { + frame[j] = (short)((data[i + 1] << 8) + data[i]); + j++; + } + kfree(data); + return OK; +} + +/** + * Return the number of Sense Channels (Rx) + * @return number of Rx channels + */ +int getSenseLen(void) +{ + if (systemInfo.u8_scrRxLen == 0) { + getChannelsLength(); + } + return systemInfo.u8_scrRxLen; +} + +/** + * Return the number of Force Channels (Tx) + * @return number of Tx channels + */ +int getForceLen(void) +{ + if (systemInfo.u8_scrTxLen == 0) { + getChannelsLength(); + } + return systemInfo.u8_scrTxLen; +} + +/******************** New API **************************/ + +/** +* Read a MS Frame from frame buffer memory +* @param type type of MS frame to read +* @param frame pointer to MutualSenseFrame variable which will contain the data +* @return OK if success or an error code which specify the type of error encountered +*/ +int getMSFrame3(MSFrameType type, MutualSenseFrame *frame) +{ + u16 offset; + int ret, force_len, sense_len; + + force_len = getForceLen(); + sense_len = getSenseLen(); + + frame->node_data = NULL; + + logError(0, "%s %s: Starting to get frame %02X \n", tag, __func__, + type); + switch (type) { + case MS_RAW: + offset = systemInfo.u16_msTchRawAddr; + goto LOAD_NORM; + case MS_FILTER: + offset = systemInfo.u16_msTchFilterAddr; + + goto LOAD_NORM; + case MS_STRENGTH: + offset = systemInfo.u16_msTchStrenAddr; + goto LOAD_NORM; + case MS_BASELINE: + offset = systemInfo.u16_msTchBaselineAddr; +LOAD_NORM: + if (force_len == 0 || sense_len == 0) { + logError( + 1, + "%s %s: number of channels not initialized ERROR %08X\n", + tag, __func__, ERROR_CH_LEN); + return (ERROR_CH_LEN | ERROR_GET_FRAME); + } + + break; + + case MS_KEY_RAW: + offset = systemInfo.u16_keyRawAddr; + goto LOAD_KEY; + case MS_KEY_FILTER: + offset = systemInfo.u16_keyFilterAddr; + goto LOAD_KEY; + case MS_KEY_STRENGTH: + offset = systemInfo.u16_keyStrenAddr; + goto LOAD_KEY; + case MS_KEY_BASELINE: + offset = systemInfo.u16_keyBaselineAddr; +LOAD_KEY: + if (systemInfo.u8_keyLen == 0) { + logError( + 1, + "%s %s: number of channels not initialized ERROR %08X\n", + tag, __func__, ERROR_CH_LEN); + return (ERROR_CH_LEN | ERROR_GET_FRAME); + } + force_len = 1; + sense_len = systemInfo.u8_keyLen; + break; + + case FRC_RAW: + offset = systemInfo.u16_frcRawAddr; + goto LOAD_FRC; + case FRC_FILTER: + offset = systemInfo.u16_frcFilterAddr; + goto LOAD_FRC; + case FRC_STRENGTH: + offset = systemInfo.u16_frcStrenAddr; + goto LOAD_FRC; + case FRC_BASELINE: + offset = systemInfo.u16_frcBaselineAddr; +LOAD_FRC: + if (force_len == 0) { + logError( + 1, + "%s %s: number of channels not initialized ERROR %08X\n", + tag, __func__, ERROR_CH_LEN); + return (ERROR_CH_LEN | ERROR_GET_FRAME); + } + sense_len = 1; + break; + default: + logError(1, "%s %s: Invalid type ERROR %08X\n", tag, __func__, + ERROR_OP_NOT_ALLOW | ERROR_GET_FRAME); + return ERROR_OP_NOT_ALLOW | ERROR_GET_FRAME; + } + + frame->node_data_size = ((force_len)*sense_len); + frame->header.force_node = force_len; + frame->header.sense_node = sense_len; + frame->header.type = type; + + logError(0, "%s %s: Force_len = %d Sense_len = %d Offset = %04X \n", + tag, __func__, force_len, sense_len, offset); + + frame->node_data = (short *)kmalloc( + frame->node_data_size * sizeof(short), GFP_KERNEL); + if (frame->node_data == NULL) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, + ERROR_ALLOC | ERROR_GET_FRAME); + return ERROR_ALLOC | ERROR_GET_FRAME; + } + + ret = getFrameData(offset, frame->node_data_size * BYTES_PER_NODE, + (frame->node_data)); + if (ret < OK) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, + ERROR_GET_FRAME_DATA); + kfree(frame->node_data); + frame->node_data = NULL; + return (ret | ERROR_GET_FRAME_DATA | ERROR_GET_FRAME); + } + logError(0, "%s Frame acquired! \n", tag); + return frame->node_data_size; +} + +/** +* Read a SS Frame from frame buffer +* @param type type of SS frame to read +* @param frame pointer to SelfSenseFrame variable which will contain the data +* @return OK if success or an error code which specify the type of error encountered +*/ +int getSSFrame3(SSFrameType type, SelfSenseFrame *frame) +{ + u16 offset_force, offset_sense; + int ret; + + frame->force_data = NULL; + frame->sense_data = NULL; + + frame->header.force_node = getForceLen(); + frame->header.sense_node = getSenseLen(); + + if (frame->header.force_node == 0 || frame->header.sense_node == 0) { + logError( + 1, + "%s %s: number of channels not initialized ERROR %08X\n", + tag, __func__, ERROR_CH_LEN); + return (ERROR_CH_LEN | ERROR_GET_FRAME); + } + + logError(0, "%s %s: Starting to get frame %02X \n", tag, __func__, + type); + switch (type) { + case SS_RAW: + offset_force = systemInfo.u16_ssTchTxRawAddr; + offset_sense = systemInfo.u16_ssTchRxRawAddr; + break; + case SS_FILTER: + offset_force = systemInfo.u16_ssTchTxFilterAddr; + offset_sense = systemInfo.u16_ssTchRxFilterAddr; + break; + case SS_STRENGTH: + offset_force = systemInfo.u16_ssTchTxStrenAddr; + offset_sense = systemInfo.u16_ssTchRxStrenAddr; + break; + case SS_BASELINE: + offset_force = systemInfo.u16_ssTchTxBaselineAddr; + offset_sense = systemInfo.u16_ssTchRxBaselineAddr; + break; + + case SS_HVR_RAW: + offset_force = systemInfo.u16_ssHvrTxRawAddr; + offset_sense = systemInfo.u16_ssHvrRxRawAddr; + break; + case SS_HVR_FILTER: + offset_force = systemInfo.u16_ssHvrTxFilterAddr; + offset_sense = systemInfo.u16_ssHvrRxFilterAddr; + break; + case SS_HVR_STRENGTH: + offset_force = systemInfo.u16_ssHvrTxStrenAddr; + offset_sense = systemInfo.u16_ssHvrRxStrenAddr; + break; + case SS_HVR_BASELINE: + offset_force = systemInfo.u16_ssHvrTxBaselineAddr; + offset_sense = systemInfo.u16_ssHvrRxBaselineAddr; + break; + + case SS_PRX_RAW: + offset_force = systemInfo.u16_ssPrxTxRawAddr; + offset_sense = systemInfo.u16_ssPrxRxRawAddr; + break; + case SS_PRX_FILTER: + offset_force = systemInfo.u16_ssPrxTxFilterAddr; + offset_sense = systemInfo.u16_ssPrxRxFilterAddr; + break; + case SS_PRX_STRENGTH: + offset_force = systemInfo.u16_ssPrxTxStrenAddr; + offset_sense = systemInfo.u16_ssPrxRxStrenAddr; + break; + case SS_PRX_BASELINE: + offset_force = systemInfo.u16_ssPrxTxBaselineAddr; + offset_sense = systemInfo.u16_ssPrxRxBaselineAddr; + break; + + default: + logError(1, "%s %s: Invalid type ERROR %08X\n", tag, __func__, + ERROR_OP_NOT_ALLOW | ERROR_GET_FRAME); + return ERROR_OP_NOT_ALLOW | ERROR_GET_FRAME; + } + + frame->header.type = type; + + logError( + 0, + "%s %s: Force_len = %d Sense_len = %d Offset_force = %04X Offset_sense = %04X \n", + tag, __func__, frame->header.force_node, + frame->header.sense_node, offset_force, offset_sense); + + frame->force_data = (short *)kmalloc( + frame->header.force_node * sizeof(short), GFP_KERNEL); + if (frame->force_data == NULL) { + logError(1, "%s %s: can not allocate force_data ERROR %08X\n", + tag, __func__, ERROR_ALLOC | ERROR_GET_FRAME); + return ERROR_ALLOC | ERROR_GET_FRAME; + } + + frame->sense_data = (short *)kmalloc( + frame->header.sense_node * sizeof(short), GFP_KERNEL); + if (frame->sense_data == NULL) { + kfree(frame->force_data); + frame->force_data = NULL; + logError(1, "%s %s: can not allocate sense_data ERROR %08X\n", + tag, __func__, ERROR_ALLOC | ERROR_GET_FRAME); + return ERROR_ALLOC | ERROR_GET_FRAME; + } + + ret = getFrameData(offset_force, + frame->header.force_node * BYTES_PER_NODE, + (frame->force_data)); + if (ret < OK) { + logError(1, + "%s %s: error while reading force data ERROR %08X\n", + tag, __func__, ERROR_GET_FRAME_DATA); + kfree(frame->force_data); + frame->force_data = NULL; + kfree(frame->sense_data); + frame->sense_data = NULL; + return (ret | ERROR_GET_FRAME_DATA | ERROR_GET_FRAME); + } + + ret = getFrameData(offset_sense, + frame->header.sense_node * BYTES_PER_NODE, + (frame->sense_data)); + if (ret < OK) { + logError(1, + "%s %s: error while reading sense data ERROR %08X\n", + tag, __func__, ERROR_GET_FRAME_DATA); + kfree(frame->force_data); + frame->force_data = NULL; + kfree(frame->sense_data); + frame->sense_data = NULL; + return (ret | ERROR_GET_FRAME_DATA | ERROR_GET_FRAME); + } + + logError(0, "%s Frame acquired! \n", tag); + return frame->header.force_node + frame->header.sense_node; +} diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFrame.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFrame.h new file mode 100644 index 000000000000..bade71c39e67 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsFrame.h @@ -0,0 +1,92 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS functions for getting frames * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsFrame.h +* \brief Contains all the definitions and structs to work with frames +*/ + +#ifndef FTS_FRAME_H +#define FTS_FRAME_H + +#include "ftsSoftware.h" + +/*Number of data bytes for each node */ +#define BYTES_PER_NODE 2 /*number of data bytes for each node*/ + +#define RETRY_FRAME_DATA_READ 2 /*max number of attempts to read a frame*/ + +/** +* Possible types of MS frames +*/ +typedef enum { + MS_RAW = 0, /*Mutual Sense Raw Frame*/ + MS_FILTER = 1, /*Mutual Sense Filtered Frame*/ + MS_STRENGTH = 2, /*Mutual Sense Strength Frame (Baseline-Raw)*/ + MS_BASELINE = 3, /*Mutual Sense Baseline Frame*/ + MS_KEY_RAW = 4, /*Mutual Sense Key Raw Frame*/ + MS_KEY_FILTER = 5, /*Mutual Sense Key Filter Frame*/ + MS_KEY_STRENGTH = 6, /*Mutual Sense Key Strength Frame (Baseline-Raw)*/ + MS_KEY_BASELINE = 7, /*Mutual Sense Key Baseline Frame*/ + FRC_RAW = 8, /*Force Raw Frame*/ + FRC_FILTER = 9, /*Force Filtered Frame*/ + FRC_STRENGTH = 10, /*Force Strength Frame (Baseline-Raw)*/ + FRC_BASELINE = 11 /*Force Baseline Frame*/ +} MSFrameType; + +/** +* Possible types of SS frames +*/ +typedef enum { + SS_RAW = 0, /*Self Sense Raw Frame*/ + SS_FILTER = 1, /*Self Sense Filtered Frame*/ + SS_STRENGTH = 2, /*Self Sense Strength Frame (Baseline-Raw)*/ + SS_BASELINE = 3, /*Self Sense Baseline Frame*/ + SS_HVR_RAW = 4, /*Self Sense Hover Raw Frame*/ + SS_HVR_FILTER = 5, /*Self Sense Hover Filter Frame*/ + SS_HVR_STRENGTH = 6, /*Self Sense Hover Strength Frame (Baseline-Raw)*/ + SS_HVR_BASELINE = 7, /*Self Sense Hover Baseline Frame*/ + SS_PRX_RAW = 8, /*Self Sense Proximity Raw Frame*/ + SS_PRX_FILTER = 9, /*Self Sense Proximity Filtered Frame*/ + SS_PRX_STRENGTH = + 10, /*Self Sense Proximity Strength Frame (Baseline-Raw)*/ + SS_PRX_BASELINE = 11 /*Self Sense Proximity Baseline Frame*/ +} SSFrameType; + +/** +* Struct which contains the data of a MS Frame +*/ +typedef struct { + DataHeader header; /*Header which contain basic info of the frame*/ + short *node_data; /*Data of the frame*/ + int node_data_size; /*Dimension of the data of the frame*/ +} MutualSenseFrame; + +/** +* Struct which contains the data of a SS Frame +*/ +typedef struct { + DataHeader header; /*Header which contain basic info of the frame*/ + short *force_data; /*Force Channels Data*/ + short *sense_data; /*Sense Channels Data*/ +} SelfSenseFrame; + +int getChannelsLength(void); +int getFrameData(u16 address, int size, short *frame); +int getSenseLen(void); +int getForceLen(void); +int getMSFrame3(MSFrameType type, MutualSenseFrame *frame); +int getSSFrame3(SSFrameType type, SelfSenseFrame *frame); +#endif diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsGesture.c b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsGesture.c new file mode 100644 index 000000000000..32457f9a427a --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsGesture.c @@ -0,0 +1,363 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS Gesture Utilities * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsGesture.c +* \brief Contains all the functions and variable to handle the Gesture Detection features +*/ + +#include "ftsSoftware.h" +#include "ftsCore.h" +#include "ftsError.h" +#include "ftsGesture.h" +#include "ftsIO.h" +#include "ftsTime.h" +#include "ftsTool.h" + +static u8 gesture_mask[GESTURE_MASK_SIZE] = { 0 }; +u16 gesture_coordinates_x[GESTURE_MAX_COORDS_PAIRS_REPORT] = { 0 }; +u16 gesture_coordinates_y[GESTURE_MAX_COORDS_PAIRS_REPORT] = { 0 }; +int gesture_coords_reported = ERROR_OP_NOT_ALLOW; +static u8 refreshGestureMask; +struct mutex gestureMask_mutex; + +/** + * Update the gesture mask stored in the driver and have to be used in gesture mode + * @param mask pointer to a byte array which store the gesture mask update that want to be performed. + * @param size dimension in byte of mask. This size can be <= GESTURE_MASK_SIZE. If size < GESTURE_MASK_SIZE the bytes of mask are considering continuos and starting from the less significant byte. + * @param en 0 = enable the gestures set in mask, 1 = disable the gestures set in mask + * @return OK if success or an error code which specify the type of error encountered + */ +int updateGestureMask(u8 *mask, int size, int en) +{ + u8 temp; + int i; + + if (mask != NULL) { + if (size <= GESTURE_MASK_SIZE) { + if (en == FEAT_ENABLE) { + mutex_lock(&gestureMask_mutex); + logError( + 0, + "%s updateGestureMask: setting gesture mask to enable...\n", + tag); + if (mask != NULL) { + for (i = 0; i < size; i++) { + gesture_mask[i] = + gesture_mask[i] | + mask[i]; + } + } + refreshGestureMask = 1; + logError( + 0, + "%s updateGestureMask: gesture mask to enable SET! \n", + tag); + mutex_unlock(&gestureMask_mutex); + return OK; + } + + else if (en == FEAT_DISABLE) { + mutex_lock(&gestureMask_mutex); + logError( + 0, + "%s updateGestureMask: setting gesture mask to disable...\n", + tag); + for (i = 0; i < size; i++) { + temp = gesture_mask[i] ^ mask[i]; + gesture_mask[i] = temp & + gesture_mask[i]; + } + logError( + 0, + "%s updateGestureMask: gesture mask to disable SET! \n", + tag); + refreshGestureMask = 1; + mutex_unlock(&gestureMask_mutex); + return OK; + } else { + logError( + 1, + "updateGestureMask: Enable parameter Invalid! %d != %d or %d ERROR %08X", + tag, FEAT_DISABLE, FEAT_ENABLE, + ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + } else { + logError( + 1, + "%s updateGestureMask: Size not valid! %d > %d ERROR %08X \n", + tag, size, GESTURE_MASK_SIZE); + return ERROR_OP_NOT_ALLOW; + } + } else { + logError(1, "%s updateGestureMask: Mask NULL! ERROR %08X \n", + tag, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } +} + +/** + * Enable in the FW the gesture mask to be used in gesture mode + * @param mask pointer to a byte array which store the gesture mask update that want to be sent to the FW, if NULL, will be used gesture_mask set previously without any changes. + * @param size dimension in byte of mask. This size can be <= GESTURE_MASK_SIZE. If size < GESTURE_MASK_SIZE the bytes of mask are considering continuos and starting from the less significant byte. + * @return OK if success or an error code which specify the type of error encountered + */ +int enableGesture(u8 *mask, int size) +{ + int i, res; + + logError(0, "%s Trying to enable gesture... \n", tag); + + if (size <= GESTURE_MASK_SIZE) { + mutex_lock(&gestureMask_mutex); + if (mask != NULL) { + for (i = 0; i < size; i++) { + gesture_mask[i] = gesture_mask[i] | mask[i]; + } + } + + res = setFeatures(FEAT_SEL_GESTURE, gesture_mask, + GESTURE_MASK_SIZE); + if (res < OK) { + logError(1, "%s enableGesture: ERROR %08X \n", tag, + res); + goto END; + } + + logError(0, "%s enableGesture DONE! \n", tag); + res = OK; + +END: + mutex_unlock(&gestureMask_mutex); + return res; + } else { + logError( + 1, + "%s enableGesture: Size not valid! %d > %d ERROR %08X \n", + tag, size, GESTURE_MASK_SIZE); + return ERROR_OP_NOT_ALLOW; + } +} + +/** + * Disable in the FW the gesture mask to be used in gesture mode + * @param mask pointer to a byte array which store the gesture mask update that want to be sent to the FW, if NULL, all the gestures will be disabled. + * @param size dimension in byte of mask. This size can be <= GESTURE_MASK_SIZE. If size < GESTURE_MASK_SIZE the bytes of mask are considering continuos and starting from the less significant byte. + * @return OK if success or an error code which specify the type of error encountered + */ +int disableGesture(u8 *mask, int size) +{ + u8 temp; + int i, res; + u8 *pointer; + + logError(0, "%s Trying to disable gesture... \n", tag); + + if (size <= GESTURE_MASK_SIZE) { + mutex_lock(&gestureMask_mutex); + if (mask != NULL) { + for (i = 0; i < size; i++) { + temp = gesture_mask[i] ^ mask[i]; + gesture_mask[i] = temp & gesture_mask[i]; + } + + pointer = gesture_mask; + } else { + i = 0; + pointer = (u8 *)&i; + } + + res = setFeatures(FEAT_SEL_GESTURE, pointer, GESTURE_MASK_SIZE); + if (res < OK) { + logError(1, "%s disableGesture: ERROR %08X \n", tag, + res); + goto END; + } + + logError(0, "%s disableGesture DONE! \n", tag); + + res = OK; + +END: + mutex_unlock(&gestureMask_mutex); + return res; + } else { + logError( + 1, + "%s disableGesture: Size not valid! %d > %d ERROR %08X \n", + tag, size, GESTURE_MASK_SIZE); + return ERROR_OP_NOT_ALLOW; + } +} + +/** + * Perform all the steps required to put the chip in gesture mode + * @param reload if set to 1, before entering in gesture mode it will re-enable in the FW the last defined gesture mask + * @return OK if success or an error code which specify the type of error encountered + */ +int enterGestureMode(int reload) +{ + int res, ret; + + res = fts_disableInterruptNoSync(); + if (res < OK) { + logError(1, "%s enterGestureMode: ERROR %08X \n", tag, + res | ERROR_DISABLE_INTER); + return res | ERROR_DISABLE_INTER; + } + + if (reload == 1 || refreshGestureMask == 1) { + res = enableGesture(NULL, 0); + if (res < OK) { + logError( + 1, + "%s enterGestureMode: enableGesture ERROR %08X \n", + tag, res); + goto END; + } + + refreshGestureMask = 0; + } + + res = setScanMode(SCAN_MODE_LOW_POWER, 0); + if (res < OK) { + logError( + 1, + "%s enterGestureMode: enter gesture mode ERROR %08X \n", + tag, res); + goto END; + } + + res = OK; +END: + ret = fts_enableInterrupt(); + if (ret < OK) { + logError( + 1, + "%s enterGestureMode: fts_enableInterrupt ERROR %08X \n", + tag, res | ERROR_ENABLE_INTER); + res |= ret | ERROR_ENABLE_INTER; + } + + return res; +} + +/** + * Check if one or more Gesture IDs are currently enabled in gesture_mask + * @return FEAT_ENABLE if one or more gesture ids are enabled, FEAT_DISABLE if all the gesture ids are currently disabled + */ +int isAnyGestureActive(void) +{ + int res = 0; + + while (res < (GESTURE_MASK_SIZE - 1) && gesture_mask[res] == 0) { + res++; + } + + if (gesture_mask[res] != 0) { + logError( + 0, + "%s %s: Active Gestures Found! gesture_mask[%d] = %02X !\n", + tag, __func__, res, gesture_mask[res]); + return FEAT_ENABLE; + } else { + logError(0, "%s %s: All Gestures Disabled!\n", tag, __func__); + return FEAT_DISABLE; + } +} + +/** + * Read from the frame buffer the gesture coordinates pairs of the points draw by an user when a gesture is detected + * @param event pointer to a byte array which contains the gesture event reported by the fw when a gesture is detected + * @return OK if success or an error code which specify the type of error encountered + */ +int readGestureCoords(u8 *event) +{ + int i = 0; + u64 address = 0; + int res; + + u8 val[GESTURE_MAX_COORDS_PAIRS_REPORT * 4]; + + if (event[0] == EVT_ID_USER_REPORT && + event[1] == EVT_TYPE_USER_GESTURE) { + address = (event[4] << 8) | event[3]; + gesture_coords_reported = event[5]; + if (gesture_coords_reported > GESTURE_MAX_COORDS_PAIRS_REPORT) { + logError( + 1, + "%s %s: FW reported more than %d points for the gestures! Decreasing to %d \n", + tag, __func__, gesture_coords_reported, + GESTURE_MAX_COORDS_PAIRS_REPORT); + gesture_coords_reported = + GESTURE_MAX_COORDS_PAIRS_REPORT; + } + + logError(1, "%s %s: Offset: %08X , coords pairs = %d\n", tag, + __func__, address, gesture_coords_reported); + + res = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, address, + val, (gesture_coords_reported * 2 * 2), + DUMMY_FRAMEBUFFER); + if (res < OK) { + logError( + 1, + "%s %s: Cannot read the coordinates! ERROR %08X \n", + tag, __func__, res); + gesture_coords_reported = ERROR_OP_NOT_ALLOW; + return res; + } + + for (i = 0; i < gesture_coords_reported; i++) { + gesture_coordinates_x[i] = + (((u16)val[i * 2 + 1]) & 0x0F) << 8 | + (((u16)val[i * 2]) & 0xFF); + gesture_coordinates_y[i] = + (((u16)val[gesture_coords_reported * 2 + i * 2 + + 1]) & + 0x0F) << 8 | + (((u16)val[gesture_coords_reported * 2 + i * 2]) & + 0xFF); + } + + logError(1, "%s %s: Reading Gesture Coordinates DONE! \n", tag, + __func__); + return OK; + + } else { + logError( + 1, + "%s %s: The event passsed as argument is invalid! ERROR %08X \n", + tag, __func__, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } +} + +/** + * Return the coordinates of the points stored during the last detected gesture + * @param x output parameter which will store the address of the array containing the x coordinates + * @param y output parameter which will store the address of the array containing the y coordinates + * @return the number of points (x,y) stored and therefore the size of the x and y array returned. + */ +int getGestureCoords(u16 **x, u16 **y) +{ + *x = gesture_coordinates_x; + *y = gesture_coordinates_y; + logError(1, + "%s %s: Number of gesture coordinates pairs returned = %d \n", + tag, __func__, gesture_coords_reported); + return gesture_coords_reported; +} diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsGesture.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsGesture.h new file mode 100644 index 000000000000..99a914203ab8 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsGesture.h @@ -0,0 +1,38 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS Gesture Utilities * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsGesture.h +* \brief Contains all the macro and prototypes to handle the Gesture Detection features +*/ + +#ifndef FTS_GESTURE_H_ +#define FTS_GESTURE_H_ + +#include "ftsHardware.h" + +#define GESTURE_MASK_SIZE 4 + +#define GESTURE_MAX_COORDS_PAIRS_REPORT 100 + +int updateGestureMask(u8 *mask, int size, int en); +int disableGesture(u8 *mask, int size); +int enableGesture(u8 *mask, int size); +int enterGestureMode(int reload); +int isAnyGestureActive(void); +int readGestureCoords(u8 *event); +int getGestureCoords(u16 **x, u16 **y); + +#endif diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsHardware.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsHardware.h new file mode 100644 index 000000000000..8e9e87eb0caa --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsHardware.h @@ -0,0 +1,217 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* HW related data * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsHardware.h +* \brief Contains all the definitions and information related to the IC from an hardware point of view +*/ + +#ifndef FTS_HARDWARE_H +#define FTS_HARDWARE_H + +/*DIGITAL CHIP INFO*/ +#define DCHIP_ID_0 0x36 /*LSB chip ID for FTM5*/ +#define DCHIP_ID_1 0x39 /*MSB chip ID for FTM5*/ + +#define DCHIP_FW_VER_BYTE 2 /*number of bytes of the fw versions*/ + +/*CHUNKS*/ +#define READ_CHUNK \ + 1024 /*chunk dimension of a single i2c read, max allowed value is 2kB*/ +#define WRITE_CHUNK \ + 1024 /*chunk dimension of a single i2c write, max allowed value is 2kB*/ +#define MEMORY_CHUNK \ + 1024 /*chunk dimenasion of a single i2c write on mem, max allowed value is 2kB*/ + +/*PROTOCOL INFO*/ +#define I2C_INTERFACE /*comment if the chip use SPI bus*/ +#ifdef I2C_INTERFACE +#define I2C_SAD 0x49 /*slave address of the IC*/ +#else +#define SPI4_WIRE /*comment if the master is SPI3 wires (MOSI and MISO share same line)*/ +#define SPI_DELAY_CS 10 /*time in usec to wait before rising the CS*/ +#define SPI_CLOCK_FREQ 7000000 /*clock frequency in Hz of the SPI bus*/ +#endif + +#define IER_ENABLE 0x41 /*value to write in IER_ADDR to enable the interrupts*/ +#define IER_DISABLE \ + 0x00 /*value to write in IER_ADDR to disable the interrupts*/ + +/*FLASH COMMAND*/ +/** @defgroup flash_command Flash Commands + * All the commands that works with the flash of the IC + * @{ + */ +#define FLASH_CMD_UNLOCK 0xF7 + +#define FLASH_CMD_READ_REGISTER 0xFA +#define FLASH_CMD_WRITE_REGISTER 0xFA + +/*FLASH UNLOCK PARAMETER*/ +#define FLASH_UNLOCK_CODE0 0x25 +#define FLASH_UNLOCK_CODE1 0x20 +#define FLASH_UNLOCK_CODE2 0x6B +#define FLASH_UNLOCK_CODE3 0x00 + +#define FLASH_UVLO_ENABLE_CODE0 0x1B +#define FLASH_UVLO_ENABLE_CODE1 0x66 +#define FLASH_AUTOPOWERDOWN_ENABLE_CODE0 0x68 +#define FLASH_AUTOPOWERDOWN_ENABLE_CODE1 0x13 +/*FLASH ERASE and DMA PARAMETER*/ +#define FLASH_ERASE_START 0x80 +#define FLASH_ERASE_CODE1 0xC0 +#define FLASH_DMA_CODE1 0xC0 +#define FLASH_ERASE_UNLOCK_CODE0 0xDE +#define FLASH_ERASE_UNLOCK_CODE1 0x03 +#define FLASH_ERASE_CODE0 0x6A +#define FLASH_DMA_CODE0 0x71 +#define FLASH_DMA_CONFIG 0x72 +#define FLASH_NUM_PAGE 32 /*number of pages in main flash*/ + +#define FLASH_CX_PAGE_START 28 /*starting page which contain Cx data*/ +#define FLASH_CX_PAGE_END 30 /*last page which contain Cx data*/ +#define FLASH_PANEL_PAGE_START \ + 26 /*starting page which contain Panel Init data*/ +#define FLASH_PANEL_PAGE_END 27 /*last page which contain Panel Init data*/ + +/** @} */ + +/*FLASH ADDRESS*/ + +#define FLASH_ADDR_CODE \ + 0x00000000 /*starting address (words) in the flash of the code in FTI*/ +#define FLASH_ADDR_CONFIG \ + 0x00007C00 /*starting address (words) in the flash of the config in FTI*/ +#define FLASH_ADDR_CX \ + 0x00007000 /*starting address (words) in the flash of the Init data in FTI*/ + +/*SIZES FW, CODE, CONFIG, MEMH*/ +/** @defgroup fw_file FW file info + * All the info related to the fw file + * @{ + */ + +#define FW_HEADER_SIZE 64 /*dimension of the header of the .fts file*/ +#define FW_HEADER_SIGNATURE 0xAA55AA55 /*header signature*/ +#define FW_FTB_VER 0x00000001 /*.ftb version*/ +#define FW_BYTES_ALLIGN 4 /*allignment of the info*/ +#define FW_BIN_VER_OFFSET 16 /*offset of the fw version in the .ftb file*/ +#define FW_BIN_CONFIG_ID_OFFSET 20 /*offset of the config id in the .ftb file*/ +#define FW_CX_VERSION (16 + 4) /*offset of CX version in the sec2 of FW file*/ + +/** @} */ + +/*FIFO*/ +#define FIFO_EVENT_SIZE 8 /*number of bytes of one event*/ +#define FIFO_DEPTH \ + 32 /*max number of events that the FIFO can collect before going in overflow in FTM5*/ + +#ifdef I2C_INTERFACE +#define FIFO_CMD_READALL 0x86 /*command to read all the events in the FIFO*/ +#else +#define FIFO_CMD_READALL 0x87 /*command to read all the events in the FIFO*/ +#endif +#define FIFO_CMD_READONE FIFO_CMD_READALL /*commad to read one event from FIFO*/ + +/*OP CODES FOR MEMORY (based on protocol)*/ +#ifdef I2C_INTERFACE +#define FTS_CMD_HW_REG_R 0xFA /*command to read an hw register if FTI*/ +#define FTS_CMD_HW_REG_W 0xFA /*command to write an hw register if FTI*/ +#define FTS_CMD_FRAMEBUFFER_R 0xA6 /*command to read the framebuffer if FTI*/ +#define FTS_CMD_CONFIG_R 0xA8 /*command to read the config memory if FTI*/ +#define FTS_CMD_CONFIG_W 0xA8 /*command to write the config memory if FTI*/ +#else +#define FTS_CMD_HW_REG_R 0xFB /*command to read an hw register if FTI*/ +#define FTS_CMD_HW_REG_W 0xFA /*command to write an hw register if FTI*/ +#define FTS_CMD_FRAMEBUFFER_R 0xA7 /*command to read the framebuffer if FTI*/ +#define FTS_CMD_CONFIG_R 0xA9 /*command to read the config memory if FTI*/ +#define FTS_CMD_CONFIG_W 0xA8 /*command to write the config memory if FTI*/ +#endif + +/*DUMMY BYTES DATA*/ + +#ifndef I2C_INTERFACE +#define DUMMY_HW_REG 1 /*1 if the first byte read from HW register is dummy*/ +#define DUMMY_FRAMEBUFFER \ + 1 /*1 if the first byte read from Frame buffer is dummy*/ +#define DUMMY_CONFIG 1 /*1 if the first byte read from Config Memory is dummy*/ +#define DUMMY_FIFO 1 /*1 if the first byte read from FIFO is dummy*/ +#else +#define DUMMY_HW_REG 0 /*1 if the first byte read from HW register is dummy*/ +#define DUMMY_FRAMEBUFFER \ + 0 /*1 if the first byte read from Frame buffer is dummy*/ +#define DUMMY_CONFIG 0 /*1 if the first byte read from Config Memory is dummy*/ +#define DUMMY_FIFO 0 /*1 if the first byte read from FIFO is dummy*/ +#endif + +/** @defgroup hw_adr HW Address + * @ingroup address + * Important addresses of hardware registers (and sometimes their important values) + * @{ + */ + +/*IMPORTANT HW ADDRESSES (u64)*/ +#define ADDR_FRAMEBUFFER \ + ((u64)0x0000000000000000) /*frame buffer address in memory*/ +#define ADDR_ERROR_DUMP \ + ((u64)0x000000000000EF80) /*start address dump error log*/ + +/*SYSTEM RESET INFO*/ +#define ADDR_SYSTEM_RESET \ + ((u64)0x0000000020000024) /*address of System control register in FTI*/ +#define SYSTEM_RESET_VALUE \ + 0x80 /*value to write in SYSTEM_RESET_ADDRESS to perform a system reset in FTM5*/ + +/*REMAP REGISTER*/ +#define ADDR_BOOT_OPTION \ + ((u64)0x0000000020000025) /*address of Boot option register in SONIA*/ + +/*INTERRUPT INFO*/ +#define ADDR_IER \ + ((u64)0x0000000020000029) /*address of the Interrupt enable register in FTMI*/ + +/*Chip ID/Fw Version*/ +#define ADDR_DCHIP_ID ((u64)0x0000000020000000) /*chip id address for FTI*/ +#define ADDR_DCHIP_FW_VER \ + ((u64)0x0000000020000004) /*fw version address for FTI*/ + +/*INTERFACE REGISTER*/ +#define ADDR_ICR \ + ((u64)0x000000002000002D) /*address of Device control register to set the comunication protocol (SPI/I2C)*/ +#define SPI4_MASK 0x02 /*bit to set spi4*/ + +/*CRC ADDR*/ +#define ADDR_CRC \ + ((u64)0x0000000020000078) /*address of the CRC control register in FTI*/ +#define CRC_MASK \ + 0x03 /*bitmask which reveal if there is a CRC error in the flash*/ + +#define ADDR_CONFIG_OFFSET \ + ((u64)0x0000000000000000) /*config address in memory if FTI*/ + +#define ADDR_GPIO_INPUT \ + ((u64)0x0000000020000030) /*address of GPIO input register*/ +#define ADDR_GPIO_DIRECTION \ + ((u64)0x0000000020000032) /*address of GPIO direction register*/ +#define ADDR_GPIO_PULLUP \ + ((u64)0x0000000020000034) /*address of GPIO pullup register*/ +#define ADDR_GPIO_CONFIG_REG0 \ + ((u64)0x000000002000003D) /*address of GPIO config register*/ +#define ADDR_GPIO_CONFIG_REG2 \ + ((u64)0x000000002000003F) /*address of GPIO config register*/ + +/**@}*/ + +#endif diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsIO.c b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsIO.c new file mode 100644 index 000000000000..9c24d52936e2 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsIO.c @@ -0,0 +1,911 @@ +/* + + ************************************************************************** + ** STMicroelectronics ** + ************************************************************************** + ** marco.cali@st.com ** + ************************************************************************** + * * + * I2C/SPI Communication * + * * + ************************************************************************** + ************************************************************************** + + */ + +/*! +* \file ftsIO.c +* \brief Contains all the functions which handle with the I2C/SPI communication +*/ + +#include "ftsSoftware.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef I2C_INTERFACE +#include +#include +static u16 I2CSAD; +#include +#endif + +static void *client; + +#include "ftsCore.h" +#include "ftsError.h" +#include "ftsHardware.h" +#include "ftsIO.h" + +extern struct fts_ts_info *fts_info; +static struct mutex rw_lock; +static u8 *buf1; +static u8 *buf2; + +/** +* Initialize the static client variable of the fts_lib library in order to allow any i2c/spi transaction in the driver. (Must be called in the probe) +* @param clt pointer to i2c_client or spi_device struct which identify the bus slave device +* @return OK +*/ +int openChannel(void *clt) +{ + client = clt; +#ifdef I2C_INTERFACE + I2CSAD = ((struct i2c_client *)clt)->addr; + logError(0, "%s openChannel: SAD: %02X \n", tag, I2CSAD); +#else + logError(1, "%s %s: spi_master: flags = %04X !\n", tag, __func__, + ((struct spi_device *)client)->master->flags); + logError( + 1, + "%s %s: spi_device: max_speed = %d chip select = %02X bits_per_words = %d mode = %04X !\n", + tag, __func__, ((struct spi_device *)client)->max_speed_hz, + ((struct spi_device *)client)->chip_select, + ((struct spi_device *)client)->bits_per_word, + ((struct spi_device *)client)->mode); + logError(1, "%s openChannel: completed! \n", tag); +#endif + mutex_init(&rw_lock); + + if (!buf1) + buf1 = (u8 *)kzalloc(PAGE_SIZE, GFP_ATOMIC); + if (!buf2) + buf2 = (u8 *)kzalloc(PAGE_SIZE, GFP_ATOMIC); + if (!buf1 || !buf2) + return ERROR_ALLOC; + + return OK; +} + +#ifdef I2C_INTERFACE +/** +* Change the I2C slave address which will be used during the transaction (For Debug Only) +* @param sad new slave address id +* @return OK +*/ +int changeSAD(u8 sad) +{ + I2CSAD = sad; + return OK; +} +#endif + +/** +* Retrieve the pointer to the device struct of the IC +* @return a the device struct pointer if client was previously set or NULL in all the other cases +*/ +struct device *getDev() +{ + if (client != NULL) + return &(getClient()->dev); + else + return NULL; +} + +#ifdef I2C_INTERFACE +/** +* Retrieve the pointer of the i2c_client struct representing the IC as i2c slave +* @return client if it was previously set or NULL in all the other cases +*/ +struct i2c_client *getClient() +{ + if (client != NULL) + return (struct i2c_client *)client; + else + return NULL; +} +#else +/** +* Retrieve the pointer of the spi_device struct representing the IC as spi slave +* @return client if it was previously set or NULL in all the other cases +*/ +struct spi_device *getClient() +{ + if (client != NULL) + return (struct spi_device *)client; + else + return NULL; +} +#endif + +/****************** New I2C API *********************/ + +/** +* Perform a direct bus read +* @param outBuf pointer of a byte array which should contain the byte read from the IC +* @param byteToRead number of bytes to read +* @return OK if success or an error code which specify the type of error encountered +*/ +int fts_read(u8 *outBuf, int byteToRead) +{ + int ret = -1; + int retry = 0; + +#ifdef I2C_INTERFACE + struct i2c_msg I2CMsg[1]; + + I2CMsg[0].addr = (__u16)I2CSAD; + I2CMsg[0].flags = (__u16)I2C_M_RD; + I2CMsg[0].len = (__u16)byteToRead; + I2CMsg[0].buf = (__u8 *)outBuf; +#else + struct spi_message msg; + struct spi_transfer transfer[1] = { { 0 } }; + + spi_message_init(&msg); + + transfer[0].len = byteToRead; + transfer[0].delay_usecs = SPI_DELAY_CS; + transfer[0].tx_buf = NULL; + transfer[0].rx_buf = outBuf; + spi_message_add_tail(&transfer[0], &msg); +#endif + + if (client == NULL) + return ERROR_BUS_O; + while (retry < I2C_RETRY && ret < OK) { +#ifdef I2C_INTERFACE + ret = i2c_transfer(getClient()->adapter, I2CMsg, 1); +#else + ret = spi_sync(getClient(), &msg); +#endif + + retry++; + if (ret < OK) + mdelay(I2C_WAIT_BEFORE_RETRY); + } + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, ERROR_BUS_R); + return ERROR_BUS_R; + } + return OK; +} + +/** +* Perform a bus write followed by a bus read without a stop condition +* @param cmd byte array containing the command to write +* @param cmdLength size of cmd +* @param outBuf pointer of a byte array which should contain the bytes read from the IC +* @param byteToRead number of bytes to read +* @return OK if success or an error code which specify the type of error encountered +*/ +int fts_writeRead(u8 *cmd, int cmdLength, u8 *outBuf, int byteToRead) +{ + int ret = -1; + int retry = 0; + +#ifdef I2C_INTERFACE + struct i2c_msg I2CMsg[2]; + + I2CMsg[0].addr = (__u16)I2CSAD; + I2CMsg[0].flags = (__u16)0; + I2CMsg[0].len = (__u16)cmdLength; + I2CMsg[0].buf = (__u8 *)cmd; + + I2CMsg[1].addr = (__u16)I2CSAD; + I2CMsg[1].flags = I2C_M_RD; + I2CMsg[1].len = byteToRead; + I2CMsg[1].buf = (__u8 *)outBuf; + +#else + struct spi_message msg; + struct spi_transfer transfer[2] = { { 0 }, { 0 } }; + + spi_message_init(&msg); + + transfer[0].len = cmdLength; + transfer[0].tx_buf = cmd; + transfer[0].rx_buf = NULL; + spi_message_add_tail(&transfer[0], &msg); + + transfer[1].len = byteToRead; + transfer[1].delay_usecs = SPI_DELAY_CS; + transfer[1].tx_buf = NULL; + transfer[1].rx_buf = outBuf; + spi_message_add_tail(&transfer[1], &msg); + +#endif + + if (client == NULL) + return ERROR_BUS_O; + + while (retry < I2C_RETRY && ret < OK) { +#ifdef I2C_INTERFACE + ret = i2c_transfer(getClient()->adapter, I2CMsg, 2); +#else + ret = spi_sync(getClient(), &msg); +#endif + + retry++; + if (ret < OK) + mdelay(I2C_WAIT_BEFORE_RETRY); + } + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, ERROR_BUS_WR); + return ERROR_BUS_WR; + } + return OK; +} + +/** +* Perform a bus write +* @param cmd byte array containing the command to write +* @param cmdLength size of cmd +* @return OK if success or an error code which specify the type of error encountered +*/ +int fts_write(u8 *cmd, int cmdLength) +{ + int ret = -1; + int retry = 0; + +#ifdef I2C_INTERFACE + struct i2c_msg I2CMsg[1]; + + I2CMsg[0].addr = (__u16)I2CSAD; + I2CMsg[0].flags = (__u16)0; + I2CMsg[0].len = (__u16)cmdLength; + I2CMsg[0].buf = (__u8 *)cmd; +#else + struct spi_message msg; + struct spi_transfer transfer[1] = { { 0 } }; + + spi_message_init(&msg); + + transfer[0].len = cmdLength; + transfer[0].delay_usecs = SPI_DELAY_CS; + transfer[0].tx_buf = cmd; + transfer[0].rx_buf = NULL; + spi_message_add_tail(&transfer[0], &msg); +#endif + + if (client == NULL) + return ERROR_BUS_O; + while (retry < I2C_RETRY && ret < OK) { +#ifdef I2C_INTERFACE + ret = i2c_transfer(getClient()->adapter, I2CMsg, 1); +#else + ret = spi_sync(getClient(), &msg); +#endif + + retry++; + if (ret < OK) + mdelay(I2C_WAIT_BEFORE_RETRY); + } + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, ERROR_BUS_W); + return ERROR_BUS_W; + } + return OK; +} +#ifdef CONFIG_I2C_BY_DMA +/** + * same as above but can be used when enable DMA. + */ +int fts_read_dma_safe(u8 *outBuf, int byteToRead) +{ + int ret; + struct fts_dma_buf *dma = fts_info->dma_buf; + u8 *malcBuf = dma->rdBuf; + u8 *tmpBuf = NULL; + u8 *finalBuf; + + mutex_lock(&dma->dmaBufLock); + /*use malloc buf*/ + if (byteToRead > 1) { + /*extend malloc buf*/ + if (unlikely(byteToRead > PAGE_SIZE)) { + tmpBuf = kzalloc(byteToRead, GFP_KERNEL); + if (!tmpBuf) { + logError(1, "%s %s:ERROR alloc mem failed!", + tag, __func__); + mutex_unlock(&dma->dmaBufLock); + return ERROR_ALLOC; + } + finalBuf = tmpBuf; + } else { + finalBuf = malcBuf; + } + } else { + finalBuf = outBuf; + } + + ret = fts_read(finalBuf, byteToRead); + if ((ret == OK) && (byteToRead > 1)) { + memcpy(outBuf, finalBuf, byteToRead); + } + if (unlikely(tmpBuf)) + kfree(tmpBuf); + mutex_unlock(&dma->dmaBufLock); + + return ret; +} + +int fts_writeRead_dma_safe(u8 *cmd, int cmdLength, u8 *outBuf, int byteToRead) +{ + int ret; + struct fts_dma_buf *dma = fts_info->dma_buf; + u8 *malcRdBuf = dma->rdBuf; + u8 *malcWrBuf = dma->wrBuf; + u8 *rdBuf, *tmpRdBuf = NULL; + u8 *wrBuf, *tmpWrBuf = NULL; + + mutex_lock(&dma->dmaBufLock); + if (cmdLength > 1) { + if (unlikely(cmdLength > PAGE_SIZE)) { + tmpWrBuf = kzalloc(cmdLength, GFP_KERNEL); + if (!tmpWrBuf) { + logError(1, "%s %s:ERROR alloc mem failed!", + tag, __func__); + mutex_unlock(&dma->dmaBufLock); + return ERROR_ALLOC; + } + wrBuf = tmpWrBuf; + } else { + wrBuf = malcWrBuf; + } + memcpy(wrBuf, cmd, cmdLength); + } else { + wrBuf = cmd; + } + + if (byteToRead > 1) { + if (unlikely(byteToRead > PAGE_SIZE)) { + tmpRdBuf = kzalloc(byteToRead, GFP_KERNEL); + if (!tmpRdBuf) { + logError(1, "%s %s:ERROR alloc mem failed!", + tag, __func__); + if (tmpWrBuf) + kfree(tmpWrBuf); + mutex_unlock(&dma->dmaBufLock); + return ERROR_ALLOC; + } + rdBuf = tmpRdBuf; + } else { + rdBuf = malcRdBuf; + } + } else { + rdBuf = outBuf; + } + + ret = fts_writeRead(wrBuf, cmdLength, rdBuf, byteToRead); + if ((ret == OK) && (byteToRead > 1)) + memcpy(outBuf, rdBuf, byteToRead); + + if (unlikely(tmpRdBuf)) + kfree(tmpRdBuf); + if (unlikely(tmpWrBuf)) + kfree(tmpWrBuf); + mutex_unlock(&dma->dmaBufLock); + + return ret; +} + +int fts_write_dma_safe(u8 *cmd, int cmdLength) +{ + int ret; + struct fts_dma_buf *dma = fts_info->dma_buf; + u8 *malcBuf = dma->wrBuf; + u8 *tmpBuf = NULL; + u8 *finalBuf; + + mutex_lock(&dma->dmaBufLock); + /*use malloc buf*/ + if (cmdLength > 1) { + /*extend malloc buf*/ + if (unlikely(cmdLength > PAGE_SIZE)) { + tmpBuf = kzalloc(cmdLength, GFP_KERNEL); + if (!tmpBuf) { + logError(1, "%s %s:ERROR alloc mem failed!", + tag, __func__); + mutex_unlock(&dma->dmaBufLock); + return ERROR_ALLOC; + } + finalBuf = tmpBuf; + } else { + finalBuf = malcBuf; + } + memcpy(finalBuf, cmd, cmdLength); + } else { + finalBuf = cmd; + } + + ret = fts_write(finalBuf, cmdLength); + + if (unlikely(tmpBuf)) + kfree(tmpBuf); + mutex_unlock(&dma->dmaBufLock); + + return ret; +} +#else +int fts_read_dma_safe(u8 *outBuf, int byteToRead) +{ + return fts_read(outBuf, byteToRead); +} +int fts_writeRead_dma_safe(u8 *cmd, int cmdLength, u8 *outBuf, int byteToRead) +{ + return fts_writeRead(cmd, cmdLength, outBuf, byteToRead); +} +int fts_write_dma_safe(u8 *cmd, int cmdLength) +{ + return fts_write(cmd, cmdLength); +} +#endif + +/** +* Write a FW command to the IC and check automatically the echo event +* @param cmd byte array containing the command to send +* @param cmdLength size of cmd +* @return OK if success, or an error code which specify the type of error encountered +*/ +int fts_writeFwCmd(u8 *cmd, int cmdLength) +{ + int ret = -1; + int ret2 = -1; + int retry = 0; +#ifdef I2C_INTERFACE + struct i2c_msg I2CMsg[1]; + + I2CMsg[0].addr = (__u16)I2CSAD; + I2CMsg[0].flags = (__u16)0; + I2CMsg[0].len = (__u16)cmdLength; + I2CMsg[0].buf = (__u8 *)cmd; +#else + struct spi_message msg; + struct spi_transfer transfer[1] = { { 0 } }; + + spi_message_init(&msg); + + transfer[0].len = cmdLength; + transfer[0].delay_usecs = SPI_DELAY_CS; + transfer[0].tx_buf = cmd; + transfer[0].rx_buf = NULL; + spi_message_add_tail(&transfer[0], &msg); +#endif + + if (client == NULL) + return ERROR_BUS_O; + resetErrorList(); + while (retry < I2C_RETRY && (ret < OK || ret2 < OK)) { +#ifdef I2C_INTERFACE + ret = i2c_transfer(getClient()->adapter, I2CMsg, 1); +#else + ret = spi_sync(getClient(), &msg); +#endif + retry++; + if (ret >= 0) + ret2 = checkEcho(cmd, cmdLength); + if (ret < OK || ret2 < OK) + mdelay(I2C_WAIT_BEFORE_RETRY); + } + if (ret < 0) { + logError(1, "%s fts_writeFwCmd: ERROR %08X\n", tag, + ERROR_BUS_W); + return ERROR_BUS_W; + } + if (ret2 < OK) { + logError(1, "%s fts_writeFwCmd: check echo ERROR %08X\n", tag, + ret2); + return ret2; + } + return OK; +} + +/** +* Perform two bus write and one bus read without any stop condition +* In case of FTI this function is not supported and the same sequence can be achieved calling fts_write followed by an fts_writeRead. +* @param writeCmd1 byte array containing the first command to write +* @param writeCmdLength size of writeCmd1 +* @param readCmd1 byte array containing the second command to write +* @param readCmdLength size of readCmd1 +* @param outBuf pointer of a byte array which should contain the bytes read from the IC +* @param byteToRead number of bytes to read +* @return OK if success or an error code which specify the type of error encountered +*/ +int fts_writeThenWriteRead(u8 *writeCmd1, int writeCmdLength, u8 *readCmd1, + int readCmdLength, u8 *outBuf, int byteToRead) +{ + int ret = -1; + int retry = 0; + +#ifdef I2C_INTERFACE + struct i2c_msg I2CMsg[3]; + + I2CMsg[0].addr = (__u16)I2CSAD; + I2CMsg[0].flags = (__u16)0; + I2CMsg[0].len = (__u16)writeCmdLength; + I2CMsg[0].buf = (__u8 *)writeCmd1; + + I2CMsg[1].addr = (__u16)I2CSAD; + I2CMsg[1].flags = (__u16)0; + I2CMsg[1].len = (__u16)readCmdLength; + I2CMsg[1].buf = (__u8 *)readCmd1; + + I2CMsg[2].addr = (__u16)I2CSAD; + I2CMsg[2].flags = I2C_M_RD; + I2CMsg[2].len = byteToRead; + I2CMsg[2].buf = (__u8 *)outBuf; +#else + struct spi_message msg; + struct spi_transfer transfer[3] = { { 0 }, { 0 }, { 0 } }; + + spi_message_init(&msg); + + transfer[0].len = writeCmdLength; + transfer[0].tx_buf = writeCmd1; + transfer[0].rx_buf = NULL; + spi_message_add_tail(&transfer[0], &msg); + + transfer[1].len = readCmdLength; + transfer[1].tx_buf = readCmd1; + transfer[1].rx_buf = NULL; + spi_message_add_tail(&transfer[1], &msg); + + transfer[2].len = byteToRead; + transfer[2].delay_usecs = SPI_DELAY_CS; + transfer[2].tx_buf = NULL; + transfer[2].rx_buf = outBuf; + spi_message_add_tail(&transfer[2], &msg); +#endif + + if (client == NULL) + return ERROR_BUS_O; + while (retry < I2C_RETRY && ret < OK) { +#ifdef I2C_INTERFACE + ret = i2c_transfer(getClient()->adapter, I2CMsg, 3); +#else + ret = spi_sync(getClient(), &msg); +#endif + retry++; + if (ret < OK) + mdelay(I2C_WAIT_BEFORE_RETRY); + } + + if (ret < 0) { + logError(1, "%s %s: ERROR %08X\n", tag, __func__, ERROR_BUS_WR); + return ERROR_BUS_WR; + } + return OK; +} + +/** +* Perform a chunked write with one byte op code and 1 to 8 bytes address +* @param cmd byte containing the op code to write +* @param addrSize address size in byte +* @param address the starting address +* @param data pointer of a byte array which contain the bytes to write +* @param dataSize size of data +* @return OK if success or an error code which specify the type of error encountered +*/ +/* this function works only if the address is max 8 bytes */ +int fts_writeU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *data, + int dataSize) +{ + u8 *finalCmd = buf1; + int remaining = dataSize; + int toWrite = 0, i = 0; + + mutex_lock(&rw_lock); + if (addrSize <= sizeof(u64)) { + while (remaining > 0) { + if (remaining >= WRITE_CHUNK) { + toWrite = WRITE_CHUNK; + remaining -= WRITE_CHUNK; + } else { + toWrite = remaining; + remaining = 0; + } + + finalCmd[0] = cmd; + logError(0, "%s %s: addrSize = %d \n", tag, __func__, + addrSize); + for (i = 0; i < addrSize; i++) { + finalCmd[i + 1] = + (u8)((address >> + ((addrSize - 1 - i) * 8)) & + 0xFF); + logError(1, "%s %s: cmd[%d] = %02X \n", tag, + __func__, i + 1, finalCmd[i + 1]); + } + + memcpy(&finalCmd[addrSize + 1], data, toWrite); + + if (fts_write(finalCmd, 1 + addrSize + toWrite) < OK) { + logError(1, "%s %s: ERROR %08X \n", tag, + __func__, ERROR_BUS_W); + mutex_unlock(&rw_lock); + return ERROR_BUS_W; + } + + address += toWrite; + + data += toWrite; + } + } else { + logError( + 1, + "%s %s: address size bigger than max allowed %d... ERROR %08X \n", + tag, __func__, sizeof(u64), ERROR_OP_NOT_ALLOW); + } + mutex_unlock(&rw_lock); + + return OK; +} + +/** +* Perform a chunked write read with one byte op code and 1 to 8 bytes address and dummy byte support. +* @param cmd byte containing the op code to write +* @param addrSize address size in byte +* @param address the starting address +* @param outBuf pointer of a byte array which contain the bytes to read +* @param byteToRead number of bytes to read +* @param hasDummyByte if the first byte of each reading is dummy (must be skipped) set to 1, otherwise if it is valid set to 0 (or any other value) +* @return OK if success or an error code which specify the type of error encountered +*/ +int fts_writeReadU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *outBuf, + int byteToRead, int hasDummyByte) +{ + u8 *finalCmd = buf1; + u8 *buff = buf2; + int remaining = byteToRead; + int toRead = 0, i = 0; + + mutex_lock(&rw_lock); + while (remaining > 0) { + if (remaining >= READ_CHUNK) { + toRead = READ_CHUNK; + remaining -= READ_CHUNK; + } else { + toRead = remaining; + remaining = 0; + } + + finalCmd[0] = cmd; + for (i = 0; i < addrSize; i++) { + finalCmd[i + 1] = + (u8)((address >> ((addrSize - 1 - i) * 8)) & + 0xFF); + } + + if (hasDummyByte == 1) { + if (fts_writeRead(finalCmd, 1 + addrSize, buff, + toRead + 1) < OK) { + logError(1, + "%s %s: read error... ERROR %08X \n", + tag, __func__, ERROR_BUS_WR); + mutex_unlock(&rw_lock); + return ERROR_BUS_WR; + } + memcpy(outBuf, buff + 1, toRead); + } else { + if (fts_writeRead(finalCmd, 1 + addrSize, buff, + toRead) < OK) { + logError(1, + "%s %s: read error... ERROR %08X \n", + tag, __func__, ERROR_BUS_WR); + mutex_unlock(&rw_lock); + return ERROR_BUS_WR; + } + memcpy(outBuf, buff, toRead); + } + + address += toRead; + + outBuf += toRead; + } + + mutex_unlock(&rw_lock); + + return OK; +} + +/** +* Perform a chunked write followed by a second write with one byte op code for each write and 1 to 8 bytes address (the sum of the 2 address size of the two writes can not exceed 8 bytes) +* @param cmd1 byte containing the op code of first write +* @param addrSize1 address size in byte of first write +* @param cmd2 byte containing the op code of second write +* @param addrSize2 address size in byte of second write +* @param address the starting address +* @param data pointer of a byte array which contain the bytes to write +* @param dataSize size of data +* @return OK if success or an error code which specify the type of error encountered +*/ +int fts_writeU8UXthenWriteU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2, + AddrSize addrSize2, u64 address, u8 *data, + int dataSize) +{ + u8 *finalCmd1 = NULL; + u8 *finalCmd2 = buf1; + int remaining = dataSize; + int toWrite = 0, i = 0, ret = OK; + + mutex_lock(&rw_lock); + finalCmd1 = (u8 *)kzalloc(sizeof(u8) * 10, GFP_KERNEL); + if (!finalCmd1) { + ret = ERROR_ALLOC; + goto end; + } + + while (remaining > 0) { + if (remaining >= WRITE_CHUNK) { + toWrite = WRITE_CHUNK; + remaining -= WRITE_CHUNK; + } else { + toWrite = remaining; + remaining = 0; + } + + finalCmd1[0] = cmd1; + for (i = 0; i < addrSize1; i++) { + finalCmd1[i + 1] = + (u8)((address >> + ((addrSize1 + addrSize2 - 1 - i) * 8)) & + 0xFF); + } + + finalCmd2[0] = cmd2; + for (i = addrSize1; i < addrSize1 + addrSize2; i++) { + finalCmd2[i - addrSize1 + 1] = + (u8)((address >> + ((addrSize1 + addrSize2 - 1 - i) * 8)) & + 0xFF); + } + + memcpy(&finalCmd2[addrSize2 + 1], data, toWrite); + + if (fts_write(finalCmd1, 1 + addrSize1) < OK) { + logError(1, "%s %s: first write error... ERROR %08X \n", + tag, __func__, ERROR_BUS_W); + ret = ERROR_BUS_W; + goto end; + } + + if (fts_write(finalCmd2, 1 + addrSize2 + toWrite) < OK) { + logError(1, + "%s %s: second write error... ERROR %08X \n", + tag, __func__, ERROR_BUS_W); + ret = ERROR_BUS_W; + goto end; + } + + address += toWrite; + + data += toWrite; + } + +end: + if (finalCmd1) + kfree(finalCmd1); + mutex_unlock(&rw_lock); + + return ret; +} + +/** +* Perform a chunked write followed by a write read with one byte op code and 1 to 8 bytes address for each write and dummy byte support. +* @param cmd1 byte containing the op code of first write +* @param addrSize1 address size in byte of first write +* @param cmd2 byte containing the op code of second write read +* @param addrSize2 address size in byte of second write read +* @param address the starting address +* @param outBuf pointer of a byte array which contain the bytes to read +* @param byteToRead number of bytes to read +* @param hasDummyByte if the first byte of each reading is dummy (must be skipped) set to 1, otherwise if it is valid set to 0 (or any other value) +* @return OK if success or an error code which specify the type of error encountered +*/ +int fts_writeU8UXthenWriteReadU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2, + AddrSize addrSize2, u64 address, u8 *outBuf, + int byteToRead, int hasDummyByte) +{ + u8 *finalCmd1 = NULL; + u8 *finalCmd2 = NULL; + u8 *buff = buf1; + int remaining = byteToRead; + int toRead = 0, i = 0, ret = OK; + + mutex_lock(&rw_lock); + finalCmd1 = (u8 *)kzalloc(sizeof(u8) * 10, GFP_KERNEL); + if (!finalCmd1) { + ret = ERROR_ALLOC; + goto end; + } + finalCmd2 = (u8 *)kzalloc(sizeof(u8) * 10, GFP_KERNEL); + if (!finalCmd2) { + ret = ERROR_ALLOC; + goto end; + } + + while (remaining > 0) { + if (remaining >= READ_CHUNK) { + toRead = READ_CHUNK; + remaining -= READ_CHUNK; + } else { + toRead = remaining; + remaining = 0; + } + + finalCmd1[0] = cmd1; + for (i = 0; i < addrSize1; i++) { + finalCmd1[i + 1] = + (u8)((address >> + ((addrSize1 + addrSize2 - 1 - i) * 8)) & + 0xFF); + } + + finalCmd2[0] = cmd2; + for (i = addrSize1; i < addrSize1 + addrSize2; i++) { + finalCmd2[i - addrSize1 + 1] = + (u8)((address >> + ((addrSize1 + addrSize2 - 1 - i) * 8)) & + 0xFF); + } + + if (fts_write(finalCmd1, 1 + addrSize1) < OK) { + logError(1, "%s %s: first write error... ERROR %08X \n", + tag, __func__, ERROR_BUS_W); + ret = ERROR_BUS_W; + goto end; + } + + if (hasDummyByte == 1) { + if (fts_writeRead(finalCmd2, 1 + addrSize2, buff, + toRead + 1) < OK) { + logError(1, + "%s %s: read error... ERROR %08X \n", + tag, __func__, ERROR_BUS_WR); + ret = ERROR_BUS_WR; + goto end; + } + memcpy(outBuf, buff + 1, toRead); + } else { + if (fts_writeRead(finalCmd2, 1 + addrSize2, buff, + toRead) < OK) { + logError(1, + "%s %s: read error... ERROR %08X \n", + tag, __func__, ERROR_BUS_WR); + ret = ERROR_BUS_WR; + goto end; + } + memcpy(outBuf, buff, toRead); + } + + address += toRead; + + outBuf += toRead; + } + +end: + if (finalCmd1) + kfree(finalCmd1); + if (finalCmd2) + kfree(finalCmd2); + mutex_unlock(&rw_lock); + return ret; +} diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsIO.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsIO.h new file mode 100644 index 000000000000..f225de35ec79 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsIO.h @@ -0,0 +1,61 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* I2C/SPI Communication * +* * +************************************************************************** +************************************************************************** + +*/ +/*! +* \file ftsIO.h +* \brief Contains all the definitions and prototypes used and implemented in ftsIO.c +*/ + +#ifndef FTS_IO_H +#define FTS_IO_H + +#include "ftsSoftware.h" + +#define I2C_RETRY 3 +#define I2C_WAIT_BEFORE_RETRY 2 + +#ifdef I2C_INTERFACE +#include +#include +struct i2c_client *getClient(void); +#else +#include +struct spi_device *getClient(void); +#endif + +int openChannel(void *clt); +struct device *getDev(void); + +/*************** NEW I2C API ****************/ +int changeSAD(u8 sad); +int fts_read(u8 *outBuf, int byteToRead); +int fts_writeRead(u8 *cmd, int cmdLength, u8 *outBuf, int byteToRead); +int fts_write(u8 *cmd, int cmdLength); +int fts_read_dma_safe(u8 *outBuf, int byteToRead); +int fts_writeRead_dma_safe(u8 *cmd, int cmdLength, u8 *outBuf, int byteToRead); +int fts_write_dma_safe(u8 *cmd, int cmdLength); +int fts_writeFwCmd(u8 *cmd, int cmdLenght); +int fts_writeThenWriteRead(u8 *writeCmd1, int writeCmdLength, u8 *readCmd1, + int readCmdLength, u8 *outBuf, int byteToRead); +int fts_writeU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *data, + int dataSize); +int fts_writeReadU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *outBuf, + int byteToRead, int hasDummyByte); +int fts_writeU8UXthenWriteU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2, + AddrSize addrSize2, u64 address, u8 *data, + int dataSize); +int fts_writeU8UXthenWriteReadU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2, + AddrSize addrSize2, u64 address, u8 *outBuf, + int count, int hasDummyByte); +#endif diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsSoftware.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsSoftware.h new file mode 100644 index 000000000000..2d13cfe58910 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsSoftware.h @@ -0,0 +1,400 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FW related data * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsSoftware.h +* \brief Contains all the definitions and information related to the IC from a fw/driver point of view +*/ + +#ifndef FTS_SOFTWARE_H +#define FTS_SOFTWARE_H +#include +#include "ftsHardware.h" + +typedef signed char i8; /*basic type that represent one signed byte (or 8 bits)*/ + +/** + * Enumerator which contains all the possible address length expressed in bytes. + */ +typedef enum { + NO_ADDR = 0, + BITS_8 = 1, + BITS_16 = 2, + BITS_24 = 3, + BITS_32 = 4, + BITS_40 = 5, + BITS_48 = 6, + BITS_56 = 7, + BITS_64 = 8 +} AddrSize; + +/******************** NEW API *********************/ + +/** @defgroup host_command Fw Host op codes + * Valid op codes for fw commands + * @{ + */ + +/** @defgroup scan_mode Scan Mode +* @ingroup host_command +* Set the scanning mode required according to the parameters +* @{ +*/ +#define FTS_CMD_SCAN_MODE 0xA0 /*OP Code to set scan mode*/ +/** @} */ + +/** @defgroup feat_sel Feature Select +* @ingroup host_command +* Set the system defined features to enable/disable according the parameters +* @{ +*/ +#define FTS_CMD_FEATURE 0xA2 /*OP code to set features*/ +/** @} */ + +/** @defgroup sys_cmd System Command +* @ingroup host_command +* Execute a system command to perform core tasks +* @{ +*/ +#define FTS_CMD_SYSTEM 0xA4 /*OP code to write s system command*/ + +#define FTS_CMD_LOCKDOWN_ID 0x70 +#define FTS_CMD_CUSTOM 0xC0 +/** @} */ + +/** @} */ + +/*SCAN MODE OPTION (0xA0)*/ +/** @defgroup scan_opt Scan Mode Option +* @ingroup scan_mode +* Valid scanning modes and their options +* @{ +*/ +#define SCAN_MODE_ACTIVE 0x00 /*Select the Active scanning mode*/ +#define SCAN_MODE_LOW_POWER 0x01 /*Select the low power scanning mode*/ +#define SCAN_MODE_JIG_1 0x02 /*Select the Jig test 1*/ +#define SCAN_MODE_LOCKED 0x03 /*Select the Scan mode which will be locked*/ +/** @}*/ + +/** @defgroup active_bitmask Active Mode Bitmask +* @ingroup scan_opt +* Bitmask to use to enables the specific scanning with the SCAN_MODE_ACTIVE option +* @{ +*/ +#define ACTIVE_MULTI_TOUCH 0x01 /*Bit 0 MS/SS scan*/ +#define ACTIVE_KEY 0x02 /*Bit 1 Key scan*/ +#define ACTIVE_HOVER 0x04 /*Bit 2 Hover scan*/ +#define ACTIVE_PROXIMITY 0x08 /*Bit 3 Proximity scan*/ +#define ACTIVE_FORCE 0x10 /*Bit 4 Force scan*/ +/** @}*/ + +/** @defgroup locked_opt Locked Mode Option +* @ingroup scan_opt +* Options to enable and lock specific scanning with the SCAN_MODE_LOCKED option +* @{ +*/ +#define LOCKED_ACTIVE 0x00 /*Active Scan Mode*/ +#define LOCKED_HOVER 0x01 /*Hover Scan Mode*/ +#define LOCKED_IDLE 0x02 /*Idle Scan Mode*/ +#define LOCKED_LP_DETECT 0x10 /*Low Power SS*/ +#define LOCKED_LP_ACTIVE 0x11 /*Low Power MS*/ +/** @}*/ + +/** @defgroup feat_opt Feature Selection Option +* @ingroup feat_sel +* System defined features that can be enable/disable +* @{ +*/ +#define FEAT_SEL_GLOVE 0x00 /*Glove Mode*/ +#define FEAT_SEL_COVER 0x01 /*Cover Mode*/ +#define FEAT_SEL_CHARGER 0x02 /*Charger Mode*/ +#define FEAT_SEL_GESTURE 0x03 /*Gesture Mode*/ +#define FEAT_SEL_GRIP 0x04 /*Grip Detection*/ +#define FEAT_SEL_STYLUS \ + 0x07 /*Stylus Mode (this is a driver define, not available in FW)*/ +/** @}*/ + +#define FEAT_ENABLE 1 /*General value to enable a feature*/ +#define FEAT_DISABLE 0 /*General value to disable a feature*/ + +/** @defgroup charger_opt Charger Mode Option +* @ingroup feat_sel +* Option for Charger Mode, it is a bitmask where the each bit indicate a different kind of chager +* @{ +*/ +#define CHARGER_CABLE 0x01 /*normal usb charger*/ +#define CHARGER_WIRLESS 0x02 /*wireless charger*/ +/** @}*/ + +/** @defgroup gesture_opt Gesture Mode Option +* @ingroup feat_sel +* Gesture IDs of the predefined gesture recognized by the fw. +* The ID represent also the position of the corresponding bit in the gesture mask +* @{ +*/ +#define GEST_ID_UP_1F 0x01 /*Bottom to Top line*/ +#define GEST_ID_DOWN_1F 0x02 /*Top to bottom line*/ +#define GEST_ID_LEFT_1F 0x03 /*Right to left line*/ +#define GEST_ID_RIGHT_1F 0x04 /*Left to right line*/ +#define GEST_ID_DBLTAP 0x05 /*Double Tap*/ +#define GEST_ID_O 0x06 /*'O'*/ +#define GEST_ID_C 0x07 /*'C'*/ +#define GEST_ID_M 0x08 /*'M'*/ +#define GEST_ID_W 0x09 /*'W'*/ +#define GEST_ID_E 0x0A /*'e'*/ +#define GEST_ID_L 0x0B /*'L'*/ +#define GEST_ID_F 0x0C /*'F'*/ +#define GEST_ID_V 0x0D /*'V'*/ +#define GEST_ID_AT 0x0E /*'@'*/ +#define GEST_ID_S 0x0F /*'S'*/ +#define GEST_ID_Z 0x10 /*'Z'*/ +#define GEST_ID_LEFTBRACE 0x11 /*'<'*/ +#define GEST_ID_RIGHTBRACE 0x12 /*'>'*/ +#define GEST_ID_CARET 0x13 /*'^'*/ +#define GEST_ID_LONG_PRESS 0x18 /*'^'*/ +#define GEST_ID_SINGTAP 0x19 /*'^'*/ +/** @}*/ + +/** @defgroup sys_opt System Command Option +* @ingroup sys_cmd +* Valid System Command Parameters +* @{ +*/ +#define SYS_CMD_SPECIAL 0x00 /*Special Commands*/ +#define SYS_CMD_INT 0x01 /*FW Interrupt Control*/ +#define SYS_CMD_FORCE_CAL 0x02 /*Force Calibration*/ +#define SYS_CMD_CX_TUNING 0x03 /*CX initialization*/ +#define SYS_CMD_ITO 0x04 /*ITO test*/ +#define SYS_CMD_SAVE_FLASH 0x05 /*Saving to flash*/ +#define SYS_CMD_LOAD_DATA 0x06 /*Load Host data memory*/ +#define SYS_CMD_SPECIAL_TUNING 0x08 /*Perform some special tuning*/ +/** @} */ + +/** @defgroup sys_special_opt Special Command Option +* @ingroup sys_cmd +* Valid special command +* @{ +*/ +#define SPECIAL_SYS_RESET 0x00 /*System Reset triggered by the FW*/ +#define SPECIAL_FIFO_FLUSH 0x01 /*Flush of the FIFO*/ +#define SPECIAL_PANEL_INIT 0x02 /*Panel Initialization*/ +#define SPECIAL_FULL_PANEL_INIT 0x03 /*Full panel initialization*/ +/** @} */ + +#define CAL_MS_TOUCH 0x00 /*Mutual Sense Touch*/ +#define CAL_MS_LOW_POWER 0x01 /*Mutual Sense Touch in low power mode*/ +#define CAL_SS_TOUCH 0x02 /*Self Sense Touch*/ +#define CAL_SS_IDLE 0x03 /*Self Sense Touch in idle mode*/ +#define CAL_MS_KEY 0x04 /*Mutual Sense Key*/ +#define CAL_SS_KEY 0x05 /*Self Sense Key*/ +#define CAL_MS_FORCE 0x06 /*Mutual Sense Force*/ +#define CAL_SS_FORCE 0x07 /*Self Sense Force*/ + +/** @defgroup ito_opt ITO Test Option +* @ingroup sys_cmd +* Valid option for the ITO test +* @{ +*/ +#define ITO_FORCE_OPEN 0x00 /*Check if some force channels is open*/ +#define ITO_SENSE_OPEN 0x01 /*Check if some sense channels is open*/ +#define ITO_FORCE_GROUND \ + 0x02 /*Check if some force channels is short to ground*/ +#define ITO_SENSE_GROUND \ + 0x03 /*Check if some sense channels is short to ground*/ +#define ITO_FORCE_VDD 0x04 /*Check if some force channels is short to VDD*/ +#define ITO_SENSE_VDD 0x05 /*Check if some sense channels is short to VDD*/ +#define ITO_FORCE_FORCE 0x06 /*Check force to force channels*/ +#define ITO_FORCE_SENSE 0x07 /*Check force to sense channels*/ +#define ITO_SENSE_SENSE 0x08 /*Check sense to sense channels*/ +#define ITO_KEY_FORCE_OPEN \ + 0x09 /*Check if some force channels used for the key is open*/ +#define ITO_KEY_SENSE_OPEN \ + 0x0A /*Check if some sense channels used for the key is open*/ +/** @}*/ + +/** @defgroup save_opt Save to Flash Option +* @ingroup sys_cmd +* Valid option for saving data to the Flash +* @{ +*/ +#define SAVE_FW_CONF 0x01 /*Save the confing to the flash*/ +#define SAVE_CX 0x02 /*Save the CX to the flash*/ +#define SAVE_PANEL_CONF 0x04 /*Save the Panel configuration to the flash*/ +/** @}*/ + +/** @defgroup load_opt Load Host Data Option +* @ingroup sys_cmd +* Valid option to ask to the FW to load host data into the memory +* @{ +*/ +#define LOAD_SYS_INFO 0x01 /*Load System Info*/ +#define LOAD_CX_MS_TOUCH 0x10 /*Load MS Init Data for Active Mode*/ +#define LOAD_CX_MS_LOW_POWER 0x11 /*Load MS Init Data for Low Power Mode*/ +#define LOAD_CX_SS_TOUCH 0x12 /*Load SS Init Data for Active Mode*/ +#define LOAD_CX_SS_TOUCH_IDLE 0x13 /*Load SS Init Data for Low Power Mode*/ +#define LOAD_CX_MS_KEY 0x14 /*Load MS Init Data for Key*/ +#define LOAD_CX_SS_KEY 0x15 /*Load SS Init Data for Key*/ +#define LOAD_CX_MS_FORCE 0x16 /*Load MS Init Data for Force*/ +#define LOAD_CX_SS_FORCE 0x17 /*Load SS Init Data for Force*/ +#define LOAD_CX_SS_HOVER 0x18 /*Load SS Hover Init Data for* Force */ +#define LOAD_SYNC_FRAME_RAW 0x30 /*Load a Synchronized Raw Frame*/ +#define LOAD_SYNC_FRAME_FILTER 0x31 /*Load a Synchronized Filter Frame*/ +#define LOAD_SYNC_FRAME_STRENGTH 0x33 /*Load a Synchronized Strength Frame*/ +#define LOAD_SYNC_FRAME_BASELINE 0x32 /*Load a Synchronized Baseline Frame*/ +#define LOAD_PANEL_CX_TOT_MS_TOUCH \ + 0x50 /*Load TOT MS Init Data for Active Mode*/ +#define LOAD_PANEL_CX_TOT_MS_LOW_POWER \ + 0x51 /*Load TOT MS Init Data for Low Power Mode*/ +#define LOAD_PANEL_CX_TOT_SS_TOUCH \ + 0x52 /*Load TOT SS Init Data for Active Mode*/ +#define LOAD_PANEL_CX_TOT_SS_TOUCH_IDLE \ + 0x53 /*Load TOT SS Init Data for Low Power Mode*/ +#define LOAD_PANEL_CX_TOT_MS_KEY 0x54 /*Load TOT MS Init Data for Key*/ +#define LOAD_PANEL_CX_TOT_SS_KEY 0x55 /*Load TOT SS Init Data for Key*/ +#define LOAD_PANEL_CX_TOT_MS_FORCE 0x56 /*Load TOT MS Init Data for Force*/ +#define LOAD_PANEL_CX_TOT_SS_FORCE 0x57 /*Load TOT SS Init Data for Force*/ +#define STAPI_HOST_DATA_ID_PANEL_CX_SS_HVR \ + 0x58 /*Load HOVER TOT SS Init Data for Activity*/ + +/** @}*/ + +#define SPECIAL_TUNING_LP_TIMER 0x01 /*Perform LP Timer calibration*/ +#define SPECIAL_TUNING_IOFF 0x02 /*Perform Ioff calibration*/ + +/** @}*/ + +/** @defgroup events_group FW Event IDs and Types +* Event IDs and Types pushed by the FW into the FIFO +* @{ +*/ +#define EVT_ID_NOEVENT 0x00 /*No Events*/ +#define EVT_ID_CONTROLLER_READY \ + 0x03 /*Controller ready, issued after a system reset.*/ +#define EVT_ID_ENTER_POINT 0x13 /*Touch enter in the sensing area*/ +#define EVT_ID_MOTION_POINT \ + 0x23 /*Touch motion (a specific touch changed position)*/ +#define EVT_ID_LEAVE_POINT 0x33 /*Touch leave the sensing area*/ +#define EVT_ID_STATUS_UPDATE 0x43 /*FW report a system condition change*/ +#define EVT_ID_USER_REPORT \ + 0x53 /*User related events triggered (keys, gestures, proximity etc)*/ +#define EVT_ID_DEBUG 0xE3 /*Debug Info*/ +#define EVT_ID_ERROR 0xF3 /*Error Event*/ + +#define NUM_EVT_ID \ + (((EVT_ID_ERROR & 0xF0) >> 4) + \ + 1) /*Max number of unique event IDs supported*/ +/** @}*/ + +/** @defgroup status_type Status Event Types +* @ingroup events_group +* Types of EVT_ID_STATUS_UPDATE events +* @{ +*/ +#define EVT_TYPE_STATUS_ECHO \ + 0x01 /*Echo event, contain the first 5 bytes of the FW command sent*/ +#define EVT_TYPE_STATUS_FRAME_DROP \ + 0x03 /*Some frame was skipped during the elaboration*/ +#define EVT_TYPE_STATUS_FORCE_CAL 0x05 /*Force Calibration has triggered*/ +#define EVT_TYPE_STATUS_WATER 0x06 /*Water Mode*/ +#define EVT_TYPE_STATUS_SS_RAW_SAT 0x07 /*Self Sense data saturated*/ +#define EVT_TYPE_STATUS_POCKET 0x09 +/** @} */ + +/** @defgroup user_type User Event Types +* @ingroup events_group +* Types of EVT_ID_USER_REPORT events generated by thw FW +* @{ +*/ +#define EVT_TYPE_USER_KEY 0x00 /*Keys pressed/relesed event report*/ +#define EVT_TYPE_USER_PROXIMITY 0x01 /*Proximity detection event report*/ +#define EVT_TYPE_USER_GESTURE 0x02 /*Gesture detection event report*/ +#define EVT_TYPE_USER_EARDET 0x03 /*ear detection event report*/ + +/** @}*/ + +/** @defgroup error_type Error Event Types +* @ingroup events_group +* Types of EVT_ID_ERROR events reported by the FW +* @{ +*/ +#define EVT_TYPE_ERROR_WATCHDOG 0x06 /*Watchdog timer expired*/ + +#define EVT_TYPE_ERROR_CRC_CFG_HEAD 0x20 /*CRC error in the Config Area Header*/ +#define EVT_TYPE_ERROR_CRC_CFG 0x21 /*CRC error in the Config Area*/ +#define EVT_TYPE_ERROR_CRC_PANEL_HEAD \ + 0x22 /*CRC error in the Panel Area Header*/ +#define EVT_TYPE_ERROR_CRC_PANEL 0x23 /*CRC error in the Panel Area*/ + +#define EVT_TYPE_ERROR_ITO_FORCETOGND 0x60 /*Force channel/s short to ground*/ +#define EVT_TYPE_ERROR_ITO_SENSETOGND 0x61 /*Sense channel/s short to ground*/ +#define EVT_TYPE_ERROR_ITO_FORCETOVDD 0x62 /*Force channel/s short to VDD*/ +#define EVT_TYPE_ERROR_ITO_SENSETOVDD 0x63 /*Sense channel/s short to VDD*/ +#define EVT_TYPE_ERROR_ITO_FORCE_P2P 0x64 /*Pin to Pin short Force channel/s*/ +#define EVT_TYPE_ERROR_ITO_SENSE_P2P 0x65 /*Pin to Pin short Sense channel/s*/ +#define EVT_TYPE_ERROR_ITO_FORCEOPEN 0x66 /*Force Panel open*/ +#define EVT_TYPE_ERROR_ITO_SENSEOPEN 0x67 /*Sense Panel open*/ +#define EVT_TYPE_ERROR_ITO_KEYOPEN 0x68 /*Key open*/ + +#define EVT_TYPE_ERROR_CRC_CX_HEAD 0xA0 /*CRC error in the CX Area Header*/ +#define EVT_TYPE_ERROR_CRC_CX 0xA1 /*CRC error in the CX Area*/ +#define EVT_TYPE_ERROR_CRC_CX_SUB_HEAD \ + 0xA5 /*CRC error in the CX Subsection Area Header*/ +#define EVT_TYPE_ERROR_CRC_CX_SUB 0xA6 /*CRC error in the CX Subsection Area*/ + +#define EVT_TYPE_ERROR_ESD 0xF0 /*ESD error*/ +/** @}*/ + +/** @defgroup address Chip Address + * Collection of HW and SW Addresses useful to collect different kind of data + * @{ + */ + +/** @defgroup config_adr SW Address + * @ingroup address + * Important addresses of data stored into Config memory (and sometimes their dimensions) + * @{ + */ +#define ADDR_CONFIG_ID 0x0010 /*Starting Address of the config ID*/ +#define CONFIG_ID_BYTE 2 /*Number of bytes of config ID*/ +#define ADDR_CONFIG_SENSE_LEN \ + 0x0030 /*Address where is stored the number of sense channels*/ +#define ADDR_CONFIG_FORCE_LEN \ + 0x0031 /*Address where is stored the number of force channels*/ +/** @}*/ + +/** @}*/ + +#define ERROR_DUMP_ROW_SIZE 32 /*number of rows of the error memory*/ +#define ERROR_DUMP_COL_SIZE \ + 4 /*number of bytes for each row of the error memory*/ +#define ERROR_DUMP_SIGNATURE 0xFA5005AF /*first row signature of a proper dump*/ + +#define TOUCH_TYPE_INVALID 0x00 /*Invalid touch type*/ +#define TOUCH_TYPE_FINGER 0x01 /*Finger touch*/ +#define TOUCH_TYPE_GLOVE 0x02 /*Glove touch*/ +#define TOUCH_TYPE_STYLUS 0x03 /*Stylus touch*/ +#define TOUCH_TYPE_PALM 0x04 /*Palm touch*/ +#define TOUCH_TYPE_HOVER 0x05 /*Hovering touch*/ + +#define FTS_KEY_0 0x01 /*Key 0 bit*/ +#define FTS_KEY_1 0x02 /*Key 1 bit*/ +#define FTS_KEY_2 0x04 /*Key 2 bit*/ +#define FTS_KEY_3 0x08 /*Key 3 bit*/ +#define FTS_KEY_4 0x10 /*Key 4 bit*/ +#define FTS_KEY_5 0x20 /*Key 5 bit*/ +#define FTS_KEY_6 0x40 /*Key 6 bit*/ +#define FTS_KEY_7 0x80 /*Key 7 bit*/ + +#endif diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTest.c b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTest.c new file mode 100644 index 000000000000..34278f45a3d1 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTest.c @@ -0,0 +1,6342 @@ +/* + + ************************************************************************** + ** STMicroelectronics ** + ************************************************************************** + ** marco.cali@st.com ** + ************************************************************************** + * * + * FTS API for MP test * + * * + ************************************************************************** + ************************************************************************** + + */ + +/*! + * \file ftsTest.c + * \brief Contains all the functions related to the Mass Production Test + */ + +#include "ftsCompensation.h" +#include "ftsCore.h" +#include "ftsError.h" +#include "ftsFrame.h" +#include "ftsHardware.h" +#include "ftsIO.h" +#include "ftsSoftware.h" +#include "ftsTest.h" +#include "ftsTime.h" +#include "ftsTool.h" +#include "../fts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef LIMITS_H_FILE +#include "../fts_limits.h" +#endif + +TestToDo tests; +static LimitFile limit_file; + +/** + * Initialize the testToDo variable with the default tests to perform during the Mass Production Test + * @return OK + */ +int initTestToDo(void) +{ + /*** Initialize Limit File ***/ + limit_file.size = 0; + limit_file.data = NULL; + strlcpy(limit_file.name, " ", MAX_LIMIT_FILE_NAME); + tests.SelfHoverForceRaw = 1; /* /< SS Hover Force Raw min/Max test */ + tests.SelfHoverSenceRaw = 1; /* /< SS Hover Sence Raw min/Max test */ + tests.SelfHoverForceIxTotal = + 1; /* /< SS Hover Total Force Ix min/Max (for each node)* test */ + tests.SelfHoverSenceIxTotal = 1; + tests.MutualRawAdjITO = 0; + tests.MutualRaw = 0; + tests.MutualRawEachNode = 1; + tests.MutualRawGap = 0; + tests.MutualRawAdj = 0; + tests.MutualRawLP = 0; + tests.MutualRawGapLP = 0; + tests.MutualRawAdjLP = 0; + tests.MutualCx1 = 0; + tests.MutualCx2 = 0; + tests.MutualCx2Adj = 0; + tests.MutualCxTotal = 0; + tests.MutualCxTotalAdj = 0; + + tests.MutualCx1LP = 0; + tests.MutualCx2LP = 1; + tests.MutualCx2AdjLP = 1; + tests.MutualCxTotalLP = 0; + tests.MutualCxTotalAdjLP = 0; +#ifdef PHONE_KEY + tests.MutualKeyRaw = 0; +#else + tests.MutualKeyRaw = 0; +#endif + tests.MutualKeyCx1 = 0; + tests.MutualKeyCx2 = 0; +#ifdef PHONE_KEY + tests.MutualKeyCxTotal = 0; +#else + tests.MutualKeyCxTotal = 0; +#endif + tests.SelfForceRaw = 1; + tests.SelfForceRawGap = 0; + tests.SelfForceRawLP = 0; + tests.SelfForceRawGapLP = 0; + tests.SelfForceIx1 = 0; + tests.SelfForceIx2 = 0; + tests.SelfForceIx2Adj = 0; + tests.SelfForceIxTotal = 1; + tests.SelfForceIxTotalAdj = 0; + tests.SelfForceCx1 = 0; + tests.SelfForceCx2 = 0; + tests.SelfForceCx2Adj = 0; + tests.SelfForceCxTotal = 0; + tests.SelfForceCxTotalAdj = 0; + tests.SelfSenseRaw = 1; + tests.SelfSenseRawGap = 0; + tests.SelfSenseRawLP = 0; + tests.SelfSenseRawGapLP = 0; + tests.SelfSenseIx1 = 0; + tests.SelfSenseIx2 = 0; + tests.SelfSenseIx2Adj = 0; + tests.SelfSenseIxTotal = 1; + tests.SelfSenseIxTotalAdj = 0; + tests.SelfSenseCx1 = 0; + tests.SelfSenseCx2 = 0; + tests.SelfSenseCx2Adj = 0; + tests.SelfSenseCxTotal = 0; + tests.SelfSenseCxTotalAdj = 0; + return OK; +} + +/** + * Compute the Horizontal adjacent matrix doing the abs of the difference between the column i with the i-1 one. \n + * Both the original data matrix and the adj matrix are disposed as 1 dimension array one row after the other \n + * The resulting matrix has one column less than the starting original one \n + * @param data pointer to the array of signed bytes containing the original data + * @param row number of rows of the original data + * @param column number of columns of the original data + * @param result pointer of a pointer to an array of unsigned bytes which will contain the adj matrix + * @return OK if success or an error code which specify the type of error encountered + */ +int computeAdjHoriz(i8 *data, int row, int column, u8 **result) +{ + int i, j; + int size = row * (column - 1); + + if (column < 2) { + logError(1, "%s computeAdjHoriz: ERROR % 08X\n", tag, + ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + *result = (u8 *)kmalloc(size * sizeof(u8), GFP_KERNEL); + + if (*result == NULL) { + logError(1, "%s computeAdjHoriz: ERROR %08X\n", tag, + ERROR_ALLOC); + return ERROR_ALLOC; + } + + for (i = 0; i < row; i++) { + for (j = 1; j < column; j++) { + *(*result + (i * (column - 1) + (j - 1))) = + abs(data[i * column + j] - + data[i * column + (j - 1)]); + } + } + + return OK; +} + +/** + * Compute the Horizontal adjacent matrix of short values doing the abs of the difference between the column i with the i-1 one. + * Both the original data matrix and the adj matrix are disposed as 1 dimension array one row after the other \n + * The resulting matrix has one column less than the starting original one \n + * @param data pointer to the array of signed bytes containing the original data + * @param row number of rows of the original data + * @param column number of columns of the original data + * @param result pointer of a pointer to an array of unsigned bytes which will contain the adj matrix + * @return OK if success or an error code which specify the type of error encountered + */ +int computeAdjHorizTotal(short *data, int row, int column, u16 **result) +{ + int i, j; + int size = row * (column - 1); + + if (column < 2) { + logError(1, "%s computeAdjHorizTotal: ERROR % 08X\n", tag, + ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + *result = (u16 *)kmalloc(size * sizeof(u16), GFP_KERNEL); + + if (*result == NULL) { + logError(1, "%s computeAdjHorizTotal: ERROR %08X\n", tag, + ERROR_ALLOC); + return ERROR_ALLOC; + } + + for (i = 0; i < row; i++) { + for (j = 1; j < column; j++) { + *(*result + (i * (column - 1) + (j - 1))) = + abs(data[i * column + j] - + data[i * column + (j - 1)]); + } + } + + return OK; +} + +/** + * Compute the Vertical adjacent matrix doing the abs of the difference between the row i with the i-1 one. + * Both the original data matrix and the adj matrix are disposed as 1 dimension array one row after the other. \n + * The resulting matrix has one column less than the starting original one \n + * @param data pointer to the array of signed bytes containing the original data + * @param row number of rows of the original data + * @param column number of columns of the original data + * @param result pointer of a pointer to an array of unsigned bytes which will contain the adj matrix + * @return OK if success or an error code which specify the type of error encountered + */ +int computeAdjVert(i8 *data, int row, int column, u8 **result) +{ + int i, j; + int size = (row - 1) * (column); + + if (row < 2) { + logError(1, "%s computeAdjVert: ERROR % 08X\n", tag, + ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + *result = (u8 *)kmalloc(size * sizeof(u8), GFP_KERNEL); + + if (*result == NULL) { + logError(1, "%s computeAdjVert: ERROR %08X\n", tag, + ERROR_ALLOC); + return ERROR_ALLOC; + } + + for (i = 1; i < row; i++) { + for (j = 0; j < column; j++) { + *(*result + ((i - 1) * column + j)) = + abs(data[i * column + j] - + data[(i - 1) * column + j]); + } + } + + return OK; +} + +/** + * Compute the Vertical adjacent matrix of short values doing the abs of the difference between the row i with the i-1 one. + * Both the original data matrix and the adj matrix are disposed as 1 dimension array one row after the other. \n + * The resulting matrix has one column less than the starting original one \n + * @param data pointer to the array of signed bytes containing the original data + * @param row number of rows of the original data + * @param column number of columns of the original data + * @param result pointer of a pointer to an array of unsigned bytes which will contain the adj matrix + * @return OK if success or an error code which specify the type of error encountered + */ +int computeAdjVertTotal(short *data, int row, int column, u16 **result) +{ + int i, j; + int size = (row - 1) * (column); + + if (row < 2) { + logError(1, "%s computeAdjVertTotal: ERROR %08X\n", tag, + ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + *result = (u16 *)kmalloc(size * sizeof(u16), GFP_KERNEL); + + if (*result == NULL) { + logError(1, "%s computeAdjVertTotal: ERROR %08X\n", tag, + ERROR_ALLOC); + return ERROR_ALLOC; + } + + for (i = 1; i < row; i++) { + for (j = 0; j < column; j++) { + *(*result + ((i - 1) * column + j)) = + abs(data[i * column + j] - + data[(i - 1) * column + j]); + } + } + + return OK; +} + +/** + * Compute the Horizontal adjacent matrix doing the abs of the difference between the column i with the i-1 one. \n + * Both the original data matrix and the adj matrix are disposed as 1 dimension array one row after the other \n + * The resulting matrix has one column less than the starting original one \n + * @param data pointer to the array of unsigned bytes containing the original data + * @param row number of rows of the original data + * @param column number of columns of the original data + * @param result pointer of a pointer to an array of unsigned bytes which will contain the adj matrix + * @return OK if success or an error code which specify the type of error encountered + */ +int computeAdjHorizFromU(u8 *data, int row, int column, u8 **result) +{ + int i, j; + int size = row * (column - 1); + + if (column < 2) { + logError(1, "%s computeAdjHoriz: ERROR %08X\n", tag, + ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + *result = (u8 *)kmalloc(size * sizeof(u8), GFP_KERNEL); + + if (*result == NULL) { + logError(1, "%s computeAdjHoriz: ERROR %08X\n", tag, + ERROR_ALLOC); + return ERROR_ALLOC; + } + + for (i = 0; i < row; i++) { + for (j = 1; j < column; j++) { + *(*result + (i * (column - 1) + (j - 1))) = + abs(data[i * column + j] - + data[i * column + (j - 1)]); + } + } + + return OK; +} + +/** + * Compute the Horizontal adjacent matrix of u16 values doing the abs of the difference between the column i with the i-1 one. + * Both the original data matrix and the adj matrix are disposed as 1 dimension array one row after the other \n + * The resulting matrix has one column less than the starting original one \n + * @param data pointer to the array of unsigned bytes containing the original data + * @param row number of rows of the original data + * @param column number of columns of the original data + * @param result pointer of a pointer to an array of unsigned bytes which will contain the adj matrix + * @return OK if success or an error code which specify the type of error encountered + */ +int computeAdjHorizTotalFromU(u16 *data, int row, int column, u16 **result) +{ + int i, j; + int size = row * (column - 1); + + if (column < 2) { + logError(1, "%s computeAdjHorizTotal: ERROR %08X\n", tag, + ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + *result = (u16 *)kmalloc(size * sizeof(u16), GFP_KERNEL); + + if (*result == NULL) { + logError(1, "%s computeAdjHorizTotal: ERROR %08X\n", tag, + ERROR_ALLOC); + return ERROR_ALLOC; + } + + for (i = 0; i < row; i++) { + for (j = 1; j < column; j++) { + *(*result + (i * (column - 1) + (j - 1))) = + abs(data[i * column + j] - + data[i * column + (j - 1)]); + } + } + + return OK; +} + +/** + * Compute the Vertical adjacent matrix doing the abs of the difference between the row i with the i-1 one. + * Both the original data matrix and the adj matrix are disposed as 1 dimension array one row after the other. \n + * The resulting matrix has one column less than the starting original one \n + * @param data pointer to the array of unsigned bytes containing the original data + * @param row number of rows of the original data + * @param column number of columns of the original data + * @param result pointer of a pointer to an array of unsigned bytes which will contain the adj matrix + * @return OK if success or an error code which specify the type of error encountered + */ +int computeAdjVertFromU(u8 *data, int row, int column, u8 **result) +{ + int i, j; + int size = (row - 1) * (column); + + if (row < 2) { + logError(1, "%s computeAdjVert: ERROR %08X\n", tag, + ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + *result = (u8 *)kmalloc(size * sizeof(u8), GFP_KERNEL); + + if (*result == NULL) { + logError(1, "%s computeAdjVert: ERROR %08X\n", tag, + ERROR_ALLOC); + return ERROR_ALLOC; + } + + for (i = 1; i < row; i++) { + for (j = 0; j < column; j++) { + *(*result + ((i - 1) * column + j)) = + abs(data[i * column + j] - + data[(i - 1) * column + j]); + } + } + + return OK; +} + +/** + * Compute the Vertical adjacent matrix of u16 values doing the abs of the difference between the row i with the i-1 one. + * Both the original data matrix and the adj matrix are disposed as 1 dimension array one row after the other. \n + * The resulting matrix has one column less than the starting original one \n + * @param data pointer to the array of unsigned bytes containing the original data + * @param row number of rows of the original data + * @param column number of columns of the original data + * @param result pointer of a pointer to an array of unsigned bytes which will contain the adj matrix + * @return OK if success or an error code which specify the type of error encountered + */ +int computeAdjVertTotalFromU(u16 *data, int row, int column, u16 **result) +{ + int i, j; + int size = (row - 1) * (column); + + if (row < 2) { + logError(1, "%s computeAdjVertTotal: ERROR %08X\n", tag, + ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + *result = (u16 *)kmalloc(size * sizeof(u16), GFP_KERNEL); + + if (*result == NULL) { + logError(1, "%s computeAdjVertTotal: ERROR %08X\n", tag, + ERROR_ALLOC); + return ERROR_ALLOC; + } + + for (i = 1; i < row; i++) { + for (j = 0; j < column; j++) { + *(*result + ((i - 1) * column + j)) = + abs(data[i * column + j] - + data[(i - 1) * column + j]); + } + } + + return OK; +} + +int computeTotal(u8 *data, u8 main, int row, int column, int m, int n, + u16 **result) +{ + int i, j; + int size = (row) * (column); + *result = (u16 *)kmalloc(size * sizeof(u16), GFP_KERNEL); + + if (*result == NULL) { + logError(1, "%s computeTotal : ERROR %02X\n", tag, ERROR_ALLOC); + return ERROR_ALLOC; + } + + for (i = 0; i < row; i++) { + for (j = 0; j < column; j++) { + *(*result + (i * column + j)) = + m * main + n * data[i * column + j]; + } + } + + return OK; +} + +/** + * Check that each value of a matrix of short doesn't exceed a min and a Max value (these values are included in the interval). \n + * The matrix is stored as 1 dimension array one row after the other. \n + * @param data pointer to the array of short containing the data to check + * @param row number of rows of data + * @param column number of columns of data + * @param min minimum value allowed + * @param max Maximum value allowed + * @return the number of elements that overcome the specified interval (0 = OK) + */ +int checkLimitsMinMax(short *data, int row, int column, int min, int max) +{ + int i, j; + int count = 0; + + for (i = 0; i < row; i++) { + for (j = 0; j < column; j++) { + if (data[i * column + j] < min || + data[i * column + j] > max) { + logError( + 1, + "%s checkLimitsMinMax: Node[%d,%d] = %d exceed limit [%d, %d] \n", + tag, i, j, data[i * column + j], min, + max); + count++; + } + } + } + + return count; +} + +/** + * Check that the difference between the max and min of a matrix of short is less or equal to a threshold.\n + * The matrix is stored as 1 dimension array one row after the other. + * @param data pointer to the array of short containing the data to check + * @param row number of rows of data + * @param column number of columns of data + * @param threshold threshold value allowed + * @return OK if the difference is <= to threshold otherwise ERROR_TEST_CHECK_FAIL + */ +int checkLimitsGap(short *data, int row, int column, int threshold) +{ + int i, j; + int min_node; + int max_node; + + if (row == 0 || column == 0) { + logError( + 1, + "%s checkLimitsGap: invalid number of rows = %d or columns = %d ERROR %08X\n", + tag, row, column, ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } + + min_node = data[0]; + max_node = data[0]; + + for (i = 0; i < row; i++) { + for (j = 0; j < column; j++) { + if (data[i * column + j] < min_node) { + min_node = data[i * column + j]; + } else { + if (data[i * column + j] > max_node) + max_node = data[i * column + j]; + } + } + } + + if (max_node - min_node > threshold) { + logError(1, "%s checkLimitsGap: GAP = %d exceed limit %d \n", + tag, max_node - min_node, threshold); + return ERROR_TEST_CHECK_FAIL; + } else + return OK; +} + +/** + * Check that each value of a matrix of i8 doesn't exceed a specific min and Max value set for each node (these values are included in the interval). \n + * The matrixes of data, min and max values are stored as 1 dimension arrays one row after the other. + * @param data pointer to the array of short containing the data to check + * @param row number of rows of data + * @param column number of columns of data + * @param min pointer to a matrix which specify the minimum value allowed for each node + * @param max pointer to a matrix which specify the Maximum value allowed for each node + * @return the number of elements that overcome the specified interval (0 = OK) + */ +int checkLimitsMap(i8 *data, int row, int column, int *min, int *max) +{ + int i, j; + int count = 0; + + for (i = 0; i < row; i++) { + for (j = 0; j < column; j++) { + if (data[i * column + j] < min[i * column + j] || + data[i * column + j] > max[i * column + j]) { + logError( + 1, + "%s checkLimitsMap: Node[%d,%d] = %d exceed limit [%d, %d] \n", + tag, i, j, data[i * column + j], + min[i * column + j], + max[i * column + j]); + count++; + } + } + } + + return count; +} + +/** + * Check that each value of a matrix of short doesn't exceed a specific min and Max value set for each node (these values are included in the interval). + * The matrixes of data, min and max values are stored as 1 dimension arrays one row after the other. + * @param data pointer to the array of short containing the data to check + * @param row number of rows of data + * @param column number of columns of data + * @param min pointer to a matrix which specify the minimum value allowed for each node + * @param max pointer to a matrix which specify the Maximum value allowed for each node + * @return the number of elements that overcome the specified interval (0 = OK) + */ +int checkLimitsMapTotal(short *data, int row, int column, int *min, int *max) +{ + int i, j; + int count = 0; + + for (i = 0; i < row; i++) { + for (j = 0; j < column; j++) { + if (data[i * column + j] < min[i * column + j] || + data[i * column + j] > max[i * column + j]) { + logError( + 1, + "%s checkLimitsMapTotal: Node[%d,%d] = %d exceed limit [%d, %d] \n", + tag, i, j, data[i * column + j], + min[i * column + j], + max[i * column + j]); + count++; + } + } + } + + return count; +} + +/** + * Check that each value of a matrix of u8 doesn't exceed a specific min and Max value set for each node (these values are included in the interval). \n + * The matrixes of data, min and max values are stored as 1 dimension arrays one row after the other. + * @param data pointer to the array of short containing the data to check + * @param row number of rows of data + * @param column number of columns of data + * @param min pointer to a matrix which specify the minimum value allowed for each node + * @param max pointer to a matrix which specify the Maximum value allowed for each node + * @return the number of elements that overcome the specified interval (0 = OK) + */ +int checkLimitsMapFromU(u8 *data, int row, int column, int *min, int *max) +{ + int i, j; + int count = 0; + + for (i = 0; i < row; i++) { + for (j = 0; j < column; j++) { + if (data[i * column + j] < min[i * column + j] || + data[i * column + j] > max[i * column + j]) { + logError( + 1, + "%s checkLimitsMap: Node[%d,%d] = %d exceed limit [%d, %d] \n", + tag, i, j, data[i * column + j], + min[i * column + j], + max[i * column + j]); + count++; + } + } + } + + return count; +} + +/** + * Check that each value of a matrix of u16 doesn't exceed a specific min and Max value set for each node (these values are included in the interval). + * The matrixes of data, min and max values are stored as 1 dimension arrays one row after the other. + * @param data pointer to the array of short containing the data to check + * @param row number of rows of data + * @param column number of columns of data + * @param min pointer to a matrix which specify the minimum value allowed for each node + * @param max pointer to a matrix which specify the Maximum value allowed for each node + * @return the number of elements that overcome the specified interval (0 = OK) + */ +int checkLimitsMapTotalFromU(u16 *data, int row, int column, int *min, int *max) +{ + int i, j; + int count = 0; + + for (i = 0; i < row; i++) { + for (j = 0; j < column; j++) { + if (data[i * column + j] < min[i * column + j] || + data[i * column + j] > max[i * column + j]) { + logError( + 1, + "%s checkLimitsMapTotal: Node[%d,%d] = %d exceed limit [%d, %d] \n", + tag, i, j, data[i * column + j], + min[i * column + j], + max[i * column + j]); + count++; + } + logError(1, + "%s checkLimitsMapTotal: Node[%d,%d] = %d\n", + tag, i, j, data[i * column + j], + min[i * column + j], max[i * column + j]); + } + } + + return count; +} + +/** + * Check that each value of a matrix of u8 doesn't exceed a specific Max value set for each node (max value is included in the interval). + * The matrixes of data and max values are stored as 1 dimension arrays one row after the other. + * @param data pointer to the array of short containing the data to check + * @param row number of rows of data + * @param column number of columns of data + * @param max pointer to a matrix which specify the Maximum value allowed for each node + * @return the number of elements that overcome the specified interval (0 = OK) + */ +int checkLimitsMapAdj(u8 *data, int row, int column, int *max) +{ + int i, j; + int count = 0; + + for (i = 0; i < row; i++) { + for (j = 0; j < column; j++) { + if (data[i * column + j] > max[i * column + j]) { + logError( + 1, + "%s checkLimitsMapAdj: Node[%d,%d] = %d exceed limit > %d \n", + tag, i, j, data[i * column + j], + max[i * column + j]); + count++; + } + } + } + + return count; +} + +/** + * Check that each value of a matrix of u16 doesn't exceed a specific Max value set for each node (max value is included in the interval). + * The matrixes of data and max values are stored as 1 dimension arrays one row after the other. + * @param data pointer to the array of short containing the data to check + * @param row number of rows of data + * @param column number of columns of data + * @param max pointer to a matrix which specify the Maximum value allowed for each node + * @return the number of elements that overcome the specified interval (0 = OK) + */ +int checkLimitsMapAdjTotal(u16 *data, int row, int column, int *max) +{ + int i, j; + int count = 0; + + for (i = 0; i < row; i++) { + for (j = 0; j < column; j++) { + if (data[i * column + j] > max[i * column + j]) { + logError( + 1, + "%s checkLimitsMapAdjTotal: Node[%d,%d] = %d exceed limit > %d \n", + tag, i, j, data[i * column + j], + max[i * column + j]); + count++; + } + } + } + + return count; +} + +/** + * Perform an ITO test setting all the possible options (see @link ito_opt ITO Options @endlink) + * @return the number of elements that overcome the specified interval (0 = OK) + */ +int production_test_ito(char *path_limits, TestToDo *todo) +{ + int res = OK; + u8 sett[2] = { 0x00, 0x00 }; + MutualSenseFrame msRawFrame; + int *thresholds = NULL; + u16 *adj = NULL; + int trows, tcolumns; + logError(1, "%s ITO Production test is starting...\n", tag); + memset(&msRawFrame, 0x00, sizeof(msRawFrame)); + res = fts_system_reset(); + + if (res < 0) { + logError(1, "%s %s: ERROR %08X \n", tag, __func__, + ERROR_PROD_TEST_ITO); + return (res | ERROR_PROD_TEST_ITO); + } + + sett[0] = SPECIAL_TUNING_IOFF; + logError(0, "%s Trimming Ioff... \n", tag); + res = writeSysCmd(SYS_CMD_SPECIAL_TUNING, sett, 2); + + if (res < OK) { + logError(1, "%s production_test_ito: Trimm Ioff ERROR %08X \n", + tag, (res | ERROR_PROD_TEST_ITO)); + return (res | ERROR_PROD_TEST_ITO); + } + + sett[0] = 0xFF; + sett[1] = 0xFF; + logError(0, "%s ITO Check command sent... \n", tag); + res = writeSysCmd(SYS_CMD_ITO, sett, 2); + + if (res < OK) { + logError(1, "%s production_test_ito: ERROR %08X \n", tag, + (res | ERROR_PROD_TEST_ITO)); + return (res | ERROR_PROD_TEST_ITO); + } + + logError(0, "%s ITO Command = OK! \n", tag); + + if (todo->MutualRawAdjITO == 1) { + logError(1, "%s MS RAW ITO ADJ TEST: \n", tag); + logError(0, "%s Collecting MS Raw data... \n", tag); + res |= getMSFrame3(MS_RAW, &msRawFrame); + + if (res < OK) { + logError(1, "%s %s: getMSFrame failed... ERROR %08X \n", + tag, __func__, ERROR_PROD_TEST_ITO); + goto ERROR; + } + + logError(0, "%s MS RAW ITO ADJ HORIZONTAL TEST: \n", tag); + res = computeAdjHorizTotal(msRawFrame.node_data, + msRawFrame.header.force_node, + msRawFrame.header.sense_node, &adj); + + if (res < OK) { + logError( + 1, + "%s %s: computeAdjHoriz failed... ERROR %08X \n", + tag, __func__, ERROR_PROD_TEST_ITO); + goto ERROR; + } + + res = parseProductionTestLimits(path_limits, &limit_file, + MS_RAW_ITO_ADJH, &thresholds, + &trows, &tcolumns); + + if (res < OK || + (trows != msRawFrame.header.force_node || + tcolumns != msRawFrame.header.sense_node - 1)) { + logError( + 1, + "%s %s: parseProductionTestLimits MS_RAW_ITO_ADJH failed... ERROR %08X \n", + tag, __func__, ERROR_PROD_TEST_DATA); + goto ERROR; + } + + res = checkLimitsMapAdjTotal(adj, msRawFrame.header.force_node, + msRawFrame.header.sense_node - 1, + thresholds); + + if (res != OK) { + logError( + 1, + "%s production_test_data: checkLimitsAdj MS RAW ITO ADJH failed... ERROR COUNT = %d \n", + tag, res); + logError( + 0, + "%s MS RAW ITO ADJ HORIZONTAL TEST:.................FAIL \n\n", + tag); + print_frame_short( + "MS Raw ITO frame =", + array1dTo2d_short(msRawFrame.node_data, + msRawFrame.node_data_size, + msRawFrame.header.sense_node), + msRawFrame.header.force_node, + msRawFrame.header.sense_node); + res = ERROR_PROD_TEST_ITO; + goto ERROR; + } else + logError( + 0, + "%s MS RAW ITO ADJ HORIZONTAL TEST:.................OK \n", + tag); + + kfree(thresholds); + thresholds = NULL; + kfree(adj); + adj = NULL; + logError(0, "%s MS RAW ITO ADJ VERTICAL TEST: \n", tag); + res = computeAdjVertTotal(msRawFrame.node_data, + msRawFrame.header.force_node, + msRawFrame.header.sense_node, &adj); + + if (res < OK) { + logError( + 1, + "%s %s: computeAdjVert failed... ERROR %08X \n", + tag, __func__, ERROR_PROD_TEST_ITO); + goto ERROR; + } + + res = parseProductionTestLimits(path_limits, &limit_file, + MS_RAW_ITO_ADJV, &thresholds, + &trows, &tcolumns); + + if (res < OK || (trows != msRawFrame.header.force_node - 1 || + tcolumns != msRawFrame.header.sense_node)) { + logError( + 1, + "%s %s: parseProductionTestLimits MS_RAW_ITO_ADJV failed... ERROR %08X \n", + tag, __func__, ERROR_PROD_TEST_ITO); + goto ERROR; + } + + res = checkLimitsMapAdjTotal(adj, + msRawFrame.header.force_node - 1, + msRawFrame.header.sense_node, + thresholds); + + if (res != OK) { + logError( + 1, + "%s %s: checkLimitsAdj MS RAW ITO ADJV failed... ERROR COUNT = %d \n", + tag, __func__, res); + logError( + 0, + "%s MS RAW ITO ADJ VERTICAL TEST:.................FAIL \n\n", + tag); + print_frame_short( + "MS Raw ITO frame =", + array1dTo2d_short(msRawFrame.node_data, + msRawFrame.node_data_size, + msRawFrame.header.sense_node), + msRawFrame.header.force_node, + msRawFrame.header.sense_node); + res = ERROR_PROD_TEST_ITO; + goto ERROR; + } else + logError( + 0, + "%s MS RAW ITO ADJ VERTICAL TEST:.................OK \n", + tag); + + kfree(thresholds); + thresholds = NULL; + kfree(adj); + adj = NULL; + } else + logError(0, + "%s MS RAW ITO ADJ TEST:.................SKIPPED \n", + tag); + +ERROR: + + if (thresholds != NULL) { + kfree(thresholds); + thresholds = NULL; + } + if (adj != NULL) { + kfree(adj); + adj = NULL; + } + if (msRawFrame.node_data != NULL) { + kfree(msRawFrame.node_data); + msRawFrame.node_data = NULL; + } + freeLimitsFile(&limit_file); + res |= fts_system_reset(); + + if (res < OK) { + logError(1, "%s production_test_ito: ERROR %08X \n", tag, + ERROR_PROD_TEST_ITO); + res = (res | ERROR_PROD_TEST_ITO); + } + + return res; +} + +/** + * Perform the Initialization of the IC + * @param type type of initialization to do (see @link sys_special_opt Initialization Options (Full or Panel) @endlink) + * @return OK if success or an error code which specify the type of error encountered + */ +int production_test_initialization(u8 type) +{ + int res; + logError(1, "%s INITIALIZATION Production test is starting,type:%d\n", + tag, type); + + if (type != SPECIAL_PANEL_INIT && type != SPECIAL_FULL_PANEL_INIT) { + logError( + 1, + "%s production_test_initialization: Type incompatible! Type = %02X ERROR %08X \n", + tag, type, + ERROR_OP_NOT_ALLOW | ERROR_PROD_TEST_INITIALIZATION); + return (ERROR_OP_NOT_ALLOW | ERROR_PROD_TEST_INITIALIZATION); + } + + res = fts_system_reset(); + + if (res < 0) { + logError(1, "%s production_test_initialization: ERROR %08X \n", + tag, ERROR_PROD_TEST_INITIALIZATION); + return (res | ERROR_PROD_TEST_INITIALIZATION); + } + + logError(0, "%s INITIALIZATION command sent... %02X \n", tag, type); + res = writeSysCmd(SYS_CMD_SPECIAL, &type, 1); + + if (res < OK) { + logError(1, "%s production_test_initialization: ERROR %08X \n", + tag, (res | ERROR_PROD_TEST_INITIALIZATION)); + return (res | ERROR_PROD_TEST_INITIALIZATION); + } + + logError(0, "%s Refresh Sys Info...\n", tag); + res |= readSysInfo(1); + + if (res < 0) { + logError( + 1, + "%s production_test_initialization: read sys info ERROR %08X\n", + tag, ERROR_PROD_TEST_INITIALIZATION); + res = (res | ERROR_PROD_TEST_INITIALIZATION); + } + + return res; +} + +/** + * Perform a FULL (ITO + INIT + DATA CHECK) Mass Production Test of the IC + * @param pathThresholds name of Production Limit file to load or "NULL" if the limits data should be loaded by a .h file + * @param stop_on_fail if 1, the test flow stops at the first data check failure otherwise it keeps going performing all the selected test + * @param saveInit if >0 (possible values: NO_INIT, SPECIAL_PANEL_INIT or SPECIAL_FULL_PANEL_INIT), the Initialization of the IC is executed otherwise it is skipped + * @param todo pointer to a TestToDo variable which select the test to do + * @return OK if success or an error code which specify the type of error encountered + */ +int production_test_main(char *pathThresholds, int stop_on_fail, int saveInit, + TestToDo *todo) +{ + int res, ret; + logError(0, "%s MAIN Production test is starting...\n", tag); + logError(0, "%s \n", tag); + logError(0, "%s ITO TEST: \n", tag); + res = production_test_ito(pathThresholds, todo); + + if (res < 0) { + logError(0, "%s Error during ITO TEST! ERROR %08X\n", tag, res); + goto END; + } else { + logError(0, "%s ITO TEST OK!\n", tag); + } + + logError(0, "%s \n", tag); + logError(0, "%s INITIALIZATION TEST : \n", tag); + + if (saveInit != NO_INIT) { + res = production_test_initialization((u8)saveInit); + + if (res < 0) { + logError( + 0, + "%s Error during INITIALIZATION TEST! ERROR %08X\n", + tag, res); + + if (stop_on_fail) + goto END; + } else { + logError(0, "%s INITIALIZATION TEST OK!\n", tag); + } + } else + logError( + 0, + "%s INITIALIZATION TEST :................. SKIPPED \n", + tag); + + logError(0, "%s \n", tag); + + if (saveInit == 1) { + logError(0, "%s Cleaning up...\n", tag); + ret = fts_system_reset(); + + if (ret < 0) { + logError( + 1, + "%s production_test_main: system reset ERROR %08X\n", + tag, ret); + res |= ret; + + if (stop_on_fail) + goto END; + } + + logError(0, "%s \n", tag); + } + + logError(1, "%s PRODUCTION DATA TEST: \n", tag); + ret = production_test_data(pathThresholds, stop_on_fail, todo); + + if (ret < 0) { + logError(0, + "%s Error during PRODUCTION DATA TEST! ERROR %08X\n", + tag, ret); + } else { + logError(0, "%s PRODUCTION DATA TEST OK!\n", tag); + } + + res |= ret; +END: + + if (res < 0) { + logError( + 0, + "%s MAIN Production test finished.................FAILED \n", + tag); + return res; + } else { + logError( + 0, + "%s MAIN Production test finished.................OK\n", + tag); + return OK; + } +} + +/** + * Perform all the test selected in a TestTodo variable related to MS raw data (touch, keys etc..) + * @param path_limits name of Production Limit file to load or "NULL" if the limits data should be loaded by a .h file + * @param stop_on_fail if 1, the test flow stops at the first data check failure otherwise it keeps going performing all the selected test + * @param todo pointer to a TestToDo variable which select the test to do + * @return OK if success or an error code which specify the type of error encountered + */ +int production_test_ms_raw(char *path_limits, int stop_on_fail, TestToDo *todo) +{ + int ret, count_fail = 0; + MutualSenseFrame msRawFrame; + int *thresholds = NULL; + int *thresholds_min = NULL; + int *thresholds_max = NULL; + int trows, tcolumns; + u16 *adj = NULL; + /******************************* Mutual Sense Test *******************************/ + logError(0, "%s \n", tag); + + if (todo->MutualRaw == 1 || todo->MutualRawGap == 1 || + todo->MutualRawAdj == 1 || todo->MutualRawEachNode == 1) { + ret = setScanMode(SCAN_MODE_LOCKED, LOCKED_ACTIVE); + mdelay(WAIT_FOR_FRESH_FRAMES); + ret |= setScanMode(SCAN_MODE_ACTIVE, 0x00); + mdelay(WAIT_AFTER_SENSEOFF); + ret |= getMSFrame3(MS_RAW, &msRawFrame); + + if (ret < OK) { + logError( + 1, + "%s production_test_data: getMSFrame failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + return (ret | ERROR_PROD_TEST_DATA); + } + + if (todo->MutualRaw == 1) { + logError(1, "%s MS RAW MIN MAX TEST: \n", tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, MS_RAW_MIN_MAX, + &thresholds, &trows, &tcolumns); + + if (ret < OK || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_RAW_MIN_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMinMax(msRawFrame.node_data, + msRawFrame.header.force_node, + msRawFrame.header.sense_node, + thresholds[0], thresholds[1]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax MS RAW failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS RAW MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail == 1) + goto ERROR; + } else + logError( + 0, + "%s MS RAW MIN MAX TEST:.................OK \n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError( + 0, + "%s MS RAW MIN MAX TEST:.................SKIPPED \n", + tag); + if (todo->MutualRawEachNode == 1) { + logError(1, "%s MS RAW EACH NODE MIN MAX TEST:\n", tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, MS_RAW_EACH_NODE_MIN, + &thresholds_min, &trows, &tcolumns); + if (ret < OK || + (trows != msRawFrame.header.force_node || + tcolumns != msRawFrame.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_RAW_EACH_NODE_MIN failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + ret = parseProductionTestLimits( + path_limits, &limit_file, MS_RAW_EACH_NODE_MAX, + &thresholds_max, &trows, &tcolumns); + if (ret < OK || + (trows != msRawFrame.header.force_node || + tcolumns != msRawFrame.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_RAW_EACH_NODE_MAX failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + ret = checkLimitsMapTotal(msRawFrame.node_data, + msRawFrame.header.force_node, + msRawFrame.header.sense_node, + thresholds_min, + thresholds_max); + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMaxEachNodeData failed... ERROR COUNT = %d\n", + tag, ret); + logError( + 0, + "%s MS_RAW EACH NODE MIN MAX TEST:.................FAIL\n\n", + tag); + count_fail += 1; + if (stop_on_fail == 1) + goto ERROR; + } else { + logError( + 0, + "%s MS_RAW_EACH_NODE_MAX TEST:.................OK\n", + tag); + } + if (thresholds_min != NULL) { + kfree(thresholds_min); + thresholds_min = NULL; + } + if (thresholds_max != NULL) { + kfree(thresholds_max); + thresholds_max = NULL; + } + } else { + logError( + 0, + "%s MS RAW EACH NODE MIN MAX TEST:.................SKIPPED\n", + tag); + } + + logError(0, "%s \n", tag); + + if (todo->MutualRawGap == 1) { + logError(1, "%s MS RAW GAP TEST: \n", tag); + ret = parseProductionTestLimits(path_limits, + &limit_file, MS_RAW_GAP, + &thresholds, &trows, + &tcolumns); + + if (ret < OK || (trows != 1 || tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_RAW_GAP failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsGap(msRawFrame.node_data, + msRawFrame.header.force_node, + msRawFrame.header.sense_node, + thresholds[0]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsGap MS RAW failed... ERROR = %08X \n", + tag, ret); + count_fail += 1; + + if (stop_on_fail == 1) + goto ERROR; + } else + logError( + 0, + "%s MS RAW GAP TEST:.................OK \n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError( + 0, + "%s MS RAW GAP TEST:.................SKIPPED \n", + tag); + + logError(0, "%s \n", tag); + + if (todo->MutualRawAdj == 1) { + logError(1, "%s MS RAW ADJ HORIZONTAL TEST: \n", tag); + ret = computeAdjHorizTotal(msRawFrame.node_data, + msRawFrame.header.force_node, + msRawFrame.header.sense_node, + &adj); + + if (ret < OK) { + logError( + 1, + "%s production_test_data: computeAdjHoriz failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits( + path_limits, &limit_file, MS_RAW_ADJH, + &thresholds, &trows, &tcolumns); + + if (ret < OK || + (trows != msRawFrame.header.force_node || + tcolumns != msRawFrame.header.sense_node - 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_RAW_ADJH failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdjTotal( + adj, msRawFrame.header.force_node, + msRawFrame.header.sense_node - 1, thresholds); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsAdj MS RAW ADJH failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS RAW ADJ HORIZONTAL TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail == 1) + goto ERROR; + } else + logError( + 0, + "%s MS RAW ADJ HORIZONTAL TEST:.................OK \n", + tag); + + kfree(thresholds); + thresholds = NULL; + kfree(adj); + adj = NULL; + logError(0, "%s MS RAW ADJ VERTICAL TEST: \n", tag); + ret = computeAdjVertTotal(msRawFrame.node_data, + msRawFrame.header.force_node, + msRawFrame.header.sense_node, + &adj); + + if (ret < OK) { + logError( + 1, + "%s production_test_data: computeAdjVert failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits( + path_limits, &limit_file, MS_RAW_ADJV, + &thresholds, &trows, &tcolumns); + + if (ret < OK || + (trows != msRawFrame.header.force_node - 1 || + tcolumns != msRawFrame.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_RAW_ADJV failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdjTotal( + adj, msRawFrame.header.force_node - 1, + msRawFrame.header.sense_node, thresholds); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsAdj MS RAW ADJV failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS RAW ADJ VERTICAL TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail == 1) + goto ERROR; + } else + logError( + 0, + "%s MS RAW ADJ VERTICAL TEST:.................OK \n", + tag); + + kfree(thresholds); + thresholds = NULL; + kfree(adj); + adj = NULL; + } else + logError( + 0, + "%s MS RAW ADJ TEST:.................SKIPPED \n", + tag); + } else + logError(0, "%s MS RAW FRAME TEST:.................SKIPPED \n", + tag); + + logError(0, "%s \n", tag); + + if (todo->MutualKeyRaw == 1) { + logError(1, "%s MS KEY RAW TEST:\n", tag); + ret = production_test_ms_key_raw(path_limits); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: production_test_ms_key_raw failed... ERROR = %08X \n", + tag, ret); + count_fail += 1; + + if (count_fail == 1) { + logError( + 0, + "%s MS RAW DATA TEST:.................FAIL fails_count = %d\n\n", + tag, count_fail); + goto ERROR_LIMITS; + } + } + } else + logError(0, "%s MS KEY RAW TEST:.................SKIPPED \n", + tag); + + ret = production_test_ms_raw_lp(path_limits, stop_on_fail, todo); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: production_test_ms_raw_lp failed... ERROR = %08X \n", + tag, ret); + count_fail += 1; + + if (count_fail == 1) { + logError( + 0, + "%s MS RAW DATA TEST:.................FAIL fails_count = %d\n\n", + tag, count_fail); + goto ERROR_LIMITS; + } + } + +ERROR: + logError(0, "%s \n", tag); + + if (count_fail == 0) { + if (msRawFrame.node_data != NULL) { + kfree(msRawFrame.node_data); + msRawFrame.node_data = NULL; + } + + logError(0, + "%s MS RAW DATA TEST finished!.................OK\n", + tag); + return OK; + } else { + print_frame_short( + "MS Raw frame =", + array1dTo2d_short(msRawFrame.node_data, + msRawFrame.node_data_size, + msRawFrame.header.sense_node), + msRawFrame.header.force_node, + msRawFrame.header.sense_node); + + if (msRawFrame.node_data != NULL) { + kfree(msRawFrame.node_data); + msRawFrame.node_data = NULL; + } + if (thresholds != NULL) { + kfree(thresholds); + thresholds = NULL; + } + if (adj != NULL) { + kfree(adj); + adj = NULL; + } + logError( + 0, + "%s MS RAW DATA TEST:.................FAIL fails_count = %d\n\n", + tag, count_fail); + return (ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL); + } + +ERROR_LIMITS: + + if (msRawFrame.node_data != NULL) { + kfree(msRawFrame.node_data); + msRawFrame.node_data = NULL; + } + if (thresholds != NULL) { + kfree(thresholds); + thresholds = NULL; + } + return ret; +} + +/** + * Perform all the test selected in a TestTodo variable related to MS low power raw data + * @param path_limits name of Production Limit file to load or "NULL" if the limits data should be loaded by a .h file + * @param stop_on_fail if 1, the test flow stops at the first data check failure otherwise it keeps going performing all the selected test + * @param todo pointer to a TestToDo variable which select the test to do + * @return OK if success or an error code which specify the type of error encountered + */ +int production_test_ms_raw_lp(char *path_limits, int stop_on_fail, + TestToDo *todo) +{ + int ret, count_fail = 0; + MutualSenseFrame msRawFrame; + int *thresholds = NULL; + int trows, tcolumns; + u16 *adj = NULL; + memset(&msRawFrame, 0x00, sizeof(msRawFrame)); + /******************************* Mutual Sense Test *******************************/ + logError(0, "%s \n", tag); + + if (todo->MutualRawLP == 1 || todo->MutualRawGapLP == 1 || + todo->MutualRawAdjLP == 1) { + ret = setScanMode(SCAN_MODE_LOCKED, LOCKED_LP_ACTIVE); + mdelay(WAIT_FOR_FRESH_FRAMES); + ret |= setScanMode(SCAN_MODE_ACTIVE, 0x00); + mdelay(WAIT_AFTER_SENSEOFF); + ret |= getMSFrame3(MS_RAW, &msRawFrame); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: getMSFrame failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + return (ret | ERROR_PROD_TEST_DATA); + } + + if (todo->MutualRawLP == 1) { + logError(1, "%s MS RAW LP MIN MAX TEST: \n", tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, MS_RAW_LP_MIN_MAX, + &thresholds, &trows, &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_RAW_LP_MIN_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMinMax(msRawFrame.node_data, + msRawFrame.header.force_node, + msRawFrame.header.sense_node, + thresholds[0], thresholds[1]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax MS RAW LP failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS RAW LP MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail == 1) + goto ERROR; + } else + logError( + 0, + "%s MS RAW LP MIN MAX TEST:.................OK \n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError( + 0, + "%s MS RAW LP MIN MAX TEST:.................SKIPPED \n", + tag); + + logError(0, "%s \n", tag); + + if (todo->MutualRawGapLP == 1) { + logError(1, "%s MS RAW LP GAP TEST: \n", tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, MS_RAW_LP_GAP, + &thresholds, &trows, &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_RAW_LP_GAP failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsGap(msRawFrame.node_data, + msRawFrame.header.force_node, + msRawFrame.header.sense_node, + thresholds[0]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsGap MS RAW LP failed... ERROR = %08X \n", + tag, ret); + count_fail += 1; + + if (stop_on_fail == 1) + goto ERROR; + } else + logError( + 0, + "%s MS RAW LP GAP TEST:.................OK \n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError( + 0, + "%s MS RAW LP GAP TEST:.................SKIPPED \n", + tag); + + logError(0, "%s \n", tag); + + if (todo->MutualRawAdjLP == 1) { + logError(1, "%s MS RAW LP ADJ HORIZONTAL TEST: \n", + tag); + ret = computeAdjHorizTotal(msRawFrame.node_data, + msRawFrame.header.force_node, + msRawFrame.header.sense_node, + &adj); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjHoriz failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits( + path_limits, &limit_file, MS_RAW_LP_ADJH, + &thresholds, &trows, &tcolumns); + + if (ret < 0 || + (trows != msRawFrame.header.force_node || + tcolumns != msRawFrame.header.sense_node - 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_RAW_LP_ADJH failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdjTotal( + adj, msRawFrame.header.force_node, + msRawFrame.header.sense_node - 1, thresholds); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsAdj MS RAW LP ADJH failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS RAW LP ADJ HORIZONTAL TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail == 1) + goto ERROR; + } else + logError( + 0, + "%s MS RAW LP ADJ HORIZONTAL TEST:.................OK \n", + tag); + + kfree(thresholds); + thresholds = NULL; + kfree(adj); + adj = NULL; + logError(0, "%s MS RAW LP ADJ VERTICAL TEST: \n", tag); + ret = computeAdjVertTotal(msRawFrame.node_data, + msRawFrame.header.force_node, + msRawFrame.header.sense_node, + &adj); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjVert failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits( + path_limits, &limit_file, MS_RAW_LP_ADJV, + &thresholds, &trows, &tcolumns); + + if (ret < 0 || + (trows != msRawFrame.header.force_node - 1 || + tcolumns != msRawFrame.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_RAW_ADJV failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdjTotal( + adj, msRawFrame.header.force_node - 1, + msRawFrame.header.sense_node, thresholds); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsAdj MS RAW ADJV failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS RAW LP ADJ VERTICAL TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail == 1) + goto ERROR; + } else + logError( + 0, + "%s MS RAW LP ADJ VERTICAL TEST:.................OK \n", + tag); + + kfree(thresholds); + thresholds = NULL; + kfree(adj); + adj = NULL; + } else + logError( + 0, + "%s MS RAW LP ADJ TEST:.................SKIPPED \n", + tag); + } else + logError(0, + "%s MS RAW LP FRAME TEST:.................SKIPPED \n", + tag); + +ERROR: + logError(0, "%s \n", tag); + + if (count_fail == 0) { + if (msRawFrame.node_data != NULL) { + kfree(msRawFrame.node_data); + msRawFrame.node_data = NULL; + } + + logError(0, + "%s MS RAW DATA TEST finished!.................OK\n", + tag); + return OK; + } else { + if (msRawFrame.node_data != NULL) { + print_frame_short( + "MS Raw LP frame =", + array1dTo2d_short(msRawFrame.node_data, + msRawFrame.node_data_size, + msRawFrame.header.sense_node), + msRawFrame.header.force_node, + msRawFrame.header.sense_node); + kfree(msRawFrame.node_data); + msRawFrame.node_data = NULL; + } + + if (thresholds != NULL) { + kfree(thresholds); + thresholds = NULL; + } + if (adj != NULL) { + kfree(adj); + adj = NULL; + } + logError( + 0, + "%s MS RAW LP DATA TEST:.................FAIL fails_count = %d\n\n", + tag, count_fail); + return (ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL); + } + +ERROR_LIMITS: + + if (msRawFrame.node_data != NULL) { + kfree(msRawFrame.node_data); + msRawFrame.node_data = NULL; + } + if (thresholds != NULL) { + kfree(thresholds); + thresholds = NULL; + } + return ret; +} + +/** + * Perform MS raw test for keys data + * @param path_limits name of Production Limit file to load or "NULL" if the limits data should be loaded by a .h file + * @return OK if success or an error code which specify the type of error encountered + */ +int production_test_ms_key_raw(char *path_limits) +{ + int ret; + MutualSenseFrame msRawFrame; + int *thresholds = NULL; + int trows, tcolumns; + /******************************* Mutual Sense Test *******************************/ + logError(1, "%s MS KEY RAW DATA TEST is starting...\n", tag); + ret = setScanMode(SCAN_MODE_ACTIVE, 0x01); + mdelay(WAIT_FOR_FRESH_FRAMES); + ret |= setScanMode(SCAN_MODE_ACTIVE, 0x00); + mdelay(WAIT_AFTER_SENSEOFF); + ret |= getMSFrame3(MS_KEY_RAW, &msRawFrame); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: getMSKeyFrame failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + return (ret | ERROR_PROD_TEST_DATA); + } + + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_KEY_RAW_MIN_MAX, &thresholds, &trows, + &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_KEY_RAW_MIN_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMinMax(msRawFrame.node_data, + msRawFrame.header.force_node, + msRawFrame.header.sense_node, thresholds[0], + thresholds[1]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax MS KEY RAW failed... ERROR COUNT = %d \n", + tag, ret); + goto ERROR; + } else + logError(0, "%s MS KEY RAW TEST:.................OK \n\n", tag); + + kfree(thresholds); + thresholds = NULL; + kfree(msRawFrame.node_data); + msRawFrame.node_data = NULL; + return OK; +ERROR: + print_frame_short("MS Key Raw frame =", + array1dTo2d_short(msRawFrame.node_data, + msRawFrame.node_data_size, + msRawFrame.header.sense_node), + msRawFrame.header.force_node, + msRawFrame.header.sense_node); + + if (msRawFrame.node_data != NULL) { + kfree(msRawFrame.node_data); + msRawFrame.node_data = NULL; + } + if (thresholds != NULL) { + kfree(thresholds); + thresholds = NULL; + } + logError(0, "%s MS KEY RAW TEST:.................FAIL \n\n", tag); + return (ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL); +ERROR_LIMITS: + + if (msRawFrame.node_data != NULL) { + kfree(msRawFrame.node_data); + msRawFrame.node_data = NULL; + } + if (thresholds != NULL) { + kfree(thresholds); + thresholds = NULL; + } + return ret; +} + +/** + * Perform all the tests selected in a TestTodo variable related to MS Init data (touch, keys etc..) + * @param path_limits name of Production Limit file to load or "NULL" if the limits data should be loaded by a .h file + * @param stop_on_fail if 1, the test flow stops at the first data check failure otherwise it keeps going performing all the selected test + * @param todo pointer to a TestToDo variable which select the test to do + * @return OK if success or an error code which specify the type of error encountered + */ +int production_test_ms_cx(char *path_limits, int stop_on_fail, TestToDo *todo) +{ + int ret; + int count_fail = 0; + int *thresholds = NULL; + int *thresholds_min = NULL; + int *thresholds_max = NULL; + int trows, tcolumns; + MutualSenseData msCompData; + TotMutualSenseData totCompData; + u8 *adjhor = NULL; + u8 *adjvert = NULL; + u16 container; + u16 *total_adjhor = NULL; + u16 *total_adjvert = NULL; + logError(0, "%s \n", tag); + ret = readMutualSenseCompensationData(LOAD_CX_MS_TOUCH, &msCompData); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: readMutualSenseCompensationData failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + return (ret | ERROR_PROD_TEST_DATA); + } + + ret = readTotMutualSenseCompensationData(LOAD_PANEL_CX_TOT_MS_TOUCH, + &totCompData); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: readTotMutualSenseCompensationData failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + kfree(msCompData.node_data); + msCompData.node_data = NULL; + return (ret | ERROR_PROD_TEST_DATA); + } + + if (todo->MutualCx1 == 1) { + logError(1, "%s MS CX1 TEST: \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_CX1_MIN_MAX, &thresholds, + &trows, &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_CX1_MIN_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + container = (u16)msCompData.cx1; + ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], + thresholds[1]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax MS CX1 failed... ERROR COUNT = %d \n", + tag, ret); + logError(0, "%s MS CX1 TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError(0, "%s MS CX1 TEST:.................OK \n\n", + tag); + } else + logError(0, "%s MS CX1 TEST:.................SKIPPED \n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + + if (todo->MutualCx2 == 1) { + logError(1, "%s MS CX2 MIN MAX TEST: \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_CX2_MAP_MIN, &thresholds_min, + &trows, &tcolumns); + + if (ret < 0 || (trows != msCompData.header.force_node || + tcolumns != msCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_CX2_MAP_MIN failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_CX2_MAP_MAX, &thresholds_max, + &trows, &tcolumns); + + if (ret < 0 || (trows != msCompData.header.force_node || + tcolumns != msCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_CX2_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMap(msCompData.node_data, + msCompData.header.force_node, + msCompData.header.sense_node, + thresholds_min, thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap MS CX2 MIN MAX failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS CX2 MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s MS CX2 MIN MAX TEST:.................OK \n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError(0, + "%s MS CX2 MIN MAX TEST:.................SKIPPED \n\n", + tag); + + if (todo->MutualCx2Adj == 1) { + logError(1, "%s MS CX2 ADJ TEST: \n", tag); + ret = computeAdjHoriz(msCompData.node_data, + msCompData.header.force_node, + msCompData.header.sense_node, &adjhor); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjHoriz failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + logError(0, "%s MS CX2 ADJ HORIZ computed! \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_CX2_ADJH_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + + if (ret < 0 || (trows != msCompData.header.force_node || + tcolumns != msCompData.header.sense_node - 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_CX2_ADJH_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdj(adjhor, msCompData.header.force_node, + msCompData.header.sense_node - 1, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMapAdj CX2 ADJH failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS CX2 ADJ HORIZ TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s MS CX2 ADJ HORIZ TEST:.................OK \n\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(adjhor); + adjhor = NULL; + logError(0, "%s MS CX2 ADJ VERT TEST: \n", tag); + ret = computeAdjVert(msCompData.node_data, + msCompData.header.force_node, + msCompData.header.sense_node, &adjvert); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjVert failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + logError(0, "%s MS CX2 ADJ VERT computed! \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_CX2_ADJV_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + + if (ret < 0 || (trows != msCompData.header.force_node - 1 || + tcolumns != msCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_CX2_ADJV_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdj(adjvert, + msCompData.header.force_node - 1, + msCompData.header.sense_node - 1, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMapAdj CX2 ADJV failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS CX2 ADJ HORIZ TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s MS CX2 ADJ VERT TEST:.................OK \n\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(adjvert); + adjvert = NULL; + } else + logError(0, "%s MS CX2 ADJ TEST:.................SKIPPED \n\n", + tag); + + if (todo->MutualCxTotal == 1 || todo->MutualCxTotalAdj == 1) { + if (todo->MutualCxTotal == 1) { + logError(1, "%s MS TOTAL CX MIN MAX TEST: \n", tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, MS_TOTAL_CX_MAP_MIN, + &thresholds_min, &trows, &tcolumns); + + if (ret < 0 || + (trows != totCompData.header.force_node || + tcolumns != totCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_MAP_MIN failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits( + path_limits, &limit_file, MS_TOTAL_CX_MAP_MAX, + &thresholds_max, &trows, &tcolumns); + + if (ret < 0 || + (trows != totCompData.header.force_node || + tcolumns != totCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapTotal(totCompData.node_data, + totCompData.header.force_node, + totCompData.header.sense_node, + thresholds_min, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap MS TOTAL CX TEST failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS TOTAL CX MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s MS TOTAL CX MIN MAX TEST:.................OK \n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError( + 0, + "%s MS TOTAL CX MIN MAX TEST:.................SKIPPED \n\n", + tag); + + if (todo->MutualCxTotalAdj == 1) { + logError(1, "%s MS TOTAL CX ADJ HORIZ TEST: \n", tag); + ret = computeAdjHorizTotal( + totCompData.node_data, + totCompData.header.force_node, + totCompData.header.sense_node, &total_adjhor); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjHoriz failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + logError(0, "%s MS TOTAL CX ADJ HORIZ computed! \n", + tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, + MS_TOTAL_CX_ADJH_MAP_MAX, &thresholds_max, + &trows, &tcolumns); + + if (ret < 0 || + (trows != totCompData.header.force_node || + tcolumns != totCompData.header.sense_node - 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_ADJH_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdjTotal( + total_adjhor, totCompData.header.force_node, + totCompData.header.sense_node - 1, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMapAdj MS TOTAL CX ADJH failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS TOTAL CX ADJ HORIZ TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s MS TOTAL CX ADJ HORIZ TEST:.................OK \n\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(total_adjhor); + total_adjhor = NULL; + logError(0, "%s MS TOTAL CX ADJ VERT TEST: \n", tag); + ret = computeAdjVertTotal(totCompData.node_data, + totCompData.header.force_node, + totCompData.header.sense_node, + &total_adjvert); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjVert failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + logError(0, "%s MS TOTAL CX ADJ VERT computed! \n", + tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, + MS_TOTAL_CX_ADJV_MAP_MAX, &thresholds_max, + &trows, &tcolumns); + + if (ret < 0 || + (trows != totCompData.header.force_node - 1 || + tcolumns != totCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_ADJV_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdjTotal( + total_adjvert, + totCompData.header.force_node - 1, + totCompData.header.sense_node - 1, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMapAdj MS TOTAL CX ADJV failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS TOTAL CX ADJ HORIZ TEST:.................FAIL \n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s MS TOTAL CX ADJ VERT TEST:.................OK \n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(total_adjvert); + total_adjvert = NULL; + } else + logError( + 0, + "%s MS TOTAL CX ADJ TEST:.................SKIPPED \n", + tag); + + kfree(totCompData.node_data); + totCompData.node_data = NULL; + } else + logError(0, "%s MS TOTAL CX TEST:.................SKIPPED \n", + tag); + + if ((todo->MutualCx1LP | todo->MutualCx2LP | todo->MutualCx2AdjLP | + todo->MutualCxTotalLP | todo->MutualCxTotalAdjLP) == 1) { + ret = production_test_ms_cx_lp(path_limits, stop_on_fail, todo); + if (ret < OK) { + count_fail += 1; + logError( + 1, + "%s production_test_data: production_test_cx_lp failed... ERROR = %08X\n", + tag, ret); + logError( + 0, + "%s MS CX testes finished!.................FAILED fails_count = %d\n\n", + tag, count_fail); + return ret; + } + } else + logError(0, "%s MS KEY CX TEST:.................SKIPPED\n", + tag); + + if ((todo->MutualKeyCx1 | todo->MutualKeyCx2 | + todo->MutualKeyCxTotal) == 1) { + ret = production_test_ms_key_cx(path_limits, stop_on_fail, + todo); + + if (ret < 0) { + count_fail += 1; + logError( + 1, + "%s production_test_data: production_test_ms_key_cx failed... ERROR = %08X \n", + tag, ret); + logError( + 0, + "%s MS CX testes finished!.................FAILED fails_count = %d\n\n", + tag, count_fail); + return ret; + } + } else + logError(0, "%s MS KEY CX TEST:.................SKIPPED \n", + tag); + +ERROR: + logError(0, "%s \n", tag); + + if (count_fail == 0) { + logError(0, "%s MS CX testes finished!.................OK\n", + tag); + kfree(msCompData.node_data); + msCompData.node_data = NULL; + return OK; + } else { + print_frame_i8("MS Init Data (Cx2) =", + array1dTo2d_i8(msCompData.node_data, + msCompData.node_data_size, + msCompData.header.sense_node), + msCompData.header.force_node, + msCompData.header.sense_node); + print_frame_short( + " TOT MS Init Data (Cx) =", + array1dTo2d_short(totCompData.node_data, + totCompData.node_data_size, + totCompData.header.sense_node), + totCompData.header.force_node, + totCompData.header.sense_node); + logError( + 0, + "%s MS CX testes finished!.................FAILED fails_count = %d\n\n", + tag, count_fail); + + if (thresholds != NULL) { + kfree(thresholds); + thresholds = NULL; + } + if (thresholds_min != NULL) { + kfree(thresholds_min); + thresholds_min = NULL; + } + if (thresholds_max != NULL) { + kfree(thresholds_max); + thresholds_max = NULL; + } + if (adjhor != NULL) { + kfree(adjhor); + adjhor = NULL; + } + if (adjvert != NULL) { + kfree(adjvert); + adjvert = NULL; + } + if (totCompData.node_data != NULL) { + kfree(totCompData.node_data); + totCompData.node_data = NULL; + } + if (total_adjhor != NULL) { + kfree(total_adjhor); + total_adjhor = NULL; + } + if (total_adjvert != NULL) { + kfree(total_adjvert); + total_adjvert = NULL; + } + if (msCompData.node_data != NULL) { + kfree(msCompData.node_data); + msCompData.node_data = NULL; + } + return (ERROR_TEST_CHECK_FAIL | ERROR_PROD_TEST_DATA); + } + +ERROR_LIMITS: + + if (thresholds != NULL) { + kfree(thresholds); + thresholds = NULL; + } + if (thresholds_min != NULL) { + kfree(thresholds_min); + thresholds_min = NULL; + } + if (thresholds_max != NULL) { + kfree(thresholds_max); + thresholds_max = NULL; + } + if (adjhor != NULL) { + kfree(adjhor); + adjhor = NULL; + } + if (adjvert != NULL) { + kfree(adjvert); + adjvert = NULL; + } + if (totCompData.node_data != NULL) { + kfree(totCompData.node_data); + totCompData.node_data = NULL; + } + if (total_adjhor != NULL) { + kfree(total_adjhor); + total_adjhor = NULL; + } + if (total_adjvert != NULL) { + kfree(total_adjvert); + total_adjvert = NULL; + } + if (msCompData.node_data != NULL) { + kfree(msCompData.node_data); + msCompData.node_data = NULL; + } + return ret; +} + +/** + * Perform all the tests selected in a TestTodo variable related to MS Init data of the keys + * @param path_limits name of Production Limit file to load or "NULL" if the limits data should be loaded by a .h file + * @param stop_on_fail if 1, the test flow stops at the first data check failure otherwise it keeps going performing all the selected test + * @param todo pointer to a TestToDo variable which select the test to do + * @return OK if success or an error code which specify the type of error encountered + */ +int production_test_ms_key_cx(char *path_limits, int stop_on_fail, + TestToDo *todo) +{ + int ret; + int count_fail = 0; + int num_keys = 0; + int *thresholds = NULL; + int *thresholds_min = NULL; + int *thresholds_max = NULL; + int trows, tcolumns; + MutualSenseData msCompData; + TotMutualSenseData totCompData; + short container; + ret = readMutualSenseCompensationData(LOAD_CX_MS_KEY, &msCompData); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: readMutualSenseCompensationData failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + return (ret | ERROR_PROD_TEST_DATA); + } + + if (msCompData.header.force_node > msCompData.header.sense_node) + num_keys = msCompData.header.force_node; + else + num_keys = msCompData.header.sense_node; + + if (todo->MutualKeyCx1 == 1) { + logError(1, "%s MS KEY CX1 TEST: \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_KEY_CX1_MIN_MAX, &thresholds, + &trows, &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_KEY_CX1_MIN_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + container = (short)msCompData.cx1; + ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], + thresholds[1]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax MS CX1 failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS KEY CX1 TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError(0, + "%s MS KEY CX1 TEST:.................OK \n\n", + tag); + } else + logError(0, "%s MS KEY CX1 TEST:.................SKIPPED \n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + + if (todo->MutualKeyCx2 == 1) { + logError(1, "%s MS KEY CX2 TEST: \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_KEY_CX2_MAP_MIN, + &thresholds_min, &trows, + &tcolumns); + + if (ret < 0 || (trows != msCompData.header.force_node || + tcolumns != msCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_KEY_CX2_MAP_MIN failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_KEY_CX2_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + + if (ret < 0 || (trows != msCompData.header.force_node || + tcolumns != msCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_KEY_CX2_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMap(msCompData.node_data, + msCompData.header.force_node, + msCompData.header.sense_node, + thresholds_min, thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap MS KEY CX2 failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS KEY CX2 TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError(0, + "%s MS KEY CX2 TEST:.................OK \n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError(0, "%s MS CX2 TEST:.................SKIPPED \n\n", + tag); + + if (todo->MutualKeyCxTotal == 1) { + logError(1, "%s MS KEY TOTAL CX TEST: \n", tag); + ret = readTotMutualSenseCompensationData( + LOAD_PANEL_CX_TOT_MS_KEY, &totCompData); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeTotalCx failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_KEY_TOTAL_CX_MAP_MIN, + &thresholds_min, &trows, + &tcolumns); + + if (ret < 0 || (trows != totCompData.header.force_node || + tcolumns != totCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_KEY_TOTAL_CX_MAP_MIN failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_KEY_TOTAL_CX_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + + if (ret < 0 || (trows != totCompData.header.force_node || + tcolumns != totCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_KEY_TOTAL_CX_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapTotal(totCompData.node_data, + totCompData.header.force_node, + totCompData.header.sense_node, + thresholds_min, thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap MS TOTAL KEY CX TEST failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s MS KEY TOTAL CX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s MS KEY TOTAL CX TEST:.................OK \n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + kfree(totCompData.node_data); + totCompData.node_data = NULL; + } else + logError(0, + "%s MS KEY TOTAL CX TEST:.................SKIPPED \n", + tag); + +ERROR: + logError(0, "%s \n", tag); + + if (count_fail == 0) { + logError(0, + "%s MS KEY CX testes finished!.................OK\n", + tag); + kfree(msCompData.node_data); + msCompData.node_data = NULL; + return OK; + } else { + print_frame_i8("MS Key Init Data (Cx2) =", + array1dTo2d_i8(msCompData.node_data, + msCompData.node_data_size, + msCompData.header.sense_node), + msCompData.header.force_node, + msCompData.header.sense_node); + logError( + 0, + "%s MS Key CX testes finished!.................FAILED fails_count = %d\n\n", + tag, count_fail); + + if (thresholds != NULL) { + kfree(thresholds); + thresholds = NULL; + } + if (thresholds_min != NULL) { + kfree(thresholds_min); + thresholds_min = NULL; + } + if (thresholds_max != NULL) { + kfree(thresholds_max); + thresholds_max = NULL; + } + if (msCompData.node_data != NULL) { + kfree(msCompData.node_data); + msCompData.node_data = NULL; + } + if (totCompData.node_data != NULL) { + kfree(totCompData.node_data); + totCompData.node_data = NULL; + } + return (ERROR_TEST_CHECK_FAIL | ERROR_PROD_TEST_DATA); + } + +ERROR_LIMITS: + + if (thresholds != NULL) { + kfree(thresholds); + thresholds = NULL; + } + if (thresholds_min != NULL) { + kfree(thresholds_min); + thresholds_min = NULL; + } + if (thresholds_max != NULL) { + kfree(thresholds_max); + thresholds_max = NULL; + } + if (msCompData.node_data != NULL) { + kfree(msCompData.node_data); + msCompData.node_data = NULL; + } + if (totCompData.node_data != NULL) { + kfree(totCompData.node_data); + totCompData.node_data = NULL; + } + return ret; +} + +/** + * Perform all the tests selected in a TestTodo variable related to MS LowPower + * Init data (touch, keys etc..) + * @param path_limits name of Production Limit file to load or + * "NULL" if the limits data should be loaded by a .h file + * @param stop_on_fail if 1, the test flow stops at the first data check + * failure otherwise it keeps going performing all the selected test + * @param todo pointer to a TestToDo variable which select the test to do + * @return OK if success or an error code which specify the type of error + */ +int production_test_ms_cx_lp(char *path_limits, int stop_on_fail, + TestToDo *todo) +{ + int ret; + int count_fail = 0; + + int *thresholds = NULL; + int *thresholds_min = NULL; + int *thresholds_max = NULL; + int trows, tcolumns; + + MutualSenseData msCompData; + TotMutualSenseData totCompData; + + u8 *adjhor = NULL; + + u8 *adjvert = NULL; + + u16 container; + /* u16 *total_cx = NULL; */ + u16 *total_adjhor = NULL; + u16 *total_adjvert = NULL; + + /* MS CX TEST */ + logError(0, "%s\n", tag); + + ret = readMutualSenseCompensationData(LOAD_CX_MS_LOW_POWER, + &msCompData); + /* read MS compensation data */ + if (ret < 0) { + logError( + 1, + "%s production_test_data: readMutualSenseCompensationData failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + return ret | ERROR_PROD_TEST_DATA; + } + + ret = readTotMutualSenseCompensationData(LOAD_PANEL_CX_TOT_MS_LOW_POWER, + &totCompData); + /* read TOT MS compensation data */ + if (ret < 0) { + logError( + 1, + "%s production_test_data: readTotMutualSenseCompensationData failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + kfree(msCompData.node_data); + msCompData.node_data = NULL; + return ret | ERROR_PROD_TEST_DATA; + } + + if (todo->MutualCx1LP == 1) { + logError(1, "%s MS LP CX1 TEST:\n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_CX1_LP_MIN_MAX, &thresholds, + &trows, &tcolumns); + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_CX1_LP_MIN_MAX failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + container = (u16)msCompData.cx1; + ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], + thresholds[1]); + /* check the limits */ + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax MS LP CX1 failed... ERROR COUNT = %d\n", + tag, ret); + logError(0, + "%s MS LP CX1 TEST:.................FAIL\n\n", + tag); + count_fail += 1; + if (stop_on_fail) + goto ERROR; + } else + logError(0, "%s MS LP CX1 TEST:.................OK\n\n", + tag); + } else + logError(0, "%s MS LP CX1 TEST:.................SKIPPED\n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + + if (todo->MutualCx2LP == 1) { + logError(1, "%s MS LP CX2 MIN MAX TEST:\n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_CX2_LP_MAP_MIN, + &thresholds_min, &trows, + &tcolumns); + /* load min thresholds */ + if (ret < 0 || (trows != msCompData.header.force_node || + tcolumns != msCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_CX2_LP_MAP_MIN failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_CX2_LP_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + /* load max thresholds */ + if (ret < 0 || (trows != msCompData.header.force_node || + tcolumns != msCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_CX2_LP_MAP_MAX failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMap(msCompData.node_data, + msCompData.header.force_node, + msCompData.header.sense_node, + thresholds_min, thresholds_max); + /* check the limits */ + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap MS LP CX2 MIN MAX failed... ERROR COUNT = %d\n", + tag, ret); + logError( + 0, + "%s MS LP CX2 MIN MAX TEST:.................FAIL\n\n", + tag); + count_fail += 1; + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s MS LP CX2 MIN MAX TEST:.................OK\n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError( + 0, + "%s MS LP CX2 MIN MAX TEST:.................SKIPPED\n\n", + tag); + + if (todo->MutualCx2AdjLP == 1) { + logError(1, "%s MS LP CX2 ADJ TEST:\n", tag); + /* MS CX2 ADJ HORIZ */ + logError(0, "%s MS LP CX2 ADJ HORIZ TEST:\n", tag); + + ret = computeAdjHoriz(msCompData.node_data, + msCompData.header.force_node, + msCompData.header.sense_node, &adjhor); + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjHoriz failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + logError(0, "%s MS LP CX2 ADJ HORIZ computed!\n", tag); + + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_CX2_ADJH_LP_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + if (ret < 0 || (trows != msCompData.header.force_node || + tcolumns != msCompData.header.sense_node - 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_CX2_ADJH_LP_MAP_MAX failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdj(adjhor, msCompData.header.force_node, + msCompData.header.sense_node - 1, + thresholds_max); + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMapAdj CX2 ADJH LP failed... ERROR COUNT = %d\n", + tag, ret); + logError( + 0, + "%s MS LP CX2 ADJ HORIZ TEST:.................FAIL\n\n", + tag); + count_fail += 1; + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s MS LP CX2 ADJ HORIZ TEST:.................OK\n\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(adjhor); + adjhor = NULL; + + /* MS CX2 ADJ VERT */ + logError(0, "%s MS LP CX2 ADJ VERT TEST:\n", tag); + + ret = computeAdjVert(msCompData.node_data, + msCompData.header.force_node, + msCompData.header.sense_node, &adjvert); + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjVert failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + logError(0, "%s MS LP CX2 ADJ VERT computed!\n", tag); + + ret = parseProductionTestLimits(path_limits, &limit_file, + MS_CX2_ADJV_LP_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + if (ret < 0 || (trows != msCompData.header.force_node - 1 || + tcolumns != msCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_CX2_ADJV_LP_MAP_MAX failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdj(adjvert, + msCompData.header.force_node - 1, + msCompData.header.sense_node - 1, + thresholds_max); + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMapAdj CX2 ADJV LP failed... ERROR COUNT = %d\n", + tag, ret); + logError( + 0, + "%s MS LP CX2 ADJ HORIZ TEST:.................FAIL\n\n", + tag); + count_fail += 1; + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s MS LP CX2 ADJ VERT TEST:.................OK\n\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(adjvert); + adjvert = NULL; + } else + logError(0, + "%s MS LP CX2 ADJ TEST:.................SKIPPED\n\n", + tag); + + /* START OF TOTAL CHECK */ + + if (todo->MutualCxTotalLP == 1 || todo->MutualCxTotalAdjLP == 1) { + if (todo->MutualCxTotalLP == 1) { + logError(1, "%s MS TOTAL LP CX MIN MAX TEST:\n", tag); + ret = parseProductionTestLimits(path_limits, + &limit_file, + MS_TOTAL_CX_LP_MAP_MIN, + &thresholds_min, &trows, + &tcolumns); + /* load min thresholds */ + if (ret < 0 || + (trows != totCompData.header.force_node || + tcolumns != totCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_LP_MAP_MIN failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits(path_limits, + &limit_file, + MS_TOTAL_CX_LP_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + /* load max thresholds */ + if (ret < 0 || + (trows != totCompData.header.force_node || + tcolumns != totCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_LP_MAP_MAX failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapTotal(totCompData.node_data, + totCompData.header.force_node, + totCompData.header.sense_node, + thresholds_min, + thresholds_max); + /* check the limits */ + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap MS TOTAL CX LP TEST failed... ERROR COUNT = %d\n", + tag, ret); + logError( + 0, + "%s MS TOTAL CX LP MIN MAX TEST:.................FAIL\n\n", + tag); + count_fail += 1; + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s MS TOTAL CX LP MIN MAX TEST:.................OK\n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError( + 0, + "%s MS TOTAL CX LP MIN MAX TEST:.................SKIPPED\n\n", + tag); + + if (todo->MutualCxTotalAdjLP == 1) { + /* MS TOTAL CX ADJ HORIZ */ + logError(1, "%s MS TOTAL CX ADJ HORIZ LP TEST:\n", tag); + + ret = computeAdjHorizTotal( + totCompData.node_data, + totCompData.header.force_node, + totCompData.header.sense_node, &total_adjhor); + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjHoriz failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + logError(0, "%s MS TOTAL CX ADJ HORIZ LP computed!\n", + tag); + + ret = parseProductionTestLimits( + path_limits, &limit_file, + MS_TOTAL_CX_ADJH_LP_MAP_MAX, &thresholds_max, + &trows, &tcolumns); + if (ret < 0 || + (trows != totCompData.header.force_node || + tcolumns != totCompData.header.sense_node - 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_ADJH_LP_MAP_MAX failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdjTotal( + total_adjhor, totCompData.header.force_node, + totCompData.header.sense_node - 1, + thresholds_max); + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMapAdj MS TOTAL CX ADJH LP failed... ERROR COUNT = %d\n", + tag, ret); + logError( + 0, + "%s MS TOTAL CX ADJ HORIZ LP TEST:.................FAIL\n\n", + tag); + count_fail += 1; + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s MS TOTAL CX ADJ HORIZ LP TEST:.................OK\n\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(total_adjhor); + total_adjhor = NULL; + + /* MS TOTAL CX ADJ VERT */ + logError(0, "%s MS TOTAL CX ADJ VERT LP TEST:\n", tag); + + ret = computeAdjVertTotal(totCompData.node_data, + totCompData.header.force_node, + totCompData.header.sense_node, + &total_adjvert); + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjVert failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + logError(0, "%s MS TOTAL CX ADJ VERT LP computed!\n", + tag); + + ret = parseProductionTestLimits( + path_limits, &limit_file, + MS_TOTAL_CX_ADJV_LP_MAP_MAX, &thresholds_max, + &trows, &tcolumns); + if (ret < 0 || + (trows != totCompData.header.force_node - 1 || + tcolumns != totCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_ADJV_LP_MAP_MAX failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdjTotal( + total_adjvert, + totCompData.header.force_node - 1, + totCompData.header.sense_node - 1, + thresholds_max); + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMapAdj MS TOTAL CX ADJV failed... ERROR COUNT = %d\n", + tag, ret); + logError( + 0, + "%s MS TOTAL CX ADJ HORIZ LP TEST:.................FAIL\n", + tag); + count_fail += 1; + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s MS TOTAL CX ADJ VERT LP TEST:.................OK\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(total_adjvert); + total_adjvert = NULL; + } else + logError( + 0, + "%s MS TOTAL CX ADJ LP TEST:.................SKIPPED\n", + tag); + + kfree(totCompData.node_data); + totCompData.node_data = NULL; + } else + logError(0, "%s MS TOTAL CX LP TEST:.................SKIPPED\n", + tag); + +ERROR: + logError(0, "%s\n", tag); + if (count_fail == 0) { + logError(0, "%s MS LP CX testes finished!.................OK\n", + tag); + kfree(msCompData.node_data); + msCompData.node_data = NULL; + return OK; + } else { + print_frame_i8("MS LP Init Data (Cx2) =", + array1dTo2d_i8(msCompData.node_data, + msCompData.node_data_size, + msCompData.header.sense_node), + msCompData.header.force_node, + msCompData.header.sense_node); + print_frame_short( + " TOT MS LP Init Data (Cx) =", + array1dTo2d_short(totCompData.node_data, + totCompData.node_data_size, + totCompData.header.sense_node), + totCompData.header.force_node, + totCompData.header.sense_node); + logError( + 0, + "%s MS LP CX testes finished!.................FAILED fails_count = %d\n\n", + tag, count_fail); + if (thresholds != NULL) { + kfree(thresholds); + thresholds = NULL; + } + if (thresholds_min != NULL) { + kfree(thresholds_min); + thresholds_min = NULL; + } + if (thresholds_max != NULL) { + kfree(thresholds_max); + thresholds_max = NULL; + } + if (adjhor != NULL) { + kfree(adjhor); + adjhor = NULL; + } + if (adjvert != NULL) { + kfree(adjvert); + adjvert = NULL; + } + if (totCompData.node_data != NULL) { + kfree(totCompData.node_data); + totCompData.node_data = NULL; + } + if (total_adjhor != NULL) { + kfree(total_adjhor); + total_adjhor = NULL; + } + if (total_adjvert != NULL) { + kfree(total_adjvert); + total_adjvert = NULL; + } + if (msCompData.node_data != NULL) { + kfree(msCompData.node_data); + msCompData.node_data = NULL; + } + return ERROR_TEST_CHECK_FAIL | ERROR_PROD_TEST_DATA; + } + +ERROR_LIMITS: + if (thresholds != NULL) { + kfree(thresholds); + thresholds = NULL; + } + if (thresholds_min != NULL) { + kfree(thresholds_min); + thresholds_min = NULL; + } + if (thresholds_max != NULL) { + kfree(thresholds_max); + thresholds_max = NULL; + } + if (adjhor != NULL) { + kfree(adjhor); + adjhor = NULL; + } + if (adjvert != NULL) { + kfree(adjvert); + adjvert = NULL; + } + if (totCompData.node_data != NULL) { + kfree(totCompData.node_data); + totCompData.node_data = NULL; + } + if (total_adjhor != NULL) { + kfree(total_adjhor); + total_adjhor = NULL; + } + if (total_adjvert != NULL) { + kfree(total_adjvert); + total_adjvert = NULL; + } + if (msCompData.node_data != NULL) { + kfree(msCompData.node_data); + msCompData.node_data = NULL; + } + return ret; +} + +int production_test_ss_hover_raw(char *path_limits, int stop_on_fail, + TestToDo *todo) +{ + int ret; + int rows, columns; + int *thresholds = NULL; + int trows, tcolumns; + u8 hover_cnt[4] = { 0xa8, 0x0b, 0x01, 0x00 }; + + SelfSenseFrame ssHoverRawFrame; + int count_fail = 0; + + ret = fts_write_dma_safe(hover_cnt, sizeof(hover_cnt)); + if (ret != OK) { + logError(1, "%s hover clear count ERROR = %d\n", tag, ret); + goto ERROR_LIMITS; + } + + logError(0, "%s Getting SS Hover Frame...\n", tag); + ret = setScanMode(SCAN_MODE_LOCKED, LOCKED_HOVER); + msleep(WAIT_FOR_FRESH_FRAMES); + ret |= setScanMode(SCAN_MODE_ACTIVE, 0x00); + msleep(WAIT_AFTER_SENSEOFF); + ret |= getSSFrame3(SS_HVR_RAW, &ssHoverRawFrame); + /* SS Hover RAW FORCE TEST */ + logError(0, "%s SS Hover RAW FORCE TEST:\n", tag); + + logError(0, "%s SS RAW FORCE MIN MAX TEST:\n", tag); + if (todo->SelfHoverForceRaw == 1) { + columns = 1; + rows = ssHoverRawFrame.header.force_node; + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_HOVER_RAW_FORCE_MIN_MAX, + &thresholds, &trows, &tcolumns); + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_HOVER_RAW_FORCE_MIN_MAX failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMinMax(ssHoverRawFrame.force_data, rows, + columns, thresholds[0], thresholds[1]); + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax SS HOVER RAW FORCE failed... ERROR COUNT = %d\n", + tag, ret); + logError( + 0, + "%s SS Hover RAW FORCE MIN MAX TEST:.................FAIL\n\n", + tag); + count_fail += 1; + print_frame_short( + "SS Raw force frame =", + array1dTo2d_short(ssHoverRawFrame.force_data, + rows * columns, columns), + rows, columns); + if (stop_on_fail) { + ret = ERROR_PROD_TEST_DATA | + ERROR_TEST_CHECK_FAIL; + goto ERROR_LIMITS; + } + } else + logError( + 0, + "%s SS RAW FORCE MIN MAX TEST:.................OK\n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError( + 0, + "%s SS RAW FORCE MIN MAX TEST:.................SKIPPED\n\n", + tag); + logError(0, "%s\n", tag); + /* SS Hover RAW SENSE TEST */ + logError(0, "%s SS Hover RAW SENSE TEST:\n", tag); + + logError(0, "%s SS RAW SENSE MIN MAX TEST:\n", tag); + if (todo->SelfHoverSenceRaw == 1) { + columns = ssHoverRawFrame.header.sense_node; + rows = 1; + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_HOVER_RAW_SENSE_MIN_MAX, + &thresholds, &trows, &tcolumns); + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_RAW_SENSE_MIN_MAX failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMinMax(ssHoverRawFrame.sense_data, rows, + columns, thresholds[0], thresholds[1]); + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax SS Hover RAW SENSE failed... ERROR COUNT = %d\n", + tag, ret); + logError( + 0, + "%s SS Hover RAW SENSE MIN MAX TEST:.................FAIL\n", + tag); + count_fail += 1; + print_frame_short( + "SS Hover Raw sense frame =", + array1dTo2d_short(ssHoverRawFrame.sense_data, + rows * columns, columns), + rows, columns); + if (stop_on_fail) { + ret = ERROR_PROD_TEST_DATA | + ERROR_TEST_CHECK_FAIL; + goto ERROR_LIMITS; + } + } else + logError( + 0, + "%s SS Hover RAW SENSE MIN MAX TEST:.................OK\n", + tag); + + kfree(thresholds); + thresholds = NULL; + } + +ERROR_LIMITS: + if (ssHoverRawFrame.force_data != NULL) + kfree(ssHoverRawFrame.force_data); + if (ssHoverRawFrame.sense_data != NULL) + kfree(ssHoverRawFrame.sense_data); + if (thresholds != NULL) + kfree(thresholds); + + return ret; +} + +/** + * Perform all the test selected in a TestTodo variable related to SS raw data (touch, keys etc..) + * @param path_limits name of Production Limit file to load or "NULL" if the limits data should be loaded by a .h file + * @param stop_on_fail if 1, the test flow stops at the first data check failure otherwise it keeps going performing all the selected test + * @param todo pointer to a TestToDo variable which select the test to do + * @return OK if success or an error code which specify the type of error encountered + */ +int production_test_ss_raw(char *path_limits, int stop_on_fail, TestToDo *todo) +{ + int ret; + int count_fail = 0; + int rows, columns; + SelfSenseFrame ssRawFrame; + int *thresholds = NULL; + int trows, tcolumns; + logError(0, "%s \n", tag); + /******************************* Self Sense Test *******************************/ + logError(0, "%s Getting SS Frame... \n", tag); + ret = setScanMode(SCAN_MODE_LOCKED, LOCKED_ACTIVE); + mdelay(WAIT_FOR_FRESH_FRAMES); + ret |= setScanMode(SCAN_MODE_ACTIVE, 0x00); + mdelay(WAIT_AFTER_SENSEOFF); + ret |= getSSFrame3(SS_RAW, &ssRawFrame); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: getSSFrame failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + return (ret | ERROR_PROD_TEST_DATA); + } + + if (todo->SelfForceRaw == 1 || todo->SelfForceRawGap == 1) { + columns = 1; + rows = ssRawFrame.header.force_node; + logError(0, "%s SS RAW FORCE MIN MAX TEST: \n", tag); + + if (todo->SelfForceRaw == 1) { + logError(1, "%s SS RAW FORCE MIN MAX TEST: \n", tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, SS_RAW_FORCE_MIN_MAX, + &thresholds, &trows, &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_RAW_FORCE_MIN_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMinMax(ssRawFrame.force_data, rows, + columns, thresholds[0], + thresholds[1]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax SS RAW FORCE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS RAW (PROXIMITY) FORCE MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + print_frame_short( + "SS Raw force frame =", + array1dTo2d_short(ssRawFrame.force_data, + rows * columns, + columns), + rows, columns); + + if (stop_on_fail) { + ret = ERROR_PROD_TEST_DATA | + ERROR_TEST_CHECK_FAIL; + goto ERROR_LIMITS; + } + } else + logError( + 0, + "%s SS RAW (PROXIMITY) FORCE MIN MAX TEST:.................OK \n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError( + 0, + "%s SS RAW (PROXIMITY) FORCE MIN MAX TEST:.................SKIPPED \n\n", + tag); + + logError(0, "%s \n", tag); + + if (todo->SelfForceRawGap == 1) { + logError(1, "%s SS RAW FORCE GAP TEST: \n", tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, SS_RAW_FORCE_GAP, + &thresholds, &trows, &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_RAW_FORCE_GAP failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsGap(ssRawFrame.force_data, rows, + columns, thresholds[0]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsGap SS RAW FORCE GAP failed... ERROR = %08X \n", + tag, ret); + logError( + 0, + "%s SS RAW FORCE GAP TEST:.................FAIL \n\n", + tag); + count_fail += 1; + print_frame_short( + "SS Raw force frame =", + array1dTo2d_short(ssRawFrame.force_data, + rows * columns, + columns), + rows, columns); + + if (stop_on_fail) { + ret = ERROR_PROD_TEST_DATA | + ERROR_TEST_CHECK_FAIL; + goto ERROR_LIMITS; + } + } else + logError( + 0, + "%s SS RAW (PROXIMITY) FORCE GAP TEST:.................OK \n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError( + 0, + "%s SS RAW (PROXIMITY) FORCE GAP TEST:.................SKIPPED \n\n", + tag); + + kfree(ssRawFrame.force_data); + ssRawFrame.force_data = NULL; + } else + logError( + 0, + "%s SS RAW (PROXIMITY) FORCE TEST:.................SKIPPED \n\n", + tag); + + logError(0, "%s \n", tag); + + if (todo->SelfSenseRaw == 1 || todo->SelfSenseRawGap == 1) { + columns = ssRawFrame.header.sense_node; + rows = 1; + + if (todo->SelfSenseRaw == 1) { + logError(1, "%s SS RAW SENSE MIN MAX TEST: \n", tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, SS_RAW_SENSE_MIN_MAX, + &thresholds, &trows, &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_RAW_SENSE_MIN_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMinMax(ssRawFrame.sense_data, rows, + columns, thresholds[0], + thresholds[1]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax SS RAW SENSE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS RAW SENSE MIN MAX TEST:.................FAIL \n", + tag); + count_fail += 1; + print_frame_short( + "SS Raw sense frame =", + array1dTo2d_short(ssRawFrame.sense_data, + rows * columns, + columns), + rows, columns); + + if (stop_on_fail) { + ret = ERROR_PROD_TEST_DATA | + ERROR_TEST_CHECK_FAIL; + goto ERROR_LIMITS; + } + } else + logError( + 0, + "%s SS RAW (PROXIMITY) SENSE MIN MAX TEST:.................OK \n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError( + 0, + "%s SS RAW (PROXIMITY) SENSE MIN MAX TEST:.................SKIPPED \n", + tag); + + logError(0, "%s \n", tag); + + if (todo->SelfSenseRawGap == 1) { + logError(1, "%s SS RAW SENSE GAP TEST: \n", tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, SS_RAW_SENSE_GAP, + &thresholds, &trows, &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_RAW_SENSE_GAP failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsGap(ssRawFrame.sense_data, rows, + columns, thresholds[0]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsGap SS RAW SENSE GAP failed... ERROR = %08X \n", + tag, ret); + logError( + 0, + "%s SS RAW SENSE GAP TEST:.................FAIL \n", + tag); + count_fail += 1; + print_frame_short( + "SS Raw sense frame =", + array1dTo2d_short(ssRawFrame.sense_data, + rows * columns, + columns), + rows, columns); + + if (stop_on_fail) { + ret = ERROR_PROD_TEST_DATA | + ERROR_TEST_CHECK_FAIL; + goto ERROR_LIMITS; + } + } else + logError( + 0, + "%s SS RAW (PROXIMITY) SENSE GAP TEST:.................OK \n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError( + 0, + "%s SS RAW (PROXIMITY) SENSE GAP TEST:.................SKIPPED \n", + tag); + + kfree(ssRawFrame.sense_data); + ssRawFrame.sense_data = NULL; + } + + ret = production_test_ss_raw_lp(path_limits, stop_on_fail, todo); + + if (ret < OK) { + logError( + 1, + "%s production_test_data: production_test_ss_raw_lp failed... ERROR = %08X \n", + tag, ret); + count_fail += 1; + } + if (todo->SelfHoverForceRaw == 1 || todo->SelfHoverSenceRaw) { + ret = production_test_ss_hover_raw(path_limits, stop_on_fail, + todo); + if (ret < OK) { + logError( + 1, + "%s production_test_data: production_test_ss_hover_raw failed... ERROR = %08X\n", + tag, ret); + count_fail += 1; + } + } + + logError(0, "%s \n", tag); + + if (count_fail == 0) { + logError(0, "%s SS RAW testes finished!.................OK\n\n", + tag); + return OK; + } else { + logError( + 0, + "%s SS RAW testes finished!.................FAILED fails_count = %d\n\n", + tag, count_fail); + return (ERROR_TEST_CHECK_FAIL | ERROR_PROD_TEST_DATA); + } + +ERROR_LIMITS: + + if (ssRawFrame.force_data != NULL) + kfree(ssRawFrame.force_data); + + if (ssRawFrame.sense_data != NULL) + kfree(ssRawFrame.sense_data); + + if (thresholds != NULL) + kfree(thresholds); + + return ret; +} + +/** + * Perform all the test selected in a TestTodo variable related to SS raw data low power + * @param path_limits name of Production Limit file to load or "NULL" if the limits data should be loaded by a .h file + * @param stop_on_fail if 1, the test flow stops at the first data check failure otherwise it keeps going performing all the selected test + * @param todo pointer to a TestToDo variable which select the test to do + * @return OK if success or an error code which specify the type of error encountered + */ +int production_test_ss_raw_lp(char *path_limits, int stop_on_fail, + TestToDo *todo) +{ + int ret; + int count_fail = 0; + int rows, columns; + SelfSenseFrame ssRawFrame; + int *thresholds = NULL; + int trows, tcolumns; + logError(0, "%s \n", tag); + /******************************* Self Sense Test *******************************/ + ret = setScanMode(SCAN_MODE_LOCKED, LOCKED_LP_DETECT); + mdelay(WAIT_FOR_FRESH_FRAMES); + ret |= setScanMode(SCAN_MODE_ACTIVE, 0x00); + mdelay(WAIT_AFTER_SENSEOFF); + ret |= getSSFrame3(SS_RAW, &ssRawFrame); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: getSSFrame failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + return (ret | ERROR_PROD_TEST_DATA); + } + + if (todo->SelfForceRawLP == 1 || todo->SelfForceRawGapLP == 1) { + columns = 1; + rows = ssRawFrame.header.force_node; + + if (todo->SelfForceRawLP == 1) { + logError(1, "%s SS RAW LP FORCE MIN MAX TEST: \n", + tag); + ret = parseProductionTestLimits(path_limits, + &limit_file, + SS_RAW_LP_FORCE_MIN_MAX, + &thresholds, &trows, + &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_RAW_FORCE_MIN_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMinMax(ssRawFrame.force_data, rows, + columns, thresholds[0], + thresholds[1]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax SS RAW FORCE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS RAW LP FORCE MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + print_frame_short( + "SS Raw LP force frame =", + array1dTo2d_short(ssRawFrame.force_data, + rows * columns, + columns), + rows, columns); + + if (stop_on_fail) { + ret = ERROR_PROD_TEST_DATA | + ERROR_TEST_CHECK_FAIL; + goto ERROR_LIMITS; + } + } else + logError( + 0, + "%s SS RAW LP FORCE MIN MAX TEST:.................OK \n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError( + 0, + "%s SS RAW LP FORCE MIN MAX TEST:.................SKIPPED \n\n", + tag); + + logError(0, "%s \n", tag); + + if (todo->SelfForceRawGapLP == 1) { + logError(1, "%s SS RAW LP FORCE GAP TEST: \n", tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, SS_RAW_LP_FORCE_GAP, + &thresholds, &trows, &tcolumns); + + if (ret < OK || (trows != 1 || tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_RAW_FORCE_GAP failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsGap(ssRawFrame.force_data, rows, + columns, thresholds[0]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsGap SS RAW FORCE GAP failed... ERROR = %08X \n", + tag, ret); + logError( + 0, + "%s SS RAW LP FORCE GAP TEST:.................FAIL \n\n", + tag); + count_fail += 1; + print_frame_short( + "SS Raw LP force frame =", + array1dTo2d_short(ssRawFrame.force_data, + rows * columns, + columns), + rows, columns); + + if (stop_on_fail) { + ret = ERROR_PROD_TEST_DATA | + ERROR_TEST_CHECK_FAIL; + goto ERROR_LIMITS; + } + } else + logError( + 0, + "%s SS RAW LP FORCE GAP TEST:.................OK \n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError( + 0, + "%s SS RAW LP FORCE GAP TEST:.................SKIPPED \n\n", + tag); + + kfree(ssRawFrame.force_data); + ssRawFrame.force_data = NULL; + } else + logError( + 0, + "%s SS RAW LP FORCE TEST:.................SKIPPED \n\n", + tag); + + logError(0, "%s \n", tag); + + if (todo->SelfSenseRawLP == 1 || todo->SelfSenseRawGapLP == 1) { + columns = ssRawFrame.header.sense_node; + rows = 1; + logError(0, "%s SS RAW LP SENSE MIN MAX TEST: \n", tag); + + if (todo->SelfSenseRawLP == 1) { + logError(1, "%s SS RAW LP SENSE MIN MAX TEST: \n", + tag); + ret = parseProductionTestLimits(path_limits, + &limit_file, + SS_RAW_LP_SENSE_MIN_MAX, + &thresholds, &trows, + &tcolumns); + + if (ret < OK || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_RAW_SENSE_MIN_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMinMax(ssRawFrame.sense_data, rows, + columns, thresholds[0], + thresholds[1]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax SS RAW SENSE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS RAW LP SENSE MIN MAX TEST:.................FAIL \n", + tag); + count_fail += 1; + print_frame_short( + "SS Raw LP sense frame =", + array1dTo2d_short(ssRawFrame.sense_data, + rows * columns, + columns), + rows, columns); + + if (stop_on_fail) { + ret = ERROR_PROD_TEST_DATA | + ERROR_TEST_CHECK_FAIL; + goto ERROR_LIMITS; + } + } else + logError( + 0, + "%s SS RAW SENSE MIN MAX TEST:.................OK \n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError( + 0, + "%s SS RAW LP SENSE MIN MAX TEST:.................SKIPPED \n", + tag); + + logError(0, "%s \n", tag); + + if (todo->SelfSenseRawGapLP == 1) { + logError(1, "%s SS RAW LP SENSE GAP TEST: \n", tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, SS_RAW_LP_SENSE_GAP, + &thresholds, &trows, &tcolumns); + + if (ret < OK || (trows != 1 || tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_RAW_SENSE_GAP failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsGap(ssRawFrame.sense_data, rows, + columns, thresholds[0]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsGap SS RAW SENSE GAP failed... ERROR = %08X \n", + tag, ret); + logError( + 0, + "%s SS RAW LP SENSE GAP TEST:.................FAIL \n", + tag); + count_fail += 1; + print_frame_short( + "SS Raw LP sense frame =", + array1dTo2d_short(ssRawFrame.sense_data, + rows * columns, + columns), + rows, columns); + + if (stop_on_fail) { + ret = ERROR_PROD_TEST_DATA | + ERROR_TEST_CHECK_FAIL; + goto ERROR_LIMITS; + } + } else + logError( + 0, + "%s SS RAW LP SENSE GAP TEST:.................OK \n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError( + 0, + "%s SS RAW LP SENSE GAP TEST:.................SKIPPED \n", + tag); + + kfree(ssRawFrame.sense_data); + ssRawFrame.sense_data = NULL; + } + + logError(0, "%s \n", tag); + + if (count_fail == 0) { + logError(0, + "%s SS RAW LP testes finished!.................OK\n\n", + tag); + return OK; + } else { + logError( + 0, + "%s SS RAW LP testes finished!.................FAILED fails_count = %d\n\n", + tag, count_fail); + return (ERROR_TEST_CHECK_FAIL | ERROR_PROD_TEST_DATA); + } + +ERROR_LIMITS: + + if (ssRawFrame.force_data != NULL) + kfree(ssRawFrame.force_data); + + if (ssRawFrame.sense_data != NULL) + kfree(ssRawFrame.sense_data); + + if (thresholds != NULL) + kfree(thresholds); + + return ret; +} + +int production_test_ss_hover_ix(char *path_limits, int stop_on_fail, + TestToDo *todo) +{ + TotSelfSenseData ssHoverCompData; + int ret; + int trows, tcolumns; + int *thresholds_min = NULL; + int *thresholds_max = NULL; + int count_fail = 0; + + /* ret = readSelfSenseCompensationData(LOAD_CX_SS_HOVER, &ssHoverCompData); */ + ret = readTotSelfSenseCompensationData( + STAPI_HOST_DATA_ID_PANEL_CX_SS_HVR, &ssHoverCompData); + /* read the SS compensation data */ + if (ret < 0) { + logError( + 1, + "%s production_test_data: readSelfSenseCompensationData failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + return ret | ERROR_PROD_TEST_DATA; + } + + logError(0, "%s SS Hover TOTAL IX FORCE TEST:\n", tag); + logError(0, "%s SS Hover TOTAL IX FORCE MIN MAX TEST:\n", tag); + if (todo->SelfHoverForceIxTotal == 1) { + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_HOVER_TOTAL_IX_FORCE_MAP_MIN, + &thresholds_min, &trows, + &tcolumns); + /* load the min thresholds */ + if (ret < 0 || (trows != ssHoverCompData.header.force_node || + tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_FORCE_MAP_MIN failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_TOTAL_IX_FORCE_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + /* load the max thresholds */ + if (ret < 0 || (trows != ssHoverCompData.header.force_node || + tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_FORCE_MAP_MAX failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapTotalFromU( + ssHoverCompData.ix_fm, + ssHoverCompData.header.force_node, 1, thresholds_min, + thresholds_max); + /* check the values with thresholds */ + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS TOTAL IX FORCE failed... ERROR COUNT = %d\n", + tag, ret); + logError( + 0, + "%s SS TOTAL IX FORCE MIN MAX TEST:.................FAIL\n\n", + tag); + count_fail += 1; + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS TOTAL IX FORCE MIN MAX TEST:.................OK\n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError( + 0, + "%s SS Hover TOTAL IX FORCE MIN MAX TEST:.................SKIPPED\n", + tag); + + logError(0, "%s SS HOVER TOTAL IX SENSE MIN MAX TEST:\n", tag); + if (todo->SelfHoverSenceIxTotal == 1) { + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_TOTAL_IX_SENSE_MAP_MIN, + &thresholds_min, &trows, + &tcolumns); + /* load the min thresholds */ + if (ret < 0 || + (trows != 1 || + tcolumns != ssHoverCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_SENSE_MAP_MIN failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_TOTAL_IX_SENSE_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + /* load the max thresholds */ + if (ret < 0 || + (trows != 1 || + tcolumns != ssHoverCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_SENSE_MAP_MAX failed... ERROR %08X\n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapTotalFromU( + ssHoverCompData.ix_sn, 1, + ssHoverCompData.header.sense_node, thresholds_min, + thresholds_max); + /* check the values with thresholds */ + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS TOTAL IX SENSE failed... ERROR COUNT = %d\n", + tag, ret); + logError( + 0, + "%s SS Hover TOTAL IX SENSE MIN MAX TEST:.................FAIL\n\n", + tag); + count_fail += 1; + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS TOTAL IX SENSE MIN MAX TEST:.................OK\n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError( + 0, + "%s SS Hover TOTAL IX SENSE MIN MAX TEST:.................SKIPPED\n", + tag); +ERROR: + logError(0, "%s\n", tag); + if (count_fail == 0) { + kfree(ssHoverCompData.ix_fm); + ssHoverCompData.ix_fm = NULL; + kfree(ssHoverCompData.ix_sn); + ssHoverCompData.ix_sn = NULL; + kfree(ssHoverCompData.cx_fm); + ssHoverCompData.cx_fm = NULL; + kfree(ssHoverCompData.cx_sn); + ssHoverCompData.cx_sn = NULL; + logError( + 0, + "%s SS Hover IX testes finished!.................OK\n\n", + tag); + return OK; + } else { + print_frame_u16( + "TOT SS hover Init Data Ix_fm = ", + array1dTo2d_u16(ssHoverCompData.ix_fm, + ssHoverCompData.header.force_node, 1), + ssHoverCompData.header.force_node, 1); + print_frame_short( + "TOT SS hover hover Init Data Cx_fm = ", + array1dTo2d_short(ssHoverCompData.cx_fm, + ssHoverCompData.header.force_node, 1), + ssHoverCompData.header.force_node, 1); + print_frame_u16( + "TOT SS hover Init Data Ix_sn = ", + array1dTo2d_u16(ssHoverCompData.ix_sn, + ssHoverCompData.header.sense_node, + ssHoverCompData.header.sense_node), + 1, ssHoverCompData.header.sense_node); + print_frame_short( + "TOT SS hover Init Data Cx_sn = ", + array1dTo2d_short(ssHoverCompData.cx_sn, + ssHoverCompData.header.sense_node, + ssHoverCompData.header.sense_node), + 1, ssHoverCompData.header.sense_node); + logError( + 0, + "%s SS hover IX CX testes finished!.................FAILED fails_count = %d\n\n", + tag, count_fail); + if (thresholds_min != NULL) + kfree(thresholds_min); + if (thresholds_max != NULL) + kfree(thresholds_max); + if (ssHoverCompData.ix_fm != NULL) + kfree(ssHoverCompData.ix_fm); + if (ssHoverCompData.ix_sn != NULL) + kfree(ssHoverCompData.ix_sn); + if (ssHoverCompData.cx_fm != NULL) + kfree(ssHoverCompData.cx_fm); + if (ssHoverCompData.cx_sn != NULL) + kfree(ssHoverCompData.cx_sn); + return ERROR_TEST_CHECK_FAIL | ERROR_PROD_TEST_DATA; + } +ERROR_LIMITS: + if (thresholds_min != NULL) + kfree(thresholds_min); + if (thresholds_max != NULL) + kfree(thresholds_max); + if (ssHoverCompData.ix_fm != NULL) + kfree(ssHoverCompData.ix_fm); + if (ssHoverCompData.ix_sn != NULL) + kfree(ssHoverCompData.ix_sn); + if (ssHoverCompData.cx_fm != NULL) + kfree(ssHoverCompData.cx_fm); + if (ssHoverCompData.cx_sn != NULL) + kfree(ssHoverCompData.cx_sn); + return ret; +} + +/** + * Perform all the tests selected in a TestTodo variable related to SS Init data (touch, keys etc..) + * @param path_limits name of Production Limit file to load or "NULL" if the limits data should be loaded by a .h file + * @param stop_on_fail if 1, the test flow stops at the first data check failure otherwise it keeps going performing all the selected test + * @param todo pointer to a TestToDo variable which select the test to do + * @return OK if success or an error code which specify the type of error encountered + */ +int production_test_ss_ix_cx(char *path_limits, int stop_on_fail, + TestToDo *todo) +{ + int ret; + int count_fail = 0; + int *thresholds = NULL; + int trows, tcolumns; + int *thresholds_min = NULL; + int *thresholds_max = NULL; + SelfSenseData ssCompData; + TotSelfSenseData totCompData; + u8 *adjhor = NULL; + u8 *adjvert = NULL; + short container; + u16 *total_adjhor = NULL; + u16 *total_adjvert = NULL; + logError(0, "%s \n", tag); + ret = readSelfSenseCompensationData(LOAD_CX_SS_TOUCH, &ssCompData); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: readSelfSenseCompensationData failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + return (ret | ERROR_PROD_TEST_DATA); + } + + ret = readTotSelfSenseCompensationData(LOAD_PANEL_CX_TOT_SS_TOUCH, + &totCompData); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: readTotSelfSenseCompensationData failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + kfree(ssCompData.ix2_fm); + kfree(ssCompData.ix2_sn); + kfree(ssCompData.cx2_fm); + kfree(ssCompData.cx2_sn); + return (ret | ERROR_PROD_TEST_DATA); + } + + /********************************************************* SS FORCE IX ****************************************************************/ + + if (todo->SelfForceIx1 == 1) { + logError(1, "%s SS IX1 FORCE TEST: \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_IX1_FORCE_MIN_MAX, + &thresholds, &trows, &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_IX1_FORCE_MIN_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + container = (short)ssCompData.f_ix1; + ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], + thresholds[1]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax SS IX1 FORCE TEST failed... ERROR COUNT = %d \n", + tag, ret); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS IX1 FORCE TEST:.................OK \n\n", + tag); + } else + logError(0, + "%s SS IX1 FORCE TEST:.................SKIPPED \n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + + if (todo->SelfForceIx2 == 1) { + logError(1, "%s SS IX2 FORCE MIN MAX TEST: \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_IX2_FORCE_MAP_MIN, + &thresholds_min, &trows, + &tcolumns); + + if (ret < 0 || + (trows != ssCompData.header.force_node || tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_IX2_FORCE_MAP_MIN failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_IX2_FORCE_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + + if (ret < 0 || + (trows != ssCompData.header.force_node || tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_IX2_FORCE_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapFromU(ssCompData.ix2_fm, + ssCompData.header.force_node, 1, + thresholds_min, thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS IX2 FORCE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS IX2 FORCE MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS IX2 FORCE MIN MAX TEST:.................OK \n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError( + 0, + "%s SS IX2 FORCE MIN MAX TEST:.................SKIPPED \n\n", + tag); + + if (todo->SelfForceIx2Adj == 1) { + logError(1, "%s SS IX2 FORCE ADJ TEST: \n", tag); + ret = computeAdjVertFromU(ssCompData.ix2_fm, + ssCompData.header.force_node, 1, + &adjvert); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjVert SS IX2 FORCE ADJV failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + logError(0, "%s SS IX2 FORCE ADJV computed! \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_IX2_FORCE_ADJV_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + + if (ret < 0 || (trows != ssCompData.header.force_node - 1 || + tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_IX2_FORCE_ADJV_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdj(adjvert, + ssCompData.header.force_node - 1, 1, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS IX2 FORCE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS IX2 FORCE ADJV TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS IX2 FORCE ADJV TEST:.................OK \n\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(adjvert); + adjvert = NULL; + } else + logError( + 0, + "%s SS IX2 FORCE ADJ TEST:.................SKIPPED \n\n", + tag); + + if (todo->SelfForceIxTotal == 1 || todo->SelfForceIxTotalAdj == 1) { + if (todo->SelfForceIxTotal == 1) { + logError(1, "%s SS TOTAL IX FORCE MIN MAX TEST: \n", + tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, + SS_TOTAL_IX_FORCE_MAP_MIN, &thresholds_min, + &trows, &tcolumns); + + if (ret < 0 || + (trows != totCompData.header.force_node || + tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_FORCE_MAP_MIN failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits( + path_limits, &limit_file, + SS_TOTAL_IX_FORCE_MAP_MAX, &thresholds_max, + &trows, &tcolumns); + + if (ret < 0 || + (trows != totCompData.header.force_node || + tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_FORCE_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapTotalFromU( + totCompData.ix_fm, + totCompData.header.force_node, 1, + thresholds_min, thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS TOTAL IX FORCE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS TOTAL IX FORCE MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS TOTAL IX FORCE MIN MAX TEST:.................OK \n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError( + 0, + "%s SS TOTAL IX FORCE MIN MAX TEST:.................SKIPPED \n", + tag); + + if (todo->SelfForceIxTotalAdj == 1) { + logError(1, "%s SS TOTAL IX FORCE ADJVERT TEST: \n", + tag); + ret = computeAdjVertTotalFromU( + totCompData.ix_fm, + totCompData.header.force_node, 1, + &total_adjvert); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjVert SS TOTAL IX FORCE ADJV failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + logError(0, "%s SS TOTAL IX FORCE ADJV computed! \n", + tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, + SS_TOTAL_IX_FORCE_ADJV_MAP_MAX, &thresholds_max, + &trows, &tcolumns); + + if (ret < 0 || + (trows != totCompData.header.force_node - 1 || + tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_FORCE_ADJV_MAP_MAX... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdjTotal( + total_adjvert, + totCompData.header.force_node - 1, 1, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS TOTAL IX FORCE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS TOTAL IX FORCE ADJV TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS TOTAL IX FORCE ADJV TEST:.................OK \n\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(total_adjvert); + total_adjvert = NULL; + } else + logError( + 0, + "%s SS TOTAL IX FORCE ADJ TEST:.................SKIPPED \n", + tag); + } else + logError( + 0, + "%s SS TOTAL IX FORCE TEST:.................SKIPPED \n\n", + tag); + + /********************************************************* SS SENSE IX ****************************************************************/ + + if (todo->SelfSenseIx1 == 1) { + logError(1, "%s SS IX1 SENSE TEST: \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_IX1_SENSE_MIN_MAX, + &thresholds, &trows, &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_IX1_SENSE_MIN_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + container = (short)ssCompData.s_ix1; + ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], + thresholds[1]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax SS IX1 SENSE TEST failed... ERROR COUNT = %d \n", + tag, ret); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS IX1 SENSE TEST:.................OK \n\n", + tag); + } else + logError(0, + "%s SS IX1 SENSE TEST:.................SKIPPED \n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + + if (todo->SelfSenseIx2 == 1) { + logError(1, "%s SS IX2 SENSE MIN MAX TEST: \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_IX2_SENSE_MAP_MIN, + &thresholds_min, &trows, + &tcolumns); + + if (ret < 0 || + (trows != 1 || tcolumns != ssCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_IX2_SENSE_MAP_MIN failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_IX2_SENSE_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + + if (ret < 0 || + (trows != 1 || tcolumns != ssCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_IX2_SENSE_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapFromU(ssCompData.ix2_sn, 1, + ssCompData.header.sense_node, + thresholds_min, thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS IX2 SENSE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS IX2 SENSE MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS IX2 SENSE MIN MAX TEST:.................OK \n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError( + 0, + "%s SS IX2 SENSE MIN MAX TEST:.................SKIPPED \n\n", + tag); + + if (todo->SelfSenseIx2Adj == 1) { + logError(1, "%s SS IX2 SENSE ADJHORIZ TEST: \n", tag); + ret = computeAdjHorizFromU(ssCompData.ix2_sn, 1, + ssCompData.header.sense_node, + &adjhor); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjHoriz SS IX2 SENSE ADJH failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + logError(0, "%s SS IX2 SENSE ADJ HORIZ computed! \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_IX2_SENSE_ADJH_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + + if (ret < 0 || (trows != 1 || + tcolumns != ssCompData.header.sense_node - 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_IX2_SENSE_ADJH_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdj(adjhor, 1, + ssCompData.header.sense_node - 1, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMapAdj SS IX2 SENSE ADJH failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS IX2 SENSE ADJH TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS IX2 SENSE ADJH TEST:.................OK \n\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(adjhor); + adjhor = NULL; + } else + logError( + 0, + "%s SS IX2 SENSE ADJ TEST:.................SKIPPED \n", + tag); + + if (todo->SelfSenseIxTotal == 1 || todo->SelfSenseIxTotalAdj == 1) { + if (todo->SelfSenseIxTotal == 1) { + logError(1, "%s SS TOTAL IX SENSE MIN MAX TEST: \n", + tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, + SS_TOTAL_IX_SENSE_MAP_MIN, &thresholds_min, + &trows, &tcolumns); + + if (ret < 0 || + (trows != 1 || + tcolumns != totCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_SENSE_MAP_MIN failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits( + path_limits, &limit_file, + SS_TOTAL_IX_SENSE_MAP_MAX, &thresholds_max, + &trows, &tcolumns); + + if (ret < 0 || + (trows != 1 || + tcolumns != totCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_SENSE_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapTotalFromU( + totCompData.ix_sn, 1, + totCompData.header.sense_node, thresholds_min, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS TOTAL IX SENSE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS TOTAL IX SENSE MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS TOTAL IX SENSE MIN MAX TEST:.................OK \n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError( + 0, + "%s SS TOTAL IX SENSE MIN MAX TEST:.................SKIPPED \n", + tag); + + if (todo->SelfSenseIxTotalAdj == 1) { + logError(1, "%s SS TOTAL IX SENSE ADJHORIZ TEST: \n", + tag); + ret = computeAdjHorizTotalFromU( + totCompData.ix_sn, 1, + totCompData.header.sense_node, &total_adjhor); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjHoriz SS TOTAL IX SENSE ADJH failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + logError(0, + "%s SS TOTAL IX SENSE ADJ HORIZ computed! \n", + tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, + SS_TOTAL_IX_SENSE_ADJH_MAP_MAX, &thresholds_max, + &trows, &tcolumns); + + if (ret < 0 || + (trows != 1 || + tcolumns != totCompData.header.sense_node - 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_SENSE_ADJH_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdjTotal( + total_adjhor, 1, + totCompData.header.sense_node - 1, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMapAdj SS TOTAL IX SENSE ADJH failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS TOTAL IX SENSE ADJH TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS TOTAL IX SENSE ADJH TEST:.................OK \n\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(total_adjhor); + total_adjhor = NULL; + } else + logError( + 0, + "%s SS TOTAL IX SENSE ADJ TEST:.................SKIPPED \n", + tag); + } else + logError( + 0, + "%s SS TOTAL IX SENSE TEST:.................SKIPPED \n", + tag); + + /********************************************************* SS SENSE CX ****************************************************************/ + + if (todo->SelfForceCx1 == 1) { + logError(1, "%s SS CX1 FORCE TEST: \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_CX1_FORCE_MIN_MAX, + &thresholds, &trows, &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_CX1_FORCE_MIN_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + container = (short)ssCompData.f_cx1; + ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], + thresholds[1]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax SS CX1 FORCE TEST failed... ERROR COUNT = %d \n", + tag, ret); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS CX1 FORCE TEST:.................OK \n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError(0, + "%s SS CX1 FORCE TEST:.................SKIPPED \n\n", + tag); + + if (todo->SelfForceCx2 == 1) { + logError(1, "%s SS CX2 FORCE MIN MAX TEST: \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_CX2_FORCE_MAP_MIN, + &thresholds_min, &trows, + &tcolumns); + + if (ret < 0 || + (trows != ssCompData.header.force_node || tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_CX2_FORCE_MAP_MIN failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_CX2_FORCE_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + + if (ret < 0 || + (trows != ssCompData.header.force_node || tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_CX2_FORCE_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMap(ssCompData.cx2_fm, + ssCompData.header.force_node, 1, + thresholds_min, thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS CX2 FORCE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS CX2 FORCE MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS CX2 FORCE MIN MAX TEST:.................OK \n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError( + 0, + "%s SS CX2 FORCE MIN MAX TEST:.................SKIPPED \n", + tag); + + if (todo->SelfForceCx2Adj == 1) { + logError(1, "%s SS CX2 FORCE ADJVERT TEST: \n", tag); + ret = computeAdjVert(ssCompData.cx2_fm, + ssCompData.header.force_node, 1, &adjvert); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjVert SS CX2 FORCE ADJV failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + logError(0, "%s SS CX2 FORCE ADJV computed! \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_CX2_FORCE_ADJV_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + + if (ret < 0 || (trows != ssCompData.header.force_node - 1 || + tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_CX2_FORCE_ADJV_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdj(adjvert, + ssCompData.header.force_node - 1, 1, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS IX2 FORCE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS CX2 FORCE ADJV TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS CX2 FORCE ADJV TEST:.................OK \n\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(adjvert); + adjvert = NULL; + } else + logError( + 0, + "%s SS CX2 FORCE ADJ TEST:.................SKIPPED \n\n", + tag); + + if (todo->SelfForceCxTotal == 1 || todo->SelfForceCxTotalAdj == 1) { + if (todo->SelfForceCxTotal == 1) { + logError(1, "%s SS TOTAL CX FORCE MIN MAX TEST: \n", + tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, + SS_TOTAL_CX_FORCE_MAP_MIN, &thresholds_min, + &trows, &tcolumns); + + if (ret < 0 || + (trows != totCompData.header.force_node || + tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_CX_FORCE_MAP_MIN failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits( + path_limits, &limit_file, + SS_TOTAL_CX_FORCE_MAP_MAX, &thresholds_max, + &trows, &tcolumns); + + if (ret < 0 || + (trows != totCompData.header.force_node || + tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_CX_FORCE_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapTotal(totCompData.cx_fm, + totCompData.header.force_node, + 1, thresholds_min, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS TOTAL FORCE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS TOTAL FORCE MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS TOTAL FORCE MIN MAX TEST:.................OK \n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError( + 0, + "%s SS TOTAL CX FORCE MIN MAX TEST:.................SKIPPED \n", + tag); + + if (todo->SelfForceCxTotalAdj == 1) { + logError(1, "%s SS TOTAL CX FORCE ADJVERT TEST: \n", + tag); + ret = computeAdjVertTotal(totCompData.cx_fm, + totCompData.header.force_node, + 1, &total_adjvert); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjVert SS TOTAL CX FORCE ADJV failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + logError(0, "%s SS TOTAL CX FORCE ADJV computed! \n", + tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, + SS_TOTAL_CX_FORCE_ADJV_MAP_MAX, &thresholds_max, + &trows, &tcolumns); + + if (ret < 0 || + (trows != totCompData.header.force_node - 1 || + tcolumns != 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_CX_FORCE_ADJV_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdjTotal( + total_adjvert, + totCompData.header.force_node - 1, 1, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS TOTAL CX FORCE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS TOTAL CX FORCE ADJV TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS TOTAL CX FORCE ADJV TEST:.................OK \n\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(total_adjvert); + total_adjvert = NULL; + } else + logError( + 0, + "%s SS TOTAL CX FORCE ADJ TEST:.................SKIPPED \n", + tag); + } else + logError( + 0, + "%s SS TOTAL CX FORCE TEST:.................SKIPPED \n\n", + tag); + + /********************************************************* SS SENSE CX ****************************************************************/ + + if (todo->SelfSenseCx1 == 1) { + logError(1, "%s SS CX1 SENSE TEST: \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_CX1_SENSE_MIN_MAX, + &thresholds, &trows, &tcolumns); + + if (ret < 0 || (trows != 1 || tcolumns != 2)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_CX1_SENSE_MIN_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + container = (short)ssCompData.s_cx1; + ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], + thresholds[1]); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMinMax SS CX1 SENSE TEST failed... ERROR COUNT = %d \n", + tag, ret); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS CX1 SENSE TEST:.................OK \n\n", + tag); + + kfree(thresholds); + thresholds = NULL; + } else + logError(0, + "%s SS CX1 SENSE TEST:.................SKIPPED \n\n", + tag); + + if (todo->SelfSenseCx2 == 1) { + logError(1, "%s SS CX2 SENSE MIN MAX TEST: \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_CX2_SENSE_MAP_MIN, + &thresholds_min, &trows, + &tcolumns); + + if (ret < 0 || + (trows != 1 || tcolumns != ssCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_CX2_SENSE_MAP_MIN failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_CX2_SENSE_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + + if (ret < 0 || + (trows != 1 || tcolumns != ssCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_CX2_SENSE_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMap(ssCompData.cx2_sn, 1, + ssCompData.header.sense_node, + thresholds_min, thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS CX2 SENSE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS CX2 SENSE MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS CX2 SENSE MIN MAX TEST:.................OK \n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError( + 0, + "%s SS CX2 SENSE MIN MAX TEST:.................SKIPPED \n", + tag); + + if (todo->SelfSenseCx2Adj == 1) { + logError(1, "%s SS CX2 SENSE ADJHORIZ TEST: \n", tag); + ret = computeAdjHoriz(ssCompData.cx2_sn, 1, + ssCompData.header.sense_node, &adjhor); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjHoriz SS CX2 SENSE ADJH failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + logError(0, "%s SS CX2 SENSE ADJH computed! \n", tag); + ret = parseProductionTestLimits(path_limits, &limit_file, + SS_CX2_SENSE_ADJH_MAP_MAX, + &thresholds_max, &trows, + &tcolumns); + + if (ret < 0 || (trows != 1 || + tcolumns != ssCompData.header.sense_node - 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_IX2_SENSE_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdj(adjhor, 1, + ssCompData.header.sense_node - 1, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMapAdj SS CX2 SENSE ADJH failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS CX2 SENSE ADJH TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS CX2 SENSE ADJH TEST:.................OK \n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(adjhor); + adjhor = NULL; + } else + logError( + 0, + "%s SS CX2 SENSE ADJ TEST:.................SKIPPED \n\n", + tag); + + if (todo->SelfSenseCxTotal == 1 || todo->SelfSenseCxTotalAdj == 1) { + if (todo->SelfSenseCxTotal == 1) { + logError(1, "%s SS TOTAL CX SENSE MIN MAX TEST: \n", + tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, + SS_TOTAL_CX_SENSE_MAP_MIN, &thresholds_min, + &trows, &tcolumns); + + if (ret < 0 || + (trows != 1 || + tcolumns != totCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_CX_SENSE_MAP_MIN failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = parseProductionTestLimits( + path_limits, &limit_file, + SS_TOTAL_CX_SENSE_MAP_MAX, &thresholds_max, + &trows, &tcolumns); + + if (ret < 0 || + (trows != 1 || + tcolumns != totCompData.header.sense_node)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_CX_SENSE_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapTotal(totCompData.cx_sn, 1, + totCompData.header.sense_node, + thresholds_min, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMap SS TOTAL CX SENSE failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS TOTAL CX SENSE MIN MAX TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS TOTAL CX SENSE MIN MAX TEST:.................OK \n\n", + tag); + + kfree(thresholds_min); + thresholds_min = NULL; + kfree(thresholds_max); + thresholds_max = NULL; + } else + logError( + 0, + "%s SS TOTAL CX SENSE MIN MAX TEST:.................SKIPPED \n", + tag); + + if (todo->SelfSenseCxTotalAdj == 1) { + logError(1, "%s SS TOTAL CX SENSE ADJHORIZ TEST: \n", + tag); + ret = computeAdjHorizTotal( + totCompData.cx_sn, 1, + totCompData.header.sense_node, &total_adjhor); + + if (ret < 0) { + logError( + 1, + "%s production_test_data: computeAdjHoriz SS TOTAL CX SENSE ADJH failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + logError(0, + "%s SS TOTAL CX SENSE ADJ HORIZ computed! \n", + tag); + ret = parseProductionTestLimits( + path_limits, &limit_file, + SS_TOTAL_CX_SENSE_ADJH_MAP_MAX, &thresholds_max, + &trows, &tcolumns); + + if (ret < 0 || + (trows != 1 || + tcolumns != totCompData.header.sense_node - 1)) { + logError( + 1, + "%s production_test_data: parseProductionTestLimits SS_TOTAL_CX_SENSE_ADJH_MAP_MAX failed... ERROR %08X \n", + tag, ERROR_PROD_TEST_DATA); + ret |= ERROR_PROD_TEST_DATA; + goto ERROR_LIMITS; + } + + ret = checkLimitsMapAdjTotal( + total_adjhor, 1, + totCompData.header.sense_node - 1, + thresholds_max); + + if (ret != OK) { + logError( + 1, + "%s production_test_data: checkLimitsMapAdj SS TOTAL CX SENSE ADJH failed... ERROR COUNT = %d \n", + tag, ret); + logError( + 0, + "%s SS TOTAL CX SENSE ADJH TEST:.................FAIL \n\n", + tag); + count_fail += 1; + + if (stop_on_fail) + goto ERROR; + } else + logError( + 0, + "%s SS TOTAL CX SENSE ADJH TEST:.................OK \n\n", + tag); + + kfree(thresholds_max); + thresholds_max = NULL; + kfree(total_adjhor); + total_adjhor = NULL; + } else + logError( + 0, + "%s SS TOTAL CX SENSE ADJ TEST:.................SKIPPED \n", + tag); + } else + logError( + 0, + "%s SS TOTAL CX SENSE TEST:.................SKIPPED \n", + tag); + if (todo->SelfHoverForceIxTotal == 1 || + todo->SelfHoverSenceIxTotal == 1) { + ret = production_test_ss_hover_ix(path_limits, stop_on_fail, + todo); + if (ret < OK) { + logError( + 1, + "%s production_test_data: production_test_ss_hover_ix_cx failed... ERROR = %08X\n", + tag, ret); + count_fail += 1; + } + } + +ERROR: + logError(0, "%s \n", tag); + + if (count_fail == 0) { + kfree(ssCompData.ix2_fm); + ssCompData.ix2_fm = NULL; + kfree(ssCompData.ix2_sn); + ssCompData.ix2_sn = NULL; + kfree(ssCompData.cx2_fm); + ssCompData.cx2_fm = NULL; + kfree(ssCompData.cx2_sn); + ssCompData.cx2_sn = NULL; + kfree(totCompData.ix_fm); + totCompData.ix_fm = NULL; + kfree(totCompData.ix_sn); + totCompData.ix_sn = NULL; + kfree(totCompData.cx_fm); + totCompData.cx_fm = NULL; + kfree(totCompData.cx_sn); + totCompData.cx_sn = NULL; + logError(0, + "%s SS IX CX testes finished!.................OK\n\n", + tag); + return OK; + } else { + print_frame_u8("SS Init Data Ix2_fm = ", + array1dTo2d_u8(ssCompData.ix2_fm, + ssCompData.header.force_node, 1), + ssCompData.header.force_node, 1); + print_frame_i8("SS Init Data Cx2_fm = ", + array1dTo2d_i8(ssCompData.cx2_fm, + ssCompData.header.force_node, 1), + ssCompData.header.force_node, 1); + print_frame_u8("SS Init Data Ix2_sn = ", + array1dTo2d_u8(ssCompData.ix2_sn, + ssCompData.header.sense_node, + ssCompData.header.sense_node), + 1, ssCompData.header.sense_node); + print_frame_i8("SS Init Data Cx2_sn = ", + array1dTo2d_i8(ssCompData.cx2_sn, + ssCompData.header.sense_node, + ssCompData.header.sense_node), + 1, ssCompData.header.sense_node); + print_frame_u16("TOT SS Init Data Ix_fm = ", + array1dTo2d_u16(totCompData.ix_fm, + totCompData.header.force_node, + 1), + totCompData.header.force_node, 1); + print_frame_short( + "TOT SS Init Data Cx_fm = ", + array1dTo2d_short(totCompData.cx_fm, + totCompData.header.force_node, 1), + totCompData.header.force_node, 1); + print_frame_u16("TOT SS Init Data Ix_sn = ", + array1dTo2d_u16(totCompData.ix_sn, + totCompData.header.sense_node, + totCompData.header.sense_node), + 1, totCompData.header.sense_node); + print_frame_short( + "TOT SS Init Data Cx_sn = ", + array1dTo2d_short(totCompData.cx_sn, + totCompData.header.sense_node, + totCompData.header.sense_node), + 1, totCompData.header.sense_node); + logError( + 0, + "%s SS IX CX testes finished!.................FAILED fails_count = %d\n\n", + tag, count_fail); + + if (thresholds != NULL) + kfree(thresholds); + + if (thresholds_min != NULL) + kfree(thresholds_min); + + if (thresholds_max != NULL) + kfree(thresholds_max); + + if (adjhor != NULL) + kfree(adjhor); + + if (adjvert != NULL) + kfree(adjvert); + + if (total_adjhor != NULL) + kfree(total_adjhor); + + if (total_adjvert != NULL) + kfree(total_adjvert); + + if (ssCompData.ix2_fm != NULL) + kfree(ssCompData.ix2_fm); + + if (ssCompData.ix2_sn != NULL) + kfree(ssCompData.ix2_sn); + + if (ssCompData.cx2_fm != NULL) + kfree(ssCompData.cx2_fm); + + if (ssCompData.cx2_sn != NULL) + kfree(ssCompData.cx2_sn); + + if (totCompData.ix_fm != NULL) + kfree(totCompData.ix_fm); + + if (totCompData.ix_sn != NULL) + kfree(totCompData.ix_sn); + + if (totCompData.cx_fm != NULL) + kfree(totCompData.cx_fm); + + if (totCompData.cx_sn != NULL) + kfree(totCompData.cx_sn); + + return (ERROR_TEST_CHECK_FAIL | ERROR_PROD_TEST_DATA); + } + +ERROR_LIMITS: + + if (thresholds != NULL) + kfree(thresholds); + + if (thresholds_min != NULL) + kfree(thresholds_min); + + if (thresholds_max != NULL) + kfree(thresholds_max); + + if (adjhor != NULL) + kfree(adjhor); + + if (adjvert != NULL) + kfree(adjvert); + + if (total_adjhor != NULL) + kfree(total_adjhor); + + if (total_adjvert != NULL) + kfree(total_adjvert); + + if (ssCompData.ix2_fm != NULL) + kfree(ssCompData.ix2_fm); + + if (ssCompData.ix2_sn != NULL) + kfree(ssCompData.ix2_sn); + + if (ssCompData.cx2_fm != NULL) + kfree(ssCompData.cx2_fm); + + if (ssCompData.cx2_sn != NULL) + kfree(ssCompData.cx2_sn); + + if (totCompData.ix_fm != NULL) + kfree(totCompData.ix_fm); + + if (totCompData.ix_sn != NULL) + kfree(totCompData.ix_sn); + + if (totCompData.cx_fm != NULL) + kfree(totCompData.cx_fm); + + if (totCompData.cx_sn != NULL) + kfree(totCompData.cx_sn); + + return ret; +} + +/** + * Perform a complete Data Test check of the IC + * @param path_limits name of Production Limit file to load or "NULL" if the limits data should be loaded by a .h file + * @param stop_on_fail if 1, the test flow stops at the first data check failure otherwise it keeps going performing all the selected test + * @param todo pointer to a TestToDo variable which select the test to do + * @return OK if success or an error code which specify the type of error encountered + */ +int production_test_data(char *path_limits, int stop_on_fail, TestToDo *todo) +{ + int res = OK, ret; + + if (todo == NULL) { + logError( + 1, + "%s production_test_data: No TestToDo specified!! ERROR = %08X \n", + tag, (ERROR_OP_NOT_ALLOW | ERROR_PROD_TEST_DATA)); + return (ERROR_OP_NOT_ALLOW | ERROR_PROD_TEST_DATA); + } + + logError(1, "%s DATA Production test is starting...\n", tag); + ret = production_test_ms_raw(path_limits, stop_on_fail, todo); + res |= ret; + + if (ret < 0) { + logError( + 1, + "%s production_test_data: production_test_ms_raw failed... ERROR = %08X \n", + tag, ret); + + if (stop_on_fail == 1) + goto END; + } + + ret = production_test_ms_cx(path_limits, stop_on_fail, todo); + res |= ret; + + if (ret < 0) { + logError( + 1, + "%s production_test_data: production_test_ms_cx failed... ERROR = %08X \n", + tag, ret); + + if (stop_on_fail == 1) + goto END; + } + + ret = production_test_ss_raw(path_limits, stop_on_fail, todo); + res |= ret; + + if (ret < 0) { + logError( + 1, + "%s production_test_data: production_test_ss_raw failed... ERROR = %08X \n", + tag, ret); + + if (stop_on_fail == 1) + goto END; + } + + ret = production_test_ss_ix_cx(path_limits, stop_on_fail, todo); + res |= ret; + + if (ret < 0) { + logError( + 1, + "%s production_test_data: production_test_ss_ix_cx failed... ERROR = %08X \n", + tag, ret); + + if (stop_on_fail == 1) + goto END; + } + +END: + freeLimitsFile(&limit_file); + + if (res < OK) + logError(0, "%s DATA Production test failed!\n", tag); + else + logError(0, "%s DATA Production test finished!\n", tag); + + return res; +} + +/** + * Retrieve the actual Test Limit data from the system (bin file or header file) + * @param path name of Production Test Limit file to load or "NULL" if the limits data should be loaded by a .h file + * @param file pointer to the LimitFile struct which will contains the limits data + * @return OK if success or an error code which specify the type of error encountered + */ +int getLimitsFile(char *path, LimitFile *file) +{ + const struct firmware *fw = NULL; + struct device *dev = NULL; + int fd = -1; + logError(0, "%s Get Limits File starting... %s\n", tag, path); + + if (file->data != NULL) { + logError( + 0, + "%s Pointer to Limits Data already contains something... freeing its content!\n", + tag); + kfree(file->data); + file->data = NULL; + file->size = 0; + } + + strlcpy(file->name, path, MAX_LIMIT_FILE_NAME); + + if (strncmp(path, "NULL", 4) == 0) { +#ifdef LIMITS_H_FILE + logError(0, "%s Loading Limits File from .h!\n", tag); + file->size = LIMITS_SIZE_NAME; + file->data = (char *)kmalloc((file->size) * sizeof(char), + GFP_KERNEL); + + if (file->data != NULL) { + memcpy(file->data, (char *)(LIMITS_ARRAY_NAME), + file->size); + return OK; + } else { + logError( + 1, + "%s Error while allocating data... ERROR %08X \n", + tag, path, ERROR_ALLOC); + return ERROR_ALLOC; + } + +#else + logError(1, "%s limit file path NULL... ERROR %08X \n", tag, + ERROR_FILE_NOT_FOUND); + return ERROR_FILE_NOT_FOUND; +#endif + } else { + dev = getDev(); + + if (dev != NULL) { + logError(0, "%s Loading Limits File from .csv!\n", tag); + fd = request_firmware(&fw, path, dev); + + if (fd == 0) { + logError(0, "%s Start to copy %s...\n", tag, + path); + file->size = fw->size; + file->data = (char *)kmalloc( + (file->size) * sizeof(char), + GFP_KERNEL); + + if (file->data != NULL) { + memcpy(file->data, (char *)fw->data, + file->size); + logError(0, + "%s Limit file Size = %d \n", + tag, file->size); + release_firmware(fw); + return OK; + } else { + logError( + 1, + "%s Error while allocating data... ERROR %08X \n", + tag, path, ERROR_ALLOC); + release_firmware(fw); + return ERROR_ALLOC; + } + } else { + logError( + 1, + "%s Request the file %s failed... ERROR %08X \n", + tag, path, ERROR_FILE_NOT_FOUND); + return ERROR_FILE_NOT_FOUND; + } + } else { + logError( + 1, + "%s Error while getting the device ERROR %08X \n", + tag, ERROR_FILE_READ); + return ERROR_FILE_READ; + } + } +} + +/** + * Reset and release the memory which store a Production Limit File previously loaded + * @param file pointer to the LimitFile struct to free + * @return OK if success or an error code which specify the type of error encountered + */ + +int freeLimitsFile(LimitFile *file) +{ + logError(0, "%s Freeing Limit File ...\n", tag); + + if (file != NULL) { + if (file->data != NULL) { + kfree(file->data); + file->data = NULL; + } else + logError(0, "%s Limit File was already freed!\n", tag); + + file->size = 0; + strlcpy(file->name, " ", MAX_LIMIT_FILE_NAME); + return OK; + } else { + logError(1, "%s Passed a NULL argument! ERROR %08X \n", tag, + ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } +} + +/** + * Reset and release the memory which store the current Limit File previously loaded + * @return OK if success or an error code which specify the type of error encountered + */ + +int freeCurrentLimitsFile(void) +{ + return freeLimitsFile(&limit_file); +} + +/** + * Parse the raw data read from a Production test limit file in order to find the specified information + * If no limits file data are passed, the function loads and stores the limit file from the system + * @param path name of Production Test Limit file to load or "NULL" if the limits data should be loaded by a .h file + * @param file pointer to LimitFile struct that should be parsed or NULL if the limit file in the system should be loaded and then parsed + * @param label string which identify a particular set of data in the file that want to be loaded + * @param data pointer to the pointer which will contains the specified limits data as 1 dimension matrix with data arranged row after row + * @param row pointer to a int variable which will contain the number of row of data + * @param column pointer to a int variable which will contain the number of column of data + * @return OK if success or an error code which specify the type of error encountered + */ +int parseProductionTestLimits(char *path, LimitFile *file, char *label, + int **data, int *row, int *column) +{ + int find = 0; + char *token = NULL; + int i = 0; + int j = 0; + int z = 0; + char *line2 = NULL; + char line[800]; + char *buf = NULL; + int n, size, pointer = 0, ret = OK; + char *data_file = NULL; + + if (file == NULL || strcmp(path, file->name) != 0 || file->size == 0) { + logError( + 0, + "%s No limit File data passed... try to get them from the system!\n", + tag); + ret = getLimitsFile(LIMITS_FILE, &limit_file); + + if (ret < OK) { + logError(1, + "%s parseProductionTestLimits: ERROR %08X\n", + tag, ERROR_FILE_NOT_FOUND); + return ERROR_FILE_NOT_FOUND; + } + + size = limit_file.size; + data_file = limit_file.data; + } else { + logError(0, "%s Limit File data passed as arguments!\n", tag); + size = file->size; + data_file = file->data; + } + + logError(0, "%s The size of the limits file is %d bytes...\n", tag, + size); + + while (find == 0) { + if (readLine(&data_file[pointer], line, size - pointer, &n) < + 0) { + find = -1; + break; + } + + pointer += n; + + if (line[0] == '*') { + line2 = kstrdup(line, GFP_KERNEL); + + if (line2 == NULL) { + logError( + 1, + "%s parseProductionTestLimits: kstrdup ERROR %08X\n", + tag, ERROR_ALLOC); + ret = ERROR_ALLOC; + goto END; + } + + buf = line2; + line2 += 1; + token = strsep(&line2, ","); + + if (strcmp(token, label) == 0) { + find = 1; + token = strsep(&line2, ","); + + if (token != NULL) { + sscanf(token, "%d", row); + logError(0, "%s Row = %d\n", tag, *row); + } else { + logError( + 1, + "%s parseProductionTestLimits 1: ERROR %08X\n", + tag, ERROR_FILE_PARSE); + ret = ERROR_FILE_PARSE; + goto END; + } + + token = strsep(&line2, ","); + + if (token != NULL) { + sscanf(token, "%d", column); + logError(0, "%s Column = %d\n", tag, + *column); + } else { + logError( + 1, + "%s parseProductionTestLimits 2: ERROR %08X\n", + tag, ERROR_FILE_PARSE); + ret = ERROR_FILE_PARSE; + goto END; + } + + kfree(buf); + buf = NULL; + *data = (int *)kmalloc(((*row) * (*column)) * + sizeof(int), + GFP_KERNEL); + j = 0; + + if (*data == NULL) { + logError( + 1, + "%s parseProductionTestLimits: ERROR %08X\n", + tag, ERROR_ALLOC); + ret = ERROR_ALLOC; + goto END; + } + + for (i = 0; i < *row; i++) { + if (readLine(&data_file[pointer], line, + size - pointer, &n) < 0) { + logError( + 1, + "%s parseProductionTestLimits : ERROR %08X\n", + tag, ERROR_FILE_READ); + ret = ERROR_FILE_READ; + goto END; + } + + pointer += n; + line2 = kstrdup(line, GFP_KERNEL); + + if (line2 == NULL) { + logError( + 1, + "%s parseProductionTestLimits: kstrdup ERROR %08X\n", + tag, ERROR_ALLOC); + ret = ERROR_ALLOC; + goto END; + } + + buf = line2; + token = strsep(&line2, ","); + + for (z = 0; + (z < *column) && (token != NULL); + z++) { + sscanf(token, "%d", + ((*data) + j)); + j++; + token = strsep(&line2, ","); + } + + kfree(buf); + buf = NULL; + } + + if (j == ((*row) * (*column))) { + logError(0, "%s READ DONE!\n", tag); + ret = OK; + goto END; + } + + logError( + 1, + "%s parseProductionTestLimits 3: ERROR %08X\n", + tag, ERROR_FILE_PARSE); + ret = ERROR_FILE_PARSE; + goto END; + } + + kfree(buf); + buf = NULL; + } + } + + logError(1, "%s parseProductionTestLimits: ERROR %08X\n", tag, + ERROR_LABEL_NOT_FOUND); + ret = ERROR_LABEL_NOT_FOUND; +END: + + if (buf != NULL) + kfree(buf); + + return ret; +} + +/** + * Read one line of a text file passed as array of byte and terminate it with a termination character '\0' + * @param data text file as array of bytes + * @param line pointer to an array of char that will contain the line read + * @param size size of data + * @param n pointer to a int variable which will contain the number of characters of the line + * @return OK if success or an error code which specify the type of error encountered + */ +int readLine(char *data, char *line, int size, int *n) +{ + int i = 0; + + if (size < 1) + return -EINVAL; + + while (data[i] != '\n' && i < size) { + line[i] = data[i]; + i++; + } + + *n = i + 1; + line[i] = '\0'; + return OK; +} diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTest.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTest.h new file mode 100644 index 000000000000..7e71bb6b4e42 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTest.h @@ -0,0 +1,304 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS API for MP test * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsTest.h +* \brief Contains all the definitions and structs related to the Mass Production Test +*/ + +#ifndef FTS_TEST_H +#define FTS_TEST_H + +#include "ftsSoftware.h" + +#ifndef LIMITS_H_FILE +#define LIMITS_FILE \ + "stm_fts_production_limits.csv" /*Name of the Production Test Limit File*/ +#else +#define LIMITS_FILE "NULL" +#endif + +#define WAIT_FOR_FRESH_FRAMES \ + 200 /*Time in ms to wait after start to sensing before reading a frame*/ +#define WAIT_AFTER_SENSEOFF \ + 50 /*Time in ms to wait after stop sensing and before reading a frame from memory*/ + +#define NO_INIT 0 /*No Initialization required during the MP*/ + +#define RETRY_INIT_BOOT \ + 3 /*number of retry of the initialization process at boot*/ + +/** @defgroup mp_test Mass Production Test + * Mass production test API. + * Mass Production Test (MP) should be executed at least one time in the life of every device \n + * It used to verify that tit is not present any hardware damage and initialize some value of the chip in order to guarantee the working performance \n + * The MP test is made up by 3 steps: + * - ITO test = production_test_ito() \n + * - Initialization = production_test_initialization() \n + * - Data Test = production_test_data(), it is possible to select which items test thanks to the TestToDo struct\n + * To execute the Data Test it is mandatory load some thresholds that are stored in the Limit File. + * @{ + */ + +/** @defgroup limit_file Limit File + * @ingroup mp_test + * Production Test Limit File is a csv which contains thresholds of the data to test. + * This file can be loaded from the file system or stored as a header file according to the LIMITS_H_FILE define \n + * For each selectable test item there can be one or more associated labels which store the corresponding thresholds \n + * @{ + */ + +/** @defgroup test_labels Test Items Labels + * @ingroup limit_file + * Labels present in the Limit File and associated to the test items of TestToDo + * @{ + */ +#define MS_RAW_MIN_MAX "MS_RAW_DATA_MIN_MAX" +#define MS_RAW_EACH_NODE_MIN "MS_RAW_DATA_EACH_MIN" +#define MS_RAW_EACH_NODE_MAX "MS_RAW_DATA_EACH_MAX" +#define MS_RAW_GAP "MS_RAW_DATA_GAP" +#define MS_RAW_ADJH "MS_RAW_DATA_ADJ_HORIZONTAL" +#define MS_RAW_ADJV "MS_RAW_DATA_ADJ_VERTICAL" +#define MS_RAW_ITO_ADJH "MS_RAW_ITO_DATA_ADJ_HORIZONTAL" +#define MS_RAW_ITO_ADJV "MS_RAW_ITO_DATA_ADJ_VERTICAL" +#define MS_RAW_LP_MIN_MAX "MS_RAW_LOWPOWER_DATA_MIN_MAX" +#define MS_RAW_LP_GAP "MS_RAW_LOWPOWER_DATA_GAP" +#define MS_RAW_LP_ADJH "MS_RAW_LOWPOWER_DATA_ADJ_HORIZONTAL" +#define MS_RAW_LP_ADJV "MS_RAW_LOWPOWER_DATA_ADJ_VERTICAL" +#define MS_CX1_MIN_MAX "MS_TOUCH_ACTIVE_CX1_MIN_MAX" +#define MS_CX2_MAP_MIN "MS_TOUCH_ACTIVE_CX2_MIN" +#define MS_CX2_MAP_MAX "MS_TOUCH_ACTIVE_CX2_MAX" +#define MS_CX2_ADJH_MAP_MAX "MS_TOUCH_ACTIVE_CX2_ADJ_HORIZONTAL" +#define MS_CX2_ADJV_MAP_MAX "MS_TOUCH_ACTIVE_CX2_ADJ_VERTICAL" +#define MS_TOTAL_CX_MAP_MIN "MS_TOUCH_ACTIVE_TOTAL_CX_MIN" +#define MS_TOTAL_CX_MAP_MAX "MS_TOUCH_ACTIVE_TOTAL_CX_MAX" +#define MS_TOTAL_CX_ADJH_MAP_MAX "MS_TOUCH_ACTIVE_TOTAL_CX_ADJ_HORIZONTAL" +#define MS_TOTAL_CX_ADJV_MAP_MAX "MS_TOUCH_ACTIVE_TOTAL_CX_ADJ_VERTICAL" +#define MS_CX1_LP_MIN_MAX "MS_TOUCH_LOWPOWER_CX1_MIN_MAX" +#define MS_CX2_LP_MAP_MIN "MS_TOUCH_LOWPOWER_CX2_MIN" +#define MS_CX2_LP_MAP_MAX "MS_TOUCH_LOWPOWER_CX2_MAX" +#define MS_CX2_ADJH_LP_MAP_MAX "MS_TOUCH_LOWPOWER_CX2_ADJ_HORIZONTAL" +#define MS_CX2_ADJV_LP_MAP_MAX "MS_TOUCH_LOWPOWER_CX2_ADJ_VERTICAL" +#define MS_TOTAL_CX_LP_MAP_MIN "MS_TOUCH_LOWPOWER_TOTAL_CX_MIN" +#define MS_TOTAL_CX_LP_MAP_MAX "MS_TOUCH_LOWPOWER_TOTAL_CX_MAX" +#define MS_TOTAL_CX_ADJH_LP_MAP_MAX "MS_TOUCH_LOWPOWER_TOTAL_CX_ADJ_HORIZONTAL" +#define MS_TOTAL_CX_ADJV_LP_MAP_MAX "MS_TOUCH_LOWPOWER_TOTAL_CX_ADJ_VERTICAL" +#define SS_RAW_FORCE_MIN_MAX "SS_RAW_DATA_FORCE_MIN_MAX" +#define SS_RAW_SENSE_MIN_MAX "SS_RAW_DATA_SENSE_MIN_MAX" +#define SS_RAW_FORCE_GAP "SS_RAW_DATA_FORCE_GAP" +#define SS_RAW_SENSE_GAP "SS_RAW_DATA_SENSE_GAP" +#define SS_RAW_LP_FORCE_MIN_MAX "SS_RAW_LOWPOWER_DATA_FORCE_MIN_MAX" +#define SS_RAW_LP_SENSE_MIN_MAX "SS_RAW_LOWPOWER_DATA_SENSE_MIN_MAX" +#define SS_RAW_LP_FORCE_GAP "SS_RAW_LOWPOWER_DATA_FORCE_GAP" +#define SS_RAW_LP_SENSE_GAP "SS_RAW_LOWPOWER_DATA_SENSE_GAP" +#define SS_IX1_FORCE_MIN_MAX "SS_TOUCH_ACTIVE_IX1_FORCE_MIN_MAX" +#define SS_IX1_SENSE_MIN_MAX "SS_TOUCH_ACTIVE_IX1_SENSE_MIN_MAX" +#define SS_CX1_FORCE_MIN_MAX "SS_TOUCH_ACTIVE_CX1_FORCE_MIN_MAX" +#define SS_CX1_SENSE_MIN_MAX "SS_TOUCH_ACTIVE_CX1_SENSE_MIN_MAX" +#define SS_IX2_FORCE_MAP_MIN "SS_TOUCH_ACTIVE_IX2_FORCE_MIN" +#define SS_IX2_FORCE_MAP_MAX "SS_TOUCH_ACTIVE_IX2_FORCE_MAX" +#define SS_IX2_SENSE_MAP_MIN "SS_TOUCH_ACTIVE_IX2_SENSE_MIN" +#define SS_IX2_SENSE_MAP_MAX "SS_TOUCH_ACTIVE_IX2_SENSE_MAX" +#define SS_IX2_FORCE_ADJV_MAP_MAX "SS_TOUCH_ACTIVE_IX2_ADJ_VERTICAL" +#define SS_IX2_SENSE_ADJH_MAP_MAX "SS_TOUCH_ACTIVE_IX2_ADJ_HORIZONTAL" +#define SS_CX2_FORCE_MAP_MIN "SS_TOUCH_ACTIVE_CX2_FORCE_MIN" +#define SS_CX2_FORCE_MAP_MAX "SS_TOUCH_ACTIVE_CX2_FORCE_MAX" +#define SS_CX2_SENSE_MAP_MIN "SS_TOUCH_ACTIVE_CX2_SENSE_MIN" +#define SS_CX2_SENSE_MAP_MAX "SS_TOUCH_ACTIVE_CX2_SENSE_MAX" +#define SS_CX2_FORCE_ADJV_MAP_MAX "SS_TOUCH_ACTIVE_CX2_ADJ_VERTICAL" +#define SS_CX2_SENSE_ADJH_MAP_MAX "SS_TOUCH_ACTIVE_CX2_ADJ_HORIZONTAL" + +#define SS_TOTAL_IX_FORCE_MAP_MIN "SS_TOUCH_ACTIVE_TOTAL_IX_FORCE_MIN" +#define SS_TOTAL_IX_FORCE_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_IX_FORCE_MAX" +#define SS_TOTAL_IX_SENSE_MAP_MIN "SS_TOUCH_ACTIVE_TOTAL_IX_SENSE_MIN" +#define SS_TOTAL_IX_SENSE_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_IX_SENSE_MAX" +#define SS_TOTAL_IX_FORCE_ADJV_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_IX_ADJ_VERTICAL" +#define SS_TOTAL_IX_SENSE_ADJH_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_IX_ADJ_HORIZONTAL" +#define SS_TOTAL_CX_FORCE_MAP_MIN "SS_TOUCH_ACTIVE_TOTAL_CX_FORCE_MIN" +#define SS_TOTAL_CX_FORCE_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_CX_FORCE_MAX" +#define SS_TOTAL_CX_SENSE_MAP_MIN "SS_TOUCH_ACTIVE_TOTAL_CX_SENSE_MIN" +#define SS_TOTAL_CX_SENSE_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_CX_SENSE_MAX" +#define SS_TOTAL_CX_FORCE_ADJV_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_CX_ADJ_VERTICAL" +#define SS_TOTAL_CX_SENSE_ADJH_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_CX_ADJ_HORIZONTAL" + +#define MS_KEY_RAW_MIN_MAX "MS_KEY_RAW_DATA_MIN_MAX" +#define MS_KEY_CX1_MIN_MAX "MS_KEY_CX1_MIN_MAX" +#define MS_KEY_CX2_MAP_MIN "MS_KEY_CX2_MIN" +#define MS_KEY_CX2_MAP_MAX "MS_KEY_CX2_MAX" +#define MS_KEY_TOTAL_CX_MAP_MIN "MS_KEY_TOTAL_CX_MIN" +#define MS_KEY_TOTAL_CX_MAP_MAX "MS_KEY_TOTAL_CX_MAX" + +#define SS_IX1_FORCE_W "IX1_FORCE_W" +#define SS_IX2_FORCE_W "IX2_FORCE_W" +#define SS_IX1_SENSE_W "IX1_SENSE_W" +#define SS_IX2_SENSE_W "IX2_SENSE_W" + +/* SS HOVER*/ +#define SS_HOVER_RAW_FORCE_MIN_MAX "SS_RAW_HOVER_DATA_FORCE_MIN_MAX" +#define SS_HOVER_TOTAL_IX_FORCE_MAP_MIN "SS_HOVER_TOTAL_IX_FORCE_MIN" +#define SS_HOVER_TOTAL_IX_FORCE_MAP_MAX "SS_HOVER_TOTAL_IX_FORCE_MAX" +#define SS_HOVER_RAW_SENSE_MIN_MAX "SS_RAW_HOVER_DATA_SENSE_MIN_MAX" +#define SS_HOVER_TOTAL_IX_SENSE_MAP_MIN "SS_HOVER_TOTAL_IX_SENSE_MIN" +#define SS_HOVER_TOTAL_IX_SENSE_MAP_MAX "SS_HOVER_TOTAL_IX_SENSE_MAX" + +/** @}*/ + +/** +* Struct used to specify which test perform during the Mass Production Test. +* For each test item selected in this structure, there should be one or more labels associated in the Limit file from where load the thresholds +*/ +typedef struct { + int MutualRaw; /*MS Raw min/Max test*/ + int MutualRawEachNode; + int MutualRawGap; /*MS Raw Gap(max-min) test*/ + int MutualRawAdj; /*MS Raw Adjacent test*/ + int MutualRawLP; /*MS Low Power Raw min/Max test*/ + int MutualRawGapLP; /*MS Low Power Raw Gap(max-min) test*/ + int MutualRawAdjLP; /*MS Low Power Raw Adjacent test*/ + int MutualRawAdjITO; /*MS Raw Adjacent test during ITO test*/ + + int MutualCx1; /*MS Cx1 min/Max test*/ + int MutualCx2; /*MS Cx2 min/Max (for each node) test*/ + int MutualCx2Adj; /*MS Vertical and Horizontal Adj Cx2 min/Max (for each node) test*/ + int MutualCxTotal; /*MS Total Cx min/Max (for each node) test*/ + int MutualCxTotalAdj; /*MS Total vertical and Horizontal Adj Cx2 min/Max (for each node) test*/ + int MutualCx1LP; /* /< MS LowPower Cx1 min/Max test */ + int MutualCx2LP; /* /< MS LowPower Cx2 min/Max (for each node) test */ + int MutualCx2AdjLP; /* /< MS LowPower Vertical and Horizontal Adj Cx2 min/Max + * (for each node) test */ + int MutualCxTotalLP; /* /< MS Total LowPower Cx min/Max (for each node) test + * */ + int MutualCxTotalAdjLP; /* /< MS Total LowPower vertical and Horizontal Adj Cx2 + * min/Max (for each node) test */ + + int MutualKeyRaw; /*MS Raw Key min/Max test*/ + int MutualKeyCx1; /*MS Cx1 Key min/Max test*/ + int MutualKeyCx2; /*MS Cx2 Key min/Max (for each node) test*/ + int MutualKeyCxTotal; /*MS Total Cx Key min/Max (for each node) test*/ + + int SelfHoverForceRaw; /* SS Hover Force Raw min/Max test */ + int SelfHoverSenceRaw; /*SS Hover Sence Raw min/Max test */ + int SelfHoverForceIxTotal; /*SS Hover Total Force Ix min/Max (for each node)* test */ + int SelfHoverSenceIxTotal; /*SS Hover Total Sence Ix min/Max (for each node)* test */ + + int SelfForceRaw; /*SS Force Raw min/Max test*/ + int SelfForceRawGap; /*SS Force Raw Gap(max-min) test*/ + int SelfForceRawLP; /*SS Low Power Force Raw min/Max test*/ + int SelfForceRawGapLP; /*SS Low Power Force Raw Gap(max-min) test*/ + + int SelfForceIx1; /*SS Force Ix1 min/Max test*/ + int SelfForceIx2; /*SS Force Ix2 min/Max (for each node) test*/ + int SelfForceIx2Adj; /*SS Vertical Adj Force Ix2 min/Max (for each node) test*/ + int SelfForceIxTotal; /*SS Total Force Ix min/Max (for each node) test*/ + int SelfForceIxTotalAdj; /*SS Total Vertical Adj Force Ix min/Max (for each node) test*/ + int SelfForceCx1; /*SS Force Cx1 min/Max test*/ + int SelfForceCx2; /*SS Force Cx2 min/Max (for each node) test*/ + int SelfForceCx2Adj; /*SS Vertical Adj Force Cx2 min/Max (for each node) test*/ + int SelfForceCxTotal; /*SS Total Force Cx min/Max (for each node) test*/ + int SelfForceCxTotalAdj; /*SS Total Vertical Adj Force Cx min/Max (for each node) test*/ + + int SelfSenseRaw; /*SS Sense Raw min/Max test*/ + int SelfSenseRawGap; /*SS Sense Raw Gap(max-min) test*/ + int SelfSenseRawLP; /*SS Low Power Sense Raw min/Max test*/ + int SelfSenseRawGapLP; /*SS Low Power Sense Raw Gap(max-min) test*/ + + int SelfSenseIx1; /*SS Sense Ix1 min/Max test*/ + int SelfSenseIx2; /*SS Sense Ix2 min/Max (for each node) test*/ + int SelfSenseIx2Adj; /*SS Horizontal Adj Sense Ix2 min/Max (for each node) test*/ + int SelfSenseIxTotal; /*SS Total Horizontal Sense Ix min/Max (for each node) test*/ + int SelfSenseIxTotalAdj; /*SS Total Horizontal Adj Sense Ix min/Max (for each node) test*/ + int SelfSenseCx1; /*SS Sense Cx1 min/Max test*/ + int SelfSenseCx2; /*SS Sense Cx2 min/Max (for each node) test*/ + int SelfSenseCx2Adj; /*SS Horizontal Adj Sense Cx2 min/Max (for each node) test*/ + int SelfSenseCxTotal; /*SS Total Sense Cx min/Max (for each node) test*/ + int SelfSenseCxTotalAdj; /*SS Total Horizontal Adj Sense Cx min/Max (for each node) test*/ + +} TestToDo; + +#define MAX_LIMIT_FILE_NAME 100 /*max number of chars of the limit file name*/ + +/** + * Struct which store the data coming from a Production Limit File + */ +typedef struct { + char *data; + int size; + char name[MAX_LIMIT_FILE_NAME]; +} LimitFile; + +int initTestToDo(void); +/**@}*/ + +/**@}*/ + +int computeAdjHoriz(i8 *data, int row, int column, u8 **result); +int computeAdjHorizTotal(short *data, int row, int column, u16 **result); +int computeAdjVert(i8 *data, int row, int column, u8 **result); +int computeAdjVertTotal(short *data, int row, int column, u16 **result); +int computeAdjHorizFromU(u8 *data, int row, int column, u8 **result); +int computeAdjHorizTotalFromU(u16 *data, int row, int column, u16 **result); +int computeAdjVertFromU(u8 *data, int row, int column, u8 **result); +int computeAdjVertTotalFromU(u16 *data, int row, int column, u16 **result); +int checkLimitsMinMax(short *data, int row, int column, int min, int max); +int checkLimitsMap(i8 *data, int row, int column, int *min, int *max); +int checkLimitsMapTotal(short *data, int row, int column, int *min, int *max); +int checkLimitsMapFromU(u8 *data, int row, int column, int *min, int *max); +int checkLimitsMapTotalFromU(u16 *data, int row, int column, int *min, + int *max); +int checkLimitsMapAdj(u8 *data, int row, int column, int *max); +int checkLimitsMapAdjTotal(u16 *data, int row, int column, int *max); + +/** @defgroup mp_api MP API + * @ingroup mp_test + * Functions to execute the MP test. + * The parameters of these functions allow to customize their behavior in order to satisfy different scenarios + * @{ + */ +int production_test_ito(char *path_limits, TestToDo *todo); +int production_test_initialization(u8 type); +int production_test_main(char *pathThresholds, int stop_on_fail, int saveInit, + TestToDo *todo); +int production_test_ms_raw(char *path_limits, int stop_on_fail, TestToDo *todo); +int production_test_ms_raw_lp(char *path_limits, int stop_on_fail, + TestToDo *todo); +int production_test_ms_cx(char *path_limits, int stop_on_fail, TestToDo *todo); +int production_test_ms_cx_lp(char *path_limits, int stop_on_fail, + TestToDo *todo); +int production_test_ss_raw(char *path_limits, int stop_on_fail, TestToDo *todo); +int production_test_ss_raw_lp(char *path_limits, int stop_on_fail, + TestToDo *todo); +int production_test_ss_ix_cx(char *path_limits, int stop_on_fail, + TestToDo *todo); +int production_test_data(char *path_limits, int stop_on_fail, TestToDo *todo); +int production_test_ms_key_cx(char *path_limits, int stop_on_fail, + TestToDo *todo); +int production_test_ms_key_raw(char *path_limits); +int computeTotal(u8 *data, u8 main, int row, int column, int m, int n, + u16 **result); +/** @}*/ + +/** + * @addtogroup limit_file + * @{ + */ +int parseProductionTestLimits(char *path, LimitFile *file, char *label, + int **data, int *row, int *column); +int readLine(char *data, char *line, int size, int *n); +int getLimitsFile(char *path, LimitFile *file); +int freeLimitsFile(LimitFile *file); +int freeCurrentLimitsFile(void); +/**@}*/ + +#endif diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTime.c b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTime.c new file mode 100644 index 000000000000..29b0f99adb81 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTime.c @@ -0,0 +1,78 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS Utility for mesuring/handling the time * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsTime.c +* \brief Contains all functions to handle and measure the time in the driver +*/ + +#include "ftsTime.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/** +* Take the starting time and save it in a StopWatch variable +* @param w pointer of a StopWatch struct +*/ +void startStopWatch(StopWatch *w) +{ + w->start = current_kernel_time(); +} + +/** +* Take the stop time and save it in a StopWatch variable +* @param w pointer of a StopWatch struct +*/ +void stopStopWatch(StopWatch *w) +{ + w->end = current_kernel_time(); +} + +/** +* Compute the amount of time spent from when the startStopWatch and then the stopStopWatch were called on the StopWatch variable +* @param w pointer of a StopWatch struct +* @return amount of time in ms (the return value is meaningless if the startStopWatch and stopStopWatch were not called before) +*/ +int elapsedMillisecond(StopWatch *w) +{ + int result; + + result = ((w->end.tv_sec - w->start.tv_sec) * 1000) + + (w->end.tv_nsec - w->start.tv_nsec) / 1000000; + return result; +} + +/** +* Compute the amount of time spent from when the startStopWatch and then the stopStopWatch were called on the StopWatch variable +* @param w pointer of a StopWatch struct +* @return amount of time in ns (the return value is meaningless if the startStopWatch and stopStopWatch were not called before) +*/ +int elapsedNanosecond(StopWatch *w) +{ + int result; + + result = ((w->end.tv_sec - w->start.tv_sec) * 1000000000) + + (w->end.tv_nsec - w->start.tv_nsec); + return result; +} diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTime.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTime.h new file mode 100644 index 000000000000..d9241c110cf4 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTime.h @@ -0,0 +1,63 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS Utility for measuring/handling the time * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsTime.h +* \brief Contains all the definitions and structs to handle and measure the time in the driver +*/ + +#ifndef FTS_TIME_H +#define FTS_TIME_H + +#include + +/** @defgroup timeouts Timeouts +* Definitions of all the Timeout used in several operations +* @{ +*/ +#define TIMEOUT_RESOLUTION \ + 2 /*timeout resolution in ms (all timeout should be multiples of this unit)*/ +#define GENERAL_TIMEOUT (50 * TIMEOUT_RESOLUTION) /*general timeout in ms*/ +#define RELEASE_INFO_TIMEOUT \ + (15 * TIMEOUT_RESOLUTION) /* timeout to request release info in ms*/ + +#define TIMEOUT_REQU_COMP_DATA \ + (100 * \ + TIMEOUT_RESOLUTION) /*timeout to request compensation data in ms*/ +#define TIMEOUT_REQU_DATA \ + (100 * TIMEOUT_RESOLUTION) /*timeout to request data in ms*/ +#define TIMEOUT_ITO_TEST_RESULT \ + (100 * TIMEOUT_RESOLUTION) /*timeout to perform ito test in ms*/ +#define TIMEOUT_INITIALIZATION_TEST_RESULT \ + (5000 * \ + TIMEOUT_RESOLUTION) /*timeout to perform initialization test in ms*/ +#define TIMEOUT_ECHO \ + TIMEOUT_INITIALIZATION_TEST_RESULT /*timeout of the echo command, should be the max of all the possible commands (used in worst case)*/ +/** @}*/ + +/** +* Struct used to measure the time elapsed between a starting and ending point. +*/ +typedef struct { + struct timespec start; /*store the starting time*/ + struct timespec end; /*store the finishing time*/ +} StopWatch; + +void startStopWatch(StopWatch *w); +void stopStopWatch(StopWatch *w); +int elapsedMillisecond(StopWatch *w); +int elapsedNanosecond(StopWatch *w); + +#endif diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTool.c b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTool.c new file mode 100644 index 000000000000..eb4bda79f117 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTool.c @@ -0,0 +1,639 @@ +/* + + ************************************************************************** + ** STMicroelectronics ** + ************************************************************************** + ** marco.cali@st.com ** + ************************************************************************** + * * + * FTS Utility Functions * + * * + ************************************************************************** + ************************************************************************** + + */ + +/*! +* \file ftsTool.c +* \brief Contains all the functions to support common operation inside the driver +*/ + +#include "ftsCompensation.h" +#include "ftsCore.h" +#include "ftsError.h" +#include "ftsHardware.h" +#include "ftsIO.h" +#include "ftsSoftware.h" +#include "ftsTime.h" +#include "ftsTool.h" +#include "../fts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** +* Print an array of byte in a HEX string and attach at the beginning a label. The function allocate memory that should be free outside the function itself +* @param label string to attach at the beginning +* @param buff pointer to the byte array that should be printed as HEX string +* @param count size of buff +* @return pointer to the array of characters that compose the HEX string. This point should be free outside when the string is no more needed +*/ +char *printHex(char *label, u8 *buff, int count, u8 *result) +{ + int i, offset; + + offset = strlen(label); + + strlcpy(result, label, offset); + + for (i = 0; i < count; i++) { + snprintf(&result[offset], 4, "%02X ", buff[i]); + offset += 3; + } + + return result; +} + +char *printHex_data(char *label, u8 *buff, int count) +{ + int i, offset; + char *result = NULL; + + offset = strlen(label); + result = (char *)kmalloc(((offset + 4 * count) + 1) * sizeof(char), + GFP_KERNEL); + if (result != NULL) { + strlcpy(result, label, offset); + + for (i = 0; i < count; i++) { + snprintf(&result[offset], 4, "%02X ", buff[i]); + offset += 3; + } + + strlcat(result, "\n", + ((offset + 4 * count) + 1) * sizeof(char)); + } + return result; +} + +/** + * Clear the FIFO from any event + * @return OK if success or an error code which specify the type of error encountered + */ +int flushFIFO(void) +{ + int ret; + u8 sett = SPECIAL_FIFO_FLUSH; + ret = writeSysCmd(SYS_CMD_SPECIAL, &sett, 1); + if (ret < OK) { + logError(1, "%s flushFIFO: ERROR %08X \n", tag, ret); + return ret; + } + + logError(0, "%s FIFO flushed! \n", tag); + return OK; +} + +/** +* Convert an array of bytes to an array of u16 taking two bytes at time, src has LSB first. +* @param src pointer to the source byte array +* @param src_length size of src +* @param dst pointer to the destination array. +* @return the final size of dst (half of the source) or ERROR_OP_NOT_ALLOW if the size of src is not multiple of 2. +*/ +int u8ToU16n(u8 *src, int src_length, u16 *dst) +{ + int i, j; + + if (src_length % 2 != 0) { + return ERROR_OP_NOT_ALLOW; + } else { + j = 0; + dst = (u16 *)kmalloc((src_length / 2) * sizeof(u16), + GFP_KERNEL); + for (i = 0; i < src_length; i += 2) { + dst[j] = ((src[i + 1] & 0x00FF) << 8) + + (src[i] & 0x00FF); + j++; + } + } + + return (src_length / 2); +} + +/** +* Convert an array of 2 bytes to a u16, src has LSB first (little endian). +* @param src pointer to the source byte array +* @param dst pointer to the destination u16. +* @return OK +*/ +int u8ToU16(u8 *src, u16 *dst) +{ + *dst = (u16)(((src[1] & 0x00FF) << 8) + (src[0] & 0x00FF)); + return OK; +} + +/** +* Convert an array of 2 bytes to a u16, src has MSB first (big endian). +* @param src pointer to the source byte array +* @param dst pointer to the destination u16. +* @return OK +*/ +int u8ToU16_be(u8 *src, u16 *dst) +{ + *dst = (u16)(((src[0] & 0x00FF) << 8) + (src[1] & 0x00FF)); + return OK; +} + +/** +* Convert an array of u16 to an array of u8, dst has MSB first (big endian). +* @param src pointer to the source array of u16 +* @param src_length size of src +* @param dst pointer to the destination array of u8. This array should be free when no need anymore +* @return size of dst (src size multiply by 2) +*/ +int u16ToU8n_be(u16 *src, int src_length, u8 *dst) +{ + int i, j; + dst = (u8 *)kmalloc((2 * src_length) * sizeof(u8), GFP_KERNEL); + j = 0; + for (i = 0; i < src_length; i++) { + dst[j] = (u8)(src[i] & 0xFF00) >> 8; + dst[j + 1] = (u8)(src[i] & 0x00FF); + j += 2; + } + + return src_length * 2; +} + +/** +* Convert a u16 to an array of 2 u8, dst has MSB first (big endian). +* @param src u16 to convert +* @param dst pointer to the destination array of 2 u8. +* @return OK +*/ +int u16ToU8_be(u16 src, u8 *dst) +{ + dst[0] = (u8)((src & 0xFF00) >> 8); + dst[1] = (u8)(src & 0x00FF); + return OK; +} + +/** +* Convert a u16 to an array of 2 u8, dst has LSB first (little endian). +* @param src u16 to convert +* @param dst pointer to the destination array of 2 u8. +* @return OK +*/ +int u16ToU8(u16 src, u8 *dst) +{ + dst[1] = (u8)((src & 0xFF00) >> 8); + dst[0] = (u8)(src & 0x00FF); + return OK; +} + +/** +* Convert an array of bytes to a u32, src has LSB first (little endian). +* @param src array of bytes to convert +* @param dst pointer to the destination u32 variable. +* @return OK +*/ +int u8ToU32(u8 *src, u32 *dst) +{ + *dst = (u32)(((src[3] & 0xFF) << 24) + ((src[2] & 0xFF) << 16) + + ((src[1] & 0xFF) << 8) + (src[0] & 0xFF)); + return OK; +} + +/** +* Convert a u32 to an array of 4 bytes, dst has LSB first (little endian). +* @param src u32 value to convert +* @param dst pointer to the destination array of 4 bytes. +* @return OK +*/ +int u32ToU8(u32 src, u8 *dst) +{ + dst[3] = (u8)((src & 0xFF000000) >> 24); + dst[2] = (u8)((src & 0x00FF0000) >> 16); + dst[1] = (u8)((src & 0x0000FF00) >> 8); + dst[0] = (u8)(src & 0x000000FF); + return OK; +} + +/** +* Convert a u32 to an array of 4 bytes, dst has MSB first (big endian). +* @param src u32 value to convert +* @param dst pointer to the destination array of 4 bytes. +* @return OK +*/ +int u32ToU8_be(u32 src, u8 *dst) +{ + dst[0] = (u8)((src & 0xFF000000) >> 24); + dst[1] = (u8)((src & 0x00FF0000) >> 16); + dst[2] = (u8)((src & 0x0000FF00) >> 8); + dst[3] = (u8)(src & 0x000000FF); + return OK; +} + +/** +* Execute a function passed as argment and retry it defined number of times if not successfull +* @param code pointer to a function which return an int and doesn't have any parameters +* @param wait_before_retry interval of time in ms to wait between one trial and another one +* @param retry_count max number of retry to attemp +* @return last return value obtained from the last execution of the code function +*/ +int attempt_function(int (*code)(void), unsigned long wait_before_retry, + int retry_count) +{ + int result; + int count = 0; + + do { + result = code(); + count++; + mdelay(wait_before_retry); + } while (count < retry_count && result < 0); + + if (count == retry_count) + return (result | ERROR_TIMEOUT); + else + return result; +} + +/** + * Enable all the possible sensing mode supported by the FW + * @return OK if success or an error code which specify the type of error encountered + */ +int senseOn(void) +{ + int ret; + + ret = setScanMode(SCAN_MODE_ACTIVE, 0x01); + if (ret < OK) { + logError(1, "%s senseOn: ERROR %08X\n", tag, ret); + return ret; + } + + logError(0, "%s senseOn: SENSE ON\n", tag); + return OK; +} + +/** + * Disable all the sensing mode + * @return OK if success or an error code which specify the type of error encountered + */ +int senseOff(void) +{ + int ret; + + ret = setScanMode(SCAN_MODE_ACTIVE, 0x00); + ; + if (ret < OK) { + logError(1, "%s senseOff: ERROR %08X\n", tag, ret); + return ret; + } + + logError(0, "%s senseOff: SENSE OFF\n", tag); + return OK; +} + +/** + * Clean up the IC status executing a system reset and giving the possibility to re-enabling the sensing + * @param enableTouch if 1, re-enable the sensing and the interrupt of the IC + * @return OK if success or an error code which specify the type of error encountered + */ +int cleanUp(int enableTouch) +{ + int res; + + logError(0, "%s cleanUp: system reset...\n", tag); + res = fts_system_reset(); + if (res < OK) + return res; + if (enableTouch) { + logError(0, "%s cleanUp: enabling touches...\n", tag); + res = senseOn(); + if (res < OK) + return res; + logError(0, "%s cleanUp: enabling interrupts...\n", tag); + res = fts_enableInterrupt(); + if (res < OK) + return res; + } + return OK; +} + +/** +* Transform an array of short in a matrix of short with a defined number of columns and the resulting number of rows +* @param data array of bytes to convert +* @param size size of data +* @param columns number of columns that the resulting matrix should have. +* @return a reference to a matrix of short where for each row there are columns elements +*/ +short **array1dTo2d_short(short *data, int size, int columns) +{ + int i; + short **matrix = (short **)kmalloc( + ((int)(size / columns)) * sizeof(short *), GFP_KERNEL); + if (matrix != NULL) { + for (i = 0; i < (int)(size / columns); i++) { + matrix[i] = (short *)kmalloc(columns * sizeof(short), + GFP_KERNEL); + } + + for (i = 0; i < size; i++) { + matrix[i / columns][i % columns] = data[i]; + } + } + + return matrix; +} + +/** +* Transform an array of u16 in a matrix of u16 with a defined number of columns and the resulting number of rows +* @param data array of bytes to convert +* @param size size of data +* @param columns number of columns that the resulting matrix should have. +* @return a reference to a matrix of u16 where for each row there are columns elements +*/ +u16 **array1dTo2d_u16(u16 *data, int size, int columns) +{ + int i; + u16 **matrix = (u16 **)kmalloc(((int)(size / columns)) * sizeof(u16 *), + GFP_KERNEL); + if (matrix != NULL) { + for (i = 0; i < (int)(size / columns); i++) { + matrix[i] = (u16 *)kmalloc(columns * sizeof(u16), + GFP_KERNEL); + } + + for (i = 0; i < size; i++) { + matrix[i / columns][i % columns] = data[i]; + } + } + + return matrix; +} + +/** +* Transform an array of u8 in a matrix of u8 with a defined number of columns and the resulting number of rows +* @param data array of bytes to convert +* @param size size of data +* @param columns number of columns that the resulting matrix should have. +* @return a reference to a matrix of short where for each row there are columns elements +*/ +u8 **array1dTo2d_u8(u8 *data, int size, int columns) +{ + int i; + u8 **matrix = (u8 **)kmalloc(((int)(size / columns)) * sizeof(u8 *), + GFP_KERNEL); + if (matrix != NULL) { + for (i = 0; i < (int)(size / columns); i++) { + matrix[i] = + (u8 *)kmalloc(columns * sizeof(u8), GFP_KERNEL); + } + + for (i = 0; i < size; i++) { + matrix[i / columns][i % columns] = data[i]; + } + } + + return matrix; +} + +/** +* Transform an array of i8 in a matrix of i8 with a defined number of columns and the resulting number of rows +* @param data array of bytes to convert +* @param size size of data +* @param columns number of columns that the resulting matrix should have. +* @return a reference to a matrix of short where for each row there are columns elements +*/ +i8 **array1dTo2d_i8(i8 *data, int size, int columns) +{ + int i; + i8 **matrix = (i8 **)kmalloc(((int)(size / columns)) * sizeof(i8 *), + GFP_KERNEL); + if (matrix != NULL) { + for (i = 0; i < (int)(size / columns); i++) { + matrix[i] = + (i8 *)kmalloc(columns * sizeof(i8), GFP_KERNEL); + } + + for (i = 0; i < size; i++) { + matrix[i / columns][i % columns] = data[i]; + } + } + + return matrix; +} + +/** +* Print in the kernel log a label followed by a matrix of short row x columns and free its memory +* @param label pointer to the string to print before the actual matrix +* @param matrix reference to the matrix of short which contain the actual data +* @param row number of rows on which the matrix should be print +* @param column number of columns for each row +*/ +void print_frame_short(char *label, short **matrix, int row, int column) +{ + int i, j; + logError(1, "%s %s \n", tag, label); + for (i = 0; i < row; i++) { + logError(1, "%s ", tag); + for (j = 0; j < column; j++) { + printk("%d ", matrix[i][j]); + } + logError(1, "\n"); + kfree(matrix[i]); + } + kfree(matrix); +} + +/** +* Print in the kernel log a label followed by a matrix of u16 row x columns and free its memory +* @param label pointer to the string to print before the actual matrix +* @param matrix reference to the matrix of u16 which contain the actual data +* @param row number of rows on which the matrix should be print +* @param column number of columns for each row +*/ +void print_frame_u16(char *label, u16 **matrix, int row, int column) +{ + int i, j; + logError(1, "%s %s \n", tag, label); + for (i = 0; i < row; i++) { + logError(0, "%s ", tag); + for (j = 0; j < column; j++) { + printk("%d ", matrix[i][j]); + } + logError(0, "\n"); + kfree(matrix[i]); + } + kfree(matrix); +} + +/** +* Print in the kernel log a label followed by a matrix of u8 row x columns and free its memory +* @param label pointer to the string to print before the actual matrix +* @param matrix reference to the matrix of u8 which contain the actual data +* @param row number of rows on which the matrix should be print +* @param column number of columns for each row +*/ +void print_frame_u8(char *label, u8 **matrix, int row, int column) +{ + int i, j; + logError(1, "%s %s \n", tag, label); + for (i = 0; i < row; i++) { + logError(1, "%s ", tag); + for (j = 0; j < column; j++) { + printk("%d ", matrix[i][j]); + } + logError(1, "\n"); + kfree(matrix[i]); + } + kfree(matrix); +} + +/** +* Print in the kernel log a label followed by a matrix of i8 row x columns and free its memory +* @param label pointer to the string to print before the actual matrix +* @param matrix reference to the matrix of u8 which contain the actual data +* @param row number of rows on which the matrix should be print +* @param column number of columns for each row +*/ +void print_frame_i8(char *label, i8 **matrix, int row, int column) +{ + int i, j; + logError(1, "%s %s \n", tag, label); + for (i = 0; i < row; i++) { + logError(1, "%s ", tag); + for (j = 0; j < column; j++) { + printk("%d ", matrix[i][j]); + } + logError(1, "\n"); + kfree(matrix[i]); + } + kfree(matrix); +} + +/** +* Print in the kernel log a label followed by a matrix of u32 row x columns and free its memory +* @param label pointer to the string to print before the actual matrix +* @param matrix reference to the matrix of u32 which contain the actual data +* @param row number of rows on which the matrix should be print +* @param column number of columns for each row +*/ +void print_frame_u32(char *label, u32 **matrix, int row, int column) +{ + int i, j; + logError(1, "%s %s \n", tag, label); + for (i = 0; i < row; i++) { + logError(0, "%s ", tag); + for (j = 0; j < column; j++) { + printk("%d ", matrix[i][j]); + } + logError(0, "\n"); + kfree(matrix[i]); + } + kfree(matrix); +} + +/** +* Print in the kernel log a label followed by a matrix of int row x columns and free its memory +* @param label pointer to the string to print before the actual matrix +* @param matrix reference to the matrix of int which contain the actual data +* @param row number of rows on which the matrix should be print +* @param column number of columns for each row +*/ +void print_frame_int(char *label, int **matrix, int row, int column) +{ + int i, j; + logError(1, "%s %s \n", tag, label); + for (i = 0; i < row; i++) { + logError(0, "%s ", tag); + for (j = 0; j < column; j++) { + printk("%d ", matrix[i][j]); + } + logError(0, "\n"); + kfree(matrix[i]); + } + kfree(matrix); +} + +/** +* Convert an array of bytes to an u64, src has MSB first (big endian). +* @param src array of bytes +* @param dest pointer to the destination u64. +* @param size size of src (can be <= 8) +* @return OK if success or ERROR_OP_NOT_ALLOW if size exceed 8 +*/ +int u8ToU64_be(u8 *src, u64 *dest, int size) +{ + int i = 0; + + if (size > sizeof(u64)) { + return ERROR_OP_NOT_ALLOW; + } else { + *dest = 0; + + for (i = 0; i < size; i++) { + *dest |= (u64)(src[i]) << ((size - 1 - i) * 8); + } + + return OK; + } +} + +/** +* Convert an u64 to an array of bytes, dest has MSB first (big endian). +* @param src value of u64 +* @param dest pointer to the destination array of bytes. +* @param size size of src (can be <= 8) +* @return OK if success or ERROR_OP_NOT_ALLOW if size exceed 8 +*/ +int u64ToU8_be(u64 src, u8 *dest, int size) +{ + int i = 0; + if (size > sizeof(u64)) { + return ERROR_OP_NOT_ALLOW; + } else { + for (i = 0; i < size; i++) { + dest[i] = (u8)((src >> ((size - 1 - i) * 8)) & 0xFF); + } + } + + return OK; +} + +/*********** NEW API *************/ + +/** + * Convert a value of an id in a bitmask with a 1 in the position of the value of the id + * @param id Value of the ID to convert + * @param mask pointer to the bitmask that will be updated with the value of id + * @param size dimension in bytes of mask + * @return OK if success or ERROR_OP_NOT_ALLOW if size of mask is not enough to contain ID + */ +int fromIDtoMask(u8 id, u8 *mask, int size) +{ + if (((int)((id) / 8)) < size) { + logError(0, "%s %s: ID = %d Index = %d Position = %d !\n", tag, + __func__, id, ((int)((id) / 8)), (id % 8)); + mask[((int)((id) / 8))] |= 0x01 << (id % 8); + return OK; + } else { + logError( + 1, + "%s %s: Bitmask too small! Impossible contain ID = %d %d>=%d! ERROR %08X\n", + tag, __func__, id, ((int)((id) / 8)), size, + ERROR_OP_NOT_ALLOW); + return ERROR_OP_NOT_ALLOW; + } +} diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTool.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTool.h new file mode 100644 index 000000000000..565c57b8636c --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsTool.h @@ -0,0 +1,56 @@ +/* + +************************************************************************** +** STMicroelectronics ** +************************************************************************** +** marco.cali@st.com ** +************************************************************************** +* * +* FTS Utility Functions * +* * +************************************************************************** +************************************************************************** + +*/ + +/*! +* \file ftsTool.h +* \brief Contains all the definitions to support common operations inside the driver +*/ + +#ifndef FTS_TOOL_H +#define FTS_TOOL_H + +char *printHex(char *label, u8 *buff, int count, u8 *result); +char *printHex_data(char *label, u8 *buff, int count); +int u8ToU16(u8 *src, u16 *dst); +int u8ToU16_be(u8 *src, u16 *dst); +int u8ToU16n(u8 *src, int src_length, u16 *dst); +int u16ToU8(u16 src, u8 *dst); +int u16ToU8_be(u16 src, u8 *dst); +int u16ToU8n_be(u16 *src, int src_length, u8 *dst); +int u8ToU32(u8 *src, u32 *dst); +int u32ToU8(u32 src, u8 *dst); +int u32ToU8_be(u32 src, u8 *dst); +int u8ToU64_be(u8 *src, u64 *dest, int size); +int u64ToU8_be(u64 src, u8 *dest, int size); +int attempt_function(int (*code)(void), unsigned long wait_before_retry, + int retry_count); +int senseOn(void); +int senseOff(void); +void print_frame_short(char *label, short **matrix, int row, int column); +short **array1dTo2d_short(short *data, int size, int columns); +void print_frame_u16(char *label, u16 **matrix, int row, int column); +u16 **array1dTo2d_u16(u16 *data, int size, int columns); +u8 **array1dTo2d_u8(u8 *data, int size, int columns); +i8 **array1dTo2d_i8(i8 *data, int size, int columns); +void print_frame_u8(char *label, u8 **matrix, int row, int column); +void print_frame_i8(char *label, i8 **matrix, int row, int column); +void print_frame_u32(char *label, u32 **matrix, int row, int column); +void print_frame_int(char *label, int **matrix, int row, int column); +int cleanUp(int enableTouch); +int flushFIFO(void); + +int fromIDtoMask(u8 id, u8 *mask, int size); + +#endif diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_limits.h b/drivers/input/touchscreen/xiaomi/fts_521/fts_limits.h new file mode 100644 index 000000000000..7d34aa93c02a --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_limits.h @@ -0,0 +1,1412 @@ +/*! +* \file fts_limits.h +* \brief Contains the size and the byte array of the production test limit file which contains thresholds used to test data +*/ + +#ifndef FTS_LIMITS_H +#define FTS_LIMITS_H +/*This is an auto generated header file*/ +/*--->Remember to change the name of the two variables!<---*/ +const uint32_t myArray2_size = 16725; + +/** + * Array containing the production limit file + */ +const uint8_t myArray2[] = { + 0x2A, 0x53, 0x54, 0x4F, 0x50, 0x5F, 0x4F, 0x4E, 0x5F, 0x46, 0x41, 0x49, + 0x4C, 0x2C, 0x31, 0x2C, 0x31, 0x0A, 0x31, 0x0A, 0x2A, 0x53, 0x54, 0x4F, + 0x50, 0x5F, 0x4F, 0x4E, 0x5F, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x2C, 0x31, + 0x2C, 0x31, 0x0A, 0x31, 0x0A, 0x2A, 0x46, 0x4F, 0x52, 0x43, 0x45, 0x5F, + 0x46, 0x57, 0x5F, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x2C, 0x31, 0x2C, + 0x31, 0x0A, 0x30, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x49, 0x58, 0x31, 0x5F, + 0x46, 0x4F, 0x52, 0x43, 0x45, 0x5F, 0x57, 0x2C, 0x31, 0x2C, 0x31, 0x0A, + 0x32, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x49, 0x58, 0x32, 0x5F, 0x46, 0x4F, + 0x52, 0x43, 0x45, 0x5F, 0x57, 0x2C, 0x31, 0x2C, 0x31, 0x0A, 0x31, 0x0A, + 0x2A, 0x53, 0x53, 0x5F, 0x49, 0x58, 0x31, 0x5F, 0x53, 0x45, 0x4E, 0x53, + 0x45, 0x5F, 0x57, 0x2C, 0x31, 0x2C, 0x31, 0x0A, 0x32, 0x0A, 0x2A, 0x53, + 0x53, 0x5F, 0x49, 0x58, 0x32, 0x5F, 0x53, 0x45, 0x4E, 0x53, 0x45, 0x5F, + 0x57, 0x2C, 0x31, 0x2C, 0x31, 0x0A, 0x31, 0x0A, 0x2A, 0x4D, 0x53, 0x5F, + 0x52, 0x41, 0x57, 0x5F, 0x44, 0x41, 0x54, 0x41, 0x5F, 0x4D, 0x49, 0x4E, + 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x31, 0x2C, 0x32, 0x0A, 0x31, 0x30, 0x30, + 0x30, 0x2C, 0x31, 0x35, 0x30, 0x30, 0x30, 0x0A, 0x2A, 0x4D, 0x53, 0x5F, + 0x52, 0x41, 0x57, 0x5F, 0x44, 0x41, 0x54, 0x41, 0x5F, 0x47, 0x41, 0x50, + 0x2C, 0x31, 0x2C, 0x31, 0x0A, 0x33, 0x30, 0x30, 0x30, 0x0A, 0x2A, 0x4D, + 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, + 0x56, 0x45, 0x5F, 0x43, 0x58, 0x31, 0x5F, 0x4D, 0x49, 0x4E, 0x5F, 0x4D, + 0x41, 0x58, 0x2C, 0x31, 0x2C, 0x32, 0x0A, 0x30, 0x2C, 0x36, 0x33, 0x0A, + 0x2A, 0x4D, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, + 0x54, 0x49, 0x56, 0x45, 0x5F, 0x43, 0x58, 0x32, 0x5F, 0x4D, 0x49, 0x4E, + 0x2C, 0x32, 0x32, 0x2C, 0x32, 0x37, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x2A, 0x4D, 0x53, 0x5F, 0x54, + 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, + 0x43, 0x58, 0x32, 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x32, 0x32, 0x2C, 0x32, + 0x37, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x2A, 0x4D, 0x53, 0x5F, + 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, + 0x5F, 0x43, 0x58, 0x32, 0x5F, 0x41, 0x44, 0x4A, 0x5F, 0x48, 0x4F, 0x52, + 0x49, 0x5A, 0x4F, 0x4E, 0x54, 0x41, 0x4C, 0x2C, 0x32, 0x32, 0x2C, 0x32, + 0x36, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x2A, 0x4D, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, + 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, 0x43, 0x58, 0x32, 0x5F, 0x41, + 0x44, 0x4A, 0x5F, 0x56, 0x45, 0x52, 0x54, 0x49, 0x43, 0x41, 0x4C, 0x2C, + 0x32, 0x31, 0x2C, 0x32, 0x37, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x0A, 0x2A, 0x4D, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, + 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, 0x54, 0x4F, 0x54, 0x41, + 0x4C, 0x5F, 0x43, 0x58, 0x5F, 0x4D, 0x49, 0x4E, 0x2C, 0x32, 0x32, 0x2C, + 0x32, 0x37, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x0A, 0x2A, 0x4D, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, + 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, 0x54, 0x4F, 0x54, 0x41, + 0x4C, 0x5F, 0x43, 0x58, 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x32, 0x32, 0x2C, + 0x32, 0x37, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, + 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x2A, 0x4D, 0x53, + 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, + 0x45, 0x5F, 0x54, 0x4F, 0x54, 0x41, 0x4C, 0x5F, 0x43, 0x58, 0x5F, 0x41, + 0x44, 0x4A, 0x5F, 0x48, 0x4F, 0x52, 0x49, 0x5A, 0x4F, 0x4E, 0x54, 0x41, + 0x4C, 0x2C, 0x32, 0x32, 0x2C, 0x32, 0x36, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x2A, 0x4D, 0x53, 0x5F, + 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, + 0x5F, 0x54, 0x4F, 0x54, 0x41, 0x4C, 0x5F, 0x43, 0x58, 0x5F, 0x41, 0x44, + 0x4A, 0x5F, 0x56, 0x45, 0x52, 0x54, 0x49, 0x43, 0x41, 0x4C, 0x2C, 0x32, + 0x31, 0x2C, 0x32, 0x37, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x2A, 0x4D, 0x53, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x52, 0x41, + 0x57, 0x5F, 0x44, 0x41, 0x54, 0x41, 0x5F, 0x4D, 0x49, 0x4E, 0x5F, 0x4D, + 0x41, 0x58, 0x2C, 0x31, 0x2C, 0x32, 0x0A, 0x30, 0x2C, 0x38, 0x30, 0x30, + 0x30, 0x0A, 0x2A, 0x4D, 0x53, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x43, 0x58, + 0x31, 0x5F, 0x4D, 0x49, 0x4E, 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x31, 0x2C, + 0x32, 0x0A, 0x30, 0x2C, 0x36, 0x34, 0x0A, 0x2A, 0x4D, 0x53, 0x5F, 0x4B, + 0x45, 0x59, 0x5F, 0x43, 0x58, 0x32, 0x5F, 0x4D, 0x49, 0x4E, 0x2C, 0x31, + 0x2C, 0x33, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x2A, 0x4D, 0x53, + 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x43, 0x58, 0x32, 0x5F, 0x4D, 0x41, 0x58, + 0x2C, 0x31, 0x2C, 0x33, 0x0A, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x2C, 0x36, + 0x34, 0x0A, 0x2A, 0x4D, 0x53, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x54, 0x4F, + 0x54, 0x41, 0x4C, 0x5F, 0x43, 0x58, 0x5F, 0x4D, 0x49, 0x4E, 0x2C, 0x31, + 0x2C, 0x33, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x2A, 0x4D, 0x53, + 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x54, 0x4F, 0x54, 0x41, 0x4C, 0x5F, 0x43, + 0x58, 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x31, 0x2C, 0x33, 0x0A, 0x36, 0x34, + 0x2C, 0x36, 0x34, 0x2C, 0x36, 0x34, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x52, + 0x41, 0x57, 0x5F, 0x44, 0x41, 0x54, 0x41, 0x5F, 0x46, 0x4F, 0x52, 0x43, + 0x45, 0x5F, 0x4D, 0x49, 0x4E, 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x31, 0x2C, + 0x32, 0x0A, 0x31, 0x30, 0x30, 0x30, 0x2C, 0x31, 0x35, 0x30, 0x30, 0x30, + 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x52, 0x41, 0x57, 0x5F, 0x44, 0x41, 0x54, + 0x41, 0x5F, 0x46, 0x4F, 0x52, 0x43, 0x45, 0x5F, 0x47, 0x41, 0x50, 0x2C, + 0x31, 0x2C, 0x31, 0x0A, 0x33, 0x30, 0x30, 0x0A, 0x2A, 0x53, 0x53, 0x5F, + 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, + 0x5F, 0x49, 0x58, 0x31, 0x5F, 0x46, 0x4F, 0x52, 0x43, 0x45, 0x5F, 0x4D, + 0x49, 0x4E, 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x31, 0x2C, 0x32, 0x0A, 0x30, + 0x2C, 0x36, 0x33, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, + 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, 0x49, 0x58, 0x32, + 0x5F, 0x46, 0x4F, 0x52, 0x43, 0x45, 0x5F, 0x4D, 0x49, 0x4E, 0x2C, 0x32, + 0x32, 0x2C, 0x31, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, + 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, + 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, + 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, + 0x2A, 0x53, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, + 0x54, 0x49, 0x56, 0x45, 0x5F, 0x49, 0x58, 0x32, 0x5F, 0x46, 0x4F, 0x52, + 0x43, 0x45, 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x32, 0x32, 0x2C, 0x31, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, + 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, 0x49, 0x58, 0x32, + 0x5F, 0x41, 0x44, 0x4A, 0x5F, 0x56, 0x45, 0x52, 0x54, 0x49, 0x43, 0x41, + 0x4C, 0x2C, 0x32, 0x31, 0x2C, 0x31, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, + 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, + 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, + 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, + 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, + 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, + 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, + 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x54, + 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, + 0x54, 0x4F, 0x54, 0x41, 0x4C, 0x5F, 0x49, 0x58, 0x5F, 0x46, 0x4F, 0x52, + 0x43, 0x45, 0x5F, 0x4D, 0x49, 0x4E, 0x2C, 0x32, 0x32, 0x2C, 0x31, 0x0A, + 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, + 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, + 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, + 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x2A, 0x53, 0x53, 0x5F, + 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, + 0x5F, 0x54, 0x4F, 0x54, 0x41, 0x4C, 0x5F, 0x49, 0x58, 0x5F, 0x46, 0x4F, + 0x52, 0x43, 0x45, 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x32, 0x32, 0x2C, 0x31, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x54, 0x4F, 0x55, + 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, 0x54, 0x4F, + 0x54, 0x41, 0x4C, 0x5F, 0x49, 0x58, 0x5F, 0x41, 0x44, 0x4A, 0x5F, 0x56, + 0x45, 0x52, 0x54, 0x49, 0x43, 0x41, 0x4C, 0x2C, 0x32, 0x31, 0x2C, 0x31, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, + 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, 0x43, 0x58, 0x31, 0x5F, 0x46, 0x4F, + 0x52, 0x43, 0x45, 0x5F, 0x4D, 0x49, 0x4E, 0x5F, 0x4D, 0x41, 0x58, 0x2C, + 0x31, 0x2C, 0x32, 0x0A, 0x30, 0x2C, 0x36, 0x33, 0x0A, 0x2A, 0x53, 0x53, + 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, + 0x45, 0x5F, 0x43, 0x58, 0x32, 0x5F, 0x46, 0x4F, 0x52, 0x43, 0x45, 0x5F, + 0x4D, 0x49, 0x4E, 0x2C, 0x32, 0x32, 0x2C, 0x31, 0x0A, 0x30, 0x0A, 0x30, + 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, + 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, + 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, + 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x54, 0x4F, 0x55, + 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, 0x43, 0x58, + 0x32, 0x5F, 0x46, 0x4F, 0x52, 0x43, 0x45, 0x5F, 0x4D, 0x41, 0x58, 0x2C, + 0x32, 0x32, 0x2C, 0x31, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, + 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x2A, 0x53, 0x53, + 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, + 0x45, 0x5F, 0x43, 0x58, 0x32, 0x5F, 0x41, 0x44, 0x4A, 0x5F, 0x56, 0x45, + 0x52, 0x54, 0x49, 0x43, 0x41, 0x4C, 0x2C, 0x32, 0x31, 0x2C, 0x31, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, + 0x2A, 0x53, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, + 0x54, 0x49, 0x56, 0x45, 0x5F, 0x54, 0x4F, 0x54, 0x41, 0x4C, 0x5F, 0x43, + 0x58, 0x5F, 0x46, 0x4F, 0x52, 0x43, 0x45, 0x5F, 0x4D, 0x49, 0x4E, 0x2C, + 0x32, 0x32, 0x2C, 0x31, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, + 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, + 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, + 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, 0x0A, 0x30, + 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, + 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, 0x54, 0x4F, 0x54, 0x41, 0x4C, 0x5F, + 0x43, 0x58, 0x5F, 0x46, 0x4F, 0x52, 0x43, 0x45, 0x5F, 0x4D, 0x41, 0x58, + 0x2C, 0x32, 0x32, 0x2C, 0x31, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x2A, 0x53, + 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, + 0x56, 0x45, 0x5F, 0x54, 0x4F, 0x54, 0x41, 0x4C, 0x5F, 0x43, 0x58, 0x5F, + 0x41, 0x44, 0x4A, 0x5F, 0x56, 0x45, 0x52, 0x54, 0x49, 0x43, 0x41, 0x4C, + 0x2C, 0x32, 0x31, 0x2C, 0x31, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x32, 0x35, + 0x35, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x52, 0x41, + 0x57, 0x5F, 0x44, 0x41, 0x54, 0x41, 0x5F, 0x53, 0x45, 0x4E, 0x53, 0x45, + 0x5F, 0x4D, 0x49, 0x4E, 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x31, 0x2C, 0x32, + 0x0A, 0x31, 0x30, 0x30, 0x30, 0x2C, 0x31, 0x35, 0x30, 0x30, 0x30, 0x0A, + 0x2A, 0x53, 0x53, 0x5F, 0x52, 0x41, 0x57, 0x5F, 0x44, 0x41, 0x54, 0x41, + 0x5F, 0x53, 0x45, 0x4E, 0x53, 0x45, 0x5F, 0x47, 0x41, 0x50, 0x2C, 0x31, + 0x2C, 0x31, 0x0A, 0x33, 0x30, 0x30, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x54, + 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, + 0x49, 0x58, 0x31, 0x5F, 0x53, 0x45, 0x4E, 0x53, 0x45, 0x5F, 0x4D, 0x49, + 0x4E, 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x31, 0x2C, 0x32, 0x0A, 0x30, 0x2C, + 0x36, 0x33, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, + 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, 0x49, 0x58, 0x32, 0x5F, + 0x53, 0x45, 0x4E, 0x53, 0x45, 0x5F, 0x4D, 0x49, 0x4E, 0x2C, 0x31, 0x2C, + 0x32, 0x37, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x2A, 0x53, 0x53, + 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, + 0x45, 0x5F, 0x49, 0x58, 0x32, 0x5F, 0x53, 0x45, 0x4E, 0x53, 0x45, 0x5F, + 0x4D, 0x41, 0x58, 0x2C, 0x31, 0x2C, 0x32, 0x37, 0x0A, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x0A, 0x2A, 0x53, 0x53, + 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, + 0x45, 0x5F, 0x49, 0x58, 0x32, 0x5F, 0x41, 0x44, 0x4A, 0x5F, 0x48, 0x4F, + 0x52, 0x49, 0x5A, 0x4F, 0x4E, 0x54, 0x41, 0x4C, 0x2C, 0x31, 0x2C, 0x32, + 0x36, 0x0A, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x0A, 0x2A, 0x53, + 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, + 0x56, 0x45, 0x5F, 0x54, 0x4F, 0x54, 0x41, 0x4C, 0x5F, 0x49, 0x58, 0x5F, + 0x53, 0x45, 0x4E, 0x53, 0x45, 0x5F, 0x4D, 0x49, 0x4E, 0x2C, 0x31, 0x2C, + 0x32, 0x37, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, + 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x2A, 0x53, 0x53, + 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, + 0x45, 0x5F, 0x54, 0x4F, 0x54, 0x41, 0x4C, 0x5F, 0x49, 0x58, 0x5F, 0x53, + 0x45, 0x4E, 0x53, 0x45, 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x31, 0x2C, 0x32, + 0x37, 0x0A, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, + 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, 0x54, 0x4F, 0x54, 0x41, 0x4C, + 0x5F, 0x49, 0x58, 0x5F, 0x41, 0x44, 0x4A, 0x5F, 0x48, 0x4F, 0x52, 0x49, + 0x5A, 0x4F, 0x4E, 0x54, 0x41, 0x4C, 0x2C, 0x31, 0x2C, 0x32, 0x36, 0x0A, + 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, + 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, + 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, + 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, + 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, + 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, + 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, + 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, + 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x0A, 0x2A, 0x53, 0x53, 0x5F, + 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, + 0x5F, 0x43, 0x58, 0x31, 0x5F, 0x53, 0x45, 0x4E, 0x53, 0x45, 0x5F, 0x4D, + 0x49, 0x4E, 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x31, 0x2C, 0x32, 0x0A, 0x30, + 0x2C, 0x36, 0x33, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, + 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, 0x43, 0x58, 0x32, + 0x5F, 0x53, 0x45, 0x4E, 0x53, 0x45, 0x5F, 0x4D, 0x49, 0x4E, 0x2C, 0x31, + 0x2C, 0x32, 0x37, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, + 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, + 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, + 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, + 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x2A, 0x53, + 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, + 0x56, 0x45, 0x5F, 0x43, 0x58, 0x32, 0x5F, 0x53, 0x45, 0x4E, 0x53, 0x45, + 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x31, 0x2C, 0x32, 0x37, 0x0A, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, + 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x0A, 0x2A, 0x53, + 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, + 0x56, 0x45, 0x5F, 0x43, 0x58, 0x32, 0x5F, 0x41, 0x44, 0x4A, 0x5F, 0x48, + 0x4F, 0x52, 0x49, 0x5A, 0x4F, 0x4E, 0x54, 0x41, 0x4C, 0x2C, 0x31, 0x2C, + 0x32, 0x36, 0x0A, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x0A, 0x2A, + 0x53, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, + 0x49, 0x56, 0x45, 0x5F, 0x54, 0x4F, 0x54, 0x41, 0x4C, 0x5F, 0x43, 0x58, + 0x5F, 0x53, 0x45, 0x4E, 0x53, 0x45, 0x5F, 0x4D, 0x49, 0x4E, 0x2C, 0x31, + 0x2C, 0x32, 0x37, 0x0A, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, + 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, + 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, + 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, + 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x0A, 0x2A, 0x53, + 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, 0x5F, 0x41, 0x43, 0x54, 0x49, + 0x56, 0x45, 0x5F, 0x54, 0x4F, 0x54, 0x41, 0x4C, 0x5F, 0x43, 0x58, 0x5F, + 0x53, 0x45, 0x4E, 0x53, 0x45, 0x5F, 0x4D, 0x41, 0x58, 0x2C, 0x31, 0x2C, + 0x32, 0x37, 0x0A, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, + 0x35, 0x35, 0x0A, 0x2A, 0x53, 0x53, 0x5F, 0x54, 0x4F, 0x55, 0x43, 0x48, + 0x5F, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5F, 0x54, 0x4F, 0x54, 0x41, + 0x4C, 0x5F, 0x43, 0x58, 0x5F, 0x41, 0x44, 0x4A, 0x5F, 0x48, 0x4F, 0x52, + 0x49, 0x5A, 0x4F, 0x4E, 0x54, 0x41, 0x4C, 0x2C, 0x31, 0x2C, 0x32, 0x36, + 0x0A, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, + 0x2C, 0x32, 0x35, 0x35, 0x2C, 0x32, 0x35, 0x35, 0x0A, +}; + +#endif diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_proc.c b/drivers/input/touchscreen/xiaomi/fts_521/fts_proc.c new file mode 100644 index 000000000000..2b1b5fa8dd0c --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_proc.c @@ -0,0 +1,2421 @@ +/* + + ************************************************************************** + ** STMicroelectronics ** + ************************************************************************** + ** marco.cali@st.com ** + ************************************************************************** + * * + * Utilities published in /proc/fts * + * * + ************************************************************************** + ************************************************************************** + + */ + +/*! +* \file fts_proc.c +* \brief contains the function and variables needed to publish a file node in the file system which allow to communicate with the IC from userspace +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fts.h" +#include "fts_lib/ftsCompensation.h" +#include "fts_lib/ftsCore.h" +#include "fts_lib/ftsIO.h" +#include "fts_lib/ftsError.h" +#include "fts_lib/ftsFrame.h" +#include "fts_lib/ftsFlash.h" +#include "fts_lib/ftsTest.h" +#include "fts_lib/ftsTime.h" +#include "fts_lib/ftsTool.h" + +#define DRIVER_TEST_FILE_NODE "driver_test" +#define CHUNK_PROC 1024 +#define DIAGNOSTIC_NUM_FRAME 10 + +/** @defgroup proc_file_code Proc File Node +* @ingroup file_nodes +* The /proc/fts/driver_test file node provide expose the most important API implemented into the driver to execute any possible operation into the IC \n +* Thanks to a series of Operation Codes, each of them, with a different set of parameter, it is possible to select a function to execute\n +* The result of the function is usually returned into the shell as an ASCII hex string where each byte is encoded in two chars.\n +* @{ +*/ + +/*Bus operations*/ +#define CMD_READ 0x00 +#define CMD_WRITE 0x01 +#define CMD_WRITEREAD 0x02 +#define CMD_WRITETHENWRITEREAD 0x03 +#define CMD_WRITEU8UX 0x04 +#define CMD_WRITEREADU8UX 0x05 +#define CMD_WRITEU8UXTHENWRITEU8UX 0x06 +#define CMD_WRITEU8UXTHENWRITEREADU8UX 0x07 +#define CMD_GETLIMITSFILE 0x08 +#define CMD_GETFWFILE 0x09 +#define CMD_VERSION 0x0A +#define CMD_READCONFIG 0x0B + +/*GUI utils byte ver*/ +#define CMD_READ_BYTE 0xF0 +#define CMD_WRITE_BYTE 0xF1 +#define CMD_WRITEREAD_BYTE 0xF2 +#define CMD_WRITETHENWRITEREAD_BYTE 0xF3 +#define CMD_WRITEU8UX_BYTE 0xF4 +#define CMD_WRITEREADU8UX_BYTE 0xF5 +#define CMD_WRITEU8UXTHENWRITEU8UX_BYTE 0xF6 +#define CMD_WRITEU8UXTHENWRITEREADU8UX_BYTE 0xF7 +#define CMD_GETLIMITSFILE_BYTE 0xF8 +#define CMD_GETFWFILE_BYTE 0xF9 +#define CMD_VERSION_BYTE 0xFA +#define CMD_CHANGE_OUTPUT_MODE 0xFF + +/*Core/Tools*/ +#define CMD_POLLFOREVENT 0x11 +#define CMD_SYSTEMRESET 0x12 +#define CMD_CLEANUP 0x13 +#define CMD_POWERCYCLE 0x14 +#define CMD_READSYSINFO 0x15 +#define CMD_FWWRITE 0x16 +#define CMD_INTERRUPT 0x17 + +/*Frame*/ +#define CMD_GETFORCELEN 0x20 +#define CMD_GETSENSELEN 0x21 +#define CMD_GETMSFRAME 0x23 +#define CMD_GETSSFRAME 0x24 + +/*Compensation*/ +#define CMD_REQCOMPDATA 0x30 +#define CMD_READCOMPDATAHEAD 0x31 +#define CMD_READMSCOMPDATA 0x32 +#define CMD_READSSCOMPDATA 0x33 +#define CMD_READTOTMSCOMPDATA 0x35 +#define CMD_READTOTSSCOMPDATA 0x36 + +/*FW Update*/ +#define CMD_GETFWVER 0x40 +#define CMD_FLASHUNLOCK 0x42 +#define CMD_READFWFILE 0x43 +#define CMD_FLASHPROCEDURE 0x44 +#define CMD_FLASHERASEUNLOCK 0x45 +#define CMD_FLASHERASEPAGE 0x46 + +/*MP test*/ +#define CMD_ITOTEST 0x50 +#define CMD_INITTEST 0x51 +#define CMD_MSRAWTEST 0x52 +#define CMD_MSINITDATATEST 0x53 +#define CMD_SSRAWTEST 0x54 +#define CMD_SSINITDATATEST 0x55 +#define CMD_MAINTEST 0x56 +#define CMD_FREELIMIT 0x57 + +/*Diagnostic*/ +#define CMD_DIAGNOSTIC 0x60 + +#define CMD_CHANGE_SAD 0x70 + +static u8 bin_output; +/** @}*/ + +/** @defgroup scriptless Scriptless Protocol + * @ingroup proc_file_code + * Scriptless Protocol allows ST Software (such as FingerTip Studio etc) to communicate with the IC from an user space. + * This mode gives access to common bus operations (write, read etc) and support additional functionalities. \n + * The protocol is based on exchange of binary messages included between a start and an end byte + * @{ + */ + +#define MESSAGE_START_BYTE 0x7B +#define MESSAGE_END_BYTE 0x7D +#define MESSAGE_MIN_HEADER_SIZE 8 + +/** + * Possible actions that can be requested by an host + */ +typedef enum { + ACTION_WRITE = (u16)0x0001, + ACTION_READ = (u16)0x0002, + ACTION_WRITE_READ = (u16)0x0003, + ACTION_GET_VERSION = (u16)0x0004, + ACTION_WRITEU8UX = (u16)0x0011, + ACTION_WRITEREADU8UX = (u16)0x0012, + ACTION_WRITETHENWRITEREAD = (u16)0x0013, + ACTION_WRITEU8XTHENWRITEREADU8UX = (u16)0x0014, + ACTION_WRITEU8UXTHENWRITEU8UX = (u16)0x0015, + ACTION_GET_FW = (u16)0x1000, + ACTION_GET_LIMIT = (u16)0x1001 +} Actions; + +/** + * Struct used to contain info of the message received by the host in Scriptless mode + */ +typedef struct { + u16 msg_size; + u16 counter; + Actions action; + u8 dummy; +} Message; + +/** @}*/ + +extern TestToDo tests; +extern SysInfo systemInfo; + +static int limit; +static int chunk; +static int printed; +static struct proc_dir_entry *fts_dir; +static u8 *driver_test_buff; +char buf_chunk[CHUNK_PROC]; +static Message mess; + +/************************ SEQUENTIAL FILE UTILITIES **************************/ +/** +* This function is called at the beginning of the stream to a sequential file or every time into the sequential were already written PAGE_SIZE bytes and the stream need to restart +* @param s pointer to the sequential file on which print the data +* @param pos pointer to the offset where write the data +* @return NULL if there is no data to print or the pointer to the beginning of the data that need to be printed +*/ +static void *fts_seq_start(struct seq_file *s, loff_t *pos) +{ + logError( + 0, + "%s %s: Entering start(), pos = %Ld limit = %d printed = %d \n", + tag, __func__, *pos, limit, printed); + + if (driver_test_buff == NULL && *pos == 0) { + logError(1, "%s %s: No data to print!\n", tag, __func__); + driver_test_buff = (u8 *)kmalloc(13 * sizeof(u8), GFP_KERNEL); + + snprintf(driver_test_buff, PAGE_SIZE, "{ %08X }\n", + ERROR_OP_NOT_ALLOW); + + limit = strlen(driver_test_buff); + } else { + if (*pos != 0) + *pos += chunk - 1; + + if (*pos >= limit) { + return NULL; + } + } + + chunk = CHUNK_PROC; + if (limit - *pos < CHUNK_PROC) + chunk = limit - *pos; + memset(buf_chunk, 0, CHUNK_PROC); + memcpy(buf_chunk, &driver_test_buff[(int)*pos], chunk); + + return buf_chunk; +} + +/** +* This function actually print a chunk amount of data in the sequential file +* @param s pointer to the sequential file where to print the data +* @param v pointer to the data to print +* @return 0 +*/ +static int fts_seq_show(struct seq_file *s, void *v) +{ + seq_write(s, (u8 *)v, chunk); + printed += chunk; + return 0; +} + +/** +* This function update the pointer and the counters to the next data to be printed +* @param s pointer to the sequential file where to print the data +* @param v pointer to the data to print +* @param pos pointer to the offset where write the next data +* @return NULL if there is no data to print or the pointer to the beginning of the next data that need to be printed +*/ +static void *fts_seq_next(struct seq_file *s, void *v, loff_t *pos) +{ + (*pos) += chunk; + chunk = CHUNK_PROC; + + if (*pos >= limit) + return NULL; + else { + if (limit - *pos < CHUNK_PROC) + chunk = limit - *pos; + } + + memset(buf_chunk, 0, CHUNK_PROC); + memcpy(buf_chunk, &driver_test_buff[(int)*pos], chunk); + return buf_chunk; +} + +/** +* This function is called when there are no more data to print the stream need to be terminated or when PAGE_SIZE data were already written into the sequential file +* @param s pointer to the sequential file where to print the data +* @param v pointer returned by fts_seq_next +*/ +static void fts_seq_stop(struct seq_file *s, void *v) +{ + if (v) { + /*logError(0, "%s %s: v is %X.\n", tag, __func__, v);*/ + } else { + limit = 0; + chunk = 0; + printed = 0; + if (driver_test_buff != NULL) { + kfree(driver_test_buff); + driver_test_buff = NULL; + + } else { + /*logError(0, "%s %s: driver_test_buff is already null.\n", tag, __func__);*/ + } + } +} + +/** +* Struct where define and specify the functions which implements the flow for writing on a sequential file +*/ +static struct seq_operations fts_seq_ops = { .start = fts_seq_start, + .next = fts_seq_next, + .stop = fts_seq_stop, + .show = fts_seq_show }; + +/** +* This function open a sequential file +* @param inode Inode in the file system that was called and triggered this function +* @param file file associated to the file node +* @return error code, 0 if success +*/ +static int fts_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &fts_seq_ops); +}; + +/*****************************************************************************/ + +/**************************** DRIVER TEST ************************************/ + +/** @addtogroup proc_file_code + * @{ + */ + +/** + * Receive the OP code and the inputs from shell when the file node is called, parse it and then execute the corresponding function + * echo cmd+parameters > /proc/fts/driver_test to execute the select command + * cat /proc/fts/driver_test to obtain the result into the shell \n + * the string returned in the shell is made up as follow: \n + * { = start byte \n + * the answer content and format strictly depend on the cmd executed. In general can be: an HEX string or a byte array (e.g in case of 0xF- commands) \n + * } = end byte \n + */ +static ssize_t fts_driver_test_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + int numberParam = 0; + struct fts_ts_info *info = dev_get_drvdata(getDev()); + char *p = NULL; + char pbuf[count]; + char path[100] = { 0 }; + int res = -1, j, index = 0; + int size = 6; + int temp, byte_call = 0; + u16 byteToRead = 0; + u32 fileSize = 0; + u8 *readData = NULL; + u8 *cmd = NULL; + u32 funcToTest[((count + 1) / 3)]; + u64 addr = 0; + MutualSenseFrame frameMS; + SelfSenseFrame frameSS; + + DataHeader dataHead; + MutualSenseData compData; + SelfSenseData comData; + TotMutualSenseData totCompData; + TotSelfSenseData totComData; + + u64 address; + u16 fw_version; + u16 config_id; + + Firmware fw; + LimitFile lim; + + mess.dummy = 0; + mess.action = 0; + mess.msg_size = 0; + + cmd = (u8 *)kzalloc(sizeof(u8) * count, GFP_KERNEL); + if (!cmd) { + res = ERROR_ALLOC; + goto END; + } + if (access_ok(VERIFY_READ, buf, count) < OK || + copy_from_user(pbuf, buf, count) != 0) { + res = ERROR_ALLOC; + goto END; + } + + p = pbuf; + if (count > MESSAGE_MIN_HEADER_SIZE - 1 && p[0] == MESSAGE_START_BYTE) { + logError(0, "%s Enter in Byte Mode! \n", tag); + byte_call = 1; + mess.msg_size = (p[1] << 8) | p[2]; + mess.counter = (p[3] << 8) | p[4]; + mess.action = (p[5] << 8) | p[6]; + logError( + 0, + "%s Message received: size = %d, counter_id = %d, action = %04X \n", + tag, mess.msg_size, mess.counter, mess.action); + size = MESSAGE_MIN_HEADER_SIZE + 2; + if (count < mess.msg_size || p[count - 2] != MESSAGE_END_BYTE) { + logError( + 1, + "%s number of byte received or end byte wrong! msg_size = %d != %d, last_byte = %02X != %02X ... ERROR %08X\n", + tag, mess.msg_size, count, p[count - 1], + MESSAGE_END_BYTE, ERROR_OP_NOT_ALLOW); + res = ERROR_OP_NOT_ALLOW; + goto END; + + } else { + numberParam = + mess.msg_size - MESSAGE_MIN_HEADER_SIZE + 1; + size = MESSAGE_MIN_HEADER_SIZE + 2; + switch (mess.action) { + case ACTION_READ: + cmd[0] = funcToTest[0] = CMD_READ_BYTE; + break; + + case ACTION_WRITE: + cmd[0] = funcToTest[0] = CMD_WRITE_BYTE; + break; + + case ACTION_WRITE_READ: + cmd[0] = funcToTest[0] = CMD_WRITEREAD_BYTE; + break; + + case ACTION_GET_VERSION: + cmd[0] = funcToTest[0] = CMD_VERSION_BYTE; + break; + + case ACTION_WRITETHENWRITEREAD: + cmd[0] = funcToTest[0] = + CMD_WRITETHENWRITEREAD_BYTE; + break; + + case ACTION_WRITEU8UX: + cmd[0] = funcToTest[0] = CMD_WRITEU8UX_BYTE; + break; + + case ACTION_WRITEREADU8UX: + cmd[0] = funcToTest[0] = CMD_WRITEREADU8UX_BYTE; + break; + + case ACTION_WRITEU8UXTHENWRITEU8UX: + cmd[0] = funcToTest[0] = + CMD_WRITEU8UXTHENWRITEU8UX_BYTE; + break; + + case ACTION_WRITEU8XTHENWRITEREADU8UX: + cmd[0] = funcToTest[0] = + CMD_WRITEU8UXTHENWRITEREADU8UX_BYTE; + break; + + case ACTION_GET_FW: + cmd[0] = funcToTest[0] = CMD_GETFWFILE_BYTE; + break; + + case ACTION_GET_LIMIT: + cmd[0] = funcToTest[0] = CMD_GETLIMITSFILE_BYTE; + break; + + default: + logError( + 1, + "%s Invalid Action = %d ... ERROR %08X\n", + tag, mess.action, ERROR_OP_NOT_ALLOW); + res = ERROR_OP_NOT_ALLOW; + goto END; + } + + if (numberParam - 1 != 0) + memcpy(&cmd[1], &p[7], numberParam - 1); + } + } else { + if (((count + 1) / 3) >= 1) { + sscanf(p, "%02X ", &funcToTest[0]); + p += 3; + cmd[0] = (u8)funcToTest[0]; + numberParam = 1; + } else { + res = ERROR_OP_NOT_ALLOW; + goto END; + } + + logError(1, "%s functionToTest[0] = %02X cmd[0]= %02X\n", tag, + funcToTest[0], cmd[0]); + switch (funcToTest[0]) { + case CMD_GETFWFILE: + case CMD_GETLIMITSFILE: + if (count - 2 - 1 > 1) { + numberParam = 2; + sscanf(p, "%100s", path); + } + break; + + default: + for (; numberParam < (count + 1) / 3; numberParam++) { + sscanf(p, "%02X ", &funcToTest[numberParam]); + p += 3; + cmd[numberParam] = (u8)funcToTest[numberParam]; + logError( + 1, + "%s functionToTest[%d] = %02X cmd[%d]= %02X\n", + tag, numberParam, + funcToTest[numberParam], numberParam, + cmd[numberParam]); + } + } + } + + fw.data = NULL; + lim.data = NULL; + + logError(1, "%s Number of Parameters = %d \n", tag, numberParam); + + if (numberParam >= 1) { + switch (funcToTest[0]) { + case CMD_VERSION_BYTE: + logError(0, "%s %s: Get Version Byte \n", tag, __func__, + res); + byteToRead = 2; + mess.dummy = 0; + readData = (u8 *)kmalloc(byteToRead * sizeof(u8), + GFP_KERNEL); + size += byteToRead; + if (readData != NULL) { + readData[0] = (u8)(FTS_TS_DRV_VER >> 24); + readData[1] = (u8)(FTS_TS_DRV_VER >> 16); + res = OK; + logError(0, "%s %s: Version = %02X%02X \n", tag, + __func__, readData[0], readData[1]); + } else { + res = ERROR_ALLOC; + logError( + 1, + "%s %s: Impossible allocate memory... ERROR %08X \n", + tag, __func__, res); + } + break; + + case CMD_VERSION: + byteToRead = 2 * sizeof(u32); + mess.dummy = 0; + readData = (u8 *)kmalloc(byteToRead * sizeof(u8), + GFP_KERNEL); + u32ToU8_be(FTS_TS_DRV_VER, readData); + fileSize = 0; +#ifdef FW_H_FILE + fileSize |= 0x00010000; +#endif + +#ifdef LIMITS_H_FILE + fileSize |= 0x00020000; +#endif + +#ifdef USE_ONE_FILE_NODE + fileSize |= 0x00040000; +#endif + +#ifdef FW_UPDATE_ON_PROBE + fileSize |= 0x00080000; +#endif + +#ifdef PRE_SAVED_METHOD + fileSize |= 0x00100000; +#endif + +#ifdef USE_GESTURE_MASK + fileSize |= 0x00100000; +#endif + +#ifdef I2C_INTERFACE + fileSize |= 0x00200000; +#endif + +#ifdef PHONE_KEY + fileSize |= 0x00000100; +#endif + +#ifdef GESTURE_MODE + fromIDtoMask(FEAT_SEL_GESTURE, (u8 *)&fileSize, 4); +#endif + +#ifdef GRIP_MODE + fromIDtoMask(FEAT_SEL_GRIP, (u8 *)&fileSize, 4); +#endif + +#ifdef CHARGER_MODE + fromIDtoMask(FEAT_SEL_CHARGER, (u8 *)&fileSize, 4); +#endif + +#ifdef GLOVE_MODE + fromIDtoMask(FEAT_SEL_GLOVE, (u8 *)&fileSize, 4); +#endif + +#ifdef COVER_MODE + fromIDtoMask(FEAT_SEL_COVER, (u8 *)&fileSize, 4); +#endif + +#ifdef STYLUS_MODE + fromIDtoMask(FEAT_SEL_STYLUS, (u8 *)&fileSize, 4); +#endif + + u32ToU8_be(fileSize, &readData[4]); + res = OK; + size += (byteToRead * sizeof(u8)); + break; + + case CMD_WRITEREAD: + case CMD_WRITEREAD_BYTE: + if (numberParam >= 5) { + temp = numberParam - 4; + if (cmd[numberParam - 1] == 0) { + mess.dummy = 0; + } else + mess.dummy = 1; + + u8ToU16_be(&cmd[numberParam - 3], &byteToRead); + logError(0, "%s bytesToRead = %d \n", tag, + byteToRead + mess.dummy); + + readData = (u8 *)kmalloc( + (byteToRead + mess.dummy) * sizeof(u8), + GFP_KERNEL); + res = fts_writeRead_dma_safe( + &cmd[1], temp, readData, + byteToRead + mess.dummy); + size += (byteToRead * sizeof(u8)); + + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_WRITE: + case CMD_WRITE_BYTE: + if (numberParam >= 2) { + temp = numberParam - 1; + res = fts_write_dma_safe(&cmd[1], temp); + + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_READ: + case CMD_READ_BYTE: + if (numberParam >= 3) { + if (numberParam == 3 || + (numberParam == 4 && + cmd[numberParam - 1] == 0)) { + mess.dummy = 0; + } else + mess.dummy = 1; + u8ToU16_be(&cmd[1], &byteToRead); + readData = (u8 *)kmalloc( + (byteToRead + mess.dummy) * sizeof(u8), + GFP_KERNEL); + res = fts_read_dma_safe( + readData, byteToRead + mess.dummy); + size += (byteToRead * sizeof(u8)); + + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_WRITETHENWRITEREAD: + case CMD_WRITETHENWRITEREAD_BYTE: + if (numberParam >= 6) { + u8ToU16_be(&cmd[numberParam - 2], &byteToRead); + readData = (u8 *)kmalloc( + byteToRead * sizeof(u8), GFP_KERNEL); + res = fts_writeThenWriteRead( + &cmd[3], cmd[1], &cmd[3 + (int)cmd[1]], + cmd[2], readData, byteToRead); + size += (byteToRead * sizeof(u8)); + + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_WRITEU8UX: + case CMD_WRITEU8UX_BYTE: + if (numberParam >= 4) { + if (cmd[2] <= sizeof(u64)) { + u8ToU64_be(&cmd[3], &addr, cmd[2]); + logError(0, "%s addr = %016X %ld \n", + tag, addr, addr); + res = fts_writeU8UX( + cmd[1], cmd[2], addr, + &cmd[3 + cmd[2]], + (numberParam - cmd[2] - 3)); + } else { + logError(1, "%s Wrong address size!\n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_WRITEREADU8UX: + case CMD_WRITEREADU8UX_BYTE: + if (numberParam >= 6) { + if (cmd[2] <= sizeof(u64)) { + u8ToU64_be(&cmd[3], &addr, cmd[2]); + u8ToU16_be(&cmd[numberParam - 3], + &byteToRead); + readData = (u8 *)kmalloc( + byteToRead * sizeof(u8), + GFP_KERNEL); + logError( + 0, + "%s addr = %016X byteToRead = %d \n", + tag, addr, byteToRead); + res = fts_writeReadU8UX( + cmd[1], cmd[2], addr, readData, + byteToRead, + cmd[numberParam - 1]); + size += (byteToRead * sizeof(u8)); + + } else { + logError(1, "%s Wrong address size!\n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_WRITEU8UXTHENWRITEU8UX: + case CMD_WRITEU8UXTHENWRITEU8UX_BYTE: + if (numberParam >= 6) { + if ((cmd[2] + cmd[4]) <= sizeof(u64)) { + u8ToU64_be(&cmd[5], &addr, + cmd[2] + cmd[4]); + logError(0, "%s addr = %016X %ld \n", + tag, addr, addr); + res = fts_writeU8UXthenWriteU8UX( + cmd[1], cmd[2], cmd[3], cmd[4], + addr, &cmd[5 + cmd[2] + cmd[4]], + (numberParam - cmd[2] - cmd[4] - + 5)); + } else { + logError(1, "%s Wrong address size! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_WRITEU8UXTHENWRITEREADU8UX: + case CMD_WRITEU8UXTHENWRITEREADU8UX_BYTE: + if (numberParam >= 8) { + if ((cmd[2] + cmd[4]) <= sizeof(u64)) { + u8ToU64_be(&cmd[5], &addr, + cmd[2] + cmd[4]); + logError( + 1, + "%s %s: cmd[5] = %02X, addr = %016X \n", + tag, __func__, cmd[5], addr); + u8ToU16_be(&cmd[numberParam - 3], + &byteToRead); + readData = (u8 *)kmalloc( + byteToRead * sizeof(u8), + GFP_KERNEL); + res = fts_writeU8UXthenWriteReadU8UX( + cmd[1], cmd[2], cmd[3], cmd[4], + addr, readData, byteToRead, + cmd[numberParam - 1]); + size += (byteToRead * sizeof(u8)); + } else { + logError( + 1, + "%s Wrong total address size! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + + break; + + case CMD_CHANGE_OUTPUT_MODE: + if (numberParam >= 2) { + bin_output = cmd[1]; + logError( + 0, + "%s Setting Scriptless output mode: %d \n", + tag, bin_output); + res = OK; + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_FWWRITE: + if (numberParam >= 3) { + if (numberParam >= 2) { + temp = numberParam - 1; + res = fts_writeFwCmd(&cmd[1], temp); + } else { + logError(1, "%s Wrong parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_INTERRUPT: + if (numberParam >= 2) { + if (cmd[1] == 1) + res = fts_enableInterrupt(); + else + res = fts_disableInterrupt(); + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_READCONFIG: + if (numberParam == 5) { + byteToRead = + ((funcToTest[3] << 8) | funcToTest[4]); + readData = (u8 *)kmalloc( + byteToRead * sizeof(u8), GFP_KERNEL); + res = readConfig( + (u16)((((u8)funcToTest[1] & 0x00FF) + << 8) + + ((u8)funcToTest[2] & 0x00FF)), + readData, byteToRead); + size += (byteToRead * sizeof(u8)); + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_POLLFOREVENT: + if (numberParam >= 5) { + temp = (int)funcToTest[1]; + if (numberParam == 5 + (temp - 1) && + temp != 0) { + readData = (u8 *)kmalloc( + FIFO_EVENT_SIZE * sizeof(u8), + GFP_KERNEL); + res = pollForEvent( + (int *)&funcToTest[2], temp, + readData, + ((funcToTest[temp + 2] & 0x00FF) + << 8) + (funcToTest[temp + 3] & + 0x00FF)); + if (res >= OK) + res = OK; + size += (FIFO_EVENT_SIZE * sizeof(u8)); + byteToRead = FIFO_EVENT_SIZE; + } else { + logError(1, "%s Wrong parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_SYSTEMRESET: + res = fts_system_reset(); + + break; + + case CMD_READSYSINFO: + if (numberParam == 2) { + res = readSysInfo(funcToTest[1]); + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + + break; + + case CMD_CLEANUP: + if (numberParam == 2) { + res = cleanUp(funcToTest[1]); + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + + break; + + case CMD_GETFORCELEN: + temp = getForceLen(); + if (temp < OK) + res = temp; + else { + size += (1 * sizeof(u8)); + res = OK; + } + break; + + case CMD_GETSENSELEN: + temp = getSenseLen(); + if (temp < OK) + res = temp; + else { + size += (1 * sizeof(u8)); + res = OK; + } + break; + + case CMD_GETMSFRAME: + if (numberParam == 2) { + logError(0, "%s Get 1 MS Frame \n", tag); + setScanMode(SCAN_MODE_ACTIVE, 0x01); + mdelay(WAIT_FOR_FRESH_FRAMES); + setScanMode(SCAN_MODE_ACTIVE, 0x00); + mdelay(WAIT_AFTER_SENSEOFF); + flushFIFO(); + res = getMSFrame3((MSFrameType)cmd[1], + &frameMS); + if (res < 0) { + logError( + 0, + "%s Error while taking the MS frame... ERROR %08X \n", + tag, res); + + } else { + logError( + 0, + "%s The frame size is %d words\n", + tag, res); + size += (res * sizeof(short) + 2); + /* set res to OK because if getMSFrame is + successful res = number of words read + */ + res = OK; + print_frame_short( + "MS frame =", + array1dTo2d_short( + frameMS.node_data, + frameMS.node_data_size, + frameMS.header + .sense_node), + frameMS.header.force_node, + frameMS.header.sense_node); + } + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + /*read self raw */ + case CMD_GETSSFRAME: + if (numberParam == 2) { + logError(0, "%s Get 1 SS Frame \n", tag); + flushFIFO(); + setScanMode(SCAN_MODE_ACTIVE, 0x01); + mdelay(WAIT_FOR_FRESH_FRAMES); + setScanMode(SCAN_MODE_ACTIVE, 0x00); + mdelay(WAIT_AFTER_SENSEOFF); + res = getSSFrame3((SSFrameType)cmd[1], + &frameSS); + + if (res < OK) { + logError( + 0, + "%s Error while taking the SS frame... ERROR %08X \n", + tag, res); + + } else { + logError( + 0, + "%s The frame size is %d words\n", + tag, res); + size += (res * sizeof(short) + 2); + /* set res to OK because if getMSFrame is + successful res = number of words read + */ + res = OK; + print_frame_short( + "SS force frame =", + array1dTo2d_short( + frameSS.force_data, + frameSS.header + .force_node, + 1), + frameSS.header.force_node, 1); + print_frame_short( + "SS sense frame =", + array1dTo2d_short( + frameSS.sense_data, + frameSS.header + .sense_node, + frameSS.header + .sense_node), + 1, frameSS.header.sense_node); + } + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_REQCOMPDATA: + if (numberParam == 2) { + logError(0, + "%s Requesting Compensation Data \n", + tag); + res = requestCompensationData(cmd[1]); + + if (res < OK) { + logError( + 0, + "%s Error requesting compensation data ERROR %08X \n", + tag, res); + } else { + logError( + 0, + "%s Requesting Compensation Data Finished! \n", + tag); + } + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_READCOMPDATAHEAD: + if (numberParam == 2) { + logError(0, + "%s Requesting Compensation Data \n", + tag); + res = requestCompensationData(cmd[1]); + if (res < OK) { + logError( + 0, + "%s Error requesting compensation data ERROR %08X \n", + tag, res); + } else { + logError( + 0, + "%s Requesting Compensation Data Finished! \n", + tag); + res = readCompensationDataHeader( + (u8)funcToTest[1], &dataHead, + &address); + if (res < OK) { + logError( + 0, + "%s Read Compensation Data Header ERROR %08X\n", + tag, res); + } else { + logError( + 0, + "%s Read Compensation Data Header OK!\n", + tag); + size += (1 * sizeof(u8)); + } + } + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_READMSCOMPDATA: + if (numberParam == 2) { + logError(0, "%s Get MS Compensation Data \n", + tag); + res = readMutualSenseCompensationData( + cmd[1], &compData); + + if (res < OK) { + logError( + 0, + "%s Error reading MS compensation data ERROR %08X \n", + tag, res); + } else { + logError( + 0, + "%s MS Compensation Data Reading Finished! \n", + tag); + size = ((compData.node_data_size + 10) * + sizeof(i8)); + print_frame_i8( + "MS Data (Cx2) =", + array1dTo2d_i8( + compData.node_data, + compData.node_data_size, + compData.header + .sense_node), + compData.header.force_node, + compData.header.sense_node); + } + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_READSSCOMPDATA: + if (numberParam == 2) { + logError(0, "%s Get SS Compensation Data... \n", + tag); + res = readSelfSenseCompensationData(cmd[1], + &comData); + if (res < OK) { + logError( + 0, + "%s Error reading SS compensation data ERROR %08X\n", + tag, res); + } else { + logError( + 0, + "%s SS Compensation Data Reading Finished! \n", + tag); + size = ((comData.header.force_node + + comData.header.sense_node) * + 2 + + 13) * + sizeof(i8); + print_frame_i8( + "SS Data Ix2_fm = ", + array1dTo2d_i8( + comData.ix2_fm, + comData.header + .force_node, + comData.header + .force_node), + 1, comData.header.force_node); + print_frame_i8( + "SS Data Cx2_fm = ", + array1dTo2d_i8( + comData.cx2_fm, + comData.header + .force_node, + comData.header + .force_node), + 1, comData.header.force_node); + print_frame_i8( + "SS Data Ix2_sn = ", + array1dTo2d_i8( + comData.ix2_sn, + comData.header + .sense_node, + comData.header + .sense_node), + 1, comData.header.sense_node); + print_frame_i8( + "SS Data Cx2_sn = ", + array1dTo2d_i8( + comData.cx2_sn, + comData.header + .sense_node, + comData.header + .sense_node), + 1, comData.header.sense_node); + } + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_READTOTMSCOMPDATA: + if (numberParam == 2) { + logError(0, + "%s Get TOT MS Compensation Data \n", + tag); + res = readTotMutualSenseCompensationData( + cmd[1], &totCompData); + + if (res < OK) { + logError( + 0, + "%s Error reading TOT MS compensation data ERROR %08X \n", + tag, res); + } else { + logError( + 0, + "%s TOT MS Compensation Data Reading Finished! \n", + tag); + size = (totCompData.node_data_size * + sizeof(short) + + 9); + print_frame_short( + "MS Data (TOT Cx) =", + array1dTo2d_short( + totCompData.node_data, + totCompData + .node_data_size, + totCompData.header + .sense_node), + totCompData.header.force_node, + totCompData.header.sense_node); + } + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_READTOTSSCOMPDATA: + if (numberParam == 2) { + logError( + 0, + "%s Get TOT SS Compensation Data... \n", + tag); + res = readTotSelfSenseCompensationData( + cmd[1], &totComData); + if (res < OK) { + logError( + 0, + "%s Error reading TOT SS compensation data ERROR %08X\n", + tag, res); + } else { + logError( + 0, + "%s TOT SS Compensation Data Reading Finished! \n", + tag); + size = ((totComData.header.force_node + + totComData.header.sense_node) * + 2 * sizeof(short) + + 9); + print_frame_u16( + "SS Data TOT Ix_fm = ", + array1dTo2d_u16( + totComData.ix_fm, + totComData.header + .force_node, + totComData.header + .force_node), + 1, + totComData.header.force_node); + print_frame_short( + "SS Data TOT Cx_fm = ", + array1dTo2d_short( + totComData.cx_fm, + totComData.header + .force_node, + totComData.header + .force_node), + 1, + totComData.header.force_node); + print_frame_u16( + "SS Data TOT Ix_sn = ", + array1dTo2d_u16( + totComData.ix_sn, + totComData.header + .sense_node, + totComData.header + .sense_node), + 1, + totComData.header.sense_node); + print_frame_short( + "SS Data TOT Cx_sn = ", + array1dTo2d_short( + totComData.cx_sn, + totComData.header + .sense_node, + totComData.header + .sense_node), + 1, + totComData.header.sense_node); + } + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_GETFWVER: + res = getFirmwareVersion(&fw_version, &config_id); + if (res < OK) { + logError( + 1, + "%s Error reading firmware version and config id ERROR %02X\n", + tag, res); + } else { + logError(0, + "%s getFirmwareVersion Finished! \n", + tag); + size += (4) * sizeof(u8); + } + break; + + case CMD_FLASHUNLOCK: + res = flash_unlock(); + if (res < OK) { + logError( + 1, + "%s Impossible Unlock Flash ERROR %08X\n", + tag, res); + } else { + logError(0, "%s Flash Unlock OK!\n", tag); + } + break; + + case CMD_READFWFILE: + if (numberParam == 2) { + logError(0, "%s Reading FW File... \n", tag); + res = readFwFile(PATH_FILE_FW, &fw, + funcToTest[1]); + if (res < OK) { + logError( + 0, + "%s Error reading FW File ERROR %08X\n", + tag, res); + } else { + logError(0, + "%s Read FW File Finished! \n", + tag); + } + kfree(fw.data); + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_FLASHPROCEDURE: + if (numberParam == 3) { + logError(0, + "%s Starting Flashing Procedure... \n", + tag); + res = flashProcedure(PATH_FILE_FW, cmd[1], + cmd[2]); + if (res < OK) { + logError( + 0, + "%s Error during flash procedure ERROR %08X\n", + tag, res); + } else { + logError( + 0, + "%s Flash Procedure Finished! \n", + tag); + } + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_FLASHERASEUNLOCK: + res = flash_erase_unlock(); + if (res < OK) { + logError( + 0, + "%s Error during flash erase unlock... ERROR %08X\n", + tag, res); + } else { + logError(0, + "%s Flash Erase Unlock Finished! \n", + tag); + } + break; + + case CMD_FLASHERASEPAGE: + if (numberParam == 2) { + logError( + 0, + "%s Starting Flashing Page Erase... \n", + tag); + res = flash_erase_page_by_page(cmd[1]); + if (res < OK) { + logError( + 0, + "%s Error during flash page erase... ERROR %08X\n", + tag, res); + } else { + logError( + 0, + "%s Flash Page Erase Finished! \n", + tag); + } + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + /*ITO TEST */ + case CMD_ITOTEST: + res = production_test_ito(LIMITS_FILE, &tests); + break; + + /*Initialization */ + case CMD_INITTEST: + if (numberParam == 2) { + res = production_test_initialization(cmd[1]); + + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_MSRAWTEST: + if (numberParam == 2) + res = production_test_ms_raw(LIMITS_FILE, + cmd[1], &tests); + else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_MSINITDATATEST: + if (numberParam == 2) + res = production_test_ms_cx(LIMITS_FILE, cmd[1], + &tests); + else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_SSRAWTEST: + if (numberParam == 2) + res = production_test_ss_raw(LIMITS_FILE, + cmd[1], &tests); + else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_SSINITDATATEST: + if (numberParam == 2) + res = production_test_ss_ix_cx(LIMITS_FILE, + cmd[1], &tests); + else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + /*PRODUCTION TEST */ + case CMD_MAINTEST: + if (numberParam == 3) + res = production_test_main(LIMITS_FILE, cmd[1], + cmd[2], &tests); + else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_FREELIMIT: + res = freeCurrentLimitsFile(); + break; + + case CMD_POWERCYCLE: + res = fts_chip_powercycle(info); + break; + + case CMD_GETLIMITSFILE: + if (numberParam >= 1) { + lim.data = NULL; + lim.size = 0; + if (numberParam == 1) + res = getLimitsFile(LIMITS_FILE, &lim); + else + res = getLimitsFile(path, &lim); + readData = lim.data; + fileSize = lim.size; + size += (fileSize * sizeof(u8)); + if (byte_call == 1) + size += sizeof(u32); + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_GETLIMITSFILE_BYTE: + if (numberParam >= 3) { + lim.data = NULL; + lim.size = 0; + + u8ToU16_be(&cmd[1], &byteToRead); + addr = ((u64)byteToRead) * 4; + + res = getLimitsFile(LIMITS_FILE, &lim); + + readData = lim.data; + fileSize = lim.size; + + if (fileSize > addr) { + logError( + 1, + "%s Limits dimension expected by Host is less than actual size: expected = %d, real = %d \n", + tag, byteToRead, fileSize); + res = ERROR_OP_NOT_ALLOW; + } + + size += (addr * sizeof(u8)); + + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_GETFWFILE: + if (numberParam >= 1) { + if (numberParam == 1) + res = getFWdata(PATH_FILE_FW, &readData, + &fileSize); + else + res = getFWdata(path, &readData, + &fileSize); + + size += (fileSize * sizeof(u8)); + if (byte_call == 1) + size += sizeof(u32); + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + + case CMD_GETFWFILE_BYTE: + if (numberParam == 3) { + u8ToU16_be(&cmd[1], &byteToRead); + addr = ((u64)byteToRead) * 4; + + res = getFWdata(PATH_FILE_FW, &readData, + &fileSize); + if (fileSize > addr) { + logError( + 1, + "%s FW dimension expected by Host is less than actual size: expected = %d, real = %d \n", + tag, byteToRead, fileSize); + res = ERROR_OP_NOT_ALLOW; + } + + size += (addr * sizeof(u8)); + + } else { + logError(1, "%s Wrong number of parameters! \n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + break; + /* +* finish all the diagnostic command with a goto ERROR in order to skip the modification on driver_test_buff +* remember to set properly the limit and printed variables in order to make the seq_file logic to work +*/ + case CMD_DIAGNOSTIC: + index = 0; + size = 0; + fileSize = 256 * 1024 * sizeof(char); + driver_test_buff = (u8 *)kzalloc(fileSize, GFP_KERNEL); + readData = (u8 *)kmalloc( + (ERROR_DUMP_ROW_SIZE * ERROR_DUMP_COL_SIZE) * + sizeof(u8), + GFP_KERNEL); + if (driver_test_buff == NULL || readData == NULL) { + res = ERROR_ALLOC; + logError( + 1, + "%s Impossible allocate memory for buffers! ERROR %08X! \n", + tag, res); + goto END; + } + j = snprintf(&driver_test_buff[index], fileSize - index, + "DIAGNOSTIC TEST:\n1) I2C Test: "); + index += j; + + res = fts_writeReadU8UX(FTS_CMD_HW_REG_R, + ADDR_SIZE_HW_REG, ADDR_DCHIP_ID, + (u8 *)&temp, 2, DUMMY_HW_REG); + if (res < OK) { + logError( + 1, + "%s Error during I2C test: ERROR %08X! \n", + tag, res); + j = snprintf(&driver_test_buff[index], + fileSize - index, "ERROR %08X \n", + res); + index += j; + res = ERROR_OP_NOT_ALLOW; + goto END_DIAGNOSTIC; + } + + temp &= 0xFFFF; + logError(1, "%s Chip ID = %04X! \n", tag, temp); + j = snprintf(&driver_test_buff[index], fileSize - index, + "DATA = %04X, expected = %02X%02X \n", + temp, DCHIP_ID_1, DCHIP_ID_0); + index += j; + if (temp != ((DCHIP_ID_1 << 8) | DCHIP_ID_0)) { + logError( + 1, + "%s Wrong CHIP ID, Diagnostic failed! \n", + tag, res); + res = ERROR_OP_NOT_ALLOW; + goto END_DIAGNOSTIC; + } + + j = snprintf(&driver_test_buff[index], fileSize - index, + "Present Driver Mode: %08X \n", + info->mode); + index += j; + + j = snprintf(&driver_test_buff[index], fileSize - index, + "2) FW running: Sensing On..."); + index += j; + logError(1, "%s Sensing On! \n", tag, temp); + readData[0] = FTS_CMD_SCAN_MODE; + readData[1] = SCAN_MODE_ACTIVE; + readData[2] = 0x1; + fts_write(readData, 3); + res = checkEcho(readData, 3); + if (res < OK) { + logError(1, + "%s No Echo received.. ERROR %08X !\n", + tag, res); + j = snprintf(&driver_test_buff[index], + fileSize - index, + "No echo found... ERROR %08X!\n", + res); + index += j; + goto END_DIAGNOSTIC; + } else { + logError(1, "%s Echo FOUND... OK!\n", tag, res); + j = snprintf(&driver_test_buff[index], + fileSize - index, + "Echo FOUND... OK!\n"); + index += j; + } + + logError(1, "%s Reading Frames...! \n", tag, temp); + j = snprintf(&driver_test_buff[index], fileSize - index, + "3) Read Frames: \n"); + index += j; + for (temp = 0; temp < DIAGNOSTIC_NUM_FRAME; temp++) { + logError(1, "%s Iteration n. %d...\n", tag, + temp + 1); + j = snprintf(&driver_test_buff[index], + fileSize - index, + "Iteration n. %d...\n", temp + 1); + index += j; + for (addr = 0; addr < 3; addr++) { + switch (addr) { + case 0: + j = snprintf( + &driver_test_buff[index], + fileSize - index, + "MS RAW FRAME ="); + index += j; + res |= getMSFrame3(MS_RAW, + &frameMS); + break; + case 2: + j = snprintf( + &driver_test_buff[index], + fileSize - index, + "MS STRENGTH FRAME ="); + index += j; + res |= getMSFrame3(MS_STRENGTH, + &frameMS); + break; + case 1: + j = snprintf( + &driver_test_buff[index], + fileSize - index, + "MS BASELINE FRAME ="); + index += j; + res |= getMSFrame3(MS_BASELINE, + &frameMS); + break; + } + if (res < OK) { + j = snprintf( + &driver_test_buff[index], + fileSize - index, + "No data! ERROR %08X \n", + res); + index += j; + } else { + for (address = 0; + address < + frameMS.node_data_size; + address++) { + if (address % + frameMS.header + .sense_node == + 0) { + j = snprintf( + &driver_test_buff + [index], + fileSize - + index, + "\n"); + index += j; + } + j = snprintf( + &driver_test_buff + [index], + fileSize - + index, + "%5d, ", + frameMS.node_data + [address]); + index += j; + } + j = snprintf( + &driver_test_buff[index], + fileSize - index, "\n"); + index += j; + } + if (frameMS.node_data != NULL) + kfree(frameMS.node_data); + } + for (addr = 0; addr < 3; addr++) { + switch (addr) { + case 0: + j = snprintf( + &driver_test_buff[index], + fileSize - index, + "SS RAW FRAME = \n"); + index += j; + res |= getSSFrame3(SS_RAW, + &frameSS); + break; + case 2: + j = snprintf( + &driver_test_buff[index], + fileSize - index, + "SS STRENGTH FRAME = \n"); + index += j; + res |= getSSFrame3(SS_STRENGTH, + &frameSS); + break; + case 1: + j = snprintf( + &driver_test_buff[index], + fileSize - index, + "SS BASELINE FRAME = \n"); + index += j; + res |= getSSFrame3(SS_BASELINE, + &frameSS); + break; + } + if (res < OK) { + j = snprintf( + &driver_test_buff[index], + fileSize - index, + "No data! ERROR %08X \n", + res); + index += j; + } else { + for (address = 0; + address < + frameSS.header.force_node; + address++) { + j = snprintf( + &driver_test_buff + [index], + fileSize - + index, + "%d\n", + frameSS.force_data + [address]); + + index += j; + } + for (address = 0; + address < + frameSS.header.sense_node; + address++) { + j = snprintf( + &driver_test_buff + [index], + fileSize - + index, + "%d, ", + frameSS.sense_data + [address]); + + index += j; + } + j = snprintf( + &driver_test_buff[index], + fileSize - index, "\n"); + index += j; + } + if (frameSS.force_data != NULL) + kfree(frameSS.force_data); + if (frameSS.sense_data != NULL) + kfree(frameSS.sense_data); + } + } + + logError(1, "%s Reading error info... \n", tag, temp); + j = snprintf(&driver_test_buff[index], fileSize - index, + "4) FW INFO DUMP: "); + index += j; + temp = dumpErrorInfo(readData, + ERROR_DUMP_ROW_SIZE * + ERROR_DUMP_COL_SIZE); + if (temp < OK) { + logError(1, + "%s Error during dump: ERROR %08X! \n", + tag, res); + j = snprintf(&driver_test_buff[index], + fileSize - index, "ERROR %08X \n", + temp); + index += j; + } else { + logError(1, "%s DUMP OK! \n", tag, res); + for (temp = 0; + temp < + ERROR_DUMP_ROW_SIZE * ERROR_DUMP_COL_SIZE; + temp++) { + if (temp % ERROR_DUMP_COL_SIZE == 0) { + j = snprintf( + &driver_test_buff[index], + fileSize - index, + "\n%2d - ", + temp / ERROR_DUMP_COL_SIZE); + index += j; + } + j = snprintf(&driver_test_buff[index], + fileSize - index, "%02X ", + readData[temp]); + index += j; + } + } + res |= temp; + +END_DIAGNOSTIC: + if (res < OK) { + j = snprintf(&driver_test_buff[index], + fileSize - index, + "\nRESULT = FAIL \n"); + index += j; + } else { + j = snprintf(&driver_test_buff[index], + fileSize - index, + "\nRESULT = FINISHED \n"); + index += j; + } + limit = index; + printed = 0; + goto ERROR; + break; + case CMD_CHANGE_SAD: + res = changeSAD(cmd[1]); + break; + + default: + logError(1, "%s COMMAND ID NOT VALID!!! \n", tag); + res = ERROR_OP_NOT_ALLOW; + break; + } + + } else { + logError( + 1, + "%s NO COMMAND SPECIFIED!!! do: 'echo [cmd_code] [args] > stm_fts_cmd' before looking for result!\n", + tag); + res = ERROR_OP_NOT_ALLOW; + } + +END: + if (driver_test_buff != NULL) { + logError( + 1, + "%s Consecutive echo on the file node, free the buffer with the previous result\n", + tag); + kfree(driver_test_buff); + } + + if (byte_call == 0) { + size *= 2; + size += 2; + } else { + if (bin_output != 1) { + size *= 2; + size -= 1; + } else + size += 1; + } + + logError(0, "%s Size = %d\n", tag, size); + driver_test_buff = (u8 *)kzalloc(size, GFP_KERNEL); + logError(0, "%s Finish to allocate memory! \n", tag); + if (driver_test_buff == NULL) { + logError(0, + "%s Unable to allocate driver_test_buff! ERROR %08X\n", + tag, ERROR_ALLOC); + goto ERROR; + } + + if (byte_call == 0) { + index = 0; + snprintf(&driver_test_buff[index], 3, "{ "); + index += 2; + snprintf(&driver_test_buff[index], 9, "%08X", res); + + index += 8; + if (res >= OK) { + /*all the other cases are already fine printing only the res. */ + switch (funcToTest[0]) { + case CMD_VERSION: + case CMD_READ: + case CMD_WRITEREAD: + case CMD_WRITETHENWRITEREAD: + case CMD_WRITEREADU8UX: + case CMD_WRITEU8UXTHENWRITEREADU8UX: + case CMD_READCONFIG: + case CMD_POLLFOREVENT: + if (mess.dummy == 1) + j = 1; + else + j = 0; + for (; j < byteToRead + mess.dummy; j++) { + snprintf(&driver_test_buff[index], 3, + "%02X", readData[j]); + index += 2; + } + break; + case CMD_GETFWFILE: + case CMD_GETLIMITSFILE: + logError(0, "%s Start To parse! \n", tag); + for (j = 0; j < fileSize; j++) { + snprintf(&driver_test_buff[index], 3, + "%02X", readData[j]); + index += 2; + } + logError(0, "%s Finish to parse! \n", tag); + break; + case CMD_GETFORCELEN: + case CMD_GETSENSELEN: + snprintf(&driver_test_buff[index], 3, "%02X", + (u8)temp); + index += 2; + + break; + + case CMD_GETMSFRAME: + snprintf(&driver_test_buff[index], 3, "%02X", + (u8)frameMS.header.force_node); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + (u8)frameMS.header.sense_node); + index += 2; + + for (j = 0; j < frameMS.node_data_size; j++) { + snprintf(&driver_test_buff[index], 5, + "%02X%02X", + (frameMS.node_data[j] & + 0xFF00) >> + 8, + frameMS.node_data[j] & 0xFF); + index += 4; + } + + kfree(frameMS.node_data); + break; + + case CMD_GETSSFRAME: + snprintf(&driver_test_buff[index], 3, "%02X", + (u8)frameSS.header.force_node); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + (u8)frameSS.header.sense_node); + index += 2; + for (j = 0; j < frameSS.header.force_node; + j++) { + snprintf(&driver_test_buff[index], 5, + "%02X%02X", + (frameSS.force_data[j] & + 0xFF00) >> + 8, + frameSS.force_data[j] & 0xFF); + index += 4; + } + + for (j = 0; j < frameSS.header.sense_node; + j++) { + snprintf(&driver_test_buff[index], 5, + "%02X%02X", + (frameSS.sense_data[j] & + 0xFF00) >> + 8, + frameSS.sense_data[j] & 0xFF); + index += 4; + } + + kfree(frameSS.force_data); + kfree(frameSS.sense_data); + break; + + case CMD_READMSCOMPDATA: + snprintf(&driver_test_buff[index], 3, "%02X", + (u8)compData.header.type); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + (u8)compData.header.force_node); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + (u8)compData.header.sense_node); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + compData.cx1 & 0xFF); + index += 2; + + for (j = 0; j < compData.node_data_size; j++) { + snprintf(&driver_test_buff[index], 3, + "%02X", + compData.node_data[j] & 0xFF); + index += 2; + } + + kfree(compData.node_data); + break; + + case CMD_READSSCOMPDATA: + snprintf(&driver_test_buff[index], 3, "%02X", + (u8)comData.header.type); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + comData.header.force_node); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + comData.header.sense_node); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + comData.f_ix1 & 0xFF); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + comData.s_ix1 & 0xFF); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + comData.f_cx1 & 0xFF); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + comData.s_cx1 & 0xFF); + index += 2; + + for (j = 0; j < comData.header.force_node; + j++) { + snprintf(&driver_test_buff[index], 3, + "%02X", + comData.ix2_fm[j] & 0xFF); + index += 2; + } + + for (j = 0; j < comData.header.sense_node; + j++) { + snprintf(&driver_test_buff[index], 3, + "%02X", + comData.ix2_sn[j] & 0xFF); + index += 2; + } + + for (j = 0; j < comData.header.force_node; + j++) { + snprintf(&driver_test_buff[index], 3, + "%02X", + comData.cx2_fm[j] & 0xFF); + + index += 2; + } + + for (j = 0; j < comData.header.sense_node; + j++) { + snprintf(&driver_test_buff[index], 3, + "%02X", + comData.cx2_sn[j] & 0xFF); + index += 2; + } + + kfree(comData.ix2_fm); + kfree(comData.ix2_sn); + kfree(comData.cx2_fm); + kfree(comData.cx2_sn); + break; + + case CMD_READTOTMSCOMPDATA: + snprintf(&driver_test_buff[index], 3, "%02X", + (u8)totCompData.header.type); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + (u8)totCompData.header.force_node); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + (u8)totCompData.header.sense_node); + + index += 2; + + for (j = 0; j < totCompData.node_data_size; + j++) { + snprintf(&driver_test_buff[index], 5, + "%02X%02X", + (totCompData.node_data[j] & + 0xFF00) >> + 8, + totCompData.node_data[j] & + 0xFF); + index += 4; + } + + kfree(totCompData.node_data); + break; + + case CMD_READTOTSSCOMPDATA: + snprintf(&driver_test_buff[index], 3, "%02X", + (u8)totComData.header.type); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + totComData.header.force_node); + index += 2; + + snprintf(&driver_test_buff[index], 3, "%02X", + totComData.header.sense_node); + index += 2; + + for (j = 0; j < totComData.header.force_node; + j++) { + snprintf(&driver_test_buff[index], 5, + "%02X%02X", + (totComData.ix_fm[j] & + 0xFF00) >> + 8, + totComData.ix_fm[j] & 0xFF); + index += 4; + } + + for (j = 0; j < totComData.header.sense_node; + j++) { + snprintf(&driver_test_buff[index], 5, + "%02X%02X", + (totComData.ix_sn[j] & + 0xFF00) >> + 8, + totComData.ix_sn[j] & 0xFF); + index += 4; + } + + for (j = 0; j < totComData.header.force_node; + j++) { + snprintf(&driver_test_buff[index], 5, + "%02X%02X", + (totComData.cx_fm[j] & + 0xFF00) >> + 8, + totComData.cx_fm[j] & 0xFF); + + index += 4; + } + + for (j = 0; j < totComData.header.sense_node; + j++) { + snprintf(&driver_test_buff[index], 5, + "%02X%02X", + (totComData.cx_sn[j] & + 0xFF00) >> + 8, + totComData.cx_sn[j] & 0xFF); + index += 4; + } + + kfree(totComData.ix_fm); + kfree(totComData.ix_sn); + kfree(totComData.cx_fm); + kfree(totComData.cx_sn); + break; + + case CMD_GETFWVER: + snprintf(&driver_test_buff[index], 5, "%04X", + fw_version); + index += 4; + + snprintf(&driver_test_buff[index], 5, "%04X", + config_id); + index += 4; + break; + + case CMD_READCOMPDATAHEAD: + snprintf(&driver_test_buff[index], 3, "%02X", + dataHead.type); + index += 2; + break; + + default: + break; + } + } + + snprintf(&driver_test_buff[index], 4, " }\n"); + limit = size - 1; + printed = 0; + } else { + driver_test_buff[index++] = MESSAGE_START_BYTE; + if (bin_output == 1) { + driver_test_buff[index++] = (size & 0xFF00) >> 8; + driver_test_buff[index++] = (size & 0x00FF); + + driver_test_buff[index++] = (mess.counter & 0xFF00) >> + 8; + driver_test_buff[index++] = (mess.counter & 0x00FF); + + driver_test_buff[index++] = (mess.action & 0xFF00) >> 8; + driver_test_buff[index++] = (mess.action & 0x00FF); + + driver_test_buff[index++] = (res & 0xFF00) >> 8; + driver_test_buff[index++] = (res & 0x00FF); + + } else { + if (funcToTest[0] == CMD_GETLIMITSFILE_BYTE || + funcToTest[0] == CMD_GETFWFILE_BYTE) + snprintf(&driver_test_buff[index], 5, + "%02X%02X", + (((fileSize + 3) / 4) & 0xFF00) >> 8, + ((fileSize + 3) / 4) & 0x00FF); + else + snprintf(&driver_test_buff[index], 5, + "%02X%02X", (size & 0xFF00) >> 8, + size & 0xFF); + index += 4; + index += snprintf(&driver_test_buff[index], 5, "%04X", + (u16)mess.counter); + index += snprintf(&driver_test_buff[index], 5, "%04X", + (u16)mess.action); + index += snprintf(&driver_test_buff[index], 5, + "%02X%02X", (res & 0xFF00) >> 8, + res & 0xFF); + } + + switch (funcToTest[0]) { + case CMD_VERSION_BYTE: + case CMD_READ_BYTE: + case CMD_WRITEREAD_BYTE: + case CMD_WRITETHENWRITEREAD_BYTE: + case CMD_WRITEREADU8UX_BYTE: + case CMD_WRITEU8UXTHENWRITEREADU8UX_BYTE: + if (bin_output == 1) { + if (mess.dummy == 1) + memcpy(&driver_test_buff[index], + &readData[1], byteToRead); + else + memcpy(&driver_test_buff[index], + readData, byteToRead); + index += byteToRead; + } else { + j = mess.dummy; + for (; j < byteToRead + mess.dummy; j++) + index += snprintf( + &driver_test_buff[index], 3, + "%02X", (u8)readData[j]); + } + break; + + case CMD_GETLIMITSFILE_BYTE: + case CMD_GETFWFILE_BYTE: + if (bin_output == 1) { + driver_test_buff[1] = + (((fileSize + 3) / 4) & 0xFF00) >> 8; + driver_test_buff[2] = + (((fileSize + 3) / 4) & 0x00FF); + + if (readData != NULL) { + memcpy(&driver_test_buff[index], + readData, fileSize); + } else { + logError( + 0, + "%s readData = NULL... returning junk data!", + tag); + } + index += addr; + } else { + for (j = 0; j < fileSize; j++) { + index += snprintf( + &driver_test_buff[index], 3, + "%02X", (u8)readData[j]); + } + for (; j < addr; j++) + index += snprintf( + &driver_test_buff[index], 3, + "%02X", 0); + } + break; + default: + break; + } + + driver_test_buff[index++] = MESSAGE_END_BYTE; + driver_test_buff[index] = '\n'; + limit = size; + printed = 0; + } +ERROR: + numberParam = 0; + if (readData != NULL) + kfree(readData); + if (cmd) + kfree(cmd); + return count; +} + +/** @}*/ + +/** + * file_operations struct which define the functions for the canonical operation on a device file node (open. read, write etc.) + */ +static struct file_operations fts_driver_test_ops = { + .open = fts_open, + .read = seq_read, + .write = fts_driver_test_write, + .llseek = seq_lseek, + .release = seq_release +}; + +/*****************************************************************************/ + +/** +* This function is called in the probe to initialize and create the directory /proc/fts and the driver test file node DRIVER_TEST_FILE_NODE into the /proc file system +* @return OK if success or an error code which specify the type of error encountered +*/ +int fts_proc_init(void) +{ + struct proc_dir_entry *entry; + + int retval = 0; + + fts_dir = proc_mkdir_data("fts", 0777, NULL, NULL); + if (fts_dir == NULL) { + retval = -ENOMEM; + goto out; + } + + entry = proc_create(DRIVER_TEST_FILE_NODE, 0644, fts_dir, + &fts_driver_test_ops); + + if (entry) { + logError(1, "%s %s: proc entry CREATED! \n", tag, __func__); + } else { + logError(1, "%s %s: error creating proc entry! \n", tag, + __func__); + retval = -ENOMEM; + goto badfile; + } + return OK; +badfile: + remove_proc_entry("fts", NULL); +out: + return retval; +} + +/** +* Delete and Clean from the file system, all the references to the driver test file node +* @return OK +*/ +int fts_proc_remove(void) +{ + remove_proc_entry(DRIVER_TEST_FILE_NODE, fts_dir); + remove_proc_entry("fts", NULL); + return OK; +} diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/Kconfig b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/Kconfig new file mode 100644 index 000000000000..e894eb406199 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/Kconfig @@ -0,0 +1,45 @@ +# +# Goodix touchscreen driver configuration +# +menuconfig TOUCHSCREEN_GOODIX_GTX8 + bool "Goodix GTx8 touchscreen" + depends on I2C + help + Say Y here if you have a Goodix GTx5xx touchscreen connected + to your system. + + If unsure, say N. + +if TOUCHSCREEN_GOODIX_GTX8 + +config TOUCHSCREEN_GOODIX_GTX8_UPDATE + tristate "Goodix GTx8 firmware update module" + default y + help + Say Y here to enable support for doing firmware update. + + If unsure, say N. + + To compile this driver as a module, choose M here. + +config TOUCHSCREEN_GOODIX_GTX8_GESTURE + tristate "Goodix GTx8 gesture wakeup feature" + default y + help + Say Y here to enable support for gesture wakeup feature.. + + If unsure, say N. + + To compile this driver as a module, choose M here. + +config TOUCHSCREEN_GOODIX_GTX8_TOOLS + tristate "Goodix touch tools support" + default y + help + Say Y here to enable debug tools. + + If unsure, say N. + + To compile this driver as a module, choose M here. + +endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/Makefile b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/Makefile new file mode 100644 index 000000000000..ed921866fb75 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_TOUCHSCREEN_GOODIX_GTX8) += goodix_ts_i2c.o +obj-$(CONFIG_TOUCHSCREEN_GOODIX_GTX8) += goodix_ts_core.o +obj-$(CONFIG_TOUCHSCREEN_GOODIX_GTX8) += goodix_cfg_bin.o +obj-$(CONFIG_TOUCHSCREEN_GOODIX_GTX8_UPDATE) += goodix_gtx8_update.o +obj-$(CONFIG_TOUCHSCREEN_GOODIX_GTX8_GESTURE) += goodix_ts_gesture.o +obj-$(CONFIG_TOUCHSCREEN_GOODIX_GTX8_TOOLS) += goodix_ts_tools.o +obj-$(CONFIG_TOUCHSCREEN_GOODIX_GTX8) += test_core/ diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_cfg_bin.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_cfg_bin.c new file mode 100644 index 000000000000..d1025106a6a5 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_cfg_bin.c @@ -0,0 +1,674 @@ +#include "goodix_cfg_bin.h" +#include + +extern int goodix_i2c_write(struct goodix_ts_device *dev, unsigned int reg, + unsigned char *data, unsigned int len); +extern int goodix_i2c_read(struct goodix_ts_device *dev, unsigned int reg, + unsigned char *data, unsigned int len); +extern int goodix_hw_reset(struct goodix_ts_device *dev); +extern struct goodix_module goodix_modules; + +int goodix_start_cfg_bin(struct goodix_ts_core *ts_core) +{ + struct task_struct *cfg_bin_thrd; + /* create and run update thread */ + ts_err("enter::%s\n", __func__); + cfg_bin_thrd = kthread_run(goodix_cfg_bin_proc, ts_core, + "goodix-parse_cfg_bin"); + if (IS_ERR_OR_NULL(cfg_bin_thrd)) { + ts_err("Failed to create update thread:%ld", + PTR_ERR(cfg_bin_thrd)); + return -EFAULT; + } + return 0; +} + +int goodix_get_lockdowninfo(struct goodix_ts_core *ts_core) +{ + int ret = 0; + struct goodix_ts_device *ts_dev = ts_core->ts_dev; + + ret = ts_dev->hw_ops->read(ts_dev, TS_LOCKDOWN_REG, + ts_core->lockdown_info, + GOODIX_LOCKDOWN_SIZE); + if (ret) { + ts_err("can't get lockdown"); + return -EINVAL; + } + ts_info("lockdown is:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x", + ts_core->lockdown_info[0], ts_core->lockdown_info[1], + ts_core->lockdown_info[2], ts_core->lockdown_info[3], + ts_core->lockdown_info[4], ts_core->lockdown_info[5], + ts_core->lockdown_info[6], ts_core->lockdown_info[7]); + return 0; +} + +int goodix_parse_cfg_bin(struct goodix_cfg_bin *cfg_bin) +{ + u8 checksum; + int i, r; + u16 offset1, offset2; + if (!cfg_bin->bin_data || cfg_bin->bin_data_len == 0) { + ts_err("NO cfg_bin data, cfg_bin data length:%d", + cfg_bin->bin_data_len); + r = -EINVAL; + goto exit; + } + + /* copy cfg_bin head info */ + if (cfg_bin->bin_data_len < sizeof(struct goodix_cfg_bin_head)) { + ts_err("Invalid cfg_bin size:%d", cfg_bin->bin_data_len); + r = -EINVAL; + goto exit; + } + memcpy(&cfg_bin->head, cfg_bin->bin_data, + sizeof(struct goodix_cfg_bin_head)); + cfg_bin->head.bin_len = le32_to_cpu(cfg_bin->head.bin_len); + + /*check length*/ + if (cfg_bin->bin_data_len != cfg_bin->head.bin_len) { + ts_err("cfg_bin length error,len in cfg_bin:%d, len of firmware:%d", + cfg_bin->head.bin_len, cfg_bin->bin_data_len); + r = -EINVAL; + goto exit; + } + + /*check cfg_bin valid*/ + checksum = 0; + for (i = TS_BIN_VERSION_START_INDEX; i < cfg_bin->bin_data_len; i++) { + checksum += cfg_bin->bin_data[i]; + } + if (checksum != cfg_bin->head.checksum) { + ts_err("cfg_bin checksum ERROR, checksum in cfg_bin:0x%02x, checksum caculate:0x%02x", + cfg_bin->head.checksum, checksum); + r = -EINVAL; + goto exit; + } + + /*allocate memory for cfg packages*/ + cfg_bin->cfg_pkgs = kzalloc(sizeof(struct goodix_cfg_package) * + cfg_bin->head.pkg_num, + GFP_KERNEL); + if (!cfg_bin->cfg_pkgs) { + ts_err("cfg_pkgs, allocate memory ERROR"); + r = -ENOMEM; + goto exit; + } + /*get cfg_pkg's info*/ + for (i = 0; i < cfg_bin->head.pkg_num; i++) { + /*get cfg pkg length*/ + if (i == cfg_bin->head.pkg_num - 1) { + offset1 = cfg_bin->bin_data[TS_CFG_BIN_HEAD_LEN + + i * TS_CFG_OFFSET_LEN] + + (cfg_bin->bin_data[TS_CFG_BIN_HEAD_LEN + + i * TS_CFG_OFFSET_LEN + 1] + << 8); + cfg_bin->cfg_pkgs[i].pkg_len = + cfg_bin->bin_data_len - offset1; + } else { + offset1 = cfg_bin->bin_data[TS_CFG_BIN_HEAD_LEN + + i * TS_CFG_OFFSET_LEN] + + (cfg_bin->bin_data[TS_CFG_BIN_HEAD_LEN + + i * TS_CFG_OFFSET_LEN + 1] + << 8); + offset2 = cfg_bin->bin_data[TS_CFG_BIN_HEAD_LEN + + i * TS_CFG_OFFSET_LEN + 2] + + (cfg_bin->bin_data[TS_CFG_BIN_HEAD_LEN + + i * TS_CFG_OFFSET_LEN + 3] + << 8); + if (offset2 <= offset1) { + ts_err("offset error,pkg:%d, offset1:%d, offset2:%d", + i, offset1, offset2); + r = -EINVAL; + goto exit; + } + cfg_bin->cfg_pkgs[i].pkg_len = offset2 - offset1; + } + /*get cfg pkg head*/ + memcpy(&cfg_bin->cfg_pkgs[i].cnst_info, + &cfg_bin->bin_data[offset1], TS_PKG_CONST_INFO_LEN); + memcpy(&cfg_bin->cfg_pkgs[i].reg_info, + &cfg_bin->bin_data[offset1 + TS_PKG_CONST_INFO_LEN], + TS_PKG_REG_INFO_LEN); + /*compatible little edition and big edition*/ + goodix_cfg_pkg_leToCpu(&cfg_bin->cfg_pkgs[i]); + + /*get configuration data*/ + cfg_bin->cfg_pkgs[i].cfg = + &cfg_bin->bin_data[offset1 + TS_PKG_HEAD_LEN]; + } + + /*debug, print pkg information*/ + for (i = 0; i < cfg_bin->head.pkg_num; i++) { + ts_info("---------------------------------------------"); + ts_info("------package:%d------", i + 1); + ts_info("package len:%04x", + cfg_bin->cfg_pkgs[i].cnst_info.pkg_len); + ts_info("package ic_type:%s", + cfg_bin->cfg_pkgs[i].cnst_info.ic_type); + ts_info("package cfg_type:%01x", + cfg_bin->cfg_pkgs[i].cnst_info.cfg_type); + ts_info("package sensor_id:%01x", + cfg_bin->cfg_pkgs[i].cnst_info.sensor_id); + ts_info("package hw_pid:%s", + cfg_bin->cfg_pkgs[i].cnst_info.hw_pid); + ts_info("package hw_vid:%s", + cfg_bin->cfg_pkgs[i].cnst_info.hw_vid); + ts_info("package fw_mask_version:%s", + cfg_bin->cfg_pkgs[i].cnst_info.fw_mask); + ts_info("package fw_patch_version:%s", + cfg_bin->cfg_pkgs[i].cnst_info.fw_patch); + ts_info("package x_res_offset:%02x", + cfg_bin->cfg_pkgs[i].cnst_info.x_res_offset); + ts_info("package y_res_offset:%02x", + cfg_bin->cfg_pkgs[i].cnst_info.y_res_offset); + ts_info("package trigger_offset:%02x", + cfg_bin->cfg_pkgs[i].cnst_info.trigger_offset); + + ts_info(""); + ts_info("send_cfg_flag reg:%02x", + cfg_bin->cfg_pkgs[i].reg_info.cfg_send_flag.addr); + ts_info("version base reg:%02x, len:%d", + cfg_bin->cfg_pkgs[i].reg_info.version_base.addr, + cfg_bin->cfg_pkgs[i].reg_info.version_base.reserved1); + ts_info("pid reg:%02x", cfg_bin->cfg_pkgs[i].reg_info.pid.addr); + ts_info("vid reg:%02x", cfg_bin->cfg_pkgs[i].reg_info.vid.addr); + ts_info("sensor_id reg:%02x", + cfg_bin->cfg_pkgs[i].reg_info.sensor_id.addr); + ts_info("fw_status reg:%02x", + cfg_bin->cfg_pkgs[i].reg_info.fw_status.addr); + ts_info("cfg_addr reg:%02x", + cfg_bin->cfg_pkgs[i].reg_info.cfg_addr.addr); + ts_info("esd reg:%02x", cfg_bin->cfg_pkgs[i].reg_info.esd.addr); + ts_info("command reg:%02x", + cfg_bin->cfg_pkgs[i].reg_info.command.addr); + ts_info("coor:%02x", cfg_bin->cfg_pkgs[i].reg_info.coor.addr); + ts_info("gesture:%02x", + cfg_bin->cfg_pkgs[i].reg_info.gesture.addr); + ts_info("fw_request:%02x", + cfg_bin->cfg_pkgs[i].reg_info.fw_request.addr); + ts_info("proximity:%02x", + cfg_bin->cfg_pkgs[i].reg_info.proximity.addr); + ts_info("--------------------------------------------"); + } + r = 0; +exit: + return r; +} + +int goodix_cfg_bin_proc(void *data) +{ + struct goodix_ts_core *core_data = data; + struct goodix_ts_device *ts_dev = core_data->ts_dev; + + struct device *dev = ts_dev->dev; + int r; + +#ifdef CONFIG_GOODIX_HWINFO + u8 *tp_maker; +#endif + struct goodix_cfg_bin *cfg_bin = + kzalloc(sizeof(struct goodix_cfg_bin), GFP_KERNEL); + if (!cfg_bin) { + ts_err("Failed to alloc memory for cfg_bin"); + r = -ENOMEM; + goto exit; + } + /*get cfg_bin from file system*/ + r = goodix_read_cfg_bin(dev, cfg_bin); + if (r < 0) { + ts_err("read cfg_bin from /etc/firmware FAILED"); + goto exit; + } + /*parse cfg bin*/ + r = goodix_parse_cfg_bin(cfg_bin); + if (!r) { + ts_info("parse cfg bin SUCCESS"); + } else { + ts_err("parse cfg bin FAILED"); + goto exit; + } + /*init i2c_set_doze_mode para*/ + ts_dev->doze_mode_set_count = 0; + mutex_init(&ts_dev->doze_mode_lock); + /*get register address and configuration from cfg bin*/ + r = goodix_get_reg_and_cfg(ts_dev, cfg_bin); + if (!r) { + ts_info("get reg and cfg from cfg_bin SUCCESS"); + } else { + if (r != -EBUS) { + ts_err("get reg and cfg from cfg_bin FAILED, update fw then retry"); + goodix_modules.core_data = core_data; + goodix_modules.core_exit = false; + complete_all(&goodix_modules.core_comp); + goto exit; + } else { + ts_err("get reg and cfg from cfg_bin FAILED, I2C com ERROR"); + goto exit; + } + } + /*init i2c_set_doze_mode para*/ + ts_dev->doze_mode_set_count = 0; + mutex_init(&ts_dev->doze_mode_lock); + + ts_info("cfg_send_flag:0x%04x", ts_dev->reg.cfg_send_flag); + ts_info("pid:0x%04x", ts_dev->reg.pid); + ts_info("vid:0x%04x", ts_dev->reg.vid); + ts_info("sensor_id:0x%04x", ts_dev->reg.sensor_id); + ts_info("fw_mask:0x%04x", ts_dev->reg.fw_mask); + ts_info("fw_status:0x%04x", ts_dev->reg.fw_status); + ts_info("cfg_addr:0x%04x", ts_dev->reg.cfg_addr); + ts_info("esd:0x%04x", ts_dev->reg.esd); + ts_info("command:0x%04x", ts_dev->reg.command); + ts_info("coor:0x%04x", ts_dev->reg.coor); + ts_info("gesture:0x%04x", ts_dev->reg.gesture); + ts_info("fw_request:0x%04x", ts_dev->reg.fw_request); + ts_info("proximity:0x%04x", ts_dev->reg.proximity); + + /* initialize firmware */ + r = ts_dev->hw_ops->init(ts_dev); + if (-EBUS == r) + goto exit; + + /* alloc/config/register input device */ + r = goodix_ts_input_dev_config(core_data); + if (r < 0) + goto exit; + + /* request irq line */ + r = goodix_ts_irq_setup(core_data); + if (r < 0) + goto exit; + + /*set flag, prevent fwupdate module parse cfg_group again*/ + core_data->cfg_group_parsed = true; + + /* inform the external module manager that + * touch core layer is ready now */ + goodix_modules.core_data = core_data; + goodix_modules.core_exit = false; + /*complete_all(&goodix_modules.core_comp);*/ + +#ifdef CONFIG_DRM + core_data->fb_notifier.notifier_call = goodix_ts_fb_notifier_callback; + if (drm_register_client(&core_data->fb_notifier)) + ts_err("Failed to register fb notifier client:%d", r); +#elif defined(CONFIG_HAS_EARLYSUSPEND) + core_data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + core_data->early_suspend.resume = goodix_ts_lateresume; + core_data->early_suspend.suspend = goodix_ts_earlysuspend; + register_early_suspend(&core_data->early_suspend); +#endif + goodix_get_lockdowninfo(core_data); + + /* esd protector */ + goodix_ts_esd_init(core_data); + + /* generic notifier callback */ + core_data->ts_notifier.notifier_call = goodix_generic_noti_callback; + goodix_ts_register_notifier(&core_data->ts_notifier); + +#ifdef CONFIG_GOODIX_HWINFO + tp_maker = kzalloc(20, GFP_KERNEL); + if (tp_maker == NULL) + ts_err("fail to alloc vendor name memory\n"); + else { + kfree(tp_maker); + tp_maker = NULL; + } +#endif + +exit: + complete_all(&goodix_modules.core_comp); + if (cfg_bin->cfg_pkgs) { + kfree(cfg_bin->cfg_pkgs); + cfg_bin->cfg_pkgs = NULL; + } + if (cfg_bin->bin_data) { + kfree(cfg_bin->bin_data); + cfg_bin->bin_data = NULL; + } + return r; +} + +int goodix_get_reg_and_cfg(struct goodix_ts_device *ts_dev, + struct goodix_cfg_bin *cfg_bin) +{ + int i; + u16 addr; + u8 read_len; + struct goodix_cfg_package *normal_pkg, *high_sense_pkg; + char temp_sensor_id = -1; + u8 temp_fw_mask[TS_CFG_BLOCK_FW_MASK_LEN] = { 0x00 }; + u8 temp_pid[TS_CFG_BLOCK_PID_LEN] = { 0x00 }; + int r = -EINVAL; + normal_pkg = NULL; + high_sense_pkg = NULL; + + if (!cfg_bin->head.pkg_num || !cfg_bin->cfg_pkgs) { + ts_err("there is none cfg package, pkg_num:%d", + cfg_bin->head.pkg_num); + r = -EINVAL; + goto exit; + } + + /*select suitable cfg packages*/ + for (i = 0; i < cfg_bin->head.pkg_num; i++) { + /*get ic type*/ + if (!strncmp(cfg_bin->cfg_pkgs[i].cnst_info.ic_type, "nanjing", + sizeof(cfg_bin->cfg_pkgs[i].cnst_info.ic_type))) + ts_dev->ic_type = IC_TYPE_NANJING; + else if (!strncmp( + cfg_bin->cfg_pkgs[i].cnst_info.ic_type, + "normandy", + sizeof(cfg_bin->cfg_pkgs[i].cnst_info.ic_type))) + ts_dev->ic_type = IC_TYPE_NORMANDY; + else + ts_err("get ic type FAILED, unknow ic type from cfg_bin:%s", + cfg_bin->cfg_pkgs[i].cnst_info.ic_type); + + ts_info("ic_type:%d", ts_dev->ic_type); + /*contrast sensor id*/ + addr = cfg_bin->cfg_pkgs[i].reg_info.sensor_id.addr; + if (!addr) { + ts_info("pkg:%d, sensor_id reg is NULL", i); + continue; + } + r = goodix_i2c_read(ts_dev, addr, &temp_sensor_id, 1); + if (r < 0) { + ts_err("read sensor id FAILED,I2C ERROR, pkg:%d, sensor_id reg:0x%02x", + i, addr); + goto exit; + } else { + /*sensor.reserved1 is a mask, if it's not ZERO, use it*/ + if (cfg_bin->cfg_pkgs[i].reg_info.sensor_id.reserved1 != + 0) + temp_sensor_id &= + cfg_bin->cfg_pkgs[i] + .reg_info.sensor_id.reserved1; + if (temp_sensor_id != + cfg_bin->cfg_pkgs[i].cnst_info.sensor_id) { + ts_err("pkg:%d, sensor id contrast FAILED, reg:0x%02x", + i, addr); + ts_err("sensor_id from i2c:%d, sensor_id of cfg bin:%d", + temp_sensor_id, + cfg_bin->cfg_pkgs[i].cnst_info.sensor_id); + continue; + } + } + + /*contrast fw_mask, if this reg is null, skip this step*/ + addr = cfg_bin->cfg_pkgs[i].reg_info.fw_mask.addr; + if (!addr || !cfg_bin->cfg_pkgs[i].cnst_info.fw_mask[0]) { + ts_err("pkg:%d, fw_mask of cfg bin is NULL, Skip!!", i); + } else { + r = goodix_i2c_read(ts_dev, addr, temp_fw_mask, + sizeof(temp_fw_mask)); + if (r < 0) { + ts_err("read fw_mask FAILED, I2C ERROR, pkg: %d, fw_mask reg:0x%02x", + i, addr); + goto exit; + } else if (strncmp(temp_fw_mask, + cfg_bin->cfg_pkgs[i] + .cnst_info.fw_mask, + sizeof(temp_fw_mask))) { + ts_err("pkg:%d, fw_mask contrast FAILED, reg:0x%02x,", + i, addr); + ts_err("mask from i2c:%s, mask of cfg bin:%s", + temp_fw_mask, + cfg_bin->cfg_pkgs[i].cnst_info.fw_mask); + continue; + } + } + + /*contrast pid*/ + addr = cfg_bin->cfg_pkgs[i].reg_info.pid.addr; + read_len = cfg_bin->cfg_pkgs[i].reg_info.pid.reserved1; + if (!addr) { + ts_err("pkg:%d, pid reg is NULL", i); + continue; + } + if (read_len <= 0 || read_len > TS_CFG_BLOCK_PID_LEN) { + ts_err("pkg:%d, hw_pid length ERROR, len:%d", i, + read_len); + continue; + } + r = goodix_i2c_read(ts_dev, addr, temp_pid, read_len); + if (r < 0) { + ts_err("read pid FAILED, I2C ERROR, pkg: %d, pid reg:0x%02x", + i, addr); + goto exit; + } else if (strncmp(temp_pid, + cfg_bin->cfg_pkgs[i].cnst_info.hw_pid, + read_len)) { + ts_err("pkg:%d, pid contrast FAILED, reg:0x%02x", i, + addr); + ts_err("pid from i2c:%s, pid of cfg bin:%s", temp_pid, + cfg_bin->cfg_pkgs[i].cnst_info.hw_pid); + continue; + } + + /*contrast success, cfg_type*/ + if (cfg_bin->cfg_pkgs[i].cnst_info.cfg_type == TS_NORMAL_CFG) { + ts_info("find normal cfg_pkg SUCCESS"); + r = 0; + normal_pkg = &cfg_bin->cfg_pkgs[i]; + } + if (cfg_bin->cfg_pkgs[i].cnst_info.cfg_type == + TS_HIGH_SENSE_CFG) { + ts_info("find high sense cfg_pkg SUCCESS"); + high_sense_pkg = &cfg_bin->cfg_pkgs[i]; + } + } + + /*get register address from normal_pkg*/ + if (!normal_pkg) { + ts_err("ERROR, none suitable normal_pkg exist in cfg_bin"); + /*ts_dev->ic_type = IC_TYPE_NONE;*/ + r = -EINVAL; + goto exit; + } else { + /*get ic type*/ + if (!strncmp(normal_pkg->cnst_info.ic_type, "nanjing", + sizeof(normal_pkg->cnst_info.ic_type))) + ts_dev->ic_type = IC_TYPE_NANJING; + else if (!strncmp(normal_pkg->cnst_info.ic_type, "normandy", + sizeof(normal_pkg->cnst_info.ic_type))) + ts_dev->ic_type = IC_TYPE_NORMANDY; + else + ts_err("get ic type FAILED, unknow ic type from cfg_bin:%s", + normal_pkg->cnst_info.ic_type); + + /*get register info*/ + ts_dev->reg.cfg_send_flag = + normal_pkg->reg_info.cfg_send_flag.addr; + ts_dev->reg.version_base = + normal_pkg->reg_info.version_base.addr; + ts_dev->reg.version_len = + normal_pkg->reg_info.version_base.reserved1; + ts_dev->reg.pid = normal_pkg->reg_info.pid.addr; + ts_dev->reg.pid_len = normal_pkg->reg_info.pid.reserved1; + ts_dev->reg.vid = normal_pkg->reg_info.vid.addr; + ts_dev->reg.vid_len = normal_pkg->reg_info.vid.reserved1; + ts_dev->reg.sensor_id = normal_pkg->reg_info.sensor_id.addr; + ts_dev->reg.sensor_id_mask = + normal_pkg->reg_info.sensor_id.reserved1; + ts_dev->reg.fw_mask = normal_pkg->reg_info.fw_mask.addr; + ts_dev->reg.fw_status = normal_pkg->reg_info.fw_status.addr; + ts_dev->reg.cfg_addr = normal_pkg->reg_info.cfg_addr.addr; + ts_dev->reg.esd = normal_pkg->reg_info.esd.addr; + ts_dev->reg.command = normal_pkg->reg_info.command.addr; + ts_dev->reg.coor = normal_pkg->reg_info.coor.addr; + ts_dev->reg.gesture = normal_pkg->reg_info.gesture.addr; + ts_dev->reg.fw_request = normal_pkg->reg_info.fw_request.addr; + ts_dev->reg.proximity = normal_pkg->reg_info.proximity.addr; + } + + /*get configuration from pkgs*/ + if (normal_pkg) { + ts_info("normal cfg is found!"); + if (!ts_dev->normal_cfg) { + ts_dev->normal_cfg = devm_kzalloc( + ts_dev->dev, sizeof(*ts_dev->normal_cfg), + GFP_KERNEL); + if (!ts_dev->normal_cfg) { + ts_err("Failed to alloc memory for normal cfg"); + return -ENOMEM; + } + mutex_init(&ts_dev->normal_cfg->lock); + } + + ts_dev->normal_cfg->length = normal_pkg->pkg_len - + TS_PKG_CONST_INFO_LEN - + TS_PKG_REG_INFO_LEN; + memcpy(ts_dev->normal_cfg->data, normal_pkg->cfg, + ts_dev->normal_cfg->length); + } + + if (high_sense_pkg) { + ts_info("high sense cfg is found!"); + if (!ts_dev->highsense_cfg) { + ts_dev->highsense_cfg = devm_kzalloc( + ts_dev->dev, sizeof(*ts_dev->highsense_cfg), + GFP_KERNEL); + if (!ts_dev->highsense_cfg) { + ts_err("Failed to alloc memory for high sense cfg"); + return -ENOMEM; + } + mutex_init(&ts_dev->highsense_cfg->lock); + } + + ts_dev->highsense_cfg->length = high_sense_pkg->pkg_len - + TS_PKG_CONST_INFO_LEN - + TS_PKG_REG_INFO_LEN; + memcpy(ts_dev->highsense_cfg->data, high_sense_pkg->cfg, + ts_dev->highsense_cfg->length); + } + +exit: + return r; +} + +int goodix_read_cfg_bin(struct device *dev, struct goodix_cfg_bin *cfg_bin) +{ + int r; + const struct firmware *firmware; + char cfg_bin_name[32] = { 0x00 }; + int i = 0; + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + struct goodix_ts_device *ts_dev = core_data->ts_dev; + struct goodix_ts_board_data *ts_bdata = ts_dev->board_data; + + if (ts_dev == NULL) { + ts_err("can't get ts_dev"); + return -EINVAL; + } + ts_bdata = ts_dev->board_data; + if (ts_bdata == NULL) { + ts_err("can't get ts_bdata"); + return -EINVAL; + } + /*get cfg_bin_name*/ + if (ts_bdata->cfg_bin_name) + strlcpy(cfg_bin_name, ts_bdata->cfg_bin_name, + sizeof(cfg_bin_name)); + else + strlcpy(cfg_bin_name, TS_DEFAULT_CFG_BIN, sizeof(cfg_bin_name)); + ts_info("ts_bdata->cfg_bin_name:%s", ts_bdata->cfg_bin_name); + ts_info("cfg_bin_name:%s", cfg_bin_name); + for (i = 0; i < TS_RQST_FW_RETRY_TIMES; i++) { + r = request_firmware(&firmware, cfg_bin_name, dev); + if (r < 0) { + ts_err("Cfg_bin image [%s] not available,error:%d, try_times:%d", + cfg_bin_name, r, i + 1); + msleep(1000); + } else { + ts_info("Cfg_bin image [%s] is ready, try_times:%d", + cfg_bin_name, i + 1); + break; + } + } + if (i >= TS_RQST_FW_RETRY_TIMES) { + ts_err("get cfg_bin FAILED"); + goto exit; + } + + if (firmware->size <= 0) { + ts_err("request_firmware, cfg_bin length ERROR,len:%zu", + firmware->size); + r = -EINVAL; + goto exit; + } + + cfg_bin->bin_data_len = firmware->size; + /*allocate memory for cfg_bin->bin_data*/ + cfg_bin->bin_data = kzalloc(cfg_bin->bin_data_len, GFP_KERNEL); + if (!cfg_bin->bin_data) { + ts_err("Allocate memory for cfg_bin->bin_data FAILED"); + r = -ENOMEM; + } + memcpy(cfg_bin->bin_data, firmware->data, cfg_bin->bin_data_len); + r = 0; +exit: + if (firmware) { + release_firmware(firmware); + firmware = NULL; + } + return r; +} + +int goodix_read_cfg_bin_from_dts(struct device_node *node, + struct goodix_cfg_bin *cfg_bin) +{ + unsigned int len = 0; + struct property *prop = NULL; + + prop = of_find_property(node, "goodix_cfg_bin", &len); + if (!prop || !prop->value || len == 0) { + ts_err("Invalid cfg type, size:%u", len); + return -EINVAL; + } + + cfg_bin->bin_data_len = len; + /*allocate memory for cfg_bin->bin_data*/ + cfg_bin->bin_data = kzalloc(cfg_bin->bin_data_len, GFP_KERNEL); + if (!cfg_bin->bin_data) { + ts_err("Allocate memory for cfg_bin->bin_data FAILED"); + return -ENOMEM; + } + memcpy(cfg_bin->bin_data, prop->value, cfg_bin->bin_data_len); + return 0; +} + +void goodix_cfg_pkg_leToCpu(struct goodix_cfg_package *pkg) +{ + if (!pkg) { + ts_err("cfg package is NULL"); + return; + } + /*package const_info*/ + pkg->cnst_info.pkg_len = le32_to_cpu(pkg->cnst_info.pkg_len); + pkg->cnst_info.x_res_offset = le16_to_cpu(pkg->cnst_info.x_res_offset); + pkg->cnst_info.y_res_offset = le16_to_cpu(pkg->cnst_info.y_res_offset); + pkg->cnst_info.trigger_offset = + le16_to_cpu(pkg->cnst_info.trigger_offset); + + /*package reg_info*/ + pkg->reg_info.cfg_send_flag.addr = + le16_to_cpu(pkg->reg_info.cfg_send_flag.addr); + pkg->reg_info.pid.addr = le16_to_cpu(pkg->reg_info.pid.addr); + pkg->reg_info.vid.addr = le16_to_cpu(pkg->reg_info.vid.addr); + pkg->reg_info.sensor_id.addr = + le16_to_cpu(pkg->reg_info.sensor_id.addr); + pkg->reg_info.fw_status.addr = + le16_to_cpu(pkg->reg_info.fw_status.addr); + pkg->reg_info.cfg_addr.addr = le16_to_cpu(pkg->reg_info.cfg_addr.addr); + pkg->reg_info.esd.addr = le16_to_cpu(pkg->reg_info.esd.addr); + pkg->reg_info.command.addr = le16_to_cpu(pkg->reg_info.command.addr); + pkg->reg_info.coor.addr = le16_to_cpu(pkg->reg_info.coor.addr); + pkg->reg_info.gesture.addr = le16_to_cpu(pkg->reg_info.gesture.addr); + pkg->reg_info.fw_request.addr = + le16_to_cpu(pkg->reg_info.fw_request.addr); + pkg->reg_info.proximity.addr = + le16_to_cpu(pkg->reg_info.proximity.addr); +} diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_cfg_bin.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_cfg_bin.h new file mode 100644 index 000000000000..5828c59d65be --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_cfg_bin.h @@ -0,0 +1,108 @@ +#ifndef _GOODIX_CFG_BIN_H_ +#define _GOODIX_CFG_BIN_H_ + +#include "goodix_ts_core.h" + +#define TS_DEFAULT_CFG_BIN "goodix_gt9886_cfg_f11.bin" +#define TS_BIN_VERSION_START_INDEX 5 +#define TS_BIN_VERSION_LEN 4 +#define TS_CFG_BIN_HEAD_RESERVED_LEN 6 +#define TS_CFG_OFFSET_LEN 2 +#define TS_IC_TYPE_NAME_MAX_LEN 15 +#define TS_CFG_BIN_HEAD_LEN \ + (sizeof(struct goodix_cfg_bin_head) + TS_CFG_BIN_HEAD_RESERVED_LEN) +#define TS_PKG_CONST_INFO_LEN (sizeof(struct goodix_cfg_pkg_const_info)) +#define TS_PKG_REG_INFO_LEN (sizeof(struct goodix_cfg_pkg_reg_info)) +#define TS_PKG_HEAD_LEN (TS_PKG_CONST_INFO_LEN + TS_PKG_REG_INFO_LEN) + +/*cfg block definitin*/ +#define TS_CFG_BLOCK_PID_LEN 8 +#define TS_CFG_BLOCK_VID_LEN 8 +#define TS_CFG_BLOCK_FW_MASK_LEN 9 +#define TS_CFG_BLOCK_FW_PATCH_LEN 4 +#define TS_CFG_BLOCK_RESERVED_LEN 9 + +#define TS_NORMAL_CFG 0x01 +#define TS_HIGH_SENSE_CFG 0x03 +#define TS_RQST_FW_RETRY_TIMES 2 +#define TS_LOCKDOWN_REG 0xBDB4 + +#pragma pack(1) +struct goodix_cfg_pkg_reg { + u16 addr; + u8 reserved1; + u8 reserved2; +}; + +struct goodix_cfg_pkg_const_info { + u32 pkg_len; + u8 ic_type[TS_IC_TYPE_NAME_MAX_LEN]; + u8 cfg_type; + u8 sensor_id; + u8 hw_pid[TS_CFG_BLOCK_PID_LEN]; + u8 hw_vid[TS_CFG_BLOCK_VID_LEN]; + u8 fw_mask[TS_CFG_BLOCK_FW_MASK_LEN]; + u8 fw_patch[TS_CFG_BLOCK_FW_PATCH_LEN]; + u16 x_res_offset; + u16 y_res_offset; + u16 trigger_offset; +}; + +struct goodix_cfg_pkg_reg_info { + struct goodix_cfg_pkg_reg cfg_send_flag; + struct goodix_cfg_pkg_reg version_base; + struct goodix_cfg_pkg_reg pid; + struct goodix_cfg_pkg_reg vid; + struct goodix_cfg_pkg_reg sensor_id; + struct goodix_cfg_pkg_reg fw_mask; + struct goodix_cfg_pkg_reg fw_status; + struct goodix_cfg_pkg_reg cfg_addr; + struct goodix_cfg_pkg_reg esd; + struct goodix_cfg_pkg_reg command; + struct goodix_cfg_pkg_reg coor; + struct goodix_cfg_pkg_reg gesture; + struct goodix_cfg_pkg_reg fw_request; + struct goodix_cfg_pkg_reg proximity; + u8 reserved[TS_CFG_BLOCK_RESERVED_LEN]; +}; + +struct goodix_cfg_bin_head { + u32 bin_len; + u8 checksum; + u8 bin_version[TS_BIN_VERSION_LEN]; + u8 pkg_num; +}; + +#pragma pack() + +struct goodix_cfg_package { + struct goodix_cfg_pkg_const_info cnst_info; + struct goodix_cfg_pkg_reg_info reg_info; + const u8 *cfg; + u32 pkg_len; +}; + +struct goodix_cfg_bin { + unsigned char *bin_data; + unsigned int bin_data_len; + struct goodix_cfg_bin_head head; + struct goodix_cfg_package *cfg_pkgs; +}; + +int goodix_cfg_bin_proc(void *data); + +int goodix_parse_cfg_bin(struct goodix_cfg_bin *cfg_bin); + +int goodix_get_reg_and_cfg(struct goodix_ts_device *ts_dev, + struct goodix_cfg_bin *cfg_bin); + +int goodix_read_cfg_bin(struct device *dev, struct goodix_cfg_bin *cfg_bin); + +int goodix_read_cfg_bin_from_dts(struct device_node *node, + struct goodix_cfg_bin *cfg_bin); + +void goodix_cfg_pkg_leToCpu(struct goodix_cfg_package *pkg); + +int goodix_start_cfg_bin(struct goodix_ts_core *ts_core); + +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_default_fw.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_default_fw.h new file mode 100644 index 000000000000..00fd39d4b840 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_default_fw.h @@ -0,0 +1,6 @@ +#ifndef _GOODIX_FIRMWARE_FW_H_ +#define _GOODIX_FIRMWARE_FW_H_ + +u8 goodix_default_fw[] = { 0x00 }; + +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_gtx8_update.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_gtx8_update.c new file mode 100644 index 000000000000..8e97ed43e820 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_gtx8_update.c @@ -0,0 +1,1397 @@ +/* + * Goodix GTX5 Firmware Update Driver. + * + * Copyright (C) 2015 - 2016 Goodix, Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * Authors: Yulong Cai + * + * 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. + */ +#include "goodix_ts_core.h" +#include "goodix_cfg_bin.h" +#include "goodix_default_fw.h" +/* COMMON PART - START */ +#define TS_DEFAULT_FIRMWARE "goodix_gt9886_fw_f11.bin" + +#define FW_HEADER_SIZE 256 +#define FW_SUBSYS_INFO_SIZE 8 +#define FW_SUBSYS_INFO_OFFSET 32 +#define FW_SUBSYS_MAX_NUM 28 +#define FW_UPDATE_RETRY 2 + +#define ISP_MAX_BUFFERSIZE (1024 * 4) + +#define HW_REG_CPU_CTRL 0x2180 +#define HW_REG_DSP_MCU_POWER 0x2010 +#define HW_REG_RESET 0x2184 +#define HW_REG_SCRAMBLE 0x2218 +#define HW_REG_BANK_SELECT 0x2048 +#define HW_REG_ACCESS_PATCH0 0x204D +#define HW_REG_EC_SRM_START 0x204F +#define HW_REG_CPU_RUN_FROM 0x4506 /* for nor_L is 0x4006 */ +#define HW_REG_ISP_RUN_FLAG 0x6006 +#define HW_REG_ISP_ADDR 0xC000 +#define HW_REG_ISP_BUFFER 0x6100 +#define HW_REG_SUBSYS_TYPE 0x6020 +#define HW_REG_FLASH_FLAG 0x6022 +#define HW_REG_CACHE 0x204B +#define HW_REG_ESD_KEY 0x2318 +#define HW_REG_WTD_TIMER 0x20B0 + +#define CPU_CTRL_PENDING 0x00 +#define CPU_CTRL_RUNNING 0x01 + +#define ISP_STAT_IDLE 0xFF +#define ISP_STAT_READY 0xAA +#define ISP_STAT_WRITING 0xAA +#define ISP_FLASH_SUCCESS 0xBB +#define ISP_FLASH_ERROR 0xCC +#define ISP_FLASH_CHECK_ERROR 0xDD +#define ISP_CMD_PREPARE 0x55 +#define ISP_CMD_FLASH 0xAA + +#define TS_CHECK_ISP_STATE_RETRY_TIMES 200 +#define TS_READ_FLASH_STATE_RETRY_TIMES 200 + +/*0: Header update + *1: request firmware update*/ +atomic_t fw_update_mode = ATOMIC_INIT(1); + +/** + * fw_subsys_info - subsytem firmware infomation + * @type: sybsystem type + * @size: firmware size + * @flash_addr: flash address + * @data: firmware data + */ +struct fw_subsys_info { + u8 type; + u32 size; + u16 flash_addr; + const u8 *data; +}; + +#pragma pack(1) +/** + * firmware_info + * @size: fw total length + * @checksum: checksum of fw + * @hw_pid: mask pid string + * @hw_pid: mask vid code + * @fw_pid: fw pid string + * @fw_vid: fw vid code + * @subsys_num: number of fw subsystem + * @chip_type: chip type + * @protocol_ver: firmware packing + * protocol version + * @subsys: sybsystem info + */ +struct firmware_info { + u32 size; + u16 checksum; + u8 hw_pid[6]; + u8 hw_vid[3]; + u8 fw_pid[8]; + u8 fw_vid[4]; + u8 subsys_num; + u8 chip_type; + u8 protocol_ver; + u8 reserved[2]; + struct fw_subsys_info subsys[FW_SUBSYS_MAX_NUM]; +}; + +#pragma pack() + +/** + * firmware_data - firmware data structure + * @fw_info: firmware infomation + * @firmware: firmware data structure + */ +struct firmware_data { + struct firmware_info fw_info; + const struct firmware *firmware; +}; + +enum update_status { + UPSTA_NOTWORK = 0, + UPSTA_PREPARING, + UPSTA_UPDATING, + UPSTA_ABORT, + UPSTA_SUCCESS, + UPSTA_FAILED +}; + +/** + * fw_update_ctrl - sturcture used to control the + * firmware update process + * @status: update status + * @progress: indicate the progress of update + * @allow_reset: control the reset callback + * @allow_irq: control the irq callback + * @allow_suspend: control the suspend callback + * @allow_resume: allow resume callback + * @fw_data: firmware data + * @ts_dev: touch device + * @fw_name: firmware name + * @attr_fwimage: sysfs bin attrs, for storing fw image + * @fw_from_sysfs: whether the firmware image is loadind + * from sysfs + */ +struct fw_update_ctrl { + enum update_status status; + unsigned int progress; + bool force_update; + bool allow_reset; + bool allow_irq; + bool allow_suspend; + bool allow_resume; + struct firmware_data fw_data; + struct goodix_ts_device *ts_dev; + struct goodix_ts_core *core_data; + char fw_name[32]; + struct bin_attribute attr_fwimage; + bool fw_from_sysfs; +}; + +/** + * goodix_parse_firmware - parse firmware header infomation + * and subsystem infomation from firmware data buffer + * + * @fw_data: firmware struct, contains firmware header info + * and firmware data. + * return: 0 - OK, < 0 - error + */ +static int goodix_parse_firmware(struct firmware_data *fw_data) +{ + const struct firmware *firmware; + struct firmware_info *fw_info; + unsigned int i, fw_offset, info_offset; + u16 checksum; + int r = 0; + + if (!fw_data || !fw_data->firmware) { + ts_err("Invalid goodix firmware data"); + return -EINVAL; + } + fw_info = &fw_data->fw_info; + + /* copy firmware head info */ + firmware = fw_data->firmware; + if (firmware->size < FW_SUBSYS_INFO_OFFSET) { + ts_err("Invalid goodix firmware size:%zu", firmware->size); + r = -EINVAL; + goto err_size; + } + memcpy(fw_info, firmware->data, FW_SUBSYS_INFO_OFFSET); + + /* check firmware size */ + fw_info->size = be32_to_cpu(fw_info->size); + if (firmware->size != fw_info->size + 6) { + ts_err("Bad goodix firmware, size not match"); + r = -EINVAL; + goto err_size; + } + + /* calculate checksum, note: sum of bytes, but check + * by u16 checksum */ + for (i = 6, checksum = 0; i < firmware->size; i++) + checksum += firmware->data[i]; + + /* byte order change, and check */ + fw_info->checksum = be16_to_cpu(fw_info->checksum); + if (checksum != fw_info->checksum) { + ts_err("Bad goodix firmware, cheksum error"); + r = -EINVAL; + goto err_size; + } + + if (fw_info->subsys_num > FW_SUBSYS_MAX_NUM) { + ts_err("Bad goodix firmware, invalid subsys num: %d", + fw_info->subsys_num); + r = -EINVAL; + goto err_size; + } + + /* parse subsystem info */ + fw_offset = FW_HEADER_SIZE; + for (i = 0; i < fw_info->subsys_num; i++) { + info_offset = FW_SUBSYS_INFO_OFFSET + i * FW_SUBSYS_INFO_SIZE; + fw_info->subsys[i].type = firmware->data[info_offset]; + fw_info->subsys[i].size = be32_to_cpup( + (__be32 *)&firmware->data[info_offset + 1]); + fw_info->subsys[i].flash_addr = be16_to_cpup( + (__be16 *)&firmware->data[info_offset + 5]); + if (fw_offset > firmware->size) { + ts_err("Sybsys offset exceed Firmware size"); + goto err_size; + } + fw_info->subsys[i].data = firmware->data + fw_offset; + fw_offset += fw_info->subsys[i].size; + } + + ts_info("Firmware package protocol: V%u", fw_info->protocol_ver); + ts_info("Fimware PID:GT%s", fw_info->fw_pid); + ts_info("Fimware VID:0x%02X %02X %02X %02x", fw_info->fw_vid[0], + fw_info->fw_vid[1], fw_info->fw_vid[2], fw_info->fw_vid[3]); + ts_info("Firmware chip type:0x%02X", fw_info->chip_type); + ts_info("Firmware size:%u", fw_info->size); + ts_info("Firmware subsystem num:%u", fw_info->subsys_num); +#ifdef CONFIG_GOODIX_DEBUG + for (i = 0; i < fw_info->subsys_num; i++) { + ts_debug("------------------------------------------"); + ts_debug("Index:%d", i); + ts_debug("Subsystem type:0x%02X", fw_info->subsys[i].type); + ts_debug("Subsystem size:%u", fw_info->subsys[i].size); + ts_debug("Subsystem flash_addr:0x%08X", + fw_info->subsys[i].flash_addr); + ts_debug("Subsystem Ptr:%p", fw_info->subsys[i].data); + } + ts_debug("------------------------------------------"); +#endif + +err_size: + return r; +} + +/** + * goodix_check_update - compare the version of firmware running in + * touch device with the version getting from the firmware file. + * @fw_info: firmware infomation to be compared + * return: 0 firmware in the touch device needs to be updated + * < 0 no need to update firmware + */ +static int goodix_check_update(struct goodix_ts_device *dev, + const struct firmware_info *fw_info) +{ + struct goodix_ts_version fw_ver; + /*u8 fwimg_cid;*/ + int r = 0; + int res = 0; + + /* read version from chip, if we got invalid + * firmware version, maybe fimware in flash is + * incorrect, so we need to update firmware */ + r = dev->hw_ops->read_version(dev, &fw_ver); + if (r == -EBUS) + return r; + + if (fw_ver.valid) { + ts_info("pid_len=%d\n", dev->reg.pid_len); + ts_info("tp.pid=%s fw.pid=%s\n", fw_ver.pid, fw_info->fw_pid); + if (memcmp(fw_ver.pid, fw_info->fw_pid, dev->reg.pid_len)) { + ts_err("tp.pid=0x%x fw.pid=0x%x\n", fw_ver.pid, + fw_info->fw_pid); + ts_err("Product ID is not match"); + return -EPERM; + } + + ts_info("vid_len=%d\n", dev->reg.vid_len); + ts_info("Touchpanel VID:0x%02x 0x%02x 0x%02x 0x%02x", + fw_ver.vid[0], fw_ver.vid[1], fw_ver.vid[2], + fw_ver.vid[3]); + ts_info("Fimware VID:0x%02X 0x%02x 0x%02x 0x%02x", + fw_info->fw_vid[0], fw_info->fw_vid[1], + fw_info->fw_vid[2], fw_info->fw_vid[3]); + res = memcmp(fw_ver.vid, fw_info->fw_vid, dev->reg.vid_len); + if (res == 0) { + ts_err("FW version is equal to the IC's"); + return -EPERM; + } else { + ts_info("tp version not equal firmware version\n"); + } + } /* else invalid firmware, update firmware */ + + ts_info("Firmware needs to be updated"); + return 0; +} + +/** + * goodix_reg_write_confirm - write register and confirm the value + * in the register. + * @dev: pointer to touch device + * @addr: register address + * @data: pointer to data buffer + * @len: data length + * return: 0 write success and confirm ok + * < 0 failed + */ +static int goodix_reg_write_confirm(struct goodix_ts_device *dev, + unsigned int addr, unsigned char *data, + unsigned int len) +{ + u8 *cfm, cfm_buf[32]; + int r, i; + + if (len > sizeof(cfm_buf)) { + cfm = kzalloc(len, GFP_KERNEL); + if (!cfm) { + ts_err("Mem alloc failed"); + return -ENOMEM; + } + } else { + cfm = &cfm_buf[0]; + } + + for (i = 0; i < GOODIX_BUS_RETRY_TIMES; i++) { + r = dev->hw_ops->write_trans(dev, addr, data, len); + if (r < 0) + goto exit; + + r = dev->hw_ops->read_trans(dev, addr, cfm, len); + if (r < 0) + goto exit; + + if (memcmp(data, cfm, len)) { + r = -EMEMCMP; + continue; + } else { + r = 0; + break; + } + } + +exit: + if (cfm != &cfm_buf[0]) + kfree(cfm); + return r; +} + +static inline int goodix_reg_write(struct goodix_ts_device *dev, + unsigned int addr, unsigned char *data, + unsigned int len) +{ + return dev->hw_ops->write_trans(dev, addr, data, len); +} + +static inline int goodix_reg_read(struct goodix_ts_device *dev, + unsigned int addr, unsigned char *data, + unsigned int len) +{ + return dev->hw_ops->read_trans(dev, addr, data, len); +} +/** + * goodix_load_isp - load ISP program to deivce ram + * @dev: pointer to touch device + * @fw_data: firmware data + * return 0 ok, <0 error + */ +static int goodix_load_isp(struct goodix_ts_device *ts_dev, + struct firmware_data *fw_data) +{ + struct fw_subsys_info *fw_isp; + u8 reg_val[8] = { 0x00 }; + int r; + int i; + + fw_isp = &fw_data->fw_info.subsys[0]; + ts_info("Loading ISP start"); + /* select bank0 */ + reg_val[0] = 0x00; + r = goodix_reg_write(ts_dev, HW_REG_BANK_SELECT, reg_val, 1); + if (r < 0) { + ts_err("Failed to select bank0"); + return r; + } + ts_debug("Success select bank0, Set 0x%x -->0x00", HW_REG_BANK_SELECT); + + /* enable bank0 access */ + reg_val[0] = 0x01; + r = goodix_reg_write(ts_dev, HW_REG_ACCESS_PATCH0, reg_val, 1); + if (r < 0) { + ts_err("Failed to enable patch0 access"); + return r; + } + ts_debug("Success select bank0, Set 0x%x -->0x01", + HW_REG_ACCESS_PATCH0); + r = goodix_reg_write_confirm(ts_dev, HW_REG_ISP_ADDR, + (u8 *)fw_isp->data, fw_isp->size); + if (r < 0) { + ts_err("Loading ISP error"); + return r; + } + ts_debug("Success send ISP data to IC"); + + /* forbid patch access */ + reg_val[0] = 0x00; + r = goodix_reg_write_confirm(ts_dev, HW_REG_ACCESS_PATCH0, reg_val, 1); + if (r < 0) { + ts_err("Failed to disable patch0 access"); + return r; + } + ts_debug("Success forbit bank0 accedd, set 0x%x -->0x00", + HW_REG_ACCESS_PATCH0); + + /*clear 0x6006*/ + reg_val[0] = 0x00; + reg_val[1] = 0x00; + r = goodix_reg_write(ts_dev, HW_REG_ISP_RUN_FLAG, reg_val, 2); + if (r < 0) { + ts_err("Failed to clear 0x%x", HW_REG_ISP_RUN_FLAG); + return r; + } + ts_debug("Success clear 0x%x", HW_REG_ISP_RUN_FLAG); + + /* TODO: change address 0xBDE6 set backdoor flag HW_REG_CPU_RUN_FROM */ + memset(reg_val, 0x55, 8); + r = goodix_reg_write(ts_dev, HW_REG_CPU_RUN_FROM, reg_val, 8); + if (r < 0) { + ts_err("Failed set backdoor flag"); + return r; + } + ts_debug("Success write [8]0x55 to 0x%x", HW_REG_CPU_RUN_FROM); + /* TODO: change reg_val 0x08---> 0x00 release ss51 */ + reg_val[0] = 0x00; + r = goodix_reg_write(ts_dev, HW_REG_CPU_CTRL, reg_val, 1); + if (r < 0) { + ts_err("Failed to run isp"); + return r; + } + ts_debug("Success run isp, set 0x%x-->0x00", HW_REG_CPU_CTRL); + + /* check isp work state */ + for (i = 0; i < TS_CHECK_ISP_STATE_RETRY_TIMES; i++) { + r = goodix_reg_read(ts_dev, HW_REG_ISP_RUN_FLAG, reg_val, 2); + if (r < 0 || (reg_val[0] == 0xAA && reg_val[1] == 0xBB)) + break; + usleep_range(5000, 5100); + } + if (reg_val[0] == 0xAA && reg_val[1] == 0xBB) { + ts_info("ISP working OK"); + return 0; + } else { + ts_err("ISP not work,0x%x=0x%x, 0x%x=0x%x", HW_REG_ISP_RUN_FLAG, + reg_val[0], HW_REG_ISP_RUN_FLAG + 1, reg_val[1]); + return -EFAULT; + } +} + +/** + * goodix_update_prepare - update prepare, loading ISP program + * and make sure the ISP is running. + * @fwu_ctrl: pointer to fimrware control structure + * return: 0 ok, <0 error + */ +static int goodix_update_prepare(struct fw_update_ctrl *fwu_ctrl) +{ + struct goodix_ts_device *ts_dev = fwu_ctrl->ts_dev; + u8 reg_val[4] = { 0x00 }; + u8 temp_buf[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + int retry = 20; + int r; + + ts_dev->hw_ops->write(ts_dev, HW_REG_CPU_RUN_FROM, temp_buf, 8); + + /*reset IC*/ + fwu_ctrl->allow_reset = true; + ts_info("normandy firmware update, reset"); + gpio_direction_output(ts_dev->board_data->reset_gpio, 0); + udelay(2000); + gpio_direction_output(ts_dev->board_data->reset_gpio, 1); + usleep_range(10000, 11000); + fwu_ctrl->allow_reset = false; + + retry = 20; + do { + /*r = goodix_reg_read(ts_dev, addr + index, temp_buf, rlen); + if (r < 0) { + ts_err("Failed read back addr 0x%x", addr + index); + goto err_out; + }*/ + reg_val[0] = 0x24; + r = goodix_reg_write_confirm(ts_dev, HW_REG_CPU_CTRL, reg_val, + 1); + if (r < 0) { + ts_info("Failed to hold ss51, retry"); + msleep(20); + } else { + break; + } + } while (--retry); + if (!retry) { + ts_err("Failed hold ss51,return =%d", r); + return -EINVAL; + } + ts_debug("Success hold ss51"); + + /* enable DSP & MCU power */ + reg_val[0] = 0x00; + r = goodix_reg_write_confirm(ts_dev, HW_REG_DSP_MCU_POWER, reg_val, 1); + if (r < 0) { + ts_err("Failed enable DSP&MCU power"); + return r; + } + ts_debug("Success enabled DSP&MCU power,set 0x%x-->0x00", + HW_REG_DSP_MCU_POWER); + + /* disable watchdog timer */ + reg_val[0] = 0x00; + r = goodix_reg_write(ts_dev, HW_REG_CACHE, reg_val, 1); + if (r < 0) { + ts_err("Failed to clear cache"); + return r; + } + ts_debug("Success clear cache"); + + reg_val[0] = 0x95; + r = goodix_reg_write(ts_dev, HW_REG_ESD_KEY, reg_val, 1); + reg_val[0] = 0x00; + r |= goodix_reg_write(ts_dev, HW_REG_WTD_TIMER, reg_val, 1); + + reg_val[0] = 0x27; + r |= goodix_reg_write(ts_dev, HW_REG_ESD_KEY, reg_val, 1); + if (r < 0) { + ts_err("Failed to disable watchdog"); + return r; + } + ts_debug("Success disable watchdog"); + + /* set scramble */ + reg_val[0] = 0x00; + r = goodix_reg_write(ts_dev, HW_REG_SCRAMBLE, reg_val, 1); + if (r < 0) { + ts_err("Failed to set scramble"); + return r; + } + ts_debug("Succcess set scramble"); + /* load ISP code and run form isp */ + r = goodix_load_isp(ts_dev, &fwu_ctrl->fw_data); + if (r < 0) + ts_err("Failed lode and run isp"); + return r; +} + +/** + * goodix_format_fw_packet - formate one flash packet + * @pkt: target firmware packet + * @flash_addr: flash address + * @size: packet size + * @data: packet data + */ +static int goodix_format_fw_packet(u8 *pkt, u32 flash_addr, u16 len, + const u8 *data) +{ + u16 checksum; + if (!pkt || !data) + return -EINVAL; + + /* + * checksum rule:sum of data in one format is equal to zero + * data format: byte/le16/be16/le32/be32/le64/be64 + */ + pkt[0] = (len >> 8) & 0xff; + pkt[1] = len & 0xff; + pkt[2] = (flash_addr >> 16) & + 0xff; /* u16 >> 16bit seems nosense but really important */ + pkt[3] = (flash_addr >> 8) & 0xff; + memcpy(&pkt[4], data, len); + checksum = checksum_be16(pkt, len + 4); + checksum = 0 - checksum; + pkt[len + 4] = (checksum >> 8) & 0xff; + pkt[len + 5] = checksum & 0xff; + return 0; +} +/** + * goodix_send_fw_packet - send one firmware packet to ISP + * @dev: target touch device + * @pkt: firmware packet + * return:0 ok, <0 error + */ +static int goodix_send_fw_packet(struct goodix_ts_device *dev, u8 type, u8 *pkt, + u32 len) +{ + u8 reg_val[4]; + int r, i; + + if (!pkt) + return -EINVAL; + + r = goodix_reg_write_confirm(dev, HW_REG_ISP_BUFFER, pkt, len); + if (r < 0) { + ts_err("Failed to write firmware packet"); + return r; + } + + reg_val[0] = 0; + reg_val[1] = 0; + /* clear flash flag 0X6022 */ + r = goodix_reg_write_confirm(dev, HW_REG_FLASH_FLAG, reg_val, 2); + if (r < 0) { + ts_err("Faile to clear flash flag"); + return r; + } + + /* write subsystem type 0X8020*/ + reg_val[0] = type; + reg_val[1] = type; + r = goodix_reg_write_confirm(dev, HW_REG_SUBSYS_TYPE, reg_val, 2); + if (r < 0) { + ts_err("Failed write subsystem type to IC"); + return r; + } + + for (i = 0; i < TS_READ_FLASH_STATE_RETRY_TIMES; i++) { + r = goodix_reg_read(dev, HW_REG_FLASH_FLAG, reg_val, 2); + if (r < 0) { + ts_err("Failed read flash state"); + return r; + } + + /* flash haven't end */ + if (reg_val[0] == ISP_STAT_WRITING && + reg_val[1] == ISP_STAT_WRITING) { + ts_debug("Flash not ending..."); + usleep_range(55000, 56000); + continue; + } + if (reg_val[0] == ISP_FLASH_SUCCESS && + reg_val[1] == ISP_FLASH_SUCCESS) { + /* read twice to confirm the result */ + r = goodix_reg_read(dev, HW_REG_FLASH_FLAG, reg_val, 2); + if (!r && reg_val[0] == ISP_FLASH_SUCCESS && + reg_val[1] == ISP_FLASH_SUCCESS) { + /*r = goodix_read_back_check(dev, 0x8104, len - 6, (char*)pkt + 4); + if (r) { + ts_err("Read back compare failed"); + } else { + ts_info("Read back compare OK"); + }*/ + ts_info("Flash subsystem ok"); + return 0; + } + } + if (reg_val[0] == ISP_FLASH_ERROR && + reg_val[1] == ISP_FLASH_ERROR) { + ts_err(" Flash subsystem failed"); + return -EAGAIN; + } + if (reg_val[0] == ISP_FLASH_CHECK_ERROR) { + ts_err("Subsystem checksum err"); + return -EAGAIN; + } + usleep_range(250, 260); + } + + ts_err("Wait for flash end timeout, 0x6022= %x %x", reg_val[0], + reg_val[1]); + return -EAGAIN; +} + +/** + * goodix_flash_subsystem - flash subsystem firmware, + * Main flow of flashing firmware. + * Each firmware subsystem is divided into several + * packets, the max size of packet is limited to + * @{ISP_MAX_BUFFERSIZE} + * @dev: pointer to touch device + * @subsys: subsystem infomation + * return: 0 ok, < 0 error + */ +static int goodix_flash_subsystem(struct goodix_ts_device *dev, + struct fw_subsys_info *subsys) +{ + u16 data_size, offset; + u32 total_size; + u32 subsys_base_addr = subsys->flash_addr << 8; + u8 *fw_packet; + int r = 0, i; + + /* + * if bus(i2c/spi) error occued, then exit, we will do + * hardware reset and re-prepare ISP and then retry + * flashing + */ + total_size = subsys->size; + fw_packet = kzalloc(ISP_MAX_BUFFERSIZE + 6, GFP_KERNEL); + if (!fw_packet) { + ts_err("Failed alloc memory"); + return -EINVAL; + } + + offset = 0; + while (total_size > 0) { + data_size = total_size > ISP_MAX_BUFFERSIZE ? + ISP_MAX_BUFFERSIZE : + total_size; + ts_info("Flash firmware to %08x,size:%u bytes", + subsys_base_addr + offset, data_size); + + /* format one firmware packet */ + r = goodix_format_fw_packet(fw_packet, + subsys_base_addr + offset, + data_size, &subsys->data[offset]); + if (r < 0) { + ts_err("Invalid packet params"); + goto exit; + } + + /* send one firmware packet, retry 3 time if send failed */ + for (i = 0; i < 3; i++) { + r = goodix_send_fw_packet(dev, subsys->type, fw_packet, + data_size + 6); + if (!r) + break; + } + if (r) { + ts_err("Failed flash subsystem"); + goto exit; + } + offset += data_size; + total_size -= data_size; + } /* end while */ + +exit: + kfree(fw_packet); + return r; +} + +/** + * goodix_flash_firmware - flash firmware + * @dev: pointer to touch device + * @fw_data: firmware data + * return: 0 ok, < 0 error + */ +static int goodix_flash_firmware(struct goodix_ts_device *dev, + struct firmware_data *fw_data) +{ + struct fw_update_ctrl *fw_ctrl; + struct firmware_info *fw_info; + struct fw_subsys_info *fw_x; + int retry = GOODIX_BUS_RETRY_TIMES; + int i, r = 0, fw_num, prog_step; + + /* start from subsystem 1, + * subsystem 0 is the ISP program */ + fw_ctrl = container_of(fw_data, struct fw_update_ctrl, fw_data); + fw_info = &fw_data->fw_info; + fw_num = fw_info->subsys_num; + + /* we have 80% work here */ + prog_step = 80 / (fw_num - 1); + + for (i = 1; i < fw_num && retry;) { + ts_info("--- Start to flash subsystem[%d] ---", i); + fw_x = &fw_info->subsys[i]; + r = goodix_flash_subsystem(dev, fw_x); + if (r == 0) { + ts_info("--- End flash subsystem[%d]: OK ---", i); + fw_ctrl->progress += prog_step; + i++; + } else if (r == -EAGAIN) { + retry--; + ts_err("--- End flash subsystem%d: Fail, errno:%d, retry:%d ---", + i, r, GOODIX_BUS_RETRY_TIMES - retry); + } else if (r < 0) { /* bus error */ + ts_err("--- End flash subsystem%d: Fatal error:%d exit ---", + i, r); + goto exit_flash; + } + } + +exit_flash: + return r; +} + +/** + * goodix_update_finish - update finished, free resource + * and reset flags--- + * @fwu_ctrl: pointer to fw_update_ctrl structrue + * return: 0 ok, < 0 error + */ +static int goodix_update_finish(struct goodix_ts_device *ts_dev, + struct fw_update_ctrl *fwu_ctrl) +{ + u8 reg_val[8] = { 0 }; + int r = 0; + + /* hold ss51 */ + reg_val[0] = 0x24; + r = goodix_reg_write(ts_dev, HW_REG_CPU_CTRL, reg_val, 1); + if (r < 0) + ts_err("Failed to hold ss51"); + + /* clear back door flag */ + memset(reg_val, 0, sizeof(reg_val)); + r = goodix_reg_write(ts_dev, HW_REG_CPU_RUN_FROM, reg_val, 8); + if (r) { + ts_err("Failed set CPU run from normal firmware"); + return r; + } + + /* release ss51 */ + reg_val[0] = 0x00; + r = goodix_reg_write(ts_dev, HW_REG_CPU_CTRL, reg_val, 1); + if (r < 0) + ts_err("Failed to run ss51"); + + /*reset*/ + r = ts_dev->hw_ops->reset(ts_dev); + + return r; +} + +/** + * goodix_fw_update_proc - firmware update process, the entry of + * firmware update flow + * @fwu_ctrl: firmware control + * return: 0 ok, < 0 error + */ +int goodix_fw_update_proc(struct fw_update_ctrl *fwu_ctrl) +{ + int retry0 = FW_UPDATE_RETRY; + int retry1 = FW_UPDATE_RETRY; + int r = 0; + + if (fwu_ctrl->status == UPSTA_PREPARING || + fwu_ctrl->status == UPSTA_UPDATING) { + ts_err("Firmware update already in progress"); + return 0; + } + + fwu_ctrl->progress = 0; + fwu_ctrl->status = UPSTA_PREPARING; + + r = goodix_parse_firmware(&fwu_ctrl->fw_data); + if (r < 0) { + fwu_ctrl->status = UPSTA_ABORT; + goto err_parse_fw; + } + + /* TODO: set force update flag*/ + /*fwu_ctrl->force_update = true;*/ + fwu_ctrl->progress = 10; + if (fwu_ctrl->force_update == false) { + r = goodix_check_update(fwu_ctrl->ts_dev, + &fwu_ctrl->fw_data.fw_info); + if (r < 0) { + fwu_ctrl->status = UPSTA_ABORT; + goto err_check_update; + } + } + +start_update: + fwu_ctrl->progress = 20; + fwu_ctrl->status = UPSTA_UPDATING; /* show upgrading status */ + r = goodix_update_prepare(fwu_ctrl); + if ((r == -EBUS || r == -EAGAIN) && --retry0 > 0) { + ts_err("Bus error, retry prepare ISP:%d", + FW_UPDATE_RETRY - retry0); + goto start_update; + } else if (r < 0) { + ts_err("Failed to prepare ISP, exit update:%d", r); + fwu_ctrl->status = UPSTA_FAILED; + goto err_fw_prepare; + } + + /* progress: 20%~100% */ + r = goodix_flash_firmware(fwu_ctrl->ts_dev, &fwu_ctrl->fw_data); + if ((r == -EBUS || r == -ETIMEOUT) && --retry1 > 0) { + /* we will retry[twice] if returns bus error[i2c/spi] + * we will do hardware reset and re-prepare ISP and then retry + * flashing + */ + ts_err("Bus error, retry firmware update:%d", + FW_UPDATE_RETRY - retry1); + goto start_update; + } else if (r < 0) { + ts_err("Fatal error, exit update:%d", r); + fwu_ctrl->status = UPSTA_FAILED; + goto err_fw_flash; + } + fwu_ctrl->status = UPSTA_SUCCESS; + +err_fw_flash: +err_fw_prepare: + goodix_update_finish(fwu_ctrl->ts_dev, fwu_ctrl); +err_check_update: +err_parse_fw: + if (fwu_ctrl->status == UPSTA_SUCCESS) + ts_info("Firmware update successfully"); + else if (fwu_ctrl->status == UPSTA_FAILED) + ts_err("Firmware update failed"); + fwu_ctrl->progress = 100; /* 100% */ + return r; +} +/* COMMON PART - END */ + +static struct goodix_ext_module goodix_fwu_module; + +/** + * goodix_request_firmware - request firmware data from user space + * + * @fw_data: firmware struct, contains firmware header info + * and firmware data pointer. + * return: 0 - OK, < 0 - error + */ +static int goodix_request_firmware(struct firmware_data *fw_data, + const char *name) +{ + struct fw_update_ctrl *fw_ctrl = + container_of(fw_data, struct fw_update_ctrl, fw_data); + struct device *dev = fw_ctrl->ts_dev->dev; + int r; + + ts_info("Request firmware image [%s]", name); + r = request_firmware(&fw_data->firmware, name, dev); + ts_info("Request firmware r = %d\n", r); + if (r < 0) + ts_err("Firmware image [%s] not available,errno:%d", name, r); + else + ts_info("Firmware image [%s] is ready", name); + return r; +} + +/** + * relase firmware resources + * + */ +static inline void goodix_release_firmware(struct firmware_data *fw_data) +{ + if (fw_data->firmware) { + release_firmware(fw_data->firmware); + fw_data->firmware = NULL; + } +} + +static int goodix_fw_update_thread(void *data) +{ + struct fw_update_ctrl *fwu_ctrl = data; + struct firmware *temp_firmware = NULL; + static DEFINE_MUTEX(fwu_lock); + int r; + + ts_err("%s:start\n", __func__); + if (!fwu_ctrl) { + ts_err("Invaid thread params"); + goodix_unregister_ext_module(&goodix_fwu_module); + return 0; + } + + mutex_lock(&fwu_lock); + if (!fwu_ctrl->fw_from_sysfs) { + if (atomic_read(&fw_update_mode) == 0) { + ts_info("goodix Firmware header update starts"); + temp_firmware = + kzalloc(sizeof(struct firmware), GFP_KERNEL); + if (!temp_firmware) { + ts_err("Failed to allocate memory for firmware"); + goto out; + } + temp_firmware->size = sizeof(goodix_default_fw); + temp_firmware->data = goodix_default_fw; + fwu_ctrl->fw_data.firmware = temp_firmware; + } else if (atomic_read(&fw_update_mode) == 1) { + ts_info("goodix Firmware request update starts"); + r = goodix_request_firmware(&fwu_ctrl->fw_data, + fwu_ctrl->fw_name); + if (r < 0) { + fwu_ctrl->status = UPSTA_ABORT; + fwu_ctrl->progress = 100; + goto out; + } + } + } else { + if (!fwu_ctrl->fw_data.firmware) { + ts_err("Invalid goodix firmware from sysfs"); + fwu_ctrl->status = UPSTA_ABORT; + fwu_ctrl->progress = 100; + goto out; + } + } + + /* DONT allow reset/irq/suspend/resume during update */ + fwu_ctrl->allow_irq = false; + fwu_ctrl->allow_suspend = false; + fwu_ctrl->allow_resume = false; + fwu_ctrl->allow_reset = false; + goodix_ts_blocking_notify(NOTIFY_FWUPDATE_START, NULL); + + /* ready to update */ + goodix_fw_update_proc(fwu_ctrl); + + goodix_ts_blocking_notify(NOTIFY_FWUPDATE_END, NULL); + fwu_ctrl->allow_reset = true; + fwu_ctrl->allow_irq = true; + fwu_ctrl->allow_suspend = true; + fwu_ctrl->allow_resume = true; + + /* clean */ + if (!fwu_ctrl->fw_from_sysfs) { + if (atomic_read(&fw_update_mode) == 0) { + kfree(fwu_ctrl->fw_data.firmware); + fwu_ctrl->fw_data.firmware = NULL; + temp_firmware = NULL; + } else if (atomic_read(&fw_update_mode) == 1) { + goodix_release_firmware(&fwu_ctrl->fw_data); + } + } else { + fwu_ctrl->fw_from_sysfs = false; + vfree(fwu_ctrl->fw_data.firmware); + fwu_ctrl->fw_data.firmware = NULL; + if (atomic_read(&fw_update_mode) == 0) + temp_firmware = NULL; + } + + /*parse cfg_group.bin*/ + if (!fwu_ctrl->core_data->cfg_group_parsed) + goodix_cfg_bin_proc(fwu_ctrl->core_data); + +out: + goodix_unregister_ext_module(&goodix_fwu_module); + mutex_unlock(&fwu_lock); + atomic_set(&fw_update_mode, 0); + return 0; +} +/* sysfs attributes */ +static ssize_t goodix_sysfs_update_en_store(struct goodix_ext_module *module, + const char *buf, size_t count) +{ + int val = 0, r; + r = sscanf(buf, "%d", &val); + if (r < 0) + return r; + if (r) { + atomic_set(&fw_update_mode, 1); + if (goodix_register_ext_module(&goodix_fwu_module)) + return -EIO; + } + return count; +} + +static ssize_t +goodix_sysfs_update_progress_show(struct goodix_ext_module *module, char *buf) +{ + struct fw_update_ctrl *fw_ctrl = module->priv_data; + return scnprintf(buf, PAGE_SIZE, "%d\n", fw_ctrl->progress); +} + +static ssize_t goodix_sysfs_update_result_show(struct goodix_ext_module *module, + char *buf) +{ + char *result = NULL; + struct fw_update_ctrl *fw_ctrl = module->priv_data; + + ts_info("result show"); + switch (fw_ctrl->status) { + case UPSTA_NOTWORK: + result = "notwork"; + break; + case UPSTA_PREPARING: + result = "preparing"; + break; + case UPSTA_UPDATING: + result = "upgrading"; + break; + case UPSTA_ABORT: + result = "abort"; + break; + case UPSTA_SUCCESS: + result = "success"; + break; + case UPSTA_FAILED: + result = "failed"; + break; + default: + break; + } + + return scnprintf(buf, PAGE_SIZE, "%s\n", result); +} + +static ssize_t +goodix_sysfs_update_fwversion_show(struct goodix_ext_module *module, char *buf) +{ + struct goodix_ts_version fw_ver; + struct fw_update_ctrl *fw_ctrl = module->priv_data; + int r = 0; + char str[5]; + + /* read version from chip */ + r = fw_ctrl->ts_dev->hw_ops->read_version(fw_ctrl->ts_dev, &fw_ver); + if (!r) { + memcpy(str, fw_ver.pid, 4); + str[4] = '\0'; + return scnprintf( + buf, PAGE_SIZE, + "PID:%s VID:%02x %02x %02x %02x SENSOR_ID:%d\n", str, + fw_ver.vid[0], fw_ver.vid[1], fw_ver.vid[2], + fw_ver.vid[3], fw_ver.sensor_id); + } + return 0; +} + +static ssize_t goodix_sysfs_fwsize_show(struct goodix_ext_module *module, + char *buf) +{ + struct fw_update_ctrl *fw_ctrl = module->priv_data; + int r = -EINVAL; + + if (fw_ctrl && fw_ctrl->fw_data.firmware) + r = snprintf(buf, PAGE_SIZE, "%zu\n", + fw_ctrl->fw_data.firmware->size); + return r; +} + +static ssize_t goodix_sysfs_fwsize_store(struct goodix_ext_module *module, + const char *buf, size_t count) +{ + struct fw_update_ctrl *fw_ctrl = module->priv_data; + struct firmware *fw; + u8 **data; + size_t size = 0; + + if (!fw_ctrl) + return -EINVAL; + + if (sscanf(buf, "%zu", &size) < 0 || !size) { + ts_err("Failed to get fwsize"); + return -EFAULT; + } + + fw = vmalloc(sizeof(*fw) + size); + if (fw == NULL) { + ts_err("Failed to alloc memory,size:%zu", size + sizeof(*fw)); + return -ENOMEM; + } + + memset(fw, 0x00, sizeof(*fw) + size); + data = (u8 **)&fw->data; + *data = (u8 *)fw + sizeof(struct firmware); + fw->size = size; + fw_ctrl->fw_data.firmware = fw; + fw_ctrl->fw_from_sysfs = true; + return count; +} + +static ssize_t goodix_sysfs_fwimage_store(struct file *file, + struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t pos, size_t count) +{ + struct fw_update_ctrl *fw_ctrl; + struct firmware_data *fw_data; + + fw_ctrl = container_of(attr, struct fw_update_ctrl, attr_fwimage); + fw_data = &fw_ctrl->fw_data; + + if (!fw_data->firmware) { + ts_err("Need set fw image size first"); + return -ENOMEM; + } + + if (fw_data->firmware->size == 0) { + ts_err("Invalid firmware size"); + return -EINVAL; + } + + if (pos + count > fw_data->firmware->size) + return -EFAULT; + memcpy((u8 *)&fw_data->firmware->data[pos], buf, count); + fw_ctrl->force_update = true; + return count; +} + +static ssize_t goodix_sysfs_force_update_store(struct goodix_ext_module *module, + const char *buf, size_t count) +{ + struct fw_update_ctrl *fw_ctrl = module->priv_data; + int val = 0, r; + + r = sscanf(buf, "%d", &val); + if (r < 0) + return r; + if (r) + fw_ctrl->force_update = true; + else + fw_ctrl->force_update = false; + return count; +} + +static struct goodix_ext_attribute goodix_fwu_attrs[] = { + __EXTMOD_ATTR(update_en, S_IWUGO, NULL, goodix_sysfs_update_en_store), + __EXTMOD_ATTR(progress, S_IRUGO, goodix_sysfs_update_progress_show, + NULL), + __EXTMOD_ATTR(result, S_IRUGO, goodix_sysfs_update_result_show, NULL), + __EXTMOD_ATTR(fwversion, S_IRUGO, goodix_sysfs_update_fwversion_show, + NULL), + __EXTMOD_ATTR(fwsize, S_IRUGO | S_IWUGO, goodix_sysfs_fwsize_show, + goodix_sysfs_fwsize_store), + __EXTMOD_ATTR(force_update, S_IWUGO, NULL, + goodix_sysfs_force_update_store), +}; + +static int goodix_syfs_init(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + struct fw_update_ctrl *fw_ctrl = module->priv_data; + struct kobj_type *ktype; + int ret = 0, i; + + ktype = goodix_get_default_ktype(); + ret = kobject_init_and_add(&module->kobj, ktype, + &core_data->pdev->dev.kobj, "fwupdate"); + if (ret) { + ts_err("Create fwupdate sysfs node error!"); + goto exit_sysfs_init; + } + + for (i = 0; i < ARRAY_SIZE(goodix_fwu_attrs); i++) { + if (sysfs_create_file(&module->kobj, + &goodix_fwu_attrs[i].attr)) { + ts_err("Create sysfs attr file error"); + kobject_put(&module->kobj); + ret = -EINVAL; + goto exit_sysfs_init; + } + } + + fw_ctrl->attr_fwimage.attr.name = "fwimage"; + fw_ctrl->attr_fwimage.attr.mode = S_IRUGO | S_IWUGO; + fw_ctrl->attr_fwimage.size = 0; + fw_ctrl->attr_fwimage.write = goodix_sysfs_fwimage_store; + ret = sysfs_create_bin_file(&module->kobj, &fw_ctrl->attr_fwimage); + +exit_sysfs_init: + return ret; +} + +static int goodix_fw_update_init(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + struct goodix_ts_board_data *ts_bdata = board_data(core_data); + struct task_struct *fwu_thrd; + struct fw_update_ctrl *fwu_ctrl; + static bool init_sysfs = true; + + if (!core_data->ts_dev) + return -ENODEV; + + if (!module->priv_data) { + module->priv_data = + kzalloc(sizeof(struct fw_update_ctrl), GFP_KERNEL); + if (!module->priv_data) { + ts_err("Failed to alloc memory for fwu_ctrl"); + return -ENOMEM; + } + } + fwu_ctrl = module->priv_data; + fwu_ctrl->ts_dev = core_data->ts_dev; + fwu_ctrl->allow_reset = true; + fwu_ctrl->allow_irq = true; + fwu_ctrl->allow_suspend = true; + fwu_ctrl->allow_resume = true; + fwu_ctrl->core_data = core_data; + + /* find a valid firmware image name */ + if (ts_bdata && ts_bdata->fw_name) { + strlcpy(fwu_ctrl->fw_name, ts_bdata->fw_name, + sizeof(fwu_ctrl->fw_name)); + ts_info("find goodix firmware:%s\n", ts_bdata->fw_name); + } else { + strlcpy(fwu_ctrl->fw_name, TS_DEFAULT_FIRMWARE, + sizeof(fwu_ctrl->fw_name)); + ts_info("can't find goodix firmware,use default name\n"); + } + + /* create sysfs interface */ + if (init_sysfs) { + if (!goodix_syfs_init(core_data, module)) + init_sysfs = false; + } + + /* create and run update thread */ + fwu_thrd = kthread_run(goodix_fw_update_thread, module->priv_data, + "goodix-fwu"); + if (IS_ERR_OR_NULL(fwu_thrd)) { + ts_err("goodix:Failed to create update thread:%ld", + PTR_ERR(fwu_thrd)); + return -EFAULT; + } + + return 0; +} + +static int goodix_fw_update_exit(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + return 0; +} + +static int goodix_fw_before_suspend(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + struct fw_update_ctrl *fwu_ctrl = module->priv_data; + + return fwu_ctrl->allow_suspend ? EVT_HANDLED : EVT_CANCEL_SUSPEND; +} + +static int goodix_fw_before_resume(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + struct fw_update_ctrl *fwu_ctrl = module->priv_data; + return fwu_ctrl->allow_resume ? EVT_HANDLED : EVT_CANCEL_RESUME; +} + +static int goodix_fw_after_resume(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + return 0; +} + +static int goodix_fw_irq_event(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + struct fw_update_ctrl *fwu_ctrl = module->priv_data; + return fwu_ctrl->allow_irq ? EVT_HANDLED : EVT_CANCEL_IRQEVT; +} + +static int goodix_fw_before_reset(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + struct fw_update_ctrl *fwu_ctrl = module->priv_data; + return fwu_ctrl->allow_reset ? EVT_HANDLED : EVT_CANCEL_RESET; +} + +static const struct goodix_ext_module_funcs goodix_ext_funcs = { + .init = goodix_fw_update_init, + .exit = goodix_fw_update_exit, + .before_reset = goodix_fw_before_reset, + .after_reset = NULL, + .before_suspend = goodix_fw_before_suspend, + .after_suspend = NULL, + .before_resume = goodix_fw_before_resume, + .after_resume = goodix_fw_after_resume, + .irq_event = goodix_fw_irq_event, +}; + +static struct goodix_ext_module goodix_fwu_module = { + .name = "goodix-fwu", + .funcs = &goodix_ext_funcs, + .priority = EXTMOD_PRIO_FWUPDATE, +}; + +static int __init goodix_fwu_module_init(void) +{ + pr_err("goodix firmware update module init start\n"); + return goodix_register_ext_module(&goodix_fwu_module); +} + +static void __exit goodix_fwu_module_exit(void) +{ + return; +} + +module_init(goodix_fwu_module_init); +module_exit(goodix_fwu_module_exit); + +MODULE_DESCRIPTION("Goodix FWU Module"); +MODULE_AUTHOR("Goodix, Inc."); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c new file mode 100644 index 000000000000..37eadcd09e81 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c @@ -0,0 +1,2910 @@ +/* + * Goodix Touchscreen Driver + * Core layer of touchdriver architecture. + * + * Copyright (C) 2015 - 2016 Goodix, Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * Authors: Yulong Cai + * + * 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. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_DRM +#include +#include +#include +#endif +#include +#include +//#include +#include "goodix_ts_core.h" + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) +#include +#define INPUT_TYPE_B_PROTOCOL +#endif +#include +#include "../xiaomi/xiaomi_touch.h" +#include "test_core/test_param_init.h" + +#define INPUT_EVENT_START 0 +#define INPUT_EVENT_SENSITIVE_MODE_OFF 0 +#define INPUT_EVENT_SENSITIVE_MODE_ON 1 +#define INPUT_EVENT_STYLUS_MODE_OFF 2 +#define INPUT_EVENT_STYLUS_MODE_ON 3 +#define INPUT_EVENT_WAKUP_MODE_OFF 4 +#define INPUT_EVENT_WAKUP_MODE_ON 5 +#define INPUT_EVENT_COVER_MODE_OFF 6 +#define INPUT_EVENT_COVER_MODE_ON 7 +#define INPUT_EVENT_SLIDE_FOR_VOLUME 8 +#define INPUT_EVENT_DOUBLE_TAP_FOR_VOLUME 9 +#define INPUT_EVENT_SINGLE_TAP_FOR_VOLUME 10 +#define INPUT_EVENT_LONG_SINGLE_TAP_FOR_VOLUME 11 +#define INPUT_EVENT_PALM_OFF 12 +#define INPUT_EVENT_PALM_ON 13 +#define INPUT_EVENT_END 13 +#define IS_USB_EXIST 0x06 +#define IS_USB_NOT_EXIST 0x07 + +#define GOOIDX_INPUT_PHYS "goodix_ts/input0" +#define PINCTRL_STATE_ACTIVE "pmx_ts_active" +#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend" +extern int goodix_start_cfg_bin(struct goodix_ts_core *ts_core); +extern int goodix_i2c_write(struct goodix_ts_device *dev, unsigned int reg, + unsigned char *data, unsigned int len); + +struct goodix_module goodix_modules; +struct goodix_ts_core *goodix_core_data; +/** + * __do_register_ext_module - register external module + * to register into touch core modules structure + */ +static void __do_register_ext_module(struct work_struct *work) +{ + struct goodix_ext_module *module = + container_of(work, struct goodix_ext_module, work); + struct goodix_ext_module *ext_module; + struct list_head *insert_point = &goodix_modules.head; + + ts_info("__do_register_ext_module IN, goodix_modules.core_exit:%d", + goodix_modules.core_exit); + + /* waitting for core layer */ + if (!wait_for_completion_timeout(&goodix_modules.core_comp, 25 * HZ)) { + ts_err("Module [%s] timeout", module->name); + return; + } + + /* driver probe failed */ + if (goodix_modules.core_exit) { + ts_err("Can't register ext_module, core exit"); + return; + } + ts_info("start register ext_module"); + /* prority level *must* be set */ + if (module->priority == EXTMOD_PRIO_RESERVED) { + ts_err("Priority of module [%s] needs to be set", module->name); + return; + } + + mutex_lock(&goodix_modules.mutex); + if (!list_empty(&goodix_modules.head)) { + list_for_each_entry(ext_module, &goodix_modules.head, list) { + if (ext_module == module) { + ts_info("Module [%s] already exists", + module->name); + mutex_unlock(&goodix_modules.mutex); + return; + } + } + + list_for_each_entry(ext_module, &goodix_modules.head, list) { + /* small value of priority have + * higher priority level*/ + if (ext_module->priority >= module->priority) { + insert_point = &ext_module->list; + break; + } + } /* else module will be inserted + to goodix_modules->head */ + } + + if (module->funcs && module->funcs->init) { + if (module->funcs->init(goodix_modules.core_data, module) < 0) { + ts_err("Module [%s] init error", + module->name ? module->name : " "); + mutex_unlock(&goodix_modules.mutex); + return; + } + } + list_add(&module->list, insert_point->prev); + goodix_modules.count++; + mutex_unlock(&goodix_modules.mutex); + ts_info("Module [%s] registered,priority:%u", module->name, + module->priority); + return; +} + +/** + * goodix_register_ext_module - interface for external module + * to register into touch core modules structure + * + * @module: pointer to external module to be register + * return: 0 ok, <0 failed + */ +int goodix_register_ext_module(struct goodix_ext_module *module) +{ + if (!module) + return -EINVAL; + + if (!goodix_modules.initilized) { + goodix_modules.initilized = true; + goodix_modules.core_exit = true; + INIT_LIST_HEAD(&goodix_modules.head); + mutex_init(&goodix_modules.mutex); + init_completion(&goodix_modules.core_comp); + } + + /*if (goodix_modules.core_exit) { + ts_err("Can't register ext_module, core exit"); + return -EFAULT; + } +*/ + ts_info("goodix_register_ext_module IN"); + INIT_WORK(&module->work, __do_register_ext_module); + schedule_work(&module->work); + ts_info("goodix_register_ext_module OUT"); + return 0; +} +EXPORT_SYMBOL_GPL(goodix_register_ext_module); + +/** + * goodix_unregister_ext_module - interface for external module + * to unregister external modules + * + * @module: pointer to external module + * return: 0 ok, <0 failed + */ +int goodix_unregister_ext_module(struct goodix_ext_module *module) +{ + struct goodix_ext_module *ext_module; + bool found = false; + if (!module) + return -EINVAL; + if (!goodix_modules.initilized) + return -EINVAL; + if (!goodix_modules.core_data) + return -ENODEV; + mutex_lock(&goodix_modules.mutex); + if (!list_empty(&goodix_modules.head)) { + list_for_each_entry(ext_module, &goodix_modules.head, list) { + if (ext_module == module) { + found = true; + break; + } + } + } else { + mutex_unlock(&goodix_modules.mutex); + return -EFAULT; + } + + if (!found) { + ts_err("Module [%s] never registed", module->name); + mutex_unlock(&goodix_modules.mutex); + return -EFAULT; + } + + list_del(&module->list); + mutex_unlock(&goodix_modules.mutex); + if (module->funcs && module->funcs->exit) + module->funcs->exit(goodix_modules.core_data, module); + goodix_modules.count--; + ts_info("Moudle [%s] unregistered", module->name ? module->name : " "); + return 0; +} +EXPORT_SYMBOL_GPL(goodix_unregister_ext_module); + +static void goodix_ext_sysfs_release(struct kobject *kobj) +{ + ts_info("Kobject released!"); +} + +#define to_ext_module(kobj) container_of(kobj, struct goodix_ext_module, kobj) +#define to_ext_attr(attr) container_of(attr, struct goodix_ext_attribute, attr) + +static ssize_t goodix_ext_sysfs_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct goodix_ext_module *module = to_ext_module(kobj); + struct goodix_ext_attribute *ext_attr = to_ext_attr(attr); + + if (ext_attr->show) + return ext_attr->show(module, buf); + return -EIO; +} + +static ssize_t goodix_ext_sysfs_store(struct kobject *kobj, + struct attribute *attr, const char *buf, + size_t count) +{ + struct goodix_ext_module *module = to_ext_module(kobj); + struct goodix_ext_attribute *ext_attr = to_ext_attr(attr); + + if (ext_attr->store) + return ext_attr->store(module, buf, count); + return -EIO; +} + +static const struct sysfs_ops goodix_ext_ops = { + .show = goodix_ext_sysfs_show, + .store = goodix_ext_sysfs_store +}; + +static struct kobj_type goodix_ext_ktype = { + .release = goodix_ext_sysfs_release, + .sysfs_ops = &goodix_ext_ops, +}; + +struct kobj_type *goodix_get_default_ktype(void) +{ + return &goodix_ext_ktype; +} +EXPORT_SYMBOL_GPL(goodix_get_default_ktype); + +struct kobject *goodix_get_default_kobj(void) +{ + struct kobject *kobj = NULL; + + if (goodix_modules.core_data && goodix_modules.core_data->pdev) + kobj = &goodix_modules.core_data->pdev->dev.kobj; + return kobj; +} +EXPORT_SYMBOL_GPL(goodix_get_default_kobj); + +/* debug fs */ +struct debugfs_buf { + struct debugfs_blob_wrapper buf; + int pos; + struct dentry *dentry; +} goodix_dbg; + +void goodix_msg_printf(const char *fmt, ...) +{ + va_list args; + int r; + + if (goodix_dbg.pos < goodix_dbg.buf.size) { + va_start(args, fmt); + r = vscnprintf(goodix_dbg.buf.data + goodix_dbg.pos, + goodix_dbg.buf.size - 1, fmt, args); + goodix_dbg.pos += r; + va_end(args); + } +} +EXPORT_SYMBOL_GPL(goodix_msg_printf); + +static int goodix_debugfs_init(void) +{ + struct dentry *r_b; + goodix_dbg.buf.size = PAGE_SIZE; + goodix_dbg.pos = 0; + goodix_dbg.buf.data = kzalloc(goodix_dbg.buf.size, GFP_KERNEL); + if (goodix_dbg.buf.data == NULL) { + pr_err("Debugfs init failed\n"); + goto exit; + } + r_b = debugfs_create_blob("goodix_ts", 0644, NULL, &goodix_dbg.buf); + if (!r_b) { + pr_err("Debugfs create failed\n"); + return -ENOENT; + } + goodix_dbg.dentry = r_b; + +exit: + return 0; +} + +static void goodix_debugfs_exit(void) +{ + debugfs_remove(goodix_dbg.dentry); + goodix_dbg.dentry = NULL; + pr_info("Debugfs module exit\n"); +} + +/* show external module infomation */ +static ssize_t goodix_ts_extmod_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct goodix_ext_module *module; + size_t offset = 0; + int r; + + mutex_lock(&goodix_modules.mutex); + if (!list_empty(&goodix_modules.head)) { + list_for_each_entry(module, &goodix_modules.head, list) { + r = snprintf(&buf[offset], PAGE_SIZE, + "priority:%u module:%s\n", + module->priority, module->name); + if (r < 0) { + mutex_unlock(&goodix_modules.mutex); + return -EINVAL; + } + offset += r; + } + } + + mutex_unlock(&goodix_modules.mutex); + return offset; +} + +/* show driver infomation */ +static ssize_t goodix_ts_driver_info_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "DriverVersion:%s\n", + GOODIX_DRIVER_VERSION); +} + +/* show chip infoamtion */ +static ssize_t goodix_ts_chip_info_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + struct goodix_ts_device *ts_dev = core_data->ts_dev; + struct goodix_ts_version chip_ver; + int r, cnt = 0; + + cnt += snprintf(buf, PAGE_SIZE, "TouchDeviceName:%s\n", ts_dev->name); + if (ts_dev->hw_ops->read_version) { + r = ts_dev->hw_ops->read_version(ts_dev, &chip_ver); + if (!r && chip_ver.valid) { + cnt += snprintf( + &buf[cnt], PAGE_SIZE, + "PID:%s\nVID:%02x %02x %02x %02x\nSensorID:%02x\n", + chip_ver.pid, chip_ver.vid[0], chip_ver.vid[1], + chip_ver.vid[2], chip_ver.vid[3], + chip_ver.sensor_id); + } + } + return cnt; +} + +/* show chip configuration data */ +static ssize_t goodix_ts_config_data_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + struct goodix_ts_device *ts_dev = core_data->ts_dev; + struct goodix_ts_config *ncfg = ts_dev->normal_cfg; + u8 *data; + int i, r, offset = 0; + + if (ncfg && ncfg->initialized && ncfg->length < PAGE_SIZE) { + data = kmalloc(ncfg->length, GFP_KERNEL); + if (!data) + return -ENOMEM; + + r = ts_dev->hw_ops->read(ts_dev, ncfg->reg_base, &data[0], + ncfg->length); + if (r < 0) { + kfree(data); + return -EINVAL; + } + + for (i = 0; i < ncfg->length; i++) { + if (i != 0 && i % 20 == 0) + buf[offset++] = '\n'; + offset += snprintf(&buf[offset], PAGE_SIZE - offset, + "%02x ", data[i]); + } + buf[offset++] = '\n'; + buf[offset++] = '\0'; + kfree(data); + return offset; + } + return -EINVAL; +} + +/* reset chip */ +static ssize_t goodix_ts_reset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + struct goodix_ts_device *ts_dev = core_data->ts_dev; + int en; + + if (sscanf(buf, "%d", &en) != 1) + return -EINVAL; + if (en != 1) + return -EINVAL; + if (ts_dev->hw_ops->reset) + ts_dev->hw_ops->reset(ts_dev); + return count; +} + +static ssize_t goodix_ts_read_cfg_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + struct goodix_ts_device *ts_dev = core_data->ts_dev; + int ret, i, offset; + char *cfg_buf; + + cfg_buf = kzalloc(4096, GFP_KERNEL); + disable_irq(core_data->irq); + if (ts_dev->hw_ops->read_config) + ret = ts_dev->hw_ops->read_config(ts_dev, cfg_buf, 0); + else + ret = -EINVAL; + enable_irq(core_data->irq); + + offset = 0; + if (ret > 0) { + for (i = 0; i < ret; i++) { + if (i != 0 && i % 20 == 0) + buf[offset++] = '\n'; + offset += snprintf(&buf[offset], 4096 - offset, "%02x ", + cfg_buf[i]); + } + } + kfree(cfg_buf); + return ret; +} + +static int goodix_ts_convert_0x_data(const u8 *buf, int buf_size, + unsigned char *out_buf, int *out_buf_len) +{ + int i, m_size = 0; + int temp_index = 0; + + for (i = 0; i < buf_size; i++) { + if (buf[i] == 'x' || buf[i] == 'X') + m_size++; + } + ts_info("***m_size:%d", m_size); + if (m_size <= 1) { + ts_err("cfg file ERROR, valid data count:%d\n", m_size); + return -EINVAL; + } + *out_buf_len = m_size; + for (i = 0; i < buf_size; i++) { + if (buf[i] == 'x' || buf[i] == 'X') { + if (temp_index >= m_size) { + ts_err("exchange cfg data error, overflow, temp_index:%d,m_size:%d\n", + temp_index, m_size); + return -EINVAL; + } + if (buf[i + 1] >= '0' && buf[i + 1] <= '9') + out_buf[temp_index] = (buf[i + 1] - '0') << 4; + else if (buf[i + 1] >= 'a' && buf[i + 1] <= 'f') + out_buf[temp_index] = (buf[i + 1] - 'a' + 10) + << 4; + else if (buf[i + 1] >= 'A' && buf[i + 1] <= 'F') + out_buf[temp_index] = (buf[i + 1] - 'A' + 10) + << 4; + if (buf[i + 2] >= '0' && buf[i + 2] <= '9') + out_buf[temp_index] += (buf[i + 2] - '0'); + else if (buf[i + 2] >= 'a' && buf[i + 2] <= 'f') + out_buf[temp_index] += (buf[i + 2] - 'a' + 10); + else if (buf[i + 2] >= 'A' && buf[i + 2] <= 'F') + out_buf[temp_index] += (buf[i + 2] - 'A' + 10); + temp_index++; + } + } + return 0; +} + +static ssize_t goodix_ts_send_cfg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + struct goodix_ts_device *ts_dev = core_data->ts_dev; + int en, r; + const struct firmware *cfg_img; + struct goodix_ts_config *config = NULL; + + ts_err("%s::enter\n", __func__); + if (sscanf(buf, "%d", &en) != 1) + return -EINVAL; + + if (en != 1) + return -EINVAL; + + ts_err("en:%d", en); + disable_irq(core_data->irq); + + /*request configuration*/ + r = request_firmware(&cfg_img, GOODIX_DEFAULT_CFG_NAME, dev); + if (r < 0) { + ts_err("cfg file [%s] not available,errno:%d", + GOODIX_DEFAULT_CFG_NAME, r); + goto exit; + } else + ts_info("cfg file [%s] is ready", GOODIX_DEFAULT_CFG_NAME); + + config = kzalloc(sizeof(struct goodix_ts_config), GFP_KERNEL); + if (config == NULL) { + ts_err("Memory allco err"); + goto exit; + } + + /*parse cfg data*/ + if (goodix_ts_convert_0x_data(cfg_img->data, cfg_img->size, + config->data, &config->length)) { + ts_err("convert config data FAILED"); + goto exit; + } + + config->reg_base = ts_dev->reg.cfg_addr; + mutex_init(&config->lock); + config->initialized = true; + if (ts_dev->hw_ops->send_config) + ts_dev->hw_ops->send_config(ts_dev, config); + +exit: + enable_irq(core_data->irq); + if (config) { + kfree(config); + config = NULL; + } + if (cfg_img) { + release_firmware(cfg_img); + cfg_img = NULL; + } + ts_info("******OUT"); + return count; +} + +/* show irq infomation */ +static ssize_t goodix_ts_irq_info_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + struct irq_desc *desc; + size_t offset = 0; + int r; + + r = snprintf(&buf[offset], PAGE_SIZE, "irq:%u\n", core_data->irq); + if (r < 0) + return -EINVAL; + + offset += r; + r = snprintf(&buf[offset], PAGE_SIZE - offset, "state:%s\n", + atomic_read(&core_data->irq_enabled) ? "enabled" : + "disabled"); + if (r < 0) + return -EINVAL; + + desc = irq_to_desc(core_data->irq); + offset += r; + r = snprintf(&buf[offset], PAGE_SIZE - offset, "disable-depth:%d\n", + desc->depth); + if (r < 0) + return -EINVAL; + + offset += r; + r = snprintf(&buf[offset], PAGE_SIZE - offset, "trigger-count:%zu\n", + core_data->irq_trig_cnt); + if (r < 0) + return -EINVAL; + + offset += r; + r = snprintf(&buf[offset], PAGE_SIZE - offset, + "echo 0/1 > irq_info to disable/enable irq"); + if (r < 0) + return -EINVAL; + offset += r; + return offset; +} + +/* enable/disable irq */ +static ssize_t goodix_ts_irq_info_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + int en; + + if (sscanf(buf, "%d", &en) != 1) + return -EINVAL; + goodix_ts_irq_enable(core_data, en); + return count; +} + +/* open short test */ +static ssize_t goodix_ts_tp_test_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0; + int r = 0; + ret = goodix_tools_register(); + + if (ret) { + ret = 0; + ts_err("tp_test prepare goodix_tools_register failed"); + r = snprintf(buf, sizeof(ret), "%d", ret); + if (r < 0) + return -EINVAL; + return sizeof(ret); + } + ts_info("test start!"); + ret = test_process(dev); + + if (ret == 0) { + ret = 1; + ts_err("test PASS!"); + } else { + ts_err("test FAILED. result:%x", ret); + ret = 0; + } + goodix_tools_unregister(); + r = snprintf(buf, sizeof(ret), "%d\n", ret); + if (r < 0) + return -EINVAL; + + ts_info("test finish!"); + return sizeof(ret); +} + +/* tp get rawdata */ +static ssize_t goodix_ts_tp_rawdata_show(struct device *dev, + struct device_attribute *attr, + char *buf) + +{ + int ret = 0; + int r = 0; + int buf_size = 0; + ret = goodix_tools_register(); + + if (ret) { + ret = 0; + ts_err("tp_rawdata prepare goodix_tools_register failed"); + r = snprintf(buf, 6, "-EIO\t\n"); + if (r < 0) + return -EINVAL; + return 4; /*sizeof("-EIO")*/ + } + ts_info("start get rawdata!"); + ret = get_tp_rawdata(dev, buf, &buf_size); + goodix_tools_unregister(); + ts_info("test finish!"); + return ret; +} + +static ssize_t goodix_ts_power_reset_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + const struct goodix_ts_hw_ops *hw_ops = ts_hw_ops(core_data); + + int ret = 0; + ts_info("ts power reset test!"); + + goodix_ts_power_off(core_data); + goodix_ts_power_on(core_data); + if (hw_ops->reset) + hw_ops->reset(core_data->ts_dev); + + return ret; +} + +/* tp get test config */ +static ssize_t goodix_ts_tp_get_testcfg_show(struct device *dev, + struct device_attribute *attr, + char *buf) + +{ + int ret = 0; + int r = 0; + int buf_size = 0; + ret = goodix_tools_register(); + + if (ret) { + ret = 0; + ts_err("tp_rawdata prepare goodix_tools_register failed"); + r = snprintf(buf, 6, "-EIO\t\n"); + if (r < 0) + return -EINVAL; + return 4; /*sizeof("-EIO")*/ + } + + ts_info("start get rawdata!"); + ret = get_tp_testcfg(dev, buf, &buf_size); + goodix_tools_unregister(); + ts_info("test finish!"); + return ret; +} +static DEVICE_ATTR(extmod_info, S_IRUGO, goodix_ts_extmod_show, NULL); +static DEVICE_ATTR(driver_info, S_IRUGO, goodix_ts_driver_info_show, NULL); +static DEVICE_ATTR(chip_info, S_IRUGO, goodix_ts_chip_info_show, NULL); +static DEVICE_ATTR(config_data, S_IRUGO, goodix_ts_config_data_show, NULL); +static DEVICE_ATTR(reset, S_IWUSR | S_IWGRP, NULL, goodix_ts_reset_store); +static DEVICE_ATTR(send_cfg, S_IWUSR | S_IWGRP, NULL, goodix_ts_send_cfg_store); +static DEVICE_ATTR(read_cfg, S_IRUGO, goodix_ts_read_cfg_show, NULL); +static DEVICE_ATTR(irq_info, S_IRUGO | S_IWUSR | S_IWGRP, + goodix_ts_irq_info_show, goodix_ts_irq_info_store); +static DEVICE_ATTR(tp_test, S_IRUGO, goodix_ts_tp_test_show, NULL); +static DEVICE_ATTR(tp_rawdata, S_IRUGO, goodix_ts_tp_rawdata_show, NULL); +static DEVICE_ATTR(tp_get_testcfg, S_IRUGO, goodix_ts_tp_get_testcfg_show, + NULL); +static DEVICE_ATTR(tp_power_reset, S_IRUGO, goodix_ts_power_reset_show, NULL); + +static struct attribute *sysfs_attrs[] = { + &dev_attr_extmod_info.attr, + &dev_attr_driver_info.attr, + &dev_attr_chip_info.attr, + &dev_attr_config_data.attr, + &dev_attr_reset.attr, + &dev_attr_send_cfg.attr, + &dev_attr_read_cfg.attr, + &dev_attr_irq_info.attr, + &dev_attr_tp_test.attr, + &dev_attr_tp_rawdata.attr, + &dev_attr_tp_get_testcfg.attr, + &dev_attr_tp_power_reset.attr, + NULL, +}; + +static const struct attribute_group sysfs_group = { + .attrs = sysfs_attrs, +}; + +int goodix_ts_sysfs_init(struct goodix_ts_core *core_data) +{ + return sysfs_create_group(&core_data->pdev->dev.kobj, &sysfs_group); +} + +static void goodix_ts_sysfs_exit(struct goodix_ts_core *core_data) +{ + sysfs_remove_group(&core_data->pdev->dev.kobj, &sysfs_group); +} + +/* event notifier */ +static BLOCKING_NOTIFIER_HEAD(ts_notifier_list); +/** + * goodix_ts_register_client - register a client notifier + * @nb: notifier block to callback on events + * see enum ts_notify_event in goodix_ts_core.h + */ +int goodix_ts_register_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&ts_notifier_list, nb); +} +EXPORT_SYMBOL(goodix_ts_register_notifier); + +/** + * goodix_ts_unregister_client - unregister a client notifier + * @nb: notifier block to callback on events + * see enum ts_notify_event in goodix_ts_core.h + */ +int goodix_ts_unregister_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&ts_notifier_list, nb); +} +EXPORT_SYMBOL(goodix_ts_unregister_notifier); + +/** + * fb_notifier_call_chain - notify clients of fb_events + * see enum ts_notify_event in goodix_ts_core.h + */ +int goodix_ts_blocking_notify(enum ts_notify_event evt, void *v) +{ + return blocking_notifier_call_chain(&ts_notifier_list, + (unsigned long)evt, v); +} +EXPORT_SYMBOL_GPL(goodix_ts_blocking_notify); + +static void release_all_touches(struct goodix_ts_core *core_data) +{ + unsigned int type = MT_TOOL_FINGER; + struct goodix_ts_device *ts_dev = core_data->ts_dev; + int i; + mutex_lock(&ts_dev->report_mutex); + + for (i = 0; i < GOODIX_MAX_TOUCH; i++) { + input_mt_slot(core_data->input_dev, i); + input_mt_report_slot_state(core_data->input_dev, type, 0); + } + ts_err("enter:%s core_data->touch_id=%d\n", __func__, + core_data->touch_id); + core_data->sleep_finger = core_data->touch_id; + core_data->touch_id = 0; + input_sync(core_data->input_dev); + mutex_unlock(&ts_dev->report_mutex); +} + +/** + * goodix_ts_input_report - report touch event to input subsystem + * + * @dev: input device pointer + * @touch_data: touch data pointer + * return: 0 ok, <0 failed + */ +static int goodix_ts_input_report(struct input_dev *dev, + struct goodix_touch_data *touch_data) +{ + struct goodix_ts_coords *coords = &touch_data->coords[0]; + struct goodix_ts_core *core_data = input_get_drvdata(dev); + struct goodix_ts_board_data *ts_bdata = board_data(core_data); + struct goodix_ts_device *ts_dev = core_data->ts_dev; + unsigned int touch_num = touch_data->touch_num; + int i, id; + + if (core_data->fod_status) { + if ((core_data->event_status & 0x20) == 0x20) { + ts_info("%s:the data sended was error,return\n", + __func__); + return 0; + } + } + + mutex_lock(&ts_dev->report_mutex); + id = coords->id; + for (i = 0; i < ts_bdata->panel_max_id * 2; i++) { + if (touch_num && + i == id) { /* this is a valid touch down event */ + input_mt_slot(dev, id); + input_mt_report_slot_state(dev, MT_TOOL_FINGER, true); + + /*first touch down event*/ + input_report_key(dev, BTN_TOUCH, !!touch_num); + /*point position*/ + input_report_abs(dev, ABS_MT_POSITION_X, coords->x); + input_report_abs(dev, ABS_MT_POSITION_Y, coords->y); + /* + input_report_abs(dev, ABS_MT_TOUCH_MAJOR, coords->w); + input_report_abs(dev, ABS_MT_PRESSURE, coords->p); + input_report_abs(dev, ABS_MT_TOUCH_MINOR, coords->area); + */ + + if ((core_data->event_status & 0x88) != 0x88 || + !core_data->fod_status) + coords->overlapping_area = 0; + input_report_abs(dev, ABS_MT_WIDTH_MINOR, + coords->overlapping_area); + input_report_abs(dev, ABS_MT_WIDTH_MAJOR, + coords->overlapping_area); + if (!__test_and_set_bit(i, &core_data->touch_id)) { + ts_info("[GTP] %s report press:%d", __func__, + i); + } + dev_dbg(core_data->ts_dev->dev, + "[GTP] %s report:[%d](%d, %d, %d, %d)", + __func__, id, touch_data->coords[0].x, + touch_data->coords[0].y, + touch_data->coords[0].area, + touch_data->coords[0].overlapping_area); + id = (++coords)->id; + } else { + if (__test_and_clear_bit(i, &core_data->touch_id)) { + input_mt_slot(dev, i); + input_mt_report_slot_state(dev, MT_TOOL_FINGER, + false); + if (!touch_num) { + input_report_key(dev, BTN_TOUCH, + !!touch_num); + input_report_key(dev, BTN_TOOL_FINGER, + 0); + core_data->sleep_finger = 0; + } + ts_info("[GTP] %s report leave:%d", __func__, + i); + } + } + } + + /*report finger*/ + /*ts_info("get_event_now :0x%02x, pre_event : %d", get_event_now, pre_event);*/ + if ((core_data->event_status & 0x88) == 0x88 && core_data->fod_status) { + input_report_key(core_data->input_dev, BTN_INFO, 1); + /*input_report_key(core_data->input_dev, KEY_INFO, 1);*/ + core_data->fod_pressed = true; + ts_info("BTN_INFO press"); + } else if (core_data->fod_pressed && + (core_data->event_status & 0x88) != 0x88) { + if (unlikely(!core_data->fod_test)) { + input_report_key(core_data->input_dev, BTN_INFO, 0); + /*input_report_key(core_data->input_dev, KEY_INFO, 0);*/ + ts_info("BTN_INFO release"); + core_data->fod_pressed = false; + } + } + mutex_unlock(&ts_dev->report_mutex); + input_sync(dev); + /* check the ghost touch issue */ + if (!touch_num && core_data->touch_id) { + ts_err("touch fw miss the up event"); + release_all_touches(core_data); + } + + return 0; +} + +static void goodix_ts_sleep_work(struct work_struct *work) +{ + struct goodix_ts_core *core_data = + container_of(work, struct goodix_ts_core, sleep_work); + struct goodix_ts_device *ts_dev = core_data->ts_dev; + struct goodix_ext_module *ext_module; + struct goodix_ts_event *ts_event = &core_data->ts_event; + int r; + + ts_info("enter"); + + if (core_data->tp_already_suspend) { + r = wait_for_completion_timeout( + &core_data->pm_resume_completion, + msecs_to_jiffies(500)); + if (!r) { + ts_info("pm_resume_completion timeout, i2c is closed"); + return; + } else { + ts_info("pm_resume_completion be completed, handling irq"); + } + } + + mutex_lock(&goodix_modules.mutex); + list_for_each_entry(ext_module, &goodix_modules.head, list) { + if (!ext_module->funcs->irq_event) + continue; + r = ext_module->funcs->irq_event(core_data, ext_module); + if (r == EVT_CANCEL_IRQEVT) { + ts_info("irq exit"); + mutex_unlock(&goodix_modules.mutex); + return; + } + } + mutex_unlock(&goodix_modules.mutex); + + /* read touch data from touch device */ + r = ts_dev->hw_ops->event_handler(ts_dev, ts_event); + if (likely(r >= 0)) { + if (ts_event->event_type == EVENT_TOUCH) { + /* report touch */ + goodix_ts_input_report( + core_data->input_dev, + &ts_event->event_data.touch_data); + } + } + ts_info("exit"); +} + +/** + * goodix_ts_threadirq_func - Bottom half of interrupt + * This functions is excuted in thread context, + * sleep in this function is permit. + * + * @core_data: pointer to touch core data + * return: 0 ok, <0 failed + */ +static irqreturn_t goodix_ts_threadirq_func(int irq, void *data) +{ + u8 irq_flag = 0; + struct goodix_ts_core *core_data = data; + struct goodix_ts_device *ts_dev = core_data->ts_dev; + struct goodix_ext_module *ext_module; + struct goodix_ts_event *ts_event = &core_data->ts_event; + int r; + struct i2c_client *client = NULL; + + client = to_i2c_client(ts_dev->dev); + i2c_set_clientdata(client, core_data); + + core_data->irq_trig_cnt++; + /* inform external module */ + /* ts_err("enter %s\n", __func__);*/ + if (core_data->tp_already_suspend) { + ts_info("device in suspend noirq, schedue to work"); + pm_wakeup_event(&client->dev, msecs_to_jiffies(500)); + queue_work(core_data->event_wq, &core_data->sleep_work); + return IRQ_HANDLED; + } + + mutex_lock(&goodix_modules.mutex); + list_for_each_entry(ext_module, &goodix_modules.head, list) { + if (!ext_module->funcs->irq_event) + continue; + r = ext_module->funcs->irq_event(core_data, ext_module); + /*ts_err("enter %s r=%d\n", __func__, r);*/ + if (r == EVT_CANCEL_IRQEVT) { + ts_err("enter %s EVT_CANCEL_IRQEVT \n", __func__); + mutex_unlock(&goodix_modules.mutex); + return IRQ_HANDLED; + } + } + mutex_unlock(&goodix_modules.mutex); + + /* read touch data from touch device */ + r = ts_dev->hw_ops->event_handler(ts_dev, ts_event); + if (likely(r >= 0)) { + if (ts_event->event_type == EVENT_TOUCH) { + /* report touch */ + goodix_ts_input_report( + core_data->input_dev, + &ts_event->event_data.touch_data); + } + } + /* clean irq flag */ + ts_dev->hw_ops->write_trans(ts_dev, ts_dev->reg.coor, &irq_flag, + 1); /*TS_REG_COORDS_BASE*/ + return IRQ_HANDLED; +} + +/** + * goodix_ts_init_irq - Requset interrput line from system + * @core_data: pointer to touch core data + * return: 0 ok, <0 failed + */ +int goodix_ts_irq_setup(struct goodix_ts_core *core_data) +{ + const struct goodix_ts_board_data *ts_bdata = board_data(core_data); + int r; + + /* if ts_bdata-> irq is invalid */ + if (ts_bdata->irq <= 0) { + core_data->irq = gpio_to_irq(ts_bdata->irq_gpio); + } else { + core_data->irq = ts_bdata->irq; + } + + ts_info("IRQ:%u,flags:%d", core_data->irq, (int)ts_bdata->irq_flags); + r = devm_request_threaded_irq(&core_data->pdev->dev, core_data->irq, + NULL, goodix_ts_threadirq_func, + ts_bdata->irq_flags | IRQF_ONESHOT, + GOODIX_CORE_DRIVER_NAME, core_data); + if (r < 0) + ts_err("Failed to requeset threaded irq:%d", r); + else + atomic_set(&core_data->irq_enabled, 1); + return r; +} + +/** + * goodix_ts_irq_enable - Enable/Disable a irq + * @core_data: pointer to touch core data + * enable: enable or disable irq + * return: 0 ok, <0 failed + */ +int goodix_ts_irq_enable(struct goodix_ts_core *core_data, bool enable) +{ + if (enable) { + if (!atomic_cmpxchg(&core_data->irq_enabled, 0, 1)) { + enable_irq(core_data->irq); + ts_debug("Irq enabled"); + } + } else { + if (atomic_cmpxchg(&core_data->irq_enabled, 1, 0)) { + disable_irq(core_data->irq); + ts_debug("Irq disabled"); + } + } + return 0; +} +EXPORT_SYMBOL(goodix_ts_irq_enable); +/** + * goodix_ts_power_init - Get regulator for touch device + * @core_data: pointer to touch core data + * return: 0 ok, <0 failed + */ +static int goodix_ts_power_init(struct goodix_ts_core *core_data) +{ + struct goodix_ts_board_data *ts_bdata; + ts_bdata = board_data(core_data); + + gpio_direction_output(ts_bdata->reset_gpio, 0); + gpio_direction_output(ts_bdata->irq_gpio, 1); + + return 0; +} + +/** + * goodix_ts_power_on - Turn on power to the touch device + * @core_data: pointer to touch core data + * return: 0 ok, <0 failed + */ +int goodix_ts_power_on(struct goodix_ts_core *core_data) +{ + struct goodix_ts_board_data *ts_bdata = board_data(core_data); + int r = 0; + + ts_err("enter::%s\n", __func__); + if (core_data->power_on) + return 0; + gpio_direction_output(ts_bdata->vdd_gpio, 1); + gpio_direction_output(ts_bdata->avdd_gpio, 1); + core_data->power_on = 1; + return r; +} + +/** + * goodix_ts_power_off - Turn off power to the touch device + * @core_data: pointer to touch core data + * return: 0 ok, <0 failed + */ +int goodix_ts_power_off(struct goodix_ts_core *core_data) +{ + struct goodix_ts_board_data *ts_bdata = board_data(core_data); + int r = 0; + + ts_info("Device power off"); + if (!core_data->power_on) + return 0; + gpio_direction_output(ts_bdata->vdd_gpio, 0); + gpio_direction_output(ts_bdata->avdd_gpio, 0); + core_data->power_on = 0; + return r; +} + +#ifdef CONFIG_PINCTRL +/** + * goodix_ts_pinctrl_init - Get pinctrl handler and pinctrl_state + * @core_data: pointer to touch core data + * return: 0 ok, <0 failed + */ +static int goodix_ts_pinctrl_init(struct goodix_ts_core *core_data) +{ + int r = 0; + + /* get pinctrl handler from of node */ + core_data->pinctrl = devm_pinctrl_get(core_data->ts_dev->dev); + if (IS_ERR_OR_NULL(core_data->pinctrl)) { + ts_err("Failed to get pinctrl handler"); + return PTR_ERR(core_data->pinctrl); + } + + /* active state */ + core_data->pin_sta_active = + pinctrl_lookup_state(core_data->pinctrl, PINCTRL_STATE_ACTIVE); + if (IS_ERR_OR_NULL(core_data->pin_sta_active)) { + r = PTR_ERR(core_data->pin_sta_active); + ts_err("Failed to get pinctrl state:%s, r:%d", + PINCTRL_STATE_ACTIVE, r); + goto exit_pinctrl_put; + } + + /* suspend state */ + core_data->pin_sta_suspend = + pinctrl_lookup_state(core_data->pinctrl, PINCTRL_STATE_SUSPEND); + if (IS_ERR_OR_NULL(core_data->pin_sta_suspend)) { + r = PTR_ERR(core_data->pin_sta_suspend); + ts_err("Failed to get pinctrl state:%s, r:%d", + PINCTRL_STATE_SUSPEND, r); + goto exit_pinctrl_put; + } + + return 0; +exit_pinctrl_put: + devm_pinctrl_put(core_data->pinctrl); + core_data->pinctrl = NULL; + return r; +} +#endif + +/** + * goodix_ts_gpio_setup - Request gpio resources from GPIO subsysten + * reset_gpio and irq_gpio number are obtained from goodix_ts_device + * which created in hardware layer driver. e.g.goodix_xx_i2c.c + * A goodix_ts_device should set those two fileds to right value + * before registed to touch core driver. + * @core_data: pointer to touch core data + * return: 0 ok, <0 failed + */ +static int goodix_ts_gpio_setup(struct goodix_ts_core *core_data) +{ + struct goodix_ts_board_data *ts_bdata = board_data(core_data); + int r = 0; + + ts_info("GPIO setup,reset-gpio:%d, irq-gpio:%d", ts_bdata->reset_gpio, + ts_bdata->irq_gpio); + /* + * after kenerl3.13, gpio_ api is deprecated, new + * driver should use gpiod_ api. + */ + r = devm_gpio_request_one(&core_data->pdev->dev, ts_bdata->reset_gpio, + GPIOF_OUT_INIT_HIGH, "ts_reset_gpio"); + if (r < 0) { + ts_err("Failed to request reset gpio, r:%d", r); + return r; + } + + r = devm_gpio_request_one(&core_data->pdev->dev, ts_bdata->irq_gpio, + GPIOF_IN, "ts_irq_gpio"); + if (r < 0) { + ts_err("Failed to request irq gpio, r:%d", r); + return r; + } + return 0; +} + +static ssize_t gtp_touch_suspend_notify_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", + !!atomic_read(&goodix_core_data->suspend_stat)); +} + +static ssize_t gtp_fod_test_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int value = 0; + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + + ts_info("buf:%c,count:%zu\n", buf[0], count); + sscanf(buf, "%u", &value); + if (value) { + input_report_key(core_data->input_dev, BTN_INFO, 1); + /*input_report_key(core_data->input_dev, KEY_INFO, 1);*/ + input_sync(core_data->input_dev); + input_mt_slot(core_data->input_dev, 0); + input_mt_report_slot_state(core_data->input_dev, MT_TOOL_FINGER, + 1); + input_report_key(core_data->input_dev, BTN_TOUCH, 1); + input_report_key(core_data->input_dev, BTN_TOOL_FINGER, 1); + input_report_abs(core_data->input_dev, ABS_MT_TRACKING_ID, 0); + input_report_abs(core_data->input_dev, ABS_MT_POSITION_X, + CENTER_X); + input_report_abs(core_data->input_dev, ABS_MT_POSITION_Y, + CENTER_Y); + input_report_abs(core_data->input_dev, ABS_MT_WIDTH_MINOR, 8); + input_report_abs(core_data->input_dev, ABS_MT_WIDTH_MAJOR, 8); + input_sync(core_data->input_dev); + } else { + input_mt_slot(core_data->input_dev, 0); + input_mt_report_slot_state(core_data->input_dev, MT_TOOL_FINGER, + 0); + input_report_abs(core_data->input_dev, ABS_MT_TRACKING_ID, -1); + input_report_key(core_data->input_dev, BTN_INFO, 0); + /*input_report_key(core_data->input_dev, KEY_INFO, 0);*/ + input_sync(core_data->input_dev); + } + return count; +} + +static ssize_t gtp_fod_status_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + + return snprintf(buf, 10, "%d\n", core_data->fod_status); +} + +static ssize_t gtp_fod_status_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + //struct goodix_ts_event *ts_event = &core_data->ts_event; + ts_info("buf:%s, count:%zu\n", buf, count); + sscanf(buf, "%u", &core_data->fod_status); + + //goodix_ts_input_report(core_data->input_dev,&ts_event->event_data.touch_data); + core_data->gesture_enabled = core_data->double_wakeup | + core_data->fod_status; + goodix_check_gesture_stat(!!core_data->fod_status); + + return count; +} +static DEVICE_ATTR(fod_status, (S_IRUGO | S_IWUSR | S_IWGRP), + gtp_fod_status_show, gtp_fod_status_store); + +static DEVICE_ATTR(fod_test, (S_IRUGO | S_IWUSR | S_IWGRP), NULL, + gtp_fod_test_store); + +static DEVICE_ATTR(touch_suspend_notify, (S_IRUGO | S_IRGRP), + gtp_touch_suspend_notify_show, NULL); + +static void goodix_switch_mode_work(struct work_struct *work) +{ + struct goodix_mode_switch *ms = + container_of(work, struct goodix_mode_switch, switch_mode_work); + + struct goodix_ts_core *info = ms->info; + unsigned char value = ms->mode; + +#ifdef CONFIG_GOODIX_HWINFO + char ch[16] = { + 0x0, + }; +#endif + if (value >= INPUT_EVENT_WAKUP_MODE_OFF && + value <= INPUT_EVENT_WAKUP_MODE_ON) { + info->double_wakeup = value - INPUT_EVENT_WAKUP_MODE_OFF; + info->gesture_enabled = info->double_wakeup | info->fod_status; + /*goodix_gesture_enable(!!info->gesture_enabled);*/ +#ifdef CONFIG_GOODIX_HWINFO + snprintf(ch, sizeof(ch), "%s", + info->gesture_enabled ? "enabled" : "disabled"); +#endif + } +} + +static int goodix_input_event(struct input_dev *dev, unsigned int type, + unsigned int code, int value) +{ + struct goodix_ts_core *core_data = input_get_drvdata(dev); + struct goodix_mode_switch *ms; + + if (!core_data) { + ts_err("core_data is NULL"); + return 0; + } + + if (type == EV_SYN && code == SYN_CONFIG) { + if (value >= INPUT_EVENT_START && value <= INPUT_EVENT_END) { + ms = (struct goodix_mode_switch *)kmalloc( + sizeof(struct goodix_mode_switch), GFP_ATOMIC); + if (ms != NULL) { + ms->info = core_data; + ms->mode = (unsigned char)value; + INIT_WORK(&ms->switch_mode_work, + goodix_switch_mode_work); + schedule_work(&ms->switch_mode_work); + } else { + ts_err("failed in allocating memory for switching mode"); + return -ENOMEM; + } + } else { + ts_err("Invalid event value"); + return -EINVAL; + } + } + return 0; +} + +/** + * goodix_input_set_params - set input parameters + */ +static void goodix_ts_set_input_params(struct input_dev *input_dev, + struct goodix_ts_board_data *ts_bdata) +{ + int i; + + if (ts_bdata->swap_axis) + swap(ts_bdata->panel_max_x, ts_bdata->panel_max_y); + input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, + ts_bdata->panel_max_x, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, + ts_bdata->panel_max_y, 0, 0); + /*input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, + 0, ts_bdata->panel_max_w, 0, 0);*/ + /*input_set_abs_params(input_dev, ABS_MT_PRESSURE, + 0, ts_bdata->panel_max_p, 0, 0);*/ + /*input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, + 0, ts_bdata->panel_max_w, 0, 0);*/ + input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, + ts_bdata->panel_max_overlapping_area, 0, 0); + input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, + ts_bdata->panel_max_overlapping_area, 0, 0); + if (ts_bdata->panel_max_key) { + for (i = 0; i < ts_bdata->panel_max_key; i++) + input_set_capability(input_dev, EV_KEY, + ts_bdata->panel_key_map[i]); + } +} + +/** + * goodix_ts_input_dev_config - Requset and config a input device + * then register it to input sybsystem. + * NOTE that some hardware layer may provide a input device + * (ts_dev->input_dev not NULL). + * @core_data: pointer to touch core data + * return: 0 ok, <0 failed + */ +int goodix_ts_input_dev_config(struct goodix_ts_core *core_data) +{ + struct goodix_ts_board_data *ts_bdata = board_data(core_data); + struct input_dev *input_dev = NULL; + int r; + + input_dev = devm_input_allocate_device(&core_data->pdev->dev); + if (!input_dev) { + ts_err("Failed to allocated input device"); + return -ENOMEM; + } + + core_data->input_dev = input_dev; + input_set_drvdata(input_dev, core_data); + + input_dev->name = GOODIX_CORE_DRIVER_NAME; + input_dev->phys = GOOIDX_INPUT_PHYS; + input_dev->id.product = 0xDEAD; + input_dev->id.vendor = 0xBEEF; + input_dev->id.version = 10427; + input_dev->event = goodix_input_event; + + __set_bit(EV_SYN, input_dev->evbit); + __set_bit(EV_KEY, input_dev->evbit); + __set_bit(EV_ABS, input_dev->evbit); + __set_bit(BTN_TOUCH, input_dev->keybit); + __set_bit(BTN_TOOL_FINGER, input_dev->keybit); + +#ifdef INPUT_PROP_DIRECT + __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); +#endif + + /* set input parameters */ + goodix_ts_set_input_params(input_dev, ts_bdata); + +#ifdef INPUT_TYPE_B_PROTOCOL +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 0) + input_mt_init_slots(input_dev, ts_bdata->panel_max_id * 2 + 1, + INPUT_MT_DIRECT); +#else + input_mt_init_slots(input_dev, ts_bdata->panel_max_id * 2 + 1); +#endif +#endif + + input_set_capability(input_dev, EV_KEY, KEY_WAKEUP); + input_set_capability(input_dev, EV_KEY, BTN_INFO); + input_set_capability(input_dev, EV_KEY, KEY_GOTO); + /*input_set_capability(input_dev, EV_KEY, KEY_INFO);*/ + + r = input_register_device(input_dev); + if (r < 0) { + ts_err("Unable to register input device"); + return r; + } + return 0; +} + +/** + * goodix_ts_hw_init - Hardware initilize + * poweron - hardware reset - sendconfig + * @core_data: pointer to touch core data + * return: 0 intilize ok, <0 failed + */ +int goodix_ts_hw_init(struct goodix_ts_core *core_data) +{ + const struct goodix_ts_hw_ops *hw_ops = ts_hw_ops(core_data); + int r; + + /* reset touch device */ + if (hw_ops->reset) { + r = hw_ops->reset(core_data->ts_dev); + if (r < 0) + goto exit; + } + + /* init */ + if (hw_ops->init) { + r = hw_ops->init(core_data->ts_dev); + if (r < 0) + goto exit; + } + +exit: + /* if bus communication error occured then + * exit driver binding, other errors will + * be ignored */ + if (r != -EBUS) + r = 0; + return r; +} + +/** + * goodix_ts_esd_work - check hardware status and recovery + * the hardware if needed. + */ +static void goodix_ts_esd_work(struct work_struct *work) +{ + struct delayed_work *dwork = to_delayed_work(work); + struct goodix_ts_esd *ts_esd = + container_of(dwork, struct goodix_ts_esd, esd_work); + struct goodix_ts_core *core = + container_of(ts_esd, struct goodix_ts_core, ts_esd); + const struct goodix_ts_hw_ops *hw_ops = ts_hw_ops(core); + int r = 0; + u8 data = GOODIX_ESD_TICK_WRITE_DATA; + + if (ts_esd->esd_on == false) + return; + + if (hw_ops->check_hw) + r = hw_ops->check_hw(core->ts_dev); + if (r < 0) { + goodix_ts_power_off(core); + goodix_ts_power_on(core); + if (hw_ops->reset) + hw_ops->reset(core->ts_dev); + + /*init static esd*/ + if (core->ts_dev->ic_type == IC_TYPE_NANJING) { + r = hw_ops->write(core->ts_dev, 0x8043, &data, 1); + if (r < 0) + ts_err("nanjing esd reset, init static esd FAILED, i2c wirte ERROR"); + } + + /*init dynamic esd*/ + r = hw_ops->write_trans(core->ts_dev, core->ts_dev->reg.esd, + &data, 1); + if (r < 0) + ts_err("esd reset, init dynamic esd FAILED, i2c write ERROR"); + } else { + /*init dynamic esd*/ + r = hw_ops->write_trans(core->ts_dev, core->ts_dev->reg.esd, + &data, 1); + if (r < 0) + ts_err("esd init watch dog FAILED, i2c write ERROR"); + } + mutex_lock(&ts_esd->esd_mutex); + if (ts_esd->esd_on) + schedule_delayed_work(&ts_esd->esd_work, + GOODIX_ESD_CHECK_INTERVAL * HZ); + mutex_unlock(&ts_esd->esd_mutex); +} + +/** + * goodix_ts_esd_on - turn on esd protection + */ +static void goodix_ts_esd_on(struct goodix_ts_core *core) +{ + struct goodix_ts_esd *ts_esd = &core->ts_esd; + + if (core->ts_dev->reg.esd == 0) + return; + + mutex_lock(&ts_esd->esd_mutex); + if (ts_esd->esd_on == false) { + ts_esd->esd_on = true; + schedule_delayed_work(&ts_esd->esd_work, + GOODIX_ESD_CHECK_INTERVAL * HZ); + mutex_unlock(&ts_esd->esd_mutex); + ts_info("Esd on"); + return; + } + mutex_unlock(&ts_esd->esd_mutex); +} + +/** + * goodix_ts_esd_off - turn off esd protection + */ +static void goodix_ts_esd_off(struct goodix_ts_core *core) +{ + struct goodix_ts_esd *ts_esd = &core->ts_esd; + + mutex_lock(&ts_esd->esd_mutex); + if (ts_esd->esd_on == true) { + ts_esd->esd_on = false; + cancel_delayed_work(&ts_esd->esd_work); + mutex_unlock(&ts_esd->esd_mutex); + ts_info("Esd off"); + return; + } + mutex_unlock(&ts_esd->esd_mutex); +} + +/** + * goodix_esd_notifier_callback - notification callback + * under certain condition, we need to turn off/on the esd + * protector, we use kernel notify call chain to achieve this. + * + * for example: before firmware update we need to turn off the + * esd protector and after firmware update finished, we should + * turn on the esd protector. + */ +static int goodix_esd_notifier_callback(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct goodix_ts_esd *ts_esd = + container_of(nb, struct goodix_ts_esd, esd_notifier); + + switch (action) { + case NOTIFY_FWUPDATE_START: + case NOTIFY_SUSPEND: + case NOTIFY_ESD_OFF: + goodix_ts_esd_off(ts_esd->ts_core); + break; + case NOTIFY_FWUPDATE_END: + case NOTIFY_RESUME: + case NOTIFY_ESD_ON: + goodix_ts_esd_on(ts_esd->ts_core); + break; + } + return 0; +} + +/** + * goodix_ts_esd_init - initialize esd protection + */ +int goodix_ts_esd_init(struct goodix_ts_core *core) +{ + struct goodix_ts_esd *ts_esd = &core->ts_esd; + struct goodix_ts_device *dev = core->ts_dev; + u8 data = GOODIX_ESD_TICK_WRITE_DATA; + int r; + + INIT_DELAYED_WORK(&ts_esd->esd_work, goodix_ts_esd_work); + mutex_init(&ts_esd->esd_mutex); + ts_esd->ts_core = core; + ts_esd->esd_on = false; + ts_esd->esd_notifier.notifier_call = goodix_esd_notifier_callback; + goodix_ts_register_notifier(&ts_esd->esd_notifier); + + if (dev->hw_ops->check_hw && dev->reg.esd != 0) { + /*init static esd*/ + if (dev->ic_type == IC_TYPE_NANJING) { + r = dev->hw_ops->write_trans(core->ts_dev, 0x8043, + &data, 1); + if (r < 0) + ts_err("static ESD init ERROR, i2c write failed"); + } + + /*init dynamic esd*/ + r = dev->hw_ops->write_trans(core->ts_dev, + core->ts_dev->reg.esd, &data, 1); + if (r < 0) + ts_err("dynamic ESD init ERROR, i2c write failed"); + goodix_ts_esd_on(core); + } + return 0; +} + +/** + * goodix_ts_suspend - Touchscreen suspend function + * Called by PM/FB/EARLYSUSPEN module to put the device to sleep + */ +int goodix_ts_suspend(struct goodix_ts_core *core_data) +{ + struct goodix_ext_module *ext_module; + struct goodix_ts_device *ts_dev = core_data->ts_dev; + int r = 0; + + ts_info("Suspend start"); + + mutex_lock(&core_data->work_stat); + if (atomic_read(&core_data->suspend_stat)) { + ts_info("suspended, skip"); + goto out; + } + + /* + * notify suspend event, inform the esd protector + * and charger detector to turn off the work + */ + goodix_ts_blocking_notify(NOTIFY_SUSPEND, NULL); + + /* inform external module */ + mutex_lock(&goodix_modules.mutex); + if (!list_empty(&goodix_modules.head)) { + list_for_each_entry(ext_module, &goodix_modules.head, list) { + if (!ext_module->funcs->before_suspend) + continue; + + r = ext_module->funcs->before_suspend(core_data, + ext_module); + if (r == EVT_CANCEL_SUSPEND) { + if (core_data->double_wakeup && + core_data->fod_status) { + atomic_set(&core_data->suspend_stat, + TP_GESTURE_DBCLK_FOD); + } else if (core_data->double_wakeup) { + atomic_set(&core_data->suspend_stat, + TP_GESTURE_DBCLK); + } else if (core_data->fod_status) { + atomic_set(&core_data->suspend_stat, + TP_GESTURE_FOD); + } + mutex_unlock(&goodix_modules.mutex); + ts_info("suspend_stat[%d]", + atomic_read(&core_data->suspend_stat)); + ts_info("Canceled by module:%s", + ext_module->name); + if (!atomic_read(&core_data->suspend_stat)) + ts_info("go suspend remaind work\n"); + else + goto out; + } + } + } + mutex_unlock(&goodix_modules.mutex); + + /* disable irq */ + goodix_ts_irq_enable(core_data, false); + + /* let touch ic work in sleep mode */ + if (ts_dev && ts_dev->hw_ops->suspend) + ts_dev->hw_ops->suspend(ts_dev); + atomic_set(&core_data->suspended, 1); + atomic_set(&core_data->suspend_stat, TP_SLEEP); + +#ifdef CONFIG_PINCTRL + if (core_data->pinctrl) { + r = pinctrl_select_state(core_data->pinctrl, + core_data->pin_sta_suspend); + if (r < 0) + ts_err("Failed to select active pinstate, r:%d", r); + } +#endif + + /* inform exteranl modules */ + mutex_lock(&goodix_modules.mutex); + if (!list_empty(&goodix_modules.head)) { + list_for_each_entry(ext_module, &goodix_modules.head, list) { + if (!ext_module->funcs->after_suspend) + continue; + + r = ext_module->funcs->after_suspend(core_data, + ext_module); + if (r == EVT_CANCEL_SUSPEND) { + mutex_unlock(&goodix_modules.mutex); + ts_info("Canceled by module:%s", + ext_module->name); + goto out; + } + } + } + mutex_unlock(&goodix_modules.mutex); + +out: + /* release all the touch IDs */ + release_all_touches(core_data); + core_data->ts_event.event_data.touch_data.touch_num = 0; + + sysfs_notify(&core_data->gtp_touch_dev->kobj, NULL, + "touch_suspend_notify"); + + mutex_unlock(&core_data->work_stat); + + ts_info("Suspend end"); + return 0; +} + +/** + * goodix_ts_resume - Touchscreen resume function + * Called by PM/FB/EARLYSUSPEN module to wakeup device + */ +int goodix_ts_resume(struct goodix_ts_core *core_data) +{ + struct goodix_ext_module *ext_module; + struct goodix_ts_device *ts_dev = core_data->ts_dev; + int r = 0; + + ts_info("Resume start"); + /*goodix_ts_irq_enable(core_data, false);*/ + mutex_lock(&core_data->work_stat); + if (!atomic_read(&core_data->suspend_stat)) { + ts_info("resumed, skip"); + /*goodix_ts_irq_enable(core_data, true);*/ + goto out; + } + + mutex_lock(&goodix_modules.mutex); + if (!list_empty(&goodix_modules.head)) { + list_for_each_entry(ext_module, &goodix_modules.head, list) { + if (!ext_module->funcs->before_resume) + continue; + + r = ext_module->funcs->before_resume(core_data, + ext_module); + if (r == EVT_CANCEL_RESUME) { + mutex_unlock(&goodix_modules.mutex); + ts_info("Canceled by module:%s", + ext_module->name); + goto out; + } + } + } + mutex_unlock(&goodix_modules.mutex); + +#ifdef CONFIG_PINCTRL + if (core_data->pinctrl) { + r = pinctrl_select_state(core_data->pinctrl, + core_data->pin_sta_active); + if (r < 0) + ts_err("Failed to select active pinstate, r:%d", r); + } +#endif + + atomic_set(&core_data->suspended, 0); + /* resume device */ + if (ts_dev && ts_dev->hw_ops->resume) + ts_dev->hw_ops->resume(ts_dev); + + atomic_set(&core_data->suspend_stat, TP_NO_SUSPEND); + + mutex_lock(&goodix_modules.mutex); + if (!list_empty(&goodix_modules.head)) { + list_for_each_entry(ext_module, &goodix_modules.head, list) { + if (!ext_module->funcs->after_resume) + continue; + + r = ext_module->funcs->after_resume(core_data, + ext_module); + if (r == EVT_CANCEL_RESUME) { + mutex_unlock(&goodix_modules.mutex); + ts_info("Canceled by module:%s", + ext_module->name); + goto out; + } + } + } + mutex_unlock(&goodix_modules.mutex); + goodix_ts_irq_enable(core_data, true); +out: + /* + * notify resume event, inform the esd protector + * and charger detector to turn on the work + */ + goodix_ts_blocking_notify(NOTIFY_RESUME, NULL); + + ts_err("core_data->fod_pressed = %d\n", core_data->fod_pressed); + + if (!core_data->fod_pressed) { + ts_err("resume release all touch"); + release_all_touches(core_data); + } + core_data->sleep_finger = 0; + + sysfs_notify(&core_data->gtp_touch_dev->kobj, NULL, + "touch_suspend_notify"); + + mutex_unlock(&core_data->work_stat); + + ts_info("Resume end"); + return 0; +} + +static int goodix_bl_state_chg_callback(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct goodix_ts_core *core_data = + container_of(nb, struct goodix_ts_core, bl_notifier); + unsigned int blank; + if (val != BACKLIGHT_UPDATED) + return NOTIFY_OK; + if (data && core_data) { + blank = *(int *)(data); + ts_info("%s val:%lu, blank:%u\n", __func__, val, blank); + if (blank == BACKLIGHT_OFF && + (atomic_read(&core_data->suspend_stat) && + core_data->fod_status)) { + ts_info("%s BACKLIGHT OFF, disable irq\n", __func__); + goodix_ts_irq_enable(core_data, false); + } else + goodix_ts_irq_enable(core_data, true); + } + return NOTIFY_OK; +} + +#ifdef CONFIG_DRM +/** + * goodix_ts_fb_notifier_callback - Framebuffer notifier callback + * Called by kernel during framebuffer blanck/unblank phrase + */ +int goodix_ts_fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct goodix_ts_core *core_data = + container_of(self, struct goodix_ts_core, fb_notifier); + struct drm_notify_data *fb_event = data; + int blank; + + if (fb_event && fb_event->data && core_data) { + blank = *(int *)(fb_event->data); + flush_workqueue(core_data->event_wq); + if (event == DRM_EVENT_BLANK && + (blank == DRM_BLANK_POWERDOWN || blank == DRM_BLANK_LP1 || + blank == DRM_BLANK_LP2)) { + ts_info("touchpanel suspend .....blank=%d\n", blank); + ts_info("touchpanel suspend .....suspend_stat=%d\n", + atomic_read(&core_data->suspend_stat)); + if (atomic_read(&core_data->suspend_stat)) + return 0; + ts_info("touchpanel suspend by %s", + blank == DRM_BLANK_POWERDOWN ? "blank" : + "doze"); + queue_work(core_data->event_wq, + &core_data->suspend_work); + } else if (event == DRM_EVENT_BLANK && + blank == DRM_BLANK_UNBLANK) { + //if (!atomic_read(&core_data->suspend_stat)) + ts_info("core_data->suspend_stat = %d\n", + atomic_read(&core_data->suspend_stat)); + ts_info("touchpanel resume"); + queue_work(core_data->event_wq, + &core_data->resume_work); + } + } + + return 0; +} +#endif + +#ifdef CONFIG_HAS_EARLYSUSPEND +/** + * goodix_ts_earlysuspend - Early suspend function + * Called by kernel during system suspend phrase + */ +static void goodix_ts_earlysuspend(struct early_suspend *h) +{ + struct goodix_ts_core *core_data = + container_of(h, struct goodix_ts_core, early_suspend); + + goodix_ts_suspend(core_data); +} +/** + * goodix_ts_lateresume - Late resume function + * Called by kernel during system wakeup + */ +static void goodix_ts_lateresume(struct early_suspend *h) +{ + struct goodix_ts_core *core_data = + container_of(h, struct goodix_ts_core, early_suspend); + goodix_ts_resume(core_data); +} +#endif + +#ifdef CONFIG_PM +#ifdef CONFIG_DRM +static void goodix_ts_resume_work(struct work_struct *work) +{ + struct goodix_ts_core *core_data = + container_of(work, struct goodix_ts_core, resume_work); + goodix_ts_resume(core_data); +} +static void goodix_ts_suspend_work(struct work_struct *work) +{ + struct goodix_ts_core *core_data = + container_of(work, struct goodix_ts_core, suspend_work); + goodix_ts_suspend(core_data); +} + +/** + * goodix_ts_pm_suspend - PM suspend function + * Called by kernel during system suspend phrase + */ +static int goodix_ts_pm_suspend(struct device *dev) +{ + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + if (device_may_wakeup(dev) && core_data->gesture_enabled) { + enable_irq_wake(core_data->irq); + } + + core_data->tp_already_suspend = true; + reinit_completion(&core_data->pm_resume_completion); + + return 0; +} +/** + * goodix_ts_pm_resume - PM resume function + * Called by kernel during system wakeup + */ +static int goodix_ts_pm_resume(struct device *dev) +{ + struct goodix_ts_core *core_data = dev_get_drvdata(dev); + if (device_may_wakeup(dev) && core_data->gesture_enabled) { + disable_irq_wake(core_data->irq); + } + + core_data->tp_already_suspend = false; + complete(&core_data->pm_resume_completion); + + return 0; +} + +#endif +#endif + +#ifdef CONFIG_TOUCHSCREEN_GOODIX_DEBUG_FS +/* +static void tpdbg_shutdown(struct goodix_ts_core *core_data, bool sleep) +{ + +} +*/ + +static void tpdbg_suspend(struct goodix_ts_core *core_data, bool enable) +{ + if (enable) + queue_work(core_data->event_wq, &core_data->suspend_work); + else + queue_work(core_data->event_wq, &core_data->resume_work); +} + +static int tpdbg_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + + return 0; +} + +static ssize_t tpdbg_read(struct file *file, char __user *buf, size_t size, + loff_t *ppos) +{ + const char *str = "cmd support as below:\n \ + echo \"irq-disable\" or \"irq-enable\" to ctrl irq\n \ + echo \"tp-suspend-en\" or \"tp-suspend-off\" to ctrl panel in or off suspend status\n"; + + loff_t pos = *ppos; + int len = strlen(str); + + if (pos < 0) + return -EINVAL; + if (pos >= len) + return 0; + + if (copy_to_user(buf, str, len)) + return -EFAULT; + + *ppos = pos + len; + + return len; +} + +static ssize_t tpdbg_write(struct file *file, const char __user *buf, + size_t size, loff_t *ppos) +{ + struct goodix_ts_core *core_data = file->private_data; + char *cmd = kzalloc(size + 1, GFP_KERNEL); + int ret = size; + + if (!cmd) + return -ENOMEM; + + if (copy_from_user(cmd, buf, size)) { + ret = -EFAULT; + goto out; + } + + cmd[size] = '\0'; + + if (!strncmp(cmd, "irq-disable", 11)) + goodix_ts_irq_enable(core_data, false); + else if (!strncmp(cmd, "irq-enable", 10)) + goodix_ts_irq_enable(core_data, true); + /* + else if (!strncmp(cmd, "tp-sd-en", 8)) + tpdbg_shutdown(core_data, true); + else if (!strncmp(cmd, "tp-sd-off", 9)) + tpdbg_shutdown(core_data, false); +*/ + else if (!strncmp(cmd, "tp-suspend-en", 13)) + tpdbg_suspend(core_data, true); + else if (!strncmp(cmd, "tp-suspend-off", 14)) + tpdbg_suspend(core_data, false); +out: + kfree(cmd); + + return ret; +} + +static int tpdbg_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + + return 0; +} + +static const struct file_operations tpdbg_operations = { + .owner = THIS_MODULE, + .open = tpdbg_open, + .read = tpdbg_read, + .write = tpdbg_write, + .release = tpdbg_release, +}; +#endif + +/** + * goodix_generic_noti_callback - generic notifier callback + * for goodix touch notification event. + */ +int goodix_generic_noti_callback(struct notifier_block *self, + unsigned long action, void *data) +{ + struct goodix_ts_core *ts_core = + container_of(self, struct goodix_ts_core, ts_notifier); + const struct goodix_ts_hw_ops *hw_ops = ts_hw_ops(ts_core); + int r; + + switch (action) { + case NOTIFY_FWUPDATE_END: + if (hw_ops->init) { + /* Firmware has been updated, we need to reinit + * the chip, read the sensor ID and send the + * correct config data based on sensor ID. + * The input parameters also needs to be updated.*/ + r = hw_ops->init(ts_core->ts_dev); + if (r < 0) + goto exit; + goodix_ts_set_input_params(ts_core->input_dev, + ts_core->ts_dev->board_data); + } + break; + } +exit: + return 0; +} + +static ssize_t goodix_lockdown_info_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + int cnt = 0, ret = 0; +#define TP_INFO_MAX_LENGTH 50 + char tmp[TP_INFO_MAX_LENGTH]; + + if (*pos != 0 || !goodix_core_data) + return 0; + + cnt = snprintf( + tmp, TP_INFO_MAX_LENGTH, + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", + goodix_core_data->lockdown_info[0], + goodix_core_data->lockdown_info[1], + goodix_core_data->lockdown_info[2], + goodix_core_data->lockdown_info[3], + goodix_core_data->lockdown_info[4], + goodix_core_data->lockdown_info[5], + goodix_core_data->lockdown_info[6], + goodix_core_data->lockdown_info[7]); + ret = copy_to_user(buf, tmp, cnt); + *pos += cnt; + if (ret != 0) + return 0; + else + return cnt; +} + +static const struct file_operations goodix_lockdown_info_ops = { + .read = goodix_lockdown_info_read, +}; + +static ssize_t goodix_panel_color_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + if (!goodix_core_data) + return 0; + + return snprintf(buf, PAGE_SIZE, "%c\n", + goodix_core_data->lockdown_info[2]); +} + +static ssize_t goodix_panel_vendor_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (!goodix_core_data) + return 0; + + return snprintf(buf, PAGE_SIZE, "%c\n", + goodix_core_data->lockdown_info[6]); +} + +static ssize_t goodix_panel_display_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (!goodix_core_data) + return 0; + + return snprintf(buf, PAGE_SIZE, "%c\n", + goodix_core_data->lockdown_info[1]); +} + +static ssize_t goodix_lockdown_info_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (!goodix_core_data) + return 0; + + return snprintf( + buf, PAGE_SIZE, + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", + goodix_core_data->lockdown_info[0], + goodix_core_data->lockdown_info[1], + goodix_core_data->lockdown_info[2], + goodix_core_data->lockdown_info[3], + goodix_core_data->lockdown_info[4], + goodix_core_data->lockdown_info[5], + goodix_core_data->lockdown_info[6], + goodix_core_data->lockdown_info[7]); +} + +static DEVICE_ATTR(lockdown_info, (S_IRUGO), goodix_lockdown_info_show, NULL); +static DEVICE_ATTR(panel_vendor, (S_IRUGO), goodix_panel_vendor_show, NULL); +static DEVICE_ATTR(panel_color, (S_IRUGO), goodix_panel_color_show, NULL); +static DEVICE_ATTR(panel_display, (S_IRUGO), goodix_panel_display_show, NULL); + +static struct attribute *goodix_attr_group[] = { + &dev_attr_panel_vendor.attr, + &dev_attr_panel_color.attr, + &dev_attr_panel_display.attr, + &dev_attr_lockdown_info.attr, + NULL, +}; + +static int gtp_i2c_test(void) +{ + int ret = 0; + u8 read_val = 0; + struct goodix_ts_device *ts_device; + ts_device = goodix_core_data->ts_dev; + + ret = ts_device->hw_ops->read_trans(ts_device, 0x3100, &read_val, 1); + if (!ret) { + ts_info("i2c test SUCCESS"); + } else { + ts_err("i2c test FAILED"); + return GTP_RESULT_FAIL; + } + + return GTP_RESULT_PASS; +} + +static ssize_t gtp_selftest_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + char tmp[5] = { 0 }; + int cnt; + + if (*pos != 0 || !goodix_core_data) + return 0; + cnt = snprintf(tmp, sizeof(goodix_core_data->result_type), "%d\n", + goodix_core_data->result_type); + if (copy_to_user(buf, tmp, strlen(tmp))) { + return -EFAULT; + } + *pos += cnt; + return cnt; +} + +static int gtp_short_open_test(void) +{ + int ret = 0; + + ret = goodix_tools_register(); + + if (ret) { + ts_err("tp_test prepare goodix_tools_register failed"); + return GTP_RESULT_INVALID; + } + ts_info("test start!"); + ret = test_process((void *)(&goodix_core_data->pdev->dev)); + + if (ret == 0) { + ts_err("test PASS!"); + return GTP_RESULT_PASS; + } else { + ts_err("test FAILED. result:%x", ret); + return GTP_RESULT_FAIL; + } + goodix_tools_unregister(); + + ts_info("test finish!"); + return GTP_RESULT_FAIL; +} +static ssize_t gtp_selftest_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + int retval = 0; + char tmp[6]; + + if (copy_from_user(tmp, buf, count)) { + retval = -EFAULT; + goto out; + } + if (!goodix_core_data) + return GTP_RESULT_INVALID; + + if (!strncmp("short", tmp, 5) || !strncmp("open", tmp, 4)) { + retval = gtp_short_open_test(); + } else if (!strncmp("i2c", tmp, 3)) + retval = gtp_i2c_test(); + + goodix_core_data->result_type = retval; +out: + if (retval >= 0) + retval = count; + + return retval; +} + +static const struct file_operations gtp_selftest_ops = { + .read = gtp_selftest_read, + .write = gtp_selftest_write, +}; + +static void gtp_power_supply_work(struct work_struct *work) +{ + struct goodix_ts_core *core_data = + container_of(work, struct goodix_ts_core, power_supply_work); + struct goodix_ts_device *dev = core_data->ts_dev; + u8 state_data[3]; + int is_usb_exist = 0; + + if (!atomic_read(&core_data->suspend_stat) && + !goodix_modules.core_exit) { + is_usb_exist = !!power_supply_is_system_supplied(); + if (is_usb_exist != core_data->is_usb_exist || + core_data->is_usb_exist < 0) { + core_data->is_usb_exist = is_usb_exist; + ts_info("Power_supply_event:%d", is_usb_exist); + if (is_usb_exist) { + state_data[0] = IS_USB_EXIST; + state_data[1] = 0x00; + state_data[2] = 0xFA; + goodix_i2c_write(dev, 0x6F68, state_data, 3); + ts_info("USB is exist"); + } else { + state_data[0] = IS_USB_NOT_EXIST; + state_data[1] = 0x00; + state_data[2] = 0xF9; + goodix_i2c_write(dev, 0x6F68, state_data, 3); + ts_info("USB is not exist"); + } + } + } +} +static int gtp_power_supply_event(struct notifier_block *nb, + unsigned long event, void *ptr) +{ + struct goodix_ts_core *ts_core = + container_of(nb, struct goodix_ts_core, power_supply_notifier); + + queue_work(ts_core->event_wq, &ts_core->power_supply_work); + + return 0; +} + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE +static struct xiaomi_touch_interface xiaomi_touch_interfaces; + +static int gtp_set_cur_value(int gtp_mode, int gtp_value) +{ + u8 state_data[3] = { 0 }; + u8 goodix_game_value = 0; + u8 temp_value = 0; + int ret = 0; + int i = 0; + + struct goodix_ts_device *dev = goodix_core_data->ts_dev; + /* + if (gtp_mode == Touch_Fod_Enable && goodix_core_data && gtp_value >= 0) { + ts_info("set fod status"); + goodix_core_data->fod_status = gtp_value; + goodix_core_data->gesture_enabled = goodix_core_data->double_wakeup | + goodix_core_data->fod_status | goodix_core_data->aod_status; + goodix_check_gesture_stat(!!goodix_core_data->fod_status); + return 0; + } + if (gtp_mode == Touch_Aod_Enable && goodix_core_data && gtp_value >= 0) { + ts_info("set aod status"); + goodix_core_data->aod_status = gtp_value; + goodix_core_data->gesture_enabled = goodix_core_data->double_wakeup | + goodix_core_data->fod_status | goodix_core_data->aod_status; + goodix_check_gesture_stat(!!goodix_core_data->aod_status); + return 0; + } +*/ + if (gtp_mode >= Touch_Mode_NUM && gtp_mode < 0) { + ts_err("gtp mode is error:%d", gtp_mode); + return -EINVAL; + } else if (xiaomi_touch_interfaces.touch_mode[gtp_mode][SET_CUR_VALUE] > + xiaomi_touch_interfaces.touch_mode[gtp_mode][GET_MAX_VALUE]) { + xiaomi_touch_interfaces.touch_mode[gtp_mode][SET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[gtp_mode][GET_MAX_VALUE]; + + } else if (xiaomi_touch_interfaces.touch_mode[gtp_mode][SET_CUR_VALUE] < + xiaomi_touch_interfaces.touch_mode[gtp_mode][GET_MIN_VALUE]) { + xiaomi_touch_interfaces.touch_mode[gtp_mode][SET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[gtp_mode][GET_MIN_VALUE]; + } + + xiaomi_touch_interfaces.touch_mode[gtp_mode][SET_CUR_VALUE] = gtp_value; + + if (gtp_mode == Touch_Game_Mode && gtp_value == 0) { + ts_info("exit touch game mode"); + state_data[0] = GTP_EXIT_GAME_CMD; + state_data[1] = 0x00; + state_data[2] = 0xF1; + ret = goodix_i2c_write(dev, GTP_GAME_CMD_ADD, state_data, 3); + if (ret < 0) { + ts_err("exit game mode fail"); + } + goodix_game_value = 0; + return ret; + } + + for (i = 0; i < Touch_Mode_NUM; i++) { + switch (i) { + case Touch_Game_Mode: + break; + case Touch_Active_MODE: + break; + case Touch_UP_THRESHOLD: + temp_value = xiaomi_touch_interfaces + .touch_mode[Touch_UP_THRESHOLD] + [SET_CUR_VALUE]; + goodix_game_value &= 0xFC; + goodix_game_value |= temp_value; + break; + case Touch_Tolerance: + temp_value = xiaomi_touch_interfaces + .touch_mode[Touch_Tolerance] + [SET_CUR_VALUE]; + temp_value = 3 - temp_value; + goodix_game_value &= 0xF3; + goodix_game_value |= (temp_value << 2); + break; + case Touch_Edge_Filter: + temp_value = xiaomi_touch_interfaces + .touch_mode[Touch_Edge_Filter] + [SET_CUR_VALUE]; + goodix_game_value &= 0xCF; + goodix_game_value |= (temp_value << 4); + break; + case Touch_Panel_Orientation: + /* 0,1,2,3 = 0, 90, 180,270 */ + temp_value = + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation] + [SET_CUR_VALUE]; + if (temp_value == 3) + temp_value = 2; + else if (temp_value == 2) + temp_value = 3; + goodix_game_value &= 0x3F; + goodix_game_value |= (temp_value << 6); + break; + default: + /* Don't support */ + break; + }; + } + ts_info("mode:%d, value:%d, write value:0x%x", gtp_mode, gtp_value, + goodix_game_value); + + xiaomi_touch_interfaces.touch_mode[gtp_mode][GET_CUR_VALUE] = + xiaomi_touch_interfaces.touch_mode[gtp_mode][SET_CUR_VALUE]; + + if (xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][SET_CUR_VALUE]) { + state_data[0] = GTP_GAME_CMD; + state_data[1] = goodix_game_value; + state_data[2] = 0xFF & (0 - state_data[0] - state_data[1]); + + ret = goodix_i2c_write(dev, GTP_GAME_CMD_ADD, state_data, 3); + + if (ret < 0) { + ts_err("change game mode fail"); + } + } + return ret; +} + +static int gtp_get_mode_value(int mode, int value_type) +{ + int value = -1; + + if (mode < Touch_Mode_NUM && mode >= 0) + value = xiaomi_touch_interfaces.touch_mode[mode][value_type]; + else + ts_err("don't support"); + + return value; +} + +static int gtp_get_mode_all(int mode, int *value) +{ + if (mode < Touch_Mode_NUM && mode >= 0) { + value[0] = + xiaomi_touch_interfaces.touch_mode[mode][GET_CUR_VALUE]; + value[1] = + xiaomi_touch_interfaces.touch_mode[mode][GET_DEF_VALUE]; + value[2] = + xiaomi_touch_interfaces.touch_mode[mode][GET_MIN_VALUE]; + value[3] = + xiaomi_touch_interfaces.touch_mode[mode][GET_MAX_VALUE]; + } else { + ts_err("don't support"); + } + ts_info("mode:%d, value:%d:%d:%d:%d", mode, value[0], value[1], + value[2], value[3]); + + return 0; +} + +static int gtp_reset_mode(int mode) +{ + int i = 0; + + if (mode < Touch_Mode_NUM && mode > 0) { + xiaomi_touch_interfaces.touch_mode[mode][SET_CUR_VALUE] = + xiaomi_touch_interfaces.touch_mode[mode][GET_DEF_VALUE]; + gtp_set_cur_value( + mode, + xiaomi_touch_interfaces.touch_mode[mode][SET_CUR_VALUE]); + } else if (mode == 0) { + for (i = 0; i < Touch_Mode_NUM; i++) { + xiaomi_touch_interfaces.touch_mode[i][SET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[i][GET_DEF_VALUE]; + gtp_set_cur_value( + mode, xiaomi_touch_interfaces + .touch_mode[mode][SET_CUR_VALUE]); + } + } else { + ts_err("don't support"); + } + + ts_info("mode:%d", mode); + + return 0; +} + +static void gtp_init_touchmode_data(void) +{ + int i; + + /* Touch Game Mode Switch */ + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_DEF_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_MAX_VALUE] = 1; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][SET_CUR_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_CUR_VALUE] = 0; + + /* Acitve Mode */ + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_MAX_VALUE] = + 1; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_MIN_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_DEF_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][SET_CUR_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_CUR_VALUE] = + 0; + + /* finger hysteresis */ + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_MAX_VALUE] = + 3; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_MIN_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_DEF_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][SET_CUR_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_CUR_VALUE] = + 0; + + /* Tolerance */ + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_MAX_VALUE] = 3; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_DEF_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][SET_CUR_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_CUR_VALUE] = 0; + + /* edge filter */ + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_MAX_VALUE] = + 3; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_MIN_VALUE] = + 1; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_DEF_VALUE] = + 1; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][SET_CUR_VALUE] = + 1; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_CUR_VALUE] = + 1; + + /* Orientation */ + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_MAX_VALUE] = 3; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_DEF_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][SET_CUR_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_CUR_VALUE] = 0; + + for (i = 0; i < Touch_Mode_NUM; i++) { + ts_info("mode:%d, set cur:%d, get cur:%d, def:%d min:%d max:%d\n", + i, xiaomi_touch_interfaces.touch_mode[i][SET_CUR_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_CUR_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_DEF_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_MIN_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_MAX_VALUE]); + } + + return; +} +#endif + +/** + * goodix_ts_probe - called by kernel when a Goodix touch + * platform driver is added. + */ +static int goodix_ts_probe(struct platform_device *pdev) +{ + struct goodix_ts_core *core_data = NULL; + struct goodix_ts_device *ts_device; + struct i2c_client *client = NULL; + int r; + u8 read_val = 0; + + ts_err("enter::%s\n", __func__); + ts_device = pdev->dev.platform_data; + if (!ts_device || !ts_device->hw_ops || !ts_device->board_data) { + ts_err("Invalid touch device"); + return -ENODEV; + } + + core_data = devm_kzalloc(&pdev->dev, sizeof(struct goodix_ts_core), + GFP_KERNEL); + if (!core_data) { + ts_err("Failed to allocate memory for core data"); + return -ENOMEM; + } + goodix_core_data = core_data; + + /* touch core layer is a platform driver */ + core_data->pdev = pdev; + core_data->ts_dev = ts_device; + platform_set_drvdata(pdev, core_data); + + client = to_i2c_client(ts_device->dev); + i2c_set_clientdata(client, core_data); + core_data->cfg_group_parsed = false; + + r = goodix_ts_power_init(core_data); + if (r < 0) { + pr_err("goodix_ts_power_init fail \n"); + goto out; + } + + r = goodix_ts_power_on(core_data); + if (r < 0) { + pr_err("goodix_ts_power_on fail \n"); + goto out; + } + +#ifdef CONFIG_PINCTRL + /* Pinctrl handle is optional. */ + r = goodix_ts_pinctrl_init(core_data); + if (!r && core_data->pinctrl) { + r = pinctrl_select_state(core_data->pinctrl, + core_data->pin_sta_active); + if (r < 0) + ts_err("Failed to select active pinstate, r:%d", r); + } +#endif + + /* get GPIO resource */ + r = goodix_ts_gpio_setup(core_data); + if (r < 0) { + pr_err("goodix_ts_gpio_setup fail \n"); + goto out; + } + /*init lock to protect suspend_stat*/ + mutex_init(&core_data->work_stat); + mutex_init(&ts_device->report_mutex); + /*init complete and pm status*/ + core_data->tp_already_suspend = false; + init_completion(&core_data->pm_resume_completion); + + /*create sysfs files*/ + goodix_ts_sysfs_init(core_data); + + r = ts_device->hw_ops->reset(ts_device); + if (r < 0) { + pr_err("goodix_hw_ops->reset fail \n"); + goto out; + } + + core_data->event_wq = + alloc_workqueue("gdt-event-queue", + WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); + if (!core_data->event_wq) { + ts_err("goodix cannot create work thread"); + r = -ENOMEM; + goto out; + } + + INIT_WORK(&core_data->resume_work, goodix_ts_resume_work); + INIT_WORK(&core_data->suspend_work, goodix_ts_suspend_work); + INIT_WORK(&core_data->sleep_work, goodix_ts_sleep_work); + device_init_wakeup(&pdev->dev, 1); + + core_data->is_usb_exist = -1; + /*i2c test*/ + r = ts_device->hw_ops->read_trans(ts_device, 0x3100, &read_val, 1); + if (!r) + ts_info("i2c test SUCCESS"); + else { + ts_err("i2c test FAILED"); + goto out; + } + + core_data->tp_lockdown_info_proc = proc_create( + "tp_lockdown_info", 0664, NULL, &goodix_lockdown_info_ops); + + /*unified protocl + * start a thread to parse cfg_bin and init IC*/ + r = goodix_start_cfg_bin(core_data); + if (!r) { + ts_info("***start cfg_bin_proc SUCCESS"); + } else { + ts_err("***start cfg_bin_proc FAILED"); + goto out; + } + + core_data->power_supply_notifier.notifier_call = gtp_power_supply_event; + power_supply_reg_notifier(&core_data->power_supply_notifier); + INIT_WORK(&core_data->power_supply_work, gtp_power_supply_work); + + core_data->bl_notifier.notifier_call = goodix_bl_state_chg_callback; + if (backlight_register_notifier(&core_data->bl_notifier) < 0) { + ts_err("ERROR:register bl_notifier failed\n"); + goto out; + } + core_data->attrs.attrs = goodix_attr_group; + r = sysfs_create_group(&client->dev.kobj, &core_data->attrs); + if (r) { + ts_err("ERROR: Cannot create sysfs structure!\n"); + r = -ENODEV; + goto out; + } + + if (core_data->gtp_tp_class == NULL) +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + core_data->gtp_tp_class = get_xiaomi_touch_class(); + if (core_data->gtp_tp_class == NULL) + ts_err("ERROR: gtp_tp_class is NULL!\n"); +#else + core_data->gtp_tp_class = class_create(THIS_MODULE, "touch"); +#endif + core_data->gtp_touch_dev = device_create(core_data->gtp_tp_class, NULL, + 0x5d, core_data, "tp_dev"); + if (IS_ERR(core_data->gtp_touch_dev)) { + ts_err("ERROR: Cannot create device for the sysfs!\n"); + goto out; + } + dev_set_drvdata(core_data->gtp_touch_dev, core_data); + + if (sysfs_create_file(&core_data->gtp_touch_dev->kobj, + &dev_attr_touch_suspend_notify.attr)) { + ts_err("Failed to create sysfs group!\n"); + goto out; + } + + if (sysfs_create_file(&core_data->gtp_touch_dev->kobj, + &dev_attr_fod_status.attr)) { + ts_err("Failed to create fod_status sysfs group!\n"); + goto out; + } + + if (sysfs_create_file(&core_data->gtp_touch_dev->kobj, + &dev_attr_fod_test.attr)) { + ts_err("Failed to create fod_test sysfs group!"); + goto out; + } + + core_data->tp_selftest_proc = + proc_create("tp_selftest", 0644, NULL, >p_selftest_ops); + +#ifdef CONFIG_GOODIX_HWINFO + core_data->dbclick_count = 0; +#endif + + /*core_data->fod_status = -1;*/ + //wake_lock_init(&core_data->tp_wakelock, WAKE_LOCK_SUSPEND, "touch_locker"); +#ifdef CONFIG_TOUCHSCREEN_GOODIX_DEBUG_FS + core_data->debugfs = debugfs_create_dir("tp_debug", NULL); + if (core_data->debugfs) { + debugfs_create_file("switch_state", 0660, core_data->debugfs, + core_data, &tpdbg_operations); + } +#endif +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + memset(&xiaomi_touch_interfaces, 0x00, + sizeof(struct xiaomi_touch_interface)); + xiaomi_touch_interfaces.getModeValue = gtp_get_mode_value; + xiaomi_touch_interfaces.setModeValue = gtp_set_cur_value; + xiaomi_touch_interfaces.resetMode = gtp_reset_mode; + xiaomi_touch_interfaces.getModeAll = gtp_get_mode_all; + xiaomitouch_register_modedata(&xiaomi_touch_interfaces); + gtp_init_touchmode_data(); +#endif + +out: + backlight_unregister_notifier(&core_data->bl_notifier); + ts_info("goodix_ts_probe OUT, r:%d", r); + return r; +} + +static int goodix_ts_remove(struct platform_device *pdev) +{ + struct goodix_ts_core *core_data = platform_get_drvdata(pdev); +#ifdef CONFIG_DRM + drm_unregister_client(&core_data->fb_notifier); +#endif + //wake_lock_destroy(&core_data->tp_wakelock); + power_supply_unreg_notifier(&core_data->power_supply_notifier); + goodix_ts_power_off(core_data); + goodix_debugfs_exit(); + goodix_ts_sysfs_exit(core_data); + return 0; +} + +#ifdef CONFIG_PM +static const struct dev_pm_ops dev_pm_ops = { + .suspend = goodix_ts_pm_suspend, + .resume = goodix_ts_pm_resume, +}; +#endif + +static const struct platform_device_id ts_core_ids[] = { + { .name = GOODIX_CORE_DRIVER_NAME }, + {} +}; +MODULE_DEVICE_TABLE(platform, ts_core_ids); + +static struct platform_driver goodix_ts_driver = { + .driver = { + .name = GOODIX_CORE_DRIVER_NAME, + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &dev_pm_ops, +#endif + }, + .probe = goodix_ts_probe, + .remove = goodix_ts_remove, + .id_table = ts_core_ids, +}; + +static int __init goodix_ts_core_init(void) +{ + ts_info("goodix9886 Core layer init"); + if (!goodix_modules.initilized) { + goodix_modules.initilized = true; + goodix_modules.core_exit = true; + INIT_LIST_HEAD(&goodix_modules.head); + mutex_init(&goodix_modules.mutex); + init_completion(&goodix_modules.core_comp); + } + goodix_debugfs_init(); + return platform_driver_register(&goodix_ts_driver); +} + +static void __exit goodix_ts_core_exit(void) +{ + ts_info("Core layer exit"); + platform_driver_unregister(&goodix_ts_driver); + return; +} + +module_init(goodix_ts_core_init); +module_exit(goodix_ts_core_exit); + +MODULE_DESCRIPTION("Goodix Touchscreen Core Module"); +MODULE_AUTHOR("Goodix, Inc."); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.h new file mode 100644 index 000000000000..c6033562578a --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.h @@ -0,0 +1,788 @@ +/* + * Goodix Touchscreen Driver + * Core layer of touchdriver architecture. + * + * Copyright (C) 2015 - 2016 Goodix, Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * Authors: Yulong Cai + * + * 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_TS_CORE_H_ +#define _GOODIX_TS_CORE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_OF +#include +#include +#endif +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#ifdef CONFIG_DRM +#include +#include +#include +#endif + +/* macros definition */ +#define GOODIX_CORE_DRIVER_NAME "goodix_ts" +#define GOODIX_DRIVER_VERSION "v1.2.0.1" +#define GOODIX_BUS_RETRY_TIMES 3 +#define GOODIX_MAX_TOUCH 10 +#define GOODIX_MAX_PEN 1 +#define GOODIX_MAX_KEY 3 +#define GOODIX_PEN_MAX_KEY 2 +#define GOODIX_CFG_MAX_SIZE 1024 +#define GOODIX_ESD_TICK_WRITE_DATA 0xAA +#define GOODIX_PID_MAX_LEN 8 +#define GOODIX_VID_MAX_LEN 8 +#define GOODIX_ESD_CHECK_INTERVAL 5 + +#define GOODIX_DEFAULT_CFG_NAME "goodix_config.cfg" + +#define IC_TYPE_NONE 0 +#define IC_TYPE_NORMANDY 1 +#define IC_TYPE_NANJING 2 + +#define GOODIX_TOUCH_EVENT 0x80 +#define GOODIX_REQUEST_EVENT 0x40 +#define GOODIX_GESTURE_EVENT 0x20 +#define GOODIX_HOTKNOT_EVENT 0x10 +#define GOODIX_LOCKDOWN_SIZE 8 + +#define CENTER_X 540 +#define CENTER_Y 2030 + +#define KEY_GOTO 0x162 +#define BTN_INFO 0x152 + +#define GTP_RESULT_INVALID 0 +#define GTP_RESULT_PASS 2 +#define GTP_RESULT_FAIL 1 + +#define GTP_GAME_CMD_ADD 0x6F68 +#define GTP_GAME_CMD 0x0E +#define GTP_EXIT_GAME_CMD 0x0F + +#define CONFIG_TOUCHSCREEN_GOODIX_DEBUG_FS + +#define CONFIG_GOODIX_HWINFO + +/* + * struct goodix_module - external modules container + * @head: external modules list + * @initilized: whether this struct is initilized + * @mutex: mutex lock + * @count: current number of registered external module + * @wq: workqueue to do register work + * @core_exit: if goodix touch core exit, then no + * registration is allowed. + * @core_data: core_data pointer + */ +struct goodix_module { + struct list_head head; + bool initilized; + struct mutex mutex; + unsigned int count; + struct workqueue_struct *wq; + bool core_exit; + struct completion core_comp; + struct goodix_ts_core *core_data; +}; + +/* + * struct goodix_ts_board_data - board data + * @avdd_name: name of analoy regulator + * @reset_gpio: reset gpio number + * @irq_gpio: interrupt gpio number + * @irq_flag: irq trigger type + * @power_on_delay_us: power on delay time (us) + * @power_off_delay_us: power off delay time (us) + * @swap_axis: whether swaw x y axis + * @panel_max_id: max supported fingers + * @panel_max_x/y/w/p: resolution and size + * @panel_max_key: max supported keys + * @pannel_key_map: key map + * @fw_name: name of the firmware image + */ +struct goodix_ts_board_data { + const char *avdd_name; + const char *vddio_name; + unsigned int avdd_load; + unsigned int reset_gpio; + unsigned int irq_gpio; + unsigned int vdd_gpio; + unsigned int avdd_gpio; + int irq; + unsigned int irq_flags; + + unsigned int power_on_delay_us; + unsigned int power_off_delay_us; + + unsigned int swap_axis; + unsigned int panel_max_id; /*max touch id*/ + unsigned int panel_max_x; + unsigned int panel_max_y; + unsigned int panel_max_w; /*major and minor*/ + unsigned int panel_max_p; /*pressure*/ + unsigned int panel_max_area; /*pressure*/ + unsigned int panel_max_overlapping_area; /*pressure*/ + unsigned int panel_max_key; + unsigned int panel_key_map[GOODIX_MAX_KEY + GOODIX_PEN_MAX_KEY]; + /*add by lishuai*/ + unsigned int x2x; + unsigned int y2y; + bool pen_enable; + unsigned int tp_key_num; + /*add end*/ + + const char *fw_name; + const char *limit_name; + const char *cfg_bin_name; + bool esd_default_on; +}; + +/* + * struct goodix_ts_config - chip config data + * @initialized: whether intialized + * @name: name of this config + * @lock: mutex + * @reg_base: register base of config data + * @length: bytes of the config + * @delay: delay time after sending config + * @data: config data buffer + */ +struct goodix_ts_config { + bool initialized; + char name[24]; + struct mutex lock; + unsigned int reg_base; + unsigned int length; + unsigned int delay; /*ms*/ + unsigned char data[GOODIX_CFG_MAX_SIZE]; +}; + +/* + * struct goodix_ts_cmd - command package + * @initialized: whether initialized + * @cmd_reg: command register + * @length: command length in bytes + * @cmds: command data + */ +#pragma pack(4) +struct goodix_ts_cmd { + u32 initialized; + u32 cmd_reg; + u32 length; + u8 cmds[3]; +}; +#pragma pack() + +/* interrupt event type */ +enum ts_event_type { + EVENT_INVALID, + EVENT_TOUCH, + EVENT_REQUEST, +}; + +/* requset event type */ +enum ts_request_type { + REQUEST_INVALID, + REQUEST_CONFIG, + REQUEST_BAKREF, + REQUEST_RESET, + REQUEST_MAINCLK, +}; + +/* notifier event */ + +enum ts_notify_event { + NOTIFY_FWUPDATE_START, + NOTIFY_FWUPDATE_END, + NOTIFY_SUSPEND, + NOTIFY_RESUME, + NOTIFY_ESD_OFF, + NOTIFY_ESD_ON, +}; + +/* suspend status*/ +enum tp_suspend_stat { + TP_NO_SUSPEND, + TP_GESTURE_DBCLK, + TP_GESTURE_FOD, + TP_GESTURE_DBCLK_FOD, + TP_SLEEP, +}; + +/* coordinate package */ +struct goodix_ts_coords { + int id; + unsigned int x, y, w, p, area, overlapping_area; +}; + +/* touch event data */ +struct goodix_touch_data { + /* finger */ + int touch_num; + struct goodix_ts_coords coords[GOODIX_MAX_TOUCH]; + /* key */ + u8 key_value; + bool have_key; + /*pen*/ + struct goodix_ts_coords pen_coords[GOODIX_MAX_PEN]; + bool pen_down; +}; + +/* request event data */ +struct goodix_request_data { + enum ts_request_type request_type; +}; + +/* + * struct goodix_ts_event - touch event struct + * @event_type: touch event type, touch data or + * request event + * @event_data: event data + */ +struct goodix_ts_event { + enum ts_event_type event_type; + union { + struct goodix_touch_data touch_data; + struct goodix_request_data request_data; + } event_data; +}; + +/* + * struct goodix_ts_version - firmware version + * @valid: whether these infomation is valid + * @pid: product id string + * @vid: firmware version code + * @cid: customer id code + * @sensor_id: sendor id + */ +struct goodix_ts_version { + bool valid; + char pid[GOODIX_PID_MAX_LEN]; + char vid[GOODIX_VID_MAX_LEN]; + u8 cid; + u8 sensor_id; +}; + +struct goodix_ts_regs { + u16 cfg_send_flag; + u16 version_base; + u8 version_len; + u16 pid; + u8 pid_len; + u16 vid; + u8 vid_len; + u16 sensor_id; + u8 sensor_id_mask; + u16 fw_mask; + u16 fw_status; + u16 cfg_addr; + u16 esd; + u16 command; + u16 coor; + u16 gesture; + u16 fw_request; + u16 proximity; +}; + +/* + * struct goodix_ts_device - ts device data + * @name: device name + * @version: reserved + * @bus_type: i2c or spi + * @board_data: board data obtained from dts + * @normal_cfg: normal config data + * @highsense_cfg: high sense config data + * @hw_ops: hardware operations + * @chip_version: firmware version infomation + * @sleep_cmd: sleep commang + * @gesture_cmd: gesture command + * @dev: device pointer,may be a i2c or spi device + * @of_node: device node + */ +struct goodix_ts_device { + char *name; + int version; + int bus_type; + u8 ic_type; + struct goodix_ts_regs reg; + int doze_mode_set_count; + struct mutex doze_mode_lock; + struct mutex report_mutex; + struct goodix_ts_board_data *board_data; + struct goodix_ts_config *normal_cfg; + struct goodix_ts_config *highsense_cfg; + const struct goodix_ts_hw_ops *hw_ops; + struct goodix_ts_version chip_version; + struct device *dev; +}; + +/* + * struct goodix_ts_hw_ops - hardware opeartions + * @init: hardware initialization + * @reset: hardware reset + * @read: read data from touch device + * @write: write data to touch device + * @send_cmd: send command to touch device + * @send_config: send configuration data + * @read_version: read firmware version + * @event_handler: touch event handler + * @suspend: put touch device into low power mode + * @resume: put touch device into working mode + */ +struct goodix_ts_hw_ops { + int (*init)(struct goodix_ts_device *dev); + int (*reset)(struct goodix_ts_device *dev); + int (*read)(struct goodix_ts_device *dev, unsigned int addr, + unsigned char *data, unsigned int len); + int (*write)(struct goodix_ts_device *dev, unsigned int addr, + unsigned char *data, unsigned int len); + int (*read_trans)(struct goodix_ts_device *dev, unsigned int addr, + unsigned char *data, unsigned int len); + int (*write_trans)(struct goodix_ts_device *dev, unsigned int addr, + unsigned char *data, unsigned int len); + int (*send_cmd)(struct goodix_ts_device *dev, + struct goodix_ts_cmd *cmd); + int (*send_config)(struct goodix_ts_device *dev, + struct goodix_ts_config *config); + int (*read_config)(struct goodix_ts_device *dev, u8 *config_data, + u32 config_len); + int (*read_version)(struct goodix_ts_device *dev, + struct goodix_ts_version *version); + int (*event_handler)(struct goodix_ts_device *dev, + struct goodix_ts_event *ts_event); + int (*check_hw)(struct goodix_ts_device *dev); + int (*suspend)(struct goodix_ts_device *dev); + int (*resume)(struct goodix_ts_device *dev); +}; + +/* + * struct goodix_ts_esd - esd protector structure + * @esd_work: esd delayed work + * @esd_on: true - turn on esd protection, false - turn + * off esd protection + * @esd_mutex: protect @esd_on flag + */ +struct goodix_ts_esd { + struct delayed_work esd_work; + struct mutex esd_mutex; + struct notifier_block esd_notifier; + struct goodix_ts_core *ts_core; + bool esd_on; +}; + +/* + * struct godix_ts_core - core layer data struct + * @pdev: core layer platform device + * @ts_dev: hardware layer touch device + * @input_dev: input device + * @avdd: analog regulator + * @pinctrl: pinctrl handler + * @pin_sta_active: active/normal pin state + * @pin_sta_suspend: suspend/sleep pin state + * @ts_event: touch event data struct + * @power_on: power on/off flag + * @irq: irq number + * @irq_enabled: irq enabled/disabled flag + * @suspended: suspend/resume flag + * @hw_err: indicate that hw_ops->init() failed + * @ts_notifier: generic notifier + * @ts_esd: esd protector structure + * @fb_notifier: framebuffer notifier + * @early_suspend: early suspend + */ +struct goodix_ts_core { + struct platform_device *pdev; + struct goodix_ts_device *ts_dev; + struct input_dev *input_dev; + + struct regulator *avdd; + struct regulator *vddio; +#ifdef CONFIG_PINCTRL + struct pinctrl *pinctrl; + struct pinctrl_state *pin_sta_active; + struct pinctrl_state *pin_sta_suspend; +#endif + struct goodix_ts_event ts_event; + unsigned long touch_id; + unsigned long sleep_finger; + unsigned long event_status; + unsigned int avdd_load; + unsigned char lockdown_info[GOODIX_LOCKDOWN_SIZE]; + + int power_on; + int irq; + size_t irq_trig_cnt; + + atomic_t irq_enabled; + atomic_t suspended; + + bool cfg_group_parsed; + struct attribute_group attrs; + + struct notifier_block ts_notifier; + struct goodix_ts_esd ts_esd; + + struct proc_dir_entry *tp_selftest_proc; + struct proc_dir_entry *tp_data_dump_proc; + struct proc_dir_entry *tp_fw_version_proc; + struct proc_dir_entry *tp_lockdown_info_proc; +#ifdef CONFIG_DRM + struct notifier_block fb_notifier; +#elif defined(CONFIG_HAS_EARLYSUSPEND) + struct early_suspend early_suspend; +#endif + struct notifier_block power_supply_notifier; + struct notifier_block bl_notifier; + struct workqueue_struct *event_wq; + struct work_struct suspend_work; + struct work_struct resume_work; + struct work_struct power_supply_work; + atomic_t suspend_stat; + int is_usb_exist; + int gesture_enabled; + int fod_status; + int aod_status; + int fod_pressed; + int fod_test; + int double_wakeup; + int result_type; + struct class *gtp_tp_class; + struct device *gtp_touch_dev; + char *current_clicknum_file; + struct mutex work_stat; + struct work_struct sleep_work; + bool tp_already_suspend; + bool palm_sensor_switch; + struct completion pm_resume_completion; +#ifdef CONFIG_TOUCHSCREEN_GOODIX_DEBUG_FS + struct dentry *debugfs; +#endif +#ifdef CONFIG_GOODIX_HWINFO + int dbclick_count; +#endif +}; + +struct goodix_mode_switch { + struct goodix_ts_core *info; + unsigned char mode; + struct work_struct switch_mode_work; +}; + +/* external module structures */ +enum goodix_ext_priority { + EXTMOD_PRIO_RESERVED = 0, + EXTMOD_PRIO_FWUPDATE, + EXTMOD_PRIO_GESTURE, + EXTMOD_PRIO_HOTKNOT, + EXTMOD_PRIO_DBGTOOL, + EXTMOD_PRIO_DEFAULT, +}; + +struct goodix_ext_module; +/* external module's operations callback */ +struct goodix_ext_module_funcs { + int (*init)(struct goodix_ts_core *core_data, + struct goodix_ext_module *module); + int (*exit)(struct goodix_ts_core *core_data, + struct goodix_ext_module *module); + + int (*before_reset)(struct goodix_ts_core *core_data, + struct goodix_ext_module *module); + int (*after_reset)(struct goodix_ts_core *core_data, + struct goodix_ext_module *module); + + int (*before_suspend)(struct goodix_ts_core *core_data, + struct goodix_ext_module *module); + int (*after_suspend)(struct goodix_ts_core *core_data, + struct goodix_ext_module *module); + + int (*before_resume)(struct goodix_ts_core *core_data, + struct goodix_ext_module *module); + int (*after_resume)(struct goodix_ts_core *core_data, + struct goodix_ext_module *module); + + int (*irq_event)(struct goodix_ts_core *core_data, + struct goodix_ext_module *module); +}; + +/* + * struct goodix_ext_module - external module struct + * @list: list used to link into modules manager + * @name: name of external module + * @priority: module priority vlaue, zero is invalid + * @funcs: operations callback + * @priv_data: private data region + * @kobj: kobject + * @work: used to queue one work to do registration + */ +struct goodix_ext_module { + struct list_head list; + char *name; + enum goodix_ext_priority priority; + const struct goodix_ext_module_funcs *funcs; + void *priv_data; + struct kobject kobj; + struct work_struct work; +}; + +/* + * struct goodix_ext_attribute - exteranl attribute struct + * @attr: attribute + * @show: show interface of external attribute + * @store: store interface of external attribute + */ +struct goodix_ext_attribute { + struct attribute attr; + ssize_t (*show)(struct goodix_ext_module *, char *); + ssize_t (*store)(struct goodix_ext_module *, const char *, size_t); +}; + +/* external attrs helper macro */ +#define __EXTMOD_ATTR(_name, _mode, _show, _store) \ + { \ + .attr = { .name = __stringify(_name), .mode = _mode }, \ + .show = _show, \ + .store = _store, \ + } + +/* external attrs helper macro, used to define external attrs */ +#define DEFINE_EXTMOD_ATTR(_name, _mode, _show, _store) \ + static struct goodix_ext_attribute ext_attr_##_name = \ + __EXTMOD_ATTR(_name, _mode, _show, _store); + +/* + * get board data pointer + */ +static inline struct goodix_ts_board_data * +board_data(struct goodix_ts_core *core) +{ + return core->ts_dev->board_data; +} + +/* + * get touch device pointer + */ +static inline struct goodix_ts_device *ts_device(struct goodix_ts_core *core) +{ + return core->ts_dev; +} + +/* + * get touch hardware operations pointer + */ +static inline const struct goodix_ts_hw_ops * +ts_hw_ops(struct goodix_ts_core *core) +{ + return core->ts_dev->hw_ops; +} + +/* + * checksum helper functions + * checksum can be u8/le16/be16/le32/be32 format + * NOTE: the caller shoule be responsible for the + * legality of @data and @size parameters, so be + * careful when call these functions. + */ +static inline u8 checksum_u8(u8 *data, u32 size) +{ + u8 checksum = 0; + u32 i; + for (i = 0; i < size; i++) + checksum += data[i]; + return checksum; +} + +static inline u16 checksum_le16(u8 *data, u32 size) +{ + u16 checksum = 0; + u32 i; + + for (i = 0; i < size; i += 2) + checksum += le16_to_cpup((__le16 *)(data + i)); + return checksum; +} + +static inline u16 checksum_be16(u8 *data, u32 size) +{ + u16 checksum = 0; + u32 i; + for (i = 0; i < size; i += 2) + checksum += be16_to_cpup((__be16 *)(data + i)); + return checksum; +} + +static inline u32 checksum_le32(u8 *data, u32 size) +{ + u32 checksum = 0; + u32 i; + for (i = 0; i < size; i += 4) + checksum += le32_to_cpup((__le32 *)(data + i)); + return checksum; +} + +static inline u32 checksum_be32(u8 *data, u32 size) +{ + u32 checksum = 0; + u32 i; + for (i = 0; i < size; i += 4) + checksum += be32_to_cpup((__be32 *)(data + i)); + return checksum; +} + +/* + * define event action + * EVT_xxx macros are used in opeartions callback + * defined in @goodix_ext_module_funcs to control + * the behaviors of event such as suspend/resume/irq_event. + * generally there are two types of behaviors: + * 1. you want the flow of this event be canceled, + * in this condition, you should return EVT_CANCEL_XXX in + * the operations callback. + * e.g. the firmware update module is updating + * the firmware, you want to cancel suspend flow, + * so you need to return EVT_CANCEL_SUSPEND in + * suspend callback function. + * 2. you want the flow of this event continue, in + * this condition, you should return EVT_HANDLED in + * the callback function. + * */ +#define EVT_HANDLED 0 +#define EVT_CONTINUE 0 +#define EVT_CANCEL 1 +#define EVT_CANCEL_IRQEVT 1 +#define EVT_CANCEL_SUSPEND 1 +#define EVT_CANCEL_RESUME 1 +#define EVT_CANCEL_RESET 1 + +/* + * errno define + * Note: + * 1. bus read/write functions defined in hardware + * layer code(e.g. goodix_xxx_i2c.c) *must* return + * -EBUS if failed to transfer data on bus. + */ +#define EBUS 1000 +#define ETIMEOUT 1001 +#define ECHKSUM 1002 +#define EMEMCMP 1003 + +#define CONFIG_GOODIX_DEBUG +/* log macro */ +#define ts_info(fmt, arg...) \ + pr_info("[GTP9886-INF][%s:%d] " fmt "\n", __func__, __LINE__, ##arg) +#define ts_err(fmt, arg...) \ + pr_err("[GTP9886-ERR][%s:%d] " fmt "\n", __func__, __LINE__, ##arg) +#define boot_log(fmt, arg...) g_info(fmt, ##arg) +#ifdef CONFIG_GOODIX_DEBUG +#define ts_debug(fmt, arg...) \ + pr_info("[GTP9886-DBG][%s:%d] " fmt "\n", __func__, __LINE__, ##arg) +#else +#define ts_debug(fmt, arg...) \ + do { \ + } while (0) +#endif + +/** + * goodix_register_ext_module - interface for external module + * to register into touch core modules structure + * + * @module: pointer to external module to be register + * return: 0 ok, <0 failed + */ +int goodix_register_ext_module(struct goodix_ext_module *module); + +/** + * goodix_unregister_ext_module - interface for external module + * to unregister external modules + * + * @module: pointer to external module + * return: 0 ok, <0 failed + */ +int goodix_unregister_ext_module(struct goodix_ext_module *module); + +/** + * goodix_ts_irq_enable - Enable/Disable a irq + + * @core_data: pointer to touch core data + * enable: enable or disable irq + * return: 0 ok, <0 failed + */ +int goodix_ts_irq_enable(struct goodix_ts_core *core_data, bool enable); + +struct kobj_type *goodix_get_default_ktype(void); + +/** + * fb_notifier_call_chain - notify clients of fb_events + * see enum ts_notify_event in goodix_ts_core.h + */ +int goodix_ts_blocking_notify(enum ts_notify_event evt, void *v); + +/** + * * goodix_ts_power_on - Turn on power to the touch device + * * @core_data: pointer to touch core data + * * return: 0 ok, <0 failed + * */ +int goodix_ts_power_on(struct goodix_ts_core *core_data); + +/** + * goodix_ts_power_off - Turn off power to the touch device + * @core_data: pointer to touch core data + * return: 0 ok, <0 failed + */ +int goodix_ts_power_off(struct goodix_ts_core *core_data); +int goodix_ts_hw_init(struct goodix_ts_core *core_data); +int goodix_ts_input_dev_config(struct goodix_ts_core *core_data); +int goodix_ts_irq_setup(struct goodix_ts_core *core_data); +int goodix_ts_sysfs_init(struct goodix_ts_core *core_data); +int goodix_ts_esd_init(struct goodix_ts_core *core); +int goodix_ts_register_notifier(struct notifier_block *nb); +int goodix_generic_noti_callback(struct notifier_block *self, + unsigned long action, void *data); +int goodix_ts_fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data); +extern void goodix_msg_printf(const char *fmt, ...); +int goodix_gesture_enable(bool enable); + +int goodix_check_gesture_stat(bool enable); + +int goodix_get_lockdowninfo(struct goodix_ts_core *ts_core); +extern int sync_read_rawdata(unsigned int reg, unsigned char *data, + unsigned int len); +extern int goodix_tools_register(void); +extern int goodix_tools_unregister(void); +extern struct goodix_ts_core *goodix_core_data; +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_gesture.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_gesture.c new file mode 100644 index 000000000000..5cfebdea0eb3 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_gesture.c @@ -0,0 +1,756 @@ +/* + * Goodix GTX5 Gesture Dirver + * + * Copyright (C) 2015 - 2016 Goodix, Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * Authors: Wang Yafei + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "goodix_ts_core.h" + +#define GSX_REG_GESTURE_DATA 0x4100 +#define GSX_REG_GESTURE 0x6F68 + +#define GSX_GESTURE_CMD 0x08 + +#define QUERYBIT(longlong, bit) (!!(longlong[bit / 8] & (1 << bit % 8))) + +extern int goodix_i2c_write(struct goodix_ts_device *dev, unsigned int reg, + unsigned char *data, unsigned int len); +extern int goodix_i2c_read(struct goodix_ts_device *dev, unsigned int reg, + unsigned char *data, unsigned int len); +static int goodix_set_suspend_func(struct goodix_ts_core *core_data); +static int goodix_wakeup_and_set_suspend_func(struct goodix_ts_core *core_data); + +#define GSX_KEY_DATA_LEN 37 +#define GSX_GESTURE_TYPE_LEN 32 +static int FP_Event_Gesture; + +/* + * struct gesture_module - gesture module data + * @registered: module register state + * @sysfs_node_created: sysfs node state + * @gesture_type: store valied gesture type,each bit stand for a gesture + * @gesture_data: gesture data + * @gesture_ts_cmd: gesture command data +*/ +struct gesture_module { + atomic_t registered; + unsigned int kobj_initialized; + rwlock_t rwlock; + unsigned char gesture_type[GSX_GESTURE_TYPE_LEN]; + unsigned char gesture_data[GSX_KEY_DATA_LEN]; + struct goodix_ext_module module; + struct goodix_ts_cmd cmd; +}; + +extern struct goodix_module goodix_modules; /*declaration at goodix_ts_core.c*/ + +static struct gesture_module *gsx_gesture; /*allocated in gesture init module*/ + +/** + * gsx_gesture_type_show - show valid gesture type + * + * @module: pointer to goodix_ext_module struct + * @buf: pointer to output buffer + * Returns >=0 - succeed,< 0 - failed + */ +static ssize_t gsx_gesture_type_show(struct goodix_ext_module *module, + char *buf) +{ + int count = 0, i, ret = 0; + unsigned char *type; + + if (atomic_read(&gsx_gesture->registered) != 1) { + ts_info("Gesture module not register!"); + return -EPERM; + } + type = kzalloc(256, GFP_KERNEL); + if (!type) + return -ENOMEM; + read_lock(&gsx_gesture->rwlock); + for (i = 0; i < 256; i++) { + if (QUERYBIT(gsx_gesture->gesture_type, i)) { + type[count] = i; + count++; + } + } + type[count] = '\0'; + if (count > 0) { + /* TODO 这里使用scnprintf需è¦ç¡®è®¤ä¸€ä¸‹æ˜¯å¦æœ‰æ•ˆ */ + ret = scnprintf(buf, PAGE_SIZE, "%s", type); + } + read_unlock(&gsx_gesture->rwlock); + + kfree(type); + return ret; +} + +/** + * gsx_gesture_type_store - set vailed gesture + * + * @module: pointer to goodix_ext_module struct + * @buf: pointer to valid gesture type + * @count: length of buf + * Returns >0 - valid gestures, < 0 - failed + */ +static ssize_t gsx_gesture_type_store(struct goodix_ext_module *module, + const char *buf, size_t count) +{ + int i; + + if (count <= 0 || count > 256 || buf == NULL) { + ts_err("Parameter error"); + return -EINVAL; + } + + write_lock(&gsx_gesture->rwlock); + memset(gsx_gesture->gesture_type, 0, GSX_GESTURE_TYPE_LEN); + for (i = 0; i < count; i++) + gsx_gesture->gesture_type[buf[i] / 8] |= (0x1 << buf[i] % 8); + write_unlock(&gsx_gesture->rwlock); + + return count; +} + +static ssize_t gsx_gesture_enable_show(struct goodix_ext_module *module, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d\n", + atomic_read(&gsx_gesture->registered)); +} + +static ssize_t gsx_gesture_enable_store(struct goodix_ext_module *module, + const char *buf, size_t count) +{ + unsigned int tmp; + int ret; + + if (sscanf(buf, "%u", &tmp) != 1) { + ts_info("Parameter illegal"); + return -EINVAL; + } + ts_debug("Tmp value =%d", tmp); + + if (tmp == 1) { + if (atomic_read(&gsx_gesture->registered)) { + ts_debug("Gesture module has aready registered"); + return count; + } + ret = goodix_register_ext_module(&gsx_gesture->module); + if (!ret) { + ts_info("Gesture module registered!"); + atomic_set(&gsx_gesture->registered, 1); + } else { + atomic_set(&gsx_gesture->registered, 0); + ts_err("Gesture module register failed"); + } + } else if (tmp == 0) { + if (!atomic_read(&gsx_gesture->registered)) { + ts_debug("Gesture module has aready unregistered"); + return count; + } + ts_debug("Start unregistered gesture module"); + ret = goodix_unregister_ext_module(&gsx_gesture->module); + if (!ret) { + atomic_set(&gsx_gesture->registered, 0); + ts_info("Gesture module unregistered success"); + } else { + atomic_set(&gsx_gesture->registered, 1); + ts_info("Gesture module unregistered failed"); + } + } else { + ts_err("Parameter error!"); + return -EINVAL; + } + return count; +} + +int goodix_gesture_enable(bool enable) +{ + int ret = 0; + + if (enable == true) { + if (atomic_read(&gsx_gesture->registered)) { + ts_debug("Gesture module has aready registered"); + return 0; + } + ret = goodix_register_ext_module(&gsx_gesture->module); + if (!ret) { + ts_info("Gesture module registered!"); + atomic_set(&gsx_gesture->registered, 1); + } else { + atomic_set(&gsx_gesture->registered, 0); + ts_err("Gesture module register failed"); + } + } else { + if (!atomic_read(&gsx_gesture->registered)) { + ts_debug("Gesture module has aready unregistered"); + return 0; + } + ts_debug("Start unregistered gesture module"); + ret = goodix_unregister_ext_module(&gsx_gesture->module); + if (!ret) { + atomic_set(&gsx_gesture->registered, 0); + ts_info("Gesture module unregistered success"); + } else { + atomic_set(&gsx_gesture->registered, 1); + ts_info("Gesture module unregistered failed"); + } + } + + return 0; +} + +int goodix_sync_ic_stat(struct goodix_ts_core *core_data) +{ + int tp_stat; + int ret = 0; + + if (!core_data) { + ts_err("parameter illegal"); + } + + mutex_lock(&core_data->work_stat); + tp_stat = atomic_read(&core_data->suspend_stat); + if (tp_stat == TP_GESTURE_DBCLK) { + ts_info("sync IC suspend stat from DBCLK to DBCLK_FOD"); + + /*TODO:maybe add retry here*/ + ret = goodix_set_suspend_func(core_data); + if (ret < 0) + ts_err("set suspend function failed!!"); + } else if (tp_stat == TP_SLEEP) { + ts_info("sync IC suspend stat from SLEEP to FOD"); + + ret = goodix_wakeup_and_set_suspend_func(core_data); + if (ret < 0) + ts_err("set suspend function failed!!"); + } + mutex_unlock(&core_data->work_stat); + + return ret; +} + +int goodix_check_gesture_stat(bool enable) +{ + if (enable) { + goodix_sync_ic_stat(goodix_core_data); + } + return 0; +} +/** + * gsx_gesture_data_show - show gesture data read frome IC + * + * @module: pointer to goodix_ext_module struct + * @buf: pointer to output buffer + * Returns >0 - gesture data length,< 0 - failed + */ +/*static ssize_t gsx_gesture_data_show(struct goodix_ext_module *module, + char *buf) +{ + int count = GSX_KEY_DATA_LEN; + + if (atomic_read(&gsx_gesture->registered) != 1) { + ts_info("Gesture module not register!"); + return -EPERM; + } + if (!buf || !gsx_gesture->gesture_data) { + ts_info("Parameter error!"); + return -EPERM; + } + read_lock(&gsx_gesture->rwlock); + memcpy(buf, gsx_gesture->gesture_data, count); + read_unlock(&gsx_gesture->rwlock); + + return count; +}*/ + +static ssize_t gsx_gesture_data_show(struct goodix_ext_module *module, + char *buf) +{ + int count = GSX_KEY_DATA_LEN; + + if (atomic_read(&gsx_gesture->registered) != 1) { + ts_info("Gesture module not register!"); + return -EPERM; + } + if (!buf || !*(gsx_gesture->gesture_data)) { + ts_info("Parameter error!"); + return -EPERM; + } + read_lock(&gsx_gesture->rwlock); + + count = scnprintf(buf, PAGE_SIZE, "Previous gesture type:0x%x\n", + gsx_gesture->gesture_data[2]); + read_unlock(&gsx_gesture->rwlock); + + return count; +} + +const struct goodix_ext_attribute gesture_attrs[] = { + __EXTMOD_ATTR(type, 0666, gsx_gesture_type_show, + gsx_gesture_type_store), + __EXTMOD_ATTR(enable, 0666, gsx_gesture_enable_show, + gsx_gesture_enable_store), + __EXTMOD_ATTR(data, 0444, gsx_gesture_data_show, NULL) +}; + +static int gsx_gesture_init(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + int i, ret; + struct goodix_ts_device *ts_dev = core_data->ts_dev; + + if (!core_data || !ts_dev->hw_ops->write || !ts_dev->hw_ops->read) { + ts_err("Register gesture module failed, ts_core unsupported"); + goto exit_gesture_init; + } + + gsx_gesture->cmd.cmd_reg = GSX_REG_GESTURE; + gsx_gesture->cmd.length = 3; + gsx_gesture->cmd.cmds[0] = GSX_GESTURE_CMD; + gsx_gesture->cmd.cmds[1] = 0x0; + gsx_gesture->cmd.cmds[2] = 0 - GSX_GESTURE_CMD; + gsx_gesture->cmd.initialized = 1; + + memset(gsx_gesture->gesture_type, 0, GSX_GESTURE_TYPE_LEN); + memset(gsx_gesture->gesture_data, 0xff, GSX_KEY_DATA_LEN); + + ts_debug("Set gesture type manually"); + memset(gsx_gesture->gesture_type, 0xff, GSX_GESTURE_TYPE_LEN); + /*gsx_gesture->gesture_type[34/8] |= (0x1 << 34%8);*/ /* 0x22 double click */ + /*gsx_gesture->gesture_type[170/8] |= (0x1 << 170%8);*/ /* 0xaa up swip */ + /*gsx_gesture->gesture_type[187/8] |= (0x1 << 187%8);*/ /* 0xbb right swip */ + /*gsx_gesture->gesture_type[171/8] |= (0x1 << 171%8);*/ /* 0xab down swip */ + /*gsx_gesture->gesture_type[186/8] |= (0x1 << 186%8);*/ /* 0xba left swip */ + + if (gsx_gesture->kobj_initialized) + goto exit_gesture_init; + + ret = kobject_init_and_add(&module->kobj, goodix_get_default_ktype(), + &core_data->pdev->dev.kobj, "gesture"); + + if (ret) { + ts_err("Create gesture sysfs node error!"); + goto exit_gesture_init; + } + + for (i = 0; i < sizeof(gesture_attrs) / sizeof(gesture_attrs[0]); i++) { + if (sysfs_create_file(&module->kobj, &gesture_attrs[i].attr)) { + ts_err("Create sysfs attr file error"); + kobject_put(&module->kobj); + goto exit_gesture_init; + } + } + gsx_gesture->kobj_initialized = 1; + +exit_gesture_init: + return 0; +} +static int gsx_gesture_exit(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + /*if (gsx_gesture->kobj_initialized) + kobject_put(&module->kobj); + gsx_gesture->kobj_initialized = 0;*/ + atomic_set(&gsx_gesture->registered, 0); + return 0; +} + +/** + * gsx_gesture_ist - Gesture Irq handle + * This functions is excuted when interrupt happended and + * ic in doze mode. + * + * @core_data: pointer to touch core data + * @module: pointer to goodix_ext_module struct + * return: 0 goon execute, EVT_CANCEL_IRQEVT stop execute + */ +static int gsx_gesture_ist(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + int ret; + int x, y, area, overlapping_area; + unsigned char clear_reg = 0; + unsigned char checksum = 0, temp_data[GSX_KEY_DATA_LEN]; + struct goodix_ts_device *ts_dev = core_data->ts_dev; +#ifdef CONFIG_GOODIX_HWINFO + char ch[64] = { + 0x0, + }; +#endif + + /*ts_debug("gsx_gesture_ist, core_data-suspend=%d", + atomic_read(&core_data->suspended));*/ + /*ts_err("enter %s core_data->suspended=%d\n", __func__, atomic_read(&core_data->suspended));*/ + if (atomic_read(&core_data->suspended) == 0) + return EVT_CONTINUE; + + mutex_lock(&ts_dev->report_mutex); + /* get ic gesture state*/ + ret = ts_dev->hw_ops->read_trans(core_data->ts_dev, + GSX_REG_GESTURE_DATA, temp_data, + sizeof(temp_data)); + /*ts_err("enter %s temp_data[0]=0x%x ret=%d\n", __func__, temp_data[0], ret);*/ + if (ret < 0 || ((temp_data[0] & GOODIX_GESTURE_EVENT) == 0)) { + ts_err("Read gesture data faild, ret=%d, temp_data[0]=0x%x", + ret, temp_data[0]); + goto re_send_ges_cmd; + } + + if ((temp_data[0] & 0x08) != 0) { + FP_Event_Gesture = 1; + /*ts_debug("FP_Event_Gesture = %d", FP_Event_Gesture);*/ + } + + checksum = checksum_u8(temp_data, sizeof(temp_data)); + if (checksum != 0) { + ts_err("Gesture data checksum error:0x%x", checksum); + ts_info("Gesture data %*ph", (int)sizeof(temp_data), temp_data); + goto re_send_ges_cmd; + } + + /*ts_debug("temp_data: %*ph", (int)sizeof(temp_data), temp_data); + ts_debug("FP_Event_Gesture: %d", FP_Event_Gesture); + ts_debug("fod_status= %d aod_status=%d", core_data->fod_status, core_data->aod_status); + ts_debug("sleep_finger: %d", !core_data->sleep_finger);*/ + + if (core_data->fod_status || core_data->aod_status) { + if ((FP_Event_Gesture == 1) && (temp_data[2] == 0x46)) { + x = temp_data[4] | (temp_data[5] << 8); + y = temp_data[6] | (temp_data[7] << 8); + overlapping_area = temp_data[8]; + area = temp_data[9]; + + input_mt_slot(core_data->input_dev, 0); + input_mt_report_slot_state(core_data->input_dev, + MT_TOOL_FINGER, true); + input_report_key(core_data->input_dev, BTN_INFO, 1); + /*input_report_key(core_data->input_dev, KEY_INFO, 1);*/ + input_report_key(core_data->input_dev, BTN_TOUCH, 1); + input_report_key(core_data->input_dev, BTN_TOOL_FINGER, + 1); + input_report_abs(core_data->input_dev, ABS_MT_TOOL_TYPE, + MT_TOOL_FINGER); + input_report_abs(core_data->input_dev, + ABS_MT_POSITION_X, x); + input_report_abs(core_data->input_dev, + ABS_MT_POSITION_Y, y); + input_report_abs(core_data->input_dev, + ABS_MT_WIDTH_MINOR, overlapping_area); + /*input_report_abs(core_data->input_dev, ABS_MT_TOUCH_MINOR, area);*/ + + core_data->fod_pressed = true; + __set_bit(0, &core_data->touch_id); + + ts_debug( + "Gesture report, x=%d, y=%d, overlapping_area=%d, area=%d", + x, y, overlapping_area, area); + + /*wait for report key event*/ + FP_Event_Gesture = 0; + input_sync(core_data->input_dev); + } + + if ((FP_Event_Gesture == 1) && (temp_data[2] == 0x4c)) { + /*wait for report key event*/ + FP_Event_Gesture = 0; + input_report_key(core_data->input_dev, KEY_GOTO, 1); + input_sync(core_data->input_dev); + input_report_key(core_data->input_dev, KEY_GOTO, 0); + input_sync(core_data->input_dev); + core_data->sleep_finger = 0; + ts_debug("Gesture report L"); + } + + if ((FP_Event_Gesture == 1) && (temp_data[2] == 0xff)) { + if (core_data->fod_pressed) { + ts_debug("Gesture report up"); + input_mt_slot(core_data->input_dev, 0); + input_mt_report_slot_state(core_data->input_dev, + MT_TOOL_FINGER, + false); + input_report_abs(core_data->input_dev, + ABS_MT_WIDTH_MINOR, 0); + input_report_key(core_data->input_dev, BTN_INFO, + 0); + /*input_report_key(core_data->input_dev, KEY_INFO, 0);*/ + input_report_key(core_data->input_dev, + BTN_TOUCH, 0); + input_report_key(core_data->input_dev, + BTN_TOOL_FINGER, 0); + input_sync(core_data->input_dev); + __clear_bit(0, &core_data->touch_id); + core_data->fod_pressed = false; + } + core_data->sleep_finger = 0; + } + + write_lock(&gsx_gesture->rwlock); + memcpy(gsx_gesture->gesture_data, temp_data, sizeof(temp_data)); + write_unlock(&gsx_gesture->rwlock); + } + + if (temp_data[2] == 0xcc && core_data->double_wakeup) { + /*ts_info("Gesture match success, resume IC");*/ +#ifdef CONFIG_GOODIX_HWINFO + if (core_data) { + core_data->dbclick_count++; + snprintf(ch, sizeof(ch), "%d", + core_data->dbclick_count); + } +#endif + input_report_key(core_data->input_dev, KEY_WAKEUP, 1); + input_sync(core_data->input_dev); + input_report_key(core_data->input_dev, KEY_WAKEUP, 0); + input_sync(core_data->input_dev); + goto gesture_ist_exit; + } + if (QUERYBIT(gsx_gesture->gesture_type, temp_data[2])) { + /* do resume routine */ + /*ts_info("Gesture match success, resume IC");*/ + + goto gesture_ist_exit; + } else { + ts_info("Unsupported gesture:%x", temp_data[2]); + } + +re_send_ges_cmd: + /*if (ts_dev->hw_ops->send_cmd(core_data->ts_dev, gesture_cmd)) + ts_info("warning: failed re_send gesture cmd\n");*/ + if (goodix_set_suspend_func(core_data) < 0) + ts_err("set suspend function failed!!"); +gesture_ist_exit: + ts_dev->hw_ops->write_trans(core_data->ts_dev, GSX_REG_GESTURE_DATA, + &clear_reg, 1); + mutex_unlock(&ts_dev->report_mutex); + return EVT_CANCEL_IRQEVT; +} + +/** + *goodix_set_suspend_func - send cmd choose func when at suspend stat + *When cmd send successful,IC in doze mode + * + * @core_data: pointer to touch core data + * return: 0 send cmd successful, other send cmd failed. + */ +static int goodix_set_suspend_func(struct goodix_ts_core *core_data) +{ + struct goodix_ts_device *dev = core_data->ts_dev; + u8 state_data[3] = { 0 }; + int ret; + + if (core_data->double_wakeup && core_data->fod_status) { + state_data[0] = GSX_GESTURE_CMD; + state_data[1] = 0x01; + state_data[2] = 0xF7; + ret = goodix_i2c_write(dev, GSX_REG_GESTURE, state_data, 3); + ts_info("Set IC double wakeup mode on,FOD mode on;"); + } else if (core_data->double_wakeup && (!core_data->fod_status)) { + state_data[0] = GSX_GESTURE_CMD; + state_data[1] = 0x03; + state_data[2] = 0xF5; + ret = goodix_i2c_write(dev, GSX_REG_GESTURE, state_data, 3); + ts_info("Set IC double wakeup mode on,FOD mode off;"); + } else if (!core_data->double_wakeup && core_data->fod_status) { + state_data[0] = GSX_GESTURE_CMD; + state_data[1] = 0x00; + state_data[2] = 0xF8; + ret = goodix_i2c_write(dev, GSX_REG_GESTURE, state_data, 3); + ts_info("Set IC double wakeup mode off,FOD mode on;"); + } else if (!core_data->double_wakeup && (!core_data->fod_status)) { + state_data[0] = GSX_GESTURE_CMD; + state_data[1] = 0x02; + state_data[2] = 0xF6; + ret = goodix_i2c_write(dev, GSX_REG_GESTURE, state_data, 3); + ts_info("Set IC double wakeup mode off,FOD mode off;"); + } else { + ret = -1; + ts_info("Get IC mode falied,core_data->double_wakeup=%d,core_data->fod_status=%d;", + core_data->double_wakeup, core_data->fod_status); + } + + return ret; +} + +/** + *goodix_wakeup_and_set_suspend_func --- wake up ic from sleep mode and set suspend func + *invoke this func when ic in sleep mode + * + * @core_data: pointer to touch core data + * return: 0 reset ic stat successful, other failed. + */ +static int goodix_wakeup_and_set_suspend_func(struct goodix_ts_core *core_data) +{ + int r = 0; + int retry = 0; + struct goodix_ext_module *ext_module; + struct goodix_ts_device *ts_dev = core_data->ts_dev; + + /*start resume*/ + if (!list_empty(&goodix_modules.head)) { + list_for_each_entry(ext_module, &goodix_modules.head, list) { + if (!ext_module->funcs->before_resume) + continue; + + do { + r = ext_module->funcs->before_resume( + core_data, ext_module); + if (r == EVT_CANCEL_RESUME) { + ts_info("wait for fwupdate findish"); + mdelay(5); + } + } while (r == EVT_CANCEL_RESUME && ++retry < 3); + } + } + + if (ts_dev && ts_dev->hw_ops->resume) + ts_dev->hw_ops->resume(ts_dev); + goodix_ts_irq_enable(core_data, true); + /*finish resume*/ + + /*start suspend*/ + do { + r = goodix_set_suspend_func(core_data); + if (r < 0) { + ts_info("Send doze command failed, retry"); + } + } while (r < 0 && ++retry < 3); + + if (core_data->double_wakeup && core_data->fod_status) { + atomic_set(&core_data->suspend_stat, TP_GESTURE_DBCLK_FOD); + } else if (core_data->double_wakeup) { + atomic_set(&core_data->suspend_stat, TP_GESTURE_DBCLK); + } else if (core_data->fod_status) { + atomic_set(&core_data->suspend_stat, TP_GESTURE_FOD); + } + ts_info("suspend_stat[%d]", atomic_read(&core_data->suspend_stat)); + + /*finish suspend*/ + + return r; +} + +/** + * gsx_gesture_before_suspend - execute gesture suspend routine + * This functions is excuted to set ic into doze mode + * + * @core_data: pointer to touch core data + * @module: pointer to goodix_ext_module struct + * return: 0 goon execute, EVT_IRQCANCLED stop execute + */ +static int gsx_gesture_before_suspend(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + int ret; + const struct goodix_ts_hw_ops *hw_ops = core_data->ts_dev->hw_ops; + struct goodix_ts_cmd *gesture_cmd = &gsx_gesture->cmd; + + if (!gesture_cmd->initialized || hw_ops == NULL) { + ts_err("Uninitialized doze command or hw_ops"); + return 0; + } + + if (!core_data->gesture_enabled) { + ts_err("enter %s\n", __func__); + atomic_set(&core_data->suspended, 1); + return EVT_CONTINUE; + } + + ret = goodix_set_suspend_func(core_data); + if (ret != 0) { + ts_err("Send doze command error"); + return 0; + } else { + ts_info("Set IC in doze mode"); + atomic_set(&core_data->suspended, 1); + return EVT_CANCEL_SUSPEND; + } +} + +/** + * gsx_gesture_before_resume - execute gesture resume routine + * This functions is excuted to make ic out doze mode + * + * @core_data: pointer to touch core data + * @module: pointer to goodix_ext_module struct + * return: 0 goon execute, EVT_CANCLED stop execute + * +static int gsx_gesture_before_resume(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + struct goodix_ts_device *ts_dev = core_data->ts_dev; + + ts_dev->hw_ops->reset(ts_dev); + return 0; +} +*/ + +static struct goodix_ext_module_funcs gsx_gesture_funcs = { + .irq_event = gsx_gesture_ist, + .init = gsx_gesture_init, + .exit = gsx_gesture_exit, + .before_suspend = gsx_gesture_before_suspend +}; + +static int __init goodix_gsx_gesture_init(void) +{ + /* initialize core_data->ts_dev->gesture_cmd*/ + int result; + ts_info("gesture module init"); + gsx_gesture = kzalloc(sizeof(struct gesture_module), GFP_KERNEL); + if (!gsx_gesture) + result = -ENOMEM; + gsx_gesture->module.funcs = &gsx_gesture_funcs; + gsx_gesture->module.priority = EXTMOD_PRIO_GESTURE; + gsx_gesture->module.name = "Goodix_gsx_gesture"; + gsx_gesture->module.priv_data = gsx_gesture; + gsx_gesture->kobj_initialized = 0; + atomic_set(&gsx_gesture->registered, 0); + rwlock_init(&gsx_gesture->rwlock); + + result = goodix_register_ext_module(&(gsx_gesture->module)); + if (result == 0) + atomic_set(&gsx_gesture->registered, 1); + + return result; +} + +static void __exit goodix_gsx_gesture_exit(void) +{ + ts_info("gesture module exit"); + if (gsx_gesture->kobj_initialized) + kobject_put(&gsx_gesture->module.kobj); + kfree(gsx_gesture); + return; +} + +module_init(goodix_gsx_gesture_init); +module_exit(goodix_gsx_gesture_exit); + +MODULE_DESCRIPTION("Goodix gsx Touchscreen Gesture Module"); +MODULE_AUTHOR("Goodix, Inc."); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_i2c.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_i2c.c new file mode 100644 index 000000000000..e9aa14f30a20 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_i2c.c @@ -0,0 +1,2230 @@ +/* + * Goodix GTx5 I2C Dirver + * Hardware interface layer of touchdriver architecture. + * + * Copyright (C) 2015 - 2016 Goodix, Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * Authors: Yulong Cai + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include "goodix_ts_core.h" +#include "goodix_cfg_bin.h" +#include +#include + +#define TS_DT_COMPATIBLE "goodix,gt9889" +#define TS_DRIVER_NAME "goodix_i2c" +#define I2C_MAX_TRANSFER_SIZE 256 +#define TS_ADDR_LENGTH 2 +#define TS_DOZE_ENABLE_RETRY_TIMES 10 +#define TS_DOZE_DISABLE_RETRY_TIMES 10 +#define TS_WAIT_CFG_READY_RETRY_TIMES 30 +#define TS_WAIT_CMD_FREE_RETRY_TIMES 10 + +#define TS_REG_COORDS_BASE 0x824E +#define TS_REG_CMD 0x8040 +#define TS_REG_REQUEST 0x8044 +#define TS_REG_VERSION 0x8240 +#define TS_REG_CFG_BASE 0x8050 +#define TS_REG_DOZE_CTRL 0x30F0 +#define TS_REG_DOZE_STAT 0x3100 +#define TS_REG_ESD_TICK_R 0x3103 + +#define CFG_XMAX_OFFSET (0x8052 - 0x8050) +#define CFG_YMAX_OFFSET (0x8054 - 0x8050) + +#define REQUEST_HANDLED 0x00 +#define REQUEST_CONFIG 0x01 +#define REQUEST_BAKREF 0x02 +#define REQUEST_RESET 0x03 +#define REQUEST_MAINCLK 0x04 +#define REQUEST_IDLE 0x05 + +#define COMMAND_SLEEP 0x05 +#define COMMAND_CLOSE_HID 0xaa +#define COMMAND_START_SEND_CFG 0x80 +#define COMMAND_END_SEND_CFG 0x83 +#define COMMAND_SEND_SMALL_CFG 0x81 +#define COMMAND_SEND_CFG_PREPARE_OK 0x82 +#define COMMAND_START_READ_CFG 0x86 +#define COMMAND_READ_CFG_PREPARE_OK 0x85 + +#define BYTES_PER_COORD 8 +#define TS_MAX_SENSORID 5 +#define TS_CFG_MAX_LEN 1024 +#define TS_CFG_HEAD_LEN 4 +#define TS_CFG_BAG_NUM_INDEX 2 +#define TS_CFG_BAG_START_INDEX 4 +#if TS_CFG_MAX_LEN > GOODIX_CFG_MAX_SIZE +#error GOODIX_CFG_MAX_SIZE too small, please fix. +#endif + +#define TS_DOZE_DISABLE_DATA 0xAA +#define TS_DOZE_CLOSE_OK_DATA 0xBB +#define TS_DOZE_ENABLE_DATA 0xCC +#define TS_CMD_REG_READY 0xFF + +#ifdef CONFIG_OF +int pre_event; + +/** + * goodix_parse_dt_resolution - parse resolution from dt + * @node: devicetree node + * @board_data: pointer to board data structure + * return: 0 - no error, <0 error +*/ +static int goodix_parse_dt_resolution(struct device_node *node, + struct goodix_ts_board_data *board_data) +{ + int r, err; + + r = of_property_read_u32(node, "goodix,panel-max-id", + &board_data->panel_max_id); + if (r) { + err = -ENOENT; + } else { + if (board_data->panel_max_id > GOODIX_MAX_TOUCH) + board_data->panel_max_id = GOODIX_MAX_TOUCH; + } + + r = of_property_read_u32(node, "goodix,panel-max-x", + &board_data->panel_max_x); + if (r) + err = -ENOENT; + + r = of_property_read_u32(node, "goodix,panel-max-y", + &board_data->panel_max_y); + if (r) + err = -ENOENT; + + r = of_property_read_u32(node, "goodix,panel-max-w", + &board_data->panel_max_w); + if (r) + err = -ENOENT; + + r = of_property_read_u32(node, "goodix,panel-max-p", + &board_data->panel_max_p); + if (r) + err = -ENOENT; + + r = of_property_read_u32(node, "goodix,panel-max-fod", + &board_data->panel_max_overlapping_area); + if (r) + err = -ENOENT; + + board_data->swap_axis = of_property_read_bool(node, "goodix,swap-axis"); + + board_data->x2x = of_property_read_bool(node, "goodix,x2x"); + + board_data->y2y = of_property_read_bool(node, "goodix,y2y"); + + return 0; +} + +/** + * goodix_parse_dt - parse board data from dt + * @dev: pointer to device + * @board_data: pointer to board data structure + * return: 0 - no error, <0 error +*/ +static int goodix_parse_dt(struct device_node *node, + struct goodix_ts_board_data *board_data) +{ + struct property *prop; + int r; + + ts_err("enter::%s\n", __func__); + if (!board_data) { + ts_err("Invalid board data"); + return -EINVAL; + } + + r = of_get_named_gpio(node, "goodix,reset-gpio", 0); + if (r < 0) { + ts_err("Invalid reset-gpio in dt: %d", r); + return -EINVAL; + } else { + ts_info("Parse reset-gpio[%d] from dt", r); + board_data->reset_gpio = r; + } + + r = of_get_named_gpio(node, "goodix,vdd-gpio", 0); + if (r < 0) { + ts_err("Invalid vdd-gpio in dt: %d", r); + return -EINVAL; + } else { + ts_info("Parse vdd-gpio[%d] from dt", r); + board_data->vdd_gpio = r; + } + + r = of_get_named_gpio(node, "goodix,avdd-gpio", 0); + if (r < 0) { + ts_err("Invalid avdd-gpio in dt: %d", r); + return -EINVAL; + } else { + ts_info("Parse avdd-gpio[%d] from dt", r); + board_data->avdd_gpio = r; + } + + r = of_get_named_gpio(node, "goodix,irq-gpio", 0); + if (r < 0) { + ts_err("Invalid irq-gpio in dt: %d", r); + return -EINVAL; + } else { + ts_info("Parse irq-gpio[%d] from dt", r); + board_data->irq_gpio = r; + } + + r = of_property_read_u32(node, "goodix,irq-flags", + &board_data->irq_flags); + if (r) { + ts_err("Invalid irq-flags"); + return -EINVAL; + } + + board_data->avdd_name = "vtouch"; + board_data->vddio_name = "iotouch"; + r = of_property_read_u32(node, "vtouch-load", &board_data->avdd_load); + if (r) { + ts_err("can't get vtouch-load"); + board_data->avdd_load = 0; + } + + r = of_property_read_string(node, "goodix,cfg-name", + &board_data->cfg_bin_name); + if (r) { + ts_err("can't get cfg name"); + board_data->cfg_bin_name = NULL; + } + + r = of_property_read_u32(node, "goodix,power-on-delay-us", + &board_data->power_on_delay_us); + if (!r) { + /* 1000ms is too large, maybe you have pass + * a wrong value */ + if (board_data->power_on_delay_us > 1000 * 1000) { + ts_err("Power on delay time exceed 1s, please check"); + board_data->power_on_delay_us = 0; + } + } + + r = of_property_read_u32(node, "goodix,power-off-delay-us", + &board_data->power_off_delay_us); + if (!r) { + /* 1000ms is too large, maybe you have pass + * a wrong value */ + if (board_data->power_off_delay_us > 1000 * 1000) { + ts_err("Power off delay time exceed 1s, please check"); + board_data->power_off_delay_us = 0; + } + } + + /* get xyz resolutions */ + r = goodix_parse_dt_resolution(node, board_data); + if (r < 0) { + ts_err("Failed to parse resolutions:%d", r); + return r; + } + + /* key map */ + prop = of_find_property(node, "goodix,panel-key-map", NULL); + if (prop && prop->length) { + if (prop->length / sizeof(u32) > GOODIX_MAX_KEY) { + ts_err("Size of panel-key-map is invalid"); + return r; + } + + board_data->panel_max_key = prop->length / sizeof(u32); + board_data->tp_key_num = prop->length / sizeof(u32); + r = of_property_read_u32_array(node, "goodix,panel-key-map", + &board_data->panel_key_map[0], + board_data->panel_max_key); + if (r) + return r; + } + + /*get pen-enable switch and pen keys, must after "key map"*/ + board_data->pen_enable = + of_property_read_bool(node, "goodix,pen-enable"); + if (board_data->pen_enable) { + prop = of_find_property(node, "goodix,key-of-pen", NULL); + if (prop && prop->length) { + if (prop->length / sizeof(u32) > GOODIX_PEN_MAX_KEY) { + ts_err("Size of key-of-pen is invalid"); + return r; + } + r = of_property_read_u32_array( + node, "goodix,key-of-pen", + &board_data->panel_key_map + [board_data->panel_max_key], + prop->length / sizeof(u32)); + if (r) + return r; + board_data->panel_max_key += + (prop->length / sizeof(u32)); + } + } + ts_info("***key:%d, %d, %d, %d, %d", board_data->panel_key_map[0], + board_data->panel_key_map[1], board_data->panel_key_map[2], + board_data->panel_key_map[3], board_data->panel_key_map[4]); + /*add end*/ + + ts_debug("[DT]id:%d, x:%d, y:%d, w:%d, p:%d", board_data->panel_max_id, + board_data->panel_max_x, board_data->panel_max_y, + board_data->panel_max_w, board_data->panel_max_p); + return 0; +} + +/** + * goodix_parse_customize_params - parse sensor independent params + * @dev: pointer to device data + * @board_data: board data + * @sensor_id: sensor ID + * return: 0 - read ok, < 0 - i2c transter error +*/ +static int +goodix_parse_customize_params(struct goodix_ts_device *dev, + struct goodix_ts_board_data *board_data, + unsigned int sensor_id) +{ + struct device_node *node = dev->dev->of_node; + char of_node_name[24]; + int r; + + if (sensor_id > TS_MAX_SENSORID || node == NULL) { + ts_err("Invalid sensor id"); + return -EINVAL; + } + + /* parse sensor independent parameters */ + snprintf(of_node_name, sizeof(of_node_name), "sensor%u", sensor_id); + node = of_find_node_by_name(dev->dev->of_node, of_node_name); + if (!node) { + ts_err("Child property[%s] not found", of_node_name); + return -EINVAL; + } + + r = of_property_read_string(node, "goodix,fw-name", + &board_data->fw_name); + if (r) { + ts_err("can't get firmware name"); + board_data->fw_name = NULL; + } + + r = of_property_read_string(node, "goodix,limit-name", + &board_data->limit_name); + if (r) { + ts_err("can't get limit name"); + board_data->limit_name = NULL; + } + + /* sensor independent resolutions */ + r = goodix_parse_dt_resolution(node, board_data); + return r; +} +#endif + +#ifdef CONFIG_ACPI +static int goodix_parse_acpi(struct acpi_device *dev, + struct goodix_ts_board_data *bdata) +{ + return 0; +} + +static int goodix_parse_acpi_cfg(struct acpi_device *dev, char *cfg_type, + struct goodix_ts_config *config, + unsigned int sensor_id) +{ + return 0; +} +#endif + +/** + * goodix_i2c_read_trans - read device register through i2c bus + * @dev: pointer to device data + * @addr: register address + * @data: read buffer + * @len: bytes to read + * return: 0 - read ok, < 0 - i2c transter error +*/ +int goodix_i2c_read_trans(struct goodix_ts_device *dev, unsigned int reg, + unsigned char *data, unsigned int len) +{ + struct i2c_client *client = to_i2c_client(dev->dev); + unsigned int transfer_length = 0; + unsigned int pos = 0, address = reg; + unsigned char get_buf[32], addr_buf[2]; + int retry, r = 0; + struct i2c_msg msgs[] = { { + .addr = client->addr, + .flags = !I2C_M_RD, + .buf = &addr_buf[0], + .len = TS_ADDR_LENGTH, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + } }; + + if (likely(len < sizeof(get_buf))) { + /* code optimize, use stack memory */ + msgs[1].buf = &get_buf[0]; + } else { + msgs[1].buf = kzalloc(I2C_MAX_TRANSFER_SIZE < len ? + I2C_MAX_TRANSFER_SIZE : + len, + GFP_KERNEL); + if (msgs[1].buf == NULL) { + ts_err("Malloc failed"); + return -ENOMEM; + } + } + + while (pos != len) { + if (unlikely(len - pos > I2C_MAX_TRANSFER_SIZE)) + transfer_length = I2C_MAX_TRANSFER_SIZE; + else + transfer_length = len - pos; + + msgs[0].buf[0] = (address >> 8) & 0xFF; + msgs[0].buf[1] = address & 0xFF; + msgs[1].len = transfer_length; + + for (retry = 0; retry < GOODIX_BUS_RETRY_TIMES; retry++) { + if (likely(i2c_transfer(client->adapter, msgs, 2) == + 2)) { + memcpy(&data[pos], msgs[1].buf, + transfer_length); + pos += transfer_length; + address += transfer_length; + break; + } + ts_info("I2c read retry[%d]:0x%x", retry + 1, reg); + msleep(20); + } + if (unlikely(retry == GOODIX_BUS_RETRY_TIMES)) { + ts_err("I2c read failed,dev:%02x,reg:%04x,size:%u", + client->addr, reg, len); + r = -EBUS; + goto read_exit; + } + } + +read_exit: + if (unlikely(len >= sizeof(get_buf))) + kfree(msgs[1].buf); + return r; +} + +/** + * goodix_i2c_write_trans - write device register through i2c bus + * @dev: pointer to device data + * @addr: register address + * @data: write buffer + * @len: bytes to write + * return: 0 - write ok; < 0 - i2c transter error. +*/ +int goodix_i2c_write_trans(struct goodix_ts_device *dev, unsigned int reg, + unsigned char *data, unsigned int len) +{ + struct i2c_client *client = to_i2c_client(dev->dev); + unsigned int pos = 0, transfer_length = 0; + unsigned int address = reg; + unsigned char put_buf[64]; + int retry, r = 0; + struct i2c_msg msg = { + .addr = client->addr, + .flags = !I2C_M_RD, + }; + + if (likely(len + TS_ADDR_LENGTH < sizeof(put_buf))) { + /* code optimize,use stack memory*/ + msg.buf = &put_buf[0]; + } else { + msg.buf = kmalloc(I2C_MAX_TRANSFER_SIZE < len + TS_ADDR_LENGTH ? + I2C_MAX_TRANSFER_SIZE : + len + TS_ADDR_LENGTH, + GFP_KERNEL); + if (msg.buf == NULL) { + ts_err("Malloc failed"); + return -ENOMEM; + } + } + + while (pos != len) { + if (unlikely(len - pos > + I2C_MAX_TRANSFER_SIZE - TS_ADDR_LENGTH)) + transfer_length = + I2C_MAX_TRANSFER_SIZE - TS_ADDR_LENGTH; + else + transfer_length = len - pos; + + msg.buf[0] = (unsigned char)((address >> 8) & 0xFF); + msg.buf[1] = (unsigned char)(address & 0xFF); + msg.len = transfer_length + 2; + memcpy(&msg.buf[2], &data[pos], transfer_length); + + for (retry = 0; retry < GOODIX_BUS_RETRY_TIMES; retry++) { + if (likely(i2c_transfer(client->adapter, &msg, 1) == + 1)) { + pos += transfer_length; + address += transfer_length; + break; + } + ts_info("I2c write retry[%d]", retry + 1); + msleep(20); + } + if (unlikely(retry == GOODIX_BUS_RETRY_TIMES)) { + ts_err("I2c write failed,dev:%02x,reg:%04x,size:%u", + client->addr, reg, len); + r = -EBUS; + goto write_exit; + } + } + +write_exit: + if (likely(len + TS_ADDR_LENGTH >= sizeof(put_buf))) + kfree(msg.buf); + return r; +} + +/** + * goodix_set_i2c_doze_mode - disable or enable doze mode + * @dev: pointer to device data + * @enable: true/flase + * return: 0 - ok; < 0 - error. + * This func must be used in pairs, when you disable doze + * mode, then you must enable it again. + * Between set_doze_false and set_doze_true, do not reset + * IC! +*/ +int goodix_set_i2c_doze_mode(struct goodix_ts_device *dev, int enable) +{ + int result = -EINVAL; + int i; + u8 w_data, r_data; + + if (dev->ic_type != IC_TYPE_NORMANDY) + return 0; + mutex_lock(&dev->doze_mode_lock); + if (enable) { + if (dev->doze_mode_set_count != 0) + dev->doze_mode_set_count--; + /*when count equal 0, allow ic enter doze mode*/ + if (dev->doze_mode_set_count == 0) { + w_data = TS_DOZE_ENABLE_DATA; + for (i = 0; i < TS_DOZE_ENABLE_RETRY_TIMES; i++) { + result = goodix_i2c_write_trans( + dev, TS_REG_DOZE_CTRL, &w_data, 1); + if (!result) { + result = 0; + goto exit; + } + usleep_range(1000, 1100); + } + if (i >= TS_DOZE_ENABLE_RETRY_TIMES) + ts_err("i2c doze mode enable failed, i2c write fail"); + } else { + /*ts_info("doze count not euqal 0, so skip doze mode enable");*/ + result = 0; + goto exit; + } + } else { + dev->doze_mode_set_count++; + if (dev->doze_mode_set_count == 1) { + w_data = TS_DOZE_DISABLE_DATA; + goodix_i2c_write_trans(dev, TS_REG_DOZE_CTRL, &w_data, + 1); + usleep_range(1000, 1100); + for (i = 0; i < TS_DOZE_DISABLE_RETRY_TIMES; i++) { + goodix_i2c_read_trans(dev, TS_REG_DOZE_STAT, + &r_data, 1); + if (TS_DOZE_CLOSE_OK_DATA == r_data) { + result = 0; + goto exit; + } else if (0xAA != r_data) { + w_data = TS_DOZE_DISABLE_DATA; + goodix_i2c_write_trans(dev, + TS_REG_DOZE_CTRL, + &w_data, 1); + } + usleep_range(10000, 10100); + } + ts_err("doze mode disable FAILED"); + } else { + result = 0; + goto exit; + } + } + +exit: + mutex_unlock(&dev->doze_mode_lock); + return result; +} + +/** + * goodix_i2c_write - write device register through i2c bus + * @dev: pointer to device data + * @addr: register address + * @data: write buffer + * @len: bytes to write + * return: 0 - write ok; < 0 - i2c transter error. +*/ +int goodix_i2c_write(struct goodix_ts_device *dev, unsigned int reg, + unsigned char *data, unsigned int len) +{ + int r; + + if (dev->ic_type == IC_TYPE_NORMANDY) { + if (goodix_set_i2c_doze_mode(dev, false) != 0) + ts_err("gtx8 i2c write:0x%04x ERROR, disable doze mode FAILED", + reg); + } + + r = goodix_i2c_write_trans(dev, reg, data, len); + + if (dev->ic_type == IC_TYPE_NORMANDY) { + if (goodix_set_i2c_doze_mode(dev, true) != 0) + ts_err("gtx8 i2c write:0x%04x ERROR, enable doze mode FAILED", + reg); + } + return r; +} + +/** + * goodix_i2c_read - read device register through i2c bus + * @dev: pointer to device data + * @addr: register address + * @data: read buffer + * @len: bytes to read + * return: 0 - read ok, < 0 - i2c transter error +*/ +int goodix_i2c_read(struct goodix_ts_device *dev, unsigned int reg, + unsigned char *data, unsigned int len) +{ + int r; + + if (dev->ic_type == IC_TYPE_NORMANDY) { + if (goodix_set_i2c_doze_mode(dev, false) != 0) + ts_err("gtx8 i2c read:0x%04x ERROR, disable doze mode FAILED", + reg); + } + r = goodix_i2c_read_trans(dev, reg, data, len); + if (dev->ic_type == IC_TYPE_NORMANDY) { + if (goodix_set_i2c_doze_mode(dev, true) != 0) + ts_err("gtx8 i2c read:0x%04x ERROR, enable doze mode FAILED", + reg); + } + return r; +} + +/** + * goodix_i2c_write_trans_once - + * write device register through i2c bus, no retry + * @dev: pointer to device data + * @addr: register address + * @data: write buffer + * @len: bytes to write + * return: 0 - write ok; < 0 - i2c transter error. +*/ +int goodix_i2c_write_trans_once(struct goodix_ts_device *dev, unsigned int reg, + unsigned char *data, unsigned int len) +{ + struct i2c_client *client = to_i2c_client(dev->dev); + unsigned int pos = 0, transfer_length = 0; + unsigned int address = reg; + unsigned char put_buf[64]; + struct i2c_msg msg = { + .addr = client->addr, + .flags = !I2C_M_RD, + }; + + if (likely(len + TS_ADDR_LENGTH < sizeof(put_buf))) { + /* code optimize,use stack memory*/ + msg.buf = &put_buf[0]; + } else { + msg.buf = kmalloc(I2C_MAX_TRANSFER_SIZE < len + TS_ADDR_LENGTH ? + I2C_MAX_TRANSFER_SIZE : + len + TS_ADDR_LENGTH, + GFP_KERNEL); + if (msg.buf == NULL) { + ts_err("Malloc failed"); + return -ENOMEM; + } + } + + while (pos != len) { + if (unlikely(len - pos > + I2C_MAX_TRANSFER_SIZE - TS_ADDR_LENGTH)) + transfer_length = + I2C_MAX_TRANSFER_SIZE - TS_ADDR_LENGTH; + else + transfer_length = len - pos; + + msg.buf[0] = (unsigned char)((address >> 8) & 0xFF); + msg.buf[1] = (unsigned char)(address & 0xFF); + msg.len = transfer_length + 2; + memcpy(&msg.buf[2], &data[pos], transfer_length); + + i2c_transfer(client->adapter, &msg, 1); + pos += transfer_length; + address += transfer_length; + } + + if (likely(len + TS_ADDR_LENGTH >= sizeof(put_buf))) + kfree(msg.buf); + return 0; +} + +static void goodix_cmds_init(struct goodix_ts_cmd *ts_cmd, u8 cmds, u8 cmd_data, + u32 reg_addr) +{ + if (reg_addr) { + ts_cmd->cmd_reg = reg_addr; + ts_cmd->length = 3; + ts_cmd->cmds[0] = cmds; + ts_cmd->cmds[1] = cmd_data; + ts_cmd->cmds[2] = 0 - cmds - cmd_data; + ts_cmd->initialized = true; + } else { + ts_cmd->initialized = false; + } +} + +/** + * goodix_send_command - seng cmd to firmware + * + * @dev: pointer to device + * @cmd: pointer to command struct which cotain command data + * Returns 0 - succeed,<0 - failed + */ +int goodix_send_command(struct goodix_ts_device *dev, struct goodix_ts_cmd *cmd) +{ + int ret; + + if (!cmd || !cmd->initialized) + return -EINVAL; + + ret = goodix_i2c_write(dev, cmd->cmd_reg, cmd->cmds, cmd->length); + + return ret; +} + +static int goodix_read_version(struct goodix_ts_device *dev, + struct goodix_ts_version *version) +{ + u8 buffer[12]; + u8 temp_buf[256], checksum; + int r; + u8 pid_read_len = dev->reg.pid_len; + u8 vid_read_len = dev->reg.vid_len; + u8 sensor_id_mask = dev->reg.sensor_id_mask; +#define IS_CHAR(c) \ + (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z') || \ + ((c) >= '0' && (c) <= '9')) + + if (!version) { + ts_err("pointer of version is NULL"); + return -EINVAL; + } + version->valid = false; + + /*check reg info valid*/ + if (!dev->reg.pid || !dev->reg.sensor_id || !dev->reg.vid) { + ts_err("reg is NULL, pid:0x%04x, vid:0x%04x, sensor_id:0x%04x", + dev->reg.pid, dev->reg.vid, dev->reg.sensor_id); + return -EINVAL; + } + if (!pid_read_len || pid_read_len > GOODIX_PID_MAX_LEN || + !vid_read_len || vid_read_len > GOODIX_VID_MAX_LEN) { + ts_err("pid vid read len ERROR, pid_read_len:%d, vid_read_len:%d", + pid_read_len, vid_read_len); + return -EINVAL; + } + + /*disable doze mode, just valid for normandy + * this func must be used in pairs*/ + goodix_set_i2c_doze_mode(dev, false); + + /*check checksum*/ + if (dev->reg.version_base && dev->reg.version_len < 256) { + r = goodix_i2c_read(dev, dev->reg.version_base, temp_buf, + dev->reg.version_len); + + if (r < 0) { + ts_err("Read version base failed, reg:0x%02x, len:%d", + dev->reg.version_base, dev->reg.version_len); + if (version) + version->valid = false; + goto exit; + } + + checksum = checksum_u8(temp_buf, dev->reg.version_len); + if (checksum) { + ts_err("checksum error:0x%02x, base:0x%02x, len:%d", + checksum, dev->reg.version_base, + dev->reg.version_len); + ts_err("%*ph", (int)(dev->reg.version_len / 2), + temp_buf); + ts_err("%*ph", + (int)(dev->reg.version_len - + dev->reg.version_len / 2), + &temp_buf[dev->reg.version_len / 2]); + + if (version) + version->valid = false; + r = -EINVAL; + goto exit; + } + } + + /*read pid*/ + memset(buffer, 0, sizeof(buffer)); + memset(version->pid, 0, sizeof(version->pid)); + r = goodix_i2c_read(dev, dev->reg.pid, buffer, pid_read_len); + if (r < 0) { + ts_err("Read pid failed"); + if (version) + version->valid = false; + goto exit; + } + memcpy(version->pid, buffer, pid_read_len); + + /*read vid*/ + memset(buffer, 0, sizeof(buffer)); + memset(version->vid, 0, sizeof(version->vid)); + r = goodix_i2c_read(dev, dev->reg.vid, buffer, vid_read_len); + if (r < 0) { + ts_err("Read vid failed"); + if (version) + version->valid = false; + goto exit; + } + memcpy(version->vid, buffer, vid_read_len); + ts_info("PID:%s, VID:0x%02x 0x%02x 0x%02x 0x%02x", version->pid, + version->vid[0], version->vid[1], version->vid[2], + version->vid[3]); + /*read sensor_id*/ + memset(buffer, 0, sizeof(buffer)); + r = goodix_i2c_read(dev, dev->reg.sensor_id, buffer, 1); + if (r < 0) { + ts_err("Read sensor_id failed"); + if (version) + version->valid = false; + goto exit; + } + if (sensor_id_mask != 0) { + version->sensor_id = buffer[0] & sensor_id_mask; + ts_info("sensor_id_mask:0x%02x, sensor_id:0x%02x", + sensor_id_mask, version->sensor_id); + } else { + version->sensor_id = buffer[0]; + } + + version->valid = true; + + r = goodix_i2c_read(dev, dev->reg.vid, buffer, vid_read_len); + memcpy(version->vid, buffer, vid_read_len); + ts_info("PID:%s,SensorID:%d, VID:%*ph", version->pid, + version->sensor_id, (int)sizeof(version->vid), version->vid); + +exit: + /*enable doze mode, just valid for normandy + * this func must be used in pairs*/ + goodix_set_i2c_doze_mode(dev, true); + + return r; +} + +static int goodix_wait_cfg_cmd_ready(struct goodix_ts_device *dev, u8 right_cmd, + u8 send_cmd) +{ + int try_times = 0; + u8 cmd_flag = 0; + u8 cmd_buf[3] = { 0 }; + u16 command_reg = dev->reg.command; + struct goodix_ts_cmd ts_cmd; + + goodix_cmds_init(&ts_cmd, send_cmd, 0, command_reg); + + for (try_times = 0; try_times < TS_WAIT_CFG_READY_RETRY_TIMES; + try_times++) { + if (goodix_i2c_read(dev, command_reg, cmd_buf, 3)) { + ts_err("Read cmd_reg error"); + return -EINVAL; + } + cmd_flag = cmd_buf[0]; + if (cmd_flag == right_cmd) { + return 0; + } else if (cmd_flag != send_cmd) { + ts_err("Read cmd_reg data abnormal,return:0x%02X, 0x%02X, 0x%02X, send again", + cmd_buf[0], cmd_buf[1], cmd_buf[2]); + if (goodix_send_command(dev, &ts_cmd)) { + ts_err("Resend cmd 0x%02X FAILED", send_cmd); + return -EINVAL; + } + } + usleep_range(10000, 11000); + } + + return -EINVAL; +} + +static int goodix_send_small_config(struct goodix_ts_device *dev, + struct goodix_ts_config *config) +{ + int r = 0; + int try_times = 0; + u8 buf = 0; + u16 command_reg = dev->reg.command; + u16 cfg_reg = dev->reg.cfg_addr; + struct goodix_ts_cmd ts_cmd; + + /*1. Inquire command_reg until it's free*/ + for (try_times = 0; try_times < TS_WAIT_CMD_FREE_RETRY_TIMES; + try_times++) { + if (!goodix_i2c_read(dev, command_reg, &buf, 1) && + buf == TS_CMD_REG_READY) + break; + usleep_range(10000, 11000); + } + if (try_times >= TS_WAIT_CMD_FREE_RETRY_TIMES) { + ts_err("Send small cfg FAILED, before send, reg:0x%04x is not 0xff", + command_reg); + r = -EINVAL; + goto exit; + } + + /*2. write cfg data*/ + if (goodix_i2c_write(dev, cfg_reg, config->data, config->length)) { + ts_err("Send small cfg FAILED, write cfg to fw ERROR"); + r = -EINVAL; + goto exit; + } + + /*3. send 0x81 command*/ + goodix_cmds_init(&ts_cmd, COMMAND_SEND_SMALL_CFG, 0, dev->reg.command); + if (goodix_send_command(dev, &ts_cmd)) { + ts_err("Send large cfg FAILED, send COMMAND_SEND_SMALL_CFG ERROR"); + r = -EINVAL; + goto exit; + } + + r = 0; + ts_info("send small cfg SUCCESS"); + +exit: + return r; +} + +static int goodix_send_large_config(struct goodix_ts_device *dev, + struct goodix_ts_config *config) +{ + int r = 0; + int try_times = 0; + u8 buf = 0; + u16 command_reg = dev->reg.command; + u16 cfg_reg = dev->reg.cfg_addr; + struct goodix_ts_cmd ts_cmd; + + /*1. Inquire command_reg until it's free*/ + for (try_times = 0; try_times < TS_WAIT_CMD_FREE_RETRY_TIMES; + try_times++) { + if (!goodix_i2c_read(dev, command_reg, &buf, 1) && + buf == TS_CMD_REG_READY) + break; + usleep_range(10000, 11000); + } + if (try_times >= TS_WAIT_CMD_FREE_RETRY_TIMES) { + ts_err("Send large cfg FAILED, before send, reg:0x%04x is not 0xff", + command_reg); + r = -EINVAL; + goto exit; + } + + /*2. send "start write cfg" command*/ + goodix_cmds_init(&ts_cmd, COMMAND_START_SEND_CFG, 0, dev->reg.command); + if (goodix_send_command(dev, &ts_cmd)) { + ts_err("Send large cfg FAILED, send COMMAND_START_SEND_CFG ERROR"); + r = -EINVAL; + goto exit; + } + + /*3. wait ic set command_reg to 0x82*/ + if (goodix_wait_cfg_cmd_ready(dev, COMMAND_SEND_CFG_PREPARE_OK, + COMMAND_START_SEND_CFG)) { + ts_err("Send large cfg FAILED, reg:0x%04x is not 0x82", + command_reg); + r = -EINVAL; + goto exit; + } + + /*4. write cfg*/ + if (goodix_i2c_write(dev, cfg_reg, config->data, config->length)) { + ts_err("Send large cfg FAILED, write cfg to fw ERROR"); + r = -EINVAL; + goto exit; + } + + /*5. send "end send cfg" command*/ + goodix_cmds_init(&ts_cmd, COMMAND_END_SEND_CFG, 0, dev->reg.command); + if (goodix_send_command(dev, &ts_cmd)) { + ts_err("Send large cfg FAILED, send COMMAND_END_SEND_CFG ERROR"); + r = -EINVAL; + goto exit; + } + + /*6. wait ic set command_reg to 0xff*/ + for (try_times = 0; try_times < TS_WAIT_CMD_FREE_RETRY_TIMES; + try_times++) { + if (!goodix_i2c_read(dev, command_reg, &buf, 1) && + buf == TS_CMD_REG_READY) + break; + usleep_range(10000, 11000); + } + if (try_times >= TS_WAIT_CMD_FREE_RETRY_TIMES) { + ts_err("Send large cfg FAILED, after send, reg:0x%04x is not 0xff", + command_reg); + r = -EINVAL; + goto exit; + } + + ts_info("Send large cfg SUCCESS"); + r = 0; + +exit: + return r; +} + +static int goodix_check_cfg_valid(struct goodix_ts_device *dev, u8 *cfg, + u32 length) +{ + int ret; + u8 bag_num; + u8 checksum; + int i, j; + int bag_start = 0; + int bag_end = 0; + if (!cfg || length < TS_CFG_HEAD_LEN) { + ts_err("cfg is INVALID, len:%d", length); + ret = -EINVAL; + goto exit; + } + + if (dev->ic_type == IC_TYPE_NANJING) { + /*check configuration head checksum*/ + checksum = 0; + for (i = 0; i < 3; i++) + checksum += cfg[i]; + + if (checksum != 0) { + ts_err("cfg head checksum ERROR, ic type:nanjing, checksum:0x%02x", + checksum); + ret = -EINVAL; + goto exit; + } + bag_num = cfg[1]; + bag_start = 3; + } else if (dev->ic_type == IC_TYPE_NORMANDY) { + checksum = 0; + for (i = 0; i < TS_CFG_HEAD_LEN; i++) + checksum += cfg[i]; + if (checksum != 0) { + ts_err("cfg head checksum ERROR, ic type:normandy, checksum:0x%02x", + checksum); + ret = -EINVAL; + goto exit; + } + bag_num = cfg[TS_CFG_BAG_NUM_INDEX]; + bag_start = TS_CFG_BAG_START_INDEX; + } else { + ts_err("cfg check FAILED, unkonw ic_type"); + ret = -EINVAL; + goto exit; + } + + ts_info("cfg bag_num:%d, cfg length:%d", bag_num, length); + + /*check each bag's checksum*/ + for (j = 0; j < bag_num; j++) { + if (bag_start >= length - 1) { + ts_err("ERROR, overflow!!bag_start:%d, cfg_len:%d", + bag_start, length); + ret = -EINVAL; + goto exit; + } + + bag_end = bag_start + cfg[bag_start + 1] + 3; + if ((j == 0) && (dev->ic_type == IC_TYPE_NANJING)) + /*the first bag of nanjing cfg is different!*/ + bag_end = 336; + + checksum = 0; + if (bag_end > length) { + ts_err("ERROR, overflow!!bag:%d, bag_start:%d, bag_end:%d, cfg length:%d", + j, bag_start, bag_end, length); + ret = -EINVAL; + goto exit; + } + for (i = bag_start; i < bag_end; i++) + checksum += cfg[i]; + if (checksum != 0) { + ts_err("cfg INVALID, bag:%d checksum ERROR:0x%02x", j, + checksum); + ret = -EINVAL; + goto exit; + } + bag_start = bag_end; + } + + ret = 0; + ts_info("configuration check SUCCESS"); + +exit: + return ret; +} + +static int goodix_send_config(struct goodix_ts_device *dev, + struct goodix_ts_config *config) +{ + int r = 0; + + /*check reg valid*/ + /* if (!dev->reg.cfg_addr) { + ts_err("cfg register is NULL"); + return -EINVAL; + }*/ + if (!config || !*(config->data)) { + ts_err("Null config data"); + return -EINVAL; + } + + /*check configuration valid*/ + r = goodix_check_cfg_valid(dev, config->data, config->length); + if (r != 0) { + ts_err("cfg check FAILED"); + return -EINVAL; + } + + ts_info("ver:%02xh,size:%d", config->data[0], config->length); + + mutex_lock(&config->lock); + + if (dev->ic_type == IC_TYPE_NANJING) + r = goodix_send_large_config(dev, config); + else if (dev->ic_type == IC_TYPE_NORMANDY) { + /*disable doze mode*/ + goodix_set_i2c_doze_mode(dev, false); + + if (config->length > 32) + r = goodix_send_large_config(dev, config); + else + r = goodix_send_small_config(dev, config); + + /*enable doze mode*/ + goodix_set_i2c_doze_mode(dev, true); + } + + if (r != 0) + ts_err("send_cfg FAILED, ic_type:%d, cfg_len:%d", dev->ic_type, + config->length); + + mutex_unlock(&config->lock); + return r; +} + +#if 0 +/** + * goodix_send_config - send config data to device. + * @dev: pointer to device + * @config: pointer to config data struct to be send + * @return: 0 - succeed, < 0 - failed + */ +static int goodix_send_config(struct goodix_ts_device *dev, + struct goodix_ts_config *config) +{ + int r = 0; + + if (!config || !config->data) { + ts_err("Null config data"); + return -EINVAL; + } + + ts_info("Send %s,ver:%02xh,size:%d", + config->name, config->data[0], + config->length); + + mutex_lock(&config->lock); + r = goodix_i2c_write(dev, config->reg_base, + config->data, config->length); + if (r) + goto exit; + + /* make sure the firmware accept the config data*/ + if (config->delay) + msleep(config->delay); +exit: + mutex_unlock(&config->lock); + return r; +} +#endif + +/** + * goodix_close_hidi2c_mode + * Called by touch core module when bootup + * @ts_dev: pointer to touch device + * return: 0 - no error, <0 error +*/ +static int goodix_close_hidi2c_mode(struct goodix_ts_device *ts_dev) +{ + int r = 0; + int try_times; + int j; + unsigned char buffer[1]; + unsigned char reg_sta; + struct goodix_ts_cmd ts_cmd; + + for (try_times = 0; try_times < 10; try_times++) { + if (goodix_i2c_read(ts_dev, 0x8040, ®_sta, 1) != 0) + continue; + else if (reg_sta == 0xff) + break; + usleep_range(10000, 11000); + } + if (try_times >= 10) { + ts_info("goodix_close_hidi2c_mode FAILED, 0x8040 is not equal to 0xff"); + return -EINVAL; + } + + goodix_cmds_init(&ts_cmd, COMMAND_CLOSE_HID, 0, 0x8040); + for (try_times = 0; try_times < 3; try_times++) { + if (ts_cmd.initialized) { + r = goodix_send_command(ts_dev, &ts_cmd); + if (r) + continue; + + usleep_range(100000, 110000); + + /*read 0x8040, if it's not 0xFF,continue*/ + for (j = 0; j < 3; j++) { + if (goodix_i2c_read(ts_dev, 0x8040, buffer, + 1) != 0) + continue; + else { + if (buffer[0] != 0xFF) { + ts_info("try_times:%d:%d, read 0x8040:0x%02x", + try_times, j, + buffer[0]); + usleep_range(10000, 11000); + continue; + } else + goto exit; + } + } + } + } + +exit: + if (try_times >= 3) { + ts_info("close hid_i2c mode FAILED"); + r = -EINVAL; + } else { + ts_info("close hid_i2c mode SUCCESS"); + r = 0; + } + return r; +} + +/* success return config length else return -1 */ +static int _goodix_do_read_config(struct goodix_ts_device *dev, u32 base_addr, + u8 *buf) +{ + int sub_bags = 0; + int offset = 0; + int subbag_len; + u8 checksum; + int i; + int ret; + + /*disable doze mode*/ + if (dev->ic_type == IC_TYPE_NORMANDY) + goodix_set_i2c_doze_mode(dev, false); + + ret = goodix_i2c_read(dev, base_addr, buf, TS_CFG_HEAD_LEN); + if (ret) + goto err_out; + + if (dev->ic_type == IC_TYPE_NANJING) { + offset = 3; + sub_bags = buf[1]; + checksum = checksum_u8(buf, 3); + } else { + offset = TS_CFG_BAG_START_INDEX; + sub_bags = buf[TS_CFG_BAG_NUM_INDEX]; + checksum = checksum_u8(buf, TS_CFG_HEAD_LEN); + } + if (checksum) { + ts_err("Config head checksum err:0x%x,data:%*ph", checksum, + TS_CFG_HEAD_LEN, buf); + ret = -EINVAL; + goto err_out; + } + + ts_info("config_version:%u, vub_bags:%u", buf[0], sub_bags); + for (i = 0; i < sub_bags; i++) { + /* read sub head [0]: sub bag num, [1]: sub bag length */ + ret = goodix_i2c_read(dev, base_addr + offset, buf + offset, 2); + if (ret) + goto err_out; + + /* read sub bag data */ + if (dev->ic_type == IC_TYPE_NANJING && i == 0) + subbag_len = buf[offset + 1] + 256; + else + subbag_len = buf[offset + 1]; + + ts_info("sub bag num:%u,sub bag length:%u", buf[offset], + subbag_len); + ret = goodix_i2c_read(dev, base_addr + offset + 2, + buf + offset + 2, subbag_len + 1); + if (ret) + goto err_out; + checksum = checksum_u8(buf + offset, subbag_len + 3); + if (checksum) { + ts_err("sub bag checksum err:0x%x", checksum); + ret = -EINVAL; + goto err_out; + } + offset += subbag_len + 3; + ts_debug("sub bag %d, data:%*ph", buf[offset], + buf[offset + 1] + 3, buf + offset); + } + ret = offset; + +err_out: + /*enable doze mode*/ + if (dev->ic_type == IC_TYPE_NORMANDY) + goodix_set_i2c_doze_mode(dev, true); + + return ret; +} + +/* success return config_len, <= 0 failed */ +static int goodix_read_config(struct goodix_ts_device *dev, u8 *config_data, + u32 config_len) +{ + struct goodix_ts_cmd ts_cmd; + u8 cmd_flag; + u32 cmd_reg = dev->reg.command; + int r = 0; + int i; + + if (!config_data || config_len > TS_CFG_MAX_LEN) { + ts_err("Illegal params"); + return -EINVAL; + } + if (!dev->reg.command) { + ts_err("command register ERROR:0x%04x", dev->reg.command); + return -EINVAL; + } + + /*disable doze mode*/ + if (dev->ic_type == IC_TYPE_NORMANDY) + goodix_set_i2c_doze_mode(dev, false); + + /* wait for IC in IDLE state */ + for (i = 0; i < TS_WAIT_CMD_FREE_RETRY_TIMES; i++) { + cmd_flag = 0; + r = goodix_i2c_read(dev, cmd_reg, &cmd_flag, 1); + if (r < 0 || cmd_flag == TS_CMD_REG_READY) + break; + usleep_range(10000, 11000); + } + if (cmd_flag != TS_CMD_REG_READY) { + ts_err("Wait for IC ready IDEL state timeout:addr 0x%x\n", + cmd_reg); + r = -EAGAIN; + goto exit; + } + /* 0x86 read config command */ + goodix_cmds_init(&ts_cmd, COMMAND_START_READ_CFG, 0, cmd_reg); + r = goodix_send_command(dev, &ts_cmd); + if (r) { + ts_err("Failed send read config command"); + goto exit; + } + /* wait for config data ready */ + if (goodix_wait_cfg_cmd_ready(dev, COMMAND_READ_CFG_PREPARE_OK, + COMMAND_START_READ_CFG)) { + ts_err("Wait for config data ready timeout"); + r = -EAGAIN; + goto exit; + } + if (config_len) { + r = goodix_i2c_read(dev, cmd_reg + 16, config_data, config_len); + if (r) + ts_err("Failed read config data"); + else + r = config_len; + } else { + r = _goodix_do_read_config(dev, cmd_reg + 16, config_data); + if (r < 0) + ts_err("Failed read config data"); + } + if (r > 0) + ts_info("success read config, len:%d", r); + /* clear command */ + goodix_cmds_init(&ts_cmd, TS_CMD_REG_READY, 0, cmd_reg); + goodix_send_command(dev, &ts_cmd); + + /*enable doze mode*/ + if (dev->ic_type == IC_TYPE_NORMANDY) + goodix_set_i2c_doze_mode(dev, true); + +exit: + return r; +} + +/** + * goodix_hw_init - hardware initialize + * Called by touch core module when bootup + * @ts_dev: pointer to touch device + * return: 0 - no error, <0 error +*/ +static int goodix_hw_init(struct goodix_ts_device *ts_dev) +{ + int r; + + BUG_ON(!ts_dev); + ts_info("goodix_hw_init"); + /* goodix_hw_init may be called many times */ + if (!ts_dev->normal_cfg) { + ts_dev->normal_cfg = devm_kzalloc( + ts_dev->dev, sizeof(*ts_dev->normal_cfg), GFP_KERNEL); + if (!ts_dev->normal_cfg) { + ts_err("Failed to alloc memory for normal cfg"); + return -ENOMEM; + } + mutex_init(&ts_dev->normal_cfg->lock); + } + if (!ts_dev->highsense_cfg) { + ts_dev->highsense_cfg = devm_kzalloc( + ts_dev->dev, sizeof(*ts_dev->highsense_cfg), + GFP_KERNEL); + if (!ts_dev->highsense_cfg) { + ts_err("Failed to alloc memory for high sense cfg"); + return -ENOMEM; + } + mutex_init(&ts_dev->highsense_cfg->lock); + } + + /*for Nanjing IC, close HID_I2C mode when driver is probed*/ + if (ts_dev->ic_type == IC_TYPE_NANJING) { + r = goodix_close_hidi2c_mode(ts_dev); + if (r < 0) + ts_info("close hid i2c mode FAILED"); + } + + /* read chip version: PID/VID/sensor ID,etc.*/ + r = goodix_read_version(ts_dev, &ts_dev->chip_version); + if (r < 0) + return r; + + /* devicetree property like resolution(panel_max_xxx) + * may be different between sensors, here we try to parse + * parameters form sensor child node */ + r = goodix_parse_customize_params(ts_dev, ts_dev->board_data, + ts_dev->chip_version.sensor_id); + if (r < 0) + ts_info("Cann't find customized parameters"); + + ts_dev->normal_cfg->delay = 500; + /* send normal-cfg to firmware */ + r = goodix_send_config(ts_dev, ts_dev->normal_cfg); + + return r; +} + +/** + * goodix_hw_reset - reset device + * + * @dev: pointer to touch device + * Returns 0 - succeed,<0 - failed + */ +int goodix_hw_reset(struct goodix_ts_device *dev) +{ + u8 data[2] = { 0x00 }; + int r = 0; + + ts_info("HW reset"); + ts_info("ic_type = %d\n", dev->ic_type); + dev->ic_type = IC_TYPE_NORMANDY; + if (dev->ic_type == IC_TYPE_NORMANDY) { + ts_info("touchpanel normandy reset"); + //gpio_direction_output(dev->board_data->reset_gpio, 1); + //msleep(10); + gpio_direction_output(dev->board_data->reset_gpio, 0); + udelay(2000); + gpio_direction_output(dev->board_data->reset_gpio, 1); + msleep(100); + } else if (dev->ic_type == IC_TYPE_NANJING) { + ts_info("nanjing reset"); + + /*close watch dog*/ + data[0] = 0; + goodix_i2c_write(dev, 0x40b0, data, 1); + msleep(10); + + /*soft reset*/ + data[0] = 1; + goodix_i2c_write_trans_once(dev, 0x4180, data, 1); + msleep(250); + goodix_close_hidi2c_mode(dev); + + /*clear coor_reg*/ + data[0] = 0; + data[1] = 0; + goodix_i2c_write(dev, 0x824d, data, 2); + } + + /*init static esd*/ + data[0] = GOODIX_ESD_TICK_WRITE_DATA; + if (dev->ic_type == IC_TYPE_NANJING) { + r = goodix_i2c_write(dev, 0x8043, data, 1); + if (r < 0) + ts_err("nanjing reset, init static esd FAILED, i2c wirte ERROR"); + } + + /*init dynamic esd*/ + if (dev->reg.esd) { + r = goodix_i2c_write_trans(dev, dev->reg.esd, data, 1); + if (r < 0) + ts_err("IC reset, init dynamic esd FAILED, i2c write ERROR"); + } else + ts_info("reg.esd is NULL, skip dynamic esd init"); + + return 0; +} + +/** + * goodix_request_handler - handle firmware request + * + * @dev: pointer to touch device + * @request_data: requset information + * Returns 0 - succeed,<0 - failed + */ +static int goodix_request_handler(struct goodix_ts_device *dev, + struct goodix_request_data *request_data) +{ + unsigned char buffer[1]; + int r; + + if (dev->reg.fw_request != 0x6F6D) { + ts_info("firmware reg is wrong!\n"); + dev->reg.fw_request = 0x6F6D; + } + r = goodix_i2c_read_trans(dev, dev->reg.fw_request, buffer, + 1); /*TS_REG_REQUEST*/ + if (r < 0) + return r; + + switch (buffer[0]) { + case REQUEST_CONFIG: + ts_info("HW request config"); + goodix_send_config(dev, dev->normal_cfg); + goto clear_requ; + break; + case REQUEST_BAKREF: + ts_info("HW request bakref"); + goto clear_requ; + break; + case REQUEST_RESET: + ts_info("HW requset reset"); + goto clear_requ; + break; + case REQUEST_MAINCLK: + ts_info("HW request mainclk"); + goto clear_requ; + break; + default: + ts_info("Unknown hw request:%d", buffer[0]); + return 0; + } + +clear_requ: + buffer[0] = 0x00; + r = goodix_i2c_write_trans(dev, dev->reg.fw_request, buffer, + 1); /*TS_REG_REQUEST*/ + return r; +} + +/*goodix_swap_coords - swap coord + */ + +static void goodix_swap_coords(struct goodix_ts_device *dev, + struct goodix_ts_coords *coords, int touch_num) +{ + int i, temp; + struct goodix_ts_board_data *bdata = dev->board_data; + for (i = 0; i < touch_num; i++) { + if (bdata->swap_axis) { + temp = coords->x; + coords->x = coords->y; + coords->y = temp; + } + if (bdata->x2x) + coords->x = bdata->panel_max_x - coords->x; + if (bdata->y2y) + coords->y = bdata->panel_max_y - coords->y; + coords++; + } +} + +static int goodix_remap_trace_id(struct goodix_ts_device *dev, u8 *coor_buf, + u32 coor_buf_len, int touch_num) +{ + static u8 remap_array[20] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + int i, j; + int offset = 0; + bool need_leave = false; + bool need_add = false; + u8 temp_buf[BYTES_PER_COORD] = { 0x00 }; + u8 *small; + bool need_swap = false; + int max_touch_num = dev->board_data->panel_max_id; + + if (touch_num > dev->board_data->panel_max_id) { + ts_err("touch num error, trace id no remap:%d", touch_num); + return 0; + } + + if (!coor_buf || coor_buf_len > (2 + BYTES_PER_COORD * max_touch_num)) { + ts_err("touch data buff error, !coor_buf:%d, len:%d", !coor_buf, + coor_buf_len); + return 0; + } + + /*clear and reset remap_array*/ + if (touch_num == 0) { + for (i = 0; i < sizeof(remap_array); i++) + remap_array[i] = 0xff; + return 0; + } + + /*find and add new point*/ + offset = 0; + for (i = 0; i < touch_num; i++) { + need_add = true; + for (j = 0; j < sizeof(remap_array); j++) { + if (coor_buf[offset] == remap_array[j]) { + need_add = false; + break; + } + } + if (need_add == true) { + for (j = 0; j < sizeof(remap_array); j++) { + if (remap_array[j] == 0xff) { + remap_array[j] = coor_buf[offset]; + break; + } + } + } + offset += BYTES_PER_COORD; + } + + /*scan remap_array, find and remove leave point*/ + for (i = 0; i < sizeof(remap_array); i++) { + if (remap_array[i] == 0xff) + continue; + else { + need_leave = true; + offset = 0; + for (j = 0; j < touch_num; j++) { + if (remap_array[i] == coor_buf[offset]) { + need_leave = false; + break; + } + offset += BYTES_PER_COORD; + } + if (need_leave == true) { + /*ts_info("---leave, trace id:%d:%d", remap_array[i], i);*/ + remap_array[i] = 0xff; + } + } + } + + /*remap trace id*/ + offset = 0; + for (i = 0; i < touch_num; i++) { + /*do not remap pen's trace ID*/ + if (coor_buf[offset] >= 0x80) { + offset += BYTES_PER_COORD; + continue; + } else { + for (j = 0; j < sizeof(remap_array); j++) { + if (remap_array[j] == coor_buf[offset]) { + /*ts_info("***remap, %d--->%d", coor_buf[offset], j);*/ + coor_buf[offset] = j; + break; + } + } + if (j >= sizeof(remap_array)) { + ts_err("remap ERROR!!trace id:%d", + coor_buf[offset]); + ts_err("remap_array:%*ph", + (int)sizeof(remap_array), remap_array); + } + offset += BYTES_PER_COORD; + } + } + + /*for (i = 0; i < touch_num; i++) { + ts_info("remap data%d:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x", + i, coor_buf[i * 8], coor_buf[i * 8 + 1], + coor_buf[i * 8 + 2], coor_buf[i * 8 + 3], + coor_buf[i * 8 + 4], coor_buf[i * 8 + 5], + coor_buf[i * 8 + 6], coor_buf[i * 8 + 7]); + }*/ + + /*realign coor data by new trace ID*/ + for (i = 0; i < touch_num - 1; i++) { + small = &coor_buf[BYTES_PER_COORD * i]; + need_swap = false; + for (j = i + 1; j < touch_num; j++) { + if (coor_buf[BYTES_PER_COORD * j] < *small) { + need_swap = true; + small = &coor_buf[BYTES_PER_COORD * j]; + } + } + /*swap*/ + if (need_swap) { + memcpy(temp_buf, small, BYTES_PER_COORD); + memcpy(small, &coor_buf[BYTES_PER_COORD * i], + BYTES_PER_COORD); + memcpy(&coor_buf[BYTES_PER_COORD * i], temp_buf, + BYTES_PER_COORD); + } + } + + /*for (i = 0; i < touch_num; i++) { + ts_info("final data%d:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x", + i, coor_buf[i * 8], coor_buf[i * 8 + 1], + coor_buf[i * 8 + 2], coor_buf[i * 8 + 3], + coor_buf[i * 8 + 4], coor_buf[i * 8 + 5], + coor_buf[i * 8 + 6], coor_buf[i * 8 + 7]); + }*/ + + return 0; +} + +/** + * goodix_event_handler - handle firmware event + * + * @dev: pointer to touch device + * @ts_event: pointer to touch event structure + * Returns 0 - succeed,<0 - failed + */ + +static int goodix_touch_handler(struct goodix_ts_device *dev, + struct goodix_ts_event *ts_event, u8 *pre_buf, + u32 pre_buf_len) +{ + struct goodix_touch_data *touch_data = &ts_event->event_data.touch_data; + struct goodix_ts_coords *coords = &(touch_data->coords[0]); + int max_touch_num = dev->board_data->panel_max_id; + unsigned char buffer[4 + BYTES_PER_COORD * max_touch_num]; + unsigned char coord_sta; + int touch_num = 0, i, r; + unsigned char chksum = 0; + + if (!pre_buf || pre_buf_len != (4 + BYTES_PER_COORD)) { + r = -EINVAL; + return r; + } + + /*copy data to buffer*/ + memcpy(buffer, pre_buf, pre_buf_len); + + /* buffer[1]: touch state */ + coord_sta = buffer[1]; + + touch_num = coord_sta & 0x0F; + + if (unlikely(touch_num > max_touch_num)) { + touch_num = -EINVAL; + goto exit_clean_sta; + } else if (unlikely(touch_num > 1)) { + r = goodix_i2c_read_trans( + dev, + dev->reg.coor + 4 + + BYTES_PER_COORD, /*TS_REG_COORDS_BASE*/ + &buffer[4 + BYTES_PER_COORD], + (touch_num - 1) * BYTES_PER_COORD); + if (unlikely(r < 0)) + goto exit_clean_sta; + } + + /* touch_num * BYTES_PER_COORD + 1(touch event state) + * + 1(checksum) + 1(key value) */ + if (dev->ic_type == IC_TYPE_NANJING) { + chksum = checksum_u8(&buffer[1], + touch_num * BYTES_PER_COORD + 3); + } else { + chksum = checksum_u8(&buffer[0], + touch_num * BYTES_PER_COORD + 4); + } + if (unlikely(chksum != 0)) { + ts_err("Checksum error:%X, ic_type:%d", chksum, dev->ic_type); + r = -EINVAL; + goto exit_clean_sta; + } + + touch_data->have_key = false; /*clear variable*/ + touch_data->key_value = 0; /*clear variable*/ + touch_data->have_key = (coord_sta >> 4) & 0x01; + if (unlikely(touch_data->have_key)) { + touch_data->key_value = buffer[touch_num * BYTES_PER_COORD + 2]; + if (dev->board_data->pen_enable) + touch_data->key_value = + (touch_data->key_value & 0x0f) | + ((touch_data->key_value & 0xf0) >> + (4 - dev->board_data->tp_key_num)); + } + /*ts_info("$$$$$$coord_sta:0x%02x, have_key:%d, key_value:0x%02x", + coord_sta, touch_data->have_key, touch_data->key_value);*/ + + /*for (i = 0; i < touch_num; i++) { + ts_info("raw coor data%d:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x", + i, buffer[i * 8 + 2], buffer[i * 8 + 3], + buffer[i * 8 + 4], buffer[i * 8 + 5], + buffer[i * 8 + 6], buffer[i * 8 + 7], + buffer[i * 8 + 8], buffer[i * 8 + 9]); + }*/ + + /*add end*/ + + /*remap trace id*/ + if (dev->ic_type == IC_TYPE_NANJING) + goodix_remap_trace_id(dev, &buffer[2], + 2 + BYTES_PER_COORD * max_touch_num, + touch_num); + + /*clear buffer*/ + memset(touch_data->coords, 0x00, sizeof(touch_data->coords)); + memset(touch_data->pen_coords, 0x00, sizeof(touch_data->pen_coords)); + + if (likely(touch_num >= 1)) { + /*"0 ~ touch_num - 2" is finger, "touch_num - 1" may be a finger or a pen*/ + /*process "0 ~ touch_num -2"*/ + for (i = 0; i < touch_num - 1; i++) { + coords->id = buffer[i * BYTES_PER_COORD + 2] & 0x0f; + coords->x = buffer[i * BYTES_PER_COORD + 3] | + (buffer[i * BYTES_PER_COORD + 4] << 8); + coords->y = buffer[i * BYTES_PER_COORD + 5] | + (buffer[i * BYTES_PER_COORD + 6] << 8); + coords->w = buffer[i * BYTES_PER_COORD + 7]; + coords->p = coords->w; + coords->overlapping_area = buffer[8]; + coords->area = buffer[i * BYTES_PER_COORD + 9]; + coords++; + } + + /*process "touch_num - 1", it may be a finger or a pen*/ + /*it's a pen*/ + i = touch_num - 1; + //ts_err("%s:i=%d touch_num=%d\n",__func__,i,touch_num); + if (unlikely(touch_num >= 1 && + buffer[i * BYTES_PER_COORD + 2] >= 0x80)) { + if (dev->board_data->pen_enable) { /*pen_enable*/ + touch_data->pen_down = true; + /*change pen's trace ID, let it equal to "panel_max_id - 1"*/ + /*touch_data->pen_coords[0].id = dev->board_data->panel_max_id - 1;*/ + touch_data->pen_coords[0].id = + dev->board_data->panel_max_id * 2; + touch_data->pen_coords[0].x = + buffer[i * BYTES_PER_COORD + 3] | + (buffer[i * BYTES_PER_COORD + 4] << 8); + touch_data->pen_coords[0].y = + buffer[i * BYTES_PER_COORD + 5] | + (buffer[i * BYTES_PER_COORD + 6] << 8); + touch_data->pen_coords[0].w = + buffer[i * BYTES_PER_COORD + 7]; + touch_data->pen_coords[0].p = + touch_data->pen_coords[0].w; + } + } else { /*it's a finger*/ + coords->id = buffer[i * BYTES_PER_COORD + 2] & 0x0f; + coords->x = buffer[i * BYTES_PER_COORD + 3] | + (buffer[i * BYTES_PER_COORD + 4] << 8); + coords->y = buffer[i * BYTES_PER_COORD + 5] | + (buffer[i * BYTES_PER_COORD + 6] << 8); + coords->w = buffer[i * BYTES_PER_COORD + 7]; + coords->p = coords->w; + coords->overlapping_area = buffer[8]; + coords->area = buffer[i * BYTES_PER_COORD + 9]; + /*ts_debug("EF:[%d](%d, %d)", coords->id, coords->x, coords->y);*/ + if (touch_data->pen_down == true) { + touch_data->pen_down = false; + /*ts_info("***pen leave");*/ + } + } + } + + /*swap coord*/ + goodix_swap_coords(dev, &touch_data->coords[0], touch_num); + goodix_swap_coords(dev, &touch_data->pen_coords[0], 1); + + touch_data->touch_num = touch_num; + /* mark this event as touch event */ + ts_event->event_type = EVENT_TOUCH; + r = 0; + +exit_clean_sta: + /* handshake */ + /*buffer[0] = 0x00;*/ + /*goodix_i2c_write_trans(dev, dev->reg.coor, buffer, 1);*/ + return r; +} + +static int goodix_event_handler(struct goodix_ts_device *dev, + struct goodix_ts_event *ts_event) +{ + unsigned char pre_buf[4 + BYTES_PER_COORD]; + unsigned char event_sta; + struct i2c_client *client = to_i2c_client(dev->dev); + struct goodix_ts_core *core_data = i2c_get_clientdata(client); + int r; + + /*memset(pre_buf, 0, sizeof(pre_buf));*/ + + r = goodix_i2c_read_trans(dev, dev->reg.coor, pre_buf, + 4 + BYTES_PER_COORD); + if (unlikely(r < 0)) + return r; + + /* buffer[0]: event state */ + core_data->event_status = pre_buf[0]; + event_sta = pre_buf[0]; + + if (likely((event_sta & GOODIX_TOUCH_EVENT) == GOODIX_TOUCH_EVENT)) { + /*handle touch event*/ + goodix_touch_handler(dev, ts_event, pre_buf, + 4 + BYTES_PER_COORD); + } else if (unlikely((event_sta & GOODIX_REQUEST_EVENT) == + GOODIX_REQUEST_EVENT)) { + /* handle request event */ + ts_event->event_type = EVENT_REQUEST; + goodix_request_handler(dev, &ts_event->event_data.request_data); + } else if ((event_sta & GOODIX_GESTURE_EVENT) == GOODIX_GESTURE_EVENT) { + /* handle gesture event */ + ts_info("Gesture event"); + } else if ((event_sta & GOODIX_HOTKNOT_EVENT) == GOODIX_HOTKNOT_EVENT) { + /* handle hotknot event */ + ts_info("Hotknot event"); + } else { + ts_info("unknow event type:%02x", event_sta); + r = -EINVAL; + } + + return r; +} + +/** + * goodix_hw_suspend - Let touch deivce stay in lowpower mode. + * @dev: pointer to goodix touch device + * @return: 0 - succeed, < 0 - failed + */ +static int goodix_hw_suspend(struct goodix_ts_device *dev) +{ + struct goodix_ts_cmd sleep_cmd; + int r = 0; + + goodix_cmds_init(&sleep_cmd, COMMAND_SLEEP, 0, dev->reg.command); + if (sleep_cmd.initialized) { + r = goodix_send_command(dev, &sleep_cmd); + if (!r) + ts_info("Chip in sleep mode"); + } else + ts_err("Uninitialized sleep command"); + + return r; +} + +/** + * goodix_hw_resume - Let touch deivce stay in active mode. + * @dev: pointer to goodix touch device + * @return: 0 - succeed, < 0 - failed + */ +static int goodix_hw_resume(struct goodix_ts_device *dev) +{ + int r = 0, i, retry = GOODIX_BUS_RETRY_TIMES; + u8 temp_buf[256], checksum; + u8 data[2] = { 0x00 }; + + for (; retry > 0; retry--) { + /*resume IC*/ + if (dev->ic_type == IC_TYPE_NORMANDY) + goodix_hw_reset(dev); + else if (dev->ic_type == IC_TYPE_NANJING) { + /*1. read 0x8000 to resume nanjing*/ + goodix_i2c_read(dev, 0x8000, data, 1); + msleep(150); + /*2. check resume success or not*/ + for (i = 0; i < 10; i++) { + r = goodix_i2c_read(dev, dev->reg.command, data, + 1); + if (!r && data[0] == 0xff) + break; + msleep(20); + } + + if (i >= 10) { + ts_err("resume nanjing failed, after read 0x8000, 0x8040 not equal 0xff"); + continue; + } + /*3. close hid i2c*/ + goodix_close_hidi2c_mode(dev); + + /*4. clear coor*/ + data[0] = 0; + data[1] = 0; + goodix_i2c_write(dev, 0x824d, data, 2); + } + + /*read version and check checksum*/ + if (dev->reg.version_base && dev->reg.version_len < 256) { + r = goodix_i2c_read(dev, dev->reg.version_base, + temp_buf, dev->reg.version_len); + if (r < 0) + continue; + + checksum = checksum_u8(temp_buf, dev->reg.version_len); + if (!checksum) { + ts_info("read version SUCCESS"); + break; + } + } + } + return r; +} + +static int goodix_esd_check(struct goodix_ts_device *dev) +{ + int r; + u8 data = 0; + + if (dev->reg.esd == 0) { + ts_err("esd reg is NULL"); + return 0; + } + + /*check dynamic esd*/ + if (dev->ic_type == IC_TYPE_NORMANDY) + r = dev->hw_ops->read_trans(dev, TS_REG_ESD_TICK_R, &data, 1); + else + r = dev->hw_ops->read_trans(dev, dev->reg.esd, &data, 1); + + if (r < 0 || (data == GOODIX_ESD_TICK_WRITE_DATA)) { + ts_info("dynamic esd occur, r:%d, data:0x%02x", r, data); + r = -EINVAL; + goto exit; + } + + /*check static esd*/ + if (dev->ic_type == IC_TYPE_NANJING) { + r = dev->hw_ops->read_trans(dev, 0x8043, &data, 1); + + if (r < 0 || (data != 0xaa)) { + ts_info("static esd occur, r:%d, data:0x%02x", r, data); + r = -EINVAL; + goto exit; + } + } + +exit: + return r; +} + +/* hardware opeation funstions */ +static const struct goodix_ts_hw_ops hw_i2c_ops = { + .init = goodix_hw_init, + .read = goodix_i2c_read, + .write = goodix_i2c_write, + .read_trans = goodix_i2c_read_trans, + .write_trans = goodix_i2c_write_trans, + .reset = goodix_hw_reset, + .event_handler = goodix_event_handler, + .send_config = goodix_send_config, + .read_config = goodix_read_config, + .send_cmd = goodix_send_command, + .read_version = goodix_read_version, + .suspend = goodix_hw_suspend, + .resume = goodix_hw_resume, + .check_hw = goodix_esd_check, +}; + +static struct platform_device *goodix_pdev; + +static void goodix_pdev_release(struct device *dev) +{ + kfree(goodix_pdev); + return; +} + +static int goodix_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct goodix_ts_device *ts_device = NULL; + struct goodix_ts_board_data *ts_bdata = NULL; + int r = 0; + + ts_err("enter::%s\n", __func__); + + r = i2c_check_functionality(client->adapter, I2C_FUNC_I2C); + if (!r) + return -EIO; + + /* board data */ + ts_bdata = devm_kzalloc( + &client->dev, sizeof(struct goodix_ts_board_data), GFP_KERNEL); + if (!ts_bdata) + return -ENOMEM; + + if (IS_ENABLED(CONFIG_OF) && client->dev.of_node) { + /* parse devicetree property */ + r = goodix_parse_dt(client->dev.of_node, ts_bdata); + if (r < 0) + return r; + } +#ifdef CONFIG_ACPI + else if (ACPI_COMPANION(&client->dev)) { + r = goodix_parse_acpi(&client->dev, ts_bdata); + if (r < 0) + return r; + } +#endif + else { + /* use platform data */ + devm_kfree(&client->dev, ts_bdata); + ts_bdata = client->dev.platform_data; + } + + if (!ts_bdata) + return -ENODEV; + + ts_device = devm_kzalloc(&client->dev, sizeof(struct goodix_ts_device), + GFP_KERNEL); + if (!ts_device) + return -ENOMEM; + + ts_device->name = "GTx5 TouchDevcie"; + ts_device->dev = &client->dev; + ts_device->board_data = ts_bdata; + ts_device->hw_ops = &hw_i2c_ops; + + /* ts core device */ + goodix_pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); + if (!goodix_pdev) + return -ENOMEM; + + goodix_pdev->name = GOODIX_CORE_DRIVER_NAME; + goodix_pdev->id = 0; + goodix_pdev->num_resources = 0; + /* + * you could find this platform dev in + * /sys/devices/platfrom/goodix_ts.0 + * goodix_pdev->dev.parent = &client->dev; + */ + goodix_pdev->dev.platform_data = ts_device; + goodix_pdev->dev.release = goodix_pdev_release; + + /* register platform device, then the goodix_ts_core + * module will probe the touch deivce. */ + r = platform_device_register(goodix_pdev); + + ts_info("goodix9886_i2c_probe OUT"); + + return r; +} + +static int goodix_i2c_remove(struct i2c_client *client) +{ + platform_device_unregister(goodix_pdev); + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id i2c_matchs[] = { + { + .compatible = TS_DT_COMPATIBLE, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, i2c_matchs); +#endif + +#ifdef CONFIG_ACPI +static const struct acpi_device_id acpi_matchs[] = { + { .id = "PNPxxx" }, + {}, +}; +MODULE_DEVICE_TABLE(acpi, acpi_matchs); +#endif + +static const struct i2c_device_id i2c_id_table[] = { + { TS_DRIVER_NAME, 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, i2c_id_table); + +static struct i2c_driver goodix_i2c_driver = { + .driver = { + .name = TS_DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(i2c_matchs), +#ifdef CONFIG_ACPI + .acpi_match_table = acpi_matchs, +#endif + }, + .probe = goodix_i2c_probe, + .remove = goodix_i2c_remove, + .id_table = i2c_id_table, +}; + +static int __init goodix_i2c_init(void) +{ + ts_info("GTx5xx HW layer init"); + return i2c_add_driver(&goodix_i2c_driver); +} + +static void __exit goodix_i2c_exit(void) +{ + i2c_del_driver(&goodix_i2c_driver); + return; +} + +module_init(goodix_i2c_init); +module_exit(goodix_i2c_exit); + +MODULE_DESCRIPTION("Goodix GTx5 Touchscreen Hardware Module"); +MODULE_AUTHOR("Goodix, Inc."); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_tools.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_tools.c new file mode 100644 index 000000000000..cd6387d57709 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_tools.c @@ -0,0 +1,722 @@ +/* + * Goodix GTX5 tools Dirver + * + * Copyright (C) 2015 - 2016 Goodix, Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * Authors: Wang Yafei + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "goodix_ts_core.h" + +#define GOODIX_TOOLS_NAME "gtp_tools" +#define GOODIX_TS_IOC_MAGIC 'G' +#define NEGLECT_SIZE_MASK (~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) + +#define GTP_IRQ_ENABLE _IO(GOODIX_TS_IOC_MAGIC, 0) +#define GTP_DEV_RESET _IO(GOODIX_TS_IOC_MAGIC, 1) +#define GTP_SEND_COMMAND (_IOW(GOODIX_TS_IOC_MAGIC, 2, u8) & NEGLECT_SIZE_MASK) +#define GTP_SEND_CONFIG (_IOW(GOODIX_TS_IOC_MAGIC, 3, u8) & NEGLECT_SIZE_MASK) +#define GTP_ASYNC_READ (_IOR(GOODIX_TS_IOC_MAGIC, 4, u8) & NEGLECT_SIZE_MASK) +#define GTP_SYNC_READ (_IOR(GOODIX_TS_IOC_MAGIC, 5, u8) & NEGLECT_SIZE_MASK) +#define GTP_ASYNC_WRITE (_IOW(GOODIX_TS_IOC_MAGIC, 6, u8) & NEGLECT_SIZE_MASK) +#define GTP_READ_CONFIG (_IOW(GOODIX_TS_IOC_MAGIC, 7, u8) & NEGLECT_SIZE_MASK) +#define GTP_ESD_ENABLE _IO(GOODIX_TS_IOC_MAGIC, 8) +#define GTP_DRV_VERSION (_IOR(GOODIX_TS_IOC_MAGIC, 9, u8) & NEGLECT_SIZE_MASK) + +#define GOODIX_TS_IOC_MAXNR 10 + +#define IRQ_FALG (0x01 << 2) + +#define I2C_MSG_HEAD_LEN 20 +#define TS_REG_COORDS_BASE 0x4100 + +/* + * struct goodix_tools_data - goodix tools data message used in sync read + * @data: The buffer into which data is written + * @reg_addr: Slave device register start address to start read data + * @length: Number of data bytes in @data being read from slave device + * @filled: When buffer @data be filled will set this flag with 1, outhrwise 0 + * @list_head:Eonnet every goodix_tools_data struct into a list +*/ + +struct goodix_tools_data { + u32 reg_addr; + u32 length; + u8 *data; + bool filled; + struct list_head list; +}; + +/* + * struct goodix_tools_dev - goodix tools device struct + * @ts_core: The core data struct of ts driver + * @ops_mode: represent device work mode + * @rawdiffcmd: Set slave device into rawdata mode + * @normalcmd: Set slave device into normal mode + * @wq: Wait queue struct use in synchronous data read + * @mutex: Protect goodix_tools_dev +*/ +struct goodix_tools_dev { + struct goodix_ts_core *ts_core; + struct list_head head; + unsigned int ops_mode; + struct goodix_ts_cmd rawdiffcmd, normalcmd; + wait_queue_head_t wq; + struct mutex mutex; + atomic_t t_count; + struct goodix_ext_module module; +} *goodix_tools_dev; + +/* read data from i2c asynchronous, +** success return bytes read, else return <= 0 +*/ +static int async_read(struct goodix_tools_dev *dev, void __user *arg) +{ + u8 *databuf = NULL; + int ret = 0; + u32 reg_addr, length; + u8 i2c_msg_head[I2C_MSG_HEAD_LEN]; + struct goodix_ts_device *ts_dev = dev->ts_core->ts_dev; + const struct goodix_ts_hw_ops *hw_ops = ts_dev->hw_ops; + + ret = copy_from_user(&i2c_msg_head, arg, I2C_MSG_HEAD_LEN); + if (ret) { + ret = -EFAULT; + goto err_out; + } + reg_addr = i2c_msg_head[0] + (i2c_msg_head[1] << 8) + + (i2c_msg_head[2] << 16) + (i2c_msg_head[3] << 24); + length = i2c_msg_head[4] + (i2c_msg_head[5] << 8) + + (i2c_msg_head[6] << 16) + (i2c_msg_head[7] << 24); + + databuf = kzalloc(length, GFP_KERNEL); + if (!databuf) { + ts_err("Alloc memory failed"); + return -ENOMEM; + } + + if (!hw_ops->read_trans(ts_dev, reg_addr, databuf, length)) { + if (copy_to_user((u8 *)arg + I2C_MSG_HEAD_LEN, databuf, + length)) { + ret = -EFAULT; + ts_err("Copy_to_user failed"); + } else { + ret = length; + } + } else { + ret = -EBUSY; + ts_err("Read i2c failed"); + } +err_out: + kfree(databuf); + return ret; +} + +/* if success return config data length */ +static int read_config_data(struct goodix_ts_device *ts_dev, void __user *arg) +{ + int ret = 0; + u32 reg_addr, length; + u8 i2c_msg_head[I2C_MSG_HEAD_LEN]; + u8 *tmp_buf; + + ret = copy_from_user(&i2c_msg_head, arg, I2C_MSG_HEAD_LEN); + if (ret) { + ts_err("Copy data from user failed"); + return -EFAULT; + } + reg_addr = i2c_msg_head[0] + (i2c_msg_head[1] << 8) + + (i2c_msg_head[2] << 16) + (i2c_msg_head[3] << 24); + length = i2c_msg_head[4] + (i2c_msg_head[5] << 8) + + (i2c_msg_head[6] << 16) + (i2c_msg_head[7] << 24); + ts_info("read config,reg_addr=0x%x, length=%d", reg_addr, length); + tmp_buf = kzalloc(length, GFP_KERNEL); + if (!tmp_buf) { + ts_err("failed alloc memory"); + return -ENOMEM; + } + /* if reg_addr == 0, read config data with specific flow */ + if (!reg_addr) { + if (ts_dev->hw_ops->read_config) + ret = ts_dev->hw_ops->read_config(ts_dev, tmp_buf, 0); + else + ret = -EINVAL; + } else { + ret = ts_dev->hw_ops->read_trans(ts_dev, reg_addr, tmp_buf, + length); + if (!ret) + ret = length; + } + if (ret <= 0) + goto err_out; + + if (copy_to_user((u8 *)arg + I2C_MSG_HEAD_LEN, tmp_buf, ret)) { + ret = -EFAULT; + ts_err("Copy_to_user failed"); + } + +err_out: + kfree(tmp_buf); + return ret; +} + +/* read data from i2c synchronous, +** success return bytes read, else return <= 0 +*/ +static int sync_read(struct goodix_tools_dev *dev, void __user *arg) +{ + int ret = 0; + u8 i2c_msg_head[I2C_MSG_HEAD_LEN]; + struct goodix_tools_data tools_data; + + ret = copy_from_user(&i2c_msg_head, arg, I2C_MSG_HEAD_LEN); + if (ret) { + ts_err("Copy data from user failed"); + return -EFAULT; + } + tools_data.reg_addr = i2c_msg_head[0] + (i2c_msg_head[1] << 8) + + (i2c_msg_head[2] << 16) + (i2c_msg_head[3] << 24); + tools_data.length = i2c_msg_head[4] + (i2c_msg_head[5] << 8) + + (i2c_msg_head[6] << 16) + (i2c_msg_head[7] << 24); + tools_data.filled = 0; + + tools_data.data = kzalloc(tools_data.length, GFP_KERNEL); + if (!tools_data.data) { + ts_err("Alloc memory failed"); + return -ENOMEM; + } + + mutex_lock(&dev->mutex); + list_add_tail(&tools_data.list, &dev->head); + mutex_unlock(&dev->mutex); + /* wait queue will timeout after 1 seconds */ + wait_event_interruptible_timeout(dev->wq, tools_data.filled == 1, + HZ * 3); + + mutex_lock(&dev->mutex); + list_del(&tools_data.list); + mutex_unlock(&dev->mutex); + if (tools_data.filled == 1) { + if (copy_to_user((u8 *)arg + I2C_MSG_HEAD_LEN, tools_data.data, + tools_data.length)) { + ret = -EFAULT; + ts_err("Copy_to_user failed"); + } else { + ret = tools_data.length; + } + } else { + ret = -EAGAIN; + ts_err("Wait queue timeout"); + } + + kfree(tools_data.data); + return ret; +} + +/* write data to i2c asynchronous, +** success return bytes write, else return <= 0 +*/ +static int async_write(struct goodix_tools_dev *dev, void __user *arg) +{ + u8 *databuf; + int ret = 0; + u32 reg_addr, length; + u8 i2c_msg_head[I2C_MSG_HEAD_LEN]; + struct goodix_ts_device *ts_dev = dev->ts_core->ts_dev; + const struct goodix_ts_hw_ops *hw_ops = ts_dev->hw_ops; + + ret = copy_from_user(&i2c_msg_head, arg, I2C_MSG_HEAD_LEN); + if (ret) { + ts_err("Copy data from user failed"); + return -EFAULT; + } + reg_addr = i2c_msg_head[0] + (i2c_msg_head[1] << 8) + + (i2c_msg_head[2] << 16) + (i2c_msg_head[3] << 24); + length = i2c_msg_head[4] + (i2c_msg_head[5] << 8) + + (i2c_msg_head[6] << 16) + (i2c_msg_head[7] << 24); + + databuf = kzalloc(length, GFP_KERNEL); + if (!databuf) { + ts_err("Alloc memory failed"); + return -ENOMEM; + } + ret = copy_from_user(databuf, (u8 *)arg + I2C_MSG_HEAD_LEN, length); + if (ret) { + ret = -EFAULT; + ts_err("Copy data from user failed"); + goto err_out; + } + + if (hw_ops->write_trans(ts_dev, reg_addr, databuf, length)) { + ret = -EBUSY; + ts_err("Write data to device failed"); + } else { + ret = length; + } + +err_out: + kfree(databuf); + return ret; +} + +/** + + * sync_read_rawdata - read device register through i2c bus + + * @dev: pointer to device data + + * @addr: register address + + * @data: read buffer + + * @len: bytes to read + + * return: 0 - read ok, < 0 - i2c transter error + +*/ + +int sync_read_rawdata(unsigned int reg, unsigned char *data, unsigned int len) + +{ + int ret = 0; + + struct goodix_tools_dev *dev = goodix_tools_dev; + + struct goodix_tools_data tools_data; + + tools_data.reg_addr = reg; + + tools_data.length = len; + + tools_data.filled = 0; + + tools_data.data = kzalloc(tools_data.length, GFP_KERNEL); + + if (!tools_data.data) { + ts_err("Alloc memory failed"); + + return -ENOMEM; + } + + mutex_lock(&dev->mutex); + + list_add_tail(&tools_data.list, &dev->head); + + ts_info("add sync_read to list"); + + mutex_unlock(&dev->mutex); + + /* wait queue will timeout after 1 seconds */ + + wait_event_interruptible_timeout(dev->wq, tools_data.filled == 1, + HZ * 3); + + mutex_lock(&dev->mutex); + + list_del(&tools_data.list); + + mutex_unlock(&dev->mutex); + + if (tools_data.filled == 1) { + memcpy(data, tools_data.data, tools_data.length); + + } else { + ret = -EAGAIN; + + ts_err("Wait queue timeout"); + } + + kfree(tools_data.data); + + return ret; +} + +int goodix_tools_register(void) + +{ + int ret = 0; + + ts_info("register tools module"); + + /* Only the first time open device need to register module */ + + ret = goodix_register_ext_module(&goodix_tools_dev->module); + + if (ret) { + ts_info("failed register to core module"); + } + + return ret; +} + +int goodix_tools_unregister(void) + +{ + int ret = 0; + + /* when the last close this dev node unregister the module */ + + ret = goodix_unregister_ext_module(&goodix_tools_dev->module); + + return ret; +} + +static int init_cfg_data(struct goodix_ts_config *cfg, void __user *arg) +{ + int ret = 0; + u32 reg_addr, length; + u8 i2c_msg_head[I2C_MSG_HEAD_LEN]; + + cfg->initialized = 0; + mutex_init(&cfg->lock); + ret = copy_from_user(&i2c_msg_head, arg, I2C_MSG_HEAD_LEN); + if (ret) { + ts_err("Copy data from user failed"); + return -EFAULT; + } + + reg_addr = i2c_msg_head[0] + (i2c_msg_head[1] << 8) + + (i2c_msg_head[2] << 16) + (i2c_msg_head[3] << 24); + length = i2c_msg_head[4] + (i2c_msg_head[5] << 8) + + (i2c_msg_head[6] << 16) + (i2c_msg_head[7] << 24); + + ret = copy_from_user(cfg->data, (u8 *)arg + I2C_MSG_HEAD_LEN, length); + if (ret) { + ret = -EFAULT; + ts_err("Copy data from user failed"); + goto err_out; + } + cfg->reg_base = reg_addr; + cfg->length = length; + strlcpy(cfg->name, "tools-send-cfg", sizeof(cfg->name)); + cfg->delay = 50; + cfg->initialized = true; + return 0; + +err_out: + return ret; +} +/** + * goodix_tools_ioctl - ioctl implementation + * + * @filp: Pointer to file opened + * @cmd: Ioctl opertion command + * @arg: Command data + * Returns >=0 - succeed, else failed + */ +static long goodix_tools_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + int ret = 0; + struct goodix_tools_dev *dev = filp->private_data; + struct goodix_ts_device *ts_dev; + const struct goodix_ts_hw_ops *hw_ops; + struct goodix_ts_cmd temp_cmd; + struct goodix_ts_config *temp_cfg = NULL; + + if (dev->ts_core == NULL) { + ts_err("Tools module not register"); + return -EINVAL; + } + ts_dev = dev->ts_core->ts_dev; + hw_ops = ts_dev->hw_ops; + + if (_IOC_TYPE(cmd) != GOODIX_TS_IOC_MAGIC) { + ts_err("Bad magic num:%c", _IOC_TYPE(cmd)); + return -ENOTTY; + } + if (_IOC_NR(cmd) > GOODIX_TS_IOC_MAXNR) { + ts_err("Bad cmd num:%d > %d", _IOC_NR(cmd), + GOODIX_TS_IOC_MAXNR); + return -ENOTTY; + } + + switch (cmd & NEGLECT_SIZE_MASK) { + case GTP_IRQ_ENABLE: + if (arg == 1) { + goodix_ts_irq_enable(dev->ts_core, true); + mutex_lock(&dev->mutex); + dev->ops_mode |= IRQ_FALG; + mutex_unlock(&dev->mutex); + ts_info("IRQ enabled"); + } else if (arg == 0) { + goodix_ts_irq_enable(dev->ts_core, false); + mutex_lock(&dev->mutex); + dev->ops_mode &= ~IRQ_FALG; + mutex_unlock(&dev->mutex); + ts_info("IRQ disabled"); + } else { + ts_info("Irq aready set with, arg = %ld", arg); + } + ret = 0; + break; + case GTP_ESD_ENABLE: + if (arg == 0) + goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL); + else + goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL); + break; + case GTP_DEV_RESET: + hw_ops->reset(ts_dev); + break; + case GTP_SEND_COMMAND: + ret = copy_from_user(&temp_cmd, (void __user *)arg, + sizeof(struct goodix_ts_cmd)); + if (ret) { + ret = -EINVAL; + goto err_out; + } + + ret = hw_ops->send_cmd(ts_dev, &temp_cmd); + if (ret) { + ts_err("Send command failed"); + ret = -EAGAIN; + } + break; + case GTP_SEND_CONFIG: + temp_cfg = kzalloc(sizeof(struct goodix_ts_config), GFP_KERNEL); + if (temp_cfg == NULL) { + ts_err("Memory allco err"); + ret = -ENOMEM; + goto err_out; + } + + ret = init_cfg_data(temp_cfg, (void __user *)arg); + + if (!ret && hw_ops->send_config) { + ret = hw_ops->send_config(ts_dev, temp_cfg); + if (ret) { + ts_err("Failed send config"); + ret = -EAGAIN; + } else { + ts_info("Send config success"); + ret = 0; + } + } + break; + case GTP_READ_CONFIG: + ret = read_config_data(ts_dev, (void __user *)arg); + if (ret > 0) + ts_info("success read config:len=%d", ret); + else + ts_err("failed read config:ret=0x%x", ret); + break; + case GTP_ASYNC_READ: + ret = async_read(dev, (void __user *)arg); + if (ret < 0) + ts_err("Async data read failed"); + break; + case GTP_SYNC_READ: + if (filp->f_flags & O_NONBLOCK) { + ts_err("Goodix tools now worked in sync_bus mode"); + ret = -EAGAIN; + goto err_out; + } + ret = sync_read(dev, (void __user *)arg); + if (ret < 0) + ts_err("Sync data read failed"); + break; + case GTP_ASYNC_WRITE: + ret = async_write(dev, (void __user *)arg); + if (ret < 0) + ts_err("Async data write failed"); + break; + case GTP_DRV_VERSION: + ret = copy_to_user((u8 *)arg, GOODIX_DRIVER_VERSION, + sizeof(GOODIX_DRIVER_VERSION)); + if (ret) + ts_err("failed copy driver version info to user"); + break; + default: + ts_info("Invalid cmd"); + ret = -ENOTTY; + break; + } + +err_out: + if (!temp_cfg) { + kfree(temp_cfg); + temp_cfg = NULL; + } + return ret; +} + +#ifdef CONFIG_COMPAT +static long goodix_tools_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + void __user *arg32 = compat_ptr(arg); + + if (!file->f_op || !file->f_op->unlocked_ioctl) + return -ENOTTY; + return file->f_op->unlocked_ioctl(file, cmd, (unsigned long)arg32); +} +#endif + +static int goodix_tools_open(struct inode *inode, struct file *filp) +{ + int ret = 0; + filp->private_data = goodix_tools_dev; + ts_info("tools open"); + /* Only the first time open device need to register module */ + ret = goodix_register_ext_module(&goodix_tools_dev->module); + if (ret) { + ts_info("failed register to core module"); + } + + return ret; +} + +static int goodix_tools_release(struct inode *inode, struct file *filp) +{ + int ret = 0; + /* when the last close this dev node unregister the module */ + ret = goodix_unregister_ext_module(&goodix_tools_dev->module); + return ret; +} + +/** + * goodix_tools_module_irq - goodix tools Irq handle + * This functions is excuted when interrupt happended + * + * @core_data: pointer to touch core data + * @module: pointer to goodix_ext_module struct + * return: EVT_CONTINUE let other module handle this irq + */ +static int goodix_tools_module_irq(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + struct goodix_tools_dev *dev = module->priv_data; + struct goodix_ts_device *ts_dev = dev->ts_core->ts_dev; + const struct goodix_ts_hw_ops *hw_ops = ts_dev->hw_ops; + struct goodix_tools_data *tools_data; + int r = 0; + u8 evt_sta = 0; + + mutex_lock(&dev->mutex); + if (!list_empty(&dev->head)) { + r = hw_ops->read_trans(ts_dev, + ts_dev->reg.coor /* TS_REG_COORDS_BASE*/, + &evt_sta, 1); + if (r < 0 || ((evt_sta & GOODIX_TOUCH_EVENT) == 0)) { + ts_err("data not ready:0x%x, read ret =%d", evt_sta, r); + mutex_unlock(&dev->mutex); + return EVT_CONTINUE; + } + + list_for_each_entry(tools_data, &dev->head, list) { + if (!hw_ops->read_trans(ts_dev, tools_data->reg_addr, + tools_data->data, + tools_data->length)) { + tools_data->filled = 1; + } + } + wake_up(&dev->wq); + } + mutex_unlock(&dev->mutex); + return EVT_CONTINUE; +} + +static int goodix_tools_module_init(struct goodix_ts_core *core_data, + struct goodix_ext_module *module) +{ + struct goodix_tools_dev *tools_dev = module->priv_data; + + if (core_data) + tools_dev->ts_core = core_data; + else + return -ENODEV; + + return 0; +} + +static const struct file_operations goodix_tools_fops = { + .owner = THIS_MODULE, + .open = goodix_tools_open, + .release = goodix_tools_release, + .unlocked_ioctl = goodix_tools_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = goodix_tools_compat_ioctl, +#endif +}; + +static struct miscdevice goodix_tools_miscdev = { + .minor = MISC_DYNAMIC_MINOR, + .name = GOODIX_TOOLS_NAME, + .fops = &goodix_tools_fops, +}; + +static struct goodix_ext_module_funcs goodix_tools_module_funcs = { + .irq_event = goodix_tools_module_irq, + .init = goodix_tools_module_init, +}; + +/** + * goodix_tools_init - init goodix tools device and register a miscdevice + * + * return: 0 success, else failed + */ +static int __init goodix_tools_init(void) +{ + int ret; + + goodix_tools_dev = kzalloc(sizeof(struct goodix_tools_dev), GFP_KERNEL); + if (goodix_tools_dev == NULL) { + ts_err("Memory allco err"); + return -ENOMEM; + } + + INIT_LIST_HEAD(&goodix_tools_dev->head); + goodix_tools_dev->ops_mode = 0; + goodix_tools_dev->ops_mode |= IRQ_FALG; + init_waitqueue_head(&goodix_tools_dev->wq); + mutex_init(&goodix_tools_dev->mutex); + atomic_set(&goodix_tools_dev->t_count, 0); + + goodix_tools_dev->module.funcs = &goodix_tools_module_funcs; + goodix_tools_dev->module.name = GOODIX_TOOLS_NAME; + goodix_tools_dev->module.priv_data = goodix_tools_dev; + goodix_tools_dev->module.priority = EXTMOD_PRIO_DBGTOOL; + + ret = misc_register(&goodix_tools_miscdev); + if (ret) + ts_err("Debug tools miscdev register failed"); + + return ret; +} + +static void __exit goodix_tools_exit(void) +{ + misc_deregister(&goodix_tools_miscdev); + kfree(goodix_tools_dev); + ts_info("Goodix tools miscdev exit"); +} + +module_init(goodix_tools_init); +module_exit(goodix_tools_exit); + +MODULE_DESCRIPTION("Goodix tools Module"); +MODULE_AUTHOR("Goodix, Inc."); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/Makefile b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/Makefile new file mode 100644 index 000000000000..b82ae26d8dc2 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/Makefile @@ -0,0 +1,40 @@ +# test core code +# +ccflags-y += -I$(srctree)/drivers/input/touchscreen/normandy_unified_protocol + +obj-y += board_opr_interface_kernel.o +obj-y += public_fun.o +obj-y += simple_mem_manager_mach.o +obj-y += test_proc.o +obj-y += tp_additional_option.o +obj-y += tp_dev_control.o +obj-y += tp_item_permutation.o +obj-y += tp_normandy_control.o +obj-y += tp_open_test.o +obj-y += normandy_short_test.o +obj-y += tp_short_test.o +obj-y += tp_test_item_buf_mem.o +obj-y += tp_test_item_mem.o +obj-y += tp_version_test.o +obj-y += memory_override.o + +#comm +obj-y += crc_decrypt.o +obj-y += extra_tp_control.o +obj-y += generic_func.o +obj-y += save_test_data.o +obj-y += test_item_init.o +obj-y += test_order.o +obj-y += test_param_init.o + +# xml lib +obj-y += mxml-attr.o +obj-y += mxml-entity.o +obj-y += mxml-file.o +obj-y += mxml-get.o +obj-y += mxml-index.o +obj-y += mxml-node.o +obj-y += mxml-private.o +obj-y += mxml-search.o +obj-y += mxml-set.o +obj-y += mxml-string.o diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/board_opr_interface.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/board_opr_interface.h new file mode 100644 index 000000000000..acbf89d8f57c --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/board_opr_interface.h @@ -0,0 +1,123 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : board_opr_interface.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 08/23/2017 +* Description : board operation interface +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef BOARD_OPR_INTERFACE_H +#define BOARD_OPR_INTERFACE_H + +#include "user_test_type_def.h" +#include "tp_dev_def.h" +#include "res_inc.h" + +#include +#include "../goodix_ts_core.h" +#include +#include +#include +#include +/*#include */ +/*#include */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define L_MAX 2147483647 /*0x7FFFFFFF */ +#define L_MIN (-2147483647 - 1) /*-0x80000000*/ + +#define CONFIG_GOODIX_DEBUG +#ifdef CONFIG_GOODIX_DEBUG +#define board_print_debug(fmt, arg...) \ + pr_info("[GTP-DBG][%s:%d]" fmt "\n", __func__, __LINE__, ##arg) +#else +#define board_print_debug(fmt, arg...) \ + do { \ + } while (0) +#endif +#define board_print_error(fmt, arg...) \ + pr_err("[GTP-ERR][%s:%d]" fmt "\n", __func__, __LINE__, ##arg) +#define board_print_warning(fmt, arg...) \ + pr_info("[GTP-WARN][%s:%d]" fmt "\n", __func__, __LINE__, ##arg) +#define board_print_info(fmt, arg...) \ + pr_info("[GTP-INF][%s:%d]" fmt "\n", __func__, __LINE__, ##arg) +#define printf(fmt, arg...) \ + pr_info("[GTP-INF][%s:%d]" fmt "\n", __func__, __LINE__, ##arg) + +#define usleep(ms) msleep(ms / 1000) +#define EOF -1 +/*********************************str opr**********************************/ +extern char *strdup(const char *s); +extern int strtol(const char *nptr, char **endptr, int base); + +/*********************************mem opr**********************************/ +extern void *malloc(size_t size); +extern void free(void *ptr); +extern void *realloc(void *ptr, size_t size); +extern void *calloc(size_t n, size_t size); + +/*********************************adc opr**********************************/ +/*such 2 functions only used in arm test board*/ +extern u16 board_get_volt_value(PST_TP_DEV p_dev, u8 adc_id, u16 aver_len); +extern u32 board_get_avg_current(PST_TP_DEV p_dev, u32 cnt); + +/*********************************dac opr**********************************/ +/*such 2 functions only used in arm test board*/ +extern s32 board_set_power_volt(PST_TP_DEV p_dev, u16 volt, u16 aver_len, + u8 cnt); +extern s32 board_set_comm_volt(PST_TP_DEV p_dev, u16 volt, u16 aver_len, + u8 cnt); + +/*********************************gpio opr**********************************/ +/*such 2 functions only used in arm test board*/ +extern void board_gpio_mode_set(PST_TP_DEV p_dev, u8 gpio_type, u16 gpio_pin, + u8 gpio_mode); +extern void board_gpio_reset_bits(PST_TP_DEV p_dev, u8 gpio_type, u16 gpio_pin); +extern void board_gpio_set_bits(PST_TP_DEV p_dev, u8 gpio_type, u16 gpio_pin); + +/*********************************delay opr**********************************/ +extern void board_delay_ms(u16 ms); +extern void board_delay_s(u16 s); +extern void board_delay_us(u16 us); +extern void board_get_now_time(u8 *p_tim_buf, u8 *p_len); + +/*********************************communicate opr**********************************/ +extern s32 board_read_chip_reg(PST_TP_DEV p_dev, u16 addr, u8 *p_buf, + u16 buf_len); +extern s32 board_write_chip_reg(PST_TP_DEV p_dev, u16 addr, u8 *p_buf, + u16 buf_len); + +/*********************************platform debug**********************************/ + +/*********************************work mode**********************************/ +extern s32 board_enter_rawdata_mode(PST_TP_DEV p_dev); +extern s32 board_enter_coord_mode(PST_TP_DEV p_dev); +extern s32 board_enter_sleep_mode(PST_TP_DEV p_dev); +extern s32 board_enter_diffdata_mode(PST_TP_DEV p_dev); + +extern s32 board_get_rawdata(PST_TP_DEV p_dev, u16 time_out_ms, + u8 b_filter_data, ptr32 p_cur_data); +extern s32 board_get_diffdata(PST_TP_DEV p_dev, u16 time_out_ms, + u8 b_filter_data, ptr32 p_cur_data); + +/*********************************chip opr**********************************/ +extern s32 board_hard_reset_chip(PST_TP_DEV p_dev); +extern s32 board_chip_hid_opr(PST_TP_DEV p_dev, + s32 b_ena); /*use for hid protocol*/ +extern s32 board_disable_dev_status(PST_TP_DEV p_dev); +extern s32 board_recovery_dev_status(PST_TP_DEV p_dev); +extern s32 board_seek_dev_addr(PST_TP_DEV p_dev); +extern s32 board_max_trans_len(PST_TP_DEV p_dev); +extern s32 board_update_chip_fw(PST_TP_DEV p_dev, ptr32 p_cur_data); +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/board_opr_interface_kernel.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/board_opr_interface_kernel.c new file mode 100644 index 000000000000..30d3763d457a --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/board_opr_interface_kernel.c @@ -0,0 +1,691 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : board_opr_interface.cpp +* Author : +* Version : V1.0.0 +* Date : 08/23/2017 +* Description : board operation interface,you may change this file if you + use a new test platform +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE +#include "board_opr_interface.h" +#include "tp_dev_control.h" +#include "tp_open_test.h" +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* +* Function Name : board_delay_ms +* Description : delay milliseconds +* Input : u16 ms +* Output : none +* Return : void +*******************************************************************************/ +extern void board_delay_ms(u16 ms) +{ +#if WCE_CODE == 1 + +#else + usleep(ms * 1000); +#endif +} +/******************************************************************************* +* Function Name : board_delay_us +* Description : delay microseconds +* Input : u16 us +* Output : none +* Return : void +*******************************************************************************/ +extern void board_delay_us(u16 us) +{ +#if QNX_CODE == 1 + /*usleep(us);*/ +#elif ANDROID_CODE == 1 + +#endif +} + +/******************************************************************************* +* Function Name : board_delay_s +* Description : delay seconds +* Input : u16 s +* Output : none +* Return : void +*******************************************************************************/ +extern void board_delay_s(u16 s) +{ +#if ANDROID_CODE == 1 + +#elif QNX_CODE == 1 + +#endif +} + +/******************************************************************************* +* Function Name : seg_read_chip_reg +* Description : read chip reg segmentally +* Input : PST_TP_DEV p_dev + : u16 addr(address) + : u8* p_buf(data buffer) + : u16 buf_len(buffer length) +* Output : u8* p_buf +* Return : u8(0:have not handled 1:handled) +*******************************************************************************/ +static s32 seg_read_chip_reg(PST_TP_DEV p_dev, u16 addr, u8 *p_buf, u16 buf_len) +{ + struct device *dev; + struct goodix_ts_core *core_data; + struct goodix_ts_device *ts_dev; + const struct goodix_ts_hw_ops *hw_ops; + s32 ret = 1; + + u16 i = 0; + u16 pack_size = 255; + u16 code_len = buf_len; + u16 packages; + u32 send_len; + u16 start_addr, tmp_addr; + start_addr = addr; + tmp_addr = addr; + send_len = pack_size; + packages = code_len / pack_size + 1; + for (i = 0; i < packages; i++) { + if (send_len > code_len) { + send_len = code_len; + } + /*read code*/ + dev = (struct device *)p_dev->p_logic_dev; + core_data = dev_get_drvdata(dev); + ts_dev = core_data->ts_dev; + hw_ops = ts_dev->hw_ops; + ret = hw_ops->read_trans(ts_dev, tmp_addr, + (u8 *)&p_buf[tmp_addr - start_addr], + send_len); + if (ret < 0) + ret = 0; + else + ret = 1; + + if (ret == 0) + return 0; + tmp_addr += send_len; + code_len -= send_len; + if (code_len <= 0) { + break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : seg_write_chip_reg +* Description : write chip reg segmentally +* Input : PST_TP_DEV p_dev + : u16 addr(address) + : u8* p_buf(data buffer) + : u16 buf_len(buffer length) +* Output : u8* p_buf +* Return : u8(0:have not handled 1:handled) +*******************************************************************************/ +static s32 seg_write_chip_reg(PST_TP_DEV p_dev, u16 addr, u8 *p_buf, + u16 buf_len) +{ + struct device *dev; + struct goodix_ts_core *core_data; + struct goodix_ts_device *ts_dev; + const struct goodix_ts_hw_ops *hw_ops; + s32 ret = 1; + + u16 i = 0; + u16 pack_size = 255; + u16 code_len = buf_len; + u16 packages; + u32 write_len; + u16 start_addr, tmp_addr; + start_addr = addr; + tmp_addr = addr; + write_len = pack_size; + packages = code_len / pack_size + 1; + for (i = 0; i < packages; i++) { + if (write_len > code_len) { + write_len = code_len; + } + /*send code*/ + dev = (struct device *)p_dev->p_logic_dev; + core_data = dev_get_drvdata(dev); + ts_dev = core_data->ts_dev; + hw_ops = ts_dev->hw_ops; + ret = hw_ops->write_trans(ts_dev, tmp_addr, + (u8 *)&p_buf[tmp_addr - start_addr], + write_len); + if (ret < 0) { + ret = 0; + } else { + ret = 1; + } + + if (ret == 0) { + /*board_print_error("segment write code error!\n");*/ + return 0; + } + + tmp_addr += write_len; + code_len -= write_len; + if (code_len <= 0) { + break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : board_read_chip_reg +* Description : read data from module +* Input : PST_TP_DEV p_dev + : u16 addr(address) + : u8* p_buf(data buffer) + : u16 buf_len(buffer length) +* Output : u8* p_buf +* Return : u8(0:have not handled 1:handled) +*******************************************************************************/ +extern s32 board_read_chip_reg(PST_TP_DEV p_dev, u16 addr, u8 *p_buf, + u16 buf_len) +{ + return seg_read_chip_reg(p_dev, addr, p_buf, buf_len); +} +/******************************************************************************* +* Function Name : board_write_chip_reg +* Description : write data to module +* Input : PST_TP_DEV p_dev + : u16 addr(address) + : u8* p_buf(data buffer) + : u16 buf_len(buffer length) +* Output : none +* Return : u8(0:have not handled 1:handled) +*******************************************************************************/ +extern s32 board_write_chip_reg(PST_TP_DEV p_dev, u16 addr, u8 *p_buf, + u16 buf_len) +{ + return seg_write_chip_reg(p_dev, addr, p_buf, buf_len); +} + +/******************************************************************************* +* Function Name : board_hard_reset_chip +* Description : hard reset chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : u8(0:fail 1:ok) +*******************************************************************************/ +extern s32 board_hard_reset_chip(IN PST_TP_DEV p_dev) +{ + s32 ret = 0; + struct device *dev; + struct goodix_ts_core *core_data; + struct goodix_ts_device *ts_dev; + const struct goodix_ts_hw_ops *hw_ops; + dev = (struct device *)p_dev->p_logic_dev; + core_data = dev_get_drvdata(dev); + ts_dev = core_data->ts_dev; + hw_ops = ts_dev->hw_ops; + ret = hw_ops->reset(ts_dev); + if (ret < 0) { + ret = 0; + } else { + ret = 1; + } + return ret; +} + +/******************************************************************************* +* Function Name : board_disable_dev_status +* Description : disable esd ird ... +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : u8(0:fail 1:ok) +*******************************************************************************/ +extern s32 board_disable_dev_status(PST_TP_DEV p_dev) +{ + s32 ret = 1; + struct device *dev; + struct goodix_ts_core *core_data; + dev = (struct device *)p_dev->p_logic_dev; + core_data = dev_get_drvdata(dev); + /*disable esd*/ + goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL); + /*disable irq*/ + goodix_ts_irq_enable(core_data, false); + return ret; +} + +/******************************************************************************* +* Function Name : board_recovery_dev_status +* Description : recovey dev status(esd,irq) +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : u8(0:fail 1:ok) +*******************************************************************************/ +extern s32 board_recovery_dev_status(PST_TP_DEV p_dev) +{ + s32 ret = 1; + struct device *dev; + struct goodix_ts_core *core_data; + dev = (struct device *)p_dev->p_logic_dev; + core_data = dev_get_drvdata(dev); + + /*disable esd*/ + goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL); + /*disable irq*/ + goodix_ts_irq_enable(core_data, true); + return ret; +} + +/******************************************************************************* +* Function Name : board_enter_rawdata_mode +* Description : chip enter rawdata mode +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : u8(0:fail 1:ok) +*******************************************************************************/ +extern s32 board_enter_rawdata_mode(IN PST_TP_DEV p_dev) +{ + s32 ret = 0; + u8 i = 0; + u8 retry_cnt = 5; + board_delay_ms(5); + + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_write(p_dev, p_dev->cmd_set.rawdata_cmd.addr, + p_dev->cmd_set.rawdata_cmd.cmd_buf, + p_dev->cmd_set.rawdata_cmd.cmd_len); + if (1 == ret) { + break; + } + } + + board_delay_ms(18); + ret = clr_data_flag(p_dev); + return ret; +} + +/******************************************************************************* +* Function Name : board_enter_coord_mode +* Description : set chip enter coordinate mode +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : u8(0:fail 1:ok) +*******************************************************************************/ +extern s32 board_enter_coord_mode(IN PST_TP_DEV p_dev) +{ + s32 ret = 0; + u8 i = 0; + u8 retry_cnt = 5; + + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_write(p_dev, p_dev->cmd_set.coorddata_cmd.addr, + p_dev->cmd_set.coorddata_cmd.cmd_buf, + p_dev->cmd_set.coorddata_cmd.cmd_len); + if (1 == ret) { + break; + } + } + + board_delay_ms(18); + ret = clr_data_flag(p_dev); + return ret; +} + +/******************************************************************************* +* Function Name : board_enter_sleep_mode +* Description : set chip entering sleep mode +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : u8(0:fail 1:ok) +*******************************************************************************/ +extern s32 board_enter_sleep_mode(IN PST_TP_DEV p_dev) +{ + s32 ret = 0; + u8 retry_cnt = 3; + u8 i = 0; + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_write(p_dev, p_dev->cmd_set.sleep_cmd.addr, + p_dev->cmd_set.sleep_cmd.cmd_buf, + p_dev->cmd_set.sleep_cmd.cmd_len); + if (1 == ret) { + break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : board_enter_diffdata_mode +* Description : set chip entering diffdata mode +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : u8(0:fail 1:ok) +*******************************************************************************/ +extern s32 board_enter_diffdata_mode(IN PST_TP_DEV p_dev) +{ + return board_enter_rawdata_mode(p_dev); +} + +/******************************************************************************* +* Function Name : board_get_rawdata +* Description : board_get_rawdata +* Input : PST_TP_DEV p_dev(touch panel device) +* Input : u16 time_out_ms +* Output : ptr32 p_cur_data +* Return : u8(0:fail 1:ok) +*******************************************************************************/ +extern s32 board_get_rawdata(PST_TP_DEV p_dev, u16 time_out_ms, + u8 b_filter_data, ptr32 p_cur_data) +{ + s32 ret = 0; + u8 i = 0; + u8 retry_cnt = 3; + u8 data_size = 1; + PST_CUR_RAWDATA p_rawdata = (PST_CUR_RAWDATA)p_cur_data; + + if ((p_dev->chip_type == TP_NORMANDY) || + (p_dev->chip_type == TP_OSLO)) { + if (b_filter_data == 1) { + return 1; + } + + data_size = get_data_size(p_dev->rawdata_option); + for (i = 0; i < retry_cnt; i++) { + ret = sync_read_rawdata(p_dev->rawdata_addr, + p_rawdata->p_data_buf, + p_dev->rawdata_len * data_size); + if (ret >= 0) { + ret = 1; + break; + } + } + board_print_debug("rawdata buf len :%d!\n", + p_rawdata->data_len); + if (ret == 1) { + if ((p_dev->rawdata_option & _DATA_LARGE_ENDIAN) || + (p_dev->rawdata_option & _DATA_DRV_SEN_INVERT)) { + reshape_data(p_dev->rawdata_option, p_dev, + p_rawdata); + } + } + return ret; + } else { + return get_rawdata(p_dev, time_out_ms, b_filter_data, + p_rawdata); + } +} + +/******************************************************************************* +* Function Name : board_get_diffdata +* Description : board_get_diffdata +* Input : PST_TP_DEV p_dev(touch panel device) +* Input : u16 time_out_ms +* Output : ptr32 p_cur_data +* Return : u8(0:fail 1:ok) +*******************************************************************************/ +extern s32 board_get_diffdata(PST_TP_DEV p_dev, u16 time_out_ms, + u8 b_filter_data, ptr32 p_cur_data) +{ + s32 ret = 0; + u8 i = 0; + u8 retry_cnt = 3; + u8 data_size = 1; + PST_CUR_DIFFDATA p_diffdata = (PST_CUR_DIFFDATA)p_cur_data; + + if ((p_dev->chip_type == TP_NORMANDY) || + (p_dev->chip_type == TP_OSLO)) { + if (b_filter_data == 1) { + return 1; + } + + data_size = get_data_size(p_dev->diffdata_option); + for (i = 0; i < retry_cnt; i++) { + ret = sync_read_rawdata( + p_dev->diffdata_addr, p_diffdata->p_data_buf, + p_dev->diffdata_len * data_size); + if (ret > 0) { + ret = 1; + break; + } + } + if (ret == 1) { + if ((p_dev->diffdata_option & _DATA_LARGE_ENDIAN) || + (p_dev->diffdata_option & _DATA_DRV_SEN_INVERT)) { + reshape_data(p_dev->diffdata_option, p_dev, + p_diffdata); + } + } + return ret; + } else { + return get_diffdata(p_dev, time_out_ms, b_filter_data, + p_diffdata); + } +} + +/******************************************************************************* +* Function Name : board_hard_reset_chip +* Description : (use for hid protocol) +* Input : PST_TP_DEV p_dev(touch panel deice) +* Input : s32 b_ena(1:enable hid 0:disable hid) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 board_chip_hid_opr(PST_TP_DEV p_dev, s32 b_ena) +{ + s32 ret = 1; + s32 i = 0; + s32 retry_cnt = 3; + + if ((1 == b_ena && 0 == p_dev->hid_state) || + (0 == b_ena && 1 == p_dev->hid_state)) { + p_dev->hid_state = (p_dev->hid_state == 0) ? (1) : (0); + } else { + return 1; + } + + if (1 == b_ena) { + for (i = 0; i < retry_cnt; i++) { + ret = board_write_chip_reg( + p_dev, p_dev->cmd_set.hid_ena_cmd.addr, + p_dev->cmd_set.hid_ena_cmd.cmd_buf, + p_dev->cmd_set.hid_ena_cmd.cmd_len); + /* + cmd_buf[0] = 0xbb; + cmd_buf[1] = 0x00; + cmd_buf[2] = 0x45; + ret = board_write_chip_reg(p_dev, 0x8040,cmd_buf, 3); + */ + if (1 == ret) { + break; + } + } + } else if (0 == b_ena) { + for (i = 0; i < retry_cnt; i++) { + ret = board_write_chip_reg( + p_dev, p_dev->cmd_set.hid_dis_cmd.addr, + p_dev->cmd_set.hid_dis_cmd.cmd_buf, + p_dev->cmd_set.hid_dis_cmd.cmd_len); + /* + cmd_buf[0] = 0xaa; + cmd_buf[1] = 0x00; + cmd_buf[2] = 0x56; + ret = board_write_chip_reg(p_dev, 0x8040,cmd_buf, 3); + */ + if (1 == ret) { + break; + } + } + } + + if (0 == ret) { + board_print_error("%s\n", "send hid opr cmd fail!"); + } + return ret; +} +extern char *strdup(const char *s) +{ + size_t len = strlen(s) + 1; + void *new = malloc(len); + if (new == NULL) { + return NULL; + } + return (char *)memcpy(new, s, len); +} + +extern int strtol(const char *nptr, char **endptr, int base) +{ + const char *p = nptr; + int ret; + int ch; + int Overflow; + int sign = 0, flag, LimitRemainder; + /*delete space*/ + do { + ch = *p++; + } while (ch == ' '); + + if (ch == '-') { + sign = 1; + ch = *p++; + } else if (ch == '+') + ch = *p++; + if ((base == 0 || base == 16) && ch == '0' && + (*p == 'x' || *p == 'X')) { + ch = p[1]; + p += 2; + base = 16; + } + if (base == 0) + base = ch == '0' ? 8 : 10; + Overflow = sign ? -(u32)L_MIN : L_MAX; + LimitRemainder = Overflow % (u32)base; + Overflow /= (u32)base; + for (ret = 0, flag = 0;; ch = *p++) { + /*get target value*/ + if (ch >= '0' && ch <= '9') + ch -= '0'; + else if (ch >= 'A' && ch <= 'Z') + ch -= 'A' - 10; + else if (ch >= 'a' && ch <= 'z') + ch -= 'a' - 10; + else + break; + if (ch >= base) + break; + /*overflow*/ + if (flag < 0 || ret > Overflow || + (ret == Overflow && ch > LimitRemainder)) + flag = -1; + else { + flag = 1; + ret *= base; + ret += ch; + } + } + if (flag < 0) + ret = sign ? L_MIN : L_MAX; + else if (sign) + ret = -ret; + if (endptr != 0) + *endptr = (char *)(flag ? (p - 1) : nptr); + return ret; +} +/* +extern void* realloc(void* ptr, size_t size){ + void *new = NULL; + if (ptr == NULL) + return NULL; + if (size != 0){ + if (!(new == kmalloc(size, GFP_KERNEL))) + return NULL; + memcpy(new,ptr,strlen((const char*)ptr)); + kfree(ptr); + return new; + }else + return NULL; + +}*/ + +extern void *calloc(size_t n, size_t size) +{ + void *buf = NULL; + buf = malloc(n * size); + if (buf != NULL) + memset(buf, 0, n * size); + return buf; +} +/****************************************arm interface**************************************************/ +extern s32 board_get_exti_flag(PST_TP_DEV p_dev, u8 exti_id) +{ + return 1; +} +extern s32 board_clear_exti_flag(PST_TP_DEV p_dev, u8 exti_id) +{ + return 1; +} + +extern u16 board_get_volt_value(PST_TP_DEV p_dev, u8 adc_id, u16 aver_len) +{ + return 1; +} + +extern s32 board_set_power_volt(PST_TP_DEV p_dev, u16 volt, u16 aver_len, + u8 cnt) +{ + return 1; +} +extern s32 board_set_comm_volt(PST_TP_DEV p_dev, u16 volt, u16 aver_len, u8 cnt) +{ + return 1; +} + +extern void board_gpio_mode_set(PST_TP_DEV p_dev, u8 gpio_type, u16 gpio_pin, + u8 gpio_mode) +{ + ; +} +extern void board_gpio_reset_bits(PST_TP_DEV p_dev, u8 gpio_type, u16 gpio_pin) +{ + ; +} +extern void board_gpio_set_bits(PST_TP_DEV p_dev, u8 gpio_type, u16 gpio_pin) +{ + ; +} +extern s32 board_set_exti_on(PST_TP_DEV p_dev, u8 exti_id, u16 modle) +{ + return 1; +} +extern void board_get_now_time(u8 *p_tim_buf, u8 *p_len) +{ + ; +} +extern u32 board_get_avg_current(PST_TP_DEV p_dev, u32 cnt) +{ + return 1; +} + +extern s32 board_max_trans_len(PST_TP_DEV p_dev) +{ + return 1024; +} + +extern s32 board_seek_dev_addr(PST_TP_DEV p_dev) +{ + return 1; +} + +extern s32 board_update_chip_fw(PST_TP_DEV p_dev, ptr32 p_cur_data) +{ + return 0; +} +/****************************************arm interface end**************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/chip_ini.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/chip_ini.h new file mode 100644 index 000000000000..1c3dfadd72cb --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/chip_ini.h @@ -0,0 +1,70 @@ +/******************** (C) COPYRIGHT 2018 Goodix ******************** +* File Name : chip_ini.h +* Author : zhitao yang +* Version : V1.0.0 +* Date : 14/11/2018 +* Description : chip info +*******************************************************************************/ +#ifndef CHIP_INI_H +#define CHIP_INI_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tp_product_id_def.h" +#include "user_test_type_def.h" + +/*cfg*/ +#define CFG_START_ADDR 0x6F78 +#define CFG_LEN 690 + +#define SEN_MAX_NUM_IN_DIE 36 +#define DRV_MAX_NUM_IN_DIE 40 +#define MAX_SEN_NUM 36 +#define MAX_DRV_NUM 40 +#define MAX_KEY_NUM 4 + +/*cmd*/ +#define CMD_ADDR 0x6F68 + +/*rawdata*/ +#define DATA_ENDIAN 1 +#define DATA_INVERT 1 +#define RAWDATA_ADDR 0x8FA0 +#define RAW_UNIT_OF_BYTE 2 +#define RAW_SIGNED 1 +#define SYN_ADDR 0x4100 +#define SYN_MASK 0x80 + +#define MAP_DISABLE 0 + +u8 IC_NAME[] = "GT9886"; +u8 SEN_NUM_ADDR[] = "T1,10,0,7"; +u8 DRV_NUM_ADDR[] = "T1,14,0,7,T1,15,0,7"; + +u8 SEN_START_ADDR[] = "T2,2,0,7"; +u8 DRV_START_ADDR[] = "T2,38,0,7"; + +u8 KEY_START_ADDR[] = "T16,12,0,15"; +u8 SEN_AS_KEY_ADDR[] = "T16,2,3,3"; +u8 KEY_PORT_NUM[] = ""; +u8 KEY_EN[] = "T16,2,0,0"; +u8 HOPPING_EN[] = "T10,2,0,0"; + +/*channel map*/ +u8 DRV_MAP[] = { 46, 48, 49, 47, 45, 50, 56, 52, 51, 53, + 55, 54, 59, 64, 57, 60, 62, 58, 65, 63, + 61, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; +u8 SEN_MAP[] = { 32, 34, 35, 30, 31, 33, 27, 28, 29, 10, 25, 26, + 23, 13, 24, 12, 9, 11, 8, 7, 5, 6, 4, 3, + 2, 1, 0, 73, 75, 74, 39, 72, 40, 36, 37, 38 }; +/*cmd buf*/ +u8 RAW_CMD_BUF[] = { 0x01, 0x00, 0xff }; +u8 COOR_CMD_BUF[] = { 0x00, 0x00, 0x00 }; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/config.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/config.h new file mode 100644 index 000000000000..1e321045d260 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/config.h @@ -0,0 +1,81 @@ +/* + * Configuration file for Mini-XML, a small XML file parsing library. + * + * Copyright 2003-2017 by Michael R Sweet. + * Copyright (C) 2019 XiaoMi, Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Michael R Sweet and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "COPYING" + * which should have been included with this file. If this file is + * missing or damaged, see the license at: + * + * https://michaelrsweet.github.io/mxml + */ + +/* + * Beginning with VC2005, Microsoft breaks ISO C and POSIX conformance + * by deprecating a number of functions in the name of security, even + * when many of the affected functions are otherwise completely secure. + * The _CRT_SECURE_NO_DEPRECATE definition ensures that we won't get + * warnings from their use... + * + * Then Microsoft decided that they should ignore this in VC2008 and use + * yet another define (_CRT_SECURE_NO_WARNINGS) instead. Bastards. + */ + +#define _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_WARNINGS + +/* + * Include necessary headers... + */ + +#include +#include +#include +/*#include */ +#include "board_opr_interface.h" + +/* + * Microsoft also renames the POSIX functions to _name, and introduces + * a broken compatibility layer using the original names. As a result, + * random crashes can occur when, for example, strdup() allocates memory + * from a different heap than used by malloc() and free(). + * + * To avoid moronic problems like this, we #define the POSIX function + * names to the corresponding non-standard Microsoft names. + */ + +/* + * Version number... + */ + +#define MXML_VERSION "Mini-XML v2.11" +#define HAVE_LONG_LONG 1 +#define HAVE_SNPRINTF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_STRDUP 1 + +#ifndef HAVE_STRDUP +extern char *_mxml_strdup(const char *); +#define strdup _mxml_strdup +#endif /* !HAVE_STRDUP */ + +#ifndef HAVE_STRLCPY +extern size_t _mxml_strlcpy(char *, const char *, size_t); +#define strlcpy _mxml_strlcpy +#endif /* !HAVE_STRLCPY */ + +extern char *_mxml_strdupf(const char *, ...); +extern char *_mxml_vstrdupf(const char *, va_list); + +#ifndef HAVE_SNPRINTF +extern int _mxml_snprintf(char *, size_t, const char *, ...); +#define snprintf _mxml_snprintf +#endif /* !HAVE_SNPRINTF */ + +#ifndef HAVE_VSNPRINTF +extern int _mxml_vsnprintf(char *, size_t, const char *, va_list); +#define vsnprintf _mxml_vsnprintf +#endif /* !HAVE_VSNPRINTF */ diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/crc_decrypt.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/crc_decrypt.c new file mode 100644 index 000000000000..96dc961501aa --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/crc_decrypt.c @@ -0,0 +1,205 @@ +/******************** (C) COPYRIGHT 2018 Goodix ******************** +* File Name : crc_decrypt.cpp +* Author : +* Version : V1.0.0 +* Date : 26/03/2018 +* Description : decrypt file +*******************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#include "crc_decrypt.h" +#include "generic_func.h" +#include "board_opr_interface.h" +#include "simple_mem_manager.h" +#include +#include +#include "../goodix_ts_core.h" +const char default_order_name[] = "goodix_gt9886_limit_f11.tporder"; + +/******************************************************************************* +* Function Name : decrypt_reflect +* Description : +* Input : u32 ref + : s8 ch +* Output : +* Return : s32(0:Fail 1:ok) +*******************************************************************************/ +extern u32 decrypt_reflect(u32 ref, s8 ch) +{ + u32 value = 0; + s32 i; + for (i = 1; i < (ch + 1); i++) { + if (ref & 1) + value |= 1 << (ch - i); + ref >>= 1; + } + return value; +} + +/******************************************************************************* +* Function Name : decrypt_init_crc32_table +* Description : init crc32 table +* Input : u32 crc32_table[] +* Output : +* Return : s32(0:Fail 1:ok) +*******************************************************************************/ +extern s32 decrypt_init_crc32_table(u32 *crc32_table) +{ + u32 crc, temp; + u32 t1, t2; + u32 flag; + u32 ulPolynomial = 0x04c11db7; + s32 i, j; + for (i = 0; i <= 0xFF; i++) { + temp = decrypt_reflect(i, 8); + crc32_table[i] = temp << 24; + for (j = 0; j < 8; j++) { + flag = crc32_table[i] & 0x80000000; + t1 = (crc32_table[i] << 1); + if (flag == 0) + t2 = 0; + else + t2 = ulPolynomial; + crc32_table[i] = t1 ^ t2; + } + crc = crc32_table[i]; + crc32_table[i] = decrypt_reflect(crc32_table[i], 32); + } + return 1; +} + +/******************************************************************************* +* Function Name : decrypt_generate_crc32 +* Description : generate crc32 code +* Input : u32 crc32_table[] + : u8* buf + : u32 len +* Output : +* Return : u32() +*******************************************************************************/ +extern u32 decrypt_generate_crc32(u32 *crc32_table, u8 *buf, u32 len) +{ + u32 old_crc32 = 0xFFFFFFFF; + u32 i = 0; + for (i = 0; i < len; ++i) { + u32 t = (old_crc32 ^ buf[i]) & 0xFF; + old_crc32 = ((old_crc32 >> 8) & 0xFFFFFF) ^ crc32_table[t]; + } + /*old_crc32 = ~old_crc32;*/ + return (~old_crc32) & 0xffffffff; +} + +/******************************************************************************* +* Function Name : read_file_decoder +* Description : read file and decode file content +* Input : PST_TP_DEV p_tp_dev + : s8* ver_date + : s8* file_content +* Output : +* Return : s32(0:Fail 1:ok) +*******************************************************************************/ +extern s32 read_file_decoder(PST_TP_DEV p_tp_dev, s8 **ver_date, + s8 **file_content) +{ + s32 ret = 0; + s32 i = 0; + u32 file_len = 0; + u32 index_ver = 0; + u32 index_cont = 0; + s8 *cont_buf = NULL; + u32 crc_calc = 0; + u32 crc_origin = 0; + u32 crc32_table[256]; + char order_name[64]; + const struct firmware *firmware; + struct device *dev; + struct goodix_ts_board_data *ts_bdata = board_data(goodix_core_data); + + dev = (struct device *)p_tp_dev->p_logic_dev; + + if (ts_bdata && ts_bdata->limit_name) + strlcpy(order_name, ts_bdata->limit_name, sizeof(order_name)); + else + strlcpy(order_name, default_order_name, sizeof(order_name)); + /*read content*/ + for (i = 0; i < 2; i++) { + ret = request_firmware(&firmware, order_name, dev); + if (ret < 0) { + board_delay_ms(1); + } else { + ret = 1; + break; + } + } + if (i >= 2) { + board_print_error("request firmware error:%s\n", order_name); + ret = 0; + goto DECODE_EXIT; + } + + file_len = firmware->size; + board_print_debug("read file len:%d\n", file_len); + board_print_debug("malloc memory [crc]1!"); + /*malloc memory*/ + ret = alloc_mem_in_heap((void **)&cont_buf, file_len + 1); + if (cont_buf == NULL) { + board_print_error("malloc buf error!"); + } + ret = alloc_mem_in_heap((void **)ver_date, VECTOR_BYTE_LEN + 1); + ret = alloc_mem_in_heap((void **)file_content, file_len + 1); + if ((cont_buf == NULL) || (*ver_date == NULL) || + (*file_content == NULL)) { + board_print_error("cont buf malloc error!\n"); + release_firmware(firmware); + firmware = NULL; + return 0; + } + /*init*/ + cont_buf[file_len] = '\0'; + (*ver_date)[VECTOR_BYTE_LEN] = '\0'; + (*file_content)[file_len] = '\0'; + memcpy(cont_buf, firmware->data, file_len); + release_firmware(firmware); + firmware = NULL; + decrypt_init_crc32_table(crc32_table); + for (i = 0; i < 256; i++) { + crc32_table[i] &= 0xffffffff; + } + + crc_calc = decrypt_generate_crc32(crc32_table, (u8 *)cont_buf, + file_len - CRC_BYTE_LEN); + crc_origin += (u8)cont_buf[file_len - 1]; + crc_origin <<= 8; + crc_origin += (u8)cont_buf[file_len - 2]; + crc_origin <<= 8; + crc_origin += (u8)cont_buf[file_len - 3]; + crc_origin <<= 8; + crc_origin += (u8)cont_buf[file_len - 4]; + crc_origin = crc_origin & 0xffffffff; + if (crc_calc != crc_origin) { + board_print_error("crc check error!crc_calc=%d,crc_origin=%d\n", + crc_calc, crc_origin); + ret = 0; + goto DECODE_EXIT; + } + board_print_debug("crc check pass!crc_calc=%d,crc_origin=%d\n", + crc_calc, crc_origin); + for (i = 0; i < file_len - CRC_BYTE_LEN; i++) { + if (i < VECTOR_BYTE_LEN) { + (*ver_date)[index_ver++] = ((cont_buf[i] >> 4) & 0xFF); + (*ver_date)[index_ver++] = (cont_buf[i] & 0xFF); + } else { + (*file_content)[index_cont++] = (u8)(cont_buf[i] - 1); + } + } + ret = 1; +DECODE_EXIT: + free_mem_in_heap(cont_buf); + return ret; +} + +#ifdef __cplusplus +} +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/crc_decrypt.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/crc_decrypt.h new file mode 100644 index 000000000000..2dd27f4c673f --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/crc_decrypt.h @@ -0,0 +1,32 @@ +/******************** (C) COPYRIGHT 2018 Goodix ******************** +* File Name : crc_decrypt.h +* Author : +* Version : V1.0.0 +* Date : 26/03/2018 +* Description : decrypt file +*******************************************************************************/ +#ifndef CRC_DECRYPT_H +#define CRC_DECRYPT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "user_test_type_def.h" +#include "board_opr_interface.h" + +#define CRC_BYTE_LEN 4 +#define VECTOR_BYTE_LEN 5 + +/*************************************Public methods start********************************************/ +extern u32 decrypt_reflect(u32 ref, s8 ch); +extern s32 decrypt_init_crc32_table(u32 *crc32_table); +extern u32 decrypt_generate_crc32(u32 *crc32_table, u8 *buf, u32 len); +extern s32 read_file_decoder(PST_TP_DEV p_tp_dev, s8 **ver_date, + s8 **file_content); +/*************************************Public methods end********************************************/ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/custom_info_def.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/custom_info_def.h new file mode 100644 index 000000000000..596cfa49bab1 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/custom_info_def.h @@ -0,0 +1,30 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : custom_info_def.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : define custom info struct +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef CUSTOM_INFO_DEF_H +#define CUSTOM_INFO_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "user_test_type_def.h" + +#define CUSTOM_INFO_DESC_MAX_LEN 20 +typedef struct CUSTOM_INFO_BYTE { + u8 index; + u8 value; + u8 desc[CUSTOM_INFO_DESC_MAX_LEN]; +} ST_CUSTOM_INFO_BYTE, *PST_CUSTOM_INFO_BYTE; + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/extra_tp_control.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/extra_tp_control.c new file mode 100644 index 000000000000..dff5b8ccc977 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/extra_tp_control.c @@ -0,0 +1,108 @@ + +/******************** (C) COPYRIGHT 2018 Goodix ******************** +* File Name : extra_tp_control.cpp +* Author : yangzhitao +* Version : V1.0.0 +* Date : 30/03/2018 +* Description : tp control func +*******************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#include "extra_tp_control.h" +#include "tp_dev_control.h" +#include "tp_normandy_control.h" +#include "generic_func.h" +#include + +/******************************************************************************* +* Function Name : read_sensor_id +* Description : read sensor id +* Input : PST_TP_DEV p_tp_dev + : u8* sensor_id +* Output : u8* sensor_id +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 read_sensor_id(PST_TP_DEV p_tp_dev, u8 *sensor_id) +{ + s32 ret = 0; + u8 tmp_id[1]; + u16 sen_id_addr; + + switch (p_tp_dev->chip_type) { + case TP_NORMANDY: { + sen_id_addr = 0x4541; + break; + } + default: { + sen_id_addr = 0x814A; + break; + } + } + board_print_debug("sensor id addr:0x%04x!\n", sen_id_addr); + ret = chip_reg_read(p_tp_dev, sen_id_addr, sensor_id, 1); + ret = chip_reg_read(p_tp_dev, sen_id_addr, tmp_id, 1); + if (sensor_id[0] != tmp_id[0]) { + ret = chip_reg_read(p_tp_dev, sen_id_addr, sensor_id, 1); + ret = chip_reg_read(p_tp_dev, sen_id_addr, tmp_id, 1); + if (sensor_id[0] != tmp_id[0]) { + board_print_error("sensor id is not equal!\n"); + return 0; + } + } + sensor_id[0] &= 0x0F; + return ret; +} + +/******************************************************************************* +* Function Name : read_chip_original_cfg +* Description : read chip original config +* Input : PST_TP_DEV p_tp_dev +* Output : none +* Return : s32(0:Fail >0:read config len) +*******************************************************************************/ +extern s32 read_chip_original_cfg(PST_TP_DEV p_tp_dev) +{ + s32 ret = 0; + switch (p_tp_dev->chip_type) { + case TP_NORMANDY: { + ret = read_cfg_arr(p_tp_dev, p_tp_dev->cfg, 0); + p_tp_dev->cfg_len = ret; + /*updata status flag*/ + p_tp_dev->cfg[1] |= 0x01; + break; + } + default: { + ret = read_cfg_arr(p_tp_dev, p_tp_dev->cfg, p_tp_dev->cfg_len); + break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : update_cfg_checksum +* Description : update test config checksum +* Input : PST_TP_DEV p_tp_dev + : u8* test_cfg +* Output : +* Return : void +*******************************************************************************/ +extern void update_cfg_checksum(PST_TP_DEV p_tp_dev, u8 *test_cfg, u16 len) +{ + switch (p_tp_dev->chip_type) { + case TP_NORMANDY: + case TP_OSLO: { + normandy_cfg_update_chksum(test_cfg, len); + break; + } + default: { + break; + } + } +} + +#ifdef __cplusplus +} +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/extra_tp_control.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/extra_tp_control.h new file mode 100644 index 000000000000..d9bc87efc4f5 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/extra_tp_control.h @@ -0,0 +1,26 @@ +/******************** (C) COPYRIGHT 2018 Goodix ******************** +* File Name : extra_tp_control.h +* Author : +* Version : V1.0.0 +* Date : 30/03/2018 +* Description : tp control func +*******************************************************************************/ +#ifndef EXTRA_TP_CONTROL_H +#define EXTRA_TP_CONTROL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tp_dev_def.h" + +/*************************************Public methods start********************************************/ +extern s32 read_sensor_id(PST_TP_DEV p_tp_dev, u8 *sensor_id); +extern s32 read_chip_original_cfg(PST_TP_DEV p_tp_dev); +extern void update_cfg_checksum(PST_TP_DEV p_tp_dev, u8 *test_cfg, u16 len); +/*************************************Public methods end********************************************/ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/generic_func.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/generic_func.c new file mode 100644 index 000000000000..a43064ffd622 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/generic_func.c @@ -0,0 +1,250 @@ +/******************** (C) COPYRIGHT 2017 Goodix ******************** +* File Name : generic_func.cpp +* Author : +* Version : V1.0.0 +* Date : 07/03/2017 +* Description : init test param interface +*******************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#include "generic_func.h" +#include "board_opr_interface.h" +#include "simple_mem_manager.h" +#include + +static s32 test_res_all; +static u8 show_detail_info; + +/******************************************************************************* +* Function Name : set_detail_info_flag +* Description : set detail test info flag +* Input : u8 flag +* Output : none +* Return : none +*******************************************************************************/ +extern void set_detail_info_flag(u8 flag) +{ + show_detail_info = flag; +} +/******************************************************************************* +* Function Name : get_detail_info_flag +* Description : get detail test info flag +* Input : none +* Output : none +* Return : u8(1:save reult in csv file 0:no need save) +*******************************************************************************/ +extern u8 get_detail_info_flag(void) +{ + return show_detail_info; +} + +/******************************************************************************* +* Function Name : getrid_space +* Description : get rid of space +* Input : s8* data + : s32 len +* Output : none +* Return : s32 (length of data) +*******************************************************************************/ +extern s32 getrid_space(s8 *data, s32 len) +{ + u8 *buf = NULL; + s32 i; + u32 count = 0; + + if (alloc_mem_in_heap((void **)&buf, len + 5) == 0) + return (s32)(-1); + for (i = 0; i < len; i++) { + if (data[i] == ' ' || data[i] == '\r' || data[i] == '\n') { + continue; + } + buf[count++] = data[i]; + } + buf[count++] = '\0'; + memcpy(data, buf, count); + free_mem_in_heap(buf); + return count; +} + +extern int atoi(const char *str) +{ + int value = 0; + int sign = 1; + if (str == NULL) + return 0; + while (*str == ' ') { + str++; + } + if (*str == '-') { + sign = -1; + } + + if (*str == '-' || *str == '+') { + str++; + } + /*str to int*/ + while (*str >= '0' && *str <= '9') { + value = value * 10 + *str - '0'; + str++; + } + value = value * sign; + return value; +} +/******************************************************************************* +* Function Name : atohex +* Description : alpha to hex +* Input : s8* buf + : u16 len +* Output : +* Return : u16(0:Fail others:value) +*******************************************************************************/ +extern u16 atohex(u8 *buf, u16 len) +{ + u16 value = 0; + u8 data[10]; + u8 data_len = 0; + u8 i = 0; + if (len == 1) { + data[0] = '0'; + data[1] = buf[0]; + data_len = 2; + } + + if (len >= 2) { + if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) { + for (i = 2; i < len; i++) { + data[data_len] = buf[i]; + data_len++; + } + } else { + for (i = 0; i < len; i++) { + data[data_len] = buf[i]; + data_len++; + } + } + } + + for (i = 0; i < data_len; i++) { + if (HEX(data[i])) { + value = value << 4; + if (data[i] >= '0' && data[i] <= '9') { + value |= (data[i] - '0'); + } else if (data[i] >= 'A' && data[i] <= 'F') { + value |= (data[i] - 'A' + 10); + } else if (data[i] >= 'a' && data[i] <= 'f') { + value |= (data[i] - 'a' + 10); + } + } else { + return 0; + board_print_error("HEX string is illegal!\n"); + } + } + return value; +} + +/******************************************************************************* +* Function Name : decstr_to_array +* Description : dec string to integer array(Only use for one byte) +* Input : u8* tmp_value +* Input : u8* txt +* Input : s32 len(max array_value length) +* Output : +* Return : s32(array len) +*******************************************************************************/ +extern s32 decstr_to_array(u8 *tmp_value, u8 *text, s32 len) +{ + s32 i = 0; + u8 *field = NULL; + + field = (u8 *)strsep((char **)&tmp_value, ","); + while (field != NULL) { + text[i] = atoi((const char *)field); + i++; + field = (u8 *)strsep((char **)&tmp_value, ","); + if (i >= len) { + break; + } + } + return i; +} + +/******************************************************************************* +* Function Name : hexstr_to_array +* Description : hex string to integer array +* Input : u8* array_value + : s8* str_param + : s32 len +* Output : +* Return : s32(array len) +*******************************************************************************/ +extern s32 hexstr_to_array(u8 *array_value, s8 *str_param, s32 len) +{ + s32 i = 0; + s32 data_len = 0; + data_len = getrid_space(str_param, strlen((cstr)str_param)); + for (i = 0; i < (data_len + 1) / 5; i++) { + if (i >= len) { + break; + } + array_value[i] = (u8)atohex((u8 *)&str_param[i * 5], 4); + } + return i; +} + +/******************************************************************************* +* Function Name : str_to_int +* Description : string to integer +* Input : s8* data +* Output : +* Return : s32(value) +*******************************************************************************/ +extern s32 str_to_int(s8 *data) +{ + s32 i = 0; + s32 data_len = 0; + data_len = getrid_space(data, strlen((cstr)data)); + i = atoi((cstr)data); + return i; +} + +/******************************************************************************* +* Function Name : init_test_res +* Description : init test result +* Input : none +* Output : none +* Return : s32(test result) +*******************************************************************************/ +extern void init_test_res(void) +{ + test_res_all = 0; +} + +/******************************************************************************* +* Function Name : get_test_res +* Description : get test result +* Input : none +* Output : none +* Return : s32(test result) +*******************************************************************************/ +extern s32 get_test_res(void) +{ + return test_res_all; +} + +/******************************************************************************* +* Function Name : modify_test_result +* Description : modify test result +* Input : none +* Output : none +* Return : s32(test result) +*******************************************************************************/ +extern void modify_test_result(s32 test_res) +{ + test_res_all |= test_res; +} + +#ifdef __cplusplus +} +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/generic_func.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/generic_func.h new file mode 100644 index 000000000000..f271f6d0f021 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/generic_func.h @@ -0,0 +1,65 @@ +/******************** (C) COPYRIGHT 2017 Goodix ******************** +* File Name : generic_func +* Author : +* Version : V1.0.0 +* Date : 07/03/2017 +* Description : init test param interface +*******************************************************************************/ +#ifndef GENERIC_FUNC_H +#define GENERIC_FUNC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "user_test_type_def.h" + +#include +#include +#include + +#define LIB_VERSION \ + "Goodix Touch Panel Mutiple Production Test Core Version 1.0.2" +#define RESULT_LOG_VERSION "GTLib01.00.0000.01" +#define MAX_BUFFER_SIZE 15000 +#define PATH_LEN 250 +#define HEX(a) \ + ((a >= '0' && a <= '9') || (a >= 'A' && a <= 'F') || \ + (a >= 'a' && a <= 'f')) + +/*---------------------------------LOG DEFINE---------------------------------------*/ +#define BOARD_PRINT(fmt, arg...) \ + do { \ + if (get_detail_info_flag()) { \ + board_print_info(fmt, ##arg); \ + } else { \ + board_print_debug(fmt, ##arg); \ + } \ + } while (0) + +/**********************************operator file*************************************/ + +/*************************************Public methods start********************************************/ +extern u16 atohex(u8 *buf, u16 len); +extern s32 getrid_space(s8 *data, s32 len); +extern s32 hexstr_to_array(u8 *array_value, s8 *str_param, s32 len); +extern s32 str_to_int(s8 *dat); +extern int atoi(const char *str); +extern s32 decstr_to_array(u8 *tmp_value, u8 *text, s32 len); + +/*get test result value*/ +extern s32 get_test_res(void); +/*add the result of test item*/ +extern void modify_test_result(s32 test_res); +extern void init_test_res(void); + +/*set/get detail info flag*/ +extern void set_detail_info_flag(u8 flag); +extern u8 get_detail_info_flag(void); + +/*************************************Public methods start********************************************/ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/memory_override.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/memory_override.c new file mode 100644 index 000000000000..e45d34e88d38 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/memory_override.c @@ -0,0 +1,126 @@ +#include +#include +#include /* for list_head */ +#include +#include +#include "board_opr_interface.h" + +typedef struct memblock_s { + struct list_head list; + void *ptr; + size_t size; +} memblock_t; + +/* +* The list of memory blocks (one simple list) +*/ +static LIST_HEAD(memblock_list); +/*static rwlock_t memblock_lock = RW_LOCK_UNLOCKED;*/ +static DEFINE_RWLOCK(memblock_lock); + +static int memblock_add(void *ptr, size_t size) +{ + memblock_t *m; + m = kmalloc(sizeof(memblock_t), GFP_KERNEL); + if (!m) + return -ENOMEM; + m->ptr = ptr; + m->size = size; + + write_lock(&memblock_lock); + list_add(&m->list, &memblock_list); + write_unlock(&memblock_lock); + return 0; +} + +static void memblock_del(memblock_t *m) +{ + write_lock(&memblock_lock); + list_del(&m->list); + write_unlock(&memblock_lock); + kfree(m); +} + +static memblock_t *memblock_get(void *ptr) +{ + struct list_head *l; + memblock_t *m; + + read_lock(&memblock_lock); + list_for_each(l, &memblock_list) { + m = list_entry(l, memblock_t, list); + if (m->ptr == ptr) { + /* HIT */ + read_unlock(&memblock_lock); + return m; + } + } + read_unlock(&memblock_lock); + return NULL; +} + +void *malloc(size_t size) +{ + void *ptr; + ptr = kmalloc(size, GFP_KERNEL); + if (!ptr) + return NULL; + if (memblock_add(ptr, size)) { + kfree(ptr); + return NULL; + } + return ptr; +} + +void free(void *ptr) +{ + memblock_t *m; + if (!ptr) + return; + m = memblock_get(ptr); + if (!m) { + printk(KERN_ERR "bug: free non-exist memory\n"); + return; + } + memblock_del(m); + kfree(ptr); +} + +void *realloc(void *ptr, size_t size) +{ + memblock_t *m; + void *new = NULL; + + if (ptr) { + m = memblock_get(ptr); + if (!m) { + printk(KERN_ERR "bug: realloc non-exist memory\n"); + return NULL; + } + if (size == m->size) + return ptr; + if (size != 0) { + new = kmalloc(size, GFP_KERNEL); + if (!new) + return NULL; + memmove(new, ptr, m->size); + if (memblock_add(new, size)) { + kfree(new); + return NULL; + } + } + memblock_del(m); + kfree(ptr); + } else { + if (size != 0) { + new = kmalloc(size, GFP_KERNEL); + if (!new) + return NULL; + if (memblock_add(new, size)) { + kfree(new); + return NULL; + } + } + } + return new; +} diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-attr.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-attr.c new file mode 100644 index 000000000000..396be9765217 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-attr.c @@ -0,0 +1,251 @@ +/* + * Attribute support code for Mini-XML, a small XML file parsing library. + * + * Copyright 2003-2017 by Michael R Sweet. + * Copyright (C) 2019 XiaoMi, Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Michael R Sweet and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "COPYING" + * which should have been included with this file. If this file is + * missing or damaged, see the license at: + * + * https://michaelrsweet.github.io/mxml + */ + +/* + * Include necessary headers... + */ + +#include "config.h" +#include "mxml.h" + +/* + * Local functions... + */ + +static int mxml_set_attr(mxml_node_t *node, const char *name, char *value); + +/* + * 'mxmlElementDeleteAttr()' - Delete an attribute. + * + * @since Mini-XML 2.4@ + */ + +void mxmlElementDeleteAttr(mxml_node_t *node, /* I - Element */ + const char *name) +{ /* I - Attribute name */ + int i; /* Looping var */ + mxml_attr_t *attr; /* Cirrent attribute */ + + /* Range check input */ + if (!node || node->type != MXML_ELEMENT || !name) + return; + + /* Look for the attribute */ + for (i = node->value.element.num_attrs, + attr = node->value.element.attrs; + i > 0; i--, attr++) { + if (!strcmp(attr->name, name)) { + /* Delete this attribute...*/ + free(attr->name); + free(attr->value); + i--; + if (i > 0) + memmove(attr, attr + 1, + i * sizeof(mxml_attr_t)); + node->value.element.num_attrs--; + if (node->value.element.num_attrs == 0) + free(node->value.element.attrs); + return; + } + } +} + +/* + * 'mxmlElementGetAttr()' - Get an attribute. + * + * This function returns @code NULL@ if the node is not an element or the + * named attribute does not exist. + */ + +const char * /* O - Attribute value or @code NULL@ */ +mxmlElementGetAttr(mxml_node_t *node, /* I - Element node */ + const char *name) +{ /* I - Name of attribute */ + int i; /* Looping var */ + mxml_attr_t *attr; /* Cirrent attribute */ + + /* Range check input... */ + + if (!node || node->type != MXML_ELEMENT || !name) + return NULL; + /* Look for the attribute...*/ + + for (i = node->value.element.num_attrs, + attr = node->value.element.attrs; + i > 0; i--, attr++) { + if (!strcmp(attr->name, name)) { + return attr->value; + } + } + + /* Didn't find attribute, so return NULL... */ + return NULL; +} + +/* + * 'mxmlElementGetAttrByIndex()' - Get an element attribute by index. + * + * The index ("idx") is 0-based. @code NULL@ is returned if the specified index + * is out of range. + * + * @since Mini-XML 2.11@ + */ + +const char * /* O - Attribute value */ +mxmlElementGetAttrByIndex(mxml_node_t *node, /* I - Node */ + int idx, /* I - Attribute index, starting at 0 */ + const char **name) +{ /* O - Attribute name */ + if (!node || node->type != MXML_ELEMENT || idx < 0 || + idx >= node->value.element.num_attrs) + return NULL; + + if (name) + *name = node->value.element.attrs[idx].name; + return node->value.element.attrs[idx].value; +} + +/* + * 'mxmlElementGetAttrCount()' - Get the number of element attributes. + * + * @since Mini-XML 2.11@ + */ + +int mxmlElementGetAttrCount(/* O - Number of attributes */ + mxml_node_t *node) +{ /* I - Node */ + if (node && node->type == MXML_ELEMENT) + return node->value.element.num_attrs; + else + return 0; +} + +/* + * 'mxmlElementSetAttr()' - Set an attribute. + * + * If the named attribute already exists, the value of the attribute + * is replaced by the new string value. The string value is copied + * into the element node. This function does nothing if the node is + * not an element. + */ + +void mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */ + const char *name, /* I - Name of attribute */ + const char *value) +{ /* I - Attribute value */ + char *valuec; /* Copy of value */ + + /* Range check input... */ + + if (!node || node->type != MXML_ELEMENT || !name) + return; + if (value) + valuec = strdup(value); + else + valuec = NULL; + if (mxml_set_attr(node, name, valuec)) + free(valuec); +} + +/* + * 'mxmlElementSetAttrf()' - Set an attribute with a formatted value. + * + * If the named attribute already exists, the value of the attribute + * is replaced by the new formatted string. The formatted string value is + * copied into the element node. This function does nothing if the node + * is not an element. + * + * @since Mini-XML 2.3@ + */ + +void mxmlElementSetAttrf( + mxml_node_t *node, /* I - Element node */ + const char *name, /* I - Name of attribute */ + const char *format, /* I - Printf-style attribute value */ + ...) +{ /* I - Additional arguments as needed */ + va_list ap; /* Argument pointer */ + char *value; /* Value */ + + /* Range check input... */ + if (!node || node->type != MXML_ELEMENT || !name || !format) + return; + + /* Format the value... */ + + va_start(ap, format); + value = _mxml_vstrdupf(format, ap); + va_end(ap); + + if (!value) + mxml_error( + "Unable to allocate memory for attribute '%s' in element %s!", + name, node->value.element.name); + else if (mxml_set_attr(node, name, value)) + free(value); +} + +/* + * 'mxml_set_attr()' - Set or add an attribute name/value pair. + */ +/* O - 0 on success, -1 on failure */ +static int mxml_set_attr(mxml_node_t *node, /* I - Element node */ + const char *name, /* I - Attribute name */ + char *value) +{ /* I - Attribute value */ + int i; /* Looping var */ + mxml_attr_t *attr; /* New attribute */ + + /* Look for the attribute... */ + + for (i = node->value.element.num_attrs, + attr = node->value.element.attrs; + i > 0; i--, attr++) + if (!strcmp(attr->name, name)) { + /* Free the old value as needed... */ + if (attr->value) + free(attr->value); + attr->value = value; + return 0; + } + /* Add a new attribute... */ + + if (node->value.element.num_attrs == 0) + attr = malloc(sizeof(mxml_attr_t)); + else + attr = realloc(node->value.element.attrs, + (node->value.element.num_attrs + 1) * + sizeof(mxml_attr_t)); + + if (!attr) { + mxml_error( + "Unable to allocate memory for attribute '%s' in element %s!", + name, node->value.element.name); + return (-1); + } + + node->value.element.attrs = attr; + attr += node->value.element.num_attrs; + attr->name = strdup(name); + if (attr->name == NULL) { + mxml_error( + "Unable to allocate memory for attribute '%s' in element %s!", + name, node->value.element.name); + return (-1); + } + attr->value = value; + node->value.element.num_attrs++; + return 0; +} diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-entity.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-entity.c new file mode 100644 index 000000000000..1c1e6e07e929 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-entity.c @@ -0,0 +1,246 @@ +/* + * Character entity support code for Mini-XML, a small XML file parsing library. + * + * Copyright 2003-2017 by Michael R Sweet. + * Copyright (C) 2019 XiaoMi, Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Michael R Sweet and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "COPYING" + * which should have been included with this file. If this file is + * missing or damaged, see the license at: + * + * https://michaelrsweet.github.io/mxml + */ + +/* + * Include necessary headers... + */ + +#include "mxml-private.h" + +/* + * 'mxmlEntityAddCallback()' - Add a callback to convert entities to Unicode. + */ +/* O - 0 on success, -1 on failure */ +int mxmlEntityAddCallback(mxml_entity_cb_t cb) +{ /* I - Callback function to add */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + if (global->num_entity_cbs < + (int)(sizeof(global->entity_cbs) / sizeof(global->entity_cbs[0]))) { + global->entity_cbs[global->num_entity_cbs] = cb; + global->num_entity_cbs++; + + return 0; + } else { + mxml_error("Unable to add entity callback!"); + return (-1); + } +} + +/* + * 'mxmlEntityGetName()' - Get the name that corresponds to the character value. + * + * If val does not need to be represented by a named entity, @code NULL@ is returned. + */ + +const char * /* O - Entity name or @code NULL@ */ +mxmlEntityGetName(int val) +{ /* I - Character value */ + switch (val) { + case '&': + return "amp"; + + case '<': + return "lt"; + + case '>': + return "gt"; + + case '\"': + return "quot"; + + default: + return NULL; + } +} + +/* + * 'mxmlEntityGetValue()' - Get the character corresponding to a named entity. + * + * The entity name can also be a numeric constant. -1 is returned if the + * name is not known. + */ +/* O - Character value or -1 on error */ +int mxmlEntityGetValue(const char *name) +{ /* I - Entity name */ + int i; /* Looping var */ + int ch; /* Character value */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + for (i = 0; i < global->num_entity_cbs; i++) { + ch = (global->entity_cbs[i])(name); + if (ch >= 0) + return ch; + } + return (int)(-1); +} + +/* + * 'mxmlEntityRemoveCallback()' - Remove a callback. + */ + +void mxmlEntityRemoveCallback(mxml_entity_cb_t cb) +{ /* I - Callback function to remove */ + int i; /* Looping var */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + for (i = 0; i < global->num_entity_cbs; i++) + if (cb == global->entity_cbs[i]) { + /* Remove the callback... */ + global->num_entity_cbs--; + if (i < global->num_entity_cbs) + memmove(global->entity_cbs + i, + global->entity_cbs + i + 1, + (global->num_entity_cbs - i) * + sizeof(global->entity_cbs[0])); + return; + } +} + +/* + * '_mxml_entity_cb()' - Lookup standard (X)HTML entities. + */ + +int _mxml_entity_cb(const char *name) /* O - Unicode value or -1 */ +{ /* I - Entity name */ + int diff; /* Difference between names */ + int curent; /* Current entity in search */ + int first; /* First entity in search */ + int last; /* Last entity in search */ + static const struct { + const char *name; /* Entity name */ + int val; /* Character value */ + } entities[] = { + { "AElig", 198 }, { "Aacute", 193 }, { "Acirc", 194 }, + { "Agrave", 192 }, { "Alpha", 913 }, { "Aring", 197 }, + { "Atilde", 195 }, { "Auml", 196 }, { "Beta", 914 }, + { "Ccedil", 199 }, { "Chi", 935 }, { "Dagger", 8225 }, + { "Delta", 916 }, { "Dstrok", 208 }, { "ETH", 208 }, + { "Eacute", 201 }, { "Ecirc", 202 }, { "Egrave", 200 }, + { "Epsilon", 917 }, { "Eta", 919 }, { "Euml", 203 }, + { "Gamma", 915 }, { "Iacute", 205 }, { "Icirc", 206 }, + { "Igrave", 204 }, { "Iota", 921 }, { "Iuml", 207 }, + { "Kappa", 922 }, { "Lambda", 923 }, { "Mu", 924 }, + { "Ntilde", 209 }, { "Nu", 925 }, { "OElig", 338 }, + { "Oacute", 211 }, { "Ocirc", 212 }, { "Ograve", 210 }, + { "Omega", 937 }, { "Omicron", 927 }, { "Oslash", 216 }, + { "Otilde", 213 }, { "Ouml", 214 }, { "Phi", 934 }, + { "Pi", 928 }, { "Prime", 8243 }, { "Psi", 936 }, + { "Rho", 929 }, { "Scaron", 352 }, { "Sigma", 931 }, + { "THORN", 222 }, { "Tau", 932 }, { "Theta", 920 }, + { "Uacute", 218 }, { "Ucirc", 219 }, { "Ugrave", 217 }, + { "Upsilon", 933 }, { "Uuml", 220 }, { "Xi", 926 }, + { "Yacute", 221 }, { "Yuml", 376 }, { "Zeta", 918 }, + { "aacute", 225 }, { "acirc", 226 }, { "acute", 180 }, + { "aelig", 230 }, { "agrave", 224 }, { "alefsym", 8501 }, + { "alpha", 945 }, { "amp", '&' }, { "and", 8743 }, + { "ang", 8736 }, { "apos", '\'' }, { "aring", 229 }, + { "asymp", 8776 }, { "atilde", 227 }, { "auml", 228 }, + { "bdquo", 8222 }, { "beta", 946 }, { "brkbar", 166 }, + { "brvbar", 166 }, { "bull", 8226 }, { "cap", 8745 }, + { "ccedil", 231 }, { "cedil", 184 }, { "cent", 162 }, + { "chi", 967 }, { "circ", 710 }, { "clubs", 9827 }, + { "cong", 8773 }, { "copy", 169 }, { "crarr", 8629 }, + { "cup", 8746 }, { "curren", 164 }, { "dArr", 8659 }, + { "dagger", 8224 }, { "darr", 8595 }, { "deg", 176 }, + { "delta", 948 }, { "diams", 9830 }, { "die", 168 }, + { "divide", 247 }, { "eacute", 233 }, { "ecirc", 234 }, + { "egrave", 232 }, { "empty", 8709 }, { "emsp", 8195 }, + { "ensp", 8194 }, { "epsilon", 949 }, { "equiv", 8801 }, + { "eta", 951 }, { "eth", 240 }, { "euml", 235 }, + { "euro", 8364 }, { "exist", 8707 }, { "fnof", 402 }, + { "forall", 8704 }, { "frac12", 189 }, { "frac14", 188 }, + { "frac34", 190 }, { "frasl", 8260 }, { "gamma", 947 }, + { "ge", 8805 }, { "gt", '>' }, { "hArr", 8660 }, + { "harr", 8596 }, { "hearts", 9829 }, { "hellip", 8230 }, + { "hibar", 175 }, { "iacute", 237 }, { "icirc", 238 }, + { "iexcl", 161 }, { "igrave", 236 }, { "image", 8465 }, + { "infin", 8734 }, { "int", 8747 }, { "iota", 953 }, + { "iquest", 191 }, { "isin", 8712 }, { "iuml", 239 }, + { "kappa", 954 }, { "lArr", 8656 }, { "lambda", 955 }, + { "lang", 9001 }, { "laquo", 171 }, { "larr", 8592 }, + { "lceil", 8968 }, { "ldquo", 8220 }, { "le", 8804 }, + { "lfloor", 8970 }, { "lowast", 8727 }, { "loz", 9674 }, + { "lrm", 8206 }, { "lsaquo", 8249 }, { "lsquo", 8216 }, + { "lt", '<' }, { "macr", 175 }, { "mdash", 8212 }, + { "micro", 181 }, { "middot", 183 }, { "minus", 8722 }, + { "mu", 956 }, { "nabla", 8711 }, { "nbsp", 160 }, + { "ndash", 8211 }, { "ne", 8800 }, { "ni", 8715 }, + { "not", 172 }, { "notin", 8713 }, { "nsub", 8836 }, + { "ntilde", 241 }, { "nu", 957 }, { "oacute", 243 }, + { "ocirc", 244 }, { "oelig", 339 }, { "ograve", 242 }, + { "oline", 8254 }, { "omega", 969 }, { "omicron", 959 }, + { "oplus", 8853 }, { "or", 8744 }, { "ordf", 170 }, + { "ordm", 186 }, { "oslash", 248 }, { "otilde", 245 }, + { "otimes", 8855 }, { "ouml", 246 }, { "para", 182 }, + { "part", 8706 }, { "permil", 8240 }, { "perp", 8869 }, + { "phi", 966 }, { "pi", 960 }, { "piv", 982 }, + { "plusmn", 177 }, { "pound", 163 }, { "prime", 8242 }, + { "prod", 8719 }, { "prop", 8733 }, { "psi", 968 }, + { "quot", '\"' }, { "rArr", 8658 }, { "radic", 8730 }, + { "rang", 9002 }, { "raquo", 187 }, { "rarr", 8594 }, + { "rceil", 8969 }, { "rdquo", 8221 }, { "real", 8476 }, + { "reg", 174 }, { "rfloor", 8971 }, { "rho", 961 }, + { "rlm", 8207 }, { "rsaquo", 8250 }, { "rsquo", 8217 }, + { "sbquo", 8218 }, { "scaron", 353 }, { "sdot", 8901 }, + { "sect", 167 }, { "shy", 173 }, { "sigma", 963 }, + { "sigmaf", 962 }, { "sim", 8764 }, { "spades", 9824 }, + { "sub", 8834 }, { "sube", 8838 }, { "sum", 8721 }, + { "sup", 8835 }, { "sup1", 185 }, { "sup2", 178 }, + { "sup3", 179 }, { "supe", 8839 }, { "szlig", 223 }, + { "tau", 964 }, { "there4", 8756 }, { "theta", 952 }, + { "thetasym", 977 }, { "thinsp", 8201 }, { "thorn", 254 }, + { "tilde", 732 }, { "times", 215 }, { "trade", 8482 }, + { "uArr", 8657 }, { "uacute", 250 }, { "uarr", 8593 }, + { "ucirc", 251 }, { "ugrave", 249 }, { "uml", 168 }, + { "upsih", 978 }, { "upsilon", 965 }, { "uuml", 252 }, + { "weierp", 8472 }, { "xi", 958 }, { "yacute", 253 }, + { "yen", 165 }, { "yuml", 255 }, { "zeta", 950 }, + { "zwj", 8205 }, { "zwnj", 8204 } + }; + + /* + * Do a binary search for the named entity... + */ + + first = 0; + last = (int)(sizeof(entities) / sizeof(entities[0]) - 1); + + while ((last - first) > 1) { + curent = (first + last) / 2; + diff = strcmp(name, entities[curent].name); + if (diff == 0) + return entities[curent].val; + else if (diff < 0) + last = curent; + else + first = curent; + } + + /* + * If we get here, there is a small chance that there is still + * a match; check first and last... + */ + + if (!strcmp(name, entities[first].name)) + return entities[first].val; + else if (!strcmp(name, entities[last].name)) + return entities[last].val; + else + return (-1); +} diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-file.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-file.c new file mode 100644 index 000000000000..54881fff5d72 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-file.c @@ -0,0 +1,1626 @@ +/* + * File loading code for Mini-XML, a small XML file parsing library. + * + * Copyright 2003-2017 by Michael R Sweet. + * Copyright (C) 2019 XiaoMi, Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Michael R Sweet and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "COPYING" + * which should have been included with this file. If this file is + * missing or damaged, see the license at: + * + * https://michaelrsweet.github.io/mxml + */ + +/* + * Include necessary headers... + */ + +#ifndef WIN32 +#endif /* !WIN32 */ +#include "mxml-private.h" +#include + +/* + * Character encoding... + */ + +#define ENCODE_UTF8 0 /* UTF-8 */ +#define ENCODE_UTF16BE 1 /* UTF-16 Big-Endian */ +#define ENCODE_UTF16LE 2 /* UTF-16 Little-Endian */ + +/* + * Macro to test for a bad XML character... + */ + +#define mxml_bad_char(ch) \ + ((ch) < ' ' && (ch) != '\n' && (ch) != '\r' && (ch) != '\t') + +/* + * Types and structures... + */ + +typedef int (*_mxml_getc_cb_t)(void *, int *); +typedef int (*_mxml_putc_cb_t)(int, void *); + +typedef struct _mxml_fdbuf_s { + /**** File descriptor buffer ****/ + int fd; /* File descriptor */ + unsigned char *curr, /* Current position in buffer */ + *end, /* End of buffer */ + buffer[8192]; /* Character buffer */ +} _mxml_fdbuf_t; + +/* + * Local functions... + */ + +static int mxml_add_char(int ch, char **ptr, char **buffer, int *bufsize); + +static int mxml_get_entity(mxml_node_t *parent, void *p, int *encoding, + _mxml_getc_cb_t getc_cb); +static inline int mxml_isspace(int ch) +{ + return (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'); +} + +static mxml_node_t *mxml_load_data(mxml_node_t *top, void *p, mxml_load_cb_t cb, + _mxml_getc_cb_t getc_cb, + mxml_sax_cb_t sax_cb, void *sax_data); +static int mxml_parse_element(mxml_node_t *node, void *p, int *encoding, + _mxml_getc_cb_t getc_cb); +static int mxml_string_getc(void *p, int *encoding); +static int mxml_string_putc(int ch, void *p); +static int mxml_write_name(const char *s, void *p, _mxml_putc_cb_t putc_cb); +static int mxml_write_node(mxml_node_t *node, void *p, mxml_save_cb_t cb, + int col, _mxml_putc_cb_t putc_cb, + _mxml_global_t *global); +static int mxml_write_string(const char *s, void *p, _mxml_putc_cb_t putc_cb); +static int mxml_write_ws(mxml_node_t *node, void *p, mxml_save_cb_t cb, int ws, + int col, _mxml_putc_cb_t putc_cb); + +/* + * 'mxmlLoadString()' - Load a string into an XML node tree. + * + * The nodes in the specified string are added to the specified top node. + * If no top node is provided, the XML string MUST be well-formed with a + * single parent node like for the entire string. The callback + * function returns the value type that should be used for child nodes. + * The constants @code MXML_INTEGER_CALLBACK@, @code MXML_OPAQUE_CALLBACK@, + * @code MXML_REAL_CALLBACK@, and @code MXML_TEXT_CALLBACK@ are defined for + * loading child (data) nodes of the specified type. + */ + +mxml_node_t * /* O - First node or @code NULL@ if the string has errors. */ +mxmlLoadString(mxml_node_t *top, /* I - Top node */ + const char *s, /* I - String to load */ + mxml_load_cb_t cb) +{ /* I - Callback function or constant */ + /* + * Read the XML data... + */ + + return (mxml_load_data(top, (void *)&s, cb, mxml_string_getc, + MXML_NO_CALLBACK, NULL)); +} + +/* + * 'mxmlSaveAllocString()' - Save an XML tree to an allocated string. + * + * This function returns a pointer to a string containing the textual + * representation of the XML node tree. The string should be freed + * using the free() function when you are done with it. @code NULL@ is returned + * if the node would produce an empty string or if the string cannot be + * allocated. + * + * The callback argument specifies a function that returns a whitespace + * string or NULL before and after each element. If @code MXML_NO_CALLBACK@ + * is specified, whitespace will only be added before @code MXML_TEXT@ nodes + * with leading whitespace and before attribute names inside opening + * element tags. + */ + +char * /* O - Allocated string or @code NULL@ */ +mxmlSaveAllocString(mxml_node_t *node, /* I - Node to write */ + mxml_save_cb_t cb) +{ /* I - Whitespace callback or @code MXML_NO_CALLBACK@ */ + int bytes; /* Required bytes */ + //char buffer[2000]; /* Temporary buffer */ + char buffer[512]; /* Temporary buffer */ + char *s; /* Allocated string */ + + /* + * Write the node to the temporary buffer... + */ + + bytes = mxmlSaveString(node, buffer, sizeof(buffer), cb); + + if (bytes <= 0) + return NULL; + if (bytes < (int)(sizeof(buffer) - 1)) { + /* + * Node fit inside the buffer, so just duplicate that string and + * return... + */ + return strdup(buffer); + } + /* + * Allocate a buffer of the required size and save the node to the + * new buffer... + */ + s = malloc(bytes + 1); + if (s == NULL) + return NULL; + + mxmlSaveString(node, s, bytes + 1, cb); + /* Return the allocated string... */ + return s; +} + +/* + * 'mxmlSaveString()' - Save an XML node tree to a string. + * + * This function returns the total number of bytes that would be + * required for the string but only copies (bufsize - 1) characters + * into the specified buffer. + * + * The callback argument specifies a function that returns a whitespace + * string or NULL before and after each element. If @code MXML_NO_CALLBACK@ + * is specified, whitespace will only be added before @code MXML_TEXT@ nodes + * with leading whitespace and before attribute names inside opening + * element tags. + */ +/* O - Size of string */ +int mxmlSaveString(mxml_node_t *node, /* I - Node to write */ + char *buffer, /* I - String buffer */ + int bufsize, /* I - Size of string buffer */ + mxml_save_cb_t cb) +{ /* I - Whitespace callback or @code MXML_NO_CALLBACK@ */ + int col; /* Final column */ + char *ptr[2]; /* Pointers for putc_cb */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + /* Write the node... */ + ptr[0] = buffer; + ptr[1] = buffer + bufsize; + col = mxml_write_node(node, ptr, cb, 0, mxml_string_putc, global); + if (col < 0) + return (-1); + + if (col > 0) + mxml_string_putc('\n', ptr); + + /* Nul-terminate the buffer... */ + + if (ptr[0] >= ptr[1]) + buffer[bufsize - 1] = '\0'; + else + ptr[0][0] = '\0'; + /* Return the number of characters... */ + return ((int)(ptr[0] - buffer)); +} + +/* + * 'mxmlSAXLoadString()' - Load a string into an XML node tree + * using a SAX callback. + * + * The nodes in the specified string are added to the specified top node. + * If no top node is provided, the XML string MUST be well-formed with a + * single parent node like for the entire string. The callback + * function returns the value type that should be used for child nodes. + * The constants @code MXML_INTEGER_CALLBACK@, @code MXML_OPAQUE_CALLBACK@, + * @code MXML_REAL_CALLBACK@, and @code MXML_TEXT_CALLBACK@ are defined for + * loading child nodes of the specified type. + * + * The SAX callback must call @link mxmlRetain@ for any nodes that need to + * be kept for later use. Otherwise, nodes are deleted when the parent + * node is closed or after each data, comment, CDATA, or directive node. + * + * @since Mini-XML 2.3@ + */ + +mxml_node_t * /* O - First node or @code NULL@ if the string has errors. */ +mxmlSAXLoadString( + mxml_node_t *top, /* I - Top node */ + const char *s, /* I - String to load */ + mxml_load_cb_t cb, /* I - Callback function or constant */ + mxml_sax_cb_t sax_cb, /* I - SAX callback or @code MXML_NO_CALLBACK@ */ + void *sax_data) +{ /* I - SAX user data */ + /* Read the XML data... */ + return (mxml_load_data(top, (void *)&s, cb, mxml_string_getc, sax_cb, + sax_data)); +} + +/* + * 'mxmlSetCustomHandlers()' - Set the handling functions for custom data. + * + * The load function accepts a node pointer and a data string and must + * return 0 on success and non-zero on error. + * + * The save function accepts a node pointer and must return a malloc'd + * string on success and @code NULL@ on error. + * + */ + +void mxmlSetCustomHandlers(mxml_custom_load_cb_t load, /* I - Load function */ + mxml_custom_save_cb_t save) +{ /* I - Save function */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + global->custom_load_cb = load; + global->custom_save_cb = save; +} + +/* + * 'mxmlSetErrorCallback()' - Set the error message callback. + */ + +void mxmlSetErrorCallback(mxml_error_cb_t cb) +{ /* I - Error callback function */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + global->error_cb = cb; +} + +/* + * 'mxmlSetWrapMargin()' - Set the wrap margin when saving XML data. + * + * Wrapping is disabled when "column" is 0. + * + * @since Mini-XML 2.3@ + */ + +void mxmlSetWrapMargin(int column) +{ /* I - Column for wrapping, 0 to disable wrapping */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + global->wrap = column; +} + +/* + * 'mxml_add_char()' - Add a character to a buffer, expanding as needed. + */ + +static int /* O - 0 on success, -1 on error */ +mxml_add_char(int ch, /* I - Character to add */ + char **bufptr, /* IO - Current position in buffer */ + char **buffer, /* IO - Current buffer */ + int *bufsize) +{ /* IO - Current buffer size */ + char *newbuffer; /* New buffer value */ + if (*bufptr >= (*buffer + *bufsize - 4)) { + /* Increase the size of the buffer... */ + if (*bufsize < 1024) + (*bufsize) *= 2; + else + (*bufsize) += 1024; + newbuffer = realloc(*buffer, *bufsize); + if (newbuffer == NULL) { + free(*buffer); + mxml_error( + "Unable to expand string buffer to %d bytes!", + *bufsize); + return (-1); + } + *bufptr = newbuffer + (*bufptr - *buffer); + *buffer = newbuffer; + } + + if (ch < 0x80) { + /* Single byte ASCII... */ + *(*bufptr)++ = ch; + } else if (ch < 0x800) { + /* Two-byte UTF-8... */ + *(*bufptr)++ = 0xc0 | (ch >> 6); + *(*bufptr)++ = 0x80 | (ch & 0x3f); + } else if (ch < 0x10000) { + /* Three-byte UTF-8... */ + *(*bufptr)++ = 0xe0 | (ch >> 12); + *(*bufptr)++ = 0x80 | ((ch >> 6) & 0x3f); + *(*bufptr)++ = 0x80 | (ch & 0x3f); + } else { + /* Four-byte UTF-8... */ + *(*bufptr)++ = 0xf0 | (ch >> 18); + *(*bufptr)++ = 0x80 | ((ch >> 12) & 0x3f); + *(*bufptr)++ = 0x80 | ((ch >> 6) & 0x3f); + *(*bufptr)++ = 0x80 | (ch & 0x3f); + } + return 0; +} + +/* + * 'mxml_get_entity()' - Get the character corresponding to an entity... + */ + +static int mxml_get_entity(mxml_node_t *parent, void *p, int *encoding, + int (*getc_cb)(void *, int *)) +{ + int ch; /* Current character */ + char entity[64], /* Entity string */ + *entptr; /* Pointer into entity */ + + entptr = entity; + while ((ch = (*getc_cb)(p, encoding)) != EOF) + if (ch > 126 || (!isalnum(ch) && ch != '#')) + break; + else if (entptr < (entity + sizeof(entity) - 1)) + *entptr++ = ch; + else { + mxml_error("Entity name too long under parent <%s>!", + parent ? parent->value.element.name : + "null"); + break; + } + + *entptr = '\0'; + if (ch != ';') { + mxml_error( + "Character entity \"%s\" not terminated under parent <%s>!", + entity, parent ? parent->value.element.name : "null"); + return EOF; + } + + if (entity[0] == '#') { + if (entity[1] == 'x') + ch = (int)strtol(entity + 2, NULL, 16); + else + ch = (int)strtol(entity + 1, NULL, 10); + } else { + ch = mxmlEntityGetValue(entity); + if (ch < 0) + mxml_error( + "Entity name \"%s;\" not supported under parent <%s>!", + entity, + parent ? parent->value.element.name : "null"); + } + if (mxml_bad_char(ch)) { + mxml_error( + "Bad control character 0x%02x under parent <%s> not allowed by XML standard!", + ch, parent ? parent->value.element.name : "null"); + return EOF; + } + return ch; +} + +/* + * 'mxml_load_data()' - Load data into an XML node tree. + */ + +static mxml_node_t * /* O - First node or NULL if the file could not be read. */ +mxml_load_data(mxml_node_t *top, /* I - Top node */ + void *p, /* I - Pointer to data */ + mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */ + _mxml_getc_cb_t getc_cb, /* I - Read function */ + mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */ + void *sax_data) +{ /* I - SAX user data */ + mxml_node_t *node = NULL, /* Current node */ + *first = NULL, /* First node added */ + *parent = NULL; /* Current parent node */ + int ch, /* Character from file */ + whitespace; /* Non-zero if whitespace seen */ + char *buffer = NULL, /* String buffer */ + *bufptr = NULL; /* Pointer into buffer */ + int bufsize; /* Size of buffer */ + mxml_type_t type; /* Current node type */ + int encoding; /* Character encoding */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + static const char *const types[] = /* Type strings... */ + { + "MXML_ELEMENT", /* XML element with attributes */ + "MXML_INTEGER", /* Integer value */ + "MXML_OPAQUE", /* Opaque string */ + "MXML_REAL", /* Real value */ + "MXML_TEXT", /* Text fragment */ + "MXML_CUSTOM" /* Custom data */ + }; + + /* + * Read elements and other nodes from the file... + */ + buffer = malloc(64); + if (buffer == NULL) { + mxml_error("Unable to allocate string buffer!"); + return NULL; + } + + bufsize = 64; + bufptr = buffer; + parent = top; + first = NULL; + whitespace = 0; + encoding = ENCODE_UTF8; + + if (cb && parent) + type = (*cb)(parent); + else if (parent) + type = MXML_TEXT; + else + type = MXML_IGNORE; + + while ((ch = (*getc_cb)(p, &encoding)) != EOF) { + if ((ch == '<' || (mxml_isspace(ch) && type != MXML_OPAQUE && + type != MXML_CUSTOM)) && + bufptr > buffer) { + /* Add a new value node... */ + + *bufptr = '\0'; + switch (type) { + case MXML_INTEGER: + node = mxmlNewInteger(parent, + (int)strtol(buffer, + &bufptr, 0)); + break; + + case MXML_OPAQUE: + node = mxmlNewOpaque(parent, buffer); + break; + + case MXML_REAL: + break; + + case MXML_TEXT: + node = mxmlNewText(parent, whitespace, buffer); + break; + + case MXML_CUSTOM: + if (global->custom_load_cb) { + /* * Use the callback to fill in the custom data... */ + node = mxmlNewCustom(parent, NULL, + NULL); + if ((*global->custom_load_cb)(node, + buffer)) { + mxml_error( + "Bad custom value '%s' in parent <%s>!", + buffer, + parent ? + parent->value + .element + .name : + "null"); + mxmlDelete(node); + node = NULL; + } + break; + } + + default: /* Ignore... */ + node = NULL; + break; + } + + if (*bufptr) { + /* Bad integer/real number value... */ + + mxml_error("Bad %s value '%s' in parent <%s>!", + type == MXML_INTEGER ? "integer" : + "real", + buffer, + parent ? parent->value.element.name : + "null"); + break; + } + + bufptr = buffer; + whitespace = mxml_isspace(ch) && type == MXML_TEXT; + + if (!node && type != MXML_IGNORE) { + /* Print error and return... */ + mxml_error( + "Unable to add value node of type %s to parent <%s>!", + types[type], + parent ? parent->value.element.name : + "null"); + goto error; + } + + if (sax_cb) { + (*sax_cb)(node, MXML_SAX_DATA, sax_data); + + if (!mxmlRelease(node)) + node = NULL; + } + + if (!first && node) + first = node; + } else if (mxml_isspace(ch) && type == MXML_TEXT) + whitespace = 1; + + /* + * Add lone whitespace node if we have an element and existing + * whitespace... + */ + + if (ch == '<' && whitespace && type == MXML_TEXT) { + if (parent) { + node = mxmlNewText(parent, whitespace, ""); + if (sax_cb) { + (*sax_cb)(node, MXML_SAX_DATA, + sax_data); + if (!mxmlRelease(node)) + node = NULL; + } + if (!first && node) + first = node; + } + whitespace = 0; + } + + if (ch == '<') { + /* Start of open/close tag... */ + bufptr = buffer; + while ((ch = (*getc_cb)(p, &encoding)) != EOF) + if (mxml_isspace(ch) || ch == '>' || + (ch == '/' && bufptr > buffer)) + break; + else if (ch == '<') { + mxml_error("Bare < in element!"); + goto error; + } else if (ch == '&') { + ch = mxml_get_entity( + parent, p, &encoding, getc_cb); + if (ch == EOF) + goto error; + if (mxml_add_char(ch, &bufptr, &buffer, + &bufsize)) + goto error; + } else if (ch < '0' && ch != '!' && ch != '-' && + ch != '.' && ch != '/') + goto error; + else if (mxml_add_char(ch, &bufptr, &buffer, + &bufsize)) + goto error; + else if (((bufptr - buffer) == 1 && + buffer[0] == '?') || + ((bufptr - buffer) == 3 && + !strncmp(buffer, "!--", 3)) || + ((bufptr - buffer) == 8 && + !strncmp(buffer, "![CDATA[", 8))) + break; + + *bufptr = '\0'; + if (!strcmp(buffer, "!--")) { + /* Gather rest of comment... */ + while ((ch = (*getc_cb)(p, &encoding)) != EOF) { + if (ch == '>' && + bufptr > (buffer + 4) && + bufptr[-3] != '-' && + bufptr[-2] == '-' && + bufptr[-1] == '-') + break; + else if (mxml_add_char(ch, &bufptr, + &buffer, + &bufsize)) + goto error; + } + + /* Error out if we didn't get the whole comment... */ + if (ch != '>') { + /* Print error and return... */ + + mxml_error( + "Early EOF in comment node!"); + goto error; + } + /* Otherwise add this as an element under the curr parent... */ + *bufptr = '\0'; + if (!parent && first) { + /* There can only be one root element! */ + mxml_error( + "<%s> cannot be a second root node after <%s>", + buffer, + first->value.element.name); + goto error; + } + node = mxmlNewElement(parent, buffer); + if (node == NULL) { + /* Just print error for now... */ + mxml_error( + "Unable to add comment node to parent <%s>!", + parent ? parent->value.element + .name : + "null"); + break; + } + + if (sax_cb) { + (*sax_cb)(node, MXML_SAX_COMMENT, + sax_data); + if (!mxmlRelease(node)) + node = NULL; + } + if (node && !first) + first = node; + } else if (!strcmp(buffer, "![CDATA[")) { + /* Gather CDATA section... */ + while ((ch = (*getc_cb)(p, &encoding)) != EOF) { + if (ch == '>' && + !strncmp(bufptr - 2, "]]", 2)) { + /* Drop terminator from CDATA string... */ + bufptr[-2] = '\0'; + break; + } else if (mxml_add_char(ch, &bufptr, + &buffer, + &bufsize)) + goto error; + } + /* Error out if we didn't get the whole comment... */ + if (ch != '>') { + /* Print error and return... */ + mxml_error("Early EOF in CDATA node!"); + goto error; + } + /* Otherwise add this as an element under the curr parent... */ + + *bufptr = '\0'; + + if (!parent && first) { + /* There can only be one root element! */ + mxml_error( + "<%s> cannot be a second root node after <%s>", + buffer, + first->value.element.name); + goto error; + } + node = mxmlNewElement(parent, buffer); + if (node == NULL) { + /* Print error and return... */ + mxml_error( + "Unable to add CDATA node to parent <%s>!", + parent ? parent->value.element + .name : + "null"); + goto error; + } + + if (sax_cb) { + (*sax_cb)(node, MXML_SAX_CDATA, + sax_data); + if (!mxmlRelease(node)) + node = NULL; + } + if (node && !first) + first = node; + } else if (buffer[0] == '?') { + /* Gather rest of processing instruction... */ + while ((ch = (*getc_cb)(p, &encoding)) != EOF) { + if (ch == '>' && bufptr > buffer && + bufptr[-1] == '?') + break; + else if (mxml_add_char(ch, &bufptr, + &buffer, + &bufsize)) + goto error; + } + + /* Error out if we didn't get the whole processing instruction... */ + if (ch != '>') { + /* Print error and return... */ + mxml_error( + "Early EOF in processing instruction node!"); + goto error; + } + /* Otherwise add this as an element under the current parent... */ + *bufptr = '\0'; + if (!parent && first) { + /* * There can only be one root element! */ + mxml_error( + "<%s> cannot be a second root node after <%s>", + buffer, + first->value.element.name); + goto error; + } + node = mxmlNewElement(parent, buffer); + if (node == NULL) { + /* Print error and return... */ + mxml_error( + "Unable to add processing instruction node to parent <%s>!", + parent ? parent->value.element + .name : + "null"); + goto error; + } + + if (sax_cb) { + (*sax_cb)(node, MXML_SAX_DIRECTIVE, + sax_data); + if (!mxmlRelease(node)) + node = NULL; + } + + if (node) { + if (!first) + first = node; + if (!parent) { + parent = node; + if (cb) + type = (*cb)(parent); + else + type = MXML_TEXT; + } + } + } else if (buffer[0] == '!') { + /* Gather rest of declaration... */ + do { + if (ch == '>') + break; + else { + if (ch == '&') { + ch = mxml_get_entity( + parent, p, + &encoding, + getc_cb); + if (ch == EOF) + goto error; + } + if (mxml_add_char(ch, &bufptr, + &buffer, + &bufsize)) + goto error; + } + } while ((ch = (*getc_cb)(p, &encoding)) != + EOF); + /* Error out if we didn't get the whole declaration... */ + if (ch != '>') { + /* Print error and return... */ + mxml_error( + "Early EOF in declaration node!"); + goto error; + } + /* Otherwise add this as an element under the current parent... */ + *bufptr = '\0'; + if (!parent && first) { + /* * There can only be one root element! */ + mxml_error( + "<%s> cannot be a second root node after <%s>", + buffer, + first->value.element.name); + goto error; + } + node = mxmlNewElement(parent, buffer); + if (node == NULL) { + /* * Print error and return... */ + mxml_error( + "Unable to add declaration node to parent <%s>!", + parent ? parent->value.element + .name : + "null"); + goto error; + } + + if (sax_cb) { + (*sax_cb)(node, MXML_SAX_DIRECTIVE, + sax_data); + if (!mxmlRelease(node)) + node = NULL; + } + + if (node) { + if (!first) + first = node; + if (!parent) { + parent = node; + if (cb) + type = (*cb)(parent); + else + type = MXML_TEXT; + } + } + } else if (buffer[0] == '/') { + /* Handle close tag... */ + if (!parent || + strcmp(buffer + 1, + parent->value.element.name)) { + /* * Close tag doesn't match tree; print an error for now... */ + mxml_error( + "Mismatched close tag <%s> under parent <%s>!", + buffer, + parent ? parent->value.element + .name : + "(null)"); + goto error; + } + + /* * Keep reading until we see >... */ + while (ch != '>' && ch != EOF) + ch = (*getc_cb)(p, &encoding); + node = parent; + parent = parent->parent; + if (sax_cb) { + (*sax_cb)(node, MXML_SAX_ELEMENT_CLOSE, + sax_data); + if (!mxmlRelease(node) && first == node) + first = NULL; + } + /* * Ascend into the parent and set the value type as needed... */ + if (cb && parent) + type = (*cb)(parent); + } else { + /* * Handle open tag... */ + if (!parent && first) { + /* * There can only be one root element! */ + mxml_error( + "<%s> cannot be a second root node after <%s>", + buffer, + first->value.element.name); + goto error; + } + node = mxmlNewElement(parent, buffer); + if (node == NULL) { + /* * Just print error for now... */ + mxml_error( + "Unable to add element node to parent <%s>!", + parent ? parent->value.element + .name : + "null"); + goto error; + } + + if (mxml_isspace(ch)) { + ch = mxml_parse_element( + node, p, &encoding, getc_cb); + if (ch == EOF) + goto error; + } else if (ch == '/') { + ch = (*getc_cb)(p, &encoding); + if (ch != '>') { + mxml_error( + "Expected > but got '%c' instead for element <%s/>!", + ch, buffer); + mxmlDelete(node); + goto error; + } + ch = '/'; + } + if (sax_cb) + (*sax_cb)(node, MXML_SAX_ELEMENT_OPEN, + sax_data); + if (!first) + first = node; + if (ch == EOF) + break; + if (ch != '/') { + /* * Descend into this node, setting the value type as needed... */ + parent = node; + if (cb && parent) + type = (*cb)(parent); + else + type = MXML_TEXT; + } else if (sax_cb) { + (*sax_cb)(node, MXML_SAX_ELEMENT_CLOSE, + sax_data); + if (!mxmlRelease(node) && first == node) + first = NULL; + } + } + bufptr = buffer; + } else if (ch == '&') { + /* * Add character entity to current buffer... */ + ch = mxml_get_entity(parent, p, &encoding, getc_cb); + if (ch == EOF) + goto error; + if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) + goto error; + } else if (type == MXML_OPAQUE || type == MXML_CUSTOM || + !mxml_isspace(ch)) { + /* * Add character to current buffer... */ + if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) + goto error; + } + } + /* * Free the string buffer - we don't need it anymore... */ + free(buffer); + /* * Find the top element and return it... */ + if (parent) { + node = parent; + while (parent != top && parent->parent) + parent = parent->parent; + if (node != parent) { + mxml_error("Missing close tag under parent <%s>!", + node->value.element.name, + node->parent ? + node->parent->value.element.name : + "(null)"); + mxmlDelete(first); + return NULL; + } + } + if (parent) + return parent; + else + return first; + /* * Common error return... */ + +error: + mxmlDelete(first); + free(buffer); + return NULL; +} + +/* + * 'mxml_parse_element()' - Parse an element for any attributes... + */ + +static int /* O - Terminating character */ +mxml_parse_element(mxml_node_t *node, /* I - Element node */ + void *p, /* I - Data to read from */ + int *encoding, /* IO - Encoding */ + _mxml_getc_cb_t getc_cb) +{ /* I - Data callback */ + int ch, /* Current character in file */ + quote; /* Quoting character */ + char *name, /* Attribute name */ + *value, /* Attribute value */ + *ptr; /* Pointer into name/value */ + int namesize, /* Size of name string */ + valsize; /* Size of value string */ + + /* Initialize the name and value buffers... */ + name = malloc(64); + if (name == NULL) { + mxml_error("Unable to allocate memory for name!"); + return EOF; + } + + namesize = 64; + value = malloc(64); + if (value == NULL) { + free(name); + mxml_error("Unable to allocate memory for value!"); + return EOF; + } + valsize = 64; + /* * Loop until we hit a >, /, ?, or EOF... */ + + while ((ch = (*getc_cb)(p, encoding)) != EOF) { + /* * Skip leading whitespace... */ + if (mxml_isspace(ch)) + continue; + /* * Stop at /, ?, or >... */ + if (ch == '/' || ch == '?') { + /* * Grab the > character and print an error if it isn't there... */ + quote = (*getc_cb)(p, encoding); + if (quote != '>') { + mxml_error( + "Expected '>' after '%c' for element %s, but got '%c'!", + ch, node->value.element.name, quote); + goto error; + } + break; + } else if (ch == '<') { + mxml_error("Bare < in element %s!", + node->value.element.name); + goto error; + } else if (ch == '>') + break; + /* * Read the attribute name... */ + name[0] = ch; + ptr = name + 1; + if (ch == '\"' || ch == '\'') { + /* * Name is in quotes, so get a quoted string... */ + quote = ch; + while ((ch = (*getc_cb)(p, encoding)) != EOF) { + if (ch == '&') { + ch = mxml_get_entity(node, p, encoding, + getc_cb); + if (ch == EOF) + goto error; + } + if (mxml_add_char(ch, &ptr, &name, &namesize)) + goto error; + if (ch == quote) + break; + } + } else { + /* * Grab an normal, non-quoted name... */ + while ((ch = (*getc_cb)(p, encoding)) != EOF) + if (mxml_isspace(ch) || ch == '=' || + ch == '/' || ch == '>' || ch == '?') + break; + else { + if (ch == '&') { + ch = mxml_get_entity(node, p, + encoding, + getc_cb); + if (ch == EOF) + goto error; + } + if (mxml_add_char(ch, &ptr, &name, + &namesize)) + goto error; + } + } + *ptr = '\0'; + if (mxmlElementGetAttr(node, name)) + goto error; + while (ch != EOF && mxml_isspace(ch)) + ch = (*getc_cb)(p, encoding); + if (ch == '=') { + /* * Read the attribute value... */ + do { + ch = (*getc_cb)(p, encoding); + } while (ch != EOF && mxml_isspace(ch)); + + if (ch == EOF) { + mxml_error( + "Missing value for attribute '%s' in element %s!", + name, node->value.element.name); + goto error; + } + if (ch == '\'' || ch == '\"') { + /* * Read quoted value... */ + quote = ch; + ptr = value; + while ((ch = (*getc_cb)(p, encoding)) != EOF) + if (ch == quote) + break; + else { + if (ch == '&') { + ch = mxml_get_entity( + node, p, + encoding, + getc_cb); + if (ch == EOF) + goto error; + } + if (mxml_add_char(ch, &ptr, + &value, + &valsize)) + goto error; + } + *ptr = '\0'; + } else { + /* * Read unquoted value... */ + value[0] = ch; + ptr = value + 1; + while ((ch = (*getc_cb)(p, encoding)) != EOF) + if (mxml_isspace(ch) || ch == '=' || + ch == '/' || ch == '>') + break; + else { + if (ch == '&') { + ch = mxml_get_entity( + node, p, + encoding, + getc_cb); + if (ch == EOF) + goto error; + } + if (mxml_add_char(ch, &ptr, + &value, + &valsize)) + goto error; + } + *ptr = '\0'; + } + /* * Set the attribute with the given string value... */ + mxmlElementSetAttr(node, name, value); + } else { + mxml_error( + "Missing value for attribute '%s' in element %s!", + name, node->value.element.name); + goto error; + } + + /* * Check the end character... */ + if (ch == '/' || ch == '?') { + /* * Grab the > character and print an error if it isn't there... */ + quote = (*getc_cb)(p, encoding); + if (quote != '>') { + mxml_error( + "Expected '>' after '%c' for element %s, but got '%c'!", + ch, node->value.element.name, quote); + ch = EOF; + } + break; + } else if (ch == '>') + break; + } + /* * Free the name and value buffers and return... */ + free(name); + free(value); + return ch; + /* * Common error return point... */ +error: + free(name); + free(value); + return EOF; +} + +/* + * 'mxml_string_getc()' - Get a character from a string. + */ + +static int /* O - Character or EOF */ +mxml_string_getc(void *p, /* I - Pointer to file */ + int *encoding) +{ /* IO - Encoding */ + int ch; /* Character */ + const char **s; /* Pointer to string pointer */ + + s = (const char **)p; + ch = (*s)[0] & 255; + if (ch != 0 || *encoding == ENCODE_UTF16LE) { + /* * Got character; convert UTF-8 to integer and return... */ + + (*s)++; + switch (*encoding) { + case ENCODE_UTF8: + if (!(ch & 0x80)) { + if (mxml_bad_char(ch)) { + mxml_error( + "Bad control character 0x%02x not allowed by XML standard!", + ch); + return EOF; + } + return ch; + } else if (ch == 0xfe) { + /* * UTF-16 big-endian BOM? */ + if (((*s)[0] & 255) != 0xff) + return EOF; + *encoding = ENCODE_UTF16BE; + (*s)++; + return mxml_string_getc(p, encoding); + } else if (ch == 0xff) { + /* * UTF-16 little-endian BOM? */ + if (((*s)[0] & 255) != 0xfe) + return EOF; + *encoding = ENCODE_UTF16LE; + (*s)++; + return mxml_string_getc(p, encoding); + } else if ((ch & 0xe0) == 0xc0) { + if (((*s)[0] & 0xc0) != 0x80) + return EOF; + ch = ((ch & 0x1f) << 6) | ((*s)[0] & 0x3f); + (*s)++; + if (ch < 0x80) { + mxml_error( + "Invalid UTF-8 sequence for character 0x%04x!", + ch); + return EOF; + } + return ch; + } else if ((ch & 0xf0) == 0xe0) { + if (((*s)[0] & 0xc0) != 0x80 || + ((*s)[1] & 0xc0) != 0x80) + return EOF; + ch = ((((ch & 0x0f) << 6) | ((*s)[0] & 0x3f)) + << 6) | + ((*s)[1] & 0x3f); + (*s) += 2; + if (ch < 0x800) { + mxml_error( + "Invalid UTF-8 sequence for character 0x%04x!", + ch); + return EOF; + } + if (ch == 0xfeff) + return mxml_string_getc(p, encoding); + return ch; + } else if ((ch & 0xf8) == 0xf0) { + if (((*s)[0] & 0xc0) != 0x80 || + ((*s)[1] & 0xc0) != 0x80 || + ((*s)[2] & 0xc0) != 0x80) + return EOF; + ch = ((((((ch & 0x07) << 6) | ((*s)[0] & 0x3f)) + << 6) | + ((*s)[1] & 0x3f)) + << 6) | + ((*s)[2] & 0x3f); + (*s) += 3; + if (ch < 0x10000) { + mxml_error( + "Invalid UTF-8 sequence for character 0x%04x!", + ch); + return EOF; + } + return ch; + } else + return EOF; + + case ENCODE_UTF16BE: + ch = (ch << 8) | ((*s)[0] & 255); + (*s)++; + if (mxml_bad_char(ch)) { + mxml_error( + "Bad control character 0x%02x not allowed by XML standard!", + ch); + return EOF; + } else if (ch >= 0xd800 && ch <= 0xdbff) { + int lch; /* Lower word */ + if (!(*s)[0]) + return EOF; + lch = (((*s)[0] & 255) << 8) | ((*s)[1] & 255); + (*s) += 2; + if (lch < 0xdc00 || lch >= 0xdfff) + return EOF; + ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + + 0x10000; + } + return ch; + + case ENCODE_UTF16LE: + ch = ch | (((*s)[0] & 255) << 8); + if (!ch) { + (*s)--; + return EOF; + } + (*s)++; + if (mxml_bad_char(ch)) { + mxml_error( + "Bad control character 0x%02x not allowed by XML standard!", + ch); + return EOF; + } else if (ch >= 0xd800 && ch <= 0xdbff) { + int lch; /* Lower word */ + if (!(*s)[1]) + return EOF; + lch = (((*s)[1] & 255) << 8) | ((*s)[0] & 255); + (*s) += 2; + if (lch < 0xdc00 || lch >= 0xdfff) + return EOF; + ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + + 0x10000; + } + return ch; + } + } + return EOF; +} + +/* + * 'mxml_string_putc()' - Write a character to a string. + */ + +static int /* O - 0 on success, -1 on failure */ +mxml_string_putc(int ch, /* I - Character to write */ + void *p) +{ /* I - Pointer to string pointers */ + char **pp; /* Pointer to string pointers */ + pp = (char **)p; + if (pp[0] < pp[1]) + pp[0][0] = ch; + pp[0]++; + return 0; +} + +/* + * 'mxml_write_name()' - Write a name string. + */ + +static int /* O - 0 on success, -1 on failure */ +mxml_write_name(const char *s, /* I - Name to write */ + void *p, /* I - Write pointer */ + int (*putc_cb)(int, void *)) +/* I - Write callback */ +{ + char quote; /* Quote character */ + const char *name; /* Entity name */ + + if (*s == '\"' || *s == '\'') { + if ((*putc_cb)(*s, p) < 0) + return (-1); + quote = *s++; + while (*s && *s != quote) { + name = mxmlEntityGetName(*s); + if (name != NULL) { + if ((*putc_cb)('&', p) < 0) + return (-1); + while (*name) { + if ((*putc_cb)(*name, p) < 0) + return (-1); + name++; + } + if ((*putc_cb)(';', p) < 0) + return (-1); + } else if ((*putc_cb)(*s, p) < 0) + return (-1); + s++; + } + if ((*putc_cb)(quote, p) < 0) + return (-1); + } else { + while (*s) { + if ((*putc_cb)(*s, p) < 0) + return (-1); + s++; + } + } + return 0; +} + +/* + * 'mxml_write_node()' - Save an XML node to a file. + */ + +static int /* O - Column or -1 on error */ +mxml_write_node(mxml_node_t *node, /* I - Node to write */ + void *p, /* I - File to write to */ + mxml_save_cb_t cb, /* I - Whitespace callback */ + int col, /* I - Current column */ + _mxml_putc_cb_t putc_cb, /* I - Output callback */ + _mxml_global_t *global) +{ /* I - Global data */ + mxml_node_t *curr, /* Current node */ + *next; /* Next node */ + int i, /* Looping var */ + width; /* Width of attr + value */ + mxml_attr_t *attr; /* Current attribute */ + char s[255]; /* Temporary string */ + + /* * Loop through this node and all of its children... */ + for (curr = node; curr; curr = next) { + switch (curr->type) { + case MXML_ELEMENT: + col = mxml_write_ws(curr, p, cb, MXML_WS_BEFORE_OPEN, + col, putc_cb); + if ((*putc_cb)('<', p) < 0) + return (-1); + if (curr->value.element.name[0] == '?' || + !strncmp(curr->value.element.name, "!--", 3)) { + /* + * Comments and processing instructions do not use character + * entities. + */ + const char *ptr; /* Pointer into name */ + for (ptr = curr->value.element.name; *ptr; + ptr++) + if ((*putc_cb)(*ptr, p) < 0) + return (-1); + } else if (!strncmp(curr->value.element.name, + "![CDATA[", 8)) { + /* + * CDATA elements do not use character entities, but also need the + * "]]" terminator added at the end. + */ + const char *ptr; /* Pointer into name */ + for (ptr = curr->value.element.name; *ptr; + ptr++) + if ((*putc_cb)(*ptr, p) < 0) + return (-1); + if ((*putc_cb)(']', p) < 0) + return (-1); + if ((*putc_cb)(']', p) < 0) + return (-1); + } else if (mxml_write_name(curr->value.element.name, p, + putc_cb) < 0) + return (-1); + col += strlen(curr->value.element.name) + 1; + for (i = curr->value.element.num_attrs, + attr = curr->value.element.attrs; + i > 0; i--, attr++) { + width = (int)strlen(attr->name); + if (attr->value) + width += strlen(attr->value) + 3; + { + if ((*putc_cb)(' ', p) < 0) + return (-1); + col++; + } + if (mxml_write_name(attr->name, p, putc_cb) < 0) + return (-1); + if (attr->value) { + if ((*putc_cb)('=', p) < 0) + return (-1); + if ((*putc_cb)('\"', p) < 0) + return (-1); + if (mxml_write_string(attr->value, p, + putc_cb) < 0) + return (-1); + if ((*putc_cb)('\"', p) < 0) + return (-1); + } + col += width; + } + if (curr->child) { + if ((*putc_cb)('>', p) < 0) + return (-1); + else + col++; + col = mxml_write_ws(curr, p, cb, + MXML_WS_AFTER_OPEN, col, + putc_cb); + } else if (curr->value.element.name[0] == '!' || + curr->value.element.name[0] == '?') { + if ((*putc_cb)('>', p) < 0) + return (-1); + else + col++; + col = mxml_write_ws(curr, p, cb, + MXML_WS_AFTER_OPEN, col, + putc_cb); + } else { + if ((*putc_cb)(' ', p) < 0) + return (-1); + if ((*putc_cb)('/', p) < 0) + return (-1); + if ((*putc_cb)('>', p) < 0) + return (-1); + col += 3; + col = mxml_write_ws(curr, p, cb, + MXML_WS_AFTER_OPEN, col, + putc_cb); + } + break; + case MXML_INTEGER: + if (curr->prev) { + if (global->wrap > 0 && col > global->wrap) { + if ((*putc_cb)('\n', p) < 0) + return (-1); + col = 0; + } else if ((*putc_cb)(' ', p) < 0) + return (-1); + else + col++; + } + snprintf(s, sizeof(s), "%d", curr->value.integer); + if (mxml_write_string(s, p, putc_cb) < 0) + return (-1); + col += strlen(s); + break; + case MXML_OPAQUE: + if (mxml_write_string(curr->value.opaque, p, putc_cb) < + 0) + return (-1); + col += strlen(curr->value.opaque); + break; + + case MXML_REAL: + if (curr->prev) { + if (global->wrap > 0 && col > global->wrap) { + if ((*putc_cb)('\n', p) < 0) + return (-1); + col = 0; + } else if ((*putc_cb)(' ', p) < 0) + return (-1); + else + col++; + } + /*sprintf(s, "%f", curr->value.real);*/ + if (mxml_write_string(s, p, putc_cb) < 0) + return (-1); + + col += strlen(s); + break; + + case MXML_TEXT: + if (curr->value.text.whitespace && col > 0) { + if (global->wrap > 0 && col > global->wrap) { + if ((*putc_cb)('\n', p) < 0) + return (-1); + + col = 0; + } else if ((*putc_cb)(' ', p) < 0) + return (-1); + else + col++; + } + + if (mxml_write_string(curr->value.text.string, p, + putc_cb) < 0) + return (-1); + + col += strlen(curr->value.text.string); + break; + + case MXML_CUSTOM: + if (global->custom_save_cb) { + char *data; /* Custom data string */ + const char *newline; /* Last newline in string */ + data = (*global->custom_save_cb)(curr); + if (data == NULL) + return (-1); + if (mxml_write_string(data, p, putc_cb) < 0) + return (-1); + newline = strrchr(data, '\n'); + if (newline == NULL) + col += strlen(data); + else + col = (int)strlen(newline); + + free(data); + break; + } + + default: /* Should never happen */ + return (-1); + } + + next = curr->child; + if (next == NULL) { + while ((next = curr->next) == NULL) { + if (curr == node) + break; + + curr = curr->parent; + if (curr->value.element.name[0] != '!' && + curr->value.element.name[0] != '?') { + col = mxml_write_ws( + curr, p, cb, + MXML_WS_BEFORE_CLOSE, col, + putc_cb); + if ((*putc_cb)('<', p) < 0) + return (-1); + if ((*putc_cb)('/', p) < 0) + return (-1); + if (mxml_write_string( + curr->value.element.name, p, + putc_cb) < 0) + return (-1); + if ((*putc_cb)('>', p) < 0) + return (-1); + col += strlen(curr->value.element.name) + + 3; + col = mxml_write_ws(curr, p, cb, + MXML_WS_AFTER_CLOSE, + col, putc_cb); + } + } + } + } + return col; +} + +/* + * 'mxml_write_string()' - Write a string, escaping & and < as needed. + */ + +static int /* O - 0 on success, -1 on failure */ +mxml_write_string(const char *s, /* I - String to write */ + void *p, /* I - Write pointer */ + _mxml_putc_cb_t putc_cb) +{ /* I - Write callback */ + const char *name; /* Entity name, if any */ + + while (*s) { + name = mxmlEntityGetName(*s); + if (name != NULL) { + if ((*putc_cb)('&', p) < 0) + return (-1); + while (*name) { + if ((*putc_cb)(*name, p) < 0) + return (-1); + name++; + } + if ((*putc_cb)(';', p) < 0) + return (-1); + } else if ((*putc_cb)(*s, p) < 0) + return (-1); + s++; + } + return 0; +} + +/* + * 'mxml_write_ws()' - Do whitespace callback... + */ + +static int /* O - New column */ +mxml_write_ws(mxml_node_t *node, /* I - Current node */ + void *p, /* I - Write pointer */ + mxml_save_cb_t cb, /* I - Callback function */ + int ws, /* I - Where value */ + int col, /* I - Current column */ + _mxml_putc_cb_t putc_cb) +{ /* I - Write callback */ + const char *s; /* Whitespace string */ + s = (*cb)(node, ws); + if (cb && s != NULL) { + while (*s) { + if ((*putc_cb)(*s, p) < 0) + return (-1); + else if (*s == '\n') + col = 0; + else if (*s == '\t') { + col += MXML_TAB; + col = col - (col % MXML_TAB); + } else + col++; + s++; + } + } + return col; +} diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-get.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-get.c new file mode 100644 index 000000000000..4e9c97f116f1 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-get.c @@ -0,0 +1,287 @@ +/* + * Node get functions for Mini-XML, a small XML file parsing library. + * + * Copyright 2014-2017 by Michael R Sweet. + * Copyright (C) 2019 XiaoMi, Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Michael R Sweet and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "COPYING" + * which should have been included with this file. If this file is + * missing or damaged, see the license at: + * + * https://michaelrsweet.github.io/mxml + */ + +/* + * Include necessary headers... + */ + +#include "config.h" +#include "mxml.h" + +/* + * 'mxmlGetCDATA()' - Get the value for a CDATA node. + * + * @code NULL@ is returned if the node is not a CDATA element. + * + * @since Mini-XML 2.7@ + */ + +const char * /* O - CDATA value or @code NULL@ */ +mxmlGetCDATA(mxml_node_t *node) +{ /* I - Node to get */ + + if (!node || node->type != MXML_ELEMENT || + strncmp(node->value.element.name, "![CDATA[", 8)) + return NULL; + /* Return the text following the CDATA declaration... */ + return (node->value.element.name + 8); +} + +/* + * 'mxmlGetCustom()' - Get the value for a custom node. + * + * @code NULL@ is returned if the node (or its first child) is not a custom + * value node. + * + * @since Mini-XML 2.7@ + */ + +const void * /* O - Custom value or @code NULL@ */ +mxmlGetCustom(mxml_node_t *node) +{ /* I - Node to get */ + if (!node) + return NULL; + + /* * Return the integer value... */ + + if (node->type == MXML_CUSTOM) + return node->value.custom.data; + else if (node->type == MXML_ELEMENT && node->child && + node->child->type == MXML_CUSTOM) + return node->child->value.custom.data; + else + return NULL; +} + +/* + * 'mxmlGetElement()' - Get the name for an element node. + * + * @code NULL@ is returned if the node is not an element node. + * + * @since Mini-XML 2.7@ + */ + +const char * /* O - Element name or @code NULL@ */ +mxmlGetElement(mxml_node_t *node) +{ /* I - Node to get */ + if (!node || node->type != MXML_ELEMENT) + return NULL; + /* * Return the element name... */ + return node->value.element.name; +} + +/* + * 'mxmlGetFirstChild()' - Get the first child of an element node. + * + * @code NULL@ is returned if the node is not an element node or if the node + * has no children. + * + * @since Mini-XML 2.7@ + */ + +mxml_node_t * /* O - First child or @code NULL@ */ +mxmlGetFirstChild(mxml_node_t *node) +{ /* I - Node to get */ + if (!node || node->type != MXML_ELEMENT) + return NULL; + /* * Return the first child node... */ + return node->child; +} + +/* + * 'mxmlGetInteger()' - Get the integer value from the specified node or its + * first child. + * + * 0 is returned if the node (or its first child) is not an integer value node. + * + * @since Mini-XML 2.7@ + */ + +int /* O - Integer value or 0 */ mxmlGetInteger(mxml_node_t *node) +{ /* I - Node to get */ + if (!node) + return 0; + + /* * Return the integer value... */ + + if (node->type == MXML_INTEGER) + return node->value.integer; + else if (node->type == MXML_ELEMENT && node->child && + node->child->type == MXML_INTEGER) + return node->child->value.integer; + else + return 0; +} + +/* + * 'mxmlGetLastChild()' - Get the last child of an element node. + * + * @code NULL@ is returned if the node is not an element node or if the node + * has no children. + * + * @since Mini-XML 2.7@ + */ + +mxml_node_t * /* O - Last child or @code NULL@ */ +mxmlGetLastChild(mxml_node_t *node) +{ /* I - Node to get */ + if (!node || node->type != MXML_ELEMENT) + return NULL; + /* * Return the node type... */ + return node->last_child; +} + +/* + * 'mxmlGetNextSibling()' - Get the next node for the current parent. + * + * @code NULL@ is returned if this is the last child for the current parent. + * + * @since Mini-XML 2.7@ + */ + +mxml_node_t *mxmlGetNextSibling(mxml_node_t *node) +{ /* I - Node to get */ + if (!node) + return NULL; + /* * Return the node type... */ + return node->next; +} + +/* + * 'mxmlGetOpaque()' - Get an opaque string value for a node or its first child. + * + * @code NULL@ is returned if the node (or its first child) is not an opaque + * value node. + * + * @since Mini-XML 2.7@ + */ + +const char * /* O - Opaque string or @code NULL@ */ +mxmlGetOpaque(mxml_node_t *node) +{ /* I - Node to get */ + if (!node) + return NULL; + /* * Return the integer value... */ + if (node->type == MXML_OPAQUE) + return node->value.opaque; + else if (node->type == MXML_ELEMENT && node->child && + node->child->type == MXML_OPAQUE) + return node->child->value.opaque; + else + return NULL; +} + +/* + * 'mxmlGetParent()' - Get the parent node. + * + * @code NULL@ is returned for a root node. + * + * @since Mini-XML 2.7@ + */ + +mxml_node_t * /* O - Parent node or @code NULL@ */ +mxmlGetParent(mxml_node_t *node) +{ /* I - Node to get */ + if (!node) + return NULL; + /* * Return the node type... */ + return node->parent; +} + +/* + * 'mxmlGetPrevSibling()' - Get the previous node for the current parent. + * + * @code NULL@ is returned if this is the first child for the current parent. + * + * @since Mini-XML 2.7@ + */ + +mxml_node_t * /* O - Previous node or @code NULL@ */ +mxmlGetPrevSibling(mxml_node_t *node) +{ /* I - Node to get */ + if (!node) + return NULL; + /* * Return the node type... */ + return node->prev; +} + +/* + * 'mxmlGetText()' - Get the text value for a node or its first child. + * + * @code NULL@ is returned if the node (or its first child) is not a text node. + * The "whitespace" argument can be @code NULL@. + * + * @since Mini-XML 2.7@ + */ + +const char * /* O - Text string or @code NULL@ */ +mxmlGetText(mxml_node_t *node, /* I - Node to get */ + int *whitespace) +{ /* O - 1 if string is preceded by whitespace, 0 otherwise */ + if (!node) { + if (whitespace) + *whitespace = 0; + return NULL; + } + if (node->type == MXML_TEXT) { + if (whitespace) + *whitespace = node->value.text.whitespace; + + return node->value.text.string; + } else if (node->type == MXML_ELEMENT && node->child && + node->child->type == MXML_TEXT) { + if (whitespace) + *whitespace = node->child->value.text.whitespace; + return node->child->value.text.string; + } else { + if (whitespace) + *whitespace = 0; + return NULL; + } +} + +/* + * 'mxmlGetType()' - Get the node type. + * + * @code MXML_IGNORE@ is returned if "node" is @code NULL@. + * + * @since Mini-XML 2.7@ + */ + +mxml_type_t /* O - Type of node */ +mxmlGetType(mxml_node_t *node) +{ /* I - Node to get */ + if (!node) + return MXML_IGNORE; + /* * Return the node type... */ + return node->type; +} + +/* + * 'mxmlGetUserData()' - Get the user data pointer for a node. + * + * @since Mini-XML 2.7@ + */ + +void * /* O - User data pointer */ +mxmlGetUserData(mxml_node_t *node) +{ /* I - Node to get */ + if (!node) + return NULL; + /* + * Return the user data pointer... + */ + return node->user_data; +} diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-index.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-index.c new file mode 100644 index 000000000000..b55ab95c4a83 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-index.c @@ -0,0 +1,358 @@ +/* + * Index support code for Mini-XML, a small XML file parsing library. + * + * Copyright 2003-2017 by Michael R Sweet. + * Copyright (C) 2019 XiaoMi, Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Michael R Sweet and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "COPYING" + * which should have been included with this file. If this file is + * missing or damaged, see the license at: + * + * https://michaelrsweet.github.io/mxml + */ + +/* + * Include necessary headers... + */ + +#include "config.h" +#include "mxml.h" + +/* + * Sort functions... + */ + +static int index_compare(mxml_index_t *ind, mxml_node_t *first, + mxml_node_t *second); +static int index_find(mxml_index_t *ind, const char *element, const char *value, + mxml_node_t *node); +static void index_sort(mxml_index_t *ind, int left, int right); + +/* + * 'mxmlIndexDelete()' - Delete an index. + */ + +void mxmlIndexDelete(mxml_index_t *ind) +{ /* I - Index to delete */ + if (!ind) + return; + if (ind->attr) + free(ind->attr); + if (ind->alloc_nodes) + free(ind->nodes); + free(ind); +} + +/* + * 'mxmlIndexEnum()' - Return the next node in the index. + * + * You should call @link mxmlIndexReset@ prior to using this function to get + * the first node in the index. Nodes are returned in the sorted order of the + * index. + */ + +mxml_node_t * /* O - Next node or @code NULL@ if there is none */ +mxmlIndexEnum(mxml_index_t *ind) +{ /* I - Index to enumerate */ + if (!ind) + return NULL; + if (ind->cur_node < ind->num_nodes) + return ind->nodes[ind->cur_node++]; + else + return NULL; +} + +/* + * 'mxmlIndexFind()' - Find the next matching node. + * + * You should call @link mxmlIndexReset@ prior to using this function for + * the first time with a particular set of "element" and "value" + * strings. Passing @code NULL@ for both "element" and "value" is equivalent + * to calling @link mxmlIndexEnum@. + */ + +mxml_node_t * /* O - Node or @code NULL@ if none found */ +mxmlIndexFind(mxml_index_t *ind, /* I - Index to search */ + const char *element, /* I - Element name to find, if any */ + const char *value) +{ /* I - Attribute value, if any */ + int diff, /* Difference between names */ + curr, /* Current entity in search */ + first, /* First entity in search */ + last; /* Last entity in search */ + + if (!ind || (!ind->attr && value)) { + return NULL; + } + + /* + * If both element and value are NULL, just enumerate the nodes in the + * index... + */ + + if (!element && !value) + return mxmlIndexEnum(ind); + + /* * If there are no nodes in the index, return NULL... */ + + if (!ind->num_nodes) { + return NULL; + } + + /* * If cur_node == 0, then find the first matching node... */ + if (ind->cur_node == 0) { + /* * Find the first node using a modified binary search algorithm... */ + first = 0; + last = ind->num_nodes - 1; + while ((last - first) > 1) { + curr = (first + last) / 2; + diff = index_find(ind, element, value, + ind->nodes[curr]); + if (diff == 0) { + /* * Found a match, move back to find the first... */ + while (curr > 0 && + !index_find(ind, element, value, + ind->nodes[curr - 1])) + curr--; + /* * Return the first match and save the index to the next... */ + ind->cur_node = curr + 1; + return ind->nodes[curr]; + } else if (diff < 0) + last = curr; + else + first = curr; + } + /* * If we get this far, then we found exactly 0 or 1 matches... */ + for (curr = first; curr <= last; curr++) + if (!index_find(ind, element, value, + ind->nodes[curr])) { + /* * Found exactly one (or possibly two) match... */ + ind->cur_node = curr + 1; + return ind->nodes[curr]; + } + ind->cur_node = ind->num_nodes; + return NULL; + } else if (ind->cur_node < ind->num_nodes && + !index_find(ind, element, value, + ind->nodes[ind->cur_node])) { + /* * Return the next matching node... */ + return ind->nodes[ind->cur_node++]; + } + /* * If we get this far, then we have no matches... */ + ind->cur_node = ind->num_nodes; + return NULL; +} + +/* + * 'mxmlIndexGetCount()' - Get the number of nodes in an index. + * + * @since Mini-XML 2.7@ + */ + +int /* I - Number of nodes in index */ mxmlIndexGetCount(mxml_index_t *ind) +{ /* I - Index of nodes */ + if (!ind) + return 0; + /* + * Return the number of nodes in the index... + */ + return ind->num_nodes; +} + +/* + * 'mxmlIndexNew()' - Create a new index. + * + * The index will contain all nodes that contain the named element and/or + * attribute. If both "element" and "attr" are @code NULL@, then the index will + * contain a sorted list of the elements in the node tree. Nodes are + * sorted by element name and optionally by attribute value if the "attr" + * argument is not NULL. + */ + +mxml_index_t * /* O - New index */ +mxmlIndexNew( + mxml_node_t *node, /* I - XML node tree */ + const char *element, /* I - Element to index or @code NULL@ for all */ + const char *attr) +{ /* I - Attribute to index or @code NULL@ for none */ + mxml_index_t *ind; /* New index */ + mxml_node_t *curr, /* Current node in index */ + **temp; /* Temporary node pointer array */ + + if (!node) + return NULL; + + ind = calloc(1, sizeof(mxml_index_t)); + if (ind == NULL) { + mxml_error("Unable to allocate %d bytes for index - %s", + sizeof(mxml_index_t), NULL); + return NULL; + } + + if (attr) + ind->attr = strdup(attr); + + if (!element && !attr) + curr = node; + else + curr = mxmlFindElement(node, node, element, attr, NULL, + MXML_DESCEND); + + while (curr) { + if (ind->num_nodes >= ind->alloc_nodes) { + if (!ind->alloc_nodes) + temp = malloc(64 * sizeof(mxml_node_t *)); + else + temp = realloc(ind->nodes, + (ind->alloc_nodes + 64) * + sizeof(mxml_node_t *)); + if (!temp) { + /* * Unable to allocate memory for the index, so abort... */ + mxml_error( + "Unable to allocate %d bytes for index: %s", + (ind->alloc_nodes + 64) * + sizeof(mxml_node_t *), + NULL); + mxmlIndexDelete(ind); + return NULL; + } + ind->nodes = temp; + ind->alloc_nodes += 64; + } + ind->nodes[ind->num_nodes++] = curr; + curr = mxmlFindElement(curr, node, element, attr, NULL, + MXML_DESCEND); + } + + /* + * Sort nodes based upon the search criteria... + */ + + if (ind->num_nodes > 1) + index_sort(ind, 0, ind->num_nodes - 1); + return ind; +} + +/* + * 'mxmlIndexReset()' - Reset the enumeration/find pointer in the index and + * return the first node in the index. + * + * This function should be called prior to using @link mxmlIndexEnum@ or + * @link mxmlIndexFind@ for the first time. + */ + +mxml_node_t * /* O - First node or @code NULL@ if there is none */ +mxmlIndexReset(mxml_index_t *ind) +{ /* I - Index to reset */ + if (!ind) + return NULL; + + /* * Set the index to the first element... */ + ind->cur_node = 0; + if (ind->num_nodes) + return ind->nodes[0]; + else + return NULL; +} + +/* + * 'index_compare()' - Compare two nodes. + */ + +static int /* O - Result of comparison */ +index_compare(mxml_index_t *ind, /* I - Index */ + mxml_node_t *first, /* I - First node */ + mxml_node_t *second) +{ /* I - Second node */ + int diff; /* Difference */ + diff = strcmp(first->value.element.name, second->value.element.name); + if (diff != 0) + return diff; + if (ind->attr) { + diff = strcmp(mxmlElementGetAttr(first, ind->attr), + mxmlElementGetAttr(second, ind->attr)); + if (diff != 0) + return diff; + } + return 0; +} + +/* + * 'index_find()' - Compare a node with index values. + */ + +static int /* O - Result of comparison */ +index_find(mxml_index_t *ind, /* I - Index */ + const char *element, /* I - Element name or @code NULL@ */ + const char *value, /* I - Attribute value or @code NULL@ */ + mxml_node_t *node) +{ /* I - Node */ + int diff; /* Difference */ + if (element) { + diff = strcmp(element, node->value.element.name); + if (diff != 0) + return diff; + } + if (value) { + diff = strcmp(value, mxmlElementGetAttr(node, ind->attr)); + if (diff != 0) + return diff; + } + return 0; +} + +/* + * 'index_sort()' - Sort the nodes in the index... + * + * This function implements the classic quicksort algorithm... + */ + +static void index_sort(mxml_index_t *ind, /* I - Index to sort */ + int left, /* I - Left node in partition */ + int right) +{ /* I - Right node in partition */ + mxml_node_t *pivot, /* Pivot node */ + *temp; /* Swap node */ + int templ, /* Temporary left node */ + tempr; /* Temporary right node */ + + /* * Loop until we have sorted all the way to the right... */ + + do { + /* * Sort the pivot in the curr partition... */ + pivot = ind->nodes[left]; + for (templ = left, tempr = right; templ < tempr;) { + /* * Move left while left node <= pivot node... */ + while ((templ < right) && + index_compare(ind, ind->nodes[templ], pivot) <= + 0) + templ++; + /* * Move right while right node > pivot node... */ + while ((tempr > left) && + index_compare(ind, ind->nodes[tempr], pivot) > 0) + tempr--; + /* * Swap nodes if needed... */ + if (templ < tempr) { + temp = ind->nodes[templ]; + ind->nodes[templ] = ind->nodes[tempr]; + ind->nodes[tempr] = temp; + } + } + + /* + * When we get here, the right (tempr) node is the new position for the + * pivot node... + */ + + if (index_compare(ind, pivot, ind->nodes[tempr]) > 0) { + ind->nodes[left] = ind->nodes[tempr]; + ind->nodes[tempr] = pivot; + } + + /* * Recursively sort the left partition as needed... */ + if (left < (tempr - 1)) + index_sort(ind, left, tempr - 1); + } while (right > (left = tempr + 1)); +} diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-node.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-node.c new file mode 100644 index 000000000000..c8a3fcbd67db --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-node.c @@ -0,0 +1,551 @@ +/* + * Node support code for Mini-XML, a small XML file parsing library. + * + * Copyright 2003-2017 by Michael R Sweet. + * Copyright (C) 2019 XiaoMi, Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Michael R Sweet and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "COPYING" + * which should have been included with this file. If this file is + * missing or damaged, see the license at: + * + * https://michaelrsweet.github.io/mxml + */ + +/* + * Include necessary headers... + */ + +#include "config.h" +#include "mxml.h" + +/* + * Local functions... + */ + +static void mxml_free(mxml_node_t *node); +static mxml_node_t *mxml_new(mxml_node_t *parent, mxml_type_t type); + +/* + * 'mxmlAdd()' - Add a node to a tree. + * + * Adds the specified node to the parent. If the child argument is not + * @code NULL@, puts the new node before or after the specified child depending + * on the value of the where argument. If the child argument is @code NULL@, + * puts the new node at the beginning of the child list (@code MXML_ADD_BEFORE@) + * or at the end of the child list (@code MXML_ADD_AFTER@). The constant + * @code MXML_ADD_TO_PARENT@ can be used to specify a @code NULL@ child pointer. + */ + +void mxmlAdd( + mxml_node_t *parent, /* I - Parent node */ + int where, /* I - Where to add, @code MXML_ADD_BEFORE@ or @code MXML_ADD_AFTER@ */ + mxml_node_t * + child, /* I - Child node for where or @code MXML_ADD_TO_PARENT@ */ + mxml_node_t *node) +{ /* I - Node to add */ + + /* Range check input... */ + + if (!parent || !node) + return; + + /* Remove the node from any existing parent... */ + if (node->parent) + mxmlRemove(node); + + /* Reset pointers... */ + + node->parent = parent; + switch (where) { + case MXML_ADD_BEFORE: + if (!child || child == parent->child || + child->parent != parent) { + /* Insert as first node under parent... */ + node->next = parent->child; + if (parent->child) + parent->child->prev = node; + else + parent->last_child = node; + parent->child = node; + } else { + /* Insert node before this child... */ + node->next = child; + node->prev = child->prev; + if (child->prev) + child->prev->next = node; + else + parent->child = node; + child->prev = node; + } + break; + + case MXML_ADD_AFTER: + if (!child || child == parent->last_child || + child->parent != parent) { + /* Insert as last node under parent... */ + node->parent = parent; + node->prev = parent->last_child; + if (parent->last_child) + parent->last_child->next = node; + else + parent->child = node; + parent->last_child = node; + } else { + /* Insert node after this child... */ + node->prev = child; + node->next = child->next; + if (child->next) + child->next->prev = node; + else + parent->last_child = node; + child->next = node; + } + break; + } +} + +/* + * 'mxmlDelete()' - Delete a node and all of its children. + * + * If the specified node has a parent, this function first removes the + * node from its parent using the @link mxmlRemove@ function. + */ + +void mxmlDelete(mxml_node_t *node) +{ /* I - Node to delete */ + mxml_node_t *curr, /* Current node */ + *next; /* Next node */ + + /* Range check input... */ + + if (!node) + return; + /* Remove the node from its parent, if any... */ + mxmlRemove(node); + /* Delete children... */ + for (curr = node->child; curr; curr = next) { + /* Get the next node... */ + next = curr->child; + if (next != NULL) { + /* Free parent nodes after child nodes have been freed... */ + curr->child = NULL; + continue; + } + next = curr->next; + if (next == NULL) { + /* Next node is the parent, which we'll free as needed... */ + next = curr->parent; + if (next == node) + next = NULL; + } + /* Free child... */ + mxml_free(curr); + } + /* Then free the memory used by the parent node... */ + mxml_free(node); +} + +/* + * 'mxmlGetRefCount()' - Get the current reference (use) count for a node. + * + * The initial reference count of new nodes is 1. Use the @link mxmlRetain@ + * and @link mxmlRelease@ functions to increment and decrement a node's + * reference count. + * + * @since Mini-XML 2.7@. + */ + +int /* O - Reference count */ mxmlGetRefCount(mxml_node_t *node) +{ /* I - Node */ + /* Range check input... */ + + if (!node) + return 0; + /* Return the reference count... */ + return node->ref_count; +} + +/* + * 'mxmlNewCDATA()' - Create a new CDATA node. + * + * The new CDATA node is added to the end of the specified parent's child + * list. The constant @code MXML_NO_PARENT@ can be used to specify that the new + * CDATA node has no parent. The data string must be nul-terminated and + * is copied into the new node. CDATA nodes currently use the + * @code MXML_ELEMENT@ type. + * + * @since Mini-XML 2.3@ + */ + +mxml_node_t * /* O - New node */ +mxmlNewCDATA(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ + const char *data) +{ /* I - Data string */ + mxml_node_t *node; /* New node */ + + /* Range check input... */ + + if (!data) + return NULL; + + /* Create the node and set the name value... */ + node = mxml_new(parent, MXML_ELEMENT); + if (node != NULL) + node->value.element.name = _mxml_strdupf("![CDATA[%s]]", data); + return node; +} + +/* + * 'mxmlNewCustom()' - Create a new custom data node. + * + * The new custom node is added to the end of the specified parent's child + * list. The constant @code MXML_NO_PARENT@ can be used to specify that the new + * element node has no parent. @code NULL@ can be passed when the data in the + * node is not dynamically allocated or is separately managed. + * + * @since Mini-XML 2.1@ + */ + +mxml_node_t * /* O - New node */ +mxmlNewCustom(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ + void *data, /* I - Pointer to data */ + mxml_custom_destroy_cb_t destroy) +{ /* I - Function to destroy data */ + mxml_node_t *node; /* New node */ + + /* Create the node and set the value... */ + node = mxml_new(parent, MXML_CUSTOM); + if (node != NULL) { + node->value.custom.data = data; + node->value.custom.destroy = destroy; + } + return node; +} + +/* + * 'mxmlNewElement()' - Create a new element node. + * + * The new element node is added to the end of the specified parent's child + * list. The constant @code MXML_NO_PARENT@ can be used to specify that the new + * element node has no parent. + */ + +mxml_node_t * /* O - New node */ +mxmlNewElement( + mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ + const char *name) +{ /* I - Name of element */ + mxml_node_t *node; /* New node */ + + /* Range check input... */ + + if (!name) + return NULL; + + /* Create the node and set the element name... */ + node = mxml_new(parent, MXML_ELEMENT); + if (node != NULL) + node->value.element.name = strdup(name); + return node; +} + +/* + * 'mxmlNewInteger()' - Create a new integer node. + * + * The new integer node is added to the end of the specified parent's child + * list. The constant @code MXML_NO_PARENT@ can be used to specify that the new + * integer node has no parent. + */ + +mxml_node_t * /* O - New node */ +mxmlNewInteger( + mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ + int integer) +{ /* I - Integer value */ + mxml_node_t *node; /* New node */ + + /* Create the node and set the element name... */ + node = mxml_new(parent, MXML_INTEGER); + if (node != NULL) + node->value.integer = integer; + return node; +} + +/* + * 'mxmlNewOpaque()' - Create a new opaque string. + * + * The new opaque string node is added to the end of the specified parent's + * child list. The constant @code MXML_NO_PARENT@ can be used to specify that + * the new opaque string node has no parent. The opaque string must be nul- + * terminated and is copied into the new node. + */ + +mxml_node_t * /* O - New node */ +mxmlNewOpaque(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ + const char *opaque) +{ /* I - Opaque string */ + mxml_node_t *node; /* New node */ + + /* * Range check input... */ + if (!opaque) + return NULL; + /* Create the node and set the element name... */ + node = mxml_new(parent, MXML_OPAQUE); + if (node != NULL) + node->value.opaque = strdup(opaque); + return node; +} + +/* + * 'mxmlNewOpaquef()' - Create a new formatted opaque string node. + * + * The new opaque string node is added to the end of the specified parent's + * child list. The constant @code MXML_NO_PARENT@ can be used to specify that + * the new opaque string node has no parent. The format string must be + * nul-terminated and is formatted into the new node. + */ + +mxml_node_t * /* O - New node */ +mxmlNewOpaquef( + mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ + const char *format, /* I - Printf-style format string */ + ...) +{ /* I - Additional args as needed */ + mxml_node_t *node; /* New node */ + va_list ap; /* Pointer to arguments */ + + /* Range check input... */ + if (!format) + return NULL; + /* Create the node and set the text value... */ + node = mxml_new(parent, MXML_OPAQUE); + if (node != NULL) { + va_start(ap, format); + node->value.opaque = _mxml_vstrdupf(format, ap); + va_end(ap); + } + return node; +} + +/* + * 'mxmlNewText()' - Create a new text fragment node. + * + * The new text node is added to the end of the specified parent's child + * list. The constant @code MXML_NO_PARENT@ can be used to specify that the new + * text node has no parent. The whitespace parameter is used to specify + * whether leading whitespace is present before the node. The text + * string must be nul-terminated and is copied into the new node. + */ + +mxml_node_t * /* O - New node */ +mxmlNewText(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ + int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ + const char *string) +{ /* I - String */ + mxml_node_t *node; /* New node */ + + /* Range check input... */ + + if (!string) + return NULL; + /* Create the node and set the text value... */ + node = mxml_new(parent, MXML_TEXT); + if (node != NULL) { + node->value.text.whitespace = whitespace; + node->value.text.string = strdup(string); + } + return node; +} + +/* + * 'mxmlNewTextf()' - Create a new formatted text fragment node. + * + * The new text node is added to the end of the specified parent's child + * list. The constant @code MXML_NO_PARENT@ can be used to specify that the new + * text node has no parent. The whitespace parameter is used to specify + * whether leading whitespace is present before the node. The format + * string must be nul-terminated and is formatted into the new node. + */ + +mxml_node_t * /* O - New node */ +mxmlNewTextf(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ + int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ + const char *format, /* I - Printf-style format string */ + ...) +{ /* I - Additional args as needed */ + mxml_node_t *node; /* New node */ + va_list ap; /* Pointer to arguments */ + + /* Range check input... */ + if (!format) + return NULL; + + /* Create the node and set the text value... */ + node = mxml_new(parent, MXML_TEXT); + if (node != NULL) { + va_start(ap, format); + node->value.text.whitespace = whitespace; + node->value.text.string = _mxml_vstrdupf(format, ap); + va_end(ap); + } + return node; +} + +/* + * 'mxmlRemove()' - Remove a node from its parent. + * + * This function does not free memory used by the node - use @link mxmlDelete@ + * for that. This function does nothing if the node has no parent. + */ + +void mxmlRemove(mxml_node_t *node) +{ /* I - Node to remove */ + + /* Range check input... */ + if (!node || !node->parent) + return; + + /* Remove from parent... */ + if (node->prev) + node->prev->next = node->next; + else + node->parent->child = node->next; + if (node->next) + node->next->prev = node->prev; + else + node->parent->last_child = node->prev; + node->parent = NULL; + node->prev = NULL; + node->next = NULL; +} + +/* + * 'mxmlNewXML()' - Create a new XML document tree. + * + * The "version" argument specifies the version number to put in the + * ?xml element node. If @code NULL@, version "1.0" is assumed. + * + * @since Mini-XML 2.3@ + */ + +mxml_node_t * /* O - New ?xml node */ +mxmlNewXML(const char *version) +{ /* I - Version number to use */ + char element[1024]; /* Element text */ + snprintf(element, sizeof(element), + "?xml version=\"%s\" encoding=\"utf-8\"?", + version ? version : "1.0"); + return mxmlNewElement(NULL, element); +} + +/* + * 'mxmlRelease()' - Release a node. + * + * When the reference count reaches zero, the node (and any children) + * is deleted via @link mxmlDelete@. + * + * @since Mini-XML 2.3@ + */ + +int /* O - New reference count */ mxmlRelease(mxml_node_t *node) +{ /* I - Node */ + if (node) { + if ((--node->ref_count) <= 0) { + mxmlDelete(node); + return 0; + } else + return node->ref_count; + } else + return (-1); +} + +/* + * 'mxmlRetain()' - Retain a node. + * + * @since Mini-XML 2.3@ + */ + +int /* O - New reference count */ mxmlRetain(mxml_node_t *node) +{ /* I - Node */ + if (node) + return (++node->ref_count); + else + return (-1); +} + +/* + * 'mxml_free()' - Free the memory used by a node. + * + * Note: Does not free child nodes, does not remove from parent. + */ + +static void mxml_free(mxml_node_t *node) +{ /* I - Node */ + int i; /* Looping var */ + + switch (node->type) { + case MXML_ELEMENT: + if (node->value.element.name) + free(node->value.element.name); + + if (node->value.element.num_attrs) { + for (i = 0; i < node->value.element.num_attrs; i++) { + if (node->value.element.attrs[i].name) + free(node->value.element.attrs[i].name); + if (node->value.element.attrs[i].value) + free(node->value.element.attrs[i].value); + } + free(node->value.element.attrs); + } + break; + case MXML_INTEGER: + /* Nothing to do */ + break; + case MXML_OPAQUE: + if (node->value.opaque) + free(node->value.opaque); + break; + case MXML_REAL: + /* Nothing to do */ + break; + case MXML_TEXT: + if (node->value.text.string) + free(node->value.text.string); + break; + case MXML_CUSTOM: + if (node->value.custom.data && node->value.custom.destroy) + (*(node->value.custom.destroy))( + node->value.custom.data); + break; + default: + break; + } + free(node); +} + +/* + * 'mxml_new()' - Create a new node. + */ + +static mxml_node_t * /* O - New node */ +mxml_new(mxml_node_t *parent, /* I - Parent node */ + mxml_type_t type) +{ /* I - Node type */ + mxml_node_t *node; /* New node */ + + /* Allocate memory for the node... */ + node = calloc(1, sizeof(mxml_node_t)); + if (node == NULL) { + return NULL; + } + /* Set the node type... */ + node->type = type; + node->ref_count = 1; + /* Add to the parent if present... */ + if (parent) + mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node); + /* Return the new node... */ + return node; +} diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-private.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-private.c new file mode 100644 index 000000000000..b8553299b956 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-private.c @@ -0,0 +1,267 @@ +/* + * Private functions for Mini-XML, a small XML file parsing library. + * + * Copyright 2003-2017 by Michael R Sweet. + * Copyright (C) 2019 XiaoMi, Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Michael R Sweet and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "COPYING" + * which should have been included with this file. If this file is + * missing or damaged, see the license at: + * + * https://michaelrsweet.github.io/mxml + */ + +/* + * Include necessary headers... + */ + +#include "mxml-private.h" + +/* + * Some crazy people think that unloading a shared object is a good or safe + * thing to do. Unfortunately, most objects are simply *not* safe to unload + * and bad things *will* happen. + * + * The following mess of conditional code allows us to provide a destructor + * function in Mini-XML for our thread-global storage so that it can possibly + * be unloaded safely, although since there is no standard way to do so I + * can't even provide any guarantees that you can do it safely on all platforms. + * + * This code currently supports AIX, HP-UX, Linux, Mac OS X, Solaris, and + * Windows. It might work on the BSDs and IRIX, but I haven't tested that. + */ + +#if defined(__sun) || defined(_AIX) +#pragma fini(_mxml_fini) +#define _MXML_FINI _mxml_fini +#elif defined(__hpux) +#pragma FINI _mxml_fini +#define _MXML_FINI _mxml_fini +#elif defined(__GNUC__) /* Linux and Mac OS X */ +#define _MXML_FINI (__attribute((destructor)) _mxml_fini) +#else +#define _MXML_FINI _fini +#endif /* __sun */ + +/* + * 'mxml_error()' - Display an error message. + */ + +void mxml_error(const char *format, /* I - Printf-style format string */ + ...) +{ /* I - Additional arguments as needed */ + va_list ap; /* Pointer to arguments */ + char s[1024]; /* Message string */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + /* Range check input... */ + + if (!format) + return; + + /* Format the error message string... */ + + va_start(ap, format); + vsnprintf(s, sizeof(s), format, ap); + va_end(ap); + /* * And then display the error message... */ + if (global->error_cb) + (*global->error_cb)(s); +} + +/* + * 'mxml_ignore_cb()' - Default callback for ignored values. + */ + +mxml_type_t /* O - Node type */ +mxml_ignore_cb(mxml_node_t *node) +{ /* I - Current node */ + (void)node; + return MXML_IGNORE; +} + +/* + * 'mxml_integer_cb()' - Default callback for integer values. + */ + +mxml_type_t /* O - Node type */ +mxml_integer_cb(mxml_node_t *node) +{ /* I - Current node */ + (void)node; + return MXML_INTEGER; +} + +/* + * 'mxml_opaque_cb()' - Default callback for opaque values. + */ + +mxml_type_t /* O - Node type */ +mxml_opaque_cb(mxml_node_t *node) +{ /* I - Current node */ + (void)node; + return MXML_OPAQUE; +} + +/* + * 'mxml_real_cb()' - Default callback for real number values. + */ + +mxml_type_t /* O - Node type */ +mxml_real_cb(mxml_node_t *node) +{ /* I - Current node */ + (void)node; + return MXML_REAL; +} + +#ifdef HAVE_PTHREAD_H /**** POSIX threading ****/ +#include + +static pthread_key_t _mxml_key = -1; /* Thread local storage key */ +static pthread_once_t _mxml_key_once = PTHREAD_ONCE_INIT; +/* One-time initialization object */ +static void _mxml_init(void); +static void _mxml_destructor(void *g); + +/* + * '_mxml_destructor()' - Free memory used for globals... + */ + +static void _mxml_destructor(void *g) +{ /* I - Global data */ + free(g); +} + +/* + * '_mxml_fini()' - Clean up when unloaded. + */ + +static void _MXML_FINI(void) +{ + _mxml_global_t *global; /* Global data */ + if (_mxml_key != -1) { + global = (_mxml_global_t *)pthread_getspecific(_mxml_key); + if (global != NULL) + _mxml_destructor(global); + pthread_key_delete(_mxml_key); + _mxml_key = -1; + } +} + +/* + * '_mxml_global()' - Get global data. + */ + +_mxml_global_t * /* O - Global data */ +_mxml_global(void) +{ + _mxml_global_t *global; /* Global data */ + pthread_once(&_mxml_key_once, _mxml_init); + global = (_mxml_global_t *)pthread_getspecific(_mxml_key); + if (global == NULL) { + global = (_mxml_global_t *)calloc(1, sizeof(_mxml_global_t)); + pthread_setspecific(_mxml_key, global); + global->num_entity_cbs = 1; + global->entity_cbs[0] = _mxml_entity_cb; + global->wrap = 72; + } + return global; +} + +/* + * '_mxml_init()' - Initialize global data... + */ + +static void _mxml_init(void) +{ + pthread_key_create(&_mxml_key, _mxml_destructor); +} + +#elif defined(WIN32) && defined(MXML1_EXPORTS) /**** WIN32 threading ****/ +#include + +static DWORD _mxml_tls_index; /* Index for global storage */ + +/* + * 'DllMain()' - Main entry for library. + */ + +BOOL WINAPI /* O - Success/failure */ +DllMain(HINSTANCE hinst, /* I - DLL module handle */ + DWORD reason, /* I - Reason */ + LPVOID reserved) +{ /* I - Unused */ + _mxml_global_t *global; /* Global data */ + (void)hinst; + (void)reserved; + + switch (reason) { + case DLL_PROCESS_ATTACH: /* Called on library initialization */ + _mxml_tls_index = TlsAlloc(); + if (_mxml_tls_index == TLS_OUT_OF_INDEXES) + return FALSE; + break; + + case DLL_THREAD_DETACH: /* Called when a thread terminates */ + global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index); + if (global != NULL) + free(global); + break; + + case DLL_PROCESS_DETACH: /* Called when library is unloaded */ + global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index); + if (global != NULL) + free(global); + + TlsFree(_mxml_tls_index); + break; + + default: + break; + } + + return TRUE; +} + +/* + * '_mxml_global()' - Get global data. + */ + +_mxml_global_t * /* O - Global data */ +_mxml_global(void) +{ + _mxml_global_t *global; /* Global data */ + global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index); + if (global == NULL) { + global = (_mxml_global_t *)calloc(1, sizeof(_mxml_global_t)); + global->num_entity_cbs = 1; + global->entity_cbs[0] = _mxml_entity_cb; + global->wrap = 72; + TlsSetValue(_mxml_tls_index, (LPVOID)global); + } + return global; +} + +#else /**** No threading ****/ +/* + * '_mxml_global()' - Get global data. + */ + +_mxml_global_t * /* O - Global data */ +_mxml_global(void) +{ + static _mxml_global_t global = /* Global data */ + { + NULL, /* error_cb */ + 1, /* num_entity_cbs */ + { _mxml_entity_cb }, /* entity_cbs */ + 72, /* wrap */ + NULL, /* custom_load_cb */ + NULL /* custom_save_cb */ + }; + + return &global; +} +#endif /* HAVE_PTHREAD_H */ diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-private.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-private.h new file mode 100644 index 000000000000..51b1c41a8848 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-private.h @@ -0,0 +1,41 @@ +/* + * Private definitions for Mini-XML, a small XML file parsing library. + * + * Copyright 2003-2017 by Michael R Sweet. + * Copyright (C) 2019 XiaoMi, Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Michael R Sweet and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "COPYING" + * which should have been included with this file. If this file is + * missing or damaged, see the license at: + * + * https://michaelrsweet.github.io/mxml + */ + +/* + * Include necessary headers... + */ + +#include "config.h" +#include "mxml.h" + +/* + * Global, per-thread data... + */ + +typedef struct _mxml_global_s { + void (*error_cb)(const char *); + int num_entity_cbs; + int (*entity_cbs[100])(const char *name); + int wrap; + mxml_custom_load_cb_t custom_load_cb; + mxml_custom_save_cb_t custom_save_cb; +} _mxml_global_t; + +/* + * Functions... + */ + +extern _mxml_global_t *_mxml_global(void); +extern int _mxml_entity_cb(const char *name); diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-search.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-search.c new file mode 100644 index 000000000000..0291641c180d --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-search.c @@ -0,0 +1,196 @@ +/* + * Search/navigation functions for Mini-XML, a small XML file parsing library. + * + * Copyright 2003-2017 by Michael R Sweet. + * Copyright (C) 2019 XiaoMi, Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Michael R Sweet and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "COPYING" + * which should have been included with this file. If this file is + * missing or damaged, see the license at: + * + * https://michaelrsweet.github.io/mxml + */ + +/* + * Include necessary headers... + */ + +#include "config.h" +#include "mxml.h" + +/* + * 'mxmlFindElement()' - Find the named element. + * + * The search is constrained by the name, attribute name, and value; any + * @code NULL@ names or values are treated as wildcards, so different kinds of + * searches can be implemented by looking for all elements of a given name + * or all elements with a specific attribute. The descend argument determines + * whether the search descends into child nodes; normally you will use + * @code MXML_DESCEND_FIRST@ for the initial search and @code MXML_NO_DESCEND@ + * to find additional direct descendents of the node. The top node argument + * constrains the search to a particular node's children. + */ + +mxml_node_t * /* O - Element node or @code NULL@ */ +mxmlFindElement( + mxml_node_t *node, /* I - Current node */ + mxml_node_t *top, /* I - Top node */ + const char *element, /* I - Element name or @code NULL@ for any */ + const char *attr, /* I - Attribute name, or @code NULL@ for none */ + const char *value, /* I - Attribute value, or @code NULL@ for any */ + int descend) +{ /* I - Descend into tree - @code MXML_DESCEND@, @code MXML_NO_DESCEND@, or @code MXML_DESCEND_FIRST@ */ + const char *temp; /* Current attribute value */ + if (!node || !top || (!attr && value)) + return NULL; + /* * Start with the next node... */ + node = mxmlWalkNext(node, top, descend); + /* * Loop until we find a matching element... */ + while (node != NULL) { + /* * See if this node matches... */ + if (node->type == MXML_ELEMENT && node->value.element.name && + (!element || !strcmp(node->value.element.name, element))) { + /* * See if we need to check for an attribute... */ + if (!attr) + return node; + /* * Check for the attribute... */ + temp = mxmlElementGetAttr(node, attr); + if (temp != NULL) { + /* * OK, we have the attribute, does it match? */ + if (!value || !strcmp(value, temp)) + return node; /* Yes, return it... */ + } + } + /* * No match, move on to the next node... */ + if (descend == MXML_DESCEND) + node = mxmlWalkNext(node, top, MXML_DESCEND); + else + node = node->next; + } + return NULL; +} + +/* + * 'mxmlFindPath()' - Find a node with the given path. + * + * The "path" is a slash-separated list of element names. The name "*" is + * considered a wildcard for one or more levels of elements. For example, + * "foo/one/two", "bar/two/one", "*\/one", and so forth. + * + * The first child node of the found node is returned if the given node has + * children and the first child is a value node. + * + * @since Mini-XML 2.7@ + */ + +mxml_node_t * /* O - Found node or @code NULL@ */ +mxmlFindPath(mxml_node_t *top, /* I - Top node */ + const char *path) +{ /* I - Path to element */ + mxml_node_t *node; /* Current node */ + char element[256]; /* Current element name */ + const char *pathsep; /* Separator in path */ + int descend; /* mxmlFindElement option */ + + if (!top || !path || !*path) + return NULL; + /* * Search each element in the path... */ + + node = top; + while (*path) { + /* * Handle wildcards... */ + if (!strncmp(path, "*/", 2)) { + path += 2; + descend = MXML_DESCEND; + } else + descend = MXML_DESCEND_FIRST; + /* * Get the next element in the path... */ + pathsep = strnchr(path, '/', strlen(path)); + if (pathsep == NULL) + pathsep = path + strlen(path); + if (pathsep == path || (pathsep - path) >= sizeof(element)) + return NULL; + memcpy(element, path, pathsep - path); + element[pathsep - path] = '\0'; + if (*pathsep) + path = pathsep + 1; + else + path = pathsep; + /* * Search for the element... */ + node = mxmlFindElement(node, node, element, NULL, NULL, + descend); + if (node == NULL) + return NULL; + } + + /* * If we get this far, return the node or its first child... */ + if (node->child && node->child->type != MXML_ELEMENT) + return node->child; + else + return node; +} + +/* + * 'mxmlWalkNext()' - Walk to the next logical node in the tree. + * + * The descend argument controls whether the first child is considered + * to be the next node. The top node argument constrains the walk to + * the node's children. + */ + +mxml_node_t * /* O - Next node or @code NULL@ */ +mxmlWalkNext(mxml_node_t *node, /* I - Current node */ + mxml_node_t *top, /* I - Top node */ + int descend) +{ /* I - Descend into tree - @code MXML_DESCEND@, @code MXML_NO_DESCEND@, or @code MXML_DESCEND_FIRST@ */ + if (!node) + return NULL; + else if (node->child && descend) + return node->child; + else if (node == top) + return NULL; + else if (node->next) + return node->next; + else if (node->parent && node->parent != top) { + node = node->parent; + while (!node->next) + if (node->parent == top || !node->parent) + return NULL; + else + node = node->parent; + return node->next; + } else + return NULL; +} + +/* + * 'mxmlWalkPrev()' - Walk to the previous logical node in the tree. + * + * The descend argument controls whether the previous node's last child + * is considered to be the previous node. The top node argument constrains + * the walk to the node's children. + */ + +mxml_node_t * /* O - Previous node or @code NULL@ */ +mxmlWalkPrev(mxml_node_t *node, /* I - Current node */ + mxml_node_t *top, /* I - Top node */ + int descend) +{ /* I - Descend into tree - @code MXML_DESCEND@, @code MXML_NO_DESCEND@, or @code MXML_DESCEND_FIRST@ */ + if (!node || node == top) + return NULL; + else if (node->prev) { + if (node->prev->last_child && descend) { + /* * Find the last child under the previous node... */ + node = node->prev->last_child; + while (node->last_child) + node = node->last_child; + return node; + } else + return node->prev; + } else if (node->parent != top) + return node->parent; + else + return NULL; +} diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-set.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-set.c new file mode 100644 index 000000000000..2206ecbaa2fe --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-set.c @@ -0,0 +1,238 @@ +/* + * Node set functions for Mini-XML, a small XML file parsing library. + * + * Copyright 2003-2017 by Michael R Sweet. + * Copyright (C) 2019 XiaoMi, Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Michael R Sweet and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "COPYING" + * which should have been included with this file. If this file is + * missing or damaged, see the license at: + * + * https://michaelrsweet.github.io/mxml + */ + +/* + * Include necessary headers... + */ + +#include "config.h" +#include "mxml.h" + +/* + * 'mxmlSetCDATA()' - Set the element name of a CDATA node. + * + * The node is not changed if it (or its first child) is not a CDATA element node. + * + * @since Mini-XML 2.3@ + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetCDATA(mxml_node_t *node, /* I - Node to set */ + const char *data) +{ /* I - New data string */ + if (node && node->type == MXML_ELEMENT && + strncmp(node->value.element.name, "![CDATA[", 8) && node->child && + node->child->type == MXML_ELEMENT && + !strncmp(node->child->value.element.name, "![CDATA[", 8)) + node = node->child; + + if (!node || node->type != MXML_ELEMENT || !data || + strncmp(node->value.element.name, "![CDATA[", 8)) + return (-1); + /* * Free any old element value and set the new value... */ + if (node->value.element.name) + free(node->value.element.name); + node->value.element.name = _mxml_strdupf("![CDATA[%s]]", data); + return 0; +} + +/* + * 'mxmlSetCustom()' - Set the data and destructor of a custom data node. + * + * The node is not changed if it (or its first child) is not a custom node. + * + * @since Mini-XML 2.1@ + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetCustom(mxml_node_t *node, /* I - Node to set */ + void *data, /* I - New data pointer */ + mxml_custom_destroy_cb_t destroy) +{ /* I - New destructor function */ + if (node && node->type == MXML_ELEMENT && node->child && + node->child->type == MXML_CUSTOM) + node = node->child; + + if (!node || node->type != MXML_CUSTOM) + return (-1); + /* * Free any old element value and set the new value... */ + + if (node->value.custom.data && node->value.custom.destroy) + (*(node->value.custom.destroy))(node->value.custom.data); + node->value.custom.data = data; + node->value.custom.destroy = destroy; + return 0; +} + +/* + * 'mxmlSetElement()' - Set the name of an element node. + * + * The node is not changed if it is not an element node. + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetElement(mxml_node_t *node, /* I - Node to set */ + const char *name) +{ /* I - New name string */ + if (!node || node->type != MXML_ELEMENT || !name) + return (-1); + + /* * Free any old element value and set the new value... */ + + if (node->value.element.name) + free(node->value.element.name); + node->value.element.name = strdup(name); + return 0; +} + +/* + * 'mxmlSetInteger()' - Set the value of an integer node. + * + * The node is not changed if it (or its first child) is not an integer node. + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetInteger(mxml_node_t *node, /* I - Node to set */ + int integer) +{ /* I - Integer value */ + if (node && node->type == MXML_ELEMENT && node->child && + node->child->type == MXML_INTEGER) + node = node->child; + + if (!node || node->type != MXML_INTEGER) + return (-1); + node->value.integer = integer; + return 0; +} + +/* + * 'mxmlSetOpaque()' - Set the value of an opaque node. + * + * The node is not changed if it (or its first child) is not an opaque node. + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetOpaque(mxml_node_t *node, /* I - Node to set */ + const char *opaque) +{ /* I - Opaque string */ + if (node && node->type == MXML_ELEMENT && node->child && + node->child->type == MXML_OPAQUE) + node = node->child; + if (!node || node->type != MXML_OPAQUE || !opaque) + return (-1); + /* * Free any old opaque value and set the new value... */ + if (node->value.opaque) + free(node->value.opaque); + node->value.opaque = strdup(opaque); + return 0; +} + +/* + * 'mxmlSetOpaquef()' - Set the value of an opaque string node to a formatted string. + * + * The node is not changed if it (or its first child) is not an opaque node. + * + * @since Mini-XML 2.11@ + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetOpaquef(mxml_node_t *node, /* I - Node to set */ + const char *format, /* I - Printf-style format string */ + ...) +{ /* I - Additional arguments as needed */ + va_list ap; /* Pointer to arguments */ + if (node && node->type == MXML_ELEMENT && node->child && + node->child->type == MXML_OPAQUE) + node = node->child; + if (!node || node->type != MXML_OPAQUE || !format) + return (int)(-1); + /* * Free any old string value and set the new value... */ + if (node->value.opaque) + free(node->value.opaque); + va_start(ap, format); + node->value.opaque = _mxml_strdupf(format, ap); + va_end(ap); + return 0; +} + +/* + * 'mxmlSetText()' - Set the value of a text node. + * + * The node is not changed if it (or its first child) is not a text node. + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetText(mxml_node_t *node, /* I - Node to set */ + int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ + const char *string) +{ /* I - String */ + if (node && node->type == MXML_ELEMENT && node->child && + node->child->type == MXML_TEXT) + node = node->child; + + if (!node || node->type != MXML_TEXT || !string) + return (int)(-1); + /* * Free any old string value and set the new value... */ + if (node->value.text.string) + free(node->value.text.string); + node->value.text.whitespace = whitespace; + node->value.text.string = strdup(string); + return 0; +} + +/* + * 'mxmlSetTextf()' - Set the value of a text node to a formatted string. + * + * The node is not changed if it (or its first child) is not a text node. + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetTextf(mxml_node_t *node, /* I - Node to set */ + int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ + const char *format, /* I - Printf-style format string */ + ...) +{ /* I - Additional arguments as needed */ + va_list ap; /* Pointer to arguments */ + if (node && node->type == MXML_ELEMENT && node->child && + node->child->type == MXML_TEXT) + node = node->child; + if (!node || node->type != MXML_TEXT || !format) + return (-1); + /* * Free any old string value and set the new value... */ + if (node->value.text.string) + free(node->value.text.string); + va_start(ap, format); + node->value.text.whitespace = whitespace; + node->value.text.string = _mxml_strdupf(format, ap); + va_end(ap); + return 0; +} + +/* + * 'mxmlSetUserData()' - Set the user data pointer for a node. + * + * @since Mini-XML 2.7@ + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetUserData(mxml_node_t *node, /* I - Node to set */ + void *data) +{ /* I - User data pointer */ + if (!node) + return (int)(-1); + /* * Set the user data pointer and return... */ + node->user_data = data; + return 0; +} diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-string.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-string.c new file mode 100644 index 000000000000..96aa5fcb6510 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml-string.c @@ -0,0 +1,393 @@ +/* + * String functions for Mini-XML, a small XML file parsing library. + * + * Copyright 2003-2017 by Michael R Sweet. + * Copyright (C) 2019 XiaoMi, Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Michael R Sweet and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "COPYING" + * which should have been included with this file. If this file is + * missing or damaged, see the license at: + * + * https://michaelrsweet.github.io/mxml + */ + +/* + * Include necessary headers... + */ + +#include "config.h" + +/* + * The va_copy macro is part of C99, but many compilers don't implement it. + * Provide a "direct assignment" implmentation when va_copy isn't defined... + */ + +#ifndef va_copy +#ifdef __va_copy +#define va_copy(dst, src) __va_copy(dst, src) +#else +#define va_copy(dst, src) memcpy(&dst, src, sizeof(va_list)) +#endif /* __va_copy */ +#endif /* va_copy */ + +#ifndef HAVE_SNPRINTF +/* + * '_mxml_snprintf()' - Format a string. + */ + +int /* O - Number of bytes formatted */ +_mxml_snprintf(char *buffer, /* I - Output buffer */ + size_t bufsize, /* I - Size of output buffer */ + const char *format, /* I - Printf-style format string */ + ...) +{ /* I - Additional arguments as needed */ + va_list ap; /* Argument list */ + int bytes; /* Number of bytes formatted */ + va_start(ap, format); + bytes = vsnprintf(buffer, bufsize, format, ap); + va_end(ap); + return bytes; +} +#endif /* !HAVE_SNPRINTF */ + +/* + * '_mxml_strdup()' - Duplicate a string. + */ + +#ifndef HAVE_STRDUP +char * /* O - New string pointer */ +_mxml_strdup(const char *s) +{ /* I - String to duplicate */ + char *t; /* New string pointer */ + if (s == NULL) + return NULL; + t = malloc(strlen(s) + 1); + if (r == NULL) + return NULL; + return strlcpy(t, s, strlen(s) + 1); +} +#endif /* !HAVE_STRDUP */ + +/* + * '_mxml_strdupf()' - Format and duplicate a string. + */ + +char * /* O - New string pointer */ +_mxml_strdupf(const char *format, /* I - Printf-style format string */ + ...) +{ /* I - Additional arguments as needed */ + va_list ap; /* Pointer to additional arguments */ + char *s; /* Pointer to formatted string */ + + /* + * Get a pointer to the additional arguments, format the string, + * and return it... + */ + + va_start(ap, format); +#ifdef HAVE_VASPRINTF + if (vasprintf(&s, format, ap) < 0) + s = NULL; +#else + s = _mxml_vstrdupf(format, ap); +#endif /* HAVE_VASPRINTF */ + va_end(ap); + return s; +} + +#ifndef HAVE_STRLCAT +size_t /* O - Number of bytes copied */ +_mxml_strlcat(char *dst, /* I - Destination buffer */ + const char *src, /* I - Source string */ + size_t dstsize) +{ /* I - Size of destinatipon buffer */ + size_t srclen; /* Length of source string */ + size_t dstlen; /* Length of destination string */ + dstlen = strlen(dst); + if (dstsize <= (dstlen + 1)) + return dstlen; /* No room, return immediately... */ + dstsize -= dstlen + 1; + srclen = strlen(src); + if (srclen > dstsize) + srclen = dstsize; + memmove(dst + dstlen, src, srclen); + dst[dstlen + srclen] = '\0'; + return (dstlen + srclen); +} +#endif /* !HAVE_STRLCAT */ + +#ifndef HAVE_STRLCPY +size_t /* O - Number of bytes copied */ +_mxml_strlcpy(char *dst, /* I - Destination buffer */ + const char *src, /* I - Source string */ + size_t dstsize) +{ /* I - Size of destinatipon buffer */ + size_t srclen; /* Length of source string */ + dstsize--; + srclen = strlen(src); + if (srclen > dstsize) + srclen = dstsize; + memmove(dst, src, srclen); + dst[srclen] = '\0'; + return srclen; +} +#endif /* !HAVE_STRLCPY */ + +#ifndef HAVE_VSNPRINTF +int /* O - Number of bytes formatted */ +_mxml_vsnprintf(char *buffer, /* O - Output buffer */ + size_t bufsize, /* O - Size of output buffer */ + const char *format, /* I - Printf-style format string */ + va_list ap) +{ /* I - Pointer to additional arguments */ + char *bufptr, /* Pointer to position in buffer */ + *bufend, /* Pointer to end of buffer */ + sign, /* Sign of format width */ + size, /* Size character (h, l, L) */ + type; /* Format type character */ + int width, /* Width of field */ + prec; /* Number of characters of precision */ + char tformat[100], /* Temporary format string for sprintf() */ + *tptr, /* Pointer into temporary format */ + temp[1024]; /* Buffer for formatted numbers */ + char *s; /* Pointer to string */ + int slen; /* Length of string */ + int bytes; /* Total number of bytes needed */ + + bufptr = buffer; + bufend = buffer + bufsize - 1; + bytes = 0; + + while (*format) { + if (*format == '%') { + tptr = tformat; + *tptr++ = *format++; + if (*format == '%') { + if (bufptr && bufptr < bufend) + *bufptr++ = *format; + bytes++; + format++; + continue; + } else if (strnchr(" -+#\'", *format, + strlen(" -+#\'"))) { + *tptr++ = *format; + sign = *format++; + } else + sign = 0; + if (*format == '*') { + format++; + width = va_arg(ap, int); + snprintf(tptr, + sizeof(tformat) - (tptr - tformat), + "%d", width); + tptr += strlen(tptr); + } else { + width = 0; + while (isdigit(*format & 255)) { + if (tptr < + (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + width = width * 10 + *format++ - '0'; + } + } + if (*format == '.') { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + format++; + if (*format == '*') { + format++; + prec = va_arg(ap, int); + snprintf(tptr, + sizeof(tformat) - + (tptr - tformat), + "%d", prec); + tptr += strlen(tptr); + } else { + prec = 0; + while (isdigit(*format & 255)) { + if (tptr < + (tformat + sizeof(tformat) - + 1)) + *tptr++ = *format; + prec = prec * 10 + *format++ - + '0'; + } + } + } else + prec = -1; + if (*format == 'l' && format[1] == 'l') { + size = 'L'; + if (tptr < (tformat + sizeof(tformat) - 2)) { + *tptr++ = 'l'; + *tptr++ = 'l'; + } + format += 2; + } else if (*format == 'h' || *format == 'l' || + *format == 'L') { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + size = *format++; + } + if (!*format) + break; + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + type = *format++; + *tptr = '\0'; + switch (type) { + case 'E': /* Floating point formats */ + case 'G': + case 'e': + case 'f': + case 'g': + break; + case 'B': /* Integer formats */ + case 'X': + case 'b': + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + if ((width + 2) > sizeof(temp)) + break; +#ifdef HAVE_LONG_LONG + if (size == 'L') + snprintf(temp, sizeof(temp), tformat, + va_arg(ap, long long)); + else +#endif /* HAVE_LONG_LONG */ + snprintf(temp, sizeof(temp), tformat, + va_arg(ap, int)); + bytes += strlen(temp); + if (bufptr) { + if ((bufptr + strlen(temp)) > bufend) { + strlcpy(bufptr, temp, + (size_t)(bufend - + bufptr + 1)); + bufptr = bufend; + } else { + strlcpy(bufptr, temp, + bytes + 1); + bufptr += strlen(temp); + } + } + break; + + case 'p': /* Pointer value */ + if ((width + 2) > sizeof(temp)) + break; + snprintf(temp, sizeof(temp), tformat, + va_arg(ap, void *)); + bytes += strlen(temp); + if (bufptr) { + if ((bufptr + strlen(temp)) > bufend) { + strlcpy(bufptr, temp, + (size_t)(bufend - + bufptr + 1)); + bufptr = bufend; + } else { + strlcpy(bufptr, temp, + bytes + 1); + bufptr += strlen(temp); + } + } + break; + + case 'c': /* Character or character array */ + bytes += width; + + if (bufptr) { + if (width <= 1) + *bufptr++ = va_arg(ap, int); + else { + if ((bufptr + width) > bufend) + width = bufend - bufptr; + + memcpy(bufptr, + va_arg(ap, char *), + (size_t)width); + bufptr += width; + } + } + break; + + case 's': /* String */ + s = va_arg(ap, char *); + if (s == NULL) + s = "(null)"; + slen = strlen(s); + if (slen > width && prec != width) + width = slen; + bytes += width; + if (bufptr) { + if ((bufptr + width) > bufend) + width = bufend - bufptr; + if (slen > width) + slen = width; + if (sign == '-') { + strlcpy(bufptr, s, + (size_t)(slen + 1)); + memset(bufptr + slen, ' ', + (size_t)(width - slen)); + } else { + memset(bufptr, ' ', + (size_t)(width - slen)); + strlcpy(bufptr + width - slen, + s, (size_t)(slen + 1)); + } + bufptr += width; + } + break; + + case 'n': /* Output number of chars so far */ + *(va_arg(ap, int *)) = bytes; + break; + } + } else { + bytes++; + if (bufptr && bufptr < bufend) + *bufptr++ = *format; + format++; + } + } + *bufptr = '\0'; + return bytes; +} +#endif /* !HAVE_VSNPRINTF */ + +char * /* O - New string pointer */ +_mxml_vstrdupf(const char *format, /* I - Printf-style format string */ + va_list ap) +{ /* I - Pointer to additional arguments */ +#ifdef HAVE_VASPRINTF + char *s; /* String */ + if (vasprintf(&s, format, ap) < 0) + s = NULL; + return s; + +#else + int bytes; /* Number of bytes required */ + char *buffer, /* String buffer */ + temp[256]; /* Small buffer for first vsnprintf */ + +#ifdef WIN32 + bytes = _vscprintf(format, ap); +#else + va_list apcopy; /* Copy of argument list */ + va_copy(apcopy, ap); + bytes = vsnprintf(temp, sizeof(temp), format, apcopy); +#endif /* WIN32 */ + + if (bytes < sizeof(temp)) { + return strdup(temp); + } + + buffer = calloc(1, bytes + 1); + if (buffer != NULL) + vsnprintf(buffer, bytes + 1, format, ap); + return buffer; +#endif /* HAVE_VASPRINTF */ +} diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml.h new file mode 100644 index 000000000000..657e0587b496 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/mxml.h @@ -0,0 +1,317 @@ +/* + * Header file for Mini-XML, a small XML file parsing library. + * + * Copyright 2003-2017 by Michael R Sweet. + * Copyright (C) 2019 XiaoMi, Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Michael R Sweet and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "COPYING" + * which should have been included with this file. If this file is + * missing or damaged, see the license at: + * + * https://michaelrsweet.github.io/mxml + */ + +/* + * Prevent multiple inclusion... + */ + +#ifndef _mxml_h_ +#define _mxml_h_ + +/* + * Include necessary headers... + */ + +#include +#include +#include + +#include "board_opr_interface.h" + +#define DEBUG 0 +/* + * Constants... + */ + +#define MXML_MAJOR_VERSION 2 /* Major version number */ +#define MXML_MINOR_VERSION 11 /* Minor version number */ + +#define MXML_TAB 8 /* Tabs every N columns */ + +#define MXML_NO_CALLBACK 0 /* Don't use a type callback */ +#define MXML_INTEGER_CALLBACK mxml_integer_cb +/* Treat all data as integers */ +#define MXML_OPAQUE_CALLBACK mxml_opaque_cb +/* Treat all data as opaque */ +#define MXML_REAL_CALLBACK mxml_real_cb +/* Treat all data as real numbers */ +#define MXML_TEXT_CALLBACK 0 /* Treat all data as text */ +#define MXML_IGNORE_CALLBACK mxml_ignore_cb +/* Ignore all non-element content */ + +#define MXML_NO_PARENT 0 /* No parent for the node */ + +#define MXML_DESCEND 1 /* Descend when finding/walking */ +#define MXML_NO_DESCEND 0 /* Don't descend when finding/walking */ +#define MXML_DESCEND_FIRST -1 /* Descend for first find */ + +#define MXML_WS_BEFORE_OPEN 0 /* Callback for before open tag */ +#define MXML_WS_AFTER_OPEN 1 /* Callback for after open tag */ +#define MXML_WS_BEFORE_CLOSE 2 /* Callback for before close tag */ +#define MXML_WS_AFTER_CLOSE 3 /* Callback for after close tag */ + +#define MXML_ADD_BEFORE 0 /* Add node before specified node */ +#define MXML_ADD_AFTER 1 /* Add node after specified node */ +#define MXML_ADD_TO_PARENT NULL /* Add node relative to parent */ + +/* + * Data types... + */ + +typedef enum mxml_sax_event_e { + /**** SAX event type. ****/ + MXML_SAX_CDATA, /* CDATA node */ + MXML_SAX_COMMENT, /* Comment node */ + MXML_SAX_DATA, /* Data node */ + MXML_SAX_DIRECTIVE, /* Processing directive node */ + MXML_SAX_ELEMENT_CLOSE, /* Element closed */ + MXML_SAX_ELEMENT_OPEN /* Element opened */ +} mxml_sax_event_t; + +typedef enum mxml_type_e { + /**** The XML node type. ****/ + MXML_IGNORE = -1, /* Ignore/throw away node @since Mini-XML 2.3@ */ + MXML_ELEMENT, /* XML element with attributes */ + MXML_INTEGER, /* Integer value */ + MXML_OPAQUE, /* Opaque string */ + MXML_REAL, /* Real value */ + MXML_TEXT, /* Text fragment */ + MXML_CUSTOM /* Custom data @since Mini-XML 2.1@ */ +} mxml_type_t; + +/**** Custom data destructor ****/ +typedef void (*mxml_custom_destroy_cb_t)(void *); + +/**** Error callback function ****/ +typedef void (*mxml_error_cb_t)(const char *); + +typedef struct mxml_attr_s { + /**** An XML element attribute value. @private@ ****/ + char *name; /* Attribute name */ + char *value; /* Attribute value */ +} mxml_attr_t; + +typedef struct mxml_element_s { + /**** An XML element value. @private@ ****/ + char *name; /* Name of element */ + int num_attrs; /* Number of attributes */ + mxml_attr_t *attrs; /* Attributes */ +} mxml_element_t; + +typedef struct mxml_text_s { + /**** An XML text value. @private@ ****/ + int whitespace; /* Leading whitespace? */ + char *string; /* Fragment string */ +} mxml_text_t; + +typedef struct mxml_custom_s { + /**** An XML custom value. @private@ ****/ + void *data; /* Pointer to (allocated) custom data */ + mxml_custom_destroy_cb_t destroy; /* Pointer to destructor function */ +} mxml_custom_t; + +typedef union mxml_value_u { + /**** An XML node value. @private@ ****/ + mxml_element_t element; /* Element */ + int integer; /* Integer number */ + char *opaque; /* Opaque string */ + mxml_text_t text; /* Text fragment */ + mxml_custom_t custom; /* Custom data @since Mini-XML 2.1@ */ +} mxml_value_t; + +struct mxml_node_s { + /**** An XML node. @private@ ****/ + mxml_type_t type; /* Node type */ + struct mxml_node_s *next; /* Next node under same parent */ + struct mxml_node_s *prev; /* Previous node under same parent */ + struct mxml_node_s *parent; /* Parent node */ + struct mxml_node_s *child; /* First child node */ + struct mxml_node_s *last_child; /* Last child node */ + mxml_value_t value; /* Node value */ + int ref_count; /* Use count */ + void *user_data; /* User data */ +}; + +typedef struct mxml_node_s mxml_node_t; /**** An XML node. ****/ + +struct mxml_index_s { + /**** An XML node index. @private@ ****/ + char *attr; /* Attribute used for indexing or NULL */ + int num_nodes; /* Number of nodes in index */ + int alloc_nodes; /* Allocated nodes in index */ + int cur_node; /* Current node */ + mxml_node_t **nodes; /* Node array */ +}; + +/**** An XML node index. ****/ +typedef struct mxml_index_s mxml_index_t; + +/**** Custom data load callback function ****/ +typedef int (*mxml_custom_load_cb_t)(mxml_node_t *, const char *); + +/**** Custom data save callback function ****/ +typedef char *(*mxml_custom_save_cb_t)(mxml_node_t *); + +/**** Entity callback function */ +typedef int (*mxml_entity_cb_t)(const char *); + +/**** Load callback function ****/ +typedef mxml_type_t (*mxml_load_cb_t)(mxml_node_t *); + +/**** Save callback function ****/ +typedef const char *(*mxml_save_cb_t)(mxml_node_t *, int); + +/**** SAX callback function ****/ +typedef void (*mxml_sax_cb_t)(mxml_node_t *, mxml_sax_event_t, void *); + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Prototypes... + */ + +extern void mxmlAdd(mxml_node_t *parent, int where, mxml_node_t *child, + mxml_node_t *node); +extern void mxmlDelete(mxml_node_t *node); +extern void mxmlElementDeleteAttr(mxml_node_t *node, const char *name); +extern const char *mxmlElementGetAttr(mxml_node_t *node, const char *name); +extern const char *mxmlElementGetAttrByIndex(mxml_node_t *node, int idx, + const char **name); +extern int mxmlElementGetAttrCount(mxml_node_t *node); +extern void mxmlElementSetAttr(mxml_node_t *node, const char *name, + const char *value); +extern void mxmlElementSetAttrf(mxml_node_t *node, const char *name, + const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(__printf__, 3, 4))) +#endif /* __GNUC__ */ + ; +extern int mxmlEntityAddCallback(mxml_entity_cb_t cb); +extern const char *mxmlEntityGetName(int val); +extern int mxmlEntityGetValue(const char *name); +extern void mxmlEntityRemoveCallback(mxml_entity_cb_t cb); +extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top, + const char *element, const char *attr, + const char *value, int descend); +extern mxml_node_t *mxmlFindPath(mxml_node_t *node, const char *path); +extern const char *mxmlGetCDATA(mxml_node_t *node); +extern const void *mxmlGetCustom(mxml_node_t *node); +extern const char *mxmlGetElement(mxml_node_t *node); +extern mxml_node_t *mxmlGetFirstChild(mxml_node_t *node); +extern int mxmlGetInteger(mxml_node_t *node); +extern mxml_node_t *mxmlGetLastChild(mxml_node_t *node); +extern mxml_node_t *mxmlGetNextSibling(mxml_node_t *node); +extern const char *mxmlGetOpaque(mxml_node_t *node); +extern mxml_node_t *mxmlGetParent(mxml_node_t *node); +extern mxml_node_t *mxmlGetPrevSibling(mxml_node_t *node); +extern int mxmlGetRefCount(mxml_node_t *node); +extern const char *mxmlGetText(mxml_node_t *node, int *whitespace); +extern mxml_type_t mxmlGetType(mxml_node_t *node); +extern void *mxmlGetUserData(mxml_node_t *node); +extern void mxmlIndexDelete(mxml_index_t *ind); +extern mxml_node_t *mxmlIndexEnum(mxml_index_t *ind); +extern mxml_node_t *mxmlIndexFind(mxml_index_t *ind, const char *element, + const char *value); +extern int mxmlIndexGetCount(mxml_index_t *ind); +extern mxml_index_t *mxmlIndexNew(mxml_node_t *node, const char *element, + const char *attr); +extern mxml_node_t *mxmlIndexReset(mxml_index_t *ind); +extern mxml_node_t *mxmlLoadFd(mxml_node_t *top, int fd, + mxml_type_t (*cb)(mxml_node_t *)); +extern mxml_node_t *mxmlLoadString(mxml_node_t *top, const char *s, + mxml_type_t (*cb)(mxml_node_t *)); +extern mxml_node_t *mxmlNewCDATA(mxml_node_t *parent, const char *string); +extern mxml_node_t *mxmlNewCustom(mxml_node_t *parent, void *data, + mxml_custom_destroy_cb_t destroy); +extern mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name); +extern mxml_node_t *mxmlNewInteger(mxml_node_t *parent, int integer); +extern mxml_node_t *mxmlNewOpaque(mxml_node_t *parent, const char *opaque); +extern mxml_node_t *mxmlNewOpaquef(mxml_node_t *parent, const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(__printf__, 2, 3))) +#endif /* __GNUC__ */ + ; + +extern mxml_node_t *mxmlNewText(mxml_node_t *parent, int whitespace, + const char *string); +extern mxml_node_t *mxmlNewTextf(mxml_node_t *parent, int whitespace, + const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(__printf__, 3, 4))) +#endif /* __GNUC__ */ + ; +extern mxml_node_t *mxmlNewXML(const char *version); +extern int mxmlRelease(mxml_node_t *node); +extern void mxmlRemove(mxml_node_t *node); +extern int mxmlRetain(mxml_node_t *node); +extern char *mxmlSaveAllocString(mxml_node_t *node, mxml_save_cb_t cb); +extern int mxmlSaveFd(mxml_node_t *node, int fd, mxml_save_cb_t cb); +extern int mxmlSaveString(mxml_node_t *node, char *buffer, int bufsize, + mxml_save_cb_t cb); +extern mxml_node_t *mxmlSAXLoadFd(mxml_node_t *top, int fd, + mxml_type_t (*cb)(mxml_node_t *), + mxml_sax_cb_t sax, void *sax_data); +extern mxml_node_t *mxmlSAXLoadString(mxml_node_t *top, const char *s, + mxml_type_t (*cb)(mxml_node_t *), + mxml_sax_cb_t sax, void *sax_data); +extern int mxmlSetCDATA(mxml_node_t *node, const char *data); +extern int mxmlSetCustom(mxml_node_t *node, void *data, + mxml_custom_destroy_cb_t destroy); +extern void mxmlSetCustomHandlers(mxml_custom_load_cb_t load, + mxml_custom_save_cb_t save); +extern int mxmlSetElement(mxml_node_t *node, const char *name); +extern void mxmlSetErrorCallback(mxml_error_cb_t cb); +extern int mxmlSetInteger(mxml_node_t *node, int integer); +extern int mxmlSetOpaque(mxml_node_t *node, const char *opaque); +extern int mxmlSetOpaquef(mxml_node_t *node, const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(__printf__, 2, 3))) +#endif /* __GNUC__ */ + ; + +extern int mxmlSetText(mxml_node_t *node, int whitespace, const char *string); +extern int mxmlSetTextf(mxml_node_t *node, int whitespace, const char *format, + ...) +#ifdef __GNUC__ + __attribute__((__format__(__printf__, 3, 4))) +#endif /* __GNUC__ */ + ; +extern int mxmlSetUserData(mxml_node_t *node, void *data); +extern void mxmlSetWrapMargin(int column); +extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top, + int descend); +extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top, + int descend); + +/* + * Semi-private functions... + */ + +extern void mxml_error(const char *format, ...); +extern mxml_type_t mxml_ignore_cb(mxml_node_t *node); +extern mxml_type_t mxml_integer_cb(mxml_node_t *node); +extern mxml_type_t mxml_opaque_cb(mxml_node_t *node); +extern mxml_type_t mxml_real_cb(mxml_node_t *node); + +/* + * C++ support... + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* !_mxml_h_ */ diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/normandy_short_test.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/normandy_short_test.c new file mode 100644 index 000000000000..24204808a2d9 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/normandy_short_test.c @@ -0,0 +1,900 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : normandy_short_test.c +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : normandy short test +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#include "normandy_short_test.h" +#include "tp_short_test.h" +#include "simple_mem_manager.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*************************************Private methods start********************************************/ +static s32 have_short_code_in_fw(PST_TP_DEV p_dev); +static s32 download_short_code(ptr32 p_data); +static s32 run_short_code(ptr32 p_data); +static s32 send_cmd(PST_TP_DEV p_dev, u8 cmd, u8 param); +static s32 wait_status(PST_TP_DEV p_dev, u16 sta_addr, u8 right_sta, + u16 time_out); +static s32 send_short_param(ptr32 p_data); +static s32 wait_short_end(PST_TP_DEV p_dev); +static u16 calc_short_gnd_vdd(u16 diff_code, s32 avdd, u8 *p_short_opt); +static u16 calc_short_chn(PST_TP_DEV p_dev, IN u8 chn1, IN u8 chn2, + IN u16 self_code, IN u16 short_code); +static s32 analyse_short_res(ptr32 p_data); +static u8 short_id_to_selfdata_id(PST_TP_DEV p_dev, u8 short_id); +/*************************************Private methods end********************************************/ +/******************************************************************************* +* Function Name : normandy_short_test +* Description : normandy short test +* Input : ptr32 p_data(You must cast it to type 'PST_TEST_ITEM' ) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 normandy_short_test(IN_OUT ptr32 p_data) +{ + s32 ret = 0; + PST_SHORT_PARAM p_param = NULL; + PST_SHORT_TEST_RES p_test_res = NULL; + PST_TEST_ITEM p_item = NULL; + PST_TP_DEV p_dev = NULL; + p_item = (PST_TEST_ITEM)p_data; + if (NULL == p_item) { + board_print_error("%s\n", + "in short test, p_item parameter is NULL"); + goto NORMANDY_SHORT_TEST_END; + } + p_dev = p_item->p_tp_dev; + p_param = (PST_SHORT_PARAM)p_item->param.ptr_param; + if (NULL == p_param) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = SHORT_TEST_PARAMETER_ERROR; + p_test_res->item_res_header.test_status = TEST_ABORTED; + p_test_res->item_res_header.test_result = TEST_NG; + board_print_error("%s\n", "in short test, parameter is NULL"); + goto NORMANDY_SHORT_TEST_END; + } + + p_test_res = (PST_SHORT_TEST_RES)p_item->test_res.ptr_res; + /*clear short mess*/ + clear_short_mess_in_res(p_item); + /*********test program*************/ + ret = have_short_code_in_fw(p_dev); + if (1 != ret) { + /*download short code in ram,and run this code*/ + ret = download_short_code(p_data); + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = + SHORT_TEST_DOWNLOAD_FW_FAIL; + p_test_res->item_res_header.test_status = TEST_ABORTED; + p_test_res->item_res_header.test_result = TEST_NG; + board_print_error( + "%s\n", + "in short test, download short fw fail"); + goto NORMANDY_SHORT_TEST_END; + } + } + /* (2)run short code*/ + ret = run_short_code(p_data); + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = SHORT_TEST_RUN_FW_FAIL; + p_test_res->item_res_header.test_status = TEST_ABORTED; + p_test_res->item_res_header.test_result = TEST_NG; + board_print_error("%s\n", "in short test, run short fw error"); + goto NORMANDY_SHORT_TEST_END; + } + /*(3)send short param*/ + ret = send_short_param(p_data); + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = SHORT_TEST_SEND_PARAMETER_FAIL; + p_test_res->item_res_header.test_status = TEST_ABORTED; + p_test_res->item_res_header.test_result = TEST_NG; + board_print_error("%s\n", + "in short test, send short parameter fail"); + goto NORMANDY_SHORT_TEST_END; + } + /* (4)wait test end*/ + ret = wait_short_end(p_dev); + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = SHORT_TEST_END_FAIL; + p_test_res->item_res_header.test_status = TEST_ABORTED; + p_test_res->item_res_header.test_result = TEST_NG; + board_print_error("%s\n", "in short test, wait test end fail"); + goto NORMANDY_SHORT_TEST_END; + } + /* (5)annlyze short result*/ + ret = analyse_short_res(p_data); + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = SHORT_TEST_ANALYSIS_RESULT_FAIL; + p_test_res->item_res_header.test_status = TEST_ABORTED; + p_test_res->item_res_header.test_result = TEST_NG; + board_print_error( + "%s\n", + "in short test, annlyze short test result fail"); + goto NORMANDY_SHORT_TEST_END; + } + + short_test_channel_map(p_item, TX_RX_SHARED); + p_test_res->item_res_header.test_status = TEST_FINISH; +NORMANDY_SHORT_TEST_END: + return ret; +} + +#ifdef __cplusplus +} +#endif + +/******************************************************************************* +* Function Name : have_short_code_in_fw +* Description : Judge that is there short code in firmware +* Input : PST_TP_DEV p_dev +* Output : none +* Return : s32(0:not exist short code in fw 1:exist short code in fw) +*******************************************************************************/ +static s32 have_short_code_in_fw(IN PST_TP_DEV p_dev) +{ + return 1; +} + +/******************************************************************************* +* Function Name : download_short_code +* Description : download short code +* Input : ptr32 p_data(You must cast it to type 'PST_TEST_ITEM' ) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +static s32 download_short_code(IN ptr32 p_data) +{ + return 0; +} + +/******************************************************************************* +* Function Name : run_short_code +* Description : run short code +* Input : ptr32 p_data(You must cast it to type 'PST_TEST_ITEM' ) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +static s32 run_short_code(IN ptr32 p_data) +{ + s32 ret = 0; + u8 i = 0, retry_cnt = 3; + PST_TEST_ITEM p_item = NULL; + PST_TP_DEV p_dev = NULL; + p_item = (PST_TEST_ITEM)p_data; + p_dev = p_item->p_tp_dev; + + for (i = 0; i < retry_cnt; i++) { + /*switch to short firmware*/ + ret = send_cmd(p_dev, 0x0B, 0x00); + if (0 == ret) { + continue; + } + /*delay 130ms -> 50ms*/ + board_delay_ms(50); + + /*wait short ready*/ + ret = wait_status(p_dev, NORM_SHORT_STA_ADDR, + NORM_SHORT_STA_READY, 200); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_error("%s\n", "switch to short firmware fail"); + } + return ret; +} + +/******************************************************************************* +* Function Name : send_cmd +* Description : send_cmd +* Input : PST_TP_DEV p_dev +* Input : u8 cmd +* Input : u8 param +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +static s32 send_cmd(IN PST_TP_DEV p_dev, IN u8 cmd, IN u8 param) +{ + s32 ret = 0; + u8 buf_arr[3]; + buf_arr[0] = cmd; + buf_arr[1] = param; + buf_arr[2] = (u8)(0 - (cmd + param)); + ret = chip_reg_write(p_dev, p_dev->real_cmd_addr, buf_arr, 3); + return ret; +} + +/******************************************************************************* +* Function Name : wait_status +* Description : wait_status +* Input : PST_TP_DEV p_dev +* Input : u16 sta_addr +* Input : u8 right_sta +* Input : u16 time_out +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +static s32 wait_status(IN PST_TP_DEV p_dev, IN u16 sta_addr, IN u8 right_sta, + IN u16 time_out) +{ + s32 ret = 0; + u16 i = 0; + u16 cnt = (time_out + 9) / 10; + /*make sure unequal for initialization*/ + u8 data_tmp = right_sta - 1; + + for (i = 0; i < cnt; i++) { + ret = chip_reg_read(p_dev, sta_addr, &data_tmp, 1); + if ((ret == 1) && (data_tmp == right_sta)) { + break; + } + board_delay_ms(10); + } + if (i >= cnt) { + ret = 0; + board_print_debug("short test status:0x%02x!\n", data_tmp); + } + return ret; +} + +/******************************************************************************* +* Function Name : send_short_param +* Description : send_short_param +* Input : ptr32 p_data(You must cast it to type 'PST_TEST_ITEM' ) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +static s32 send_short_param(IN ptr32 p_data) +{ + s32 ret = 0; + u8 buf_tmp[10]; + + PST_TEST_ITEM p_item = NULL; + PST_TP_DEV p_dev = NULL; + PST_SHORT_PARAM p_short_param = NULL; + p_item = (PST_TEST_ITEM)p_data; + p_dev = p_item->p_tp_dev; + p_short_param = (PST_SHORT_PARAM)p_item->param.ptr_param; + + /*data store in normandy ram wit big-endian + //Tx&Tx Rx&Rx Tx&Rx short adc threshold + */ + buf_tmp[0] = ((p_short_param->short_threshold.gt_short_threshold >> 8) & + 0xFF); + buf_tmp[1] = + ((p_short_param->short_threshold.gt_short_threshold) & 0xFF); + /*diffcode threshold*/ + buf_tmp[2] = + ((p_short_param->short_threshold.diffcode_short_threshold >> + 8) & + 0xFF); + buf_tmp[3] = + ((p_short_param->short_threshold.diffcode_short_threshold) & + 0xFF); + /*adc read delay*/ + buf_tmp[4] = + ((p_short_param->short_threshold.adc_read_delay >> 8) & 0xFF); + buf_tmp[5] = ((p_short_param->short_threshold.adc_read_delay) & 0xFF); + ret = chip_reg_write(p_dev, NORM_SHORT_TXRX_ADC_THD_ADDR, buf_tmp, 6); + if (0 == ret) { + board_print_error( + "%s\n", + "send tx&rx or gnd&vdd adc threshold or adc delay fail"); + goto SEND_END; + } + /*Intialize cfg ,and start test*/ + buf_tmp[0] = 0x01; + ret = chip_reg_write(p_dev, 0x5095, buf_tmp, 1); + if (0 == ret) { + board_print_error("%s\n", "write 0x01 to 0x5095 fail"); + goto SEND_END; + } +SEND_END: + return ret; +} + +/******************************************************************************* +* Function Name : wait_short_end +* Description : wait shott end +* Input : PST_TP_DEV p_dev +* Output : none +* Return : u8(0:fail 1:short test end) +*******************************************************************************/ +static s32 wait_short_end(IN PST_TP_DEV p_dev) +{ + s32 ret = 0; + u8 tmp_data = 0; + + /*send start short test cmd*/ + tmp_data = 0x01; + ret = chip_reg_write(p_dev, NORM_SHORT_STA_ADDR, &tmp_data, 1); + if (0 == ret) { + board_print_error("%s\n", "send start short test cmd fail!"); + goto WAIT_END; + } + /*delay 1800ms*/ + board_delay_ms(1800); + /*wait test end*/ + ret = wait_status(p_dev, NORM_SHORT_TESTEND_ADDR, + NORM_SHORT_ALL_TEST_END, 1200); + if (0 == ret) { + board_print_error("%s\n", "wait test end fail!"); + goto WAIT_END; + } +WAIT_END: + return ret; +} + +/******************************************************************************* +* Function Name : get_chn_group +* Description : get the group of channel +* Input : u8 chn +* Output : none +* Return : u8(group num the channel in) +*******************************************************************************/ +static u8 get_chn_group(IN u8 chn) +{ + u8 group = 0; + + if ((chn >= 0) && (chn < 9)) { /*pad s0~s8*/ + group = 5; + } else if ((chn >= 9) && (chn < 14)) { /*pad s9~s13*/ + group = 4; + } else if ((chn >= 14) && (chn < 18)) { /*pad s14~s17*/ + group = 3; + } else if ((chn >= 18) && (chn < 27)) { /* pad s18~s26*/ + group = 2; + } else if ((chn >= 27) && (chn < 32)) { /* pad s27~s31*/ + group = 1; + } else if ((chn >= 32) && (chn < 36)) { /* pad s32~s35*/ + group = 0; + } else if ((chn >= 36) && (chn < 45)) { /* pad d0~d8*/ + group = 5; + } else if ((chn >= 45) && (chn < 54)) { /* pad d9~d17*/ + group = 2; + } else if ((chn >= 54) && (chn < 59)) { /* pad d18~d22*/ + group = 1; + } else if ((chn >= 59) && (chn < 63)) { /* pad d23~d26*/ + group = 0; + } else if ((chn >= 63) && (chn < 67)) { /* pad d27~d30*/ + group = 3; + } else if ((chn >= 67) && (chn < 72)) { /* pad d31~d35*/ + group = 4; + } else if ((chn >= 72) && (chn < 76)) { /* pad d36~d39 */ + group = 0; + } + return group; +} + +/******************************************************************************* +* Function Name : calc_short_gnd_vdd +* Description : calculate short between channel with gnd or vdd(similar to gt9p) +* Input : u16 diff_code +* Input : s32 avdd +* Output : u8* p_short_opt(0:gnd short 1:vdd short) +* Return : u16((resistor(0.1kom))) +*******************************************************************************/ +static u16 calc_short_gnd_vdd(IN u16 diff_code, IN s32 avdd, + OUT u8 *p_short_opt) +{ + s32 r = 0; + if ((diff_code & 0x7fff) == 0) { + diff_code += 1; + } + /*bit15==1 means vdd,bit15==0 means gnd*/ + if ((diff_code & (0x8000)) == 0) { /*short to GND*/ + /*52662.85/diff_code-40*/ + r = (526628 / (diff_code & (~0x8000)) - 40 * 10); + *p_short_opt = 0; + } else { /*short to VDD*/ + diff_code &= (~0x8000); + r = 9 * 1024 * (avdd - 9) * 40 / diff_code / 7 - 40 * 10; + *p_short_opt = 1; + } + /*r *= 2;*/ + if (r < 65530) { + ; + } else { + r = 65535; + } + board_print_info("GND/VDD r:%d", r); + return (u16)(r >= 0 ? r : 0); +} + +/******************************************************************************* +* Function Name : calc_short_chn +* Description : calculate short between chn1 with chn2 +* Input : PST_TP_DEV p_dev + : u8 chn1 +* Input : u8 chn2 +* Input : u16 self_code +* Input : u16 short_code +* Output : none +* Return : u16(resistor(0.1kom)) +*******************************************************************************/ +static u16 calc_short_chn(PST_TP_DEV p_dev, IN u8 chn1, IN u8 chn2, + IN u16 self_code, IN u16 short_code) +{ + s32 r = 0; + s32 b_in_same_grp = 0; + u8 group1 = 0; + u8 group2 = 0; + u8 die_num1 = 0; + u8 die_num2 = 0; + u8 chn_flag = 0; + if (((chn1 & CHANNEL_TX_FLAG) == CHANNEL_TX_FLAG) && + ((chn2 & CHANNEL_TX_FLAG) == CHANNEL_TX_FLAG)) { + chn1 &= ~CHANNEL_TX_FLAG; + chn2 &= ~CHANNEL_TX_FLAG; + group1 = get_chn_group(chn1); + group2 = get_chn_group(chn2); + chn_flag = 1; + if (group1 == group2) { + b_in_same_grp = 1; + die_num1 += chn1; + die_num2 += chn2; + } + } else if (((chn1 & CHANNEL_TX_FLAG) == 0) && + ((chn2 & CHANNEL_TX_FLAG) == 0)) { + group1 = get_chn_group(chn1); + group2 = get_chn_group(chn2); + chn_flag = 1; + if (group1 == group2) { + b_in_same_grp = 1; + } + } + + if (!b_in_same_grp) { + r = (10 * self_code * 81 / short_code - 81 * 10); + } else { + die_num1 = (die_num1 >= die_num2) ? (die_num1 - die_num2) : + (die_num2 - die_num1); + if ((die_num1 > 3) && (group1 == 0)) { /*different setting*/ + r = (10 * self_code * 81 / short_code - 81 * 10); + } else { + r = (10 * self_code * 64 / short_code - 64 * 10); + } + } + if (r < 65535) { + ; + } else { + r = 65535; + } + return (u16)(r >= 0 ? r : 0); +} + +/******************************************************************************* +* Function Name : analyse_short_res +* Description : analyse short result +* Input : ptr32 p_data(You must cast it to type 'PST_TEST_ITEM' ) +* Output : none +* Return : u8(0:fail 1:ok) +*******************************************************************************/ +static s32 analyse_short_res(IN_OUT ptr32 p_data) +{ + s32 ret = 0; + u8 *p_tmp_data_arr = NULL; + u16 i = 0, j = 0; + u16 retry_cnt = 3; + PST_TEST_ITEM p_test_item = NULL; + PST_TP_DEV p_dev = NULL; + PST_SHORT_PARAM p_short_param = NULL; + PST_SHORT_TEST_RES p_short_res = NULL; + + u16 short_code_tmp = 0; + u16 data_len_tmp = 0; + u16 tmp_data16 = 0; + u8 chn_id_tmp1 = 0; + u8 chn_id_tmp2 = 0; + u8 id_tmp = 0; + u8 short_flag = 0; + u8 chn_short_cnt[3]; + u16 diff_code_tmp = 0; + u16 short_r = 0; + u16 *p_self_code_arr = NULL; + u16 chn_short_mess_addr = 0; + u8 max_sen_num_in_die = 0; + u8 max_drv_num_in_die = 0; + + p_test_item = (PST_TEST_ITEM)p_data; + p_dev = p_test_item->p_tp_dev; + p_short_param = (PST_SHORT_PARAM)p_test_item->param.ptr_param; + p_short_res = (PST_SHORT_TEST_RES)p_test_item->test_res.ptr_res; + max_sen_num_in_die = p_dev->max_sen_num_in_die; + max_drv_num_in_die = p_dev->max_drv_num_in_die; + + data_len_tmp = (max_drv_num_in_die + max_sen_num_in_die) * 2; + ret = alloc_mem_block((void **)&p_tmp_data_arr, data_len_tmp); + if (0 == ret) { + board_print_error( + "%s\n", + "in analyse short test result, malloc memory for p_tmp_data_arr fail"); + goto ANALYSE_SHORT_RES_END; + } + + data_len_tmp = (max_drv_num_in_die + max_sen_num_in_die) * 2; + ret = alloc_mem_block((void **)&p_self_code_arr, data_len_tmp); + if (0 == ret) { + board_print_error( + "%s\n", + "in analyse short test result, malloc memory for self_code_arr fail"); + goto ANALYSE_SHORT_RES_END; + } + /*judge short flag*/ + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_read(p_dev, NORM_SHORT_TEST_RESULT_ADDR, + &short_flag, 1); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_error( + "%s\n", + "in analyse short test result, read short flag fail"); + goto ANALYSE_SHORT_RES_END; + } + + /*short_flag: + bit0: Tx & Tx + bit1: Rx & Rx + bit2: Tx & Rx + bit3: Tx/Rx & GND/VDD + */ + + if (0 == (short_flag & 0x0F)) { + /*board_print_error("%s\n", "in analyse short test result, read short flag fail");*/ + goto ANALYSE_SHORT_RES_END; + } + /*bit3: Tx/Rx & GND/VDD */ + data_len_tmp = (max_drv_num_in_die + max_sen_num_in_die) * 2; + if (0x08 == (short_flag & 0x08)) { + /*get diffcode*/ + for (i = 0; i < retry_cnt; i++) { + /*NORM_SHORT_DIFFCODE_ADDR is the start address of diffcode*/ + ret = chip_reg_read(p_dev, NORM_SHORT_DIFFCODE_ADDR, + p_tmp_data_arr, data_len_tmp); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_error( + "%s\n", + "in analyse Tx/Rx & GND/VDD, read diffcode fail"); + goto ANALYSE_SHORT_RES_END; + } + for (i = 0; i < data_len_tmp; i += 2) { + diff_code_tmp = (p_tmp_data_arr[i] << 8) + + p_tmp_data_arr[i + 1]; + /*calculate short_r*/ + short_r = calc_short_gnd_vdd( + diff_code_tmp, (10 * p_dev->power_volt / 1000), + &chn_id_tmp2); + chn_id_tmp1 = i >> 1; + + /*must convert it + //|max_drv_num_in_die|max_sen_num_in_die| + */ + if (chn_id_tmp1 < max_drv_num_in_die) { + chn_id_tmp1 += max_sen_num_in_die; + chn_id_tmp1 |= CHANNEL_TX_FLAG; + tmp_data16 = + p_short_param->short_threshold + .drv_gnd_vdd_resistor_threshold * + 10; + } else { + chn_id_tmp1 -= max_drv_num_in_die; + tmp_data16 = + p_short_param->short_threshold + .sen_gnd_vdd_resistor_threshold * + 10; + } + if (1 == chn_id_tmp2) { + chn_id_tmp2 = CHANNEL_VDD; + } else if (0 == chn_id_tmp2) { + chn_id_tmp2 = CHANNEL_GND; + } + /*store this data in result*/ + if (short_r < tmp_data16) { + store_short_mess_in_res(chn_id_tmp1, + chn_id_tmp2, short_r, + p_short_res); + } + } + } + + /*get self code*/ + data_len_tmp = (max_drv_num_in_die + max_sen_num_in_die) * 2; + for (i = 0; i < retry_cnt; i++) { + /*NORM_SHORT_DRVSELFCODE_ADDR is the start address of self code*/ + ret = chip_reg_read(p_dev, NORM_SHORT_DRVSELFCODE_ADDR, + p_tmp_data_arr, data_len_tmp); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_error("%s\n", + "in analyse Tx/Rx, read selfcode fail"); + goto ANALYSE_SHORT_RES_END; + } + for (i = 0; i < data_len_tmp / 2; i++) { + p_self_code_arr[i] = ((p_tmp_data_arr[2 * i] << 8) + + p_tmp_data_arr[2 * i + 1]) & + 0x7FFF; + } + + /*get channel short cnt*/ + for (i = 0; i < retry_cnt; i++) { + /*0x8042 Tx&Tx short cnt + //0x8043 Rx&Rx short cnt + //0x8044 Tx&Rx short cnt + */ + ret = chip_reg_read(p_dev, NORM_SHORT_NUMBER_ADDR, + chn_short_cnt, 3); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_error( + "%s\n", + "in analyse Tx/Rx, read channel short cnt fail"); + goto ANALYSE_SHORT_RES_END; + } + /*Tx & Tx*/ + if (0x01 == (short_flag & 0x01)) { + chn_short_mess_addr = NORM_SHORT_TxTx_PIN_NUM_ADDR; + /*2 bytes short pin num + //2 bytes reserved + //2*max_drv_num_in_die bytes TX buffer + //2 bytes check sum + */ + data_len_tmp = 2 + 2 + 2 * max_drv_num_in_die + 2; + for (i = 0; i < chn_short_cnt[0]; i++) { + /*get short code*/ + for (j = 0; j < retry_cnt; j++) { + ret = chip_reg_read(p_dev, chn_short_mess_addr, + p_tmp_data_arr, + data_len_tmp); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_error( + "%s\n", + "in analyse Tx & Tx, read short code fail"); + goto ANALYSE_SHORT_RES_END; + } + /*calc resistor + Normandy Sens Pad and Drv Pads is Unified Numbering + 0~35 is s0~s35(RX) And 36~76 is d0 ~d40(TX) + */ + chn_id_tmp1 = + (p_tmp_data_arr[0] << 8) + p_tmp_data_arr[1]; + { + /*Tx*/ + for (j = 0; j < max_drv_num_in_die; j++) { + short_code_tmp = + (p_tmp_data_arr[NORM_SHORT_HEAD + + j * 2] + << 8) + + p_tmp_data_arr[NORM_SHORT_HEAD + + j * 2 + 1]; + chn_id_tmp1 |= CHANNEL_TX_FLAG; + chn_id_tmp2 = (j + max_sen_num_in_die) | + CHANNEL_TX_FLAG; + if (short_code_tmp >= + p_short_param->short_threshold + .gt_short_threshold) { + id_tmp = short_id_to_selfdata_id( + p_dev, chn_id_tmp1); + short_r = calc_short_chn( + p_dev, chn_id_tmp1, + chn_id_tmp2, + p_self_code_arr[id_tmp], + short_code_tmp); + if (short_r < + p_short_param->short_threshold + .drv_drv_resistor_threshold * + 10) { + store_short_mess_in_res( + chn_id_tmp1, + chn_id_tmp2, + short_r, + p_short_res); + } + } + } + } + /*update address*/ + chn_short_mess_addr += data_len_tmp; + } + } + /*Rx & Rx*/ + if (0x02 == (short_flag & 0x02)) { + chn_short_mess_addr = NORM_SHORT_RxRx_PIN_NUM_ADDR; + /*2 bytes short pin num + //2 bytes reserved + //2*max_sen_num_in_die bytes RX buffer + //2 bytes check sum + */ + data_len_tmp = 2 + 2 + 2 * max_sen_num_in_die + 2; + for (i = 0; i < chn_short_cnt[1]; i++) { + /*get short code*/ + for (j = 0; j < retry_cnt; j++) { + ret = chip_reg_read(p_dev, chn_short_mess_addr, + p_tmp_data_arr, + data_len_tmp); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_error( + "%s\n", + "in analyse Rx & Rx, read short code fail"); + goto ANALYSE_SHORT_RES_END; + } + /*calc resistor*/ + chn_id_tmp1 = (p_tmp_data_arr[0] << 8) + + p_tmp_data_arr[1]; /*Rx*/ + { + /*Rx*/ + for (j = 0; j < max_sen_num_in_die; j++) { + /*filter this case*/ + if (j == chn_id_tmp1 || + (j < chn_id_tmp1 && + ((j & 0x01) == 0))) { + continue; + } + + short_code_tmp = + (p_tmp_data_arr[NORM_SHORT_HEAD + + j * 2] + << 8) + + p_tmp_data_arr[NORM_SHORT_HEAD + + j * 2 + 1]; + chn_id_tmp2 = (u8)j; + if (short_code_tmp >= + p_short_param->short_threshold + .gt_short_threshold) { + id_tmp = short_id_to_selfdata_id( + p_dev, chn_id_tmp1); + short_r = calc_short_chn( + p_dev, chn_id_tmp1, + chn_id_tmp2, + p_self_code_arr[id_tmp], + short_code_tmp); + if (short_r < + p_short_param->short_threshold + .sen_sen_resistor_threshold * + 10) { + store_short_mess_in_res( + chn_id_tmp1, + chn_id_tmp2, + short_r, + p_short_res); + } + } + } + } + /*update address*/ + chn_short_mess_addr += data_len_tmp; + } + } + /*Tx & Rx*/ + if (0x04 == (short_flag & 0x04)) { + chn_short_mess_addr = NORM_SHORT_TxRx_PIN_NUM_ADDR; + /*2 bytes short pin num + //2 bytes reserved + //2*max_drv_num_in_die bytes RX buffer + //2 bytes check sum + */ + data_len_tmp = 2 + 2 + 2 * max_drv_num_in_die + 2; + for (i = 0; i < chn_short_cnt[2]; i++) { + /*get short code*/ + for (j = 0; j < retry_cnt; j++) { + ret = chip_reg_read(p_dev, chn_short_mess_addr, + p_tmp_data_arr, + data_len_tmp); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_error( + "%s\n", + "in analyse Tx & Rx, read short code fail"); + goto ANALYSE_SHORT_RES_END; + } + /*calc resistor*/ + chn_id_tmp1 = (p_tmp_data_arr[0] << 8) + + p_tmp_data_arr[1]; /*Rx*/ + { + /*Tx*/ + for (j = 0; j < max_drv_num_in_die; j++) { + short_code_tmp = + (p_tmp_data_arr[NORM_SHORT_HEAD + + j * 2] + << 8) + + p_tmp_data_arr[NORM_SHORT_HEAD + + j * 2 + 1]; + chn_id_tmp2 = (j + max_sen_num_in_die) | + CHANNEL_TX_FLAG; + if (short_code_tmp >= + p_short_param->short_threshold + .gt_short_threshold) { + id_tmp = short_id_to_selfdata_id( + p_dev, chn_id_tmp1); + short_r = calc_short_chn( + p_dev, chn_id_tmp1, + chn_id_tmp2, + p_self_code_arr[id_tmp], + short_code_tmp); + if (short_r < + p_short_param->short_threshold + .drv_sen_resistor_threshold * + 10) { + store_short_mess_in_res( + chn_id_tmp1, + chn_id_tmp2, + short_r, + p_short_res); + } + } + } + } + /*update address*/ + chn_short_mess_addr += data_len_tmp; + } + } + if (p_short_res->short_num > 0) { + p_short_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = SHORT_TEST_EXIST_SHORT; + p_short_res->item_res_header.test_status = TEST_ABORTED; + p_short_res->item_res_header.test_result = TEST_NG; + } + +ANALYSE_SHORT_RES_END: + free_mem_block(p_tmp_data_arr); + free_mem_block(p_self_code_arr); + return ret; +} + +/******************************************************************************* +* Function Name : short_id_to_selfdata_id +* Description : short_id_to_selfdata_id +* Input : PST_TP_DEV p_dev +* Input : u8 short_id +* Output : none +* Return : u8(0:fail 1:ok) +*******************************************************************************/ +static u8 short_id_to_selfdata_id(IN PST_TP_DEV p_dev, IN u8 short_id) +{ + u8 ret = 0; + /*drv*/ + if ((short_id & CHANNEL_TX_FLAG) == CHANNEL_TX_FLAG) { + ret = (short_id & ~CHANNEL_TX_FLAG) - p_dev->max_sen_num_in_die; + } else { + ret = short_id + p_dev->max_drv_num_in_die; + } + return ret; +} + +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/normandy_short_test.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/normandy_short_test.h new file mode 100644 index 000000000000..328110725ac2 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/normandy_short_test.h @@ -0,0 +1,56 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : normandy_short_test.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 10/26/2017 +* Description : normandy short test +*******************************************************************************/ +#ifndef NORMANDY_SHORT_TEST_H +#define NORMANDY_SHORT_TEST_H + +#include "user_test_type_def.h" + +#include "test_item_def.h" +#include "tp_dev_control.h" +#include "public_fun.h" + +/*------------------------------------define-----------------------------------*/ +/*Address*/ +#define NORM_SHORT_STA_ADDR 0x5095 +#define NORM_ESD_KEY_ADDR 0x20B0 +#define NORM_SHORT_TXRX_ADC_THD_ADDR 0x8408 +#define NORM_SHORT_DIFF_THD_ADDR 0x840A +#define NORM_ADC_READ_DELAY_ADDR 0x840C + +#define NORM_SEN_CONFIG_ADDR 0x8436 +#define NORM_DRV_CONFIG_ADDR 0x840E +#define NORM_SHORT_CHECKSUM_ADDR 0x845A + +#define NORM_SHORT_TESTEND_ADDR 0x8400 +#define NORM_SHORT_TEST_RESULT_ADDR 0x8401 +#define NORM_SHORT_NUMBER_ADDR 0x8402 +#define NORM_SHORT_DRVSELFCODE_ADDR 0xA8E0 +#define NORM_SHORT_DIFFCODE_ADDR 0xA97A +#define NORM_SHORT_TxTx_PIN_NUM_ADDR 0x8460 +#define NORM_SHORT_RxRx_PIN_NUM_ADDR 0x91D0 +#define NORM_SHORT_TxRx_PIN_NUM_ADDR 0x9CC8 + +/*Status*/ +#define NORM_SHORT_STA_READY 0xAA +#define NORM_SHORT_START_TEST 0x00 +#define NORM_SHORT_TX_TEST_END 0x08 +#define NORM_SHORT_RX_TEST_END 0x80 +#define NORM_SHORT_ALL_TEST_END 0x88 + +#define NORM_SHORT_HEAD 4 +/*------------------------------------define-----------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif + +extern s32 normandy_short_test(ptr32 p_data); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/public_fun.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/public_fun.c new file mode 100644 index 000000000000..2d46c4c56d45 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/public_fun.c @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : public_func.cpp +* Author : Bob Huang +* Version : V1.0.0 +* Date : 10/23/2017 +* Description : this file contain some public functions that do not depend + on platform such as Windows,Arm or Android +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifdef __cplusplus +extern "C" { +#endif + +#include "public_fun.h" + +/******************************************************************************* +* Function Name : compare_buffer +* Description : compare_buffer +* Input : u8* src_buf + : u8* dest_buf + : u8 size +* Output : none +* Return : src_buf == dest_buf 1 else return 0 +*******************************************************************************/ +extern s32 compare_buffer(IN u8 *src_buf, IN u8 *dest_buf, IN u8 size) +{ + u8 index; + for (index = 0; index < size; size++) { + if (src_buf[index] != dest_buf[index]) { + return 0; + } + } + return 1; +} + +/******************************************************************************* +* Function Name : current_test_status +* Description : compare_buffer +* Input : IN u8 res +* Output : IN_OUT P_TEST_ITEM_RES p_res +* Return : 1,0 +*******************************************************************************/ +extern s32 current_test_status(IN u8 res, IN_OUT P_TEST_ITEM_RES p_res) +{ + if (res == 1) + return 1; + else { + p_res->test_status = TEST_ABORTED; + p_res->test_result = TEST_WARNING; + } + return 0; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/public_fun.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/public_fun.h new file mode 100644 index 000000000000..92f47b8b493a --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/public_fun.h @@ -0,0 +1,28 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : public_func.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 10/23/2017 +* Description : this file contain some public functions that do not depend + on platform such as Windows,Arm or Android +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef PUBLIC_FUN_H +#define PUBLIC_FUN_H + +#include "user_test_type_def.h" +#include "test_item_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern s32 compare_buffer(u8 *src_buf, u8 *dest_buf, u8 size); +extern s32 current_test_status(u8 res, P_TEST_ITEM_RES p_res); + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/res_inc.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/res_inc.h new file mode 100644 index 000000000000..0c67c5360790 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/res_inc.h @@ -0,0 +1,167 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : res_inc.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 01/22/2018 +* Description : resource include +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef RES_INC_H +#define RES_INC_H + +/*#ifdef __cplusplus +extern "C" { +#endif*/ + +#include "user_test_type_def.h" +#include "tp_dev_def.h" +#if ARM_CODE == 1 +#ifdef STM32F4XX +#include "stm32f4xx.h" +#endif +#ifdef STM32F1XX +/*STM32F10x Library Definitions*/ +#include "Gpio_define.h" +#endif +#elif PC_CODE == 1 +#include "TestInclude.h" + +#ifdef _DEBUG +#include "MemoryLeakDetected.h" +#define new DEBUG_NEW +#endif + +#elif QNX_CODE == 1 + +#endif +/****************************test board resouce define***************************/ +#if ARM_CODE != 1 + +#define GPIO_Pin_0 ((u16)0x0001) /* Pin 0 selected */ +#define GPIO_Pin_1 ((u16)0x0002) /* Pin 1 selected */ +#define GPIO_Pin_2 ((u16)0x0004) /* Pin 2 selected */ +#define GPIO_Pin_3 ((u16)0x0008) /* Pin 3 selected */ +#define GPIO_Pin_4 ((u16)0x0010) /* Pin 4 selected */ +#define GPIO_Pin_5 ((u16)0x0020) /* Pin 5 selected */ +#define GPIO_Pin_6 ((u16)0x0040) /* Pin 6 selected */ +#define GPIO_Pin_7 ((u16)0x0080) /* Pin 7 selected */ +#define GPIO_Pin_8 ((u16)0x0100) /* Pin 8 selected */ +#define GPIO_Pin_9 ((u16)0x0200) /* Pin 9 selected */ +#define GPIO_Pin_10 ((u16)0x0400) /* Pin 10 selected */ +#define GPIO_Pin_11 ((u16)0x0800) /* Pin 11 selected */ +#define GPIO_Pin_12 ((u16)0x1000) /* Pin 12 selected */ +#define GPIO_Pin_13 ((u16)0x2000) /* Pin 13 selected */ +#define GPIO_Pin_14 ((u16)0x4000) /* Pin 14 selected */ +#define GPIO_Pin_15 ((u16)0x8000) /* Pin 15 selected */ +#define GPIO_Pin_All ((u16)0xFFFF) /* All pins selected */ + +typedef enum { + GPIO_Speed_10MHz = 1, + GPIO_Speed_2MHz, + GPIO_Speed_50MHz +} GPIOSpeed_TypeDef; + +/*Test board Rst pin*/ +#define MODULE_SHDN GPIO_Pin_12 +#define MODULE_SHDN_PORT TPYE_GPIO_C + +#define nV_LEVEL_EN_PORT TPYE_GPIO_B +#define nV_LEVEL_EN_PIN GPIO_Pin_4 + +#define G_IC_INT_PORT TPYE_GPIO_B +#define G_IC_INT_PIN GPIO_Pin_2 + +#define G_SPI_NSS_PORT TPYE_GPIO_B +#define G_SPI_NSS_PIN GPIO_Pin_12 /*SPI_CS*/ + +#define ADC_GF_INT_PORT TPYE_GPIO_B +#define ADC_GF_INT_PIN GPIO_Pin_1 + +#define GF_RST_PORT TPYE_GPIO_B +#define GF_RST_PIN GPIO_Pin_0 + +#define G_IC_SHDN_PORT TPYE_GPIO_B +#define G_IC_SHDN_PIN GPIO_Pin_11 + +#define DAC_PROPER_RANGE (u16)15 /*if (1-x)% ~ (1+x)% dac output ok*/ +#define DVE_TYPE_IIC 0x00; +#define DVE_TYPE_SPI 0x01; +#else +#include "stm32f10x_gpio.h" +#endif + +enum { + TPYE_GPIO_A, + TPYE_GPIO_B, + TPYE_GPIO_C, + TPYE_GPIO_D, + TPYE_GPIO_E, + TPYE_GPIO_F, + TPYE_GPIO_G, + TPYE_GPIO_H, +}; + +/*io mode type*/ +typedef enum { GIO_LOW = 0x00, GIO_HIGH = 0x01 } GIOBit_Def; + +typedef enum { + Mode_AIN = 0x00, + Mode_IPD = 0x28, + Mode_IPU = 0x48, + Mode_Out_OD = 0x14, + Mode_Out_PP = 0x10, + Mode_AF_OD = 0x1C, + Mode_AF_PP = 0x18, + + MODE_PD = 0x02, /*pull down*/ + MODE_PU = 0x03, /*pull up*/ + Mode_IN_FLOATING = 0x04, /*floating*/ + MODE_OUTPUT = 0x05 /*output*/ +} GIOMode_Def; +/*define INT id*/ +#define MODULE_INT_ID 5 +/* +// in test board we use pin12 as shdn to reset chip +// how to know group of pin +// in doc we can see PA PB PC PD,for example, +// look for GUITAR TEST TOOL SCH V4.1_20150624.pdf +// we know line 53-PC12/USART5_TX is MODULE_SHDN ,so we can use GPIOC*/ +#define MODULE_IC GPIO_Pin_2 +#define MODULE_EN GPIO_Pin_4 +/* PB5 GPIOB*/ +#define MODULE_INT GPIO_Pin_5 +#define MODULE_SCL GPIO_Pin_8 +#define MODULE_SDA GPIO_Pin_9 + +#define ADC_I_AVDD GPIO_Pin_6 +#define ADC_Is_AVDD GPIO_Pin_7 + +/*ADC define*/ +#define ADC_V_AVDD_VALUE ((u8)0x01) +#define ADC_V_VDDIO_VALUE ((u8)0x02) +#define ADC_VREF_PIN_VALUE ((u8)0x03) +#define ADC_I_AVDD_VALUE ((u8)0x04) +#define ADC_Is_AVDD_VALUE ((u8)0x05) +#define ADC_I_VDDIO_VALUE ((u8)0x0C) +#define ADC_Is_VDDIO_VALUE ((u8)0x0D) +#define ADC_M_SHDN_VALUE ((u8)0x08) +#define ADC_M_INT_VALUE ((u8)0x09) +#define ADC_M_SCL_VALUE ((u8)0x0A) +#define ADC_M_SDA_VALUE ((u8)0x0B) +#define ADC_GF_RST_VALUE ((u8)0x06) +#define ADC_GF_INT_VALUE ((u8)0x07) + +/*ADS1015 define*/ +#define ADS_FLAG 0x80 +#define ADS_SPI_CS_VALUE ((u8)(0x4 | ADS_FLAG)) +#define ADS_SPI_SCK_VALUE ((u8)(0x5 | ADS_FLAG)) +#define ADS_SPI_MOSI_VALUE ((u8)(0x6 | ADS_FLAG)) +#define ADS_SPI_MISO_VALUE ((u8)(0x7 | ADS_FLAG)) + +/*#ifdef __cplusplus +} +#endif*/ + +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/save_test_data.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/save_test_data.c new file mode 100644 index 000000000000..0360b883e515 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/save_test_data.c @@ -0,0 +1,355 @@ +/******************** (C) COPYRIGHT 2018 Goodix ******************** +* File Name : save_test_data.cpp +* Author : +* Version : V1.0.0 +* Date : 27/03/2018 +* Description : save test data +*******************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#include "save_test_data.h" + +#include "tp_dev_control.h" +#include "tp_open_test.h" +#include "tp_short_test.h" +#include "tp_version_test.h" +#include "tp_additional_option.h" +#include "simple_mem_manager.h" +#include "test_order.h" +#include "generic_func.h" +#include "board_opr_interface.h" +/******************************************************************************* +* Function Name : print_rawdata_test_res +* Description : print rawdata test reult +* Input : ptr32 p_data (You must cast it to type PST_TEST_ORDER ) +* Output : ptr32 p_data +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 print_rawdata_test_res(ptr32 p_data) +{ + s32 ret = 1; + u16 i = 0; + PST_TEST_ITEM p_test_item = NULL; + PST_RAWDATA_TEST_RES p_raw_test_res = NULL; + s32 open_test_res = 0; + PST_TP_DEV p_tp_dev = NULL; + u16 node_num = 0; + u8 key_num = 0; + PST_SUB_TEST_ITEM_ID_SET p_sub_id_set = NULL; + + p_test_item = (PST_TEST_ITEM)p_data; + p_raw_test_res = (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + open_test_res = p_raw_test_res->open_test_result; + p_tp_dev = p_test_item->p_tp_dev; + node_num = p_tp_dev->sc_sen_num * p_tp_dev->sc_drv_num; + key_num = p_tp_dev->key_num; + p_sub_id_set = p_raw_test_res->item_res_header.p_sub_id_set; + + modify_test_result(open_test_res); + board_print_info("\n---Show open test result!---\n"); + if ((p_raw_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] != RAWDATA_TEST_FAIL) && + (p_raw_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] != RAWDATA_TEST_SUCCESSFULLY)) { + board_print_info("OPEN TEST ABORTED: OPEN TEST ERROR!\n"); + return 1; + } + if (p_sub_id_set->len == 0) { + board_print_info("RAWDATA TEST PASS!\n"); + } + + for (i = 0; i < p_sub_id_set->len; i++) { + switch (p_sub_id_set->p_id_set[i]) { + case TP_RAWDATA_MAX_TEST_ITEM_ID: { + if ((open_test_res & BEYOND_RAWDATA_UPPER_LIMIT) != 0) { + board_print_info( + "BEYOND RAWDATA UPPER LIMIT!\n"); + /*print_beyond_limit_node(p_raw_test_res->p_beyond_rawdata_upper_limit_cnt,node_num);*/ + } else { + board_print_info( + "RAWDATA UPPER LIMIT TEST PASS!\n"); + } + break; + } + case TP_RAWDATA_MIN_TEST_ITEM_ID: { + if ((open_test_res & BEYOND_RAWDATA_LOWER_LIMIT) != 0) { + board_print_info( + "BEYOND RAWDATA LOWER LIMIT!\n"); + /*print_beyond_limit_node(p_raw_test_res->p_beyond_rawdata_lower_limit_cnt,node_num);*/ + } else { + board_print_info( + "RAWDATA LOWER LIMIT TEST PASS!\n"); + } + break; + } + case TP_KEYDATA_MAX_TEST_ITEM_ID: { + if ((open_test_res & KEY_BEYOND_UPPER_LIMIT) != 0) { + board_print_info("KEY BEYOND UPPER LIMIT!\n"); + /*print_beyond_limit_node(p_raw_test_res->p_beyond_key_upper_limit_cnt,key_num);*/ + } else { + board_print_info( + "KEYDATA UPPER LIMIT TEST PASS!\n"); + } + break; + } + case TP_KEYDATA_MIN_TEST_ITEM_ID: { + if ((open_test_res & KEY_BEYOND_LOWER_LIMIT) != 0) { + board_print_info("KEY BEYOND LOWER LIMIT!\n"); + /*print_beyond_limit_node(p_raw_test_res->p_beyond_key_lower_limit_cnt,key_num);*/ + } else { + board_print_info( + "KEYDATA LOWER LIMIT TEST PASS!\n"); + } + break; + } + case TP_OFFSET_TEST_ITEM_ID: { + if ((open_test_res & BEYOND_OFFSET_LIMIT) != 0) { + board_print_info("BEYOND OFFSET LIMIT!\n"); + /*print_beyond_limit_node(p_raw_test_res->p_beyond_offset_limit_cnt,node_num);*/ + } else { + board_print_info("OFFSET TEST PASS!\n"); + } + break; + } + case TP_RAWDATA_JITTER_TEST_ITEM_ID: { + if ((open_test_res & BEYOND_JITTER_LIMIT) != 0) { + board_print_info("BEYOND JITTER LIMIT!\n"); + /*rint_beyond_limit_node(p_raw_test_res->p_beyond_jitter_limit_cnt,node_num);*/ + } else { + board_print_info("JITTER TEST PASS!\n"); + } + break; + } + case TP_ACCORD_TEST_ITEM_ID: { + if ((open_test_res & BEYOND_ACCORD_LIMIT) != 0) { + board_print_info("BEYOND ACCORD LIMIT!\n"); + /*print_beyond_limit_node(p_raw_test_res->p_beyond_accord_limit_cnt,node_num);*/ + } else { + board_print_info("ACCORD TEST PASS!\n"); + } + break; + } + case TP_UNIFORMITY_TEST_ITEM_ID: { + if ((open_test_res & BEYOND_UNIFORMITY_LIMIT) != 0) { + board_print_info("BEYOND UNIFORMITY LIMIT!\n"); + /*print_beyond_limit_node(p_raw_test_res->p_beyond_jitter_limit_cnt,node_num);*/ + } else { + board_print_info("UNIFORMITY TEST PASS!\n"); + } + break; + } + default: + break; + } + } + + return ret; +} + +/******************************************************************************* +* Function Name : print_short_test_res +* Description : print short test result +* Input : ptr32 p_data(You must cast it to type PST_TEST_ORDER ) +* Output : +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 print_short_test_res(ptr32 p_data) +{ + s32 ret = 1; + u16 i = 0; + PST_TEST_ITEM p_test_item = NULL; + PST_SHORT_TEST_RES p_short_res = NULL; + + p_test_item = (PST_TEST_ITEM)p_data; + p_short_res = (PST_SHORT_TEST_RES)p_test_item->test_res.ptr_res; + board_print_info("\n---show short test result!---\n"); + modify_test_result(p_short_res->item_res_header.test_item_err_code + .ptr_err_code_set[0]); + if ((p_short_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] != SHORT_TEST_NONE_ERROR) && + (p_short_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] != SHORT_TEST_EXIST_SHORT)) { + board_print_info("SHORT TEST ABORTED:SHORT TEST ERROR!\n"); + return 1; + } + + if (p_short_res->short_num > 0) { + board_print_info("SHORT TEST FAILD!\n"); + for (i = 0; i < p_short_res->short_num; i++) { + if (p_short_res->short_mess_arr[4 * i + 0] == + CHANNEL_GND) { + board_print_info("GND and "); + } else if (p_short_res->short_mess_arr[4 * i + 0] == + CHANNEL_VDD) { + board_print_info("VDD and "); + } else { + if (p_short_res->short_mess_arr[4 * i + 0] & + 0x80) { + board_print_info( + "drv-%d and ", + p_short_res->short_mess_arr + [4 * i + 0] & + 0x7f); + } else { + board_print_info( + "sen-%d and ", + p_short_res->short_mess_arr + [4 * i + 0] & + 0x7f); + } + } + + if (p_short_res->short_mess_arr[4 * i + 1] == + CHANNEL_GND) { + board_print_info("GND short,"); + } else if (p_short_res->short_mess_arr[4 * i + 1] == + CHANNEL_VDD) { + board_print_info("VDD short,"); + } else { + if (p_short_res->short_mess_arr[4 * i + 1] & + 0x80) { + board_print_info( + "drv-%d short,", + p_short_res->short_mess_arr + [4 * i + 1] & + 0x7f); + } else { + board_print_info( + "sen-%d short,", + p_short_res->short_mess_arr + [4 * i + 1] & + 0x7f); + } + } + board_print_info( + "short r=%d Kohm\n", + (((p_short_res->short_mess_arr[4 * i + 2] << 8) + + p_short_res->short_mess_arr[4 * i + 3])) / + 10); + } + } else { + board_print_info("SHORT TEST PASS!\n"); + } + return ret; +} + +/******************************************************************************* +* Function Name : print_version_test_res +* Description : print version test result +* Input : ptr32 p_data(You must cast it to type PST_TEST_ORDER ) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 print_version_test_res(ptr32 p_data) +{ + s32 ret = 1; + + PST_TEST_ITEM p_test_item = NULL; + PST_VERSION_TEST_RES p_ver_test_res = NULL; + PST_VERSION_PARAM p_ver_param = NULL; + + p_test_item = (PST_TEST_ITEM)p_data; + p_ver_test_res = (PST_VERSION_TEST_RES)p_test_item->test_res.ptr_res; + p_ver_param = (PST_VERSION_PARAM)p_test_item->param.ptr_param; + board_print_info("\n---Show fw version test result!---\n"); + + modify_test_result(p_ver_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0]); + if (p_ver_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] == VERSION_TEST_NONE_ERROR) { + board_print_info("FW VERSION TEST PASS!\n"); + } else { + board_print_info("VERSION TEST FAILD!\n"); + } + return ret; +} + +/******************************************************************************* +* Function Name : print_flash_test_res +* Description : print flash test result +* Input : ptr32 p_data(You must cast it to type PST_TEST_ORDER ) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 print_flash_test_res(ptr32 p_data) +{ + s32 ret = 1; + PST_TEST_ITEM p_test_item = NULL; + PST_FLASH_TEST_RES p_flash_test_res = NULL; + + p_test_item = (PST_TEST_ITEM)p_data; + p_flash_test_res = (PST_FLASH_TEST_RES)p_test_item->test_res.ptr_res; + board_print_info("\n---Show flash test result!---\n"); + + modify_test_result(p_flash_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0]); + if (p_flash_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] == FLASH_TEST_ERROR_CODE_NONE) { + board_print_info("FLASH TEST PASS!\n"); + } else { + board_print_info("FLASH TEST FAILD!\n"); + } + return ret; +} + +/******************************************************************************* +* Function Name : print_send_cfg_test_res +* Description : print send config test result +* Input : ptr32 p_data(You must cast it to type PST_TEST_ORDER ) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 print_send_cfg_test_res(ptr32 p_data) +{ + s32 ret = 1; + PST_TEST_ITEM p_test_item = NULL; + PST_CHIP_CONFIG_PROC_RES p_send_cfg_test_res = NULL; + + p_test_item = (PST_TEST_ITEM)p_data; + p_send_cfg_test_res = + (PST_CHIP_CONFIG_PROC_RES)p_test_item->test_res.ptr_res; + board_print_info("\n---Show send config test result!---\n"); + modify_test_result(p_send_cfg_test_res->item_res_header + .test_item_err_code.ptr_err_code_set[0]); + if (p_send_cfg_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] == CFG_CHECK_TEST_NONE_ERROR) { + board_print_info("SEND CONFIG TEST PASS!\n"); + } else { + board_print_info("SEND CONFIG FAILD!\n"); + } + return ret; +} + +/******************************************************************************* +* Function Name : print_cfg_recover_test_res +* Description : print config recover test result +* Input : ptr32 p_data(You must cast it to type PST_TEST_ORDER ) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 print_cfg_recover_test_res(ptr32 p_data) +{ + s32 ret = 1; + PST_TEST_ITEM p_test_item = NULL; + PST_RECOVER_CHIP_CFG_RES p_cfg_recover_test_res = NULL; + p_test_item = (PST_TEST_ITEM)p_data; + p_cfg_recover_test_res = + (PST_RECOVER_CHIP_CFG_RES)p_test_item->test_res.ptr_res; + board_print_info("\n---Show cfg recover test result!---\n"); + + modify_test_result(p_cfg_recover_test_res->item_res_header + .test_item_err_code.ptr_err_code_set[0]); + if (p_cfg_recover_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] == RECOVER_CFG_ERROR_CODE_NONE) { + board_print_info("CONFIG RECOVER TEST PASS!\n"); + } else { + board_print_info("CONFIG RECOVER FAILD!\n"); + } + return ret; +} + +#ifdef __cplusplus +} +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/save_test_data.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/save_test_data.h new file mode 100644 index 000000000000..add6f3571ff6 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/save_test_data.h @@ -0,0 +1,43 @@ +/******************** (C) COPYRIGHT 2018 Goodix ******************** +* File Name : save_test_data.h +* Author : +* Version : V1.0.0 +* Date : 28/03/2018 +* Description : save test data +*******************************************************************************/ +#ifndef SAVE_TEST_DATA_H +#define SAVE_TEST_DATA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "user_test_type_def.h" +#include "mxml.h" +#include "config.h" + +#define GT_SHORT 0x00400000 +#define VERSION_ERR 0x10000 +#define BEYOND_FLASH_LAYER_LIMIT 0x01000000 +#define SEND_CONFIG_ERR 0x00100000 +#define RECOVER_CONFIG_ERR 0x00200000 +#define TEST_ABORT 0x00000100 + +/***********************************print test data**************************************/ +extern s32 print_rawdata_test_res(ptr32 p_data); +/*print short test result*/ +extern s32 print_short_test_res(ptr32 p_data); +/*print version test result*/ +extern s32 print_version_test_res(ptr32 p_data); +/*print flash test result*/ +extern s32 print_flash_test_res(ptr32 p_data); +/*print send config test result*/ +extern s32 print_send_cfg_test_res(ptr32 p_data); +/*print cfg recover test result*/ +extern s32 print_cfg_recover_test_res(ptr32 p_data); +/**********************************print test data end**********************************/ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/simple_mem_manager.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/simple_mem_manager.h new file mode 100644 index 000000000000..c85f3b40b4fa --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/simple_mem_manager.h @@ -0,0 +1,33 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : simple_mem_manager.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 08/23/2017 +* Description : we use this module manger memory pool +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef SIMPLE_MEM_MANAGER_H +#define SIMPLE_MEM_MANAGER_H + +#include "user_test_type_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**********************memory manger in stack*******************************/ +extern s32 alloc_mem_block(void **pp_buf, u16 buf_size); +extern s32 free_mem_block(void *p_buf); + +/**********************memory manger in heap*******************************/ +extern s32 alloc_mem_in_heap(void **pp_param, u32 data_size); +extern s32 free_mem_in_heap(void *p_param); + +extern s32 free_mem_in_heap_p(void **pp_param); + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/simple_mem_manager_mach.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/simple_mem_manager_mach.c new file mode 100644 index 000000000000..5300b07c57f6 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/simple_mem_manager_mach.c @@ -0,0 +1,105 @@ +/******************** (C) COPYRIGHT 2018 Goodix ******************** +* File Name : simple_mem_manager_mach.cpp +* Author : +* Version : V1.0.0 +* Date : 05/14/2018 +* Description : we use this module manager memory,or support dynamic memory +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#include "simple_mem_manager.h" +#include "board_opr_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* +* Function Name : alloc_mem_block +* Description : allocate memory block +* Input : void** pp_buf(pointer to buffer pointer) + : u16 buf_size (no more than 8K) +* Output : void** pp_buf +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 alloc_mem_block(IN_OUT void **pp_buf, IN u16 buf_size) +{ + s32 ret = 0; + (*pp_buf) = (void *)malloc(buf_size * sizeof(u8)); + if (NULL != (*pp_buf)) { + ret = 1; + } + return ret; +} + +/******************************************************************************* +* Function Name : free_mem_block +* Description : free memory block +* Input : void* p_buf +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 free_mem_block(IN void *p_buf) +{ + s32 ret = 0; + if (p_buf != NULL) { + ret = free_mem_in_heap(p_buf); + } + return ret; +} + +/******************************************************************************* +* Function Name : alloc_mem_in_heap +* Description : alloc memory in heap +* Input : void** pp_param(pointer to buffer pointer) + : u32 data_size +* Output : void** pp_param +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 alloc_mem_in_heap(IN_OUT void **pp_param, IN u32 data_size) +{ + s32 ret = 0; + (*pp_param) = (void *)malloc(data_size * sizeof(u8)); + if (NULL != (*pp_param)) { + ret = 1; + } + + return ret; +} + +/******************************************************************************* +* Function Name : free_mem_in_heap +* Description : free memory in heap +* Input : void* p_param(buffer pointer) +* Output : void* p_param +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 free_mem_in_heap(IN void *p_param) +{ + if (p_param != NULL) { + free(p_param); + p_param = NULL; + } + return 1; +} +/******************************************************************************* +* Function Name : free_mem_in_heap_p +* Description : free memory in heap +* Input : void** pp_param(pointer to buffer pointer) +* Output : void** pp_param +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 free_mem_in_heap_p(IN_OUT void **pp_param) +{ + if (*pp_param != NULL) { + free(*pp_param); + *pp_param = NULL; + } + return 1; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/strtol.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/strtol.c new file mode 100644 index 000000000000..3a97167cfbe2 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/strtol.c @@ -0,0 +1,58 @@ +#define LONG_MAX 2147483647L /*0x7FFFFFFF */ +#define LONG_MIN (-2147483647L - 1L) /*-0x80000000*/ + +int strtol(const char *nptr, char **endptr, int base) +{ + const char *p = nptr; + unsigned long ret; + int ch; + unsigned long Overflow; + int sign = 0, flag, LimitRemainder; + /*delete space*/ + do { + ch = *p++; + } while (isspace(ch)); + if (ch == '-') { + sign = 1; + ch = *p++; + } else if (ch == '+') + ch = *p++; + if ((base == 0 || base == 16) && ch == '0' && + (*p == 'x' || *p == 'X')) { + ch = p[1]; + p += 2; + base = 16; + } + if (base == 0) + base = ch == '0' ? 8 : 10; + Overflow = sign ? -(unsigned long)LONG_MIN : LONG_MAX; + LimitRemainder = Overflow % (unsigned long)base; + Overflow /= (unsigned long)base; + for (ret = 0, flag = 0;; ch = *p++) { + /*get target value*/ + if (isdigit(ch)) + ch -= '0'; + else if (isalpha(ch)) + ch -= isupper(ch) ? 'A' - 10 : 'a' - 10; + else + break; + if (ch >= base) + break; + /*overflow*/ + if (flag < 0 || ret > Overflow || + (ret == Overflow && ch > LimitRemainder)) + flag = -1; + else { + flag = 1; + ret *= base; + ret += ch; + } + } + if (flag < 0) + ret = sign ? LONG_MIN : LONG_MAX; + else if (sign) + ret = -ret; + if (endptr != 0) + *endptr = (char *)(flag ? (p - 1) : nptr); + return ret; +} diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_item_def.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_item_def.h new file mode 100644 index 000000000000..43cbccac9ffc --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_item_def.h @@ -0,0 +1,180 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : test_item_def.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : define test item id or test item error code or struct +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef TEST_ITEM_DEF_H +#define TEST_ITEM_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tp_test_item_id.h" +#include "tp_dev_def.h" + +/*test item callback function pointer define*/ +typedef s32 (*TEST_CALLBACK_PTR)(ptr32); + +/*test item callback function pointer define*/ +typedef TEST_CALLBACK_PTR TEST_ITEM_FUNC_PTR; + +/*sub test item id set*/ +typedef struct SUB_TEST_ITEM_ID_SET { + u8 len; + u8 *p_id_set; +} ST_SUB_TEST_ITEM_ID_SET, *PST_SUB_TEST_ITEM_ID_SET; + +/*test item define*/ +typedef struct TEST_ITEM { + /*test item id*/ + u16 test_item_id; + + /*sub test item id set*/ + PST_SUB_TEST_ITEM_ID_SET p_sub_id_set; + + /*touch panel device*/ + PST_TP_DEV p_tp_dev; + + /*we use this variable optimal + //(1)In arm test board platform,this variable store starting address of test item parameter in flash + //(2)In other platform ,this variable store pointer of test item parameter,now it is not used + */ + union { + u32 item_addr_u32; + ptr32 item_addr_ptr; + } item_addr_start; + + /*current data*/ + union { + u32 n_cur_data; /*interger data*/ + ptr32 ptr_cur_data; /*pointer data*/ + } cur_data; + + /*you can use this for parameter limit or other infomation*/ + union { + u32 n_param; /*interger data*/ + ptr32 ptr_param; /*pointer data*/ + } param; + + /*test callback function*/ + TEST_ITEM_FUNC_PTR ptr_general_func; + ptr32 ptr_general_func_param; + + /*this function may use p_tp_dev to decide some branch + //the return value 1 means ok,0 means fail + //the parameter of function is 'TEST_ITEM' + */ + TEST_ITEM_FUNC_PTR ptr_test_func; + + /*this function is used to do some word for preparing testing,such as + //(1)set some hardware + //(2)get test parameter pointer + //(3)notify test starting + //the return value 1 means ok,0 means fail + */ + TEST_ITEM_FUNC_PTR ptr_test_item_before_func; + ptr32 ptr_test_item_before_func_param; + + /*this function is used to do some word for finish testing,such as + //(1)recover some hardware + //(2)notify function + //(3)save test result + //(4)notify test finished + //the return value 1 means ok,0 means fail + */ + TEST_ITEM_FUNC_PTR ptr_test_item_finished_func; + ptr32 ptr_test_item_finished_func_param; + + /*test result*/ + union { + u32 n_res; /*integer data*/ + ptr32 ptr_res; /*pointer data*/ + } test_res; + + /*shared data,you can use this data to communicate with other module*/ + ptr32 ptr_share_data; + + /*this pointer to ST_TEST_PROC_DATA*/ + ptr32 ptr_test_proc_data; + + /*this pointer point special struct which contains special callback function + //you must cast this pointer to you declared struct + */ + ptr32 ptr_special_callback_data; + +} ST_TEST_ITEM, *PST_TEST_ITEM; + +/*test result enum define */ +typedef enum TEST_RESULT { + TEST_OK = 0x00, + TEST_NG = 0x01, + TEST_WARNING = 0x02 +} ENUM_TEST_RESULT; + +/*test status define*/ +typedef enum TEST_STATUS { + TEST_NOT_START = 0x00, + TEST_START = 0x01, + TEST_DOING = 0x02, + TEST_FINISH = 0x03, + TEST_ABORTED = 0x04, + TEST_START_PRE = 0x05, +} ENUM_TEST_STATUS; + +/*test item error code set*/ +typedef struct TEST_ITEM_ERR_CODE_SET { + u8 item_num; + u16 *p_item_arr; +} ST_TEST_ITEM_ERR_CODE_SET, *PST_TEST_ITEM_ERR_CODE_SET; + +typedef struct ITEM_ERR_CODE { + u16 len; + u16 *ptr_err_code_set; +} ST_ITEM_ERR_CODE, *PST_ST_ITEM_ERR_CODE; + +/*test item result define*/ +typedef struct TEST_ITEM_RES { + /*test ietm id */ + u16 test_id; + + /*test progress*/ + u16 test_progress; + + /*sub test item id set*/ + PST_SUB_TEST_ITEM_ID_SET p_sub_id_set; + + ENUM_TEST_RESULT test_result; + ENUM_TEST_STATUS test_status; + + ST_ITEM_ERR_CODE test_item_err_code; + +} ST_TEST_ITEM_RES, *P_TEST_ITEM_RES; + +/*test process data*/ +typedef struct TEST_PROC_DATA { + u16 test_item_num; + ENUM_TEST_STATUS test_proc_status; + u8 test_break_flag; + + PST_TP_DEV p_dev; /*touc pannel device pointer*/ + + PST_TEST_ITEM *pp_test_item_arr; + + TEST_CALLBACK_PTR p_test_items_before_func_ptr; + ptr32 p_test_items_before_func_ptr_param; + TEST_CALLBACK_PTR p_test_items_finished_func_ptr; + ptr32 p_test_items_finished_func_ptr_param; +} ST_TEST_PROC_DATA, *PST_TEST_PROC_DATA; +typedef const ST_TEST_PROC_DATA CST_TEST_PROC_DATA; +typedef const PST_TEST_PROC_DATA CPST_TEST_PROC_DATA; + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_item_init.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_item_init.c new file mode 100644 index 000000000000..6f3907634031 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_item_init.c @@ -0,0 +1,705 @@ +/******************** (C) COPYRIGHT 2018 Goodix ******************** +* File Name : test_item_init.h +* Author : Zhitao Yang +* Version : V1.0.0 +* Date : 28/03/2018 +* Description : initial test item +*******************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#include "test_item_init.h" + +#include "tp_dev_control.h" +#include "tp_open_test.h" +#include "tp_short_test.h" +#include "tp_version_test.h" +#include "tp_additional_option.h" +#include "tp_test_item_mem.h" +#include "simple_mem_manager.h" +#include "save_test_data.h" + +/******************************************************************************* +* Function Name : free_item_param +* Description : +* Input : PST_TEST_ITEM p_test_item +* Output : none +* Return : void +*******************************************************************************/ +extern void free_item_param(PST_TEST_ITEM p_test_item) +{ + if (p_test_item->p_sub_id_set != NULL) { + p_test_item->p_sub_id_set->p_id_set = NULL; + } + p_test_item->p_sub_id_set = NULL; + p_test_item->p_tp_dev = NULL; + p_test_item->item_addr_start.item_addr_ptr = NULL; + p_test_item->ptr_general_func = NULL; + p_test_item->ptr_general_func_param = NULL; + p_test_item->ptr_test_func = NULL; + p_test_item->ptr_test_item_before_func = NULL; + p_test_item->ptr_test_item_before_func_param = NULL; + p_test_item->ptr_test_item_finished_func = NULL; + p_test_item->ptr_test_item_finished_func_param = NULL; + p_test_item->ptr_share_data = NULL; + p_test_item->ptr_test_proc_data = NULL; + if (p_test_item->ptr_special_callback_data != NULL) { + free_mem_in_heap(p_test_item->ptr_special_callback_data); + p_test_item->ptr_special_callback_data = NULL; + } +} + +/*-------------------------------init open test item---------------------------------------*/ + +/******************************************************************************* +* Function Name : rawdata_test_before_func +* Description : set some hardware and init rawdata test param +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : ptr32 p_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 rawdata_test_before_func(ptr32 p_data, ptr32 p_param) +{ + s32 ret = 0; + PST_TEST_ITEM p_test_item = NULL; + PST_CUR_RAWDATA p_cur_data = NULL; + PST_TEST_PARAM p_test_param = NULL; + + p_test_item = (PST_TEST_ITEM)p_data; + p_test_item->test_res.ptr_res = NULL; + p_test_param = (PST_TEST_PARAM)p_param; + /*init raw param*/ + p_test_item->param.ptr_param = p_test_param->p_raw_test_param; + + /* get rawdata test result buf*/ + ret = alloc_rawdata_test_item_res(p_test_item); + if (ret == 0) { + board_print_error("get raw test result error!\n"); + return 0; + } + p_cur_data = (PST_CUR_RAWDATA)p_test_item->cur_data.ptr_cur_data; + board_print_debug("rawdata buf len :%d!\n", p_cur_data->data_len); + return ret; +} + +/******************************************************************************* +* Function Name : release_rawdata_test_item +* Description : release test param +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 release_rawdata_test_item(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + p_test_item->param.ptr_param = NULL; + /*release rawdata test res*/ + ret = free_rawdata_test_item_res(p_test_item); + free_item_param(p_test_item); + return ret; +} + +/*-------------------------------init short test item---------------------------------------*/ + +/******************************************************************************* +* Function Name : get_gt900_short_param +* Description : gt900 short test res mem malloc +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) + : PST_TEST_PARAM p_test_param +* Output : none +* Return : s32(0:have not handled 1:handled) +*******************************************************************************/ +static s32 get_gt900_short_param(IN_OUT PST_TEST_ITEM p_test_item, + PST_TEST_PARAM p_test_param) +{ + s32 ret = 1; + p_test_item->param.ptr_param = p_test_param->p_short_param; + return ret; +} + +/******************************************************************************* +* Function Name : get_phoenix_test_param +* Description : phoenix short test res mem malloc +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:have not handled 1:handled) +*******************************************************************************/ +static s32 get_phoenix_test_param(IN_OUT PST_TEST_ITEM p_test_item, + PST_TEST_PARAM p_test_param) +{ + s32 ret = 1; + u16 i = 0; + u16 j = 0; + u16 chk_sum = 0; + PST_SHORT_PARAM p_short_param = NULL; + PST_TP_DEV p_tp_dev = NULL; + u16 param_addr = 0x8118; + u16 len = 0x81FE - 0x8118; + u8 *opt_param = NULL; + + p_short_param = p_test_param->p_short_param; + p_tp_dev = p_test_item->p_tp_dev; + p_short_param->short_opt.len = len + 5; + if (alloc_mem_in_heap((void **)&p_short_param->short_opt.opt.opt_ptr, + p_short_param->short_opt.len) == 0) { + board_print_error("short testopt param malloc momory error!\n"); + return 0; + } + memset(p_short_param->short_opt.opt.opt_ptr, 0, len + 3); + opt_param = p_short_param->short_opt.opt.opt_ptr; + /*param len*/ + opt_param[i++] = len + 2; + /*param addr*/ + opt_param[i++] = (param_addr & 0xff); + opt_param[i++] = (param_addr >> 8) & 0xff; + /*sen/drv line*/ + for (j = 0; j < p_tp_dev->max_sen_num_in_die; j++) { + if (j > p_tp_dev->max_sen_num) { + opt_param[i++] = 0xFF; + } else { + opt_param[i++] = p_tp_dev->sen_map[j]; + } + } + for (j = 0; j < p_tp_dev->max_drv_num_in_die; j++) { + if (j > p_tp_dev->max_drv_num) { + opt_param[i++] = 0xFF; + } else { + opt_param[i++] = p_tp_dev->drv_map[j]; + } + } + /* 4 bytes reseverd -> 2 bytes reseved add 2 bytes for driver,so driver max number is 46*/ + opt_param[i++] = 0x00; + opt_param[i++] = 0x00; + + /*Short Check Max num ≤100*/ + opt_param[i++] = 100; + /* + ShortCheck + Mode Sensor Line + Rx的线åºé€‰æ‹©ï¼š0~3å…±4ç§æ¨¡å¼ï¼› + PIN脚å·ï¼šS0~121ï¼› + 0:S0~75ï¼›1:S46~121ï¼›2:S22~97ï¼› + 3:S0~37&S84~121。 + æ ¹æ®äº§å“é…置自动获å–,并上传到此寄存器。 + */ + /*p_test_param->mode_sen_line = (p_test_param->test_cfg[0x80AC-p_tp_dev->cfg_start_addr]>>5) & 0x03;*/ + opt_param[i++] = p_test_param->mode_sen_line; + + /*Tx&Tx short resistor threshold*/ + opt_param[i++] = + ((p_short_param->short_threshold.drv_drv_resistor_threshold) & + 0xFF); + opt_param[i++] = + ((p_short_param->short_threshold.drv_drv_resistor_threshold >> + 8) & + 0xFF); + /*Tx&Rx short resistor threshold*/ + opt_param[i++] = + ((p_short_param->short_threshold.drv_sen_resistor_threshold) & + 0xFF); + opt_param[i++] = + ((p_short_param->short_threshold.drv_sen_resistor_threshold >> + 8) & + 0xFF); + /*Rx&Rx short resistor threshold*/ + opt_param[i++] = + ((p_short_param->short_threshold.sen_sen_resistor_threshold) & + 0xFF); + opt_param[i++] = + ((p_short_param->short_threshold.sen_sen_resistor_threshold >> + 8) & + 0xFF); + /*adc read delay*/ + opt_param[i++] = + ((p_short_param->short_threshold.adc_read_delay) & 0xFF); + opt_param[i++] = + ((p_short_param->short_threshold.adc_read_delay >> 8) & 0xFF); + /*Tx&GND short resistor threshold*/ + opt_param[i++] = ((p_short_param->short_threshold + .drv_gnd_vdd_resistor_threshold) & + 0xFF); + opt_param[i++] = ((p_short_param->short_threshold + .drv_gnd_vdd_resistor_threshold >> + 8) & + 0xFF); + /*Tx&VDD short resistor threshold*/ + opt_param[i++] = ((p_short_param->short_threshold + .drv_gnd_vdd_resistor_threshold) & + 0xFF); + opt_param[i++] = ((p_short_param->short_threshold + .drv_gnd_vdd_resistor_threshold >> + 8) & + 0xFF); + /*Rx&GND short resistor threshold*/ + opt_param[i++] = ((p_short_param->short_threshold + .sen_gnd_vdd_resistor_threshold) & + 0xFF); + opt_param[i++] = ((p_short_param->short_threshold + .sen_gnd_vdd_resistor_threshold >> + 8) & + 0xFF); + /*Rx&VDD short resistor threshold*/ + opt_param[i++] = ((p_short_param->short_threshold + .sen_gnd_vdd_resistor_threshold) & + 0xFF); + opt_param[i++] = ((p_short_param->short_threshold + .sen_gnd_vdd_resistor_threshold >> + 8) & + 0xFF); + /*第一段ADCæ•°æ®åŒºé—´èµ·å§‹æ—¶é—´ï¼Œå•ä½ï¼š0.5us;建议>=200。(暂未使用)*/ + opt_param[i++] = 0x00; + opt_param[i++] = 0x00; + /*第二段ADCæ•°æ®åŒºé—´èµ·å§‹æ—¶é—´ï¼Œå•ä½ï¼š0.5us;建议>=1000。(暂未使用)*/ + opt_param[i++] = 0x00; + opt_param[i++] = 0x00; + /*ADC Samping Time,å•ä½ï¼šHz,建议:<=1700Hz(采样时间约588us),ä¸èƒ½ä½ŽäºŽç¬¬äºŒæ®µADC区间起始时间。(暂未使用)*/ + opt_param[i++] = 0x00; + opt_param[i++] = 0x00; + /*Tx&Tx Rx&Rx Tx&Rx short adc threshold*/ + opt_param[i++] = + ((p_short_param->short_threshold.gt_short_threshold) & 0xFF); + opt_param[i++] = + ((p_short_param->short_threshold.gt_short_threshold >> 8) & + 0xFF); + /*diffcode threshold*/ + opt_param[i++] = + ((p_short_param->short_threshold.diffcode_short_threshold) & + 0xFF); + opt_param[i++] = + ((p_short_param->short_threshold.diffcode_short_threshold >> + 8) & + 0xFF); + /*Tx与Tx短路æ¢ç®—系数,范围40~500*/ + opt_param[i++] = ((p_short_param->short_threshold.tx_tx_factor) & 0xFF); + opt_param[i++] = + ((p_short_param->short_threshold.tx_tx_factor >> 8) & 0xFF); + /*Tx与Rx短路æ¢ç®—系数,范围40~500*/ + opt_param[i++] = ((p_short_param->short_threshold.tx_rx_factor) & 0xFF); + opt_param[i++] = + ((p_short_param->short_threshold.tx_rx_factor >> 8) & 0xFF); + /*Rx与Rx短路æ¢ç®—系数,范围40~500*/ + opt_param[i++] = ((p_short_param->short_threshold.rx_rx_factor) & 0xFF); + opt_param[i++] = + ((p_short_param->short_threshold.rx_rx_factor >> 8) & 0xFF); + /*reserved*/ + opt_param[i++] = 0x00; + opt_param[i++] = 0x00; + + for (j = 3; j < len + 3; j += 2) { + chk_sum += ((u16)(opt_param[j + 1] << 8) + opt_param[j]); + } + chk_sum = 0 - chk_sum; + opt_param[len + 3] = ((chk_sum) & 0xFF); + opt_param[len + 4] = ((chk_sum >> 8) & 0xFF); + opt_param[0] = len + 2; + p_short_param->short_opt.len = len + 5; + board_print_debug("short test opt param len:%d\n", len + 2); + + p_test_item->param.ptr_param = p_short_param; + + return ret; +} + +/******************************************************************************* +* Function Name : get_short_param +* Description : get short param +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 get_short_param(IN_OUT PST_TEST_ITEM p_test_item, + PST_TEST_PARAM p_test_param) +{ + s32 ret = 1; + switch (p_test_item->p_tp_dev->chip_type) { + case TP_NANJING: + case TP_PHOENIX: { + ret = get_phoenix_test_param(p_test_item, p_test_param); + } break; + default: { + ret = get_gt900_short_param(p_test_item, p_test_param); + } break; + } + return ret; +} + +/******************************************************************************* +* Function Name : short_test_before_func +* Description : set some hardware and init short param +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : ptr32 p_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 short_test_before_func(ptr32 p_data, ptr32 p_param) +{ + s32 ret = 0; + PST_TEST_ITEM p_test_item = NULL; + PST_TEST_PARAM p_test_param = NULL; + p_test_item = (PST_TEST_ITEM)p_data; + p_test_item->test_res.ptr_res = NULL; + p_test_param = (PST_TEST_PARAM)p_param; + + /*init short param*/ + ret = get_short_param(p_test_item, p_test_param); + if (ret == 0) { + board_print_error("get short param error!\n"); + return ret; + } + + ret = alloc_short_test_item_res(p_test_item); + if (ret == 0) { + board_print_error("get short res buf error!\n"); + return ret; + } + return ret; +} + +/******************************************************************************* +* Function Name : release_short_test_item +* Description : release memory function +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:have not handled 1:handled) +*******************************************************************************/ +extern s32 release_short_test_item(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + PST_TEST_ITEM p_test_item = NULL; + PST_SHORT_PARAM p_short_param = NULL; + p_test_item = (PST_TEST_ITEM)p_data; + p_short_param = (PST_SHORT_PARAM)p_test_item->param.ptr_param; + + if (p_short_param != NULL) { + p_short_param->short_bin.update_bin_addr.bin_ptr = NULL; + if (p_short_param->short_opt.opt.opt_ptr != NULL) { + free_mem_in_heap(p_short_param->short_opt.opt.opt_ptr); + p_short_param->short_opt.opt.opt_ptr = NULL; + } + p_short_param = NULL; + } + /*release short test result*/ + ret = free_short_test_item_res(p_test_item); + free_item_param(p_test_item); + return ret; +} + +/*-------------------------------init version test item---------------------------------------*/ + +/******************************************************************************* +* Function Name : version_test_before_func +* Description : set some hardware and init version test param +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) + : ptr32 p_param +* Output : ptr32 p_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 version_test_before_func(ptr32 p_data, ptr32 p_param) +{ + s32 ret = 0; + PST_TEST_ITEM p_test_item = NULL; + PST_TEST_PARAM p_test_param = NULL; + + p_test_item = (PST_TEST_ITEM)p_data; + p_test_param = (PST_TEST_PARAM)p_param; + p_test_item->test_res.ptr_res = NULL; + /*init version param*/ + p_test_item->param.ptr_param = p_test_param->p_version_test_param; + /* get version test result buf*/ + ret = alloc_version_test_item_res(p_test_item); + if (ret == 0) { + board_print_error("get version test result error!\n"); + return 0; + } + return ret; +} + +/******************************************************************************* +* Function Name : version_test_finished_func +* Description : release test param +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 version_test_finished_func(ptr32 p_data) +{ + s32 ret = 1; + PST_TEST_ITEM p_test_item = NULL; + p_test_item = (PST_TEST_ITEM)p_data; + p_test_item->param.ptr_param = NULL; + /*release version test res*/ + ret = free_version_test_item_res(p_test_item); + free_item_param(p_test_item); + return ret; +} + +/*-------------------------------init flash test item---------------------------------------*/ + +/******************************************************************************* +* Function Name : flash_test_before_func +* Description : set some hardware and init flash param +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) + : ptr32 p_param +* Output : ptr32 p_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 flash_test_before_func(ptr32 p_data, ptr32 p_param) +{ + s32 ret = 0; + PST_TEST_ITEM p_test_item = NULL; + PST_TEST_PARAM p_test_param = NULL; + PST_FLASH_TEST_PARAM p_flash_param = NULL; + + p_test_item = (PST_TEST_ITEM)p_data; + p_test_param = (PST_TEST_PARAM)p_param; + p_test_item->test_res.ptr_res = NULL; + + /*init falsh param*/ + p_flash_param = p_test_param->p_flash_test_param; + p_flash_param->config_arr = p_test_param->test_cfg; + p_flash_param->cfg_len = p_test_param->cfg_len; + p_test_item->param.ptr_param = p_flash_param; + + /* get flash test result buf*/ + ret = alloc_flash_test_item_res(p_test_item); + if (ret == 0) { + board_print_error("get flash test result error!\n"); + return 0; + } + return ret; +} + +/******************************************************************************* +* Function Name : release_flash_test_item +* Description : release test param +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 release_flash_test_item(ptr32 p_data) +{ + s32 ret = 1; + PST_TEST_ITEM p_test_item = NULL; + PST_FLASH_TEST_PARAM p_flash_param = NULL; + p_test_item = (PST_TEST_ITEM)p_data; + p_flash_param = (PST_FLASH_TEST_PARAM)p_test_item->param.ptr_param; + if (p_test_item->param.ptr_param != NULL) { + p_flash_param->config_arr = NULL; + p_test_item->param.ptr_param = NULL; + } + /*release flash test res*/ + ret = free_flash_test_item_res(p_test_item); + free_item_param(p_test_item); + return ret; +} + +/*-------------------------------init send config test item---------------------------------------*/ + +/******************************************************************************* +* Function Name : send_cfg_test_before_func +* Description : set some hardware and init send config param +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) + : ptr32 p_param +* Output : ptr32 p_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 send_cfg_test_before_func(ptr32 p_data, ptr32 p_param) +{ + s32 ret = 0; + PST_TEST_ITEM p_test_item = NULL; + PST_TEST_PARAM p_test_param = NULL; + p_test_item = (PST_TEST_ITEM)p_data; + p_test_item->test_res.ptr_res = NULL; + + p_test_param = (PST_TEST_PARAM)p_param; + p_test_item->test_res.ptr_res = NULL; + + ret = get_send_cfg_param_mess(p_test_item, p_test_param); + if (ret == 0) { + board_print_error("get send config param error!\n"); + return 0; + } + + /*get send config test result buf*/ + ret = alloc_chip_cfg_proc_item_res(p_test_item); + if (ret == 0) { + board_print_error("get send config test result error!\n"); + return 0; + } + return ret; +} + +/******************************************************************************* +* Function Name : get_send_cfg_param_mess +* Description : get send cfg param +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : u8(0:fail 1:ok) +*******************************************************************************/ +extern s32 get_send_cfg_param_mess(PST_TEST_ITEM p_test_item, + PST_TEST_PARAM p_test_param) +{ + s32 ret = 0; + PST_CHIP_CONFIG_PROC_PARAM p_send_cfg_param = NULL; + + ret = alloc_mem_in_heap((void **)&p_send_cfg_param, + sizeof(ST_CHIP_CONFIG_PROC_PARAM)); + if (ret == 0) { + board_print_error("send config param alloc memory error!\n"); + return 0; + } + + p_send_cfg_param->config = p_test_param->test_cfg; + p_send_cfg_param->cfg_len = p_test_param->cfg_len; + p_send_cfg_param->option = p_test_param->send_cfg_option; + p_test_item->param.ptr_param = p_send_cfg_param; + return ret; +} + +/******************************************************************************* +* Function Name : release_cfg_test_item +* Description : release test param +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 release_cfg_test_item(ptr32 p_data) +{ + s32 ret = 1; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + + /*release send config test param*/ + ret = release_send_cfg_param(p_test_item); + /*release send config test res*/ + ret = free_chip_cfg_proc_item_res(p_test_item); + free_item_param(p_test_item); + return ret; +} + +/******************************************************************************* +* Function Name : release_send_cfg_param +* Description : release send config param +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 release_send_cfg_param(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_CHIP_CONFIG_PROC_PARAM p_send_cfg_param = NULL; + p_send_cfg_param = + (PST_CHIP_CONFIG_PROC_PARAM)p_test_item->param.ptr_param; + if (p_send_cfg_param != NULL) { + p_send_cfg_param->config = NULL; + ret = free_mem_in_heap_p( + (void **)&p_test_item->param.ptr_param); + p_test_item->param.ptr_param = NULL; + } + return ret; +} + +/*-------------------------------init config recover test item---------------------------------------*/ + +/******************************************************************************* +* Function Name : cfg_recover_test_before_func +* Description : set some hardware and init recover config param +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : ptr32 p_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 cfg_recover_test_before_func(ptr32 p_data) +{ + s32 ret = 0; + PST_RECOVER_CHIP_CFG_RES p_res = NULL; + PST_TEST_ITEM p_test_item = NULL; + + p_test_item = (PST_TEST_ITEM)p_data; + p_test_item->test_res.ptr_res = NULL; + + ret = get_recover_cfg_param_mess(p_test_item); + if (ret == 0) { + board_print_error("get recover config param error!\n"); + return 0; + } + /* get cfg recover test result buf*/ + ret = alloc_recover_cfg_item_res(p_test_item); + if (ret == 0) { + board_print_error("get cfg recover test result error!\n"); + return 0; + } + p_res = (PST_RECOVER_CHIP_CFG_RES)p_test_item->test_res.ptr_res; + return ret; +} + +/******************************************************************************* +* Function Name : get_recover_cfg_param_mess +* Description : get recover cfg param +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : u8(0:fail 1:ok) +*******************************************************************************/ +extern s32 get_recover_cfg_param_mess(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_RECOVER_CHIP_CFG_PARAM p_recover_cfg_param = NULL; + PST_TP_DEV p_tp_dev = p_test_item->p_tp_dev; + + ret = alloc_mem_in_heap((void **)&p_recover_cfg_param, + sizeof(ST_RECOVER_CHIP_CFG_PARAM)); + if (ret == 0) { + board_print_error( + "recovery config param alloc memory error!\n"); + return 0; + } + + p_recover_cfg_param->config_arr = p_tp_dev->cfg; + p_recover_cfg_param->cfg_len = p_tp_dev->cfg_len; + p_test_item->param.ptr_param = p_recover_cfg_param; + return ret; +} +/******************************************************************************* +* Function Name : release_cfg_recover_test_item +* Description : release test param +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 release_cfg_recover_test_item(ptr32 p_data) +{ + s32 ret = 1; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + + /*release config recover test param*/ + ret = release_cfg_recover_param(p_test_item); + /*release config recover test res*/ + ret = free_recover_cfg_item_res(p_test_item); + free_item_param(p_test_item); + return ret; +} + +/******************************************************************************* +* Function Name : release_cfg_recover_param +* Description : release config recover param +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 release_cfg_recover_param(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_RECOVER_CHIP_CFG_PARAM p_recover_cfg_param = NULL; + p_recover_cfg_param = + (PST_RECOVER_CHIP_CFG_PARAM)p_test_item->param.ptr_param; + if (p_recover_cfg_param != NULL) { + p_recover_cfg_param->config_arr = NULL; + ret = free_mem_in_heap_p( + (void **)&p_test_item->param.ptr_param); + p_test_item->param.ptr_param = NULL; + } + return ret; +} + +#ifdef __cplusplus +} +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_item_init.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_item_init.h new file mode 100644 index 000000000000..b769021423fe --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_item_init.h @@ -0,0 +1,63 @@ +/******************** (C) COPYRIGHT 2018 Goodix ******************** +* File Name : test_item_init.h +* Author : Zhitao Yang +* Version : V1.0.0 +* Date : 28/03/2018 +* Description : initial test item +*******************************************************************************/ +#ifndef TEST_ITEM_INIT_H +#define TEST_ITEM_INIT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "user_test_type_def.h" +#include "test_item_def.h" +#include "test_order.h" + +/*************************************init open test item********************************************/ +extern s32 rawdata_test_before_func(ptr32 p_data, ptr32 p_param); +extern s32 release_rawdata_test_item(ptr32 p_data); +/*************************************init open test item end*****************************************/ + +/*************************************init short test item********************************************/ +/*init short test param*/ +extern s32 short_test_before_func(ptr32 p_data, ptr32 p_param); +extern s32 get_short_param(IN_OUT PST_TEST_ITEM p_test_item, + PST_TEST_PARAM p_test_param); +extern s32 release_short_test_item(IN_OUT ptr32 p_data); + +/*************************************init short test item end*****************************************/ + +/*************************************init version test item********************************************/ +extern s32 version_test_before_func(ptr32 p_data, ptr32 p_param); +extern s32 version_test_finished_func(ptr32 p_data); +/*************************************init version test item end*****************************************/ + +/*************************************init flash test item********************************************/ +extern s32 flash_test_before_func(ptr32 p_data, ptr32 p_param); +extern s32 release_flash_test_item(ptr32 p_data); + +/*************************************init flash test item end*****************************************/ + +/*************************************init send config test item********************************************/ +extern s32 send_cfg_test_before_func(ptr32 p_data, ptr32 p_param); +/*init send config test param*/ +extern s32 get_send_cfg_param_mess(PST_TEST_ITEM p_test_item, + PST_TEST_PARAM p_test_param); +extern s32 release_cfg_test_item(ptr32 p_data); +extern s32 release_send_cfg_param(PST_TEST_ITEM p_test_item); +/*************************************init send config test item end*****************************************/ + +/*************************************init recover config test item********************************************/ +extern s32 cfg_recover_test_before_func(ptr32 p_data); +/*init cfg recover test param*/ +extern s32 get_recover_cfg_param_mess(PST_TEST_ITEM p_test_item); +extern s32 release_cfg_recover_test_item(ptr32 p_data); +extern s32 release_cfg_recover_param(PST_TEST_ITEM p_test_item); +/*************************************init recover config test item end*****************************************/ +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_order.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_order.c new file mode 100644 index 000000000000..a278a7533719 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_order.c @@ -0,0 +1,2531 @@ +/******************** (C) COPYRIGHT 2018 Goodix ******************** +* File Name : test_order.h +* Author : +* Version : V1.0.0 +* Date : 03/05/2018 +* Description : parse XML order +*******************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#include "chip_ini.h" +#include "test_order.h" +#include "crc_decrypt.h" +#include "simple_mem_manager.h" +#include "tp_dev_control.h" +#include "generic_func.h" + +#include "generic_func.h" +#include "extra_tp_control.h" +#include "tp_dev_control.h" + +#include "config.h" +#include "mxml.h" + +static mxml_node_t *top; + +/******************************************************************************* +* Function Name : get_rawdata_len +* Description : get rawdata len +* Input : PST_TP_DEV p_tp_dev +* Output : PST_TP_DEV p_tp_dev +* Return : none +*******************************************************************************/ +static void get_rawdata_len(PST_TP_DEV p_tp_dev) +{ + p_tp_dev->rawdata_len = + p_tp_dev->total_drv_num * p_tp_dev->total_sen_num; + p_tp_dev->key_rawdata_num = + p_tp_dev->total_drv_num * p_tp_dev->total_sen_num - + p_tp_dev->sc_sen_num * p_tp_dev->sc_drv_num; +} +/******************************************************************************* +* Function Name : get_key_pos_map +* Description : get key position +* Input : PST_TP_DEV p_tp_dev + : u8* key_pos + : u8 key_num_in_port + : u8 drv_flag +* Output : PST_TP_DEV p_tp_dev +* Return : none +*******************************************************************************/ +static void get_key_pos_map(PST_TP_DEV p_tp_dev, u8 *key_pos, + u8 key_num_in_port, u8 drv_flag) +{ + u8 i = 0; + u8 area_key = 0; + u8 tmp_pos = 0; + u8 key_num = 0; + u8 depend_key_rat = 8; + if (p_tp_dev->chip_type == TP_ALTO) { + depend_key_rat = 6; + } + for (i = 0; i < strlen((const char *)key_pos); i++) { + if (key_pos[i] % depend_key_rat != 0) { + area_key = 1; + break; + } + } + if (area_key == 1) { + p_tp_dev->key_num = + p_tp_dev->total_drv_num * p_tp_dev->total_sen_num - + p_tp_dev->sc_sen_num * p_tp_dev->sc_drv_num; + for (i = 0; i < p_tp_dev->key_num; i++) { + p_tp_dev->key_pos_arr[i] = i; + } + } else { + key_num = 0; + for (i = 0; i < strlen((const char *)key_pos); i++) { + if (key_pos[i] != 0) { + if (drv_flag) { + tmp_pos = + key_pos[i] / depend_key_rat + + p_tp_dev->sc_sen_num * + (i / key_num_in_port) - + 1; + } else { + tmp_pos = + key_pos[i] / depend_key_rat + + p_tp_dev->sc_drv_num * + (i / key_num_in_port) - + 1; + } + p_tp_dev->key_pos_arr[key_num] = tmp_pos; + key_num++; + } + } + p_tp_dev->key_num = key_num; + } +} + +/******************************************************************************* +* Function Name : get_sc_drv_sen_key_num +* Description : get sc_drv_num sc_sen_num key_num +* Input : PST_TP_DEV p_tp_dev +* Input : u8 key_start_addr + : u8 key_en + :u8 sen_as_key + :u8 key_com_port_num + :u8 max_key_num +* Output : PST_TP_DEV p_tp_dev +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 get_sc_drv_sen_key_num(PST_TP_DEV p_tp_dev, u8 key_start_addr, + u8 key_en, u8 sen_as_key, u8 key_com_port_num, + u8 max_key_num) +{ + s32 ret = 1; + u8 key_pos[TP_MAX_KEY_NUM]; + u8 max_key_num_in_com_port = 0; + u8 drv_flag = 0; + + p_tp_dev->sc_drv_num = p_tp_dev->total_drv_num; + p_tp_dev->sc_sen_num = p_tp_dev->total_sen_num; + /* screen sensor and driver num */ + if (sen_as_key == 0) { + drv_flag = 1; + + if (key_com_port_num == 1) { + max_key_num_in_com_port = max_key_num / 2; + p_tp_dev->sc_drv_num = + p_tp_dev->total_drv_num - key_en * 2; + } else { + max_key_num_in_com_port = max_key_num; + p_tp_dev->sc_drv_num = p_tp_dev->total_drv_num - key_en; + } + } else { + if (key_com_port_num == 1) { + max_key_num_in_com_port = max_key_num / 2; + p_tp_dev->sc_sen_num = + p_tp_dev->total_sen_num - key_en * 2; + } else { + max_key_num_in_com_port = max_key_num; + p_tp_dev->sc_sen_num = p_tp_dev->total_sen_num - key_en; + } + } + board_print_debug("sc drv num is:%d\n", p_tp_dev->sc_drv_num); + board_print_debug("sc sen num is:%d\n", p_tp_dev->sc_sen_num); + get_rawdata_len(p_tp_dev); + if (p_tp_dev->key_rawdata_num == 0) { + p_tp_dev->key_num = 0; + } else { + /*read key_pos*/ + ret = chip_reg_read(p_tp_dev, key_start_addr, key_pos, + sizeof(key_pos)); + if (ret == 0) { + board_print_error("read key_pos faild!\n"); + return 0; + } + get_key_pos_map(p_tp_dev, key_pos, max_key_num_in_com_port, + drv_flag); + } + board_print_debug("key_num:%d\n", p_tp_dev->key_num); + return ret; +} + +/******************************************************************************* +* Function Name : get_data_step +* Description : get data step +* Input : u8 *data_str +* Output : +* Return : s32(data step) +*******************************************************************************/ +static s32 get_data_step(cu8 *data_str) +{ + s32 step = 0; + if (data_str[0] == 'T') { + step = 4; + } else { + step = 3; + } + return step; +} + +/******************************************************************************* +* Function Name : get_step4_abs_addr +* Description : get_step4_abs_addr +* Input : PST_TP_DEV p_dev +* Output : PST_ADDR_POS_INFO p_addr_info +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +static s32 get_step4_abs_addr(PST_TP_DEV p_dev, PST_ADDR_POS_INFO p_addr_info, + cu8 *config) +{ + s32 ret = 1; + cu8 *sub_bag_ptr = NULL; + u8 i; + + sub_bag_ptr = &config[4]; + for (i = 0; i < config[2]; i++) { + if (sub_bag_ptr[0] == p_addr_info->package_id) + break; + sub_bag_ptr += sub_bag_ptr[1] + 3; + } + + if (i >= config[2]) { + board_print_error("Cann't find the specifiled bag num %d\n", + p_addr_info->package_id); + return 0; + } + + if (sub_bag_ptr[1] + 3 < p_addr_info->offset + 1) { + board_print_debug( + "Sub bag len less then you want to read: %d < %d,pacakge id:%d,offset:%d,lsb:%d,hsb:%d\n", + sub_bag_ptr[1] + 3, p_addr_info->offset + 1, + p_addr_info->package_id, p_addr_info->offset, + p_addr_info->lsb, p_addr_info->hsb); + return 0; + } + + p_addr_info->addr = p_dev->cfg_start_addr + + (sub_bag_ptr + p_addr_info->offset - config); + return ret; +} + +/******************************************************************************* +* Function Name : parse_step3_addr_data +* Description : parse_step3_addr_data +* Input : cu8* string_info +* Input : PST_ADDR_POS_INFO p_addr1_info +* Input : PST_ADDR_POS_INFO p_addr2_info +* Output : PST_ADDR_POS_INFO p_addr1_info +* Output : PST_ADDR_POS_INFO p_addr2_info +* Return : s32(0:fail 1,2:ok,1:p_addr1_info 2:p_addr1_info,p_addr2_info) +*******************************************************************************/ +static s32 parse_step3_addr_data(PST_TP_DEV p_dev, cu8 *string_info, + PST_ADDR_POS_INFO p_addr1_info, + PST_ADDR_POS_INFO p_addr2_info) +{ + s32 ret = 0; + u8 str_tmp[128]; + u8 string_info_len = strlen((const s8 *)string_info); + u8 *field = NULL; + if (NULL == string_info || string_info_len == 0) { + board_print_error("parse str is null!\n"); + return ret; + } + if (string_info_len > sizeof(str_tmp)) { + board_print_error("ini addr str is error:%s!\n", string_info); + return ret; + } + memcpy(str_tmp, string_info, string_info_len); + str_tmp[string_info_len] = '0'; + + if ((strlen((const char *)str_tmp) == 0)) { + return ret; + } + + field = (u8 *)strsep((char **)&str_tmp, ","); + if (field == NULL) { + board_print_error("get addr1 null!\n"); + return ret; + } + p_addr1_info->addr = atohex(field, strlen((const char *)field)); + + field = (u8 *)strsep((char **)&str_tmp, ","); + if (field == NULL) { + return ret; + } + p_addr1_info->lsb = atoi((char const *)field); + + field = (u8 *)strsep((char **)&str_tmp, ","); + if (field == NULL) { + return ret; + } + p_addr1_info->hsb = atoi((char const *)field); + ret++; + + if (p_addr2_info != NULL) { + field = (u8 *)strsep((char **)&str_tmp, ","); + if (field == NULL) { + board_print_debug("get addr2 null, parse str:%s!\n", + string_info); + return ret; + } + p_addr2_info->addr = atohex(field, strlen((const char *)field)); + + field = (u8 *)strsep((char **)&str_tmp, ","); + if (field == NULL) { + return ret; + } + p_addr2_info->lsb = atoi((char const *)field); + + field = (u8 *)strsep((char **)&str_tmp, ","); + if (field == NULL) { + return ret; + } + p_addr2_info->hsb = atoi((char const *)field); + ret++; + } + return ret; +} + +/******************************************************************************* +* Function Name : parse_step4_addr_data +* Description : get data with package id and offset +* Input : cu8* string_info +* Output : PST_ADDR_POS_INFO p_addr1_info +* Output : PST_ADDR_POS_INFO p_addr2_info +* Return : s32(0:fail 1,2:ok,1:p_addr1_info 2:p_addr1_info,p_addr2_info) +*******************************************************************************/ +static s32 parse_step4_addr_data(PST_TP_DEV p_dev, cu8 *string_info, + PST_ADDR_POS_INFO p_addr1_info, + PST_ADDR_POS_INFO p_addr2_info) +{ + s32 ret = 0; + s32 free_mem = 0; + u8 *field = NULL; + u8 *str_tmp = NULL; + u8 string_info_len = 0; + + string_info_len = strlen((const s8 *)string_info); + if (string_info_len == 0) { + board_print_error("string_info len is invalid!\n"); + return ret; + } + /*board_print_debug("string_info len is: %d!\n",string_info_len);*/ + ret = alloc_mem_in_heap((void **)&str_tmp, string_info_len + 1); + if (0 == ret) { + board_print_error("string_info malloc error!\n"); + free_mem_in_heap((void *)str_tmp); + return ret; + } + memcpy(str_tmp, string_info, string_info_len); + str_tmp[string_info_len] = '\0'; + + /*sub package id*/ + field = (u8 *)strsep((char **)&str_tmp, ","); + if (field == NULL) { + board_print_error("get addr1 null!\n"); + goto mallc_exit; + } + p_addr1_info->package_id = atoi((const char *)&field[1]); + + /*offset*/ + field = (u8 *)strsep((char **)&str_tmp, ","); + if (field == NULL) { + goto mallc_exit; + } + p_addr1_info->offset = atoi((char const *)field); + + /*low bit*/ + field = (u8 *)strsep((char **)&str_tmp, ","); + if (field == NULL) { + goto mallc_exit; + } + p_addr1_info->lsb = atoi((char const *)field); + + /*high bit*/ + field = (u8 *)strsep((char **)&str_tmp, ","); + if (field == NULL) { + goto mallc_exit; + } + p_addr1_info->hsb = atoi((char const *)field); + ret++; + + field = (u8 *)strsep((char **)&str_tmp, ","); + if ((p_addr2_info != NULL) && (field != NULL)) { + if (field == NULL) { + board_print_debug("get addr2 null!,parse str:%s\n", + string_info); + goto mallc_exit; + } + p_addr2_info->package_id = atoi((const char *)&field[1]); + + field = (u8 *)strsep((char **)&str_tmp, ","); + if (field == NULL) { + goto mallc_exit; + } + p_addr2_info->offset = atoi((char const *)field); + + field = (u8 *)strsep((char **)&str_tmp, ","); + if (field == NULL) { + goto mallc_exit; + } + p_addr2_info->lsb = atoi((char const *)field); + + field = (u8 *)strsep((char **)&str_tmp, ","); + if (field == NULL) { + goto mallc_exit; + } + p_addr2_info->hsb = atoi((char const *)field); + ret++; + } + +mallc_exit: + free_mem = free_mem_in_heap((void *)str_tmp); + board_print_debug("free_mem_in_heap return %d \n", free_mem); + str_tmp = NULL; + return ret; +} + +/******************************************************************************* +* Function Name : parse_addr_data +* Description : parse_addr_data +* Input : u8* string_info +* Input : PST_ADDR_POS_INFO p_addr1_info +* Input : PST_ADDR_POS_INFO p_addr2_info +* Input : u8 data_step +* Output : PST_ADDR_POS_INFO p_addr1_info +* Output : PST_ADDR_POS_INFO p_addr2_info +* Return : s32(0:fail 1,2:ok,1:p_addr1_info 2:p_addr1_info,p_addr2_info) +*******************************************************************************/ +static s32 parse_addr_data(PST_TP_DEV p_dev, u8 *string_info, + PST_ADDR_POS_INFO p_addr1_info, + PST_ADDR_POS_INFO p_addr2_info, u8 data_step) +{ + getrid_space((s8 *)string_info, strlen((const char *)string_info)); + if (data_step == 3) { + return parse_step3_addr_data(p_dev, string_info, p_addr1_info, + p_addr2_info); + } + if (data_step == 4) { + return parse_step4_addr_data(p_dev, string_info, p_addr1_info, + p_addr2_info); + } + return 0; +} + +/******************************************************************************* +* Function Name : get_step3_cfg_data +* Description : get_step3_cfg_data +* Input : PST_TP_DEV p_tp_dev +* Input : PST_ADDR_POS_INFO p_addr_info +* Input : cu8* config +* Output : none +* Return : u8(data in cfg) +*******************************************************************************/ +static u8 get_step3_cfg_data(PST_TP_DEV p_tp_dev, PST_ADDR_POS_INFO p_addr_info, + cu8 *config) +{ + u8 value = 0; + u8 tmp = 0; + tmp = (1 << (p_addr_info->hsb - p_addr_info->lsb + 1)) - 1; + tmp &= 0xff; + value = (config[p_addr_info->addr - p_tp_dev->cfg_start_addr] >> + p_addr_info->lsb) & + tmp; + return value; +} + +/******************************************************************************* +* Function Name : get_step4_cfg_data +* Description : get_step4_cfg_data +* Input : PST_TP_DEV p_tp_dev +* Input : PST_ADDR_POS_INFO p_addr_info +* Input : cu8* config +* Output : none +* Return : u8(data in cfg) +*******************************************************************************/ +static u8 get_step4_cfg_data(PST_TP_DEV p_tp_dev, PST_ADDR_POS_INFO p_addr_info, + cu8 *config) +{ + s32 ret = 0; + u8 value = 0; + u32 tmp = 0; + + ret = get_step4_abs_addr(p_tp_dev, p_addr_info, config); + if (ret == 0) { + return 0; + } + + tmp = (1 << (p_addr_info->hsb - p_addr_info->lsb + 1)) - 1; + tmp &= 0xff; + value = ((config[p_addr_info->addr - p_tp_dev->cfg_start_addr] >> + p_addr_info->lsb) & + tmp); + return value; +} + +/******************************************************************************* +* Function Name : get_reg_data +* Description : get reg data +* Input : PST_TP_DEV p_tp_dev +* Input : PST_ADDR_POS_INFO p_addr_info +* Input : cu8* config +* Input : u8 data_step +* Output : none +* Return : u8(data in reg) +*******************************************************************************/ +static u8 get_cfg_data(PST_TP_DEV p_tp_dev, PST_ADDR_POS_INFO p_addr_info, + cu8 *config, u8 data_step) +{ + if (data_step == 3) { + return get_step3_cfg_data(p_tp_dev, p_addr_info, config); + } + if (data_step == 4) { + return get_step4_cfg_data(p_tp_dev, p_addr_info, config); + } + return 0; +} + +/******************************************************************************* +* Function Name : parse_cfg_value +* Description : parse_cfg_value +* Input : PST_TP_DEV p_dev +* Input : u8* string_info +* Input : u8* p_config +* Output : PST_TP_DEV p_tp_dev +* Return : u32 (data in cfg parsed) +*******************************************************************************/ +extern u32 parse_cfg_value(PST_TP_DEV p_dev, u8 *string_info, u8 *p_config) +{ + u32 ret = 0; + s32 step = 0; + u8 value1 = 0; + u8 value2 = 0; + s32 val_num = 0; + ST_ADDR_POS_INFO addr_info1, addr_info2; + step = get_data_step(string_info); + val_num = parse_addr_data(p_dev, string_info, &addr_info1, &addr_info2, + step); + if (val_num == 0) { + return 0; + } + value1 = get_cfg_data(p_dev, &addr_info1, p_config, step); + if (val_num >= 2) { + value2 = get_cfg_data(p_dev, &addr_info2, p_config, step); + } + ret = value1 + value2; + return ret; +} + +/******************************************************************************* +* Function Name : parse_addr_from_str +* Description : parse_addr_from_str +* Input : PST_TP_DEV p_dev +* Input : u8* string_info +* Input : cu8* config +* Output : none +* Return : u32 (address) +*******************************************************************************/ +extern u32 parse_addr_from_str(PST_TP_DEV p_dev, u8 *string_info, cu8 *config) +{ + s32 ret = 0; + s32 step = 0; + s32 val_num = 0; + ST_ADDR_POS_INFO addr_info1, addr_info2; + step = get_data_step(string_info); + val_num = parse_addr_data(p_dev, string_info, &addr_info1, &addr_info2, + step); + if (val_num == 0) { + return 0; + } + if (step == 4) { + ret = get_step4_abs_addr(p_dev, &addr_info1, config); + if (ret == 0) { + return 0; + } + } + return addr_info1.addr; +} + +/******************************************************************************* +* Function Name : disable_hopping +* Description : disable hopping +* Input : PST_TP_DEV p_tp_dev +* Input : u8*str_info + : u8*cfg +* Output : PST_TP_DEV p_tp_dev +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 disable_hopping(PST_TP_DEV p_tp_dev, u8 *str_info, u8 *cfg, + u16 cfg_len) +{ + s32 ret = 1; + u8 num = 0; + s32 step = 0; + u32 hopping_en = 0; + u8 tmp = 1; + ST_ADDR_POS_INFO addr_info1; + + step = get_data_step(str_info); + num = parse_addr_data(p_tp_dev, str_info, &addr_info1, NULL, step); + if (num == 0) { + return 0; + } + hopping_en = get_cfg_data(p_tp_dev, &addr_info1, cfg, step); + if (hopping_en == 1) { + tmp = (1 << (addr_info1.hsb - addr_info1.lsb + 1)) - 1; + tmp = tmp << addr_info1.lsb; + tmp = (~tmp) & 0xff; + if (step == 4) { + get_step4_abs_addr(p_tp_dev, &addr_info1, cfg); + } + + cfg[addr_info1.addr - p_tp_dev->cfg_start_addr] &= tmp; + } + update_cfg_checksum(p_tp_dev, cfg, cfg_len); + return ret; +} + +/******************************************************************************* +* Function Name : init_dev_const_param +* Description : init dev const param +* Input : PST_TP_DEV p_tp_dev +* Output : PST_TP_DEV p_tp_dev +* Return : void +*******************************************************************************/ +extern void init_dev_const_param(PST_TP_DEV p_tp_dev) +{ + p_tp_dev->chip_type = TP_NORMANDY; /* chip type*/ + p_tp_dev->chip_sub_type = TP_GT9886; /* chip sub type*/ + + /*voltage setting*/ + p_tp_dev->doze_ref_cnt = 1; /*1:doze mode 0:exit doze*/ + + /*cfg*/ + p_tp_dev->cfg_start_addr = 0x6F78; + p_tp_dev->ext_cfg_addr = 0; + p_tp_dev->ext_cfg_len = 0; + p_tp_dev->cfg_len = + 690; /*if ext_cfg_len != 0 then cfg_len = base_cfg_len + ext_cfg_len*/ + + p_tp_dev->use_soft_reset = 0; /* 1 use soft reset first */ + p_tp_dev->no_rst_pin = 0; /* 1 no rst pin 0 has rst pin default 0*/ + + /* max sensor and driver num for die*/ + p_tp_dev->max_sen_num_in_die = 36; + p_tp_dev->max_drv_num_in_die = 40; + + /* max sensor and driver num for this chip*/ + p_tp_dev->max_sen_num = 36; + p_tp_dev->max_drv_num = 40; + /*p_tp_dev->max_key_num = 4;*/ + + /*drv channel map*/ + p_tp_dev->map_disable = 0; + memcpy(p_tp_dev->drv_map, DRV_MAP, sizeof(DRV_MAP)); + memcpy(p_tp_dev->sen_map, SEN_MAP, sizeof(SEN_MAP)); + + /*real_cmd_addr*/ + p_tp_dev->real_cmd_addr = + 0x6F68; /*this field may be same as fields in cmd_set*/ + + /*rawdata_cmd*/ + p_tp_dev->cmd_set.coorddata_cmd.addr = 0x6F68; + p_tp_dev->cmd_set.coorddata_cmd.cmd_buf[0] = 0x00; + p_tp_dev->cmd_set.coorddata_cmd.cmd_buf[1] = 0x00; + p_tp_dev->cmd_set.coorddata_cmd.cmd_buf[2] = 0x00; + p_tp_dev->cmd_set.coorddata_cmd.cmd_len = 3; + + p_tp_dev->cmd_set.rawdata_cmd.addr = 0x6F68; + p_tp_dev->cmd_set.rawdata_cmd.cmd_buf[0] = 0x01; + p_tp_dev->cmd_set.rawdata_cmd.cmd_buf[1] = 0x00; + p_tp_dev->cmd_set.rawdata_cmd.cmd_buf[2] = 0xff; + p_tp_dev->cmd_set.rawdata_cmd.cmd_len = 3; + + p_tp_dev->rawdata_addr = 0x8FA0; + p_tp_dev->rawdata_len = 0; + p_tp_dev->rawdata_option = _DATA_BIT_16 | _DATA_LARGE_ENDIAN | + _DATA_SIGNED | _DATA_DRV_SEN_INVERT; + + p_tp_dev->syncflag_addr = 0x4100; + p_tp_dev->syncflag_mask = 0x80; +} + +/******************************************************************************* +* Function Name : parse_key_data +* Description : parse key infor +* Input : PST_TP_DEV p_tp_dev +* Input : dictionary* p_dict_ini +* Output : PST_TP_DEV p_tp_dev +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_key_data(PST_TP_DEV p_tp_dev, u8 *cfg) +{ + s32 ret = 1; + u16 key_start_addr; + u8 sen_as_key = 0; /*0:use sen chn as key, 1: use drv chn as key*/ + u8 key_com_port_num = 0; + u8 key_en = 0; + u8 max_key_num = 4; + + key_start_addr = parse_addr_from_str(p_tp_dev, KEY_START_ADDR, cfg); + sen_as_key = parse_cfg_value(p_tp_dev, SEN_AS_KEY_ADDR, cfg); + key_en = parse_cfg_value(p_tp_dev, KEY_EN, cfg); + + ret = get_sc_drv_sen_key_num(p_tp_dev, key_start_addr, key_en, + sen_as_key, key_com_port_num, max_key_num); + return ret; +} + +/******************************************************************************* +* Function Name : parse_cfg +* Description : prse config +* Input : PST_TP_DEV p_tp_dev + : u8*cfg + : u16 cfg_len +* Output : PST_TP_DEV p_tp_dev +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_cfg(PST_TP_DEV p_tp_dev, u8 *cfg) +{ + s32 ret = 0; + p_tp_dev->total_sen_num = parse_cfg_value(p_tp_dev, SEN_NUM_ADDR, cfg); + p_tp_dev->sc_sen_num = p_tp_dev->total_sen_num; + board_print_debug("total sen num:%d\n", p_tp_dev->total_sen_num); + p_tp_dev->total_drv_num = parse_cfg_value(p_tp_dev, DRV_NUM_ADDR, cfg); + p_tp_dev->sc_drv_num = p_tp_dev->total_drv_num; + board_print_debug("total drv num:%d\n", p_tp_dev->total_drv_num); + + p_tp_dev->sen_start_addr = + parse_addr_from_str(p_tp_dev, SEN_START_ADDR, cfg); + p_tp_dev->drv_start_addr = + parse_addr_from_str(p_tp_dev, DRV_START_ADDR, cfg); + ret = parse_key_data(p_tp_dev, cfg); + return ret; +} + +/******************************************************************************* +* Function Name : init_test_config +* Description : init test config +* Input : PST_TP_DEV p_tp_dev + : u8*cfg + :u16 p_cfg_len +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +static s32 init_test_config(PST_TP_DEV p_tp_dev, u8 *test_cfg, u16 *p_cfg_len) +{ + s32 ret = 1; + if (*p_cfg_len == 0) { + BOARD_PRINT("switch to original config!\n"); + memcpy(test_cfg, p_tp_dev->cfg, p_tp_dev->cfg_len); + *p_cfg_len = p_tp_dev->cfg_len; + } else { + BOARD_PRINT("switch to test config in order!\n"); + test_cfg[0] = p_tp_dev->cfg[0]; + if (p_tp_dev->chip_type == TP_NORMANDY) { + test_cfg[1] |= 0x01; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : header_file_init_dev +* Description : init dev info with chip_ini.h +* Input : PST_TP_DEV p_tp_dev +* Output : PST_TP_DEV p_tp_dev +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 header_file_init_dev(PST_TP_DEV p_tp_dev, u8 *cfg, u16 *p_cfg_len) +{ + s32 ret = 1; + /*init const param*/ + init_dev_const_param(p_tp_dev); + + /*read cfg*/ + ret = read_chip_original_cfg(p_tp_dev); + if (ret == 0) { + board_print_error("read chip config faild!\n"); + return 0; + } + /*init test config*/ + ret = init_test_config(p_tp_dev, cfg, p_cfg_len); + if (ret == 0) { + board_print_error("init test config faild!\n"); + return 0; + } + /*parse config*/ + ret = parse_cfg(p_tp_dev, cfg); + if (ret == 0) { + board_print_error("parse config faild!\n"); + return 0; + } + /*disable hopping*/ + ret = disable_hopping(p_tp_dev, HOPPING_EN, cfg, *p_cfg_len); + return ret; +} + +/******************************************************************************* +* Function Name : parse_init_dev_info +* Description : parse device info from order +* Input : PST_TP_DEV p_tp_dev + : PST_TEST_PARAM p_test_parm +* Output : PST_TP_DEV p_tp_dev +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_init_dev_info(PST_TP_DEV p_tp_dev, PST_TEST_PARAM p_test_param) +{ + s32 ret = 1; + mxml_node_t *obj_set = NULL; + mxml_node_t *chip_ini = NULL; + mxml_node_t *parent_xnode = NULL; + u16 chip_type = 0; + u16 chip_sub_type = 0; + + /* get chip ini content from xml order*/ + obj_set = mxmlFindElement(top, top, "OBJ_SETTING", NULL, NULL, + MXML_DESCEND); + + if ((obj_set == NULL) || (obj_set->child == NULL)) { + board_print_error("can not find OBJ_SETTING in order!\n"); + return 0; + } + + parent_xnode = mxmlFindElement(obj_set, obj_set, "powerVolt", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + p_tp_dev->power_volt = 2800; + } else { + p_tp_dev->power_volt = + str_to_int(parent_xnode->child->value.opaque); + } + board_print_debug("power volt:%d!\n", p_tp_dev->power_volt); + /*find chip type*/ + parent_xnode = mxmlFindElement(obj_set, obj_set, "tpMainType", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error("can not find tpMainType in order!\n"); + return 0; + } + chip_type = str_to_int(parent_xnode->child->value.opaque); + if (chip_type != p_tp_dev->chip_type) { + board_print_error("chip type set in order is error!\n"); + return 0; + } + + parent_xnode = mxmlFindElement(parent_xnode, obj_set, "tpSubType", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error("can not find tpSubType in order!\n"); + return 0; + } + chip_sub_type = str_to_int(parent_xnode->child->value.opaque); + chip_ini = + mxmlFindElement(top, top, "chipIni", NULL, NULL, MXML_DESCEND); + if ((chip_ini == NULL) || (chip_ini->child == NULL)) { + board_print_error( + "order error,test station should be set as ANDR-MAC!\n"); + return 0; + } + + memset(p_tp_dev->drv_map, 255, TP_MAX_CHN_NUM); + memset(p_tp_dev->sen_map, 255, TP_MAX_CHN_NUM); + memset(p_tp_dev->pack_drv_2_adc_map, 255, TP_MAX_CHN_NUM); + memset(p_tp_dev->pack_sen_2_adc_map, 255, TP_MAX_CHN_NUM); + + /*init tp device with header file*/ + ret = header_file_init_dev(p_tp_dev, p_test_param->test_cfg, + &p_test_param->cfg_len); + return ret; +} + +/******************************************************************************* +* Function Name : parse_order_config +* Description : parse order config +* Input : PST_TEST_PARAM p_test_param +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_order_config(PST_TEST_PARAM p_test_param) +{ + s32 ret = 1; + mxml_node_t *parent_xnode = NULL; + mxml_node_t *child_xnode = NULL; + p_test_param->cfg_len = 0; + + board_print_debug("parse order config!\n"); + ret = alloc_mem_in_heap((void **)&p_test_param->test_cfg, + TP_MAX_CFG_LEN); + if (ret == 0) { + board_print_error("test config malloc memory error!\n"); + return 0; + } + p_test_param->test_cfg[0] = '\0'; + + /*find config from top node*/ + parent_xnode = mxmlFindElement(top, top, "chipConfigProc", NULL, NULL, + MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error( + "can not find chipConfigProc param in order!\n"); + return 0; + } + /*init test config */ + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, "config", + NULL, NULL, MXML_DESCEND); + if ((child_xnode != NULL) && (child_xnode->child != NULL)) { + ret = hexstr_to_array(p_test_param->test_cfg, + child_xnode->child->value.opaque, + TP_MAX_CFG_LEN); + if (ret > 0) { + board_print_debug("test cfg len=%d\n", ret); + p_test_param->cfg_len = ret; + } + } + + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, "option", + NULL, NULL, MXML_DESCEND); + if ((child_xnode != NULL) && (child_xnode->child != NULL)) { + p_test_param->send_cfg_option = + str_to_int(child_xnode->child->value.opaque); + } + return ret; +} + +/******************************************************************************* +* Function Name : is_mach_test_item +* Description : test item +* Input : u16 test_id +* Output : +* Return : s32(0:no 1:yes) +*******************************************************************************/ +static s32 is_mach_test_item(u16 test_id) +{ + if (test_id == TP_RAWDATA_TEST_ITEMS_SET_ID) { + return 1; + } else if (test_id == TP_SHORT_TEST_ITEM_ID) { + return 1; + } else if (test_id == TP_VERSION_TEST_ITEM_ID) { + return 1; + } else if (test_id == TP_FLASH_TEST_ITEM_ID) { + return 1; + } else if (test_id == TP_CHIP_CFG_PROC_ITEM_ID) { + return 1; + } else if (test_id == TP_RECOVER_CFG_ITEM_ID) { + return 1; + } else { + return 0; + } +} + +/******************************************************************************* +* Function Name : parse_test_item_id +* Description : parse test item id +* Input : PST_TEST_PARAM p_test_param +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_test_item_id(PST_TEST_PARAM p_test_param) +{ + s32 ret = 0; + u16 i = 0; + u16 itest_id = 0xffff; + u16 test_num = 0; + u16 sub_id_num = 0; + mxml_node_t *test_item = NULL; + mxml_node_t *test_id = NULL; + mxml_node_t *is_select = NULL; + mxml_node_t *sub_item = NULL; + mxml_node_t *parent_xnode = NULL; + PST_TEST_ITEM_ID_SET p_test_id_set = NULL; + p_test_param->test_item_num = 0; + /*定义空节点*/ + + /*find testItemSet from top node */ + parent_xnode = mxmlFindElement(top, top, "testItemSet", NULL, NULL, + MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_debug("no testItenSet in order file!\n"); + return 0; + } + /*malloc memory for test id*/ + ret = alloc_mem_in_heap((void **)&p_test_param->p_test_item_id_set, + MAX_TEST_NUM * sizeof(ST_TEST_ITEM_ID_SET)); + if (ret == 0) { + board_print_error("test item id set malloc memory error!\n"); + return 0; + } + p_test_id_set = p_test_param->p_test_item_id_set; + for (i = 0; i < MAX_TEST_NUM; i++) { + p_test_id_set[i].p_sub_id_set = NULL; + } + + /*find test item*/ + test_item = mxmlFindElement(parent_xnode, parent_xnode, "testItem", + NULL, NULL, MXML_DESCEND); + while ((test_item != NULL) && (test_item->child != NULL)) { + /*test item is select or not*/ + is_select = mxmlFindElement(test_item, test_item, "bSelected", + NULL, NULL, MXML_DESCEND); + if ((is_select != NULL) && (is_select->child != NULL) && + (str_to_int(is_select->child->value.opaque) == 1)) { + /*find test id*/ + test_id = mxmlFindElement(test_item, test_item, + "itemId", NULL, NULL, + MXML_DESCEND); + if ((test_id != NULL) && (test_id->child != NULL)) { + itest_id = str_to_int( + test_id->child->value.opaque); + if (is_mach_test_item(itest_id) != 1) { + test_item = mxmlFindElement( + test_item, parent_xnode, + "testItem", NULL, NULL, + MXML_NO_DESCEND); + continue; + } + board_print_debug("test id :%d\n", itest_id); + p_test_id_set[test_num].test_id = str_to_int( + test_id->child->value.opaque); + /*find sub test id*/ + sub_item = mxmlFindElement(test_item, test_item, + "subTestItem", NULL, + NULL, MXML_DESCEND); + if ((sub_item != NULL) && + (sub_item->child != NULL)) { + sub_id_num = 0; + ret = alloc_mem_in_heap( + (void **)&p_test_id_set[test_num] + .p_sub_id_set, + sizeof(ST_TEST_ITEM_ID_SET)); + if (ret == 0) { + board_print_error( + "test item id malloc memory error!i=%d\n", + i); + return 0; + } + p_test_id_set[test_num] + .p_sub_id_set->len = 0; + ret = alloc_mem_in_heap( + (void **)&p_test_id_set[test_num] + .p_sub_id_set->p_id_set, + MAX_SUBTEST_NUM); + if (ret == 0) { + board_print_error( + "sub id malloc memory error!test_id=%d\n", + p_test_id_set[test_num] + .test_id); + return 0; + } + } + while ((sub_item != NULL) && + (sub_item->child != NULL)) { + is_select = mxmlFindElement( + sub_item, sub_item, "bSelected", + NULL, NULL, MXML_DESCEND); + board_print_debug( + "sub id is select:%d\n", + str_to_int( + is_select->child->value + .opaque)); + if ((is_select != NULL) && + (is_select->child != NULL) && + (str_to_int(is_select->child->value + .opaque) == + 1)) { + /*find sub item id */ + test_id = mxmlFindElement( + sub_item, sub_item, + "itemId", NULL, NULL, + MXML_DESCEND); + if ((test_id != NULL) && + (test_id->child != NULL)) { + p_test_id_set[test_num] + .p_sub_id_set + ->p_id_set + [sub_id_num] = str_to_int( + test_id->child + ->value + .opaque); + sub_id_num++; + } + } + /*find next sub test item*/ + sub_item = mxmlFindElement( + sub_item, test_item, + "subTestItem", NULL, NULL, + MXML_DESCEND); + } + if (p_test_id_set[test_num].p_sub_id_set != + NULL) { + p_test_id_set[test_num] + .p_sub_id_set->len = sub_id_num; + board_print_debug("sub test num:%d\n", + sub_id_num); + } + test_num++; + } + } + /*find next test item*/ + test_item = mxmlFindElement(test_item, parent_xnode, "testItem", + NULL, NULL, MXML_NO_DESCEND); + } + p_test_param->test_item_num = test_num; + board_print_debug("test num:%d\n", test_num); + return ret; +} + +/******************************************************************************* +* Function Name : parse_need_check_node +* Description : parse need check node +* Input : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Output : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Return : u16(node num) +*******************************************************************************/ +extern u16 parse_need_check_node(PST_RAWDATA_TEST_PARAM p_raw_test_param) +{ + s32 ret = 0; + char *tmp_value = NULL; + u16 data_len = 0; + mxml_node_t *parent_xnode = NULL; + + parent_xnode = mxmlFindElement(top, top, "needCheckNodeParam", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error("please set need check node!\n"); + return 0; + } + + if (parent_xnode->child == NULL) { + board_print_error("no need check node!\n"); + return 0; + } + tmp_value = parent_xnode->child->value.opaque; + data_len = (strlen(tmp_value) + 1) / 5 + 1; + + ret = alloc_mem_in_heap((void **)&p_raw_test_param->p_need_check_node, + sizeof(ST_NEED_CHECK_NODE)); + if (ret == 0) { + board_print_error("need check node malloc memory error!\n"); + return 0; + } + ret = alloc_mem_in_heap( + (void **)&p_raw_test_param->p_need_check_node->p_data_buf, + data_len); + if (ret == 0) { + board_print_error("need check node malloc memory error!\n"); + return 0; + } + /*init need check node*/ + p_raw_test_param->p_need_check_node->data_len = 0; + memset(p_raw_test_param->p_need_check_node->p_data_buf, 0, data_len); + p_raw_test_param->p_need_check_node->data_len = + hexstr_to_array(p_raw_test_param->p_need_check_node->p_data_buf, + tmp_value, data_len); + return data_len; +} + +/******************************************************************************* +* Function Name : parse_need_check_key +* Description : parse need check key +* Input : PST_RAWDATA_TEST_PARAM p_raw_test_param + : u16 data_len +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_need_check_key(PST_RAWDATA_TEST_PARAM p_raw_test_param, + u16 data_len) +{ + s32 ret = 0; + char *tmp_value = NULL; + mxml_node_t *parent_xnode = NULL; + mxml_node_t *child_xnode = NULL; + PST_NEED_CHECK_KEY p_need_check_key = NULL; + /*judge if need check key*/ + if (p_raw_test_param->p_raw_key_limit == NULL) { + return 1; + } + + ret = alloc_mem_in_heap( + (void **)&p_raw_test_param->p_raw_key_limit->p_need_check_key, + sizeof(ST_NEED_CHECK_KEY)); + if (ret == 0) { + board_print_error("need check key malloc memory error!\n"); + return 0; + } + p_need_check_key = p_raw_test_param->p_raw_key_limit->p_need_check_key; + /*init need check key*/ + ret = alloc_mem_in_heap((void **)&p_need_check_key->p_data_buf, + data_len); + if (ret == 0) { + board_print_error("need check key buf malloc memory error!\n"); + return 0; + } + p_need_check_key->len = 0; + memset(p_need_check_key->p_data_buf, 0, data_len); + + child_xnode = mxmlFindElement(parent_xnode, top, "needCheckKey", NULL, + NULL, MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + board_print_debug( + "no need check key, please set need check key!\n"); + return 1; + } + tmp_value = child_xnode->child->value.opaque; + p_need_check_key->len = hexstr_to_array(p_need_check_key->p_data_buf, + tmp_value, data_len); + return ret; +} + +/******************************************************************************* +* Function Name : parse_special_node +* Description : parse special node +* Input : PST_RAWDATA_TEST_PARAM p_raw_test_param + : u16 data_len +* Output : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_special_node(PST_RAWDATA_TEST_PARAM p_raw_test_param, + u16 data_len) +{ + s32 ret = 0; + u16 i = 0; + + mxml_node_t *parent_xnode = NULL; + mxml_node_t *child_xnode = NULL; + mxml_node_t *special_xnode = NULL; + + ret = alloc_mem_in_heap((void **)&p_raw_test_param->p_special_node, + sizeof(ST_RAWDATA_SPECIAL_NODE_PARAM)); + if (ret == 0) { + board_print_error("need check node malloc memory error!\n"); + return 0; + } + + ret = alloc_mem_in_heap( + (void **)&p_raw_test_param->p_special_node->p_data_buf, + data_len * sizeof(ST_SPECIAL_NODE_DEF)); + if (ret == 0) { + board_print_error("need check node malloc memory error!\n"); + return 0; + } + /*init sepcial node*/ + p_raw_test_param->p_special_node->data_len = 0; + special_xnode = mxmlFindElement(top, top, "rawdataSpecialNodeParam", + NULL, NULL, MXML_DESCEND); + if ((special_xnode == NULL) || (special_xnode->child == NULL)) { + return 1; + } + + i = 0; + parent_xnode = mxmlFindElement(special_xnode, special_xnode, "node", + NULL, NULL, MXML_DESCEND); + while ((special_xnode != NULL) && (special_xnode->child != NULL)) { + /*node id */ + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, + "nodeId", NULL, NULL, + MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + break; + } + p_raw_test_param->p_special_node->p_data_buf[i].node_id = + str_to_int(child_xnode->child->value.opaque); + + /*high raw limit*/ + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, + "highRawLimit", NULL, NULL, + MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + break; + } + p_raw_test_param->p_special_node->p_data_buf[i].high_raw_limit = + str_to_int(child_xnode->child->value.opaque); + + /*low raw limit*/ + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, + "lowRawLimit", NULL, NULL, + MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + break; + } + p_raw_test_param->p_special_node->p_data_buf[i].low_raw_limit = + str_to_int(child_xnode->child->value.opaque); + + /*accord limit*/ + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, + "accordLimit", NULL, NULL, + MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + break; + } + p_raw_test_param->p_special_node->p_data_buf[i].accord_limit = + str_to_int(child_xnode->child->value.opaque); + + /*offset limit*/ + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, + "offsetLimit", NULL, NULL, + MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + break; + } + p_raw_test_param->p_special_node->p_data_buf[i].offset_limit = + str_to_int(child_xnode->child->value.opaque); + + /*accord option*/ + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, + "accordOption", NULL, NULL, + MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + break; + } + p_raw_test_param->p_special_node->p_data_buf[i].accord_option = + str_to_int(child_xnode->child->value.opaque); + i++; + parent_xnode = mxmlFindElement(parent_xnode, special_xnode, + "node", NULL, NULL, + MXML_DESCEND); + } + p_raw_test_param->p_special_node->data_len = i; + return ret; +} + +/******************************************************************************* +* Function Name : parse_raw_max_limit +* Description : parse raw upper limit +* Input : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Output : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_raw_max_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param) +{ + s32 ret = 0; + mxml_node_t *parent_xnode = NULL; + mxml_node_t *child_xnode = NULL; + board_print_debug("parse raw max limit!\n"); + parent_xnode = mxmlFindElement(top, top, "rawdataLimitParam", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error( + "can not find rawdataLimitParam,please set in order!\n"); + return 0; + } + + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, "upperLimit", + NULL, NULL, MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + board_print_error( + "can not find raw upperLimit,please set in order!\n"); + return 0; + } + + if (p_raw_test_param->p_rawdata_limit == NULL) { + ret = alloc_mem_in_heap( + (void **)&p_raw_test_param->p_rawdata_limit, + sizeof(ST_RAWDATA_LIMIT_PARAM)); + if (ret == 0) { + board_print_error( + "rawdata limit malloc memory error!\n"); + return 0; + } + } + p_raw_test_param->p_rawdata_limit->upper_limit = + str_to_int(child_xnode->child->value.opaque); + board_print_debug("rawdata upper limit:%d!\n", + p_raw_test_param->p_rawdata_limit->upper_limit); + return ret; +} + +/******************************************************************************* +* Function Name : parse_raw_min_limit +* Description : parse raw lower limit +* Input : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Output : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_raw_min_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param) +{ + s32 ret = 1; + mxml_node_t *parent_xnode = NULL; + mxml_node_t *child_xnode = NULL; + board_print_debug("parse raw lower limit!\n"); + parent_xnode = mxmlFindElement(top, top, "rawdataLimitParam", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error("can not find rawdataLimitParam in order!\n"); + return 0; + } + + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, "lowerLimit", + NULL, NULL, MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + board_print_error( + "can not find raw lowerLimit,please set raw low limit!\n"); + return 0; + } + + if (p_raw_test_param->p_rawdata_limit == NULL) { + ret = alloc_mem_in_heap( + (void **)&p_raw_test_param->p_rawdata_limit, + sizeof(ST_RAWDATA_LIMIT_PARAM)); + if (ret == 0) { + board_print_error( + "rawdata limit malloc memory error!\n"); + return 0; + } + } + p_raw_test_param->p_rawdata_limit->lower_limit = + str_to_int(child_xnode->child->value.opaque); + board_print_debug("rawdata lower limit:%d!\n", + p_raw_test_param->p_rawdata_limit->lower_limit); + return ret; +} + +/******************************************************************************* +* Function Name : parse_accord_limit +* Description : parse accord limit +* Input : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Output : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_accord_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param) +{ + s32 ret = 0; + mxml_node_t *parent_xnode = NULL; + mxml_node_t *child_xnode = NULL; + + parent_xnode = mxmlFindElement(top, top, "accordLimitParam", NULL, NULL, + MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error("can not find accordLimitParam in order!\n"); + return 0; + } + ret = alloc_mem_in_heap((void **)&p_raw_test_param->p_raw_accord_limit, + sizeof(ST_RAW_ACCORD_LIMIT_PARAM)); + if (ret == 0) { + board_print_error("accord limit malloc memory error!\n"); + return 0; + } + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, "accordLimit", + NULL, NULL, MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + board_print_error("can not find accordLimit in order!\n"); + return 0; + } + p_raw_test_param->p_raw_accord_limit->accord_limit = + str_to_int(child_xnode->child->value.opaque); + + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, + "accordOption", NULL, NULL, MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + board_print_error("can not find accordOption in order!\n"); + return 0; + } + p_raw_test_param->p_raw_accord_limit->accord_option = + str_to_int(child_xnode->child->value.opaque); + board_print_debug("accord limit:%d!\n", + p_raw_test_param->p_raw_accord_limit->accord_limit); + return ret; +} + +/******************************************************************************* +* Function Name : parse_offset_limit +* Description : parse offset limit +* Input : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Output : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_offset_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param) +{ + s32 ret = 0; + mxml_node_t *parent_xnode = NULL; + mxml_node_t *child_xnode = NULL; + + parent_xnode = mxmlFindElement(top, top, "offsetLimitParam", NULL, NULL, + MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error("can not find offsetLimitParam in order!\n"); + return 0; + } + ret = alloc_mem_in_heap((void **)&p_raw_test_param->p_raw_offset_limit, + sizeof(ST_RAW_OFFSET_LIMIT_PARAM)); + if (ret == 0) { + board_print_error("offset limit malloc memory error!\n"); + return 0; + } + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, "offsetLimit", + NULL, NULL, MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + board_print_error("can not find offsetLimit in order!\n"); + return 0; + } + p_raw_test_param->p_raw_offset_limit->offset_limit = + str_to_int(child_xnode->child->value.opaque); + board_print_debug("offset limit:%d!\n", + p_raw_test_param->p_raw_offset_limit->offset_limit); + return ret; +} + +/******************************************************************************* +* Function Name : parse_uniform_limit +* Description : parse uniform limit +* Input : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Output : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_uniform_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param) +{ + s32 ret = 0; + mxml_node_t *parent_xnode = NULL; + mxml_node_t *child_xnode = NULL; + + parent_xnode = mxmlFindElement(top, top, "uniformLimitParam", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error("can not find uniformLimitParam in order!\n"); + return 0; + } + ret = alloc_mem_in_heap((void **)&p_raw_test_param->p_raw_uniform_limit, + sizeof(ST_RAW_UNIFORM_LIMIT_PARAM)); + if (ret == 0) { + board_print_error("uniform limit malloc memory error!\n"); + return 0; + } + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, + "uniformLimit", NULL, NULL, MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + board_print_error( + "can not find uniformLimit, please set uniform limit!\n"); + return 0; + } + p_raw_test_param->p_raw_uniform_limit->uniform_limit = + str_to_int(child_xnode->child->value.opaque); + board_print_debug("uniform limit:%d!\n", + p_raw_test_param->p_raw_uniform_limit->uniform_limit); + return ret; +} + +/******************************************************************************* +* Function Name : parse_jitter_limit +* Description : parse jitter limit +* Input : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Output : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_jitter_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param) +{ + s32 ret = 0; + mxml_node_t *parent_xnode = NULL; + mxml_node_t *child_xnode = NULL; + + parent_xnode = mxmlFindElement(top, top, "jitterLimitParam", NULL, NULL, + MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error("can not find jitterLimitParam in order!\n"); + return 0; + } + ret = alloc_mem_in_heap((void **)&p_raw_test_param->p_raw_jitter_limit, + sizeof(ST_RAW_JITTER_LIMIT_PARAM)); + if (ret == 0) { + board_print_error("jitter limit malloc memory error!\n"); + return 0; + } + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, "jitterLimit", + NULL, NULL, MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + board_print_error( + "can not find jitterLimit, please set jitter limit!\n"); + return 0; + } + p_raw_test_param->p_raw_jitter_limit->jitter_limit = + str_to_int(child_xnode->child->value.opaque); + board_print_debug("jitter limit:%d!\n", + p_raw_test_param->p_raw_jitter_limit->jitter_limit); + return ret; +} + +/******************************************************************************* +* Function Name : parse_key_max_limit +* Description : parse key upper limit +* Input : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Output : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_key_max_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param) +{ + s32 ret = 0; + mxml_node_t *parent_xnode = NULL; + mxml_node_t *child_xnode = NULL; + + parent_xnode = mxmlFindElement(top, top, "keydataLimitParam", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error("can not find keydataLimitParam in order!\n"); + return 0; + } + if (p_raw_test_param->p_raw_key_limit == NULL) { + ret = alloc_mem_in_heap( + (void **)&p_raw_test_param->p_raw_key_limit, + sizeof(ST_RAW_KEY_LIMIT_PARAM)); + if (ret == 0) { + board_print_error( + "key data limit malloc memory error!\n"); + return 0; + } + } + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, "upperLimit", + NULL, NULL, MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + board_print_error("can not find key upperLimit in order!\n"); + return 0; + } + p_raw_test_param->p_raw_key_limit->upper_limit = + str_to_int(child_xnode->child->value.opaque); + board_print_debug("key upper limit:%d!\n", + p_raw_test_param->p_raw_key_limit->upper_limit); + return ret; +} + +/******************************************************************************* +* Function Name : parse_key_min_limit +* Description : parse key lower limit +* Input : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Output : PST_RAWDATA_TEST_PARAM p_raw_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_key_min_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param) +{ + s32 ret = 1; + mxml_node_t *parent_xnode = NULL; + mxml_node_t *child_xnode = NULL; + + parent_xnode = mxmlFindElement(top, top, "keydataLimitParam", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error("can not find keydataLimitParam in order!\n"); + return 0; + } + if (p_raw_test_param->p_raw_key_limit == NULL) { + ret = alloc_mem_in_heap( + (void **)&p_raw_test_param->p_raw_key_limit, + sizeof(ST_RAW_KEY_LIMIT_PARAM)); + if (ret == 0) { + board_print_error( + "key data limit malloc memory error!\n"); + return 0; + } + } + child_xnode = mxmlFindElement(parent_xnode, parent_xnode, "lowerLimit", + NULL, NULL, MXML_DESCEND); + if ((child_xnode == NULL) || (child_xnode->child == NULL)) { + board_print_error("can not find key lowerLimit in order!\n"); + return 0; + } + p_raw_test_param->p_raw_key_limit->lower_limit = + str_to_int(child_xnode->child->value.opaque); + board_print_debug("key lower limit:%d!\n", + p_raw_test_param->p_raw_key_limit->lower_limit); + return ret; +} + +/******************************************************************************* +* Function Name : parse_raw_test_param +* Description : parse rawdata test param +* Input : PST_TEST_PARAM p_test_param + : PST_SUB_TEST_ITEM_ID_SET p_sub_id_set +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_raw_test_param(PST_TEST_PARAM p_test_param, + PST_SUB_TEST_ITEM_ID_SET p_sub_id_set) +{ + s32 ret = 0; + u16 i = 0; + u16 data_len = 0; + PST_RAWDATA_TEST_PARAM p_raw_test_param = NULL; + mxml_node_t *test_item = NULL; + + /*no sub id */ + if (p_sub_id_set == NULL) { + return 1; + } + /*find rawdat test param*/ + test_item = mxmlFindElement(top, top, "rawdataTestParam", NULL, NULL, + MXML_DESCEND); + if ((test_item == NULL) || (test_item->child == NULL)) { + board_print_error("can not find rawdataTestParam in order!\n"); + return 0; + } + + ret = alloc_mem_in_heap((void **)&p_test_param->p_raw_test_param, + sizeof(ST_RAWDATA_TEST_PARAM)); + if (ret == 0) { + board_print_error("raw test param malloc memory error!\n"); + return ret; + } + p_raw_test_param = + (PST_RAWDATA_TEST_PARAM)p_test_param->p_raw_test_param; + + p_raw_test_param->p_need_check_node = NULL; + p_raw_test_param->p_special_node = NULL; + p_raw_test_param->p_rawdata_limit = NULL; + p_raw_test_param->p_raw_accord_limit = NULL; + p_raw_test_param->p_raw_offset_limit = NULL; + p_raw_test_param->p_raw_jitter_limit = NULL; + p_raw_test_param->p_raw_uniform_limit = NULL; + p_raw_test_param->p_raw_key_limit = NULL; + + for (i = 0; i < p_sub_id_set->len; i++) { + switch (p_sub_id_set->p_id_set[i]) { + case TP_RAWDATA_MAX_TEST_ITEM_ID: { + /*rawdata limit*/ + ret = parse_raw_max_limit(p_raw_test_param); + break; + } + case TP_RAWDATA_MIN_TEST_ITEM_ID: { + ret = parse_raw_min_limit(p_raw_test_param); + break; + } + case TP_ACCORD_TEST_ITEM_ID: { + /*accord limit*/ + ret = parse_accord_limit(p_raw_test_param); + break; + } + case TP_OFFSET_TEST_ITEM_ID: { + /*offset limit*/ + ret = parse_offset_limit(p_raw_test_param); + break; + } + case TP_UNIFORMITY_TEST_ITEM_ID: { + /*uniform limit*/ + ret = parse_uniform_limit(p_raw_test_param); + break; + } + case TP_RAWDATA_JITTER_TEST_ITEM_ID: { + /*jitter limit*/ + ret = parse_jitter_limit(p_raw_test_param); + break; + } + case TP_KEYDATA_MAX_TEST_ITEM_ID: { + /*key data upper limit*/ + ret = parse_key_max_limit(p_raw_test_param); + break; + } + case TP_KEYDATA_MIN_TEST_ITEM_ID: { + /*key data min limit*/ + ret = parse_key_min_limit(p_raw_test_param); + break; + } + default: { + break; + } + } + + if (ret == 0) { + return ret; + board_print_error("parse rawdata item error!\n"); + } + } + /*need check node*/ + data_len = parse_need_check_node(p_raw_test_param); + if (data_len == 0) { + board_print_error("parse need check node error!\n"); + return 0; + } + /*special test node*/ + ret = parse_special_node(p_raw_test_param, data_len + TP_MAX_KEY_NUM); + if (ret == 0) { + board_print_error("parse special node error!\n"); + return 0; + } + board_print_debug("special node len:%d!\n", + p_raw_test_param->p_special_node->data_len); + + /*need check key*/ + ret = parse_need_check_key(p_raw_test_param, TP_MAX_KEY_NUM); + if (ret == 0) { + board_print_error("parse need check key error!\n"); + return 0; + } + return ret; +} + +/******************************************************************************* +* Function Name : parse_short_test_param +* Description : parse short test param +* Input : PST_TEST_PARAM p_test_param +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_short_test_param(PST_TEST_PARAM p_test_param) +{ + s32 ret = 0; + mxml_node_t *test_item = NULL; + mxml_node_t *parent_xnode = NULL; + PST_SHORT_PARAM p_short_param = NULL; + + /*find short test param*/ + test_item = mxmlFindElement(top, top, "shortThresholdParam", NULL, NULL, + MXML_DESCEND); + if ((test_item == NULL) || (test_item->child == NULL)) { + board_print_error( + "can not find shortThresholdParam,plesse set short param in order!\n"); + return 0; + } + + ret = alloc_mem_in_heap((void **)&p_test_param->p_short_param, + sizeof(ST_SHORT_PARAM)); + if (ret == 0) { + board_print_error("short test param malloc memory error!\n"); + return 0; + } + p_short_param = (PST_SHORT_PARAM)p_test_param->p_short_param; + p_short_param->short_bin.update_bin_addr.bin_ptr = NULL; + p_short_param->short_bin.update_bin_len = 0; + p_short_param->short_opt.opt.opt_ptr = NULL; + + /*short test thrd node*/ + parent_xnode = mxmlFindElement(test_item, test_item, + "drvGndVddResistorThreshold", NULL, NULL, + MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error( + "can not find drvGndVddResistorThreshold,plesse set in order!\n"); + return 0; + } + p_short_param->short_threshold.drv_gnd_vdd_resistor_threshold = + str_to_int(parent_xnode->child->value.opaque); + board_print_debug( + "drv_gnd_vdd_resistor_threshold is :%d\n", + p_short_param->short_threshold.drv_gnd_vdd_resistor_threshold); + + parent_xnode = mxmlFindElement(test_item, test_item, + "senGndVddResistorThreshold", NULL, NULL, + MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error( + "can not find senGndVddResistorThreshold,plesse set in order!\n"); + return 0; + } + p_short_param->short_threshold.sen_gnd_vdd_resistor_threshold = + str_to_int(parent_xnode->child->value.opaque); + board_print_debug( + "sen_gnd_vdd_resistor_threshold is :%d\n", + p_short_param->short_threshold.sen_gnd_vdd_resistor_threshold); + + parent_xnode = mxmlFindElement(test_item, test_item, + "senSenResistorThreshold", NULL, NULL, + MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error( + "can not find senSenResistorThreshold,plesse set in order!\n"); + return 0; + } + p_short_param->short_threshold.sen_sen_resistor_threshold = + str_to_int(parent_xnode->child->value.opaque); + board_print_debug( + "sen_sen_resistor_threshold is :%d\n", + p_short_param->short_threshold.sen_sen_resistor_threshold); + + parent_xnode = mxmlFindElement(test_item, test_item, + "drvDrvResistorThreshold", NULL, NULL, + MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error( + "can not find drvDrvResistorThreshold,plesse set in order!\n"); + return 0; + } + p_short_param->short_threshold.drv_drv_resistor_threshold = + str_to_int(parent_xnode->child->value.opaque); + board_print_debug( + "drv_drv_resistor_threshold is :%d\n", + p_short_param->short_threshold.drv_drv_resistor_threshold); + + parent_xnode = mxmlFindElement(test_item, test_item, + "drvSenResistorThreshold", NULL, NULL, + MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error( + "can not find drvSenResistorThreshold,plesse set in order!\n"); + return 0; + } + p_short_param->short_threshold.drv_sen_resistor_threshold = + str_to_int(parent_xnode->child->value.opaque); + board_print_debug( + "drv_sen_resistor_threshold is :%d\n", + p_short_param->short_threshold.drv_sen_resistor_threshold); + + parent_xnode = mxmlFindElement(test_item, test_item, "gtShortThreshold", + NULL, NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error( + "can not find gtShortThreshold,plesse set in order!\n"); + return 0; + } + p_short_param->short_threshold.gt_short_threshold = + str_to_int(parent_xnode->child->value.opaque); + board_print_debug("gt_short_threshold is :%d\n", + p_short_param->short_threshold.gt_short_threshold); + + parent_xnode = mxmlFindElement(test_item, test_item, "adcReadDelay", + NULL, NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error( + "can not find adcReadDelay,plesse set in order!\n"); + return 0; + } + p_short_param->short_threshold.adc_read_delay = + str_to_int(parent_xnode->child->value.opaque); + board_print_debug("adc_read_delay is :%d\n", + p_short_param->short_threshold.adc_read_delay); + + parent_xnode = mxmlFindElement(test_item, test_item, + "diffcodeShortThreshold", NULL, NULL, + MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error( + "can not find diffcodeShortThreshold,plesse set in order!\n"); + return 0; + } + p_short_param->short_threshold.diffcode_short_threshold = + str_to_int(parent_xnode->child->value.opaque); + board_print_debug( + "diffcode_short_threshold is :%d\n", + p_short_param->short_threshold.diffcode_short_threshold); + + p_short_param->short_threshold.tx_tx_factor = 68; + parent_xnode = mxmlFindElement(test_item, test_item, "txTxFactor", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode != NULL) && (parent_xnode->child != NULL)) { + p_short_param->short_threshold.tx_tx_factor = + str_to_int(parent_xnode->child->value.opaque); + board_print_debug("tx_tx_factor is :%d\n", + p_short_param->short_threshold.tx_tx_factor); + } + + p_short_param->short_threshold.tx_rx_factor = 89; + parent_xnode = mxmlFindElement(test_item, test_item, "txRxFactor", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode != NULL) && (parent_xnode->child != NULL)) { + p_short_param->short_threshold.tx_rx_factor = + str_to_int(parent_xnode->child->value.opaque); + board_print_debug("tx_rx_factor is :%d\n", + p_short_param->short_threshold.tx_rx_factor); + } + + p_short_param->short_threshold.rx_rx_factor = 75; + parent_xnode = mxmlFindElement(test_item, test_item, "rxRxFactor", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode != NULL) && (parent_xnode->child != NULL)) { + p_short_param->short_threshold.rx_rx_factor = + str_to_int(parent_xnode->child->value.opaque); + board_print_debug("rx_rx_factor is :%d\n", + p_short_param->short_threshold.rx_rx_factor); + } + return ret; +} + +/******************************************************************************* +* Function Name : parse_version_test_param +* Description : parse version test param +* Input : PST_TEST_PARAM p_test_param +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_version_test_param(PST_TEST_PARAM p_test_param) +{ + s32 ret = 0; + mxml_node_t *test_item = NULL; + mxml_node_t *parent_xnode = NULL; + PST_VERSION_PARAM p_ver_param = NULL; + + /*malloc memory*/ + if (p_test_param->p_version_test_param == NULL) { + ret = alloc_mem_in_heap( + (void **)&p_test_param->p_version_test_param, + sizeof(ST_VERSION_PARAM)); + if (ret == 0) { + board_print_error( + "version test param malloc memory error!\n"); + return 0; + } + } else { + board_print_error("version test param memory error!\n"); + } + p_ver_param = (PST_VERSION_PARAM)p_test_param->p_version_test_param; + p_ver_param->p_update_bin_param = NULL; + + /*find version test param*/ + test_item = mxmlFindElement(top, top, "versionTestParam", NULL, NULL, + MXML_DESCEND); + if ((test_item == NULL) || (test_item->child == NULL)) { + board_print_error( + "can not find varsion test param,plesse set version param in order!\n"); + return 0; + } + + parent_xnode = mxmlFindElement(test_item, test_item, "icVerAddr", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error( + "can not find icVerAddr,plesse set icVerAddr in order!\n"); + return 0; + } + p_ver_param->ic_ver_addr = + atohex((unsigned char *)parent_xnode->child->value.opaque, + strlen((const char *)parent_xnode->child->value.opaque)); + board_print_debug("ic version addr:0x%04x!\n", + p_ver_param->ic_ver_addr); + p_ver_param->b_auto_update = 0; + + parent_xnode = mxmlFindElement(test_item, test_item, "versionStr", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error( + "can not find varsion info,plesse set fw version in order!\n"); + return 0; + } + p_ver_param->ver_param_len = hexstr_to_array( + p_ver_param->ver_param_str, parent_xnode->child->value.opaque, + MAX_VERSION_LEN); + board_print_debug("ver_param_len:%d!\n", p_ver_param->ver_param_len); + return ret; +} + +/******************************************************************************* +* Function Name : parse_flash_test_param +* Description : parse flash test param +* Input : PST_TEST_PARAM p_test_param +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_flash_test_param(PST_TEST_PARAM p_test_param) +{ + s32 ret = 0; + mxml_node_t *test_item = NULL; + mxml_node_t *parent_xnode = NULL; + PST_FLASH_TEST_PARAM p_flash_param = NULL; + + /*find version test param*/ + ret = alloc_mem_in_heap((void **)&p_test_param->p_flash_test_param, + sizeof(ST_FLASH_TEST_PARAM)); + if (ret == 0) { + board_print_error("flash test param malloc memory error!\n"); + return 0; + } + p_flash_param = (PST_FLASH_TEST_PARAM)p_test_param->p_flash_test_param; + p_flash_param->config_arr = NULL; + p_flash_param->delay_time = 0; + + test_item = mxmlFindElement(top, top, "flashTestParam", NULL, NULL, + MXML_DESCEND); + if ((test_item == NULL) || (test_item->child == NULL)) { + board_print_error( + "can not find flash test param,plesse set flash param in order!\n"); + return 0; + } + + parent_xnode = mxmlFindElement(test_item, test_item, "option", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error("can not find flash option,order error!\n"); + return 0; + } + p_flash_param->option = str_to_int(parent_xnode->child->value.opaque); + board_print_debug("flash test option:0x%04x!\n", p_flash_param->option); + + parent_xnode = mxmlFindElement(test_item, test_item, "delayTime", NULL, + NULL, MXML_DESCEND); + if ((parent_xnode != NULL) && (parent_xnode->child != NULL)) { + p_flash_param->delay_time = + str_to_int(parent_xnode->child->value.opaque); + } + board_print_debug("delay_time in xml:%d!\n", p_flash_param->delay_time); + + return ret; +} + +/******************************************************************************* +* Function Name : parse_ic_name +* Description : parse_ic_name from order +* Input : PST_TEST_PARAM p_test_param +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +static s32 parse_ic_name(PST_TEST_PARAM p_test_param) +{ + s32 ret = 1; + mxml_node_t *obj_set = NULL; + mxml_node_t *parent_xnode = NULL; + + obj_set = mxmlFindElement(top, top, "OBJ_SETTING", NULL, NULL, + MXML_DESCEND); + + if ((obj_set == NULL) || (obj_set->child == NULL)) { + board_print_error("can not find OBJ_SETTING in order!\n"); + return 0; + } + + parent_xnode = mxmlFindElement(obj_set, obj_set, "chipName", NULL, NULL, + MXML_DESCEND); + if ((parent_xnode == NULL) || (parent_xnode->child == NULL)) { + board_print_error("can not find chipName in order!\n"); + return 0; + } + memcpy(p_test_param->ic_name, parent_xnode->child->value.opaque, + strlen((const char *)parent_xnode->child->value.opaque) + 1); + board_print_debug("ic name in order :%s\n", p_test_param->ic_name); + + return ret; +} + +/******************************************************************************* +* Function Name : parse_test_param +* Description : parse test param +* Input : PST_TEST_PARAM *pp_test_param +* Output : PST_TEST_PARAM *pp_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 parse_test_param(PST_TEST_PARAM *pp_test_param) +{ + PST_TEST_PARAM p_test_param; + u16 i = 0; + s32 ret = 0; + u8 need_send_cfg = 0; + u8 cfg_flag = 0; + + /*(1)malloc memory for test param*/ + if (alloc_mem_in_heap((void **)pp_test_param, sizeof(ST_TEST_PARAM)) == + 0) { + board_print_error("test param malloc memory error!"); + return 0; + } + p_test_param = (PST_TEST_PARAM)(*pp_test_param); + p_test_param->test_cfg = NULL; + p_test_param->cfg_len = 0; + p_test_param->mode_sen_line = 0; + p_test_param->p_test_item_id_set = NULL; + p_test_param->p_raw_test_param = NULL; + p_test_param->p_diff_test_param = NULL; + p_test_param->p_short_param = NULL; + p_test_param->p_version_test_param = NULL; + p_test_param->p_flash_test_param = NULL; + + ret = parse_ic_name(p_test_param); + if (ret == 0) { + return 0; + } + + ret = parse_test_item_id(p_test_param); + if (ret == 0) { + board_print_error("parse test item id error!\n"); + return 0; + } + + if (p_test_param->test_item_num == 0) { + board_print_error("no need test item!\n"); + return 0; + } + + ret = parse_order_config(p_test_param); + if (ret == 0) { + board_print_error("parse_order_config error!\n"); + return 0; + } + + for (i = 0; i < p_test_param->test_item_num; i++) { + switch (p_test_param->p_test_item_id_set[i].test_id) { + case TP_RAWDATA_TEST_ITEMS_SET_ID: { + p_test_param->close_hop = 1; + need_send_cfg++; + ret = parse_raw_test_param( + p_test_param, + p_test_param->p_test_item_id_set[i] + .p_sub_id_set); + break; + } + case TP_SHORT_TEST_ITEM_ID: { + need_send_cfg++; + ret = parse_short_test_param(p_test_param); + break; + } + case TP_VERSION_TEST_ITEM_ID: { + ret = parse_version_test_param(p_test_param); + break; + } + case TP_FLASH_TEST_ITEM_ID: { + ret = parse_flash_test_param(p_test_param); + break; + } + case TP_CHIP_CFG_PROC_ITEM_ID: { + cfg_flag |= 0x01; + /*ret = parse_order_config(p_test_param);*/ + break; + } + case TP_RECOVER_CFG_ITEM_ID: { + cfg_flag |= 0x02; + break; + } + default: { + break; + } + } + if (ret == 0) { + board_print_error("parse test param error!\n"); + break; + } + } + + if (need_send_cfg > 0) { + if ((cfg_flag & 0x01) == 0) { + p_test_param + ->p_test_item_id_set[p_test_param->test_item_num] + .test_id = TP_CHIP_CFG_PROC_ITEM_ID; + p_test_param->test_item_num++; + } + if ((cfg_flag & 0x02) == 0) { + p_test_param + ->p_test_item_id_set[p_test_param->test_item_num] + .test_id = TP_RECOVER_CFG_ITEM_ID; + p_test_param->test_item_num++; + } + } else { + if (((cfg_flag & 0x01) == 1) && ((cfg_flag & 0x02) == 0)) { + p_test_param + ->p_test_item_id_set[p_test_param->test_item_num] + .test_id = TP_RECOVER_CFG_ITEM_ID; + p_test_param->test_item_num++; + } + } + if ((cfg_flag & 0x01) == 0) { + p_test_param->test_cfg[0] = '\0'; + p_test_param->cfg_len = 0; + } + return ret; +} + +/******************************************************************************* +* Function Name : release_order_config +* Description : release order config +* Input : PST_TEST_PARAM p_test_param +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 release_order_config(PST_TEST_PARAM p_test_param) +{ + s32 ret = 1; + if (p_test_param->test_cfg != NULL) { + ret = free_mem_in_heap_p((void **)&p_test_param->test_cfg); + } + + return ret; +} + +/******************************************************************************* +* Function Name : release_test_item_id +* Description : release test item id +* Input : PST_TEST_PARAM p_test_param +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 release_test_item_id(PST_TEST_PARAM p_test_param) +{ + s32 ret = 1; + u16 i = 0; + if (p_test_param->p_test_item_id_set != NULL) { + if (p_test_param->p_test_item_id_set[i].p_sub_id_set != NULL) { + if (p_test_param->p_test_item_id_set[i] + .p_sub_id_set->p_id_set != NULL) { + ret = free_mem_in_heap_p( + (void **)&p_test_param + ->p_test_item_id_set[i] + .p_sub_id_set->p_id_set); + } + ret = free_mem_in_heap_p( + (void **)&p_test_param->p_test_item_id_set[i] + .p_sub_id_set); + } + ret = free_mem_in_heap_p( + (void **)&p_test_param->p_test_item_id_set); + } + + return ret; +} + +/******************************************************************************* +* Function Name : release_raw_test_param +* Description : release rawdata test param +* Input : PST_TEST_PARAM p_test_param +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 release_raw_test_param(PST_TEST_PARAM p_test_param) +{ + s32 ret = 1; + PST_RAWDATA_TEST_PARAM p_raw_test_param = + p_test_param->p_raw_test_param; + if (p_raw_test_param != NULL) { + /*free need check node buffer*/ + if (p_raw_test_param->p_need_check_node != NULL) { + ret = free_mem_in_heap_p( + (void **)&p_raw_test_param->p_need_check_node + ->p_data_buf); + ret = free_mem_in_heap_p( + (void **)&p_raw_test_param->p_need_check_node); + } + /*free special node buffer*/ + if (p_raw_test_param->p_special_node != NULL) { + ret = free_mem_in_heap_p( + (void **)&p_raw_test_param->p_special_node + ->p_data_buf); + ret = free_mem_in_heap_p( + (void **)&p_raw_test_param->p_special_node); + } + /*free raw limit parameter buffer*/ + if (p_raw_test_param->p_rawdata_limit != NULL) { + ret = free_mem_in_heap_p( + (void **)&p_raw_test_param->p_rawdata_limit); + } + /*free rawdata acoord limit parameter buffe*/ + if (p_raw_test_param->p_raw_accord_limit != NULL) { + ret = free_mem_in_heap_p( + (void **)&p_raw_test_param->p_raw_accord_limit); + } + /*free raw offset limit parameter buffer*/ + if (p_raw_test_param->p_raw_offset_limit != NULL) { + ret = free_mem_in_heap_p( + (void **)&p_raw_test_param->p_raw_offset_limit); + } + /*free raw jitter limit parameter buffer*/ + if (p_raw_test_param->p_raw_jitter_limit != NULL) { + ret = free_mem_in_heap_p( + (void **)&p_raw_test_param->p_raw_jitter_limit); + } + /*free raw uniform limit parameter buffer*/ + if (p_raw_test_param->p_raw_uniform_limit != NULL) { + ret = free_mem_in_heap_p( + (void **)&p_raw_test_param->p_raw_uniform_limit); + } + /*free keydata limit parameter buffer*/ + if (p_raw_test_param->p_raw_key_limit != NULL) { + if (p_raw_test_param->p_raw_key_limit + ->p_need_check_key != NULL) { + if (p_raw_test_param->p_raw_key_limit + ->p_need_check_key->p_data_buf != + NULL) { + ret = free_mem_in_heap_p( + (void **)&p_raw_test_param + ->p_raw_key_limit + ->p_need_check_key + ->p_data_buf); + } + ret = free_mem_in_heap_p( + (void **)&p_raw_test_param + ->p_raw_key_limit + ->p_need_check_key); + } + ret = free_mem_in_heap_p( + (void **)&p_raw_test_param->p_raw_key_limit); + } + /*free raw test parameter*/ + ret = free_mem_in_heap_p((void **)&p_raw_test_param); + p_test_param->p_raw_test_param = NULL; + } + + return ret; +} + +/******************************************************************************* +* Function Name : release_short_test_param +* Description : release short test param +* Input : PST_TEST_PARAM p_test_param +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 release_short_test_param(PST_TEST_PARAM p_test_param) +{ + s32 ret = 1; + PST_SHORT_PARAM p_short_param = p_test_param->p_short_param; + if (p_short_param != NULL) { + ret = free_mem_in_heap_p((void **)&p_short_param); + } + return ret; +} + +/******************************************************************************* +* Function Name : release_version_test_param +* Description : release version test param +* Input : PST_TEST_PARAM p_test_param +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 release_version_test_param(PST_TEST_PARAM p_test_param) +{ + s32 ret = 0; + PST_VERSION_PARAM p_ver_param = NULL; + p_ver_param = p_test_param->p_version_test_param; + if (p_ver_param == NULL) { + return 1; + } + p_ver_param->p_update_bin_param = NULL; + ret = free_mem_in_heap((void *)p_ver_param); + p_test_param->p_version_test_param = NULL; + return ret; +} + +/******************************************************************************* +* Function Name : release_flash_test_param +* Description : release flash test param +* Input : PST_TEST_PARAM p_test_param +* Output : PST_TEST_PARAM p_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 release_flash_test_param(PST_TEST_PARAM p_test_param) +{ + s32 ret = 1; + PST_FLASH_TEST_PARAM p_flash_param = NULL; + p_flash_param = p_test_param->p_flash_test_param; + if (p_flash_param != NULL) { + if (p_flash_param->config_arr != NULL) { + ret = free_mem_in_heap( + (void *)p_flash_param->config_arr); + } + ret = free_mem_in_heap((void *)p_flash_param); + } + return ret; +} + +/******************************************************************************* +* Function Name : release_test_param +* Description : release test param +* Input : PST_TEST_PARAM* pp_test_param +* Output : PST_TEST_PARAM* pp_test_param +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 release_test_param(PST_TEST_PARAM *pp_test_param) +{ + s32 ret = 1; + PST_TEST_PARAM p_test_param = NULL; + if ((pp_test_param == NULL) || ((*pp_test_param) == NULL)) { + return 1; + } + p_test_param = (*pp_test_param); + ret = release_order_config(p_test_param); + ret = release_test_item_id(p_test_param); + ret = release_raw_test_param(p_test_param); + ret = release_short_test_param(p_test_param); + ret = release_version_test_param(p_test_param); + ret = release_flash_test_param(p_test_param); + ret = free_mem_in_heap(p_test_param); + p_test_param = NULL; + return ret; +} + +/******************************************************************************* +* Function Name : decrypt_tp_order +* Description : decrypt_tp_order +* Input : s8** pp_buf(buf content)you need free memory by yourself +* Input : s2* p_len(len) +* Output : none +* Return : s32(0:ok other:error code) +*******************************************************************************/ +static s32 decrypt_tp_order(PST_TP_DEV p_tp_dev, s8 **pp_buf, u32 *p_len) +{ + s32 ret = 0; + s8 *ver = NULL; + + /*read decode order*/ + ret = read_file_decoder(p_tp_dev, &ver, pp_buf); + if (ret == 0) { + board_print_error("read file decoder error!\n"); + free_mem_in_heap(ver); + return 0; + } + /*get length of xml*/ + *p_len = strlen((cstr)*pp_buf); + + free_mem_in_heap(ver); + return ret; +} + +/******************************************************************************* +* Function Name : parse_init_param_dev +* Description : parse_init_param_dev +* Input : PST_TEST_PROC_DATA p_test_proc_data +* Output : PST_TEST_PROC_DATA p_test_proc_data +* Return : s32(0:faild 1:ok) +*******************************************************************************/ +extern int parse_test_order(PST_TEST_PARAM *pp_test_param, PST_TP_DEV p_tp_dev) +{ + s32 ret = 1; + s8 *file_content = NULL; + u32 xml_buf_len = 0; + PST_TEST_PARAM p_test_param = NULL; + + /*(1)decrypt order*/ + board_print_debug("decypt order!"); + ret = decrypt_tp_order(p_tp_dev, &file_content, &xml_buf_len); + if (ret == 0) { + free_mem_in_heap(file_content); + return 0; + } + /*(2)load xml file*/ + board_print_debug("load xml file!"); + top = mxmlLoadString(NULL, file_content, MXML_OPAQUE_CALLBACK); + if (top == NULL) { + ret = 0; + board_print_error("load xml fail!\n"); + free_mem_in_heap(file_content); + return 0; + } + /*(3)init test param struct*/ + board_print_debug("parse test param!\n"); + ret = parse_test_param(pp_test_param); + p_test_param = (PST_TEST_PARAM)(*pp_test_param); + if (ret == 0) { + goto PARSE_END; + } + /*(2)init tp ev struct*/ + ret = parse_init_dev_info(p_tp_dev, p_test_param); + if (ret == 0) { + goto PARSE_END; + } + /*judge need check node*/ + if (p_test_param->p_raw_test_param != NULL && + p_test_param->p_raw_test_param->p_need_check_node != NULL) { + if (p_test_param->p_raw_test_param->p_need_check_node->data_len < + p_tp_dev->sc_drv_num * p_tp_dev->sc_sen_num) { + board_print_error( + "need check node param error, node len in xml:%d, sc_drv_num:%d, sc_sen_num:%d\n", + p_test_param->p_raw_test_param + ->p_need_check_node->data_len, + p_tp_dev->sc_drv_num, p_tp_dev->sc_sen_num); + ret = 0; + goto PARSE_END; + } + } + +PARSE_END: + /*release xml file */ + /*mxmlDelete(top);*/ + free_mem_in_heap(file_content); + + return ret; +} + +#ifdef __cplusplus +} +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_order.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_order.h new file mode 100644 index 000000000000..cf440a8e2b09 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_order.h @@ -0,0 +1,142 @@ +/******************** (C) COPYRIGHT 2018 Goodix ******************** +* File Name : test_order.h +* Author : +* Version : V1.0.0 +* Date : 03/05/2018 +* Description : test order info +*******************************************************************************/ +#ifndef TEST_ORDER_H +#define TEST_ORDER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "test_item_def.h" +#include "tp_open_test_param.h" +#include "tp_short_test_param.h" +#include "tp_version_test_param.h" +#include "tp_additional_option_param.h" +#include "tp_dev_def.h" +#include "mxml.h" +#include "config.h" + +/***********************************dev info**********************************/ + +#define IC_NAME_LEN 15 +#define MAX_PARAM_LEN 200 + +/***********************************test param**********************************/ + +typedef struct TEST_ITEM_ID_SET { + u16 test_id; + PST_SUB_TEST_ITEM_ID_SET p_sub_id_set; +} ST_TEST_ITEM_ID_SET, *PST_TEST_ITEM_ID_SET; + +#define MAX_TEST_NUM 20 +#define MAX_SUBTEST_NUM 10 + +typedef struct TEST_PARAM { + u8 ic_name[15]; + u16 cfg_len; + u8 *test_cfg; + u16 send_cfg_option; + u16 close_hop; /*1:need close hopping 0:do nothing*/ + u8 mode_sen_line; + /*test items*/ + u16 test_item_num; + PST_TEST_ITEM_ID_SET p_test_item_id_set; + /*rawdata test*/ + PST_RAWDATA_TEST_PARAM p_raw_test_param; + /*diffdata test*/ + PST_DIFFDATA_TEST_PARAM p_diff_test_param; + /*short test*/ + PST_SHORT_PARAM p_short_param; + /*version test*/ + PST_VERSION_PARAM p_version_test_param; + /*flash test*/ + PST_FLASH_TEST_PARAM p_flash_test_param; +} ST_TEST_PARAM, *PST_TEST_PARAM; + +typedef struct ADDR_POS_INFO { + u16 addr; + u16 package_id; /*package_id(Tx),*/ + u16 offset; /*normandy*/ + u8 lsb; /*least significant bit*/ + u8 hsb; /*high significant bit*/ +} ST_ADDR_POS_INFO, *PST_ADDR_POS_INFO; + +/*************************************Public methods start********************************************/ + +/*malloc memory for test order param*/ +extern int parse_test_order(PST_TEST_PARAM *pp_test_param, PST_TP_DEV p_tp_dev); +extern s32 release_test_order(PST_TEST_PARAM *pp_test_param); + +/*parse dev info*/ +extern s32 parse_init_dev_info(PST_TP_DEV p_tp_dev, + PST_TEST_PARAM p_test_param); + +/*init dev*/ +extern s32 header_file_init_dev(PST_TP_DEV p_tp_dev, u8 *cfg, u16 *p_cfg_len); +extern void init_dev_const_param(PST_TP_DEV p_tp_dev); +extern s32 parse_key_data(PST_TP_DEV p_tp_dev, u8 *cfg); +extern s32 parse_cfg(PST_TP_DEV p_tp_dev, u8 *cfg); +extern u32 parse_addr_from_str(PST_TP_DEV p_dev, u8 *string_info, cu8 *config); +extern u32 parse_cfg_value(PST_TP_DEV p_dev, u8 *string_info, u8 *p_config); +extern s32 get_sc_drv_sen_key_num(PST_TP_DEV p_tp_dev, u8 key_start_addr, + u8 key_en, u8 sen_as_key, u8 key_com_port_num, + u8 max_key_num); +extern s32 disable_hopping(PST_TP_DEV p_tp_dev, u8 *str_info, u8 *cfg, + u16 cfg_len); + +/*parse test param*/ +extern s32 parse_test_param(PST_TEST_PARAM *pp_test_param); +extern s32 release_test_param(PST_TEST_PARAM *pp_test_param); + +/*parse test config*/ +extern s32 parse_order_config(PST_TEST_PARAM p_test_param); +extern s32 release_order_config(PST_TEST_PARAM p_test_param); + +/*parse test item id*/ +extern s32 parse_test_item_id(PST_TEST_PARAM p_test_param); +extern s32 release_test_item_id(PST_TEST_PARAM p_test_param); + +/*parse rawdata test param*/ +extern s32 parse_raw_test_param(PST_TEST_PARAM p_test_param, + PST_SUB_TEST_ITEM_ID_SET p_sub_id_set); +extern u16 parse_need_check_node(PST_RAWDATA_TEST_PARAM p_raw_test_param); +extern s32 parse_need_check_key(PST_RAWDATA_TEST_PARAM p_raw_test_param, + u16 data_len); +extern s32 parse_special_node(PST_RAWDATA_TEST_PARAM p_raw_test_param, + u16 data_len); +extern s32 parse_raw_max_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param); +extern s32 parse_raw_min_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param); +extern s32 parse_accord_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param); +extern s32 parse_offset_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param); +extern s32 parse_uniform_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param); +extern s32 parse_jitter_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param); +extern s32 parse_key_max_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param); +extern s32 parse_key_min_limit(PST_RAWDATA_TEST_PARAM p_raw_test_param); +extern s32 release_raw_test_param(PST_TEST_PARAM p_test_param); + +/*parse diffdata test param*/ +extern s32 parse_diff_test_param(PST_TEST_PARAM p_test_param); +extern s32 release_diff_test_param(PST_TEST_PARAM p_test_param); + +/*parse short test param*/ +extern s32 parse_short_test_param(PST_TEST_PARAM p_test_param); +extern s32 release_short_test_param(PST_TEST_PARAM p_test_param); + +/*parse version test param*/ +extern s32 parse_version_test_param(PST_TEST_PARAM p_test_param); +extern s32 release_version_test_param(PST_TEST_PARAM p_test_param); + +/*parse flash test param*/ +extern s32 parse_flash_test_param(PST_TEST_PARAM p_test_param); +extern s32 release_flash_test_param(PST_TEST_PARAM p_test_param); +/*************************************Public methods end********************************************/ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_param_init.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_param_init.c new file mode 100644 index 000000000000..b2d713de3631 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_param_init.c @@ -0,0 +1,624 @@ +/******************** (C) COPYRIGHT 2017 Goodix ******************** +* File Name : test_param_init.h +* Author : Zhitao Yang +* Version : V1.0.0 +* Date : 12/29/2017 +* Description : initial test param +*******************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#include "test_param_init.h" +#include "test_proc.h" +#include "simple_mem_manager.h" + +#include "tp_dev_control.h" +#include "tp_open_test.h" +#include "tp_short_test.h" +#include "tp_version_test.h" +#include "tp_additional_option.h" + +#include "test_item_init.h" +#include "save_test_data.h" +#include "generic_func.h" +#include "extra_tp_control.h" +#include "tp_item_permutation.h" +#include "board_opr_interface.h" +#include + +#include "tp_normandy_control.h" + +/*static s8 s_ic_name[10] = "";*/ + +/******************************************************************************* +* Function Name : init_test_item +* Description : initial test item +* Input : PST_TEST_PROC_DATA p_test_proc_data + : PST_TEST_PARAM p_test_param +* Output : PST_TEST_PROC_DATA p_test_proc_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 init_test_item(PST_TEST_PROC_DATA p_test_proc_data, + PST_TEST_PARAM p_test_param) +{ + s32 ret = 1; + u16 i = 0; + PST_TEST_ITEM *pp_test_item_arr = NULL; + u16 item_num = 0; + + pp_test_item_arr = p_test_proc_data->pp_test_item_arr; + item_num = p_test_proc_data->test_item_num; + + for (i = 0; i < item_num; i++) { + switch (pp_test_item_arr[i]->test_item_id) { + /*----------------------tp open test-----------------------*/ + case TP_RAWDATA_TEST_ITEMS_SET_ID: { + ret = rawdata_test_before_func( + (p_test_proc_data->pp_test_item_arr)[i], + p_test_param); + } break; + + /*----------------------hardware test-----------------------*/ + case TP_SHORT_TEST_ITEM_ID: { + ret = short_test_before_func( + (p_test_proc_data->pp_test_item_arr)[i], + p_test_param); + } break; + + case TP_VERSION_TEST_ITEM_ID: { + ret = version_test_before_func( + (p_test_proc_data->pp_test_item_arr)[i], + p_test_param); + } break; + + /*----------------------other test-----------------------*/ + case TP_CHIP_CFG_PROC_ITEM_ID: { + ret = send_cfg_test_before_func( + (p_test_proc_data->pp_test_item_arr)[i], + p_test_param); + } break; + + case TP_RECOVER_CFG_ITEM_ID: { + ret = cfg_recover_test_before_func( + (p_test_proc_data->pp_test_item_arr)[i]); + } break; + + case TP_FLASH_TEST_ITEM_ID: { + ret = flash_test_before_func( + (p_test_proc_data->pp_test_item_arr)[i], + p_test_param); + } break; + + default: { + ; + } break; + } + } + + return ret; +} + +/******************************************************************************* +* Function Name : register_test_item_finished_func +* Description : print test result +* Input : PST_TEST_PROC_DATA* pp_test_proc_data +* Output : PST_TEST_PROC_DATA* pp_test_proc_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 register_test_item_finished_func(PST_TEST_PROC_DATA p_test_proc_data) +{ + s32 ret = 1; + u16 i = 0; + PST_TEST_ITEM *pp_test_item_arr = NULL; + u16 item_num = 0; + pp_test_item_arr = p_test_proc_data->pp_test_item_arr; + item_num = p_test_proc_data->test_item_num; + if (pp_test_item_arr == NULL) { + return ret; + } + + for (i = 0; i < item_num; i++) { + if ((p_test_proc_data->pp_test_item_arr)[i] != NULL) { + switch (pp_test_item_arr[i]->test_item_id) { + /*----------------------tp open test-----------------------*/ + case TP_RAWDATA_TEST_ITEMS_SET_ID: { + pp_test_item_arr[i] + ->ptr_test_item_finished_func = + print_rawdata_test_res; + pp_test_item_arr[i] + ->ptr_test_item_finished_func_param = + (p_test_proc_data->pp_test_item_arr)[i]; + } break; + + /*----------------------hardware test-----------------------*/ + case TP_SHORT_TEST_ITEM_ID: { + pp_test_item_arr[i] + ->ptr_test_item_finished_func = + print_short_test_res; + pp_test_item_arr[i] + ->ptr_test_item_finished_func_param = + (p_test_proc_data->pp_test_item_arr)[i]; + } break; + + case TP_VERSION_TEST_ITEM_ID: { + pp_test_item_arr[i] + ->ptr_test_item_finished_func = + print_version_test_res; + pp_test_item_arr[i] + ->ptr_test_item_finished_func_param = + (p_test_proc_data->pp_test_item_arr)[i]; + } break; + + /*----------------------other test-----------------------*/ + case TP_CHIP_CFG_PROC_ITEM_ID: { + pp_test_item_arr[i] + ->ptr_test_item_finished_func = + print_send_cfg_test_res; + pp_test_item_arr[i] + ->ptr_test_item_finished_func_param = + (p_test_proc_data->pp_test_item_arr)[i]; + } break; + + case TP_RECOVER_CFG_ITEM_ID: { + pp_test_item_arr[i] + ->ptr_test_item_finished_func = + print_cfg_recover_test_res; + pp_test_item_arr[i] + ->ptr_test_item_finished_func_param = + (p_test_proc_data->pp_test_item_arr)[i]; + } break; + + case TP_FLASH_TEST_ITEM_ID: { + pp_test_item_arr[i] + ->ptr_test_item_finished_func = + print_flash_test_res; + pp_test_item_arr[i] + ->ptr_test_item_finished_func_param = + (p_test_proc_data->pp_test_item_arr)[i]; + } break; + + default: { + ; + } break; + } + } + } + return ret; +} + +/******************************************************************************* +* Function Name : release_test_item +* Description : release test item +* Input : PST_TEST_PROC_DATA* pp_test_proc_data +* Output : PST_TEST_PROC_DATA* pp_test_proc_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 release_test_item(PST_TEST_PROC_DATA p_test_proc_data) +{ + s32 ret = 1; + u16 i = 0; + PST_TEST_ITEM *pp_test_item_arr = NULL; + u16 item_num = 0; + pp_test_item_arr = p_test_proc_data->pp_test_item_arr; + item_num = p_test_proc_data->test_item_num; + if (pp_test_item_arr == NULL) { + return ret; + } + + for (i = 0; i < item_num; i++) { + if ((p_test_proc_data->pp_test_item_arr)[i] != NULL) { + switch (pp_test_item_arr[i]->test_item_id) { + /*----------------------tp open test-----------------------*/ + case TP_RAWDATA_TEST_ITEMS_SET_ID: { + ret = release_rawdata_test_item(( + p_test_proc_data->pp_test_item_arr)[i]); + } break; + + /*----------------------hardware test-----------------------*/ + case TP_SHORT_TEST_ITEM_ID: { + ret = release_short_test_item(( + p_test_proc_data->pp_test_item_arr)[i]); + } break; + + case TP_VERSION_TEST_ITEM_ID: { + ret = version_test_finished_func(( + p_test_proc_data->pp_test_item_arr)[i]); + } break; + + /*----------------------other test-----------------------*/ + case TP_CHIP_CFG_PROC_ITEM_ID: { + ret = release_cfg_test_item(( + p_test_proc_data->pp_test_item_arr)[i]); + } break; + + case TP_RECOVER_CFG_ITEM_ID: { + ret = release_cfg_recover_test_item(( + p_test_proc_data->pp_test_item_arr)[i]); + } break; + + case TP_FLASH_TEST_ITEM_ID: { + ret = release_flash_test_item(( + p_test_proc_data->pp_test_item_arr)[i]); + } break; + default: { + ; + } break; + } + } + } + return ret; +} + +/******************************************************************************* +* Function Name : init_test_proc_data +* Description : initial test proc data +* Input : PST_TEST_PROC_DATA p_test_proc_data + : PST_TEST_PARAM* pp_test_param +* Output : PST_TEST_PROC_DATA p_test_proc_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 init_test_proc_data(PST_TEST_PROC_DATA *pp_test_proc_data, + PST_TEST_PARAM *pp_test_param, void *p_drv_dev) +{ + s32 ret = 1; + u16 i = 0; + PST_TEST_PARAM p_test_param = NULL; + PST_TEST_PROC_DATA p_test_proc_data = NULL; + + /*(1)malloc memory for test proc data*/ + if (alloc_mem_in_heap((void **)pp_test_proc_data, + sizeof(ST_TEST_PROC_DATA)) == 0) { + board_print_error("test proc data malloc memory error!"); + return 0; + } + p_test_proc_data = (PST_TEST_PROC_DATA)(*pp_test_proc_data); + p_test_proc_data->p_dev = NULL; + p_test_proc_data->test_item_num = 0; + p_test_proc_data->test_break_flag = 0; + p_test_proc_data->pp_test_item_arr = NULL; + p_test_proc_data->p_test_items_before_func_ptr = NULL; + p_test_proc_data->p_test_items_finished_func_ptr = NULL; + + /*malloc memory for tp device */ + ret = alloc_mem_in_heap((void **)&p_test_proc_data->p_dev, + sizeof(ST_TP_DEV)); + if (0 == ret) { + board_print_error("tp device malloc memory error!"); + return 0; + } + p_test_proc_data->p_dev->doze_ref_cnt = 1; + p_test_proc_data->p_dev->hid_state = 1; + p_test_proc_data->p_dev->chip_type = TP_NORMANDY; + p_test_proc_data->p_dev->p_logic_dev = p_drv_dev; + + /*(4)parse test param*/ + ret = parse_test_order(pp_test_param, p_test_proc_data->p_dev); + if (ret == 0) { + board_print_error("parse test order error!\n"); + return 0; + } + p_test_param = (PST_TEST_PARAM)(*pp_test_param); + + /*(7)init test param*/ + p_test_proc_data->test_item_num = p_test_param->test_item_num; + ret = alloc_mem_in_heap((void **)&(p_test_proc_data->pp_test_item_arr), + p_test_proc_data->test_item_num * + sizeof(PST_TEST_ITEM)); + if (0 == ret) { + board_print_error("pp_test_item_arr malloc error!\n"); + return ret; + } + /*alloc memory for each varibale*/ + for (i = 0; i < p_test_proc_data->test_item_num; i++) { + ret = alloc_mem_in_heap( + (void **)(&(p_test_proc_data->pp_test_item_arr[i])), + sizeof(ST_TEST_ITEM)); + if (0 == ret) { + return ret; + } + /*init pointer in test item struct*/ + (p_test_proc_data->pp_test_item_arr)[i]->test_item_id = + p_test_param->p_test_item_id_set[i].test_id; + (p_test_proc_data->pp_test_item_arr)[i]->p_sub_id_set = + p_test_param->p_test_item_id_set[i].p_sub_id_set; + (p_test_proc_data->pp_test_item_arr)[i]->p_tp_dev = + p_test_proc_data->p_dev; + (p_test_proc_data->pp_test_item_arr)[i]->cur_data.ptr_cur_data = + NULL; + (p_test_proc_data->pp_test_item_arr)[i]->param.ptr_param = NULL; + (p_test_proc_data->pp_test_item_arr)[i]->test_res.ptr_res = + NULL; + (p_test_proc_data->pp_test_item_arr)[i]->ptr_general_func = + NULL; + (p_test_proc_data->pp_test_item_arr)[i] + ->ptr_test_item_before_func = NULL; + (p_test_proc_data->pp_test_item_arr)[i] + ->ptr_test_item_before_func_param = NULL; + (p_test_proc_data->pp_test_item_arr)[i]->ptr_test_func = NULL; + (p_test_proc_data->pp_test_item_arr)[i] + ->ptr_test_item_finished_func = NULL; + (p_test_proc_data->pp_test_item_arr)[i] + ->ptr_test_item_finished_func_param = NULL; + (p_test_proc_data->pp_test_item_arr)[i]->ptr_test_proc_data = + p_test_proc_data; + (p_test_proc_data->pp_test_item_arr)[i] + ->ptr_special_callback_data = NULL; + } + + /*register test item function*/ + ret = register_test_item_func(p_test_proc_data); + + /*register test item finish func(print test result)*/ + ret = register_test_item_finished_func(p_test_proc_data); + + /*init test item*/ + ret = init_test_item(p_test_proc_data, p_test_param); + if (ret == 0) { + board_print_error("init test item error!\n"); + return ret; + } + /*sort test item*/ + ret = sort_item_permutation(p_test_proc_data); + for (i = 0; i < p_test_proc_data->test_item_num; i++) { + board_print_debug( + "test seq:%d\n", + (p_test_proc_data->pp_test_item_arr)[i]->test_item_id); + } + + return ret; +} + +/******************************************************************************* +* Function Name : release_test_proc_data +* Description : release test proc data ,this function will be called + after changing test parameter +* Input : PST_TEST_PROC_DATA* pp_test_proc_data +* Output : PST_TEST_PROC_DATA* pp_test_proc_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 release_test_proc_data(PST_TEST_PROC_DATA *pp_test_proc_data) +{ + s32 ret = 1; + u16 i = 0; + + PST_TEST_PROC_DATA p_test_proc_data = NULL; + if ((pp_test_proc_data == NULL) || ((*pp_test_proc_data) == NULL)) { + return 1; + } + + p_test_proc_data = (*pp_test_proc_data); + ret = release_test_item(p_test_proc_data); + if (NULL != p_test_proc_data->p_dev) { + if (p_test_proc_data->p_dev->chip_type != 0xffff) { + if (p_test_proc_data->p_dev->chip_type == TP_PHOENIX) { + ret = chip_reg_write( + p_test_proc_data->p_dev, + p_test_proc_data->p_dev->cmd_set + .hid_ena_cmd.addr, + p_test_proc_data->p_dev->cmd_set + .hid_ena_cmd.cmd_buf, + p_test_proc_data->p_dev->cmd_set + .hid_ena_cmd.cmd_len); + } + } + p_test_proc_data->p_dev->p_logic_dev = NULL; + ret = free_mem_in_heap(p_test_proc_data->p_dev); + p_test_proc_data->p_dev = NULL; + } + + if (NULL != p_test_proc_data->pp_test_item_arr) { + for (i = 0; i < p_test_proc_data->test_item_num; i++) { + ret = free_mem_in_heap( + p_test_proc_data->pp_test_item_arr[i]); + p_test_proc_data->pp_test_item_arr[i] = NULL; + } + ret = free_mem_in_heap(p_test_proc_data->pp_test_item_arr); + p_test_proc_data->pp_test_item_arr = NULL; + } + ret = free_mem_in_heap(p_test_proc_data); + p_test_proc_data = NULL; + + return ret; +} + +/* test */ +/******************************************************************************* +* Function Name : test_process +* Description : test process +* Input : void* p_drv_dev +* Output : none +* Return : s32(-1:fail other:test finish) +*******************************************************************************/ +extern s32 test_process(void *p_drv_dev) +{ + s32 ret = 0; + PST_TEST_PARAM p_test_param = NULL; + PST_TEST_PROC_DATA p_test_proc_data = NULL; + + init_test_res(); /* init result as 0 before start test*/ + + /*(1)parse test order and init test proc data*/ + board_print_debug("init test proc data!\n"); + ret = init_test_proc_data(&p_test_proc_data, &p_test_param, p_drv_dev); + if (ret == 0) { + goto TEST_EXIT; + } + /*(2)start test*/ + board_print_debug("start test!\n"); + start_test_interface(p_test_proc_data); + /*(4)set test status*/ + board_print_debug("release test proc data!\n"); + ret &= stop_test_interface(p_test_proc_data); + if (get_detail_info_flag() == 0) { + } + +TEST_EXIT: + /*(5)release test proc data*/ + ret &= release_test_proc_data(&p_test_proc_data); + /*(6)release test param*/ + ret &= release_test_param(&p_test_param); + + /*(7)modify return value*/ + if (ret == 0) { + return (s32)(-1); + } + ret = get_test_res(); + board_print_debug("test_result is:%d\n", ret); + if (ret & TEST_ABORT) { + return (s32)(-1); + } + return ret; +} + +/* test*/ +/******************************************************************************* +* Function Name : get_tp_rawdata +* Description : get_tp_rawdata +* Input : void* p_drv_dev +* Output : none +* Return : s32(-1:fail other:test finish) +*******************************************************************************/ +extern int get_tp_rawdata(void *p_drv_dev, char *buf, int *buf_size) +{ + s32 ret = 0; + int offset = 0; + int r = 0, i = 0; + s32 data_tmp = 0; + u16 node_num = 0; + u8 data_size = 0; + u8 rawdata_test_id = 0; + PST_TEST_PARAM p_test_param = NULL; + PST_TEST_PROC_DATA p_test_proc_data = NULL; + PST_CUR_RAWDATA p_cur_data = NULL; + /*(1)parse test order and init test proc data*/ + board_print_debug("init get rawdata proc!\n"); + ret = init_test_proc_data(&p_test_proc_data, &p_test_param, p_drv_dev); + if (ret == 0) { + goto TEST_EXIT; + } + /*find the rawdata_test_item id for get_rawdata */ + for (i = 0; i < p_test_proc_data->test_item_num; i++) { + if (p_test_proc_data->pp_test_item_arr[i]->test_item_id == + TP_RAWDATA_TEST_ITEMS_SET_ID) { + rawdata_test_id = i; + break; + } + } + if (i == p_test_proc_data->test_item_num) { + goto TEST_EXIT; + } + node_num = p_test_proc_data->p_dev->sc_sen_num * + p_test_proc_data->p_dev->sc_drv_num; + data_size = get_data_size(p_test_proc_data->p_dev->rawdata_option); + board_print_debug("[%s]node_num = %d,data_size = %d\n", __func__, + node_num, data_size); + + if (!alloc_mem_block((void **)&(p_cur_data), sizeof(p_cur_data))) { + goto TEST_EXIT; + } + if (alloc_mem_block((void **)&(p_cur_data->p_data_buf), + node_num * data_size)) { + /*init_for_buffer*/ + for (i = 0; i < node_num * data_size; i++) { + p_cur_data->p_data_buf[i] = 0; + } + } + ret = chip_mode_select( + (p_test_proc_data->pp_test_item_arr)[rawdata_test_id]->p_tp_dev, + CHIP_RAW_DATA_MODE); + board_get_rawdata( + (p_test_proc_data->pp_test_item_arr)[rawdata_test_id]->p_tp_dev, + 3000, 0, p_cur_data); + + r = snprintf(&buf[offset], 20, "Tx:%d Rx:%d\n", + p_test_proc_data->p_dev->sc_drv_num, + p_test_proc_data->p_dev->sc_sen_num); + offset += r; + r = snprintf(&buf[offset], 2, "\n"); + offset += r; + /*end print test cfg */ + r = snprintf(&buf[offset], 20, "Rawdata:\n"); + offset += r; + board_print_debug("[%s]r = %d\n", __func__, r); + for (i = 0; i < node_num; i++) { + data_tmp = (s16)((p_cur_data->p_data_buf[i * 2]) + + (p_cur_data->p_data_buf[i * 2 + 1] << 8)); + r = snprintf(&buf[offset], 10, "%4d,", data_tmp); + offset += r; + if (((i + 1) % (p_test_proc_data->p_dev->sc_drv_num)) == 0) { + r = snprintf(&buf[offset], 2, "\n"); + offset += r; + } + } + *buf_size = offset; + ret = chip_mode_select( + (p_test_proc_data->pp_test_item_arr)[rawdata_test_id]->p_tp_dev, + CHIP_COORD_MODE); + /*get diff data end*/ + + ret &= free_mem_block((void *)p_cur_data->p_data_buf); + p_cur_data->p_data_buf = NULL; +TEST_EXIT: + ret &= free_mem_block((void *)p_cur_data); + p_cur_data = NULL; + /*(5)release test proc data*/ + ret &= release_test_proc_data(&p_test_proc_data); + /*(6)release test order*/ + ret &= release_test_param(&p_test_param); + /*(7)modify return value*/ + return offset; +} + +/* test*/ +/******************************************************************************* +* Function Name : get_tp_rawdata +* Description : get_tp_rawdata +* Input : void* p_drv_dev +* Output : none +* Return : s32(-1:fail other:test finish) +*******************************************************************************/ +extern int get_tp_testcfg(void *p_drv_dev, char *buf, int *buf_size) +{ + s32 ret = 0; + int offset = 0; + int r = 0, i = 0; + PST_TEST_PARAM p_test_param = NULL; + PST_TEST_PROC_DATA p_test_proc_data = NULL; + + /*(1)parse test order and init test proc data*/ + board_print_debug("init get rawdata proc!\n"); + ret = init_test_proc_data(&p_test_proc_data, &p_test_param, p_drv_dev); + if (ret == 0) { + goto TEST_EXIT; + } + + offset += r; + /*print test cfg */ + r = snprintf(&buf[offset], 20, "Test-config:\n"); + offset += r; + for (i = 0; i < p_test_param->cfg_len; i++) { + r = snprintf(&buf[offset], 10, "0x%2x,", + p_test_param->test_cfg[i]); + offset += r; + if ((i + 1) % 30 == 0) { + r = snprintf(&buf[offset], 2, "\n"); + offset += r; + } + } + r = snprintf(&buf[offset], 2, "\n"); + offset += r; + /*end print test cfg */ +TEST_EXIT: + /*(5)release test proc data*/ + ret &= release_test_proc_data(&p_test_proc_data); + /*(6)release test order*/ + ret &= release_test_param(&p_test_param); + /*(7)modify return value*/ + + return offset; +} + +#ifdef __cplusplus +} +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_param_init.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_param_init.h new file mode 100644 index 000000000000..8e479c41272e --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_param_init.h @@ -0,0 +1,43 @@ +/******************** (C) COPYRIGHT 2017 Goodix ******************** +* File Name : test_param_init.h +* Author : Zhitao Yang +* Version : V1.0.0 +* Date : 12/29/2017 +* Description : initial test data +*******************************************************************************/ + +#ifndef TEST_PARAM_INIT_H +#define TEST_PARAM_INIT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tp_dev_def.h" +#include "test_item_def.h" +#include "test_order.h" + +/*************************************Public methods start********************************************/ +/*init test item*/ +extern s32 init_test_item(PST_TEST_PROC_DATA p_test_proc_data, + PST_TEST_PARAM p_test_param); +extern s32 release_test_item(PST_TEST_PROC_DATA p_test_proc_data); + +/*register callback function*/ +extern s32 +register_test_item_finished_func(PST_TEST_PROC_DATA p_test_proc_data); + +/*init proc data*/ +extern s32 init_test_proc_data(PST_TEST_PROC_DATA *pp_test_proc_data, + PST_TEST_PARAM *pp_test_param, void *p_drv_dev); +extern s32 release_test_proc_data(PST_TEST_PROC_DATA *pp_test_proc_data); + +/*test process*/ +extern s32 test_process(void *p_drv_dev); +extern int get_tp_rawdata(void *p_drv_dev, char *buf, int *buf_size); +extern int get_tp_testcfg(void *p_drv_dev, char *buf, int *buf_size); +/*************************************Public methods end********************************************/ +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_proc.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_proc.c new file mode 100644 index 000000000000..2cfb700a3897 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_proc.c @@ -0,0 +1,260 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : test_proc.c +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : structs in this file also exist in pc,it is an interface + of test item +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#include "test_proc.h" + +#include "tp_open_test.h" +#include "tp_short_test.h" +#include "tp_version_test.h" +#include "tp_additional_option.h" +#include "simple_mem_manager.h" +#include "tp_test_general_error_code_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* +* Function Name : get_arr_id_from_sub_item +* Description : get array index from sub test item array +* Input : PST_TEST_ITEM p_test_item +* Output : none +* Return : s32(array id) +*******************************************************************************/ +extern s32 get_arr_id_from_sub_item(IN PST_TEST_ITEM p_test_item, + IN u8 sub_item_id) +{ + s32 ret = 0xFF; + u8 i = 0; + PST_SUB_TEST_ITEM_ID_SET p_sub_id_set = NULL; + p_sub_id_set = p_test_item->p_sub_id_set; + for (i = 0; i < p_sub_id_set->len; i++) { + if (p_sub_id_set->p_id_set[i] == sub_item_id) { + ret = i; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : test_proc_func +* Description : test process functiton +* Input : PST_TEST_PROC_DATA p_test_proc_data +* Output : PST_TEST_PROC_DATA p_test_proc_data +* Return : s32(0:fail 1:ok) If all functions in test_proc_func excuting ok + then the return value is 1 +*******************************************************************************/ +extern s32 test_proc_func(IN_OUT PST_TEST_PROC_DATA p_test_proc_data) +{ + u16 i = 0; + s32 res = 1; + /*off line run*/ + p_test_proc_data->test_proc_status = TEST_START; + if (NULL != p_test_proc_data->p_test_items_before_func_ptr) { + res &= p_test_proc_data->p_test_items_before_func_ptr( + p_test_proc_data->p_test_items_before_func_ptr_param); + } + /*(2)run all test items*/ + p_test_proc_data->test_proc_status = TEST_DOING; + for (i = 0; i < p_test_proc_data->test_item_num; i++) { + if (1 == p_test_proc_data->test_break_flag) { + p_test_proc_data->test_proc_status = TEST_ABORTED; + break; + } + if (NULL != p_test_proc_data->pp_test_item_arr[i] && + NULL != p_test_proc_data->pp_test_item_arr[i] + ->ptr_test_func) { + res &= p_test_proc_data->pp_test_item_arr[i] + ->ptr_test_func( + p_test_proc_data + ->pp_test_item_arr[i]); + } + } + if (1 == p_test_proc_data->test_break_flag) { + p_test_proc_data->test_proc_status = TEST_ABORTED; + } + + if (NULL != p_test_proc_data->p_test_items_finished_func_ptr) { + res &= p_test_proc_data->p_test_items_finished_func_ptr( + p_test_proc_data->p_test_items_finished_func_ptr_param); + } + p_test_proc_data->test_proc_status = TEST_FINISH; + return res; +} + +/******************************************************************************* +* Function Name : register_test_item_func +* Description : register test function.you must modify this function,while you + add some tes functions. +* Input : PST_TEST_PROC_DATA p_test_proc_data +* Output : PST_TEST_PROC_DATA p_test_proc_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 register_test_item_func(IN_OUT PST_TEST_PROC_DATA p_test_proc_data) +{ + s32 ret = 1; + u16 i = 0; + PST_TEST_ITEM *pp_test_item_arr = p_test_proc_data->pp_test_item_arr; + u16 item_num = p_test_proc_data->test_item_num; + + for (i = 0; i < item_num; i++) { + switch (pp_test_item_arr[i]->test_item_id) { + /*----------------------tp open test-----------------------*/ + case TP_RAWDATA_TEST_ITEMS_SET_ID: { + pp_test_item_arr[i]->ptr_test_func = + rawdata_test_sets_func; + } break; + + /*----------------------hardware test-----------------------*/ + case TP_SHORT_TEST_ITEM_ID: { + pp_test_item_arr[i]->ptr_test_func = short_test_func; + } break; + + /*----------------------firmware test-----------------------*/ + case TP_VERSION_TEST_ITEM_ID: { + pp_test_item_arr[i]->ptr_test_func = fw_version_test; + } break; + + /*----------------------other test-----------------------*/ + case TP_CHIP_CFG_PROC_ITEM_ID: { + pp_test_item_arr[i]->ptr_test_func = tp_chip_cfg_proc; + } break; + case TP_FLASH_TEST_ITEM_ID: { + pp_test_item_arr[i]->ptr_test_func = tp_flash_test; + } break; + + case TP_RECOVER_CFG_ITEM_ID: { + pp_test_item_arr[i]->ptr_test_func = + tp_recover_cfg_to_chip; + } break; + + default: { + pp_test_item_arr[i]->ptr_test_func = NULL; + } break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : get_test_item_from_proc_data +* Description : get test item from test proce data +* Input : PST_TEST_PROC_DATA p_test_proc_data +* Input : u16 test_item_id +* Output : PST_TEST_ITEM* pp_test_item +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 get_test_item_from_proc_data(IN PST_TEST_PROC_DATA p_test_proc_data, + IN u16 test_item_id, + OUT PST_TEST_ITEM *pp_test_item) +{ + u16 i = 0; + s32 ret = 0; + PST_TEST_ITEM *pp_test_item_arr = p_test_proc_data->pp_test_item_arr; + u16 item_num = p_test_proc_data->test_item_num; + + for (i = 0; i < item_num; i++) { + if (pp_test_item_arr[i]->test_item_id == test_item_id) { + *pp_test_item = pp_test_item_arr[i]; + ret = 1; + break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : test_before_func_fail_proc +* Description : test_before_func_fail_proc +* Input : P_TEST_ITEM_RES p_test_res_head +* Output : P_TEST_ITEM_RES p_test_res_head +* Return : none +*******************************************************************************/ +extern void test_before_func_fail_proc(IN_OUT P_TEST_ITEM_RES p_test_res_head) +{ + if (p_test_res_head->test_item_err_code.len >= 1) { + p_test_res_head->test_item_err_code.ptr_err_code_set[0] = + TEST_BEFORE_FUNC_FAIL; + } + p_test_res_head->test_status = TEST_ABORTED; + p_test_res_head->test_result = TEST_NG; + board_print_error("p_test_item->ptr_test_item_before_func fail\n"); +} + +/******************************************************************************* +* Function Name : 0 == judge_test_item_legal +* Description : 0 == judge_test_item_legal +* Input : PST_TEST_ITEM p_test_item +* Output : none +* Return : 1:OK 0:Fail +*******************************************************************************/ +extern s32 judge_test_item_legal(PST_TEST_ITEM p_test_item) +{ + s32 ret = 1; + + /*-----------------Judge parameter----------------*/ + if (NULL == p_test_item || NULL == p_test_item->param.ptr_param || + NULL == p_test_item->test_res.ptr_res || + NULL == p_test_item->p_tp_dev || + NULL == p_test_item->ptr_test_proc_data) { + ret = 0; + } + return ret; +} + +/******************************************************************************* +* Function Name : start_test_interface +* Description : start test interface +* Input : ptr32 p_data(must cast to 'PST_TEST_PROC_DATA') +* Output : ptr32 p_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 start_test_interface(IN_OUT ptr32 ptr) +{ + s32 ret = 1; + ret = test_proc_func((PST_TEST_PROC_DATA)ptr); + return ret; +} + +/******************************************************************************* +* Function Name : stop_test_interface +* Description : stop test interface +* Input : ptr32 p_data(must cast to 'PST_TEST_PROC_DATA') +* Output : ptr32 p_data +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 stop_test_interface(IN_OUT ptr32 ptr) +{ + s32 ret = 1; + u16 i = 0; + PST_TEST_PROC_DATA p_test_proc_data = (PST_TEST_PROC_DATA)ptr; + P_TEST_ITEM_RES p_test_res_header = NULL; + p_test_proc_data->test_proc_status = TEST_ABORTED; + + /*set all test item */ + for (i = 0; i < p_test_proc_data->test_item_num; i++) { + if ((NULL != p_test_proc_data->pp_test_item_arr[i]) && + (NULL != (p_test_proc_data->pp_test_item_arr[i]) + ->test_res.ptr_res)) { + p_test_res_header = + (P_TEST_ITEM_RES)(p_test_proc_data + ->pp_test_item_arr[i]) + ->test_res.ptr_res; + p_test_res_header->test_status = TEST_ABORTED; + } + } + return ret; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_proc.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_proc.h new file mode 100644 index 000000000000..fd50d756f7e7 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/test_proc.h @@ -0,0 +1,41 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : test_proc.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : structs in this file also exist in pc,it is an interface + of test item +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef TEST_PROC_H +#define TEST_PROC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "test_item_def.h" +/*get array index from sub test item array*/ +extern s32 get_arr_id_from_sub_item(PST_TEST_ITEM p_test_item, u8 sub_item_id); +/*test proc func*/ +extern s32 test_proc_func(PST_TEST_PROC_DATA p_test_proc_data); +extern s32 get_test_item_by_another_item(u16 item_id, + PST_TEST_ITEM p_src_test_item, + PST_TEST_ITEM *pp_des_test_item); +extern s32 register_test_item_func(PST_TEST_PROC_DATA p_test_proc_data); +extern s32 get_test_item_from_proc_data(PST_TEST_PROC_DATA p_test_proc_data, + u16 test_item_id, + PST_TEST_ITEM *pp_test_item); + +extern void test_before_func_fail_proc(P_TEST_ITEM_RES p_test_res_head); +extern s32 judge_test_item_legal(PST_TEST_ITEM p_test_item); +/*start test interface*/ +extern s32 start_test_interface(ptr32 ptr); +/*stop test interface*/ +extern s32 stop_test_interface(ptr32 ptr); +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_additional_option.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_additional_option.c new file mode 100644 index 000000000000..806191b9da84 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_additional_option.c @@ -0,0 +1,392 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_additional_option.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 10/26/2017 +* Description : this file offer some functions which are called close to test end +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#include "tp_additional_option.h" +#include "tp_dev_control.h" +#include "simple_mem_manager.h" +#include "tp_version_test.h" +#include "test_proc.h" +#include "tp_test_general_error_code_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* +* Function Name : tp_send_cfg_to_chip +* Description : tp_send_cfg_to_chip +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 tp_chip_cfg_proc(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + u16 i = 0; + PST_CHIP_CONFIG_PROC_PARAM p_param = NULL; + PST_CHIP_CONFIG_PROC_RES p_test_res = NULL; + PST_TP_DEV p_dev = NULL; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + + /*-----------------Judge parameter----------------*/ + if (0 == judge_test_item_legal((PST_TEST_ITEM)p_data)) { + ret = 0; + goto SEN_CFG_END; + } + + p_param = (PST_CHIP_CONFIG_PROC_PARAM)p_test_item->param.ptr_param; + p_test_res = (PST_CHIP_CONFIG_PROC_RES)p_test_item->test_res.ptr_res; + p_dev = p_test_item->p_tp_dev; + + if (NULL != p_test_item->ptr_test_item_before_func) { + ret &= p_test_item->ptr_test_item_before_func( + p_test_item->ptr_test_item_before_func_param); + if (0 == ret) { + test_before_func_fail_proc( + &p_test_res->item_res_header); + goto SEN_CFG_END; + } + } + + p_test_res->item_res_header.test_item_err_code.ptr_err_code_set[0] = + CFG_CHECK_TEST_NONE_ERROR; + p_test_res->item_res_header.test_status = TEST_START; + p_test_res->item_res_header.test_result = TEST_OK; + /*clear config in res*/ + for (i = 0; i < p_test_res->cfg_len; i++) { + p_test_res->p_read_cfg[i] = 0x00; + } + + if (p_param->option == CHIP_CFG_SEND) { + /*write cfg*/ + ret &= force_update_cfg(p_dev, p_param->config, + p_param->cfg_len); + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = + CFG_CHECK_TEST_UPDATE_FAIL; + p_test_res->item_res_header.test_result = TEST_NG; + board_print_error( + "[send config test]update config error!\n"); + goto SEN_CFG_END; + } + } + /*read cfg*/ + if (read_cfg_arr(p_dev, p_test_res->p_read_cfg, p_test_res->cfg_len) == + 0) { + ret = 0; + } else { + ret &= 1; + } + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = CFG_CHECK_TEST_READ_FAIL; + p_test_res->item_res_header.test_result = TEST_NG; + p_test_res->item_res_header.test_status = TEST_ABORTED; + board_print_error("[send config test]read config error!\n"); + goto SEN_CFG_END; + } + p_test_res->item_res_header.test_status = TEST_FINISH; +SEN_CFG_END: + if (p_test_item->ptr_test_item_finished_func) { + ret &= p_test_item->ptr_test_item_finished_func( + p_test_item->ptr_test_item_finished_func_param); + } + return ret; +} + +/******************************************************************************* +* Function Name : tp_send_spec_cfg_to_chip +* Description : tp send spec cfg to chip +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:error 1:Ok) +*******************************************************************************/ +extern s32 tp_send_spec_cfg_to_chip(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + u16 i = 0; + PST_SPEC_CONFIG_PARAM p_param = NULL; + PST_SEND_SPEC_CONFIG_RES p_test_res = NULL; + PST_TP_DEV p_dev = NULL; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + + /*-----------------Judge parameter----------------*/ + if (0 == judge_test_item_legal((PST_TEST_ITEM)p_data)) { + ret = 0; + goto SEN_SPC_CFG_END; + } + + p_param = (PST_SPEC_CONFIG_PARAM)p_test_item->param.ptr_param; + p_test_res = (PST_SEND_SPEC_CONFIG_RES)p_test_item->test_res.ptr_res; + p_dev = p_test_item->p_tp_dev; + + if (NULL != p_test_item->ptr_test_item_before_func) { + ret &= p_test_item->ptr_test_item_before_func( + p_test_item->ptr_test_item_before_func_param); + if (0 == ret) { + test_before_func_fail_proc( + &p_test_res->item_res_header); + goto SEN_SPC_CFG_END; + } + } + + p_test_res->item_res_header.test_item_err_code.ptr_err_code_set[0] = + SPEC_CONFIG_ERROR_CODE_NONE; + p_test_res->item_res_header.test_status = TEST_START; + p_test_res->item_res_header.test_result = TEST_OK; + /*clear config in res*/ + for (i = 0; i < p_test_res->read_cfg_len; i++) { + p_test_res->read_config[i] = 0x00; + } + + if (1 > p_test_res->read_cfg_len) { + ret = 0; + goto SEN_SPC_CFG_END; + } + /*write config to chip*/ + ret &= force_update_cfg(p_dev, p_param->config, p_param->cfg_len); + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = SPEC_CONFIG_UPDATE_FAIL; + p_test_res->item_res_header.test_result = TEST_NG; + p_test_res->item_res_header.test_status = TEST_ABORTED; + board_print_error( + "[send special config]update config error!\n"); + goto SEN_SPC_CFG_END; + } + /*read config from chip*/ + if (read_cfg_arr(p_dev, p_test_res->read_config, + p_test_res->read_cfg_len) == 0) { + ret = 0; + } else { + ret &= 1; + } + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = SPEC_CONFIG_READ_FAIL; + p_test_res->item_res_header.test_result = TEST_NG; + p_test_res->item_res_header.test_status = TEST_ABORTED; + board_print_error("[send special config]read config error!\n"); + goto SEN_SPC_CFG_END; + } + /*check cfg*/ + ret &= cmp_cfg(p_dev, p_test_res->read_config, p_param->config, + p_param->cfg_len); + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = SPEC_CONFIG_CHECK_FAIL; + p_test_res->item_res_header.test_result = TEST_NG; + ret = 1; + board_print_info( + "[send special config]cfg is not equal with chip config!\n"); + } + p_test_res->item_res_header.test_status = TEST_FINISH; + +SEN_SPC_CFG_END: + if (p_test_item->ptr_test_item_finished_func) { + ret &= p_test_item->ptr_test_item_finished_func( + p_test_item->ptr_test_item_finished_func_param); + } + return ret; +} + +/******************************************************************************* +* Function Name : tp_flash_test +* Description : tp_flash_test +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:error 1:Ok) +*******************************************************************************/ +extern s32 tp_flash_test(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + u16 i = 0; + PST_FLASH_TEST_PARAM p_param = NULL; + PST_FLASH_TEST_RES p_test_res = NULL; + PST_TP_DEV p_dev = NULL; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + + /*-----------------Judge parameter----------------*/ + if (0 == judge_test_item_legal((PST_TEST_ITEM)p_data)) { + ret = 0; + goto FLASH_TEST_END; + } + + p_param = (PST_FLASH_TEST_PARAM)p_test_item->param.ptr_param; + p_test_res = (PST_FLASH_TEST_RES)p_test_item->test_res.ptr_res; + p_dev = p_test_item->p_tp_dev; + + if (NULL != p_test_item->ptr_test_item_before_func) { + ret &= p_test_item->ptr_test_item_before_func( + p_test_item->ptr_test_item_before_func_param); + if (0 == ret) { + test_before_func_fail_proc( + &p_test_res->item_res_header); + goto FLASH_TEST_END; + } + } + + p_test_res->item_res_header.test_item_err_code.ptr_err_code_set[0] = + FLASH_TEST_ERROR_CODE_NONE; + p_test_res->item_res_header.test_status = TEST_START; + p_test_res->item_res_header.test_result = TEST_OK; + /*clear config in res*/ + for (i = 0; i < p_test_res->cfg_len; i++) { + p_test_res->config_arr[i] = 0x00; + } + + /*Write cfg to ram*/ + if ((p_param->option & FLASH_TEST_SEND_CFG_OPT) == + FLASH_TEST_SEND_CFG_OPT) { + /*write cfg*/ + ret &= force_update_cfg(p_dev, p_param->config_arr, + p_param->cfg_len); + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = + FLASH_TEST_CFG_WRITE_ERROR; + p_test_res->item_res_header.test_result = TEST_NG; + board_print_error("[flash test]update config error!\n"); + goto FLASH_TEST_END; + } + } + /*wait firmware transfer config to flash from ram*/ + if ((p_param->option & FLASH_TEST_DEFAULT_DELAY) == + FLASH_TEST_DEFAULT_DELAY) { + cfg_to_flash_delay(p_dev); + } else { + board_delay_ms(p_param->delay_time); + } + + /*Reset chip and wait firmware initialization*/ + ret &= reset_chip_proc(p_dev, RESET_TO_AP); + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = FLASH_TEST_RST_FAIL_ERROR; + p_test_res->item_res_header.test_result = TEST_NG; + p_test_res->item_res_header.test_status = TEST_ABORTED; + goto FLASH_TEST_END; + } + /*read cfg*/ + if (read_cfg_arr(p_dev, p_test_res->config_arr, p_test_res->cfg_len) == + 0) { + ret = 0; + } else { + ret &= 1; + } + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = FLASH_TEST_CFG_READ_ERROR; + p_test_res->item_res_header.test_result = TEST_NG; + p_test_res->item_res_header.test_status = TEST_ABORTED; + board_print_error("[flash test]read config error!\n"); + goto FLASH_TEST_END; + } + p_test_res->item_res_header.test_status = TEST_FINISH; + +FLASH_TEST_END: + if (p_test_item->ptr_test_item_finished_func) { + ret &= p_test_item->ptr_test_item_finished_func( + p_test_item->ptr_test_item_finished_func_param); + } + return ret; +} + +/******************************************************************************* +* Function Name : tp_recover_cfg_to_chip +* Description : tp_recover_cfg_to_chip +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:error 1:Ok) +*******************************************************************************/ +extern s32 tp_recover_cfg_to_chip(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + PST_RECOVER_CHIP_CFG_PARAM p_param = NULL; + PST_RECOVER_CHIP_CFG_RES p_test_res = NULL; + PST_TP_DEV p_dev = NULL; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + + /*-----------------Judge parameter----------------*/ + if (0 == judge_test_item_legal((PST_TEST_ITEM)p_data)) { + ret = 0; + goto RECOVER_CFG_END; + } + + p_param = (PST_RECOVER_CHIP_CFG_PARAM)p_test_item->param.ptr_param; + p_test_res = (PST_RECOVER_CHIP_CFG_RES)p_test_item->test_res.ptr_res; + p_dev = p_test_item->p_tp_dev; + + if (NULL != p_test_item->ptr_test_item_before_func) { + ret &= p_test_item->ptr_test_item_before_func( + p_test_item->ptr_test_item_before_func_param); + if (0 == ret) { + test_before_func_fail_proc( + &p_test_res->item_res_header); + goto RECOVER_CFG_END; + } + } + + p_test_res->item_res_header.test_item_err_code.ptr_err_code_set[0] = + RECOVER_CFG_ERROR_CODE_NONE; + p_test_res->item_res_header.test_status = TEST_START; + p_test_res->item_res_header.test_result = TEST_OK; + + /*Write cfg to ram*/ + ret &= force_update_cfg(p_dev, p_param->config_arr, p_param->cfg_len); + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = RECOVER_CFG_CFG_WRITE_ERROR; + p_test_res->item_res_header.test_result = TEST_NG; + board_print_error( + "[recover config test]update config error!\n"); + goto RECOVER_CFG_END; + } + /*read cfg*/ + if (read_cfg_arr(p_dev, p_test_res->config_arr, p_test_res->cfg_len) == + 0) { + ret = 0; + } else { + ret &= 1; + } + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = RECOVER_CFG_CFG_READ_ERROR; + p_test_res->item_res_header.test_result = TEST_NG; + p_test_res->item_res_header.test_status = TEST_ABORTED; + board_print_error("[recover config test]read config error!\n"); + goto RECOVER_CFG_END; + } + /*check cfg*/ + ret &= cmp_cfg(p_dev, p_test_res->config_arr, p_param->config_arr, + p_param->cfg_len); + if (0 == ret) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = RECOVER_CFG_CMP_ERROR; + p_test_res->item_res_header.test_result = TEST_NG; + ret = 1; + board_print_info( + "[recover config test]cfg is not equal with chip config!\n"); + } + p_test_res->item_res_header.test_status = TEST_FINISH; + +RECOVER_CFG_END: + if (p_test_item->ptr_test_item_finished_func) { + ret &= p_test_item->ptr_test_item_finished_func( + p_test_item->ptr_test_item_finished_func_param); + } + return ret; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_additional_option.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_additional_option.h new file mode 100644 index 000000000000..11fbe427c111 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_additional_option.h @@ -0,0 +1,186 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_additional_option.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 10/26/2017 +* Description : this file offer some functions which are called close to test end +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef TP_ADDITIONAL_OPTION_H +#define TP_ADDITIONAL_OPTION_H + +#include "board_opr_interface.h" +#include "tp_additional_option_param.h" + +#ifdef __cplusplus +extern "C" { +#endif +/******************************chip config proc*********************************/ + +#define CFG_CHECK_TEST_NONE_ERROR 0x00 +#define CFG_CHECK_TEST_UPDATE_FAIL 0x01 +#define CFG_CHECK_TEST_READ_FAIL 0x02 +#define CFG_CHECK_TEST_CHECK_FAIL 0x03 +#define CFG_SET_CHIP_COORD_MODE_FAIL 0x04 + +/*send config result*/ +typedef struct CHIP_CONFIG_PROC_RES { + ST_TEST_ITEM_RES item_res_header; + u16 cfg_len; + u8 *p_read_cfg; +} ST_CHIP_CONFIG_PROC_RES, *PST_CHIP_CONFIG_PROC_RES; + +extern s32 tp_chip_cfg_proc(ptr32 p_data); + +/*************send spec config test error code**************/ +#define SPEC_CONFIG_ERROR_CODE_NONE 0x00 +#define SPEC_CONFIG_UPDATE_FAIL 0x01 +#define SPEC_CONFIG_READ_FAIL 0x02 +#define SPEC_CONFIG_CHECK_FAIL 0x03 +/*send special config result*/ +typedef struct SEND_SPEC_CONFIG_RES { + ST_TEST_ITEM_RES item_res_header; + u16 read_cfg_len; + u8 *read_config; +} ST_SEND_SPEC_CONFIG_RES, *PST_SEND_SPEC_CONFIG_RES; + +/*************send spec config test error code**************/ + +extern s32 tp_send_spec_cfg_to_chip(ptr32 p_data); + +/**********************************flash test***********************************/ +/*flash test (TP_FLASH_TEST_ITEM_ID)*/ + +/*------------Error Code-------------*/ +#define FLASH_TEST_ERROR_CODE_NONE 0 /*test ok*/ +#define FLASH_TEST_CFG_WRITE_ERROR 1 +#define FLASH_TEST_CFG_READ_ERROR 2 +#define FLASH_TEST_RST_FAIL_ERROR 3 +#define FLASH_TEST_CMP_ERROR 4 + +/*flash test result*/ +typedef struct FLASH_TEST_RES { + ST_TEST_ITEM_RES item_res_header; + u16 cfg_len; + u8 *config_arr; +} ST_FLASH_TEST_RES, *PST_FLASH_TEST_RES; + +extern s32 tp_flash_test(ptr32 p_data); + +/**********************************update special firmware***********************************/ +/*//update special firmware(TP_UPDATE_SPEC_FW_ITEM_ID) +//------------------Error Code--------------------//*/ +#define UPDATE_SPEC_FW_ERROR_NONE 0x00 +#define UPDATE_SPEC_FW_FAIL 0x01 + +/*flash test result*/ +typedef struct UPDATE_SPEC_FW_RES { + ST_TEST_ITEM_RES item_res_header; +} ST_UPDATE_SPEC_FW_RES, *PST_UPDATE_SPEC_FW_RES; + +extern s32 tp_update_spec_fw(ptr32 p_data); + +/**********************************custom information************************************/ +/*custom information(TP_CUSTOM_INFO_TEST_ITEM_ID)*/ + +/*--------------------Error Code----------------------*/ +#define CUSTOM_INFO_NONE_ERROR 0x00 +#define CUSTOM_INFO_WRITE_ERROR 0x01 +#define CUSTOM_INFO_READ_ERROR 0x02 +#define CUSTOM_INFO_CMP_ERROR 0x03 +#define CUSTOM_INFO_RESET_ERROR 0x04 + +/*write custom information test result*/ +typedef struct CUSTOM_INFO_RES { + ST_TEST_ITEM_RES item_res_header; + u8 info_len; + PST_CUSTOM_INFO_BYTE p_info; +} ST_CUSTOM_INFO_RES, *PST_CUSTOM_INFO_RES; + +extern s32 tp_custom_info_proc(ptr32 p_data); + +/**********************************Check Chip Test Result************************************/ +/*//TP_CHK_CHIP_TEST_RESULT_ITEM_ID +//------------------Error Code--------------------//*/ +#define CHECK_CHIP_TEST_ERROR_NONE 0x00 + +/*test result*/ +typedef struct CHECK_CHIP_TEST_RES { + ST_TEST_ITEM_RES item_res_header; + u16 chip_test_res_info_len; + u8 *chip_test_res_info; +} ST_CHECK_CHIP_TEST_RES, *PST_CHECK_CHIP_TEST_RES; +extern s32 tp_check_chip_test_result(ptr32 p_data); + +/**********************************Check Module Test Result************************************/ +/*TP_CHK_MODULE_TEST_RESULT_ITEM_ID*/ +#define MAX_TEST_RES_LEN 8 +/*--------------------Error Code---------------------*/ +#define CHECK_MODULE_TEST_ERROR_NONE 0x00 +#define CHECK_MODULE_TEST_READ_FAIL 0x01 +#define CHECK_MODULE_TEST_RES_NG 0x02 +#define CHECK_MODULE_TEST_CHKSUM_ERROR 0x03 + +/*test result*/ +typedef struct CHECK_MODULE_TEST_RES { + ST_TEST_ITEM_RES item_res_header; + u8 test_res_buf[MAX_TEST_RES_LEN]; + u8 test_res_buf_len; +} ST_CHECK_MODULE_TEST_RES, *PST_CHECK_MODULE_TEST_RES; +extern s32 tp_check_module_test_result(ptr32 p_data); + +/**********************************Recover Config To Chip************************************/ +/*TP_RECOVER_CFG_ITEM_ID*/ +#define RECOVER_CFG_ERROR_CODE_NONE 0 /*test ok*/ +#define RECOVER_CFG_CFG_WRITE_ERROR 1 +#define RECOVER_CFG_CFG_READ_ERROR 2 +#define RECOVER_CFG_CMP_ERROR 3 + +/*test result*/ +typedef struct RECOVER_CHIP_CFG_RES { + ST_TEST_ITEM_RES item_res_header; + u16 cfg_len; + u8 *config_arr; +} ST_RECOVER_CHIP_CFG_RES, *PST_RECOVER_CHIP_CFG_RES; +extern s32 tp_recover_cfg_to_chip(ptr32 p_data); + +/**********************************Save Result To Chip Storage************************************/ +/*//TP_SAVE_RES_TO_IC_STORAGE_ITEM_ID +//--------------------Error Code---------------------//*/ +#define SAVE_RES_TO_CHIP_ERROR_NONE 0 +#define SAVE_RES_GET_TOTAL_RES_FAIL 1 +#define SAVE_RES_WRITE_TO_CHIP_FAIL 2 + +/*test result*/ +typedef struct SAVE_RES_TO_CHIP_RES { + ST_TEST_ITEM_RES item_res_header; + u8 test_res_buf[MAX_TEST_RES_LEN]; + u8 test_res_buf_len; +} ST_SAVE_RES_TO_CHIP_RES, *PST_SAVE_RES_TO_CHIP_RES; +extern s32 tp_save_res_to_chip(ptr32 p_data); + +/**********************************Chip Uid Process************************************/ +/*//TP_CHIP_UID_PROCESS_ITEM_ID +//--------------------Error Code---------------------//*/ +#define CHIP_UID_PROC_ERROR_NONE 0 +#define CHIP_UID_PROC_READ_ERROR 1 +#define CHIP_UID_PROC_WRITE_ERROR 2 + +/*test result*/ +#define MAX_CHIP_UID_LEN 32 +typedef struct CHIP_UID_PROCESS_RES { + ST_TEST_ITEM_RES item_res_header; + u8 uid_len; + u8 uid_arr[MAX_CHIP_UID_LEN]; +} ST_CHIP_UID_PROCESS_RES, *PST_CHIP_UID_PROCESS_RES; +extern s32 tp_chip_uid_proc(ptr32 p_data); + +/*************************************Private methods start********************************************/ + +/*************************************Private methods end********************************************/ +#ifdef __cplusplus +} +#endif +#endif +#endif \ No newline at end of file diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_additional_option_param.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_additional_option_param.h new file mode 100644 index 000000000000..e7e993d0829c --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_additional_option_param.h @@ -0,0 +1,86 @@ +#ifndef TP_ADDITIONAL_OPTION_PARAM_H +#define TP_ADDITIONAL_OPTION_PARAM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "user_test_type_def.h" +#include "test_item_def.h" +#include "custom_info_def.h" + +/*chip config proc param*/ +#define CHIP_CFG_SEND 0x0000 +#define CHIP_CFG_CHECKED 0x0001 +typedef struct CHIP_CONFIG_PROC_PARAM { + u16 option; + u16 cfg_len; + u8 *config; +} ST_CHIP_CONFIG_PROC_PARAM, *PST_CHIP_CONFIG_PROC_PARAM; + +/****************************send special config*******************************/ +/*special config param(TP_SEND_SPEC_CFG_ITEM_ID)*/ +typedef struct SPEC_CONFIG_PARAM { + u16 cfg_len; + u8 *config; +} ST_SPEC_CONFIG_PARAM, *PST_SPEC_CONFIG_PARAM; + +/*check config param(TP_CFG_CHECK_TEST_ITEM_ID)*/ +typedef ST_CHIP_CONFIG_PROC_PARAM ST_CHECK_CONFIG_PARAM; +typedef PST_CHIP_CONFIG_PROC_PARAM PST_CHECK_CONFIG_PARAM; + +/*---------------option----------------*/ +#define FLASH_TEST_SEND_CFG_OPT 0x0001 +#define FLASH_TEST_DEFAULT_DELAY 0x0002 +typedef struct FLASH_TEST_PARAM { + u16 delay_time; + u16 option; + u16 cfg_len; + u8 *config_arr; +} ST_FLASH_TEST_PARAM, *PST_FLASH_TEST_PARAM; + +typedef struct UPDATE_SPEC_FW_PARAM { + u8 *fw_buf; + u32 fw_len; +} ST_UPDATE_SPEC_FW_PARAM, *PST_UPDATE_SPEC_FW_PARAM; + +/*--------------------Option------------------------*/ +#define CUSTOM_INFO_WRITE_OPTION 0x00 +#define CUSTOM_INFO_READ_OPTION 0x01 +#define CUSTOM_INFO_SMART_OPTION 0x02 + +typedef struct CUSTOM_INFO_PARAM { + u8 option; + u8 info_len; + PST_CUSTOM_INFO_BYTE p_info; +} ST_CUSTOM_INFO_PARAM, *PST_CUSTOM_INFO_PARAM; + +typedef struct CHECK_CHIP_TEST_PARAM { + u8 reserved1; +} ST_CHECK_CHIP_TEST_PARAM, *PST_CHECK_CHIP_TEST_PARAM; + +typedef struct CHECK_MODULE_TEST_PARAM { + u8 reserved1; +} ST_CHECK_MODULE_TEST_PARAM, *PST_CHECK_MODULE_TEST_PARAM; + +typedef struct RECOVER_CHIP_CFG_PARAM { + u16 cfg_len; + u8 *config_arr; +} ST_RECOVER_CHIP_CFG_PARAM, *PST_RECOVER_CHIP_CFG_PARAM; + +typedef struct SAVE_RES_TO_CHIP_PARAM { + u8 reserved1; +} ST_SAVE_RES_TO_CHIP_PARAM, *PST_SAVE_RES_TO_CHIP_PARAM; + +/*--------------------Option---------------------*/ +#define CHIP_UID_PROC_READ_OPT 0x00 +#define CHIP_UID_PROC_WRITE_OPT 0x01 +#define CHIP_UID_PROC_SMART_OPT 0x02 +typedef struct CHIP_UID_PROCESS_PARAM { + u8 option; +} ST_CHIP_UID_PROCESS_PARAM, *PST_CHIP_UID_PROCESS_PARAM; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_board_flash_alloc.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_board_flash_alloc.h new file mode 100644 index 000000000000..de0cdd420dfa --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_board_flash_alloc.h @@ -0,0 +1,32 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_board_flash_alloc.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : test parameter store in flash must obey this file's rules +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef TP_BOARD_FLASH_ALLOC_H +#define TP_BOARD_FLASH_ALLOC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "user_test_type_def.h" + +#if ARM_CODE == 1 +#include "flash_mem_alloc_def.h" +#include "user_test_type_def.h" + +#define USER_TEST_FLASH_MEM_START_ADDR (_STORAGE_MEM_ADDR) +#define USER_TEST_FLASH_MEM_LEN (256 * 1024) + +#endif + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_dev_control.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_dev_control.c new file mode 100644 index 000000000000..5b1faed4c14a --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_dev_control.c @@ -0,0 +1,568 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_dev_contol.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : device control interface +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#include "simple_mem_manager.h" +#include "tp_dev_control.h" +#include "tp_dev_def.h" +#include "public_fun.h" +#include "tp_normandy_control.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static s32 soft_reset_chip(PST_TP_DEV p_dev); + +static s32 reset_hold_chip(PST_TP_DEV p_dev); + +static s32 chip_int_sync(PST_TP_DEV p_dev); + +/******************************************************************************* +* Function Name : chip_reg_write +* Description : write chip register +* Input : PST_TP_DEV p_dev(pointer to a touch panel deice, which should be inited before) +* Input : u16 addr(address) +* Input : s32* p_buf(data buffer) +* Input : u16 buf_len(buffer length) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 chip_reg_write(IN PST_TP_DEV p_dev, IN u16 addr, IN u8 *p_buf, + IN u16 buf_len) +{ + s32 ret = 0; + u8 retry_cnt = 3; + u8 i = 0; + + switch (p_dev->chip_type) { + case TP_NORMANDY: + case TP_OSLO: { + ret = normandy_reg_write(p_dev, addr, p_buf, buf_len); + } break; + default: { + for (i = 0; i < retry_cnt; i++) { + ret = board_write_chip_reg(p_dev, addr, p_buf, buf_len); + if (1 == ret) { + break; + } + } + } break; + } + + return ret; +} + +/******************************************************************************* +* Function Name : chip_reg_read +* Description : read chip register +* Input : PST_TP_DEV p_dev(pointer to a touch panel deice, which should be inited before) +* Input : u16 addr(address) +* Input : s32* p_buf(data buffer) +* Input : u16 buf_len(buffer length) +* Output : s32* p_buf +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 chip_reg_read(IN PST_TP_DEV p_dev, IN u16 addr, OUT u8 *p_buf, + IN u16 buf_len) +{ + s32 ret = 0; + u8 retry_cnt = 3; + u8 i = 0; + + switch (p_dev->chip_type) { + case TP_NORMANDY: + case TP_OSLO: { + ret = normandy_reg_read(p_dev, addr, p_buf, buf_len); + } break; + default: { + for (i = 0; i < retry_cnt; i++) { + ret = board_read_chip_reg(p_dev, addr, p_buf, buf_len); + if (1 == ret) { + break; + } + } + } break; + } + return ret; +} + +/******************************************************************************* +* Function Name : chip_reg_write_chk +* Description : write chip register and check whether writing successfully +* Input : PST_TP_DEV p_dev(pointer to a touch panel deice, which should be inited before) +* Input : u16 addr(address) +* Input : s32* p_buf(data buffer) +* Input : u16 buf_len(buffer length) +* Output : s32* p_buf +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 chip_reg_write_chk(IN PST_TP_DEV p_dev, IN u16 addr, IN u8 *p_buf, + IN u16 buf_len) +{ + s32 ret = 0; + u16 i = 0; + u8 *p_buf_read_tmp = NULL; + ret = chip_reg_write(p_dev, addr, p_buf, buf_len); + if (1 == ret) { + ret = alloc_mem_in_heap((void **)&p_buf_read_tmp, buf_len); + if (0 == ret) { + return ret; + } + ret = chip_reg_read(p_dev, addr, p_buf_read_tmp, buf_len); + if (1 == ret) { + for (i = 0; i < buf_len; i++) { + if (p_buf[i] != p_buf_read_tmp[i]) { + ret = 0; + break; + } + } + } + free_mem_in_heap(p_buf_read_tmp); + } + return ret; +} + +/******************************************************************************* +* Function Name : reset_chip +* Description : reset chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Input : RST_OPTION rst_opt(reset option,you can refer RST_OPTION) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 reset_chip_proc(IN PST_TP_DEV p_dev, IN RST_OPTION rst_opt) +{ + s32 ret = 0; + if (p_dev == NULL) { + return ret; + } + /* reset ap flow + // 1. reset chip 2.chip init sync 3.seek dev addr + // (1)reset chip + */ + switch (rst_opt) { + case RESET_TO_AP: { + ret = reset_chip(p_dev); + /*(2)sync int pin*/ + if (ret) { + ret = chip_int_sync(p_dev); + } + } break; + case RESET_TP_DSP: { + ret = reset_hold_chip(p_dev); + } break; + default: + break; + } + + return ret; +} + +/******************************************************************************* +* Function Name : chip_mode_select +* Description : set chip to a pointed work mode +* Input : PST_TP_DEV p_dev(pointer to a touch panel deice, which should be inited before) +* Input : s32 work_mode +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 chip_mode_select(IN PST_TP_DEV p_dev, IN u8 work_mode) +{ + s32 ret = 0; + switch (work_mode) { + case CHIP_RAW_DATA_MODE: + ret = board_enter_rawdata_mode(p_dev); + break; + case CHIP_COORD_MODE: + ret = board_enter_coord_mode(p_dev); + break; + case CHIP_SLEEP_MODE: + ret = board_enter_sleep_mode(p_dev); + break; + case CHIP_DIFF_DATA_MODE: + ret = board_enter_diffdata_mode(p_dev); + break; + default: + break; + } + return ret; +} + +/******************************************************************************* +* Function Name : reset_chip +* Description : reset chip,hardware reset or softreset +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 reset_chip(IN PST_TP_DEV p_dev) +{ + s32 ret = 0; + if (p_dev->no_rst_pin) { + ret = soft_reset_chip(p_dev); + } else { + /*(1)Judge whether use soft reset*/ + if (p_dev->use_soft_reset) { + ret = soft_reset_chip(p_dev); + } + /*(2)If soft reset fail or no use soft reset*/ + if (0 == ret) { + ret = board_hard_reset_chip(p_dev); + } + } + /*clear doze_ref_cnt,module power on initialized with doze*/ + p_dev->doze_ref_cnt = 1; + /*p_dev->hid_state = 1;*/ + + return ret; +} +/******************************************************************************* +* Function Name : wakeup_chip +* Description : wakeup chip,reset or read +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +s32 wakeup_chip(PST_TP_DEV p_dev) +{ + s32 ret = 1; + switch (p_dev->chip_type) { + case TP_NORMANDY: + case TP_OSLO: { + ret = normandy_wakeup_chip(p_dev); + } break; + default: { + board_print_warning( + "chip type (%d) is not exist, please check it", + p_dev->chip_type); + ret = 0; + } break; + } + return ret; +} + +/******************************************************************************* +* Function Name : get_data_flag +* Description : get data flag +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : s32(0:no flag 1:flag) +*******************************************************************************/ +extern s32 get_data_flag(IN PST_TP_DEV p_dev) +{ + s32 ret = 0; + u16 i = 0, retry_cnt = 15; + u8 data_temp; + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_read(p_dev, p_dev->syncflag_addr, &data_temp, 1); + if ((1 == ret) && (0 != (p_dev->syncflag_mask & data_temp))) { + ret = 1; + break; + } else { + ret = 0; + } + board_delay_ms(2); + } + return ret; +} + +/******************************************************************************* +* Function Name : clr_data_flag +* Description : clr data flag +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 clr_data_flag(IN PST_TP_DEV p_dev) +{ + s32 ret = 0; + u8 i = 0, retry_cnt = 3; + u8 buf_tmp = 0x00; + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_write(p_dev, p_dev->syncflag_addr, &buf_tmp, 1); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_warning("clr_data_flag fail"); + } + return ret; +} + +/******************************************************************************* +* Function Name : write_cfg +* Description : write config to tp chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Input : u8* config(the buffer store cfg) +* Input : u16 cfg_len(cfg len) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 force_update_cfg(IN PST_TP_DEV p_dev, IN u8 *config, IN u16 cfg_len) +{ + s32 ret = 0; + switch (p_dev->chip_type) { + case TP_NORMANDY: + case TP_OSLO: { + ret = normandy_force_update_cfg(p_dev, config, cfg_len); + } break; + default: { + ret = 0; + board_print_warning( + "chip type (%d) is not exist, please check it", + p_dev->chip_type); + break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : write_cfg +* Description : write config to tp chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Input : s32* cfg1 +* Input : s32* cfg2 +* Input : u16 cfg_len +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 cmp_cfg(IN PST_TP_DEV p_dev, IN u8 *cfg1, IN u8 *cfg2, + IN u16 cfg_len) +{ + s32 ret = 0; + switch (p_dev->chip_type) { + case TP_NORMANDY: + case TP_OSLO: { + ret = normandy_cmp_cfg(p_dev, cfg1, cfg2, cfg_len); + } break; + default: { + ret = 0; + board_print_warning( + "chip type (%d) is not exist, please check it", + p_dev->chip_type); + break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : write_cmd +* Description : write_cmd +* Input : PST_TP_DEV p_dev(touch panel deice) +* Input : u16 cmd_addr +* Input : s32 cmd_byte +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 write_cmd(IN PST_TP_DEV p_dev, IN u16 cmd_addr, IN u8 cmd_byte) +{ + s32 ret = 0; + switch (p_dev->chip_type) { + case TP_GT900: + case TP_ALTO: { + ret = chip_reg_write(p_dev, cmd_addr, &cmd_byte, 1); + } break; + + default: { + u8 buf_tmp[3]; + buf_tmp[0] = cmd_byte; + buf_tmp[1] = 0; + buf_tmp[2] = 0x100 - buf_tmp[0] - buf_tmp[1]; + ret = chip_reg_write(p_dev, cmd_addr, buf_tmp, 3); + } break; + } + return ret; +} + +/******************************************************************************* +* Function Name : write_cfg +* Description : write config to tp chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 write_cfg(IN PST_TP_DEV p_dev) +{ + return write_cfg_arr(p_dev, p_dev->cfg, p_dev->cfg_len); +} + +/******************************************************************************* +* Function Name : read_cfg +* Description : read config from tp chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : PST_TP_DEV p_dev(touch panel deice) +* Return : s32(0:fail >0:read config len) +*******************************************************************************/ +extern s32 read_cfg(IN_OUT PST_TP_DEV p_dev) +{ + return read_cfg_arr(p_dev, p_dev->cfg, p_dev->cfg_len); +} + +/******************************************************************************* +* Function Name : write_cfg_arr +* Description : write config to tp chip +* Input : PST_TP_DEV p_dev (touch panel deice) +* Input : s32* config (the buffer store cfg) +* Input : u16 cfg_len (cfg len) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 write_cfg_arr(IN PST_TP_DEV p_dev, IN u8 *config, IN u16 cfg_len) +{ + s32 ret = 0; + switch (p_dev->chip_type) { + case TP_NORMANDY: + case TP_OSLO: { + ret = normandy_write_cfg(p_dev); + } break; + default: { + board_print_warning( + "chip type (%d) is not exist, please check it", + p_dev->chip_type); + ret = 0; + break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : read_cfg +* Description : read config from tp chip +* Input : PST_TP_DEV p_dev (touch panel deice) +* Input : s32* config (the buffer store cfg) +* Input : u16 cfg_len (cfg len) +* Output : s32* config +* Return : s32(0:fail >0:read config len) +*******************************************************************************/ +extern s32 read_cfg_arr(IN PST_TP_DEV p_dev, IN_OUT u8 *config, IN u16 cfg_len) +{ + s32 ret = 0; + switch (p_dev->chip_type) { + case TP_NORMANDY: + case TP_OSLO: { + ret = normandy_read_cfg_arr(p_dev, config, cfg_len); + } break; + default: { + board_print_warning( + "chip type (%d) is not exist, please check it", + p_dev->chip_type); + ret = 0; + break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : cfg_to_flash_delay +* Description : wait cfg save to flash from ram +* Input : PST_TP_DEV p_dev(pointer to a touch panel deice, which should be inited before) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 cfg_to_flash_delay(IN PST_TP_DEV p_dev) +{ + s32 ret = 1; + switch (p_dev->chip_type) { + case TP_NORMANDY: + case TP_OSLO: { + board_delay_ms(600); + } break; + default: { + board_print_warning( + "chip type (%d) is not exist, please check it", + p_dev->chip_type); + ret = 0; + } break; + } + return ret; +} + +#ifdef __cplusplus +} +#endif + +/*************************************Private methods start********************************************/ + +/******************************************************************************* +* Function Name : soft_reset_chip +* Description : soft reset chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +s32 soft_reset_chip(IN PST_TP_DEV p_dev) +{ + s32 ret = 1; + switch (p_dev->chip_type) { + case TP_NORMANDY: + case TP_OSLO: { + ret = normandy_soft_reset_chip(p_dev); + } break; + default: { + board_print_warning( + "chip type (%d) is not exist, please check it", + p_dev->chip_type); + ret = 0; + } break; + } + return ret; +} + +/******************************************************************************* +* Function Name : reset_hold_chip +* Description : reset hold chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +static s32 reset_hold_chip(IN PST_TP_DEV p_dev) +{ + s32 ret = 0; + switch (p_dev->chip_type) { + case TP_NORMANDY: + case TP_OSLO: { + ret = normandy_reset_hold_chip(p_dev); + } break; + default: { + board_print_warning( + "chip type (%d) is not exist, please check it", + p_dev->chip_type); + break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : chip_int_sync +* Description : chip int pin sync +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +static s32 chip_int_sync(IN PST_TP_DEV p_dev) +{ + s32 ret = 1; + /*set gpio mode GPIO_Mode_Out_PP( if you wanna input high)*/ + board_gpio_mode_set(p_dev, TPYE_GPIO_B, MODULE_INT, Mode_Out_PP); + board_gpio_reset_bits(p_dev, TPYE_GPIO_B, MODULE_INT); + board_delay_ms(50); + board_gpio_set_bits(p_dev, TPYE_GPIO_B, MODULE_INT); + board_gpio_mode_set(p_dev, TPYE_GPIO_B, MODULE_INT, Mode_IN_FLOATING); + return ret; +} + +/*************************************Private methods end********************************************/ + +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_dev_control.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_dev_control.h new file mode 100644 index 000000000000..b8f76617309a --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_dev_control.h @@ -0,0 +1,86 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_dev_contol.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : device control interface +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef TP_DEV_CONTROL_H +#define TP_DEV_CONTROL_H + +#include "tp_dev_def.h" +#include "board_opr_interface.h" +#include "custom_info_def.h" + +#ifdef __cplusplus +extern "C" { +#endif +/*************************************Public methods start********************************************/ +extern s32 chip_reg_write(PST_TP_DEV p_dev, u16 addr, u8 *p_buf, u16 buf_len); +extern s32 chip_reg_read(PST_TP_DEV p_dev, u16 addr, u8 *p_buf, u16 buf_len); +extern s32 chip_reg_write_chk(PST_TP_DEV p_dev, u16 addr, u8 *p_buf, + u16 buf_len); + +extern s32 ctrl_chip_io(PST_TP_DEV p_dev, u16 io_id, GIOMode_Def modeType); + +/*set tp chip io state*/ +extern s32 setbit_chip_io(PST_TP_DEV p_dev, u16 io_id, GIOBit_Def bit_state); +/*get tp chip io state*/ +extern GIOBit_Def getbit_chip_io(PST_TP_DEV p_dev, u16 io_id); + +/*rst pin operation*/ +typedef enum { RESET_TO_AP = 0x00, RESET_TP_DSP = 0x01 } RST_OPTION; +extern s32 reset_chip_proc(PST_TP_DEV p_dev, RST_OPTION rst_opt); +extern s32 reset_chip(PST_TP_DEV p_dev); + +extern s32 wakeup_chip(PST_TP_DEV p_dev); + +/*int pin operation*/ +extern s32 set_chip_int_floating(PST_TP_DEV p_dev); + +enum { + CHIP_RAW_DATA_MODE, + CHIP_COORD_MODE, /*coordinate mode */ + CHIP_SLEEP_MODE, + CHIP_DIFF_DATA_MODE, +}; +extern s32 chip_mode_select(PST_TP_DEV p_dev, u8 work_mode); + +extern s32 enter_gest_doze(PST_TP_DEV p_dev); +extern s32 exit_gest_doze(PST_TP_DEV p_dev); + +/*data flag indicate there is coord data(rawdata) or not*/ +extern s32 get_data_flag(PST_TP_DEV p_dev); +extern s32 clr_data_flag(PST_TP_DEV p_dev); + +/*cfg process*/ +extern s32 write_cfg_arr(PST_TP_DEV p_dev, u8 *config, u16 cfg_len); +extern s32 read_cfg_arr(PST_TP_DEV p_dev, u8 *config, u16 cfg_len); +extern s32 write_cfg(PST_TP_DEV p_dev); +extern s32 read_cfg(PST_TP_DEV p_dev); +extern s32 force_update_cfg(PST_TP_DEV p_dev, u8 *config, u16 cfg_len); + +extern s32 cfg_to_flash_delay(PST_TP_DEV p_dev); + +extern s32 cmp_cfg(PST_TP_DEV p_dev, u8 *cfg1, u8 *cfg2, u16 cfg_len); + +/*cmd*/ +extern s32 write_cmd(PST_TP_DEV p_dev, u16 cmd_addr, u8 cmd_byte); + +#define CHECK_CHIP_TEST_RES_OK 0 +#define CHECK_CHIP_TEST_COMM_ERR 1 +#define CHECK_CHIP_TEST_CHK_SUM_ERR 2 +#define CHECK_CHIP_TEST_RES_NG 3 +#define CHECK_CHIP_TEST_QUALITY_NG 4 +extern s32 check_chip_test_res_info(PST_TP_DEV p_dev, u8 *test_res_info, + u32 len); +/*************************************Public methods end**********************************************/ + +#ifdef __cplusplus +} +#endif +/*************************************Private methods start********************************************/ /*************************************Private methods end********************************************/ +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_dev_def.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_dev_def.h new file mode 100644 index 000000000000..e9177180ec32 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_dev_def.h @@ -0,0 +1,176 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_dev_def.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 12/31/2017 +* Description : touch panel device define +*******************************************************************************/ +#ifndef TP_DEF_DEF_H +#define TP_DEF_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "user_test_type_def.h" +#include "tp_product_id_def.h" +#include "tp_micro_def.h" + +/* communication info*/ +typedef struct TP_COMM { + u8 comm_type; /* the type of communication -default i2c*/ + u8 i2c_address_num; + u8 i2c_address[TP_MAX_I2C_ADDRESS_NUM]; /*127*/ + u8 dev_address; /* seek i2c address*/ + u8 dev_fix_address; /* fixed address*/ +} ST_TP_COMM, *PST_TP_COMM; + +/*device command define*/ +typedef struct TP_DEV_CMD { + u16 addr; + u8 cmd_len; + u8 cmd_buf[TP_DEV_CMD_LEN]; +} ST_TP_DEV_CMD, *PST_TP_DEV_CMD; +/*cmd set*/ +typedef struct TP_DEV_CMD_SET { + ST_TP_DEV_CMD rawdata_cmd; + ST_TP_DEV_CMD diffdata_cmd; + ST_TP_DEV_CMD coorddata_cmd; + ST_TP_DEV_CMD sleep_cmd; + ST_TP_DEV_CMD hid_ena_cmd; + ST_TP_DEV_CMD hid_dis_cmd; + ST_TP_DEV_CMD enter_gest_cmd; + +} ST_TP_DEV_CMD_SET, *PST_TP_DEV_CMD_SET; + +/*data option*/ +#define _DATA_BIT_8 0x01 +#define _DATA_BIT_16 0x02 +#define _DATA_BIT_32 0x04 +#define _DATA_BIT_64 0x08 +#define _DATA_DRV_SEN_INVERT 0x10 +#define _DATA_SIGNED 0x40 +#define _DATA_LARGE_ENDIAN 0x80 + +/*touch panel device define*/ +typedef struct TP_DEV { + /* COMM*/ + PST_TP_COMM p_tp_comm; + ptr32 p_logic_dev; /*use in pc code,arm code equeal null*/ + + u16 chip_type; /* chip type*/ + u16 chip_sub_type; /* chip sub type*/ + + /*voltage setting*/ + u16 power_volt; /* mV*/ + u16 comm_volt; /* mV */ + + /*cfg*/ + u16 cfg_start_addr; + u16 ext_cfg_addr; + u16 ext_cfg_len; + u16 cfg_len; /*if ext_cfg_len != 0 then cfg_len = base_cfg_len + ext_cfg_len*/ + u8 cfg[TP_MAX_CFG_LEN]; + + u8 use_soft_reset; /* 1 use soft reset first */ + u8 no_rst_pin; /* 1 no rst pin 0 has rst pin default 0*/ + + /* max sensor and driver num for die*/ + u8 max_sen_num_in_die; + u8 max_drv_num_in_die; + + /* max sensor and driver num for this chip*/ + u8 max_sen_num; + u8 max_drv_num; + + /* current sensor num and driver(include key channel)*/ + u8 total_sen_num; + u8 total_drv_num; + + /*screen sensor num and driver(exclude key channel)*/ + u8 sc_sen_num; + u8 sc_drv_num; + u16 sen_start_addr; + u16 drv_start_addr; + u16 sen1_start_addr; /*have two G1 use,eg Phoenix*/ + u16 drv1_start_addr; /*have two G1 use,eg Phoenix*/ + /*channel map*/ + u8 map_disable; + u8 drv_map[TP_MAX_CHN_NUM]; + u8 sen_map[TP_MAX_CHN_NUM]; + u8 pack_drv_2_adc_map[TP_MAX_CHN_NUM]; + u8 pack_sen_2_adc_map[TP_MAX_CHN_NUM]; + u8 chn_map[TP_MAX_CHN_NUM]; + + /* key*/ + u8 key_num; + u8 key_rawdata_num; + u8 key_pos_arr[TP_MAX_KEY_NUM]; + + /* cmd */ + u16 seek_reg_addr; + + u16 real_cmd_addr; /*this field may be same as fields in cmd_set*/ + ST_TP_DEV_CMD_SET cmd_set; + + u16 rawdata_addr; + u16 rawdata_len; + u8 rawdata_option; + + u16 diffdata_addr; + u16 diffdata_len; + u8 diffdata_option; + + u16 basedata_addr; + u16 basedata_len; + u8 basedata_option; + + u16 syncflag_addr; + u16 syncflag_mask; + u16 coordchk_sum; + + /*in GT900/GT9P/GT9L this address is u16,in Phoenix/Normandy this address is u32*/ + u32 custom_info_addr; + u8 custom_info_len; + + u32 module_test_res_addr; + u8 module_test_res_len; + + u32 uid_addr; + u8 uid_len; + + u32 chip_test_res_addr; + u16 chip_test_res_len; + + /* general flash protocol*/ + u32 flash_rw_cmd_addr; + u8 flash_read_cmd_byte; + u8 flash_write_cmd_byte; + u8 flash_send_cmd_end_byte; + + u32 flash_rw_sta_addr; + u8 flash_rw_ok_sta_byte; + u8 flash_rw_fail_sta_byte; + u8 flash_enter_rw_sta_byte; + u8 flash_chk_sum_err_sta_byte; + u8 flash_erase_fail_sta_byte; + u8 flash_write_fail_sta_byte; + u8 flash_read_fail_sta_byte; + u8 flash_access_fail_sta_byte; + u8 flash_clr_sta_byte; + u8 flash_rw_available; + u8 b_flash_big_endian; + + u32 flash_rw_switch_buf_addr; + u32 flash_max_data_size; + u32 flash_page_size; + + u8 doze_ref_cnt; /*1:doze mode 0:exit doze*/ + u8 hid_state; /*1:state of enable hid 0:state of disable hid*/ + +} ST_TP_DEV, *PST_TP_DEV; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_item_permutation.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_item_permutation.c new file mode 100644 index 000000000000..06458b79dc96 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_item_permutation.c @@ -0,0 +1,123 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : test_proc.c +* Author : Bob Huang +* Version : V1.0.0 +* Date : 02/06/2018 +* Description : Sort item +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#include "tp_item_permutation.h" +#include "board_opr_interface.h" + +/*-----------------------------static variable-------------------------------*/ +const static u16 cs_item_permutation[] = { + TP_CHK_CHIP_TEST_RESULT_ITEM_ID, + TP_CHK_MODULE_TEST_RESULT_ITEM_ID, + TP_I2C_VOLT_TEST_ITEM_ID, + TP_INT_VOLT_TEST_ITEM_ID, + TP_INT_CAP_TEST_ITEM_ID, + TP_RST_VOLT_TEST_ITEM_ID, + TP_PIN1_TEST_ITEM_ID, + TP_PIN2_TEST_ITEM_ID, + TP_CHIP_UID_PROCESS_ITEM_ID, + TP_VERSION_TEST_ITEM_ID, + TP_CHK_FW_RUN_STATE_ITEM_ID, + TP_CUSTOM_INFO_TEST_ITEM_ID, + TP_MODULE_TYPE_TEST_ITEM_ID, + TP_CHIP_CFG_PROC_ITEM_ID, + TP_GESTURE_TEST_ITEM_ID, + TP_SLEEP_CURRENT_TEST_ITEM_ID, + TP_FLASH_TEST_ITEM_ID, + TP_SHORT_TEST_ITEM_ID, + TP_ACTIVE_CURRENT_TEST_ITEM_ID, + TP_RAWDATA_TEST_ITEMS_SET_ID, + TP_DIFFDATA_TEST_ITEMS_SET_ID, + TP_LINE_TEST_ITEM_ID, + TP_KEY_TOUCH_TEST_ITEM_ID, + TP_RECOVER_CFG_ITEM_ID, + TP_UPDATE_SPEC_FW_ITEM_ID, + TP_SEND_SPEC_CFG_ITEM_ID, + TP_SAVE_RES_TO_IC_STORAGE_ITEM_ID, + TP_TEST_ITEM_END_ID, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* +* Function Name : get_index_from_permutaion_arr +* Description : sort item get_index_from_permutaion_arr +* Input : u16 item_id +* Output : none +* Return : s32(index) +*******************************************************************************/ +extern s32 get_index_from_permutaion_arr(IN u16 item_id) +{ + s32 index_ret = -1; + s32 arr_size = sizeof(cs_item_permutation); + s32 i = 0; + for (i = 0; + i < arr_size && cs_item_permutation[i] != TP_TEST_ITEM_END_ID; + i++) { + if (cs_item_permutation[i] == item_id) { + index_ret = i; + break; + } + } + return index_ret; +} + +/******************************************************************************* +* Function Name : sort_item_permutation +* Description : sort item permutation +* Input : PST_TEST_PROC_DATA p_test_proc_data +* Output : PST_TEST_PROC_DATA p_test_proc_data +* Return : s32(1:ok 0:fail) +*******************************************************************************/ +extern s32 sort_item_permutation(IN_OUT PST_TEST_PROC_DATA p_test_proc_data) +{ + s32 ret = 1; + s32 i = 0, j = 0; + s32 item_cnt = 0; + s32 index1 = -1, index2 = -1; + PST_TEST_ITEM p_item_tmp = NULL; + if (NULL != p_test_proc_data) { + item_cnt = p_test_proc_data->test_item_num; + for (i = 0; i < item_cnt; i++) { + for (j = i + 1; j < item_cnt; j++) { + index1 = get_index_from_permutaion_arr( + p_test_proc_data->pp_test_item_arr[i] + ->test_item_id); + index2 = get_index_from_permutaion_arr( + p_test_proc_data->pp_test_item_arr[j] + ->test_item_id); + if (-1 == index1 || -1 == index2) { + board_print_error( + "%s\n", + "can not find test item!"); + } + if (index1 != -1 && index2 != -1 && + index1 > index2) { + p_item_tmp = + p_test_proc_data + ->pp_test_item_arr[i]; + p_test_proc_data->pp_test_item_arr[i] = + p_test_proc_data + ->pp_test_item_arr[j]; + p_test_proc_data->pp_test_item_arr[j] = + p_item_tmp; + } + } + } + ret = 1; + } + return ret; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_item_permutation.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_item_permutation.h new file mode 100644 index 000000000000..ac6544bbf266 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_item_permutation.h @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : test_proc.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : structs in this file also exist in pc,it is an interface + of test item +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef TP_ITEM_PERMUTATION_H +#define TP_ITEM_PERMUTATION_H + +#include "test_item_def.h" + +#ifdef __cplusplus +extern "C" { +#endif +/*sort item permutation */ +extern s32 sort_item_permutation(PST_TEST_PROC_DATA p_test_proc_data); +extern s32 get_index_from_permutaion_arr(u16 item_id); + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_micro_def.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_micro_def.h new file mode 100644 index 000000000000..b4f7cffadd3c --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_micro_def.h @@ -0,0 +1,64 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_micro_def.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 12/31/2017 +* Description : touch panel device define +*******************************************************************************/ +#ifndef TP_MICRO_DEF_H +#define TP_MICRO_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "user_test_type_def.h" +#include "tp_product_id_def.h" + +#define TP_MAX_KEY_NUM (15) +#define TP_MAX_SEN_NUM (152) +#define TP_MAX_DRV_NUM (152) +#define TP_MAX_CHN_NUM (TP_MAX_SEN_NUM + TP_MAX_DRV_NUM) +#define TP_MAX_NODE_NUM (TP_MAX_SEN_NUM * TP_MAX_DRV_NUM) + +#define TP_MAX_BIN_SIZE (256 * 1024) +#define TP_MAX_SHORT_BIN_SIZE (128 * 1024) +#define TP_MAX_SHORT_OPT_PARAM_SIZE (256) +#define TP_MAX_OPT_MESS_SIZE (2 * 1024) + +#define TP_MAX_CUSTOM_INFO_SIZE (64) + +#define TP_MAX_NC_LEN (TP_MAX_SEN_NUM * TP_MAX_DRV_NUM) +#define TP_MAX_KEY_NC_LEN (TP_MAX_KEY_NUM * TP_MAX_CHN_NUM) + +#define TP_FLAG_NEED_CHECK (0x01) +#define TP_FLAG_NOT_NEED_CHECK (!TP_FLAG_NEED_CHECK) +#define TP_FLAG_KEY_NEED_CHECK (0x01) +#define TP_FLAG_KEY_NOT_NEED_CHECK (!TP_FLAG_KEY_NEED_CHECK) + +/*need move to other place*/ +#define TP_INVALID_SNODE (0xFFFF) + +/*cfg pack num*/ +#define TP_MAX_CFG_PACK_NUM (100) + +/* cfg length*/ +#define TP_MAX_CFG_LEN (2048) +#define TP_MAX_I2C_ADDRESS_NUM (127) +#define TP_MAX_CMD_LEN (10) +#define TP_DEV_CMD_LEN (3) + +#define TP_MAX_TOUCH_NUM (10) +#define TP_MAX_INT_MODE_NUM (4) + +/*channel define */ +#define GT_9P_DRV_NUM_MAX (32) +#define GT_9P_SEN_NUM_MAX (32) + +#define GT_9PT_DRV_NUM_MAX GT_9P_DRV_NUM_MAX +#define GT_9PT_SEN_NUM_MAX GT_9P_SEN_NUM_MAX + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_normandy_control.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_normandy_control.c new file mode 100644 index 000000000000..49576593d2af --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_normandy_control.c @@ -0,0 +1,692 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_normandy_control.cpp +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : normandy device control interface +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#include "tp_normandy_control.h" +#include "board_opr_interface.h" +#include "tp_dev_control.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*************************************Private methods start********************************************/ +static s32 normandy_hold_dsp(PST_TP_DEV p_dev); +/*************************************Private methods End********************************************/ + +/******************************************************************************* +* Function Name : normandy_reg_write +* Description : write chip register +* Input : PST_TP_DEV p_dev(pointer to a touch panel deice, which should be initialized before) +* Input : u16 addr(address) +* Input : u32* p_buf(data buffer) +* Input : u16 buf_len(buffer length) +* Output : none +* Return : u32(1:ok 0:fail) +*******************************************************************************/ +extern s32 normandy_reg_write(IN PST_TP_DEV p_dev, IN u16 addr, IN u8 *p_buf, + IN u16 buf_len) +{ + s32 ret = 0; + u8 retry_cnt = 3; + u8 i = 0; + ret = normandy_doze_mode(p_dev, 0, 0); + if (0 == ret) { + board_print_error( + "[normandy_reg_write]normandy_doze_mode(p_dev,0,0) fail!\n"); + return ret; + } + + for (i = 0; i < retry_cnt; i++) { + ret = board_write_chip_reg(p_dev, addr, p_buf, buf_len); + if (1 == ret) { + break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : normandy_reg_read +* Description : read chip register +* Input : PST_TP_DEV p_dev(pointer to a touch panel deice, which should be inited before) +* Input : u16 addr(address) +* Input : u32* p_buf(data buffer) +* Input : u16 buf_len(buffer length) +* Output : none +* Return : u32(1:ok 0:fail) +*******************************************************************************/ +extern s32 normandy_reg_read(IN PST_TP_DEV p_dev, IN u16 addr, IN_OUT u8 *p_buf, + IN u16 buf_len) +{ + s32 ret = 0; + u8 retry_cnt = 3; + u8 i = 0; + ret = normandy_doze_mode(p_dev, 0, 0); + if (0 == ret) { + board_print_error( + "[normandy_reg_read]normandy_doze_mode(p_dev,0,0) fail!\n"); + return ret; + } + for (i = 0; i < retry_cnt; i++) { + ret = board_read_chip_reg(p_dev, addr, p_buf, buf_len); + if (1 == ret) { + break; + } + } + return ret; +} +/******************************************************************************* +* Function Name : normandy_wakeup_chip +* Description : normandy wakeup chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 normandy_wakeup_chip(PST_TP_DEV p_dev) +{ + return reset_chip_proc(p_dev, RESET_TO_AP); +} +/******************************************************************************* +* Function Name : normandy_soft_reset_chip +* Description : normandy soft reset chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : u32(0:fail 1:ok) +*******************************************************************************/ +extern s32 normandy_soft_reset_chip(IN PST_TP_DEV p_dev) +{ + s32 ret = 1; + u8 i = 0, retry_cnt = 3; + u8 hold_reg_val = 0x01; + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_write(p_dev, 0x4180, &hold_reg_val, 1); + if (1 == ret) { + break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : normandy_reset_hold_chip +* Description : normandy reset hold chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : u32(0:fail 1:ok) +*******************************************************************************/ +extern s32 normandy_reset_hold_chip(IN PST_TP_DEV p_dev) +{ + s32 ret = 0; + /* (3) reset ic*/ + ret = board_hard_reset_chip(p_dev); + if (1 == ret) { + ret = normandy_hold_dsp(p_dev); + } + return ret; +} + +/******************************************************************************* +* Function Name : normandy_force_update_cfg +* Description : force update cfg (version) +* Input : PST_TP_DEV p_dev(touch panel deice) +* Input : u16 cfg_len +* Output : OUT u8* config +* Return : u32(0:fail 1:ok) +*******************************************************************************/ +extern s32 normandy_force_update_cfg(IN PST_TP_DEV p_dev, IN u8 *config, + IN u16 cfg_len) +{ + s32 ret = 0; + u8 ver_tmp = 0; + u8 i = 0; + u8 retry_cnt = 3; + + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_read(p_dev, p_dev->cfg_start_addr, &ver_tmp, 1); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_error( + "%s\n", + "[normandy_force_update_cfg],read cfg version fail"); + goto UPDATE_CFG_END; + } + if (config[0] < ver_tmp && config[0] != 0) { + config[0] = 0xFF; + } + + for (i = 0; i < retry_cnt; i++) { + normandy_cfg_update_chksum(config, cfg_len); + ret = normandy_write_cfg_arr(p_dev, config, cfg_len); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_error("%s\n", + "[normandy_force_update_cfg],write cfg fail"); + goto UPDATE_CFG_END; + } + +UPDATE_CFG_END: + return ret; +} + +/******************************************************************************* +* Function Name : normandy_write_cfg +* Description : normandy write config to tp chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : u32(0:fail 1:ok) +*******************************************************************************/ +extern s32 normandy_write_cfg(IN_OUT PST_TP_DEV p_dev) +{ + return normandy_write_cfg_arr(p_dev, p_dev->cfg, p_dev->cfg_len); +} + +/******************************************************************************* +* Function Name : normandy_read_cfg +* Description : read config from tp normandy chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : PST_TP_DEV p_dev(touch panel deice) +* Return : u32(0:fail 1:ok) +*******************************************************************************/ +extern s32 normandy_read_cfg(IN_OUT PST_TP_DEV p_dev) +{ + return normandy_read_cfg_arr(p_dev, p_dev->cfg, p_dev->cfg_len); +} + +/******************************************************************************* +* Function Name : normandy_write_cfg_arr +* Description : write config from tp normandy chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Input : u32* config +* Input : u16 cfg_len +* Return : u32(0:fail 1:ok) +*******************************************************************************/ +extern s32 normandy_write_cfg_arr(IN PST_TP_DEV p_dev, IN u8 *config, + IN u16 cfg_len) +{ + s32 ret = 1; + u8 buf_arr[10]; + u8 retry_cnt = 10; + u8 retry_cnt1 = 10; + u8 i = 0; + u8 j = 0; + u8 tmp_write_cmd = 0; + u8 write_wait_cmd = 0; + + /*----------------------------------------enter idle ------------------------------------------*/ + buf_arr[0] = 0xFF; + buf_arr[1] = 0x00; + buf_arr[2] = 0x100 - buf_arr[0] - buf_arr[1]; + ret = chip_reg_write(p_dev, p_dev->real_cmd_addr, buf_arr, 3); + if (0 == ret) { + board_print_error("%s\n", "write 0xFF to real_cmd_addr fail!"); + goto READ_END; + } + /*----------------------------------------scan idle status------------------------------------------*/ + for (i = 0; i < retry_cnt; i++) { + buf_arr[0] = 0x00; + ret = chip_reg_read(p_dev, p_dev->real_cmd_addr, buf_arr, 1); + if (1 == ret && 0xFF == buf_arr[0]) { + break; + } else { + ret = 0; + } + board_delay_ms(10); + } + if (0 == ret) { + board_print_error("%s\n", "fail to wait idle status!"); + goto READ_END; + } + + /*-------------------------------------send write cfg cmd--------------------------------------*/ + if (cfg_len > 32) { + tmp_write_cmd = 0x80; + write_wait_cmd = 0x82; + } else { + tmp_write_cmd = 0x81; + write_wait_cmd = 0x81; + } + retry_cnt = 3; + for (i = 0; i < retry_cnt; i++) { + /*send write cfg cmd*/ + buf_arr[0] = tmp_write_cmd; + buf_arr[1] = 0x00; + buf_arr[2] = 0x100 - buf_arr[0] - buf_arr[1]; + ret = chip_reg_write(p_dev, p_dev->real_cmd_addr, buf_arr, 3); + if (1 == ret) { + board_delay_ms(50); + /*wait ready status*/ + retry_cnt1 = 50; + for (j = 0; j < retry_cnt1; j++) { + buf_arr[0] = 0x00; + ret = chip_reg_read(p_dev, p_dev->real_cmd_addr, + buf_arr, 1); + if (1 == ret && write_wait_cmd == buf_arr[0]) { + break; + } else { + ret = 0; + } + board_delay_ms(10); + } + if (ret == 1) { + break; + } + } else if (i == retry_cnt - 1) { + board_print_error("fail to send write cfg cmd!"); + return 0; + } + } + if ((0 == ret) && (j >= retry_cnt1)) { + board_print_error("%s\n", "fail to wait ready status!"); + goto READ_END; + } + + /*-------------------------------------- write cfg ------------------------------------------*/ + retry_cnt = 3; + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_write(p_dev, p_dev->cfg_start_addr, config, + cfg_len); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_error("%s\n", "fail to write cfg!"); + goto READ_END; + } + /*---------------------------------notify write completion------------------------------------*/ + buf_arr[0] = 0x83; + buf_arr[1] = 0x00; + buf_arr[2] = 0x100 - buf_arr[0] - buf_arr[1]; + ret = chip_reg_write(p_dev, p_dev->real_cmd_addr, buf_arr, 3); + if (0 == ret) { + board_print_error("%s\n", + "fail to notify write cfg completion!"); + goto READ_END; + } + /*---------------------------------wait idle------------------------------------*/ + board_delay_ms(50); + retry_cnt = 3; + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_read(p_dev, p_dev->real_cmd_addr, buf_arr, 1); + if (1 == ret && 0xFF == buf_arr[0]) { + break; + } else { + ret = 0; + } + board_delay_ms(1); + } + if (0 == ret) { + board_print_error("%s\n", "fail to wait idle status!"); + goto READ_END; + } + p_dev->doze_ref_cnt = 1; + /*for fw store config to fresh*/ + board_delay_ms(50); +READ_END: + return ret; +} + +/******************************************************************************* +* Function Name : normandy_read_cfg_arr +* Description : read config from tp normandy chip +* Input : PST_TP_DEV p_dev(touch panel deice) +* Input : u16 cfg_len +* Output : u8* config +* Return : s32(0:fail >0:read cfg len) +*******************************************************************************/ +extern s32 normandy_read_cfg_arr(IN PST_TP_DEV p_dev, IN_OUT u8 *config, + IN u16 cfg_len) +{ + s32 ret = 1; + u8 buf_arr[10]; + u8 retry_cnt = 10; + u8 retry_cnt1 = 0; + u8 i = 0; + u8 j = 0; + u8 sub_bags = 0; + u16 offset = 0; + /*enter idle */ + buf_arr[0] = 0xFF; + buf_arr[1] = 0x00; + buf_arr[2] = 0x100 - buf_arr[0] - buf_arr[1]; + board_print_debug("start read cfg!"); + ret = chip_reg_write(p_dev, p_dev->real_cmd_addr, buf_arr, 3); + if (0 == ret) { + board_print_error("%s\n", "write 0xFF to real_cmd_addr fail!"); + return 0; + } + /*scan idle status*/ + for (i = 0; i < retry_cnt; i++) { + buf_arr[0] = 0x00; + ret = chip_reg_read(p_dev, p_dev->real_cmd_addr, buf_arr, 1); + if (1 == ret && 0xFF == buf_arr[0]) { + break; + } else { + ret = 0; + } + board_delay_ms(10); + } + if (0 == ret) { + board_print_error("%s\n", "fail to wait idle status!"); + return 0; + } + + retry_cnt = 5; + for (i = 0; i < retry_cnt; i++) { + /*send read cfg cmd*/ + buf_arr[0] = 0x86; + buf_arr[1] = 0x00; + buf_arr[2] = 0x100 - buf_arr[0] - buf_arr[1]; + ret = chip_reg_write(p_dev, p_dev->real_cmd_addr, buf_arr, 3); + if (ret == 1) { + ret = 0; + /*wait for firmware ready for reading cfg*/ + retry_cnt1 = 50; + for (j = 0; j < retry_cnt1; j++) { + buf_arr[0] = 0x00; + ret = chip_reg_read(p_dev, p_dev->real_cmd_addr, + buf_arr, 1); + if (1 == ret && 0x85 == buf_arr[0]) { + break; + } else { + ret = 0; + } + board_delay_ms(10); + } + if (ret == 1) { + break; + } + } else if (i == retry_cnt - 1) { + board_print_error("fail to send read cfg end!"); + return 0; + } + } + if ((0 == ret) && (j >= retry_cnt1)) { + board_print_error( + "%s\n", + "fail to wait for firmware ready for reading cfg!"); + return 0; + } + + /*read cfg*/ + retry_cnt = 3; + if (cfg_len == 0) { /*config len is not known*/ + /*read config head*/ + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_read(p_dev, p_dev->cfg_start_addr, + config, 4); + if (ret == 1) { + break; + } + } + if (0 == ret) { + board_print_error("%s\n", "fail to read cfg head!"); + return 0; + } + /*read sub bugs*/ + sub_bags = config[2]; + offset = 4; + for (j = 0; j < sub_bags; j++) { + /*read sub bags head*/ + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_read( + p_dev, p_dev->cfg_start_addr + offset, + config + offset, 2); + if (ret == 1) { + break; + } + } + if (0 == ret) { + board_print_error( + "fail to read cfg sub bug %d head!\n", + j); + return 0; + } + /*read sub bugs*/ + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_read(p_dev, + p_dev->cfg_start_addr + + offset + 2, + config + offset + 2, + config[offset + 1] + 1); + if (ret == 1) { + break; + } + } + if (0 == ret) { + board_print_error( + "fail to read cfg sub bug %d!\n", j); + return 0; + } + board_print_debug("read sub bug %d offset is %d\n", j, + offset); + offset += config[offset + 1] + 3; + } + cfg_len = offset; + board_print_debug("chip cfg len: %d\n", cfg_len); + + } else { + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_read(p_dev, p_dev->cfg_start_addr, + config, cfg_len); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_error("%s\n", "fail to read cfg!"); + return 0; + } + } + + /*write idle cmd*/ + buf_arr[0] = 0xFF; + buf_arr[1] = 0x00; + buf_arr[2] = 0x100 - buf_arr[0] - buf_arr[1]; + ret = chip_reg_write(p_dev, p_dev->real_cmd_addr, buf_arr, 3); + if (0 == ret) { + board_print_error("%s\n", "fail to write idle cmd!"); + return 0; + } + + return cfg_len; +} + +/******************************************************************************* +* Function Name : normandy_cfg_update_chksum +* Description : update check sum +* Input : u32* config +* Input : u16 cfg_len +* Output : u8* config +* Return : none +*******************************************************************************/ +extern void normandy_cfg_update_chksum(IN_OUT u8 *config, IN u16 cfg_len) +{ + u16 pack_map_len_arr[100]; + u16 packNum = 0; + u16 pack_len_tmp = 0; + u16 pack_id_tmp = 0; + u16 i = 0, j = 0; + u16 cur_pos = 0; + u8 check_sum = 0; + + if (cfg_len < 4) + return; + + pack_map_len_arr[pack_id_tmp] = 4; + packNum = config[2]; + for (i = 4; i < cfg_len;) { + pack_id_tmp++; + pack_len_tmp = config[i + 1] + 3; + pack_map_len_arr[pack_id_tmp] = pack_len_tmp; + i += pack_len_tmp; + } + + cur_pos = 0; + for (i = 0; i <= pack_id_tmp; i++) { + check_sum = 0; + for (j = cur_pos; j < cur_pos + pack_map_len_arr[i] - 1; j++) { + check_sum += config[j]; + } + config[cur_pos + pack_map_len_arr[i] - 1] = (u8)(0 - check_sum); + cur_pos += pack_map_len_arr[i]; + } +} + +/******************************************************************************* +* Function Name : normandy_cmp_cfg +* Description : normandy_cmp_cfg +* Input : PST_TP_DEV p_dev(touch panel deice) +* Input : u32* cfg1 +* Input : u32* cfg2 +* Input : u16 cfg_len +* Output : OUT u8* config +* Return : u32(0:fail 1:ok) +*******************************************************************************/ +extern s32 normandy_cmp_cfg(IN PST_TP_DEV p_dev, IN u8 *cfg1, IN u8 *cfg2, + IN u16 cfg_len) +{ + s32 ret = 1; + u16 i = 0; + for (i = 0; i < cfg_len; i++) { + if (0 == i || 1 == i || 3 == i) /*|| + //cfg_len - 1 == i)*/ + { + continue; + } + if (cfg1[i] != cfg2[i]) { + ret = 0; + break; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : normandy_doze_mode +* Description : normandy_doze_mode +* Input : PST_TP_DEV p_dev(touch panel deice) +* Input : u32 b_ena +* Input : u32 b_force +* Output : none +* Return : u32(0:fail 1:ok) +*******************************************************************************/ +extern s32 normandy_doze_mode(IN PST_TP_DEV p_dev, IN u8 b_ena, IN u8 b_force) +{ + s32 ret = 1; + u8 temp_data = 0; + u8 temp_read = 0; + u8 i = 0; + u8 j = 0; + u8 retry_cnt = 20; + if (b_ena) { /*enter doze*/ + + if (p_dev->doze_ref_cnt == 0 || b_force) { + temp_data = 0xCC; + for (i = 0; i < retry_cnt; i++) { + ret = board_write_chip_reg(p_dev, 0x30f0, + &temp_data, 1); + if (1 == ret) { + break; + } + board_delay_ms(1); + } + if (1 == ret && 0 == p_dev->doze_ref_cnt) { + p_dev->doze_ref_cnt++; + } + if (0 == ret) { + board_print_error( + "%s\n", + "[normandy_doze_mode]board_write_chip_reg 0xCC in 0x30f0 fail!"); + } + } + } else { /*exit doze*/ + + if (p_dev->doze_ref_cnt == 1 || b_force) { + for (i = 0; i < retry_cnt; i++) { + if (0xAA != + temp_read) { /*only 0x3100 is not 0xAA and need write 0x30f0 0xAA */ + temp_data = 0xAA; + ret = board_write_chip_reg( + p_dev, 0x30f0, &temp_data, 1); + if (ret == 0) { + continue; + } + board_delay_ms(1); + } + + for (j = 0; j < retry_cnt; j++) { + ret = board_read_chip_reg( + p_dev, 0x3100, &temp_read, 1); + if ((1 == ret && 0xBB == temp_read)) { + break; + } + if ((1 == ret && 0xAA != temp_read)) { + ret = 0; + break; /*if 0x3100 is not 0xAA or 0xBB,rewrite 0x30F0 0xAA*/ + } + ret = 0; + board_delay_ms(5); + } + if ((1 == ret && 0xBB == temp_read)) { + break; + } + } + if (1 == ret && 1 == p_dev->doze_ref_cnt) { + p_dev->doze_ref_cnt--; + } + if (0 == ret) { + board_print_error( + "%s\n", + "[normandy_doze_mode]board_write_chip_reg 0xAA in 0x30f0 fail!"); + } + } + } + return ret; +} + +#ifdef __cplusplus +} +#endif + +/******************************************************************************* +* Function Name : normandy_hold_dsp +* Description : normandy hold dsp +* Input : PST_TP_DEV p_dev(touch panel deice) +* Output : none +* Return : u32(0:fail 1:ok) +*******************************************************************************/ +static s32 normandy_hold_dsp(IN PST_TP_DEV p_dev) +{ + /* if failed,retry, for max times 10*/ + s32 ret = 0; + u8 index = 0; + u8 write_value = 0x24; + u8 buf_tmp[2]; + buf_tmp[0] = write_value; + for (index = 0; index < 10; index++) { + ret = chip_reg_write(p_dev, 0x2180, buf_tmp, 1); + if (1 == ret) { + ret = chip_reg_read(p_dev, 0x2180, &(write_value), 1); + if (1 == ret && write_value == buf_tmp[0]) { + ret = 1; + break; + } + } + } + return ret; +} + +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_normandy_control.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_normandy_control.h new file mode 100644 index 000000000000..7e3976c66ce3 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_normandy_control.h @@ -0,0 +1,52 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_normandy_control.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : normandy device control interface +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef TP_NORMANDY_CONTROL_H +#define TP_NORMANDY_CONTROL_H + +#include "tp_dev_def.h" +#include "board_opr_interface.h" +#include "custom_info_def.h" + +#ifdef __cplusplus +extern "C" { +#endif +/*************************************Public methods start********************************************/ +extern s32 normandy_reg_write(PST_TP_DEV p_dev, u16 addr, u8 *p_buf, + u16 buf_len); +extern s32 normandy_reg_read(PST_TP_DEV p_dev, u16 addr, u8 *p_buf, + u16 buf_len); +extern s32 normandy_soft_reset_chip(PST_TP_DEV p_dev); +extern s32 normandy_reset_hold_chip(PST_TP_DEV p_dev); +extern s32 normandy_wakeup_chip(PST_TP_DEV p_dev); +extern s32 normandy_ctrl_chip_io(PST_TP_DEV p_dev, u16 io_id, + GIOMode_Def modeType); +extern s32 normandy_setbit_chip_io(PST_TP_DEV p_dev, u16 io_id, + GIOBit_Def bit_state); +extern GIOBit_Def normandy_getbit_chip_io(PST_TP_DEV p_dev, u16 io_id); +extern s32 normandy_force_update_cfg(PST_TP_DEV p_dev, u8 *config, u16 cfg_len); +extern s32 normandy_write_cfg(PST_TP_DEV p_dev); +extern s32 normandy_read_cfg(PST_TP_DEV p_dev); +extern s32 normandy_write_cfg_arr(PST_TP_DEV p_dev, u8 *config, u16 cfg_len); +extern s32 normandy_read_cfg_arr(PST_TP_DEV p_dev, u8 *config, u16 cfg_len); +extern void normandy_cfg_update_chksum(u8 *config, u16 cfg_len); +extern s32 normandy_cmp_cfg(PST_TP_DEV p_dev, u8 *cfg1, u8 *cfg2, u16 cfg_len); +extern s32 normandy_write_custom_info(PST_TP_DEV p_dev, + PST_CUSTOM_INFO_BYTE custom_info, u8 len); +extern s32 normandy_read_custom_info(PST_TP_DEV p_dev, + PST_CUSTOM_INFO_BYTE custom_info, u8 len); +extern s32 normandy_doze_mode(PST_TP_DEV p_dev, u8 b_ena, u8 b_force); +extern s32 normandy_check_chip_test_res_info(IN PST_TP_DEV p_dev, + IN u8 *test_res_info, IN u32 len); +/*************************************Public methods End********************************************/ +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_open_test.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_open_test.c new file mode 100644 index 000000000000..6033b02a1242 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_open_test.c @@ -0,0 +1,2196 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_open_test.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : touch panel circuit open test +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#include +#include "tp_open_test.h" +#include "tp_dev_control.h" +#include "test_proc.h" +#include "simple_mem_manager.h" +#include "tp_additional_option.h" +#include "tp_test_general_error_code_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static s32 clear_rawtest_res_buf(PST_TEST_ITEM p_test_item); + +/*analyze rawdata test result*/ +static s32 analyze_rawtest_res(u8 offse_and_accord_flag, + PST_TEST_ITEM p_test_item); + +/*---------------rawdata limit test------------*/ +/*modify max and min avg */ +static s32 modify_statistic_data(PST_TEST_ITEM p_test_item); +/*-----------------------------rawdata as data source end-------------------------------*/ + +/*-----------------------------diffdata as data source start-------------------------------*/ + +static s32 clear_difftest_res_buf(PST_TEST_ITEM p_test_item); + +/*analyze diffdata test result*/ +static s32 analyze_difftest_res(u8 cur_frame_id, PST_TEST_ITEM p_test_item); + +/*modify statistic data of diffdata*/ +static s32 modify_diff_statistic_data(PST_TEST_ITEM p_test_item); + +/*-----------------------------diffdata as data source end-------------------------------*/ + +/******************************************************************************* +* Function Name : rawdata_test_sets_func +* Description : rawdata test func +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : u8(0:test error 1:ok) +*******************************************************************************/ +extern s32 rawdata_test_sets_func(IN_OUT ptr32 p_data) +{ + //You can leran more details from code gtp + s32 ret = 0; + u8 i = 0; + u8 offse_and_accord_flag = 0; + u16 err_code = RAWDATA_TEST_SUCCESSFULLY; + u16 get_rawdata_timeout = 3000; + u8 max_frame_total_num = TOTAL_FRAME_NUM_MAX; + u8 cur_frame_total_num = 16; + u8 add_frame_num = 16; + u8 filter_frame_cnt = 0; + u8 filter_frame_num = 1; + u8 b_filter_data = 0; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + PST_RAWDATA_TEST_RES p_test_res = NULL; + PST_RAWDATA_TEST_CALLBACK_SET p_spec_callback_set = NULL; + PST_CUR_RAWDATA p_cur_data = NULL; + PST_TEST_PROC_DATA p_test_proc_data = NULL; + + /*-----------------Judge parameter----------------**/ + if (0 == judge_test_item_legal((PST_TEST_ITEM)p_data)) { + ret = 0; + goto EXIT_RAWDATA_TEST; + } + /*(1)callback function test before*/ + if (NULL != p_test_item->ptr_test_item_before_func) { + ret = p_test_item->ptr_test_item_before_func( + p_test_item->ptr_test_item_before_func_param); + if (ret == 0) { + board_print_error( + "[open test]callback function test before error!\n"); + err_code = TEST_BEFORE_FUNC_FAIL; + goto EXIT_RAWDATA_TEST; + } + } + p_test_proc_data = (PST_TEST_PROC_DATA)p_test_item->ptr_test_proc_data; + p_test_res = (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + /*p_test_res->item_res_header.test_item_err_code.ptr_err_code_set[0] = RAWDATA_TEST_SUCCESSFULLY; + //p_test_res->item_res_header.test_result = TEST_NG; + //p_test_res->item_res_header.test_status = TEST_START;*/ + + /*(2)clear rawdate result buf*/ + clear_rawtest_res_buf(p_test_item); + + /*(3)sending command and then get raw data.*/ + ret = chip_mode_select(p_test_item->p_tp_dev, CHIP_RAW_DATA_MODE); + if (0 == ret) { + board_print_error("enter raw data mode error!\n"); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = RAWDATA_TEST_ENTER_MODE_FAIL; + p_test_res->item_res_header.test_status = TEST_ABORTED; + err_code = RAWDATA_TEST_ENTER_MODE_FAIL; + goto RAWDATA_TEST_SETS_FUNC_END; + } + p_cur_data = (PST_CUR_RAWDATA)p_test_item->cur_data.ptr_cur_data; + p_cur_data->cur_frame_id = 0; + while (1) { + if (p_test_proc_data->test_break_flag) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = RAWDATA_TEST_BREAK_OUT; + p_test_res->item_res_header.test_status = TEST_ABORTED; + err_code = RAWDATA_TEST_BREAK_OUT; + board_print_error("rawdata test break out!\n"); + goto RAWDATA_TEST_SETS_FUNC_END; + } + /*get rawdata*/ + b_filter_data = 0; + if (filter_frame_cnt < filter_frame_num) { + b_filter_data = 1; + } + ret = board_get_rawdata(p_test_item->p_tp_dev, + get_rawdata_timeout, b_filter_data, + p_cur_data); + if (0 == ret) { + board_print_error("get rawdata error!\n"); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = + RAWDATA_TEST_GET_DATA_TIME_OUT; + p_test_res->item_res_header.test_status = TEST_ABORTED; + err_code = RAWDATA_TEST_GET_DATA_TIME_OUT; + goto RAWDATA_TEST_SETS_FUNC_END; + } + if (filter_frame_cnt < filter_frame_num) { + filter_frame_cnt++; + continue; + } + /*modify max & min & avg data*/ + modify_statistic_data(p_test_item); + + /*sub test items*/ + for (i = 0; i < p_test_item->p_sub_id_set->len; i++) { + switch (p_test_item->p_sub_id_set->p_id_set[i]) { + case TP_RAWDATA_MAX_TEST_ITEM_ID: + rawdata_max_test_func(p_data); + break; + case TP_RAWDATA_MIN_TEST_ITEM_ID: + rawdata_min_test_func(p_data); + break; + case TP_KEYDATA_MAX_TEST_ITEM_ID: + keydata_max_test_func(p_data); + break; + case TP_KEYDATA_MIN_TEST_ITEM_ID: + keydata_min_test_func(p_data); + break; + case TP_ACCORD_TEST_ITEM_ID: + rawdata_accord_test_func(p_data); + offse_and_accord_flag |= 0x01; + break; + case TP_OFFSET_TEST_ITEM_ID: + rawdata_offset_test_func(p_data); + offse_and_accord_flag |= 0x02; + break; + case TP_UNIFORMITY_TEST_ITEM_ID: + rawdata_uniform_test_func(p_data); + break; + case TP_RAWDATA_JITTER_TEST_ITEM_ID: + rawdata_jitter_test_func(p_data); + break; + default: + break; + } + } + + p_spec_callback_set = + (PST_RAWDATA_TEST_CALLBACK_SET) + p_test_item->ptr_special_callback_data; + if (NULL != p_spec_callback_set) { + /*save current data*/ + ret = p_spec_callback_set->ptr_save_cur_data_func( + p_spec_callback_set + ->ptr_save_cur_data_func_param); + if (ret == 0) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = + SAVE_CUR_DATA_ERR; + err_code = SAVE_CUR_DATA_ERR; + board_print_error( + "save current rawdata error!\n"); + } + } + /*count frame id*/ + p_cur_data->cur_frame_id++; + + p_test_res->total_frame_cnt = p_cur_data->cur_frame_id; + + /*(4)analysis result*/ + if ((cur_frame_total_num <= max_frame_total_num) && + (0 == p_cur_data->cur_frame_id % add_frame_num)) { + ret = analyze_rawtest_res(offse_and_accord_flag, + p_test_item); + if (ret == 0 || ret == 1) { + break; + } else if (ret == 2) { + cur_frame_total_num += add_frame_num; + p_test_res->open_test_result |= FIRST_TEST_FLAG; + } + } + if (p_cur_data->cur_frame_id >= max_frame_total_num) { + break; + } + } + + /*(5)clear flag*/ + p_test_res->open_test_result &= (~FIRST_TEST_FLAG); + + /*(6)modify test status*/ + p_test_res->item_res_header.test_status = TEST_FINISH; + if (p_test_res->open_test_result == 0) { + p_test_res->item_res_header.test_result = TEST_OK; + } else { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = RAWDATA_TEST_FAIL; + p_test_res->item_res_header.test_result = TEST_NG; + } +RAWDATA_TEST_SETS_FUNC_END: + + /*(7)enter coord mode*/ + ret = chip_mode_select(p_test_item->p_tp_dev, CHIP_COORD_MODE); + if (ret == 0) { + board_print_error("enter coordinate mode error!\n"); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = ENTER_COORD_MODE_ERR; + err_code = ENTER_COORD_MODE_ERR; + } +EXIT_RAWDATA_TEST: + /*(8)callback function after test finished*/ + if (NULL != p_test_item->ptr_test_item_finished_func) { + ret = p_test_item->ptr_test_item_finished_func( + p_test_item->ptr_test_item_finished_func_param); + if (ret == 0) { + board_print_error( + "[open test]callback function after test error!\n"); + err_code = TEST_FINISH_FUNC_FAIL; + } + } + + if (err_code == RAWDATA_TEST_SUCCESSFULLY) { + ret = 1; + } else { + ret = 0; + } + return ret; +} + +/******************************************************************************* +* Function Name : rawdata_max_test_func +* Description : rawdata max limit test function +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:test ng 1:test ok) +*******************************************************************************/ +extern s32 rawdata_max_test_func(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + s32 index = 0; + PST_RAWDATA_TEST_RES p_raw_test_res = NULL; + + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + p_raw_test_res = (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + + /*judge test item result*/ + if (((p_raw_test_res->open_test_result & FIRST_TEST_FLAG) != 0) && + ((p_raw_test_res->open_test_result & BEYOND_RAWDATA_UPPER_LIMIT) == + 0)) { + return ret; + } + + index = get_arr_id_from_sub_item(p_test_item, + TP_RAWDATA_MAX_TEST_ITEM_ID); + if (0xFF != index) { + u16 id = 0; + u16 node_num = 0; + s32 data_tmp = 0; + s32 para_tmp = 0; + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + node_num = p_dev->sc_sen_num * p_dev->sc_drv_num; + + /*upper limit*/ + for (id = 0; id < node_num; id++) { + if (get_chn_need_check(p_test_item, id)) { + data_tmp = get_chn_rawdata(p_test_item, id); + para_tmp = get_chn_upper_limit(p_test_item, id); + if (data_tmp > para_tmp) { + /*mark this channel beyond upper limit count*/ + p_raw_test_res + ->p_beyond_rawdata_upper_limit_cnt + [id]++; + p_raw_test_res->open_test_result |= + BEYOND_RAWDATA_UPPER_LIMIT; + p_raw_test_res->item_res_header + .test_item_err_code + .ptr_err_code_set[index + 1] = + RAWDATA_TEST_BEYOND_MAX_LIMIT; + ret = 0; + } + } + } + } + + return ret; +} + +/******************************************************************************* +* Function Name : rawdata_min_test_func +* Description : rawdata min limit test function +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:test ng 1:test ok) +*******************************************************************************/ +extern s32 rawdata_min_test_func(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + s32 index = 0; + PST_RAWDATA_TEST_RES p_raw_test_res = NULL; + + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + p_raw_test_res = (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + + /*judge test item result*/ + if (((p_raw_test_res->open_test_result & FIRST_TEST_FLAG) != 0) && + ((p_raw_test_res->open_test_result & BEYOND_RAWDATA_LOWER_LIMIT) == + 0)) { + return ret; + } + + index = get_arr_id_from_sub_item(p_test_item, + TP_RAWDATA_MIN_TEST_ITEM_ID); + if (0xFF != index) { + u16 id = 0; + u16 node_num = 0; + s32 data_tmp = 0; + s32 para_tmp = 0; + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + node_num = p_dev->sc_sen_num * p_dev->sc_drv_num; + + /*lower limit*/ + for (id = 0; id < node_num; id++) { + if (get_chn_need_check(p_test_item, id)) { + data_tmp = get_chn_rawdata(p_test_item, id); + para_tmp = get_chn_lower_limit(p_test_item, id); + if (data_tmp < para_tmp) { + /*mark this channel beyond lower limit count*/ + p_raw_test_res + ->p_beyond_rawdata_lower_limit_cnt + [id]++; + p_raw_test_res->open_test_result |= + BEYOND_RAWDATA_LOWER_LIMIT; + p_raw_test_res->item_res_header + .test_item_err_code + .ptr_err_code_set[index + 1] = + BEYOND_RAWDATA_LOWER_LIMIT; + ret = 0; + } + } + } + } + + return ret; +} + +/******************************************************************************* +* Function Name : rawdata_accord_test_func +* Description : accord test function +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:test ng 1:test ok) +*******************************************************************************/ +extern s32 rawdata_accord_test_func(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + s32 index = 0; + PST_RAWDATA_TEST_RES p_raw_test_res = NULL; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + p_raw_test_res = (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + if ((p_raw_test_res->open_test_result & FIRST_TEST_FLAG) != 0 && + (p_raw_test_res->open_test_result & BEYOND_ACCORD_LIMIT) == 0) { + return ret; + } + + index = get_arr_id_from_sub_item(p_test_item, TP_ACCORD_TEST_ITEM_ID); + if (0xFF != index) { + u16 id = 0; + u16 node_num = 0; + s32 data_tmp = 0; + s32 para_tmp = 0; + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + node_num = p_dev->sc_sen_num * p_dev->sc_drv_num; + + for (id = 0; id < node_num; id++) { + if (get_chn_need_check(p_test_item, id)) { + data_tmp = get_chn_accord(p_test_item, id); + /*/upper limit*/ + para_tmp = + get_chn_accord_limit(p_test_item, id); + if (data_tmp > para_tmp) { + /*mark this channel beyond accord limit count*/ + p_raw_test_res + ->p_beyond_accord_limit_cnt[id]++; + p_raw_test_res->open_test_result |= + BEYOND_ACCORD_LIMIT; + p_raw_test_res->item_res_header + .test_item_err_code + .ptr_err_code_set[index + 1] = + RAWDATA_TEST_BEYOND_ACCORD_LIMIT; + ret = 0; + } + } + } + } + return ret; +} + +/******************************************************************************* +* Function Name : keydata_max_test_func +* Description : keydata max limit test function +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:test ng 1:test ok) +*******************************************************************************/ +extern s32 keydata_max_test_func(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + s32 index = 0; + PST_RAWDATA_TEST_RES p_raw_test_res = NULL; + + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + p_raw_test_res = (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + + /*judge test item result*/ + if (((p_raw_test_res->open_test_result & FIRST_TEST_FLAG) != 0) && + ((p_raw_test_res->open_test_result & KEY_BEYOND_UPPER_LIMIT) == + 0)) { + return ret; + } + + index = get_arr_id_from_sub_item(p_test_item, + TP_KEYDATA_MAX_TEST_ITEM_ID); + if (0xFF != index) { + u8 id = 0; + u8 key_num = 0; + s32 data_tmp = 0; + s32 para_tmp = 0; + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + key_num = p_dev->key_num; + + /*upper limit*/ + for (id = 0; id < key_num; id++) { + if (get_key_need_check(p_test_item, id)) { + data_tmp = get_keydata(p_test_item, id); + para_tmp = get_key_upper_limit(p_test_item, id); + if (data_tmp > para_tmp) { + /*mark this channel beyond upper limit count*/ + p_raw_test_res + ->p_beyond_key_upper_limit_cnt + [id]++; + p_raw_test_res->open_test_result |= + KEY_BEYOND_UPPER_LIMIT; + p_raw_test_res->item_res_header + .test_item_err_code + .ptr_err_code_set[index + 1] = + RAWDATA_TEST_BEYOND_KEY_MAX_LIMIT; + ret = 0; + } + } + } + } + + return ret; +} + +/******************************************************************************* +* Function Name : keydata_min_test_func +* Description : keydata min limit test function +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:test ng 1:test ok) +*******************************************************************************/ +extern s32 keydata_min_test_func(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + s32 index = 0; + PST_RAWDATA_TEST_RES p_raw_test_res = NULL; + + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + p_raw_test_res = (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + + /*judge test item result*/ + if (((p_raw_test_res->open_test_result & FIRST_TEST_FLAG) != 0) && + ((p_raw_test_res->open_test_result & KEY_BEYOND_LOWER_LIMIT) == + 0)) { + return ret; + } + + index = get_arr_id_from_sub_item(p_test_item, + TP_KEYDATA_MIN_TEST_ITEM_ID); + if (0xFF != index) { + u8 id = 0; + u8 key_num = 0; + s32 data_tmp = 0; + s32 para_tmp = 0; + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + key_num = p_dev->key_num; + /*PST_SUB_TEST_ITEM_ID_SET p_sub_item_id_set = NULL; + //p_sub_item_id_set = (PST_SUB_TEST_ITEM_ID_SET)p_test_item->p_sub_id_set;*/ + + /*lower limit*/ + for (id = 0; id < key_num; id++) { + if (get_key_need_check(p_test_item, id)) { + data_tmp = get_keydata(p_test_item, id); + para_tmp = get_key_lower_limit(p_test_item, id); + if (data_tmp < para_tmp) { + /*mark this channel beyond lower limit count*/ + p_raw_test_res + ->p_beyond_key_lower_limit_cnt + [id]++; + p_raw_test_res->open_test_result |= + KEY_BEYOND_LOWER_LIMIT; + p_raw_test_res->item_res_header + .test_item_err_code + .ptr_err_code_set[index + 1] = + RAWDATA_TEST_BEYOND_KEY_MIN_LIMIT; + ret = 0; + } + } + } + } + + return ret; +} + +/******************************************************************************* +* Function Name : rawdata_jitter_test_func +* Description : rawdata jitter test function +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* : u8 cur_frame_id +* Output : none +* Return : s32(0:test ng 1:test ok) +*******************************************************************************/ +extern s32 rawdata_jitter_test_func(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + s32 index = 0; + PST_RAWDATA_TEST_RES p_raw_test_res = NULL; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + PST_CUR_RAWDATA p_cur_data = + (PST_CUR_RAWDATA)p_test_item->cur_data.ptr_cur_data; + p_raw_test_res = (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + if ((p_cur_data->cur_frame_id + 1) != 16) { + return 1; + } + + index = get_arr_id_from_sub_item(p_test_item, + TP_RAWDATA_JITTER_TEST_ITEM_ID); + if (0xFF != index) { + u16 id = 0; + s32 data_tmp = 0; + s32 para_tmp = 0; + u16 node_num = 0; + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + node_num = p_dev->sc_sen_num * p_dev->sc_drv_num; + para_tmp = get_rawdata_jitter_limit(p_test_item); + for (id = 0; id < node_num; id++) { + if (get_chn_need_check(p_test_item, id)) { + data_tmp = p_raw_test_res->p_max_raw_tmp_data + ->p_data_buf[id] - + p_raw_test_res->p_min_raw_tmp_data + ->p_data_buf[id]; + if (data_tmp > para_tmp) { + /*mark this beyond jitter limit count*/ + p_raw_test_res + ->p_beyond_jitter_limit_cnt[id] |= + 0x80; + p_raw_test_res->open_test_result |= + BEYOND_JITTER_LIMIT; + p_raw_test_res->item_res_header + .test_item_err_code + .ptr_err_code_set[index + 1] = + RAWDATA_TEST_BEYOND_JITTER_LIMIT; + ret = 0; + } + } + } + } + + return ret; +} + +/******************************************************************************* +* Function Name : rawdata_uniform_test_func +* Description : rawdata uniform test function +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:test ng 1:test ok) +*******************************************************************************/ +extern s32 rawdata_uniform_test_func(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + s32 index = 0; + PST_RAWDATA_TEST_RES p_raw_test_res = NULL; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + p_raw_test_res = (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + if ((p_raw_test_res->open_test_result & FIRST_TEST_FLAG) != 0 && + (p_raw_test_res->open_test_result & BEYOND_UNIFORMITY_LIMIT) == 0) { + return ret; + } + + index = get_arr_id_from_sub_item(p_test_item, + TP_UNIFORMITY_TEST_ITEM_ID); + if (0xFF != index) { + s32 data_tmp = 0; + s32 para_tmp = 0; + data_tmp = get_uniform_value(p_test_item); + para_tmp = get_uniform_limit(p_test_item); + + if (data_tmp < para_tmp) { + /*mark this channel beyond lower limit*/ + p_raw_test_res->beyond_uniform_limit_cnt++; + p_raw_test_res->open_test_result |= + BEYOND_UNIFORMITY_LIMIT; + p_raw_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[index + 1] = + RAWDATA_TEST_BEYOND_UNIFORM_LIMIT; + ret = 0; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : rawdata_offset_test_func +* Description : rawdata offset test function +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:test ng 1:test ok) +*******************************************************************************/ +extern s32 rawdata_offset_test_func(IN_OUT ptr32 p_data) +{ + s32 ret = 1; + s32 index = 0; + PST_RAWDATA_TEST_RES p_raw_test_res = NULL; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + p_raw_test_res = (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + if ((p_raw_test_res->open_test_result & FIRST_TEST_FLAG) != 0 && + (p_raw_test_res->open_test_result & BEYOND_OFFSET_LIMIT) == 0) { + return ret; + } + + index = get_arr_id_from_sub_item(p_test_item, TP_OFFSET_TEST_ITEM_ID); + if (0xFF != index) { + u16 id = 0; + u16 node_num = 0; + s32 data_tmp = 0; + s32 para_tmp = 0; + /*PST_SUB_TEST_ITEM_ID_SET p_sub_item_id_set = NULL;*/ + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + /*p_sub_item_id_set = (PST_SUB_TEST_ITEM_ID_SET)p_test_item->p_sub_id_set;*/ + node_num = p_dev->sc_sen_num * p_dev->sc_drv_num; + + /*(1)sending command and then get rawdata.*/ + for (id = 0; id < node_num; id++) { + data_tmp = get_chn_offset(p_test_item, id); + if (get_chn_need_check(p_test_item, id)) { + /*upper limit*/ + para_tmp = + get_chn_offset_limit(p_test_item, id); + if (data_tmp > para_tmp) { + /*//mark this channel beyond offset limit count*/ + p_raw_test_res + ->p_beyond_offset_limit_cnt[id]++; + p_raw_test_res->open_test_result |= + BEYOND_OFFSET_LIMIT; + p_raw_test_res->item_res_header + .test_item_err_code + .ptr_err_code_set[index + 1] = + RAWDATA_TEST_BEYOND_OFFSET_LIMIT; + ret = 0; + } + } + } + } + + return ret; +} + +/******************************************************************************* +* Function Name : diffdata_test_sets_func +* Description : diffdata test sets function +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 diffdata_test_sets_func(IN_OUT ptr32 p_data) +{ + /*//You can leran more details from code gtp*/ + s32 ret = 1; + u8 i = 0; + u16 get_diffdata_timeout = 3000; + u8 max_frame_total_num = 64; + u8 cur_frame_total_num = 16; + u8 add_frame_num = 16; + u8 filter_frame_cnt = 0; + u8 filter_frame_num = 1; + u8 b_filter_data = 0; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + PST_DIFFDATA_TEST_RES p_test_res = NULL; + PST_DIFFDATA_TEST_CALLBACK_SET p_spec_callback_set = NULL; + PST_CUR_DIFFDATA p_cur_data = NULL; + PST_TEST_PROC_DATA p_test_proc_data = NULL; + + /*//-----------------Judge parameter----------------*/ + if (0 == judge_test_item_legal((PST_TEST_ITEM)p_data)) { + ret = 0; + goto DIFFDATA_TEST_SETS_FUNC_END; + } + + p_test_proc_data = (PST_TEST_PROC_DATA)p_test_item->ptr_test_proc_data; + p_test_res = (PST_DIFFDATA_TEST_RES)p_test_item->test_res.ptr_res; + p_cur_data = (PST_CUR_DIFFDATA)p_test_item->cur_data.ptr_cur_data; + + /*//(1)callback function test before*/ + if (NULL != p_test_item->ptr_test_item_before_func) { + ret &= p_test_item->ptr_test_item_before_func( + p_test_item->ptr_test_item_before_func_param); + if (ret == 0) { + test_before_func_fail_proc( + &p_test_res->item_res_header); + goto DIFFDATA_TEST_SETS_FUNC_END; + } + } + /*//clear result buffer*/ + clear_difftest_res_buf(p_test_item); + + /*//sending command and then get diff data.*/ + ret = chip_mode_select(p_test_item->p_tp_dev, CHIP_DIFF_DATA_MODE); + if (0 == ret) { + board_print_error("enter diff data mode error!\n"); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = DIFFDATA_TEST_ENTER_MODE_FAIL; + p_test_res->item_res_header.test_result = TEST_NG; + p_test_res->item_res_header.test_status = TEST_ABORTED; + goto DIFFDATA_TEST_SETS_FUNC_END; + } + + p_cur_data->cur_frame_id = 0; + while (1) { + if (p_test_proc_data->test_break_flag) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = DIFFDATA_TEST_BREAK_OUT; + p_test_res->item_res_header.test_result = TEST_NG; + p_test_res->item_res_header.test_status = TEST_ABORTED; + goto DIFFDATA_TEST_SETS_FUNC_END; + } + /*//get diffdata*/ + b_filter_data = 0; + if (filter_frame_cnt < filter_frame_num) { + b_filter_data = 1; + } + ret = board_get_diffdata(p_test_item->p_tp_dev, + get_diffdata_timeout, b_filter_data, + p_cur_data); + if (0 == ret) { + board_print_error("get diffdata error!\n"); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = + DIFFDATA_TEST_GET_DATA_TIME_OUT; + p_test_res->item_res_header.test_result = TEST_NG; + p_test_res->item_res_header.test_status = TEST_ABORTED; + goto DIFFDATA_TEST_SETS_FUNC_END; + } + + if (filter_frame_cnt < filter_frame_num) { + filter_frame_cnt++; + continue; + } + + /*//statistic data modify*/ + ret = modify_diff_statistic_data(p_test_item); + /*//sub test items*/ + for (i = 0; i < p_test_item->p_sub_id_set->len; i++) { + switch (p_test_item->p_sub_id_set->p_id_set[i]) { + case TP_DIFFDATA_JITTER_TEST_ITEM_ID: + diffdata_jitter_test_func(p_data); + break; + default: + break; + } + } + + p_spec_callback_set = + (PST_DIFFDATA_TEST_CALLBACK_SET) + p_test_item->ptr_special_callback_data; + if (NULL != p_spec_callback_set) { + /*//save current data*/ + p_spec_callback_set->ptr_save_cur_data_func( + p_spec_callback_set + ->ptr_save_cur_data_func_param); + } + /*//count frame id*/ + p_cur_data->cur_frame_id++; + p_test_res->total_frame_cnt = p_cur_data->cur_frame_id; + /*//analysis result*/ + if ((cur_frame_total_num <= max_frame_total_num) && + (0 == p_cur_data->cur_frame_id % add_frame_num)) { + ret = analyze_difftest_res(p_cur_data->cur_frame_id, + p_test_item); + if (ret == 0) { + break; + } else if (ret == 1) { + p_test_res->item_res_header.test_result = + TEST_NG; + p_test_res->item_res_header.test_status = + TEST_ABORTED; + break; + } else if (ret == 2) { + cur_frame_total_num += add_frame_num; + } + } + if (p_cur_data->cur_frame_id >= max_frame_total_num) { + break; + } + } + +DIFFDATA_TEST_SETS_FUNC_END: + + /*//enter coord mode*/ + ret = chip_mode_select(p_test_item->p_tp_dev, CHIP_COORD_MODE); + if (ret == 0) { + board_print_error("enter coordinate mode error!\n"); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = ENTER_COORD_MODE_ERR; + p_test_res->item_res_header.test_result = TEST_NG; + p_test_res->item_res_header.test_status = TEST_ABORTED; + } + + if (NULL != p_test_item->ptr_test_item_finished_func) { + if (0 == + p_test_item->ptr_test_item_finished_func( + p_test_item->ptr_test_item_finished_func_param)) { + board_print_error( + "[diffdata_test_sets_func]callback function after test error!\n"); + ret = 0; + } + } + + return ret; +} + +/******************************************************************************* +* Function Name : diffdata_jitter_test_func +* Description : diffdata jitter test function +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 diffdata_jitter_test_func(IN_OUT ptr32 p_data) +{ + /*//PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data;*/ + return 1; +} + +/******************************************************************************* +* Function Name : get rawdata +* Description : get rawdata +* Input : PST_TP_DEV p_dev(device ) +* Input : u16 time_out_ms +* Input : u8 b_filter_data +* Output : OUT PST_CUR_RAWDATA p_cur_data +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 get_rawdata(IN PST_TP_DEV p_dev, IN u16 time_out_ms, + IN u8 b_filter_data, OUT PST_CUR_RAWDATA p_cur_data) +{ + s32 ret = 0; + u16 i = 0; + u8 retry_cnt = 3; + u8 data_size = 1; + u16 wait_time = 0; + s32 data_flag = 0; + if (p_dev->rawdata_option & _DATA_BIT_8) { + data_size = 1; + } else if (p_dev->rawdata_option & _DATA_BIT_16) { + data_size = 2; + } else if (p_dev->rawdata_option & _DATA_BIT_32) { + data_size = 4; + } else if (p_dev->rawdata_option & _DATA_BIT_64) { + data_size = 8; + } + + while (wait_time < time_out_ms) { + /*//Is there data ?*/ + data_flag = get_data_flag(p_dev); + board_print_debug("get rawdata flag!"); + if (data_flag) { + if (0 == b_filter_data) { + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_read( + p_dev, p_dev->rawdata_addr, + p_cur_data->p_data_buf, + p_dev->rawdata_len * data_size); + if (1 == ret) { + break; + } + } + if (0 == ret) { + board_print_error( + "read rawdata error!\n"); + goto GET_RAWDATA_END; + } + + if ((p_dev->rawdata_option & + _DATA_LARGE_ENDIAN) || + (p_dev->rawdata_option & + _DATA_DRV_SEN_INVERT)) { + reshape_data(p_dev->rawdata_option, + p_dev, p_cur_data); + } + } + /*//clear data flag*/ + ret = clr_data_flag(p_dev); + if (0 == ret) { + board_print_error("clear dataflag error!\n"); + goto GET_RAWDATA_END; + } + goto GET_RAWDATA_END; + } + board_delay_ms(5); + wait_time += 5; + } + if (data_flag == 0) { + board_print_error("get_data_flag failed\n"); + return 0; + } +GET_RAWDATA_END: + + return ret; +} + +/******************************************************************************* +* Function Name : get_diffdata +* Description : get diffdata +* Input : PST_TP_DEV p_tp_dev(device ) +* Input : u16 time_out_ms +* Input : u8 b_filter_data +* Output : PST_CUR_DIFFDATA p_cur_data +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +extern s32 get_diffdata(IN PST_TP_DEV p_dev, IN u16 time_out_ms, + IN u8 b_filter_data, IN_OUT PST_CUR_DIFFDATA p_cur_data) +{ + s32 ret = 0; + u8 i = 0; + u8 retry_cnt = 3; + u8 data_size = 0; + u16 wait_time = 0; + if (p_dev->diffdata_option & _DATA_BIT_8) { + data_size = 1; + } else if (p_dev->diffdata_option & _DATA_BIT_16) { + data_size = 2; + } else if (p_dev->diffdata_option & _DATA_BIT_32) { + data_size = 4; + } else if (p_dev->diffdata_option & _DATA_BIT_64) { + data_size = 8; + } + + while (wait_time < time_out_ms) { + /*//Is there data ?*/ + if (get_data_flag(p_dev)) { + if (0 == b_filter_data) { + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_read( + p_dev, p_dev->diffdata_addr, + (u8 *)p_cur_data->p_data_buf, + p_dev->diffdata_len * + data_size); + if (1 == ret) { + break; + } + } + + if (0 == ret) { + board_print_error( + "read diffdata error!\n"); + goto GET_DIFFDATA_END; + } + if ((p_dev->diffdata_option & + _DATA_LARGE_ENDIAN) || + (p_dev->diffdata_option & + _DATA_DRV_SEN_INVERT)) { + reshape_data(p_dev->diffdata_option, + p_dev, p_cur_data); + } + } + /*//clear data flag*/ + ret = clr_data_flag(p_dev); + if (0 == ret) { + board_print_error("clear dataflag error!\n"); + goto GET_DIFFDATA_END; + } + goto GET_DIFFDATA_END; + } + board_delay_ms(5); + wait_time += 5; + } +GET_DIFFDATA_END: + + return ret; +} + +/******************************************************************************* +* Function Name : get_data_size +* Description : get byte count of data +* Input : u8 data_option +* Output : +* Return : u8(byte cnt of data) +*******************************************************************************/ +extern u8 get_data_size(u8 data_option) +{ + u8 data_size = 2; + if (data_option & _DATA_BIT_8) { + data_size = 1; + } else if (data_option & _DATA_BIT_16) { + data_size = 2; + } else if (data_option & _DATA_BIT_32) { + data_size = 4; + } else if (data_option & _DATA_BIT_64) { + data_size = 8; + } + return data_size; +} + +/******************************************************************************* +* Function Name : reshape_data +* Description : +* Input : u8 data_option +: PST_CUR_RAWDATA p_cur_data +: PST_TP_DEV p_dev +* Output : PST_CUR_RAWDATA p_cur_data +* Return : none +*******************************************************************************/ +extern void reshape_data(IN u8 data_option, IN PST_TP_DEV p_dev, + IN_OUT PST_CUR_RAWDATA p_cur_data) +{ + u8 data_size = 2; + u8 data_tmp = 0; + u16 i = 0; + u8 j = 0; + u8 *p_buf_tmp = NULL; + u8 drv_id = 0; + u8 sen_id = 0; + u16 tmp_id = 0; + u8 *p_buf_bak = NULL; + + if (data_option & _DATA_BIT_8) { + data_size = 1; + } else if (data_option & _DATA_BIT_16) { + data_size = 2; + } else if (data_option & _DATA_BIT_32) { + data_size = 4; + } else if (data_option & _DATA_BIT_64) { + data_size = 8; + } + + p_buf_tmp = p_cur_data->p_data_buf; + /*//in arm or pc,data is little-endian in ram so we need change "large-endian" to "little-endian"*/ + if ((data_option & _DATA_LARGE_ENDIAN) && (data_size > 1)) { + for (i = 0; i < p_dev->rawdata_len * data_size; + i += data_size) { + for (j = 0; j < data_size - j; j++) { + data_tmp = p_buf_tmp[i + j]; + p_buf_tmp[i + j] = + p_buf_tmp[i + data_size - j - 1]; + p_buf_tmp[i + data_size - j - 1] = data_tmp; + } + } + } + /*//storage data in driver direction must change in sensor direction in single-chip*/ + /*//drv sen invert*/ + if ((data_option & _DATA_DRV_SEN_INVERT)) { + if (alloc_mem_block((void **)&p_buf_bak, + p_dev->rawdata_len * data_size)) { + memcpy(p_buf_bak, p_buf_tmp, + p_dev->rawdata_len * data_size); + for (i = 0; i < p_dev->sc_drv_num * p_dev->sc_sen_num; + i++) { + drv_id = i / p_dev->sc_sen_num; + sen_id = i % p_dev->sc_sen_num; + tmp_id = sen_id * p_dev->sc_drv_num + drv_id; + for (j = 0; j < data_size; j++) { + p_buf_tmp[tmp_id * data_size + j] = + p_buf_bak[i * data_size + j]; + } + } + free_mem_block(p_buf_bak); + } + } +} + +/******************************************************************************* +* Function Name : get_chn_rawdata +* Description : get specialized channel rawdata +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u16 chn_id(channel index) +* Output : none +* Return : s32 +*******************************************************************************/ +extern s32 get_chn_rawdata(IN PST_TEST_ITEM p_test_item, IN u16 chn_id) +{ + s32 ret = 0; + PST_CUR_RAWDATA p_cur_rawdata = + (PST_CUR_RAWDATA)(p_test_item->cur_data.ptr_cur_data); + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + u16 len = p_dev->sc_sen_num * p_dev->sc_drv_num; + + /*//data is little-endian after reshaping*/ + if (len > chn_id) { + if (p_dev->rawdata_option & _DATA_BIT_8) { + ret = p_cur_rawdata->p_data_buf[chn_id]; + } else if (p_dev->rawdata_option & _DATA_BIT_16) { + ret = (s16)((p_cur_rawdata->p_data_buf[chn_id * 2]) + + (p_cur_rawdata->p_data_buf[chn_id * 2 + 1] + << 8)); + } else if (p_dev->rawdata_option & _DATA_BIT_32) { + ret = (p_cur_rawdata->p_data_buf[chn_id * 4]) + + (p_cur_rawdata->p_data_buf[chn_id * 4 + 1] << 8) + + (p_cur_rawdata->p_data_buf[chn_id * 4 + 2] + << 16) + + (p_cur_rawdata->p_data_buf[chn_id * 4 + 3] << 24); + } + } + return ret; +} + +/******************************************************************************* +* Function Name : get_chn_need_check +* Description : judge specialized channel whether need check or not.we use bit +to save memory. +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u16 chn_id(channel index) +* Output : none +* Return : s32(0:not need check 1:need check) +*******************************************************************************/ +extern s32 get_chn_need_check(IN PST_TEST_ITEM p_test_item, IN u16 chn_id) +{ + s32 ret = 0; + PST_TP_DEV p_dev = NULL; + PST_RAWDATA_TEST_PARAM p_rawdata_test_param = NULL; + if (NULL == p_test_item) { + return 1; + } + p_dev = p_test_item->p_tp_dev; + p_rawdata_test_param = + (PST_RAWDATA_TEST_PARAM)(p_test_item->param.ptr_param); + if (chn_id < p_dev->sc_sen_num * p_dev->sc_drv_num) { + if (p_rawdata_test_param->p_need_check_node + ->p_data_buf[chn_id] == TP_FLAG_NEED_CHECK) { + ret = 1; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : get_chn_upper_limit +* Description : get node upper limit +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u16 chn_id(channel index) +* Output : none +* Return : s32 +*******************************************************************************/ +extern s32 get_chn_upper_limit(IN PST_TEST_ITEM p_test_item, IN u16 chn_id) +{ + s32 ret = 0; + u16 i = 0; + PST_RAWDATA_TEST_PARAM p_rawdata_test_param = + (PST_RAWDATA_TEST_PARAM)(p_test_item->param.ptr_param); + PST_RAWDATA_SPECIAL_NODE_PARAM p_spec_node = + p_rawdata_test_param->p_special_node; + + ret = p_rawdata_test_param->p_rawdata_limit->upper_limit; + for (i = 0; i < p_spec_node->data_len; i++) { + if (chn_id == p_spec_node->p_data_buf[i].node_id) { + ret = p_spec_node->p_data_buf[i].high_raw_limit; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : get_chn_lower_limit +* Description : get node lower limit +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u16 chn_id(channel index) +* Output : none +* Return : s32 +*******************************************************************************/ +extern s32 get_chn_lower_limit(IN PST_TEST_ITEM p_test_item, IN u16 chn_id) +{ + s32 ret = 0; + u16 i = 0; + PST_RAWDATA_TEST_PARAM p_rawdata_test_param = + (PST_RAWDATA_TEST_PARAM)(p_test_item->param.ptr_param); + PST_RAWDATA_SPECIAL_NODE_PARAM p_spec_node = + p_rawdata_test_param->p_special_node; + ret = p_rawdata_test_param->p_rawdata_limit->lower_limit; + for (i = 0; i < p_spec_node->data_len; i++) { + if (chn_id == p_spec_node->p_data_buf[i].node_id) { + ret = p_spec_node->p_data_buf[i].low_raw_limit; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : get_chn_accord +* Description : get chn accord(*1000) +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u16 chn_id(channel index) +* Output : none +* Return : s32 +*******************************************************************************/ +extern s32 get_chn_accord(IN PST_TEST_ITEM p_test_item, IN u16 chn_id) +{ + s32 ret = 0; + u16 accord_opt = DEF_ACCORD_CALC; + s32 tmp_data = 0x7FFFFFFF; + s32 cur_data = 0; + u8 i = 0; + s16 pos_arr[4] = { -1, -1, -1, -1 }; + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + + tmp_data = get_adjacent_node(chn_id, p_dev, pos_arr); + accord_opt = get_chn_accord_option(p_test_item, chn_id); + for (i = 0; i < 4; i++) { + /*//upon,down,left,right*/ + if (0 == (accord_opt & (1 << i))) { + pos_arr[i] = -1; + } + } + cur_data = get_chn_rawdata(p_test_item, chn_id); + for (i = 0; i < 4; i++) { + if (-1 == pos_arr[i]) { + continue; + } + tmp_data = get_chn_rawdata(p_test_item, (u16)pos_arr[i]); + tmp_data = (tmp_data - cur_data) > 0 ? (tmp_data - cur_data) : + (cur_data - tmp_data); + tmp_data = (s32)(1000 * tmp_data / cur_data); + if (tmp_data > ret) { + ret = tmp_data; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : get_chn_accord_limit +* Description : get chn accord limit(*1000) +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u16 chn_id(channel index) +* Output : none +* Return : s32 +*******************************************************************************/ +extern s32 get_chn_accord_limit(IN PST_TEST_ITEM p_test_item, IN u16 chn_id) +{ + s32 ret = 0; + u16 i = 0; + PST_RAWDATA_TEST_PARAM p_rawdata_test_param = + (PST_RAWDATA_TEST_PARAM)(p_test_item->param.ptr_param); + PST_RAWDATA_SPECIAL_NODE_PARAM p_spec_node = + p_rawdata_test_param->p_special_node; + ret = p_rawdata_test_param->p_raw_accord_limit->accord_limit; + for (i = 0; i < p_spec_node->data_len; i++) { + if (chn_id == p_spec_node->p_data_buf[i].node_id) { + ret = p_spec_node->p_data_buf[i].accord_limit; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : get_chn_accord_option +* Description : get_chn_accord_option +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u16 chn_id(channel index) +* Output : none +* Return : u16 +*******************************************************************************/ +extern u16 get_chn_accord_option(PST_TEST_ITEM p_test_item, u16 chn_id) +{ + u16 ret = DEF_ACCORD_CALC; + u16 i = 0; + PST_RAWDATA_TEST_PARAM p_rawdata_test_param = + (PST_RAWDATA_TEST_PARAM)(p_test_item->param.ptr_param); + PST_RAWDATA_SPECIAL_NODE_PARAM p_spec_node = + p_rawdata_test_param->p_special_node; + + ret = p_rawdata_test_param->p_raw_accord_limit->accord_option; + for (i = 0; i < p_spec_node->data_len; i++) { + if (chn_id == p_spec_node->p_data_buf[i].node_id) { + ret = p_spec_node->p_data_buf[i].accord_option; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : get_adjacent_node +* Description : get adjacent node +* Input : u16 node_id +: PST_TP_DEV p_dev +* Output : s16* p_arr +* Return : s32(adjacent node num) +*******************************************************************************/ +extern u8 get_adjacent_node(IN u16 node_id, IN PST_TP_DEV p_dev, OUT s16 *p_arr) +{ + u8 ret = 4; + u16 drv_id = 0; /*//col_id*/ + u16 sen_id = 0; /*//row_id*/ + + drv_id = node_id % p_dev->sc_drv_num; + sen_id = node_id / p_dev->sc_drv_num; + + p_arr[ADJ_POS_UP] = (sen_id - 1) * (p_dev->sc_drv_num) + drv_id; + p_arr[ADJ_POS_DOWN] = (sen_id + 1) * (p_dev->sc_drv_num) + drv_id; + p_arr[ADJ_POS_LEFT] = (sen_id) * (p_dev->sc_drv_num) + drv_id - 1; + p_arr[ADJ_POS_RIGHT] = (sen_id) * (p_dev->sc_drv_num) + drv_id + 1; + + if (sen_id == 0) { + p_arr[ADJ_POS_UP] = -1; + ret--; + } else if (sen_id == p_dev->sc_sen_num - 1) { + p_arr[ADJ_POS_DOWN] = -1; + ret--; + } + + if (drv_id == 0) { + p_arr[ADJ_POS_LEFT] = -1; + ret--; + } else if (drv_id == p_dev->sc_drv_num - 1) { + p_arr[ADJ_POS_RIGHT] = -1; + ret--; + } + return ret; +} + +/******************************************************************************* +* Function Name : get_chn_offset +* Description : get chn offset(*1000) +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u16 chn_id(channel index) +* Return : s32 +*******************************************************************************/ +extern s32 get_chn_offset(IN PST_TEST_ITEM p_test_item, IN u16 chn_id) +{ + s32 ret = 0; + PST_RAWDATA_TEST_RES p_raw_test_res = + (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + u16 len = p_dev->sc_sen_num * p_dev->sc_drv_num; + u32 tmp_data = 0; + u32 tmp_raw = 0; + u32 avg = 0; + if (len > chn_id) { + tmp_raw = get_chn_rawdata(p_test_item, chn_id); + avg = p_raw_test_res->raw_avg; + tmp_data = (tmp_raw - avg) > 0 ? (tmp_raw - avg) : + (avg - tmp_raw); + ret = (s32)(1000 * tmp_data / p_raw_test_res->raw_avg); + } + return ret; +} + +/******************************************************************************* +* Function Name : get_chn_offset_limit +* Description : get channel offset limit(*1000) +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u16 chn_id(channel index) +* Return : s32 +*******************************************************************************/ +extern s32 get_chn_offset_limit(IN PST_TEST_ITEM p_test_item, IN u16 chn_id) +{ + s32 ret = 0; + u16 i = 0; + PST_RAWDATA_TEST_PARAM p_rawdata_test_param = + (PST_RAWDATA_TEST_PARAM)(p_test_item->param.ptr_param); + PST_RAWDATA_SPECIAL_NODE_PARAM p_spec_node = + p_rawdata_test_param->p_special_node; + ret = p_rawdata_test_param->p_raw_offset_limit->offset_limit; + for (i = 0; i < p_spec_node->data_len; i++) { + if (chn_id == p_spec_node->p_data_buf[i].node_id) { + ret = p_spec_node->p_data_buf[i].offset_limit; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : get_keydata +* Description : get keydata +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u8 key_id(key id) +* Return : s32 +*******************************************************************************/ +extern s32 get_keydata(IN PST_TEST_ITEM p_test_item, IN u8 key_id) +{ + s32 ret = 0; + u16 tmp_id = 0; + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + PST_CUR_RAWDATA p_cur_rawdata = + (PST_CUR_RAWDATA)p_test_item->cur_data.ptr_cur_data; + + if (key_id < p_dev->key_num) { + tmp_id = p_dev->sc_sen_num * p_dev->sc_drv_num + + p_dev->key_pos_arr[key_id] - 1; + + if (p_dev->rawdata_option & _DATA_BIT_8) { + ret = p_cur_rawdata->p_data_buf[tmp_id]; + } else if (p_dev->rawdata_option & _DATA_BIT_16) { + ret = (s16)((p_cur_rawdata->p_data_buf[tmp_id * 2]) + + (p_cur_rawdata->p_data_buf[tmp_id * 2 + 1] + << 8)); + } else if (p_dev->rawdata_option & _DATA_BIT_32) { + ret = (p_cur_rawdata->p_data_buf[tmp_id * 4]) + + (p_cur_rawdata->p_data_buf[tmp_id * 4 + 1] << 8) + + (p_cur_rawdata->p_data_buf[tmp_id * 4 + 2] + << 16) + + (p_cur_rawdata->p_data_buf[tmp_id * 4 + 3] << 24); + } + } + return ret; +} +/******************************************************************************* +* Function Name : get_key_need_check +* Description : judge specialized key whether need check or not +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u16 key_id(key id) +* Return : s32(0:not need check 1:need check) +*******************************************************************************/ +extern s32 get_key_need_check(IN PST_TEST_ITEM p_test_item, IN u16 key_id) +{ + s32 ret = 0; + u16 key_pos = 0; + + PST_RAWDATA_TEST_PARAM p_rawdata_test_param = + (PST_RAWDATA_TEST_PARAM)(p_test_item->param.ptr_param); + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + + if (key_id < p_dev->key_num) { + key_pos = p_dev->key_pos_arr[key_id] - 1; + if (p_rawdata_test_param->p_raw_key_limit->p_need_check_key + ->p_data_buf[key_pos] == TP_FLAG_KEY_NEED_CHECK) { + ret = 1; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : get_key_upper_limit +* Description : get key upper limit +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u8 key_id(key id) +* Return : s32 +*******************************************************************************/ +extern s32 get_key_upper_limit(IN PST_TEST_ITEM p_test_item, IN u8 key_id) +{ + s32 ret = 0; + PST_RAWDATA_TEST_PARAM p_rawdata_test_param = + (PST_RAWDATA_TEST_PARAM)(p_test_item->param.ptr_param); + u16 i = 0; + u16 node_id; + PST_TP_DEV p_tp_dev = p_test_item->p_tp_dev; + PST_RAWDATA_SPECIAL_NODE_PARAM p_spec_node = + p_rawdata_test_param->p_special_node; + ret = p_rawdata_test_param->p_raw_key_limit->upper_limit; + for (i = 0; i < p_spec_node->data_len; i++) { + node_id = p_spec_node->p_data_buf[i].node_id; + if ((node_id >= p_tp_dev->sc_drv_num * p_tp_dev->sc_sen_num) && + node_id - p_tp_dev->sc_drv_num * p_tp_dev->sc_sen_num == + key_id) { + ret = p_spec_node->p_data_buf[i].high_raw_limit; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : get_key_lower_limit +* Description : get key lower limit +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u8 key_id(key id) +* Return : s32 +*******************************************************************************/ +extern s32 get_key_lower_limit(IN PST_TEST_ITEM p_test_item, IN u8 key_id) +{ + s16 ret = 0; + PST_RAWDATA_TEST_PARAM p_rawdata_test_param = + (PST_RAWDATA_TEST_PARAM)(p_test_item->param.ptr_param); + u16 i = 0; + u16 node_id; + PST_TP_DEV p_tp_dev = p_test_item->p_tp_dev; + PST_RAWDATA_SPECIAL_NODE_PARAM p_spec_node = + p_rawdata_test_param->p_special_node; + ret = p_rawdata_test_param->p_raw_key_limit->lower_limit; + for (i = 0; i < p_spec_node->data_len; i++) { + node_id = p_spec_node->p_data_buf[i].node_id; + if ((node_id >= p_tp_dev->sc_drv_num * p_tp_dev->sc_sen_num) && + (node_id - p_tp_dev->sc_drv_num * p_tp_dev->sc_sen_num == + key_id)) { + ret = p_spec_node->p_data_buf[i].low_raw_limit; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : get_uniform_value +* Description : get uniform value(amplify 1000) +* Input : PST_TEST_ITEM p_test_item +* Output : none +* Return : s32 +*******************************************************************************/ +extern s32 get_uniform_value(IN PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + s32 max_data_tmp = 0; + s32 min_data_tmp = 0; + s32 data_tmp = 0; + u16 i = 0; + u8 flag = 0; + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + for (i = 0; i < p_dev->sc_drv_num * p_dev->sc_sen_num; i++) { + if (get_chn_need_check(p_test_item, i)) { + data_tmp = get_chn_rawdata(p_test_item, i); + /*//Initialize max_data_tmp and min_data_tmp*/ + if (flag == 0) { + max_data_tmp = data_tmp; + min_data_tmp = max_data_tmp; + flag = 1; + } else { + /*//Update max_data_tmp*/ + if (data_tmp > max_data_tmp) { + max_data_tmp = data_tmp; + } + /*//Update min_data_tmp*/ + if (data_tmp < min_data_tmp) { + min_data_tmp = data_tmp; + } + } + } + } + + /*//avoid 0*/ + if (0 == max_data_tmp) { + max_data_tmp++; + } + if (0 == min_data_tmp) { + min_data_tmp++; + } + ret = (s32)(1000 * min_data_tmp / max_data_tmp); + return ret; +} + +/******************************************************************************* +* Function Name : get_uniform_limit +* Description : get uniform limit +* Input : PST_TEST_ITEM p_test_item +* Output : none +* Return : s32 +*******************************************************************************/ +extern s32 get_uniform_limit(IN PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_RAWDATA_TEST_PARAM p_rawdata_test_param = + (PST_RAWDATA_TEST_PARAM)(p_test_item->param.ptr_param); + ret = p_rawdata_test_param->p_raw_uniform_limit->uniform_limit; + return ret; +} + +/******************************************************************************* +* Function Name : get_rawdata_jitter_value +* Description : get rawdata jitter value limit +* Input : PST_TEST_ITEM p_test_item +* Output : none +* Return : s32 +*******************************************************************************/ +extern s32 get_rawdata_jitter_value(IN PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + s32 tmp_data = 0; + u16 i = 0; + PST_RAWDATA_TEST_RES p_raw_test_res = + (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + for (i = 0; i < p_raw_test_res->p_max_raw_tmp_data->len; i++) { + tmp_data = p_raw_test_res->p_max_raw_tmp_data->p_data_buf[i] - + p_raw_test_res->p_min_raw_tmp_data->p_data_buf[i]; + if (ret < tmp_data) { + ret = tmp_data; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : get_rawdata_jitter_limit +* Description : get rawdata jitter limit +* Input : PST_TEST_ITEM p_test_item +* Output : none +* Return : s32 +*******************************************************************************/ +extern s32 get_rawdata_jitter_limit(IN PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_RAWDATA_TEST_PARAM p_rawdata_test_param = + (PST_RAWDATA_TEST_PARAM)(p_test_item->param.ptr_param); + ret = p_rawdata_test_param->p_raw_jitter_limit->jitter_limit; + return ret; +} + +//-----------------------------diffdata as data source start-------------------------------// +// +/******************************************************************************* +* Function Name : get_chn_diffdata +* Description : get specialized channel diffdata +* Input : PST_TEST_ITEM p_test_item(item pointer) +: u16 chn_id(channel index) +* Output : none +* Return : s32 +*******************************************************************************/ +extern s32 get_chn_diffdata(PST_TEST_ITEM p_test_item, u16 chn_id) +{ + s32 ret = 0; + PST_CUR_DIFFDATA p_cur_diffdata = + (PST_CUR_DIFFDATA)(p_test_item->cur_data.ptr_cur_data); + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + u16 len = p_dev->sc_sen_num * p_dev->sc_drv_num; + + /*//data is little-endian after reshaping*/ + if (len > chn_id) { + if (p_dev->diffdata_option & _DATA_BIT_8) { + ret = p_cur_diffdata->p_data_buf[chn_id]; + } else if (p_dev->diffdata_option & _DATA_BIT_16) { + ret = (s16)((p_cur_diffdata->p_data_buf[chn_id * 2]) + + (p_cur_diffdata->p_data_buf[chn_id * 2 + 1] + << 8)); + } else if (p_dev->diffdata_option & _DATA_BIT_32) { + ret = (p_cur_diffdata->p_data_buf[chn_id * 4]) + + (p_cur_diffdata->p_data_buf[chn_id * 4 + 1] + << 8) + + (p_cur_diffdata->p_data_buf[chn_id * 4 + 2] + << 16) + + (p_cur_diffdata->p_data_buf[chn_id * 4 + 3] + << 24); + } + } + return ret; +} + +#ifdef __cplusplus +} +#endif + +/******************************************************************************* +* Function Name : init_for_buffer +* Description : initialize temp buffer with 0 +* Input : u8* p_buf +: u16 buf_size +* Output : u8* p_buf +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +static s32 init_for_buffer(u8 *p_buf, u16 buf_size) +{ + s32 ret = 1; + u16 i = 0; + for (i = 0; i < buf_size; i++) { + p_buf[i] = 0; + } + return ret; +} + +/******************************************************************************* +* Function Name : get_need_check +* Description : judge channel or key whether need check or not +* Input : PST_TEST_ITEM p_test_item +: u16 node_num +: s32 beyond_limit_status +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:not need check 1:need check) +*******************************************************************************/ +static s32 get_need_check(IN_OUT PST_TEST_ITEM p_test_item, IN u16 id, + IN s32 beyond_limit_status) +{ + if ((beyond_limit_status == KEY_BEYOND_UPPER_LIMIT) || + (beyond_limit_status == KEY_BEYOND_LOWER_LIMIT)) { + return get_key_need_check(p_test_item, id); + } else { + return get_chn_need_check(p_test_item, id); + } +} + +/******************************************************************************* +* Function Name : analyze_test_item_res +* Description : analyze rawdata subitem test result +* Input : PST_TEST_ITEM p_test_item +: s32 beyond_limit_status +: u8* p_beyond_limit_num +: u16 node_num +* Output : PST_TEST_ITEM p_test_item +* Return : s32(beyond_limit_satus:test result is unstable 0:others) +*******************************************************************************/ +static s32 analyze_test_item_res(IN_OUT PST_TEST_ITEM p_test_item, + IN s32 beyond_limit_status, + IN u8 *p_beyond_limit_cnt, IN u16 node_num) +{ + s32 ret = beyond_limit_status; + u16 id = 0; + s32 low_ratio = 10 * 0.1; + s32 high_ratio = 10 * 0.9; + PST_RAWDATA_TEST_RES p_raw_test_res = NULL; + u16 cur_frame_id = 0; + s32 tmp_open_test_result = 0; + p_raw_test_res = (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + cur_frame_id = p_raw_test_res->total_frame_cnt; + tmp_open_test_result = p_raw_test_res->open_test_result; + tmp_open_test_result &= ~beyond_limit_status; + for (id = 0; id < node_num; id++) { + if (get_need_check(p_test_item, id, beyond_limit_status)) { + if (p_beyond_limit_cnt[id] * 10 >= + high_ratio * cur_frame_id) { + p_beyond_limit_cnt[id] |= 0x80; + tmp_open_test_result |= beyond_limit_status; + ret = 0; + } else if (p_beyond_limit_cnt[id] * 10 > + low_ratio * cur_frame_id) { + p_beyond_limit_cnt[id] |= 0x80; + tmp_open_test_result |= beyond_limit_status; + if (cur_frame_id >= TOTAL_FRAME_NUM_MAX) { + ret = 0; + } + } else { + ret = 0; + } + } + } + p_raw_test_res->open_test_result = tmp_open_test_result; + return ret; +} + +/******************************************************************************* +* Function Name : clear_rawtest_res_buf +* Description : clear_rawtest_res_buf +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(1:ok 0:fail) +*******************************************************************************/ +static s32 clear_rawtest_res_buf(IN_OUT PST_TEST_ITEM p_test_item) +{ + PST_RAWDATA_TEST_RES p_test_res = + (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + PST_TP_DEV p_dev = (PST_TP_DEV)p_test_item->p_tp_dev; + u16 buf_size = p_dev->sc_drv_num * p_dev->sc_sen_num; + u16 i = 0; + u8 key_buf_size = p_dev->key_num; + PST_CUR_RAWDATA p_cur_data = + (PST_CUR_RAWDATA)p_test_item->cur_data.ptr_cur_data; + + p_cur_data->cur_frame_id = 0; + p_test_res->item_res_header.test_status = TEST_START; + p_test_res->item_res_header.test_result = TEST_NG; + for (i = 0; i < p_test_res->item_res_header.test_item_err_code.len; + i++) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[i] = RAWDATA_TEST_SUCCESSFULLY; + } + p_test_res->open_test_result = OPEN_TEST_PASS; + p_test_res->total_frame_cnt = 0; + + /*//max data record*/ + for (i = 0; i < buf_size; i++) { + p_test_res->p_max_raw_tmp_data->p_data_buf[i] = 0; + } + + /*/min data record*/ + for (i = 0; i < buf_size; i++) { + p_test_res->p_min_raw_tmp_data->p_data_buf[i] = 0x7FFFFFFF; + } + + init_for_buffer(p_test_res->p_beyond_rawdata_upper_limit_cnt, buf_size); + init_for_buffer(p_test_res->p_beyond_rawdata_lower_limit_cnt, buf_size); + init_for_buffer(p_test_res->p_beyond_jitter_limit_cnt, buf_size); + init_for_buffer(p_test_res->p_beyond_accord_limit_cnt, buf_size); + init_for_buffer(p_test_res->p_beyond_offset_limit_cnt, buf_size); + init_for_buffer(p_test_res->p_beyond_key_upper_limit_cnt, key_buf_size); + init_for_buffer(p_test_res->p_beyond_key_lower_limit_cnt, key_buf_size); + p_test_res->beyond_uniform_limit_cnt = 0; + return 1; +} + +/******************************************************************************* +* Function Name : analyze_rawtest_res +* Description : analyze rawdata test result +* Input : u8 offse_and_accord_flag +* : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:test result is pass 1:test result is fail 2:test result is unstable) +*******************************************************************************/ +static s32 analyze_rawtest_res(IN u8 offse_and_accord_flag, + IN_OUT PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + u16 i = 0; + s32 test_res_unstb = 0; + s32 test_end = 0; + u16 node_num = 0; + u8 key_num = 0; + s32 low_ratio = 10 * 0.1; + s32 high_ratio = 10 * 0.9; + u8 id_tmp = 0; + + PST_RAWDATA_TEST_RES p_test_res = NULL; + + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + node_num = p_dev->sc_sen_num * p_dev->sc_drv_num; + p_test_res = (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + key_num = p_dev->key_num; + + /*//cover error code*/ + for (i = 0; i < p_test_res->item_res_header.test_item_err_code.len; + i++) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[i] = RAWDATA_TEST_SUCCESSFULLY; + } + + /*//analyze rawdata upper limit*/ + if ((p_test_res->open_test_result & BEYOND_RAWDATA_UPPER_LIMIT) != 0) { + test_res_unstb |= analyze_test_item_res( + p_test_item, BEYOND_RAWDATA_UPPER_LIMIT, + p_test_res->p_beyond_rawdata_upper_limit_cnt, node_num); + + if (0 == (test_res_unstb & BEYOND_RAWDATA_UPPER_LIMIT) && + (p_test_res->open_test_result & + BEYOND_RAWDATA_UPPER_LIMIT) != 0) { + id_tmp = get_arr_id_from_sub_item( + p_test_item, TP_RAWDATA_MAX_TEST_ITEM_ID); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[id_tmp + 1] = + RAWDATA_TEST_BEYOND_MAX_LIMIT; + } + } + /*//analyze rawdata lower limit*/ + if ((p_test_res->open_test_result & BEYOND_RAWDATA_LOWER_LIMIT) != 0) { + test_res_unstb |= analyze_test_item_res( + p_test_item, BEYOND_RAWDATA_LOWER_LIMIT, + p_test_res->p_beyond_rawdata_lower_limit_cnt, node_num); + + if (0 == (test_res_unstb & BEYOND_RAWDATA_LOWER_LIMIT) && + (p_test_res->open_test_result & + BEYOND_RAWDATA_LOWER_LIMIT) != 0) { + id_tmp = get_arr_id_from_sub_item( + p_test_item, TP_RAWDATA_MIN_TEST_ITEM_ID); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[id_tmp + 1] = + RAWDATA_TEST_BEYOND_MIN_LIMIT; + } + } + /*//analyze key upper limit*/ + if ((p_test_res->open_test_result & KEY_BEYOND_UPPER_LIMIT) != 0) { + test_res_unstb |= analyze_test_item_res( + p_test_item, KEY_BEYOND_UPPER_LIMIT, + p_test_res->p_beyond_key_upper_limit_cnt, key_num); + + if (0 == (test_res_unstb & KEY_BEYOND_UPPER_LIMIT) && + (p_test_res->open_test_result & KEY_BEYOND_UPPER_LIMIT) != + 0) { + id_tmp = get_arr_id_from_sub_item( + p_test_item, TP_KEYDATA_MAX_TEST_ITEM_ID); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[id_tmp + 1] = + RAWDATA_TEST_BEYOND_KEY_MAX_LIMIT; + } + } + /*//analyze key lower limit*/ + if ((p_test_res->open_test_result & KEY_BEYOND_LOWER_LIMIT) != 0) { + test_res_unstb |= analyze_test_item_res( + p_test_item, KEY_BEYOND_LOWER_LIMIT, + p_test_res->p_beyond_key_lower_limit_cnt, key_num); + + if (0 == (test_res_unstb & KEY_BEYOND_LOWER_LIMIT) && + (p_test_res->open_test_result & KEY_BEYOND_LOWER_LIMIT) != + 0) { + id_tmp = get_arr_id_from_sub_item( + p_test_item, TP_KEYDATA_MIN_TEST_ITEM_ID); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[id_tmp + 1] = + RAWDATA_TEST_BEYOND_KEY_MIN_LIMIT; + } + } + /*//analyze offset limit*/ + if ((p_test_res->open_test_result & BEYOND_OFFSET_LIMIT) != 0) { + test_res_unstb |= analyze_test_item_res( + p_test_item, BEYOND_OFFSET_LIMIT, + p_test_res->p_beyond_offset_limit_cnt, node_num); + + if (0 == (test_res_unstb & BEYOND_OFFSET_LIMIT) && + (p_test_res->open_test_result & BEYOND_OFFSET_LIMIT) != 0) { + id_tmp = get_arr_id_from_sub_item( + p_test_item, TP_OFFSET_TEST_ITEM_ID); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[id_tmp + 1] = + RAWDATA_TEST_BEYOND_OFFSET_LIMIT; + } + } + + /*//analyze uniform limit*/ + if ((p_test_res->open_test_result & BEYOND_UNIFORMITY_LIMIT) != 0) { + p_test_res->open_test_result &= ~BEYOND_UNIFORMITY_LIMIT; + if (p_test_res->beyond_uniform_limit_cnt * 10 >= + high_ratio * p_test_res->total_frame_cnt) { + p_test_res->open_test_result |= BEYOND_UNIFORMITY_LIMIT; + } else if (p_test_res->beyond_uniform_limit_cnt * 10 > + low_ratio * p_test_res->total_frame_cnt) { + p_test_res->open_test_result |= BEYOND_UNIFORMITY_LIMIT; + test_res_unstb |= BEYOND_UNIFORMITY_LIMIT; + } + + if (0 == (test_res_unstb & BEYOND_UNIFORMITY_LIMIT) && + (p_test_res->open_test_result & BEYOND_UNIFORMITY_LIMIT) != + 0) { + id_tmp = get_arr_id_from_sub_item( + p_test_item, TP_UNIFORMITY_TEST_ITEM_ID); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[id_tmp + 1] = + RAWDATA_TEST_BEYOND_UNIFORM_LIMIT; + } + } + + /*//analyze accord limit*/ + if ((p_test_res->open_test_result & BEYOND_ACCORD_LIMIT) != 0) { + test_res_unstb |= analyze_test_item_res( + p_test_item, BEYOND_ACCORD_LIMIT, + p_test_res->p_beyond_accord_limit_cnt, node_num); + + if (0 == (test_res_unstb & BEYOND_ACCORD_LIMIT) && + (p_test_res->open_test_result & BEYOND_ACCORD_LIMIT) != 0) { + id_tmp = get_arr_id_from_sub_item( + p_test_item, TP_ACCORD_TEST_ITEM_ID); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[id_tmp + 1] = + RAWDATA_TEST_BEYOND_ACCORD_LIMIT; + } + } + + /*// analyze accord and offset limit*/ + if (offse_and_accord_flag == 0x03) { + u32 tmp_accord_res = 0; + for (i = 0; i < node_num; i++) { + if (get_chn_need_check(p_test_item, i)) { + if ((p_test_res->p_beyond_accord_limit_cnt[i] & + 0x80) != 0) { + if ((p_test_res->p_beyond_offset_limit_cnt + [i] & + 0x80) != 0) { + tmp_accord_res |= + BEYOND_ACCORD_LIMIT; + } else { + p_test_res + ->p_beyond_accord_limit_cnt + [i] &= 0x7f; + } + } + } + } + if (tmp_accord_res == 0) { + test_res_unstb &= ~BEYOND_ACCORD_LIMIT; + p_test_res->open_test_result &= ~BEYOND_ACCORD_LIMIT; + + id_tmp = get_arr_id_from_sub_item( + p_test_item, TP_ACCORD_TEST_ITEM_ID); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[id_tmp + 1] = + RAWDATA_TEST_SUCCESSFULLY; + } + } + + if (p_test_res->open_test_result & BEYOND_JITTER_LIMIT) { + id_tmp = get_arr_id_from_sub_item( + p_test_item, TP_RAWDATA_JITTER_TEST_ITEM_ID); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[id_tmp + 1] = + RAWDATA_TEST_BEYOND_JITTER_LIMIT; + return 1; + } + test_end = p_test_res->open_test_result; + test_end &= (~FIRST_TEST_FLAG); + if (test_end == OPEN_TEST_PASS) { + ret = 0; + } else if (test_end == test_res_unstb) { + ret = 2; + } else { + ret = 1; + } + return ret; +} + +/******************************************************************************* +* Function Name : modify_statistic_data +* Description : modify max and min avg data +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +static s32 modify_statistic_data(IN_OUT PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + u16 i = 0; + s32 curval; + u16 cnt = 0; + PST_RAWDATA_TEST_RES p_raw_test_res = + (PST_RAWDATA_TEST_RES)p_test_item->test_res.ptr_res; + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + + p_raw_test_res->raw_avg = 0; + for (i = 0; i < p_dev->rawdata_len; i++) { + if (get_chn_need_check(p_test_item, i)) { + curval = get_chn_rawdata(p_test_item, i); + p_raw_test_res->raw_avg += curval; + cnt++; + if (curval > + p_raw_test_res->p_max_raw_tmp_data->p_data_buf[i]) { + p_raw_test_res->p_max_raw_tmp_data + ->p_data_buf[i] = curval; + } + + if (curval < + p_raw_test_res->p_min_raw_tmp_data->p_data_buf[i]) { + p_raw_test_res->p_min_raw_tmp_data + ->p_data_buf[i] = curval; + } + } + } + if (0 != cnt) { + p_raw_test_res->raw_avg /= cnt; + } else { + p_raw_test_res->raw_avg = 0; + } + ret = 1; + return ret; +} + +/******************************************************************************* +* Function Name : clear_difftest_res_buf +* Description : clear_difftest_res_buf +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(1:ok 0:fail) +*******************************************************************************/ +static s32 clear_difftest_res_buf(IN_OUT PST_TEST_ITEM p_test_item) +{ + PST_DIFFDATA_TEST_RES p_test_res = + (PST_DIFFDATA_TEST_RES)p_test_item->test_res.ptr_res; + PST_TP_DEV p_dev = (PST_TP_DEV)p_test_item->p_tp_dev; + u16 buf_size = p_dev->sc_drv_num * p_dev->sc_sen_num; + u16 i = 0; + + PST_CUR_DIFFDATA p_cur_data = + (PST_CUR_DIFFDATA)p_test_item->cur_data.ptr_cur_data; + + p_cur_data->cur_frame_id = 0; + p_test_res->item_res_header.test_status = TEST_START; + p_test_res->item_res_header.test_result = TEST_OK; + for (i = 0; i < p_test_res->item_res_header.test_item_err_code.len; + i++) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[i] = DIFFDATA_TEST_SUCCESSFULLY; + } + p_test_res->total_frame_cnt = 0; + + /*//max data record*/ + for (i = 0; i < buf_size && i < p_test_res->p_max_diff_tmp_data->len; + i++) { + p_test_res->p_max_diff_tmp_data->p_data_buf[i] = 0; + } + return 1; +} + +/******************************************************************************* +* Function Name : analyze_difftest_res +* Description : analyze diffdata test result +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:test result is pass 1:test result is fail 2:test result is unstable) +*******************************************************************************/ +static s32 analyze_difftest_res(u8 cur_frame_id, PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + u16 i = 0; + u16 node_num = 0; + u8 id_tmp = 0; + + PST_DIFFDATA_TEST_RES p_test_res = NULL; + PST_DIFFDATA_TEST_PARAM p_param = NULL; + PST_TEST_ITEM p_raw_data_test_item = NULL; + PST_TP_DEV p_dev = NULL; + get_test_item_from_proc_data( + (PST_TEST_PROC_DATA)p_test_item->ptr_test_proc_data, + TP_RAWDATA_TEST_ITEMS_SET_ID, &p_raw_data_test_item); + + p_param = (PST_DIFFDATA_TEST_PARAM)p_test_item->param.ptr_param; + p_test_res = (PST_DIFFDATA_TEST_RES)p_test_item->test_res.ptr_res; + p_dev = p_test_item->p_tp_dev; + node_num = p_dev->sc_sen_num * p_dev->sc_drv_num; + + /*//cover error code*/ + for (i = 0; i < p_test_res->item_res_header.test_item_err_code.len; + i++) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[i] = DIFFDATA_TEST_SUCCESSFULLY; + } + + /*//diff jitter test */ + id_tmp = get_arr_id_from_sub_item(p_test_item, + TP_DIFFDATA_JITTER_TEST_ITEM_ID); + for (i = 0; i < node_num; i++) { + /*//share need_check_node with item 'TP_RAWDATA_TEST_ITEMS_SET_ID'*/ + if (get_chn_need_check(p_raw_data_test_item, i)) { + if (p_test_res->p_max_diff_tmp_data->p_data_buf[i] > + p_param->p_diff_jitter_limit->diff_jitter_limit) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[id_tmp + 1] = + DIFFTEST_JITTER_BEYOND_LIMIT; + ret = 1; + break; + } + } + } + return ret; +} + +/******************************************************************************* +* Function Name : modify_diff_statistic_data +* Description : modify statistic data of diffdata +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +static s32 modify_diff_statistic_data(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + u16 i = 0; + s32 curval; + PST_DIFFDATA_TEST_RES p_test_res = + (PST_DIFFDATA_TEST_RES)p_test_item->test_res.ptr_res; + + PST_TP_DEV p_dev = p_test_item->p_tp_dev; + PST_TEST_ITEM p_raw_data_test_item = NULL; + get_test_item_from_proc_data( + (PST_TEST_PROC_DATA)p_test_item->ptr_test_proc_data, + TP_RAWDATA_TEST_ITEMS_SET_ID, &p_raw_data_test_item); + + if (NULL == p_test_res->p_max_diff_tmp_data) { + goto MODIFY_END; + } + + for (i = 0; i < p_dev->diffdata_len; i++) { + /*//share need_check_node with item 'TP_RAWDATA_TEST_ITEMS_SET_ID'*/ + if (get_chn_need_check(p_raw_data_test_item, i)) { + curval = get_chn_diffdata(p_test_item, i); + if (curval > + p_test_res->p_max_diff_tmp_data->p_data_buf[i]) { + p_test_res->p_max_diff_tmp_data->p_data_buf[i] = + curval; + } + } + } + ret = 1; + +MODIFY_END: + return ret; +} + +/*//-----------------------------diffdata as data source end-------------------------------*/ + +#endif \ No newline at end of file diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_open_test.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_open_test.h new file mode 100644 index 000000000000..d146f7b589b2 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_open_test.h @@ -0,0 +1,227 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_open_test.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : touch panel circuit open test +data 1-dimension means drv data +data 2-dimension means sen data + +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef TP_OPEN_TEST_H +#define TP_OPEN_TEST_H + +#include "tp_open_test_param.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*//rawdata test sets error code define*/ +#define RAWDATA_TEST_SUCCESSFULLY 0 + +#define RAWDATA_TEST_BREAK_OUT 1 +#define GET_RAW_PARAM_ERR 2 +#define SEND_TEST_CONFIG_ERR 3 +#define RAWDATA_TEST_ENTER_MODE_FAIL 4 +#define RAWDATA_TEST_SUB_ITEM_ERR 5 +#define RAWDATA_TEST_GET_BUF_FAIL 6 +#define RAWDATA_TEST_GET_DATA_TIME_OUT 7 +#define RAWDATA_TEST_GET_RES_BUF_FAIL 8 +#define OPEN_HOPPING_ERR 9 +#define ENTER_COORD_MODE_ERR 10 +#define SAVE_CUR_DATA_ERR 11 + +#define RAWDATA_TEST_BEYOND_MAX_LIMIT 12 +#define RAWDATA_TEST_BEYOND_MIN_LIMIT 13 +#define RAWDATA_TEST_BEYOND_PARAM_LIMIT 14 + +#define RAWDATA_TEST_BEYOND_KEY_MAX_LIMIT 15 +#define RAWDATA_TEST_BEYOND_KEY_MIN_LIMIT 16 +#define RAWDATA_TEST_BEYOND_KEY_PARAM_LIMIT 17 + +#define RAWDATA_TEST_BEYOND_ACCORD_LIMIT 18 +#define RAWDATA_TEST_BEYOND_OFFSET_LIMIT 19 +#define RAWDATA_TEST_BEYOND_UNIFORM_LIMIT 20 +#define RAWDATA_TEST_BEYOND_JITTER_LIMIT 21 +#define RAWDATA_TEST_FAIL 22 + +/*//diffdata error code*/ +#define DIFFDATA_TEST_SUCCESSFULLY 0 +#define DIFFDATA_TEST_BREAK_OUT 1 +#define GET_DIFF_PARAM_ERR 2 +#define DIFFDATA_TEST_ENTER_MODE_FAIL 3 +#define DIFFDATA_TEST_BEFORE_FUNC_FAIL 4 +#define DIFFDATA_TEST_GET_DATA_TIME_OUT 5 +#define DIFFTEST_JITTER_BEYOND_LIMIT 6 + +/*//Max Frame NUm*/ +#define TOTAL_FRAME_NUM_MAX 64 + +/*//current rawdata define*/ +typedef struct CUR_RAWDATA { + u8 cur_frame_id; + u16 data_len; /*//rawdata len*/ + u8 *p_data_buf; /*//storage rawdata by byte*/ +} ST_CUR_RAWDATA, *PST_CUR_RAWDATA; + +/*//-------------------------------------RAWDATA TEST RESULT SATRT-------------------------------------*/ +/*//rawdata test tmp data*/ +typedef struct RAW_TMP_DATA { + u16 len; + s32 *p_data_buf; +} ST_RAW_TMP_DATA, *PST_RAW_TMP_DATA; + +#define OPEN_TEST_PASS 0x0000 +#define BEYOND_RAWDATA_UPPER_LIMIT 0x0001 +#define BEYOND_RAWDATA_LOWER_LIMIT 0x0002 +#define KEY_BEYOND_UPPER_LIMIT 0x1000 +#define KEY_BEYOND_LOWER_LIMIT 0x2000 +#define BEYOND_ACCORD_LIMIT 0x0004 +#define BEYOND_OFFSET_LIMIT 0x0008 +#define BEYOND_JITTER_LIMIT 0x0010 +#define BEYOND_UNIFORMITY_LIMIT 0x00800000 +#define FIRST_TEST_FLAG 0x80000000 +/*//rawdata test result*/ +typedef struct RAWDATA_TEST_RES { + ST_TEST_ITEM_RES item_res_header; + s32 raw_avg; + u8 total_frame_cnt; + + PST_RAW_TMP_DATA p_max_raw_tmp_data; + PST_RAW_TMP_DATA p_min_raw_tmp_data; + /*//test item test fail count*/ + u8 *p_beyond_rawdata_upper_limit_cnt; + u8 *p_beyond_rawdata_lower_limit_cnt; + u8 *p_beyond_jitter_limit_cnt; + u8 *p_beyond_accord_limit_cnt; + u8 *p_beyond_offset_limit_cnt; + u8 *p_beyond_key_upper_limit_cnt; + u8 *p_beyond_key_lower_limit_cnt; + u8 beyond_uniform_limit_cnt; + /*//the highest bit set if need another test*/ + s32 open_test_result; + +} ST_RAWDATA_TEST_RES, *PST_RAWDATA_TEST_RES; + +/*//rawdata test special callback set*/ +typedef struct RAWDATA_TEST_CALLBACK_SET { + TEST_CALLBACK_PTR ptr_save_cur_data_func; + ptr32 ptr_save_cur_data_func_param; +} ST_RAWDATA_TEST_CALLBACK_SET, *PST_RAWDATA_TEST_CALLBACK_SET; +/*//-------------------------------------RAWDATA TEST RESULT END-------------------------------------*/ + +typedef ST_CUR_RAWDATA ST_CUR_DIFFDATA; +typedef PST_CUR_RAWDATA PST_CUR_DIFFDATA; + +typedef ST_RAWDATA_TEST_CALLBACK_SET ST_DIFFDATA_TEST_CALLBACK_SET; +typedef PST_RAWDATA_TEST_CALLBACK_SET PST_DIFFDATA_TEST_CALLBACK_SET; + +typedef ST_RAW_TMP_DATA ST_DIFF_TMP_DATA; +typedef PST_RAW_TMP_DATA PST_DIFF_TMP_DATA; + +/*//-------------------------------------DIFFDATA TEST RESULT SATRT-------------------------------------*/ +/*//diffdata test result*/ +typedef struct DIFFDATA_TEST_RES { + ST_TEST_ITEM_RES item_res_header; + u8 total_frame_cnt; + + PST_DIFF_TMP_DATA p_max_diff_tmp_data; +} ST_DIFFDATA_TEST_RES, *PST_DIFFDATA_TEST_RES; +/*//-------------------------------------DIFFDATA TEST RESULT END-------------------------------------*/ + +/*************************************Public methods start********************************************/ + +/*//-----------------------------rawdata as data source---------------------------*/ + +/*//rawdata test */ +extern s32 rawdata_test_sets_func(ptr32 p_data); + +/*//sub test items*/ +/*//rawdata test function*/ +extern s32 rawdata_max_test_func(ptr32 p_data); +extern s32 rawdata_min_test_func(ptr32 p_data); +/*//accord test function*/ +extern s32 rawdata_accord_test_func(ptr32 p_data); +/*//keydata test function*/ +extern s32 keydata_max_test_func(ptr32 p_data); +extern s32 keydata_min_test_func(ptr32 p_data); +/*//rawdata jitter test function*/ +extern s32 rawdata_jitter_test_func(ptr32 p_data); +/*//rawdata uniform test function*/ +extern s32 rawdata_uniform_test_func(ptr32 p_data); +/*//rawdata offset test function*/ +extern s32 rawdata_offset_test_func(ptr32 p_data); + +/*//get rawdata*/ +extern s32 get_rawdata(PST_TP_DEV p_tp_dev, u16 time_out_ms, u8 b_filter_data, + PST_CUR_RAWDATA p_cur_data); + +/*//-----------------------------diffdata as data source---------------------------*/ +extern s32 diffdata_test_sets_func(ptr32 p_data); +extern s32 diffdata_jitter_test_func(ptr32 p_data); + +/*//get diffdata */ +extern s32 get_diffdata(PST_TP_DEV p_dev, u16 time_out_ms, u8 b_filter_data, + PST_CUR_DIFFDATA p_cur_data); + +/*//judge specialized channel whether need check or not*/ +extern s32 get_chn_need_check(PST_TEST_ITEM p_test_item, u16 chn_id); + +/*//get specialized channel rawdata*/ +extern s32 get_chn_rawdata(PST_TEST_ITEM p_test_item, u16 chn_id); +/*//rawdata_limit_test_func parameter*/ +extern s32 get_chn_upper_limit(PST_TEST_ITEM p_test_item, u16 chn_id); +extern s32 get_chn_lower_limit(PST_TEST_ITEM p_test_item, u16 chn_id); + +extern u8 get_adjacent_node(u16 node_id, PST_TP_DEV p_dev, s16 *p_arr); +/*//---------------accord test------------*/ +/*//get chn accord(*1000)*/ +extern s32 get_chn_accord(PST_TEST_ITEM p_test_item, u16 chn_id); +/*//1000*/ +extern s32 get_chn_accord_limit(PST_TEST_ITEM p_test_item, u16 chn_id); +extern u16 get_chn_accord_option(PST_TEST_ITEM p_test_item, u16 chn_id); + +/*//-----------------keydata test--------------------*/ +/*//get keydata*/ +extern s32 get_keydata(IN PST_TEST_ITEM p_test_item, IN u8 key_id); +/*//judge specialized key whether need check or not*/ +extern s32 get_key_need_check(PST_TEST_ITEM p_test_item, u16 key_id); +/*//key parameter limit*/ +extern s32 get_key_upper_limit(PST_TEST_ITEM p_test_item, u8 key_id); +extern s32 get_key_lower_limit(PST_TEST_ITEM p_test_item, u8 key_id); + +/*//-----------------uniform test-------------------*/ +extern s32 get_uniform_value(PST_TEST_ITEM p_test_item); +extern s32 get_uniform_limit(PST_TEST_ITEM p_test_item); + +/*//---------------rawdata jitter test---------------*/ +extern s32 get_rawdata_jitter_value(PST_TEST_ITEM p_test_item); +extern s32 get_rawdata_jitter_limit(PST_TEST_ITEM p_test_item); +extern s32 get_chn_offset(IN PST_TEST_ITEM p_test_item, IN u16 chn_id); +extern s32 get_chn_offset_limit(IN PST_TEST_ITEM p_test_item, IN u16 chn_id); + +/*//reshape data*/ +extern void reshape_data(u8 data_option, PST_TP_DEV p_tp_dev, + PST_CUR_RAWDATA p_cur_data); +extern u8 get_data_size(u8 data_option); + +/*//get specialized channel diffdata*/ +extern s32 get_chn_diffdata(PST_TEST_ITEM p_test_item, u16 chn_id); + +/*************************************Public methods end********************************************/ +#ifdef __cplusplus +} +#endif +/*************************************private methods start********************************************/ +/*//-----------------------------rawdata as data source start---------------------------------*/ +/*//get adjacent node*/ +#define ADJ_POS_UP 0 +#define ADJ_POS_DOWN 1 +#define ADJ_POS_LEFT 2 +#define ADJ_POS_RIGHT 3 +/*************************************private methods end********************************************/ +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_open_test_param.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_open_test_param.h new file mode 100644 index 000000000000..ce8d6bb10bc9 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_open_test_param.h @@ -0,0 +1,132 @@ +#ifndef TP_OPEN_TEST_PARAM_H +#define TP_OPEN_TEST_PARAM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "user_test_type_def.h" +#include "test_item_def.h" + +/*//need check node define*/ +typedef struct NEED_CHECK_NODE { + u16 data_len; + u8 *p_data_buf; +} ST_NEED_CHECK_NODE, *PST_NEED_CHECK_NODE; + +/*//----------accord_option----------*/ +#define ACCORD_CALC_UPON 0x0001 +#define ACCORD_CALC_DOWN 0x0002 +#define ACCORD_CALC_LEFT 0x0004 +#define ACCORD_CALC_RIGHT 0x0008 + +#define DEF_ACCORD_CALC \ + (ACCORD_CALC_UPON | ACCORD_CALC_DOWN | ACCORD_CALC_LEFT | \ + ACCORD_CALC_RIGHT) + +/*//special node define*/ +typedef struct SPECIAL_NODE_DEF { + u16 node_id; + s32 high_raw_limit; + s32 low_raw_limit; + s32 accord_limit; + s32 offset_limit; + u16 accord_option; +} ST_SPECIAL_NODE_DEF, *PST_SPECIAL_NODE_DEF; + +/*//rawdata special node parameter define*/ +typedef struct RAWDATA_SPECIAL_NODE_PARAM { + u16 data_len; + PST_SPECIAL_NODE_DEF p_data_buf; +} ST_RAWDATA_SPECIAL_NODE_PARAM, *PST_RAWDATA_SPECIAL_NODE_PARAM; + +/*//rawdata limit test parameter*/ +typedef struct RAWDATA_LIMIT_PARAM { + s32 upper_limit; + s32 lower_limit; +} ST_RAWDATA_LIMIT_PARAM, *PST_RAWDATA_LIMIT_PARAM; + +/*//rawdata accord limit test parameter*/ +typedef struct RAW_ACCORD_LIMIT_PARAM { + s32 accord_limit; + u16 accord_option; +} ST_RAW_ACCORD_LIMIT_PARAM, *PST_RAW_ACCORD_LIMIT_PARAM; + +/*//rawdata offset limit test parameter*/ +typedef struct RAW_OFFSET_LIMIT_PARAM { + s32 offset_limit; +} ST_RAW_OFFSET_LIMIT_PARAM, *PST_RAW_OFFSET_LIMIT_PARAM; + +/*//rawdata jitter limit test parameter*/ +typedef struct RAW_JITTER_LIMIT_PARAM { + s32 jitter_limit; +} ST_RAW_JITTER_LIMIT_PARAM, *PST_RAW_JITTER_LIMIT_PARAM; + +/*//rawdata uniform limit test parameter*/ +typedef struct RAW_UNIFORM_LIMIT_PARAM { + s32 uniform_limit; +} ST_RAW_UNIFORM_LIMIT_PARAM, *PST_RAW_UNIFORM_LIMIT_PARAM; + +/*//rawdata key limit test parameter*/ +typedef struct NEED_CHECK_KEY { + u16 len; + u8 *p_data_buf; +} ST_NEED_CHECK_KEY, *PST_NEED_CHECK_KEY; +typedef struct RAW_KEY_LIMIT_PARAM { + s32 upper_limit; + s32 lower_limit; + PST_NEED_CHECK_KEY p_need_check_key; +} ST_RAW_KEY_LIMIT_PARAM, *PST_RAW_KEY_LIMIT_PARAM; + +/*//this struct is used for +(1)rawdata limit test +(2)accord limit test +(3)offset limit test +(4)rawdata jitter test +(5)uniform test +(6)key test +rawdata limit paramter define*/ +typedef struct RAWDATA_TEST_PARAM { + /*//In arm,the pointers follows below equal flash address + //In Pc,the pointers point special struct*/ + + /*//need check node*/ + PST_NEED_CHECK_NODE p_need_check_node; + + /*//special node*/ + PST_RAWDATA_SPECIAL_NODE_PARAM p_special_node; + + /*//rawdata limit parameter*/ + PST_RAWDATA_LIMIT_PARAM p_rawdata_limit; + + /*//rawdata acoord limit parameter*/ + PST_RAW_ACCORD_LIMIT_PARAM p_raw_accord_limit; + + /*//raw offset limit parameter*/ + PST_RAW_OFFSET_LIMIT_PARAM p_raw_offset_limit; + + /*//raw jitter limit parameter*/ + PST_RAW_JITTER_LIMIT_PARAM p_raw_jitter_limit; + + /*//raw uniform limit parameter*/ + PST_RAW_UNIFORM_LIMIT_PARAM p_raw_uniform_limit; + + /*//keydata limit parameter*/ + PST_RAW_KEY_LIMIT_PARAM p_raw_key_limit; + +} ST_RAWDATA_TEST_PARAM, *PST_RAWDATA_TEST_PARAM; + +/*//diff jitter limit parameter*/ +typedef struct DIFF_JITTER_LIMIT_PARAM { + s32 diff_jitter_limit; +} ST_DIFF_JITTER_LIMIT_PARAM, *PST_DIFF_JITTER_LIMIT_PARAM; + +/*//diffdata test parameter*/ +typedef struct DIFFDATA_TEST_PARAM { + PST_DIFF_JITTER_LIMIT_PARAM p_diff_jitter_limit; +} ST_DIFFDATA_TEST_PARAM, *PST_DIFFDATA_TEST_PARAM; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_product_id_def.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_product_id_def.h new file mode 100644 index 000000000000..1bc85b42283c --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_product_id_def.h @@ -0,0 +1,66 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_product_id_def.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 12/31/2017 +* Description : touch panel product id define +*******************************************************************************/ +#ifndef TP_PRODUCT_ID_DEF_H +#define TP_PRODUCT_ID_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*//this file must be used in arm code +//define chip main type +//we plan use 2 bytes store it,so we can distinguish 65536 chip main types.*/ +#define TP_GT900 0x0000 +#define TP_GT9P 0x0001 +#define TP_GT9L 0x0002 +#define TP_GT9PT 0x0003 +#define TP_BOSTON 0x0004 +#define TP_NANJING 0x0005 +#define TP_NORMANDY 0x0006 +#define TP_ALTO 0x0007 +#define TP_PHOENIX 0x0008 +#define TP_OSLO 0x0009 +#define TP_NORMANDY_L 0x000A + +/*//we plan use two bytes store it,so we can distinguish 65536 chip sub types.*/ +/*//TP_GT900 sub type*/ +#define TP_GT915 0x0000 +#define TP_GT9157 0x0001 + +/*//TP_GT9P sub type*/ +#define TP_GT1151 0x0000 +#define TP_GT9286 0x0001 + +/*//TP_GT9L sub type*/ +#define TP_GT5668 0x0000 +#define TP_GT5663 0x0001 +#define TP_GT5688 0x0002 + +/*//TP_GT9PT sub type*/ +#define TP_GT1158 0x0000 +#define TP_GT7288 0x0001 + +/*//TP_NORMANDY sub type*/ +#define TP_GT9886 0x0001 /*//normal iic*/ +#define TP_GT9886S 0x0002 /*//GT9886S spi*/ + +/*//TP_PHOENIX sub type*/ +#define TP_GT7387P 0x0001 +#define TP_GT7385P 0x0002 +#define TP_GT7389 0x0003 +#define TP_GT7387 0x0004 +#define TP_GT7385 0x0005 + +/*//TP_OSLO sub type*/ +#define TP_GT6861 0x0001 +#define TP_GT6861P 0x0002 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_short_test.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_short_test.c new file mode 100644 index 000000000000..55b5af0d9058 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_short_test.c @@ -0,0 +1,460 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : short_test_func.c +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : We use this file unify a interface for short test +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#include "simple_mem_manager.h" +#include "tp_short_test.h" + +#include "normandy_short_test.h" +#include "tp_test_general_error_code_def.h" +#include "test_proc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* +* Function Name : short_test_func +* Description : short test +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : s32(0:test error 1:ok) +*******************************************************************************/ +extern s32 short_test_func(IN_OUT ptr32 p_data) +{ + s32 ret = 0; + u16 err_code = SHORT_TEST_NONE_ERROR; + PST_TEST_ITEM p_test_item = (PST_TEST_ITEM)p_data; + PST_SHORT_TEST_RES p_test_res = NULL; + + /*//-----------------Judge parameter----------------*/ + if (0 == judge_test_item_legal((PST_TEST_ITEM)p_data)) { + ret = 0; + goto SHORTTEST_END; + } + /*//prepared for test*/ + if (NULL != p_test_item->ptr_test_item_before_func) { + ret = p_test_item->ptr_test_item_before_func( + p_test_item->ptr_test_item_before_func_param); + if (0 == ret) { + board_print_error( + "[short test]callback function test before error!\n"); + err_code = TEST_BEFORE_FUNC_FAIL; + goto SHORTTEST_END; + } + } + + p_test_res = (PST_SHORT_TEST_RES)p_test_item->test_res.ptr_res; + p_test_res->item_res_header.test_item_err_code.ptr_err_code_set[0] = + SHORT_TEST_NONE_ERROR; + p_test_res->item_res_header.test_status = TEST_START; + p_test_res->item_res_header.test_result = TEST_NG; + + ret = board_disable_dev_status(p_test_item->p_tp_dev); + if (0 == ret) { + board_print_error("[short test]disable device status faild!\n"); + err_code = DISABLE_DEV_STATUS_FAIL; + goto SHORTTEST_END; + } + /*//selecting different branch according to chip id*/ + switch (p_test_item->p_tp_dev->chip_type) { + case TP_NORMANDY: + case TP_OSLO: { + ret = normandy_short_test(p_data); + } break; + default: + board_print_warning( + "chip type (%d) is not exist, please check it", + p_test_item->p_tp_dev->chip_type); + err_code = CHIP_TYPE_NOT_EXIST; + break; + } + err_code = p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0]; + +SHORTTEST_END: + + /*// recovery chip on normal mode*/ + ret = short_test_end(p_test_item); + if (ret == 0) { + board_print_warning("[short test]recovry chip status error!\n"); + err_code = SHORT_TEST_END_FAIL; + } + /*//notify test result*/ + if (p_test_item->ptr_test_item_finished_func) { + ret = p_test_item->ptr_test_item_finished_func( + p_test_item->ptr_test_item_finished_func_param); + if (ret == 0) { + board_print_error( + "[short test]callback function after test error!\n"); + err_code = TEST_FINISH_FUNC_FAIL; + } + } + if ((err_code == SHORT_TEST_NONE_ERROR) || + (err_code == SHORT_TEST_EXIST_SHORT)) { + ret = 1; + } else { + ret = 0; + } + + return ret; +} + +/******************************************************************************* +* Function Name : clear_short_mess_in_res +* Description : clear_short_mess_in_res +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 clear_short_mess_in_res(IN_OUT PST_TEST_ITEM p_test_item) +{ + PST_SHORT_TEST_RES p_short_res = + (PST_SHORT_TEST_RES)p_test_item->test_res.ptr_res; + p_short_res->short_num = 0; + p_short_res->item_res_header.test_id = p_test_item->test_item_id; + p_short_res->item_res_header.test_status = TEST_START; + p_short_res->item_res_header.test_result = TEST_OK; + p_short_res->item_res_header.test_item_err_code.ptr_err_code_set[0] = + SHORT_TEST_NONE_ERROR; + return 1; +} + +/******************************************************************************* +* Function Name : store_short_mess_in_res +* Description : store short message in result +* Input : s32 chn1 +* Input : s32 chn2 +* Input : u16 r +* Output : PST_SHORT_TEST_RES p_short_res +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 store_short_mess_in_res(IN u8 chn1, IN u8 chn2, IN u16 r, + OUT PST_SHORT_TEST_RES p_short_res) +{ + s32 ret = 0; + u8 i = 0; + u8 repeat_cnt = 0; + u8 repeat = 0; + if (chn1 == chn2 || p_short_res->short_num >= MAX_SHORT_NUM) { + goto STORE_END; + } + /*//filter repeating data*/ + for (i = 0; i < p_short_res->short_num; i++) { + repeat_cnt = 0; + if (p_short_res->short_mess_arr[4 * i + 0] == chn1) { + repeat_cnt++; + } + + if (p_short_res->short_mess_arr[4 * i + 0] == chn2) { + repeat_cnt++; + } + + if (p_short_res->short_mess_arr[4 * i + 1] == chn1) { + repeat_cnt++; + } + + if (p_short_res->short_mess_arr[4 * i + 1] == chn2) { + repeat_cnt++; + } + if (repeat_cnt >= 2) { + repeat = 1; + } + } + if (repeat == 0) { + p_short_res->short_mess_arr[4 * p_short_res->short_num + 0] = + chn1; + p_short_res->short_mess_arr[4 * p_short_res->short_num + 1] = + chn2; + p_short_res->short_mess_arr[4 * p_short_res->short_num + 2] = + (r >> 8) & 0xFF; + p_short_res->short_mess_arr[4 * p_short_res->short_num + 3] = + r & 0xFF; + if (p_short_res->short_num < MAX_SHORT_NUM) { + p_short_res->short_num++; + } + ret = 1; + } + +STORE_END: + return ret; +} + +/******************************************************************************* +* Function Name : short_test_channel_map +* Description : +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Input : ENUM_CHN_MAP_MODE chn_enum +* Output : none +* Return : void +*******************************************************************************/ +extern void short_test_channel_map(IN ptr32 p_data, + IN ENUM_CHN_MAP_MODE chn_enum) +{ + u8 i = 0; + u8 j = 0; + u8 k = 0; + u8 ch_cnt = 0; + PST_TEST_ITEM p_item = NULL; + PST_SHORT_TEST_RES p_short_res = NULL; + PST_TP_DEV p_dev = NULL; + u8 b_find = 0; + u8 ic_chn_num; + u8 valid_chn_mark[4 * MAX_SHORT_NUM]; + u8 *p_short_mess_tmp = NULL; + + p_item = (PST_TEST_ITEM)p_data; + p_short_res = (PST_SHORT_TEST_RES)p_item->test_res.ptr_res; + p_dev = p_item->p_tp_dev; + + if (p_dev->map_disable == 1) { + return; + } + + memset(valid_chn_mark, 0x00, 4 * p_short_res->short_num); + + for (i = 0; i < p_short_res->short_num * 4; i++) { + if (i % 4 == 2 || i % 4 == 3) { + continue; + } + + switch (chn_enum) { + case TX_RX_SHARED: { + b_find = 0; + j = p_short_res->short_mess_arr[i] & (~CHANNEL_TX_FLAG); + + if (0 == b_find) { + for (ch_cnt = 0; ch_cnt < p_dev->max_drv_num; + ch_cnt++) { + if (p_dev->drv_map[ch_cnt] == j) { + p_short_res->short_mess_arr[i] = + CHANNEL_TX_FLAG | + ch_cnt; + valid_chn_mark[i] = 1; + b_find = 1; + break; + } + } + } + + if (0 == b_find) { + for (ch_cnt = 0; ch_cnt < p_dev->max_sen_num; + ch_cnt++) { + if (p_dev->sen_map[ch_cnt] == j) { + p_short_res->short_mess_arr[i] = + ch_cnt; + valid_chn_mark[i] = 1; + b_find = 1; + break; + } + } + } + } break; + case TX_RX_PACK_ADC: { + j = p_short_res->short_mess_arr[i]; + if ((j & CHANNEL_TX_FLAG) == + CHANNEL_TX_FLAG) { /*//Drv Chancel*/ + + j = j & (~CHANNEL_TX_FLAG); + for (ch_cnt = 0; ch_cnt < p_dev->max_drv_num; + ch_cnt++) { + if (p_dev->drv_map[ch_cnt] == j) { + ic_chn_num = + p_dev->pack_drv_2_adc_map + [ch_cnt]; + if (ch_cnt < + (p_dev->max_drv_num / + 2)) { /*//the first G1 chancel*/ + + for (k = 0; + k < + (p_dev->max_drv_num / + 2); + k++) { + if (p_dev->cfg + [p_dev->drv_start_addr - + p_dev->cfg_start_addr + + k] == + ic_chn_num) { + p_short_res + ->short_mess_arr + [i] = + CHANNEL_TX_FLAG | + j; + valid_chn_mark + [i] = 1; + break; + } + } + } else { /*//the second G1 chancel*/ + for (k = 0; + k < + p_dev->max_drv_num / + 2; + k++) { + if (p_dev->cfg + [p_dev->drv1_start_addr - + p_dev->cfg_start_addr + + k] == + ic_chn_num) { + p_short_res + ->short_mess_arr + [i] = + CHANNEL_TX_FLAG | + j; //((p_dev->max_drv_num / 2) + k); + valid_chn_mark + [i] = 1; + break; + } + } + } + break; + } + } /*//end for (ch_cnt = 0; ch_cnt < p_dev->max_drv_num; ch_cnt++)*/ + } else { /*// Sen Chancel*/ + + for (ch_cnt = 0; ch_cnt < p_dev->max_sen_num; + ch_cnt++) { + if (p_dev->sen_map[ch_cnt] == j) { + ic_chn_num = + p_dev->pack_sen_2_adc_map + [ch_cnt]; + if (ch_cnt < + (p_dev->max_sen_num / + 2)) { /*//the first G1 chancel*/ + for (k = 0; + k < + (p_dev->max_sen_num / + 2); + k++) { + if (p_dev->cfg + [p_dev->sen_start_addr - + p_dev->cfg_start_addr + + k] == + ic_chn_num) { + p_short_res + ->short_mess_arr + [i] = + j; + valid_chn_mark + [i] = 1; + break; + } + } + } else { /*//the second G1 chancel*/ + for (k = 0; + k < + p_dev->max_sen_num / + 2; + k++) { + if (p_dev->cfg + [p_dev->sen1_start_addr - + p_dev->cfg_start_addr + + k] == + ic_chn_num) { + p_short_res + ->short_mess_arr + [i] = + j; /*//(p_dev->max_sen_num / 2) + k;*/ + valid_chn_mark + [i] = 1; + break; + } + } + } + break; + } + } /*//end for (ch_cnt = 0; ch_cnt < p_dev->max_sen_num; ch_cnt++)*/ + } + } break; + case TX_RX_SEPERATION: + default: { + if ((p_short_res->short_mess_arr[i] & + CHANNEL_TX_FLAG) == CHANNEL_TX_FLAG) { + j = p_short_res->short_mess_arr[i] & + (~CHANNEL_TX_FLAG); + for (ch_cnt = 0; ch_cnt < p_dev->max_drv_num; + ch_cnt++) { + if (p_dev->drv_map[ch_cnt] == j) { + p_short_res->short_mess_arr[i] = + CHANNEL_TX_FLAG | + ch_cnt; + valid_chn_mark[i] = 1; + break; + } + } + } else { + j = p_short_res->short_mess_arr[i]; + for (ch_cnt = 0; ch_cnt < p_dev->max_sen_num; + ch_cnt++) { + if (p_dev->sen_map[ch_cnt] == j) { + p_short_res->short_mess_arr[i] = + ch_cnt; + valid_chn_mark[i] = 1; + break; + } + } + } + } break; + } /*// end switch (chn_enum)*/ + } /*//end for(i = 0; ishort_num*4; i++)*/ + + /*//check the short valid or not*/ + ic_chn_num = 0; + p_short_mess_tmp = &p_short_res->short_mess_arr[0]; + for (i = 0; i < p_short_res->short_num * 4; i += 4) { + if ((valid_chn_mark[i] != 1 && + p_short_mess_tmp[0] != CHANNEL_GND && + p_short_mess_tmp[0] != CHANNEL_VDD) || + (valid_chn_mark[i + 1] != 1 && + p_short_mess_tmp[1] != CHANNEL_GND && + p_short_mess_tmp[1] != CHANNEL_VDD)) { + if (p_short_res->short_num * 4 - i - 4 >= 4) { + memcpy(p_short_mess_tmp, p_short_mess_tmp + 4, + p_short_res->short_num * 4 - (i + 4)); + } + } else { + ic_chn_num++; + p_short_mess_tmp += 4; + } + } + p_short_res->short_num = ic_chn_num; + if (p_short_res->short_num == 0) { + p_short_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = SHORT_TEST_NONE_ERROR; + p_short_res->item_res_header.test_result = TEST_OK; + } +} + +/******************************************************************************* +* Function Name : short_test_end +* Description : (1)open esd and irq (2)reset chip +* Input : PST_TEST_ITEM p_test_item +* Output : none +* Return : s32(0:have not handled 1:handled) +*******************************************************************************/ +extern s32 short_test_end(PST_TEST_ITEM p_test_item) +{ + s32 ret = 1; + if (board_recovery_dev_status(p_test_item->p_tp_dev) == 0) { + ret = 0; + } + + if (reset_chip_proc(p_test_item->p_tp_dev, RESET_TO_AP) == 0) { + board_print_error("reset tp error!\n"); + ret = 0; + } + return ret; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_short_test.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_short_test.h new file mode 100644 index 000000000000..f03e07e500c5 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_short_test.h @@ -0,0 +1,79 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : short_test_func.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : We use this file unify a interface for short test +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef TP_SHORT_TEST_H +#define TP_SHORT_TEST_H + +#include "tp_dev_def.h" +#include "tp_short_test_param.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SHORT_TEST_NONE_ERROR 0x00 +#define SHORT_TEST_PARAMETER_ERROR 0x01 +#define SHORT_TEST_DOWNLOAD_FW_FAIL 0x02 +#define SHORT_TEST_RUN_FW_FAIL 0x03 +#define SHORT_TEST_SEND_PARAMETER_FAIL 0x04 +#define SHORT_TEST_END_FAIL 0x05 +#define SHORT_TEST_EXIST_SHORT 0x06 +#define SHORT_TEST_ANALYSIS_RESULT_FAIL 0x07 +#define SHORT_TEST_WRITE_LINE_SEQ_FAIL 0x08 +#define WAIT_SHORT_CODE_RUN_FINISHED_ERROR 0x09 +#define SHORT_TEST_RECOVERY_CHIP_ERROR 0x09 +#define DISABLE_DEV_STATUS_FAIL 0x0A + +/*//short res*/ +/*//bit7=1 means Tx,bit7==0 means Rx*/ +#define CHANNEL_TX_FLAG 0x80 + +/*//exclude 0x7f and 0xff from 0~0xff,so we can use 254 ids stand for channel*/ +#define CHANNEL_GND 0x7f +#define CHANNEL_VDD 0xff + +#define MAX_SHORT_NUM 15 +typedef struct SHORT_TEST_RES { + ST_TEST_ITEM_RES item_res_header; + u8 short_num; + /*//byte1:chn1 + //byte2:chn2 + //byte3~4:resistence,unit 0.1Kom*/ + u8 short_mess_arr[4 * MAX_SHORT_NUM]; +} ST_SHORT_TEST_RES, *PST_SHORT_TEST_RES; +typedef const ST_SHORT_TEST_RES CST_SHORT_TEST_RES; +typedef const PST_SHORT_TEST_RES CPST_SHORT_TEST_RES; + +/*************************************Public methods start********************************************/ +/*//short test*/ +extern s32 short_test_func(ptr32 p_data); + +extern s32 clear_short_mess_in_res(PST_TEST_ITEM p_test_item); +/*//store short message in result*/ +extern s32 store_short_mess_in_res(u8 chn1, u8 chn2, u16 r, + PST_SHORT_TEST_RES p_short_res); + +typedef enum SHORT_CHN_MAP_ENUM { + TX_RX_SEPERATION = 0x00, + TX_RX_SHARED = 0x01, + TX_RX_PACK_ADC = 0x02 +} ENUM_CHN_MAP_MODE; +extern void short_test_channel_map(ptr32 p_data, ENUM_CHN_MAP_MODE chn_enum); +extern s32 short_test_end(PST_TEST_ITEM p_test_item); + +/*************************************Public methods end********************************************/ + +/*************************************Private methods start********************************************/ + +/*************************************Private methods end********************************************/ +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_short_test_param.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_short_test_param.h new file mode 100644 index 000000000000..5b3e88281e99 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_short_test_param.h @@ -0,0 +1,56 @@ +#ifndef TP_SHORT_TEST_PARAM_H +#define TP_SHORT_TEST_PARAM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "user_test_type_def.h" +#include "test_item_def.h" + +/*//short test threshold parameter*/ +typedef struct SHORT_THRESHOLD_PARAM { + u16 drv_gnd_vdd_resistor_threshold; + u16 sen_gnd_vdd_resistor_threshold; + u16 sen_sen_resistor_threshold; + u16 drv_drv_resistor_threshold; + u16 drv_sen_resistor_threshold; + + u16 gt_short_threshold; + u16 adc_read_delay; + u16 diffcode_short_threshold; + u16 tx_tx_factor; + u16 tx_rx_factor; + u16 rx_rx_factor; + +} ST_SHORT_THRESHOLD_PARAM, *PST_SHORT_THRESHOLD_PARAM; + +/*//short bin*/ +typedef struct SHORT_BIN_PARAM { + u32 update_bin_len; + union { + u32 bin_addr; + u8 *bin_ptr; + } update_bin_addr; + +} ST_SHORT_BIN_PARAM, *PST_SHORT_BIN_PARAM; + +/*//short option*/ +typedef struct SHORT_OPTION { + u16 len; + union { + u32 opt_u32; + u8 *opt_ptr; + } opt; +} ST_SHORT_OPTION, *PST_SHORT_OPTION; + +typedef struct SHORT_PARAM { + ST_SHORT_THRESHOLD_PARAM short_threshold; + ST_SHORT_BIN_PARAM short_bin; + ST_SHORT_OPTION short_opt; +} ST_SHORT_PARAM, *PST_SHORT_PARAM; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_general_error_code_def.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_general_error_code_def.h new file mode 100644 index 000000000000..a01893889608 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_general_error_code_def.h @@ -0,0 +1,35 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_test_general_error_code_def.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 03/30/2018 +* Description : general error code start with 0x8000 +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef TP_TEST_GENERAL_ERROR_CODE_DEF_H +#define TP_TEST_GENERAL_ERROR_CODE_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*//--------------------------------------------test item error code define start------------------------------------------------//*/ +#define ERROR_CODE_NONE 0 /*//ok*/ +#define PROCESS_BREAK_OUT 0x8001 /*//process break out*/ +#define PARAMETER_ERRROR 0x8002 /*//parameter error*/ +#define COMMUNICATION_ERROR 0x8003 /*//communication error*/ +#define MEMORY_ACCESS_ERROR 0x8004 /*//memory access error*/ +#define POINTER_ERROR 0x8005 /*//pointer error*/ +#define TEST_BEFORE_FUNC_FAIL 0x8006 /*//test before function fail*/ +#define TEST_FINISH_FUNC_FAIL 0x8007 /*//test finshed function fail*/ +#define TEST_RST_OPR_FAIL 0x8008 /*//test rst operation fail*/ +#define CHIP_TYPE_NOT_EXIST 0x8009 /*//chip type is not exist*/ + +/*//--------------------------------------------test item error code define start------------------------------------------------//*/ + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_buf_mem.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_buf_mem.c new file mode 100644 index 000000000000..64ffdbae3b00 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_buf_mem.c @@ -0,0 +1,216 @@ +/******************** (C) COPYRIGHT 2017 Goodix ******************** +* File Name : TpTestItemResultMemProc.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 01/11/2018 +* Description : Tp Test Item Result Memory Process +*******************************************************************************/ + +#include "tp_test_item_mem.h" +#include "test_proc.h" +#include "simple_mem_manager.h" +#include "tp_open_test.h" +#include "tp_short_test.h" +#include "tp_version_test.h" + +#ifdef __cplusplus +extern "C" { +#endif +/******************************************************************************* +* Function Name : alloc_test_item_cur_buf +* Description : alloc_test_item_cur_buf +* Input : none +* Output : none +* Return : s32(1:ok false:fail) +*******************************************************************************/ +extern s32 alloc_test_item_cur_buf(PST_TEST_ITEM *pp_test_item, u16 item_num) +{ + s32 bRet = 0; + u32 i = 0; + for (i = 0; i < item_num; i++) { + PST_TEST_ITEM pTestItem = pp_test_item[i]; + switch (pTestItem->test_item_id) { + /*//----------------------tp open test-----------------------//*/ + case TP_RAWDATA_TEST_ITEMS_SET_ID: { + } break; + + case TP_DIFFDATA_TEST_ITEMS_SET_ID: { + } break; + + /*//----------------------hardware test-----------------------//*/ + case TP_SHORT_TEST_ITEM_ID: { + } break; + + case TP_RST_VOLT_TEST_ITEM_ID: { + } break; + + case TP_I2C_VOLT_TEST_ITEM_ID: { + } break; + + case TP_INT_VOLT_TEST_ITEM_ID: { + } break; + case TP_ACTIVE_CURRENT_TEST_ITEM_ID: { + } break; + + case TP_SLEEP_CURRENT_TEST_ITEM_ID: { + } break; + + case TP_INT_CAP_TEST_ITEM_ID: { + } break; + + case TP_MODULE_TYPE_TEST_ITEM_ID: { + } break; + + case TP_PIN1_TEST_ITEM_ID: { + } break; + + case TP_PIN2_TEST_ITEM_ID: { + } break; + + /*//----------------------firmware test-----------------------//*/ + case TP_VERSION_TEST_ITEM_ID: { + } break; + case TP_CHK_FW_RUN_STATE_ITEM_ID: { + } break; + + /*//----------------line test or key touch test---------------//*/ + case TP_KEY_TOUCH_TEST_ITEM_ID: { + } break; + + case TP_LINE_TEST_ITEM_ID: { + } break; + + /*//----------------------other test-----------------------//*/ + case TP_CHIP_CFG_PROC_ITEM_ID: { + } break; + + case TP_FLASH_TEST_ITEM_ID: { + } break; + + case TP_SEND_SPEC_CFG_ITEM_ID: { + } break; + + case TP_UPDATE_SPEC_FW_ITEM_ID: { + } break; + + case TP_CUSTOM_INFO_TEST_ITEM_ID: { + } break; + + case TP_CHK_CHIP_TEST_RESULT_ITEM_ID: { + } break; + case TP_CHK_MODULE_TEST_RESULT_ITEM_ID: { + } break; + case TP_RECOVER_CFG_ITEM_ID: { + } break; + case TP_SAVE_RES_TO_IC_STORAGE_ITEM_ID: { + } break; + + default: + break; + } + } + bRet = 1; + + return bRet; +} + +/******************************************************************************* +* Function Name : free_test_item_cur_buf +* Description : free_test_item_cur_buf +* Input : PST_TEST_ITEM* pp_test_item +* Output : u16 item_num +* Return : s32(1:ok false:fail) +*******************************************************************************/ +extern s32 free_test_item_cur_buf(PST_TEST_ITEM *pp_test_item, u16 item_num) +{ + s32 bRet = 0; + u32 i = 0; + for (i = 0; i < item_num; i++) { + PST_TEST_ITEM pTestItem = pp_test_item[i]; + switch (pTestItem->test_item_id) { + /*//----------------------tp open test-----------------------//*/ + case TP_RAWDATA_TEST_ITEMS_SET_ID: { + } break; + + case TP_DIFFDATA_TEST_ITEMS_SET_ID: { + } break; + + /*//----------------------hardware test-----------------------//*/ + case TP_SHORT_TEST_ITEM_ID: { + } break; + + case TP_RST_VOLT_TEST_ITEM_ID: { + } break; + + case TP_I2C_VOLT_TEST_ITEM_ID: { + } break; + + case TP_INT_VOLT_TEST_ITEM_ID: { + } break; + case TP_ACTIVE_CURRENT_TEST_ITEM_ID: { + } break; + + case TP_SLEEP_CURRENT_TEST_ITEM_ID: { + } break; + + case TP_INT_CAP_TEST_ITEM_ID: { + } break; + + case TP_MODULE_TYPE_TEST_ITEM_ID: { + } break; + + case TP_PIN1_TEST_ITEM_ID: { + } break; + + case TP_PIN2_TEST_ITEM_ID: { + } break; + + /*//----------------------firmware test-----------------------//*/ + case TP_VERSION_TEST_ITEM_ID: { + } break; + case TP_CHK_FW_RUN_STATE_ITEM_ID: { + } break; + + /*//----------------line test or key touch test---------------//*/ + case TP_KEY_TOUCH_TEST_ITEM_ID: { + } break; + + case TP_LINE_TEST_ITEM_ID: { + } break; + + /*//----------------------other test-----------------------//*/ + case TP_CHIP_CFG_PROC_ITEM_ID: { + } break; + + case TP_FLASH_TEST_ITEM_ID: { + } break; + + case TP_SEND_SPEC_CFG_ITEM_ID: { + } break; + + case TP_UPDATE_SPEC_FW_ITEM_ID: { + } break; + case TP_CUSTOM_INFO_TEST_ITEM_ID: { + } break; + + case TP_CHK_CHIP_TEST_RESULT_ITEM_ID: { + } break; + case TP_CHK_MODULE_TEST_RESULT_ITEM_ID: { + } break; + case TP_RECOVER_CFG_ITEM_ID: { + } break; + case TP_SAVE_RES_TO_IC_STORAGE_ITEM_ID: { + } break; + + default: + break; + } + } + bRet = 1; + + return bRet; +} + +#ifdef __cplusplus +} +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_buf_mem.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_buf_mem.h new file mode 100644 index 000000000000..c93edae94472 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_buf_mem.h @@ -0,0 +1,22 @@ +/******************** (C) COPYRIGHT 2017 Goodix ******************** +* File Name : tp_test_item_buf_mem.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 01/11/2018 +* Description : Tp Test Item Current Buffer Memory Process +*******************************************************************************/ +#ifndef TP_TEST_ITEM_BUF_MEM_H +#define TP_TEST_ITEM_BUF_MEM_H + +#include "test_item_def.h" + +#ifdef __cplusplus +extern "C" { +#endif +s32 alloc_test_item_cur_buf(PST_TEST_ITEM *pp_test_item, u16 item_num); +s32 free_test_item_cur_buf(PST_TEST_ITEM *pp_test_item, u16 item_num); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_id.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_id.h new file mode 100644 index 000000000000..c1f27aaff78d --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_id.h @@ -0,0 +1,86 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : tp_test_item_id.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 12/31/2017 +* Description : touch panel test item id + //-----------------Very Important--------------------// + You can not modify each micro define,because this define + will be recorded in doc and send to custom. +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef TP_TEST_ITEM_ID_H +#define TP_TEST_ITEM_ID_H + +#ifdef __cplusplus +extern "C" { +#endif +/*//touch panel project start with TP*/ + +/*//device information ID may occupy 0~4 reserved ID*/ +#define TP_DEV_INFO_ID 0 + +/*//--------------------------------------------test item Id define start------------------------------------------------//*/ +/*//test item ID define 0~4 reserved*/ +#define TP_TEST_ITEM_START_ID 5 +/*//data test*/ +#define TP_RAWDATA_TEST_ITEMS_SET_ID 5 +#define TP_RAWDATA_MAX_TEST_ITEM_ID 0 +#define TP_RAWDATA_MIN_TEST_ITEM_ID 1 +#define TP_KEYDATA_MAX_TEST_ITEM_ID 2 +#define TP_KEYDATA_MIN_TEST_ITEM_ID 3 +#define TP_ACCORD_TEST_ITEM_ID 4 +#define TP_OFFSET_TEST_ITEM_ID 5 +#define TP_UNIFORMITY_TEST_ITEM_ID 6 +#define TP_RAWDATA_JITTER_TEST_ITEM_ID 7 + +#define TP_DIFFDATA_TEST_ITEMS_SET_ID 6 +#define TP_DIFFDATA_JITTER_TEST_ITEM_ID 0 + +/*//hardware test*/ +#define TP_SHORT_TEST_ITEM_ID 200 +#define TP_RST_VOLT_TEST_ITEM_ID 201 +#define TP_I2C_VOLT_TEST_ITEM_ID 202 +#define TP_INT_VOLT_TEST_ITEM_ID 203 +#define TP_PIN1_TEST_ITEM_ID 204 +#define TP_PIN2_TEST_ITEM_ID 205 + +#define TP_ACTIVE_CURRENT_TEST_ITEM_ID 206 +#define TP_SLEEP_CURRENT_TEST_ITEM_ID 207 +#define TP_INT_CAP_TEST_ITEM_ID 208 +#define TP_MODULE_TYPE_TEST_ITEM_ID 209 +#define TP_GESTURE_TEST_ITEM_ID 210 +#define TP_SPI_VOLT_TEST_ITEM_ID 211 + +/*//firmware test*/ +#define TP_VERSION_TEST_ITEM_ID 600 +#define TP_CHK_FW_RUN_STATE_ITEM_ID 601 + +/*//line test or key touch test*/ +#define TP_KEY_TOUCH_TEST_ITEM_ID 800 +#define TP_LINE_TEST_ITEM_ID 801 + +/*//other test*/ +#define TP_CHIP_CFG_PROC_ITEM_ID \ + 1200 /*/cfg check,check cfg in chip whether ok or not,or send config*/ +#define TP_FLASH_TEST_ITEM_ID \ + 1201 /*//flash test using send cfg ,reset chip,then read and compare cfg*/ +#define TP_SEND_SPEC_CFG_ITEM_ID 1202 /*//after test send special config*/ +#define TP_UPDATE_SPEC_FW_ITEM_ID 1203 /*//after test update special firmware*/ +#define TP_CUSTOM_INFO_TEST_ITEM_ID \ + 1204 /*//custom information:including write information or check information*/ +#define TP_CHK_CHIP_TEST_RESULT_ITEM_ID 1205 /*//check chip test result*/ +#define TP_CHK_MODULE_TEST_RESULT_ITEM_ID 1206 /*//check module test result*/ +#define TP_RECOVER_CFG_ITEM_ID 1207 /*//recovery config to chip*/ +#define TP_SAVE_RES_TO_IC_STORAGE_ITEM_ID 1208 /*//save result to ic storage*/ +#define TP_CHIP_UID_PROCESS_ITEM_ID 1209 /*//tp chip uid process*/ + +#define TP_TEST_SUB_ITEM_END_ID 0xFF +#define TP_TEST_ITEM_END_ID 0xFFFF +/*//--------------------------------------------test item Id define end------------------------------------------------//*/ +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_mem.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_mem.c new file mode 100644 index 000000000000..19215c0b0159 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_mem.c @@ -0,0 +1,932 @@ +/******************** (C) COPYRIGHT 2017 Goodix ******************** +* File Name : tp_test_item_mem.cpp +* Author : Bob Huang +* Version : V1.0.0 +* Date : 01/11/2018 +* Description : Tp Test Item Result Memory Process +*******************************************************************************/ + +#include "tp_test_item_mem.h" +#include "test_proc.h" +#include "simple_mem_manager.h" +#include "tp_open_test.h" +#include "tp_short_test.h" +#include "tp_version_test.h" +#include "tp_additional_option.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static s32 init_for_buffer(u8 *p_buf, u16 buf_size); + +/******************************************************************************* +* Function Name : alloc_test_item_res +* Description : alloc test item res +* Input : none +* Output : none +* Return : s32(1:ok 0:fail) +*******************************************************************************/ +s32 alloc_test_item_res(PST_TEST_ITEM *pp_test_item, u16 item_num) +{ + s32 ret = 0; + u16 i = 0; + for (i = 0; i < item_num; i++) { + PST_TEST_ITEM p_test_item = pp_test_item[i]; + switch (p_test_item->test_item_id) { + /*//----------------------tp open test-----------------------//*/ + case TP_RAWDATA_TEST_ITEMS_SET_ID: { + if (1 == alloc_rawdata_test_item_res(p_test_item)) { + ret = 1; + } + } break; + + case TP_DIFFDATA_TEST_ITEMS_SET_ID: { + if (1 == alloc_diffdata_test_item_res(p_test_item)) { + ret = 1; + } + } break; + + /*//----------------------hardware test-----------------------//*/ + case TP_SHORT_TEST_ITEM_ID: { + if (1 == alloc_short_test_item_res(p_test_item)) { + ret = 1; + } + } break; + + /*//----------------------firmware test-----------------------//*/ + case TP_VERSION_TEST_ITEM_ID: { + if (1 == alloc_version_test_item_res(p_test_item)) { + ret = 1; + } + } break; + + /*//----------------------other test-----------------------//*/ + case TP_CHIP_CFG_PROC_ITEM_ID: { + if (1 == alloc_chip_cfg_proc_item_res(p_test_item)) { + ret = 1; + } + } break; + + case TP_FLASH_TEST_ITEM_ID: { + if (1 == alloc_flash_test_item_res(p_test_item)) { + ret = 1; + } + } break; + + case TP_RECOVER_CFG_ITEM_ID: { + if (1 == alloc_recover_cfg_item_res(p_test_item)) { + ret = 1; + } + } break; + default: + break; + } + } + ret = 1; + return ret; +} + +/******************************************************************************* +* Function Name : free_test_item_res +* Description : free test item res +* Input : none +* Output : none +* Return : s32(1:ok 0:fail) +*******************************************************************************/ +s32 free_test_item_res(PST_TEST_ITEM *pp_test_item, u16 item_num) +{ + s32 ret = 0; + u16 i = 0; + for (i = 0; i < item_num; i++) { + PST_TEST_ITEM p_test_item = pp_test_item[i]; + switch (p_test_item->test_item_id) { + /*//----------------------tp open test-----------------------//*/ + case TP_RAWDATA_TEST_ITEMS_SET_ID: { + if (1 == free_rawdata_test_item_res(p_test_item)) { + ret = 1; + } + } break; + + case TP_DIFFDATA_TEST_ITEMS_SET_ID: { + if (1 == free_diffdata_test_item_res(p_test_item)) { + ret = 1; + } + } break; + + /*//----------------------hardware test-----------------------//*/ + case TP_SHORT_TEST_ITEM_ID: { + if (1 == free_short_test_item_res(p_test_item)) { + ret = 1; + } + } break; + + /*//----------------------firmware test-----------------------//*/ + case TP_VERSION_TEST_ITEM_ID: { + if (1 == free_version_test_item_res(p_test_item)) { + ret = 1; + } + } break; + /*//----------------------other test-----------------------//*/ + case TP_CHIP_CFG_PROC_ITEM_ID: { + if (1 == free_chip_cfg_proc_item_res(p_test_item)) { + ret = 1; + } + } break; + + case TP_FLASH_TEST_ITEM_ID: { + if (1 == free_flash_test_item_res(p_test_item)) { + ret = 1; + } + } break; + + case TP_RECOVER_CFG_ITEM_ID: { + if (1 == free_recover_cfg_item_res(p_test_item)) { + ret = 1; + } + } break; + default: + break; + } + } + ret = 1; + return ret; +} + +/******************************************************************************* +* Function Name : alloc_item_res_header +* Description : alloc_item_res_header +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +s32 alloc_item_res_header(IN_OUT PST_TEST_ITEM p_test_item) +{ + P_TEST_ITEM_RES p_item_res_header = NULL; + p_item_res_header = (P_TEST_ITEM_RES)p_test_item->test_res.ptr_res; + + /*//default initialization*/ + p_item_res_header->test_id = p_test_item->test_item_id; + p_item_res_header->test_status = TEST_START; + p_item_res_header->test_result = TEST_OK; + + /*//item_res_header.p_sub_id_set*/ + if (NULL != p_test_item->p_sub_id_set) { + if (alloc_mem_in_heap( + (void **)&(p_item_res_header->p_sub_id_set), + sizeof(ST_SUB_TEST_ITEM_ID_SET))) { + p_item_res_header->p_sub_id_set->len = + p_test_item->p_sub_id_set->len; + if (alloc_mem_in_heap( + (void **)&(p_item_res_header->p_sub_id_set + ->p_id_set), + p_item_res_header->p_sub_id_set->len * + sizeof(u8))) { + memcpy(p_item_res_header->p_sub_id_set->p_id_set, + p_test_item->p_sub_id_set->p_id_set, + p_test_item->p_sub_id_set->len); + } + } + /*//item_res_header.test_item_err_code.ptr_err_code_set*/ + p_item_res_header->test_item_err_code.len = + p_test_item->p_sub_id_set->len + + 1; /*//each sub test for 1byte,maybe modify in future*/ + alloc_mem_in_heap( + (void **)&(p_item_res_header->test_item_err_code + .ptr_err_code_set), + p_item_res_header->test_item_err_code.len * + sizeof(u16)); + memset(p_item_res_header->test_item_err_code.ptr_err_code_set, + 0, p_item_res_header->test_item_err_code.len); + } else { + p_item_res_header->p_sub_id_set = NULL; + p_item_res_header->test_item_err_code.len = + 1; /*//main test for 1byte,maybe modify in future*/ + alloc_mem_in_heap( + (void **)&(p_item_res_header->test_item_err_code + .ptr_err_code_set), + p_item_res_header->test_item_err_code.len * + sizeof(u16)); + memset(p_item_res_header->test_item_err_code.ptr_err_code_set, + 0, + p_item_res_header->test_item_err_code.len * sizeof(u16)); + } + + return 1; +} + +/******************************************************************************* +* Function Name : free_item_res_header +* Description : free_item_res_header +* Input : PST_TEST_ITEM p_test_item +: u16 buf_size +* Output : +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +s32 free_item_res_header(IN_OUT PST_TEST_ITEM p_test_item) +{ + P_TEST_ITEM_RES p_item_res_header = NULL; + p_item_res_header = (P_TEST_ITEM_RES)p_test_item->test_res.ptr_res; + + if (NULL != p_item_res_header->test_item_err_code.ptr_err_code_set) { + free_mem_in_heap((void *)p_item_res_header->test_item_err_code + .ptr_err_code_set); + p_item_res_header->test_item_err_code.ptr_err_code_set = NULL; + } + + if (NULL != p_item_res_header->p_sub_id_set) { + if (NULL != p_item_res_header->p_sub_id_set->p_id_set) { + free_mem_in_heap((void *)p_item_res_header->p_sub_id_set + ->p_id_set); + p_item_res_header->p_sub_id_set->p_id_set = NULL; + } + free_mem_in_heap((void *)p_item_res_header->p_sub_id_set); + p_item_res_header->p_sub_id_set = NULL; + } + return 1; +} + +/******************************************************************************* +* Function Name : alloc_rawdata_test_item_res +* Description : alloc_rawdata_test_item_res +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +s32 alloc_rawdata_test_item_res(IN_OUT PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + u16 i = 0; + + PST_TP_DEV p_tp_dev = p_test_item->p_tp_dev; + u16 buf_size = p_tp_dev->sc_drv_num * p_tp_dev->sc_sen_num; + u8 key_buf_size = p_tp_dev->key_num; + u8 data_byte = 0; + PST_RAWDATA_TEST_RES *pp_rawdata_res = + (PST_RAWDATA_TEST_RES *)(&p_test_item->test_res.ptr_res); + PST_CUR_RAWDATA p_cur_rawdata = NULL; + if (p_tp_dev->rawdata_option & _DATA_BIT_8) { + data_byte = 1; + } else if (p_tp_dev->rawdata_option & _DATA_BIT_16) { + data_byte = 2; + } else if (p_tp_dev->rawdata_option & _DATA_BIT_32) { + data_byte = 4; + } + + if (NULL != p_test_item->test_res.ptr_res) { + return 1; + } + if (alloc_mem_in_heap((void **)pp_rawdata_res, + sizeof(ST_RAWDATA_TEST_RES))) { + ret = alloc_item_res_header(p_test_item); + if (0 == ret) { + return ret; + } + + (*pp_rawdata_res)->p_max_raw_tmp_data = NULL; + (*pp_rawdata_res)->p_min_raw_tmp_data = NULL; + (*pp_rawdata_res)->p_beyond_rawdata_upper_limit_cnt = NULL; + (*pp_rawdata_res)->p_beyond_rawdata_lower_limit_cnt = NULL; + (*pp_rawdata_res)->p_beyond_jitter_limit_cnt = NULL; + (*pp_rawdata_res)->p_beyond_accord_limit_cnt = NULL; + (*pp_rawdata_res)->p_beyond_offset_limit_cnt = NULL; + (*pp_rawdata_res)->p_beyond_key_upper_limit_cnt = NULL; + (*pp_rawdata_res)->p_beyond_key_lower_limit_cnt = NULL; + (*pp_rawdata_res)->beyond_uniform_limit_cnt = 0; + (*pp_rawdata_res)->total_frame_cnt = 0; + (*pp_rawdata_res)->open_test_result = OPEN_TEST_PASS; + + /*//max data tmp buffer*/ + if (alloc_mem_in_heap( + (void **)&((*pp_rawdata_res)->p_max_raw_tmp_data), + sizeof(ST_RAW_TMP_DATA))) { + (*pp_rawdata_res)->p_max_raw_tmp_data->len = 0; + if (1 == alloc_mem_block( + (void **)&((*pp_rawdata_res) + ->p_max_raw_tmp_data + ->p_data_buf), + buf_size * sizeof(s32))) { + for (i = 0; i < buf_size; i++) { + (*pp_rawdata_res) + ->p_max_raw_tmp_data + ->p_data_buf[i] = 0; + } + (*pp_rawdata_res)->p_max_raw_tmp_data->len = + p_tp_dev->sc_sen_num * + p_tp_dev->sc_drv_num; + } + } + + /*//min data tmp buffer*/ + if (alloc_mem_in_heap( + (void **)&((*pp_rawdata_res)->p_min_raw_tmp_data), + sizeof(ST_RAW_TMP_DATA))) { + (*pp_rawdata_res)->p_min_raw_tmp_data->len = 0; + if (alloc_mem_block( + (void **)&((*pp_rawdata_res) + ->p_min_raw_tmp_data + ->p_data_buf), + buf_size * sizeof(s32))) { + for (i = 0; i < buf_size; i++) { + (*pp_rawdata_res) + ->p_min_raw_tmp_data + ->p_data_buf[i] = 0x7FFFFFFF; + } + (*pp_rawdata_res)->p_min_raw_tmp_data->len = + p_tp_dev->sc_sen_num * + p_tp_dev->sc_drv_num; + } + } + /*//beyond rawdata upper limit buffer*/ + if (alloc_mem_in_heap( + (void **)&( + (*pp_rawdata_res) + ->p_beyond_rawdata_upper_limit_cnt), + buf_size)) { + init_for_buffer( + (u8 *)(*pp_rawdata_res) + ->p_beyond_rawdata_upper_limit_cnt, + buf_size); + } + /*//beyond rawdata lower limit buffer*/ + if (alloc_mem_in_heap( + (void **)&( + (*pp_rawdata_res) + ->p_beyond_rawdata_lower_limit_cnt), + buf_size)) { + init_for_buffer( + (*pp_rawdata_res) + ->p_beyond_rawdata_lower_limit_cnt, + buf_size); + } + /*//beyond jitter limit buffer*/ + if (alloc_mem_in_heap( + (void **)&((*pp_rawdata_res) + ->p_beyond_jitter_limit_cnt), + buf_size)) { + init_for_buffer( + (*pp_rawdata_res)->p_beyond_jitter_limit_cnt, + buf_size); + } + /*//beyond accord limit buffer*/ + if (alloc_mem_in_heap( + (void **)&((*pp_rawdata_res) + ->p_beyond_accord_limit_cnt), + buf_size)) { + init_for_buffer( + (*pp_rawdata_res)->p_beyond_accord_limit_cnt, + buf_size); + } + /*//beyond offset limit buffer*/ + if (alloc_mem_in_heap( + (void **)&((*pp_rawdata_res) + ->p_beyond_offset_limit_cnt), + buf_size)) { + init_for_buffer( + (*pp_rawdata_res)->p_beyond_offset_limit_cnt, + buf_size); + } + /*//beyond key upper limit buffer*/ + if (alloc_mem_in_heap( + (void **)&((*pp_rawdata_res) + ->p_beyond_key_upper_limit_cnt), + key_buf_size)) { + init_for_buffer( + (*pp_rawdata_res)->p_beyond_key_upper_limit_cnt, + key_buf_size); + } + /*//beyond key lower limit buffer*/ + if (alloc_mem_in_heap( + (void **)&((*pp_rawdata_res) + ->p_beyond_key_lower_limit_cnt), + key_buf_size)) { + init_for_buffer( + (*pp_rawdata_res)->p_beyond_key_lower_limit_cnt, + key_buf_size); + } + + if (alloc_mem_in_heap( + (void **)&(p_test_item->cur_data.ptr_cur_data), + sizeof(ST_CUR_RAWDATA))) { + buf_size = p_tp_dev->rawdata_len; + p_cur_rawdata = + (PST_CUR_RAWDATA) + p_test_item->cur_data.ptr_cur_data; + p_cur_rawdata->cur_frame_id = 0; + p_cur_rawdata->data_len = buf_size; + if (alloc_mem_block( + (void **)&(p_cur_rawdata->p_data_buf), + buf_size * data_byte)) { + init_for_buffer( + (u8 *)(p_cur_rawdata->p_data_buf), + buf_size * data_byte); + } + } + + if (NULL != (*pp_rawdata_res)->p_max_raw_tmp_data->p_data_buf && + NULL != (*pp_rawdata_res)->p_min_raw_tmp_data->p_data_buf && + NULL != (*pp_rawdata_res)->p_beyond_rawdata_upper_limit_cnt && + NULL != (*pp_rawdata_res)->p_beyond_rawdata_lower_limit_cnt && + NULL != (*pp_rawdata_res)->p_beyond_jitter_limit_cnt && + NULL != (*pp_rawdata_res)->p_beyond_accord_limit_cnt && + NULL != (*pp_rawdata_res)->p_beyond_offset_limit_cnt && + NULL != (*pp_rawdata_res)->p_beyond_key_upper_limit_cnt && + NULL != (*pp_rawdata_res)->p_beyond_key_lower_limit_cnt && + NULL != (*pp_rawdata_res) + ->item_res_header.test_item_err_code + .ptr_err_code_set && + NULL != p_test_item->cur_data.ptr_cur_data && + NULL != ((PST_CUR_RAWDATA)p_test_item->cur_data.ptr_cur_data) + ->p_data_buf) { + ret = 1; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : free_rawdata_test_item_res +* Description : free_rawdata_test_item_res +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +s32 free_rawdata_test_item_res(PST_TEST_ITEM p_test_item) +{ + s32 ret = 1; + PST_RAWDATA_TEST_RES *pp_rawdata_res = NULL; + PST_CUR_RAWDATA p_curdata = NULL; + if (NULL == p_test_item->test_res.ptr_res) { + return 1; + } + pp_rawdata_res = + (PST_RAWDATA_TEST_RES *)(&p_test_item->test_res.ptr_res); + + /*//free test item res header*/ + ret &= free_item_res_header(p_test_item); + + /*//free beyond rawdata upper limit buffer*/ + ret &= free_mem_in_heap( + (void *)(*pp_rawdata_res)->p_beyond_rawdata_upper_limit_cnt); + (*pp_rawdata_res)->p_beyond_rawdata_upper_limit_cnt = NULL; + + /*//free beyond rawdata lower limit buffer*/ + ret &= free_mem_in_heap( + (void *)(*pp_rawdata_res)->p_beyond_rawdata_lower_limit_cnt); + (*pp_rawdata_res)->p_beyond_rawdata_lower_limit_cnt = NULL; + + /*//free beyond jitter limit buffer*/ + ret &= free_mem_in_heap( + (void *)(*pp_rawdata_res)->p_beyond_jitter_limit_cnt); + (*pp_rawdata_res)->p_beyond_jitter_limit_cnt = NULL; + + /*//free beyond accord limit buffer*/ + ret &= free_mem_in_heap( + (void *)(*pp_rawdata_res)->p_beyond_accord_limit_cnt); + (*pp_rawdata_res)->p_beyond_accord_limit_cnt = NULL; + + /*//free beyond offset limit buffer*/ + ret &= free_mem_in_heap( + (void *)(*pp_rawdata_res)->p_beyond_offset_limit_cnt); + (*pp_rawdata_res)->p_beyond_offset_limit_cnt = NULL; + + /*//free beyond key upper limit buffer*/ + ret &= free_mem_in_heap( + (void *)(*pp_rawdata_res)->p_beyond_key_upper_limit_cnt); + (*pp_rawdata_res)->p_beyond_key_upper_limit_cnt = NULL; + + /*//free beyond key lower limit buffer*/ + ret &= free_mem_in_heap( + (void *)(*pp_rawdata_res)->p_beyond_key_lower_limit_cnt); + (*pp_rawdata_res)->p_beyond_key_lower_limit_cnt = NULL; + + /*//free max tmp data buffer*/ + ret &= free_mem_block( + (void *)(*pp_rawdata_res)->p_max_raw_tmp_data->p_data_buf); + (*pp_rawdata_res)->p_max_raw_tmp_data->p_data_buf = NULL; + ret &= free_mem_in_heap((*pp_rawdata_res)->p_max_raw_tmp_data); + (*pp_rawdata_res)->p_max_raw_tmp_data = NULL; + + /*//free min tmp data buffer*/ + ret &= free_mem_block( + (void *)(*pp_rawdata_res)->p_min_raw_tmp_data->p_data_buf); + (*pp_rawdata_res)->p_min_raw_tmp_data->p_data_buf = NULL; + ret &= free_mem_in_heap((*pp_rawdata_res)->p_min_raw_tmp_data); + (*pp_rawdata_res)->p_min_raw_tmp_data = NULL; + + /*//free struct */ + ret &= free_mem_in_heap_p((void **)(pp_rawdata_res)); + + /*//free current data*/ + p_curdata = (PST_CUR_RAWDATA)p_test_item->cur_data.ptr_cur_data; + ret &= free_mem_block((void *)(p_curdata->p_data_buf)); + ret &= free_mem_in_heap_p( + (void **)&(p_test_item->cur_data.ptr_cur_data)); + + return ret; +} + +/******************************************************************************* +* Function Name : alloc_diffdata_test_item_res +* Description : alloc_diffdata_test_item_res +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +s32 alloc_diffdata_test_item_res(PST_TEST_ITEM p_test_item) +{ + s32 i = 0; + s32 ret = 0; + PST_TP_DEV p_tp_dev = p_test_item->p_tp_dev; + u16 buf_size = p_tp_dev->sc_drv_num * p_tp_dev->sc_sen_num; + u8 data_byte = 0; + PST_DIFFDATA_TEST_RES *pp_diffdata_res = NULL; + PST_CUR_DIFFDATA p_cur_diffdata = NULL; + if (p_tp_dev->diffdata_option & _DATA_BIT_8) { + data_byte = 1; + } else if (p_tp_dev->diffdata_option & _DATA_BIT_16) { + data_byte = 2; + } else if (p_tp_dev->diffdata_option & _DATA_BIT_32) { + data_byte = 4; + } + + if (NULL != p_test_item->test_res.ptr_res) { + return 1; + } + pp_diffdata_res = + (PST_DIFFDATA_TEST_RES *)(&p_test_item->test_res.ptr_res); + if (alloc_mem_in_heap((void **)pp_diffdata_res, + sizeof(ST_DIFFDATA_TEST_RES))) { + ret = alloc_item_res_header(p_test_item); + if (0 == ret) { + return ret; + } + /*//max data tmp buffer*/ + if (alloc_mem_in_heap( + (void **)&((*pp_diffdata_res)->p_max_diff_tmp_data), + sizeof(ST_DIFF_TMP_DATA))) { + buf_size = p_tp_dev->sc_drv_num * p_tp_dev->sc_sen_num; + (*pp_diffdata_res)->p_max_diff_tmp_data->len = 0; + if (1 == + alloc_mem_block( + (void **)&((*pp_diffdata_res) + ->p_max_diff_tmp_data + ->p_data_buf), + buf_size * sizeof(s32))) { + for (i = 0; i < buf_size; i++) { + (*pp_diffdata_res) + ->p_max_diff_tmp_data + ->p_data_buf[i] = 0; + } + (*pp_diffdata_res)->p_max_diff_tmp_data->len = + buf_size; + } + } + + if (alloc_mem_in_heap( + (void **)&(p_test_item->cur_data.ptr_cur_data), + sizeof(ST_CUR_DIFFDATA))) { + buf_size = p_tp_dev->diffdata_len; + p_cur_diffdata = + (PST_CUR_DIFFDATA) + p_test_item->cur_data.ptr_cur_data; + p_cur_diffdata->cur_frame_id = 0; + p_cur_diffdata->data_len = buf_size; + if (alloc_mem_block( + (void **)&(p_cur_diffdata->p_data_buf), + buf_size * data_byte)) { + init_for_buffer( + (u8 *)(p_cur_diffdata->p_data_buf), + buf_size * data_byte); + } + } + } + + return ret; +} + +/******************************************************************************* +* Function Name : free_diffdata_test_item_res +* Description : free_diffdata_test_item_res +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +s32 free_diffdata_test_item_res(PST_TEST_ITEM p_test_item) +{ + s32 ret = 1; + PST_DIFFDATA_TEST_RES *pp_diffdata_res = NULL; + PST_CUR_DIFFDATA p_curdata = NULL; + if (NULL == p_test_item->test_res.ptr_res) { + return 1; + } + /*//free struct */ + pp_diffdata_res = + (PST_DIFFDATA_TEST_RES *)(&p_test_item->test_res.ptr_res); + + ret &= free_item_res_header(p_test_item); + /*//free max tmp data buffer*/ + ret &= free_mem_block( + (void *)(*pp_diffdata_res)->p_max_diff_tmp_data->p_data_buf); + (*pp_diffdata_res)->p_max_diff_tmp_data->p_data_buf = NULL; + ret &= free_mem_in_heap((*pp_diffdata_res)->p_max_diff_tmp_data); + (*pp_diffdata_res)->p_max_diff_tmp_data = NULL; + + ret = free_mem_in_heap_p((void **)(pp_diffdata_res)); + + /*//free current data*/ + p_curdata = (PST_CUR_DIFFDATA)p_test_item->cur_data.ptr_cur_data; + ret &= free_mem_block((void *)(p_curdata->p_data_buf)); + ret &= free_mem_in_heap_p( + (void **)&(p_test_item->cur_data.ptr_cur_data)); + + return ret; +} + +/******************************************************************************* +* Function Name : alloc_short_test_item_res +* Description : alloc_short_test_item_res +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +s32 alloc_short_test_item_res(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_SHORT_TEST_RES *pp_test_res = NULL; + if (NULL != p_test_item->test_res.ptr_res) { + return 1; + } + pp_test_res = (PST_SHORT_TEST_RES *)(&p_test_item->test_res.ptr_res); + if (alloc_mem_in_heap((void **)pp_test_res, + sizeof(ST_SHORT_TEST_RES))) { + ret = alloc_item_res_header(p_test_item); + (*pp_test_res)->short_num = 0; + } + + return ret; +} + +/******************************************************************************* +* Function Name : free_short_test_item_res +* Description : free_short_test_item_res +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +s32 free_short_test_item_res(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_SHORT_TEST_RES *pp_test_res = NULL; + if (NULL == p_test_item->test_res.ptr_res) { + return 1; + } + pp_test_res = (PST_SHORT_TEST_RES *)(&p_test_item->test_res.ptr_res); + ret = free_item_res_header(p_test_item); + ret = free_mem_in_heap_p((void **)pp_test_res); + return ret; +} + +/******************************************************************************* +* Function Name : alloc_version_test_item_res +* Description : alloc_version_test_item_res +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +s32 alloc_version_test_item_res(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_VERSION_TEST_RES *pp_test_res = NULL; + if (NULL != p_test_item->test_res.ptr_res) { + return 1; + } + + pp_test_res = (PST_VERSION_TEST_RES *)(&p_test_item->test_res.ptr_res); + if (alloc_mem_in_heap((void **)pp_test_res, + sizeof(ST_VERSION_TEST_RES))) { + ret = alloc_item_res_header(p_test_item); + (*pp_test_res)->cur_ver_data_len = 0; + } + + return ret; +} + +/******************************************************************************* +* Function Name : free_version_test_item_res +* Description : free_version_test_item_res +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +s32 free_version_test_item_res(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_VERSION_TEST_RES *pp_test_res = NULL; + if (NULL == p_test_item->test_res.ptr_res) { + return 1; + } + pp_test_res = (PST_VERSION_TEST_RES *)(&p_test_item->test_res.ptr_res); + ret = free_item_res_header(p_test_item); + ret = free_mem_in_heap_p((void **)(pp_test_res)); + return ret; +} +/******************************************************************************* +* Function Name : free_sleep_current_test_item_res +* Description : free sleep current test item res +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(1:ok 0:fail) +*******************************************************************************/ +s32 alloc_chip_cfg_proc_item_res(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_CHIP_CONFIG_PROC_RES *pp_test_res = NULL; + PST_CHIP_CONFIG_PROC_PARAM p_param = NULL; + if (NULL != p_test_item->test_res.ptr_res) { + return 1; + } + + pp_test_res = + (PST_CHIP_CONFIG_PROC_RES *)(&p_test_item->test_res.ptr_res); + if (alloc_mem_in_heap((void **)pp_test_res, + sizeof(ST_CHIP_CONFIG_PROC_RES))) { + ret = alloc_item_res_header(p_test_item); + p_param = (PST_CHIP_CONFIG_PROC_PARAM) + p_test_item->param.ptr_param; + if (NULL != p_param && 0 < p_param->cfg_len) { + (*pp_test_res)->cfg_len = p_param->cfg_len; + ret = alloc_mem_in_heap( + (void **)(&(*pp_test_res)->p_read_cfg), + (*pp_test_res)->cfg_len * sizeof(u8)); + } else { + (*pp_test_res)->cfg_len = 0; + (*pp_test_res)->p_read_cfg = NULL; + } + } + return ret; +} + +/******************************************************************************* +* Function Name : free_cfg_check_test_item_res +* Description : free sleep free_cfg_check_test_item_res test item res +* Input : PST_TEST_ITEM p_test_item +* Output : PST_TEST_ITEM p_test_item +* Return : s32(1:ok 0:fail) +*******************************************************************************/ +s32 free_chip_cfg_proc_item_res(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_CHIP_CONFIG_PROC_RES *pp_test_res = NULL; + if (NULL == p_test_item->test_res.ptr_res) { + return 1; + } + pp_test_res = + (PST_CHIP_CONFIG_PROC_RES *)(&p_test_item->test_res.ptr_res); + ret = free_item_res_header(p_test_item); + if (NULL != (*pp_test_res)->p_read_cfg) { + ret = free_mem_in_heap_p((void **)&(*pp_test_res)->p_read_cfg); + } + ret = free_mem_in_heap_p((void **)(pp_test_res)); + return ret; +} + +/***************************************************************** +* Function Name : alloc_flash_test_item_res +* Description : alloc_flash_test_item_res +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 alloc_flash_test_item_res(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_FLASH_TEST_RES *pp_test_res = NULL; + PST_FLASH_TEST_PARAM p_param = NULL; + if (NULL != p_test_item->test_res.ptr_res) { + return 1; + } + pp_test_res = (PST_FLASH_TEST_RES *)(&p_test_item->test_res.ptr_res); + if (alloc_mem_in_heap((void **)pp_test_res, + sizeof(ST_FLASH_TEST_RES))) { + ret = alloc_item_res_header(p_test_item); + + p_param = (PST_FLASH_TEST_PARAM)p_test_item->param.ptr_param; + if (NULL != p_param && 0 < p_param->cfg_len) { + (*pp_test_res)->cfg_len = p_param->cfg_len; + ret = alloc_mem_in_heap( + (void **)(&(*pp_test_res)->config_arr), + (*pp_test_res)->cfg_len * sizeof(u8)); + } else { + (*pp_test_res)->cfg_len = 0; + (*pp_test_res)->config_arr = NULL; + } + } + return ret; +} + +/***************************************************************** +* Function Name : free_flash_test_item_res +* Description : free_flash_test_item_res +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 free_flash_test_item_res(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_FLASH_TEST_RES *pp_test_res = NULL; + if (NULL == p_test_item->test_res.ptr_res) { + return 1; + } + pp_test_res = (PST_FLASH_TEST_RES *)(&p_test_item->test_res.ptr_res); + ret = free_item_res_header(p_test_item); + if (NULL != (*pp_test_res)->config_arr) { + ret = free_mem_in_heap_p((void **)&(*pp_test_res)->config_arr); + } + + ret = free_mem_in_heap_p((void **)(pp_test_res)); + return ret; +} + +/***************************************************************** +* Function Name : alloc_recover_cfg_item_res +* Description : alloc_recover_cfg_item_res +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 alloc_recover_cfg_item_res(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_RECOVER_CHIP_CFG_RES *pp_test_res = NULL; + PST_RECOVER_CHIP_CFG_PARAM p_param = + (PST_RECOVER_CHIP_CFG_PARAM)p_test_item->param.ptr_param; + if (NULL != p_test_item->test_res.ptr_res) { + return 1; + } + pp_test_res = + (PST_RECOVER_CHIP_CFG_RES *)(&p_test_item->test_res.ptr_res); + if (alloc_mem_in_heap((void **)pp_test_res, + sizeof(ST_RECOVER_CHIP_CFG_RES))) { + ret = alloc_item_res_header(p_test_item); + if (NULL != p_param) { + (*pp_test_res)->cfg_len = p_param->cfg_len; + ret = alloc_mem_in_heap( + (void **)&(*pp_test_res)->config_arr, + (*pp_test_res)->cfg_len * sizeof(u8)); + } else { + (*pp_test_res)->cfg_len = 0; + (*pp_test_res)->config_arr = NULL; + } + } + return ret; +} + +/***************************************************************** +* Function Name : free_revover_cfg_item_res +* Description : free_revover_cfg_item_res +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Return : s32(0:fail 1:ok) +*******************************************************************************/ +extern s32 free_recover_cfg_item_res(PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + PST_RECOVER_CHIP_CFG_RES *pp_test_res = NULL; + if (NULL == p_test_item->test_res.ptr_res) { + return 1; + } + pp_test_res = + (PST_RECOVER_CHIP_CFG_RES *)(&p_test_item->test_res.ptr_res); + + ret = free_item_res_header(p_test_item); + if (NULL != (*pp_test_res)->config_arr) { + ret = free_mem_in_heap_p((void **)&(*pp_test_res)->config_arr); + } + ret = free_mem_in_heap_p((void **)(pp_test_res)); + return ret; +} + +#ifdef __cplusplus +} +#endif + +/******************************************************************************* +* Function Name : init_for_buffer +* Description : initialize temp buffer with 0 +* Input : u8* p_buf +: u16 buf_size +* Output : u8* p_buf +* Return : s32(0:Fail 1:Ok) +*******************************************************************************/ +static s32 init_for_buffer(u8 *p_buf, u16 buf_size) +{ + s32 ret = 1; + u16 i = 0; + for (i = 0; i < buf_size; i++) { + p_buf[i] = 0; + } + return ret; +} \ No newline at end of file diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_mem.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_mem.h new file mode 100644 index 000000000000..9012bdbd1332 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_test_item_mem.h @@ -0,0 +1,42 @@ +/******************** (C) COPYRIGHT 2017 Goodix ******************** +* File Name : tp_test_item_mem.cpp.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 01/11/2018 +* Description : Tp Test Item Result Memory Process +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE +#ifndef TP_TEST_ITEM_MEM_H +#define TP_TEST_ITEM_MEM_H + +#include "test_item_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern s32 alloc_test_item_res(PST_TEST_ITEM *pp_test_item, u16 item_num); +extern s32 free_test_item_res(PST_TEST_ITEM *pp_test_item, u16 item_num); + +extern s32 alloc_item_res_header(PST_TEST_ITEM p_test_item); +extern s32 free_item_res_header(PST_TEST_ITEM p_test_item); +extern s32 alloc_rawdata_test_item_res(PST_TEST_ITEM p_test_item); +extern s32 free_rawdata_test_item_res(PST_TEST_ITEM p_test_item); +extern s32 alloc_diffdata_test_item_res(PST_TEST_ITEM p_test_item); +extern s32 free_diffdata_test_item_res(PST_TEST_ITEM p_test_item); +extern s32 alloc_short_test_item_res(PST_TEST_ITEM p_test_item); +extern s32 free_short_test_item_res(PST_TEST_ITEM p_test_item); +extern s32 alloc_version_test_item_res(PST_TEST_ITEM p_test_item); +extern s32 free_version_test_item_res(PST_TEST_ITEM p_test_item); +extern s32 alloc_chip_cfg_proc_item_res(PST_TEST_ITEM p_test_item); +extern s32 free_chip_cfg_proc_item_res(PST_TEST_ITEM p_test_item); +extern s32 alloc_flash_test_item_res(PST_TEST_ITEM p_test_item); +extern s32 free_flash_test_item_res(PST_TEST_ITEM p_test_item); +extern s32 alloc_recover_cfg_item_res(PST_TEST_ITEM p_test_item); +extern s32 free_recover_cfg_item_res(PST_TEST_ITEM p_test_item); + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_version_test.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_version_test.c new file mode 100644 index 000000000000..dfb894933d15 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_version_test.c @@ -0,0 +1,267 @@ +/******************** (C) COPYRIGHT 2016 Goodix **************************** +* File Name : version_test.c +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : test touch panel version or update firmware +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#include "test_item_def.h" +#include "tp_version_test.h" +#include "tp_dev_control.h" +#include "board_opr_interface.h" +#include "tp_test_general_error_code_def.h" +#include "test_proc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static s32 compare_version_equal(PST_TEST_ITEM p_test_item); +static s32 compare_version_equal_greater(PST_TEST_ITEM p_test_item); +static s32 compare_version(PST_TEST_ITEM p_test_item); + +/******************************************************************************* +* Function Name : fw_version_test +* Description : firmware version test +* Input : ptr32 p_data(You must cast it to type PST_TEST_ITEM ) +* Output : none +* Return : u8(0:test error 1:ok) +*******************************************************************************/ +extern s32 fw_version_test(IN_OUT ptr32 p_data) +{ + PST_TEST_ITEM p_test_item = NULL; + PST_VERSION_PARAM p_ver_param = NULL; + PST_VERSION_TEST_RES p_test_res = NULL; + u16 err_code = VERSION_TEST_NONE_ERROR; + u8 i = 0; + s32 ret = 0; + + p_test_item = (PST_TEST_ITEM)p_data; + /*-----------------Judge parameter----------------*/ + if (0 == judge_test_item_legal((PST_TEST_ITEM)p_data)) { + ret = 0; + goto TEST_ITEM_END; + } + + p_ver_param = (PST_VERSION_PARAM)p_test_item->param.ptr_param; + p_test_res = (PST_VERSION_TEST_RES)p_test_item->test_res.ptr_res; + + /*callback function test before*/ + if (NULL != p_test_item->ptr_test_item_before_func) { + ret = p_test_item->ptr_test_item_before_func( + p_test_item->ptr_test_item_before_func_param); + if (0 == ret) { + board_print_error( + "[version test]callback function test before error!\n"); + err_code = TEST_BEFORE_FUNC_FAIL; + goto TEST_ITEM_END; + } + } + + p_test_res->cur_ver_data_len = p_ver_param->ver_param_len; + p_test_res->item_res_header.test_status = TEST_START; + p_test_res->item_res_header.test_result = TEST_NG; + p_test_res->item_res_header.test_item_err_code.ptr_err_code_set[0] = + VERSION_TEST_NONE_ERROR; + for (i = 0; i < p_ver_param->ver_param_len; i++) { /*//clear res*/ + p_test_res->cur_ver_data[i] = 0x00; + } + + /*//force update*/ + if (1 == p_ver_param->b_force_update) { + /*//update fw*/ + } + /*//compare version*/ + ret = compare_version(p_test_item); + if (ret == 0) { + if (1 == p_ver_param->b_force_update) { + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = + VERSION_TEST_VERSIONMATCH_FAIL_AFTER; + } + p_test_res->item_res_header.test_result = TEST_NG; + p_test_res->item_res_header.test_status = TEST_ABORTED; + board_print_debug("compare fw version error!\n"); + err_code = p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0]; + /*//goto TEST_ITEM_END;*/ + } + + if (p_test_res->item_res_header.test_result == TEST_OK) { + p_test_res->item_res_header.test_status = TEST_FINISH; + goto TEST_ITEM_END; + } else { + if (0 == p_ver_param->b_auto_update) { + p_test_res->item_res_header.test_status = TEST_FINISH; + goto TEST_ITEM_END; + } else if (0 == p_ver_param->b_force_update) { + /*//compare version again*/ + ret = compare_version(p_test_item); + if (0 == ret) { + if (1 == p_ver_param->b_force_update) { + p_test_res->item_res_header + .test_item_err_code + .ptr_err_code_set[0] = + VERSION_TEST_VERSIONMATCH_FAIL_AFTER; + } + p_test_res->item_res_header.test_result = + TEST_NG; + p_test_res->item_res_header.test_status = + TEST_ABORTED; + board_print_error( + "auto update:compare fw version error!\n"); + err_code = p_test_res->item_res_header + .test_item_err_code + .ptr_err_code_set[0]; + goto TEST_ITEM_END; + } + } + } + + p_test_res->item_res_header.test_status = TEST_FINISH; +TEST_ITEM_END: + if (NULL != p_test_item->ptr_test_item_finished_func) { + ret = p_test_item->ptr_test_item_finished_func( + p_test_item->ptr_test_item_finished_func_param); + if (ret == 0) { + board_print_error( + "[version test]callback function after test error!\n"); + err_code = TEST_FINISH_FUNC_FAIL; + } + } + + if (err_code == VERSION_TEST_NONE_ERROR) { + ret = 1; + } else { + ret = 0; + } + return ret; +} + +/******************************************************************************* +* Function Name : compare_version +* Description : compare version +* Input : PST_TEST_ITEM p_test_item +* Output : none +* Return : s32(0:error 1:handled) +*******************************************************************************/ +static s32 compare_version(PST_TEST_ITEM p_test_item) +{ + u8 i = 0, retry_cnt = 3; + s32 ret = 0; + s32 cmp_ret = 0; + PST_VERSION_PARAM p_ver_param = + (PST_VERSION_PARAM)p_test_item->param.ptr_param; + PST_VERSION_TEST_RES p_test_res = + (PST_VERSION_TEST_RES)p_test_item->test_res.ptr_res; + /*//read ic version */ + for (i = 0; i < retry_cnt; i++) { + ret = chip_reg_read(p_test_item->p_tp_dev, + p_ver_param->ic_ver_addr, + p_test_res->cur_ver_data, + p_ver_param->ver_param_len); + if (1 == ret) { + break; + } + } + if (i >= retry_cnt) { + board_print_error("%s\n", + "in compare version, read version fail"); + goto COMPARE_END; + } + + if (p_ver_param->ver_cmp_opt == VERSION_CMP_EQUAL) { + cmp_ret = compare_version_equal(p_test_item); + } else if (p_ver_param->ver_cmp_opt == VERSION_CMP_GREATOR_EQUAL) { + cmp_ret = compare_version_equal_greater(p_test_item); + } + + if (0 == cmp_ret) { + board_print_debug("%s\n", + "in compare version, version match fail"); + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = VERSION_TEST_VERSION_MATCH_FAIL; + p_test_res->item_res_header.test_result = TEST_NG; + ret = 0; + goto COMPARE_END; + } else { + p_test_res->item_res_header.test_result = TEST_OK; + p_test_res->item_res_header.test_item_err_code + .ptr_err_code_set[0] = VERSION_TEST_NONE_ERROR; + ret = 1; + } +COMPARE_END: + return ret; +} + +/******************************************************************************* +* Function Name : compare_version_equal +* Description : compare_version_equal +* Input : PST_TEST_ITEM p_test_item +* Output : none +* Return : s32(0:error 1:cmp ok) +*******************************************************************************/ +static s32 compare_version_equal(IN PST_TEST_ITEM p_test_item) +{ + u8 i = 0; + s32 ret = 0; + PST_VERSION_PARAM p_ver_param = + (PST_VERSION_PARAM)p_test_item->param.ptr_param; + PST_VERSION_TEST_RES p_test_res = + (PST_VERSION_TEST_RES)p_test_item->test_res.ptr_res; + + /*//compare version*/ + for (i = 0; i < p_ver_param->ver_param_len; i++) { + if (p_test_res->cur_ver_data[i] != + p_ver_param->ver_param_str[i]) { + break; + } + } + + if (i == p_ver_param->ver_param_len) { + ret = 1; + } + return ret; +} + +/******************************************************************************* +* Function Name : compare_version_equal_greater +* Description : compare_version_equal_greater +* Input : PST_TEST_ITEM p_test_item +* Output : none +* Return : s32(0:error 1:cmp ok) +*******************************************************************************/ +static s32 compare_version_equal_greater(IN PST_TEST_ITEM p_test_item) +{ + s32 ret = 0; + u8 i = 0; + PST_VERSION_PARAM p_ver_param = + (PST_VERSION_PARAM)p_test_item->param.ptr_param; + PST_VERSION_TEST_RES p_test_res = + (PST_VERSION_TEST_RES)p_test_item->test_res.ptr_res; + ret = compare_version_equal(p_test_item); + if (1 == ret) { + return ret; + } + /*//compare version + //do not care about public version and special version updating*/ + for (i = 0; i < p_ver_param->ver_param_len; i++) { + if (p_test_res->cur_ver_data[i] < + p_ver_param->ver_param_str[i]) { + return 0; + } + if (p_test_res->cur_ver_data[i] > + p_ver_param->ver_param_str[i]) { + return 1; + } + } + + return 1; +} +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_version_test.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_version_test.h new file mode 100644 index 000000000000..5d51596978cf --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_version_test.h @@ -0,0 +1,57 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : version_test.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : test touch panel version or update firmware +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef VERSION_TEST_H +#define VERSION_TEST_H + +#include "tp_version_test_param.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define VERSION_TEST_NONE_ERROR 0x00 +#define VERSION_TEST_VERSION_MATCH_FAIL 0x01 +#define VERSION_TEST_FW_UPDATE_FAIL 0x02 +#define VERSION_TEST_VERSIONMATCH_FAIL_AFTER 0x03 + +/*//---------------------Version Test----------------------//*/ + +/*//test result*/ +typedef struct VERSION_TEST_RES { + ST_TEST_ITEM_RES item_res_header; + u8 cur_ver_data_len; + u8 cur_ver_data[MAX_VERSION_LEN]; +} ST_VERSION_TEST_RES, *PST_VERSION_TEST_RES; + +extern s32 fw_version_test(ptr32 p_data); +extern s32 fw_update(ptr32 p_data, PST_UPDATA_BIN_PARAM p_update_bin); + +typedef struct CHK_FW_RUN_STATE_RES { + ST_TEST_ITEM_RES item_res_header; +} ST_CHK_FW_RUN_STATE_RES, *PST_CHK_FW_RUN_STATE_RES; +extern s32 check_fw_run_state(ptr32 p_data); + +/*//--------------------Error code---------------------//*/ +#define GEST_TEST_ERROR_NONE 0x00 +#define GEST_TEST_ENTER_DOZE_FAIL 0x01 +#define GEST_TEST_EXIT_DOZE_FAIL 0x02 +#define GEST_TEST_VER_CMP_ERROR 0x03 +typedef struct GESTURE_TEST_RES { + ST_TEST_ITEM_RES item_res_header; + u8 ver_buf[MAX_GESTURE_VER_BUF_SIZE]; + u8 ver_buf_len; +} ST_GESTURE_TEST_RES, *PST_GESTURE_TEST_RES; +extern s32 tp_gesture_test(ptr32 p_data); + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_version_test_param.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_version_test_param.h new file mode 100644 index 000000000000..79d5944f258a --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/tp_version_test_param.h @@ -0,0 +1,51 @@ +#ifndef VERSION_TEST_PARAM_H +#define VERSION_TEST_PARAM_H + +#include "user_test_type_def.h" +#include "test_item_def.h" + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct UPDATA_BIN_PARAM { + u32 update_bin_len; + union { + u32 bin_addr; + u8 *bin_ptr; + } update_bin_addr; + +} ST_UPDATA_BIN_PARAM, *PST_UPDATA_BIN_PARAM; + +/*//ver_cmp_opt */ +#define VERSION_CMP_EQUAL 0 +#define VERSION_CMP_GREATOR_EQUAL 1 +/*test param */ +#define MAX_VERSION_LEN 30 +typedef struct VERSION_PARAM { + u8 ver_param_len; + u8 ver_cmp_opt; + u8 b_auto_update; + u8 b_force_update; + u16 ic_ver_addr; + u8 ver_param_str[MAX_VERSION_LEN]; + PST_UPDATA_BIN_PARAM p_update_bin_param; +} ST_VERSION_PARAM, *PST_VERSION_PARAM; + +/*//---------------------Fw state check----------------------//*/ +typedef struct CHK_FW_RUN_STATE_PARAM { + u8 option; +} ST_CHK_FW_RUN_STATE_PARAM, *PST_CHK_FW_RUN_STATE_PARAM; + +/*//---------------------Gesture test----------------------//*/ +#define MAX_GESTURE_VER_BUF_SIZE 10 +typedef struct GESTURE_TEST_PARAM { + u16 ver_addr; + u8 ver_len; + u8 option; + u8 ver_buf[MAX_GESTURE_VER_BUF_SIZE]; +} ST_GESTURE_TEST_PARAM, *PST_GESTURE_TEST_PARAM; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/user_test_type_def.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/user_test_type_def.h new file mode 100644 index 000000000000..4918ef0a3b2a --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/test_core/user_test_type_def.h @@ -0,0 +1,143 @@ +/******************** (C) COPYRIGHT 2016 Goodix ******************** +* File Name : user_test_type_def.h +* Author : Bob Huang +* Version : V1.0.0 +* Date : 07/26/2017 +* Description : The basic type in user test module +*******************************************************************************/ +#ifndef TP_TEST_MODULE_DISABLE + +#ifndef USER_TEST_TYPE_DEF_H +#define USER_TEST_TYPE_DEF_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define KERNEL_CODE_OPEN +/*//--------------------Platform Micro--------------------//*/ +#if defined(PC_CODE_OPEN) +#define PC_CODE 1 +#else +#define PC_CODE 0 +#endif + +#if defined(ARM_CODE_OPEN) +#define ARM_CODE 1 +#else +#define ARM_CODE 0 +#endif + +#if defined(ANDROID_CODE_OPEN) +#define ANDROID_CODE 1 +#else +#define ANDROID_CODE 0 +#endif + +#if defined(QNX_CODE_OPEN) +#define QNX_CODE 1 +#else +#define QNX_CODE 0 +#endif + +#if defined(WCE_CODE_OPEN) +#define WCE_CODE 1 +#else +#define WCE_CODE 0 +#endif + +#if defined(KERNEL_CODE_OPEN) +#define LINUX_KERNEL 1 +#else +#define LINUX_KERNEL 0 +#endif + +/*//----------------------------------------//*/ +#define IN +#define OUT +#define IN_OUT + +#if WCE_CODE == 1 +typedef unsigned char u8; +typedef const unsigned char cu8; +typedef unsigned short u16; +typedef const unsigned short cu16; +typedef unsigned int u32; +typedef const unsigned int cu32; +typedef int s32; +typedef const int cs32; +typedef signed short s16; +typedef const signed short cs16; +typedef void *ptr32; +typedef void const *cptr32; +typedef unsigned long vu32; +typedef const unsigned long cvu32; +#define NULL 0 +typedef const char *cstr; + +#elif PC_CODE == 1 +typedef char s8; +typedef unsigned char u8; +typedef const unsigned char cu8; +typedef unsigned short u16; +typedef const unsigned short cu16; +typedef unsigned int u32; +typedef const unsigned int cu32; +typedef int s32; +typedef const int cs32; +typedef signed short s16; +typedef const signed short cs16; +typedef void *ptr32; +typedef void const *cptr32; +typedef unsigned long vu32; +typedef const unsigned long cvu32; + +#define NULL 0 + +typedef const char *cstr; +#elif ARM_CODE == 1 +#include "type.h" +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef int s32; + +typedef const unsigned short cu16; +typedef const signed short cs16; +typedef signed short s16; +typedef void *ptr32; +typedef void const *cptr32; + +#ifdef STM32F1XX +typedef unsigned int uint32_t; +typedef int int32_t; +typedef const char *cstr; +#endif + +#elif ANDROID_CODE == 1 || QNX_CODE || LINUX_KERNEL == 1 +//typedef unsigned char u8; +//typedef signed char s8; +typedef const unsigned char cu8; +//typedef unsigned short u16; +typedef const unsigned short cu16; +//typedef unsigned int u32; +typedef const unsigned int cu32; +//typedef int s32; +typedef const int cs32; +//typedef signed short s16; +typedef const signed short cs16; +typedef void *ptr32; +typedef void const *cptr32; +typedef unsigned long vu32; +typedef const unsigned long cvu32; +typedef const char *cstr; + +#endif + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/drivers/input/touchscreen/xiaomi/ndt_core.c b/drivers/input/touchscreen/xiaomi/ndt_core.c new file mode 100644 index 000000000000..1f3851b32a2a --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/ndt_core.c @@ -0,0 +1,1380 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ndt_core.h" +#ifdef CONFIG_TOUCHSCREEN_ST_CORE +#include "./fts/fts.h" +#endif +#ifdef CONFIG_TOUCHSCREEN_ST_FTS_V521 +#include "./fts_521/fts.h" +#endif +#define IIC_EEPROM 0 +#define IIC_DEV_ID 0x02 +#define IIC_MANU_ID 0x03 +#define IIC_MODULE_ID 0x04 +#define IIC_FW_VER 0x05 +#define IIC_WAKE_UP 0x06 +#define IIC_SLEEP 0x07 +#define IIC_DEBUG_MODE 0x60 +#define IIC_DATA_READY 0x61 +#define IIC_DEBUG_DATA1 0x62 +#define IIC_DEBUG_DATA2 0x63 +#define IIC_DEBUG_DATA3 0x64 +#define IIC_DEBUG_DATA4 0x65 +#define IIC_KEY_SEN 0xD0 +#define CONFIG_INPUT_NDT_FWUPDATE + +#ifdef CONFIG_INPUT_NDT_INTERRUPT +#define RELEASE_THRE 70 +#endif +static struct i2c_client *g_ndt_client; +struct input_dev *ndt_input_dev; +static int ndt_read_register(unsigned char reg, unsigned char *datbuf, + int byteno); +static int ndt_write_register(unsigned char reg, unsigned char *datbuf, + int byteno); +#ifdef CONFIG_INPUT_NDT_FWUPDATE +static int ndt_read_eeprom(unsigned short reg, unsigned char *datbuf, + int byteno); +static int ndt_write_eeprom(unsigned short reg, unsigned char *datbuf, + int byteno); +static void ndt_reset(void); +#endif +#ifdef CONFIG_INPUT_NDT_FWUPDATE +static int ndt_burn_fw(unsigned char *buf, unsigned int len); +static int ndt_eeprom_erase(void); +static int ndt_eeprom_skip(void); +static ssize_t pressure_update_fw_show(struct device *dev, + struct device_attribute *attr, + char *buf); +static ssize_t pressure_update_fw_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); +static ssize_t pressure_erase_fw_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); +static ssize_t pressure_force_update_fw_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); +#endif +static ssize_t pressure_fw_info_show(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t pressure_pressure_show(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t ndt_threshold_show(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t ndt_reset_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count); +static ssize_t ndt_irq_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); +static ssize_t ndt_threshold_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); +static ssize_t ndt_reset_and_read_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); +static DEVICE_ATTR(fw_info, 0444, pressure_fw_info_show, NULL); +static DEVICE_ATTR(pressure, 0444, pressure_pressure_show, NULL); +static DEVICE_ATTR(reset, 0200, NULL, ndt_reset_store); +static DEVICE_ATTR(irq_enable, 0200, NULL, ndt_irq_enable_store); +static DEVICE_ATTR(reset_and_read, 0200, NULL, ndt_reset_and_read_store); +static DEVICE_ATTR(threshold, 0644, ndt_threshold_show, ndt_threshold_store); +#ifdef CONFIG_INPUT_NDT_FWUPDATE +static DEVICE_ATTR(fw_update, (S_IRUGO | S_IWUSR | S_IWGRP), + pressure_update_fw_show, pressure_update_fw_store); +static DEVICE_ATTR(fw_erase, (S_IRUGO | S_IWUSR | S_IWGRP), + pressure_update_fw_show, pressure_erase_fw_store); +static DEVICE_ATTR(fw_update_force, (S_IRUGO | S_IWUSR | S_IWGRP), + pressure_update_fw_show, pressure_force_update_fw_store); +#endif + +static struct attribute *ndt_attr[] = { &dev_attr_fw_info.attr, + &dev_attr_pressure.attr, + &dev_attr_reset.attr, + &dev_attr_irq_enable.attr, + &dev_attr_reset_and_read.attr, + &dev_attr_threshold.attr, +#ifdef CONFIG_INPUT_NDT_FWUPDATE + &dev_attr_fw_update.attr, + &dev_attr_fw_update_force.attr, + &dev_attr_fw_erase.attr, +#endif + NULL }; + +static const struct attribute_group ndt_attr_group = { + .attrs = ndt_attr, +}; + +struct ndt_force_data { + struct i2c_client *client; + struct input_dev *input_dev; + struct hrtimer release_timer; + int released; + struct work_struct release_work; + struct workqueue_struct *event_wq; + int report_status; + struct ndt_platform_data *pdata; + int suspend_flag; + struct regulator *ndt_vdd; + struct regulator *ndt_vddio; + bool fw_updated; +}; + +struct ndt_platform_data { + int irq_gpio; +}; + +static int ndt_read_register(unsigned char reg, unsigned char *datbuf, + int byteno) +{ + struct i2c_msg msg[2]; + int ret = 0, retry = 0; + msg[0].addr = g_ndt_client->addr; + msg[0].flags = 0; + msg[0].len = 1; + msg[0].buf = ® + msg[1].addr = g_ndt_client->addr; + msg[1].flags = I2C_M_RD; + msg[1].len = byteno; + msg[1].buf = datbuf; + + if (!datbuf) + return -EINVAL; + do { + ret = i2c_transfer(g_ndt_client->adapter, msg, 2); + if (ret >= 0) + break; + if (ret < 0) + pr_err("ndt:i2c_transfer Error ! err_code:%d, retry:%d\n", + ret, retry); + } while (retry++ < 5); + return ret; +} + +static int ndt_write_register(unsigned char reg, unsigned char *datbuf, + int byteno) +{ + unsigned char *buf; + struct i2c_msg msg; + int ret = 0, retry = 0; + + if (!datbuf) + return -EINVAL; + + buf = (unsigned char *)kmalloc(byteno + 1, GFP_KERNEL); + + if (!buf) + return -EINVAL; + + memset(buf, 0, byteno + 1); + buf[0] = reg; + + if (byteno > 0) { + memcpy(buf + 1, datbuf, byteno); + } + msg.addr = g_ndt_client->addr; + msg.flags = 0; + msg.len = byteno + 1; + msg.buf = buf; + do { + ret = i2c_transfer(g_ndt_client->adapter, &msg, 1); + if (ret >= 0) + break; + if (ret < 0) { + pr_err("ndt:i2c_transfer Error ! err_code:%d, retry:%d\n", + ret, retry); + } + } while (retry++ < 5); + + kfree(buf); + return ret; +} + +static unsigned int g_last_x; +static unsigned int g_last_y; +static unsigned char g_touch_flag; + +int ndt_get_pressure(int touch_flag, int x, int y) +{ + int i; + int pressure; + unsigned char buf[10]; + int count = 0; + int ndt_press_num = 0; + + if (g_ndt_client == NULL) + return 1; + + pr_debug("%s,touch_flag:%d,g_touch_flag:%d,x:%d,y:%d\n", __func__, + touch_flag, g_touch_flag, x, y); + if (touch_flag == 0 && g_touch_flag == 0) { + return 1; + } + + if (touch_flag == 0 && x == 0 && y == 0) { + x = g_last_x; + y = g_last_y; + } + buf[0] = x & 0xff; + buf[1] = x >> 8; + buf[2] = y & 0xff; + buf[3] = y >> 8; + buf[4] = touch_flag; + if (x != g_last_x || y != g_last_y) { + ndt_write_register(0x11, buf, 5); + } + g_last_x = x; + g_last_y = y; + if (touch_flag == 1 && g_touch_flag == 0) { + buf[0] = 1; + ndt_write_register(0x1f, buf, 1); + ndt_write_register(0x10, buf, 1); + g_touch_flag = 1; + } else if (touch_flag == 0 && g_touch_flag == 1) { + buf[0] = 0; + ndt_write_register(0x10, buf, 1); + g_touch_flag = 0; + return 1; + } + buf[0] = 0; + do { + ndt_read_register(0x20, buf, 1); + + if (buf[0] != 0) + break; + msleep(2); + } while (count++ < 10); + + ndt_press_num = buf[0]; + + if (ndt_press_num != 1) + ndt_press_num = 1; + + memset(buf, 0, sizeof(buf)); + + for (i = 0; i < ndt_press_num; i++) { + ndt_read_register(0x21, buf, 2); + } + + pressure = buf[1] << 8 | buf[0]; + pr_debug("ndt:pressure:pressure = %d\n", pressure); + + if (pressure == 0) { + pressure = 1; + } + return pressure; +} + +#ifdef CONFIG_INPUT_NDT_FWUPDATE +static void ndt_reset(void) +{ + int error = 0; + struct ndt_force_data *data = i2c_get_clientdata(g_ndt_client); + + error = regulator_disable(data->ndt_vdd); + msleep(2000); + error = regulator_enable(data->ndt_vdd); + msleep(20); +} + +static int ndt_burn_fw(unsigned char *buf, unsigned int len) +{ + unsigned short reg; + int byteno = 0; + int pos = 0; + unsigned char *read_buf; + int ret = 1; + int i = 0; + int number = 0; + bool i2c_ok_flag = true; + + if (len % 128 != 0) { + pr_err("ndt:burn len is not 128 *\n"); + return 0; + } + /*reset*/ + ndt_reset(); + /*erase flash*/ + read_buf = (unsigned char *)kmalloc(len, GFP_KERNEL); + + do { + pr_info("ndt:burn eeprom number: %d\n", number + 1); + ret = 1; + byteno = 0; + + if (ndt_eeprom_erase() == 0) { + i2c_ok_flag = false; + } + /*write eeprom*/ + pos = 0; + reg = IIC_EEPROM; + byteno = 128; + while (i2c_ok_flag && pos < len) { + if (ndt_write_eeprom(reg, buf + pos, byteno) > 0) { + pr_debug("reg=0x%02x,byteno=%d\n", reg, byteno); + } else { + pr_info("failed!\n"); + i2c_ok_flag = false; + } + + pos += byteno; + reg += byteno; + msleep(15); + } + + /*read eeprom and check*/ + pos = 0; + reg = IIC_EEPROM; + byteno = 256; + + while (i2c_ok_flag && pos < len) { + if (ndt_read_eeprom(reg, read_buf + pos, byteno) > 0) { + pr_debug("ndt:reg=0x%02x,byteno=%d\n", reg, + byteno); + } else { + pr_info("ndt:failed!\n"); + i2c_ok_flag = false; + } + + pos += byteno; + reg += byteno; + msleep(15); + } + + /*check */ + for (i = 0; i < len; i++) { + if (i2c_ok_flag && buf[i] != read_buf[i]) { + pr_info("ndt:burn check error!%d,%d\n", buf[i], + read_buf[i]); + ret = 0; + break; + } + } + + number++; + } while (i2c_ok_flag && number < 3 && ret == 0); + + if (i2c_ok_flag == false || ret == 0) { + pr_err("ndt:burn eeprom fail!\n"); + ret = 0; + } else { + pr_info("ndt:burn eeprom succeed!\n"); + } + + /*exit burn */ + ndt_eeprom_skip(); + kfree(read_buf); + return ret; +} + +static ssize_t pressure_update_fw_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int fw_size; + unsigned char ic_fw_ver[2]; + unsigned char reg; + int byteno; + unsigned char file_fw_ver[2]; + const struct firmware *fw_entry = NULL; + char *data; + + ret = request_firmware(&fw_entry, "ndt_fw.bin", &(g_ndt_client->dev)); + if (ret != 0) { + pr_err("%s request firmware failed\n", __func__); + return -EINVAL; + } + + fw_size = fw_entry->size; + data = (char *)kzalloc(fw_size * sizeof(char), GFP_KERNEL); + if (data == NULL) { + pr_err("%s kzalloc memory fail\n", __func__); + release_firmware(fw_entry); + return -EINVAL; + } + memcpy(data, fw_entry->data, fw_size); + + reg = IIC_FW_VER; + byteno = 2; + if (ndt_read_register(reg, ic_fw_ver, byteno) > 0) { + pr_debug("ndt:reg=0x%02x,byteno=%d\n", reg, byteno); + } else { + pr_err("ndt:failed!\n"); + } + memcpy(file_fw_ver, data + 8, sizeof(file_fw_ver)); + pr_info("ndt:read file_fw_ver: %02x%02x\n", file_fw_ver[0], + file_fw_ver[1]); + ret = snprintf(buf, PAGE_SIZE, + "ic_fw_ver:%02x%02x,file_fw_ver:%02x%02x\n", + ic_fw_ver[0], ic_fw_ver[1], file_fw_ver[1], + file_fw_ver[0]); + release_firmware(fw_entry); + kfree(data); + data = NULL; + return ret; +} + +static ssize_t ndt_reset_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + int yes_no; + + yes_no = simple_strtoul(buf, NULL, 10); + + if (yes_no == 1) + ndt_reset(); + return count; +} + +static ssize_t ndt_irq_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int yes_no; + + yes_no = simple_strtoul(buf, NULL, 10); + + if (yes_no == 1) + enable_irq(g_ndt_client->irq); + else + disable_irq(g_ndt_client->irq); + return count; +} + +#define MIN_LIMIT 50 +#define MAX_LIMIT 10000 +static ssize_t ndt_threshold_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + int value; + unsigned char buffer[10]; + + ret = sscanf(buf, "%d", &value); + if (ret != 1 || value < MIN_LIMIT || value > MAX_LIMIT) { + pr_err("failed to set trigger value -- invalid argumet\n"); + return -EINVAL; + } + + buffer[0] = 0x32; + ndt_write_register(0x80, buffer, 1); + msleep(20); + + buffer[0] = 0x00; + buffer[1] = 0x00; + buffer[2] = value & 0xFF; + buffer[3] = (value >> 8) & 0xFF; + buffer[4] = (value >> 16) & 0xFF; + buffer[5] = (value >> 24) & 0xFF; + ndt_write_register(0x82, buffer, 6); + msleep(20); + + buffer[0] = 0x06; + ndt_write_register(0x81, buffer, 1); + msleep(100); + + buffer[0] = 0x00; + ndt_write_register(0x80, buffer, 1); + pr_info("%s,threshold:%d\n", __func__, value); + + return count; +} + +static ssize_t ndt_reset_and_read_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int yes_no; + int error = 0; + struct ndt_force_data *data = i2c_get_clientdata(g_ndt_client); + static unsigned char g_ver[2] = { 0 }; + + yes_no = simple_strtoul(buf, NULL, 10); + + if (yes_no == 1) { + error = regulator_disable(data->ndt_vdd); + msleep(20); + error = regulator_enable(data->ndt_vdd); + msleep(10); + } + /*i2c test */ + error = ndt_read_register(0x05, g_ver, 2); + if (error < 0) { + pr_err("ndt:i2c test error\n"); + } else + pr_info("ndt:i2c test ok,g_ver:0x%x:0x%x\n", g_ver[0], + g_ver[1]); + return count; +} + +static ssize_t pressure_erase_fw_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ndt_force_data *data = i2c_get_clientdata(g_ndt_client); + int yes_no = simple_strtoul(buf, NULL, 10); + + if (yes_no != 1) { + pr_info("ndt:no need update fw\n"); + return count; + } + disable_irq(data->client->irq); + ndt_reset(); + ndt_eeprom_erase(); + enable_irq(data->client->irq); + return count; +} + +static ssize_t pressure_update_fw_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int len = 0; + char *fw_name; + + len = strnlen(buf, count); + fw_name = kzalloc(len + 1, GFP_KERNEL); + if (fw_name == NULL) + return -ENOMEM; + if (count > 0) { + strlcpy(fw_name, buf, len); + if (fw_name[len - 1] == '\n') + fw_name[len - 1] = 0; + else + fw_name[len] = 0; + } + pr_info("ndt:fw_name%s\n", fw_name); + ndt_update_fw(false, fw_name); + return count; +} + +static int ndt_eeprom_erase(void) +{ + unsigned char erase_cmd[10]; + unsigned short reg; + int byteno = 0; + + if (g_ndt_client == NULL) + return 0; + + /*erase flash*/ + reg = IIC_EEPROM; + erase_cmd[byteno++] = 0xaa; + erase_cmd[byteno++] = 0x55; + erase_cmd[byteno++] = 0xa5; + erase_cmd[byteno++] = 0x5a; + + if (ndt_write_eeprom(reg, erase_cmd, byteno) > 0) { + pr_debug("ndt:reg=0x%02x,byteno=%d\n", reg, byteno); + } else { + pr_err("ndt:failed!\n"); + return 0; + } + + msleep(2000); + return 1; +} + +static int ndt_eeprom_skip(void) +{ + unsigned char erase_cmd[10]; + unsigned short reg; + int byteno = 0; + + ndt_reset(); + msleep(100); + + if (g_ndt_client == NULL) + return 0; + + reg = IIC_EEPROM; + byteno = 0; + erase_cmd[byteno++] = 0x7e; + erase_cmd[byteno++] = 0xe7; + erase_cmd[byteno++] = 0xee; + erase_cmd[byteno++] = 0x77; + + if (ndt_write_eeprom(reg, erase_cmd, byteno) > 0) { + pr_debug("ndt:reg=0x%02x,byteno=%d\n", reg, byteno); + } else { + pr_err("ndt:failed!\n"); + return 0; + } + + return 1; +} + +int ndt_update_fw(bool force, char *fw_name) +{ + loff_t pos = 0; + char fw_data_len[4]; + int len = 0; + char *fw_data = NULL; + char *data = NULL; + char tmpbuf[10]; + unsigned char ic_fw_ver[2]; + unsigned char reg = 0; + int byteno = 0; + unsigned char file_fw_ver[2]; + int ret = 1; + int fw_size = 0; + const struct firmware *fw_entry = NULL; + struct ndt_force_data *ndt_data = NULL; + i2c_get_clientdata(g_ndt_client); + + if (g_ndt_client == NULL) + return -EINVAL; + ndt_data = i2c_get_clientdata(g_ndt_client); + if (!force && ndt_data->fw_updated) { + pr_info("ndt fw aleady updated or fw is updating,no need to update fw\n"); + return ret; + } + disable_irq(g_ndt_client->irq); + ret = request_firmware(&fw_entry, fw_name, &(g_ndt_client->dev)); + if (ret != 0) { + pr_err("%s request firmware failed\n", __func__); + enable_irq(g_ndt_client->irq); + ndt_threshold_store(&g_ndt_client->dev, NULL, "70", 2); + return -EINVAL; + } + + fw_size = fw_entry->size; + data = (char *)kzalloc(fw_size * sizeof(char), GFP_KERNEL); + if (data == NULL) { + pr_err("%s kzalloc memory fail\n", __func__); + ret = -EINVAL; + goto FAIL; + } + memcpy(data, fw_entry->data, fw_size); + memcpy(tmpbuf, data, sizeof(tmpbuf)); + pr_debug("ndt:file header: 0x%02x%02x\n", tmpbuf[0], tmpbuf[1]); + pos = 8; + data += pos; + reg = IIC_FW_VER; + byteno = 2; + ic_fw_ver[0] = 0; + ic_fw_ver[1] = 0; + if (ndt_read_register(reg, ic_fw_ver, byteno) > 0) { + pr_info("ndt:ic_fw_ver: %02x%02x\n", ic_fw_ver[0], + ic_fw_ver[1]); + } else + pr_err("ndt:failed!\n"); + memcpy(file_fw_ver, data, sizeof(file_fw_ver)); + pr_info("ndt:read file_fw_ver: %02x%02x\n", file_fw_ver[0], + file_fw_ver[1]); + if ((ic_fw_ver[0] | (ic_fw_ver[1] << 8)) == + (file_fw_ver[1] | (file_fw_ver[0] << 8))) { + if (!force) { + pr_info("ndt:fw version is equal,no need update!\n"); + ret = -EINVAL; + goto FAIL; + } + } + pos = 12 - 8; + data += pos; + memcpy(fw_data_len, data, sizeof(fw_data_len)); + pr_debug("ndt:read fw_data_len: 0x%02x%02x%02x%02x\n", fw_data_len[0], + fw_data_len[1], fw_data_len[2], fw_data_len[3]); + len = (int)((unsigned int)fw_data_len[3] << 0) | + ((unsigned int)fw_data_len[2] << 8) | + ((unsigned int)fw_data_len[1] << 16) | (fw_data_len[0] << 24); + fw_data = (char *)kzalloc(len, GFP_KERNEL); + if (fw_data == NULL) { + pr_err("%s malloc fw_data error", __func__); + ret = -EINVAL; + goto FAIL; + } + pos = 0x100 - 0x0c; + data += pos; + memcpy(fw_data, data, len); + + if (ndt_burn_fw(fw_data, len) == 0) { + pr_err("ndt:Burn FW failed!\n"); + ret = -EINVAL; + } +FAIL: + if (data) { + kfree(data); + data = NULL; + } + if (fw_data) { + kfree(fw_data); + fw_data = NULL; + } + release_firmware(fw_entry); + enable_irq(g_ndt_client->irq); + ndt_threshold_store(&g_ndt_client->dev, NULL, "70", 2); + return ret; +} + +static ssize_t pressure_force_update_fw_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int len = 0; + char *fw_name; + + len = strnlen(buf, count); + fw_name = kzalloc(len + 1, GFP_KERNEL); + if (fw_name == NULL) + return -ENOMEM; + if (count > 0) { + strlcpy(fw_name, buf, len); + if (fw_name[len - 1] == '\n') + fw_name[len - 1] = 0; + else + fw_name[len] = 0; + } + pr_info("ndt:fw_name%s\n", fw_name); + ndt_update_fw(true, fw_name); + return count; +} + +#endif + +bool ndt_is_pressed(void) +{ + struct ndt_force_data *data = NULL; + + if (g_ndt_client == NULL) + return false; + else { + data = i2c_get_clientdata(g_ndt_client); + return data->released; + } +} + +static ssize_t pressure_pressure_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int pressure, count; + int touch_down, x, y; + + fts_get_pointer(&touch_down, &x, &y); + pressure = ndt_get_pressure(touch_down, x, y); + + count = snprintf(buf, PAGE_SIZE, "Pressure:%d\n", pressure); + return count; +} + +static ssize_t pressure_fw_info_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int i = 0; + char s_dev_id[30]; + ssize_t ret; + unsigned char dev_id[10]; + unsigned char manu_id[2]; + unsigned char module_id[2]; + unsigned char fw_ver[2]; + unsigned char reg; + int byteno = 0; + + memset(dev_id, 0, sizeof(dev_id)); + memset(manu_id, 0, sizeof(manu_id)); + memset(module_id, 0, sizeof(module_id)); + memset(fw_ver, 0, sizeof(fw_ver)); + reg = IIC_DEV_ID; + byteno = 10; + + if (ndt_read_register(reg, dev_id, byteno) > 0) { + pr_debug("ndt:reg=0x%02x,byteno=%d\n", reg, byteno); + } else { + pr_err("ndt:failed!\n"); + } + + reg = IIC_MANU_ID; + byteno = 2; + + if (ndt_read_register(reg, manu_id, byteno) > 0) { + pr_debug("ndt:reg=0x%02x,byteno=%d\n", reg, byteno); + } else { + pr_err("ndt:failed!\n"); + } + + reg = IIC_MODULE_ID; + byteno = 2; + + if (ndt_read_register(reg, module_id, byteno) > 0) { + pr_debug("ndt:reg=0x%02x,byteno=%d\n", reg, byteno); + } else { + pr_err("ndt:failed!\n"); + } + + reg = IIC_FW_VER; + byteno = 2; + + if (ndt_read_register(reg, fw_ver, byteno) > 0) { + pr_debug("ndt:reg=0x%02x,byteno=%d\n", reg, byteno); + } else { + pr_err("ndt:failed!\n"); + } + + memset(s_dev_id, 0, 30); + + for (i = 0; i < 10; i++) { + snprintf(s_dev_id + 2 * i, PAGE_SIZE, "%02x", dev_id[i]); + } + + ret = snprintf( + buf, PAGE_SIZE, + "device id:%s,manu id:%02x%02x,module id:%02x%02x,fw version:%02x%02x\n", + s_dev_id, manu_id[0], manu_id[1], module_id[0], module_id[1], + fw_ver[0], fw_ver[1]); + return ret + 1; +} + +static ssize_t ndt_threshold_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + int value; + int retry = 0; + unsigned char buffer[10]; + + buffer[0] = 0x33; + ndt_write_register(0x80, buffer, 1); + msleep(20); + buffer[0] = 0x00; + buffer[1] = 0x00; + ndt_write_register(0x82, buffer, 2); + msleep(20); + buffer[0] = 0x02; + ndt_write_register(0x81, buffer, 1); + msleep(20); + /* check if ready*/ + do { + ndt_read_register(0x81, buffer, 1); + if (buffer[0] == 1 || buffer[0] == 4) + break; + msleep(20); + } while (retry++ < 5); + if (buffer[0] != 4) { + ret = snprintf(buf, PAGE_SIZE, "failed to read back threshold"); + goto exit_error; + } + ndt_read_register(0x82, buffer, 4); + value = buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0]; + ret = snprintf(buf, PAGE_SIZE, "threshold: %d\n", value); +exit_error: + buffer[0] = 0x00; + ndt_write_register(0x80, buffer, 1); + return ret; +} + +#ifdef CONFIG_INPUT_NDT_FWUPDATE +static int ndt_read_eeprom(unsigned short reg, unsigned char *datbuf, + int byteno) +{ + struct i2c_msg msg[2]; + int ret; + unsigned char reg16[2]; + int count = 0; + + if (!datbuf) + return -EINVAL; + + reg16[0] = (reg >> 8) & 0xff; + reg16[1] = reg & 0xff; + msg[0].addr = g_ndt_client->addr; + msg[0].flags = 0; + msg[0].len = 2; + msg[0].buf = reg16; + msg[1].addr = g_ndt_client->addr; + msg[1].flags = I2C_M_RD; + msg[1].len = byteno; + msg[1].buf = datbuf; + do { + ret = i2c_transfer(g_ndt_client->adapter, msg, 2); + if (ret >= 0) + break; + msleep(1); + } while (count++ < 5); + + if (ret < 0) { + pr_err("ndt:i2c_transfer Error ! err_code:%d\n", ret); + } else { + pr_debug("ndt:i2c_transfer OK !\n"); + } + + return ret; +} + +static int ndt_write_eeprom(unsigned short reg, unsigned char *datbuf, + int byteno) +{ + unsigned char *buf; + struct i2c_msg msg; + int ret; + int count = 0; + + if (!datbuf) + return -EINVAL; + + buf = (unsigned char *)kmalloc(byteno + 2, GFP_KERNEL); + + if (!buf) + return -EINVAL; + + memset(buf, 0, byteno + 2); + buf[0] = (reg >> 8) & 0xff; + buf[1] = reg & 0xff; + memcpy(buf + 2, datbuf, byteno); + msg.addr = g_ndt_client->addr; + msg.flags = 0; + msg.len = byteno + 2; + msg.buf = buf; + do { + ret = i2c_transfer(g_ndt_client->adapter, &msg, 1); + if (ret >= 0) + break; + msleep(1); + } while (count++ < 5); + + if (ret < 0) { + pr_err("ndt:i2c_master_send Error ! err_code:%d\n", ret); + } else { + pr_debug("ndt:i2c_master_send OK !\n"); + } + + kfree(buf); + return ret; +} +#endif + +#ifdef CONFIG_INPUT_NDT_INTERRUPT +static void ndt_abs_input_report(struct ndt_force_data *data, int pressure) +{ + if (fts_is_infod()) { + input_report_abs(data->input_dev, ABS_MT_PRESSURE, pressure); + input_sync(data->input_dev); + } +} + +bool ndt_down_flag; + +static void ndt_release_work(struct work_struct *work) +{ + struct ndt_force_data *data = + container_of(work, struct ndt_force_data, release_work); + int pressure = 0; + int touch_down, x, y; + + fts_get_pointer(&touch_down, &x, &y); + pressure = ndt_get_pressure(touch_down, x, y); + pr_info("%s,pressure:%d\n", __func__, pressure); + if (pressure < RELEASE_THRE) { + input_report_abs(data->input_dev, ABS_MT_PRESSURE, 0); + input_sync(data->input_dev); + } + ndt_down_flag = false; + /* +#ifdef CONFIG_TOUCHSCREEN_ST_CORE + fts_senseoff_without_cal(); +#endif +*/ +} + +static enum hrtimer_restart ndt_timer_func(struct hrtimer *timer) +{ + struct ndt_force_data *data = + container_of(timer, struct ndt_force_data, release_timer); + + data->released = 1; + queue_work(data->event_wq, &data->release_work); + return HRTIMER_NORESTART; +} + +static irqreturn_t ndt_force_interrupt(int irq, void *dev_id) +{ + struct ndt_force_data *data = (struct ndt_force_data *)dev_id; + int pressure; + int touch_down, x, y; + + pr_debug("%s\n", __func__); + fts_get_pointer(&touch_down, &x, &y); + pressure = ndt_get_pressure(touch_down, x, y); + if (!ndt_down_flag) { + pr_info("ndt down in the fod area,pressure:%d\n", pressure); + ndt_down_flag = true; + } + /* +#ifdef CONFIG_TOUCHSCREEN_ST_CORE + fts_senseon_without_cal(); +#endif +*/ + ndt_abs_input_report(data, pressure); + if (data->released == 1) + hrtimer_start(&data->release_timer, + ktime_set(0, 15 * 1000 * 1000), HRTIMER_MODE_REL); + if (!data->released) { + hrtimer_start_range_ns(&data->release_timer, + ns_to_ktime(15 * 1000 * 1000), 0, + HRTIMER_MODE_REL); + } + data->released = 0; + return IRQ_HANDLED; +} +#endif + +static int ndt_open(struct inode *inode, struct file *file) +{ + if (g_ndt_client == NULL) { + return -EINVAL; + } else { + return 0; + } +} + +static int ndt_close(struct inode *inode, struct file *file) +{ + return 0; +} + +static ssize_t ndt_read(struct file *file, char __user *buf, size_t count, + loff_t *offset) +{ + char *kbuf = NULL; + int err = 0; + char reg = 0; + + kbuf = kzalloc(count, GFP_KERNEL); + if (!kbuf) { + err = -ENOMEM; + goto exit; + } + /*get reg addr buf[0]*/ + if (copy_from_user(®, buf, 1)) { + err = -EFAULT; + goto exit_kfree; + } + + ndt_read_register(reg, kbuf, count); + + if (copy_to_user(buf + 1, kbuf, count)) + err = -EFAULT; +exit_kfree: + kfree(kbuf); + +exit: + return err; +} + +static ssize_t ndt_write(struct file *file, const char __user *buf, + size_t count, loff_t *offset) +{ + char *kbuf = NULL; + int err = 0; + char reg = 0; + + kbuf = kzalloc(count, GFP_KERNEL); + if (!kbuf) { + err = -ENOMEM; + goto exit; + } + + if (copy_from_user(®, buf, 1) || + copy_from_user(kbuf, buf + 1, count)) { + err = -EFAULT; + goto exit_kfree; + } + + ndt_write_register(reg, kbuf, count); +exit_kfree: + kfree(kbuf); + +exit: + return err; +} + +static const struct file_operations ndt_fops = { + .owner = THIS_MODULE, + .read = ndt_read, + .write = ndt_write, + .open = ndt_open, + .release = ndt_close, +}; + +static struct miscdevice ndt_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "ndt_i2c_node", + .fops = &ndt_fops, +}; + +static int ndt_parse_dt(struct device *dev, struct ndt_platform_data *pdata) +{ + struct device_node *np = dev->of_node; + + if (!np) + return -EINVAL; + /* irq gpio */ + pdata->irq_gpio = of_get_named_gpio(np, "ndt,irq-gpio", 0); + return 0; +} + +#ifdef CONFIG_PM +static int ndt_pm_suspend(struct device *dev) +{ + struct ndt_force_data *data = dev_get_drvdata(dev); + pr_info("%s enable ndt irq wake\n", __func__); + enable_irq_wake(data->client->irq); +#ifdef CONFIG_INPUT_NDT_INTERRUPT + hrtimer_cancel(&data->release_timer); + cancel_work(&data->release_work); +#endif + data->suspend_flag = 1; + return 0; +} + +static int ndt_pm_resume(struct device *dev) +{ + struct ndt_force_data *data = dev_get_drvdata(dev); + pr_info("%s disable ndt irq wake\n", __func__); + disable_irq_wake(data->client->irq); + data->suspend_flag = 0; + return 0; +} + +static const struct dev_pm_ops ndt_dev_pm_ops = { + .suspend = ndt_pm_suspend, + .resume = ndt_pm_resume, +}; +#endif + +static int ndt_force_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ndt_force_data *data; + int error = -EINVAL; + static unsigned char g_ver[2] = { 0 }; + + data = kzalloc(sizeof(struct ndt_force_data), GFP_KERNEL); + if (!data) { + dev_err(&client->dev, "Failed to allocate memory for data!\n"); + return -ENOMEM; + } + + data->pdata = kzalloc(sizeof(struct ndt_platform_data), GFP_KERNEL); + if (!data->pdata) { + dev_err(&client->dev, "Failed to allocate memory for data!\n"); + goto ndt_free_data; + } + + error = ndt_parse_dt(&client->dev, data->pdata); + if (error < 0) { + dev_err(&client->dev, "Failed to get pdata!\n"); + goto ndt_free_pdata; + } + + error = i2c_check_functionality(client->adapter, I2C_FUNC_I2C); + if (!error) { + dev_err(&client->dev, "I2C check functionality failed\n"); + goto ndt_free_pdata; + } + /* enable power */ + data->ndt_vdd = regulator_get(&client->dev, "ndt,vdd"); + if (IS_ERR(data->ndt_vdd)) { + dev_err(&client->dev, "failed to get ndt vdd"); + goto ndt_free_pdata; + } + error = regulator_enable(data->ndt_vdd); + if (error < 0) { + dev_err(&client->dev, "Failed to enable power regulator\n"); + goto ndt_free_pdata; + } + + data->ndt_vddio = regulator_get(&client->dev, "ndt,vddio"); + if (IS_ERR(data->ndt_vddio)) { + dev_err(&client->dev, "failed to get ndt vdd"); + goto ndt_free_pdata; + } + error = regulator_enable(data->ndt_vddio); + if (error < 0) { + dev_err(&client->dev, "Failed to enable power regulator\n"); + goto ndt_free_pdata; + } + + if (data->pdata->irq_gpio) { + error = gpio_request(data->pdata->irq_gpio, + "ndt_force_irq_gpio"); + if (error) { + dev_err(&client->dev, "Unable to request gpio [%d]\n", + data->pdata->irq_gpio); + goto ndt_vddio_disable; + } + error = gpio_direction_input(data->pdata->irq_gpio); + if (error) { + dev_err(&client->dev, + "unable to set direction for gpio [%d]\n", + data->pdata->irq_gpio); + goto ndt_free_irq_gpio; + } + client->irq = gpio_to_irq(data->pdata->irq_gpio); + } + data->client = client; + i2c_set_clientdata(data->client, data); + g_ndt_client = client; + data->fw_updated = false; + + /* Initialize input device */ + data->input_dev = input_allocate_device(); + + if (!data->input_dev) { + dev_err(&client->dev, "Failed to allocate input device\n"); + goto ndt_free_irq_gpio; + } + data->input_dev->name = "ndt_force"; + data->input_dev->id.bustype = BUS_I2C; + data->input_dev->dev.parent = &data->client->dev; + input_set_capability(data->input_dev, EV_KEY, KEY_POWER); + input_set_abs_params(data->input_dev, ABS_MT_PRESSURE, 0, 2048, 0, 0); + input_set_drvdata(data->input_dev, data); + dev_set_drvdata(&data->client->dev, data); + __set_bit(EV_SYN, data->input_dev->evbit); + __set_bit(EV_KEY, data->input_dev->evbit); + error = input_register_device(data->input_dev); + + if (error) { + dev_err(&client->dev, + "Unable to register input device, error: %d\n", error); + goto ndt_free_irq_gpio; + } + + msleep(10); + /*i2c test *, if i2c error ,maybe fw is wrong ,so goon*/ + error = ndt_read_register(0x05, g_ver, 2); + if (error < 0) { + pr_err("ndt:i2c test error, maybe fw fail, force update fw\n"); + error = ndt_update_fw(1, "ndt_fw.bin"); + if (error == -EINVAL) { + pr_err("ndt:i2c error after fw update, unregister device\n"); + goto ndt_free_input_dev; + } else { + pr_err("i2c is ok after fw update\n"); + data->fw_updated = true; + } + } else + pr_info("ndt:i2c test ok,g_ver:0x%x:0x%x\n", g_ver[0], + g_ver[1]); + error = sysfs_create_group(&client->dev.kobj, &ndt_attr_group); + + if (error) + dev_err(&client->dev, "Failure %d creating sysfs group\n", + error); + + data->event_wq = create_singlethread_workqueue("ndt-event-queue"); +#ifdef CONFIG_INPUT_NDT_INTERRUPT + INIT_WORK(&data->release_work, ndt_release_work); + hrtimer_init(&data->release_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + data->release_timer.function = ndt_timer_func; + data->released = 1; + error = request_threaded_irq(client->irq, NULL, ndt_force_interrupt, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + client->dev.driver->name, data); + + if (error) { + dev_err(&client->dev, "Error %d registering irq\n", error); + goto ndt_free_input_dev; + } +#endif + misc_register(&ndt_misc); + ndt_input_dev = data->input_dev; + pr_info("%s,probe ok\n", __func__); + return 0; +ndt_free_input_dev: + input_unregister_device(data->input_dev); + g_ndt_client = NULL; +ndt_free_irq_gpio: + gpio_free(data->pdata->irq_gpio); +ndt_vddio_disable: + regulator_disable(data->ndt_vddio); +ndt_free_pdata: + kfree(data->pdata); + data->pdata = NULL; +ndt_free_data: + kfree(data); + data = NULL; + return error; +} + +static const struct i2c_device_id cyt_id[] = { + { "ndt_press", 0 }, + {}, +}; + +static struct of_device_id ndt_match_table[] = { + { + .compatible = "ndt,press", + }, + {}, +}; + +static int ndt_force_remove(struct i2c_client *client) +{ + struct ndt_force_data *data = i2c_get_clientdata(client); + struct ndt_platform_data *pdata = data->pdata; + + misc_deregister(&ndt_misc); + free_irq(client->irq, data); + if (data->input_dev != NULL) + input_unregister_device(data->input_dev); + + gpio_free(pdata->irq_gpio); + if (pdata != NULL) { + kfree(pdata); + pdata = NULL; + } + if (data != NULL) { + kfree(data); + data = NULL; + } + return 0; +} + +static struct i2c_driver ndt_force_driver = { + .driver = { + .name = "ndt_press", + .owner = THIS_MODULE, + .of_match_table = ndt_match_table, +#ifdef CONFIG_PM + .pm = &ndt_dev_pm_ops, +#endif + }, + .probe = ndt_force_probe, + .remove = ndt_force_remove, + .id_table = cyt_id, +}; + +static int __init ndt_force_init(void) +{ + return i2c_add_driver(&ndt_force_driver); +} + +static void __exit ndt_force_exit(void) +{ + i2c_del_driver(&ndt_force_driver); +} + +module_init(ndt_force_init); +module_exit(ndt_force_exit); + +MODULE_AUTHOR("Liuyinghong "); +MODULE_DESCRIPTION("Ndt Press Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/xiaomi/ndt_core.h b/drivers/input/touchscreen/xiaomi/ndt_core.h new file mode 100644 index 000000000000..78650cac565a --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/ndt_core.h @@ -0,0 +1,3 @@ +int ndt_update_fw(bool force, char *fw_name); +bool ndt_is_pressed(void); +int ndt_get_pressure(int touch_flag, int x, int y); diff --git a/drivers/input/touchscreen/xiaomi/nt36523/Kconfig b/drivers/input/touchscreen/xiaomi/nt36523/Kconfig new file mode 100644 index 000000000000..c67b1b795d4e --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36523/Kconfig @@ -0,0 +1,11 @@ +# +# Novatek NT36523 touchscreen driver configuration +# +config TOUCHSCREEN_NT36523_HOSTDL_SPI + tristate "Novatek NT36523 host download SPI driver" + default n + help + Say Y here if you have a Novatek NT36523 no flash touchscreen connected + to your system by SPI bus. + + If unsure, say N. diff --git a/drivers/input/touchscreen/xiaomi/nt36523/Makefile b/drivers/input/touchscreen/xiaomi/nt36523/Makefile new file mode 100644 index 000000000000..4f0bf8732633 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36523/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for the Novatek NT36523 touchscreen driver. +# + +obj-$(CONFIG_TOUCHSCREEN_NT36523_HOSTDL_SPI) += nt36523_touch.o +nt36523_touch-y := nt36xxx.o \ + nt36xxx_fw_update.o \ + nt36xxx_ext_proc.o \ + nt36xxx_mp_ctrlram.o diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c new file mode 100644 index 000000000000..1851c7c5b5e6 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c @@ -0,0 +1,3992 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * $Revision: 73033 $ + * $Date: 2020-11-26 10:09:14 +0800 (週四, 26 å一月 2020) $ + * + * 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. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_FB) +#ifdef CONFIG_DRM +#include +#endif +#include +#include +#elif defined(CONFIG_HAS_EARLYSUSPEND) +#include +#endif + +#include "nt36xxx.h" +#ifndef NVT_SAVE_TESTDATA_IN_FILE +#include "nt36xxx_mp_ctrlram.h" +#endif +#if NVT_TOUCH_ESD_PROTECT +#include +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE +#include "../xiaomi/xiaomi_touch.h" +#endif + +#if NVT_TOUCH_ESD_PROTECT +static struct delayed_work nvt_esd_check_work; +static struct workqueue_struct *nvt_esd_check_wq; +static unsigned long irq_timer = 0; +uint8_t esd_check = false; +uint8_t esd_retry = 0; +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + +#if NVT_TOUCH_EXT_PROC +extern int32_t nvt_extra_proc_init(void); +extern void nvt_extra_proc_deinit(void); +#endif + +#if NVT_TOUCH_MP +extern int32_t nvt_mp_proc_init(void); +extern void nvt_mp_proc_deinit(void); +#endif + +struct nvt_ts_data *ts; + +#if BOOT_UPDATE_FIRMWARE +static struct workqueue_struct *nvt_fwu_wq; +static struct workqueue_struct *nvt_lockdown_wq; +extern void Boot_Update_Firmware(struct work_struct *work); +#endif + +#if defined(CONFIG_FB) +#ifdef CONFIG_DRM +static int nvt_drm_notifier_callback(struct notifier_block *self, + unsigned long event, void *data); +#else +static int nvt_fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data); +#endif +#elif defined(CONFIG_HAS_EARLYSUSPEND) +static void nvt_ts_early_suspend(struct early_suspend *h); +static void nvt_ts_late_resume(struct early_suspend *h); +#endif + +static int32_t nvt_ts_suspend(struct device *dev); +static int32_t nvt_ts_resume(struct device *dev); +extern int dsi_panel_lockdown_info_read(unsigned char *plockdowninfo); +extern void dsi_panel_doubleclick_enable(bool on); +extern void touch_irq_boost(void); +extern void lpm_disable_for_input(bool on); +extern int pen_charge_state_notifier_register_client(struct notifier_block *nb); +extern int +pen_charge_state_notifier_unregister_client(struct notifier_block *nb); + +uint32_t ENG_RST_ADDR = 0x7FFF80; +uint32_t SWRST_N8_ADDR = 0; //read from dtsi +uint32_t SPI_RD_FAST_ADDR = 0; //read from dtsi + +#if TOUCH_KEY_NUM > 0 +const uint16_t touch_key_array[TOUCH_KEY_NUM] = { KEY_BACK, KEY_HOME, + KEY_MENU }; +#endif + +#if WAKEUP_GESTURE +const uint16_t gesture_key_array[] = { + KEY_POWER, //GESTURE_WORD_C + KEY_POWER, //GESTURE_WORD_W + KEY_POWER, //GESTURE_WORD_V + KEY_WAKEUP, //GESTURE_DOUBLE_CLICK + KEY_POWER, //GESTURE_WORD_Z + KEY_POWER, //GESTURE_WORD_M + KEY_POWER, //GESTURE_WORD_O + KEY_POWER, //GESTURE_WORD_e + KEY_POWER, //GESTURE_WORD_S + KEY_POWER, //GESTURE_SLIDE_UP + KEY_POWER, //GESTURE_SLIDE_DOWN + KEY_POWER, //GESTURE_SLIDE_LEFT + KEY_POWER, //GESTURE_SLIDE_RIGHT + KEY_WAKEUP, //GESTURE_PEN_ONE_CLICK +}; +#endif + +#ifdef CONFIG_MTK_SPI +const struct mt_chip_conf spi_ctrdata = { + .setuptime = 25, + .holdtime = 25, + .high_time = 5, /* 10MHz (SPI_SPEED=100M / (high_time+low_time(10ns)))*/ + .low_time = 5, + .cs_idletime = 2, + .ulthgh_thrsh = 0, + .cpol = 0, + .cpha = 0, + .rx_mlsb = 1, + .tx_mlsb = 1, + .tx_endian = 0, + .rx_endian = 0, + .com_mod = DMA_TRANSFER, + .pause = 0, + .finish_intr = 1, + .deassert = 0, + .ulthigh = 0, + .tckdly = 0, +}; +#endif + +#ifdef CONFIG_SPI_MT65XX +const struct mtk_chip_config spi_ctrdata = { + .rx_mlsb = 1, + .tx_mlsb = 1, + .cs_pol = 0, +}; +#endif + +static ssize_t nvt_panel_color_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%c\n", ts->lockdown_info[2]); +} + +static ssize_t nvt_panel_vendor_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%c\n", ts->lockdown_info[6]); +} + +static ssize_t nvt_panel_display_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%c\n", ts->lockdown_info[1]); +} + +static DEVICE_ATTR(panel_color, (S_IRUGO), nvt_panel_color_show, NULL); +static DEVICE_ATTR(panel_vendor, (S_IRUGO), nvt_panel_vendor_show, NULL); +static DEVICE_ATTR(panel_display, (S_IRUGO), nvt_panel_display_show, NULL); + +struct attribute *nvt_panel_attr[] = { + &dev_attr_panel_color.attr, + &dev_attr_panel_vendor.attr, + &dev_attr_panel_display.attr, + NULL, +}; + +static uint8_t bTouchIsAwake = 0; + +/******************************************************* +Description: + Novatek touchscreen irq enable/disable function. + +return: + n.a. +*******************************************************/ +static void nvt_irq_enable(bool enable) +{ + struct irq_desc *desc; + + if (enable) { + if (!ts->irq_enabled) { + enable_irq(ts->client->irq); + ts->irq_enabled = true; + } + } else { + if (ts->irq_enabled) { + disable_irq(ts->client->irq); + ts->irq_enabled = false; + } + } + + desc = irq_to_desc(ts->client->irq); + NVT_LOG("enable=%d, desc->depth=%d\n", enable, desc->depth); +} + +/******************************************************* +Description: + Novatek touchscreen spi read/write core function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static inline int32_t spi_read_write(struct spi_device *client, uint8_t *buf, + size_t len, NVT_SPI_RW rw) +{ + struct spi_message m; + struct spi_transfer t = { + .len = len, + }; + + memset(ts->xbuf, 0, len + DUMMY_BYTES); + memcpy(ts->xbuf, buf, len); + + switch (rw) { + case NVTREAD: + t.tx_buf = ts->xbuf; + t.rx_buf = ts->rbuf; + t.len = (len + DUMMY_BYTES); + break; + + case NVTWRITE: + t.tx_buf = ts->xbuf; + break; + } + + spi_message_init(&m); + spi_message_add_tail(&t, &m); + return spi_sync(client, &m); +} + +/******************************************************* +Description: + Novatek touchscreen spi read function. + +return: + Executive outcomes. 2---succeed. -5---I/O error +*******************************************************/ +int32_t CTP_SPI_READ(struct spi_device *client, uint8_t *buf, uint16_t len) +{ + int32_t ret = -1; + int32_t retries = 0; + + mutex_lock(&ts->xbuf_lock); + + buf[0] = SPI_READ_MASK(buf[0]); + + while (retries < 5) { + ret = spi_read_write(client, buf, len, NVTREAD); + if (ret == 0) + break; + retries++; + } + + if (unlikely(retries == 5)) { + NVT_ERR("read error, ret=%d\n", ret); + ret = -EIO; + } else { + memcpy((buf + 1), (ts->rbuf + 2), (len - 1)); + } + + mutex_unlock(&ts->xbuf_lock); + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen spi write function. + +return: + Executive outcomes. 1---succeed. -5---I/O error +*******************************************************/ +int32_t CTP_SPI_WRITE(struct spi_device *client, uint8_t *buf, uint16_t len) +{ + int32_t ret = -1; + int32_t retries = 0; + + mutex_lock(&ts->xbuf_lock); + + buf[0] = SPI_WRITE_MASK(buf[0]); + + while (retries < 5) { + ret = spi_read_write(client, buf, len, NVTWRITE); + if (ret == 0) + break; + retries++; + } + + if (unlikely(retries == 5)) { + NVT_ERR("error, ret=%d\n", ret); + ret = -EIO; + } + + mutex_unlock(&ts->xbuf_lock); + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen set index/page/addr address. + +return: + Executive outcomes. 0---succeed. -5---access fail. +*******************************************************/ +int32_t nvt_set_page(uint32_t addr) +{ + uint8_t buf[4] = { 0 }; + + buf[0] = 0xFF; //set index/page/addr command + buf[1] = (addr >> 15) & 0xFF; + buf[2] = (addr >> 7) & 0xFF; + + return CTP_SPI_WRITE(ts->client, buf, 3); +} + +/******************************************************* +Description: + Novatek touchscreen write data to specify address. + +return: + Executive outcomes. 0---succeed. -5---access fail. +*******************************************************/ +int32_t nvt_write_addr(uint32_t addr, uint8_t data) +{ + int32_t ret = 0; + uint8_t buf[4] = { 0 }; + + //---set xdata index--- + buf[0] = 0xFF; //set index/page/addr command + buf[1] = (addr >> 15) & 0xFF; + buf[2] = (addr >> 7) & 0xFF; + ret = CTP_SPI_WRITE(ts->client, buf, 3); + if (ret) { + NVT_ERR("set page 0x%06X failed, ret = %d\n", addr, ret); + return ret; + } + + //---write data to index--- + buf[0] = addr & (0x7F); + buf[1] = data; + ret = CTP_SPI_WRITE(ts->client, buf, 2); + if (ret) { + NVT_ERR("write data to 0x%06X failed, ret = %d\n", addr, ret); + return ret; + } + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen enable hw bld crc function. + +return: + N/A. +*******************************************************/ +void nvt_bld_crc_enable(void) +{ + uint8_t buf[4] = { 0 }; + + //---set xdata index to BLD_CRC_EN_ADDR--- + nvt_set_page(ts->mmap->BLD_CRC_EN_ADDR); + + //---read data from index--- + buf[0] = ts->mmap->BLD_CRC_EN_ADDR & (0x7F); + buf[1] = 0xFF; + CTP_SPI_READ(ts->client, buf, 2); + + //---write data to index--- + buf[0] = ts->mmap->BLD_CRC_EN_ADDR & (0x7F); + buf[1] = buf[1] | (0x01 << 7); + CTP_SPI_WRITE(ts->client, buf, 2); +} + +/******************************************************* +Description: + Novatek touchscreen clear status & enable fw crc function. + +return: + N/A. +*******************************************************/ +void nvt_fw_crc_enable(void) +{ + uint8_t buf[4] = { 0 }; + + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR); + + //---clear fw reset status--- + buf[0] = EVENT_MAP_RESET_COMPLETE & (0x7F); + buf[1] = 0x00; + CTP_SPI_WRITE(ts->client, buf, 2); + + //---enable fw crc--- + buf[0] = EVENT_MAP_HOST_CMD & (0x7F); + buf[1] = 0xAE; //enable fw crc command + CTP_SPI_WRITE(ts->client, buf, 2); +} + +/******************************************************* +Description: + Novatek touchscreen set boot ready function. + +return: + N/A. +*******************************************************/ +void nvt_boot_ready(void) +{ + //---write BOOT_RDY status cmds--- + nvt_write_addr(ts->mmap->BOOT_RDY_ADDR, 1); + + mdelay(5); + + if (!ts->hw_crc) { + //---write BOOT_RDY status cmds--- + nvt_write_addr(ts->mmap->BOOT_RDY_ADDR, 0); + + //---write POR_CD cmds--- + nvt_write_addr(ts->mmap->POR_CD_ADDR, 0xA0); + } +} + +/******************************************************* +Description: + Novatek touchscreen enable auto copy mode function. + +return: + N/A. +*******************************************************/ +void nvt_tx_auto_copy_mode(void) +{ + //---write TX_AUTO_COPY_EN cmds--- + nvt_write_addr(ts->mmap->TX_AUTO_COPY_EN, 0x69); + + NVT_ERR("tx auto copy mode enable\n"); +} + +/******************************************************* +Description: + Novatek touchscreen check spi dma tx info function. + +return: + N/A. +*******************************************************/ +int32_t nvt_check_spi_dma_tx_info(void) +{ + uint8_t buf[8] = { 0 }; + int32_t i = 0; + const int32_t retry = 200; + + for (i = 0; i < retry; i++) { + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->SPI_DMA_TX_INFO); + + //---read fw status--- + buf[0] = ts->mmap->SPI_DMA_TX_INFO & 0x7F; + buf[1] = 0xFF; + CTP_SPI_READ(ts->client, buf, 2); + + if (buf[1] == 0x00) + break; + + usleep_range(1000, 1000); + } + + if (i >= retry) { + NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]); + return -1; + } else { + return 0; + } +} + +/******************************************************* +Description: + Novatek touchscreen eng reset cmd + function. + +return: + n.a. +*******************************************************/ +void nvt_eng_reset(void) +{ + //---eng reset cmds to ENG_RST_ADDR--- + nvt_write_addr(ENG_RST_ADDR, 0x5A); + + mdelay(1); //wait tMCU_Idle2TP_REX_Hi after TP_RST +} + +/******************************************************* +Description: + Novatek touchscreen reset MCU + function. + +return: + n.a. +*******************************************************/ +void nvt_sw_reset(void) +{ + //---software reset cmds to SWRST_N8_ADDR--- + nvt_write_addr(SWRST_N8_ADDR, 0x55); + + msleep(10); +} + +/******************************************************* +Description: + Novatek touchscreen reset MCU then into idle mode + function. + +return: + n.a. +*******************************************************/ +void nvt_sw_reset_idle(void) +{ + //---MCU idle cmds to SWRST_N8_ADDR--- + nvt_write_addr(SWRST_N8_ADDR, 0xAA); + + msleep(15); +} + +/******************************************************* +Description: + Novatek touchscreen reset MCU (boot) function. + +return: + n.a. +*******************************************************/ +void nvt_bootloader_reset(void) +{ + //---reset cmds to SWRST_N8_ADDR--- + nvt_write_addr(SWRST_N8_ADDR, 0x69); + + mdelay(5); //wait tBRST2FR after Bootload RST + + if (SPI_RD_FAST_ADDR) { + /* disable SPI_RD_FAST */ + nvt_write_addr(SPI_RD_FAST_ADDR, 0x00); + } +} + +/******************************************************* +Description: + Novatek touchscreen clear FW status function. + +return: + Executive outcomes. 0---succeed. -1---fail. +*******************************************************/ +int32_t nvt_clear_fw_status(void) +{ + uint8_t buf[8] = { 0 }; + int32_t i = 0; + const int32_t retry = 20; + + for (i = 0; i < retry; i++) { + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | + EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE); + + //---clear fw status--- + buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; + buf[1] = 0x00; + CTP_SPI_WRITE(ts->client, buf, 2); + + //---read fw status--- + buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; + buf[1] = 0xFF; + CTP_SPI_READ(ts->client, buf, 2); + + if (buf[1] == 0x00) + break; + + usleep_range(10000, 10000); + } + + if (i >= retry) { + NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]); + return -1; + } else { + return 0; + } +} + +/******************************************************* +Description: + Novatek touchscreen check FW status function. + +return: + Executive outcomes. 0---succeed. -1---failed. +*******************************************************/ +int32_t nvt_check_fw_status(void) +{ + uint8_t buf[8] = { 0 }; + int32_t i = 0; + const int32_t retry = 50; + + for (i = 0; i < retry; i++) { + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | + EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE); + + //---read fw status--- + buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; + buf[1] = 0x00; + CTP_SPI_READ(ts->client, buf, 2); + + if ((buf[1] & 0xF0) == 0xA0) + break; + + usleep_range(10000, 10000); + } + + if (i >= retry) { + NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]); + return -1; + } else { + return 0; + } +} + +/******************************************************* +Description: + Novatek touchscreen check FW reset state function. + +return: + Executive outcomes. 0---succeed. -1---failed. +*******************************************************/ +int32_t nvt_check_fw_reset_state(RST_COMPLETE_STATE check_reset_state) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + int32_t retry = 0; + int32_t retry_max = (check_reset_state == RESET_STATE_INIT) ? 10 : 50; + + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_RESET_COMPLETE); + + while (1) { + //---read reset state--- + buf[0] = EVENT_MAP_RESET_COMPLETE; + buf[1] = 0x00; + CTP_SPI_READ(ts->client, buf, 6); + + if ((buf[1] >= check_reset_state) && + (buf[1] <= RESET_STATE_MAX)) { + ret = 0; + break; + } + + retry++; + if (unlikely(retry > retry_max)) { + NVT_ERR("error, retry=%d, buf[1]=0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", + retry, buf[1], buf[2], buf[3], buf[4], buf[5]); + ret = -1; + break; + } + + usleep_range(10000, 10000); + } + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen get novatek project id information + function. + +return: + Executive outcomes. 0---success. -1---fail. +*******************************************************/ +int32_t nvt_read_pid(void) +{ + uint8_t buf[4] = { 0 }; + int32_t ret = 0; + + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_PROJECTID); + + //---read project id--- + buf[0] = EVENT_MAP_PROJECTID; + buf[1] = 0x00; + buf[2] = 0x00; + CTP_SPI_READ(ts->client, buf, 3); + + ts->nvt_pid = (buf[2] << 8) + buf[1]; + + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR); + + NVT_LOG("PID=%04X\n", ts->nvt_pid); + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen get firmware related information + function. + +return: + Executive outcomes. 0---success. -1---fail. +*******************************************************/ +int32_t nvt_get_fw_info(void) +{ + uint8_t buf[64] = { 0 }; + uint32_t retry_count = 0; + int32_t ret = 0; + +info_retry: + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_FWINFO); + + //---read fw info--- + buf[0] = EVENT_MAP_FWINFO; + CTP_SPI_READ(ts->client, buf, 39); + ts->fw_ver = buf[1]; + ts->x_num = buf[3]; + ts->y_num = buf[4]; + ts->abs_x_max = (uint16_t)((buf[5] << 8) | buf[6]); + ts->abs_y_max = (uint16_t)((buf[7] << 8) | buf[8]); + ts->max_button_num = buf[11]; + ts->cascade = buf[34] & 0x01; + if (ts->pen_support) { + ts->x_gang_num = buf[37]; + ts->y_gang_num = buf[38]; + } + + //---clear x_num, y_num if fw info is broken--- + if ((buf[1] + buf[2]) != 0xFF) { + NVT_ERR("FW info is broken! fw_ver=0x%02X, ~fw_ver=0x%02X\n", + buf[1], buf[2]); + ts->fw_ver = 0; + ts->x_num = 18; + ts->y_num = 32; + ts->abs_x_max = TOUCH_DEFAULT_MAX_WIDTH; + ts->abs_y_max = TOUCH_DEFAULT_MAX_HEIGHT; + ts->max_button_num = TOUCH_KEY_NUM; + + if (retry_count < 3) { + retry_count++; + NVT_ERR("retry_count=%d\n", retry_count); + goto info_retry; + } else { + NVT_ERR("Set default fw_ver=%d, x_num=%d, y_num=%d, " + "abs_x_max=%d, abs_y_max=%d, max_button_num=%d!\n", + ts->fw_ver, ts->x_num, ts->y_num, ts->abs_x_max, + ts->abs_y_max, ts->max_button_num); + ret = -1; + } + } else { + ret = 0; + } + + NVT_LOG("fw_ver = 0x%02X, fw_type = 0x%02X, x_num=%d, y_num=%d\n", + ts->fw_ver, buf[14], ts->x_num, ts->y_num); + + //---Get Novatek PID--- + nvt_read_pid(); + + return ret; +} + +/******************************************************* + Create Device Node (Proc Entry) +*******************************************************/ +#if NVT_TOUCH_PROC +static struct proc_dir_entry *NVT_proc_entry; +#define DEVICE_NAME "NVTSPI" + +/******************************************************* +Description: + Novatek touchscreen /proc/NVTSPI read function. + +return: + Executive outcomes. 2---succeed. -5,-14---failed. +*******************************************************/ +static ssize_t nvt_flash_read(struct file *file, char __user *buff, + size_t count, loff_t *offp) +{ + uint8_t *str = NULL; + int32_t ret = 0; + int32_t retries = 0; + int8_t spi_wr = 0; + uint8_t *buf; + + if ((count > NVT_TRANSFER_LEN + 3) || (count < 3)) { + NVT_ERR("invalid transfer len!\n"); + return -EFAULT; + } + + /* allocate buffer for spi transfer */ + str = (uint8_t *)kzalloc((count), GFP_KERNEL); + if (str == NULL) { + NVT_ERR("kzalloc for buf failed!\n"); + ret = -ENOMEM; + goto kzalloc_failed; + } + + buf = (uint8_t *)kzalloc((count), GFP_KERNEL | GFP_DMA); + if (buf == NULL) { + NVT_ERR("kzalloc for buf failed!\n"); + ret = -ENOMEM; + kfree(str); + str = NULL; + goto kzalloc_failed; + } + + if (copy_from_user(str, buff, count)) { + NVT_ERR("copy from user error\n"); + ret = -EFAULT; + goto out; + } + +#if NVT_TOUCH_ESD_PROTECT + /* + * stop esd check work to avoid case that 0x77 report righ after here to enable esd check again + * finally lead to trigger esd recovery bootloader reset + */ + cancel_delayed_work_sync(&nvt_esd_check_work); + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + spi_wr = str[0] >> 7; + memcpy(buf, str + 2, ((str[0] & 0x7F) << 8) | str[1]); + + if (spi_wr == NVTWRITE) { //SPI write + while (retries < 20) { + ret = CTP_SPI_WRITE(ts->client, buf, + ((str[0] & 0x7F) << 8) | str[1]); + if (!ret) + break; + else + NVT_ERR("error, retries=%d, ret=%d\n", retries, + ret); + + retries++; + } + + if (unlikely(retries == 20)) { + NVT_ERR("error, ret = %d\n", ret); + ret = -EIO; + goto out; + } + } else if (spi_wr == NVTREAD) { //SPI read + while (retries < 20) { + ret = CTP_SPI_READ(ts->client, buf, + ((str[0] & 0x7F) << 8) | str[1]); + if (!ret) + break; + else + NVT_ERR("error, retries=%d, ret=%d\n", retries, + ret); + + retries++; + } + + memcpy(str + 2, buf, ((str[0] & 0x7F) << 8) | str[1]); + // copy buff to user if spi transfer + if (retries < 20) { + if (copy_to_user(buff, str, count)) { + ret = -EFAULT; + goto out; + } + } + + if (unlikely(retries == 20)) { + NVT_ERR("error, ret = %d\n", ret); + ret = -EIO; + goto out; + } + } else { + NVT_ERR("Call error, str[0]=%d\n", str[0]); + ret = -EFAULT; + goto out; + } + +out: + kfree(str); + kfree(buf); +kzalloc_failed: + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen /proc/NVTSPI open function. + +return: + Executive outcomes. 0---succeed. -12---failed. +*******************************************************/ +static int32_t nvt_flash_open(struct inode *inode, struct file *file) +{ + struct nvt_flash_data *dev; + + dev = kmalloc(sizeof(struct nvt_flash_data), GFP_KERNEL); + if (dev == NULL) { + NVT_ERR("Failed to allocate memory for nvt flash data\n"); + return -ENOMEM; + } + + rwlock_init(&dev->lock); + file->private_data = dev; + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen /proc/NVTSPI close function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t nvt_flash_close(struct inode *inode, struct file *file) +{ + struct nvt_flash_data *dev = file->private_data; + + if (dev) + kfree(dev); + + return 0; +} + +static const struct file_operations nvt_flash_fops = { + .owner = THIS_MODULE, + .open = nvt_flash_open, + .release = nvt_flash_close, + .read = nvt_flash_read, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/NVTSPI initial function. + +return: + Executive outcomes. 0---succeed. -12---failed. +*******************************************************/ +static int32_t nvt_flash_proc_init(void) +{ + NVT_proc_entry = proc_create(DEVICE_NAME, 0444, NULL, &nvt_flash_fops); + if (NVT_proc_entry == NULL) { + NVT_ERR("Failed!\n"); + return -ENOMEM; + } else { + NVT_LOG("Succeeded!\n"); + } + + NVT_LOG("============================================================\n"); + NVT_LOG("Create /proc/%s\n", DEVICE_NAME); + NVT_LOG("============================================================\n"); + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen /proc/NVTSPI deinitial function. + +return: + n.a. +*******************************************************/ +static void nvt_flash_proc_deinit(void) +{ + if (NVT_proc_entry != NULL) { + remove_proc_entry(DEVICE_NAME, NULL); + NVT_proc_entry = NULL; + NVT_LOG("Removed /proc/%s\n", DEVICE_NAME); + } +} +#endif + +#if WAKEUP_GESTURE +#define GESTURE_WORD_C 12 +#define GESTURE_WORD_W 13 +#define GESTURE_WORD_V 14 +#define GESTURE_DOUBLE_CLICK 15 +#define GESTURE_WORD_Z 16 +#define GESTURE_WORD_M 17 +#define GESTURE_WORD_O 18 +#define GESTURE_WORD_e 19 +#define GESTURE_WORD_S 20 +#define GESTURE_SLIDE_UP 21 +#define GESTURE_SLIDE_DOWN 22 +#define GESTURE_SLIDE_LEFT 23 +#define GESTURE_SLIDE_RIGHT 24 +#define GESTURE_PEN_ONE_CLICK 25 +/* customized gesture id */ +#define DATA_PROTOCOL 30 + +/* function page definition */ +#define FUNCPAGE_GESTURE 1 + +/******************************************************* +Description: + Novatek touchscreen wake up gesture key report function. + +return: + n.a. +*******************************************************/ +void nvt_ts_wakeup_gesture_report(uint8_t gesture_id, uint8_t *data) +{ + uint32_t keycode = 0; + uint8_t func_type = data[2]; + uint8_t func_id = data[3]; + + /* support fw specifal data protocol */ + if ((gesture_id == DATA_PROTOCOL) && (func_type == FUNCPAGE_GESTURE)) { + gesture_id = func_id; + } else if (gesture_id > DATA_PROTOCOL) { + NVT_ERR("gesture_id %d is invalid, func_type=%d, func_id=%d\n", + gesture_id, func_type, func_id); + return; + } + + NVT_LOG("gesture_id = %d\n", gesture_id); + + switch (gesture_id) { + case GESTURE_WORD_C: + NVT_LOG("Gesture : Word-C.\n"); + keycode = gesture_key_array[0]; + break; + case GESTURE_WORD_W: + NVT_LOG("Gesture : Word-W.\n"); + keycode = gesture_key_array[1]; + break; + case GESTURE_WORD_V: + NVT_LOG("Gesture : Word-V.\n"); + keycode = gesture_key_array[2]; + break; + case GESTURE_DOUBLE_CLICK: + NVT_LOG("Gesture : Double Click.\n"); + if (ts->db_wakeup & 0x01) { + keycode = gesture_key_array[3]; + } else { + NVT_LOG("Gesture : Double Click Not Enable.\n"); + keycode = 0; + } + break; + case GESTURE_WORD_Z: + NVT_LOG("Gesture : Word-Z.\n"); + keycode = gesture_key_array[4]; + break; + case GESTURE_WORD_M: + NVT_LOG("Gesture : Word-M.\n"); + keycode = gesture_key_array[5]; + break; + case GESTURE_WORD_O: + NVT_LOG("Gesture : Word-O.\n"); + keycode = gesture_key_array[6]; + break; + case GESTURE_WORD_e: + NVT_LOG("Gesture : Word-e.\n"); + keycode = gesture_key_array[7]; + break; + case GESTURE_WORD_S: + NVT_LOG("Gesture : Word-S.\n"); + keycode = gesture_key_array[8]; + break; + case GESTURE_SLIDE_UP: + NVT_LOG("Gesture : Slide UP.\n"); + keycode = gesture_key_array[9]; + break; + case GESTURE_SLIDE_DOWN: + NVT_LOG("Gesture : Slide DOWN.\n"); + keycode = gesture_key_array[10]; + break; + case GESTURE_SLIDE_LEFT: + NVT_LOG("Gesture : Slide LEFT.\n"); + keycode = gesture_key_array[11]; + break; + case GESTURE_SLIDE_RIGHT: + NVT_LOG("Gesture : Slide RIGHT.\n"); + keycode = gesture_key_array[12]; + break; + case GESTURE_PEN_ONE_CLICK: + NVT_LOG("Gesture : Pen Click.\n"); + if (ts->db_wakeup & 0x02) { + keycode = gesture_key_array[13]; + } else { + NVT_LOG("Gesture : Pen Click Not Enable.\n"); + keycode = 0; + } + break; + default: + break; + } + + if (keycode > 0) { + input_report_key(ts->input_dev, keycode, 1); + input_sync(ts->input_dev); + input_report_key(ts->input_dev, keycode, 0); + input_sync(ts->input_dev); + } +} +#endif + +static void release_pen_event() +{ + if (ts && ts->pen_input_dev) { + input_report_abs(ts->pen_input_dev, ABS_X, 0); + input_report_abs(ts->pen_input_dev, ABS_Y, 0); + input_report_abs(ts->pen_input_dev, ABS_PRESSURE, 0); + input_report_abs(ts->pen_input_dev, ABS_TILT_X, 0); + input_report_abs(ts->pen_input_dev, ABS_TILT_Y, 0); + input_report_abs(ts->pen_input_dev, ABS_DISTANCE, 0); + input_report_key(ts->pen_input_dev, BTN_TOUCH, 0); + input_report_key(ts->pen_input_dev, BTN_TOOL_PEN, 0); + input_report_key(ts->pen_input_dev, BTN_STYLUS, 0); + input_report_key(ts->pen_input_dev, BTN_STYLUS2, 0); + input_sync(ts->pen_input_dev); + } +} + +/******************************************************* +Description: + Novatek touchscreen parse device tree function. + +return: + n.a. +*******************************************************/ +#ifdef CONFIG_OF +static int32_t nvt_parse_dt(struct device *dev) +{ + struct nvt_config_info *config_info; + struct device_node *temp, *np = dev->of_node; + int32_t ret = 0; + uint32_t temp_val; + +#if NVT_TOUCH_SUPPORT_HW_RST + ts->reset_gpio = of_get_named_gpio_flags(np, "novatek,reset-gpio", 0, + &ts->reset_flags); + NVT_LOG("novatek,reset-gpio=%d\n", ts->reset_gpio); +#endif + ts->irq_gpio = of_get_named_gpio_flags(np, "novatek,irq-gpio", 0, + &ts->irq_flags); + NVT_LOG("novatek,irq-gpio=%d\n", ts->irq_gpio); + + ts->pen_support = of_property_read_bool(np, "novatek,pen-support"); + NVT_LOG("novatek,pen-support=%d\n", ts->pen_support); + + ts->wgp_stylus = of_property_read_bool(np, "novatek,wgp-stylus"); + NVT_LOG("novatek,wgp-stylus=%d\n", ts->wgp_stylus); + + ret = of_property_read_u32(np, "novatek,swrst-n8-addr", &SWRST_N8_ADDR); + if (ret) { + NVT_ERR("error reading novatek,swrst-n8-addr. ret=%d\n", ret); + return ret; + } else { + NVT_LOG("SWRST_N8_ADDR=0x%06X\n", SWRST_N8_ADDR); + } + + ret = of_property_read_u32(np, "novatek,spi-rd-fast-addr", + &SPI_RD_FAST_ADDR); + if (ret) { + NVT_LOG("not support novatek,spi-rd-fast-addr\n"); + SPI_RD_FAST_ADDR = 0; + ret = 0; + } else { + NVT_LOG("SPI_RD_FAST_ADDR=0x%06X\n", SPI_RD_FAST_ADDR); + } + + ret = of_property_read_u32(np, "novatek,config-array-size", + &ts->config_array_size); + if (ret) { + NVT_LOG("Unable to get array size\n"); + return ret; + } else { + NVT_LOG("config-array-size: %u\n", ts->config_array_size); + } + + ret = of_property_read_u32(np, "spi-max-frequency", &ts->spi_max_freq); + if (ret) { + NVT_LOG("Unable to get spi freq\n"); + return ret; + } else { + NVT_LOG("spi-max-frequency: %u\n", ts->spi_max_freq); + } + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + ret = of_property_read_u32_array(np, "novatek,touch-game-param-config1", + ts->gamemode_config[0], 5); + if (ret) { + NVT_LOG("Failed to get touch-game-param-config1\n"); + SPI_RD_FAST_ADDR = 0; + ret = 0; + } else { + NVT_LOG("read touch gamemode parameter config1:[%d, %d, %d, %d, %d]", + ts->gamemode_config[0][0], ts->gamemode_config[0][1], + ts->gamemode_config[0][2], ts->gamemode_config[0][3], + ts->gamemode_config[0][4]); + } + + ret = of_property_read_u32_array(np, "novatek,touch-game-param-config2", + ts->gamemode_config[1], 5); + if (ret) { + NVT_LOG("Failed to get touch-game-param-config2\n"); + SPI_RD_FAST_ADDR = 0; + ret = 0; + } else { + NVT_LOG("read touch gamemode parameter config2:[%d, %d, %d, %d, %d]", + ts->gamemode_config[1][0], ts->gamemode_config[1][1], + ts->gamemode_config[1][2], ts->gamemode_config[1][3], + ts->gamemode_config[1][4]); + } + + ret = of_property_read_u32_array(np, "novatek,touch-game-param-config3", + ts->gamemode_config[2], 5); + if (ret) { + NVT_LOG("Failed to get touch-game-param-config3\n"); + SPI_RD_FAST_ADDR = 0; + ret = 0; + } else { + NVT_LOG("read touch gamemode parameter config3:[%d, %d, %d, %d, %d]", + ts->gamemode_config[2][0], ts->gamemode_config[2][1], + ts->gamemode_config[2][2], ts->gamemode_config[2][3], + ts->gamemode_config[2][4]); + } +#endif /* #if CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE */ + ts->config_array = devm_kzalloc( + dev, ts->config_array_size * sizeof(struct nvt_config_info), + GFP_KERNEL); + if (!ts->config_array) { + NVT_LOG("Unable to allocate memory\n"); + return -ENOMEM; + } + + config_info = ts->config_array; + for_each_child_of_node(np, temp) { + if (config_info - ts->config_array >= ts->config_array_size) { + NVT_ERR("parse %ld config down\n", + config_info - ts->config_array); + break; + } + + ret = of_property_read_u32(temp, "novatek,display-maker", + &temp_val); + if (ret) { + NVT_LOG("Unable to read tp hw version\n"); + } else { + config_info->display_maker = (u8)temp_val; + NVT_LOG("tp hw version: %u", + config_info->display_maker); + } + + ret = of_property_read_string(temp, "novatek,fw-name", + &config_info->nvt_fw_name); + if (ret && (ret != -EINVAL)) { + NVT_LOG("Unable to read fw name\n"); + } else { + NVT_LOG("fw_name: %s", config_info->nvt_fw_name); + } + + ret = of_property_read_string(temp, "novatek,mp-name", + &config_info->nvt_mp_name); + if (ret && (ret != -EINVAL)) { + NVT_LOG("Unable to read mp name\n"); + } else { + NVT_LOG("mp_name: %s", config_info->nvt_mp_name); + } + + config_info++; + } + + return ret; +} +#else +static int32_t nvt_parse_dt(struct device *dev) +{ +#if NVT_TOUCH_SUPPORT_HW_RST + ts->reset_gpio = NVTTOUCH_RST_PIN; +#endif + ts->irq_gpio = NVTTOUCH_INT_PIN; + return 0; +} +#endif + +static int nvt_get_panel_type(struct nvt_ts_data *ts_data) +{ + int i; + int j; + u8 *lockdown = ts_data->lockdown_info; + struct nvt_config_info *panel_list = ts->config_array; + + for (j = 0; j < 60; j++) { + if (lockdown[1] == 0x42) { + i = 0; + NVT_ERR("This is CSOT Display Panel!"); + break; + } + if (lockdown[1] == 0x36) { + i = 1; + NVT_ERR("This is TM Display Panel!"); + break; + } + + mdelay(1000); + } + if (i != 0 && i != 1) { + i = 1; + } + + ts->panel_index = i; + + if (i >= ts->config_array_size) { + NVT_ERR("mismatch panel type, use default fw"); + ts->panel_index = -EINVAL; + return ts->panel_index; + } + + NVT_LOG("match panle type, fw is [%s], mp is [%s]", + panel_list[i].nvt_fw_name, panel_list[i].nvt_mp_name); + + return ts->panel_index; +} + +bool is_lockdown_empty(u8 *lockdown) +{ + bool ret = true; + int i; + + for (i = 0; i < NVT_LOCKDOWN_SIZE; i++) { + if (lockdown[i] != 0) { + ret = false; + break; + } + } + return ret; +} + +void nvt_match_fw(void) +{ + NVT_LOG("start match fw name"); + if (is_lockdown_empty(ts->lockdown_info)) + flush_delayed_work(&ts->nvt_lockdown_work); + if (nvt_get_panel_type(ts) < 0) { + ts->fw_name = DEFAULT_BOOT_UPDATE_FIRMWARE_NAME; + ts->mp_name = DEFAULT_MP_UPDATE_FIRMWARE_NAME; + } else { + ts->fw_name = ts->config_array[ts->panel_index].nvt_fw_name; + ts->mp_name = ts->config_array[ts->panel_index].nvt_mp_name; + } +} + +/******************************************************* +Description: + Novatek touchscreen config and request gpio + +return: + Executive outcomes. 0---succeed. not 0---failed. +*******************************************************/ +static int nvt_gpio_config(struct nvt_ts_data *ts) +{ + int32_t ret = 0; + +#if NVT_TOUCH_SUPPORT_HW_RST + /* request RST-pin (Output/High) */ + if (gpio_is_valid(ts->reset_gpio)) { + ret = gpio_request_one(ts->reset_gpio, GPIOF_OUT_INIT_LOW, + "NVT-tp-rst"); + if (ret) { + NVT_ERR("Failed to request NVT-tp-rst GPIO\n"); + goto err_request_reset_gpio; + } + } +#endif + + /* request INT-pin (Input) */ + if (gpio_is_valid(ts->irq_gpio)) { + ret = gpio_request_one(ts->irq_gpio, GPIOF_IN, "NVT-int"); + if (ret) { + NVT_ERR("Failed to request NVT-int GPIO\n"); + goto err_request_irq_gpio; + } + } + + return ret; + +err_request_irq_gpio: +#if NVT_TOUCH_SUPPORT_HW_RST + gpio_free(ts->reset_gpio); +err_request_reset_gpio: +#endif + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen deconfig gpio + +return: + n.a. +*******************************************************/ +static void nvt_gpio_deconfig(struct nvt_ts_data *ts) +{ + if (gpio_is_valid(ts->irq_gpio)) + gpio_free(ts->irq_gpio); +#if NVT_TOUCH_SUPPORT_HW_RST + if (gpio_is_valid(ts->reset_gpio)) + gpio_free(ts->reset_gpio); +#endif +} + +static uint8_t nvt_fw_recovery(uint8_t *point_data) +{ + uint8_t i = 0; + uint8_t detected = true; + + /* check pattern */ + for (i = 1; i < 7; i++) { + if (point_data[i] != 0x77) { + detected = false; + break; + } + } + + return detected; +} + +void nvt_set_dbgfw_status(bool enable) +{ + ts->fw_debug = enable; +} + +bool nvt_get_dbgfw_status(void) +{ + return ts->fw_debug; +} + +#if NVT_TOUCH_ESD_PROTECT +void nvt_esd_check_enable(uint8_t enable) +{ + /* update interrupt timer */ + irq_timer = jiffies; + /* clear esd_retry counter, if protect function is enabled */ + esd_retry = enable ? 0 : esd_retry; + /* enable/disable esd check flag */ + esd_check = enable; +} + +static void nvt_esd_check_func(struct work_struct *work) +{ + unsigned int timer = jiffies_to_msecs(jiffies - irq_timer); + + //NVT_LOG("esd_check = %d (retry %d)\n", esd_check, esd_retry); //DEBUG + + if ((timer > NVT_TOUCH_ESD_CHECK_PERIOD) && esd_check) { + mutex_lock(&ts->lock); + NVT_ERR("do ESD recovery, timer = %d, retry = %d\n", timer, + esd_retry); + /* do esd recovery, reload fw */ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_FW_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + mutex_unlock(&ts->lock); + /* update interrupt timer */ + irq_timer = jiffies; + /* update esd_retry counter */ + esd_retry++; + } + + queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work, + msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD)); +} +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + +#if NVT_TOUCH_WDT_RECOVERY +static uint8_t recovery_cnt = 0; +static uint8_t nvt_wdt_fw_recovery(uint8_t *point_data) +{ + uint32_t recovery_cnt_max = 10; + uint8_t recovery_enable = false; + uint8_t i = 0; + + recovery_cnt++; + + /* check pattern */ + for (i = 1; i < 7; i++) { + if ((point_data[i] != 0xFD) && (point_data[i] != 0xFE)) { + recovery_cnt = 0; + break; + } + } + + if (recovery_cnt > recovery_cnt_max) { + recovery_enable = true; + recovery_cnt = 0; + } + + return recovery_enable; +} +#endif /* #if NVT_TOUCH_WDT_RECOVERY */ + +#define PEN_DATA_LEN 14 +#if CHECK_PEN_DATA_CHECKSUM +static int32_t nvt_ts_pen_data_checksum(uint8_t *buf, uint8_t length) +{ + uint8_t checksum = 0; + int32_t i = 0; + + // Calculate checksum + for (i = 0; i < length - 1; i++) { + checksum += buf[i]; + } + checksum = (~checksum + 1); + + // Compare ckecksum and dump fail data + if (checksum != buf[length - 1]) { + NVT_ERR("pen packet checksum not match. (buf[%d]=0x%02X, checksum=0x%02X)\n", + length - 1, buf[length - 1], checksum); + //--- dump pen buf --- + for (i = 0; i < length; i++) { + printk("%02X ", buf[i]); + } + printk("\n"); + + return -1; + } + + return 0; +} +#endif // #if CHECK_PEN_DATA_CHECKSUM + +#define FW_HISTORY_SIZE 128 +static uint32_t nvt_dump_fw_history(void) +{ + int32_t ret = 0; + uint8_t buf[FW_HISTORY_SIZE + 1 + DUMMY_BYTES] = { 0 }; + int32_t i = 0; + char *tmp_dump = NULL; + int32_t line_cnt = 0; + + if (ts->mmap->FW_HISTORY_ADDR == 0) { + NVT_ERR("FW_HISTORY_ADDR not available!\n"); + ret = -1; + goto exit_nvt_dump_fw_history; + } + nvt_set_page(ts->mmap->FW_HISTORY_ADDR); + buf[0] = ts->mmap->FW_HISTORY_ADDR & 0xFF; + CTP_SPI_READ(ts->client, buf, FW_HISTORY_SIZE + 1); + if (ret) { + NVT_ERR("CTP_SPI_READ failed.(%d)\n", ret); + ret = -1; + goto exit_nvt_dump_fw_history; + } + + tmp_dump = (char *)kzalloc(FW_HISTORY_SIZE * 4, GFP_KERNEL); + for (i = 0; i < FW_HISTORY_SIZE; i++) { + sprintf(tmp_dump + i * 3 + line_cnt, "%02X ", buf[1 + i]); + if ((i + 1) % 16 == 0) { + sprintf(tmp_dump + i * 3 + line_cnt + 3, "%c", '\n'); + line_cnt++; + } + } + NVT_LOG("%s", tmp_dump); + +exit_nvt_dump_fw_history: + if (tmp_dump) { + kfree(tmp_dump); + tmp_dump = NULL; + } + nvt_set_page(ts->mmap->EVENT_BUF_ADDR); + + return ret; +} + +#if POINT_DATA_CHECKSUM +static int32_t nvt_ts_point_data_checksum(uint8_t *buf, uint8_t length) +{ + uint8_t checksum = 0; + int32_t i = 0; + + // Generate checksum + for (i = 0; i < length - 1; i++) { + checksum += buf[i + 1]; + } + checksum = (~checksum + 1); + + // Compare ckecksum and dump fail data + if (checksum != buf[length]) { + NVT_ERR("i2c/spi packet checksum not match. (point_data[%d]=0x%02X, checksum=0x%02X)\n", + length, buf[length], checksum); + + for (i = 0; i < 10; i++) { + NVT_LOG("%02X %02X %02X %02X %02X %02X\n", + buf[1 + i * 6], buf[2 + i * 6], buf[3 + i * 6], + buf[4 + i * 6], buf[5 + i * 6], buf[6 + i * 6]); + } + + NVT_LOG("%02X %02X %02X %02X %02X\n", buf[61], buf[62], buf[63], + buf[64], buf[65]); + + return -1; + } + + return 0; +} +#endif /* POINT_DATA_CHECKSUM */ + +#define POINT_DATA_LEN 65 +/******************************************************* +Description: + Novatek touchscreen work function. + +return: + n.a. +*******************************************************/ +static irqreturn_t nvt_ts_work_func(int irq, void *data) +{ + int32_t ret = -1; + uint8_t point_data[POINT_DATA_LEN + PEN_DATA_LEN + 1 + DUMMY_BYTES] = { + 0 + }; + uint32_t position = 0; + uint32_t input_x = 0; + uint32_t input_y = 0; + uint32_t input_w = 0; + uint32_t input_p = 0; + uint8_t input_id = 0; +#if MT_PROTOCOL_B + uint8_t press_id[TOUCH_MAX_FINGER_NUM] = { 0 }; +#endif /* MT_PROTOCOL_B */ + int32_t i = 0; + int32_t finger_cnt = 0; + uint8_t pen_format_id = 0; + uint32_t pen_x = 0; + uint32_t pen_y = 0; + uint32_t pen_pressure = 0; + uint32_t pen_distance = 0; + int8_t pen_tilt_x = 0; + int8_t pen_tilt_y = 0; + uint32_t pen_btn1 = 0; + uint32_t pen_btn2 = 0; + uint32_t pen_battery = 0; + +#if WAKEUP_GESTURE + if (bTouchIsAwake == 0) { + pm_wakeup_event(&ts->input_dev->dev, 5000); + } +#endif + + touch_irq_boost(); + lpm_disable_for_input(true); + + mutex_lock(&ts->lock); + + if (ts->dev_pm_suspend) { + ret = wait_for_completion_timeout( + &ts->dev_pm_suspend_completion, msecs_to_jiffies(500)); + if (!ret) { + NVT_ERR("system(spi) can't finished resuming procedure, skip it\n"); + lpm_disable_for_input(false); + goto XFER_ERROR; + } + } + + if (ts->pen_support) + ret = CTP_SPI_READ(ts->client, point_data, + POINT_DATA_LEN + PEN_DATA_LEN + 1); + else + ret = CTP_SPI_READ(ts->client, point_data, POINT_DATA_LEN + 1); + if (ret < 0) { + NVT_ERR("CTP_SPI_READ failed.(%d)\n", ret); + goto XFER_ERROR; + } + + /*--- dump SPI buf --- + for (i = 0; i < 10; i++) { + NVT_LOG("%02X %02X %02X %02X %02X %02X \n", + point_data[1+i*6], point_data[2+i*6], point_data[3+i*6], point_data[4+i*6], point_data[5+i*6], point_data[6+i*6]); + } + */ + +#if NVT_TOUCH_WDT_RECOVERY + /* ESD protect by WDT */ + if (nvt_wdt_fw_recovery(point_data)) { + NVT_ERR("Recover for fw reset, %02X\n", point_data[1]); + if (point_data[1] == 0xFD) { + NVT_ERR("Dump FW history:\n"); + nvt_dump_fw_history(); + } + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_FW_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + goto XFER_ERROR; + } +#endif /* #if NVT_TOUCH_WDT_RECOVERY */ + + /* ESD protect by FW handshake */ + if (nvt_fw_recovery(point_data)) { +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(true); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + goto XFER_ERROR; + } + +#if POINT_DATA_CHECKSUM + if (POINT_DATA_LEN >= POINT_DATA_CHECKSUM_LEN) { + ret = nvt_ts_point_data_checksum(point_data, + POINT_DATA_CHECKSUM_LEN); + if (ret) { + goto XFER_ERROR; + } + } +#endif /* POINT_DATA_CHECKSUM */ + +#if WAKEUP_GESTURE + if (bTouchIsAwake == 0) { + NVT_LOG("Enter WAKEUP_GESTURE\n"); + input_id = (uint8_t)(point_data[1] >> 3); + nvt_ts_wakeup_gesture_report(input_id, point_data); + mutex_unlock(&ts->lock); + lpm_disable_for_input(false); + return IRQ_HANDLED; + } +#endif + + finger_cnt = 0; + + for (i = 0; i < ts->max_touch_num; i++) { + position = 1 + 6 * i; + input_id = (uint8_t)(point_data[position + 0] >> 3); + if ((input_id == 0) || (input_id > ts->max_touch_num)) + continue; + + if (((point_data[position] & 0x07) == 0x01) || + ((point_data[position] & 0x07) == + 0x02)) { //finger down (enter & moving) +#if NVT_TOUCH_ESD_PROTECT + /* update interrupt timer */ + irq_timer = jiffies; +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + input_x = (uint32_t)(point_data[position + 1] << 4) + + (uint32_t)(point_data[position + 3] >> 4); + input_y = (uint32_t)(point_data[position + 2] << 4) + + (uint32_t)(point_data[position + 3] & 0x0F); + if ((input_x < 0) || (input_y < 0)) + continue; + if ((input_x > ts->abs_x_max) || + (input_y > ts->abs_y_max)) + continue; + input_w = (uint32_t)(point_data[position + 4]); + if (input_w == 0) + input_w = 1; + if (i < 2) { + input_p = (uint32_t)(point_data[position + 5]) + + (uint32_t)(point_data[i + 63] << 8); + if (input_p > TOUCH_FORCE_NUM) + input_p = TOUCH_FORCE_NUM; + } else { + input_p = (uint32_t)(point_data[position + 5]); + } + if (input_p == 0) + input_p = 1; + +#if MT_PROTOCOL_B + press_id[input_id - 1] = 1; + input_mt_slot(ts->input_dev, input_id - 1); + input_mt_report_slot_state(ts->input_dev, + MT_TOOL_FINGER, true); +#else /* MT_PROTOCOL_B */ + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, + input_id - 1); + input_report_key(ts->input_dev, BTN_TOUCH, 1); +#endif /* MT_PROTOCOL_B */ + + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, + input_x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, + input_y); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, + input_w); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, + input_p); + +#if MT_PROTOCOL_B +#else /* MT_PROTOCOL_B */ + input_mt_sync(ts->input_dev); +#endif /* MT_PROTOCOL_B */ + + finger_cnt++; + } + } + +#if MT_PROTOCOL_B + for (i = 0; i < ts->max_touch_num; i++) { + if (press_id[i] != 1) { + input_mt_slot(ts->input_dev, i); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0); + input_mt_report_slot_state(ts->input_dev, + MT_TOOL_FINGER, false); + } + } + input_report_key(ts->input_dev, BTN_TOUCH, (finger_cnt > 0)); +#else /* MT_PROTOCOL_B */ + if (finger_cnt == 0) { + input_report_key(ts->input_dev, BTN_TOUCH, 0); + input_mt_sync(ts->input_dev); + } +#endif /* MT_PROTOCOL_B */ + +#if TOUCH_KEY_NUM > 0 + if (point_data[61] == 0xF8) { +#if NVT_TOUCH_ESD_PROTECT + /* update interrupt timer */ + irq_timer = jiffies; +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + for (i = 0; i < ts->max_button_num; i++) { + input_report_key(ts->input_dev, touch_key_array[i], + ((point_data[62] >> i) & 0x01)); + } + } else { + for (i = 0; i < ts->max_button_num; i++) { + input_report_key(ts->input_dev, touch_key_array[i], 0); + } + } +#endif + + input_sync(ts->input_dev); + + if (ts->pen_support && ts->pen_input_dev_enable && + !(ts->pen_is_charge)) { +/* + //--- dump pen buf --- + printk("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + point_data[66], point_data[67], point_data[68], point_data[69], point_data[70], + point_data[71], point_data[72], point_data[73], point_data[74], point_data[75], + point_data[76], point_data[77], point_data[78], point_data[79]); +*/ +#if CHECK_PEN_DATA_CHECKSUM + if (nvt_ts_pen_data_checksum(&point_data[66], PEN_DATA_LEN)) { + // pen data packet checksum not match, skip it + goto XFER_ERROR; + } +#endif // #if CHECK_PEN_DATA_CHECKSUM + + // parse and handle pen report + pen_format_id = point_data[66]; + if (pen_format_id != 0xFF) { + if (pen_format_id == 0x01) { + // report pen data + pen_x = (uint32_t)(point_data[67] << 8) + + (uint32_t)(point_data[68]); + pen_y = (uint32_t)(point_data[69] << 8) + + (uint32_t)(point_data[70]); + if (pen_x >= ts->abs_x_max * 2 - 1) { + pen_x -= 1; + } + if (pen_y >= ts->abs_y_max * 2 - 1) { + pen_y -= 1; + } + pen_pressure = (uint32_t)(point_data[71] << 8) + + (uint32_t)(point_data[72]); + pen_tilt_x = (int32_t)point_data[73]; + pen_tilt_y = (int32_t)point_data[74]; + pen_distance = (uint32_t)(point_data[75] << 8) + + (uint32_t)(point_data[76]); + pen_btn1 = (uint32_t)(point_data[77] & 0x01); + pen_btn2 = (uint32_t)((point_data[77] >> 1) & + 0x01); + pen_battery = (uint32_t)point_data[78]; + // printk("x=%d,y=%d,p=%d,tx=%d,ty=%d,d=%d,b1=%d,b2=%d,bat=%d\n", pen_x, pen_y, pen_pressure, + // pen_tilt_x, pen_tilt_y, pen_distance, pen_btn1, pen_btn2, pen_battery); + + input_report_abs(ts->pen_input_dev, ABS_X, + pen_x); + input_report_abs(ts->pen_input_dev, ABS_Y, + pen_y); + input_report_abs(ts->pen_input_dev, + ABS_PRESSURE, pen_pressure); + input_report_key(ts->pen_input_dev, BTN_TOUCH, + !!pen_pressure); + input_report_abs(ts->pen_input_dev, ABS_TILT_X, + pen_tilt_x); + input_report_abs(ts->pen_input_dev, ABS_TILT_Y, + pen_tilt_y); + input_report_abs(ts->pen_input_dev, + ABS_DISTANCE, pen_distance); + input_report_key( + ts->pen_input_dev, BTN_TOOL_PEN, + !!pen_distance || !!pen_pressure); + input_report_key(ts->pen_input_dev, BTN_STYLUS, + pen_btn1); + input_report_key(ts->pen_input_dev, BTN_STYLUS2, + pen_btn2); + input_sync(ts->pen_input_dev); + // TBD: pen battery event report + // NVT_LOG("pen_battery=%d\n", pen_battery); + } else if (pen_format_id == 0xF0) { + // report Pen ID + } else { + NVT_ERR("Unknown pen format id!\n"); + goto XFER_ERROR; + } + } else { // pen_format_id = 0xFF, i.e. no pen present + release_pen_event(); + } + } /* if (ts->pen_support) */ + +XFER_ERROR: + + mutex_unlock(&ts->lock); + lpm_disable_for_input(false); + return IRQ_HANDLED; +} + +/******************************************************* +Description: + Novatek touchscreen check chip version trim function. + +return: + Executive outcomes. 0---NVT IC. -1---not NVT IC. +*******************************************************/ +static int8_t nvt_ts_check_chip_ver_trim(uint32_t chip_ver_trim_addr) +{ + uint8_t buf[8] = { 0 }; + int32_t retry = 0; + int32_t list = 0; + int32_t i = 0; + int32_t found_nvt_chip = 0; + int32_t ret = -1; + + //---Check for 5 times--- + for (retry = 5; retry > 0; retry--) { + nvt_bootloader_reset(); + + nvt_set_page(chip_ver_trim_addr); + + buf[0] = chip_ver_trim_addr & 0x7F; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x00; + CTP_SPI_READ(ts->client, buf, 7); + NVT_LOG("buf[1]=0x%02X, buf[2]=0x%02X, buf[3]=0x%02X, buf[4]=0x%02X, buf[5]=0x%02X, buf[6]=0x%02X\n", + buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); + + // compare read chip id on supported list + for (list = 0; list < (sizeof(trim_id_table) / + sizeof(struct nvt_ts_trim_id_table)); + list++) { + found_nvt_chip = 0; + + // compare each byte + for (i = 0; i < NVT_ID_BYTE_MAX; i++) { + if (trim_id_table[list].mask[i]) { + if (buf[i + 1] != + trim_id_table[list].id[i]) + break; + } + } + + if (i == NVT_ID_BYTE_MAX) { + found_nvt_chip = 1; + } + + if (found_nvt_chip) { + NVT_LOG("This is NVT touch IC\n"); + ts->mmap = trim_id_table[list].mmap; + ts->carrier_system = + trim_id_table[list] + .hwinfo->carrier_system; + ts->hw_crc = trim_id_table[list].hwinfo->hw_crc; + ret = 0; + goto out; + } else { + ts->mmap = NULL; + ret = -1; + } + } + + msleep(10); + } + +out: + return ret; +} + +static void nvt_switch_mode_work(struct work_struct *work) +{ + NVT_LOG("%s double click wakeup", ts->db_wakeup ? "ENABLE" : "DISABLE"); + if (ts->ic_state <= NVT_IC_SUSPEND_OUT && ts->ic_state != NVT_IC_INIT) { + ts->gesture_command_delayed = ts->db_wakeup; + NVT_ERR("Panel off, don't set dbclick gesture flag util panel on"); + ts->db_wakeup = 0; + } else if (ts->ic_state >= NVT_IC_RESUME_IN) { + dsi_panel_doubleclick_enable(!!ts->db_wakeup); + } +} + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE +static struct xiaomi_touch_interface xiaomi_touch_interfaces; + +int32_t nvt_check_palm(uint8_t input_id, uint8_t *data) +{ + int32_t ret = 0; + uint8_t func_type = data[2]; + uint8_t palm_state = data[3]; + + if ((input_id == DATA_PROTOCOL) && (func_type == FUNCPAGE_PALM)) { + ret = palm_state; + if (palm_state == PACKET_PALM_ON) { + NVT_LOG("get packet palm on event.\n"); + update_palm_sensor_value(1); + } else if (palm_state == PACKET_PALM_OFF) { + NVT_LOG("get packet palm off event.\n"); + update_palm_sensor_value(0); + } else { + NVT_ERR("invalid palm state %d!\n", palm_state); + ret = -1; + } + } else { + ret = 0; + } + + return ret; +} + +static int nvt_palm_sensor_write(int value) +{ + int ret = 0; + NVT_LOG("enter %d %d\n", value, ts->palm_sensor_switch); + ts->palm_sensor_switch = value; + + if (ts->dev_pm_suspend) { + NVT_LOG("tp has dev_pm_suspend status\n"); + return 0; + } + + if (bTouchIsAwake) + ret = nvt_set_pocket_palm_switch(value); + return ret; +} + +static void nvt_init_touchmode_data(void) +{ + int i; + + NVT_LOG("%s,ENTER\n", __func__); + /* Touch Game Mode Switch */ + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_MAX_VALUE] = 1; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_DEF_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][SET_CUR_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_CUR_VALUE] = 0; + + /* Acitve Mode */ + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_MAX_VALUE] = + 1; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_MIN_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_DEF_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][SET_CUR_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_CUR_VALUE] = + 0; + + /* Tap Sensivity */ + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_MAX_VALUE] = + 4; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_MIN_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_DEF_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][SET_CUR_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_CUR_VALUE] = + 0; + + /* Touch Tolerance */ + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_MAX_VALUE] = 4; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_DEF_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][SET_CUR_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_CUR_VALUE] = 0; + + /* Touch Aim Sensitivity */ + xiaomi_touch_interfaces + .touch_mode[Touch_Aim_Sensitivity][GET_MAX_VALUE] = 4; + xiaomi_touch_interfaces + .touch_mode[Touch_Aim_Sensitivity][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Aim_Sensitivity][GET_DEF_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Aim_Sensitivity][SET_CUR_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Aim_Sensitivity][GET_CUR_VALUE] = 0; + + /* [Touch Tap Stability */ + xiaomi_touch_interfaces.touch_mode[Touch_Tap_Stability][GET_MAX_VALUE] = + 4; + xiaomi_touch_interfaces.touch_mode[Touch_Tap_Stability][GET_MIN_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Tap_Stability][GET_DEF_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Tap_Stability][SET_CUR_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Tap_Stability][GET_CUR_VALUE] = + 0; + + xiaomi_touch_interfaces.touch_mode[Touch_Expert_Mode][GET_MAX_VALUE] = + 3; + xiaomi_touch_interfaces.touch_mode[Touch_Expert_Mode][GET_MIN_VALUE] = + 1; + xiaomi_touch_interfaces.touch_mode[Touch_Expert_Mode][GET_DEF_VALUE] = + 1; + xiaomi_touch_interfaces.touch_mode[Touch_Expert_Mode][SET_CUR_VALUE] = + 1; + xiaomi_touch_interfaces.touch_mode[Touch_Expert_Mode][GET_CUR_VALUE] = + 1; + + /* Panel orientation*/ + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_MAX_VALUE] = 3; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_DEF_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][SET_CUR_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_CUR_VALUE] = 0; + + /* Edge filter area*/ + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_MAX_VALUE] = + 3; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_MIN_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_DEF_VALUE] = + 2; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][SET_CUR_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_CUR_VALUE] = + 0; + + /* Resist RF interference*/ + xiaomi_touch_interfaces.touch_mode[Touch_Resist_RF][GET_MAX_VALUE] = 1; + xiaomi_touch_interfaces.touch_mode[Touch_Resist_RF][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Resist_RF][GET_DEF_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Resist_RF][SET_CUR_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Resist_RF][GET_CUR_VALUE] = 0; + + for (i = 0; i < Touch_Mode_NUM; i++) { + NVT_LOG("mode:%d, set cur:%d, get cur:%d, def:%d min:%d max:%d\n", + i, xiaomi_touch_interfaces.touch_mode[i][SET_CUR_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_CUR_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_DEF_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_MIN_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_MAX_VALUE]); + } + + return; +} + +static int nvt_touchfeature_cmd_xsfer(uint8_t *touchfeature) +{ + int ret; + uint8_t buf[8] = { 0 }; + + NVT_LOG("++\n"); + NVT_LOG("cmd xsfer:%02x, %02x", touchfeature[0], touchfeature[1]); + /* ---set xdata index to EVENT BUF ADDR--- */ + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_touchfeature_cmd_xsfer_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = touchfeature[0]; + buf[2] = touchfeature[1]; + + ret = CTP_SPI_WRITE(ts->client, buf, 3); + if (ret < 0) { + NVT_ERR("Write sensitivity switch command fail!\n"); + goto nvt_touchfeature_cmd_xsfer_out; + } + +nvt_touchfeature_cmd_xsfer_out: + NVT_LOG("--\n"); + return ret; +} + +static int nvt_touchfeature_set(uint8_t *touchfeature) +{ + int ret; + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + ret = nvt_touchfeature_cmd_xsfer(touchfeature); + if (ret < 0) + NVT_ERR("send cmd via SPI failed, errno:%d", ret); + + mutex_unlock(&ts->lock); + msleep(35); + return ret; +} + +#define PANEL_ORIENTATION_DEGREE_0 0 /* normal portrait orientation */ +#define PANEL_ORIENTATION_DEGREE_90 1 /* anticlockwise 90 degrees */ +#define PANEL_ORIENTATION_DEGREE_180 2 /* anticlockwise 180 degrees */ +#define PANEL_ORIENTATION_DEGREE_270 3 /* anticlockwise 270 degrees */ + +static void update_touchfeature_value_work(struct work_struct *work) +{ + uint8_t ret = 0; + uint8_t i = 0; + uint8_t nvt_game_value[2] = { 0 }; + int size = 6; + enum MODE_TYPE mode_type[6] = { + Touch_Game_Mode, Touch_UP_THRESHOLD, Touch_Tolerance, + Touch_Tap_Stability, Touch_Aim_Sensitivity, Touch_Edge_Filter + }; + uint8_t touchfeature_addr[6] = { 0x7A, 0x71, 0x78, 0x70, 0x79, 0x72 }; + uint8_t temp_set_value; + uint8_t temp_get_value; + + NVT_LOG("enter"); + for (i = 0; i < size; i++) { + temp_get_value = + xiaomi_touch_interfaces + .touch_mode[mode_type[i]][GET_CUR_VALUE]; + temp_set_value = + xiaomi_touch_interfaces + .touch_mode[mode_type[i]][SET_CUR_VALUE]; + if (temp_get_value == temp_set_value) + continue; + nvt_game_value[0] = touchfeature_addr[i]; + nvt_game_value[1] = temp_set_value; + ret = nvt_touchfeature_set(nvt_game_value); + msleep(40); + if (ret < 0) { + NVT_ERR("change game mode fail, mode is %d", + mode_type[i]); + return; + } + xiaomi_touch_interfaces.touch_mode[mode_type[i]][GET_CUR_VALUE] = + temp_set_value; + NVT_LOG("set mode:%d = %d", mode_type[i], temp_set_value); + } + /* orientation set */ + temp_get_value = + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_CUR_VALUE]; + temp_set_value = + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][SET_CUR_VALUE]; + if (temp_get_value != temp_set_value) { + if (temp_set_value == PANEL_ORIENTATION_DEGREE_0 || + temp_set_value == PANEL_ORIENTATION_DEGREE_180) { + nvt_game_value[0] = 0xBA; + } else if (temp_set_value == PANEL_ORIENTATION_DEGREE_90) { + nvt_game_value[0] = 0xBC; + } else if (temp_set_value == PANEL_ORIENTATION_DEGREE_270) { + nvt_game_value[0] = 0xBB; + } + nvt_game_value[1] = 0; + ret = nvt_touchfeature_set(nvt_game_value); + if (ret < 0) { + NVT_ERR("change panel orientation mode fail"); + return; + } + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_CUR_VALUE] = + temp_set_value; + NVT_LOG("set mode:%d = %d", Touch_Panel_Orientation, + temp_set_value); + } + + /* RF set */ + temp_get_value = xiaomi_touch_interfaces + .touch_mode[Touch_Resist_RF][GET_CUR_VALUE]; + temp_set_value = xiaomi_touch_interfaces + .touch_mode[Touch_Resist_RF][SET_CUR_VALUE]; + if (temp_get_value != temp_set_value) { + if (temp_set_value == 0) { + nvt_game_value[0] = 0x76; + } else if (temp_set_value == 1) { + nvt_game_value[0] = 0x75; + } + nvt_game_value[1] = 0; + ret = nvt_touchfeature_set(nvt_game_value); + if (ret < 0) { + NVT_ERR("change panel RF mode fail"); + return; + } + xiaomi_touch_interfaces + .touch_mode[Touch_Resist_RF][GET_CUR_VALUE] = + temp_set_value; + NVT_LOG("set mode:%d = %d", Touch_Resist_RF, temp_set_value); + } + NVT_LOG("exit"); +} + +static int disable_pen_input_device(bool disable) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + if (!bTouchIsAwake || !ts) { + NVT_LOG("touch suspend, stop set pen state %s", + disable ? "DISABLE" : "ENABLE"); + goto nvt_set_pen_enable_out; + } + + msleep(35); + disable = (!(ts->pen_input_dev_enable) || ts->pen_is_charge) ? true : + disable; + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_set_pen_enable_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x7B; + buf[2] = !!disable; + ret = CTP_SPI_WRITE(ts->client, buf, 3); + if (ret < 0) { + NVT_ERR("set pen %s failed!\n", disable ? "DISABLE" : "ENABLE"); + goto nvt_set_pen_enable_out; + } + NVT_LOG("pen charge state is %s, %s pen input device\n", + ts->pen_is_charge ? "ENABLE" : "DISABLE", + disable ? "DISABLE" : "ENABLE"); + +nvt_set_pen_enable_out: + NVT_LOG("--\n"); + return ret; +} + +static int nvt_pen_charge_state_notifier_callback(struct notifier_block *self, + unsigned long event, + void *data) +{ + ts->pen_is_charge = !!event; + release_pen_event(); + schedule_work(&ts->pen_charge_state_change_work); + return 0; +} + +static void nvt_pen_charge_state_change_work(struct work_struct *work) +{ + NVT_LOG("pen charge is %s", ts->pen_is_charge ? "ENABLE" : "DISABLE"); + disable_pen_input_device(ts->pen_is_charge); +} + +static int nvt_set_cur_value(int nvt_mode, int nvt_value) +{ + if (nvt_mode >= Touch_Mode_NUM && nvt_mode < 0) { + NVT_ERR("%s, nvt mode is error:%d", __func__, nvt_mode); + return -EINVAL; + } + + NVT_LOG("mode:%d, value:%d", nvt_mode, nvt_value); + if (nvt_mode == Touch_Doubletap_Mode && ts && nvt_value >= 0) { + ts->db_wakeup = nvt_value ? (ts->db_wakeup | 0x01) : + (ts->db_wakeup & 0xFE); + ts->db_wakeup = nvt_value ? (ts->db_wakeup | 0x02) : + (ts->db_wakeup & + 0xFD); /* enable pen wake up */ + schedule_work(&ts->switch_mode_work); + return 0; + } else if (nvt_mode == Touch_Pen_ENABLE && ts && nvt_value >= 0) { + ts->pen_input_dev_enable = !!nvt_value; + NVT_LOG("%s pen input dev", + ts->pen_input_dev_enable ? "ENABLE" : "DISABLE"); + disable_pen_input_device(!ts->pen_input_dev_enable); + release_pen_event(); + return 0; + } + + if (nvt_value > + xiaomi_touch_interfaces.touch_mode[nvt_mode][GET_MAX_VALUE]) { + nvt_value = xiaomi_touch_interfaces + .touch_mode[nvt_mode][GET_MAX_VALUE]; + } else if (nvt_value < + xiaomi_touch_interfaces.touch_mode[nvt_mode][GET_MIN_VALUE]) { + nvt_value = xiaomi_touch_interfaces + .touch_mode[nvt_mode][GET_MIN_VALUE]; + } + xiaomi_touch_interfaces.touch_mode[nvt_mode][SET_CUR_VALUE] = nvt_value; + + if (nvt_mode == Touch_Expert_Mode) { + NVT_LOG("This is Expert Mode, mode is %d", nvt_value); + xiaomi_touch_interfaces + .touch_mode[Touch_UP_THRESHOLD][SET_CUR_VALUE] = + ts->gamemode_config[nvt_value - 1][0]; + xiaomi_touch_interfaces + .touch_mode[Touch_Tolerance][SET_CUR_VALUE] = + ts->gamemode_config[nvt_value - 1][1]; + xiaomi_touch_interfaces + .touch_mode[Touch_Aim_Sensitivity][SET_CUR_VALUE] = + ts->gamemode_config[nvt_value - 1][2]; + xiaomi_touch_interfaces + .touch_mode[Touch_Tap_Stability][SET_CUR_VALUE] = + ts->gamemode_config[nvt_value - 1][3]; + xiaomi_touch_interfaces + .touch_mode[Touch_Edge_Filter][SET_CUR_VALUE] = + ts->gamemode_config[nvt_value - 1][4]; + } + + if (bTouchIsAwake) { + queue_work(ts->set_touchfeature_wq, &ts->set_touchfeature_work); + } + + return 0; +} + +static char nvt_touch_vendor_read(void) +{ + char value = '4'; + NVT_LOG("%s Get touch vendor: %c\n", __func__, value); + return value; +} + +static u8 nvt_panel_vendor_read(void) +{ + char value = '0'; + int ret = 0; + if (!ts) + return value; + ret = dsi_panel_lockdown_info_read(ts->lockdown_info); + if (ret <= 0) { + NVT_ERR("can't get lockdown info"); + return value; + } + if (!ts->lockdown_info[6]) { + NVT_ERR("%s lockdown info is NULL\n", __func__); + return value; + } else { + value = ts->lockdown_info[1]; + NVT_LOG("%s Get touch vendor: %d\n", __func__, value); + } + return value; +} + +static u8 nvt_panel_color_read(void) +{ + char value = '2'; + + return value; +} + +static u8 nvt_panel_display_read(void) +{ + char value = '0'; + int ret = 0; + if (!ts) + return value; + ret = dsi_panel_lockdown_info_read(ts->lockdown_info); + if (ret <= 0) { + NVT_ERR("can't get lockdown info"); + return value; + } + if (!ts->lockdown_info[1]) { + NVT_ERR("%s lockdown info is NULL\n", __func__); + return value; + } else { + value = ts->lockdown_info[1]; + NVT_LOG("%s Get touch vendor: %d\n", __func__, value); + } + return value; +} + +static int nvt_get_mode_value(int mode, int value_type) +{ + int value = -1; + + if (mode < Touch_Mode_NUM && mode >= 0) + value = xiaomi_touch_interfaces.touch_mode[mode][value_type]; + else + NVT_ERR("%s, don't support\n", __func__); + + return value; +} + +static int nvt_get_mode_all(int mode, int *value) +{ + if (mode < Touch_Mode_NUM && mode >= 0) { + value[0] = + xiaomi_touch_interfaces.touch_mode[mode][GET_CUR_VALUE]; + value[1] = + xiaomi_touch_interfaces.touch_mode[mode][GET_DEF_VALUE]; + value[2] = + xiaomi_touch_interfaces.touch_mode[mode][GET_MIN_VALUE]; + value[3] = + xiaomi_touch_interfaces.touch_mode[mode][GET_MAX_VALUE]; + } else { + NVT_ERR("%s, don't support\n", __func__); + } + NVT_LOG("%s, mode:%d, value:%d:%d:%d:%d\n", __func__, mode, value[0], + value[1], value[2], value[3]); + + return 0; +} + +static void nvt_game_mode_recovery(void) +{ + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_DEF_VALUE]; + + queue_work(ts->set_touchfeature_wq, &ts->set_touchfeature_work); +} + +static int nvt_reset_mode(int mode) +{ + int i = 0; + + NVT_LOG("nvt_reset_mode enter\n"); + + if (mode < Touch_Report_Rate && mode > 0) { + xiaomi_touch_interfaces.touch_mode[mode][SET_CUR_VALUE] = + xiaomi_touch_interfaces.touch_mode[mode][GET_DEF_VALUE]; + nvt_set_cur_value( + mode, + xiaomi_touch_interfaces.touch_mode[mode][SET_CUR_VALUE]); + } else if (mode == 0) { + for (i = 0; i <= Touch_Report_Rate; i++) { + if (i == Touch_Panel_Orientation) { + xiaomi_touch_interfaces + .touch_mode[i][SET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[i][GET_CUR_VALUE]; + } else { + xiaomi_touch_interfaces + .touch_mode[i][SET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[i][GET_DEF_VALUE]; + } + if (i == Touch_Expert_Mode) { + continue; + } + nvt_set_cur_value( + i, xiaomi_touch_interfaces + .touch_mode[i][SET_CUR_VALUE]); + } + } else { + NVT_ERR("%s, don't support\n", __func__); + } + + NVT_LOG("%s, mode:%d\n", __func__, mode); + + return 0; +} +#endif + +#ifdef CONFIG_TOUCHSCREEN_NVT_DEBUG_FS +static void tpdbg_suspend(struct nvt_ts_data *ts_core, bool enable) +{ + if (enable) + nvt_ts_suspend(&ts_core->client->dev); + else + nvt_ts_resume(&ts_core->client->dev); +} + +static int tpdbg_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + + return 0; +} + +static ssize_t tpdbg_read(struct file *file, char __user *buf, size_t size, + loff_t *ppos) +{ + const char *str = "cmd support as below:\n \ + echo \"irq-disable\" or \"irq-enable\" to ctrl irq\n \ + echo \"tp-sd-en\" or \"tp-sd-off\" to ctrl panel on or off sensor\n \ + echo \"tp-suspend-en\" or \"tp-suspend-off\" to ctrl panel in or off suspend status\n \ + echo \"fw-debug-on\" or \"fw-debug-off\" to on or off fw debug function\n"; + + loff_t pos = *ppos; + int len = strlen(str); + + if (pos < 0) + return -EINVAL; + if (pos >= len) + return 0; + + if (copy_to_user(buf, str, len)) + return -EFAULT; + + *ppos = pos + len; + + return len; +} + +static ssize_t tpdbg_write(struct file *file, const char __user *buf, + size_t size, loff_t *ppos) +{ + struct nvt_ts_data *ts_core = file->private_data; + char *cmd = kzalloc(size + 1, GFP_KERNEL); + int ret = size; + + if (!cmd) + return -ENOMEM; + + if (copy_from_user(cmd, buf, size)) { + ret = -EFAULT; + goto out; + } + +#if NVT_TOUCH_ESD_PROTECT + cancel_delayed_work_sync(&nvt_esd_check_work); + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + cmd[size] = '\0'; + + if (!strncmp(cmd, "irq-disable", 11)) + nvt_irq_enable(false); + else if (!strncmp(cmd, "irq-enable", 10)) + nvt_irq_enable(true); + else if (!strncmp(cmd, "tp-sd-en", 8)) + tpdbg_suspend(ts_core, true); + else if (!strncmp(cmd, "tp-sd-off", 9)) + tpdbg_suspend(ts_core, false); + else if (!strncmp(cmd, "tp-suspend-en", 13)) + tpdbg_suspend(ts_core, true); + else if (!strncmp(cmd, "tp-suspend-off", 14)) + tpdbg_suspend(ts_core, false); + else if (!strncmp(cmd, "fw-debug-on", 11)) + nvt_set_dbgfw_status(true); + else if (!strncmp(cmd, "fw-debug-off", 12)) + nvt_set_dbgfw_status(false); +out: + kfree(cmd); + + return ret; +} + +static int tpdbg_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + + return 0; +} + +static ssize_t nvt_touch_test_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + int retval = -1; + uint8_t cmd[8]; + if (copy_from_user(cmd, buf, count)) { + retval = -EFAULT; + goto out; + } + switch (cmd[0]) { + case '0': + ts->debug_flag = 0; + break; + case '1': + ts->debug_flag = 1; + break; + case '2': + ts->debug_flag = 2; + break; + default: + NVT_LOG("%s invalid input cmd, set default value\n", __func__); + ts->debug_flag = 2; + } + NVT_LOG("%s set touch boost debug flag to %d\n", __func__, + ts->debug_flag); + retval = count; +out: + return retval; +} + +static const struct file_operations nvt_touch_test_fops = { + .owner = THIS_MODULE, + .write = nvt_touch_test_write, +}; + +static const struct file_operations tpdbg_ops = { + .owner = THIS_MODULE, + .open = tpdbg_open, + .read = tpdbg_read, + .write = tpdbg_write, + .release = tpdbg_release, +}; +#endif + +static void nvt_suspend_work(struct work_struct *work) +{ + struct nvt_ts_data *ts_core = + container_of(work, struct nvt_ts_data, suspend_work); + nvt_ts_suspend(&ts_core->client->dev); +} + +static void nvt_resume_work(struct work_struct *work) +{ + struct nvt_ts_data *ts_core = + container_of(work, struct nvt_ts_data, resume_work); + nvt_ts_resume(&ts_core->client->dev); +} + +static int nvt_pinctrl_init(struct nvt_ts_data *nvt_data) +{ + int retval = 0; + /* Get pinctrl if target uses pinctrl */ + nvt_data->ts_pinctrl = devm_pinctrl_get(&nvt_data->client->dev); + NVT_LOG("%s Enter\n", __func__); + if (IS_ERR_OR_NULL(nvt_data->ts_pinctrl)) { + retval = PTR_ERR(nvt_data->ts_pinctrl); + NVT_ERR("Target does not use pinctrl %d\n", retval); + goto err_pinctrl_get; + } + + nvt_data->pinctrl_state_active = pinctrl_lookup_state( + nvt_data->ts_pinctrl, PINCTRL_STATE_ACTIVE); + + if (IS_ERR_OR_NULL(nvt_data->pinctrl_state_active)) { + retval = PTR_ERR(nvt_data->pinctrl_state_active); + NVT_ERR("Can not lookup %s pinstate %d\n", PINCTRL_STATE_ACTIVE, + retval); + goto err_pinctrl_lookup; + } + + nvt_data->pinctrl_state_suspend = pinctrl_lookup_state( + nvt_data->ts_pinctrl, PINCTRL_STATE_SUSPEND); + + if (IS_ERR_OR_NULL(nvt_data->pinctrl_state_suspend)) { + retval = PTR_ERR(nvt_data->pinctrl_state_suspend); + NVT_ERR("Can not lookup %s pinstate %d\n", + PINCTRL_STATE_SUSPEND, retval); + goto err_pinctrl_lookup; + } + + return 0; +err_pinctrl_lookup: + devm_pinctrl_put(nvt_data->ts_pinctrl); +err_pinctrl_get: + nvt_data->ts_pinctrl = NULL; + return retval; +} + +static void get_lockdown_info(struct work_struct *work) +{ + int ret = 0; + + NVT_LOG("lkdown_readed = %d", ts->lkdown_readed); + + if (!ts->lkdown_readed) { + ret = dsi_panel_lockdown_info_read(ts->lockdown_info); + if (ret < 0) { + NVT_ERR("can't get lockdown info"); + } else { + NVT_LOG("Lockdown:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", + ts->lockdown_info[0], ts->lockdown_info[1], + ts->lockdown_info[2], ts->lockdown_info[3], + ts->lockdown_info[4], ts->lockdown_info[5], + ts->lockdown_info[6], ts->lockdown_info[7]); + } + ts->lkdown_readed = true; + NVT_LOG("READ LOCKDOWN!!!"); + } else { + NVT_LOG("use lockdown info that readed before"); + NVT_LOG("Lockdown:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", + ts->lockdown_info[0], ts->lockdown_info[1], + ts->lockdown_info[2], ts->lockdown_info[3], + ts->lockdown_info[4], ts->lockdown_info[5], + ts->lockdown_info[6], ts->lockdown_info[7]); + } +} + +/******************************************************* +Description: + Novatek touchscreen write doubleclick wakeup cmd. + +return: + n.a. +*******************************************************/ +void nvt_enable_doubleclick(void) +{ + int ret = 0; + uint8_t buf[4] = { 0 }; + if (ts->db_wakeup) { + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x13; + ret = CTP_SPI_WRITE(ts->client, buf, 2); + if (ret) { + NVT_ERR("Failed\n"); + return; + } + NVT_LOG("Success\n"); + msleep(20); + } else { + NVT_LOG("skip\n"); + } +} + +/******************************************************* +Description: + Novatek touchscreen driver probe function. + +return: + Executive outcomes. 0---succeed. negative---failed +*******************************************************/ +static int32_t nvt_ts_probe(struct spi_device *client) +{ + int32_t ret = 0; +#if ((TOUCH_KEY_NUM > 0) || WAKEUP_GESTURE) + int32_t retry = 0; +#endif + struct attribute_group *attrs_p = NULL; + + NVT_LOG("probe start\n"); + + ts = kzalloc(sizeof(struct nvt_ts_data), GFP_KERNEL); + if (ts == NULL) { + NVT_ERR("failed to allocated memory for nvt ts data\n"); + return -ENOMEM; + } + + ts->xbuf = (uint8_t *)kzalloc((NVT_TRANSFER_LEN + 1 + DUMMY_BYTES), + GFP_KERNEL); + if (ts->xbuf == NULL) { + NVT_ERR("kzalloc for xbuf failed!\n"); + ret = -ENOMEM; + goto err_malloc_xbuf; + } + + ts->rbuf = (uint8_t *)kzalloc(NVT_READ_LEN, GFP_KERNEL); + if (ts->rbuf == NULL) { + NVT_ERR("kzalloc for rbuf failed!\n"); + ret = -ENOMEM; + goto err_malloc_rbuf; + } + + ts->client = client; + spi_set_drvdata(client, ts); + + //---prepare for spi parameter--- + if (ts->client->master->flags & SPI_MASTER_HALF_DUPLEX) { + NVT_ERR("Full duplex not supported by master\n"); + ret = -EIO; + goto err_ckeck_full_duplex; + } + ts->client->bits_per_word = 8; + ts->client->mode = SPI_MODE_0; + + ret = spi_setup(ts->client); + if (ret < 0) { + NVT_ERR("Failed to perform SPI setup\n"); + goto err_spi_setup; + } + +#ifdef CONFIG_MTK_SPI + /* old usage of MTK spi API */ + memcpy(&ts->spi_ctrl, &spi_ctrdata, sizeof(struct mt_chip_conf)); + ts->client->controller_data = (void *)&ts->spi_ctrl; +#endif + +#ifdef CONFIG_SPI_MT65XX + /* new usage of MTK spi API */ + memcpy(&ts->spi_ctrl, &spi_ctrdata, sizeof(struct mtk_chip_config)); + ts->client->controller_data = (void *)&ts->spi_ctrl; +#endif + + NVT_LOG("mode=%d, max_speed_hz=%d\n", ts->client->mode, + ts->client->max_speed_hz); + + //---parse dts--- + ret = nvt_parse_dt(&client->dev); + if (ret) { + NVT_ERR("parse dt error\n"); + goto err_spi_setup; + } + + ret = nvt_pinctrl_init(ts); + if (!ret && ts->ts_pinctrl) { + ret = pinctrl_select_state(ts->ts_pinctrl, + ts->pinctrl_state_active); + if (ret < 0) { + NVT_ERR("Failed to select %s pinstate %d\n", + PINCTRL_STATE_ACTIVE, ret); + } + } else { + NVT_ERR("Failed to init pinctrl\n"); + } + + //---request and config GPIOs--- + ret = nvt_gpio_config(ts); + if (ret) { + NVT_ERR("gpio config error!\n"); + goto err_gpio_config_failed; + } + + mutex_init(&ts->lock); + mutex_init(&ts->xbuf_lock); + + //---eng reset before TP_RESX high + nvt_eng_reset(); + +#if NVT_TOUCH_SUPPORT_HW_RST + gpio_set_value(ts->reset_gpio, 1); +#endif + + // need 10ms delay after POR(power on reset) + msleep(10); + + //---check chip version trim--- + ret = nvt_ts_check_chip_ver_trim(CHIP_VER_TRIM_ADDR); + if (ret) { + NVT_LOG("try to check from old chip ver trim address\n"); + ret = nvt_ts_check_chip_ver_trim(CHIP_VER_TRIM_OLD_ADDR); + if (ret) { + NVT_ERR("chip is not identified\n"); + ret = -EINVAL; + goto err_chipvertrim_failed; + } + } + + ts->abs_x_max = TOUCH_DEFAULT_MAX_WIDTH; + ts->abs_y_max = TOUCH_DEFAULT_MAX_HEIGHT; + + //---allocate input device--- + ts->input_dev = input_allocate_device(); + if (ts->input_dev == NULL) { + NVT_ERR("allocate input device failed\n"); + ret = -ENOMEM; + goto err_input_dev_alloc_failed; + } + + ts->max_touch_num = TOUCH_MAX_FINGER_NUM; + +#if TOUCH_KEY_NUM > 0 + ts->max_button_num = TOUCH_KEY_NUM; +#endif + + ts->int_trigger_type = INT_TRIGGER_TYPE; + + //---set input device info.--- + ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | + BIT_MASK(EV_ABS); + ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + ts->input_dev->propbit[0] = BIT(INPUT_PROP_DIRECT); + + ts->db_wakeup = 0; + ts->fw_ver = 0; + ts->x_num = 32; + ts->y_num = 50; + ts->x_gang_num = 4; + ts->y_gang_num = 6; + ts->abs_x_max = TOUCH_DEFAULT_MAX_WIDTH; + ts->abs_y_max = TOUCH_DEFAULT_MAX_HEIGHT; + ts->max_button_num = TOUCH_KEY_NUM; + NVT_LOG("Set default fw_ver=%d, x_num=%d, y_num=%d, " + "abs_x_max=%d, abs_y_max=%d, max_button_num=%d!\n", + ts->fw_ver, ts->x_num, ts->y_num, ts->abs_x_max, ts->abs_y_max, + ts->max_button_num); + +#if MT_PROTOCOL_B + input_mt_init_slots(ts->input_dev, ts->max_touch_num, 0); +#endif + + input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE, 0, TOUCH_FORCE_NUM, + 0, 0); //pressure = TOUCH_FORCE_NUM + +#if TOUCH_MAX_FINGER_NUM > 1 + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, + 0); //area = 255 + + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, + ts->abs_x_max - 1, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, + ts->abs_y_max - 1, 0, 0); +#if MT_PROTOCOL_B + // no need to set ABS_MT_TRACKING_ID, input_mt_init_slots() already set it +#else + input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, + ts->max_touch_num, 0, 0); +#endif //MT_PROTOCOL_B +#endif //TOUCH_MAX_FINGER_NUM > 1 + +#if TOUCH_KEY_NUM > 0 + for (retry = 0; retry < ts->max_button_num; retry++) { + input_set_capability(ts->input_dev, EV_KEY, + touch_key_array[retry]); + } +#endif + +#if WAKEUP_GESTURE + for (retry = 0; + retry < (sizeof(gesture_key_array) / sizeof(gesture_key_array[0])); + retry++) { + input_set_capability(ts->input_dev, EV_KEY, + gesture_key_array[retry]); + } +#endif + + sprintf(ts->phys, "input/ts"); + ts->input_dev->name = NVT_TS_NAME; + ts->input_dev->phys = ts->phys; + ts->input_dev->id.bustype = BUS_SPI; + + //---register input device--- + ret = input_register_device(ts->input_dev); + if (ret) { + NVT_ERR("register input device (%s) failed. ret=%d\n", + ts->input_dev->name, ret); + goto err_input_register_device_failed; + } + + if (ts->pen_support) { + //---allocate pen input device--- + ts->pen_input_dev = input_allocate_device(); + if (ts->pen_input_dev == NULL) { + NVT_ERR("allocate pen input device failed\n"); + ret = -ENOMEM; + goto err_pen_input_dev_alloc_failed; + } + + //---set pen input device info.--- + ts->pen_input_dev->evbit[0] = + BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + ts->pen_input_dev->keybit[BIT_WORD(BTN_TOUCH)] = + BIT_MASK(BTN_TOUCH); + ts->pen_input_dev->keybit[BIT_WORD(BTN_TOOL_PEN)] |= + BIT_MASK(BTN_TOOL_PEN); + //ts->pen_input_dev->keybit[BIT_WORD(BTN_TOOL_RUBBER)] |= BIT_MASK(BTN_TOOL_RUBBER); + ts->pen_input_dev->keybit[BIT_WORD(BTN_STYLUS)] |= + BIT_MASK(BTN_STYLUS); + ts->pen_input_dev->keybit[BIT_WORD(BTN_STYLUS2)] |= + BIT_MASK(BTN_STYLUS2); + ts->pen_input_dev->propbit[0] = BIT(INPUT_PROP_DIRECT); + + if (ts->wgp_stylus) { + input_set_abs_params(ts->pen_input_dev, ABS_X, 0, + ts->abs_x_max * 2 - 1, 0, 0); + input_set_abs_params(ts->pen_input_dev, ABS_Y, 0, + ts->abs_y_max * 2 - 1, 0, 0); + } else { + input_set_abs_params(ts->pen_input_dev, ABS_X, 0, + ts->abs_x_max - 1, 0, 0); + input_set_abs_params(ts->pen_input_dev, ABS_Y, 0, + ts->abs_y_max - 1, 0, 0); + } + + input_set_abs_params(ts->pen_input_dev, ABS_PRESSURE, 0, + PEN_PRESSURE_MAX, 0, 0); + input_set_abs_params(ts->pen_input_dev, ABS_DISTANCE, 0, + PEN_DISTANCE_MAX, 0, 0); + input_set_abs_params(ts->pen_input_dev, ABS_TILT_X, + PEN_TILT_MIN, PEN_TILT_MAX, 0, 0); + input_set_abs_params(ts->pen_input_dev, ABS_TILT_Y, + PEN_TILT_MIN, PEN_TILT_MAX, 0, 0); + + sprintf(ts->pen_phys, "input/pen"); + ts->pen_input_dev->name = NVT_PEN_NAME; + ts->pen_input_dev->phys = ts->pen_phys; + ts->pen_input_dev->id.bustype = BUS_SPI; + + //---register pen input device--- + ret = input_register_device(ts->pen_input_dev); + if (ret) { + NVT_ERR("register pen input device (%s) failed. ret=%d\n", + ts->pen_input_dev->name, ret); + goto err_pen_input_register_device_failed; + } + } /* if (ts->pen_support) */ + + //---set int-pin & request irq--- + client->irq = gpio_to_irq(ts->irq_gpio); + if (client->irq) { + NVT_LOG("int_trigger_type=%d\n", ts->int_trigger_type); + ts->irq_enabled = true; + ret = request_threaded_irq(client->irq, NULL, nvt_ts_work_func, + ts->int_trigger_type | IRQF_ONESHOT, + NVT_SPI_NAME, ts); + if (ret != 0) { + NVT_ERR("request irq failed. ret=%d\n", ret); + goto err_int_request_failed; + } else { + nvt_irq_enable(false); + NVT_LOG("request irq %d succeed\n", client->irq); + } + } + + INIT_WORK(&ts->switch_mode_work, nvt_switch_mode_work); + INIT_WORK(&ts->pen_charge_state_change_work, + nvt_pen_charge_state_change_work); + ts->pen_is_charge = false; + + ts->lkdown_readed = false; + pm_stay_awake(&client->dev); + nvt_lockdown_wq = alloc_workqueue("nvt_lockdown_wq", + WQ_UNBOUND | WQ_MEM_RECLAIM, 1); + if (!nvt_lockdown_wq) { + NVT_ERR("nvt_lockdown_wq create workqueue failed\n"); + ret = -ENOMEM; + goto err_create_nvt_lockdown_wq_failed; + } + INIT_DELAYED_WORK(&ts->nvt_lockdown_work, get_lockdown_info); + /* please make sure boot update start after display reset(RESX) sequence*/ + queue_delayed_work(nvt_lockdown_wq, &ts->nvt_lockdown_work, + msecs_to_jiffies(4000)); + +#if WAKEUP_GESTURE + device_init_wakeup(&ts->input_dev->dev, 1); +#endif + + ts->ic_state = NVT_IC_INIT; + ts->dev_pm_suspend = false; + ts->gesture_command_delayed = -1; + init_completion(&ts->dev_pm_suspend_completion); + ts->fw_debug = false; + +#ifdef CONFIG_FACTORY_BUILD + ts->pen_input_dev_enable = 1; +#else + ts->pen_input_dev_enable = 0; +#endif + +#if BOOT_UPDATE_FIRMWARE + nvt_fwu_wq = + alloc_workqueue("nvt_fwu_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 1); + if (!nvt_fwu_wq) { + NVT_ERR("nvt_fwu_wq create workqueue failed\n"); + ret = -ENOMEM; + goto err_create_nvt_fwu_wq_failed; + } + INIT_DELAYED_WORK(&ts->nvt_fwu_work, Boot_Update_Firmware); + // please make sure boot update start after display reset(RESX) sequence + queue_delayed_work(nvt_fwu_wq, &ts->nvt_fwu_work, + msecs_to_jiffies(14000)); +#endif + + NVT_LOG("NVT_TOUCH_ESD_PROTECT is %d\n", NVT_TOUCH_ESD_PROTECT); +#if NVT_TOUCH_ESD_PROTECT + INIT_DELAYED_WORK(&nvt_esd_check_work, nvt_esd_check_func); + nvt_esd_check_wq = + alloc_workqueue("nvt_esd_check_wq", WQ_MEM_RECLAIM, 1); + if (!nvt_esd_check_wq) { + NVT_ERR("nvt_esd_check_wq create workqueue failed\n"); + ret = -ENOMEM; + goto err_create_nvt_esd_check_wq_failed; + } + queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work, + msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD)); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + //---set device node--- +#if NVT_TOUCH_PROC + ret = nvt_flash_proc_init(); + if (ret != 0) { + NVT_ERR("nvt flash proc init failed. ret=%d\n", ret); + goto err_flash_proc_init_failed; + } +#endif + +#if NVT_TOUCH_EXT_PROC + ret = nvt_extra_proc_init(); + if (ret != 0) { + NVT_ERR("nvt extra proc init failed. ret=%d\n", ret); + goto err_extra_proc_init_failed; + } +#endif + +#if NVT_TOUCH_MP + ret = nvt_mp_proc_init(); + if (ret != 0) { + NVT_ERR("nvt mp proc init failed. ret=%d\n", ret); + goto err_mp_proc_init_failed; + } +#endif + +#ifndef NVT_SAVE_TESTDATA_IN_FILE + ret = nvt_test_data_proc_init(ts->client); + if (ret < 0) { + NVT_ERR("nvt test data interface init failed. ret=%d\n", ret); + goto err_mp_proc_init_failed; + } +#endif + + attrs_p = (struct attribute_group *)devm_kzalloc( + &client->dev, sizeof(*attrs_p), GFP_KERNEL); + if (!attrs_p) { + NVT_ERR("no mem to alloc"); + goto err_mp_proc_init_failed; + } + ts->attrs = attrs_p; + attrs_p->name = "panel_info"; + attrs_p->attrs = nvt_panel_attr; + ret = sysfs_create_group(&client->dev.kobj, ts->attrs); + + ts->event_wq = + alloc_workqueue("nvt-event-queue", + WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); + if (!ts->event_wq) { + NVT_ERR("Can not create work thread for suspend/resume!!"); + ret = -ENOMEM; + goto err_alloc_work_thread_failed; + } + INIT_WORK(&ts->resume_work, nvt_resume_work); + INIT_WORK(&ts->suspend_work, nvt_suspend_work); + ts->set_touchfeature_wq = + create_singlethread_workqueue("nvt-set-touchfeature-queue"); + if (!ts->set_touchfeature_wq) { + NVT_ERR("create set touch feature workqueue fail"); + ret = -ENOMEM; + goto err_create_set_touchfeature_work_queue; + } + INIT_WORK(&ts->set_touchfeature_work, update_touchfeature_value_work); + + ts->pen_charge_state_notifier.notifier_call = + nvt_pen_charge_state_notifier_callback; + ret = pen_charge_state_notifier_register_client( + &ts->pen_charge_state_notifier); + if (ret) { + NVT_ERR("register pen charge state change notifier failed. ret=%d\n", + ret); + goto err_register_pen_charge_state_failed; + } +#if defined(CONFIG_FB) +#ifdef CONFIG_DRM + ts->drm_notif.notifier_call = nvt_drm_notifier_callback; + ret = drm_register_client(&ts->drm_notif); + if (ret) { + NVT_ERR("register drm_notifier failed. ret=%d\n", ret); + goto err_register_drm_notif_failed; + } +#else + ts->fb_notif.notifier_call = nvt_fb_notifier_callback; + ret = fb_register_client(&ts->fb_notif); + if (ret) { + NVT_ERR("register fb_notifier failed. ret=%d\n", ret); + goto err_register_fb_notif_failed; + } +#endif +#elif defined(CONFIG_HAS_EARLYSUSPEND) + ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + ts->early_suspend.suspend = nvt_ts_early_suspend; + ts->early_suspend.resume = nvt_ts_late_resume; + ret = register_early_suspend(&ts->early_suspend); + if (ret) { + NVT_ERR("register early suspend failed. ret=%d\n", ret); + goto err_register_early_suspend_failed; + } +#endif + +#ifdef CONFIG_TOUCHSCREEN_NVT_DEBUG_FS + ts->debugfs = debugfs_create_dir("tp_debug", NULL); + if (ts->debugfs) { + debugfs_create_file("switch_state", 0660, ts->debugfs, ts, + &tpdbg_ops); + debugfs_create_file("touch_boost", 0660, ts->debugfs, ts, + &nvt_touch_test_fops); + } +#endif + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + xiaomi_touch_interfaces.touch_vendor_read = nvt_touch_vendor_read; + xiaomi_touch_interfaces.panel_display_read = nvt_panel_display_read; + xiaomi_touch_interfaces.panel_vendor_read = nvt_panel_vendor_read; + xiaomi_touch_interfaces.panel_color_read = nvt_panel_color_read; + xiaomi_touch_interfaces.getModeValue = nvt_get_mode_value; + xiaomi_touch_interfaces.setModeValue = nvt_set_cur_value; + xiaomi_touch_interfaces.resetMode = nvt_reset_mode; + xiaomi_touch_interfaces.getModeAll = nvt_get_mode_all; + xiaomi_touch_interfaces.palm_sensor_write = nvt_palm_sensor_write; + nvt_init_touchmode_data(); + xiaomitouch_register_modedata(&xiaomi_touch_interfaces); +#endif + + bTouchIsAwake = 1; + NVT_LOG("end\n"); + + nvt_irq_enable(true); + + return 0; + +#if defined(CONFIG_FB) +#ifdef CONFIG_DRM + if (drm_unregister_client(&ts->drm_notif)) + NVT_ERR("Error occurred while unregistering drm_notifier.\n"); +err_register_drm_notif_failed: +#else + if (fb_unregister_client(&ts->fb_notif)) + NVT_ERR("Error occurred while unregistering fb_notifier.\n"); +err_register_fb_notif_failed: +#endif +#elif defined(CONFIG_HAS_EARLYSUSPEND) + unregister_early_suspend(&ts->early_suspend); +err_register_early_suspend_failed: +#endif + if (pen_charge_state_notifier_unregister_client( + &ts->pen_charge_state_notifier)) + NVT_ERR("Error occurred while unregistering pen charge state notifier.\n"); +err_register_pen_charge_state_failed: + destroy_workqueue(ts->set_touchfeature_wq); +err_create_set_touchfeature_work_queue: + destroy_workqueue(ts->event_wq); +err_alloc_work_thread_failed: +#ifndef NVT_SAVE_TESTDATA_IN_FILE + nvt_test_data_proc_deinit(); +#endif +#if NVT_TOUCH_MP + nvt_mp_proc_deinit(); +err_mp_proc_init_failed: +#endif +#if NVT_TOUCH_EXT_PROC + nvt_extra_proc_deinit(); +err_extra_proc_init_failed: +#endif +#if NVT_TOUCH_PROC + nvt_flash_proc_deinit(); +err_flash_proc_init_failed: +#endif +#if NVT_TOUCH_ESD_PROTECT + if (nvt_esd_check_wq) { + cancel_delayed_work_sync(&nvt_esd_check_work); + destroy_workqueue(nvt_esd_check_wq); + nvt_esd_check_wq = NULL; + } +err_create_nvt_esd_check_wq_failed: +#endif +#if BOOT_UPDATE_FIRMWARE + if (nvt_fwu_wq) { + cancel_delayed_work_sync(&ts->nvt_fwu_work); + destroy_workqueue(nvt_fwu_wq); + nvt_fwu_wq = NULL; + } +err_create_nvt_fwu_wq_failed: + if (nvt_lockdown_wq) { + cancel_delayed_work_sync(&ts->nvt_lockdown_work); + destroy_workqueue(nvt_lockdown_wq); + nvt_lockdown_wq = NULL; + } +#endif +err_create_nvt_lockdown_wq_failed: +#if WAKEUP_GESTURE + device_init_wakeup(&ts->input_dev->dev, 0); +#endif + free_irq(client->irq, ts); +err_int_request_failed: + if (ts->pen_support) { + input_unregister_device(ts->pen_input_dev); + ts->pen_input_dev = NULL; + } +err_pen_input_register_device_failed: + if (ts->pen_support) { + if (ts->pen_input_dev) { + input_free_device(ts->pen_input_dev); + ts->pen_input_dev = NULL; + } + } +err_pen_input_dev_alloc_failed: + input_unregister_device(ts->input_dev); + ts->input_dev = NULL; +err_input_register_device_failed: + if (ts->input_dev) { + input_free_device(ts->input_dev); + ts->input_dev = NULL; + } +err_input_dev_alloc_failed: +err_chipvertrim_failed: + mutex_destroy(&ts->xbuf_lock); + mutex_destroy(&ts->lock); + nvt_gpio_deconfig(ts); +err_gpio_config_failed: +err_spi_setup: +err_ckeck_full_duplex: + spi_set_drvdata(client, NULL); + if (ts->rbuf) { + kfree(ts->rbuf); + ts->rbuf = NULL; + } +err_malloc_rbuf: + if (ts->xbuf) { + kfree(ts->xbuf); + ts->xbuf = NULL; + } +err_malloc_xbuf: + if (ts) { + kfree(ts); + ts = NULL; + } + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen driver release function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t nvt_ts_remove(struct spi_device *client) +{ + NVT_LOG("Removing driver...\n"); + +#if defined(CONFIG_FB) +#ifdef CONFIG_DRM + if (drm_unregister_client(&ts->drm_notif)) + NVT_ERR("Error occurred while unregistering drm_notifier.\n"); +#else + if (fb_unregister_client(&ts->fb_notif)) + NVT_ERR("Error occurred while unregistering fb_notifier.\n"); +#endif +#elif defined(CONFIG_HAS_EARLYSUSPEND) + unregister_early_suspend(&ts->early_suspend); +#endif + + if (pen_charge_state_notifier_unregister_client( + &ts->pen_charge_state_notifier)) + NVT_ERR("Error occurred while unregistering pen charge state notifier.\n"); + +#if NVT_TOUCH_MP + nvt_mp_proc_deinit(); +#endif +#if NVT_TOUCH_EXT_PROC + nvt_extra_proc_deinit(); +#endif +#if NVT_TOUCH_PROC + nvt_flash_proc_deinit(); +#endif + +#if NVT_TOUCH_ESD_PROTECT + if (nvt_esd_check_wq) { + cancel_delayed_work_sync(&nvt_esd_check_work); + nvt_esd_check_enable(false); + destroy_workqueue(nvt_esd_check_wq); + nvt_esd_check_wq = NULL; + } +#endif + +#if BOOT_UPDATE_FIRMWARE + if (nvt_fwu_wq) { + cancel_delayed_work_sync(&ts->nvt_fwu_work); + destroy_workqueue(nvt_fwu_wq); + nvt_fwu_wq = NULL; + } +#endif + +#if WAKEUP_GESTURE + device_init_wakeup(&ts->input_dev->dev, 0); +#endif + + nvt_irq_enable(false); + free_irq(client->irq, ts); + + mutex_destroy(&ts->xbuf_lock); + mutex_destroy(&ts->lock); + + nvt_gpio_deconfig(ts); + + if (ts->pen_support) { + if (ts->pen_input_dev) { + input_unregister_device(ts->pen_input_dev); + ts->pen_input_dev = NULL; + } + } + + if (ts->input_dev) { + input_unregister_device(ts->input_dev); + ts->input_dev = NULL; + } + + spi_set_drvdata(client, NULL); + + if (ts->set_touchfeature_wq) + destroy_workqueue(ts->set_touchfeature_wq); + + if (ts) { + kfree(ts); + ts = NULL; + } + + return 0; +} + +static void nvt_ts_shutdown(struct spi_device *client) +{ + NVT_LOG("Shutdown driver...\n"); + + nvt_irq_enable(false); + +#if defined(CONFIG_FB) +#ifdef CONFIG_DRM + if (drm_unregister_client(&ts->drm_notif)) + NVT_ERR("Error occurred while unregistering drm_notifier.\n"); +#else + if (fb_unregister_client(&ts->fb_notif)) + NVT_ERR("Error occurred while unregistering fb_notifier.\n"); +#endif +#elif defined(CONFIG_HAS_EARLYSUSPEND) + unregister_early_suspend(&ts->early_suspend); +#endif + + destroy_workqueue(ts->event_wq); + if (pen_charge_state_notifier_unregister_client( + &ts->pen_charge_state_notifier)) + NVT_ERR("Error occurred while unregistering pen charge state notifier.\n"); + +#if NVT_TOUCH_MP + nvt_mp_proc_deinit(); +#endif +#if NVT_TOUCH_EXT_PROC + nvt_extra_proc_deinit(); +#endif +#if NVT_TOUCH_PROC + nvt_flash_proc_deinit(); +#endif + +#if NVT_TOUCH_ESD_PROTECT + if (nvt_esd_check_wq) { + cancel_delayed_work_sync(&nvt_esd_check_work); + nvt_esd_check_enable(false); + destroy_workqueue(nvt_esd_check_wq); + nvt_esd_check_wq = NULL; + } +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + +#if BOOT_UPDATE_FIRMWARE + if (nvt_fwu_wq) { + cancel_delayed_work_sync(&ts->nvt_fwu_work); + destroy_workqueue(nvt_fwu_wq); + nvt_fwu_wq = NULL; + } +#endif + +#if WAKEUP_GESTURE + device_init_wakeup(&ts->input_dev->dev, 0); +#endif +} + +/******************************************************* +Description: + Novatek touchscreen driver suspend function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t nvt_ts_suspend(struct device *dev) +{ + uint8_t buf[4] = { 0 }; + int ret; +#if MT_PROTOCOL_B + uint32_t i = 0; +#endif + + if (!bTouchIsAwake) { + NVT_LOG("Touch is already suspend\n"); + return 0; + } + + pm_stay_awake(dev); + ts->ic_state = NVT_IC_SUSPEND_IN; + + if (!ts->db_wakeup) { + if (!ts->irq_enabled) + NVT_LOG("IRQ already disabled\n"); + else + nvt_irq_enable(false); + } + +#if NVT_TOUCH_ESD_PROTECT + NVT_LOG("cancel delayed work sync\n"); + cancel_delayed_work_sync(&nvt_esd_check_work); + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + mutex_lock(&ts->lock); + + NVT_LOG("suspend start\n"); + + bTouchIsAwake = 0; + + if (ts->pen_input_dev_enable) { + NVT_LOG("if enable pen,will close it"); + disable_pen_input_device(true); + } + + if (ts->db_wakeup) { + /*---write command to enter "wakeup gesture mode"---*/ + /*DoubleClick wakeup CMD was sent by display to meet timing*/ + /* + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x13; + CTP_SPI_WRITE(ts->client, buf, 2); + */ + enable_irq_wake(ts->client->irq); + + NVT_LOG("Enabled touch wakeup gesture\n"); + } else { + /*---write command to enter "deep sleep mode"---*/ + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x11; + CTP_SPI_WRITE(ts->client, buf, 2); + if (ts->ts_pinctrl) { + ret = pinctrl_select_state(ts->ts_pinctrl, + ts->pinctrl_state_suspend); + if (ret < 0) { + NVT_ERR("Failed to select %s pinstate %d\n", + PINCTRL_STATE_SUSPEND, ret); + } + } else { + NVT_ERR("Failed to init pinctrl\n"); + } + } + + mutex_unlock(&ts->lock); + + /* release all touches */ +#if MT_PROTOCOL_B + for (i = 0; i < ts->max_touch_num; i++) { + input_mt_slot(ts->input_dev, i); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); + } +#endif + input_report_key(ts->input_dev, BTN_TOUCH, 0); +#if !MT_PROTOCOL_B + input_mt_sync(ts->input_dev); +#endif + input_sync(ts->input_dev); + + msleep(50); + /* release pen event */ + release_pen_event(); + if (likely(ts->ic_state == NVT_IC_SUSPEND_IN)) + ts->ic_state = NVT_IC_SUSPEND_OUT; + else + NVT_ERR("IC state may error,caused by suspend/resume flow, please CHECK!!"); + pm_relax(dev); + NVT_LOG("end\n"); + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen driver resume function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t nvt_ts_resume(struct device *dev) +{ + int ret = 0; + if (bTouchIsAwake) { + NVT_LOG("Touch is already resume\n"); + return 0; + } + + if (ts->dev_pm_suspend) + pm_stay_awake(dev); + + mutex_lock(&ts->lock); + + NVT_LOG("resume start\n"); + ts->ic_state = NVT_IC_RESUME_IN; + if (!ts->db_wakeup) { + if (ts->ts_pinctrl) { + ret = pinctrl_select_state(ts->ts_pinctrl, + ts->pinctrl_state_active); + if (ret < 0) { + NVT_ERR("Failed to select %s pinstate %d\n", + PINCTRL_STATE_ACTIVE, ret); + } + } else { + NVT_ERR("Failed to init pinctrl\n"); + } + } + + // please make sure display reset(RESX) sequence and mipi dsi cmds sent before this +#if NVT_TOUCH_SUPPORT_HW_RST + gpio_set_value(ts->reset_gpio, 1); +#endif + if (nvt_get_dbgfw_status()) { + ret = nvt_update_firmware(DEFAULT_DEBUG_FW_NAME); + if (ret < 0) { + NVT_ERR("use built-in fw"); + ret = nvt_update_firmware(ts->fw_name); + } + } else { + ret = nvt_update_firmware(ts->fw_name); + } + if (ret) + NVT_ERR("download firmware failed\n"); + + nvt_check_fw_reset_state(RESET_STATE_REK); + + if (!ts->db_wakeup && !ts->irq_enabled) { + nvt_irq_enable(true); + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); + queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work, + msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD)); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + bTouchIsAwake = 1; + + mutex_unlock(&ts->lock); + + disable_pen_input_device(false); + dsi_panel_doubleclick_enable( + !!ts->db_wakeup); /*if true, dbclick work until next suspend*/ + if (likely(ts->ic_state == NVT_IC_RESUME_IN)) { + ts->ic_state = NVT_IC_RESUME_OUT; + } else { + NVT_ERR("IC state may error,caused by suspend/resume flow, please CHECK!!"); + } + if (ts->gesture_command_delayed >= 0) { + ts->db_wakeup = ts->gesture_command_delayed; + ts->gesture_command_delayed = -1; + NVT_LOG("execute delayed command, set double click wakeup %d\n", + ts->db_wakeup); + dsi_panel_doubleclick_enable(!!ts->db_wakeup); + } + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + NVT_LOG("reload the game mode cmd"); + nvt_game_mode_recovery(); +#endif + + if (ts->dev_pm_suspend) + pm_relax(dev); + NVT_LOG("end\n"); + + return 0; +} + +#if defined(CONFIG_FB) +#ifdef CONFIG_DRM +static int nvt_drm_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct drm_notify_data *evdata = data; + int *blank; + struct nvt_ts_data *ts_data = + container_of(self, struct nvt_ts_data, drm_notif); + + if (!evdata) + return 0; + + if (evdata && ts_data) { + blank = evdata->data; + if (event == DRM_EARLY_EVENT_BLANK) { + if (*blank == DRM_BLANK_POWERDOWN) { + NVT_LOG("event=%lu, *blank=%d\n", event, + *blank); + flush_workqueue(ts_data->event_wq); + queue_work(ts_data->event_wq, + &ts_data->suspend_work); + } + } else if (event == DRM_R_EARLY_EVENT_BLANK) { + if (*blank == DRM_BLANK_POWERDOWN) { + NVT_LOG("event=%lu, *blank=%d\n", event, + *blank); + nvt_enable_doubleclick(); + } + } else if (event == DRM_EVENT_BLANK) { + if (*blank == DRM_BLANK_UNBLANK) { + NVT_LOG("event=%lu, *blank=%d\n", event, + *blank); + flush_workqueue(ts_data->event_wq); + queue_work(ts_data->event_wq, + &ts_data->resume_work); + } + } + } + + return 0; +} +#else +static int nvt_fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + struct nvt_ts_data *ts = + container_of(self, struct nvt_ts_data, fb_notif); + + if (evdata && evdata->data && event == FB_EARLY_EVENT_BLANK) { + blank = evdata->data; + if (*blank == FB_BLANK_POWERDOWN) { + NVT_LOG("event=%lu, *blank=%d\n", event, *blank); + nvt_ts_suspend(&ts->client->dev); + } + } else if (evdata && evdata->data && event == FB_EVENT_BLANK) { + blank = evdata->data; + if (*blank == FB_BLANK_UNBLANK) { + NVT_LOG("event=%lu, *blank=%d\n", event, *blank); + nvt_ts_resume(&ts->client->dev); + } + } + + return 0; +} +#endif + +static int nvt_pm_suspend(struct device *dev) +{ + if (device_may_wakeup(dev) && ts->db_wakeup) { + NVT_LOG("enable touch irq wake\n"); + enable_irq_wake(ts->client->irq); + } + ts->dev_pm_suspend = true; + reinit_completion(&ts->dev_pm_suspend_completion); + + return 0; +} + +static int nvt_pm_resume(struct device *dev) +{ + if (device_may_wakeup(dev) && ts->db_wakeup) { + NVT_LOG("disable touch irq wake\n"); + disable_irq_wake(ts->client->irq); + } + ts->dev_pm_suspend = false; + complete(&ts->dev_pm_suspend_completion); + + return 0; +} + +static const struct dev_pm_ops nvt_dev_pm_ops = { + .suspend = nvt_pm_suspend, + .resume = nvt_pm_resume, +}; + +#elif defined(CONFIG_HAS_EARLYSUSPEND) +/******************************************************* +Description: + Novatek touchscreen driver early suspend function. + +return: + n.a. +*******************************************************/ +static void nvt_ts_early_suspend(struct early_suspend *h) +{ + nvt_ts_suspend(ts->client, PMSG_SUSPEND); +} + +/******************************************************* +Description: + Novatek touchscreen driver late resume function. + +return: + n.a. +*******************************************************/ +static void nvt_ts_late_resume(struct early_suspend *h) +{ + nvt_ts_resume(ts->client); +} +#endif + +static const struct spi_device_id nvt_ts_id[] = { { NVT_SPI_NAME, 0 }, {} }; + +#ifdef CONFIG_OF +static struct of_device_id nvt_match_table[] = { + { + .compatible = "novatek,NVT-ts-spi", + }, + {}, +}; +#endif + +static struct spi_driver nvt_spi_driver = { + .probe = nvt_ts_probe, + .remove = nvt_ts_remove, + .shutdown = nvt_ts_shutdown, + .id_table = nvt_ts_id, + .driver = { + .name = NVT_SPI_NAME, + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &nvt_dev_pm_ops, +#endif +#ifdef CONFIG_OF + .of_match_table = nvt_match_table, +#endif + }, +}; + +static bool nvt_off_charger_mode(void) +{ + bool charger_mode = false; + char charger_node[8] = { '\0' }; + char *chose = (char *)strnstr(saved_command_line, "androidboot.mode=", + strlen(saved_command_line)); + if (chose) { + memcpy(charger_node, (chose + strlen("androidboot.mode=")), + sizeof(charger_node) - 1); + NVT_LOG("%s: charger_node is %s\n", __func__, charger_node); + if (!strncmp(charger_node, "charger", strlen("charger"))) { + charger_mode = true; + } + } + return charger_mode; +} + +/******************************************************* +Description: + Driver Install function. + +return: + Executive Outcomes. 0---succeed. not 0---failed. +********************************************************/ +static int32_t __init nvt_driver_init(void) +{ + int32_t ret = 0; + + NVT_LOG("driver init start\n"); + if (nvt_off_charger_mode()) { + NVT_LOG("off_charger states, %s exit", __func__); + return 0; + } + + //---add spi driver--- + ret = spi_register_driver(&nvt_spi_driver); + if (ret) { + NVT_ERR("failed to add spi driver"); + goto err_driver; + } + + NVT_LOG("finished\n"); + +err_driver: + return ret; +} + +/******************************************************* +Description: + Driver uninstall function. + +return: + n.a. +********************************************************/ +static void __exit nvt_driver_exit(void) +{ + spi_unregister_driver(&nvt_spi_driver); +} + +late_initcall(nvt_driver_init); +//module_init(nvt_driver_init); +module_exit(nvt_driver_exit); + +MODULE_DESCRIPTION("Novatek Touchscreen Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.h b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.h new file mode 100644 index 000000000000..fcc59ba5cf78 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.h @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * $Revision: 69262 $ + * $Date: 2020-09-23 15:07:14 +0800 (週三, 23 乿œˆ 2020) $ + * + * 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 _LINUX_NVT_TOUCH_H +#define _LINUX_NVT_TOUCH_H + +#include +#include +#include +#include +#include + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include "nt36xxx_mem_map.h" + +#ifdef CONFIG_MTK_SPI +/* Please copy mt_spi.h file under mtk spi driver folder */ +#include "mt_spi.h" +#endif + +#ifdef CONFIG_SPI_MT65XX +#include +#endif + +#define NVT_DEBUG 1 + +//---GPIO number--- +#define NVTTOUCH_RST_PIN 980 +#define NVTTOUCH_INT_PIN 943 + +#define NVT_LOCKDOWN_SIZE 8 +#define PINCTRL_STATE_ACTIVE "pmx_ts_active" +#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend" + +//---INT trigger mode--- +//#define IRQ_TYPE_EDGE_RISING 1 +//#define IRQ_TYPE_EDGE_FALLING 2 +#define INT_TRIGGER_TYPE IRQ_TYPE_EDGE_RISING + +//---SPI driver info.--- +#define NVT_SPI_NAME "NVT-ts" + +#if NVT_DEBUG +#define NVT_LOG(fmt, args...) \ + pr_err("[%s] %s %d: " fmt, NVT_SPI_NAME, __func__, __LINE__, ##args) +#else +#define NVT_LOG(fmt, args...) \ + pr_info("[%s] %s %d: " fmt, NVT_SPI_NAME, __func__, __LINE__, ##args) +#endif +#define NVT_ERR(fmt, args...) \ + pr_err("[%s] %s %d: " fmt, NVT_SPI_NAME, __func__, __LINE__, ##args) + +//---Input device info.--- +#define NVT_TS_NAME "NVTCapacitiveTouchScreen" +#define NVT_PEN_NAME "NVTCapacitivePen" + +//---Touch info.--- +#define TOUCH_DEFAULT_MAX_WIDTH 1600 +#define TOUCH_DEFAULT_MAX_HEIGHT 2560 +#define TOUCH_MAX_FINGER_NUM 10 +#define TOUCH_KEY_NUM 0 +#if TOUCH_KEY_NUM > 0 +extern const uint16_t touch_key_array[TOUCH_KEY_NUM]; +#endif +#define TOUCH_FORCE_NUM 1000 +//---for Pen--- +#define PEN_PRESSURE_MAX (4095) +#define PEN_DISTANCE_MAX (1) +#define PEN_TILT_MIN (-60) +#define PEN_TILT_MAX (60) + +/* Enable only when module have tp reset pin and connected to host */ +#define NVT_TOUCH_SUPPORT_HW_RST 0 + +//---Customerized func.--- +#define NVT_TOUCH_PROC 1 +#define NVT_TOUCH_EXT_PROC 1 +#define NVT_TOUCH_MP 1 +#define NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV 1 +#define MT_PROTOCOL_B 1 +#define WAKEUP_GESTURE 1 +#define FUNCPAGE_PALM 4 +#define PACKET_PALM_ON 3 +#define PACKET_PALM_OFF 4 + +#if WAKEUP_GESTURE +extern const uint16_t gesture_key_array[]; +#endif +#define BOOT_UPDATE_FIRMWARE 1 +#define DEFAULT_BOOT_UPDATE_FIRMWARE_NAME "novatek_ts_fw.bin" +#define DEFAULT_MP_UPDATE_FIRMWARE_NAME "novatek_ts_mp.bin" +#define DEFAULT_DEBUG_FW_NAME "novatek_debug_fw.bin" +#define DEFAULT_DEBUG_MP_NAME "novatek_debug_mp.bin" +#define POINT_DATA_CHECKSUM 1 +#define POINT_DATA_CHECKSUM_LEN 65 +#define CHECK_PEN_DATA_CHECKSUM 0 + +//---ESD Protect.--- +#define NVT_TOUCH_ESD_PROTECT 1 +#define NVT_TOUCH_ESD_CHECK_PERIOD 1500 /* ms */ +#define NVT_TOUCH_WDT_RECOVERY 1 + +enum nvt_ic_state { + NVT_IC_SUSPEND_IN, + NVT_IC_SUSPEND_OUT, + NVT_IC_RESUME_IN, + NVT_IC_RESUME_OUT, + NVT_IC_INIT, +}; + +struct nvt_config_info { + u8 tp_vendor; + u8 tp_color; + u8 display_maker; + u8 glass_vendor; + const char *nvt_fw_name; + const char *nvt_mp_name; + const char *nvt_limit_name; +}; + +struct nvt_ts_data { + struct spi_device *client; + struct input_dev *input_dev; + struct delayed_work nvt_fwu_work; + struct delayed_work nvt_lockdown_work; + struct work_struct switch_mode_work; + struct work_struct pen_charge_state_change_work; + bool pen_is_charge; + struct notifier_block pen_charge_state_notifier; + uint16_t addr; + int8_t phys[32]; +#if defined(CONFIG_FB) +#ifdef CONFIG_DRM + struct notifier_block drm_notif; +#else + struct notifier_block fb_notif; +#endif +#elif defined(CONFIG_HAS_EARLYSUSPEND) + struct early_suspend early_suspend; +#endif + uint32_t config_array_size; + struct nvt_config_info *config_array; + const u8 *fw_name; + const u8 *mp_name; + bool lkdown_readed; + u8 lockdown_info[NVT_LOCKDOWN_SIZE]; + uint8_t fw_ver; + uint8_t x_num; + uint8_t y_num; + int ic_state; + uint16_t abs_x_max; + uint16_t abs_y_max; + uint8_t max_touch_num; + uint8_t max_button_num; + uint32_t int_trigger_type; +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + u32 gamemode_config[3][5]; + struct workqueue_struct *set_touchfeature_wq; + struct work_struct set_touchfeature_work; +#endif + int32_t irq_gpio; + uint32_t irq_flags; + int32_t reset_gpio; + uint32_t reset_flags; + struct mutex lock; + const struct nvt_ts_mem_map *mmap; + uint8_t carrier_system; + uint8_t hw_crc; + uint16_t nvt_pid; + uint8_t *rbuf; + uint8_t *xbuf; + struct mutex xbuf_lock; + bool irq_enabled; + uint8_t cascade; + bool pen_support; + bool wgp_stylus; + uint8_t x_gang_num; + uint8_t y_gang_num; + struct input_dev *pen_input_dev; + bool pen_input_dev_enable; + int8_t pen_phys[32]; + struct workqueue_struct *event_wq; + struct work_struct suspend_work; + struct work_struct resume_work; + struct attribute_group *attrs; + int result_type; + int panel_index; + uint32_t spi_max_freq; + int db_wakeup; +#ifdef CONFIG_MTK_SPI + struct mt_chip_conf spi_ctrl; +#endif +#ifdef CONFIG_SPI_MT65XX + struct mtk_chip_config spi_ctrl; +#endif +#ifdef CONFIG_TOUCHSCREEN_NVT_DEBUG_FS + struct dentry *debugfs; +#endif + uint8_t debug_flag; + bool fw_debug; + bool dev_pm_suspend; + struct completion dev_pm_suspend_completion; + bool palm_sensor_switch; + int gesture_command_delayed; + struct pinctrl *ts_pinctrl; + struct pinctrl_state *pinctrl_state_active; + struct pinctrl_state *pinctrl_state_suspend; +#ifndef NVT_SAVE_TESTDATA_IN_FILE + void *testdata; +#endif +}; + +#if NVT_TOUCH_PROC +struct nvt_flash_data { + rwlock_t lock; +}; +#endif + +typedef enum { + RESET_STATE_INIT = 0xA0, // IC reset + RESET_STATE_REK, // ReK baseline + RESET_STATE_REK_FINISH, // baseline is ready + RESET_STATE_NORMAL_RUN, // normal run + RESET_STATE_MAX = 0xAF +} RST_COMPLETE_STATE; + +typedef enum { + EVENT_MAP_HOST_CMD = 0x50, + EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE = 0x51, + EVENT_MAP_RESET_COMPLETE = 0x60, + EVENT_MAP_FWINFO = 0x78, + EVENT_MAP_PROJECTID = 0x9A, +} SPI_EVENT_MAP; + +//---SPI READ/WRITE--- +#define SPI_WRITE_MASK(a) (a | 0x80) +#define SPI_READ_MASK(a) (a & 0x7F) + +#define DUMMY_BYTES (1) +#define NVT_TRANSFER_LEN (63 * 1024) +#define NVT_READ_LEN (2 * 1024) + +typedef enum { NVTWRITE = 0, NVTREAD = 1 } NVT_SPI_RW; + +//---extern structures--- +extern struct nvt_ts_data *ts; + +//---extern functions--- +int32_t CTP_SPI_READ(struct spi_device *client, uint8_t *buf, uint16_t len); +int32_t CTP_SPI_WRITE(struct spi_device *client, uint8_t *buf, uint16_t len); +void nvt_bootloader_reset(void); +void nvt_eng_reset(void); +void nvt_sw_reset(void); +void nvt_sw_reset_idle(void); +void nvt_boot_ready(void); +void nvt_bld_crc_enable(void); +void nvt_fw_crc_enable(void); +void nvt_tx_auto_copy_mode(void); +void nvt_set_dbgfw_status(bool enable); +void nvt_match_fw(void); +int32_t nvt_update_firmware(const char *firmware_name); +int32_t nvt_check_fw_reset_state(RST_COMPLETE_STATE check_reset_state); +int32_t nvt_get_fw_info(void); +int32_t nvt_clear_fw_status(void); +int32_t nvt_check_fw_status(void); +int32_t nvt_check_spi_dma_tx_info(void); +int32_t nvt_set_page(uint32_t addr); +int32_t nvt_write_addr(uint32_t addr, uint8_t data); +bool nvt_get_dbgfw_status(void); +int32_t nvt_set_pocket_palm_switch(uint8_t pocket_palm_switch); +#if NVT_TOUCH_ESD_PROTECT +extern void nvt_esd_check_enable(uint8_t enable); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + +#endif /* _LINUX_NVT_TOUCH_H */ diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_ext_proc.c b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_ext_proc.c new file mode 100644 index 000000000000..5fe90c63a0dd --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_ext_proc.c @@ -0,0 +1,2639 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * $Revision: 57674 $ + * $Date: 2020-03-02 11:16:20 +0800 (週一, 02 三月 2020) $ + * + * 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. + * + */ + +#include +#include + +#include "nt36xxx.h" + +#if NVT_TOUCH_EXT_PROC +#define NVT_FW_VERSION "nvt_fw_version" +#define NVT_BASELINE "nvt_baseline" +#define NVT_RAW "nvt_raw" +#define NVT_DIFF "nvt_diff" +#define NVT_PEN_DIFF "nvt_pen_diff" +#define NVT_PF_SWITCH "nvt_pf_switch" +#define NVT_SENSITIVITY_SWITCH "nvt_sensitivity_switch" +#define NVT_ER_RANGE_SWITCH "nvt_er_range_switch" +#define NVT_EDGE_REJECT_SWITCH "nvt_edge_reject_switch" +#define NVT_HAND_ONLY_SWITCH "nvt_hand_only_switch" +#define NVT_DRAG_LATENCY_SWITCH "nvt_drag_latency_switch" +#define NVT_SMALL_JITTER_SWITCH "nvt_small_jitter_switch" +#define NVT_GAME_MODE_SWITCH "nvt_game_mode_switch" +#define NVT_XIAOMI_LOCKDOWN_INFO "tp_lockdown_info" + +#define BUS_TRANSFER_LENGTH 256 + +#define NORMAL_MODE 0x00 +#define TEST_MODE_1 0x21 +#define TEST_MODE_2 0x22 +#define HANDSHAKING_HOST_READY 0xBB + +#define XDATA_SECTOR_SIZE 256 + +static uint8_t xdata_tmp[5000] = { 0 }; +static int32_t xdata[2500] = { 0 }; +static int32_t xdata_pen_tip_x[256] = { 0 }; +static int32_t xdata_pen_tip_y[256] = { 0 }; +static int32_t xdata_pen_ring_x[256] = { 0 }; +static int32_t xdata_pen_ring_y[256] = { 0 }; + +static struct proc_dir_entry *NVT_proc_fw_version_entry; +static struct proc_dir_entry *NVT_proc_baseline_entry; +static struct proc_dir_entry *NVT_proc_raw_entry; +static struct proc_dir_entry *NVT_proc_diff_entry; +static struct proc_dir_entry *NVT_proc_pen_diff_entry; +static struct proc_dir_entry *NVT_proc_pf_switch_entry; +static struct proc_dir_entry *NVT_proc_sensitivity_switch_entry; +static struct proc_dir_entry *NVT_proc_er_range_switch_entry; +static struct proc_dir_entry *NVT_proc_edge_reject_switch_entry; +static struct proc_dir_entry *NVT_proc_hand_only_switch_entry; +static struct proc_dir_entry *NVT_proc_drag_latency_switch_entry; +static struct proc_dir_entry *NVT_proc_small_jitter_switch_entry; +static struct proc_dir_entry *NVT_proc_xiaomi_lockdown_info_entry; +static struct proc_dir_entry *NVT_proc_game_mode_switch_entry; + +/******************************************************* +Description: + Novatek touchscreen change mode function. + +return: + n.a. +*******************************************************/ +void nvt_change_mode(uint8_t mode) +{ + uint8_t buf[8] = { 0 }; + + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + //---set mode--- + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = mode; + CTP_SPI_WRITE(ts->client, buf, 2); + + if (mode == NORMAL_MODE) { + buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; + buf[1] = HANDSHAKING_HOST_READY; + CTP_SPI_WRITE(ts->client, buf, 2); + msleep(20); + } +} + +int32_t nvt_set_pen_inband_mode_1(uint8_t freq_idx, uint8_t x_term) +{ + uint8_t buf[8] = { 0 }; + int32_t i = 0; + const int32_t retry = 5; + + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + //---set mode--- + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0xC1; + buf[2] = 0x02; + buf[3] = freq_idx; + buf[4] = x_term; + CTP_SPI_WRITE(ts->client, buf, 5); + + for (i = 0; i < retry; i++) { + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0xFF; + CTP_SPI_READ(ts->client, buf, 2); + + if (buf[1] == 0x00) + break; + + usleep_range(10000, 10000); + } + + if (i >= retry) { + NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]); + return -1; + } else { + return 0; + } +} + +int32_t nvt_set_pen_normal_mode(void) +{ + uint8_t buf[8] = { 0 }; + int32_t i = 0; + const int32_t retry = 5; + + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + //---set mode--- + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0xC1; + buf[2] = 0x04; + CTP_SPI_WRITE(ts->client, buf, 3); + + for (i = 0; i < retry; i++) { + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0xFF; + CTP_SPI_READ(ts->client, buf, 2); + + if (buf[1] == 0x00) + break; + + usleep_range(10000, 10000); + } + + if (i >= retry) { + NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]); + return -1; + } else { + return 0; + } +} + +/******************************************************* +Description: + Novatek touchscreen get firmware pipe function. + +return: + Executive outcomes. 0---pipe 0. 1---pipe 1. +*******************************************************/ +uint8_t nvt_get_fw_pipe(void) +{ + uint8_t buf[8] = { 0 }; + + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | + EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE); + + //---read fw status--- + buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; + buf[1] = 0x00; + CTP_SPI_READ(ts->client, buf, 2); + + //NVT_LOG("FW pipe=%d, buf[1]=0x%02X\n", (buf[1]&0x01), buf[1]); + + return (buf[1] & 0x01); +} + +/******************************************************* +Description: + Novatek touchscreen read meta data function. + +return: + n.a. +*******************************************************/ +void nvt_read_mdata(uint32_t xdata_addr, uint32_t xdata_btn_addr) +{ + int32_t i = 0; + int32_t j = 0; + int32_t k = 0; + uint8_t buf[BUS_TRANSFER_LENGTH + 2] = { 0 }; + uint32_t head_addr = 0; + int32_t dummy_len = 0; + int32_t data_len = 0; + int32_t residual_len = 0; + + //---set xdata sector address & length--- + head_addr = xdata_addr - (xdata_addr % XDATA_SECTOR_SIZE); + dummy_len = xdata_addr - head_addr; + data_len = ts->x_num * ts->y_num * 2; + residual_len = (head_addr + dummy_len + data_len) % XDATA_SECTOR_SIZE; + + //printk("head_addr=0x%05X, dummy_len=0x%05X, data_len=0x%05X, residual_len=0x%05X\n", head_addr, dummy_len, data_len, residual_len); + + //read xdata : step 1 + for (i = 0; i < ((dummy_len + data_len) / XDATA_SECTOR_SIZE); i++) { + //---change xdata index--- + nvt_set_page(head_addr + XDATA_SECTOR_SIZE * i); + + //---read xdata by BUS_TRANSFER_LENGTH + for (j = 0; j < (XDATA_SECTOR_SIZE / BUS_TRANSFER_LENGTH); + j++) { + //---read data--- + buf[0] = BUS_TRANSFER_LENGTH * j; + CTP_SPI_READ(ts->client, buf, BUS_TRANSFER_LENGTH + 1); + + //---copy buf to xdata_tmp--- + for (k = 0; k < BUS_TRANSFER_LENGTH; k++) { + xdata_tmp[XDATA_SECTOR_SIZE * i + + BUS_TRANSFER_LENGTH * j + k] = + buf[k + 1]; + //printk("0x%02X, 0x%04X\n", buf[k+1], (XDATA_SECTOR_SIZE*i + BUS_TRANSFER_LENGTH*j + k)); + } + } + //printk("addr=0x%05X\n", (head_addr+XDATA_SECTOR_SIZE*i)); + } + + //read xdata : step2 + if (residual_len != 0) { + //---change xdata index--- + nvt_set_page(xdata_addr + data_len - residual_len); + + //---read xdata by BUS_TRANSFER_LENGTH + for (j = 0; j < (residual_len / BUS_TRANSFER_LENGTH + 1); j++) { + //---read data--- + buf[0] = BUS_TRANSFER_LENGTH * j; + CTP_SPI_READ(ts->client, buf, BUS_TRANSFER_LENGTH + 1); + + //---copy buf to xdata_tmp--- + for (k = 0; k < BUS_TRANSFER_LENGTH; k++) { + xdata_tmp[(dummy_len + data_len - residual_len) + + BUS_TRANSFER_LENGTH * j + k] = + buf[k + 1]; + //printk("0x%02X, 0x%04x\n", buf[k+1], ((dummy_len+data_len-residual_len) + BUS_TRANSFER_LENGTH*j + k)); + } + } + //printk("addr=0x%05X\n", (xdata_addr+data_len-residual_len)); + } + + //---remove dummy data and 2bytes-to-1data--- + for (i = 0; i < (data_len / 2); i++) { + xdata[i] = (int16_t)(xdata_tmp[dummy_len + i * 2] + + 256 * xdata_tmp[dummy_len + i * 2 + 1]); + } + +#if TOUCH_KEY_NUM > 0 + //read button xdata : step3 + //---change xdata index--- + nvt_set_page(xdata_btn_addr); + + //---read data--- + buf[0] = (xdata_btn_addr & 0xFF); + CTP_SPI_READ(ts->client, buf, (TOUCH_KEY_NUM * 2 + 1)); + + //---2bytes-to-1data--- + for (i = 0; i < TOUCH_KEY_NUM; i++) { + xdata[ts->x_num * ts->y_num + i] = + (int16_t)(buf[1 + i * 2] + 256 * buf[1 + i * 2 + 1]); + } +#endif + + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR); +} + +/******************************************************* +Description: + Novatek touchscreen get meta data function. + +return: + n.a. +*******************************************************/ +void nvt_get_mdata(int32_t *buf, uint8_t *m_x_num, uint8_t *m_y_num) +{ + *m_x_num = ts->x_num; + *m_y_num = ts->y_num; + memcpy(buf, xdata, + ((ts->x_num * ts->y_num + TOUCH_KEY_NUM) * sizeof(int32_t))); +} + +/******************************************************* +Description: + Novatek touchscreen read and get number of meta data function. + +return: + n.a. +*******************************************************/ +void nvt_read_get_num_mdata(uint32_t xdata_addr, int32_t *buffer, uint32_t num) +{ + int32_t i = 0; + int32_t j = 0; + int32_t k = 0; + uint8_t buf[BUS_TRANSFER_LENGTH + 2] = { 0 }; + uint32_t head_addr = 0; + int32_t dummy_len = 0; + int32_t data_len = 0; + int32_t residual_len = 0; + + //---set xdata sector address & length--- + head_addr = xdata_addr - (xdata_addr % XDATA_SECTOR_SIZE); + dummy_len = xdata_addr - head_addr; + data_len = num * 2; + residual_len = (head_addr + dummy_len + data_len) % XDATA_SECTOR_SIZE; + + //printk("head_addr=0x%05X, dummy_len=0x%05X, data_len=0x%05X, residual_len=0x%05X\n", head_addr, dummy_len, data_len, residual_len); + + //read xdata : step 1 + for (i = 0; i < ((dummy_len + data_len) / XDATA_SECTOR_SIZE); i++) { + //---change xdata index--- + nvt_set_page(head_addr + XDATA_SECTOR_SIZE * i); + + //---read xdata by BUS_TRANSFER_LENGTH + for (j = 0; j < (XDATA_SECTOR_SIZE / BUS_TRANSFER_LENGTH); + j++) { + //---read data--- + buf[0] = BUS_TRANSFER_LENGTH * j; + CTP_SPI_READ(ts->client, buf, BUS_TRANSFER_LENGTH + 1); + + //---copy buf to xdata_tmp--- + for (k = 0; k < BUS_TRANSFER_LENGTH; k++) { + xdata_tmp[XDATA_SECTOR_SIZE * i + + BUS_TRANSFER_LENGTH * j + k] = + buf[k + 1]; + //printk("0x%02X, 0x%04X\n", buf[k+1], (XDATA_SECTOR_SIZE*i + BUS_TRANSFER_LENGTH*j + k)); + } + } + //printk("addr=0x%05X\n", (head_addr+XDATA_SECTOR_SIZE*i)); + } + + //read xdata : step2 + if (residual_len != 0) { + //---change xdata index--- + nvt_set_page(xdata_addr + data_len - residual_len); + + //---read xdata by BUS_TRANSFER_LENGTH + for (j = 0; j < (residual_len / BUS_TRANSFER_LENGTH + 1); j++) { + //---read data--- + buf[0] = BUS_TRANSFER_LENGTH * j; + CTP_SPI_READ(ts->client, buf, BUS_TRANSFER_LENGTH + 1); + + //---copy buf to xdata_tmp--- + for (k = 0; k < BUS_TRANSFER_LENGTH; k++) { + xdata_tmp[(dummy_len + data_len - residual_len) + + BUS_TRANSFER_LENGTH * j + k] = + buf[k + 1]; + //printk("0x%02X, 0x%04x\n", buf[k+1], ((dummy_len+data_len-residual_len) + BUS_TRANSFER_LENGTH*j + k)); + } + } + //printk("addr=0x%05X\n", (xdata_addr+data_len-residual_len)); + } + + //---remove dummy data and 2bytes-to-1data--- + for (i = 0; i < (data_len / 2); i++) { + buffer[i] = (int16_t)(xdata_tmp[dummy_len + i * 2] + + 256 * xdata_tmp[dummy_len + i * 2 + 1]); + } + + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR); +} + +/******************************************************* +Description: + Novatek touchscreen firmware version show function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t c_fw_version_show(struct seq_file *m, void *v) +{ + seq_printf(m, "fw_ver=%d, x_num=%d, y_num=%d, button_num=%d\n", + ts->fw_ver, ts->x_num, ts->y_num, ts->max_button_num); + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen xdata sequence print show + function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t c_show(struct seq_file *m, void *v) +{ + int32_t i = 0; + int32_t j = 0; + + for (i = 0; i < ts->y_num; i++) { + for (j = 0; j < ts->x_num; j++) { + seq_printf(m, "%5d, ", xdata[i * ts->x_num + j]); + } + seq_puts(m, "\n"); + } + +#if TOUCH_KEY_NUM > 0 + for (i = 0; i < TOUCH_KEY_NUM; i++) { + seq_printf(m, "%5d, ", xdata[ts->x_num * ts->y_num + i]); + } + seq_puts(m, "\n"); +#endif + + seq_printf(m, "\n\n"); + return 0; +} + +/******************************************************* +Description: + Novatek pen 1D diff xdata sequence print show + function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t c_pen_1d_diff_show(struct seq_file *m, void *v) +{ + int32_t i = 0; + + seq_printf(m, "Tip X:\n"); + for (i = 0; i < ts->x_num; i++) { + seq_printf(m, "%5d, ", xdata_pen_tip_x[i]); + } + seq_puts(m, "\n"); + seq_printf(m, "Tip Y:\n"); + for (i = 0; i < ts->y_num; i++) { + seq_printf(m, "%5d, ", xdata_pen_tip_y[i]); + } + seq_puts(m, "\n"); + seq_printf(m, "Ring X:\n"); + for (i = 0; i < ts->x_num; i++) { + seq_printf(m, "%5d, ", xdata_pen_ring_x[i]); + } + seq_puts(m, "\n"); + seq_printf(m, "Ring Y:\n"); + for (i = 0; i < ts->y_num; i++) { + seq_printf(m, "%5d, ", xdata_pen_ring_y[i]); + } + seq_puts(m, "\n"); + + seq_printf(m, "\n\n"); + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen xdata sequence print start + function. + +return: + Executive outcomes. 1---call next function. + NULL---not call next function and sequence loop + stop. +*******************************************************/ +static void *c_start(struct seq_file *m, loff_t *pos) +{ + return *pos < 1 ? (void *)1 : NULL; +} + +/******************************************************* +Description: + Novatek touchscreen xdata sequence print next + function. + +return: + Executive outcomes. NULL---no next and call sequence + stop function. +*******************************************************/ +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return NULL; +} + +/******************************************************* +Description: + Novatek touchscreen xdata sequence print stop + function. + +return: + n.a. +*******************************************************/ +static void c_stop(struct seq_file *m, void *v) +{ + return; +} + +const struct seq_operations nvt_fw_version_seq_ops = { + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = c_fw_version_show +}; + +const struct seq_operations nvt_seq_ops = { .start = c_start, + .next = c_next, + .stop = c_stop, + .show = c_show }; + +const struct seq_operations nvt_pen_diff_seq_ops = { + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = c_pen_1d_diff_show +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_fw_version open + function. + +return: + n.a. +*******************************************************/ +static int32_t nvt_fw_version_open(struct inode *inode, struct file *file) +{ + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + + NVT_LOG("++\n"); + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + mutex_unlock(&ts->lock); + + NVT_LOG("--\n"); + + return seq_open(file, &nvt_fw_version_seq_ops); +} + +static const struct file_operations nvt_fw_version_fops = { + .owner = THIS_MODULE, + .open = nvt_fw_version_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_baseline open function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t nvt_baseline_open(struct inode *inode, struct file *file) +{ + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + + NVT_LOG("++\n"); + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + if (nvt_clear_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + nvt_change_mode(TEST_MODE_2); + + if (nvt_check_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + nvt_read_mdata(ts->mmap->BASELINE_ADDR, ts->mmap->BASELINE_BTN_ADDR); + + nvt_change_mode(NORMAL_MODE); + + mutex_unlock(&ts->lock); + + NVT_LOG("--\n"); + + return seq_open(file, &nvt_seq_ops); +} + +static const struct file_operations nvt_baseline_fops = { + .owner = THIS_MODULE, + .open = nvt_baseline_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_raw open function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t nvt_raw_open(struct inode *inode, struct file *file) +{ + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + + NVT_LOG("++\n"); + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + if (nvt_clear_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + nvt_change_mode(TEST_MODE_2); + + if (nvt_check_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + if (nvt_get_fw_pipe() == 0) + nvt_read_mdata(ts->mmap->RAW_PIPE0_ADDR, + ts->mmap->RAW_BTN_PIPE0_ADDR); + else + nvt_read_mdata(ts->mmap->RAW_PIPE1_ADDR, + ts->mmap->RAW_BTN_PIPE1_ADDR); + + nvt_change_mode(NORMAL_MODE); + + mutex_unlock(&ts->lock); + + NVT_LOG("--\n"); + + return seq_open(file, &nvt_seq_ops); +} + +static const struct file_operations nvt_raw_fops = { + .owner = THIS_MODULE, + .open = nvt_raw_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_diff open function. + +return: + Executive outcomes. 0---succeed. negative---failed. +*******************************************************/ +static int32_t nvt_diff_open(struct inode *inode, struct file *file) +{ + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + + NVT_LOG("++\n"); + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + if (nvt_clear_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + nvt_change_mode(TEST_MODE_2); + + if (nvt_check_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + if (nvt_get_fw_pipe() == 0) + nvt_read_mdata(ts->mmap->DIFF_PIPE0_ADDR, + ts->mmap->DIFF_BTN_PIPE0_ADDR); + else + nvt_read_mdata(ts->mmap->DIFF_PIPE1_ADDR, + ts->mmap->DIFF_BTN_PIPE1_ADDR); + + nvt_change_mode(NORMAL_MODE); + + mutex_unlock(&ts->lock); + + NVT_LOG("--\n"); + + return seq_open(file, &nvt_seq_ops); +} + +static const struct file_operations nvt_diff_fops = { + .owner = THIS_MODULE, + .open = nvt_diff_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_pen_diff open function. + +return: + Executive outcomes. 0---succeed. negative---failed. +*******************************************************/ +static int32_t nvt_pen_diff_open(struct inode *inode, struct file *file) +{ + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + + NVT_LOG("++\n"); + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + if (nvt_set_pen_inband_mode_1(0xFF, 0x00)) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + if (nvt_check_fw_reset_state(RESET_STATE_NORMAL_RUN)) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + if (nvt_clear_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + nvt_change_mode(TEST_MODE_2); + + if (nvt_check_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + nvt_read_get_num_mdata(ts->mmap->PEN_1D_DIFF_TIP_X_ADDR, + xdata_pen_tip_x, ts->x_num); + nvt_read_get_num_mdata(ts->mmap->PEN_1D_DIFF_TIP_Y_ADDR, + xdata_pen_tip_y, ts->y_num); + nvt_read_get_num_mdata(ts->mmap->PEN_1D_DIFF_RING_X_ADDR, + xdata_pen_ring_x, ts->x_num); + nvt_read_get_num_mdata(ts->mmap->PEN_1D_DIFF_RING_Y_ADDR, + xdata_pen_ring_y, ts->y_num); + + nvt_change_mode(NORMAL_MODE); + + nvt_set_pen_normal_mode(); + + nvt_check_fw_reset_state(RESET_STATE_NORMAL_RUN); + + mutex_unlock(&ts->lock); + + NVT_LOG("--\n"); + + return seq_open(file, &nvt_pen_diff_seq_ops); +} + +static const struct file_operations nvt_pen_diff_fops = { + .owner = THIS_MODULE, + .open = nvt_pen_diff_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int nvt_xiaomi_lockdown_info_show(struct seq_file *m, void *v) +{ + u8 *lk = ts->lockdown_info; + + seq_printf(m, + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", + lk[0], lk[1], lk[2], lk[3], lk[4], lk[5], lk[6], lk[7]); + return 0; +} + +static int32_t nvt_xiaomi_lockdown_info_open(struct inode *inode, + struct file *file) +{ + return single_open(file, nvt_xiaomi_lockdown_info_show, NULL); +} + +static const struct file_operations nvt_xiaomi_lockdown_info_fops = { + .owner = THIS_MODULE, + .open = nvt_xiaomi_lockdown_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +int32_t nvt_set_pocket_palm_switch(uint8_t pocket_palm_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("set pocket palm switch: %d\n", pocket_palm_switch); + + msleep(35); + + /* ---set xdata index to EVENT BUF ADDR--- */ + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_set_pocket_palm_switch_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + if (pocket_palm_switch == 0) { + /* pocket palm disable */ + buf[1] = 0x74; + } else if (pocket_palm_switch == 1) { + /* pocket palm enable */ + buf[1] = 0x73; + } else { + NVT_ERR("Invalid value! pocket_palm_switch = %d\n", + pocket_palm_switch); + ret = -EINVAL; + goto nvt_set_pocket_palm_switch_out; + } + ret = CTP_SPI_WRITE(ts->client, buf, 2); + if (ret < 0) { + NVT_ERR("Write pocket palm switch command fail!\n"); + goto nvt_set_pocket_palm_switch_out; + } + +nvt_set_pocket_palm_switch_out: + NVT_LOG("%s --\n", __func__); + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_pf_switch function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +int32_t nvt_set_pf_switch(uint8_t pf_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + NVT_LOG("set pf switch: %d\n", pf_switch); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_set_pf_switch_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x70; + buf[2] = pf_switch; + ret = CTP_SPI_WRITE(ts->client, buf, 3); + if (ret < 0) { + NVT_ERR("Write pf switch command fail!\n"); + goto nvt_set_pf_switch_out; + } + +nvt_set_pf_switch_out: + NVT_LOG("--\n"); + return ret; +} + +int32_t nvt_get_pf_switch(uint8_t *pf_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + + msleep(35); + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | 0x5D); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_get_pf_switch_out; + } + + buf[0] = 0x5D; + buf[1] = 0x00; + ret = CTP_SPI_READ(ts->client, buf, 2); + if (ret < 0) { + NVT_ERR("Read pf switch status fail!\n"); + goto nvt_get_pf_switch_out; + } + + *pf_switch = (buf[1] & 0x07); + NVT_LOG("pf_switch = %d\n", *pf_switch); + +nvt_get_pf_switch_out: + NVT_LOG("--\n"); + return ret; +} + +static ssize_t nvt_pf_switch_proc_read(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + static int finished; + int32_t cnt = 0; + int32_t len = 0; + uint8_t pf_switch; + char tmp_buf[64]; + + NVT_LOG("++\n"); + + /* + * We return 0 to indicate end of file, that we have + * no more information. Otherwise, processes will + * continue to read from us in an endless loop. + */ + if (finished) { + NVT_LOG("read END\n"); + finished = 0; + return 0; + } + finished = 1; + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_get_pf_switch(&pf_switch); + + mutex_unlock(&ts->lock); + + //cnt = snprintf(buf, PAGE_SIZE - len, "pf_switch: %d\n", pf_switch); + cnt = snprintf(tmp_buf, sizeof(tmp_buf), "pf_switch: %d\n", pf_switch); + if (copy_to_user(buf, tmp_buf, sizeof(tmp_buf))) { + NVT_ERR("copy_to_user() error!\n"); + return -EFAULT; + } + buf += cnt; + len += cnt; + + NVT_LOG("--\n"); + return len; +} + +static ssize_t nvt_pf_switch_proc_write(struct file *filp, + const char __user *buf, size_t count, + loff_t *f_pos) +{ + int32_t ret; + int32_t tmp; + uint8_t pf_switch; + char *tmp_buf; + + NVT_LOG("++\n"); + + if (count == 0 || count > 2) { + NVT_ERR("Invalid value! count = %zu\n", count); + ret = -EINVAL; + goto out; + } + + tmp_buf = kzalloc((count + 1), GFP_KERNEL); + if (!tmp_buf) { + NVT_ERR("Allocate tmp_buf fail!\n"); + ret = -ENOMEM; + goto out; + } + if (copy_from_user(tmp_buf, buf, count)) { + NVT_ERR("copy_from_user() error!\n"); + ret = -EFAULT; + goto out; + } + + ret = sscanf(tmp_buf, "%d", &tmp); + if (ret != 1) { + NVT_ERR("Invalid value! ret = %d\n", ret); + ret = -EINVAL; + goto out; + } + if (tmp < 0 || tmp > 4) { + NVT_ERR("Invalid value! tmp = %d\n", tmp); + ret = -EINVAL; + goto out; + } + pf_switch = (uint8_t)tmp; + NVT_LOG("pf_switch = %d\n", pf_switch); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_set_pf_switch(pf_switch); + + mutex_unlock(&ts->lock); + + ret = count; +out: + if (tmp_buf) + kfree(tmp_buf); + NVT_LOG("--\n"); + return ret; +} + +static const struct file_operations nvt_pf_switch_fops = { + .owner = THIS_MODULE, + .read = nvt_pf_switch_proc_read, + .write = nvt_pf_switch_proc_write, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_sensitivity_switch function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +int32_t nvt_set_sensitivity_switch(uint8_t sensitivity_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + NVT_LOG("set sensitivity switch: %d\n", sensitivity_switch); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_set_sensitivity_switch_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x71; + buf[2] = sensitivity_switch; + ret = CTP_SPI_WRITE(ts->client, buf, 3); + if (ret < 0) { + NVT_ERR("Write sensitivity switch command fail!\n"); + goto nvt_set_sensitivity_switch_out; + } + +nvt_set_sensitivity_switch_out: + NVT_LOG("--\n"); + return ret; +} + +int32_t nvt_get_sensitivity_switch(uint8_t *sensitivity_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | 0x5D); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_get_sensitivity_switch_out; + } + + buf[0] = 0x5D; + buf[1] = 0x00; + ret = CTP_SPI_READ(ts->client, buf, 2); + if (ret < 0) { + NVT_ERR("Read sensitivity switch status fail!\n"); + goto nvt_get_sensitivity_switch_out; + } + + *sensitivity_switch = ((buf[1] >> 3) & 0x07); + NVT_LOG("sensitivity_switch = %d\n", *sensitivity_switch); + +nvt_get_sensitivity_switch_out: + NVT_LOG("--\n"); + return ret; +} + +static ssize_t nvt_sensitivity_switch_proc_read(struct file *filp, + char __user *buf, size_t count, + loff_t *f_pos) +{ + static int finished; + int32_t cnt = 0; + int32_t len = 0; + uint8_t sensitivity_switch; + char tmp_buf[64]; + + NVT_LOG("++\n"); + + /* + * We return 0 to indicate end of file, that we have + * no more information. Otherwise, processes will + * continue to read from us in an endless loop. + */ + if (finished) { + NVT_LOG("read END\n"); + finished = 0; + return 0; + } + finished = 1; + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_get_sensitivity_switch(&sensitivity_switch); + + mutex_unlock(&ts->lock); + + //cnt = snprintf(buf, PAGE_SIZE - len, "sensitivity_switch: %d\n", sensitivity_switch); + cnt = snprintf(tmp_buf, sizeof(tmp_buf), "sensitivity_switch: %d\n", + sensitivity_switch); + if (copy_to_user(buf, tmp_buf, sizeof(tmp_buf))) { + NVT_ERR("copy_to_user() error!\n"); + return -EFAULT; + } + buf += cnt; + len += cnt; + + NVT_LOG("--\n"); + return len; +} + +static ssize_t nvt_sensitivity_switch_proc_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *f_pos) +{ + int32_t ret; + int32_t tmp; + uint8_t sensitivity_switch; + char *tmp_buf; + + NVT_LOG("++\n"); + + if (count == 0 || count > 2) { + NVT_ERR("Invalid value! count = %zu\n", count); + ret = -EINVAL; + goto out; + } + + tmp_buf = kzalloc((count + 1), GFP_KERNEL); + if (!tmp_buf) { + NVT_ERR("Allocate tmp_buf fail!\n"); + ret = -ENOMEM; + goto out; + } + if (copy_from_user(tmp_buf, buf, count)) { + NVT_ERR("copy_from_user() error!\n"); + ret = -EFAULT; + goto out; + } + + ret = sscanf(tmp_buf, "%d", &tmp); + if (ret != 1) { + NVT_ERR("Invalid value! ret = %d\n", ret); + ret = -EINVAL; + goto out; + } + if (tmp < 0 || tmp > 4) { + NVT_ERR("Invalid value! tmp = %d\n", tmp); + ret = -EINVAL; + goto out; + } + sensitivity_switch = (uint8_t)tmp; + NVT_LOG("sensitivity_switch = %d\n", sensitivity_switch); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_set_sensitivity_switch(sensitivity_switch); + + mutex_unlock(&ts->lock); + + ret = count; +out: + if (tmp_buf) + kfree(tmp_buf); + NVT_LOG("--\n"); + return ret; +} + +static const struct file_operations nvt_sensitivity_switch_fops = { + .owner = THIS_MODULE, + .read = nvt_sensitivity_switch_proc_read, + .write = nvt_sensitivity_switch_proc_write, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_er_range_switch function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +int32_t nvt_set_er_range_switch(uint8_t er_range_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + NVT_LOG("set er range switch: %d\n", er_range_switch); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_set_er_range_switch_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x72; + buf[2] = er_range_switch; + ret = CTP_SPI_WRITE(ts->client, buf, 3); + if (ret < 0) { + NVT_ERR("Write er range switch command fail!\n"); + goto nvt_set_er_range_switch_out; + } + +nvt_set_er_range_switch_out: + NVT_LOG("--\n"); + return ret; +} + +int32_t nvt_get_er_range_switch(uint8_t *er_range_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | 0x5D); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_get_er_range_switch_out; + } + + buf[0] = 0x5D; + buf[1] = 0x00; + ret = CTP_SPI_READ(ts->client, buf, 2); + if (ret < 0) { + NVT_ERR("Read er range switch status fail!\n"); + goto nvt_get_er_range_switch_out; + } + + *er_range_switch = ((buf[1] >> 6) & 0x03); + NVT_LOG("er_range_switch = %d\n", *er_range_switch); + +nvt_get_er_range_switch_out: + NVT_LOG("--\n"); + return ret; +} + +static ssize_t nvt_er_range_switch_proc_read(struct file *filp, + char __user *buf, size_t count, + loff_t *f_pos) +{ + static int finished; + int32_t cnt = 0; + int32_t len = 0; + uint8_t er_range_switch; + char tmp_buf[64]; + + NVT_LOG("++\n"); + + /* + * We return 0 to indicate end of file, that we have + * no more information. Otherwise, processes will + * continue to read from us in an endless loop. + */ + if (finished) { + NVT_LOG("read END\n"); + finished = 0; + return 0; + } + finished = 1; + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_get_er_range_switch(&er_range_switch); + + mutex_unlock(&ts->lock); + + cnt = snprintf(tmp_buf, sizeof(tmp_buf), "er_range_switch: %d\n", + er_range_switch); + if (copy_to_user(buf, tmp_buf, sizeof(tmp_buf))) { + NVT_ERR("copy_to_user() error!\n"); + return -EFAULT; + } + buf += cnt; + len += cnt; + + NVT_LOG("--\n"); + return len; +} + +static ssize_t nvt_er_range_switch_proc_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *f_pos) +{ + int32_t ret; + int32_t tmp; + uint8_t er_range_switch; + char *tmp_buf = 0; + + NVT_LOG("++\n"); + + if (count == 0 || count > 2) { + NVT_ERR("Invalid value! count = %zu\n", count); + ret = -EINVAL; + goto out; + } + tmp_buf = kzalloc((count + 1), GFP_KERNEL); + if (!tmp_buf) { + NVT_ERR("Allocate tmp_buf fail!\n"); + ret = -ENOMEM; + goto out; + } + if (copy_from_user(tmp_buf, buf, count)) { + NVT_ERR("copy_from_user() error!\n"); + ret = -EFAULT; + goto out; + } + + ret = sscanf(tmp_buf, "%d", &tmp); + if (ret != 1) { + NVT_ERR("Invalid value! ret = %d\n", ret); + ret = -EINVAL; + goto out; + } + + if (tmp < 0 || tmp > 3) { + NVT_ERR("Invalid value! tmp = %d\n", tmp); + ret = -EINVAL; + goto out; + } + er_range_switch = (uint8_t)tmp; + NVT_LOG("er_range_switch = %d\n", er_range_switch); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_set_er_range_switch(er_range_switch); + + mutex_unlock(&ts->lock); + + ret = count; +out: + if (tmp_buf) + kfree(tmp_buf); + NVT_LOG("--\n"); + return ret; +} + +static const struct file_operations nvt_er_range_switch_fops = { + .owner = THIS_MODULE, + .read = nvt_er_range_switch_proc_read, + .write = nvt_er_range_switch_proc_write, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_edge_reject_switch function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +int32_t nvt_set_edge_reject_switch(uint8_t edge_reject_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + NVT_LOG("set edge reject switch: %d\n", edge_reject_switch); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_set_edge_reject_switch_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + if (edge_reject_switch == 1) { + // vertical + buf[1] = 0xBA; + } else if (edge_reject_switch == 2) { + // left up + buf[1] = 0xBB; + } else if (edge_reject_switch == 3) { + // righ up + buf[1] = 0xBC; + } else { + NVT_ERR("Invalid value! edge_reject_switch = %d\n", + edge_reject_switch); + ret = -EINVAL; + goto nvt_set_edge_reject_switch_out; + } + ret = CTP_SPI_WRITE(ts->client, buf, 2); + if (ret < 0) { + NVT_ERR("Write edge reject switch command fail!\n"); + goto nvt_set_edge_reject_switch_out; + } + +nvt_set_edge_reject_switch_out: + NVT_LOG("--\n"); + return ret; +} + +int32_t nvt_get_edge_reject_switch(uint8_t *edge_reject_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | 0x5C); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_get_edge_reject_switch_out; + } + + buf[0] = 0x5C; + buf[1] = 0x00; + ret = CTP_SPI_READ(ts->client, buf, 2); + if (ret < 0) { + NVT_ERR("Read edge reject switch status fail!\n"); + goto nvt_get_edge_reject_switch_out; + } + + *edge_reject_switch = ((buf[1] >> 5) & 0x03); + NVT_LOG("edge_reject_switch = %d\n", *edge_reject_switch); + +nvt_get_edge_reject_switch_out: + NVT_LOG("--\n"); + return ret; +} + +static ssize_t nvt_edge_reject_switch_proc_read(struct file *filp, + char __user *buf, size_t count, + loff_t *f_pos) +{ + static int finished; + int32_t cnt = 0; + int32_t len = 0; + uint8_t edge_reject_switch; + char tmp_buf[64]; + + NVT_LOG("++\n"); + + /* + * We return 0 to indicate end of file, that we have + * no more information. Otherwise, processes will + * continue to read from us in an endless loop. + */ + if (finished) { + NVT_LOG("read END\n"); + finished = 0; + return 0; + } + finished = 1; + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_get_edge_reject_switch(&edge_reject_switch); + + mutex_unlock(&ts->lock); + + cnt = snprintf(tmp_buf, sizeof(tmp_buf), "edge_reject_switch: %d\n", + edge_reject_switch); + if (copy_to_user(buf, tmp_buf, sizeof(tmp_buf))) { + NVT_ERR("copy_to_user() error!\n"); + return -EFAULT; + } + buf += cnt; + len += cnt; + + NVT_LOG("--\n"); + return len; +} + +static ssize_t nvt_edge_reject_switch_proc_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *f_pos) +{ + int32_t ret; + int32_t tmp; + uint8_t edge_reject_switch; + char *tmp_buf = 0; + + NVT_LOG("++\n"); + + if (count == 0 || count > 2) { + NVT_ERR("Invalid value! count = %zu\n", count); + ret = -EINVAL; + goto out; + } + + tmp_buf = kzalloc((count + 1), GFP_KERNEL); + if (!tmp_buf) { + NVT_ERR("Allocate tmp_buf fail!\n"); + ret = -ENOMEM; + goto out; + } + if (copy_from_user(tmp_buf, buf, count)) { + NVT_ERR("copy_from_user() error!\n"); + ret = -EFAULT; + goto out; + } + + ret = sscanf(tmp_buf, "%d", &tmp); + if (ret != 1) { + NVT_ERR("Invalid value! ret = %d\n", ret); + ret = -EINVAL; + goto out; + } + + if (tmp < 1 || tmp > 3) { + NVT_ERR("Invalid value! tmp = %d\n", tmp); + ret = -EINVAL; + goto out; + } + edge_reject_switch = (uint8_t)tmp; + NVT_LOG("edge_reject_switch = %d\n", edge_reject_switch); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_set_edge_reject_switch(edge_reject_switch); + + mutex_unlock(&ts->lock); + + ret = count; +out: + if (tmp_buf) + kfree(tmp_buf); + NVT_LOG("--\n"); + return ret; +} + +static const struct file_operations nvt_edge_reject_switch_fops = { + .owner = THIS_MODULE, + .read = nvt_edge_reject_switch_proc_read, + .write = nvt_edge_reject_switch_proc_write, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_hand_only_switch function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +int32_t nvt_set_hand_only_switch(uint8_t hand_only_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + NVT_LOG("set hand only switch: %d\n", hand_only_switch); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_set_hand_only_switch_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x77; + buf[2] = hand_only_switch; + ret = CTP_SPI_WRITE(ts->client, buf, 3); + if (ret < 0) { + NVT_ERR("Write hand only switch command fail!\n"); + goto nvt_set_hand_only_switch_out; + } + +nvt_set_hand_only_switch_out: + NVT_LOG("--\n"); + return ret; +} + +int32_t nvt_get_hand_only_switch(uint8_t *hand_only_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | 0x5E); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_get_hand_only_switch_out; + } + + buf[0] = 0x5E; + buf[1] = 0x00; + ret = CTP_SPI_READ(ts->client, buf, 2); + if (ret < 0) { + NVT_ERR("Read hand only switch status fail!\n"); + goto nvt_get_hand_only_switch_out; + } + + *hand_only_switch = ((buf[1] >> 2) & 0x01); + NVT_LOG("hand_only_switch = %d\n", *hand_only_switch); + +nvt_get_hand_only_switch_out: + NVT_LOG("--\n"); + return ret; +} + +static ssize_t nvt_hand_only_switch_proc_read(struct file *filp, + char __user *buf, size_t count, + loff_t *f_pos) +{ + static int finished; + int32_t cnt = 0; + int32_t len = 0; + uint8_t hand_only_switch; + char tmp_buf[64]; + + NVT_LOG("++\n"); + + /* + * We return 0 to indicate end of file, that we have + * no more information. Otherwise, processes will + * continue to read from us in an endless loop. + */ + if (finished) { + NVT_LOG("read END\n"); + finished = 0; + return 0; + } + finished = 1; + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_get_hand_only_switch(&hand_only_switch); + + mutex_unlock(&ts->lock); + + cnt = snprintf(tmp_buf, sizeof(tmp_buf), "hand_only_switch: %d\n", + hand_only_switch); + if (copy_to_user(buf, tmp_buf, sizeof(tmp_buf))) { + NVT_ERR("copy_to_user() error!\n"); + return -EFAULT; + } + buf += cnt; + len += cnt; + + NVT_LOG("--\n"); + return len; +} + +static ssize_t nvt_hand_only_switch_proc_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *f_pos) +{ + int32_t ret; + int32_t tmp; + uint8_t hand_only_switch; + char *tmp_buf; + + NVT_LOG("++\n"); + + if (count == 0 || count > 2) { + NVT_ERR("Invalid value!, count = %zu\n", count); + ret = -EINVAL; + goto out; + } + + tmp_buf = kzalloc((count + 1), GFP_KERNEL); + if (!tmp_buf) { + NVT_ERR("Allocate tmp_buf fail!\n"); + ret = -ENOMEM; + goto out; + } + if (copy_from_user(tmp_buf, buf, count)) { + NVT_ERR("copy_from_user() error!\n"); + ret = -EFAULT; + goto out; + } + ret = sscanf(tmp_buf, "%d", &tmp); + if (ret != 1) { + NVT_ERR("Invalid value!, ret = %d\n", ret); + ret = -EINVAL; + goto out; + } + if ((tmp < 0) || (tmp > 1)) { + NVT_ERR("Invalid value!, tmp = %d\n", tmp); + ret = -EINVAL; + goto out; + } + hand_only_switch = (uint8_t)tmp; + NVT_LOG("hand_only_switch = %d\n", hand_only_switch); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_set_hand_only_switch(hand_only_switch); + + mutex_unlock(&ts->lock); + + ret = count; +out: + if (tmp_buf) + kfree(tmp_buf); + NVT_LOG("--\n"); + return ret; +} + +static const struct file_operations nvt_hand_only_switch_fops = { + .owner = THIS_MODULE, + .read = nvt_hand_only_switch_proc_read, + .write = nvt_hand_only_switch_proc_write, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_drag_latency_switch function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +int32_t nvt_set_drag_latency_switch(uint8_t drag_latency_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + NVT_LOG("set drag latency switch: %d\n", drag_latency_switch); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_set_drag_latency_switch_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x78; + buf[2] = drag_latency_switch; + ret = CTP_SPI_WRITE(ts->client, buf, 3); + if (ret < 0) { + NVT_ERR("Write drag_latency switch command fail!\n"); + goto nvt_set_drag_latency_switch_out; + } + +nvt_set_drag_latency_switch_out: + NVT_LOG("--\n"); + return ret; +} + +int32_t nvt_get_drag_latency_switch(uint8_t *drag_latency_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | 0x5E); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_get_drag_latency_switch_out; + } + + buf[0] = 0x5E; + buf[1] = 0x00; + ret = CTP_SPI_READ(ts->client, buf, 2); + if (ret < 0) { + NVT_ERR("Read drag_latency switch status fail!\n"); + goto nvt_get_drag_latency_switch_out; + } + + *drag_latency_switch = ((buf[1] >> 3) & 0x07); + NVT_LOG("drag_latency_switch = %d\n", *drag_latency_switch); + +nvt_get_drag_latency_switch_out: + NVT_LOG("--\n"); + return ret; +} + +static ssize_t nvt_drag_latency_switch_proc_read(struct file *filp, + char __user *buf, size_t count, + loff_t *f_pos) +{ + static int finished; + int32_t cnt = 0; + int32_t len = 0; + uint8_t drag_latency_switch; + char tmp_buf[64]; + + NVT_LOG("++\n"); + + /* + * We return 0 to indicate end of file, that we have + * no more information. Otherwise, processes will + * continue to read from us in an endless loop. + */ + if (finished) { + NVT_LOG("read END\n"); + finished = 0; + return 0; + } + finished = 1; + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_get_drag_latency_switch(&drag_latency_switch); + + mutex_unlock(&ts->lock); + + cnt = snprintf(tmp_buf, sizeof(tmp_buf), "drag_latency_switch: %d\n", + drag_latency_switch); + if (copy_to_user(buf, tmp_buf, sizeof(tmp_buf))) { + NVT_ERR("copy_to_user() error!\n"); + return -EFAULT; + } + buf += cnt; + len += cnt; + + NVT_LOG("--\n"); + return len; +} + +static ssize_t nvt_drag_latency_switch_proc_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *f_pos) +{ + int32_t ret; + int32_t tmp; + uint8_t drag_latency_switch; + char *tmp_buf; + + NVT_LOG("++\n"); + + if (count == 0 || count > 2) { + NVT_ERR("Invalid value! count = %zu\n", count); + ret = -EINVAL; + goto out; + } + + tmp_buf = kzalloc((count + 1), GFP_KERNEL); + if (!tmp_buf) { + NVT_ERR("Allocate tmp_buf fail!\n"); + ret = -ENOMEM; + goto out; + } + if (copy_from_user(tmp_buf, buf, count)) { + NVT_ERR("copy_from_user() error!\n"); + ret = -EFAULT; + goto out; + } + + ret = sscanf(tmp_buf, "%d", &tmp); + if (ret != 1) { + NVT_ERR("Invalid value! ret = %d\n", ret); + ret = -EINVAL; + goto out; + } + if (tmp < 0 || tmp > 4) { + NVT_ERR("Invalid value! tmp = %d\n", tmp); + ret = -EINVAL; + goto out; + } + drag_latency_switch = (uint8_t)tmp; + NVT_LOG("drag_latency_switch = %d\n", drag_latency_switch); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_set_drag_latency_switch(drag_latency_switch); + + mutex_unlock(&ts->lock); + + ret = count; +out: + if (tmp_buf) + kfree(tmp_buf); + NVT_LOG("--\n"); + return ret; +} + +static const struct file_operations nvt_drag_latency_switch_fops = { + .owner = THIS_MODULE, + .read = nvt_drag_latency_switch_proc_read, + .write = nvt_drag_latency_switch_proc_write, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_small_jitter_switch function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +int32_t nvt_set_small_jitter_switch(uint8_t small_jitter_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + NVT_LOG("set small jitter switch: %d\n", small_jitter_switch); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_set_small_jitter_switch_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x79; + buf[2] = small_jitter_switch; + ret = CTP_SPI_WRITE(ts->client, buf, 3); + if (ret < 0) { + NVT_ERR("Write small jitter switch command fail!\n"); + goto nvt_set_small_jitter_switch_out; + } + +nvt_set_small_jitter_switch_out: + NVT_LOG("--\n"); + return ret; +} + +int32_t nvt_get_small_jitter_switch(uint8_t *small_jitter_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | 0x5E); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_get_small_jitter_switch_out; + } + + buf[0] = 0x5E; + buf[1] = 0x00; + buf[2] = 0x00; + ret = CTP_SPI_READ(ts->client, buf, 3); + if (ret < 0) { + NVT_ERR("Read small jitter switch status fail!\n"); + goto nvt_get_small_jitter_switch_out; + } + + *small_jitter_switch = + (((buf[2] & 0x01) << 2) | ((buf[1] >> 6) & 0x03)); + NVT_LOG("small_jitter_switch = %d\n", *small_jitter_switch); + +nvt_get_small_jitter_switch_out: + NVT_LOG("--\n"); + return ret; +} + +static ssize_t nvt_small_jitter_switch_proc_read(struct file *filp, + char __user *buf, size_t count, + loff_t *f_pos) +{ + static int finished; + int32_t cnt = 0; + int32_t len = 0; + uint8_t small_jitter_switch; + char tmp_buf[64]; + + NVT_LOG("++\n"); + + /* + * We return 0 to indicate end of file, that we have + * no more information. Otherwise, processes will + * continue to read from us in an endless loop. + */ + if (finished) { + NVT_LOG("read END\n"); + finished = 0; + return 0; + } + finished = 1; + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_get_small_jitter_switch(&small_jitter_switch); + + mutex_unlock(&ts->lock); + + cnt = snprintf(tmp_buf, sizeof(tmp_buf), "small_jitter_switch: %d\n", + small_jitter_switch); + if (copy_to_user(buf, tmp_buf, sizeof(tmp_buf))) { + NVT_ERR("copy_to_user() error!\n"); + return -EFAULT; + } + buf += cnt; + len += cnt; + + NVT_LOG("--\n"); + return len; +} + +static ssize_t nvt_small_jitter_switch_proc_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *f_pos) +{ + int32_t ret; + int32_t tmp; + uint8_t small_jitter_switch; + char *tmp_buf; + + NVT_LOG("++\n"); + + if (count == 0 || count > 2) { + NVT_ERR("Invalid value! count = %zu\n", count); + ret = -EINVAL; + goto out; + } + + tmp_buf = kzalloc((count + 1), GFP_KERNEL); + if (!tmp_buf) { + NVT_ERR("Allocate tmp_buf fail!\n"); + ret = -ENOMEM; + goto out; + } + if (copy_from_user(tmp_buf, buf, count)) { + NVT_ERR("copy_from_user() error!\n"); + ret = -EFAULT; + goto out; + } + + ret = sscanf(tmp_buf, "%d", &tmp); + if (ret != 1) { + NVT_ERR("Invalid value! ret = %d\n", ret); + ret = -EINVAL; + goto out; + } + if (tmp < 0 || tmp > 4) { + NVT_ERR("Invalid value! tmp = %d\n", tmp); + ret = -EINVAL; + goto out; + } + small_jitter_switch = (uint8_t)tmp; + NVT_LOG("small_jitter_switch = %d\n", small_jitter_switch); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_set_small_jitter_switch(small_jitter_switch); + + mutex_unlock(&ts->lock); + + ret = count; +out: + if (tmp_buf) + kfree(tmp_buf); + NVT_LOG("--\n"); + return ret; +} + +static const struct file_operations nvt_small_jitter_switch_fops = { + .owner = THIS_MODULE, + .read = nvt_small_jitter_switch_proc_read, + .write = nvt_small_jitter_switch_proc_write, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_game_mode_switch function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +int32_t nvt_set_game_mode_switch(uint8_t game_mode_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + NVT_LOG("set game mode switch: %d\n", game_mode_switch); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_set_game_mode_switch_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x7A; + buf[2] = game_mode_switch; + ret = CTP_SPI_WRITE(ts->client, buf, 3); + if (ret < 0) { + NVT_ERR("Write game mode switch command fail!\n"); + goto nvt_set_game_mode_switch_out; + } + +nvt_set_game_mode_switch_out: + NVT_LOG("--\n"); + return ret; +} + +int32_t nvt_get_game_mode_switch(uint8_t *game_mode_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + + msleep(35); + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | 0x5F); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_get_game_mode_switch_out; + } + + buf[0] = 0x5F; + buf[1] = 0x00; + ret = CTP_SPI_READ(ts->client, buf, 2); + if (ret < 0) { + NVT_ERR("Read game mode switch status fail!\n"); + goto nvt_get_game_mode_switch_out; + } + + *game_mode_switch = ((buf[1] >> 1) & 0x01); + NVT_LOG("game_mode_switch = %d\n", *game_mode_switch); + +nvt_get_game_mode_switch_out: + NVT_LOG("--\n"); + return ret; +} + +static ssize_t nvt_game_mode_switch_proc_read(struct file *filp, + char __user *buf, size_t count, + loff_t *f_pos) +{ + static int finished; + int32_t cnt = 0; + int32_t len = 0; + uint8_t game_mode_switch; + char tmp_buf[64]; + + NVT_LOG("++\n"); + + /* + * We return 0 to indicate end of file, that we have + * no more information. Otherwise, processes will + * continue to read from us in an endless loop. + */ + if (finished) { + NVT_LOG("read END\n"); + finished = 0; + return 0; + } + finished = 1; + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_get_game_mode_switch(&game_mode_switch); + + mutex_unlock(&ts->lock); + + cnt = snprintf(tmp_buf, sizeof(tmp_buf), "game_mode_switch: %d\n", + game_mode_switch); + if (copy_to_user(buf, tmp_buf, sizeof(tmp_buf))) { + NVT_ERR("copy_to_user() error!\n"); + return -EFAULT; + } + buf += cnt; + len += cnt; + + NVT_LOG("--\n"); + return len; +} + +static ssize_t nvt_game_mode_switch_proc_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *f_pos) +{ + int32_t ret; + int32_t tmp; + uint8_t game_mode_switch; + char *tmp_buf; + + NVT_LOG("++\n"); + + if (count == 0 || count > 2) { + NVT_ERR("Invalid value!, count = %zu\n", count); + ret = -EINVAL; + goto out; + } + + tmp_buf = kzalloc((count + 1), GFP_KERNEL); + if (!tmp_buf) { + NVT_ERR("Allocate tmp_buf fail!\n"); + ret = -ENOMEM; + goto out; + } + if (copy_from_user(tmp_buf, buf, count)) { + NVT_ERR("copy_from_user() error!\n"); + ret = -EFAULT; + goto out; + } + ret = sscanf(tmp_buf, "%d", &tmp); + if (ret != 1) { + NVT_ERR("Invalid value!, ret = %d\n", ret); + ret = -EINVAL; + goto out; + } + if ((tmp < 0) || (tmp > 1)) { + NVT_ERR("Invalid value!, tmp = %d\n", tmp); + ret = -EINVAL; + goto out; + } + game_mode_switch = (uint8_t)tmp; + NVT_LOG("game_mode_switch = %d\n", game_mode_switch); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + nvt_set_game_mode_switch(game_mode_switch); + + mutex_unlock(&ts->lock); + + ret = count; +out: + if (tmp_buf) + kfree(tmp_buf); + NVT_LOG("--\n"); + return ret; +} + +static const struct file_operations nvt_game_mode_switch_fops = { + .owner = THIS_MODULE, + .read = nvt_game_mode_switch_proc_read, + .write = nvt_game_mode_switch_proc_write, +}; + +/******************************************************* +Description: + Novatek touchscreen extra function proc. file node + initial function. + +return: + Executive outcomes. 0---succeed. -12---failed. +*******************************************************/ +int32_t nvt_extra_proc_init(void) +{ + NVT_proc_fw_version_entry = + proc_create(NVT_FW_VERSION, 0444, NULL, &nvt_fw_version_fops); + if (NVT_proc_fw_version_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_FW_VERSION); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_FW_VERSION); + } + + NVT_proc_baseline_entry = + proc_create(NVT_BASELINE, 0444, NULL, &nvt_baseline_fops); + if (NVT_proc_baseline_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_BASELINE); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_BASELINE); + } + + NVT_proc_raw_entry = proc_create(NVT_RAW, 0444, NULL, &nvt_raw_fops); + if (NVT_proc_raw_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_RAW); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_RAW); + } + + NVT_proc_diff_entry = proc_create(NVT_DIFF, 0444, NULL, &nvt_diff_fops); + if (NVT_proc_diff_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_DIFF); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_DIFF); + } + + if (ts->pen_support) { + NVT_proc_pen_diff_entry = proc_create(NVT_PEN_DIFF, 0444, NULL, + &nvt_pen_diff_fops); + if (NVT_proc_pen_diff_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_PEN_DIFF); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_PEN_DIFF); + } + } + + NVT_proc_pf_switch_entry = + proc_create(NVT_PF_SWITCH, 0666, NULL, &nvt_pf_switch_fops); + if (NVT_proc_pf_switch_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_PF_SWITCH); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_PF_SWITCH); + } + + NVT_proc_sensitivity_switch_entry = + proc_create(NVT_SENSITIVITY_SWITCH, 0666, NULL, + &nvt_sensitivity_switch_fops); + if (NVT_proc_sensitivity_switch_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_SENSITIVITY_SWITCH); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_SENSITIVITY_SWITCH); + } + + NVT_proc_er_range_switch_entry = proc_create( + NVT_ER_RANGE_SWITCH, 0666, NULL, &nvt_er_range_switch_fops); + if (NVT_proc_er_range_switch_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_ER_RANGE_SWITCH); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_ER_RANGE_SWITCH); + } + + NVT_proc_edge_reject_switch_entry = + proc_create(NVT_EDGE_REJECT_SWITCH, 0666, NULL, + &nvt_edge_reject_switch_fops); + if (NVT_proc_edge_reject_switch_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_EDGE_REJECT_SWITCH); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_EDGE_REJECT_SWITCH); + } + + NVT_proc_hand_only_switch_entry = proc_create( + NVT_HAND_ONLY_SWITCH, 0666, NULL, &nvt_hand_only_switch_fops); + if (NVT_proc_hand_only_switch_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_HAND_ONLY_SWITCH); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_HAND_ONLY_SWITCH); + } + + NVT_proc_drag_latency_switch_entry = + proc_create(NVT_DRAG_LATENCY_SWITCH, 0666, NULL, + &nvt_drag_latency_switch_fops); + if (NVT_proc_drag_latency_switch_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_DRAG_LATENCY_SWITCH); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_DRAG_LATENCY_SWITCH); + } + + NVT_proc_small_jitter_switch_entry = + proc_create(NVT_SMALL_JITTER_SWITCH, 0666, NULL, + &nvt_small_jitter_switch_fops); + if (NVT_proc_small_jitter_switch_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_SMALL_JITTER_SWITCH); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_SMALL_JITTER_SWITCH); + } + + NVT_proc_game_mode_switch_entry = proc_create( + NVT_GAME_MODE_SWITCH, 0666, NULL, &nvt_game_mode_switch_fops); + if (NVT_proc_game_mode_switch_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_GAME_MODE_SWITCH); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_GAME_MODE_SWITCH); + } + + NVT_proc_xiaomi_lockdown_info_entry = + proc_create(NVT_XIAOMI_LOCKDOWN_INFO, 0444, NULL, + &nvt_xiaomi_lockdown_info_fops); + if (NVT_proc_xiaomi_lockdown_info_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_XIAOMI_LOCKDOWN_INFO); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", + NVT_XIAOMI_LOCKDOWN_INFO); + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen extra function proc. file node + deinitial function. + +return: + n.a. +*******************************************************/ +void nvt_extra_proc_deinit(void) +{ + if (NVT_proc_fw_version_entry != NULL) { + remove_proc_entry(NVT_FW_VERSION, NULL); + NVT_proc_fw_version_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_FW_VERSION); + } + + if (NVT_proc_baseline_entry != NULL) { + remove_proc_entry(NVT_BASELINE, NULL); + NVT_proc_baseline_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_BASELINE); + } + + if (NVT_proc_raw_entry != NULL) { + remove_proc_entry(NVT_RAW, NULL); + NVT_proc_raw_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_RAW); + } + + if (NVT_proc_diff_entry != NULL) { + remove_proc_entry(NVT_DIFF, NULL); + NVT_proc_diff_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_DIFF); + } + + if (ts->pen_support) { + if (NVT_proc_pen_diff_entry != NULL) { + remove_proc_entry(NVT_PEN_DIFF, NULL); + NVT_proc_pen_diff_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_PEN_DIFF); + } + } + + if (NVT_proc_pf_switch_entry != NULL) { + remove_proc_entry(NVT_PF_SWITCH, NULL); + NVT_proc_pf_switch_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_PF_SWITCH); + } + + if (NVT_proc_sensitivity_switch_entry != NULL) { + remove_proc_entry(NVT_SENSITIVITY_SWITCH, NULL); + NVT_proc_sensitivity_switch_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_SENSITIVITY_SWITCH); + } + + if (NVT_proc_er_range_switch_entry != NULL) { + remove_proc_entry(NVT_ER_RANGE_SWITCH, NULL); + NVT_proc_er_range_switch_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_ER_RANGE_SWITCH); + } + + if (NVT_proc_edge_reject_switch_entry != NULL) { + remove_proc_entry(NVT_EDGE_REJECT_SWITCH, NULL); + NVT_proc_edge_reject_switch_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_EDGE_REJECT_SWITCH); + } + + if (NVT_proc_hand_only_switch_entry != NULL) { + remove_proc_entry(NVT_HAND_ONLY_SWITCH, NULL); + NVT_proc_hand_only_switch_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_HAND_ONLY_SWITCH); + } + + if (NVT_proc_drag_latency_switch_entry != NULL) { + remove_proc_entry(NVT_DRAG_LATENCY_SWITCH, NULL); + NVT_proc_drag_latency_switch_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_DRAG_LATENCY_SWITCH); + } + + if (NVT_proc_small_jitter_switch_entry != NULL) { + remove_proc_entry(NVT_SMALL_JITTER_SWITCH, NULL); + NVT_proc_small_jitter_switch_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_SMALL_JITTER_SWITCH); + } + + if (NVT_proc_game_mode_switch_entry != NULL) { + remove_proc_entry(NVT_GAME_MODE_SWITCH, NULL); + NVT_proc_game_mode_switch_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_GAME_MODE_SWITCH); + } +} +#endif diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_fw_update.c b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_fw_update.c new file mode 100644 index 000000000000..a721ec364c13 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_fw_update.c @@ -0,0 +1,1110 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * $Revision: 68983 $ + * $Date: 2020-09-17 09:43:23 +0800 (週四, 17 乿œˆ 2020) $ + * + * 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. + * + */ + +#include +#include + +#include "nt36xxx.h" + +#if BOOT_UPDATE_FIRMWARE + +#define SIZE_4KB 4096 +#define FLASH_SECTOR_SIZE SIZE_4KB +#define FW_BIN_VER_OFFSET (fw_need_write_size - SIZE_4KB) +#define FW_BIN_VER_BAR_OFFSET (FW_BIN_VER_OFFSET + 1) +#define NVT_FLASH_END_FLAG_LEN 3 +#define NVT_FLASH_END_FLAG_ADDR (fw_need_write_size - NVT_FLASH_END_FLAG_LEN) + +#define NVT_DUMP_PARTITION (0) +#define NVT_DUMP_PARTITION_LEN (1024) +#define NVT_DUMP_PARTITION_PATH "/data/local/tmp" + +static ktime_t start, end; +const struct firmware *fw_entry = NULL; +static size_t fw_need_write_size = 0; +static uint8_t *fwbuf = NULL; + +struct nvt_ts_bin_map { + char name[12]; + uint32_t BIN_addr; + uint32_t SRAM_addr; + uint32_t size; + uint32_t crc; +}; + +static struct nvt_ts_bin_map *bin_map; + +static int32_t nvt_get_fw_need_write_size(const struct firmware *fw_entry) +{ + int32_t i = 0; + int32_t total_sectors_to_check = 0; + + total_sectors_to_check = fw_entry->size / FLASH_SECTOR_SIZE; + /* printk("total_sectors_to_check = %d\n", total_sectors_to_check); */ + + for (i = total_sectors_to_check; i > 0; i--) { + /* printk("current end flag address checked = 0x%X\n", i * FLASH_SECTOR_SIZE - NVT_FLASH_END_FLAG_LEN); */ + /* check if there is end flag "NVT" at the end of this sector */ + if (strncmp(&fw_entry->data[i * FLASH_SECTOR_SIZE - + NVT_FLASH_END_FLAG_LEN], + "NVT", NVT_FLASH_END_FLAG_LEN) == 0) { + fw_need_write_size = i * FLASH_SECTOR_SIZE; + NVT_LOG("fw_need_write_size = %zu(0x%zx), NVT end flag\n", + fw_need_write_size, fw_need_write_size); + return 0; + } + + /* check if there is end flag "MOD" at the end of this sector */ + if (strncmp(&fw_entry->data[i * FLASH_SECTOR_SIZE - + NVT_FLASH_END_FLAG_LEN], + "MOD", NVT_FLASH_END_FLAG_LEN) == 0) { + fw_need_write_size = i * FLASH_SECTOR_SIZE; + NVT_LOG("fw_need_write_size = %zu(0x%zx), MOD end flag\n", + fw_need_write_size, fw_need_write_size); + return 0; + } + } + + NVT_ERR("end flag \"NVT\" \"MOD\" not found!\n"); + return -1; +} + +/******************************************************* +Description: + Novatek touchscreen init variable and allocate buffer +for download firmware function. + +return: + n.a. +*******************************************************/ +static int32_t nvt_download_init(void) +{ + /* allocate buffer for transfer firmware */ + //NVT_LOG("NVT_TRANSFER_LEN = 0x%06X\n", NVT_TRANSFER_LEN); + + if (fwbuf == NULL) { + fwbuf = (uint8_t *)kzalloc((NVT_TRANSFER_LEN + 1 + DUMMY_BYTES), + GFP_KERNEL); + if (fwbuf == NULL) { + NVT_ERR("kzalloc for fwbuf failed!\n"); + return -ENOMEM; + } + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen checksum function. Calculate bin +file checksum for comparison. + +return: + n.a. +*******************************************************/ +static uint32_t CheckSum(const u8 *data, size_t len) +{ + uint32_t i = 0; + uint32_t checksum = 0; + + for (i = 0; i < len + 1; i++) + checksum += data[i]; + + checksum += len; + checksum = ~checksum + 1; + + return checksum; +} + +static uint32_t byte_to_word(const uint8_t *data) +{ + return data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24); +} + +/******************************************************* +Description: + Novatek touchscreen parsing bin header function. + +return: + n.a. +*******************************************************/ +static uint32_t partition = 0; +static uint8_t ilm_dlm_num = 2; +static uint8_t cascade_2nd_header_info = 0; +static int32_t nvt_bin_header_parser(const u8 *fwdata, size_t fwsize) +{ + uint32_t list = 0; + uint32_t pos = 0x00; + uint32_t end = 0x00; + uint8_t info_sec_num = 0; + uint8_t ovly_sec_num = 0; + uint8_t ovly_info = 0; + uint8_t find_bin_header = 0; + + /* Find the header size */ + end = fwdata[0] + (fwdata[1] << 8) + (fwdata[2] << 16) + + (fwdata[3] << 24); + + /* check cascade next header */ + cascade_2nd_header_info = (fwdata[0x20] & 0x02) >> 1; + NVT_LOG("cascade_2nd_header_info = %d\n", cascade_2nd_header_info); + + if (cascade_2nd_header_info) { + pos = 0x30; // info section start at 0x30 offset + while (pos < (end / 2)) { + info_sec_num++; + pos += 0x10; /* each header info is 16 bytes */ + } + + info_sec_num = info_sec_num + 1; //next header section + } else { + pos = 0x30; // info section start at 0x30 offset + while (pos < end) { + info_sec_num++; + pos += 0x10; /* each header info is 16 bytes */ + } + } + + /* + * Find the DLM OVLY section + * [0:3] Overlay Section Number + * [4] Overlay Info + */ + ovly_info = (fwdata[0x28] & 0x10) >> 4; + ovly_sec_num = (ovly_info) ? (fwdata[0x28] & 0x0F) : 0; + + /* + * calculate all partition number + * ilm_dlm_num (ILM & DLM) + ovly_sec_num + info_sec_num + */ + partition = ilm_dlm_num + ovly_sec_num + info_sec_num; + NVT_LOG("ovly_info = %d, ilm_dlm_num = %d, ovly_sec_num = %d, info_sec_num = %d, partition = %d\n", + ovly_info, ilm_dlm_num, ovly_sec_num, info_sec_num, partition); + + /* allocated memory for header info */ + bin_map = (struct nvt_ts_bin_map *)kzalloc( + (partition + 1) * sizeof(struct nvt_ts_bin_map), GFP_KERNEL); + if (bin_map == NULL) { + NVT_ERR("kzalloc for bin_map failed!\n"); + return -ENOMEM; + } + + for (list = 0; list < partition; list++) { + /* + * [1] parsing ILM & DLM header info + * BIN_addr : SRAM_addr : size (12-bytes) + * crc located at 0x18 & 0x1C + */ + if (list < ilm_dlm_num) { + bin_map[list].BIN_addr = + byte_to_word(&fwdata[0 + list * 12]); + bin_map[list].SRAM_addr = + byte_to_word(&fwdata[4 + list * 12]); + bin_map[list].size = + byte_to_word(&fwdata[8 + list * 12]); + if (ts->hw_crc) + bin_map[list].crc = + byte_to_word(&fwdata[0x18 + list * 4]); + else { //ts->hw_crc + if ((bin_map[list].BIN_addr + + bin_map[list].size) < fwsize) + bin_map[list].crc = CheckSum( + &fwdata[bin_map[list].BIN_addr], + bin_map[list].size); + else { + NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", + bin_map[list].BIN_addr, + bin_map[list].BIN_addr + + bin_map[list].size); + return -EINVAL; + } + } //ts->hw_crc + if (list == 0) + sprintf(bin_map[list].name, "ILM"); + else if (list == 1) + sprintf(bin_map[list].name, "DLM"); + } + + /* + * [2] parsing others header info + * SRAM_addr : size : BIN_addr : crc (16-bytes) + */ + if ((list >= ilm_dlm_num) && + (list < (ilm_dlm_num + info_sec_num))) { + if (find_bin_header == 0) { + /* others partition located at 0x30 offset */ + pos = 0x30 + (0x10 * (list - ilm_dlm_num)); + } else if (find_bin_header && cascade_2nd_header_info) { + /* cascade 2nd header info */ + pos = end - 0x10; + } + + bin_map[list].SRAM_addr = byte_to_word(&fwdata[pos]); + bin_map[list].size = byte_to_word(&fwdata[pos + 4]); + bin_map[list].BIN_addr = byte_to_word(&fwdata[pos + 8]); + if (ts->hw_crc) + bin_map[list].crc = + byte_to_word(&fwdata[pos + 12]); + else { //ts->hw_crc + if ((bin_map[list].BIN_addr + + bin_map[list].size) < fwsize) + bin_map[list].crc = CheckSum( + &fwdata[bin_map[list].BIN_addr], + bin_map[list].size); + else { + NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", + bin_map[list].BIN_addr, + bin_map[list].BIN_addr + + bin_map[list].size); + return -EINVAL; + } + } //ts->hw_crc + /* detect header end to protect parser function */ + if ((bin_map[list].BIN_addr < end) && + (bin_map[list].size != 0)) { + sprintf(bin_map[list].name, "Header"); + find_bin_header = 1; + } else { + sprintf(bin_map[list].name, "Info-%d", + (list - ilm_dlm_num)); + } + } + + /* + * [3] parsing overlay section header info + * SRAM_addr : size : BIN_addr : crc (16-bytes) + */ + if (list >= (ilm_dlm_num + info_sec_num)) { + /* overlay info located at DLM (list = 1) start addr */ + pos = bin_map[1].BIN_addr + + (0x10 * (list - ilm_dlm_num - info_sec_num)); + + bin_map[list].SRAM_addr = byte_to_word(&fwdata[pos]); + bin_map[list].size = byte_to_word(&fwdata[pos + 4]); + bin_map[list].BIN_addr = byte_to_word(&fwdata[pos + 8]); + if (ts->hw_crc) + bin_map[list].crc = + byte_to_word(&fwdata[pos + 12]); + else { //ts->hw_crc + if ((bin_map[list].BIN_addr + + bin_map[list].size) < fwsize) + bin_map[list].crc = CheckSum( + &fwdata[bin_map[list].BIN_addr], + bin_map[list].size); + else { + NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", + bin_map[list].BIN_addr, + bin_map[list].BIN_addr + + bin_map[list].size); + return -EINVAL; + } + } //ts->hw_crc + sprintf(bin_map[list].name, "Overlay-%d", + (list - ilm_dlm_num - info_sec_num)); + } + + /* BIN size error detect */ + if ((bin_map[list].BIN_addr + bin_map[list].size) > fwsize) { + NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", + bin_map[list].BIN_addr, + bin_map[list].BIN_addr + bin_map[list].size); + return -EINVAL; + } + + // NVT_LOG("[%d][%s] SRAM (0x%08X), SIZE (0x%08X), BIN (0x%08X), CRC (0x%08X)\n", + // list, bin_map[list].name, + // bin_map[list].SRAM_addr, bin_map[list].size, bin_map[list].BIN_addr, bin_map[list].crc); + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen release update firmware function. + +return: + n.a. +*******************************************************/ +static void update_firmware_release(void) +{ + if (fw_entry) { + release_firmware(fw_entry); + } + + fw_entry = NULL; +} + +/******************************************************* +Description: + Novatek touchscreen request update firmware function. + +return: + Executive outcomes. 0---succeed. -1,-22---failed. +*******************************************************/ +static int32_t update_firmware_request(const char *filename) +{ + uint8_t retry = 0; + int32_t ret = 0; + + if (NULL == filename) { + return -ENOENT; + } + + while (1) { + NVT_LOG("filename is %s\n", filename); + + ret = request_firmware(&fw_entry, filename, &ts->client->dev); + if (ret) { + NVT_ERR("firmware load failed, ret=%d\n", ret); + goto request_fail; + } + + // check FW need to write size + if (nvt_get_fw_need_write_size(fw_entry)) { + NVT_ERR("get fw need to write size fail!\n"); + ret = -EINVAL; + goto invalid; + } + + // check if FW version add FW version bar equals 0xFF + if (*(fw_entry->data + FW_BIN_VER_OFFSET) + + *(fw_entry->data + FW_BIN_VER_BAR_OFFSET) != + 0xFF) { + NVT_ERR("bin file FW_VER + FW_VER_BAR should be 0xFF!\n"); + NVT_ERR("FW_VER=0x%02X, FW_VER_BAR=0x%02X\n", + *(fw_entry->data + FW_BIN_VER_OFFSET), + *(fw_entry->data + FW_BIN_VER_BAR_OFFSET)); + ret = -ENOEXEC; + goto invalid; + } + + /* BIN Header Parser */ + ret = nvt_bin_header_parser(fw_entry->data, fw_entry->size); + if (ret) { + NVT_ERR("bin header parser failed\n"); + goto invalid; + } else { + break; + } + +invalid: + update_firmware_release(); + if (!IS_ERR_OR_NULL(bin_map)) { + kfree(bin_map); + bin_map = NULL; + } + +request_fail: + retry++; + if (unlikely(retry > 2)) { + NVT_ERR("error, retry=%d\n", retry); + break; + } + } + + return ret; +} + +#if NVT_DUMP_PARTITION +/******************************************************* +Description: + Novatek touchscreen dump flash partition function. + +return: + n.a. +*******************************************************/ +loff_t file_offset = 0; +static int32_t nvt_read_ram_and_save_file(uint32_t addr, uint16_t len, + char *name) +{ + char file[256] = ""; + uint8_t *fbufp = NULL; + int32_t ret = 0; + struct file *fp = NULL; + mm_segment_t org_fs; + + sprintf(file, "%s/dump_%s.bin", NVT_DUMP_PARTITION_PATH, name); + NVT_LOG("Dump [%s] from 0x%08X to 0x%08X\n", file, addr, addr + len); + + fbufp = (uint8_t *)kzalloc(len + 1, GFP_KERNEL); + if (fbufp == NULL) { + NVT_ERR("kzalloc for fbufp failed!\n"); + ret = -ENOMEM; + goto alloc_buf_fail; + } + + org_fs = get_fs(); + set_fs(KERNEL_DS); + fp = filp_open(file, O_RDWR | O_CREAT, 0644); + if (fp == NULL || IS_ERR(fp)) { + ret = -ENOMEM; + NVT_ERR("open file failed\n"); + goto open_file_fail; + } + + /* SPI read */ + //---set xdata index to addr--- + nvt_set_page(addr); + + fbufp[0] = addr & 0x7F; //offset + CTP_SPI_READ(ts->client, fbufp, len + 1); + + /* Write to file */ + ret = vfs_write(fp, (char __user *)fbufp + 1, len, &file_offset); + if (ret != len) { + NVT_ERR("write file failed\n"); + goto open_file_fail; + } else { + ret = 0; + } + +open_file_fail: + set_fs(org_fs); + if (!IS_ERR_OR_NULL(fp)) { + filp_close(fp, NULL); + fp = NULL; + } + + if (!IS_ERR_OR_NULL(fbufp)) { + kfree(fbufp); + fbufp = NULL; + } +alloc_buf_fail: + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen nvt_dump_partition function to dump + each partition for debug. + +return: + n.a. +*******************************************************/ +static int32_t nvt_dump_partition(void) +{ + uint32_t list = 0; + char *name; + uint32_t SRAM_addr, size; + uint32_t i = 0; + uint16_t len = 0; + int32_t count = 0; + int32_t ret = 0; + + if (NVT_DUMP_PARTITION_LEN >= sizeof(ts->rbuf)) { + NVT_ERR("dump len %d is larger than buffer size %ld\n", + NVT_DUMP_PARTITION_LEN, sizeof(ts->rbuf)); + return -EINVAL; + } else if (NVT_DUMP_PARTITION_LEN >= NVT_TRANSFER_LEN) { + NVT_ERR("dump len %d is larger than NVT_TRANSFER_LEN\n", + NVT_DUMP_PARTITION_LEN); + return -EINVAL; + } + + if (bin_map == NULL) { + NVT_ERR("bin_map is NULL\n"); + return -ENOMEM; + } + + memset(fwbuf, 0, (NVT_DUMP_PARTITION_LEN + 1)); + + for (list = 0; list < partition; list++) { + /* initialize variable */ + SRAM_addr = bin_map[list].SRAM_addr; + size = bin_map[list].size; + name = bin_map[list].name; + + /* ignore reserved partition (Reserved Partition size is zero) */ + if (!size) + continue; + else + size = size + 1; + + /* write data to SRAM */ + if (size % NVT_DUMP_PARTITION_LEN) + count = (size / NVT_DUMP_PARTITION_LEN) + 1; + else + count = (size / NVT_DUMP_PARTITION_LEN); + + for (i = 0; i < count; i++) { + len = (size < NVT_DUMP_PARTITION_LEN) ? + size : + NVT_DUMP_PARTITION_LEN; + + /* dump for debug download firmware */ + ret = nvt_read_ram_and_save_file(SRAM_addr, len, name); + if (ret < 0) { + NVT_ERR("nvt_read_ram_and_save_file failed, ret = %d\n", + ret); + goto out; + } + + SRAM_addr += NVT_DUMP_PARTITION_LEN; + size -= NVT_DUMP_PARTITION_LEN; + } + + file_offset = 0; + } + +out: + return ret; +} +#endif /* NVT_DUMP_PARTITION */ + +/******************************************************* +Description: + Novatek touchscreen write data to sram function. + +- fwdata : The buffer is written +- SRAM_addr: The sram destination address +- size : Number of data bytes in @fwdata being written +- BIN_addr : The transferred data offset of @fwdata + +return: + Executive outcomes. 0---succeed. else---fail. +*******************************************************/ +static int32_t nvt_write_sram(const u8 *fwdata, uint32_t SRAM_addr, + uint32_t size, uint32_t BIN_addr) +{ + int32_t ret = 0; + uint32_t i = 0; + uint16_t len = 0; + int32_t count = 0; + + if (size % NVT_TRANSFER_LEN) + count = (size / NVT_TRANSFER_LEN) + 1; + else + count = (size / NVT_TRANSFER_LEN); + + for (i = 0; i < count; i++) { + len = (size < NVT_TRANSFER_LEN) ? size : NVT_TRANSFER_LEN; + + //---set xdata index to start address of SRAM--- + ret = nvt_set_page(SRAM_addr); + if (ret) { + NVT_ERR("set page failed, ret = %d\n", ret); + return ret; + } + + //---write data into SRAM--- + fwbuf[0] = SRAM_addr & 0x7F; //offset + memcpy(fwbuf + 1, &fwdata[BIN_addr], len); //payload + ret = CTP_SPI_WRITE(ts->client, fwbuf, len + 1); + if (ret) { + NVT_ERR("write to sram failed, ret = %d\n", ret); + return ret; + } + + SRAM_addr += NVT_TRANSFER_LEN; + BIN_addr += NVT_TRANSFER_LEN; + size -= NVT_TRANSFER_LEN; + } + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen nvt_write_firmware function to write +firmware into each partition. + +return: + n.a. +*******************************************************/ +static int32_t nvt_write_firmware(const u8 *fwdata, size_t fwsize) +{ + uint32_t list = 0; + char *name; + uint32_t BIN_addr, SRAM_addr, size; + int32_t ret = 0; + + memset(fwbuf, 0, (NVT_TRANSFER_LEN + 1)); + + for (list = 0; list < partition; list++) { + /* initialize variable */ + SRAM_addr = bin_map[list].SRAM_addr; + size = bin_map[list].size; + BIN_addr = bin_map[list].BIN_addr; + name = bin_map[list].name; + + // NVT_LOG("[%d][%s] SRAM (0x%08X), SIZE (0x%08X), BIN (0x%08X)\n", + // list, name, SRAM_addr, size, BIN_addr); + + /* Check data size */ + if ((BIN_addr + size) > fwsize) { + NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", + BIN_addr, BIN_addr + size); + ret = -EINVAL; + goto out; + } + + /* ignore reserved partition (Reserved Partition size is zero) */ + if (!size) + continue; + else + size = size + 1; + + /* write data to SRAM */ + ret = nvt_write_sram(fwdata, SRAM_addr, size, BIN_addr); + if (ret) { + NVT_ERR("sram program failed, ret = %d\n", ret); + goto out; + } + } + +out: + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen check checksum function. +This function will compare file checksum and fw checksum. + +return: + n.a. +*******************************************************/ +static int32_t nvt_check_fw_checksum(void) +{ + uint32_t fw_checksum = 0; + uint32_t len = partition * 4; + uint32_t list = 0; + int32_t ret = 0; + + memset(fwbuf, 0, (len + 1)); + + //---set xdata index to checksum--- + nvt_set_page(ts->mmap->R_ILM_CHECKSUM_ADDR); + + /* read checksum */ + fwbuf[0] = (ts->mmap->R_ILM_CHECKSUM_ADDR) & 0x7F; + ret = CTP_SPI_READ(ts->client, fwbuf, len + 1); + if (ret) { + NVT_ERR("Read fw checksum failed\n"); + return ret; + } + + /* + * Compare each checksum from fw + * ILM + DLM + Overlay + Info + * ilm_dlm_num (ILM & DLM) + ovly_sec_num + info_sec_num + */ + for (list = 0; list < partition; list++) { + fw_checksum = byte_to_word(&fwbuf[1 + list * 4]); + + /* ignore reserved partition (Reserved Partition size is zero) */ + if (!bin_map[list].size) + continue; + + if (bin_map[list].crc != fw_checksum) { + NVT_ERR("[%d] BIN_checksum=0x%08X, FW_checksum=0x%08X\n", + list, bin_map[list].crc, fw_checksum); + ret = -EIO; + } + } + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen set bootload crc reg bank function. +This function will set hw crc reg before enable crc function. + +return: + n.a. +*******************************************************/ +static void nvt_set_bld_crc_bank(uint32_t DES_ADDR, uint32_t SRAM_ADDR, + uint32_t LENGTH_ADDR, uint32_t size, + uint32_t G_CHECKSUM_ADDR, uint32_t crc) +{ + /* write destination address */ + nvt_set_page(DES_ADDR); + fwbuf[0] = DES_ADDR & 0x7F; + fwbuf[1] = (SRAM_ADDR) & 0xFF; + fwbuf[2] = (SRAM_ADDR >> 8) & 0xFF; + fwbuf[3] = (SRAM_ADDR >> 16) & 0xFF; + CTP_SPI_WRITE(ts->client, fwbuf, 4); + + /* write length */ + //nvt_set_page(LENGTH_ADDR); + fwbuf[0] = LENGTH_ADDR & 0x7F; + fwbuf[1] = (size) & 0xFF; + fwbuf[2] = (size >> 8) & 0xFF; + fwbuf[3] = (size >> 16) & 0x01; + if (ts->hw_crc == 1) { + CTP_SPI_WRITE(ts->client, fwbuf, 3); + } else if (ts->hw_crc > 1) { + CTP_SPI_WRITE(ts->client, fwbuf, 4); + } + + /* write golden dlm checksum */ + //nvt_set_page(G_CHECKSUM_ADDR); + fwbuf[0] = G_CHECKSUM_ADDR & 0x7F; + fwbuf[1] = (crc) & 0xFF; + fwbuf[2] = (crc >> 8) & 0xFF; + fwbuf[3] = (crc >> 16) & 0xFF; + fwbuf[4] = (crc >> 24) & 0xFF; + CTP_SPI_WRITE(ts->client, fwbuf, 5); + + return; +} + +/******************************************************* +Description: + Novatek touchscreen set BLD hw crc function. +This function will set ILM and DLM crc information to register. + +return: + n.a. +*******************************************************/ +static void nvt_set_bld_hw_crc(void) +{ + /* [0] ILM */ + /* write register bank */ + nvt_set_bld_crc_bank(ts->mmap->ILM_DES_ADDR, bin_map[0].SRAM_addr, + ts->mmap->ILM_LENGTH_ADDR, bin_map[0].size, + ts->mmap->G_ILM_CHECKSUM_ADDR, bin_map[0].crc); + + /* [1] DLM */ + /* write register bank */ + nvt_set_bld_crc_bank(ts->mmap->DLM_DES_ADDR, bin_map[1].SRAM_addr, + ts->mmap->DLM_LENGTH_ADDR, bin_map[1].size, + ts->mmap->G_DLM_CHECKSUM_ADDR, bin_map[1].crc); +} + +/******************************************************* +Description: + Novatek touchscreen read BLD hw crc info function. +This function will check crc results from register. + +return: + n.a. +*******************************************************/ +static void nvt_read_bld_hw_crc(void) +{ + uint8_t buf[8] = { 0 }; + uint32_t g_crc = 0, r_crc = 0; + + /* CRC Flag */ + nvt_set_page(ts->mmap->BLD_ILM_DLM_CRC_ADDR); + buf[0] = ts->mmap->BLD_ILM_DLM_CRC_ADDR & 0x7F; + buf[1] = 0x00; + CTP_SPI_READ(ts->client, buf, 2); + NVT_ERR("crc_done = %d, ilm_crc_flag = %d, dlm_crc_flag = %d\n", + (buf[1] >> 2) & 0x01, (buf[1] >> 0) & 0x01, + (buf[1] >> 1) & 0x01); + + /* ILM CRC */ + nvt_set_page(ts->mmap->G_ILM_CHECKSUM_ADDR); + buf[0] = ts->mmap->G_ILM_CHECKSUM_ADDR & 0x7F; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + CTP_SPI_READ(ts->client, buf, 5); + g_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24); + + nvt_set_page(ts->mmap->R_ILM_CHECKSUM_ADDR); + buf[0] = ts->mmap->R_ILM_CHECKSUM_ADDR & 0x7F; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + CTP_SPI_READ(ts->client, buf, 5); + r_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24); + + NVT_ERR("ilm: bin crc = 0x%08X, golden = 0x%08X, result = 0x%08X\n", + bin_map[0].crc, g_crc, r_crc); + + /* DLM CRC */ + nvt_set_page(ts->mmap->G_DLM_CHECKSUM_ADDR); + buf[0] = ts->mmap->G_DLM_CHECKSUM_ADDR & 0x7F; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + CTP_SPI_READ(ts->client, buf, 5); + g_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24); + + nvt_set_page(ts->mmap->R_DLM_CHECKSUM_ADDR); + buf[0] = ts->mmap->R_DLM_CHECKSUM_ADDR & 0x7F; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + CTP_SPI_READ(ts->client, buf, 5); + r_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24); + + NVT_ERR("dlm: bin crc = 0x%08X, golden = 0x%08X, result = 0x%08X\n", + bin_map[1].crc, g_crc, r_crc); + + return; +} + +/******************************************************* +Description: + Novatek touchscreen Download_Firmware with HW CRC +function. It's complete download firmware flow. + +return: + Executive outcomes. 0---succeed. else---fail. +*******************************************************/ +static int32_t nvt_download_firmware_hw_crc(void) +{ + uint8_t retry = 0; + int32_t ret = 0; + + start = ktime_get(); + + while (1) { + /* bootloader reset to reset MCU */ + nvt_bootloader_reset(); + + /* set ilm & dlm reg bank */ + nvt_set_bld_hw_crc(); + + /* Start to write firmware process */ + if (cascade_2nd_header_info) { + /* for cascade */ + nvt_tx_auto_copy_mode(); + + ret = nvt_write_firmware(fw_entry->data, + fw_entry->size); + if (ret) { + NVT_ERR("Write_Firmware failed. (%d)\n", ret); + goto fail; + } + + ret = nvt_check_spi_dma_tx_info(); + if (ret) { + NVT_ERR("spi dma tx info failed. (%d)\n", ret); + goto fail; + } + } else { + ret = nvt_write_firmware(fw_entry->data, + fw_entry->size); + if (ret) { + NVT_ERR("Write_Firmware failed. (%d)\n", ret); + goto fail; + } + } + +#if NVT_DUMP_PARTITION + ret = nvt_dump_partition(); + if (ret) { + NVT_ERR("nvt_dump_partition failed, ret = %d\n", ret); + } +#endif + + /* enable hw bld crc function */ + nvt_bld_crc_enable(); + + /* clear fw reset status & enable fw crc check */ + nvt_fw_crc_enable(); + + /* Set Boot Ready Bit */ + nvt_boot_ready(); + + ret = nvt_check_fw_reset_state(RESET_STATE_INIT); + if (ret) { + NVT_ERR("nvt_check_fw_reset_state failed. (%d)\n", ret); + goto fail; + } else { + break; + } + +fail: + retry++; + if (unlikely(retry > 2)) { + NVT_ERR("error, retry=%d\n", retry); + nvt_read_bld_hw_crc(); + break; + } + } + + end = ktime_get(); + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen Download_Firmware function. It's +complete download firmware flow. + +return: + n.a. +*******************************************************/ +static int32_t nvt_download_firmware(void) +{ + uint8_t retry = 0; + int32_t ret = 0; + + start = ktime_get(); + + while (1) { + /* + * Send eng reset cmd before download FW + * Keep TP_RESX low when send eng reset cmd + */ +#if NVT_TOUCH_SUPPORT_HW_RST + gpio_set_value(ts->reset_gpio, 0); + mdelay(1); //wait 1ms +#endif + nvt_eng_reset(); +#if NVT_TOUCH_SUPPORT_HW_RST + gpio_set_value(ts->reset_gpio, 1); + mdelay(10); //wait tRT2BRST after TP_RST +#endif + nvt_bootloader_reset(); + + /* clear fw reset status */ + nvt_write_addr(ts->mmap->EVENT_BUF_ADDR | + EVENT_MAP_RESET_COMPLETE, + 0x00); + + /* Start to write firmware process */ + ret = nvt_write_firmware(fw_entry->data, fw_entry->size); + if (ret) { + NVT_ERR("Write_Firmware failed. (%d)\n", ret); + goto fail; + } + +#if NVT_DUMP_PARTITION + ret = nvt_dump_partition(); + if (ret) { + NVT_ERR("nvt_dump_partition failed, ret = %d\n", ret); + } +#endif + + /* Set Boot Ready Bit */ + nvt_boot_ready(); + + ret = nvt_check_fw_reset_state(RESET_STATE_INIT); + if (ret) { + NVT_ERR("nvt_check_fw_reset_state failed. (%d)\n", ret); + goto fail; + } + + /* check fw checksum result */ + ret = nvt_check_fw_checksum(); + if (ret) { + NVT_ERR("firmware checksum not match, retry=%d\n", + retry); + goto fail; + } else { + break; + } + +fail: + retry++; + if (unlikely(retry > 2)) { + NVT_ERR("error, retry=%d\n", retry); + break; + } + } + + end = ktime_get(); + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen update firmware main function. + +return: + n.a. +*******************************************************/ +int32_t nvt_update_firmware(const char *firmware_name) +{ + int32_t ret = 0; + + // request bin file in "/etc/firmware" + ret = update_firmware_request(firmware_name); + if (ret) { + NVT_ERR("update_firmware_request failed. (%d)\n", ret); + goto request_firmware_fail; + } + + /* initial buffer and variable */ + ret = nvt_download_init(); + if (ret) { + NVT_ERR("Download Init failed. (%d)\n", ret); + goto download_fail; + } + + /* download firmware process */ + if (ts->hw_crc) + ret = nvt_download_firmware_hw_crc(); + else + ret = nvt_download_firmware(); + if (ret) { + NVT_ERR("Download Firmware failed. (%d)\n", ret); + goto download_fail; + } + + NVT_LOG("Update firmware success! <%ld us>\n", + (long)ktime_us_delta(end, start)); + + /* Get FW Info */ + ret = nvt_get_fw_info(); + if (ret) { + NVT_ERR("nvt_get_fw_info failed. (%d)\n", ret); + } + +download_fail: + if (!IS_ERR_OR_NULL(bin_map)) { + kfree(bin_map); + bin_map = NULL; + } + + update_firmware_release(); +request_firmware_fail: + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen update firmware when booting + function. + +return: + n.a. +*******************************************************/ +void Boot_Update_Firmware(struct work_struct *work) +{ + nvt_match_fw(); + mutex_lock(&ts->lock); + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_FW_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + nvt_get_fw_info(); + mutex_unlock(&ts->lock); +} +#endif /* BOOT_UPDATE_FIRMWARE */ diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_mem_map.h b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_mem_map.h new file mode 100644 index 000000000000..cc92256f9efe --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_mem_map.h @@ -0,0 +1,442 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * $Revision: 57674 $ + * $Date: 2020-03-02 11:16:20 +0800 (週一, 02 三月 2020) $ + * + * 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. + * + */ + +#define CHIP_VER_TRIM_ADDR 0x3F004 +#define CHIP_VER_TRIM_OLD_ADDR 0x1F64E + +struct nvt_ts_mem_map { + uint32_t EVENT_BUF_ADDR; + uint32_t RAW_PIPE0_ADDR; + uint32_t RAW_PIPE1_ADDR; + uint32_t BASELINE_ADDR; + uint32_t BASELINE_BTN_ADDR; + uint32_t DIFF_PIPE0_ADDR; + uint32_t DIFF_PIPE1_ADDR; + uint32_t RAW_BTN_PIPE0_ADDR; + uint32_t RAW_BTN_PIPE1_ADDR; + uint32_t DIFF_BTN_PIPE0_ADDR; + uint32_t DIFF_BTN_PIPE1_ADDR; + uint32_t PEN_2D_BL_TIP_X_ADDR; + uint32_t PEN_2D_BL_TIP_Y_ADDR; + uint32_t PEN_2D_BL_RING_X_ADDR; + uint32_t PEN_2D_BL_RING_Y_ADDR; + uint32_t PEN_2D_DIFF_TIP_X_ADDR; + uint32_t PEN_2D_DIFF_TIP_Y_ADDR; + uint32_t PEN_2D_DIFF_RING_X_ADDR; + uint32_t PEN_2D_DIFF_RING_Y_ADDR; + uint32_t PEN_2D_RAW_TIP_X_ADDR; + uint32_t PEN_2D_RAW_TIP_Y_ADDR; + uint32_t PEN_2D_RAW_RING_X_ADDR; + uint32_t PEN_2D_RAW_RING_Y_ADDR; + uint32_t PEN_1D_DIFF_TIP_X_ADDR; + uint32_t PEN_1D_DIFF_TIP_Y_ADDR; + uint32_t PEN_1D_DIFF_RING_X_ADDR; + uint32_t PEN_1D_DIFF_RING_Y_ADDR; + uint32_t READ_FLASH_CHECKSUM_ADDR; + uint32_t RW_FLASH_DATA_ADDR; + /* Phase 2 Host Download */ + uint32_t BOOT_RDY_ADDR; + uint32_t POR_CD_ADDR; + uint32_t TX_AUTO_COPY_EN; + uint32_t SPI_DMA_TX_INFO; + /* BLD CRC */ + uint32_t BLD_LENGTH_ADDR; + uint32_t ILM_LENGTH_ADDR; + uint32_t DLM_LENGTH_ADDR; + uint32_t BLD_DES_ADDR; + uint32_t ILM_DES_ADDR; + uint32_t DLM_DES_ADDR; + uint32_t G_ILM_CHECKSUM_ADDR; + uint32_t G_DLM_CHECKSUM_ADDR; + uint32_t R_ILM_CHECKSUM_ADDR; + uint32_t R_DLM_CHECKSUM_ADDR; + uint32_t BLD_CRC_EN_ADDR; + uint32_t DMA_CRC_EN_ADDR; + uint32_t BLD_ILM_DLM_CRC_ADDR; + uint32_t DMA_CRC_FLAG_ADDR; + uint32_t FW_HISTORY_ADDR; +}; + +struct nvt_ts_hw_info { + uint8_t carrier_system; + uint8_t hw_crc; +}; + +static const struct nvt_ts_mem_map NT36523_memory_map = { + .EVENT_BUF_ADDR = 0x2FE00, + .RAW_PIPE0_ADDR = 0x30FA0, + .RAW_PIPE1_ADDR = 0x30FA0, + .BASELINE_ADDR = 0x36510, + .BASELINE_BTN_ADDR = 0, + .DIFF_PIPE0_ADDR = 0x373E8, + .DIFF_PIPE1_ADDR = 0x38068, + .RAW_BTN_PIPE0_ADDR = 0, + .RAW_BTN_PIPE1_ADDR = 0, + .DIFF_BTN_PIPE0_ADDR = 0, + .DIFF_BTN_PIPE1_ADDR = 0, + .PEN_2D_BL_TIP_X_ADDR = 0x2988A, + .PEN_2D_BL_TIP_Y_ADDR = 0x29A1A, + .PEN_2D_BL_RING_X_ADDR = 0x29BAA, + .PEN_2D_BL_RING_Y_ADDR = 0x29D3A, + .PEN_2D_DIFF_TIP_X_ADDR = 0x29ECA, + .PEN_2D_DIFF_TIP_Y_ADDR = 0x2A05A, + .PEN_2D_DIFF_RING_X_ADDR = 0x2A1EA, + .PEN_2D_DIFF_RING_Y_ADDR = 0x2A37A, + .PEN_2D_RAW_TIP_X_ADDR = 0x2A50A, + .PEN_2D_RAW_TIP_Y_ADDR = 0x2A69A, + .PEN_2D_RAW_RING_X_ADDR = 0x2A82A, + .PEN_2D_RAW_RING_Y_ADDR = 0x2A9BA, + .PEN_1D_DIFF_TIP_X_ADDR = 0x2AB4A, + .PEN_1D_DIFF_TIP_Y_ADDR = 0x2ABAE, + .PEN_1D_DIFF_RING_X_ADDR = 0x2AC12, + .PEN_1D_DIFF_RING_Y_ADDR = 0x2AC76, + .READ_FLASH_CHECKSUM_ADDR = 0x24000, + .RW_FLASH_DATA_ADDR = 0x24002, + /* Phase 2 Host Download */ + .BOOT_RDY_ADDR = 0x3F10D, + .TX_AUTO_COPY_EN = 0x3F7E8, + .SPI_DMA_TX_INFO = 0x3F7F1, + /* BLD CRC */ + .BLD_LENGTH_ADDR = 0x3F138, //0x3F138 ~ 0x3F13A (3 bytes) + .ILM_LENGTH_ADDR = 0x3F118, //0x3F118 ~ 0x3F11A (3 bytes) + .DLM_LENGTH_ADDR = 0x3F130, //0x3F130 ~ 0x3F132 (3 bytes) + .BLD_DES_ADDR = 0x3F114, //0x3F114 ~ 0x3F116 (3 bytes) + .ILM_DES_ADDR = 0x3F128, //0x3F128 ~ 0x3F12A (3 bytes) + .DLM_DES_ADDR = 0x3F12C, //0x3F12C ~ 0x3F12E (3 bytes) + .G_ILM_CHECKSUM_ADDR = 0x3F100, //0x3F100 ~ 0x3F103 (4 bytes) + .G_DLM_CHECKSUM_ADDR = 0x3F104, //0x3F104 ~ 0x3F107 (4 bytes) + .R_ILM_CHECKSUM_ADDR = 0x3F120, //0x3F120 ~ 0x3F123 (4 bytes) + .R_DLM_CHECKSUM_ADDR = 0x3F124, //0x3F124 ~ 0x3F127 (4 bytes) + .BLD_CRC_EN_ADDR = 0x3F30E, + .DMA_CRC_EN_ADDR = 0x3F136, + .BLD_ILM_DLM_CRC_ADDR = 0x3F133, + .DMA_CRC_FLAG_ADDR = 0x3F134, + .FW_HISTORY_ADDR = 0x38D54, +}; + +static const struct nvt_ts_mem_map NT36526_memory_map = { + .EVENT_BUF_ADDR = 0x22D00, + .RAW_PIPE0_ADDR = 0x24000, + .RAW_PIPE1_ADDR = 0x24000, + .BASELINE_ADDR = 0x21758, + .BASELINE_BTN_ADDR = 0, + .DIFF_PIPE0_ADDR = 0x20AB0, + .DIFF_PIPE1_ADDR = 0x24AB0, + .RAW_BTN_PIPE0_ADDR = 0, + .RAW_BTN_PIPE1_ADDR = 0, + .DIFF_BTN_PIPE0_ADDR = 0, + .DIFF_BTN_PIPE1_ADDR = 0, + .READ_FLASH_CHECKSUM_ADDR = 0x24000, + .RW_FLASH_DATA_ADDR = 0x24002, + /* Phase 2 Host Download */ + .BOOT_RDY_ADDR = 0x3F10D, + /* BLD CRC */ + .BLD_LENGTH_ADDR = 0x3F138, //0x3F138 ~ 0x3F13A (3 bytes) + .ILM_LENGTH_ADDR = 0x3F118, //0x3F118 ~ 0x3F11A (3 bytes) + .DLM_LENGTH_ADDR = 0x3F130, //0x3F130 ~ 0x3F132 (3 bytes) + .BLD_DES_ADDR = 0x3F114, //0x3F114 ~ 0x3F116 (3 bytes) + .ILM_DES_ADDR = 0x3F128, //0x3F128 ~ 0x3F12A (3 bytes) + .DLM_DES_ADDR = 0x3F12C, //0x3F12C ~ 0x3F12E (3 bytes) + .G_ILM_CHECKSUM_ADDR = 0x3F100, //0x3F100 ~ 0x3F103 (4 bytes) + .G_DLM_CHECKSUM_ADDR = 0x3F104, //0x3F104 ~ 0x3F107 (4 bytes) + .R_ILM_CHECKSUM_ADDR = 0x3F120, //0x3F120 ~ 0x3F123 (4 bytes) + .R_DLM_CHECKSUM_ADDR = 0x3F124, //0x3F124 ~ 0x3F127 (4 bytes) + .BLD_CRC_EN_ADDR = 0x3F30E, + .DMA_CRC_EN_ADDR = 0x3F136, + .BLD_ILM_DLM_CRC_ADDR = 0x3F133, + .DMA_CRC_FLAG_ADDR = 0x3F134, +}; + +static const struct nvt_ts_mem_map NT36675_memory_map = { + .EVENT_BUF_ADDR = 0x22D00, + .RAW_PIPE0_ADDR = 0x24000, + .RAW_PIPE1_ADDR = 0x24000, + .BASELINE_ADDR = 0x21B90, + .BASELINE_BTN_ADDR = 0, + .DIFF_PIPE0_ADDR = 0x20C60, + .DIFF_PIPE1_ADDR = 0x24C60, + .RAW_BTN_PIPE0_ADDR = 0, + .RAW_BTN_PIPE1_ADDR = 0, + .DIFF_BTN_PIPE0_ADDR = 0, + .DIFF_BTN_PIPE1_ADDR = 0, + .READ_FLASH_CHECKSUM_ADDR = 0x24000, + .RW_FLASH_DATA_ADDR = 0x24002, + /* Phase 2 Host Download */ + .BOOT_RDY_ADDR = 0x3F10D, + /* BLD CRC */ + .BLD_LENGTH_ADDR = 0x3F138, //0x3F138 ~ 0x3F13A (3 bytes) + .ILM_LENGTH_ADDR = 0x3F118, //0x3F118 ~ 0x3F11A (3 bytes) + .DLM_LENGTH_ADDR = 0x3F130, //0x3F130 ~ 0x3F132 (3 bytes) + .BLD_DES_ADDR = 0x3F114, //0x3F114 ~ 0x3F116 (3 bytes) + .ILM_DES_ADDR = 0x3F128, //0x3F128 ~ 0x3F12A (3 bytes) + .DLM_DES_ADDR = 0x3F12C, //0x3F12C ~ 0x3F12E (3 bytes) + .G_ILM_CHECKSUM_ADDR = 0x3F100, //0x3F100 ~ 0x3F103 (4 bytes) + .G_DLM_CHECKSUM_ADDR = 0x3F104, //0x3F104 ~ 0x3F107 (4 bytes) + .R_ILM_CHECKSUM_ADDR = 0x3F120, //0x3F120 ~ 0x3F123 (4 bytes) + .R_DLM_CHECKSUM_ADDR = 0x3F124, //0x3F124 ~ 0x3F127 (4 bytes) + .BLD_CRC_EN_ADDR = 0x3F30E, + .DMA_CRC_EN_ADDR = 0x3F136, + .BLD_ILM_DLM_CRC_ADDR = 0x3F133, + .DMA_CRC_FLAG_ADDR = 0x3F134, +}; + +static const struct nvt_ts_mem_map NT36672A_memory_map = { + .EVENT_BUF_ADDR = 0x21C00, + .RAW_PIPE0_ADDR = 0x20000, + .RAW_PIPE1_ADDR = 0x23000, + .BASELINE_ADDR = 0x20BFC, + .BASELINE_BTN_ADDR = 0x23BFC, + .DIFF_PIPE0_ADDR = 0x206DC, + .DIFF_PIPE1_ADDR = 0x236DC, + .RAW_BTN_PIPE0_ADDR = 0x20510, + .RAW_BTN_PIPE1_ADDR = 0x23510, + .DIFF_BTN_PIPE0_ADDR = 0x20BF0, + .DIFF_BTN_PIPE1_ADDR = 0x23BF0, + .READ_FLASH_CHECKSUM_ADDR = 0x24000, + .RW_FLASH_DATA_ADDR = 0x24002, + /* Phase 2 Host Download */ + .BOOT_RDY_ADDR = 0x3F10D, + /* BLD CRC */ + .BLD_LENGTH_ADDR = 0x3F10E, //0x3F10E ~ 0x3F10F (2 bytes) + .ILM_LENGTH_ADDR = 0x3F118, //0x3F118 ~ 0x3F119 (2 bytes) + .DLM_LENGTH_ADDR = 0x3F130, //0x3F130 ~ 0x3F131 (2 bytes) + .BLD_DES_ADDR = 0x3F114, //0x3F114 ~ 0x3F116 (3 bytes) + .ILM_DES_ADDR = 0x3F128, //0x3F128 ~ 0x3F12A (3 bytes) + .DLM_DES_ADDR = 0x3F12C, //0x3F12C ~ 0x3F12E (3 bytes) + .G_ILM_CHECKSUM_ADDR = 0x3F100, //0x3F100 ~ 0x3F103 (4 bytes) + .G_DLM_CHECKSUM_ADDR = 0x3F104, //0x3F104 ~ 0x3F107 (4 bytes) + .R_ILM_CHECKSUM_ADDR = 0x3F120, //0x3F120 ~ 0x3F123 (4 bytes) + .R_DLM_CHECKSUM_ADDR = 0x3F124, //0x3F124 ~ 0x3F127 (4 bytes) + .BLD_CRC_EN_ADDR = 0x3F30E, + .DMA_CRC_EN_ADDR = 0x3F132, + .BLD_ILM_DLM_CRC_ADDR = 0x3F133, + .DMA_CRC_FLAG_ADDR = 0x3F134, +}; + +static const struct nvt_ts_mem_map NT36772_memory_map = { + .EVENT_BUF_ADDR = 0x11E00, + .RAW_PIPE0_ADDR = 0x10000, + .RAW_PIPE1_ADDR = 0x12000, + .BASELINE_ADDR = 0x10E70, + .BASELINE_BTN_ADDR = 0x12E70, + .DIFF_PIPE0_ADDR = 0x10830, + .DIFF_PIPE1_ADDR = 0x12830, + .RAW_BTN_PIPE0_ADDR = 0x10E60, + .RAW_BTN_PIPE1_ADDR = 0x12E60, + .DIFF_BTN_PIPE0_ADDR = 0x10E68, + .DIFF_BTN_PIPE1_ADDR = 0x12E68, + .READ_FLASH_CHECKSUM_ADDR = 0x14000, + .RW_FLASH_DATA_ADDR = 0x14002, + /* Phase 2 Host Download */ + .BOOT_RDY_ADDR = 0x1F141, + .POR_CD_ADDR = 0x1F61C, + /* BLD CRC */ + .R_ILM_CHECKSUM_ADDR = 0x1BF00, +}; + +static const struct nvt_ts_mem_map NT36525_memory_map = { + .EVENT_BUF_ADDR = 0x11A00, + .RAW_PIPE0_ADDR = 0x10000, + .RAW_PIPE1_ADDR = 0x12000, + .BASELINE_ADDR = 0x10B08, + .BASELINE_BTN_ADDR = 0x12B08, + .DIFF_PIPE0_ADDR = 0x1064C, + .DIFF_PIPE1_ADDR = 0x1264C, + .RAW_BTN_PIPE0_ADDR = 0x10634, + .RAW_BTN_PIPE1_ADDR = 0x12634, + .DIFF_BTN_PIPE0_ADDR = 0x10AFC, + .DIFF_BTN_PIPE1_ADDR = 0x12AFC, + .READ_FLASH_CHECKSUM_ADDR = 0x14000, + .RW_FLASH_DATA_ADDR = 0x14002, + /* Phase 2 Host Download */ + .BOOT_RDY_ADDR = 0x1F141, + .POR_CD_ADDR = 0x1F61C, + /* BLD CRC */ + .R_ILM_CHECKSUM_ADDR = 0x1BF00, +}; + +static const struct nvt_ts_mem_map NT36676F_memory_map = { + .EVENT_BUF_ADDR = 0x11A00, + .RAW_PIPE0_ADDR = 0x10000, + .RAW_PIPE1_ADDR = 0x12000, + .BASELINE_ADDR = 0x10B08, + .BASELINE_BTN_ADDR = 0x12B08, + .DIFF_PIPE0_ADDR = 0x1064C, + .DIFF_PIPE1_ADDR = 0x1264C, + .RAW_BTN_PIPE0_ADDR = 0x10634, + .RAW_BTN_PIPE1_ADDR = 0x12634, + .DIFF_BTN_PIPE0_ADDR = 0x10AFC, + .DIFF_BTN_PIPE1_ADDR = 0x12AFC, + .READ_FLASH_CHECKSUM_ADDR = 0x14000, + .RW_FLASH_DATA_ADDR = 0x14002, +}; + +static struct nvt_ts_hw_info NT36523_hw_info = { + .carrier_system = 2, + .hw_crc = 2, +}; + +static struct nvt_ts_hw_info NT36526_hw_info = { + .carrier_system = 2, + .hw_crc = 2, +}; + +static struct nvt_ts_hw_info NT36675_hw_info = { + .carrier_system = 2, + .hw_crc = 2, +}; + +static struct nvt_ts_hw_info NT36672A_hw_info = { + .carrier_system = 0, + .hw_crc = 1, +}; + +static struct nvt_ts_hw_info NT36772_hw_info = { + .carrier_system = 0, + .hw_crc = 0, +}; + +static struct nvt_ts_hw_info NT36525_hw_info = { + .carrier_system = 0, + .hw_crc = 0, +}; + +static struct nvt_ts_hw_info NT36676F_hw_info = { + .carrier_system = 0, + .hw_crc = 0, +}; + +#define NVT_ID_BYTE_MAX 6 +struct nvt_ts_trim_id_table { + uint8_t id[NVT_ID_BYTE_MAX]; + uint8_t mask[NVT_ID_BYTE_MAX]; + const struct nvt_ts_mem_map *mmap; + const struct nvt_ts_hw_info *hwinfo; +}; + +static const struct nvt_ts_trim_id_table trim_id_table[] = { + { .id = { 0x20, 0xFF, 0xFF, 0x23, 0x65, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36523_memory_map, + .hwinfo = &NT36523_hw_info }, + { .id = { 0x0C, 0xFF, 0xFF, 0x23, 0x65, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36523_memory_map, + .hwinfo = &NT36523_hw_info }, + { .id = { 0x0B, 0xFF, 0xFF, 0x23, 0x65, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36523_memory_map, + .hwinfo = &NT36523_hw_info }, + { .id = { 0x0A, 0xFF, 0xFF, 0x23, 0x65, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36523_memory_map, + .hwinfo = &NT36523_hw_info }, + { .id = { 0xFF, 0xFF, 0xFF, 0x23, 0x65, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36523_memory_map, + .hwinfo = &NT36523_hw_info }, + { .id = { 0x0C, 0xFF, 0xFF, 0x72, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36675_memory_map, + .hwinfo = &NT36675_hw_info }, + { .id = { 0xFF, 0xFF, 0xFF, 0x26, 0x65, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36526_memory_map, + .hwinfo = &NT36526_hw_info }, + { .id = { 0xFF, 0xFF, 0xFF, 0x75, 0x66, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36675_memory_map, + .hwinfo = &NT36675_hw_info }, + { .id = { 0x0B, 0xFF, 0xFF, 0x72, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info }, + { .id = { 0x0B, 0xFF, 0xFF, 0x82, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info }, + { .id = { 0x0B, 0xFF, 0xFF, 0x25, 0x65, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info }, + { .id = { 0x0A, 0xFF, 0xFF, 0x72, 0x65, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info }, + { .id = { 0x0A, 0xFF, 0xFF, 0x72, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info }, + { .id = { 0x0A, 0xFF, 0xFF, 0x82, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info }, + { .id = { 0x0A, 0xFF, 0xFF, 0x70, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info }, + { .id = { 0x0B, 0xFF, 0xFF, 0x70, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info }, + { .id = { 0x0A, 0xFF, 0xFF, 0x72, 0x67, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info }, + { .id = { 0x55, 0x00, 0xFF, 0x00, 0x00, 0x00 }, + .mask = { 1, 1, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info }, + { .id = { 0x55, 0x72, 0xFF, 0x00, 0x00, 0x00 }, + .mask = { 1, 1, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info }, + { .id = { 0xAA, 0x00, 0xFF, 0x00, 0x00, 0x00 }, + .mask = { 1, 1, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info }, + { .id = { 0xAA, 0x72, 0xFF, 0x00, 0x00, 0x00 }, + .mask = { 1, 1, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info }, + { .id = { 0xFF, 0xFF, 0xFF, 0x72, 0x67, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info }, + { .id = { 0xFF, 0xFF, 0xFF, 0x70, 0x66, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info }, + { .id = { 0xFF, 0xFF, 0xFF, 0x70, 0x67, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info }, + { .id = { 0xFF, 0xFF, 0xFF, 0x72, 0x66, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info }, + { .id = { 0xFF, 0xFF, 0xFF, 0x25, 0x65, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36525_memory_map, + .hwinfo = &NT36525_hw_info }, + { .id = { 0xFF, 0xFF, 0xFF, 0x76, 0x66, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36676F_memory_map, + .hwinfo = &NT36676F_hw_info } +}; diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_mp_ctrlram.c b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_mp_ctrlram.c new file mode 100644 index 000000000000..91bf34c77526 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_mp_ctrlram.c @@ -0,0 +1,4254 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * $Revision: 60182 $ + * $Date: 2020-04-13 10:07:31 +0800 (週一, 13 四月 2020) $ + * + * 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. + * + */ + +#include +#include +#include +#include +#include + +#include "nt36xxx.h" +#include "nt36xxx_mp_ctrlram.h" + +#if NVT_TOUCH_MP + +#define NORMAL_MODE 0x00 +#define TEST_MODE_1 0x21 +#define TEST_MODE_2 0x22 +#define MP_MODE_CC 0x41 +#define FREQ_HOP_DISABLE 0x66 +#define FREQ_HOP_ENABLE 0x65 + +#define NVT_RESULT_INVALID 0 +#define NVT_RESULT_PASS 2 +#define NVT_RESULT_FAIL 1 + +#define SHORT_TEST_CSV_FILE "/data/misc/tp_selftest_data/ShortTest.csv" +#define OPEN_TEST_CSV_FILE "/data/misc/tp_selftest_data/OpenTest.csv" +#define FW_RAWDATA_CSV_FILE "/data/misc/tp_selftest_data/FWMutualTest.csv" +#define FW_CC_CSV_FILE "/data/misc/tp_selftest_data/FWCCTest.csv" +#define NOISE_TEST_CSV_FILE "/data/misc/tp_selftest_data/NoiseTest.csv" +#define PEN_FW_RAW_TEST_CSV_FILE "/data/misc/tp_selftest_data/PenFWRawTest.csv" +#define PEN_NOISE_TEST_CSV_FILE "/data/misc/tp_selftest_data/PenNoiseTest.csv" + +#define nvt_mp_seq_printf(m, fmt, args...) \ + do { \ + seq_printf(m, fmt, ##args); \ + if (!nvt_mp_test_result_printed) \ + printk(fmt, ##args); \ + } while (0) + +static uint8_t *RecordResult_Short = NULL; +static uint8_t *RecordResult_Open = NULL; +static uint8_t *RecordResult_FWMutual = NULL; +static uint8_t *RecordResult_FW_CC = NULL; +static uint8_t *RecordResult_FW_DiffMax = NULL; +static uint8_t *RecordResult_FW_DiffMin = NULL; +static uint8_t *RecordResult_PenTipX_Raw = NULL; +static uint8_t *RecordResult_PenTipY_Raw = NULL; +static uint8_t *RecordResult_PenRingX_Raw = NULL; +static uint8_t *RecordResult_PenRingY_Raw = NULL; +static uint8_t *RecordResult_PenTipX_DiffMax = NULL; +static uint8_t *RecordResult_PenTipX_DiffMin = NULL; +static uint8_t *RecordResult_PenTipY_DiffMax = NULL; +static uint8_t *RecordResult_PenTipY_DiffMin = NULL; +static uint8_t *RecordResult_PenRingX_DiffMax = NULL; +static uint8_t *RecordResult_PenRingX_DiffMin = NULL; +static uint8_t *RecordResult_PenRingY_DiffMax = NULL; +static uint8_t *RecordResult_PenRingY_DiffMin = NULL; + +static int32_t TestResult_Short = 0; +static int32_t TestResult_Open = 0; +static int32_t TestResult_FW_Rawdata = 0; +static int32_t TestResult_FWMutual = 0; +static int32_t TestResult_FW_CC = 0; +static int32_t TestResult_Noise = 0; +static int32_t TestResult_FW_DiffMax = 0; +static int32_t TestResult_FW_DiffMin = 0; +static int32_t TestResult_Pen_FW_Raw = 0; +static int32_t TestResult_PenTipX_Raw = 0; +static int32_t TestResult_PenTipY_Raw = 0; +static int32_t TestResult_PenRingX_Raw = 0; +static int32_t TestResult_PenRingY_Raw = 0; +static int32_t TestResult_Pen_Noise = 0; +static int32_t TestResult_PenTipX_DiffMax = 0; +static int32_t TestResult_PenTipX_DiffMin = 0; +static int32_t TestResult_PenTipY_DiffMax = 0; +static int32_t TestResult_PenTipY_DiffMin = 0; +static int32_t TestResult_PenRingX_DiffMax = 0; +static int32_t TestResult_PenRingX_DiffMin = 0; +static int32_t TestResult_PenRingY_DiffMax = 0; +static int32_t TestResult_PenRingY_DiffMin = 0; + +static int32_t *RawData_Short = NULL; +static int32_t *RawData_Open = NULL; +static int32_t *RawData_Diff = NULL; +static int32_t *RawData_Diff_Min = NULL; +static int32_t *RawData_Diff_Max = NULL; +static int32_t *RawData_FWMutual = NULL; +static int32_t *RawData_FW_CC = NULL; +static int32_t *RawData_PenTipX_Raw = NULL; +static int32_t *RawData_PenTipY_Raw = NULL; +static int32_t *RawData_PenRingX_Raw = NULL; +static int32_t *RawData_PenRingY_Raw = NULL; +static int32_t *RawData_PenTipX_DiffMin = NULL; +static int32_t *RawData_PenTipX_DiffMax = NULL; +static int32_t *RawData_PenTipY_DiffMin = NULL; +static int32_t *RawData_PenTipY_DiffMax = NULL; +static int32_t *RawData_PenRingX_DiffMin = NULL; +static int32_t *RawData_PenRingX_DiffMax = NULL; +static int32_t *RawData_PenRingY_DiffMin = NULL; +static int32_t *RawData_PenRingY_DiffMax = NULL; + +static struct proc_dir_entry *NVT_proc_selftest_entry = NULL; +static struct proc_dir_entry *NVT_proc_aftersales_test_entry; +#ifndef NVT_SAVE_TESTDATA_IN_FILE +static struct proc_dir_entry *NVT_proc_test_data_entry = NULL; +#endif + +static int8_t nvt_mp_test_result_printed = 0; +static uint8_t fw_ver = 0; + +extern void nvt_change_mode(uint8_t mode); +extern uint8_t nvt_get_fw_pipe(void); +extern void nvt_read_mdata(uint32_t xdata_addr, uint32_t xdata_btn_addr); +extern void nvt_get_mdata(int32_t *buf, uint8_t *m_x_num, uint8_t *m_y_num); +extern void nvt_read_get_num_mdata(uint32_t xdata_addr, int32_t *buffer, + uint32_t num); +int32_t nvt_mp_parse_dt(struct device_node *root, const char *node_compatible); + +/******************************************************* +Description: + Novatek touchscreen allocate buffer for mp selftest. + +return: + Executive outcomes. 0---succeed. -12---Out of memory +*******************************************************/ +static int nvt_mp_buffer_init(void) +{ + size_t RecordResult_BufSize = + IC_X_CFG_SIZE * IC_Y_CFG_SIZE + IC_KEY_CFG_SIZE; + size_t RawData_BufSize = + (IC_X_CFG_SIZE * IC_Y_CFG_SIZE + IC_KEY_CFG_SIZE) * + sizeof(int32_t); + size_t Pen_RecordResult_BufSize = + max(ts->x_num * ts->y_gang_num, ts->x_gang_num * ts->y_num); + size_t Pen_RawData_BufSize = + max(ts->x_num * ts->y_gang_num, ts->x_gang_num * ts->y_num) * + sizeof(int32_t); + + RecordResult_Short = + (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_Short) { + NVT_ERR("kzalloc for RecordResult_Short failed!\n"); + return -ENOMEM; + } + + RecordResult_Open = + (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_Open) { + NVT_ERR("kzalloc for RecordResult_Open failed!\n"); + return -ENOMEM; + } + + RecordResult_FWMutual = + (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_FWMutual) { + NVT_ERR("kzalloc for RecordResult_FWMutual failed!\n"); + return -ENOMEM; + } + + RecordResult_FW_CC = + (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_FW_CC) { + NVT_ERR("kzalloc for RecordResult_FW_CC failed!\n"); + return -ENOMEM; + } + + RecordResult_FW_DiffMax = + (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_FW_DiffMax) { + NVT_ERR("kzalloc for RecordResult_FW_DiffMax failed!\n"); + return -ENOMEM; + } + + RecordResult_FW_DiffMin = + (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_FW_DiffMin) { + NVT_ERR("kzalloc for RecordResult_FW_DiffMin failed!\n"); + return -ENOMEM; + } + + if (ts->pen_support) { + RecordResult_PenTipX_Raw = (uint8_t *)kzalloc( + Pen_RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_PenTipX_Raw) { + NVT_ERR("kzalloc for RecordResult_PenTipX_Raw failed!\n"); + return -ENOMEM; + } + + RecordResult_PenTipY_Raw = (uint8_t *)kzalloc( + Pen_RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_PenTipY_Raw) { + NVT_ERR("kzalloc for RecordResult_PenTipY_Raw failed!\n"); + return -ENOMEM; + } + + RecordResult_PenRingX_Raw = (uint8_t *)kzalloc( + Pen_RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_PenRingX_Raw) { + NVT_ERR("kzalloc for RecordResult_PenRingX_Raw failed!\n"); + return -ENOMEM; + } + + RecordResult_PenRingY_Raw = (uint8_t *)kzalloc( + Pen_RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_PenRingY_Raw) { + NVT_ERR("kzalloc for RecordResult_PenRingY_Raw failed!\n"); + return -ENOMEM; + } + + RecordResult_PenTipX_DiffMax = (uint8_t *)kzalloc( + Pen_RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_PenTipX_DiffMax) { + NVT_ERR("kzalloc for RecordResult_PenTipX_DiffMax failed!\n"); + return -ENOMEM; + } + + RecordResult_PenTipX_DiffMin = (uint8_t *)kzalloc( + Pen_RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_PenTipX_DiffMin) { + NVT_ERR("kzalloc for RecordResult_PenTipX_DiffMin failed!\n"); + return -ENOMEM; + } + + RecordResult_PenTipY_DiffMax = (uint8_t *)kzalloc( + Pen_RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_PenTipY_DiffMax) { + NVT_ERR("kzalloc for RecordResult_PenTipY_DiffMax failed!\n"); + return -ENOMEM; + } + + RecordResult_PenTipY_DiffMin = (uint8_t *)kzalloc( + Pen_RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_PenTipY_DiffMin) { + NVT_ERR("kzalloc for RecordResult_PenTipY_DiffMin failed!\n"); + return -ENOMEM; + } + + RecordResult_PenRingX_DiffMax = (uint8_t *)kzalloc( + Pen_RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_PenRingX_DiffMax) { + NVT_ERR("kzalloc for RecordResult_PenRingX_DiffMax failed!\n"); + return -ENOMEM; + } + + RecordResult_PenRingX_DiffMin = (uint8_t *)kzalloc( + Pen_RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_PenRingX_DiffMin) { + NVT_ERR("kzalloc for RecordResult_PenRingX_DiffMin failed!\n"); + return -ENOMEM; + } + + RecordResult_PenRingY_DiffMax = (uint8_t *)kzalloc( + Pen_RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_PenRingY_DiffMax) { + NVT_ERR("kzalloc for RecordResult_PenRingY_DiffMax failed!\n"); + return -ENOMEM; + } + + RecordResult_PenRingY_DiffMin = (uint8_t *)kzalloc( + Pen_RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_PenRingY_DiffMin) { + NVT_ERR("kzalloc for RecordResult_PenRingY_DiffMin failed!\n"); + return -ENOMEM; + } + } /* if (ts->pen_support) */ + + RawData_Short = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_Short) { + NVT_ERR("kzalloc for RawData_Short failed!\n"); + return -ENOMEM; + } + + RawData_Open = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_Open) { + NVT_ERR("kzalloc for RawData_Open failed!\n"); + return -ENOMEM; + } + + RawData_Diff = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_Diff) { + NVT_ERR("kzalloc for RawData_Diff failed!\n"); + return -ENOMEM; + } + + RawData_Diff_Min = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_Diff_Min) { + NVT_ERR("kzalloc for RawData_Diff_Min failed!\n"); + return -ENOMEM; + } + + RawData_Diff_Max = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_Diff_Max) { + NVT_ERR("kzalloc for RawData_Diff_Max failed!\n"); + return -ENOMEM; + } + + RawData_FWMutual = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_FWMutual) { + NVT_ERR("kzalloc for RawData_FWMutual failed!\n"); + return -ENOMEM; + } + + RawData_FW_CC = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_FW_CC) { + NVT_ERR("kzalloc for RawData_FW_CC failed!\n"); + return -ENOMEM; + } + + if (ts->pen_support) { + RawData_PenTipX_Raw = + (int32_t *)kzalloc(Pen_RawData_BufSize, GFP_KERNEL); + if (!RawData_PenTipX_Raw) { + NVT_ERR("kzalloc for RawData_PenTipX_Raw failed!\n"); + return -ENOMEM; + } + + RawData_PenTipY_Raw = + (int32_t *)kzalloc(Pen_RawData_BufSize, GFP_KERNEL); + if (!RawData_PenTipY_Raw) { + NVT_ERR("kzalloc for RawData_PenTipY_Raw failed!\n"); + return -ENOMEM; + } + + RawData_PenRingX_Raw = + (int32_t *)kzalloc(Pen_RawData_BufSize, GFP_KERNEL); + if (!RawData_PenRingX_Raw) { + NVT_ERR("kzalloc for RawData_PenRingX_Raw failed!\n"); + return -ENOMEM; + } + + RawData_PenRingY_Raw = + (int32_t *)kzalloc(Pen_RawData_BufSize, GFP_KERNEL); + if (!RawData_PenRingY_Raw) { + NVT_ERR("kzalloc for RawData_PenRingY_Raw failed!\n"); + return -ENOMEM; + } + + RawData_PenTipX_DiffMax = + (int32_t *)kzalloc(Pen_RawData_BufSize, GFP_KERNEL); + if (!RawData_PenTipX_DiffMax) { + NVT_ERR("kzalloc for RawData_PenTipX_DiffMax failed!\n"); + return -ENOMEM; + } + + RawData_PenTipX_DiffMin = + (int32_t *)kzalloc(Pen_RawData_BufSize, GFP_KERNEL); + if (!RawData_PenTipX_DiffMin) { + NVT_ERR("kzalloc for RawData_PenTipX_DiffMin failed!\n"); + return -ENOMEM; + } + + RawData_PenTipY_DiffMax = + (int32_t *)kzalloc(Pen_RawData_BufSize, GFP_KERNEL); + if (!RawData_PenTipY_DiffMax) { + NVT_ERR("kzalloc for RawData_PenTipY_DiffMax failed!\n"); + return -ENOMEM; + } + + RawData_PenTipY_DiffMin = + (int32_t *)kzalloc(Pen_RawData_BufSize, GFP_KERNEL); + if (!RawData_PenTipY_DiffMin) { + NVT_ERR("kzalloc for RawData_PenTipY_DiffMin failed!\n"); + return -ENOMEM; + } + + RawData_PenRingX_DiffMax = + (int32_t *)kzalloc(Pen_RawData_BufSize, GFP_KERNEL); + if (!RawData_PenRingX_DiffMax) { + NVT_ERR("kzalloc for RawData_PenRingX_DiffMax failed!\n"); + return -ENOMEM; + } + + RawData_PenRingX_DiffMin = + (int32_t *)kzalloc(Pen_RawData_BufSize, GFP_KERNEL); + if (!RawData_PenRingX_DiffMin) { + NVT_ERR("kzalloc for RawData_PenRingX_DiffMin failed!\n"); + return -ENOMEM; + } + + RawData_PenRingY_DiffMax = + (int32_t *)kzalloc(Pen_RawData_BufSize, GFP_KERNEL); + if (!RawData_PenRingY_DiffMax) { + NVT_ERR("kzalloc for RawData_PenRingY_DiffMax failed!\n"); + return -ENOMEM; + } + + RawData_PenRingY_DiffMin = + (int32_t *)kzalloc(Pen_RawData_BufSize, GFP_KERNEL); + if (!RawData_PenRingY_DiffMin) { + NVT_ERR("kzalloc for RawData_PenRingY_DiffMin failed!\n"); + return -ENOMEM; + } + } /* if (ts->pen_support) */ + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen free buffer for mp selftest. + +return: + n.a. +*******************************************************/ +static void nvt_mp_buffer_deinit(void) +{ + if (RecordResult_Short) { + kfree(RecordResult_Short); + RecordResult_Short = NULL; + } + + if (RecordResult_Open) { + kfree(RecordResult_Open); + RecordResult_Open = NULL; + } + + if (RecordResult_FWMutual) { + kfree(RecordResult_FWMutual); + RecordResult_FWMutual = NULL; + } + + if (RecordResult_FW_CC) { + kfree(RecordResult_FW_CC); + RecordResult_FW_CC = NULL; + } + + if (RecordResult_FW_DiffMax) { + kfree(RecordResult_FW_DiffMax); + RecordResult_FW_DiffMax = NULL; + } + + if (RecordResult_FW_DiffMin) { + kfree(RecordResult_FW_DiffMin); + RecordResult_FW_DiffMin = NULL; + } + + if (ts->pen_support) { + if (RecordResult_PenTipX_Raw) { + kfree(RecordResult_PenTipX_Raw); + RecordResult_PenTipX_Raw = NULL; + } + + if (RecordResult_PenTipY_Raw) { + kfree(RecordResult_PenTipY_Raw); + RecordResult_PenTipY_Raw = NULL; + } + + if (RecordResult_PenRingX_Raw) { + kfree(RecordResult_PenRingX_Raw); + RecordResult_PenRingX_Raw = NULL; + } + + if (RecordResult_PenRingY_Raw) { + kfree(RecordResult_PenRingY_Raw); + RecordResult_PenRingY_Raw = NULL; + } + + if (RecordResult_PenTipX_DiffMax) { + kfree(RecordResult_PenTipX_DiffMax); + RecordResult_PenTipX_DiffMax = NULL; + } + + if (RecordResult_PenTipX_DiffMin) { + kfree(RecordResult_PenTipX_DiffMin); + RecordResult_PenTipX_DiffMin = NULL; + } + + if (RecordResult_PenTipY_DiffMax) { + kfree(RecordResult_PenTipY_DiffMax); + RecordResult_PenTipY_DiffMax = NULL; + } + + if (RecordResult_PenTipY_DiffMin) { + kfree(RecordResult_PenTipY_DiffMin); + RecordResult_PenTipY_DiffMin = NULL; + } + + if (RecordResult_PenRingX_DiffMax) { + kfree(RecordResult_PenRingX_DiffMax); + RecordResult_PenRingX_DiffMax = NULL; + } + + if (RecordResult_PenRingX_DiffMin) { + kfree(RecordResult_PenRingX_DiffMin); + RecordResult_PenRingX_DiffMin = NULL; + } + + if (RecordResult_PenRingY_DiffMax) { + kfree(RecordResult_PenRingY_DiffMax); + RecordResult_PenRingY_DiffMax = NULL; + } + + if (RecordResult_PenRingY_DiffMin) { + kfree(RecordResult_PenRingY_DiffMin); + RecordResult_PenRingY_DiffMin = NULL; + } + } /* if (ts->pen_support) */ + + if (RawData_Short) { + kfree(RawData_Short); + RawData_Short = NULL; + } + + if (RawData_Open) { + kfree(RawData_Open); + RawData_Open = NULL; + } + + if (RawData_Diff) { + kfree(RawData_Diff); + RawData_Diff = NULL; + } + + if (RawData_Diff_Min) { + kfree(RawData_Diff_Min); + RawData_Diff_Min = NULL; + } + + if (RawData_Diff_Max) { + kfree(RawData_Diff_Max); + RawData_Diff_Max = NULL; + } + + if (RawData_FWMutual) { + kfree(RawData_FWMutual); + RawData_FWMutual = NULL; + } + + if (RawData_FW_CC) { + kfree(RawData_FW_CC); + RawData_FW_CC = NULL; + } + + if (ts->pen_support) { + if (RawData_PenTipX_Raw) { + kfree(RawData_PenTipX_Raw); + RawData_PenTipX_Raw = NULL; + } + + if (RawData_PenTipY_Raw) { + kfree(RawData_PenTipY_Raw); + RawData_PenTipY_Raw = NULL; + } + + if (RawData_PenRingX_Raw) { + kfree(RawData_PenRingX_Raw); + RawData_PenRingX_Raw = NULL; + } + + if (RawData_PenRingY_Raw) { + kfree(RawData_PenRingY_Raw); + RawData_PenRingY_Raw = NULL; + } + + if (RawData_PenTipX_DiffMax) { + kfree(RawData_PenTipX_DiffMax); + RawData_PenTipX_DiffMax = NULL; + } + + if (RawData_PenTipX_DiffMin) { + kfree(RawData_PenTipX_DiffMin); + RawData_PenTipX_DiffMin = NULL; + } + + if (RawData_PenTipY_DiffMax) { + kfree(RawData_PenTipY_DiffMax); + RawData_PenTipY_DiffMax = NULL; + } + + if (RawData_PenTipY_DiffMin) { + kfree(RawData_PenTipY_DiffMin); + RawData_PenTipY_DiffMin = NULL; + } + + if (RawData_PenRingX_DiffMax) { + kfree(RawData_PenRingX_DiffMax); + RawData_PenRingX_DiffMax = NULL; + } + + if (RawData_PenRingX_DiffMin) { + kfree(RawData_PenRingX_DiffMin); + RawData_PenRingX_DiffMin = NULL; + } + + if (RawData_PenRingY_DiffMax) { + kfree(RawData_PenRingY_DiffMax); + RawData_PenRingY_DiffMax = NULL; + } + + if (RawData_PenRingY_DiffMin) { + kfree(RawData_PenRingY_DiffMin); + RawData_PenRingY_DiffMin = NULL; + } + } /* if (ts->pen_support) */ +} + +static void nvt_print_data_log_in_one_line(int32_t *data, int32_t data_num) +{ + char *tmp_log = NULL; + int32_t i = 0; + + tmp_log = (char *)kzalloc(data_num * 7 + 1, GFP_KERNEL); + if (!tmp_log) { + NVT_ERR("kzalloc for tmp_log failed!\n "); + return; + } + + for (i = 0; i < data_num; i++) { + sprintf(tmp_log + i * 7, "%5d, ", data[i]); + } + tmp_log[data_num * 7] = '\0'; + printk("%s", tmp_log); + if (tmp_log) { + kfree(tmp_log); + tmp_log = NULL; + } + + return; +} + +static void nvt_print_result_log_in_one_line(uint8_t *result, + int32_t result_num) +{ + char *tmp_log = NULL; + int32_t i = 0; + + tmp_log = (char *)kzalloc(result_num * 6 + 1, GFP_KERNEL); + if (!tmp_log) { + NVT_ERR("kzalloc for tmp_log failed!\n "); + return; + } + + for (i = 0; i < result_num; i++) { + sprintf(tmp_log + i * 6, "0x%02X, ", result[i]); + } + tmp_log[result_num * 6] = '\0'; + printk("%s", tmp_log); + if (tmp_log) { + kfree(tmp_log); + tmp_log = NULL; + } + + return; +} + +/******************************************************* +Description: + Novatek touchscreen self-test criteria print function. + +return: + n.a. +*******************************************************/ +static void nvt_print_lmt_array(int32_t *array, int32_t x_ch, int32_t y_ch) +{ + int32_t j = 0; + + for (j = 0; j < y_ch; j++) { + nvt_print_data_log_in_one_line(array + j * x_ch, x_ch); + printk("\n"); + } +#if TOUCH_KEY_NUM > 0 + nvt_print_data_log_in_one_line(array + y_ch * x_ch, Key_Channel); + printk("\n"); +#endif /* #if TOUCH_KEY_NUM > 0 */ +} + +static void nvt_print_criteria(void) +{ + NVT_LOG("++\n"); + + //---PS_Config_Lmt_Short_Rawdata--- + printk("PS_Config_Lmt_Short_Rawdata_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_Short_Rawdata_P, X_Channel, + Y_Channel); + printk("PS_Config_Lmt_Short_Rawdata_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_Short_Rawdata_N, X_Channel, + Y_Channel); + + //---PS_Config_Lmt_Open_Rawdata--- + printk("PS_Config_Lmt_Open_Rawdata_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_Open_Rawdata_P, X_Channel, Y_Channel); + printk("PS_Config_Lmt_Open_Rawdata_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_Open_Rawdata_N, X_Channel, Y_Channel); + + //---PS_Config_Lmt_FW_Rawdata--- + printk("PS_Config_Lmt_FW_Rawdata_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_FW_Rawdata_P, X_Channel, Y_Channel); + printk("PS_Config_Lmt_FW_Rawdata_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_FW_Rawdata_N, X_Channel, Y_Channel); + + //---PS_Config_Lmt_FW_CC--- + printk("PS_Config_Lmt_FW_CC_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_FW_CC_P, X_Channel, Y_Channel); + printk("PS_Config_Lmt_FW_CC_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_FW_CC_N, X_Channel, Y_Channel); + + //---PS_Config_Lmt_FW_Diff--- + printk("PS_Config_Lmt_FW_Diff_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_FW_Diff_P, X_Channel, Y_Channel); + printk("PS_Config_Lmt_FW_Diff_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_FW_Diff_N, X_Channel, Y_Channel); + + if (ts->pen_support) { + //---PS_Config_Lmt_PenTipX_FW_Raw--- + printk("PS_Config_Lmt_PenTipX_FW_Raw_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenTipX_FW_Raw_P, ts->x_num, + ts->y_gang_num); + printk("PS_Config_Lmt_PenTipX_FW_Raw_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenTipX_FW_Raw_N, ts->x_num, + ts->y_gang_num); + + //---PS_Config_Lmt_PenTipY_FW_Raw--- + printk("PS_Config_Lmt_PenTipY_FW_Raw_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenTipY_FW_Raw_P, + ts->x_gang_num, ts->y_num); + printk("PS_Config_Lmt_PenTipY_FW_Raw_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenTipY_FW_Raw_N, + ts->x_gang_num, ts->y_num); + + //---PS_Config_Lmt_PenRingX_FW_Raw--- + printk("PS_Config_Lmt_PenRingX_FW_Raw_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenRingX_FW_Raw_P, ts->x_num, + ts->y_gang_num); + printk("PS_Config_Lmt_PenRingX_FW_Raw_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenRingX_FW_Raw_N, ts->x_num, + ts->y_gang_num); + + //---PS_Config_Lmt_PenRingY_FW_Raw--- + printk("PS_Config_Lmt_PenRingY_FW_Raw_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenRingY_FW_Raw_P, + ts->x_gang_num, ts->y_num); + printk("PS_Config_Lmt_PenRingY_FW_Raw_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenRingY_FW_Raw_N, + ts->x_gang_num, ts->y_num); + + //---PS_Config_Lmt_PenTipX_FW_Diff--- + printk("PS_Config_Lmt_PenTipX_FW_Diff_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenTipX_FW_Diff_P, ts->x_num, + ts->y_gang_num); + printk("PS_Config_Lmt_PenTipX_FW_Diff_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenTipX_FW_Diff_N, ts->x_num, + ts->y_gang_num); + + //---PS_Config_Lmt_PenTipY_FW_Diff--- + printk("PS_Config_Lmt_PenTipY_FW_Diff_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenTipY_FW_Diff_P, + ts->x_gang_num, ts->y_num); + printk("PS_Config_Lmt_PenTipY_FW_Diff_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenTipY_FW_Diff_N, + ts->x_gang_num, ts->y_num); + + //---PS_Config_Lmt_PenRingX_FW_Diff--- + printk("PS_Config_Lmt_PenRingX_FW_Diff_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenRingX_FW_Diff_P, ts->x_num, + ts->y_gang_num); + printk("PS_Config_Lmt_PenRingX_FW_Diff_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenRingX_FW_Diff_N, ts->x_num, + ts->y_gang_num); + + //---PS_Config_Lmt_PenRingY_FW_Diff--- + printk("PS_Config_Lmt_PenRingY_FW_Diff_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenRingY_FW_Diff_P, + ts->x_gang_num, ts->y_num); + printk("PS_Config_Lmt_PenRingY_FW_Diff_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_PenRingY_FW_Diff_N, + ts->x_gang_num, ts->y_num); + } /* if (ts->pen_support) */ + + NVT_LOG("--\n"); +} + +#ifndef NVT_SAVE_TESTDATA_IN_FILE +void dump_buff(int32_t *rawdata, uint8_t x_ch, uint8_t y_ch) +{ + int32_t y = 0; + + for (y = 0; y < y_ch; y++) { + nvt_print_data_log_in_one_line(rawdata + y * x_ch, x_ch); + printk("\n"); + } +} +#endif + +static int32_t nvt_save_rawdata_to_csv(int32_t *rawdata, uint8_t x_ch, + uint8_t y_ch, const char *file_path, + uint32_t offset, enum test_type type) +{ +#ifdef NVT_SAVE_TESTDATA_IN_FILE + int32_t x = 0; + int32_t y = 0; + int32_t iArrayIndex = 0; + struct file *fp = NULL; + char *fbufp = NULL; + mm_segment_t org_fs; + int32_t write_ret = 0; + uint32_t output_len = 0; + loff_t pos = 0; +#if TOUCH_KEY_NUM > 0 + int32_t k = 0; + int32_t keydata_output_offset = 0; +#endif /* #if TOUCH_KEY_NUM > 0 */ +#else /*#ifdef NVT_SAVE_TESTDATA_IN_FILE*/ + struct test_buf *tbuf = ts->testdata; +#endif /*#ifdef NVT_SAVE_TESTDATA_IN_FILE*/ + + printk("%s:++\n", __func__); +#ifdef NVT_SAVE_TESTDATA_IN_FILE + fbufp = (char *)kzalloc(16384, GFP_KERNEL); + if (!fbufp) { + NVT_ERR("kzalloc for fbufp failed!\n"); + return -ENOMEM; + } + + for (y = 0; y < y_ch; y++) { + for (x = 0; x < x_ch; x++) { + iArrayIndex = y * x_ch + x; + sprintf(fbufp + iArrayIndex * 7 + y * 2, "%5d, ", + rawdata[iArrayIndex]); + } + nvt_print_data_log_in_one_line(rawdata + y * x_ch, x_ch); + printk("\n"); + sprintf(fbufp + (iArrayIndex + 1) * 7 + y * 2, "\r\n"); + } +#if TOUCH_KEY_NUM > 0 + keydata_output_offset = y_ch * x_ch * 7 + y_ch * 2; + for (k = 0; k < Key_Channel; k++) { + iArrayIndex = y_ch * x_ch + k; + sprintf(fbufp + keydata_output_offset + k * 7, "%5d, ", + rawdata[iArrayIndex]); + } + nvt_print_data_log_in_one_line(rawdata + y_ch * x_ch, Key_Channel); + printk("\n"); + sprintf(fbufp + y_ch * x_ch * 7 + y_ch * 2 + Key_Channel * 7, "\r\n"); +#endif /* #if TOUCH_KEY_NUM > 0 */ + + org_fs = get_fs(); + set_fs(KERNEL_DS); + fp = filp_open(file_path, O_RDWR | O_CREAT, 0644); + if (fp == NULL || IS_ERR(fp)) { + NVT_ERR("open %s failed\n", file_path); + set_fs(org_fs); + if (fbufp) { + kfree(fbufp); + fbufp = NULL; + } + return -1; + } + +#if TOUCH_KEY_NUM > 0 + output_len = y_ch * x_ch * 7 + y_ch * 2 + Key_Channel * 7 + 2; +#else + output_len = y_ch * x_ch * 7 + y_ch * 2; +#endif /* #if TOUCH_KEY_NUM > 0 */ + pos = offset; + write_ret = vfs_write(fp, (char __user *)fbufp, output_len, &pos); + if (write_ret <= 0) { + NVT_ERR("write %s failed\n", file_path); + set_fs(org_fs); + if (fp) { + filp_close(fp, NULL); + fp = NULL; + } + if (fbufp) { + kfree(fbufp); + fbufp = NULL; + } + return -1; + } + + set_fs(org_fs); + if (fp) { + filp_close(fp, NULL); + fp = NULL; + } + if (fbufp) { + kfree(fbufp); + fbufp = NULL; + } +#else /*#ifdef NVT_SAVE_TESTDATA_IN_FILE*/ + switch (type) { + case SHORT_TEST: + NVT_LOG("SHORT_TEST start copy TEST_BUF_LEN = %d", + TEST_BUF_LEN); + memset(tbuf->shorttest.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->shorttest.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->shorttest.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST(%p):=============\n", + tbuf->shorttest.buf); + dump_buff((int32_t *)tbuf->shorttest.buf, x_ch, y_ch); + NVT_LOG("SHORT_TEST copy complete"); + break; + case OPEN_TEST: + NVT_LOG("OPEN_TEST start copy"); + memset(tbuf->opentest.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->opentest.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->opentest.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST(%p):=============\n", + tbuf->opentest.buf); + dump_buff((int32_t *)tbuf->opentest.buf, x_ch, y_ch); + NVT_LOG("OPEN_TEST copy complete"); + break; + case FWMUTUAL_TEST: + NVT_LOG("FWMUTUAL_TEST start copy"); + memset(tbuf->fwmutualtest.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->fwmutualtest.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->fwmutualtest.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->fwmutualtest.buf, x_ch, y_ch); + NVT_LOG("FWMUTUAL_TEST copy complete"); + break; + case FWCC_TEST: + NVT_LOG("FWCC_TEST start copy"); + memset(tbuf->fwcctest.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->fwcctest.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->fwcctest.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->fwcctest.buf, x_ch, y_ch); + NVT_LOG("FWCC_TEST copy complete"); + break; + case NOISE_MAX_TEST: + NVT_LOG("NOISE_MAX_TEST start copy"); + memset(tbuf->noisetest_max.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->noisetest_max.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->noisetest_max.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->noisetest_max.buf, x_ch, y_ch); + NVT_LOG("NOISE_MAX_TEST copy complete"); + break; + case NOISE_MIN_TEST: + NVT_LOG("NOISE_MIN_TEST start copy"); + memset(tbuf->noisetest_min.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->noisetest_min.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->noisetest_min.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->noisetest_min.buf, x_ch, y_ch); + NVT_LOG("NOISE_MIN_TEST copy complete"); + break; + case PEN_TIPX_RAW: + NVT_LOG("PEN_TIPX_RAW start copy"); + memset(tbuf->pen_tipx_raw.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->pen_tipx_raw.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->pen_tipx_raw.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->pen_tipx_raw.buf, x_ch, y_ch); + NVT_LOG("PEN_TIPX_RAW copy complete"); + break; + case PEN_TIPY_RAW: + NVT_LOG("PEN_TIPY_RAW start copy"); + memset(tbuf->pen_tipy_raw.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->pen_tipy_raw.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->pen_tipy_raw.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->pen_tipy_raw.buf, x_ch, y_ch); + NVT_LOG("PEN_TIPY_RAW copy complete"); + break; + case PEN_RINGX_RAW: + NVT_LOG("PEN_RINGX_RAW start copy"); + memset(tbuf->pen_ringx_raw.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->pen_ringx_raw.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->pen_ringx_raw.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->pen_ringx_raw.buf, x_ch, y_ch); + NVT_LOG("PEN_RINGX_RAW copy complete"); + break; + case PEN_RINGY_RAW: + NVT_LOG("PEN_RINGY_RAW start copy"); + memset(tbuf->pen_ringy_raw.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->pen_ringy_raw.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->pen_ringy_raw.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->pen_ringy_raw.buf, x_ch, y_ch); + NVT_LOG("PEN_RINGY_RAW copy complete"); + break; + case PEN_TIPX_DIFFMAX: + NVT_LOG("PEN_TIPX_DIFFMAX start copy"); + memset(tbuf->pen_tipx_diffmax.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->pen_tipx_diffmax.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->pen_tipx_diffmax.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->pen_tipx_diffmax.buf, x_ch, y_ch); + NVT_LOG("PEN_TIPX_DIFFMAX copy complete"); + break; + case PEN_TIPX_DIFFMIN: + NVT_LOG("PEN_TIPX_DIFFMIN start copy"); + memset(tbuf->pen_tipx_diffmin.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->pen_tipx_diffmin.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->pen_tipx_diffmin.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->pen_tipx_diffmin.buf, x_ch, y_ch); + NVT_LOG("PEN_TIPX_DIFFMIN copy complete"); + break; + case PEN_TIPY_DIFFMAX: + NVT_LOG("PEN_TIPY_DIFFMAX start copy"); + memset(tbuf->pen_tipy_diffmax.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->pen_tipy_diffmax.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->pen_tipy_diffmax.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->pen_tipy_diffmax.buf, x_ch, y_ch); + NVT_LOG("PEN_TIPY_DIFFMAX copy complete"); + break; + case PEN_TIPY_DIFFMIN: + NVT_LOG("PEN_TIPY_DIFFMIN start copy"); + memset(tbuf->pen_tipy_diffmin.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->pen_tipy_diffmin.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->pen_tipy_diffmin.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->pen_tipy_diffmin.buf, x_ch, y_ch); + NVT_LOG("PEN_TIPY_DIFFMIN copy complete"); + break; + case PEN_RINGX_DIFFMAX: + NVT_LOG("PEN_RINGX_DIFFMAX start copy"); + memset(tbuf->pen_ringx_diffmax.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->pen_ringx_diffmax.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->pen_ringx_diffmax.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->pen_ringx_diffmax.buf, x_ch, y_ch); + NVT_LOG("PEN_RINGX_DIFFMAX copy complete"); + break; + case PEN_RINGX_DIFFMIN: + NVT_LOG("PEN_RINGX_DIFFMIN start copy"); + memset(tbuf->pen_ringx_diffmin.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->pen_ringx_diffmin.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->pen_ringx_diffmin.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->pen_ringx_diffmin.buf, x_ch, y_ch); + NVT_LOG("PEN_RINGX_DIFFMIN copy complete"); + break; + case PEN_RINGY_DIFFMAX: + NVT_LOG("PEN_RINGY_DIFFMAX start copy"); + memset(tbuf->pen_ringy_diffmax.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->pen_ringy_diffmax.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->pen_ringy_diffmax.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->pen_ringy_diffmax.buf, x_ch, y_ch); + NVT_LOG("PEN_RINGY_DIFFMAX copy complete"); + break; + case PEN_RINGY_DIFFMIN: + NVT_LOG("PEN_RINGY_DIFFMIN start copy"); + memset(tbuf->pen_ringy_diffmin.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->pen_ringy_diffmin.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->pen_ringy_diffmin.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->pen_ringy_diffmin.buf, x_ch, y_ch); + NVT_LOG("PEN_RINGY_DIFFMIN copy complete"); + break; + default: + NVT_ERR("test type is illegal"); + break; + } +#endif /*#ifdef NVT_SAVE_TESTDATA_IN_FILE*/ + printk("%s:--\n", __func__); + + return 0; +} + +static int32_t nvt_polling_hand_shake_status(void) +{ + uint8_t buf[8] = { 0 }; + int32_t i = 0; + const int32_t retry = 250; + + for (i = 0; i < retry; i++) { + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | + EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE); + + //---read fw status--- + buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; + buf[1] = 0x00; + CTP_SPI_READ(ts->client, buf, 2); + + if ((buf[1] == 0xA0) || (buf[1] == 0xA1)) + break; + + usleep_range(10000, 10000); + } + + if (i >= retry) { + NVT_ERR("polling hand shake status failed, buf[1]=0x%02X\n", + buf[1]); + + // Read back 5 bytes from offset EVENT_MAP_HOST_CMD for debug check + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + buf[5] = 0x00; + CTP_SPI_READ(ts->client, buf, 6); + NVT_ERR("Read back 5 bytes from offset EVENT_MAP_HOST_CMD: 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", + buf[1], buf[2], buf[3], buf[4], buf[5]); + + return -1; + } else { + return 0; + } +} + +static int8_t nvt_switch_FreqHopEnDis(uint8_t FreqHopEnDis) +{ + uint8_t buf[8] = { 0 }; + uint8_t retry = 0; + int8_t ret = 0; + + NVT_LOG("++\n"); + + for (retry = 0; retry < 20; retry++) { + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + //---switch FreqHopEnDis--- + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = FreqHopEnDis; + CTP_SPI_WRITE(ts->client, buf, 2); + + msleep(35); + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0xFF; + CTP_SPI_READ(ts->client, buf, 2); + + if (buf[1] == 0x00) + break; + } + + if (unlikely(retry == 20)) { + NVT_ERR("switch FreqHopEnDis 0x%02X failed, buf[1]=0x%02X\n", + FreqHopEnDis, buf[1]); + ret = -1; + } + + NVT_LOG("--\n"); + + return ret; +} + +static int32_t nvt_read_baseline(int32_t *xdata) +{ + uint8_t x_num = 0; + uint8_t y_num = 0; + uint32_t x = 0; + uint32_t y = 0; + int32_t iArrayIndex = 0; +#if TOUCH_KEY_NUM > 0 + int32_t k = 0; +#endif /* #if TOUCH_KEY_NUM > 0 */ + + NVT_LOG("++\n"); + + nvt_read_mdata(ts->mmap->BASELINE_ADDR, ts->mmap->BASELINE_BTN_ADDR); + + nvt_get_mdata(xdata, &x_num, &y_num); + + for (y = 0; y < y_num; y++) { + for (x = 0; x < x_num; x++) { + iArrayIndex = y * x_num + x; + xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex]; + } + } +#if TOUCH_KEY_NUM > 0 + for (k = 0; k < Key_Channel; k++) { + iArrayIndex = Y_Channel * X_Channel + k; + xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex]; + } +#endif /* #if TOUCH_KEY_NUM > 0 */ + + printk("%s:\n", __func__); + // Save Rawdata to CSV file + if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, + FW_RAWDATA_CSV_FILE, 0, + FWMUTUAL_TEST) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + + NVT_LOG("--\n"); + + return 0; +} + +static int32_t nvt_read_CC(int32_t *xdata) +{ + uint8_t x_num = 0; + uint8_t y_num = 0; + uint32_t x = 0; + uint32_t y = 0; + int32_t iArrayIndex = 0; +#if TOUCH_KEY_NUM > 0 + int32_t k = 0; +#endif /* #if TOUCH_KEY_NUM > 0 */ + + NVT_LOG("++\n"); + + if (nvt_get_fw_pipe() == 0) + nvt_read_mdata(ts->mmap->DIFF_PIPE1_ADDR, + ts->mmap->DIFF_BTN_PIPE1_ADDR); + else + nvt_read_mdata(ts->mmap->DIFF_PIPE0_ADDR, + ts->mmap->DIFF_BTN_PIPE0_ADDR); + + nvt_get_mdata(xdata, &x_num, &y_num); + + for (y = 0; y < y_num; y++) { + for (x = 0; x < x_num; x++) { + iArrayIndex = y * x_num + x; + xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex]; + } + } +#if TOUCH_KEY_NUM > 0 + for (k = 0; k < Key_Channel; k++) { + iArrayIndex = Y_Channel * X_Channel + k; + xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex]; + } +#endif /* #if TOUCH_KEY_NUM > 0 */ + + printk("%s:\n", __func__); + // Save Rawdata to CSV file + if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, FW_CC_CSV_FILE, + 0, FWCC_TEST) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + + NVT_LOG("--\n"); + + return 0; +} + +static int32_t nvt_read_pen_baseline(void) +{ + uint32_t csv_output_offset = 0; + + NVT_LOG("++\n"); + + nvt_read_get_num_mdata(ts->mmap->PEN_2D_BL_TIP_X_ADDR, + RawData_PenTipX_Raw, ts->x_num * ts->y_gang_num); + nvt_read_get_num_mdata(ts->mmap->PEN_2D_BL_TIP_Y_ADDR, + RawData_PenTipY_Raw, ts->x_gang_num * ts->y_num); + nvt_read_get_num_mdata(ts->mmap->PEN_2D_BL_RING_X_ADDR, + RawData_PenRingX_Raw, + ts->x_num * ts->y_gang_num); + nvt_read_get_num_mdata(ts->mmap->PEN_2D_BL_RING_Y_ADDR, + RawData_PenRingY_Raw, + ts->x_gang_num * ts->y_num); + + // Save Rawdata to CSV file + printk("%s:RawData_PenTipX_Raw\n", __func__); + if (nvt_save_rawdata_to_csv(RawData_PenTipX_Raw, ts->x_num, + ts->y_gang_num, PEN_FW_RAW_TEST_CSV_FILE, + csv_output_offset, PEN_TIPX_RAW) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + csv_output_offset += + ts->y_gang_num * ts->x_num * 7 + ts->y_gang_num * 2; + printk("%s:RawData_PenTipY_Raw\n", __func__); + if (nvt_save_rawdata_to_csv(RawData_PenTipY_Raw, ts->x_gang_num, + ts->y_num, PEN_FW_RAW_TEST_CSV_FILE, + csv_output_offset, PEN_TIPY_RAW) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + csv_output_offset += ts->y_num * ts->x_gang_num * 7 + ts->y_num * 2; + printk("%s:RawData_PenRingX_Raw\n", __func__); + if (nvt_save_rawdata_to_csv(RawData_PenRingX_Raw, ts->x_num, + ts->y_gang_num, PEN_FW_RAW_TEST_CSV_FILE, + csv_output_offset, PEN_RINGX_RAW) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + csv_output_offset += + ts->y_gang_num * ts->x_num * 7 + ts->y_gang_num * 2; + printk("%s:RawData_PenRingY_Raw\n", __func__); + if (nvt_save_rawdata_to_csv(RawData_PenRingY_Raw, ts->x_gang_num, + ts->y_num, PEN_FW_RAW_TEST_CSV_FILE, + csv_output_offset, PEN_RINGY_RAW) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + + NVT_LOG("--\n"); + + return 0; +} + +static void nvt_enable_noise_collect(int32_t frame_num) +{ + uint8_t buf[8] = { 0 }; + + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + //---enable noise collect--- + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x47; + buf[2] = 0xAA; + buf[3] = frame_num; + buf[4] = 0x00; + CTP_SPI_WRITE(ts->client, buf, 5); +} + +static int32_t nvt_read_fw_noise(int32_t *xdata) +{ + uint8_t x_num = 0; + uint8_t y_num = 0; + uint32_t x = 0; + uint32_t y = 0; + int32_t iArrayIndex = 0; + int32_t frame_num = 0; + uint32_t rawdata_diff_min_offset = 0; +#if TOUCH_KEY_NUM > 0 + int32_t k = 0; +#endif /* #if TOUCH_KEY_NUM > 0 */ + uint32_t csv_pen_noise_offset = 0; + + NVT_LOG("++\n"); + + //---Enter Test Mode--- + if (nvt_clear_fw_status()) { + return -EAGAIN; + } + + frame_num = PS_Config_Diff_Test_Frame / 10; + if (frame_num <= 0) + frame_num = 1; + printk("%s: frame_num=%d\n", __func__, frame_num); + nvt_enable_noise_collect(frame_num); + // need wait PS_Config_Diff_Test_Frame * 8.3ms + msleep(frame_num * 83); + + if (nvt_polling_hand_shake_status()) { + return -EAGAIN; + } + + if (nvt_get_fw_info()) { + return -EAGAIN; + } + + if (nvt_get_fw_pipe() == 0) + nvt_read_mdata(ts->mmap->DIFF_PIPE0_ADDR, + ts->mmap->DIFF_BTN_PIPE0_ADDR); + else + nvt_read_mdata(ts->mmap->DIFF_PIPE1_ADDR, + ts->mmap->DIFF_BTN_PIPE1_ADDR); + + nvt_get_mdata(xdata, &x_num, &y_num); + + for (y = 0; y < y_num; y++) { + for (x = 0; x < x_num; x++) { + iArrayIndex = y * x_num + x; + RawData_Diff_Max[iArrayIndex] = + (int8_t)((xdata[iArrayIndex] >> 8) & 0xFF); + RawData_Diff_Min[iArrayIndex] = + (int8_t)(xdata[iArrayIndex] & 0xFF); + } + } +#if TOUCH_KEY_NUM > 0 + for (k = 0; k < Key_Channel; k++) { + iArrayIndex = Y_Channel * X_Channel + k; + RawData_Diff_Max[iArrayIndex] = + (int8_t)((xdata[iArrayIndex] >> 8) & 0xFF); + RawData_Diff_Min[iArrayIndex] = + (int8_t)(xdata[iArrayIndex] & 0xFF); + } +#endif /* #if TOUCH_KEY_NUM > 0 */ + + if (ts->pen_support) { + // get pen noise data + nvt_read_get_num_mdata(ts->mmap->PEN_2D_DIFF_TIP_X_ADDR, + RawData_PenTipX_DiffMax, + ts->x_num * ts->y_gang_num); + nvt_read_get_num_mdata(ts->mmap->PEN_2D_RAW_TIP_X_ADDR, + RawData_PenTipX_DiffMin, + ts->x_num * ts->y_gang_num); + nvt_read_get_num_mdata(ts->mmap->PEN_2D_DIFF_TIP_Y_ADDR, + RawData_PenTipY_DiffMax, + ts->x_gang_num * ts->y_num); + nvt_read_get_num_mdata(ts->mmap->PEN_2D_RAW_TIP_Y_ADDR, + RawData_PenTipY_DiffMin, + ts->x_gang_num * ts->y_num); + nvt_read_get_num_mdata(ts->mmap->PEN_2D_DIFF_RING_X_ADDR, + RawData_PenRingX_DiffMax, + ts->x_num * ts->y_gang_num); + nvt_read_get_num_mdata(ts->mmap->PEN_2D_RAW_RING_X_ADDR, + RawData_PenRingX_DiffMin, + ts->x_num * ts->y_gang_num); + nvt_read_get_num_mdata(ts->mmap->PEN_2D_DIFF_RING_Y_ADDR, + RawData_PenRingY_DiffMax, + ts->x_gang_num * ts->y_num); + nvt_read_get_num_mdata(ts->mmap->PEN_2D_RAW_RING_Y_ADDR, + RawData_PenRingY_DiffMin, + ts->x_gang_num * ts->y_num); + } /* if (ts->pen_support) */ + + //---Leave Test Mode--- + nvt_change_mode(NORMAL_MODE); + + printk("%s:RawData_Diff_Max:\n", __func__); + // Save Rawdata to CSV file + if (nvt_save_rawdata_to_csv(RawData_Diff_Max, X_Channel, Y_Channel, + NOISE_TEST_CSV_FILE, 0, + NOISE_MAX_TEST) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + +#if TOUCH_KEY_NUM > 0 + rawdata_diff_min_offset = + Y_Channel * X_Channel * 7 + Y_Channel * 2 + Key_Channel * 7 + 2; +#else + rawdata_diff_min_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2; +#endif /* #if TOUCH_KEY_NUM > 0 */ + printk("%s:RawData_Diff_Min:\n", __func__); + // Save Rawdata to CSV file + if (nvt_save_rawdata_to_csv( + RawData_Diff_Min, X_Channel, Y_Channel, NOISE_TEST_CSV_FILE, + rawdata_diff_min_offset, NOISE_MIN_TEST) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + + if (ts->pen_support) { + // save pen noise to csv + printk("%s:RawData_PenTipX_DiffMax:\n", __func__); + if (nvt_save_rawdata_to_csv( + RawData_PenTipX_DiffMax, ts->x_num, ts->y_gang_num, + PEN_NOISE_TEST_CSV_FILE, csv_pen_noise_offset, + PEN_TIPX_DIFFMAX) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + csv_pen_noise_offset += + ts->y_gang_num * ts->x_num * 7 + ts->y_gang_num * 2; + printk("%s:RawData_PenTipX_DiffMin:\n", __func__); + if (nvt_save_rawdata_to_csv( + RawData_PenTipX_DiffMin, ts->x_num, ts->y_gang_num, + PEN_NOISE_TEST_CSV_FILE, csv_pen_noise_offset, + PEN_TIPX_DIFFMIN) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + csv_pen_noise_offset += + ts->y_gang_num * ts->x_num * 7 + ts->y_gang_num * 2; + printk("%s:RawData_PenTipY_DiffMax:\n", __func__); + if (nvt_save_rawdata_to_csv( + RawData_PenTipY_DiffMax, ts->x_gang_num, ts->y_num, + PEN_NOISE_TEST_CSV_FILE, csv_pen_noise_offset, + PEN_TIPY_DIFFMAX) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + csv_pen_noise_offset += + ts->y_num * ts->x_gang_num * 7 + ts->y_num * 2; + printk("%s:RawData_PenTipY_DiffMin:\n", __func__); + if (nvt_save_rawdata_to_csv( + RawData_PenTipY_DiffMin, ts->x_gang_num, ts->y_num, + PEN_NOISE_TEST_CSV_FILE, csv_pen_noise_offset, + PEN_TIPY_DIFFMIN) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + csv_pen_noise_offset += + ts->y_num * ts->x_gang_num * 7 + ts->y_num * 2; + printk("%s:RawData_PenRingX_DiffMax:\n", __func__); + if (nvt_save_rawdata_to_csv( + RawData_PenRingX_DiffMax, ts->x_num, ts->y_gang_num, + PEN_NOISE_TEST_CSV_FILE, csv_pen_noise_offset, + PEN_RINGX_DIFFMAX) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + csv_pen_noise_offset += + ts->y_gang_num * ts->x_num * 7 + ts->y_gang_num * 2; + printk("%s:RawData_PenRingX_DiffMin:\n", __func__); + if (nvt_save_rawdata_to_csv( + RawData_PenRingX_DiffMin, ts->x_num, ts->y_gang_num, + PEN_NOISE_TEST_CSV_FILE, csv_pen_noise_offset, + PEN_RINGX_DIFFMIN) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + csv_pen_noise_offset += + ts->y_gang_num * ts->x_num * 7 + ts->y_gang_num * 2; + printk("%s:RawData_PenRingY_DiffMax:\n", __func__); + if (nvt_save_rawdata_to_csv( + RawData_PenRingY_DiffMax, ts->x_gang_num, ts->y_num, + PEN_NOISE_TEST_CSV_FILE, csv_pen_noise_offset, + PEN_RINGY_DIFFMAX) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + csv_pen_noise_offset += + ts->y_num * ts->x_gang_num * 7 + ts->y_num * 2; + printk("%s:RawData_PenRingY_DiffMin:\n", __func__); + if (nvt_save_rawdata_to_csv( + RawData_PenRingY_DiffMin, ts->x_gang_num, ts->y_num, + PEN_NOISE_TEST_CSV_FILE, csv_pen_noise_offset, + PEN_RINGY_DIFFMIN) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + } /* if (ts->pen_support) */ + + NVT_LOG("--\n"); + + return 0; +} + +static void nvt_enable_open_test(void) +{ + uint8_t buf[8] = { 0 }; + + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + //---enable open test--- + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x45; + buf[2] = 0xAA; + buf[3] = 0x02; + buf[4] = 0x00; + CTP_SPI_WRITE(ts->client, buf, 5); +} + +static void nvt_enable_short_test(void) +{ + uint8_t buf[8] = { 0 }; + + //---set xdata index to EVENT BUF ADDR--- + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + //---enable short test--- + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x43; + buf[2] = 0xAA; + buf[3] = 0x02; + buf[4] = 0x00; + CTP_SPI_WRITE(ts->client, buf, 5); +} + +static int32_t nvt_read_fw_open(int32_t *xdata) +{ + uint32_t raw_pipe_addr = 0; + uint8_t *rawdata_buf = NULL; + uint32_t x = 0; + uint32_t y = 0; + uint8_t buf[128] = { 0 }; +#if TOUCH_KEY_NUM > 0 + uint32_t raw_btn_pipe_addr = 0; + int32_t k = 0; +#endif /* #if TOUCH_KEY_NUM > 0 */ + + NVT_LOG("++\n"); + + //---Enter Test Mode--- + if (nvt_clear_fw_status()) { + return -EAGAIN; + } + + nvt_enable_open_test(); + + if (nvt_polling_hand_shake_status()) { + return -EAGAIN; + } + +#if TOUCH_KEY_NUM > 0 + rawdata_buf = (uint8_t *)kzalloc( + (IC_X_CFG_SIZE * IC_Y_CFG_SIZE + IC_KEY_CFG_SIZE) * 2, + GFP_KERNEL); +#else + rawdata_buf = (uint8_t *)kzalloc(IC_X_CFG_SIZE * IC_Y_CFG_SIZE * 2, + GFP_KERNEL); +#endif /* #if TOUCH_KEY_NUM > 0 */ + if (!rawdata_buf) { + NVT_ERR("kzalloc for rawdata_buf failed!\n"); + return -ENOMEM; + } + + if (nvt_get_fw_pipe() == 0) + raw_pipe_addr = ts->mmap->RAW_PIPE0_ADDR; + else + raw_pipe_addr = ts->mmap->RAW_PIPE1_ADDR; + + for (y = 0; y < IC_Y_CFG_SIZE; y++) { + //---change xdata index--- + nvt_set_page(raw_pipe_addr + y * IC_X_CFG_SIZE * 2); + buf[0] = (uint8_t)((raw_pipe_addr + y * IC_X_CFG_SIZE * 2) & + 0xFF); + CTP_SPI_READ(ts->client, buf, IC_X_CFG_SIZE * 2 + 1); + memcpy(rawdata_buf + y * IC_X_CFG_SIZE * 2, buf + 1, + IC_X_CFG_SIZE * 2); + } +#if TOUCH_KEY_NUM > 0 + if (nvt_get_fw_pipe() == 0) + raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE0_ADDR; + else + raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE1_ADDR; + + //---change xdata index--- + nvt_set_page(raw_btn_pipe_addr); + buf[0] = (uint8_t)(raw_btn_pipe_addr & 0xFF); + CTP_SPI_READ(ts->client, buf, IC_KEY_CFG_SIZE * 2 + 1); + memcpy(rawdata_buf + IC_Y_CFG_SIZE * IC_X_CFG_SIZE * 2, buf + 1, + IC_KEY_CFG_SIZE * 2); +#endif /* #if TOUCH_KEY_NUM > 0 */ + + for (y = 0; y < IC_Y_CFG_SIZE; y++) { + for (x = 0; x < IC_X_CFG_SIZE; x++) { + if ((AIN_Y[y] != 0xFF) && (AIN_X[x] != 0xFF)) { + xdata[AIN_Y[y] * X_Channel + AIN_X[x]] = (int16_t)(( + rawdata_buf[(y * IC_X_CFG_SIZE + x) * 2] + + 256 * rawdata_buf[(y * IC_X_CFG_SIZE + + x) * 2 + + 1])); + } + } + } +#if TOUCH_KEY_NUM > 0 + for (k = 0; k < IC_KEY_CFG_SIZE; k++) { + if (AIN_KEY[k] != 0xFF) + xdata[Y_Channel * X_Channel + AIN_KEY[k]] = + (int16_t)(rawdata_buf[(IC_Y_CFG_SIZE * + IC_X_CFG_SIZE + + k) * + 2] + + 256 * rawdata_buf[(IC_Y_CFG_SIZE * + IC_X_CFG_SIZE + + k) * 2 + + 1]); + } +#endif /* #if TOUCH_KEY_NUM > 0 */ + + if (rawdata_buf) { + kfree(rawdata_buf); + rawdata_buf = NULL; + } + + //---Leave Test Mode--- + nvt_change_mode(NORMAL_MODE); + + printk("%s:RawData_Open\n", __func__); + // Save RawData to CSV file + if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, + OPEN_TEST_CSV_FILE, 0, OPEN_TEST) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + + NVT_LOG("--\n"); + + return 0; +} + +static int32_t nvt_read_fw_short(int32_t *xdata) +{ + uint32_t raw_pipe_addr = 0; + uint8_t *rawdata_buf = NULL; + uint32_t x = 0; + uint32_t y = 0; + uint8_t buf[128] = { 0 }; + int32_t iArrayIndex = 0; +#if TOUCH_KEY_NUM > 0 + uint32_t raw_btn_pipe_addr = 0; + int32_t k = 0; +#endif /* #if TOUCH_KEY_NUM > 0 */ + + NVT_LOG("++\n"); + + //---Enter Test Mode--- + if (nvt_clear_fw_status()) { + return -EAGAIN; + } + + nvt_enable_short_test(); + + if (nvt_polling_hand_shake_status()) { + return -EAGAIN; + } + +#if TOUCH_KEY_NUM > 0 + rawdata_buf = (uint8_t *)kzalloc( + (X_Channel * Y_Channel + Key_Channel) * 2, GFP_KERNEL); +#else + rawdata_buf = (uint8_t *)kzalloc(X_Channel * Y_Channel * 2, GFP_KERNEL); +#endif /* #if TOUCH_KEY_NUM > 0 */ + if (!rawdata_buf) { + NVT_ERR("kzalloc for rawdata_buf failed!\n"); + return -ENOMEM; + } + + if (nvt_get_fw_pipe() == 0) + raw_pipe_addr = ts->mmap->RAW_PIPE0_ADDR; + else + raw_pipe_addr = ts->mmap->RAW_PIPE1_ADDR; + + for (y = 0; y < Y_Channel; y++) { + //---change xdata index--- + nvt_set_page(raw_pipe_addr + y * X_Channel * 2); + buf[0] = (uint8_t)((raw_pipe_addr + y * X_Channel * 2) & 0xFF); + CTP_SPI_READ(ts->client, buf, X_Channel * 2 + 1); + memcpy(rawdata_buf + y * X_Channel * 2, buf + 1, X_Channel * 2); + } +#if TOUCH_KEY_NUM > 0 + if (nvt_get_fw_pipe() == 0) + raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE0_ADDR; + else + raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE1_ADDR; + + //---change xdata index--- + nvt_set_page(raw_btn_pipe_addr); + buf[0] = (uint8_t)(raw_btn_pipe_addr & 0xFF); + CTP_SPI_READ(ts->client, buf, Key_Channel * 2 + 1); + memcpy(rawdata_buf + Y_Channel * X_Channel * 2, buf + 1, + Key_Channel * 2); +#endif /* #if TOUCH_KEY_NUM > 0 */ + + for (y = 0; y < Y_Channel; y++) { + for (x = 0; x < X_Channel; x++) { + iArrayIndex = y * X_Channel + x; + xdata[iArrayIndex] = + (int16_t)(rawdata_buf[iArrayIndex * 2] + + 256 * rawdata_buf[iArrayIndex * 2 + + 1]); + } + } +#if TOUCH_KEY_NUM > 0 + for (k = 0; k < Key_Channel; k++) { + iArrayIndex = Y_Channel * X_Channel + k; + xdata[iArrayIndex] = + (int16_t)(rawdata_buf[iArrayIndex * 2] + + 256 * rawdata_buf[iArrayIndex * 2 + 1]); + } +#endif /* #if TOUCH_KEY_NUM > 0 */ + + if (rawdata_buf) { + kfree(rawdata_buf); + rawdata_buf = NULL; + } + + //---Leave Test Mode--- + nvt_change_mode(NORMAL_MODE); + + printk("%s:RawData_Short\n", __func__); + // Save Rawdata to CSV file + if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, + SHORT_TEST_CSV_FILE, 0, SHORT_TEST) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + + NVT_LOG("--\n"); + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen raw data test for each single point function. + +return: + Executive outcomes. 0---passed. negative---failed. +*******************************************************/ +static int32_t RawDataTest_SinglePoint_Sub(int32_t rawdata[], + uint8_t RecordResult[], uint8_t x_ch, + uint8_t y_ch, + int32_t Rawdata_Limit_Postive[], + int32_t Rawdata_Limit_Negative[]) +{ + int32_t i = 0; + int32_t j = 0; +#if TOUCH_KEY_NUM > 0 + int32_t k = 0; +#endif /* #if TOUCH_KEY_NUM > 0 */ + int32_t iArrayIndex = 0; + bool isPass = true; + + for (j = 0; j < y_ch; j++) { + for (i = 0; i < x_ch; i++) { + iArrayIndex = j * x_ch + i; + + RecordResult[iArrayIndex] = + 0x00; // default value for PASS + + if (rawdata[iArrayIndex] > + Rawdata_Limit_Postive[iArrayIndex]) + RecordResult[iArrayIndex] |= 0x01; + + if (rawdata[iArrayIndex] < + Rawdata_Limit_Negative[iArrayIndex]) + RecordResult[iArrayIndex] |= 0x02; + } + } +#if TOUCH_KEY_NUM > 0 + for (k = 0; k < Key_Channel; k++) { + iArrayIndex = y_ch * x_ch + k; + + RecordResult[iArrayIndex] = 0x00; // default value for PASS + + if (rawdata[iArrayIndex] > Rawdata_Limit_Postive[iArrayIndex]) + RecordResult[iArrayIndex] |= 0x01; + + if (rawdata[iArrayIndex] < Rawdata_Limit_Negative[iArrayIndex]) + RecordResult[iArrayIndex] |= 0x02; + } +#endif /* #if TOUCH_KEY_NUM > 0 */ + + //---Check RecordResult--- + for (j = 0; j < y_ch; j++) { + for (i = 0; i < x_ch; i++) { + if (RecordResult[j * x_ch + i] != 0) { + isPass = false; + break; + } + } + } +#if TOUCH_KEY_NUM > 0 + for (k = 0; k < Key_Channel; k++) { + iArrayIndex = y_ch * x_ch + k; + if (RecordResult[iArrayIndex] != 0) { + isPass = false; + break; + } + } +#endif /* #if TOUCH_KEY_NUM > 0 */ + + if (isPass == false) { + return -1; // FAIL + } else { + return 0; // PASS + } +} + +/******************************************************* +Description: + Novatek touchscreen print self-test result function. + +return: + n.a. +*******************************************************/ +void print_selftest_result(struct seq_file *m, int32_t TestResult, + uint8_t RecordResult[], int32_t rawdata[], + uint8_t x_len, uint8_t y_len) +{ + int32_t i = 0; + int32_t j = 0; + int32_t iArrayIndex = 0; +#if TOUCH_KEY_NUM > 0 + int32_t k = 0; +#endif /* #if TOUCH_KEY_NUM > 0 */ + + switch (TestResult) { + case 0: + nvt_mp_seq_printf(m, " PASS!\n"); + break; + + case 1: + nvt_mp_seq_printf(m, " ERROR! Read Data FAIL!\n"); + break; + + case -1: + nvt_mp_seq_printf(m, " FAIL!\n"); + nvt_mp_seq_printf(m, "RecordResult:\n"); + for (i = 0; i < y_len; i++) { + for (j = 0; j < x_len; j++) { + iArrayIndex = i * x_len + j; + seq_printf(m, "0x%02X, ", + RecordResult[iArrayIndex]); + } + if (!nvt_mp_test_result_printed) + nvt_print_result_log_in_one_line( + RecordResult + i * x_len, x_len); + nvt_mp_seq_printf(m, "\n"); + } +#if TOUCH_KEY_NUM > 0 + for (k = 0; k < Key_Channel; k++) { + iArrayIndex = y_len * x_len + k; + seq_printf(m, "0x%02X, ", RecordResult[iArrayIndex]); + } + if (!nvt_mp_test_result_printed) + nvt_print_result_log_in_one_line( + RecordResult + y_len * x_len, Key_Channel); + nvt_mp_seq_printf(m, "\n"); +#endif /* #if TOUCH_KEY_NUM > 0 */ + nvt_mp_seq_printf(m, "ReadData:\n"); + for (i = 0; i < y_len; i++) { + for (j = 0; j < x_len; j++) { + iArrayIndex = i * x_len + j; + seq_printf(m, "%5d, ", rawdata[iArrayIndex]); + } + if (!nvt_mp_test_result_printed) + nvt_print_data_log_in_one_line( + rawdata + i * x_len, x_len); + nvt_mp_seq_printf(m, "\n"); + } +#if TOUCH_KEY_NUM > 0 + for (k = 0; k < Key_Channel; k++) { + iArrayIndex = y_len * x_len + k; + seq_printf(m, "%5d, ", rawdata[iArrayIndex]); + } + if (!nvt_mp_test_result_printed) + nvt_print_data_log_in_one_line(rawdata + y_len * x_len, + Key_Channel); + nvt_mp_seq_printf(m, "\n"); +#endif /* #if TOUCH_KEY_NUM > 0 */ + break; + } + nvt_mp_seq_printf(m, "\n"); +} + +/******************************************************* +Description: + Novatek touchscreen self-test sequence print show + function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t c_show_selftest(struct seq_file *m, void *v) +{ + NVT_LOG("++\n"); + + nvt_mp_seq_printf(m, "FW Version: %d\n\n", fw_ver); + + nvt_mp_seq_printf(m, "Short Test"); + print_selftest_result(m, TestResult_Short, RecordResult_Short, + RawData_Short, X_Channel, Y_Channel); + + nvt_mp_seq_printf(m, "Open Test"); + print_selftest_result(m, TestResult_Open, RecordResult_Open, + RawData_Open, X_Channel, Y_Channel); + + nvt_mp_seq_printf(m, "FW Rawdata Test"); + if ((TestResult_FW_Rawdata == 0) || (TestResult_FW_Rawdata == 1)) { + print_selftest_result(m, TestResult_FWMutual, + RecordResult_FWMutual, RawData_FWMutual, + X_Channel, Y_Channel); + } else { // TestResult_FW_Rawdata is -1 + nvt_mp_seq_printf(m, " FAIL!\n"); + if (TestResult_FWMutual == -1) { + nvt_mp_seq_printf(m, "FW Mutual"); + print_selftest_result(m, TestResult_FWMutual, + RecordResult_FWMutual, + RawData_FWMutual, X_Channel, + Y_Channel); + } + if (TestResult_FW_CC == -1) { + nvt_mp_seq_printf(m, "FW CC"); + print_selftest_result(m, TestResult_FW_CC, + RecordResult_FW_CC, RawData_FW_CC, + X_Channel, Y_Channel); + } + } + + nvt_mp_seq_printf(m, "Noise Test"); + if ((TestResult_Noise == 0) || (TestResult_Noise == 1)) { + print_selftest_result(m, TestResult_FW_DiffMax, + RecordResult_FW_DiffMax, RawData_Diff_Max, + X_Channel, Y_Channel); + } else { // TestResult_Noise is -1 + nvt_mp_seq_printf(m, " FAIL!\n"); + if (TestResult_FW_DiffMax == -1) { + nvt_mp_seq_printf(m, "FW Diff Max"); + print_selftest_result(m, TestResult_FW_DiffMax, + RecordResult_FW_DiffMax, + RawData_Diff_Max, X_Channel, + Y_Channel); + } + if (TestResult_FW_DiffMin == -1) { + nvt_mp_seq_printf(m, "FW Diff Min"); + print_selftest_result(m, TestResult_FW_DiffMin, + RecordResult_FW_DiffMin, + RawData_Diff_Min, X_Channel, + Y_Channel); + } + } + + if (ts->pen_support) { + nvt_mp_seq_printf(m, "Pen FW Rawdata Test"); + if ((TestResult_Pen_FW_Raw == 0) || + (TestResult_Pen_FW_Raw == 1)) { + print_selftest_result(m, TestResult_Pen_FW_Raw, + RecordResult_PenTipX_Raw, + RawData_PenTipX_Raw, ts->x_num, + ts->y_gang_num); + } else { // TestResult_Pen_FW_Raw is -1 + nvt_mp_seq_printf(m, " FAIL!\n"); + if (TestResult_PenTipX_Raw == -1) { + nvt_mp_seq_printf(m, "Pen Tip X Raw"); + print_selftest_result(m, TestResult_PenTipX_Raw, + RecordResult_PenTipX_Raw, + RawData_PenTipX_Raw, + ts->x_num, + ts->y_gang_num); + } + if (TestResult_PenTipY_Raw == -1) { + nvt_mp_seq_printf(m, "Pen Tip Y Raw"); + print_selftest_result(m, TestResult_PenTipY_Raw, + RecordResult_PenTipY_Raw, + RawData_PenTipY_Raw, + ts->x_gang_num, + ts->y_num); + } + if (TestResult_PenRingX_Raw == -1) { + nvt_mp_seq_printf(m, "Pen Ring X Raw"); + print_selftest_result(m, + TestResult_PenRingX_Raw, + RecordResult_PenRingX_Raw, + RawData_PenRingX_Raw, + ts->x_num, + ts->y_gang_num); + } + if (TestResult_PenRingY_Raw == -1) { + nvt_mp_seq_printf(m, "Pen Ring Y Raw"); + print_selftest_result(m, + TestResult_PenRingY_Raw, + RecordResult_PenRingY_Raw, + RawData_PenRingY_Raw, + ts->x_gang_num, + ts->y_num); + } + } + + nvt_mp_seq_printf(m, "Pen Noise Test"); + if ((TestResult_Pen_Noise == 0) || + (TestResult_Pen_Noise == 1)) { + print_selftest_result(m, TestResult_Pen_Noise, + RecordResult_PenTipX_DiffMax, + RawData_PenTipX_DiffMax, + ts->x_num, ts->y_gang_num); + } else { // TestResult_Pen_Noise is -1 + nvt_mp_seq_printf(m, " FAIL!\n"); + if (TestResult_PenTipX_DiffMax == -1) { + nvt_mp_seq_printf(m, "Pen Tip X Diff Max"); + print_selftest_result( + m, TestResult_PenTipX_DiffMax, + RecordResult_PenTipX_DiffMax, + RawData_PenTipX_DiffMax, ts->x_num, + ts->y_gang_num); + } + if (TestResult_PenTipX_DiffMin == -1) { + nvt_mp_seq_printf(m, "Pen Tip X Diff Min"); + print_selftest_result( + m, TestResult_PenTipX_DiffMin, + RecordResult_PenTipX_DiffMin, + RawData_PenTipX_DiffMin, ts->x_num, + ts->y_gang_num); + } + if (TestResult_PenTipY_DiffMax == -1) { + nvt_mp_seq_printf(m, "Pen Tip Y Diff Max"); + print_selftest_result( + m, TestResult_PenTipY_DiffMax, + RecordResult_PenTipY_DiffMax, + RawData_PenTipY_DiffMax, ts->x_gang_num, + ts->y_num); + } + if (TestResult_PenTipY_DiffMin == -1) { + nvt_mp_seq_printf(m, "Pen Tip Y Diff Min"); + print_selftest_result( + m, TestResult_PenTipY_DiffMin, + RecordResult_PenTipY_DiffMin, + RawData_PenTipY_DiffMin, ts->x_gang_num, + ts->y_num); + } + if (TestResult_PenRingX_DiffMax == -1) { + nvt_mp_seq_printf(m, "Pen Ring X Diff Max"); + print_selftest_result( + m, TestResult_PenRingX_DiffMax, + RecordResult_PenRingX_DiffMax, + RawData_PenRingX_DiffMax, ts->x_num, + ts->y_gang_num); + } + if (TestResult_PenRingX_DiffMin == -1) { + nvt_mp_seq_printf(m, "Pen Ring X Diff Min"); + print_selftest_result( + m, TestResult_PenRingX_DiffMin, + RecordResult_PenRingX_DiffMin, + RawData_PenRingX_DiffMin, ts->x_num, + ts->y_gang_num); + } + if (TestResult_PenRingY_DiffMax == -1) { + nvt_mp_seq_printf(m, "Pen Ring Y Diff Max"); + print_selftest_result( + m, TestResult_PenRingY_DiffMax, + RecordResult_PenRingY_DiffMax, + RawData_PenRingY_DiffMax, + ts->x_gang_num, ts->y_num); + } + if (TestResult_PenRingY_DiffMin == -1) { + nvt_mp_seq_printf(m, "Pen Ring Y Diff Min"); + print_selftest_result( + m, TestResult_PenRingY_DiffMin, + RecordResult_PenRingY_DiffMin, + RawData_PenRingY_DiffMin, + ts->x_gang_num, ts->y_num); + } + } + } /* if (ts->pen_support) */ + + nvt_mp_test_result_printed = 1; + NVT_LOG("--\n"); + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen self-test sequence print start + function. + +return: + Executive outcomes. 1---call next function. + NULL---not call next function and sequence loop + stop. +*******************************************************/ +static void *c_start(struct seq_file *m, loff_t *pos) +{ + return *pos < 1 ? (void *)1 : NULL; +} + +/******************************************************* +Description: + Novatek touchscreen self-test sequence print next + function. + +return: + Executive outcomes. NULL---no next and call sequence + stop function. +*******************************************************/ +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return NULL; +} + +/******************************************************* +Description: + Novatek touchscreen self-test sequence print stop + function. + +return: + n.a. +*******************************************************/ +static void c_stop(struct seq_file *m, void *v) +{ + return; +} + +const struct seq_operations nvt_selftest_seq_ops = { .start = c_start, + .next = c_next, + .stop = c_stop, + .show = c_show_selftest }; + +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV +static void goto_next_line(char **ptr) +{ + do { + *ptr = *ptr + 1; + } while (**ptr != '\n'); + *ptr = *ptr + 1; +} + +static void copy_this_line(char *dest, char *src) +{ + char *copy_from; + char *copy_to; + + copy_from = src; + copy_to = dest; + do { + *copy_to = *copy_from; + copy_from++; + copy_to++; + } while ((*copy_from != '\n') && (*copy_from != '\r')); + *copy_to = '\0'; +} + +int32_t parse_mp_setting_criteria_item(char **ptr, const char *item_string, + int32_t *item_value) +{ + char *tmp = NULL; + + NVT_LOG("%s ++\n", __func__); + tmp = strstr(*ptr, item_string); + if (tmp == NULL) { + NVT_ERR("%s not found\n", item_string); + return -1; + } + *ptr = tmp; + goto_next_line(ptr); + sscanf(*ptr, "%d,", item_value); + NVT_LOG("%s %d\n", item_string, *item_value); + + NVT_LOG("%s --\n", __func__); + return 0; +} + +int32_t parse_mp_setting_ain_array(char **ptr, const char *item_string, + uint8_t *ain_array, uint32_t IC_CFG_SIZE) +{ + char *tmp = NULL; + int32_t i = 0; + char *token = NULL; + char *tok_ptr = NULL; + size_t offset = 0; + char tmp_buf[512] = { 0 }; + + NVT_LOG("%s ++\n", __func__); + tmp = strstr(*ptr, item_string); + if (tmp == NULL) { + NVT_ERR("%s not found!\n", item_string); + return -1; + } + *ptr = tmp; + + NVT_LOG("%s\n", item_string); + /* walk thru this line */ + goto_next_line(ptr); + + /* copy this line to tmp_buf */ + memset(tmp_buf, 0, sizeof(tmp_buf)); + copy_this_line(tmp_buf, *ptr); + offset = strlen(tmp_buf); + tok_ptr = tmp_buf; + i = 0; + while ((token = strsep(&tok_ptr, ", \t\r\0"))) { + if (strlen(token) == 0) + continue; + if (!strcmp(token, "0xFF") || !strcmp(token, "0xff")) + ain_array[i] = 255; + else + ain_array[i] = (uint8_t)simple_strtol(token, NULL, 10); + NVT_LOG("%d, ", ain_array[i]); + + i++; + } + NVT_LOG("\n"); + /* check if number equals to IC_CFG_SIZE */ + if (i != IC_CFG_SIZE) { + NVT_ERR("load AIN config failed!, i=%d, IC_CFG_SIZE=%d\n", i, + IC_CFG_SIZE); + return -1; + } + /* go forward */ + *ptr = *ptr + offset; + + NVT_LOG("%s --\n", __func__); + return 0; +} + +int32_t parse_mp_criteria_item_array(char **ptr, const char *item_string, + int32_t *item_array, uint32_t x_num, + uint32_t y_num) +{ + char *tmp = NULL; + int32_t i = 0; + int32_t j = 0; + char *token = NULL; + char *tok_ptr = NULL; + size_t offset = 0; + char tmp_buf[512] = { 0 }; + + NVT_LOG("%s ++\n", __func__); + tmp = strstr(*ptr, item_string); + if (tmp == NULL) { + NVT_ERR("%s not found\n", item_string); + return -1; + } + *ptr = tmp; + + NVT_LOG("%s\n", item_string); + for (i = 0; i < y_num; i++) { + /* walk thru this line */ + goto_next_line(ptr); + memset(tmp_buf, 0, sizeof(tmp_buf)); + copy_this_line(tmp_buf, *ptr); + offset = strlen(tmp_buf); + tok_ptr = tmp_buf; + j = 0; + while ((token = strsep(&tok_ptr, ", \t\r\0"))) { + if (strlen(token) == 0) + continue; + item_array[i * x_num + j] = + (int32_t)simple_strtol(token, NULL, 10); + //NVT_LOG("%5d, ", item_array[i * x_num + j]); + printk("%5d, ", item_array[i * x_num + j]); + j++; + } + //NVT_LOG("\n"); + printk("\n"); + /* check if j equals to x_num */ + if (j != x_num) { + NVT_ERR("%s :j not equal x_num!, j=%d, x_num=%d\n", + item_string, j, x_num); + return -1; + } + /* go forward */ + *ptr = *ptr + offset; + } + + NVT_LOG("%s --\n", __func__); + return 0; +} + +static int32_t nvt_load_mp_setting_criteria_from_csv(const char *filename) +{ + int32_t retval = 0; + const struct firmware *fw_entry = NULL; + char *fbufp = NULL; + char *ptr = NULL; + + NVT_LOG("%s ++\n", __func__); + + if (NULL == filename) { + NVT_ERR("filename is null\n"); + retval = -1; + goto exit_free; + } + + retval = request_firmware(&fw_entry, filename, &ts->client->dev); + if (retval) { + NVT_ERR("%s load failed, retval=%d\n", filename, retval); + retval = -1; + goto exit_free; + } + + fbufp = (char *)kzalloc(fw_entry->size + 2, GFP_KERNEL); + if (!fbufp) { + NVT_ERR("kzalloc %zu bytes failed!\n", fw_entry->size); + retval = -1; + goto exit_free; + } + + memcpy(fbufp, fw_entry->data, fw_entry->size); + + /* NVT_LOG("File Size: %zu\n", fw_entry->size); + NVT_LOG("---------------------------------------------------\n"); + printk("fbufp:\n"); + for(i = 0; i < fw_entry->size; i++) { + printk("%c", fbufp[i]); + } + NVT_LOG("---------------------------------------------------\n"); */ + + fbufp[fw_entry->size] = '\0'; + fbufp[fw_entry->size + 1] = '\n'; + + ptr = fbufp; + if (parse_mp_setting_criteria_item( + &ptr, "IC_X_CFG_SIZE:", &IC_X_CFG_SIZE) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_setting_criteria_item( + &ptr, "IC_Y_CFG_SIZE:", &IC_Y_CFG_SIZE) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_setting_criteria_item(&ptr, "X_Channel:", &X_Channel) < + 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_setting_criteria_item(&ptr, "Y_Channel:", &Y_Channel) < + 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_setting_ain_array(&ptr, "AIN_X:", AIN_X, IC_X_CFG_SIZE) < + 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_setting_ain_array(&ptr, "AIN_Y:", AIN_Y, IC_Y_CFG_SIZE) < + 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_Short_Rawdata_P:", + PS_Config_Lmt_Short_Rawdata_P, + X_Channel, Y_Channel) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_Short_Rawdata_P array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_Short_Rawdata_N:", + PS_Config_Lmt_Short_Rawdata_N, + X_Channel, Y_Channel) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_Short_Rawdata_N array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_Open_Rawdata_P:", + PS_Config_Lmt_Open_Rawdata_P, + X_Channel, Y_Channel) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_Open_Rawdata_P array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_Open_Rawdata_N:", + PS_Config_Lmt_Open_Rawdata_N, + X_Channel, Y_Channel) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_Open_Rawdata_N array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_FW_Rawdata_P:", + PS_Config_Lmt_FW_Rawdata_P, X_Channel, + Y_Channel) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_FW_Rawdata_P array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_FW_Rawdata_N:", + PS_Config_Lmt_FW_Rawdata_N, X_Channel, + Y_Channel) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_FW_Rawdata_N array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_FW_CC_P:", PS_Config_Lmt_FW_CC_P, + X_Channel, Y_Channel) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_FW_CC_P array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_FW_CC_N:", PS_Config_Lmt_FW_CC_N, + X_Channel, Y_Channel) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_FW_CC_N array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_FW_Diff_P:", PS_Config_Lmt_FW_Diff_P, + X_Channel, Y_Channel) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_FW_Diff_P array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_FW_Diff_N:", PS_Config_Lmt_FW_Diff_N, + X_Channel, Y_Channel) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_FW_Diff_N array value!\n"); + retval = -1; + goto exit_free; + } + + if (ts->pen_support) { + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenTipX_FW_Raw_P:", + PS_Config_Lmt_PenTipX_FW_Raw_P, ts->x_num, + ts->y_gang_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenTipX_FW_Raw_N:", + PS_Config_Lmt_PenTipX_FW_Raw_N, ts->x_num, + ts->y_gang_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenTipY_FW_Raw_P:", + PS_Config_Lmt_PenTipY_FW_Raw_P, ts->x_gang_num, + ts->y_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenTipY_FW_Raw_N:", + PS_Config_Lmt_PenTipY_FW_Raw_N, ts->x_gang_num, + ts->y_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenRingX_FW_Raw_P:", + PS_Config_Lmt_PenRingX_FW_Raw_P, ts->x_num, + ts->y_gang_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenRingX_FW_Raw_N:", + PS_Config_Lmt_PenRingX_FW_Raw_N, ts->x_num, + ts->y_gang_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenRingY_FW_Raw_P:", + PS_Config_Lmt_PenRingY_FW_Raw_P, ts->x_gang_num, + ts->y_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenRingY_FW_Raw_N:", + PS_Config_Lmt_PenRingY_FW_Raw_N, ts->x_gang_num, + ts->y_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenTipX_FW_Diff_P:", + PS_Config_Lmt_PenTipX_FW_Diff_P, ts->x_num, + ts->y_gang_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenTipX_FW_Diff_N:", + PS_Config_Lmt_PenTipX_FW_Diff_N, ts->x_num, + ts->y_gang_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenTipY_FW_Diff_P:", + PS_Config_Lmt_PenTipY_FW_Diff_P, ts->x_gang_num, + ts->y_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenTipY_FW_Diff_N:", + PS_Config_Lmt_PenTipY_FW_Diff_N, ts->x_gang_num, + ts->y_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenRingX_FW_Diff_P:", + PS_Config_Lmt_PenRingX_FW_Diff_P, ts->x_num, + ts->y_gang_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenRingX_FW_Diff_N:", + PS_Config_Lmt_PenRingX_FW_Diff_N, ts->x_num, + ts->y_gang_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenRingY_FW_Diff_P:", + PS_Config_Lmt_PenRingY_FW_Diff_P, ts->x_gang_num, + ts->y_num) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array( + &ptr, "PS_Config_Lmt_PenRingY_FW_Diff_N:", + PS_Config_Lmt_PenRingY_FW_Diff_N, ts->x_gang_num, + ts->y_num) < 0) { + retval = -1; + goto exit_free; + } + } /* if (ts->pen_support) */ + + ptr = fbufp; + if (parse_mp_setting_criteria_item(&ptr, "PS_Config_Diff_Test_Frame:", + &PS_Config_Diff_Test_Frame) < 0) { + retval = -1; + goto exit_free; + } + + NVT_LOG("Load MP setting and criteria from CSV file finished.\n"); + retval = 0; + +exit_free: + if (fw_entry) { + release_firmware(fw_entry); + fw_entry = NULL; + } + if (fbufp) { + kfree(fbufp); + fbufp = NULL; + } + + NVT_LOG("--, retval=%d\n", retval); + return retval; +} +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_selftest open function. + +return: + Executive outcomes. 0---succeed. negative---failed. +*******************************************************/ +static int32_t nvt_selftest_open(struct inode *inode, struct file *file) +{ + struct device_node *np = ts->client->dev.of_node; + unsigned char mpcriteria[32] = { 0 }; //novatek-mp-criteria-default +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + char mp_setting_criteria_csv_filename[64] = { 0 }; +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + + TestResult_Short = 0; + TestResult_Open = 0; + TestResult_FW_Rawdata = 0; + TestResult_FWMutual = 0; + TestResult_FW_CC = 0; + TestResult_Noise = 0; + TestResult_FW_DiffMax = 0; + TestResult_FW_DiffMin = 0; + if (ts->pen_support) { + TestResult_Pen_FW_Raw = 0; + TestResult_PenTipX_Raw = 0; + TestResult_PenTipY_Raw = 0; + TestResult_PenRingX_Raw = 0; + TestResult_PenRingY_Raw = 0; + TestResult_Pen_Noise = 0; + TestResult_PenTipX_DiffMax = 0; + TestResult_PenTipX_DiffMin = 0; + TestResult_PenTipY_DiffMax = 0; + TestResult_PenTipY_DiffMin = 0; + TestResult_PenRingX_DiffMax = 0; + TestResult_PenRingX_DiffMin = 0; + TestResult_PenRingY_DiffMax = 0; + TestResult_PenRingY_DiffMin = 0; + } /* if (ts->pen_support) */ + + NVT_LOG("++\n"); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + //---Download MP FW--- + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_MP_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->mp_name); + } + } else { + nvt_update_firmware(ts->mp_name); + } + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + NVT_ERR("get fw info failed!\n"); + return -EAGAIN; + } + + nvt_mp_buffer_deinit(); + if (nvt_mp_buffer_init()) { + NVT_ERR("Allocate mp memory failed\n"); + return -ENOMEM; + } + + fw_ver = ts->fw_ver; +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + /* ---Check if MP Setting Criteria CSV file exist and load--- */ + snprintf(mp_setting_criteria_csv_filename, + sizeof(mp_setting_criteria_csv_filename), + "NT36xxx_MP_Setting_Criteria_%04X.csv", ts->nvt_pid); + NVT_LOG("MP setting criteria csv filename: %s\n", + mp_setting_criteria_csv_filename); + if (nvt_load_mp_setting_criteria_from_csv( + mp_setting_criteria_csv_filename) < 0) { + NVT_ERR("SelfTest MP setting criteria CSV file not exist or load failed\n"); +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + /* Parsing criteria from dts */ + if (of_property_read_bool(np, "novatek,mp-support-dt")) { + /* + * Parsing Criteria by Novatek PID + * The string rule is "novatek-mp-criteria-" + * nvt_pid is 2 bytes (show hex). + * + * Ex. nvt_pid = 500A + * mpcriteria = "novatek-mp-criteria-500A" + */ + snprintf(mpcriteria, sizeof(mpcriteria), + "novatek-mp-criteria-%04X", ts->nvt_pid); + + if (nvt_mp_parse_dt(np, mpcriteria)) { + //---Download Normal FW--- + nvt_update_firmware(ts->fw_name); + mutex_unlock(&ts->lock); + NVT_ERR("mp parse device tree failed!\n"); + return -EINVAL; + } + } else { + NVT_LOG("Not found novatek,mp-support-dt, use default setting\n"); + //---Print Test Criteria--- + nvt_print_criteria(); + } +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + } else { + NVT_LOG("SelfTest MP setting criteria loaded from CSV file\n"); + } +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + + if (nvt_switch_FreqHopEnDis(FREQ_HOP_DISABLE)) { + mutex_unlock(&ts->lock); + NVT_ERR("switch frequency hopping disable failed!\n"); + return -EAGAIN; + } + + if (nvt_check_fw_reset_state(RESET_STATE_NORMAL_RUN)) { + mutex_unlock(&ts->lock); + NVT_ERR("check fw reset state failed!\n"); + return -EAGAIN; + } + + msleep(100); + + //---Enter Test Mode--- + if (nvt_clear_fw_status()) { + mutex_unlock(&ts->lock); + NVT_ERR("clear fw status failed!\n"); + return -EAGAIN; + } + + nvt_change_mode(MP_MODE_CC); + + if (nvt_check_fw_status()) { + mutex_unlock(&ts->lock); + NVT_ERR("check fw status failed!\n"); + return -EAGAIN; + } + + //---FW Rawdata Test--- + if (nvt_read_baseline(RawData_FWMutual) != 0) { + TestResult_FWMutual = 1; + } else { + TestResult_FWMutual = RawDataTest_SinglePoint_Sub( + RawData_FWMutual, RecordResult_FWMutual, X_Channel, + Y_Channel, PS_Config_Lmt_FW_Rawdata_P, + PS_Config_Lmt_FW_Rawdata_N); + } + if (nvt_read_CC(RawData_FW_CC) != 0) { + TestResult_FW_CC = 1; + } else { + TestResult_FW_CC = RawDataTest_SinglePoint_Sub( + RawData_FW_CC, RecordResult_FW_CC, X_Channel, Y_Channel, + PS_Config_Lmt_FW_CC_P, PS_Config_Lmt_FW_CC_N); + } + + if ((TestResult_FWMutual == 1) || (TestResult_FW_CC == 1)) { + TestResult_FW_Rawdata = 1; + } else { + if ((TestResult_FWMutual == -1) || (TestResult_FW_CC == -1)) + TestResult_FW_Rawdata = -1; + else + TestResult_FW_Rawdata = 0; + } + + if (ts->pen_support) { + //---Pen FW Rawdata Test--- + if (nvt_read_pen_baseline() != 0) { + TestResult_Pen_FW_Raw = 1; + } else { + TestResult_PenTipX_Raw = RawDataTest_SinglePoint_Sub( + RawData_PenTipX_Raw, RecordResult_PenTipX_Raw, + ts->x_num, ts->y_gang_num, + PS_Config_Lmt_PenTipX_FW_Raw_P, + PS_Config_Lmt_PenTipX_FW_Raw_N); + TestResult_PenTipY_Raw = RawDataTest_SinglePoint_Sub( + RawData_PenTipY_Raw, RecordResult_PenTipY_Raw, + ts->x_gang_num, ts->y_num, + PS_Config_Lmt_PenTipY_FW_Raw_P, + PS_Config_Lmt_PenTipY_FW_Raw_N); + TestResult_PenRingX_Raw = RawDataTest_SinglePoint_Sub( + RawData_PenRingX_Raw, RecordResult_PenRingX_Raw, + ts->x_num, ts->y_gang_num, + PS_Config_Lmt_PenRingX_FW_Raw_P, + PS_Config_Lmt_PenRingX_FW_Raw_N); + TestResult_PenRingY_Raw = RawDataTest_SinglePoint_Sub( + RawData_PenRingY_Raw, RecordResult_PenRingY_Raw, + ts->x_gang_num, ts->y_num, + PS_Config_Lmt_PenRingY_FW_Raw_P, + PS_Config_Lmt_PenRingY_FW_Raw_N); + + if ((TestResult_PenTipX_Raw == -1) || + (TestResult_PenTipY_Raw == -1) || + (TestResult_PenRingX_Raw == -1) || + (TestResult_PenRingY_Raw == -1)) + TestResult_Pen_FW_Raw = -1; + else + TestResult_Pen_FW_Raw = 0; + } + } /* if (ts->pen_support) */ + + //---Leave Test Mode--- + nvt_change_mode(NORMAL_MODE); + + //---Noise Test--- + if (nvt_read_fw_noise(RawData_Diff) != 0) { + TestResult_Noise = 1; // 1: ERROR + TestResult_FW_DiffMax = 1; + TestResult_FW_DiffMin = 1; + if (ts->pen_support) { + TestResult_Pen_Noise = 1; + TestResult_PenTipX_DiffMax = 1; + TestResult_PenTipX_DiffMin = 1; + TestResult_PenTipY_DiffMax = 1; + TestResult_PenTipY_DiffMin = 1; + TestResult_PenRingX_DiffMax = 1; + TestResult_PenRingX_DiffMin = 1; + TestResult_PenRingY_DiffMax = 1; + TestResult_PenRingY_DiffMin = 1; + } /* if (ts->pen_support) */ + } else { + TestResult_FW_DiffMax = RawDataTest_SinglePoint_Sub( + RawData_Diff_Max, RecordResult_FW_DiffMax, X_Channel, + Y_Channel, PS_Config_Lmt_FW_Diff_P, + PS_Config_Lmt_FW_Diff_N); + + TestResult_FW_DiffMin = RawDataTest_SinglePoint_Sub( + RawData_Diff_Min, RecordResult_FW_DiffMin, X_Channel, + Y_Channel, PS_Config_Lmt_FW_Diff_P, + PS_Config_Lmt_FW_Diff_N); + + if ((TestResult_FW_DiffMax == -1) || + (TestResult_FW_DiffMin == -1)) + TestResult_Noise = -1; + else + TestResult_Noise = 0; + + if (ts->pen_support) { + TestResult_PenTipX_DiffMax = + RawDataTest_SinglePoint_Sub( + RawData_PenTipX_DiffMax, + RecordResult_PenTipX_DiffMax, ts->x_num, + ts->y_gang_num, + PS_Config_Lmt_PenTipX_FW_Diff_P, + PS_Config_Lmt_PenTipX_FW_Diff_N); + + TestResult_PenTipX_DiffMin = + RawDataTest_SinglePoint_Sub( + RawData_PenTipX_DiffMin, + RecordResult_PenTipX_DiffMin, ts->x_num, + ts->y_gang_num, + PS_Config_Lmt_PenTipX_FW_Diff_P, + PS_Config_Lmt_PenTipX_FW_Diff_N); + + TestResult_PenTipY_DiffMax = + RawDataTest_SinglePoint_Sub( + RawData_PenTipY_DiffMax, + RecordResult_PenTipY_DiffMax, + ts->x_gang_num, ts->y_num, + PS_Config_Lmt_PenTipY_FW_Diff_P, + PS_Config_Lmt_PenTipY_FW_Diff_N); + + TestResult_PenTipY_DiffMin = + RawDataTest_SinglePoint_Sub( + RawData_PenTipY_DiffMin, + RecordResult_PenTipY_DiffMin, + ts->x_gang_num, ts->y_num, + PS_Config_Lmt_PenTipY_FW_Diff_P, + PS_Config_Lmt_PenTipY_FW_Diff_N); + + TestResult_PenRingX_DiffMax = + RawDataTest_SinglePoint_Sub( + RawData_PenRingX_DiffMax, + RecordResult_PenRingX_DiffMax, + ts->x_num, ts->y_gang_num, + PS_Config_Lmt_PenRingX_FW_Diff_P, + PS_Config_Lmt_PenRingX_FW_Diff_N); + + TestResult_PenRingX_DiffMin = + RawDataTest_SinglePoint_Sub( + RawData_PenRingX_DiffMin, + RecordResult_PenRingX_DiffMin, + ts->x_num, ts->y_gang_num, + PS_Config_Lmt_PenRingX_FW_Diff_P, + PS_Config_Lmt_PenRingX_FW_Diff_N); + + TestResult_PenRingY_DiffMax = + RawDataTest_SinglePoint_Sub( + RawData_PenRingY_DiffMax, + RecordResult_PenRingY_DiffMax, + ts->x_gang_num, ts->y_num, + PS_Config_Lmt_PenRingY_FW_Diff_P, + PS_Config_Lmt_PenRingY_FW_Diff_N); + + TestResult_PenRingY_DiffMin = + RawDataTest_SinglePoint_Sub( + RawData_PenRingY_DiffMin, + RecordResult_PenRingY_DiffMin, + ts->x_gang_num, ts->y_num, + PS_Config_Lmt_PenRingY_FW_Diff_P, + PS_Config_Lmt_PenRingY_FW_Diff_N); + + if ((TestResult_PenTipX_DiffMax == -1) || + (TestResult_PenTipX_DiffMin == -1) || + (TestResult_PenTipY_DiffMax == -1) || + (TestResult_PenTipY_DiffMin == -1) || + (TestResult_PenRingX_DiffMax == -1) || + (TestResult_PenRingX_DiffMin == -1) || + (TestResult_PenRingY_DiffMax == -1) || + (TestResult_PenRingY_DiffMin == -1)) + TestResult_Pen_Noise = -1; + else + TestResult_Pen_Noise = 0; + } /* if (ts->pen_support) */ + } + + //--Short Test--- + if (nvt_read_fw_short(RawData_Short) != 0) { + TestResult_Short = 1; // 1:ERROR + } else { + //---Self Test Check --- // 0:PASS, -1:FAIL + TestResult_Short = RawDataTest_SinglePoint_Sub( + RawData_Short, RecordResult_Short, X_Channel, Y_Channel, + PS_Config_Lmt_Short_Rawdata_P, + PS_Config_Lmt_Short_Rawdata_N); + } + + //---Open Test--- + if (nvt_read_fw_open(RawData_Open) != 0) { + TestResult_Open = 1; // 1:ERROR + } else { + //---Self Test Check --- // 0:PASS, -1:FAIL + TestResult_Open = RawDataTest_SinglePoint_Sub( + RawData_Open, RecordResult_Open, X_Channel, Y_Channel, + PS_Config_Lmt_Open_Rawdata_P, + PS_Config_Lmt_Open_Rawdata_N); + } + + //---Download Normal FW--- + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_FW_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + + mutex_unlock(&ts->lock); + + NVT_LOG("--\n"); + + nvt_mp_test_result_printed = 0; + + return seq_open(file, &nvt_selftest_seq_ops); +} + +static const struct file_operations nvt_selftest_fops = { + .owner = THIS_MODULE, + .open = nvt_selftest_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +#ifdef CONFIG_OF +/******************************************************* +Description: + Novatek touchscreen parse AIN setting for array type. + +return: + n.a. +*******************************************************/ +int32_t nvt_mp_parse_ain(struct device_node *np, const char *name, + uint8_t *array, int32_t size) +{ + struct property *data; + int32_t len, ret; + int32_t tmp[50]; + int32_t i; + + data = of_find_property(np, name, &len); + len /= sizeof(u32); + if ((!data) || (!len) || (len != size)) { + NVT_ERR("error find %s. len=%d\n", name, len); + return -1; + } else { + NVT_LOG("%s. len=%d\n", name, len); + ret = of_property_read_u32_array(np, name, tmp, len); + if (ret) { + NVT_ERR("error reading %s. ret=%d\n", name, ret); + return -1; + } + + for (i = 0; i < len; i++) + array[i] = tmp[i]; + +#if NVT_DEBUG + printk("[NVT-ts] %s = ", name); + nvt_print_result_log_in_one_line(array, len); + printk("\n"); +#endif + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen parse criterion for u32 type. + +return: + n.a. +*******************************************************/ +int32_t nvt_mp_parse_u32(struct device_node *np, const char *name, + int32_t *para) +{ + int32_t ret; + + ret = of_property_read_u32(np, name, para); + if (ret) { + NVT_ERR("error reading %s. ret=%d\n", name, ret); + return -1; + } else { +#if NVT_DEBUG + NVT_LOG("%s=%d\n", name, *para); +#endif + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen parse criterion for array type. + +return: + n.a. +*******************************************************/ +int32_t nvt_mp_parse_array(struct device_node *np, const char *name, + int32_t *array, int32_t size) +{ + struct property *data; + int32_t len, ret; +#if NVT_DEBUG + int32_t j = 0; +#endif + + data = of_find_property(np, name, &len); + len /= sizeof(u32); + if ((!data) || (!len) || (len < size)) { + NVT_ERR("error find %s. len=%d\n", name, len); + return -1; + } else { + NVT_LOG("%s. len=%d\n", name, len); + ret = of_property_read_u32_array(np, name, array, len); + if (ret) { + NVT_ERR("error reading %s. ret=%d\n", name, ret); + return -1; + } + +#if NVT_DEBUG + NVT_LOG("%s =\n", name); + for (j = 0; j < Y_Channel; j++) { + nvt_print_data_log_in_one_line(array + j * X_Channel, + X_Channel); + printk("\n"); + } +#if TOUCH_KEY_NUM > 0 + nvt_print_data_log_in_one_line(array + Y_Channel * X_Channel, + Key_Channel); + printk("\n"); +#endif +#endif + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen parse criterion for pen array type. + +return: + n.a. +*******************************************************/ +int32_t nvt_mp_parse_pen_array(struct device_node *np, const char *name, + int32_t *array, uint32_t x_num, uint32_t y_num) +{ + struct property *data; + int32_t len, ret; +#if NVT_DEBUG + int32_t j = 0; +#endif + uint32_t size; + + size = x_num * y_num; + data = of_find_property(np, name, &len); + len /= sizeof(u32); + if ((!data) || (!len) || (len < size)) { + NVT_ERR("error find %s. len=%d\n", name, len); + return -1; + } else { + NVT_LOG("%s. len=%d\n", name, len); + ret = of_property_read_u32_array(np, name, array, len); + if (ret) { + NVT_ERR("error reading %s. ret=%d\n", name, ret); + return -1; + } + +#if NVT_DEBUG + NVT_LOG("%s =\n", name); + for (j = 0; j < y_num; j++) { + nvt_print_data_log_in_one_line(array + j * x_num, + x_num); + printk("\n"); + } +#endif + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen parse device tree mp function. + +return: + n.a. +*******************************************************/ +int32_t nvt_mp_parse_dt(struct device_node *root, const char *node_compatible) +{ + struct device_node *np = root; + struct device_node *child = NULL; + + NVT_LOG("Parse mp criteria for node %s\n", node_compatible); + + /* find each MP sub-nodes */ + for_each_child_of_node(root, child) { + /* find the specified node */ + if (of_device_is_compatible(child, node_compatible)) { + NVT_LOG("found child node %s\n", node_compatible); + np = child; + break; + } + } + if (child == NULL) { + NVT_ERR("Not found compatible node %s!\n", node_compatible); + return -1; + } + + /* MP Config*/ + if (nvt_mp_parse_u32(np, "IC_X_CFG_SIZE", &IC_X_CFG_SIZE)) + return -1; + + if (nvt_mp_parse_u32(np, "IC_Y_CFG_SIZE", &IC_Y_CFG_SIZE)) + return -1; + +#if TOUCH_KEY_NUM > 0 + if (nvt_mp_parse_u32(np, "IC_KEY_CFG_SIZE", &IC_KEY_CFG_SIZE)) + return -1; +#endif + + if (nvt_mp_parse_u32(np, "X_Channel", &X_Channel)) + return -1; + + if (nvt_mp_parse_u32(np, "Y_Channel", &Y_Channel)) + return -1; + + if (nvt_mp_parse_ain(np, "AIN_X", AIN_X, IC_X_CFG_SIZE)) + return -1; + + if (nvt_mp_parse_ain(np, "AIN_Y", AIN_Y, IC_Y_CFG_SIZE)) + return -1; + +#if TOUCH_KEY_NUM > 0 + if (nvt_mp_parse_ain(np, "AIN_KEY", AIN_KEY, IC_KEY_CFG_SIZE)) + return -1; +#endif + + /* MP Criteria */ + if (nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Rawdata_P", + PS_Config_Lmt_Short_Rawdata_P, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Rawdata_N", + PS_Config_Lmt_Short_Rawdata_N, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_Open_Rawdata_P", + PS_Config_Lmt_Open_Rawdata_P, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_Open_Rawdata_N", + PS_Config_Lmt_Open_Rawdata_N, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Rawdata_P", + PS_Config_Lmt_FW_Rawdata_P, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Rawdata_N", + PS_Config_Lmt_FW_Rawdata_N, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_P", + PS_Config_Lmt_FW_CC_P, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_N", + PS_Config_Lmt_FW_CC_N, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Diff_P", + PS_Config_Lmt_FW_Diff_P, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Diff_N", + PS_Config_Lmt_FW_Diff_N, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (ts->pen_support) { + if (nvt_mp_parse_pen_array(np, "PS_Config_Lmt_PenTipX_FW_Raw_P", + PS_Config_Lmt_PenTipX_FW_Raw_P, + ts->x_num, ts->y_gang_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, "PS_Config_Lmt_PenTipX_FW_Raw_N", + PS_Config_Lmt_PenTipX_FW_Raw_N, + ts->x_num, ts->y_gang_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, "PS_Config_Lmt_PenTipY_FW_Raw_P", + PS_Config_Lmt_PenTipY_FW_Raw_P, + ts->x_gang_num, ts->y_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, "PS_Config_Lmt_PenTipY_FW_Raw_N", + PS_Config_Lmt_PenTipY_FW_Raw_N, + ts->x_gang_num, ts->y_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, + "PS_Config_Lmt_PenRingX_FW_Raw_P", + PS_Config_Lmt_PenRingX_FW_Raw_P, + ts->x_num, ts->y_gang_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, + "PS_Config_Lmt_PenRingX_FW_Raw_N", + PS_Config_Lmt_PenRingX_FW_Raw_N, + ts->x_num, ts->y_gang_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, + "PS_Config_Lmt_PenRingY_FW_Raw_P", + PS_Config_Lmt_PenRingY_FW_Raw_P, + ts->x_gang_num, ts->y_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, + "PS_Config_Lmt_PenRingY_FW_Raw_N", + PS_Config_Lmt_PenRingY_FW_Raw_N, + ts->x_gang_num, ts->y_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, + "PS_Config_Lmt_PenTipX_FW_Diff_P", + PS_Config_Lmt_PenTipX_FW_Diff_P, + ts->x_num, ts->y_gang_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, + "PS_Config_Lmt_PenTipX_FW_Diff_N", + PS_Config_Lmt_PenTipX_FW_Diff_N, + ts->x_num, ts->y_gang_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, + "PS_Config_Lmt_PenTipY_FW_Diff_P", + PS_Config_Lmt_PenTipY_FW_Diff_P, + ts->x_gang_num, ts->y_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, + "PS_Config_Lmt_PenTipY_FW_Diff_N", + PS_Config_Lmt_PenTipY_FW_Diff_N, + ts->x_gang_num, ts->y_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, + "PS_Config_Lmt_PenRingX_FW_Diff_P", + PS_Config_Lmt_PenRingX_FW_Diff_P, + ts->x_num, ts->y_gang_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, + "PS_Config_Lmt_PenRingX_FW_Diff_N", + PS_Config_Lmt_PenRingX_FW_Diff_N, + ts->x_num, ts->y_gang_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, + "PS_Config_Lmt_PenRingY_FW_Diff_P", + PS_Config_Lmt_PenRingY_FW_Diff_P, + ts->x_gang_num, ts->y_num)) + return -1; + + if (nvt_mp_parse_pen_array(np, + "PS_Config_Lmt_PenRingY_FW_Diff_N", + PS_Config_Lmt_PenRingY_FW_Diff_N, + ts->x_gang_num, ts->y_num)) + return -1; + } /* if (ts->pen_support) */ + + if (nvt_mp_parse_u32(np, "PS_Config_Diff_Test_Frame", + &PS_Config_Diff_Test_Frame)) + return -1; + + NVT_LOG("Parse mp criteria done!\n"); + + return 0; +} +#endif /* #ifdef CONFIG_OF */ + +static int nvt_short_test(void) +{ + struct device_node *np = ts->client->dev.of_node; + unsigned char mpcriteria[32] = { 0 }; /*novatek-mp-criteria-default*/ +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + char mp_setting_criteria_csv_filename[64] = { 0 }; +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + + TestResult_Short = 0; + + NVT_LOG("++\n"); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + /*---Download MP FW---*/ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_MP_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->mp_name); + } + } else { + nvt_update_firmware(ts->mp_name); + } + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + NVT_ERR("get fw info failed!\n"); + return -EAGAIN; + } + fw_ver = ts->fw_ver; +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + /*---Check if MP Setting Criteria CSV file exist and load---*/ + snprintf(mp_setting_criteria_csv_filename, + sizeof(mp_setting_criteria_csv_filename), + "NT36xxx_MP_Setting_Criteria_%04X.csv", ts->nvt_pid); + NVT_LOG("MP setting criteria csv filename: %s\n", + mp_setting_criteria_csv_filename); + if (nvt_load_mp_setting_criteria_from_csv( + mp_setting_criteria_csv_filename) < 0) { + NVT_ERR("SelfTest MP setting criteria CSV file not exist or load failed\n"); +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + /* Parsing criteria from dts */ + if (of_property_read_bool(np, "novatek,mp-support-dt")) { + /* + * Parsing Criteria by Novatek PID + * The string rule is "novatek-mp-criteria-" + * nvt_pid is 2 bytes (show hex). + * + * Ex. nvt_pid = 500A + * mpcriteria = "novatek-mp-criteria-500A" + */ + snprintf(mpcriteria, sizeof(mpcriteria), + "novatek-mp-criteria-%04X", ts->nvt_pid); + + if (nvt_mp_parse_dt(np, mpcriteria)) { + /*---Download Normal FW---*/ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware( + DEFAULT_DEBUG_FW_NAME) < + 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware( + ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + mutex_unlock(&ts->lock); + NVT_ERR("mp parse device tree failed!\n"); + return -EINVAL; + } + } else { + NVT_LOG("Not found novatek,mp-support-dt, use default setting\n"); + /*---Print Test Criteria---*/ + nvt_print_criteria(); + } +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + } else { + NVT_LOG("SelfTest MP setting criteria loaded from CSV file\n"); + } +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + + if (nvt_switch_FreqHopEnDis(FREQ_HOP_DISABLE)) { + mutex_unlock(&ts->lock); + NVT_ERR("switch frequency hopping disable failed!\n"); + return -EAGAIN; + } + + if (nvt_check_fw_reset_state(RESET_STATE_NORMAL_RUN)) { + mutex_unlock(&ts->lock); + NVT_ERR("check fw reset state failed!\n"); + return -EAGAIN; + } + + msleep(100); + + /*--Short Test---*/ + if (nvt_read_fw_short(RawData_Short) != 0) { + TestResult_Short = 1; /* 1:ERROR*/ + } else { + /*---Self Test Check ---*/ /* 0:PASS, -1:FAIL*/ + TestResult_Short = RawDataTest_SinglePoint_Sub( + RawData_Short, RecordResult_Short, X_Channel, Y_Channel, + PS_Config_Lmt_Short_Rawdata_P, + PS_Config_Lmt_Short_Rawdata_N); + } + + /*---Download Normal FW---*/ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_FW_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + + mutex_unlock(&ts->lock); + + NVT_LOG("--\n"); + + nvt_mp_test_result_printed = 0; + return TestResult_Short; +} + +static int nvt_open_test(void) +{ + struct device_node *np = ts->client->dev.of_node; + unsigned char mpcriteria[32] = { 0 }; /*novatek-mp-criteria-default*/ +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + char mp_setting_criteria_csv_filename[64] = { 0 }; +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + + TestResult_Open = 0; + + NVT_LOG("++\n"); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + /*---Download MP FW---*/ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_MP_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->mp_name); + } + } else { + nvt_update_firmware(ts->mp_name); + } + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + NVT_ERR("get fw info failed!\n"); + return -EAGAIN; + } + fw_ver = ts->fw_ver; +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + /*---Check if MP Setting Criteria CSV file exist and load---*/ + snprintf(mp_setting_criteria_csv_filename, + sizeof(mp_setting_criteria_csv_filename), + "NT36xxx_MP_Setting_Criteria_%04X.csv", ts->nvt_pid); + NVT_LOG("MP setting criteria csv filename: %s\n", + mp_setting_criteria_csv_filename); + if (nvt_load_mp_setting_criteria_from_csv( + mp_setting_criteria_csv_filename) < 0) { + NVT_ERR("SelfTest MP setting criteria CSV file not exist or load failed\n"); +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + /* Parsing criteria from dts */ + if (of_property_read_bool(np, "novatek,mp-support-dt")) { + /* + * Parsing Criteria by Novatek PID + * The string rule is "novatek-mp-criteria-" + * nvt_pid is 2 bytes (show hex). + * + * Ex. nvt_pid = 500A + * mpcriteria = "novatek-mp-criteria-500A" + */ + snprintf(mpcriteria, sizeof(mpcriteria), + "novatek-mp-criteria-%04X", ts->nvt_pid); + + if (nvt_mp_parse_dt(np, mpcriteria)) { + /*---Download Normal FW---*/ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware( + DEFAULT_DEBUG_FW_NAME) < + 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware( + ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + mutex_unlock(&ts->lock); + NVT_ERR("mp parse device tree failed!\n"); + return -EINVAL; + } + } else { + NVT_LOG("Not found novatek,mp-support-dt, use default setting\n"); + /*---Print Test Criteria---*/ + nvt_print_criteria(); + } +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + } else { + NVT_LOG("SelfTest MP setting criteria loaded from CSV file\n"); + } +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + + if (nvt_switch_FreqHopEnDis(FREQ_HOP_DISABLE)) { + mutex_unlock(&ts->lock); + NVT_ERR("switch frequency hopping disable failed!\n"); + return -EAGAIN; + } + + if (nvt_check_fw_reset_state(RESET_STATE_NORMAL_RUN)) { + mutex_unlock(&ts->lock); + NVT_ERR("check fw reset state failed!\n"); + return -EAGAIN; + } + + msleep(100); + + /*---Open Test---*/ + if (nvt_read_fw_open(RawData_Open) != 0) { + TestResult_Open = 1; /* 1:ERROR*/ + } else { + /*---Self Test Check ---*/ /* 0:PASS, -1:FAIL*/ + TestResult_Open = RawDataTest_SinglePoint_Sub( + RawData_Open, RecordResult_Open, X_Channel, Y_Channel, + PS_Config_Lmt_Open_Rawdata_P, + PS_Config_Lmt_Open_Rawdata_N); + } + + /*---Download Normal FW---*/ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_FW_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + + mutex_unlock(&ts->lock); + + NVT_LOG("--\n"); + + nvt_mp_test_result_printed = 0; + + return TestResult_Open; +} + +static ssize_t nvt_selftest_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + char tmp[5] = { 0 }; + int cnt; + + if (*pos != 0) + return 0; + cnt = snprintf(tmp, sizeof(tmp), "%d\n", ts->result_type); + if (copy_to_user(buf, tmp, strlen(tmp))) { + return -EFAULT; + } + + *pos += cnt; + return cnt; +} + +static ssize_t nvt_selftest_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + int retval = 0; + char tmp[6]; + + if (copy_from_user(tmp, buf, count)) { + retval = -EFAULT; + goto out; + } + + if (!strncmp("short", tmp, 5)) { + retval = nvt_short_test(); + } else if (!strncmp("open", tmp, 4)) { + retval = nvt_open_test(); + } else if (!strncmp("i2c", tmp, 3)) { + retval = nvt_get_fw_info(); + } else { + NVT_ERR("[%s] cmd not support", tmp); + retval = -EINVAL; + } + + switch (retval) { + case 0: + ts->result_type = NVT_RESULT_PASS; + break; + case -EINVAL: + ts->result_type = NVT_RESULT_INVALID; + break; + default: + ts->result_type = NVT_RESULT_FAIL; + break; + } + +out: + if (retval >= 0) + retval = count; + + return retval; +} + +static const struct file_operations nvt_aftersales_test_ops = { + .read = nvt_selftest_read, + .write = nvt_selftest_write, +}; + +/******************************************************* +Description: + Novatek touchscreen MP function proc. file node + initial function. + +return: + Executive outcomes. 0---succeed. -1---failed. +*******************************************************/ +int32_t nvt_mp_proc_init(void) +{ + NVT_proc_selftest_entry = + proc_create("nvt_selftest", 0444, NULL, &nvt_selftest_fops); + if (NVT_proc_selftest_entry == NULL) { + NVT_ERR("create /proc/nvt_selftest Failed!\n"); + return -1; + } else { + if (nvt_mp_buffer_init()) { + NVT_ERR("Allocate mp memory failed\n"); + return -1; + } else { + NVT_LOG("create /proc/nvt_selftest Succeeded!\n"); + } + } + + NVT_proc_aftersales_test_entry = proc_create("tp_selftest", 0644, NULL, + &nvt_aftersales_test_ops); + if (NVT_proc_aftersales_test_entry == NULL) { + NVT_ERR("create /proc/tp_selftest Failed!\n"); + return -1; + } else { + NVT_LOG("create /proc/tp_selftest Succeeded!\n"); + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen MP function proc. file node + deinitial function. + +return: + n.a. +*******************************************************/ +void nvt_mp_proc_deinit(void) +{ + nvt_mp_buffer_deinit(); + if (NVT_proc_selftest_entry != NULL) { + remove_proc_entry("nvt_selftest", NULL); + NVT_proc_selftest_entry = NULL; + NVT_LOG("Removed /proc/%s\n", "nvt_selftest"); + } +} + +#ifndef NVT_SAVE_TESTDATA_IN_FILE +static void test_buff_free(struct test_buf *buf) +{ + if (buf) { + if (buf->shorttest.buf) + kfree(buf->shorttest.buf); + if (buf->opentest.buf) + kfree(buf->opentest.buf); + if (buf->fwmutualtest.buf) + kfree(buf->fwmutualtest.buf); + if (buf->fwcctest.buf) + kfree(buf->fwcctest.buf); + if (buf->noisetest_max.buf) + kfree(buf->noisetest_max.buf); + if (buf->noisetest_min.buf) + kfree(buf->noisetest_min.buf); + if (buf->pen_tipx_raw.buf) + kfree(buf->pen_tipx_raw.buf); + if (buf->pen_tipy_raw.buf) + kfree(buf->pen_tipy_raw.buf); + if (buf->pen_ringx_raw.buf) + kfree(buf->pen_ringx_raw.buf); + if (buf->pen_ringy_raw.buf) + kfree(buf->pen_ringy_raw.buf); + if (buf->pen_tipx_diffmax.buf) + kfree(buf->pen_tipx_diffmax.buf); + if (buf->pen_tipx_diffmin.buf) + kfree(buf->pen_tipx_diffmin.buf); + if (buf->pen_tipy_diffmax.buf) + kfree(buf->pen_tipy_diffmax.buf); + if (buf->pen_tipy_diffmin.buf) + kfree(buf->pen_tipy_diffmin.buf); + if (buf->pen_ringx_diffmax.buf) + kfree(buf->pen_ringx_diffmax.buf); + if (buf->pen_ringx_diffmin.buf) + kfree(buf->pen_ringx_diffmin.buf); + if (buf->pen_ringy_diffmax.buf) + kfree(buf->pen_ringy_diffmax.buf); + if (buf->pen_ringy_diffmin.buf) + kfree(buf->pen_ringy_diffmin.buf); + + kfree(buf); + } + return; +} + +static int32_t test_buff_init(struct test_buf **tbuf) +{ + struct test_buf *buf; + int32_t ret; + + buf = (struct test_buf *)kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf); + goto alloc_fail; + } + + buf->shorttest.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->shorttest.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->shorttest.buf); + goto alloc_fail; + } + + buf->opentest.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->opentest.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->opentest.buf); + goto alloc_fail; + } + + buf->fwmutualtest.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->fwmutualtest.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->fwmutualtest.buf); + goto alloc_fail; + } + + buf->fwcctest.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->fwcctest.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->fwcctest.buf); + goto alloc_fail; + } + + buf->noisetest_max.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->noisetest_max.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->noisetest_max.buf); + goto alloc_fail; + } + + buf->noisetest_min.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->noisetest_min.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->noisetest_min.buf); + goto alloc_fail; + } + + buf->pen_tipx_raw.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->pen_tipx_raw.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->pen_tipx_raw.buf); + goto alloc_fail; + } + + buf->pen_tipy_raw.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->pen_tipy_raw.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->pen_tipy_raw.buf); + goto alloc_fail; + } + + buf->pen_ringx_raw.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->pen_ringx_raw.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->pen_ringx_raw.buf); + goto alloc_fail; + } + + buf->pen_ringy_raw.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->pen_ringy_raw.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->pen_ringy_raw.buf); + goto alloc_fail; + } + + buf->pen_tipx_diffmax.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->pen_tipx_diffmax.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->pen_tipx_diffmax.buf); + goto alloc_fail; + } + + buf->pen_tipx_diffmin.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->pen_tipx_diffmin.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->pen_tipx_diffmin.buf); + goto alloc_fail; + } + + buf->pen_tipy_diffmax.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->pen_tipy_diffmax.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->pen_tipy_diffmax.buf); + goto alloc_fail; + } + + buf->pen_tipy_diffmin.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->pen_tipy_diffmin.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->pen_tipy_diffmin.buf); + goto alloc_fail; + } + + buf->pen_ringx_diffmax.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->pen_ringx_diffmax.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->pen_ringx_diffmax.buf); + goto alloc_fail; + } + + buf->pen_ringx_diffmin.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->pen_ringx_diffmin.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->pen_ringx_diffmin.buf); + goto alloc_fail; + } + + buf->pen_ringy_diffmax.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->pen_ringy_diffmax.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->pen_ringy_diffmax.buf); + goto alloc_fail; + } + + buf->pen_ringy_diffmin.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->pen_ringy_diffmin.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->pen_ringy_diffmin.buf); + goto alloc_fail; + } + + buf->shorttest.type = SHORT_TEST; + buf->opentest.type = OPEN_TEST; + buf->fwmutualtest.type = FWMUTUAL_TEST; + buf->fwcctest.type = FWCC_TEST; + buf->noisetest_max.type = NOISE_MAX_TEST; + buf->noisetest_min.type = NOISE_MIN_TEST; + buf->pen_tipx_raw.type = PEN_TIPX_RAW; + buf->pen_tipy_raw.type = PEN_TIPY_RAW; + buf->pen_ringx_raw.type = PEN_RINGX_RAW; + buf->pen_ringy_raw.type = PEN_RINGY_RAW; + buf->pen_tipx_diffmax.type = PEN_TIPX_DIFFMAX; + buf->pen_tipx_diffmin.type = PEN_TIPX_DIFFMIN; + buf->pen_tipy_diffmax.type = PEN_TIPY_DIFFMAX; + buf->pen_tipy_diffmin.type = PEN_TIPY_DIFFMIN; + buf->pen_ringx_diffmax.type = PEN_RINGX_DIFFMAX; + buf->pen_ringx_diffmin.type = PEN_RINGX_DIFFMIN; + buf->pen_ringy_diffmax.type = PEN_RINGY_DIFFMAX; + buf->pen_ringy_diffmin.type = PEN_RINGY_DIFFMIN; + + *tbuf = buf; + return ret; + +alloc_fail: + *tbuf = NULL; + test_buff_free(buf); + return ret; +} + +struct item_buf *item_arr[MAX_TEST_TYPE]; + +static void *t_start(struct seq_file *m, loff_t *pos) +{ + struct test_buf *tbuf = ts->testdata; + + item_arr[SHORT_TEST] = &tbuf->shorttest; + item_arr[OPEN_TEST] = &tbuf->opentest; + item_arr[FWMUTUAL_TEST] = &tbuf->fwmutualtest; + item_arr[FWCC_TEST] = &tbuf->fwcctest; + item_arr[NOISE_MAX_TEST] = &tbuf->noisetest_max; + item_arr[NOISE_MIN_TEST] = &tbuf->noisetest_min; + item_arr[PEN_TIPX_RAW] = &tbuf->pen_tipx_raw; + item_arr[PEN_TIPY_RAW] = &tbuf->pen_tipy_raw; + item_arr[PEN_RINGX_RAW] = &tbuf->pen_ringx_raw; + item_arr[PEN_RINGY_RAW] = &tbuf->pen_ringy_raw; + item_arr[PEN_TIPX_DIFFMAX] = &tbuf->pen_tipx_diffmax; + item_arr[PEN_TIPX_DIFFMIN] = &tbuf->pen_tipx_diffmin; + item_arr[PEN_TIPY_DIFFMAX] = &tbuf->pen_tipy_diffmax; + item_arr[PEN_TIPY_DIFFMIN] = &tbuf->pen_tipy_diffmin; + item_arr[PEN_RINGX_DIFFMAX] = &tbuf->pen_ringx_diffmax; + item_arr[PEN_RINGX_DIFFMIN] = &tbuf->pen_ringx_diffmin; + item_arr[PEN_RINGY_DIFFMAX] = &tbuf->pen_ringy_diffmax; + item_arr[PEN_RINGY_DIFFMIN] = &tbuf->pen_ringy_diffmin; + + if (*pos >= MAX_TEST_TYPE) { + /* *pos = 0; */ + return NULL; + } + + NVT_LOG("In start\n"); + NVT_LOG("=short= item ptr (%p), type (%d), buf ptr(%p)\n", + &tbuf->shorttest, tbuf->shorttest.type, tbuf->shorttest.buf); + NVT_LOG("=open= item ptr (%p), type (%d), buf ptr(%p)\n", + &tbuf->opentest, tbuf->opentest.type, tbuf->opentest.buf); + NVT_LOG("pos (%lld), first item ptr(%p)", *pos, item_arr[*pos]); + return item_arr[*pos]; +} + +static void *t_next(struct seq_file *m, void *v, loff_t *pos) +{ + NVT_LOG("In next\n"); + NVT_LOG("ptr v (%p), pos (%lld), item ptr (%p)\n", v, *pos, + &item_arr[*pos]); + + ++*pos; + if (*pos >= MAX_TEST_TYPE) { + /* *pos = 0; */ + return NULL; + } + + NVT_LOG("ptr v (%p), pos (%lld), item ptr (%p)\n", v, *pos, + &item_arr[*pos]); + return item_arr[*pos]; +} + +static int32_t t_show(struct seq_file *m, void *v) +{ + int i, j; + struct item_buf *item = v; + int32_t *data = (int32_t *)item->buf; + + NVT_LOG("In show\n"); + NVT_LOG("item ptr (%p), type (%d), buf ptr(%p)\n", item, item->type, + item->buf); + + switch (item->type) { + case SHORT_TEST: + seq_printf(m, "========SHORT_TEST========\n"); + break; + case OPEN_TEST: + seq_printf(m, "========OPEN_TEST========\n"); + break; + case FWMUTUAL_TEST: + seq_printf(m, "========FWMUTUAL_TEST========\n"); + break; + case FWCC_TEST: + seq_printf(m, "========FWCC_TEST========\n"); + break; + case NOISE_MAX_TEST: + seq_printf(m, "========NOISE_MAX_TEST========\n"); + break; + case NOISE_MIN_TEST: + seq_printf(m, "========NOISE_MIN_TEST========\n"); + break; + case PEN_TIPX_RAW: + seq_printf(m, "========PEN_TIPX_RAW========\n"); + break; + case PEN_TIPY_RAW: + seq_printf(m, "========PEN_TIPY_RAW========\n"); + break; + case PEN_RINGX_RAW: + seq_printf(m, "========PEN_RINGX_RAW========\n"); + break; + case PEN_RINGY_RAW: + seq_printf(m, "========PEN_RINGY_RAW========\n"); + break; + case PEN_TIPX_DIFFMAX: + seq_printf(m, "========PEN_TIPX_DIFFMAX========\n"); + break; + case PEN_TIPX_DIFFMIN: + seq_printf(m, "========PEN_TIPX_DIFFMIN========\n"); + break; + case PEN_TIPY_DIFFMAX: + seq_printf(m, "========PEN_TIPY_DIFFMAX========\n"); + break; + case PEN_TIPY_DIFFMIN: + seq_printf(m, "========PEN_TIPY_DIFFMIN========\n"); + break; + case PEN_RINGX_DIFFMAX: + seq_printf(m, "========PEN_RINGX_DIFFMAX========\n"); + break; + case PEN_RINGX_DIFFMIN: + seq_printf(m, "========PEN_RINGX_DIFFMIN========\n"); + break; + case PEN_RINGY_DIFFMAX: + seq_printf(m, "========PEN_RINGY_DIFFMAX========\n"); + break; + case PEN_RINGY_DIFFMIN: + seq_printf(m, "========PEN_RINGY_DIFFMIN========\n"); + break; + default: + NVT_LOG("test type illegal (%d)\n", item->type); + return -EINVAL; + } + + for (i = 0; i < Y_Channel; i++) { + for (j = 0; j < X_Channel; j++) { + seq_printf(m, "%5d, ", data[i * X_Channel + j]); + } + seq_puts(m, "\n"); + } + seq_puts(m, "\n\n"); + + return 0; +} + +static void t_stop(struct seq_file *m, void *v) +{ + NVT_LOG("In stop\n"); + return; +} + +const struct seq_operations t_fops = { .start = t_start, + .next = t_next, + .stop = t_stop, + .show = t_show }; + +static int32_t nvt_test_data_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &t_fops); +} + +static const struct file_operations nvt_test_data_fops = { + .owner = THIS_MODULE, + .open = nvt_test_data_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +int32_t nvt_test_data_proc_init(struct spi_device *client) +{ + int ret; + struct test_buf *tbuf; + struct nvt_ts_data *ts = spi_get_drvdata(client); + + NVT_proc_test_data_entry = + proc_create("nvt_test_data", 0, NULL, &nvt_test_data_fops); + if (NVT_proc_test_data_entry == NULL) { + NVT_ERR("create proc/nvt_test_data Failed!"); + return -ENOMEM; + } else { + NVT_LOG("create proc/nvt_test_data Succeeded!"); + } + + ret = test_buff_init(&tbuf); + if (!tbuf) { + NVT_ERR("test buff init failed"); + remove_proc_entry("nvt_test_data", NULL); + return ret; + } + + ts->testdata = tbuf; + + return 0; +} + +void nvt_test_data_proc_deinit(void) +{ + test_buff_free(ts->testdata); + ts->testdata = NULL; + + if (NVT_proc_test_data_entry != NULL) { + remove_proc_entry("nvt_test_data", NULL); + NVT_proc_test_data_entry = NULL; + NVT_LOG("Removed /proc/nvt_test_data"); + } +} +#endif /*ifndef NVT_SAVE_TESTDATA_IN_FILE*/ +#endif /* #if NVT_TOUCH_MP */ diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_mp_ctrlram.h b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_mp_ctrlram.h new file mode 100644 index 000000000000..4745e7f0ac53 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx_mp_ctrlram.h @@ -0,0 +1,1678 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * $Revision: 71886 $ + * $Date: 2020-11-10 15:36:01 +0800 (週二, 10 å一月 2020) $ + * + * 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. + * + */ + +#if NVT_TOUCH_MP + +static uint32_t IC_X_CFG_SIZE = 32; +static uint32_t IC_Y_CFG_SIZE = 50; +static uint32_t IC_KEY_CFG_SIZE = 4; +static uint32_t X_Channel = 32; +static uint32_t Y_Channel = 50; +static uint32_t Key_Channel = TOUCH_KEY_NUM; +static uint8_t AIN_X[50] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; +static uint8_t AIN_Y[50] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49 }; +#if TOUCH_KEY_NUM > 0 +static uint8_t AIN_KEY[8] = { 0, 1, 2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +#endif /* #if TOUCH_KEY_NUM > 0 */ + +static int32_t PS_Config_Lmt_Short_Rawdata_P[50 * 50] = { + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, +#if TOUCH_KEY_NUM > 0 + 14008, 14008, 14008, +#endif /* #if TOUCH_KEY_NUM > 0 */ +}; + +static int32_t PS_Config_Lmt_Short_Rawdata_N[50 * 50] = { + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, +#if TOUCH_KEY_NUM > 0 + 10000, 10000, 10000, +#endif /* #if TOUCH_KEY_NUM > 0 */ +}; + +static int32_t PS_Config_Lmt_Open_Rawdata_P[50 * 50] = { + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, +#if TOUCH_KEY_NUM > 0 + 5120, 5120, 5120, +#endif /* #if TOUCH_KEY_NUM > 0 */ +}; + +static int32_t PS_Config_Lmt_Open_Rawdata_N[50 * 50] = { + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, -511, + -511, -511, -511, -511, +#if TOUCH_KEY_NUM > 0 + -511, -511, -511, +#endif /* #if TOUCH_KEY_NUM > 0 */ +}; + +static int32_t PS_Config_Lmt_FW_Rawdata_P[50 * 50] = { + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, +#if TOUCH_KEY_NUM > 0 + 3840, 3840, 3840, +#endif /* #if TOUCH_KEY_NUM > 0 */ +}; + +static int32_t PS_Config_Lmt_FW_Rawdata_N[50 * 50] = { + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, +#if TOUCH_KEY_NUM > 0 + 240, 240, 240, +#endif /* #if TOUCH_KEY_NUM > 0 */ +}; + +static int32_t PS_Config_Lmt_FW_CC_P[50 * 50] = { + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, +#if TOUCH_KEY_NUM > 0 + 314, 314, 314, +#endif /* #if TOUCH_KEY_NUM > 0 */ +}; + +static int32_t PS_Config_Lmt_FW_CC_N[50 * 50] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +#if TOUCH_KEY_NUM > 0 + 0, 0, 0, +#endif /* #if TOUCH_KEY_NUM > 0 */ +}; + +static int32_t PS_Config_Lmt_FW_Diff_P[50 * 50] = { + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, +#if TOUCH_KEY_NUM > 0 + 75, 75, 75, +#endif /* #if TOUCH_KEY_NUM > 0 */ +}; + +static int32_t PS_Config_Lmt_FW_Diff_N[50 * 50] = { + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, +#if TOUCH_KEY_NUM > 0 + -75, -75, -75, +#endif /* #if TOUCH_KEY_NUM > 0 */ +}; + +static int32_t PS_Config_Lmt_PenTipX_FW_Raw_P[200] = { + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, +}; + +static int32_t PS_Config_Lmt_PenTipX_FW_Raw_N[200] = { + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, +}; + +static int32_t PS_Config_Lmt_PenTipY_FW_Raw_P[200] = { + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, +}; + +static int32_t PS_Config_Lmt_PenTipY_FW_Raw_N[200] = { + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, +}; + +static int32_t PS_Config_Lmt_PenRingX_FW_Raw_P[200] = { + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, +}; + +static int32_t PS_Config_Lmt_PenRingX_FW_Raw_N[200] = { + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, +}; + +static int32_t PS_Config_Lmt_PenRingY_FW_Raw_P[200] = { + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, +}; + +static int32_t PS_Config_Lmt_PenRingY_FW_Raw_N[200] = { + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, -570, + -570, -570, -570, -570, -570, -570, -570, -570, +}; + +static int32_t PS_Config_Lmt_PenTipX_FW_Diff_P[200] = { + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, +}; + +static int32_t PS_Config_Lmt_PenTipX_FW_Diff_N[200] = { + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, +}; + +static int32_t PS_Config_Lmt_PenTipY_FW_Diff_P[200] = { + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, +}; + +static int32_t PS_Config_Lmt_PenTipY_FW_Diff_N[200] = { + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, +}; + +static int32_t PS_Config_Lmt_PenRingX_FW_Diff_P[200] = { + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, +}; + +static int32_t PS_Config_Lmt_PenRingX_FW_Diff_N[200] = { + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, +}; + +static int32_t PS_Config_Lmt_PenRingY_FW_Diff_P[200] = { + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, +}; + +static int32_t PS_Config_Lmt_PenRingY_FW_Diff_N[200] = { + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, -870, + -870, -870, -870, -870, -870, -870, -870, -870, +}; + +static int32_t PS_Config_Diff_Test_Frame = 50; + +#ifndef NVT_SAVE_TESTDATA_IN_FILE +#define TEST_BUF_LEN 5000 + +enum test_type { + SHORT_TEST = 0, + OPEN_TEST, + FWMUTUAL_TEST, + FWCC_TEST, + NOISE_MAX_TEST, + NOISE_MIN_TEST, + PEN_TIPX_RAW, + PEN_TIPY_RAW, + PEN_RINGX_RAW, + PEN_RINGY_RAW, + PEN_TIPX_DIFFMAX, + PEN_TIPX_DIFFMIN, + PEN_TIPY_DIFFMAX, + PEN_TIPY_DIFFMIN, + PEN_RINGX_DIFFMAX, + PEN_RINGX_DIFFMIN, + PEN_RINGY_DIFFMAX, + PEN_RINGY_DIFFMIN, + MAX_TEST_TYPE = 18, +}; + +struct item_buf { + uint8_t *buf; + uint32_t len; + enum test_type type; +}; + +struct test_buf { + // spinlock_t tbuf_lock; + // bool update; + struct item_buf shorttest; + struct item_buf opentest; + struct item_buf fwmutualtest; + struct item_buf fwcctest; + struct item_buf noisetest_max; + struct item_buf noisetest_min; + struct item_buf pen_tipx_raw; + struct item_buf pen_tipy_raw; + struct item_buf pen_ringx_raw; + struct item_buf pen_ringy_raw; + struct item_buf pen_tipx_diffmax; + struct item_buf pen_tipx_diffmin; + struct item_buf pen_tipy_diffmax; + struct item_buf pen_tipy_diffmin; + struct item_buf pen_ringx_diffmax; + struct item_buf pen_ringx_diffmin; + struct item_buf pen_ringy_diffmax; + struct item_buf pen_ringy_diffmin; +}; + +int32_t nvt_test_data_proc_init(struct spi_device *client); +void nvt_test_data_proc_deinit(void); + +#endif /*#ifndef NVT_SAVE_TESTDATA_IN_FILE*/ +#endif /* #if NVT_TOUCH_MP */ diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/Kconfig b/drivers/input/touchscreen/xiaomi/nt36672c/Kconfig new file mode 100755 index 000000000000..28271c8535ed --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36672c/Kconfig @@ -0,0 +1,15 @@ +# +# Novatek NT36xxx touchscreen driver configuration +# +config TOUCHSCREEN_NT36xxx_HOSTDL_SPI + bool "Novatek NT36xxx host download SPI driver" + help + Say Y here if you have a Novatek NT36xxx no flash touchscreen connected + to your system by SPI bus. + + If unsure, say N. + +config TOUCHSCREEN_NVT_DEBUG_FS + bool "Touch debug interface" + help + Control IRQ,suspend,sensor,debug firmware,etc. diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/Makefile b/drivers/input/touchscreen/xiaomi/nt36672c/Makefile new file mode 100755 index 000000000000..93505a4512d9 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36672c/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the Novatek NT36xxx touchscreen driver. +# + +# Each configuration option enables a list of files. + +obj-$(CONFIG_TOUCHSCREEN_NT36xxx_HOSTDL_SPI) += nt36xxx.o nt36xxx_fw_update.o nt36xxx_ext_proc.o nt36xxx_mp_ctrlram_data.o nt36xxx_mp_ctrlram.o diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c new file mode 100644 index 000000000000..cb4c52513ded --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c @@ -0,0 +1,3347 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * + * $Revision: 32206 $ + * $Date: 2018-08-10 19:23:04 +0800 (週五, 10 八月 2018) $ + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../spi-xiaomi-tp.h" +#include + +#include +#ifdef CONFIG_DRM +#include +#endif + +#include +#if defined(CONFIG_HAS_EARLYSUSPEND) +#include +#endif + +#include "nt36xxx.h" +#ifndef NVT_SAVE_TESTDATA_IN_FILE +#include "nt36xxx_mp_ctrlram.h" +#endif +#if NVT_TOUCH_ESD_PROTECT +#include +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE +#include "../xiaomi/xiaomi_touch.h" +#endif + +#if NVT_TOUCH_ESD_PROTECT +static struct delayed_work nvt_esd_check_work; +static struct workqueue_struct *nvt_esd_check_wq; +static unsigned long irq_timer = 0; +uint8_t esd_check = false; +uint8_t esd_retry = 0; +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + +#if NVT_TOUCH_EXT_PROC +extern int32_t nvt_extra_proc_init(void); +extern void nvt_extra_proc_deinit(void); +#endif + +#if NVT_TOUCH_MP +extern int32_t nvt_mp_proc_init(void); +extern void nvt_mp_proc_deinit(void); +#endif + +struct nvt_ts_data *ts; + +#if BOOT_UPDATE_FIRMWARE +static struct workqueue_struct *nvt_fwu_wq; +static struct workqueue_struct *nvt_lockdown_wq; +extern void Boot_Update_Firmware(struct work_struct *work); +#endif + +#ifdef CONFIG_DRM +static int nvt_drm_notifier_callback(struct notifier_block *self, + unsigned long event, void *data); +#else +static int nvt_fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data); +#endif +#if defined(CONFIG_HAS_EARLYSUSPEND) +static void nvt_ts_early_suspend(struct early_suspend *h); +static void nvt_ts_late_resume(struct early_suspend *h); +#endif +static int32_t nvt_ts_suspend(struct device *dev); +static int32_t nvt_ts_resume(struct device *dev); +extern int dsi_panel_lockdown_info_read(unsigned char *plockdowninfo); +extern void dsi_panel_doubleclick_enable(bool on); +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE +static int32_t nvt_check_palm(uint8_t input_id, uint8_t *data); +#endif +extern void touch_irq_boost(void); +extern void lpm_disable_for_input(bool on); +uint32_t ENG_RST_ADDR = 0x7FFF80; +uint32_t SWRST_N8_ADDR = 0; /* read from dtsi */ +uint32_t SPI_RD_FAST_ADDR = 0; /* read from dtsi */ + +#ifdef CONFIG_MTK_SPI +const struct mt_chip_conf spi_ctrdata = { + .setuptime = 25, + .holdtime = 25, + .high_time = 5, /* 10MHz (SPI_SPEED=100M / (high_time+low_time(10ns)))*/ + .low_time = 5, + .cs_idletime = 2, + .ulthgh_thrsh = 0, + .cpol = 0, + .cpha = 0, + .rx_mlsb = 1, + .tx_mlsb = 1, + .tx_endian = 0, + .rx_endian = 0, + .com_mod = DMA_TRANSFER, + .pause = 0, + .finish_intr = 1, + .deassert = 0, + .ulthigh = 0, + .tckdly = 0, +}; +#endif /*endif CONFIG_MTK_SPI*/ + +#ifdef CONFIG_SPI_MT65XX +const struct mtk_chip_config spi_ctrdata = { + .rx_mlsb = 1, + .tx_mlsb = 1, + .cs_pol = 0, +}; +#endif /*endif CONFIG_SPI_MT65XX*/ + +static ssize_t nvt_cg_color_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%c\n", ts->lockdown_info[2]); +} + +static ssize_t nvt_cg_maker_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%c\n", ts->lockdown_info[6]); +} + +static ssize_t nvt_display_maker_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%c\n", ts->lockdown_info[1]); +} + +static DEVICE_ATTR(cg_color, (S_IRUGO), nvt_cg_color_show, NULL); +static DEVICE_ATTR(cg_maker, (S_IRUGO), nvt_cg_maker_show, NULL); +static DEVICE_ATTR(display_maker, (S_IRUGO), nvt_display_maker_show, NULL); + +struct attribute *nvt_panel_attr[] = { + &dev_attr_cg_color.attr, + &dev_attr_cg_maker.attr, + &dev_attr_display_maker.attr, + NULL, +}; + +static uint8_t bTouchIsAwake = 0; +/******************************************************* +Description: + Novatek touchscreen irq enable/disable function. + +return: + n.a. +*******************************************************/ +static void nvt_irq_enable(bool enable) +{ + struct irq_desc *desc; + + if (enable) { + if (!ts->irq_enabled) { + enable_irq(ts->client->irq); + ts->irq_enabled = true; + } + } else { + if (ts->irq_enabled) { + disable_irq(ts->client->irq); + ts->irq_enabled = false; + } + } + + desc = irq_to_desc(ts->client->irq); + NVT_LOG("enable=%d, desc->depth=%d\n", enable, desc->depth); +} + +/******************************************************* +Description: + Novatek touchscreen spi read/write core function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static inline int32_t spi_read_write(struct spi_device *client, uint8_t *buf, + size_t len, NVT_SPI_RW rw) +{ + struct spi_message m; + struct spi_transfer t = { + .len = len, + }; + + memcpy(ts->xbuf, buf, len); + + switch (rw) { + case NVTREAD: + t.tx_buf = ts->xbuf; + t.rx_buf = ts->rbuf; + t.len = (len + DUMMY_BYTES); + break; + + case NVTWRITE: + t.tx_buf = ts->xbuf; + break; + } + spi_message_init(&m); + spi_message_add_tail(&t, &m); + return spi_sync(client, &m); +} + +/******************************************************* +Description: + Novatek touchscreen spi read function. + +return: + Executive outcomes. 2---succeed. -5---I/O error +*******************************************************/ +int32_t CTP_SPI_READ(struct spi_device *client, uint8_t *buf, uint16_t len) +{ + int32_t ret = -1; + int32_t retries = 0; + + mutex_lock(&ts->xbuf_lock); + + buf[0] = SPI_READ_MASK(buf[0]); + + while (retries < 5) { + ret = spi_read_write(client, buf, len, NVTREAD); + if (ret == 0) + break; + retries++; + } + + if (unlikely(retries == 5)) { + NVT_ERR("read error, ret=%d\n", ret); + ret = -EIO; + } else { + memcpy((buf + 1), (ts->rbuf + 2), (len - 1)); + } + + mutex_unlock(&ts->xbuf_lock); + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen spi write function. + +return: + Executive outcomes. 1---succeed. -5---I/O error +*******************************************************/ +int32_t CTP_SPI_WRITE(struct spi_device *client, uint8_t *buf, uint16_t len) +{ + int32_t ret = -1; + int32_t retries = 0; + mutex_lock(&ts->xbuf_lock); + buf[0] = SPI_WRITE_MASK(buf[0]); + while (retries < 5) { + ret = spi_read_write(client, buf, len, NVTWRITE); + if (ret == 0) + break; + retries++; + } + + if (unlikely(retries == 5)) { + NVT_ERR("error, ret=%d\n", ret); + ret = -EIO; + } + mutex_unlock(&ts->xbuf_lock); + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen set index/page/addr address. + +return: + Executive outcomes. 0---succeed. -5---access fail. +*******************************************************/ +int32_t nvt_set_page(uint32_t addr) +{ + uint8_t buf[4] = { 0 }; + + buf[0] = 0xFF; /* set index/page/addr command */ + buf[1] = (addr >> 15) & 0xFF; + buf[2] = (addr >> 7) & 0xFF; + + return CTP_SPI_WRITE(ts->client, buf, 3); +} + +/******************************************************* +Description: + Novatek touchscreen write data to specify address. + +return: + Executive outcomes. 0---succeed. -5---access fail. +*******************************************************/ +int32_t nvt_write_addr(uint32_t addr, uint8_t data) +{ + int32_t ret = 0; + uint8_t buf[4] = { 0 }; + NVT_LOG("nvt_write_addr enter\n"); + /* ---set xdata index--- */ + buf[0] = 0xFF; /* set index/page/addr command */ + buf[1] = (addr >> 15) & 0xFF; + buf[2] = (addr >> 7) & 0xFF; + ret = CTP_SPI_WRITE(ts->client, buf, 3); + if (ret) { + NVT_ERR("set page 0x%06X failed, ret = %d\n", addr, ret); + return ret; + } + + /* ---write data to index--- */ + buf[0] = addr & (0x7F); + buf[1] = data; + ret = CTP_SPI_WRITE(ts->client, buf, 2); + if (ret) { + NVT_ERR("write data to 0x%06X failed, ret = %d\n", addr, ret); + return ret; + } + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen enable hw bld crc function. + +return: + N/A. +*******************************************************/ +void nvt_bld_crc_enable(void) +{ + uint8_t buf[2] = { 0 }; + + /* ---set xdata index to BLD_CRC_EN_ADDR--- */ + nvt_set_page(ts->mmap->BLD_CRC_EN_ADDR); + + /* ---read data from index--- */ + buf[0] = ts->mmap->BLD_CRC_EN_ADDR & (0x7F); + buf[1] = 0xFF; + CTP_SPI_READ(ts->client, buf, 2); + + /* ---write data to index--- */ + buf[0] = ts->mmap->BLD_CRC_EN_ADDR & (0x7F); + buf[1] = buf[1] | (0x01 << 7); + CTP_SPI_WRITE(ts->client, buf, 2); +} + +/******************************************************* +Description: + Novatek touchscreen clear status & enable fw crc function. + +return: + N/A. +*******************************************************/ +void nvt_fw_crc_enable(void) +{ + uint8_t buf[2] = { 0 }; + + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR); + + /* ---clear fw reset status--- */ + buf[0] = EVENT_MAP_RESET_COMPLETE & (0x7F); + buf[1] = 0x00; + CTP_SPI_WRITE(ts->client, buf, 2); + + /* ---enable fw crc--- */ + buf[0] = EVENT_MAP_HOST_CMD & (0x7F); + buf[1] = 0xAE; /* enable fw crc command */ + CTP_SPI_WRITE(ts->client, buf, 2); +} + +/******************************************************* +Description: + Novatek touchscreen set boot ready function. + +return: + N/A. +*******************************************************/ +void nvt_boot_ready(void) +{ + /* ---write BOOT_RDY status cmds--- */ + nvt_write_addr(ts->mmap->BOOT_RDY_ADDR, 1); + + mdelay(5); + + if (!ts->hw_crc) { + /* ---write BOOT_RDY status cmds--- */ + nvt_write_addr(ts->mmap->BOOT_RDY_ADDR, 0); + + /* ---write POR_CD cmds--- */ + nvt_write_addr(ts->mmap->POR_CD_ADDR, 0xA0); + } +} + +/******************************************************* +Description: + Novatek touchscreen eng reset cmd + function. + +return: + n.a. +*******************************************************/ +void nvt_eng_reset(void) +{ + /* ---eng reset cmds to ENG_RST_ADDR--- */ + NVT_LOG("%s \n", __func__); + nvt_write_addr(ENG_RST_ADDR, 0x5A); + NVT_LOG("%s leave\n", __func__); + mdelay(1); /* wait tMCU_Idle2TP_REX_Hi after TP_RST */ +} + +/******************************************************* +Description: + Novatek touchscreen reset MCU + function. + +return: + n.a. +*******************************************************/ +void nvt_sw_reset(void) +{ + /* ---software reset cmds to SWRST_N8_ADDR--- */ + nvt_write_addr(SWRST_N8_ADDR, 0x55); + + msleep(10); +} + +/******************************************************* +Description: + Novatek touchscreen reset MCU then into idle mode + function. + +return: + n.a. +*******************************************************/ +void nvt_sw_reset_idle(void) +{ + /* ---MCU idle cmds to SWRST_N8_ADDR--- */ + nvt_write_addr(SWRST_N8_ADDR, 0xAA); + + msleep(15); +} + +/******************************************************* +Description: + Novatek touchscreen reset MCU (boot) function. + +return: + n.a. +*******************************************************/ +void nvt_bootloader_reset(void) +{ + /* ---reset cmds to SWRST_N8_ADDR--- */ + nvt_write_addr(SWRST_N8_ADDR, 0x69); + + mdelay(5); /* wait tBRST2FR after Bootload RST */ + + if (SPI_RD_FAST_ADDR) { + /* disable SPI_RD_FAST */ + nvt_write_addr(SPI_RD_FAST_ADDR, 0x00); + } +} + +/******************************************************* +Description: + Novatek touchscreen clear FW status function. + +return: + Executive outcomes. 0---succeed. -1---fail. +*******************************************************/ +int32_t nvt_clear_fw_status(void) +{ + uint8_t buf[8] = { 0 }; + int32_t i = 0; + const int32_t retry = 20; + + for (i = 0; i < retry; i++) { + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | + EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE); + + /* ---clear fw status--- */ + buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; + buf[1] = 0x00; + CTP_SPI_WRITE(ts->client, buf, 2); + + /* ---read fw status--- */ + buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; + buf[1] = 0xFF; + CTP_SPI_READ(ts->client, buf, 2); + + if (buf[1] == 0x00) + break; + + usleep_range(10000, 10000); + } + + if (i >= retry) { + NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]); + return -1; + } else { + return 0; + } +} + +/******************************************************* +Description: + Novatek touchscreen check FW status function. + +return: + Executive outcomes. 0---succeed. -1---failed. +*******************************************************/ +int32_t nvt_check_fw_status(void) +{ + uint8_t buf[8] = { 0 }; + int32_t i = 0; + const int32_t retry = 50; + + for (i = 0; i < retry; i++) { + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | + EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE); + + /* ---read fw status--- */ + buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; + buf[1] = 0x00; + CTP_SPI_READ(ts->client, buf, 2); + + if ((buf[1] & 0xF0) == 0xA0) + break; + + usleep_range(10000, 10000); + } + + if (i >= retry) { + NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]); + return -1; + } else { + return 0; + } +} + +/******************************************************* +Description: + Novatek touchscreen check FW reset state function. + +return: + Executive outcomes. 0---succeed. -1---failed. +*******************************************************/ +int32_t nvt_check_fw_reset_state(RST_COMPLETE_STATE check_reset_state) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + int32_t retry = 0; + int32_t retry_max = (check_reset_state == RESET_STATE_INIT) ? 10 : 50; + + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_RESET_COMPLETE); + + while (1) { + /* ---read reset state--- */ + buf[0] = EVENT_MAP_RESET_COMPLETE; + buf[1] = 0x00; + CTP_SPI_READ(ts->client, buf, 6); + + if ((buf[1] >= check_reset_state) && + (buf[1] <= RESET_STATE_MAX)) { + ret = 0; + break; + } + + retry++; + if (unlikely(retry > retry_max)) { + NVT_ERR("error, retry=%d, buf[1]=0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", + retry, buf[1], buf[2], buf[3], buf[4], buf[5]); + ret = -1; + break; + } + + usleep_range(10000, 10000); + } + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen get novatek project id information + function. + +return: + Executive outcomes. 0---success. -1---fail. +*******************************************************/ +int32_t nvt_read_pid(void) +{ + uint8_t buf[3] = { 0 }; + int32_t ret = 0; + + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_PROJECTID); + + /* ---read project id--- */ + buf[0] = EVENT_MAP_PROJECTID; + buf[1] = 0x00; + buf[2] = 0x00; + CTP_SPI_READ(ts->client, buf, 3); + + ts->nvt_pid = (buf[2] << 8) + buf[1]; + + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR); + + NVT_LOG("PID=%04X\n", ts->nvt_pid); + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen get firmware related information + function. + +return: + Executive outcomes. 0---success. -1---fail. +*******************************************************/ +int32_t nvt_get_fw_info(void) +{ + uint8_t buf[64] = { 0 }; + uint32_t retry_count = 0; + int32_t ret = 0; + +#if 0 + /* READ CHIP ID */ + /* ---set xdata index to 0x1F600-- */ + nvt_set_page(0x1F600); + buf[0] = 0x4E; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x00; + CTP_SPI_READ(ts->client, buf, 7); + NVT_LOG("buf[1]=0x%02X, buf[2]=0x%02X, buf[3]=0x%02X, buf[4]=0x%02X, buf[5]=0x%02X, buf[6]=0x%02X\n", + buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); + memset(buf, 0, 64); +#endif +info_retry: + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_FWINFO); + + /* ---read fw info--- */ + buf[0] = EVENT_MAP_FWINFO; + CTP_SPI_READ(ts->client, buf, 17); + ts->fw_ver = buf[1]; + ts->x_num = buf[3]; + ts->y_num = buf[4]; + ts->abs_x_max = (uint16_t)((buf[5] << 8) | buf[6]); + ts->abs_y_max = (uint16_t)((buf[7] << 8) | buf[8]); + ts->max_button_num = buf[11]; + + /* ---clear x_num, y_num if fw info is broken--- */ + if ((buf[1] + buf[2]) != 0xFF) { + NVT_ERR("FW info is broken! fw_ver=0x%02X, ~fw_ver=0x%02X\n", + buf[1], buf[2]); + ts->fw_ver = 0; + ts->x_num = 18; + ts->y_num = 32; + ts->abs_x_max = TOUCH_DEFAULT_MAX_WIDTH; + ts->abs_y_max = TOUCH_DEFAULT_MAX_HEIGHT; + ts->max_button_num = TOUCH_KEY_NUM; + + if (retry_count < 3) { + retry_count++; + NVT_ERR("retry_count=%d\n", retry_count); + goto info_retry; + } else { + NVT_ERR("Set default fw_ver=%d, x_num=%d, y_num=%d, " + "abs_x_max=%d, abs_y_max=%d, max_button_num=%d!\n", + ts->fw_ver, ts->x_num, ts->y_num, ts->abs_x_max, + ts->abs_y_max, ts->max_button_num); + ret = -1; + } + } else { + ret = 0; + } + + NVT_LOG("FW type is 0x%02X, fw_ver=%d\n", buf[14], ts->fw_ver); + + /* ---Get Novatek PID--- */ + nvt_read_pid(); + return ret; +} + +/******************************************************* + Create Device Node (Proc Entry) +*******************************************************/ +#if NVT_TOUCH_PROC +static struct proc_dir_entry *NVT_proc_entry; +#define DEVICE_NAME "NVTSPI" + +/******************************************************* +Description: + Novatek touchscreen /proc/NVTSPI read function. + +return: + Executive outcomes. 2---succeed. -5,-14---failed. +*******************************************************/ +static ssize_t nvt_flash_read(struct file *file, char __user *buff, + size_t count, loff_t *offp) +{ + uint8_t *str = NULL; + int32_t ret = 0; + int32_t retries = 0; + int8_t spi_wr = 0; + uint8_t *buf; + + if (count > NVT_TRANSFER_LEN) { + NVT_ERR("invalid transfer len!\n"); + return -EFAULT; + } + + /* allocate buffer for spi transfer */ + str = (uint8_t *)kzalloc((count), GFP_KERNEL); + if (str == NULL) { + NVT_ERR("kzalloc for buf failed!\n"); + ret = -ENOMEM; + goto kzalloc_failed; + } + + buf = (uint8_t *)kzalloc((count), GFP_KERNEL | GFP_DMA); + if (buf == NULL) { + NVT_ERR("kzalloc for buf failed!\n"); + ret = -ENOMEM; + kfree(str); + str = NULL; + goto kzalloc_failed; + } + + if (copy_from_user(str, buff, count)) { + NVT_ERR("copy from user error\n"); + ret = -EFAULT; + goto out; + } + +#if NVT_TOUCH_ESD_PROTECT + /* + * stop esd check work to avoid case that 0x77 report righ after here to enable esd check again + * finally lead to trigger esd recovery bootloader reset + */ + cancel_delayed_work_sync(&nvt_esd_check_work); + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + spi_wr = str[0] >> 7; + memcpy(buf, str + 2, ((str[0] & 0x7F) << 8) | str[1]); + + if (spi_wr == NVTWRITE) { /* SPI write */ + while (retries < 20) { + ret = CTP_SPI_WRITE(ts->client, buf, + ((str[0] & 0x7F) << 8) | str[1]); + if (!ret) + break; + else + NVT_ERR("error, retries=%d, ret=%d\n", retries, + ret); + + retries++; + } + + if (unlikely(retries == 20)) { + NVT_ERR("error, ret = %d\n", ret); + ret = -EIO; + goto out; + } + } else if (spi_wr == NVTREAD) { /* SPI read */ + while (retries < 20) { + ret = CTP_SPI_READ(ts->client, buf, + ((str[0] & 0x7F) << 8) | str[1]); + if (!ret) + break; + else + NVT_ERR("error, retries=%d, ret=%d\n", retries, + ret); + + retries++; + } + + memcpy(str + 2, buf, ((str[0] & 0x7F) << 8) | str[1]); + /* copy buff to user if spi transfer */ + if (retries < 20) { + if (copy_to_user(buff, str, count)) { + ret = -EFAULT; + goto out; + } + } + + if (unlikely(retries == 20)) { + NVT_ERR("error, ret = %d\n", ret); + ret = -EIO; + goto out; + } + } else { + NVT_ERR("Call error, str[0]=%d\n", str[0]); + ret = -EFAULT; + goto out; + } + +out: + kfree(str); + kfree(buf); +kzalloc_failed: + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen /proc/NVTSPI open function. + +return: + Executive outcomes. 0---succeed. -12---failed. +*******************************************************/ +static int32_t nvt_flash_open(struct inode *inode, struct file *file) +{ + struct nvt_flash_data *dev; + + dev = kmalloc(sizeof(struct nvt_flash_data), GFP_KERNEL); + if (dev == NULL) { + NVT_ERR("Failed to allocate memory for nvt flash data\n"); + return -ENOMEM; + } + + rwlock_init(&dev->lock); + file->private_data = dev; + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen /proc/NVTSPI close function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t nvt_flash_close(struct inode *inode, struct file *file) +{ + struct nvt_flash_data *dev = file->private_data; + + if (dev) + kfree(dev); + + return 0; +} + +static const struct file_operations nvt_flash_fops = { + .owner = THIS_MODULE, + .open = nvt_flash_open, + .release = nvt_flash_close, + .read = nvt_flash_read, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/NVTSPI initial function. + +return: + Executive outcomes. 0---succeed. -12---failed. +*******************************************************/ +static int32_t nvt_flash_proc_init(void) +{ + NVT_proc_entry = proc_create(DEVICE_NAME, 0444, NULL, &nvt_flash_fops); + if (NVT_proc_entry == NULL) { + NVT_ERR("Failed!\n"); + return -ENOMEM; + } else { + NVT_LOG("Succeeded!\n"); + } + + NVT_LOG("============================================================\n"); + NVT_LOG("Create /proc/%s\n", DEVICE_NAME); + NVT_LOG("============================================================\n"); + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen /proc/NVTSPI deinitial function. + +return: + n.a. +*******************************************************/ +static void nvt_flash_proc_deinit(void) +{ + if (NVT_proc_entry != NULL) { + remove_proc_entry(DEVICE_NAME, NULL); + NVT_proc_entry = NULL; + NVT_LOG("Removed /proc/%s\n", DEVICE_NAME); + } +} +#endif + +#if WAKEUP_GESTURE +#define GESTURE_WORD_C 12 +#define GESTURE_WORD_W 13 +#define GESTURE_WORD_V 14 +#define GESTURE_DOUBLE_CLICK 15 +#define GESTURE_WORD_Z 16 +#define GESTURE_WORD_M 17 +#define GESTURE_WORD_O 18 +#define GESTURE_WORD_e 19 +#define GESTURE_WORD_S 20 +#define GESTURE_SLIDE_UP 21 +#define GESTURE_SLIDE_DOWN 22 +#define GESTURE_SLIDE_LEFT 23 +#define GESTURE_SLIDE_RIGHT 24 +/* customized gesture id */ +#define DATA_PROTOCOL 30 + +/* function page definition */ +#define FUNCPAGE_GESTURE 1 + +/******************************************************* +Description: + Novatek touchscreen wake up gesture key report function. + +return: + n.a. +*******************************************************/ +void nvt_ts_wakeup_gesture_report(uint8_t gesture_id, uint8_t *data) +{ + uint8_t func_type = data[2]; + uint8_t func_id = data[3]; + + /* support fw specifal data protocol */ + if ((gesture_id == DATA_PROTOCOL) && (func_type == FUNCPAGE_GESTURE)) { + gesture_id = func_id; + } else if (gesture_id > DATA_PROTOCOL) { + NVT_ERR("gesture_id %d is invalid, func_type=%d, func_id=%d\n", + gesture_id, func_type, func_id); + return; + } + + NVT_LOG("gesture_id = %d\n", gesture_id); + + switch (gesture_id) { + case GESTURE_DOUBLE_CLICK: + NVT_LOG("Gesture : Double Click.\n"); + input_report_key(ts->input_dev, KEY_WAKEUP, 1); + input_sync(ts->input_dev); + input_report_key(ts->input_dev, KEY_WAKEUP, 0); + input_sync(ts->input_dev); + break; + default: + break; + } +} +#endif + +/******************************************************* +Description: + Novatek touchscreen parse device tree function. + +return: + n.a. +*******************************************************/ +#ifdef CONFIG_OF +static int32_t nvt_parse_dt(struct device *dev) +{ + struct nvt_config_info *config_info; + struct device_node *temp, *np = dev->of_node; + int32_t ret = 0; + uint32_t temp_val; + +#if NVT_TOUCH_SUPPORT_HW_RST + ts->reset_gpio = of_get_named_gpio_flags(np, "novatek,reset-gpio", 0, + &ts->reset_flags); + NVT_LOG("novatek,reset-gpio=%d\n", ts->reset_gpio); +#endif + ts->irq_gpio = of_get_named_gpio_flags(np, "novatek,irq-gpio", 0, + &ts->irq_flags); + NVT_LOG("novatek,irq-gpio=%d\n", ts->irq_gpio); + + ret = of_property_read_u32(np, "novatek,swrst-n8-addr", &SWRST_N8_ADDR); + if (ret) { + NVT_ERR("error reading novatek,swrst-n8-addr. ret=%d\n", ret); + return ret; + } else { + NVT_LOG("SWRST_N8_ADDR=0x%06X\n", SWRST_N8_ADDR); + } + + ret = of_property_read_u32(np, "novatek,spi-rd-fast-addr", + &SPI_RD_FAST_ADDR); + if (ret) { + NVT_ERR("not support novatek,spi-rd-fast-addr\n"); + SPI_RD_FAST_ADDR = 0; + ret = 0; + } else { + NVT_LOG("SPI_RD_FAST_ADDR=0x%06X\n", SPI_RD_FAST_ADDR); + } + + ret = of_property_read_u32(np, "novatek,config-array-size", + &ts->config_array_size); + if (ret) { + NVT_ERR("Unable to get array size\n"); + return ret; + } else { + NVT_LOG("config-array-size: %u\n", ts->config_array_size); + } + + ret = of_property_read_u32(np, "spi-max-frequency", &ts->spi_max_freq); + if (ret) { + NVT_ERR("Unable to get spi freq\n"); + return ret; + } else { + NVT_LOG("spi-max-frequency: %u\n", ts->spi_max_freq); + } + + ts->config_array = devm_kzalloc( + dev, ts->config_array_size * sizeof(struct nvt_config_info), + GFP_KERNEL); + if (!ts->config_array) { + NVT_ERR("Unable to allocate memory\n"); + return -ENOMEM; + } + + config_info = ts->config_array; + for_each_child_of_node(np, temp) { + if (config_info - ts->config_array >= ts->config_array_size) { + NVT_LOG("parse %ld config down\n", + config_info - ts->config_array); + break; + } + + ret = of_property_read_u32(temp, "novatek,tp-vendor", + &temp_val); + if (ret) { + NVT_ERR("Unable to read tp vendor\n"); + } else { + config_info->tp_vendor = (u8)temp_val; + NVT_LOG("tp vendor: %u", config_info->tp_vendor); + } + + ret = of_property_read_u32(temp, "novatek,display-maker", + &temp_val); + if (ret) { + NVT_ERR("Unable to read tp hw version\n"); + } else { + config_info->display_maker = (u8)temp_val; + NVT_LOG("tp hw version: %u", + config_info->display_maker); + } + + /* + ret = of_property_read_u32(temp, "novatek,glass-vendor", &temp_val); + if (ret) { + NVT_ERR("Unable to read tp hw version\n"); + } else { + config_info->glass_vendor = (u8) temp_val; + NVT_LOG("tp hw version: %u", config_info->glass_vendor); + }*/ + + ret = of_property_read_string(temp, "novatek,fw-name", + &config_info->nvt_fw_name); + if (ret && (ret != -EINVAL)) { + NVT_ERR("Unable to read fw name\n"); + } else { + NVT_LOG("fw_name: %s", config_info->nvt_fw_name); + } + + ret = of_property_read_string(temp, "novatek,mp-name", + &config_info->nvt_mp_name); + if (ret && (ret != -EINVAL)) { + NVT_ERR("Unable to read mp name\n"); + } else { + NVT_LOG("mp_name: %s", config_info->nvt_mp_name); + } + + /* + ret = of_property_read_string(temp, "novatek,limit-name", + &config_info->nvt_limit_name); + if (ret && (ret != -EINVAL)) { + NVT_LOG("Unable to read limit name\n"); + } else { + NVT_LOG("limit_name: %s", config_info->nvt_limit_name); + }*/ + config_info++; + } + return ret; +} +#endif + +static bool nvt_cmds_panel_info(void) +{ + bool panel_id = false; + char display_node[37] = { '\0' }; + char *match = (char *)strnstr( + saved_command_line, + "msm_drm.dsi_display0=", strlen(saved_command_line)); + if (match) { + memcpy(display_node, (match + strlen("msm_drm.dsi_display0=")), + sizeof(display_node) - 1); + NVT_LOG("%s: display_node is %s\n", __func__, display_node); + if (!strncmp(display_node, "dsi_j20s_36_02_0a_video_display", + strlen("dsi_j20s_36_02_0a_video_display"))) { + panel_id = true; + } + } + return panel_id; +} + +static int nvt_get_panel_type(struct nvt_ts_data *ts_data) +{ + int i; + u8 *lockdown = ts_data->lockdown_info; + struct nvt_config_info *panel_list = ts->config_array; + + for (i = 0; i < ts->config_array_size; i++) { + if (lockdown[0] == panel_list[i].tp_vendor) { + if (lockdown[0] == 0x46) { + break; + } + if (lockdown[7] == panel_list[i].glass_vendor) { + break; + } + } + } + + ts->panel_index = i; + + if (i >= ts->config_array_size) { + NVT_ERR("mismatch panel type, use default fw"); + ts->panel_index = -EINVAL; + return ts->panel_index; + } + + NVT_LOG("match panle type, fw is [%s], mp is [%s]", + panel_list[i].nvt_fw_name, panel_list[i].nvt_mp_name); + return ts->panel_index; +} + +bool is_lockdown_empty(u8 *lockdown) +{ + bool ret = true; + int i; + for (i = 0; i < NVT_LOCKDOWN_SIZE; i++) { + if (lockdown[i] != 0) { + ret = false; + break; + } + } + + return ret; +} + +void nvt_match_fw(void) +{ + NVT_LOG("start match fw name"); + if (is_lockdown_empty(ts->lockdown_info)) + flush_delayed_work(&ts->nvt_lockdown_work); + if (nvt_get_panel_type(ts) < 0) { + if (nvt_cmds_panel_info()) { + NVT_LOG("%s: panel is first\n", __func__); + ts->fw_name = DEFAULT_BOOT_UPDATE_FIRMWARE_FIRST; + ts->mp_name = DEFAULT_MP_UPDATE_FIRMWARE_FIRST; + } else { + NVT_LOG("%s: panel is second\n", __func__); + ts->fw_name = DEFAULT_BOOT_UPDATE_FIRMWARE_SECOND; + ts->mp_name = DEFAULT_MP_UPDATE_FIRMWARE_SECOND; + } + } else { + ts->fw_name = ts->config_array[ts->panel_index].nvt_fw_name; + ts->mp_name = ts->config_array[ts->panel_index].nvt_mp_name; + } +} + +/******************************************************* +Description: + Novatek touchscreen config and request gpio + +return: + Executive outcomes. 0---succeed. not 0---failed. +*******************************************************/ +static int nvt_gpio_config(struct nvt_ts_data *ts) +{ + int32_t ret = 0; + +#if NVT_TOUCH_SUPPORT_HW_RST + /* request RST-pin (Output/High) */ + if (gpio_is_valid(ts->reset_gpio)) { + ret = gpio_request_one(ts->reset_gpio, GPIOF_OUT_INIT_LOW, + "NVT-tp-rst"); + if (ret) { + NVT_ERR("Failed to request NVT-tp-rst GPIO\n"); + goto err_request_reset_gpio; + } + } +#endif + + /* request INT-pin (Input) */ + if (gpio_is_valid(ts->irq_gpio)) { + ret = gpio_request_one(ts->irq_gpio, GPIOF_IN, "NVT-int"); + if (ret) { + NVT_ERR("Failed to request NVT-int GPIO\n"); + goto err_request_irq_gpio; + } + } + NVT_LOG("%s Exit\n", __func__); + return ret; + +err_request_irq_gpio: +#if NVT_TOUCH_SUPPORT_HW_RST + gpio_free(ts->reset_gpio); +err_request_reset_gpio: +#endif + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen deconfig gpio + +return: + n.a. +*******************************************************/ +static void nvt_gpio_deconfig(struct nvt_ts_data *ts) +{ + if (gpio_is_valid(ts->irq_gpio)) + gpio_free(ts->irq_gpio); +#if NVT_TOUCH_SUPPORT_HW_RST + if (gpio_is_valid(ts->reset_gpio)) + gpio_free(ts->reset_gpio); +#endif +} + +void nvt_set_dbgfw_status(bool enable) +{ + ts->fw_debug = enable; +} + +bool nvt_get_dbgfw_status(void) +{ + return ts->fw_debug; +} + +#if NVT_TOUCH_ESD_PROTECT +void nvt_esd_check_enable(uint8_t enable) +{ + /* update interrupt timer */ + irq_timer = jiffies; + /* clear esd_retry counter, if protect function is enabled */ + esd_retry = enable ? 0 : esd_retry; + /* enable/disable esd check flag */ + esd_check = enable; +} + +static uint8_t nvt_fw_recovery(uint8_t *point_data) +{ + uint8_t i = 0; + uint8_t detected = true; + + /* check pattern */ + for (i = 1; i < 7; i++) { + if (point_data[i] != 0x77) { + detected = false; + break; + } + } + + return detected; +} + +static void nvt_esd_check_func(struct work_struct *work) +{ + unsigned int timer = jiffies_to_msecs(jiffies - irq_timer); + + if ((timer > NVT_TOUCH_ESD_CHECK_PERIOD) && esd_check) { + mutex_lock(&ts->lock); + NVT_LOG("do ESD recovery, timer = %d, retry = %d\n", timer, + esd_retry); + /* do esd recovery, reload fw */ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_FW_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + mutex_unlock(&ts->lock); + /* update interrupt timer */ + irq_timer = jiffies; + /* update esd_retry counter */ + esd_retry++; + } + + queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work, + msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD)); +} +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + +#if NVT_TOUCH_WDT_RECOVERY +static uint8_t recovery_cnt = 0; +static uint8_t nvt_wdt_fw_recovery(uint8_t *point_data) +{ + uint32_t recovery_cnt_max = 10; + uint8_t recovery_enable = false; + uint8_t i = 0; + + recovery_cnt++; + + /* check pattern */ + for (i = 1; i < 7; i++) { + if ((point_data[i] != 0xFD) && (point_data[i] != 0xFE)) { + recovery_cnt = 0; + break; + } + } + + if (recovery_cnt > recovery_cnt_max) { + recovery_enable = true; + recovery_cnt = 0; + } + + return recovery_enable; +} +#endif /* #if NVT_TOUCH_WDT_RECOVERY */ + +static uint32_t nvt_dump_fw_history(void) +{ + int32_t ret = 0; + uint8_t buf[FW_HISTORY_SIZE + 1 + DUMMY_BYTES] = { 0 }; + int32_t i = 0; + char *tmp_dump = NULL; + int32_t line_cnt = 0; + + if (ts->mmap->FW_HISTORY_ADDR == 0) { + NVT_ERR("FW_HISTORY_ADDR not available!\n"); + ret = -1; + goto exit_nvt_dump_fw_history; + } + nvt_set_page(ts->mmap->FW_HISTORY_ADDR); + buf[0] = ts->mmap->FW_HISTORY_ADDR & 0xFF; + CTP_SPI_READ(ts->client, buf, FW_HISTORY_SIZE + 1); + if (ret) { + NVT_ERR("CTP_SPI_READ failed.(%d)\n", ret); + ret = -1; + goto exit_nvt_dump_fw_history; + } + + tmp_dump = (char *)kzalloc(FW_HISTORY_SIZE * 4, GFP_KERNEL); + for (i = 0; i < FW_HISTORY_SIZE; i++) { + sprintf(tmp_dump + i * 3 + line_cnt, "%02X ", buf[1 + i]); + if ((i + 1) % 16 == 0) { + sprintf(tmp_dump + i * 3 + line_cnt + 3, "%c", '\n'); + line_cnt++; + } + } + NVT_LOG("%s", tmp_dump); + +exit_nvt_dump_fw_history: + if (tmp_dump) { + kfree(tmp_dump); + tmp_dump = NULL; + } + nvt_set_page(ts->mmap->EVENT_BUF_ADDR); + + return ret; +} + +#define POINT_DATA_LEN 65 +/******************************************************* +Description: + Novatek touchscreen work function. + +return: + n.a. +*******************************************************/ +static irqreturn_t nvt_ts_work_func(int irq, void *data) +{ + int32_t ret = -1; + uint8_t point_data[POINT_DATA_LEN + 1 + DUMMY_BYTES] = { 0 }; + uint32_t position = 0; + uint32_t input_x = 0; + uint32_t input_y = 0; + uint32_t input_w = 0; + uint32_t input_p = 0; + uint8_t input_id = 0; +#if MT_PROTOCOL_B + uint8_t press_id[TOUCH_MAX_FINGER_NUM] = { 0 }; +#endif /* MT_PROTOCOL_B */ + int32_t i = 0; + int32_t finger_cnt = 0; + +#if WAKEUP_GESTURE + if (bTouchIsAwake == 0) { + pm_wakeup_event(&ts->input_dev->dev, 5000); + } +#endif + if (ts->debug_flag == TOUCH_IRQ_BOOST) + touch_irq_boost(); + mutex_lock(&ts->lock); + if (ts->debug_flag >= TOUCH_DISABLE_LPM) + lpm_disable_for_input(true); + if (ts->dev_pm_suspend) { + ret = wait_for_completion_timeout( + &ts->dev_pm_suspend_completion, msecs_to_jiffies(500)); + if (!ret) { + NVT_ERR("system(spi) can't finished resuming procedure, skip it\n"); + if (ts->debug_flag >= TOUCH_DISABLE_LPM) + lpm_disable_for_input(false); + goto XFER_ERROR; + } + } + + ret = CTP_SPI_READ(ts->client, point_data, POINT_DATA_LEN + 1); + if (ret < 0) { + NVT_ERR("CTP_SPI_READ failed.(%d)\n", ret); + if (ts->debug_flag >= TOUCH_DISABLE_LPM) + lpm_disable_for_input(false); + goto XFER_ERROR; + } + /* + //--- dump SPI buf --- + for (i = 0; i < 10; i++) { + printk("%02X %02X %02X %02X %02X %02X ", + point_data[1+i*6], point_data[2+i*6], point_data[3+i*6], point_data[4+i*6], point_data[5+i*6], point_data[6+i*6]); + } + printk("\n");*/ + +#if NVT_TOUCH_WDT_RECOVERY + /* ESD protect by WDT */ + if (nvt_wdt_fw_recovery(point_data)) { + NVT_ERR("Recover for fw reset, %02X\n", point_data[1]); + if (point_data[1] == 0xFD) { + NVT_ERR("Dump FW history:\n"); + nvt_dump_fw_history(); + } + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_FW_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + if (ts->debug_flag >= TOUCH_DISABLE_LPM) + lpm_disable_for_input(false); + goto XFER_ERROR; + } +#endif /* #if NVT_TOUCH_WDT_RECOVERY */ + +#if NVT_TOUCH_ESD_PROTECT + /* ESD protect by FW handshake */ + if (nvt_fw_recovery(point_data)) { + nvt_esd_check_enable(true); + if (ts->debug_flag >= TOUCH_DISABLE_LPM) + lpm_disable_for_input(false); + goto XFER_ERROR; + } +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + input_id = (uint8_t)(point_data[1] >> 3); + if (nvt_check_palm(input_id, point_data)) { + if (ts->debug_flag >= TOUCH_DISABLE_LPM) + lpm_disable_for_input(false); + goto XFER_ERROR; /* to skip point data parsing */ + } +#endif + +#if WAKEUP_GESTURE + if (bTouchIsAwake == 0) { + input_id = (uint8_t)(point_data[1] >> 3); + nvt_ts_wakeup_gesture_report(input_id, point_data); + if (ts->debug_flag >= TOUCH_DISABLE_LPM) + lpm_disable_for_input(false); + mutex_unlock(&ts->lock); + return IRQ_HANDLED; + } +#endif + + finger_cnt = 0; + + for (i = 0; i < ts->max_touch_num; i++) { + position = 1 + 6 * i; + input_id = (uint8_t)(point_data[position + 0] >> 3); + if ((input_id == 0) || (input_id > ts->max_touch_num)) + continue; + + if (((point_data[position] & 0x07) == 0x01) || + ((point_data[position] & 0x07) == + 0x02)) { //finger down (enter & moving) +#if NVT_TOUCH_ESD_PROTECT + /* update interrupt timer */ + irq_timer = jiffies; +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + input_x = (uint32_t)(point_data[position + 1] << 4) + + (uint32_t)(point_data[position + 3] >> 4); + input_y = (uint32_t)(point_data[position + 2] << 4) + + (uint32_t)(point_data[position + 3] & 0x0F); + if ((input_x < 0) || (input_y < 0)) + continue; + if ((input_x > ts->abs_x_max) || + (input_y > ts->abs_y_max)) + continue; + input_w = (uint32_t)(point_data[position + 4]); + if (input_w == 0) + input_w = 1; + if (i < 2) { + input_p = (uint32_t)(point_data[position + 5]) + + (uint32_t)(point_data[i + 63] << 8); + if (input_p > TOUCH_FORCE_NUM) + input_p = TOUCH_FORCE_NUM; + } else { + input_p = (uint32_t)(point_data[position + 5]); + } + if (input_p == 0) + input_p = 1; + +#if MT_PROTOCOL_B + press_id[input_id - 1] = 1; + input_mt_slot(ts->input_dev, input_id - 1); + input_mt_report_slot_state(ts->input_dev, + MT_TOOL_FINGER, true); + input_report_key(ts->input_dev, BTN_TOUCH, 1); + input_report_key(ts->input_dev, BTN_TOOL_FINGER, 1); +#else /* MT_PROTOCOL_B */ + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, + input_id - 1); + input_report_key(ts->input_dev, BTN_TOUCH, 1); +#endif /* MT_PROTOCOL_B */ + + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, + input_x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, + input_y); + /*input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w);*/ + /*input_report_abs(ts->input_dev, ABS_MT_PRESSURE, input_p);*/ + +#if MT_PROTOCOL_B +#else /* MT_PROTOCOL_B */ + input_mt_sync(ts->input_dev); +#endif /* MT_PROTOCOL_B */ + + set_bit(input_id - 1, ts->slot_map); + finger_cnt++; + } + } + +#if MT_PROTOCOL_B + for (i = 0; i < ts->max_touch_num; i++) { + if (press_id[i] != 1) { + input_mt_slot(ts->input_dev, i); + /*input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);*/ + input_mt_report_slot_state(ts->input_dev, + MT_TOOL_FINGER, false); + /*input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0); */ + if (finger_cnt == 0 && test_bit(i, ts->slot_map)) { + input_report_key(ts->input_dev, BTN_TOUCH, 0); + input_report_key(ts->input_dev, BTN_TOOL_FINGER, + 0); + if (ts->debug_flag >= TOUCH_DISABLE_LPM) + lpm_disable_for_input(false); + } + clear_bit(i, ts->slot_map); + } + } + /* input_report_key(ts->input_dev, BTN_TOUCH, (finger_cnt > 0)); */ +#else /* MT_PROTOCOL_B */ + if (finger_cnt == 0) { + input_report_key(ts->input_dev, BTN_TOUCH, 0); + input_mt_sync(ts->input_dev); + } +#endif /* MT_PROTOCOL_B */ + + input_sync(ts->input_dev); + +XFER_ERROR: + mutex_unlock(&ts->lock); + return IRQ_HANDLED; +} + +/******************************************************* +Description: + Novatek touchscreen check chip version trim function. + +return: + Executive outcomes. 0---NVT IC. -1---not NVT IC. +*******************************************************/ +static int8_t nvt_ts_check_chip_ver_trim(void) +{ + uint8_t buf[8] = { 0 }; + int32_t retry = 0; + int32_t list = 0; + int32_t i = 0; + int32_t found_nvt_chip = 0; + int32_t ret = -1; + + /* ---Check for 5 times--- */ + for (retry = 5; retry > 0; retry--) { + nvt_bootloader_reset(); + + /* ---set xdata index to 0x1F600--- */ + nvt_set_page(0x1F600); + + buf[0] = 0x4E; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x00; + CTP_SPI_READ(ts->client, buf, 7); + NVT_LOG("buf[1]=0x%02X, buf[2]=0x%02X, buf[3]=0x%02X, buf[4]=0x%02X, buf[5]=0x%02X, buf[6]=0x%02X\n", + buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); + + /* compare read chip id on supported list */ + for (list = 0; list < (sizeof(trim_id_table) / + sizeof(struct nvt_ts_trim_id_table)); + list++) { + found_nvt_chip = 0; + /* compare each byte */ + for (i = 0; i < NVT_ID_BYTE_MAX; i++) { + if (trim_id_table[list].mask[i]) { + if (buf[i + 1] != + trim_id_table[list].id[i]) + break; + } + } + + if (i == NVT_ID_BYTE_MAX) { + found_nvt_chip = 1; + } + + if (found_nvt_chip) { + NVT_LOG("This is NVT touch IC\n"); + ts->mmap = trim_id_table[list].mmap; + ts->carrier_system = + trim_id_table[list] + .hwinfo->carrier_system; + ts->hw_crc = trim_id_table[list].hwinfo->hw_crc; + ret = 0; + goto out; + } else { + ts->mmap = NULL; + ret = -1; + } + } + + msleep(10); + } + +out: + return ret; +} + +static int nvt_pinctrl_init(struct nvt_ts_data *nvt_data) +{ + int retval = 0; + /* Get pinctrl if target uses pinctrl */ + nvt_data->ts_pinctrl = devm_pinctrl_get(&nvt_data->pdev->dev); + NVT_LOG("%s Enter\n", __func__); + if (IS_ERR_OR_NULL(nvt_data->ts_pinctrl)) { + retval = PTR_ERR(nvt_data->ts_pinctrl); + NVT_ERR("Target does not use pinctrl %d\n", retval); + goto err_pinctrl_get; + } + + nvt_data->pinctrl_state_active = pinctrl_lookup_state( + nvt_data->ts_pinctrl, PINCTRL_STATE_ACTIVE); + + if (IS_ERR_OR_NULL(nvt_data->pinctrl_state_active)) { + retval = PTR_ERR(nvt_data->pinctrl_state_active); + NVT_ERR("Can not lookup %s pinstate %d\n", PINCTRL_STATE_ACTIVE, + retval); + goto err_pinctrl_lookup; + } + + nvt_data->pinctrl_state_suspend = pinctrl_lookup_state( + nvt_data->ts_pinctrl, PINCTRL_STATE_SUSPEND); + + if (IS_ERR_OR_NULL(nvt_data->pinctrl_state_suspend)) { + retval = PTR_ERR(nvt_data->pinctrl_state_suspend); + NVT_ERR("Can not lookup %s pinstate %d\n", + PINCTRL_STATE_SUSPEND, retval); + goto err_pinctrl_lookup; + } + + return 0; +err_pinctrl_lookup: + devm_pinctrl_put(nvt_data->ts_pinctrl); +err_pinctrl_get: + nvt_data->ts_pinctrl = NULL; + return retval; +} + +static void nvt_switch_mode_work(struct work_struct *work) +{ + NVT_LOG("%s double click wakeup", ts->db_wakeup ? "ENABLE" : "DISABLE"); + if (ts->ic_state <= NVT_IC_SUSPEND_OUT && ts->ic_state != NVT_IC_INIT) { + ts->gesture_command_delayed = ts->db_wakeup; + NVT_ERR("Panel off, don't set dbclick gesture flag util panel on"); + ts->db_wakeup = 0; + } else if (ts->ic_state >= NVT_IC_RESUME_IN) { + dsi_panel_doubleclick_enable(!!ts->db_wakeup); + } +} + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + +static struct xiaomi_touch_interface xiaomi_touch_interfaces; + +int32_t nvt_check_palm(uint8_t input_id, uint8_t *data) +{ + int32_t ret = 0; + uint8_t func_type = data[2]; + uint8_t palm_state = data[3]; + + if ((input_id == DATA_PROTOCOL) && (func_type == FUNCPAGE_PALM)) { + ret = palm_state; + if (palm_state == PACKET_PALM_ON) { + NVT_LOG("get packet palm on event.\n"); + update_palm_sensor_value(1); + } else if (palm_state == PACKET_PALM_OFF) { + NVT_LOG("get packet palm off event.\n"); + update_palm_sensor_value(0); + } else { + NVT_ERR("invalid palm state %d!\n", palm_state); + ret = -1; + } + } else { + ret = 0; + } + + return ret; +} + +static int nvt_palm_sensor_write(int value) +{ + int ret = 0; + NVT_LOG("enter %d %d\n", value, ts->palm_sensor_switch); + ts->palm_sensor_switch = value; + + if (ts->dev_pm_suspend) { + NVT_LOG("tp has dev_pm_suspend status\n"); + return 0; + } + + if (bTouchIsAwake) + ret = nvt_set_pocket_palm_switch(value); + return ret; +} + +static struct xiaomi_touch_interface xiaomi_touch_interfaces; +static void nvt_init_touchmode_data(void) +{ + int i; + + NVT_LOG("%s,ENTER\n", __func__); + /* Touch Game Mode Switch */ + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_MAX_VALUE] = 1; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_DEF_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][SET_CUR_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Game_Mode][GET_CUR_VALUE] = 0; + + /* Acitve Mode */ + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_MAX_VALUE] = + 1; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_MIN_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_DEF_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][SET_CUR_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Active_MODE][GET_CUR_VALUE] = + 0; + + /* Sensivity */ + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_MAX_VALUE] = + 2; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_MIN_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_DEF_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][SET_CUR_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_UP_THRESHOLD][GET_CUR_VALUE] = + 0; + + /* Tolerance */ + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_MAX_VALUE] = 2; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_DEF_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][SET_CUR_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Tolerance][GET_CUR_VALUE] = 0; + + /* Panel orientation*/ + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_MAX_VALUE] = 3; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_DEF_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][SET_CUR_VALUE] = 0; + xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation][GET_CUR_VALUE] = 0; + + /* Edge filter area*/ + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_MAX_VALUE] = + 3; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_MIN_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_DEF_VALUE] = + 2; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][SET_CUR_VALUE] = + 0; + xiaomi_touch_interfaces.touch_mode[Touch_Edge_Filter][GET_CUR_VALUE] = + 0; + + /* Resist RF interference*/ + xiaomi_touch_interfaces.touch_mode[Touch_Resist_RF][GET_MAX_VALUE] = 1; + xiaomi_touch_interfaces.touch_mode[Touch_Resist_RF][GET_MIN_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Resist_RF][GET_DEF_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Resist_RF][SET_CUR_VALUE] = 0; + xiaomi_touch_interfaces.touch_mode[Touch_Resist_RF][GET_CUR_VALUE] = 0; + + for (i = 0; i < Touch_Mode_NUM; i++) { + NVT_LOG("mode:%d, set cur:%d, get cur:%d, def:%d min:%d max:%d\n", + i, xiaomi_touch_interfaces.touch_mode[i][SET_CUR_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_CUR_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_DEF_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_MIN_VALUE], + xiaomi_touch_interfaces.touch_mode[i][GET_MAX_VALUE]); + } + + return; +} + +static int nvt_touchfeature_cmd_xsfer(uint8_t *touchfeature) +{ + int ret; + uint8_t buf[8] = { 0 }; + + NVT_LOG("++\n"); + NVT_LOG("cmd xsfer:%02x, %02x", touchfeature[0], touchfeature[1]); + /* ---set xdata index to EVENT BUF ADDR--- */ + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_touchfeature_cmd_xsfer_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = touchfeature[0]; + buf[2] = touchfeature[1]; + + ret = CTP_SPI_WRITE(ts->client, buf, 3); + if (ret < 0) { + NVT_ERR("Write sensitivity switch command fail!\n"); + goto nvt_touchfeature_cmd_xsfer_out; + } + +nvt_touchfeature_cmd_xsfer_out: + NVT_LOG("--\n"); + return ret; +} + +static int nvt_touchfeature_set(uint8_t *touchfeature) +{ + int ret; + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + ret = nvt_touchfeature_cmd_xsfer(touchfeature); + if (ret < 0) + NVT_ERR("send cmd via SPI failed, errno:%d", ret); + + mutex_unlock(&ts->lock); + msleep(35); + return ret; +} + +static int nvt_set_cur_value(int nvt_mode, int nvt_value) +{ + bool skip = false; + uint8_t nvt_game_value[2] = { 0 }; + uint8_t temp_value = 0; + uint8_t ret = 0; + + if (nvt_mode >= Touch_Mode_NUM && nvt_mode < 0) { + NVT_ERR("%s, nvt mode is error:%d", __func__, nvt_mode); + return -EINVAL; + } + + if (nvt_mode == Touch_Doubletap_Mode && ts && nvt_value >= 0) { + ts->db_wakeup = nvt_value; + schedule_work(&ts->switch_mode_work); + } + + xiaomi_touch_interfaces.touch_mode[nvt_mode][SET_CUR_VALUE] = nvt_value; + + if (xiaomi_touch_interfaces.touch_mode[nvt_mode][SET_CUR_VALUE] > + xiaomi_touch_interfaces.touch_mode[nvt_mode][GET_MAX_VALUE]) { + xiaomi_touch_interfaces.touch_mode[nvt_mode][SET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[nvt_mode][GET_MAX_VALUE]; + + } else if (xiaomi_touch_interfaces.touch_mode[nvt_mode][SET_CUR_VALUE] < + xiaomi_touch_interfaces.touch_mode[nvt_mode][GET_MIN_VALUE]) { + xiaomi_touch_interfaces.touch_mode[nvt_mode][SET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[nvt_mode][GET_MIN_VALUE]; + } + + switch (nvt_mode) { + case Touch_Game_Mode: + break; + case Touch_Active_MODE: + break; + case Touch_UP_THRESHOLD: + temp_value = + xiaomi_touch_interfaces + .touch_mode[Touch_UP_THRESHOLD][SET_CUR_VALUE]; + nvt_game_value[0] = 0x71; + nvt_game_value[1] = temp_value; + break; + case Touch_Tolerance: + temp_value = + xiaomi_touch_interfaces + .touch_mode[Touch_Tolerance][SET_CUR_VALUE]; + nvt_game_value[0] = 0x70; + nvt_game_value[1] = temp_value; + break; + case Touch_Edge_Filter: + /* filter 0,1,2,3 = default,1,2,3 level*/ + temp_value = + xiaomi_touch_interfaces + .touch_mode[Touch_Edge_Filter][SET_CUR_VALUE]; + nvt_game_value[0] = 0x72; + nvt_game_value[1] = temp_value; + break; + case Touch_Panel_Orientation: + /* 0,1,2,3 = 0, 90, 180,270 Counter-clockwise*/ + temp_value = xiaomi_touch_interfaces + .touch_mode[Touch_Panel_Orientation] + [SET_CUR_VALUE]; + if (temp_value == 0 || temp_value == 2) { + nvt_game_value[0] = 0xBA; + } else if (temp_value == 1) { + nvt_game_value[0] = 0xBC; + } else if (temp_value == 3) { + nvt_game_value[0] = 0xBB; + } + nvt_game_value[1] = 0; + break; + case Touch_Resist_RF: + temp_value = + xiaomi_touch_interfaces + .touch_mode[Touch_Resist_RF][SET_CUR_VALUE]; + if (temp_value == 0) { + nvt_game_value[0] = 0x76; + } else if (temp_value == 1) { + nvt_game_value[0] = 0x75; + } + nvt_game_value[1] = 0; + break; + default: + /* Don't support */ + skip = true; + break; + }; + + NVT_LOG("mode:%d, value:%d,temp_value:%d,game value:0x%x,0x%x", + nvt_mode, nvt_value, temp_value, nvt_game_value[0], + nvt_game_value[1]); + + if (!skip) { + xiaomi_touch_interfaces.touch_mode[nvt_mode][GET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[nvt_mode][SET_CUR_VALUE]; + + ret = nvt_touchfeature_set(nvt_game_value); + if (ret < 0) { + NVT_ERR("change game mode fail"); + } + } else { + NVT_LOG("Cmd is not support,skip!"); + } + + return 0; +} + +static char nvt_touch_vendor_read(void) +{ + char value = '4'; + NVT_LOG("%s Get touch vendor: %c\n", __func__, value); + return value; +} + +static u8 nvt_panel_vendor_read(void) +{ + char value = '0'; + int ret = 0; + if (!ts) + return value; + ret = dsi_panel_lockdown_info_read(ts->lockdown_info); + if (ret <= 0) { + NVT_ERR("can't get lockdown info"); + return value; + } + if (!ts->lockdown_info[6]) { + NVT_ERR("%s lockdown info is NULL\n", __func__); + return value; + } else { + value = ts->lockdown_info[1]; + NVT_LOG("%s Get touch vendor: %d\n", __func__, value); + } + return value; +} + +static u8 nvt_panel_color_read(void) +{ + char value = '0'; + int ret = 0; + if (!ts) + return value; + ret = dsi_panel_lockdown_info_read(ts->lockdown_info); + if (ret <= 0) { + NVT_ERR("can't get lockdown info"); + return value; + } + if (!ts->lockdown_info[2]) { + NVT_ERR("%s lockdown info is NULL\n", __func__); + return value; + } else { + value = ts->lockdown_info[2]; + NVT_LOG("%s Get touch vendor: %d\n", __func__, value); + } + return value; +} + +static u8 nvt_panel_display_read(void) +{ + char value = '0'; + int ret = 0; + if (!ts) + return value; + ret = dsi_panel_lockdown_info_read(ts->lockdown_info); + if (ret <= 0) { + NVT_ERR("can't get lockdown info"); + return value; + } + if (!ts->lockdown_info[1]) { + NVT_ERR("%s lockdown info is NULL\n", __func__); + return value; + } else { + value = ts->lockdown_info[1]; + NVT_LOG("%s Get touch vendor: %d\n", __func__, value); + } + return value; +} + +static int nvt_get_mode_value(int mode, int value_type) +{ + int value = -1; + + if (mode < Touch_Mode_NUM && mode >= 0) + value = xiaomi_touch_interfaces.touch_mode[mode][value_type]; + else + NVT_ERR("%s, don't support\n", __func__); + + return value; +} + +static int nvt_get_mode_all(int mode, int *value) +{ + if (mode < Touch_Mode_NUM && mode >= 0) { + value[0] = + xiaomi_touch_interfaces.touch_mode[mode][GET_CUR_VALUE]; + value[1] = + xiaomi_touch_interfaces.touch_mode[mode][GET_DEF_VALUE]; + value[2] = + xiaomi_touch_interfaces.touch_mode[mode][GET_MIN_VALUE]; + value[3] = + xiaomi_touch_interfaces.touch_mode[mode][GET_MAX_VALUE]; + } else { + NVT_ERR("%s, don't support\n", __func__); + } + NVT_LOG("%s, mode:%d, value:%d:%d:%d:%d\n", __func__, mode, value[0], + value[1], value[2], value[3]); + + return 0; +} + +static int nvt_reset_mode(int mode) +{ + int i = 0; + + NVT_LOG("nvt_reset_mode enter\n"); + + if (mode < Touch_Report_Rate && mode > 0) { + xiaomi_touch_interfaces.touch_mode[mode][SET_CUR_VALUE] = + xiaomi_touch_interfaces.touch_mode[mode][GET_DEF_VALUE]; + nvt_set_cur_value( + mode, + xiaomi_touch_interfaces.touch_mode[mode][SET_CUR_VALUE]); + } else if (mode == 0) { + for (i = 0; i <= Touch_Report_Rate; i++) { + if (i == Touch_Panel_Orientation) { + xiaomi_touch_interfaces + .touch_mode[i][SET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[i][GET_CUR_VALUE]; + } else { + xiaomi_touch_interfaces + .touch_mode[i][SET_CUR_VALUE] = + xiaomi_touch_interfaces + .touch_mode[i][GET_DEF_VALUE]; + } + nvt_set_cur_value( + i, xiaomi_touch_interfaces + .touch_mode[i][SET_CUR_VALUE]); + } + } else { + NVT_ERR("%s, don't support\n", __func__); + } + + NVT_LOG("%s, mode:%d\n", __func__, mode); + + return 0; +} +#endif + +#ifdef CONFIG_TOUCHSCREEN_NVT_DEBUG_FS + +/*static void tpdbg_shutdown(struct nvt_ts_data *ts_core, bool enable) +{ + mutex_lock(&ts->lock); + if (enable) { + if (nvt_write_addr(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD, 0x1A) < 0) { + NVT_ERR("disable tp sensor failed!"); + } + } else { + if (nvt_write_addr(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD, 0x15) < 0) { + NVT_ERR("enable tp sensor failed!"); + } + } + mutex_unlock(&ts->lock); +}*/ + +static void tpdbg_suspend(struct nvt_ts_data *ts_core, bool enable) +{ + if (enable) + nvt_ts_suspend(&ts_core->client->dev); + else + nvt_ts_resume(&ts_core->client->dev); +} + +static int tpdbg_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + + return 0; +} + +static ssize_t tpdbg_read(struct file *file, char __user *buf, size_t size, + loff_t *ppos) +{ + const char *str = "cmd support as below:\n \ + echo \"irq-disable\" or \"irq-enable\" to ctrl irq\n \ + echo \"tp-sd-en\" or \"tp-sd-off\" to ctrl panel on or off sensor\n \ + echo \"tp-suspend-en\" or \"tp-suspend-off\" to ctrl panel in or off suspend status\n \ + echo \"fw-debug-on\" or \"fw-debug-off\" to on or off fw debug function\n"; + + loff_t pos = *ppos; + int len = strlen(str); + + if (pos < 0) + return -EINVAL; + if (pos >= len) + return 0; + + if (copy_to_user(buf, str, len)) + return -EFAULT; + + *ppos = pos + len; + + return len; +} + +static ssize_t tpdbg_write(struct file *file, const char __user *buf, + size_t size, loff_t *ppos) +{ + struct nvt_ts_data *ts_core = file->private_data; + char *cmd = kzalloc(size + 1, GFP_KERNEL); + int ret = size; + + if (!cmd) + return -ENOMEM; + + if (copy_from_user(cmd, buf, size)) { + ret = -EFAULT; + goto out; + } + +#if NVT_TOUCH_ESD_PROTECT + cancel_delayed_work_sync(&nvt_esd_check_work); + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + cmd[size] = '\0'; + + if (!strncmp(cmd, "irq-disable", 11)) + nvt_irq_enable(false); + else if (!strncmp(cmd, "irq-enable", 10)) + nvt_irq_enable(true); + else if (!strncmp(cmd, "tp-sd-en", 8)) + tpdbg_suspend(ts_core, true); + else if (!strncmp(cmd, "tp-sd-off", 9)) + tpdbg_suspend(ts_core, false); + else if (!strncmp(cmd, "tp-suspend-en", 13)) + tpdbg_suspend(ts_core, true); + else if (!strncmp(cmd, "tp-suspend-off", 14)) + tpdbg_suspend(ts_core, false); + else if (!strncmp(cmd, "fw-debug-on", 11)) + nvt_set_dbgfw_status(true); + else if (!strncmp(cmd, "fw-debug-off", 12)) + nvt_set_dbgfw_status(false); +out: + kfree(cmd); + + return ret; +} + +static int tpdbg_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + + return 0; +} + +static ssize_t nvt_touch_test_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + int retval = -1; + uint8_t cmd[8]; + if (copy_from_user(cmd, buf, count)) { + retval = -EFAULT; + goto out; + } + switch (cmd[0]) { + case '0': + ts->debug_flag = 0; + break; + case '1': + ts->debug_flag = 1; + break; + case '2': + ts->debug_flag = 2; + break; + default: + NVT_LOG("%s invalid input cmd, set default value\n", __func__); + ts->debug_flag = 2; + } + NVT_LOG("%s set touch boost debug flag to %d\n", __func__, + ts->debug_flag); + retval = count; +out: + return retval; +} + +static const struct file_operations nvt_touch_test_fops = { + .owner = THIS_MODULE, + .write = nvt_touch_test_write, +}; + +static const struct file_operations tpdbg_ops = { + .owner = THIS_MODULE, + .open = tpdbg_open, + .read = tpdbg_read, + .write = tpdbg_write, + .release = tpdbg_release, +}; +#endif + +/* +static void nvt_suspend_work(struct work_struct *work) +{ + struct nvt_ts_data *ts_core = container_of(work, struct nvt_ts_data, suspend_work); + nvt_ts_suspend(&ts_core->client->dev); +} +*/ + +static void nvt_resume_work(struct work_struct *work) +{ + struct nvt_ts_data *ts_core = + container_of(work, struct nvt_ts_data, resume_work); + nvt_ts_resume(&ts_core->client->dev); +} + +static void get_lockdown_info(struct work_struct *work) +{ + int ret = 0; + + NVT_LOG("lkdown_readed = %d", ts->lkdown_readed); + + if (!ts->lkdown_readed) { + ret = dsi_panel_lockdown_info_read(ts->lockdown_info); + if (ret < 0) { + NVT_ERR("can't get lockdown info"); + } else { + NVT_LOG("Lockdown:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", + ts->lockdown_info[0], ts->lockdown_info[1], + ts->lockdown_info[2], ts->lockdown_info[3], + ts->lockdown_info[4], ts->lockdown_info[5], + ts->lockdown_info[6], ts->lockdown_info[7]); + } + ts->lkdown_readed = true; + NVT_LOG("READ LOCKDOWN!!!"); + } else { + NVT_LOG("use lockdown info that readed before"); + NVT_LOG("Lockdown:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", + ts->lockdown_info[0], ts->lockdown_info[1], + ts->lockdown_info[2], ts->lockdown_info[3], + ts->lockdown_info[4], ts->lockdown_info[5], + ts->lockdown_info[6], ts->lockdown_info[7]); + } +} + +/******************************************************* +Description: + Novatek touchscreen driver probe function. + +return: + Executive outcomes. 0---succeed. negative---failed +*******************************************************/ +static int32_t nvt_ts_probe(struct platform_device *pdev) +{ + struct spi_device *ts_xsfer; + int32_t ret = 0; + int32_t retry = 0; + struct attribute_group *attrs_p = NULL; + + NVT_LOG("start\n"); + + ts = kzalloc(sizeof(struct nvt_ts_data), GFP_KERNEL); + if (ts == NULL) { + NVT_ERR("failed to allocated memory for nvt ts data\n"); + return -ENOMEM; + } + ts->xbuf = (uint8_t *)kzalloc((NVT_TRANSFER_LEN + 1), GFP_KERNEL); + if (ts->xbuf == NULL) { + NVT_ERR("kzalloc for xbuf failed!\n"); + if (ts) { + kfree(ts); + ts = NULL; + } + return -ENOMEM; + } + + ts->pdev = pdev; + for (retry = 1; retry <= 3; ++retry) { + ret = tmp_hold_ts_xsfer(&ts_xsfer); + if (ret < 0) { + if (ret == -EBUSY) { + NVT_ERR("tmp hold ts_xsfer failed, retry:%d\n", + retry); + mdelay(100); + continue; + } else if (ret == -EPERM) { + NVT_ERR("ts_xsfer has been used, exit nvt probe\n"); + goto err_get_spi; + } else if (ret == -EINVAL) { + NVT_ERR("ts_xsfer not exist, exit nvt probe\n"); + goto err_get_spi; + } + } else { + break; + } + } + if (ret == -EBUSY) { + NVT_ERR("ts_xsfer always busy, exit nvt probe\n"); + goto err_get_spi; + } + + /* ---parse dts--- */ + ret = nvt_parse_dt(&pdev->dev); + if (ret) { + NVT_ERR("parse dt error\n"); + goto err_spi_setup; + } + + ts->client = ts_xsfer; + spi_set_drvdata(ts->client, ts); + + /* ---prepare for spi parameter--- */ + if (ts->client->master->flags & SPI_MASTER_HALF_DUPLEX) { + NVT_ERR("Full duplex not supported by master\n"); + ret = -EIO; + goto err_ckeck_full_duplex; + } + ts->client->bits_per_word = 8; + ts->client->mode = SPI_MODE_0; + ts->client->max_speed_hz = ts->spi_max_freq; + ts->debug_flag = 2; + + ret = spi_setup(ts->client); + if (ret < 0) { + NVT_ERR("Failed to perform SPI setup\n"); + goto err_spi_setup; + } + +#ifdef CONFIG_MTK_SPI + /* old usage of MTK spi API */ + memcpy(&ts->spi_ctrl, &spi_ctrdata, sizeof(struct mt_chip_conf)); + ts->client->controller_data = (void *)&ts->spi_ctrl; +#endif + +#ifdef CONFIG_SPI_MT65XX + /* new usage of MTK spi API */ + memcpy(&ts->spi_ctrl, &spi_ctrdata, sizeof(struct mtk_chip_config)); + ts->client->controller_data = (void *)&ts->spi_ctrl; +#endif + + NVT_LOG("mode=%d, max_speed_hz=%d\n", ts->client->mode, + ts->client->max_speed_hz); + + ret = nvt_pinctrl_init(ts); + if (!ret && ts->ts_pinctrl) { + ret = pinctrl_select_state(ts->ts_pinctrl, + ts->pinctrl_state_active); + + if (ret < 0) { + NVT_ERR("Failed to select %s pinstate %d\n", + PINCTRL_STATE_ACTIVE, ret); + } + } else { + NVT_ERR("Failed to init pinctrl\n"); + } + + NVT_LOG("Request GPIO\n"); + /* ---request and config GPIOs--- */ + ret = nvt_gpio_config(ts); + if (ret) { + NVT_ERR("gpio config error!\n"); + goto err_gpio_config_failed; + } + + mutex_init(&ts->lock); + mutex_init(&ts->xbuf_lock); + + /* ---eng reset before TP_RESX high */ + + nvt_eng_reset(); +#if NVT_TOUCH_SUPPORT_HW_RST + gpio_set_value(ts->reset_gpio, 1); +#endif + NVT_LOG("gpio set complete\n"); + /* need 10ms delay after POR(power on reset) */ + msleep(10); + + /* ---check chip version trim--- */ + NVT_LOG("start check chip\n"); + ret = nvt_ts_check_chip_ver_trim(); + if (ret) { + NVT_ERR("chip is not identified\n"); + ret = -EINVAL; + goto err_chipvertrim_failed; + } + NVT_LOG("finish check chip\n"); + + get_ts_xsfer(NVT_SPI_NAME); + tmp_drop_ts_xsfer(); + ts->abs_x_max = TOUCH_DEFAULT_MAX_WIDTH; + ts->abs_y_max = TOUCH_DEFAULT_MAX_HEIGHT; + ts->input_dev = input_allocate_device(); + if (ts->input_dev == NULL) { + NVT_ERR("allocate input device failed\n"); + ret = -ENOMEM; + goto err_input_dev_alloc_failed; + } + + ts->max_touch_num = TOUCH_MAX_FINGER_NUM; + + ts->int_trigger_type = INT_TRIGGER_TYPE; + + ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | + BIT_MASK(EV_ABS); + __set_bit(BTN_TOUCH, ts->input_dev->keybit); + __set_bit(BTN_TOOL_FINGER, ts->input_dev->keybit); + ts->input_dev->propbit[0] = BIT(INPUT_PROP_DIRECT); + +#if MT_PROTOCOL_B + input_mt_init_slots(ts->input_dev, ts->max_touch_num, 0); +#endif + +#if TOUCH_MAX_FINGER_NUM > 1 + /*input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);*/ + + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, + ts->abs_x_max - 1, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, + ts->abs_y_max - 1, 0, 0); +#if MT_PROTOCOL_B + /* no need to set ABS_MT_TRACKING_ID, input_mt_init_slots() already set it */ +#else + input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, + ts->max_touch_num, 0, 0); +#endif +#endif + +#if WAKEUP_GESTURE + input_set_capability(ts->input_dev, EV_KEY, KEY_WAKEUP); +#endif + + sprintf(ts->phys, "input/ts"); + ts->input_dev->name = NVT_TS_NAME; + ts->input_dev->phys = ts->phys; + ts->input_dev->id.bustype = BUS_SPI; + + input_set_drvdata(ts->input_dev, ts); + ret = input_register_device(ts->input_dev); + if (ret) { + NVT_ERR("register input device (%s) failed. ret=%d\n", + ts->input_dev->name, ret); + goto err_input_register_device_failed; + } + + ts->client->irq = gpio_to_irq(ts->irq_gpio); + if (ts->client->irq) { + NVT_LOG("int_trigger_type=%d\n", ts->int_trigger_type); + ts->irq_enabled = true; + ret = request_threaded_irq(ts->client->irq, NULL, + nvt_ts_work_func, + ts->int_trigger_type | IRQF_ONESHOT, + NVT_SPI_NAME, ts); + if (ret != 0) { + NVT_ERR("request irq failed. ret=%d\n", ret); + goto err_int_request_failed; + } else { + nvt_irq_enable(false); + NVT_LOG("request irq %d succeed\n", ts->client->irq); + } + } + + INIT_WORK(&ts->switch_mode_work, nvt_switch_mode_work); + + pm_stay_awake(&ts->pdev->dev); + nvt_lockdown_wq = alloc_workqueue("nvt_lockdown_wq", + WQ_UNBOUND | WQ_MEM_RECLAIM, 1); + if (!nvt_lockdown_wq) { + NVT_ERR("nvt_fwu_wq create workqueue failed\n"); + ret = -ENOMEM; + goto err_create_nvt_lockdown_wq_failed; + } + INIT_DELAYED_WORK(&ts->nvt_lockdown_work, get_lockdown_info); + /* please make sure boot update start after display reset(RESX) sequence*/ + queue_delayed_work(nvt_lockdown_wq, &ts->nvt_lockdown_work, + msecs_to_jiffies(1000)); + +#if WAKEUP_GESTURE + device_init_wakeup(&ts->input_dev->dev, 1); +#endif + ts->ic_state = NVT_IC_INIT; + ts->dev_pm_suspend = false; + ts->gesture_command_delayed = -1; + init_completion(&ts->dev_pm_suspend_completion); + +#if BOOT_UPDATE_FIRMWARE + nvt_fwu_wq = + alloc_workqueue("nvt_fwu_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 1); + if (!nvt_fwu_wq) { + NVT_ERR("nvt_fwu_wq create workqueue failed\n"); + ret = -ENOMEM; + goto err_create_nvt_fwu_wq_failed; + } + INIT_DELAYED_WORK(&ts->nvt_fwu_work, Boot_Update_Firmware); + /* please make sure boot update start after display reset(RESX) sequence */ + queue_delayed_work(nvt_fwu_wq, &ts->nvt_fwu_work, + msecs_to_jiffies(10000)); +#endif + + NVT_LOG("NVT_TOUCH_ESD_PROTECT is %d\n", NVT_TOUCH_ESD_PROTECT); +#if NVT_TOUCH_ESD_PROTECT + INIT_DELAYED_WORK(&nvt_esd_check_work, nvt_esd_check_func); + nvt_esd_check_wq = + alloc_workqueue("nvt_esd_check_wq", WQ_MEM_RECLAIM, 1); + if (!nvt_esd_check_wq) { + NVT_ERR("nvt_esd_check_wq create workqueue failed\n"); + ret = -ENOMEM; + goto err_create_nvt_esd_check_wq_failed; + } + queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work, + msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD)); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + +#if NVT_TOUCH_PROC + ret = nvt_flash_proc_init(); + if (ret != 0) { + NVT_ERR("nvt flash proc init failed. ret=%d\n", ret); + goto err_flash_proc_init_failed; + } +#endif + +#if NVT_TOUCH_EXT_PROC + ret = nvt_extra_proc_init(); + if (ret != 0) { + NVT_ERR("nvt extra proc init failed. ret=%d\n", ret); + goto err_extra_proc_init_failed; + } +#endif + +#if NVT_TOUCH_MP + ret = nvt_mp_proc_init(); + if (ret != 0) { + NVT_ERR("nvt mp proc init failed. ret=%d\n", ret); + goto err_mp_proc_init_failed; + } + +#ifndef NVT_SAVE_TESTDATA_IN_FILE + ret = nvt_test_data_proc_init(ts->client); + if (ret < 0) { + NVT_ERR("nvt test data interface init failed. ret=%d\n", ret); + goto err_mp_proc_init_failed; + } +#endif + +#endif + attrs_p = (struct attribute_group *)devm_kzalloc( + &pdev->dev, sizeof(*attrs_p), GFP_KERNEL); + if (!attrs_p) { + NVT_ERR("no mem to alloc"); + goto err_mp_proc_init_failed; + } + ts->attrs = attrs_p; + attrs_p->name = "panel_info"; + attrs_p->attrs = nvt_panel_attr; + ret = sysfs_create_group(&pdev->dev.kobj, ts->attrs); + + ts->event_wq = + alloc_workqueue("nvt-event-queue", + WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); + if (!ts->event_wq) { + NVT_ERR("Can not create work thread for suspend/resume!!"); + ret = -ENOMEM; + goto err_alloc_work_thread_failed; + } + INIT_WORK(&ts->resume_work, nvt_resume_work); + /*INIT_WORK(&ts->suspend_work, nvt_suspend_work);*/ + +#ifdef CONFIG_DRM + ts->drm_notif.notifier_call = nvt_drm_notifier_callback; + ret = drm_register_client(&ts->drm_notif); + if (ret) { + NVT_ERR("register drm_notifier failed. ret=%d\n", ret); + goto err_register_drm_notif_failed; + } +#else + ts->fb_notif.notifier_call = nvt_fb_notifier_callback; + ret = fb_register_client(&ts->fb_notif); + if (ret) { + NVT_ERR("register fb_notifier failed. ret=%d\n", ret); + goto err_register_fb_notif_failed; + } +#endif +#if defined(CONFIG_HAS_EARLYSUSPEND) + ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + ts->early_suspend.suspend = nvt_ts_early_suspend; + ts->early_suspend.resume = nvt_ts_late_resume; + ret = register_early_suspend(&ts->early_suspend); + if (ret) { + NVT_ERR("register early suspend failed. ret=%d\n", ret); + goto err_register_early_suspend_failed; + } +#endif + +#ifdef CONFIG_TOUCHSCREEN_NVT_DEBUG_FS + ts->debugfs = debugfs_create_dir("tp_debug", NULL); + if (ts->debugfs) { + debugfs_create_file("switch_state", 0660, ts->debugfs, ts, + &tpdbg_ops); + debugfs_create_file("touch_boost", 0660, ts->debugfs, ts, + &nvt_touch_test_fops); + } +#endif +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + xiaomi_touch_interfaces.touch_vendor_read = nvt_touch_vendor_read; + xiaomi_touch_interfaces.panel_display_read = nvt_panel_display_read; + xiaomi_touch_interfaces.panel_vendor_read = nvt_panel_vendor_read; + xiaomi_touch_interfaces.panel_color_read = nvt_panel_color_read; + xiaomi_touch_interfaces.getModeValue = nvt_get_mode_value; + xiaomi_touch_interfaces.setModeValue = nvt_set_cur_value; + xiaomi_touch_interfaces.resetMode = nvt_reset_mode; + xiaomi_touch_interfaces.getModeAll = nvt_get_mode_all; + xiaomi_touch_interfaces.palm_sensor_write = nvt_palm_sensor_write; + nvt_init_touchmode_data(); + xiaomitouch_register_modedata(&xiaomi_touch_interfaces); +#endif + + bTouchIsAwake = 1; + NVT_LOG("end\n"); + + nvt_irq_enable(true); + + return 0; + +#ifdef CONFIG_DRM + if (drm_unregister_client(&ts->drm_notif)) + NVT_ERR("Error occurred while unregistering drm_notifier.\n"); +err_register_drm_notif_failed: +#else + if (fb_unregister_client(&ts->fb_notif)) + NVT_ERR("Error occurred while unregistering fb_notifier.\n"); +err_register_fb_notif_failed: +#endif +#if defined(CONFIG_HAS_EARLYSUSPEND) + unregister_early_suspend(&ts->early_suspend); +err_register_early_suspend_failed: +#endif + destroy_workqueue(ts->event_wq); +err_alloc_work_thread_failed: +#if NVT_TOUCH_MP + nvt_mp_proc_deinit(); +err_mp_proc_init_failed: +#endif +#if NVT_TOUCH_EXT_PROC + nvt_extra_proc_deinit(); +err_extra_proc_init_failed: +#endif +#if NVT_TOUCH_PROC + nvt_flash_proc_deinit(); +err_flash_proc_init_failed: +#endif +#if NVT_TOUCH_ESD_PROTECT + if (nvt_esd_check_wq) { + cancel_delayed_work_sync(&nvt_esd_check_work); + destroy_workqueue(nvt_esd_check_wq); + nvt_esd_check_wq = NULL; + } +err_create_nvt_esd_check_wq_failed: +#endif +#if BOOT_UPDATE_FIRMWARE + if (nvt_fwu_wq) { + cancel_delayed_work_sync(&ts->nvt_fwu_work); + destroy_workqueue(nvt_fwu_wq); + nvt_fwu_wq = NULL; + } +err_create_nvt_fwu_wq_failed: + if (nvt_lockdown_wq) { + cancel_delayed_work_sync(&ts->nvt_lockdown_work); + destroy_workqueue(nvt_lockdown_wq); + nvt_lockdown_wq = NULL; + } +#endif +err_create_nvt_lockdown_wq_failed: + pm_relax(&ts->pdev->dev); +#if WAKEUP_GESTURE + device_init_wakeup(&ts->input_dev->dev, 0); +#endif + free_irq(ts->client->irq, ts); +err_int_request_failed: + input_unregister_device(ts->input_dev); + ts->input_dev = NULL; +err_input_register_device_failed: + if (ts->input_dev) { + input_free_device(ts->input_dev); + ts->input_dev = NULL; + } +err_input_dev_alloc_failed: +err_chipvertrim_failed: + mutex_destroy(&ts->xbuf_lock); + mutex_destroy(&ts->lock); + nvt_gpio_deconfig(ts); +err_gpio_config_failed: +err_spi_setup: +err_ckeck_full_duplex: + spi_set_drvdata(ts->client, NULL); +err_get_spi: + tmp_drop_ts_xsfer(); + if (ts->xbuf) { + kfree(ts->xbuf); + ts->xbuf = NULL; + } + if (ts) { + kfree(ts); + ts = NULL; + } + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen driver release function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t nvt_ts_remove(struct platform_device *pdev) +{ + NVT_LOG("Removing driver...\n"); + +#ifdef CONFIG_DRM + if (drm_unregister_client(&ts->drm_notif)) + NVT_ERR("Error occurred while unregistering drm_notifier.\n"); +#else + if (fb_unregister_client(&ts->fb_notif)) + NVT_ERR("Error occurred while unregistering fb_notifier.\n"); +#endif +#if defined(CONFIG_HAS_EARLYSUSPEND) + unregister_early_suspend(&ts->early_suspend); +#endif +#ifndef NVT_SAVE_TESTDATA_IN_FILE + nvt_test_data_proc_deinit(); +#endif +#if NVT_TOUCH_MP + nvt_mp_proc_deinit(); +#endif +#if NVT_TOUCH_EXT_PROC + nvt_extra_proc_deinit(); +#endif +#if NVT_TOUCH_PROC + nvt_flash_proc_deinit(); +#endif + +#if NVT_TOUCH_ESD_PROTECT + if (nvt_esd_check_wq) { + cancel_delayed_work_sync(&nvt_esd_check_work); + nvt_esd_check_enable(false); + destroy_workqueue(nvt_esd_check_wq); + nvt_esd_check_wq = NULL; + } +#endif + +#if BOOT_UPDATE_FIRMWARE + if (nvt_fwu_wq) { + cancel_delayed_work_sync(&ts->nvt_fwu_work); + destroy_workqueue(nvt_fwu_wq); + nvt_fwu_wq = NULL; + } +#endif + +#if WAKEUP_GESTURE + device_init_wakeup(&ts->input_dev->dev, 0); +#endif + + nvt_irq_enable(false); + free_irq(ts->client->irq, ts); + + mutex_destroy(&ts->xbuf_lock); + mutex_destroy(&ts->lock); + + nvt_gpio_deconfig(ts); + + if (ts->input_dev) { + input_unregister_device(ts->input_dev); + ts->input_dev = NULL; + } + + spi_set_drvdata(ts->client, NULL); + + put_ts_xsfer(NVT_SPI_NAME); + if (ts) { + kfree(ts); + ts = NULL; + } + + return 0; +} + +static void nvt_ts_shutdown(struct platform_device *pdev) +{ + NVT_LOG("Shutdown driver...\n"); + + nvt_irq_enable(false); + +#ifdef CONFIG_DRM + if (drm_unregister_client(&ts->drm_notif)) + NVT_ERR("Error occurred while unregistering drm_notifier.\n"); +#else + if (fb_unregister_client(&ts->fb_notif)) + NVT_ERR("Error occurred while unregistering fb_notifier.\n"); +#endif +#if defined(CONFIG_HAS_EARLYSUSPEND) + unregister_early_suspend(&ts->early_suspend); +#endif +#if NVT_TOUCH_MP + nvt_mp_proc_deinit(); +#endif +#if NVT_TOUCH_EXT_PROC + nvt_extra_proc_deinit(); +#endif +#if NVT_TOUCH_PROC + nvt_flash_proc_deinit(); +#endif + +#if NVT_TOUCH_ESD_PROTECT + if (nvt_esd_check_wq) { + cancel_delayed_work_sync(&nvt_esd_check_work); + nvt_esd_check_enable(false); + destroy_workqueue(nvt_esd_check_wq); + nvt_esd_check_wq = NULL; + } +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + +#if WAKEUP_GESTURE + device_init_wakeup(&ts->input_dev->dev, 0); +#endif +} + +/******************************************************* +Description: + Novatek touchscreen driver suspend function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t nvt_ts_suspend(struct device *dev) +{ + uint8_t buf[4] = { 0 }; +#if MT_PROTOCOL_B + uint32_t i = 0; +#endif + int ret = 0; + if (!bTouchIsAwake) { + NVT_LOG("Touch is already suspend\n"); + return 0; + } + pm_stay_awake(dev); + ts->ic_state = NVT_IC_SUSPEND_IN; + +#if NVT_TOUCH_ESD_PROTECT + NVT_LOG("cancel delayed work sync\n"); + cancel_delayed_work_sync(&nvt_esd_check_work); + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + NVT_LOG("start\n"); + + if (!ts->db_wakeup) + nvt_irq_enable(false); /*must before hold lock*/ + + mutex_lock(&ts->lock); + bTouchIsAwake = 0; + +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + if (ts->palm_sensor_switch) { + NVT_LOG("palm sensor on status, switch to off\n"); + update_palm_sensor_value(0); + nvt_set_pocket_palm_switch(false); + } +#endif + mdelay(10); + if (ts->db_wakeup) { + /* ---write command to enter "wakeup gesture mode"--- */ + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x13; + CTP_SPI_WRITE(ts->client, buf, 2); + + enable_irq_wake(ts->client->irq); + + NVT_LOG("Enabled touch wakeup gesture\n"); + + } else { + /* ---write command to enter "deep sleep mode"--- */ + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x11; + CTP_SPI_WRITE(ts->client, buf, 2); + if (ts->ts_pinctrl) { + ret = pinctrl_select_state(ts->ts_pinctrl, + ts->pinctrl_state_suspend); + + if (ret < 0) { + NVT_ERR("Failed to select %s pinstate %d\n", + PINCTRL_STATE_SUSPEND, ret); + } + } else { + NVT_ERR("Failed to init pinctrl\n"); + } + } + mdelay(10); + mutex_unlock(&ts->lock); + /* release all touches */ +#if MT_PROTOCOL_B + for (i = 0; i < ts->max_touch_num; i++) { + input_mt_slot(ts->input_dev, i); + /*input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);*/ + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); + } +#endif + input_report_key(ts->input_dev, BTN_TOOL_FINGER, 0); + input_report_key(ts->input_dev, BTN_TOUCH, 0); +#if !MT_PROTOCOL_B + input_mt_sync(ts->input_dev); +#endif + input_sync(ts->input_dev); + + msleep(50); + if (likely(ts->ic_state == NVT_IC_SUSPEND_IN)) + ts->ic_state = NVT_IC_SUSPEND_OUT; + else + NVT_ERR("IC state may error,caused by suspend/resume flow, please CHECK!!"); + NVT_LOG("end\n"); + pm_relax(dev); + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen driver resume function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t nvt_ts_resume(struct device *dev) +{ + int ret; + if (ts->dev_pm_suspend) + pm_stay_awake(dev); + if (!ts->db_wakeup) { + if (ts->ts_pinctrl) { + ret = pinctrl_select_state(ts->ts_pinctrl, + ts->pinctrl_state_active); + + if (ret < 0) { + NVT_ERR("Failed to select %s pinstate %d\n", + PINCTRL_STATE_ACTIVE, ret); + } + } else { + NVT_ERR("Failed to init pinctrl\n"); + } + } + if (bTouchIsAwake) { + NVT_LOG("Touch is already resume\n"); +#if NVT_TOUCH_WDT_RECOVERY + mutex_lock(&ts->lock); + if (nvt_get_dbgfw_status()) { + ret = nvt_update_firmware(DEFAULT_DEBUG_FW_NAME); + } else { + ret = nvt_update_firmware(ts->fw_name); + } + mutex_unlock(&ts->lock); +#endif /* #if NVT_TOUCH_WDT_RECOVERY */ + goto Exit; + } + + ts->ic_state = NVT_IC_RESUME_IN; + + mutex_lock(&ts->lock); + NVT_LOG("start\n"); + + /* please make sure display reset(RESX) sequence and mipi dsi cmds sent before this */ +#if NVT_TOUCH_SUPPORT_HW_RST + gpio_set_value(ts->reset_gpio, 1); +#endif + if (nvt_get_dbgfw_status()) { + ret = nvt_update_firmware(DEFAULT_DEBUG_FW_NAME); + if (ret < 0) { + NVT_ERR("use built-in fw"); + ret = nvt_update_firmware(ts->fw_name); + } + } else { + ret = nvt_update_firmware(ts->fw_name); + } + if (ret) + NVT_ERR("download firmware failed\n"); + nvt_check_fw_reset_state(RESET_STATE_REK); + + nvt_irq_enable(true); + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); + queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work, + msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD)); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + bTouchIsAwake = 1; +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE + NVT_LOG("palm_sensor_switch=%d", ts->palm_sensor_switch); + if (ts->palm_sensor_switch) { + NVT_LOG("palm sensor on status, switch to on\n"); + nvt_set_pocket_palm_switch(true); + } +#endif + mutex_unlock(&ts->lock); + dsi_panel_doubleclick_enable( + !!ts->db_wakeup); /*if true, dbclick work until next suspend*/ + if (likely(ts->ic_state == NVT_IC_RESUME_IN)) + ts->ic_state = NVT_IC_RESUME_OUT; + else + NVT_ERR("IC state may error,caused by suspend/resume flow, please CHECK!!"); + + if (ts->gesture_command_delayed >= 0) { + ts->db_wakeup = ts->gesture_command_delayed; + ts->gesture_command_delayed = -1; + NVT_LOG("execute delayed command, set double click wakeup %d\n", + ts->db_wakeup); + dsi_panel_doubleclick_enable(!!ts->db_wakeup); + } +Exit: + if (ts->dev_pm_suspend) + pm_relax(dev); + NVT_LOG("end\n"); + + return 0; +} + +#ifdef CONFIG_DRM +static int nvt_drm_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct drm_notify_data *evdata = data; + int *blank; + struct nvt_ts_data *ts_data = + container_of(self, struct nvt_ts_data, drm_notif); + + if (evdata && ts_data) { + blank = evdata->data; + NVT_LOG("%s: event:%lu,blank:%u\n", event, blank); + + if (event == DRM_EARLY_EVENT_BLANK) { + if (*blank == DRM_BLANK_POWERDOWN) { + NVT_LOG("event=%lu, *blank=%d\n", event, + *blank); + flush_workqueue(ts_data->event_wq); + nvt_ts_suspend(&ts_data->client->dev); + } + } else if (event == DRM_EVENT_BLANK) { + if (*blank == DRM_BLANK_UNBLANK) { + NVT_LOG("event=%lu, *blank=%d\n", event, + *blank); + flush_workqueue(ts_data->event_wq); + queue_work(ts_data->event_wq, + &ts_data->resume_work); + } + } + } + return NOTIFY_OK; +} + +#else +static int nvt_fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + struct nvt_ts_data *ts = + container_of(self, struct nvt_ts_data, fb_notif); + + if (evdata && evdata->data && event == FB_EARLY_EVENT_BLANK) { + blank = evdata->data; + if (*blank == FB_BLANK_POWERDOWN) { + NVT_LOG("event=%lu, *blank=%d\n", event, *blank); + flush_workqueue(ts->event_wq); + nvt_ts_suspend(&ts->client->dev); + } + } else if (evdata && evdata->data && event == FB_EVENT_BLANK) { + blank = evdata->data; + if (*blank == FB_BLANK_UNBLANK) { + NVT_LOG("event=%lu, *blank=%d\n", event, *blank); + flush_workqueue(ts->event_wq); + queue_work(ts->event_wq, &ts->resume_work); + } + } + + return 0; +} +#endif + +static int nvt_pm_suspend(struct device *dev) +{ + if (device_may_wakeup(dev) && ts->db_wakeup) { + NVT_LOG("enable touch irq wake\n"); + enable_irq_wake(ts->client->irq); + } + ts->dev_pm_suspend = true; + reinit_completion(&ts->dev_pm_suspend_completion); + + return 0; +} + +static int nvt_pm_resume(struct device *dev) +{ + if (device_may_wakeup(dev) && ts->db_wakeup) { + NVT_LOG("disable touch irq wake\n"); + disable_irq_wake(ts->client->irq); + } + ts->dev_pm_suspend = false; + complete(&ts->dev_pm_suspend_completion); + + return 0; +} + +static const struct dev_pm_ops nvt_dev_pm_ops = { + .suspend = nvt_pm_suspend, + .resume = nvt_pm_resume, +}; + +#if defined(CONFIG_HAS_EARLYSUSPEND) +/******************************************************* +Description: + Novatek touchscreen driver early suspend function. + +return: + n.a. +*******************************************************/ +static void nvt_ts_early_suspend(struct early_suspend *h) +{ + nvt_ts_suspend(ts->client, PMSG_SUSPEND); +} + +/******************************************************* +Description: + Novatek touchscreen driver late resume function. + +return: + n.a. +*******************************************************/ +static void nvt_ts_late_resume(struct early_suspend *h) +{ + nvt_ts_resume(ts->client); +} +#endif + +static const struct platform_device_id nvt_ts_id[] = { + { NVT_SPI_NAME, 0 }, + {}, +}; + +#ifdef CONFIG_OF +static struct of_device_id nvt_match_table[] = { + { + .compatible = "novatek,NVT-ts-spi", + }, + {}, +}; +#endif + +static struct platform_driver nvt_driver = { + .probe = nvt_ts_probe, + .remove = nvt_ts_remove, + .shutdown = nvt_ts_shutdown, + .id_table = nvt_ts_id, + .driver = { + .name = NVT_SPI_NAME, + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &nvt_dev_pm_ops, +#endif +#ifdef CONFIG_OF + .of_match_table = nvt_match_table, +#endif + }, +}; + +static bool nvt_off_charger_mode(void) +{ + bool charger_mode = false; + char charger_node[8] = { '\0' }; + char *chose = (char *)strnstr(saved_command_line, "androidboot.mode=", + strlen(saved_command_line)); + if (chose) { + memcpy(charger_node, (chose + strlen("androidboot.mode=")), + sizeof(charger_node) - 1); + NVT_LOG("%s: charger_node is %s\n", __func__, charger_node); + if (!strncmp(charger_node, "charger", strlen("charger"))) { + charger_mode = true; + } + } + return charger_mode; +} + +/******************************************************* +Description: + Driver Install function. + +return: + Executive Outcomes. 0---succeed. not 0---failed. +********************************************************/ +static int32_t __init nvt_driver_init(void) +{ + int32_t ret = 0; + + NVT_LOG("start\n"); + if (nvt_off_charger_mode()) { + NVT_LOG("off_charger states, %s exit", __func__); + return 0; + } + + /* ---add platform driver--- */ + ret = platform_driver_register(&nvt_driver); + if (ret) { + NVT_ERR("failed to add nvt touch driver"); + goto err_driver; + } + + NVT_LOG("finished\n"); + +err_driver: + return ret; +} + +/******************************************************* +Description: + Driver uninstall function. + +return: + n.a. +********************************************************/ +static void __exit nvt_driver_exit(void) +{ + platform_driver_unregister(&nvt_driver); +} +late_initcall(nvt_driver_init); + +MODULE_DESCRIPTION("Novatek Touchscreen Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.h b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.h new file mode 100644 index 000000000000..130c28373106 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.h @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * + * $Revision: 32206 $ + * $Date: 2018-08-10 19:23:04 +0800 (週五, 10 八月 2018) $ + * + * 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 _LINUX_NVT_TOUCH_H +#define _LINUX_NVT_TOUCH_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif + +#include "nt36xxx_mem_map.h" + +#ifdef CONFIG_MTK_SPI +#include "mtk_spi.h" +#endif + +#ifdef CONFIG_SPI_MT65XX +#include +#endif + +#define FW_HISTORY_SIZE 128 +/*Lock down info size*/ +#define NVT_LOCKDOWN_SIZE 8 + +#define PINCTRL_STATE_ACTIVE "pmx_ts_active" +#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend" +#define PINCTRL_STATE_RELEASE "pmx_ts_release" + +#define TOUCH_DISABLE_LPM 1 +#define TOUCH_IRQ_BOOST 2 + +/* ---GPIO number--- */ +#define NVTTOUCH_RST_PIN 980 +#define NVTTOUCH_INT_PIN 943 + +/* ---INT trigger mode--- */ +/* #define IRQ_TYPE_EDGE_RISING 1 +#define IRQ_TYPE_EDGE_FALLING 2 */ +#define INT_TRIGGER_TYPE IRQ_TYPE_EDGE_RISING + +/* ---SPI driver info.--- */ +#define NVT_SPI_NAME "NVT-ts-spi" +#define NVT_LOG(fmt, args...) \ + pr_info("[%s] %s %d: " fmt, NVT_SPI_NAME, __func__, __LINE__, ##args) +#define NVT_ERR(fmt, args...) \ + pr_err("[%s] %s %d: " fmt, NVT_SPI_NAME, __func__, __LINE__, ##args) + +/* ---Input device info.--- */ +#define NVT_TS_NAME "NVTCapacitiveTouchScreen" + +/* ---Touch info.--- */ +#define TOUCH_DEFAULT_MAX_WIDTH 1080 +#define TOUCH_DEFAULT_MAX_HEIGHT 2400 +#define TOUCH_MAX_FINGER_NUM 10 +#define TOUCH_KEY_NUM 0 +#define TOUCH_FORCE_NUM 1000 + +/* Enable only when module have tp reset pin and connected to host */ +#define NVT_TOUCH_SUPPORT_HW_RST 1 + +/* ---Customerized func.--- */ +#define NVT_TOUCH_PROC 1 +#define NVT_TOUCH_EXT_PROC 1 +#define NVT_TOUCH_MP 1 +#define NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV 1 +#define MT_PROTOCOL_B 1 +#define WAKEUP_GESTURE 1 +#define FUNCPAGE_PALM 4 +#define PACKET_PALM_ON 3 +#define PACKET_PALM_OFF 4 + +#define BOOT_UPDATE_FIRMWARE 1 +#define DEFAULT_BOOT_UPDATE_FIRMWARE_FIRST "j20s_novatek_ts_fw01.bin" +#define DEFAULT_MP_UPDATE_FIRMWARE_FIRST "j20s_novatek_ts_mp01.bin" +#define DEFAULT_BOOT_UPDATE_FIRMWARE_SECOND "j20s_novatek_ts_fw02.bin" +#define DEFAULT_MP_UPDATE_FIRMWARE_SECOND "j20s_novatek_ts_mp02.bin" +#define DEFAULT_DEBUG_FW_NAME "novatek_debug_fw.bin" +#define DEFAULT_DEBUG_MP_NAME "novatek_debug_mp.bin" + +/* ---ESD Protect.--- */ +#define NVT_TOUCH_ESD_PROTECT 1 +#define NVT_TOUCH_ESD_CHECK_PERIOD 1500 /* ms */ +#define NVT_TOUCH_WDT_RECOVERY 1 +#define NVT_TOUCH_ESD_DISP_RECOVERY 1 + +struct nvt_config_info { + u8 tp_vendor; + u8 tp_color; + u8 display_maker; + u8 glass_vendor; + const char *nvt_fw_name; + const char *nvt_mp_name; + const char *nvt_limit_name; +}; + +enum nvt_ic_state { + NVT_IC_SUSPEND_IN, + NVT_IC_SUSPEND_OUT, + NVT_IC_RESUME_IN, + NVT_IC_RESUME_OUT, + NVT_IC_INIT, +}; + +struct nvt_ts_data { + struct spi_device *client; + struct platform_device *pdev; + struct input_dev *input_dev; + struct delayed_work nvt_fwu_work; + struct delayed_work nvt_lockdown_work; + struct work_struct switch_mode_work; + uint16_t addr; + int8_t phys[32]; + +#ifdef CONFIG_DRM + struct notifier_block drm_notif; +#else + struct notifier_block fb_notif; +#endif +#if defined(CONFIG_HAS_EARLYSUSPEND) + struct early_suspend early_suspend; +#endif + + uint8_t fw_ver; + uint8_t x_num; + uint8_t y_num; + uint16_t abs_x_max; + uint16_t abs_y_max; + uint8_t max_touch_num; + uint8_t max_button_num; + uint32_t int_trigger_type; + int32_t irq_gpio; + uint32_t irq_flags; + int32_t reset_gpio; + uint32_t reset_flags; + struct mutex lock; + const struct nvt_ts_mem_map *mmap; + uint8_t carrier_system; + uint8_t hw_crc; + uint16_t nvt_pid; + uint8_t rbuf[1025]; + uint8_t *xbuf; + struct mutex xbuf_lock; + bool irq_enabled; +#ifdef CONFIG_MTK_SPI + struct mt_chip_conf spi_ctrl; +#endif +#ifdef CONFIG_SPI_MT65XX + struct mtk_chip_config spi_ctrl; +#endif + struct pinctrl *ts_pinctrl; + struct pinctrl_state *pinctrl_state_active; + struct pinctrl_state *pinctrl_state_suspend; +#ifndef NVT_SAVE_TESTDATA_IN_FILE + void *testdata; +#endif + int db_wakeup; + bool lkdown_readed; + u8 lockdown_info[NVT_LOCKDOWN_SIZE]; + uint32_t config_array_size; + struct nvt_config_info *config_array; + int panel_index; + const u8 *fw_name; + const u8 *mp_name; + uint32_t spi_max_freq; + struct attribute_group *attrs; + /*bit map indicate which slot(0~9) has been used*/ + unsigned long slot_map[BITS_TO_LONGS(10)]; + bool fw_debug; +#ifdef CONFIG_TOUCHSCREEN_NVT_DEBUG_FS + struct dentry *debugfs; +#endif + struct workqueue_struct *event_wq; + struct work_struct suspend_work; + struct work_struct resume_work; + int result_type; + int ic_state; + int gesture_command_delayed; + bool dev_pm_suspend; + struct completion dev_pm_suspend_completion; + bool palm_sensor_switch; + uint8_t debug_flag; +}; + +#if NVT_TOUCH_PROC +struct nvt_flash_data { + rwlock_t lock; +}; +#endif + +typedef enum { + RESET_STATE_INIT = 0xA0, /* IC reset */ + RESET_STATE_REK, /* ReK baseline */ + RESET_STATE_REK_FINISH, /* baseline is ready */ + RESET_STATE_NORMAL_RUN, /* normal run */ + RESET_STATE_MAX = 0xAF +} RST_COMPLETE_STATE; + +typedef enum { + EVENT_MAP_HOST_CMD = 0x50, + EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE = 0x51, + EVENT_MAP_RESET_COMPLETE = 0x60, + EVENT_MAP_FWINFO = 0x78, + EVENT_MAP_PROJECTID = 0x9A, +} SPI_EVENT_MAP; + +//---SPI READ/WRITE--- +#define SPI_WRITE_MASK(a) (a | 0x80) +#define SPI_READ_MASK(a) (a & 0x7F) + +#define DUMMY_BYTES (1) +#define NVT_TRANSFER_LEN (63 * 1024) + +typedef enum { + NVTWRITE = 0, + NVTREAD = 1, +} NVT_SPI_RW; + +//---extern structures--- +extern struct nvt_ts_data *ts; + +//---extern functions--- + +int32_t CTP_SPI_READ(struct spi_device *client, uint8_t *buf, uint16_t len); +int32_t CTP_SPI_WRITE(struct spi_device *client, uint8_t *buf, uint16_t len); +void nvt_bootloader_reset(void); +void nvt_eng_reset(void); +void nvt_sw_reset(void); +void nvt_sw_reset_idle(void); +void nvt_boot_ready(void); +void nvt_bld_crc_enable(void); +void nvt_fw_crc_enable(void); +int32_t nvt_update_firmware(const char *firmware_name); +int32_t nvt_check_fw_reset_state(RST_COMPLETE_STATE check_reset_state); +int32_t nvt_get_fw_info(void); +int32_t nvt_clear_fw_status(void); +int32_t nvt_check_fw_status(void); +int32_t nvt_set_page(uint32_t addr); +int32_t nvt_write_addr(uint32_t addr, uint8_t data); +void nvt_set_dbgfw_status(bool enable); +bool nvt_get_dbgfw_status(void); +void nvt_match_fw(void); +int32_t nvt_set_pocket_palm_switch(uint8_t pocket_palm_switch); +#if NVT_TOUCH_ESD_PROTECT +extern void nvt_esd_check_enable(uint8_t enable); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ +#endif /* _LINUX_NVT_TOUCH_H */ diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_ext_proc.c b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_ext_proc.c new file mode 100644 index 000000000000..ece36127360d --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_ext_proc.c @@ -0,0 +1,737 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * + * $Revision: 32206 $ + * $Date: 2018-08-10 19:23:04 +0800 (週五, 10 八月 2018) $ + * + * 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. + * + */ + +#include +#include +#include + +#include "nt36xxx.h" + +#if NVT_TOUCH_EXT_PROC +#define NVT_FW_VERSION "nvt_fw_version" +#define NVT_BASELINE "nvt_baseline" +#define NVT_RAW "nvt_raw" +#define NVT_DIFF "nvt_diff" +#define NVT_XIAOMI_CONFIG_INFO "nvt_xiaomi_config_info" +#define NVT_XIAOMI_LOCKDOWN_INFO "tp_lockdown_info" + +#define SPI_TANSFER_LENGTH 256 + +#define NORMAL_MODE 0x00 +#define TEST_MODE_1 0x21 +#define TEST_MODE_2 0x22 +#define HANDSHAKING_HOST_READY 0xBB + +#define XDATA_SECTOR_SIZE 256 + +static uint8_t xdata_tmp[2048] = { 0 }; +static int32_t xdata[2048] = { 0 }; + +static struct proc_dir_entry *NVT_proc_fw_version_entry; +static struct proc_dir_entry *NVT_proc_baseline_entry; +static struct proc_dir_entry *NVT_proc_raw_entry; +static struct proc_dir_entry *NVT_proc_diff_entry; +static struct proc_dir_entry *NVT_proc_xiaomi_config_info_entry; +static struct proc_dir_entry *NVT_proc_xiaomi_lockdown_info_entry; + +// Xiaomi Config Info. +static uint8_t nvt_xiaomi_conf_info_fw_ver = 0; +static uint8_t nvt_xiaomi_conf_info_fae_id = 0; +static uint64_t nvt_xiaomi_conf_info_reservation = 0; + +/******************************************************* +Description: + Novatek touchscreen change mode function. + +return: + n.a. +*******************************************************/ +void nvt_change_mode(uint8_t mode) +{ + uint8_t buf[8] = { 0 }; + + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + /* ---set mode--- */ + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = mode; + CTP_SPI_WRITE(ts->client, buf, 2); + + if (mode == NORMAL_MODE) { + buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; + buf[1] = HANDSHAKING_HOST_READY; + CTP_SPI_WRITE(ts->client, buf, 2); + msleep(20); + } +} + +/******************************************************* +Description: + Novatek touchscreen get firmware pipe function. + +return: + Executive outcomes. 0---pipe 0. 1---pipe 1. +*******************************************************/ +uint8_t nvt_get_fw_pipe(void) +{ + uint8_t buf[8] = { 0 }; + + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | + EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE); + + /* ---read fw status--- */ + buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; + buf[1] = 0x00; + CTP_SPI_READ(ts->client, buf, 2); + return (buf[1] & 0x01); +} + +/******************************************************* +Description: + Novatek touchscreen read meta data function. + +return: + n.a. +*******************************************************/ +void nvt_read_mdata(uint32_t xdata_addr, uint32_t xdata_btn_addr) +{ + int32_t i = 0; + int32_t j = 0; + int32_t k = 0; + uint8_t buf[SPI_TANSFER_LENGTH + 1] = { 0 }; + uint32_t head_addr = 0; + int32_t dummy_len = 0; + int32_t data_len = 0; + int32_t residual_len = 0; + + /* ---set xdata sector address & length--- */ + head_addr = xdata_addr - (xdata_addr % XDATA_SECTOR_SIZE); + dummy_len = xdata_addr - head_addr; + data_len = ts->x_num * ts->y_num * 2; + residual_len = (head_addr + dummy_len + data_len) % XDATA_SECTOR_SIZE; + + //printk("head_addr=0x%05X, dummy_len=0x%05X, data_len=0x%05X, residual_len=0x%05X\n", head_addr, dummy_len, data_len, residual_len); + + /* read xdata : step 1 */ + for (i = 0; i < ((dummy_len + data_len) / XDATA_SECTOR_SIZE); i++) { + /* ---read xdata by SPI_TANSFER_LENGTH */ + for (j = 0; j < (XDATA_SECTOR_SIZE / SPI_TANSFER_LENGTH); j++) { + /* ---change xdata index--- */ + nvt_set_page(head_addr + (XDATA_SECTOR_SIZE * i) + + (SPI_TANSFER_LENGTH * j)); + + /* ---read data--- */ + buf[0] = SPI_TANSFER_LENGTH * j; + CTP_SPI_READ(ts->client, buf, SPI_TANSFER_LENGTH + 1); + + /* ---copy buf to xdata_tmp--- */ + for (k = 0; k < SPI_TANSFER_LENGTH; k++) { + xdata_tmp[XDATA_SECTOR_SIZE * i + + SPI_TANSFER_LENGTH * j + k] = + buf[k + 1]; + /* printk("0x%02X, 0x%04X\n", buf[k+1], (XDATA_SECTOR_SIZE*i + SPI_TANSFER_LENGTH*j + k)); */ + } + } + /* printk("addr=0x%05X\n", (head_addr+XDATA_SECTOR_SIZE*i)); */ + } + + /* read xdata : step2 */ + if (residual_len != 0) { + /* ---read xdata by SPI_TANSFER_LENGTH */ + for (j = 0; j < (residual_len / SPI_TANSFER_LENGTH + 1); j++) { + /* ---change xdata index--- */ + nvt_set_page(xdata_addr + data_len - residual_len + + (SPI_TANSFER_LENGTH * j)); + + /* ---read data--- */ + buf[0] = SPI_TANSFER_LENGTH * j; + CTP_SPI_READ(ts->client, buf, SPI_TANSFER_LENGTH + 1); + + /* ---copy buf to xdata_tmp--- */ + for (k = 0; k < SPI_TANSFER_LENGTH; k++) { + xdata_tmp[(dummy_len + data_len - residual_len) + + SPI_TANSFER_LENGTH * j + k] = + buf[k + 1]; + /* printk("0x%02X, 0x%04x\n", buf[k+1], ((dummy_len+data_len-residual_len) + SPI_TANSFER_LENGTH*j + k)); */ + } + } + /* printk("addr=0x%05X\n", (xdata_addr+data_len-residual_len)); */ + } + + /* ---remove dummy data and 2bytes-to-1data--- */ + for (i = 0; i < (data_len / 2); i++) { + xdata[i] = (int16_t)(xdata_tmp[dummy_len + i * 2] + + 256 * xdata_tmp[dummy_len + i * 2 + 1]); + } + + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR); +} + +/******************************************************* +Description: + Novatek touchscreen get meta data function. + +return: + n.a. +*******************************************************/ +void nvt_get_mdata(int32_t *buf, uint8_t *m_x_num, uint8_t *m_y_num) +{ + *m_x_num = ts->x_num; + *m_y_num = ts->y_num; + memcpy(buf, xdata, + ((ts->x_num * ts->y_num + TOUCH_KEY_NUM) * sizeof(int32_t))); +} + +/******************************************************* +Description: + Novatek touchscreen firmware version show function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t c_fw_version_show(struct seq_file *m, void *v) +{ + seq_printf(m, "fw_ver=%d, x_num=%d, y_num=%d, button_num=%d\n", + ts->fw_ver, ts->x_num, ts->y_num, ts->max_button_num); + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen xdata sequence print show + function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t c_show(struct seq_file *m, void *v) +{ + int32_t i = 0; + int32_t j = 0; + for (i = 0; i < ts->y_num; i++) { + for (j = 0; j < ts->x_num; j++) { + seq_printf(m, "%5d, ", xdata[i * ts->x_num + j]); + } + seq_puts(m, "\n"); + } + + seq_printf(m, "\n\n"); + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen xdata sequence print start + function. + +return: + Executive outcomes. 1---call next function. + NULL---not call next function and sequence loop + stop. +*******************************************************/ +static void *c_start(struct seq_file *m, loff_t *pos) +{ + return *pos < 1 ? (void *)1 : NULL; +} + +/******************************************************* +Description: + Novatek touchscreen xdata sequence print next + function. + +return: + Executive outcomes. NULL---no next and call sequence + stop function. +*******************************************************/ +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return NULL; +} + +/******************************************************* +Description: + Novatek touchscreen xdata sequence print stop + function. + +return: + n.a. +*******************************************************/ +static void c_stop(struct seq_file *m, void *v) +{ + return; +} + +const struct seq_operations nvt_fw_version_seq_ops = { + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = c_fw_version_show +}; + +const struct seq_operations nvt_seq_ops = { .start = c_start, + .next = c_next, + .stop = c_stop, + .show = c_show }; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_fw_version open + function. + +return: + n.a. +*******************************************************/ +static int32_t nvt_fw_version_open(struct inode *inode, struct file *file) +{ + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + + NVT_LOG("%s ++\n", __func__); + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + mutex_unlock(&ts->lock); + + NVT_LOG("%s --\n", __func__); + + return seq_open(file, &nvt_fw_version_seq_ops); +} + +static const struct file_operations nvt_fw_version_fops = { + .owner = THIS_MODULE, + .open = nvt_fw_version_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_baseline open function. + +return: +Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t nvt_baseline_open(struct inode *inode, struct file *file) +{ + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + + NVT_LOG("%s ++\n", __func__); + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + if (nvt_clear_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + nvt_change_mode(TEST_MODE_2); + + if (nvt_check_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + nvt_read_mdata(ts->mmap->BASELINE_ADDR, ts->mmap->BASELINE_BTN_ADDR); + + nvt_change_mode(NORMAL_MODE); + + mutex_unlock(&ts->lock); + + NVT_LOG("%s --\n", __func__); + + return seq_open(file, &nvt_seq_ops); +} + +static const struct file_operations nvt_baseline_fops = { + .owner = THIS_MODULE, + .open = nvt_baseline_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_raw open function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t nvt_raw_open(struct inode *inode, struct file *file) +{ + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + + NVT_LOG("%s ++\n", __func__); + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + if (nvt_clear_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + nvt_change_mode(TEST_MODE_2); + + if (nvt_check_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + if (nvt_get_fw_pipe() == 0) + nvt_read_mdata(ts->mmap->RAW_PIPE0_ADDR, + ts->mmap->RAW_BTN_PIPE0_ADDR); + else + nvt_read_mdata(ts->mmap->RAW_PIPE1_ADDR, + ts->mmap->RAW_BTN_PIPE1_ADDR); + + nvt_change_mode(NORMAL_MODE); + + mutex_unlock(&ts->lock); + + NVT_LOG("%s --\n", __func__); + + return seq_open(file, &nvt_seq_ops); +} + +static const struct file_operations nvt_raw_fops = { + .owner = THIS_MODULE, + .open = nvt_raw_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_diff open function. + +return: + Executive outcomes. 0---succeed. negative---failed. +*******************************************************/ +static int32_t nvt_diff_open(struct inode *inode, struct file *file) +{ + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + + NVT_LOG("%s ++\n", __func__); + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + if (nvt_clear_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + nvt_change_mode(TEST_MODE_2); + + if (nvt_check_fw_status()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + return -EAGAIN; + } + + if (nvt_get_fw_pipe() == 0) + nvt_read_mdata(ts->mmap->DIFF_PIPE0_ADDR, + ts->mmap->DIFF_BTN_PIPE0_ADDR); + else + nvt_read_mdata(ts->mmap->DIFF_PIPE1_ADDR, + ts->mmap->DIFF_BTN_PIPE1_ADDR); + + nvt_change_mode(NORMAL_MODE); + + mutex_unlock(&ts->lock); + + NVT_LOG("%s --\n", __func__); + + return seq_open(file, &nvt_seq_ops); +} + +static const struct file_operations nvt_diff_fops = { + .owner = THIS_MODULE, + .open = nvt_diff_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int nvt_xiaomi_config_info_show(struct seq_file *m, void *v) +{ + seq_printf(m, "FW version/Config version, Debug version: 0x%02X\n", + nvt_xiaomi_conf_info_fw_ver); + seq_printf(m, "FAE ID: 0x%02X\n", nvt_xiaomi_conf_info_fae_id); + seq_printf(m, "Reservation byte: 0x%012llX\n", + nvt_xiaomi_conf_info_reservation); + + return 0; +} + +static int32_t nvt_xiaomi_config_info_open(struct inode *inode, + struct file *file) +{ + uint8_t buf[16] = { 0 }; + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + + NVT_LOG("%s ++\n", __func__); + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | 0x9C); + + buf[0] = 0x9C; + CTP_SPI_READ(ts->client, buf, 9); + + nvt_xiaomi_conf_info_fw_ver = buf[1]; + nvt_xiaomi_conf_info_fae_id = buf[2]; + nvt_xiaomi_conf_info_reservation = + (((uint64_t)buf[3] << 40) | ((uint64_t)buf[4] << 32) | + ((uint64_t)buf[5] << 24) | ((uint64_t)buf[6] << 16) | + ((uint64_t)buf[7] << 8) | (uint64_t)buf[8]); + + mutex_unlock(&ts->lock); + + NVT_LOG("%s --\n", __func__); + + return single_open(file, nvt_xiaomi_config_info_show, NULL); +} + +static const struct file_operations nvt_xiaomi_config_info_fops = { + .owner = THIS_MODULE, + .open = nvt_xiaomi_config_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int nvt_xiaomi_lockdown_info_show(struct seq_file *m, void *v) +{ + u8 *lk = ts->lockdown_info; + + seq_printf(m, + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", + lk[0], lk[1], lk[2], lk[3], lk[4], lk[5], lk[6], lk[7]); + return 0; +} + +static int32_t nvt_xiaomi_lockdown_info_open(struct inode *inode, + struct file *file) +{ + return single_open(file, nvt_xiaomi_lockdown_info_show, NULL); +} + +static const struct file_operations nvt_xiaomi_lockdown_info_fops = { + .owner = THIS_MODULE, + .open = nvt_xiaomi_lockdown_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +int32_t nvt_set_pocket_palm_switch(uint8_t pocket_palm_switch) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("set pocket palm switch: %d\n", pocket_palm_switch); + + msleep(35); + + /* ---set xdata index to EVENT BUF ADDR--- */ + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_set_pocket_palm_switch_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + if (pocket_palm_switch == 0) { + /* pocket palm disable */ + buf[1] = 0x74; + } else if (pocket_palm_switch == 1) { + /* pocket palm enable */ + buf[1] = 0x73; + } else { + NVT_ERR("Invalid value! pocket_palm_switch = %d\n", + pocket_palm_switch); + ret = -EINVAL; + goto nvt_set_pocket_palm_switch_out; + } + ret = CTP_SPI_WRITE(ts->client, buf, 2); + if (ret < 0) { + NVT_ERR("Write pocket palm switch command fail!\n"); + goto nvt_set_pocket_palm_switch_out; + } + +nvt_set_pocket_palm_switch_out: + NVT_LOG("%s --\n", __func__); + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen extra function proc. file node + initial function. + +return: + Executive outcomes. 0---succeed. -12---failed. +*******************************************************/ +int32_t nvt_extra_proc_init(void) +{ + NVT_proc_fw_version_entry = + proc_create(NVT_FW_VERSION, 0444, NULL, &nvt_fw_version_fops); + if (NVT_proc_fw_version_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_FW_VERSION); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_FW_VERSION); + } + + NVT_proc_baseline_entry = + proc_create(NVT_BASELINE, 0444, NULL, &nvt_baseline_fops); + if (NVT_proc_baseline_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_BASELINE); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_BASELINE); + } + + NVT_proc_raw_entry = proc_create(NVT_RAW, 0444, NULL, &nvt_raw_fops); + if (NVT_proc_raw_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_RAW); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_RAW); + } + + NVT_proc_diff_entry = proc_create(NVT_DIFF, 0444, NULL, &nvt_diff_fops); + if (NVT_proc_diff_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_DIFF); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_DIFF); + } + + NVT_proc_xiaomi_config_info_entry = + proc_create(NVT_XIAOMI_CONFIG_INFO, 0444, NULL, + &nvt_xiaomi_config_info_fops); + if (NVT_proc_xiaomi_config_info_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_XIAOMI_CONFIG_INFO); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", NVT_XIAOMI_CONFIG_INFO); + } + + NVT_proc_xiaomi_lockdown_info_entry = + proc_create(NVT_XIAOMI_LOCKDOWN_INFO, 0444, NULL, + &nvt_xiaomi_lockdown_info_fops); + if (NVT_proc_xiaomi_lockdown_info_entry == NULL) { + NVT_ERR("create proc/%s Failed!\n", NVT_XIAOMI_LOCKDOWN_INFO); + return -ENOMEM; + } else { + NVT_LOG("create proc/%s Succeeded!\n", + NVT_XIAOMI_LOCKDOWN_INFO); + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen extra function proc. file node + deinitial function. + +return: + n.a. +*******************************************************/ +void nvt_extra_proc_deinit(void) +{ + if (NVT_proc_fw_version_entry != NULL) { + remove_proc_entry(NVT_FW_VERSION, NULL); + NVT_proc_fw_version_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_FW_VERSION); + } + + if (NVT_proc_baseline_entry != NULL) { + remove_proc_entry(NVT_BASELINE, NULL); + NVT_proc_baseline_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_BASELINE); + } + + if (NVT_proc_raw_entry != NULL) { + remove_proc_entry(NVT_RAW, NULL); + NVT_proc_raw_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_RAW); + } + + if (NVT_proc_diff_entry != NULL) { + remove_proc_entry(NVT_DIFF, NULL); + NVT_proc_diff_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_DIFF); + } + + if (NVT_proc_xiaomi_config_info_entry != NULL) { + remove_proc_entry(NVT_XIAOMI_CONFIG_INFO, NULL); + NVT_proc_xiaomi_config_info_entry = NULL; + NVT_LOG("Removed /proc/%s\n", NVT_XIAOMI_CONFIG_INFO); + } +} +#endif diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_fw_update.c b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_fw_update.c new file mode 100644 index 000000000000..d405269671e7 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_fw_update.c @@ -0,0 +1,1184 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * + * $Revision: 32206 $ + * $Date: 2018-08-10 19:23:04 +0800 (週五, 10 八月 2018) $ + * + * 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. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "nt36xxx.h" + +#if BOOT_UPDATE_FIRMWARE + +#define SIZE_4KB 4096 +#define FLASH_SECTOR_SIZE SIZE_4KB +#define FW_BIN_VER_OFFSET (fw_need_write_size - SIZE_4KB) +#define FW_BIN_VER_BAR_OFFSET (FW_BIN_VER_OFFSET + 1) +#define NVT_FLASH_END_FLAG_LEN 3 +#define NVT_FLASH_END_FLAG_ADDR (fw_need_write_size - NVT_FLASH_END_FLAG_LEN) + +#define NVT_DUMP_PARTITION (0) +#define NVT_DUMP_PARTITION_LEN (1024) +#define NVT_DUMP_PARTITION_PATH "/data/local/tmp" + +struct timeval start, end; +const struct firmware *fw_entry = NULL; +static size_t fw_need_write_size = 0; +static uint8_t *fwbuf = NULL; + +struct nvt_ts_bin_map { + char name[12]; + uint32_t BIN_addr; + uint32_t SRAM_addr; + uint32_t size; + uint32_t crc; +}; + +static struct nvt_ts_bin_map *bin_map; + +static int32_t nvt_get_fw_need_write_size(const struct firmware *fw_entry) +{ + int32_t i = 0; + int32_t total_sectors_to_check = 0; + + total_sectors_to_check = fw_entry->size / FLASH_SECTOR_SIZE; + /* printk("total_sectors_to_check = %d\n", total_sectors_to_check); */ + + for (i = total_sectors_to_check; i > 0; i--) { + /* printk("current end flag address checked = 0x%X\n", i * FLASH_SECTOR_SIZE - NVT_FLASH_END_FLAG_LEN); */ + /* check if there is end flag "NVT" at the end of this sector */ + if (strncmp(&fw_entry->data[i * FLASH_SECTOR_SIZE - + NVT_FLASH_END_FLAG_LEN], + "NVT", NVT_FLASH_END_FLAG_LEN) == 0) { + fw_need_write_size = i * FLASH_SECTOR_SIZE; + NVT_LOG("fw_need_write_size = %zu(0x%zx), NVT end flag\n", + fw_need_write_size, fw_need_write_size); + return 0; + } + + /* check if there is end flag "MOD" at the end of this sector */ + if (strncmp(&fw_entry->data[i * FLASH_SECTOR_SIZE - + NVT_FLASH_END_FLAG_LEN], + "MOD", NVT_FLASH_END_FLAG_LEN) == 0) { + fw_need_write_size = i * FLASH_SECTOR_SIZE; + NVT_LOG("fw_need_write_size = %zu(0x%zx), MOD end flag\n", + fw_need_write_size, fw_need_write_size); + return 0; + } + } + + NVT_ERR("end flag \"NVT\" \"MOD\" not found!\n"); + return -1; +} + +/******************************************************* +Description: + Novatek touchscreen init variable and allocate buffer +for download firmware function. + +return: + n.a. +*******************************************************/ +static int32_t nvt_download_init(void) +{ + /* allocate buffer for transfer firmware */ + /* NVT_LOG("NVT_TRANSFER_LEN = 0x%06X\n", NVT_TRANSFER_LEN); */ + + if (fwbuf == NULL) { + fwbuf = (uint8_t *)kzalloc((NVT_TRANSFER_LEN + 1), GFP_KERNEL); + if (fwbuf == NULL) { + NVT_ERR("kzalloc for fwbuf failed!\n"); + return -ENOMEM; + } + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen checksum function. Calculate bin +file checksum for comparison. + +return: + n.a. +*******************************************************/ +static uint32_t CheckSum(const u8 *data, size_t len) +{ + uint32_t i = 0; + uint32_t checksum = 0; + + for (i = 0; i < len + 1; i++) + checksum += data[i]; + + checksum += len; + checksum = ~checksum + 1; + + return checksum; +} + +static uint32_t byte_to_word(const uint8_t *data) +{ + return data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24); +} + +/******************************************************* +Description: + Novatek touchscreen parsing bin header function. + +return: + n.a. +*******************************************************/ +static uint32_t partition = 0; +static uint8_t ilm_dlm_num = 2; +static int32_t nvt_bin_header_parser(const u8 *fwdata, size_t fwsize) +{ + uint32_t list = 0; + uint32_t pos = 0x00; + uint32_t end = 0x00; + uint8_t info_sec_num = 0; + uint8_t ovly_sec_num = 0; + uint8_t ovly_info = 0; + + /* Find the header size */ + end = fwdata[0] + (fwdata[1] << 8) + (fwdata[2] << 16) + + (fwdata[3] << 24); + pos = 0x30; /* info section start at 0x30 offset */ + while (pos < end) { + info_sec_num++; + pos += 0x10; /* each header info is 16 bytes */ + } + + /* + * Find the DLM OVLY section + * [0:3] Overlay Section Number + * [4] Overlay Info + */ + ovly_info = (fwdata[0x28] & 0x10) >> 4; + ovly_sec_num = (ovly_info) ? (fwdata[0x28] & 0x0F) : 0; + + /* + * calculate all partition number + * ilm_dlm_num (ILM & DLM) + ovly_sec_num + info_sec_num + */ + partition = ilm_dlm_num + ovly_sec_num + info_sec_num; + NVT_LOG("ovly_info = %d, ilm_dlm_num = %d, ovly_sec_num = %d, info_sec_num = %d, partition = %d\n", + ovly_info, ilm_dlm_num, ovly_sec_num, info_sec_num, partition); + + /* allocated memory for header info */ + bin_map = (struct nvt_ts_bin_map *)kzalloc( + (partition + 1) * sizeof(struct nvt_ts_bin_map), GFP_KERNEL); + if (bin_map == NULL) { + NVT_ERR("kzalloc for bin_map failed!\n"); + return -ENOMEM; + } + + for (list = 0; list < partition; list++) { + /* + * [1] parsing ILM & DLM header info + * BIN_addr : SRAM_addr : size (12-bytes) + * crc located at 0x18 & 0x1C + */ + if (list < ilm_dlm_num) { + bin_map[list].BIN_addr = + byte_to_word(&fwdata[0 + list * 12]); + bin_map[list].SRAM_addr = + byte_to_word(&fwdata[4 + list * 12]); + bin_map[list].size = + byte_to_word(&fwdata[8 + list * 12]); + if (ts->hw_crc) + bin_map[list].crc = + byte_to_word(&fwdata[0x18 + list * 4]); + else { //ts->hw_crc + if ((bin_map[list].BIN_addr + + bin_map[list].size) < fwsize) + bin_map[list].crc = CheckSum( + &fwdata[bin_map[list].BIN_addr], + bin_map[list].size); + else { + NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", + bin_map[list].BIN_addr, + bin_map[list].BIN_addr + + bin_map[list].size); + return -EINVAL; + } + } + if (list == 0) + sprintf(bin_map[list].name, "ILM"); + else if (list == 1) + sprintf(bin_map[list].name, "DLM"); + } + + /* + * [2] parsing others header info + * SRAM_addr : size : BIN_addr : crc (16-bytes) + */ + if ((list >= ilm_dlm_num) && + (list < (ilm_dlm_num + info_sec_num))) { + /* others partition located at 0x30 offset */ + pos = 0x30 + (0x10 * (list - ilm_dlm_num)); + + bin_map[list].SRAM_addr = byte_to_word(&fwdata[pos]); + bin_map[list].size = byte_to_word(&fwdata[pos + 4]); + bin_map[list].BIN_addr = byte_to_word(&fwdata[pos + 8]); + if (ts->hw_crc) + bin_map[list].crc = + byte_to_word(&fwdata[pos + 12]); + else { + if ((bin_map[list].BIN_addr + + bin_map[list].size) < fwsize) + bin_map[list].crc = CheckSum( + &fwdata[bin_map[list].BIN_addr], + bin_map[list].size); + else { + NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", + bin_map[list].BIN_addr, + bin_map[list].BIN_addr + + bin_map[list].size); + return -EINVAL; + } + } + /* detect header end to protect parser function */ + if ((bin_map[list].BIN_addr == 0) && + (bin_map[list].size != 0)) { + sprintf(bin_map[list].name, "Header"); + } else { + sprintf(bin_map[list].name, "Info-%d", + (list - ilm_dlm_num)); + } + } + + /* + * [3] parsing overlay section header info + * SRAM_addr : size : BIN_addr : crc (16-bytes) + */ + if (list >= (ilm_dlm_num + info_sec_num)) { + /* overlay info located at DLM (list = 1) start addr */ + pos = bin_map[1].BIN_addr + + (0x10 * (list - ilm_dlm_num - info_sec_num)); + + bin_map[list].SRAM_addr = byte_to_word(&fwdata[pos]); + bin_map[list].size = byte_to_word(&fwdata[pos + 4]); + bin_map[list].BIN_addr = byte_to_word(&fwdata[pos + 8]); + if (ts->hw_crc) + bin_map[list].crc = + byte_to_word(&fwdata[pos + 12]); + else { + if ((bin_map[list].BIN_addr + + bin_map[list].size) < fwsize) + bin_map[list].crc = CheckSum( + &fwdata[bin_map[list].BIN_addr], + bin_map[list].size); + else { + NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", + bin_map[list].BIN_addr, + bin_map[list].BIN_addr + + bin_map[list].size); + return -EINVAL; + } + } + sprintf(bin_map[list].name, "Overlay-%d", + (list - ilm_dlm_num - info_sec_num)); + } + + /* BIN size error detect */ + if ((bin_map[list].BIN_addr + bin_map[list].size) > fwsize) { + NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", + bin_map[list].BIN_addr, + bin_map[list].BIN_addr + bin_map[list].size); + return -EINVAL; + } + + /* NVT_LOG("[%d][%s] SRAM (0x%08X), SIZE (0x%08X), BIN (0x%08X), CRC (0x%08X)\n", + list, bin_map[list].name, + bin_map[list].SRAM_addr, bin_map[list].size, bin_map[list].BIN_addr, bin_map[list].crc); */ + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen release update firmware function. + +return: + n.a. +*******************************************************/ +static void update_firmware_release(void) +{ + if (fw_entry) { + release_firmware(fw_entry); + } + + fw_entry = NULL; +} + +/******************************************************* +Description: + Novatek touchscreen request update firmware function. + +return: + Executive outcomes. 0---succeed. -1,-22---failed. +*******************************************************/ +static int32_t update_firmware_request(const char *filename) +{ + uint8_t retry = 0; + int32_t ret = 0; + + if (NULL == filename) { + return -ENOENT; + } + + while (1) { + NVT_LOG("filename is %s\n", filename); + + ret = request_firmware(&fw_entry, filename, &ts->client->dev); + if (ret) { + NVT_ERR("firmware load failed, ret=%d\n", ret); + goto request_fail; + } + + /* check FW need to write size */ + if (nvt_get_fw_need_write_size(fw_entry)) { + NVT_ERR("get fw need to write size fail!\n"); + ret = -EINVAL; + goto invalid; + } + + /* check if FW version add FW version bar equals 0xFF */ + if (*(fw_entry->data + FW_BIN_VER_OFFSET) + + *(fw_entry->data + FW_BIN_VER_BAR_OFFSET) != + 0xFF) { + NVT_ERR("bin file FW_VER + FW_VER_BAR should be 0xFF!\n"); + NVT_ERR("FW_VER=0x%02X, FW_VER_BAR=0x%02X\n", + *(fw_entry->data + FW_BIN_VER_OFFSET), + *(fw_entry->data + FW_BIN_VER_BAR_OFFSET)); + ret = -ENOEXEC; + goto invalid; + } + + /* BIN Header Parser */ + ret = nvt_bin_header_parser(fw_entry->data, fw_entry->size); + if (ret) { + NVT_ERR("bin header parser failed\n"); + goto invalid; + } else { + break; + } + +invalid: + update_firmware_release(); + if (!IS_ERR_OR_NULL(bin_map)) { + kfree(bin_map); + bin_map = NULL; + } + +request_fail: + retry++; + if (unlikely(retry > 2)) { + NVT_ERR("error, retry=%d\n", retry); + break; + } + } + + return ret; +} + +#if NVT_DUMP_PARTITION +/******************************************************* +Description: + Novatek touchscreen dump flash partition function. + +return: + n.a. +*******************************************************/ +loff_t file_offset = 0; +static int32_t nvt_read_ram_and_save_file(uint32_t addr, uint16_t len, + char *name) +{ + char file[256] = ""; + uint8_t *fbufp = NULL; + int32_t ret = 0; + struct file *fp = NULL; + mm_segment_t org_fs; + + sprintf(file, "%s/dump_%s.bin", NVT_DUMP_PARTITION_PATH, name); + NVT_LOG("Dump [%s] from 0x%08X to 0x%08X\n", file, addr, addr + len); + + fbufp = (uint8_t *)kzalloc(len + 1, GFP_KERNEL); + if (fbufp == NULL) { + NVT_ERR("kzalloc for fbufp failed!\n"); + ret = -ENOMEM; + goto alloc_buf_fail; + } + + org_fs = get_fs(); + set_fs(KERNEL_DS); + fp = filp_open(file, O_RDWR | O_CREAT, 0644); + if (fp == NULL || IS_ERR(fp)) { + ret = -ENOMEM; + NVT_ERR("open file failed\n"); + goto open_file_fail; + } + + /* SPI read */ + /* ---set xdata index to addr--- */ + nvt_set_page(addr); + + fbufp[0] = addr & 0x7F; + CTP_SPI_READ(ts->client, fbufp, len + 1); + + /* Write to file */ + ret = vfs_write(fp, (char __user *)fbufp + 1, len, &file_offset); + if (ret != len) { + NVT_ERR("write file failed\n"); + goto open_file_fail; + } else { + ret = 0; + } + +open_file_fail: + set_fs(org_fs); + if (!IS_ERR_OR_NULL(fp)) { + filp_close(fp, NULL); + fp = NULL; + } + + if (!IS_ERR_OR_NULL(fbufp)) { + kfree(fbufp); + fbufp = NULL; + } +alloc_buf_fail: + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen nvt_dump_partition function to dump + each partition for debug. + +return: + n.a. +*******************************************************/ +static int32_t nvt_dump_partition(void) +{ + uint32_t list = 0; + char *name; + uint32_t SRAM_addr, size; + uint32_t i = 0; + uint16_t len = 0; + int32_t count = 0; + int32_t ret = 0; + + if (NVT_DUMP_PARTITION_LEN >= sizeof(ts->rbuf)) { + NVT_ERR("dump len %d is larger than buffer size %ld\n", + NVT_DUMP_PARTITION_LEN, sizeof(ts->rbuf)); + return -EINVAL; + } else if (NVT_DUMP_PARTITION_LEN >= NVT_TRANSFER_LEN) { + NVT_ERR("dump len %d is larger than NVT_TRANSFER_LEN\n", + NVT_DUMP_PARTITION_LEN); + return -EINVAL; + } + + if (bin_map == NULL) { + NVT_ERR("bin_map is NULL\n"); + return -ENOMEM; + } + + memset(fwbuf, 0, (NVT_DUMP_PARTITION_LEN + 1)); + + for (list = 0; list < partition; list++) { + /* initialize variable */ + SRAM_addr = bin_map[list].SRAM_addr; + size = bin_map[list].size; + name = bin_map[list].name; + + /* ignore reserved partition (Reserved Partition size is zero) */ + if (!size) + continue; + else + size = size + 1; + + /* write data to SRAM */ + if (size % NVT_DUMP_PARTITION_LEN) + count = (size / NVT_DUMP_PARTITION_LEN) + 1; + else + count = (size / NVT_DUMP_PARTITION_LEN); + + for (i = 0; i < count; i++) { + len = (size < NVT_DUMP_PARTITION_LEN) ? + size : + NVT_DUMP_PARTITION_LEN; + + /* dump for debug download firmware */ + ret = nvt_read_ram_and_save_file(SRAM_addr, len, name); + if (ret < 0) { + NVT_ERR("nvt_read_ram_and_save_file failed, ret = %d\n", + ret); + goto out; + } + + SRAM_addr += NVT_DUMP_PARTITION_LEN; + size -= NVT_DUMP_PARTITION_LEN; + } + + file_offset = 0; + } + +out: + return ret; +} +#endif /* NVT_DUMP_PARTITION */ + +/******************************************************* +Description: + Novatek touchscreen write data to sram function. + +- fwdata : The buffer is written +- SRAM_addr: The sram destination address +- size : Number of data bytes in @fwdata being written +- BIN_addr : The transferred data offset of @fwdata + +return: + Executive outcomes. 0---succeed. else---fail. +*******************************************************/ +static int32_t nvt_write_sram(const u8 *fwdata, uint32_t SRAM_addr, + uint32_t size, uint32_t BIN_addr) +{ + int32_t ret = 0; + uint32_t i = 0; + uint16_t len = 0; + int32_t count = 0; + + if (size % NVT_TRANSFER_LEN) + count = (size / NVT_TRANSFER_LEN) + 1; + else + count = (size / NVT_TRANSFER_LEN); + + for (i = 0; i < count; i++) { + len = (size < NVT_TRANSFER_LEN) ? size : NVT_TRANSFER_LEN; + + /* ---set xdata index to start address of SRAM--- */ + ret = nvt_set_page(SRAM_addr); + if (ret) { + NVT_ERR("set page failed, ret = %d\n", ret); + return ret; + } + + /* ---write data into SRAM--- */ + fwbuf[0] = SRAM_addr & 0x7F; + memcpy(fwbuf + 1, &fwdata[BIN_addr], len); + ret = CTP_SPI_WRITE(ts->client, fwbuf, len + 1); + if (ret) { + NVT_ERR("write to sram failed, ret = %d\n", ret); + return ret; + } + + SRAM_addr += NVT_TRANSFER_LEN; + BIN_addr += NVT_TRANSFER_LEN; + size -= NVT_TRANSFER_LEN; + } + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen nvt_write_firmware function to write +firmware into each partition. + +return: + n.a. +*******************************************************/ +static int32_t nvt_write_firmware(const u8 *fwdata, size_t fwsize) +{ + uint32_t list = 0; + char *name; + uint32_t BIN_addr, SRAM_addr, size; + int32_t ret = 0; + + memset(fwbuf, 0, (NVT_TRANSFER_LEN + 1)); + + for (list = 0; list < partition; list++) { + /* initialize variable */ + SRAM_addr = bin_map[list].SRAM_addr; + size = bin_map[list].size; + BIN_addr = bin_map[list].BIN_addr; + name = bin_map[list].name; + + /* NVT_LOG("[%d][%s] SRAM (0x%08X), SIZE (0x%08X), BIN (0x%08X)\n", + list, name, SRAM_addr, size, BIN_addr); */ + + /* Check data size */ + if ((BIN_addr + size) > fwsize) { + NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", + BIN_addr, BIN_addr + size); + ret = -EINVAL; + goto out; + } + + /* ignore reserved partition (Reserved Partition size is zero) */ + if (!size) + continue; + else + size = size + 1; + + /* write data to SRAM */ + ret = nvt_write_sram(fwdata, SRAM_addr, size, BIN_addr); + if (ret) { + NVT_ERR("sram program failed, ret = %d\n", ret); + goto out; + } + } + +out: + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen check checksum function. +This function will compare file checksum and fw checksum. + +return: + n.a. +*******************************************************/ +static int32_t nvt_check_fw_checksum(void) +{ + uint32_t fw_checksum = 0; + uint32_t len = partition * 4; + uint32_t list = 0; + int32_t ret = 0; + + memset(fwbuf, 0, (len + 1)); + + /* ---set xdata index to checksum--- */ + nvt_set_page(ts->mmap->R_ILM_CHECKSUM_ADDR); + + /* read checksum */ + fwbuf[0] = (ts->mmap->R_ILM_CHECKSUM_ADDR) & 0x7F; + ret = CTP_SPI_READ(ts->client, fwbuf, len + 1); + if (ret) { + NVT_ERR("Read fw checksum failed\n"); + return ret; + } + + /* + * Compare each checksum from fw + * ILM + DLM + Overlay + Info + * ilm_dlm_num (ILM & DLM) + ovly_sec_num + info_sec_num + */ + for (list = 0; list < partition; list++) { + fw_checksum = byte_to_word(&fwbuf[1 + list * 4]); + + /* ignore reserved partition (Reserved Partition size is zero) */ + if (!bin_map[list].size) + continue; + + if (bin_map[list].crc != fw_checksum) { + NVT_ERR("[%d] BIN_checksum=0x%08X, FW_checksum=0x%08X\n", + list, bin_map[list].crc, fw_checksum); + ret = -EIO; + } + } + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen set bootload crc reg bank function. +This function will set hw crc reg before enable crc function. + +return: + n.a. +*******************************************************/ +static void nvt_set_bld_crc_bank(uint32_t DES_ADDR, uint32_t SRAM_ADDR, + uint32_t LENGTH_ADDR, uint32_t size, + uint32_t G_CHECKSUM_ADDR, uint32_t crc) +{ + /* write destination address */ + nvt_set_page(DES_ADDR); + fwbuf[0] = DES_ADDR & 0x7F; + fwbuf[1] = (SRAM_ADDR) & 0xFF; + fwbuf[2] = (SRAM_ADDR >> 8) & 0xFF; + fwbuf[3] = (SRAM_ADDR >> 16) & 0xFF; + CTP_SPI_WRITE(ts->client, fwbuf, 4); + + /* write length */ + /* nvt_set_page(LENGTH_ADDR); */ + fwbuf[0] = LENGTH_ADDR & 0x7F; + fwbuf[1] = (size) & 0xFF; + fwbuf[2] = (size >> 8) & 0xFF; + fwbuf[3] = (size >> 16) & 0x01; + if (ts->hw_crc == 1) { + CTP_SPI_WRITE(ts->client, fwbuf, 3); + } else if (ts->hw_crc > 1) { + CTP_SPI_WRITE(ts->client, fwbuf, 4); + } + + /* write golden dlm checksum */ + /* nvt_set_page(G_CHECKSUM_ADDR); */ + fwbuf[0] = G_CHECKSUM_ADDR & 0x7F; + fwbuf[1] = (crc) & 0xFF; + fwbuf[2] = (crc >> 8) & 0xFF; + fwbuf[3] = (crc >> 16) & 0xFF; + fwbuf[4] = (crc >> 24) & 0xFF; + CTP_SPI_WRITE(ts->client, fwbuf, 5); + + return; +} + +/******************************************************* +Description: + Novatek touchscreen set BLD hw crc function. +This function will set ILM and DLM crc information to register. + +return: + n.a. +*******************************************************/ +static void nvt_set_bld_hw_crc(void) +{ + /* [0] ILM */ + /* write register bank */ + nvt_set_bld_crc_bank(ts->mmap->ILM_DES_ADDR, bin_map[0].SRAM_addr, + ts->mmap->ILM_LENGTH_ADDR, bin_map[0].size, + ts->mmap->G_ILM_CHECKSUM_ADDR, bin_map[0].crc); + + /* [1] DLM */ + /* write register bank */ + nvt_set_bld_crc_bank(ts->mmap->DLM_DES_ADDR, bin_map[1].SRAM_addr, + ts->mmap->DLM_LENGTH_ADDR, bin_map[1].size, + ts->mmap->G_DLM_CHECKSUM_ADDR, bin_map[1].crc); +} + +/******************************************************* +Description: + Novatek touchscreen read BLD hw crc info function. +This function will check crc results from register. + +return: + n.a. +*******************************************************/ +static void nvt_read_bld_hw_crc(void) +{ + uint8_t buf[8] = { 0 }; + uint32_t g_crc = 0, r_crc = 0; + + /* CRC Flag */ + nvt_set_page(ts->mmap->BLD_ILM_DLM_CRC_ADDR); + buf[0] = ts->mmap->BLD_ILM_DLM_CRC_ADDR & 0x7F; + buf[1] = 0x00; + CTP_SPI_READ(ts->client, buf, 2); + NVT_ERR("crc_done = %d, ilm_crc_flag = %d, dlm_crc_flag = %d\n", + (buf[1] >> 2) & 0x01, (buf[1] >> 0) & 0x01, + (buf[1] >> 1) & 0x01); + + /* ILM CRC */ + nvt_set_page(ts->mmap->G_ILM_CHECKSUM_ADDR); + buf[0] = ts->mmap->G_ILM_CHECKSUM_ADDR & 0x7F; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + CTP_SPI_READ(ts->client, buf, 5); + g_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24); + + nvt_set_page(ts->mmap->R_ILM_CHECKSUM_ADDR); + buf[0] = ts->mmap->R_ILM_CHECKSUM_ADDR & 0x7F; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + CTP_SPI_READ(ts->client, buf, 5); + r_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24); + + NVT_ERR("ilm: bin crc = 0x%08X, golden = 0x%08X, result = 0x%08X\n", + bin_map[0].crc, g_crc, r_crc); + + /* DLM CRC */ + nvt_set_page(ts->mmap->G_DLM_CHECKSUM_ADDR); + buf[0] = ts->mmap->G_DLM_CHECKSUM_ADDR & 0x7F; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + CTP_SPI_READ(ts->client, buf, 5); + g_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24); + + nvt_set_page(ts->mmap->R_DLM_CHECKSUM_ADDR); + buf[0] = ts->mmap->R_DLM_CHECKSUM_ADDR & 0x7F; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + CTP_SPI_READ(ts->client, buf, 5); + r_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24); + + NVT_ERR("dlm: bin crc = 0x%08X, golden = 0x%08X, result = 0x%08X\n", + bin_map[1].crc, g_crc, r_crc); + + return; +} + +#if NVT_TOUCH_ESD_DISP_RECOVERY +#define ILM_CRC_FLAG 0x01 +#define CRC_DONE 0x04 +static int32_t nvt_check_crc_done_ilm_err(void) +{ + uint8_t buf[8] = { 0 }; + + nvt_set_page(ts->mmap->BLD_ILM_DLM_CRC_ADDR); + buf[0] = ts->mmap->BLD_ILM_DLM_CRC_ADDR & 0x7F; + buf[1] = 0x00; + CTP_SPI_READ(ts->client, buf, 2); + + NVT_LOG("CRC DONE, ILM DLM FLAG = 0x%02X\n", buf[1]); + if (((buf[1] & ILM_CRC_FLAG) && (buf[1] & CRC_DONE)) || + (buf[1] == 0xFE) || ((buf[1] & CRC_DONE) == 0x00)) + return 1; + else + return 0; +} + +#define DISP_OFF_ADDR 0x2800 +static int nvt_f2c_disp_off(void) +{ + uint8_t buf[8] = { 0 }; + int ret = 0; + uint8_t tmp_val = 0; + int32_t write_disp_off_retry = 0; + int32_t retry = 0; + + NVT_LOG("%s ++\n", __func__); + + /* SW Reset & Idle */ + nvt_sw_reset_idle(); + + /* Setp1: Set REG CPU_IF_ADDR[15:0] */ + nvt_write_addr(ts->mmap->CPU_IF_ADDR_LOW, DISP_OFF_ADDR & 0xFF); + nvt_write_addr(ts->mmap->CPU_IF_ADDR_HIGH, (DISP_OFF_ADDR >> 8) & 0xFF); + + /* Step2: Set REG FFM_ADDR[15:0] */ + /* set FFM_ADDR to 0x20000 */ + nvt_write_addr(ts->mmap->FFM_ADDR_LOW, 0x00); + nvt_write_addr(ts->mmap->FFM_ADDR_MID, 0x00); + if (ts->hw_crc > 1) + nvt_write_addr(ts->mmap->FFM_ADDR_HIGH, 0x00); + + /* Step3: Set REG F2C_LENGT[H7:0] */ + nvt_write_addr(ts->mmap->F2C_LENGTH, 1); + +nvt_write_disp_off_retry: + /* Step4: Set REG CPU_Polling_En=1, F2C_RW=1, CPU_IF_ADDR_INC=1, F2C_EN=1 */ + nvt_set_page(ts->mmap->FFM2CPU_CTL); + buf[0] = ts->mmap->FFM2CPU_CTL & 0x7F; + buf[1] = 0xFF; + ret = CTP_SPI_READ(ts->client, buf, 2); + if (ret) { + NVT_ERR("Read FFM2CPU control failed!\n"); + return ret; + } + tmp_val = buf[1] | 0x27; + nvt_write_addr(ts->mmap->FFM2CPU_CTL, tmp_val); + + /* Step5: wait F2C_EN = 0 */ + retry = 0; + while (1) { + nvt_set_page(ts->mmap->FFM2CPU_CTL); + buf[0] = ts->mmap->FFM2CPU_CTL & 0x7F; + buf[1] = 0xFF; + buf[2] = 0xFF; + ret = CTP_SPI_READ(ts->client, buf, 3); + if (ret) { + NVT_ERR("Read FFM2CPU control failed!\n"); + return ret; + } + + if ((buf[1] & 0x01) == 0x00) + break; + + usleep_range(1000, 1000); + retry++; + + if (unlikely(retry > 1)) { + NVT_ERR("Wait F2C_EN = 0 failed!\n"); + return -EIO; + } + } + + /* Step6: Check REG TH_CPU_CHK status (1: Success, 0: Fail), if 0, can Retry Step4. */ + if (((buf[2] & 0x04) >> 2) != 0x01) { + write_disp_off_retry++; + if (write_disp_off_retry <= 3) { + goto nvt_write_disp_off_retry; + } else { + NVT_ERR("Write display off failed!, buf[1]=0x%02X, buf[2]=0x%02X\n", + buf[1], buf[2]); + return -EIO; + } + } + NVT_LOG("%s --\n", __func__); + + return ret; +} +#endif /* #if NVT_TOUCH_ESD_DISP_RECOVERY */ + +/******************************************************* +Description: + Novatek touchscreen Download_Firmware with HW CRC +function. It's complete download firmware flow. + +return: + Executive outcomes. 0---succeed. else---fail. +*******************************************************/ +static int32_t nvt_download_firmware_hw_crc(void) +{ + uint8_t retry = 0; + int32_t ret = 0; + + do_gettimeofday(&start); + + while (1) { + /* bootloader reset to reset MCU */ + nvt_bootloader_reset(); + + /* Start to write firmware process */ + ret = nvt_write_firmware(fw_entry->data, fw_entry->size); + if (ret) { + NVT_ERR("Write_Firmware failed. (%d)\n", ret); + goto fail; + } + +#if NVT_DUMP_PARTITION + ret = nvt_dump_partition(); + if (ret) { + NVT_ERR("nvt_dump_partition failed, ret = %d\n", ret); + } +#endif + + /* set ilm & dlm reg bank */ + nvt_set_bld_hw_crc(); + + /* enable hw bld crc function */ + nvt_bld_crc_enable(); + + /* clear fw reset status & enable fw crc check */ + nvt_fw_crc_enable(); + + /* Set Boot Ready Bit */ + nvt_boot_ready(); + + ret = nvt_check_fw_reset_state(RESET_STATE_INIT); + if (ret) { + NVT_ERR("nvt_check_fw_reset_state failed. (%d)\n", ret); + goto fail; + } else { + break; + } + +fail: + retry++; + if (unlikely(retry > 2)) { + NVT_ERR("error, retry=%d\n", retry); + nvt_read_bld_hw_crc(); +#if NVT_TOUCH_ESD_DISP_RECOVERY + if (nvt_check_crc_done_ilm_err()) { + NVT_ERR("set display off to trigger display esd recovery.\n"); + nvt_f2c_disp_off(); + } +#endif /* #if NVT_TOUCH_ESD_DISP_RECOVERY */ + break; + } + } + + do_gettimeofday(&end); + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen Download_Firmware function. It's +complete download firmware flow. + +return: + n.a. +*******************************************************/ +static int32_t nvt_download_firmware(void) +{ + uint8_t retry = 0; + int32_t ret = 0; + + do_gettimeofday(&start); + + while (1) { + /* + * Send eng reset cmd before download FW + * Keep TP_RESX low when send eng reset cmd + */ +#if NVT_TOUCH_SUPPORT_HW_RST + gpio_set_value(ts->reset_gpio, 0); + mdelay(1); +#endif + nvt_eng_reset(); +#if NVT_TOUCH_SUPPORT_HW_RST + gpio_set_value(ts->reset_gpio, 1); + mdelay(10); +#endif + nvt_bootloader_reset(); + + /* clear fw reset status */ + nvt_write_addr(ts->mmap->EVENT_BUF_ADDR | + EVENT_MAP_RESET_COMPLETE, + 0x00); + + /* Start to write firmware process */ + ret = nvt_write_firmware(fw_entry->data, fw_entry->size); + if (ret) { + NVT_ERR("Write_Firmware failed. (%d)\n", ret); + goto fail; + } + +#if NVT_DUMP_PARTITION + ret = nvt_dump_partition(); + if (ret) { + NVT_ERR("nvt_dump_partition failed, ret = %d\n", ret); + } +#endif + + /* Set Boot Ready Bit */ + nvt_boot_ready(); + + ret = nvt_check_fw_reset_state(RESET_STATE_INIT); + if (ret) { + NVT_ERR("nvt_check_fw_reset_state failed. (%d)\n", ret); + goto fail; + } + + /* check fw checksum result */ + ret = nvt_check_fw_checksum(); + if (ret) { + NVT_ERR("firmware checksum not match, retry=%d\n", + retry); + goto fail; + } else { + break; + } + +fail: + retry++; + if (unlikely(retry > 2)) { + NVT_ERR("error, retry=%d\n", retry); + break; + } + } + + do_gettimeofday(&end); + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen update firmware main function. + +return: + n.a. +*******************************************************/ +int32_t nvt_update_firmware(const char *firmware_name) +{ + int32_t ret = 0; + + /* request bin file in "/etc/firmware" */ + ret = update_firmware_request(firmware_name); + if (ret) { + NVT_ERR("update_firmware_request failed. (%d)\n", ret); + goto request_firmware_fail; + } + + /* initial buffer and variable */ + ret = nvt_download_init(); + if (ret) { + NVT_ERR("Download Init failed. (%d)\n", ret); + goto download_fail; + } + + /* download firmware process */ + if (ts->hw_crc) + ret = nvt_download_firmware_hw_crc(); + else + ret = nvt_download_firmware(); + if (ret) { + NVT_ERR("Download Firmware failed. (%d)\n", ret); + goto download_fail; + } + + NVT_LOG("Update firmware success! <%ld us>\n", + (end.tv_sec - start.tv_sec) * 1000000L + + (end.tv_usec - start.tv_usec)); + + /* Get FW Info */ + ret = nvt_get_fw_info(); + if (ret) { + NVT_ERR("nvt_get_fw_info failed. (%d)\n", ret); + } + +download_fail: + if (!IS_ERR_OR_NULL(bin_map)) { + kfree(bin_map); + bin_map = NULL; + } + + update_firmware_release(); +request_firmware_fail: + + return ret; +} + +/******************************************************* +Description: + Novatek touchscreen update firmware when booting + function. + +return: + n.a. +*******************************************************/ +void Boot_Update_Firmware(struct work_struct *work) +{ + nvt_match_fw(); + mutex_lock(&ts->lock); + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_FW_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + nvt_get_fw_info(); + mutex_unlock(&ts->lock); + pm_relax(&ts->pdev->dev); +} +#endif /* BOOT_UPDATE_FIRMWARE */ diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mem_map.h b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mem_map.h new file mode 100644 index 000000000000..57643b2f89a3 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mem_map.h @@ -0,0 +1,358 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * + * $Revision: 32206 $ + * $Date: 2018-08-10 19:23:04 +0800 (週五, 10 八月 2018) $ + * + * 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. + * + */ + +struct nvt_ts_mem_map { + uint32_t EVENT_BUF_ADDR; + uint32_t RAW_PIPE0_ADDR; + uint32_t RAW_PIPE1_ADDR; + uint32_t BASELINE_ADDR; + uint32_t BASELINE_BTN_ADDR; + uint32_t DIFF_PIPE0_ADDR; + uint32_t DIFF_PIPE1_ADDR; + uint32_t RAW_BTN_PIPE0_ADDR; + uint32_t RAW_BTN_PIPE1_ADDR; + uint32_t DIFF_BTN_PIPE0_ADDR; + uint32_t DIFF_BTN_PIPE1_ADDR; + uint32_t READ_FLASH_CHECKSUM_ADDR; + uint32_t RW_FLASH_DATA_ADDR; + /* Phase 2 Host Download */ + uint32_t BOOT_RDY_ADDR; + uint32_t POR_CD_ADDR; + /* BLD CRC */ + uint32_t BLD_LENGTH_ADDR; + uint32_t ILM_LENGTH_ADDR; + uint32_t DLM_LENGTH_ADDR; + uint32_t BLD_DES_ADDR; + uint32_t ILM_DES_ADDR; + uint32_t DLM_DES_ADDR; + uint32_t G_ILM_CHECKSUM_ADDR; + uint32_t G_DLM_CHECKSUM_ADDR; + uint32_t R_ILM_CHECKSUM_ADDR; + uint32_t R_DLM_CHECKSUM_ADDR; + uint32_t BLD_CRC_EN_ADDR; + uint32_t DMA_CRC_EN_ADDR; + uint32_t BLD_ILM_DLM_CRC_ADDR; + uint32_t DMA_CRC_FLAG_ADDR; + uint32_t FFM2CPU_CTL; + uint32_t F2C_LENGTH; + uint32_t CPU_IF_ADDR_LOW; + uint32_t CPU_IF_ADDR_HIGH; + uint32_t FFM_ADDR_LOW; + uint32_t FFM_ADDR_MID; + uint32_t FFM_ADDR_HIGH; + uint32_t FW_HISTORY_ADDR; +}; + +struct nvt_ts_hw_info { + uint8_t carrier_system; + uint8_t hw_crc; +}; + +static const struct nvt_ts_mem_map NT36675_memory_map = { + .EVENT_BUF_ADDR = 0x22D00, + .RAW_PIPE0_ADDR = 0x24000, + .RAW_PIPE1_ADDR = 0x24000, + .BASELINE_ADDR = 0x21B90, + .BASELINE_BTN_ADDR = 0, + .DIFF_PIPE0_ADDR = 0x20C60, + .DIFF_PIPE1_ADDR = 0x24C60, + .RAW_BTN_PIPE0_ADDR = 0, + .RAW_BTN_PIPE1_ADDR = 0, + .DIFF_BTN_PIPE0_ADDR = 0, + .DIFF_BTN_PIPE1_ADDR = 0, + .READ_FLASH_CHECKSUM_ADDR = 0x24000, + .RW_FLASH_DATA_ADDR = 0x24002, + /* Phase 2 Host Download */ + .BOOT_RDY_ADDR = 0x3F10D, + /* BLD CRC */ + .BLD_LENGTH_ADDR = 0x3F138, //0x3F138 ~ 0x3F13A (3 bytes) + .ILM_LENGTH_ADDR = 0x3F118, //0x3F118 ~ 0x3F11A (3 bytes) + .DLM_LENGTH_ADDR = 0x3F130, //0x3F130 ~ 0x3F132 (3 bytes) + .BLD_DES_ADDR = 0x3F114, //0x3F114 ~ 0x3F116 (3 bytes) + .ILM_DES_ADDR = 0x3F128, //0x3F128 ~ 0x3F12A (3 bytes) + .DLM_DES_ADDR = 0x3F12C, //0x3F12C ~ 0x3F12E (3 bytes) + .G_ILM_CHECKSUM_ADDR = 0x3F100, //0x3F100 ~ 0x3F103 (4 bytes) + .G_DLM_CHECKSUM_ADDR = 0x3F104, //0x3F104 ~ 0x3F107 (4 bytes) + .R_ILM_CHECKSUM_ADDR = 0x3F120, //0x3F120 ~ 0x3F123 (4 bytes) + .R_DLM_CHECKSUM_ADDR = 0x3F124, //0x3F124 ~ 0x3F127 (4 bytes) + .BLD_CRC_EN_ADDR = 0x3F30E, + .DMA_CRC_EN_ADDR = 0x3F136, + .BLD_ILM_DLM_CRC_ADDR = 0x3F133, + .DMA_CRC_FLAG_ADDR = 0x3F134, + .FFM2CPU_CTL = 0x3F280, + .F2C_LENGTH = 0x3F283, + .CPU_IF_ADDR_LOW = 0x3F284, + .CPU_IF_ADDR_HIGH = 0x3F285, + .FFM_ADDR_LOW = 0x3F286, + .FFM_ADDR_MID = 0x3F287, + .FFM_ADDR_HIGH = 0x3F288, + .FW_HISTORY_ADDR = 0x23D10, +}; + +static const struct nvt_ts_mem_map NT36672A_memory_map = { + .EVENT_BUF_ADDR = 0x21C00, + .RAW_PIPE0_ADDR = 0x20000, + .RAW_PIPE1_ADDR = 0x23000, + .BASELINE_ADDR = 0x20BFC, + .BASELINE_BTN_ADDR = 0x23BFC, + .DIFF_PIPE0_ADDR = 0x206DC, + .DIFF_PIPE1_ADDR = 0x236DC, + .RAW_BTN_PIPE0_ADDR = 0x20510, + .RAW_BTN_PIPE1_ADDR = 0x23510, + .DIFF_BTN_PIPE0_ADDR = 0x20BF0, + .DIFF_BTN_PIPE1_ADDR = 0x23BF0, + .READ_FLASH_CHECKSUM_ADDR = 0x24000, + .RW_FLASH_DATA_ADDR = 0x24002, + /* Phase 2 Host Download */ + .BOOT_RDY_ADDR = 0x3F10D, + /* BLD CRC */ + .BLD_LENGTH_ADDR = 0x3F10E, //0x3F10E ~ 0x3F10F (2 bytes) + .ILM_LENGTH_ADDR = 0x3F118, //0x3F118 ~ 0x3F119 (2 bytes) + .DLM_LENGTH_ADDR = 0x3F130, //0x3F130 ~ 0x3F131 (2 bytes) + .BLD_DES_ADDR = 0x3F114, //0x3F114 ~ 0x3F116 (3 bytes) + .ILM_DES_ADDR = 0x3F128, //0x3F128 ~ 0x3F12A (3 bytes) + .DLM_DES_ADDR = 0x3F12C, //0x3F12C ~ 0x3F12E (3 bytes) + .G_ILM_CHECKSUM_ADDR = 0x3F100, //0x3F100 ~ 0x3F103 (4 bytes) + .G_DLM_CHECKSUM_ADDR = 0x3F104, //0x3F104 ~ 0x3F107 (4 bytes) + .R_ILM_CHECKSUM_ADDR = 0x3F120, //0x3F120 ~ 0x3F123 (4 bytes) + .R_DLM_CHECKSUM_ADDR = 0x3F124, //0x3F124 ~ 0x3F127 (4 bytes) + .BLD_CRC_EN_ADDR = 0x3F30E, + .DMA_CRC_EN_ADDR = 0x3F132, + .BLD_ILM_DLM_CRC_ADDR = 0x3F133, + .DMA_CRC_FLAG_ADDR = 0x3F134, +}; + +static const struct nvt_ts_mem_map NT36772_memory_map = { + .EVENT_BUF_ADDR = 0x11E00, + .RAW_PIPE0_ADDR = 0x10000, + .RAW_PIPE1_ADDR = 0x12000, + .BASELINE_ADDR = 0x10E70, + .BASELINE_BTN_ADDR = 0x12E70, + .DIFF_PIPE0_ADDR = 0x10830, + .DIFF_PIPE1_ADDR = 0x12830, + .RAW_BTN_PIPE0_ADDR = 0x10E60, + .RAW_BTN_PIPE1_ADDR = 0x12E60, + .DIFF_BTN_PIPE0_ADDR = 0x10E68, + .DIFF_BTN_PIPE1_ADDR = 0x12E68, + .READ_FLASH_CHECKSUM_ADDR = 0x14000, + .RW_FLASH_DATA_ADDR = 0x14002, + /* Phase 2 Host Download */ + .BOOT_RDY_ADDR = 0x1F141, + .POR_CD_ADDR = 0x1F61C, + /* BLD CRC */ + .R_ILM_CHECKSUM_ADDR = 0x1BF00, +}; + +static const struct nvt_ts_mem_map NT36525_memory_map = { + .EVENT_BUF_ADDR = 0x11A00, + .RAW_PIPE0_ADDR = 0x10000, + .RAW_PIPE1_ADDR = 0x12000, + .BASELINE_ADDR = 0x10B08, + .BASELINE_BTN_ADDR = 0x12B08, + .DIFF_PIPE0_ADDR = 0x1064C, + .DIFF_PIPE1_ADDR = 0x1264C, + .RAW_BTN_PIPE0_ADDR = 0x10634, + .RAW_BTN_PIPE1_ADDR = 0x12634, + .DIFF_BTN_PIPE0_ADDR = 0x10AFC, + .DIFF_BTN_PIPE1_ADDR = 0x12AFC, + .READ_FLASH_CHECKSUM_ADDR = 0x14000, + .RW_FLASH_DATA_ADDR = 0x14002, + /* Phase 2 Host Download */ + .BOOT_RDY_ADDR = 0x1F141, + .POR_CD_ADDR = 0x1F61C, + /* BLD CRC */ + .R_ILM_CHECKSUM_ADDR = 0x1BF00, +}; + +static const struct nvt_ts_mem_map NT36676F_memory_map = { + .EVENT_BUF_ADDR = 0x11A00, + .RAW_PIPE0_ADDR = 0x10000, + .RAW_PIPE1_ADDR = 0x12000, + .BASELINE_ADDR = 0x10B08, + .BASELINE_BTN_ADDR = 0x12B08, + .DIFF_PIPE0_ADDR = 0x1064C, + .DIFF_PIPE1_ADDR = 0x1264C, + .RAW_BTN_PIPE0_ADDR = 0x10634, + .RAW_BTN_PIPE1_ADDR = 0x12634, + .DIFF_BTN_PIPE0_ADDR = 0x10AFC, + .DIFF_BTN_PIPE1_ADDR = 0x12AFC, + .READ_FLASH_CHECKSUM_ADDR = 0x14000, + .RW_FLASH_DATA_ADDR = 0x14002, +}; + +static struct nvt_ts_hw_info NT36675_hw_info = { + .carrier_system = 2, + .hw_crc = 2, +}; + +static struct nvt_ts_hw_info NT36672A_hw_info = { + .carrier_system = 0, + .hw_crc = 1, +}; + +static struct nvt_ts_hw_info NT36772_hw_info = { + .carrier_system = 0, + .hw_crc = 0, +}; + +static struct nvt_ts_hw_info NT36525_hw_info = { + .carrier_system = 0, + .hw_crc = 0, +}; + +static struct nvt_ts_hw_info NT36676F_hw_info = { + .carrier_system = 0, + .hw_crc = 0, +}; + +#define NVT_ID_BYTE_MAX 6 +struct nvt_ts_trim_id_table { + uint8_t id[NVT_ID_BYTE_MAX]; + uint8_t mask[NVT_ID_BYTE_MAX]; + const struct nvt_ts_mem_map *mmap; + const struct nvt_ts_hw_info *hwinfo; +}; + +static const struct nvt_ts_trim_id_table trim_id_table[] = { + { + .id = { 0x0C, 0xFF, 0xFF, 0x72, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36675_memory_map, + .hwinfo = &NT36675_hw_info, + }, + { + .id = { 0xFF, 0xFF, 0xFF, 0x75, 0x66, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36675_memory_map, + .hwinfo = &NT36675_hw_info, + }, + { + .id = { 0x0B, 0xFF, 0xFF, 0x72, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info, + }, + { + .id = { 0x0B, 0xFF, 0xFF, 0x82, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info, + }, + { + .id = { 0x0B, 0xFF, 0xFF, 0x25, 0x65, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info, + }, + { + .id = { 0x0A, 0xFF, 0xFF, 0x72, 0x65, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info, + }, + { + .id = { 0x0A, 0xFF, 0xFF, 0x72, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info, + }, + { + .id = { 0x0A, 0xFF, 0xFF, 0x82, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info, + }, + { + .id = { 0x0A, 0xFF, 0xFF, 0x70, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info, + }, + { + .id = { 0x0B, 0xFF, 0xFF, 0x70, 0x66, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info, + }, + { + .id = { 0x0A, 0xFF, 0xFF, 0x72, 0x67, 0x03 }, + .mask = { 1, 0, 0, 1, 1, 1 }, + .mmap = &NT36672A_memory_map, + .hwinfo = &NT36672A_hw_info, + }, + { + .id = { 0x55, 0x00, 0xFF, 0x00, 0x00, 0x00 }, + .mask = { 1, 1, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info, + }, + { + .id = { 0x55, 0x72, 0xFF, 0x00, 0x00, 0x00 }, + .mask = { 1, 1, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info, + }, + { + .id = { 0xAA, 0x00, 0xFF, 0x00, 0x00, 0x00 }, + .mask = { 1, 1, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info, + }, + { + .id = { 0xAA, 0x72, 0xFF, 0x00, 0x00, 0x00 }, + .mask = { 1, 1, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info, + }, + { + .id = { 0xFF, 0xFF, 0xFF, 0x72, 0x67, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info, + }, + { + .id = { 0xFF, 0xFF, 0xFF, 0x70, 0x66, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info, + }, + { + .id = { 0xFF, 0xFF, 0xFF, 0x70, 0x67, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info, + }, + { + .id = { 0xFF, 0xFF, 0xFF, 0x72, 0x66, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36772_memory_map, + .hwinfo = &NT36772_hw_info, + }, + { + .id = { 0xFF, 0xFF, 0xFF, 0x25, 0x65, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36525_memory_map, + .hwinfo = &NT36525_hw_info, + }, + { + .id = { 0xFF, 0xFF, 0xFF, 0x76, 0x66, 0x03 }, + .mask = { 0, 0, 0, 1, 1, 1 }, + .mmap = &NT36676F_memory_map, + .hwinfo = &NT36676F_hw_info, + }, +}; diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mp_ctrlram.c b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mp_ctrlram.c new file mode 100644 index 000000000000..62e2bf33e9d4 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mp_ctrlram.c @@ -0,0 +1,2610 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * + * $Revision: 32206 $ + * $Date: 2018-08-10 19:23:04 +0800 (週五, 10 八月 2018) $ + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "nt36xxx.h" +#include "nt36xxx_mp_ctrlram.h" + +#if NVT_TOUCH_MP + +#define NORMAL_MODE 0x00 +#define TEST_MODE_1 0x21 +#define TEST_MODE_2 0x22 +#define MP_MODE_CC 0x41 +#define FREQ_HOP_DISABLE 0x66 +#define FREQ_HOP_ENABLE 0x65 + +#define SHORT_TEST_CSV_FILE "/data/misc/tp_selftest_data/ShortTest.csv" +#define OPEN_TEST_CSV_FILE "/data/misc/tp_selftest_data/OpenTest.csv" +#define FW_RAWDATA_CSV_FILE "/data/misc/tp_selftest_data/FWMutualTest.csv" +#define FW_CC_CSV_FILE "/data/misc/tp_selftest_data/FWCCTest.csv" +#define NOISE_TEST_CSV_FILE "/data/misc/tp_selftest_data/NoiseTest.csv" + +#define nvt_mp_seq_printf(m, fmt, args...) \ + do { \ + seq_printf(m, fmt, ##args); \ + if (!nvt_mp_test_result_printed) \ + printk(fmt, ##args); \ + } while (0) + +#define NVT_RESULT_INVALID 0 +#define NVT_RESULT_PASS 2 +#define NVT_RESULT_FAIL 1 + +static uint8_t *RecordResult_Short = NULL; +static uint8_t *RecordResult_Open = NULL; +static uint8_t *RecordResult_FWMutual = NULL; +static uint8_t *RecordResult_FW_CC = NULL; +static uint8_t *RecordResult_FW_DiffMax = NULL; +static uint8_t *RecordResult_FW_DiffMin = NULL; + +static int32_t TestResult_Short = 0; +static int32_t TestResult_Open = 0; +static int32_t TestResult_FW_Rawdata = 0; +static int32_t TestResult_FWMutual = 0; +static int32_t TestResult_FW_CC = 0; +static int32_t TestResult_Noise = 0; +static int32_t TestResult_FW_DiffMax = 0; +static int32_t TestResult_FW_DiffMin = 0; + +static int32_t *RawData_Short = NULL; +static int32_t *RawData_Open = NULL; +static int32_t *RawData_Diff = NULL; +static int32_t *RawData_Diff_Min = NULL; +static int32_t *RawData_Diff_Max = NULL; +static int32_t *RawData_FWMutual = NULL; +static int32_t *RawData_FW_CC = NULL; + +static struct proc_dir_entry *NVT_proc_selftest_entry = NULL; +static struct proc_dir_entry *NVT_proc_aftersales_test_entry; + +#ifndef NVT_SAVE_TESTDATA_IN_FILE +static struct proc_dir_entry *NVT_proc_test_data_entry = NULL; +#endif + +static int8_t nvt_mp_test_result_printed = 0; +static uint8_t fw_ver = 0; + +extern void nvt_change_mode(uint8_t mode); +extern uint8_t nvt_get_fw_pipe(void); +extern void nvt_read_mdata(uint32_t xdata_addr, uint32_t xdata_btn_addr); +extern void nvt_get_mdata(int32_t *buf, uint8_t *m_x_num, uint8_t *m_y_num); +int32_t nvt_mp_parse_dt(struct device_node *root, const char *node_compatible); + +/******************************************************* +Description: + Novatek touchscreen allocate buffer for mp selftest. + +return: + Executive outcomes. 0---succeed. -12---Out of memory +*******************************************************/ +static int nvt_mp_buffer_init(void) +{ + size_t RecordResult_BufSize = + IC_X_CFG_SIZE * IC_Y_CFG_SIZE + IC_KEY_CFG_SIZE; + size_t RawData_BufSize = + (IC_X_CFG_SIZE * IC_Y_CFG_SIZE + IC_KEY_CFG_SIZE) * + sizeof(int32_t); + + RecordResult_Short = + (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_Short) { + NVT_ERR("kzalloc for RecordResult_Short failed!\n"); + return -ENOMEM; + } + + RecordResult_Open = + (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_Open) { + NVT_ERR("kzalloc for RecordResult_Open failed!\n"); + return -ENOMEM; + } + + RecordResult_FWMutual = + (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_FWMutual) { + NVT_ERR("kzalloc for RecordResult_FWMutual failed!\n"); + return -ENOMEM; + } + + RecordResult_FW_CC = + (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_FW_CC) { + NVT_ERR("kzalloc for RecordResult_FW_CC failed!\n"); + return -ENOMEM; + } + + RecordResult_FW_DiffMax = + (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_FW_DiffMax) { + NVT_ERR("kzalloc for RecordResult_FW_DiffMax failed!\n"); + return -ENOMEM; + } + + RecordResult_FW_DiffMin = + (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL); + if (!RecordResult_FW_DiffMin) { + NVT_ERR("kzalloc for RecordResult_FW_DiffMin failed!\n"); + return -ENOMEM; + } + + RawData_Short = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_Short) { + NVT_ERR("kzalloc for RawData_Short failed!\n"); + return -ENOMEM; + } + + RawData_Open = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_Open) { + NVT_ERR("kzalloc for RawData_Open failed!\n"); + return -ENOMEM; + } + + RawData_Diff = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_Diff) { + NVT_ERR("kzalloc for RawData_Diff failed!\n"); + return -ENOMEM; + } + + RawData_Diff_Min = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_Diff_Min) { + NVT_ERR("kzalloc for RawData_Diff_Min failed!\n"); + return -ENOMEM; + } + + RawData_Diff_Max = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_Diff_Max) { + NVT_ERR("kzalloc for RawData_Diff_Max failed!\n"); + return -ENOMEM; + } + + RawData_FWMutual = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_FWMutual) { + NVT_ERR("kzalloc for RawData_FWMutual failed!\n"); + return -ENOMEM; + } + + RawData_FW_CC = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL); + if (!RawData_FW_CC) { + NVT_ERR("kzalloc for RawData_FW_CC failed!\n"); + return -ENOMEM; + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen free buffer for mp selftest. + +return: + n.a. +*******************************************************/ +static void nvt_mp_buffer_deinit(void) +{ + if (RecordResult_Short) { + kfree(RecordResult_Short); + RecordResult_Short = NULL; + } + + if (RecordResult_Open) { + kfree(RecordResult_Open); + RecordResult_Open = NULL; + } + + if (RecordResult_FWMutual) { + kfree(RecordResult_FWMutual); + RecordResult_FWMutual = NULL; + } + + if (RecordResult_FW_CC) { + kfree(RecordResult_FW_CC); + RecordResult_FW_CC = NULL; + } + + if (RecordResult_FW_DiffMax) { + kfree(RecordResult_FW_DiffMax); + RecordResult_FW_DiffMax = NULL; + } + + if (RecordResult_FW_DiffMin) { + kfree(RecordResult_FW_DiffMin); + RecordResult_FW_DiffMin = NULL; + } + + if (RawData_Short) { + kfree(RawData_Short); + RawData_Short = NULL; + } + + if (RawData_Open) { + kfree(RawData_Open); + RawData_Open = NULL; + } + + if (RawData_Diff) { + kfree(RawData_Diff); + RawData_Diff = NULL; + } + + if (RawData_Diff_Min) { + kfree(RawData_Diff_Min); + RawData_Diff_Min = NULL; + } + + if (RawData_Diff_Max) { + kfree(RawData_Diff_Max); + RawData_Diff_Max = NULL; + } + + if (RawData_FWMutual) { + kfree(RawData_FWMutual); + RawData_FWMutual = NULL; + } + + if (RawData_FW_CC) { + kfree(RawData_FW_CC); + RawData_FW_CC = NULL; + } +} + +static void nvt_print_data_log_in_one_line(int32_t *data, int32_t data_num) +{ + char *tmp_log = NULL; + int32_t i = 0; + + tmp_log = (char *)kzalloc(data_num * 7 + 1, GFP_KERNEL); + if (!tmp_log) { + NVT_ERR("kzalloc for tmp_log failed!\n "); + return; + } + + for (i = 0; i < data_num; i++) { + sprintf(tmp_log + i * 7, "%5d, ", data[i]); + } + tmp_log[data_num * 7] = '\0'; + NVT_LOG("%s", tmp_log); + if (tmp_log) { + kfree(tmp_log); + tmp_log = NULL; + } + + return; +} + +static void nvt_print_result_log_in_one_line(uint8_t *result, + int32_t result_num) +{ + char *tmp_log = NULL; + int32_t i = 0; + + tmp_log = (char *)kzalloc(result_num * 6 + 1, GFP_KERNEL); + if (!tmp_log) { + NVT_ERR("kzalloc for tmp_log failed!\n "); + return; + } + + for (i = 0; i < result_num; i++) { + sprintf(tmp_log + i * 6, "0x%02X, ", result[i]); + } + tmp_log[result_num * 6] = '\0'; + printk("%s", tmp_log); + if (tmp_log) { + kfree(tmp_log); + tmp_log = NULL; + } + + return; +} + +/******************************************************* +Description: + Novatek touchscreen self-test criteria print function. + +return: + n.a. +*******************************************************/ +static void nvt_print_lmt_array(int32_t *array, int32_t x_ch, int32_t y_ch) +{ + int32_t j = 0; + + for (j = 0; j < y_ch; j++) { + nvt_print_data_log_in_one_line(array + j * x_ch, x_ch); + printk("\n"); + } +} + +static void nvt_print_criteria(void) +{ + NVT_LOG("%s ++\n", __func__); + + /* ---PS_Config_Lmt_Short_Rawdata--- */ + NVT_LOG("PS_Config_Lmt_Short_Rawdata_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_Short_Rawdata_P, X_Channel, + Y_Channel); + NVT_LOG("PS_Config_Lmt_Short_Rawdata_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_Short_Rawdata_N, X_Channel, + Y_Channel); + + /* ---PS_Config_Lmt_Open_Rawdata--- */ + NVT_LOG("PS_Config_Lmt_Open_Rawdata_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_Open_Rawdata_P, X_Channel, Y_Channel); + NVT_LOG("PS_Config_Lmt_Open_Rawdata_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_Open_Rawdata_N, X_Channel, Y_Channel); + + /* ---PS_Config_Lmt_FW_Rawdata--- */ + NVT_LOG("PS_Config_Lmt_FW_Rawdata_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_FW_Rawdata_P, X_Channel, Y_Channel); + NVT_LOG("PS_Config_Lmt_FW_Rawdata_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_FW_Rawdata_N, X_Channel, Y_Channel); + + /* ---PS_Config_Lmt_FW_CC--- */ + NVT_LOG("PS_Config_Lmt_FW_CC_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_FW_CC_P, X_Channel, Y_Channel); + NVT_LOG("PS_Config_Lmt_FW_CC_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_FW_CC_N, X_Channel, Y_Channel); + + /* ---PS_Config_Lmt_FW_Diff--- */ + NVT_LOG("PS_Config_Lmt_FW_Diff_P:\n"); + nvt_print_lmt_array(PS_Config_Lmt_FW_Diff_P, X_Channel, Y_Channel); + NVT_LOG("PS_Config_Lmt_FW_Diff_N:\n"); + nvt_print_lmt_array(PS_Config_Lmt_FW_Diff_N, X_Channel, Y_Channel); + + NVT_LOG("%s --\n", __func__); +} + +#ifndef NVT_SAVE_TESTDATA_IN_FILE +void dump_buff(int32_t *rawdata, uint8_t x_ch, uint8_t y_ch) +{ + int32_t y = 0; + + for (y = 0; y < y_ch; y++) { + nvt_print_data_log_in_one_line(rawdata + y * x_ch, x_ch); + NVT_LOG("%s:++\n", __func__); + } +} +#endif +static int32_t nvt_save_rawdata_to_csv(int32_t *rawdata, uint8_t x_ch, + uint8_t y_ch, const char *file_path, + uint32_t offset, enum test_type type) +{ +#ifdef NVT_SAVE_TESTDATA_IN_FILE + int32_t x = 0; + int32_t y = 0; + int32_t iArrayIndex = 0; + struct file *fp = NULL; + char *fbufp = NULL; + mm_segment_t org_fs; + int32_t write_ret = 0; + uint32_t output_len = 0; + loff_t pos = 0; +#else /*#ifdef NVT_SAVE_TESTDATA_IN_FILE*/ + struct test_buf *tbuf = ts->testdata; +#endif /*#ifdef NVT_SAVE_TESTDATA_IN_FILE*/ + + NVT_LOG("%s:++\n", __func__); + +#ifdef NVT_SAVE_TESTDATA_IN_FILE + fbufp = (char *)kzalloc(8192, GFP_KERNEL); + if (!fbufp) { + NVT_ERR("kzalloc for fbufp failed!\n"); + return -ENOMEM; + } + + for (y = 0; y < y_ch; y++) { + for (x = 0; x < x_ch; x++) { + iArrayIndex = y * x_ch + x; + sprintf(fbufp + iArrayIndex * 7 + y * 2, "%5d, ", + rawdata[iArrayIndex]); + } + nvt_print_data_log_in_one_line(rawdata + y * x_ch, x_ch); + NVT_LOG("\n"); + sprintf(fbufp + (iArrayIndex + 1) * 7 + y * 2, "\r\n"); + } + + org_fs = get_fs(); + set_fs(KERNEL_DS); + fp = filp_open(file_path, O_RDWR | O_CREAT, 0644); + if (fp == NULL || IS_ERR(fp)) { + NVT_ERR("open %s failed\n", file_path); + set_fs(org_fs); + if (fbufp) { + kfree(fbufp); + fbufp = NULL; + } + return -1; + } + + output_len = y_ch * x_ch * 7 + y_ch * 2; + pos = offset; + write_ret = vfs_write(fp, (char __user *)fbufp, output_len, &pos); + if (write_ret <= 0) { + NVT_ERR("write %s failed\n", file_path); + set_fs(org_fs); + if (fp) { + filp_close(fp, NULL); + fp = NULL; + } + if (fbufp) { + kfree(fbufp); + fbufp = NULL; + } + return -1; + } + + set_fs(org_fs); + if (fp) { + filp_close(fp, NULL); + fp = NULL; + } + if (fbufp) { + kfree(fbufp); + fbufp = NULL; + } +#else /*#ifdef NVT_SAVE_TESTDATA_IN_FILE*/ + switch (type) { + case SHORT_TEST: + NVT_LOG("SHORT_TEST start copy TEST_BUF_LEN = %d", + TEST_BUF_LEN); + memset(tbuf->shorttest.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->shorttest.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->shorttest.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST(%p):=============\n", + tbuf->shorttest.buf); + dump_buff((int32_t *)tbuf->shorttest.buf, x_ch, y_ch); + NVT_LOG("SHORT_TEST copy complete"); + break; + case OPEN_TEST: + NVT_LOG("OPEN_TEST start copy"); + memset(tbuf->opentest.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->opentest.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->opentest.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST(%p):=============\n", + tbuf->opentest.buf); + dump_buff((int32_t *)tbuf->opentest.buf, x_ch, y_ch); + NVT_LOG("OPEN_TEST copy complete"); + break; + case FWMUTUAL_TEST: + NVT_LOG("FWMUTUAL_TEST start copy"); + memset(tbuf->fwmutualtest.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->fwmutualtest.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->fwmutualtest.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->fwmutualtest.buf, x_ch, y_ch); + NVT_LOG("FWMUTUAL_TEST copy complete"); + break; + case FWCC_TEST: + NVT_LOG("FWCC_TEST start copy"); + memset(tbuf->fwcctest.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->fwcctest.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->fwcctest.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->fwcctest.buf, x_ch, y_ch); + NVT_LOG("FWCC_TEST copy complete"); + break; + case NOISE_MAX_TEST: + NVT_LOG("NOISE_MAX_TEST start copy"); + memset(tbuf->noisetest_max.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->noisetest_max.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->noisetest_max.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->noisetest_max.buf, x_ch, y_ch); + NVT_LOG("NOISE_MAX_TEST copy complete"); + break; + case NOISE_MIN_TEST: + NVT_LOG("NOISE_MIN_TEST start copy"); + memset(tbuf->noisetest_min.buf, 0, TEST_BUF_LEN); + memcpy(tbuf->noisetest_min.buf, (uint8_t *)rawdata, + x_ch * y_ch * sizeof(int32_t)); + tbuf->noisetest_min.len = x_ch * y_ch * sizeof(int32_t); + NVT_LOG("===========SRC:=============\n"); + dump_buff(rawdata, x_ch, y_ch); + NVT_LOG("===========DST:=============\n"); + dump_buff((int32_t *)tbuf->noisetest_min.buf, x_ch, y_ch); + NVT_LOG("NOISE_MIN_TEST copy complete"); + break; + default: + NVT_ERR("test type is illegal"); + break; + } +#endif /*#ifdef NVT_SAVE_TESTDATA_IN_FILE*/ + NVT_LOG("%s:--\n", __func__); + + return 0; +} + +static int32_t nvt_polling_hand_shake_status(void) +{ + uint8_t buf[8] = { 0 }; + int32_t i = 0; + const int32_t retry = 250; + + for (i = 0; i < retry; i++) { + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | + EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE); + + /* ---read fw status--- */ + buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; + buf[1] = 0x00; + CTP_SPI_READ(ts->client, buf, 2); + + if ((buf[1] == 0xA0) || (buf[1] == 0xA1)) + break; + + usleep_range(10000, 10000); + } + + if (i >= retry) { + NVT_ERR("polling hand shake status failed, buf[1]=0x%02X\n", + buf[1]); + + /* Read back 5 bytes from offset EVENT_MAP_HOST_CMD for debug check */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + buf[5] = 0x00; + CTP_SPI_READ(ts->client, buf, 6); + NVT_ERR("Read back 5 bytes from offset EVENT_MAP_HOST_CMD: 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", + buf[1], buf[2], buf[3], buf[4], buf[5]); + + return -1; + } else { + return 0; + } +} + +static int8_t nvt_switch_FreqHopEnDis(uint8_t FreqHopEnDis) +{ + uint8_t buf[8] = { 0 }; + uint8_t retry = 0; + int8_t ret = 0; + + NVT_LOG("%s ++\n", __func__); + + for (retry = 0; retry < 20; retry++) { + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + /* ---switch FreqHopEnDis--- */ + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = FreqHopEnDis; + CTP_SPI_WRITE(ts->client, buf, 2); + + msleep(35); + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0xFF; + CTP_SPI_READ(ts->client, buf, 2); + + if (buf[1] == 0x00) + break; + } + + if (unlikely(retry == 20)) { + NVT_ERR("switch FreqHopEnDis 0x%02X failed, buf[1]=0x%02X\n", + FreqHopEnDis, buf[1]); + ret = -1; + } + + NVT_LOG("%s --\n", __func__); + + return ret; +} + +static int32_t nvt_read_baseline(int32_t *xdata) +{ + uint8_t x_num = 0; + uint8_t y_num = 0; + uint32_t x = 0; + uint32_t y = 0; + int32_t iArrayIndex = 0; + + NVT_LOG("%s ++\n", __func__); + + nvt_read_mdata(ts->mmap->BASELINE_ADDR, ts->mmap->BASELINE_BTN_ADDR); + + nvt_get_mdata(xdata, &x_num, &y_num); + + for (y = 0; y < y_num; y++) { + for (x = 0; x < x_num; x++) { + iArrayIndex = y * x_num + x; + xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex]; + } + } + + NVT_LOG("%s:\n", __func__); + // Save Rawdata to CSV file + if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, + FW_RAWDATA_CSV_FILE, 0, + FWMUTUAL_TEST) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + + NVT_LOG("%s --\n", __func__); + + return 0; +} + +static int32_t nvt_read_CC(int32_t *xdata) +{ + uint8_t x_num = 0; + uint8_t y_num = 0; + uint32_t x = 0; + uint32_t y = 0; + int32_t iArrayIndex = 0; + + NVT_LOG("%s ++\n", __func__); + + if (nvt_get_fw_pipe() == 0) + nvt_read_mdata(ts->mmap->DIFF_PIPE1_ADDR, + ts->mmap->DIFF_BTN_PIPE1_ADDR); + else + nvt_read_mdata(ts->mmap->DIFF_PIPE0_ADDR, + ts->mmap->DIFF_BTN_PIPE0_ADDR); + + nvt_get_mdata(xdata, &x_num, &y_num); + + for (y = 0; y < y_num; y++) { + for (x = 0; x < x_num; x++) { + iArrayIndex = y * x_num + x; + xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex]; + } + } + + NVT_LOG("%s:\n", __func__); + /* Save Rawdata to CSV file */ + if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, FW_CC_CSV_FILE, + 0, FWCC_TEST) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + + NVT_LOG("%s --\n", __func__); + + return 0; +} + +static void nvt_enable_noise_collect(int32_t frame_num) +{ + uint8_t buf[8] = { 0 }; + + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + /* ---enable noise collect--- */ + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x47; + buf[2] = 0xAA; + buf[3] = frame_num; + buf[4] = 0x00; + CTP_SPI_WRITE(ts->client, buf, 5); +} + +static int32_t nvt_read_fw_noise(int32_t *xdata) +{ + uint8_t x_num = 0; + uint8_t y_num = 0; + uint32_t x = 0; + uint32_t y = 0; + int32_t iArrayIndex = 0; + int32_t frame_num = 0; + uint32_t rawdata_diff_min_offset = 0; + + NVT_LOG("%s ++\n", __func__); + + /* --Enter Test Mode--- */ + if (nvt_clear_fw_status()) { + return -EAGAIN; + } + + frame_num = PS_Config_Diff_Test_Frame / 10; + if (frame_num <= 0) + frame_num = 1; + NVT_LOG("%s: frame_num=%d\n", __func__, frame_num); + nvt_enable_noise_collect(frame_num); + /* need wait PS_Config_Diff_Test_Frame * 8.3ms */ + msleep(frame_num * 83); + + if (nvt_polling_hand_shake_status()) { + return -EAGAIN; + } + + if (nvt_get_fw_info()) { + return -EAGAIN; + } + + if (nvt_get_fw_pipe() == 0) + nvt_read_mdata(ts->mmap->DIFF_PIPE0_ADDR, + ts->mmap->DIFF_BTN_PIPE0_ADDR); + else + nvt_read_mdata(ts->mmap->DIFF_PIPE1_ADDR, + ts->mmap->DIFF_BTN_PIPE1_ADDR); + + nvt_get_mdata(xdata, &x_num, &y_num); + + for (y = 0; y < y_num; y++) { + for (x = 0; x < x_num; x++) { + iArrayIndex = y * x_num + x; + RawData_Diff_Max[iArrayIndex] = + (int8_t)((xdata[iArrayIndex] >> 8) & 0xFF); + RawData_Diff_Min[iArrayIndex] = + (int8_t)(xdata[iArrayIndex] & 0xFF); + } + } + + /*---Leave Test Mode--- */ + nvt_change_mode(NORMAL_MODE); + + NVT_LOG("%s:RawData_Diff_Max:\n", __func__); + /* Save Rawdata to CSV file */ + if (nvt_save_rawdata_to_csv(RawData_Diff_Max, X_Channel, Y_Channel, + NOISE_TEST_CSV_FILE, 0, + NOISE_MAX_TEST) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + + rawdata_diff_min_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2; + NVT_LOG("%s:RawData_Diff_Min:\n", __func__); + /* Save Rawdata to CSV file */ + if (nvt_save_rawdata_to_csv( + RawData_Diff_Min, X_Channel, Y_Channel, NOISE_TEST_CSV_FILE, + rawdata_diff_min_offset, NOISE_MIN_TEST) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + + NVT_LOG("%s --\n", __func__); + + return 0; +} + +static void nvt_enable_open_test(void) +{ + uint8_t buf[8] = { 0 }; + + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + /* ---enable open test--- */ + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x45; + buf[2] = 0xAA; + buf[3] = 0x02; + buf[4] = 0x00; + CTP_SPI_WRITE(ts->client, buf, 5); +} + +static void nvt_enable_short_test(void) +{ + uint8_t buf[8] = { 0 }; + + /* ---set xdata index to EVENT BUF ADDR--- */ + nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + + /* ---enable short test--- */ + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x43; + buf[2] = 0xAA; + buf[3] = 0x02; + buf[4] = 0x00; + CTP_SPI_WRITE(ts->client, buf, 5); +} + +static int32_t nvt_read_fw_open(int32_t *xdata) +{ + uint32_t raw_pipe_addr = 0; + uint8_t *rawdata_buf = NULL; + uint32_t x = 0; + uint32_t y = 0; + uint8_t buf[128] = { 0 }; + + NVT_LOG("%s ++\n", __func__); + + /*---Enter Test Mode--- */ + if (nvt_clear_fw_status()) { + return -EAGAIN; + } + + nvt_enable_open_test(); + + if (nvt_polling_hand_shake_status()) { + return -EAGAIN; + } + + rawdata_buf = (uint8_t *)kzalloc(IC_X_CFG_SIZE * IC_Y_CFG_SIZE * 2, + GFP_KERNEL); + + if (!rawdata_buf) { + NVT_ERR("kzalloc for rawdata_buf failed!\n"); + return -ENOMEM; + } + + if (nvt_get_fw_pipe() == 0) + raw_pipe_addr = ts->mmap->RAW_PIPE0_ADDR; + else + raw_pipe_addr = ts->mmap->RAW_PIPE1_ADDR; + + for (y = 0; y < IC_Y_CFG_SIZE; y++) { + /* ---change xdata index--- */ + nvt_set_page(raw_pipe_addr + y * IC_X_CFG_SIZE * 2); + + buf[0] = (uint8_t)((raw_pipe_addr + y * IC_X_CFG_SIZE * 2) & + 0xFF); + CTP_SPI_READ(ts->client, buf, IC_X_CFG_SIZE * 2 + 1); + memcpy(rawdata_buf + y * IC_X_CFG_SIZE * 2, buf + 1, + IC_X_CFG_SIZE * 2); + } + + for (y = 0; y < IC_Y_CFG_SIZE; y++) { + for (x = 0; x < IC_X_CFG_SIZE; x++) { + if ((AIN_Y[y] != 0xFF) && (AIN_X[x] != 0xFF)) { + xdata[AIN_Y[y] * X_Channel + AIN_X[x]] = (int16_t)(( + rawdata_buf[(y * IC_X_CFG_SIZE + x) * 2] + + 256 * rawdata_buf[(y * IC_X_CFG_SIZE + + x) * 2 + + 1])); + } + } + } + + if (rawdata_buf) { + kfree(rawdata_buf); + rawdata_buf = NULL; + } + + /* ---Leave Test Mode--- */ + nvt_change_mode(NORMAL_MODE); + + NVT_LOG("%s:RawData_Open\n", __func__); + /* Save RawData to CSV file */ + if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, + OPEN_TEST_CSV_FILE, 0, OPEN_TEST) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + + NVT_LOG("%s --\n", __func__); + + return 0; +} + +static int32_t nvt_read_fw_short(int32_t *xdata) +{ + uint32_t raw_pipe_addr = 0; + uint8_t *rawdata_buf = NULL; + uint32_t x = 0; + uint32_t y = 0; + uint8_t buf[128] = { 0 }; + int32_t iArrayIndex = 0; + + NVT_LOG("%s ++\n", __func__); + + /* ---Enter Test Mode--- */ + if (nvt_clear_fw_status()) { + return -EAGAIN; + } + + nvt_enable_short_test(); + + if (nvt_polling_hand_shake_status()) { + return -EAGAIN; + } + + rawdata_buf = (uint8_t *)kzalloc(X_Channel * Y_Channel * 2, GFP_KERNEL); + + if (!rawdata_buf) { + NVT_ERR("kzalloc for rawdata_buf failed!\n"); + return -ENOMEM; + } + + if (nvt_get_fw_pipe() == 0) + raw_pipe_addr = ts->mmap->RAW_PIPE0_ADDR; + else + raw_pipe_addr = ts->mmap->RAW_PIPE1_ADDR; + + for (y = 0; y < Y_Channel; y++) { + /* ---change xdata index--- */ + nvt_set_page(raw_pipe_addr + y * X_Channel * 2); + + buf[0] = (uint8_t)((raw_pipe_addr + y * X_Channel * 2) & 0xFF); + CTP_SPI_READ(ts->client, buf, X_Channel * 2 + 1); + memcpy(rawdata_buf + y * X_Channel * 2, buf + 1, X_Channel * 2); + } + + for (y = 0; y < Y_Channel; y++) { + for (x = 0; x < X_Channel; x++) { + iArrayIndex = y * X_Channel + x; + xdata[iArrayIndex] = + (int16_t)(rawdata_buf[iArrayIndex * 2] + + 256 * rawdata_buf[iArrayIndex * 2 + + 1]); + } + } + + if (rawdata_buf) { + kfree(rawdata_buf); + rawdata_buf = NULL; + } + + /* ---Leave Test Mode--- */ + nvt_change_mode(NORMAL_MODE); + + NVT_LOG("%s:RawData_Short\n", __func__); + /* Save Rawdata to CSV file */ + if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, + SHORT_TEST_CSV_FILE, 0, SHORT_TEST) < 0) { + NVT_ERR("save rawdata to CSV file failed\n"); + return -EAGAIN; + } + + NVT_LOG("%s --\n", __func__); + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen raw data test for each single point function. + +return: + Executive outcomes. 0---passed. negative---failed. +*******************************************************/ +static int32_t RawDataTest_SinglePoint_Sub(int32_t rawdata[], + uint8_t RecordResult[], uint8_t x_ch, + uint8_t y_ch, + int32_t Rawdata_Limit_Postive[], + int32_t Rawdata_Limit_Negative[]) +{ + int32_t i = 0; + int32_t j = 0; + int32_t iArrayIndex = 0; + bool isPass = true; + + for (j = 0; j < y_ch; j++) { + for (i = 0; i < x_ch; i++) { + iArrayIndex = j * x_ch + i; + + RecordResult[iArrayIndex] = + 0x00; /* default value for PASS */ + + if (rawdata[iArrayIndex] > + Rawdata_Limit_Postive[iArrayIndex]) + RecordResult[iArrayIndex] |= 0x01; + + if (rawdata[iArrayIndex] < + Rawdata_Limit_Negative[iArrayIndex]) + RecordResult[iArrayIndex] |= 0x02; + } + } + + /* ---Check RecordResult--- */ + for (j = 0; j < y_ch; j++) { + for (i = 0; i < x_ch; i++) { + if (RecordResult[j * x_ch + i] != 0) { + isPass = false; + break; + } + } + } + + if (isPass == false) { + return -1; + } else { + return 0; + } +} + +/******************************************************* +Description: + Novatek touchscreen print self-test result function. + +return: + n.a. +*******************************************************/ +void print_selftest_result(struct seq_file *m, int32_t TestResult, + uint8_t RecordResult[], int32_t rawdata[], + uint8_t x_len, uint8_t y_len) +{ + int32_t i = 0; + int32_t j = 0; + int32_t iArrayIndex = 0; + + switch (TestResult) { + case 0: + nvt_mp_seq_printf(m, " PASS!\n"); + break; + + case 1: + nvt_mp_seq_printf(m, " ERROR! Read Data FAIL!\n"); + break; + + case -1: + nvt_mp_seq_printf(m, " FAIL!\n"); + nvt_mp_seq_printf(m, "RecordResult:\n"); + for (i = 0; i < y_len; i++) { + for (j = 0; j < x_len; j++) { + iArrayIndex = i * x_len + j; + seq_printf(m, "0x%02X, ", + RecordResult[iArrayIndex]); + } + if (!nvt_mp_test_result_printed) + nvt_print_result_log_in_one_line( + RecordResult + i * x_len, x_len); + nvt_mp_seq_printf(m, "\n"); + } + nvt_mp_seq_printf(m, "ReadData:\n"); + for (i = 0; i < y_len; i++) { + for (j = 0; j < x_len; j++) { + iArrayIndex = i * x_len + j; + seq_printf(m, "%5d, ", rawdata[iArrayIndex]); + } + if (!nvt_mp_test_result_printed) + nvt_print_data_log_in_one_line( + rawdata + i * x_len, x_len); + nvt_mp_seq_printf(m, "\n"); + } + break; + } + nvt_mp_seq_printf(m, "\n"); +} + +/******************************************************* +Description: + Novatek touchscreen self-test sequence print show + function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int32_t c_show_selftest(struct seq_file *m, void *v) +{ + NVT_LOG("%s ++\n", __func__); + + nvt_mp_seq_printf(m, "FW Version: %d\n\n", fw_ver); + + nvt_mp_seq_printf(m, "Short Test"); + if ((TestResult_Short == 0) || (TestResult_Short == 1)) { + print_selftest_result(m, TestResult_Short, RecordResult_Short, + RawData_Short, X_Channel, Y_Channel); + } else { /* TestResult_Short is -1 */ + print_selftest_result(m, TestResult_Short, RecordResult_Short, + RawData_Short, X_Channel, Y_Channel); + } + + nvt_mp_seq_printf(m, "Open Test"); + print_selftest_result(m, TestResult_Open, RecordResult_Open, + RawData_Open, X_Channel, Y_Channel); + + nvt_mp_seq_printf(m, "FW Rawdata Test"); + if ((TestResult_FW_Rawdata == 0) || (TestResult_FW_Rawdata == 1)) { + print_selftest_result(m, TestResult_FWMutual, + RecordResult_FWMutual, RawData_FWMutual, + X_Channel, Y_Channel); + } else { /* TestResult_FW_Rawdata is -1 */ + nvt_mp_seq_printf(m, " FAIL!\n"); + if (TestResult_FWMutual == -1) { + nvt_mp_seq_printf(m, "FW Mutual"); + print_selftest_result(m, TestResult_FWMutual, + RecordResult_FWMutual, + RawData_FWMutual, X_Channel, + Y_Channel); + } + if (TestResult_FW_CC == -1) { + nvt_mp_seq_printf(m, "FW CC"); + print_selftest_result(m, TestResult_FW_CC, + RecordResult_FW_CC, RawData_FW_CC, + X_Channel, Y_Channel); + } + } + + nvt_mp_seq_printf(m, "Noise Test"); + if ((TestResult_Noise == 0) || (TestResult_Noise == 1)) { + print_selftest_result(m, TestResult_FW_DiffMax, + RecordResult_FW_DiffMax, RawData_Diff_Max, + X_Channel, Y_Channel); + } else { /* TestResult_Noise is -1 */ + nvt_mp_seq_printf(m, " FAIL!\n"); + + if (TestResult_FW_DiffMax == -1) { + nvt_mp_seq_printf(m, "FW Diff Max"); + print_selftest_result(m, TestResult_FW_DiffMax, + RecordResult_FW_DiffMax, + RawData_Diff_Max, X_Channel, + Y_Channel); + } + if (TestResult_FW_DiffMin == -1) { + nvt_mp_seq_printf(m, "FW Diff Min"); + print_selftest_result(m, TestResult_FW_DiffMin, + RecordResult_FW_DiffMin, + RawData_Diff_Min, X_Channel, + Y_Channel); + } + } + + nvt_mp_test_result_printed = 1; + + NVT_LOG("%s --\n", __func__); + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen self-test sequence print start + function. + +return: + Executive outcomes. 1---call next function. + NULL---not call next function and sequence loop + stop. +*******************************************************/ +static void *c_start(struct seq_file *m, loff_t *pos) +{ + return *pos < 1 ? (void *)1 : NULL; +} + +/******************************************************* +Description: + Novatek touchscreen self-test sequence print next + function. + +return: + Executive outcomes. NULL---no next and call sequence + stop function. +*******************************************************/ +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return NULL; +} + +/******************************************************* +Description: + Novatek touchscreen self-test sequence print stop + function. + +return: + n.a. +*******************************************************/ +static void c_stop(struct seq_file *m, void *v) +{ + return; +} + +const struct seq_operations nvt_selftest_seq_ops = { .start = c_start, + .next = c_next, + .stop = c_stop, + .show = c_show_selftest }; + +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV +static void goto_next_line(char **ptr) +{ + do { + *ptr = *ptr + 1; + } while (**ptr != '\n'); + *ptr = *ptr + 1; +} + +static void copy_this_line(char *dest, char *src) +{ + char *copy_from; + char *copy_to; + + copy_from = src; + copy_to = dest; + do { + *copy_to = *copy_from; + copy_from++; + copy_to++; + } while ((*copy_from != '\n') && (*copy_from != '\r')); + *copy_to = '\0'; +} + +int32_t parse_mp_setting_criteria_item(char **ptr, const char *item_string, + int32_t *item_value) +{ + char *tmp = NULL; + + NVT_LOG("%s ++\n", __func__); + tmp = strstr(*ptr, item_string); + if (tmp == NULL) { + NVT_ERR("%s not found\n", item_string); + return -1; + } + *ptr = tmp; + goto_next_line(ptr); + sscanf(*ptr, "%d,", item_value); + NVT_LOG("%s %d\n", item_string, *item_value); + + NVT_LOG("%s --\n", __func__); + return 0; +} + +int32_t parse_mp_setting_ain_array(char **ptr, const char *item_string, + uint8_t *ain_array, uint32_t IC_CFG_SIZE) +{ + char *tmp = NULL; + int32_t i = 0; + char *token = NULL; + char *tok_ptr = NULL; + size_t offset = 0; + char tmp_buf[512] = { 0 }; + + NVT_LOG("%s ++\n", __func__); + tmp = strstr(*ptr, item_string); + if (tmp == NULL) { + NVT_ERR("%s not found!\n", item_string); + return -1; + } + *ptr = tmp; + + NVT_LOG("%s\n", item_string); + /* walk thru this line */ + goto_next_line(ptr); + + /* copy this line to tmp_buf */ + memset(tmp_buf, 0, sizeof(tmp_buf)); + copy_this_line(tmp_buf, *ptr); + offset = strlen(tmp_buf); + tok_ptr = tmp_buf; + i = 0; + while ((token = strsep(&tok_ptr, ", \t\r\0"))) { + if (strlen(token) == 0) + continue; + if (!strcmp(token, "0xFF") || !strcmp(token, "0xff")) + ain_array[i] = 255; + else + ain_array[i] = (uint8_t)simple_strtol(token, NULL, 10); + NVT_LOG("%d, ", ain_array[i]); + + i++; + } + NVT_LOG("\n"); + /* check if number equals to IC_CFG_SIZE */ + if (i != IC_CFG_SIZE) { + NVT_ERR("load AIN config failed!, i=%d, IC_CFG_SIZE=%d\n", i, + IC_CFG_SIZE); + return -1; + } + /* go forward */ + *ptr = *ptr + offset; + + NVT_LOG("%s --\n", __func__); + return 0; +} + +int32_t parse_mp_criteria_item_array(char **ptr, const char *item_string, + int32_t *item_array) +{ + char *tmp = NULL; + int32_t i = 0; + int32_t j = 0; + char *token = NULL; + char *tok_ptr = NULL; + size_t offset = 0; + char tmp_buf[512] = { 0 }; + + NVT_LOG("%s ++\n", __func__); + tmp = strstr(*ptr, item_string); + if (tmp == NULL) { + NVT_ERR("%s not found\n", item_string); + return -1; + } + *ptr = tmp; + + NVT_LOG("%s\n", item_string); + for (i = 0; i < Y_Channel; i++) { + /* walk thru this line */ + goto_next_line(ptr); + memset(tmp_buf, 0, sizeof(tmp_buf)); + copy_this_line(tmp_buf, *ptr); + offset = strlen(tmp_buf); + tok_ptr = tmp_buf; + j = 0; + while ((token = strsep(&tok_ptr, ", \t\r\0"))) { + if (strlen(token) == 0) + continue; + item_array[i * X_Channel + j] = + (int32_t)simple_strtol(token, NULL, 10); + NVT_LOG("%5d, ", item_array[i * X_Channel + j]); + j++; + } + NVT_LOG("\n"); + /* check if j equals to X_Channel */ + if (j != X_Channel) { + NVT_ERR("%s :j not equal X_Channel!, j=%d, X_Channel=%d\n", + item_string, j, X_Channel); + return -1; + } + /* go forward */ + *ptr = *ptr + offset; + } + + NVT_LOG("%s --\n", __func__); + return 0; +} + +static int32_t nvt_load_mp_setting_criteria_from_csv(const char *filename) +{ + int32_t retval = 0; + const struct firmware *fw_entry = NULL; + char *fbufp = NULL; + char *ptr = NULL; + + NVT_LOG("%s ++\n", __func__); + + if (NULL == filename) { + NVT_ERR("filename is null\n"); + retval = -1; + goto exit_free; + } + + retval = request_firmware(&fw_entry, filename, &ts->client->dev); + if (retval) { + NVT_ERR("%s load failed, retval=%d\n", filename, retval); + retval = -1; + goto exit_free; + } + + fbufp = (char *)kzalloc(fw_entry->size + 2, GFP_KERNEL); + if (!fbufp) { + NVT_ERR("kzalloc %zu bytes failed!\n", fw_entry->size); + retval = -1; + goto exit_free; + } + + memcpy(fbufp, fw_entry->data, fw_entry->size); + + /* NVT_LOG("File Size: %zu\n", fw_entry->size); + NVT_LOG("---------------------------------------------------\n"); + printk("fbufp:\n"); + for(i = 0; i < fw_entry->size; i++) { + printk("%c", fbufp[i]); + } + NVT_LOG("---------------------------------------------------\n"); */ + + fbufp[fw_entry->size] = '\0'; + fbufp[fw_entry->size + 1] = '\n'; + + ptr = fbufp; + if (parse_mp_setting_criteria_item( + &ptr, "IC_X_CFG_SIZE:", &IC_X_CFG_SIZE) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_setting_criteria_item( + &ptr, "IC_Y_CFG_SIZE:", &IC_Y_CFG_SIZE) < 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_setting_criteria_item(&ptr, "X_Channel:", &X_Channel) < + 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_setting_criteria_item(&ptr, "Y_Channel:", &Y_Channel) < + 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_setting_ain_array(&ptr, "AIN_X:", AIN_X, IC_X_CFG_SIZE) < + 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_setting_ain_array(&ptr, "AIN_Y:", AIN_Y, IC_Y_CFG_SIZE) < + 0) { + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_Short_Rawdata_P:", + PS_Config_Lmt_Short_Rawdata_P) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_Short_Rawdata_P array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_Short_Rawdata_N:", + PS_Config_Lmt_Short_Rawdata_N) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_Short_Rawdata_N array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_Open_Rawdata_P:", + PS_Config_Lmt_Open_Rawdata_P) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_Open_Rawdata_P array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_Open_Rawdata_N:", + PS_Config_Lmt_Open_Rawdata_N) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_Open_Rawdata_N array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_FW_Rawdata_P:", + PS_Config_Lmt_FW_Rawdata_P) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_FW_Rawdata_P array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_FW_Rawdata_N:", + PS_Config_Lmt_FW_Rawdata_N) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_FW_Rawdata_N array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_FW_CC_P:", + PS_Config_Lmt_FW_CC_P) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_FW_CC_P array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_FW_CC_N:", + PS_Config_Lmt_FW_CC_N) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_FW_CC_N array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_FW_Diff_P:", + PS_Config_Lmt_FW_Diff_P) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_FW_Diff_P array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_criteria_item_array(&ptr, "PS_Config_Lmt_FW_Diff_N:", + PS_Config_Lmt_FW_Diff_N) < 0) { + NVT_ERR("Cannot get PS_Config_Lmt_FW_Diff_N array value!\n"); + retval = -1; + goto exit_free; + } + + ptr = fbufp; + if (parse_mp_setting_criteria_item(&ptr, "PS_Config_Diff_Test_Frame:", + &PS_Config_Diff_Test_Frame) < 0) { + retval = -1; + goto exit_free; + } + + NVT_LOG("Load MP setting and criteria from CSV file finished.\n"); + retval = 0; + +exit_free: + if (fw_entry) { + release_firmware(fw_entry); + fw_entry = NULL; + } + if (fbufp) { + kfree(fbufp); + fbufp = NULL; + } + + NVT_LOG("--, retval=%d\n", retval); + return retval; +} +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + +/******************************************************* +Description: + Novatek touchscreen /proc/nvt_selftest open function. + +return: + Executive outcomes. 0---succeed. negative---failed. +*******************************************************/ +static int32_t nvt_selftest_open(struct inode *inode, struct file *file) +{ + struct device_node *np = ts->pdev->dev.of_node; + unsigned char mpcriteria[32] = { 0 }; +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + char mp_setting_criteria_csv_filename[64] = { 0 }; +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + + TestResult_Short = 0; + TestResult_Open = 0; + TestResult_FW_Rawdata = 0; + TestResult_FWMutual = 0; + TestResult_FW_CC = 0; + TestResult_Noise = 0; + TestResult_FW_DiffMax = 0; + TestResult_FW_DiffMin = 0; + + NVT_LOG("%s ++\n", __func__); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_MP_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->mp_name); + } + } else { + nvt_update_firmware(ts->mp_name); + } + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + NVT_ERR("get fw info failed!\n"); + return -EAGAIN; + } + fw_ver = ts->fw_ver; +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + /* ---Check if MP Setting Criteria CSV file exist and load--- */ + snprintf(mp_setting_criteria_csv_filename, PAGE_SIZE, + "NT36xxx_MP_Setting_Criteria_%04X.csv", ts->nvt_pid); + NVT_LOG("MP setting criteria csv filename: %s\n", + mp_setting_criteria_csv_filename); + if (nvt_load_mp_setting_criteria_from_csv( + mp_setting_criteria_csv_filename) < 0) { + NVT_ERR("SelfTest MP setting criteria CSV file not exist or load failed\n"); +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + /* Parsing criteria from dts */ + if (of_property_read_bool(np, "novatek,mp-support-dt")) { + /* + * Parsing Criteria by Novatek PID + * The string rule is "novatek-mp-criteria-" + * nvt_pid is 2 bytes (show hex). + * + * Ex. nvt_pid = 500A + * mpcriteria = "novatek-mp-criteria-500A" + */ + snprintf(mpcriteria, PAGE_SIZE, + "novatek-mp-criteria-%04X", ts->nvt_pid); + + if (nvt_mp_parse_dt(np, mpcriteria)) { + /* ---Download Normal FW--- */ + nvt_update_firmware(ts->fw_name); + mutex_unlock(&ts->lock); + NVT_ERR("mp parse device tree failed!\n"); + return -EINVAL; + } + } else { + NVT_LOG("Not found novatek,mp-support-dt, use default setting\n"); + /* ---Print Test Criteria--- */ + nvt_print_criteria(); + } +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + } else { + NVT_LOG("SelfTest MP setting criteria loaded from CSV file\n"); + } +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + + if (nvt_switch_FreqHopEnDis(FREQ_HOP_DISABLE)) { + mutex_unlock(&ts->lock); + NVT_ERR("switch frequency hopping disable failed!\n"); + return -EAGAIN; + } + + if (nvt_check_fw_reset_state(RESET_STATE_NORMAL_RUN)) { + mutex_unlock(&ts->lock); + NVT_ERR("check fw reset state failed!\n"); + return -EAGAIN; + } + + msleep(100); + + /* ---Enter Test Mode--- */ + if (nvt_clear_fw_status()) { + mutex_unlock(&ts->lock); + NVT_ERR("clear fw status failed!\n"); + return -EAGAIN; + } + + nvt_change_mode(MP_MODE_CC); + + if (nvt_check_fw_status()) { + mutex_unlock(&ts->lock); + NVT_ERR("check fw status failed!\n"); + return -EAGAIN; + } + + /* ---FW Rawdata Test--- */ + if (nvt_read_baseline(RawData_FWMutual) != 0) { + TestResult_FWMutual = 1; + } else { + TestResult_FWMutual = RawDataTest_SinglePoint_Sub( + RawData_FWMutual, RecordResult_FWMutual, X_Channel, + Y_Channel, PS_Config_Lmt_FW_Rawdata_P, + PS_Config_Lmt_FW_Rawdata_N); + } + if (nvt_read_CC(RawData_FW_CC) != 0) { + TestResult_FW_CC = 1; + } else { + TestResult_FW_CC = RawDataTest_SinglePoint_Sub( + RawData_FW_CC, RecordResult_FW_CC, X_Channel, Y_Channel, + PS_Config_Lmt_FW_CC_P, PS_Config_Lmt_FW_CC_N); + } + + if ((TestResult_FWMutual == 1) || (TestResult_FW_CC == 1)) { + TestResult_FW_Rawdata = 1; + } else { + if ((TestResult_FWMutual == -1) || (TestResult_FW_CC == -1)) + TestResult_FW_Rawdata = -1; + else + TestResult_FW_Rawdata = 0; + } + + /*---Leave Test Mode--- */ + nvt_change_mode(NORMAL_MODE); + + /*---Noise Test--- */ + if (nvt_read_fw_noise(RawData_Diff) != 0) { + TestResult_Noise = 1; /* 1: ERROR */ + TestResult_FW_DiffMax = 1; + TestResult_FW_DiffMin = 1; + } else { + TestResult_FW_DiffMax = RawDataTest_SinglePoint_Sub( + RawData_Diff_Max, RecordResult_FW_DiffMax, X_Channel, + Y_Channel, PS_Config_Lmt_FW_Diff_P, + PS_Config_Lmt_FW_Diff_N); + + TestResult_FW_DiffMin = RawDataTest_SinglePoint_Sub( + RawData_Diff_Min, RecordResult_FW_DiffMin, X_Channel, + Y_Channel, PS_Config_Lmt_FW_Diff_P, + PS_Config_Lmt_FW_Diff_N); + + if ((TestResult_FW_DiffMax == -1) || + (TestResult_FW_DiffMin == -1)) + TestResult_Noise = -1; + else + TestResult_Noise = 0; + } + + /* --Short Test--- */ + if (nvt_read_fw_short(RawData_Short) != 0) { + TestResult_Short = 1; // 1:ERROR */ + } else { + /* ---Self Test Check --- 0:PASS, -1:FAIL */ + TestResult_Short = RawDataTest_SinglePoint_Sub( + RawData_Short, RecordResult_Short, X_Channel, Y_Channel, + PS_Config_Lmt_Short_Rawdata_P, + PS_Config_Lmt_Short_Rawdata_N); + } + + /*---Open Test--- */ + if (nvt_read_fw_open(RawData_Open) != 0) { + TestResult_Open = 1; /* 1:ERROR */ + } else { + /*---Self Test Check --- 0:PASS, -1:FAIL */ + TestResult_Open = RawDataTest_SinglePoint_Sub( + RawData_Open, RecordResult_Open, X_Channel, Y_Channel, + PS_Config_Lmt_Open_Rawdata_P, + PS_Config_Lmt_Open_Rawdata_N); + } + + /* ---Download Normal FW--- */ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_FW_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + + mutex_unlock(&ts->lock); + + NVT_LOG("%s --\n", __func__); + + nvt_mp_test_result_printed = 0; + + return seq_open(file, &nvt_selftest_seq_ops); +} + +static const struct file_operations nvt_selftest_fops = { + .owner = THIS_MODULE, + .open = nvt_selftest_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +#ifdef CONFIG_OF +/******************************************************* +Description: + Novatek touchscreen parse AIN setting for array type. + +return: + n.a. +*******************************************************/ +int32_t nvt_mp_parse_ain(struct device_node *np, const char *name, + uint8_t *array, int32_t size) +{ + struct property *data; + int32_t len, ret; + int32_t tmp[40]; + int32_t i; + + data = of_find_property(np, name, &len); + len /= sizeof(u32); + if ((!data) || (!len) || (len != size)) { + NVT_ERR("error find %s. len=%d\n", name, len); + return -1; + } else { + NVT_LOG("%s. len=%d\n", name, len); + ret = of_property_read_u32_array(np, name, tmp, len); + if (ret) { + NVT_ERR("error reading %s. ret=%d\n", name, ret); + return -1; + } + + for (i = 0; i < len; i++) + array[i] = tmp[i]; + + NVT_LOG("[NVT-ts] %s = ", name); + nvt_print_result_log_in_one_line(array, len); + NVT_LOG("\n"); + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen parse criterion for u32 type. + +return: + n.a. +*******************************************************/ +int32_t nvt_mp_parse_u32(struct device_node *np, const char *name, + int32_t *para) +{ + int32_t ret; + + ret = of_property_read_u32(np, name, para); + if (ret) { + NVT_ERR("error reading %s. ret=%d\n", name, ret); + return -1; + } else { + NVT_LOG("%s=%d\n", name, *para); + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen parse criterion for array type. + +return: + n.a. +*******************************************************/ +int32_t nvt_mp_parse_array(struct device_node *np, const char *name, + int32_t *array, int32_t size) +{ + struct property *data; + int32_t len, ret; + int32_t j = 0; + + data = of_find_property(np, name, &len); + len /= sizeof(u32); + if ((!data) || (!len) || (len < size)) { + NVT_ERR("error find %s. len=%d\n", name, len); + return -1; + } else { + NVT_LOG("%s. len=%d\n", name, len); + ret = of_property_read_u32_array(np, name, array, len); + if (ret) { + NVT_ERR("error reading %s. ret=%d\n", name, ret); + return -1; + } + + NVT_LOG("%s =\n", name); + for (j = 0; j < Y_Channel; j++) { + nvt_print_data_log_in_one_line(array + j * X_Channel, + X_Channel); + NVT_LOG("\n"); + } + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen parse device tree mp function. + +return: + n.a. +*******************************************************/ +int32_t nvt_mp_parse_dt(struct device_node *root, const char *node_compatible) +{ + struct device_node *np = root; + struct device_node *child = NULL; + + NVT_LOG("Parse mp criteria for node %s\n", node_compatible); + + /* find each MP sub-nodes */ + for_each_child_of_node(root, child) { + /* find the specified node */ + if (of_device_is_compatible(child, node_compatible)) { + NVT_LOG("found child node %s\n", node_compatible); + np = child; + break; + } + } + if (child == NULL) { + NVT_ERR("Not found compatible node %s!\n", node_compatible); + return -1; + } + + /* MP Config*/ + if (nvt_mp_parse_u32(np, "IC_X_CFG_SIZE", &IC_X_CFG_SIZE)) + return -1; + + if (nvt_mp_parse_u32(np, "IC_Y_CFG_SIZE", &IC_Y_CFG_SIZE)) + return -1; + + if (nvt_mp_parse_u32(np, "X_Channel", &X_Channel)) + return -1; + + if (nvt_mp_parse_u32(np, "Y_Channel", &Y_Channel)) + return -1; + + if (nvt_mp_parse_ain(np, "AIN_X", AIN_X, IC_X_CFG_SIZE)) + return -1; + + if (nvt_mp_parse_ain(np, "AIN_Y", AIN_Y, IC_Y_CFG_SIZE)) + return -1; + + /* MP Criteria */ + if (nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Rawdata_P", + PS_Config_Lmt_Short_Rawdata_P, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Rawdata_N", + PS_Config_Lmt_Short_Rawdata_N, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_Open_Rawdata_P", + PS_Config_Lmt_Open_Rawdata_P, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_Open_Rawdata_N", + PS_Config_Lmt_Open_Rawdata_N, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Rawdata_P", + PS_Config_Lmt_FW_Rawdata_P, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Rawdata_N", + PS_Config_Lmt_FW_Rawdata_N, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_P", + PS_Config_Lmt_FW_CC_P, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_N", + PS_Config_Lmt_FW_CC_N, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Diff_P", + PS_Config_Lmt_FW_Diff_P, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Diff_N", + PS_Config_Lmt_FW_Diff_N, + X_Channel * Y_Channel + Key_Channel)) + return -1; + + if (nvt_mp_parse_u32(np, "PS_Config_Diff_Test_Frame", + &PS_Config_Diff_Test_Frame)) + return -1; + + NVT_LOG("Parse mp criteria done!\n"); + + return 0; +} +#endif /* #ifdef CONFIG_OF */ + +static int nvt_short_test(void) +{ + struct device_node *np = ts->client->dev.of_node; + unsigned char mpcriteria[32] = { 0 }; +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + char mp_setting_criteria_csv_filename[64] = { 0 }; +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + + TestResult_Short = 0; + + NVT_LOG("%s ++\n", __func__); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_MP_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->mp_name); + } + } else { + nvt_update_firmware(ts->mp_name); + } + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + NVT_ERR("get fw info failed!\n"); + return -EAGAIN; + } + fw_ver = ts->fw_ver; +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + /* ---Check if MP Setting Criteria CSV file exist and load--- */ + snprintf(mp_setting_criteria_csv_filename, PAGE_SIZE, + "NT36xxx_MP_Setting_Criteria_%04X.csv", ts->nvt_pid); + NVT_LOG("MP setting criteria csv filename: %s\n", + mp_setting_criteria_csv_filename); + if (nvt_load_mp_setting_criteria_from_csv( + mp_setting_criteria_csv_filename) < 0) { + NVT_ERR("SelfTest MP setting criteria CSV file not exist or load failed\n"); +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + /* Parsing criteria from dts */ + if (of_property_read_bool(np, "novatek,mp-support-dt")) { + /* + * Parsing Criteria by Novatek PID + * The string rule is "novatek-mp-criteria-" + * nvt_pid is 2 bytes (show hex). + * + * Ex. nvt_pid = 500A + * mpcriteria = "novatek-mp-criteria-500A" + */ + snprintf(mpcriteria, PAGE_SIZE, + "novatek-mp-criteria-%04X", ts->nvt_pid); + + if (nvt_mp_parse_dt(np, mpcriteria)) { + /* ---Download Normal FW--- */ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware( + DEFAULT_DEBUG_FW_NAME) < + 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware( + ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + mutex_unlock(&ts->lock); + NVT_ERR("mp parse device tree failed!\n"); + return -EINVAL; + } + } else { + NVT_LOG("Not found novatek,mp-support-dt, use default setting\n"); + /* ---Print Test Criteria--- */ + nvt_print_criteria(); + } +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + } else { + NVT_LOG("SelfTest MP setting criteria loaded from CSV file\n"); + } +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + + if (nvt_switch_FreqHopEnDis(FREQ_HOP_DISABLE)) { + mutex_unlock(&ts->lock); + NVT_ERR("switch frequency hopping disable failed!\n"); + return -EAGAIN; + } + + if (nvt_check_fw_reset_state(RESET_STATE_NORMAL_RUN)) { + mutex_unlock(&ts->lock); + NVT_ERR("check fw reset state failed!\n"); + return -EAGAIN; + } + + msleep(100); + + /* --Short Test--- */ + if (nvt_read_fw_short(RawData_Short) != 0) { + TestResult_Short = 1; /* 1:ERROR */ + } else { + /* ---Self Test Check --- 0:PASS, -1:FAIL */ + TestResult_Short = RawDataTest_SinglePoint_Sub( + RawData_Short, RecordResult_Short, X_Channel, Y_Channel, + PS_Config_Lmt_Short_Rawdata_P, + PS_Config_Lmt_Short_Rawdata_N); + } + + /* ---Download Normal FW--- */ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_FW_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + + mutex_unlock(&ts->lock); + + NVT_LOG("%s --\n", __func__); + + nvt_mp_test_result_printed = 0; + return TestResult_Short; +} + +static int nvt_open_test(void) +{ + struct device_node *np = ts->client->dev.of_node; + unsigned char mpcriteria[32] = { 0 }; +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + char mp_setting_criteria_csv_filename[64] = { 0 }; +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + + TestResult_Open = 0; + + NVT_LOG("%s ++\n", __func__); + + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } + +#if NVT_TOUCH_ESD_PROTECT + nvt_esd_check_enable(false); +#endif /* #if NVT_TOUCH_ESD_PROTECT */ + + /* ---Download MP FW--- */ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_MP_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->mp_name); + } + } else { + nvt_update_firmware(ts->mp_name); + } + + if (nvt_get_fw_info()) { + mutex_unlock(&ts->lock); + NVT_ERR("get fw info failed!\n"); + return -EAGAIN; + } + fw_ver = ts->fw_ver; +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + /* ---Check if MP Setting Criteria CSV file exist and load--- */ + snprintf(mp_setting_criteria_csv_filename, PAGE_SIZE, + "NT36xxx_MP_Setting_Criteria_%04X.csv", ts->nvt_pid); + NVT_LOG("MP setting criteria csv filename: %s\n", + mp_setting_criteria_csv_filename); + if (nvt_load_mp_setting_criteria_from_csv( + mp_setting_criteria_csv_filename) < 0) { + NVT_ERR("SelfTest MP setting criteria CSV file not exist or load failed\n"); +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + /* Parsing criteria from dts */ + if (of_property_read_bool(np, "novatek,mp-support-dt")) { + /* + * Parsing Criteria by Novatek PID + * The string rule is "novatek-mp-criteria-" + * nvt_pid is 2 bytes (show hex). + * + * Ex. nvt_pid = 500A + * mpcriteria = "novatek-mp-criteria-500A" + */ + snprintf(mpcriteria, PAGE_SIZE, + "novatek-mp-criteria-%04X", ts->nvt_pid); + + if (nvt_mp_parse_dt(np, mpcriteria)) { + /* ---Download Normal FW--- */ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware( + DEFAULT_DEBUG_FW_NAME) < + 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware( + ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + mutex_unlock(&ts->lock); + NVT_ERR("mp parse device tree failed!\n"); + return -EINVAL; + } + } else { + NVT_LOG("Not found novatek,mp-support-dt, use default setting\n"); + /* ---Print Test Criteria--- */ + nvt_print_criteria(); + } +#if NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV + } else { + NVT_LOG("SelfTest MP setting criteria loaded from CSV file\n"); + } +#endif /* NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV */ + + if (nvt_switch_FreqHopEnDis(FREQ_HOP_DISABLE)) { + mutex_unlock(&ts->lock); + NVT_ERR("switch frequency hopping disable failed!\n"); + return -EAGAIN; + } + + if (nvt_check_fw_reset_state(RESET_STATE_NORMAL_RUN)) { + mutex_unlock(&ts->lock); + NVT_ERR("check fw reset state failed!\n"); + return -EAGAIN; + } + + msleep(100); + + /*---Open Test--- */ + if (nvt_read_fw_open(RawData_Open) != 0) { + TestResult_Open = 1; /* 1:ERROR */ + } else { + /* ---Self Test Check --- 0:PASS, -1:FAIL */ + TestResult_Open = RawDataTest_SinglePoint_Sub( + RawData_Open, RecordResult_Open, X_Channel, Y_Channel, + PS_Config_Lmt_Open_Rawdata_P, + PS_Config_Lmt_Open_Rawdata_N); + } + + /* ---Download Normal FW--- */ + if (nvt_get_dbgfw_status()) { + if (nvt_update_firmware(DEFAULT_DEBUG_FW_NAME) < 0) { + NVT_ERR("use built-in fw"); + nvt_update_firmware(ts->fw_name); + } + } else { + nvt_update_firmware(ts->fw_name); + } + + mutex_unlock(&ts->lock); + + NVT_LOG("%s --\n", __func__); + + nvt_mp_test_result_printed = 0; + + return TestResult_Open; +} + +static ssize_t nvt_selftest_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + char tmp[5] = { 0 }; + int cnt; + + if (*pos != 0) + return 0; + cnt = snprintf(tmp, sizeof(ts->result_type), "%d\n", ts->result_type); + if (copy_to_user(buf, tmp, strlen(tmp))) { + return -EFAULT; + } + + *pos += cnt; + return cnt; +} + +static ssize_t nvt_selftest_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + int retval = 0; + char tmp[6]; + + if (copy_from_user(tmp, buf, count)) { + retval = -EFAULT; + goto out; + } + + if (!strncmp("short", tmp, 5)) { + retval = nvt_short_test(); + } else if (!strncmp("open", tmp, 4)) { + retval = nvt_open_test(); + } else if (!strncmp("i2c", tmp, 3)) { + retval = nvt_get_fw_info(); + } else { + NVT_ERR("[%s] cmd not support", tmp); + retval = -EINVAL; + } + + switch (retval) { + case 0: + ts->result_type = NVT_RESULT_PASS; + break; + case -EINVAL: + ts->result_type = NVT_RESULT_INVALID; + break; + default: + ts->result_type = NVT_RESULT_FAIL; + break; + } + +out: + if (retval >= 0) + retval = count; + + return retval; +} + +static const struct file_operations nvt_aftersales_test_ops = { + .read = nvt_selftest_read, + .write = nvt_selftest_write, +}; + +/******************************************************* +Description: + Novatek touchscreen MP function proc. file node + initial function. + +return: + Executive outcomes. 0---succeed. -1---failed. +*******************************************************/ +int32_t nvt_mp_proc_init(void) +{ + NVT_proc_selftest_entry = + proc_create("nvt_selftest", 0444, NULL, &nvt_selftest_fops); + if (NVT_proc_selftest_entry == NULL) { + NVT_ERR("create /proc/nvt_selftest Failed!\n"); + return -1; + } else { + if (nvt_mp_buffer_init()) { + NVT_ERR("Allocate mp memory failed\n"); + return -1; + } else { + NVT_LOG("create /proc/nvt_selftest Succeeded!\n"); + } + } + + NVT_proc_aftersales_test_entry = proc_create("tp_selftest", 0644, NULL, + &nvt_aftersales_test_ops); + if (NVT_proc_aftersales_test_entry == NULL) { + NVT_ERR("create /proc/tp_selftest Failed!\n"); + return -1; + } else { + NVT_LOG("create /proc/tp_selftest Succeeded!\n"); + } + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen MP function proc. file node + deinitial function. + +return: + n.a. +*******************************************************/ +void nvt_mp_proc_deinit(void) +{ + nvt_mp_buffer_deinit(); + + if (NVT_proc_selftest_entry != NULL) { + remove_proc_entry("nvt_selftest", NULL); + NVT_proc_selftest_entry = NULL; + NVT_LOG("Removed /proc/%s\n", "nvt_selftest"); + } +} + +#ifndef NVT_SAVE_TESTDATA_IN_FILE +static void test_buff_free(struct test_buf *buf) +{ + if (buf) { + if (buf->shorttest.buf) + kfree(buf->shorttest.buf); + if (buf->opentest.buf) + kfree(buf->opentest.buf); + if (buf->fwmutualtest.buf) + kfree(buf->fwmutualtest.buf); + if (buf->fwcctest.buf) + kfree(buf->fwcctest.buf); + if (buf->noisetest_max.buf) + kfree(buf->noisetest_max.buf); + if (buf->noisetest_min.buf) + kfree(buf->noisetest_min.buf); + kfree(buf); + } + return; +} + +static int32_t test_buff_init(struct test_buf **tbuf) +{ + struct test_buf *buf; + int32_t ret; + + buf = (struct test_buf *)kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf); + goto alloc_fail; + } + + buf->shorttest.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->shorttest.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->shorttest.buf); + goto alloc_fail; + } + + buf->opentest.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->opentest.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->opentest.buf); + goto alloc_fail; + } + + buf->fwmutualtest.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->fwmutualtest.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->fwmutualtest.buf); + goto alloc_fail; + } + + buf->fwcctest.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->fwcctest.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->fwcctest.buf); + goto alloc_fail; + } + + buf->noisetest_max.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->noisetest_max.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->noisetest_max.buf); + goto alloc_fail; + } + + buf->noisetest_min.buf = kzalloc(TEST_BUF_LEN, GFP_KERNEL); + if (!buf->noisetest_min.buf) { + NVT_ERR("alloc memory failed"); + ret = PTR_ERR(buf->noisetest_min.buf); + goto alloc_fail; + } + + buf->shorttest.type = SHORT_TEST; + buf->opentest.type = OPEN_TEST; + buf->fwmutualtest.type = FWMUTUAL_TEST; + buf->fwcctest.type = FWCC_TEST; + buf->noisetest_max.type = NOISE_MAX_TEST; + buf->noisetest_min.type = NOISE_MIN_TEST; + + *tbuf = buf; + return ret; + +alloc_fail: + *tbuf = NULL; + test_buff_free(buf); + return ret; +} + +struct item_buf *item_arr[MAX_TEST_TYPE]; + +static void *t_start(struct seq_file *m, loff_t *pos) +{ + struct test_buf *tbuf = ts->testdata; + + item_arr[SHORT_TEST] = &tbuf->shorttest; + item_arr[OPEN_TEST] = &tbuf->opentest; + item_arr[FWMUTUAL_TEST] = &tbuf->fwmutualtest; + item_arr[FWCC_TEST] = &tbuf->fwcctest; + item_arr[NOISE_MAX_TEST] = &tbuf->noisetest_max; + item_arr[NOISE_MIN_TEST] = &tbuf->noisetest_min; + + if (*pos >= MAX_TEST_TYPE) { + /* *pos = 0; */ + return NULL; + } + + NVT_LOG("In start\n"); + NVT_LOG("=short= item ptr (%p), type (%d), buf ptr(%p)\n", + &tbuf->shorttest, tbuf->shorttest.type, tbuf->shorttest.buf); + NVT_LOG("=open= item ptr (%p), type (%d), buf ptr(%p)\n", + &tbuf->opentest, tbuf->opentest.type, tbuf->opentest.buf); + NVT_LOG("pos (%lld), first item ptr(%p)", *pos, item_arr[*pos]); + return item_arr[*pos]; +} + +static void *t_next(struct seq_file *m, void *v, loff_t *pos) +{ + NVT_LOG("In next\n"); + NVT_LOG("ptr v (%p), pos (%lld), item ptr (%p)\n", v, *pos, + &item_arr[*pos]); + + ++*pos; + if (*pos >= MAX_TEST_TYPE) { + /* *pos = 0; */ + return NULL; + } + + NVT_LOG("ptr v (%p), pos (%lld), item ptr (%p)\n", v, *pos, + &item_arr[*pos]); + return item_arr[*pos]; +} + +static int32_t t_show(struct seq_file *m, void *v) +{ + int i, j; + struct item_buf *item = v; + int32_t *data = (int32_t *)item->buf; + + NVT_LOG("In show\n"); + NVT_LOG("item ptr (%p), type (%d), buf ptr(%p)\n", item, item->type, + item->buf); + + switch (item->type) { + case SHORT_TEST: + seq_printf(m, "========SHORT_TEST========\n"); + break; + case OPEN_TEST: + seq_printf(m, "========OPEN_TEST========\n"); + break; + case FWMUTUAL_TEST: + seq_printf(m, "========FWMUTUAL_TEST========\n"); + break; + case FWCC_TEST: + seq_printf(m, "========FWCC_TEST========\n"); + break; + case NOISE_MAX_TEST: + seq_printf(m, "========NOISE_MAX_TEST========\n"); + break; + case NOISE_MIN_TEST: + seq_printf(m, "========NOISE_MIN_TEST========\n"); + break; + default: + NVT_LOG("test type illegal (%d)\n", item->type); + return -EINVAL; + } + + for (i = 0; i < Y_Channel; i++) { + for (j = 0; j < X_Channel; j++) { + seq_printf(m, "%5d, ", data[i * X_Channel + j]); + } + seq_puts(m, "\n"); + } + seq_puts(m, "\n\n"); + + return 0; +} + +static void t_stop(struct seq_file *m, void *v) +{ + NVT_LOG("In stop\n"); + return; +} + +const struct seq_operations t_fops = { + .start = t_start, + .next = t_next, + .stop = t_stop, + .show = t_show, +}; + +static int32_t nvt_test_data_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &t_fops); +} + +static const struct file_operations nvt_test_data_fops = { + .owner = THIS_MODULE, + .open = nvt_test_data_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +int32_t nvt_test_data_proc_init(struct spi_device *client) +{ + int ret; + struct test_buf *tbuf; + struct nvt_ts_data *ts = spi_get_drvdata(client); + + NVT_proc_test_data_entry = + proc_create("nvt_test_data", 0, NULL, &nvt_test_data_fops); + if (NVT_proc_test_data_entry == NULL) { + NVT_ERR("create proc/nvt_test_data Failed!"); + return -ENOMEM; + } else { + NVT_LOG("create proc/nvt_test_data Succeeded!"); + } + + ret = test_buff_init(&tbuf); + if (!tbuf) { + NVT_ERR("test buff init failed"); + remove_proc_entry("nvt_test_data", NULL); + return ret; + } + + ts->testdata = tbuf; + + return 0; +} + +void nvt_test_data_proc_deinit(void) +{ + test_buff_free(ts->testdata); + ts->testdata = NULL; + + if (NVT_proc_test_data_entry != NULL) { + remove_proc_entry("nvt_test_data", NULL); + NVT_proc_test_data_entry = NULL; + NVT_LOG("Removed /proc/nvt_test_data"); + } +} +#endif /*ifndef NVT_SAVE_TESTDATA_IN_FILE*/ +#endif /* #if NVT_TOUCH_MP */ diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mp_ctrlram.h b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mp_ctrlram.h new file mode 100644 index 000000000000..f42c64546aa2 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mp_ctrlram.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2010 - 2018 Novatek, Inc. + * + * $Revision: 32206 $ + * $Date: 2018-08-10 19:23:04 +0800 (週五, 10 八月 2018) $ + * + * 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. + * + */ + +#if NVT_TOUCH_MP + +extern uint32_t IC_X_CFG_SIZE; +extern uint32_t IC_Y_CFG_SIZE; +extern uint32_t IC_KEY_CFG_SIZE; +extern uint32_t X_Channel; +extern uint32_t Y_Channel; +extern uint32_t Key_Channel; +extern uint8_t AIN_X[40]; +extern uint8_t AIN_Y[40]; + +extern int32_t PS_Config_Lmt_Short_Rawdata_P[40 * 40]; + +extern int32_t PS_Config_Lmt_Short_Rawdata_N[40 * 40]; + +extern int32_t PS_Config_Lmt_Open_Rawdata_P[40 * 40]; + +extern int32_t PS_Config_Lmt_Open_Rawdata_N[40 * 40]; + +extern int32_t PS_Config_Lmt_FW_Rawdata_P[40 * 40]; + +extern int32_t PS_Config_Lmt_FW_Rawdata_N[40 * 40]; + +extern int32_t PS_Config_Lmt_FW_CC_P[40 * 40]; + +extern int32_t PS_Config_Lmt_FW_CC_N[40 * 40]; + +extern int32_t PS_Config_Lmt_FW_Diff_P[40 * 40]; + +extern int32_t PS_Config_Lmt_FW_Diff_N[40 * 40]; + +extern int32_t PS_Config_Diff_Test_Frame; + +#ifndef NVT_SAVE_TESTDATA_IN_FILE +#define TEST_BUF_LEN 5000 + +enum test_type { + SHORT_TEST = 0, + OPEN_TEST, + FWMUTUAL_TEST, + FWCC_TEST, + NOISE_MAX_TEST, + NOISE_MIN_TEST, + MAX_TEST_TYPE = 6, +}; + +struct item_buf { + uint8_t *buf; + uint32_t len; + enum test_type type; +}; + +struct test_buf { + // spinlock_t tbuf_lock; + // bool update; + struct item_buf shorttest; + struct item_buf opentest; + struct item_buf fwmutualtest; + struct item_buf fwcctest; + struct item_buf noisetest_max; + struct item_buf noisetest_min; +}; + +int32_t nvt_test_data_proc_init(struct spi_device *client); +void nvt_test_data_proc_deinit(void); + +#endif /*#ifndef NVT_SAVE_TESTDATA_IN_FILE*/ + +#endif /* #if NVT_TOUCH_MP */ diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mp_ctrlram_data.c b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mp_ctrlram_data.c new file mode 100644 index 000000000000..ce96954ba111 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx_mp_ctrlram_data.c @@ -0,0 +1,536 @@ +#include "nt36xxx.h" + +#if NVT_TOUCH_MP + +uint32_t IC_X_CFG_SIZE = 18; +uint32_t IC_Y_CFG_SIZE = 36; +uint32_t IC_KEY_CFG_SIZE = 4; +uint32_t X_Channel = 18; +uint32_t Y_Channel = 36; +uint32_t Key_Channel = TOUCH_KEY_NUM; +uint8_t AIN_X[40] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17 }; +uint8_t AIN_Y[40] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 }; + +int32_t PS_Config_Lmt_Short_Rawdata_P[40 * 40] = { + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, + 14008, 14008, 14008, 14008, 14008, 14008, 14008, 14008, +}; + +int32_t PS_Config_Lmt_Short_Rawdata_N[40 * 40] = { + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, +}; + +int32_t PS_Config_Lmt_Open_Rawdata_P[40 * 40] = { + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, +}; + +int32_t PS_Config_Lmt_Open_Rawdata_N[40 * 40] = { + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, +}; + +int32_t PS_Config_Lmt_FW_Rawdata_P[40 * 40] = { + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, +}; + +int32_t PS_Config_Lmt_FW_Rawdata_N[40 * 40] = { + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, +}; + +int32_t PS_Config_Lmt_FW_CC_P[40 * 40] = { + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, +}; + +int32_t PS_Config_Lmt_FW_CC_N[40 * 40] = { + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, +}; + +int32_t PS_Config_Lmt_FW_Diff_P[40 * 40] = { + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, +}; + +int32_t PS_Config_Lmt_FW_Diff_N[40 * 40] = { + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, + +}; + +int32_t PS_Config_Diff_Test_Frame = 50; +#endif /*NVT_TOUCH_MP*/ diff --git a/drivers/input/touchscreen/xiaomi/spi-xiaomi-tp.c b/drivers/input/touchscreen/xiaomi/spi-xiaomi-tp.c new file mode 100644 index 000000000000..3301a6c252b2 --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/spi-xiaomi-tp.c @@ -0,0 +1,196 @@ +#include + +#define DEBUG + +static struct ts_spi_info owner; + +static ssize_t ts_xsfer_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + mutex_lock(&owner.lock); + ret = snprintf(buf, PAGE_SIZE, "[%s] used:%d, tmp:%d\n", owner.name, + owner.used, owner.tmp); + mutex_unlock(&owner.lock); + return ret; +} + +static DEVICE_ATTR(ts_xsfer_state, S_IRUGO, ts_xsfer_state_show, NULL); + +/*tmporary get spi device's ownership until invoke tmp_drop_ts_xsfer() + * + *return -EBUSY others is using, -EPERM if spi device already belong to others. + */ +int32_t tmp_hold_ts_xsfer(struct spi_device **client) +{ + if (!owner.init) { + PDEBUG("ts_xsfer does not exist"); + return -EINVAL; + } + mutex_lock(&owner.lock); + if (owner.used) { + PDEBUG("ts_xsfer belong to %s, can't tmporary use it\n", + owner.name); + mutex_unlock(&owner.lock); + return -EPERM; + } + + if (owner.tmp) { + PDEBUG("ts_xsfer is in using, others can't use it now\n"); + mutex_unlock(&owner.lock); + return -EBUSY; + } + + owner.tmp = true; + *client = owner.client; + mutex_unlock(&owner.lock); + return 0; +} + +EXPORT_SYMBOL_GPL(tmp_hold_ts_xsfer); + +/*must balance with tmp_hold_ts_xsfer*/ +void tmp_drop_ts_xsfer(void) +{ + if (owner.init) { + mutex_lock(&owner.lock); + owner.tmp = false; + mutex_unlock(&owner.lock); + } +} + +EXPORT_SYMBOL_GPL(tmp_drop_ts_xsfer); + +/*make spi device belong to module which invoke this function + *-EPERM if spi device already belong to others. + */ +int32_t get_ts_xsfer(const char *name) +{ + if (!name) { + PDEBUG("name can't be empty\n"); + return -EINVAL; + } + mutex_lock(&owner.lock); + if (owner.used) { + PDEBUG("ts_xsfer belong to %s, others can't get it\n", + owner.name); + mutex_unlock(&owner.lock); + return -EPERM; + } + owner.used = true; + strlcpy(owner.name, name, NAME_MAX_LENS); + mutex_unlock(&owner.lock); + return 0; +} + +EXPORT_SYMBOL_GPL(get_ts_xsfer); + +void put_ts_xsfer(const char *name) +{ + if (name && !strncmp(name, owner.name, NAME_MAX_LENS)) { + mutex_lock(&owner.lock); + owner.used = false; + owner.name[0] = '\0'; + mutex_unlock(&owner.lock); + } else { + PDEBUG("must released by owner\n"); + } +} + +EXPORT_SYMBOL_GPL(put_ts_xsfer); + +const char *get_owner_name(void) +{ + if (owner.name[0] == '\0') + return NULL; + return owner.name; +} + +EXPORT_SYMBOL_GPL(get_owner_name); + +/*test weather spi device belong someone, if not get the device's ownership. + *name@:name of owner + *return NULL if device already been used. + */ +struct spi_device *test_then_get_spi(const char *name) +{ + struct spi_device *ret; + + mutex_lock(&owner.lock); + if (owner.used) { + ret = NULL; + } else { + owner.used = true; + ret = owner.client; + if (name) + strlcpy(owner.name, name, NAME_MAX_LENS); + } + mutex_unlock(&owner.lock); + + return ret; +} + +EXPORT_SYMBOL_GPL(test_then_get_spi); + +static int32_t ts_spi_probe(struct spi_device *client) +{ + int32_t ret; + PDEBUG("Start probe\n"); + mutex_init(&owner.lock); + owner.name[0] = '\0'; + owner.used = false; + owner.tmp = false; + owner.client = client; + + ret = sysfs_create_file(&client->dev.kobj, + &dev_attr_ts_xsfer_state.attr); + if (ret < 0) { + PDEBUG("create sysfs failed\n"); + } + + owner.init = true; + PDEBUG("init ts_xsfer device successful\n"); + + return 0; +} + +static int32_t ts_spi_remove(struct spi_device *client) +{ + PDEBUG("touch_xsfer will be remove, touch must stop spi xsfer\n"); + sysfs_remove_file(&client->dev.kobj, &dev_attr_ts_xsfer_state.attr); + return 0; +} + +static struct of_device_id ts_match_tbl[] = { + { + .compatible = "xiaomi,spi-for-tp", + }, + {}, +}; + +static struct spi_driver touch_spi_drv = { + .probe = ts_spi_probe, + .remove = ts_spi_remove, + .driver = { + .name = "touch_xsfer", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(ts_match_tbl), + }, +}; + +static int32_t __init touch_spi_init(void) +{ + PDEBUG("Start register spi for tp\n"); + return spi_register_driver(&touch_spi_drv); +} + +static void __exit touch_spi_exit(void) +{ + spi_unregister_driver(&touch_spi_drv); +} + +module_init(touch_spi_init); +module_exit(touch_spi_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("XIAOMI,JIANGHAO"); diff --git a/drivers/input/touchscreen/xiaomi/spi-xiaomi-tp.h b/drivers/input/touchscreen/xiaomi/spi-xiaomi-tp.h new file mode 100644 index 000000000000..1de8d7b4f52b --- /dev/null +++ b/drivers/input/touchscreen/xiaomi/spi-xiaomi-tp.h @@ -0,0 +1,52 @@ +#ifndef _SPI_XIAOMI_TP_H +#define _SPI_XIAOMI_TP_H + +#include +#include +#include +#include +#include + +#define TP_SPI_DEBUG + +#define TP_TAG "[TP_SPI]: " + +#undef PDEBUG +#ifdef TP_SPI_DEBUG +#ifdef __KERNEL__ +#define PDEBUG(fmt, args...) printk(KERN_ERR TP_TAG fmt, ##args) +#else /*NO __KERNEL__*/ +#define PDEBUG(fmt, args...) fprintf(stderr, TP_TAG fmt, ##args) +#endif /*END __KERNEL__*/ +#else /*NO TP_SPI_DEBUG*/ +#define PDEBUG(fmt, args...) +#endif /*END TP_SPI_DEBUG*/ + +#undef PDEBUGG +#define PDEBUGG(fmt, args...) +#define NAME_MAX_LENS 32 + +/*lock@:protect this struct + *name@:indicate who own this device + *used@:indicate this device has it owner + *tmp@:device in using but don't has it owner + *init&:indicate ts_xsfer already init. + *client@:pointer to spi device + */ +struct ts_spi_info { + struct mutex lock; + char name[NAME_MAX_LENS]; + bool used; + bool tmp; + bool init; + struct spi_device *client; +}; + +extern int32_t tmp_hold_ts_xsfer(struct spi_device **client); +extern void tmp_drop_ts_xsfer(void); +extern int32_t get_ts_xsfer(const char *name); +extern void put_ts_xsfer(const char *name); +extern const char *get_owner_name(void); +extern struct spi_device *test_then_get_spi(const char *name); + +#endif /*_SPI_XIAOMI_TP_H*/ diff --git a/firmware/Makefile b/firmware/Makefile index 96b4a8b0a63b..dc3996547019 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -20,6 +20,18 @@ fw-external-y := $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE)) # For the former two cases we want $(fw-shipped-y) and $(fw-shipped-m) to be # accurate. In the latter case it doesn't matter -- it'll use $(fw-shipped-all). # But be aware that the config file might not be included at all. +fw-shipped-$(CONFIG_TOUCHSCREEN_GOODIX_GTX8) += goodix_gt9886_cfg_f11.bin goodix_gt9886_fw_f11.bin +fw-shipped-$(CONFIG_TOUCHSCREEN_ST_FTS_V521) += st_fts_f1.ftb st_fts.ftb st_fts_e5.ftb st_fts_f1x.ftb +fw-shipped-$(CONFIG_TOUCHSCREEN_ST_FTS_V59y) += st_fts_j2a.ftb st_fts_j2a_sdc.ftb st_fts_j2a_csot.ftb +fw-shipped-$(CONFIG_INPUT_PRESS_NDT) += ndt_fw.bin +fw-shipped-$(CONFIG_TOUCHSCREEN_NT36XX) += novatek_nt36672_f10.fw +fw-shipped-$(CONFIG_TOUCHSCREEN_NT36xxx_HOSTDL_SPI) += j20s_novatek_ts_fw01.bin +fw-shipped-$(CONFIG_TOUCHSCREEN_NT36xxx_HOSTDL_SPI) += j20s_novatek_ts_mp01.bin +fw-shipped-$(CONFIG_TOUCHSCREEN_NT36xxx_HOSTDL_SPI) += j20s_novatek_ts_fw02.bin +fw-shipped-$(CONFIG_TOUCHSCREEN_NT36xxx_HOSTDL_SPI) += j20s_novatek_ts_mp02.bin +fw-shipped-$(CONFIG_TOUCHSCREEN_NT36523_HOSTDL_SPI) += novatek_ts_fw.bin novatek_ts_mp.bin +fw-shipped-$(CONFIG_TOUCHSCREEN_NT36523_HOSTDL_SPI) += novatek_nt36523_fw01.bin novatek_nt36523_mp01.bin +fw-shipped-$(CONFIG_TOUCHSCREEN_NT36523_HOSTDL_SPI) += novatek_nt36523_fw02.bin novatek_nt36523_mp02.bin fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) diff --git a/firmware/goodix_gt9886_cfg_f11.bin.ihex b/firmware/goodix_gt9886_cfg_f11.bin.ihex new file mode 100755 index 000000000000..d15385aa4983 --- /dev/null +++ b/firmware/goodix_gt9886_cfg_f11.bin.ihex @@ -0,0 +1,116 @@ +:10000000260700005D000000000200000000000064 +:1000100014009D03890300006E6F726D616E647938 +:1000200000000000000000010139383836000000EF +:1000300000000000000000000000000000000000C0 +:100040000000000000000000000000004245040025 +:100050002C454800354504003D45040041450F004E +:100060000000000000000000786F0000F330000086 +:10007000686F000000410000000000000000000068 +:10008000000000000000000000000000001E012C25 +:10009000B5011F34F188821E200401210117DE08FA +:1000A000070400000F210000320000222112003F4F +:1000B000FFFF50025828244A270049030102040682 +:1000C00007080B090C0D1817191A1C1D1F212223D4 +:1000D000201E1B0A054BFFFFFF32343337364039F1 +:1000E0003E3A383F353B3C41FFFFFFFFFFFFFFFF3C +:1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:10010000FF00000000000000000000000042035853 +:100110000D11130E23142022211F1D1C1B181A174A +:10012000160B0C0A09070604020100030508191E34 +:1001300012FFFFFF1E1C1D191A0217121618031BAF +:10014000151401FFFFFFFFFFFFFFFFFFFFFFFFFF92 +:10015000FFFFFFFFFFFFFFFFFFFFFFFF00000000AB +:10016000000000000000000054040901020105190C +:100170002D17DE00AF050A04380924003C005A0A96 +:100180000FD906020100F7071414161A20141A22B8 +:10019000161A20161A20000047080C0C151508081E +:1001A0000040008000C002026C090919000A000A20 +:1001B000000B000AAC0A131F0503002808007894FE +:1001C0008C8783807E1D202326293D0B020A05E4AF +:1001D0000C050800000000E70D0D4138A50BB80D17 +:1001E0002D043C001E0028450E0C030A010EB43CF1 +:1001F000AA0000003250AE0F00F11000F0110B0009 +:100200000100208D4E2064230000411207000000F1 +:1002100001010000E51308025800C8000F0000B4F7 +:100220001400EC1525000000040050010502001C1C +:100230000002004000040000000505050800010060 +:100240003A984E201432000000006A160B15206404 +:100250000BB800A0006400007F1700E9180C013201 +:10026000001900781A1F252B00008F1911010A149C +:10027000501E040A321507000A2222360000691AAD +:100280005E00040335033513B1022403350335132F +:10029000B101351FFF1FFF1FFF000000000000001D +:1002A00000020406070B18262E020406070B182668 +:1002B0002E285A145A1402C832066464005A0800E0 +:1002C00064A8025FFE0B3C1E3C3203E814000000F1 +:1002D0000070000000004000000000000000003539 +:1002E0001B00E51C0F0A0410001E001E02C0000FB8 +:1002F00000C80000E21D00E31E00E21F00E1200430 +:100300000000C8789C210A01004000010060010043 +:100310000032221322053900000000000000000016 +:10032000000000000000006B230400002000B9243E +:1003300000DC252007000C5C11A436763BD3061B9D +:10034000336300157C00002D876B0F964035005AF3 +:10035000004B32186D260427000000AF2700D92873 +:1003600000D82900D72A00D62B00D52C2F01928740 +:100370008887888787898685878484858584848320 +:100380008281807F7D7D7B7B77767472706C6C0060 +:1003900000000000000000000000000021890300B0 +:1003A000006E6F726D616E647900000000000000E5 +:1003B000010039383836000000000000000000005D +:1003C000000000000000000000000000000000002D +:1003D0000000000000424504002C4548003545045B +:1003E000003D45040041450F0000000000000000F2 +:1003F00000786F0000F3300000686F0000004100DB +:1004000000000000000000000000000000000000EC +:100410000000000000001E012CB5011F34F188828D +:1004200026280401210117DE08070400000F21001F +:1004300000320000222112003FFFFF40025820221C +:10044000231E1F211B1C1D0A191A170D180C090B3E +:10045000080705060403020100494B4A274828FF04 +:10046000FFFF2E30312F2D323834333537363B40B5 +:1004700039FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:10048000FFFFFFFFFFFFFFFFFFFF00000000000076 +:100490000000000000006703580301000504020883 +:1004A0000706190A090C160B171A181B1C1E1D1F0C +:1004B000202122231412130E150DFFFFFF22201FEF +:1004C00021231E181C1D1B191A150217FFFFFFFF01 +:1004D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:1004E000FFFFFFFFFF000000000000000000000011 +:1004F00000EB040901020105192D17DE00AF050A02 +:1005000004380924003C005A0A0FD906020100F7FA +:10051000071414161A20141A22161A20161A20006C +:100520000047080C0C151508080040008000C002A8 +:10053000026C09091F000A000A000B000AA60A1330 +:100540001F05030028080078948C8783807D1B1E7C +:10055000212428470B020A05E40C050800000000CE +:10056000E70D0D4138A50BB81321044C001E0028DF +:100570003B0E0C030A010EB43CAA0000003250AE40 +:100580000F00F11000F0110B000100208D4E2064CF +:1005900023000041120700000001010000E51308DC +:1005A000025800C8000F0000B41400EC152500002C +:1005B00000040050010502001C000200400004007D +:1005C0000000050505080001003A984E201432008D +:1005D0000000006A160B1520640BB800A000640030 +:1005E000007F1700E9180C0132001900781B202643 +:1005F0002B00008C1911010A14501E040A32150731 +:10060000000A2222360000691A5E00040335033511 +:1006100013B102240335033513B101351FFF1FFF4A +:100620001FFF0000000000000000020406070B1876 +:10063000262E020406070B18262E285A145A1402D6 +:10064000C832066464005A080064A8025FFE0B3CCE +:100650001E3C3203E814000000007000000000405F +:100660000000000000000000351B00E51C0F0A041C +:1006700010001E001E02C0000F00C80000E21D0096 +:10068000E31E00E21F00E120040000C8789C210A5C +:1006900001004000010060010000322213220636F2 +:1006A000000000000000000000000000000000004A +:1006B0006D230400002000B92400DC252007000C75 +:1006C0005C11A436763BD3061B336300157C000017 +:1006D0002D876B0F964035005A004B32176E26045B +:1006E00027000000AF2700D92800D82900D72A000A +:1006F000D62B00D52C2F01928788878887878986FB +:100700008587848485858484838281807F7D7D7BC9 +:100710007B77767472706C6C000000000000000043 +:06072000000000000021B2 +:00000001FF diff --git a/firmware/goodix_gt9886_fw_f11.bin.ihex b/firmware/goodix_gt9886_fw_f11.bin.ihex new file mode 100755 index 000000000000..0a9a29d8c27c --- /dev/null +++ b/firmware/goodix_gt9886_fw_f11.bin.ihex @@ -0,0 +1,5522 @@ +:10000000000158FA4A4E4E4F525F473100000A39FC +:1000100038383600000000030402290B9302020066 +:10002000010000080000FF00030000200000400065 +:10003000030000200000600003000020000080009A +:10004000030000200000A000030000200000C0000A +:100050000300002000010000030000200001200038 +:1000600003000020000140000300001000016000B8 +:10007000020000400000000000000000000000003E +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:100100003AF34A4C4017BB2B08342315C63DBBD0ED +:1001100070922DE17F66FA8360B260601B4E3BD126 +:10012000B683AC738365940A6906A335AE1484CD97 +:100130007193ADC3E975B92E21CEE07CE72C3A93DB +:1001400016C1E9260615542DD0714CC98064116280 +:100150004DA1132592D5B04002712935C971F063C4 +:1001600061554A4442C7CF26477929D6DD7173606D +:1001700094557B85B1276CF8277C2A57D56072612E +:100180007A8A2C217D6CA32E72486845B4305AC5FA +:1001900032C8D506D2FA518BA148FD42452C2E40DB +:1001A0003BD93B059B2D39D3E854EB6596D6AB6A1A +:1001B0006B79CD86EB7C9926D1D989425B2F10963D +:1001C00071CDF6DC425F442A0A6C62D1C368F96AD9 +:1001D00013B50FB6B27BB82B026DC944B70F496B8C +:1001E000F0508C6A4C4DF96F6DE983BEDF65DCCA57 +:1001F0004BA1E0FAC09B3AF0CF89754BCA6C78C22C +:100200009762A2312F01A30FAB482C8C5036707A25 +:10021000741209469094906E755B21FEC66F7884C7 +:10022000F0E3E1528776A834B92435301327D1138F +:1002300035C1A51C39F70EB21833C813FDD5DDF84A +:100240007AD84A44BC4663DA6E1324FBC5F3D37DE7 +:10025000C923AF18ACF05A3A340832AEA870B7E6EA +:100260003BC743B5FD3AF156930CEAEDA9A35038CC +:10027000B2A3CB477287F0C7250FE5D31DE63A0539 +:100280003ED86817847FBCB32E56C455274EFA71EA +:10029000761A0DAEB66F29921E40401B2D397FDDB8 +:1002A00067AD5E979B21535EE886F0E1074F04F847 +:1002B000771D6DF90C9D528B3D856B52E3CF126B10 +:1002C00038CECB9F391C76E3C59A95F716FAF9011B +:1002D000B5A75E1484366E324C3A80199F07924F50 +:1002E000193A2613A7E9E9332FED17DB8F23DED365 +:1002F0000FAAE171AFF9D032611B89C78174FBD0BD +:100300005825A77F5B21B55FB063BAC6A63ABF3058 +:100310004833898C1C74E6C44A1CF6C7BF6701E8E1 +:10032000DA874C7002867FE02902653D0A968C4D83 +:100330002333268591EC45C12113643A3935938FD7 +:10034000227C08C65424E9E6F3110CAAB541F581D4 +:10035000335278850234E82F6CFEC5CC7A0511EA59 +:10036000437FFDC6C7DA143E1366C586CB8554D7D6 +:10037000B2A281036E05D4A8ED8316C84D0499E896 +:10038000B2E76FA8DC9EE1296AC9CEE18CBE9EE788 +:100390005298297855E0E0B2020AB236B2BAD24495 +:1003A0005B89A83B5CF0692933493BAF8DAA1EEA03 +:1003B00011F90FCA2D4110C9808B3214F9AD2246B4 +:1003C0004C35668E19CC3A36120A6AC33278DFAEE3 +:1003D000EDA953009221DE2702F86ECC551082BFA2 +:1003E0001DCB7B2DDB9FC276130BE643D51CE9ADFD +:1003F0001557C5DF6DDDBB46035AC38E449F64E9C4 +:100400001E71306BFE97081FA052DADFEABF5D5BFA +:100410002A9ECCC1D29194105CD24D5CA04725712C +:10042000DC07609B05779DE155C3C0DD36B79F8231 +:100430008101B59B2E64E13E4531C4D251C4F375B0 +:1004400006C725D41FB975A40AE5C74BB562B2F833 +:10045000F822F6919529C24D026796763CE0FD0997 +:10046000714F249F3162983CC1818E345D4489B6BE +:10047000E5A0B39C9555E6A9BF00A127C2A8F1331A +:10048000DE0EA894F097D7084EA8D803B6DD767E86 +:1004900056BD8EFC55B99C1818CA6B7DC0B715BBEC +:1004A00047EB8C17C7EEBCB73B56EC98B3EFA07781 +:1004B00057BC0E9D2C6CE96659C91204C13B9E04C1 +:1004C00049FB7A33DE1E62BA816ACFDA92D16CBE02 +:1004D0006929773D4D4AE35FF7F7C3D03EE8F55908 +:1004E000E43BA63D77C41DFF7C294F59556C02CCD7 +:1004F0002DA8ED94CC57678D0D37AB7239F9373D88 +:10050000A4EC800DE1A4C69FB886C5674B2CD767C5 +:100510006CDEB24DD00072BD7C0F5303E8EABE23FF +:10052000B5FE86C6BFB6D9A5CE8CC6862197FE2E4F +:1005300079D72B4170FA11A3BBB23D713B5F0E6CB2 +:10054000241FF3F8C04412246E660800D06452647D +:10055000770F05C1C854132560D8E004D8745365DB +:10056000815708FAC145922609658822D165D2666D +:100570006A172149C9559327996749CAD975D3671D +:10058000A0B00ECC33B2A4DFD23E98B33A8EDF4F88 +:100590004FEB138433429A276AE7FE05329F2649C0 +:1005A0006BF908AB2C6245F612EF6A0603A91CE64C +:1005B0005D9162196B22BD976D2AD70F5B2B536D2E +:1005C00036CCCE9FC24C1A2CAD17355CD26C5A6C0F +:1005D0004ADA2B6FCA5C1B2D2A3EE9B3DA7C5B6DCD +:1005E000C35F0940C34D9A2E87EF2C00D36DDA6E9E +:1005F00073897500CB5D9B2FA55D494EDB7DDB6F5D +:100600007C022990E4A12EBBBC02E777361C74B4AF +:10061000741228B158F6701118F7E05FA645D2752C +:100620003D039052E36732338566E2A7FD27C0B2EF +:10063000CD823ABEF5179170BE273DB55DA3967584 +:10064000EF5DD71FC4C43234BC53E713D4E47274D3 +:100650004A54E733CCD433359CE6E919DCF473759E +:10066000388708EDC5C5B236FD429D96D5E5F276D0 +:1006700092C42410CDD5B3372D374916DDF5F37765 +:10068000470A18B8DC899B3E483B6CF383B899D382 +:1006900076BFC816F661477BFD4BB7F244DEFB68B8 +:1006A0007FFAB27F1300DBDB75AD09F5EFAFFCBE5F +:1006B0006FB0EDB62D033B7A78B102CD3B5F7B6A1C +:1006C000EE6AF543C6CC3A3CFE4B15DCD6EC7A7CA0 +:1006D000AED9AE1ACEDC3B3D2E3EC11CDEFC7B7D8E +:1006E000AF6B0E99C7CDBA3E97FF6012D7EDFA7E79 +:1006F0005FD8705ECFDDBB3F06040A90DFFDFB7F55 +:100700007A006C621F5DC57D16AEC89BBC26F51FC6 +:10071000EAE143FF92F497E04832E1460784D04192 +:100720005F9665218A85B08811DE848CABE6F56220 +:100730005B375191340736A53996C5866633D32782 +:1007400000030A0FE04616A4C410E5C2F06656E4A2 +:10075000BDB0AB0EE85617A51852EB4EF87657E52C +:10076000A3A12A0DE14796A661043BC9F167D6E62D +:100770002DB105AFE95797A77D91E31AF977D7E730 +:100780008583DCDA327EFDA7C42A62C8D6AC55E880 +:10079000249804E96A08E15281BE89D4653A5B2D48 +:1007A0000486AE8AC32BC9A59B89CC348B9D144A81 +:1007B0001399BDEB829B59A2D24C52A698F977A906 +:1007C000E0DAADE9E24E1EAC386FCC8DF26E5EEC35 +:1007D00030DBACCCEA5E1FAD02F86BC4FA7E5FED95 +:1007E000394F2DEBE34F9EAEEB896233F36FDEEEB4 +:1007F000B4FF5A72EB5F9FAF43896C8EFB7FDFEFD4 +:10080000E560883D2BF497F14A948F3590567CFF34 +:10081000127E036D4425B0F60EF4F76C846682FEFA +:10082000E061A236061368506B90F07D2525C492D6 +:1008300094CCB36E0534CAB596C930C885E7FDFCC3 +:1008400004E2CA99E4C636B41D190DF0F4E676F454 +:100850005495F1F9ECD637B504D543D5FCF677F5C8 +:100860009E418673E5C7B6B665E766D6F5E7F6F648 +:100870008A93ABF9EDD7B7B77DF3E7D7FDF7F7F775 +:100880007E61AE896698EC35B4ED420426F581446C +:10089000EE89E4E7880BB91D40A1B94D1CFCF8DED8 +:1008A00081E98DB5580B782EE3F57FE59CD12DB805 +:1008B00012BF2A3C6D98C2FB61B4E995609FFB3F73 +:1008C00046CBA396E6CE3EBC76EA6EDCF6EE7EFC28 +:1008D00017FD8E8CEEDE3FBD7EFA6FDDFEFE7FFDE6 +:1008E0001FEF6791E7CFBEBE77EBEEDEF7EFFEFEC0 +:1008F00017880C80EFDFBFBF7FFBEFDFFFFF01EA50 +:1009000060C97E0D20F47B736E84CDEDA8DB56BBF1 +:1009100032E323AE3C6BB281CC0B27B4E671A4C2A8 +:1009200059058996FF02652DC7B2A6EDF85AB80A97 +:100930005D566820DD66BB284BB5BAFE11C6D4C330 +:10094000FB2F7EFB0822B38BEB9819FF0B1D2DE1CB +:100950001CD4C63C1292172358F460BAC789762774 +:10096000F8FD75AB9F6233895F8CD21D1136C6BD11 +:100970008902E68C833832ABC9F388E9F779A4DEC3 +:100980005BAACEA5021D3AA1B180947BC65F7263BB +:10099000079CC0423EE072D2DAC1B09DF82CB06A2A +:1009A00053814E00815CBA21249C34C9133CFA0661 +:1009B000CB4AFA0630F09880CA26F7FEF93DD87582 +:1009C000F875E148069C562F6A978BC60D4C652436 +:1009D000EE7FAAAC003EEC480A1A13401A987C2F0E +:1009E00019B8FCA1FB7818F9D4EBEEB50A6D3BD130 +:1009F00073A6C34BF3A214A91196684971B859158F +:100A00003C7E8C1D80E434182C90524FBCC676DCA2 +:100A1000346B521188F4351963C34BF0E793D0CE91 +:100A2000FA03BBE11CF69EBBAF5BF09F4D2139057D +:100A3000CD95541D14117436255E0850F5D70E7DE2 +:100A4000102026B4FC14813B11021D4F79E7743A43 +:100A50007270E11517044C800774E14F1CF467377E +:100A600015866096FD156E398E3599D52A61C54972 +:100A700005D58B0010C88437A1752A8A124DCC4C3D +:100A8000A64AA4C58E883161C2460B95AE527EA39C +:100A90000839C03A31EC31304014823D1EC2BB7976 +:100AA0007FAE55156FACB163825A6CD1FEEA05FC7E +:100AB00057A6E1180FDC8C79245B45E697817B41D2 +:100AC0006640C35FFC373C7796F9045716BAA2F12B +:100AD0009A6A232DAE8D6CB66618235B1EAAE7C6F4 +:100AE00035C8FEB31F49ED25D26BA528A869DD35B1 +:100AF0008F8F0B15D73F17B49670AB502079DC342D +:100B0000DB25A57F6C426F20E21D2E82D0EF55EDD4 +:100B10009780355C1151FC899F8BBD225FC6D5FE45 +:100B2000E1FEBAEEFA0792896E5810514EE03D8A06 +:100B30004B138692CF527E8B8E82C378A77347EB7E +:100B40000E4402266638D4A4E09EE74EB3043EE984 +:100B5000BCAC852D9128D5C5402207CA2CFFB88092 +:100B6000C5D2028BE9D26B208C8146B6ACD1396BF1 +:100B7000203130E2A14A15E61957B0CAC14676DCE9 +:100B800042C372859C4ED6E00D343A3C326F3565D7 +:100B9000F29EC412A27CE2A2449AA6EA7A6DC7161B +:100BA0003B2F8A26DD4F1E10E46DE447CD8F37C9F9 +:100BB000031C0CCF6E6CBB220E9A746A007D7C16EF +:100BC0005A77E5C8FE2C5DB3787AED805A99BF8FCD +:100BD00051B8A330E0BEBCA9849849A325FAB3C894 +:100BE000DAF765EAE94A3DA3C4194C94B698D812DD +:100BF000134AA5226EDDBB8693094D953B2824AD93 +:100C000004ADA6BA8A89CBB64CC9627C63C43700EE +:100C10003486C49717127D52871792939252735D50 +:100C200043E1C5B2EAC6B21ED092452DC8C79CB0FA +:100C300062D306D2B593BCF9134B440C485959FE04 +:100C400066040E90952430FFB48A42D2340E5BF2D3 +:100C5000643005B48C17B13E36EF45D8106427FDDB +:100C600063B1242C0243CADF393B475A387A57090B +:100C7000AA51FC9F6D35B1BC7C71EC5EFB75B41262 +:100C8000E6D9B037D8CAD7D082C893E54B2AB5CEBB +:100C900078804FF56ECD58FBFEE9F3265F40C446E1 +:100CA000F195CA2ED92F5799F7FDD5E71B200327B9 +:100CB000112A671881304ADE65C5D174E4BFFBBBD9 +:100CC0003CCB8DDEB44A03194E6865FA490C09BB6A +:100CD000219B293DF9BEBDDF460900B827FE9E4293 +:100CE00049C4519827233FFC0F69E95328EFC1FD00 +:100CF000D927C464EB2FD0B04708DCD93F06322493 +:100D0000F0FD147B8186035F2AC8EE8FEB03F1911F +:100D1000F7947AEDF0302E69D538E247E6337567FF +:100D200080ED80B9B98787B048932744EF2321B17C +:100D3000A12C87185015709C5399A2B0D58770FCD0 +:100D400052A8E940CA04B120E40266B951E64DC593 +:100D5000EC74BEAEF0AFD2478492673EE094196364 +:100D60007BF174A942C7C9D52B7140EEE985D60342 +:100D700031C963860D859FF80A8D29BC147172985C +:100D8000A68C34D042E83F696AD4B4B3264EA30D92 +:100D900021540FB5D4FE392F1E4AB20B0A4F73C827 +:100DA000C3CFD048E3D9942763C4B311ABD37467DE +:100DB0003D9D02EFC42379D4C3DD284DA30DEB7410 +:100DC00060BB8E813148022AD9844A0D660ED8163E +:100DD000DA66A8D0CFBE9BCDFA0A29E7BAB1339123 +:100DE00011F7616A08F43BA6098EB6E147E91FA531 +:100DF000337E7600F48DE529257E6A0EA35A26609F +:100E0000C4422052FA82D1B3AB42E22ACE7D06DF41 +:100E1000C1858217F4FB5A3E1C3465B563DB1A7E2C +:100E2000691D411476763CCF04C31F8931C7D47F36 +:100E3000471F00ECCEA7D1D87D647D8EDE8791F868 +:100E40006FAEF354A418483B2BC415FC69D98D2907 +:100E500017195835CC24373A85F082EA6896F13F65 +:100E6000C5D691D7E5E1304C8A50DD26061B53C923 +:100E700090D0DC6779257E38CD83618DE7AE501246 +:100E8000B2EAAAA2F88AD9BB6E8F9557E8AA99FB55 +:100E9000B17AAB93F6B89AB4DA586326E69886A48A +:100EA000A3D60B7F747E34E7D7FE1F53645E74872E +:100EB0006CFB567E3B7F1534E6421AA4E79A047415 +:100EC000C6C9C891E658B846010AE8F6E90EF836F0 +:100ED0000156881B7A2C8932C191CA5B611EF9B711 +:100EE0001E6F4D18C73DFA31288BCE586F93591B92 +:100EF00085F1085EEFD1394510444859DD9F9B6E5E +:100F0000E0FABFC29EE4B7C5FD0CE7820AD8442DC3 +:100F10008B96D8BC53797EAE9BC249CE80C8F9EC83 +:100F20004B1382CC1EE5B0AFDD9746B821A597499B +:100F3000E9C1B5C1EA25F50859FEA9CE46CFD5A32A +:100F4000EB66EDE0AFFBB529DC114F4290AB3EA65E +:100F50005AAD23E95CB4951F58E0C784EA14C91A56 +:100F600059B2258E818A96A96010C74FDF95549C8F +:100F700053CC780A3E352C2BCD91B01099BAFBEAB0 +:100F80004A8C0A43DC08FD2BCDD64C5332A5B78CD6 +:100F9000EA500DCBD27176A6BA2DCF9388C1796273 +:100FA000AB8F0B5250FC107733D2D8888BDE7FFA90 +:100FB000C76108F8E82DFD60FD456EAEB50236AF9D +:100FC00081C8F012A84B5CA5ADB435371390E76625 +:100FD000FA38F056A83E332CB487D1B63A7A9356F5 +:100FE0001B6C7381A7DFBFFC286BEA157794ADEE0D +:100FF0006B0032336FBFA7223197C7427FFBDBD92B +:101000001C003FB0106498BFCF265BE924243370E6 +:1010100054106647BAF455A2C7362ACFC4343E2EC0 +:101020008A61086F11A35D910F58172D8D25A38339 +:10103000156C099ED4E146A30731B200859354ECA8 +:10104000D020513CE43672BBBEEFC75E34B59F750D +:10105000FCE386148C1B37B804703C268474680744 +:10106000BAFBDD7E51371DB90D61B165F465A1A7ED +:101070003C39624A12F016B145A1E9B5C50654974C +:1010800046467A641C75D59B4E8DCFDE02CCC79D3B +:101090004E4A8594FE3BCAF8F722CEDF43F95984C5 +:1010A0005FAC5195B1ED431778774FDC8F4150F726 +:1010B0004F426594CFCEAEB6764C4CD2E15DAF7E5A +:1010C000CCC2EB61A9F0E3B33CEF9155C4A970FA2F +:1010D000DAA58C9B23FB9EB6FAF7ED679E3713F2D9 +:1010E000CDEF739153B01DB8738BE229BDD85D73FA +:1010F000A2CB0E606FF81EB6A899AC2C6FDBDBFF9D +:10110000DBC97F04A97B8130D06BEE46EE2356CC41 +:10111000FC920A0AE1EE93EB6070C37B9AD4D76726 +:10112000DCA8863EA1011D415C4F61E9813C29EBB1 +:1011300031939AF65BF7137910B50891D4C3D7CFE2 +:101140001A73A161B863EF2B284721BF40E659FE0F +:10115000BF1C6093F2D6B93402DFE020FC3DD14FD2 +:101160001B1C210062B479ED29E33C94E945732608 +:101170003176E037B1D788C303316041C317514D91 +:101180007A8A03CC806E9AE272E1F50AE0AE17CE5D +:10119000729A124ED080BAA493BC8048925ADBA3B4 +:1011A0003B8B930DD5EFBB4A3D9B4A70537EF87144 +:1011B00051182A0DF4ED029A7BF03809CEDFEA438C +:1011C0003ACAF406BA6BB96EA5302939B68EDFDE9D +:1011D000107DA868642E991722FAB584C6F892810A +:1011E00019F2296B33569C602B4EA94EE982584464 +:1011F0001172286AECBF372001C3682ABBBCFE2DE0 +:101200005D94AD73AA22C99174692512EC831363AE +:10121000716FA30B2CE6530B7C7924DAE49312163E +:10122000AE24750CBDB56E9DBF28C302ED829364DC +:1012300071EF0276F392B79FDB534DD8E537077E07 +:10124000B3A441439B3B347F94BE7352EC0FB3165F +:101250003452DD970C301433241C786E8C9667372B +:101260003DE6C1641D41777A9B7F81A91135FE2936 +:10127000177A0072C364D0DF810DE315F31AF5D736 +:10128000B96AAA22967CE3894E4AEA62CC87DB1DC2 +:10129000BACA277BC318FC787E71281B6D621A2E90 +:1012A000FAEBEB1EF98B59B96B2D21DDCDFE5B7C82 +:1012B000CB49A19AB0AC18BAB530CA0BE79A9A18C4 +:1012C0001C4B891ABEEB5994FCBCE806BFEC768334 +:1012D00036FF481AB6FB7B7F4F1AEE9E9DCE1BE66B +:1012E000B019C969BFEAD954C58B68642882917165 +:1012F000375B554FE111185A657BF05BA1FB1AFC77 +:10130000E906A55FDE00F5239A12C6FA0801F7E6A2 +:10131000616D034D9727B42058FBBC830C54D72B29 +:1013200095617B84EC835DE53AA70DC3FDDD751DFA +:10133000ECF391850EE4112E178147F96F687686DC +:101340003A96A582808FB0242A4DE5C2DE53EB6D1C +:1013500010756463D0861FA300820F87B56E514954 +:101360009697E51199C591F6865FA571F58786E098 +:101370001174E400A52B34E5D349C1DC57F5CC57F3 +:101380006B756FEAF0C7F7CCB9AE85C90DCC78B3F1 +:10139000529816069627F6EDA1D8CFF362DA79EFC8 +:1013A0005B2CEF9E635CBC2153E2C141B35D27A877 +:1013B00013E5218691AF86E943BF084A4859BE0C20 +:1013C0001A6D6D6D488B690BC6EE8BBD323D32AE2A +:1013D00030F4ACE813A519E6BA2CA18F937E5FED2B +:1013E0001BC970073C13A195E3EF4592DD80D84EF1 +:1013F000313E2C8933DB5ADBA39FB0EFFBFDD47564 +:10140000DB6660D64275B03D546B255BCC2482AF61 +:101410004C42189C6CC5153A5450121BE608D6F77E +:10142000A7A3E0D0F74E5FD6B3414859EF095797CD +:10143000E916E66093AE5EF7E29ADA914E4596447D +:101440003EC885F1E6249ABB0CC5C5D20715FAB68D +:101450009BBE4450F4524CE6C890E55FFCF6CA5E71 +:101460003FC30590BFC2B07ABD914709F32DF6F690 +:1014700015F4C4642D813BB1AF772E89856F177643 +:1014800036E8609E9C3E27FAEFAA8D67CE891F48FA +:10149000D0785AA396AED1167341CC53E40DDE9C9E +:1014A0006A700D100DAB451BF74FCBDCCF2D023A08 +:1014B000F0DE922B0FEDDF813B448EFBE5495E9E13 +:1014C0001E48D00E111E5DBCD51F85C7D61DFA71F2 +:1014D000344C8C9B44E439A685DDCE223EEFECFDF6 +:1014E0003DE90DFB9F3FAAFC172F4BD3A551159A41 +:1014F00098FBCC2B5B5B7ACE1F3A6102FFFFFFBDEE +:10150000AA0C06A0CE052FA0404252466BA674FA44 +:10151000087E230CD3F6F0DE20CEC36BE0B675CA8E +:10152000680180025858EB225DB361E3A9F563BA04 +:101530008895445349549898FD53EF45A1CB2CE925 +:101540003E47A3DB71E4794E30B405C41E99D81F21 +:10155000AB101FF89685228E60A04B43A7F0742E27 +:101560008117406AC4B4D1C429E3DD76D489D2EBB3 +:101570002B5480C703B7AC61162860CAB9BC246A73 +:10158000C2199B08C2F418D3DF8AEB2D9389760B1E +:1015900054FA5B8CD33B9BD1623A474F15DEDBBEDE +:1015A00087F6777781F1C568B8CB292FD9C727B7D8 +:1015B0001913624F897FF87357BE68B4D05F9A9B46 +:1015C000229184871B5361CE32B18043B2B99463B8 +:1015D000481289B70A723986190AC9F7A2FE40D2A1 +:1015E00047ABD6F99844E54E73F4746E8B68B9EC4A +:1015F000AF3B692F0754F0A5549B4935E3F8D50D4F +:10160000048D9D99BC7A9C3D3A42E5921483D17B2E +:10161000EEB41290EC2A223C7C7DE85EE49312B793 +:1016200081E1A43B7A01C18E7578365F9427BB8F28 +:10163000B57945D276B210CCB123F159E537BA5C11 +:101640003C42794019A005136C8022312B663D3253 +:10165000E1AFBE9813C535603C293A5ACA968471E9 +:101660001F6501579AE6C1A46D01AADB8587B67B89 +:101670002D0861189D24BCD76773FC715D970471B8 +:101680006645231746718E3E92584857AE4C7C1DD6 +:10169000F548211FC481F8B37E75EC56D05F3976CA +:1016A00067507217744119C577703657AF4DE07C9B +:1016B000C2B60A1DF7633B7AB32BFD512B4D8974DB +:1016C00026052411981C48972E6A31E4187E8F73E2 +:1016D000365A34BF5631036693F1CA3F8E9E3F702F +:1016E000BC4BE54089F8D1F46F89E058686FB55874 +:1016F00077226A95B224C9A49B29955CC99F047B73 +:101700001AB2F22FB802BC258440C6BAD002CCEF80 +:1017100028120581F0FAE87987D0E94A1ADB01BA84 +:101720008587CC9C1565F5F8417C67A721DB8F196F +:1017300094E22611F1E3E6743DD124C5B9452EA10A +:1017400066BFBCC627B75D39750064C9BAFB74E9CA +:10175000D0D05C910CBA811E40920FC3C088141582 +:10176000BC1AB58EBF93B5DDF4E19D6035E5CDB90A +:1017700011D18CC32EAF8F5C362A87C899A251E84D +:10178000103ADC27FDDE23A9FF80EFCE6ACADE42D5 +:10179000541D0B2971431BA2F5D8CFB3E09AFEEF7D +:1017A0008379EE5D7A0FE32AFE85CA66084DFF8ACB +:1017B000421B8D8B549D6B61CCD94FB1F5407CE0C1 +:1017C0005AC85538E0CAAAAF48E815E8493C1D1C7C +:1017D000302AAC8BA07D7407421A1FA89AAE2EE067 +:1017E0001BC9D57ABD8ACC050BE9D1AC93BA54E1BB +:1017F0002441ECAFD6AED8B0431BDFAAD1FA9C0F80 +:101800006BA4852FEFE47740B05205DF8E59723C10 +:101810001FC986F4E683B7F0C795C42E5CD48E2C1E +:1018200091E126E82E65493E557A44DFD75976780E +:1018300012712729337537645D7E6891112CF4F29B +:10184000E338D316623B72F64CF6E4AE748489F248 +:1018500014503817AE27741AEC0368F76C84447878 +:101860007641E9E85467DDDC1113EED93B600BF9F2 +:10187000552C257DB306A21C2323DB7C077F10ECAF +:1018800014E8D7FD6BECC3329C274F8802CC872528 +:1018900001788124D6E1FC33BB58C152E44C015697 +:1018A0001F09B34F230D9813576661515B34FFE84E +:1018B00057E520F92860FE5B4E59C9701FCD9F5136 +:1018C0000D28D7162C67011E38320516CA186C333E +:1018D000FDFD8CD1B54E405D6B03534615086F324C +:1018E000E035531C3E10C50113065385AE8919E53A +:1018F0007CB48C5D6FF19D643B89109D7F54E3FF48 +:101900005F7006ACB77C63206F28E55B2BBBD21AF7 +:10191000F762777D4230E42E27D672F9C7446245DC +:10192000377EE02241015C249E7A6752B6C7F420DC +:10193000B65E36053D6A3225A2D7D1BE22C3C19E0E +:10194000209C360B1F8F901E5012B9065486FEE461 +:101950002880EF0ACAB6911F64F21414A0846B2782 +:10196000218CDC0B4727B1668985C4EAA942B126E0 +:10197000D92301CD4B37B067215546E47315D5DC2B +:10198000488F0EC4CD7CB92BEA0CCD7A68D0519328 +:10199000339C0D3FDB7E580920BA127F9E4EA22B4E +:1019A00056F184B1BD181A10BB694DF993C0D831F6 +:1019B000B4E82A6BF3391B01637FEF0543D9AE51BD +:1019C000C1AA88B6C0AE6DE6FAD0CFAF03E89F08D3 +:1019D000C7BAA786135C602DF2D4C977E2CE616FD7 +:1019E00093AB26851C1AA50DFBCC4F6C43EF870DDE +:1019F00011BB09B5904D9D548AFD83516F1F397CF1 +:101A000005FB87ED0500F995D911039610469176EF +:101A10007296C09237CEEC4CD1149C5E438877BD51 +:101A200013E3C0D5AAFA69AE6D9E8754D8755332B8 +:101A3000E1622D9E22CB04EFB123C759B21550634A +:101A4000BBE78312BC4629D5342958DFD4247278E9 +:101A5000F8AF8059B45634B896D9C25CDC967FE9A9 +:101A60000A787F19FD47ADF6D503C650512EF27D99 +:101A70001FF5D4ADF52A1F3A0983619DDDF7FB7789 +:101A8000E2674B384688A26492584E57F6786475E0 +:101A9000F690945623EEBB43243A7688FE6507F40D +:101AA000E361B5663CC325C7BF906D79F771827558 +:101AB000B0A8089AA87F3BB1673BF6CAE73FE6BBF0 +:101AC00099F2153AA6013EC0060AE89652AE0DB646 +:101AD0008E3C0C5FAE189E30C51A8A5B07FC9AC21A +:101AE0009EC94BA1BFEA4731C28B6874087CC54EC2 +:101AF0006149DCA530FA1A3995D048591F19DC33F1 +:101B000012FD8B066F64E3C5616466C66FE66B40C9 +:101B10002B6D6D8CF71A13E1F5F2E6C778D272AF30 +:101B20002243807999F8E7A2FB1767C46827355DDF +:101B30003BA16EC7CC5868DFF49F66A6F871B3E589 +:101B4000B6B2578BFDC40D24706246C47541F7636D +:101B50005275A4E088829AE700F68E5FE2C27605AD +:101B6000D5B36689D9B93AAB4BE1DDE5A0737AEB21 +:101B700011D18C2EC799C2AC015464A299565BEA6C +:101B800018BA83270B7089AE4AA853B9FCFDFD171C +:101B9000701B8336FF50E8F5603EEEAC7DBBDB8901 +:101BA00087790215EF7F9A664BA9D3FB77AAD2609B +:101BB000725F7CC40660001061F36ECDDBF6DE6000 +:101BC0005AB5A281E0CC05CC0AE8551FF86FFDADEF +:101BD000127DF2823D2CBCAB688449017E995FE5A1 +:101BE0000392B0729B6B1C140B87D9F5F34FDEEA9E +:101BF0000B9AE282265F3CCAF1FF2945FB5DD322A6 +:101C00005571A01D44E4CB0F4C207BF38C246F1145 +:101C10001615D21ACE9634E34495C6D78449D9FC1A +:101C200077444FF609E86EEF4D21FBB1CD25EBB2BD +:101C300029145A8819F5D56CF00746D5DD7314B10F +:101C4000BBBC194629D6EBBBBEDBC5D261642D6E89 +:101C5000AC3600D72C80B2F77414CBD8A652D4B4CB +:101C6000BCC3DD6951B815F7BF4A47CDAF3E5593A8 +:101C7000C788859A3533351F24B240D19DA6B47CE0 +:101C80002BF48B88D9FC5E47FB1BCDDE1C5AFEB2C1 +:101C9000157C3D2417043EE9A38A9226015C7B55FE +:101CA000986D9F12DC48010CFA924F770FF05F9FFE +:101CB000D773B0D604F068D7050B1204FD3B34D6B9 +:101CC000674869ECB03E04B3BC5FCF23AB0CD2775E +:101CD0001626746696F95C7E05A5CCB834CB7931AE +:101CE0005F49F92D535F1DDBC3896CF4E60D1FF8C6 +:101CF0003336F3C42F8CA834C019CB9DE37B84AC5E +:101D0000C0568C4180041020102040409024506028 +:101D1000099449F6881411211830414198345161D1 +:101D20003BE93ECD810590221121C0429125D06230 +:101D300009118103891591231931C1439935D16363 +:101D400040400204C044122450604244D0645264B3 +:101D500048500305C854132558704345D87453653B +:101D600041418206C14592265161C246D165D26683 +:101D700049518307C95593275971C347D975D3670B +:101D8000928CAEBC820C182812284848922C5868B5 +:101D90006AC8A1068A1C19291A3849499A3C596906 +:101DA00063D04007830D982A1329C84A932DD86A17 +:101DB0009B9D4CEC8B1D992B1B39C94B9B3DD96BC3 +:101DC00042480A0CC24C1A2C52684A4CD26C5A6CCB +:101DD0004A580B0DCA5C1B2D5A784B4DDA7C5B6D53 +:101DE00043498A0EC34D9A2E5369CA4ED36DDA6E9B +:101DF0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F23 +:101E0000048020108484303014A0605094A470703A +:101E10000C9021118C9431311CB061519CB47171C2 +:101E20000581A0128585B03215A1E05295A5F0720A +:101E30000D91A1138D95B1331DB1E1539DB5F17392 +:101E400044C02214C4C4323454E06254D4E47274E2 +:101E50004CD02315CCD433355CF06355DCF473756A +:101E600045C1A216C5C5B23655E1E256D5E5F276B2 +:101E70004DD1A317CDD5B3375DF1E357DDF5F3773A +:101E800006882818868C383816A8685896AC787852 +:101E90000E9829198E9C39391EB869599EBC7979DA +:101EA0000789A81A878DB83A17A9E85A97ADF87A22 +:101EB0000F99A91B8F9DB93B1FB9E95B9FBDF97BAA +:101EC00046C82A1CC6CC3A3C56E86A5CD6EC7A7CFA +:101ED0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7D82 +:101EE00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7ECA +:101EF0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7F52 +:101F0000E0E6230DA00614A0302244C0B02654E021 +:101F100012FA884EA81615A1383245C1B83655E1D7 +:101F2000DE07519AA10794A23123C4C2B127D4E29B +:101F300028E5A1C1A91795A33933C5C3B937D5E39E +:101F400060420684E04616A4706246C4F06656E419 +:101F500068520785E85617A5787247C5F87657E5A1 +:101F600061438686E14796A67163C6C6F167D6E6E9 +:101F700069538787E95797A77973C7C7F977D7E771 +:101F8000CE6208E6A20E1CA8322A4CC8B22E5CE82B +:101F90002A1A0D89AA1E1DA93A3A4DC9BA3E5DE911 +:101FA000450B8C8AA30F9CAA332BCCCAB32FDCEA37 +:101FB0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEBE1 +:101FC000624A0E8CE24E1EAC726A4ECCF26E5EEC31 +:101FD0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FEDB9 +:101FE000634B8E8EE34F9EAE736BCECEF36FDEEE01 +:101FF0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEF89 +:1020000024822490A48634B034A264D0B4A674F0A0 +:102010002C922591AC9635B13CB265D1BCB675F128 +:102020002583A492A587B4B235A3E4D2B5A7F4F270 +:102030002D93A593AD97B5B33DB3E5D3BDB7F5F3F8 +:1020400064C22694E4C636B474E266D4F4E676F448 +:102050006CD22795ECD637B57CF267D5FCF677F5D0 +:1020600065C3A696E5C7B6B675E3E6D6F5E7F6F618 +:102070006DD3A797EDD7B7B77DF3E7D7FDF7F7F7A0 +:10208000268A2C98A68E3CB836AA6CD8B6AE7CF8B8 +:102090002E9A2D99AE9E3DB93EBA6DD9BEBE7DF940 +:1020A000278BAC9AA78FBCBA37ABECDAB7AFFCFA88 +:1020B0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFB10 +:1020C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFC60 +:1020D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFDE8 +:1020E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE30 +:1020F0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFFB8 +:102100000000000080041020102040409024506007 +:10211000081001018814112118304141983451618F +:1021200001018002810590221121C0429125D062D7 +:1021300009118103891591231931C1439935D1635F +:1021400040400204C044122450604244D0645264AF +:1021500048500305C854132558704345D874536537 +:1021600041418206C14592265161C246D165D2667F +:1021700049518307C95593275971C347D975D36707 +:1021800002080808820C182812284848922C58681F +:102190000A1809098A1C19291A3849499A3C5969A7 +:1021A0000309880A830D982A1329C84A932DD86AEF +:1021B0000B19890B8B1D992B1B39C94B9B3DD96B77 +:1021C00042480A0CC24C1A2C52684A4CD26C5A6CC7 +:1021D0004A580B0DCA5C1B2D5A784B4DDA7C5B6D4F +:1021E00043498A0EC34D9A2E5369CA4ED36DDA6E97 +:1021F0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F1F +:10220000048020108484303014A0605094A4707036 +:102210000C9021118C9431311CB061519CB47171BE +:102220000581A0128585B03215A1E05295A5F07206 +:102230000D91A1138D95B1331DB1E1539DB5F1738E +:1022400044C02214C4C4323454E06254D4E47274DE +:102250004CD02315CCD433355CF06355DCF4737566 +:1022600045C1A216C5C5B23655E1E256D5E5F276AE +:102270004DD1A317CDD5B3375DF1E357DDF5F37736 +:1022800006882818868C383816A8685896AC78784E +:102290000E9829198E9C39391EB869599EBC7979D6 +:1022A0000789A81A878DB83A17A9E85A97ADF87A1E +:1022B0000F99A91B8F9DB93B1FB9E95B9FBDF97BA6 +:1022C00046C82A1CC6CC3A3C56E86A5CD6EC7A7CF6 +:1022D0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7D7E +:1022E00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7EC6 +:1022F0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7F4E +:1023000020020480A00614A0302244C0B02654E06D +:1023100028120581A81615A1383245C1B83655E1F5 +:1023200021038482A10794A23123C4C2B127D4E23D +:1023300029138583A91795A33933C5C3B937D5E3C5 +:1023400060420684E04616A4706246C4F06656E415 +:1023500068520785E85617A5787247C5F87657E59D +:1023600061438686E14796A67163C6C6F167D6E6E5 +:1023700069538787E95797A77973C7C7F977D7E76D +:10238000220A0C88A20E1CA8322A4CC8B22E5CE885 +:102390002A1A0D89AA1E1DA93A3A4DC9BA3E5DE90D +:1023A000230B8C8AA30F9CAA332BCCCAB32FDCEA55 +:1023B0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEBDD +:1023C000624A0E8CE24E1EAC726A4ECCF26E5EEC2D +:1023D0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FEDB5 +:1023E000634B8E8EE34F9EAE736BCECEF36FDEEEFD +:1023F0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEF85 +:1024000024822490A48634B034A264D0B4A674F09C +:102410002C922591AC9635B13CB265D1BCB675F124 +:102420002583A492A587B4B235A3E4D2B5A7F4F26C +:102430002D93A593AD97B5B33DB3E5D3BDB7F5F3F4 +:1024400064C22694E4C636B474E266D4F4E676F444 +:102450006CD22795ECD637B57CF267D5FCF677F5CC +:1024600065C3A696E5C7B6B675E3E6D6F5E7F6F614 +:102470006DD3A797EDD7B7B77DF3E7D7FDF7F7F79C +:10248000268A2C98A68E3CB836AA6CD8B6AE7CF8B4 +:102490002E9A2D99AE9E3DB93EBA6DD9BEBE7DF93C +:1024A000278BAC9AA78FBCBA37ABECDAB7AFFCFA84 +:1024B0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFB0C +:1024C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFC5C +:1024D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFDE4 +:1024E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE2C +:1024F0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFFB4 +:102500000000000080041020102040409024506003 +:10251000081001018814112118304141983451618B +:1025200001018002810590221121C0429125D062D3 +:1025300009118103891591231931C1439935D1635B +:1025400040400204C044122450604244D0645264AB +:1025500048500305C854132558704345D874536533 +:1025600041418206C14592265161C246D165D2667B +:1025700049518307C95593275971C347D975D36703 +:1025800002080808820C182812284848922C58681B +:102590000A1809098A1C19291A3849499A3C5969A3 +:1025A0000309880A830D982A1329C84A932DD86AEB +:1025B0000B19890B8B1D992B1B39C94B9B3DD96B73 +:1025C00042480A0CC24C1A2C52684A4CD26C5A6CC3 +:1025D0004A580B0DCA5C1B2D5A784B4DDA7C5B6D4B +:1025E00043498A0EC34D9A2E5369CA4ED36DDA6E93 +:1025F0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F1B +:10260000048020108484303014A0605094A4707032 +:102610000C9021118C9431311CB061519CB47171BA +:102620000581A0128585B03215A1E05295A5F07202 +:102630000D91A1138D95B1331DB1E1539DB5F1738A +:1026400044C02214C4C4323454E06254D4E47274DA +:102650004CD02315CCD433355CF06355DCF4737562 +:1026600045C1A216C5C5B23655E1E256D5E5F276AA +:102670004DD1A317CDD5B3375DF1E357DDF5F37732 +:1026800006882818868C383816A8685896AC78784A +:102690000E9829198E9C39391EB869599EBC7979D2 +:1026A0000789A81A878DB83A17A9E85A97ADF87A1A +:1026B0000F99A91B8F9DB93B1FB9E95B9FBDF97BA2 +:1026C00046C82A1CC6CC3A3C56E86A5CD6EC7A7CF2 +:1026D0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7D7A +:1026E00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7EC2 +:1026F0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7F4A +:1027000020020480A00614A0302244C0B02654E069 +:1027100028120581A81615A1383245C1B83655E1F1 +:1027200021038482A10794A23123C4C2B127D4E239 +:1027300029138583A91795A33933C5C3B937D5E3C1 +:1027400060420684E04616A4706246C4F06656E411 +:1027500068520785E85617A5787247C5F87657E599 +:1027600061438686E14796A67163C6C6F167D6E6E1 +:1027700069538787E95797A77973C7C7F977D7E769 +:10278000220A0C88A20E1CA8322A4CC8B22E5CE881 +:102790002A1A0D89AA1E1DA93A3A4DC9BA3E5DE909 +:1027A000230B8C8AA30F9CAA332BCCCAB32FDCEA51 +:1027B0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEBD9 +:1027C000624A0E8CE24E1EAC726A4ECCF26E5EEC29 +:1027D0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FEDB1 +:1027E000634B8E8EE34F9EAE736BCECEF36FDEEEF9 +:1027F0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEF81 +:1028000024822490A48634B034A264D0B4A674F098 +:102810002C922591AC9635B13CB265D1BCB675F120 +:102820002583A492A587B4B235A3E4D2B5A7F4F268 +:102830002D93A593AD97B5B33DB3E5D3BDB7F5F3F0 +:1028400064C22694E4C636B474E266D4F4E676F440 +:102850006CD22795ECD637B57CF267D5FCF677F5C8 +:1028600065C3A696E5C7B6B675E3E6D6F5E7F6F610 +:102870006DD3A797EDD7B7B77DF3E7D7FDF7F7F798 +:10288000268A2C98A68E3CB836AA6CD8B6AE7CF8B0 +:102890002E9A2D99AE9E3DB93EBA6DD9BEBE7DF938 +:1028A000278BAC9AA78FBCBA37ABECDAB7AFFCFA80 +:1028B0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFB08 +:1028C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFC58 +:1028D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFDE0 +:1028E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE28 +:1028F0006FDBAF9FEFDFBFBF7FFBEFDFFFFF01E8C5 +:10290000DB7D7F19E866EF624D2173403BEEEB3BC8 +:10291000D96F2041047671A410B8C3B80704F19EA2 +:102920005E0486B98D4412A8BDA588A10ECC70F9AD +:102930001DC3874EF71370A0F85332262285ACBC16 +:1029400078BF261F7F70F536C793C6E96712B9B7FF +:10295000F26078AAA8292228C8F23EFC488420A464 +:10296000E73775167AF1756700DD2922D01339959E +:10297000E9A1FED4D35EB7FC037B60CA2685AE75A1 +:10298000278CA5185D339CF72AD3E445296EF99569 +:10299000CAE0A14BA27E1F64C3BA7A497F5EA26FD0 +:1029A0001B98F755384F39D7E80E69B5BB4F5A9386 +:1029B000D06E8F66685AB7F7F7BD81A8D179DF2648 +:1029C0003C4FAB4D8CB1E3B732B84F4300927EE140 +:1029D000325DEB8CC9B01B6CC591D936BAA5C76204 +:1029E0001A466FA59DB40B55E78BEE15B3B416616F +:1029F0003AAA0F82108DE4563A5D49C5BBA45562D0 +:102A0000B8A9A31DECE6CF3E00E9E2A99820DD1AA3 +:102A1000CC788D5373164C47B7F76F8D5595668AF2 +:102A2000FA4301CDBD7BB639F6254577CD37F61F84 +:102A3000B5A0008CB56A1D3ED97B5AACBDB7F588F0 +:102A40001EC28171544635882CC4E06E8FBB0D5474 +:102A500005B2D470E7B6E57464721E43437AD2FCC3 +:102A60007F2320BEFD5A307C18831D3315A4FB70D4 +:102A7000752E874C92D5C031F2134FAAF615B312BA +:102A8000B2EA5513FDAB998776787185B22877A1A4 +:102A90000C65BD3836833F747EC5F7541A8E196EA7 +:102AA00087F3DD13477C70786F8E155507DB9375C0 +:102AB000631D0CA290191412E0C66856E1BB18F809 +:102AC000D921B8C719CD1E3A2ECC8FC3EE9C1575EF +:102AD000137AC6BCB6F8B9B720FE08A4931ED77205 +:102AE000D834385F8D881BBE569F8AC5529F784464 +:102AF0007726B1F247BFFB30CF0596A40047732677 +:102B0000ECE208C27458879F38323B1484617A3CE7 +:102B10001352E0C3FA6BE2A7DB15E44B47B4287706 +:102B20009DCF82CFB3256B7F25E0463B657947DD9E +:102B3000951BA4C3E35334FCE6CC474981D979EE15 +:102B4000322DEDE0BBB76D2A7D00B1A1E862FE46F3 +:102B50009720D15A7866535A214DA26AE81453C07F +:102B6000F10467703CDAA1A6498B8A8791B62FEBF6 +:102B7000092E518AD3EB1AC5337B2268BFF5AADC34 +:102B800036557B71166CA359BA58EFAD25C1E93B98 +:102B900012658C8406EE9DDFB2586E89D25CA2E786 +:102BA000FC857986DC61EA358CC94E404ADED1CAA3 +:102BB000EB7DF4C9566D0BF48F59EE8B83C1DB5856 +:102BC000196DAF0D993110133C4E7DC4CA2950EFD9 +:102BD000F5E2E4E9B748F0BF02F844893A189146B3 +:102BE00053B80A057339FEEECBE995DACB6B764C18 +:102BF000FBD98813D1EB854043F9947BB57EA4EFD4 +:102C0000DBF0D72F0FC13A6CF4C4B2BC0955F87D84 +:102C100055B584AECC4630BC55599AD75849905AD0 +:102C200045FE329F614D0F4DE1FDCA0E515997D2BD +:102C300099F112F6D6B0140CA229444CC5B2157203 +:102C4000B03CDB1574F6494B150AC419949BE4F9A2 +:102C500097AD1475B5C313E946469494B13FAAFAEB +:102C6000413C4745DF7B414B67E21DC40AC057F03A +:102C7000FD51DA41569902D4D171A4BF4988549BC1 +:102C80001EB7D3C50A11CD6E82C81067475DF875AF +:102C900051E01F0695C00E59E1538DA2849AFF5151 +:102CA000F47555A9EF5E45660C171F81E5C0179EA8 +:102CB000F29B9A9E033A68D80D4AA6FBF4DD0A9E61 +:102CC0005E34829180AC85A34E786FDACE7CBEFAFA +:102CD0005625C64ED6250844B9DE0FBD753E2FFBDE +:102CE000F7B8D03F77AD4DDB3DAF4F58BA265F7890 +:102CF000BB2546AC32559BA48089C10060655E78D7 +:102D00008B89AC0D25F4182F15DC3DBBEFE3ADD658 +:102D100045D962D98790B4E920CB3241F97449ECA6 +:102D20007313C2045E43965970A3CB06CB2763BBD3 +:102D30007136E28754B5A6E3C433F643F9EC156C5B +:102D400039B320893DA812A9B49E216475E0FB39EE +:102D500018E0A1DA9146F62CD8133BF8628E43A80E +:102D600057E07DABBEC1B56DB59E974D359AE182FA +:102D7000892FDF8A08D136A599127E21CB8C382382 +:102D80007AF5F24AB8F71E63D247430A4D9AD11931 +:102D90004502AAF230EF3B3945B2CBE1945C5F04C7 +:102DA000DE50690C5B29ABDF2FC7BBB3534E6F6C92 +:102DB000F49DB6B331EEB32D525B7E2EC52EFBB81B +:102DC00022918003F8CBEDA729884E61881128C392 +:102DD00048BAAA61710628E960834D067E0A30620E +:102DE00023900803C7CA61B24486FD4E77127975F5 +:102DF00029498ADF0B3A033D831AB3495F4FBB5918 +:102E0000B89D261BBCF47039EFD35332CFA4760D96 +:102E1000CC70DECAB07AB39910703957FD8F5BE47D +:102E2000FA050D8005C6C470EAE6E63FD9598D89DA +:102E3000536C30A895F7425652BE8233CD31C2163C +:102E4000E0A2DD5618261632AF64C7DA8C1B4100AB +:102E500028202B1AB4284ECE4E025021CEF0886E78 +:102E600033FC20AC5A29D1A786126E5B1586471019 +:102E70002D08291A942CBF75A7876CD1FC715E436D +:102E80004070285ABE77BA906EDAC457B9D3A1E41D +:102E9000A939ABE0B673F13AF23A2256F94798EF06 +:102EA0005EAE7C19CEEF0F5FC8EB688B2CF775F721 +:102EB0006EFBC018C58E9391272AC35DE4CED3DA8A +:102EC000442A0E079960C7B34628174716154C8148 +:102ED000AA30EBD2B65E4666BA0758D97B78D220C4 +:102EE000E24D0343C54FC745F26D4303ADFD056594 +:102EF00016DE4E73F722885BE53E35573B03C8DB91 +:102F000040CB1F8DEF85B52708CD428D96872AA22D +:102F100048DB128CB074E2C4F8543F8367BCE9C24A +:102F2000DE87BB3A2592160A00A7B13F8EA2A31BEB +:102F3000D697BA3B91E8170B3629C38E0897AEC3D4 +:102F40005AC05D405AA921A4EF8BE7A88E60B767ED +:102F50006CAFE9C5505311E8CC10B8DE1C1619FE51 +:102F600019AB0A4D21A769E4B5C367564C945A6B57 +:102F7000B40A053D10BF1B67DD054A315CF37E498D +:102F8000E26CC223E96CEFCDBD113D537253D533D2 +:102F9000714572A91BBE1B22999A91EAF638FC96DC +:102FA0006D0AF78E9BF4208933AF39492CD24EEC51 +:102FB000EB5A84C94A9DC68D05CE40A9623FA6EF53 +:102FC00006282D9ECE9669047A6EE784168169ECF8 +:102FD00078BDE4C92AA72950588C7CD968853C144F +:102FE00003920C833C77E546B30DC2D5A997ED2A31 +:102FF00051EBC420914F1D07BB1CA502BACB2CADD1 +:103000007C92889D64FAC9F27ADDC5768C599DF36D +:10301000F32C21EA8F14322D7251C40E2B45F17A14 +:103020003B2285321D3EB20A65E3AAD4615997E47A +:1030300022E19617956919BE89D11A91220B1E9724 +:1030400006FA27D45E81E8BC710AFA963480F167EB +:10305000B5B0D858EE2904515E0461986F05F37835 +:103060005967246F65A4417B498D68CD8BE01FB201 +:10307000C14CA6662DB130243F03EFB1ABF01C93D9 +:10308000DC622DD5590A43CB8AEB6F888D4CD04535 +:103090007788C810D6B9C0B6BE5812F5864F57F912 +:1030A000D80F1D9AC74B6D6757727051CF2DA7FC73 +:1030B0002B7BA9BECF4E48B61FB36F616B1AD3717D +:1030C00006B7159198C9C3B32EEE8FBA490C6EBEE0 +:1030D000D4EAC4224AA85F12C77D4EAC0716F33D5E +:1030E000A3EB0F7F27A8D4A56F4AE8F34FFEF8B3F0 +:1030F000AFBDE112B2D050A4BF9824B9C336DBBE35 +:10310000DB0482AADA58B34521A435BD6DDB853DC9 +:10311000E48B02813052176CAD81F5C2F9B0F474C2 +:103120007B637BFFDB173360CA5CBF543ADDADD9EC +:1031300033EF0193C5E4FB632E94310059492C7899 +:103140001F50F1468D88B3A4A18D3DE3E89FA126D1 +:1031500050407C51859DB2A5A91E4568E00BD26800 +:1031600018667FDEB9A5D620D18C9B04550E276A40 +:10317000699101FEB1A86C65A0F576E96ACD2FD4FE +:1031800062D9E3055F1C2FD4D24743939A4AA72AFA +:10319000421C7E29D69E425D14F04F2415D4A5A46E +:1031A0007C7607BCDC0C9EB78CD45A4CAA2DDE274B +:1031B00051FEFDA4D1183AD045BD64B0E0353CD4F1 +:1031C000A72AF5F11F159816E6EC02A97F13C72E62 +:1031D000317FAAB217059917215FEAF225BEFAB22C +:1031E0006B2B26038E2F656C33A4B8436F00596395 +:1031F0009224B00A023F646DEF1B3C2A1B080CD3DB +:1032000056FFADB67B0035EBAEC04112BFCAA1324E +:103210006A34CA5251698773E334CCC35830D82E0C +:10322000D1728E9F5A84B665A9BCE6592958F6CF4B +:10323000A2EF7CEE50CC9535DD511E88FD74757E75 +:103240007C4487ADE240971E54E062D9D7E47274A3 +:10325000742FA018CC38EE8E9C2F4A53CEF96815E7 +:1032600085A69A189B74F24D352C8C59D5E5F22C15 +:10327000B6559072C951421C12FA80D75B2CAC67CC +:10328000583D287BC98699C74855F9E3E954780326 +:10329000702CC8B836C10ACC479FEBA0237D7F3481 +:1032A000D32CEB0547E7B8785151E818B741F83A05 +:1032B000D96640D83567A9F67EC74A3EBA39546BFD +:1032C00086AE42C156D208C82E6CD49ED6EC7A4641 +:1032D00091DAAB5D1BD249493E3519505BFC7B7DD1 +:1032E0003FEE571192D78C8AC76D33201ADCA1C8E4 +:1032F00090DAAD7598AF50EC24DE4AE09186ABD5FC +:103300008070662AD10404A6B0594A1F7058365CF2 +:10331000F812EEE2AEEBAFE3A7CFD7C793B2FCBE95 +:103320005F042529EE1135A9F1589B190E7C053F44 +:1033300073E1F12C744E74A537FB645C0C9661E06C +:10334000BD6000C93D1F10E9489DC4BE4F3D87398F +:10335000C3150959B20CB4C0182366C8C394FB58EE +:103360007EC72BAF49C5EBF07AE78E23DAE3734DC6 +:10337000AD993C28B3A2341C825466388166A94AB0 +:1033800082786E22ED05BFEA8648B78972415733CD +:103390004CBFE62A087C3EEB633DAA8BB4E6FCB644 +:1033A0005D0C2DE61BA91E10F34521472CD24EECD7 +:1033B0001188AB24CBC649A605AFFEAF0F5D6254A2 +:1033C0002C88AF73E2B6BC57B20485CA258EA24CD6 +:1033D000F5A79950B55E6CA1CCF85045339417C74A +:1033E000A30A8755E7CBF50ABE23C86E200EFBAFB4 +:1033F00043397283345E9904BB6A5CCFB066C0A562 +:103400007620228DDB02C1338B40629DAC370BAF3F +:10341000D59AC0EE6CF582B7E1B0522D67C1739CAE +:10342000916B585F062768917952E9F2755F5CB03D +:10343000ED63331EE28C14CC62B2E3607157F9B1D4 +:10344000FFE659139A7BBB19C08091B18B676DC39E +:1034500023D944F5D26A25733370C6DE36A72BF51F +:10346000A52EFF90322F14704D1CC2D03EE7F6F609 +:1034700015A19413A59EB1FAE1D446DCFDF7F7F748 +:10348000303FD3357F8E47BC3A6DEEE20A627AB5A3 +:1034900017BD1A60E21C74235E7376D402B65EF028 +:1034A000F53B1ED8FC8FBAC7FEC92EDB8CEF19B8CE +:1034B000F211ABD6977111B65DE7EC3B64C282ADF9 +:1034C0009C4E9764B8ACC9D9B96875E6F6EE7EFC37 +:1034D0004CACCDBD73E009487CDDCE5400F2648D68 +:1034E000A7AD0885DF20B8D34F9BBBD5B8C5BEE4D8 +:1034F000EEA950DD3AA191195D9BC3D93B36817F7E +:103500000000007A8B801908CF2EC56750CCFC9D37 +:103510000A100101D3AF6AA6560F670320A39932A0 +:103520000421C94A5A78EF34CE25C6B91A45F42089 +:10353000091181035489A623C6E03D20D70EEBF67E +:10354000F0F22C48C044122450604244D0645264CB +:10355000484C8602C854132558704345D8745365A7 +:10356000319E6D44C14592265161C246D165D266F5 +:10357000A1F2A7D3C95593275971C347D975D3670A +:103580000208080802ECE72BD2D503BDC3D1502AAC +:10359000C7C4754B3D1D94253C99CDEDF5B86A0C1B +:1035A0000309880A0318172841ADB7E09F6CDE278E +:1035B000D4170C2CE3035FDF4B3E682E2461F85BCD +:1035C00092572457C24C1A2C52684A4CD26C5A6CEF +:1035D000D5DCAE17CA5C1B2D5A784B4DDA7C5B6D7F +:1035E000DCB01895C34D9A2E5369CA4ED36DDA6E6E +:1035F000E01E85D3CB5D9B2F5B79CB4FDB7DDB6FF3 +:103600002210A22AFAB75BB5E58457A954593BFDAD +:1036100016A000415F8EF9C242614113BA15F5D57B +:10362000CBE3E39305C322964883DF576A218FD803 +:10363000D2A5A7E8AA642D73A1E9E77BCDB29A30A1 +:1036400012DA40C1C4C4323454E06254D4E4727417 +:10365000F39FB6C8CCD433355CF06355DCF4737596 +:1036600095FE8C6AC5C5B23655E1E256D5E5F276CF +:10367000E4A31808CDD5B3375DF1E357DDF5F37753 +:1036800048FAD75A6E061AEE1A5492A316516836A3 +:1036900040FACB55E65EBFCC2E553F02361EA696AD +:1036A000D8582A20F82DBCBA655195E1E78B1A1934 +:1036B0000C1BB2F1509D9DEF1F3DCAA45FBDADD55F +:1036C000F17DDEDFC6CC3A3C56E86A5CD6EC7A7C0B +:1036D0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7D6A +:1036E00087D9C95FC7CDBA3E57E9EA5ED7EDFA7E02 +:1036F0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7F3A +:10370000FF03027B4674FF06CFA63B6AE93433C051 +:1037100010A00E719348C81CF8C6C283B71281E28C +:103720006F819F28FF95907E998143E56E88D2999D +:1037300049DACA8E06094357F6D98D401E9652447F +:10374000A488BD78E04616A4706246C4F06656E4CC +:10375000C3A10AF0E85617A5787247C5F87657E571 +:103760005E1C531BE14796A67163C6C6F167D6E699 +:10377000BD7DA13CE95797A77973C7C7F977D7E70C +:1037800068126D1845FDC6030C9A6F881A88D9CF48 +:10379000EAE7468F0141A055049B6E89F44CA2AB29 +:1037A0003B1AF35AC00B49F7358E84E96CADDA1138 +:1037B00066CA2C0C0829414E3D9B066864EE3C14F9 +:1037C000664E74A4E24E1EAC726A4ECCF26E5EEC93 +:1037D000AAB2A379EA5E1FAD7A7A4FCDFA7E5FED89 +:1037E00040EF56EDE34F9EAE736BCECEF36FDEEE41 +:1037F000BD45E93BEB5F9FAF7B7BCFCFFB7FDFEF2F +:103800001CA28930F5990EF2F4C5359264D9F1F70E +:1038100062548FD368C83BAFE7CF1AD4ECA95FBF1F +:10382000FA8FA2691D4F61DE6BB0DFD75D04D02631 +:10383000F755A169D06483F163F6C5A8CBF153BFF6 +:1038400064C22694E4C636B474E266D4F4E676F430 +:103850006CD22795ECD637B57CF267D5FCF677F5B8 +:1038600065C3A696E5C7B6B675E3E6D6F5E7F6F600 +:103870006DD3A797EDD7B7B77DF3E7D7FDF7F7F788 +:103880005F940E6C1E19D7123646EE63C25334BADB +:10389000FA954FD7719F3B91FEDCA3721EAD5F9DE1 +:1038A00073908ACE90264CA9332F96F2687E34D935 +:1038B00059DD0BD9A31B180571BAEBB660B77AFCBA +:1038C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFC48 +:1038D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFDD0 +:1038E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE18 +:1038F0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFFA0 +:1039000000000000800410201020404090245060EF +:103910000810010188141121183041419834516177 +:1039200001018002810590221121C0429125D062BF +:1039300009118103891591231931C1439935D16347 +:1039400040400204C044122450604244D064526497 +:1039500048500305C854132558704345D87453651F +:1039600041418206C14592265161C246D165D26667 +:1039700049518307C95593275971C347D975D367EF +:1039800002080808820C182812284848922C586807 +:103990000A1809098A1C19291A3849499A3C59698F +:1039A0000309880A830D982A1329C84A932DD86AD7 +:1039B0000B19890B8B1D992B1B39C94B9B3DD96B5F +:1039C00042480A0CC24C1A2C52684A4CD26C5A6CAF +:1039D0004A580B0DCA5C1B2D5A784B4DDA7C5B6D37 +:1039E00043498A0EC34D9A2E5369CA4ED36DDA6E7F +:1039F0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F07 +:103A0000048020108484303014A0605094A470701E +:103A10000C9021118C9431311CB061519CB47171A6 +:103A20000581A0128585B03215A1E05295A5F072EE +:103A30000D91A1138D95B1331DB1E1539DB5F17376 +:103A400044C02214C4C4323454E06254D4E47274C6 +:103A50004CD02315CCD433355CF06355DCF473754E +:103A600045C1A216C5C5B23655E1E256D5E5F27696 +:103A70004DD1A317CDD5B3375DF1E357DDF5F3771E +:103A800006882818868C383816A8685896AC787836 +:103A90000E9829198E9C39391EB869599EBC7979BE +:103AA0000789A81A878DB83A17A9E85A97ADF87A06 +:103AB0000F99A91B8F9DB93B1FB9E95B9FBDF97B8E +:103AC00046C82A1CC6CC3A3C56E86A5CD6EC7A7CDE +:103AD0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7D66 +:103AE00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7EAE +:103AF0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7F36 +:103B000020020480A00614A0302244C0B02654E055 +:103B100028120581A81615A1383245C1B83655E1DD +:103B200021038482A10794A23123C4C2B127D4E225 +:103B300029138583A91795A33933C5C3B937D5E3AD +:103B400060420684E04616A4706246C4F06656E4FD +:103B500068520785E85617A5787247C5F87657E585 +:103B600061438686E14796A67163C6C6F167D6E6CD +:103B700069538787E95797A77973C7C7F977D7E755 +:103B8000220A0C88A20E1CA8322A4CC8B22E5CE86D +:103B90002A1A0D89AA1E1DA93A3A4DC9BA3E5DE9F5 +:103BA000230B8C8AA30F9CAA332BCCCAB32FDCEA3D +:103BB0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEBC5 +:103BC000624A0E8CE24E1EAC726A4ECCF26E5EEC15 +:103BD0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FED9D +:103BE000634B8E8EE34F9EAE736BCECEF36FDEEEE5 +:103BF0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEF6D +:103C000024822490A48634B034A264D0B4A674F084 +:103C10002C922591AC9635B13CB265D1BCB675F10C +:103C20002583A492A587B4B235A3E4D2B5A7F4F254 +:103C30002D93A593AD97B5B33DB3E5D3BDB7F5F3DC +:103C400064C22694E4C636B474E266D4F4E676F42C +:103C50006CD22795ECD637B57CF267D5FCF677F5B4 +:103C600065C3A696E5C7B6B675E3E6D6F5E7F6F6FC +:103C70006DD3A797EDD7B7B77DF3E7D7FDF7F7F784 +:103C8000268A2C98A68E3CB836AA6CD8B6AE7CF89C +:103C90002E9A2D99AE9E3DB93EBA6DD9BEBE7DF924 +:103CA000278BAC9AA78FBCBA37ABECDAB7AFFCFA6C +:103CB0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFBF4 +:103CC00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFC44 +:103CD0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFDCC +:103CE00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE14 +:103CF0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFF9C +:103D000000000000800410201020404090245060EB +:103D10000810010188141121183041419834516173 +:103D200001018002810590221121C0429125D062BB +:103D300009118103891591231931C1439935D16343 +:103D400040400204C044122450604244D064526493 +:103D500048500305C854132558704345D87453651B +:103D600041418206C14592265161C246D165D26663 +:103D700049518307C95593275971C347D975D367EB +:103D800002080808820C182812284848922C586803 +:103D90000A1809098A1C19291A3849499A3C59698B +:103DA0000309880A830D982A1329C84A932DD86AD3 +:103DB0000B19890B8B1D992B1B39C94B9B3DD96B5B +:103DC00042480A0CC24C1A2C52684A4CD26C5A6CAB +:103DD0004A580B0DCA5C1B2D5A784B4DDA7C5B6D33 +:103DE00043498A0EC34D9A2E5369CA4ED36DDA6E7B +:103DF0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F03 +:103E0000048020108484303014A0605094A470701A +:103E10000C9021118C9431311CB061519CB47171A2 +:103E20000581A0128585B03215A1E05295A5F072EA +:103E30000D91A1138D95B1331DB1E1539DB5F17372 +:103E400044C02214C4C4323454E06254D4E47274C2 +:103E50004CD02315CCD433355CF06355DCF473754A +:103E600045C1A216C5C5B23655E1E256D5E5F27692 +:103E70004DD1A317CDD5B3375DF1E357DDF5F3771A +:103E800006882818868C383816A8685896AC787832 +:103E90000E9829198E9C39391EB869599EBC7979BA +:103EA0000789A81A878DB83A17A9E85A97ADF87A02 +:103EB0000F99A91B8F9DB93B1FB9E95B9FBDF97B8A +:103EC00046C82A1CC6CC3A3C56E86A5CD6EC7A7CDA +:103ED0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7D62 +:103EE00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7EAA +:103EF0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7F32 +:103F000020020480A00614A0302244C0B02654E051 +:103F100028120581A81615A1383245C1B83655E1D9 +:103F200021038482A10794A23123C4C2B127D4E221 +:103F300029138583A91795A33933C5C3B937D5E3A9 +:103F400060420684E04616A4706246C4F06656E4F9 +:103F500068520785E85617A5787247C5F87657E581 +:103F600061438686E14796A67163C6C6F167D6E6C9 +:103F700069538787E95797A77973C7C7F977D7E751 +:103F8000220A0C88A20E1CA8322A4CC8B22E5CE869 +:103F90002A1A0D89AA1E1DA93A3A4DC9BA3E5DE9F1 +:103FA000230B8C8AA30F9CAA332BCCCAB32FDCEA39 +:103FB0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEBC1 +:103FC000624A0E8CE24E1EAC726A4ECCF26E5EEC11 +:103FD0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FED99 +:103FE000634B8E8EE34F9EAE736BCECEF36FDEEEE1 +:103FF0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEF69 +:1040000024822490A48634B034A264D0B4A674F080 +:104010002C922591AC9635B13CB265D1BCB675F108 +:104020002583A492A587B4B235A3E4D2B5A7F4F250 +:104030002D93A593AD97B5B33DB3E5D3BDB7F5F3D8 +:1040400064C22694E4C636B474E266D4F4E676F428 +:104050006CD22795ECD637B57CF267D5FCF677F5B0 +:1040600065C3A696E5C7B6B675E3E6D6F5E7F6F6F8 +:104070006DD3A797EDD7B7B77DF3E7D7FDF7F7F780 +:10408000268A2C98A68E3CB836AA6CD8B6AE7CF898 +:104090002E9A2D99AE9E3DB93EBA6DD9BEBE7DF920 +:1040A000278BAC9AA78FBCBA37ABECDAB7AFFCFA68 +:1040B0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFBF0 +:1040C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFC40 +:1040D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFDC8 +:1040E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE10 +:1040F0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFF98 +:1041000000000000800410201020404090245060E7 +:10411000081001018814112118304141983451616F +:1041200001018002810590221121C0429125D062B7 +:1041300009118103891591231931C1439935D1633F +:1041400040400204C044122450604244D06452648F +:1041500048500305C854132558704345D874536517 +:1041600041418206C14592265161C246D165D2665F +:1041700049518307C95593275971C347D975D367E7 +:1041800002080808820C182812284848922C5868FF +:104190000A1809098A1C19291A3849499A3C596987 +:1041A0000309880A830D982A1329C84A932DD86ACF +:1041B0000B19890B8B1D992B1B39C94B9B3DD96B57 +:1041C00042480A0CC24C1A2C52684A4CD26C5A6CA7 +:1041D0004A580B0DCA5C1B2D5A784B4DDA7C5B6D2F +:1041E00043498A0EC34D9A2E5369CA4ED36DDA6E77 +:1041F0004B598B0FCB5D9B2F5B79CB4FDB7DDB6FFF +:10420000048020108484303014A0605094A4707016 +:104210000C9021118C9431311CB061519CB471719E +:104220000581A0128585B03215A1E05295A5F072E6 +:104230000D91A1138D95B1331DB1E1539DB5F1736E +:1042400044C02214C4C4323454E06254D4E47274BE +:104250004CD02315CCD433355CF06355DCF4737546 +:1042600045C1A216C5C5B23655E1E256D5E5F2768E +:104270004DD1A317CDD5B3375DF1E357DDF5F37716 +:1042800006882818868C383816A8685896AC78782E +:104290000E9829198E9C39391EB869599EBC7979B6 +:1042A0000789A81A878DB83A17A9E85A97ADF87AFE +:1042B0000F99A91B8F9DB93B1FB9E95B9FBDF97B86 +:1042C00046C82A1CC6CC3A3C56E86A5CD6EC7A7CD6 +:1042D0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7D5E +:1042E00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7EA6 +:1042F0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7F2E +:1043000020020480A00614A0302244C0B02654E04D +:1043100028120581A81615A1383245C1B83655E1D5 +:1043200021038482A10794A23123C4C2B127D4E21D +:1043300029138583A91795A33933C5C3B937D5E3A5 +:1043400060420684E04616A4706246C4F06656E4F5 +:1043500068520785E85617A5787247C5F87657E57D +:1043600061438686E14796A67163C6C6F167D6E6C5 +:1043700069538787E95797A77973C7C7F977D7E74D +:10438000220A0C88A20E1CA8322A4CC8B22E5CE865 +:104390002A1A0D89AA1E1DA93A3A4DC9BA3E5DE9ED +:1043A000230B8C8AA30F9CAA332BCCCAB32FDCEA35 +:1043B0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEBBD +:1043C000624A0E8CE24E1EAC726A4ECCF26E5EEC0D +:1043D0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FED95 +:1043E000634B8E8EE34F9EAE736BCECEF36FDEEEDD +:1043F0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEF65 +:1044000024822490A48634B034A264D0B4A674F07C +:104410002C922591AC9635B13CB265D1BCB675F104 +:104420002583A492A587B4B235A3E4D2B5A7F4F24C +:104430002D93A593AD97B5B33DB3E5D3BDB7F5F3D4 +:1044400064C22694E4C636B474E266D4F4E676F424 +:104450006CD22795ECD637B57CF267D5FCF677F5AC +:1044600065C3A696E5C7B6B675E3E6D6F5E7F6F6F4 +:104470006DD3A797EDD7B7B77DF3E7D7FDF7F7F77C +:10448000268A2C98A68E3CB836AA6CD8B6AE7CF894 +:104490002E9A2D99AE9E3DB93EBA6DD9BEBE7DF91C +:1044A000278BAC9AA78FBCBA37ABECDAB7AFFCFA64 +:1044B0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFBEC +:1044C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFC3C +:1044D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFDC4 +:1044E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE0C +:1044F0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFF94 +:1045000000000000800410201020404090245060E3 +:10451000081001018814112118304141983451616B +:1045200001018002810590221121C0429125D062B3 +:1045300009118103891591231931C1439935D1633B +:1045400040400204C044122450604244D06452648B +:1045500048500305C854132558704345D874536513 +:1045600041418206C14592265161C246D165D2665B +:1045700049518307C95593275971C347D975D367E3 +:1045800002080808820C182812284848922C5868FB +:104590000A1809098A1C19291A3849499A3C596983 +:1045A0000309880A830D982A1329C84A932DD86ACB +:1045B0000B19890B8B1D992B1B39C94B9B3DD96B53 +:1045C00042480A0CC24C1A2C52684A4CD26C5A6CA3 +:1045D0004A580B0DCA5C1B2D5A784B4DDA7C5B6D2B +:1045E00043498A0EC34D9A2E5369CA4ED36DDA6E73 +:1045F0004B598B0FCB5D9B2F5B79CB4FDB7DDB6FFB +:10460000048020108484303014A0605094A4707012 +:104610000C9021118C9431311CB061519CB471719A +:104620000581A0128585B03215A1E05295A5F072E2 +:104630000D91A1138D95B1331DB1E1539DB5F1736A +:1046400044C02214C4C4323454E06254D4E47274BA +:104650004CD02315CCD433355CF06355DCF4737542 +:1046600045C1A216C5C5B23655E1E256D5E5F2768A +:104670004DD1A317CDD5B3375DF1E357DDF5F37712 +:1046800006882818868C383816A8685896AC78782A +:104690000E9829198E9C39391EB869599EBC7979B2 +:1046A0000789A81A878DB83A17A9E85A97ADF87AFA +:1046B0000F99A91B8F9DB93B1FB9E95B9FBDF97B82 +:1046C00046C82A1CC6CC3A3C56E86A5CD6EC7A7CD2 +:1046D0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7D5A +:1046E00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7EA2 +:1046F0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7F2A +:1047000020020480A00614A0302244C0B02654E049 +:1047100028120581A81615A1383245C1B83655E1D1 +:1047200021038482A10794A23123C4C2B127D4E219 +:1047300029138583A91795A33933C5C3B937D5E3A1 +:1047400060420684E04616A4706246C4F06656E4F1 +:1047500068520785E85617A5787247C5F87657E579 +:1047600061438686E14796A67163C6C6F167D6E6C1 +:1047700069538787E95797A77973C7C7F977D7E749 +:10478000220A0C88A20E1CA8322A4CC8B22E5CE861 +:104790002A1A0D89AA1E1DA93A3A4DC9BA3E5DE9E9 +:1047A000230B8C8AA30F9CAA332BCCCAB32FDCEA31 +:1047B0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEBB9 +:1047C000624A0E8CE24E1EAC726A4ECCF26E5EEC09 +:1047D0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FED91 +:1047E000634B8E8EE34F9EAE736BCECEF36FDEEED9 +:1047F0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEF61 +:1048000024822490A48634B034A264D0B4A674F078 +:104810002C922591AC9635B13CB265D1BCB675F100 +:104820002583A492A587B4B235A3E4D2B5A7F4F248 +:104830002D93A593AD97B5B33DB3E5D3BDB7F5F3D0 +:1048400064C22694E4C636B474E266D4F4E676F420 +:104850006CD22795ECD637B57CF267D5FCF677F5A8 +:1048600065C3A696E5C7B6B675E3E6D6F5E7F6F6F0 +:104870006DD3A797EDD7B7B77DF3E7D7FDF7F7F778 +:10488000268A2C98A68E3CB836AA6CD8B6AE7CF890 +:104890002E9A2D99AE9E3DB93EBA6DD9BEBE7DF918 +:1048A000278BAC9AA78FBCBA37ABECDAB7AFFCFA60 +:1048B0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFBE8 +:1048C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFC38 +:1048D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFDC0 +:1048E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE08 +:1048F0006FDBAF9FEFDFBFBF7FFBEFDFFFFF7735E2 +:104900005ABF680362F794AD2A901BEFC92AAFAD76 +:1049100047E38D409A72792C2690294C08C7DD6CAC +:104920007F076181D3C4B439B5053D4DEA2D35DD2E +:1049300037B0E90E9B277A670B4F2A076212709CEB +:10494000F422F968F8BB5A60F116A9774F9DC07F31 +:1049500068BAF68CD256A064C837703192749B0640 +:10496000FEDA738F51824CFB501729157313F6CD65 +:1049700069DBA7F862737E45E3E2B1E8975AF53246 +:10498000109EE34CB8BC496928981309CCCE1CC5CD +:10499000AE7AFE6CB8E3F026E74721443A5E77B67C +:1049A00039B983A5BBFC3B2B2BC76447C31FFCC88D +:1049B000333D6008EBFD5624090B220FC03DA20BCE +:1049C000229C56D169C93E2A03E0AFEA8648A7CDAA +:1049D000DA3AFC68CA787842628B75287A0E39F523 +:1049E0003B6E77018E4F3BA8869AA40FEB5D3EC1CC +:1049F00073A6064E5CAE1FA2638AB9214B1F280A1C +:104A000094F302BBFB7C307002C2005EEAA291F319 +:104A1000B063A5BC2C871B555394E3EBC66019B259 +:104A20007D854093059278716BA701D1DA567C336E +:104A30007521DCBCB324DA3C56D31636E3B310F050 +:104A4000161CC970542CF6F906FF0815608662889A +:104A500074E065BA82FB2A60A39290304C96841071 +:104A6000D5F003B79B15B299EF1FF29B2FED0FB94D +:104A7000EDA3C1DDC4F1C4CE650A7E6AE5323964B6 +:104A8000A2AC95B906087C082E570848CE5FF4758D +:104A9000786BAD942E8F135D60BF4D5F654DDAF975 +:104AA0003FB8099BBFA9707969AF0989075E747720 +:104AB0005D58427FD17FBD96D7E248AD208FDDCED5 +:104AC00038CF8B5D19460D3CFBCC8F876D7F143D35 +:104AD0005C50C059E9AE5FC2E549010261B35F6D48 +:104AE00051ABC213FD369E2557D88C217E936F02A1 +:104AF0007569ECB08EAB9F323F193C1E6507EBB277 +:104B000036606C8D1479B7E10A92156F3022CE1F92 +:104B100012A20EC09026570E00C1C1D50C54AEA3F0 +:104B200033B16FC65E74B603954177A76A27757D6A +:104B300013E0EB2C0965F7E49DF45B9E3920206FB0 +:104B40001E45A71BB28AFDC016CAAFB7C89DFAE9B9 +:104B5000CC30F4E04C34E8C0D40D8DF6EA41BCA171 +:104B6000D521A2295AA5B20917D6E2190A4077A77A +:104B700051A8A381D15F4A6847DBA6C3C795B51E7C +:104B800073616787DC09E9A72828FF65CBFEFFF47E +:104B9000541CE4860681E224AA44EEACF0234CA81F +:104BA000A339ECAA17703FEB975B4CDCAAD12166C6 +:104BB00079FB66EFC91F6A6684D924C8E1DEB5E8CF +:104BC0002DF7AF00E331F9ED0B142FC88C697AE1B2 +:104BD000FAAA7F2C512E9FB2CDCB3CCDC280A281B0 +:104BE000A7CECDEE98086758124F3A4D0CED899F2D +:104BF0003BA80B02D02F1FB9BB7F3A1B185B7E105E +:104C00001A844C33760270808F20634C145CF95DFB +:104C10008861A99CBA27DE1226B0F7908624750D0C +:104C20005B8545319D7918BF2FA157DF6134D20DC7 +:104C3000BD6337321626D71C5D6AB6DEAFB6287064 +:104C4000C0A0028F1FE197D8CBCFD9098BC2152501 +:104C50002DA4036AAD4013781C12B4DA04304DB4AD +:104C600000B56496BCDC706BA40D5F56E347457BD2 +:104C70005373CF9A7824D13AD1D7D4C3A315F35A1A +:104C80007279A815F4AAB367CD8DCD77B65081B9E6 +:104C9000BE784E9EEFE8EBF83A58497405CEFDE633 +:104CA00075F647FEFE1C594C97B56051890E710C84 +:104CB000393B46DF1561AD766F8A4C5A2F405C64F4 +:104CC00074C6C5D8373D54BAE41C7C5125DC5A71F2 +:104CD000CAFECE32A1069E62DE885972495E7943D1 +:104CE0005D7B0831BF119AB8A51DCA71894E15FDAB +:104CF000B9289D845BBD9B24DBDC4E7E500F8B5E10 +:104D000050EAA50BD08091A0024ABF52F0FDA46DDD +:104D100058948081485626AAB4D89D8CC0FF8C6ECA +:104D20000BF17EA3B9B79832AB913F9D6E027164CF +:104D30003395003838F738B2FEB924952D4A72659C +:104D4000F422DF4600065C6656E4C37FD48654D85E +:104D50004C23290CBDD092C7AF416107B8AD86681E +:104D60006DD9E9256928942A0BCE61CDF0E15F0960 +:104D7000CED3A0E90916F321716162B8C1719168BF +:104D800038EA6B99424FEA255AA8CAF25825F9C366 +:104D90005D6AAA89D39EFCD64087214A7FCBB06644 +:104DA00015A98E46C904B963B84BEB1AEB0D3851FF +:104DB000D01939088A6BAAFFDB7B89C0DECA5BD1B8 +:104DC0007AB7A6010CC3BB27486D6BCCEC00795FAA +:104DD000327FF6029AAF9FA09A3FEEB882D9D9D718 +:104DE00023A911F205BDB68FECDBD22EB3AC106354 +:104DF0002BB9100299FB704B0BFD047E749F59D5A3 +:104E0000B062263C7B8CD5360324E1781520F9F27C +:104E10001F603FB038EB9221DCF3E12A982442F77F +:104E200076F3033FDD526D3D2D5F4C5FCB04F8C53B +:104E30005D62259E376AA1FE1D5DA111274BE1BE73 +:104E400014C8A2B4F822B01EAB11C114600605CE7E +:104E5000E71A98EA369209770A74E262250F753EDE +:104E6000E9647775A3A781526B41E45A0A04CD86A1 +:104E70002D0D9D1A24F8B5899DB3ADA80577B8D935 +:104E80005454C37CDF1AE5F7F95969FA696BFA02E1 +:104E900026742F75D64B3F554E3CE8FA53BCD8AF1D +:104EA0003FE9B55886F25F3C494BECF793CF267C3F +:104EB000FB59A4907C1FFEFB27474556D72440F79B +:104EC000CD2A8611DABEC52796AA6381EE4CDBAEE9 +:104ED00071B85B966242380F3E5E1350853900FF11 +:104EE000C82B2AEF63BB4DC32FCE17510C908513EF +:104EF0004B25AB0A9557C77DB36BA3550261CC7F99 +:104F000021004CEC0FF0045D32C027116744EF6CB8 +:104F100041F9E67E6851E3BAC7C21560C7D607FA01 +:104F2000F55DAA5E5B83158A2783778F75A29782CA +:104F300092E17285CB616AB369C0414E9A4122F316 +:104F40003846AA89D8A9F70BC7C240BA5B84215E4C +:104F50007EF2018968D2E02528F6C645018D51AE62 +:104F6000394FE571B47CB45D919338672EC5E9166D +:104F70006BA3C788EFF77EA4410387CC218B8C1CE1 +:104F8000E9A7AD5218E69A5460F6A7AC08696F9E7F +:104F9000EA58C1266A5CEBEB12AFAEC258BAD4A293 +:104FA0005B2C2D7059076165F369088851D029F889 +:104FB0008FEB7284072A8D66BB452EC0B3365F2106 +:104FC0000293D3814EDC42A6AF9AB06D05EA93837B +:104FD0003E3A55068A8265A0207B49C13A29F06095 +:104FE0001CABA623632E2DEF23EF4F4E28B3A17FDA +:104FF0006FA78F9AA142BCEFDDFF4E2D9BA3E1E08E +:10500000D3B306D264C576B6CB26E9AE702337900B +:105010003696045018F406113A36E89CDC7B75B3DA +:105020000D93056D6F92156DF57C8FD84A18F0D3EE +:1050300092E3BD98013260D0018BE3DF153EC68755 +:1050400034CAA634CC27973DF966E7033406892F86 +:10505000C7189C6A1BEB31B9D49F92DA340F908E3B +:10506000C96673F5E1A7E23DB5A1A894AD1AFE6D3E +:105070000D0F999AEFB5D697C97766133E1BF7B512 +:10508000724D1F6C0D448747EFC8E15E0C3183EA17 +:1050900094082D918E1FBF731656CC5966FE29FFBA +:1050A0009D19BE88C76F2767176BA8980D31FAD670 +:1050B000397331562F1B3439474B137A72BF5C0456 +:1050C000AD348291FECB62B8B6A8209EAE115A874D +:1050D0003465479EB4DF9CA610984DD0817A58B6AF +:1050E000A8978F6E0C4DE5425BDB6C747003FE730A +:1050F000AF99EF144BA9C2B4BF7F6ECB6FFFFFFF18 +:1051000060C1CA0DE0CDDC2D97A25FA0B8565372E6 +:10511000C281A207901D930B9871E04767C851F4B4 +:105120007FB16104E2C5D6DF2951C849F1F1956F1D +:10513000456020DCEF771CA55433609CCF0EB7216F +:10514000A7804CA98D266E8B6EC14448DD5A43263C +:105150000C233E84F0E8F83D0174CE2674E6136F0C +:10516000DAD38A0ECCC7DB3C41E54BB84A393B6EFB +:10517000B2AE6AFE90427688F2D416595D84D2E7C8 +:10518000B66A0E4402CC0C2EA64AB7C1123BE52AE1 +:1051900032E2A5048E7C1D01F6478B59BAB65AEA55 +:1051A000848B83E3CC0B39A39375E9683F3C6DE3B3 +:1051B000749BC274676F7208A0ABC94337BF9E6906 +:1051C000EED709CC113F6C402F87DF918C2D56C153 +:1051D0000248432E4A7FD76F321ABC0FD2EDB26518 +:1051E0007DA9482E9A475C26FAAB6BB1DBAA188ED4 +:1051F000471277B66727FB260386220C1FF8D5E5F2 +:10520000C4C67C8DBC6BA5ED045C6012326399B39F +:10521000C8126A6EB4670B54561027C1E5C71BF855 +:10522000A9045FAF2C07F7F0A42A1D5972DB917611 +:10523000A2730DEEB56687357D65A85EBD3FF06350 +:10524000E0FF5FBFCCB6D96C94009DF614A30DDFD0 +:10525000CED982CA65B610A408E1417469B5753229 +:105260003DC55F54BB88307C81E3E6F619E519FC47 +:10527000F9B321BD9725DBE4B073E8F119098E8CF1 +:105280007E0A735C4CD99907D22D66D2F675FC75EF +:1052900042E92F55A2BB512A7E6DF754A44F5B7F84 +:1052A0003FE99C1CE759E478D08949F2CFA9F1770E +:1052B0004A1BEEA9B128CF38E059D95AD32E5884C9 +:1052C000BB4CA3A3B8CADBBF6849C95AB71455C7BA +:1052D0002838289D96D893C5F28B09AB23107B3FC5 +:1052E0000FC543E7C93E36331B7A4BA1DF053EB3FA +:1052F00049A42B8123AEF2B93F2DA15005648C1433 +:105300001BE0A83DC0C7DEADF35D86C488B5324D55 +:1053100084901EA5EB74FE02FAB04E67D8E209EC49 +:1053200059A3C212DFA216688AB1C4C8E75754FD58 +:105330001181C5C11D757E6001CCA4E3A33547E989 +:10534000DFC68FD49E40FFABB020BD3137952849D2 +:10535000DC30854FD0A556C0400DC6C83C852945D8 +:105360001F442759B3A67DC2D19D33CA2607C68ADA +:10537000EED70E38D1A4DEE547D2C1CBF57534A502 +:105380008E8F0D48C2DA0AA56A2E45C524AC1B20B3 +:10539000328FF8E5D4B69F63C14538C291508C5521 +:1053A00043D2DB87DDBA30A753FBAEC78BD0ABEA65 +:1053B000EFE570E9EA7D6ACEBB7A6C300664DBAB60 +:1053C0002A46E7354E347EA00DEEC7325E93E1B734 +:1053D0006C238FC0B8BFF4C9AE94CCC0F3FA3CBB09 +:1053E00005378D0E9D4977A165097113F350C73BB1 +:1053F000AB18C320D3783E0084B96E102002A0F908 +:105400001C1DDB961A823DBDF69344A38A06F9065D +:10541000D7102E586CD59910FF3022790B17734A8C +:10542000EF1B05449805FFCDA5D0D1D9BDA3FD4EF6 +:1054300015A3A12C7CE48F6005F4EBD01E35B25B84 +:105440005A63663BA6B5773DE41E4D2F2B9649BCAB +:105450000AAE24556B91DE1D540368D53C1250787A +:10546000B5B0DFF8C55536BC5D1BCD6D2CE71749CF +:1054700053AE6D9C8FAD5E3F5B8BA4AC834A1E0424 +:1054800099C0D584F6F938900E3BEE128E2B7272CD +:10549000821FF8FBD5FCA3E40641E2DF80C61D268F +:1054A0002689E4469FC83E103CC91FBF608F5D3B04 +:1054B0004670ABD7CF4E02F972B14C6D40CC849799 +:1054C0006E1BC7DFFCCCFC47F46EC8BE5A06BA3A66 +:1054D000CE24DA912E99360846057530E84394B902 +:1054E000A7898E6BEFCB16462AE4037FBF779DF624 +:1054F00057A42E92E1E5FE4AAB056D77C54FD0501B +:10550000A46260A98C3414DF92D1054099D741C0C0 +:10551000D4E38D0C48A7386396743641A2C77BCC80 +:105520007F076181DAE0EB3F4F743FE64244DA23C4 +:105530000BF3C9F07F704D2BC0D4A2CACD72E20725 +:10554000CA22F161C2A67123EA9E528910262B69F4 +:10555000881282AA13369CA3B40F8145F074F2EC32 +:1055600079BA6B05D7E5942AAEE5B918A3748624F9 +:10557000ED2B20628B15B865E2E3CB4D5D159725C9 +:1055800022D28585BC4C398B046CF395706C5C45DC +:10559000308B48A60A2EA67CB5CB0CBDCECFDDE461 +:1055A00065586372BD60F32541CC1577A0DD33CB20 +:1055B000829B8E05F3E1BAD0957E2023C9F8320F85 +:1055C0007DAA6927EA4CBBD346ECC34AFA6C395C26 +:1055D0006227A84F752C5324649A2946E2CE57FDC2 +:1055E00055E98C22D948BB7E4148210AABE95BD7FB +:1055F00063592A86CD22FA1F9B3FA7541B3FDBE449 +:1056000054F72C9DFB97C768C85D84FDEC20F170B2 +:1056100037CE91390E877469260124CECC30F0251F +:105620007E7A59CEA37AAD369B91E4EDADC5ACDF61 +:105630000C93AD51ABC0AC71A80CE7C65DF3D1FCC7 +:10564000841F491C6CF91374461989107B4430B4CB +:10565000E005416A97D035799CB60F177597758B21 +:10566000C5A2A6541EC9C9326B03805D15EBA534D3 +:10567000E1552A7C98B75157023F6CAA9577F43AC6 +:10568000AA90BB672AF6583529F29DC4CEA889F79F +:10569000A20A28B4DC78D25DC2518D8281DE8E3BB5 +:1056A00079DC7CD2F98B513538D63101CFFCFE76CE +:1056B00085E9299DB1D11A5EADFE14DDB7BD0C742C +:1056C0004ECC835C44342E8734E89FDA16AA603EC1 +:1056D00056DC825D81839A34727A0B7C728EA5824D +:1056E00027107F13C7CFAE385329821CFF22F92C15 +:1056F000164E4E99CD25F38421FF0250E5630C111F +:1057000018FCA88D9074EFE25666046F88D5766F0A +:10571000165E731E1B5E13C60676CA67E20A3DE27A +:10572000DE32993D79E3689AE6512FCAE9237DF785 +:1057300085609875A1086A77B5F3EC16C051F6A399 +:1057400064A202A9B89AEA87D314B1D4748450A889 +:10575000070D0189D62ADD1C91B5BA43FED7FF910A +:10576000507CA4C421984ECACB9CC07DA497DAE992 +:10577000763165A745C5DFAD590D05C769F3004909 +:105780005C5BE5D05915E73CB85901498E045AE4F1 +:10579000940BEC268C5EF202B0C0F13A3DC15BE5A1 +:1057A000C0F8CD89D8FE23CA37D02D69AC4D1D6015 +:1057B00021E8C4165606BFB4FB013410A45D9E1B3D +:1057C000E0CE8F8C6D09F7A77AAA48E032926BEA97 +:1057D0008ADE86166E9E5656DA09EC4E4E1CA0AF37 +:1057E000395B2D9585321328135BF161FDA77F315D +:1057F000B659B88FEBA3DFED23FF46FBF465D9B7AD +:1058000004C2603B9ACB97F28693617FEA44705D55 +:10581000FB8168F99FDAC9891AFF285C844CD9FC9E +:10582000AF83CF7A09C64CCA39B0F11AE523755156 +:1058300013C2511B1EDFB36A43FF0EABC2C4D7B104 +:10584000444AC312E4010552260260F89422ABF9DF +:10585000C4B7E5B50F162FAEDC81C4568574702928 +:105860006503BED45F58A47B50D3CA79129997F2CE +:1058700025D70ED788A16DA525776236C58777E134 +:1058800017CB3C9C2DFD011948EA90F09EA0979CF7 +:105890004775C67155E15581655F161CC64FDEB967 +:1058A000A30F210A9F705DD988CBE4288C4D504707 +:1058B0008CCF5892D1D64818FF08C476811FFBF7C9 +:1058C000A689AC1D5C543F2CB613F9B2BEFFF95F3C +:1058D000166A0CDFB6CA39B11CFA6E1DFEFE7FFDDA +:1058E000BA382A3387166BB3C8796E03375498BF1A +:1058F000C7EE9C99EF2FFFB0BFB9EF54FFFFFFFF3A +:10590000A7A0E9037F861B892E94CFC6F71536CF53 +:105910005C486A429176792CCAB5AA82E633F0B027 +:1059200051639CA9A10912081161D8EF3157B269DE +:105930003B02F06076979ACA1F89414C62C50FC23C +:10594000208D020915EDDAB7FCBD41F5F11232BB2D +:1059500036E8E20348511569A38FA2C623FC5549D6 +:105960003FEC2E0B1047D6D1086A27C72E17B099E7 +:10597000118F208CECA43067A68FF0830EF15EE9C6 +:1059800022100E24424F828549C8338240DFDCE575 +:105990005E072FADB4AC6F861A076F9CA200B28A67 +:1059A00085360CA5D53073192D8C7711C1CD330EEA +:1059B00096BC6008DA5A70884FBDAA1D77AEFB63AB +:1059C0003C75E148FFC89BE4922B340E65112D6CA9 +:1059D000EE3AB00B4A3DA780817878A91A78979063 +:1059E00079F985A1030B0824FFBB36F78A7B3FD1E9 +:1059F00004622A0698CEAD82E182CD0F4E8EBDB2F2 +:105A00004C95263CB53C2034F74D650B3837027871 +:105A1000F4AB0F53E57BCA9CC45480FE63C703F00C +:105A2000CF90C61601013DA215D31B105121796EEE +:105A3000A527A77FD8AB8326CFC2873F1D4B0C1D60 +:105A4000E88B23AD86B5473FFF931BF58DF2745865 +:105A5000E00D20BCF42B1138EB8950B185FF964343 +:105A6000858388545F47E585CEA6EC698461777BA2 +:105A7000FAA8D4170651366C9DB2D11569174EF8A5 +:105A8000A0B3168DD584B858700D6B3A756C303A4A +:105A90005A1C5CC17363B4BFF94BEDD49808F92765 +:105AA000D6B68ECF47CAE824D7EA79DBBB79B0995E +:105AB000A3EA93BD87DDBDC04D59023FA10876FD25 +:105AC0001FDF2C3079ECD39EFE8A59488EE8CFF345 +:105AD000E3A7B60639DD2B99699A481D3292D8188A +:105AE00090875F42078BC6C14BA768E4CF7D78756E +:105AF000ED5D26661A7473AC43A76985621F7974DD +:105B0000E0444D2F47F52A0DEBC23B0AB1353AE38D +:105B1000FD6127C396BA374C38093783EB2733E545 +:105B2000F024252DF3997FF10F867B998F93964D65 +:105B300081C36E90AF657EF0A670B2C84E453E60E0 +:105B4000E003C18235D52CACD60D3A6B21953CFFD4 +:105B5000224624C54A20E8702E9A8387A277F4480B +:105B6000AAFA277961262ABDA30DB06957E353A885 +:105B70006585EC6476294BA8D1B5A487E606A2EC2E +:105B80009668E7BBDCA3F5BBEDFE3FC3CC9FB70B2C +:105B90007CE96B24D4B6F69AE33A4B0216AD73E374 +:105BA00019F8EE25F378D4276CFF70A9CD9B352921 +:105BB000F95C47E895B269F87CC7EE307CBB54F7D6 +:105BC00061BB3C8CD060BDD30A193365B5EC7D3226 +:105BD000D5FAAABCB056BC84D1F86C13654F7C8151 +:105BE0005D36AD3FE2CB13D72B0BCAE7CB0F90430B +:105BF000AB19FFCD5EB70F62439BCBE63F942316F4 +:105C0000F17DCD8373F4DFB30CB2C770B4E63845D1 +:105C10002C6B24D39386DE7206215B7E9CA6E172F8 +:105C2000432F5309FB3F4B42E7A101BE632371356C +:105C3000ADED581393233A456BC12F801806F39F9F +:105C40003ED285BC35C472432380995E9A951CFB75 +:105C50002EA3049EC92794F5D7811EDE10D2FAB474 +:105C6000112B3E5B65C2B0FA7003E2FF419490F9DC +:105C70006751F024D053367F358CC5BA9D2EA4FAD7 +:105C8000583FA11EEE235F6E481AD07B1095166D0B +:105C9000F88ACC36942E1E1606A2EFF3EABA082133 +:105CA000254BA031B13B57FECED8CED9E590DA2FA7 +:105CB0007C88C3580BFD4A30A5D985D6E54042A45F +:105CC0005E6A872F2688ACB47D6EEB878DC9DF4373 +:105CD000C2912E3E3FAD011BBEBC1322C446949917 +:105CE000A789DEDC35BCCC184FCB0F7CE5E615BAB6 +:105CF000AF9985DDBA1FCFA488FAFF7BC70CC99A7C +:105D000038F33EADBEA4DA63B7269424134638C9EF +:105D100036BD0FFE0B677B870E95BEEC19745323BF +:105D2000D0468EDD4142F22A69052961E9475FE4E8 +:105D3000A5635FAC5FEE78A04980E701B14F5319CE +:105D40001A41A1A49646DD746ED1A14D102293266E +:105D5000881223479A561F8E26DCEF48F8CCBA26C5 +:105D60001343337B64F47389D0E54B8E3FA7D3266E +:105D7000618D68849B548F0B27DC9F3AC1F1B090F2 +:105D8000577ADEA7E4B81E44BA1F499801DC1467AD +:105D9000741EE89AA252B888E54B2BEA5020FA28E4 +:105DA0005272E8AAD1CDDE682D98A0A9B32D396C26 +:105DB000CB5BC7F495FF6469C9BD4CAE3C9D3068B0 +:105DC000AEDA0A04DE223BAE4CCD6BAEC7E8DBECAC +:105DD00018AB8F804A6EA4780E7FF60FAA555D61CE +:105DE000C0B944AFFDE8F12175CD4EEA897C79E573 +:105DF0001924606BB3A1E6D47725382A008D65603D +:105E0000A4F252522C73FB74D4E70FD14C580D8B73 +:105E1000372182CEA003371D265288229CC68A33A2 +:105E2000ADA1DCED05143C70932561DC2D48932970 +:105E300054A744ACF7E693BAAE1DD213455118707F +:105E4000C1E3F1B9EE40FD3A821862EFAD96D53A62 +:105E500032788F1896760B77625D6539C970F2F5E6 +:105E6000154527BEFF605975D565E68B80C19181C8 +:105E700033784A14E529B55B5B82D5DE87E5503679 +:105E80005D88179BA6063B70BDEF66848EBD99D7D3 +:105E900052F60B9A266BF27DDEFB8AF4C8B89806A0 +:105EA000594CCE583ABDA478D36353A5C1AFF4D1B1 +:105EB000091D28860F0C35794FC9694DFF7C337653 +:105EC000868E69B3320C5A7E76626BDC7549A6FF0A +:105ED00098AA9CB686E0582B584982FE87F29EA26B +:105EE00095EE0BB16FA8787EF445362DF45C22BD9B +:105EF0001926409CDA593A14F376E83EDE8B00E32B +:105F00007932A13F88C0B5CE78BE42ACA82B3FC342 +:105F100076D723C36854E4A5F87086CC9E4E7BE503 +:105F20007A03BB81C39B9512EFDCA422BAD6F26739 +:105F3000757DB602A89318482F42663EBAB35C033B +:105F40003A43A5C6587D30314853786BD0EBD43EE8 +:105F500056F7457A781DEA9906DE1B38C04BA868CB +:105F600049876D05B5C3B559A419AC95600529835A +:105F700057E30A71B3E8AFE5616E33942D89B4E05D +:105F80009AFBAFC8624C9B25203F4AC40528B7CB7B +:105F90006178FEEC92F0B1A4BE7A118B6ED328AB7F +:105FA00011F40E30DB8DC7305949434C148B1493D8 +:105FB000132BC524562F85E913414D9B1763DBA096 +:105FC0002A566DBACA5EBF25C5C73DCCE7EADF37A2 +:105FD00050EA722245B6CBABC1647939A07CCDE7DB +:105FE00075FB65CA632F9A832C6FC88ECBEB572144 +:105FF000CFAB8780B38899E3AE45A93AFE8FABDE7D +:106000008C32AB968811B91D7CBE8D734BC9F906D5 +:106010006C16A8F38C7CDC326EC2E5C7949673FDD7 +:1060200068800514F318413BF5E0037FFD7E49B01D +:10603000251B4495B79527B975B76560764497B128 +:1060400099ADA932DC947584B4A1230B4FBC15DF44 +:106050002822B5E4564437A7A90D9273C4266FFCD5 +:10606000B183A2BBFDCA39A4C1816B7060637FFAA2 +:10607000AD918C9A5745B3BDAC0D8CD879737A89A4 +:10608000EC968FDAB00C3BF5080704D59E6A835571 +:1060900091AA61DB511ABCC71234E0743D4EEF582F +:1060A0000FC54D959F7110B7C8D8DA98E56822F0F2 +:1060B00007494C94A7173F716B28C364ED3B7CD014 +:1060C0007ECE87ECA8BD18B7F6990459435ACA5F2B +:1060D00052CACE32753E53A640180D243E2114BC40 +:1060E000597B8DDEEECDE343658D059A405F0A9DB9 +:1060F000BE2891600F5D9C81BFB8CD7FFFFFFFFF81 +:106100003AF322064042304C142244FB10650A66E2 +:10611000F763236D0A90905E07504D032C56AE2313 +:106120004D922180667F4628115E8362C9E271BD6F +:10613000EE5185224956B38EB5BD9DBEF22C0D2081 +:106140005241FD8900A4ED6542D7A9000BAEDF994D +:1061500098CFF68C60DD911F74A32350D8B4177EBE +:1061600095BF0DABA191C3646BD1C904B36927E09E +:1061700069BBE003E8374D2127772A48FC85FFA655 +:10618000927B2A4AD688999708386BBFF2CCC765AC +:106190008A395FA43EFE510AE51FE8B0F45EAE0CFA +:1061A0002B15DD01FD0A792573E56747CB345A616C +:1061B0005B0962288F3DD12803C16546A3C2DFF584 +:1061C000238852A78F5BBBFA0015A1282848C391EA +:1061D00014E80F09E93ED94D72584D611A3E1B6013 +:1061E00011580A1ECBA01814E88B370CFE9D245FB3 +:1061F000CFA8E92FAB940722354973E0C16CF8F6BC +:106200003386D3529C8DCD39EB87C1EF0FC42C8DD3 +:106210006EECD4971774213706B1408984BC42458F +:106220006E672DEF06F6C99BD57FCAAF8DB9198B66 +:106230000DD1A532D55AD2132311E75F27259878BF +:10624000FE28B6E8684133942AE7975BF8A6D3FEA8 +:1062500015FBC6EA777433E5900D21CE7021110A43 +:10626000BFC95FD99F59B47AD2A0B58D5785C634BE +:106270004CA79083F3B93CB1C2084E2C1DB6D47F15 +:10628000C7FAD75AFE8E5C959557EAB2CEA8303B36 +:10629000309E555B1174A1F42643E6A4616C25A6DB +:1062A0002F15437E18EDBC98B2CB1B3FF779B07722 +:1062B00027E95E59CD62503078C73B53206DDBF73C +:1062C000E93E3AE1C28C762795046A1EC668F796C5 +:1062D000D3D04C3D663E08EE810E1856877F9E8BCC +:1062E000BD216EDBE63DAE7C0F169D1485030D12BD +:1062F0007526987B7526D03000F8D48D9E8B2D772F +:1063000040C3CE8DA40330DCCF05E539B7397A4DD3 +:10631000CF5201A078E53B0E80CCC79B6CF19FA2C9 +:10632000DE70AEEE1E48750D29D3F7436147B34FBB +:10633000EA970413FB934A174751B13CB133555ABE +:1063400000A2D1898246171DD011E5471CE2D38DEA +:106350003AAD238353761735000D2FC8A1E0B23A2A +:106360004B932527BBD790EAEE904A1B9377D564D1 +:106370002780268645D58C836F11A760F801288B6E +:10638000A9EA08A9988C3FD6864838778C8B7FE994 +:106390009D1CFA2492E13E69203B6C1345DE4DF2D0 +:1063A000E28F0D58DB8DC71FF3F5E637D3F624E7F0 +:1063B0007F9F0C8A9562F4A05BF762C69A499F4260 +:1063C0005A4E27ECDADC1AEE0C6CAF4F928EC9E114 +:1063D0006B6C7E9646DC04896854A489C2E05C3EFE +:1063E0003A416AF74FCA9D3E3FEF476014EDFDD03A +:1063F000DE2D709FD3CDBFED4599AD36A19EE7ADA3 +:10640000880ECDB3081937F03126E540FEBB000FEA +:1064100088E1A160B4927F087412E78BF4329CB2D9 +:10642000E5C1843DA3675D0BD93811448B037B0420 +:10643000EDD1C44CF49D5031C13768655EF7CD5E37 +:10644000DE3CDBF866F45684ADE260DFB40EA2B643 +:106450007AB04F98BE0731B9600A446E25E2710BDD +:106460008603876B9BC15FB98A1FAD2DD91FC9F603 +:106470007F654CD32B28DCB8BA1EF08CA3B7EBF3A6 +:10648000E6C87A3759FD49D4C92EED0A6669B69B2C +:10649000EED84CF735C18045883EEC4989DC5C6B11 +:1064A00083F8286B404FB81A49ACEA7AFFBB7E40AC +:1064B000CCDBED206F5C4EB3C03F6CA4E10FF10666 +:1064C0005C7A25DE64B5DE3D766E4D23F61E80CD0A +:1064D0005FA48C60966E74FF251A14E6FC1C1C0ADF +:1064E0004B18A8F2613C3A13AC3A913E37ADBE75F9 +:1064F00079B9C79247FF44FDA237D8DFEA7B7E7F98 +:1065000038B2481034666CDFB38C9C33C2F4566CDE +:1065100032F68632B0EABD2C22C3373EA2C77B6773 +:106520005B3DB81DA603404636995CF15779F12AC8 +:10653000990FEBF71AEE97D879E5C94E528C70E9AE +:1065400080076E1F7ABC12D532A04EB4319EDD9901 +:10655000F2B885471BDCF4FE40753C6558B37709FB +:10656000E2377516984A75BB7DD43FFFB61B006EA7 +:10657000655785BC56A8015CC98CC306498470E781 +:10658000D07AE3EB84137E8C6FAA6B36104C08E54F +:1065900052003AED2E3BB52454C7E8762D9C5F5748 +:1065A00063D07007570B50692B49804CF3F420657A +:1065B000B1EABB67740EB76F21D774B40F22F36DC5 +:1065C000ABA0CCD122A05AA16887FD4A6D5E5C00C9 +:1065D00013DAEED2AA91CF20E33F9547A49C8F9483 +:1065E000B94177C1BC49BD651FFA6BB1E2E957D823 +:1065F0004A2F7414D3FC19058B17CD43FC010BD61D +:1066000051BB12E55B95ADCDA0C21CFFCE2E187319 +:106610006792DCB08C68317334259E6CC856397231 +:10662000D7BFCA5028EA4BA9B5DB961055E7DBDF88 +:10663000DB62CF150D82B75F62761CE5BD2BD58E70 +:106640008487A4BBFC5BB07E94A236AB1437A08FCA +:10665000447948564E50A0359CB34125DCF47375FF +:10666000E1452390EEA7643CE86563E9D1E139E0B8 +:1066700049D3C1110D0B3176DCF32251DDF5F377EF +:106680005E478911ECFF5E874CAADB8556EE757577 +:10669000DA0B88C60E8BC4489AA91F093DE79E698C +:1066A00016B69AE77871B8780DAB7A52E88A5961D4 +:1066B0005466D2E470E38FE49AD664FDA04B0439AB +:1066C0008BD68B63A69D29311A7BD753D6EC7A7C67 +:1066D00062D4C0791D2F457FA4F08F24DEFC7B7D22 +:1066E0009EC9575C3CEA1BEAC79BD9DAD7EDFA7E14 +:1066F000773307127860BD8AF31023B2DFFDFB7F8A +:106700001E7ECE3986A298C5EB22BC537B9FF56ACC +:1067100092E137ED57057FE543B64125F70D36C1C8 +:10672000010FB746152035530E860ECFB447CEE481 +:1067300017F34F7A8FA719C6079EB93CC108F7A176 +:106740000234F594862437D5F33E67D560E2A28EF5 +:1067500081BA95587AD400C4C1F6C6C414E457ED82 +:10676000DBB8803D0DD5D6ACC80EE7A791A61CEBD3 +:10677000935B7A48D1E59F55B935E7787D7308304A +:1067800020F9368E166CEB0C0C863A17DF0BB5CB66 +:10679000A8982E370E39B1CC819FBACFF023D23FC3 +:1067A0007BC42D83F50954298C1A6D35F9322B17CA +:1067B00013E8B7FE932366E935F36C54B33B01C885 +:1067C000F201F3B082823EA1C608B9A932B1BCADD4 +:1067D000C6C10CD5245119E1525AA4A9FA0CA0AD96 +:1067E00059B8A873914E8CA84B94738C2C6ED8E03A +:1067F00055FFAC7FAEDD9813BB6A2392937F3E10AA +:10680000E486E82C346B68F2636234D69C02D54F80 +:10681000D1AD434474E4DEB2C8D044B146BE8C3E30 +:106820009AD8089F09DBB2F96D6C45DB01C5E44ECF +:106830007B177697933738A884531D26023374FF4D +:106840001AC4B6F0ED81B4FE35745510F4E676F452 +:10685000C83C21F9D22731B97DC416B9FCF677F5C9 +:10686000F02C1335CAA57C7D8F91F619F5E7F6F665 +:106870008D5726F2D117FFB120F90AC5FDF7F7F7BA +:1068800099BB423702183FE2E58EB89BC8A9DD47A5 +:10689000167A293BFEAC5DDB190BB19D44B68436FC +:1068A000F109F746F96DB817900E3C5903CDEC4647 +:1068B000F9A4C3DAD19954B49CBC4C24003B7CAFFE +:1068C0002E5A1D1D2E81C3B39402F613F6EE7EFCE4 +:1068D0008D9A3F9B55503E0DE3188F22FEFE7FFDA3 +:1068E000DF3517F2778843C82EFC0B7AF7EFFEFEF0 +:1068F000A64EA993D0504422CC19DC5BFFFF660F53 +:106900003EA0680DBF35B1A1A407E19F303EDC7BFE +:1069100032A006AEDAD9358C0A20AA0518B0155176 +:1069200013F76B4661F614AFA5433FFFB653BB6D3B +:10693000AD737666592430A223892A2722D77D9EFB +:106940003E47A39B5F1BB141E402B9289D6BF3B2A4 +:10695000F71F96D86826714F66D5919A2153F20B8E +:10696000F523A67A7EA7B6896FD118B941965E6BDA +:10697000E03FADA1B752B78AC989C3FCBE1B01264F +:106980003AF72CA761FF9CA52AD2E445EA08F9D77B +:1069900032E7ECA81AF46FE42208AEE69B4AE62838 +:1069A000A76B7F6FD1C0734E6C0D2DEBCA123D35B6 +:1069B0003329CBA49D7FF944BB4BAB01FB6CF8663C +:1069C0007AA3B94D927DBBADD6EC4E7A7E1E90A4D3 +:1069D000345EEA8E98EF3F418B866F4BA13B7FCCB4 +:1069E000196CE20DE3BE1EA3EC443593AC1F10C638 +:1069F000BBAA07022C2E38A61783682AE34D99C03C +:106A0000947A1364BC3593EF894280D104D752D174 +:106A10003EA039BE8CB0D8524EAA45FE3CC613D615 +:106A2000BF7003D2BBFD0F69155E095DAD9597DDA3 +:106A3000ADE202909BF7D1F5B9CF42360D4555D264 +:106A40003A746A1796BD168F6E0BD1157D9AE708BA +:106A5000742BAC13CC296C7522F682D68941BB26E7 +:106A6000D5A35173C128BAED0F368A556AAAD6D27A +:106A700000DB02A1C967585391026F5A8CE695D486 +:106A800048AC1B6CF88AD9BBA94A4CF3465FFCF5AD +:106A90003CA804B6C39F98BF2C8825F60E4FF5740A +:106AA000BD780BDA4AA9373C6FBD0159C560131E8A +:106AB000AFEA0A98CF1FA23FBFCA4AD8E49A588AC1 +:106AC0002601E611FE3F5059C6FB1B53466E61C3BB +:106AD0002CD8DE9B5E1BB9176CDCCA8294615F11F7 +:106AE00024ED25E3FF3EDCC36518491EEF68F41C66 +:106AF0004DFD407B6CBF6539EB9B14C4656EBAC01D +:106B0000807066EADE00F523A0D244614B01F51FD8 +:106B10005035F88EBE7475F16A94AEA528C69740BC +:106B2000B1F0085FEA237DA161D0404FEA53AFED99 +:106B300093E22643D7117420A9C31962E9C4516EA8 +:106B4000F065A75BC0AC3209CF8062C2501434A399 +:106B5000D50974853E247D66CC10B88486C3FBE8D5 +:106B6000D521793A7C76F8093C61671961945AEB32 +:106B7000A9571D7A97E3B30895F1DC9387DFF348B3 +:106B8000103A4027522A77A762D9C845E09DB78CB2 +:106B900064E98184A4D7BC58AAB8024FEACDD9646D +:106BA00083782F09233D63AC619827AE23DF324BF6 +:106BB000D03C2C74549DD4B1030A6C6FE98C368F91 +:106BC000704B2A274630BDC94AF81ECA561CFD899B +:106BD000126B61223A6FBE2C7A5E856E0159FEF10E +:106BE0001B4F6E5B5CADBA033E606F488B4B21E37D +:106BF000BD25E54CD9AC1B22D60452904435CFAE0E +:106C00006AA6CFF49C1434F17A8607704BDC029CA0 +:106C100054E44E9E53E553D20602C37E439206F1DE +:106C20009E61086F9B32DCBF23030F967159099058 +:106C3000AFA1C5BA56E8D5A599970EB7E2B2F3B39E +:106C40003A202239A8DD97F5741B2A94B590BC9C94 +:106C5000D7308B68135339D78A80C4B005D1D6B4E6 +:106C60003147E2A6850E4DBBF5F464EC65147AFB62 +:106C700015F70638A74A93B1ED037576A4B1124112 +:106C8000588CC597D9F05E418D48C0250DD114F5BB +:106C900055BD8C26779E19B42C3B869D2EDC8A9C94 +:106CA000755A8897DCFC81C54FDD84D74AD1D2A5BF +:106CB000519D7DFFD4B81C14050BB69A874070BA5D +:106CC000B2ED8F33ABC49F4A2419EA5709669B6A19 +:106CD00038FD8E320DFABD87DADECE22ECCC94B9C7 +:106CE00035EC0F31870672B3E85AC0710CCB96F3BE +:106CF000BDFF0E00CCBD61B9CB996D65C54FAEBE71 +:106D0000BBA5CA0D4065DDF44A1C2843CEC614CD90 +:106D10007E46A008B02FB02A421A294258564D2369 +:106D20007EFBA404D31AFA606847E170C1A171DB4D +:106D3000C8ED6BF801D27880673720C0A55B38605A +:106D400078BF04299ACAF38B6E82635480F6526C22 +:106D5000182321698546B22C00740B46E6D4F00056 +:106D6000743E21A691B6B82057C02B6550E7C9C222 +:106D70002B408047D62778A439A1AC4AE7D470616C +:106D8000D8E50353E00EF1AB64DBC445524E462A0E +:106D9000D2FC7EAE4A7EE1A2CD5A882BBDCDFAA9A7 +:106DA000037B7348E10D99C90B084AF0AB20DE273D +:106DB000D4EDB65B8FFFFA2BDFE9C542A59DDF66F8 +:106DC00066642E81FCFC978AAD1AB10EDC1CFBB305 +:106DD0002A887A00875BBA92FDCDAAE2E6EE20E02F +:106DE0003DE9612DD88DB7280C121E8D670F252C1B +:106DF000B40B85857CED9D94093E22CC80CEDDE4EC +:106E0000A4F242AADA25709B6AA7C15B54C6EDDBE7 +:106E1000535E275CBB344E1120F3675C5CD60833AD +:106E2000C5E37450D0840C1195820510EDB1197131 +:106E3000C751F7BE4D6BF15D9843C213A5B89A7C5C +:106E400016448F66BAC2519354BB02ABCE8604ABD4 +:106E500058A2D8E0931AE7F6FB1283F45D965178B6 +:106E60001FC3301C05A76A747A511DEB6EC1703CBC +:106E70001F554E026A603C9A0BC042D70D55F3E78E +:106E8000560C896AB83DFA30AD5A4B1816DF5AFDD8 +:106E90005EA9889886943F34DEDAA71BA05E1BF3B8 +:106EA000C7EBB4B7B93D7A3A23DF01598563133E86 +:106EB000676A2D96B8FFD81B27A7EF805FDF647F36 +:106EC0006EAAD710105E3A91A99A911EB6207271DF +:106ED00026BAD4138AAEF1DEE1BACA1FBCFC781F11 +:106EE0007F4D0397155FAD36E9C36B53286957444F +:106EF0007727AD94302D599963896852CFFDDB799E +:106F0000F9027F7FB6A612ADF2A6E575AFA2F13AFF +:106F100056B2669DF2337DA20D40E683A23376160B +:106F2000A1E7A30F9765B7430BC1C2EFB7863DC179 +:106F30003FB383EE6971872205702EA779555AA158 +:106F4000E662A7C4DF58305016C3A76211E44D6053 +:106F5000224F2788D0ADFEE606C3C54F388FAE312D +:106F60005D567B0A3534B80721A3DB4BAB6675A7AA +:106F7000E930CB0A3DAD150F2411386A2968F94A6A +:106F8000A4684F78A6F1FDCB68D5EFAD8A2337E72B +:106F90002A692F286EED37C7430B6F66A884B6ADFC +:106FA0003B5A8A87137892574B688041335CFE6F57 +:106FB000132B7824C90F9CCB9B49AF4185DDBF6162 +:106FC0001CFEE56FF82CE9C9242D90C6265FFF133F +:106FD000B438648251E619A0D609657B9A2F36E051 +:106FE0001DFB0C04DB7675EA2618AC71CDCBF031B5 +:106FF000EB6970226EAF7E1E5408ED496C805D47D0 +:10700000765B229DBC92329D5DBC4224B222D54566 +:10701000ECF4629996651FF3FCD0797CBC32DCDD20 +:107020008607DFCCD3E59589E12749228F45F2FF1A +:10703000E9170CA69550B3BE6D3744A17DD5685EA7 +:1070400085D344343638CB158B20C70B3DE7D77535 +:107050004C88A51FCCDEDE56C0D72F760772DACF5C +:1070600037470BF7B1349C6BB513709474181795B0 +:1070700030B15891FB765C945D49AF541EB7F5EC86 +:107080001EEA74DA230A95E5F6C8B89AE62ADD8A7C +:10709000569865DB16853BB411E0984502A37BF456 +:1070A0001B38CFBA67EDBCF8EC61352777CDE0B877 +:1070B00013284C94431B18618C1F11B8123B5C4E73 +:1070C0002C228F43D87A54BF5A711925B1885D8C10 +:1070D0003EDAC4BECE48B01064989CB8867C38FEB8 +:1070E000C0296E35996FF63DA8616C76973BC67ED8 +:1070F000D4C40C1BBB4DBF12BF98699DA55B5CBE81 +:10710000C0678B013C79132228BBC27AF0FDC66DA3 +:1071100032921AE6B4FF174C9EB25AA6585793EC17 +:107120003905A8F9E1CC4C60B443124AC921D9FC15 +:107130007136220550D5D96143394180E6C843B83C +:10714000C001C146BAA4160090025E06A9175BED05 +:10715000701BFA39F0B41701650EC248181656278D +:107160007B41730A11C781C96B61C426F1EFD3A6B5 +:107170008936021C19D78078E6336292654A5496A4 +:107180004F1F0E453A7A5827FEAAB6B60DA823849B +:107190003225F60FB6F7DB39F15A9F43AD512A6914 +:1071A000EA8B93CEE3C476682BB64ABD4854A7EF6A +:1071B000460A28D8308F992309BB3776468CB2010E +:1071C000373EFD1CFABF174904572C0E120E5D2ED8 +:1071D0004A9AAA12F2AF5248A5BAEA92D00691058D +:1071E000F9B68C83FBBEDB4BEB7C49436B6D57C818 +:1071F0008B5C32D2F3AEDE6D9B0C1CF3935C26E904 +:107200006449B81D4A1791EF91227BB738D705D64C +:1072100088CEAC73C19A90C72652E149D4ACFCDC4D +:10722000D67F5D0931E74F344FA543378A6232324A +:10723000A614322CED5C293E4DB18111C5268C1D62 +:107240001DF6C7EBFC143439D0D064196560DF0A31 +:1072500017D02555B4D0D3B45A408AD660E772848B +:107260009EC15A3590CD579D6A11EA591587FB3456 +:10727000EBAECB544D26379A05F5AB34E3B492739D +:10728000F90A336C65CC203EAEDE0B59F4A87B388E +:10729000761A3256F6BBD836DEDBD21B733E222F6F +:1072A000BC6B04E7CA3ADB1A6F2BF3BF9B67FE89FE +:1072B0003766DE1BEF545736A3C4EAD8A7CDF17268 +:1072C0003878DBCFBE7C197E504C6396B4EE799D46 +:1072D000A24B081731A6EDE2585843B856678AF416 +:1072E000396C435D7FCD37C85148C293178A78D334 +:1072F000915D0EA28E591AB7CFBF9744FF17125750 +:10730000DB7D37E0227975A208BDC63766A27FBD56 +:10731000ECD8BE7E6AB297BB79B04E18F4A5F41EC5 +:107320008A448A5E2AE7FEA3084112C88BD4F6E499 +:1073300049DA495ED57562C601539FC587975815CE +:107340004820FB88D80210A9CF399719F01837E0E8 +:1073500050ACAB889052F724408DAEA614099D2DF9 +:1073600059C1C114B44F730D5A10A4679365D70463 +:1073700094D722D7D3A4130AAD8D456FC726B6E3A1 +:107380005A2DF1879AF193AE7FCDED37BA2A557613 +:1073900092D48FB3CAD7D5A4DDB8463D19BC06BF79 +:1073A00043C210C8EE193D5C53EA4EC7048FDA5150 +:1073B0008A79F17448DFDFAD03A9CDC3838DD52968 +:1073C0000A28F1829AFE63EE3B08F9A98B103FE888 +:1073D00081446179941AEE7BC3C6A4A9C2BA5980CC +:1073E0005BB588675B4F13584B56258A922F9AAC32 +:1073F0003A48F2CC951E8DED40606C8D4CB9A3F4EB +:107400004456069D5BA195B6546BBA9234E7E75497 +:10741000146DD0F218E9963CE5725D93502500F9A1 +:107420003D965933E88569BD0948E2BFAA061DD1DA +:10743000D611BE5BCD5E1FBC85C586D13DF6665EAE +:107440005C224FD624A036D85766C75CEEE4E4FE33 +:10745000542C8B9860165F18C89084DEEE098CE778 +:10746000D9764DF2839747100BE44709B70F423B9B +:107470008141A74A6545B71AFD8D04DC474708B529 +:10748000E6EC6592597234FA4EA8449AE22AD13752 +:10749000166081942C1C269E4638763FDCBE887090 +:1074A0006509B712160441B38FDD8F9A77CDE0944A +:1074B0005019B60FF59E1EFAFFD856999F2D7DF1F3 +:1074C0007CC8EC98EABEBE3AF6E9489ECEAF9598E5 +:1074D000D97229D0D09AF5754604C3D0863803E610 +:1074E0006F935A7DC78FA4D04F3B05BACC0D524342 +:1074F000E95F027CD18EDEBB051BEB02CC7B5281A7 +:107500007B84A14AF214128BD042E84DF0F0286D32 +:107510001D6E60050990B4AD7A4042810356D3AB2D +:10752000C166480AD5016D2B49B93D2EC950524854 +:107530006B138242D104972ED95783BC0CD7306588 +:1075400051C24575DA46A1B930A9A04954E056B9EF +:10755000302281CF0AD0BEB81573E2C3E08F2FF876 +:1075600079C389DFDB47002E49554F40650721036A +:107570005CB301CD90FE743749F56AFD0A32B263FF +:10758000C26F8AF53A7EBB6A322C37C1DE50FB737C +:107590007366680D1E98B8644F1763FCCFDE6A41AE +:1075A0006473E90EBB2E3923B48829E59B4B5AA09E +:1075B0006AD98310B30D3AA04BC4C109231A7A6D5E +:1075C00055AA88C67DBA97F11AE4C886B06E59AF3D +:1075D000B27FAA16824DFA3F3AB1EDCD893B3A69A6 +:1075E000162BB906D94F582A440BE9CCEC5DA8E319 +:1075F00047BF09C531557C3423FB90F9B97FD83E8C +:1076000013E2AF9668171A38746D80DBFD5E43781D +:10761000D2E2CA1277B0D832FDD29E58A44AE08C8A +:1076200003C1A43783BA9270EA4362E86D27B72199 +:1076300057ADC9104DF7B57159354076B4BD7133AA +:10764000C542254404C0FEE96E45FFA9440CD4BFE1 +:107650001CB27F98CCD09A691F92943025D040926A +:107660007D3E2F7405A61F35F80F609CD10D1CBD03 +:107670002D1037182157B48B650ED0606795EFB584 +:107680007FEE0B58BAB83E352E48741A3A09EBE72C +:107690001838C25DB6113F34DEDAC1D25408D81CA6 +:1076A00033FCCB052AFE9A78AFFBCB9ACEEC5F7CFD +:1076B0003529EAB40AEE9B791D5BEF765FDA1F7F0E +:1076C00086295618FE5F103AED1E9D4C6C2BB8ECC7 +:1076D000593A2D309E1C4651E4027B9004FD5F8098 +:1076E00041BB28D40F971B98E81FD9F9DFFDC93992 +:1076F0008599EF19AF09E132203E16E92211FB7995 +:107700001374647F893736E2CB32C6BAFCDCF51FCE +:10771000D7EC038C2FF61FD460AAC7BB6E69F68422 +:10772000DE8B61011D1235280341ADC10545562888 +:10773000E19724FFFDEC69A05A51E40106D55729D1 +:10774000B620F9E11630992248B24EC2A9D1B388C9 +:107750008D21328CBB673D0A18BBA5CA7AF4F1347F +:10776000591C80CB6407CA2DBC4C654B937FD5D484 +:10777000EFD18CD3BD25FDA4E9F19CB2C1E585EF25 +:10778000CA37288E62F91ADD86486D8A604CA3EEEE +:10779000EE3AACC9FA9AF2EB20016F329341CCF980 +:1077A000EE022DE6F7F6945F09D8F6B179867D35BD +:1077B0001FEE0FCC6B7D38A63FBF3A4B9B3B5088EA +:1077C0005A7B67839CEE29CC4A5BEF63E749FF1342 +:1077D00095D804D9B55BC2D02AF8149845CCA03FFF +:1077E000038A02833E6FEDAE2719E06191F3DF6EED +:1077F000531C518544012A73434A6E30A2D9B8AF55 +:1078000080E00543180932BDA651E8DDB2F8F992CF +:107810005294C412FC12C2F064B6945E43C873BCA6 +:107820007F1FCC910885FC474E84455D1E2267CDA5 +:10783000DD60299EAB375CB0256B86C25835B2F04F +:107840002970879D014471264F92E6CBBE52C3FB3F +:1078500054602F174054708774E754E2220544485F +:10786000E341E127DD49B506CE9366C0418855A2C4 +:107870005751BCD0D548357D4605F76A0275FC9155 +:107880007E2A2AD50A1C74B2200A879C8ECE687A7A +:1078900098F8DA64CE4A05B49AD886FAE4BFDEFDD9 +:1078A00065742E10278CEDFB0D1B4A75CF2DBB4B3D +:1078B0008305ACDAF79B3411FFD945D6ACCCC8F0C0 +:1078C0001E4831E9A7ACE8B48CAD68B1CC0CD2014C +:1078D000BB9C299BD62093B04600C3D0800A5BBCDA +:1078E0001F8DE8D2724DB9224C69E9428F1E95FE78 +:1078F0002269EF901027BF04003C3102FFFFFFFF19 +:1079000059BCE5ABF8B45B625FB7464DAFE39A6B29 +:10791000612F85076A90B068503DC3FB8E56AECC90 +:107920007915860FB934962FCFA56BB0D99D39E163 +:107930004686870E49779F61FCB560A84D90266505 +:1079400094D20A0C93BEFBBDCDE4ED54FA23BB07E1 +:1079500016E0024733AC135EF6612541740779C324 +:10796000C3B0AC2601A2C8675964C42BB7C192D971 +:10797000755C22D89CA49C54B602A9E3896520CAF0 +:107980001C378C0E3E313C97D2CB16409CE4F977E5 +:10799000B5FAEC88358E19F4DA5A730B3A562F2B58 +:1079A0004C862B6F43F40F44D3AD6178274FA4C5A9 +:1079B000229D24EBE91CBD6923AFCF46A3305B2198 +:1079C000F62A85AA02B8FD42CF8AAAE7065D7C00A6 +:1079D00042D80D20F4F5D1CE5A83A2428E4D7901C2 +:1079E0001137406DFDE1503D2B6D2ACF179EFCC332 +:1079F000643B06895BAC386F096338E21F8EF9E29D +:107A0000410481CDFAA9DB7441223B26B41A6C747F +:107A1000B9E6D20128F64438A6026DAFFE2598D209 +:107A2000C5E39A09BF35BF9DD5C2DF92F6E219B111 +:107A3000B76A9E330998319E0D20EC48FFB5F2637A +:107A40007E3340BBE044D39B879E008D6D94F262F1 +:107A5000572FC276F42BDAB68E830539A4F64BE89D +:107A600013B29FB79747B9902B5803F9DDF491569D +:107A7000B6550A38614AB0143B41E0A57167E77D0D +:107A8000C64C57033BF11B78C52CC9C9C80978D32C +:107A9000CEFF555B211842ED26DC6F5432CF1FFF1D +:107AA000D40D09B58B246547D7CBA918C54D783BB4 +:107AB000370FAF164F20264E4A3D48D1DACE93FD00 +:107AC0007C33D6CF717C3C87968AD0E04297B84C05 +:107AD000E05A645BA87C385D8C7CCE73A6F89B82F0 +:107AE000F470ACA564BEC752E8B219F3DF710BD5D0 +:107AF00077B9E219E9A0999248060250E0CDF3C0A7 +:107B000018FD863AFFC89B5D8BA6E5A28A44E785EF +:107B100030160D1DA832CDE26129A2DA07A5D13CAD +:107B2000B661C67BC3476124F144B84F89D4508CF9 +:107B3000E9709BC10268402EEAB76405D877C54357 +:107B4000E78256C6D2A9A2ABEDE6E97690BFC0EBBC +:107B5000107601A8D308EF7660ABA66AB057A6638B +:107B60005D1827064E3C4B7A11B64CCBCE2014B68E +:107B7000462124C5DAEE91ACAF80F5C1FC37855AB9 +:107B80001AA33FBDDCBFF76BF24876CE605D3AE3E7 +:107B90005568B2CB92E1A0C5E7D23B8BE84D3FE2FE +:107BA00099F19C475E8D970C7CBCCAE7333EB64A80 +:107BB000E3E68BA64CDF972003B7CBC63B2EF35BE7 +:107BC0005E47E7EF1D6A75AFBCEDEF63AC8C5A6999 +:107BD000127E643EB4FAE002027EAF18070C71B266 +:107BE0001B6C670D1C3D758D2118F3650C15BECE01 +:107BF000F0AAF9003FFF9FEF034B2C6046FB729DFC +:107C000071068DE2BBE9BB16F4C00C1DB466645B63 +:107C1000501726F31EE0CA6A2EBF8E95CCB42924D5 +:107C2000E5E5A4D03E47E3A96B41A05761A79F714A +:107C3000742FA39EADF84E2803518779EB88936883 +:107C4000AA50873BBC01FC9727D91796CE4385984D +:107C5000127ACC56B8A54ED9BC95AA75C786F7E35B +:107C600037B14D75EDC27EBD89EBE7B6CA635B6483 +:107C700053672A318B73B4D7AFF17095F5E3754D27 +:107C8000E70E8DABA60A385CF6C8499AB6572CBAEF +:107C9000969A2BB6D02ECC6A46AE8D58190EF25459 +:107CA000E7E947D890F2410B0F02097137B82899DC +:107CB000EBDBF49DD13A454221486976ED2DFC5627 +:107CC000340A3831C0B718114E419960171E7AF343 +:107CD0005C2B8CDDE6DBF764287ECAF33E7C689C77 +:107CE000B5D893917C0874DDC8B01D73AE491BF7FD +:107CF000AFB92A2A3BCEDDBB680006D0C7B83D9F8E +:107D00004809825A0027DEADA807214230DEDD7B1C +:107D10008C50498C5704E6630210144865BCB4C704 +:107D200011630D84E1C8282D9A419ABFE1531A418D +:107D300069C8170C389E6C2ADF4EA063C9DB531943 +:107D4000FF3082DCA080C32900279C4E3C1760C214 +:107D50006FA0220AC041687F076EC10F8E3447C8EA +:107D60001959003CDB475022045EE0040316BCC0F6 +:107D7000FDA1CB08164295DA72F56A780B482CCA39 +:107D8000928A13608488FB0A99C8000AA74EB3D070 +:107D90001EEB2784B77E382B7AF1C944A6A65F4430 +:107DA0003BE68E47A3991A10AB13CBDA53B2642883 +:107DB000D8EAAF494BE6782D43296546F939BA3DF3 +:107DC00062CCF7072F68C66F32B4344184D0AD68F7 +:107DD0001254893775D8B65B23FA1C9E3D83B2CE08 +:107DE000C737EB1EE4E806ADB417AB4AD62A33AD6D +:107DF0006CA908000B3ACE6D63094B5938830F8C80 +:107E000021E2D7753A6C34EC2A055CAF9CACF24A9F +:107E1000698E07E5E57F593CD8CF6F57BC788CF861 +:107E20003D7EA652290065502B05D63EB255F27D07 +:107E3000D913BAB7F3344450D09A42551DE9D2E36E +:107E40008028C0D9AD46390E1B3CC1524F1991D97B +:107E50004DB20005ABAAF135E8929C8DE651800E3B +:107E60001DDD206CFD3E3DCB9E5D438948D483C91A +:107E70002D013518C5052ECA45616CAA8D04FC3448 +:107E80003E768415F82C3E15DFB4C9A7F665A0F33D +:107E900025F6F85BB66F604CF22768199A5EF961B7 +:107EA000F8D215A6E40FA70F77645057874F54F107 +:107EB0008F12AF76DBB39B79A05BCDA05FDB55F271 +:107EC000F23878136B82CF60349E9FD5160DCF7A2F +:107ED00001E5885CC8ED1D7F5BD86B9DA6DB925EDB +:107EE0001EDA4F18FD2609B5777B6A549AE6137D92 +:107EF0009059DC1FF7AB1AC03F20BCD4A77FBCCE83 +:107F00009823FB0D6D2DE9AF2A2667528AA44F54A2 +:107F1000D1D587BB653DE8AEF519E6C2633253B4EF +:107F2000F24C79FE61ED3CA40F86F8C4C900771DC0 +:107F30000D714783C9DAE1AE392364AFDC48F6A39B +:107F4000D4B25E8BD8CB10C938EACB6957CEBF8785 +:107F50003141634AEF2911881A734615381499E1A3 +:107F6000018A528BD734B8ADEAF0BFA8A9723FA5F9 +:107F7000099A5F8AF8D33A7F47930D3EFF04F1A533 +:107F800042C38C850E9C50A2F6C8CEB29E8B5AA5D9 +:107F90000E45FDCA927E4E922A7A0F42E2BEDF2340 +:107FA00041038DCA3B8D839F0649434C075FD43202 +:107FB0001CBE0FB11C686A9B2BD94D3BB0BB7843EC +:107FC000637EE9CE222CD0EE9EF846C4CAE3B58883 +:107FD0000AF93F805DF6EF0EC59807CEC4D6FCAC1B +:107FE0005F9F8D1C5F7C6A4D75156DABCDDA7D8B07 +:107FF000335EAD4DDCEB99745BC12EC93B99E9341E +:108000000C003FF843A9DD93B45E6492A4FA55E0F6 +:10801000C0E10B67FC33C6B7B94F250EA6B7566152 +:108020001D7CD392B3E54F1F842819D90A47F82F36 +:108030001337739BA3F61402FD9D7F2EDD7E2D78F2 +:10804000A4ECBC69DE3CCD6B7000E4F3CC547EC67E +:108050006CD048FBC4B4CAB990707CF19C3FEFB7B8 +:108060007DD2A08925C20F6B6481C7E7953390FB51 +:108070000D1A2F9AD5A4D5364561E395414177571E +:1080800024940A6C590C75B16EAEC43EE64CD073A4 +:1080900097042CF9D6A7D6FDBE99A3DF015E712403 +:1080A000F34C116C9F374B316E3249D3374D7C6B9B +:1080B000EFFC2CD9F5EBCF0E72A94CD0A5BBDC3B65 +:1080C00004CE28B1E231DFDF4A336D6E5DA9702046 +:1080D000107AADB7D621BCB0266FED97457C64C948 +:1080E000280BE31327A94CB01748DAD3332545F101 +:1080F00009B95032145BFF3450992D5887DBFFFFCC +:108100003AF32EAFFF801C1DEF7BF5FCAC803B9358 +:108110007318E4BEAFBCC1C2BEB25EE1AF5957FE38 +:1081200053E97CCF26A944114A21C60243D4D1E1A8 +:10813000D4B4EA69325730DE210C3E4545F238802E +:1081400044A2807E00260E6668E25525B0B1906993 +:10815000289983086BD0ACED38B18948880771093C +:10816000D2B1CE09FD09942B29E53157AFC433C9EB +:1081700011412F0A81E47AA439BDE348BFD4D02548 +:1081800056F528D3AA6E9585DF38E99BF489B12B83 +:1081900034BD2BE4B4B91F64621FB446484CD97F88 +:1081A000648DA357D19EFED5E8ABC32C892F6BC736 +:1081B0000D6B62687ADF38D4B8C82280933411A876 +:1081C00058C82B14DA70F34F0BEF3966EC015C13CF +:1081D000A6CA0305F251F26E9A1F46C01A93BDC09B +:1081E00023884003032E926C8ABDF107677EE7C4A3 +:1081F000CEDD7EBA0B3F556D3BA04F4046F97E0C5D +:10820000058268CC14009D1E0ED30AD66BD756D6B5 +:10821000657BDE4CE26931EA51A3C0CEFA4084D7D7 +:10822000A904757095E7B41315E1BC54C55B7F8F45 +:108230007269A151AD110505A9D31AF5C3F5B5753C +:108240005CD95D1C1BC516CF9E69C3D2675074AD47 +:10825000045264042593CE936480E3D3BF180E0EBA +:108260009EC1A451C5E1B48D4663A5445EC1F45BD3 +:10827000754100111FAB799479B1F751BC1D0FBA4C +:10828000869FAA5239EC3C19C4D2A2FBDBAB916B9E +:108290006E5CC814B618907A8EFF90FF6E4AFB236E +:1082A00039EBD4E5E90FA35E5FAC1419EF891961CE +:1082B000DC672B91D1209B904DC32338DADFD86A3D +:1082C0008F418B1556489B0B19EE097CA83C6AB16F +:1082D0004A5C8D17AE09B53026DCB71E61000686F4 +:1082E000C1348AC5B97966DD2F6BF179A93CFCA749 +:1082F000DFAB2945B17C5A90785C77DCBE1507B2BC +:108300005EB23B20C864E3E2A03D62C660353A83BA +:10831000620FB2ED0BBFCDB2A3924501ED34C88F11 +:1083200041CA3F8FA3F748F17C7BC28F978EE6420C +:1083300049D76C8E8AA27CE059FAD48187921FC0FB +:10834000A0A520C6DC8DFFE710AE6AC9D011725B14 +:1083500052D05CD3D019118828F050C4A6B3351080 +:108360005C410696212558E49DF1CECEAA67E9A589 +:1083700011BB694860D336D741C1CFF62F49B1A5AB +:1083800044BA8EC235F1FDCB8A56C3658C8E3DEC66 +:10839000626E0BC409B7F6BAEEA927C19AB45CDBCA +:1083A000196946E9587D40F961B8AA67CA5CFA6361 +:1083B000F064BE2BD5AA61F87E48AB4D859A17C8EC +:1083C00002939881DCEA18A112AB84C1AE00356635 +:1083D0007BAA4D82D4FA19A06AFEEA584BCAA74E6E +:1083E0007B5F0C4426CB37909FF9CAC6F34B620DD6 +:1083F0000B8FBF822EDB3ED373F640C9C8CF230C50 +:10840000F660886DAC36CCC93CA71B59D467BEFD5D +:1084100075103A11E191941E9ED0AF12F954F7EB0A +:108420005D9DCB3D657D9BB4A5E466E8ED8376A8B4 +:10843000EDF5D22FFC6693B7C231FE774133BDED27 +:10844000F020A4CEB4B514D84A4760F98FEE934B10 +:108450000AB0A813D2AE31CAC8908C16AE725CA80E +:10846000752124BC8366B5F472810D7528439D9CEB +:108470006993D78C59C4C61DC2774697C347D51A8E +:108480009BD1D184F82B34350E2EC98FB6AE7CF833 +:1084900028C4A0FB020D00B3EE458C5F4599DC5665 +:1084A00018C1BC9ED92655899B5B6C7CD776AFF7EB +:1084B000841E3EA43CEC87F93F450C441FA171701B +:1084C000FE3269C72621D811B6896E9E73A99F5ABC +:1084D000D29F2922CEA9547EF43A7E70984E947E83 +:1084E0002B2220DCFC4B1BDD4FF5E8A1A11C947373 +:1084F000F759A439CC2ED1BFAF7F4EADC15BDD1291 +:108500008547E1A6CC97B1DF765B284DCAD4F30549 +:108510006EB4EA42C031ED22AAC3ADEAC22CF2EC3D +:10852000D5F2AE8FBFA51DD46FB321EDCB7D730700 +:10853000E562EBA549EC458E2F392AC6F9F41B6C90 +:108540000EC7FD45C044122450604244D0645264BA +:108550007063FE0AC854132558704345D874536598 +:108560001B41FA44C14592265161C246D165D2668B +:108570001379FBA8C95593275971C347D975D36798 +:10858000D67B2E811D7D3B21BAA2DCDC12AE582A9F +:10859000101A9B0195FC4D845BFEDB4A1BC159B24E +:1085A00023E36189017EED83B632A33E2F5DF86738 +:1085B000890AEB48DB2C38AAF8C279B88BB96D5D13 +:1085C000E23A684BC24C1A2C52684A4CD26C5A6C34 +:1085D0001049734FCA5C1B2D5A784B4DDA7C5B6D8A +:1085E0003D4E3701C34D9A2E5369CA4ED36DDA6E94 +:1085F000732F623CCB5D9B2F5B79CB4FDB7DDB6FB9 +:108600001B628CAD3C503322AB24C1B6AC167882D1 +:108610001E60CA5549109041DCD361FE6793D08E2D +:108620007DFEC81FBB21B63FD5C6092DF5F4D17F0D +:108630003721BCE6B330B71EB9DF4236FD61973152 +:1086400080601074C4C4323454E06254D4E4727450 +:10865000013F8216CCD433355CF06355DCF473757E +:108660005565FA10C5C5B23655E1E256D5E5F27644 +:10867000F7D4A5FACDD5B3375DF1E357DDF5F37740 +:10868000A60A73218D0899ECAB4A951AAA2A7E8115 +:10869000B6A98898364838592057901BC4BDDA3B94 +:1086A0007FAE551547742F782F24EE37BB2FF3A3D9 +:1086B0000C6A2D96509C9DC023E1023FD430187D5A +:1086C000EC4CD307C6CC3A3C56E86A5CD6EC7A7CD4 +:1086D000D84061EDCEDC3B3D5EF86B5DDEFC7B7D22 +:1086E000D7A9E79DC7CDBA3E57E9EA5ED7EDFA7E36 +:1086F000CAD1EFBFCFDDBB3F5FF9EB5FDFFDFB7F93 +:1087000006B32A5542F5902D829054050F4610A2CB +:1087100048C610C31F0737A50B3AA174CBB2F8683F +:10872000F13CAAC3F3C692CF4709C5074CE6D20D68 +:1087300091FDB646413349E0E63346CDA955C1180F +:1087400018666584E04616A4706246C4F06656E476 +:1087500052B06425E85617A5787247C5F87657E5F4 +:10876000F6C72723E14796A67163C6C6F167D6E62A +:10877000FED7264AE95797A77973C7C7F977D7E78E +:108780009888579185ABE1EAD215688AB2D2DCAA03 +:10879000D59EA046AA9ABC7D04C86E893EBAB88B05 +:1087A0005BE3ECC79B0B9A870F2BCAA702A421E3BC +:1087B0001C1D0F316BE60AE982C9EE3A2BBD9A5AAD +:1087C00058A8F3CEE24E1EAC726A4ECCF26E5EEC4E +:1087D00030A5ACE8EA5E1FAD7A7A4FCDFA7E5FED48 +:1087E0005F6365EAE34F9EAE736BCECEF36FDEEE52 +:1087F000137FADBDEB5F9FAF7B7BCFCFFB7FDFEF09 +:1088000076DAD8D4A4A2B67A8D40C8ADF8DAD7B15A +:1088100098ED861CF5A690B73B4269DEF1DDD44E9B +:10882000455A999DAC0311ED4DD8E2FF754831F4DE +:108830004D526F9CE2FF16B589C14693E6B7F3B37C +:10884000E0C622B4E4C636B474E266D4F4E676F444 +:108850006CD22795ECD637B57CF267D5FCF677F568 +:1088600065C3A696E5C7B6B675E3E6D6F5E7F6F6B0 +:108870006DD3A797EDD7B7B77DF3E7D7FDF7F7F738 +:10888000A6082CF6E9F75F204A8613D8D3E9817E43 +:108890000658F95FD61C66805BC54CFAB6BB02F978 +:1088A00067B4A4F6DFA8DF3FEC2BEA8F30D13EFAA5 +:1088B000880C4C34F5D21EDE0548CFDD2FC07F2456 +:1088C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFCF8 +:1088D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFD80 +:1088E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFEC8 +:1088F0006FDBAF9FEFDFBFBF7FFBEFDFFFFF9A7A3A +:108900005B000640DF35328FBCA247FC00A619FA97 +:10891000F762D76DF613B0DED06A2045084B5F03CF +:10892000BA4661F42177F24829BE3544A9DB7C6F51 +:10893000F29386FFD7F78B8E6053A047D3882E0F14 +:10894000ECC24585E0AE71202864A2C5EFE0DB965D +:1089500028895008F6E0B04020C04C04D0BCD11F9C +:1089600079D38A47A0617942E09246EBEA155270CA +:10897000B2762246F7E0306639BC954A2917289A24 +:108980003A97FD0ED23E3CA1730CB74EF2F87065DB +:10899000737A680D497E782DAE5AF22CA24CD97F9D +:1089A000CB57E90EA3E71AE0DE91695574AF9F6BD0 +:1089B0006A3D7649EA39163023D765460BC5D9D0CA +:1089C0007AB6A6013DCE53760B622E83C597BB0FB8 +:1089D000F1BAA7F0B57896A0CA8BCFC0BD065D21CD +:1089E000BCCBDD66FBB73623121BAC81A81EFC0096 +:1089F0003305AF632CA27AF909A1202B24BD87B2DD +:108A0000D77EDDB15AF4B02FB4D3C3D3874CC2BDE7 +:108A1000F760B3E01C16CD266797C0100C4A8CD0C7 +:108A20003D7E5571BEF530245B526C5F6AC78C7D0C +:108A30007397C2EAB56B1D3E40130CF2A54A0410B1 +:108A40003AC7069DBAC2D3B7AB9291EBEC0422723F +:108A500056D2B1542494D2330E358831DD160CE64B +:108A6000652B4B15CBE13575C51266DB984D53FE72 +:108A7000AAAFC21307E11076CD8E83331D18AA71F9 +:108A8000D57BA459DF991C932E4772B56D88F57E6E +:108A900018FAD6C4BCAC219657DA9E3C983E3EF8F4 +:108AA00055765FE7FF995139C3476AF25D9C59FCDF +:108AB000DB6750EA2FEE1AB8279D892BA72FF93ACA +:108AC0003FAA4B189CB0523FA99A1C831BABDB8377 +:108AD00040BA431002F8B9479A03E65B2FA3D818AF +:108AE00026ED28C4B9CB5BBDE801A61F638F7804CF +:108AF000B05BFC9765BF443995644AE9601F7CBD53 +:108B0000263586FA0190066DCD06E7A534A25004FD +:108B100010E9A98C96B37DAC7D4167448BD4BEEE41 +:108B2000726177E7BB0527E38EC1AFCDF623D03F57 +:108B3000D23424C2BB817EE72B752E878B0E2A4E42 +:108B40000086DF8970BE6B1FE0923865EA67753773 +:108B5000F8A3A4C5D0B933C92AAAACA1D2A60BE404 +:108B600007B76F2D802521C3A190424B91BE0CEB1E +:108B70005B634228D3C4F058E9546638C1C7559D99 +:108B800095AA7B8898BE17E90CC82E3DCA96ABA95A +:108B9000EA1EC174D139BC16422EA4CA15C84D14A0 +:108BA00014AEFF8AC3CB4DA74D2CE8618BD070E784 +:108BB0003DBA7216078CAE06090BE064411B5F914B +:108BC000C239AD0FD8DD7573C6085E30010C1EE3E7 +:108BD00030D773225E3CA0ECEAF818A569FC40BAD5 +:108BE000FCB802CF73B43FF1896333011FFDD2E6B5 +:108BF000CB29ED55FD3DFF39438563C2C39FDB8A19 +:108C00005A84D543EAA2B6FA4AA48503A2C414D171 +:108C100098F0AAE79469B8B788D09A90F79216B3FB +:108C20005B84054D0EE543D74BA4450DCBA11571D3 +:108C300094E3258C65CC144567F98DD0AB061EB73F +:108C40005C67D1D5A855976B2EE0420FD4F797F209 +:108C5000544007938C027DB8231E6F583EE2F53FC7 +:108C60008941E13749585DF5C21E44AD385955F583 +:108C7000A7E30611FB735CF402D70CDCEC95D62558 +:108C80009DFAAC8E590C3B2448AC8D5B8C1E2F5743 +:108C900016DD234690F356B640BD8CD6044D3EE912 +:108CA000B709ABD79F114BFBFB58609B138BCF0FC2 +:108CB0009BF9A3642FAD49B48BC44E50054CB6BA92 +:108CC000EDEE8291860AEBB1D597B6052D1F01E036 +:108CD000A4EA8E1E42ACE50227FD8A02234648FD27 +:108CE00075CB0D989CE81F0154920F9FAC2E85798F +:108CF0006B398B34D5454CD17E8DCB563F1F00242C +:108D00004BFD559BE0C9D92D2830E34459A0DD41E6 +:108D1000CBFC0143E8D9D42C6BD2CE7A034BD31BC6 +:108D20004DF846799B04B3BB175342385166372040 +:108D300051EEA1C1E9D8232CBB46F257EF57F023DF +:108D40005F33248B92C0CD806A9374EB73D08E878F +:108D5000F717C9A6F0A79F88741EE2BA27F0DA3485 +:108D600059E963F9FFE1940A84F0A804B1A8176BEC +:108D700001D8E06718B73F8A82714CE11932972514 +:108D8000820BE50E59CD67AFD26B607AD0CE7CE511 +:108D90000888AA0D57A42E291218CB33FC5EA6C44E +:108DA000CE4B2903D8C0E3C6AD59485CED885A4084 +:108DB0008D6B0B714BFD6669B15BA90B4F7A076335 +:108DC000D5CC8F3A17AE1C60871B7C0E3D7F120FEF +:108DD000CFA80DFCF6DA9480F9D4973E1058FAC269 +:108DE0007B38AC05F73EF821FB96CBAEE7FBFE687F +:108DF0008B1A7E021DB54B6D7DC8EDE28B5A7AC091 +:108E0000C92F819189F6937215227F9CEA109B935A +:108E1000FDF243EE89B403F164CF4223E205B9C801 +:108E2000FA632268858992712D23EBF4EB0D1B41C7 +:108E300075F382535695CE137D7C1B5ECFC6931D72 +:108E40007C3FD356285BC3E2788264580BE5745CA0 +:108E50009DF782BA016E9098E763555DBD8759F41E +:108E60006D9403B9CD9D53306FA62825D9198F8DE8 +:108E7000981669F41BE412C8DD9265515D0E12D498 +:108E8000B2EA0B79A69C4F38E9C82A5EF0D079384F +:108E90001C67AF9B8AC01AE8A1C44829290C7FC26D +:108EA000674D0B17588D45B35B3A4985BB4100832D +:108EB0006F49C3904FDFD2317F745356A0E604C789 +:108EC000787C4B18F87814E39BBECBF386167C674E +:108ED0006E522ADD2C54DE7F5D7CEE789B3A5DD0AD +:108EE0003EBA9C976BB289FA0596BF576392AF75ED +:108EF0006975CDBBE7A4B87D670A89598BCC5A80C8 +:108F0000D2E0A88F88D012CCCF506A1F3045924B48 +:108F1000D7970B0B511EF0DE83B6C03E8A06C44EB7 +:108F200041DA5E8FE1EF686FDD50E234C9373D8191 +:108F3000FEB3240369E7032E312B47B91944766049 +:108F400062A086E4CC67FF672682E369A4157C45AE +:108F500076E324C7AF76516C46C626C12C8851A94A +:108F6000E6412F7BFB4504ACA7E74F14C9983FE5CA +:108F70003356EF24B040727818338363D6295A856C +:108F80008A8E89FBC2C3E2A71CDA44C7ECDDD0E5B8 +:108F900060872F84559C023E78D8CF030E5CAA8C44 +:108FA0009C8E82E8C3C219A753E64D41C8087D557F +:108FB000AB5DCF8D93D843A32A5932C083BB5836BB +:108FC000A20C9421E3382DF8A0C6862F59EBCDD3FF +:108FD000D3AA078238A01981AAFECAFB27F4B44796 +:108FE000B3A988A271B06BBCA69BC26F2A12E5F828 +:108FF0006DEA762EFADB1E034388E98DA47FACE18F +:1090000020605B23B102B9E2983068DA9FD8A5C529 +:10901000613A841BA4B6B7CB5C7FDFDEE4F671DD7A +:10902000E56EFD9449033522B5808B5F2ACC7B54D5 +:10903000D37120515CE516D65D7E6CDE673370EC33 +:10904000B177CFE748B558AFB9B4C756CA4670F83C +:10905000527E4D86D26256B1BCB086BBC4743074A9 +:10906000736A4DA5C4433F970D676FC77B8509930E +:10907000137BBF278C17BBB61B46127152155B0AB8 +:109080001C083334A46CBC7AC928732F15A9045763 +:10909000E3CC8C92AC7C3BB576A698B5C0B9DC56D7 +:1090A0005FAC0D9CC74242B70F55612C17DC70694D +:1090B0002E19B20C45603F135DB3EC506FCFA1F297 +:1090C00011CA260C24EE3890A4AA2E088ECA9FFA44 +:1090D0005A81C63E024D51602C7EE68C86B859BC42 +:1090E00053B8E61DF64B3F33A5F480733DDF5D9B1F +:1090F00037DF06CD896BBE3FBFBCAB2A5C644BB883 +:109100003EF18D62C80D925A4680C041EB03F16674 +:10911000CCE32B00248AB22767428B42CE738BDECE +:109120007FA169C99667B142BD530A61597FD60EC6 +:10913000D91589FF442C302862763CF520AF220FE8 +:109140003EE0828494767264B39E444800F6D0C9AF +:1091500076F020459AB4F841BB30476CCF0775E3F1 +:1091600047E002ABBF437B29A7261CDB85F7DA6CFF +:1091700055F8011DF1AB3F2A0F8152E68906F9E14E +:1091800052A00C2802CA322929ACC9F1ADB3AD2ACC +:109190008EB80FC9B4703A39D788E8EFFAF177344E +:1091A000AC7ABD01D709B08D5BB8454CBF6CDBBA5A +:1091B0006BD4F1809B99D1694FDB4B31E31A646426 +:1091C000B92A294C3DC89BCB02ECCB43D22C7691DB +:1091D0001ADA0CC051BC5DA6C14969E2DABC456B24 +:1091E0005FE06BA15CAD9EB309E969C5B1612FE891 +:1091F00073A6620CB56CB16DFB0BA9256C3F7AF0C0 +:1092000004796052E440E13D4EA2D3896BE3B2F0B1 +:109210001CD010174131E83ED101C0571ECB10734E +:109220002D81A172FAA211347461F0542E37F07AB4 +:10923000C0A8007F39EE1235D08842501655E97526 +:109240008844A3B80A4B933D561F0122159BB07763 +:1092500035AA4211CC50B1FF66406CFA1C8BB17339 +:10926000A95EC11245C7EE35434109126E77F27E01 +:109270002C11A73E9DB792A7F98E40DA6667FB7D59 +:109280005F22EE174BB55BFEC6B9484B5F57D9144A +:109290005E394A5B310F1394D381C8A6FE70827485 +:1092A0005F8D2F39FF8FE5549788025CF5A8F9BAD6 +:1092B00023FD2B61DF19388246130C84C7B89278DE +:1092C000104CABFBA61C08B72849837F576ED09D76 +:1092D0006E52285D72D81C761635005284F8D87B01 +:1092E000AB565B97942FBC72FB017A98EF5FF21E2E +:1092F0005368984AAF185032DF8AC1DAABC85AF8BF +:10930000C2E002AC8CB615E0E4408EC3D0EB2C6B0F +:10931000DC901AC27C74E2C462AEE6C7AF5476D168 +:10932000734380A2B52516D849A1DB7330C5569882 +:1093300011EC8BE191E8181EF40A64C80DC7D1EC5A +:10934000CCDD07C44815FFA70E65E745440407EDCB +:109350007EF20189407FF6AA6ED2AC8178B64BE3EB +:109360007DEAE59A9934BCE4739CA552B520276048 +:109370001131C4885D4734A343C3C8688D5B76EC64 +:1093800068B7B3E645F1ED7EF10BBC8A6D3C5A93AC +:1093900053606C8D706D76EBEA58C0ABEABC46ED5D +:1093A0001C84EF8E58C8610C1F4F4EB0BC0B3D455E +:1093B0004ADBDD5083669C49447C307D83C171E685 +:1093C0003B5C6B85E05F3484D615ED47F4ECF40D1F +:1093D000A3C2AE72AF7AFEABDA082DA72AEC4B40DF +:1093E000E32AE4880B5EBC862C5AEC61F18D534372 +:1093F000B05B89A39F763CA9057C6E4EAFEDDFE59F +:10940000F0E0D7F5AC13B6FA98DDB2DFB024634FC5 +:109410004B6DD00794142AD2FCF0A9DBB42A945ED9 +:109420001D78296F8EE54BD7D92761D38D6036D251 +:10943000D65458350275194E7BF40475E9C4DF9F84 +:10944000DE5DDD869A66300A66908D9074DAF9F2F8 +:109450004017CCF13C52E4D502F5C60AD5747069C8 +:10946000DF5D55D461D99C424B01842F3DBC5770C0 +:10947000553D0B9AB4DD5230C9911895C587777167 +:1094800072F90EDADE0C2309EC518D7EEFA4BAF2EC +:1094900016AB0796B91AB0C8F6E5CC6FE1A09400F8 +:1094A0000FF2AD0AFD131FBE695161DC7390D6B88F +:1094B0004F568396CF5293B6043F6CB9A15FDE7BC3 +:1094C000CA519B0AE2D6BC495A2F68D0D6AE245165 +:1094D000C232DF50151E33B045864C7EAA6C7FF732 +:1094E0006FCF873D4BAD33385996CD9E277DEA53DC +:1094F0008824BD52ED3D32122119EB723BB802793E +:10950000817EC200C8CCE98128A2BC57AE90386DDC +:109510009EE0FE0E7396583B60B2620163F3D31B6C +:10952000490D0225B9FA6141BEC36CBF6E56BA013E +:10953000BDE1890CB1FB3D2E21CE6D4E6F570FBEA4 +:10954000407B3F9F9003D8BD6EC0CFE25523B3C28E +:10955000EB80DFAFB6F5F86626D1AA66BED1B806B5 +:1095600041C586E2C944B6AB81A1B3CB8396B0EBCB +:10957000E63E5EDB12B5F884F5E2ED4DE7C5BB24AF +:109580005B02ED6415FF9C757217FEB4F2E1BE2A12 +:109590006ABB3504F4B5B5247A9B794436BE468E51 +:1095A000610D897A50FE14276B0E3545BBB9DBB9C6 +:1095B00069E78A6BF5B1168D7BE9FB42A3AEBFC6A6 +:1095C000FB163DF59ABD7C3A9EECCB4FACC8B30F71 +:1095D000359AAA929121603BF6022A49DD7ED1C0DC +:1095E0009EC309031A30A1386B93664385CC314D75 +:1095F0008B2576D47CFD9DD1397BC8AD8BF956FC8B +:10960000660023E0557BD9032E42CC5F56A17683BA +:1096100034022117DD6703EC0AD201BD638F577551 +:10962000E9035C3E567B4D932B05885F7821756D71 +:10963000BAD30095DB205AD063B700D01F31746CC9 +:109640000EC0EA575337B6996C1ECE5900239BF7CC +:109650001EEF4DC0EA60B791640B905BC6F6C0D8B0 +:109660000BEEC8439341335BAA9FCCF0B3111BDDD3 +:109670009F55D6EA9BD2D838651B5EA609857361D3 +:1096800002C83095803C2088DB5BE41A6955243A97 +:109690006E3B4516AEBA715AA54B03F6BA865D0508 +:1096A000672A9815F08DB0AA3F98EE16F82EB039BB +:1096B0006FA61B16ABEB50F8CD4A87F420F26CA6D0 +:1096C000786C2C3046B73CFCA9861C83DEE8FD5D37 +:1096D00018A6419EF633B6C00D02E927D67CF907DD +:1096E0009EF8C0B1C2AF0D5B6A50114387CCB07F0A +:1096F0003169AD332A224E690C7DA3BAD7797ADE5F +:109700001812A78672757E2932D248CFE6A44B275D +:109710002CF22F87B21487A9A840AE823E453FEEB7 +:10972000552B250B81ED7D91A1D3BACD716540E814 +:109730005D3F240A2B04AF0059FE77CE0D44B3ECF5 +:10974000FFBF942F207D3451B0205FC930249F5B30 +:1097500009A3617C8783F61AD4009D7AC7F3A88990 +:10976000333EED253379FCE40A446779CA20D839C1 +:1097700037E61523D73AD55843E93485C7D3094A84 +:10978000266A2C8E84A27A15CD596AA48C9ED36E3B +:1097900048120E996A5C50A4D3496B8B7794FC6F86 +:1097A000944C2DE6B56D6337D46BC8EFB66F88EC7B +:1097B0004BB8B18650383C0A175926AF3BFF99E8A1 +:1097C000B6EAE78FDD09C0A65A23BFC3A6F05DAC99 +:1097D000785EF400152C31EF52FDFEC19CDAB46EB8 +:1097E0007BE3676D7934FE8EC7106D8C1B4E53532F +:1097F0003DEF7C24C714766C43FF4ECCC0ECF540A3 +:10980000DBA5859664C5621D655106741DD5497238 +:1098100098ED8697A4F3BA1CD02110DBFE455B5C63 +:109820009239799DF3F734A42A060DB1CB031D6B51 +:109830009A3D046CFC05B51E61889826204656B3F7 +:109840003DF3483B1F3795F47243EF8034A4F09A00 +:1098500012666D9692D0DEBA025B8676F8D2F8B4C4 +:10986000B3BDCC55DAF5D6A04B468EE535F698FE5D +:109870004D814638BFAA5CD32C00D57751D378EC04 +:1098800092E8AE6D70FEBC3EE22E1765848387556C +:109890009178AF6063DC9CD785E0D52096DC84F5B9 +:1098A000D4D40FFF87CFFBBC18D43546CF030F6746 +:1098B00015F952FECD9FBCA9027C27D08780D3200A +:1098C0003739149ADE2092B126A9EE9D8698BC7C89 +:1098D00007DA2F9D906ECAEBD39884DEF6FB7937BA +:1098E000AA73A83E1A8843C8DFCA6C94B6993CFE96 +:1098F0006FA9449C917A9D5225044C721BDBFFFF9B +:109900005EAD6BAB80FDEF6240A4CDD3AE949AA365 +:10991000C28CA264D867334D6017A852D030D113DF +:10992000524B610459E1718D6F2629A1AF801AC194 +:1099300071EDC8F8D01F572B61CDFEB8A781B14398 +:109940008D7CA368EDC65B3E4190464BB0B040268F +:1099500028899908B7D092DF8812BC29E6D472759D +:10996000234481B6F9BF3E2B7144403C793DD1F68A +:109970003B50C706C151DB2499375005B9B8D06AAE +:1099800061E50B57022DAD836BC566E3ED5E32CB0F +:10999000D1E97615B82C178629994F62FD4F77FFCC +:1099A0007C8DAF41FB097129DF803009E8EA31E99C +:1099B0005064F21D2B6E3AA8A27E4B81D3A9549617 +:1099C0004A4D0C329BEEFFAD7EF949EEC41DF92DD8 +:1099D0005C3AC92D0A1E58251AFCCE4DA258BA6B06 +:1099E000928E08C43CB288E3932A5244E9EFC564DE +:1099F0008B1A10054B4CB96D5374CD23AF5178C001 +:109A000054C7EA89FA8391EFAF115EFF445651B112 +:109A1000577D5A0E1164D490CB4C28AA5CF2B8DC66 +:109A20000D85A82E31E7E53BC0B0C272CF569871C4 +:109A3000B8351530D96635BE7E8A90C84D57919499 +:109A400015C224E96DBAA7486C30955B86DB991086 +:109A5000F14F4011CD50B2EB3C34C65886F5D037AB +:109A6000E9445D787A8AB47AC5930955EF61733316 +:109A700034BD311F0D96699AA6D64228F5C3527E91 +:109A8000B130DC6BD449D35C162C5B3DE8AA99FB62 +:109A90005F8647ADFAB498C6390CB9FA9C5E907AE5 +:109AA000C7DCDEEEBF6DE33CB0013CB9085E747705 +:109AB000DD83C3969785DA2746860C845FFBC1D683 +:109AC000C60E0852967E329EFF96FF5A53ABB8A33D +:109AD00046910B15DCD5D079EA9A90F26C9E3B72D8 +:109AE000974D2350078BAAC159214BC19FF9FC7296 +:109AF0004479D1DEF561505BFFE3671D1FBF0A7239 +:109B0000F9F33B9CEAF598ADF7408E43D68EA1461B +:109B100056C2A98CF0123D6CFCF2096C6C879D62F8 +:109B200041D7A08F5A20357A0F86C2EE67E78C4660 +:109B300057C2835AF3E87E00EDD1696E6B29BB17DB +:109B4000E003BE82C890FDE0FA6002C2A0E2D779CD +:109B500017D040576B252AE700F6C2C568F2DAEF46 +:109B6000ACE727794240FDA9BB57A5E6C9B775EF19 +:109B700051BD2B8A6B5E91AB7167450D3934C76659 +:109B80009D793109DCBAF7EB60C8A58BE33D76AB74 +:109B900078E5E6AA90ED37046E9FBA3416AC01E37F +:109BA000DCF8AA07DDBA77B925493367B58E35C920 +:109BB00011E8AF26FF9B18502D8326583B1EE34625 +:109BC0009F8DD407780E1A0CE0086F0C829DDA4145 +:109BD0004AD00E6DF85719A17E986DC5D2943FAA50 +:109BE00043A13B07B3CB1BBE13A2DD458BDF22ACE9 +:109BF0003BFFC9C1D3DB1619FDF9D4DC857936E00A +:109C0000FB7D536FB22732BC35D4DB8CE244D85D88 +:109C10009D279D52B493C8BA458D5704A8BF51BD26 +:109C20005A791881DDE5F7428EED05ED6745BCF107 +:109C30001C222AD123AC9F46EB37A5586DF1C77E75 +:109C4000040F0099DC289AB95C966794BEFB5737DD +:109C50004049A8930791B57F6E0D9858D0FE1772B2 +:109C60009A3FA6D418B8B0BA73430FAF35A0F5B475 +:109C7000A74E0661AAB529EABDB1A4DF83F11EF89B +:109C8000203F2DE8F60A25DF567E4C05D6676FF794 +:109C9000702FD236993FC1BAAE466222583AAE2CE6 +:109CA0001D7A9E65042A60394F8C11D51F0FFA1654 +:109CB000FD68C7366FEF13D74156BB807F7DFDFD32 +:109CC000DD4EA7FEFCCC8DBAF6FB4CB0A4D178F0EB +:109CD0000E0E4B90CE543E2DE3057D105E8DDC7E46 +:109CE0006FCF2EEF2D571F372E490B788EDF18516F +:109CF000C349AB958F0BA5B21DFBE9F3480C7372FA +:109D00007827FD0F81F0028D9FD3C4CDAE49309FDF +:109D10002408610D800003EA20CFC3CB5877C8CC5C +:109D2000C1DEB64018C2520243872B266E57B29D41 +:109D30007717680C891DF622AF5336BE4B083A27B9 +:109D40003136F5027BCAE5995F44C0FE121AF10173 +:109D5000305212B8B3D6448D007CC19F5BF086EAC6 +:109D60008C7923D7A4BE63309EE547446E87F025E7 +:109D700017B3CB8209447F65D581C748917C326196 +:109D80005037E36CD82670D0BEB64BE2AC9D5E6413 +:109D900030FA0F05FCEF9524E56A472BBC8DD5649E +:109DA000B88D094FFD0B79A973F0B6472F3EBE2E33 +:109DB000B97B068D9308AACF513CE869E01A789ADE +:109DC0005059FDF16AE7B66EE69859431FC0F9098C +:109DD0002A952100CCE9185D9730EA5217D5382D25 +:109DE000AFD78BECEBDB176C932F7048AB6FEA6847 +:109DF0005158AA1FF531590FEF1B702AA3593A6920 +:109E0000000C43E7197F433093439DD93CE173B085 +:109E100036207ABEDC657271ED36ECAC9E56775D0D +:109E200013214B565821DB5892C1B710F568D27FE9 +:109E3000A9F32E953A2145907FB914D5C48497DCB7 +:109E400022222344A41D5339D427465219D811F491 +:109E5000E0AAFD1A1CF0DA6C1C107B5301AD5737D9 +:109E60007AF003E9D5B7BE7A1A80E41AAD187E34C9 +:109E70006DC042119515317D96B4A35875F5F01754 +:109E800002C8300346559E9516686F4344D212DBD4 +:109E900026E2D41622EEF31AA4471A59AA085D78CE +:109EA00021FF5758D72D5588B1DF1F4AE91CB0F95B +:109EB00009394018F13C589D40BCEF1B884C7B0190 +:109EC0008BF0891A6DAECD59E2181A5316AA5D307F +:109ED0002CD42A9D70CC3D5176C99438971EFC3EF7 +:109EE0008AF10B70FF324F3D3724FB1C869F78446C +:109EF000A7E04A100E2339759FBB2D3137BD79B5C8 +:109F000070C2149B7A06046B8FA74A4ACE87A5338A +:109F1000AC52418742087F0EDCCD7625ECA5324C51 +:109F200000750904B32392AEB5A1095DCF875B4FDD +:109F30005D3FE6A37B6517D903C5D53EE7B3508BDC +:109F40003A46A5C6A84334E6488CEAC93DCAF5811D +:109F500052D018A6787625B583097D7A07F448D6BD +:109F60004DFD06F76180B2CAE69C7315898F642B9C +:109F70001151A79CF9F7DFA442DB34C1C14A74EA4E +:109F80005AFA122935ECB0A7C858B343BA3FDE924B +:109F9000127A25CB068D6CA1145824311613D044A7 +:109FA000738F09F9DDBF75294D16CA86242DDEA8E9 +:109FB00003612C0C2B3C0A06232B913CEFA028A913 +:109FC000133CF527324AB7F0BF2A48C01EFC56E4BE +:109FD0000A977F8075B7BEC1AC3A5FCE2AFE593171 +:109FE0001B4F6E71238548A891ACC86EB51D7DEDE1 +:109FF000109C51022FFF3EFFB97EEFC781BFC3E91E +:10A000008810789AF47516DE514AA80DE4C48B5B6B +:10A01000752EC03E923233FDAC303E22BA48F78BEB +:10A02000A5E20CD39B267ED1CFAB191DCDB6147300 +:10A03000A263163221D7F11705E1EBB12AD50E9DA7 +:10A0400034FB70D6CFA4C5D1B4F308DC6604706AC3 +:10A0500074D6C69A5752BE9DBCB0A1B03CB016FF94 +:10A06000497D4FCFDD3C39407661F9CE4663293AD0 +:10A070000D1ED79AE5C3622ABDB18FD3B975B0560C +:10A08000A979A815F62AF49B7CAF4DFB55EE6EFE20 +:10A0900016FA29BDC876D4FA3F4E4B98DCBF7E68CD +:10A0A000755B47FE73C855D96EBC8BDA7A0E5D942A +:10A0B000546B813AC96ABEE366AC8ADBE5BE5EE0FA +:10A0C0008A583E944D91C74071687144CEFEDDF7C9 +:10A0D000A3E66F92D65C20EEB3B269D1C6EEDCBFC8 +:10A0E00064B90D984B4DA1CDB7A928D8756DB97F2E +:10A0F000B051A9E42F99EEB569BC7120922CDBFF19 +:10A1000050AC308D404678DF28C05646305772B389 +:10A1100068DD670E649059C2A03947AF26B1E604E6 +:10A1200061CCF00D358111E45E516141EF22712760 +:10A1300050BB64FC811813590CB3DE92A1B06EDEE3 +:10A140003F32709B5426EDA35EAC7120EAE611C746 +:10A150006A2EE415D836E4AEE28E53884B16AC6C0A +:10A1600081A92E1DC548107C91222054A941501C64 +:10A17000F6A791CA4912452FA6993F8A87321187BF +:10A1800062C570058B8899892AC85C4E844EA7F5F4 +:10A19000B5FA0F053C98DE6DA63D4F973FDE5F098F +:10A1A000AF968B4A7C2A9E8A5C596949536F9537D2 +:10A1B00055D9D949C3891B519B1DE95889468860E7 +:10A1C000B940EFF3D0BC1E40AB60AF339A79A7E53E +:10A1D00070C6F84F037CBAA4828436B68803D4EBE9 +:10A1E000EF3B54B1248D8A280C96CC05530DDE200C +:10A1F000E38DE859CF3DDD293A9137825D3DD92D78 +:10A20000644D181DD0CED1362CB0C35692C6307FC7 +:10A21000C1B98012137D90CE0A34E0171630F47164 +:10A2200067810314CA0E1334D8F1E65EB5A8F61E92 +:10A23000B30083A02110933EA29C1E8ED5B0F73FA1 +:10A240001E4AC504E1A6111C4EE2F05C47868D361D +:10A250004C54A6DF6A50BAB264727CA2F80B758BBC +:10A260009F03B2DDA508422D5463FD7A08BCF45A61 +:10A270008D977ACB0D934B752583612DEC1D27BCF3 +:10A28000840A732E06ADFB3EC756916B4E28AF1E57 +:10A29000591A36280EBB98327E752819A642D574F5 +:10A2A0005D880B544DBD193168D3DAC5072FBF3B0C +:10A2B00055980A7E8E196AEE198E6B21603FAEF3B7 +:10A2C000EA4DFF7E6EF73C62FC0A1D76D26E3D348D +:10A2D000B430BBD0F6BC7F3E01B254CE9E78B9F903 +:10A2E0002E22998A584FA509885B99F5EF1E87851C +:10A2F000B4D14EE00BD8BD88A67DC8A01F8A048AC1 +:10A300008C8EF3EEF16454AF310266601FA2DDAEB5 +:10A31000A8D46782E8940A706DCE383A6854AAA32C +:10A32000E141DC8A99959CAA6187C0E3B90A5698F5 +:10A330007E0607B9F303365858B71AD611FDD3CFA6 +:10A34000F7B1820FACD5B75B0B6AA37BD83CA96988 +:10A3500053B0AB38EB29D5E526B73A8798BB23E84D +:10A36000FEFF6DE20DD5D6ACACC3F13F8EE3F1AD8F +:10A3700011AA871CE15B15FD251DF463BB95F31C39 +:10A380006B68EEA8410A2310E95733DEF4EE0AAAFF +:10A39000D55D8FF3D23A6A02F78FECA5DAEA39E499 +:10A3A000E3E33E47998D83B9F37053CC9F24DFD804 +:10A3B000BA795384F5BFF60059BBCE1917ADD1E178 +:10A3C0000AB706CE762CFCECC0CA5E0995EA615449 +:10A3D00037D03C998A93A3A0C492DF8FF50CA0AF2D +:10A3E0003D58B9776709D8EF27ACF50A2C90D89576 +:10A3F0003126689FF30A1D15575AD52226265D95EA +:10A400007EBA87966459F1913E26E5710F4487958F +:10A41000149B233F946899BC3AFAC993AE32F85220 +:10A420006AF30591C905F3F3CA4BA4900A4576383F +:10A43000C011BA42D2CD402F3B8467A98286540C0A +:10A4400065B49184B7443D12AF2319126B62B470A6 +:10A4500012975CB594767187A16E50D53CADE8B784 +:10A46000DF2CB65BDD45A9012E3B9D0E35A47E0990 +:10A47000ED6AAED58D1A5DBABD1318D1D5D3089249 +:10A480001E6A189E99171F983C2E24C68D2AFD100F +:10A4900012932B8551E413660438723AC6420002C7 +:10A4A00068FB0D99E4F4D4B737ABECDA0E4D508766 +:10A4B0002F19B24A913EC1144739F2C3DEC49DDB65 +:10A4C0004E1C28F00A5C26B43A79CFD536FF92BEEE +:10A4D0000F5EA652D68C3137BEA9E19D817A58B65F +:10A4E0002727D3E5A74DE508F56F3FEBDFB50173EF +:10A4F000AFA75299697F1E1FD3376D853F3C42BD80 +:10A50000EF612406A0473426B83A23556B3E13C4A6 +:10A51000034E8C63834A9C434A83AA252981A9322E +:10A52000B6BB862E1E77960E86D244CF0CF46C7185 +:10A53000A294123C2290021C21518B45AA9CD5BAB0 +:10A54000E2642217FE283194E6E25DCCB0A92A6BC2 +:10A5500088165D47E0431085587043C86F94A79CE8 +:10A56000C561A4770103CC6491705146412A2F1A2A +:10A57000614680D5F3AA957039BCAD48EE0923DE5B +:10A58000FD7789057D739925DF0CE9C42D32669C22 +:10A59000A69DDC6B2699CC4B5A0ABD468580B0BA85 +:10A5A000C34A91D6434E81F65934A345C036A2CE54 +:10A5B00062F27205E2F662254233AD8477AEAC6199 +:10A5C000F1B9F6C71F688791E68A6E0E6F5DFBCD05 +:10A5D0004A98050BE523C2803AADD5407A0E39473B +:10A5E0001C4D8C026E036B72FB19C98FEB5D38C179 +:10A5F00086ED8D2356CDF32203594985A57ADDCF0B +:10A60000C0DE2E0E40DA3E2E2E5365FD94A5247436 +:10A61000F3145EB173104E91541888A2F090F30BAE +:10A62000787A231FF87E333F9DE62ACBABB486763B +:10A63000B2620296326612B60FB51EDED5D77EF52F +:10A640006C93731D7367938B759641D580DA503484 +:10A6500032D6C2969856CFD25E12825303BEF1BF55 +:10A6600006314CE70538FAC23542DA5B4E9A85DD91 +:10A67000D2222F1AF52A31C229DC40514D717E5663 +:10A6800079B28BB5F9FF167A40149FF317EC663A4E +:10A690009E705FD458830BCC5097600C3DBB1A5909 +:10A6A000D30D214FABA79CEE5DA920323FA5133EF1 +:10A6B000F0A91AB41261B9A0178297CEE73FE6AAB3 +:10A6C0001ED5490032AEC17EE1AFC95A561CEC7CA2 +:10A6D00076386F5FB6EEC0903C5C6ACDDEFC7B7D69 +:10A6E000D04D2B1118DC479123C04B30D7EDFA7EAB +:10A6F000E771C83F9B59322A3F29D9D4DFFDFB7F40 +:10A7000018FD027B98F9125B715C220FA11D2915BF +:10A710009FAC03ADF012138DB837438D8D4BEC8F8A +:10A72000271CAA84A718BAA46885214562A3AF5F35 +:10A73000224D08E1A24918C11A17C3EFDFD7D6414D +:10A740004C208B021FBA163FE600C94246E4492856 +:10A75000A56E64E5D26BE878B247E6455509CAB9FB +:10A760006703D680E1C39242F7A388C0C97775A773 +:10A7700011776681BB954E5A01F180664239D1CB83 +:10A78000898F9FB7098B8F9716343A678C9620472D +:10A790004A25BBCBCA21ABEB647BDC64C439B45A19 +:10A7A000DC740D875C701DA7E4DACD61135CE239BF +:10A7B000074358E7874748C7A6AB26A3C336811C83 +:10A7C000AFFEADCDCDB475064A7AEDC7D6707C43E9 +:10A7D0003B28AC70E61F9D58426AEC8F8524AA7115 +:10A7E00059B488C2E7B296EEF1E9894FA7EB5F2032 +:10A7F000AB1DF0CD9D3D60A916A8EBD43B3C381AAB +:10A8000084F0461AA4023054E726112DEEB3D7F691 +:10A81000F9620960A25F9440E5836C7EC4C4F78B43 +:10A820005B84059965C421B40BE6E2FEF80197D27A +:10A8300053954410D33B371B31CD8FDBF555D7C132 +:10A840001CDFD86474804EF8A3006098F4E676F4B8 +:10A85000482D21297F34B5CFEC703CE1FCF677F52B +:10A8600009E7A0BAB1B534CCC967C19DF5E7F6F6E2 +:10A87000805726D6FE3535CD4541A7F6FDF7F7F7CB +:10A88000D679A095EFEC4A1748EA6AF4F62C67BF30 +:10A890001661D8F596A3C2BFE9C4070A7E747DBBD2 +:10A8A000DC09EF7FF20DF5006E9A92758F1DF4CAE8 +:10A8B000485BA1D9A1471C684107A59354D4FB85E7 +:10A8C00006077FDEB22CBCC6162EBF57F6EE7EFC06 +:10A8D0004646D09B8E1359B2067EEE13FEFE7FFDD8 +:10A8E0004F5702DC332D12B157094253F7EFFEFEEA +:10A8F000A293A93F8F12D5B2807FB64BFFFFEECD5A +:10A90000000000008004102010204040902450607F +:10A910000810010188141121183041419834516107 +:10A9200001018002810590221121C0429125D0624F +:10A9300009118103891591231931C1439935D163D7 +:10A9400040400204C044122450604244D064526427 +:10A9500048500305C854132558704345D8745365AF +:10A9600041418206C14592265161C246D165D266F7 +:10A9700049518307C95593275971C347D975D3677F +:10A9800002080808820C182812284848922C586897 +:10A990000A1809098A1C19291A3849499A3C59691F +:10A9A0000309880A830D982A1329C84A932DD86A67 +:10A9B0000B19890B8B1D992B1B39C94B9B3DD96BEF +:10A9C00042480A0CC24C1A2C52684A4CD26C5A6C3F +:10A9D0004A580B0DCA5C1B2D5A784B4DDA7C5B6DC7 +:10A9E00043498A0EC34D9A2E5369CA4ED36DDA6E0F +:10A9F0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F97 +:10AA0000048020108484303014A0605094A47070AE +:10AA10000C9021118C9431311CB061519CB4717136 +:10AA20000581A0128585B03215A1E05295A5F0727E +:10AA30000D91A1138D95B1331DB1E1539DB5F17306 +:10AA400044C02214C4C4323454E06254D4E4727456 +:10AA50004CD02315CCD433355CF06355DCF47375DE +:10AA600045C1A216C5C5B23655E1E256D5E5F27626 +:10AA70004DD1A317CDD5B3375DF1E357DDF5F377AE +:10AA800006882818868C383816A8685896AC7878C6 +:10AA90000E9829198E9C39391EB869599EBC79794E +:10AAA0000789A81A878DB83A17A9E85A97ADF87A96 +:10AAB0000F99A91B8F9DB93B1FB9E95B9FBDF97B1E +:10AAC00046C82A1CC6CC3A3C56E86A5CD6EC7A7C6E +:10AAD0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7DF6 +:10AAE00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7E3E +:10AAF0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7FC6 +:10AB000020020480A00614A0302244C0B02654E0E5 +:10AB100028120581A81615A1383245C1B83655E16D +:10AB200021038482A10794A23123C4C2B127D4E2B5 +:10AB300029138583A91795A33933C5C3B937D5E33D +:10AB400060420684E04616A4706246C4F06656E48D +:10AB500068520785E85617A5787247C5F87657E515 +:10AB600061438686E14796A67163C6C6F167D6E65D +:10AB700069538787E95797A77973C7C7F977D7E7E5 +:10AB8000220A0C88A20E1CA8322A4CC8B22E5CE8FD +:10AB90002A1A0D89AA1E1DA93A3A4DC9BA3E5DE985 +:10ABA000230B8C8AA30F9CAA332BCCCAB32FDCEACD +:10ABB0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEB55 +:10ABC000624A0E8CE24E1EAC726A4ECCF26E5EECA5 +:10ABD0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FED2D +:10ABE000634B8E8EE34F9EAE736BCECEF36FDEEE75 +:10ABF0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEFFD +:10AC000024822490A48634B034A264D0B4A674F014 +:10AC10002C922591AC9635B13CB265D1BCB675F19C +:10AC20002583A492A587B4B235A3E4D2B5A7F4F2E4 +:10AC30002D93A593AD97B5B33DB3E5D3BDB7F5F36C +:10AC400064C22694E4C636B474E266D4F4E676F4BC +:10AC50006CD22795ECD637B57CF267D5FCF677F544 +:10AC600065C3A696E5C7B6B675E3E6D6F5E7F6F68C +:10AC70006DD3A797EDD7B7B77DF3E7D7FDF7F7F714 +:10AC8000268A2C98A68E3CB836AA6CD8B6AE7CF82C +:10AC90002E9A2D99AE9E3DB93EBA6DD9BEBE7DF9B4 +:10ACA000278BAC9AA78FBCBA37ABECDAB7AFFCFAFC +:10ACB0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFB84 +:10ACC00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFCD4 +:10ACD0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFD5C +:10ACE00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFEA4 +:10ACF0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFF2C +:10AD0000000000008004102010204040902450607B +:10AD10000810010188141121183041419834516103 +:10AD200001018002810590221121C0429125D0624B +:10AD300009118103891591231931C1439935D163D3 +:10AD400040400204C044122450604244D064526423 +:10AD500048500305C854132558704345D8745365AB +:10AD600041418206C14592265161C246D165D266F3 +:10AD700049518307C95593275971C347D975D3677B +:10AD800002080808820C182812284848922C586893 +:10AD90000A1809098A1C19291A3849499A3C59691B +:10ADA0000309880A830D982A1329C84A932DD86A63 +:10ADB0000B19890B8B1D992B1B39C94B9B3DD96BEB +:10ADC00042480A0CC24C1A2C52684A4CD26C5A6C3B +:10ADD0004A580B0DCA5C1B2D5A784B4DDA7C5B6DC3 +:10ADE00043498A0EC34D9A2E5369CA4ED36DDA6E0B +:10ADF0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F93 +:10AE0000048020108484303014A0605094A47070AA +:10AE10000C9021118C9431311CB061519CB4717132 +:10AE20000581A0128585B03215A1E05295A5F0727A +:10AE30000D91A1138D95B1331DB1E1539DB5F17302 +:10AE400044C02214C4C4323454E06254D4E4727452 +:10AE50004CD02315CCD433355CF06355DCF47375DA +:10AE600045C1A216C5C5B23655E1E256D5E5F27622 +:10AE70004DD1A317CDD5B3375DF1E357DDF5F377AA +:10AE800006882818868C383816A8685896AC7878C2 +:10AE90000E9829198E9C39391EB869599EBC79794A +:10AEA0000789A81A878DB83A17A9E85A97ADF87A92 +:10AEB0000F99A91B8F9DB93B1FB9E95B9FBDF97B1A +:10AEC00046C82A1CC6CC3A3C56E86A5CD6EC7A7C6A +:10AED0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7DF2 +:10AEE00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7E3A +:10AEF0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7FC2 +:10AF000020020480A00614A0302244C0B02654E0E1 +:10AF100028120581A81615A1383245C1B83655E169 +:10AF200021038482A10794A23123C4C2B127D4E2B1 +:10AF300029138583A91795A33933C5C3B937D5E339 +:10AF400060420684E04616A4706246C4F06656E489 +:10AF500068520785E85617A5787247C5F87657E511 +:10AF600061438686E14796A67163C6C6F167D6E659 +:10AF700069538787E95797A77973C7C7F977D7E7E1 +:10AF8000220A0C88A20E1CA8322A4CC8B22E5CE8F9 +:10AF90002A1A0D89AA1E1DA93A3A4DC9BA3E5DE981 +:10AFA000230B8C8AA30F9CAA332BCCCAB32FDCEAC9 +:10AFB0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEB51 +:10AFC000624A0E8CE24E1EAC726A4ECCF26E5EECA1 +:10AFD0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FED29 +:10AFE000634B8E8EE34F9EAE736BCECEF36FDEEE71 +:10AFF0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEFF9 +:10B0000024822490A48634B034A264D0B4A674F010 +:10B010002C922591AC9635B13CB265D1BCB675F198 +:10B020002583A492A587B4B235A3E4D2B5A7F4F2E0 +:10B030002D93A593AD97B5B33DB3E5D3BDB7F5F368 +:10B0400064C22694E4C636B474E266D4F4E676F4B8 +:10B050006CD22795ECD637B57CF267D5FCF677F540 +:10B0600065C3A696E5C7B6B675E3E6D6F5E7F6F688 +:10B070006DD3A797EDD7B7B77DF3E7D7FDF7F7F710 +:10B08000268A2C98A68E3CB836AA6CD8B6AE7CF828 +:10B090002E9A2D99AE9E3DB93EBA6DD9BEBE7DF9B0 +:10B0A000278BAC9AA78FBCBA37ABECDAB7AFFCFAF8 +:10B0B0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFB80 +:10B0C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFCD0 +:10B0D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFD58 +:10B0E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFEA0 +:10B0F0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFF28 +:10B100000000000080041020102040409024506077 +:10B1100008100101881411211830414198345161FF +:10B1200001018002810590221121C0429125D06247 +:10B1300009118103891591231931C1439935D163CF +:10B1400040400204C044122450604244D06452641F +:10B1500048500305C854132558704345D8745365A7 +:10B1600041418206C14592265161C246D165D266EF +:10B1700049518307C95593275971C347D975D36777 +:10B1800002080808820C182812284848922C58688F +:10B190000A1809098A1C19291A3849499A3C596917 +:10B1A0000309880A830D982A1329C84A932DD86A5F +:10B1B0000B19890B8B1D992B1B39C94B9B3DD96BE7 +:10B1C00042480A0CC24C1A2C52684A4CD26C5A6C37 +:10B1D0004A580B0DCA5C1B2D5A784B4DDA7C5B6DBF +:10B1E00043498A0EC34D9A2E5369CA4ED36DDA6E07 +:10B1F0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F8F +:10B20000048020108484303014A0605094A47070A6 +:10B210000C9021118C9431311CB061519CB471712E +:10B220000581A0128585B03215A1E05295A5F07276 +:10B230000D91A1138D95B1331DB1E1539DB5F173FE +:10B2400044C02214C4C4323454E06254D4E472744E +:10B250004CD02315CCD433355CF06355DCF47375D6 +:10B2600045C1A216C5C5B23655E1E256D5E5F2761E +:10B270004DD1A317CDD5B3375DF1E357DDF5F377A6 +:10B2800006882818868C383816A8685896AC7878BE +:10B290000E9829198E9C39391EB869599EBC797946 +:10B2A0000789A81A878DB83A17A9E85A97ADF87A8E +:10B2B0000F99A91B8F9DB93B1FB9E95B9FBDF97B16 +:10B2C00046C82A1CC6CC3A3C56E86A5CD6EC7A7C66 +:10B2D0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7DEE +:10B2E00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7E36 +:10B2F0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7FBE +:10B3000020020480A00614A0302244C0B02654E0DD +:10B3100028120581A81615A1383245C1B83655E165 +:10B3200021038482A10794A23123C4C2B127D4E2AD +:10B3300029138583A91795A33933C5C3B937D5E335 +:10B3400060420684E04616A4706246C4F06656E485 +:10B3500068520785E85617A5787247C5F87657E50D +:10B3600061438686E14796A67163C6C6F167D6E655 +:10B3700069538787E95797A77973C7C7F977D7E7DD +:10B38000220A0C88A20E1CA8322A4CC8B22E5CE8F5 +:10B390002A1A0D89AA1E1DA93A3A4DC9BA3E5DE97D +:10B3A000230B8C8AA30F9CAA332BCCCAB32FDCEAC5 +:10B3B0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEB4D +:10B3C000624A0E8CE24E1EAC726A4ECCF26E5EEC9D +:10B3D0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FED25 +:10B3E000634B8E8EE34F9EAE736BCECEF36FDEEE6D +:10B3F0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEFF5 +:10B4000024822490A48634B034A264D0B4A674F00C +:10B410002C922591AC9635B13CB265D1BCB675F194 +:10B420002583A492A587B4B235A3E4D2B5A7F4F2DC +:10B430002D93A593AD97B5B33DB3E5D3BDB7F5F364 +:10B4400064C22694E4C636B474E266D4F4E676F4B4 +:10B450006CD22795ECD637B57CF267D5FCF677F53C +:10B4600065C3A696E5C7B6B675E3E6D6F5E7F6F684 +:10B470006DD3A797EDD7B7B77DF3E7D7FDF7F7F70C +:10B48000268A2C98A68E3CB836AA6CD8B6AE7CF824 +:10B490002E9A2D99AE9E3DB93EBA6DD9BEBE7DF9AC +:10B4A000278BAC9AA78FBCBA37ABECDAB7AFFCFAF4 +:10B4B0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFB7C +:10B4C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFCCC +:10B4D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFD54 +:10B4E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE9C +:10B4F0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFF24 +:10B500000000000080041020102040409024506073 +:10B5100008100101881411211830414198345161FB +:10B5200001018002810590221121C0429125D06243 +:10B5300009118103891591231931C1439935D163CB +:10B5400040400204C044122450604244D06452641B +:10B5500048500305C854132558704345D8745365A3 +:10B5600041418206C14592265161C246D165D266EB +:10B5700049518307C95593275971C347D975D36773 +:10B5800002080808820C182812284848922C58688B +:10B590000A1809098A1C19291A3849499A3C596913 +:10B5A0000309880A830D982A1329C84A932DD86A5B +:10B5B0000B19890B8B1D992B1B39C94B9B3DD96BE3 +:10B5C00042480A0CC24C1A2C52684A4CD26C5A6C33 +:10B5D0004A580B0DCA5C1B2D5A784B4DDA7C5B6DBB +:10B5E00043498A0EC34D9A2E5369CA4ED36DDA6E03 +:10B5F0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F8B +:10B60000048020108484303014A0605094A47070A2 +:10B610000C9021118C9431311CB061519CB471712A +:10B620000581A0128585B03215A1E05295A5F07272 +:10B630000D91A1138D95B1331DB1E1539DB5F173FA +:10B6400044C02214C4C4323454E06254D4E472744A +:10B650004CD02315CCD433355CF06355DCF47375D2 +:10B6600045C1A216C5C5B23655E1E256D5E5F2761A +:10B670004DD1A317CDD5B3375DF1E357DDF5F377A2 +:10B6800006882818868C383816A8685896AC7878BA +:10B690000E9829198E9C39391EB869599EBC797942 +:10B6A0000789A81A878DB83A17A9E85A97ADF87A8A +:10B6B0000F99A91B8F9DB93B1FB9E95B9FBDF97B12 +:10B6C00046C82A1CC6CC3A3C56E86A5CD6EC7A7C62 +:10B6D0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7DEA +:10B6E00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7E32 +:10B6F0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7FBA +:10B7000020020480A00614A0302244C0B02654E0D9 +:10B7100028120581A81615A1383245C1B83655E161 +:10B7200021038482A10794A23123C4C2B127D4E2A9 +:10B7300029138583A91795A33933C5C3B937D5E331 +:10B7400060420684E04616A4706246C4F06656E481 +:10B7500068520785E85617A5787247C5F87657E509 +:10B7600061438686E14796A67163C6C6F167D6E651 +:10B7700069538787E95797A77973C7C7F977D7E7D9 +:10B78000220A0C88A20E1CA8322A4CC8B22E5CE8F1 +:10B790002A1A0D89AA1E1DA93A3A4DC9BA3E5DE979 +:10B7A000230B8C8AA30F9CAA332BCCCAB32FDCEAC1 +:10B7B0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEB49 +:10B7C000624A0E8CE24E1EAC726A4ECCF26E5EEC99 +:10B7D0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FED21 +:10B7E000634B8E8EE34F9EAE736BCECEF36FDEEE69 +:10B7F0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEFF1 +:10B8000024822490A48634B034A264D0B4A674F008 +:10B810002C922591AC9635B13CB265D1BCB675F190 +:10B820002583A492A587B4B235A3E4D2B5A7F4F2D8 +:10B830002D93A593AD97B5B33DB3E5D3BDB7F5F360 +:10B8400064C22694E4C636B474E266D4F4E676F4B0 +:10B850006CD22795ECD637B57CF267D5FCF677F538 +:10B8600065C3A696E5C7B6B675E3E6D6F5E7F6F680 +:10B870006DD3A797EDD7B7B77DF3E7D7FDF7F7F708 +:10B88000268A2C98A68E3CB836AA6CD8B6AE7CF820 +:10B890002E9A2D99AE9E3DB93EBA6DD9BEBE7DF9A8 +:10B8A000278BAC9AA78FBCBA37ABECDAB7AFFCFAF0 +:10B8B0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFB78 +:10B8C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFCC8 +:10B8D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFD50 +:10B8E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE98 +:10B8F0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFF20 +:10B90000000000008004102010204040902450606F +:10B9100008100101881411211830414198345161F7 +:10B9200001018002810590221121C0429125D0623F +:10B9300009118103891591231931C1439935D163C7 +:10B9400040400204C044122450604244D064526417 +:10B9500048500305C854132558704345D87453659F +:10B9600041418206C14592265161C246D165D266E7 +:10B9700049518307C95593275971C347D975D3676F +:10B9800002080808820C182812284848922C586887 +:10B990000A1809098A1C19291A3849499A3C59690F +:10B9A0000309880A830D982A1329C84A932DD86A57 +:10B9B0000B19890B8B1D992B1B39C94B9B3DD96BDF +:10B9C00042480A0CC24C1A2C52684A4CD26C5A6C2F +:10B9D0004A580B0DCA5C1B2D5A784B4DDA7C5B6DB7 +:10B9E00043498A0EC34D9A2E5369CA4ED36DDA6EFF +:10B9F0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F87 +:10BA0000048020108484303014A0605094A470709E +:10BA10000C9021118C9431311CB061519CB4717126 +:10BA20000581A0128585B03215A1E05295A5F0726E +:10BA30000D91A1138D95B1331DB1E1539DB5F173F6 +:10BA400044C02214C4C4323454E06254D4E4727446 +:10BA50004CD02315CCD433355CF06355DCF47375CE +:10BA600045C1A216C5C5B23655E1E256D5E5F27616 +:10BA70004DD1A317CDD5B3375DF1E357DDF5F3779E +:10BA800006882818868C383816A8685896AC7878B6 +:10BA90000E9829198E9C39391EB869599EBC79793E +:10BAA0000789A81A878DB83A17A9E85A97ADF87A86 +:10BAB0000F99A91B8F9DB93B1FB9E95B9FBDF97B0E +:10BAC00046C82A1CC6CC3A3C56E86A5CD6EC7A7C5E +:10BAD0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7DE6 +:10BAE00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7E2E +:10BAF0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7FB6 +:10BB000020020480A00614A0302244C0B02654E0D5 +:10BB100028120581A81615A1383245C1B83655E15D +:10BB200021038482A10794A23123C4C2B127D4E2A5 +:10BB300029138583A91795A33933C5C3B937D5E32D +:10BB400060420684E04616A4706246C4F06656E47D +:10BB500068520785E85617A5787247C5F87657E505 +:10BB600061438686E14796A67163C6C6F167D6E64D +:10BB700069538787E95797A77973C7C7F977D7E7D5 +:10BB8000220A0C88A20E1CA8322A4CC8B22E5CE8ED +:10BB90002A1A0D89AA1E1DA93A3A4DC9BA3E5DE975 +:10BBA000230B8C8AA30F9CAA332BCCCAB32FDCEABD +:10BBB0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEB45 +:10BBC000624A0E8CE24E1EAC726A4ECCF26E5EEC95 +:10BBD0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FED1D +:10BBE000634B8E8EE34F9EAE736BCECEF36FDEEE65 +:10BBF0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEFED +:10BC000024822490A48634B034A264D0B4A674F004 +:10BC10002C922591AC9635B13CB265D1BCB675F18C +:10BC20002583A492A587B4B235A3E4D2B5A7F4F2D4 +:10BC30002D93A593AD97B5B33DB3E5D3BDB7F5F35C +:10BC400064C22694E4C636B474E266D4F4E676F4AC +:10BC50006CD22795ECD637B57CF267D5FCF677F534 +:10BC600065C3A696E5C7B6B675E3E6D6F5E7F6F67C +:10BC70006DD3A797EDD7B7B77DF3E7D7FDF7F7F704 +:10BC8000268A2C98A68E3CB836AA6CD8B6AE7CF81C +:10BC90002E9A2D99AE9E3DB93EBA6DD9BEBE7DF9A4 +:10BCA000278BAC9AA78FBCBA37ABECDAB7AFFCFAEC +:10BCB0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFB74 +:10BCC00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFCC4 +:10BCD0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFD4C +:10BCE00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE94 +:10BCF0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFF1C +:10BD0000000000008004102010204040902450606B +:10BD100008100101881411211830414198345161F3 +:10BD200001018002810590221121C0429125D0623B +:10BD300009118103891591231931C1439935D163C3 +:10BD400040400204C044122450604244D064526413 +:10BD500048500305C854132558704345D87453659B +:10BD600041418206C14592265161C246D165D266E3 +:10BD700049518307C95593275971C347D975D3676B +:10BD800002080808820C182812284848922C586883 +:10BD90000A1809098A1C19291A3849499A3C59690B +:10BDA0000309880A830D982A1329C84A932DD86A53 +:10BDB0000B19890B8B1D992B1B39C94B9B3DD96BDB +:10BDC00042480A0CC24C1A2C52684A4CD26C5A6C2B +:10BDD0004A580B0DCA5C1B2D5A784B4DDA7C5B6DB3 +:10BDE00043498A0EC34D9A2E5369CA4ED36DDA6EFB +:10BDF0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F83 +:10BE0000048020108484303014A0605094A470709A +:10BE10000C9021118C9431311CB061519CB4717122 +:10BE20000581A0128585B03215A1E05295A5F0726A +:10BE30000D91A1138D95B1331DB1E1539DB5F173F2 +:10BE400044C02214C4C4323454E06254D4E4727442 +:10BE50004CD02315CCD433355CF06355DCF47375CA +:10BE600045C1A216C5C5B23655E1E256D5E5F27612 +:10BE70004DD1A317CDD5B3375DF1E357DDF5F3779A +:10BE800006882818868C383816A8685896AC7878B2 +:10BE90000E9829198E9C39391EB869599EBC79793A +:10BEA0000789A81A878DB83A17A9E85A97ADF87A82 +:10BEB0000F99A91B8F9DB93B1FB9E95B9FBDF97B0A +:10BEC00046C82A1CC6CC3A3C56E86A5CD6EC7A7C5A +:10BED0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7DE2 +:10BEE00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7E2A +:10BEF0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7FB2 +:10BF000020020480A00614A0302244C0B02654E0D1 +:10BF100028120581A81615A1383245C1B83655E159 +:10BF200021038482A10794A23123C4C2B127D4E2A1 +:10BF300029138583A91795A33933C5C3B937D5E329 +:10BF400060420684E04616A4706246C4F06656E479 +:10BF500068520785E85617A5787247C5F87657E501 +:10BF600061438686E14796A67163C6C6F167D6E649 +:10BF700069538787E95797A77973C7C7F977D7E7D1 +:10BF8000220A0C88A20E1CA8322A4CC8B22E5CE8E9 +:10BF90002A1A0D89AA1E1DA93A3A4DC9BA3E5DE971 +:10BFA000230B8C8AA30F9CAA332BCCCAB32FDCEAB9 +:10BFB0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEB41 +:10BFC000624A0E8CE24E1EAC726A4ECCF26E5EEC91 +:10BFD0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FED19 +:10BFE000634B8E8EE34F9EAE736BCECEF36FDEEE61 +:10BFF0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEFE9 +:10C0000024822490A48634B034A264D0B4A674F000 +:10C010002C922591AC9635B13CB265D1BCB675F188 +:10C020002583A492A587B4B235A3E4D2B5A7F4F2D0 +:10C030002D93A593AD97B5B33DB3E5D3BDB7F5F358 +:10C0400064C22694E4C636B474E266D4F4E676F4A8 +:10C050006CD22795ECD637B57CF267D5FCF677F530 +:10C0600065C3A696E5C7B6B675E3E6D6F5E7F6F678 +:10C070006DD3A797EDD7B7B77DF3E7D7FDF7F7F700 +:10C08000268A2C98A68E3CB836AA6CD8B6AE7CF818 +:10C090002E9A2D99AE9E3DB93EBA6DD9BEBE7DF9A0 +:10C0A000278BAC9AA78FBCBA37ABECDAB7AFFCFAE8 +:10C0B0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFB70 +:10C0C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFCC0 +:10C0D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFD48 +:10C0E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE90 +:10C0F0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFF18 +:10C100000000000080041020102040409024506067 +:10C1100008100101881411211830414198345161EF +:10C1200001018002810590221121C0429125D06237 +:10C1300009118103891591231931C1439935D163BF +:10C1400040400204C044122450604244D06452640F +:10C1500048500305C854132558704345D874536597 +:10C1600041418206C14592265161C246D165D266DF +:10C1700049518307C95593275971C347D975D36767 +:10C1800002080808820C182812284848922C58687F +:10C190000A1809098A1C19291A3849499A3C596907 +:10C1A0000309880A830D982A1329C84A932DD86A4F +:10C1B0000B19890B8B1D992B1B39C94B9B3DD96BD7 +:10C1C00042480A0CC24C1A2C52684A4CD26C5A6C27 +:10C1D0004A580B0DCA5C1B2D5A784B4DDA7C5B6DAF +:10C1E00043498A0EC34D9A2E5369CA4ED36DDA6EF7 +:10C1F0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F7F +:10C20000048020108484303014A0605094A4707096 +:10C210000C9021118C9431311CB061519CB471711E +:10C220000581A0128585B03215A1E05295A5F07266 +:10C230000D91A1138D95B1331DB1E1539DB5F173EE +:10C2400044C02214C4C4323454E06254D4E472743E +:10C250004CD02315CCD433355CF06355DCF47375C6 +:10C2600045C1A216C5C5B23655E1E256D5E5F2760E +:10C270004DD1A317CDD5B3375DF1E357DDF5F37796 +:10C2800006882818868C383816A8685896AC7878AE +:10C290000E9829198E9C39391EB869599EBC797936 +:10C2A0000789A81A878DB83A17A9E85A97ADF87A7E +:10C2B0000F99A91B8F9DB93B1FB9E95B9FBDF97B06 +:10C2C00046C82A1CC6CC3A3C56E86A5CD6EC7A7C56 +:10C2D0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7DDE +:10C2E00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7E26 +:10C2F0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7FAE +:10C3000020020480A00614A0302244C0B02654E0CD +:10C3100028120581A81615A1383245C1B83655E155 +:10C3200021038482A10794A23123C4C2B127D4E29D +:10C3300029138583A91795A33933C5C3B937D5E325 +:10C3400060420684E04616A4706246C4F06656E475 +:10C3500068520785E85617A5787247C5F87657E5FD +:10C3600061438686E14796A67163C6C6F167D6E645 +:10C3700069538787E95797A77973C7C7F977D7E7CD +:10C38000220A0C88A20E1CA8322A4CC8B22E5CE8E5 +:10C390002A1A0D89AA1E1DA93A3A4DC9BA3E5DE96D +:10C3A000230B8C8AA30F9CAA332BCCCAB32FDCEAB5 +:10C3B0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEB3D +:10C3C000624A0E8CE24E1EAC726A4ECCF26E5EEC8D +:10C3D0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FED15 +:10C3E000634B8E8EE34F9EAE736BCECEF36FDEEE5D +:10C3F0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEFE5 +:10C4000024822490A48634B034A264D0B4A674F0FC +:10C410002C922591AC9635B13CB265D1BCB675F184 +:10C420002583A492A587B4B235A3E4D2B5A7F4F2CC +:10C430002D93A593AD97B5B33DB3E5D3BDB7F5F354 +:10C4400064C22694E4C636B474E266D4F4E676F4A4 +:10C450006CD22795ECD637B57CF267D5FCF677F52C +:10C4600065C3A696E5C7B6B675E3E6D6F5E7F6F674 +:10C470006DD3A797EDD7B7B77DF3E7D7FDF7F7F7FC +:10C48000268A2C98A68E3CB836AA6CD8B6AE7CF814 +:10C490002E9A2D99AE9E3DB93EBA6DD9BEBE7DF99C +:10C4A000278BAC9AA78FBCBA37ABECDAB7AFFCFAE4 +:10C4B0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFB6C +:10C4C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFCBC +:10C4D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFD44 +:10C4E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE8C +:10C4F0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFF14 +:10C500000000000080041020102040409024506063 +:10C5100008100101881411211830414198345161EB +:10C5200001018002810590221121C0429125D06233 +:10C5300009118103891591231931C1439935D163BB +:10C5400040400204C044122450604244D06452640B +:10C5500048500305C854132558704345D874536593 +:10C5600041418206C14592265161C246D165D266DB +:10C5700049518307C95593275971C347D975D36763 +:10C5800002080808820C182812284848922C58687B +:10C590000A1809098A1C19291A3849499A3C596903 +:10C5A0000309880A830D982A1329C84A932DD86A4B +:10C5B0000B19890B8B1D992B1B39C94B9B3DD96BD3 +:10C5C00042480A0CC24C1A2C52684A4CD26C5A6C23 +:10C5D0004A580B0DCA5C1B2D5A784B4DDA7C5B6DAB +:10C5E00043498A0EC34D9A2E5369CA4ED36DDA6EF3 +:10C5F0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F7B +:10C60000048020108484303014A0605094A4707092 +:10C610000C9021118C9431311CB061519CB471711A +:10C620000581A0128585B03215A1E05295A5F07262 +:10C630000D91A1138D95B1331DB1E1539DB5F173EA +:10C6400044C02214C4C4323454E06254D4E472743A +:10C650004CD02315CCD433355CF06355DCF47375C2 +:10C6600045C1A216C5C5B23655E1E256D5E5F2760A +:10C670004DD1A317CDD5B3375DF1E357DDF5F37792 +:10C6800006882818868C383816A8685896AC7878AA +:10C690000E9829198E9C39391EB869599EBC797932 +:10C6A0000789A81A878DB83A17A9E85A97ADF87A7A +:10C6B0000F99A91B8F9DB93B1FB9E95B9FBDF97B02 +:10C6C00046C82A1CC6CC3A3C56E86A5CD6EC7A7C52 +:10C6D0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7DDA +:10C6E00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7E22 +:10C6F0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7FAA +:10C7000020020480A00614A0302244C0B02654E0C9 +:10C7100028120581A81615A1383245C1B83655E151 +:10C7200021038482A10794A23123C4C2B127D4E299 +:10C7300029138583A91795A33933C5C3B937D5E321 +:10C7400060420684E04616A4706246C4F06656E471 +:10C7500068520785E85617A5787247C5F87657E5F9 +:10C7600061438686E14796A67163C6C6F167D6E641 +:10C7700069538787E95797A77973C7C7F977D7E7C9 +:10C78000220A0C88A20E1CA8322A4CC8B22E5CE8E1 +:10C790002A1A0D89AA1E1DA93A3A4DC9BA3E5DE969 +:10C7A000230B8C8AA30F9CAA332BCCCAB32FDCEAB1 +:10C7B0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEB39 +:10C7C000624A0E8CE24E1EAC726A4ECCF26E5EEC89 +:10C7D0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FED11 +:10C7E000634B8E8EE34F9EAE736BCECEF36FDEEE59 +:10C7F0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEFE1 +:10C8000024822490A48634B034A264D0B4A674F0F8 +:10C810002C922591AC9635B13CB265D1BCB675F180 +:10C820002583A492A587B4B235A3E4D2B5A7F4F2C8 +:10C830002D93A593AD97B5B33DB3E5D3BDB7F5F350 +:10C8400064C22694E4C636B474E266D4F4E676F4A0 +:10C850006CD22795ECD637B57CF267D5FCF677F528 +:10C8600065C3A696E5C7B6B675E3E6D6F5E7F6F670 +:10C870006DD3A797EDD7B7B77DF3E7D7FDF7F7F7F8 +:10C88000268A2C98A68E3CB836AA6CD8B6AE7CF810 +:10C890002E9A2D99AE9E3DB93EBA6DD9BEBE7DF998 +:10C8A000278BAC9AA78FBCBA37ABECDAB7AFFCFAE0 +:10C8B0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFB68 +:10C8C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFCB8 +:10C8D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFD40 +:10C8E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE88 +:10C8F0006FDBAF9FEFDFBFBF7FFBEFDFFFFF07FF08 +:10C900005982E5AB7FF5B3A01156BFCDCA2038538D +:10C9100008E385ACB6A57A2E61B44D7C14C7DD6CF6 +:10C9200079056083BFB070636ADA777DEF2331E108 +:10C9300071A184AC0927F171304B507F0946F3C8CF +:10C94000ACDFF3D2E6F096803B02BD42405A3C9108 +:10C95000F7B2814D9952DBC606920348710AC6248C +:10C96000D11E21639742B682CEAA6307802A2F1A6E +:10C97000C9337C626D7132F8A056623826172002E6 +:10C98000A62C3B0EFC0AF1272D63DD95EA28B8E9B9 +:10C990003828FEA61A2373898A5ABE2CE11BF8D6C2 +:10C9A000B9F82B4AD1ED734EBA66353613092767AD +:10C9B000AB6A2A88DDED1EDA23C64B633742039447 +:10C9C0007A6CE760762EE5406D4C3C20EA97D59A6C +:10C9D0003527D180559ABA6CA506E828215BFA0163 +:10C9E00087B60503532F65289797372CE8F3FE6326 +:10C9F0002959AF09F3A23722E49BEFE2B9292EE9C6 +:10CA000084B240505B8047186CA480D16BCF1B7FF1 +:10CA100056E34BBAB220D190A8D29EFC0C45D2313D +:10CA2000957FA692157413C29585418D159790F246 +:10CA3000759541925B6635BE4B404213A319F7B31F +:10CA40007C3A8E19FC963C56011B934710617CFE84 +:10CA5000DCB2D47037DCD6CACE0F71985CC6133501 +:10CA6000E95E53C08FC096FB2E9FC6DB12C1997939 +:10CA7000759661BD96D5C8F70F0A143B4D0E12E4AA +:10CA800086AC89C7D06ED35C24986C1993CE8B1D6D +:10CA9000869C8886F376BB039E8A0919F9C2AB3857 +:10CAA000B3EB571CB98B9CB729108355AF567787CA +:10CAB000BBFB8DB010FF46578F484ADBA743551587 +:10CAC000FD5A2A5D46C8A0A76E774E5AADAB87CAFD +:10CAD00095D8549D4E57D651EA9A941CDE056F3F67 +:10CAE00018C995E1C734B67E5BF94B816C77DEE5FA +:10CAF000CFD849120B23A3D206720EDE5FEA7482EE +:10CB000028F1888DDE00F523B040B7A50BBCA36DDE +:10CB100092E3A6C190ECB9ACB8412F4441DDE6A345 +:10CB2000DA24257D3EF418E30907AFCDCADCEB1DFE +:10CB30001B23852CD69590E32BED2E873D5C447E00 +:10CB40006C46A75B803BEE58A053E73BF04235B6FE +:10CB5000A660A62E78662D0AE883E485A0CABC816B +:10CB6000D521A28099606BA94FC2E8196694526DD5 +:10CB70001157670649241B2447C7C1076987529686 +:10CB80008279AF0B9AF0B0A50CC82E319B5578E591 +:10CB900012E0A18457EF77899E58BAACE4DC1DA857 +:10CBA0002FF800CB33E71E674D2CE86548087D154C +:10CBB0005464E684F41BEEE303C4786083C171E639 +:10CBC00042B98A21C9BD92217708B9A98C68BF6F83 +:10CBD00055ABACCD8A0409CB07153332C290F3E0D4 +:10CBE0001BFB83CF076B770D4B943B8F3D9C52AF64 +:10CBF000596B8BCE7BDD8415C2C7387257E4FBE2DC +:10CC00005C86CDC3FE17EA4F0692D17F8C34752D1A +:10CC100057B5842E966CCEF3F241E90C1BC0F76D2C +:10CC2000E597BC9F9F15B46D95D04751D7A7D0E924 +:10CC3000133FC5B329FC44F2459418DC7C30D1E89D +:10CC40009FE5AB992039D72B5F11E25964D4164385 +:10CC50008FF6513A55349BC844D6C64AAE8B5370B2 +:10CC60009AB8780B9AE35DD2279E0DB28BE11FF93B +:10CC7000C9B154F295F3359FC9916A21EF481CB3AD +:10CC8000D9F80247983A4017A659E0D513D88BE84F +:10CC9000953FDAD8D0999C66C1C01BB5179AD19C34 +:10CCA00098BA0D6507FCD6694C8C4D2B0D40692751 +:10CCB000768048441BFD42FAFB4510B9874551F682 +:10CCC0005E310AC166ACC1D94D744A51C80C1C050D +:10CCD000CEA98C1E5ABCB23B26980F5D44A1DC98AD +:10CCE00055FB5F31DFEB1F610A016CE4679901EED0 +:10CCF000A1FF2D66C7A17DBF8089C19E401DDB7548 +:10CD000087FF6B0FD6C41E8B97A4CD83DCD7D4CD01 +:10CD1000980F6BFCD9E795AC3006A04EB0D7310B1D +:10CD20008172EE87F90C70A3635CD800E995B3209B +:10CD3000694B9765DB4F7A47ADD3415BE733386C7E +:10CD4000C4B16CC5FC739705689EC1492006846E0A +:10CD5000E4C702749050BAC0B4F40BA674CD7168E5 +:10CD600081036644019BE7DB2EA363D941678024DE +:10CD70008912930A90D7952B5134446618F798C9B5 +:10CD8000FD8C9F1CB88BF3EB72C80F45C0DCB30C55 +:10CD90009A6B6365F4A8F886B68CABB0E2B8D0495C +:10CDA0004B0CF7F5A31DF8856128D80828CF749798 +:10CDB000698D8A315D9910839B3B8BE689A4322F64 +:10CDC000396FAB62D3C89B1A92B63FB1EA4CFB0EE7 +:10CDD0004A1805A0299C472B5AFCCA07ACF8DE81EB +:10CDE00025FC7B88BC0A44B34BC4CC428A57588488 +:10CDF0001DCBCD0786843AA3243E15D2BBA8396249 +:10CE00007C89D552A8D550FBAE30E25BEAA3857F82 +:10CE10001914ACEEDECFDA555E97C2DC4AC71FF8B4 +:10CE200029CDA67EFB8359560F43094121DA53D2FF +:10CE30001FF74A57B7124E71A93524001E5523D843 +:10CE4000DAA2D57100147E37342939590760F344CA +:10CE5000EB24DC053950BE864C9267785C33576E04 +:10CE60007D3E860DFDC0A0FD9164A1A515A2957C17 +:10CE7000F73EA53B32751245EB798400BD717266B1 +:10CE8000386A4AB3AA8D580AD6EA8C85C7354B7ED4 +:10CE9000082DC0FADC6DD25DDEFA8D1BE69B906A30 +:10CEA000798E5515F98B51356F8E15552D2FDBF376 +:10CEB0007D9168B6B57F15C6B32EEA1BE79A9A5BDB +:10CEC000154CF3839FF6DBFDC600F09116AEE01221 +:10CED00054D90A5DB126B63B9EBB961F5F7E0633D2 +:10CEE000271C5413B8455FBD4FED43BB30972C76DC +:10CEF00073EE9849017A1A89732C6A52E702FD830E +:10CF00001AF16A2DB2F8FFE4666586028EC4364BCC +:10CF10002D968CD9D611F4C7D4A017C90C5453CD73 +:10CF200077FDEF8D9F00F63E39362D61CF20753DA0 +:10CF3000E954BD0F56931C83BBB74800B907CF4CCB +:10CF4000E6316CEAAA5B34A993A21AC213A616FFB3 +:10CF5000A8156102C8CB24A38F52E68598BF48A7C5 +:10CF600003DB8746F3CFF1F33CBAC0AA569329A757 +:10CF7000F55A058C2915A7AA4544D50C5537F7EA6B +:10CF8000E24DF309B0CFF7EC404F508A125DFF6BD2 +:10CF900052AA6626D419FCA68ECA4EC6A8B3B6AD50 +:10CFA0001FF808279DEDFE211B1D2DC5EDAB5DC5AE +:10CFB0008F642E201F603EE91BB7FECD85DDBF408C +:10CFC000ACBA06831969BF53C74E48C072A97A61CB +:10CFD000957EACCF091E4BAB96FECAA4F263DD145E +:10CFE000D4FAAA750F344033730939AB0CEB41EA1C +:10CFF000D7C60D84A6863E23337F662A131DD9E348 +:10D00000727387A0DC975A1D18178D7374F042B2A3 +:10D010008CE0470D96655BF378C10F5708C9D6F5CC +:10D0200017B3A53D7335E815D931EEDA99AF01FD97 +:10D03000539444F58196D519FF73E1F63B337CE3B5 +:10D04000DE2253D6841390B94BA0C7093D2664EF66 +:10D050009056AE7C4B22C848441F7D973CB4ED9956 +:10D0600049BCA0DA8607F6AD5D811BDA956377E7E8 +:10D0700045B15E9BBDB5A5B1550B64DA1A8D21FD96 +:10D080006C97AE33D888D5B709D906B68C4CD0F793 +:10D090006E180E53966091B40AC1847A16F77C59C3 +:10D0A0009869C789F57F57DE5533ED9A77ED18B843 +:10D0B00017EBA5926FDCBD3A9329AB76E10AC9FF65 +:10D0C0005EB4AF91A81D9FBF8928CF03F56C03B252 +:10D0D0006C5EAE068E0B91FF4600E29F373E7B935F +:10D0E000D8890FE5DF4E8DEB1F8915D0CF10F802E0 +:10D0F00007B9509147883D55794EEE9F6FB8DBFFD9 +:10D10000A7B833E8BEB89DA658288868C79610EC23 +:10D1100055F6074D0625673E382189F2C1B6576D91 +:10D120005A01B7BE83C5F4A9C632C54AAF9DF343C1 +:10D13000439508B233EAF2CBCA3381E188572E0611 +:10D140007BCE0394BEF0F987B7A0525F7CFBA3B2FD +:10D15000AFD24C9AB6E1150960832D4389653961D8 +:10D160002194790B0106882BB017E32699601AC524 +:10D1700071CF82258C377834C62A62E833F7AEBB8C +:10D18000A14DE38094B5ABE54529780AAAAE17B75F +:10D1900050E7E2FACAEC548864789D61E2B8D82975 +:10D1A000A05863C278CA4622BBB41CB93CCF74975E +:10D1B0007559BA0D58F75CF6657D28E4A3C275660B +:10D1C000820F7F0A020F00210380C881EA9F6061FD +:10D1D0004CDA4492DCED1D01F6E9C4BB8C0F310141 +:10D1E0008DA78C42BDE4F960119AF00CADC17BC1F2 +:10D1F000E4BB27F2DB3F78265371F81982FF1D65E7 +:10D200003C7E8C1D2B669CCDAB33658D75E42776FB +:10D2100073145A4FD6C15982BFF1BD1934BBEFEC1C +:10D22000FA0521C4FDF75B8173E0E1B25B537F3007 +:10D23000B6D300EEF4E3B73F3B08F0117CF5A175DF +:10D24000443D6656BA6C9E39CB26C3FB6E74990773 +:10D25000F620DC1A7644D8661E0351535E16F37727 +:10D26000417320FCBB6C81308309609BB53017FD96 +:10D270008D924E55AD0056BC9387803702F47337BC +:10D280002EEA2E145508B9C93E7A6E545843D98EE9 +:10D2900036668514D9AE59E478E89CFF7DFC3C7F66 +:10D2A0006D0D292A47CE1697122D658AF7784F778C +:10D2B000F01D28F1F19B50349379A58F51C758A4E4 +:10D2C000C459BF9BC02E13A22E89B95AEC137C609F +:10D2D000E7627C4151879A921885484D84E8D83C92 +:10D2E00094862916FD3EDC38C833EC32D76FB5B3CF +:10D2F00015BC369519BF502C670A8DF4BF281E72D5 +:10D300009A92EF530AF6590167513EAED0EE541C83 +:10D310007190E0ED020763A5F870868328B41ABC0B +:10D320009B936F31F6ED515F579FC788C90029ED78 +:10D33000EDEC6C304506EF0E110EC3AF81C979EEEE +:10D3400018C68B5DE3B69105CAD04E84B797F5A495 +:10D35000C043859FD0A521A1C2C0430578F2D6D590 +:10D36000019671C4B7C31FA7516AF590CFCB36673A +:10D37000690C24E22EBF156A190E48CA393512A568 +:10D38000CE950D72F5BC5C94B1B94D15D2FBEBAAEC +:10D3900072D30B8564701BE5998791C1DAEBBAAB48 +:10D3A0001DB3EDAA6348E9AC5596CF2A1F35DD9A27 +:10D3B000419F0C7AAD9DD2361D8280A513304376F5 +:10D3C000DDA82A97A0BD28A80CC36704DA6758C057 +:10D3D0006AB7F0D68A2398A0E521CF0DACD2174EBC +:10D3E000B1B38E35253D756D4998A8C8882FD24AAE +:10D3F00044B2685495EA33A24188A9C9DBB0ECE98C +:10D400005B065FCEF65332BCB8BD257400C4F61A75 +:10D4100093C9A69C7F12B4815AE69077B4BBF71BE0 +:10D420000EFD752E98F1B2BE62EA6B2FCE2379669F +:10D43000D251044C6DD41B1E33F3A907C43370873B +:10D440007A8DA55DDC355CB222E3E6D58E86107957 +:10D4500047AFB202D267BA43D0631ADEEA47C43894 +:10D46000CC04DFEA7A991749159E7D948B56953541 +:10D47000B79CCD7CA54A5EA4BD719AC90205D6B6FB +:10D48000E6EBE14CF1BC5CB738B5297C53D4EAF04B +:10D4900010DEE791FC4B3BB51E8D8C768650D1F4A7 +:10D4A0002B94A9F4D98955B560E7A469A42DB3E5F7 +:10D4B00011DA6768928EC71668A897084278048DBB +:10D4C00066CAB3022689FBFE4E5862AC36AC04BE77 +:10D4D000B8585221445ABE8D004E047E4A9C80505A +:10D4E0005D38C831CFC6B8B2179661D3DFD25F219D +:10D4F000AF9CE5F3D72513B2FFF9A752A97B7E4174 +:10D50000BA8481D3DA4030E290F04D636DDAF73DB2 +:10D5100024B7E8A2461EE7AF9D2D4760CB245943B0 +:10D52000C14398400515DE337A86E6DCF9598FA8A9 +:10D53000C957E241764557EDB493C7DD4A415FBF15 +:10D5400063F5DA177BD7682C58E4C3DDAEDCE7F26D +:10D55000D79AA00309D66E3BF47045698FF0D29438 +:10D56000E4E863008936E02D9122E104AFC8D46A73 +:10D57000D69E201CF1C7972D743183BCE18F7F6A42 +:10D580002A6340AB7D46BCB1612544CBECD3FBD6CE +:10D59000253C2460DB71EB14F29D4529332600DA2B +:10D5A0003DB86ACA1211985A9E72AAD2D6BB01859A +:10D5B0009768E0A28B118BEA8B039DC8C59F260557 +:10D5C00027BE1AC3C52E7A12566A4EB7AD135C40F9 +:10D5D0008A1F0B0055AF978064C402FE1A3BE9C254 +:10D5E0003DE4619DBD4B7BAD532637327BE95B9FAC +:10D5F000B07E2AF01ABF19D6037D773C081309C004 +:10D60000878047D95D93BE47B2546D526BB470A00A +:10D61000F7EE21077353910B9F4400513D3B833C30 +:10D620001BD186E239FB536D1575D30203F9D389FB +:10D630006CF82551D908CF0A1D858CB8E34A46FC01 +:10D640009B9B1D6425B2BFB2069D89306BABC5E1C3 +:10D650008C340498DE12351939E4FF268BCB05375C +:10D660009CC1D9E94705AAFB6B4D414D00DE80A363 +:10D67000337D4A24DDA685389DB392FA5DE22713F7 +:10D6800096AC2038F1F2C75590BC97A7D5B1687811 +:10D69000D4E90BE91B7481B4E1A596A6A643C2A404 +:10D6A000F8773F0C75F0B53A69DDAFAA82F538EF2F +:10D6B0000B84500C35DE86436093AED126CB107BB5 +:10D6C0000437C34F9F427E4807D5811871EAAB21CA +:10D6D00072112D7145F85032807CE6BD6D55872E54 +:10D6E000EB56AB5E94DC8C12695CEC72FCB647C204 +:10D6F0004F5D2AE54FA2BD339FBA72571FF937110C +:10D70000FEF76B6B6FE62FE4BB406850D1965CB2BE +:10D7100037F72ADA12FCEAD1FC8A90A2FDFFF08FDB +:10D720003E7AFD3B8080608CB506B65EECF87CBA34 +:10D73000B367E08B2D1687C0BD23377FDEF7DB2B69 +:10D74000A00506C689440CA24ECF7BCDA7E2D757D1 +:10D7500036FF0FC78A521415ABF6CA2B8351F65AFF +:10D760004DAD87E67E8837CAE75DBC333125CEEB09 +:10D77000C5462658D16744081F333261A795D31A8E +:10D78000F8B65BCC3EFE77D3F6929DC56F69CBDCD5 +:10D790002A906A20D5E51919119F3F55D39D3CFB6E +:10D7A000070C4C7381840925A72E8C5661A2DFECEF +:10D7B000A7BF8F743953B8E0EF1E9D6B7EF617F745 +:10D7C000D628F1CE423C7C55A52A54D7C05E1EAE69 +:10D7D000931A032692DC62D33263AA4C4E1CD25BAE +:10D7E000CF5E88A29D4877FD161D0C6EDB667F31EB +:10D7F000385AF876D34F3CB454884B4204010D9309 +:10D80000FE520260600F0ACB3A4A702FF2026D0A94 +:10D810004D662AB0E1BE79B136E32611DA15AC1CAB +:10D8200067825BCD915C4B94CA4D545829D3C9692A +:10D830002D8EA1F0385B5D9CC284A65B4148F5F358 +:10D84000A48105D6F742B7A7761F6ED04B75F25963 +:10D85000CB6E21F9407CDCE6C3BD8EDD4786F7E365 +:10D860003A0D72252585CAF4F51EE6AA519776E988 +:10D87000EB57266D544D5C84734EC497F5F378B620 +:10D88000F2D0A9FB595CAE522846B927B6AE7CF857 +:10D89000FA3ED415A9AA2C23ADF1A9704141820604 +:10D8A00074D1FC6AB48FBCFA37542455B7AF030562 +:10D8B000FBA77E0B09387E36EFA62C4E1C0E2138B6 +:10D8C00058625233B82C3A41C352874F5ACA839296 +:10D8D000422F2926C67639B1A9C56E9FC1A15BBC6E +:10D8E000C7B8C0DC278DFAFCEA8BB90B90AFBE023B +:10D8F00086C5D16BEA5B32A8D32C250CFFFFFFFF56 +:10D900003AF32EAFDAD16262B8BF462C3CA0D58282 +:10D91000A08F62DF1FE795AA20CFA8C2F8E1B16C03 +:10D9200055F2A6402968F362A1433727D921D9D1FE +:10D930009EE2058801A97A47D972D54E64CC55F884 +:10D940000F222009B8AC8E22E9E4CFD6021F12CBF9 +:10D9500068F10509B65C91DCA757E243891A9986FC +:10D9600047C9E5DE5EF6944A31B4334B04A26FC07A +:10D9700049D506FD3FD11E88C64E1E48D17D47843D +:10D980009DB4E36CB9EEB495690FE9F71ED15CB3B1 +:10D99000CA5FAD825AFCF18979F845EDC3B2BC0784 +:10D9A00039EB2405FB1CBE87BF5612971FA901F552 +:10D9B000F4FB2504DF1F3186CB892028F93DD82BC5 +:10D9C0000A6588E6A299B821E617E95777C4A3EC5F +:10D9D000CA6A6BD6AA89E720584A2B808BF8DA5D91 +:10D9E000712BE101386A3BD1331FA141ADD5DC2257 +:10D9F0008B1FA14D5CA219C5257F2240E39377625E +:10DA0000DD805BEFCC8039834D2285AF3CC9F218B5 +:10DA1000CC740653EE9032712211A351A44B77CAF5 +:10DA2000DA85D77AE550503FB9D2C6A435C7071773 +:10DA3000F7E2CA90812C82355570081074CB7C11A6 +:10DA4000FA72AA94542C0CAFABC7C352AA582A70CE +:10DA50008C93CE927750B6BFE88FC047E3AB8E1958 +:10DA60009F552284C5296B0DCA463F59B697098A2E +:10DA7000EDC142D80D93EDE3E7733205BFE5F056F3 +:10DA8000F9FAAA133C633E14A5095B18692E6333A7 +:10DA90006E4DD714D712DC57B572D2E6F9CEBB79EA +:10DAA000C96B4379D40961A5BB0C3D39AF56758765 +:10DAB00015988AF1ED9DB87B34C738DA9760FF7707 +:10DAC000664C2C30903F5CE8B25A13ED8C410663F3 +:10DAD000944DAB0DE2E5C4E9F260E9B7C9169EE2E8 +:10DAE000F97B269E113E887C373C1E1C6D13990DD8 +:10DAF0008F9A46989A2E8DB22D9B1C3A3363FAAFBB +:10DB000026A6EDC37441D68042234864BC9FD60A42 +:10DB1000328E4CA21AA613CF06966681EE372EA53A +:10DB20007907CCA1F81895D2E1938C8183456B4994 +:10DB300071D8838CA59312703F924845E272AAA3D4 +:10DB40004CAA84EC5324945D22B7ADA00D219CB760 +:10DB50005015D9188883F5A8180FED39F9786D910B +:10DB6000C12175E394C313E0499C6ACB48F4ECEC03 +:10DB70008A93D3811270365801543AC8280C9748BA +:10DB8000228E9BC815AE3863F159664E696B5A46B2 +:10DB9000EA597FCB428F2EAF5ADA0AC6E23A545A7C +:10DBA0007A8969F55CF263EB336B3447A050BDCAE8 +:10DBB00004E1B28F11585FEB459A26887B79B1A9B1 +:10DBC0002F93AFE0829BB0A1C89BED4CA5A9E31AAF +:10DBD0002BAE1EC11A3C9D54DA09EC4E51108A112D +:10DBE000A7EB2F2E74B01C44415B7F614AF1DFBE6E +:10DBF0002D7F89A31EDB1AE9B58843C24620266F14 +:10DC00005A23CFD3A83F329C8D51E05BB422F5BAA2 +:10DC1000298D079713E63DBA045CC9DC5FF62BB388 +:10DC20009227A21EF3037F23FB1B0FB6CA602A6F45 +:10DC30007546049A2DD6CFF1C03760251582F3DFE3 +:10DC400046C641869B2EB4794C1DE42DAE4B0AEBA3 +:10DC5000F3FD84F0A41B31F9C310E53F29CFC4398B +:10DC6000A5804B909EBC3B20C29D45B35F9D337DFC +:10DC7000573125ADBC5336460D911CB246A1ABF3CE +:10DC800070F90E178E8E3A946CAE1077EF2C71BC33 +:10DC9000103FA21F47E0B0DBFEFD08525221C82F03 +:10DCA0003F2BE4F9B670BA01975BE5098F4150F755 +:10DCB0002BDBF3D9501DA6F00482069FB7A77FC1C6 +:10DCC000ADA8D110DE2092B14E6813FB9BF7847C87 +:10DCD0003EB823DF574D55B7067812BA2BC7CC3064 +:10DCE000A34EEDFE1A88747D580942631F9D057589 +:10DCF000C67E2D75EED1D5CBC4194322001FE9F99C +:10DD00000C04064C3466AF6228DAEC4DB858B903FF +:10DD1000C857640724D1ACD0103C474D48B0D43824 +:10DD200020850D2FAD3C6F60FDBE319406D654CFDB +:10DD30008115874F767BE7FC08B548DDF1572E6DDE +:10DD400041336883D8DCBE29D027667433A38CF9AD +:10DD5000D8416520E05DB2FA338F45B9B8F0D2748E +:10DD60004544FD260107E4647D58C40A32A58C7D34 +:10DD70001CAC83467D371CA19031C729E1527298B3 +:10DD8000238C85753D3DB9D71A2CC709AAD25ED31D +:10DD9000C9E9AA4926D99BD0B6AA41414BB8D44D6E +:10DDA000C34EED0E38A86F6873545B477A33E29E1A +:10DDB000B49D089A627F9F271ABBB4355B7E966735 +:10DDC000820E854EEB32D82CC21AF10E79038F11D8 +:10DDD00071C60854273E7A6D673F9547F241F76058 +:10DDE0006BD707F88B4518D7FBB388B1132A1F2CC4 +:10DDF0002B245202D359146ED0FD4A4FA4F9A4CF5C +:10DE0000C9E2E17263C4341CD4E6615AAC5EFF32ED +:10DE10008C57050AAA34BD732434E082A20552113E +:10DE20004F94801F82969A76D3239DCC9310F192C3 +:10DE300068E72E9525BE303EDDF3F95E42B4D5315C +:10DE40007C3E8E192D03CFB2FC8E63D5DCE0FD3510 +:10DE50008C93E81FC4D0BC74A7D7C2AA1196B2FF96 +:10DE6000BA4523FC1ABB703695A3D25B79C1704CBE +:10DE70009F552A3BADA8243A607562EB5AD55237BC +:10DE800082486C0839CE9995ED8FC9363AAF7E3409 +:10DE90008E5F0D1FB03D45961E786118B6DE807509 +:10DEA000BD1BE812550939E375651DDC6B297193BB +:10DEB000839D08752FEE9B797FC47A56A7C3787629 +:10DEC000868A32113B48BFE796AA161E3AC8494ACD +:10DED00029A6F915AEA1E07F9EBA5B1F96E86BB04C +:10DEE000BCEE0B722B52BB4EFF87EB8E6D2A381E99 +:10DEF000DDB2AD1367DE65357343ED53BDF8FA3F10 +:10DF0000E041AA3D7382959008B04CCA885DD5ED7A +:10DF10000079038DAC3298E0A7F9E4839054A1D244 +:10DF2000E1442DC0614195A8B164E0C40A65751F44 +:10DF3000A9970CE40AB74980118FC3CF0E9B347C9C +:10DF40009FC6DBDE803BC5A9489CEAC94F2194A748 +:10DF5000F709A605C05FB67A8FF6C6F538352F8B60 +:10DF60002942A2802105E0E48E08C0CAB96359A7FE +:10DF700014BB054A5D3568A141896BCA9B3D22618E +:10DF80001D8E81F581AAC4CBA548BBADCDC346AAE1 +:10DF9000156A4D82786D7F2B51584BC545FCFC3678 +:10DFA000E349353A06BF7D050BD44E339B395FE715 +:10DFB000DA3F0FB1546CFBC7E8BF4C3AD35D26E59E +:10DFC00020B5B7E07D95BFEE9EF5BF1AF2AE02AE6A +:10DFD000D7310981EF3CECC8FAFEC65A4E1CD06B13 +:10DFE000840B8AA2CBF398A23BCFC8C2DB6F7F31F0 +:10DFF000B8DF0EBFD3A49914BB39D78D24011DEF10 +:10E00000469227700CEAB7BD46A324B50BE4D5258C +:10E01000649301D36C6FA265A368C42EC74D4A7187 +:10E0200091E166125A45156D0D8447D4E098C27F80 +:10E03000850E5AD17B8887175DCE72DE7DF531FD66 +:10E04000E946A76564A489C9E366E38918C245A2C5 +:10E050009356A643C4EB9BB879B1E9BB6B0996967E +:10E060005D3D0A9B25818CF43DE76B974F18E43B9F +:10E07000AD906C9DFBB54817ED71FCAD06300A7193 +:10E080000A652DA87288F4FBDA356D1B8E51FFF5F9 +:10E090004C9A2EB986FCC0B5FEF81B9BD6DC8E953B +:10E0A00098192D47030B398F57D63FD74C6D5D45D7 +:10E0B000BF1F2CD997ECDBF917B24C847FAE93F1DC +:10E0C000264EA7B0461DBAFC4EB860BEF0901FF8B1 +:10E0D00095FD8EF3D67BC8FF46FEE09C12DA79638D +:10E0E000A789D293A1C8F4FAB33BE6DF95EDFFBE52 +:10E0F00008A57D97431AB9B31F867CD2B5DBFFFF15 +:10E100003AEF3306B88091F3D06258027C00D2997E +:10E11000C84FA60773339C63C4B4C07C8021F0E869 +:10E12000BBFEFB0A4147882F3D86C60E7C47B102E5 +:10E13000C7667C0CA577920347D3811E1955D50D70 +:10E14000EC64E3AB2D3F169AE41FE1E477CD616206 +:10E1500011D2C50F6470911FE700264CA353F2DA69 +:10E160001732E86A864109CD07208A071127E26B3A +:10E1700090D5023F04371E451A0EA24F19338D98D1 +:10E1800038E68AE2128E65562018FDE702C4C2A561 +:10E19000A6930849EA61C224D4BCC8AE1AFB7DE448 +:10E1A000BD6B3357BBBF9CC8B35A6BC97FBF9C6262 +:10E1B0000FB3BA0D4B5FEF69DB7BB59664BFA4D597 +:10E1C000820A7601D22E1E424AFDC8471295CDB86A +:10E1D00084660D21B858433DDEC7363DF27C5D4173 +:10E1E000B86E2B0853A500E3990B286E0272E42C3D +:10E1F000A91B2A4D719A594F3B998C42CA82DDD492 +:10E200001304ADA544C7485C74697F12AC5EDC7D25 +:10E21000E00F22C18C5439709C77454A9ECF207AFA +:10E220003D7E4911E77845B4B91EC05FEA57A17B2E +:10E230006D445F1EEDE82A3E78C76ED51D72D5830A +:10E240006CFDD71B9183EC3E6E99F5B99A9AB07428 +:10E2500064992519E4023539B51B040B857F961B9B +:10E26000F1BE0154D2B68874CA2F1B3D9DD47D37B0 +:10E2700048B354725AF212C8E4047458BFF1F0451E +:10E28000F9E7A5EE46CE4E7A94683848B6E3FA81AF +:10E290002E08ABF3B663BBC09CCEE4DF0177D81584 +:10E2A0004F993C39AF84195FAD3BAC50FCCF0F7C2C +:10E2B000F8FBEBE466FFBF379B79ED357C7DB11E43 +:10E2C0007E4A655B9F4E3C308F26D178D79A985C0A +:10E2D000765CAA5B864CD20EA4FFFCC2FE82B97D9E +:10E2E000878A6C12D64925B5BE0E6E00952A07F8AE +:10E2F00012C2AD730F9E677D7DF9EB2197F076D248 +:10E300009A900588880FB57F4805B9CF88D8A98C21 +:10E310002864FE1AA068D7A190D743CD908F53ED03 +:10E32000636D7B59156519246FC1848052E7E8A09D +:10E3300029978167E116B1A5CFB744F32E552686FC +:10E3400048C43DF0A852F3C86A63676419156C634A +:10E3500050D68292047211E9E80D410542C45FB7BC +:10E36000A1049188834695E6861EC2A8F543E5D0B0 +:10E3700041317A8B2E9055A23FBD2014F80158618F +:10E380001FF10AC83DC4BD2189C8E0358AD5BF70D8 +:10E39000AA142F8F35D81BE55AEFA0C4A2BB5BE5AA +:10E3A0004614AE8E23EFEEAC4B27C488ABBA257271 +:10E3B00066672C828F62BE3B62B92A8AECBB5CDB4B +:10E3C0005ACE877159DC1EA49F7B4F9272AE50418A +:10E3D00052A58C8094F79D54E6B4E6642BEC5FE77D +:10E3E00059A03D806388BA2308B7593126FD5E43A2 +:10E3F000AB19C6CD403D6002967FAA91FE382269D6 +:10E4000099C5FA9A7702B580A42019AE8C59F450B8 +:10E41000123386C56C6B7D4C14B2C40E43467D002E +:10E42000200729279DA0150D0DC3B890D5DA6FFFE1 +:10E43000799EA3BF4105CABB89D168557DF4359D3E +:10E44000AD0087D6CCCF9AB975E6F98421743D59D1 +:10E45000D390868E2C1954BF92A4631B7C315399A0 +:10E46000CD69279B1A4337B6F52967962475F6FCC4 +:10E470004A572EB8E9F3FF8442F724046D75EC8DFA +:10E48000010EAD69A44918D616D4AED8D4A67FD84B +:10E49000D1F42B95E3463BD55EC7F2D496967BB577 +:10E4A0001F75009737C898BC7FAF639B27477EB81E +:10E4B000401F242F58BF1CFB4DBAEBBEB27FF5BAEC +:10E4C0005C219D92C684B3FDF630D49CCECEDFBCD9 +:10E4D000AE9866DF2E23774092FEA2C83E31FFF74A +:10E4E0005F342D93DFE81F019CDFEA601BCB81DEE8 +:10E4F00047D25A90434D9FFEFF20D89FFBDBF9F394 +:10E500000084814AA8B8162C6FE79648DA99706D96 +:10E5100032A8B66DB0245ADE9E4BCC9767B0CE655C +:10E520007E31817D166767471330FE4611E2F4EFB6 +:10E53000B69E7455B3A96638513589D09128539A3F +:10E54000084C80FD995EF7D20D7BC07ED06452648A +:10E55000E79C00C7CDBCC7E850593C65D8745365EB +:10E560006E237D448033442E89E54704D165D2660D +:10E57000891383452EDD76F1C951EB26D975D36712 +:10E580004A092C0EE2889939ADEF8A287A4E5E64EA +:10E5900022A40F050ADB3D451DF84DE95A7F8A612B +:10E5A0009C522948434B99201B3C35CC40A9595AD1 +:10E5B0009C7B7E6E1B9F8251CA4AFF251BFAFD7011 +:10E5C0006A8C85FA8A48956D42FC4457D26C5A6C25 +:10E5D0002A25D200441B28F924C94D61DA7C5B6DE1 +:10E5E00078D78B9E9A429C42331F75C3D36DDA6EE7 +:10E5F000B4DD565571C289E208FD00DEDB7DDB6FBC +:10E600002C80265C96AC365CF884536673DEA67A62 +:10E6100093CB80EE4CD2BE7354A4719CA44B778DE7 +:10E62000CA41BC14AA45B873AF66221296278D3C26 +:10E63000CDCEB619A50B4A5F7FA1E01354F5F51DA9 +:10E640008483F11CC4C432349A43C3A2D4E47274E8 +:10E6500064D02519CCD433359252C283DCF473755F +:10E66000C5068654C5C5B2360CFB0550D5E5F27615 +:10E6700085167D8ACDD5B3371C0761BDDDF5F377EF +:10E6800002ACA55961F6EE32FA8C6E7406EB5C7E34 +:10E69000DB6B5BB2B6729534A52A69535A9CD839A4 +:10E6A0003D7A9EB580093978006E2A0FDA755916C1 +:10E6B0005A989A1D63020CED1E3D685B7399865B48 +:10E6C000A5887A1AC6CC3A3CA66CE78CD6EC7A7C44 +:10E6D0008E873C15CEDC3B3DB910BF92DEFC7B7DC6 +:10E6E000D8920BE1C7CDBA3E373C0053D7EDFA7E46 +:10E6F000CF1E8F5DCFDDBB3F3F2C0952DFFDFB7F7F +:10E7000018FD86A898831A2A52224770D0A2D5F104 +:10E710001055DBDC44322697303BAC525F4C83E92A +:10E72000A16133E7762735E20F8E068271654E8C44 +:10E73000CAD38DC213D05723D5A1C1CB38B5A8AD4C +:10E74000284689C503061CE6CF024A3FF06656E418 +:10E75000A530278852AC076818BB6C87F87657E558 +:10E76000CD6704BC4D12A5D27147FDB2F167D6E664 +:10E77000E994A37C96906A11D1F7C6A7F977D7E7F9 +:10E780007B84E90FEA1A0C65B2ED68688AD15A14E5 +:10E79000F1DDD381463A1BA5AAB85653DABADCF8A4 +:10E7A000A3028AC6C11F9DEA662920A67A6FCEF110 +:10E7B000ABDCA9C9AB9B1CE1031B6C8B7B7D478742 +:10E7C00066CE918859D41FECAD6B6A37F26E5EEC61 +:10E7D00045380981EA5E1FAD7AF80018FA7E5FEDD0 +:10E7E0006B560C770F6B13EF734FC8D0F36FDEEEE1 +:10E7F000B8DF0E7EEB5F9FAFBB3C9BC9FB7FDFEFBB +:10E800009EB2DF6FEC0232FCF4E47DDA7469F4F856 +:10E8100064CB23BD970834E1A3E9C4938432F42286 +:10E820001B2A296449404D44B564C0D43225894E21 +:10E830000D6CC6F36DD5B3F1150FE3DF7DF589B12E +:10E840004CC22098E4C636B4976A8196F4E676F412 +:10E850008F122FD4ECD637B5C60046B5FCF677F547 +:10E86000AD84780BE5C7B6B6DFB6D522F5E7F6F688 +:10E87000C1F785B6EDD7B7B7FD9D6695FDF7F7F7FC +:10E88000E6C9A8270ECE3FF8A12EEDEE1A5A7FB8A2 +:10E89000AA1EA4DDEEBABF8311FA3BDFBE3AFCB379 +:10E8A000E776E4114BABBA74257AEAB65B8BFAF6DD +:10E8B000D41F249FE4FDB3D9A0E54C9913200C2D5F +:10E8C00025EA680CE6CE3EBC9D006FBCF6EE7EFCF1 +:10E8D00000E2D294EEDE3FBD1E3316D0FEFE7FFD79 +:10E8E000A788C4DCE7CFBEBEB729EE9FF7EFFEFED8 +:10E8F000EB26AFDEEFDFBFBFA0FB18B3FFFFC525E0 +:10E90000607DBC8BDCF79C2D9229508F245BF3211A +:10E910000CF283EBE850152C6034A1C037D6FD9C77 +:10E920000AE32C89FA22316348A325E92BDAC0AF28 +:10E93000B8737E66F232309C19C245EEE11153394C +:10E940009F4079855037133FC0E2590D59245ECF5F +:10E9500075223C8589C237886912CCB3DC07160959 +:10E96000D1AB8466E3D37BD5699E40AC5861B9AE28 +:10E97000B0BA304541BD03E1C90E20C7BF39D0EF61 +:10E980003A8A75BD12E47AB36A0CA19B964E383868 +:10E99000729A469C8EE019D2083CA20D76BE52BDFA +:10E9A000ACEB24F783F498514DCBCCCF6C5FF6B52C +:10E9B00033E625068A1991AC25DBED50A3A25B4115 +:10E9C00040B8FF4DFC0D08EA32292A43B28C3F6162 +:10E9D000C06A6BE47003B848CAE7B4405A1EA4E6A4 +:10E9E0001DAB8EA3533B653E8828B55F8BE158066F +:10E9F000355F620074BFBF6DB8872AD0E74C9E2D8B +:10EA00003FDF8375BCDBD7206C106DFFEAA3857FE9 +:10EA1000D896E9528067BD3C244B459C3356DD8C2B +:10EA2000BA6384B63A7394B1B1C3133721DA53335E +:10EA3000A960025376B210CCB2534DAEE537F43331 +:10EA400040220612F63BB03F200D300FACE09BBCDD +:10EA5000F33207CE78AB90313C25B9587C87D0F69D +:10EA6000093B0173D8B6113955931917E7D5D8D991 +:10EA7000D22C1F8C09A748C8170A6CD181715A7B08 +:10EA800038392ED816FF75B96E40A495AE53D4759B +:10EA9000B17AE17A7162C498B15AC5A4E69B8476D2 +:10EAA00002F70B7F787259B9E8A14497072FFFB599 +:10EAB000AF8A8F7FB7664C58679D82540FDF061E62 +:10EAC0004A312E67063A0CC152CCE866D0B8FADB60 +:10EAD000762787101A5E18049A28671C54BBB12544 +:10EAE000D725AA5FD1AF45E39C8B2B3C89B9F2D3E4 +:10EAF0002FA457E3B7FA463021FF0ADC97B57974A3 +:10EB0000407FF87C98F8B8AD9454BBD0974482A16C +:10EB1000486FFD8C90ECB9AC87D061C7D8E3B86A78 +:10EB2000597C288DC142105D8B7C67A7E838B37A89 +:10EB3000D6342485D633E3CFA68C30CCBDD5F1EEC8 +:10EB400032A222255AD761AF0F8F0E9B481D50FB72 +:10EB50005A62B22AF9D4346CC29DD218C0912B1AD1 +:10EB600059B225C63E2E906BE11531D6EF9BD6A447 +:10EB7000C9202404D1B7C1A1D0017CD842CF5737D6 +:10EB8000EC64D18766F0E1CA8655EFCE4909FD17DE +:10EB9000B525AC7615FC39B2423EAD4800C04D24D7 +:10EBA00097742F8C5C713FCFFD196D611F0BEF8E39 +:10EBB0009F790F610F7D62CE1BC84966441BBF83DE +:10EBC000AC6E1C416E4ABF53E2191B7DC53ABF13A0 +:10EBD000527E8D7495DAAC042989C3C0C299231280 +:10EBE00098436B7183BE37A30D6D27763399E8ACDC +:10EBF000DEB9230454AE3CEFEB87B234C0C32844E3 +:10EC00007A60203DDFF56501B4D121558CF9F60914 +:10EC10001468899CFF65B9BC025007DAC49216B12A +:10EC20007307E0A2DB815DCA27CA0F968245580FA1 +:10EC3000D4E9C5933D7F697E43B4442CABE31EB752 +:10EC40001CE5DB9B84260FB97811EA296E84558672 +:10EC500015F5866AB077EABAD7AD9E2903741CD839 +:10EC6000F5302A9B1AE017B00DC7334B358443FBB0 +:10EC70005372CF9A59A814B1ED00635AC50CF1E84C +:10EC8000D9F81A475D0C737582C848738C1E71578A +:10EC9000FE9DC43AAE61CC6A0C8A1176BE5CD1721C +:10ECA000012E283E9F77BC3B4FAF0512138B7ED2BF +:10ECB0007179A9DBCFE201B49FC84E583E5D8AD37B +:10ECC000F622E251BEBE9F43241B85B8E8127EBEE9 +:10ECD000FE5826DD31CFE3E570CBCE22FAC380208B +:10ECE0009CC34B6153AD45FC4F10CA734F7FF8D3A3 +:10ECF00057210392B5DB301941ABC100ACFDF57271 +:10ED00007F3F45427B23B18168D1196BA8D7550558 +:10ED10004A94A82182A8FA6944C15C6AC031B82922 +:10ED2000FBAD864F8FF69D8F4F7D7B99A9D6DDED8C +:10ED30009EEE70D0256698854769EB47E35581CEF6 +:10ED400020A06309FEE5CC892264044222E0293A2E +:10ED500033D40733A881B56720988B43181693E600 +:10ED600056BA636591DB919F9F53A16672C50E45AC +:10ED700029B1EEDAF56A11CDD575C56A51F17A4738 +:10ED8000F9F9AB48557F198E51ACADEA9C1D55C7BA +:10ED900017EB8DA4595CD1DA4699944612CF5C07E3 +:10EDA0003D5D688B50CDDC8ED34B1F4C1F5E99C9E7 +:10EDB00073A9AA4987DA7043AF466AE0A57C139825 +:10EDC0003A6FF703B42EC4537080D24AADE8FF47C0 +:10EDD0001EDA28C429B2A6F1783F6F0F0A637501C5 +:10EDE000D3B5A1F5A3987823DF6FCC6313944DBA04 +:10EDF00073ABCBB07203A86F21F6F8DAE5DC19E04B +:10EE0000007FC173FE643C9D28CEC1AFB2FDFCDB28 +:10EE1000EBEE40154CF2DECCDCD698135CA069DC3E +:10EE2000FEC649DA567791824FC288BAEDA1199A87 +:10EE3000746121059B285AC064C08ADB95575DDE4A +:10EE40008AFE241928BFF064ABE4EF151A1D7A3648 +:10EE50004DF72518DF138EB3E41998172E1CBFB891 +:10EE6000A24947E9FE57B23E95820414E96CF45B6F +:10EE7000E059A51A4CBB7137023F3754A6FD16C89E +:10EE80004E8D43003D3D4E9716B7211A9A4E309055 +:10EE9000876B301FF0DC953426576F14BA95FB72E0 +:10EEA00003FAEDBB54091D1D2B685F3FB30FB0B2D1 +:10EEB00057E808E4F1DC5A30E1D695F481DF998413 +:10EEC000AA252A47CEE9591CF1496C11169BB93D78 +:10EED000CE24225F002784669E01FC89BCFE7A1D39 +:10EEE000C33055E5BF255CA50B6D434E8E6F1F12D9 +:10EEF000973D29F501344F7D8FE6C55905FBDF6449 +:10EF00001C404C48C647FDE83FC32F188E669E3311 +:10EF10002C9026089CADBD46B5D32E59B0252BC9E3 +:10EF200001A0EF4AC74797E265DFEF69B9331C31AB +:10EF300011EC6C4B9E42696B4420D42B1544D84590 +:10EF4000BD0831844B0118784A56B9D6CEC694C450 +:10EF500008B2628804253953C79AD70C2CE4B44808 +:10EF6000A1A7A1C7258D2D59CBD3C219B97E5B4B63 +:10EF700013437CFCD7F341AD217632D529E5DFED93 +:10EF80008E950DC862F82A7C0C7FC36EBE5D594E0B +:10EF9000A089182696DFF67AD0B86E00327E958169 +:10EFA00017C50127A910D5E83E6BC8EFBBEF984EF7 +:10EFB0002268980A1F7D765803DBB489B72C88AF86 +:10EFC0004BA60ECEE8CC517BE88A0A6172297AB74B +:10EFD000A479AE04B9B69D60EA92830AC6FF5902CD +:10EFE000BBAFAA88DB3F96A7EA0BCAA23D862AAC34 +:10EFF0006F3BDC89895A9E0C846FDF08AE972B74B7 +:10F000001ACBAB6620F5353FE3CC127F4BD4160FFD +:10F0100052DBCC59BAD7DE99C795C47043C85B2E72 +:10F020002D930510BD9F5D1AE62741F54ED89CFF34 +:10F030007DF1814893C7DFBB3340EC7E83EB895C75 +:10F0400050322E9BD84F015EBADC60F9949070F973 +:10F05000143AA55EA852D886446D9CD35888D490A3 +:10F060005F41E941B871B09BC261A9F19757FF595F +:10F070006951AED7B461C45DB3514601421512B5B2 +:10F080007A7797DAD8CEF4203C1687D016DD252B78 +:10F09000C51806A6F07C3914B3BD84310ADC82FFA2 +:10F0A0009DA3AA97079CA1DE11F3687EC9A85D25E0 +:10F0B00080790166211BF98BFFD99ED6E7CE5C448F +:10F0C000A6A8F087B9CF38910D91BB41CE7C1CB476 +:10F0D0000E9E2BDFBC9F3990D27FBABF4A85DC3DA4 +:10F0E000C1BD518EA24B1F3ADC03EA0289E80FF141 +:10F0F000570C46C6EB24B992161010B113DBFFFF74 +:10F1000060D59E0D4067C42A70E1824D1856BBC879 +:10F1100068D4150CB0F41A2720AE42E19942AA2314 +:10F12000590588BF4F87D721F6A3CB24C82235FDC8 +:10F1300019738523416730DCA2D36DBEC6FB050B76 +:10F1400046B14B84B81BB141326C41E468AC61629A +:10F150005252C10172A4172A1F030E2B4CF0F2F871 +:10F1600061750FDB7EA710CC0F35CA426BF5D42B2F +:10F1700001497E8ED5A132F83B7DC2D7B908799B73 +:10F180003D8CA1DC366E9AA26A5ACA72357C6B8CB1 +:10F190005381AC0035FE9B63815ACB83E5035CBC95 +:10F1A0004B0D80B751523B4FE3CB4A6029D7C8A7DC +:10F1B0008B18700D337F664E8EDB284D97B9A235C4 +:10F1C00062DA8A06762EE52A6C3DC5CAAA4BA76389 +:10F1D0006ADC84D07E23B86FD07CCB1D1A1A772FBF +:10F1E00045B8C31E5CF66F2112A982E569FDB263C2 +:10F1F000515B490BF75519D6652C44C9E30759965D +:10F20000AFEEF552E4505E3D02C2085D775BFF321F +:10F21000DEEE82744CF23C37244F095C47B5F13185 +:10F2200085FF22987AA211CE4CE1473729A8F1F246 +:10F23000B273D21347B810350BD3D27B46B57C31AD +:10F24000EF9F9FE8EA9B91510DFF8752ECD98D7299 +:10F25000EA8AD6896E64367766126518435F7558F8 +:10F260001ACDA4567A27B43BCACE41331BDB537068 +:10F2700062AE7ABAF5AF31CEB573EA174E77BCF00D +:10F28000598DF565CAF09BB5EE2A2FBB2AA17BF8F4 +:10F29000CE9CDC1FEE48413647BCBC35C1BCF4A453 +:10F2A000A8D71DC6E75980352F574457C8AC783AC0 +:10F2B000431E5C14EF499B36DBE7E745F84376F2E3 +:10F2C000CA8F24C368939959068A5451EE12D67195 +:10F2D000B1A25DC26C6C327F90966D70E6C1847B8A +:10F2E0007999A4AF782FBC33A8CE4B58286FB519A5 +:10F2F0007C9C5397F7A739C6767BA4C2115B5A79D9 +:10F30000EAA267C398841FC67C5EE7DB1D59C9BCAF +:10F31000107201A0D0940EE66DD076E904375461E6 +:10F320005981C3B30EE5385F394546080A695BA0C9 +:10F3300062919E37F316362E811466C5663655A344 +:10F34000284EFB0D173CB5C131224A6F0439F581B7 +:10F35000ECA34E15C428B4C062626665980BBDA7C5 +:10F3600041D1068EDEA5145FFB662F6E4E85E592B9 +:10F37000DA167B0F56B5155E4722255745E6C7E1DD +:10F38000782AAF8EC2C7C4A77ED0ED376D2ED1AA22 +:10F390009E78B212F35EBACCEC65EEAC613FDDA9AB +:10F3A000EB512DD5C3DBA6A787494E000F2EDF6A90 +:10F3B0002BE2897493F794E484D961C6603F5016B8 +:10F3C000394A752C4E34BDC97719074D6DD958810E +:10F3D000D7C5BA5BC8EE16EF855EA665C280F3E0BE +:10F3E000A34F42E2DCAD98A3F72C0406B5ED91E9FA +:10F3F00023725AD2D3251D566D2F308E04FD901ADC +:10F4000090FD8796BC8276BF495D91929434F4F862 +:10F410009B106672D26399BC29426DF0DEB47451C0 +:10F42000EDF1A2BFC557D2BF8DE66618B6D895F6E6 +:10F43000150C2719D37F3799F331AAA58744BCF758 +:10F44000A4C6BC60C99995D1DB00CA296B4970D9A3 +:10F45000E276CE7D4E6632F7DE426E97479456B521 +:10F46000EBC1AA3D5A25B0BB0DEBE0DB66C374ECE3 +:10F470008141E79DD5AD354E4589653DD99DF12A40 +:10F48000F4E8FA9242ECD7130ECA55DE63E98971AB +:10F490009178AFD33E80434DA2386A89B9798070A4 +:10F4A00021F50FFF13ED5771FD824DD3973D7CF28F +:10F4B000971F046EA785B40F071B4C419F2D7DF14C +:10F4C00060B8C5544B919DD9CDB5CDB942AE7AD86F +:10F4D00082486F95575A9603DC4A6A9FCA1CFD17EB +:10F4E000476B4776582D3C54C809E8D3CE9D7C1411 +:10F4F0006CA8E2F18F0A4EFD47816D35189DDEB78D +:10F5000060D5E40DE0CCA5DC705DBCDDF0F1D72268 +:10F5100068D9560CE8D1532C784DB94CF6364123B6 +:10F520007EB38840F9226D2D6906394DA96AD62D22 +:10F5300059739D0576323025E6166045E3B4D20353 +:10F540002095E0460E6A1409E402C0BD10997A6263 +:10F5500064D4A27067B6BFD8E792C1AFA0506091E3 +:10F560007D618419E8C7DDB3FC3E61231F0E73E69D +:10F570002984250AB1277824E38183486387F27EB2 +:10F58000CC2AA989CB76C5278D8B954752C6666E46 +:10F590002A99F08E3EFEF0708507E8B61A1BFA6FC6 +:10F5A0002BE154C537723BA7A7566B4C5DB279610E +:10F5B0008B900B3193211B31AF5B4BB2551B30321B +:10F5C000B96FABF3FCEC9737891535FB096CD8950F +:10F5D0008CDA444AF4FC1D2087F87C4D76D98E0ED7 +:10F5E00083A3600AA3DB991D08BCB113E00FE92EC9 +:10F5F0008B3AAB4DA9D932C79B99340D70B760C017 +:10F6000020C2A2FA8C88D1367469375DCB6AFF8D2F +:10F610005464A32BC5EA713E4CD225579E90777C4B +:10F62000B7E3C1524BB31334D124A3A1F7A505F41A +:10F63000C6F3AF71ED402F3ED7654058BF05F8DCEB +:10F64000C8448B2C68BAF054F8C464192B183D8F49 +:10F6500037F782E402E290593C25875ACDDB5920E6 +:10F660002584A61BCDD0533071A1A6DB6C1DFBCD2C +:10F67000B2ABD57B5DC49133CD73AC928D71D08824 +:10F680004C350A159C8D1B42D02A33E032CE8F1D9B +:10F6900036F8401F9694BB1126B86F14C38186E4D8 +:10F6A0009A0BEFD0E754E1372FC9E218AF52FE377B +:10F6B000C1B708C48FFFD82A683DCE104CFAF7A412 +:10F6C0008236D77E314E75F96E086E588CCC7C51DF +:10F6D000F53A87E05E239AA26606C7501E9AA3C831 +:10F6E000B84BD7B2FFDD1950C36BE31E2D69812DD6 +:10F6F000375BD6E87BBF407D3F2C5F1D8B79802C2C +:10F70000EB6089E21964E3C5C47DE73DC8557FE934 +:10F710008FE6D44C686DAFABA7CFAFBAE1B4B0E71A +:10F72000716186999985936DF141A019354594EDE4 +:10F73000496E398CEF95863E78DFC54E771076A1FD +:10F7400019F1008920202D1B4C1B62C2A478743F44 +:10F7500050ACAB8853C41BAFFE9257C3B8F2B8711C +:10F76000D4C1C90121BE01CA3CBF674C6E9A2E5D4F +:10F7700096D734ABACA634E7362A66CC22A2A8BA18 +:10F780009678AF8E9AF0B0A54DAE6B834A8F7C7998 +:10F790004ACF8C8695B51E699DCE9C442AC1FC76C5 +:10F7A000ED3D2F07C3CADEE8F3487CD137AB2133E8 +:10F7B0004BCE538495735F8B5BEE29C40F5D26A9F6 +:10F7C00002378351DCEE18A1F22D6ACACCCED38E5B +:10F7D0000A8FEF80D61719807F08CD273A898FAF1F +:10F7E0001B6C738105FF9BECBD5C6FC7CDCED05108 +:10F7F000AB39430CEADBE4F1C99963C04332D9E485 +:10F8000090E0DB4DBC97D5B6F4C1845D0B238BF63D +:10F81000E2A8840ED06ADCE8AC361A0008C9D6F734 +:10F82000E5E06F94A98717F0557600DD2A1C01FDED +:10F8300099F15E95F5875C98FD59E57E220C540C94 +:10F840005C3D8A99BB08B9B2CB2B67244B14360BAD +:10F8500014F5DA9A8C1F0AB887D5C6D33C90A4B7A2 +:10F8600005BE6B6AA8BF174015A7E2DBAFCF9ED5D8 +:10F870000DAE6E9A0EF3359FB3C9E12A22D6C403AA +:10F88000EA1ADD97BE07BE90AFCA00DE02CCFE01C9 +:10F89000051E88CA6E795AA22A386A16015C6F342E +:10F8A00093F00F11A7ED9FC8F98D4DD19BF05F9F8D +:10F8B000941F04D60BE942AB074441D6A5E3DEC949 +:10F8C00099ED8F9AE6AC1F7E3B2A78512C11FC16DD +:10F8D000DAA58C9BB03C77391EBB6BD06E8E3A2F6D +:10F8E000F8807391871A07B3173E0AD1121FFAF1F5 +:10F8F000F09C0E60D13D9CDF80DC4ED9FFFFFFFF06 +:10F9000060D5F60D40655A8D92A2638AF7A61F96C0 +:10F910000C2A327572E795AC2022236901545D23CD +:10F920001B00A142D13431A34B206300A9459CCFD9 +:10F93000B3EF91CEDBD1976ED952C94567FB383A08 +:10F940008E76A30DF824352241E4EB51EE85F19B30 +:10F9500070616A0AB0A86EDE20F20CC88754552583 +:10F96000D4C3CD330F37F1066BE38D830A65A1064F +:10F970002998A60A7CB8B77C21F398637F9D5FBA6B +:10F98000FD00ED979C3C94341E2C4E4788287BFA52 +:10F990007343DDDAB4BC7124222A2B01903DFA6F47 +:10F9A000027F7348790565E5E7E9CA08F3F802675D +:10F9B000ACA460D8998D726FDB5AC14DD6E47894AF +:10F9C000BDCA4539C23EE16E6A080ACE2864A7A3C3 +:10F9D0008CDA50B50A3A2D2B157B282D8776B47F0B +:10F9E0007B8E54061BA9F9E62B6B8E488A573BAFDA +:10F9F0007339DB4D05829D0223D9BBCC61CDDF5D20 +:10FA0000BC91A11DE44D513DAF3316116B465232EE +:10FA1000A91484B4B40A3240E6B8861DA4E4317E49 +:10FA2000BAC301096207AB5B4F5ED3B61327BFC4ED +:10FA300065F35E1DED5CD47109C30A50FD7CD07E78 +:10FA40002415C3193B46754EEB7B9D89AC97471A2D +:10FA5000545DA1FF38369FC83E9A96D3E6763CB0F7 +:10FA60005D480E1BFD7930CF361F6DABB7E4F3D682 +:10FA7000F1B3401EB557F4CDD931AB15A577BCE134 +:10FA80003E76A75A3E28E63E766C8D55692E37DDC8 +:10FA90006E4D9F5B86053F74F9782ED21FC358992F +:10FAA000013CABEBCAFC19ECE8DACA36AF6A267245 +:10FAB00033A62BF1D31FA2228C88CB44FF68237678 +:10FAC00004BB1F17FE33149A8D9FEA02EE8C321985 +:10FAD000CC5A64ABB83E97B09EE9F85DBE29DF70A2 +:10FAE000C6BA8115FFB238C7C76BF931EFBDF871DF +:10FAF00077B9EF190FBFD7245FF9EB5987DD7995F7 +:10FB00008C87EF539AB61BE2B82642CF1CA374ED44 +:10FB1000FF60878A81E0055C58D202CE3EB41A5756 +:10FB20001FBE8A2D1976F446C5638C4F3458F4EF06 +:10FB3000E3F107695306B7A759E633488167D1EC6B +:10FB4000584200C98FC45989B09179860E645AA66B +:10FB5000A831E7082688B6A3500CE4A0C2147405A7 +:10FB600016C7A1CD212185A02E40446C8935540CA7 +:10FB70000986638876F434C2C69145EF99A23FEABC +:10FB8000D08EA57D45E68C65B6C868778C42D36E6D +:10FB90004ACFBFCB10EC3C81C5BE369774A5FC6143 +:10FBA00043DE3687D9EF90B80BD560C7336FC0EC12 +:10FBB000939036C96B7C7BC7D74407383BDD7160B7 +:10FBC000F20C7E97D8AC187872086FCDE41FFD61F7 +:10FBD000724AEA0AD2A09D673438EE523A18D7E743 +:10FBE000C43DEF16C7CDD9F4B39266C893BA66E1A7 +:10FBF000E15F081EA03DFFAFCF1934A3F91DB74642 +:10FC000053E0A67A9C19B68A8CC271D6BEAED7B222 +:10FC1000ECF46D9D2F142EE8221244E1DC63A77AE8 +:10FC2000560701A43BE562B8FB3D452D0DEDF510EF +:10FC300015EC249E6DF193458241C473B95577C983 +:10FC40002BC1879D433273F63BBBC7DFC204F41E52 +:10FC5000F3FD446A22E094B3B295C65AA57490F3BA +:10FC60003405D690D9ED57B0F5828DD00285D534C4 +:10FC700015F4C4B7A430B11725F7CE7C33C554F1C1 +:10FC80007F912AD5C64705B5680B64DCECCC5D884E +:10FC900046F8DAF560A95E995E6FBB74E6AF02794B +:10FCA00011490D65444FF8BC32D907F9D7763EF7B4 +:10FCB000EF8AC391D7BBBBA46F5911D87F0D37FD15 +:10FCC0001E3653678F4A5C76B68CFFD438CDDD275D +:10FCD0006EA8D4DFB6F7BD57B089CED6BE1084BFAC +:10FCE00050268EC5BEEB57E7F78A85D839127B853B +:10FCF000B73FA99208CF1CDAFD79A052A0A87D15C4 +:10FD000028F0080F9202FB6438C27346A8CC540C4A +:10FD1000E482090B7B965EA4102DA42FF1DFBA427A +:10FD200061D45A0FBFE7960FAB660242457BFEBE19 +:10FD30008D9564E0B10532627B33C2733A95A69A21 +:10FD40009F45048220C0BBCC0FAE9BB9016CB7CBE2 +:10FD50009754058340D0B249EBB1BF0FD89D3124F1 +:10FD600063C555C1012714A57E3B37DA0488D23D0F +:10FD70006BB901CA093EA8AC99100E067AD10F04DE +:10FD8000928A47BEE2C56D2572FDE0454D172328D6 +:10FD900002090FE67D7EE647F1FF6DE454C1ECC435 +:10FDA0003BCE4A2A9BC41AC00B2CCEE553DA08B1CD +:10FDB000E2DEAD0DE9009A818249CD40CB7AD7C60B +:10FDC000229DE703C67D6C6E32BC3241F5DCBBC3BD +:10FDD000725589E70A3E9DAE3A296A40BCCC58DE8E +:10FDE000832F0D0DFF3367214968E9D6851EB002C8 +:10FDF000F13B7480C7AE176DA05E6AB01B1FB8627E +:10FE0000C4E3591607067F7ED459F73E545D463247 +:10FE100074570517381098D07EB462935C4D478CA8 +:10FE2000CBF70177BD7B1C3FAA33E08F2DBE085175 +:10FE3000C3D300944DE27228DDD34F48E7A50EF8F6 +:10FE4000C4BF2419964CF43CF5820AFD96BBD1112F +:10FE5000123227A8CDA2D896640FE17FE60B75D6A3 +:10FE6000A3450BFE43B359B52D63E9326A078956A2 +:10FE70007FE1A8B861A6DD2CFC936EA10471529FAE +:10FE8000028D2EB7E6FA7AC733DE9F48879D523A35 +:10FE900036F8255B9CDAD27DF77F94DF8A54A5B2D1 +:10FEA000470BE73FE7584637AD56EEE12F77FE8127 +:10FEB000B2EF481DB52DF6941FC72B1B6099187D16 +:10FEC000E6BB899FE45AD3FF1EE4E8166D0ED68187 +:10FED000315C5043742F5D2D9A58CA4DB8D80C9799 +:10FEE0001D4D033E865BB9DED68B1532AFFC9053B9 +:10FEF000EC187755752ED551657BE00B0062C42F49 +:10FF0000EE99A5891FE60CBBABA00B45E4A3AFA2FD +:10FF100010C20988F02795033072054A35B2761E63 +:10FF2000B3819F38C171F58209DC49444F3DD2AF9E +:10FF3000EBEE89C1C9C26BAE99D1E16862E2AABE9B +:10FF40007847AA79DCEB10A9295DA39B0F41F7182C +:10FF50005020A4834C34E8C0F8F63AE9878951462A +:10FF600019C1FB1301F793097015797D31041D6BDD +:10FF7000A7242678D1BF5B5B19B2B24C20F3760F71 +:10FF800040180AA6B04DF7EC4A2EB18AE96F27F95E +:10FF900048082D2B0E7C7DE916D285047ADEA262FC +:10FFA00072F688C899BFD3050B25CAC7068E68E9C3 +:10FFB000A99F74D7F29DF8A0C0332834AABB74243B +:10FFC0000237B2811846E36376884856498CF211AD +:10FFD000127ED3757A99F60EE198A694C28EFE121F +:10FFE0001B6C2F76E5F31E79B6194CE48B7EB4AC0E +:10FFF0004C9BE480B24D5902636E4DE54F1D5D850B +:020000021000EC +:10000000EAA8879600F997B63C9B57747A85D7F68D +:10001000AC17A7ABD4B156F1C3302A54DC639DFCB6 +:10002000EBC105156B3815328F5DF41FF8C6550D01 +:10003000B6F15A95D595F1B50548E3DE1128F6538A +:100040003A202239DA6F05A00C664D252DE6974B34 +:100050003E9621B80E967B78BC9159D3320BF28E26 +:10006000EA47077007B484A4E561EF96351E3B2D7F +:10007000602204D7937FA77AF5F7D433BD1BF77AB4 +:10008000E8C98DF668315F98542EC50FEFB11B0794 +:1000900038EB8EF5827C19623FCC9272122C71F192 +:1000A000C04BE897DFFD3E506EA0090527477E371D +:1000B000BFE92F71AF1DC02E47BF145EFF379A04F2 +:1000C000580ACE1D9867B311B6891477896A05104E +:1000D000166A44DFD0722D7BD212ED1B8616FD32DC +:1000E00022382A3332272E78A4EA070DCD6DB1F2DB +:1000F00053DA54DDA7CA5A103757E9D26FFFFFFF12 +:10010000591F67FF800410201004738190245060F1 +:1001100009E6832988141121C531761B9834516171 +:1001200061D42C0F810590224AE8BB629125D062F0 +:1001300089737E66891591234401B6439935D1634D +:1001400040400204C044122450604244D0645264CF +:1001500048500305C854132558704345D874536557 +:1001600041418206C14592265161C246D165D2669F +:1001700049518307C95593275971C347D975D36727 +:100180003A00D5C7820C1828CD254E68922C5868A5 +:10019000364319F58A1C1929FFDACC8A9A3C596929 +:1001A00002766F48830D982A615B4AA0932DD86A26 +:1001B000F1668F068B1D992B8BBB863D9B3DD96BC2 +:1001C00042480A0CC24C1A2C52684A4CD26C5A6CE7 +:1001D0004A580B0DCA5C1B2D5A784B4DDA7C5B6D6F +:1001E00043498A0EC34D9A2E5369CA4ED36DDA6EB7 +:1001F0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F3F +:10020000CA1E43EF8484303084679DE694A47070E6 +:100210003E72A3FB8C9431318C34C49C9CB47171BC +:100220007DF322F88585B032AE3BE17295A5F07280 +:10023000397323F98D95B1338D761CE59DB5F17336 +:1002400044C02214C4C4323454E06254D4E47274FE +:100250004CD02315CCD433355CF06355DCF4737586 +:1002600045C1A216C5C5B23655E1E256D5E5F276CE +:100270004DD1A317CDD5B3375DF1E357DDF5F37756 +:10028000306AAAF2868C3838AD32697896AC7878C4 +:100290006D7A3BD48E9C39398EB869599EBC797978 +:1002A000606B2AF0878DB83A872D4D9797ADF87A15 +:1002B0007D66E1968F9DB93B1FB9E95B9FBDF97BD8 +:1002C00046C82A1CC6CC3A3C56E86A5CD6EC7A7C16 +:1002D0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7D9E +:1002E00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7EE6 +:1002F0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7F6E +:1003000080B20DC2A00614A008424E4DB02654E0A3 +:1003100087E4F8C3A81615A1AB0FF68CB83655E1E3 +:100320001979B724A10794A24F4F3B49B127D4E2D2 +:100330001115E7CBA91795A321378D9AB937D5E3C6 +:1003400060420684E04616A4706246C4F06656E435 +:1003500068520785E85617A5787247C5F87657E5BD +:1003600061438686E14796A67163C6C6F167D6E605 +:1003700069538787E95797A77973C7C7F977D7E78D +:10038000E268FD93A20E1CA8B59510A7B22E5CE8FA +:1003900095EC2904AA1E1DA981A04C49BA3E5DE92D +:1003A000C5546B9AA30F9CAAA3EC317CB32FDCEA53 +:1003B00072996A8DAB1F9DABFB5D288ABB3FDDEB5D +:1003C000624A0E8CE24E1EAC726A4ECCF26E5EEC4D +:1003D0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FEDD5 +:1003E000634B8E8EE34F9EAE736BCECEF36FDEEE1D +:1003F0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEFA5 +:100400004457DA9FA48634B034A264D0B4A674F002 +:100410009355E771AC9635B13CB265D1BCB675F178 +:10042000B507DB32A587B4B235A3E4D2B5A7F4F2A1 +:100430002583C691AD97B5B33DB3E5D3BDB7F5F30D +:1004400064C22694E4C636B474E266D4F4E676F464 +:100450006CD22795ECD637B57CF267D5FCF677F5EC +:1004600065C3A696E5C7B6B675E3E6D6F5E7F6F634 +:100470006DD3A797EDD7B7B77DF3E7D7FDF7F7F7BC +:10048000C175D1F4A68E3CB836AA6CD8B6AE7CF84D +:100490009118D0A6AE9E3DB93EBA6DD9BEBE7DF9CB +:1004A000458EAF7AA78FBCBA37ABECDAB7AFFCFAA0 +:1004B000CB648960AF9FBDBB3FBBEDDBBFBFFDFB26 +:1004C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFC7C +:1004D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFD04 +:1004E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE4C +:1004F0006FDBAF9FEFDFBFBF7FFBEFDFFFFFFFFFD4 +:100500000000000080041020102040409024506023 +:1005100008100101881411211830414198345161AB +:1005200001018002810590221121C0429125D062F3 +:1005300009118103891591231931C1439935D1637B +:1005400040400204C044122450604244D0645264CB +:1005500048500305C854132558704345D874536553 +:1005600041418206C14592265161C246D165D2669B +:1005700049518307C95593275971C347D975D36723 +:1005800002080808820C182812284848922C58683B +:100590000A1809098A1C19291A3849499A3C5969C3 +:1005A0000309880A830D982A1329C84A932DD86A0B +:1005B0000B19890B8B1D992B1B39C94B9B3DD96B93 +:1005C00042480A0CC24C1A2C52684A4CD26C5A6CE3 +:1005D0004A580B0DCA5C1B2D5A784B4DDA7C5B6D6B +:1005E00043498A0EC34D9A2E5369CA4ED36DDA6EB3 +:1005F0004B598B0FCB5D9B2F5B79CB4FDB7DDB6F3B +:10060000048020108484303014A0605094A4707052 +:100610000C9021118C9431311CB061519CB47171DA +:100620000581A0128585B03215A1E05295A5F07222 +:100630000D91A1138D95B1331DB1E1539DB5F173AA +:1006400044C02214C4C4323454E06254D4E47274FA +:100650004CD02315CCD433355CF06355DCF4737582 +:1006600045C1A216C5C5B23655E1E256D5E5F276CA +:100670004DD1A317CDD5B3375DF1E357DDF5F37752 +:1006800006882818868C383816A8685896AC78786A +:100690000E9829198E9C39391EB869599EBC7979F2 +:1006A0000789A81A878DB83A17A9E85A97ADF87A3A +:1006B0000F99A91B8F9DB93B1FB9E95B9FBDF97BC2 +:1006C00046C82A1CC6CC3A3C56E86A5CD6EC7A7C12 +:1006D0004ED82B1DCEDC3B3D5EF86B5DDEFC7B7D9A +:1006E00047C9AA1EC7CDBA3E57E9EA5ED7EDFA7EE2 +:1006F0004FD9AB1FCFDDBB3F5FF9EB5FDFFDFB7F6A +:1007000020020480A00614A0302244C0B02654E089 +:1007100028120581A81615A1383245C1B83655E111 +:1007200021038482A10794A23123C4C2B127D4E259 +:1007300029138583A91795A33933C5C3B937D5E3E1 +:1007400060420684E04616A4706246C4F06656E431 +:1007500068520785E85617A5787247C5F87657E5B9 +:1007600061438686E14796A67163C6C6F167D6E601 +:1007700069538787E95797A77973C7C7F977D7E789 +:10078000220A0C88A20E1CA8322A4CC8B22E5CE8A1 +:100790002A1A0D89AA1E1DA93A3A4DC9BA3E5DE929 +:1007A000230B8C8AA30F9CAA332BCCCAB32FDCEA71 +:1007B0002B1B8D8BAB1F9DAB3B3BCDCBBB3FDDEBF9 +:1007C000624A0E8CE24E1EAC726A4ECCF26E5EEC49 +:1007D0006A5A0F8DEA5E1FAD7A7A4FCDFA7E5FEDD1 +:1007E000634B8E8EE34F9EAE736BCECEF36FDEEE19 +:1007F0006B5B8F8FEB5F9FAF7B7BCFCFFB7FDFEFA1 +:1008000024822490A48634B034A264D0B4A674F0B8 +:100810002C922591AC9635B13CB265D1BCB675F140 +:100820002583A492A587B4B235A3E4D2B5A7F4F288 +:100830002D93A593AD97B5B33DB3E5D3BDB7F5F310 +:1008400064C22694E4C636B474E266D4F4E676F460 +:100850006CD22795ECD637B57CF267D5FCF677F5E8 +:1008600065C3A696E5C7B6B675E3E6D6F5E7F6F630 +:100870006DD3A797EDD7B7B77DF3E7D7FDF7F7F7B8 +:10088000268A2C98A68E3CB836AA6CD8B6AE7CF8D0 +:100890002E9A2D99AE9E3DB93EBA6DD9BEBE7DF958 +:1008A000278BAC9AA78FBCBA37ABECDAB7AFFCFAA0 +:1008B0002F9BAD9BAF9FBDBB3FBBEDDBBFBFFDFB28 +:1008C00066CA2E9CE6CE3EBC76EA6EDCF6EE7EFC78 +:1008D0006EDA2F9DEEDE3FBD7EFA6FDDFEFE7FFD00 +:1008E00067CBAE9EE7CFBEBE77EBEEDEF7EFFEFE48 +:1008F0006FDBAF9FEFDFBFBF7FFBEFDFFFFFDFFDF2 +:10090000A83F8540E9FB6EDF71CEBBBB30A0E94A52 +:1009100070922DC1D2A5171CC0D47E57A0B0E89804 +:100920006124CC8F7E8129DB29DD7000B947696E97 +:10093000719578FC84979339C03120FC35C5A72187 +:10094000E0C4BB2EFDD693401AE40A5AEDF3D3005F +:1009500070D4BAFC8416B218981B4A079436F25821 +:1009600069233B0AE943941BAE9E3D49F963D45B7E +:10097000E5A1D845E137951A64E34223F117D55A2A +:10098000622CC885421DF485CDC43F7DAF605EC832 +:1009900032482906C2989B68A7504FA4F25E5F5464 +:1009A0007B8BA06E8E4A5A3BD3CDEF0811EF795561 +:1009B0006BD94380C17F66A0C8BD784B50FF5D6591 +:1009C0007F040CACCEC852EC7A6E4C71DEE812ACEF +:1009D000223A0D30F2D8A2F7721A4D70E2F8E2B75F +:1009E000C18B2B31AB2F21201F2B6B73BB0F616091 +:1009F000809B0F01A35B184BC43EA82EB37B580B02 +:100A00006492309D0AC5909D4ED4C35B3420C95A70 +:100A100074B7C01EC48CB3533C5B4557A430C88820 +:100A20007DA6C3C088C272F19541EC52BDC7497E14 +:100A3000B961A31CC711F92D8D79E7F33145B231A6 +:100A4000BB23A055F953B3503D1F9DABE973F31081 +:100A5000EC549A3F809692089C9BA15990B6D2483C +:100A60000C832E1AEDC3B40BD2655B7EFDE3F44B11 +:100A700065B31A1BE5B7B50AF9B36715F597F54ADB +:100A8000B2782017797397C77F5797A7ABE07ED8C6 +:100A90006E8A3694220E07334447CA5FF6DE7F44DF +:100AA000B3792A15A7BD5102E82BCCD0156F594553 +:100AB00077BE0A598C1FB7B15F69EFFB547F7D7514 +:100AC0007E4C93E5CA4872FC6B29EB51DA6832BC64 +:100AD00073942DBDF65882E763B96DFDE678C2A721 +:100AE000EB39B75CAFAF01306AAB4B1CBF8F4170C5 +:100AF000CD1B0A20A7DB385BDD3B4A60B7FB781BC8 +:100B000091E086E13682A181F04C0BC614A2ED790A +:100B10004832AB0CC1EC9D7139D0439C27454C8DBC +:100B2000E4F34E8D810319C11323654A1DD7A2CA70 +:100B30005191A961C93386AF01B105C3DB72D6D02B +:100B4000C4C6BF1DFC24FF9CB0095386D0DABFDCAD +:100B5000551E8587BDD4192F05B0E687ABF4596FB4 +:100B6000CDB39BC40DD5CEAE777745CB1DF5DAEE70 +:100B70002032262A2946045844AF44833966441853 +:100B80001ADAFB87064C98EA0A7ACCC7D2AB1FAABE +:100B9000BCF80B72975CBCEB183A2EDD7DC1DFA868 +:100BA000432E92019ECE1DA7F355ABCCB5E5231580 +:100BB000EF9F6C499662102043B9CE6DF27D51E7EC +:100BC0006F0DCC141D53E1EE1A6D67C17591A1AE86 +:100BD0000ADF4CCFAEDAA6F5BB3A6DCBBEFAE6B56E +:100BE0006B4F06ACDE3213254D224148CE125365C1 +:100BF0006D9170708BDF8CEDBFABC96F9BFFCCAD7F +:100C00001B3FA69A6497A74F5DA264D01022CD69BE +:100C10002D925A13E8E52CDDFCA3F6D16FC56C9D2F +:100C200043E146C75A78CAB63521E6C81957F1F6E6 +:100C3000ED6B0D97CF2AB6803DB3E5D2DFFFF6000E +:100C40000CA020A9F8A4DF8C1C8060E934F79AF08E +:100C5000C8569E0CB954393FD893C6783CE7E40A8D +:100C6000AE0122980955A6BEBE2162D8E665F87C81 +:100C7000C123BAD52DC62448703425F57A0808B5A5 +:100C80005A08ECD8C60B7FFAA4AE6533D62B3FBA10 +:100C90005618ED995179BFF8297A7CDF4141FFB8A8 +:100CA0001D69AAA7A145434509E2615CB1650395A9 +:100CB00057BC0EE0E6DD31B7FB6BEB7BF6FD71F761 +:100CC0005B86AC9E9E31C1FE7E4AECBECB93F37731 +:100CD000631DED6FAA5A86E58105CC229E7E6CBF0E +:100CE0002DAA0F33DAB233353D6FA6C0B36B47A6DA +:100CF000676F2DFD8F5FACFDBF90E69DF9C87DBE8F +:100D00004A62FF8BE08417AB5ADEE34614C6D20278 +:100D100028148C620766B22760B24F239214F267E0 +:100D20008585352352E71220518CA3235547939E86 +:100D300060EB62F9C949F20121E1364C5DF8B2433A +:100D400040400204B8C6108F5060C006581A30E008 +:100D50004E9A03057C26B040587043457887DFE8FB +:100D600021C59344F9159A2953E58A58AF241A2EC0 +:100D700049510145B1D7911C39F5D305A106D225BA +:100D80007AF50048FA8E1AB072A862C3EAAE560924 +:100D9000C19A2DD0CA9DBA2FBE5A0A965E183A093A +:100DA000582A8EA1D9283B2C17CB4A28C9387B6CEE +:100DB00051182A0DCBCD9F8B63BBC768E3BFD74AC1 +:100DC0000BCC4212FA1C122354A24A4C6BD9AB63CF +:100DD0002AD9BB4F7E2EB82B1AFC0353E282F76050 +:100DE00043498A0E77BD92215369480CECE96F8D17 +:100DF0004D938B0F8BBCDB205B79CB4F248C782FF2 +:100E000094718198FCA3933684BEC312EC83138F34 +:100E100056F2628E7776B33398D22031C6B5D2308F +:100E200025632253C57411B8ACB86230ED27F29235 +:100E30000790021554E7125665D3A2AF42BF861140 +:100E400024456156C83737762C626C3549DB77A16B +:100E5000B32FA1774CA6909A24726D748CD93773F6 +:100E6000430B5DE9FB9F30B22D63EC17D96107F9A5 +:100E700069B3E0EA1A25E7962573ED0DFFF152F705 +:100E8000C6322EB8FE0E3A031C28CB5E565D168382 +:100E90000E1A2BF9EE1C1EB4663A6792FE3C27F23E +:100EA0006E89A81ABF5D4F3587698B7A0B29872118 +:100EB000357B2B19F7BA1A3D27691454075FFF4693 +:100EC0003E4A2417114883F70CE9C95AAEFD04D1F4 +:100ED0008A2D8A975BC33A739A5DCAD596F8D2C5B4 +:100EE0001DC80918BDAD8D729388495800AA386F86 +:100EF000B43B297D59CEBA87DB1B693D4FBA06C981 +:100F0000B07AE58FC906185F0AC0C6A2EA33F7E6D1 +:100F1000AEF003BC680786A140B04BA23ED4F46992 +:100F20004127DB095E8596B89141873F7526756A32 +:100F3000809187732DE86AA501E338CCE1D557A2EB +:100F4000604284A654B656AB10E60486CEDBB66586 +:100F500068520785A85074D07872C58780C6E7A705 +:100F600010C7CE98553535A077A9C6C6C994524B3F +:100F700009D7B6C5917076A838F78FD9C4CD502659 +:100F80001ADAFB87E2CFBD2252AF6943FDDE54E798 +:100F90006065AE84E2EE15A67CD8CFABB03FFEEF25 +:100FA000438E8A871CED1EA837C94EA8D3AFD0E761 +:100FB000211E2E8DCB9FFA26A7496ECDFB69BE0B55 +:100FC00064800E8C82CE02A1726A4ECCCC2A3E6C1A +:100FD00033DE47932E5E7CCD70DAECCBF68D46493E +:100FE000634B0CCCE94E3DA813EEEEC38D233F4D71 +:100FF0006B5B8F8F937B7E00BFB6ACAF2C32D97208 +:10100000A5E0670FE46797B6548248DDC0247653A5 +:101010006C37841B7378332A7645C693A6D27378CF +:101020002F820794E591F4BD3FAB47DFEFA657B0A1 +:1010300082712791991595ABE2CF67D1F9334CAF07 +:10104000BEA067B424A9CFFAA41226DB0998A4ABEA +:1010500036D384932CB4AA4E368DC4D37AB19683FA +:101060001D41826277D4B78E15638DDB3589BCFC58 +:10107000A926061FE9534EA23D1A465D008561A8C8 +:10108000640E6486FC8F9FFA7AC82F07D62A4CBA62 +:10109000141E94FE311C33B8066A90D6BEBEFFBB48 +:1010A000278BAC9A3BCDBAD34F29EEAAB165FCFA97 +:1010B0004F1B8396974F0E33076B1AD4EE3BB5E563 +:1010C000E628ACDD26A07ABAC908ECDE368034F416 +:1010D0000E5E2FDF960ADF681E7A625057A0CA2183 +:1010E000A83BA291C5CB1F15D11BE2D1F5A1BFFA38 +:1010F0006911AF9F97EF9E100779ED97509022BE30 +:101100003AF349AFFE48F1833668C40237228404BB +:101110000194E89D5F5917BCB8230C25E632B0C294 +:101120008BF2CDAD0FF68986A878085AAF23B0E8C8 +:1011300069038D8E142A80F6D95A52EE3DC65DEEB3 +:101140003E46E3876870CE1C57E2665EEA9BAF08B6 +:10115000670AF699714D916458704343820E2FCA05 +:10116000E5655BFB01270F6491705146B724D157A9 +:10117000D9D38D0680D1DB39C9A122487907B1CFF7 +:101180007A2FABA70C88E598981808B7EA0BFB29CB +:10119000DD9CB0C2A80CB8A9C7707E499C0BDB28A7 +:1011A000D4F9EEABD320DC2C29988195F3AD9B28A4 +:1011B00071F98D2AF30CE78621C2CF00D21930A332 +:1011C0007A98D703C24C1A2C92128198AC6BFBB35D +:1011D00071288B12B2D8EA839EA84DEDDCF8EEFCA4 +:1011E000D30E77B8A369D9A35B76C3487FFFBA64EF +:1011F000F0290B19681D4707328634B0FB70B8F22E +:101200005603CBB814F64F10D4CB581220DBD33191 +:10121000B5C9E9D918D3FB09FF34D80F9AC9F373BC +:1012200023D524507E7E43B92814E66FBCCE6132AC +:10123000AD82E877F07FB5937DA3F15E1CD7B28DC8 +:10124000F0E4A0904C5A318476F1C3D45E17FE7955 +:101250007497FD48C6DC9033624D83D494E57528BD +:10126000C4A31573A5D7BA3B2D1041162EA230F793 +:10127000DD222FBAEFC112B7840267FACEF7EFFC76 +:10128000C6E3BBBC19EE8B5DED8FC934EE2E7A3808 +:10129000AABF851477BB9846927871172A9B901144 +:1012A0008D8F60B2BF66143771F91DFCCDAC5B3B0E +:1012B00074BE08A4B6B90A468A3B297BE79A10F3A4 +:1012C0004A2A86B1BEBF449D2E58D21E96D191386F +:1012D0007082A999352CAE7F6045E6DBE317901943 +:1012E000CF2B8E5CFF325B5D6A53A2ADED5DBF3CE0 +:1012F00049AB0864F2BBF3CC4EB93F1EE140588FB6 +:10130000674438C27741D621E8513A40A236BFA49B +:101310000E561CC338E71CA194A025CB1C45544A8B +:101320001C2A0143E9039C004F632DCA8B969D4DF7 +:10133000115C83BE0E531042ECC3A362C133D123B0 +:10134000F005CCBC80C355E68FE6B76A6795D269D5 +:10135000D31817C417A91138744C46878585DB4804 +:101360009AB38E9AE78D6959B10D8233A336D0DBDB +:10137000CAEEE44487D32267C7A8324D2E958BE38B +:10138000F488CCE8844A45EA3AAEF503B7DECFEEFE +:101390001824AE08AE9AE4BC07A4ACC6FA8AFEA82C +:1013A0001BFA2F521E74B85141D4D488F39A7FECA3 +:1013B00043E8C856085A41238FD94D4AC53828E416 +:1013C000F1B98A01550FEAA4AD9048919E1CA11174 +:1013D00012490AC9534AEE271A6847C0EF8E5D1CAE +:1013E0003159AAEB233845ECFBF1CD7E5FFCDFE4FD +:1013F0004D1A03EA34A199F271736CC985793E6C78 +:101400001A3F4C9D6B79816A0CF260DFCC82085FD9 +:10141000763223AC954EC6F08BE69179C2B184FE4C +:10142000DAF18A4D5EECEF0D33E3640515574C217C +:10143000951165136D86593EFDCD6AD009CC56B223 +:101440002C2CDD6FDA7BBB32B491B7D2D42552AFEE +:10145000B436C63AB5E0D21AA1BAD06ADE7250BE2E +:10146000BC3F1ED4F7876AF757F707D9F51E092D39 +:10147000BA23F336E13FD7FAA2BD90E26D7396BE70 +:101480001E7B8F52798FCB07A3BEEE5C024CD0F748 +:1014900007693C44942EFD169697E8182E4DF1F4FA +:1014A00015B50F1BDCAB57FEB3C9ACD5034D50F5DA +:1014B0007D0146730BFD42FA01F38D5BC1029DA6CF +:1014C000B14E9757988E01ADB60E4951369E7407AE +:1014D000FCC536DF52335F46684769E0AECB195032 +:1014E0001DABF1D038D3B8C309568D1DF36B8DDB1E +:1014F0005794A9C23D5B02D2A509CE05F0B83DECD8 +:10150000C06B7DAD44EEEE34C8C4883834D7DCB54A +:1015100063FBB243B034B01E7A184259256F226182 +:101520000EC1CA83FF87D2421A52912E461AD1DECB +:101530000F6C0341E9359F2E432DA9DB59311D9EC8 +:101540004EBD687FFE1472AE30720EB9D064526424 +:1015500037D4244E44D0AAB2608CF307D8745365B4 +:10156000C4AD828BBF437385299850BDD165D266C7 +:101570002900E98C594B8AD3E2474172D975D36768 +:10158000508CB191C8F1BBA5D2432FC7842AA7B50F +:10159000CAC889E1EA0E494CBD614F349263339A5F +:1015A000C362490C78F6EB5F0B854FABC52A05CBC0 +:1015B00019533214B32C38D424C4C109341004385C +:1015C00012AAA68C4BC8A3280B16E929D26C5A6C18 +:1015D000327F68F5782F0EAC81534D90DA7C5B6DCD +:1015E0003B6EE9F49C999CF3EC8BB515D36DDA6EE8 +:1015F000337EE86581AE1FA2E9FB7F0DDB7DDB6FEB +:101600007D0468E936F25BC38122A070D026729314 +:1016100031E8272C9EF28E6A16B1C255DC00D23317 +:10162000650040508576B1292D0184F2CFB1537405 +:101630002713A79A8DA5B9CC99E1A15CA666257957 +:10164000D40720E1C4C43234F5E7C3A5D4E47274EE +:10165000EF46FFF3CCD433355FF2CE39DCF473754B +:1016600041862318C5C5B236AA939489D5E5F2768A +:10167000772269BCCDD5B337676E1CDADDF5F37719 +:10168000260990A03F29CF8410F0E87F316DF7D56F +:101690004A2A2F244E98F5E426E86556D6CCF966FA +:1016A000C7E2691C3AD6CB3A872BEA0A183EF3D731 +:1016B000141D10972318525FABDBA87BA1E1987F24 +:1016C00024CCC1D9C6CC3A3CB5164E88D6EC7A7C2F +:1016D0004F2BCB51CEDC3B3DFEE6E7F0DEFC7B7DC5 +:1016E00039FEC1BBC7CDBA3E5AF6FFAAD7EDFA7E86 +:1016F0002EC37BABCFDDBB3FFFC9BA1DDFFDFB7F38 +:10170000E0137986A600DFE40F088C98D0344BEF05 +:101710003396BC0D08743B7E066A43FC1F6FB44EC3 +:10172000E13382BF219618009130DDA6055877A3DA +:101730004997C487962A6A7E8C4D66A632C4884C27 +:101740001865468BB60F1099CB80EA39F06656E4DF +:10175000DCA2038A6C3437A8DF2AA63AF87657E56C +:101760005BC73F8992631424094712BEF167D6E62E +:10177000DDA3C78894AA9FE5828936ABF977D7E7BE +:10178000F27955E6F1F067AC8DC8CE4CFADD57AA78 +:10179000B55A4324A6F659EB027D9354D420081D74 +:1017A000418A8AB7F80F9A7732493FAF8E8CDA7741 +:1017B000242B78B4ADD2B9B0D8FBC785344C84E2C1 +:1017C000B91B711DB96D3C5315AA5C6CF26E5EECD1 +:1017D000BB25EC0DD20E1DA2F79A4B6DFA7E5FED84 +:1017E0003C1E88359CCD9CCE78189F9BF36FDEEE17 +:1017F0000B0AA0807B5F9FAFF6EB248BFB7FDFEFB4 +:10180000440647D21B03DFF44C2066B0D5E6245DC6 +:10181000AC6A8D9253E45F42E3B6634A82EABFFB4F +:1018200023B4DBB29BC7D4920DF3ECDD3A34FF0D49 +:10183000BF83EDEB56ADCB060931C5B146B5E99F87 +:101840004333BA86E4C636B449E81D0CF4E676F4B0 +:1018500013EDD940ECD637B5F5C2367AFCF677F5FC +:101860008D498440E5C7B6B6B59D027BF5E7F6F62F +:101870009EE85D02EDD7B7B7DD818DEFFDF7F7F795 +:10188000068FCD37AE0A385C0EFAECD7886FB600FB +:101890002EE8D66C111B55FDC144312E3540A921CF +:1018A000AA66AFC11CC8B265F7D4885748DCFF5C94 +:1018B000A6A5B4D9D19948183FBAB90C18E2D920D5 +:1018C0001508ADDAE6CE3EBCB6819C9DF6EE7EFCF8 +:1018D00031CE7346EEDE3FBDBE91EF66FEFE7FFD6C +:1018E000D0EF4F61E7CFBEBED4AE3256F7EFFEFE6B +:1018F0004D5F5A5AEFDFBFBFB57F1A1AFFFFEC8169 +:1019000060254C8D2C8BA5A92DA465926F5A7EBFA6 +:1019100070B019E2A89E358E33D247CFE313F0DEC4 +:101920007983ACC2A1EF65AB71816FC9F174C36FEC +:101930006935BE832D6B32465DB5CECE0EC655FEE3 +:1019400094B90EDBD218F960E402BD894012981DEB +:10195000F3D2589FDE367B28C8378106D82B77C450 +:101960001A418646FBF578672A6927F92EED37E09C +:1019700071AF2F0ADB317863E20143C1E14515C83D +:101980007A8A2CB93DEEFD891A24CA5241DFD4650A +:1019900030FA8B482A6E7B431A38494920C249A441 +:1019A0007B8BACFBBB3DDA85EFAD80546A0A7915C1 +:1019B00098FB0B2A1BE4DD2DDB65CF098D5F26B676 +:1019C0003C4EDE68F8FCF06D724CF7ED721E384646 +:1019D000345EEA8E5DAF9FB0FA0A29F4219EF7C00B +:1019E0007B6DEA12FBB736236B59EFE1439E56C37A +:1019F00087AA074E18AE176ECBFB8C07249FFF7487 +:101A0000C4E1555227835080A0C21CFFCA466ADD3C +:101A1000CC02E1532867BD70B8D29634E2B2987E0A +:101A20007641DF92FB835191B5DB96FD1A9790BE0C +:101A3000F805DE33D377AB9E259516AECF8AD568F1 +:101A400067B6D504BFB2D96766D02EFBB42D24A9E2 +:101A5000E8F410D05CA70E2E12D4E1DFBC3D4BA8F9 +:101A6000FF3226C2C4B35945F59241D5ADC20F79B4 +:101A7000F72E9096EFE14CBA8F8F4032A5D20E78B8 +:101A8000C61AE8E309BE582400CA9785F6CE87B582 +:101A9000CEC2D6C2DCA3D25D57DA9A3C3A98921DE8 +:101AA000470D6A9EF98B5135C3576AF2ECA51DEEBE +:101AB0004264E2591F725858274295F4245F5586B4 +:101AC000FEF5D5918778E77DE90ABEB7B635047192 +:101AD00076FCB759EE36CAB4127F9E525A9C657B8B +:101AE000933757BF6B524FB72901CE58FD68F4F4B6 +:101AF000EEDE077AEF579F90EB86488B12755AA05F +:101B0000D56045C03FCCB57FFC5047A020D67811AA +:101B10001042018EA89211458FB63C4A48C5D9A003 +:101B20005981ACD515656B39F110998CCF21356190 +:101B30001143C58CF61F91E3E617C345E380BDE072 +:101B40009FB3A5B69E41E3AB488A8E0B4710A5F420 +:101B500042A183285567B6244943356AA6B3611E5E +:101B60005F1E6607553835E7AEE3E24D4B9CE9F55D +:101B700011E37BC6DBA4132AD901A560E98B0DA56F +:101B8000422EFA05197874A5102EF6D5CC28BD6B17 +:101B900052E7BC5290AE1AE8819FBACFC439FC36E6 +:101BA0005B89A83DB1F977EE8C1A6D35C5DC50AB79 +:101BB000AF9FE68911E18D6635F36C540F5D22AA63 +:101BC000CE392D2AB0373AC90C6D6ADEAE00DC067C +:101BD000C6297A2B9521C570D97D6B669AB233E000 +:101BE000FC5B65CDDBB532A3C995DE03160DFD8721 +:101BF000744BAB94887B67EB036F263700587E10DD +:101C00001BAC53AA5DF9081F94D8127FCC82917146 +:101C1000921078D908ED96F0045D5E55EE739E95AE +:101C2000FA56A22F05F9821D91C153B7CB54707F8C +:101C300015330C83BBF5D5368382442C2D465633A1 +:101C40005C3C8A9944B4401B2A1101954084892C3C +:101C5000C8B0D4F058B4EA7A6ED28C913F88D49050 +:101C60009ACC22C241E317498A8C8EDBED6774CC93 +:101C700055F75298ECA850F647439E96421575CDFD +:101C8000F9FD2AE3D888DD3B73DD420788F39C79B0 +:101C9000EE4851DBD5B99CF8050686BDC60E36B8B0 +:101CA000280F5DE8AC7C30B70896079EAB5C785790 +:101CB0000234AB4754E0D5B6074541D6A9DD02F65C +:101CC000D2B58D9ABF4CDB6389889DB9E390DD99CD +:101CD000DAB8D0063EFAF75E1984BD9CA6DFF2FBA7 +:101CE000F8050F41E6B9410B4F106123480D17A7C6 +:101CF0006FFF0E404FCCD9DB699987D2378C5E5984 +:101D00005582078DF1E6BCFCC660000CBC79D25A46 +:101D1000C8921AD3B044512E268183498030D89975 +:101D20003992B208F987B0CCC762CB2EC447B14212 +:101D300033F32D88E9352FA827810343F9957E6E6B +:101D400038C22284BE75386628E25D8E9E0D5480AE +:101D50008FB2814426A797A896FFE2C27D95AE6E0A +:101D60007BA32E8DE53633A76992A040BEA59624AD +:101D70006BA18B089B9078435D79413D48F7C4D8AF +:101D800083EA8A3286EE9F7D5A2CC1628876792852 +:101D90005014AA45F29E35C82E262FBD5CCC1D6678 +:101DA000167B2B6FE328F0A7FB91CEF1BF705A6B27 +:101DB000BC9B9258F3BDEB8BCDBBD27864B99090AD +:101DC000226C9681FAAC082A190A6B0CEA1C52673D +:101DD00048BAA7020A9A1D809E1A6AEDE20C536661 +:101DE0003BCBAECA8CC33B252DD9488404EF990D5B +:101DF0002B7835029B2D9F26027E2E440D82DD38E6 +:101E00003B0BCB335C0614C744182812EC26509EBB +:101E1000553FC4B07F76B370B49EE8A9A205117394 +:101E20003E0B4B11BF673273CEE9604DADF5F27DCD +:101E300035A1F7BCFA77B7987D78DB5E62C79BF077 +:101E40001B722463E4A611B4E34164EF8E74D17273 +:101E5000763225BE9491B11222558AECE245FE837A +:101E6000184382F471A7D316F66566559F405389CF +:101E70003417F55BDCB7908445E40ACE95E171CD6B +:101E8000A6FA4A224D0E187A0CAC49086DD34BD8ED +:101E9000BAFAD275B64C863604E24A195A76C2F8B6 +:101EA000798E0985BF5D5735770947573CEAF6A615 +:101EB000693C42B8B74D42342BBFEFD01D4618A83D +:101EC000158ED61AA600C13114991F57F61C7E73C1 +:101ED000FABAD078AE19F4309329CAA2C6F839728A +:101EE00057FB0B81DDC9999DD7788058B739F473BA +:101EF0007727071297E01732615D66A94F025AE013 +:101F000018E8A88D60FA05A408C27CC6D007EAEDDF +:101F10009C70BA87F217B6A72898AC422C1EB4EE74 +:101F20005C2425DDD885B803218C67C4BB2677E403 +:101F30003921241C3D2236EF41142C600DC7D1EC11 +:101F40002ABCA5C66025C52F7510C47E1021AB62C2 +:101F5000DFE374E5D2B03305BC90A66AF05AAF86D1 +:101F6000B9A972057276BCB95181440CF21914E614 +:101F7000363981C7BD146F0A2D00EDAB4ED3D11C8D +:101F80009668F7ED138C38234AA86C26D20A986A13 +:101F90008695E6EA77A366C95A1AF342DA1A9D696A +:101FA0001BF520879BDF61A50B7B8CC5CB083DE52E +:101FB000909566C891E09B203FD94A9EC3BDF99F8A +:101FC0000739607DB4FC16FC2B6D88C6F411D16A0C +:101FD000C56A077149DA9BAEDE7549C9B57C3CCD4F +:101FE000CC38E85DD9B09815AA18E48CF72F84E8AE +:101FF000395B78CD95FA1D95D527EEB683FD988D82 +:102000001F11023F9C56C3BF24D0DB6BCFD48BB2D1 +:10201000FA1BDC10F7934EACE430415A48D45653C7 +:102020007745589316374811B55CE2596DFD76F146 +:10203000D76C54106D932F1E05E3E7DCDD929DFCF9 +:102040009B403DC7BCEBDF173C638FB740848DB628 +:10205000DBF6FB96FE547C854256AFB69EE2537883 +:10206000A5D24AD80955B2BCD97CE5A6AA297B2BB2 +:102070000D126D9AD5291BBA05C16A7122F6004866 +:10208000D974CD0770B3E115568AD255D68B10F7A7 +:10209000FEB1078CAAC15FB99544845AC63C515819 +:1020A00058A482CF7533613B4FD8865BD78BC07AFB +:1020B0007FDCAB3B541BC63C6D446FDAC73DD11A85 +:1020C0009939449F861F62FE24AA5C718DA4C7E0E3 +:1020D00037DDD2528E0F12B06E894D54468814F2FD +:1020E000A7CF07004114BF4E279BE6D777FE83E5B5 +:1020F0005559E8BD14F81EB9FF1B9F54F9CDDBFFFD +:10210000607D310D40C785DB8F49E19FD552308717 +:102110001C0D430AE86920AAD2D2B4CB8235729250 +:102120001355A342018152A65B2042885126726F4B +:102130008930CF8276F7B56199B39AE523B155A17D +:102140005450E78C0897B32FB2A027F14BC82D4409 +:10215000CAB8C3C8C0AC309E8FF4FFAC47C19B6EF9 +:1021600061B7A04442B9B1DD825EC393119C06C23F +:102170004371641CF97AE278FE8E17988C66AAD4B3 +:10218000F7BA0A08A7AC1E156AACDDEFAAD3DAD2FB +:102190006A125FA84058B82FDA385DB2C29D6AED66 +:1021A0000B0DA0FB6A0F9A2C0B38EB2A044F9A9365 +:1021B00033FC81D840583AD09BBD0BCF210DAD7474 +:1021C000603E430F02BC8CF775939AD3F41064C140 +:1021D00013DA0D49941B15B2F80EA0A21E83B28E1D +:1021E000B9E9FA3E9FB01B830D86C655865CE802AE +:1021F000473BCA1FF5A99590EB874D8ECDC9560D6B +:10220000088083515077529FCBB566D75406ECFBBC +:10221000CC2ACA305A67039EE6B487DB4C72596AEF +:10222000ED3141EDD376D69D73D3D3DE9494D6DDD4 +:102230000C15530FD8668798DDBAC311BFA1D9EA30 +:1022400048A26304FC03F0280A0F22FFA623B0E78C +:10225000E83025AEAC10B0386EC062FAFC3477516D +:102260003DD08454CDE953392DE50B856E9572F040 +:102270009CAE409736F212C8FD8240D480868D7E97 +:102280001280AA395688D33B2DEEEA8256B2F07EF0 +:1022900076BF8891F03D0A3F7CAAE9C8DD3E36D47E +:1022A000F6EBEBE7DE9EDF7A9BCB1718D8F4597379 +:1022B0000B7B2B5A55D9A9F4C09BEFDDA7DDBF7D61 +:1022C000B920A85EA608B5310E6CE6FAC59F0BFED4 +:1022D0008EDB6AE026BE4DE2DECA9F52393C5FD0FB +:1022E000630EC25D5032387469848151289E841017 +:1022F00037FD906B94DDC07F49B90057086D04CA63 +:10230000343F2C71E082D624EF8242460846644076 +:102310002CD60D0A6353B45E6233E63A9C97BE85B1 +:1023200025538C3A616594A413A18BB4E1CF14A01A +:102330002DE68DD8698555E2BBB72765E021D387A7 +:1023400018E204B739A3296120564A6F6721584B18 +:102350006924F89EB0ABB7A37FD2F47AAB31591A97 +:102360003844635921EDA57D8C73ADB92214AC4777 +:1023700009257497219136382791C36AC7DABFB40B +:1023800026BC0414C2DA19A56B782BE828C69CAACF +:102390003E270514759E1B2F3A5A05C2E3345B8D08 +:1023A00027D18407C3D391A513AECABD97AB378E8F +:1023B0002FF46C8D893B7C04BFBFCD9B21BB51E0CA +:1023C000D8B98A18562CE5F7A1582EC90929501DED +:1023D000D5B82D1C9BB619E8289A49A9CDC2A0AF43 +:1023E000C7352DEB3FA22FEC0D6D27C15FEA351DE0 +:1023F0006AD389CBA7DD98211DDBABAFA404D9EB51 +:102400003972289F0CA716F216A6C5D07AC1D57FBF +:10241000D3166C6ABF7EF57E3850E543DC63A2B309 +:10242000E5FE4F1F25A65FFE557A6259ADBA73636C +:102430004DB79918CD5350BEE2B2E35599E895E3F4 +:10244000DAF3876B24C2C3B2CF53187B27620D49DE +:102450000C833C9858A994389C0E4C2E5CFD74D784 +:1024600020B488492D0543B9A2F290D235E514B4C1 +:10247000FA20A69159351BB87D0BCC6CC34AB7081E +:102480002268AC875966FC75142EA93676AD3D05D9 +:102490002EBE52B914AED3FB1CB835229EB61AF923 +:1024A000CF8B88D60B10BFA0E8AFEA5CCF47703166 +:1024B000EF096D9D8B3D1CB23B3F2F5FEF16B1FACC +:1024C00068028F4F76BCC1FE6E0645A7C1527847A1 +:1024D000D42959303CCD1CAE34FA84773EF8E7F568 +:1024E00019769D7AB8D176475F989F75C86B7E79CB +:1024F000BC9C9C8BC9A6CD1BBF8712D9E38C89F6E7 +:1025000013733D826566EF9F899244705D77F11F7A +:10251000EFD025AC9FEFF04200356341559EF00DA2 +:10252000FE72F66CE1C8062F71F87C4FE324C86494 +:10253000DA817AF6F26EF0030DCDDEB8FB31D0729F +:10254000C01EA6E9FAA690CEC012A9376715D05EC4 +:1025500031AF81FCA881BE28258335EAB8BD7968F2 +:10256000851F8C182427B3C42FD929F50107AE691C +:1025700022D507DED7EDB0D68E82FD418B75706116 +:10258000D58C73B589EC2533F2C54613CB22BD0437 +:10259000AA130A2B35AE1179456F3E33A444391680 +:1025A000C30B6A48737BB9E3135B3308F13CD9FA78 +:1025B00035A5C9B4EBD04B26C4BFF6CB644B569DB2 +:1025C0001D5D0C4CA231BC2118CDEBB39F55FB9384 +:1025D000F1DA76D355FFBA8E527CE225E2E3D95781 +:1025E000E5508C4ED5F039286DC447B87FEFC12D2A +:1025F000F0BB27F218BFBF82018AA33C8F1F196F5F +:1026000043026722E449EA3D16BF4A54405AF2D8D1 +:10261000CC93D2BCAC900E3118AC9CD8A44BDD7CD2 +:102620003D03E700DD958F1290BC1E52DC217CF04B +:10263000DEA00092D2944D109AEDC27EFDC8628F4A +:10264000DBA6D71B1187EE322A596410A0C45C6444 +:1026500003D2821C5956746F87F098CEA4D3D0341D +:10266000F1BE01100B4A133D040A1EE5EF67E915A0 +:1026700099BE80140DD66EB65D75E7B36A84714D50 +:10268000B77BAC954662AFC52C53945BEE8B8577D8 +:10269000501CA5938C1E268F1A87431B01728C76C3 +:1026A00055D1AE3EDF985119D75346E157AEA27CC3 +:1026B00047114088F71FA6AD641E08E42BC25A7D5F +:1026C00086CB701A8648B2B4F554B6AF848E0673C2 +:1026D000D521635F85543D191C8B1DDB8CFCD87B99 +:1026E000D807AC5A782F38F4BB9A94D8B724D4734F +:1026F0006BF029E6A3EDA97D5F39F7F292C15A800C +:1027000097BF023BF8162B80E9223F3FF822DD08F5 +:10271000E8149D8992EDE9A2F500263EDA3A54715B +:102720001E8704058103ABA2F1DA09C4E828318EC3 +:102730007D91C23169F9025E4117243C875AB52C5C +:1027400018C07BDAB3B7B5B4B061AFC9F8FED4DE58 +:102750009775A6E7D2E7B47AF811394E98BF3BE8EF +:1027600059656BE4D3778E590FDB25CDA005F52491 +:10277000092E267BB0D572F8EA42B5D8E1F7A8A7B2 +:102780001A884B1AFA1BF5ABC9DA38394D58D31EE3 +:10279000FD9E8510D29C02FF049AAF36E72CB0480C +:1027A000E3087F27A18D833C4A4DED7AFB2B550230 +:1027B000EB1CCE8393AD95FB3924EFCF83C0C706C6 +:1027C0001A6DF383E3388AC8CA8A4AE132DC94E896 +:1027D000CAAE74ED4EE2F4C92564C2609AB775E2E0 +:1027E00003361DCC74BC1A03A454F08CF629B463D0 +:1027F000AB58B789D5E23C0F23E8B24F4F9DD9D8EB +:102800003C12CD239C7917C08302626FFB1BD50F4E +:102810006E6D4CC2CC5BD51C5C7FF35A38D62D4A0A +:102820003D034D0B11E59552A6DCC5129F22FA78A7 +:10283000359B583AFD7591B539519EF3BB337D01F7 +:102840008FBC85F1C096CBBB237022DE8BA1F4CE6A +:1028500005B0D0F0135E319174FA6191B153D67323 +:10286000DA21246F8513E9BB73882416A7852CF021 +:10287000553BA34B01E797F5CB03EFD8FDB7AB0A68 +:10288000F3EA20636B159DB3810B6A67D6D3EB2502 +:10289000BE672DD8CE53DD145E77F352DEC3EAF463 +:1028A00027AFD3BAA2F09D7AA4D4CD1ACF8801F570 +:1028B000713B5236FB7D99BD3B596FA144985CE05A +:1028C000D6BD2040C29EC3B3566AE371EEF6015CEA +:1028D0000EA78A40FE6F0946AD686FD77E7A85AC39 +:1028E000A3011D61774B5860A079E873375D34050B +:1028F00017FC5290EB5B5D19797F6B3A174EDBFF4B +:102900003AEBEB0386B13360925B6120824EBB24CD +:1029100068C9300C30E2226C2FDFF6243C46DF9E83 +:10292000A9207B9D95CB713941008300AB957ACD71 +:10293000F66B0CF533EA1CA521761FBC599A5E781C +:102940000A32A14677E4149F6B82EEF9869738C469 +:102950000439A047F6F59C836542238515BCF2CA6D +:10296000727D63006256EB052990615681243760C1 +:10297000A844746B5295A59227772A4889F79C1131 +:102980000A0C00D6874C1C09ABB64E9D675A3367BC +:10299000B939FE6C8C2E79E45550E8C8E43AB8EAAF +:1029A000C337C5486A72F3254169B24C111FB8E4B8 +:1029B00033E60BB1F51B78A864C63827EFCE55E691 +:1029C000A5080E245D73306E0035A128EADE527C26 +:1029D00072A79AD06DF9E7D425888DBCC278B06E05 +:1029E0006FCB8DBC9C364E6D6B936643B3A08163F9 +:1029F00062510B4F749A5124257FA8D8370EBDC958 +:102A00003CADD543D627DB54EBCEB61254B04E3294 +:102A10002C5065174C854C2A7C69505C5CCD126A41 +:102A2000A9F12094BF020B2DA611E1C2E21D7791FE +:102A3000C7C10093FE11F9E70F4F9058EE31B984EA +:102A4000C0A20219C2606E308C26381540D52F36D0 +:102A500034D89A903B562CDF04F44A60BC249F780B +:102A600038B319BD2BD49832352CAD5BF1D75389CF +:102A70005FC14853F52A5AB4E993C0174215AD35E2 +:102A80007E0A73013941C7E5970840B896AC78785B +:102A90008E99B65BF1E62A81B69931C98AB05D7F1D +:102AA0003F19D9114E7341002D42035907455DBAB4 +:102AB0003876AFCE04C098901BB11052D3655884BD +:102AC000782A48E42A533BFC4AC3481E76437C7864 +:102AD000FABAD0B0D651C6BCFA8E00521EFFEC3FF7 +:102AE00039CE0B81A7143A33D788524579697E7F56 +:102AF000C42808070C225A5CDFCB2350FB86FD7BE1 +:102B0000BF60B3E5D4F5982DD7E22C5D54D7F7809C +:102B1000CD7C64853276595CECCCB8601845F662A1 +:102B200019EC0B7F45F8A7D523273B4F83176E4D34 +:102B3000506DE487B312B4E301CC30A0CAC4596E1F +:102B4000CCC7951BA863940CA391CA59A0153C62ED +:102B5000089B1BC7D067390A7DD927B33852643622 +:102B60002B426D5EAB2521C309443FC9F127D2A892 +:102B70000CF981B14939FDE419B2FECA43848A6C6B +:102B8000434A448EB6DDFD53C9A8177156C13FC8EC +:102B9000EA2440CB6A09F228FA0447965ED55B899D +:102BA000ED850C48A7F167350BC560C757C1BFAAB3 +:102BB000983A7AEE15EC19268F59403D6A117ED469 +:102BC000BB395B859C49BFC0708847BC8B5F0343A2 +:102BD000AAD16ECFECEE57CEA75A78ED8479FEE4F9 +:102BE000E1C995FE81529DEEA8D1B148531DBC6448 +:102BF00078970D0DD5FABCEF4180C9847B7C536476 +:102C0000B5C26A96FDC45390B5206F76A4C470D83F +:102C1000D76DD4FD9165B13CDBF22DD7B0F1B49303 +:102C20006AEB051365905B330D5C1DBC1907AEB2F2 +:102C3000CA53A30EFF345ED771201CDC7967F9F20A +:102C4000562D929B1F01DF37221100595A1970D05F +:102C50005EFFD8389526B7A3D01AEB133CF5267E35 +:102C6000583205D602B9D7B20B430FD5DD637EA823 +:102C7000157F506AE5DB350D75F7CE33F915F1D3C5 +:102C8000348E2A2D9C09CB33A6D85FD48EAA757FAB +:102C9000668FB40407753B7945529F9BB4BFDEBB7A +:102CA000DC0F58CBA3082967CD541B65D72FF0F74D +:102CB000025D859F7A1B715439A560997FFD7FBAAB +:102CC00070A8D141C6ACDC9C484A68B8FD8C1FDCBA +:102CD000F929AB16D06E577EF51A6BF40B7AFF11FB +:102CE000B335CD186309B8FFD26F6E32AF72F8BA40 +:102CF0001C6744FB916B5E1CDB89045C3FF9DFBD04 +:102D000024F1FB42BA83EBAB11D48101CA16F366FE +:102D10006A30F487884FB244CB52BE47E01332EAA0 +:102D2000DACB0FFF8582128AB69D4288DE4CB31A39 +:102D30000951C541B6F711E3D388609CE112B2FB9B +:102D400032D38575E826EF28AF1A94FF2B43F39B07 +:102D50003377A2BA352A3D7AF40339E31706F0989F +:102D60002198BB0BF9C1167E53E54626C370D402E9 +:102D70002988B20AA1376C298C8A2AD4CB7DD50345 +:102D800026506BF7057379788D48044EEA0B3BF8B3 +:102D900032EA28E0C00138A91EDABCE0A0BE163F26 +:102DA0007B8D0092DB1671F9072E69C2EB8DE4333F +:102DB00055FB8DA6EBC99024C8D9CD6EE3BF9EE329 +:102DC000542AB581FAB2FB9334C4B9201D1EF92DE3 +:102DD000D73AFC688584BAB21264A23E763ED8998E +:102DE00097A708B443A9BD286CF63B983FED264E43 +:102DF00073A68D047F3F6080498620FC7B6357CBA0 +:102E0000577A26344EC591CF2E10C2FF2B20F27078 +:102E1000F5B7807D46D090CE12B567E6C25675F400 +:102E20002D722C1F4568E934B1D36E54F570667F5E +:102E30006AFF731B4D78E8715E81E5FC6237B6FB73 +:102E4000A33FD3C29DF2D7CB6C1FCE59146A61DF6A +:102E50001BAA55BAB205D256E8D7BE5A8C6A88E981 +:102E6000BEBADEB99CF517C7F0E77632707D7560A3 +:102E70001E96C213B305303AE98E401564AF4EF684 +:102E80009360D8D5D68CBAF2B6DA0A5FAE6BA6D507 +:102E9000B428D2863A7E1D3F6148613FC4BEEB71C3 +:102EA00015745308D0FECE3569AE093CEFDD786568 +:102EB000E3E673C6C2B518327FE8A9E7DE5547B628 +:102EC00024CA29AE39484FC1F204CBA3561FB4F12E +:102ED0008EDCDE7335FB9ABCFFFFB652A06F10FB91 +:102EE0001CC9D19EA714E933E38B761A841E3CF3E8 +:102EF000716075C2C92E3FB2EB86481EDD0E2DD023 +:102F0000AF3064DE9EBA57AFF950BB3DC8A40FD9AD +:102F10007AC203856252B6562A32AE854711F47ED4 +:102F20005F056D8D5A67D4A46FC1884789D978EF42 +:102F300087EC0805280217820383676C0D552E86DF +:102F40009F66DA27405C9AA94ECE243B54F09EA09F +:102F5000A85530885C34A0C022C52F66DBE88F13EB +:102F600042F75E65FB46B5DF0FDB469617E340F29E +:102F700017EB2B8AD1B8687BB970654C39F9FBA582 +:102F80000274CEC8066C5D889658C2618AC0F0E5AE +:102F9000159E85227747625664D8014C82CF1EE980 +:102FA0006B868AAEDBF23FE8E0CBD7374EAD87F3D6 +:102FB000399B76066BF2C4AD293A268FC5EEDB321B +:102FC0001CF36D6B5B10E3A08D8848A813A63598A1 +:102FD000523A60CF9458FE3ECE0935C21985344B23 +:102FE000F4CF0689DB34FE0EAA18BCC171A94CEDE2 +:102FF000CB9774E32B5CF410DE7D5BABA28E05FFF8 +:1030000047C204D224C51CB64C859D92C6A2727DCF +:1030100082A2866E18F4B70B42B48452DC7F01FCA6 +:1030200001F8A2966FCF154D423B8452D5663EFD06 +:1030300096235A4C32C816D64D40695E4235EE9002 +:103040007EC0953924C4F34BB4E47EBA1317ACE4C4 +:10305000646EC63AC4B431F11C2B34B05BC19C50D1 +:1030600036B326805E85174B17E2E7278B7D223328 +:103070003E20DD93643842D4450C0C93A3C5F3B5D0 +:10308000E689ADDA196C0F39D22825988C4CD00519 +:1030900015042C79D61C66003849E95486DE19B728 +:1030A000037A236C1F0DE7A3F710BE5BCF2DF75CEF +:1030B000768CCA9BF5C71EDE6D1906BFE942F1BBCF +:1030C0006A0DC72F1F0C9F43D5EDCF5E178615885D +:1030D00008762E5E915A18F600FC8E9F1D05FCF3B3 +:1030E0000166470D8FAD49330F948E7E77296CFDB5 +:1030F000AFDDB8698F06ECB25FAD10021FC0DBFF19 +:1031000060D09C0DDCF7948D29A4F600CA4613FF0D +:10311000A972EAC2F9C3EE8ED834DB2F2705F09EE0 +:103120007FB00288F9B56260A2803C011EC7F4BD81 +:1031300069C41F0E29E41D23A6BE341522902665FE +:10314000FFA64ABE63FEECF1E6442982C6C4ADB9CF +:1031500004D6A2FAE0F2CBB2628389EE174571CAB7 +:103160007F98A60039AE55030D900C46839425ED4B +:103170002990BA0AFD4FE0273B75E7937907B11D07 +:103180001A19E90E420DB7335AB8E40A5BA0F937B1 +:103190005CF80D2935EA2A04AD884F093A522FC64A +:1031A00049412BA718EBAB47E22D3C29274FA4C57B +:1031B000FB6AEF0031F578E47EFE343D3F5F2E0E72 +:1031C000D2B9CC6743661AC0B07784E7AC6BFBD347 +:1031D0002C5D608BA0D61BA8DA5C20E8DA8F69181A +:1031E0001DDE3BA59237B479356DA1C8ED15B18DC3 +:1031F0004FA85D6406A07788DF882B6F46F975A815 +:103200001A0269193B723627A1226219DEA6877657 +:10321000F378DDDCBEA4FA9E2652E35343E8D28C59 +:103220003D7F0C1F297413F24FA44337055451F806 +:10323000769944AC2DE612B09CD3A2AE3191737155 +:103240006331BE74337F7811991BEC4960868DEF32 +:103250007AD54890F8FE33D9DD0D8FF24319E1D1CC +:10326000AD4B86BDED636AA155133D568B1C632D96 +:103270004997310C9CD5A76073140340895C3B349B +:10328000DB294372F27FB4B56E2CDA348CCE8F1DFD +:103290006E5C98146D5C29220C21821DE59BD888F8 +:1032A000D30DCFD563734556494BE4DFAF52547706 +:1032B00074BE08A4146D4674215B8BCC60C78FA4C8 +:1032C000E4BE4188AC663AE96FD68A830768B4FAEF +:1032D00061B7F281CEB8AEC24FF87FA0218F511EE8 +:1032E000473A725FF5A92F298443EA49E949927365 +:1032F000F6837BDA2E664449A212E2C8247FB245E7 +:10330000A003A286F96550B28BAC450088D9D95D7F +:103310004A5806E10C1613817FD4431028B45ED8B6 +:10332000EC2D25EE1BF41009112325D956D8253490 +:10333000110326985527009CA3DB9F6E81B5D251BF +:103340003EDDE22FCEA3F6B3D8E86269F6C6D61802 +:103350006C76EC33F93C17B20E906319FD0164A54D +:103360000646ED10D87976B103816A6BAC583B39CB +:1033700037C9832CE9578330422D1A7A5230D93B12 +:10338000656CE78BFB6DF9C462CC68C94D4CABF43E +:103390004AD7B984509659EB5AAA41C482C11EC972 +:1033A000390FAFC1454FA427B62FE4A30C65CCABB2 +:1033B000C78995831E50AEA62B597687919AF388BC +:1033C000D0AB6569D911E63BDD74AA3836A4E54D6A +:1033D000585E8A9BFF81B7B1FA8BAF8D2E8D75EB4E +:1033E00063B866250AD065FCC54FA56BCB9CF83346 +:1033F00015414716EBE84B38EBF1CF4AF5B77E3075 +:103400009326D0B364253BF1F408AB7B2456E551F9 +:10341000788D0397A8C41BD29CA1C6B5EE679E9574 +:10342000E57A33469D7875384DA7047DFA54707F50 +:10343000E5FD040C7947356CFDB68C868548D102D4 +:1034400043F54D31A139A89E4FD1AB28CCDB89F291 +:10345000C458EFA6210A96B4950434230706E6540F +:10346000453246161A48F9B0426C8B41FB2F57255E +:103470004EC09123D5D33FA702F3F3D72D0C945C14 +:1034800092E8D76DC6AA57B54E416A1849CC0AFED4 +:103490007154F9FA11CC3333FE10E072015C5972A9 +:1034A00075B582D8ED72E9B5E20BF2A3E60B5F9F2A +:1034B000882B2FD12B603FFA47BE0D5A278EA6E4EA +:1034C000F63BF4CCDC3D1C11F76656DCA04F8DA713 +:1034D000D784F2E0A6F248BD31257D42A75C9A5B15 +:1034E0005D387C42B78874C7F634468168026C92B6 +:1034F000C0C54B6BB42EDCA387B1EF382F0CC9EDE0 +:10350000BA932AAFF800F0A1B442B325E864572279 +:10351000989212EEF0EAEC80F1F7BCC7A6945745FA +:1035200054854E8485FA718129DAC6F93580D3DA5B +:1035300031F18527B1EA6440194F03035DC65D6E22 +:103540001A44A102C4C387F9D252228AB0A91469CD +:10355000B3B281671DBCDAE50AD345D2A6D4D18FB8 +:10356000015C238C68AE94E62F672B492E37919629 +:103570006D33C0FAE9E2723CD1990688E317F0573F +:1035800033E076C5797F4FD95A2D6AB96D0BF96E44 +:10359000026E3A9D59EF9525E5C141092E43FAC4C3 +:1035A0005A066F11FD0B719016C154875DF20565C7 +:1035B000F19D01462F5F1D2682D9FA3FCBB95128D4 +:1035C0003ACA49D76EBA3E810C8A0EB18254466A15 +:1035D000357FAAD21E2E71C6FA0BE8CEDC03189DE9 +:1035E0007BB326039A7DD881615905E11DE27B6595 +:1035F000FF3B7409B5F916292FFD3907A5DD59855B +:103600005A6264959C9511145FC2A132CE5718532B +:10361000327243BBDC1636FC245D80FE821452D12C +:1036200017884B56AAA1519DD171EC5155A6197F0F +:103630007396008CB56A583005C2C03F2A14F5C88D +:1036400024454D19A411AD39AE9251F8AF080F0FB2 +:103650008824829D2B145950A3B750B9FAAC603717 +:103660004FC001103AB69058AF092B9BB4F6EF9CAF +:1036700049330F1AF5269931BF319D4C44CA074F83 +:10368000B2EAD35A2A13397874E06B7335BD527C91 +:103690006C98DC9F983C8A7451BF0256933E361456 +:1036A000584727E7B346DBEB31756CFEAFBCDA5FFA +:1036B0008F59CF00976850381DCAC819C5425A3A69 +:1036C0004CCC891A08179BC3FA9E490F61A04D85FF +:1036D00004CDA97F86F8C31E5F8E90F212EF2AF701 +:1036E0000DB50BE1F96C35C80EA30FC10A673206A0 +:1036F0009F3B5695787DBD84FFE367F4E8A4FDF811 +:103700007AFDA786DB21B51F8ADD5482CE21F51F05 +:10371000AC96B03F57643B7EA82C1E358469F68476 +:10372000EF8C25899F67F482154539CD05455608EC +:103730007009602870176802F2289AC506D5794E7C +:10374000A4920024281DB7222935A1D61B04DB42F0 +:103750003247A483D02697234A42586A683173318E +:10376000D7C1A27C99C5913ACB9265A6A127D288F0 +:10377000AD54260DC997D30CD901A5B17768C6738E +:103780005A0EEC096DF1A97B630EB9C7E2CCBD47B7 +:1037900052AA70CB0ADC91A6F55A416282C1B4CA22 +:1037A00019F80827638450A487546F67E7AD9F8991 +:1037B0000FB19F461F603E0BF4734FE117A0DED997 +:1037C00099A80857324E75CF0C6D2DECFF754BB88C +:1037D000B37D8DCC01BC9D479E857CD1A07C955549 +:1037E000A73971CCF43D1C449785AD8E7E608F82E5 +:1037F000CCAB8780023D74ACC28DDF32840D1DEFEF +:1038000007F44F9F64853AF2B6ABE5B4D482337BBC +:103810005294CC9E2912B1BE88D09E7CDC36397C75 +:10382000A5B1C4D285D036C81DA5454D314558FD3A +:103830007F73A3B7A5E2B3D72582BA2CC535F3644D +:103840007C90281EDB42B6330CE69B968B1A0B0F3E +:1038500026287A9A3CA6B7AA87026FB3710F3BB7A6 +:10386000E33C0A9B4954981BF7EA07B094C8A7A306 +:10387000B2B1D04656A737A167FFC4B7A5F7800EEF +:103880005702C933724E19150C0F6AEE76BFEFF866 +:10389000B269A9346E9CF0BF9A58C124A4DA7B7037 +:1038A0005F9F4C1BF70B34F9916968D4B7AFFCB834 +:1038B000572BE6346282BBFF47C8CC70FB3DF3F068 +:1038C000A63B409AEEDABC56CD9A6ED529648E148A +:1038D00016FE1CEAE87FBFD3DA12A69F4FB37BF631 +:1038E00027AACDBE0CADFEB135F06A4AC0A742662C +:1038F000D524C490E97F3FB30CAF18541AFB802E37 +:103900003E6C23129205CDA32452E3CBD0A0D4D693 +:10391000D5B0B6BE4816B6292280E7EE215062C562 +:10392000DAA7FF02818118B9001C2B0651B71020BD +:10393000C9E84CD80D11D30CBD4362B323CAD7E5F7 +:10394000C0C4B6075F75493B0EF661EFF6C0D6C03E +:10395000B702400AF4D0895ABC81952E1872241EF1 +:1039600021912A0B7EA39410B743C4108562E153C2 +:1039700031D5615BBB4D6A6507EEAA05D999C325B0 +:10398000F2F51C73DB0BFDF7AD580043B0AE035CE2 +:10399000F51C72E584CC1F4DAD414FF208C1D42B0C +:1039A00082E588B1827B672C260D30B3AB5DD06198 +:1039B0006BBFF106C9ED662424D1459646645BD100 +:1039C0002298A20148DC1CE4B34D21893D9D5B3E59 +:1039D00032B09BC0EAF928E89AF6AD010E7B681870 +:1039E000BC1BC9FEF6CFD96A0B982646F5DD5ECA28 +:1039F0005360097571DF8C9D3A881B4F1B7BAC149B +:103A0000936A851994E6433656D11D59F4688BDDC7 +:103A100034D7E34ECEB39038DCB7E9D069363E07F1 +:103A200050052837CA93113955E6D3D60C47F67B93 +:103A30004585A737CD11358519EE8353A555FD3141 +:103A400080105C15397662996C90E242449750364A +:103A50008CC6165746FFB1BFB4929C301CF30500CC +:103A60007DD0DD560591F0741DFC601CF160C10332 +:103A7000BF73A7D016B740526573E4598FDBDD8260 +:103A800032EA6817461EF87AD6AABD50E88E13129D +:103A9000F51A8FC834633FBF63C91050C06D66D23A +:103AA000C78A00173B0A8B9EC2DA99D8115CBB24E7 +:103AB00037625C75AD1949CF5DCA94525523C6D2A1 +:103AC000500F28E9FE379631F90AC6A18668BC3D39 +:103AD0008E5621B6AE59787FE9DCE9E7726E337510 +:103AE000438E2B103CEA1BC12F2B6918D14D137D3F +:103AF000FD3CC0FAC9EABF14929B699579D97EAEA4 +:103B0000DF7131EE60FAA22DCA2AB90F1544DB66C7 +:103B1000B1F0E4871CF431A0064F6411F73D36A1E3 +:103B2000C643882FC17A06AD0F5AE580B567DAE43F +:103B3000D92F26E6EC13BD5495B749E7C1B59E5E73 +:103B4000A82024899834E9E6561A9E6FF08A46A682 +:103B5000C4D01C81A7A6180428ECBCC33875A76E76 +:103B6000F36380E738607709D47741D01E96D72673 +:103B700051C18F8FA6BD3258B1B5C19106953EE4B3 +:103B800078F5AF8EC2DFE5A520D5914B8AAB7EE5F7 +:103B9000480B0EB35D9C609232EEA4706F1A22A99E +:103BA000D3322DE4B36D988BCCAF4C163269DAA6C4 +:103BB00011E4EE5A93E010C923AE24B27B91E2AA3D +:103BC000E68D8EACB8337616C62DCC86326D78F77E +:103BD000A8428D37266F44B244C82EC94FDAEBCEC7 +:103BE000CF0BCC8D9A3039251F090469C6EB523DA5 +:103BF0000C3970ED53A0999902F9C8C14CDFD9294D +:103C000043C2204DC45FF0BD7426E8E86DB40FAE2A +:103C1000146CA7D61469B70BC336ED4A7C98575A73 +:103C20005D072CB7FD4E87BA275C3951EEB28BD2B7 +:103C3000BAF15E4E8CF5C8BAFDB142DB71A29E7935 +:103C40007A46B0C22FB4DDB7F866FCD3942AC9F91E +:103C500077C94CE197E9B31A150845D8835607B5DB +:103C60003BD9A632DB67B0F255E76BB45962B5D6E3 +:103C7000E8153594B9C8911A6A1B879AC70C0EFECD +:103C80008A112FEAA3A99D31F1C10561555F37ADB6 +:103C9000260BD896AA7CBF037CCB10D0E052CC4236 +:103CA00019E76EBA27EFB0312F3E05A3E97B1181EA +:103CB0000F1AABBF8AFD5FFB7F3F61E34F47B10047 +:103CC0008531D26BB64AB2AC162634D3FE6C77DCA3 +:103CD0005D60DE25496E3999CA8884676D2E239E02 +:103CE000D475562950C955DDA8EAE885CF8FC8B0EC +:103CF000E4868E35DCBD9E6EBF7046542B5ABCE008 +:103D00001204FB06F806006E909B3246B2A62D5BAD +:103D10000BEF833BD211B22087CD4303C8566B23F0 +:103D20004CC58646C1878B28DB6561EDA9DA5D004D +:103D30004373FC0A5A1097177B23C7149135A69A30 +:103D400040B94AF8EAC151C49066ECC5F033AD7F82 +:103D5000E3D407D8F058B28E603781E5628FB21A8B +:103D6000FC1E575BA189C82550E54ACEE413217695 +:103D700089574C6BB14573D81175430619B1ACCA5C +:103D8000824E7C73512C1648ABAA01524DC4AD64CF +:103D9000F56A27D6861CB820E5D56B1236B9AE5920 +:103DA0000772E82AD38D862C2BD76447ABC41487BF +:103DB000B65E57D609BD974B994B320925B8B92B3A +:103DC0002060E3A771AE9ACC926E342982E8D22F9C +:103DD0002A886D80F0F9EC2BDCD8EA1F8A0F790174 +:103DE0002149899CFB7C3BD16B3BC4C4136E4DCEF7 +:103DF000337EE8C785B33ADE9B7F65CEB960DA498A +:103E0000D9501710A600B130AC4F539519203895F2 +:103E1000C89527864C06F173C85E67DAD368D07AF6 +:103E2000C5615F11DCA755CDAF8C5FDF7D9AD4747F +:103E30002AE3232915DB9535FC355F915B37F6FEC8 +:103E4000E47D8E19FE2651D3FF629C6949867C165B +:103E50001CB26157BCA690BEAB9AC286DB7668CA1C +:103E60006F44E1F6D365B4126DDC41509F58D27BAC +:103E7000ED76C387E4E491752573B82DE50AFD1549 +:103E80004A6A845A4CCD9923A1D56EDEAE52D475C0 +:103E9000447A0D184E0EF97BB6048000FE78DC746F +:103EA000A7912A20237BC71A358D6D5868297C2657 +:103EB0004A6C8929E504BF774788C919649A5884F0 +:103EC00086CB6B1166449BB66E17E896123C247F36 +:103ED0006A608A1686659E347EFCE63F3E9E84F6C6 +:103EE0005F61B85C400A783EDB6D7079EF71789461 +:103EF000CF9A0D041EAE997D360369D520B70663AF +:103F00003A00B70B20FB3CA3E8C642EECF54227F19 +:103F1000877DD8C360E610AEF845BA83E111D76B50 +:103F2000018987B2E11F16988CA7130BD94523A0EE +:103F30005C4E99871D6536E185B442B2B3B39D06E8 +:103F400018B3698498C45D9B76E6CE4C6014ADE2EC +:103F50008C20A4E0A79BB625D8D52745B4AEF6E6BD +:103F60001FAB04ACD9FB35A04903DA84BDE175E091 +:103F7000337B242C91737608B97086CAC17A55AD0B +:103F8000182A784916D03CCA52E656C5D2FE1DE51D +:103F9000D13DAC7692F6BD66E5223EB10E5CAA8CB0 +:103FA00043C28B87618DDB826BBEBB52C8087D55D7 +:103FB000705AF68B741E9B2D64CBFE4A83C05F61E2 +:103FC0003C4AE547B2BE6A0D2A7AAFD7B59E56E3A2 +:103FD00034B8A3202AAEAF0CBF5C1BAA820CDD57FD +:103FE000038F2B23B3A53BA5D29DEA8093AE586ED9 +:103FF000B1B9ABCDBBDB1BDA9B5BC9F9199D5D6524 +:10400000610033A283047D13A4D14FDB74A0BBB144 +:104010006240841118F4D7190452759F4591D48ECB +:104020001DE3A6949D35F930F621FFD8D57B82FF9C +:1040300055F12A152AB01434EE31FE59E6B78E93A5 +:104040004746AE07C04330B06F42C784F5E472986C +:1040500048154705562C2778780D1CF536B3D4F350 +:104060005D3CB4D44B3885C34DB1E85C212D05F0DF +:10407000ADD0E69A923ABFF55DFB465B33745606C7 +:1040800027CA60D66A8290B54EA87EDE49F0C92460 +:1040900074D30DAB5B9EBD19FE7C6FDF3F3A792474 +:1040A0006289A0D8D55FF4F83BAB4DD177AB3041F6 +:1040B000AD1F5798709BBB3D727B4C597FB96860B0 +:1040C000F135CFFF2E33D7BFB23A66239637B8F318 +:1040D00068A44E99CA10D6BE5C7E85BB86A18601B7 +:1040E0009C8C531827CCB0FC4D10E807CD6DBD4A11 +:1040F0000DD9AE4F2FDC99FD1F2B9ED27F3316FFBB +:104100003A82EACCF801F0A1D85AE14982E4BB2412 +:104110002972C306DAAEFA45E6D2C343BC39574525 +:1041200079C60238DDF614AFDE534218AB953A205B +:1041300069D84D0EB3922EA881532A9BE843B96EDD +:10414000BDB00A6290D03F3F1E82EEE9E2E0C4DCDF +:1041500035B8AEC8F065B2A443724729B9D485DA40 +:10416000B8B1866016336D879B83C4518F6AC028AF +:1041700017B38782BBA617AA8DBB30988797D7DA6B +:1041800060180B0B868BAFA3A64AA3B0844E38E110 +:1041900068108B33366AEE86621F2A55ECB8D568F4 +:1041A00063C05807038A233173A9EDC7ED2B39E9A2 +:1041B000AE7B4B0B2BEC152B637FD509C280DF4FF9 +:1041C0003C4EC203908DF148DD8AC82DE05C5AC395 +:1041D000FBBAB04FC204F2B4CA663DB9868FD72F7E +:1041E000E7CD86A7FB8A582ED10B9F41731E79ED30 +:1041F000C9F48D1A89A3668E8CFBD0303A5AB06010 +:104200003AEC03D06014CFED76A095D6B065917FDF +:10421000087227924CF14C731CA4E310A656F3626B +:1042200065326599291AB18215E1EE100527C2128F +:104230006813EE6511D7B7CA0041ED5C1AA5527537 +:104240003E3E7D1B2856323C7D9BF344BC628E353E +:1042500087329ABE37AB5B38F755B64BA30E576E15 +:1042600025E4E61BD1B68FB475F06F35EF18FAA9C7 +:1042700035C143E8DBB7D3D0200E616DE583C03A8A +:104280003E6822C3F8CA2476C9901F7886D2DB7BA9 +:10429000FE617F6234DBFB99C0D8EB5BCE313A35EF +:1042A0004D741B81C3A98BC9D758EA1868567F0F74 +:1042B0000977AF10C721BF1F87CABC545A5547B6EC +:1042C000549A2C0BB8CADBBF768A3D832C04C4B148 +:1042D000FAAB28126242386D467492FCECCCB0D234 +:1042E0000FBAF7118B3E3633E38BB5862C1C59BEC3 +:1042F000F0E94A5DAF098B3267C951F07F8E58FCF7 +:10430000682686A76007BB21574042EBE4A2DCF792 +:1043100038124187D7FEF46C0012E4FE783031A3E6 +:104320003061A71008ED7120FAA186A20BD677D0D4 +:10433000E32A2488058C940259B3A4CE9D3AD3C7AE +:104340005EE20CF4D877B72548B3301B701DB66514 +:104350001075A483BA97FCC1F392433A80C67C4A95 +:1043600001C3430B97B4122BC5018D35E994524B11 +:10437000294624C6D11041ADE9F1DC785D0427E877 +:10438000E67939E6FCEC5855C90DED37C35837E7E7 +:104390004AD6F6840A6DBE2A0207B2547A397D24C1 +:1043A000410E8F1A913F570587493FAFF6AB5446F0 +:1043B000491E8E0BDFEC1126E8C54236E5DDC7A9A4 +:1043C0004117D686B43876A14A9540AE461DA6E37D +:1043D0001B228FCD9458FE2E423AAE72CDC5AF7AD5 +:1043E0004E3417CCF52DFE69B7BB90CD44D02A3999 +:1043F000C7FE1C10A7AC13A2217AB8CFAB7B9FE1FC +:10440000DB068490F002BCA780D139DFEA44307526 +:10441000E21D849A6C9529F346D23ECA825417D67F +:10442000E50BA4941F03302DA54B451FA7751FB6A0 +:10443000A9174473893D50F1C8C51A78C3B01495C3 +:10444000151F939BBCD65164D49004EE8015FA7965 +:10445000323067106CC3B8B7AF0CCBD84609FA43FB +:10446000D1AC05ABA3AB92B50BE4477C111CC5BB2B +:1044700092E362D55AD63ABB334EB2DEB54E9CF8C3 +:10448000A6CA889E02863ADC4EBE8C59E84C707DE6 +:1044900056F8A21F6E9D8F74460AC776805C1F6E09 +:1044A000EE7C0D1AB70B34995D586877A59617BE48 +:1044B0002D5BE99DB9FDD5B69BC96370C1B81C9D44 +:1044C000170AC7F68ED0F848F217669D74909E7D45 +:1044D00016A54F5090E8D4585EFF10FD864ED55279 +:1044E0001FEC4714014B28AA7050EC529D1C7A53C4 +:1044F000AF71F032B1ECAF10EF06EF9E5B8D7154EF +:104500007805E08102ECBAEBEFDFBFBFF244AFCD3C +:104510005AAAEA656A0BDF8A97D2EDCAC3342A2108 +:104520005DF2048F9407B2F671A144C922B7FBBDB6 +:1045300033963E88EF10FAA51BD3E545593124B7D1 +:1045400094BEFFA50046DF66CDE4B672A8A6D122D0 +:10455000B3D258BC9669ECB80892EFE8DC841F6AC5 +:1045600079BE77656137940231B5D0EB664150670B +:1045700071BF2F0A1AABA0A60D93418DB9559FECC0 +:10458000068FBF83863294DD5D3EE9CF2133A49D43 +:10459000AAE985096D988F487DBC8BCD1A2CDA6706 +:1045A000838E33FE23134EDE17A9CE0E24132C69FF +:1045B000CB18268A542BF2EEDB532B507B02FD9056 +:1045C000BF75E1487A611C08901B6C43D68ED86D8C +:1045D00072A6A70019D89F0DCA804B360771BAD2B0 +:1045E000FAF5616AD87065B3E71AE441519DDB6161 +:1045F000B4560F5B0B5AAB6D0B88C40C042CAC6E1D +:104600007504680E64BB14EB178066602046F0E00A +:104610006C141153DC907D5F4DB54352FC65D4FCA6 +:10462000FA7E5FED8578B8734505A453CC95558D1A +:104630000B5B5EECCDAAB95F1833BA07E5920C7C30 +:104640000BBD839D84FB3A58C313E6DFEC567A9486 +:1046500003A982CA6C25E57EA37278BAD6F5D03458 +:10466000654B8610ED07B460DF65629AB5C47E7B4A +:10467000F9B34853934A1275651F4F5A84A616F72B +:10468000F977AA5AAE4ED9972E2A33ACB9C3A1F501 +:10469000F167D6E6E894D2BFA447485BFE6DD474B8 +:1046A000560DE004657E76916F8DDB4D68298DFE99 +:1046B0006F1D9859D1039E907F60355689DF067D26 +:1046C000E5CF0EC727E018EAAB2F972AA904B7B1A8 +:1046D000555CDF2B904210963E3527D696CC6BB0BA +:1046E0004C344AABB8492C7AEC67EBBEAC9677E811 +:1046F0002F0DF9B228BDBD695B1BCFEF26F51ED08B +:1047000089E8E1897CF7F8651654BB80B402C91DBD +:10471000AA10E17A97497E35DD5066C9636B2A613C +:104720002527B7CF6189025E533146281C87802236 +:10473000D6370781A9084D0859EA43CE9927A2E93F +:10474000C4B3A5C4C48810E0B083F38530CC80E244 +:104750005076B0E02850F6E700F0587180F4733DD1 +:104760005AC7C2B601C3164A4BE1D926E12FB5C6D6 +:1047700051BC0A7ACD9991C34113C24AC395E82727 +:10478000E5FAF387070A9BBE2A2ECC6B6D1E859532 +:104790002CD0F2765C20FBAA229EA490075E456492 +:1047A000438A3CC8F391675F53F21CC79CAB0EDF92 +:1047B000D4E40FA92B0F1EA56326ED09DBEE78E4E8 +:1047C00087B5FBDAF3CA9E400D11B1CA2D4E298D73 +:1047D0003238D1502A5D88DDDABBB0106EF33C0C64 +:1047E000980C0C341CCB1AE8BE706F8C33C508E8EB +:1047F00071593C89C7ADBBC1AF85AC9783FDFB9BAD +:104800002248DB6F43E4DF06CF65BAD8FAC0D59300 +:1048100075166D8F1E775E54AC36DF60843432823D +:10482000DA7C26D0FB1DB01937DD22DD4E25B361C1 +:10483000D26C5A6CB5132310ADA861477D3C08B10A +:1048400034208A397566E00B03E7B39654E8FA5FC3 +:10485000ADA1019A0DF1BA184476E3E57EFF14D5B7 +:104860003121245C850367F49999E0108DE30FB43E +:10487000D9A089981B45B7480FF2E35A198AD497F3 +:10488000460E3DDAF610C7BE92F1D1642BC6FEEBA0 +:10489000D165AFDBD6B9D40C7E8565B53A5C596479 +:1048A000214153656FD1552F67AFA0B433DD5F71E0 +:1048B000661FE585D7D8544E177914D0ADBE027661 +:1048C0003FFA8B3DD878FC970ECE8FA3CC690BF7BF +:1048D000CEA84D056E5A3B60C3BDB1D7D0085B4D25 +:1048E0005FFB4E311C37BE052EDD0B217594BCE5F8 +:1048F000D8DD582A8F1B2242737F6B99DF38DBFF8C +:10490000044081009666700268274620A8523B6FDB +:1049100000520181C7E79DBC98247F7DBED6DD2370 +:1049200003418042FF0371A10F0F637D11173B26E6 +:104930002911C10BF132682C267AF2C71D44656C2F +:10494000C440F069A88694D130AC1449EC062E6BB3 +:1049500037540B0524D4EF052057964A0B96D1AF58 +:104960004550829151E596C602E38190B1DA736BAE +:104970003A3687A7651710F3C9F398230C85826828 +:104980002A080A04128E5BB1A8D3B579EF281C1B44 +:104990000A0828090DBCB8EB62D085849B4AD49FD5 +:1049A00003898907BBF259A0D32E97F7CAF33D9527 +:1049B0001B59280BEBCDA2266452A96BD335DF6CB3 +:1049C00042F2F1622053D4A16A97E641669C0A63E1 +:1049D000629AE2874AAFFF82225FB642A99EF7E65B +:1049E00003768262BDDEF1A833B95CB2B3A1CCE537 +:1049F000459CA8CF7DAC733F3BB0C342B99FDD5906 +:104A000014E220B07BFE46EF36D60081705B43AEE9 +:104A1000B66182D11B76B3C60EA167752342777645 +:104A20001D819365E53A6F3F6CC71B6F2F95336D02 +:104A30003FA162BC66F7C73C529582FC17C7C2AD66 +:104A40006210FABF94C07E5A6C626519F37319D272 +:104A50001C4ED81BE416356324D4EC57A26A988305 +:104A6000E049250085FABA5AFA034EAB509719F07F +:104A700025575F566A512585EAF06E5B836EEFD845 +:104A8000A6FB8B9B06AC3823812CE0F56CA49F39E8 +:104A9000EA698A790CAE59B7DCDA2AA99A247159E5 +:104AA000737A249772FBD3352F56EE1E97BDF8AB61 +:104AB0003DA99FB4F19B5034471D14191FB8FD1B2D +:104AC00069B7F38098FA19973EF6ACA8B5F29E88BC +:104AD0006CBA53C23C58AD85F582BEA17BCEFE6B4D +:104AE000FC9328A471EFBC68B16D7C4A611C121E56 +:104AF0002F00271291D2F57160A63F89F9482BDB70 +:104B0000222004E0D21648BBF0211FD23ACE8B20DF +:104B100038122789B02226C1B8B6CD7BBEB222F9A1 +:104B2000294184222161F5C28BD87D439159F4C07B +:104B30001113CD8B11A599E36038207C9941E6943F +:104B400039E161069E7493B28F45E7C2C56452880D +:104B5000CFC5BA09B65905EBCC0DE4C3FC89515059 +:104B600041725240C25D4E123BF91BC935AD256CF6 +:104B700023B1C6C788F74118B0EF663849B1C9E11B +:104B8000221B0D8482929EAA0F1A408A08DFFF28FA +:104B9000BA188C8992E1B1A445512D491A4DFE6A8B +:104BA000238A8C8AB96D6BCF17F2DE07811F1745F8 +:104BB00029198D8ED0383C5AFB3896D0CFCC51660F +:104BC0001CD9650AB24A5EA2C608CC46BE07FF6C75 +:104BD000AAD4E9C11D60E918C598CDB74D7FD2E1CF +:104BE000E3CF18FB8BC9625B90346DAB8B4B51EC00 +:104BF0000A48801B9C656DEE791930AA938E19EFD7 +:104C000084F18713F625DFD4100662F4B0A778B0DC +:104C1000C87D46B128A455010482CA7EBC0CD89137 +:104C2000D070281F9F00DFBD6B58197331A3F83275 +:104C3000C97DC6D3D3915CBC9DC187493BB7079E54 +:104C4000374065C28566E00BD37D8D62A5FD1D8072 +:104C50000C1B2398DB6DC7229D070C701F0DF4FB06 +:104C60001DE47399527842612B79E294752164F5C1 +:104C70007A2D25ADBDD3F7B95D0207571DC8D3996D +:104C8000C2611F66F434D7DC48AD9DD732BE786F61 +:104C9000946B8ED9AA198A32FEB9639BCDD97DB99E +:104CA0009DBB6F859D08033183D04F2717AAECFA6F +:104CB0001D68293F2F1806A01B4A1626BB0579DB65 +:104CC00062A85C9A8E48C2FDDE60A656B6D1769088 +:104CD000C538ADC791241BFF20F52B93A744795D00 +:104CE0002D510DFBDD32B66154F8A56ADF2D22FD92 +:104CF000A8B9D7408A813D481E5B39605C957EF239 +:104D00003D42A1358443912E3028467650AAEC22AC +:104D1000C801450FB74B7AF722CF471ADCF2C362BE +:104D200051854C7F418B4CDE60A55A197070BB16C3 +:104D300031FA020E890A4F61ADB5B2A47ACE526D36 +:104D400020C04E8F7FB236A92844358EAF5BAC674A +:104D5000EAACFDFE60F837238170A2FA384B779EEB +:104D600045A384F3A18CE4298EA8FD765175516882 +:104D7000A2BCD75C03E832A099880E41DD51514DA9 +:104D80007B6757F763ED738DE2344CD972137C2A3D +:104D900045E3B8932296D1431E7FC8470A9C7959B0 +:104DA000BAD57F37A3FC78AADAEECABF0E455A7986 +:104DB00070F17B49A80EDA9FBC85FADCC1FD7A0E42 +:104DC000423AF14EC059B6A798B529B7B40E690852 +:104DD000D2A8070208D8E90398FA0C77FA1E994D71 +:104DE0009BAD080CC1AF9C592B89CE45292A58543C +:104DF000FF2B284DAB880522619B67C493F459159E +:104E00005C8430DF40547C334D1A66F010547C7F54 +:104E1000A0022D19ADF6599BAB946706A4D4457733 +:104E20006558DC1FBD043218F06363140527FBAB23 +:104E3000496130E27235FDD3A43536A4D2325078C0 +:104E4000EC6D0256D082623279566423EE1750FF21 +:104E500072BC02B524FB352F9C47D1177C7CD26EE7 +:104E6000C3619C26D56A53399765D78BFCD4D0345F +:104E7000A5552464A4A7801A81AFD0437B0316FDF7 +:104E8000C68E3A15355DD392D6072E438428D009B5 +:104E9000F4EE085986EF7276DE5C7B1BD453DA7F22 +:104EA0004D949BEE28F3652136DFC9DBF764CA77A2 +:104EB000A7088D00D6DC4474EED7EF55D0AB587000 +:104EC000D68E145D3C44DD7EEC6A293F518C3289DC +:104ED000B1FF8A1B712A08E4667A28DED85C927ECC +:104EE00027009213728289332F6B97BB8769C9336E +:104EF0000245761095221C7D27DDEDD4736FA777D0 +:104F0000268D878EFE0958EEF03390DDEA16F7E421 +:104F1000FB64FA00771696AF001933830CC615EEC2 +:104F2000C13CA099C0A7421D19417DCE37D789ED5C +:104F30008EE0010E4928B1579F5C46CED966B0EE8F +:104F400051A702A2B857101BF180EA493804A9887A +:104F50000886010E12D4956F00F0003F38F096E3FA +:104F60008CE3804696459AE40944A59635C7778632 +:104F7000E8B1B490E135752723BF648634B376E495 +:104F800070B9E7ECEC8A6DCE4FE8EDD74909FD1713 +:104F900065A7AC05D22156AFB1C4F471DAEFE6AB28 +:104FA0001B6BD48CC3CE18578E763397D3FE6BE72A +:104FB000EF9ECEEBE1673C2744519C54DE405FF806 +:104FC000D8B58C4660BEE1A3B287048ECA7F21CCDF +:104FD0008D1A4750BAE613E128FE5CCD9AAE71E017 +:104FE000A32979E023E12BEF8205C8103379EBAFD9 +:104FF0008CB90FCFB87BBD3FBBBC598DE17EFCCED9 +:10500000BFE40580344136454926DA1232242FC4E4 +:10501000BC42C49EF2003545A19F6386DC7F47FCFD +:10502000E5072594A1C035BCF5FAE0908D15F04256 +:10503000ED181D974B667FC384377880B7A756B1AC +:10504000D0BD8592900312B7490AD4114CC2F47EA8 +:10505000D8B0A5AF5BD7BAB91C3B11D82190FA03E1 +:1050600028EE076965D239B46B43D097D28509ED34 +:105070007D8C04F2855321957F1146BBF57775F53C +:10508000A6CD22869C7DFE63F6052A9AC10E7A4F34 +:105090007EF861DB4D7B564F323E6EBD144E31F6CD +:1050A0005C09B7EA7B72BD1170E4EA82E48B7EF89A +:1050B0004AEBD2BBA71B2BDAAF7CEF2E0B4F02F4CF +:1050C000D928ACA6B8F8111714EE6D2C718C3D23BD +:1050D000565834DC602FA3CDED9890B19E376B7697 +:1050E000F2A951FB51F9B8E8AD056CE48F6B409320 +:1050F000C039036207559D691D15EC8FFB1DDBFF51 +:10510000C03FC442CE763E8FF13F909643DAD297AD +:10511000451CA2430868EC6344B4D717F88BB46C01 +:10512000A59E6104CBC731DD36BEC6142F47AC6DDA +:10513000D64B0339FACC1309672B09DA4AD7D5B80D +:105140006036EBC700AE96DF0920E742C0C33144AA +:10515000B377A2FA0897DF671476E2438241F0241E +:105160003EB9820BC5C150A21E6B6140A9E7FE1477 +:105170008955195B253D951B166A600719CF886113 +:10518000836A2B2A62FC1C2735D9D46A33A8EE1017 +:10519000099A02D08E7A2A5565FACA0FFAF84D6438 +:1051A0005AA66D01DA437F31FBA3EA9CDB295D62DD +:1051B0003379CD08719FC2EDAC1D1D935FB8D7E167 +:1051C000F90697F137B13E6C219B4CF79F44FB6782 +:1051D00011582F0B1DACE4223C050BB2D89E683150 +:1051E000EE3AE0B1A15F18E4F02E2345D2EFD128CA +:1051F000811D2A09AB7DD2A29B7FF9902159E8B687 +:105200006692267D3066033834C6444B8CA8327FC4 +:10521000BBED2797F4E6B38B9E8201DF1C3093D75A +:10522000E1054DED3D07EBE6E0D78B5DAD45B88977 +:105230002F951FD16D77953563B7085C0D37D31C5B +:1052400011A201D4A409D8391A0BC13130CAF05CBB +:105250004CDC0714F413ED3D2472686CBC54DC780C +:105260001544AE543A47CF602D63B92CD515F37968 +:105270001A542C11CBB7314D2573A81AAFDBFFFCA4 +:10528000B56AD3C5CB4899A7440B833CAE1ECC1856 +:10529000149CC25D2EEE4B96BACAE726CE8B1A59E5 +:1052A00055AD5BA733EFC4952D2ECCF5CD025B7CBD +:1052B0002C9E8DE42BFF4EB045B86704E73FDB0E14 +:1052C0008BE48B9AB02E1E3A2ECFC91D230E5E1290 +:1052D00076A8AB9BCD5E7E379077CA54F63E480ADF +:1052E000544BB52F8BB11B3797475A5897D2F212B0 +:1052F0006B99AF71F53F17B4DBFD1A62600B7871E3 +:10530000E40726A298EEC96F977FA53F7706F54080 +:10531000E8BCB00CF14CF2A17D4D2EA5C644D7DB04 +:105320001C458EC3C1D74CAF8E645AC86E23D2754C +:10533000700D62C1396517193902986C9BD55051AF +:10534000AB02A57F98C4365CCF7CE54148161EEDC4 +:10535000A8240883E85617E418AB1EC8388EB9A2F3 +:1053600021C74402E3A596A68E5D658775E368892B +:10537000A21326781C9279D7616EC1317A7373B902 +:105380004D443F5C81EC9E129259C06B22AC47FBAE +:10539000E05EAC26CAC781A69A4A41663A3AF3143F +:1053A000996BCA8C011F3F27B8D840678B4F941167 +:1053B000B4E68FC9CBC61FA49B406E3BDBF6B7E6B5 +:1053C000E2D8CE97E2421EFCB61860CA32C0EBAEFD +:1053D000325B4B8E8C93E0DA1D2E490AE3FAE12F03 +:1053E000D05F6B9CE3439EFEBD186D8C98A6D86081 +:1053F000384F0DB5F8A0216CDB5F2EC93BB09FAFD5 +:105400009F32004FA4BBDFF46EA6EAEFCC2456FF18 +:105410008C8CA9D008F440B8E7FF1A5A7C15B7B3B2 +:105420009AF3A03D9F37BD1D6CC10193EF5857B350 +:105430004DB6E99E2DD1C1F282F1444866C0F3D841 +:10544000F4850292AC24302EB4C54F9614D952EF95 +:10545000A793846E0EB4C8B396D6E51F1780177B4A +:10546000AF87079020E3340C6CC9E053499109EDF4 +:105470002D576513A21A16DBAA03A7D8848810EC4F +:10548000D97A2484C60E5DB53D533C83912AA0533E +:10549000C21AD1B91AFCCEDC2CDC92C230787BCE99 +:1054A0001AC1BCDB5CA81D453C460CC1772D57B822 +:1054B00083D92ED997A242268DCD9174903B2BA0F3 +:1054C000A6BD239A018E76F276EAECDD1DFA5ABE6D +:1054D000EE48EF107E5C13CF6EAB2FD28D7A37E3A0 +:1054E000AC8A0F61304B00D3F8994DD8B7EF7CBC34 +:1054F0000F023790B54C1CB97FFBEF9EFFFFFFFFFB +:1055000080F93BEB68A89543AC04C27A90245060C4 +:10551000C7BFD786B8F6BD2E4DD2C622983451618A +:1055200056FD8085117712DB874342789125D06242 +:10553000C6EE73631997D3438991CD239935D1630F +:1055400040400204C044122450604244D06452647B +:1055500048500305C854132558704345D874536503 +:1055600041418206C14592265161C246D165D2664B +:1055700049518307C95593275971C347D9753A1EB5 +:10558000FDB2143FBA2CB91792C0600A922C586829 +:10559000D72EE76E8E18BF23D4B7E8429A3C5969DC +:1055A0005BAA826D13F0B8F1C917EC4C932DD86A41 +:1055B000D6E67B69F362F2249FBD6A4B9B3DD96BB3 +:1055C00042480A0CC24C1A2C52684A4CAD945A9963 +:1055D0004A580B0DCA5C1B2D5A784B4D2E6D87D542 +:1055E00043498A0EC34D9A2E5369CA4EDE53CB2CC3 +:1055F0004B598B0FCB5D9B2F5B79CB4F78250317D6 +:10560000B8A4CB7414843030E5CE660E94A47070C8 +:10561000749427D18C943131DC1ED4139CB47171F5 +:105620005CD345B98585B032EEA55E9095A5F07244 +:1056300008E32F528D95B133F3FEE5249DB5F17348 +:1056400044C02214C4C4323454E06254AB60553FA9 +:105650004CD02315CCD433355CF0635505894C63AD +:1056600045C1A216C5C5B23655E1E2560EB18D2E22 +:105670004DD1A317CDD5B3375DF1E3578320F3D3D5 +:10568000DD5C57AB868C3838D42CDE0596AC787848 +:1056900034632D528E9C3939EB2C6F0E9EBC797978 +:1056A000DA9D9F1A878DB83AD7F61D1A97ADF87A0A +:1056B000D7EB56908F9DB93BA63D6EF79FBDF97B0A +:1056C00046C82A1CC6CC3A3C56E86A5C8624019C33 +:1056D0004ED82B1DCEDC3B3D5EF86B5D6900068627 +:1056E00047C9AA1EC7CDBA3E57E9EA5E8CEDFC2732 +:1056F0004FD9AB1FCFDDBB3F5FF9EB5FBE8ED9004B +:10570000DFB81A67263430BBA0A00BB6B02654E031 +:10571000F6BD6016D848979B8E0E6183B83655E16A +:1057200099B9AA1572716BE209C3C880B127D4E296 +:10573000F7EC77E2FF6836E2A5AAC443B937D5E3B0 +:1057400060420684E04616A4706246C4D32A5274AE +:1057500068520785E85617A5787247C5A8316CF0DE +:1057600061438686E14796A67163C6C6D84337492A +:1057700069538787E95797A77973C7C7479F3B2125 +:10578000DDB0309362777FE408C2D807B22E5CE8C0 +:105790002A7C807FE7AFBEE819C5BF6EBA3E5DE9DF +:1057A000276D7391E72B7DACA380D0BDB32FDCEACE +:1057B000231E8BFCF258FA8BC4812389BB3FDDEB9F +:1057C000624A0E8CE24E1EAC726A4ECCE07EB5EFA1 +:1057D0006A5A0F8DEA5E1FAD7A7A4FCD0750FC36BC +:1057E000634B8E8EE34F9EAE736BCECEAD8DDA6B78 +:1057F0006B5B8F8FEB5F9FAF7B7BCFCF64824D6204 +:105800008DBF971DA48634B0B40D22D6B4A674F013 +:10581000D6B621B1AC9635B144F44B90BCB675F117 +:10582000DF9E5AC2A587B4B2780A8792B5A7F4F270 +:105830002D82BD93AD97B5B3FD1D5091BDB7F5F366 +:1058400064C22694E4C636B474E266D42DE60D94A0 +:105850006CD22795ECD637B57CF267D5630BE56E35 +:1058600065C3A696E5C7B6B675E3E6D63507F62D49 +:105870006DD3A797EDD7B7B77DF3E7D7770EE28261 +:105880002375DEC1A68E3CB8589E68AFB6AE7CF8D4 +:10589000CF8FA06FAE9E3DB95E7719D6BEBE7DF9A3 +:1058A000D831D1D8A78FBCBAF5D48C3AB7AFFCFAAF +:1058B000279EABECAF9FBDBBAF3F1FB6BFBFFDFB8D +:1058C00066CA2E9CE6CE3EBC76EA6EDCA6027EBCA4 +:1058D0006EDA2F9DEEDE3FBD7EFA6FDD56FE7FFD58 +:1058E00067CBAE9EE7CFBEBE77EBEEDEAF60FA8948 +:1058F0006FDBAF9FEFDFBFBF7FFBEFDFFFFF65D049 +:00000001FF diff --git a/firmware/j20s_novatek_ts_fw01.bin.ihex b/firmware/j20s_novatek_ts_fw01.bin.ihex new file mode 100644 index 000000000000..ca0422729ef8 --- /dev/null +++ b/firmware/j20s_novatek_ts_fw01.bin.ihex @@ -0,0 +1,8707 @@ +:1000000000010000000000003F2F010000810100FE +:1000100040710200EF410000C70F9B14332BFA7DA3 +:1000200000000000A000000002000000000000002E +:10003000708F020000000000309F01000C52006829 +:10004000707B020000000000308B0100DFD4CD592E +:10005000709902000000000030A90100DFD4CD59E2 +:10006000402F0100C40B00004030010044C56B92DA +:100070000000020080090000043C01008AD88BAE19 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F00040700200FF00000000000000095CC353D4 +:10010000480001EA400000094000000940000009E1 +:100110003AFFBFFC3A0FA83C4400000148000190A0 +:100120003AFFBFFC3A0FA83C440000024800018897 +:100130003AFFBFFC3A0FA83C44000003480001808E +:100140003AFFBFFC3A0FA83C440000044800017885 +:100150003AFFBFFC3A0FA83C44000005480001707C +:100160003AFFBFFC3A0FA83C440000064800016873 +:100170003AFFBFFC3A0FA83C44000007480001606A +:10018000480000004000000940000009400000094C +:100190003AFFBCBC3A0F943C440000004800017197 +:1001A0003AFFBCBC3A0F943C440000014800017483 +:1001B0003AFFBCBC3A0F943C440000024800016C7A +:1001C0003AFFBCBC3A0F943C44000003480001597C +:1001D0003AFFBCBC3A0F943C440000044800015C68 +:1001E0003AFFBCBC3A0F943C44000005480001496A +:1001F0003AFFBCBC3A0F943C440000064800014161 +:100200003AFFBCBC3A0F943C440000074800013957 +:100210003AFFBCBC3A0F943C44000008480001314E +:100220003AFFBCBC3A0F943C440000094800012945 +:100230003AFFBCBC3A0F943C4400000A480001213C +:100240003AFFBCBC3A0F943C4400000B4800011933 +:100250003AFFBCBC3A0F943C4400000C480001112A +:100260003AFFBCBC3A0F943C4400000D4800010921 +:100270003AFFBCBC3A0F943C4400000E4800010118 +:100280003AFFBCBC3A0F943C4400000F4800010404 +:100290003AFFBCBC3A0F943C44000010480000FCFC +:1002A0003AFFBCBC3A0F943C44000011480000E9FE +:1002B0003AFFBCBC3A0F943C44000012480000E1F5 +:1002C0003AFFBCBC3A0F943C44000013480000D9EC +:1002D0003AFFBCBC3A0F943C44000014480000DCD8 +:1002E0003AFFBCBC3A0F943C44000015480000D4CF +:1002F0003AFFBCBC3A0F943C44000016480000C1D1 +:100300003AFFBCBC3A0F943C44000017480000B9C7 +:100310003AFFBCBC3A0F943C44000018480000B1BE +:100320003AFFBCBC3A0F943C44000019480000A9B5 +:100330003AFFBCBC3A0F943C4400001A480000A1AC +:100340003AFFBCBC3A0F943C4400001B48000099A3 +:100350003AFFBCBC3A0F943C4400001C480000919A +:100360003AFFBCBC3A0F943C4400001D4800008991 +:100370003AFFBCBC3A0F943C4400001E4800008188 +:100380003AFFBCBC3A0F943C4400001F480000797F +:100390007E0500007E050000F0090000C608000090 +:1003A000C6080000C6080000C6080000C608000015 +:1003B000C6080000C608000000000000E0050000BC +:1003C000E8050000DE0B00006A0C0000F4050000E8 +:1003D000AA0C00007E060000A2060000AA0600008B +:1003E000B2060000BA060000460D0000C20600007A +:1003F000600D0000CA060000EE060000A207000023 +:10040000AE070000FE07000006080000740D0000A3 +:100410008E0D0000A80D000058080000D80D000047 +:10042000A2080000AA080000AC080000B408000000 +:10043000FA0D0000B6080000BE0800006412A40215 +:10044000642204023A1F883C803F442002983821ED +:100450000202643200029ED964320003DD2264028B +:100460000043640000083A1F88046412A403642255 +:1004700004033A0FA8043AFFBFC4640000044420F8 +:1004800002BC38210202DD223A0F94043AFFBC84F8 +:10049000640000046412A402642204023A1F883C2F +:1004A000442002BC38210202643200029ED9643228 +:1004B0000003DD2264020043640000083A1F880440 +:1004C0006412A403642204033A0F94043AFFBC8428 +:1004D000640000044FF2001D3A0FA83C3AFFBFFC35 +:1004E00045D2CA30801F64126402965F9E49C105DE +:1004F0003CFD4E18480000043CFD4E19E809DD2F74 +:10050000C8073AFFBFC43A0FA8046400000464029D +:100510002402441F3FFFFE0E5800400064022403E3 +:100520006400000845D2CA3045F3000044F00536A7 +:100530004EF20003DD2F3CFD4E1ADD2F640FFFEA63 +:100540003A6F98BC4402B3304462E1C49AB084204C +:10055000490094AE440FFFAAAE313A6F9884DD9EF5 +:100560003BFFFE3CEFFC84003C0FFABF3C0FFAC798 +:100570003C0FFACB3C0FFACF3C0FFAD83C0FFADC19 +:100580003C0FFAC53C0FFAD03C0FFACC3C0FFAD521 +:100590003C0FFACD3C0FFAC93C0FFAC63C0FFAC12A +:1005A0003C0FFADA3C0FFADE3C0FFAD33C0FFAD4D8 +:1005B0003C0FFAD13C0FFABD3C0FFADB3C0FFACEF0 +:1005C0003C0FFAC43C0FFAC03C0FFABE3C0FFAC312 +:1005D0003C0FFADD3C0FFAD23C0FFAD93C0FFACAB5 +:1005E0003C0FFAC264030003640304036412240290 +:1005F0009646C103640300034400400064022403E0 +:10060000641200028419FE0E6402000364000008F4 +:10061000640304024616F7845010807CFE0F6403C6 +:100620000403640200025800000164020003EC04A9 +:100630003BFFFE04DD9E4403F04B843FAE40440389 +:10064000F0EDA6405A1801048420AE404413F0DABD +:10065000A608540000F0AE088404640304034403B5 +:10066000F0498425AE404403F04A44100053AE40A4 +:10067000640304025800400064030403DD9EDD9E11 +:100680004443F114B46492784031E008FE1FB6048C +:100690004403F13844300055AC404403F13A84201F +:1006A000AE404403F1048421B6404403F1364423B0 +:1006B000F04AAE404413F134A608960EC803AED0FB +:1006C000D5FC4403F134A6009606DD9E924284A038 +:1006D000D207383016023830960A8CA1D5FADD9E42 +:1006E00084013C0FFABFDD9E3C0DFAC78C013C0F24 +:1006F000FAC7DD9E3A6F9ABCEFFC4900046AC01449 +:1007000084004900046A4900047B5A08010E3C0F2A +:10071000FAC84412B3AC3C0DFA994422B50C3C3DE6 +:10072000FAA349008B194900044BC00784013C0F10 +:10073000FAD7840049000448490004A0C01484008A +:10074000490004A04900045C5A08010E3C0FFABE9F +:100750004412B3AC3C0DFA994422B50C3C3DFAA3CB +:1007600049008AFA49000481C007840049000481D5 +:1007700084013C0FFAC0EC043A6F9A84DD9E840138 +:100780003C0FFADC4403F082A600C00B3BFFFCBC2C +:10079000EFFC44000069490004AFEC043BFFFC841B +:1007A000DD9E84013C0FFAC5DD9E84013C0FFAD02A +:1007B000DD9E84013C0FFACCDD9E84013C0FFAD50E +:1007C000DD9E84013C0FFAC9DD9E4403F04B843F5B +:1007D0003BFFFCBCAE408401EFFC3C0FFAC144007F +:1007E000006949000489EC043BFFFC84DD9E3C0D5C +:1007F000FAC35A08010884203C1FFAC33E07E915D2 +:10080000D50484023E07E9154403F04BA6405A1074 +:10081000FF05843FAE40D5FF84013C0FFAD684002B +:100820003C0FFADA3E07E9173C0DFA993A6F98BC8B +:10083000A6015A00040A49002A375A08010649004D +:1008400044D43E07E9473C0DFA99A6415A180328BB +:100850002E17E9515A180124A6405A1801212E6773 +:10086000E91297B0CE1C3C1DFAB5A6485A180118DB +:100870003C1DFAAAA6485A18011380263C6FFADBE1 +:10088000490009403C0DFAB5AF802E07E961C80464 +:100890003C1DFAAAAE08840149002A203A6F9884C8 +:1008A000DD9E3C0DFADA8C013C0FFADADD9E840104 +:1008B0003C0FFACA3E00041C4403F07E3BFFFCBC24 +:1008C000A640EFFC5A10010FA6405A10020CA64099 +:1008D0005A100309A6405A100406A6405A101003E5 +:1008E000A60084418420806280824400B1014900D6 +:1008F0006CDC49006CF1EC043BFFFC84DD9E840160 +:100900003C0FFADEDD9E84013C0FFAD34403F06411 +:10091000A6409646C9194423F010AE50A640581080 +:100920008001AE403C0DFA99A6008E02E602E91461 +:100930003BFFFCBCEFFC44000055490003DDEC0428 +:100940003BFFFC84D509A6409646C106A64054103C +:1009500080FEAE40DD9EDD9E3A6F9ABCEFFC490002 +:10096000044D5A0802143C5DFADB2E000D12D0062D +:100970003C0DFA99A6015A08040A490044363E077C +:10098000E925490007DB3E07E91784013C0FFAD946 +:100990003C0DFADB8C013C0FFADBEC043A6F9A84D5 +:1009A000DD9E84013C0FFAC4DD9EDD9E84013C0F78 +:1009B000FAC3DD9EDD9E84013C0FFAD2DD9E8401E8 +:1009C0003C0FFAC2DD9E4403F04B843F3BFFFCBC6E +:1009D000AE404403F0ED8420EFFCAE4044000069DB +:1009E0004900038AEC043BFFFC84DD9EEFF0F081BC +:1009F000F001441003E8FE0C50007C6144100093A9 +:100A000040000437F08340000009F0039E41F18369 +:100A1000C8FB4403F04A44100055AE40EC10DD9E84 +:100A2000EFF0F081F001441003E8FE0C50007C610F +:100A30004410009340000437F08340000009F003A5 +:100A40009E41F183C8FBEC10DD9EEFF0F081F101D7 +:100A5000460000F450000240FE0C50007D3A441065 +:100A6000024440000437F083F003441186A0401094 +:100A70000417C8064403F04A44100055AE40F00382 +:100A80009E41F183C8F2EC10DD9E3C1DFA37A608AA +:100A90008C01AE083C1DFA37A6089606C8063C0D28 +:100AA000FA393C0FFA36D5053C0DFA383C0FFA36C8 +:100AB0003C0DFA36A64880A01010003F8420181282 +:100AC00080015000003C18128001D8FEDD9E3C2DB4 +:100AD000FA36A65098D1AE199C0996005CF0003BFE +:100AE000E9028400AE10A6108840841FAE11DD9E7E +:100AF0003A6F9EBC84008020490002558400640542 +:100B0000E4034403F00EA440964EC90FA440965649 +:100B1000C90CA440965EC909A4409666C906A40003 +:100B2000540001004E0200BA4413F00EA408960EC1 +:100B3000C806A5C85473810097F9C72144122D50E7 +:100B40008400A7C8AC0844122CF03E07E939AE086F +:100B500044122CF197F8AE0844122CF2AE0844125D +:100B60002CF3AE0844122CF4AE0844122CF5AE0857 +:100B700044122CF6AE0844122CF7AE0849FFFCE2F2 +:100B80004403F00EA440964EC908A4409666C905D9 +:100B9000A40054000100C00349FFFF7944022D6006 +:100BA0008420AC4084C0440270403C6FFABE3C0FCD +:100BB000FAA43C6FFAC03C6FFAD65A78AE4384E38D +:100BC0003C0DFAA494BC8840A051C10CB4029649D3 +:100BD000A09349FFFD575A08010640001C0CFF87EF +:100BE00097B18CE15A780FEE3C2DFAA40411003D28 +:100BF0000401003C8E2496490421003F49FFFD4238 +:100C00005A08010544008000FF8744022D788420A3 +:100C1000AC40C61744022D60441FFF9FAE40440203 +:100C20002D619670AE4044022D6292C8AF8044039D +:100C3000F04A44100055AE40440000694900025C8F +:100C400044028F7044122D78FA5449FFFD413C0D47 +:100C5000FAA444322D7C44222D7D0400000940106A +:100C600020093E07C55D3E17C55E40104009921839 +:100C70003E17C55F3E07C560A618A6509602964A65 +:100C8000AE58AE1044322D7E44222D7FA618A650B9 +:100C90009602964AAE58AE104413F00E3C0DFA364A +:100CA000A6481010003C4413F00FA6481010003D59 +:100CB000490002FC9E81E6483C0FFAADE80C842115 +:100CC0004010880C5410808FC10650007FE09600C1 +:100CD00049FFFEFF4900901F3A6F9E84DD9E3A6FE8 +:100CE0009ABCEFFC3C0DFACB8C013C0FFACB3C0DCF +:100CF000FA99A6008E01E602E8322E07E93F5A0073 +:100D000055062E07E9355A0855213C03F4D98C01C4 +:100D10009601E60A3C0BF4D9E91B840449FFFED98D +:100D200084013E00045C8400490027D83C0DFA99F8 +:100D3000A6005A08010744000069490001DDD508F2 +:100D40008E02E602E900D50484003C0BF4D944008D +:100D500000553E07E93F3E07E935D50484003C0BCA +:100D6000F4D9EC043A6F9A84DD9E3BFFFCBCEFFCA7 +:100D7000FA1049FFFEAE84013C0FFACF490001CEC4 +:100D8000490027A53C0DFA998422490006BB490079 +:100D900027BC8420840284468061808180A1490030 +:100DA000028DEC043BFFFC84DD9E3A6F9ABCEFFCA5 +:100DB0003C1DFAB584013C0FFAD8AE08440FFFAAD7 +:100DC0003E07E93F4900021A3C2DFA995A080215DC +:100DD0003C13F4EE3C03F469E220E80EA6118E0306 +:100DE000E602E80A2E0004398C213C1BF4EE5A0876 +:100DF00001043E07E94B84003C0FFAD6A6115400CB +:100E000000FD5A000406800284214900067B490047 +:100E10002751C80A2E17E92F3E07E98B5A180111EE +:100E20003E07E989D50D840949FFFE53FA1849FFA9 +:100E3000FDDF840249003E6F84013E07E961EC0456 +:100E40003A6F9A84DD9E3BFFFCBCEFFCFA1249FF2F +:100E5000FE40EC0484013C0FFACD3BFFFC84DD9E98 +:100E60003BFFFCBCEFFCFA1349FFFE33EC043BFFF5 +:100E7000FC84DD9E3BFFFCBCEFFCFA1549FFFE291C +:100E8000EC0484013C0FFAD43BFFFC84DD9E3BFF65 +:100E9000FCBCEFFCFA1649FFFE1CEC0484013C0F7D +:100EA000FAD13BFFFC84DD9E3BFFFCBCEFFCFA1754 +:100EB00049FFFE0F84013C0FFABD490082355A08F4 +:100EC000A1064400005549000117840249003E2351 +:100ED000EC043BFFFC84DD9E3BFFFCBCEFFCFA18FE +:100EE00049FFFDF784013C0FFACE4400005549004C +:100EF0000103EC043BFFFC84DD9E3BFFFCBCEFFCEC +:100F0000FA1949FFFDE684013C0FFADD49003C5621 +:100F1000490026CAC804490026DAD50349003C2501 +:100F2000EC043BFFFC84DD9EFC2080C14413F04AAE +:100F300080E244200055AE885A080207490000901C +:100F4000C8FE640304034403F04A441000554433CC +:100F5000F04BAE40A6185A00FF05841FAE18D5000E +:100F60004443F0DA97B0A620540000F040238004F8 +:100F70004403F0ED9690AEA0AF80A6185A00FF058E +:100F8000841FAE18D5004403F041AE404000000974 +:100F9000400000094000000940000009400000092D +:100FA000FCA0944D4423F042FE0F9600A6D0AE1054 +:100FB000DD9E4413F046AE08DD9E00004403F0C4FD +:100FC000A600DD9E4413F0C49600AE08DD9E4403E7 +:100FD000F0C3A600DD9E4413F0C39600AE08DD9E6C +:100FE0004403F0CE4413F0D0A400A6489407FE0FAB +:100FF000441DD30088015C000041DD9E4403F0CE17 +:101000004413F0D0A400A6489407FE0F441DD2B0AC +:1010100088015C000001DD9E44022D00DD9E44033A +:10102000F0CE4410045AAC404403F0D08420AE40CB +:101030004403F0C7843FAE40DD9E4413F0E6AC08A5 +:10104000DD9E4403F0F58421AE404413F04A442071 +:101050000055AE88A6405A1001FFDD9E4403F0F40F +:10106000A6009204DD9E4403F0F7A600DD9E441323 +:10107000F0F79600AE08DD9E4403F0F6A600DD9E74 +:101080004413F0F69600AE08DD9E44522D00441243 +:101090002D3E18028001D9FEDD9E3A6FA8BC4400A7 +:1010A000400064030403440000FD49FFFFF04413C3 +:1010B000F04B841FAE0844A3F0CE4480045A812133 +:1010C00080E04463F0681285000010748000A63050 +:1010D000520000014900003F440009C449FFFCA23E +:1010E000A6305200000149000036440009C449FFFF +:1010F000FC99D5E83BFFFCBCEFFC49FFFFD0920018 +:101100004423F0EC9606A6509402541080FBFE0F88 +:10111000AE10DD9E48FFFFF6C80844122CF5A60865 +:101120008C019600AE08D50F44222CF6A6508C21D7 +:101130009648AE505A0801084413F060A6085800BB +:101140000004D5064413F060A608540000FBAE0866 +:10115000DD9E4413F0689600AE08DD9E4423F053F4 +:101160009606A650541080FE88019600AE10DD9EB3 +:101170004433F0404443F00EA69884A05421001C50 +:10118000FE579648AD60AE584413F06A9606A6889E +:10119000542100FEAE88A68888029600AE08DD9E27 +:1011A0004403F061A600960FDD9E4423F06DC90351 +:1011B0008425D5028424AE509444FE0F4413F06E6F +:1011C0009600AE084413F06FAE08DD9E4403F06D48 +:1011D0008420AE40DD9E4403F061A6009203960693 +:1011E000DD9E4403F061A60092029606DD9E440354 +:1011F000F061A6009207DD9EFC0049FFFFFAC807D8 +:1012000049FFFFF15A0001068401D5048400D5028C +:101210008402FC802E00043A2E5004183BFFFCBCD4 +:10122000EFFCD00FC8064400005249FFFC52D50520 +:101230004400005149FFFC4D2E00043A3E000418C2 +:101240002E0004382E500419D00FC8064400005454 +:1012500049FFFC3FD5054400005349FFFC3A2E00EE +:1012600004383E0004192E0004392E50041AD00F01 +:10127000C8064400005649FFFC2CD5054400005523 +:1012800049FFFC272E0004393E00041A2E00179552 +:101290005A00AA08EC0484073BFFFC8448FFFC19B1 +:1012A000EC043BFFFC84DD9E48003B7E4403F04A97 +:1012B00044100055AE40DD9E3BFFFCBCEFE4F081E6 +:1012C000F1828005F101F283F384F48549FFFF5236 +:1012D000F002F10349FFFE674403F04A4410005551 +:1012E000AE40F001F104F205EC1C3BFFFC8448FF2A +:1012F000FE1D3A6FA0BC80E084C0E2C7E80C840108 +:10130000844080208062808080A28CC149FFFFD60B +:1013100097B0D5F43A6FA084DD9E48FFFE7F3BFF77 +:10132000FCBCEFFC49FFFE5EEC043BFFFC84DD9E51 +:101330002E000431C80A3BFFFCBCEFFC49FFFE90C5 +:10134000EC043BFFFC84DD9E8400DD9E48FFFF0330 +:101350002E07C66EC8143BFFFCBCEFFC2E07C54B26 +:1013600049FFFEF9FA0949FFFB432E07C54BEC0480 +:10137000520000013BFFFC8448FFFEEDDD9E48006B +:101380003DBC48003DAF44124000B62044124C60C2 +:10139000A84544120C60A84644121B90A84244126F +:1013A0004B40A844441237FC1410001144129970A9 +:1013B00014100012441220A01410001444126620CD +:1013C00014100015DD9E3A6FA4BC80C044012EA805 +:1013D000EFDC3A20140044012EB8B1C43A2F942017 +:1013E0003A201400813F3A23942049003F14C02141 +:1013F0002E17C9CB2E07E9258E21E020E80296089A +:1014000038148202442000481413000A3813820260 +:101410001413000B4412D2404210087344022900F6 +:101420001403000944022C60141300131403000C6D +:10143000EC243A6FA484DD9E842C3A6FA0BCAE41AC +:1014400084003C0FFAD2840149FFFE684463F04AED +:10145000447000553C0DFAD2C00D84208461840292 +:101460008041808380A33A6FA0843C1FFAD248FF5A +:10147000FF2549003B2D5A0801F2AFF0D5EC44138B +:10148000F01F4433F302A648542080E0A658966724 +:10149000E001E806A658966788229A0896804403D9 +:1014A000F01FAE80DD9E3BFFFCBCEFFC49003B071C +:1014B000EC0484013BFFFC8448003B06A4408C21E3 +:1014C00096495CF08190AC40E9113BFFFCBCEFFC1D +:1014D000840549FFFAFE840049002400EC0444001E +:1014E00000693BFFFC8448FFFE07DD9E3BFFFCBC20 +:1014F000A740EFFCD90C8CA19768E6A5E90284A06F +:10150000AF40440FFFAA3E07E935D511840649FFD5 +:10151000FAE044122CF0A6088C019600AE08840074 +:10152000490023DC4400005549FFFDE644022CF04D +:10153000A600C00484013E00045CEC043BFFFC8474 +:10154000DD9EA6885A28AA08A680AE888420AE40D0 +:1015500048003CB7DD9E3C0DFAAD5A0804273BFF1E +:10156000FCBCEFFC49FFFE4A5A0002142E07C5DB03 +:101570005A08011084003E07E91084003C0BF4D99E +:101580004412B36A4402B36349FFFFDD8403D50507 +:10159000FA003C0FFAAD8405EC0484203C2DFA9946 +:1015A0003BFFFC844800351EDD9EA6885A20AA0D0C +:1015B000AE80442FFFAAAE88A6005A080104480056 +:1015C0003C7948003C7EDD9E8440AE808400AC08BF +:1015D000DD9E4403F5608420AE404403F56184231E +:1015E000AE408400802080408060480038EF440393 +:1015F000F5608423AE404403F5618420AE4084004E +:10160000802080408060480038E14403F007A60055 +:101610005A08720A4403F004A6405A100C12A6009D +:101620005A000E0F44022D60441FFF9EAE408420DE +:10163000840280418461808180A148FFFE3FDD9E5D +:101640003A6FA83C44012EC8EFDC3A2014003A2F30 +:10165000942044212ED8B0043A2114003A201420BA +:101660002E27E95F38400A022E000430C834846116 +:101670003E30043095524432714044624510383156 +:1016800094004472AD7096D8385F8A0281203C1372 +:10169000E2BAE201E820944140A098008827028540 +:1016A0000000A44838220101964B8A22382280008B +:1016B0004224082440210C0E88229649121500006D +:1016C00002150000964B4E140004129500008C0188 +:1016D0009601D5DEEC243A6FA804DD9E3C23E2BAE5 +:1016E0004412451084A0D210A4080230EB408C2292 +:1016F0008A0396034E040003FE025EF00051E806E2 +:101700008CA19769D5F18400DD9E8401DD9E842142 +:10171000480042673BFFFCBCEFCC96D0FA4084A067 +:101720008481F2858442F583F584F586F287F58815 +:10173000F589B67FF481F382F48A804180A4490060 +:10174000371EEC343BFFFC84DD9E3A6F98BC44228C +:101750008F70EFD00031000FFAC00041001084A15B +:101760008440F68584C2F283F284F286F687F2889A +:10177000F289B67FF581F382F58A8041490036FF10 +:10178000EC303A6F9884DD9E84213E17E98954003D +:1017900000FB84203E100430C807440200004412BD +:1017A000451048FFFFD444020000441200024422C6 +:1017B00045102E37C54F2E47C55084A048003781AD +:1017C0003C1DFA993A6F98BCA64980C049FFFFDEDC +:1017D0005A6803092E07C66EC8053A6F988448FFF9 +:1017E000FF313A6F9884DD9E3A6F98BC44428F7007 +:1017F000EFD00062000F84A000420010F581F58256 +:10180000F583F584F586F588F58984A1B6DFF28540 +:10181000F387F58A80668041490036B1EC303A6F33 +:101820009884DD9E3BFFFCBCEFC484A0F38DFA607E +:101830008082F38584418462F281F482F387F28AA4 +:10184000B6BFF583F584F586F588F5898064804117 +:10185000F40D49003694EC3C3BFFFC84DD9E3BFFDD +:10186000FCBCEFBCF18EF08D8023F28F2E37C54F7C +:10187000C4052E47C5508003D50380048481B61F5C +:1018800084A1F0828400F083F184F085F086F088F2 +:10189000F089F08AF581F587F00DF10EF20F49001D +:1018A000366EEC443BFFFC84DD9E3A6FAABCEFFC35 +:1018B000006F802401EF8020F689026F801C00FFFA +:1018C0008028F68E006F803C008F802C00AF803027 +:1018D000009F8034F68F23CF8020227F8022006FEC +:1018E000804815EF800814FF800A148F800B14AF16 +:1018F000800C149F800D15CF8010F791F692EC04A8 +:101900003A6FAA844800363B3A6F9CBCEFD44462DD +:101910008F700073000F00630010F381B0C7F38471 +:101920008460B6DFF482F583808380A7490035B3F5 +:10193000EC2C3A6F9C84DD9E3A6FA0BC4473F42378 +:10194000A678978849FFFC49C0045413001FD505A9 +:10195000A67896678E2196482E200D012E000D1236 +:10196000400008172E27E925E642E9083C2DFA99A0 +:10197000A6915A2804048C019600400004063A6F90 +:10198000A084DD9EFE0C4420007840000817DD9EF8 +:101990003C23F47CFE0C40000817DD9E3A6F98BC97 +:1019A00044012EE8EFF83A200C003A2F8C2049FF32 +:1019B000FBF9385F81013C13F47D3C5BF47D3C1BFB +:1019C000F47CD14950007F80960049FFF8823C0D9D +:1019D000FA9C49003BA23C03F47D4410016844207A +:1019E0000078FE44401088373C1BE4D63C1C0111B3 +:1019F0003C33F47CFE4440108C373C1E01113C1CEF +:101A00000112FE4440108C373C1E01124210082483 +:101A1000401088373C1BF4D44410003CFE44401076 +:101A200088373C1BF4ED44101C20FE4440108837DE +:101A30003C1BF4693C13F4EEFE0C40000C173C0B0D +:101A4000F4EE4900645849006549EC083A6F9884FF +:101A500048001666EC083A6F9884DD9E3BFFFCBC9C +:101A6000EFF45A0801173C0DF16D3C1DF168B61FEB +:101A70003C0DF16E3C2DF169F0813C3DF16A3C0D6D +:101A8000F1673C4DF16B3C5DF16C49003825D51593 +:101A90003C0DF1653C1DF160B61F3C0DF1663C2D1F +:101AA000F161F0813C3DF1623C0DF15F3C4DF16331 +:101AB0003C5DF164490038108400802080408060E3 +:101AC0004900366AEC0C3BFFFC844800364E3BFF75 +:101AD000FCBCEFFC49008C054403F705441FFFA53F +:101AE000AE40EC048420AE403BFFFC84DD9E4423EA +:101AF000F0779606A650541080FEFE0FAE10DD9EC5 +:101B00004423F04A3BFFFCBC44300055AED0EFFC10 +:101B10004433F380A6985A2001FF4E13008DA6018E +:101B20008E01E60E4EF200D544F01A3838078101D6 +:101B300040F03C004A003C001C009601CC009200A2 +:101B4000CC0092009601280028009E009E00920082 +:101B5000CC00D800EC0484023BFFFC84480037DB57 +:101B6000840149FFFAFD840049FFFF7A2E07E9202E +:101B70002E17C9C35A0001072E07E9688E04E60232 +:101B8000E811E624E8064400088E49FFF731D5182D +:101B9000E62DE8168E22440003E8FE0C49FFF728E4 +:101BA000D50FE624E80484018424D504E62DE80852 +:101BB000840184408062808280A049FFFB7F840191 +:101BC00049FFF9F9840149FFFF94EC0484003BFFCD +:101BD000FC84480037A0840149FFFF8B840049FF43 +:101BE000FF3F2E07E9205A0801074400088E49FFED +:101BF000F6FFD5098440840184248062808280A01D +:101C000049FFFB5CEC0484003BFFFC844800389DEA +:101C10008440840180A02E17C9C38062808249FF5E +:101C2000FB4D840149FFF9C7EC0484003BFFFC84B1 +:101C3000480037715A180142A6018E03E60CE848A5 +:101C400044F01B503807800040F03C004A003C0044 +:101C5000340C340C7E18182E2E7E3440EC04840193 +:101C60003BFFFC8448003757840149FFFEF984019B +:101C7000490037514400003749FFF6BAD5128401B4 +:101C800049FFFEEEEC0484013BFFFC844800385D14 +:101C9000840149FFFEE549FFFC9E84014900373B72 +:101CA000840049FFFF26840049FFF985EC04840085 +:101CB0003BFFFC8448FFFA545A18020B8401490088 +:101CC000372AEC0484003BFFFC8448FFF974EC04E1 +:101CD0003BFFFC84DD9E92002E07E9125A08012E7C +:101CE0003A6F98BC49FFFA8AC8263C0DFAB5A6405F +:101CF0005A1801FFA6005A08011F3C0DFAAAA78036 +:101D000097B05A6801193C0DFA998429AE41842094 +:101D100049FFFEF83C0DFA99842AAE413C1DFAB504 +:101D20008400AE083C1DFAAAAE0880063A6F98847B +:101D300048001FD43A6F9884DD9E3C0DFA99A64165 +:101D40005A1006292E17E924C9253A6F98BC2E6728 +:101D5000E97ECE1E3C1DFAB5A6485A18011A3C1D54 +:101D6000FAAAA6485A18011580263C6FFADB49FFEB +:101D7000FEC93C0DFAB5AF802E07E961C8043C1DD1 +:101D8000FAAAAE0884013A6F988448001FA73A6FF8 +:101D90009884DD9E3BFFFCBCEFFC49FFFA2F5A08FC +:101DA0000207EC043BFFFC8448FFFFC93C0DFA9995 +:101DB000A6015A000B07EC043BFFFC8448FFFF8E92 +:101DC000EC043BFFFC84DD9E3C0FFAE1DD9E3C0F02 +:101DD000FAE0DD9EFC00C0085A08010B49003806F5 +:101DE0003C0FFAE3D505490037FE3C0FFAE2FC80D0 +:101DF0008020E6293C0DFAE3E82544F01D08381759 +:101E0000840040F0BC00DD0F0A3C10161C22282E76 +:101E100034003C0DFAE2DD9E50000050DD9E500083 +:101E200000A0DD9E500000F0DD9E50000140DD9ED0 +:101E3000500001E0DD9E50000280DD9E5000032036 +:101E4000DD9E8400DD9E9200FC52F18C44112DBC7D +:101E5000F48EB11580C381423A208C043A220C24BE +:101E6000F08DA6488125AE6044112DC8B1183A20E6 +:101E70008C043A220C24A64880E6AE608420121F0F +:101E800080293C2DFAE33C1DFAE24900377F3C1DD6 +:101E9000FAE0A60AA64B4900379D5CF30100E9036E +:101EA000447000FF97F98007490037A784C03C1DA4 +:101EB000FAE100008010E2C0E810800638109800B7 +:101EC000490037A83C0DFAE19846800600108008CA +:101ED000490037C88CC1D5EC8400490037924900CD +:101EE000376884014900378D490037635A980147A4 +:101EF0002E37C54284C044007FFF97FB2E47C54361 +:101F0000B67FF088501F8052F00D44226B3080A9BC +:101F1000F681F682F683F684F685F686F687F789EB +:101F2000F68A4900332C2E37C54244126B302E47B7 +:101F3000C543B67FF38280A98041F00C149F8001D5 +:101F4000F683F684F685F686149F8007F688F68970 +:101F5000149F800A490033133C1DFAE23C2DFAE33A +:101F600044026B3049003712440004B04900374541 +:101F70008402490037464900371C4900373AF10EC0 +:101F8000AE082E00040CC8092E0004085A000204F2 +:101F9000480000D7480000E787C0F00EA60040FFC9 +:101FA0000006E8F304150005400F08088801A64064 +:101FB00000800002F193A641A603F191F092F01285 +:101FC000E2084EF300B550047FFE5CF000204EF2B4 +:101FD00000A940041008F090F013F08DF10DF011FD +:101FE000E2014EF3009FF00D8E02E60C4EF20095DA +:101FF000F010F10DB46A988194119858F08FA609E9 +:1020000096064E02008AA7484C5F40878420440011 +:1020100007D0B11538420410888297219521888312 +:10202000A761E6A4E80FA7200455000338529101E8 +:10203000E005E902962B0455000238429101E6873B +:10204000E9088C215A1809E784204E060006D513AA +:1020500084214E070062F30C40F0040A38418911D4 +:102060004430007F42F20C7340F781F65EF78074D3 +:10207000E853C952F00CB15B848038600911B01587 +:102080008420383010108001886296D9B1D53893F9 +:102090008410F70C89234094801338F3A511B1D82C +:1020A000389384108C214207A4735A1809F1AA2985 +:1020B0004E670009441001F4FE0C4000181614028B +:1020C000FFFF8C815A4809DD8440B15B84DE8400C7 +:1020D00044312DD480209913383200105A38010928 +:1020E000383282025EF1FF38E8038C2196485A1894 +:1020F0000208B46AF70F8867A7D9FFF6AFD98C0139 +:102100005A0809ECB40AF10F8801A6019606C0042A +:102110008C495A2890DEF00D8C01960048FFFF5F35 +:1021200050040001548000FF48FFFF4B51EF0001B5 +:1021300048FFFF358C01F10EA648E201E9183C1D6D +:10214000FAE23C2DFAE3F00C490036208403490002 +:1021500036584900362E4900364CF10EAE08840040 +:10216000D5458400446F800084FED5E60425000335 +:102170009441382101015CF10056E8070425000173 +:102180008822A488FEB7AC880425000594428822E2 +:10219000A68800808001F28D00908003A68AE32249 +:1021A000E9CA41E11008F10DE301E917405F0400BD +:1021B000B48A976994E98864A71954F20001E80A7F +:1021C00004FF800C38F795115EF78056E803FF3E58 +:1021D000AF198C219648D5E98C419690D5E104152C +:1021E000000138508101D8078C01F10EA648E201A8 +:1021F000E9F7D52B966B4E15FFF90425000594429F +:10220000956A98D18845A6DAA712E264E802AED2B0 +:102210000425000598D18845A6DBA713E283E802D0 +:10222000AED304250005383104008845A710E264C8 +:10223000E802AED004250005882288A2A649A6A9F6 +:10224000E241E8D3AE69D5D1FCD23C0FFB42DD9E22 +:102250003C0FFB41DD9EFC41444000FC4201907379 +:102260000040001854520001CD07B4C05A60010567 +:10227000005000E0C51E4422B724840038010C0839 +:102280004422B714848138410C08A4884442B6D84B +:10229000A44938220E09949A8844AC514412B6C815 +:1022A00038008C084412B6B838008C084800018AFF +:1022B0005A6802494422B7144442B6C838610C0037 +:1022C0004402B6B85A68010938520C0838500C0854 +:1022D00038510C08D51738200C00E642E8058C412F +:1022E00038200C08D50338500C0838220C00CA0AD4 +:1022F00038200C005A2802074422B6C8848138418D +:102300000C0838200C008083840F42410073442263 +:10231000B6D822508000226080018004945A38414F +:102320000E014472B60488229B2C38438209A50909 +:10233000940288079B34AD0138510E09AD894800DD +:1023400001415A6004044800013D544200FD104020 +:1023500000184442B7144482B72438420C005A484B +:10236000010A38440C00959988864462B5C83853F0 +:10237000110938440C004E4300DD4452B6C844A253 +:10238000B60438628C004452B6B838928C005A6059 +:10239000010680E480A487CFD521955A894580C461 +:1023A00080A484E14C54C00384E222F500008CA197 +:1023B0004243BC7322F5000197684263BC7350A589 +:1023C000003C5A5803F084A440421496406314D64B +:1023D0003C4FFAE53C6FFAE4D51980C34262F873CA +:1023E00038F51A1195B288CA8CA12263000197684A +:1023F000888FE32588E6E8F28D21404224964073D9 +:10240000A4F63C4FFAE53C7FFAE44462B5C840A12B +:102410008808405328003C9DFAE5848038430E0923 +:10242000AD2980A94E940004525480003C7DFAE40A +:1024300083C74E74000453E380003C4DFB4240F2DE +:10244000F800A1219281E28F004000F3F481E904B9 +:102450008E8BE682E86E4E9700094442B6D838F279 +:102460000E1152F7843FD5074E92000E4442B6D863 +:1024700038F20E114440006442479024405214B692 +:102480009769D5034450FFFF4E77000A4442B6D8FF +:10249000888A22F2000152F7896BD507C70E4442A1 +:1024A000B6D8888A22F20001444000644247902452 +:1024B000404278969721D5034440FFFF04FF8001F6 +:1024C00050F7FFF55CF78002E81C4E920003CF76D0 +:1024D0004452B6D82270800038428E11229080017A +:1024E0009B3C3C4FFAE54042A80038728E0922120C +:1024F000000112920001401484013C1FFAE4D55EF1 +:10250000E2A44042BC1B5CF20096E8058C8A38438A +:102510000E09D50F5CF2012CE808928138430E09B0 +:1025200088CA8C8AAD31D5054410009638130E093F +:10253000001000F3E622E9035A1806084412D558A1 +:1025400038108C00C935D50A38440C0094598824B9 +:102550004452B5C838728501CF058421101000DEC1 +:10256000D527E6824452B6D8959AE8163C4DFAE54E +:1025700038128E01FF3C44900064404224968881CA +:1025800038428E093C1DFAE4992EFE7CA5E14010EC +:10259000A4368827AC610010001858108002101073 +:1025A000001838028E0188A6AC10A429AC1138049A +:1025B0000C008C0138040C08D504444000C7D5AE8B +:1025C000FCC13C0FFC44DD9E3C0FFC43DD9E8400BF +:1025D0003E07F108DD9E5A00016AFC202E57F108E3 +:1025E000D02F4430004480E242708C735061003F31 +:1025F00084804C4000264C12001F2033803F20F383 +:1026000000008A6F4E340003FEDA8E62E662E81341 +:1026100020F37FFF2033803E8A6F8C61E663E80BF6 +:102620009EF30253801EA4D8E2A3E80584011003A0 +:10263000803AD5388C81972050630044D5DB4430F4 +:102640000044808242408C738460D5058C6196D8AA +:10265000502100444C3000294C11BFFAB4A25CF266 +:10266000A711E9F500510043006200428CA1E0A6E9 +:10267000E9EE00520043006100428CA1E0A6E9E7C8 +:1026800000510041006200408CA1E0A6E9E0005248 +:102690000041006100408CA1E0A6E9D9840210024B +:1026A000003A8401D5058400D5038400DD9EFCA09A +:1026B000FC42A10D94D28864F1830081800000A1C6 +:1026C0008001A65A40552001F1818CA1A65BE4A3AC +:1026D000F1824EF200B684603C4DFC4305CF800190 +:1026E000812380E380C3F102E03CE9304E82001593 +:1026F00000F2000283C843EE3C7340FF040839E057 +:1027000079114FE70003893E40F03C0022F7FFFFBC +:102710004EF70003886F01E2000250FF7FFFE14F98 +:10272000E812802A421E787339E0051140F08408CF +:102730004FE7000388DE40F03C0022F780014EF7AF +:10274000000388EF51CE0001D5CF5A5001075A58E7 +:10275000022F2EF00467E82B878A43E1F02440FF24 +:102760002407E80E42F3F02440F79807E8094E8268 +:10277000000800F2000250F7FFFFE14FE9635A58EA +:102780000117F502F1018AA1E4A5E8042E500467BF +:10279000C50E40FF2407E9034E83000A84AAFF7C8C +:1027A000E0A6E950A7628EA14CA2804D2E5004678E +:1027B000C50884AAFEECE069E945FFECE0E6E942E1 +:1027C000F103949100A20003A04C88418420A751FA +:1027D00080E181218441E04AE823A7A2810542816A +:1027E000187340340408388021114E840004528448 +:1027F00000008928C50A40800C0022847FFF4E8497 +:1028000000045284000088E88EC1D6088860223116 +:1028100080014E340003FEDA88238C41D5DD5EF45E +:1028200087D1E90B5EF38064E902CD075EF0806436 +:10283000E909A6228E01D00684003E0004678401C7 +:10284000D5028400FCC2FC40A14D94D288A3A04CC8 +:102850009491A6E88841A7A9A72AA691A76BC304CB +:102860009E599648D50280239491884080E48460E4 +:10287000E2A7E909409394088CE138912401886922 +:1028800096DBD5F74092100844700064E2C1E92F4E +:1028900054208001CA2A5A1007294080A40040848D +:1028A0000408890083848142E2BCE90F02F400003D +:1028B00051CE0001894F02F4000140A50011884F5C +:1028C000969350840020D5F1E628E805E142E80D12 +:1028D0008A4AD505E04AE80940250801FEBC40F1D6 +:1028E0000DF65EF78033E8058C21D5D18401D50241 +:1028F0008400FCC0FC4051FFF728F1858540501F43 +:1029000084DCF382F284F48CF18180E080C1810A5E +:102910008461F005E340F086E851F1022203800073 +:10292000224380011203000A1203000CA04BA039BD +:102930001243000B1243000D1033003B1083003A8A +:10294000381081011403000B1213001EF102409095 +:102950000408F486A08D94428822500300408444E9 +:10296000F3834900829BF0028442A00489208029DD +:102970005003003E4900829200548001F303F406A4 +:10298000C50C3C1DFC43A60A8E01D00700548000F4 +:10299000C504A60B8E01D80410330035D50310836F +:1029A00000355EF2091C800340043C1B1003003616 +:1029B0008D41506300448CE8D5AD2E87F10884002A +:1029C000148F800350AF80688020509F80A4B1F89E +:1029D000506F811C445000444432B73CF401422003 +:1029E0001424888288433815020A3814820A38135E +:1029F000820A3813020A8C011012002A1011002AD0 +:102A00005A080FEE4402B7BE844084C3E248E8305F +:102A100000107FB88C415A18012980828020E288FA +:102A2000E82400507FBDE6A8E807A6C99DEA4C71DE +:102A3000800B8CA3D5075A500815A6C99DDAD70379 +:102A40008C63DB0F20F0800020307FBC8A6F8C61AC +:102A5000E663E8070030FFFDCB0410607FB8D505C2 +:102A60008C8150108044D5DC50000044D5D0440007 +:102A7000003C42040024F08F8400F089460000F3FB +:102A800050000A703C2DFC4451EF8158049F800196 +:102A9000F091F009F105E2014EF20104F309B01AD8 +:102AA000842138100E0A85404402B73CF10F4CA037 +:102AB00080F0F1052234800CE228E8092210000E93 +:102AC0002240000F8A612214800DD5082210000CCC +:102AD0002240000D8A612214800D8A24FE4C42118E +:102AE0008C73F1872214800C2264800DF18BF30B20 +:102AF0002210000C2240000D9A59F188F3089B34F3 +:102B0000045000094212102442118C73F58AB460FB +:102B10005A580408005000285A580104480005AFCC +:102B20000450000CCD71A151E2254EF30588A5514A +:102B3000FF5CE225E82CA152E225E80AA144A1832A +:102B4000F708FF64425398734E560579D520C31F8A +:102B5000A153E225E81CA184A143F708FFA4426326 +:102B6000947344500064FF7440528CB7FF6CFF5C58 +:102B70004470271040F29DF7007100274450006414 +:102B8000FFCC407394F7E2EF4EF305570050002955 +:102B9000A790E2C5E805A194E2264EF30550C322B2 +:102BA000E6A2E920F511E2A1E91DA144A183FF2CD1 +:102BB000F5084242987344500064FF6440528CB759 +:102BC000FF6CFEEC4450271040F195F700510027B0 +:102BD00044300064FF4C40528CB7E2AFE8034E46ED +:102BE000052E003100264E32054AA0D3E2234EF2D4 +:102BF0000546F10A5A18040448000541F107463910 +:102C000000004800053A5A5002065A500404480091 +:102C10000536F30A5A380404480005312230000E04 +:102C200085E6F38D2230000FA1C3F38E846AFE5C2B +:102C3000F190A051A14442F78424F110E22F4EF309 +:102C400004FE0011002842F38424FE6C40F78DF648 +:102C500040108C36F30EF18A88659AF3F60DF10B6D +:102C600088C78A26FEDC42308473F10AFE4C421784 +:102C7000BC73E0614EF20503F108FF2C42409C73E7 +:102C80004E4704FDF10746380000480004F6F009FD +:102C900051EF00048C01F0895094804448FFFEFB02 +:102CA0008400B0E98421E208E8053811820A8C0129 +:102CB000D5FBF005E60BE80BE70BE8098028B09A96 +:102CC000504F8158B15249000525D509F00580289B +:102CD000B09A504F8158B152490004D3F0883C0D4E +:102CE000FC448500F0874605FFFF50000FFEF08D85 +:102CF0004608FFFF50000FFF81484412B73C45E2F1 +:102D0000D558F08EF008E3404EF201CCB092400569 +:102D1000040888028061A601442000444230087300 +:102D20000421800C5A280214B092846F38212900A3 +:102D300042200C73503F815838218A024E250008EA +:102D4000B0A984613831020A480001A94430004426 +:102D5000B092808142400C7338212900F602005263 +:102D60000037504F84DC42410C738064A1B3503172 +:102D70008028F689F70950420030A199AF6738637F +:102D80009901F70702738015E2E6E808CD07A75A14 +:102D900058528001AF5A8461AEE744400044503F2E +:102DA00084DC81214231107342901073506180188D +:102DB0002251800C2244800CF58A9B2C2253000166 +:102DC000F58BF70B2254800D9B7D42F2942442F246 +:102DD000107380EF81E3A95C1C778002F70A144727 +:102DE000800188E4ADF2F70B88A7AD7384AF80C291 +:102DF00042601473505F8158F70D38529A0246664C +:102E0000000088C5E2E6E855F60EE2C5E852005437 +:102E1000803F50318038E6A8A6DFE806E668E8354E +:102E20004E440034D505E668E9304E47002F444053 +:102E3000004480614230107300618020445000FCE7 +:102E4000F70442731473005380FAC514505F84DC96 +:102E500042511073808500528034CD170251801E7C +:102E60000242001E44300064FF5CFA6EFEE4E0A300 +:102E7000E80C44300044504F88D842410C738064C1 +:102E800084841441FF0DD51844400044503F84DC35 +:102E90004231107384A21451800C80A142501073EF +:102EA00080858C908C70A562A523AD5AAD1BD5048E +:102EB00084801441800C44400044503F84DC80C135 +:102EC00042311073426010738086507180108CD034 +:102ED0002253800222930002226300038AA9A95987 +:102EE000225380038AA6A95A0052002050618020F4 +:102EF00010518020043200095A38037A383F1400F8 +:102F00005A38010A003200288C6A10320028846284 +:102F1000383F14084432D558383194005A38030EDB +:102F200044300044808142400C73806484811041AD +:102F30008028FA60383F1408383F14005A38040ECD +:102F400044300044808142400C738064848110418D +:102F50008028FA70383F1408383F14005A38022687 +:102F600044300044504F88D842450C73F60904425F +:102F70007F0C38631101848AFFA4808142400C7366 +:102F80002272001C80648487FF3CE0C4E8078481CF +:102F90001041802844300030D506003180285A384E +:102FA00001058465383F140844300044504F84DCE8 +:102FB00042410C73FEC48861005200370031802802 +:102FC0005A5801038E611032002844300044504F9B +:102FD00084DC42410C738064004200285031802020 +:102FE000CC038481D5028483A919D50684603E3040 +:102FF00004678462A8F14440004480614230107349 +:10300000003180345CF180C8E8038C6196D8505F51 +:1030100084DC42511073103280344432B73C423069 +:103020001073B4C55042802800318029F507AEE105 +:10303000A16DE2A6E805E66AE80A8C61D507F50706 +:10304000A16EE2C5E804C3038E61AEE144500044C2 +:10305000503F84DCF40242311473A1230461800BDD +:103060008D013842190180C1426014732203001C93 +:10307000E00440403C1A1241801C00418020503F37 +:10308000811C84013801920AB0F838018A0AF006DE +:103090008E01F086F0038E01F0838D4148FFFE34EF +:1030A0008400509F80A44462B73CF08750AF80E01A +:1030B0002E07F108F107E220E803F003C806049F99 +:1030C000800184E0480000C23C3DFC4300018009CF +:1030D000E300E8F60C0480015A0001044800009F58 +:1030E000040300095A08031300230020441000FCC5 +:1030F000F40442410473001200FBC908F0031414E5 +:10310000FFFF8E01F0834800008A9E41E622E80717 +:103110000403000C5A08023A8400D53E5A08033AC8 +:1031200000430020440000FCF104421200732220FE +:10313000807380012253001C842AFE8C8427FE6C3D +:10314000E041E80D001000FBC10A00130037C10781 +:10315000001000F2C1040013003AC11184201013C2 +:10316000002884201414FFFFF103000000F28E21D8 +:10317000F183C81484013E000467D5104402D55879 +:1031800044100040381010083C0DFC44A601D50442 +:10319000000300288E0110030028000300285A08AD +:1031A00001080013002A581080041013002A00118F +:1031B000801984E0B09AE2E1E80938351E02CB04B8 +:1031C00038311E02C3058CE1D5F784E0D525C00354 +:1031D0008404D50284054420004414030009500FE0 +:1031E00084DC42038873802649007E580023002037 +:1031F000501F811C840138008A0A38051E0A840089 +:103200001404FFFFF0038D018E01F083D5073825EC +:103210001E02C2DE8CE14C70FFFCF00750630044DC +:103220008C01F08748FFFF46F0064E02010D0013A7 +:103230000009E3014EF20108B01A38001E025A00DC +:10324000010C8CE150948044F0053C6DFC43E2E0BD +:10325000E9EC480000F9B03838601E02CEF3500F98 +:10326000811C38001A024E0300E98029B609A8091A +:10327000A80AA80BA80C0204800C10648020120479 +:10328000800E0204800DF1041204800F3C0DFC44FA +:1032900088080000001C10048028440000FC421331 +:1032A000007380018421101000FB2E000411C00A5D +:1032B00049FFEFA45A080207000480288C0110047B +:1032C00080280434800B00148020440000FC04AFEC +:1032D000800442A0807380433C0C0278F102F383A7 +:1032E00049FFFAB3100500FA1004803BF303C80746 +:1032F00000048028C804840110048028840010057C +:1033000000F1F1028043F00C49FFF9D40014802051 +:10331000100500F2F204440000FC4220807300011A +:1033200000F2C80700048028C80484011004802823 +:10333000F0059678502F84DC49FFF94F81405A08F8 +:10334000010B49FFEF5B5A08020700048028C803FD +:1033500010A48028F00200148028A0C30404800B6D +:10336000C9153C2DFC443811810102210015E241B0 +:10337000E80800148036C905842114148009D51486 +:103380008423141480098421D50D3C4DFC448443CE +:10339000142480090242001538218101E282E904E7 +:1033A0008C2110148028004480364412D558002403 +:1033B00080205A4801052E57E91DC50284803840F7 +:1033C0008808381181013C3DFC4402318015E261DE +:1033D0008421E90284204432D5C41014803784202B +:1033E00038118808F404443000FC42410C73F302A5 +:1033F000101200F010148034101480290014802A58 +:103400008441A0DBFE571014802A380181018420FA +:103410001204801C500F811C1414800C38201A0ACE +:10342000B038890238201E0AB01A38101E0AF00679 +:103430008E01F08648FFFF078CC1E2C14EF3FF11F9 +:1034400048FFFF018400F104804000330009E203DB +:10345000E808B641102080E08C01501080FCD5F6C1 +:1034600084003E0004113E07F108447000C8854006 +:10347000509F80E000030019E3404EF200D738046B +:10348000AA025A000104480000CAF00104400009E1 +:103490005A4005222E87F108442000444402B73CDC +:1034A00042040873F101F48349007CF8F001F2044E +:1034B0008D0100100020440000FC422080730001B8 +:1034C00000F03E87F1085CF000C8F403E8048C01CA +:1034D000100100F0F001048F80040010002044006F +:1034E00000FC42808073F0015014001CB68800007C +:1034F000002A10040018F0010200000A1204000261 +:10350000F0010200000B12040003F0010200000CA5 +:1035100012040004F0010200000D12040005F00185 +:103520000420000BB400B641A80AF001A001A80BCA +:10353000F001A002A80CF0010400000C1404000C1F +:103540005A480311000400F2C80D001400F1840170 +:10355000C907100400F1F102F00C49FFF8AB1004A8 +:1035600000F2F001048F800400100020440000FCF1 +:1035700042808073B4885A400416F001F202F4834A +:103580000400000BA093944138010101120400745F +:10359000F002A084500400668822844249007C7EA8 +:1035A000F4033C0DFA9CB40092029606C0034470EA +:1035B00001902204002E22F400028A0F4E04000320 +:1035C000FE02E0E0E90B2204002F22F400038A0F40 +:1035D0004E040003FE02E0E0E80A000400DE5A08A0 +:1035E00002075A48020584013E000409F001B400B4 +:1035F0005CF02711E9085A4802072E0004118C01DB +:103600003E000411F0010000002A9606C8070004DD +:1036100000FAC8048401100400FAF0018D41500042 +:103620000044F08148FFFF282E07F1083E07E95DBE +:1036300051FF88D8FCC04E67FAABF10A5A18031440 +:1036400000100034C9100010003A5A180309F1059F +:103650004C140006F107463A0000D50EF10746313A +:103660000000D50AF107381F280A5000004450A571 +:10367000003C48FFFA1D8823D5F7843FD5F5FC436D +:10368000F08181008400F484F182F58580E18380FB +:10369000812084814E82003DC73B5A48013A84A074 +:1036A0008085855EF101D122386116025A68011DBC +:1036B000F10495AA88C1F68384C0F1024C6080159C +:1036C00039E19A025BE8010F4410003C42F3042404 +:1036D000F1033810BC02E22AE80583868125809E2A +:1036E00081418CC1D5EB8CA1D5DEC4D5F1059541C6 +:1036F00088A18C0184201092800011C28001960064 +:103700003811260A8F013811F20A8EE1D5C4FCC3A4 +:10371000C06EC16FFC4051FFFB90E220E82F80E1BA +:1037200044A0003C851F81244293A87384C0388440 +:103730009A0A8CC14C607FFD8CE14C707FF680C092 +:1037400083818001802681248105F28181434900A3 +:1037500028F0B03B490028F48009490028FBB0025A +:1037600049002902840F490029094900290C844095 +:1037700080A245E0003C8082D514E201E8E184E0CB +:1037800044A0003C851F81244293A87380C03884E4 +:103790009A0A8CC14C60FFFD8CE14C70FFF6D5D0CD +:1037A000840F81E94212802442F2F87384E098F990 +:1037B000B00238300C005A38011138379E025A379F +:1037C000FF0D94D188688C41AFD8AF59F301969022 +:1037D00038419E0A3845160A8CE14C737FEA8CA169 +:1037E0004C5E7FE0800251FF8470FCC08040D502B7 +:1037F00080418002DD9E3C0FFC76DD9E3C0FFC7517 +:10380000DD9E4402BBC084213C0FFC5084003E0777 +:10381000F1443E07F1453E07F1463E07F1473E07BA +:10382000F1483E07F1493E07F14A3E07F1193E07CC +:10383000F1183E07F11A3C1FFA1E3E07EAE7441250 +:10384000BB7C8400845F382080088C015A0841FDCD +:10385000DD9EFC0049FFED63FC80FC0080C049FF59 +:10386000ED60C00784013E07E8D48400AE34AE3575 +:10387000FC802E07F120DD9E4432BB48AE18AE59C5 +:10388000AE9ADD9E3C0FFA1EDD9E3C0DFA1EDD9EBB +:103890003C0DFAB9465FF00F50528F00FF464600CC +:1038A0001000D80684003E07EAE78401DD9E84000C +:1038B000DD9E2E17F1462E57F1473C0DFC764C123B +:1038C000C0102E27F1445A28010CA6059D4940023C +:1038D00080B697683E57F1463E57F147DD9EA605F4 +:1038E0008CA1400280B697683E57F147D904840105 +:1038F0003E07F144DD9E2E57F1462E17F147D904BD +:103900002E07F144C0103C0DFC768CA1A6054002A8 +:1039100080B697683E57F1464C12C00584003E07BA +:10392000F1448401DD9E2E57F1462E07F147D80859 +:103930002E07F14484208E0140008006DD9E840124 +:10394000DD9E2E57F1462E07F147D8072E17F1447A +:10395000840040000406DD9E8401DD9EFC0084A0FE +:103960008C81E2A4E8073860080438608C0C8CA1D4 +:10397000D5F9FC8080603C0DFA1E9E41E622E825C8 +:103980003C2DFC7584200041000AE224E809A1597D +:10399000385287025A58010384028C21D5F7FC0063 +:1039A000842000410009445000FCE224E80DB443A7 +:1039B00042209473B4429F91E6C2E9055A20040460 +:1039C0008C21D5F48401FC80DD9EFC42F181B5415F +:1039D000843F101F800F2E17C5D88120C1082E17D5 +:1039E000F120C90549FFFFC83C0FFA1E3C3DFA1EF5 +:1039F0005A300104480001113C1DFC753DEDFC7678 +:103A0000B67F84C0B45F004080098E419690E24446 +:103A1000841F4EF200FD440000FCB489FE1499603E +:103A2000B50550F47FFF5CF78002E9055A80040475 +:103A3000480000E800F28056E92A004280DE5A4839 +:103A400001304442CFC438420800E6944EF200DA16 +:103A50004452CFC48C8138428808B4898880B4A489 +:103A60005A500404480000CE4452CFB8382288008F +:103A70004E2300C822520073024200748443FEA405 +:103A8000956A9693E0A2E90C480000BC5AF8020936 +:103A90000222806B8880ACAE0222006CACA7002FA3 +:103AA0000000B4A9C2099928022080092242000618 +:103AB0008E418A44D50498A822210006004F0001B7 +:103AC000C40988A00240800A225280078E818A851C +:103AD000D50488A022428007005F0003C530025051 +:103AE000800900FF00028EA1E9120280800250745A +:103AF0007FFF850240F2A1F642F11C7340279456E5 +:103B00000250800A02F080038EA1D511028080034A +:103B100050747FFF850240F2A1F642F11C734027EA +:103B200094560250800A02F080028EA150F7FFFFE7 +:103B30004082A11642823C7340441496A54AE04557 +:103B4000E9029EA94E2400038440A54BE085E902CA +:103B50009F294E440003848084E680AA42531C734C +:103B6000B4FF40F2100A40838C085884000210828F +:103B70008000007F00024081100ACF0A949484F0F4 +:103B80001082800110F28002971FFEBED509952495 +:103B900084F010F2800110828002969FFF3EFEA703 +:103BA000B489AEAB88800222000AC2039690D50287 +:103BB000844180AA84E642531C73AEAC0222000BFF +:103BC000C2039690D5028441AEAD845F1025003CBF +:103BD0001025003D0020800CE642E911B4498840E0 +:103BE00000210035CA0284414045180010220046D9 +:103BF000B4498802200000361002006E8CC197B0D4 +:103C0000B41F8C019600B61F48FFFEFE1005003E53 +:103C10001005003FD51C2E67F118C6192E07F119A3 +:103C200000150000E61EE80594039657FE0FD50325 +:103C3000440000F0100500002E07F11A1065000185 +:103C40001005000284013E07F12084C02E07F120F8 +:103C50005A00FF0DC00BCE0A841F3E07F1203C0D19 +:103C6000FC478C013C0FFC47D5033E67F1205A38D6 +:103C700001173C0DFC7500400009E2C4E810F0019A +:103C80008426FE74B4408A868406FF0496488822FF +:103C9000500F800F84408E8149FFFE62F001B420F6 +:103CA000840080A150208040083280018803960063 +:103CB000DAFCFE02100080408401C60284003E0748 +:103CC000F14AFCC2FC20844180624440004080E014 +:103CD00080C149FFFE453C0DFC750000000CE6026A +:103CE000E91050538046501300465073805008022C +:103CF0008001180080012002802710008027DFF853 +:103D0000FCA0A60092038C1596275C000014DD9E93 +:103D1000FC4080C1A640844081203E27F149C1314A +:103D20002E07F1455A08010C2E17F1483E27F144A1 +:103D30003E17F1463E17F1473E07F14949FFFDBBEB +:103D40003C0DFC762E77F1473C1DFC50A7048441C6 +:103D5000040480014213907380628E8149FFFE004B +:103D60002E07F14A5A0801063E07F1453E77F14811 +:103D70002E07F1145A00FF088C013E07F114D503F9 +:103D80003E17F1142E17F149B4065A180132A60550 +:103D9000C81849FFEACFC80F3C0DFC76B4262E3771 +:103DA000F148A6843C0DFC5042018873B42149FFC0 +:103DB000FF8BD50A49FFEA7C49FFEABCC8FED5ED76 +:103DC00049FFEAB8C80349FFEAC5B42684003E07A4 +:103DD000F1493E07F1458401AE0DB426AE0CB4C6E0 +:103DE000B40649FFFF905A080141AE37D53EA644BC +:103DF000C90549FFFDA8C039D50DA6055A08010817 +:103E000049FFEA98C83249FFEAA5D52F49FFFD8D41 +:103E1000C8F849FFEA8F80E0C82849FFFD6E3C0DD5 +:103E2000FC76B4262E97F146A6843C0DFC50B421B6 +:103E30004204887349FFFF482E17F1455A180111B3 +:103E40002E57F1484C54C00DB4063E77F145AE45AF +:103E5000B4E6B40749FFFF575A080103AE3F49FFD4 +:103E6000EA79B4068421AE44FCC0FC20804080E1A5 +:103E70004402BB64A0514462BB7CB6202E17F120E3 +:103E80003C6FFC4C10100008A052A8414412BB60CB +:103E900049FFFD9D4402BB582E17F120A981AE4079 +:103EA000B4273C1FFC494412BB5449FFFF33440272 +:103EB000BB488420AE40AE41AE4249FFFD44FCA069 +:103EC0003C0FFF9DDD9E3C0FFF9CDD9EFC41F5817C +:103ED0004082801141C2C00A445000FC42019473E8 +:103EE000005000182260800054A28001221080013E +:103EF0004EA2000D4472C7B884A038538C08447297 +:103F0000C7A838538C084800007301E000E15BE863 +:103F1000030B4452C7B838A28C084452C7A838A231 +:103F20008C08D5654FE300214472C7B88523385308 +:103F30008C00814542A1A473409508088CA144A23D +:103F4000C6F4892A9768E6A31264800012148001DF +:103F500038538C08E94C4452C7A8852138928C0804 +:103F600039E38C08D5445BE801434492C7B884E345 +:103F700038548C0081E542F19C7340F78808447204 +:103F8000C6F440F79C008CA1976812678000121756 +:103F90008001E6A338548C084452C7A8E90539E2E9 +:103FA0008C0838A48C0838528C00CD0538548C000D +:103FB000C51ED50284A3842C42718473846080233F +:103FC00080C3549180FFE325E80E4091880889273B +:103FD00038A38E010294800188CA882997B3964B32 +:103FE0008C61D5F0406314D640109436003F802891 +:103FF0005A380128B4005A0801253C5DFF9DA42DC4 +:10400000E280E81F403320014E340003FEDA400016 +:10401000F0014E040003FE028803A4EEE003E81161 +:10402000A4EF9F1940018409421270734262207309 +:1040300088C0880140630CD640100C3697B3964B6D +:10404000AD90AC51FCC1FC403DCDFF9D2E700439BC +:10405000005E0016006E0017CF0540A28013977116 +:10406000D504445000508145446000FC42019873DF +:10407000B50084DD40F418024492C6E44462C6D41C +:104080004472C2245AF00105000000E0C018840008 +:1040900038048C08840138030C08FAC4FF9C220001 +:1040A00080004442C21438039A0995B2221080015C +:1040B00088C738A20C08AC714800009138030C0086 +:1040C000E614E8048C0138030C0838048C004462C0 +:1040D000C6E4E613E9038400D5028C0138030C081A +:1040E00038948C00FAC4FF9C02F0800040049800D1 +:1040F000A44938F3820994028807AC41021E000DDE +:10410000E081E90380AAD51003CE000C40FE100721 +:10411000E80B8B4540027001420500244040F0014D +:104120004040109688A444A2C2145A88040438550A +:104130000C0038450C0084038024421280738C22CA +:10414000840440008016E0804482C214E8058C811B +:10415000E08040023C1B38040C084402C6D43845B9 +:104160000C0038100C00840AFE44E08140123C1B15 +:10417000854040008016806A808A4CA0001340541D +:10418000980038839611956A88A788882252800102 +:1041900088654E9200048F21D502FB238D41D5EE18 +:1041A00084AA4202142442419424403094B6C50C9F +:1041B00088C938339A1195B288C742028C7322336A +:1041C000000142428C734030840A880388644000B6 +:1041D0000416401184369603964BAC10AC51FCC0CB +:1041E000FC41445000FC420194734472C1D8B4A015 +:1041F0002280800023C080014462C19C38138E025B +:10420000853D40949402F18144A2C16038130E02AE +:104210003C5DFF9D5A900105000000E0C00A0202CB +:10422000800F38838E0A39C30E0A38050E0AD5412D +:1042300003E2801140FF1007E9040202800ED5114D +:10424000029280120202800FE089E80B02F2800ED7 +:104250008A9E8A0FFF044004F80140020016880F6E +:1042600038450E0285234240247380040252801098 +:1042700084848C024000101640928001964B4214B8 +:10428000842440428409421070738824401094367C +:1042900038130E0A221F800238050E0A42148424A5 +:1042A0004210207381218924405494B638538E0AD9 +:1042B00038038E02AC1038030E02AC11FCC1222070 +:1042C0000000E022E8153C4DFF9C023200098E619F +:1042D0008A61E043E80D22200001E022E8090202A1 +:1042E000000A8E018A01E04056078001DD9E8401AC +:1042F000DD9EFC0194928822F0812230800096039A +:10430000E060E8045231843F96DB2200800122FF06 +:104310008003E00FE8045200096B9603E06040015F +:10432000BC1BFC81FC0196435EF082219010E904E5 +:1043300052108440964B5EF004B7E9045200096CB9 +:104340009603E0204000BC1BFC81442000FC42009E +:104350008873B4205A1802058420101000F7DD9EDF +:10436000FC41F60BF081440000FC42230073000185 +:1043700000188122960EC85DB4028E01E602E8594B +:104380003C83F44050047FFF960042732024C00B0E +:104390009887945288238E010410FFFF96003811ED +:1043A0008A0AD5F6400408080474803BFE3438714C +:1043B000800A01C480F35BC0093D5CF289C4E8391E +:1043C000F0018144B67F49FFFFAF5EF00065E80A67 +:1043D00022FF80035EF78909E92C540E00FD5A0084 +:1043E0000C29840A421380244603FFFF9CB150002D +:1043F0000FFF42012073B45F380102028447FE14AC +:10440000E220E8174FC3000B3C0DFA9CB400920663 +:104410009606C80444003840D50344000E10380501 +:104420001A0AF00A8426381018088409100480F348 +:10443000FCC1442000FC42008873B4604422BD7477 +:104440005A38051D003000F75A3801114400006445 +:10445000380105092E07F340E603E9043E30046BFA +:10446000D50D8C013E07F340D50984003E07F3408B +:104470003E00046B84003801050938010501C00CB9 +:104480008E014422BD74960138010509C8053E0716 +:10449000F3403E00046BDD9E444000FC42019073FB +:1044A000000000F35A0006045A08090A8823A608E7 +:1044B000C0048E01AE08DD9E38010E0ADD9EFC218F +:1044C000F381F3093C73F4418843A710E287E823A2 +:1044D0008C81AF10444000FC4201907394DA998BB8 +:1044E0003C13F47B8480FE4C104000F3B626A650AB +:1044F0004C13C0128421101000F3F008B04188035F +:10450000844480E5490074CA3C03F479FE04B6068D +:104510008400B607FCA1FC01956A8885F0812222FF +:1045200000009603E040E8045221043F96932202E3 +:10453000000122FF8003E00FE8045200096B96039C +:104540008825E04040013C1BB44142300024E26237 +:10455000E80DE406E9048E05FE04B6013C03F47997 +:10456000B441FE04E240E802B601FC81443000FCA4 +:1045700042010C73003000F5CB090430003B5EF1C2 +:104580009771E9048461103000F5003000F55A3865 +:10459000011394D28861B4835CF20E10E8044440A5 +:1045A0000E10B683000000F35A0801063C03F479AC +:1045B000FE04B6033C0DFA9CB400920296065A081B +:1045C00001122E0004575A0001052E000465C00A8E +:1045D00094928822B4015CF007E9E804440007E9FA +:1045E000B601DD9E2E30046B5A38011794D2882311 +:1045F000B4615CF1A710E80444302710B661443080 +:1046000000FC42010C73000000F35A0801063C0351 +:10461000F479FE04B601DD9EFC01F081F007444010 +:1046200000FC42101073004080F9CC1D225080061F +:10463000C50E3C6DFF9C024300098E81D4082250B8 +:104640008007C5050243000A8E81DC0D848210407C +:1046500080F9848638418008443019003831020AD4 +:10466000104080F3FC810000FC41F70AF481953A88 +:1046700040A11000B44AE241E845441000FC420366 +:10468000847380C0000000F3E602E805000300DE4A +:104690005A000139840F100300F8B041982C84446B +:1046A0008123490073FB8400B60A2E000439C0023E +:1046B0008409B60A840038049C08000300F3E60E5F +:1046C000E82144F045D03807800040F03C00DD0F81 +:1046D0000E1232321A321E3232163222322684033F +:1046E000D50C8402D50A840AD5088405D50684072A +:1046F000D504840CD502840E100300F3840110034A +:1047000000F6FCC1442000FC42008873001000F653 +:104710005A1803058428101000F3DD9EFC003C139A +:10472000F47D840F49FFE9303C0BF4413C13F47DE8 +:10473000840449FFE9293C0BF440FC8080413C5350 +:10474000F47C3C13F47DD108FC009982A63049FF2B +:10475000E921AE30FC80DD9EFC0196CB9683903043 +:1047600090108A018A43FE0442010873FC81FC41D7 +:10477000810084003E00046A49FFE5405A08024275 +:10478000812884C04421869F000480F75A000109D3 +:104790008CC197B0509480FC5A680AF8D52704045D +:1047A00080165A0801F7814884E05034800C0005D7 +:1047B00000F75A08011505C500165BC801114C63C6 +:1047C000800FB40304150003F281B67F49FFFFC6D2 +:1047D000F201B47FE240E9033FC0046A8CE197F83C +:1047E00050A500FC5A780AE5D5D42E00046A5A0870 +:1047F000010544000053D503440000A73C0FF245D7 +:10480000FCC1FC43F085000F803CF184E603F2819B +:10481000810305CF800E049F8010E90B2E17E970ED +:10482000C90DE606E80B44A0007884EF84C8D50AD9 +:1048300044A0007884E384C5D50544A0003CFAEE8A +:10484000FAC03C0DFA9CB400920296065A08010D7B +:104850002E0004575A0001052E000465C00544A02F +:10486000003CFAE4FAC92E000439C00544A0003C1B +:10487000FAEEFAC0F004F105F583F48249FFFF6E09 +:104880005CF009C4E841F402FFB4E286F503E839BC +:1048900041CE2400000E0000E340E82540148808C3 +:1048A0003822A60188A1F105A42940004008FE177E +:1048B00049FFFF54E206E815F00549FFFD355EF0BB +:1048C0000065E90F440000FC04AF800142A480733E +:1048D00042139C2484043814260A100500F3D514CE +:1048E0008400D50CC808400488088805B045844475 +:1048F000490072D4000E00008C01100E0000D50497 +:104900008400380E2408FCC3FC4199DCF081A638F1 +:10491000E615E9374402BD34814138001202F10145 +:1049200080C4812249FFFF1A5CF00384E82644001A +:1049300000FC3C33F44042A30073840042130C2477 +:104940008080E283E80E98A10455003B38248A0257 +:104950008A454E240003FE928C8188029720D5F26E +:104960008E6140F00DF75CF781918401E8028400CC +:104970003E0004578400D51284003E000457D50E33 +:10498000C80C4412BD34022F8002382092099522AF +:104990008881021F8003AC618C01AE383C0DFA9C0B +:1049A000B40092029606C8033E000457FCC1FC41C5 +:1049B00080E281218045802480C5F081810381448B +:1049C00049FFFC99441000FC42730473001380F803 +:1049D0005A180F26381419018C2FE201E8048400BC +:1049E000100380F4000380F45A08011A95B2892656 +:1049F000F001022480010214800040214008FE578B +:104A000049FFFEACE604E80840051800802984440C +:104A100049007244D5048400100380F4FCC1FC41B9 +:104A20008501B61F80818120838185404004A001DB +:104A3000E320405E28014C5780234074A000E2E947 +:104A4000400E28004067800040037C0892E1FFC7C9 +:104A500092C18007802680478066F481490071FEFC +:104A6000F401E281E9094C124005B43FE220E90477 +:104A700081078146D5DC81278386D5D9E602E8DE29 +:104A80008008802AFCC1FC42F60DF083440000FC43 +:104A900042330073000180F681428385048F800CCD +:104AA00081235A08016E003180F35A3802073C73A3 +:104AB000F478100480F4D5195A3803053C73F4785F +:104AC000D5145A380505100480F4D50D5A30070C5A +:104AD0005A300AF6540180FD84E05A080C074470ED +:104AE0000078D503447000323C2DFA9CB402920643 +:104AF00096065A08010495F997F92E07E983E6030B +:104B0000E80B8E62E662E808B40292069606C804D4 +:104B10008405FFC497F994F24402BD14990B8440B4 +:104B200080243820190940040C008444F382F48165 +:104B3000490071B4F0038028804649FFFBDCE2079E +:104B4000F401F302E804380E1909D503387E190977 +:104B50009431881CA440C9038421AC4040150C004A +:104B6000A420A5484422BCD88A05A44938011A09C2 +:104B7000A42188628A01AC198402100480F6000422 +:104B800080F85A080F61000480F64432BD1495F293 +:104B90005A08030F40051C00B0438444F3814900C8 +:104BA000717DF301380E190138019909D54C004483 +:104BB00080F4CC1C38141A018907F0030224000188 +:104BC000F38240214008FE57F48149FFFDC7F401FC +:104BD000802449FFFF26F30296013C0BF95238115D +:104BE0009901E220E80338019909957188BC3811D0 +:104BF0009901A428E220E9084412BD14380099095B +:104C00008403100480F6381199014432BCD8A528D9 +:104C100038019A119AA1FE14022F8006894740009C +:104C200010169A101205000088E3A4A82233800110 +:104C30009A1142118024020F8007401088369A4151 +:104C400012150001FCC2FC4222408000226080015B +:104C5000441000FC42018473B520F2824412BC98D7 +:104C6000955A3C7DFF9D5A980116AD10AD91384084 +:104C70008E09A63D8825AD895A000104480000F23E +:104C80004402BC5C88A0842038100E09AC6948003E +:104C900000E9A6BD00A00018F2835A28014054057F +:104CA0000002C03C4402BC5C38700E11CF0888A0E2 +:104CB00022028001C03338408E11D5308805220091 +:104CC0000001C80588A122628001D52888A181E45D +:104CD0002242800152938000FFE438408E114250FE +:104CE0000024427010754244A4244082900043C0C6 +:104CF000242442423C24424E187542401C75FE0258 +:104D000042002424FFAC42603C7342649C754042E4 +:104D10002096406320D6972397B3540500024E0295 +:104D200000833C0DFF9C80E402A00009E08AE908B2 +:104D300038908E11E12AE80F50957FFFD50C4E4434 +:104D4000000838908E114E9500078520D5048124E7 +:104D50008500D50285010250000A41E18808E0C5BE +:104D60008006E90A4080F80022840001E105E8108D +:104D70005082FFFFD50D4E6400094080F800228468 +:104D800000014E840069D5045A88014E810639C05D +:104D90008E1141E0F80040227001B65F222F000121 +:104DA000F28140F30801B45FC20C84024001001696 +:104DB00041E4F001420F3C7340000816F201880202 +:104DC000E80DF20184E241E40801B45F40779CF60B +:104DD000427F08734073BCF688FCF2014C81003EB0 +:104DE000E0EAE90552A500018947D5054E74003671 +:104DF00052A380004C9E000CE005E9055252800150 +:104E000088A0D5064E040004FF42D50284A0E0AA83 +:104E1000E805404480119783D506E145E804973BB7 +:104E200040640011F203941A5A28010E38708E0162 +:104E30004452BC5C9BE738728E0999C888A0A5F9DA +:104E40009BF7ADE938408E098820F002AD89AD00AE +:104E5000AD81D5078500D59C85404C9E7FCFD5E39D +:104E6000FCC2FC4022608000225080014412D558D0 +:104E7000AD90AD51387090003C6BF9143C5BF91566 +:104E80005A7801174492D780386491094492D148E6 +:104E9000385491094492D0783864920A4462D454C8 +:104EA0003853120A4452BC4838729008D5665A7872 +:104EB000026544A2BC4838751000E6EAE812448254 +:104EC000D0788CE13894120238751008892638940D +:104ED000120A4482D4543894120289253894120A52 +:104EE0004472D78038A39111407518014E740003A5 +:104EF000FFFA5EF380B54492D148E91038849111ED +:104F000050F2800E40F7A007E8125EF380DDE90959 +:104F10005072800FE0E8E90BD5045EF38051E90A96 +:104F20003884911150F2FFF1E10FE80484E4387005 +:104F30009008387491115EF384B6E8055093802888 +:104F4000E125D508449004B64C74800950F3FFD88D +:104F5000E0AFE804852338909008389090008F23C4 +:104F6000E722E80B4492D5448ACA38649109446226 +:104F7000D1348AA738531109385090005A50100480 +:104F80005A58202384A03851920A4432D7803831AD +:104F90009111ACD038509000443000FC42020C73A8 +:104FA0005A581008846B103000F34400096BD50880 +:104FB000846D103000F34402D14838001111AC1157 +:104FC000840038009008380090005A0805194402FF +:104FD000BC48383010004402D07838101202440225 +:104FE000D45440108C3638001202AC5040000C16DD +:104FF000AC114402D558842038101008FCC0FC4580 +:10500000F0852E07E983049F8005F0872200800049 +:10501000F2863C0BFB9622008001843D3C0BFB9703 +:10502000440000FC42918073B40980C3FE0E4482A8 +:10503000C14C44A2C13C5A000105000480E0C04DAF +:105040003C13F47B4442C100FE4C840038121A0A1F +:105050003C13F4403804180838051808100480F38D +:10506000100480F4100480F5100480F6840110040C +:1050700080F74223042484004432BF20E201E8097F +:1050800099C204A4803B8C0138A19E0A9600D5F7F2 +:1050900094F24472BEE498BBF00588644412C15C8B +:1050A000808649FFFEE04402BEA838A39A0244105D +:1050B000003238A01A0A4402C15C49FFF9024412C6 +:1050C000BE78100480F98400380098084412BE6845 +:1050D00038009808480000BB4472BEA83C1DFDCBB8 +:1050E00038038E0249FFFB3AF0898026800849FF89 +:1050F000FB27FA00100480F8000480F38127E60201 +:10510000E827B1493C3DFDCB4442BF20F005804833 +:10511000B6FFF6814412C10049FFF9D3F00580467D +:105120004412C10049FFFA24F00580464412C10030 +:1051300049FFFA5A3C0DFDCB4412C1004422BE98EF +:105140004432BE88808780A649FFF9E7D5369E4263 +:10515000E622E9085A0005079E47E622E9035A08B5 +:105160000A2DF005802649FFFACFF005802649FF79 +:10517000F8EE4402BE78B61FF0074412BEE4F08198 +:10518000F6823C0DFDCB38109A02F2054432C10084 +:10519000F4094452BE2C49FFFB36B73FF6813C0D63 +:1051A000FDCBF1054422C1004432C13C4442BE98CB +:1051B0004452BE8849FFFA323C0DFDCBF105442232 +:1051C000BF204432BE68808649FFFBA04442C10034 +:1051D000F5093C0DFDCB4412BEA8F2054432BF20B8 +:1051E000B75FF68149FFF8BEF0054412C13C442286 +:1051F000C100806649FFF9524472BD94F005F1097F +:105200004422C1004432C13C3C4DFDCB4452BEA8B7 +:10521000B6DF49FFFA2B3C0DFDCB4412BDF0442212 +:10522000BEE4F3054442C1004452BDD0B6FFF6814E +:1052300049FFFC2B3C0DFDCB4412BDF0F20544327E +:10524000BDD0808780A649FFFBB44412BEE4F206BD +:1052500038009A11AC109432880122000001AC1180 +:105260003C1DFDCB4402BDF038101A0AFCC5FC40C1 +:105270008140440000FC423280730001801880E4C9 +:10528000960680C54492BC0CC009840238011408FB +:105290008400380094088400D54A41C09400000E70 +:1052A0000000E603E8048C01100E000040811800A5 +:1052B00000040000E602E9038400D5028C0110041A +:1052C0000000A479A4B84010C008FE5738049A0220 +:1052D00049FFFA4444100064FE0C842049FFFBA1FE +:1052E0008080846300040000FEF4880384A03845B5 +:1052F000020A94DA000E0000886A8025E2A0E8061F +:10530000382196028CA18822D5FA402004098841D0 +:10531000401100369A8C80014E240003FE925EF10B +:105320000051E9058C81882440008409A478381450 +:105330009A0995B288C9A479AC71FCC0FC433C1DA4 +:10534000FF9DF0823C0DFA1FA44DE201E8048C01A0 +:105350003C0FFA1FF00284C05070000C3C0DFF9C03 +:1053600000300009E2C34EF200910403FFFD4E023B +:1053700000845A08050448000080A43A4412C7DC9F +:10538000120F800AA43B4422C7CC120F800BA43812 +:10539000F30212038067A439B1051203806880A666 +:1053A0004402C7EC49FFFF653C9DFF9DF083B0457B +:1053B000000480018041B61F8066F0023C4DFA1F58 +:1053C0003C5DFF6649FFF58400048003C008B045DA +:1053D000F00280418066F40349FFF6370004800440 +:1053E000C008B045F00280418066F40349FFF6FA38 +:1053F000F002F1058046490047F43C0DFF9DA602EE +:10540000C007B045F0028041806649FFFDFAB04513 +:105410008041F002806649FFE720B045F0028041FC +:10542000806649FFFC12220F800A4E0400058400AA +:10543000120F800A3C1DFF9C222F800A0200800967 +:10544000E040E9048E01120F800A220F800B4E0407 +:1054500000058400120F800B0200800A221F800BBF +:10546000E020E9048E01120F800B020F800AAC3895 +:10547000020F800BAC398026F00249FFF7DC8CC1AB +:10548000507380FC48FFFF6CF502444000FC80C56F +:10549000426190733C27FECC3C17FECD3C0DFA1FB9 +:1054A0008066D30CB4855A48050722228006221252 +:1054B00080078400505280FCD5F53C2BFECC3C1B71 +:1054C000FECD3C0FFA1FFCC33C0FFF9EDD9EFC206F +:1054D00084808E4184C2E044E91198E2403198769C +:1054E00038700D019559E027E90788A0A529E02427 +:1054F000E9079D19D5F19E99D5EF841FD502800348 +:10550000FCA0FC423C7DFF9EF1825013800AF18199 +:10551000508380DC51C000028540853EF002E340AC +:105520004EF200DB226E7FFFA43DE006E85CA53C66 +:105530009C23940188079EA1A401E0C0E904A5B8BA +:105540008EC1D552F0018026F48349FFFFC25A076D +:10555000FF4CA57BA4B9E2059441F403E810882729 +:10556000FE14A4CDA44E8AC3FF94404314969B8B93 +:10557000406218D6405014B788C5D5368A858E81CA +:10558000E204E9188827A4FAA50D886552F1800184 +:10559000880F8AC4FF94FE1440001417A4F84053E7 +:1055A00014B6A58E8A628AC48803406298D688C0E1 +:1055B000D51B8827A4F84231247381E3A4CDA53AF2 +:1055C0008A058AC38E814267982442003C244000A9 +:1055D000101740431096A58E88408AC3406218D6A3 +:1055E00088C2D50284C0126E7FFF0203806E226ED5 +:1055F0000000E006E86B0243806D5002006B9401EE +:1056000088079EA1A402E0C0E905026380698EC1FB +:10561000D55E80088026F48349FFFF5B5A07FF5858 +:105620000253806C0223806AE2059441F403E8127D +:105630008827FE140230806E0210806F8AC3FF94A8 +:10564000404314969B8B406218D6405014B788C5CF +:10565000D53E8A858E81E204E91C88270233806B5F +:105660000240806E886552F18001880F8AC4FF94E1 +:10567000FE144000141702338069405314B60260D0 +:10568000806F8A628AC48803406298D688C0D51F1A +:105690008827023380694231247381E30230806EAF +:1056A0000243806B8A058AC38E8142679824420038 +:1056B0003C2440001017404310960260806F8840E1 +:1056C0008AC3406218D688C2D50284C01A6E00040C +:1056D0008D4148FFFF25FCC23C0FFF9FDD9EFC442F +:1056E00095CCB52488E095F940A49C0084C0008541 +:1056F0000000B6C2A9915A88FF06B7031481800141 +:10570000D51800850000A1A138632101448000FF65 +:1057100097AF1481800104820004B6C395B188C894 +:10572000008300014C044005A7B04C13008484C1E1 +:1057300050807FFFB71F50800001148F8001508F71 +:1057400080108388F082F0839E09B88200050000F3 +:10575000F184B9818C21B98350007F0184204000FD +:10576000800638AF8602E750E81D39C406025CFEA9 +:105770000024E81841CE1008895C38F4A9005AF0DA +:10578000FF1204A20001C80638053D01962FB6039A +:10579000D50838053D0104F18000962F4CF04007F4 +:1057A00084018C215A1804DFD54A8420380F8602E0 +:1057B000E610E83C384406025CF20024E837952401 +:1057C0008804384481005A40FF3239C281113802BE +:1057D0009C11E01CE82B38451101400E000154F2E9 +:1057E000003F5A60010DC6045A600214D52514F119 +:1057F0008000B48284C18804B602D518B4834CF208 +:10580000000C14F18001A11184C28804A811D50EE6 +:10581000B4834CF24006B4828804B602D507A119BD +:105820004CF2400DA1118804A8118C215A1804C013 +:10583000D5038401D5048006D5028403FCC4FC4A48 +:1058400080C08400F283B63FB08A8060B43FE2013A +:10585000E808944388248C01A04938310408D5F71E +:1058600084A0B08A8781B41FE2A0E857942B8804F3 +:1058700005E30001A001383F01014C30404D3801E3 +:105880000C00C849945AF181D04294438824049F63 +:105890008001A1C9A07540F0A40000978002149F68 +:1058A000800200978000149F80040097800100F719 +:1058B0008003149F800540938808882950F7800151 +:1058C0000080800300A0800000908001A64A8E2105 +:1058D00040F78407E91CF1028D018E21E101E917EF +:1058E000F1058F418C21E02AE912F1048D218E21EE +:1058F000E121E90D380F1D0139C10C084C03C00C22 +:1059000038110000C90839C10008D505B43F8C0121 +:10591000E201E9BB8CA1D5A885002E07E94AE30086 +:105920004EF20103A031385021014C5440FBB00A23 +:10593000380020005A000104480000F4A07540041B +:1059400008088801A7C2E6E2E9048EE197F8D502CB +:1059500084E0A6435CF08022E8048C219648D502BE +:10596000FA33F184A640E622E9048E219648D50256 +:105970008420A601F181E60EE8048C019600D50290 +:10598000840FF085943CF082F004E0074EF300CAE7 +:1059900004AF8001F002F103880A94014090800076 +:1059A000F005E00A4EF300B9F00341C48001B406EB +:1059B000881CA6405A18FF04480000AB20000001D4 +:1059C000221480004E0500A54E1700A3B41FE60662 +:1059D0004EF20098800A8027B086B0C88086F50312 +:1059E00049FFFE7F5A0002044800008CB406A0F173 +:1059F000F108380070003851850138018101962F77 +:105A0000D93FB04A381094005A18013BF10622F4ED +:105A10008000F2074240BC24884140120836A1367B +:105A2000D8199482996240178401B44542250475BF +:105A3000B645F208A13794928844B48242438475F3 +:105A4000B682F2080443000894928844B4829A61B2 +:105A5000D516956A88A4A137B44542250473B64586 +:105A6000F20894928844B48242438473B682F20866 +:105A70000443000894928844B4828824B622F10931 +:105A800038518501D93EB04A381094005A18013A6D +:105A9000F10722348000F20642408C2488414012F3 +:105AA0000836A0B6D818940299509A59B405420500 +:105AB0000475B605F009A0B794028802B4404223E9 +:105AC0008475B640F0090423000894028802B440AB +:105AD0009A51D516956A88A2A0B7B40542050473F9 +:105AE000B605F00994028802B44042238473B6409C +:105AF000F0090423000894028802B4408822B620EA +:105B0000B406442FFF80881CA641FE57AE418D414C +:105B10008D2248FFFF47F0028CE18C1048FFFF35D3 +:105B20008D0148FFFEFCFCCAFC403CADFF9F80C1DC +:105B300084E085019B31E282E832A14708430001FD +:105B400001C5003238F292020450000838929202E5 +:105B5000A14638529202425E14244052A4B7AD5876 +:105B6000004500334247902440422497AD192EF758 +:105B7000C5E3E8135052FF8797695CF2834FE8084A +:105B800050427F8797215CF2087BE80288E95CF34A +:105B90008DADE9033E8004688C68D5CDFCC0FC4126 +:105BA00081208400B63F80E4AE28F28180C53C0DA0 +:105BB000FF9F84204442C8B0E223E81104248001FE +:105BC00038510501D91EA6B038120808A6B08C417C +:105BD0009690AEB000500019E245E9138009A67016 +:105BE000B45FF301808749FFFE2C8009A6B0441200 +:105BF000C8B0806749FFFF9A84004422C8B0D5032B +:105C00008C21D5DBA670E201E8089443383100000E +:105C100088278C01A8C9D5F7FCC1FC202E07E951C3 +:105C2000FD325A0801053C0C0180D50E9E0CE6029F +:105C3000E9048E28E622E8043C0C017CD5052E07F9 +:105C4000E97049000788B607B4073C1C017A4C008C +:105C5000800A3C1C017B4C0080063C1C01874C00E8 +:105C6000C0048421D5028420445E000088A03C0F3B +:105C7000FAA692A244027B9097693E17E92FAD40A5 +:105C80004403F40044101EE4AC404403F40297B013 +:105C9000AF80FCA084003C0FFAD84403F4038421B5 +:105CA000AE40DD9E4403F403A6005C000001DD9ECF +:105CB0004403F40CA6009600C8074413F3CFA6488B +:105CC00040000406DD9E8401DD9E4413F40384003D +:105CD0003C0FFAD8AE08DD9EFC005A08011349FFBC +:105CE000DA8D5A0802074403F010441FFFAAAE40A1 +:105CF00049FFFFD284003C0BF4E13E07E961D50384 +:105D000049FFFFE5FC804403F01DA680A641A6C024 +:105D10004010A008FE57581084009688AE80922844 +:105D2000A681AE414413F42144200055AE8844209E +:105D300000004430000A502100014C21FFFE844045 +:105D4000AE88442000004430000A502100014C215C +:105D5000FFFEA6409648AE40DD9E84004442D4E457 +:105D60004452D2204412D16C4432D5DC3822800017 +:105D70003822000838218000382080088C015A0819 +:105D800020F7DD9EA640A7053E100D00A641A6C740 +:105D90003E100D01A642404220083E100D02A643CF +:105DA0004031A0083E100D03A64400200008888161 +:105DB000A646972388610010000996DB4010A008D2 +:105DC00088223C1806840010000B0020000A4010B6 +:105DD000A00888223C1806850010000C3C4806826A +:105DE0003E100D0C0010000D3C3806833E100D0DCA +:105DF0000010000E96463E100D0E0010000E92216F +:105E000096463E100D0F0010000E922296463E1050 +:105E10000D100010000E922396463E100D1100103A +:105E2000000F965F3E100D120010000F92243E10DE +:105E30000D1300100011002000104010A00888224F +:105E40003C18068A00100013002000124010A00821 +:105E500088223C18068B0020001500100014968F35 +:105E600040212008884196933C28068C001000159C +:105E700092223E100D1A0010001700500016964F87 +:105E80004010A0088825964B3C18068E005000173D +:105E900092A23E500D1E0000001E962F3E000D28BF +:105EA00040022C0A9606C006440FF000FF073C484B +:105EB00006824001AC0A9606C006440FF000FEC7F9 +:105EC0003C3806834001240AC006440FFC00FE87CC +:105ED0003C28068C4000A40AC006440FFC00FE4784 +:105EE0003C18068EDD9E3C1C017A440E00008801A1 +:105EF000920244127B909601AC08DD9EFC00442384 +:105F0000F6A84413F6A95A080105AE108407D50374 +:105F10008400AE10AE08840080208040FA6F4900F3 +:105F20001455FC80FC20B48084608C8484E6B40426 +:105F30005A380506920A40002808D504921E4000EF +:105F4000780842219C24969084A05A20200C386026 +:105F500088008C414063140C8CA5880696905A5892 +:105F60001EF68C6196D8AA215A3806E3FCA0FC00E4 +:105F7000B48084408C9C840080A098D096D8958270 +:105F800038308C008C0196DF4031980C88A35A0879 +:105F900008F68C489690AB615A2820EFFC80FC04F0 +:105FA000A649B4405A1003045A180D112E17E9706F +:105FB000542080FBCA044412D710D5055A18032573 +:105FC0004412D51849FFFFD5D51F5A180408A05709 +:105FD0008410FE0E58000003D5165030FFF6E6621E +:105FE000E80A842084463820FC088C215A1820FDB9 +:105FF000803FD5E98E28E622E807A0578410FE0EE0 +:1060000058000004A817FC84FC00A68180C05A2018 +:1060100003155A2006139E14E602E90F50017FF87B +:10602000E602E90D50017FF6E602E9095A280D1C47 +:1060300049FFD8E45A0802048400D50284013E07CF +:10604000E9122E07E912A6712E27E92884812E373E +:10605000E9454452B4E049FFFDE24402B4E0802641 +:1060600049FFFF9FFC80FC00B48084405042002C1C +:10607000840080A098D096D8958238308C008C010E +:1060800096DF4031980C88A35A0808F68C48969001 +:10609000AB615A2820EFFC80FC014412D4E4F0816B +:1060A00049FFFF42F0014412D16C49FFFFDEFC8141 +:1060B000FC442E200D124472D710812038638800D2 +:1060C0004442D4E48EC25C6300014402D16C2E30A1 +:1060D0000D015A18063C842A38120808E662842208 +:1060E00038100808E96B49FFD8895A08026884000B +:1060F0005A9803182E100D0184004432D518382107 +:106100008000382F80088C015A0820FB2E000D12C9 +:10611000C00F881F8E228440E24110F07FFFD50817 +:1061200038138000381F80088C015A0820FB2E008D +:106130000D1284295A600103842A381F8008440202 +:10614000B4E0803F49FFFF15D53984203812080894 +:106150005014FFFDE6228423E9028421E662381010 +:106160000808E92C49FFD84A5A08022984005A989D +:1061700003192E000D0184285A0802038427840085 +:106180004432D51838218000382F80088C015A08F5 +:1061900020FB2E000D12C00C881F10107FFFD508A9 +:1061A00038138000381F80088C015A0820FB5A6879 +:1061B00001C82E000D128422D5C14402B4E049FF6B +:1061C000FF6DFCC43C4C0187442200FC54000FFFCF +:1061D000041200124000480892305410FFFF944A05 +:1061E0008822462C003F0430800850210FFFFED645 +:1061F000FEC714308008041200124432015092305D +:106200005410FFFF944A882304308008FE9EFE87C6 +:1062100014208008DD9EFC00441290743800811127 +:1062200049FFFFD2FC80FC4180C081223C0D990DCA +:10623000F081CE04AF908441D50E80E15A68040607 +:10624000800149FFFFEAD504B001386004001074F2 +:106250008000844384004432D16C386180088C0112 +:106260004412D16C5A0820FB2E000D1238208008F1 +:106270004402B4E049FFFEF9FCC1FC0180C03E07C6 +:10628000E9708001B65FF38149FFFEC08006B43F2C +:10629000F20149FFFFCAFC81FC413C0DFA9984835D +:1062A0002E87E95FA74184E0AF0144A2B38FF58157 +:1062B000B69F4492B4E03E77E91249FFFD502E6745 +:1062C000E9708048806A3E77E97084004472D22089 +:1062D0003C1DFA9949FFFFD38009802749FFFE241E +:1062E000B49F8048806A84033C1DFA993E47E97058 +:1062F00049FFFFC58009802749FFFE163C0DFA992A +:10630000F5013E67E9703E67E958AF41FCC1FC000A +:106310002E27FE9E84C3401118574430009096905B +:1063200044125F6042110C734420004849FFD9F4C5 +:106330002E07FE9E8C01960040601837964840104C +:10634000041B3E17FE9EFC80FC002E27FE9D84C38E +:106350004011185744300120969044125C004211BD +:106360000C734420009049FFD9D72E07FE9D8C0165 +:1063700096004060183796484010041B3E17FE9D5B +:10638000FC8084003C0BF4E53C0BF4D62E07E9704E +:10639000540000FBC812440228384412283AA600D0 +:1063A0004422283B3C0BF4D644022839A600A648D8 +:1063B000A6903C2BF4E5D5235A08012084004452D2 +:1063C0002838802044322850A7283C23F4D68CA4B7 +:1063D00088443C2BF4D60022FFFD88020022FFFEF9 +:1063E0000042FFFF88223C23F4E596018844964949 +:1063F0003C2BF4E5DBEAD503840080203C23F4E564 +:1064000088223C23F4D69649880296013C1BF4E589 +:1064100088203C0BF4D63C1BF4E3DD9EFC02F082AA +:10642000F183B65F8002F1028043F38149FFD974A2 +:10643000B41FF103F20149FFD96FFC82FC008460B4 +:1064400080A384DF9718E282E80738500D0938608E +:106450008D098C61D5F8FC80FC56F08384C0F181F5 +:10646000F282842044200090B00880E38124126FDF +:10647000800B4900651D8401100F801A100F801ECB +:106480003C0DFAA7107F8018107F801B1260000C53 +:106490001260000D3C0DFA7E109F8019107F801C49 +:1064A000106F801F109F801D49001022B007804090 +:1064B000B046490010583C0DFAA7FA231010000A04 +:1064C000AD8484004900114CF001F1038040490083 +:1064D00010144403F04A44100055AE404900100324 +:1064E0004413F140A6085A0001FFB0078040B046AF +:1064F000490010393C0DFAA7FA241010000AF002E6 +:10650000F103804049000FF94403F04A441000555C +:10651000AE4049000FE84413F140A6085A0001FFBD +:106520008401B0478041100F8019100F801DB00604 +:1065300049001019F001F102B08849000FDE3C0D4E +:10654000FAA7FA211010000A4403F04A441000553B +:10655000AE4049000FC84413F140A6085A0001FF9D +:106560008400B047100F801E100F801F84018041EF +:10657000100F801DB006107F801C49000FF4501FC3 +:1065800080168041B00849000FB83C0DFAA7FA23E5 +:106590001010000A4403F04A44100055AE40490070 +:1065A0000FA24413F140A6085A0001FF020F800B0E +:1065B000FCD6FC004440012080C14412000042107F +:1065C000107380018481802280434430004849FF59 +:1065D000FF45AC30FC80FC00EED8F08184003C0824 +:1065E0000214B066B00244224A204430004849FFF9 +:1065F000FF17B042B0A644300048848344025F6075 +:1066000049FFFF2C3C080214B042B0A644300048B9 +:106610008481F00149FFFF223C08021444124A2001 +:10662000F00149FFFE762E07E9705A0804153C0375 +:10663000F4C85CF00097E90B9E8150107F6A440F0C +:10664000FFCE4000801688029601D50344000096D4 +:106650003C0BF4C849FFD5D23C1DFFA85A00020AE2 +:106660000210800E8403FE0C96014440FFFFD50506 +:106670000200800E0040802A3C1DFA9C2E37E8D094 +:10668000B441924296865A280104E664E80B3C1015 +:10669000021440218409882240108C363C180214D0 +:1066A000D503440000A03C100214E2018402E90B6F +:1066B0002E27E9702E00042CCA093C23F4E3E28261 +:1066C000E8058C013E00042CD514C0048E013E0068 +:1066D000042C3C03F4F1E201E9093C03FF494410B6 +:1066E000EA5FE220E9068C01D50284003C0BFF49F9 +:1066F0002E00042CE6028401E80284003E00042AF5 +:10670000ED28FC80944988204430FFFF84404C00F1 +:10671000800EA500E244E803A4809691A500E283E0 +:10672000E803A4C096D98C02D5F35CF1809780036E +:10673000E903440000969A109601DD9EFC424460F5 +:106740000240FF8444A2000040032800812144123B +:106750000002F381F48280E2882680404430009079 +:106760008481FAA049000FAD50830120838614AFC5 +:106770008003F003FA3440AE0000800A49FFFFC4F2 +:106780000A138001E220E8031203FFFFF302F10184 +:10679000402E18018822800A88438481FA7449FFB8 +:1067A000FE5D0A148001E220E8031204FFFF51CECF +:1067B00000484DC47FE0FCC2FC002E00041D2E10DA +:1067C0000456C01E3C0DF24A5A1801049201D5022B +:1067D00092023C2C01099601E2402E00042DE805AE +:1067E000E61EE80E8C01D50AC00B5CF10E10E9051F +:1067F000E60FE9038E05D5028E013E00042D5A18DE +:10680000010D2E00042D5A081E048405D508E61437 +:106810008406E8058407D503490013603C0FFA9B02 +:10682000FC803C33FF495CF18033E910949188414E +:1068300084A34C11000CA5080A300001FF2C9082A3 +:10684000926288641A308001D5F5DD9E84003E0096 +:10685000042C84003C0BFF49DD9EFC003C03FF49F7 +:106860005CF00033E90649FFFFF384003C0BF4C7FA +:106870003C03FF485CF00033E90484003C0BFF4814 +:10688000FC80FC0080C084003C0BF4E349FFFD7BEE +:1068900049FFD4B492C13C13E3305A000208840388 +:1068A000FE4496494400FFFFD5053C0DFFA80000BB +:1068B000002B2E20046C5A28010A84003C0BF4E3C0 +:1068C000C11B2E07E983C009D50BE2C1E8153C13B3 +:1068D000F4E3E201E8F7D5102E00043AC003840186 +:1068E000D50C3C1C01125CF08078E9093E00046C78 +:1068F0003C0BFF48D50584003E00046C8401FC80FD +:10690000FC20540000FBC00644725C004460009010 +:10691000D50544725F60446000482E07E9368E0159 +:10692000E602E80844024B4044124A20804649FFF0 +:10693000D6F32E07E936540000FD5A08011095B130 +:1069400084A044324B4098AB987D8403A5108E01FF +:106950003840980DC8FC8CA2DEF7FCA0FC0049FF73 +:10696000FF7E2E07E970540000FBC80A44020A208B +:106970003C1C02774420004849FFD6CED50D440286 +:106980000A2044120A223C2C027744300090848171 +:10699000FAA049000E962E07E936C00A49FFFF58B3 +:1069A0002E07E97049FFFFAE84003E07E936FC8000 +:1069B0002E1004565A1801052E17C662D5033C1333 +:1069C000E3053C2DFA9CB442924296865A28010473 +:1069D0008C3996492E27E955CA052E27C664882288 +:1069E0009649AC402E17C662AC44DD9E2E3004564C +:1069F0005A380117003000103E37C911A0053C0F6E +:106A0000F245A60A3E07C95CA60B3E07C95DA41263 +:106A10003C0BE4C3A4133C0BE4C88405D514A6C006 +:106A20003E37C911A0033C0FF245A6083E07C95CDA +:106A3000A6093E07C95DA4103C0BE4C3A4113C0B9E +:106A4000E4C8FA093C0BE4C42E000439C008440031 +:106A500001F43C0BE4C8840F3C0BE4C4DD9EFC4015 +:106A60005A00010A44625C008086441001204420E0 +:106A70000090D50944625F6044424A20441000906F +:106A800044200048840080A0385201098C0196C03F +:106A9000E262E9FB840694494432000081E080E42C +:106AA000810384A00A94000102A380004094BD37B2 +:106AB0008CA1892A97681A938001DAF58E019600D5 +:106AC0008861C8EE95D194C188668423385201014B +:106AD0008E21964838519C0DC9FA8C019640E222CD +:106AE000E9F3FCC0FC40848084FF838784C180A4D8 +:106AF000814445E2C8C802F00000548200FF40F71C +:106B000088068120E80F02F0800040F78C06E80A32 +:106B100084C0386F1008A580E2DCE80883868148CD +:106B2000D50585E138FF1008D50284C002948000A5 +:106B30000AF08001892FE3278C818C024074BC1BF2 +:106B400040543C1B5A4804D95A60010380AA80056E +:106B5000FCC080203C0C017AC1195A1801053C0C7C +:106B60000182DD9E5A1803053C0C017BDD9E5A18FC +:106B700002053C0C0183DD9E5A1804053C0C01877C +:106B8000DD9E5A1805043C0C0188DD9EFC002E6732 +:106B9000E955CE353C0C0112E614E9313CF7F52EEF +:106BA0005EF7FFCFE8043C6E0112D5294400007067 +:106BB00049FFCF8F3C6BF4DF8006442225B080660E +:106BC0003C13E2BAE201E80698428C01AEC8960195 +:106BD000D5F83C0C02733C1C027549FFD5B8440043 +:106BE00000333C0BFF4944124A203C0C02774420FE +:106BF000004849FFFE1884013E07E955FC8094D9FE +:106C000088604C0180051A200001D5FCDD9E4403FC +:106C1000F04A44100055AE404413F403A608C8FFE0 +:106C2000DD9EFC0084003C0FFAD83C0DFAAA8421BA +:106C3000AE4049FFD8B14403F04A44100055AE407D +:106C40003C2DFAAAA6505A1001FF44100055AE4040 +:106C50004413F403A6089600C8FE3C1DFAAA84411A +:106C6000AE883C0E0112FC80FC0080C049FFFFD1C1 +:106C70003C0DFA993E67E97049FFF9C8FC80FC4079 +:106C80002E1004665A18011F2E10041D5A180123D5 +:106C90002E10046AC91F84223E10046644528F706D +:106CA0002E77C6D42E37E9702E4004662E90043914 +:106CB000842080C544A0005A4480007D45C0003235 +:106CC000D5245A1802082E10041D5A1001E98420F8 +:106CD000D5E42E1004655A1801FCD5DFC31A98813B +:106CE00000F1002098A910F10184CC199881C314F7 +:106CF0000021002840F304001027818C5A980105D8 +:106D000098B111C1018C8C219688E247E9E8D50F32 +:106D100038F00400D5E800210008D5ED5A480105F7 +:106D20001081018CD5EC10A1018CD5E9FCC0442266 +:106D3000D01844320000B482A09184A10412001241 +:106D400092305410FFFF944A8823443201500410BB +:106D50008008944A9234964B121000813C1BF4F048 +:106D6000041200120421001392305410FFFF944AC1 +:106D7000882354217FFF4432000C949288430230D0 +:106D8000801B103001040230801B92681030010516 +:106D90000230801A103001060230801A92681030DA +:106DA0000107A4D310300108A4D392681030010960 +:106DB000A4D11030010AA4D192681030010BA0D2E6 +:106DC00092785441803F0430800F9261FEEE94DF50 +:106DD000FEE71030010CA0920410800F9248FE6E66 +:106DE00096AF944FFE571010010DDD9EFC4280E0DF +:106DF000812180C28420801FFA40490060592E07FB +:106E0000FE94A6784432B41C4442CEA038118008C7 +:106E1000401498009649C90284213812010984401F +:106E20009D4144912E6844A00BB8986A96573861EA +:106E300084005A60FF0F381488003882090142101C +:106E4000A8244010A036388F9A028828381F9A0A42 +:106E50008C415A2808EC842080418061384F86029A +:106E60009788E2648C2140233C1B40323C1B5A181B +:106E700004F7E607E8043E57FE94D50484003E0775 +:106E8000FE94AEB8FCC2FC57B186B61FF1818448AF +:106E900084208006509F80204900600A8420800959 +:106EA0008448490060058400F1013C080214440054 +:106EB000009040000416548000FF9401F08244A228 +:106EC0005F6084E0F0014C70003FB00AB05C804825 +:106ED00049FFFAB650557CA08005B04AB09C806846 +:106EE0008481F58349FFFABA920138131D01960196 +:106EF000E220F503E80338031D09505281204C5568 +:106F00007FEDB41F445DA0A088AA88A08005B04A88 +:106F1000B09C80688481F58349FFFAA09201381300 +:106F20001D019601E220F503E80338031D098005E1 +:106F3000802849FFFBE9920138049D09F0028CE1A9 +:106F40008940D5C1B41F49FFFA0149FFD1573C1D03 +:106F5000FFA80220800F5A0002058403FE84969148 +:106F600080628026800949FFFDBF8040100F801796 +:106F700038148901500F80173823090149FFFF3861 +:106F80002E07E95F003F8017382481013813010183 +:106F90003C280214882238448D0138230D0188448E +:106FA000E041E8069A8A5CF100C8E805D502844011 +:106FB000100F80179451443001F440108C37E623B1 +:106FC000E807C907441000C740108806D50284238B +:106FD000002F80172E57FE9CDA072E37FE9588610A +:106FE0003E37FE95D5033E17FE952E37FE95E66398 +:106FF000E8035A18030684003E07FE9580023E27E8 +:10700000FE9CFCD74412C8C8380080005A0801050D +:107010002E07C665DD9E8401DD9E84004412B41CEB +:10702000845F382080088C015A0808FD84003E07E0 +:10703000FE94DD9E5A0801068401AE088400D50E38 +:107040003C0DFFA80200000FE20440403C1BE2831D +:10705000E9F4A410E61EE8048C01AC10DD9E840067 +:10706000AE08DD9EFC40810184203C18021444627D +:10707000C8C810810000842480E2814349FFFF05D5 +:107080008120380320005A0801102E00042CE6024B +:10709000E8048C013E00042C84013E000456840068 +:1070A0003C0BF4C6D53084004412CE864422B3BCD7 +:1070B0003C3002143C43F4F149FFFFBE2E00042C87 +:1070C000C0048E013E00042C5AA8011284008020C6 +:1070D00038230000CA038C2196498C015A0804FA0F +:1070E0005A1804063C03FF488C01D50284003C0B6F +:1070F000FF483C03FF494410EA5FE220E9048C01A9 +:107100003C0BFF4984003E00042A2E00042CC006DC +:1071100084013E00042A10938000FCC0FC4084815E +:10712000405010024062900C4470004888C1FF7CBF +:1071300044900120441200004052900C42102473ED +:1071400080019855989D806749FFF988AC30FCC054 +:10715000FC4051FFFDB0F081F182B67FB0044412D3 +:107160004A204430009080E28440F48349FFFD4986 +:107170004420FFFF44300090500F813044124A20D9 +:1071800049FFFD3F3C0DFAAA842184C0AE40840132 +:107190003C6FFAD94493F04A49000DD84480005519 +:1071A00049FFFB56F0014C600041840085403E07DA +:1071B000E9753CAFFADB49FFD5EF108480002E075C +:1071C000E975F102E201E8262E17E9753C0DFADBBC +:1071D000E220E8F63CAFFAD92E07E975B43F5A78B9 +:1071E0000209F203B0C4504F813049FFFAA9D50B10 +:1071F000B084503F81305A78010549FFF9DCD5034E +:1072000049FFFF8E2E07E9758C0196003E07E97550 +:10721000D5D73C0DFAAA84218CC1AE40440FFFAAF9 +:107220003E07E93597B0D5BF51FF8250FCC0FC0343 +:1072300084208448B00249005E3B84208448B00426 +:1072400049005E36840249FFFD11B0C2B1048401D9 +:107250008426844249FFFF7EB04284448402490070 +:10726000321C49FFCFCB3C1DFFA80220800F5A00E3 +:1072700002058403FE849691B0428062B00449FF07 +:10728000FC33F08149FFFECB840249FFFBEA49FF52 +:10729000FCC0F001FC83FC0180C0840149FFFCE6D6 +:1072A000840184268040B0C1404F840049FFFF52D2 +:1072B0005A680105800649FFFBD449FFFCAA020F6A +:1072C000800249FFFAE0FC81FC2149FFFB492E07BF +:1072D000E970C0135A080453440000323C0BF4F127 +:1072E0004412CE8684004422B3BC3C300214444095 +:1072F000003249FFFEA1D5073E000456440000506D +:107300003C0BF4F13C0C0277842049FFF9663C0CFD +:10731000027744124A204420004849FFFA842E078D +:10732000E95E5A000104480000BA2E60042A5A603F +:107330000104480000B484003E00045844000043A7 +:1073400049FFCBC749FFFF7580403C1DFA99443285 +:10735000B38F100F8007840349FFF79184003C0B23 +:10736000F4C63E07E9553E60045649FFFC5C49FF00 +:10737000FA6F3E600458480000924400012C3C0B18 +:10738000F4F12E00042B5A080107440000313C3C64 +:107390000112D5058460C8052E37E94A40300C0635 +:1073A0003C0C02772E17E95F502F800749FFFE5CE7 +:1073B0002E07E95E5A0801732E00042A5A08012498 +:1073C0002E67E9405A6801202E57E95F000F8007B9 +:1073D000D06584E0440000483E70045849FFCB79F2 +:1073E00049FFFC1784033C1DFA99002F80074432A3 +:1073F000B38F49FFF7443E77E9553E60045849FF93 +:10740000FC12D54C3C03FF485CF000322E00046CAB +:10741000E902C0085A0801433C0C01125CF00078F4 +:10742000E93D4400004284C049FFCB533C6BFF4818 +:1074300049FFFBEF2E07E97049FFD1C4840149FFE2 +:10744000FF2CC8232E20042BCA0E3C1DFA9944326F +:10745000B38F49FFF7143E67E95549FFFBE449FF45 +:10746000F9F7D51C84033C1DFA992E27E95F4432B5 +:10747000B38F49FFF7043C0C01125CF00033E90EB6 +:1074800084013E07E963D50A84033C1DFA992E273F +:10749000E95F4432B38F49FFF6F22E07E9703E07E9 +:1074A000E9583C0DFFA80000002EC00B3C10021450 +:1074B00044022D54AC403C13F4E844022D56AC4039 +:1074C000FCA1FC002E000D123C1DFADB8C01E22019 +:1074D000E80449FFF3E9C00C84003C0BF4E149FFE8 +:1074E000F3E9C81749FFF74F49FFFEF0D5122E0701 +:1074F000E9335A0801064402B3F249FFCFE1844060 +:107500008401842A8062808080A249FFCED7D5DBA7 +:10751000FC80FC402E37E9702E07E94F2E17E92D2D +:107520002E27E91C2E400D28CB0480A080C1D50554 +:1075300080A280C4804080813C7C0275FF74FEA4E0 +:107540008460449211703C03E2BAE260E81A941934 +:107550004010240040A3800002808000A44802055F +:107560000000FE649A08FE2C42841824400008168D +:107570004004000196018C611205000096D9D5E403 +:107580003C0C02753C1C027349FFD0E1FCC0445224 +:107590004A20442003E844324AB05A080509A52885 +:1075A00002128048FE6440108837D5095A08010A43 +:1075B000A46802428048FE54401090379649AC6857 +:1075C0008CA2DBECDD9EFC4180C0812181028143E5 +:1075D000F4812E77E9705A080113C1049F4954922F +:1075E00080FF2E57E95F4C5480092E00042B5A0867 +:1075F000010580094900132D8403D5095A08020F9B +:107600005A780405840149FFFFC484003C1DFA999F +:1076100080494432B38F49FFF6323C1DFAB5A608C3 +:1076200096005A0801FE3C1DFAAAAE0849FFD3B4E1 +:107630003C0DFAB5A640C9FFA6405A1801FF2E0717 +:10764000E97049FFD0BF2E07E970C8045A780408D2 +:10765000D5045A080405CF0349FFFF5D5A680108A5 +:1076600010640000840010650000D5095A68020A01 +:10767000840010040000100500008401F101AE0830 +:10768000FCC1DD9EFC0080C0C82444020A204412D4 +:107690005F604420004849FFD03F44020A20441262 +:1076A0005FF04420004849FFD03744020A204412CA +:1076B00060804420004849FFD02F44020A20441231 +:1076C0004A204420004849FFD0273E60042AD510B4 +:1076D00049FFF65944020A20842049FFF77E4402FC +:1076E0000A2044124A204420004849FFF89C2E07F3 +:1076F000E95EC8033E00042A2E00042AFC80FC40F8 +:10770000009080004E930008445000FF80C980E93B +:107710008065D5298420445000FF80C180E18065C8 +:107720009708E289E820A10138A2050197094CA237 +:10773000401904A00005950A888A00A20002E343CC +:1077400040353C1B00A20003E2EA40753C1B00A24E +:107750000000A721E34540553C1BE2C440623C1BAE +:107760008C21D5DF8400E2E3E92A8540408190083E +:107770008085802AE2C4E91840941000409484086F +:10778000892202F4800040F780115EF78033E90916 +:10779000E688E8048C219648D5048D4154A500FF65 +:1077A0008C819720D5E8E34140153C1A9708E28088 +:1077B00040103C1B8C61960896D8D5D6E602E802AC +:1077C0008402FCC03BFFFCBCEFFC49FFCD175A080C +:1077D00002124403F04A44100055AE403C2DFAD644 +:1077E000CA09840180208062808080A249FFCD6622 +:1077F000D5F6EC043BFFFC84DD9E3A6F9EBCEFF0B7 +:1078000080C0A601F282F3835A080408A6305A0801 +:107810000105840049000C3E2E07E97C5A08010C42 +:107820004402B3ACF102F2033C3DFAA53C4DFAA38D +:1078300049004F57440FFFAA3E07E9783C0DFAA3D1 +:107840003C1DFA99B61F4422B363F302F4033C5D76 +:10785000FAA54402B4AC4900506D96003E07E968B1 +:1078600049004CCC2E07E9685A00010584013C0F01 +:10787000FABEA6315A080816A6305A00020448007B +:1078800000A83C0DFAAD5A00067C5A0009044800D5 +:10789000009649FFCCB35A00020448000090D5700E +:1078A0005A08090EA6305A000204480000923C0D06 +:1078B000FAAD8E06E6024EF20082D5625A080A0838 +:1078C000A6308E02E6024EF20084D55A5A08030D05 +:1078D000A7B05A68017E800649000A49800649001F +:1078E0000A358408D576540000FD5A080472A63083 +:1078F0005A08016F49000A3B3C0DFAAD5A08060CC4 +:107900004403F04A44100055AE4084003C0FFAD6C0 +:1079100049FFFF5A840149000A1949000C663E07D5 +:10792000E94749FFCC3F2E57E95C84203E07E91622 +:107930003E17E926D00649FFD03384013E07E926E9 +:107940002E07E916A7F13E07E95C5A78061A2E07BA +:10795000E9472E27E93EE240E91584003E07E93E6B +:107960003C0DFA9949FFF3522E07E970802749FF31 +:10797000F3A184013E07E98284003C0BF4DA840819 +:10798000D528CA033E07E93E8404AE312E000D120D +:1079900049000CD580E0C8F4840149000B7B8006C7 +:1079A00049000B8FF082F102840280478461808756 +:1079B00080A749FFCC838408D50C8440846184026D +:1079C000FA25808380A249FFCC798408D5028401FE +:1079D000EC103A6F9E84DD9E3BFFFCBC8401EFFC03 +:1079E00049FFF17C4403F04A44100055AE40441373 +:1079F000F403A6085A0001FFEC043BFFFC84DD9E63 +:107A00003A6FA8BCC00349FFC822446000654473B4 +:107A1000F04A4490005549FFCBF1C0128EC1C61008 +:107A2000842180418061848044004F004900343DBE +:107A30004400006449FFC7DC10938000D5ED84004A +:107A40003A6FA88448FFCB6A2E07E920C8072E07A3 +:107A5000E9688E045C000002DD9E8400DD9E00006B +:107A6000A6C18E63E6694EF202AF3A6FA4BCEFF492 +:107A700080E280C044F0798438378D0140F1BC0049 +:107A80004A003C0012002E013A0540023A05060366 +:107A900070032404BC043C0DFAAD5A08091E49FFCA +:107AA000CBAD5A08021A4402B3404412B3E249FF74 +:107AB000CD8D4402B3634412B36A49FFCD78840C80 +:107AC000AE313C0DFA99842049FFD01C8403AE31BD +:107AD000FA003C0FFAAD2E07C5DAC00F5A000109B3 +:107AE0002E07C5DA5A0001044800026BD5363C0364 +:107AF000E4D6A07BE220E8F54403F04A44100055A8 +:107B0000AE404493F04B3C0DFAB5A600C8EA3C0DDC +:107B1000FAAAA6005A0801E62E07E9335A08010618 +:107B20004402B3F249FFCCCC3C1DFADB2E07C56FF3 +:107B3000E220E8EA000480004413F04B5A00FF05FD +:107B4000841FAE08D5FF84408401842A806280802F +:107B500080A249FFCBB3D5D80493800349000AD94A +:107B6000E320E80AA63A5A0001044800022A2E003F +:107B700004134E03022649FFDE7E4E030222440315 +:107B8000F04A44100055AE403C1DFAB5A608C0FFAF +:107B90008406AE3184023E07E98249FFCB033E07EB +:107BA000E95C49000C5D3C0DFAAA8420AE40480017 +:107BB00002082E07E980C826800649000A0F2E0712 +:107BC000E917C8074402D3FC49FFCBFF49000E1256 +:107BD0002E07E9805A00031C84213C0DFA9949FFC5 +:107BE000CF91840149000A56800649000A6AF08153 +:107BF00084408402F1018461808280A249FFCB5ECF +:107C0000D5065A08030584013E07E98084003E0733 +:107C1000E9822E17E968800649000EB72E07E93C75 +:107C20005A080104480000AE2E07E9805A080304F0 +:107C3000480000A8A63149000A5A490009EA3C73E5 +:107C4000F4DAA63149000A5DE2E0E8052E07E962B0 +:107C50005A0801232E77E928440FFFAA3E07E93589 +:107C600097F88406AE315A78011380273C0DFA99B3 +:107C700049FFCF48800649000A24F08184408402ED +:107C8000F1018067808280A249FFCB184403F06D28 +:107C90008424AE40D5093C0DFA99842149FFCF32A6 +:107CA0008401490009F7800649000A0BF081F101BF +:107CB000EC0C844084028461808280A23A6FA484A8 +:107CC00048FFCAFC2E07E9825A08012F49000F24F9 +:107CD0002E00043A5A08011549FFCA905A080211A9 +:107CE000490013ED80C03E07E93C5A08010A8400B0 +:107CF00049001E6B84003E6004133E00043A2E07C8 +:107D0000E93C5A08010B2E67E962CE0749000A8B4D +:107D10003E67E979480001553C0DFA99842149FFF5 +:107D2000CEF1480001195A0002044800014A2E779A +:107D3000E9625A78010B3C0DFA99842049FFCEE2A2 +:107D40003E77E9824800013DA608C80B2E07E93CB2 +:107D5000C8088404AE313C0DFA9949FFF157D5A10A +:107D600049FFFE74C8F72E00043A5A08010649FF7D +:107D7000CA455A0002F03C0DFA99842049FFCEC250 +:107D8000EC0C3A6FA48448000A4E3C0DFAAD5A0838 +:107D9000062084003E07E9803E07E9823E07E94766 +:107DA0003E07E9254402D3FC49FFCB0F49FFCA2611 +:107DB000C00749FFCB7A3C03E4E649FFFE23840376 +:107DC00049FFC687EC0C3A6FA48448000A715A0038 +:107DD0000904480000F649FFCA115A00020448008D +:107DE00000F03C0DFA99842049FFCE8C8403AE311B +:107DF000480000E72E97E9804E93001B490008EEEB +:107E000049000CF83C0DFAAA8421AE402E07E98007 +:107E10005A000314800649000954F08184618402E9 +:107E2000F1018049808380A949FFCA48D5065A9844 +:107E3000030584013E07E98080062E17E9684900A2 +:107E40000DA42E07E93C5A0001062E07E9805A08C6 +:107E50000307EC0C3A6FA48448000A2AA6314900B3 +:107E60000946490008D63C93F4DAA631490009498D +:107E7000E320E91285203C0DFA99149380038029B0 +:107E800049FFCE40840BAE3184013E07E9823C9B22 +:107E9000F4DA48000096800649000913F081F101E8 +:107EA0008402844048000085A6005A08023CA608C7 +:107EB000C8042E07E93CC0042E07E937C829A1FBF6 +:107EC000490018EFE2E0E8042E07E937C8794403D7 +:107ED000F04A44100055AE403C1DFAB5A608C0FF5C +:107EE000A63149000904F081F1014402B3B04422F3 +:107EF000B40449000A898400842B3C0BF4DAAE7187 +:107F000084223E17E9823C1DFAAAAE08D5598400A6 +:107F1000A83BEC0C84011003801C3A6FA484480039 +:107F200018933C0DFAAD5A0807098409AE3149008F +:107F300009BFFA003C0FFAAD84001003801CD54045 +:107F40002E07E9825A0801103C0DFA9949FFF05EAC +:107F500049FFFD4484023E07E9823C0DFAAA8420D1 +:107F6000AE40D52E5A08022D84003E07E982A608AD +:107F7000C8042E07E93CC00A2E07E937C0072E07C0 +:107F8000E9855A00010448FFFF668409AE313C0DC3 +:107F9000FA9949FFF03B3C0DFA99842149FFCDB293 +:107FA000840084401003801CA8BB8402FA26EC0CD9 +:107FB0008461808380A23A6FA48448FFC97FEC0C5F +:107FC0003A6FA484DD9E92004403F04A44100055A9 +:107FD000AE404413F403A6085A0001FFDD9E0000E2 +:107FE0003A6FA8BC812080E249FFC99980C049FF4F +:107FF000FFED5004FFFFE60C4EF2018644F07F0CCB +:108000003807810140F03C004A003C0018007A002B +:1080100050016202BA00F802F802F802F802F8020F +:108020008C02DE024400003049FFC553840EAE3995 +:108030008405AE383C1DFA9C840010030050B44106 +:10804000440FBFFFFE16B6014463F04A449000554A +:1080500049FFC8D45A08020510930000D5FA44031A +:10806000F0108420AE4049FFC8C9C020842180415F +:108070008061808144005AF0490031174400006457 +:1080800049FFFCC0D513840EAE398406AE38840097 +:108090001003005080A650030041843F1812800155 +:1080A000D8FE4403F0108420AE408007842149FFAD +:1080B000CD298420840280418461808180A13A6F2F +:1080C000A88448FFC8FB4400003149FFC5024403AF +:1080D000F42985201090000049FFF0E084013E97CC +:1080E000E912AE38109300502E07E912A6792E2718 +:1080F000E92884812E37E9454452B4E049FFED8FE9 +:108100002E07E970C8084402B4E04412D71049FFB2 +:10811000EF30D5095A0803084402B4E04412D518D8 +:1081200049FFEF2784003E0004542E1004588400B9 +:108130003C0E011184013E07E9295A1001043E0753 +:10814000E936840049000602A6398E08E6044EF29C +:1081500000DE80073A6FA88448FFC97044000032EF +:1081600049FFC4B73C1DFAAA8402AE08AE38A6394E +:108170009E43E624E9075A000D065A080E0749FFF8 +:10818000CA388408AE39D5038409AE3985201093E6 +:1081900000503E97E9413E97E92649FFF07F3C0DAC +:1081A000FA9949FFEF334463F04A3E97E90544905A +:1081B000005549FFC8235A08020510930000D5FA5C +:1081C0004403F0108420AE404403F429441FFFC34D +:1081D000AE4049FFC813C009842144005AF08041D1 +:1081E000806180814900306184003C1DFA9C3E0022 +:1081F000045484003C0E0111B441440FBFFFFE162D +:10820000B60184013E07E9292E07E9745A080306DE +:10821000840949FFC936D504840549FFC9322E00B7 +:1082200004585A00010584013E07E93684004900DC +:10823000058D8007842049FFCC653C0DFAAD5A00BE +:1082400004045A08070C8421844084028062848FCD +:1082500080A13A6FA88448FFC83184408402FA257F +:108260008062848F84A13A6FA88448FFC8273C0DA0 +:10827000FA99842049FFCC46840AAE398403AE388B +:108280008400100300503C0DFA9949FFEEBF8401B1 +:108290003A6FA88448FFDAF849FFC7B03C1DFA9945 +:1082A0005A08020CA6095A0003128001842049FFD3 +:1082B000CC29490007B8D50AA6095A000A08800146 +:1082C000842049FFCC1F490007F30003005100132D +:1082D00000524422B37E4432B3504442B38E49FF2D +:1082E000F974840010030050D511000300515A00A6 +:1082F00001055A08020584003E07E9628400100364 +:108300000050D504841B100300503A6FA884DD9EF2 +:10831000E606E87544F082243807800040F03C000F +:108320004A003C00062644D8669E4413F248840165 +:108330004423F249AE088422AE504423F24A8464B6 +:10834000AE104423F24BAE50D5304413F248841F94 +:10835000AE084413F2498448AE084413F24AAE080A +:108360004413F24BAE08D53C4413F2488401AE08E6 +:108370004413F249AE084413F24AAE084413F24BD8 +:10838000AE084413F24CAE08D52E4413F2488401D3 +:108390004423F249AE088424AE504423F24A846C4C +:1083A000AE104423F24BAE504423F24CAED04423E3 +:1083B000F24DAE504423F24EAE104423F24FAE5075 +:1083C000D51B4413F2488400AE084413F24984419B +:1083D000AE084413F24AAE084413F24BAE084413FD +:1083E000F24CAE884413F24DAE084413F24EAE0880 +:1083F0004413F24FAE084413F250AE08DD9E9200D3 +:10840000C103580000104413F2519600AE08DD9EDF +:1084100040003C084423F2449210AC104010BC08C9 +:108420004403F2469230AC40DD9E4403F240842186 +:10843000AE404413F04A44200055AE88A6405A107E +:1084400001FFDD9E4413F258A448AC404413F25A95 +:10845000A448AC414413F25CA448AC424413F25E1D +:10846000A448AC434413F260A64810100008DD9EF7 +:10847000FC02F0818002F383F18249FFFF4BF0019F +:10848000F10249FFFFC749FFFFD2F00349FFFFDCBC +:10849000FC82FC02F0814403F242F182F283AF409D +:1084A000001F80204403F243AE404403F252842173 +:1084B000ACC04403F254AD004403F256AC40001F7C +:1084C00080244403F241AE40000F8028001F802C1E +:1084D00049FFFF98F001F102F203F30C49FFFFCAD4 +:1084E000FC824403F1408421AE40DD9E84203C0F99 +:1084F000FAA7AC43DD9E3C3DFAA79201922192413E +:10850000AC18AC59AC9ADD9E3C1DFAA7A68210208F +:10851000800CA6831020800DA680A6011020800E5E +:108520001000800FDD9E3C1DFAA7A682102080104F +:10853000A68310208011A680A601102080121000B2 +:108540008013DD9E3C1DFAA7A68210208014A6830E +:1085500010208015A680A60110208016100080171C +:10856000DD9EFC01B63FF28149FFFFD0B41F49FFF9 +:10857000FFDCF00149FFFFE8FC81FC24F081F1827F +:10858000F283001F803C002F8038000F8040007F66 +:108590008060006F804C105F8016103F8014102F99 +:1085A0008017104F8015101F801A103F8018100F71 +:1085B000801B104F8019CF08105F801E103F801C59 +:1085C000102F801FD507101F801E103F801C100F1A +:1085D000801F3C0DFA7E104F801D49FFFF89B005BA +:1085E000B046B08749FFFFBFF001F102F20349FF37 +:1085F000FF843C0DFAA7021F8028002F8044AC4462 +:10860000001F8054FE775263001095B1FF8F001F4A +:1086100080481060000A58108040FE571010000B70 +:10862000221F802C1210000C221F802E1210000D11 +:108630004403F04A44100055AE404403F140842105 +:10864000AE40A6405A1001FFFCA4FC02B61F2E0744 +:10865000C54FF1812E17C55084C1100F800A100F2D +:108660008009100F800D3C0DFA7E101F8008101F2E +:10867000800C101F800F106F800B106F800E49FF51 +:10868000FF37B0438041B00249FFFF6DF101B41FD5 +:10869000804149FFFF323C0DFAA784221010000AE6 +:1086A00084201010000B4403F04A44100055AE40E3 +:1086B0004403F140AF80A6405A1001FFFC82FC2425 +:1086C000F08194199600100F8017100F801B840101 +:1086D00084E2100F801E3C0DFA7E80C5103F80148E +:1086E000104F8015103F8018104F8019103F801CCC +:1086F000103F801F104F801DF182F283107F801683 +:10870000107F801A49FFFEF4B005B046B08749FFDC +:10871000FF2AF001F102F20349FFFEEF3C0DFAA738 +:108720002E27E9568420AC445A28010895B31070CE +:10873000000A1060000BD50684491020000A1010B2 +:10874000000B4403F04A44100055AE404403F1408E +:108750008421AE40A6405A1001FFFCA43C1DFAA79C +:108760001000800BDD9E4403F04A44100055AE40DB +:108770004413F403A6085A0001FF4403F380842144 +:10878000AE404413F04A44200055AE88A6405A102B +:1087900001FFDD9E4453F381944AA7289407544275 +:1087A00000F0FEA7FE579648FE0F9600AE28440341 +:1087B000F38496D8AEC0DD9E4413F3868400AE08E1 +:1087C0004413F387AE08DD9EFC004403F38496D87F +:1087D000AEC049FFFFCA4403F04A44100055AE4002 +:1087E0004413F380A6085A0001FF4463F380440356 +:1087F000F386A6005A08010F49FFFFE049FFFFB5C5 +:108800004403F04A44100055AE40A6305A0001FF20 +:10881000D5EF4403F387A6005A0001F0FC8044130F +:10882000F280A60858000001AE08DD9E4423F280C5 +:108830009405A650FE479648AE50DD9E441E0000AB +:1088400088014413F2869681AC8892104413F28812 +:108850009606AE08DD9EFC40810080C1A440440322 +:10886000F28445C3F280AC400404000149FFFFE8F4 +:10887000001400084403F2834473F04AAE4044906D +:108880000055001400090024000A96469409001EB1 +:1088900000003DCFFA80541080FDFE47101E0000FE +:1088A000968694D2002E000044000055542100FB0F +:1088B000FE9F102E000044A3F418AE3802050000FD +:1088C000C011020500005CF00781E80C4403F2913E +:1088D0008421AE400004000B49FFFFAA49FFFFA11D +:1088E000D50649FFC48B5A0002EBD5F1000E0000FB +:1088F0009606C00410938000D5FA4413F291AE0896 +:108900004403F2813C0FFA7F5A680307A640922283 +:108910009646C1B8D5085A680105A6009202D50549 +:108920005A680206A60092039606C0ACFCC09404E6 +:10893000FE4796084413F481AE08DD9E4413F48389 +:1089400096019680A6C89208AE88A689AE09DD9EDB +:108950004413F48596019680A6C89208AE88A6892D +:10896000AE09DD9E4413F4879680AE8892084413C6 +:10897000F4889600AE08DD9E4413F4899600AE0894 +:10898000DD9E4403F48244200055A640541080FE2E +:1089900058108001AE404413F04AAE88A640964677 +:1089A000C9FEDD9E3A6F98BC4463F00EA4305400BB +:1089B0000100C00944122CF4A6088C019600AE08F0 +:1089C0008408D575A430960EC85FA430961EC009E1 +:1089D00044122CF3A6088C019600AE088403D567D8 +:1089E000A4309616C00944122CF2A6088C019600F9 +:1089F000AE088402D55CA4309626C00944122CF13E +:108A0000A6088C019600AE088404D551A4309606C1 +:108A1000C803FA00D54C49FFBDA5A4309636C83628 +:108A2000A430962EC835A430963EC834A4305400E5 +:108A30000200C00C4403F064A6409646C12DA64037 +:108A4000541080FEAE408409D5324403F00EA44099 +:108A500054108400C923A44054108800C921A440A4 +:108A600054109000C91FA4405410A000C91DA44078 +:108A70005410C000C91BA400920FC0CC84013E005A +:108A8000041C840FD5148401D5128406D5108405E6 +:108A9000D50E8407D50C8409D50A840AD508840B21 +:108AA000D506840CD504840DD502840E4413F00E33 +:108AB0008440AC883A6F9884DD9E4403F32284217D +:108AC000AE40DD9E4413F323AE08DD9E4403F32342 +:108AD000A600DD9E3A6F9C3C4463F540B606440315 +:108AE000F544B6204403F548B6404403F54CB6605F +:108AF0004403F550B6804403F554B6A0F102440394 +:108B0000F558B620F1034403F55C3A6F9C04B62097 +:108B1000DD9E3A6F98BC44212E70EFF83A210C008C +:108B20003A2F8C204423F5044443F5024433F503E3 +:108B30003C2FFA824423F505803F3C4FFA853C3FA9 +:108B4000FA843C2FFA815A000204480000904453F2 +:108B5000F500443C0B004403F50898AB382088002E +:108B600018228001D8FB4403F50744100045AE40AD +:108B70004403F50084C1AF80840080208040806081 +:108B800049FFFE244403F5018423AE408400802085 +:108B90008040806049FFFE1A3C1DFA85A6085800F7 +:108BA0000002AE08840080208040806049FFFE0EF5 +:108BB000440007D049FFBF1C3C1DFA84A60858009A +:108BC0000002AE08840080208040806049FFFDFEE6 +:108BD000440003E849FFBF0C84008020804080608F +:108BE00049FFFDF43C3DFA853C2DFA84A658A610B9 +:108BF0005810801D5800001DAE58AE108400802013 +:108C00008040806049FFFDE22E07E95AC81B3C0DF9 +:108C1000FA993E67E95AA78149FFC2F03C1DFA99CB +:108C20005A0802058404AE09D5038409AE093C0D37 +:108C3000FA9949FFE9EB840149FFE8503C0DFA99A4 +:108C4000AF81440005AA49FFBED349FFE82DC0FE0D +:108C50003C2DFA85440FFFEFA650FE46AE503C1D5A +:108C6000FA84A688FE16AE08D562C8334403F50020 +:108C70008421AE404403F5018423AE402E200D1024 +:108C80003C1DFA853C0DFA84CA09A68858210001CA +:108C9000AE88A68058210001AE80A6885821000227 +:108CA000AE88A64058108002AE40840080208040EC +:108CB000806049FFFD8B3C3DFA853C2DFA84A65827 +:108CC000A6105810800C5800000CAE58AE10D52FCE +:108CD0005A080137A620A758845BFE168437FE0E7B +:108CE000FEAEAE20FE568400AE58804080208060EC +:108CF00049FFFD6C4413F5008400AE084413F501F0 +:108D0000AE082E100D103C2DFA853C0DFA84C908D2 +:108D1000A6D0843EFECEAED0A6C0FE5EAE40A6D0AB +:108D2000843DFECEAED0A680FE56AE40EC08840058 +:108D30008020804080603A6F988448FFFD47EC08AF +:108D40003A6F9884DD9EDD9E46100800641324036C +:108D500064230402461FF7FF50108FFFFE564000A9 +:108D60005C08FE0F64030403DD9E4410800064135E +:108D7000240364230402441F7FFFFE5640003C0886 +:108D8000FE0F64030403DD9E40003C084433F20000 +:108D90009210AC184010BC084403F2029230AC4070 +:108DA00040213C084403F2049250AC80DD9E440311 +:108DB000F20A44200055A640541080FE581080014D +:108DC000AE404413F04AAE88A6409646C9FEDD9EEA +:108DD0004423F2069600AE104403F2079648AE40D4 +:108DE000DD9E440232E8DD9E44022F00DD9E4403F6 +:108DF000F20BA600DD9E4413F208AC08DD9E44236E +:108E0000F20A9401A6509646FE479648AE50DD9E63 +:108E1000E608E82544F08D243807800040F03C0047 +:108E20004A003C00080E141A20262C324403F20C8F +:108E3000D5154403F20ED5124403F210D50F4403A6 +:108E4000F212D50C4403F214D5094403F216D506E8 +:108E50004403F218D5034403F21AAE40DD9E92009B +:108E6000E608E82544F08D743807800040F03C00A7 +:108E70004A003C00080E141A20262C324403F20D3E +:108E8000D5154403F20FD5124403F211D50F440354 +:108E9000F213D50C4403F215D5094403F217D50695 +:108EA0004403F219D5034403F21BAE40DD9E920049 +:108EB0004413F050A60858000080AE08DD9E44130D +:108EC000F050A6089637AE08DD9E4413F051A60870 +:108ED00058000001AE08DD9E3C0DFFA9A600DD9EF6 +:108EE00044024000441245103C0FFAB43C1FFA956E +:108EF0003C0FFA9ADD9EC0045A000209DD9E3C0D2B +:108F0000FFA9A6003C0FFA21DD9E3C1FFA21DD9E41 +:108F100040003C084433F1C49210AC184010BC0827 +:108F20004403F1C69230AC4040213C084403F1C8F0 +:108F30009250AC80DD9EFC0044028F700020000F38 +:108F4000001000104403F1C2AE804403F1C3AE40F0 +:108F50003C0DFAB43C1DFA953C2DFA9A49FFFFDA14 +:108F6000FC8084003C0FFAD54403F1C08421AE405C +:108F7000DD9EFC0649FFFFE13C0DFA215A000F136C +:108F80004413F1C19600AE0849FFFFED4403F04AD7 +:108F900044100055AE404413F1C0A6085A0001FF2A +:108FA000D51BFA202E37C54FF1858422840084A179 +:108FB000F18744124000F083F084F086F088F08955 +:108FC0002E47C550B67FF581F382F58A44024510DD +:108FD000804149FFFAD4FC86FC00842049FFC592F9 +:108FE000840149FFE67B84018440842A808080627A +:108FF00080A249FFC1634403F04A44100055AE40CB +:1090000049FFE652C8043C0DFAD8C0FBFC802E177D +:10901000E9255A10FF3E2E27C9CBE022E9039E51D5 +:1090200096484422E1B438310501E260E931FC2080 +:109030008400380105093C0BF4EA842084832E0760 +:10904000C5439401E020E8233C3C027D3C0C027EB9 +:109050003C5C028694898862880288A1A598A5C094 +:10906000A628880742031073405008099769AD5835 +:109070003C5C027D3C3C028688458861A4908C2142 +:1090800094928A029600AE189648D5DAFCA0DD9E2E +:10909000FC005A0801132E100D012E000D005A1865 +:1090A00001048E03D5028E022E100D1296005C1064 +:1090B000800349FFC07CD50349FFC08AFC80FC00C7 +:1090C00049FFC09C5A0802102E07E928C8092E073C +:1090D000E925E6038405E8092E07C9AED5062E0763 +:1090E000C9AFD5032E07C9B0FC80540000FD5A0853 +:1090F00004053C03FF56DD9E3C03E4DFDD9E5A0879 +:1091000004053C03FF55DD9E3C03E4E0DD9E3C0D81 +:10911000FA7DA400DD9EFC00B400920196065A0878 +:109120000109440000643C0BFF5644000168D50768 +:109130003C03E4DD3C0BFF563C03E4DE3C0BFF55F7 +:109140003C13F47D3C03FF5649FFC41E3C0BFF5605 +:109150003C13F47D3C03FF5549FFC4163C0BFF55FF +:10916000FC802E17E920C90A84423E17E9373E27C2 +:10917000E9573E17E93C1010001CDD9EFC0044033B +:10918000F04A44100055AE403C0DFAD8C8122E07E4 +:10919000E9335A0801064402B3F249FFC191840140 +:1091A000844080208062808080A249FFC087D5ED06 +:1091B0003C0DFA998429AE41842149FFC4A33C0D9A +:1091C000FA99842AAE412E27EAE4CA0A84022E17AD +:1091D000C9B18461848380A249FFC070D504840E24 +:1091E00049FFC089FC80FC0049FFC0085A08020EF4 +:1091F0004403F4222E17C9CAA600961FE220E907ED +:10920000C0068E019600D5058400D503440000FFFA +:10921000FC802E07E925842050007F014000800655 +:10922000DD9EFC003C0DFA99842384C1AE41842567 +:109230003E17E9463E67E94349FFE6E82E07E97035 +:10924000842349FFE7373C0DFAB5AF803C0DFAAAFD +:10925000AF802E0004135A08010B84003E07E980FA +:1092600084003C0E01113E000413D51A2E07E9803C +:109270005A0003082E07E926C80484043E07E98043 +:109280002E07E977C80A3C1DFA7DA4485CF0803CB3 +:10929000E9055000FFC4D50284003C0E0111840191 +:1092A0003E07E97984003E07E982FC80FC003C0D22 +:1092B000FA99A601540000FD5A0809162E07E98004 +:1092C0005A00030584043E07E9802E07E977C80B9E +:1092D00049000EE75CF0003CE90649000EE2500050 +:1092E0007FC4D50284003C0E011184013E00045469 +:1092F0003E07E93749000EA849FFC96B3C0DFA99B2 +:10930000A6415A180807842AAE4149FFE67FD511C5 +:109310008429AE41842049FFC3F53C0DFA99842A83 +:10932000AE4149FFE67349FFF359840E49FFBFE39D +:109330003C0DFAAA8421AE40FC805C000003DD9E57 +:10934000FC402E17E9575A18020B2E17E937C907A8 +:109350002E17E9808E225C108001D50284202E47D2 +:10936000C5433C9C027E95A18EC19FE184A084618F +:1093700044A2CEB052800000E0A6E81BD71740F20E +:1093800084084024BC0050F7800240F4BC00A49044 +:1093900002F780008A4F9693E00238251509E90309 +:1093A000E048E8045A18010384628CA19768D5E567 +:1093B0005A18011F92014422CEB084208122FF421C +:1093C000E027E81638610511E006E80740A09000A4 +:1093D00038F12911E00FE908E0C5E807998C3864F5 +:1093E0009911E0C5E80284628C219648D5EA800391 +:1093F000FCC084204422E1B4380105098C215A18AC +:1094000008FDDD9EFC2080E0A60080C25A080420F2 +:109410008401AE383C0DFA99A60149FFFE6849FF68 +:10942000FFEA3C13F4C9E62AE8058C213C1BF4C989 +:10943000D51584003C0BF4C9A470E639E805AE38B4 +:10944000840049FFFFD88400AC30D508840049FF70 +:10945000FFD28400AC303C0BF4C9FCA0FC013C0DF5 +:10946000FA99A60149FFFE43F081F1014402B3B02D +:109470004422B40449FFFFC82E17E98084003C0B46 +:10948000F4DA3E07E941C9033E07E90184003E07DB +:10949000E9473E07E9253E07E93E440FFFAA3E079C +:1094A000E9353C0DFAAA8421AE40FC81FC202E67F0 +:1094B000E9252E07C9CB80E1E0C02E17E917E903A3 +:1094C0008E0197805A18011849FFBE985A08021455 +:1094D00084002E17C5439449E001E817838794411F +:1094E000BA09BB0B884188238C01A4489600964991 +:1094F000AC50D5F04402E1B44410FFFF38501901DC +:10950000D1048CA1385019092E17E9014000980E9A +:109510009606C81D2E27C5439491E002E812838762 +:109520009481BB0A8C01991ABB0996008862A558E0 +:109530009769AD60BC0BA4D8884496D9ACD0D5EB64 +:1095400084014000180CFE0F3E07E901FCA0FC421C +:109550002E27E9255A28FF044800011A8101F081CD +:109560004412D3FC4402B37749FFFFA28048440071 +:10957000FFFF8420A852A8132E07C9C2E610E804F2 +:10958000521000109648E61180A0E902FAA085402A +:109590009628B61F80EA800A80CA4492D5FC2E27FE +:1095A000C5433C3C027F41E10408E0DE4EF2008B03 +:1095B0003C0C027E94B199023C0C027CA5608802AE +:1095C00004FF8000A400FF4C42503C7380059204CD +:1095D0009601AC203C0C027E88628802A5003C0CFF +:1095E000027D8802A4009A209603AC18A418960362 +:1095F000E140E805A41880E640A000113C0DFA7D8A +:10960000A4D8A40596DBFE02E060E82C2E07E9371B +:109610005A0801292E00043AC81D380498003C332A +:10962000E4DC8C019600E26038049808E8213C0CE8 +:10963000027E3C3C027D88028862A4009601AC1840 +:1096400084003804980884013E07E9003E07E98653 +:10965000D50FF183F28249FFBDD1F202F1035A081E +:1096600002DE38049800C0048E01380498083C3C9F +:10967000027E040400028862A518E204E804A4182B +:1096800014040002A51804040003E280E804A418EE +:1096900014040003F001A6C13C0DFA7D5A380904F8 +:1096A000A403D502A4043C3C027F8843A490969373 +:1096B000E002E80484413E27E93C8CC197B048FFB2 +:1096C000FF7094799919E2E2A560976BE826CF07BD +:1096D0008C228823887EA448970BD50B9F919F0AE4 +:1096E000884788834C73400EA4609491970B8862DE +:1096F000A458964B88248825964B44200050D52E9C +:109700008C22882394918862A520A448A49897234A +:10971000964B96938824D51D4C71400A8C22882341 +:10972000A448968BA458964B8822D5E69F0A506F82 +:109730007FFF9ABA88834C733FD9A5A09D0A88837E +:1097400094918862A460A49897B3964B96938826C8 +:1097500088228825964B442000784E170007E04168 +:10976000E80484213E17E93C2E17E9265A18010720 +:109770003E17E93C84203E17E9803C1DFA99A64932 +:109780005A18090649FFFDDE3E07E957FCC2FC20D6 +:109790002E27C9CA441000FF4020880C4413F4222D +:1097A000FE93A6489690965FC1038E2196482E3769 +:1097B000C9CB84C0E223E9049E59964884C1A7C05E +:1097C00084A14042840CFF3F972296E0AEC04C71CA +:1097D000C003C60D84014C31000C88204000040CED +:1097E000FE279600FE1D5C000001D5028005FCA04E +:1097F000FC2184003C0BF4DA3C0BF4EA120F8003EA +:109800003E07E93C3C0DFA99A6015A0804222E07AE +:10981000E980C8284402B33149FFFFBB80605A0881 +:1098200001222E17C9CB2E27C550500F8006FE8C63 +:1098300096904412D24049FFBFF72E07E985C8042D +:109840002E00043AC0038401D5078403D5052E07F2 +:10985000E937C80584023E07E980D5042E07E9856B +:10986000D5F22E07E9805A08020584003E07E90078 +:109870008400444000C880604452D5FC2E17C54384 +:109880009449E001E8233C6C027C944188C13C2C63 +:10989000027EA5B0884197B1AD902E70043A3C6C21 +:1098A000027E3C2C027DCF0788418826A448964939 +:1098B000AC50D5038822AD083C1C02868820AEC877 +:1098C000383280088C019600D5DAFCA1FC202E37B6 +:1098D000E937CB59A6005A0802572E17E9575A18EC +:1098E000024E2E57C5433C7C027F9569442075305B +:1098F00084818003E065E81994598827A58897B387 +:10990000E0C2E803A4889693A58897B3E086E803AD +:10991000A5089723A448964B5EF0FF9CE8038C01B2 +:1099200096008C6196D8D5E75EF17F9CE81E843660 +:10993000FE8C40211056E455E918C0172E07FEA8EA +:109940008C019600E60B3E07FEA88400E9113E0755 +:10995000FEA884013E07E9372E07E9805A08021461 +:1099600084003E07E980D50F84003E07FEA83E072D +:10997000E93C84003C0BF4EAD5065A1801053E1771 +:10998000E937D5EBFCA0FC4080C1A64180E05A1825 +:10999000041C9E34E604E91E5A600C1D2E07E98063 +:1099A0005A0003192E07E9285A08010784003C0FC2 +:1099B000FAD649FFEF09800749FFFB104402D3FCA8 +:1099C00049FFBD03D5072E17E9805A10030449FF4C +:1099D000FB053C03F4EA4412D5048C013C0BF4EA89 +:1099E0003C03F4DA8C013C0BF4DA800749FFFDB14B +:1099F00049FFBC045A08021549FFFBF7C8112E178E +:109A0000E97DC10E3E07E92C49000E882E07E94288 +:109A10005A0801043E07E91984003E07E97D2E003B +:109A2000043A5A08012049FFBBE95A08021C4900C0 +:109A30000546852080E03E07E93C3C9BF4EA5A0855 +:109A40000109840049000FC13E7004133E90043A9E +:109A50002E07E9535A0801073C03F4DA8C143C0B37 +:109A6000F4DA2E07E93C5A08011784003E07E94161 +:109A700084002E17C9CB4432E1B480809680E24145 +:109A8000E805384181098C01D5FA4400005049FFAE +:109A9000B820D5192E77E9375A7801169E34E60298 +:109AA000E9124402D5043C13E3174422B371490080 +:109AB00004A35A080209FA0149FFB80B3E77E93CB2 +:109AC0003E77E9863C0DFA9949FFFF02440FFFAA51 +:109AD0003E07E9359E34E602E810440000FF2E10F0 +:109AE000046449003BB284003E07E93C84003C0B1F +:109AF000F4DA3C0BF4EAD5065A68020584013E0705 +:109B0000E93C2E07E9205A0801063E07E93C3E07DA +:109B1000E937FCC0FC0084003C0FFADB3C0FFAD6AE +:109B2000840149FFE0DB4403F04A44100055AE4095 +:109B30002E000D123C1DFADB8C01E220E80A8401A4 +:109B4000844080208062808080A249FFBBB7D5F12D +:109B50002E07E917C8154402D3FC49FFBC363C0D5B +:109B6000FA994412D50449FFFCF42E07E93CC808D1 +:109B70003C0DFA99A60149FFFABA49FFFA4A440393 +:109B8000F04A44100055AE4049FFE08E8040C809BD +:109B9000840180208062808080A249FFBB8FD5F540 +:109BA0002E07E93CC81C2E000D12E603E8183C0DF8 +:109BB000FA998424AE4149FFE2293C0DFA992E1707 +:109BC000E96849FFFEE23C0DFA998426AE412E0772 +:109BD000E93CC8053C03FF5649FFFA1BFC80FC44E6 +:109BE00044212E78B1843A2114003A2F9420442144 +:109BF0002E88387F82023A2114003A23142094C21E +:109C0000442271403843020238510C002E37E92DAE +:109C1000442FFF38FED4976896D984404461228847 +:109C2000981694010290000038011C008C414204F7 +:109C300080244000140E8803029200009603400026 +:109C4000041688091A0200015A2A88ECFCC4FC4553 +:109C500044212E78B0423A2114003A209420442125 +:109C60002E9844728F70B1863A2114003A23142042 +:109C700081200023800F8400120F80033810A60279 +:109C8000500F800600338010924149FFBDCD500F28 +:109C90008006381326020023800F0033801049FF0E +:109CA000BDC3FCC5FC072E17E92D440000C8FE0CFF +:109CB000120F801B44028F7084A1A6C2A7038400E8 +:109CC000F081F082F083F084F085F086F088F089EE +:109CD000F08AB67FF58744021B90501F80364422DD +:109CE000AD7049FFF44CFC87FC42FD30F281F383F8 +:109CF00049FFBA845A00020545E000A0D50345E0BB +:109D000000782E07C5502E57C54F8E0150A2FFFF79 +:109D1000F0828027049F8001F001F203400480015B +:109D20009600E202E85D09C48001424E1424080056 +:109D3000800198A095D13883091184418068C006BC +:109D400098B722317FFF84428868E00AE80788E6F6 +:109D50008C4122738001969088675CFE0002E91BAB +:109D60009BE540F380004077840838F33D11886F0D +:109D7000C8038C41D50740F31C008C4222F7FFFF3B +:109D8000886FE00A9690E80788E68C41227380018C +:109D900096908867F70240FE1C07E818888588803F +:109DA00095E1384311118864C8038C41D506993771 +:109DB0008C4222427FFF8864E00A9690E80788E69A +:109DC0008C41220380019690886040218856E4509F +:109DD000E903E51AE80740FF0C07E89FD503840074 +:109DE000D5028401FCC2FC40846044407D0084C2F2 +:109DF0002E17C550E261E86D2E17C54F44507D0007 +:109E00004271842495F940A0840988E0850080454A +:109E1000541400FFE22AE8113893A1114E92000C6D +:109E2000E122E907E0A980294012BC1B8122968B20 +:109E300080A280498D01D5EDD40588A2405298B604 +:109E400096AB84202E87C54F40940409E2294271C5 +:109E5000A024E80C88E195F988E022538000C5032E +:109E60008AA2AD788C219648D5EE44507D00804979 +:109E70008025E248E81340A3880038A029114EA2AB +:109E8000000BE141E906E0AA40553C1A8141966B7E +:109E900080A1802A8C419690D5EDD41488A140529F +:109EA00098B6966BD50F80A94251887394A98840C3 +:109EB00022510000C5038AA1AD5050248001549165 +:109EC00000FF2E27C54FE322E9EF8C6196D8D5918C +:109ED000FCC0FC46B18881018142838084208006D9 +:109EE000FA40490047E550040006F0855004000799 +:109EF000F0865005000684A08481F0872E07C550A7 +:109F0000E080E854500500078460F0842E07C54FB8 +:109F1000E060E849802342120073380E0511E40D19 +:109F2000E93F84E038231D119678E040E836F205D9 +:109F30008006F283F20605EF8004F282F20785279D +:109F4000F281E2298E02E817F20302F000078F2166 +:109F500012F0000808F17FFFF283F202549480FFB0 +:109F600018F17FFFF282F20108F17FFFF28118FF02 +:109F70007FFFD5E82E07C54F804342220073380E7D +:109F80000901E6A83834040838031D0938450408D7 +:109F9000E8078CA19768D5048CE15A7808C58C61D4 +:109FA00096D8D5B58C819720D5AA8005FCC6FC0231 +:109FB00044212E7880C33A2114003A2F9420383F50 +:109FC0009A024412714095B288C1843EA7303C5336 +:109FD000E2BA97204201847380439A539649E2255E +:109FE000E8103860091108110001FE744010900E4D +:109FF0004E140003FE4A5EF08051E9F08401D50260 +:10A000008400FC82FC424647FFFFF28350220FFF90 +:10A01000814084618001448200003C1C017BF2820B +:10A020002E47C56DE2834EF3009B8381FAA8BC10D6 +:10A030004460003054427FFF9522424194738888E7 +:10A04000F203025200099769F5810252000840F2BA +:10A050008013A767A7E6BC1254427FFF95224242B5 +:10A060009873BD1288885452FFFF956A42539873C3 +:10A0700088A884C05A28014E844397F040738937DA +:10A0800097F8549480FF844A39C21E02429488246F +:10A0900041CE240D55CE03FF5BC3FF12F20141C137 +:10A0A0007000804339E571012FC7C54F422370739B +:10A0B0008382F20241CE080039E0710938729E02B3 +:10A0C0008CC14093A40D549483FF5A93FF0B2E77B9 +:10A0D000C54F892FFFF4389525018AE338901D0973 +:10A0E0005A6824CCD5383872A6028CC14073F00D62 +:10A0F000547383FF5A73FF0C2E97C54F88EF42931A +:10A1000024248B233895250138901D095A60242476 +:10A11000844397F0409388F7549480FF97F8844ADB +:10A1200043C38824387226024073F00D547383FFB2 +:10A130005A73FFDB2FE7C54F80434223787383C2F6 +:10A14000F20241EF0800F20139E5790188E239E0D5 +:10A150001D09D5CA8C6196D848FFFF64802A49FF43 +:10A16000BAF6FCC2842080612E27C54FE222E806A1 +:10A17000383005098C219648D5F82E17C5508480B3 +:10A180002E27C550E222E81184402E37C54FE24306 +:10A19000E80980A242508C738C4138401509969092 +:10A1A000D5F58C219648D5ED2E17C54F84602E2706 +:10A1B000C54FE222E81384402E47C550E244E80B25 +:10A1C0002E47C54F80A1425110738C41383015097C +:10A1D0009690D5F38C219648D5EB2E37E8882E172C +:10A1E000E889421188738440382005092E47E88A9F +:10A1F0002E37C54F2E17E88B42120C7338200509F5 +:10A20000DD9EFC0051FFF5C880C0C936C0463C3316 +:10A21000E2BA442237FCB186444003E89609E203DF +:10A22000E80C0201068A0A510001FE2440001416BF +:10A23000380305098C21D5F3800649FFFF95501F8F +:10A2400085288006844149FFFEDF800649FFFDCD59 +:10A250008006501F8528844049FFFED6B042B08456 +:10A26000800649FFFE38F081B0428006B084F301D9 +:10A2700049FFFD3CD51044024510441237FCB0861E +:10A280008460848149FFBAEDB006B042B084806634 +:10A2900049FFFE8FF081D502F0814402451044123F +:10A2A00037FC49FFBA54F00151FF8A38FC80FC4268 +:10A2B00084C084013C6FFADB3E67E93C810649FFBC +:10A2C000F54581463C6FFAD6B6DF812680E65A789E +:10A2D00004112E07E970842349FFDEEC84003C1D45 +:10A2E000FA9980404432B38F49FFDFC98481D51386 +:10A2F000800749FFE689F0813C1DFA998403804775 +:10A300004432B38F49FFDFBB2E07E970842349FF36 +:10A31000DED1F40188899620F081F0014C90006034 +:10A3200049FFEA5249FFBD38B41FE209E831800A0B +:10A3300049FFE66AF082B41F8C019600B61F4C6597 +:10A3400000038500500400019600F0838028800AF5 +:10A3500049FFFF595A0801162E07E95E5A080112F3 +:10A360003C0DFAB5A78097B05A6801FE2E07E97038 +:10A37000842349FFDE9F4400007349FFB3AAD53907 +:10A38000800AF10249FFFC2D80CA048F8003440338 +:10A39000F04A44100055AE402E17E9703C0DFAB556 +:10A3A0005A180311A6405A1801FF44020000441233 +:10A3B000000244224510FA62FA94FAA049FFF181A2 +:10A3C000D504A6405A1801FF50048001549000FFA4 +:10A3D0003C0DFAAA84218147AE40D5A08CE197F8C4 +:10A3E0005A70050448FFFF75840049FFF4AF84C02C +:10A3F0008006FCC22E37C5F05A38015FFC003C3D98 +:10A40000FA99A6D95A3009045A38040EA1022E67C7 +:10A41000E9483C33E315404218972E57C637972139 +:10A42000A003D51F2E47E9703C33E3145A480411AA +:10A430002E47E91C523180FFFF1C2E37E94F2E605A +:10A440000D2840420C96524200FF96E1D5032E673C +:10A45000E92DB4802E57C636404218979721A001A7 +:10A4600040001817E2239999960197B1E8048A6190 +:10A4700096D9D50284605CF302018026E90344107A +:10A4800002009649E281E904A6108C01D504E2603D +:10A49000E8FC8400AE10A610E2A08401E80C840061 +:10A4A000AE102E00045B8C013E00045BFA0549FFF0 +:10A4B000B3108402FC808401DD9EFC0084003E0712 +:10A4C000E95384003C6C027F80608020804099705A +:10A4D000A52897235EF20064E9038C418C21A5280E +:10A4E00097235EF27F9DE8038C618C418C025A08B1 +:10A4F00090F05A3048045A18480584013E07E95341 +:10A5000084003C4C027E2E10041280609960A56885 +:10A510005CF28050E8078C6196D8E664E9038424F5 +:10A5200084408C025A0890F4E62480013E10041204 +:10A53000E90684003E0004128401D511C903E649EE +:10A54000E80E3C0DFA99A6015A08060684043E005E +:10A550000412D5048C213E1004128400FC80A61144 +:10A56000A6909CC18A6296D8E6634EF2009FE632BE +:10A570004EF3009CFC4184E040A1040894C13C4C93 +:10A5800002788127838780C780A750A50240508129 +:10A59000824040351C008864A4D896DBE466E90656 +:10A5A0008CC1887C97B041C1801140341C00886404 +:10A5B000A4D896DBE466E9068CA188699768409187 +:10A5C0008011507380205A7A40E640FE19F64034DC +:10A5D000947684E040978013149F8001838783C71B +:10A5E0004091801340351C008864A4D896DBE46653 +:10A5F000E90A04FF80018A6F4E340003FEDA887E88 +:10A6000041E1801340341C008864A4D896DBE466E2 +:10A61000E9088A694E340003FEDA887C41C1801360 +:10A62000507380205A7A40E0E6D0E941E6B0E93F35 +:10A63000406F18D6E4D9E805405E14B6E4B9E939AC +:10A64000C21694CC8843949198E28E428844A558CF +:10A65000A590976B97B3E0C5E805A4D8A4909A9A03 +:10A66000D504A490A4D88A439691D503442000FF32 +:10A67000E60FE81F944C8801940198608C02888052 +:10A68000A4C8A42096DB9603E003E804A408A46011 +:10A69000D503A420A4488A015CF100249601E809AE +:10A6A0005CF00024E806D5038400DD9E8400D50319 +:10A6B00044008000FCC1FC008441842080628082D0 +:10A6C0004400200049001DF1FC80FC0080C0440FC4 +:10A6D0008000E262E90F9514A17588819521888533 +:10A6E000A560976BE005E803A52096238C41969022 +:10A6F000D5F1FC805A3FFF044800010FFC4684203E +:10A700004452CF5080C13862860A8C215A1810FDFD +:10A7100084BF8420F58180A1E2A4E80FA191386371 +:10A720001501DE09A19238631501E226E804D3037E +:10A730008026F5818CA1D5F18100941AF084A015B2 +:10A74000F28338900E00F0019402F085F003F104DA +:10A75000A0058820A689E3224EF200C84024801379 +:10A760009CD140A18013F3015A37FF1DF3058803E4 +:10A77000A6C0E243E904A701E282E806E343E91246 +:10A78000A681E24AE90FA7C2A68BE247E8048EE160 +:10A7900097F9D509A783A60AE2C0E8078CC1FAF3A6 +:10A7A000D507FAF384C3D504447000FF80C7B048CE +:10A7B00084003800A4089A3EE406F0824EF3009329 +:10A7C0009770973855C480FF804580648008803C2E +:10A7D000F587F48649FFFF7B5EF0003CF406F50741 +:10A7E0004EF30081501E0001800896488045806429 +:10A7F00049FFFF6D5EF0003CE975B0488401380008 +:10A80000A40894744020A4008400882A9491944958 +:10A8100080A680808060E2E5E91905C4000540F06B +:10A82000080040FE3C008CA102F7800040F7801138 +:10A83000886F40F0040040FE3C005000002002F70A +:10A84000800040F78011888FD5E7F0028C0140101E +:10A85000040A88618881401524018540405180B6F2 +:10A86000404200969449838A800AE2E6E91C05E4A6 +:10A87000000540F10400403F080040FF3C00A4D820 +:10A8800002F7800096DB40F780118A6540F790015F +:10A8900042018C7343C7BC7342A1BC738CC150216D +:10A8A0000020D5E484204900049580C08420801CC9 +:10A8B00049000490C8028401CE0284C1FF84443060 +:10A8C00000644003040942050C734000181740243B +:10A8D00088085EF000654412CF504001BC1A380071 +:10A8E000880A8D2148FFFF34A64844000064444292 +:10A8F000CF50E222E80CB0C838318400C3063832A9 +:10A900000602E060E802961B8C21D5F45EF000465A +:10A91000540780FFFCC68400DD9EFC4484602E4703 +:10A92000C6D444628F7080E39758E2A4E806995E2B +:10A930008C611072818CD5F9A6CA5A3001072E306D +:10A940000409CB08A6C8CB068400AE0884004800E2 +:10A95000008B8120A005FA6E80E1504F801F80207F +:10A9600084A080C249FFBA72000F801F847FF083E9 +:10A9700084008020F4039680E244E810A17196815F +:10A9800038528101DA09A0B238210101E2224011D6 +:10A990003C1B40303C1B8C01D5EE5A37FF1DA0B745 +:10A9A000A036945A38810E020423000838000E02A3 +:10A9B00038510E02C55D3CADFA8A00250032FE8496 +:10A9C00040011417F0820005003342040024405077 +:10A9D00014B7D54F84A0F58280058025D50EC078A8 +:10A9E000001F0032B45FF401FE8C40110037002FCD +:10A9F0000033FF1440020017A6B85A20010544A0F6 +:10AA0000003CD502FB58F2028A4180224E2400030A +:10AA1000FE52E341E9079AA84E240003FE92E34266 +:10AA2000E81EA0B238210D01E659E9138AA04E5460 +:10AA30000003FF6AE0A14012BC1A5EF08190E809B1 +:10AA4000800980278046F40349FFFE565A080143D7 +:10AA5000440000783C0802058401D5083C0002054A +:10AA6000C0058E013C080205D535AE38D533F582D8 +:10AA7000A0353DEDFA8A8820A60BA68AF0848400D2 +:10AA8000F081B61FF404E282E9ABA70900A08000C0 +:10AA9000F485F405E28AE91A008F0002808A04F442 +:10AAA00080054241207340820408890F028400001F +:10AAB00040840011E51EE908B49F8C01888AB69F86 +:10AAC000F4018882F4818D41D5E58C41D5DC80206C +:10AAD000D594FCC4FC0004000015844480208461EB +:10AAE000848584A049FFB712FC803C1DFFAEA00303 +:10AAF000A44CE201E90684003E0004548402DD9E79 +:10AB00008400DD9E3A6FAABC84E0EFFC3C2DFFAED2 +:10AB1000808180C780A78545B5244E9200118F247F +:10AB2000E722E90D048200070490000238F4A10135 +:10AB300000810006E30FE80310A18002B5245084D1 +:10AB4000FFFFE702E9035A9804192292000702F175 +:10AB5000001EE12FE9120281001FE109E90E229295 +:10AB6000000602F1001CE12FE9080281001DE10945 +:10AB7000E9048CC197B080E58CA19768504200FC35 +:10AB80005A580ACC2EA7FEDDCE0684008420AE1AC9 +:10AB90008081D51FA61A5A00051B5A68011450055A +:10ABA0007FFFE602E8042E57FEDADFF0440000FCE7 +:10ABB0004213807384012240800622108007AE1A5F +:10ABC000D50884038420AE1A8081D5038420808137 +:10ABD0002E00043A5A0801048405AE1AA61A5A082F +:10ABE00001633C9DFFAC005480005A5801093C5D54 +:10ABF000FFAD025280098EA19B2C97230054800147 +:10AC00005A5801093C5DFFAD0252800A8EA19A6933 +:10AC1000964B00548003008480025A5801403C9DAA +:10AC2000FFAD025480094E83001E50F2FFFF025414 +:10AC3000800251C2FFFF84A2408795164282707342 +:10AC400040443C970284800A029480038F018F2144 +:10AC5000405414B64250A4734012A0379723964B29 +:10AC6000D52251C2FFFF0254800351E2FFFF84A2AC +:10AC700040FE15F642F278734047F09702F4800ADE +:10AC80000294800250F7FFFF8F21405794B6425044 +:10AC9000A4734012BC379723964B5A88010580A4B1 +:10ACA00080818025E745E81944F0ABB838A7A800B3 +:10ACB00040F53C004A003C00060C0C161C005A08EB +:10ACC000010BD5105A00010CC80C8403D50BE60209 +:10ACD000E808D503C806D5068400D5048402D50249 +:10ACE00084043E07FEDD8E01E60484A04EF2014896 +:10ACF00044F0AC003807810140F03C004A003C00C1 +:10AD0000080056008A01760284A03C5FFFB53C5FD4 +:10AD1000FFB484A184003C5FFA23445FFFAA3C0B8C +:10AD2000FF6C3E07FEDC3E07FEDB3E57E8903C4BE7 +:10AD3000FF663C1BFF673C4BFF643C1BFF653C4BC5 +:10AD4000FF623C1BFF633E77FEDA3E07FEC23E0712 +:10AD5000FEC0480001172E07FEC20251001A3C4BEC +:10AD6000FF62E2053C1BFF63E8048C013E07FEC264 +:10AD70003C07FF649BC44E740003FFFA3C57FF6519 +:10AD80009A294E040003FE02025100198807E0A030 +:10AD9000E80484013E07FEC03C97FF664004900132 +:10ADA0004E040003FE023DC7FF67407E04014E745F +:10ADB0000003FFFA02A100059978E3454EF200E294 +:10ADC000A5562E87FEDBE205E90DE124E806854065 +:10ADD00058540002812AD509545400018540852128 +:10ADE000D50480A88542852002F10007E2EFE90D35 +:10ADF000E03CE80458528001D508974E8D219768B1 +:10AE0000549480FF58A500013CFDFFB488EF3C7FBF +:10AE1000FFB43C7DFFB588073C0FFFB55A98020E82 +:10AE20002E07FEDCC81D84013E07FEDC3C0DFA2324 +:10AE300094023C0FFA23D5255AA803132E07FEDCF3 +:10AE4000C80F3C0DFA239402580000023C0FFA236D +:10AE500084013E07FEDC84023E07FEDBD5124C5423 +:10AE600000112E77FEDCE6E7E80C3C0DFA238CE1BE +:10AE70009402FE2F3C0FFA233E77FEDC3E57FEDBAA +:10AE80003C4BFF663C1BFF67D57C2E57E8905CF27D +:10AE90008020E811A410A5114000400840101004C3 +:10AEA0005202801F4000800E9606C805440FFFAA7C +:10AEB0003E07E890A410920C9606C0632E07FEC3CE +:10AEC0005A08012A2E17FEC20201001AE220E823C6 +:10AED0002E17FEC10201001BE220E81D2E07FEC056 +:10AEE000C81A3C07FF623CF7FF5E021100198A0F87 +:10AEF0004E040003FE02E001E80E3C07FF633CF74E +:10AF0000FF5F8A0F4E040003FE02E001E8048403A1 +:10AF10003E07E8902E17E89084003E07FEC15A10C5 +:10AF200003313E07FEC32E07FEC0C82B3C07FF635C +:10AF30000211001EE001E91D0211001FE020E919C5 +:10AF40003C17FF620241001CE024E9130241001D8E +:10AF5000E081E90F2E57FEC20241001AE2A4E81177 +:10AF600084813E47FEC33C1BFF5E3C0BFF5FD5095F +:10AF70008402AE1AD5063E57FEC3D5033E57FEDD0A +:10AF800084003E07FEDE3C03FF6CCE052E10043A23 +:10AF90005A180115A454E201E8058C013C0BFF6C22 +:10AFA000D5272E00042BC80684013E07FEDE84044C +:10AFB000AE1A84043E07FEDDD51B2E17FEC35A18B9 +:10AFC000010E2E17FEC10241001BE224E8058C2170 +:10AFD0003E17FEC1D5033E67FEC3A454E201E90556 +:10AFE000440FFFAA3E07E89084003C0BFF6C2E271D +:10AFF000E8905CF10020E8218C4C96908401E65E9C +:10B00000AE18AE998401E905FA2E49FFC437D5047C +:10B01000802249FFC433840349FFC4368400EC0412 +:10B020003E07FEDD440FFFAA3E07E8903A6FAA8470 +:10B030004400006048FFAD4DEC048400AE183A6F48 +:10B04000AA84DD9E3BFFFE3CEFFC4412B4908400DA +:10B05000442FFFAAAE08AE0AAE8984203C1FFFB57C +:10B060003C1FFFB43E17FEDC3C1BFF6C84213E27D7 +:10B07000E8903E07FEDD3C1FFA233E07FEDB3E075D +:10B08000FEDE3E07FEDA3E07FEC33E07FEC23E0777 +:10B09000FEC13E07FEC0EC043BFFFE04DD9E3C0DFE +:10B0A000FFAEA404DD9E2E07FEDEDD9E84002E177B +:10B0B000C54944328F7080809680E241E8069883CB +:10B0C0008C01104103ECD5F94400003C3C0BE49D9D +:10B0D000DD9E3C13E394AC40DD9E4402CF9084207F +:10B0E000AE40AE41AE42AE43AE44AE45AE46AE47D4 +:10B0F000DD9EFC4046F7FFFF50F78FFF5A180244D1 +:10B1000080A0808084E0B4645A38022280C0852008 +:10B110004C748019B4665A38021622120006223383 +:10B1200000069ACB4E340003FEDA2212000722F307 +:10B1300000078A2F4E140003FE4AFE4C42118C7306 +:10B1400081E18D21506300FC5A980AE48CE1504261 +:10B1500000FC5A780ADA500009D8B4655A3802104F +:10B16000A0EFA11594DA8864A718C414A7195A404F +:10B170000F12A71AC40FA6DB5A30230D505280FCC1 +:10B18000D8EDD50684003E07FEE03E00046584004D +:10B19000D50284012E3004654420FDE7E04FCB0C3E +:10B1A000E90C2E17FEE08C219648E6233E17FEE0C0 +:10B1B000E9098421D505E8FE84203E17FEE03E1013 +:10B1C0000465C00684003E07FEE03E000465FCC046 +:10B1D000FC418501B61F8081812083818540400428 +:10B1E000A001E320405E28014C5780234074A0005A +:10B1F000E2E9400E28004067800040037C0892E1AD +:10B20000FFC792C18007802680478066F48149008D +:10B210003E25F401E281E9094C124005B43FE220E9 +:10B22000E90481078146D5DC81278386D5D9E602EA +:10B23000E8DE8008802AFCC1FC204430271080C052 +:10B24000FE5C220000284020885622130050FE1C7D +:10B2500040100436E02222430000E85340F011F68B +:10B26000E04FE85144500078FA388083980D9001FF +:10B270005CF00051E904523000A0D50480605A000F +:10B28000280552700078D5034470005038330D11F2 +:10B2900038731D11FEE440319C76E043E8039F4182 +:10B2A000D504E062E8349C41E0A1E8E14C00800371 +:10B2B00080A15CF28051E904521280A0D502802561 +:10B2C000507280285CF38051E903527280788A6260 +:10B2D0004E340003FEDA3813051144402710FF0CEA +:10B2E00038131D11404204969AA24E240003FE9288 +:10B2F000E062E90DE043E90AE2054002BC1AD50725 +:10B30000FA18D50544000078D5028005FCA05CF051 +:10B310000051E905523000A0B661D502B6015010C7 +:10B320007FD85CF08051E905520000C8B602DD9E6E +:10B33000B622DD9EFC0196CB9683903090108A0158 +:10B340008A43FE0442010873FC81A6493C43E3059D +:10B350005A1001049660D502A6522E2004545A2891 +:10B360000103A65C22F00003E02FE80484013E07FD +:10B37000E967DD9E3C2DFA992E37C5FEA6915A202D +:10B38000060496D9D5032E37C600A6015A08010433 +:10B390002E37C5FF2E07E9145A08010444300078FF +:10B3A0002E47E9522E07C6042E27C5FDE280E93458 +:10B3B0002E07E9545A0801384020080C3A6FA83C7F +:10B3C0008A43EFFC969104A08002B521047080149A +:10B3D00084A044600480408514004004940002F47A +:10B3E0000000993DA400A460FE1C42013C7388014A +:10B3F0002E17C5FD8CA24010040D964912140000B2 +:10B40000021400002E87C5FD4010A00C8A01960191 +:10B41000AC20DEE2D5058C813E47E952DD9EEC048E +:10B420003A6FA804DD9E3A6F9ABCEFFC2E07C5E781 +:10B430005A0001048401D55884003C0BF4DF2E0728 +:10B44000E967C0052E07E93B5A0801F64617FFDDFC +:10B45000445225B050108A508460442227F0982925 +:10B460003C4C027894018804A40096035EF07FC9E6 +:10B47000E80EA6288C019600AE28A628E60AE90860 +:10B480003C03F4DF8C013C0BF4DFD502AEE88CA169 +:10B49000DAE73C03F4DFC8052E07E93B5A0801CC84 +:10B4A00084003C0BF4DF445225B0441227F018020C +:10B4B0008001D9FE2E07E93B5A08010B2E00045AE1 +:10B4C0008C013E00045AFA0649FFAB03D5092E0051 +:10B4D00004598C013E000459FA0449FFAAFA840079 +:10B4E0003E07E93B8402EC043A6F9A84DD9E3A6F92 +:10B4F000AABCEFBC84C0126F8018126F8019958CA3 +:10B500004083000050647FFF5074001040A300137C +:10B5100050640001F28B97F997B1C906C0145A081C +:10B520000F1680CAD51350947FF0409480135A1898 +:10B530002307C00E5A080F1080CAD50DC00E5A0836 +:10B540000F0ED50B81468127D5098127D507814666 +:10B5500080E9D50480E9D50280CA3C0C01EE956AE9 +:10B5600088A041C40408A668A62941E504084C1037 +:10B5700040233CAC027940057000A54040057800AE +:10B58000976BA4409431880A964BA4009A6996035D +:10B590004E140003FE4AE0A1E9079A284E04000376 +:10B5A000FE02E0A0E8082E00042EE607E8048C0165 +:10B5B0003E00042E3C0C02752E87E92DF0823C0CD7 +:10B5C0000273F08340048408F0849439F085943148 +:10B5D000F0862E07E93B2E900433F081440000C82A +:10B5E000420400245010005050007FB0F088440FF7 +:10B5F000FF3842040024F187F0898420F202F0032E +:10B6000097C840011C1AF2043850701138600801C4 +:10B61000F205126F801B125F801A38600801F20673 +:10B62000126F801C3860780138000801126F801D8D +:10B63000120F801ECF0840F2A1F65EF78032E803B9 +:10B640008401F081B00CB14D38A0051184C52202EF +:10B650008000F207F58AE040E904F208E002E81011 +:10B66000F20988024E040003FE02AC285A78010B4E +:10B6700022FF801A5EF7A7114093BC1AD5038400FD +:10B68000AC28F00A8CA2220000004E040003FE0247 +:10B690008EC1880A97B040A00011CEDAB00C38A055 +:10B6A00005095A1001048421D5AA000F8004F10B6A +:10B6B0003E07E93B3E900433220F801822FF801999 +:10B6C0005A10010A5A3001082E0004335A000109A9 +:10B6D0008400D50A8A0F96035EF000A0E9F6840183 +:10B6E000AE2044008000EC443A6FAA84DD9EFC004A +:10B6F000842084618041808344005640490015D5F0 +:10B700005410007F84415810808080628082440001 +:10B710005640490015CAFC80FC00842084618041A9 +:10B720004400DAE08083490015C044100271FE0C29 +:10B73000441003E8400004162E1FE96D50007FD826 +:10B7400096025A187F043E07E96D2E1FE96D5A10C4 +:10B750007F1A8A014E040003FE02E40FE9138421DC +:10B76000E41E3E17E942E9095EF0003C3E17E9237A +:10B77000E9073E17E96FD50D84003E07E9238400F1 +:10B78000D50684003E07E9423E07E9233E07E96FFC +:10B79000FC80FC43F0842E07E96F5A00010A2E0753 +:10B7A000E9235A08010BFAF144A000C8D5094470F6 +:10B7B000003244A0012CD504FAE944A000962E07DB +:10B7C000E96A94D9F0834402C92C88604402C9BC58 +:10B7D000B61F50008480F08584C0440FF448F08187 +:10B7E00083C1808645C00BB880068126F6825A60E8 +:10B7F000071D225F000022FF000140F2BC014EF451 +:10B80000000452F7800040F79C07E82D81E54E5474 +:10B81000000452F2800040F7A807E8258805960347 +:10B8200038F11901A558D51B2250800722F0800657 +:10B8300040F2BC014EF4000452F7800040F79C0730 +:10B84000E81281E54E54000452F2800040F7A80748 +:10B85000E80A8805960302F18000A55788AF8C811D +:10B86000AD5897202A5F00014E5500068D21549453 +:10B8700080FFD509048F800250F40001548780FFB7 +:10B88000148F8002048F8001E0BC41C2BC1BE10523 +:10B890004082BC1B8CC1148F80015A6808AAC4590D +:10B8A0002251800040001016405290B6AD589603C9 +:10B8B0005A900805F5025A580829E685E92680803D +:10B8C0004E040003FF02E499E920404070014E4419 +:10B8D0000003FF22E0E4E919F4018A8080044E4469 +:10B8E0000003FE22E0E0E911F0045A080107B49FCA +:10B8F000000F8010AE20D505B49F840110020024F3 +:10B90000F0038C019600F08380A2506100102A029F +:10B910008001224180004E0500068A044E04000783 +:10B92000D5048A044E07000384001202FFFFDEF0F4 +:10B93000B41F501080208C01B61FF005502100204C +:10B940008C624C107F4B000F800C3E07E96AFCC3F1 +:10B950005A9808B2D5DAC8113E07E96A4432C9BC20 +:10B9600080804412C92C80403841800838208109E9 +:10B970008C015A0848FBDD9EFC008061A04E5A08ED +:10B980000105A09D8460D505A09D8C308C50FA7473 +:10B9900049FFFF01FC80FC0084003E07FFD42E0716 +:10B9A000FFD5C00F84C13E67E93C3E60041349FFE8 +:10B9B000AC255A0802043E67E93784003E07FFD5EC +:10B9C0002E07FFD4FC803E07FFD584003E07FFD43E +:10B9D0008400DD9E841F3C0FFA2584003E07FFD5BE +:10B9E0003E07FFD4DD9EFC42A712F383C4038E8181 +:10B9F000AF123CADFA8BA753004500038E81D403F0 +:10BA00008CA1AF53A710C4038E81AF100045000274 +:10BA1000A7518E81D4038CA1AF513C8DFA9CB48880 +:10BA2000928E97065A48010644300032B67FD503FD +:10BA3000FA89B69FA6D18480A790F38180A4F301F0 +:10BA4000E266E946A6D3A7D2F382F302E267E93EB3 +:10BA50000095000283C643E3A4730490801541CF90 +:10BA60000408893CB47F02F4800040F78011E06F45 +:10BA7000E82004F00000F30338F7F90005E00001C6 +:10BA800038FF3D014CF1C00904F4000040F7B8094B +:10BA900054F78001E80904F4000040F7B80954F7AE +:10BAA00080015AF80107029480004094801188892F +:10BAB00004908005893C02F4800040F78011E0AFDB +:10BAC000E803025480008CE1D5C18CC1D5B9C5060C +:10BAD000440001F4FF04404214978004FCC2FC427D +:10BAE00081403C0DFA8C80C1853FA640A7034400ED +:10BAF00003E8FE0CA65080E23C9FFA25408000132C +:10BB0000C9038400D52A840080A0E0A1E81104259F +:10BB1000000138211501DA0A042500023821150137 +:10BB2000E2024092BC1B40013C1B8CA1D5EF3C9F24 +:10BB3000FA255A97FFE80425000540148808882252 +:10BB4000B0038444B69F490039A9800A8026B08397 +:10BB5000806949FFFF4AB49F3C1DFA9CB421922E94 +:10BB600096465A180114041500033C2DFA25381086 +:10BB700089015CF0812CE80344802AF83C13F52D00 +:10BB80005CF08051E9038400D503E300E9082E103E +:10BB900004085A18010F2E100463C90B84013E07D4 +:10BBA000FFD43C0DFA8C8421A6013E07FFD5D56158 +:10BBB000441003E8FE649649E220E85A808A3C1D5E +:10BBC000FA25A0234430006438200501FA18FE1439 +:10BBD00040000C169601E20380404021BC1B9611E8 +:10BBE000F081A025944A880184200080000300A0F1 +:10BBF0000002A74101E00000E30A4004280196008A +:10BC0000E902802096498460B63F805E8123E24548 +:10BC1000E81D802AE228E814950C04F300058882C8 +:10BC20009521888F04FF8001A5209723E08FE905E7 +:10BC300050448001409200138C219648D5ECB43FCB +:10BC40008C418861969096D9D5E3E662E91144105B +:10BC500000644214842440308C7696D95CF180488C +:10BC6000E9078ABE97688A058C01E603E998842073 +:10BC70002E07FFD5C00D5A1801053E17FFD4D50871 +:10BC80008E0196003E07FFD5C8033E07FFD42E075E +:10BC9000FFD45A0801048420AE78FCC2FC42840020 +:10BCA000100F800F3C0C0278504F800F802084A032 +:10BCB0004422D1D4FA7849FFB0C98420005F800FB4 +:10BCC0003CAC01EA3C6C01EB808180019688E24546 +:10BCD000E80F3875050196C94C71C0093833050164 +:10BCE000E20340413C1B4001BC1B8C21D5F0946217 +:10BCF0003C9C01EEC039405484003DEC0278A629FA +:10BD0000A6A8B61F3C8C01E9840041C20013B47F91 +:10BD1000E262E921A7ABA6EAF681F601E2C3E918DF +:10BD200095DC88E295B988DE02F3000040F78011C7 +:10BD30005EF78028E90A38741D0038751D014C7EB5 +:10BD40004005A5B097B388068C6196D8D5E78C419D +:10BD50009690D5DE442001F4FE143C2C01EC3821F1 +:10BD6000110140000817882944504E1FE2A0A6CBBD +:10BD7000A70AA689A648E80E8A6496D8E66BE80565 +:10BD80008A419690E64BE90844106D5F40008006BA +:10BD9000D5048400D5028401FCC24403F080441F12 +:10BDA000FFB6AE403C0DFA193C3DFA1892028C01E8 +:10BDB000442200008420E220E806A3113841860ACC +:10BDC0008C21D5FA84013E07E9064403F0808420E3 +:10BDD000AE40DD9EC0174E1700164E270014980A7D +:10BDE000E41FE910E02244000064E807AE18FE0CEE +:10BDF00040200856AEA0DD9EFE8440210456AE9839 +:10BE0000D50444000064AE18AE20DD9EC10B402076 +:10BE100084094430006442200C7340110436960BB0 +:10BE2000DD9E8001DD9EFC5880E02E07C5422E5726 +:10BE3000C543509F8034B61F8420FA42B00844A006 +:10BE400000694460006AF583490038328420FA4270 +:10BE5000800910AF802010AF802210AF802410AF77 +:10BE6000802610AF802810AF802A10AF802C10AF32 +:10BE7000802E106F8021106F8023106F8025106F2F +:10BE80008027106F8029106F802B106F802D106F0E +:10BE9000802F4900380D8420FA42B01210AF803450 +:10BEA00010A4800210A4800410A4800610A48008AE +:10BEB00010A4800A10A4800C10A4800E10648001CD +:10BEC000106480031064800510648007106480098A +:10BED0001064800B1064800D1064800F490037E8F7 +:10BEE0008420FA42B01710AF804810AF804A10AFDC +:10BEF000804C10AF804E10AF805010AF805210AF0A +:10BF0000805410AF8056106F8049106F804B106FB7 +:10BF1000804D106F804F106F8051106F8053106FE5 +:10BF20008055106F8057490037C310AF805C10AF49 +:10BF3000805E10AF806010AF806210AF806410AF81 +:10BF4000806610AF806810AF806A840050AF807048 +:10BF5000100F801E100F801F8420FA42800A508F1D +:10BF60008084106F805D106F805F106F8061106F34 +:10BF70008063106F8065106F8067106F8069106F2D +:10BF8000806B49003795440000464410005A4460D5 +:10BF9000006451CF809844400063100F80701015EA +:10BFA0000007101500081005000F8420FA428008D1 +:10BFB000104500011045000EF48110650002106567 +:10BFC000000310650004106500051065000610658B +:10BFD00000091065000A1065000B1065000C106563 +:10BFE000000D490037658420FA42801C106F808460 +:10BFF0001064000110640002106400031064000467 +:10C000001064000510640006106400071064000846 +:10C01000106400091064000A1064000B1064000C26 +:10C020001064000D1064000E1064000F49003740CA +:10C03000F401B0EB80038420FA42104F8098104E38 +:10C04000000FF482F381106E0001106E0002106E7A +:10C050000003106E0004106E0005106E0006106ED6 +:10C060000007106E0008106E0009106E000A106EB6 +:10C07000000B106E000C106E000D106E000E4900CB +:10C080003717F30144000055F402100F80AC100183 +:10C09000800F2E00041EAF19AF9AAF9BAF9CAF9DCF +:10C0A000AF9EAF9F10618008106180091061800A07 +:10C0B0001061800B1061800C1061800D1041800EAA +:10C0C0005A08010448000120B41FF50394018807B1 +:10C0D000B43FF0819E2AFE0C94018807F0839E29CC +:10C0E0004260042495B1F084983EF08284C0B43F4D +:10C0F0009630E201E8363803991138151800F385B7 +:10C1000049FFFE8638039909F001381418003800F9 +:10C11000191149FFFE7DF10138009909F003381E1D +:10C1200018003800191149FFFE73F103F3053800B8 +:10C130009909F002381198003800191149FFFE687A +:10C14000F10238009909F0013814980038001911EB +:10C1500049FFFE5EF101F305380099098CC1D5C88D +:10C160008C2140908408840138138511222380019A +:10C17000503F801E504F801F49FFFE2E002F801F12 +:10C18000FAC142011824004F801E2213800050344F +:10C19000FFFE445000468867814042A21473FE446B +:10C1A0004010A83602A1800045CFFFBA882AAC58BB +:10C1B0002233800044AFFFEF4221282442227073D3 +:10C1C0004211802440008816802788033800A40D7F +:10C1D0004623FFFFB41F50210FFF8840408108080D +:10C1E00084012210FFFD38238A11503F801E504FDA +:10C1F000801F8F248927F58149FFFDEE002F801EC7 +:10C2000022048000FF94001F801FF5018D02890722 +:10C21000806642309473FE3440000C1602340000F5 +:10C2200042212824880312040000220480004220B6 +:10C23000F073FF8440A309568940F504B41F4410ED +:10C240000064FF449A28101F801E101F801F944115 +:10C2500012A4800040938400946941C38400442068 +:10C2600005DC221E00000244800044302134FE54CC +:10C2700040108C36882412148000224E0000441096 +:10C280001B58FF0C40420C96124E0000B49F84C015 +:10C290008E8188A4956988A7880494012242800031 +:10C2A0008807FEA4A50040210C568844AC802202D9 +:10C2B0008000B088FE4440108C36AC6850AF804897 +:10C2C000508F805CB43F9630E201E81D38111800B1 +:10C2D00038039911F28149FFFD9B3803990938040D +:10C2E00099113815180049FFFD9338049909380E43 +:10C2F00019113814180049FFFD8B380E1909F20185 +:10C300008CC1D5E1FCD83A6F9ABCEFFC49FFA77607 +:10C310004413F0105A080206440FFFAAAE08D503D2 +:10C320008400AE083C0DFAAD9E46E622E9048E0973 +:10C33000E605E80F3C0DFA994412CE683C2DFA9CB4 +:10C340004432B50C3C4DFAA349FFDA595A000803B0 +:10C350008401EC043A6F9A84DD9E3BFFFCBCEFFC49 +:10C360004900390B490038293C0DFA998421AE4126 +:10C3700049003B8249FFA7425A08020449FFF9B924 +:10C38000440000A0490027CBEC044402B4AC3C1D9F +:10C39000FA993BFFFC844800382E3BFFFCBC840428 +:10C3A000EFFC3E07E905440000A1490027B83C0D19 +:10C3B000FA994412B3AC4422B50C3C3DFAA34900AF +:10C3C0002CCB2E07E9335A08010A4402B340441229 +:10C3D000B3E249FFA8FB49FFE5743C1DFAB58402AE +:10C3E000AE083C1DFAAAAE08490039552E07E933BC +:10C3F0005A08010449FFE55E49003A434400007FC2 +:10C40000EC043E07E96DFA043E07E92C3BFFFC848F +:10C41000840248FFA35E3BFFFEBCEFF82E07E93322 +:10C420005A0801074402B340842049FFA8612E073F +:10C43000E9708E03E602E80D2E07C5DC5A08010AF2 +:10C4400049FFD1BC84023C1DFA9B49FFA79AD5083D +:10C4500049FFE544F081F101840049FFA7923C0DBA +:10C46000FA99A6415A180D048423AE41440000A352 +:10C47000490027552E07C5DD5A08010C3C0DFA99D5 +:10C48000A6005A0801072E07E97049FFE574D50791 +:10C49000440245104412400049FFA9594402D3FC0C +:10C4A0004412B48844328F704422D5044442D3F0FD +:10C4B000490022D43C3C027984004412D47C9898F0 +:10C4C000A490382080098C025A0840FBEC083BFFFE +:10C4D000FE84DD9E84003E00041E2E07C5423C2CD7 +:10C4E000027994418E2488223C3004E0A4483A6FBB +:10C4F000A0BC964BE061E80C94028E048802A40074 +:10C5000096035EF07FECE80484013E00041E49FFC0 +:10C51000A6755A08021F49FFE668C81B3C0DFA9928 +:10C52000A6015A0803072E07E92C5A081413D5034D +:10C530005A08061084C03E67E92C49FFF8EF2E0721 +:10C54000E9425A0801043E07E9193E67E97DD51022 +:10C5500049FFA6545A08020D49FFE647C0093C0DA1 +:10C56000FA99A6015A08060584013E07E97D2E07BF +:10C57000E92CE614E8048C013E07E92C84004412FF +:10C58000D0548040382081098C014462D0545A082C +:10C5900012FB2E07C5DE5A08010B2E000439C8070E +:10C5A0004402D3FC80264900261BD50E3C0C0279A0 +:10C5B0003C1C027849FFA8CB840080203813010975 +:10C5C0008C015A0812FD2E77E9195A78011649FF95 +:10C5D000A61580C05A08021184004412D3FC49FFFA +:10C5E000F9BC80074412D3FC49FFF9B78006441216 +:10C5F000D3FC49FFF9B284013E0004642E07E968C8 +:10C600005A08120D3C03F4DB8421490026CB5A085A +:10C6100001062E100464490026182E17E9335A1813 +:10C6200001064402B34049FFA7632E07E9685A0890 +:10C6300012103C03F4DB8422490026B45A08010995 +:10C6400084022E1004643A6FA084480025FE3A6FDD +:10C65000A084DD9E2E07E9683BFFFCBCEFFC5A0876 +:10C66000120E3C03F4DB842F4900269C5A08010774 +:10C67000840F2E100464490025E82E07C5DB5A08F4 +:10C68000010C3C0DFA99A6015A080A07EC043BFF7D +:10C69000FC8448FFE575EC043BFFFC84DD9EDD9ED9 +:10C6A0003A6F9ABCEFFC2E07E94E4E0300872E002E +:10C6B000043AC8042E07E967C0052E07E93B5A086B +:10C6C000012449FFB8D8C8202E07E986C81D2E07C7 +:10C6D000E9195A08010CFA0249FFA1FB84003E0740 +:10C6E000E91984013E07E986D50F49FFF69E5A00F5 +:10C6F00002F44402D5043C13E3164422B3A749FFD5 +:10C70000EE7B5A0002EA3C0DFA99A6412E07E98613 +:10C710005A1006045A180B125A0001092E00046020 +:10C720005A0001052E07E977C04884013E07E93C1D +:10C730003E07E9378401D5425A00010A2E00046001 +:10C740005A0001062E07E9635A0801254403F04AFE +:10C7500044100055AE403C1DFAB5A608C0FF840049 +:10C760003E07E9863E00046084013E0004612E0716 +:10C77000E9685A08120E3C03F4DB842549002612AE +:10C780005A08010784052E1004644900255E8402BE +:10C79000D5152E07E96B5A080F1184003E000421BD +:10C7A0003E07E96B4400007149FFA1933C0C027302 +:10C7B0003C1C027549FFA7CB8401EC043A6F9A84B4 +:10C7C000DD9E2E07C5DC3BFFFCBCEFFC5A08010ACE +:10C7D00044029370501000285020005849FFD1089F +:10C7E0003C0DFA994412CE682E27E9832E37E95082 +:10C7F0002E47E92E490007782E07C5DB5A0801109D +:10C800002E0004545A08010C4402CE6849FFF16F0F +:10C81000C806EC043BFFFC8448FFF44AEC043BFFF1 +:10C82000FC84DD9E3A6F9EBCEFF88400100F8007F9 +:10C830003E00043384C02E07E94AE2C0E85F3C0CA6 +:10C8400001EA95F138501901DE253C2C01ED3C0C34 +:10C8500001EC88474432D054A65138001911A690F3 +:10C860003C4004E04900237B3C1C01EA8827A48863 +:10C87000FE17AC083C0C01EC381019013C03E63201 +:10C88000E220E8082E07E92E5A00FF058C013E073A +:10C89000E92E3C0C01EA38501C01DE153C1C01ED70 +:10C8A0002E27E91488272E30041FA609504F800731 +:10C8B000A64880A649FFF61D3C1C01EA8827A488EB +:10C8C000FE17AC083C0C01EA38501C01DE153C0C8C +:10C8D00001EC3C1C01ED3C3C01EE94B238109C0094 +:10C8E00038001C11884349FFEE3C3C1C01EA88E1FA +:10C8F000A478FE0FAC388CC1D59F006F80075A68B2 +:10C90000012B2E0004348C013E00043444000072DC +:10C9100049FFA0DF2E000434E60BE9222E00043389 +:10C9200084203E1004343E10042E3E67E93B5A0832 +:10C9300001182E0004328C019600E60BE90F44002A +:10C9400000743E10043249FFA0C44400005549FF62 +:10C95000A3D3D50684003E0004343E000432EC0824 +:10C960003A6F9E84DD9E3C0DFA993A6F98BCA60101 +:10C970005A00030649FFB78BE603E9072E07E9686B +:10C980005A0005045A08120A84003E07EAE43E07EA +:10C99000EAE53E07EAE6D5673C0DFAC05A08010908 +:10C9A00084003C0FFAC04402B51049FFB758440256 +:10C9B000D5384412B51C49FFBA5A3E07EAE649FF8A +:10C9C000B7665A0803274402B3634412B36A49FFA7 +:10C9D000A5BA4460005F8401844080608080842C1C +:10C9E00080A249FFA46B3C0DFAC05A08010A8400DA +:10C9F0003C0FFAC04402B51049FFB731D5048EC1CF +:10CA000097B0CEEA4402B3634412B36A49FFA5CF9C +:10CA100049FFB74080C05A08011D49FFB7385A087E +:10CA20000309800649FFB7304400006149FFA05167 +:10CA300049FFB72D5A080505840149FFB72549FF6D +:10CA4000B7265A08041184013A6F988448FFB71C2E +:10CA500049FFB71D5A08030884003C0E01118401E8 +:10CA60003E07E9373A6F9884DD9E3A6F9ABCEFF43F +:10CA7000840C4900245E4403F04A44100055AE4043 +:10CA800049FFA56B3C0DFA9C2E2004692E40043A08 +:10CA9000B4608403FE14842A2E20043842020473F6 +:10CAA00088022E200463441003E8420104732E27F9 +:10CAB000E970441000644201047380402E00042198 +:10CAC0002E400439FA2EFE0C926284254202047331 +:10CAD00096C644100032420184732E37E91D44107B +:10CAE00027104201847388023C080B9E4900298B61 +:10CAF0003C0DFA99A6415A100D0B2E100454C9078B +:10CB00004412B3B34422CE6849FFD7AC2E07E929BB +:10CB10005A0801058402480000932E07E9685A0864 +:10CB20001904490023C52E07E989C80C49FFC8BC70 +:10CB30005A0801093C1DFA992E07E970A64949FFD8 +:10CB4000A6252E07E97C5A08010E4402B3AC3C1D11 +:10CB5000FA9C4422B50C3C3DFAA53C4DFAA3490091 +:10CB600025C03C0DFABE5A08014E2E07E97884C054 +:10CB70003C6FFABE5A08552D3C0DFAA33C1DFA999C +:10CB8000B61F4422B3634402B4AC3C3DFA9C444219 +:10CB9000B50C3C5DFAA5490026CD3E07E9682E009C +:10CBA000042F5A08050B3E07E96844022D50FA325B +:10CBB000AE403E60042FD5105A08040F3E07E968C6 +:10CBC00044022D50FA31AE403E60042FD50544009A +:10CBD00000553E07E9782E07E968490023B396001F +:10CBE0003E07E9215A00032C5A08020D4403F04A7B +:10CBF00044100055AE403C1DFAB5A608C0FF48FFE2 +:10CC0000FF8B49FFA8C92E07E9705A0803072E07B2 +:10CC1000C66EC80349FFA5162E07E9795A08010F09 +:10CC200084003E07E97949FFFEA03C0DFAAAA64020 +:10CC3000C9FF8421AE40FA03D5028401EC0C3A6F9F +:10CC40009A84DD9E3A6FAABCEFF449FFA2D74E0248 +:10CC500001122E07C5E45A0001044800010C3C0DE6 +:10CC6000FA9C49000B9E4412D1D44402D794490047 +:10CC70001E224402D7944412D1D449001D5D4402BF +:10CC8000D7944412D1D43C2C027849001025440298 +:10CC9000D7944412D1D43C2C02784462D7944900F2 +:10CCA000177E84003E07E92A850050A300084470DF +:10CCB00000FC509300D051C300D8B4064E0200D4FB +:10CCC000000300544E0200C1001300CA4E12009728 +:10CCD000000300CB5A08030A42041C24403500001C +:10CCE0008809A483A444D50842041C2440350000CC +:10CCF0008809A481A4424010C008A019FE5749FF2A +:10CD0000F31B842049FFF2660213006696C1E223FA +:10CD1000E807840010030054100300CA8061000378 +:10CD200000CB22530006C056E602E93D5EF28220A7 +:10CD300084A0E9034450043F5A08022A84031003E4 +:10CD400000CB020300694412D7EC1203006B02030C +:10CD5000006AF3811203006C42041C2440448000EA +:10CD6000402E00008820A421A522A04941E24008CD +:10CD7000A511A492400F000440214008FEA7B6BFB1 +:10CD800049000B6E1203006AF301B4BF0213006680 +:10CD9000222300069A0BFE2C42010C73400004165D +:10CDA000AC36D50A222300699A0BFE1442028C731A +:10CDB00040000416AC36022300662203006A2253A8 +:10CDC00000079A53FE0C42028C7340000816AC37E1 +:10CDD000D52F2223002E9A0BFE8442228C734021F1 +:10CDE00004562253002FACB622230007FE2C42012A +:10CDF0000C7340000416AC37D51B2223002E2213DF +:10CE0000000652500002FE84422284738462402154 +:10CE10000C562213002FACB622230007FE44421208 +:10CE2000887340108C368E01AC77100300542203B7 +:10CE300000064E0400048400AC36220300074E04B2 +:10CE400000048400AC37040300165A0801060403EA +:10CE500000265A0001092E07E92A8C013E07E92A1B +:10CE60008400B6068D01506300FC5A800A0448FF16 +:10CE7000FF26EC0C3A6FAA84DD9E3A6FAABCEFFC49 +:10CE80002E07E9335A0801074402B340842249FFC0 +:10CE9000A32F2E07C5DC5A0801064402D3F049FF30 +:10CEA000CD892E07C5E25A08010A4402D3FC441278 +:10CEB000CE684422D1D449FFED322E07C5DB5A0893 +:10CEC000010F2E0004545A08010B4402CE6849FF9A +:10CED000EE0EC8054402D3F049FFF0FD490027A833 +:10CEE0002E07E970540000FBC80C4402D1D4441250 +:10CEF000B37A3C2C027849FFD4043E07E8D0D5042D +:10CF000084023E07E8D03C0C027849FFF78E4402C9 +:10CF1000D3FC4412B4A444228F70846084854900F9 +:10CF20001D648400442291403E07E9674412CE68A4 +:10CF30004402B4A45031001449FFF2092E07E968F5 +:10CF40005A08120E3C03F4DB84234900222B5A08B2 +:10CF5000010784032E100464490021773C1C0279E8 +:10CF60003C0C02785030800E5050000E8487446292 +:10CF7000D054A5E83823110188479693AC980272E3 +:10CF80008010382311018847969312218010A498AD +:10CF9000409100112E27C542884494918841A5D024 +:10CFA00097FBE127E804A4909693AC988CA28C623E +:10CFB0005A4008048488D5DE3C2C028849002D8222 +:10CFC0003E0004632E07C5E25A0801102E00043803 +:10CFD0005A08010C2E07E967C0082E000439C8055D +:10CFE0004402D3FC49FFED7849FFA108C00D2E078C +:10CFF000C5E45A08010A3C0C02784412D1D43C2002 +:10D0000004E049000B622E07E967C8074402CE68B6 +:10D010004412D3FC49FFF1B02E07E9674E0200D05D +:10D0200084003E07E9693E07E9522E07E9685A087D +:10D03000120E3C03F4DB8424490021B45A08010792 +:10D0400084042E100464490021002E07E9435A0885 +:10D0500001073C0004E08E0A3C0804E02E07C5DC12 +:10D060005A0001062E07C5E25A0801064402910C37 +:10D0700049FFCE0784023E0004082E07E9505A08F3 +:10D08000010E3C0DFA9CB400920E96065A08010758 +:10D0900049FFF6063E000408D50484003E0004085B +:10D0A0002E07E970C80584013E00040CD5048400F5 +:10D0B0003E00040C3C0C02883C1C02784422D1D473 +:10D0C0003C3004E04442B37A84A149FFA6BF840007 +:10D0D0003E00040C2E07E94AC01249FFA08F5A08EF +:10D0E000020F2E600439CE0B4402D1D44412D3FC7B +:10D0F0004422B37A490003B63C6BF4D84402D1D43D +:10D1000049FFFB922E07C5E15A08011C3C0DFA9C11 +:10D11000B40096065A0001083C0DFAA5A600960632 +:10D120005A0801102E00042CC80C4402D1D4441219 +:10D13000D3FC4422B37A49FFF4D43E00043AD50626 +:10D1400084003E00043A49FFF4473C00021D5A089F +:10D15000010B3C0DFA9CB400920E96065A0801048D +:10D160003E00043C2E00043C5A08010F49FFB383E3 +:10D17000C80B3E00043CFA2E8404844349FFB37E6E +:10D18000840549FFB3812E00043A5A08014C3C0D36 +:10D19000FA9C84203E100412B400920E96065A089F +:10D1A00001053E000413D5033E10041349FFA026D9 +:10D1B0005A08023984003E07E937D5343E00040995 +:10D1C0002E00043A5A08010649FFF3E73E00043AEC +:10D1D0002E07E9692E17E91AE201E8048C013E07DF +:10D1E000E96984003E07E94A3E07E92E3C03F4E280 +:10D1F000C0193C23E4D63C13F4D43C03F4D8E241F8 +:10D2000040113C1BE001E8058C013C0BF4D8D50A29 +:10D2100084003C0BF4E23C0BF4D73C0BF4D83E000A +:10D2200004693C00021D5A0900113C0DFA9CB4002F +:10D23000920E96065A08010A84048040FA2E49FF8D +:10D24000B31D840549FFB3202E00043A3E00043B81 +:10D250002E07E9335A0801074402B340842349FFEB +:10D26000A1473C53F4EE3C03F469D8052E07E94B83 +:10D270003E07C5E32E07C5E35A08013E3C0DFA9C64 +:10D280003C1DFAA5B400920196065A000107A608B3 +:10D29000920196065A080130A60892039606C82BFA +:10D2A0002E0004563C1DFA99490004D63C0DFA990B +:10D2B000A6015A0003045A08061B2E07E955C01799 +:10D2C0002E000468C8143C03F4D7C8112E0004696A +:10D2D000C80E3C0C02784412D1D44422B37A3C30BC +:10D2E00004E0490004D33E000439D5054900047F19 +:10D2F0003E0004392E37E94ACB043E37E983D50D89 +:10D300004402D1D43C1C02783C2C02794442D564BE +:10D310004452B3B349FFC4452E17E983C1552E3794 +:10D32000C5722E47C573926192814402D5648440D0 +:10D33000E241E80BA5408C4188A3AD40A5418C0893 +:10D3400088A412507FFDD5F53C0DFA9CB4009202E2 +:10D3500096065A0801072E07E970C8033E00042309 +:10D360004402D56449FFC0CF84003C0E01113C0E3D +:10D3700001123E07E9773E07E9693E07E96B3C0D7C +:10D38000FA99A6015A0803172E07E9805A08030FD5 +:10D3900049FFD35CC8052E07E9625A0801088403D7 +:10D3A0003E07E980D57A5A08037984003E07E98070 +:10D3B000D5745A080A732E07E9805A0804F68401C6 +:10D3C0003E07E980D56A2E00043AC8672E10042B68 +:10D3D0003E07E94A3E07E9833E00042D3C0E011456 +:10D3E0005A10010C3C0C01114420EA60E240E907AC +:10D3F0003C23F4E2CA048C013C0E01113C0C0112E6 +:10D400004420EA60E240E90E3C2002143C33F4F18F +:10D41000E262E802C1058C013C0E0112D5033C1EFC +:10D4200001122E07E9205A0801083E07E93C840052 +:10D430003C0E0111D50484003E07E93C2E00042077 +:10D440005A08011584003C0E01112E17E9842E079D +:10D45000E96BE201E80E2E27E9692E17E91AE2418D +:10D46000E9088C013E07E96BD50484003E07E96BAF +:10D470002E0004395A08010784003C0E01113C0EAD +:10D4800001122E67C5DC5A68010984003E00045869 +:10D4900049FFCB7E3E60045849FFF9045A08020454 +:10D4A000480000F32E00043A5A08010784003C0E9D +:10D4B00001113C0E011249FFF9864402D5642E1772 +:10D4C000E9834422D7944432D1D43C4C027849FFBA +:10D4D000AA132E07E9685A08120E3C03F4DB8426CF +:10D4E00049001F605A08010784062E100464490091 +:10D4F0001EAC84003E07E9434412D7943C0C0278EA +:10D500002E27E983490027C22E07E9335A0801076D +:10D510004402B340842449FF9FEB2E07C5EB5A0811 +:10D52000010A4402D7944412D1D43C2C0278490019 +:10D5300029934402D79449FFBF032E07E9685A088C +:10D54000120E3C03F4DB842749001F2C5A08010704 +:10D5500084072E10046449001E7849FFFB754402BD +:10D56000D79449FFB9062E07C5DB5A08011D2E00C6 +:10D5700004545A0801194402CE6849FFEAB8C81396 +:10D580004402D1D44412D7942E27E9834432B49074 +:10D5900049FFEABA49FFED895A0801064402CE68FC +:10D5A00049FFDDE18400842184413E17E9713C0E8E +:10D5B00001093E07E9602E67C5493C7C01EB80A06C +:10D5C0004412D7948060853D8142448000FFE2662A +:10D5D000E824B48140F224025AF00105CC0480858D +:10D5E000D5178440A10F384391015CF20100E8088F +:10D5F000E6951240800AE9068C019600D503128058 +:10D60000800A0440800912A0800BE285E9E98C6160 +:10D61000501080FC80A4D5DC3E07E9603C5E010927 +:10D620003E27E97149FF9DF849FF9DE85A08020C21 +:10D630004402D7942E17E9834422D1D43C3C0109FB +:10D6400049FFED5949FFF9912E07E9833E00041D7A +:10D6500049FFB111C0093C000207E619E8078C0137 +:10D660003C080207D5033C0802072E67C5DC5A6850 +:10D67000010E3C0DFA99A6015A00060A5A000B0841 +:10D6800049FFCF21D50480C0D50284C18006EC04B7 +:10D690003A6FAA84DD9EFC2080E180C2C00D5A0052 +:10D6A000041184003C0BF4E349FFC66D44423FD8AB +:10D6B00044323FD6D50A44423FD244323FD0D5050A +:10D6C00044423FD844323FDC84009680E246E8077B +:10D6D00038138101381201098C01D5F83C03F4E3B9 +:10D6E000AC18FCA0FC40A7002E67C5495A400107B2 +:10D6F000848044728F708124D5124442937184A037 +:10D70000D608087200018CA110727FEA9768D5F9DB +:10D71000A6003C43E6325A080150D5099760E2A6BC +:10D72000E8F899678C81109283ECD5F92E07E97699 +:10D730009A10E402E9095A3801082E07FFD8E605D5 +:10D74000E8078C01D50284003E07FFD8846084007E +:10D750003E07E976A609C82D5A3001085A28010C5F +:10D760003C03F53AE614E9073C0004E08C053C0B69 +:10D77000E49DD5033C4BE49D2E07E9435A0801077D +:10D780003C0004E08C113C0BE49D3C03F4E2C0053A +:10D79000440000B43C0BE49D3C0DFA9CB4009202A2 +:10D7A00096065A08010D3C0004E050000023D50500 +:10D7B0003C03E389D50284003C0BE49DFCC0FC40A3 +:10D7C000A10394C93CADFFF738620501A10490C2E2 +:10D7D00088838460A7E180039F79976A51C38001A1 +:10D7E00040FE1407E9324E55002E00850002E0A8E5 +:10D7F000E829009200005014FFFF964A51E480018E +:10D8000040FF0407E91F4E15001B00F50003E02F41 +:10D81000E816DF034C14801481E542F0A07340F752 +:10D82000840840F13C0002F7800040F7801140F787 +:10D830009807E8038C6196D88C0196008C21964A53 +:10D84000D5E08CA1976AD5CD44200064421188248C +:10D85000400080165E000019FCC03C0FFFF7DD9E03 +:10D86000FC40EEE8F28180E0442000508121B00AC3 +:10D87000842049002B1D842044200050B01E490004 +:10D880002B17B03284204420005049002B11F001A6 +:10D89000A6004E0201AA8400F082F08380C0F0014D +:10D8A000A600E2C04EF200A1A03941E304083850BE +:10D8B00019014C534096A03D9472882004048005C1 +:10D8C00044A000FFF085A03B810A38201901FA1816 +:10D8D000FE1444200064400008163C23E305E002E7 +:10D8E00040203C1AF286A68BA60AF2893C2DFFF74F +:10D8F000F28784408082F284F309E260E92FA6C9AE +:10D90000A748F388F308E265E926F30700F18002EF +:10D91000806542303C7340F18408F30540F1BC005F +:10D92000F30602F7800040F78011E06FE811F3047E +:10D93000E20840803C1BE26040303C1BE2AA40A26F +:10D94000BC1B8C41E285F3844042BC1B96918CA1A8 +:10D950009768D5D98C019600D5D0C2138A8A8C815C +:10D960004E440003FF22F304B00A8A688C613840F9 +:10D9700019094E340003FEDAB01E38301909D507F4 +:10D98000B00A38201909B01E38201909B0323820E1 +:10D990001909F00388409611F083F002C821A03BDA +:10D9A0003C1DFA9038007801A489E202E919A44AE2 +:10D9B000E220E9163C0DFA9CB400920196065A004A +:10D9C00001093C0DFAA5A600920196065A08010924 +:10D9D000800780260424800549FFFEF3F0828CC175 +:10D9E00097B048FFFF5E854080CAF001A600E2C004 +:10D9F0004EF200C3A03940830408385019014C533B +:10DA000040B8802680070424800549FFFEDAA07D07 +:10DA100083C094328801A641A6C0F184A742A643E0 +:10DA2000A03BF185384019015CF200D3E90984007C +:10DA30003C0BF4D73C0BF4E285404800009EB0322A +:10DA400038001901F086B00A38001901F087B01EBD +:10DA500038001901F088F003E619E85FF0049C41F2 +:10DA6000F0058A2396499C818A45E6239691E8052C +:10DA70008403FE0CE040E807E643E84F8403FE140D +:10DA8000E020E94BA03C89000004000150F07FFF3A +:10DA90005CF7800EE8420084000050F47FFF5CF7E2 +:10DAA0008022E83B04FF800100F780005AF801382B +:10DAB0005A1803185A2801363C0DFFF70414800544 +:10DAC000A60242040024886094D98861A498F304D3 +:10DAD0009693880394018801A4C096DB8862D519C7 +:10DAE0005A2803205A18011E3C2DFFF780600414A9 +:10DAF0008005A69242328873F50594D94202887354 +:10DB0000940188618801A4D8A40096DB96038860FC +:10DB1000E06456378001D5068460D5048461D5025F +:10DB2000806F3C13F4E2C10A3C23E3058403FE1436 +:10DB3000400200075BE80155D5165BE0011A5CF274 +:10DB400000B4E8168001F40644200064FF14804409 +:10DB5000F507F408FF6444400037FF2CE044E90473 +:10DB6000CB03C106C0055005000154A000FF8CC1C5 +:10DB700097B048FFFF3CF001A600E604E8074EA27C +:10DB800000093C03F4D78C01D5059201E340E8FA83 +:10DB900084003C0BF4D7F0035CF00046E9048400F9 +:10DBA0003C0BF4E2F00285E55A08010385E93C13D9 +:10DBB000F4D7E22FE90884003C0BF4D73C03F4EDE2 +:10DBC0003C0BF4E23C03F4E2C008F1018E013C0B93 +:10DBD000F4E28400AE0884013E000469D5055CF2DD +:10DBE00000B4E9B2D5C0ED18FCC0FC0084203C1B99 +:10DBF000FFF53C1BFFF43E17FFEF441000403E17BB +:10DC0000E89D3E17E89C3E17E89B3E17E89A3E17B2 +:10DC1000E8993E17E89884203C1FFFFE2E10046808 +:10DC200084003E07FFF03E07FFE03E07FFED3E07A2 +:10DC3000FFEC3E07FFEE3E07FFE15A18010B3C1DCB +:10DC4000FA903C27F52FA44CE041E8033E0004681D +:10DC50008400FC803C43FFF33C2DFA903C33FFF200 +:10DC6000C009E68FE9038E85AD11E66FE9058E6583 +:10DC7000D502AD11ACD4A6095A0806048401D50317 +:10DC80002E07FFE2AE10DD9EFC49F0813C0DFA90BC +:10DC9000F1842E17FFE0A5C2F288F38CA6005A1873 +:10DCA00001049401D5029601F0853C0DFFFD84C26C +:10DCB000A642A603B63FF0892E07FFF05A080103DB +:10DCC00084C08401100F80429431960052100010DD +:10DCD00052000024960085209648FA40100F80419B +:10DCE000100F80453C0DFA7E101F8040102F80439E +:10DCF000101F8044129F801F109F8046109F8047F6 +:10DD000049FFD3F6B0518041B01049FFD42CB41F65 +:10DD1000F1018C01FE3494018801501F803E804146 +:10DD200049FFD3EB3C0DFAA7FA331010000A12900A +:10DD30000004840049FFD5144403F04A4410005500 +:10DD4000AE4049FFD3D04413F140A6085A0001FF6A +:10DD50003C0DFAA7F1010200001197898A06920191 +:10DD60005410000F96019204409080109642F18268 +:10DD7000221F801FF1832E17FFF05A18010E3C1D41 +:10DD8000FA9085EAF203A44A944B4010BC36E02294 +:10DD9000E8038CF997F9F1033DEDFA90E0E114FF07 +:10DDA0008007F203021F0001544480FFF18640A067 +:10DDB00088079E64E629E8089E449648E63DE80404 +:10DDC00084213E17FFE14EA2004C2E1FE89D5A1001 +:10DDD000405D2E37E8992E27E89B2E67E89AF38A54 +:10DDE0002E77E89884A0E2C2E91FB47FFED4F38BBB +:10DDF000F30AE2E3E916048F800B04FF8001890334 +:10DE000040840408890F02840000408400114E847D +:10DE100000045284000088A88C61976B96D8D5EADC +:10DE20008C419690D5E1F206E045E9352E27FFE1D9 +:10DE3000C2322E2FE89CF3029A9A4E240003FE92DF +:10DE40004014840196924E140003FE4A964AE4243C +:10DE5000E803E444E92084213E17FFEFD51C440089 +:10DE600000403E07E89D3E07E89C3E07E89B3E07D2 +:10DE7000E89A3E07E8993E07E8983EA7FFEF3EA7DD +:10DE8000FFE03EA7FFE1D509001F80083E97E89D0F +:10DE90003E17E89C5AA001048400D57E4E920005EE +:10DEA0009F619768D50280A9B43F8E21E121E803E4 +:10DEB0008C81D5029708F10285004E1700059E411E +:10DEC000548080FFF1099F89F102E026E8029D81DC +:10DED000F103840440308076844096D997B080E87E +:10DEE00080228002F38DE2C7E924B47F8A05FEFC1C +:10DEF000F38AF08B8065F00BE28388039600E916C5 +:10DF0000F00A04FF800188039401880F02F00000EA +:10DF1000A400882F04FF800D9603E00F964BE803C2 +:10DF20008C4196908C6196D8D5E78CE197F8D5DC3A +:10DF30002E37E8995A38400A3E87E89B3E67E89AB0 +:10DF40003E57E8993E47E898F402B4BF80694232F0 +:10DF50001473F40194D98864025F0005A518FF4486 +:10DF6000846940F28DF6E02F9723E915025F0006E1 +:10DF70008A249F01FF2C964B40F20DF6E02FE90B0F +:10DF800044100064FE8C40010016E419E986840107 +:10DF90003E07FFE084013C1DFFFE5A100131C10520 +:10DFA0005A10024A480000813C17FFF4F206E022B2 +:10DFB000E8038420D506022F0002E041E804842112 +:10DFC0003E17FFEE2E17FFEEC9185AA80117F107EA +:10DFD000C914C8132E17FFEF5A1801102E17FFEDA2 +:10DFE000F2058C218C4196489041E0413E17FFEDAF +:10DFF000E85B3CAFFFFED5188400D5165AA801187F +:10E00000F107C915C8142E17FFEF5A1801112E1762 +:10E01000FFEDF2058C219648E2413E17FFEDE84402 +:10E0200084223C1FFFFE3E07FFEDD53E84003C0FDF +:10E03000FFFED5FAF207021F00075A2001045A0812 +:10E0400001202E07FFEC002F0001E240E9048C01C3 +:10E050003E07FFEC3C03FFF5E220E9048C013C0B9A +:10E06000FFF52E07FFECE240E9053C03FFF5E22057 +:10E07000E81B84003C0FFFFE3E07FFECD513840035 +:10E080003E07FFEC84005AA001053C03FFF58C011C +:10E090003C0BFFF53C03FFF5E220E80684003C0F53 +:10E0A000FFFE3C0BFFF53C0DFFFE5A080204840105 +:10E0B000D50284003E07FFF02E07FFF05A0001044E +:10E0C000480000A549FF989AC00E2E07C5E45A08DB +:10E0D000010B3C2DFA903C0C02784412D1D4A4944C +:10E0E000490002F33C3DFA903C0C02883C1C02784B +:10E0F000F204A4DCF40884A149FF9EA8F008A6005D +:10E100004E0200853C0DFA9084C0F085B41F45EFA7 +:10E1100080008E01F086F0098E01F087000F801CD0 +:10E12000F08B000F8018F08DF008A600E2C0E86EBA +:10E13000F004408304080490000189280254800000 +:10E14000DE62A00338001901F082F102F00CE20156 +:10E15000E95AF004A0048808A641A680C1059E09DA +:10E1600054A000FFD5028141F006E020E8048C2194 +:10E170009648D502F10DC2049F119720D5028082E6 +:10E18000F007E040E8048C419690D502F20B8460E1 +:10E190008003E244E91BB4FF8A0AFFE4F789F08AAE +:10E1A00080EAF00AE22788079600E90DF00904FFEB +:10E1B000800188079401880F8CE1A40097F888609B +:10E1C00096DBD5F08C819720D5E5F105A48D8429C7 +:10E1D000FE8440F105F6E06FE912F2028E018A62D8 +:10E1E000F20596DBA496FE1440F005F6E06FE90711 +:10E1F000F004A00238002001E603E8054052F804CC +:10E20000125480008CC197B0D590020F80063C0B51 +:10E21000FFF43C0DFFFE8E025C000001FCC94402CD +:10E22000519B4412519AA600A64840002008FE0FB8 +:10E23000DD9E4402519D4412519CA600A648400018 +:10E240002008FE0F441FAE6088205CF0805AE9036E +:10E25000440051A0DD9E44025198A600920196060A +:10E26000DD9E44025198A60092029606DD9E44026D +:10E270005199A600DD9E4412519EA6089600C00E3C +:10E28000A60896005A00010BA60896005A0002073D +:10E29000A60896005A0003038400DD9E4412519F95 +:10E2A0009600AE08DD9EFC0044625198AE704412A8 +:10E2B000D6F8B6018401A9891020800910008008D1 +:10E2C0001030800A1000800B8001802449FFD2C5E5 +:10E2D000A630FC80FC00844184208062808244005F +:10E2E000B10049FFFFE284003C0FFACA3E00041C63 +:10E2F000FC80FC003C13F47D4400003C49FF9B443F +:10E300003C0BF4613C13F47D4400003349FF9B3C1B +:10E310003C0BF45F3C13F47D4400003249FF9B3416 +:10E320003C0BF45E3C13F47D440000C749FF9B2C7A +:10E330003C0BF45D3C13F47D4400003249FF9B2408 +:10E340003C0BF45CFC8080413C53F47C3C13F47D3A +:10E35000D126FC00443000FC42010C7380C0020056 +:10E36000002549FF9B17120300253C13F47D02038F +:10E37000002649FF9B0F120300263C13F47D000387 +:10E38000007449FF9B07100300743C13F47D0003E5 +:10E39000007A49FF9AFF1003007AFC80DD9EB420CA +:10E3A000922696465A180109B44092459686CA04A8 +:10E3B0003C1E00DFD510B420922696465A1801095B +:10E3C000B400920596065A0801048402D50284001E +:10E3D0003C0E00DF3C0C00DF3E07E91DDD9EFC012A +:10E3E000F181441000FC42010473041000165A101D +:10E3F0000206041000265A180232001000F3E6222A +:10E40000E82D021F80024432D5C48E3F5CF08402A6 +:10E41000E8042E17E91DC10A021F80038E3F5CF03D +:10E42000892EE8192E17E91DC116381188004442BB +:10E43000D5C4C905840138020808D510E625E80EC0 +:10E440008C219648381208085A18050984211010A2 +:10E4500000E0D504840038018808FC81FC02F182C8 +:10E46000F281964B96839A5190104E140003FE4A07 +:10E47000964BC9028421223F800397018A03023F01 +:10E48000800585E29AE396DB880340003C165EF146 +:10E49000022096C3E90352210440FE9C4011043639 +:10E4A000964B80434E340003FE9A949180614E1443 +:10E4B0000003FECAE043E8039441964B9A61964BF1 +:10E4C0005EF0896D8001E9034400096C96434E14A7 +:10E4D000000384009603FC82FC003C13F47D44009E +:10E4E000003C49FF9A513C0BF4603C13F47D44001E +:10E4F000003249FF9A493C0BF45A3C13F47DFA0070 +:10E5000049FF9A423C0BF4583C13F47DFA1349FF3F +:10E510009A3B3C0BF45B3C13F47DFA0E49FF9A34B2 +:10E520003C0BF459FC8080413C53F47C3C13F47D5B +:10E53000D12EFC00443000FC42010C7380C002006C +:10E54000004E49FF9A271203004E3C13F47D00034E +:10E5500000A249FF9A1F100300A23C13F47D02039E +:10E56000005049FF9A17120300503C13F47D00033A +:10E5700000B449FF9A0F100300B43C13F47D00036C +:10E5800000B549FF9A07100300B5FC80DD9EFC0230 +:10E5900080A1F281B421A0A9F382F48349FFD3F6CC +:10E5A0008401F10149FFD416F00249FFD42684C04A +:10E5B0008006842049FFD42E8006F1038CC149FFD8 +:10E5C000D4515A6808F7840049FFD41B49FFD3F19E +:10E5D000840149FFD41649FFD3EC840349FFD411C9 +:10E5E00049FFD3E749FFD405FC82FC40AE88844054 +:10E5F000A708E244E81AA10138520901D214A10582 +:10E600009592956A99E68885A7FA00F20002E2EFF2 +:10E61000E802AFE2A1C588C788A7A733A7ABE2C4C9 +:10E62000E802AF2B8C41D5E59DD984A092E15060E2 +:10E6300080258125D736A688E2A2E82EA081382140 +:10E6400015014C22C02A50F00014B50F94AA89027B +:10E65000990D00A40003008400028D418B4810A294 +:10E660000025B54F894200A5000210A20037B54F22 +:10E67000884AA69310220049A08338A11501502290 +:10E6800080349491884112A10003A08438211500A0 +:10E690001022005BD503109300008CA18CC1D5CB58 +:10E6A0008C2184A0849FD30FB440382115005A28B0 +:10E6B000FF04AF08D505A18138230901AE888CA1DC +:10E6C0008C21D5F2FCC0FC4A2E77C5435CF10024B6 +:10E6D0008120B63F2E67C54250A3FFFFE909FA1318 +:10E6E0003C0BF4CA4083040880298400D5043C2BE9 +:10E6F000F4CAD5F9E207E808B0C23820A0053821ED +:10E7000081098C01D5F8B43F80473C33F4CA4440BA +:10E710000055B00249FFFF3DF0814412CD18B41FEF +:10E72000F201806749FFFF634014A0008400E20704 +:10E73000E8090220FFFFB0C28828382181098C0136 +:10E74000D5F7B43F80473C33F4CA44400055B0028B +:10E7500049FFFF1FF0814412CC84B41FF20180678F +:10E7600049FFFF458400E206E80838148101B082C1 +:10E77000381101098C01D5F8B43F80463C33F4CA06 +:10E7800044400032B00249FFFF04F0814412CBF054 +:10E79000B41FF201806649FFFF2A42942873840067 +:10E7A000E206E80838148101B082381101098C01B1 +:10E7B000D5F8B43F804644400032B0023C33F4CA3E +:10E7C00049FFFEE7F0814412CB5CB41FF201806682 +:10E7D00049FFFF0DFCCAFC4683C02E07C542F385E6 +:10E7E000F486F0812EA7C543C907406088068401DE +:10E7F000C20984FFD508C20484C3841FD5FB84C228 +:10E80000841F84E1F301FED4808388819521F38401 +:10E81000403F10003C43F4CA22918000F387E08916 +:10E820004EF200F59710F4889708F489F308F40580 +:10E830008883A6E1F38AF40AF30588832032002551 +:10E84000F409F382F3068883A6E1F38BF40BF30655 +:10E8500088832032002538429800F383C4048484DE +:10E8600038429808F30242938824E06AE903F302ED +:10E870008E618923F30142438824FEFC048F8001CA +:10E880008C8141C18408814142321C2442A1A07381 +:10E89000806A94D9850040AF0C00B71FE124E90BD2 +:10E8A00038F520114EF70005B47F886FB67F8C8154 +:10E8B000891CD5F5B47FCB038461B67FF303F401E3 +:10E8C00042A00424E064E8038943D504F4038E8164 +:10E8D00089449501429004248D218064F4044244CB +:10E8E000807395218780408F1000809CE149E90A60 +:10E8F00038F470114EF70003888F8D2141CE0C0043 +:10E90000D5F6CC028481F3018847FE9C40808000CC +:10E9100040912000854A39CF25113CFC00DFE91FDA +:10E92000B43FF2054230A824F10A403190765010ED +:10E930008034944988414490005AA513F20444104D +:10E9400000508848FF0C429E24244410006440423A +:10E950000496382F091140948536D520B47F424261 +:10E96000282440320C76F40B049F80065042003479 +:10E9700095218924882202F4800344400050382FD6 +:10E9800005114410005A4490006442479024421EEE +:10E990000424404224964090A536F10722F08000DE +:10E9A000E08FE840F102E423E804F103E423E93ACC +:10E9B000E122E838E47538329800E8035A38043325 +:10E9C000F103F2098E21422004739652F202F408F8 +:10E9D0008E4142438873852496A238929808992ED6 +:10E9E000CB03AEA4D5102032000442F38824FFDC10 +:10E9F000E0EFE802AEA42022000842F00424FE1456 +:10EA0000E00FE81010120008D50D8E84E1243802C2 +:10EA10009800E804C0078E01D503C00484043802BE +:10EA20009808FCC6FC46F1892E17C5438383F18202 +:10EA3000F48AF58B2E37C542843FC802842194D9CD +:10EA400043E080243C43F4CAF387423F0424F3812B +:10EA50008A608E8494D9F484F38895018540F3020A +:10EA6000E143E862F30A3831A8005A38014DF3094E +:10EA7000886AA6D95A30FF34B4BC383290005A3074 +:10EA8000FF2FBE01BF05B6DF38630D0197AFC80584 +:10EA900094F28867A7D9D50338739A004233842447 +:10EAA000F383F308813E88648865F38684A08060E0 +:10EAB000F703E0E9E915F70188E5F785F70638F38C +:10EAC0009500B4FF3883BD015484003F4C8340055A +:10EAD0005AF0FF03F3058D2188A1D5EB806020510A +:10EAE000002442608C24FF4CE0C5E809A750E6A34F +:10EAF000E9038EA1AF50A750E6A3E811103100241E +:10EB00008464D50CF30B10010024F5043831901106 +:10EB1000E065E805A6D0C3038E61AED0F3078D4152 +:10EB20008C418883D59DFCC6FC422E87C542F2816C +:10EB30002E77C543CD63B0838142B181C00451C0FB +:10EB40007FFFD50283809EBAE241E8038EE1D502C1 +:10EB50009DC944200032FF1444200064F0834042E9 +:10EB600008978520F503E225E91004F50000B44676 +:10EB700042243C7338F18911E28FE903D003D102BA +:10EB80008D2A8CA1F583D5EFF083B4AAB446422434 +:10EB900014733C9BF4CB382189114E270004E28288 +:10EBA000E80284404C00800FF18304F50000B4A615 +:10EBB00042543C73385195114E570005E285E902E5 +:10EBC000884515CF80034DC0000CB4AAB40642049A +:10EBD000147338018111E408E9038E078840F78334 +:10EBE0004C708012B42AB4064204047338018111B7 +:10EBF000E408E9098E078840D506B08180E88142A3 +:10EC0000B183D59D840AFE14404010974002240031 +:10EC1000FCC200008E61E6643C53E2A93C43E2AAD8 +:10EC2000E826FC002260000044F0EB3838378C0006 +:10EC300040F1BC004A003C000410181CE026E91911 +:10EC400022100001E041D5108EA19A69E0C1D5F8EB +:10EC5000E026D5048EA19A69E0C1E90B22100001DB +:10EC60008E819A22E02056078001D5048400DD9E23 +:10EC70008400FC80FC00442000FC4200887380C0BB +:10EC80008401100300CA5013000C500300D28444C6 +:10EC9000490021044400009612030066FC804420D1 +:10ECA00000FC4200887322F0000984205EF784B7DC +:10ECB000E902842114100025DD9E442000FC42005E +:10ECC000887384211410001610100055842014102D +:10ECD000000FDD9EFC5DF082F2818101FA548420F8 +:10ECE000B016490020E58420FA54B01F490020E006 +:10ECF0008420FA54B028490020DBB0318420FA5433 +:10ED0000490020D62E07C542B61F2E07C543F090F6 +:10ED10003C03E2A9F0953C03F4575CF00190E80451 +:10ED20008C013C0BF4573C03F4565CF00190E80472 +:10ED30008C013C0BF4563C03F4555CF00190E80464 +:10ED40008C013C0BF45584208041F0014432CD18F5 +:10ED50004442CBF04452CA3049FFFD3FF0108420BA +:10ED60009F8197B2F00180464432CD184442CB5C7B +:10ED70004452CA3049FFFD31B41F84408E019602CF +:10ED8000F092F112F0014432CC844442CBF0445270 +:10ED9000CA3049FFFD22F001F11280464432CC8492 +:10EDA0004442CB5C4452CA3049FFFD178400F085D1 +:10EDB0004402CB14F083B016F08884004492CD183E +:10EDC000F0865004806E50648025F08485400004F5 +:10EDD0008000E340E82A08030001C022000300236A +:10EDE00000730011F087F004F107F206A50084001B +:10EDF0003C0BF4CBF301800784A049FFFE975CF045 +:10EE0000005B4EF206A7F00388E0F003F1079A38A2 +:10EE1000E220E90608038001C0F94800069BF004DF +:10EE20008D418C02F084D5D4F0055A0001044800CD +:10EE3000068384004412CD184422CB148068B11696 +:10EE4000F50149FFFDF1F0124412CC844422CACCF2 +:10EE5000F5018068B11F49FFFDE7F0028420F087CB +:10EE6000502009D880A0B405C0118E04E602E90E36 +:10EE7000000280F3E602E90A0402800FC8070402D8 +:10EE800080205CF00065E9028421505280FCDAECBD +:10EE90005A18010C840A3E07FFFCB41FF6029401C5 +:10EEA000F0948400F083D50D2E07FFFCC0F78E018F +:10EEB000D5F3B406C80DF003506300FC8C01F08359 +:10EEC0002E07C549F103E220E9F5480005C75A00BD +:10EED00005F45A080404480004D80003001C041474 +:10EEE0000004F08C94018801A641A600F18DF08900 +:10EEF000000F8034B43F10030065000F80248E2182 +:10EF0000100300640403000FC80804040005F20C99 +:10EF100038000A00C010D5035A000115B41FF1864D +:10EF200050907FFE4402CA3CF08F841FF08B440255 +:10EF3000CC84D5114412CA84F18F8421F18B8121B4 +:10EF4000D5074412CA84F08B8120F18F8400F086AB +:10EF50004402CD18F10C944AF193F2130414000505 +:10EF60008822B45FA7C88E41A749CF08DA084400B9 +:10EF700000FFF08E8401F084D551DA4AA68AB47F6E +:10EF8000A74BF1064211887394498460E2A2E940DC +:10EF9000B488888138420C005A40FF220474000172 +:10EFA000387391019902A7215A40FF1A04AF800CCF +:10EFB0004C75401680248820F48E0020805B00A0D1 +:10EFC0008037007080495012003494498801F28AD9 +:10EFD000A5034EA3000914AF8005D508F4148C4195 +:10EFE0008864D5D550057FFFF085F0108E02E207CA +:10EFF000E804F0108E01D5029C39F0888027800A41 +:10F00000F206F30184A049FFFD91F084D50B440082 +:10F0100000FFF08E8401F08484E08147F78AF7884E +:10F02000F785B43FF005F305FE0CF1069881F10178 +:10F030008809949194018841880184208121F1916B +:10F04000F408E083E911384104114E470005F51139 +:10F0500088A4F591384004114E4700038924F41424 +:10F060008C618824D5EEF10580048A01FE03842793 +:10F07000429004734E9600038521F111840AFE0C20 +:10F0800040902536F103F00249FFF95F00030018B4 +:10F090009606C0753C03F45D0413000F8440120310 +:10F0A0000034102300CBC1258421121300258423B2 +:10F0B00014130016102300554EA20006F1108E21E5 +:10F0C0004C70C0058C0A12030034000F8028F10A2E +:10F0D000B45F1003007DF00642008873F101380030 +:10F0E00081111203003F020F800812030028D50E81 +:10F0F000440001901203002584011403001610033C +:10F1000000551213003F1213002822130008840038 +:10F110008465121300671213002E1413001C0213CF +:10F12000000910030054103300571213002FF30C82 +:10F130000414000384401223002638108D011003AC +:10F14000007410030075100300761003007710039D +:10F150000078100300791003007A1003007B10037D +:10F16000007C84001403002084011493001B1213FC +:10F1700000291023005610030084D5780403000FE3 +:10F18000C0254EA20006F0108E014C7040073C03D3 +:10F19000F45D8C0A120300340003007DB45FF106B5 +:10F1A000421008738001F101380081112213003FE1 +:10F1B000E020E8031203003F02030028F104E2010B +:10F1C000E805020F800812030028020300255CF006 +:10F1D0000190E80E5023006C8C0112030025B4024C +:10F1E000A0518809B602220300088801A811B406BC +:10F1F0005A080108A4361203002EA4371203002F68 +:10F2000002030028F104E201E805020F800812035E +:10F210000028F10C04040003380005012213002922 +:10F22000E020E80D96031203002944100064FE0C50 +:10F230003C17F52F40000416120300682203002E2D +:10F24000222300089A824E240003FE922213002FEC +:10F25000220300099A084E040003FE020413002052 +:10F260008802E220E803140300203C7C00DF8400D5 +:10F2700010030048CF2F0403000FC02C5A000103D5 +:10F2800084034412CA3038208000C2248801F20B63 +:10F29000F30D2010000842F10C24FE54E02FE91A6F +:10F2A000F10920000004FE4AFE02E001E913020316 +:10F2B00000285CF00029E905840110030048D50A04 +:10F2C00000030057C00784218E011013004810036B +:10F2D0000057223300085011FF9B96495CF083775A +:10F2E000E90444000037D50344000064842FCF02B2 +:10F2F000FA2E002300484E2300960423000F4E22CE +:10F3000000920423000C5A2802044800008C0423B5 +:10F3100000168E42E6424EF2008622230006E022CC +:10F320004EF2008152F0843FE04FE87C0213002847 +:10F33000E201E9780423001122030067CA498A0325 +:10F340004E040003FE02E61EE943021300254000BE +:10F350000417E605E93D0213002F50F0FFB95CF7F2 +:10F3600088DFE83600030055C8590003009E5A089C +:10F3700001568542F002F10310A3005449FFFC7CC2 +:10F380002213002E5000FFA196015CF00383E904D4 +:10F3900010A300CBD54322030067E001E8055EF02F +:10F3A000005FE907D50AE020E8085EF003E2E9051E +:10F3B0008402100300CBD5328401100300CB50131C +:10F3C000005C500300D2844449001D68D527021315 +:10F3D0000025E624E9049E11E602E8053C03F45CFE +:10F3E000E201E82000030055C8190013009E5A18D6 +:10F3F0000116001300F3E622E80410030054D50EB2 +:10F40000842210130054100300CBF103F00249FFD3 +:10F41000FC334400003212030066F002F10349FF9E +:10F42000FC4E000300482E47E983C0070413000F79 +:10F430004E130088480001610403000FC0F8040364 +:10F440000011C8F50403000C5A0002F20403001670 +:10F450005A0005058E02E602E8EA2213002F220375 +:10F4600000099A084E040003FE022E37C57344209B +:10F470000032FE9C0233002844F003E8FE9C402149 +:10F480003C57E2402213002E22530008E8D05CF0E3 +:10F490000029E9CDB55F0023007DF30642312873D2 +:10F4A00004AF800138F50D112233003F8542403111 +:10F4B000A876E06FE80AF305E043E904F308E062A8 +:10F4C000E8B65CF0012DE9B344F000C8F011404704 +:10F4D0009096E080E8AC9A0D4E040003FE02E4151D +:10F4E000E91D00030055C81A0003009E5A080117C1 +:10F4F000840210030054F103F00249FFFBBD2223F4 +:10F50000002F50117FB996495CF088DFE80722038D +:10F510000009880290011203002FF002F10349FF55 +:10F52000FBCEF10FF00588018420F20FF3089A82D8 +:10F53000E2624EF3FF7D1810000110100023D5F693 +:10F54000040300165A000304480001180223002592 +:10F5500002030034E202E97204030010E602E80B41 +:10F56000020300268C0112030026000300748C01A4 +:10F5700010030074000300485A08010C020300261F +:10F580008C0112030026000300758C011003007526 +:10F590005EF48029E807F004420480245CF007D17F +:10F5A000E90B020300268C011203002600030076FB +:10F5B0008C0110030076020300285CF00047E90C80 +:10F5C000CF0B020300268C011203002600030078F3 +:10F5D0008C0110030078040300205CF00065E90C46 +:10F5E000CF0B020300268C011203002600030079D2 +:10F5F0008C01100300793C03F4625CF00032E808EF +:10F600002E17FFFCC105CF04842514130016041324 +:10F6100000118E21E6224EF200B14E7300AFC803F6 +:10F62000E642E80A3C13F45EE2014EF200A72E0720 +:10F63000FFFC4E0200A38405D5350403001B4000E7 +:10F6400008175CF00038E817F304FEC45CF18ABFC9 +:10F65000E812409024018D2AE735E80D02030028C6 +:10F660005CF00033E80802030026003300768A03CA +:10F67000120300260403001C40000816E40BE90DE9 +:10F68000F21550F17FF5E00FE80802030026002391 +:10F6900000748A021203002602030026E610E90520 +:10F6A000840214030016D5695A18010722030006C4 +:10F6B000E41EE9F7D5085A18020722F300065EF7A0 +:10F6C0008423E8EF00030055C8120013009E5A1867 +:10F6D000010F842210130054100300CBF103F00239 +:10F6E00049FFFACA4400003212030066F002F10337 +:10F6F00049FFFAE5D5420403000C5A00023F040317 +:10F7000000168E02E604E83900030055C812001303 +:10F71000009E5A18010F842210130054100300CBCE +:10F72000F103F00249FFFAA8440000321203006618 +:10F73000840114030016100300550203002F50F03B +:10F740007FB95CF787F2E8192213002E5000FFA161 +:10F7500096015CF00383E80E22030067E001E805F0 +:10F760005EF0005FE907D509E020E8075EF003E2FC +:10F77000E9048402100300CB0403000FC01EF1094A +:10F780004402CB1438100400C109F1098801F10DBD +:10F7900020000024E0014EF201EAF1094402CACC43 +:10F7A00038100400C154F109880120F00024F00D44 +:10F7B000E00F4EF201DCD54BF00E5A00FF49F10983 +:10F7C0004402CB1438000400C00BF00DC809040437 +:10F7D0000005F1138801A741B41F8E01D811F1096A +:10F7E0004402CACC38000400C032B41FF50D8E01AB +:10F7F000D82E04040005F10C38000600C02884044B +:10F8000014030016F00D4E0201B78402001F802879 +:10F810001403000F1013007D5A080104480001AFC3 +:10F82000B41F8E01F10AB45F42008873F101380001 +:10F8300081111203003F020300081203002E02038D +:10F8400000091203002F840012030028040300168D +:10F850005A080111B4068E01E602E80C0013008478 +:10F8600084003C0BF4555A180106100300843C0B2D +:10F87000F457A43612030030A437120300314400B9 +:10F880000032480000BC0003001896164E0200DE4D +:10F89000045300165A58010584003C0BF45600939B +:10F8A00000658400B43F003300641003004E8009FB +:10F8B00042018473F101224300293810811184032D +:10F8C000FE0C9461E0208401E80584021003004EE0 +:10F8D0008400022300285CF10047E9083C1C00DF9B +:10F8E000C90584031003004E800102730025041330 +:10F8F000001C5CF1003840109C36E90750F0FFEC2A +:10F900005CF78410E80DD5045CF1002EE91C5CF076 +:10F910008438E91002F300745CF78046E80B3CA3DE +:10F92000F4578F415CF50031E9042EF7FFFCE80243 +:10F9300084005CF10049E90750F0FFF65CF784248D +:10F94000E902840002F300685CF78032E8095EF2A5 +:10F950000096E8069F0D5CF2042FE90284003C4308 +:10F96000F4575CF20065E90F02F300745CF780461F +:10F97000E80A5CF10033E90750F0FFFC5CF78430E3 +:10F98000E90284005A58050384008E825CF200303C +:10F99000E82C5EF08028E80722F3002E5EF780282E +:10F9A000E90AD5235EF08410E92022F3002E5EF7E9 +:10F9B0008410E91B4442CA8438420C00C409444202 +:10F9C000CA84888320420024E089E90284004442FA +:10F9D000CA3C38420C00C4094442CA84886420F1FD +:10F9E0008024E12FE90284005CF10051E9028400E7 +:10F9F0003C33F461E267E80684051003004E48FFDB +:10FA0000FA5C5CF1003D0433001BE90B40F19DF70B +:10FA10005CF78038E9068E2A5CF084254EF2FA4DB8 +:10FA20005A58010448FFFA495A00010448FFFA45B0 +:10FA300004130026140300165A10010448FFFA3D6F +:10FA40001003005648FFFA39A43612030030A437D9 +:10FA50001203003148FFFA31441000FCF202422048 +:10FA60000473B0F18481B168F0074C01003DF007E8 +:10FA7000B4008E01E603E832F007020000345CF0C7 +:10FA800000C8E9039600D503440000C7F10704103D +:10FA900080165A1002045A180507F607026300255B +:10FAA000E206E9035A18041BF007041400050000DD +:10FAB000001C94028801A642A783E2C1E90FF00767 +:10FAC0000400000F5A08010538009408D5055A08AB +:10FAD000020438408C088C21D5F1F007500000FC5E +:10FAE000F087D5C384004412CD184422CA848068AC +:10FAF000B128F50149FFF798F0124412CC84442252 +:10FB0000CA3C8068B131F50149FFF78E3C03F462CD +:10FB10003C13F45FE201E8048C013C0BF4623C030B +:10FB2000F457C8063C13F463C1033C0BF4623C0B6E +:10FB3000F463FCDDB41F4492CC848E01F086B01FC8 +:10FB4000F0884402CACCF0838401F08548FFF93B79 +:10FB50000003001100130023E0204EF3F962F208C5 +:10FB60008461383100088C01D5F884041403001630 +:10FB700048FFFE6E840148FFFE4B840048FFFE54A0 +:10FB8000442000FC420088738421141000261010C9 +:10FB9000009E842014100023DD9EFC4AF0852E0771 +:10FBA000C5428141F0822E07C543F288F08B3C03A9 +:10FBB000E2AA3C13E2A9F08D3C03F4545CF00190FE +:10FBC000E8048C013C0BF4543C03F4535CF00190CA +:10FBD000E8048C013C0BF4533C03F4525CF00190BC +:10FBE000E8048C013C0BF4523C03F4515CF00190AE +:10FBF000E8048C013C0BF4513C03F4505CF00190A0 +:10FC0000E8048C013C0BF4503C03F44F5CF0019091 +:10FC1000E8048C013C0BF44F4000840AF08EF00D98 +:10FC2000F6059001F0918400F0812E07C549F1019D +:10FC3000E2204EF204CDB4064E0204C35A08050475 +:10FC4000480004BF5A0804044800042B0003001CA9 +:10FC500004150004F08994018801A641A600F192E0 +:10FC6000F09304030023C809F00904150005940269 +:10FC70008801A602C00FD5035A000111F00B4412EF +:10FC8000CB5C8E01F083F00B8E02F08C841FF0872A +:10FC9000D50B8421F187F18CD504F087F08C84009A +:10FCA000F0834412CBF0F0099402F090F2100405B6 +:10FCB00000058802F20BA6C28E41A743CB04DA04EA +:10FCC0008103D541DA3FA680A6C1F402F003FF0408 +:10FCD000E262E938B4AA9814380281005A00FF1C85 +:10FCE0000455000138528101980AA6015A00FF14F8 +:10FCF000F709DF1198885000003494010031005B4F +:10FD0000880100710037F38A00910049A503CF05EF +:10FD1000F786D5058C41D5DD9E39F086F0028E023E +:10FD2000E209E805F00250807FFFD503508480018E +:10FD300080078029F203F30884A149FFF6F7F084D5 +:10FD4000D50A85008401148F8006F084812880E81C +:10FD5000148F800AF002F1039401F2084220047328 +:10FD6000F10CF308848042300473F48CF006E10057 +:10FD7000E90F381101114E170005F50C88A1F58C1B +:10FD8000381181114E17000388818C01D5F1F006DE +:10FD9000842740040001FE0342400473F48F4E4662 +:10FDA00000048401F08FF005F10149FFF3BE001358 +:10FDB00000180403002396464E1200CB3C13F45B5C +:10FDC00012130056C02384011203004E840314034F +:10FDD000002684001003009EC705F0028E014C909F +:10FDE00040058C2A12130056000F8028F103F202FE +:10FDF000100300A6F00A42008873F1083800811150 +:10FE000012030054020F8008D50C44100190121305 +:10FE1000004E8421141300261013009E1203005478 +:10FE20003C23F4583C33F4542213000912030052CB +:10FE3000E24384001413002C12030050100300A2AC +:10FE4000100300B4100300B5100300B6100300B790 +:10FE5000E9028401100300AA3C03F453E240840148 +:10FE6000E8028400100300AB8401100300C43C03CB +:10FE7000F467C82F2E20043F5A28012C3C0C00DFC9 +:10FE80005A0802135EF08096E82422F300085EF719 +:10FE90008096E81F8466143300262E37E8ECC319D9 +:10FEA00014230023D5145A0801155EF08096E8113A +:10FEB00022F300085EF783A3E90C8446142300268E +:10FEC0002E27E8ECC2061403002384031403002544 +:10FED0003C03F465C8312E00043F5A08012E3C0C47 +:10FEE00000DF5A0802145EF088CBE92622F30008EE +:10FEF0005EF78096E8218426141300262E17E8EC7E +:10FF0000C11B140300238404D5155A0801165EF0A2 +:10FF100088CBE91222F300085EF783A3E90D84067B +:10FF2000140300262E07E8ECC00784021403002304 +:10FF3000840514030025804AF109A0153800060045 +:10FF4000F110100300C8A0158801A601D556C023E2 +:10FF5000C705F0028E014C9040073C03F45B8C0A0D +:10FF600012030056F103F202000300A64200887358 +:10FF7000F1083800811122130054E020E803120335 +:10FF8000005402030052F104E201E805020F800868 +:10FF9000120300520203004E5CF00190E80B8C014A +:10FFA0000413002C1203004E2203000988011403DD +:10FFB000002C3C03F4583C13F454E201E90484217E +:10FFC000101300AA3C13F453E201E9048401100366 +:10FFD00000AB804AF109A01538100600000300C8E4 +:10FFE00088019001100300C8F110A0158801A641F6 +:10FFF000000300C9880190013C9C00DF100300C988 +:020000021000EC +:100000005074FFFFE6E2E913440001901203004E32 +:100010000413002684011003009E841DFE0E5A085E +:100020000107140300268400140300238400E6E281 +:1000300010030048E83404030023C0315A080108C3 +:1000400084205A98010E841F8422D50A5A08020778 +:100050005A980105841F8423D503840180204422FB +:10006000CA3038210400C21B4432CA308823F2123D +:1000700020308008FE84FE1CE002E911F207F01334 +:1000800020108004FE14FE54E020E909020300520F +:100090005CF00029E90484011003004800030048D3 +:1000A000C86704030023C0640403000C5A00026103 +:1000B0000223004EE64BE95C040300265A080307BE +:1000C00004130025E622E827D5035A080225A47761 +:1000D0008E305CF0894CE81F021300525CF0804CBB +:1000E000E81A000300555A0801400003009EC83C6E +:1000F000001300F3E622E9368422101300541003A3 +:1001000000CBF101F00549FFF5B7440000321203BE +:100110000066D52A8E02E602E82BA4378E105CF02A +:10012000094CE8263C03F45DE202E92204030025C1 +:100130005A00020A5A0004085A9002085A00031989 +:100140005A0005175A980115020300525CF0004C42 +:10015000E80F000300555A0801080003009EC80478 +:10016000840210030054F005F10149FFFD0B000368 +:100170000048C86304130023C1600403000C5A0044 +:10018000025D040300265A0006058E02E602E855C9 +:100190005A180105000300AAD5055A18024F00039A +:1001A00000ABC84B2213002E220300089A084E040D +:1001B0000003FE022E27C57244100032FE540223B3 +:1001C000005244F003E8FE544010BC37E220E8350A +:1001D0005CF00029E932001300A6F303F402804129 +:1001E00042219073F30838F189112223005484626C +:1001F00040210C56E04FE809F206E022E903E10154 +:10020000E81C5CF0012DE919000300555A080112A1 +:100210000003009EC80E842210130054100300CB6C +:10022000F101F00549FFF52844000096120300662D +:10023000F005F10149FFFCA6041300230403002686 +:100240004E1200E35A000304480001020223004E4C +:1002500002030056E2024EF300AD04230024CA0B51 +:10026000000300A28C01100300A2000300B58C0162 +:10027000100300B5F30C840AFEC48003F30F4000A2 +:100280000C165EF001C3E808F304444057E442F062 +:100290000C24E28FE80B003300A28C61103300A223 +:1002A000003300B78C61103300B7003300485A3870 +:1002B0000114004300A2E6428C81104300A20043D7 +:1002C00000B68C81104300B6E909021300508C215E +:1002D00012130050D52DE642E82B5A1801155A98F2 +:1002E000010722F30008F10EE02FD5075A98021FEC +:1002F00022130008F20EE022E90F22130009E42B7A +:10030000E815D50A5A180213F10D2223000950F0FE +:10031000FFF5E04FE90B021300508C21121300503F +:10032000001300B48C21101300B45A3001D05EF0D9 +:100330000029E806F104FE0C5CF007D1E90602038F +:1003400000508C0112030050020300525CF0004C7C +:10035000E908E6E2E806020300508C0112030050AF +:10036000040300205CF00065E908E6E2E80F020300 +:1003700000508C01120300505A9802090403002512 +:100380005A0002105A080464D5075A980161040300 +:1003900000255A0805053C03F464D5055A0803589E +:1003A0003C03F4663C13F459E2208406E82AD54F56 +:1003B0000403002C400008165A180208F10D50F0F2 +:1003C000FFF5E00FE81DD5155A18011B5A980107D3 +:1003D00022F30008F10EE02FD5075A9802122213DB +:1003E0000008F20EE022E803E41FD502E40BE9085E +:1003F00002030050001300B48A011203005084026B +:1004000014030026D5240413000C5A1002219E4226 +:10041000E622E9048E05E602E81A000300555A08B0 +:1004200001120003009EC80E842210130054100312 +:1004300000CBF101F00549FFF41F440000961203C0 +:1004400000668401140300261003009E04030026A6 +:100450005A080123040300165A08011FB4068E012E +:10046000E602E81AF01122F30009001300C4E00FBD +:100470008400E90A3C0BF4545A18010F100300C41D +:100480003C0BF452D5093C0BF4535A1801061003E7 +:1004900000C43C0BF45044000032480000830003C9 +:1004A000001896164E02008D042300265A28010ECD +:1004B000F01122F30009E00F8400E9043C0BF45131 +:1004C000D5063C0BF44FD5035A20060784001003D1 +:1004D00000AE8421D5058401100300AE84200033D2 +:1004E0000064F4020003006542019073F30838F1E0 +:1004F0008111220300298463940140000C16E00F4F +:10050000E8058402100300AE842002430052023347 +:10051000004E0403002C5CF2004C40000C16E90F66 +:100520003C4C00DF8E81E682E80A50F07FD85CF711 +:10053000891CE9088423101300AE84205EF07FFC40 +:10054000E90CF40D8C83E080E908004300A200531D +:1005500000B58A85104300A23C43F460E283E903BE +:10056000E662E8058425101300AE842004330020E1 +:100570005CF18065E9193C3C00DF8E61E662E814BD +:10058000003300A6004300C8E264E905004300C947 +:10059000E283E80A50F07FD85CF7891CE9058406FD +:1005A000100300AED50D5A20010C5A18010A04039D +:1005B0000016141300265A08010410130056F00107 +:1005C000506300FC8C01F08148FFFB313C13F45474 +:1005D000C9063C03F467C0033C1BF4663C03F466A5 +:1005E0003C23F459E240E9048C013C0BF4663C1BCB +:1005F000F4673C13F453C9063C03F465C0033C1B89 +:10060000F4643C03F464E240E9048C013C0BF464C0 +:100610003C1BF465FCCA442000FC420088730410B3 +:1006200000265A1806243C1C00DF5A18011002103C +:10063000000950F0FF6A5CF78835E91822100008BD +:10064000440003A240000407DD9E5A180210021065 +:10065000000950F0FF6A5CF78835E90822000008BD +:100660005EF00096540780FFDD9E8400DD9E4420EE +:1006700000FC420088733C33F4752220000880207F +:10068000E062E90822F000093C43F4748402E08F40 +:10069000E80C52F1843FE04FE90E224080093C0310 +:1006A000F474E004E9148403140080258401140028 +:1006B0008023DD9EE062E9193C03F4742220800966 +:1006C00052F0096BE04F8404E910D508E062E8F5C8 +:1006D00052F0096BE08FE90984051400802584023B +:1006E000140080238401DD9E8400DD9E442000FCF4 +:1006F0004200887304100023C10A5A18010B2220FB +:1007000000095EF17FFCE90EE45FE9128422D51056 +:100710005A1802113C23E2AA223000099D13E083FB +:10072000E8038420D5058E5FE062E902842114107D +:100730000024DD9EFC4184C0F08181215070008C3A +:10074000814685022E07C549E2C0E85C0013FF8C94 +:100750000403FFDD9646C129C028F001802649FF29 +:10076000FF88C818F001802649FFF29B0403FFE4CC +:100770000414800594028801A642A603C9065A0003 +:1007800023098401B607D5065A082304B707D50202 +:10079000B7472FC7E8EC4FC3002EF001802649FF72 +:1007A000F28015C38000D5268E01E603E827F0010C +:1007B000802649FFFF5E5A00011AF001802649FF9A +:1007C000FF2C8380C813F001802649FFF26A0423BE +:1007D000FFE40404800594928840A612C007A61383 +:1007E0005CF00023E80315C380002E07E8ECC80284 +:1007F000B607F001802649FFFF7B8CC1507380FC57 +:10080000D5A2FCC1FC20442000FC42008873047087 +:10081000000F80C0CF05840314030010D52E5A7832 +:10082000010E220000085EF07FF3E912E40BE91CE0 +:100830005EF000298402E91CD51A5A78021C3C0398 +:10084000E2A9221300085020000CE041E8038400D4 +:10085000D50F50F07FF5E02FE9038401D50950F062 +:100860007FD7E02FE90414730010D5048403140328 +:1008700000103C0C00DFC0038400D50E5A78011034 +:100880005003001044100064442000C8846349FFF2 +:10089000F1C34003801B14030011D50B5A78020AE0 +:1008A0005003001044100064442000C88464D5F054 +:1008B000FCA0FC41F08183812E07C542F101852017 +:1008C0005060803C80E9810950A07FFF2E07C54918 +:1008D000E320E84500137FDC04037FF19646C11353 +:1008E000C01204037FF8B90594028801A640A7410D +:1008F000C90584014C554006D5234C55402284023D +:10090000B606D5218E01E603E826B4065A08010D85 +:1009100004037FF8B90594028801A640C911A741D4 +:100920004C554012D50D5A08020F04037FF8B90543 +:1009300094028801A640C104A7414C5500058CE1F2 +:10094000B70697F82E07E8ECC802B606F001802932 +:1009500049FFFF5A8D21506300FCD5B98007FCC1C7 +:100960003A6FA6BCEFF880C080E2501F8006B4004A +:10097000FA40846349FF873A020F8003A470B607E8 +:100980003C0DFAA744928F70FA4002000011846473 +:100990008A010014800F9201400004371013801068 +:1009A000B406501F800649FF8721020F8003A47000 +:1009B000A8393C0DFAA73C3DFA9184810200001150 +:1009C0008A010014800F9201400004371013801137 +:1009D000B406A072A0B60031800C49FF8742EC0833 +:1009E0003A6FA684DD9E3A6FA8BCEFD880E18144BF +:1009F0005A480404A006D502A00500110010509F1B +:100A0000801C84C0443000320051000F8083B63F08 +:100A1000F6818020F682F683149F8004844549FF86 +:100A2000BD3A020F800E02148003AC38020480012C +:100A3000AC7AAC3922048002AC3B5AA0040B3C13C4 +:100A4000E6343E67E950E001E80484013E07E950DE +:100A5000EC283A6FA884DD9E3A6FAABCEF5C812334 +:100A60008460814081013E37E95049FFFF7B84006B +:100A7000003480028020B118B16044607FFF96800E +:100A8000E243E80AB09038120109381101093862CE +:100A900081098C01D5F50044800344000080F08377 +:100AA0000405000684C084E194598E818820B67FB5 +:100AB000F382442232E8972080A7F781F684F685F6 +:100AC000F686F787F688F689F68A49FF86F00034BD +:100AD0008002440FFFE2F088FA0E00448003B67FE4 +:100AE000F089501F803E040500060425001180A7F0 +:100AF000F681F682F683F684F685F786F687F68A1F +:100B0000126F801F49FF86D30044800300348002A7 +:100B100044000080F0838E81440232E88040B67F3A +:100B2000501F803E972080A7F681F682F684F685D6 +:100B3000F686F687F688F689F68A127F801F49FFC7 +:100B400086B60044800300348002FA00F0888E816B +:100B5000440232E88040B67F501F803E972080A735 +:100B6000F681F682F683F684F685F786F687F689AF +:100B7000F68A126F801F49FF869A0044800384081A +:100B800000348002F087040500118E818040B67F1A +:100B9000F382441232E8972080A7F781F683F68427 +:100BA000F685F686F688F689F68A49FF868000443F +:100BB000800300348002B05084058E818041B67F6E +:100BC000F08897200405001180A7F781F682F6834C +:100BD000F684F685F686F687F689F78A49FF8667F2 +:100BE000004480030034800244000080B058F08349 +:100BF0008E81841B8041B67FF08997200405001107 +:100C000080A7F781F682F684F685F686F687F68861 +:100C1000F78A49FF864C003480028404F087B020B4 +:100C2000804000448003F3820415000680A7B6DFED +:100C3000F781F683F684F685F686F688F689F68AD5 +:100C400049FF8635003480028411F088440FFC1877 +:100C500000448003B67FF089501F803E04050006E3 +:100C6000442232E880A7F681F682F683F684F68580 +:100C7000F686F687F68A126F801F49FF86183C0DAC +:100C8000FAA70044800280460250000E8E81976BC6 +:100C9000802683C680068066E0E4E81CB19038F3C5 +:100CA0001D015CF78012E9068C618C0196D99601D2 +:100CB0008441B19838F31D015EF78012E908506F46 +:100CC00000018C2141E30013964984418CE197F89F +:100CD000D5E43E20041F84403E200421222F804082 +:100CE000E450E909022F8020E64CE9058C019601C9 +:100CF0008441D5028440B1E038739111E4F0E90AEF +:100D0000B19038731101E6ECE9058C418C019691A4 +:100D10009601027F8030E6EC84E0E9048C2196495C +:100D200084E1B19838431101E68CE9088C21964999 +:100D3000C20B8CE197F9CB04D507C205C3048441EB +:100D40003E200421C7064FE2000584413E200421D5 +:100D5000E630E803E610E90584013E000420D504EE +:100D600084003E000420800A8028804984608484B6 +:100D7000F58D49FFFE3A22F40002F50D5EF780651D +:100D8000E90484013E0004212E07E91F5A080107E7 +:100D90002214000344025198AC405EF28065E904DD +:100DA00084013E07E9142E07E9145A080107E4BE3E +:100DB000E80484003E07E91422F400035EF780DCB7 +:100DC000E80484013E07E95044007FA6120F801F0B +:100DD00002040000C83902040001C0362E07E94CA5 +:100DE00004350006C81E9481884322FF801FA4504A +:100DF000964BE02FE806A4503C0BF4EC121F801F2A +:100E00008C015A0A40F23C03F4EC94019858A4086F +:100E100096035EF07FC9E81D84013E07E94CD519B1 +:100E20003C13F4EC94498823A448964B5EF0FFC928 +:100E3000E80B8C019600E60B3E07E94CE90A8401B9 +:100E40003E07E93BD50684003E07E94C3E07E93BF7 +:100E5000ECA43A6FAA84DD9E3A6FA8BC80C044001F +:100E600000FCEFC842110073CB0E225080044400F6 +:100E7000004422408005405280B644000043404276 +:100E80000096D50AA00F3C1C01ED94018801A741F2 +:100E9000A700976B972380065013006284401A20A6 +:100EA00000014C00FFFE9E6B54A280FF549200FF95 +:100EB0004E15000850257FFD969084208467D50745 +:100EC000FE4A96485230800796D884409FE34E757C +:100ED000000A8407100F80375004FFFD960084E05D +:100EE000D508FFFA97F852038007100F8037840067 +:100EF0008CA3E4B0E9045235001396D88C835EF2DB +:100F00000024E90552948027109F803785274213DB +:100F1000A473940488029489FA20B63F4410008098 +:100F2000F1838420F184F185F186F188F1893C1CFC +:100F3000027884A184E29401149F8002F787004F15 +:100F40008037F581F58A88018846501F803749FF30 +:100F500084AEEC383A6FA884DD9E2E57E9143A6FC0 +:100F60009C3C97205A5001062E60041F5A680108C5 +:100F7000E642E9035A2823044440008738318511AA +:100F80008803E004E9115A5001062E00041F5A0894 +:100F9000010FE642E80C949488224402D47C380085 +:100FA0000511E004E80444008000D50284003A6F93 +:100FB0009C04DD9E3C1C00E02E07E955A68EC81659 +:100FC0002E07C5DC5A0801139411AE0AA6098E013A +:100FD000FE148442400008168E01940196033C0BD7 +:100FE000F4CDFE033C0BF4CCD50FA609AE8A8E01DE +:100FF000FE148442400008168E0196033C0BF4CD8B +:10100000FE033C0BF4CC2E0004215A08010D3C03D6 +:10101000F4CD94033C0BF4CD3C03F4CC94033C0B93 +:10102000F4CCD527C8262E07E9195A080123A60AA9 +:101030009401AE0A2E07E96F5A08010E3C23F4CD45 +:101040008406FE843C2BF4CD3C23F4CCFE143C0BF4 +:10105000F4CCD50F2E07E9235A08010C3C03F4CD3C +:1010600094013C0BF4CD3C03F4CC94013C0BF4CC48 +:10107000A6093E07E90C8C013E07E90DDD9E222002 +:101080000000223000013A6FAABCEFAC9AD3B181C4 +:101090004E340003FEDAACF04637FFFF50318FFFCD +:1010A0005090FFFF882394C93850051198432210AF +:1010B000FFFF9A694E140003FE4A3CA7F4CD970B3C +:1010C000E142384325093C87F4CC3C7C00E0E90947 +:1010D000E048E90722F30000A6FA8421E06FE80364 +:1010E00084408022E145E90AE0A8E908A6FAE06424 +:1010F000E90588458C219693964B9CC2878140FEDA +:101100002406E8262A0180012241800041E01001E6 +:101110004FE4000453EF00002251FFFE9B054E44B4 +:101120000003FF22E09E404F3C1BE1403843710921 +:10113000E90CE008E90AA77A40F20011E0AFE905FE +:1011400088409C099693964351CE0001D5D9A63C80 +:10115000E0018400E804400104169603EC543A6F61 +:10116000AA84DD9E3A6FA8BC51FFFAF0812080E18D +:10117000A006803F49FFBA6B3CAC00E084C000850C +:1011800000050005000BE2C0E8252E07C5438028B6 +:10119000FE349401881F49FFFF7494718827AC08BE +:1011A0008400E208E8152E27C542806642310073AC +:1011B000044480069699043480059491886288449A +:1011C0008C01A490A5088A449693AC98D5EB8CC169 +:1011D000D5D951FF85103A6FA884DD9E3BFFFCBC3A +:1011E000EFF4B61FF18149FFFEE7B41FF101EC0CEB +:1011F0003BFFFC8448FFFFB8FC005A08060484014A +:10120000D5045A08070684003E07E920D51C5A0871 +:101210000D0784003E07E9208421D5075A080E0BEC +:1012200084013E07E92084203E17E95E3E07E94E2F +:10123000D50A5A0810048401D5045A0811058400FF +:101240003E07E91FFC804433F04A444000553C2DE2 +:10125000FAB5A690CA03AF18D5FB3C2C00EB1001E1 +:101260000053C904440FFFA0D503440FFFA1100190 +:1012700000512E07E9705A080305440FFFB1D5034A +:10128000440FFFB010010052443000554423F04A8F +:101290003C0C00EB001000515A10BB04AED0D5F945 +:1012A00084201010005110100052DD9E4413F04AAB +:1012B000442000553C0C00EB000000515A08A004EB +:1012C000AE88D5F9DD9E4413F04A442000553C0C0D +:1012D00000EB000000515A08A004AE88D5F9FC00CC +:1012E0005A08BB0449FF7EAF2E0004315A08A005FE +:1012F00044024000D5085A08A10544021B90D503BA +:1013000044020C604412451049FF82213C0C00EB62 +:10131000441FFFA010100051FC803C1C00EB10008B +:101320008060DD9E3C0C00EB00000060DD9E3C1CFC +:1013300000EB100080613C1DFA361000803EDD9EFF +:10134000FC0080C049FFFF5A84015A68030549FF29 +:10135000A5CC800650137FF3E622E9035A680221E8 +:101360003C0DFA99A7815A6003185A680A0B842920 +:10137000AE41842049FF83C63C0DFA99AF81D50464 +:10138000842049FF83BF49FF7F395A0802063C0D7C +:10139000FA998423AE4184013E0004618402FC80FA +:1013A0004000040E9606DD9E5A0001085A08030B01 +:1013B000B40158000004D504B441841BFE16B601E4 +:1013C000DD9E8402AE10DD9EFC409F01E68B4EF256 +:1013D000007C800144F112E43847900040F23C0068 +:1013E0004A003C00E80C107EB0B6E2BECCDADE006B +:1013F0008407D56E4473F04A4490005549FFE73D99 +:1014000080C05A00020510938000D5F9840149FF7D +:10141000E74749FFE7063C0E033249FFE70C3C0E65 +:10142000033349FFE71A3E000CD149FFE7223E0093 +:101430000CD049FFE7183E000CD284214402D6F8B4 +:1014400049FFBA0B800649FFE72B4463F04A44701A +:10145000005549FFE712C003AFF0D5FC49FFE72074 +:10146000D5183C2C00EB842EAE418426AE4084205F +:10147000101100504423F010AE50842149FF8342E4 +:101480008420840280418461808180A149FF7F168D +:101490008401D51E8401AE10D5118401AE10840ED6 +:1014A000D5178401AE10840149FFA52A8402D51006 +:1014B0008401AE10840049FFA523840DD509FA00EC +:1014C000D507FA01D5058402AE18D5E38406FCC021 +:1014D000FC005A000142C0055A000254480000872F +:1014E000C915FA043C0BF47B4400003C3C0BF47A35 +:1014F000840F3C0BF479FA38FA0E3C0BF4783E0773 +:10150000C9823E17C9838401D5245A180115840F56 +:101510003C0BF47B84083C0BF47A3C0BF479FA0E18 +:101520003C0BF478FA043E07C9833E07C9823E1794 +:10153000C96FD55C5A18025B84083C0BF47B8405A8 +:101540003C0BF47A3C0BF479FA0E3C0BF4788400F3 +:101550003E07C96FD54BC10A5A1801073E17E9115A +:101560003E17E920D5435A1802053E17E911D50662 +:101570005A18033D84003E07E9113E07E920D5369D +:10158000C9083E17E8EC3C1BF4753C1BF474D522EB +:101590005A18010D440000643E17E8EC3C0BF4754A +:1015A0003C0BF4743E10043FD5155A1802073E1741 +:1015B000E8EC440000AAD5075A18030D3E17E8ECE2 +:1015C000440000FA3C0BF4753C0BF47484013E00BB +:1015D000043F2E00043F5A08010A44000E103C1339 +:1015E000F47D49FF81D13C0BE4D6FC80FC00E6058C +:1015F000E84344F115003807800040F03C00DD0F5F +:101600000620405A6A00B462964F4000A008441F6A +:10161000FCFFFE5EFE47B622B42284009228D50D60 +:10162000B462964F4000A808441FF3FFFE5EFE47D9 +:10163000B622B4228401922A964F49FFFF4BD51E51 +:10164000B462964F4000B008441FCFFFFE5EFE47D5 +:10165000B622B4228402922CD5F0B4025800400085 +:10166000B60284003E00043BD509B422440FBFFFFC +:10167000FE0EB602D5038402AE18FC80FC00FA040C +:101680003C0BF47B4400003C44628F703C0BF47ACA +:10169000840F3C0BF479FA38FA0E1013044310034C +:1016A00004423C0BF478842284011003042F3E177B +:1016B000E8EC8400441000AA3E07E9113E07E92047 +:1016C0003C1BF4753C1BF4743E00043F3C13F47D5A +:1016D0004400016849FF815812030236FC80FC4037 +:1016E00080C18420AE40B40280E29211960681242B +:1016F0005A080107B42644020000FE0FB606B407DC +:1017000092119606C806B426440DFFFFFE0EB606DB +:10171000B407920196065A080109B406580000025F +:10172000B606800649FFBCF9B40792019606C80CBC +:10173000B426841DFE0EB60649FFE2593E00043968 +:10174000800649FFBCEAB40796065A080106B406AB +:1017500058000001B606B4079606C805B426841ED4 +:10176000FE0EB606B407920296065A080106B406A3 +:1017700058000004B606B40792029606C805B426BF +:10178000841BFE0EB606B407920396065A0801069D +:10179000B40658000008B606B40792039606C805BA +:1017A000B4268417FE0EB606B407920496065A08AD +:1017B0000106B40658000010B606B4079204960657 +:1017C000C806B426440FFFEFFE0EB606B407920516 +:1017D0009606C806B426440FFFDFFE0EB606B40711 +:1017E000920596065A080106B40658000020B6066F +:1017F000B40792069606C808B426440FFFBFFE0E33 +:10180000B60649FFFF3DB407920696065A08010640 +:10181000B40658000040B6060004800092075A083B +:10182000011600048000963710048000B42784005D +:101830009228964F49FFFE4EB407B4465410030059 +:10184000440FFCFFFE16FE0FB6060004800196064C +:101850005A08011600148001541080FE10148001F3 +:10186000B427922A964F49FFFE35B407B446541068 +:101870000C00440FF3FFFE16FE0FB60600048001B5 +:10188000920196065A08011700048001540000FDD9 +:1018900010048001B4278402922C964F49FFFE1A4F +:1018A000B407B44654103000440FCFFFFE16FE0FAD +:1018B000B606B407920E96065A080109B4065800F7 +:1018C0004000B60684003E00043BB407920E960624 +:1018D000C806B426440FBFFFFE0EB606FCC05A0071 +:1018E0000B135A000C1A5A080A21FC00B441440F89 +:1018F000FFBFFE16B601B40158000020B60149FF33 +:10190000FEBFFC80B40158000040B601B441440F52 +:10191000FFDFFE16D508B40158000040B601B4013F +:1019200058000020B601DD9E8402AE10DD9E00004E +:10193000FC42A7493C6C00EB5A5804112E07E98081 +:101940005A00010D00030050540000F05A00100727 +:10195000440000553E07E978D51F00030050F4818C +:101960008123B65F80E1C0035A08FB1A2E000431C0 +:10197000C00784003E000431840049FF7BCDB41FC2 +:101980004412B36A49FF7E13440000553E07E978CC +:1019900084003E07E96684014800016F5A5001093E +:1019A00049FF7C2C5A080205840149FFB9E0B41FA5 +:1019B0004412B36A49FF7DC784003E07E97B3C0CB3 +:1019C00000EB00600050008000518401100F800F78 +:1019D00084003C0FFAC7A67940A31009979F5A18B4 +:1019E00004212E17E9285A1801063C0FFAD649FFA0 +:1019F000AEEB840149FFB9AA8420800749FF8082A9 +:101A0000840149FFA16B4403F04A44100055AE40E5 +:101A100049FFA14AC0FE4402D3FC49FF7CD6D5272A +:101A2000A6785A10010A4403F04A44100055AE400B +:101A30003C0DFAB5D5103C0FFAD64403F04A4410D9 +:101A40000055AE403C0DFAD6C8EF49FF7BD75A008F +:101A500002FBD5EAA640C1FFA6005A0002093C0DD0 +:101A6000FAAAA6405A1802048420AE408F41E74BE0 +:101A70004EF200DE44F1198438A7A90140F53C007C +:101A80004A003C0016005A00A801A8015A0168014A +:101A90007A01A801A801A8018A014402B3404412B6 +:101AA000B3E249FF7D93B41F4412B36A49FF7D4BF3 +:101AB00080068028804749FFB2958400100F800F70 +:101AC0005A600F04480000B73C0C00EB84CC0000C7 +:101AD00000505A00FB04480000B5480000AC8EC11D +:101AE0008401E6C63E07E97BE87744F119F83867D8 +:101AF000980040F33C00DD0F062442AEB84C840051 +:101B0000100F800F84013E07E9662E07E9204E037F +:101B10000094841F3C0E01114800008F8400100FB8 +:101B2000800F84013E07E9662E07E9204E030087F7 +:101B3000841F3C0E0111480000823E07E96684C202 +:101B4000480000808400100F800F84013E07E96682 +:101B50003C0C00EB001000525A18AA200010005351 +:101B6000440FFFA0FE0F3E00043149FF7A6C840150 +:101B700049FF7AD23C0C00EB000000525A08AA053B +:101B800044004510D5034400475049FF7A583C0CA7 +:101B900000EB8420101000522E07E920C851841F4A +:101BA0003C0E0111D54D4400006949FF7AA5D5428C +:101BB0003C1C00EB8400100F800F84013E07E96697 +:101BC00000008055001080544000200888013C0B24 +:101BD000F4DBFAC2D53684003E07E97BD5288006BF +:101BE0008029502F800F49FFFBE1D518FD034422C7 +:101BF000B3AB503F800F49FFFBE99780D5228006A9 +:101C000080288049503F800F49FFFCF2D5078006AD +:101C10008029502F800F49FFFE64000F800F5A006B +:101C2000020AF101B40984CBB601D50B8402100F6E +:101C3000800F84C1D50684C4D50484C5D502FAC9F1 +:101C4000000F800F84205A0001055A080207843BC8 +:101C50003C0C00EB101000502E07E97BC80C44022E +:101C6000B3404412B3E249FF7CB1B41F4412B36ADB +:101C700049FF7C9D8006FCC25A08073CE625E865C2 +:101C800044F11B903817840040F0BC004A003C002F +:101C9000061E3A505800A660440FFF80FE0FAE208B +:101CA000968F40012008441FFCFFB443D50BA621AA +:101CB000968F58000001AE21441FF3FF4001280811 +:101CC000B443FE8EFE87B643DD9EA621968F580054 +:101CD0000002AE21441FCFFF40013008B443D5F2CB +:101CE000B40358004000D52FB423440FBFFFD52ABA +:101CF0005A080B1D5A100B0B5A100C115A180A26B1 +:101D0000B423440FFFBFFE0ED50CB40358000040AF +:101D1000B603B423440FFFDFD515B40358000040C9 +:101D2000B603B40358000020D50E5A0805135A1004 +:101D300001085A18030BB40358000004D504B42357 +:101D4000841BFE0EB603DD9E44022D50843BAE4044 +:101D5000DD9E9200FC42814144122D50F081F282BE +:101D6000F383A608A78844122D519204A7C8979F11 +:101D700097F85A0801249E31E602E90F5A600304DD +:101D80005A6805403C0C00EB000000605A00A106B8 +:101D90002E0004585A0001364402B3404412B3E204 +:101DA00049FF7C144402B3634412B36A49FF7BCBFE +:101DB000FD03F20149FFB116D5245A000B06541059 +:101DC000000D5A18051F2E27E9689E54E622E804E4 +:101DD0003E20042FD50484203E10042F44922D5021 +:101DE00084201014800080478026F302F40349FF0A +:101DF000FF45000480005A00FB0584011005000027 +:101E0000FCC244522DA0443DD2604422E16C440205 +:101E10002DDC986B381104011A128001D8FBDD9E6D +:101E20003C0E00EF84003E07E90FDD9E3C4C02783B +:101E30004402D79484604452CFB8041000168E2216 +:101E4000E622E910041000268E22E622E90B00109B +:101E500000DE5A18010538128C00C104B4205A184B +:101E6000030D0010006600200067944C88229449FE +:101E70008824A448121000738C61500000FC5A386A +:101E80000ADEDD9EC12C5A1802074442CFB884A155 +:101E9000385200084452CDE04C11001DFC00444271 +:101EA000D00C3842000092839DA1C3045A1802034B +:101EB0009DA3383280004442CDE0E266E8068C61A2 +:101EC000383200088001D50D8420381200088002C5 +:101ED000D5088440382280088001DD9E8002DD9E86 +:101EE000FC80FC42FA2C42018473A041B4E0B63F6E +:101EF0004412CFF404A0000438108C0000900018A5 +:101F00002E67E92AA005F1812E17E95DF08251E3E1 +:101F100000012E07E91140FF0407568780015A008F +:101F200001095A08020C444001A944500154D50A41 +:101F3000444005464450049CD50544400352445057 +:101F400002A82E07E983F0835A880103CE043C03DC +:101F5000F4CED5034400003C50F0FFFE5CF7800354 +:101F6000E8192FC7E9504FC3001640FF0407E80ED9 +:101F700040F09801840942F780245EF78046E80922 +:101F80008AC1FE3450000046D5054400003CD5020D +:101F9000801C3C6DFA9CB4C692C297865A680108B0 +:101FA000E625E8058C1E45E00145D50345E000D750 +:101FB000C212446000FC4412D7944211987300107E +:101FC00080DE84C05A10020384C552110005FE0C45 +:101FD000920288064462D794441000FC81E642F1E4 +:101FE000847303C7800B5CFE15E1401E7837E90B54 +:101FF00050FE6A2041E7FBD640FF0406E8038A3E14 +:10200000D50284204E83000C2E87E9505A8801089F +:10201000505281F4504201F4976997215CFE0FA160 +:10202000E94444F000FC4482D7944281BC730084AC +:1020300000DE21CF800CE70244800064E819425E94 +:102040002073E2AAE80584A9FE6C9221D5084045D8 +:102050000808FF0C405214B792218825F40244501E +:102060000046405214B7E2A1E81E8A25D51D424E13 +:102070002073E28AE8068489FE6440408409D50A18 +:10208000850342552024FF4C404290974010A037D2 +:102090008881F5024410004640128437E224E803A8 +:1020A0009A61D50284208801B43F9449E227E91B54 +:1020B0005CF48029E81A3CF7F53D5EF78118E81CCE +:1020C000F103E622E919B4BF842A953BFE6CE224B1 +:1020D000E90AF101E627E8109A7D5EF0FFF7E90CC6 +:1020E000E42AE80AE735E907FA2440148437400077 +:1020F000040DD50292015CF507D1E813441000FCF1 +:10210000808642418473001200DE5A180209F101F0 +:10211000E628E8059403842A40000417E2E0E91366 +:10212000441000FC42618473001300DE5A18010E53 +:102130009401E207E80ACA094402CDE0843A381063 +:102140000C08D5038401D5028402FCC22240000C95 +:102150005050000A50100028840084413832891100 +:102160008C419AE388035A2804FB8CAAD9F7DD9E98 +:102170008060804084019A50E622E90B98509221B9 +:1021800042F08424E26F4000BC1A4020BC1BD5F40E +:10219000DD9EFC2084408082806284C14053080C14 +:1021A000FF4EC505385009118C8188658C415A282D +:1021B00019F74031907784403C3FFA9480C284E123 +:1021C0004053880CFF4EC506385009118AA342625D +:1021D00094738C415A2819F64003101749FFFFCA1F +:1021E000FCA0FC5980C08106440000FC4282807340 +:1021F0002204000522A40004F0864400004481214A +:1022000040150016F18AF106F48744400043960019 +:10221000401090968780F38980E59720805C52A0DB +:102220007FDE4400004352527FDF42510073B054BE +:10223000840642110073F188FF6C8420443000440E +:10224000800A42008C73F18C80254210007380015B +:10225000F28FF48EF38DF58B49FFFF8C96015CF0C5 +:10226000007FF50BF10CF30DF40EF20FE8055200B0 +:10227000007F9601D502840004FF80083807850995 +:10228000881C8C2141C000135A1803DC8C415A2849 +:1022900003CA50AF8064800A84608026804749FF6B +:1022A000F5DD84004443F248B0D4984438218100DD +:1022B0008C01AE885A0809FB84A7846584C0B011DC +:1022C000B6BFF582F0848083F681F683800A802A87 +:1022D000844649FFB0E084AE846A804942431424B6 +:1022E00042230C7384009844882A02108008381115 +:1022F00000098C025A080AF98CC15A6805F0F00AE4 +:10230000842D8E01960140008006F1065EF088E67D +:10231000E9028C01F1074422CFDCAE082214800CC4 +:10232000960938011D093C27F4D0E040E8033C1B26 +:10233000F4D04400007FFE0C4000701612040072BE +:10234000041400073C0C01EB380005013C13F4D1E8 +:1023500054A000FF96008801001400183C0BF4D133 +:1023600096464402CFF4C90538101C00E22AE8035F +:1023700038A01C08F609FA0C46101F8D42638073C2 +:102380005010863F800949FFFF06B6063C0DFA94BF +:10239000441739C0A832800949FFFEFDA8313C0D21 +:1023A000FA94A8332204800CA834800949FFFED097 +:1023B000A83510A30018FCD9FC40441000FC4201D1 +:1023C000847302100072A1C7C90484211210007224 +:1023D0003C3C01EB96B8945138218901E64BE84129 +:1023E0003C2C01ED8841A651E622E9079F8AE62EA2 +:1023F00097B084AFE805D50284C08C229748A69098 +:10240000E642E9079E525CF100229648E806D502B2 +:1024100084208C429710D502FA933C8C0278852058 +:10242000E281E91A40A090088046E2A2E912403514 +:10243000080094D9886802F1800040F780115EF7A7 +:102440008029E904A4D896DB89238C419690D5EEA7 +:102450008C219648D5E6441001F442148424D50812 +:102460003C1C01F138209E02441001F4FE5402206D +:102470000072401088361210000B3C1C01F138101D +:102480009E021410003BFCC0FC40EE68B61F3C03EB +:10249000F53A8121E615F281E903FA18D5035200D5 +:1024A000003C3C0BF4CE2E07E983E605E9048400EA +:1024B0003C0BF4CE8400843F3C0BF4D03C0BF4D2B4 +:1024C0003C0BF4CF3E17E90E3C0BF4D1507480DF87 +:1024D00044A2D00084C04482CFB83C0C00EF00007E +:1024E0000009E2C0E8625003FF21B4009E41E623E8 +:1024F000E8360003FF399606C80B5003FF79B40095 +:102500005A0801285003FFB9B4005A0801232E07C6 +:10251000E90FE605E90400050000C817B1028009CB +:10252000B045B45FB0D2888680A649FFFE5C8009C2 +:102530004412D1D4B45F96F049FFFF404412CFD08B +:10254000840038009808D502840110050000D528C1 +:102550004402CFD0842138101808D522C0035A086D +:1025600005204412CFC48400AE381003FFFFAE3AFA +:10257000380098085013FF37844038041808AC8896 +:102580004412CDE0382098084412CFD03800980883 +:102590008421101500004412D00C380098088CC11A +:1025A000507380FC8D41D59A3C67F4D05EF303E90B +:1025B000E91250737C1890E350738032963B5EF3BF +:1025C00005DDB61FE90B50637A2490C2506300C842 +:1025D00097B3D50644000032B61F446000C884009B +:1025E0003E07E90F507480DE850044A2CFD03C0C3A +:1025F00000EF00000009E3004EF200C85093FF22F4 +:10260000B4099E41E623E87138052000C84344021E +:10261000D00038002000C83EB082B012F10138214D +:102620002000543400FF49FFFC5EAE393CF7F4D083 +:102630005EF783E9E93100038015E602E82D4402E4 +:10264000CFDC3C3C01EE382021015003FF3EE04648 +:10265000E80FB420944A8823A70BC40AA70A5CF2A7 +:102660000023E806A709C404A648E62FE911B40030 +:1026700094028803A643C109A6425A102307A64123 +:10268000C104A6005A080F09B41FE040E805840100 +:10269000D5028402AE392E0004395A00010F49FFD9 +:1026A00075AD5A08020BB0C28008A678A6B93831B9 +:1026B000A00049FFFBE9AE38B4095A000315A6385B +:1026C0005A080208A67BC90B8401AE3BAE3AD51C62 +:1026D0005A08011BA63B5A0802058403AE3BD514D9 +:1026E0005A0803138400D5FB5A08040F4402D55836 +:1026F000380020005A0840094402CFB8842138101D +:1027000020088402AE38A6785A18010C4422D00C56 +:1027100038012000E610E80C8C0138012008D508AB +:102720005A1802074402D00C84403820200838058B +:102730002000C80D4402D00038002000C8085A18F4 +:1027400002072E07E90F8C013E07E90F2E0004391E +:102750005A080106A638E602E80CD50649FF754E70 +:102760005A0802FAD50DB4095A0004048401AE3A9D +:102770004402CFB88421381020088402AE388D017D +:10278000507380FC48FFFF35ED98FCC0FC203C6C8A +:1027900000FF84E1A772A7B3C20284FFC9089E6943 +:1027A000FF4442510473B6A388A7D50B9E71FE8CDB +:1027B000802042111473884742011473B62380A00D +:1027C000B6A4FCA0FC4484C0810583808141F282D0 +:1027D000F38180E480A38126E2E5E9148005F1100D +:1027E000F202B0C4B105F58349FFFFD2F004F5034E +:1027F000380E01118CA18920F005380E011188C016 +:10280000D5ECF00180468AE0FFFB8405422380730B +:102810004E26000384418029800A49FFC50F001419 +:1028200000005A10FF058C2188019201100400005D +:10283000B046B08749FFC56DF00638150111F007A5 +:10284000382501118402400080164204887340003C +:102850000416FCC4FC4780E13C1C00FFF28450607D +:1028600000200020803200808002F2870020803328 +:102870008400F28820208039F085F2892020803A77 +:10288000A64BF28A80018E01F183F086200F800C26 +:1028900044A2CDF0F08D3C0C00FFF10500000009D2 +:1028A000E2204EF2010E04037FF84E0200F78E0480 +:1028B000E6024EF300F3A0345A080204480000EE8A +:1028C00004937FFF40048808F08BF10BA03D880142 +:1028D000A6C0CB29A642E622E9029EC9A703F003BF +:1028E0008E02E080E8038C81D502F4068440B65F56 +:1028F0003C1C0100F00480A649FFFF66A07EF207A1 +:102900003810A6028A20FE540423800838212602AB +:10291000880240008016F109880122137FF2960395 +:10292000E001D536A74150147FFFD939A6C2401423 +:102930000010E662F18CE9038E61D5028460A70382 +:10294000F0038E02E080E8038C81D502F4063C1C83 +:1029500001008400B61F501080A28441F00480A6BC +:1029600049FFFF32A07EF20C3810A602421100731C +:10297000F207FE5404238008382126028802400012 +:102980008016F109880122137FF29603E0204000AF +:10299000BC1A12037FF812037FF4D507841FAE30F0 +:1029A00002037FF212037FF8A03DF10B8801A6C25B +:1029B000CB2DA640E622E9029EC9A70150047FFE66 +:1029C000E080E8038C81D50350447FFF3C1C01006C +:1029D0008401B61F501081448440F0049D7149FF6A +:1029E000FEF3A07FF2083810A6028A20FE540423CA +:1029F000800838212602880240008016F10A8801EA +:102A000022137FF39603E001D532A743F106D936AE +:102A1000A6C0E662E9038E61D5028460A701500476 +:102A20007FFEE080E8038C81D50350447FFF3C1C8F +:102A300001008441B65F501081E69972F00449FFAD +:102A4000FEC3A07FF20D3810A60242110073F208F7 +:102A5000FE54042380083821260288024000801694 +:102A6000F10A880122137FF39603E0204000BC1A8C +:102A700012037FF912037FF5D507841FAE310203DD +:102A80007FF312037FF922037FF81205000022036F +:102A90007FF912050001D50C2205000012037FF812 +:102AA0002205000112037FF9841FAE30AE31F0051C +:102AB0008D448C01F085506300FC48FFFEEEFCC79E +:102AC000FC48F08DFA09120F801DFA07120F801EC4 +:102AD0008400120F801F2E000439F18C8122C00760 +:102AE000840A120F801D8408120F801E2E07E983AE +:102AF000C80B020F801D8C03120F801D020F801E59 +:102B00008C03120F801E844180A2F00C44126B30A3 +:102B10008460848249FF76FA8441806280298482BD +:102B200080A2F00C49FF76F2842044213598443D80 +:102B300094D044426B302E07C542E220E816980A32 +:102B40009401994388A980C1A5688C21AD402E07C6 +:102B5000C5432E57C5428E01426280739431994419 +:102B60008809A400AC28D5E844026B308020844258 +:102B70008461848384A049FF76C9802944026B3034 +:102B800084428461848384A049FF76C02E37C54285 +:102B900084C084E144026B30B67F501F803A80408D +:102BA00080A72E47C543F681F682F683F684F68524 +:102BB000F786F787F688F689F68A49FFACE02E3764 +:102BC000C5428009B67FB04F804980A72E47C543D4 +:102BD000F681F682F683F684F685F786F787F6881F +:102BE000F689F68A49FFACCB2E37C5428542B67FBF +:102BF000F38214AF80068009804980A72E47C54321 +:102C0000F781F683F684F685F687F688F689F68AE4 +:102C100044126B3049FFACB32E37C5428009B67FF2 +:102C2000B04E804980A72E47C543F681F682F683D1 +:102C3000F684F685F786F687F688F689F68A12AF67 +:102C4000801C49FFAC9C2E37C542B00EF382802910 +:102C500080A62E47C543B6DFF781F683F684F68556 +:102C6000F786F787F688F689F78A44226B30127F59 +:102C7000801C49FFAC842E37C542854844126B3016 +:102C8000B67FF382F00C804180A72E47C543F781C1 +:102C9000F683F684F685F68614AF8007F688F68903 +:102CA000F68A49FFAC6C2E37C542501F803E440067 +:102CB0007FFFB67FF088804180A72E47C543F6810D +:102CC000F682F683F684F685F686F687F789F78A24 +:102CD00044026B3049FFAC532E37C542F00D8029BA +:102CE0002E47C543B67FF781F382F683F684F685D7 +:102CF000F68614AF8007F688F689F78A804980A7A0 +:102D000049FFAC3D020F801F44102773400080062E +:102D1000FCC8FC2049FF747B49FFCAF75A0008151C +:102D200049FFCB1D4403F5728421AE404403F57383 +:102D30008420AE4049FFAD192E07E906C80349FFBC +:102D4000C82E49FFCB2C4473F04BA6384413F04BEC +:102D50005A00FF05841FAE08D5FF49FFCE885A00F0 +:102D600003E15A0002F05A0013F23C0DFAAAA780C0 +:102D700097B0CE3A49FF76143E60046449FFCB4DCC +:102D80002E07E9685A08120E3C03F4DB802649FF3F +:102D9000F3095A08010780062E10046449FFF25512 +:102DA0002E07E9685A0004125A08190449FFF28DE7 +:102DB00049FFCB9249FFD0635A0002C52E07E9684C +:102DC0005A08050A49FFCC6D440000FF2E10046428 +:102DD00049FFF23B3C0DFAAA8421AE4084003C0F2F +:102DE000FAD649FFCC3949FF72095A0802B049FFA7 +:102DF000B1FCC8AC2E67E94DCEA92E0004225A08BA +:102E00000A0549FFBC5AD51D44112F2C8461380096 +:102E1000810180468026808349FFDA472E100422F4 +:102E200044212F2038510400D00C84414400280054 +:102E300080268062808249FFDA3884013E07E94DAE +:102E40002E000422842B8C019600400004373E1093 +:102E5000042248FFFF7C00004250882440104009B3 +:102E600042500C73960140314009969142F00C2477 +:102E700042400824FE8C40078800E20240F7C00868 +:102E80004020400842F08C7340104009882F98225F +:102E9000E204882F984DDD9E8060C207994A084061 +:102EA000800118418001D9FCDD9E92008060995A12 +:102EB000D30418118001D5FDDD9E9200EFF0F1FFE3 +:102EC00000010F1011000000FFFFFFFF08FFFFFFD0 +:102ED000FF000000000000010001000000000100F0 +:102EE00000000000010000000001000000010000DF +:102EF00001000000010000000000000000010001CE +:102F000000000100010000000000000100000000BE +:102F100000000100000001000000000100000000AE +:102F2000000101000000010000000001000000009D +:102F3000010000000001000000010100000000008D +:102F4000010000000001000000010000000000007E +:102F5000010001000000000000000100000100006D +:102F60000001000004050607020202030303040433 +:102F7000000000000C0C005550710200D8730200D4 +:102F800060760200E8780200600C0200A0200200D7 +:102F900000400200604C0200701102008016020026 +:102FA000E0510200F0560200402B0200D02B02003C +:102FB000B03E0200403F0200202A0200B02A020078 +:102FC000903D0200203E020050710200D8730200C2 +:102FD00060760200E878020070110200801602009C +:102FE000E0510200F0560200F000F000B400900042 +:102FF000600C0200A020020000400200604C0200B1 +:10300000600C0200A020020000400200604C0200A0 +:103010007011020080160200E0510200F05602001A +:10302000008914000EE8070E16F00000000300C12E +:1030300003C105C107C109C10BC10DC10FC101C247 +:10304000A4C04422D0184412000094DA8861B66209 +:10305000A4C25041002094DA8861A8D2A4C494DAB2 +:103060008861A8D1A4C694DA8861B66402300008E9 +:1030700094DA8861A8E1A4C494DA8861A8E5020022 +:10308000000894028820A866DD9EB44084A08C4489 +:103090009C2EA2D196005A58200680A05A0824FAE5 +:1030A000DD9E5441801F384094088CA1976892653A +:1030B000D8F3D5F4FC20B46084008C7C9583A319EC +:1030C00097B08440995697688C415472000F96903F +:1030D0003870940892845A2808F78C0196005A0890 +:1030E00004EFFCA0FC20B46084005031802C958358 +:1030F000A31997B08440995697688C415472000F79 +:1031000096903870940892845A2808F78C0196009B +:103110005A0804EFFCA0FC003C0C017A84233C0F0D +:10312000FAA64403F40B8440AE404403F40484261E +:10313000AE404413F4078401AE084413F408AE080B +:103140004413F01EAE884413F420AE082E07C5DCED +:103150005A0801063C0C017A490000314402D0189B +:103160004412D22049FFFF934402D0184412D710D2 +:1031700049FFFFA24402D01C4412D51849FFFF9C0E +:103180004412D5DC4402D01849FFFFAE4900004F7D +:1031900044028F7049FF9DCDFC80441000963C1B7B +:1031A000F4C84412C8C884003E07E9703E07E958D5 +:1031B000AE08AE09AE0AAE0BDD9EFC0004000012A4 +:1031C00044120054921054007FFF9402880144126C +:1031D0008F700020812810200018002081291020E5 +:1031E0000019002081261020001B001081271010DC +:1031F000001AA08546110000FE57A845A08546127A +:103200000000FE57A845A08546180000FE57A845B7 +:10321000A08546140000FE57A845440228384900FE +:103220000050FC803C0FFFA8DD9E3C2C017A44122C +:1032300000A804010012921054007FFF940288013C +:1032400044120000B400920A96373E07E948040190 +:103250000012921054007FFF94028801B4200000F5 +:103260000020922A96773E17E92D3E07E94FDD9E12 +:10327000440251703C0FFA7E4403F142441028B8D6 +:10328000AC40441251888400B6013C1DFA7EA80F60 +:103290003C1DFA7E14008008DD9EFC004413F3817F +:1032A000A608540000F0AE084413F3848400AE086E +:1032B0004413F56BAE0849FFAA58FC80DD9E441EFE +:1032C0000000880192024413F3CA9601AC08DD9E07 +:1032D0004423F054AC104403F056AC40DD9EDD9E18 +:1032E00096069404965FFE474403F043AE40DD9E8D +:1032F0004413F044AC08DD9E4423F0509617A650CA +:10330000541080F8FE47AE50DD9E4423F0509617CF +:10331000A65094045410808FFE47AE50DD9EFC00F2 +:10332000840749FFFFEB4403F04C8420AE40840740 +:1033300049FFFFED4403F04E8421AE4049FFADC785 +:10334000FC803C0FFFA9DD9E3C0FFA88DD9E3C0F00 +:10335000FA7DDD9E3C0FFA8ADD9E3C0FFFAEDD9EBE +:103360003C0FFFADDD9E3C0FFFACDD9E3C0FFFB977 +:10337000DD9E3C0FFA8CDD9E3C0FFA8BDD9E3BFF01 +:10338000FCBCEFFC8401842049FFFFACEC0444004A +:103390000CD53BFFFC8448FFFFAD4423F01FA61073 +:1033A000541000E04403F302A6C0A600962788014B +:1033B0009600AE10DD9E3BFFFCBC8400EFFC80203D +:1033C00049FFFF8849FF6E2D49FFFEA749FFFFD93E +:1033D00049FFFFE549FF737D49FFFF4C49FFFFA10E +:1033E00049FFFF6E49FFFF5BEC043BFFFC8448FF95 +:1033F00068B93C0DFAAD3A6FA8BC80C15A08040DFB +:103400002E07C5DBC009840249FFEF933C0DFAADDE +:103410005A080424D51149FF6EF15A0002F68401BE +:1034200049FFEF878420846184028041808180A3EA +:1034300049FF6F44D5F149FF6EE15A00020F2E7724 +:10344000C5DB5A78010B800749FFAB3E840049FF7A +:103450009445800749FF6E624473F04A44900055DA +:103460003C0DFAD2C009840449FFEF633C0DFAAD6C +:103470005A080429D50B49FFAB2B5A0801F68403DF +:1034800049FFEF5710938000D5EC49FF6EB75A0003 +:10349000021A2E07C5DB5A08011649FF70064403BD +:1034A000F429441FFFC3AE40840049FFA2AB3C0D8A +:1034B000FA99842049FF73268402AE313A6FA884BA +:1034C000DD9E49FF6E9B5A08023284208461804150 +:1034D0008083FA1049FFD6E98441541000DF8062EE +:1034E0008082FA1049FFD6E1842084618041808384 +:1034F000440046E049FFD6D98420846180E08041C1 +:103500004400CFF0808349FFD6D05A78070BC80516 +:1035100084033E07E974D50A84043E07E974D5069E +:10352000CF05C80484013E07E974804684058420E1 +:1035300049FFA5583C0DFA99842049FF72E38402A3 +:10354000AE31840149FFAC1384053A6FA88448FF6B +:10355000EEF03C0FFA90DD9E3C0FFFFDDD9E3C0D32 +:10356000FA90A4413C1BFFF3A444A6003C1BFFF2CD +:103570003E07FFE2DD9E3A6FAABCEFFC2E57C54224 +:103580002E27C5722E47C5439629421008243C1B9E +:10359000E2A996E12E17C573FE1C3C0BE2BA42610C +:1035A000842444022D85924192213E27C5793E57BD +:1035B000C54F3C6BE2AA3E17C57A3E47C550A640B0 +:1035C0008421AE40A6418420AE4144522D9C443D0E +:1035D000D9D044228F7044022DA4986B3811041066 +:1035E00018128001D8FB84C044027B903C6FFA9F84 +:1035F00049FFFD283C0C017A44122CFE3C0FFAAC2A +:1036000044222CFC44022D5CB6C0AD90AD883C1F1A +:10361000FAA544122CF83C1FFAB544122CF93C1FB1 +:10362000FAAA44122CFA3C1FFA992E17C5E33C0F54 +:10363000FA9C3C2FFAA33E67E94E5A180107B420C2 +:1036400058108002B620D505B440843DFE56B62001 +:1036500044122D5C440FBFFFB4418521FE16B60114 +:10366000B401847B40002404B601B4018457FE1EDB +:10367000B601B40184C0FE16B601B40185405800FD +:103680000010B601B481440FFFBFFE26B601B4019D +:1036900084E058000020B601B40158000C00B601C7 +:1036A000B481440FCFFFFE2658002000B601B401BC +:1036B00044122CFE3C0FFAB7A508841DFE26AC0868 +:1036C000A508841EFE26AC08A408FEC6ACC8A40843 +:1036D000FE86AC88A44844022CFCAC403E67E97CE2 +:1036E0003E67E96C3E60043F3C9E01102E07C5E832 +:1036F0003CABF4DF3E07E933440FFFAA3E07E93A4B +:10370000440000553E07E93F3E07E9353E07E978AA +:103710003EA7E9863E67E9773E67E9413E6004617E +:103720003E67E9103CABF4D93CABF4E13E600422C7 +:103730003E67E94D3E97E9683E97E9214900024816 +:103740003C0DFA993E67E9063CABF4DB3E67E907BE +:10375000AF813E67E9203E97E95E3E67E91FAF8093 +:103760003C1DFAB584023E67E9123C9E01B53E67F6 +:10377000E9453E6004543E6004553E67E928AE08C2 +:103780003C1DFAAAAE0884043E07E9744402D0A0A6 +:103790003C0E01CB4402D18C3C0E01CC4402D360E0 +:1037A0003C0E01CD4402D6683C0E01CE44000032EE +:1037B0003C0804E03E67E9293C7FFAA63E67E95AE7 +:1037C0003E97E9543E6004573C7BF4EF3CABF4E792 +:1037D0003E67E91E3C0804E44402D6443C0E0271F4 +:1037E0004402D5D03C0FFAB1840A3E07EAAC2E075A +:1037F000C5433E67EAC03E07C67544028F703E6708 +:10380000EAAD3E67EAAE3E6004213C7FFABA3C7FF7 +:10381000FAB63C7FFAAF3C7FFAA13C7FFAB33C7F1B +:10382000FAA03C7FFABC3C7FFAB43C7FFA953C7F1F +:10383000FA9A490001E6800749FF72CE800949FFE4 +:1038400072CB800749FF72D63C0E01E9800949FF1F +:1038500072D13C0E01EA840249FF72CC3C0E01EBAE +:10386000840349FF72C73C0E01EC840449FF72C215 +:103870003C0E01ED840549FF72BD3C0E01EE84064D +:1038800049FF72B83C0E01EF840749FF72B33C0E4A +:1038900001F0840849FF72AE3C0E01F13C03E2A93D +:1038A0003C13E3B63C0BE3B43C03E2AA3C7E0114B8 +:1038B0003C0BE41D3C03E3B73E67E9464000240CA3 +:1038C00088013C0BE3B83C03E4203C13E41F4000B8 +:1038D000240C88013E67E93C3C0BE4213E60044C2B +:1038E00049FF7FB93C0FFAB849FF7F8D4402D79456 +:1038F0003C0E02C34402B5103E67EAE53E67EAE4C7 +:103900003E67EAE63E600B083C7E02C43C0FFABB11 +:10391000845F3C0DFAB8843F38201C088CE65A7846 +:103920003CFA3C0DFAB884C03C6E01111010003C0A +:103930001010003D3C6E01123E60045B3E60045975 +:103940003E60045C3E60045D3E67EA603E67EA629A +:103950003E67EA613E67E9803E67E93C3E67E962AF +:103960003E67E9513E67E9653E67E9183E67E9440D +:103970003E60046049FFBBB3440000643C08054C52 +:103980004400005A3C08054E440000963C08054F90 +:103990003C080554FA183C0805558405FA293C08EA +:1039A000055744027B703E67E94B3C6BF4EE3E608A +:1039B00004683E60045E3E600A953E600A963C687C +:1039C000054D3C6805503C6805513C6805533C1862 +:1039D00005523C6805563C6805583E67E92E3E672F +:1039E000E9503E67E9313E67E97649FF91CD2E0700 +:1039F000C5DC5A08010449FFFBD284013E0004588B +:103A00003E07E9554402D3FC49FF6CBF49FF6CBB3C +:103A100084003E07E95F3E07E9133E07E9193E07C8 +:103A2000E9423E07E9233E07E96F3E07E96A3E07A0 +:103A3000E92C3E07E9343E07E97D84003C0BF4D7CE +:103A40003C0BF4E23C0BF4D8440000783C0BF4D47B +:103A50004400003C3C0BF4ED840A4410007F3E0718 +:103A6000E91A840F3E17E96D3E07E984EC043A6FCA +:103A7000AA84DD9E3A6F9CBC44629028EFF48006D5 +:103A800049FFFC6150037F48F081490000959C3458 +:103A9000490000955003007849000097500300A8A2 +:103AA00049000090500300CC49FF719050037F48BB +:103AB000F08149FF718E500300B049FFFC5C500358 +:103AC0007F48F08149FFFC5A50037F48F08149FF4D +:103AD000FC435003011849FFFD3E50037F48F0812D +:103AE00049FFFD3C49FFFD3D5003012C49FFFC37D8 +:103AF000507303A850037F48F08149FFFC338007CF +:103B000049FFFC3350037F48F08149FF8DE75003A4 +:103B1000017049FF8CDB5003031849FF75545003B3 +:103B20007F48F08149FF75525003036449FF738F4A +:103B300050037F48F08149FF738D5003037449FFA0 +:103B400081C150037F48F08149FF81BF800749FF51 +:103B50007E5450037F48F08149FF7E52500303B4E6 +:103B600049FFFBF750037F48F08149FFFBEF3C0D15 +:103B7000FA9C49FFAAD2500303D84900003C5003E5 +:103B80007F48F0814900003A5003004849FFFB4C50 +:103B900050037F48F08149FFFBEB50037F48F081E1 +:103BA00049FFF14050037F48F081EC0C3A6F9C8450 +:103BB00048FFCE553C0FFA93DD9E3C0FFA91DD9EF7 +:103BC0003C0FFA92DD9E3C0E00E0DD9EFC0049FFBA +:103BD0006BA684203C0E00EB10100050101000511A +:103BE00010100052101000531010006010100061EF +:103BF000FC803C0E0100DD9E3C0E00FFDD9E3C0E75 +:103C00000101DD9EFC40049F800A5A90010B446232 +:103C1000D4E44472D16C3863040038738400D50353 +:103C200084E284CA8380FB48B9105410FFFF944A91 +:103C30004213287344A20000882ABE120080800725 +:103C400092D010818000A6CE54637FFFAEE0A6CC58 +:103C5000AEE80230002B024080090200002B021067 +:103C6000800888648801940194D9886AF40889409E +:103C7000F009B664B7402E07E970C0035A98010EE8 +:103C800044100054943242038473441200008801AB +:103C9000B400920A9637D5032E000D28AE10FCC052 +:103CA000FC00838044600030BD12B8125452FFFF04 +:103CB00054007FFF956A9402420218734251987330 +:103CC0004442000044620030888088C08AA03832B4 +:103CD00090028C26540183FF1200FFFD4001A809C9 +:103CE0009274543183FF1230FFFF540003FFA2E1AE +:103CF0001200FFFE540183FFAC104001A80992742A +:103D0000540003FF543183FFAC11ACD28C464C43BA +:103D10007FE0FC80FC40045000115452FFFFC91B9F +:103D20008380443200F0B910B8115410FFFF944A58 +:103D3000882354007FFFA64C9648C2249402443046 +:103D4000004842008C73445200004412004888A08E +:103D50008801D515956A4462000088C54470004802 +:103D6000E264E8DF80A642519C73509280481812AA +:103D700080014C54FFFE8C6196D8D5F31822800147 +:103D8000D8FEFCC0040000114440004854007FFFEE +:103D90009402420190734452000088A0840098C8A5 +:103DA000A6D94041E008383080004031C00888641E +:103DB0009910A721404220088864384100008C02F5 +:103DC0008864AAE95A0824EDDD9E040000114440ED +:103DD000004854007FFF94024201907380604402C7 +:103DE000000088608400A51938408008A75B990806 +:103DF000AF61B483995038410008A31992888C02AE +:103E0000AF295A0824F2DD9EE201E808A610E2601C +:103E1000E8039AC3D50B8400D50CE220E80BA6106A +:103E200052F180FFE00FE8048860AED0DD9E841F71 +:103E3000AE10DD9EFC40EEE85A3801073CA0028936 +:103E400044400120D5092E500D124C5000B93CA021 +:103E5000028844400C602E57E903F486E6A2848170 +:103E6000E9058EA14042140C97204042040E972091 +:103E7000F485CC038481F485F1888020B00EB61FD0 +:103E8000B00F505F8035F389F284F081F3828002B5 +:103E9000503F8036B08D504F803749FFFEB5F0045B +:103EA000B062B0B4003F8036004F803749FFFEFA61 +:103EB000F004B050B099003F803549FFFF88B02230 +:103EC0008120B1D08500B00E38402202F0095A0896 +:103ED000010551C20090D50351C21B90F00684C069 +:103EE0009960FA1442040024F08A382499015A2374 +:103EF000FF552E17E9043832090100FF803405EF21 +:103F0000800894118E21F0874001BC164DE0C01C42 +:103F1000F107883C03E0800040FF3DF640F7A80130 +:103F20004EF4000452F780008A0A4E040003FE0299 +:103F300040F78007E903ACC8D5303802890138035F +:103F40009808D52BF108C904383E0909D513F107A3 +:103F5000883CA48840213C568A4A4E240003FE92A5 +:103F600040F028014EF4000452F78000E04FE908C9 +:103F7000ACC8381499013823980038228509F10A11 +:103F8000B0D098B188439601802AF305F58BF48769 +:103F900049FFFF3CF50BF4078CC15A6824A85094E4 +:103FA0008048507380245A8001048501D58DF00427 +:103FB000B050B099003F803549FFFEE6ED18FCC0D7 +:103FC000FC418401B63FF28180E349FFACA13C1D76 +:103FD000FAB58401AE083C1DFAAAAE0884003C0F75 +:103FE000FAD92E0004615A0801048407D5085A78CA +:103FF00001052E07C631D5032E07C6303E07E9035B +:104000002E07E90384C08C013E07E9043C6FFAD611 +:1040100044A3F04A448000552E07E904E2C084001E +:10402000E8373C0FFADBCF0349FFA1B049FF749694 +:10403000852010850000F0014C9000243C0DFADB37 +:10404000E320E8FA2E07C5DCC0112E07C5EEC00E2E +:104050002E500D124C54C00BCF092E00042BC80655 +:10406000800649FFA0F35A00011780098026B45F3B +:10407000806749FFFEE150548001549280FFD5DCF7 +:104080003C0DFAAA8CC1842197B0AE40D5C649FF39 +:10409000AC3F8400FCC1FC002E000461C8063C1348 +:1040A000E3193C23E31AD5044420008080222E37F4 +:1040B000E9703C03E3145A38040D2E37E91C520012 +:1040C00000FFFE1C2E37E94F40000C16520000FF87 +:1040D0003C0802883C03E31596483C0802898400AA +:1040E0003E07E90296903C0DFAAC84602E47C56D00 +:1040F00049FFFE123C0DFA993C1DFAAC2E27C56F04 +:10410000846049FFFF5F80C05A080108FA0349FF35 +:104110006AC23E60042BD53E49FF6E523C1DFA999F +:104120005A0802058405AE09D5078409AE09800145 +:10413000842049FF72C93C0DFA9949FF9549844191 +:1041400080623C1DFAAC3C0DFA9949FFFF3B8400AC +:104150004412CE58844149FFD082840749FFEECBF8 +:1041600049FF6E2E5A080206842D3C0DFA99D50D92 +:104170003C0DFA99842049FF72A72E17E9723C0D75 +:10418000FA995A180203842AAE413C0DFA9949FF64 +:10419000951FFC803BFFFCBCEFFC44020000441276 +:1041A0001B9049FF70B63C0DFAAA8421EC04AE4086 +:1041B0003BFFFC84DD9E3A6FA4BCEFDC44112EF083 +:1041C000B1843A2094003A231420812049FFA0DED4 +:1041D00049FF9E11F08149FF9D048400120F800762 +:1041E00084E038131E02500F800E2E27C54F2E3745 +:1041F000C5508CE149FF70FA5A7804F5000480003C +:104200005A08012184033C1DFA99F2014432B38F0C +:1042100049FF96172E17E92D440000C8FE0C120F17 +:10422000800744121B90500F800E2E27C54F2E374B +:10423000C55049FF70DB49FF73913C1DFAB5A608D4 +:10424000C8FF4403F04A44100055EC24AE403A6FD6 +:10425000A4848400DD9E3BFFFEBCEFF8FA0049FF1A +:104260006A1A49FF935E84013E07E9563E07E92733 +:1042700084003E00042B3E07E9403E07E90149FF68 +:104280006D9F3C1DFA995A08020D8404AE09800105 +:10429000842049FF72193C0DFA99842DAE41D50B4B +:1042A0008409AE098001842049FF720E3C0DFA9901 +:1042B000842AAE413C0DFAB58421AE402E07C5DC00 +:1042C0005A0801122E07E9703E07E9582E07E95EE9 +:1042D000C8043E07E913D5072E07E9135A0801045D +:1042E0003E00042B3C0DFA99A6013E07E9728406B4 +:1042F00049FFEE012E00042BC8193C1DFA992E2708 +:10430000E95F4432B38F49FF959C3C07F4E949FFCC +:104310009F9C2E07C5E65A08010449FFFEBE840A89 +:1043200049FFEDE9840B49FFEDE62E00042B5A0806 +:10433000010D8400120F80034412AD70500F8006EF +:10434000FA40FA7449FF70522E07C5DC5A08010D75 +:104350002E00042B5A0001052E07E940C80544022F +:10436000CE5B49FFFF2A2E07C5DC5A08011B2E0031 +:10437000042BC81149FFB57F5A00010A3C1DFA9968 +:104380002E07E970A64949FF6FE3D50F3E07E913F1 +:1043900048FFFF663C1DFAB5A6085A0801FFD5EF95 +:1043A0002E07E97049FF6FF084003E00046149FF69 +:1043B0006D073C1DFA992E27E9725A0802069E12D3 +:1043C000E602E804D5055A200204AE89D503840D1F +:1043D000AE093C0DFA9949FF93FB84003E07E98042 +:1043E0003E07E9293E07E9272E07C60484213E0738 +:1043F000E9523C0DFAAAAE4049FF72B0490000698B +:104400005A08020448FFFF2C8400442225B0806033 +:10441000444220A080A03C13E2BAE201E80998429D +:10442000AEC8944188248C01AD489601D5F584002E +:104430003E07E96E84013E07E936EC083BFFFE8447 +:10444000DD9E440000A23A6F98BC49FFED4A3C0D46 +:10445000FA99A6015A080D128400847F3C2DFAB8FF +:10446000843F383100088C065A083CFA3C0DFAB8F3 +:104470001010003C1010003D49FFD19B3E00043954 +:104480002E07C54B84C0520000013E67E91049FF6A +:104490006D4184013E07E9373E07E9573E67E9630E +:1044A0003E67E9133E60043A3E60043B3E60043CD4 +:1044B00049FFC0742E07C5DC3E67E9795A0801063A +:1044C0003A6F988448FFAA243A6F9884DD9E3A6F29 +:1044D000A6BCEFE044012F00B1843A20140044014F +:1044E0002F103A2F94203A2014002E07C5DC80FFAD +:1044F0003A2314205A0801322E00042BC81F2E071D +:10450000E97049FF6ECF5A08010A2E07E95E5A0882 +:1045100001063E07E9138402D53249FFB1A7852081 +:104520003803A602381326028D2149FF6EF25A98ED +:1045300004F984013E07E940D5102E07E940C80D73 +:104540002E07E95F49FF6EC72E17E95F380F860215 +:104550003813060249FF6EDD44021B9044124510D9 +:1045600049FF6ED784C144021B90441240003E674D +:10457000E95549FF6ECE3E6004308401EC203A6F6D +:10458000A684DD9E00000000000000000000000086 +:10459000000000000000000000000000000000001B +:1045A000000000000000000000000000000000000B +:1045B00000000000000000000000000000000000FB +:1045C00000000000000000000000000000000000EB +:1045D00000000000000000000000000000000000DB +:1045E00000000000000000000000000000000000CB +:1045F00000000000000000000000000000000000BB +:1046000000000000000000000000000000000000AA +:10461000000000000000000000000000000000009A +:10462000000000000000000000000000000000008A +:10463000000000000000000000000000000000007A +:10464000000000000000000000000000000000006A +:10465000000000000000000000000000000000005A +:10466000000000000000000000000000000000004A +:10467000000000000000000000000000000000003A +:10468000000000000000000000000000000000002A +:10469000000000000000000000000000000000001A +:1046A000000000000000000000000000000000000A +:1046B00000000000000000000000000000000000FA +:1046C00000000000000000000000000000000000EA +:1046D00000000000000000000000000000000000DA +:1046E00000000000000000000000000000000000CA +:1046F00000000000000000000000000000000000BA +:1047000000000000000000000000000000000000A9 +:104710000000000000000000000000000000000099 +:104720000000000000000000000000000000000089 +:104730000000000000000000000000000000000079 +:104740000000000000000000000000000000000069 +:104750000000000000000000000000000000000059 +:104760000000000000000000000000000000000049 +:104770000000000000000000000000000000000039 +:104780000000000000000000000000000000000029 +:104790000000000000000000000000000000000019 +:1047A0000000000000000000000000000000000009 +:1047B00000000000000000000000000000000000F9 +:1047C00000000000000000000000000000000000E9 +:1047D00000000000000000000000000000000000D9 +:1047E00000000000000000000000000000000000C9 +:1047F00000000000000000000000000000000000B9 +:1048000000000000000000000000000000000000A8 +:104810000000000000000000000000000000000098 +:104820000000000000000000000000000000000088 +:104830000000000000000000000000000000000078 +:104840000000000000000000000000000000000068 +:104850000000000000000000000000000000000058 +:104860000000000000000000000000000000000048 +:104870000000000000000000000000000000000038 +:104880000000000000000000000000000000000028 +:104890000000000000000000000000000000000018 +:1048A0000000000000000000000000000000000008 +:1048B00000000000000000000000000000000000F8 +:1048C00000000000000000000000000000000000E8 +:1048D00000000000000000000000000000000000D8 +:1048E00000000000000000000000000000000000C8 +:1048F00000000000000000000000000000000000B8 +:1049000000000000000000000000000000000000A7 +:104910000000000000000000000000000000000097 +:104920000000000000000000000000000000000087 +:104930000000000000000000000000000000000077 +:104940000000000000000000000000000000000067 +:104950000000000000000000000000000000000057 +:104960000000000000000000000000000000000047 +:104970000000000000000000000000000000000037 +:104980000000000000000000000000000000000027 +:104990000000000000000000000000000000000017 +:1049A0000000000000000000000000000000000007 +:1049B00000000000000000000000000000000000F7 +:1049C00000000000000000000000000000000000E7 +:1049D00000000000000000000000000000000000D7 +:1049E00000000000000000000000000000000000C7 +:1049F00000000000000000000000000000000000B7 +:104A000000000000000000000000000000000000A6 +:104A10000000000000000000000000000000000096 +:104A20000000000000000000000000000000000086 +:104A30000000000000000000000000000000000076 +:104A40000000000000000000000000000000000066 +:104A50000000000000000000000000000000000056 +:104A60000000000000000000000000000000000046 +:104A70000000000000000000000000000000000036 +:104A80000000000000000000000000000000000026 +:104A90000000000000000000000000000000000016 +:104AA0000000000000000000000000000000000006 +:104AB00000000000000000000000000000000000F6 +:104AC00000000000000000000000000000000000E6 +:104AD00000000000000000000000000000000000D6 +:104AE00000000000000000000000000000000000C6 +:104AF00000000000000000000000000000000000B6 +:104B000000000000000000000000000000000000A5 +:104B10000000000000000000000000000000000095 +:104B20000000000000000000000000000000000085 +:104B30000000000000000000000000000000000075 +:104B40000000000000000000000000000000000065 +:104B50000000000000000000000000000000000055 +:104B60000000000000000000000000000000000045 +:104B70000000000000000000000000000000000035 +:104B80000000000000000000000000000000000025 +:104B90000000000000000000000000000000000015 +:104BA0000000000000000000000000000000000005 +:104BB00000000000000000000000000000000000F5 +:104BC00000000000000000000000000000000000E5 +:104BD00000000000000000000000000000000000D5 +:104BE00000000000000000000000000000000000C5 +:104BF00000000000000000000000000000000000B5 +:104C000000000000000000000000000000000000A4 +:104C10000000000000000000000000000000000094 +:104C20000000000000000000000000000000000084 +:104C30000000000000000000000000000000000074 +:104C40000000000000000000000000000000000064 +:104C50000000000000000000000000000000000054 +:104C60000000000000000000000000000000000044 +:104C70000000000000000000000000000000000034 +:104C80000000000000000000000000000000000024 +:104C90000000000000000000000000000000000014 +:104CA0000000000000000000000000000000000004 +:104CB00000000000000000000000000000000000F4 +:104CC00000000000000000000000000000000000E4 +:104CD00000000000000000000000000000000000D4 +:104CE00000000000000000000000000000000000C4 +:104CF00000000000000000000000000000000000B4 +:104D000000000000000000000000000000000000A3 +:104D10000000000000000000000000000000000093 +:104D20000000000000000000000000000000000083 +:104D30000000000000000000000000000000000073 +:104D40000000000000000000000000000000000063 +:104D50000000000000000000000000000000000053 +:104D60000000000000000000000000000000000043 +:104D70000000000000000000000000000000000033 +:104D80000000000000000000000000000000000023 +:104D90000000000000000000000000000000000013 +:104DA0000000000000000000000000000000000003 +:104DB00000000000000000000000000000000000F3 +:104DC00000000000000000000000000000000000E3 +:104DD00000000000000000000000000000000000D3 +:104DE00000000000000000000000000000000000C3 +:104DF00000000000000000000000000000000000B3 +:104E000000000000000000000000000000000000A2 +:104E10000000000000000000000000000000000092 +:104E20000000000000000000000000000000000082 +:104E30000000000000000000000000000000000072 +:104E40000000000000000000000000000000000062 +:104E50000000000000000000000000000000000052 +:104E60000000000000000000000000000000000042 +:104E70000000000000000000000000000000000032 +:104E80000000000000000000000000000000000022 +:104E90000000000000000000000000000000000012 +:104EA0000000000000000000000000000000000002 +:104EB00000000000000000000000000000000000F2 +:104EC00000000000000000000000000000000000E2 +:104ED00000000000000000000000000000000000D2 +:104EE00000000000000000000000000000000000C2 +:104EF00000000000000000000000000000000000B2 +:104F000000000000000000000000000000000000A1 +:104F10000000000000000000000000000000000091 +:104F20000000000000000000000000000000000081 +:104F30000000000000000000000000000000000071 +:104F40000000000000000000000000000000000061 +:104F50000000000000000000000000000000000051 +:104F60000000000000000000000000000000000041 +:104F70000000000000000000000000000000000031 +:104F80000000000000000000000000000000000021 +:104F90000000000000000000000000000000000011 +:104FA0000000000000000000000000000000000001 +:104FB00000000000000000000000000000000000F1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE00000000000000000000000000000000000C1 +:104FF00000000000000000000000000000000000B1 +:1050000000000000000000000000000000000000A0 +:105010000000000000000000000000000000000090 +:105020000000000000000000000000000000000080 +:105030000000000000000000000000000000000070 +:105040000000000000000000000000000000000060 +:105050000000000000000000000000000000000050 +:105060000000000000000000000000000000000040 +:105070000000000000000000000000000000000030 +:105080000000000000000000000000000000000020 +:105090000000000000000000000000000000000010 +:1050A0000000000000000000000000000000000000 +:1050B00000000000000000000000000000000000F0 +:1050C00000000000000000000000000000000000E0 +:1050D00000000000000000000000000000000000D0 +:1050E00000000000000000000000000000000000C0 +:1050F00000000000000000000000000000000000B0 +:10510000000000000000000000000000000000009F +:10511000000000000000000000000000000000008F +:10512000000000000000000000000000000000007F +:10513000000000000000000000000000000000006F +:10514000000000000000000000000000000000005F +:10515000000000000000000000000000000000004F +:10516000000000000000000000000000000000003F +:10517000000000000000000000000000000000002F +:10518000000000000000000000000000000000001F +:10519000000000000000000000000000000000000F +:1051A00000000000000000000000000000000000FF +:1051B00000000000000000000000000000000000EF +:1051C00000000000000000000000000000000000DF +:1051D00000000000000000000000000000000000CF +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:10520000000000000000000000000000000000009E +:10521000000000000000000000000000000000008E +:10522000000000000000000000000000000000007E +:10523000000000000000000000000000000000006E +:10524000000000000000000000000000000000005E +:10525000000000000000000000000000000000004E +:10526000000000000000000000000000000000003E +:10527000000000000000000000000000000000002E +:10528000000000000000000000000000000000001E +:10529000000000000000000000000000000000000E +:1052A00000000000000000000000000000000000FE +:1052B00000000000000000000000000000000000EE +:1052C00000000000000000000000000000000000DE +:1052D00000000000000000000000000000000000CE +:1052E00000000000000000000000000000000000BE +:1052F00000000000000000000000000000000000AE +:10530000000000000000000000000000000000009D +:10531000000000000000000000000000000000008D +:10532000000000000000000000000000000000007D +:10533000000000000000000000000000000000006D +:10534000000000000000000000000000000000005D +:10535000000000000000000000000000000000004D +:10536000000000000000000000000000000000003D +:10537000000000000000000000000000000000002D +:10538000000000000000000000000000000000001D +:10539000000000000000000000000000000000000D +:1053A00000000000000000000000000000000000FD +:1053B00000000000000000000000000000000000ED +:1053C00000000000000000000000000000000000DD +:1053D00000000000000000000000000000000000CD +:1053E00000000000000000000000000000000000BD +:1053F00000000000000000000000000000000000AD +:10540000000000000000000000000000000000009C +:10541000000000000000000000000000000000008C +:10542000000000000000000000000000000000007C +:10543000000000000000000000000000000000006C +:10544000000000000000000000000000000000005C +:10545000000000000000000000000000000000004C +:10546000000000000000000000000000000000003C +:10547000000000000000000000000000000000002C +:10548000000000000000000000000000000000001C +:10549000000000000000000000000000000000000C +:1054A00000000000000000000000000000000000FC +:1054B00000000000000000000000000000000000EC +:1054C00000000000000000000000000000000000DC +:1054D00000000000000000000000000000000000CC +:1054E00000000000000000000000000000000000BC +:1054F00000000000000000000000000000000000AC +:10550000000000000000000000000000000000009B +:10551000000000000000000000000000000000008B +:10552000000000000000000000000000000000007B +:10553000000000000000000000000000000000006B +:10554000000000000000000000000000000000005B +:10555000000000000000000000000000000000004B +:10556000000000000000000000000000000000003B +:10557000000000000000000000000000000000002B +:10558000000000000000000000000000000000001B +:10559000000000000000000000000000000000000B +:1055A00000000000000000000000000000000000FB +:1055B00000000000000000000000000000000000EB +:1055C00000000000000000000000000000000000DB +:1055D00000000000000000000000000000000000CB +:1055E00000000000000000000000000000000000BB +:1055F00000000000000000000000000000000000AB +:10560000000000000000000000000000000000009A +:10561000000000000000000000000000000000008A +:10562000000000000000000000000000000000007A +:10563000000000000000000000000000000000006A +:10564000000000000000000000000000000000005A +:10565000000000000000000000000000000000004A +:10566000000000000000000000000000000000003A +:10567000000000000000000000000000000000002A +:10568000000000000000000000000000000000001A +:10569000000000000000000000000000000000000A +:1056A00000000000000000000000000000000000FA +:1056B00000000000000000000000000000000000EA +:1056C00000000000000000000000000000000000DA +:1056D00000000000000000000000000000000000CA +:1056E00000000000000000000000000000000000BA +:1056F00000000000000000000000000000000000AA +:105700000000000000000000000000000000000099 +:105710000000000000000000000000000000000089 +:105720000000000000000000000000000000000079 +:105730000000000000000000000000000000000069 +:105740000000000000000000000000000000000059 +:105750000000000000000000000000000000000049 +:105760000000000000000000000000000000000039 +:105770000000000000000000000000000000000029 +:105780000000000000000000000000000000000019 +:105790000000000000000000000000000000000009 +:1057A00000000000000000000000000000000000F9 +:1057B00000000000000000000000000000000000E9 +:1057C00000000000000000000000000000000000D9 +:1057D00000000000000000000000000000000000C9 +:1057E00000000000000000000000000000000000B9 +:1057F00000000000000000000000000000000000A9 +:105800000000000000000000000000000000000098 +:105810000000000000000000000000000000000088 +:105820000000000000000000000000000000000078 +:105830000000000000000000000000000000000068 +:105840000000000000000000000000000000000058 +:105850000000000000000000000000000000000048 +:105860000000000000000000000000000000000038 +:105870000000000000000000000000000000000028 +:105880000000000000000000000000000000000018 +:105890000000000000000000000000000000000008 +:1058A00000000000000000000000000000000000F8 +:1058B00000000000000000000000000000000000E8 +:1058C00000000000000000000000000000000000D8 +:1058D00000000000000000000000000000000000C8 +:1058E00000000000000000000000000000000000B8 +:1058F00000000000000000000000000000000000A8 +:105900000000000000000000000000000000000097 +:105910000000000000000000000000000000000087 +:105920000000000000000000000000000000000077 +:105930000000000000000000000000000000000067 +:105940000000000000000000000000000000000057 +:105950000000000000000000000000000000000047 +:105960000000000000000000000000000000000037 +:105970000000000000000000000000000000000027 +:105980000000000000000000000000000000000017 +:105990000000000000000000000000000000000007 +:1059A00000000000000000000000000000000000F7 +:1059B00000000000000000000000000000000000E7 +:1059C00000000000000000000000000000000000D7 +:1059D00000000000000000000000000000000000C7 +:1059E00000000000000000000000000000000000B7 +:1059F00000000000000000000000000000000000A7 +:105A00000000000000000000000000000000000096 +:105A10000000000000000000000000000000000086 +:105A20000000000000000000000000000000000076 +:105A30000000000000000000000000000000000066 +:105A40000000000000000000000000000000000056 +:105A50000000000000000000000000000000000046 +:105A60000000000000000000000000000000000036 +:105A70000000000000000000000000000000000026 +:105A80000000000000000000000000000000000016 +:105A90000000000000000000000000000000000006 +:105AA00000000000000000000000000000000000F6 +:105AB00000000000000000000000000000000000E6 +:105AC00000000000000000000000000000000000D6 +:105AD00000000000000000000000000000000000C6 +:105AE00000000000000000000000000000000000B6 +:105AF00000000000000000000000000000000000A6 +:105B00000000000000000000000000000000000095 +:105B10000000000000000000000000000000000085 +:105B20000000000000000000000000000000000075 +:105B30000000000000000000000000000000000065 +:105B40000000000000000000000000000000000055 +:105B50000000000000000000000000000000000045 +:105B60000000000000000000000000000000000035 +:105B70000000000000000000000000000000000025 +:105B80000000000000000000000000000000000015 +:105B90000000000000000000000000000000000005 +:105BA00000000000000000000000000000000000F5 +:105BB00000000000000000000000000000000000E5 +:105BC00000000000000000000000000000000000D5 +:105BD00000000000000000000000000000000000C5 +:105BE00000000000000000000000000000000000B5 +:105BF00000000000000000000000000000000000A5 +:105C00000000000000000000000000000000000094 +:105C10000000000000000000000000000000000084 +:105C20000000000000000000000000000000000074 +:105C30000000000000000000000000000000000064 +:105C40000000000000000000000000000000000054 +:105C50000000000000000000000000000000000044 +:105C60000000000000000000000000000000000034 +:105C70000000000000000000000000000000000024 +:105C80000000000000000000000000000000000014 +:105C90000000000000000000000000000000000004 +:105CA00000000000000000000000000000000000F4 +:105CB00000000000000000000000000000000000E4 +:105CC00000000000000000000000000000000000D4 +:105CD00000000000000000000000000000000000C4 +:105CE00000000000000000000000000000000000B4 +:105CF00000000000000000000000000000000000A4 +:105D00000000000000000000000000000000000093 +:105D10000000000000000000000000000000000083 +:105D20000000000000000000000000000000000073 +:105D30000000000000000000000000000000000063 +:105D40000000000000000000000000000000000053 +:105D50000000000000000000000000000000000043 +:105D60000000000000000000000000000000000033 +:105D70000000000000000000000000000000000023 +:105D80000000000000000000000000000000000013 +:105D90000000000000000000000000000000000003 +:105DA00000000000000000000000000000000000F3 +:105DB00000000000000000000000000000000000E3 +:105DC00000000000000000000000000000000000D3 +:105DD00000000000000000000000000000000000C3 +:105DE00000000000000000000000000000000000B3 +:105DF00000000000000000000000000000000000A3 +:105E00000000000000000000000000000000000092 +:105E10000000000000000000000000000000000082 +:105E20000000000000000000000000000000000072 +:105E30000000000000000000000000000000000062 +:105E40000000000000000000000000000000000052 +:105E50000000000000000000000000000000000042 +:105E60000000000000000000000000000000000032 +:105E70000000000000000000000000000000000022 +:105E80000000000000000000000000000000000012 +:105E90000000000000000000000000000000000002 +:105EA00000000000000000000000000000000000F2 +:105EB00000000000000000000000000000000000E2 +:105EC00000000000000000000000000000000000D2 +:105ED00000000000000000000000000000000000C2 +:105EE00000000000000000000000000000000000B2 +:105EF00000000000000000000000000000000000A2 +:105F00000000000000000000000000000000000091 +:105F10000000000000000000000000000000000081 +:105F20000000000000000000000000000000000071 +:105F30000000000000000000000000000000000061 +:105F40000000000000000000000000000000000051 +:105F50000000000000000000000000000000000041 +:105F60000000000000000000000000000000000031 +:105F70000000000000000000000000000000000021 +:105F80000000000000000000000000000000000011 +:105F90000000000000000000000000000000000001 +:105FA00000000000000000000000000000000000F1 +:105FB00000000000000000000000000000000000E1 +:105FC00000000000000000000000000000000000D1 +:105FD00000000000000000000000000000000000C1 +:105FE00000000000000000000000000000000000B1 +:105FF00000000000000000000000000000000000A1 +:106000000000000000000000000000000000000090 +:106010000000000000000000000000000000000080 +:106020000000000000000000000000000000000070 +:106030000000000000000000000000000000000060 +:106040000000000000000000000000000000000050 +:106050000000000000000000000000000000000040 +:106060000000000000000000000000000000000030 +:106070000000000000000000000000000000000020 +:106080000000000000000000000000000000000010 +:106090000000000000000000000000000000000000 +:1060A00000000000000000000000000000000000F0 +:1060B00000000000000000000000000000000000E0 +:1060C00000000000000000000000000000000000D0 +:1060D00000000000000000000000000000000000C0 +:1060E00000000000000000000000000000000000B0 +:1060F00000000000000000000000000000000000A0 +:10610000000000000000000000000000000000008F +:10611000000000000000000000000000000000007F +:10612000000000000000000000000000000000006F +:10613000000000000000000000000000000000005F +:10614000000000000000000000000000000000004F +:10615000000000000000000000000000000000003F +:10616000000000000000000000000000000000002F +:10617000000000000000000000000000000000001F +:10618000000000000000000000000000000000000F +:1061900000000000000000000000000000000000FF +:1061A00000000000000000000000000000000000EF +:1061B00000000000000000000000000000000000DF +:1061C00000000000000000000000000000000000CF +:1061D00000000000000000000000000000000000BF +:1061E00000000000000000000000000000000000AF +:1061F000000000000000000000000000000000009F +:10620000000000000000000000000000000000008E +:10621000000000000000000000000000000000007E +:10622000000000000000000000000000000000006E +:10623000000000000000000000000000000000005E +:10624000000000000000000000000000000000004E +:10625000000000000000000000000000000000003E +:10626000000000000000000000000000000000002E +:10627000000000000000000000000000000000001E +:10628000000000000000000000000000000000000E +:1062900000000000000000000000000000000000FE +:1062A00000000000000000000000000000000000EE +:1062B00000000000000000000000000000000000DE +:1062C00000000000000000000000000000000000CE +:1062D00000000000000000000000000000000000BE +:1062E00000000000000000000000000000000000AE +:1062F000000000000000000000000000000000009E +:10630000000000000000000000000000000000008D +:10631000000000000000000000000000000000007D +:10632000000000000000000000000000000000006D +:10633000000000000000000000000000000000005D +:10634000000000000000000000000000000000004D +:10635000000000000000000000000000000000003D +:10636000000000000000000000000000000000002D +:10637000000000000000000000000000000000001D +:10638000000000000000000000000000000000000D +:1063900000000000000000000000000000000000FD +:1063A00000000000000000000000000000000000ED +:1063B00000000000000000000000000000000000DD +:1063C00000000000000000000000000000000000CD +:1063D00000000000000000000000000000000000BD +:1063E00000000000000000000000000000000000AD +:1063F000000000000000000000000000000000009D +:10640000000000000000000000000000000000008C +:10641000000000000000000000000000000000007C +:10642000000000000000000000000000000000006C +:10643000000000000000000000000000000000005C +:10644000000000000000000000000000000000004C +:10645000000000000000000000000000000000003C +:10646000000000000000000000000000000000002C +:10647000000000000000000000000000000000001C +:10648000000000000000000000000000000000000C +:1064900000000000000000000000000000000000FC +:1064A00000000000000000000000000000000000EC +:1064B00000000000000000000000000000000000DC +:1064C00000000000000000000000000000000000CC +:1064D00000000000000000000000000000000000BC +:1064E00000000000000000000000000000000000AC +:1064F000000000000000000000000000000000009C +:10650000000000000000000000000000000000008B +:10651000000000000000000000000000000000007B +:10652000000000000000000000000000000000006B +:10653000000000000000000000000000000000005B +:10654000000000000000000000000000000000004B +:10655000000000000000000000000000000000003B +:10656000000000000000000000000000000000002B +:10657000000000000000000000000000000000001B +:10658000000000000000000000000000000000000B +:1065900000000000000000000000000000000000FB +:1065A00000000000000000000000000000000000EB +:1065B00000000000000000000000000000000000DB +:1065C00000000000000000000000000000000000CB +:1065D00000000000000000000000000000000000BB +:1065E00000000000000000000000000000000000AB +:1065F000000000000000000000000000000000009B +:10660000000000000000000000000000000000008A +:10661000000000000000000000000000000000007A +:10662000000000000000000000000000000000006A +:10663000000000000000000000000000000000005A +:10664000000000000000000000000000000000004A +:10665000000000000000000000000000000000003A +:10666000000000000000000000000000000000002A +:10667000000000000000000000000000000000001A +:10668000000000000000000000000000000000000A +:1066900000000000000000000000000000000000FA +:1066A00000000000000000000000000000000000EA +:1066B00000000000000000000000000000000000DA +:1066C00000000000000000000000000000000000CA +:1066D00000000000000000000000000000000000BA +:1066E00000000000000000000000000000000000AA +:1066F000000000000000000000000000000000009A +:106700000000000000000000000000000000000089 +:106710000000000000000000000000000000000079 +:106720000000000000000000000000000000000069 +:106730000000000000000000000000000000000059 +:106740000000000000000000000000000000000049 +:106750000000000000000000000000000000000039 +:106760000000000000000000000000000000000029 +:106770000000000000000000000000000000000019 +:106780000000000000000000000000000000000009 +:1067900000000000000000000000000000000000F9 +:1067A00000000000000000000000000000000000E9 +:1067B00000000000000000000000000000000000D9 +:1067C00000000000000000000000000000000000C9 +:1067D00000000000000000000000000000000000B9 +:1067E00000000000000000000000000000000000A9 +:1067F0000000000000000000000000000000000099 +:106800000000000000000000000000000000000088 +:106810000000000000000000000000000000000078 +:106820000000000000000000000000000000000068 +:106830000000000000000000000000000000000058 +:106840000000000000000000000000000000000048 +:106850000000000000000000000000000000000038 +:106860000000000000000000000000000000000028 +:106870000000000000000000000000000000000018 +:106880000000000000000000000000000000000008 +:1068900000000000000000000000000000000000F8 +:1068A00000000000000000000000000000000000E8 +:1068B00000000000000000000000000000000000D8 +:1068C00000000000000000000000000000000000C8 +:1068D00000000000000000000000000000000000B8 +:1068E00000000000000000000000000000000000A8 +:1068F0000000000000000000000000000000000098 +:106900000000000000000000000000000000000087 +:106910000000000000000000000000000000000077 +:106920000000000000000000000000000000000067 +:106930000000000000000000000000000000000057 +:106940000000000000000000000000000000000047 +:106950000000000000000000000000000000000037 +:106960000000000000000000000000000000000027 +:106970000000000000000000000000000000000017 +:106980000000000000000000000000000000000007 +:1069900000000000000000000000000000000000F7 +:1069A00000000000000000000000000000000000E7 +:1069B00000000000000000000000000000000000D7 +:1069C00000000000000000000000000000000000C7 +:1069D00000000000000000000000000000000000B7 +:1069E00000000000000000000000000000000000A7 +:1069F0000000000000000000000000000000000097 +:106A00000000000000000000000000000000000086 +:106A10000000000000000000000000000000000076 +:106A20000000000000000000000000000000000066 +:106A30000000000000000000000000000000000056 +:106A40000000000000000000000000000000000046 +:106A50000000000000000000000000000000000036 +:106A60000000000000000000000000000000000026 +:106A70000000000000000000000000000000000016 +:106A80000000000000000000000000000000000006 +:106A900000000000000000000000000000000000F6 +:106AA00000000000000000000000000000000000E6 +:106AB00000000000000000000000000000000000D6 +:106AC00000000000000000000000000000000000C6 +:106AD00000000000000000000000000000000000B6 +:106AE00000000000000000000000000000000000A6 +:106AF0000000000000000000000000000000000096 +:106B00000000000000000000000000000000000085 +:106B10000000000000000000000000000000000075 +:106B20000000000000000000000000000000000065 +:106B30000000000000000000000000000000000055 +:106B40000000000000000000000000000000000045 +:106B50000000000000000000000000000000000035 +:106B60000000000000000000000000000000000025 +:106B70000000000000000000000000000000000015 +:106B80000000000000000000000000000000000005 +:106B900000000000000000000000000000000000F5 +:106BA00000000000000000000000000000000000E5 +:106BB00000000000000000000000000000000000D5 +:106BC00000000000000000000000000000000000C5 +:106BD00000000000000000000000000000000000B5 +:106BE00000000000000000000000000000000000A5 +:106BF0000000000000000000000000000000000095 +:106C00000000000000000000000000000000000084 +:106C10000000000000000000000000000000000074 +:106C20000000000000000000000000000000000064 +:106C30000000000000000000000000000000000054 +:106C40000000000000000000000000000000000044 +:106C50000000000000000000000000000000000034 +:106C60000000000000000000000000000000000024 +:106C70000000000000000000000000000000000014 +:106C80000000000000000000000000000000000004 +:106C900000000000000000000000000000000000F4 +:106CA00000000000000000000000000000000000E4 +:106CB00000000000000000000000000000000000D4 +:106CC00000000000000000000000000000000000C4 +:106CD00000000000000000000000000000000000B4 +:106CE00000000000000000000000000000000000A4 +:106CF0000000000000000000000000000000000094 +:106D00000000000000000000000000000000000083 +:106D10000000000000000000000000000000000073 +:106D20000000000000000000000000000000000063 +:106D30000000000000000000000000000000000053 +:106D40000000000000000000000000000000000043 +:106D50000000000000000000000000000000000033 +:106D60000000000000000000000000000000000023 +:106D70000000000000000000000000000000000013 +:106D80000000000000000000000000000000000003 +:106D900000000000000000000000000000000000F3 +:106DA00000000000000000000000000000000000E3 +:106DB00000000000000000000000000000000000D3 +:106DC00000000000000000000000000000000000C3 +:106DD00000000000000000000000000000000000B3 +:106DE00000000000000000000000000000000000A3 +:106DF0000000000000000000000000000000000093 +:106E00000000000000000000000000000000000082 +:106E10000000000000000000000000000000000072 +:106E20000000000000000000000000000000000062 +:106E30000000000000000000000000000000000052 +:106E40000000000000000000000000000000000042 +:106E50000000000000000000000000000000000032 +:106E60000000000000000000000000000000000022 +:106E70000000000000000000000000000000000012 +:106E80000000000000000000000000000000000002 +:106E900000000000000000000000000000000000F2 +:106EA00000000000000000000000000000000000E2 +:106EB00000000000000000000000000000000000D2 +:106EC00000000000000000000000000000000000C2 +:106ED00000000000000000000000000000000000B2 +:106EE00000000000000000000000000000000000A2 +:106EF0000000000000000000000000000000000092 +:106F00000000000000000000000000000000000081 +:106F10000000000000000000000000000000000071 +:106F20000000000000000000000000000000000061 +:106F30000000000000000000000000000000000051 +:106F40000000000000000000000000000000000041 +:106F50000000000000000000000000000000000031 +:106F60000000000000000000000000000000000021 +:106F70000000000000000000000000000000000011 +:106F80000000000000000000000000000000000001 +:106F900000000000000000000000000000000000F1 +:106FA00000000000000000000000000000000000E1 +:106FB00000000000000000000000000000000000D1 +:106FC00000000000000000000000000000000000C1 +:106FD00000000000000000000000000000000000B1 +:106FE00000000000000000000000000000000000A1 +:106FF0000000000000000000000000000000000091 +:107000000000000000000000000000000000000080 +:107010000000000000000000000000000000000070 +:107020000000000000000000000000000000000060 +:107030000000000000000000000000000000000050 +:107040000000000000000000000000000000000040 +:107050000000000000000000000000000000000030 +:107060000000000000000000000000000000000020 +:107070000000000000000000000000000000000010 +:107080000000000000000000000000000000000000 +:1070900000000000000000000000000000000000F0 +:1070A00000000000000000000000000000000000E0 +:1070B00000000000000000000000000000000000D0 +:1070C00000000000000000000000000000000000C0 +:1070D00000000000000000000000000000000000B0 +:1070E00000000000000000000000000000000000A0 +:1070F0000000000000000000000000000000000090 +:10710000000000000000000000000000000000007F +:10711000000000000000000000000000000000006F +:10712000000000000000000000000000000000005F +:10713000000000000000000000000000000000004F +:10714000000000000000000000000000000000003F +:10715000000000000000000000000000000000002F +:10716000000000000000000000000000000000001F +:10717000000000000000000000000000000000000F +:1071800000000000000000000000000000000000FF +:1071900000000000000000000000000000000000EF +:1071A00000000000000000000000000000000000DF +:1071B00000000000000000000000000000000000CF +:1071C00000000000000000000000000000000000BF +:1071D00000000000000000000000000000000000AF +:1071E000000000000000000000000000000000009F +:1071F000000000000000000000000000000000008F +:10720000000000000000000000000000000000007E +:10721000000000000000000000000000000000006E +:10722000000000000000000000000000000000005E +:10723000000000000000000000000000000000004E +:10724000000000000000000000000000000000003E +:10725000000000000000000000000000000000002E +:10726000000000000000000000000000000000001E +:10727000000000000000000000000000000000000E +:1072800000000000000000000000000000000000FE +:1072900000000000000000000000000000000000EE +:1072A00000000000000000000000000000000000DE +:1072B00000000000000000000000000000000000CE +:1072C00000000000000000000000000000000000BE +:1072D00000000000000000000000000000000000AE +:1072E000000000000000000000000000000000009E +:1072F000000000000000000000000000000000008E +:10730000000000000000000000000000000000007D +:10731000000000000000000000000000000000006D +:10732000000000000000000000000000000000005D +:10733000000000000000000000000000000000004D +:10734000000000000000000000000000000000003D +:10735000000000000000000000000000000000002D +:10736000000000000000000000000000000000001D +:10737000000000000000000000000000000000000D +:1073800000000000000000000000000000000000FD +:1073900000000000000000000000000000000000ED +:1073A00000000000000000000000000000000000DD +:1073B00000000000000000000000000000000000CD +:1073C00000000000000000000000000000000000BD +:1073D00000000000000000000000000000000000AD +:1073E000000000000000000000000000000000009D +:1073F000000000000000000000000000000000008D +:10740000000000000000000000000000000000007C +:10741000000000000000000000000000000000006C +:10742000000000000000000000000000000000005C +:10743000000000000000000000000000000000004C +:10744000000000000000000000000000000000003C +:10745000000000000000000000000000000000002C +:10746000000000000000000000000000000000001C +:10747000000000000000000000000000000000000C +:1074800000000000000000000000000000000000FC +:1074900000000000000000000000000000000000EC +:1074A00000000000000000000000000000000000DC +:1074B00000000000000000000000000000000000CC +:1074C00000000000000000000000000000000000BC +:1074D00000000000000000000000000000000000AC +:1074E000000000000000000000000000000000009C +:1074F000000000000000000000000000000000008C +:10750000000000000000000000000000000000007B +:10751000000000000000000000000000000000006B +:10752000000000000000000000000000000000005B +:10753000000000000000000000000000000000004B +:10754000000000000000000000000000000000003B +:10755000000000000000000000000000000000002B +:10756000000000000000000000000000000000001B +:10757000000000000000000000000000000000000B +:1075800000000000000000000000000000000000FB +:1075900000000000000000000000000000000000EB +:1075A00000000000000000000000000000000000DB +:1075B00000000000000000000000000000000000CB +:1075C00000000000000000000000000000000000BB +:1075D00000000000000000000000000000000000AB +:1075E000000000000000000000000000000000009B +:1075F000000000000000000000000000000000008B +:10760000000000000000000000000000000000007A +:10761000000000000000000000000000000000006A +:10762000000000000000000000000000000000005A +:10763000000000000000000000000000000000004A +:10764000000000000000000000000000000000003A +:10765000000000000000000000000000000000002A +:10766000000000000000000000000000000000001A +:10767000000000000000000000000000000000000A +:1076800000000000000000000000000000000000FA +:1076900000000000000000000000000000000000EA +:1076A00000000000000000000000000000000000DA +:1076B00000000000000000000000000000000000CA +:1076C00000000000000000000000000000000000BA +:1076D00000000000000000000000000000000000AA +:1076E000000000000000000000000000000000009A +:1076F000000000000000000000000000000000008A +:107700000000000000000000000000000000000079 +:107710000000000000000000000000000000000069 +:107720000000000000000000000000000000000059 +:107730000000000000000000000000000000000049 +:107740000000000000000000000000000000000039 +:107750000000000000000000000000000000000029 +:107760000000000000000000000000000000000019 +:107770000000000000000000000000000000000009 +:1077800000000000000000000000000000000000F9 +:1077900000000000000000000000000000000000E9 +:1077A00000000000000000000000000000000000D9 +:1077B00000000000000000000000000000000000C9 +:1077C00000000000000000000000000000000000B9 +:1077D00000000000000000000000000000000000A9 +:1077E0000000000000000000000000000000000099 +:1077F0000000000000000000000000000000000089 +:107800000000000000000000000000000000000078 +:107810000000000000000000000000000000000068 +:107820000000000000000000000000000000000058 +:107830000000000000000000000000000000000048 +:107840000000000000000000000000000000000038 +:107850000000000000000000000000000000000028 +:107860000000000000000000000000000000000018 +:107870000000000000000000000000000000000008 +:1078800000000000000000000000000000000000F8 +:1078900000000000000000000000000000000000E8 +:1078A00000000000000000000000000000000000D8 +:1078B00000000000000000000000000000000000C8 +:1078C00000000000000000000000000000000000B8 +:1078D00000000000000000000000000000000000A8 +:1078E0000000000000000000000000000000000098 +:1078F0000000000000000000000000000000000088 +:107900000000000000000000000000000000000077 +:107910000000000000000000000000000000000067 +:107920000000000000000000000000000000000057 +:107930000000000000000000000000000000000047 +:107940000000000000000000000000000000000037 +:107950000000000000000000000000000000000027 +:107960000000000000000000000000000000000017 +:107970000000000000000000000000000000000007 +:1079800000000000000000000000000000000000F7 +:1079900000000000000000000000000000000000E7 +:1079A00000000000000000000000000000000000D7 +:1079B00000000000000000000000000000000000C7 +:1079C00000000000000000000000000000000000B7 +:1079D00000000000000000000000000000000000A7 +:1079E0000000000000000000000000000000000097 +:1079F0000000000000000000000000000000000087 +:107A00000000000000000000000000000000000076 +:107A10000000000000000000000000000000000066 +:107A20000000000000000000000000000000000056 +:107A30000000000000000000000000000000000046 +:107A40000000000000000000000000000000000036 +:107A50000000000000000000000000000000000026 +:107A60000000000000000000000000000000000016 +:107A70000000000000000000000000000000000006 +:107A800000000000000000000000000000000000F6 +:107A900000000000000000000000000000000000E6 +:107AA00000000000000000000000000000000000D6 +:107AB00000000000000000000000000000000000C6 +:107AC00000000000000000000000000000000000B6 +:107AD00000000000000000000000000000000000A6 +:107AE0000000000000000000000000000000000096 +:107AF0000000000000000000000000000000000086 +:107B00000000000000000000000000000000000075 +:107B10000000000000000000000000000000000065 +:107B20000000000000000000000000000000000055 +:107B30000000000000000000000000000000000045 +:107B40000000000000000000000000000000000035 +:107B50000000000000000000000000000000000025 +:107B60000000000000000000000000000000000015 +:107B70000000000000000000000000000000000005 +:107B800000000000000000000000000000000000F5 +:107B900000000000000000000000000000000000E5 +:107BA00000000000000000000000000000000000D5 +:107BB00000000000000000000000000000000000C5 +:107BC00000000000000000000000000000000000B5 +:107BD00000000000000000000000000000000000A5 +:107BE0000000000000000000000000000000000095 +:107BF0000000000000000000000000000000000085 +:107C00000000000000000000000000000000000074 +:107C10000000000000000000000000000000000064 +:107C20000000000000000000000000000000000054 +:107C30000000000000000000000000000000000044 +:107C40000000000000000000000000000000000034 +:107C50000000000000000000000000000000000024 +:107C60000000000000000000000000000000000014 +:107C70000000000000000000000000000000000004 +:107C800000000000000000000000000000000000F4 +:107C900000000000000000000000000000000000E4 +:107CA00000000000000000000000000000000000D4 +:107CB00000000000000000000000000000000000C4 +:107CC00000000000000000000000000000000000B4 +:107CD00000000000000000000000000000000000A4 +:107CE0000000000000000000000000000000000094 +:107CF0000000000000000000000000000000000084 +:107D00000000000000000000000000000000000073 +:107D10000000000000000000000000000000000063 +:107D20000000000000000000000000000000000053 +:107D30000000000000000000000000000000000043 +:107D40000000000000000000000000000000000033 +:107D50000000000000000000000000000000000023 +:107D60000000000000000000000000000000000013 +:107D70000000000000000000000000000000000003 +:107D800000000000000000000000000000000000F3 +:107D900000000000000000000000000000000000E3 +:107DA00000000000000000000000000000000000D3 +:107DB00000000000000000000000000000000000C3 +:107DC00000000000000000000000000000000000B3 +:107DD00000000000000000000000000000000000A3 +:107DE0000000000000000000000000000000000093 +:107DF0000000000000000000000000000000000083 +:107E00000000000000000000000000000000000072 +:107E10000000000000000000000000000000000062 +:107E20000000000000000000000000000000000052 +:107E30000000000000000000000000000000000042 +:107E40000000000000000000000000000000000032 +:107E50000000000000000000000000000000000022 +:107E60000000000000000000000000000000000012 +:107E70000000000000000000000000000000000002 +:107E800000000000000000000000000000000000F2 +:107E900000000000000000000000000000000000E2 +:107EA00000000000000000000000000000000000D2 +:107EB00000000000000000000000000000000000C2 +:107EC00000000000000000000000000000000000B2 +:107ED00000000000000000000000000000000000A2 +:107EE0000000000000000000000000000000000092 +:107EF0000000000000000000000000000000000082 +:107F00000000000000000000000000000000000071 +:107F10000000000000000000000000000000000061 +:107F20000000000000000000000000000000000051 +:107F30000000000000000000000000000000000041 +:107F40000000000000000000000000000000000031 +:107F50000000000000000000000000000000000021 +:107F60000000000000000000000000000000000011 +:107F70000000000000000000000000000000000001 +:107F800000000000000000000000000000000000F1 +:107F900000000000000000000000000000000000E1 +:107FA00000000000000000000000000000000000D1 +:107FB00000000000000000000000000000000000C1 +:107FC00000000000000000000000000000000000B1 +:107FD00000000000000000000000000000000000A1 +:107FE0000000000000000000000000000000000091 +:107FF0000000000000000000000000000000000081 +:108000000000000000000000000000000000000070 +:108010000000000000000000000000000000000060 +:108020000000000000000000000000000000000050 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:1080800000000000000000000000000000000000F0 +:1080900000000000000000000000000000000000E0 +:1080A00000000000000000000000000000000000D0 +:1080B00000000000000000000000000000000000C0 +:1080C00000000000000000000000000000000000B0 +:1080D00000000000000000000000000000000000A0 +:1080E0000000000000000000000000000000000090 +:1080F0000000000000000000000000000000000080 +:1081000006F0F15506F0F15506F0F15506F0F1557F +:108110001414141514141414141313141313141323 +:10812000141414141414141415141414141414140E +:1081300014141414141414141514151415151514FA +:1081400014141414141414141414141414141414EF +:1081500013141413131313131514141414141415E3 +:1081600013141414131413131514141414141515D0 +:1081700014141414131413141413131314141414C4 +:1081800014141413131413131414131313141414B6 +:1081900014141413131313131313131313131414AA +:1081A0001414141414141414141414131414141490 +:1081B0001414141413131314141413131414141484 +:1081C0001414141414131414141414141414141470 +:1081D0001313131313131313141414141414141566 +:1081E0001413131313131313141414141414141555 +:1081F0001414131413131314131413131313141448 +:108200001413131313131313141414141414141534 +:10821000141313131313131313131413131314142A +:108220001414131313131314141414141414141611 +:1082300015141414141514151616161615151515EF +:1082400014141414141514151515151515151515E4 +:1082500014141414141414141414141414141415DD +:1082600015151415151515151514141414141415C5 +:1082700014141415151514141414151414141415B9 +:1082800014151415151515151515151415141415A3 +:10829000141414151414141414141414141414149D +:1082A0001415141515141514151515151515151582 +:1082B0001514151515141515151515151514151571 +:1082C0001514151515151414141415151515151464 +:1082D0001515151515151515151514141515141551 +:1082E0001515151515151515141314141414141447 +:1082F0001414141414141414151415141515151538 +:10830000141514151414141413141414141414152B +:10831000141414151413131314141414141515151C +:108320001414151514141313141415151515141508 +:1083300016161616161515151515151515151516E7 +:1083400017171818171617161415151515161515CD +:10835000000000000000000000000000000000001D +:10836000000000000000000000000000000000000D +:1083700000000000000000000000000000000000FD +:1083800000000000000000000000000000000000ED +:108390000000000000000000151514151415151537 +:1083A0001514141414141514151515151415151584 +:1083B0001515151415151515151515151415141570 +:1083C0001515151515151515151515151415141460 +:1083D0001515151515151515151414141314131456 +:1083E0001514141415151515151514141314131349 +:1083F0001515151415151516151515141414141531 +:10840000141414131414151515151414131413142B +:10841000141314131414151615141413131313141E +:10842000141313121313141515151414141414140F +:1084300014141414141415161514141413131314FB +:1084400014141414141415161515141413141314E9 +:1084500014141414151415161514141313131313DC +:1084600014141414151415161515141413131313CA +:1084700014151415151415161515141413141314B6 +:1084800013141413141415161514131313131313B0 +:108490001415151515151516151414131313131398 +:1084A000131314131414151616151414131413148B +:1084B000141415141415151716151415151515156E +:1084C0001616161616161617161515151515151552 +:1084D0001515161615161616151515151515151547 +:1084E000151515151515151615161515151515153A +:1084F000151415151515151615151515151515152C +:108500001515151515151616161615161616151514 +:108510001515151515151616151515151515151509 +:1085200015141515151515161516151515151515FA +:1085300015151615151516161615161616151615E3 +:1085400015151515151516161515151515151414DB +:1085500015151615161516161616161516151515C3 +:1085600015151515151516161516161616161515B4 +:1085700014141514151515151515151515151515AE +:108580001515151516161516151515161515151597 +:10859000141514151515151615151515151515158C +:1085A0001515151516161617151516161615151573 +:1085B000151515151616161716161717171616165B +:1085C0001616161616161617171718181816171740 +:1085D00015161616161716160000000000000000EB +:1085E000000000000000000000000000000000008B +:1085F000000000000000000000000000000000007B +:10860000000000000000000000000000000000006A +:10861000000000000000000000000000000000005A +:1086200016151515151615161615141515151515F7 +:1086300016161616161615161616161616161616DB +:1086400016161616151616161616161617161717C8 +:1086500016161616151615151616161616161717BB +:1086600016161616151615161616161616161717AA +:10867000161616161515151516161616171717179A +:10868000161616161515151616151515161616178F +:10869000151616161515151516151616161617177E +:1086A0001616161615151515151515151616161771 +:1086B0001716161616161516161616161616171758 +:1086C000161616161515151516161616171617174B +:1086D0001616161616161616161616161716181736 +:1086E0001616161615151515161616161717171829 +:1086F0001716161616151515161616171717171816 +:108700001716161615161616161616161716171706 +:1087100017161616151615151616161617171718F6 +:1087200017161616151515151615171616161718E9 +:1087300017171616161616161616161616171718D3 +:1087400017171717181818171919191918181819A9 +:10875000171717181818181818181819181818189B +:108760001617171718181717171718181717171895 +:10877000171818181818181818181818181818187A +:10878000171717181818181718181818181818186D +:108790001818181919181818181819191918181953 +:1087A0001817181818181718171717181817171850 +:1087B0001818181818181818181819181918191935 +:1087C0001818181819181818181818191919181924 +:1087D0001818181819181818181819191919191912 +:1087E0001818191919191818181818181919181803 +:1087F00018191919191819181717181719181818F6 +:1088000018181818181818181818191919191919E2 +:108810001818191A181818181718181818181819D5 +:108820001819191919181818181819191919191ABD +:1088300018191A1A19191818191919191A1A191AA6 +:108840001A1A1B1B1B1A19191919191B1A1A1A1A89 +:108850001C1C1C1D1C1B1C1A191A1A1A1B1B1A1A69 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800000000000000000000000000000000000E8 +:1088900000000000000000000000000000000000D8 +:1088A000000000000000000018181718171718180B +:1088B0001816161717161717191818181718181842 +:1088C000181818181818191818181818171717172B +:1088D0001818181818191819181918181718171817 +:1088E0001918191919191919181918171717161706 +:1088F00018181819191819191919181817181717F5 +:108900001819181919191A191719181817181717E3 +:1089100018181818191819181819181817181717D7 +:108920001818181818191A1A1918181817171718C4 +:1089300018171716181819191919181818171818B8 +:1089400019171818191919191919191817171718A3 +:108950001818171819181B1A191919181717171892 +:10896000181819191A191A19191918171717161783 +:108970001918191819191A191A191918181817176E +:1089800019191919181819191A1918181818171760 +:108990001818181718181A191A1818171717161759 +:1089A00018191918191919191A1918181717161743 +:1089B000181819171818191B1A1A1918181817182F +:1089C000181819191919191B191919191B1B1A1912 +:1089D0001B1B1B1C1A1B1A1B1A191A191A1A1A1AF2 +:1089E000191A1A1B1A1A1A1A191A1A1A1B1A1A1AE7 +:1089F0001A191A1A1A1A1A1B1A1A1A1A1B1A1A1AD6 +:108A00001A1A1A1A1A1A1A1B1A1A1B1A1B1A1A1AC3 +:108A1000191A1A1B1A1A1A1B1A1A1A1B1B1A1B1AB2 +:108A20001A1A1B1A1A1A1A1B1A1A1B1A1A1A1A1AA3 +:108A30001A1A1A1B1A1A1A1A1A1A1B1B1B1A1A1A92 +:108A40001A1A1B1A1A1B1A1B1B1A1B1C1C1B1A1B7B +:108A50001A1A1B1A1B1B1B1B1A1B1B1B1B1A1A196E +:108A60001A1A1B1B1B1B1B1B1B1B1B1C1B1A1B1A59 +:108A70001A1A1A1B1B1B1B1B1A1C1B1C1C1B1C1A47 +:108A800019191A1A1C1B1A1A1A1B1B1B1A1A1A1943 +:108A90001A1B1B1B1C1B1B1B1B1B1B1B1B1B1B1A27 +:108AA0001A1A1A1B1C1B1B1C1A1C1B1C1C1B1B1B15 +:108AB0001B1C1B1C1C1D1D1D1B1C1D1D1D1C1B1BF5 +:108AC0001C1C1C1D1E1D1D1D1D1E1E1E1E1E1D1DD3 +:108AD0001C1C1D1E1E1D1D1E1F1E201F1E1E1F1EB8 +:108AE0001C1C1D1D1D1E1D1E00000000000000009E +:108AF0000000000000000000000000000000000076 +:108B00000000000000000000000000000000000065 +:108B10000000000000000000000000000000000055 +:108B20000000000000000000000000000000000045 +:108B300005020101F401D00700000000240210002A +:108B400000064A5900000000B0568EEE4423000093 +:108B5000EB1E00000C1F00002D1F00004E1F000028 +:108B60006F1F000000000000000000001B03000059 +:108B70002088410AE62000000000000000000000FC +:108B80000000000000240000202020200502020236 +:108B90005200000000000000010000000000000082 +:108BA000000000000000000000000000D21F3E2076 +:108BB0006A20302105224E21F621F52200B8C30794 +:108BC000D638000000000000000010055805A00580 +:108BD000E80500001040040D0F0B0D0D10000E11E4 +:108BE000A5BB031F7EF80F00130F130F0F430F4396 +:108BF0001B0300000A00000000000000000000004D +:108C0000000000000000000000040000030000005D +:108C10000000000000000000000000000200000052 +:108C20000000000000000000000000000000000044 +:108C3000D21F3E206A20302105224E21F621F52246 +:108C400000B8C307D6380000000000000000000094 +:108C500048009000D80000001040040D0F0B0D0DCF +:108C600010000E11A5BB031F7EF80F00130F130F8A +:108C70000F430F431B0300002088410AE620000039 +:108C800000000000000000000000000000240000C0 +:108C9000272727277572727252000000000000001B +:108CA0006366666666666666660000000000000031 +:108CB00000000000D21F3E206A20302105224E21F4 +:108CC000F621F52200B8C307D638000000000000E6 +:108CD000000010055805A005E80500001040040D2F +:108CE0000F0B0D0D10000E11A5BB031F7EF80F001A +:108CF000130F130F0F430F431B0300008B35F72097 +:108D00000000000000000000000000000000000063 +:108D100000180000202020000000000000000000DB +:108D20000000000011111100000000000000000010 +:108D30000000000000000000D21F3E206A20302109 +:108D400005224E21F621F52200B8C307D6380000CF +:108D5000000000000000000048009000D800000063 +:108D60001040040D0F0B0D0D10000E11A5BB031FBD +:108D70007EF80F00130F130F0F430F431B03000068 +:108D80008B35F7200A000000000000000000000002 +:108D900000000000001C000027272705000000003D +:108DA0000000000000000000333333020000000028 +:108DB000000000000000000000000000D21F3E2064 +:108DC0006A20302105224E21F621F52200B8C30782 +:108DD000D6380000000000000000000048009000AD +:108DE000D80000001040040D0F0B0D0D10000E11E7 +:108DF000A5BB031F7EF80F00130F130F0F430F4384 +:108E00000000000000000000000000000000000062 +:108E10000000000000000000000000000000000052 +:108E20000000000000000000000000000000000042 +:108E30000000000000000000000000000000000032 +:108E40000000000000000000000000000000000022 +:108E50000000000000000000000000000000000012 +:108E60000000000000000000000000000000000002 +:108E700000000000000000000000000000000000F2 +:108E800000000000000000000000000000000000E2 +:108E900000000000000000000000000000000000D2 +:108EA00000000000000000000000000000000000C2 +:108EB00000000000000000000000000000000000B2 +:108EC00000000000000000000000000000000000A2 +:108ED0000000000000000000000000000000000092 +:108EE0000000000000000000000000000000000082 +:108EF0000000000000000000000000000000000072 +:108F0000000000000000000000000000090900014E +:108F10000128000000D8030012000000A51D020077 +:108F200000000000000002020228000000D8030038 +:108F30000F000000A61D0000000000000101020259 +:108F40000328000000D803000E000100A71D000048 +:108F500000000000020202020428000000D8030002 +:108F60000D000200A81D0000000000000303020223 +:108F70000528000000D803000C000300A91D000014 +:108F800000000000040402020628000000D80300CC +:108F90000B000400AA1D00000000000005050202ED +:108FA0000728000000D803000A000500AB1D0000E0 +:108FB00000000000060602020828000000D8030096 +:108FC00009000600AC1D00000000000007070202B7 +:108FD0000928000000D8030008000700AD1D0000AC +:108FE00000000000080802020A28000000D8030060 +:108FF00000000000AE1D0000000000000A09000192 +:109000000028000000D8030092148014A51D000061 +:1090100000000000090900010028000000D803003A +:1090200012000000A51D0200000000000909000157 +:109030000028000000D80300A2009000A61D020036 +:1090400000000000090900010028000000D803000A +:1090500032012001A71D02000000000009090001E3 +:109060000028000000D80300C201B001A81D0200C2 +:1090700000000000090900010028000000D80300DA +:1090800052024002A91D020000000000090900016F +:109090000028000000D80300E202D002AA1D02004E +:1090A00000000000090901000028000000D80300AA +:1090B00080149214000002000F00000005B40500A7 +:1090C0005D4C1B00610000000C0000000500040066 +:1090D0001529000060000000000000000D004000A5 +:1090E000152900001E000000030000000DFC4300D5 +:1090F000FFFE1B001F000000000000000DFC4300ED +:10910000FFFE1B001F000000030000000DB4410023 +:109110005D4C1B001F000000000000000DB441006A +:109120005D4C1B001F0000000F00000001B4050093 +:109130005D4C1B00E10001000C0000000100040078 +:1091400015290000E0000100000000000D004000B3 +:10915000152900001E0000000F00000005FC07009C +:10916000FFFE1B00610000001D1D861D1C1D1D1D36 +:109170001D1D1E1E1D1D1D1E1D1D1D1D1D1D1D1D1C +:109180001D1D1D1D1D1D1D1D1C1D1D1D1E1D1D1D0F +:109190001D1D1C1D1D1D1D1D1D1C1D1E1D1D1D1D00 +:1091A0001E1D1D1D1D1D1C1D1D1D1E1D1D671D1DA4 +:1091B0001D1D1D1D1C1C1D1D1D1D1D1E1D1D1C1EE0 +:1091C0001D1D1D1D1C1D1D1D1D1D1D1D1D1D1D1DD0 +:1091D0001C1D1D1D1D1D1D1D1D1C1B1D1D1D1C1DC4 +:1091E0001C1C1D1E1D1D1D1D1D1D1D1D1D1D1C1DB1 +:1091F0001D1D1D1D1D1D1D1D1D1D1D1D1C1D1D1DA0 +:109200001D1D1D1E1D1D1C1E1D1D1D1D1D1D1D1D8D +:109210001D1D1D1D1D1D1D1D1C1D1D1D1D1D1D1D7F +:109220001D1D1B1D1D1D1C1D1C1C1D1E1D1D1D1D72 +:109230001D1D1D1D1D1D1C1D1D1D1D1D1D1D1D1D5F +:109240001D1D1D1D1C1D1D1D1D1D1D1E1D1D1C1E4E +:109250001D1D1D1D1C1D1D1D1D1D1D1D1D1D1D1D3F +:109260001C1D1D1D1D1D1D1D1D1C1B1D1D1D1C1D33 +:109270001C1C1D1E1D1D1D1D1D1D1D1D1D1D1C1D20 +:109280001D1D1E1D1D1D1D1D1D1D1D1D1C1D1D1D0E +:109290001D1D1D1E1D1D1C1E1D1D1D1D1C1D1D1DFE +:1092A0001D1D1D1D1D1D1D1D1C1D1D1D1E1D1D1DEE +:1092B0001D1D1B1D1D1D1C1D1C1C1D1E1D1D1D1DE2 +:1092C0001D1D1D1D1D1D1C1D1D1D1D1D1D1D1D1DCF +:1092D0001D1D1D1D1D1D1D1D1D1D1E1E1D1D1C1DBD +:1092E0001D1D1D1D1C1D1D1D1D1D1D1D1D1D1D1DAF +:1092F0001C1D1D1D1D1D1D1D1D1D1B1D1D1D1C1DA2 +:109300001C1C1D1E1D1D1D1D1D1C1D1D1D1C1C1D91 +:109310001D1D1E1D1D1D1D1D1D1D1D1D1D1D1D1E7B +:109320001D1D1E1E1D1D1C1E1D1D1D1D1C1D1D1D6C +:109330001D1D1D1D1D1D1D1D1C1D1D1D1D1D1D1D5E +:109340001D1D1B1D1D1D1C1D1C1C1D1E1D1D1D1D51 +:109350001D1D1D1D1D1D1C1D1D1D1E1D1D1D1D1D3D +:109360001E1D1D1D1D1D1D1E1E1D1E1E1E1D1C1E27 +:109370001E1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1C +:109380001D1D1D1D1E1D1D1D1D1D1C1D1D1D1D1D0D +:109390001D1C1D1E1D1D1D1D1D1D1D1D1D1D1D1DFD +:1093A0001D1D1E1D1D1D1E1D0000000000000000D3 +:1093B00000000000000000000000000000000000AD +:1093C000000000000000000000000000000000009D +:1093D000000000000000000000000000000000008D +:1093E000000000000000000000000000000000007D +:1093F000323232323232323232323232323232324D +:10940000323232323232323232323232323232323C +:10941000323232323232323232323232323232322C +:10942000323232323232323232323232323232321C +:10943000323232323232323235358B35353534359F +:1094400035353536353533363535353533353535CE +:1094500035353535353535353434353535353535BE +:1094600033343335333434353333353634353535B9 +:10947000353535363333353633353635339F353735 +:10948000B66DB66DB605B60500000000B66DB66DDA +:10949000B60CB60C00000000B66DB66D960D960DBC +:1094A00000000000B66DB66DB20DB20D00000000F8 +:1094B000B62DB62DB60DB60D00000000B665B6652A +:1094C000B60DB60D00000000B66CB66CB60DB60D4C +:1094D00000000000966D966DB60DB60D0000000000 +:1094E000B26DB26DB60DB60D00000000922492244C +:1094F000920492040000000001100000000000002F +:1095000000000000FFFF3DDB38D4FC020200FF003A +:109510006C768A94DB060000040C0000A003570060 +:1095200036E60802010000003E03E600477EEC1428 +:10953000FFFF00801CC40C570380BBBB804422008B +:109540006415641588398A3935003500011000002A +:109550000000000000000000FFFF3DDB38D4FC02EB +:109560000200FF006C768A94DB060000040C000009 +:10957000A003570036E60802410002003E03E60061 +:10958000477EEC14FFFF00801CC40C17E38EBBBBAE +:10959000805522006415641588398A3935003500F4 +:1095A00001040000000000000000000000000000B6 +:1095B000000000020200FF006C768A94DB060000C7 +:1095C000040C0000B803570036EC0802010000004C +:1095D0005603EC00477EEC14FFFF00801C040C5780 +:1095E0000380BBBB804522006415641588398A3925 +:1095F000350035008304020001020304E0EC37FB70 +:10960000528BE4C5CF0304021E06AA036C768A942B +:10961000DB060000014500008C0E000000EC080293 +:10962000410002000000EC00477EEC14FFFF0080C8 +:109630001C5C11970080BBBB0057220064D164D131 +:1096400088198A19350035008304020001010101DF +:10965000E0EC37FB528BE4C5CF0304020206AA00FC +:109660006C768A94DB060000014500008C0E000039 +:1096700000EC0802410002000000EC00437D531A98 +:10968000FFFF00801C5C11BF0080BBBB00462200B6 +:1096900064D164D188398A393500350083040200E9 +:1096A00002020202E0EC37FB528BE4C5CF03040256 +:1096B0000206AA006C768A94DB06000001450000D1 +:1096C0008C0E000000EC0802410002000000EC00DB +:1096D000A87D6018FFFF00801C5C11BF0080BBBB31 +:1096E0000046220064D164D188398A3935003500BA +:1096F0008304020003030303E0EC37FB528BE4C551 +:10970000CF0304020206AA006C768A94DB060000EE +:10971000014500008C0E000000EC08024100020030 +:109720000000EC006C7E0614FFFF00801C5C11BF83 +:109730000080BBBB0046220064D164D188398A39DD +:10974000350035008304020004040404E0EC37FB18 +:10975000528BE4C5CF0304020206AA006C768A94F9 +:10976000DB060000014500008C0E000000EC080242 +:10977000410002000000EC00ED7E8610FFFF00803B +:109780001C5C11BF0080BBBB0046220064D164D1C9 +:1097900088398A393500350000005D3F0000DA471E +:1097A000C0CED0C716219CD1548694083C0E0F061B +:1097B00079CACDFCD820EF99FACECFC5FD962E51AF +:1097C0005361DF9F3B0F0F04F43CFA883C803CD48C +:1097D000390F0E032494600227A090022AACC00225 +:1097E0002DB8F00230C4200333D05003124C400196 +:1097F000155870011864A0011B70D0011E7C000276 +:1098000021883002124C4001155870011864A001E3 +:109810001B70D0011E7C0002218830020004200051 +:1098200003105000061C80000928B0000C34E00032 +:109830000F40100120C10414508105178041061A01 +:10984000B001071DE0C1072010820823004000027C +:109850003000010560C001089080020BC040030E7B +:10986000F000041120C00004508001078040020A6B +:10987000B000030DE0C00310108104134041051631 +:1098800070010619A0C1061CD081071F00420822E2 +:1098900030020001004000023000010560C00108F4 +:1098A0009080020BC040030EF000041120C104148C +:1098B000508105178041061AB001071DE0C107203D +:1098C000108208237796392541BED8210BE6771EF2 +:1098D000D50D171B9F35B617695D55143385F410E8 +:1098E000FDAC930DC7D4320A91FCD1065B24710301 +:1098F000254C100085CE19264FF6B822191E581F88 +:10990000E345F71BAD6D96187795351541BDD4111C +:109910000BE5730ED50C130B9F34B207695C510431 +:109920003384F000789A492542C2E8210CEA871E68 +:10993000D611271BA039C6176A6165143489041132 +:10994000FEB0A30DC8D8420A9200E2065C2881034B +:109950002650200084CA09264EF2A822181A481F51 +:10996000E241E71BAC6986187691251540B9C41110 +:109970000AE1630ED408030B9E30A2076858410425 +:109980003280E000799E592543C6F8210DEE971EDE +:10999000D715371BA13DD6176B657514358D14117E +:1099A000FFB4B30DC9DC520A9304F2065D2C910397 +:1099B0002754300083C6F9E54DEE98E21716381F9C +:1099C000E13DD71BAB6576D8758D15153FB5B41144 +:1099D00009DD530ED304F30A9D2C9207675431041A +:1099E000317CD0007AA2692544CA08220EF2A71E53 +:1099F000D819471BA241E6176C69851436912411CA +:109A000000B9C30DCAE0620A940802075E30A103E0 +:109A10002858400082C2E9254CEA88221612281FE5 +:109A2000E039C71BAA616618748905153EB1A411F7 +:109A300008D9430ED200E30A9C288207665021040D +:109A40003078C0007BA6792545CE18220FF6B71EC8 +:109A5000D91D571BA345F6176D6D95143795341115 +:109A600001BDD30DCBE4720A950C12075F34B1032C +:109A7000295C500081BED9254BE67822150E181FAF +:109A8000DF35B71BA95D56187385F5143DAD9411EC +:109A900007D5330ED1FCD20A9B247207654C110402 +:109AA0002F74B0007CAA892546D2282210FAC71E3E +:109AB000DA21671BA44906186E71A5143899441160 +:109AC00002C1E30DCCE8820A961022076038C10378 +:109AD0002A60600080BAC9254AE26822140A081F79 +:109AE000DE31A71BA85946187281E5143CA98411E0 +:109AF00006D1230ED0F8C20A9A20620764480104F6 +:109B00002E70A0007DAE992547D6382211FED71EB3 +:109B1000DB25771BA54D16186F75B514399D5411AB +:109B200003C5F30DCDEC920A97143207613CD103C3 +:109B30002B6470007FB6B92549DE58221306F81E43 +:109B4000DD2D971BA7553618717DD5143BA57411D3 +:109B500005CD130ECFF4B20A991C52076344F103EA +:109B60002D6C90007EB2A92548DA48221202E81E28 +:109B7000DC29871BA65126187079C5143AA16411F7 +:109B800004C9030ECEF0A20A981842076240E1030E +:109B90002C688000000000000000000000000000B1 +:109BA00000000000000000000000000000000000B5 +:109BB00000000000000000000000000000000000A5 +:109BC0000000000000000000000000000000000095 +:109BD0000000000000000000000000000000000085 +:109BE0000000000000000000000000000000000075 +:109BF0000000000000000000000000000000000065 +:109C00000000000000000000000000000000000054 +:109C10000000000000000000000000000000000044 +:109C20000000000000000000000000000000000034 +:109C30000000000000000000000000000000000024 +:109C40000000000000000000000000000000000014 +:109C50000000000000000000000000000000000004 +:109C600000000000000000000000000000000000F4 +:109C700000000000000000000000000000000000E4 +:109C800000000000000000000000000000000000D4 +:109C900000000000000000000000000000000000C4 +:109CA00000000000000000000000000000000000B4 +:109CB00000000000000000000000000000000000A4 +:109CC0000000000000000000000000000000000094 +:109CD0000000000000000000000000000000000084 +:109CE0000000000000000000000000000000000074 +:109CF0000000000000000000000000000000000064 +:109D00000000000000000000000000000000000053 +:109D10000000000000000000000000000000000043 +:109D20000000000000000000000000000000000033 +:109D30000000000000000000000000000000000023 +:109D40000000000000000000000000000000000013 +:109D50000000000000000000000000000000000003 +:109D600000000000000000000000000000000000F3 +:109D700000000000000000000000000000000000E3 +:109D800000000000000000000000000000000000D3 +:109D900000000000000000000000000000000000C3 +:109DA00000000000000000000000000000000000B3 +:109DB00000000000000000000000000000000000A3 +:109DC0000000000000000000000000000000000093 +:109DD0000000000000000000000000000000000083 +:109DE0000000000000000000000000000000000073 +:109DF0000000000000000000000000000000000063 +:109E00000000000000000000000000000000000052 +:109E10000000000000000000000000000000000042 +:109E20000000000000000000000000000000000032 +:109E30000000000000000000000000000000000022 +:109E40000000000000000000000000000000000012 +:109E50000000000000000000000000000000000002 +:109E600000000000000000000000000000000000F2 +:109E700000000000000000000000000000000000E2 +:109E800000000000000000000000000000000000D2 +:109E900000000000000000000000000000000000C2 +:109EA00000000000000000000000000000000000B2 +:109EB00000000000000000000000000000000000A2 +:109EC0000000000000000000000000000000000092 +:109ED0000000000000000000000000000000000082 +:109EE0000000000000000000000000000000000072 +:109EF0000000000000000000000000000000000062 +:109F00000000000000000000000000000000000051 +:109F10000000000000000000000000000000000041 +:109F20000000000000000000000000000000000031 +:109F300008F71024380460090E0A00010101081016 +:109F4000240040046C090000000C00000000000028 +:109F500000004A590000000000000000000801094C +:109F60000001444340020000282221008004000038 +:109F700080040000800400008004000080040000D1 +:109F800080040000800400008004000000FA030048 +:109F900080040000800400008004000000FA030038 +:109FA0008004000080040000800400000000000025 +:109FB000000101000000000000000000000000009F +:109FC000000000000000000000000101010101008C +:109FD0000001010101010101010100010000010076 +:109FE00001000000000000000F0000000107010355 +:109FF00002030A00320A400000003200370000006D +:10A000000000000000000000000000000000000050 +:10A010000000000000000000C800C8009600C80052 +:10A020000707800080000505000000000000000018 +:10A0300007010000DBFF00004100F1FF10001400E9 +:10A04000F9FFC4FFFF7FFF7FFF7FFF7F96002C019A +:10A0500096003C000A04CECE3232280500000000F3 +:10A0600000070D0000240D0000000010242424240B +:10A0700024242424242424242424242424240000E8 +:10A0800000000000000000000000000000000000D0 +:10A090000A05000A0000000020010014111400004D +:10A0A00000000000000000000000000000000000B0 +:10A0B000000000000F23283C465000006E696664D3 +:10A0C0005050505008000000000000000F23283CB2 +:10A0D000465000006E696664505050500F141E28A0 +:10A0E000000000000A0A0A0A0A0A0A0A0F1E32467B +:10A0F00000000000645F553C3C3C3C3C000000001C +:10A1000008081A00A000EAFF1E009D008300100E40 +:10A1100000000000001000003C0032009001280008 +:10A120000F000F001C023D011C02740400003704E4 +:10A1300000005F09F4010000370400005F093214D9 +:10A14000021E1E3202009B00280028007700C00378 +:10A150007700E8080000000040043000050001001E +:10A1600007000000410028012402200309043F04E5 +:10A1700000000000000000000000000000000000DF +:10A1800000000000000000000000000000000000CF +:10A1900000000000000000000000000000000000BF +:10A1A00000000000000000000000000000000000AF +:10A1B000000000000000000000000000000000009F +:10A1C000000000000000000000000000000000008F +:10A1D000000000000000000000000000000000007F +:10A1E000000000000000000000000000000000006F +:10A1F000000000000000000000000000000000005F +:10A20000000000000000000000000000000000004E +:10A21000000000000000000000000000000000003E +:10A22000000000000000000000006C093000050084 +:10A230000100070000003B006E02BC040B073F0951 +:10A240006B0900000000000000000000000000009A +:10A2500000000000000000000000000000000000FE +:10A2600000000000000000000000000000000000EE +:10A2700000000000000000000000000000000000DE +:10A2800000000000000000000000000000000000CE +:10A2900000000000000000000000000000000000BE +:10A2A00000000000000000000000000000000000AE +:10A2B000000000000000000000000000000000009E +:10A2C000000000000000000000000000000000008E +:10A2D000000000000000000000000000000000007E +:10A2E000000000000000000000000000000000006E +:10A2F000000000000000000000000000000000005E +:10A3000002020500F16C0000409C000000F91500FD +:10A3100029B1010010270000C4090000010101015A +:10A32000010101010101014B0F0055000000000077 +:10A33000020101010101010101010100F16C0000B4 +:10A340000200000084DE0100000000000F0F0A0A76 +:10A3500028000000000000000F0F1414010101018B +:10A36000010140003200E8030F0008000500E10091 +:10A3700000001E288C00B40019006400640028004E +:10A380007800000000000000B4007800E8034006F8 +:10A3900000000001410100000000000068010D0DF7 +:10A3A0000A092D0019006400140064002C016400E7 +:10A3B0002C010F02E8E8F800F8000804190000007A +:10A3C000A500B300C300D400E700FA000F01260186 +:10A3D0003E01570172018F01AE01CF01F10116025A +:10A3E0003C0265029002BD02ED021E035203890386 +:10A3F000C203FE033C047C04BF0405054D0598051B +:10A40000E50535068706DB0632078A07E5074208B9 +:10A41000A10801096309C7092C0A920AF90A600B0D +:10A42000C80B310C9A0C020D6B0DD20D390E9F0E1C +:10A43000040F670FC80F27108410DE103511891123 +:10A44000DA1128127112B712F81235136D13A01316 +:10A45000CF13F8131C143B145414681476147E1490 +:10A460008114DB00ED0000011401290140015801B5 +:10A4700072018D01A901C801E8010A022D025202F0 +:10A480007A02A302CE02FB022A035C038F03C503F8 +:10A49000FD0336047304B104F10434057805BF05E7 +:10A4A00008065306A006EF063F079207E6073B089B +:10A4B0009308EB084509A009FC09580AB60A140BD1 +:10A4C000720BD10B2F0C8D0CEB0C490DA50D010E51 +:10A4D0005B0EB40E0C0F610FB50F06105510A110D6 +:10A4E000EA1031117411B411F01128125D128D129D +:10A4F000B912E112051324133E135413651371139B +:10A5000078137B136A00750081008E009D00AC00FB +:10A51000BD00CF00E200F7000D01260140015C0103 +:10A5200079019901BC01E001060230025B02890257 +:10A53000BA02EE0224035D039A03D9031B046004EC +:10A54000A904F40443059505E90541069C06FA06AD +:10A550005B07BE0724088D08F8086509D409450A79 +:10A56000B80A2D0BA20B190C900C080D800DF80DDC +:10A570006F0EE60E5C0FD00F4210B31021118C113C +:10A58000F4115912BA1217137013C41313145D1473 +:10A59000A114E01418154B1577159C15BB15D4158F +:10A5A000E515EF15F315A500B300C300D400E700CF +:10A5B000FA000F0126013E01570172018F01AE0121 +:10A5C000CF01F10116023C0265029002BD02ED02CC +:10A5D0001E0352038903C203FE033C047C04BF0430 +:10A5E00005054D059805E50535068706DB063207A6 +:10A5F0008A07E5074208A10801096309C7092C0A6F +:10A60000920AF90A600BC80B310C9A0C020D6B0D03 +:10A61000D20D390E9F0E040F670FC80F271084103C +:10A62000DE1035118911DA1128127112B712F812E1 +:10A6300035136D13A013CF13F8131C143B145414CB +:10A64000681476147E148114550055004B004700A1 +:10A650000000000055008700DC0014000500000029 +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000008000000B2 +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A93000050201010000000000000000240104776E +:10A940000002335900000000000000000000000079 +:10A950006726000088260000A92600001A030000D0 +:10A96000410C520C07010000000000000000000034 +:10A97000000000000020000031313131252020206E +:10A980002020000000000000000000000000000087 +:10A99000000000000000000000000000CA2642275E +:10A9A00066272C28492968283A29392A00B8C3077C +:10A9B0007E17000000000000000010055805A005EB +:10A9C000E80500001040040C0E0B0C0C10000E10DB +:10A9D000A5BA031F7CC60F00100D100D0D410D41CF +:10A9E0001A0300008B35F720510200000000000020 +:10A9F00000000000000000000020000020202020B7 +:10AA0000252020202020000000000000111111113D +:10AA10001100000000000000000000000000000025 +:10AA2000CA26422766272C28492968283A29392A24 +:10AA300000B8843A7E1700000000000000001005F6 +:10AA40005805A005E80500001040040C0E0B0C0C86 +:10AA500090000E10A5BB831FFCC90F00100D100D38 +:10AA60000D410D411A0300008B35F72051C9090033 +:10AA700000000000000000000000000000280000AE +:10AA80002727272725272727272700000000000042 +:10AA900066666656660000000000000000000000C8 +:10AAA00000000000CA26422766272C28492968286A +:10AAB0003A29392A00B8C3077E17000000000000B9 +:10AAC000000010055805A005E80500001040040C22 +:10AAD0000E0B0C0C90000E10A5BB831FFCC90F00C1 +:10AAE000100D100D0D410D4100000000090901007D +:10AAF0000028000000A8030000000000A51D0200BF +:10AB000000000000000002020028000080AA0300EC +:10AB100008000000A61D0000000000000101020264 +:10AB20000028000080AA030009000100A71D000002 +:10AB300000000000020202020028000080AA0300B8 +:10AB40000A000200A81D000000000000030302022A +:10AB50000028000080AA03000B000300A91D0000CC +:10AB600000000000040402020028000080AA030084 +:10AB70000C000400AA1D00000000000005050202F0 +:10AB80000028000080AA03000D000500AB1D000096 +:10AB900000000000060602020028000080AA030050 +:10ABA0000E000600AC1D00000000000007070202B6 +:10ABB0000028000080AA03000F000700AD1D000060 +:10ABC00000000000080803120028000080AA03000B +:10ABD00000000000AE1D000000000000091301008D +:10ABE0000028000000A8030000000000A51D0200CE +:10ABF00000000000000A02020028000080A80300F4 +:10AC000008000000A61D000000000000010B020269 +:10AC10000028000080A8030009000100A71D000013 +:10AC200000000000020C02020028000080A80300BF +:10AC30000A000200A81D000000000000030D02022F +:10AC40000028000080A803000B000300A91D0000DD +:10AC500000000000040E02020028000080A803008B +:10AC60000C000400AA1D000000000000050F0202F5 +:10AC70000028000080A803000D000500AB1D0000A7 +:10AC800000000000061002020028000080A8030057 +:10AC90000E000600AC1D00000000000007110202BB +:10ACA0000028000080A803000F000700AD1D000071 +:10ACB00000000000081202020028000080A8030023 +:10ACC00000000000AE1D00000F000000016C041425 +:10ACD00087F21B00610000000F000000016C0414EB +:10ACE00030441B00610000000000000029007014C7 +:10ACF00064C700001E00000000000000290070145E +:10AD0000152900001E00000000000000296C7014CE +:10AD100030441B001F00000003000000296C701469 +:10AD200030441B001F00000000000000296C70145C +:10AD300030441B001F0000000F000000016C0414D1 +:10AD400030441B00E10001000C000000010004146D +:10AD500015290000E00001000000000000000000D4 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF0000000000000000000000000000000000051 +:10B000000000000000000000000000000000000040 +:10B010000000000000000000000000000000000030 +:10B020000000000000000000000000000000000020 +:10B030000000000000000000000000000000000010 +:10B040000000000000000000000000000000000000 +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B07000144924492409240500000000A448244957 +:10B080002409A408000000002445244924091409C7 +:10B09000000000002429244924092209000000009E +:10B0A00024492429220924090000000024492445B8 +:10B0B00014092409000000002449A448A408240914 +:10B0C0000000000024491449240524090000000060 +:10B0D00024492249240524090000000092249224D6 +:10B0E0009204920400000000966DB66DB60DB60590 +:10B0F00000000000B66CB66DB60DB60C0000000086 +:10B10000B665B66DB60D960D00000000B62DB66D95 +:10B11000B60DB20D00000000B66DB62DB20DB60D25 +:10B1200000000000B66DB665960DB60D000000007B +:10B13000B66DB66CB60CB60D00000000B66D966D1F +:10B14000B605B60D00000000B66DB26DB605B60DC1 +:10B150000000000092249224920492040000000057 +:10B1600001280000000000000000000000000000B6 +:10B17000000000020206FF006C768A94DB060000E5 +:10B180000106000041015700363C090201000000A1 +:10B19000E1003C01477EEC14FFFF00801C7C0F5750 +:10B1A0000380BBBB8E5C22006401640188398A394C +:10B1B0000000000001280000000000000000000066 +:10B1C00000000000000000020206FF006C768A9476 +:10B1D000DB06000001060000F100570036EC080213 +:10B1E000010000009100EC00477EEC14FFFF00809E +:10B1F0001C040C570380ABAA804422006411641124 +:10B2000088398A3905000500012800000000000087 +:10B210000000000000000000000000020206FF0025 +:10B220006C768A94DB06000001060000610057007E +:10B23000365C08020100000001005C00477EEC144F +:10B24000FFFF00801C240C570380ABAA804422001F +:10B250006411641188398A3905000500012800004D +:10B2600000000000000000000000000000000002DC +:10B270000200FF006C768A94DB06000001060000E5 +:10B28000F100570036EC0802410002009100EC008A +:10B29000477EEC14FFFF00801CC40C17E38EBBBB81 +:10B2A000805522006411641188398A39050005002F +:10B2B0000104000000000000000000000000000089 +:10B2C000000000020200FF006C768A94DB0600009A +:10B2D000040C0000B803570036EC0802010000001F +:10B2E0005803EC00477EEC14FFFF00801CE00C5775 +:10B2F0000380BBBB804522006411641188398A3900 +:10B30000050005009404020001020304D6F042FC8B +:10B310001C6005AFCF0304021E0600036C768A94FE +:10B32000DB06000001C50000D20F000000EC08029F +:10B33000410002000000EC00477EEC14FFFF00809B +:10B340001CC411170080BBBB00572200641164119C +:10B3500088198A1905000500940402000101010101 +:10B36000D6F042FC1C6005AFCF03040202060000C9 +:10B370006C768A94DB06000001C50000D20F000045 +:10B3800000EC0802410002000000EC007278512B32 +:10B39000FFFF00801CC4113F0080BBBB00462200A1 +:10B3A0006411641188398A3905000500940402008B +:10B3B00002020202D6F042FC1C6005AFCF03040279 +:10B3C000020600006C768A94DB06000001C50000CE +:10B3D000D20F000000EC0802410002000000EC0067 +:10B3E000BB7BC520FFFF00801CC4113F0080BBBB9E +:10B3F000004622006411641188398A39050005006D +:10B400009404020003030303D6F042FC1C6005AF62 +:10B41000CF030402020600006C768A94DB0600006B +:10B4200001C50000D20F000000EC0802410002003C +:10B430000000EC00197EFC15FFFF00801CC4113FCA +:10B440000080BBBB004622006411641188398A3930 +:10B45000050005009404020004040404D6F042FC34 +:10B460001C6005AFCF030402020600006C768A94CC +:10B47000DB06000001C50000D20F000000EC08024E +:10B48000410002000000EC00867F080BFFFF0080F7 +:10B490001CC4113F0080BBBB004622006411641134 +:10B4A00088398A390500050000005D3F0000DA4751 +:10B4B000C0CED0C7FFFF47020000A1503F0D3009AA +:10B4C000FFFF244B00009F30FFCEF0C7FFFFDF3BA4 +:10B4D000000047E43F0F3004FFFFABCE0000C5790A +:10B4E0003F0F300220C208001080000340400106D8 +:10B4F00070000209A0C0020CD080030F00410412AA +:10B500003001051560C105189081061BC041071E5A +:10B51000F001082120C00004508001078040020A89 +:10B52000B000030DE0C00310108104134041051664 +:10B5300070010619A0C1061CD081071F0042082215 +:10B540003002000120C10414508105178041061A01 +:10B55000B001071DE0C1072010820823004000024F +:10B560003000010560C001089080020BC040030E4E +:10B57000F000041100486027644A09242E72A820B4 +:10B58000F899471DC2C1E6198CE985165611251395 +:10B590002039C40FEA60630CB48802097EB0A105AB +:10B5A00048D8400286D2292650FAC8221A22681F9B +:10B5B000E449071CAE71A6187899451542C1E411FB +:10B5C0000CE9830ED610230BA038C2076A60610411 +:10B5D000348800017796392541BED8210BE6771EC5 +:10B5E000D50D171B9F35B617695D55143385F410BB +:10B5F000FDAC930DC7D4320A91FCD1065B247103D4 +:10B60000254C100085CE19264FF6B822191E581F5A +:10B61000E345F71BAD6D96187795351541BDD411EF +:10B620000BE5730ED50C130B9F34B207695C510404 +:10B630003384F000789A492542C2E8210CEA871E3B +:10B64000D611271BA039C6176A6165143489041105 +:10B65000FEB0A30DC8D8420A9200E2065C2881031E +:10B660002650200084CA09264EF2A822181A481F24 +:10B67000E241E71BAC6986187691251540B9C411E3 +:10B680000AE1630ED408030B9E30A20768584104F8 +:10B690003280E000799E592543C6F8210DEE971EB1 +:10B6A000D715371BA13DD6176B657514358D141151 +:10B6B000FFB4B30DC9DC520A9304F2065D2C91036A +:10B6C0002754300083C6F9E54DEE98E21716381F6F +:10B6D000E13DD71BAB6576D8758D15153FB5B41117 +:10B6E00009DD530ED304F30A9D2C920767543104ED +:10B6F000317CD0007AA2692544CA08220EF2A71E26 +:10B70000D819471BA241E6176C698514369124119C +:10B7100000B9C30DCAE0620A940802075E30A103B3 +:10B720002858400082C2E9254CEA88221612281FB8 +:10B73000E039C71BAA616618748905153EB1A411CA +:10B7400008D9430ED200E30A9C28820766502104E0 +:10B750003078C0007BA6792545CE18220FF6B71E9B +:10B76000D91D571BA345F6176D6D951437953411E8 +:10B7700001BDD30DCBE4720A950C12075F34B103FF +:10B78000295C500081BED9254BE67822150E181F82 +:10B79000DF35B71BA95D56187385F5143DAD9411BF +:10B7A00007D5330ED1FCD20A9B247207654C1104D5 +:10B7B0002F74B0007CAA892546D2282210FAC71E11 +:10B7C000DA21671BA44906186E71A5143899441133 +:10B7D00002C1E30DCCE8820A961022076038C1034B +:10B7E0002A60600080BAC9254AE26822140A081F4C +:10B7F000DE31A71BA85946187281E5143CA98411B3 +:10B8000006D1230ED0F8C20A9A20620764480104C8 +:10B810002E70A0007DAE992547D6382211FED71E86 +:10B82000DB25771BA54D16186F75B514399D54117E +:10B8300003C5F30DCDEC920A97143207613CD10396 +:10B840002B6470007FB6B92549DE58221306F81E16 +:10B85000DD2D971BA7553618717DD5143BA57411A6 +:10B8600005CD130ECFF4B20A991C52076344F103BD +:10B870002D6C90007EB2A92548DA48221202E81EFB +:10B88000DC29871BA65126187079C5143AA16411CA +:10B8900004C9030ECEF0A20A981842076240E103E1 +:10B8A0002C68800000000000000000000000000084 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C24000402F0100C40B000040300100000000003E +:10C25000402F010080090000043C010000000000A4 +:10C26000020000000000000001000000FFFFFFFFCF +:10C2700004000F00070000000000000F0100000094 +:10C28000AA000000FFFFFFFF4040404040409001F7 +:10C290009001900190019001900190019001900116 +:10C2A00010001E00320023003200C70032003300AD +:10C2B0003C003C00900190019001900190019001A0 +:10C2C0000200201C01000000503D02000C3D020055 +:10C2D000503D0200103D0200AA00AA0002000F001B +:10C2E0001E000F003C0014007800780000000000E1 +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F0000008F71024380460090E0A000101010810F5 +:10F01000240040046C090000000C00000000000007 +:10F0200000004A590000000000000000000801092B +:10F030000001444340020000282221008004000017 +:10F0400080040000800400008004000080040000B0 +:10F0500080040000800400008004000000FA030027 +:10F0600080040000800400008004000000FA030017 +:10F070008004000080040000800400000000000004 +:10F08000000101000000000000000000000000007E +:10F09000000000000000000000000101010101006B +:10F0A0000001010101010101010100010000010055 +:10F0B00001000000000000000F0000000107010334 +:10F0C00002030A00320A400000003200370000004C +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000C800C8009600C80032 +:10F0F00007078000800005050000000000000000F8 +:10F1000007010000DBFF00004100F1FF10001400C8 +:10F11000F9FFC4FFFF7FFF7FFF7FFF7F96002C0179 +:10F1200096003C000A04CECE3232280500000000D2 +:10F1300000070D0000240D000000001024242424EA +:10F1400024242424242424242424242424240000C7 +:10F1500000000000000000000000000000000000AF +:10F160000A05000A0000000020010014111400002C +:10F17000000000000000000000000000000000008F +:10F18000000000000F23283C465000006E696664B2 +:10F190005050505008000000000000000F23283C91 +:10F1A000465000006E696664505050500F141E287F +:10F1B000000000000A0A0A0A0A0A0A0A0F1E32465A +:10F1C00000000000645F553C3C3C3C3C00000000FB +:10F1D00008081A00A000EAFF1E009D008300100E20 +:10F1E00000000000001000003C00320090012800E8 +:10F1F0000F000F001C023D011C02740400003704C4 +:10F2000000005F09F4010000370400005F093214B8 +:10F21000021E1E3202009B00280028007700C00357 +:10F220007700E808000000004004300005000100FD +:10F2300007000000410028012402200309043F04C4 +:10F2400000000000000000000000000000000000BE +:10F2500000000000000000000000000000000000AE +:10F26000000000000000000000000000000000009E +:10F27000000000000000000000000000000000008E +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F000000000000000000000006C093000050064 +:10F300000100070000003B006E02BC040B073F0930 +:10F310006B09000000000000000000000000000079 +:10F3200000000000000000000000000000000000DD +:10F3300000000000000000000000000000000000CD +:10F3400000000000000000000000000000000000BD +:10F3500000000000000000000000000000000000AD +:10F36000000000000000000000000000000000009D +:10F37000000000000000000000000000000000008D +:10F38000000000000000000000000000000000007D +:10F39000000000000000000000000000000000006D +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D00002020500F16C0000409C000000F91500DD +:10F3E00029B1010010270000C4090000010101013A +:10F3F000010101010101014B0F0055000000000057 +:10F40000020101010101010101010100F16C000093 +:10F410000200000084DE0100000000000F0F0A0A55 +:10F4200028000000000000000F0F1414010101016A +:10F43000010140003200E8030F0008000500E10070 +:10F4400000001E288C00B40019006400640028002D +:10F450007800000000000000B4007800E8034006D7 +:10F4600000000001410100000000000068010D0DD6 +:10F470000A092D0019006400140064002C016400C6 +:10F480002C010F02E8E8F800F80008041900000059 +:10F49000A500B300C300D400E700FA000F01260165 +:10F4A0003E01570172018F01AE01CF01F101160239 +:10F4B0003C0265029002BD02ED021E035203890365 +:10F4C000C203FE033C047C04BF0405054D059805FA +:10F4D000E50535068706DB0632078A07E507420899 +:10F4E000A10801096309C7092C0A920AF90A600BED +:10F4F000C80B310C9A0C020D6B0DD20D390E9F0EFC +:10F50000040F670FC80F27108410DE103511891102 +:10F51000DA1128127112B712F81235136D13A013F5 +:10F52000CF13F8131C143B145414681476147E146F +:10F530008114DB00ED000001140129014001580194 +:10F5400072018D01A901C801E8010A022D025202CF +:10F550007A02A302CE02FB022A035C038F03C503D7 +:10F56000FD0336047304B104F10434057805BF05C6 +:10F5700008065306A006EF063F079207E6073B087A +:10F580009308EB084509A009FC09580AB60A140BB0 +:10F59000720BD10B2F0C8D0CEB0C490DA50D010E30 +:10F5A0005B0EB40E0C0F610FB50F06105510A110B5 +:10F5B000EA1031117411B411F01128125D128D127C +:10F5C000B912E112051324133E135413651371137A +:10F5D00078137B136A00750081008E009D00AC00DB +:10F5E000BD00CF00E200F7000D01260140015C01E3 +:10F5F00079019901BC01E001060230025B02890237 +:10F60000BA02EE0224035D039A03D9031B046004CB +:10F61000A904F40443059505E90541069C06FA068C +:10F620005B07BE0724088D08F8086509D409450A58 +:10F63000B80A2D0BA20B190C900C080D800DF80DBB +:10F640006F0EE60E5C0FD00F4210B31021118C111B +:10F65000F4115912BA1217137013C41313145D1452 +:10F66000A114E01418154B1577159C15BB15D4156E +:10F67000E515EF15F315A500B300C300D400E700AE +:10F68000FA000F0126013E01570172018F01AE0100 +:10F69000CF01F10116023C0265029002BD02ED02AB +:10F6A0001E0352038903C203FE033C047C04BF040F +:10F6B00005054D059805E50535068706DB06320785 +:10F6C0008A07E5074208A10801096309C7092C0A4E +:10F6D000920AF90A600BC80B310C9A0C020D6B0DE3 +:10F6E000D20D390E9F0E040F670FC80F271084101C +:10F6F000DE1035118911DA1128127112B712F812C1 +:10F7000035136D13A013CF13F8131C143B145414AA +:10F71000681476147E148114550055004B00470080 +:10F720000000000055008700DC0014000500000008 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000800000091 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F860000000000000000000000000000000000098 +:10F870000000000000000000000000000000000088 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF000000000000000000000000000004E565409 +:020000022000DC +:1000000066665A4285CB2B43C3F500400C00B740CF +:100010000000000000000000000000000A000000D6 +:1000200000000000000000000000000000000000D0 +:10003000002092000000000020508B01907B020500 +:1000400041525B14810B00000042525B14810B0093 +:10005000000043525B14810B00000046525B148188 +:100060000B00000047525B14810B000000000000F1 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:100100000000000000001101101500002002100185 +:1001100000003003000200008004000300004005DE +:10012000000400005006000000006007000000000E +:1001300070080000000090000000000000100100A6 +:100140000000022000000000030000000000040086 +:100150000000000005000000000006000000000094 +:100160000700000000000800000000000900000077 +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C00000000000000050140000000000000000CB +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:00000001FF diff --git a/firmware/j20s_novatek_ts_fw02.bin.ihex b/firmware/j20s_novatek_ts_fw02.bin.ihex new file mode 100644 index 000000000000..a28fd6ca8e14 --- /dev/null +++ b/firmware/j20s_novatek_ts_fw02.bin.ihex @@ -0,0 +1,8707 @@ +:100000000001000000000000B32E0100008101008B +:1000100040710200EF410000C6F75925E8B4A14B3A +:1000200000000000A000000002000000000000002E +:10003000708F020000000000309F0100BB4FC16CB8 +:10004000707B020000000000308B0100DFD4CD592E +:10005000709902000000000030A90100DFD4CD59E2 +:10006000B42E0100C40B0000B42F0100C9B0EFE5AD +:100070000000020080090000783B010083F88F68CF +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F00040700200FF00000000000000817D898B3D +:10010000480001EA400000094000000940000009E1 +:100110003AFFBFFC3A0FA83C4400000148000190A0 +:100120003AFFBFFC3A0FA83C440000024800018897 +:100130003AFFBFFC3A0FA83C44000003480001808E +:100140003AFFBFFC3A0FA83C440000044800017885 +:100150003AFFBFFC3A0FA83C44000005480001707C +:100160003AFFBFFC3A0FA83C440000064800016873 +:100170003AFFBFFC3A0FA83C44000007480001606A +:10018000480000004000000940000009400000094C +:100190003AFFBCBC3A0F943C440000004800017197 +:1001A0003AFFBCBC3A0F943C440000014800017483 +:1001B0003AFFBCBC3A0F943C440000024800016C7A +:1001C0003AFFBCBC3A0F943C44000003480001597C +:1001D0003AFFBCBC3A0F943C440000044800015C68 +:1001E0003AFFBCBC3A0F943C44000005480001496A +:1001F0003AFFBCBC3A0F943C440000064800014161 +:100200003AFFBCBC3A0F943C440000074800013957 +:100210003AFFBCBC3A0F943C44000008480001314E +:100220003AFFBCBC3A0F943C440000094800012945 +:100230003AFFBCBC3A0F943C4400000A480001213C +:100240003AFFBCBC3A0F943C4400000B4800011933 +:100250003AFFBCBC3A0F943C4400000C480001112A +:100260003AFFBCBC3A0F943C4400000D4800010921 +:100270003AFFBCBC3A0F943C4400000E4800010118 +:100280003AFFBCBC3A0F943C4400000F4800010404 +:100290003AFFBCBC3A0F943C44000010480000FCFC +:1002A0003AFFBCBC3A0F943C44000011480000E9FE +:1002B0003AFFBCBC3A0F943C44000012480000E1F5 +:1002C0003AFFBCBC3A0F943C44000013480000D9EC +:1002D0003AFFBCBC3A0F943C44000014480000DCD8 +:1002E0003AFFBCBC3A0F943C44000015480000D4CF +:1002F0003AFFBCBC3A0F943C44000016480000C1D1 +:100300003AFFBCBC3A0F943C44000017480000B9C7 +:100310003AFFBCBC3A0F943C44000018480000B1BE +:100320003AFFBCBC3A0F943C44000019480000A9B5 +:100330003AFFBCBC3A0F943C4400001A480000A1AC +:100340003AFFBCBC3A0F943C4400001B48000099A3 +:100350003AFFBCBC3A0F943C4400001C480000919A +:100360003AFFBCBC3A0F943C4400001D4800008991 +:100370003AFFBCBC3A0F943C4400001E4800008188 +:100380003AFFBCBC3A0F943C4400001F480000797F +:100390007E0500007E050000F0090000C608000090 +:1003A000C6080000C6080000C6080000C608000015 +:1003B000C6080000C608000000000000E0050000BC +:1003C000E8050000DE0B00006A0C0000F4050000E8 +:1003D000AA0C00007E060000A2060000AA0600008B +:1003E000B2060000BA060000460D0000C20600007A +:1003F000600D0000CA060000EE060000A207000023 +:10040000AE070000FE07000006080000740D0000A3 +:100410008E0D0000A80D000058080000D80D000047 +:10042000A2080000AA080000AC080000B408000000 +:10043000FA0D0000B6080000BE0800006412A40215 +:10044000642204023A1F883C803F442002983821ED +:100450000202643200029ED964320003DD2264028B +:100460000043640000083A1F88046412A403642255 +:1004700004033A0FA8043AFFBFC4640000044420F8 +:1004800002BC38210202DD223A0F94043AFFBC84F8 +:10049000640000046412A402642204023A1F883C2F +:1004A000442002BC38210202643200029ED9643228 +:1004B0000003DD2264020043640000083A1F880440 +:1004C0006412A403642204033A0F94043AFFBC8428 +:1004D000640000044FF2001D3A0FA83C3AFFBFFC35 +:1004E00045D2CA38801F64126402965F9E49C105D6 +:1004F0003CFD4E16480000043CFD4E17E809DD2F78 +:10050000C8073AFFBFC43A0FA8046400000464029D +:100510002402441F3FFFFE0E5800400064022403E3 +:100520006400000845D2CA3845F3000044F005369F +:100530004EF20003DD2F3CFD4E18DD2F640FFFEA65 +:100540003A6F98BC4402B3304462E1CC9AB0842044 +:100550004900940E440FFFAAAE313A6F9884DD9E95 +:100560003BFFFE3CEFFC84003C0FFABD3C0FFAC59C +:100570003C0FFAC93C0FFACD3C0FFAD63C0FFADA21 +:100580003C0FFAC33C0FFACE3C0FFACA3C0FFAD329 +:100590003C0FFACB3C0FFAC73C0FFAC43C0FFABF32 +:1005A0003C0FFAD83C0FFADC3C0FFAD13C0FFAD2E0 +:1005B0003C0FFACF3C0FFABB3C0FFAD93C0FFACCF8 +:1005C0003C0FFAC23C0FFABE3C0FFABC3C0FFAC11A +:1005D0003C0FFADB3C0FFAD03C0FFAD73C0FFAC8BD +:1005E0003C0FFAC064030003640304036412240292 +:1005F0009646C103640300034400400064022403E0 +:10060000641200028419FE0E6402000364000008F4 +:10061000640304024616F7845010807CFE0F6403C6 +:100620000403640200025800000164020003EC04A9 +:100630003BFFFE04DD9E4403F04B843FAE40440389 +:10064000F0EDA6405A1801048420AE404413F0DABD +:10065000A608540000F0AE088404640304034403B5 +:10066000F0498425AE404403F04A44100053AE40A4 +:10067000640304025800400064030403DD9EDD9E11 +:100680004443F114B46492784031E008FE1FB6048C +:100690004403F13844300055AC404403F13A84201F +:1006A000AE404403F1048421B6404403F1364423B0 +:1006B000F04AAE404413F134A608960EC803AED0FB +:1006C000D5FC4403F134A6009606DD9E924284A038 +:1006D000D207383016023830960A8CA1D5FADD9E42 +:1006E00084013C0FFABDDD9E3C0DFAC58C013C0F28 +:1006F000FAC5DD9E3A6F9ABCEFFC4900046AC0144B +:1007000084004900046A4900047B5A08010E3C0F2A +:10071000FAC64412B3AC3C0DFA974422B50C3C3DEA +:10072000FAA149008A7B4900044BC00784013C0FB1 +:10073000FAD5840049000448490004A0C01484008C +:10074000490004A04900045C5A08010E3C0FFABCA1 +:100750004412B3AC3C0DFA974422B50C3C3DFAA1CF +:1007600049008A5C49000481C00784004900048173 +:1007700084013C0FFABEEC043A6F9A84DD9E84013A +:100780003C0FFADA4403F082A600C00B3BFFFCBC2E +:10079000EFFC44000069490004AFEC043BFFFC841B +:1007A000DD9E84013C0FFAC3DD9E84013C0FFACE2E +:1007B000DD9E84013C0FFACADD9E84013C0FFAD312 +:1007C000DD9E84013C0FFAC7DD9E4403F04B843F5D +:1007D0003BFFFCBCAE408401EFFC3C0FFABF440081 +:1007E000006949000489EC043BFFFC84DD9E3C0D5C +:1007F000FAC15A08010884203C1FFAC13E07E90DDE +:10080000D50484023E07E90D4403F04BA6405A107C +:10081000FF05843FAE40D5FF84013C0FFAD484002D +:100820003C0FFAD83E07E90F3C0DFA973A6F98BC97 +:10083000A6015A00040A490029CE5A0801064900B7 +:1008400044113E07E93F3C0DFA97A6415A18032888 +:100850002E17E9495A180124A6405A1801212E677B +:10086000E90A97B0CE1C3C1DFAB3A6485A180118E5 +:100870003C1DFAA8A6485A18011380263C6FFAD9E5 +:10088000490009403C0DFAB3AF802E07E959C8046E +:100890003C1DFAA8AE088401490029B73A6F988434 +:1008A000DD9E3C0DFAD88C013C0FFAD8DD9E840108 +:1008B0003C0FFAC83E0004144403F07E3BFFFCBC2E +:1008C000A640EFFC5A10010FA6405A10020CA64099 +:1008D0005A100309A6405A100406A6405A101003E5 +:1008E000A60084418420806280824400B1014900D6 +:1008F0006B8149006B96EC043BFFFC84DD9E840118 +:100900003C0FFADCDD9E84013C0FFAD14403F06415 +:10091000A6409646C9194423F010AE50A640581080 +:100920008001AE403C0DFA97A6008E02E602E91463 +:100930003BFFFCBCEFFC44000055490003DDEC0428 +:100940003BFFFC84D509A6409646C106A64054103C +:1009500080FEAE40DD9EDD9E3A6F9ABCEFFC490002 +:10096000044D5A0802143C5DFAD92E000D12D0062F +:100970003C0DFA97A6015A08040A490043733E0742 +:10098000E91D490007DB3E07E90F84013C0FFAD758 +:100990003C0DFAD98C013C0FFAD9EC043A6F9A84D9 +:1009A000DD9E84013C0FFAC2DD9EDD9E84013C0F7A +:1009B000FAC1DD9EDD9E84013C0FFAD0DD9E8401EC +:1009C0003C0FFAC0DD9E4403F04B843F3BFFFCBC70 +:1009D000AE404403F0ED8420EFFCAE4044000069DB +:1009E0004900038AEC043BFFFC84DD9EEFF0F081BC +:1009F000F001441003E8FE0C50007C6144100093A9 +:100A000040000437F08340000009F0039E41F18369 +:100A1000C8FB4403F04A44100055AE40EC10DD9E84 +:100A2000EFF0F081F001441003E8FE0C50007C610F +:100A30004410009340000437F08340000009F003A5 +:100A40009E41F183C8FBEC10DD9EEFF0F081F101D7 +:100A5000460000F450000240FE0C50007D3A441065 +:100A6000024440000437F083F003441186A0401094 +:100A70000417C8064403F04A44100055AE40F00382 +:100A80009E41F183C8F2EC10DD9E3C1DFA35A608AC +:100A90008C01AE083C1DFA35A6089606C8063C0D2A +:100AA000FA373C0FFA34D5053C0DFA363C0FFA34D0 +:100AB0003C0DFA34A64880A01010003F8420181284 +:100AC00080015000003C18128001D8FEDD9E3C2DB4 +:100AD000FA34A65098D1AE199C0996005CF0003B00 +:100AE000E9028400AE10A6108840841FAE11DD9E7E +:100AF0003A6F9EBC84008020490002558400640542 +:100B0000E4034403F00EA440964EC90FA440965649 +:100B1000C90CA440965EC909A4409666C906A40003 +:100B2000540001004E0200BA4413F00EA408960EC1 +:100B3000C806A5C85473810097F9C72144122D50E7 +:100B40008400A7C8AC0844122CF03E07E931AE0877 +:100B500044122CF197F8AE0844122CF2AE0844125D +:100B60002CF3AE0844122CF4AE0844122CF5AE0857 +:100B700044122CF6AE0844122CF7AE0849FFFCE2F2 +:100B80004403F00EA440964EC908A4409666C905D9 +:100B9000A40054000100C00349FFFF7944022D6006 +:100BA0008420AC4084C0440270403C6FFABC3C0FCF +:100BB000FAA23C6FFABE3C6FFAD45A78AE4384E393 +:100BC0003C0DFAA294BC8840A051C10CB4029649D5 +:100BD000A09349FFFD575A08010640001C0CFF87EF +:100BE00097B18CE15A780FEE3C2DFAA20411003D2A +:100BF0000401003C8E2496490421003F49FFFD4238 +:100C00005A08010544008000FF8744022D788420A3 +:100C1000AC40C61744022D60441FFF9FAE40440203 +:100C20002D619670AE4044022D6292C8AF8044039D +:100C3000F04A44100055AE40440000694900025C8F +:100C400044028F7044122D78FA5449FFFD413C0D47 +:100C5000FAA244322D7C44222D7D0400000940106C +:100C600020093E07C5553E17C55640104009921849 +:100C70003E17C5573E07C558A618A6509602964A75 +:100C8000AE58AE1044322D7E44222D7FA618A650B9 +:100C90009602964AAE58AE104413F00E3C0DFA344C +:100CA000A6481010003C4413F00FA6481010003D59 +:100CB000490002FC9E81E6483C0FFAABE80C842117 +:100CC0004010880C5410808FC10650007FE09600C1 +:100CD00049FFFEFF49008F893A6F9E84DD9E3A6F7F +:100CE0009ABCEFFC3C0DFAC98C013C0FFAC93C0DD3 +:100CF000FA97A6008E01E602E8322E07E9375A007D +:100D000055062E07E92D5A0855213C03F4D58C01D0 +:100D10009601E60A3C0BF4D5E91B840449FFFED991 +:100D200084013E00045484004900276F3C0DFA976B +:100D3000A6005A08010744000069490001DDD508F2 +:100D40008E02E602E900D50484003C0BF4D5440091 +:100D500000553E07E9373E07E92DD50484003C0BDA +:100D6000F4D5EC043A6F9A84DD9E3BFFFCBCEFFCAB +:100D7000FA1049FFFEAE84013C0FFACD490001CEC6 +:100D80004900273C3C0DFA978422490006BB4900E4 +:100D900027538420840284468061808180A1490099 +:100DA000028DEC043BFFFC84DD9E3A6F9ABCEFFCA5 +:100DB0003C1DFAB384013C0FFAD6AE08440FFFAADB +:100DC0003E07E9374900021A3C2DFA975A080215E6 +:100DD0003C13F4EA3C03F465E220E80EA6118E030E +:100DE000E602E80A2E0004318C213C1BF4EA5A0882 +:100DF00001043E07E94384003C0FFAD4A6115400D5 +:100E000000FD5A000406800284214900067B490047 +:100E100026E8C80A2E17E9273E07E9835A18011168 +:100E20003E07E981D50D840949FFFE53FA1849FFB1 +:100E3000FDDF840249003DC384013E07E959EC040B +:100E40003A6F9A84DD9E3BFFFCBCEFFCFA1249FF2F +:100E5000FE40EC0484013C0FFACB3BFFFC84DD9E9A +:100E60003BFFFCBCEFFCFA1349FFFE33EC043BFFF5 +:100E7000FC84DD9E3BFFFCBCEFFCFA1549FFFE291C +:100E8000EC0484013C0FFAD23BFFFC84DD9E3BFF67 +:100E9000FCBCEFFCFA1649FFFE1CEC0484013C0F7D +:100EA000FACF3BFFFC84DD9E3BFFFCBCEFFCFA1756 +:100EB00049FFFE0F84013C0FFABB490081A25A088A +:100EC000A1064400005549000117840249003D77FE +:100ED000EC043BFFFC84DD9E3BFFFCBCEFFCFA18FE +:100EE00049FFFDF784013C0FFACC4400005549004E +:100EF0000103EC043BFFFC84DD9E3BFFFCBCEFFCEC +:100F0000FA1949FFFDE684013C0FFADB49003BAAD0 +:100F100049002661C80449002671D50349003B7980 +:100F2000EC043BFFFC84DD9EFC2080C14413F04AAE +:100F300080E244200055AE885A080207490000901C +:100F4000C8FE640304034403F04A441000554433CC +:100F5000F04BAE40A6185A00FF05841FAE18D5000E +:100F60004443F0DA97B0A620540000F040238004F8 +:100F70004403F0ED9690AEA0AF80A6185A00FF058E +:100F8000841FAE18D5004403F041AE404000000974 +:100F9000400000094000000940000009400000092D +:100FA000FCA0944D4423F042FE0F9600A6D0AE1054 +:100FB000DD9E4413F046AE08DD9E00004403F0C4FD +:100FC000A600DD9E4413F0C49600AE08DD9E4403E7 +:100FD000F0C3A600DD9E4413F0C39600AE08DD9E6C +:100FE0004403F0CE4413F0D0A400A6489407FE0FAB +:100FF000441DD30088015C000041DD9E4403F0CE17 +:101000004413F0D0A400A6489407FE0F441DD2B0AC +:1010100088015C000001DD9E44022D00DD9E44033A +:10102000F0CE4410045AAC404403F0D08420AE40CB +:101030004403F0C7843FAE40DD9E4413F0E6AC08A5 +:10104000DD9E4403F0F58421AE404413F04A442071 +:101050000055AE88A6405A1001FFDD9E4403F0F40F +:10106000A6009204DD9E4403F0F7A600DD9E441323 +:10107000F0F79600AE08DD9E4403F0F6A600DD9E74 +:101080004413F0F69600AE08DD9E44522D00441243 +:101090002D3E18028001D9FEDD9E3A6FA8BC4400A7 +:1010A000400064030403440000FD49FFFFF04413C3 +:1010B000F04B841FAE0844A3F0CE4480045A812133 +:1010C00080E04463F0681285000010748000A63050 +:1010D000520000014900003F440009C449FFFCA23E +:1010E000A6305200000149000036440009C449FFFF +:1010F000FC99D5E83BFFFCBCEFFC49FFFFD0920018 +:101100004423F0EC9606A6509402541080FBFE0F88 +:10111000AE10DD9E48FFFFF6C80844122CF5A60865 +:101120008C019600AE08D50F44222CF6A6508C21D7 +:101130009648AE505A0801084413F060A6085800BB +:101140000004D5064413F060A608540000FBAE0866 +:10115000DD9E4413F0689600AE08DD9E4423F053F4 +:101160009606A650541080FE88019600AE10DD9EB3 +:101170004433F0404443F00EA69884A05421001C50 +:10118000FE579648AD60AE584413F06A9606A6889E +:10119000542100FEAE88A68888029600AE08DD9E27 +:1011A0004403F061A600960FDD9E4423F06DC90351 +:1011B0008425D5028424AE509444FE0F4413F06E6F +:1011C0009600AE084413F06FAE08DD9E4403F06D48 +:1011D0008420AE40DD9E4403F061A6009203960693 +:1011E000DD9E4403F061A60092029606DD9E440354 +:1011F000F061A6009207DD9EFC0049FFFFFAC807D8 +:1012000049FFFFF15A0001068401D5048400D5028C +:101210008402FC802E0004322E5004103BFFFCBCE4 +:10122000EFFCD00FC8064400005249FFFC52D50520 +:101230004400005149FFFC4D2E0004323E000410D2 +:101240002E0004302E500411D00FC8064400005464 +:1012500049FFFC3FD5054400005349FFFC3A2E00EE +:1012600004303E0004112E0004312E500412D00F21 +:10127000C8064400005649FFFC2CD5054400005523 +:1012800049FFFC272E0004313E0004122E00179562 +:101290005A00AA08EC0484073BFFFC8448FFFC19B1 +:1012A000EC043BFFFC84DD9E48003AD24403F04A44 +:1012B00044100055AE40DD9E3BFFFCBCEFE4F081E6 +:1012C000F1828005F101F283F384F48549FFFF5236 +:1012D000F002F10349FFFE674403F04A4410005551 +:1012E000AE40F001F104F205EC1C3BFFFC8448FF2A +:1012F000FE1D3A6FA0BC80E084C0E2C7E80C840108 +:10130000844080208062808080A28CC149FFFFD60B +:1013100097B0D5F43A6FA084DD9E48FFFE7F3BFF77 +:10132000FCBCEFFC49FFFE5EEC043BFFFC84DD9E51 +:101330002E000429C80A3BFFFCBCEFFC49FFFE90CD +:10134000EC043BFFFC84DD9E8400DD9E48FFFF0330 +:101350002E07C666C8143BFFFCBCEFFC2E07C54336 +:1013600049FFFEF9FA0949FFFB432E07C543EC0488 +:10137000520000013BFFFC8448FFFEEDDD9E48006B +:101380003D1048003D0344124000B62044124C601A +:10139000A84544120C60A84644121B90A84244126F +:1013A0004B40A844441237FC1410001144129970A9 +:1013B00014100012441220A01410001444126620CD +:1013C00014100015DD9E3A6FA4BC80C044012E1C91 +:1013D000EFDC3A20140044012E2CB1C43A2F9420A3 +:1013E0003A201400813F3A23942049003E51C02105 +:1013F0002E17C9C32E07E91D8E21E020E8029608AA +:1014000038148202442000481413000A3813820260 +:101410001413000B4412D2484210087344022900EE +:101420001403000944022C60141300131403000C6D +:10143000EC243A6FA484DD9E842C3A6FA0BCAE41AC +:1014400084003C0FFAD0840149FFFE684463F04AEF +:10145000447000553C0DFAD0C00D84208461840294 +:101460008041808380A33A6FA0843C1FFAD048FF5C +:10147000FF2549003A815A0801F2AFF0D5EC441338 +:10148000F01F4433F302A648542080E0A658966724 +:10149000E001E806A658966788229A0896804403D9 +:1014A000F01FAE80DD9E3BFFFCBCEFFC49003A5BC9 +:1014B000EC0484013BFFFC8448003A5AA4408C2190 +:1014C00096495CF08190AC40E9113BFFFCBCEFFC1D +:1014D000840549FFFAFE840049002397EC04440088 +:1014E00000693BFFFC8448FFFE07DD9E3BFFFCBC20 +:1014F000A740EFFCD90C8CA19768E6A5E90284A06F +:10150000AF40440FFFAA3E07E92DD511840649FFDD +:10151000FAE044122CF0A6088C019600AE08840074 +:10152000490023734400005549FFFDE644022CF0B6 +:10153000A600C00484013E000454EC043BFFFC847C +:10154000DD9EA6885A28AA08A680AE888420AE40D0 +:1015500048003C0BDD9E3C0DFAAB5A0804273BFFCC +:10156000FCBCEFFC49FFFE4A5A0002142E07C5D30B +:101570005A08011084003E07E90884003C0BF4D5AA +:101580004412B36A4402B36349FFFFDD8403D50507 +:10159000FA003C0FFAAB8405EC0484203C2DFA974A +:1015A0003BFFFC84480034ACDD9EA6885A20AA0D7F +:1015B000AE80442FFFAAAE88A6005A080104480056 +:1015C0003BCD48003BD2DD9E8440AE808400AC0819 +:1015D000DD9E4403F5608420AE404403F56184231E +:1015E000AE4084008020804080604800384344033F +:1015F000F5608423AE404403F5618420AE4084004E +:10160000802080408060480038354403F007A60001 +:101610005A08720A4403F004A6405A100C12A6009D +:101620005A000E0F44022D60441FFF9EAE408420DE +:10163000840280418461808180A148FFFE3FDD9E5D +:101640003A6FA83C44012E3CEFDC3A2014003A2FBC +:10165000942044212E4CB0043A2114003A20142046 +:101660002E27E95738400A022E000428C834846126 +:101670003E3004289552443271404462451038315E +:1016800094004472AD7096D8385F8A0281203C1372 +:10169000E2B6E201E820944140A098008827028544 +:1016A0000000A44838220101964B8A22382280008B +:1016B0004224082440210C0E88229649121500006D +:1016C00002150000964B4E140004129500008C0188 +:1016D0009601D5DEEC243A6FA804DD9E3C23E2B6E9 +:1016E0004412451084A0D210A4080230EB408C2292 +:1016F0008A0396034E040003FE025EF00051E806E2 +:101700008CA19769D5F18400DD9E8401DD9E842142 +:10171000480041A73BFFFCBCEFCC96D0FA4084A028 +:101720008481F2858442F583F584F586F287F58815 +:10173000F589B67FF481F382F48A804180A4490060 +:1017400036ACEC343BFFFC84DD9E3A6F98BC4422FF +:101750008F70EFD00031000FFAC00041001084A15B +:101760008440F68584C2F283F284F286F687F2889A +:10177000F289B67FF581F382F58A80414900368D82 +:10178000EC303A6F9884DD9E84213E17E981540045 +:1017900000FB84203E100428C807440200004412C5 +:1017A000451048FFFFD444020000441200024422C6 +:1017B00045102E37C5472E47C54884A0480036D56A +:1017C0003C1DFA973A6F98BCA64980C049FFFFDEDE +:1017D0005A6803092E07C666C8053A6F988448FF01 +:1017E000FF313A6F9884DD9E3A6F98BC44428F7007 +:1017F000EFD00062000F84A000420010F581F58256 +:10180000F583F584F586F588F58984A1B6DFF28540 +:10181000F387F58A806680414900363FEC303A6FA5 +:101820009884DD9E3BFFFCBCEFC484A0F38DFA607E +:101830008082F38584418462F281F482F387F28AA4 +:10184000B6BFF583F584F586F588F5898064804117 +:10185000F40D49003622EC3C3BFFFC84DD9E3BFF4F +:10186000FCBCEFBCF18EF08D8023F28F2E37C54784 +:10187000C4052E47C5488003D50380048481B61F64 +:1018800084A1F0828400F083F184F085F086F088F2 +:10189000F089F08AF581F587F00DF10EF20F49001D +:1018A00035FCEC443BFFFC84DD9E3A6FAABCEFFCA8 +:1018B000006F802401EF8020F689026F801C00FFFA +:1018C0008028F68E006F803C008F802C00AF803027 +:1018D000009F8034F68F23CF8020227F8022006FEC +:1018E000804815EF800814FF800A148F800B14AF16 +:1018F000800C149F800D15CF8010F791F692EC04A8 +:101900003A6FAA84480035C93A6F9CBCEFD4446250 +:101910008F700073000F00630010F381B0C7F38471 +:101920008460B6DFF482F583808380A74900354167 +:10193000EC2C3A6F9C84DD9E3A6FA0BC4473F42378 +:10194000A678978849FFFC49C0045413001FD505A9 +:10195000A67896678E2196482E200D012E000D1236 +:10196000400008172E27E91DE642E9083C2DFA97AA +:10197000A6915A2804048C019600400004063A6F90 +:10198000A084DD9EFE0C4420007840000817DD9EF8 +:101990003C23F478FE0C40000817DD9E3A6F98BC9B +:1019A00044012E5CEFF83A200C003A2F8C2049FFBE +:1019B000FBF9385F81013C13F4793C5BF4793C1B03 +:1019C000F478D14950007F80960049FFF8823C0DA1 +:1019D000FA9A49003AF63C03F4794410016844202D +:1019E0000078FE44401088373C1BE4D23C1C010FB9 +:1019F0003C33F478FE4440108C373C1E010F3C1CF5 +:101A00000110FE4440108C373C1E01104210082487 +:101A1000401088373C1BF4D04410003CFE4440107A +:101A200088373C1BF4E944101C20FE4440108837E2 +:101A30003C1BF4653C13F4EAFE0C40000C173C0B15 +:101A4000F4EA490062FD490063EEEC083A6F9884BD +:101A500048001710EC083A6F9884DD9E3BFFFCBCF1 +:101A6000EFF45A0801173C0DF16B3C1DF166B61FEF +:101A70003C0DF16C3C2DF167F0813C3DF1683C0D73 +:101A8000F1653C4DF1693C5DF16A49003779D51546 +:101A90003C0DF1633C1DF15EB61F3C0DF1643C2D25 +:101AA000F15FF0813C3DF1603C0DF15D3C4DF16139 +:101AB0003C5DF16249003764840080208040806092 +:101AC000490035BEEC0C3BFFFC84480035A23BFFCF +:101AD000FCBCEFFC49008BBF4403F705441FFFA586 +:101AE000AE40EC048420AE403BFFFC84DD9E4423EA +:101AF000F0779606A650541080FEFE0FAE10DD9EC5 +:101B00004423F04A3A6F9CBC44300055AED0EFF409 +:101B10004433F380A6985A2001FF4E13008DA6018E +:101B20008E01E60E4EF2018544F01A383807810125 +:101B300040F03C004A003C001C00F602CC00920041 +:101B4000CC009200F602280028009E009E00920021 +:101B5000CC00D800EC0C84023A6F9C844800372FEC +:101B6000840149FFFAFD840049FFFF7A2E07E91836 +:101B70002E17C9BB5A0001072E07E9608E04E60242 +:101B8000E811E624E8064400088E49FFF731D5182D +:101B9000E62DE8168E22440003E8FE0C49FFF728E4 +:101BA000D50FE624E80484018424D504E62DE80852 +:101BB000840184408062808280A049FFFB7F840191 +:101BC00049FFF9F9840149FFFF94EC0C84003A6F56 +:101BD0009C84480036F4840149FFFF8B840049FF50 +:101BE000FF3F2E07E9185A0801074400088E49FFF5 +:101BF000F6FFD5098440840184248062808280A01D +:101C000049FFFB5CEC0C84003A6F9C84480037F180 +:101C10008440840180A02E17C9BB8062808249FF66 +:101C2000FB4D840149FFF9C7EC0C84003A6F9C849A +:101C3000480036C55A100104480000F0A6018E0382 +:101C4000E60C4EF200F644F01B543807810140F0D8 +:101C50003C00DD0F9001180090011800DA0124000B +:101C60002400E200E200DA0190019C01EC0C840106 +:101C70003A6F9C84480036A346700FC050638800BA +:101C8000808780A68007802680468066B6DFF68142 +:101C9000490036768400802080408060490034D03E +:101CA000490034B7FA1A49FFF6A3500381408080F7 +:101CB00080A6802680468066B6DFF68149003660C1 +:101CC0008400802080408060490034BA490034A1FB +:101CD000FA1A49FFF68D808780A680078026804605 +:101CE0008066B6DFF6814900364B84008020804054 +:101CF0008060490034A54900348CFA1A49FFF6780F +:101D000050038410808080A6802680468066B6DFDF +:101D1000F68149003635840080208040806049008B +:101D2000348F490034768401490036494400003735 +:101D300049FFF65ED56646700FC050638800808705 +:101D400080A68007802680468066B6DFF68149003F +:101D5000361784008020804080604900347149003B +:101D60003458FA1A49FFF64450038140808080A617 +:101D7000802680468066B6DFF68149003601840001 +:101D80008020804080604900345B49003442FA1A68 +:101D900049FFF62E808780A68007802680468066D1 +:101DA000B6DFF681490035EC8400802080408060F9 +:101DB000490034464900342DFA1A49FFF6195003F8 +:101DC0008410808080268046806680A6B6DFF681FB +:101DD000490035D68400802080408060490034303E +:101DE00049003417EC0C84013A6F9C844800370199 +:101DF000840149FFFE3549FFFBEE8401490035DFD0 +:101E0000840049FFFE76840049FFF8D5EC0C84007D +:101E10003A6F9C8448FFF9A45A18020B84014900C8 +:101E200035CEEC0C84003A6F9C8448FFF8C4EC0C6F +:101E30003A6F9C84DD9E92002E07E90A5A08012819 +:101E40003A6F98BC49FFF9DAC8203C0DFAB3A640B6 +:101E50005A1801FFA6005A0801193C0DFAA8A780DC +:101E600097B05A6801133C0DFA97842049FFFE4A47 +:101E70003C1DFAB38400AE083C1DFAA8AE088006EB +:101E80003A6F988448001EC13A6F9884DD9E3C0DDD +:101E9000FA97A6415A1006292E17E91CC9253A6F50 +:101EA00098BC2E67E976CE1E3C1DFAB3A6485A1898 +:101EB000011A3C1DFAA8A6485A18011580263C6F45 +:101EC000FAD949FFFE1F3C0DFAB3AF802E07E9593E +:101ED000C8043C1DFAA8AE0884013A6F98844800F3 +:101EE0001E943A6F9884DD9E3BFFFCBCEFFC49FFDB +:101EF000F9855A080207EC043BFFFC8448FFFFC940 +:101F00003C0DFA97A6015A000B07EC043BFFFC843A +:101F100048FFFF94EC043BFFFC84DD9E3C0FFADF9E +:101F2000DD9E3C0FFADEDD9EFC00C0085A08010B66 +:101F3000490036B03C0FFAE1D505490036A83C0F00 +:101F4000FAE0FC808020E6293C0DFAE1E82544F027 +:101F50001E5C3817840040F0BC00DD0F0A3C1016F0 +:101F60001C22282E34003C0DFAE0DD9E500000506B +:101F7000DD9E500000A0DD9E500000F0DD9E500070 +:101F80000140DD9E500001E0DD9E50000280DD9E9C +:101F900050000320DD9E8400DD9E9200FC52F18CF7 +:101FA00044112C7CF48DB11580E380C23A208C045E +:101FB0003A220C24F08EA6488145AE6044112C884C +:101FC000B1183A208C043A220C24A648AE60842032 +:101FD000121F80293C2DFAE13C1DFAE04900362A07 +:101FE0003C1DFADEA60AA64B490036485CF3810088 +:101FF0008007E903440000FF409000138009490076 +:10200000365084E03C1DFADF00008010E2E0E8106A +:10201000800738109C00490036513C0DFADF984784 +:10202000800700108008490036718CE1D5EC8400EF +:102030004900363B490036118401490036364900D3 +:10204000360C5AA801482E37C53A44007FFF84E079 +:10205000F088400480112E47C53BB67FF089501FA1 +:102060008052F00E44226B3080AAF781F782F7830A +:10207000F784F785F786F787F78A4900320E2E37FF +:10208000C53A44126B302E47C53BB67FF38280AA17 +:102090008041F00C14AF8001F783F784F785F78651 +:1020A00014AF8007F788F78914AF800A490031F52B +:1020B0003C1DFAE03C2DFAE144026B30490035BA90 +:1020C000440004B0490035ED8402490035EE490072 +:1020D00035C4490035E2F10DAE082E000404C809EC +:1020E0002E0004005A000204480000D5480000E514 +:1020F0008500F00DA600E300E8F4A0754004080890 +:102100008801A64001E00002F193A641A603F191E7 +:10211000F092F012E21E4EF300B6500F7FFE5CF01C +:1021200000204EF200AAFA02420F0024F08FF713AB +:10213000F011E2074EF300A19E3AE60E4EF200992E +:10214000F00FB4669847964994099898F08EA611B6 +:1021500096064E02008EA7504C54408B844044009B +:1021600007D0B115384208108881972195218883BE +:10217000A761E6A4E80DA720A17338529101E005FC +:10218000E902962BA17238429101E687E9088C4159 +:102190005A2809E984404E060006D51384414E07AB +:1021A0000068F30C40F0040A384185114430007F88 +:1021B00042F20C7340F781F65EF78074E859CA5812 +:1021C000F00CB15B848038F00511B01584403830D4 +:1021D000101088619619F0908002B0D538A188104F +:1021E000F3108943F30C40A500133891A911B0D81E +:1021F00038A188108C414204A8735A2809F0AA29F2 +:102200004EF70009442001F4FE1440003C1614026D +:10221000FFFF8C815A4809DB8440B15B855E8400F6 +:1022200044312C9480209913383200105A38010917 +:10223000383282025EF1FF38E8038C2196485A1842 +:10224000020CB466049F800E892300348001403163 +:10225000A802103480018C015A0809E8B406F10E76 +:102260008801A6019606C0048C495A2890DA9C3948 +:1022700097C048FFFF5F500F000155E000FF48FF87 +:10228000FF4A8D0148FFFF378C01F10DA648E2019E +:10229000E9193C1DFAE03C2DFAE1F00C490034CA82 +:1022A000840349003502490034D8490034F6F10D61 +:1022B000AE088400D545840045EF8000FAE2853EF3 +:1022C000D5E5A0B39441382101015CF1004CE80749 +:1022D000A0B18822A48840217804AC88A0B594429B +:1022E0008822A68800808001F28FA68AA64BF18EF4 +:1022F000F10EE222E9CA42A11C24F10FE301E91820 +:1023000040550400B486976994E98864A71954F28B +:102310000001E80B04FF800C38F795115EF7804C44 +:10232000E80440422402AF198C219648D5E88C413C +:102330009690D5DFA07138508101D8078C01F10D3E +:10234000A648E201E9F8D527966B4E15FFF9A0B52E +:102350009442956A98D18845A6DAA712E264E80209 +:10236000AED2A0B598D18845A6DBA713E283E802D8 +:10237000AED3A0B5383104008845A710E264E80266 +:10238000AED0A0B5882288A2A649A6A9E241E8D786 +:10239000AE69D5D5FCD23C0FFB40DD9E3C0FFB3F28 +:1023A000DD9EFC41444000FC420190730040001857 +:1023B00054520001CD07B4C05A600105005000E03E +:1023C000C51E4422B724840038010C084422B714E7 +:1023D000848138410C08A4884442B6D8A4493822E4 +:1023E0000E09949A8844AC514412B6C838008C083F +:1023F0004412B6B838008C084800018A5A6802496D +:102400004422B7144442B6C838610C004402B6B83E +:102410005A68010938520C0838500C0838510C0819 +:10242000D51738200C00E642E8058C4138200C080E +:10243000D50338500C0838220C00CA0A38200C008A +:102440005A2802074422B6C8848138410C08382033 +:102450000C008083840F424100734422B6D822507E +:102460008000226080018004945A38410E01447239 +:10247000B60488229B2C38438209A5099402880758 +:102480009B34AD0138510E09AD89480001415A60B5 +:1024900004044800013D544200FD1040001844422D +:1024A000B7144482B72438420C005A48010A384411 +:1024B0000C00959988864462B5C838531109384490 +:1024C0000C004E4300DD4452B6C844A2B604386244 +:1024D0008C004452B6B838928C005A60010680E4F1 +:1024E00080A487CFD521955A894580C480A484E1F2 +:1024F0004C54C00384E222F500008CA14243BC731B +:1025000022F5000197684263BC7350A5003C5A58FD +:1025100003F084A440421496406314D63C4FFAE37F +:102520003C6FFAE2D51980C34262F87338F51A118C +:1025300095B288CA8CA1226300019768888FE32531 +:1025400088E6E8F28D21404224964073A4F63C4F81 +:10255000FAE33C7FFAE24462B5C840A188084053E0 +:1025600028003C9DFAE3848038430E09AD2980A9F8 +:102570004E940004525480003C7DFAE283C74E74AE +:10258000000453E380003C4DFB4040F2F800A121E1 +:102590009281E28F004000F3F481E9048E8BE682A1 +:1025A000E86E4E9700094442B6D838F20E1152F741 +:1025B0008437D5074E92000E4442B6D838F20E1139 +:1025C0004440006442479024405214B69769D503B2 +:1025D0004450FFFF4E77000A4442B6D8888A22F260 +:1025E000000152F7896BD507C70E4442B6D8888AD6 +:1025F00022F2000144400064424790244042789611 +:102600009721D5034440FFFF04FF800150F7FFF5F9 +:102610005CF78002E81C4E920003CF764452B6D895 +:102620002270800038428E11229080019B3C3C4FEA +:10263000FAE34042A80038728E0922120001129279 +:102640000001401484013C1FFAE2D55EE2A440423E +:10265000BC1B5CF20096E8058C8A38430E09D50F46 +:102660005CF2012CE808928138430E0988CA8C8AF2 +:10267000AD31D5054410009638130E09001000F353 +:10268000E622E9035A1806084412D56038108C0077 +:10269000C935D50A38440C00945988244452B5C829 +:1026A00038728501CF058421101000DED527E6821F +:1026B0004452B6D8959AE8163C4DFAE338128E018A +:1026C000FF3C4490006440422496888138428E0941 +:1026D0003C1DFAE2992EFE7CA5E14010A436882725 +:1026E000AC61001000185810800210100018380259 +:1026F0008E0188A6AC10A429AC1138040C008C0102 +:1027000038040C08D504444000C7D5AEFCC13C0FCA +:10271000FC42DD9E3C0FFC41DD9E84003E07F10043 +:10272000DD9E5A00016AFC202E57F100D02F443064 +:10273000004480E242708C735061003F84804C40C2 +:1027400000264C12001F2033803F20F300008A6FC8 +:102750004E340003FEDA8E62E662E81320F37FFF58 +:102760002033803E8A6F8C61E663E80B9EF3025350 +:10277000801EA4D8E2A3E80584011003803AD5386E +:102780008C81972050630044D5DB44300044808224 +:1027900042408C738460D5058C6196D850210044EA +:1027A0004C3000294C11BFFAB4A25CF2A711E9F534 +:1027B00000510043006200428CA1E0A6E9EE005205 +:1027C0000043006100428CA1E0A6E9E7005100410E +:1027D000006200408CA1E0A6E9E0005200410061E7 +:1027E00000408CA1E0A6E9D984021002003A8401DD +:1027F000D5058400D5038400DD9EFCA0FC42A10D1C +:1028000094D28864F1830081800000A18001A65ADF +:1028100040552001F1818CA1A65BE4A3F1824EF228 +:1028200000B684603C4DFC4105CF8001812380E3EC +:1028300080C3F102E03CE9304E82001500F2000254 +:1028400083C843EE3C7340FF040839E079114FE739 +:102850000003893E40F03C0022F7FFFF4EF70003E3 +:10286000886F01E2000250FF7FFFE14FE812802AEB +:10287000421E787339E0051140F084084FE70003E9 +:1028800088DE40F03C0022F780014EF7000388EF1D +:1028900051CE0001D5CF5A5001075A58022F2EF0C1 +:1028A000045FE82B878A43E1F02440FF2407E80E09 +:1028B00042F3F02440F79807E8094E82000800F23E +:1028C000000250F7FFFFE14FE9635A580117F50284 +:1028D000F1018AA1E4A5E8042E50045FC50E40FF73 +:1028E0002407E9034E83000A84AAFF7CE0A6E9508E +:1028F000A7628EA14CA2804D2E50045FC50884AA09 +:10290000FEECE069E945FFECE0E6E942F103949171 +:1029100000A20003A04C88418420A75180E18121BE +:102920008441E04AE823A7A281054281187340341C +:102930000408388021114E84000452840000892844 +:10294000C50A40800C0022847FFF4E84000452841C +:10295000000088E88EC1D6088860223180014E349C +:102960000003FEDA88238C41D5DD5EF487D1E90BC4 +:102970005EF38064E902CD075EF08064E909A62277 +:102980008E01D00684003E00045F8401D5028400DD +:10299000FCC2FC40A10D94D28864A04C9491A798ED +:1029A0008841A759A71AA691A6DBC6049E7196482E +:1029B000D50280269491884080E484C0FB54E2676D +:1029C000E9094293A8248CE13891240188C997B37E +:1029D000D5F7FAE2FFE444900064E2A1E930542024 +:1029E0008001CA2B5A10082A40809C0040840408A9 +:1029F000890083848142E27CE90F02F4000051CE19 +:102A00000001894F02F4000140A50011884F969300 +:102A100050840024D5F1E629E805E142E80E8A4A0F +:102A2000D505E04AE80A402508014221242440F166 +:102A300019F65EF78033E8058C21D5D08401D502E4 +:102A40008400FCC0FC4051FFF728F1858540501FF1 +:102A500084DCF382F284F48CF18180E080C1810A0D +:102A60008461F005E340F086E851F1022203800022 +:102A7000224380011203000A1203000CA04BA0396C +:102A80001243000B1243000D1033003B1083003A39 +:102A9000381081011403000B1213001EF102409044 +:102AA0000408F486A08D9442882250030040844498 +:102AB000F38349008153F0028442A00489208029D5 +:102AC0005003003E4900814A00548001F303F4069C +:102AD000C50C3C1DFC41A60A8E01D00700548000A5 +:102AE000C504A60B8E01D80410330035D50310831E +:102AF00000355EF2091C800340043C1B10030036C5 +:102B00008D41506300448CE8D5AD2E87F1008400E0 +:102B1000148F800350AF80688020509F80A4B1F84C +:102B2000506F811C445000444432B73CF4014220B1 +:102B30001424888288433815020A3814820A38130C +:102B4000820A3813020A8C011012002A1011002A7E +:102B50005A080FEE4402B7BE844084C3E248E8300E +:102B600000107FB88C415A18012980828020E288A9 +:102B7000E82400507FBDE6A9E807A6C99DEA4C718C +:102B8000800B8CA3D5075A500915A6C99DDAD70327 +:102B90008C63DB0F20F0800020307FBC8A6F8C615B +:102BA000E663E8070030FFFDCB0410607FB8D50571 +:102BB0008C8150108044D5DC50000044D5D04400B6 +:102BC000003C42040024F08F8400F089460000F3AA +:102BD00050000A703C2DFC4251EF8158049F800147 +:102BE000F091F009F105E2014EF20104F309B01A87 +:102BF000842138100E0A85404402B73CF10F4CA0E6 +:102C000080F0F1052234800CE228E8092210000E41 +:102C10002240000F8A612214800DD5082210000C7A +:102C20002240000D8A612214800D8A24FE4C42113C +:102C30008C73F1872214800C2264800DF18BF30BCE +:102C40002210000C2240000D9A59F188F3089B34A1 +:102C5000045000094212102442118C73F58AB460AA +:102C60005A580408005000285A580104480005B773 +:102C70000450000CCD71A151E2254EF30590A551F1 +:102C8000FF5CE225E82CA152E225E80AA144A183D9 +:102C9000F708FF64425398734E560581D520C31F31 +:102CA000A153E225E81CA184A143F708FFA44263D5 +:102CB000947344500064FF7440528CB7FF6CFF5C07 +:102CC0004470271040F29DF70071002744500064C3 +:102CD000FFCC407394F7E2EF4EF3055F00500029FC +:102CE000A790E2C5E805A194E2264EF30558C32259 +:102CF000E6A2E920F511E2A1E91DA144A183FF2C80 +:102D0000F5084242987344500064FF6440528CB707 +:102D1000FF6CFEEC4450271040F195F7005100275E +:102D200044300064FF4C40528CB7E2AFE8034E469B +:102D30000536003100264E320552A0D3E2234EF272 +:102D4000054EF10A5A18040448000549F1074639AE +:102D50000000480005425A5002065A500404480038 +:102D6000053EF30A5A380404480005392230000EA3 +:102D700085E6F38D2230000FA1C3F38E846AFE5CDA +:102D8000F190A051A14442F78424F110E22F4EF3B8 +:102D900005060011002842F38424FE6C40F78DF6EE +:102DA00040108C36F30EF18A88659AF3F60DF10B1C +:102DB00088C78A26FEDC42308473F10AFE4C421733 +:102DC000BC73E0614EF2050BF108FF2C42409C738E +:102DD0004E470505F10746380000480004FEF0099B +:102DE00051EF00048C01F0895094804448FFFEFBB1 +:102DF0008400B0E98421E208E8053811820A8C01D8 +:102E0000D5FBF005E60BE80BE70BE8098028B09A44 +:102E1000504F8158B1524900052DD509F005802841 +:102E2000B09A504F8158B152490004DBF0883C0DF4 +:102E3000FC428500F0874605FFFF50000FFEF08D35 +:102E40004608FFFF50000FFF81484412B73C45E29F +:102E5000D560F08EF008E3404EF201CCB092400510 +:102E6000040888028061A6014420004442300873AF +:102E70000421800C5A280214B092846F3821290052 +:102E800042200C73503F815838218A024E25000899 +:102E9000B0A984613831020A480001A944300044D5 +:102EA000B092808142400C7338212900F602005212 +:102EB0000037504F84DC42410C738064A1B3503121 +:102EC0008028F689F70950420030A199AF6738632E +:102ED0009901F70702738015E2E6E808CD07A75AC3 +:102EE00058528001AF5A8461AEE744400044503FDD +:102EF00084DC81214231107342901073506180183C +:102F00002251800C2244800CF58A9B2C2253000114 +:102F1000F58BF70B2254800D9B7D42F2942442F2F4 +:102F2000107380EF81E3A95C1C778002F70A1447D5 +:102F3000800188E4ADF2F70B88A7AD7384AF80C23F +:102F400042601473505F8158F70D38529A024666FA +:102F5000000088C5E2E6E855F60EE2C5E8520054E6 +:102F6000803F50318038E6A9A6DFE806E669E835FB +:102F70004E440034D505E669E9304E47002F444001 +:102F8000004480614230107300618020445000FC96 +:102F9000F70442731473005380FAC514505F84DC45 +:102FA00042511073808500528034CD170251801E2B +:102FB0000242001E44300064FF5CFA6EFEE4E0A3AF +:102FC000E80C44300044504F88D842410C73806470 +:102FD00084841441FF0DD51844400044503F84DCE4 +:102FE0004231107384A21451800C80A1425010739E +:102FF00080858C908C70A562A523AD5AAD1BD5043D +:1030000084801441800C44400044503F84DC80C1E3 +:1030100042311073426010738086507180108CD0E2 +:103020002253800222930002226300038AA9A95935 +:10303000225380038AA6A95A0052002050618020A2 +:1030400010518020043200095A38037A383F1400A6 +:103050005A38010A003200288C6A10320028846233 +:10306000383F14084432D560383194005A38030E82 +:1030700044300044808142400C738064848110415C +:103080008028FA60383F1408383F14005A38040E7C +:1030900044300044808142400C738064848110413C +:1030A0008028FA70383F1408383F14005A38022636 +:1030B00044300044504F88D842450C73F60904420E +:1030C0007F0C38631101848AFFA4808142400C7315 +:1030D0002272001C80648487FF3CE0C4E80784817E +:1030E0001041802844300030D506003180285A38FD +:1030F00001058465383F140844300044504F84DC97 +:1031000042410C73FEC488610052003700318028B0 +:103110005A5801038E611032002844300044504F49 +:1031200084DC42410C7380640042002850318020CE +:10313000CC038481D5028483A919D50684603E30EE +:10314000045F8462A8F144400044806142301073FF +:10315000003180345CF180C8E8038C6196D8505F00 +:1031600084DC42511073103280344432B73C423018 +:103170001073B4C55042802800318029F507AEE1B4 +:10318000A16DE2A6E805E66AE80A8C61D507F507B5 +:10319000A16EE2C5E804C3038E61AEE14450004471 +:1031A000503F84DCF40242311473A1230461800B8C +:1031B0008D013842190180C1426014732203001C42 +:1031C000E00440403C1A1241801C00418020503FE6 +:1031D000811C84013801920AB0F838018A0AF0068D +:1031E0008E01F086F0038E01F0838D4148FFFE349E +:1031F0008400509F80A44462B73CF08750AF80E0C9 +:103200002E07F100F107E220E803F003C806049F4F +:10321000800184E0480000C23C3DFC41000180097F +:10322000E300E8F60C0480015A0001044800009F06 +:10323000040300095A08031300230020441000FC73 +:10324000F40442410473001200FBC908F003141493 +:10325000FFFF8E01F0834800008A9E41E622E807C6 +:103260000403000C5A08023A8400D53E5A08033A77 +:1032700000430020440000FCF104421200732220AD +:10328000807380012253001C842AFE8C8427FE6CEC +:10329000E041E80D001000FBC10A00130037C10730 +:1032A000001000F2C1040013003AC1118420101371 +:1032B000002884201414FFFFF103000000F28E2187 +:1032C000F183C81484013E00045FD5104402D56028 +:1032D00044100040381010083C0DFC42A601D504F3 +:1032E000000300288E0110030028000300285A085C +:1032F00001080013002A581080041013002A00113E +:10330000801984E0B09AE2E1E80938351E02CB0466 +:1033100038311E02C3058CE1D5F784E0D525C00302 +:103320008404D50284054420004414030009500F8E +:1033300084DC42038873802649007D10002300202E +:10334000501F811C840138008A0A38051E0A840037 +:103350001404FFFFF0038D018E01F083D50738259B +:103360001E02C2DE8CE14C70FFFCF007506300448B +:103370008C01F08748FFFF46F0064E02011500134E +:103380000009E3014EF20110B01A38001E025A0083 +:10339000010C8CE150948044F0053C6DFC41E2E06E +:1033A000E9EC48000101B03838601E02CEF3500F3E +:1033B000811C38001A024E0300F18029B609A809C1 +:1033C000A80AA80BA80C0204800C10648020120428 +:1033D000800E0204800DF1041204800F3C0DFC42AB +:1033E00088080000001C10048028440000FC4213E0 +:1033F000007380018421101000FB2E000409C00A14 +:1034000049FFEEFC5A080207000480288C011004D2 +:1034100080280434800B00148020440000FC04AF9A +:10342000800442A0807380433C0C0278F102F38355 +:1034300049FFFAB1100500FA1004803BF303C807F6 +:1034400000048028C804840110048028840010052A +:1034500000F1F1028043F00C49FFF9D20014802002 +:10346000100500F2F204440000FC422080730001C9 +:1034700000F2C80700048028C804840110048028D2 +:10348000F0059678502F84DC49FFF94D81405A08A9 +:10349000010B49FFEEB35A08020700048028C80355 +:1034A00010A48028F102000480280424800BA04B83 +:1034B000C815380089013C1DFC4202108015E2202D +:1034C000E80800048036C805840114048009D51476 +:1034D0008403140480098401D50D381089013C2D22 +:1034E000FC4284631434800902210015E241E9049E +:1034F0008C0110048028002480364412D56000041A +:1035000080205A2801052E37E915C3028440F302B2 +:10351000382080084422E1B0842038110008A0DB64 +:103520000424800B3C4DFC423831890102420015D5 +:10353000E283E80284214432D5CC10148037842001 +:1035400038118008F404443000FC42400C73F3024C +:10355000101200F00004802A101480341014802906 +:10356000A0DB8421FE0F1004802A38218901840009 +:103570001224801C502F811C1404800C38111A0A4C +:10358000B0B88D0138111E0AB05A38009E0AF006F4 +:103590008E01F08648FFFEFF8CC1E2C14EF3FF09A9 +:1035A00048FFFEF98400F104804000330009E20383 +:1035B000E808B641102080E08C01501080FCD5F660 +:1035C00084003E0004093E07F100447000C88540B5 +:1035D000509F80E000030019E3404EF200D738040A +:1035E000AA025A000104480000CAF0010440000980 +:1035F0005A4005222E87F100442000444402B73C83 +:1036000042040873F101F48349007BA8F001F2043D +:103610008D0100100020440000FC42208073000156 +:1036200000F03E87F1005CF000C8F403E8048C0170 +:10363000100100F0F001048F80040010002044000D +:1036400000FC42808073F0015014001CB68800001A +:10365000002A10040018F0010200000A12040002FF +:10366000F0010200000B12040003F0010200000C44 +:1036700012040004F0010200000D12040005F00124 +:103680000420000BB400B641A80AF001A001A80B69 +:10369000F001A002A80CF0010400000C1404000CBE +:1036A0005A480311000400F2C80D001400F184010F +:1036B000C907100400F1F102F00C49FFF8A1100451 +:1036C00000F2F001048F800400100020440000FC90 +:1036D00042808073B4885A400416F001F202F483E9 +:1036E0000400000BA09394413801010112040074FE +:1036F000F002A084500400668822844249007B2E98 +:10370000F4033C0DFA9AB40092029606C00344708A +:1037100001902204002E22F400028A0F4E040003BE +:10372000FE02E0E0E90B2204002F22F400038A0FDE +:103730004E040003FE02E0E0E80A000400DE5A083E +:1037400002075A48020584013E000401F001B4005A +:103750005CF02711E9085A4802072E0004098C0181 +:103760003E000409F0010000002A9606C807000484 +:1037700000FAC8048401100400FAF0018D415000E1 +:103780000044F08148FFFF282E07F1003E07E9556D +:1037900051FF88D8FCC04E67FAA3F10A5A180314E7 +:1037A00000100034C9100010003A5A180309F1053E +:1037B0004C140006F107463A0000D50EF1074631D9 +:1037C0000000D50AF107381F280A5000004450A510 +:1037D000003C48FFFA158823D5F7843FD5F5FC4314 +:1037E000F08181008400F484F182F58580E183809A +:1037F000812084814E82003DC73B5A48013A84A013 +:103800008085855EF101D122386116025A68011D5A +:10381000F10495AA88C1F68384C0F1024C6080153A +:1038200039E19A025BE8010F4410003C42F30424A2 +:10383000F1033810BC02E22AE80583868125809EC8 +:1038400081418CC1D5EB8CA1D5DEC4D5F105954164 +:1038500088A18C0184201092800011C28001960002 +:103860003811260A8F013811F20A8EE1D5C4FCC343 +:10387000C06EC16FFC4051FFFB90E220E82F80E159 +:1038800044A0003C851F81244293A87384C03884DF +:103890009A0A8CC14C607FFD8CE14C707FF680C031 +:1038A00083818001802681248105F2818143490042 +:1038B0002794B03B4900279880094900279FB00210 +:1038C000490027A6840F490027AD490027B084404E +:1038D00080A245E0003C8082D514E201E8E184E06A +:1038E00044A0003C851F81244293A87380C0388483 +:1038F0009A0A8CC14C60FFFD8CE14C70FFF6D5D06C +:10390000840F81E94212802442F2F87384E098F92E +:10391000B00238300C005A38011138379E025A373D +:10392000FF0D94D188688C41AFD8AF59F3019690C0 +:1039300038419E0A3845160A8CE14C737FEA8CA107 +:103940004C5E7FE0800251FF8470FCC08040D50255 +:1039500080418002DD9E3C0FFC74DD9E3C0FFC73B9 +:10396000DD9E4402BBC084213C0FFC4E84003E0718 +:10397000F13C3E07F13D3E07F13E3E07F13F3E0779 +:10398000F1403E07F1413E07F1423E07F1113E078B +:10399000F1103E07F1123C1FFA1C3E07EADF441209 +:1039A000BB7C8400845F382080088C015A0841FD6C +:1039B000DD9EFC0049FFECB3FC80FC0080C049FFA9 +:1039C000ECB0C00784013E07E8CC8400AE34AE35CD +:1039D000FC802E07F118DD9E4432BB48AE18AE596C +:1039E000AE9ADD9E3C0FFA1CDD9E3C0DFA1CDD9E5E +:1039F0003C0DFAB7465FF00F50528F00FF4646006D +:103A00001000D80684003E07EADF8401DD9E8400B2 +:103A1000DD9E2E17F13E2E57F13F3C0DFC744C12EB +:103A2000C0102E27F13C5A28010CA6059D494002E2 +:103A300080B697683E57F13E3E57F13FDD9EA605A2 +:103A40008CA1400280B697683E57F13FD9048401AB +:103A50003E07F13CDD9E2E57F13E2E17F13FD90473 +:103A60002E07F13CC0103C0DFC748CA1A605400251 +:103A700080B697683E57F13E4C12C00584003E0761 +:103A8000F13C8401DD9E2E57F13E2E07F13FD80810 +:103A90002E07F13C84208E0140008006DD9E8401CB +:103AA000DD9E2E57F13E2E07F13FD8072E17F13C31 +:103AB000840040000406DD9E8401DD9EFC0084A09D +:103AC0008C81E2A4E8073860080438608C0C8CA173 +:103AD000D5F9FC8080603C0DFA1C9E41E622E82569 +:103AE0003C2DFC7384200041000AE224E809A1591E +:103AF000385287025A58010384028C21D5F7FC0002 +:103B0000842000410009445000FCE224E80DB44345 +:103B100042209473B4429F91E6C2E9055A200404FE +:103B20008C21D5F48401FC80DD9EFC42F181B541FD +:103B3000843F101F800F2E17C5D08120C1082E177B +:103B4000F118C90549FFFFC83C0FFA1C3C3DFA1C9F +:103B50005A300104480001113C1DFC733DEDFC741A +:103B6000B67F84C0B45F004080098E419690E244E5 +:103B7000841F4EF200FD440000FCB489FE149960DD +:103B8000B50550F47FFF5CF78002E9055A80040414 +:103B9000480000E800F28056E92A004280DE5A48D8 +:103BA00001304442CFCC38420800E6944EF200DAAD +:103BB0004452CFCC8C8138428808B4898880B4A420 +:103BC0005A500404480000CE4452CFC03822880026 +:103BD0004E2300C822520073024200748443FEA4A4 +:103BE000956A9693E0A2E90C480000BC5AF80209D5 +:103BF0000222806B8880ACAE0222006CACA7002F42 +:103C00000000B4A9C20999280220800922420006B6 +:103C10008E418A44D50498A822210006004F000155 +:103C2000C40988A00240800A225280078E818A85BA +:103C3000D50488A022428007005F0003C5300250EF +:103C4000800900FF00028EA1E912028080025074F8 +:103C50007FFF850240F2A1F642F11C734027945683 +:103C60000250800A02F080038EA1D51102808003E9 +:103C700050747FFF850240F2A1F642F11C73402789 +:103C800094560250800A02F080028EA150F7FFFF86 +:103C90004082A11642823C7340441496A54AE045F6 +:103CA000E9029EA94E2400038440A54BE085E90269 +:103CB0009F294E440003848084E680AA42531C73EB +:103CC000B4FF40F2100A40838C085884000210822E +:103CD0008000007F00024081100ACF0A949484F093 +:103CE0001082800110F28002971FFEBED509952434 +:103CF00084F010F2800110828002969FFF3EFEA7A2 +:103D0000B489AEAB88800222000AC2039690D50225 +:103D1000844180AA84E642531C73AEAC0222000B9D +:103D2000C2039690D5028441AEAD845F1025003C5D +:103D30001025003D0020800CE642E911B44988407E +:103D400000210035CA028441404518001022004677 +:103D5000B4498802200000361002006E8CC197B072 +:103D6000B41F8C019600B61F48FFFEFE1005003EF2 +:103D70001005003FD51C2E67F110C6192E07F11152 +:103D800000150000E61EE80594039657FE0FD503C4 +:103D9000440000F0100500002E07F112106500012C +:103DA0001005000284013E07F11884C02E07F118A7 +:103DB0005A00FF0DC00BCE0A841F3E07F1183C0DC0 +:103DC000FC458C013C0FFC45D5033E67F1185A3881 +:103DD00001173C0DFC7300400009E2C4E810F0013B +:103DE0008426FE74B4408A868406FF04964888229E +:103DF000500F800F84408E8149FFFE62F001B42095 +:103E0000840080A150208040083280018803960001 +:103E1000DAFCFE02100080408401C60284003E07E6 +:103E2000F142FCC2FC20844180624440004080E0BA +:103E300080C149FFFE453C0DFC730000000CE6020A +:103E4000E9105053804650130046507380500802CA +:103E50008001180080012002802710008027DFF8F1 +:103E6000FCA0A60092038C1596275C000014DD9E32 +:103E7000FC4080C1A640844081203E27F141C131F1 +:103E80002E07F13D5A08010C2E17F1403E27F13C58 +:103E90003E17F13E3E17F13F3E07F14149FFFDBBA2 +:103EA0003C0DFC742E77F13F3C1DFC4EA704844171 +:103EB000040480014213907380628E8149FFFE00EA +:103EC0002E07F1425A0801063E07F13D3E77F140C8 +:103ED0002E07F10C5A00FF088C013E07F10CD503A8 +:103EE0003E17F10C2E17F141B4065A180132A605FF +:103EF000C81849FFEA1FC80F3C0DFC74B4262E37C2 +:103F0000F140A6843C0DFC4E42018873B42149FF68 +:103F1000FF8BD50A49FFE9CC49FFEA0CC8FED5ED75 +:103F200049FFEA08C80349FFEA15B42684003E07A2 +:103F3000F1413E07F13D8401AE0DB426AE0CB4C68E +:103F4000B40649FFFF905A080141AE37D53EA6445A +:103F5000C90549FFFDA8C039D50DA6055A080108B5 +:103F600049FFE9E8C83249FFE9F5D52F49FFFD8D42 +:103F7000C8F849FFE9DF80E0C82849FFFD6E3C0D25 +:103F8000FC74B4262E97F13EA6843C0DFC4EB42161 +:103F90004204887349FFFF482E17F13D5A1801115A +:103FA0002E57F1404C54C00DB4063E77F13DAE455E +:103FB000B4E6B40749FFFF575A080103AE3F49FF73 +:103FC000E9C9B4068421AE44FCC0FC20804080E1F5 +:103FD0004402BB64A0514462BB7CB6202E17F1188A +:103FE0003C6FFC4A10100008A052A8414412BB606C +:103FF00049FFFD9D4402BB582E17F118A981AE4020 +:10400000B4273C1FFC474412BB5449FFFF33440212 +:10401000BB488420AE40AE41AE4249FFFD44FCA007 +:104020003C0FFF9BDD9E3C0FFF9ADD9EFC41F5811E +:104030004082801141C2C00A445000FC4201947386 +:10404000005000182260800054A2800122108001DC +:104050004EA2000D4472C7B884A038538C08447235 +:10406000C7A838538C084800007301E000E15BE802 +:10407000030B4452C7B838A28C084452C7A838A2D0 +:104080008C08D5654FE300214472C7B885233853A7 +:104090008C00814542A1A473409508088CA144A2DC +:1040A000C6F4892A9768E6A312648000121480017E +:1040B00038538C08E94C4452C7A8852138928C08A3 +:1040C00039E38C08D5445BE801434492C7B884E3E4 +:1040D00038548C0081E542F19C7340F788084472A3 +:1040E000C6F440F79C008CA19768126780001217F5 +:1040F0008001E6A338548C084452C7A8E90539E288 +:104100008C0838A48C0838528C00CD0538548C00AB +:10411000C51ED50284A3842C4271847384608023DD +:1041200080C3549180FFE325E80E409188088927D9 +:1041300038A38E010294800188CA882997B3964BD0 +:104140008C61D5F0406314D640109436003F80282F +:104150005A380128B4005A0801253C5DFF9BA42D64 +:10416000E280E81F403320014E340003FEDA4000B5 +:10417000F0014E040003FE028803A4EEE003E81100 +:10418000A4EF9F19400184094212707342622073A8 +:1041900088C0880140630CD640100C3697B3964B0C +:1041A000AD90AC51FCC1FC403DCDFF9B2E70043165 +:1041B000005E0016006E0017CF0540A280139771B5 +:1041C000D504445000508145446000FC420198737E +:1041D000B50084DD40F418024492C6E44462C6D4BB +:1041E0004472C2245AF00105000000E0C0188400A7 +:1041F00038048C08840138030C08FAC4FF9C2200A0 +:1042000080004442C21438039A0995B222108001FA +:1042100088C738A20C08AC714800009138030C0024 +:10422000E614E8048C0138030C0838048C0044625E +:10423000C6E4E613E9038400D5028C0138030C08B8 +:1042400038948C00FAC4FF9C02F08000400498006F +:10425000A44938F3820994028807AC41021E000D7C +:10426000E081E90380AAD51003CE000C40FE1007C0 +:10427000E80B8B4540027001420500244040F001EC +:104280004040109688A444A2C2145A8804043855A9 +:104290000C0038450C0084038024421280738C2269 +:1042A000840440008016E0804482C214E8058C81BA +:1042B000E08040023C1B38040C084402C6D4384558 +:1042C0000C0038100C00840AFE44E08140123C1BB4 +:1042D000854040008016806A808A4CA000134054BC +:1042E000980038839611956A88A7888822528001A1 +:1042F00088654E9200048F21D502FB238D41D5EEB7 +:1043000084AA4202142442419424403094B6C50C3D +:1043100088C938339A1195B288C742028C73223308 +:10432000000142428C734030840A88038864400054 +:104330000416401184369603964BAC10AC51FCC069 +:10434000FC41445000FC420194734472C1D8B4A0B3 +:104350002280800023C080014462C19C38138E02F9 +:10436000853D40949402F18144A2C16038130E024D +:104370003C5DFF9B5A900105000000E0C00A02026C +:10438000800F38838E0A39C30E0A38050E0AD541CC +:1043900003E2801140FF1007E9040202800ED511EC +:1043A000029280120202800FE089E80B02F2800E76 +:1043B0008A9E8A0FFF044004F80140020016880F0D +:1043C00038450E0285234240247380040252801037 +:1043D00084848C024000101640928001964B421457 +:1043E000842440428409421070738824401094361B +:1043F00038130E0A221F800238050E0A4214842444 +:104400004210207381218924405494B638538E0A77 +:1044100038038E02AC1038030E02AC11FCC122200E +:104420000000E022E8153C4DFF9A023200098E613F +:104430008A61E043E80D22200001E022E80902023F +:10444000000A8E018A01E04056078001DD9E84014A +:10445000DD9EFC0194928822F08122308000960338 +:10446000E060E8045231843796DB2200800122FFAD +:104470008003E00FE8045200096B9603E0604001FE +:10448000BC1BFC81FC0196435EF0821D9010E90488 +:1044900052108438964B5EF004B7E9045200096C60 +:1044A0009603E0204000BC1BFC81442000FC42003D +:1044B0008873B4205A1802058420101000F7DD9E7E +:1044C000FC41F60BF081440000FC42230073000124 +:1044D00000188122960EC85AB4028E01E602E856F0 +:1044E0003C83F43C50047FFF960042732024C00BB1 +:1044F0009887945288238E010410FFFF960038118C +:104500008A0AD5F6400408080474803BFE343871EA +:10451000800A01C480F35BC0093A5CF289C4E836C2 +:10452000F0018144B67F49FFFFAF5EF00065E80708 +:104530004402E1B0380018005A080129840A4213E5 +:1045400080244603FFFF9CB150000FFF42012073FF +:10455000B45F380102028447FE14E220E8174FC31B +:10456000000B3C0DFA9AB40092069606C80444006B +:104570003840D50344000E1038051A0AF00A842684 +:10458000381018088409100480F3FCC1442000FC92 +:1045900042008873B4604422BD745A38051D00304F +:1045A00000F75A38011144000064380105092E074C +:1045B000F338E603E9043E300463D50D8C013E0771 +:1045C000F338D50984003E07F3383E0004638400C5 +:1045D0003801050938010501C00C8E014422BD7463 +:1045E000960138010509C8053E07F3383E0004630B +:1045F000DD9E444000FC42019073000000F35A002D +:1046000006045A08090A8823A608C0048E01AE08C9 +:10461000DD9E38010E0ADD9EFC21F381F3093C7317 +:10462000F43D8843A710E287E8238C81AF10444013 +:1046300000FC4201907394DA998B3C13F4778480E8 +:10464000FE4C104000F3B626A6504C13C012842135 +:10465000101000F3F008B0418803844480E549005D +:10466000737D3C03F475FE04B6068400B607FCA116 +:10467000FC01956A8885F081222200009603E040C3 +:10468000E8045221043796932202000122FF80039E +:10469000E00FE8045200096B96038825E0404001D2 +:1046A0003C1BB44142300024E262E80DE406E90418 +:1046B0008E05FE04B6013C03F475B441FE04E240ED +:1046C000E802B601FC81443000FC42010C7300306A +:1046D00000F5CB090430003B5EF19771E904846179 +:1046E000103000F5003000F55A38011394D288617B +:1046F000B4835CF20E10E80444400E10B683000050 +:1047000000F35A0801063C03F475FE04B6033C0DA1 +:10471000FA9AB400920296065A08010F2E00044F2E +:104720005A08010B94928822B4015CF007E9E8046E +:10473000440007E9B601DD9E2E3004635A380117A4 +:1047400094D28823B4615CF1A710E80444302710A8 +:10475000B661443000FC42010C73000000F35A08BB +:1047600001063C03F475FE04B601DD9EFC01F081F8 +:10477000F007444000FC42101073004080F9CC1D4B +:1047800022508006C50E3C6DFF9A024300098E81BF +:10479000D40822508007C5050243000A8E81DC0D33 +:1047A0008482104080F984863841800844301900A2 +:1047B0003831020A104080F3FC810000FC41F70A06 +:1047C000F481953A40A11000B44AE241E845441012 +:1047D00000FC4203847380C0000000F3E602E80599 +:1047E000000300DE5A000139840F100300F8B041C5 +:1047F000982C84448123490072B18400B60A2E00AB +:104800000431C0028409B60A840038049C080003FD +:1048100000F3E60EE82144F047243807800040F01A +:104820003C00DD0F0E1232321A321E3232163222A4 +:1048300032268403D50C8402D50A840AD50884055F +:10484000D5068407D504840CD502840E100300F32A +:104850008401100300F6FCC1442000FC4200887370 +:10486000001000F65A1803058428101000F3DD9E8E +:10487000FC003C13F479840F49FFE8863C0BF43DBF +:104880003C13F479840449FFE87F3C0BF43CFC8042 +:1048900080413C53F4783C13F479D108FC009982B0 +:1048A000A63049FFE877AE30FC80DD9EFC0196CB58 +:1048B0009683903090108A018A43FE044201087367 +:1048C000FC81FC41810084003E00046249FFE496C3 +:1048D0005A080242812884C04421869F000480F740 +:1048E0005A0001098CC197B0509480FC5A680AF8AC +:1048F000D527040480165A0801F7814884E0503413 +:10490000800C000500F75A08011505C500165BC8A4 +:1049100001114C63800FB40304150003F281B67FCC +:1049200049FFFFC6F201B47FE240E9033FC00462E1 +:104930008CE197F850A500FC5A780AE5D5D42E00F2 +:1049400004625A08010544000053D503440000A73F +:104950003C0FF243FCC1FC43F085000F803CF18426 +:10496000E603F281810305CF800EF710E90B2E17C5 +:10497000E968C90DE606E80B44A00078852F84C8D5 +:10498000D50A44A00078852384C5D50544A0003C01 +:10499000FB2EFAC03C0DFA9AB400920296065A0811 +:1049A000010A2E00044F5A08010644A0003CFB24D3 +:1049B000FAC92E000431C00544A0003CFB2EFAC009 +:1049C000F004F105F583F48249FFFF725CF009C43D +:1049D000E83FF402FFB4E286F503E83741CE1C005D +:1049E000000E0000E340E824947A38229E0188A15A +:1049F000F105A42940004008FE1749FFFF59E206CF +:104A0000E815F00549FFFD405EF00065E90F440040 +:104A100000FC04AF800142A380734214A4248404E8 +:104A200038141E0A100500F3D5138400D50BC807EF +:104A3000943A8805B045844449007190000E000006 +:104A40008C01100E0000D5048400380E1C08FCC335 +:104A5000FC4199DCF081A638E615E9374402BD3403 +:104A6000814138001202F10180C4812249FFFF20F8 +:104A70005CF00384E826440000FC3C33F43C42A391 +:104A80000073840042130C248080E283E80E98A116 +:104A90000455003B38248A028A454E240003FE92C6 +:104AA0008C8188029720D5F28E6140F00DF75CF77B +:104AB00081918401E80284003E00044F8400D512F5 +:104AC00084003E00044FD50EC80C4412BD34022FA2 +:104AD00080023820920995228881021F8003AC61F0 +:104AE0008C01AE383C0DFA9AB40092029606C803C7 +:104AF0003E00044FFCC1FC4180E2812180458024BE +:104B000080C5F0818103814449FFFCA5441000FC6D +:104B100042730473001380F85A180F2638141901D1 +:104B20008C2FE201E8048400100380F4000380F479 +:104B30005A08011A95B28926F00102248001021454 +:104B4000800040214008FE5749FFFEB2E609E80810 +:104B5000400518008029844449007100D504840070 +:104B6000100380F4FCC1FC418501B61F80818120C7 +:104B7000838185404004A001E320405E28014C571A +:104B800080234074A000E2E9400E280040678000C6 +:104B900040037C0892E1FFC792C1800780268047CE +:104BA0008066F481490070BAF401E281E9094C128F +:104BB0004005B43FE220E90481078146D5DC812726 +:104BC0008386D5D9E602E8DE8008802AFCC1FC4253 +:104BD000F60DF083440000FC42330073000180F6C0 +:104BE00081428385048F800C81235A08016E003135 +:104BF00080F35A3802073C73F474100480F4D5191A +:104C00005A3803053C73F474D5145A38050510045A +:104C100080F4D50D5A30070C5A300AF6540180FD45 +:104C200084E05A080C0744700078D50344700032C1 +:104C30003C2DFA9AB402920696065A08010495F998 +:104C400097F92E07E97BE603E80B8E62E662E80837 +:104C5000B40292069606C8048405FFC497F994F23C +:104C60004402BD14990B8440802438201909400463 +:104C70000C008444F382F48149007070F0038028B2 +:104C8000804649FFFBE8E207F401F302E804380E2E +:104C90001909D503387E19099431881CA440C90329 +:104CA0008421AC4040150C00A420A5484422BCD867 +:104CB0008A05A44938011A09A42188628A01AC191D +:104CC0008402100480F6000480F85A080F61000482 +:104CD00080F64432BD1495F25A08030F40051C00BB +:104CE000B0438444F38149007039F301380E19014F +:104CF00038019909D54C004480F4CC1C38141A01B1 +:104D00008907F00302240001F38240214008FE5786 +:104D1000F48149FFFDCDF401802449FFFF26F30211 +:104D200096013C0BF94E38119901E220E803380155 +:104D30009909957188BC38119901A428E220E908E5 +:104D40004412BD14380099098403100480F6381108 +:104D500099014432BCD8A52838019A119AA1FE14B1 +:104D6000022F80068947400010169A101205000095 +:104D700088E3A4A8223380019A1142118024020FF3 +:104D80008007401088369A4112150001FCC2FC428F +:104D90002240800022608001441000FC42018473A4 +:104DA000B520F2824412BC98955A3C7DFF9B5A98DC +:104DB0000116AD10AD9138408E09A63D8825AD890C +:104DC0005A000104480000F24402BC5C88A0842020 +:104DD00038100E09AC69480000E9A6BD00A0001813 +:104DE000F2835A28014054050002C03C4402BC5CD6 +:104DF00038700E11CF0888A022028001C0333840DD +:104E00008E11D530880522000001C80588A12262D4 +:104E10008001D52888A181E422428001529380003C +:104E2000FFE438408E114250002442701075424415 +:104E3000A4244082900043C0242442423C24424E99 +:104E4000187542401C75FE0242002424FFAC4260EB +:104E50003C7342649C7540422096406320D6972361 +:104E600097B3540500024E0200833C0DFF9A80E484 +:104E700002A00009E08AE90838908E11E12AE80FC3 +:104E800050957FFFD50C4E44000838908E114E95FA +:104E900000078520D50481248500D50285010250B4 +:104EA000000A41E18808E0C58006E90A4080F80070 +:104EB00022840001E105E8105082FFFFD50D4E6409 +:104EC00000094080F800228400014E840069D50466 +:104ED0005A88014E810639C08E1141E0F800402207 +:104EE0007001B65F222F0001F28140F30801B45F28 +:104EF000C20C84024001001641E4F001420F3C73F1 +:104F000040000816F2018802E80DF20184E241E453 +:104F10000801B45F40779CF6427F08734073BCF68B +:104F200088FCF2014C81003EE0EAE90552A500014F +:104F30008947D5054E74003652A380004C9E000C64 +:104F4000E005E9055252800188A0D5064E04000410 +:104F5000FF42D50284A0E0AAE8054044801197836F +:104F6000D506E145E804973B40640011F203941A2A +:104F70005A28010E38708E014452BC5C9BE738728F +:104F80008E0999C888A0A5F99BF7ADE938408E092C +:104F90008820F002AD89AD00AD81D5078500D59C94 +:104FA00085404C9E7FCFD5E3FCC2FC402260800050 +:104FB000225080014412D560AD90AD513870900000 +:104FC0003C6BF9103C5BF9115A7801174492D78871 +:104FD000386491094492D150385491094492D08058 +:104FE0003864920A4462D45C3853120A4452BC4872 +:104FF00038729008D5665A78026544A2BC48387564 +:105000001000E6EAE8124482D0808CE13894120263 +:105010003875100889263894120A4482D45C389472 +:10502000120289253894120A4472D78838A3911144 +:10503000407518014E740003FFFA5EF380B5449288 +:10504000D150E9103884911150F2800E40F7A0073A +:10505000E8125EF380DDE9095072800FE0E8E90BA9 +:10506000D5045EF38051E90A3884911150F2FFF1C2 +:10507000E10FE80484E438709008387491115EF30D +:1050800084B6E80550938028E125D508449004B6FD +:105090004C74800950F3FFD8E0AFE80485233890C2 +:1050A0009008389090008F23E722E80B4492D54C6B +:1050B0008ACA386491094462D13C8AA738531109DD +:1050C000385090005A5010045A58202384A0385168 +:1050D000920A4432D78838319111ACD038509000C0 +:1050E000443000FC42020C735A581008846B103094 +:1050F00000F34400096BD508846D103000F34402BE +:10510000D15038001111AC118400380090083800DB +:1051100090005A08051E4402E1B08421381010089E +:105120004402BC48383010004402D08038101202CB +:105130004402D45C40108C3638001202AC5040005F +:105140000C16AC114402D560842038101008FCC045 +:10515000FC45F0852E07E97B049F8005F08722003F +:105160008000F2863C0BFB9222008001843D3C0BC8 +:10517000FB93440000FC42918073B40980C3FE0E8F +:105180004482C14C44A2C13C5A000105000480E0A5 +:10519000C04D3C13F4774442C100FE4C84003812E9 +:1051A0001A0A3C13F43C380418083805180810048F +:1051B00080F3100480F4100480F5100480F684015C +:1051C000100480F74223042484004432BF20E2010B +:1051D000E80999C204A4803B8C0138A19E0A96007C +:1051E000D5F794F24472BEE498BBF005886444128B +:1051F000C15C808649FFFEDB4402BEA838A39A0248 +:105200004410003238A01A0A4402C15C49FFF9096F +:105210004412BE78100480F98400380098084412C3 +:10522000BE6838009808480000BB4472BEA83C1D08 +:10523000FDC938038E0249FFFB3BF08980268008B8 +:1052400049FFFB28FA00100480F8000480F381274E +:10525000E602E827B1493C3DFDC94442BF20F005C4 +:105260008048B6FFF6814412C10049FFF9D7F00526 +:1052700080464412C10049FFFA28F00580464412D6 +:10528000C10049FFFA5B3C0DFDC94412C100442234 +:10529000BE984432BE88808780A649FFF9EBD53698 +:1052A0009E42E622E9085A0005079E47E622E903E6 +:1052B0005A080A2DF005802649FFFAD0F00580260D +:1052C00049FFF8F54402BE78B61FF0074412BEE469 +:1052D000F081F6823C0DFDC938109A02F205443285 +:1052E000C100F4094452BE2C49FFFB37B73FF68199 +:1052F0003C0DFDC9F1054422C1004432C13C444289 +:10530000BE984452BE8849FFFA333C0DFDC9F105F1 +:105310004422BF204432BE68808649FFFB9B444242 +:10532000C100F5093C0DFDC94412BEA8F205443286 +:10533000BF20B75FF68149FFF8C5F0054412C13CB4 +:105340004422C100806649FFF9564472BD94F005BD +:10535000F1094422C1004432C13C3C4DFDC94452D4 +:10536000BEA8B6DF49FFFA2C3C0DFDC94412BDF0C2 +:105370004422BEE4F3054442C1004452BDD0B6FF0E +:10538000F68149FFFC263C0DFDC94412BDF0F20533 +:105390004432BDD0808780A649FFFBAF4412BEE4F3 +:1053A000F20638009A11AC109432880122000001F4 +:1053B000AC113C1DFDC94402BDF038101A0AFCC5F1 +:1053C000FC408140440000FC4232807300018018A0 +:1053D00080E4960680C54492BC0CC0098402380162 +:1053E00014088400380094088400D54A41C0940011 +:1053F000000E0000E603E8048C01100E000040815E +:10540000180000040000E602E9038400D5028C01C4 +:1054100010040000A479A4B84010C008FE57380456 +:105420009A0249FFFA4544100064FE0C842049FFAB +:10543000FB9C8080846300040000FEF4880384A049 +:105440003845020A94DA000E0000886A8025E2A03E +:10545000E806382196028CA18822D5FA402004095A +:105460008841401100369A8C80014E240003FE9240 +:105470005EF10051E9058C81882440008409A478FC +:1054800038149A0995B288C9A479AC71FCC0FC4360 +:105490003C1DFF9BF0823C0DFA1DA44DE201E80487 +:1054A0008C013C0FFA1DF00284C05070000C3C0DC2 +:1054B000FF9A00300009E2C34EF200910403FFFDA1 +:1054C0004E0200845A08050448000080A43A4412A1 +:1054D000C7DC120F800AA43B4422C7CC120F800BFA +:1054E000A438F30212038067A439B105120380685F +:1054F00080A64402C7EC49FFFF653C9DFF9BF083FB +:10550000B045000480018041B61F8066F0023C4D2A +:10551000FA1D3C5DFF6449FFF58B00048003C00861 +:10552000B045F00280418066F40349FFF63E000476 +:105530008004C008B045F00280418066F40349FF52 +:10554000F701F002F1058046490045F03C0DFF9B54 +:10555000A602C007B045F0028041806649FFFDFA0F +:10556000B0458041F002806649FFE71DB045F0027A +:105570008041806649FFFC0D220F800A4E04000521 +:105580008400120F800A3C1DFF9A222F800A02001D +:105590008009E040E9048E01120F800A220F800B7F +:1055A0004E0400058400120F800B0200800A221FA7 +:1055B000800BE020E9048E01120F800B020F800A9D +:1055C000AC38020F800BAC398026F00249FFF7E0BF +:1055D0008CC1507380FC48FFFF6CF502444000FC16 +:1055E00080C5426190733C27FEC83C17FEC93C0D44 +:1055F000FA1D8066D30CB4855A480507222280061E +:10560000221280078400505280FCD5F53C2BFEC846 +:105610003C1BFEC93C0FFA1DFCC33C0FFF9CDD9EEA +:105620003C0FFF9DDD9EFC44838580C0FAA2B544FB +:1056300042609473409304084055240084C0A7E856 +:10564000B6C2A9915A78FF05B6E3A9D9D514A7E83F +:10565000A1A138631D01447000FF97AFA9D9A1E44F +:10566000B6C395B188C7A7F14C03C005A7B04C13CA +:10567000007884C19FC1B6FF9DC1F781B1C4F0829B +:10568000F0839E09A83AA628F184A8798C21A87BEA +:1056900050007F0184204000800645E00012385F02 +:1056A0008602E6B2E81A388386025CF40024E81524 +:1056B00042547873385515005A50FF100482000187 +:1056C000C80638041501962FB603D506380415010F +:1056D000B4A3962FD80684018C215A1804E2D5452C +:1056E000842045E00012380F8602E612E835384380 +:1056F00086025CF20024E8304202787338450100EB +:105700005A40FF2B385E0111380E2411E005E824C1 +:105710009A2838541101976F5A60010CC6045A60D8 +:105720000211D520B6A3B48284C18804B602D51470 +:10573000B483D409A959A11184C28804A811D50C35 +:10574000B483DC05B4828804B602D506A119DC0C4A +:10575000A1118804A8118C215A1804C7D50384010B +:10576000D5048006D5028403FCC4FC4A80C08400B2 +:10577000F283B63FB08A8060B43FE201E808944308 +:1057800088248C01A04938310408D5F784A0B08A58 +:105790008781B41FE2A0E857942B880405E3000139 +:1057A000A001383F01014C30404D38010C00C84980 +:1057B000945AF181D04294438824049F8001A1C966 +:1057C000A07540F0A40000978002149F800200970B +:1057D0008000149F80040097800100F78003149FCD +:1057E000800540938808882950F780010080800355 +:1057F00000A0800000908001A64A8E2140F7840717 +:10580000E91CF1028D018E21E101E917F1058F41BB +:105810008C21E02AE912F1048D218E21E121E90D8C +:10582000380F1D0139C10C084C03C00C38110000A1 +:10583000C90839C10008D505B43F8C01E201E9BBB4 +:105840008CA1D5A885002E07E942E3004EF20104A1 +:10585000A031385021014C5440FCB00A38002000DF +:105860005A000104480000F5A075400408088801AA +:10587000A7C2E6E2E9048EE197F8D50284E0A643E8 +:105880005CF08022E8048C219648D502FA33F1843A +:10589000A640E622E9048E219648D5028420A6017E +:1058A000F181E610E8048C019600D502FA01F0853A +:1058B000FA02FE3CF082F004E0074EF300CA04AFA7 +:1058C0008001F002F103880A940140908000F00505 +:1058D000E00A4EF300B9F00341C48001B406881C0D +:1058E000A6405A18FF04480000AB20000001221413 +:1058F00080004E0500A54E1700A3B41FE6064EF229 +:105900000098800A8027B086B0C88086F50349FFDA +:10591000FE8C5A0002044800008CB406A0F1F10885 +:10592000380070003851850138018101962FD93F28 +:10593000B04A381094005A18013BF10622F4800056 +:10594000F2074240BC24884140120836A136D819DB +:105950009482996240178401B44542250475B64586 +:10596000F208A13794928844B48242438475B68287 +:10597000F2080443000894928844B4829A61D516D0 +:10598000956A88A4A137B44542250473B645F20848 +:1059900094928844B48242438473B682F2080443EA +:1059A000000894928844B4828824B622F1093851C0 +:1059B0008501D93EB04A381094005A18013AF107CF +:1059C00022348000F20642408C248841401208367E +:1059D000A0B6D818940299509A59B4054205047596 +:1059E000B605F009A0B794028802B440422384753A +:1059F000B640F0090423000894028802B4409A518A +:105A0000D516956A88A2A0B7B40542050473B605F9 +:105A1000F00994028802B44042238473B640F0092E +:105A20000423000894028802B4408822B620B406F9 +:105A3000442FFF80881CA641FE57AE418D418D2228 +:105A400048FFFF47F0028CE18C1248FFFF358D01C3 +:105A500048FFFEFBFCCAFC403CADFF9D80C184E0DA +:105A600085019B31E282E832A1470843000101C56C +:105A7000003238F292020450000838929202A14695 +:105A800038529202425E14244052A4B7AD580045E9 +:105A900000334247902440422497AD192EF7C5DBCE +:105AA000E8135052FF8797695CF28347E808504239 +:105AB0007F8797215CF2087BE80288E95CF38DAD73 +:105AC000E9033E8004608C68D5CDFCC0FC41812098 +:105AD0008400B63F80E4AE28F28180C53C0DFF9D76 +:105AE00084204442C8B0E223E811042480013851E4 +:105AF0000501D91EA6B038120808A6B08C419690B0 +:105B0000AEB000500019E245E9138009A670B45FF9 +:105B1000F301808749FFFE2B8009A6B04412C8B06C +:105B2000806749FFFF9A84004422C8B0D5038C21C6 +:105B3000D5DBA670E201E8089443383100008827DD +:105B40008C01A8C9D5F7FCC1FC202E07E949FD321C +:105B50005A0801053C0C0180D50E9E0CE602E904B2 +:105B60008E28E622E8043C0C017CD5052E07E96866 +:105B700049000786B607B4073C1C017A4C00800A2E +:105B80003C1C017B4C0080063C1C01874C00C0047F +:105B90008421D5028420445E000088A03C0FFAA432 +:105BA00092A244027B9097693E17E927AD404403D7 +:105BB000F40044101EE4AC404403F40297B0AF80FC +:105BC000FCA084003C0FFAD64403F4038421AE40C9 +:105BD000DD9E4403F403A6005C000001DD9E440347 +:105BE000F40CA6009600C8074413F3CFA648400063 +:105BF0000406DD9E8401DD9E4413F40384003C0F03 +:105C0000FAD6AE08DD9EFC005A08011349FFDAF609 +:105C10005A0802074403F010441FFFAAAE4049FF90 +:105C2000FFD284003C0BF4DD3E07E959D50349FF60 +:105C3000FFE5FC804403F01DA680A641A6C04010ED +:105C4000A008FE57581084009688AE809228A6813E +:105C5000AE414413F42144200055AE884420000096 +:105C60004430000A502100014C21FFFE8440AE88E0 +:105C7000442000004430000A502100014C21FFFE66 +:105C8000A6409648AE40DD9E84004442D4EC445287 +:105C9000D2284412D1744432D5E43822800038220C +:105CA000000838218000382080088C015A0820F72D +:105CB000DD9EA640A7053E100D00A641A6C73E10DA +:105CC0000D01A642404220083E100D02A64340317D +:105CD000A0083E100D03A644002000088881A646B7 +:105CE000972388610010000996DB4010A0088822E5 +:105CF0003C1806840010000B0020000A4010A00889 +:105D000088223C1806850010000C3C4806823E1094 +:105D10000D0C0010000D3C3806833E100D0D0010D8 +:105D2000000E96463E100D0E0010000E9221964673 +:105D30003E100D0F0010000E922296463E100D10E0 +:105D40000010000E922396463E100D110010000F19 +:105D5000965F3E100D120010000F92243E100D139E +:105D600000100011002000104010A00888223C18EC +:105D7000068A00100013002000124010A00888229C +:105D80003C18068B0020001500100014968F40214F +:105D90002008884196933C28068C0010001592221A +:105DA0003E100D1A0010001700500016964F4010BC +:105DB000A0088825964B3C18068E0050001792A22A +:105DC0003E500D1E0000001E962F3E000D28400282 +:105DD0002C0A9606C006440FF000FF073C480682D6 +:105DE0004001AC0A9606C006440FF000FEC73C38DE +:105DF00006834001240AC006440FFC00FE873C28AD +:105E0000068C4000A40AC006440FFC00FE473C1864 +:105E1000068EDD9E3C1C017A440E00008801920231 +:105E200044127B909601AC08DD9EFC004423F6A84A +:105E30004413F6A95A080105AE108407D50384005F +:105E4000AE10AE08840080208040FA6F4900141222 +:105E5000FC80FC20B48084608C8484E6B4045A38CE +:105E60000506920A40002808D504921E40007808D2 +:105E700042219C24969084A05A20200C38608800EF +:105E80008C414063140C8CA5880696905A581EF6D7 +:105E90008C6196D8AA215A3806E3FCA0FC00B48095 +:105EA00084408C9C840080A098D096D8958238300D +:105EB0008C008C0196DF4031980C88A35A0808F6B4 +:105EC0008C489690AB615A2820EFFC80FC04A649D0 +:105ED000B4405A1003045A180D112E17E9685420C3 +:105EE00080FBCA044412D718D5055A18032544125A +:105EF000D52049FFFFD5D51F5A180408A057841094 +:105F0000FE0E58000003D5165030FFF6E662E80A90 +:105F1000842084463820FC088C215A1820FD803FBC +:105F2000D5E98E28E622E807A0578410FE0E580017 +:105F30000004A817FC84FC00A68180C05A20031529 +:105F40005A2006139E14E602E90F50017FF8E6027C +:105F5000E90D50017FF6E602E9095A280D1C49FFB8 +:105F6000D94D5A0802048400D50284013E07E90A8B +:105F70002E07E90AA6712E27E92084812E37E93DF4 +:105F80004452B4E049FFFDE24402B4E0802649FFF8 +:105F9000FF9FFC80FC00B48084405042002C8400B1 +:105FA00080A098D096D8958238308C008C0196DFEE +:105FB0004031980C88A35A0808F68C489690AB613B +:105FC0005A2820EFFC80FC014412D4ECF08149FFF8 +:105FD000FF42F0014412D17449FFFFDEFC81FC4412 +:105FE0002E200D124472D718812038638800444255 +:105FF000D4EC8EC25C6300014402D1742E300D01DA +:106000005A18063C842A38120808E662842238109E +:106010000808E96B49FFD8F25A08026884005A98C8 +:1060200003182E100D0184004432D5203821800041 +:10603000382F80088C015A0820FB2E000D12C00F4B +:10604000881F8E228440E24110F07FFFD50838136C +:106050008000381F80088C015A0820FB2E000D128A +:1060600084295A600103842A381F80084402B4E05E +:10607000803F49FFFF15D539842038120808501495 +:10608000FFFDE6228423E9028421E6623810080835 +:10609000E92C49FFD8B35A08022984005A980319F9 +:1060A0002E000D0184285A080203842784004432FC +:1060B000D52038218000382F80088C015A0820FB19 +:1060C0002E000D12C00C881F10107FFFD50838134A +:1060D0008000381F80088C015A0820FB5A6801C8CC +:1060E0002E000D128422D5C14402B4E049FFFF6D99 +:1060F000FCC43C4C0187442200FC54000FFF0412F6 +:1061000000124000480892305410FFFF944A882241 +:10611000462C003F0430800850210FFFFED6FEC7FA +:10612000143080080412001244320150923054108E +:10613000FFFF944A882304308008FE9EFE871420C7 +:106140008008DD9EFC00441290743800811149FFE4 +:10615000FFD2FC80FC4180C081223C0D98BBF081C5 +:10616000CE04AF908441D50E80E15A6804068001C8 +:1061700049FFFFEAD504B0013860040010748000C4 +:10618000844384004432D174386180088C01441205 +:10619000D1745A0820FB2E000D12382080084402CA +:1061A000B4E049FFFEF9FCC1FC0180C03E07E9688C +:1061B0008001B65FF38149FFFEC08006B43FF20163 +:1061C00049FFFFCAFC81FC4084003E07E90A3C0D00 +:1061D000FA9784232E67E957A7C1AE4149FFFD56C0 +:1061E000840080404432B38F3C1DFA972E97E968B3 +:1061F00049FFFFDC4402B4E04412D22849FFFE2BE1 +:1062000084033C1DFA9780464432B38F49FFFFCE8A +:10621000E7228403E80284003E07E9684412D2289A +:106220004402B4E049FFFE172E07E9683C1DFA97C7 +:1062300080464432B38F49FFFFB92E07E9683E0715 +:10624000E9503C0DFA97AFC1FCC0FC002E27FE962A +:1062500084C34011185744300090969044125F60F8 +:1062600042110C734420004849FFDA562E07FE966F +:106270008C0196004060183796484010041B3E176A +:10628000FE96FC80FC002E27FE9584C34011185713 +:1062900044300120969044125C0042110C7344205B +:1062A000009049FFDA392E07FE958C019600406078 +:1062B000183796484010041B3E17FE95FC8084005A +:1062C0003C0BF4E13C0BF4D22E07E968540000FBD0 +:1062D000C812440228384412283AA6004422283B17 +:1062E0003C0BF4D244022839A600A648A6903C2BC9 +:1062F000F4E1D5235A080120840044522838802034 +:1063000044322850A7283C23F4D28CA488443C2B48 +:10631000F4D20022FFFD88020022FFFE0042FFFFB0 +:1063200088223C23F4E19601884496493C2BF4E111 +:10633000DBEAD503840080203C23F4E188223C235F +:10634000F4D29649880296013C1BF4E188203C0B6C +:10635000F4D23C1BF4DFDD9EFC02F082F183B65FD9 +:106360008002F1028043F38149FFD9D6B41FF103C3 +:10637000F20149FFD9D1FC82FC00846080A384DF54 +:106380009718E282E80738500D0938608D098C6152 +:10639000D5F8FC80FC56F08384C0F181F282842021 +:1063A00044200090B00880E38124126F800B4900E4 +:1063B00064DF8401100F801A100F801E3C0DFAA5B7 +:1063C000107F8018107F801B1260000C1260000D7F +:1063D0003C0DFA7C109F8019107F801C106F801F6D +:1063E000109F801D49001012B0078040B046490040 +:1063F00010483C0DFAA5FA231010000AAD84840061 +:1064000049001102F001F1038040490010044403E7 +:10641000F04A44100055AE4049000FF34413F140D8 +:10642000A6085A0001FFB0078040B0464900102975 +:106430003C0DFAA5FA241010000AF002F103804086 +:1064400049000FE94403F04A44100055AE404900AA +:106450000FD84413F140A6085A0001FF8401B04749 +:106460008041100F8019100F801DB00649001009DF +:10647000F001F102B08849000FCE3C0DFAA5FA21D7 +:106480001010000A4403F04A44100055AE40490081 +:106490000FB84413F140A6085A0001FF8400B0472A +:1064A000100F801E100F801F84018041100F801D6F +:1064B000B006107F801C49000FE4501F80168041F9 +:1064C000B00849000FA83C0DFAA5FA231010000AE5 +:1064D0004403F04A44100055AE4049000F92441363 +:1064E000F140A6085A0001FF020F800BFCD6FC0009 +:1064F0004440012080C1441200004210107380010A +:106500008481802280434430004849FFFF45AC30FD +:10651000FC80FC00EED8F08184003C080210B066DC +:10652000B00244224A204430004849FFFF17B042DD +:10653000B0A644300048848344025F6049FFFF2CCA +:106540003C080210B042B0A6443000488481F001FB +:1065500049FFFF223C08021044124A20F00149FF83 +:10656000FE762E07E9685A0804153C03F4C45CF073 +:106570000097E90B9E8150107F6A440FFFCE4000C8 +:10658000801688029601D503440000963C0BF4C4A3 +:1065900049FFD6343C1DFFA60220800E5A00020897 +:1065A0008403FE8496914430FFFFD5030030802A97 +:1065B0002E47E8C83C000210401204098801400040 +:1065C00010169601E2403C080210E80584023E00E5 +:1065D0000424D5212E27E9682E100424CA093C235F +:1065E000F4DFE262E8058C213E100424D514C104D6 +:1065F0008E213E1004243C13F4EDE220E9093C0313 +:10660000FF454410EA5FE220E9068C01D5028400D0 +:106610003C0BFF452E000424E6028401E8028400BE +:106620003E000422ED28FC80944988204430FFFF7E +:1066300084404C00800EA500E244E803A4809691BB +:10664000A500E283E803A4C096D98C02D5F35CF1DF +:1066500080978003E903440000969A109601DD9E1E +:10666000FC4244600240FF8444A200004003280032 +:10667000812144120002F381F48280E28826804066 +:10668000443000908481FAA049000F6F50830120AC +:10669000838614AF8003F003FA3440AE0000800A12 +:1066A00049FFFFC40A138001E220E8031203FFFF41 +:1066B000F302F101402E18018822800A8843848168 +:1066C000FA7449FFFE690A148001E220E80312040B +:1066D000FFFF51CE00484DC47FE0FCC2FC002E00FD +:1066E00004152E10044EC01E3C0DF2485A18010429 +:1066F0009201D50292023C2C01079601E2402E0045 +:106700000425E805E61EE80E8C01D50AC00B5CF1F5 +:106710000E10E905E60FE9038E05D5028E013E0055 +:1067200004255A18010D2E0004255A081E0484055C +:10673000D508E6148406E8058407D503490013222A +:106740003C0FFA99FC803C33FF455CF18033E91043 +:106750009491884184A34C11000CA5080A300001D3 +:10676000FF2C9082926288641A308001D5F5DD9EFC +:1067700084003E00042484003C0BFF45DD9EFC00A9 +:106780003C03FF455CF00033E90649FFFFF384005A +:106790003C0BF4C33C03FF445CF00033E904840089 +:1067A0003C0BFF44FC80FC0080C084003C0BF4DF09 +:1067B00049FFFD872E07E8C8406300D649FFD51E74 +:1067C0003C13E32C5A0002088403FE44964944001B +:1067D000FFFFD5053C0DFFA60000002B2E20046412 +:1067E0005A28010A84003C0BF4DFC11B2E07E97B09 +:1067F000C009D50BE2C1E8153C13F4DFE201E8F76C +:10680000D5102E000432C0038401D50C3C1C0110AD +:106810005CF08078E9093E0004643C0BFF44D50538 +:1068200084003E0004648401FC80FC20540000FBD2 +:10683000C00644725C0044600090D50544725F60FD +:10684000446000482E07E92E8E01E602E808440263 +:106850004B4044124A20804649FFD75E2E07E92E5E +:10686000540000FD5A08011095B184A044324B40F9 +:1068700098AB987D8403A5108E013840980DC8FC14 +:106880008CA2DEF7FCA0FC0049FFFF7B2E07E96825 +:10689000540000FBC80A44020A203C1C0277442032 +:1068A000004849FFD739D50D44020A2044120A2274 +:1068B0003C2C0277443000908481FAA049000E55A8 +:1068C0002E07E92EC00A49FFFF552E07E96849FF48 +:1068D000FFAE84003E07E92EFC802E10044E5A18AD +:1068E00001052E17C65AD5033C13E3013C2DFA9A35 +:1068F000B442924296865A2801048C3996492E2732 +:10690000E94DCA052E27C65C88229649AC402E1751 +:10691000C65AAC44DD9E2E30044E5A380117003062 +:1069200000103E37C909A0053C0FF243A60A3E07F6 +:10693000C954A60B3E07C955A4123C0BE4BFA413CF +:106940003C0BE4C48405D514A6C03E37C909A00396 +:106950003C0FF243A6083E07C954A6093E07C95595 +:10696000A4103C0BE4BFA4113C0BE4C4FA093C0B9B +:10697000E4C02E000431C008440001F43C0BE4C420 +:10698000840F3C0BE4C0DD9EFC405A00010A4462C7 +:106990005C0080864410012044200090D5094462A8 +:1069A0005F6044424A204410009044200048840024 +:1069B00080A0385201098C0196C0E262E9FB84068E +:1069C00094494432000081E080E4810384A00A9469 +:1069D000000102A380004094BD378CA1892A9768EA +:1069E0001A938001DAF58E0196008861C8EE95D180 +:1069F00094C188668423385201018E21964838510B +:106A00009C0DC9FA8C019640E222E9F3FCC0FC40DF +:106A1000848084FF838784C180A4814445E2C8C800 +:106A200002F00000548200FF40F788068120E80F42 +:106A300002F0800040F78C06E80A84C0386F100826 +:106A4000A580E2DCE80883868148D50585E138FF2A +:106A50001008D50284C0029480000AF08001892FBA +:106A6000E3278C818C024074BC1B40543C1B5A4869 +:106A700004D95A60010380AA8005FCC080203C0C28 +:106A8000017AC1195A1801053C0C0182DD9E5A1881 +:106A900003053C0C017BDD9E5A1802053C0C01836A +:106AA000DD9E5A1804053C0C0187DD9E5A1805042A +:106AB0003C0C0188DD9EFC002E67E94DCE353C0C78 +:106AC0000110E614E9313CF7F52A5EF7FFCFE80440 +:106AD0003C6E0110D5294400007049FFCFFA3C6B91 +:106AE000F4DB8006442225B080663C13E2B6E20166 +:106AF000E80698428C01AEC89601D5F83C0C0273AA +:106B00003C1C027549FFD623440000333C0BFF4573 +:106B100044124A203C0C02774420004849FFFE15ED +:106B200084013E07E94DFC8094D988604C018005C2 +:106B30001A200001D5FCDD9E4403F04A44100055A4 +:106B4000AE404413F403A608C8FFDD9EFC00840099 +:106B50003C0FFAD63C0DFAA88421AE4049FFD9C6B5 +:106B60004403F04A44100055AE403C2DFAA8A6500C +:106B70005A1001FF44100055AE404413F403A60818 +:106B80009600C8FE3C1DFAA88441AE883C0E011058 +:106B9000FC80FC0080C049FFFFD13C0DFA973E67A6 +:106BA000E96849FFF9CAFC80FC402E10045E5A18BF +:106BB000011F2E1004155A1801232E100462C91F3C +:106BC00084223E10045E44528F702E77C6CC2E373E +:106BD000E9682E40045E2E900431842080C544A0D4 +:106BE000005A4480007D45C00032D5245A1802085E +:106BF0002E1004155A1001E98420D5E42E10045DEE +:106C00005A1801FCD5DFC31A988100F1002098A919 +:106C100010F10184CC199881C3140021002840F39D +:106C200004001027818C5A98010598B111C1018C7C +:106C30008C219688E247E9E8D50F38F00400D5E8C2 +:106C400000210008D5ED5A4801051081018CD5ECD2 +:106C500010A1018CD5E9FCC04422D02044320000B0 +:106C6000B482A09184A10412001292305410FFFF4C +:106C7000944A88234432015004108008944A923484 +:106C8000964B121000813C1BF4EC041200120421FC +:106C9000001392305410FFFF944A882354217FFF41 +:106CA0004432000C949288430230801B103001045F +:106CB0000230801B9268103001050230801A1030BB +:106CC00001060230801A926810300107A4D31030F8 +:106CD0000108A4D3926810300109A4D11030010A30 +:106CE000A4D192681030010BA0D292785441803F19 +:106CF0000430800F9261FEEE94DFFEE71030010C4D +:106D0000A0920410800F9248FE6E96AF944FFE57EB +:106D10001010010DDD9EFC4280E0812180C28420A4 +:106D2000801FFA40490060242E07FE8CA67844326A +:106D3000B41C4442CEA038118008401498009649F3 +:106D4000C90284213812010984409D4144912D28B3 +:106D500044A00BB8986A9657386184005A60FF0FB8 +:106D600038148800388209014210A8244010A03647 +:106D7000388F9A028828381F9A0A8C415A2808ECC2 +:106D8000842080418061384F86029788E2648C219C +:106D900040233C1B40323C1B5A1804F7E607E8042A +:106DA0003E57FE8CD50484003E07FE8CAEB8FCC274 +:106DB000FC57B186B61FF181844884208006509F1D +:106DC000802049005FD584208009844849005FD035 +:106DD0008400F1013C0802104400009040000416B9 +:106DE000548000FF9401F08244A25F6084E0F001CF +:106DF0004C70003FB00AB05C804849FFFABF505564 +:106E00007CA08005B04AB09C80688481F58349FFEE +:106E1000FAC3920138131D019601E220F503E8033D +:106E200038031D09505281204C557FEDB41F445D3D +:106E3000A0A088AA88A08005B04AB09C8068848100 +:106E4000F58349FFFAA9920138131D019601E2204A +:106E5000F503E80338031D098005802849FFFBE698 +:106E6000920138049D09F0028CE18940D5C1B41F1C +:106E700049FFFA0A49FFD1C23C1DFFA60220800F3C +:106E80005A0002058403FE84969180628026800960 +:106E900049FFFDBF8040100F801738148901500F43 +:106EA00080173823090149FFFF382E07E957003FB3 +:106EB000801738248101381301013C2802108822F0 +:106EC00038448D0138230D018844E041E8069A8A50 +:106ED0005CF100C8E805D5028440100F801794517A +:106EE000443001F440108C37E623E807C90744100A +:106EF00000C740108806D5028423002F80172E5724 +:106F0000FE94DA072E37FE8D88613E37FE8DD5035D +:106F10003E17FE8D2E37FE8DE663E8035A180306F2 +:106F200084003E07FE8D80023E27FE94FCD744126B +:106F3000C8C8380080005A0801052E07C65DDD9ECE +:106F40008401DD9E84004412B41C845F38208008D4 +:106F50008C015A0808FD84003E07FE8CDD9E5A080D +:106F600001068401AE088400D50E3C0DFFA6020088 +:106F7000000FE20440403C1BE283E9F4A410E61E4B +:106F8000E8048C01AC10DD9E8400AE08DD9EFC4060 +:106F9000810184203C1802104462C8C8108100009E +:106FA000842480E2814349FFFF05812038032000CB +:106FB0005A0801102E000424E602E8048C013E0069 +:106FC000042484013E00044E84003C0BF4C2D530FE +:106FD00084004412CE864422B3BC3C3002103C43B1 +:106FE000F4ED49FFFFBE2E000424C0048E013E00D4 +:106FF00004245AA801128400802038230000CA0308 +:107000008C2196498C015A0804FA5A1804063C034C +:10701000FF448C01D50284003C0BFF443C03FF4538 +:107020004410EA5FE220E9048C013C0BFF45840038 +:107030003E0004222E000424C00684013E000422E7 +:1070400010938000FCC0FC408481405010024062DC +:10705000900C4470004888C1FF7C44900120441289 +:1070600000004052900C4210247380019855989D66 +:10707000806749FFF991AC30FCC0FC4051FFFDB086 +:10708000F081F182B67FB00444124A20443000906F +:1070900080E28440F48349FFFD494420FFFF4430EF +:1070A0000090500F813044124A2049FFFD3F3C0DB3 +:1070B000FAA8842184C0AE4084013C6FFAD744937F +:1070C000F04A49000D974480005549FFFB53F001F9 +:1070D0004C600041840085403E07E96D3CAFFAD921 +:1070E00049FFD704108480002E07E96DF102E20108 +:1070F000E8262E17E96D3C0DFAD9E220E8F63CAF00 +:10710000FAD72E07E96DB43F5A780209F203B0C4EA +:10711000504F813049FFFAA6D50BB084503F8130E3 +:107120005A78010549FFF9E5D50349FFFF8E2E077F +:10713000E96D8C0196003E07E96DD5D73C0DFAA8A4 +:1071400084218CC1AE40440FFFAA3E07E92D97B0C1 +:10715000D5BF51FF8250FCC0FC0384208448B0029C +:1071600049005E0684208448B00449005E01840220 +:1071700049FFFD11B0C2B10484018426844249FF55 +:10718000FF7EB042844484024900312A49FFD03650 +:107190003C1DFFA60220800F5A0002058403FE84D6 +:1071A0009691B0428062B00449FFFC33F08149FF00 +:1071B000FECB840249FFFBEA49FFFCC0F001FC83DF +:1071C000FC0180C0840149FFFCE6840184268040E4 +:1071D000B0C1404F840049FFFF525A680105800644 +:1071E00049FFFBD449FFFCAA020F800249FFFADDE8 +:1071F000FC81FC2149FFFB492E07E968C0135A08AE +:107200000453440000323C0BF4ED4412CE8684005B +:107210004422B3BC3C3002104440003249FFFEA17E +:10722000D5073E00044E440000503C0BF4ED3C0CEE +:107230000277842049FFF96F3C0C027744124A2000 +:107240004420004849FFFA812E07E9565A000104FC +:10725000480000BA2E6004225A600104480000B4BD +:1072600084003E0004504400004349FFCC3249FFF3 +:10727000FF7580403C1DFA974432B38F100F800792 +:10728000840349FFF79384003C0BF4C23E07E94DA9 +:107290003E60044E49FFFC5C49FFFA6C3E600450BE +:1072A000480000924400012C3C0BF4ED2E00042316 +:1072B0005A080107440000313C3C0110D5058460A8 +:1072C000C8052E37E94240300C063C0C02772E17D9 +:1072D000E957502F800749FFFE5C2E07E9565A08F0 +:1072E00001732E0004225A0801242E67E9385A68D7 +:1072F00001202E57E957000F8007D06584E0440035 +:1073000000483E70045049FFCBE449FFFC1784035A +:107310003C1DFA97002F80074432B38F49FFF74690 +:107320003E77E94D3E60045049FFFC12D54C3C03CA +:10733000FF445CF000322E000464E902C0085A08E1 +:1073400001433C0C01105CF00078E93D4400004230 +:1073500084C049FFCBBE3C6BFF4449FFFBEF2E07C7 +:10736000E96849FFD22F840149FFFF2CC8232E2052 +:107370000423CA0E3C1DFA974432B38F49FFF71617 +:107380003E67E94D49FFFBE449FFF9F4D51C84034E +:107390003C1DFA972E27E9574432B38F49FFF70671 +:1073A0003C0C01105CF00033E90E84013E07E95B00 +:1073B000D50A84033C1DFA972E27E9574432B38F30 +:1073C00049FFF6F42E07E9683E07E9503C0DFFA699 +:1073D0000000002EC00B3C10021044022D54AC40A3 +:1073E0003C13F4E444022D56AC40FCA1FC002E00FA +:1073F0000D123C1DFAD98C01E220E80449FFF3EBA1 +:10740000C00C84003C0BF4DD49FFF3EBC81749FFC7 +:10741000F75849FFFEF0D5122E07E92B5A0801064E +:107420004402B3F249FFD04C84408401842A806234 +:10743000808080A249FFCF42D5DBFC80FC402E3704 +:10744000E9682E07E9472E17E9252E27E9142E4073 +:107450000D28CB0480A080C1D50580A280C48040C7 +:1074600080813C7C0275FF74FEA48460449211709C +:107470003C03E2B6E260E81A94194010240040A3ED +:10748000800002808000A44802050000FE649A0883 +:10749000FE2C428418244000081640040001960186 +:1074A0008C611205000096D9D5E43C0C02753C1C99 +:1074B000027349FFD14CFCC044524A20442003E8E7 +:1074C00044324AB05A080509A52802128048FE64D1 +:1074D00040108837D5095A08010AA468024280483A +:1074E000FE54401090379649AC688CA2DBECDD9ED0 +:1074F000FC4180C0812181028143F4812E77E968BB +:107500005A080113C1049F49549280FF2E57E9572E +:107510004C5480092E0004235A08010580094900B3 +:1075200012D88403D5095A08020F5A780405840139 +:1075300049FFFFC484003C1DFA9780494432B38F51 +:1075400049FFF6343C1DFAB3A60896005A0801FE1E +:107550003C1DFAA8AE0849FFD4C93C0DFAB3A640B9 +:10756000C9FFA6405A1801FF2E07E96849FFD12A32 +:107570002E07E968C8045A780408D5045A08040597 +:10758000CF0349FFFF5D5A680108106400008400C2 +:1075900010650000D5095A68020A84001004000032 +:1075A000100500008401F101AE08FCC1DD9EFC0065 +:1075B00080C0C82444020A2044125F60442000486E +:1075C00049FFD0AA44020A2044125FF04420004838 +:1075D00049FFD0A244020A2044126080442000489F +:1075E00049FFD09A44020A2044124A20442000480D +:1075F00049FFD0923E600422D51049FFF662440252 +:107600000A20842049FFF78744020A2044124A20B6 +:107610004420004849FFF8992E07E956C8033E0068 +:1076200004222E000422FC80FC40A748CD074460C1 +:1076300000FF80E581258066D5298420446000FF15 +:1076400080E1812180669708E285E820A10138A2C7 +:10765000050197094CA2401904A00005950A888AE3 +:1076600000A20002E34340353C1B00A20003E32AD2 +:1076700040953C1B00A20000A721E34640653C1B4F +:10768000E2E440723C1B8C21D5DF840045C000122F +:10769000E323E92984804281F02480A68024E2E566 +:1076A000E91740A4140040A50408894202F500002F +:1076B00040F780115EF78033E908E6A9E8048C21E1 +:1076C0009648D5038C8197208CA19768D5E9E281F3 +:1076D00040123C1A9708E2804000BC1A8C61960068 +:1076E00096D8D5D7E602E8028402FCC03BFFFCBC7A +:1076F000EFFC49FFCD835A0802124403F04A4410BC +:107700000055AE403C2DFAD4CA0984018020806225 +:10771000808080A249FFCDD2D5F6EC043BFFFC84EB +:10772000DD9E3A6F9EBCEFF080C0A601F282F3832B +:107730005A080408A6305A080105840049000BFEC7 +:107740002E07E9745A08010C4402B3ACF102F203AB +:107750003C3DFAA33C4DFAA149004F25440FFFAA36 +:107760003E07E9703C0DFAA13C1DFA97B61F442272 +:10777000B363F302F4033C5DFAA34402B4AC4900E2 +:10778000503B96003E07E96049004CA52E07E96092 +:107790005A00010584013C0FFABCA6315A080816AC +:1077A000A6305A000204480000A83C0DFAAB5A006B +:1077B000067C5A0009044800009649FFCD1F5A0074 +:1077C000020448000090D5705A08090EA6305A00ED +:1077D0000204480000923C0DFAAB8E06E6024EF21F +:1077E0000082D5625A080A08A6308E02E6024EF2DE +:1077F0000084D55A5A08030DA7B05A68017E800646 +:1078000049000A098006490009F58408D576540024 +:1078100000FD5A080472A6305A08016F490009FB9E +:107820003C0DFAAB5A08060C4403F04A44100055CC +:10783000AE4084003C0FFAD449FFFF5A840149004E +:1078400009D949000C0F3E07E93F49FFCCAB2E5741 +:10785000E95484203E07E90E3E17E91ED00649FF91 +:10786000D09F84013E07E91E2E07E90EA7F13E07CF +:10787000E9545A78061A2E07E93F2E27E936E240E6 +:10788000E91584003E07E9363C0DFA9749FFF355A8 +:107890002E07E968802749FFF3A484013E07E97AAF +:1078A00084003C0BF4D68408D528CA033E07E93689 +:1078B0008404AE312E000D1249000C7C80E0C8F427 +:1078C000840149000B3B800649000B4FF082F10216 +:1078D000840280478461808780A749FFCCEF8408B9 +:1078E000D50C844084618402FA25808380A249FFFC +:1078F000CCE58408D5028401EC103A6F9E84DD9EAD +:107900003BFFFCBC8401EFFC49FFF17F4403F04ADC +:1079100044100055AE404413F403A6085A0001FF7A +:10792000EC043BFFFC84DD9E3A6FA8BCC00349FF1A +:10793000C88E446000654473F04A4490005549FF86 +:10794000CC5DC0128EC1C6108421804180618480CC +:1079500044004F004900334E4400006449FFC848CA +:1079600010938000D5ED84003A6FA88448FFCBD6F1 +:107970002E07E918C8072E07E9608E045C00000294 +:10798000DD9E8400DD9E0000A6C18E63E6694EF296 +:1079900002AA3A6FA4BCEFF480E280C044F078AC55 +:1079A00038378D0140F1BC004A003C0012002E0126 +:1079B000300540023005060370032404BC043C0D6E +:1079C000FAAB5A08091E49FFCC195A08021A440298 +:1079D000B3404412B3E249FFCDF94402B363441209 +:1079E000B36A49FFCDE4840CAE313C0DFA97842094 +:1079F00049FFD0888403AE31FA003C0FFAAB2E0762 +:107A0000C5D2C00F5A0001092E07C5D25A00010481 +:107A100048000266D5363C03E4D2A07BE220E8F5BC +:107A20004403F04A44100055AE404493F04B3C0DE3 +:107A3000FAB3A600C8EA3C0DFAA8A6005A0801E667 +:107A40002E07E92B5A0801064402B3F249FFCD384C +:107A50003C1DFAD92E07C567E220E8EA0004800041 +:107A60004413F04B5A00FF05841FAE08D5FF844035 +:107A70008401842A8062808080A249FFCC1FD5D8EF +:107A80000493800349000A99E320E80AA63A5A00C1 +:107A90000104480002252E00040B4E03022149FF79 +:107AA000DF9A4E03021D4403F04A44100055AE40D5 +:107AB0003C1DFAB3A608C0FF8406AE3184023E071F +:107AC000E97A49FFCB6F3E07E95449000C043C0DAD +:107AD000FAA88420AE40480002032E07E978C826A1 +:107AE0008006490009CF2E07E90FC8074402D404D5 +:107AF00049FFCC6B49000DBE2E07E9785A00031CE4 +:107B000084213C0DFA9749FFCFFD840149000A16F4 +:107B1000800649000A2AF08184408402F1018461D0 +:107B2000808280A249FFCBCAD5065A08030584018A +:107B30003E07E97884003E07E97A2E17E96080065F +:107B400049000E632E07E9345A080104480000AECC +:107B50002E07E9785A080304480000A8A631490016 +:107B60000A1A490009AA3C73F4D6A63149000A1D35 +:107B7000E2E0E8052E07E95A5A0801232E77E920AA +:107B8000440FFFAA3E07E92D97F88406AE315A78D4 +:107B9000011380273C0DFA9749FFCFB480064900B6 +:107BA00009E4F08184408402F1018067808280A230 +:107BB00049FFCB844403F06D8424AE40D5093C0DCD +:107BC000FA97842149FFCF9E8401490009B78006B6 +:107BD000490009CBF081F101EC0C844084028461FE +:107BE000808280A23A6FA48448FFCB682E07E97A8E +:107BF0005A08012F49000ED02E0004325A080115F0 +:107C000049FFCAFC5A0802114900139980C03E0777 +:107C1000E9345A08010A840049001E2584003E60A8 +:107C2000040B3E0004322E07E9345A08010B2E677C +:107C3000E95ACE0749000A343E67E971480001500D +:107C40003C0DFA97842149FFCF5D480001195A0085 +:107C50000204480001452E77E95A5A78010B3C0D81 +:107C6000FA97842049FFCF4E3E77E97A48000138E1 +:107C7000A608C80B2E07E934C8088404AE313C0DB1 +:107C8000FA9749FFF15AD5A149FFFE74C8F72E00B3 +:107C900004325A08010649FFCAB15A0002F03C0DED +:107CA000FA97842049FFCF2EEC0C3A6FA484480049 +:107CB00009F73C0DFAAB5A08062084003E07E97824 +:107CC0003E07E97A3E07E93F3E07E91D4402D40436 +:107CD00049FFCB7B49FFCA92C00749FFCBE63C0373 +:107CE000E4E249FFFE23840349FFC6F3EC0C3A6F3C +:107CF000A48448000A1A5A000904480000F149FF08 +:107D0000CA7D5A000204480000EB3C0DFA9784201B +:107D100049FFCEF88403AE31480000E22E97E9789F +:107D20004E93001B490008AE49000CA43C0DFAA874 +:107D30008421AE402E07E9785A00031480064900DA +:107D40000914F08184618402F1018049808380A953 +:107D500049FFCAB4D5065A98030584013E07E9785D +:107D600080062E17E96049000D502E07E9345A00AD +:107D700001062E07E9785A080307EC0C3A6FA48431 +:107D8000480009D3A63149000906490008963C93EA +:107D9000F4D6A63149000909E320E91285203C0DFB +:107DA000FA9714938003802949FFCEAC840BAE313F +:107DB00084013E07E97A3C9BF4D648000091800696 +:107DC000490008D3F081F10184028440480000801A +:107DD000A6005A08023CA608C8042E07E934C004CD +:107DE0002E07E92FC829A1FB490018A7E2E0E80403 +:107DF0002E07E92FC8744403F04A44100055AE40E2 +:107E00003C1DFAB3A608C0FFA631490008C4F081A2 +:107E1000F1014402B3B04422B40449000A308400A2 +:107E2000842B3C0BF4D6AE7184223E17E97A3C1DBC +:107E3000FAA8AE08D5548400A83BEC0C84011003CA +:107E4000801C3A6FA4844800184B3C0DFAAB5A08CA +:107E500007098409AE3149000968FA003C0FFAAB02 +:107E600084001003801CD53B2E07E97A5A080110C4 +:107E70003C0DFA9749FFF06149FFFD4484023E073B +:107E8000E97A3C0DFAA88420AE40D5295A08022888 +:107E900084003E07E97AA608C8042E07E934C00A20 +:107EA0002E07E92FC0072E07E97D5A00010448FF7D +:107EB000FF668409AE313C0DFA9749FFF03E84001D +:107EC00084401003801CA8BB8402FA26EC0C846159 +:107ED000808380A23A6FA48448FFC9F0EC0C3A6F0B +:107EE000A484DD9E4403F04A44100055AE40441380 +:107EF000F403A6085A0001FFDD9E00003A6FA8BCFB +:107F0000812080E249FFCA0B80C049FFFFED500489 +:107F1000FFFFE60C4EF2018644F07E28380781010F +:107F200040F03C004A003C0018007A005001620218 +:107F3000BA00F802F802F802F802F8028C02DE0237 +:107F40004400003049FFC5C5840EAE398405AE3803 +:107F50003C1DFA9A840010030050B441440FBFFF47 +:107F6000FE16B6014463F04A4490005549FFC946E5 +:107F70005A08020510930000D5FA4403F01084203B +:107F8000AE4049FFC93BC02084218041806180818F +:107F900044005AF04900302E4400006449FFFCC6FA +:107FA000D513840EAE398406AE3884001003005019 +:107FB00080A650030041843F18128001D8FE44037C +:107FC000F0108420AE408007842149FFCD9B84209F +:107FD000840280418461808180A13A6FA88448FF37 +:107FE000C96D4400003149FFC5744403F42985205C +:107FF0001090000049FFF0E984013E97E90AAE388D +:10800000109300502E07E90AA6792E27E9208481D3 +:108010002E37E93D4452B4E049FFED982E07E96858 +:10802000C8084402B4E04412D71849FFEF39D50913 +:108030005A0803084402B4E04412D52049FFEF3047 +:1080400084003E00044C2E10045084003C0E010FAE +:1080500084013E07E9215A1001043E07E92E8400FD +:10806000490005C8A6398E08E6044EF200DE8007F6 +:108070003A6FA88448FFC9E24400003249FFC5298D +:108080003C1DFAA88402AE08AE38A6399E43E62409 +:10809000E9075A000D065A080E0749FFCAAA8408C4 +:1080A000AE39D5038409AE398520109300503E9730 +:1080B000E9393E97E91E49FFF0883C0DFA9749FFE0 +:1080C000EF3C4463F04A3E97E8FD4490005549FF79 +:1080D000C8955A08020510930000D5FA4403F01021 +:1080E0008420AE404403F429441FFFC3AE4049FF3F +:1080F000C885C009842144005AF080418061808194 +:1081000049002F7884003C1DFA9A3E00044C8400FC +:108110003C0E010FB441440FBFFFFE16B6018401AF +:108120003E07E9212E07E96C5A080306840949FF36 +:10813000C9A8D504840549FFC9A42E0004505A00DB +:10814000010584013E07E92E84004900055380079C +:10815000842049FFCCD73C0DFAAB5A0004045A08DE +:10816000070C8421844084028062848F80A13A6F4E +:10817000A88448FFC8A384408402FA258062848FC3 +:1081800084A13A6FA88448FFC8993C0DFA978420CF +:1081900049FFCCB8840AAE398403AE38840010039A +:1081A00000503C0DFA9749FFEEC884013A6FA8844D +:1081B00048FFDC1A49FFC8223C1DFA975A08020CF6 +:1081C000A6095A0003128001842049FFCC9B490074 +:1081D0000767D50AA6095A000A088001842049FFCA +:1081E000CC91490007A20003005100130052442221 +:1081F000B37E4432B3504442B38E49FFF97B8400CE +:1082000010030050D511000300515A0001055A080F +:10821000020584003E07E95A840010030050D5048B +:10822000841B100300503A6FA884DD9EE606E875B3 +:1082300044F081403807800040F03C004A003C0098 +:10824000062644D8669E4413F24884014423F2492A +:10825000AE088422AE504423F24A8464AE10442314 +:10826000F24BAE50D5304413F248841FAE0844138D +:10827000F2498448AE084413F24AAE084413F24B64 +:10828000AE08D53C4413F2488401AE084413F249C9 +:10829000AE084413F24AAE084413F24BAE0844133E +:1082A000F24CAE08D52E4413F24884014423F2491F +:1082B000AE088424AE504423F24A846CAE104423AA +:1082C000F24BAE504423F24CAED04423F24DAE50AC +:1082D0004423F24EAE104423F24FAE50D51B44134C +:1082E000F2488400AE084413F2498441AE084413B6 +:1082F000F24AAE084413F24BAE084413F24CAE8877 +:108300004413F24DAE084413F24EAE084413F24F3C +:10831000AE084413F250AE08DD9E9200C10358002F +:1083200000104413F2519600AE08DD9E40003C0858 +:108330004423F2449210AC104010BC084403F246AF +:108340009230AC40DD9E4403F2408421AE404413A1 +:10835000F04A44200055AE88A6405A1001FFDD9E29 +:108360004413F258A448AC404413F25AA448AC4118 +:108370004413F25CA448AC424413F25EA448AC43FC +:108380004413F260A64810100008DD9EFC02F08144 +:108390008002F383F18249FFFF4BF001F10249FFB4 +:1083A000FFC749FFFFD2F00349FFFFDCFC82FC025C +:1083B000F0814403F242F182F283AF40001F80203B +:1083C0004403F243AE404403F2528421ACC0440360 +:1083D000F254AD004403F256AC40001F8024440325 +:1083E000F241AE40000F8028001F802C49FFFF980B +:1083F000F001F102F203F30C49FFFFCAFC824403CF +:10840000F1408421AE40DD9E84203C0FFAA5AC43B0 +:10841000DD9E3C3DFAA5920192219241AC18AC59E7 +:10842000AC9ADD9E3C1DFAA5A6821020800CA68386 +:108430001020800DA680A6011020800E1000800F55 +:10844000DD9E3C1DFAA5A68210208010A683102078 +:108450008011A680A6011020801210008013DD9EDE +:108460003C1DFAA5A68210208014A683102080153A +:10847000A680A6011020801610008017DD9EFC014A +:10848000B63FF28149FFFFD0B41F49FFFFDCF00186 +:1084900049FFFFE8FC81FC24F081F182F283001F98 +:1084A000803C002F8038000F8040007F8060006F8C +:1084B000804C105F8016103F8014102F8017104FD3 +:1084C0008015101F801A103F8018100F801B104F4E +:1084D0008019CF08105F801E103F801C102F801F56 +:1084E000D507101F801E103F801C100F801F3C0DF1 +:1084F000FA7C104F801D49FFFF89B005B046B08758 +:1085000049FFFFBFF001F102F20349FFFF843C0D78 +:10851000FAA5021F8028002F8044AC44001F80541D +:10852000FE775263001095B1FF8F001F80481060E6 +:10853000000A58108040FE571010000B221F802C9C +:108540001210000C221F802E1210000D4403F04A5E +:1085500044100055AE404403F1408421AE40A64093 +:108560005A1001FFFCA4FC24F08194199600100F0E +:108570008017100F801B840184E2100F801E3C0DB9 +:10858000FA7C80C5103F8014104F8015103F801872 +:10859000104F8019103F801C103F801F104F801D0E +:1085A000F182F283107F8016107F801A49FFFF2E20 +:1085B000B005B046B08749FFFF64F001F102F20355 +:1085C00049FFFF293C0DFAA52E27E94E8420AC4433 +:1085D0005A28010895B31070000A1060000BD506E8 +:1085E00084491020000A1010000B4403F04A441084 +:1085F0000055AE404403F1408421AE40A6405A10DD +:1086000001FFFCA43C1DFAA51000800BDD9E440375 +:10861000F04A44100055AE404413F403A6085A0033 +:1086200001FF4403F3808421AE404413F04A442008 +:108630000055AE88A6405A1001FFDD9E4453F381D9 +:10864000944AA7289407544200F0FEA7FE57964884 +:10865000FE0F9600AE284403F38496D8AEC0DD9E8C +:108660004413F3868400AE084413F387AE08DD9EFE +:10867000FC004403F38496D8AEC049FFFFCA44030C +:10868000F04A44100055AE404413F380A6085A0047 +:1086900001FF4463F3804403F386A6005A08010FE8 +:1086A00049FFFFE049FFFFB54403F04A441000557D +:1086B000AE40A6305A0001FFD5EF4403F387A60071 +:1086C0005A0001F0FC804413F280A6085800000113 +:1086D000AE08DD9E4423F2809405A650FE479648DE +:1086E000AE50DD9E441E000088014413F286968140 +:1086F000AC8892104413F2889606AE08DD9EFC40CA +:10870000810080C1A4404403F28445C3F280AC40A0 +:108710000404000149FFFFE8001400084403F28349 +:108720004473F04AAE404490005500140009002400 +:10873000000A96469409001E00003DCFFA7E5410B0 +:1087400080FDFE47101E0000968694D2002E000089 +:1087500044000055542100FBFE9F102E000044A34E +:10876000F418AE3802050000C011020500005CF0EC +:108770000781E80C4403F2918421AE400004000B11 +:1087800049FFFFAA49FFFFA1D50649FFC5375A0097 +:1087900002EBD5F1000E00009606C0041093800095 +:1087A000D5FA4413F291AE084403F2813C0FFA7DEE +:1087B0005A680307A64092229646C1B8D5085A685F +:1087C0000105A6009202D5055A680206A60092038A +:1087D0009606C0ACFCC09404FE4796084413F4818E +:1087E000AE08DD9E4413F48396019680A6C89208D5 +:1087F000AE88A689AE09DD9E4413F4859601968065 +:10880000A6C89208AE88A689AE09DD9E4413F487F7 +:108810009680AE8892084413F4889600AE08DD9ED8 +:108820004413F4899600AE08DD9E4403F48244208C +:108830000055A640541080FE58108001AE404413ED +:10884000F04AAE88A6409646C9FEDD9E3A6F98BCB7 +:108850004463F00EA43054000100C00944122CF40B +:10886000A6088C019600AE088408D575A430960E33 +:10887000C85FA430961EC00944122CF3A6088C01D0 +:108880009600AE088403D567A4309616C00944123A +:108890002CF2A6088C019600AE088402D55CA430A8 +:1088A0009626C00944122CF1A6088C019600AE0849 +:1088B0008404D551A4309606C803FA00D54C49FF6C +:1088C000BE51A4309636C836A430962EC835A43092 +:1088D000963EC834A43054000200C00C4403F06437 +:1088E000A6409646C12DA640541080FEAE40840995 +:1088F000D5324403F00EA44054108400C923A44090 +:1089000054108800C921A44054109000C91FA440ED +:108910005410A000C91DA4405410C000C91BA400DD +:10892000920FC0CC84013E000414840FD51484013E +:10893000D5128406D5108405D50E8407D50C84097C +:10894000D50A840AD508840BD506840CD504840D79 +:10895000D502840E4413F00E8440AC883A6F98849C +:10896000DD9E4403F3228421AE40DD9E4413F323B5 +:10897000AE08DD9E4403F323A600DD9E3A6F9C3CC7 +:108980004463F540B6064403F544B6204403F54875 +:10899000B6404403F54CB6604403F550B68044033A +:1089A000F554B6A0F1024403F558B620F103440390 +:1089B000F55C3A6F9C04B620DD9E3A6F98BC44216A +:1089C0002D30EFF83A210C003A2F8C204423F50487 +:1089D0004443F5024433F5033C2FFA804423F50564 +:1089E000803F3C4FFA833C3FFA823C2FFA7F5A008B +:1089F0000204480000904453F500443C0B0044033B +:108A0000F50898AB3820880018228001D8FB440371 +:108A1000F50744100045AE404403F50084C1AF8023 +:108A2000840080208040806049FFFE244403F501DB +:108A30008423AE40840080208040806049FFFE1A7D +:108A40003C1DFA83A60858000002AE08840080206E +:108A50008040806049FFFE0E440007D049FFBFC838 +:108A60003C1DFA82A60858000002AE08840080204F +:108A70008040806049FFFDFE440003E849FFBFB825 +:108A8000840080208040806049FFFDF43C3DFA83F3 +:108A90003C2DFA82A658A6105810801D5800001DC3 +:108AA000AE58AE10840080208040806049FFFDE217 +:108AB0002E07E952C81B3C0DFA973E67E952A78181 +:108AC00049FFC39C3C1DFA975A0802058404AE096D +:108AD000D5038409AE093C0DFA9749FFEA2E8401BB +:108AE00049FFE8933C0DFA97AF81440005AA49FF7E +:108AF000BF7F49FFE870C0FE3C2DFA83440FFFEFB3 +:108B0000A650FE46AE503C1DFA82A688FE16AE0860 +:108B1000D562C8334403F5008421AE404403F50117 +:108B20008423AE402E200D103C1DFA833C0DFA82AA +:108B3000CA09A68858210001AE88A68058210001E4 +:108B4000AE80A68858210002AE88A6405810800248 +:108B5000AE40840080208040806049FFFD8B3C3D1A +:108B6000FA833C2DFA82A658A6105810800C5800A3 +:108B7000000CAE58AE10D52F5A080137A620A758C2 +:108B8000845BFE168437FE0EFEAEAE20FE568400D9 +:108B9000AE5880408020806049FFFD6C4413F50092 +:108BA0008400AE084413F501AE082E100D103C2DC4 +:108BB000FA833C0DFA82C908A6D0843EFECEAED020 +:108BC000A6C0FE5EAE40A6D0843DFECEAED0A6804E +:108BD000FE56AE40EC0884008020804080603A6FF2 +:108BE000988448FFFD47EC083A6F9884DD9EDD9E2F +:108BF000461008006413240364230402461FF7FF91 +:108C000050108FFFFE5640005C08FE0F6403040303 +:108C1000DD9E441080006413240364230402441F77 +:108C20007FFFFE5640003C08FE0F64030403DD9EF8 +:108C300040003C084433F2009210AC184010BC08CD +:108C40004403F2029230AC4040213C084403F20459 +:108C50009250AC80DD9E4403F20A44200055A640A9 +:108C6000541080FE58108001AE404413F04AAE8884 +:108C7000A6409646C9FEDD9E4423F2069600AE103D +:108C80004403F2079648AE40DD9E440232E8DD9E82 +:108C900044022F00DD9E4403F20BA600DD9E441328 +:108CA000F208AC08DD9E4423F20A9401A6509646D1 +:108CB000FE479648AE50DD9EE608E82544F08BCC92 +:108CC0003807800040F03C004A003C00080E141AAF +:108CD00020262C324403F20CD5154403F20ED51293 +:108CE0004403F210D50F4403F212D50C4403F214DE +:108CF000D5094403F216D5064403F218D5034403FC +:108D0000F21AAE40DD9E9200E608E82544F08C1C85 +:108D10003807800040F03C004A003C00080E141A5E +:108D200020262C324403F20DD5154403F20FD51240 +:108D30004403F211D50F4403F213D50C4403F2158A +:108D4000D5094403F217D5064403F219D5034403A9 +:108D5000F21BAE40DD9E92004413F050A60858006E +:108D60000080AE08DD9E4413F050A6089637AE088A +:108D7000DD9E4413F051A60858000001AE08DD9EA8 +:108D80003C0DFFA7A600DD9E4402400044124510A2 +:108D90003C0FFAB23C1FFA933C0FFA98DD9EC004D8 +:108DA0005A000209DD9E3C0DFFA7A6003C0FFA1FEA +:108DB000DD9E3C1FFA1FDD9E40003C084433F1C499 +:108DC0009210AC184010BC084403F1C69230AC407D +:108DD00040213C084403F1C89250AC80DD9EFC0069 +:108DE00044028F700020000F001000104403F1C2F5 +:108DF000AE804403F1C3AE403C0DFAB23C1DFA9381 +:108E00003C2DFA9849FFFFDAFC8084003C0FFAD32E +:108E10004403F1C08421AE40DD9EFC0649FFFFE122 +:108E20003C0DFA1F5A000F134413F1C19600AE080F +:108E300049FFFFED4403F04A44100055AE4044138F +:108E4000F1C0A6085A0001FFD51BFA202E37C547EE +:108E5000F1858422840084A1F18744124000F083CC +:108E6000F084F086F088F0892E47C548B67FF581FA +:108E7000F382F58A44024510804149FFFB0EFC86CF +:108E8000FC00842049FFC63E840149FFE6BE840100 +:108E90008440842A8080806280A249FFC20F4403FC +:108EA000F04A44100055AE4049FFE695C8043C0D19 +:108EB000FAD6C0FBFC802E17E91D5A10FF3E2E2764 +:108EC000C9C3E022E9039E5196484422E1BC3831EF +:108ED0000501E260E931FC208400380105093C0B02 +:108EE000F4E6842084832E07C53B9401E020E82328 +:108EF0003C3C027D3C0C027E3C5C0286948988628C +:108F0000880288A1A598A5C0A628880742031073E7 +:108F1000405008099769AD583C5C027D3C3C028694 +:108F200088458861A4908C2194928A029600AE189C +:108F30009648D5DAFCA0DD9EFC005A0801132E10DD +:108F40000D012E000D005A1801048E03D5028E0269 +:108F50002E100D1296005C10800349FFC128D50326 +:108F600049FFC136FC80FC0049FFC1485A08021085 +:108F70002E07E920C8092E07E91DE6038405E80944 +:108F80002E07C9A6D5062E07C9A7D5032E07C9A83F +:108F9000FC80540000FD5A0804053C03FF52DD9E8E +:108FA0003C03E4DBDD9E5A0804053C03FF51DD9ED3 +:108FB0003C03E4DCDD9E3C0DFA7BA400DD9EFC005E +:108FC000B400920196065A080109440000643C0B63 +:108FD000FF5244000168D5073C03E4D93C0BFF5223 +:108FE0003C03E4DA3C0BFF513C13F4793C03FF52A1 +:108FF00049FFC4CA3C0BFF523C13F4793C03FF51B8 +:1090000049FFC4C23C0BFF51FC802E17E918C90A66 +:1090100084423E17E92F3E27E94F3E17E9341010EE +:10902000001CDD9EFC004403F04A44100055AE4095 +:109030003C0DFAD6C8122E07E92B5A080106440245 +:10904000B3F249FFC23D8401844080208062808069 +:1090500080A249FFC133D5ED840E49FFC14CFC808D +:10906000FC0049FFC0CB5A08020E4403F4222E171D +:10907000C9C2A600961FE220E907C0068E0196002D +:10908000D5058400D503440000FFFC802E07E91DB0 +:10909000842050007F0140008006DD9EFC003C0DD6 +:1090A000FA97842384C1AE4184253E17E93E3E678A +:1090B000E93B49FFE7422E07E968842349FFE7912E +:1090C0003C0DFAB3AF803C0DFAA8AF802E00040B24 +:1090D0005A08010B84003E07E97884003C0E010F1A +:1090E0003E00040BD51A2E07E9785A0003082E0714 +:1090F000E91EC80484043E07E9782E07E96FC80A10 +:109100003C1DFA7BA4485CF0803CE9055000FFC49C +:10911000D50284003C0E010F84013E07E9718400F2 +:109120003E07E97AFC80FC003C0DFA97A60154004A +:1091300000FD5A0809162E07E9785A000305840431 +:109140003E07E9782E07E96FC80B49000EF65CF080 +:10915000003CE90649000EF150007FC4D5028400AE +:109160003C0E010F84013E00044C3E07E92F4900EC +:109170000EB749FFCAD43C0DFA97A6415A18080702 +:10918000842AAE4149FFE6D9D50F842049FFC4BAED +:109190003C0DFA97842AAE4149FFE6CF49FFF3B26E +:1091A000840E49FFC0A83C0DFAA88421AE40FC8083 +:1091B0005C000003DD9EFC402E17E94F5A18020B9D +:1091C0002E17E92FC9072E17E9788E225C1080012F +:1091D000D50284202E47C53B3C9C027E95A18EC1C2 +:1091E0009FE184A0846144A2CEB052800000E0A63A +:1091F000E81BD71740F284084024BC0050F78002D7 +:1092000040F4BC00A49002F780008A4F9693E002DD +:1092100038251509E903E048E8045A180103846277 +:109220008CA19768D5E55A18011F92014422CEB04F +:1092300084208122FF42E027E81638610511E0060C +:10924000E80740A0900038F12911E00FE908E0C5D7 +:10925000E807998C38649911E0C5E80284628C2192 +:109260009648D5EA8003FCC084204422E1BC380142 +:1092700005098C215A1808FDDD9EFC2080E0A6001F +:1092800080C25A0804208401AE383C0DFA97A6012A +:1092900049FFFE8149FFFFEA3C13F4C5E62AE805D1 +:1092A0008C213C1BF4C5D51584003C0BF4C5A4707F +:1092B000E639E805AE38840049FFFFD88400AC30B9 +:1092C000D508840049FFFFD28400AC303C0BF4C5C4 +:1092D000FCA0FC013C0DFA97A60149FFFE5CF08161 +:1092E000F1014402B3B04422B40449FFFFC82E1771 +:1092F000E97884003C0BF4D63E07E939C9033E0700 +:10930000E8F984003E07E93F3E07E91D3E07E936DC +:10931000440FFFAA3E07E92D3C0DFAA88421AE4078 +:10932000FC81FC202E67E91D2E07C9C380E1E0C047 +:109330002E17E90FE9038E0197805A18011849FF8B +:10934000BF5D5A08021484002E17C53B9449E00102 +:10935000E81783879441BA09BB0B884188238C01A5 +:10936000A44896009649AC50D5F04402E1BC4410A4 +:10937000FFFF38501901D1048CA1385019092E175C +:10938000E8F94000980E9606C81D2E27C53B94911B +:10939000E002E81283879481BB0A8C01991ABB0909 +:1093A00096008862A5589769AD60BC0BA4D8884424 +:1093B00096D9ACD0D5EB84014000180CFE0F3E07C7 +:1093C000E8F9FCA0FC422E27E91D5A28FF044800BA +:1093D000011F8101F0814412D4044402B37749FF94 +:1093E000FFA280484400FFFF8420A852A8132E0744 +:1093F000C9BAE610E804521000109648E61180A0A1 +:10940000E902FAA085409628B61F80EA800A80CA41 +:109410004492D6042E27C53B3C3C027F41E1040820 +:10942000E0DE4EF2008B3C0C027E94B199023C0CC3 +:10943000027CA560880204FF8000A400FF4C42501B +:109440003C73800592049601AC203C0C027E88623D +:109450008802A5003C0C027D8802A4009A20960395 +:10946000AC18A4189603E140E805A41880E640A0D3 +:1094700000113C0DFA7BA4D8A40596DBFE02E06047 +:10948000E82C2E07E92F5A0801292E000432C81DA6 +:10949000380498003C33E4D88C019600E26038042C +:1094A0009808E8213C0C027E3C3C027D88028862E0 +:1094B000A4009601AC1884003804980884013E0783 +:1094C000E8F83E07E97ED50FF183F28249FFBE96A8 +:1094D000F202F1035A0802DE38049800C0048E013B +:1094E000380498083C3C027E040400028862A518F7 +:1094F000E204E804A41814040002A51804040003FC +:10950000E280E804A41814040003F001A6C13C0D95 +:10951000FA7B5A380904A403D502A4043C3C027F18 +:109520008843A4909693E002E80484413E27E934FE +:109530008CC197B048FFFF7094799919E2E2A56059 +:10954000976BE826CF078C228823887EA448970B48 +:10955000D50B9F919F0A884788834C73400EA46067 +:109560009491970B8862A458964B88248825964B33 +:1095700044200050D52E8C22882394918862A52007 +:10958000A448A4989723964B96938824D51D4C7194 +:10959000400A8C228823A448968BA458964B882294 +:1095A000D5E69F0A506F7FFF9ABA88834C733FD9E4 +:1095B000A5A09D0A888394918862A460A49897B31B +:1095C000964B9693882688228825964B44200078CF +:1095D0004E170007E041E80484213E17E9342E17B6 +:1095E000E91E5A1001062E17E97E5A180108842137 +:1095F0003E17E93484203E17E9783C1DFA97A649C6 +:109600005A18090649FFFDD93E07E94FFCC2FC2064 +:109610002E27C9C2441000FF4020880C4413F422B6 +:10962000FE93A6489690965FC1038E2196482E37EA +:10963000C9C384C0E223E9049E59964884C1A7C0E7 +:1096400084A14042840CFF3F972296E0AEC04C714B +:10965000C003C60D84014C31000C88204000040C6E +:10966000FE279600FE1D5C000001D5028005FCA0CF +:10967000FC2184003C0BF4D63C0BF4E6120F800373 +:109680003E07E9343C0DFA97A6015A0804222E073A +:10969000E978C8284402B33149FFFFBB80605A080B +:1096A00001222E17C9C32E27C548500F8006FE8CF5 +:1096B00096904412D24849FFC0B72E07E97DC804EE +:1096C0002E000432C0038401D5078403D5052E077C +:1096D000E92FC80584023E07E978D5042E07E97D05 +:1096E000D5F22E07E9785A08020584003E07E8F80B +:1096F0008400444000C880604452D6042E17C53B05 +:109700009449E001E8233C6C027C944188C13C2CE4 +:10971000027EA5B0884197B1AD902E7004323C6CAA +:10972000027E3C2C027DCF0788418826A4489649BA +:10973000AC50D5038822AD083C1C02868820AEC8F8 +:10974000383280088C019600D5DAFCA1FC202E3737 +:10975000E92FCB59A6005A0802572E17E94F5A187D +:10976000024E2E57C53B3C7C027F956944207530E4 +:1097700084818003E065E81994598827A58897B308 +:10978000E0C2E803A4889693A58897B3E086E8032F +:10979000A5089723A448964B5EF0FF9CE8038C0134 +:1097A00096008C6196D8D5E75EF17F9CE81E8436E2 +:1097B000FE8C40211056E455E918C0172E07FEA074 +:1097C0008C019600E60B3E07FEA08400E9113E07DF +:1097D000FEA084013E07E92F2E07E9785A080214FB +:1097E00084003E07E978D50F84003E07FEA03E07BF +:1097F000E93484003C0BF4E6D5065A1801053E17FF +:10980000E92FD5EBFCA0FC4080C1A64180E05A18AE +:10981000041C9E34E604E91E5A600C1D2E07E978EC +:109820005A0003192E07E9205A08010784003C0F4B +:10983000FAD449FFEF5D800749FFFB244402D404BA +:1098400049FFBDC3D5072E17E9785A10030449FF15 +:10985000FB193C03F4E64412D50C8C013C0BF4E6F6 +:109860003C03F4D68C013C0BF4D6800749FFFDACD9 +:1098700049FFBCC45A08021549FFFBF4C8112E1752 +:10988000E975C10E3E07E92449000E952E07E93A15 +:109890005A0801043E07E91184003E07E9752E00CD +:1098A00004325A08012049FFBCA95A08021C490089 +:1098B0000546852080E03E07E9343C9BF4E65A08E3 +:1098C0000109840049000FCF3E70040B3E90043222 +:1098D0002E07E94B5A0801073C03F4D68C143C0BC5 +:1098E000F4D62E07E9345A08011784003E07E939F7 +:1098F00084002E17C9C34432E1BC80809680E241C7 +:10990000E805384181098C01D5FA4400005049FF2F +:10991000B8E0D5192E77E92F5A7801169E34E60261 +:10992000E9124402D50C3C13E3134422B3714900FD +:1099300004A35A080209FA0149FFB8CB3E77E9347B +:109940003E77E97E3C0DFA9749FFFF02440FFFAADC +:109950003E07E92D9E34E602E810440000FF2E1079 +:10996000045C49003BDF84003E07E93484003C0B83 +:10997000F4D63C0BF4E6D5065A68020584013E078E +:10998000E9342E07E9185A0801063E07E9343E0774 +:10999000E92FFCC0FC0084003C0FFAD93C0FFAD43C +:1099A000840149FFE1324403F04A44100055AE40BF +:1099B0002E000D123C1DFAD98C01E220E80A840128 +:1099C000844080208062808080A249FFBC77D5F1EE +:1099D0002E07E90FC8154402D40449FFBCF63C0D1C +:1099E000FA974412D50C49FFFCEF2E07E934C8085A +:1099F0003C0DFA97A60149FFFACE49FFFA5E4403EF +:109A0000F04A44100055AE4049FFE0E58040C809E7 +:109A1000840180208062808080A249FFBC4FD5F500 +:109A20002E07E934C81C2E000D12E603E8183C0D81 +:109A3000FA978424AE4149FFE2803C0DFA972E1735 +:109A4000E96049FFFEE23C0DFA978426AE412E07FD +:109A5000E934C8053C03FF5249FFFA2FFC80FC445F +:109A600044212D38B1843A2114003A2F9420442106 +:109A70002D48387F82023A2114003A23142094C2E0 +:109A8000442271403843020238510C002E37E92538 +:109A9000442FFF38FED4976896D9844044612288C9 +:109AA000981694010290000038011C008C41420479 +:109AB00080244000140E88030292000096034000A8 +:109AC000041688091A0200015A2A88ECFCC4FC45D5 +:109AD00044212D38B0423A2114003A2094204421E8 +:109AE0002D5844728F70B1863A2114003A23142005 +:109AF00081200023800F8400120F80033810A602FB +:109B0000500F800600338010924149FFBE8D500FE8 +:109B10008006381326020023800F0033801049FF8F +:109B2000BE83FCC5FC072E17E925440000C8FE0CC7 +:109B3000120F801B44028F7084A1A6C2A703840069 +:109B4000F081F082F083F084F085F086F088F0896F +:109B5000F08AB67FF58744021B90501F803644225E +:109B6000AD7049FFF49AFC87FC42FD30F281F3832B +:109B700049FFBB445A00020545E000A0D50345E07B +:109B800000782E07C5482E57C5478E0150A2FFFF0B +:109B9000F0828027049F8001F001F20340048001DD +:109BA0009600E202E85D09C48001424E14240800D8 +:109BB000800198A095D13883091184418068C0063E +:109BC00098B722317FFF84428868E00AE80788E678 +:109BD0008C4122738001969088675CFE0002E91B2D +:109BE0009BE540F380004077840838F33D11886F8F +:109BF000C8038C41D50740F31C008C4222F7FFFFBD +:109C0000886FE00A9690E80788E68C41227380010D +:109C100096908867F70240FE1C07E81888858880C0 +:109C200095E1384311118864C8038C41D5069937F2 +:109C30008C4222427FFF8864E00A9690E80788E61B +:109C40008C41220380019690886040218856E45020 +:109C5000E903E51AE80740FF0C07E89FD5038400F5 +:109C6000D5028401FCC2FC40846044407D0084C273 +:109C70002E17C548E261E86D2E17C54744507D0098 +:109C80004271842495F940A0840988E085008045CC +:109C9000541400FFE22AE8113893A1114E92000CEF +:109CA000E122E907E0A980294012BC1B8122968BA2 +:109CB00080A280498D01D5EDD40588A2405298B686 +:109CC00096AB84202E87C54740940409E22942714F +:109CD000A024E80C88E195F988E022538000C503B0 +:109CE0008AA2AD788C219648D5EE44507D008049FB +:109CF0008025E248E81340A3880038A029114EA22D +:109D0000000BE141E906E0AA40553C1A8141966BFF +:109D100080A1802A8C419690D5EDD41488A1405220 +:109D200098B6966BD50F80A94251887394A9884044 +:109D300022510000C5038AA1AD50502480015491E6 +:109D400000FF2E27C547E322E9EF8C6196D8D59115 +:109D5000FCC0FC46B188810181428380842080065A +:109D6000FA404900480550040006F08550040007F9 +:109D7000F0865005000684A08481F0872E07C54830 +:109D8000E080E854500500078460F0842E07C54742 +:109D9000E060E849802342120073380E0511E40D9B +:109DA000E93F84E038231D119678E040E836F2055B +:109DB0008006F283F20605EF8004F282F20785271F +:109DC000F281E2298E02E817F20302F000078F21E8 +:109DD00012F0000808F17FFFF283F202549480FF32 +:109DE00018F17FFFF282F20108F17FFFF28118FF84 +:109DF0007FFFD5E82E07C547804342220073380E07 +:109E00000901E6A83834040838031D093845040858 +:109E1000E8078CA19768D5048CE15A7808C58C6155 +:109E200096D8D5B58C819720D5AA8005FCC6FC02B2 +:109E300044212D3880C33A2114003A2F9420383F12 +:109E40009A024412714095B288C1843EA7303C53B7 +:109E5000E2B697204201847380439A539649E225E3 +:109E6000E8103860091108110001FE744010900ECE +:109E70004E140003FE4A5EF08051E9F08401D502E1 +:109E80008400FC82FC424647FFFFF28350220FFF12 +:109E9000814084618001448200003C1C017BF2828D +:109EA0002E47C565E2834EF3009B8381FAA8BC1060 +:109EB0004460003054427FFF952242419473888869 +:109EC000F203025200099769F5810252000840F23C +:109ED0008013A767A7E6BC1254427FFF9522424237 +:109EE0009873BD1288885452FFFF956A4253987345 +:109EF00088A884C05A28014E844397F0407389375C +:109F000097F8549480FF844A39C21E0242948824F0 +:109F100041CE240D55CE03FF5BC3FF12F20141C1B8 +:109F20007000804339E571012FC7C5474223707324 +:109F30008382F20241CE080039E0710938729E0234 +:109F40008CC14093A40D549483FF5A93FF0B2E773A +:109F5000C547892FFFF4389525018AE338901D09FC +:109F60005A6824CCD5383872A6028CC14073F00DE3 +:109F7000547383FF5A73FF0C2E97C54788EF4293A3 +:109F800024248B233895250138901D095A602424F8 +:109F9000844397F0409388F7549480FF97F8844A5D +:109FA00043C38824387226024073F00D547383FF34 +:109FB0005A73FFDB2FE7C54780434223787383C280 +:109FC000F20241EF0800F20139E5790188E239E057 +:109FD0001D09D5CA8C6196D848FFFF64802A49FFC5 +:109FE000BBB6FCC2842080612E27C547E222E8066A +:109FF000383005098C219648D5F82E17C54884803D +:10A000002E27C548E222E81184402E37C547E24397 +:10A01000E80980A242508C738C4138401509969013 +:10A02000D5F58C219648D5ED2E17C54784602E278F +:10A03000C547E222E81384402E47C548E244E80BB6 +:10A040002E47C54780A1425110738C413830150905 +:10A050009690D5F38C219648D5EB2E37E8802E17B5 +:10A06000E881421188738440382005092E47E88230 +:10A070002E37C5472E17E88342120C733820050986 +:10A08000DD9EFC0051FFF5C880C0C936C0463C3398 +:10A09000E2B6442237FCB186444003E89609E20365 +:10A0A000E80C0201068A0A510001FE244000141641 +:10A0B000380305098C21D5F3800649FFFF95501F11 +:10A0C00085288006844149FFFEDF800649FFFDCDDB +:10A0D0008006501F8528844049FFFED6B042B084D8 +:10A0E000800649FFFE38F081B0428006B084F3015B +:10A0F00049FFFD3CD51044024510441237FCB086A0 +:10A100008460848149FFBBADB006B042B0848066F4 +:10A1100049FFFE8FF081D502F081440245104412C0 +:10A1200037FC49FFBB14F00151FF8A38FC80FC4228 +:10A1300084C084013C6FFAD93E67E934810649FF47 +:10A14000F55981463C6FFAD4B6DF812680E65A780D +:10A1500004112E07E968842349FFDF4384003C1D76 +:10A16000FA9780404432B38F49FFE0208481D513B1 +:10A17000800749FFE6DEF0813C1DFA9784038047A3 +:10A180004432B38F49FFE0122E07E968842349FF68 +:10A19000DF28F40188899620F081F0014C9000605E +:10A1A00049FFEAA649FFBEA2B41FE209E831800ACE +:10A1B00049FFE6BFF082B41F8C019600B61F4C65C4 +:10A1C00000038500500400019600F0838028800A77 +:10A1D00049FFFF595A0801162E07E9565A0801127D +:10A1E0003C0DFAB3A78097B05A6801FE2E07E968C4 +:10A1F000842349FFDEF64400007349FFB46AD53971 +:10A20000800AF10249FFFC2D80CA048F80034403B9 +:10A21000F04A44100055AE402E17E9683C0DFAB3E1 +:10A220005A180311A6405A1801FF440200004412B4 +:10A23000000244224510FA62FA94FAA049FFF1950F +:10A24000D504A6405A1801FF50048001549000FF25 +:10A250003C0DFAA884218147AE40D5A08CE197F847 +:10A260005A70050448FFFF75840049FFF4C384C099 +:10A270008006FCC22E37C5E85A38015FFC003C3D21 +:10A28000FA97A6D95A3009045A38040EA1022E674B +:10A29000E9403C33E311404218972E57C62F9721CF +:10A2A000A003D51F2E47E9683C33E3105A48041138 +:10A2B0002E47E914523180FFFF1C2E37E9472E60EC +:10A2C0000D2840420C96524200FF96E1D5032E67BE +:10A2D000E925B4802E57C62E404218979721A00139 +:10A2E00040001817E2239999960197B1E8048A6112 +:10A2F00096D9D50284605CF302018026E9034410FC +:10A3000002009649E281E904A6108C01D504E260BE +:10A31000E8FC8400AE10A610E2A08401E80C8400E2 +:10A32000AE102E0004538C013E000453FA0549FF81 +:10A33000B3D08402FC808401DD9EFC0084003E07D3 +:10A34000E94B84003C6C027F8060802080409970E3 +:10A35000A52897235EF20064E9038C418C21A5288F +:10A3600097235EF27F9DE8038C618C418C025A0832 +:10A3700090F05A3048045A18480584013E07E94BCA +:10A3800084003C4C027E2E10040A80609960A5680F +:10A390005CF28050E8078C6196D8E664E903842477 +:10A3A00084408C025A0890F4E62480013E10040A8E +:10A3B000E90684003E00040A8401D511C903E64978 +:10A3C000E80E3C0DFA97A6015A08060684043E00E2 +:10A3D000040AD5048C213E10040A8400FC80A611D6 +:10A3E000A6909CC18A6296D8E6634EF200A1E6323E +:10A3F0004EF3009EFC4184E040A1040894C13C4C13 +:10A4000002788127838780C780A750A50288508162 +:10A41000828840351C008864A4D896DBE466E9068F +:10A420008CC1887C97B041C1801140341C00886485 +:10A43000A4D896DBE466E9068CA188699768409108 +:10A440008011507380245A7A88E640FE19F6403411 +:10A45000947684E040978013149F8001838783C79C +:10A460004091801340351C008864A4D896DBE466D4 +:10A47000E90A04FF80018A6F4E340003FEDA887E09 +:10A4800041E1801340341C008864A4D896DBE46664 +:10A49000E9088A694E340003FEDA887C41C18013E2 +:10A4A000507380245A7A88E0E6D0E943E6B0E94167 +:10A4B000406F18D6E4D9E805405E14B6E4B9E93B2C +:10A4C000C217FA6242208C73949198E28E428844BB +:10A4D000A558A590976B97B3E0C5E805A4D8A490BC +:10A4E0009A9AD504A490A4D88A439691D50344207F +:10A4F00000FFE611E820FA6242008C739401986034 +:10A500008C028880A4C8A42096DB9603E003E804AC +:10A51000A408A460D503A420A4488A015CF1002407 +:10A520009601E8095CF00024E806D5038400DD9E6E +:10A530008400D50344008000FCC1FC0084418420D9 +:10A54000806280824400200049001D54FC80FC2071 +:10A55000FAE280C0440F8000E262E9108081A175B8 +:10A5600042411C7395218885A560976BE005E8033F +:10A57000A52096238C419690D5F0FCA05A3FFF046D +:10A5800048000107FC4784204452CF5080C1386204 +:10A59000860A8C215A1812FD84BF8420B6BF80A180 +:10A5A000E2A4E80FA19138631501DE09A192386396 +:10A5B0001501E226E804D3038026B6BF8CA1D5F1AD +:10A5C0008380941AF084A015F28338900E00B41F93 +:10A5D0009402F085F003F104A0058820A689E32207 +:10A5E0004EF200C0402480139CD140A18013B47F60 +:10A5F0005A37FF1DF3058803A6C0E243E904A7010B +:10A60000E282E806E343E912A681E24AE90FA7C223 +:10A61000A68BE247E8048EE197F9D509A783A60A3D +:10A62000E2C0E8078CC1FAF3D507FAF384C3D50476 +:10A63000447000FF80C7508F802484003804A00835 +:10A640009A3EE406F0814EF3008A9638544480FF27 +:10A650009770F08280248045801CF302F487F58691 +:10A6600049FFFF775EF0003CF506F407E9779C614F +:10A67000801C96488045F30249FFFF6B5EF0003C6A +:10A68000E96D84013804A008FA02FE344020240059 +:10A690008420880A94919401808681018061E2E49B +:10A6A000E91104FE0005994A88AF8C81A568976B73 +:10A6B0008865994888AF50108024A568976B8905F4 +:10A6C000D5EFF001401524018C014040040A886454 +:10A6D00085408888405180B6404200969449810A5E +:10A6E000800AE2E6E91C05EE000540F10400403F67 +:10A6F000080040FF3C00A4D802F7800096DB40F73A +:10A7000080118A6540F7900142018C734287BC73C7 +:10A7100042A1BC738CC150210024D5E4842049009F +:10A7200004A580C084208008490004A0C8028401D8 +:10A73000CE0284C1FF844430006440030409420512 +:10A740000C7340001817402488085EF0006544121E +:10A75000CF504001BC1A3800880A8D2148FFFF3CC9 +:10A76000A64844000064B1094452CF50E222E80BED +:10A7700038309000C30638328602E060E802961B4B +:10A780008C21D5F55EF00046540780FFFCC784009D +:10A79000DD9EFC44A6CA5A30010E2E300401CB03C4 +:10A7A000A6C8C30884602E47C6CC44628F7080E37D +:10A7B000D5088400AE0884003C080201480000D798 +:10A7C0009758E2A4E806995E8C611072818CD5F9E5 +:10A7D0008120A005FA6E80E1504F801F802084A068 +:10A7E00080C249FFBBDD000F801F847FF08384009F +:10A7F0008020F4039680E244E810A17196813852DB +:10A800008101DA09A0B238210101E22240113C1B8A +:10A8100040303C1B8C01D5EE5A37FF1DA0B7A03647 +:10A82000945A38810E020423000838000E02385171 +:10A830000E02C56A3CADFA8800250032FE84400154 +:10A840001417F0820005003342040024405014B76E +:10A85000D55C84A0F58280058025D50F4E02008549 +:10A86000001F0032B45FF401FE8C40110037002F4E +:10A870000033FF1440020017A6B85A20010544A077 +:10A88000003CD502FB58F2028A4180224E2400038C +:10A89000FE52E341E9079AA84E240003FE92E342E8 +:10A8A000E824A0B238210D01E659E9138AA04E54DC +:10A8B0000003FF6AE0A14012BC1A5EF08190E80933 +:10A8C000800980278046F40349FFFE5A5A08010890 +:10A8D000440000783C0802018401AE382E17C6CC33 +:10A8E0004402911484A0D5083C000201C0F78E01F7 +:10A8F0003C080201D5F4D13A082000018CA11020B7 +:10A900007FE79768D5F9F582A0353DEDFA88882074 +:10A91000A60BA68AF0848400F081B61FF404E282BC +:10A92000E99EA70900A08000F485F405E28AE91AEF +:10A93000008F0002808A04F4800542412073408227 +:10A940000408890F0284000040840011E51EE90814 +:10A95000B49F8C01888AB69FF4018882F4818D416E +:10A96000D5E58C41D5DC8020D588FCC4FC000400F2 +:10A970000015844480208461848584A049FFB7C683 +:10A98000FC803C1DFFACA003A44CE201E90684005E +:10A990003E00044C8402DD9E8400DD9E3A6FAABC1A +:10A9A00084E0EFFC3C2DFFAC808180C780A785450B +:10A9B000B5244E9200118F24E722E90D048200078E +:10A9C0000490000238F4A10100810006E30FE803BF +:10A9D00010A18002B5245084FFFFE702E9035A98D2 +:10A9E00004192292000702F1001EE12FE9120281F0 +:10A9F000001FE109E90E2292000602F1001CE12F7E +:10AA0000E9080281001DE109E9048CC197B080E5E5 +:10AA10008CA19768504200FC5A580ACC2EA7FED54C +:10AA2000CE0684008420AE1A8081D51FA61A5A0053 +:10AA3000051B5A68011450057FFFE602E8042E57F3 +:10AA4000FED2DFF0440000FC4213807384012240F8 +:10AA5000800622108007AE1AD50884038420AE1A1F +:10AA60008081D503842080812E0004325A0801049D +:10AA70008405AE1AA61A5A0801633C9DFFAA005429 +:10AA800080005A5801093C5DFFAB025280098EA13B +:10AA90009B2C9723005480015A5801093C5DFFAB61 +:10AAA0000252800A8EA19A69964B0054800300845A +:10AAB00080025A5801403C9DFFAB025480094E83EE +:10AAC000001E50F2FFFF0254800251C2FFFF84A219 +:10AAD000408795164282707340443C970284800AF6 +:10AAE000029480038F018F21405414B64250A47306 +:10AAF0004012A0379723964BD52251C2FFFF025434 +:10AB0000800351E2FFFF84A240FE15F642F2787303 +:10AB10004047F09702F4800A0294800250F7FFFF4A +:10AB20008F21405794B64250A4734012BC379723EC +:10AB3000964B5A88010580A480818025E745E81955 +:10AB400044F0AA5038A7A80040F53C004A003C0059 +:10AB5000060C0C161C005A08010BD5105A00010CEB +:10AB6000C80C8403D50BE602E808D503C806D50651 +:10AB70008400D5048402D50284043E07FED58E01EC +:10AB8000E60484A04EF2014844F0AA9838078101F7 +:10AB900040F03C004A003C00080056008A01760262 +:10ABA00084A03C5FFFB33C5FFFB284A184003C5FA4 +:10ABB000FA21445FFFAA3C0BFF683E07FED43E0724 +:10ABC000FED33E57E8883C4BFF623C1BFF633C4B87 +:10ABD000FF603C1BFF613C4BFF5E3C1BFF5F3E7711 +:10ABE000FED23E07FEBA3E07FEB8480001172E0708 +:10ABF000FEBA0251001A3C4BFF5EE2053C1BFF5FB0 +:10AC0000E8048C013E07FEBA3C07FF609BC44E740B +:10AC10000003FFFA3C57FF619A294E040003FE022D +:10AC2000025100198807E0A0E80484013E07FEB83D +:10AC30003C97FF62400490014E040003FE023DC7B2 +:10AC4000FF63407E04014E740003FFFA02A1000579 +:10AC50009978E3454EF200E2A5562E87FED3E20531 +:10AC6000E90DE124E806854058540002812AD509FF +:10AC70005454000185408521D50480A88542852053 +:10AC800002F10007E2EFE90DE03CE80458528001D0 +:10AC9000D508974E8D219768549480FF58A50001E0 +:10ACA0003CFDFFB288EF3C7FFFB23C7DFFB38807DD +:10ACB0003C0FFFB35A98020E2E07FED4C81D840124 +:10ACC0003E07FED43C0DFA2194023C0FFA21D52513 +:10ACD0005AA803132E07FED4C80F3C0DFA21940284 +:10ACE000580000023C0FFA2184013E07FED4840282 +:10ACF0003E07FED3D5124C5400112E77FED4E6E762 +:10AD0000E80C3C0DFA218CE19402FE2F3C0FFA2155 +:10AD10003E77FED43E57FED33C4BFF623C1BFF63A5 +:10AD2000D57C2E57E8885CF28020E811A410A5118C +:10AD300040004008401010045202801F4000800E66 +:10AD40009606C805440FFFAA3E07E888A410920C97 +:10AD50009606C0632E07FEBB5A08012A2E17FEBABC +:10AD60000201001AE220E8232E17FEB90201001B9F +:10AD7000E220E81D2E07FEB8C81A3C07FF5E3CF72C +:10AD8000FF5A021100198A0F4E040003FE02E0016F +:10AD9000E80E3C07FF5F3CF7FF5B8A0F4E040003A1 +:10ADA000FE02E001E80484033E07E8882E17E888E5 +:10ADB00084003E07FEB95A1003313E07FEBB2E0742 +:10ADC000FEB8C82B3C07FF5F0211001EE001E91D21 +:10ADD0000211001FE020E9193C17FF5E0241001C30 +:10ADE000E024E9130241001DE081E90F2E57FEBA6D +:10ADF0000241001AE2A4E81184813E47FEBB3C1BDD +:10AE0000FF5A3C0BFF5BD5098402AE1AD5063E57AC +:10AE1000FEBBD5033E57FED584003E07FED63C035D +:10AE2000FF68CE052E1004325A180115A454E20111 +:10AE3000E8058C013C0BFF68D5272E000423C806CB +:10AE400084013E07FED68404AE1A84043E07FED574 +:10AE5000D51B2E17FEBB5A18010E2E17FEB9024144 +:10AE6000001BE224E8058C213E17FEB9D5033E679E +:10AE7000FEBBA454E201E905440FFFAA3E07E8889F +:10AE800084003C0BFF682E27E8885CF10020E82155 +:10AE90008C4C96908401E65EAE18AE998401E9056B +:10AEA000FA2E49FFC59BD504802249FFC59784032C +:10AEB00049FFC59A8400EC043E07FED5440FFFAA63 +:10AEC0003E07E8883A6FAA844400006048FFAE015C +:10AED000EC048400AE183A6FAA84DD9E3BFFFE3C72 +:10AEE000EFFC4412B4908400442FFFAAAE08AE0ACF +:10AEF000AE8984203C1FFFB33C1FFFB23E17FED437 +:10AF00003C1BFF6884213E27E8883E07FED53C1F96 +:10AF1000FA213E07FED33E07FED63E07FED23E078D +:10AF2000FEBB3E07FEBA3E07FEB93E07FEB8EC0484 +:10AF30003BFFFE04DD9E3C0DFFACA404DD9E2E070E +:10AF4000FED6DD9E84002E17C54144328F7080806E +:10AF50009680E241E80698838C01104103ECD5F914 +:10AF60004400003C3C0BE499DD9E3C13E390AC4074 +:10AF7000DD9E4402CF988420AE40AE41AE42AE4347 +:10AF8000AE44AE45AE46AE47DD9EFC4046F7FFFF01 +:10AF900050F78FFF5A18024480A0808084E0B46488 +:10AFA0005A38022280C085204C748019B4665A3801 +:10AFB000021622120006223300069ACB4E340003FA +:10AFC000FEDA2212000722F300078A2F4E14000334 +:10AFD000FE4AFE4C42118C7381E18D21506300FCCE +:10AFE0005A980AE48CE1504200FC5A780ADA500080 +:10AFF00009D8B4655A380210A0EFA11594DA886414 +:10B00000A718C414A7195A401112A71AC40FA6DB17 +:10B010005A30230D505280FCD8EDD50684003E07EF +:10B02000FED83E00045D8400D50284012E30045D0C +:10B030004420FDE7E04FCB0CE90C2E17FED88C2105 +:10B040009648E6233E17FED8E9098421D505E8FE97 +:10B0500084203E17FED83E10045DC00684003E07E3 +:10B06000FED83E00045DFCC0FC418501B61F808116 +:10B070008120838185404004A001E320405E2801B7 +:10B080004C5780234074A000E2E9400E280040673E +:10B09000800040037C0892E1FFC792C180078026B0 +:10B0A00080478066F48149003E39F401E281E90974 +:10B0B0004C124005B43FE220E90481078146D5DC0B +:10B0C00081278386D5D9E602E8DE8008802AFCC184 +:10B0D000FC204430271080C0FE5C22000028402065 +:10B0E000885622130050FE1C40100436E0222243F2 +:10B0F0000000E85340F011F6E04FE851445000786A +:10B10000FA388083980D90015CF00051E9045230C8 +:10B1100000A0D50480605A00280552700078D5033D +:10B120004470005038330D1138731D11FEE4403166 +:10B130009C76E043E8039F41D504E062E8349C41FB +:10B14000E0A1E8E14C00800380A15CF28051E904B9 +:10B15000521280A0D5028025507280285CF3805165 +:10B16000E903527280788A624E340003FEDA3813A3 +:10B17000051144402710FF0C38131D11404204965E +:10B180009AA24E240003FE92E062E90DE043E90A30 +:10B19000E2054002BC1AD507FA18D505440000782C +:10B1A000D5028005FCA05CF00051E905523000A0FA +:10B1B000B661D502B60150107FD85CF08051E90528 +:10B1C000520000C8B602DD9EB622DD9EFC0196CB81 +:10B1D0009683903090108A018A43FE0442010873DE +:10B1E000FC81A6493C43E3015A1001049660D50254 +:10B1F000A6522E20044C5A280103A65C22F000031C +:10B20000E02FE80484013E07E95FDD9E3C2DFA97BC +:10B210002E37C5F6A6915A20060496D9D5032E37A7 +:10B22000C5F8A6015A0801042E37C5F72E07E90C08 +:10B230005A080104443000782E47E94A2E07C5FC1D +:10B240002E27C5F5E280E9342E07E94C5A0801386B +:10B250004020080C3A6FA83C8A43EFFC969104A06A +:10B260008002B5210470801484A0446005104085DC +:10B2700014004004940002F40000993DA400A4606E +:10B28000FE1C42013C7388012E17C5F58CA24010AC +:10B29000040D964912140000021400002E87C5F513 +:10B2A0004010A00C8A019601AC20DEE2D5058C810D +:10B2B0003E47E94ADD9EEC043A6FA804DD9E3A6FF2 +:10B2C0009ABCEFFC2E07C5DF5A0001048401D55853 +:10B2D00084003C0BF4DB2E07E95FC0052E07E93341 +:10B2E0005A0801F64617FFDD445225B050108A5027 +:10B2F00084604422283898293C4C027894018804C0 +:10B30000A40096035EF07FC9E80EA6288C01960083 +:10B31000AE28A628E60AE9083C03F4DB8C013C0BC6 +:10B32000F4DBD502AEE88CA1DAE73C03F4DBC80518 +:10B330002E07E9335A0801CC84003C0BF4DB44525D +:10B3400025B04412283818028001D9FE2E07E933AF +:10B350005A08010B2E0004528C013E000452FA06DA +:10B3600049FFABB7D5092E0004518C013E000451B2 +:10B37000FA0449FFABAE84003E07E9338402EC04D3 +:10B380003A6F9A84DD9E3A6FAABCEFBC84C0126FFC +:10B390008018126F80198100FAC24280987340743D +:10B3A000180050647FFF40A3001350640001F28B2B +:10B3B00097F997B1C906C0145A08111680CAD51357 +:10B3C00050947FEE409480135A182307C00E5A08F9 +:10B3D000111080CAD50DC00E5A08110ED50B81462A +:10B3E0008127D5098127D507814680E9D50480E9E1 +:10B3F000D50280CA3C0C01EE956A88A041C40408BD +:10B40000A668A62941E504084C1040233CAC02790B +:10B4100040057000A54040057800976BA44094312A +:10B42000880A964BA4009A6996034E140003FE4ABC +:10B43000E0A1E9079A284E040003FE02E0A0E80814 +:10B440002E000426E607E8048C013E0004263C0C8E +:10B4500002752E87E925F0823C0C0273F0834004CC +:10B460008408F0849439F0859431F0862E07E9330E +:10B470002E90042BF081440000C842040024501098 +:10B48000005050007FB0F088440FFF384204002481 +:10B49000F187F0898420F202F00397C840011C1A5A +:10B4A000F2043850701138600801F205126F801BE9 +:10B4B000125F801A38600801F206126F801C386033 +:10B4C000780138000801126F801D120F801ECF080E +:10B4D00040F2A1F65EF78032E8038401F081B00CFF +:10B4E000B14D38A0051184C522028000F207F58A0B +:10B4F000E040E904F208E002E810F20988024E0494 +:10B500000003FE02AC285A78010B22FF801A5EF776 +:10B51000A7114093BC1AD5038400AC28F00A8CA272 +:10B52000220000004E040003FE028EC1880A97B07C +:10B5300040A00011CEDAB00C38A005095A10010461 +:10B540008421D5AA000F8004F10B3E07E9333E9019 +:10B55000042B220F801822FF80195A10010A5A303A +:10B5600001082E00042B5A0001098400D50A8A0F15 +:10B5700096035EF000A0E9F68401AE20440080004E +:10B58000EC443A6FAA84DD9EFC00842084618041F3 +:10B590008083440056404900152D5410007F84419B +:10B5A00058108080806280824400564049001522F5 +:10B5B000FC80FC008420846180414400DAE08083C8 +:10B5C0004900151844100271FE0C441003E84000B5 +:10B5D00004162E1FE96550007FD896025A187F0482 +:10B5E0003E07E9652E1FE9655A107F1A8A014E044D +:10B5F0000003FE02E40FE9138421E41E3E17E93A3A +:10B60000E9095EF0003C3E17E91BE9073E17E967D0 +:10B61000D50D84003E07E91B8400D50684003E0753 +:10B62000E93A3E07E91B3E07E967FC80FC43F084EA +:10B630002E07E9675A00010A2E07E91B5A08010B79 +:10B64000FAF144A00085D5094470003244A000C836 +:10B65000D504FAE944A000642E07E96294D9F08386 +:10B660004402C92C88604402C9BCB61F5000851032 +:10B67000F08584C0440FF448F08183C1808645C0C2 +:10B680000BB880068126F6825A60081D225F0000F2 +:10B6900022FF000140F2BC014EF4000452F780008A +:10B6A00040F79C07E82E81E54E54000452F28000DA +:10B6B00040F7A807E8268805960338F11901A55830 +:10B6C000D51C2250800822F0800740F2BC014EF4C5 +:10B6D000000452F7800040F79C07E81381E54E54C0 +:10B6E000000452F2800040F7A807E80B8805960393 +:10B6F00002F180000251000888AF8C81AD5897207C +:10B700002A5F00014E5500068D21549480FFD50913 +:10B71000048F800250F40001548780FF148F800250 +:10B72000048F8001E0BC41C2BC1BE1054082BC1B10 +:10B730008CC1148F80015A6809A9C4592251800014 +:10B7400040001016405290B6AD5896035A90090525 +:10B75000F5025A580929E686E92680804E0400033E +:10B76000FF02E499E920404070014E440003FF22AB +:10B77000E0E4E919F4018A8080044E440003FE22CB +:10B78000E0E0E911F0045A080107B49F000F8010AF +:10B79000AE20D505B49F840110020024F0038C0173 +:10B7A0009600F08380A2506100122A02800122419B +:10B7B00080004E0500068A044E040007D5048A0462 +:10B7C0004E07000384001202FFFFDEF0B41F50108A +:10B7D00080248C01B61FF005502100248C624C108F +:10B7E0007F4A000F800C3E07E962FCC35A9809B2F9 +:10B7F000D5DAC8113E07E9624432C9BC80804412E0 +:10B80000C92C804038418008382081098C015A08B1 +:10B8100048FBDD9EFC008061A04E5A080105A09DFA +:10B820008460D505A09D8C328C52FA7449FFFF00CC +:10B83000FC80FC0084003E07FFCC2E07FFCDC00F2C +:10B8400084C13E67E9343E60040B49FFACD75A0817 +:10B8500002043E67E92F84003E07FFCD2E07FFCC90 +:10B86000FC803E07FFCD84003E07FFCC8400DD9EB8 +:10B87000841F3C0FFA2384003E07FFCD3E07FFCC18 +:10B88000DD9EFC42A712F383C4038E81AF123CAD50 +:10B89000FA89A753004500038E81D4038CA1AF53CE +:10B8A000A710C4038E81AF1000450002A7518E81FE +:10B8B000D4038CA1AF513C8DFA9AB488928E97062E +:10B8C0005A48010644300032B67FD503FA89B69F44 +:10B8D000A6D18480A790F38180A4F301E266E946B3 +:10B8E000A6D3A7D2F382F302E267E93E00950002F5 +:10B8F00083C643E3A4730490801541CF0408893CB8 +:10B90000B47F02F4800040F78011E06FE82004F07B +:10B910000000F30338F7F90005E0000138FF3D01AE +:10B920004CF1C00904F4000040F7B80954F7800155 +:10B93000E80904F4000040F7B80954F780015AF808 +:10B94000010702948000409480118889049080054A +:10B95000893C02F4800040F78011E0AFE803025414 +:10B9600080008CE1D5C18CC1D5B9C506440001F475 +:10B97000FF04404214978004FCC2FC4281403C0D0D +:10B98000FA8A80C1853FA640A703440003E8FE0C65 +:10B99000A65080E23C9FFA2340800013C903840034 +:10B9A000D52A840080A0E0A1E811042500013821F7 +:10B9B0001501DA0A0425000238211501E20240923D +:10B9C000BC1B40013C1B8CA1D5EF3C9FFA235A972E +:10B9D000FFE804250005401488088822B003844449 +:10B9E000B69F490039BB800A8026B083806949FF31 +:10B9F000FF4AB49F3C1DFA9AB421922E96465A18DB +:10BA00000114041500033C2DFA23381089015CF061 +:10BA1000812CE80344802AF83C13F5295CF080511E +:10BA2000E9038400D503E300E9082E1004005A1846 +:10BA3000010F2E10045BC90B84013E07FFCC3C0DA7 +:10BA4000FA8A8421A6013E07FFCDD563441003E89E +:10BA5000FE649649E220E85C808A3C1DFA23A0231C +:10BA60004430006438200501FA18FE1440000C161A +:10BA70009601E20380404021BC1B9611F081A02575 +:10BA8000944A880184200080000300A00002A701DE +:10BA900001E00000E30A400428019600E90280204A +:10BAA00096498460B63F8043803EE224E82080AA25 +:10BAB000E2A8E817FB2281E142F2A47340978408D0 +:10BAC00004F30005892F04FF800102948000409454 +:10BAD0008011E12FE9038C4196918CA19768D5E9FB +:10BAE000B4BF8C218865964896D9D5E0E662E91006 +:10BAF00044100064FE8C40310C7696D95CF180488D +:10BB0000E9078A9E97208A048C01E603E99684203F +:10BB10002E07FFCDC00D5A1801053E17FFCCD508E2 +:10BB20008E0196003E07FFCDC8033E07FFCC2E07CF +:10BB3000FFCC5A0801048420AE78FCC2FC43840088 +:10BB4000100F80173C0C0278504F8017802084A083 +:10BB50004422D1DCFA7849FFB2238420005F8017A9 +:10BB60003C9C01EA3C6C01EB808180019688E245B7 +:10BB7000E80F3874850196C94C71C0093833050146 +:10BB8000E20340413C1B4001BC1B8C21D5F0946278 +:10BB90003C7C01EEC03D997996E1A629A6A8F081EA +:10BBA0003DEC02783DCC01E98400FB02F383F30114 +:10BBB000E262E925A7ABA6EAF682F602E2C3E91C37 +:10BBC000814242A1A0734065040888DE02F30000B0 +:10BBD00040F780115EF78028E90C38AE290004FF99 +:10BBE000800338A4A9014CA7C005A5B097B3880667 +:10BBF0008C6196D8D5E38C419690D5DA442001F437 +:10BC0000FE143C2C01EC3821110140000817882754 +:10BC100044504E1FE2A0A6CBA70AA689A648E80E6C +:10BC20008A6496D8E66BE8058A419690E64BE90867 +:10BC300044106D5F40008006D5048400D502840165 +:10BC4000FCC34403F080441FFFB6AE403C0DFA171E +:10BC50003C3DFA1692028C01442200008420E2202E +:10BC6000E806A3113841860A8C21D5FA84013E07E3 +:10BC7000E8FE4403F0808420AE40DD9EC0174E17DE +:10BC800000164E270014980AE41FE910E022440031 +:10BC90000064E807AE18FE0C40200856AEA0DD9EFA +:10BCA000FE8440210456AE98D50444000064AE18CA +:10BCB000AE20DD9EC10B4020840944300064422048 +:10BCC0000C7340110436960BDD9E8001DD9EFC4016 +:10BCD000EEE080E044012D68B0483A2014043A2098 +:10BCE0009424A4002E97C53A2E87C53BAC08440186 +:10BCF0002D7C80C051CF8034803C3A2314043A20FC +:10BD00009424A5B0AD8880203A209404B0523A2003 +:10BD10009424AD88B0573A2014048001B05C3A20D6 +:10BD20001424AD808400100F801E100F801F44016A +:10BD30002D903A2014043A209424A400AC08440125 +:10BD40002DA4B0613A2014043A209424A400AC0835 +:10BD500044012DB8B0663A2014043A209424A4007B +:10BD6000FA54AC088420B03F4900380244012DCC7D +:10BD7000B06B3A2014043A209424A40050FF80C0F1 +:10BD8000AC0844012DE0802F3A2014043A2094247A +:10BD9000A400AC08B07544012DF480C13A2014040D +:10BDA0003A231424A40044212E08AC30B03A80C2B7 +:10BDB00081403A2314043A251424A4F012350000DB +:10BDC0002E2004165A2801044800014B50247FFEFF +:10BDD00042212424949140A3880050247FFFF282C2 +:10BDE00042212424949140648408884788C7F281C2 +:10BDF000850014FF8003F184F085540400FFE209FC +:10BE0000E831B06B3803A1113810A00049FFFF548E +:10BE1000F1033803A109380321113810A00049FFAC +:10BE2000FF4BF10438032109380521113810A00017 +:10BE300049FFFF4238052109F105F0013810A00043 +:10BE40003800211149FFFF38F1013800A1093803FA +:10BE50002111381E200049FFFF2F380321098D01D1 +:10BE6000D5CDB03F8140810784A09628E2094EF2EB +:10BE70000089B0A1B05C39C11400B0A6381094009C +:10BE800038228800F2815A180A39C0755004FFFF21 +:10BE9000D81202137FFFA4B08C218C418401964BF1 +:10BEA0009693503F801E504F801FF58349FFFEE858 +:10BEB000F503D50744000064100F801E100F801F8B +:10BEC000F301001F801F000F801E2224000042107B +:10BED000F024FE1C98C8FE54FE1441C08F96021533 +:10BEE0007FFF40300C7602050000883C8860121508 +:10BEF0007FFF12350000D53F5A180B35C811A470CA +:10BF0000A4B18C218C418401964B9693503F801EA6 +:10BF1000504F801FF58349FFFEB3F503D50744005A +:10BF20000064100F801E100F801FF301001F801F80 +:10BF3000000F801E222400004210F024FE1C98C82E +:10BF4000FE54FE1441C08F960215000040300C765E +:10BF500002050001883C88601215000012350001BE +:10BF6000D50A5A180C0902050000021400008801C5 +:10BF7000120500008CA18D428D028CC248FFFF7714 +:10BF8000840080409640E229E80BB07F38108101A0 +:10BF900038138109B07F382081098C01D5F4F00273 +:10BFA0004420006442002424102F801E102F801F84 +:10BFB00094814010240141C388009589222E0000FD +:10BFC00088C7444004B0A57044301E78FEA44021C8 +:10BFD0000C568845ACB0225E0000442019C8FF54BE +:10BFE00040528CB6125E00005054FFFF8805940149 +:10BFF0004083800088259449220400008827FF049C +:10C00000A40840420C968880AD082204000050AF7E +:10C01000805CFE8440210C561224000085005404EC +:10C0200000FFE209E81DB0483803A1113810A00054 +:10C0300049FFFE42B0523803A109380321113810DC +:10C04000A00049FFFE3938032109380E21113815A7 +:10C05000200049FFFE31380E21098D01D5E1ED2088 +:10C06000FCC03A6F9ABCEFFC49FFA8C84413F0101B +:10C070005A080206440FFFAAAE08D5038400AE0892 +:10C080003C0DFAAB9E46E622E9048E09E605E80F70 +:10C090003C0DFA974412CE683C2DFA9A4432B50C06 +:10C0A0003C4DFAA149FFDB3F5A0008038401EC0430 +:10C0B0003A6F9A84DD9E3BFFFCBCEFFC49003A17C7 +:10C0C000490039353C0DFA978421AE4149003C8E38 +:10C0D00049FFA8945A08020449FFFA58440000A0F6 +:10C0E0004900288AEC044402B4AC3C1DFA973BFF9B +:10C0F000FC844800393A3BFFFCBC8404EFFC3E075B +:10C10000E8FD440000A1490028773C0DFA9744124D +:10C11000B3AC4422B50C3C3DFAA149002D7F2E075B +:10C12000E92B5A08010A4402B3404412B3E249FF22 +:10C13000AA4D49FFE61A3C1DFAB38402AE083C1D25 +:10C14000FAA8AE0849003A612E07E92B5A08010403 +:10C1500049FFE60449003B4F4400007FEC043E07E2 +:10C16000E965FA043E07E9243BFFFC84840248FFAA +:10C17000A4B03BFFFEBCEFF82E07E92B5A080107DD +:10C180004402B340842049FFA9B32E07E9688E0317 +:10C19000E602E80D2E07C5D45A08010A49FFD2A0CD +:10C1A00084023C1DFA9949FFA8ECD50849FFE5EA4D +:10C1B000F081F101840049FFA8E43C0DFA97A64103 +:10C1C0005A180D048423AE41440000A349002814EA +:10C1D0002E07C5D55A08010C3C0DFA97A6005A083F +:10C1E00001072E07E96849FFE61AD5074402451002 +:10C1F0004412400049FFAAAB4402D4044412B4885C +:10C2000044328F704422D50C4442D3F8490022CBEB +:10C210003C3C027984004412D4849898A49038203D +:10C2200080098C025A0848FBEC083BFFFE84DD9E27 +:10C2300084003E0004162E07C53A3C2C0279944136 +:10C240008E2488223C3004E0A4483A6FA0BC964B70 +:10C25000E061E80C94028E048802A40096035EF06C +:10C260007FECE80484013E00041649FFA7C75A0882 +:10C27000021F49FFE6F7C81B3C0DFA97A6015A08B2 +:10C2800003072E07E9245A081413D5035A08061089 +:10C2900084C03E67E92449FFF98E2E07E93A5A081F +:10C2A00001043E07E9113E67E975D51049FFA7A6CD +:10C2B0005A08020D49FFE6D6C0093C0DFA97A601BF +:10C2C0005A08060584013E07E9752E07E924E6149D +:10C2D000E8048C013E07E92484004412D05C8040CD +:10C2E000382081098C014462D05C5A0812FB2E0769 +:10C2F000C5D65A08010B2E000431C8074402D404E5 +:10C300008026490026DAD50E3C0C02793C1C0278C6 +:10C3100049FFAA1D84008020381301098C015A08A6 +:10C3200012FD2E77E9115A78011649FFA76780C0E0 +:10C330005A08021184004412D40449FFFA5C8007B1 +:10C340004412D40449FFFA5780064412D40449FF2A +:10C35000FA5284013E00045C2E07E9605A08120D6F +:10C360003C03F4D784214900277F5A0801062E1088 +:10C37000045C490026D72E17E92B5A1801064402FF +:10C38000B34049FFA8B52E07E9605A0812103C03D4 +:10C39000F4D78422490027685A08010984022E1024 +:10C3A000045C3A6FA084480026BD3A6FA084DD9EED +:10C3B0002E07E9603BFFFCBCEFFC5A08120E3C0361 +:10C3C000F4D7842F490027505A080107840F2E10F4 +:10C3D000045C490026A72E07C5D35A08010C3C0D62 +:10C3E000FA97A6015A080A07EC043BFFFC8448FFB1 +:10C3F000E61BEC043BFFFC84DD9EDD9E3A6F9ABC9D +:10C40000EFFC2E07E9464E0300872E000432C804D5 +:10C410002E07E95FC0052E07E9335A08012449FFBA +:10C42000BADAC8202E07E97EC81D2E07E9115A087E +:10C43000010CFA0249FFA34D84003E07E911840173 +:10C440003E07E97ED50F49FFF73C5A0002F444024B +:10C45000D50C3C13E3124422B3A749FFEF0D5A0059 +:10C4600002EA3C0DFA97A6412E07E97E5A1006040F +:10C470005A180B125A0001092E0004585A000105DF +:10C480002E07E96FC04884013E07E9343E07E92FD3 +:10C490008401D5425A00010A2E0004585A000106B0 +:10C4A0002E07E95B5A0801254403F04A4410005561 +:10C4B000AE403C1DFAB3A608C0FF84003E07E97EEB +:10C4C0003E00045884013E0004592E07E9605A08D2 +:10C4D000120E3C03F4D78425490026C65A080107EA +:10C4E00084052E10045C4900261D8402D5152E07F4 +:10C4F000E9635A080F1184003E0004193E07E963FE +:10C500004400007149FFA2E53C0C02733C1C02751B +:10C5100049FFA91D8401EC043A6F9A84DD9E2E0721 +:10C52000C5D43BFFFCBCEFFC5A08010A44029370DF +:10C53000501000285020005849FFD1EF3C0DFA97C9 +:10C540004412CE682E27E97B2E37E9482E47E9268C +:10C550004900076D2E07C5D35A0801102E00044C60 +:10C560005A08010C4402CE6849FFF20DC806EC04DB +:10C570003BFFFC8448FFF4E8EC043BFFFC84DD9EB9 +:10C580003A6F9EBCEFF88400100F80073E00042B2A +:10C5900084C02E07E942E2C0E85F3C0C01EA95F155 +:10C5A00038501901DE253C2C01ED3C0C01EC88478C +:10C5B0004432D05CA65138001911A6903C4004E0EA +:10C5C000490023713C1C01EA8827A488FE17AC08A7 +:10C5D0003C0C01EC381019013C03E62EE220E8087F +:10C5E0002E07E9265A00FF058C013E07E9263C0C80 +:10C5F00001EA38501C01DE153C1C01ED2E27E90C28 +:10C6000088272E300417A609504F8007A64880A619 +:10C6100049FFF6BB3C1C01EA8827A488FE17AC083A +:10C620003C0C01EA38501C01DE153C0C01EC3C1CB2 +:10C6300001ED3C3C01EE94B238109C0038001C1116 +:10C64000884349FFEECE3C1C01EA88E1A478FE0F46 +:10C65000AC388CC1D59F006F80075A68012B2E0023 +:10C66000042C8C013E00042C4400007249FFA231CE +:10C670002E00042CE60BE9222E00042B84203E1011 +:10C68000042C3E1004263E67E9335A0801182E0098 +:10C69000042A8C019600E60BE90F440000743E105A +:10C6A000042A49FFA2164400005549FFA525D506D6 +:10C6B00084003E00042C3E00042AEC083A6F9E845D +:10C6C000DD9E3C0DFA973A6F98BCA6015A0003060E +:10C6D00049FFB98DE603E9072E07E9605A00050412 +:10C6E0005A08120A84003E07EADC3E07EADD3E07EC +:10C6F000EADED5673C0DFABE5A08010984003C0FFA +:10C70000FABE4402B51049FFB95A4402D54044125A +:10C71000B51C49FFBC5C3E07EADE49FFB9685A0810 +:10C7200003274402B3634412B36A49FFA70C446071 +:10C73000005F8401844080608080842C80A249FF57 +:10C74000A5BD3C0DFABE5A08010A84003C0FFABE92 +:10C750004402B51049FFB933D5048EC197B0CEEA73 +:10C760004402B3634412B36A49FFA72149FFB942A7 +:10C7700080C05A08011D49FFB93A5A0803098006CA +:10C7800049FFB9324400006149FFA1A349FFB92F15 +:10C790005A080505840149FFB92749FFB9285A08F5 +:10C7A000041184013A6F988448FFB91E49FFB91FEC +:10C7B0005A08030884003C0E010F84013E07E92F4C +:10C7C0003A6F9884DD9E3A6F9ABCEFF4840C49006E +:10C7D000251D4403F04A44100055AE4049FFA6BD54 +:10C7E0003C0DFA9A2E2004612E400432B46084037A +:10C7F000FE14842A2E2004304202047388022E2064 +:10C80000045B441003E8420104732E27E9684410D6 +:10C8100000644201047380402E0004192E4004314C +:10C82000FA2EFE0C926284254202047396C64410CE +:10C830000032420184732E37E9154410271042015B +:10C84000847388023C080B9E49002A3F3C0DFA97EE +:10C85000A6415A100D0B2E10044CC9074412B3B355 +:10C860004422CE6849FFD8922E07E9215A080105D3 +:10C870008402480000932E07E9605A081904490011 +:10C8800024842E07E981C80C49FFC9A55A0801096B +:10C890003C1DFA972E07E968A64949FFA7772E079E +:10C8A000E9745A08010E4402B3AC3C1DFA9A4422C2 +:10C8B000B50C3C3DFAA33C4DFAA1490026743C0D51 +:10C8C000FABC5A08014E2E07E97084C03C6FFABCCE +:10C8D0005A08552D3C0DFAA13C1DFA97B61F44226B +:10C8E000B3634402B4AC3C3DFA9A4442B50C3C5D9F +:10C8F000FAA3490027813E07E9602E0004275A0861 +:10C90000050B3E07E96044022D50FA32AE403E600E +:10C910000427D5105A08040F3E07E96044022D5041 +:10C92000FA31AE403E600427D505440000553E076D +:10C93000E9702E07E9604900247296003E07E91964 +:10C940005A00032C5A08020D4403F04A44100055C3 +:10C95000AE403C1DFAB3A608C0FF48FFFF8B49FF5D +:10C96000AAC52E07E9685A0803072E07C666C8033A +:10C9700049FFA6682E07E9715A08010F84003E0797 +:10C98000E97149FFFEA03C0DFAA8A640C9FF842129 +:10C99000AE40FA03D5028401EC0C3A6F9A84DD9E16 +:10C9A0003A6FAABCEFF449FFA4294E0201122E07E8 +:10C9B000C5DC5A0001044800010C3C0DFA9A4900FC +:10C9C0000B954412D1DC4402D79C49001E19440245 +:10C9D000D79C4412D1DC49001D544402D79C441218 +:10C9E000D1DC3C2C02784900101B4402D79C441235 +:10C9F000D1DC3C2C02784462D79C49001775840036 +:10CA00003E07E922850050A30008447000FC5093C3 +:10CA100000D051C300D8B4064E0200D40003005425 +:10CA20004E0200C1001300CA4E120097000300CB53 +:10CA30005A08030A42041C24403500008809A483D4 +:10CA4000A444D50842041C24403500008809A48170 +:10CA5000A4424010C008A019FE5749FFF3B9842032 +:10CA600049FFF3040213006696C1E223E80784003D +:10CA700010030054100300CA8061000300CB22534E +:10CA80000006C056E602E93D5EF2821C84A0E9037E +:10CA9000445004375A08022A8403100300CB0203CF +:10CAA00000694412D7F41203006B0203006AF38199 +:10CAB0001203006C42041C2440448000402E0000FD +:10CAC0008820A421A522A04941E24008A511A492F2 +:10CAD000400F000440214008FEA7B6BF49000B6587 +:10CAE0001203006AF301B4BF02130066222300069A +:10CAF0009A0BFE2C42010C7340000416AC36D50A8A +:10CB0000222300699A0BFE1442028C734000041623 +:10CB1000AC36022300662203006A225300079A53B0 +:10CB2000FE0C42028C7340000816AC37D52F22232E +:10CB3000002E9A0BFE8442228C734021045622530D +:10CB4000002FACB622230007FE2C42010C734000DC +:10CB50000416AC37D51B2223002E22130006525098 +:10CB60000002FE8442228473846240210C56221308 +:10CB7000002FACB622230007FE44421288734010F7 +:10CB80008C368E01AC7710030054220300064E044D +:10CB900000048400AC36220300074E040004840025 +:10CBA000AC37040300165A080106040300265A0095 +:10CBB00001092E07E9228C013E07E9228400B6060E +:10CBC0008D01506300FC5A800A0448FFFF26EC0CDC +:10CBD0003A6FAA84DD9E3A6FAABCEFFC2E07E92BC0 +:10CBE0005A0801074402B340842249FFA4812E075A +:10CBF000C5D45A0801064402D3F849FFCE702E0767 +:10CC0000C5DA5A08010A4402D4044412CE68442208 +:10CC1000D1DC49FFEDC02E07C5D35A08010F2E0005 +:10CC2000044C5A08010B4402CE6849FFEEACC8051B +:10CC30004402D3F849FFF19B4900285C2E07E968BC +:10CC4000540000FBC80C4402D1DC4412B37A3C2CE3 +:10CC5000027849FFD4EB3E07E8C8D50484023E07BA +:10CC6000E8C83C0C027849FFF8344402D40444126A +:10CC7000B4A444228F708460848549001D5B8400C5 +:10CC8000442291403E07E95F4412CE684402B4A4B6 +:10CC90005031001449FFF2A72E07E9605A08120E1E +:10CCA0003C03F4D78423490022DF5A080107840398 +:10CCB0002E10045C490022363C1C02793C0C0278A0 +:10CCC000503080105050001084884462D05CA5E839 +:10CCD0003823110188479693AC980272801238234A +:10CCE00011018847969312218012A4984091001157 +:10CCF0002E27C53A884494918841A5D097FBE12717 +:10CD0000E804A4909693AC988CA28C625A400904D3 +:10CD10008489D5DE3C2C028849002E313E00045B1C +:10CD20002E07C5DA5A0801102E0004305A08010CEB +:10CD30002E07E95FC0082E000431C8054402D40460 +:10CD400049FFEE1649FFA25AC00D2E07C5DC5A084E +:10CD5000010A3C0C02784412D1DC3C2004E049007A +:10CD60000B592E07E95FC8074402CE684412D40469 +:10CD700049FFF24E2E07E95F4E0200C984003E07CC +:10CD8000E9613E07E94A2E07E9605A08120E3C03A2 +:10CD9000F4D78424490022685A08010784042E101D +:10CDA000045C490021BF2E07E93B5A0801073C00FB +:10CDB00004E08E0A3C0804E02E07C5D45A000106A0 +:10CDC0002E07C5DA5A0801064402910C49FFCEEE3F +:10CDD00084023E0004002E07E9485A08010E3C0D6B +:10CDE000FA9AB400920E96065A08010749FFF6A86F +:10CDF0003E000400D50484003E00040084013E008F +:10CE000004043C1C02783C0C02884422D1DC3C30F7 +:10CE100004E04442B37A84A149FFA8C284003E00E2 +:10CE200004042E07E942C01249FFA1E85A08020F84 +:10CE30002E600431CE0B4402D1DC4412D4044422CF +:10CE4000B37A490003B13C6BF4D44402D1DC49FF0E +:10CE5000FB992E07C5D95A08011C3C0DFA9AB4005B +:10CE600096065A0001083C0DFAA3A60096065A0839 +:10CE700001102E000424C80C4402D1DC4412D40456 +:10CE80004422B37A49FFF57B3E000432D506840084 +:10CE90003E00043249FFF4EE3C0002195A08010B2F +:10CEA0003C0DFA9AB400920E96065A0801043E0010 +:10CEB00004342E0004345A08010F49FFB58CC80B06 +:10CEC0003E000434FA2E8404844349FFB587840568 +:10CED00049FFB58A2E0004325A08014C3C0DFA9ADB +:10CEE00084203E10040AB400920E96065A080105EA +:10CEF0003E00040BD5033E10040B49FFA17F5A08E6 +:10CF0000023984003E07E92FD5343E0004012E008B +:10CF100004325A08010649FFF48E3E0004322E07FF +:10CF2000E9612E17E912E201E8048C013E07E9618C +:10CF300084003E07E9423E07E9263C03F4DEC019BF +:10CF40003C23E4D23C13F4D03C03F4D4E24140113E +:10CF50003C1BE001E8058C013C0BF4D4D50A8400AD +:10CF60003C0BF4DE3C0BF4D33C0BF4D43E000461E8 +:10CF70003C0002195A0900113C0DFA9AB400920EB5 +:10CF800096065A08010A84048040FA2E49FFB52605 +:10CF9000840549FFB5292E0004323E0004332E07D4 +:10CFA000E92B5A0801074402B340842349FFA2A099 +:10CFB0003C53F4EA3C03F465D8052E07E9433E07E9 +:10CFC000C5DB2E07C5DB5A08013E3C0DFA9A3C1D15 +:10CFD000FAA3B400920196065A000107A60892012E +:10CFE00096065A080130A60892039606C82B2E0012 +:10CFF000044E3C1DFA97490004D13C0DFA97A60156 +:10D000005A0003045A08061B2E07E94DC0172E00CC +:10D010000460C8143C03F4D3C8112E000461C80E88 +:10D020003C0C02784412D1DC4422B37A3C3004E058 +:10D03000490004CE3E000431D5054900047A3E0083 +:10D0400004312E37E942CB043E37E97BD50D44024B +:10D05000D1DC3C1C02783C2C02794442D56C445211 +:10D06000B3B349FFC5352E57E97BC5512E27C56A95 +:10D070002E37C56B924192614402D56C8420E22523 +:10D08000E80BA5008C218882AD00A5018C0888835F +:10D0900012407FFDD5F53C0DFA9AB4009202960637 +:10D0A0005A0801072E07E968C8033E00041B8400E4 +:10D0B0003C0E010F3C0E01103E07E96F3E07E9618F +:10D0C0003E07E9633C0DFA97A6015A0803172E079D +:10D0D000E9785A08030F49FFD44DC8052E07E95ACD +:10D0E0005A08010884033E07E978D57A5A0803797B +:10D0F00084003E07E978D5745A080A732E07E97848 +:10D100005A0804F684013E07E978D56A2E000432F5 +:10D11000C8672E1004233E07E9423E07E97B3E0024 +:10D1200004253C0E01125A10010C3C0C010F442046 +:10D13000EA60E240E9073C23F4DECA048C013C0EBD +:10D14000010F3C0C01104420EA60E240E90E3C2053 +:10D1500002103C33F4EDE262E802C1058C013C0EA2 +:10D160000110D5033C1E01102E07E9185A080108CA +:10D170003E07E93484003C0E010FD50484003E07CD +:10D18000E9342E0004185A08011584003C0E010FE2 +:10D190002E17E97C2E07E963E201E80E2E27E961EC +:10D1A0002E17E912E241E9088C013E07E963D50434 +:10D1B00084003E07E9632E0004315A080107840009 +:10D1C0003C0E010F3C0E01102E67C5D45A680109B0 +:10D1D00084003E00045049FFCC703E60045049FF7B +:10D1E000F90F5A080204480000F32E0004325A08CE +:10D1F000010784003C0E010F3C0E011049FFF9911C +:10D200004402D56C2E17E97B4422D79C4432D1DCF2 +:10D210003C4C027849FFAC182E07E9605A08120E00 +:10D220003C03F4D784264900201F5A0801078406CE +:10D230002E10045C49001F7684003E07E93B44122F +:10D24000D79C3C0C02782E27E97B4900287C2E07CE +:10D25000E92B5A0801074402B340842449FFA1483E +:10D260002E07C5E35A08010A4402D79C4412D1DCB8 +:10D270003C2C027849002A4D4402D79C49FFC10941 +:10D280002E07E9605A08120E3C03F4D784274900A0 +:10D290001FEB5A08010784072E10045C49001F4247 +:10D2A00049FFFB804402D79C49FFBB0D2E07C5D325 +:10D2B0005A08011D2E00044C5A0801194402CE6878 +:10D2C00049FFEB61C8134402D1DC4412D79C2E27DE +:10D2D000E97B4432B49049FFEB6349FFEE325A08D0 +:10D2E00001064402CE6849FFDE9284008421844115 +:10D2F0003E17E9693C0E01073E07E9582E67C54114 +:10D300003C7C01EB80A04412D79C8060853D81422B +:10D31000448000FFE266E824B48140F224025AF01F +:10D320000105CC048085D5178440A10F38439101B5 +:10D330005CF20100E808E6951240800AE9068C01DB +:10D340009600D5031280800A0440800912A0800B49 +:10D35000E285E9E98C61501080FC80A4D5DC3E07B1 +:10D36000E9583C5E01073E27E96949FF9F5549FF9F +:10D370009F455A08020C4402D79C2E17E97B442291 +:10D38000D1DC3C3C010749FFEE0249FFF99C2E0726 +:10D39000E97B3E00041549FFB31EC0093C000203AF +:10D3A000E619E8078C013C080203D5033C08020398 +:10D3B0002E67C5D45A68010E3C0DFA97A6015A0093 +:10D3C000060A5A000B0849FFD013D50480C0D502C5 +:10D3D00084C18006EC043A6FAA84DD9EFC2080E1C3 +:10D3E00080C2C00D5A00041184003C0BF4DF49FFD9 +:10D3F000C76844423FD844323FD6D50A44423FD260 +:10D4000044323FD0D50544423FD844323FDC84000B +:10D410009680E246E80738138101381201098C0131 +:10D42000D5F83C03F4DFAC18FCA0FC40A7002E6745 +:10D43000C5415A400107848044728F708124D512FF +:10D440004442937184A0D608087200018CA1107226 +:10D450007FEA9768D5F9A6003C43E62E5A08014FAB +:10D46000D5099760E2A6E8F899678C81109283EC61 +:10D47000D5F92E07E96E9A10E402E9095A38010835 +:10D480002E07FFD0E605E8078C01D50284003E0791 +:10D49000FFD0846084003E07E96EA609C82C5A308C +:10D4A00001085A28010C3C03F536E614E9073C0054 +:10D4B00004E08C053C0BE499D5033C4BE4992E0722 +:10D4C000E93B5A0801073C0004E08C0C3C0BE49952 +:10D4D0003C03F4DEC005440000B43C0BE4993C0D71 +:10D4E000FA9AB400920296065A08010C3C0004E035 +:10D4F0008C19D5053C03E385D50284003C0BE499E7 +:10D50000FCC0FC40A10394C93CADFFF538620501A5 +:10D51000A10490C288838460A7E180039F79976A01 +:10D5200051C3800140FE1407E9324E55002E00859C +:10D530000002E0A8E829009200005014FFFF964A7C +:10D5400051E4800140FF0407E91F4E15001B00F560 +:10D550000003E02FE816DF034C14801481E542F04D +:10D56000A07340F7840840F13C0002F7800040F7C8 +:10D57000801140F79807E8038C6196D88C019600DB +:10D580008C21964AD5E08CA1976AD5CD44200064C1 +:10D5900042118824400080165E000019FCC03C0F38 +:10D5A000FFF5DD9EFC40EEE8F28180E04420005073 +:10D5B0008121B00A842049002BDB842044200050C4 +:10D5C000B01E49002BD5B0328420442000504900C1 +:10D5D0002BCFF001A6004E0201AA8400F082F08356 +:10D5E00080C0F001A600E2C04EF200A1A03941E3E4 +:10D5F0000408385019014C534096A03D947288207D +:10D600000404800544A000FFF085A03B810A382077 +:10D610001901FA18FE1444200064400008163C2347 +:10D62000E301E00240203C1AF286A68BA60AF289AA +:10D630003C2DFFF5F28784408082F284F309E2609A +:10D64000E92FA6C9A748F388F308E265E926F3079E +:10D6500000F18002806542303C7340F18408F3059C +:10D6600040F1BC00F30602F7800040F78011E06F44 +:10D67000E811F304E20840803C1BE26040303C1BB0 +:10D68000E2AA40A2BC1B8C41E285F3844042BC1B51 +:10D6900096918CA19768D5D98C019600D5D0C213EC +:10D6A0008A8A8C814E440003FF22F304B00A8A6800 +:10D6B0008C61384019094E340003FEDAB01E383050 +:10D6C0001909D507B00A38201909B01E38201909E0 +:10D6D000B03238201909F00388409611F083F00227 +:10D6E000C821A03B3C1DFA8E38007801A489E202D3 +:10D6F000E919A44AE220E9163C0DFA9AB400920115 +:10D7000096065A0001093C0DFAA3A600920196065E +:10D710005A080109800780260424800549FFFEF38A +:10D72000F0828CC197B048FFFF5E854080CAF0014F +:10D73000A600E2C04EF200C3A0394083040838506E +:10D7400019014C5340B8802680070424800549FF06 +:10D75000FEDAA07D83C094328801A641A6C0F18480 +:10D76000A742A643A03BF185384019015CF200D3E3 +:10D77000E90984003C0BF4D33C0BF4DE85404800FF +:10D78000009EB03238001901F086B00A3800190145 +:10D79000F087B01E38001901F088F003E619E85F41 +:10D7A000F0049C41F0058A2396499C818A45E62332 +:10D7B0009691E8058403FE0CE040E807E643E84F55 +:10D7C0008403FE14E020E94BA03C89000004000122 +:10D7D00050F07FFF5CF78010E8420084000050F4B6 +:10D7E0007FFF5CF78022E83B04FF800100F78000A8 +:10D7F0005AF801385A1803185A2801363C0DFFF51B +:10D8000004148005A60242040024886094D988612B +:10D81000A498F3049693880394018801A4C096DB2E +:10D820008862D5195A2803205A18011E3C2DFFF58D +:10D83000806004148005A69242328873F50594D95D +:10D8400042028873940188618801A4D8A40096DB01 +:10D8500096038860E06456378001D5068460D5045D +:10D860008461D502806F3C13F4DEC10A3C23E301DE +:10D870008403FE14400200075BE80155D5165BE007 +:10D88000011A5CF200B4E8168001F406442000643A +:10D89000FF148044F507F408FF6444400037FF2C70 +:10D8A000E044E904CB03C106C0055005000154A0C3 +:10D8B00000FF8CC197B048FFFF3CF001A600E604D2 +:10D8C000E8074EA200093C03F4D38C01D505920170 +:10D8D000E340E8FA84003C0BF4D3F0035CF000462C +:10D8E000E90484003C0BF4DEF00285E55A080103EC +:10D8F00085E93C13F4D3E22FE90884003C0BF4D310 +:10D900003C03F4E93C0BF4DE3C03F4DEC008F10117 +:10D910008E013C0BF4DE8400AE0884013E000461FD +:10D92000D5055CF200B4E9B2D5C0ED18FCC0FC002E +:10D9300084203C1BFFF13C1BFFF03E17FFE7441027 +:10D9400000403E17E8953E17E8943E17E8933E17CF +:10D95000E8923E17E8913E17E89084203C1FFFFCB8 +:10D960002E10046084003E07FFE83E07FFD83E0704 +:10D97000FFE53E07FFE43E07FFE63E07FFD95A18E2 +:10D98000010B3C1DFA8E3C27F52BA44CE041E8032B +:10D990003E0004608400FC803C43FFEF3C2DFA8E87 +:10D9A0003C33FFEEC009E68FE9038E85AD11E66FCB +:10D9B000E9058E65D502AD11ACD4A6095A08060456 +:10D9C0008401D5032E07FFDAAE10DD9EFC4AF082FB +:10D9D0003C0DFA8E81012E17FFD8A5C2F289F38E75 +:10D9E000A6005A1801049401D5029601F0863C0D58 +:10D9F000FFFB84C2A642A603F181F08A2E07FFE84E +:10DA00005A08010384C08401100F804A94319600A3 +:10DA10005210001252000024960085209648FA42C7 +:10DA2000100F8049100F804D3C0DFA7C101F80486C +:10DA3000102F804B101F804C129F8023109F804E10 +:10DA4000109F804F49FFD4E2B0538041B01249FF8C +:10DA5000D518F001F1028C01FE3494018801501FA9 +:10DA60008046804149FFD4D73C0DFAA5FA33101007 +:10DA7000000A12900004840049FFD5C64403F04A0E +:10DA800044100055AE4049FFD4BC4413F140A608F1 +:10DA90005A0001FF3C0DFAA5F102222F802302005B +:10DAA000001196499A4192219649FAC2401098D79E +:10DAB0009631F2842E27FFE8F0839649200F800CE0 +:10DAC00041E080105A28010E3C2DFA8E85EAF304BD +:10DAD000A492949340213C56E043E8038CF997F9D3 +:10DAE000F2043C9DFA8EE0E214FF8008F304022465 +:10DAF0008001006F800CF28740A10C079EB4E64BBA +:10DB0000E8089E8C9690E65DE80484413E27FFD9A4 +:10DB10004EA200502E2FE8955A2040612E47E892E1 +:10DB20002E37E893F4852E47E89184A0F48B2E4796 +:10DB3000E890F48CF405E283E920F401FF1CF48DF5 +:10DB4000F40BF70CE2E4E916F70D40F39000F7024E +:10DB500040F7840840F3BC0002F7800040F78011D2 +:10DB60004EF4000452F7800088AF8C81976B9720A9 +:10DB7000D5E98C6196D8D5DFF307E065E9332E3718 +:10DB8000FFD9C3302E3FE894403F0C014E340003D0 +:10DB9000FEDAF40396DA9AA24E240003FE929692DD +:10DBA000E444E803E464E91E84413E27FFE7D51A14 +:10DBB000440000403E07E8953E07E8943E07E8939E +:10DBC0003E07E8923E07E8913E07E8903EA7FFE750 +:10DBD0003EA7FFD83EA7FFD9D5073E07E8953FE708 +:10DBE000E8945AA001048400D57BC0039E319600BE +:10DBF000F2019F51F203E045E8029D71976884406D +:10DC00004FE700049E899690F285F20A9F9140FFAB +:10DC10001807E8029D89F204842440410496846038 +:10DC2000972197B0F70580438023F48DE2C7E9245C +:10DC3000F4018A20FF3CF48BF18C8080F10CE2A48B +:10DC400088249648E916F10B04FF80028824944941 +:10DC5000882F02F08000A448884F04FF800D964B67 +:10DC6000E02F9693E8038C6196D88C819720D5E7B6 +:10DC70008CE197F8D5DC2E47E8915A48400C004FCC +:10DC800080143E67E8923E47E8933E07E8913E578E +:10DC9000E890F401F003420F1073F4029401880439 +:10DCA00002548005A500FF4C840940F281F6E04F44 +:10DCB0009723E915025480068A449F09FF2C969306 +:10DCC00040F201F6E04FE90B44000064FEC440114D +:10DCD0008436E439E98984013E07FFD884013C1D7C +:10DCE000FFFC5A100131C1055A10024A4800008158 +:10DCF0003C17FFF0F207E022E8038420D506022457 +:10DD00008002E041E80484213E17FFE62E17FFE67B +:10DD1000C9185AA80117F108C914C8132E17FFE72C +:10DD20005A1801102E17FFE5F2068C218C419648F7 +:10DD30009041E0413E17FFE5E85B3CAFFFFCD518A2 +:10DD40008400D5165AA80118F108C915C8142E1751 +:10DD5000FFE75A1801112E17FFE5F2068C219648AD +:10DD6000E2413E17FFE5E84484223C1FFFFC3E07EA +:10DD7000FFE5D53E84003C0FFFFCD5FAF208021403 +:10DD800080075A2001045A0801202E07FFE40024CE +:10DD90008001E240E9048C013E07FFE43C03FFF10F +:10DDA000E220E9048C013C0BFFF12E07FFE4E24086 +:10DDB000E9053C03FFF1E220E81B84003C0FFFFC77 +:10DDC0003E07FFE4D51384003E07FFE484005AA019 +:10DDD00001053C03FFF18C013C0BFFF13C03FFF11B +:10DDE000E220E80684003C0FFFFC3C0BFFF13C0DF9 +:10DDF000FFFC5A0802048401D50284003E07FFE8B4 +:10DE00002E07FFE85A000104480000A649FF99F6D2 +:10DE1000C00E2E07C5DC5A08010B3C2DFA8E3C0CB7 +:10DE200002784412D1DCA494490002F43C3DFA8EFD +:10DE30003C0C02883C1C02788048A4DCF40984A1D4 +:10DE400049FFA0AEF009A6004E0200863C0DFA8EF6 +:10DE500084C0F087F00145EF80008E01F088F00A61 +:10DE60008E01F08A000F8028F08D000F8020F08F47 +:10DE7000F009A600E2C0E86F0494000140A3040882 +:10DE8000892A02548000DE6404040003380019016A +:10DE9000F086F106F00EE201E95B04040004880A52 +:10DEA000A641A680C1059E099600F083D502F183A4 +:10DEB000F008E020E8048C219608D502F00FF085E8 +:10DEC000C2049F119720D5028082F00AE040E80446 +:10DED0008C419690D502F20D84608003E244E91BE8 +:10DEE000F101F703FE648A07F18BF08CF00CF10569 +:10DEF0008807E2279600E90CF00BF10288079401ED +:10DF000088018CE1A40097F8886096DBD5F08C81BD +:10DF10009720D5E5F107A48D8429FE8440F105F60C +:10DF2000E06FE912F2068E018A62F20796DBA49690 +:10DF3000FE1440F005F6E06FE90704040002380023 +:10DF40002801E603E8054052F804125480008CC111 +:10DF500097B0D58F020F80083C0BFFF03C0DFFFC03 +:10DF60008E025C000001FCCA4402519B4412519A8B +:10DF7000A600A64840002008FE0FDD9E4402519DE9 +:10DF80004412519CA600A64840002008FE0F441FE2 +:10DF9000AE6088205CF0805AE903440051A0DD9E09 +:10DFA00044025198A60092019606DD9E44025198C3 +:10DFB000A60092029606DD9E44025199A600DD9EBF +:10DFC0004412519EA6089600C00EA60896005A005C +:10DFD000010BA60896005A000207A60896005A00F0 +:10DFE00003038400DD9E4412519F9600AE08DD9E1F +:10DFF000FC0044625198AE704412D700B60184010F +:10E00000A98910208009100080081030800A1000B3 +:10E01000800B8001802449FFD374A630FC80FC0073 +:10E0200084418420806280824400B10049FFFFE285 +:10E0300084003C0FFAC83E000414FC80FC003C1332 +:10E04000F4794400003C49FF9C9F3C0BF45D3C1379 +:10E05000F4794400003349FF9C973C0BF45B3C137C +:10E06000F4794400003249FF9C8F3C0BF45A3C1376 +:10E07000F479440000C749FF9C873C0BF4593C13DA +:10E08000F4794400003249FF9C7F3C0BF458FC803B +:10E0900080413C53F4783C13F479D126FC004430A1 +:10E0A00000FC42010C7380C00200002549FF9C72F5 +:10E0B000120300253C13F4790203002649FF9C6AF1 +:10E0C000120300263C13F4790003007449FF9C629C +:10E0D000100300743C13F4790003007A49FF9C5A42 +:10E0E0001003007AFC80DD9EB420922696465A18D2 +:10E0F0000109B44092459686CA043C1E00DDD51045 +:10E10000B420922696465A180109B4009205960644 +:10E110005A0801048402D50284003C0E00DD3C0C48 +:10E1200000DD3E07E915DD9EFC01F181441000FC95 +:10E1300042010473041000165A100206041000264F +:10E140005A180232001000F3E622E82D021F800266 +:10E150004432D5CC8E3F5CF083FAE8042E17E915E3 +:10E16000C10A021F80038E3F5CF0892EE8192E172A +:10E17000E915C116381188004442D5CCC90584017F +:10E1800038020808D510E625E80E8C21964838128A +:10E1900008085A1805098421101000E0D5048400ED +:10E1A00038018808FC81FC02F182F281964B96834B +:10E1B0009A5190104E140003FE4A964BC9028421D6 +:10E1C000223F800397018A03023F800585E29AE39C +:10E1D00096DB880340003C165EF1021C96C3E903FF +:10E1E00052210438FE9C40110436964B80434E3435 +:10E1F0000003FE9A949180614E140003FECAE0432E +:10E20000E8039441964B9A61964B5EF0896D8001CC +:10E21000E9034400096C96434E14000384009603FE +:10E22000FC82FC003C13F4794400003C49FF9BACA9 +:10E230003C0BF45C3C13F4794400003249FF9BA48E +:10E240003C0BF4563C13F479FA0049FF9B9D3C0BC0 +:10E25000F4543C13F479FA1349FF9B963C0BF457A2 +:10E260003C13F479FA0E49FF9B8F3C0BF455FC806C +:10E2700080413C53F4783C13F479D12EFC004430B7 +:10E2800000FC42010C7380C00200004E49FF9B82DB +:10E290001203004E3C13F479000300A249FF9B7A5D +:10E2A000100300A23C13F4790203005049FF9B7253 +:10E2B000120300503C13F479000300B449FF9B6A39 +:10E2C000100300B43C13F479000300B549FF9B62CE +:10E2D000100300B5FC80DD9EFC0280A1F281B42118 +:10E2E000A0A9F382F48349FFD4A58401F10149FF79 +:10E2F000D4C5F00249FFD4D584C08006842049FFEC +:10E30000D4DD8006F1038CC149FFD5005A6808F7B7 +:10E31000840049FFD4CA49FFD4A0840149FFD4C571 +:10E3200049FFD49B840349FFD4C049FFD49649FFD9 +:10E33000D4B4FC82FC40AE888440A708E244E81ACA +:10E34000A10138520901D214A1059592956A99E666 +:10E350008885A7FA00F20002E2EFE802AFE2A1C569 +:10E3600088C788A7A733A7ABE2C4E802AF2B8C41CC +:10E37000D5E59DD984A092E1506080258125D736CE +:10E38000A688E2A2E82EA081382115014C22C02ADD +:10E3900050F00014B50F94AA8902990D00A400034F +:10E3A000008400028D418B4810A20025B54F8942A0 +:10E3B00000A5000210A20037B54F884AA69310228C +:10E3C0000049A08338A115015022803494918841DE +:10E3D00012A10003A084382115001022005BD50390 +:10E3E000109300008CA18CC1D5CB8C2184A0849F7C +:10E3F000D30FB440382115005A28FF04AF08D505C3 +:10E40000A18138230901AE888CA18C21D5F2FCC0F2 +:10E41000FC4A2E77C53B5CF100248120B63F2E6775 +:10E42000C53A50A3FFFFE909FA133C0BF4C6408339 +:10E43000040880298400D5043C2BF4C6D5F9E207F2 +:10E44000E808B0C23820A005382181098C01D5F830 +:10E45000B43F80473C33F4C644400055B00249FF06 +:10E46000FF3DF0814412CD18B41FF201806749FFCF +:10E47000FF634014A0008400E207E8090220FFFFC8 +:10E48000B0C28828382181098C01D5F7B43F804774 +:10E490003C33F4C644400055B00249FFFF1FF081F1 +:10E4A0004412CC84B41FF201806749FFFF45840009 +:10E4B000E206E80838148101B082381101098C01A4 +:10E4C000D5F8B43F80463C33F4C644400032B00235 +:10E4D00049FFFF04F0814412CBF0B41FF2018066C3 +:10E4E00049FFFF2A429428738400E206E8083814A2 +:10E4F0008101B082381101098C01D5F8B43F804602 +:10E5000044400032B0023C33F4C649FFFEE7F081DC +:10E510004412CB5CB41FF201806649FFFF0DFCCAB8 +:10E52000FC4683C02E07C53AF385F486F0812EA7FA +:10E53000C53BC907406088068401C20984FFD5082D +:10E54000C20484C3841FD5FB84C2841F84E1F30109 +:10E55000FED4808388819521F384403F10003C43A2 +:10E56000F4C622918000F387E0894EF200F59710FF +:10E57000F4889708F489F308F4058883A6E1F38A00 +:10E58000F40AF305888320320025F409F382F306A8 +:10E590008883A6E1F38BF40BF306888320320025F1 +:10E5A00038429800F383C404848438429808F30204 +:10E5B00042938824E06AE903F3028E618923F30120 +:10E5C00042438824FEFC048F80018C8141C1840871 +:10E5D000814142321C2442A1A073806A94D98500F3 +:10E5E00040AF0C00B71FE124E90B38F520114EF7BE +:10E5F0000005B47F886FB67F8C81891CD5F5B47F08 +:10E60000CB038461B67FF303F40142A00424E064E9 +:10E61000E8038943D504F4038E818944950142902F +:10E6200004248D218064F404424480739521878002 +:10E63000408F1000809CE149E90A38F470114EF7D0 +:10E640000003888F8D2141CE0C00D5F6CC02848149 +:10E65000F3018847FE9C4080800040912000854A5D +:10E6600039CF25113CFC00DDE91FB43FF2054230F3 +:10E67000A824F10A403190765010803494498841A2 +:10E680004490005AA513F204441000508848FF0C2F +:10E69000429E24244410006440420496382F0911FD +:10E6A00040948536D520B47F4242282440320C76EF +:10E6B000F40B049F8006504200349521892488225F +:10E6C00002F4800344400050382F05114410005AD2 +:10E6D0004490006442479024421E04244042249601 +:10E6E0004090A536F10722F08000E08FE840F1026B +:10E6F000E423E804F103E423E93AE122E838E4758D +:10E7000038329800E8035A380433F103F2098E21B5 +:10E71000422004739652F202F4088E4142438873F9 +:10E72000852496A238929808992ECB03AEA4D510D2 +:10E730002032000442F38824FFDCE0EFE802AEA4BC +:10E740002022000842F00424FE14E00FE81010120A +:10E750000008D50D8E84E12438029800E804C00733 +:10E760008E01D503C004840438029808FCC6FC4618 +:10E77000F1892E17C53B8383F182F48AF58B2E37FE +:10E78000C53A843FC802842194D943E080243C43A5 +:10E79000F4C6F387423F0424F3818A608E8494D9BF +:10E7A000F484F38895018540F302E143E862F30ABB +:10E7B0003831A8005A38014DF309886AA6D95A3071 +:10E7C000FF34B4BC383290005A30FF2FBE01BF0571 +:10E7D000B6DF38630D0197AFC80594F28867A7D9F3 +:10E7E000D50338739A0042338424F383F308813EBF +:10E7F00088648865F38684A08060F703E0E9E91502 +:10E80000F70188E5F785F70638F39500B4FF3883FC +:10E81000BD015484003F4C8340055AF0FF03F305CB +:10E820008D2188A1D5EB80602051002442608C248A +:10E83000FF4CE0C5E809A750E6A3E9038EA1AF505D +:10E84000A750E6A3E811103100248464D50CF30B23 +:10E8500010010024F50438319011E065E805A6D0D8 +:10E86000C3038E61AED0F3078D418C418883D59D63 +:10E87000FCC6FC422E87C53AF2812E77C53BCD639C +:10E88000B0838142B181C00451C07FFFD502838033 +:10E890009EBAE241E8038EE1D5029DC944200032D0 +:10E8A000FF1444200064F083404208978520F5035C +:10E8B000E225E91004F50000B44642243C7338F127 +:10E8C0008911E28FE903D003D1028D2A8CA1F5834F +:10E8D000D5EFF083B4AAB446422414733C9BF4C72A +:10E8E000382189114E270004E282E80284404C005E +:10E8F000800FF18304F50000B4A642543C733851F4 +:10E9000095114E570005E285E902884515CF800331 +:10E910004DC0000CB4AAB40642041473380181112E +:10E92000E408E9038E078840F7834C708012B42A0C +:10E93000B4064204047338018111E408E9098E0722 +:10E940008840D506B08180E88142B183D59D840A94 +:10E95000FE144040109740022400FCC28E61E66421 +:10E960003C53E2A53C43E2A6E826FC0022600000FE +:10E9700044F0E88038378C0040F1BC004A003C008D +:10E980000410181CE026E91922100001E041D510FE +:10E990008EA19A69E0C1D5F8E026D5048EA19A69C6 +:10E9A000E0C1E90B221000018E819A22E020560777 +:10E9B0008001D5048400DD9E8400FC80FC0044209E +:10E9C00000FC4200887380C08401100300CA501309 +:10E9D000000C500300D28444490021C0440000963A +:10E9E00012030066FC80442000FC4200887322F081 +:10E9F000000984205EF784B7E90284211410002501 +:10EA0000DD9E442000FC420088738421141000160F +:10EA10001010005584201410000FDD9EFC5DF08264 +:10EA2000F2818101FA548420B016490021A184208A +:10EA3000FA54B01F4900219C8420FA54B0284900A0 +:10EA40002197B0318420FA54490021922E07C53A0B +:10EA5000B61F2E07C53BF0903C03E2A5F0953C03A2 +:10EA6000F4535CF00190E8048C013C0BF4533C033C +:10EA7000F4525CF00190E8048C013C0BF4523C032E +:10EA8000F4515CF00190E8048C013C0BF4518420BB +:10EA90008041F0014432CD184442CBF04452CA3098 +:10EAA00049FFFD40F01084209F8197B2F00180461D +:10EAB0004432CD184442CB5C4452CA3049FFFD3247 +:10EAC000B41F84408E019602F092F112F00144329C +:10EAD000CC844442CBF04452CA3049FFFD23F001BC +:10EAE000F11280464432CC844442CB5C4452CA305A +:10EAF00049FFFD188400F0854402CB14F083B01662 +:10EB0000F08884004492CD18F0865004806E5064E2 +:10EB10008025F084854000048000E340E82A080353 +:10EB20000001C0220003002300730011F087F004ED +:10EB3000F107F206A50084003C0BF4C7F30180073F +:10EB400084A049FFFE985CF0005B4EF206A8F0033B +:10EB500088E0F003F1079A38E220E9060803800113 +:10EB6000C0F94800069CF0048D418C02F084D5D495 +:10EB7000F0055A0001044800068484004412CD18B0 +:10EB80004422CB148068B116F50149FFFDF2F01262 +:10EB90004412CC844422CACCF5018068B11F49FFDD +:10EBA000FDE8F0028420F087502009D880A0B40549 +:10EBB000C0118E04E602E90E000280F3E602E90AC3 +:10EBC0000402800FC807040280205CF00065E9029F +:10EBD0008421505280FCDAEC5A18010C840A3E075A +:10EBE000FFF4B41FF6029401F0948400F083D50D75 +:10EBF0002E07FFF4C0F78E01D5F3B406C80DF0035D +:10EC0000506300FC8C01F0832E07C541F103E22024 +:10EC1000E9F5480005C85A0005F45A0804044800FC +:10EC200004D90003001C04140004F08C9401880132 +:10EC3000A641A600F18DF089000F8034B43F100387 +:10EC40000065000F80248E21100300640403000F70 +:10EC5000C80804040005F20C38000A00C010D503EF +:10EC60005A000115B41FF18650907FFE4402CA3C41 +:10EC7000F08F841FF08B4402CC84D5114412CA84D7 +:10EC8000F18F8421F18B8121D5074412CA84F08B46 +:10EC90008120F18F8400F0864402CD18F10C944A53 +:10ECA000F193F213041400058822B45FA7C88E41C3 +:10ECB000A749CF08DA08440000FFF08E8401F084F1 +:10ECC000D551DA4AA68AB47FA74BF1064211887360 +:10ECD00094498460E2A2E940B488888138420C00FB +:10ECE0005A40FF2204740001387391019902A72150 +:10ECF0005A40FF1A04AF800C4C75401680248820BF +:10ED0000F48E0020805B00A0803700708049501294 +:10ED1000003494498801F28AA5034EA3000914AF78 +:10ED20008005D508F4148C418864D5D550057FFF43 +:10ED3000F085F0108E02E207E804F0108E01D50293 +:10ED40009C39F0888027800AF206F30184A049FFED +:10ED5000FD92F084D50B440000FFF08E8401F08416 +:10ED600084E08147F78AF788F785B43FF005F3051B +:10ED7000FE0CF1069881F101880994919401884173 +:10ED8000880184208121F191F408E083E911384160 +:10ED900004114E470005F51188A4F591384004117F +:10EDA0004E4700038924F4148C618824D5EEF105C4 +:10EDB00080048A01FE038427429004734E96000368 +:10EDC0008521F111840AFE0C40902536F103F002F2 +:10EDD00049FFF960000300189606C0753C03F4591A +:10EDE0000413000F844012030034102300CBC1250C +:10EDF00084211213002584231413001610230055B8 +:10EE00004EA20006F1108E214C70C0058C0A120330 +:10EE10000034000F8028F10AB45F1003007DF00673 +:10EE200042008873F101380081111203003F020F84 +:10EE3000800812030028D50E44000190120300251B +:10EE4000840114030016100300551213003F12131F +:10EE5000002822130008840084651213006712132F +:10EE6000002E1413001C0213000910030054103369 +:10EE700000571213002FF30C0414000384401223D4 +:10EE8000002638108D011003007410030075100364 +:10EE90000076100300771003007810030079100348 +:10EEA000007A1003007B1003007C84001403002010 +:10EEB00084011493001B1213002910230056100321 +:10EEC0000084D5780403000FC0254EA20006F01080 +:10EED0008E014C7040073C03F4598C0A1203003435 +:10EEE0000003007DB45FF106421008738001F10158 +:10EEF000380081112213003FE020E8031203003F95 +:10EF000002030028F104E201E805020F8008120361 +:10EF10000028020300255CF00190E80E5023006CED +:10EF20008C0112030025B402A0518809B602220305 +:10EF300000088801A811B4065A080108A436120373 +:10EF4000002EA4371203002F02030028F104E2016F +:10EF5000E805020F800812030028F10C04040003E6 +:10EF60003800050122130029E020E80D9603120362 +:10EF7000002944100064FE0C3C17F52B40000416D9 +:10EF8000120300682203002E222300089A824E24D6 +:10EF90000003FE922213002F220300099A084E0458 +:10EFA0000003FE02041300208802E220E803140399 +:10EFB00000203C7C00DD840010030048CF2F0403B8 +:10EFC000000FC02C5A00010384034412CA303820B9 +:10EFD0008000C2248801F20BF30D2010000842F1DA +:10EFE0000C24FE54E02FE91AF10920000004FE4A27 +:10EFF000FE02E001E913020300285CF00029E905A4 +:10F00000840110030048D50A00030057C00784217B +:10F010008E011013004810030057223300085011CE +:10F02000FF9B96495CF0836FE90444000037D503E9 +:10F0300044000064842FCF02FA2E002300484E23A0 +:10F0400000970423000F4E2200930423000C5A283B +:10F0500002044800008D042300168E42E6424EF260 +:10F06000008722230006E0224EF2008252F084370D +:10F07000E04FE87D02130028E201E9790423001142 +:10F0800022030067CA4A8A034E040003FE025CF0B2 +:10F090000028E9430213002540000417E60AE93D71 +:10F0A0000213002F50F0FFB95CF788DFE836000349 +:10F0B0000055C8590003009E5A0801568542F002C7 +:10F0C000F10310A3005449FFFC7B2213002E5000D3 +:10F0D000FFA196015CF0037BE90410A300CBD543AC +:10F0E00022030067E001E8055EF0005FE907D50A4A +:10F0F000E020E8085EF003DAE9058402100300CBA3 +:10F10000D5328401100300CB5013005C500300D2B1 +:10F11000844449001E23D52702130025E624E90470 +:10F120009E11E602E8053C03F458E201E8200003E2 +:10F130000055C8190013009E5A180116001300F359 +:10F14000E622E80410030054D50E84221013005464 +:10F15000100300CBF103F00249FFFC3244000032FF +:10F1600012030066F002F10349FFFC4D0003004862 +:10F170002E47E97BC0070413000F4E130088480098 +:10F1800001610403000FC0F804030011C8F5040373 +:10F19000000C5A0002F2040300165A0005058E0204 +:10F1A000E602E8EA2213002F220300099A084E041F +:10F1B0000003FE022E37C56B44200032FE9C023352 +:10F1C000002844F003E8FE9C40213C57E240221313 +:10F1D000002E22530008E8D05CF00029E9CDB55F8D +:10F1E0000023007DF3064231287304AF800138F517 +:10F1F0000D112233003F85424031A876E06FE80AC6 +:10F20000F305E043E904F308E062E8B65CF0012DA1 +:10F21000E9B344F000C8F01140479096E080E8ACB4 +:10F220009A0D4E040003FE02E415E91D000300558B +:10F23000C81A0003009E5A080117840210030054E4 +:10F24000F103F00249FFFBBC2223002F50117FB9CC +:10F2500096495CF088DFE8072203000988029001E4 +:10F260001203002FF002F10349FFFBCDF10FF0056F +:10F2700088018420F20FF3089A82E2624EF3FF7D48 +:10F280001810000110100023D5F6040300165A00D0 +:10F290000304480001180223002502030034E2029F +:10F2A000E97204030010E602E80B020300268C0159 +:10F2B00012030026000300748C0110030074000385 +:10F2C00000485A08010C020300268C011203002694 +:10F2D000000300758C01100300755EF48029E807B7 +:10F2E000F004420480245CF007D1E90B02030026FD +:10F2F0008C0112030026000300768C0110030076B7 +:10F30000020300285CF00047E90CCF0B0203002643 +:10F310008C0112030026000300788C011003007892 +:10F32000040300205CF00065E90CCF0B020300260B +:10F330008C0112030026000300798C011003007970 +:10F340003C03F45E5CF00032E8082E17FFF4C105C0 +:10F35000CF04842514130016041300118E21E62215 +:10F360004EF200B14E7300AFC803E642E80A3C1308 +:10F37000F45AE2014EF200A72E07FFF44E0200A35A +:10F380008405D5350403001B400008175CF00038E5 +:10F39000E817F304FEC45CF18ABFE8124090240130 +:10F3A0008D2AE735E80D020300285CF00033E808F9 +:10F3B00002030026003300768A03120300260403AA +:10F3C000001C40000816E40BE90DF21550F17FF522 +:10F3D000E00FE80802030026002300748A021203EB +:10F3E000002602030026E610E90584021403001635 +:10F3F000D5695A18010722030006E41EE9F7D5086B +:10F400005A18020722F300065EF7841BE8EF000398 +:10F410000055C8120013009E5A18010F84221013C1 +:10F420000054100300CBF103F00249FFFAC9440075 +:10F43000003212030066F002F10349FFFAE4D542FC +:10F440000403000C5A00023F040300168E02E60477 +:10F45000E83900030055C8120013009E5A18010F26 +:10F46000842210130054100300CBF103F00249FF73 +:10F47000FAA7440000321203006684011403001648 +:10F48000100300550203002F50F07FB95CF787F29C +:10F49000E8192213002E5000FFA196015CF0037BB7 +:10F4A000E80E22030067E001E8055EF0005FE9076F +:10F4B000D509E020E8075EF003DAE90484021003CE +:10F4C00000CB0403000FC01EF1094402CB14381016 +:10F4D0000400C109F1098801F10D20000024E001B8 +:10F4E0004EF201EAF1094402CACC38100400C154BA +:10F4F000F109880120F00024F00DE00F4EF201DC4C +:10F50000D54BF00E5A00FF49F1094402CB143800E4 +:10F510000400C00BF00DC80904040005F1138801B4 +:10F52000A741B41F8E01D811F1094402CACC38009A +:10F530000400C032B41FF50D8E01D82E040400055E +:10F54000F10C38000600C028840414030016F00DE6 +:10F550004E0201B78402001F80281403000F10130D +:10F56000007D5A080104480001AFB41F8E01F10A62 +:10F57000B45F42008873F101380081111203003F2B +:10F58000020300081203002E020300091203002FD9 +:10F59000840012030028040300165A080111B4065F +:10F5A0008E01E602E80C0013008484003C0BF45149 +:10F5B0005A180106100300843C0BF453A4361203BE +:10F5C0000030A4371203003144000032480000BC70 +:10F5D0000003001896164E0200DE045300165A5817 +:10F5E000010584003C0BF452009300658400B43F95 +:10F5F000003300641003004E800942018473F1015E +:10F6000022430029381081118403FE0C9461E0200C +:10F610008401E80584021003004E840002230028C0 +:10F620005CF10047E9083C1C00DDC90584031003B8 +:10F63000004E8001027300250413001C5CF10038A9 +:10F6400040109C36E90750F0FFEC5CF78410E80DA1 +:10F65000D5045CF1002EE91C5CF08438E91002F35B +:10F6600000745CF78046E80B3CA3F4538F415CF5D3 +:10F670000031E9042EF7FFF4E80284005CF1004950 +:10F68000E90750F0FFF65CF78424E902840002F3F6 +:10F6900000685CF78032E8095EF20096E8069F0D8C +:10F6A0005CF2042FE90284003C43F4535CF20065F1 +:10F6B000E90F02F300745CF78046E80A5CF100335E +:10F6C000E90750F0FFFC5CF78430E90284005A58E7 +:10F6D000050384008E825CF20030E82C5EF0802806 +:10F6E000E80722F3002E5EF78028E90AD5235EF0B2 +:10F6F0008410E92022F3002E5EF78410E91B4442B7 +:10F70000CA8438420C00C4094442CA848883204217 +:10F710000024E089E90284004442CA3C38420C00DB +:10F72000C4094442CA84886420F18024E12FE9029C +:10F7300084005CF10051E90284003C33F45DE2672F +:10F74000E80684051003004E48FFFA5B5CF1003DBB +:10F750000433001BE90B40F19DF75CF78038E906A4 +:10F760008E2A5CF084254EF2FA4C5A58010448FF68 +:10F77000FA485A00010448FFFA440413002614030F +:10F7800000165A10010448FFFA3C1003005648FFC7 +:10F79000FA38A43612030030A4371203003148FFB0 +:10F7A000FA30441000FCF20242200473B0F184816C +:10F7B000B168F0074C01003DF007B4008E01E6038C +:10F7C000E832F007020000345CF000C8E90396005C +:10F7D000D503440000C7F107041080165A10020434 +:10F7E0005A180507F60702630025E206E9035A18CE +:10F7F000041BF007041400050000001C940288019B +:10F80000A642A783E2C1E90FF0070400000F5A08DF +:10F81000010538009408D5055A08020438408C08C0 +:10F820008C21D5F1F007500000FCF087D5C384008F +:10F830004412CD184422CA848068B128F50149FFDA +:10F84000F798F0124412CC844422CA3C8068B1314B +:10F85000F50149FFF78E3C03F45E3C13F45BE201D3 +:10F86000E8048C013C0BF45E3C03F453C8063C13E3 +:10F87000F45FC1033C0BF45E3C0BF45FFCDDB41F92 +:10F880004492CC848E01F086B01FF0884402CACC2A +:10F89000F0838401F08548FFF93A0003001100135A +:10F8A0000023E0204EF3F961F2088461383100084A +:10F8B0008C01D5F884041403001648FFFE6E840101 +:10F8C00048FFFE4B840048FFFE54442000FC4200E9 +:10F8D00088738421141000261010009E84201410B8 +:10F8E0000023DD9EFC4AF0852E07C53A8141F08257 +:10F8F0002E07C53BF288F08B3C03E2A63C13E2A541 +:10F90000F08D3C03F4505CF00190E8048C013C0B5A +:10F91000F4503C03F44F5CF00190E8048C013C0B84 +:10F92000F44F3C03F44E5CF00190E8048C013C0B76 +:10F93000F44E3C03F44D5CF00190E8048C013C0B68 +:10F94000F44D3C03F44C5CF00190E8048C013C0B5A +:10F95000F44C3C03F44B5CF00190E8048C013C0B4C +:10F96000F44B4000840AF08EF00DF6059001F09102 +:10F970008400F0812E07C541F101E2204EF204CD52 +:10F98000B4064E0204C35A080504480004BF5A08CE +:10F9900004044800042B0003001C04150004F08933 +:10F9A00094018801A641A600F192F093040300237C +:10F9B000C809F0090415000594028801A602C00FC9 +:10F9C000D5035A000111F00B4412CB5C8E01F08379 +:10F9D000F00B8E02F08C841FF087D50B8421F18709 +:10F9E000F18CD504F087F08C8400F0834412CBF0C6 +:10F9F000F0099402F090F210040500058802F20B61 +:10FA0000A6C28E41A743CB04DA048103D541DA3F75 +:10FA1000A680A6C1F402F003FF04E262E938B4AAAA +:10FA20009814380281005A00FF1C04550001385216 +:10FA30008101980AA6015A00FF14F709DF1198887E +:10FA40005000003494010031005B880100710037E0 +:10FA5000F38A00910049A503CF05F786D5058C41AF +:10FA6000D5DD9E39F086F0028E02E209E805F0024B +:10FA700050807FFFD5035084800180078029F203E6 +:10FA8000F30884A149FFF6F7F084D50A85008401C4 +:10FA9000148F8006F084812880E8148F800AF00299 +:10FAA000F1039401F20842200473F10CF3088480FE +:10FAB00042300473F48CF006E100E90F38110111B3 +:10FAC0004E170005F50C88A1F58C381181114E17E1 +:10FAD000000388818C01D5F1F006842740040001E1 +:10FAE000FE0342400473F48F4E4600048401F08FFD +:10FAF000F005F10149FFF3BE0013001804030023D1 +:10FB000096464E1200CB3C13F45712130056C023F6 +:10FB100084011203004E84031403002684001003A2 +:10FB2000009EC705F0028E014C9040058C2A1213EE +:10FB30000056000F8028F103F202100300A6F00A1D +:10FB400042008873F1083800811112030054020F3B +:10FB50008008D50C441001901213004E8421141318 +:10FB600000261013009E120300543C23F4543C332F +:10FB7000F4502213000912030052E24384001413CC +:10FB8000002C12030050100300A2100300B4100355 +:10FB900000B5100300B6100300B7E902840110039A +:10FBA00000AA3C03F44FE2408401E8028400100301 +:10FBB00000AB8401100300C43C03F463C82F2E2063 +:10FBC00004375A28012C3C0C00DD5A0802135EF061 +:10FBD0008096E82422F300085EF78096E81F84668A +:10FBE000143300262E37E8E4C31914230023D51458 +:10FBF0005A0801155EF08096E81122F300085EF7BE +:10FC000083A3E90C8446142300262E27E8E4C206C9 +:10FC1000140300238403140300253C03F461C8315A +:10FC20002E0004375A08012E3C0C00DD5A0802143D +:10FC30005EF088CBE92622F300085EF78096E82183 +:10FC40008426141300262E17E8E4C11B1403002396 +:10FC50008404D5155A0801165EF088CBE91222F308 +:10FC600000085EF783A3E90D8406140300262E071F +:10FC7000E8E4C0078402140300238405140300256C +:10FC8000804AF109A01538000600F110100300C8E1 +:10FC9000A0158801A601D556C023C705F0028E0124 +:10FCA0004C9040073C03F4578C0A12030056F103B2 +:10FCB000F202000300A642008873F10838008111A7 +:10FCC00022130054E020E803120300540203005200 +:10FCD000F104E201E805020F80081203005202035A +:10FCE000004E5CF00190E80B8C010413002C120311 +:10FCF000004E2203000988011403002C3C03F45435 +:10FD00003C13F450E201E9048421101300AA3C13CF +:10FD1000F44FE201E9048401100300AB804AF109C9 +:10FD2000A01538100600000300C8880190011003D8 +:10FD300000C8F110A0158801A641000300C9880180 +:10FD400090013C9C00DD100300C95074FFFFE6E207 +:10FD5000E913440001901203004E041300268401AD +:10FD60001003009E841DFE0E5A080107140300268E +:10FD70008400140300238400E6E210030048E83402 +:10FD800004030023C0315A08010884205A98010E48 +:10FD9000841F8422D50A5A0802075A980105841F35 +:10FDA0008423D503840180204422CA3038210400F2 +:10FDB000C21B4432CA308823F21220308008FE84ED +:10FDC000FE1CE002E911F207F01320108004FE147B +:10FDD000FE54E020E909020300525CF00029E90426 +:10FDE00084011003004800030048C867040300238F +:10FDF000C0640403000C5A0002610223004EE64B6B +:10FE0000E95C040300265A08030704130025E622D0 +:10FE1000E827D5035A080225A4778E305CF0894C78 +:10FE2000E81F021300525CF0804CE81A00030055F2 +:10FE30005A0801400003009EC83C001300F3E6226C +:10FE4000E936842210130054100300CBF101F005B1 +:10FE500049FFF5B64400003212030066D52A8E022F +:10FE6000E602E82BA4378E105CF0094CE8263C0330 +:10FE7000F459E202E922040300255A00020A5A005A +:10FE800004085A9002085A0003195A0005175A9894 +:10FE90000115020300525CF0004CE80F000300550E +:10FEA0005A0801080003009EC8048402100300548D +:10FEB000F005F10149FFFD0B00030048C86304137E +:10FEC0000023C1600403000C5A00025D04030026F5 +:10FED0005A0006058E02E602E8555A18010500038D +:10FEE00000AAD5055A18024F000300ABC84B2213D5 +:10FEF000002E220300089A084E040003FE022E275B +:10FF0000C56A44100032FE540223005244F003E854 +:10FF1000FE544010BC37E220E8355CF00029E9329D +:10FF2000001300A6F303F402804142219073F3080A +:10FF300038F1891122230054846240210C56E04F8D +:10FF4000E809F206E022E903E101E81C5CF0012D7A +:10FF5000E919000300555A0801120003009EC80E5B +:10FF6000842210130054100300CBF101F00549FF67 +:10FF7000F5274400009612030066F005F10149FFE1 +:10FF8000FCA604130023040300264E1200E35A00CB +:10FF90000304480001020223004E02030056E2025D +:10FFA0004EF300AD04230024CA0B000300A28C0111 +:10FFB000100300A2000300B58C01100300B5F30C80 +:10FFC000840AFEC48003F30F40000C165EF001C3E8 +:10FFD000E808F304444057E442F00C24E28FE80BB5 +:10FFE000003300A28C61103300A2003300B78C6193 +:10FFF000103300B7003300485A380114004300A200 +:020000021000EC +:10000000E6428C81104300A2004300B68C8110436D +:1000100000B6E909021300508C2112130050D52DAF +:10002000E642E82B5A1801155A98010722F30008F6 +:10003000F10EE02FD5075A98021F22130008F20E86 +:10004000E022E90F22130009E42BE815D50A5A181B +:100050000213F10D2223000950F0FFF5E04FE90BE8 +:10006000021300508C2112130050001300B48C2195 +:10007000101300B45A3001D05EF00029E806F104F4 +:10008000FE0C5CF007D1E906020300508C0112035C +:100090000050020300525CF0004CE908E6E2E8067A +:1000A000020300508C0112030050040300205CF096 +:1000B0000065E908E6E2E80F020300508C01120334 +:1000C00000505A980209040300255A0002105A08E9 +:1000D0000464D5075A980161040300255A080505F0 +:1000E0003C03F460D5055A0803583C03F4623C1302 +:1000F000F455E2208406E82AD54F0403002C400082 +:1001000008165A180208F10D50F0FFF5E00FE81D2F +:10011000D5155A18011B5A98010722F30008F10E51 +:10012000E02FD5075A98021222130008F20EE0229F +:10013000E803E41FD502E40BE908020300500013B2 +:1001400000B48A0112030050840214030026D5244F +:100150000413000C5A1002219E42E622E9048E0587 +:10016000E602E81A000300555A0801120003009E37 +:10017000C80E842210130054100300CBF101F005C7 +:1001800049FFF41E44000096120300668401140324 +:1001900000261003009E040300265A0801230403CE +:1001A00000165A08011FB4068E01E602E81AF01183 +:1001B00022F30009001300C4E00F8400E90A3C0B9D +:1001C000F4505A18010F100300C43C0BF44ED5092B +:1001D0003C0BF44F5A180106100300C43C0BF44CBE +:1001E00044000032480000830003001896164E02B7 +:1001F000008D042300265A28010EF01122F3000975 +:10020000E00F8400E9043C0BF44DD5063C0BF44BA5 +:10021000D5035A2006078400100300AE8421D505BB +:100220008401100300AE842000330064F402000354 +:10023000006542019073F30838F18111220300290F +:100240008463940140000C16E00FE805840210035B +:1002500000AE8420024300520233004E0403002CFF +:100260005CF2004C40000C16E90F3C4C00DD8E8126 +:10027000E682E80A50F07FD85CF7891CE9088423FD +:10028000101300AE84205EF07FFCE90CF40D8C832B +:10029000E080E908004300A2005300B58A851043BE +:1002A00000A23C43F45CE283E903E662E8058425AE +:1002B000101300AE8420043300205CF18065E9193E +:1002C0003C3C00DD8E61E662E814003300A600438A +:1002D00000C8E264E905004300C9E283E80A50F07F +:1002E0007FD85CF7891CE9058406100300AED50DA4 +:1002F0005A20010C5A18010A040300161413002690 +:100300005A08010410130056F001506300FC8C01E0 +:10031000F08148FFFB313C13F450C9063C03F46301 +:10032000C0033C1BF4623C03F4623C23F455E240FE +:10033000E9048C013C0BF4623C1BF4633C13F44F66 +:10034000C9063C03F461C0033C1BF4603C03F46049 +:10035000E240E9048C013C0BF4603C1BF461FCCAF4 +:10036000442000FC42008873041000265A1806241A +:100370003C1C00DD5A1801100210000950F0FF6A01 +:100380005CF78835E91822100008440003A24000F9 +:100390000407DD9E5A1802100210000950F0FF6A8F +:1003A0005CF78835E908220000085EF000965407E3 +:1003B00080FFDD9E8400DD9E442000FC42008873A7 +:1003C0003C33F471222000088020E062E90822F02A +:1003D00000093C43F4708402E08FE80C52F184374A +:1003E000E04FE90E224080093C03F470E004E91478 +:1003F000840314008025840114008023DD9EE062C4 +:10040000E9193C03F4702220800952F0096BE04F97 +:100410008404E910D508E062E8F552F0096BE08F3A +:10042000E9098405140080258402140080238401D6 +:10043000DD9E8400DD9E442000FC42008873041091 +:100440000023C10A5A18010B222000095EF17FFC2B +:10045000E90EE45FE9128422D5105A1802113C23F8 +:10046000E2A6223000099D13E083E8038420D5052D +:100470008E5FE062E902842114100024DD9EFC41BD +:1004800084C0F08181215070008C814685022E0746 +:10049000C541E2C0E85C0013FF8C0403FFDD964613 +:1004A000C129C028F001802649FFFF88C818F00143 +:1004B000802649FFF29A0403FFE4041480059402A5 +:1004C0008801A642A603C9065A0023098401B6077B +:1004D000D5065A082304B707D502B7472FC7E8E463 +:1004E0004FC3002EF001802649FFF27F15C3800024 +:1004F000D5268E01E603E827F001802649FFFF5E3E +:100500005A00011AF001802649FFFF2C8380C8138E +:10051000F001802649FFF2690423FFE4040480050A +:1005200094928840A612C007A6135CF00023E8034B +:1005300015C380002E07E8E4C802B607F001802644 +:1005400049FFFF7B8CC1507380FCD5A2FCC1FC200D +:10055000442000FC420088730470000F80C0CF0567 +:10056000840314030010D52E5A78010E22000008CF +:100570005EF07FF3E912E40BE91C5EF000298402CF +:10058000E91CD51A5A78021C3C03E2A52213000884 +:100590005020000CE041E8038400D50F50F07FF5B7 +:1005A000E02FE9038401D50950F07FD7E02FE9045B +:1005B00014730010D5048403140300103C0C00DDF8 +:1005C000C0038400D50E5A78011050030010441067 +:1005D0000064442000C8846349FFF1C24003801BCB +:1005E00014030011D50B5A78020A5003001044106E +:1005F0000064442000C88464D5F0FCA0FC41F08174 +:1006000083812E07C53AF10185205060803C80E946 +:10061000810950A07FFF2E07C541E320E845001364 +:100620007FDC04037FF19646C113C01204037FF8F8 +:10063000B90594028801A640A741C90584014C551B +:100640004006D5234C5540228402B606D5218E01A2 +:10065000E603E826B4065A08010D04037FF8B9053D +:1006600094028801A640C911A7414C554012D50DEE +:100670005A08020F04037FF8B90594028801A640C6 +:10068000C104A7414C5500058CE1B70697F82E0729 +:10069000E8E4C802B606F001802949FFFF5A8D211F +:1006A000506300FCD5B98007FCC13A6FA6BCEFF8D7 +:1006B00080C080E2501F8006B400FA40846349FF86 +:1006C0008895020F8003A470B6073C0DFAA54492EA +:1006D0008F70FA400200001184648A010014800FB8 +:1006E00092014000043710138010B406501F80069A +:1006F00049FF887C020F8003A470A8393C0DFAA53D +:100700003C3DFA8F8481020000118A010014800FA1 +:1007100092014000043710138011B406A072A0B6F5 +:100720000031800C49FF889DEC083A6FA684DD9E5D +:100730003A6FA8BCEFD880E181445A480404A0066F +:10074000D502A00500110010509F801C84C04430C9 +:1007500000320051000F8083B63FF6818020F68280 +:10076000F683149F8004844549FFBE23020F800E48 +:1007700002148003AC3802048001AC7AAC39220444 +:100780008002AC3B5AA0040B3C13E6303E67E948BC +:10079000E001E80484013E07E948EC283A6FA884A8 +:1007A000DD9E3A6FAABCEF548123846081408101B1 +:1007B0003E37E94849FFFF7B8400003480028020F7 +:1007C000B118B16144607FFF9680E243E80AB08FC0 +:1007D0003812010938110109386281098C01D5F5F7 +:1007E0000044800344000080F0830405000684C0B8 +:1007F00084E194598E818820B67FF382442232E8C6 +:10080000972080A7F781F684F685F686F787F68825 +:10081000F689F68A49FF884B00348002440FFFE2D4 +:10082000F088FA0E00448003B67FF089501F803AAA +:10083000040500060425001180A7F681F682F683E0 +:10084000F684F685F786F687F68A126F801D49FFD3 +:10085000882E004480030034800244000080F0832E +:100860008E81440232E88040B67F501F803A972044 +:1008700080A7F681F682F684F685F686F687F688F6 +:10088000F689F68A127F801D49FF88110044800393 +:1008900000348002FA00F0888E81440232E8804001 +:1008A000B67F501F803A972080A7F681F682F683A4 +:1008B000F684F685F786F687F689F68A126F801D2C +:1008C00049FF87F500448003840800348002F087E4 +:1008D000040500118E818040B67FF382441232E815 +:1008E000972080A7F781F683F684F685F686F6884A +:1008F000F689F68A49FF87DB0044800300348002D2 +:10090000B04F84058E818041B67FF0889720040522 +:10091000001180A7F781F682F683F684F685F686C5 +:10092000F687F689F78A49FF87C2004480030034BE +:10093000800244000080B058F0838E81841B804187 +:10094000B67FF08997200405001180A7F781F68211 +:10095000F684F685F686F687F688F78A49FF87A734 +:10096000003480028404F087B0218040004480037A +:10097000F3820415000680A7B6DFF781F683F684BC +:10098000F685F686F688F689F68A49FF8790003460 +:1009900080028411F088440FFC1800448003B67F65 +:1009A000F089501F803A04050006442232E880A7EF +:1009B000F681F682F683F684F685F686F687F68A61 +:1009C000126F801D49FF87733C0DFAA50044800219 +:1009D00080460250000E8E81976B802683C680066B +:1009E0008066E0E4E81CB18F38F31D015CF78012EB +:1009F000E9068C618C0196D996018441B19838F34F +:100A00001D015EF78012E908506F00018C2141E35F +:100A10000013964984418CE197F8D5E43E200417F1 +:100A200084403E200419222F8042E450E909022F1D +:100A3000801EE64CE9058C0196018441D502844074 +:100A4000B1E138739111E4F0E90AB18F3873110103 +:100A5000E6ECE9058C418C0196919601027F80308D +:100A6000E6EC84E0E9048C21964984E1B1983843AE +:100A70001101E68CE9088C219649C20B8CE197F9AB +:100A8000CB04D507C205C30484413E200419C70620 +:100A90004FE2000584413E200419E630E803E610E9 +:100AA000E90584013E000418D50484003E000418C2 +:100AB000800A8028804984608484F58D49FFFE3A4D +:100AC00022F40002F50D5EF78065E90484013E0022 +:100AD00004192E07E9175A080107221400034402DB +:100AE0005198AC405EF28065E90484013E07E90C50 +:100AF0002E07E90C5A080107E4BEE80484003E070B +:100B0000E90C22F400035EF780DCE80484013E0770 +:100B1000E94844007FA6120F801D02040000C83976 +:100B200002040001C0362E07E94404350006C81E41 +:100B30009481884322FF801DA450964BE02FE80645 +:100B4000A4503C0BF4E8121F801D8C015A0A88F255 +:100B50003C03F4E894019858A40896035EF07FC91A +:100B6000E81D84013E07E944D5193C13F4E8944993 +:100B70008823A448964B5EF0FFC9E80B8C019600D1 +:100B8000E60B3E07E944E90A84013E07E933D5064E +:100B900084003E07E9443E07E933ECAC3A6FAA848F +:100BA000DD9E3A6FA8BC80C0440000FCEFC8421133 +:100BB0000073CB0E225080044400003C224080058C +:100BC000405280B64400004340420096D50AA00F30 +:100BD0003C1C01ED94018801A741A700976B972366 +:100BE00080065013006284401A2000014C00FFFE72 +:100BF0009E6B54A280FF549200FF4E1500085005D2 +:100C00007FFD960084208467D507FE4A96485230BF +:100C1000800796D884009EA34E25000A844750740E +:100C2000FFFD102F803797F88440D508FE929690EC +:100C300052710007107F803784E08CA3E4B2E9048E +:100C40005235001596D88C835EF20024E905529443 +:100C50008027109F8037FAA24203947384E74211E1 +:100C60001C73948944100080F1838420F184F18501 +:100C7000F186F188F1893C1C0278B6BFF78284A125 +:100C800084E29401F787004F8037F581F58A880167 +:100C90008846501F803749FF860AEC383A6FA8848F +:100CA000DD9E2E57E90C3A6F9C3C97205A50010666 +:100CB0002E6004175A680108E642E9035A28230403 +:100CC0004440007D383185118803E004E9125A5010 +:100CD00001062E0004175A080110E642E80DFA0238 +:100CE000421100734402D48438000511E004E80482 +:100CF00044008000D50284003A6F9C04DD9E3C1CB9 +:100D000000DE2E07E94DA68EC8162E07C5D45A0858 +:100D100001139411AE0AA6098E01FE14844240000C +:100D200008168E01940196033C0BF4C9FE033C0B9C +:100D3000F4C8D50FA609AE8A8E01FE148442400085 +:100D400008168E0196033C0BF4C9FE033C0BF4C855 +:100D50002E0004195A08010D3C03F4C994033C0BFE +:100D6000F4C93C03F4C894033C0BF4C8D52CC82B3D +:100D70002E07E9115A080128A60A9401AE0A2E0787 +:100D8000E9675A08010E3C23F4C98406FE843C2B13 +:100D9000F4C93C23F4C8FE143C0BF4C8D5142E0748 +:100DA000E91B5A08010D3C03F4C994013C0BF4C93A +:100DB0003C03F4C894013C0BF4C8D5052E07E96840 +:100DC0005A0003F3A6093E07E9048C013E07E90532 +:100DD000DD9E3A6FAABC51FFFAAC2E37C5472E47AD +:100DE000C54884C08521F18D8382945944200080B8 +:100DF0008E818820B67FF382F2839720442232E8E6 +:100E000080A9149F8001F684F685F686149F8007DA +:100E1000F688F689F68A814049FF85492E37C5470D +:100E20002E47C548440000804021A40C448232E88B +:100E3000F083B1D084038E82F08797204001200098 +:100E400080A9B67F149F8001F382F684F685F6862A +:100E5000F688F689F68A8028884749FF8528126F28 +:100E6000801F808880A62E37C54796B3E0438CC18B +:100E700097B1E81A409104083804900138038909B1 +:100E80002E07C5489E414201842498428A03880265 +:100E90003802010138038509F00D892012548000C1 +:100EA000385E0909D5E1840184C0120F801FB0109B +:100EB000B67FF681F682F683F684F685F686F687A7 +:100EC000F688F689F68A501F803E80402E47C54836 +:100ED00084A149FF84EC2E37C5473C0C00DE84E139 +:100EE000B67FF681F682F683F684F685F786F68776 +:100EF000A602501F803E8C02F088B010F689F68A58 +:100F0000804080A72E47C548126F801F49FF84CFBD +:100F10003C07F4C82E37C547F0883C07F4C9449015 +:100F20000080B67FF681F682149F8003F684F685F2 +:100F3000F786F687F089F68A800A501F803E80A7E0 +:100F40002E47C548442232E8126F801F49FF84AF04 +:100F50002E37C547440232E8B67FF681F682149FE9 +:100F60008003F684F685F686F787F688F689F68A92 +:100F7000501F803E804080A72E47C548127F801FAB +:100F800049FF84952E37C547B0508528B67FF78135 +:100F9000F382F683F684F685F686149F8007F6883A +:100FA000F689F68A804180A72E47C548440232E878 +:100FB00049FF847D2E37C547F781B67FF682F683D9 +:100FC000F684F685F686F687F688F689F78AB010F5 +:100FD000803C805C80A72E47C54849FF84682E3737 +:100FE000C547B050B67FF781F382F683F684F68565 +:100FF000F686149F8007F688F689F68A800A804173 +:1010000080A72E47C54849FF8452F10D2E37C547AA +:10101000F781F682F683F684F685F686F687F688FB +:10102000F689F78AB67FB01080A72E47C548804161 +:1010300049FF843D51FF85543A6FAA84DD9E3A6F83 +:10104000A4BCEF9CB1CF804780C0A006F18D49FFC2 +:10105000FEC284803C2C00DEF50D81242E37C5476E +:10106000E283E81238039111A654E020E808A4684E +:10107000964B40108036964BAC68D5031292800098 +:101080008C818CA2D5EC842084A1F182F183F1843F +:10109000F185F186F188F189F18AB67FF581F587CE +:1010A000A036F10DA0B52E47C54849FF8400EC6479 +:1010B0003A6FA484DD9E3BFFFCBCEFF4B61FF181C8 +:1010C00049FFFE1FB41FF101EC0C3BFFFC8448FFFD +:1010D000FFB8FC005A0806048401D5045A08070624 +:1010E00084003E07E918D51C5A080D0784003E0706 +:1010F000E9188421D5075A080E0B84013E07E91828 +:1011000084203E17E9563E07E946D50A5A081004DE +:101110008401D5045A08110584003E07E917FC80B4 +:101120004433F04A444000553C2DFAB3A690CA031C +:10113000AF18D5FB3C2C00E910010053C904440F43 +:10114000FFA0D503440FFFA1100100512E07E9684D +:101150005A080305440FFFB1D503440FFFB0100137 +:101160000052443000554423F04A3C0C00E9001082 +:1011700000515A10BB04AED0D5F984201010005194 +:1011800010100052DD9E4413F04A442000553C0CE0 +:1011900000E9000000515A08A004AE88D5F9DD9E90 +:1011A0004413F04A442000553C0C00E90000005173 +:1011B0005A08A004AE88D5F9FC005A08BB0449FFC0 +:1011C0007F422E0004295A08A00544024000D50899 +:1011D0005A08A10544021B90D50344020C60441236 +:1011E000451049FF82B43C0C00E9441FFFA01010D9 +:1011F0000051FC803C1C00E910008060DD9E3C0C2E +:1012000000E900000060DD9E3C1C00E910008061E8 +:101210003C1DFA341000803EDD9EFC0080C049FF7A +:10122000FF5A84015A68030549FFA5F6800650134A +:101230007FF3E622E9035A6802163C0DFA97A641AD +:101240005A10030D842049FF845D49FF7FD75A0857 +:1012500002063C0DFA978423AE4184013E000459F6 +:101260008402FC804000040E9606DD9E5A000108B0 +:101270005A08030BB40158000004D504B441841B80 +:10128000FE16B601DD9E8402AE10DD9EFC409F017D +:10129000E68B4EF2007C800144F111A838479000A3 +:1012A00040F23C004A003C00E80C107EB0B6E2BEC2 +:1012B000CCDADE008407D56E4473F04A44900055C2 +:1012C00049FFE68080C05A00020510938000D5F9DE +:1012D000840149FFE68A49FFE6493C0E033249FF93 +:1012E000E64F3C0E033349FFE65D3E000CD149FF5B +:1012F000E6653E000CD049FFE65B3E000CD284213F +:101300004402D70049FFB9FD800649FFE66E4463F9 +:10131000F04A4470005549FFE655C003AFF0D5FCD4 +:1013200049FFE663D5183C2C00E9842EAE418426A3 +:10133000AE408420101100504423F010AE508421A0 +:1013400049FF83E08420840280418461808180A100 +:1013500049FF7FB48401D51E8401AE10D5118401EC +:10136000AE10840ED5178401AE10840149FFA55F2D +:101370008402D5108401AE10840049FFA558840D65 +:10138000D509FA00D507FA01D5058402AE18D5E3D0 +:101390008406FCC0FC005A000142C0055A000254F9 +:1013A00048000087C915FA043C0BF4774400003C60 +:1013B0003C0BF476840F3C0BF475FA38FA0E3C0BB8 +:1013C000F4743E07C97A3E17C97B8401D5245A18A4 +:1013D0000115840F3C0BF47784083C0BF4763C0B2E +:1013E000F475FA0E3C0BF474FA043E07C97B3E0711 +:1013F000C97A3E17C967D55C5A18025B84083C0B52 +:10140000F47784053C0BF4763C0BF475FA0E3C0B38 +:10141000F47484003E07C967D54BC10A5A18010706 +:101420003E17E9093E17E918D5435A1802053E1739 +:10143000E909D5065A18033D84003E07E9093E072D +:10144000E918D536C9083E17E8E43C1BF4713C1B8B +:10145000F470D5225A18010D440000643E17E8E4E8 +:101460003C0BF4713C0BF4703E100437D5155A1840 +:1014700002073E17E8E4440000AAD5075A18030DF6 +:101480003E17E8E4440000FA3C0BF4713C0BF470A6 +:1014900084013E0004372E0004375A08010A440034 +:1014A0000E103C13F47949FF826F3C0BE4D2FC80B0 +:1014B000FC00E605E84344F113C43807800040F01F +:1014C0003C00DD0F0620405A6A00B462964F40008F +:1014D000A008441FFCFFFE5EFE47B622B422840033 +:1014E0009228D50DB462964F4000A808441FF3FF20 +:1014F000FE5EFE47B622B4228401922A964F49FF2F +:10150000FF4BD51EB462964F4000B008441FCFFF7A +:10151000FE5EFE47B622B4228402922CD5F0B402BD +:1015200058004000B60284003E000433D509B422BE +:10153000440FBFFFFE0EB602D5038402AE18FC8036 +:10154000FC00FA043C0BF4774400003C44628F70CA +:101550003C0BF476840F3C0BF475FA38FA0E10133A +:101560000443100304423C0BF474842284011003EE +:10157000042F3E17E8E48400441000AA3E07E9095E +:101580003E07E9183C1BF4713C1BF4703E00043725 +:101590003C13F4794400016849FF81F612030236D6 +:1015A000FC80FC4080C18420AE40B40280E29211F5 +:1015B000960681245A080107B42644020000FE0F53 +:1015C000B606B40792119606C806B426440DFFFF6E +:1015D000FE0EB606B407920196065A080109B40633 +:1015E00058000002B606800649FFBCEBB407920122 +:1015F0009606C80CB426841DFE0EB60649FFE19976 +:101600003E000431800649FFBCDCB40796065A0848 +:101610000106B40658000001B606B4079606C805D0 +:10162000B426841EFE0EB606B407920296065A0829 +:101630000106B40658000004B606B40792029606E6 +:10164000C805B426841BFE0EB606B40792039606A0 +:101650005A080106B40658000008B606B4079203FB +:101660009606C805B4268417FE0EB606B407920483 +:1016700096065A080106B40658000010B606B407CC +:1016800092049606C806B426440FFFEFFE0EB60677 +:10169000B40792059606C806B426440FFFDFFE0E77 +:1016A000B606B407920596065A080106B406580015 +:1016B0000020B606B40792069606C808B426440F62 +:1016C000FFBFFE0EB60649FFFF3DB4079206960621 +:1016D0005A080106B40658000040B606000480000F +:1016E00092075A0801160004800096371004800003 +:1016F000B42784009228964F49FFFE4EB407B446A3 +:1017000054100300440FFCFFFE16FE0FB606000443 +:10171000800196065A08011600148001541080FEBC +:1017200010148001B427922A964F49FFFE35B40762 +:10173000B44654100C00440FF3FFFE16FE0FB6061D +:1017400000048001920196065A08011700048001E6 +:10175000540000FD10048001B4278402922C964F9F +:1017600049FFFE1AB407B44654103000440FCFFFAF +:10177000FE16FE0FB606B407920E96065A08010929 +:10178000B40658004000B60684003E000433B40797 +:10179000920E9606C806B426440FBFFFFE0EB6068C +:1017A000FCC05A000B135A000C1A5A080A21FC00FC +:1017B000B441440FFFBFFE16B601B401580000202B +:1017C000B60149FFFEBFFC80B40158000040B601DD +:1017D000B441440FFFDFFE16D508B40158000040A5 +:1017E000B601B40158000020B601DD9E8402AE109F +:1017F000DD9E0000FC42A7493C6C00E95A580411E8 +:101800002E07E9785A00010D00030050540000F043 +:101810005A001007440000553E07E970D51F000329 +:101820000050F4818123B65F80E1C0035A08FB1A9F +:101830002E000429C00784003E000429840049FFCB +:101840007C6BB41F4412B36A49FF7EB1440000555B +:101850003E07E97084003E07E95E84014800016F9D +:101860005A50010949FF7CCA5A080205840149FF00 +:10187000B9D2B41F4412B36A49FF7E6584003E07A3 +:10188000E9733C0C00E900600050008000518401C5 +:10189000100F800F84003C0FFAC5A67940A31009F1 +:1018A000979F5A1804212E17E9205A1801063C0F59 +:1018B000FAD449FFAF1D840149FFB99C84208007F9 +:1018C00049FF8120840149FFA1A04403F04A44104C +:1018D0000055AE4049FFA17FC0FE4402D40449FF39 +:1018E0007D74D527A6785A10010A4403F04A4410A3 +:1018F0000055AE403C0DFAB3D5103C0FFAD444036A +:10190000F04A44100055AE403C0DFAD4C8EF49FFF0 +:101910007C755A0002FBD5EAA640C1FFA6005A001A +:1019200002093C0DFAA8A6405A1802048420AE40D1 +:101930008F41E74B4EF200DE44F1184838A7A90169 +:1019400040F53C004A003C0016005A00A801A801DE +:101950005A0168017A01A801A801A8018A0144027C +:10196000B3404412B3E249FF7E31B41F4412B36A5C +:1019700049FF7DE980068028804749FFB2C1840085 +:10198000100F800F5A600F04480000B73C0C00E9AC +:1019900084CC000000505A00FB04480000B5480009 +:1019A00000AC8EC18401E6C63E07E973E87744F1D6 +:1019B00018BC3867980040F33C00DD0F062442AEA7 +:1019C000B84C8400100F800F84013E07E95E2E079B +:1019D000E9184E030094841F3C0E010F4800008F4D +:1019E0008400100F800F84013E07E95E2E07E9187E +:1019F0004E030087841F3C0E010F480000823E0703 +:101A0000E95E84C2480000808400100F800F8401CA +:101A10003E07E95E3C0C00E9001000525A18AA206B +:101A200000100053440FFFA0FE0F3E00042949FFA1 +:101A30007B0A840149FF7B703C0C00E900000052E6 +:101A40005A08AA0544004510D5034400479849FFA9 +:101A50007AF63C0C00E98420101000522E07E91899 +:101A6000C851841F3C0E010FD54D4400006949FF49 +:101A70007B43D5423C1C00E98400100F800F840199 +:101A80003E07E95E000080550010805440002008A9 +:101A900088013C0BF4D7FAC2D53684003E07E973BF +:101AA000D52880068029502F800F49FFFBE1D518EB +:101AB000FD034422B3AB503F800F49FFFBE9978001 +:101AC000D522800680288049503F800F49FFFCF2D4 +:101AD000D50780068029502F800F49FFFE64000F34 +:101AE000800F5A00020AF101B40984CBB601D50B6C +:101AF0008402100F800F84C1D50684C4D50484C528 +:101B0000D502FAC9000F800F84205A0001055A0837 +:101B10000207843B3C0C00E9101000502E07E973CB +:101B2000C80C4402B3404412B3E249FF7D4FB41FD6 +:101B30004412B36A49FF7D3B8006FCC25A08073C49 +:101B4000E625E86544F11A543817840040F0BC00DB +:101B50004A003C00061E3A505800A660440FFF8021 +:101B6000FE0FAE20968F40012008441FFCFFB443B7 +:101B7000D50BA621968F58000001AE21441FF3FF1C +:101B800040012808B443FE8EFE87B643DD9EA621A1 +:101B9000968F58000002AE21441FCFFF400130084D +:101BA000B443D5F2B40358004000D52FB423440FFA +:101BB000BFFFD52A5A080B1D5A100B0B5A100C11D7 +:101BC0005A180A26B423440FFFBFFE0ED50CB403E7 +:101BD00058000040B603B423440FFFDFD515B4030B +:101BE00058000040B603B40358000020D50E5A0830 +:101BF00005135A1001085A18030BB40358000004C7 +:101C0000D504B423841BFE0EB603DD9E44022D5082 +:101C1000843BAE40DD9E9200FC42814144122D5037 +:101C2000F081F282F383A608A78844122D51920412 +:101C3000A7C8979F97F85A0801249E31E602E90F3A +:101C40005A6003045A6805403C0C00E9000000603B +:101C50005A00A1062E0004505A0001364402B34037 +:101C60004412B3E249FF7CB24402B3634412B36A44 +:101C700049FF7C69FD03F20149FFB142D5245A00B6 +:101C80000B065410000D5A18051F2E27E9609E54AC +:101C9000E622E8043E200427D50484203E100427D1 +:101CA00044922D5084201014800080478026F30237 +:101CB000F40349FFFF45000480005A00FB0584013E +:101CC00010050000FCC244522DA0443DD2604422C5 +:101CD000E17444022DDC986B381104011A12800162 +:101CE000D8FBDD9E3C0E00ED84003E07E907DD9E3B +:101CF000FC003C3C02784402D79C8440FA82445267 +:101D0000CFC0041000168E22E622E910041000262F +:101D10008E22E622E90B001000DE5A180105381267 +:101D20008800C104B4205A18030D0060006600103A +:101D300000674213107394498823A448121000735B +:101D40008C41500000FC5A280ADEFC80C12C5A1835 +:101D500002074442CFC084A1385200084452CDE06B +:101D60004C11001DFC004442D01438420000928304 +:101D70009DA1C3045A1802039DA338328000444237 +:101D8000CDE0E266E8068C61383200088001D50DAE +:101D90008420381200088002D50884403822800848 +:101DA0008001DD9E8002DD9EFC80FC42FA2C420117 +:101DB0008473A041B4E0B63F4412CFFC0490000409 +:101DC00038108C0000A000182E67E922A005F183CE +:101DD0002E17E955F08151E300012E07E90940FF74 +:101DE0000407568780015A0001095A08020C444032 +:101DF000019A44500118D50A44400528445004244F +:101E0000D50544400334445002302E07E97BF0826C +:101E10005A880103CE043C03F4CAD50344000032BF +:101E200050F0FFFE5CF78003E8192FC7E9484FC365 +:101E3000001640FF0407E80E40F09801840942F7BD +:101E400080245EF7803CE8098AC1FE345000003CE3 +:101E5000D50544000032D502801C3C6DFA9AB4C608 +:101E600092C297865A680108E625E8058C1E45E06F +:101E70000186D50345E00118C212446000FC4412FB +:101E8000D79C42119873001080DE84C05A10020360 +:101E900084C552110005FE0C920288064462D79C4C +:101EA000441000FC81E642F1847303C7800B5CFEA2 +:101EB00015E1401E7837E90B50FE6A2041E7FBD65A +:101EC00040FF0406E8038A3ED50284204E83000CBE +:101ED0002E87E9485A880108505281F4504201F493 +:101EE000976997215CFE0C81E94444F000FC448230 +:101EF000D79C4281BC73008400DE21CF8008E702BA +:101F000044800064E819425E2073E2A9E80584A9D0 +:101F1000FE6C9221D50840448808FF0C405214B74B +:101F200092218825F40144500046405214B7E2A1A2 +:101F3000E81E8A25D51D424E2073E289E806848971 +:101F4000FE6440408409D50A85034254A024FF4C16 +:101F5000404290974010A0378881F5014410004618 +:101F600040128437E224E8039A61D5028420880174 +:101F7000B43F9449E227E9125CF50029E8113CF7E7 +:101F8000F5395EF78118E813F102E622E910B4BFD3 +:101F9000848A947BFF64E2A1E80AE755E907FA2402 +:101FA00040A505574000280DD50292015CF487D169 +:101FB000E813441000FC808642418473001200DE66 +:101FC0005A180209F103E628E8059403842A400020 +:101FD0000417E2E0E913441000FC4261847300132B +:101FE00000DE5A18010E9401E207E80ACA09440209 +:101FF000CDE0843A38100C08D5038401D502840260 +:10200000FCC22240000C5050000A501000288400EE +:102010008441383289118C419AE388035A2804FBA1 +:102020008CAAD9F7DD9E8060804084019A50E62218 +:10203000E90B9850922142F08424E26F4000BC1AD0 +:102040004020BC1BD5F4DD9EFC2084408082806251 +:1020500084C14053080CFF4EC505385009118C81CE +:1020600088658C415A2819F74031907784403C3F6D +:10207000FA9280C284E14053880CFF4EC506385066 +:1020800009118AA3426294738C415A2819F64003BD +:10209000101749FFFFCAFCA0FC5980C0810644000C +:1020A00000FC428280732204000522A40004F08612 +:1020B0004400003C812140150016F18AF106F487A6 +:1020C000444000439600401090968780F38980E555 +:1020D0009720805C52A07FE24400004352527FDF91 +:1020E00042510073B054840642110073F188FF6CB2 +:1020F00084204430003C800A42008C73F18C80259F +:10210000421000738001F28FF48EF38DF58B49FF3E +:10211000FF8C96015CF0007FF50BF10CF30DF40ED3 +:10212000F20FE8055200007F9601D502840004FFFB +:10213000800838078509881C8C2141C000135A1873 +:1021400003DC8C415A2803CA50AF8064800A846043 +:102150008026804749FFF52784004443F248B0D4E5 +:102160009844382181008C01AE885A0809FB84A765 +:10217000846584C0B011B6BFF582F0848083F68197 +:10218000F683800A802A844649FFB11384AE846AAC +:1021900080494243142442230C7384009844882AC3 +:1021A00002108008381100098C025A080AF98CC103 +:1021B0005A6805F0F00A842F8E01960140008006CF +:1021C000F1065EF088E6E9028C01F1074422CFE4D3 +:1021D000AE082214800C960938011D093C27F4CC66 +:1021E000E040E8033C1BF4CC4400007FFE0C4000C0 +:1021F000701612040072041400073C0C01EB380046 +:1022000005013C13F4CD54A000FF96008801001492 +:1022100000183C0BF4CD96464402CFFCC90538109B +:102220001C00E22AE80338A01C08F609FA0C461044 +:102230001F8D426380735010863F800949FFFF065F +:10224000B6063C0DFA92441739C0A832800949FFFE +:10225000FEFDA8313C0DFA92A8332204800CA8346C +:10226000800949FFFED0A83510A30018FCD9FC4016 +:10227000441000FC4201847302100072A187C9045B +:102280008421121000723C3C01EB96B0945138212D +:102290008901E64BE8433C2C01ED8841A651E6223A +:1022A000E9069FCAE63097F8E806D50284E08C225A +:1022B0009748D502FAA1A690E642E9079E525CF142 +:1022C00000229648E806D50284208C429710D50259 +:1022D000FA933DCC02788520FB02E281E91A42A004 +:1022E000A0248047E2A2E9124035080094D9887CF6 +:1022F00002F1800040F780115EF7800BE904A4D85A +:1023000096DB89238C419690D5EE8C219648D5E6B4 +:10231000441001F442148424D5083C1C01F13820F7 +:102320009A02441001F4FE540220007240108836D4 +:102330001210000B3C1C01F138109A021410003BE3 +:10234000FCC0FC40EE68B61F3C03F5368121E61563 +:10235000F281E903FA0ED503520000323C0BF4CAB5 +:102360002E07E97BE605E90484003C0BF4CA8400EF +:10237000843F3C0BF4CC3C0BF4CE3C0BF4CB3E172F +:10238000E9063C0BF4CD507480DF44A2D00884C031 +:102390004482CFC03C0C00ED00000009E2C0E862BE +:1023A0005003FF21B4009E41E623E8360003FF39C5 +:1023B0009606C80B5003FF79B4005A080128500351 +:1023C000FFB9B4005A0801232E07E907E605E9041E +:1023D00000050000C817B1028009B045B45FB0D253 +:1023E000888680A649FFFE5A80094412D1DCB45F7A +:1023F00096F049FFFF3E4412CFD884003800980879 +:10240000D502840110050000D5284402CFD88421CC +:1024100038101808D522C0035A0805204412CFCC22 +:102420008400AE381003FFFFAE3A3800980850130E +:10243000FF37844038041808AC884412CDE03820B7 +:1024400098084412CFD8380098088421101500004D +:102450004412D014380098088CC1507380FC8D4110 +:10246000D59A3C67F4CC5EF303E9E91250737C180B +:1024700090E350738032963B5EF305DDB61FE90BA7 +:1024800050637A2490C2506300C897B3D5064400C5 +:102490000032B61F446000C884003E07E90750744C +:1024A00080DE850044A2CFD83C0C00ED000000097E +:1024B000E3004EF200C85093FF22B4099E41E62388 +:1024C000E87138052000C8434402D00838002000D5 +:1024D000C83EB082B012F10138212000543400FF10 +:1024E00049FFFC65AE393CF7F4CC5EF783E9E9318E +:1024F00000038015E602E82D4402CFE43C3C01EEE7 +:10250000382021015003FF3EE046E80FB420944AF2 +:102510008823A70BC40AA70A5CF20023E806A709D0 +:10252000C404A648E631E911B40094028803A64326 +:10253000C109A6425A102307A641C104A6005A08A1 +:102540001109B41FE040E8058401D5028402AE39C8 +:102550002E0004315A00010F49FF76505A08020B31 +:10256000B0C28008A678A6B93831A00049FFFBF0B8 +:10257000AE38B4095A000315A6385A080208A67BDB +:10258000C90B8401AE3BAE3AD51C5A08011BA63BD1 +:102590005A0802058403AE3BD5145A08031384007D +:1025A000D5FB5A08040F4402D560380020005A08B1 +:1025B00040094402CFC08421381020088402AE387C +:1025C000A6785A18010C4422D01438012000E610D5 +:1025D000E80C8C0138012008D5085A18020744027B +:1025E000D01484403820200838052000C80D44024B +:1025F000D00838002000C8085A1802072E07E9073B +:102600008C013E07E9072E0004315A080106A6385E +:10261000E602E80CD50649FF75F15A0802FAD50D15 +:10262000B4095A0004048401AE3A4402CFC08421A4 +:10263000381020088402AE388D01507380FC48FFAA +:10264000FF35ED98FCC0FC203C6C00FD84E1A772D6 +:10265000A7B3C20284FFC9089E69FF4442510473B4 +:10266000B6A388A7D50B9E71FE8C802042111473EF +:10267000884742011473B62380A0B6A4FCA0FC4492 +:1026800084C0810583808141F282F38180E480A34C +:102690008126E2E5E9148005F110F202B0C4B1052B +:1026A000F58349FFFFD2F004F503380E01118CA128 +:1026B0008920F005380E011188C0D5ECF001804664 +:1026C0008AE0FFFB8405422380734E260003844189 +:1026D0008029800A49FFC4FE001400005A10FF053B +:1026E0008C218801920110040000B046B08749FF98 +:1026F000C55CF00638150111F00738250111840278 +:10270000400080164204887340000416FCC4FC4755 +:1027100080E13C1C00FDF2845060002000208032EB +:1027200000808002F287002080338400F28820201D +:102730008039F085F2892020803AA64BF28A800108 +:102740008E01F183F086200F800C44A2CDF0F08D35 +:102750003C0C00FDF10500000009E2204EF2010EE4 +:1027600004037FF84E0200F78E04E6024EF300F3F6 +:10277000A0345A080204480000EE04937FFF40048E +:102780008808F08BF10BA03D8801A6C0CB29A6429A +:10279000E622E9029EC9A703F0038E02E080E80367 +:1027A0008C81D502F4068440B65F3C1C00FEF00428 +:1027B00080A649FFFF66A07EF2073810A6028A2095 +:1027C000FE54042380083821260288024000801627 +:1027D000F109880122137FF29603E001D536A74163 +:1027E00050147FFFD939A6C240140010E662F18C64 +:1027F000E9038E61D5028460A703F0038E02E080B6 +:10280000E8038C81D502F4063C1C00FE8400B61F50 +:10281000501080A28441F00480A649FFFF32A07EC0 +:10282000F20C3810A60242110073F207FE54042382 +:10283000800838212602880240008016F1098801AC +:1028400022137FF29603E0204000BC1A12037FF8A7 +:1028500012037FF4D507841FAE3002037FF2120308 +:102860007FF8A03DF10B8801A6C2CB2DA640E62241 +:10287000E9029EC9A70150047FFEE080E8038C8135 +:10288000D50350447FFF3C1C00FE8401B61F50104E +:1028900081448440F0049D7149FFFEF3A07FF2085B +:1028A0003810A6028A20FE5404238008382126020C +:1028B000880240008016F10A880122137FF39603F4 +:1028C000E001D532A743F106D936A6C0E662E90396 +:1028D0008E61D5028460A70150047FFEE080E8038A +:1028E0008C81D50350447FFF3C1C00FE8441B65FC1 +:1028F000501081E69972F00449FFFEC3A07FF20DEB +:102900003810A60242110073F208FE540423800816 +:1029100038212602880240008016F10A880122131D +:102920007FF39603E0204000BC1A12037FF91203E4 +:102930007FF5D507841FAE3102037FF312037FF9C1 +:1029400022037FF81205000022037FF9120500011F +:10295000D50C2205000012037FF8220500011203A6 +:102960007FF9841FAE30AE31F0058D448C01F085C7 +:10297000506300FC48FFFEEEFCC7FC48F08DFA04F3 +:10298000120F801DFA02120F801E8400120F801F8A +:102990002E000431F18C8122C007840A120F801DA1 +:1029A0008408120F801E3C0DFA9AB400920E96060F +:1029B0005A080108840A120F801D8408120F801E15 +:1029C0002E07E97BC80B020F801D8C03120F801DA0 +:1029D000020F801E8C03120F801E844180A2F00C17 +:1029E00044126B308460848249FF77908441806216 +:1029F0008029848280A2F00C49FF778884204421BA +:102A00003598443D94D044426B302E07C53AE220BD +:102A1000E816980A9401994388A980C1A5688C2179 +:102A2000AD402E07C53B2E57C53A8E0142628073DA +:102A3000943199448809A400AC28D5E844026B304D +:102A4000802084428461848384A049FF775F802949 +:102A500044026B3084428461848384A049FF7756AA +:102A60002E37C53A84C084E144026B30B67F501FD4 +:102A7000803A804080A72E47C53BF681F682F683D8 +:102A8000F684F685F786F787F688F689F68A49FF91 +:102A9000AD042E37C53A8009B67FB04F804980A774 +:102AA0002E47C53BF681F682F683F684F685F786D7 +:102AB000F787F688F689F68A49FFACEF2E37C53AD4 +:102AC0008542B67FF38214AF80068009804980A7D3 +:102AD0002E47C53BF781F683F684F685F687F688A0 +:102AE000F689F68A44126B3049FFACD72E37C53AC7 +:102AF0008009B67FB04E804980A72E47C53BF6813E +:102B0000F682F683F684F685F786F687F688F689E8 +:102B1000F68A12AF801C49FFACC02E37C53AB00E02 +:102B2000F382802980A62E47C53BB6DFF781F68366 +:102B3000F684F685F786F787F688F689F78A4422C1 +:102B40006B30127F801C49FFACA82E37C53A8548F0 +:102B500044126B30B67FF382F00C804180A72E4781 +:102B6000C53BF781F683F684F685F68614AF8007B9 +:102B7000F688F689F68A49FFAC902E37C53A501F81 +:102B8000803E44007FFFB67FF088804180A72E47BB +:102B9000C53BF681F682F683F684F685F686F687DF +:102BA000F789F78A44026B3049FFAC772E37C53A74 +:102BB000F00D80292E47C53BB67FF781F382F6835F +:102BC000F684F685F68614AF8007F688F689F78ACC +:102BD000804980A749FFAC61020F801F4410277312 +:102BE00040008006FCC8FC2049FF751149FFCA3B24 +:102BF0005A00080B49FFCA612E07E8FEC80349FFC7 +:102C0000C82249FFCA7A4473F04BA6384413F04BEC +:102C10005A00FF05841FAE08D5FF49FFCDD65A00E4 +:102C200003EB5A0002F05A0013F23C0DFAA8A780F9 +:102C300097B0CE3A49FF76B43E60045C49FFCA9B28 +:102C40002E07E9605A08120E3C03F4D7802649FF8C +:102C5000F30B5A08010780062E10045C49FFF2624C +:102C60002E07E9605A0004125A08190449FFF29A23 +:102C700049FFCAE049FFCFB15A0002C52E07E960FB +:102C80005A08050A49FFCBBB440000FF2E10045C24 +:102C900049FFF2483C0DFAA88421AE4084003C0F65 +:102CA000FAD449FFCB8749FF72A95A0802B049FFFD +:102CB000B1D9C8AC2E67E945CEA92E00041A5A082E +:102CC0000A0549FFBC3CD51D44112EA08461380083 +:102CD000810180468026808349FFD98C2E10041AFA +:102CE00044212E9438510400D00C84414400280023 +:102CF00080268062808249FFD97D84013E07E945B4 +:102D00002E00041A842B8C019600400004373E10DC +:102D1000041A48FFFF7C00004250882440104009FC +:102D200042500C73960140314009969142F00C24B8 +:102D300042400824FE8C40078800E20240F7C008A9 +:102D40004020400842F08C7340104009882F9822A0 +:102D5000E204882F984DDD9E8060C207994A0840A2 +:102D6000800118418001D9FCDD9E92008060995A53 +:102D7000D30418118001D5FDDD9E9200EDEEEFFF2A +:102D80000001111213000000FFFFFFFF08FFFFFF0B +:102D9000FF00000000000001000100000000010031 +:102DA0000000000001000000000100000001000020 +:102DB000010000000100000000000000000100010F +:102DC0000000010001000000000000010000000000 +:102DD00000000100000001000000000100000000F0 +:102DE00000010100000001000000000100000000DF +:102DF00001000000000100000001010000000000CF +:102E000001000000000100000001000000000000BF +:102E100001000100000000000000010000010000AE +:102E20000001000004050607020202030303040474 +:102E3000000000000C0C005550710200D873020015 +:102E400060760200E8780200600C0200A020020018 +:102E500000400200604C0200701102008016020067 +:102E6000E0510200F05602006767676767676767AF +:102E700067676767676767676767000064646464BC +:102E800064646464646464646464646464640000CA +:102E90000B0B0B0B0B0B0C0C0A0B0C0C0A0A0A0A83 +:102EA0000A0A00003C2C2F3133350000083C00009A +:102EB0000306080A0D100000100D0A0806030000A2 +:102EC0003C0800003533312F2C3C00004063646423 +:102ED000646464644F4F64646464646463400000C9 +:102EE00062646464646464645A5A646464646464B8 +:102EF000646200006364646464646464646464645D +:102F000064646464646300003F646464646464646F +:102F10006464646464646464643F0000402B020081 +:102F2000D02B0200B03E0200403F0200202A0200E7 +:102F3000B02A0200903D0200203E020050710200C3 +:102F4000D873020060760200E87802007011020077 +:102F500080160200E0510200F0560200F000F0007E +:102F6000B4009000600C0200A020020000400200AB +:102F7000604C0200600C0200A02002000040020031 +:102F8000604C02007011020080160200E051020045 +:102F9000F0560200008914000EE8070E16F000003B +:102FA000000300C103C105C107C109C10BC10DC1A7 +:102FB0000FC101C2A4C04422D0204412000094DA00 +:102FC0008861B662A4C25041002094DA8861A8D218 +:102FD000A4C494DA8861A8D1A4C694DA8861B664DE +:102FE0000230000894DA8861A8E1A4C494DA886108 +:102FF000A8E50200000894028820A866DD9EB4407F +:1030000084A08C449C2EA2D196005A58200680A001 +:103010005A0824FADD9E5441801F384094088CA140 +:1030200097689265D8F3D5F4FC20B46084008C7C5A +:103030009583A31997B08440995697688C41547230 +:10304000000F96903870940892845A2808F78C01E3 +:1030500096005A0804EFFCA0FC20B46084005031B4 +:10306000802C9583A31997B08440995697688C411A +:103070005472000F96903870940892845A2808F77A +:103080008C0196005A0804EFFCA0FC003C0C017A6D +:1030900084233C0FFAA44403F40B8440AE40440361 +:1030A000F4048426AE404413F4078401AE084413AC +:1030B000F408AE084413F01EAE884413F420AE08A2 +:1030C0002E07C5D45A0801063C0C017A490000318C +:1030D0004402D0204412D22849FFFF934402D0205A +:1030E0004412D71849FFFFA24402D0244412D5202D +:1030F00049FFFF9C4412D5E44402D02049FFFFAEB3 +:103100004900004F44028F7049FF9DA8FC80441085 +:1031100000963C1BF4C44412C8C884003E07E9680A +:103120003E07E950AE08AE09AE0AAE0BDD9EFC00CC +:103130000400001244120054921054007FFF9402C5 +:10314000880144128F700020812810200018002070 +:10315000812910200019002081261020001B00105A +:1031600081271010001AA08546110000FE57A845BF +:10317000A08546120000FE57A845A085461800000D +:10318000FE57A845A08546140000FE57A8454402F6 +:10319000283849000050FC803C0FFFA6DD9E3C2CE7 +:1031A000017A441200A804010012921054007FFF1B +:1031B0009402880144120000B400920A96373E0738 +:1031C000E94004010012921054007FFF940288012C +:1031D000B42000000020922A96773E17E9253E078A +:1031E000E947DD9E440251703C0FFA7C4403F142F2 +:1031F000441028B8AC40441251888400B6013C1DEC +:10320000FA7CA80F3C1DFA7C14008008DD9EFC00AF +:103210004413F381A608540000F0AE084413F3846D +:103220008400AE084413F56BAE0849FFA9F2FC8098 +:10323000DD9E441E0000880192024413F3CA9601E9 +:10324000AC08DD9E4423F054AC104403F056AC406F +:10325000DD9EDD9E96069404965FFE474403F04390 +:10326000AE40DD9E4413F044AC08DD9E4423F05094 +:103270009617A650541080F8FE47AE50DD9E4423AA +:10328000F0509617A65094045410808FFE47AE500D +:10329000DD9EFC00840749FFFFEB4403F04C8420D3 +:1032A000AE40840749FFFFED4403F04E8421AE4059 +:1032B00049FFAD61FC803C0FFFA7DD9E3C0FFA8605 +:1032C000DD9E3C0FFA7BDD9E3C0FFA88DD9E3C0FB5 +:1032D000FFACDD9E3C0FFFABDD9E3C0FFFAADD9EE9 +:1032E0003C0FFFB7DD9E3C0FFA8ADD9E3C0FFA894A +:1032F000DD9E3BFFFCBCEFFC8401842049FFFFAC5A +:10330000EC0444000CD53BFFFC8448FFFFAD442394 +:10331000F01FA610541000E04403F302A6C0A6005C +:10332000962788019600AE10DD9E3BFFFCBC840012 +:10333000EFFC802049FFFF8849FF6E7349FFFEA71D +:1033400049FFFFD949FFFFE549FF73C349FFFF4C20 +:1033500049FFFFA149FFFF6E49FFFF5BEC043BFF04 +:10336000FC8448FF68FF3C0DFAAB3A6FA8BC80C1F3 +:103370005A08040D2E07C5D3C009840249FFEF4641 +:103380003C0DFAAB5A080424D51149FF6F375A0097 +:1033900002F6840149FFEF3A84208461840280416F +:1033A000808180A349FF6F8AD5F149FF6F275A00BA +:1033B000020F2E77C5D35A78010B800749FFAAD890 +:1033C000840049FF9422800749FF6EA84473F04AA5 +:1033D000449000553C0DFAD0C009840449FFEF1613 +:1033E0003C0DFAAB5A080429D50B49FFAAC55A0867 +:1033F00001F6840349FFEF0A10938000D5EC49FFE2 +:103400006EFD5A00021A2E07C5D35A08011649FF4D +:10341000704C4403F429441FFFC3AE40840049FFAD +:10342000A2853C0DFA97842049FF736C8402AE316B +:103430003A6FA884DD9E49FF6EE15A08023284206B +:10344000846180418083FA1049FFD5D484415410AF +:1034500000DF80628082FA1049FFD5CC842084612D +:1034600080418083440046E049FFD5C484208461C4 +:1034700080E080414400CFF0808349FFD5BB5A787B +:10348000070BC80584033E07E96CD50A84043E0790 +:10349000E96CD506CF05C80484013E07E96C804677 +:1034A0008405842049FFA52C3C0DFA97842049FF10 +:1034B00073298402AE31840149FFABAD84053A6FB4 +:1034C000A88448FFEEA33C0FFA8EDD9E3C0FFFFB65 +:1034D000DD9E3C0DFA8EA4413C1BFFEFA444A600E8 +:1034E0003C1BFFEE3E07FFDADD9E3A6FAABCEFFC05 +:1034F0002E57C53A2E27C56A2E47C53B962942103E +:1035000008243C1BE2A596E12E17C56BFE1C3C0B64 +:10351000E2B64261842444022D85924192213E27E5 +:10352000C5713E57C5473C6BE2A63E17C5723E4784 +:10353000C548A6408421AE40A6418420AE414452F5 +:103540002D9C443DD9D044228F7044022DA4986B09 +:103550003811041018128001D8FB84C044027B90FB +:103560003C6FFA9D49FFFD283C0C017A44122CFE69 +:103570003C0FFAAA44222CFC44022D5CB6C0AD904C +:10358000AD883C1FFAA344122CF83C1FFAB3441236 +:103590002CF93C1FFAA844122CFA3C1FFA972E175C +:1035A000C5DB3C0FFA9A3C2FFAA13E67E9465A1850 +:1035B0000107B42058108002B620D505B440843DE0 +:1035C000FE56B62044122D5C440FBFFFB441852146 +:1035D000FE16B601B401847B40002404B601B40198 +:1035E0008457FE1EB601B40184C0FE16B601B401B4 +:1035F000854058000010B601B481440FFFBFFE267D +:10360000B601B40184E058000020B601B4015800AE +:103610000C00B601B481440FCFFFFE2658002000F5 +:10362000B601B40144122CFE3C0FFAB5A508841D66 +:10363000FE26AC08A508841EFE26AC08A408FEC61B +:10364000ACC8A408FE86AC88A44844022CFCAC405C +:103650003E67E9743E67E9643E6004373C9E010EB4 +:103660002E07C5E03CABF4DB3E07E92B440FFFAA75 +:103670003E07E932440000553E07E9373E07E92D91 +:103680003E07E9703EA7E97E3E67E96F3E67E9398C +:103690003E6004593E67E9083CABF4D53CABF4DD31 +:1036A0003E60041A3E67E9453E97E9603E97E91996 +:1036B000490002483C0DFA973E67E8FE3CABF4D760 +:1036C0003E67E8FFAF813E67E9183E97E9563E67DF +:1036D000E917AF803C1DFAB384023E67E90A3C9EBD +:1036E00001B53E67E93D3E60044C3E60044D3E67D7 +:1036F000E920AE083C1DFAA8AE0884043E07E96C38 +:103700004402D0A83C0E01CB4402D1943C0E01CC23 +:103710004402D3683C0E01CD4402D6703C0E01CE6B +:10372000440000323C0804E03E67E9213C7FFAA4F3 +:103730003E67E9523E97E94C3E60044F3C7BF4EB18 +:103740003CABF4E33E67E9163C0804E44402D64C83 +:103750003C0E02714402D5D83C0FFAAF840A3E07F2 +:10376000EAA42E07C53B3E67EAB83E07C66D440291 +:103770008F703E67EAA53E67EAA63E6004193C7F6B +:10378000FAB83C7FFAB43C7FFAAD3C7FFA9F3C7FAD +:10379000FAB13C7FFA9E3C7FFABA3C7FFAB23C7F9A +:1037A000FA933C7FFA98490001E6800749FF73BE0F +:1037B000800949FF73BB800749FF73C63C0E01E9CE +:1037C000800949FF73C13C0E01EA840249FF73BCC2 +:1037D0003C0E01EB840349FF73B73C0E01EC8404FB +:1037E00049FF73B23C0E01ED840549FF73AD3C0EF9 +:1037F00001EE840649FF73A83C0E01EF840749FFE0 +:1038000073A33C0E01F0840849FF739E3C0E01F146 +:103810003C03E2A53C13E3B23C0BE3B03C03E2A65D +:103820003C7E01123C0BE4193C03E3B33E67E93EE6 +:103830004000240C88013C0BE3B43C03E41C3C1323 +:10384000E41B4000240C88013E67E9343C0BE41D76 +:103850003E60044449FF80AF3C0FFAB649FF8083C5 +:103860004402D79C3C0E02C34402B5103E67EADD19 +:103870003E67EADC3E67EADE3E600B083C7E02C43F +:103880003C0FFAB9845F3C0DFAB6843F38201C081F +:103890008CE65A783CFA3C0DFAB684C03C6E010FB7 +:1038A0001010003C1010003D3C6E01103E600453AF +:1038B0003E6004513E6004543E6004553E67EA5841 +:1038C0003E67EA5A3E67EA593E67E9783E67E9345F +:1038D0003E67E95A3E67E9493E67E95D3E67E910A0 +:1038E0003E67E93C3E60045849FFBB454400006424 +:1038F0003C08054C4400005A3C08054E4400009624 +:103900003C08054F3C080554FA183C080555840549 +:10391000FA293C08055744027B703E67E9433C6B3B +:10392000F4EA3E6004603E6004563E600A953E60E4 +:103930000A963C68054D3C6805503C6805513C685A +:1039400005533C1805523C6805563C6805583E67CF +:10395000E9263E67E9483E67E9293E67E96E49FF87 +:1039600091AA2E07C5D45A08010449FFFBD284014D +:103970003E0004503E07E94D4402D40449FF6D0562 +:1039800049FF6D0184003E07E9573E07E90B3E07FA +:10399000E9113E07E93A3E07E91B3E07E9673E07A2 +:1039A000E9623E07E9243E07E92C3E07E9758400F9 +:1039B0003C0BF4D33C0BF4DE3C0BF4D44400007815 +:1039C0003C0BF4D04400003C3C0BF4E9840A441066 +:1039D000007F3E07E912840F3E17E9653E07E97C48 +:1039E000EC043A6FAA84DD9E3A6F9CBC4462902836 +:1039F000EFF4800649FFFC6150037F48F0814900E5 +:103A000000959C34490000955003007849000097C8 +:103A1000500300A849000090500300CC49FF728079 +:103A200050037F48F08149FF727E500300B049FF88 +:103A3000FC5C50037F48F08149FFFC5A50037F48EB +:103A4000F08149FFFC435003011849FFFD3E50033C +:103A50007F48F08149FFFD3C49FFFD3D5003012CAB +:103A600049FFFC37507303A850037F48F08149FF9A +:103A7000FC33800749FFFC3350037F48F08149FF46 +:103A80008DD15003017049FF8DCA5003031849FFBF +:103A9000764050037F48F08149FF763E500303642F +:103AA00049FF747B50037F48F08149FF74795003CC +:103AB000037449FF82B750037F48F08149FF82B504 +:103AC000800749FF7F4A50037F48F08149FF7F48C4 +:103AD000500303B449FFFBF750037F48F08149FFCF +:103AE000FBEF3C0DFA9A49FFAA6C500303D849003A +:103AF000003C50037F48F0814900003A50030048E1 +:103B000049FFFB4C50037F48F08149FFFBEB50031A +:103B10007F48F08149FFF0E850037F48F081EC0CCA +:103B20003A6F9C8448FFCD3D3C0FFA91DD9E3C0FDF +:103B3000FA8FDD9E3C0FFA90DD9E3C0E00DEDD9E8E +:103B4000FC0049FF6BEC84203C0E00E91010005093 +:103B5000101000511010005210100053101000608F +:103B600010100061FC803C0E00FEDD9E3C0E00FD4E +:103B7000DD9E3C0E00FFDD9EFC40049F800A5A90B3 +:103B8000010B4462D4EC4472D1743863040038737E +:103B90008400D50384E284CA8380FB48B9105410A2 +:103BA000FFFF944A4213287344A20000882ABE12E1 +:103BB0000080800792D010818000A6CE54637FFFE2 +:103BC000AEE0A6CCAEE80230002B02408009020035 +:103BD000002B0210800888648801940194D9886AB7 +:103BE000F4088940F009B664B7402E07E968C003BD +:103BF0005A98010E441000549432420384734412C4 +:103C000000008801B400920A9637D5032E000D28D3 +:103C1000AE10FCC0FC00838044600030BD12B812BE +:103C20005452FFFF54007FFF956A940242021873BA +:103C3000425198734442000044620030888088C03A +:103C40008AA0383290028C26540183FF1200FFFDB7 +:103C50004001A8099274543183FF1230FFFF5400D1 +:103C600003FFA2E11200FFFE540183FFAC104001EC +:103C7000A8099274540003FF543183FFAC11ACD2F5 +:103C80008C464C437FE0FC80FC40045000115452B1 +:103C9000FFFFC91B8380443200F0B910B8115410E3 +:103CA000FFFF944A882354007FFFA64C9648C22405 +:103CB00094024430004842008C7344520000441285 +:103CC000004888A08801D515956A4462000088C51F +:103CD00044700048E264E8DF80A642519C73509231 +:103CE0008048181280014C54FFFE8C6196D8D5F3A1 +:103CF00018228001D8FEFCC0040000114440004896 +:103D000054007FFF9402420190734452000088A047 +:103D1000840098C8A6D94041E0083830800040317E +:103D2000C00888649910A72140422008886438415F +:103D300000008C028864AAE95A0824EDDD9E040084 +:103D400000114440004854007FFF940242019073E8 +:103D500080604402000088608400A5193840800813 +:103D6000A75B9908AF61B483995038410008A31943 +:103D700092888C02AF295A0824F2DD9EE201E808FD +:103D8000A610E260E8039AC3D50B8400D50CE220AC +:103D9000E80BA61052F180FFE00FE8048860AED077 +:103DA000DD9E841FAE10DD9EFC40EEE85A38010710 +:103DB0003CA0028544400120D5092E500D124C50E4 +:103DC00000B93CA0028444400C602E57E8FBF48606 +:103DD000E6A28481E9058EA14042140C972040425E +:103DE000040E9720F485CC038481F485F18880202B +:103DF000B00EB61FB00F505F8035F389F284F081AA +:103E0000F3828002503F8036B08D504F803749FF9B +:103E1000FEB5F004B062B0B4003F8036004F80378A +:103E200049FFFEFAF004B050B099003F803549FFD9 +:103E3000FF88B0228120B1D08500B00E3840220228 +:103E4000F0095A08010551C20090D50351C21B90D8 +:103E5000F00684C09960FA1442040024F08A3824E1 +:103E600099015A23FF552E17E8FC3832090100FF4B +:103E7000803405EF800894118E21F0874001BC1634 +:103E80004DE0C01CF107883C03E0800040FF3DF698 +:103E900040F7A8014EF4000452F780008A0A4E044D +:103EA0000003FE0240F78007E903ACC8D5303802B2 +:103EB000890138039808D52BF108C904383E09094F +:103EC000D513F107883CA48840213C568A4A4E24E9 +:103ED0000003FE9240F028014EF4000452F78000E7 +:103EE000E04FE908ACC8381499013823980038220B +:103EF0008509F10AB0D098B188439601802AF3056C +:103F0000F58BF48749FFFF3CF50BF4078CC15A6829 +:103F100024A850948048507380245A80010485015D +:103F2000D58DF004B050B099003F803549FFFEE6D2 +:103F3000ED18FCC0FC418401B63FF28180E349FFEB +:103F4000AC3B3C1DFAB38401AE083C1DFAA8AE0898 +:103F500084003C0FFAD72E0004595A080104840744 +:103F6000D5085A7801052E07C629D5032E07C6287D +:103F70003E07E8FB2E07E8FB84C08C013E07E8FC07 +:103F80003C6FFAD444A3F04A448000552E07E8FC65 +:103F9000E2C08400E8373C0FFAD9CF0349FFA18A79 +:103FA00049FF7586852010850000F0014C900024A3 +:103FB0003C0DFAD9E320E8FA2E07C5D4C0112E072C +:103FC000C5E6C00E2E500D124C54C00BCF092E006A +:103FD0000423C806800649FFA0CE5A0001178009B5 +:103FE0008026B45F806749FFFEE1505480015492FF +:103FF00080FFD5DC3C0DFAA88CC1842197B0AE407F +:10400000D5C649FFABD98400FCC1FC002E00045981 +:10401000C8063C13E3153C23E316D5044420008076 +:1040200080222E37E9683C03E3105A38040D2E37FE +:10403000E914520000FFFE1C2E37E94740000C1621 +:10404000520000FF3C0802843C03E31196483C0800 +:10405000028584003E07E8FA96903C0DFAAA846037 +:104060002E47C56549FFFE123C0DFA973C1DFAAA82 +:104070002E27C567846049FFFF5F80C05A0801088A +:10408000FA0349FF6B083E600423D53E49FF6E9852 +:104090003C1DFA975A0802058405AE09D507840924 +:1040A000AE098001842049FF730F3C0DFA9749FF48 +:1040B0009526844180623C1DFAAA3C0DFA9749FF7F +:1040C000FF3B84004412CE58844149FFCF6B8407E4 +:1040D00049FFEE7E49FF6E745A080206842D3C0D9E +:1040E000FA97D50D3C0DFA97842049FF72ED2E17F3 +:1040F000E96A3C0DFA975A180203842AAE413C0D36 +:10410000FA9749FF94FCFC803BFFFCBCEFFC4402A7 +:10411000000044121B9049FF70FC3C0DFAA884215A +:10412000EC04AE403BFFFC84DD9E3A6FA4BCEFDCA8 +:1041300044112E64B1843A2094003A231420812043 +:1041400049FFA0B849FF9DECF08149FF9CDF840046 +:10415000120F800784E038131E02500F800E2E27A6 +:10416000C5472E37C5488CE149FF71405A7804F5A0 +:10417000000480005A08012184033C1DFA97F201D3 +:104180004432B38F49FF95F42E17E925440000C847 +:10419000FE0C120F800744121B90500F800E2E272A +:1041A000C5472E37C54849FF712149FF74813C1D21 +:1041B000FAB3A608C8FF4403F04A44100055EC24A3 +:1041C000AE403A6FA4848400DD9E3BFFFEBCEFF856 +:1041D000FA0049FF6A6049FF933B84013E07E94EBC +:1041E0003E07E91F84003E0004233E07E9383E07EE +:1041F000E8F949FF6DE53C1DFA975A08020D840461 +:10420000AE098001842049FF725F3C0DFA97842D2E +:10421000AE41D50B8409AE098001842049FF725458 +:104220003C0DFA97842AAE413C0DFAB38421AE408E +:104230002E07C5D45A0801122E07E9683E07E95037 +:104240002E07E956C8043E07E90BD5072E07E90BF0 +:104250005A0801043E0004233C0DFA97A6013E07CC +:10426000E96A840649FFEDB42E000423C8193C1DF9 +:10427000FA972E27E9574432B38F49FF95793C07C7 +:10428000F4E549FF9F772E07C5DE5A08010449FF70 +:10429000FEBE840A49FFED9C840B49FFED992E0078 +:1042A00004235A08010D8400120F80034412AD70DC +:1042B000500F8006FA42FA7449FF70982E07C5D451 +:1042C0005A08010D2E0004235A0001052E07E93873 +:1042D000C8054402CE5B49FFFF2A2E07C5D45A0801 +:1042E000011B2E000423C81149FFB5055A00010A1D +:1042F0003C1DFA972E07E968A64949FF7029D50F9A +:104300003E07E90B48FFFF663C1DFAB3A6085A08B2 +:1043100001FFD5EF2E07E96849FF703684003E00A3 +:10432000045949FF6D4D3C1DFA972E27E96A5A083A +:1043300002069E12E602E804D5055A200204AE8960 +:10434000D503840DAE093C0DFA9749FF93D884003C +:104350003E07E9783E07E9213E07E91F2E07C5FC25 +:1043600084213E07E94A3C0DFAA8AE4049FF73A0FC +:10437000490000695A08020448FFFF2C84004422C7 +:1043800025B08060444220A080A03C13E2B6E20148 +:10439000E8099842AEC8944188248C01AD48960142 +:1043A000D5F584003E07E96684013E07E92EEC0856 +:1043B0003BFFFE84DD9E440000A23A6F98BC49FF9B +:1043C000ECFD3C0DFA97A6015A080D128400847F7B +:1043D0003C2DFAB6843F383100088C065A083CFA66 +:1043E0003C0DFAB61010003C1010003D49FFD08380 +:1043F0003E0004312E07C54384C0520000013E67D1 +:10440000E90849FF6D8784013E07E92F3E07E94F20 +:104410003E67E95B3E67E90B3E6004323E60043371 +:104420003E60043449FFC0082E07C5D43E67E971D9 +:104430005A0801063A6F988448FFA9BE3A6F9884DB +:10444000DD9E3A6FA6BCEFE044012E74B1843A20A1 +:10445000140044012E843A2F94203A2014002E0791 +:10446000C5D480FF3A2314205A0801322E000423B9 +:10447000C81F2E07E96849FF6F155A08010A2E0761 +:10448000E9565A0801063E07E90B8402D53249FF76 +:10449000B12D85203803A602381326028D2149FF4D +:1044A0006F385A9804F984013E07E938D5102E0771 +:1044B000E938C80D2E07E95749FF6F0D2E17E95748 +:1044C000380F86023813060249FF6F2344021B90FF +:1044D0004412451049FF6F1D84C144021B904412D1 +:1044E00040003E67E94D49FF6F143E600428840197 +:1044F000EC203A6FA684DD9E000000000000000062 +:1045000000000000000000000000000000000000AB +:10451000000000000000000000000000000000009B +:10452000000000000000000000000000000000008B +:10453000000000000000000000000000000000007B +:10454000000000000000000000000000000000006B +:10455000000000000000000000000000000000005B +:10456000000000000000000000000000000000004B +:10457000000000000000000000000000000000003B +:10458000000000000000000000000000000000002B +:10459000000000000000000000000000000000001B +:1045A000000000000000000000000000000000000B +:1045B00000000000000000000000000000000000FB +:1045C00000000000000000000000000000000000EB +:1045D00000000000000000000000000000000000DB +:1045E00000000000000000000000000000000000CB +:1045F00000000000000000000000000000000000BB +:1046000000000000000000000000000000000000AA +:10461000000000000000000000000000000000009A +:10462000000000000000000000000000000000008A +:10463000000000000000000000000000000000007A +:10464000000000000000000000000000000000006A +:10465000000000000000000000000000000000005A +:10466000000000000000000000000000000000004A +:10467000000000000000000000000000000000003A +:10468000000000000000000000000000000000002A +:10469000000000000000000000000000000000001A +:1046A000000000000000000000000000000000000A +:1046B00000000000000000000000000000000000FA +:1046C00000000000000000000000000000000000EA +:1046D00000000000000000000000000000000000DA +:1046E00000000000000000000000000000000000CA +:1046F00000000000000000000000000000000000BA +:1047000000000000000000000000000000000000A9 +:104710000000000000000000000000000000000099 +:104720000000000000000000000000000000000089 +:104730000000000000000000000000000000000079 +:104740000000000000000000000000000000000069 +:104750000000000000000000000000000000000059 +:104760000000000000000000000000000000000049 +:104770000000000000000000000000000000000039 +:104780000000000000000000000000000000000029 +:104790000000000000000000000000000000000019 +:1047A0000000000000000000000000000000000009 +:1047B00000000000000000000000000000000000F9 +:1047C00000000000000000000000000000000000E9 +:1047D00000000000000000000000000000000000D9 +:1047E00000000000000000000000000000000000C9 +:1047F00000000000000000000000000000000000B9 +:1048000000000000000000000000000000000000A8 +:104810000000000000000000000000000000000098 +:104820000000000000000000000000000000000088 +:104830000000000000000000000000000000000078 +:104840000000000000000000000000000000000068 +:104850000000000000000000000000000000000058 +:104860000000000000000000000000000000000048 +:104870000000000000000000000000000000000038 +:104880000000000000000000000000000000000028 +:104890000000000000000000000000000000000018 +:1048A0000000000000000000000000000000000008 +:1048B00000000000000000000000000000000000F8 +:1048C00000000000000000000000000000000000E8 +:1048D00000000000000000000000000000000000D8 +:1048E00000000000000000000000000000000000C8 +:1048F00000000000000000000000000000000000B8 +:1049000000000000000000000000000000000000A7 +:104910000000000000000000000000000000000097 +:104920000000000000000000000000000000000087 +:104930000000000000000000000000000000000077 +:104940000000000000000000000000000000000067 +:104950000000000000000000000000000000000057 +:104960000000000000000000000000000000000047 +:104970000000000000000000000000000000000037 +:104980000000000000000000000000000000000027 +:104990000000000000000000000000000000000017 +:1049A0000000000000000000000000000000000007 +:1049B00000000000000000000000000000000000F7 +:1049C00000000000000000000000000000000000E7 +:1049D00000000000000000000000000000000000D7 +:1049E00000000000000000000000000000000000C7 +:1049F00000000000000000000000000000000000B7 +:104A000000000000000000000000000000000000A6 +:104A10000000000000000000000000000000000096 +:104A20000000000000000000000000000000000086 +:104A30000000000000000000000000000000000076 +:104A40000000000000000000000000000000000066 +:104A50000000000000000000000000000000000056 +:104A60000000000000000000000000000000000046 +:104A70000000000000000000000000000000000036 +:104A80000000000000000000000000000000000026 +:104A90000000000000000000000000000000000016 +:104AA0000000000000000000000000000000000006 +:104AB00000000000000000000000000000000000F6 +:104AC00000000000000000000000000000000000E6 +:104AD00000000000000000000000000000000000D6 +:104AE00000000000000000000000000000000000C6 +:104AF00000000000000000000000000000000000B6 +:104B000000000000000000000000000000000000A5 +:104B10000000000000000000000000000000000095 +:104B20000000000000000000000000000000000085 +:104B30000000000000000000000000000000000075 +:104B40000000000000000000000000000000000065 +:104B50000000000000000000000000000000000055 +:104B60000000000000000000000000000000000045 +:104B70000000000000000000000000000000000035 +:104B80000000000000000000000000000000000025 +:104B90000000000000000000000000000000000015 +:104BA0000000000000000000000000000000000005 +:104BB00000000000000000000000000000000000F5 +:104BC00000000000000000000000000000000000E5 +:104BD00000000000000000000000000000000000D5 +:104BE00000000000000000000000000000000000C5 +:104BF00000000000000000000000000000000000B5 +:104C000000000000000000000000000000000000A4 +:104C10000000000000000000000000000000000094 +:104C20000000000000000000000000000000000084 +:104C30000000000000000000000000000000000074 +:104C40000000000000000000000000000000000064 +:104C50000000000000000000000000000000000054 +:104C60000000000000000000000000000000000044 +:104C70000000000000000000000000000000000034 +:104C80000000000000000000000000000000000024 +:104C90000000000000000000000000000000000014 +:104CA0000000000000000000000000000000000004 +:104CB00000000000000000000000000000000000F4 +:104CC00000000000000000000000000000000000E4 +:104CD00000000000000000000000000000000000D4 +:104CE00000000000000000000000000000000000C4 +:104CF00000000000000000000000000000000000B4 +:104D000000000000000000000000000000000000A3 +:104D10000000000000000000000000000000000093 +:104D20000000000000000000000000000000000083 +:104D30000000000000000000000000000000000073 +:104D40000000000000000000000000000000000063 +:104D50000000000000000000000000000000000053 +:104D60000000000000000000000000000000000043 +:104D70000000000000000000000000000000000033 +:104D80000000000000000000000000000000000023 +:104D90000000000000000000000000000000000013 +:104DA0000000000000000000000000000000000003 +:104DB00000000000000000000000000000000000F3 +:104DC00000000000000000000000000000000000E3 +:104DD00000000000000000000000000000000000D3 +:104DE00000000000000000000000000000000000C3 +:104DF00000000000000000000000000000000000B3 +:104E000000000000000000000000000000000000A2 +:104E10000000000000000000000000000000000092 +:104E20000000000000000000000000000000000082 +:104E30000000000000000000000000000000000072 +:104E40000000000000000000000000000000000062 +:104E50000000000000000000000000000000000052 +:104E60000000000000000000000000000000000042 +:104E70000000000000000000000000000000000032 +:104E80000000000000000000000000000000000022 +:104E90000000000000000000000000000000000012 +:104EA0000000000000000000000000000000000002 +:104EB00000000000000000000000000000000000F2 +:104EC00000000000000000000000000000000000E2 +:104ED00000000000000000000000000000000000D2 +:104EE00000000000000000000000000000000000C2 +:104EF00000000000000000000000000000000000B2 +:104F000000000000000000000000000000000000A1 +:104F10000000000000000000000000000000000091 +:104F20000000000000000000000000000000000081 +:104F30000000000000000000000000000000000071 +:104F40000000000000000000000000000000000061 +:104F50000000000000000000000000000000000051 +:104F60000000000000000000000000000000000041 +:104F70000000000000000000000000000000000031 +:104F80000000000000000000000000000000000021 +:104F90000000000000000000000000000000000011 +:104FA0000000000000000000000000000000000001 +:104FB00000000000000000000000000000000000F1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE00000000000000000000000000000000000C1 +:104FF00000000000000000000000000000000000B1 +:1050000000000000000000000000000000000000A0 +:105010000000000000000000000000000000000090 +:105020000000000000000000000000000000000080 +:105030000000000000000000000000000000000070 +:105040000000000000000000000000000000000060 +:105050000000000000000000000000000000000050 +:105060000000000000000000000000000000000040 +:105070000000000000000000000000000000000030 +:105080000000000000000000000000000000000020 +:105090000000000000000000000000000000000010 +:1050A0000000000000000000000000000000000000 +:1050B00000000000000000000000000000000000F0 +:1050C00000000000000000000000000000000000E0 +:1050D00000000000000000000000000000000000D0 +:1050E00000000000000000000000000000000000C0 +:1050F00000000000000000000000000000000000B0 +:10510000000000000000000000000000000000009F +:10511000000000000000000000000000000000008F +:10512000000000000000000000000000000000007F +:10513000000000000000000000000000000000006F +:10514000000000000000000000000000000000005F +:10515000000000000000000000000000000000004F +:10516000000000000000000000000000000000003F +:10517000000000000000000000000000000000002F +:10518000000000000000000000000000000000001F +:10519000000000000000000000000000000000000F +:1051A00000000000000000000000000000000000FF +:1051B00000000000000000000000000000000000EF +:1051C00000000000000000000000000000000000DF +:1051D00000000000000000000000000000000000CF +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:10520000000000000000000000000000000000009E +:10521000000000000000000000000000000000008E +:10522000000000000000000000000000000000007E +:10523000000000000000000000000000000000006E +:10524000000000000000000000000000000000005E +:10525000000000000000000000000000000000004E +:10526000000000000000000000000000000000003E +:10527000000000000000000000000000000000002E +:10528000000000000000000000000000000000001E +:10529000000000000000000000000000000000000E +:1052A00000000000000000000000000000000000FE +:1052B00000000000000000000000000000000000EE +:1052C00000000000000000000000000000000000DE +:1052D00000000000000000000000000000000000CE +:1052E00000000000000000000000000000000000BE +:1052F00000000000000000000000000000000000AE +:10530000000000000000000000000000000000009D +:10531000000000000000000000000000000000008D +:10532000000000000000000000000000000000007D +:10533000000000000000000000000000000000006D +:10534000000000000000000000000000000000005D +:10535000000000000000000000000000000000004D +:10536000000000000000000000000000000000003D +:10537000000000000000000000000000000000002D +:10538000000000000000000000000000000000001D +:10539000000000000000000000000000000000000D +:1053A00000000000000000000000000000000000FD +:1053B00000000000000000000000000000000000ED +:1053C00000000000000000000000000000000000DD +:1053D00000000000000000000000000000000000CD +:1053E00000000000000000000000000000000000BD +:1053F00000000000000000000000000000000000AD +:10540000000000000000000000000000000000009C +:10541000000000000000000000000000000000008C +:10542000000000000000000000000000000000007C +:10543000000000000000000000000000000000006C +:10544000000000000000000000000000000000005C +:10545000000000000000000000000000000000004C +:10546000000000000000000000000000000000003C +:10547000000000000000000000000000000000002C +:10548000000000000000000000000000000000001C +:10549000000000000000000000000000000000000C +:1054A00000000000000000000000000000000000FC +:1054B00000000000000000000000000000000000EC +:1054C00000000000000000000000000000000000DC +:1054D00000000000000000000000000000000000CC +:1054E00000000000000000000000000000000000BC +:1054F00000000000000000000000000000000000AC +:10550000000000000000000000000000000000009B +:10551000000000000000000000000000000000008B +:10552000000000000000000000000000000000007B +:10553000000000000000000000000000000000006B +:10554000000000000000000000000000000000005B +:10555000000000000000000000000000000000004B +:10556000000000000000000000000000000000003B +:10557000000000000000000000000000000000002B +:10558000000000000000000000000000000000001B +:10559000000000000000000000000000000000000B +:1055A00000000000000000000000000000000000FB +:1055B00000000000000000000000000000000000EB +:1055C00000000000000000000000000000000000DB +:1055D00000000000000000000000000000000000CB +:1055E00000000000000000000000000000000000BB +:1055F00000000000000000000000000000000000AB +:10560000000000000000000000000000000000009A +:10561000000000000000000000000000000000008A +:10562000000000000000000000000000000000007A +:10563000000000000000000000000000000000006A +:10564000000000000000000000000000000000005A +:10565000000000000000000000000000000000004A +:10566000000000000000000000000000000000003A +:10567000000000000000000000000000000000002A +:10568000000000000000000000000000000000001A +:10569000000000000000000000000000000000000A +:1056A00000000000000000000000000000000000FA +:1056B00000000000000000000000000000000000EA +:1056C00000000000000000000000000000000000DA +:1056D00000000000000000000000000000000000CA +:1056E00000000000000000000000000000000000BA +:1056F00000000000000000000000000000000000AA +:105700000000000000000000000000000000000099 +:105710000000000000000000000000000000000089 +:105720000000000000000000000000000000000079 +:105730000000000000000000000000000000000069 +:105740000000000000000000000000000000000059 +:105750000000000000000000000000000000000049 +:105760000000000000000000000000000000000039 +:105770000000000000000000000000000000000029 +:105780000000000000000000000000000000000019 +:105790000000000000000000000000000000000009 +:1057A00000000000000000000000000000000000F9 +:1057B00000000000000000000000000000000000E9 +:1057C00000000000000000000000000000000000D9 +:1057D00000000000000000000000000000000000C9 +:1057E00000000000000000000000000000000000B9 +:1057F00000000000000000000000000000000000A9 +:105800000000000000000000000000000000000098 +:105810000000000000000000000000000000000088 +:105820000000000000000000000000000000000078 +:105830000000000000000000000000000000000068 +:105840000000000000000000000000000000000058 +:105850000000000000000000000000000000000048 +:105860000000000000000000000000000000000038 +:105870000000000000000000000000000000000028 +:105880000000000000000000000000000000000018 +:105890000000000000000000000000000000000008 +:1058A00000000000000000000000000000000000F8 +:1058B00000000000000000000000000000000000E8 +:1058C00000000000000000000000000000000000D8 +:1058D00000000000000000000000000000000000C8 +:1058E00000000000000000000000000000000000B8 +:1058F00000000000000000000000000000000000A8 +:105900000000000000000000000000000000000097 +:105910000000000000000000000000000000000087 +:105920000000000000000000000000000000000077 +:105930000000000000000000000000000000000067 +:105940000000000000000000000000000000000057 +:105950000000000000000000000000000000000047 +:105960000000000000000000000000000000000037 +:105970000000000000000000000000000000000027 +:105980000000000000000000000000000000000017 +:105990000000000000000000000000000000000007 +:1059A00000000000000000000000000000000000F7 +:1059B00000000000000000000000000000000000E7 +:1059C00000000000000000000000000000000000D7 +:1059D00000000000000000000000000000000000C7 +:1059E00000000000000000000000000000000000B7 +:1059F00000000000000000000000000000000000A7 +:105A00000000000000000000000000000000000096 +:105A10000000000000000000000000000000000086 +:105A20000000000000000000000000000000000076 +:105A30000000000000000000000000000000000066 +:105A40000000000000000000000000000000000056 +:105A50000000000000000000000000000000000046 +:105A60000000000000000000000000000000000036 +:105A70000000000000000000000000000000000026 +:105A80000000000000000000000000000000000016 +:105A90000000000000000000000000000000000006 +:105AA00000000000000000000000000000000000F6 +:105AB00000000000000000000000000000000000E6 +:105AC00000000000000000000000000000000000D6 +:105AD00000000000000000000000000000000000C6 +:105AE00000000000000000000000000000000000B6 +:105AF00000000000000000000000000000000000A6 +:105B00000000000000000000000000000000000095 +:105B10000000000000000000000000000000000085 +:105B20000000000000000000000000000000000075 +:105B30000000000000000000000000000000000065 +:105B40000000000000000000000000000000000055 +:105B50000000000000000000000000000000000045 +:105B60000000000000000000000000000000000035 +:105B70000000000000000000000000000000000025 +:105B80000000000000000000000000000000000015 +:105B90000000000000000000000000000000000005 +:105BA00000000000000000000000000000000000F5 +:105BB00000000000000000000000000000000000E5 +:105BC00000000000000000000000000000000000D5 +:105BD00000000000000000000000000000000000C5 +:105BE00000000000000000000000000000000000B5 +:105BF00000000000000000000000000000000000A5 +:105C00000000000000000000000000000000000094 +:105C10000000000000000000000000000000000084 +:105C20000000000000000000000000000000000074 +:105C30000000000000000000000000000000000064 +:105C40000000000000000000000000000000000054 +:105C50000000000000000000000000000000000044 +:105C60000000000000000000000000000000000034 +:105C70000000000000000000000000000000000024 +:105C80000000000000000000000000000000000014 +:105C90000000000000000000000000000000000004 +:105CA00000000000000000000000000000000000F4 +:105CB00000000000000000000000000000000000E4 +:105CC00000000000000000000000000000000000D4 +:105CD00000000000000000000000000000000000C4 +:105CE00000000000000000000000000000000000B4 +:105CF00000000000000000000000000000000000A4 +:105D00000000000000000000000000000000000093 +:105D10000000000000000000000000000000000083 +:105D20000000000000000000000000000000000073 +:105D30000000000000000000000000000000000063 +:105D40000000000000000000000000000000000053 +:105D50000000000000000000000000000000000043 +:105D60000000000000000000000000000000000033 +:105D70000000000000000000000000000000000023 +:105D80000000000000000000000000000000000013 +:105D90000000000000000000000000000000000003 +:105DA00000000000000000000000000000000000F3 +:105DB00000000000000000000000000000000000E3 +:105DC00000000000000000000000000000000000D3 +:105DD00000000000000000000000000000000000C3 +:105DE00000000000000000000000000000000000B3 +:105DF00000000000000000000000000000000000A3 +:105E00000000000000000000000000000000000092 +:105E10000000000000000000000000000000000082 +:105E20000000000000000000000000000000000072 +:105E30000000000000000000000000000000000062 +:105E40000000000000000000000000000000000052 +:105E50000000000000000000000000000000000042 +:105E60000000000000000000000000000000000032 +:105E70000000000000000000000000000000000022 +:105E80000000000000000000000000000000000012 +:105E90000000000000000000000000000000000002 +:105EA00000000000000000000000000000000000F2 +:105EB00000000000000000000000000000000000E2 +:105EC00000000000000000000000000000000000D2 +:105ED00000000000000000000000000000000000C2 +:105EE00000000000000000000000000000000000B2 +:105EF00000000000000000000000000000000000A2 +:105F00000000000000000000000000000000000091 +:105F10000000000000000000000000000000000081 +:105F20000000000000000000000000000000000071 +:105F30000000000000000000000000000000000061 +:105F40000000000000000000000000000000000051 +:105F50000000000000000000000000000000000041 +:105F60000000000000000000000000000000000031 +:105F70000000000000000000000000000000000021 +:105F80000000000000000000000000000000000011 +:105F90000000000000000000000000000000000001 +:105FA00000000000000000000000000000000000F1 +:105FB00000000000000000000000000000000000E1 +:105FC00000000000000000000000000000000000D1 +:105FD00000000000000000000000000000000000C1 +:105FE00000000000000000000000000000000000B1 +:105FF00000000000000000000000000000000000A1 +:106000000000000000000000000000000000000090 +:106010000000000000000000000000000000000080 +:106020000000000000000000000000000000000070 +:106030000000000000000000000000000000000060 +:106040000000000000000000000000000000000050 +:106050000000000000000000000000000000000040 +:106060000000000000000000000000000000000030 +:106070000000000000000000000000000000000020 +:106080000000000000000000000000000000000010 +:106090000000000000000000000000000000000000 +:1060A00000000000000000000000000000000000F0 +:1060B00000000000000000000000000000000000E0 +:1060C00000000000000000000000000000000000D0 +:1060D00000000000000000000000000000000000C0 +:1060E00000000000000000000000000000000000B0 +:1060F00000000000000000000000000000000000A0 +:10610000000000000000000000000000000000008F +:10611000000000000000000000000000000000007F +:10612000000000000000000000000000000000006F +:10613000000000000000000000000000000000005F +:10614000000000000000000000000000000000004F +:10615000000000000000000000000000000000003F +:10616000000000000000000000000000000000002F +:10617000000000000000000000000000000000001F +:10618000000000000000000000000000000000000F +:1061900000000000000000000000000000000000FF +:1061A00000000000000000000000000000000000EF +:1061B00000000000000000000000000000000000DF +:1061C00000000000000000000000000000000000CF +:1061D00000000000000000000000000000000000BF +:1061E00000000000000000000000000000000000AF +:1061F000000000000000000000000000000000009F +:10620000000000000000000000000000000000008E +:10621000000000000000000000000000000000007E +:10622000000000000000000000000000000000006E +:10623000000000000000000000000000000000005E +:10624000000000000000000000000000000000004E +:10625000000000000000000000000000000000003E +:10626000000000000000000000000000000000002E +:10627000000000000000000000000000000000001E +:10628000000000000000000000000000000000000E +:1062900000000000000000000000000000000000FE +:1062A00000000000000000000000000000000000EE +:1062B00000000000000000000000000000000000DE +:1062C00000000000000000000000000000000000CE +:1062D00000000000000000000000000000000000BE +:1062E00000000000000000000000000000000000AE +:1062F000000000000000000000000000000000009E +:10630000000000000000000000000000000000008D +:10631000000000000000000000000000000000007D +:10632000000000000000000000000000000000006D +:10633000000000000000000000000000000000005D +:10634000000000000000000000000000000000004D +:10635000000000000000000000000000000000003D +:10636000000000000000000000000000000000002D +:10637000000000000000000000000000000000001D +:10638000000000000000000000000000000000000D +:1063900000000000000000000000000000000000FD +:1063A00000000000000000000000000000000000ED +:1063B00000000000000000000000000000000000DD +:1063C00000000000000000000000000000000000CD +:1063D00000000000000000000000000000000000BD +:1063E00000000000000000000000000000000000AD +:1063F000000000000000000000000000000000009D +:10640000000000000000000000000000000000008C +:10641000000000000000000000000000000000007C +:10642000000000000000000000000000000000006C +:10643000000000000000000000000000000000005C +:10644000000000000000000000000000000000004C +:10645000000000000000000000000000000000003C +:10646000000000000000000000000000000000002C +:10647000000000000000000000000000000000001C +:10648000000000000000000000000000000000000C +:1064900000000000000000000000000000000000FC +:1064A00000000000000000000000000000000000EC +:1064B00000000000000000000000000000000000DC +:1064C00000000000000000000000000000000000CC +:1064D00000000000000000000000000000000000BC +:1064E00000000000000000000000000000000000AC +:1064F000000000000000000000000000000000009C +:10650000000000000000000000000000000000008B +:10651000000000000000000000000000000000007B +:10652000000000000000000000000000000000006B +:10653000000000000000000000000000000000005B +:10654000000000000000000000000000000000004B +:10655000000000000000000000000000000000003B +:10656000000000000000000000000000000000002B +:10657000000000000000000000000000000000001B +:10658000000000000000000000000000000000000B +:1065900000000000000000000000000000000000FB +:1065A00000000000000000000000000000000000EB +:1065B00000000000000000000000000000000000DB +:1065C00000000000000000000000000000000000CB +:1065D00000000000000000000000000000000000BB +:1065E00000000000000000000000000000000000AB +:1065F000000000000000000000000000000000009B +:10660000000000000000000000000000000000008A +:10661000000000000000000000000000000000007A +:10662000000000000000000000000000000000006A +:10663000000000000000000000000000000000005A +:10664000000000000000000000000000000000004A +:10665000000000000000000000000000000000003A +:10666000000000000000000000000000000000002A +:10667000000000000000000000000000000000001A +:10668000000000000000000000000000000000000A +:1066900000000000000000000000000000000000FA +:1066A00000000000000000000000000000000000EA +:1066B00000000000000000000000000000000000DA +:1066C00000000000000000000000000000000000CA +:1066D00000000000000000000000000000000000BA +:1066E00000000000000000000000000000000000AA +:1066F000000000000000000000000000000000009A +:106700000000000000000000000000000000000089 +:106710000000000000000000000000000000000079 +:106720000000000000000000000000000000000069 +:106730000000000000000000000000000000000059 +:106740000000000000000000000000000000000049 +:106750000000000000000000000000000000000039 +:106760000000000000000000000000000000000029 +:106770000000000000000000000000000000000019 +:106780000000000000000000000000000000000009 +:1067900000000000000000000000000000000000F9 +:1067A00000000000000000000000000000000000E9 +:1067B00000000000000000000000000000000000D9 +:1067C00000000000000000000000000000000000C9 +:1067D00000000000000000000000000000000000B9 +:1067E00000000000000000000000000000000000A9 +:1067F0000000000000000000000000000000000099 +:106800000000000000000000000000000000000088 +:106810000000000000000000000000000000000078 +:106820000000000000000000000000000000000068 +:106830000000000000000000000000000000000058 +:106840000000000000000000000000000000000048 +:106850000000000000000000000000000000000038 +:106860000000000000000000000000000000000028 +:106870000000000000000000000000000000000018 +:106880000000000000000000000000000000000008 +:1068900000000000000000000000000000000000F8 +:1068A00000000000000000000000000000000000E8 +:1068B00000000000000000000000000000000000D8 +:1068C00000000000000000000000000000000000C8 +:1068D00000000000000000000000000000000000B8 +:1068E00000000000000000000000000000000000A8 +:1068F0000000000000000000000000000000000098 +:106900000000000000000000000000000000000087 +:106910000000000000000000000000000000000077 +:106920000000000000000000000000000000000067 +:106930000000000000000000000000000000000057 +:106940000000000000000000000000000000000047 +:106950000000000000000000000000000000000037 +:106960000000000000000000000000000000000027 +:106970000000000000000000000000000000000017 +:106980000000000000000000000000000000000007 +:1069900000000000000000000000000000000000F7 +:1069A00000000000000000000000000000000000E7 +:1069B00000000000000000000000000000000000D7 +:1069C00000000000000000000000000000000000C7 +:1069D00000000000000000000000000000000000B7 +:1069E00000000000000000000000000000000000A7 +:1069F0000000000000000000000000000000000097 +:106A00000000000000000000000000000000000086 +:106A10000000000000000000000000000000000076 +:106A20000000000000000000000000000000000066 +:106A30000000000000000000000000000000000056 +:106A40000000000000000000000000000000000046 +:106A50000000000000000000000000000000000036 +:106A60000000000000000000000000000000000026 +:106A70000000000000000000000000000000000016 +:106A80000000000000000000000000000000000006 +:106A900000000000000000000000000000000000F6 +:106AA00000000000000000000000000000000000E6 +:106AB00000000000000000000000000000000000D6 +:106AC00000000000000000000000000000000000C6 +:106AD00000000000000000000000000000000000B6 +:106AE00000000000000000000000000000000000A6 +:106AF0000000000000000000000000000000000096 +:106B00000000000000000000000000000000000085 +:106B10000000000000000000000000000000000075 +:106B20000000000000000000000000000000000065 +:106B30000000000000000000000000000000000055 +:106B40000000000000000000000000000000000045 +:106B50000000000000000000000000000000000035 +:106B60000000000000000000000000000000000025 +:106B70000000000000000000000000000000000015 +:106B80000000000000000000000000000000000005 +:106B900000000000000000000000000000000000F5 +:106BA00000000000000000000000000000000000E5 +:106BB00000000000000000000000000000000000D5 +:106BC00000000000000000000000000000000000C5 +:106BD00000000000000000000000000000000000B5 +:106BE00000000000000000000000000000000000A5 +:106BF0000000000000000000000000000000000095 +:106C00000000000000000000000000000000000084 +:106C10000000000000000000000000000000000074 +:106C20000000000000000000000000000000000064 +:106C30000000000000000000000000000000000054 +:106C40000000000000000000000000000000000044 +:106C50000000000000000000000000000000000034 +:106C60000000000000000000000000000000000024 +:106C70000000000000000000000000000000000014 +:106C80000000000000000000000000000000000004 +:106C900000000000000000000000000000000000F4 +:106CA00000000000000000000000000000000000E4 +:106CB00000000000000000000000000000000000D4 +:106CC00000000000000000000000000000000000C4 +:106CD00000000000000000000000000000000000B4 +:106CE00000000000000000000000000000000000A4 +:106CF0000000000000000000000000000000000094 +:106D00000000000000000000000000000000000083 +:106D10000000000000000000000000000000000073 +:106D20000000000000000000000000000000000063 +:106D30000000000000000000000000000000000053 +:106D40000000000000000000000000000000000043 +:106D50000000000000000000000000000000000033 +:106D60000000000000000000000000000000000023 +:106D70000000000000000000000000000000000013 +:106D80000000000000000000000000000000000003 +:106D900000000000000000000000000000000000F3 +:106DA00000000000000000000000000000000000E3 +:106DB00000000000000000000000000000000000D3 +:106DC00000000000000000000000000000000000C3 +:106DD00000000000000000000000000000000000B3 +:106DE00000000000000000000000000000000000A3 +:106DF0000000000000000000000000000000000093 +:106E00000000000000000000000000000000000082 +:106E10000000000000000000000000000000000072 +:106E20000000000000000000000000000000000062 +:106E30000000000000000000000000000000000052 +:106E40000000000000000000000000000000000042 +:106E50000000000000000000000000000000000032 +:106E60000000000000000000000000000000000022 +:106E70000000000000000000000000000000000012 +:106E80000000000000000000000000000000000002 +:106E900000000000000000000000000000000000F2 +:106EA00000000000000000000000000000000000E2 +:106EB00000000000000000000000000000000000D2 +:106EC00000000000000000000000000000000000C2 +:106ED00000000000000000000000000000000000B2 +:106EE00000000000000000000000000000000000A2 +:106EF0000000000000000000000000000000000092 +:106F00000000000000000000000000000000000081 +:106F10000000000000000000000000000000000071 +:106F20000000000000000000000000000000000061 +:106F30000000000000000000000000000000000051 +:106F40000000000000000000000000000000000041 +:106F50000000000000000000000000000000000031 +:106F60000000000000000000000000000000000021 +:106F70000000000000000000000000000000000011 +:106F80000000000000000000000000000000000001 +:106F900000000000000000000000000000000000F1 +:106FA00000000000000000000000000000000000E1 +:106FB00000000000000000000000000000000000D1 +:106FC00000000000000000000000000000000000C1 +:106FD00000000000000000000000000000000000B1 +:106FE00000000000000000000000000000000000A1 +:106FF0000000000000000000000000000000000091 +:107000000000000000000000000000000000000080 +:107010000000000000000000000000000000000070 +:107020000000000000000000000000000000000060 +:107030000000000000000000000000000000000050 +:107040000000000000000000000000000000000040 +:107050000000000000000000000000000000000030 +:107060000000000000000000000000000000000020 +:107070000000000000000000000000000000000010 +:107080000000000000000000000000000000000000 +:1070900000000000000000000000000000000000F0 +:1070A00000000000000000000000000000000000E0 +:1070B00000000000000000000000000000000000D0 +:1070C00000000000000000000000000000000000C0 +:1070D00000000000000000000000000000000000B0 +:1070E00000000000000000000000000000000000A0 +:1070F0000000000000000000000000000000000090 +:10710000000000000000000000000000000000007F +:10711000000000000000000000000000000000006F +:10712000000000000000000000000000000000005F +:10713000000000000000000000000000000000004F +:10714000000000000000000000000000000000003F +:10715000000000000000000000000000000000002F +:10716000000000000000000000000000000000001F +:10717000000000000000000000000000000000000F +:1071800000000000000000000000000000000000FF +:1071900000000000000000000000000000000000EF +:1071A00000000000000000000000000000000000DF +:1071B00000000000000000000000000000000000CF +:1071C00000000000000000000000000000000000BF +:1071D00000000000000000000000000000000000AF +:1071E000000000000000000000000000000000009F +:1071F000000000000000000000000000000000008F +:10720000000000000000000000000000000000007E +:10721000000000000000000000000000000000006E +:10722000000000000000000000000000000000005E +:10723000000000000000000000000000000000004E +:10724000000000000000000000000000000000003E +:10725000000000000000000000000000000000002E +:10726000000000000000000000000000000000001E +:10727000000000000000000000000000000000000E +:1072800000000000000000000000000000000000FE +:1072900000000000000000000000000000000000EE +:1072A00000000000000000000000000000000000DE +:1072B00000000000000000000000000000000000CE +:1072C00000000000000000000000000000000000BE +:1072D00000000000000000000000000000000000AE +:1072E000000000000000000000000000000000009E +:1072F000000000000000000000000000000000008E +:10730000000000000000000000000000000000007D +:10731000000000000000000000000000000000006D +:10732000000000000000000000000000000000005D +:10733000000000000000000000000000000000004D +:10734000000000000000000000000000000000003D +:10735000000000000000000000000000000000002D +:10736000000000000000000000000000000000001D +:10737000000000000000000000000000000000000D +:1073800000000000000000000000000000000000FD +:1073900000000000000000000000000000000000ED +:1073A00000000000000000000000000000000000DD +:1073B00000000000000000000000000000000000CD +:1073C00000000000000000000000000000000000BD +:1073D00000000000000000000000000000000000AD +:1073E000000000000000000000000000000000009D +:1073F000000000000000000000000000000000008D +:10740000000000000000000000000000000000007C +:10741000000000000000000000000000000000006C +:10742000000000000000000000000000000000005C +:10743000000000000000000000000000000000004C +:10744000000000000000000000000000000000003C +:10745000000000000000000000000000000000002C +:10746000000000000000000000000000000000001C +:10747000000000000000000000000000000000000C +:1074800000000000000000000000000000000000FC +:1074900000000000000000000000000000000000EC +:1074A00000000000000000000000000000000000DC +:1074B00000000000000000000000000000000000CC +:1074C00000000000000000000000000000000000BC +:1074D00000000000000000000000000000000000AC +:1074E000000000000000000000000000000000009C +:1074F000000000000000000000000000000000008C +:10750000000000000000000000000000000000007B +:10751000000000000000000000000000000000006B +:10752000000000000000000000000000000000005B +:10753000000000000000000000000000000000004B +:10754000000000000000000000000000000000003B +:10755000000000000000000000000000000000002B +:10756000000000000000000000000000000000001B +:10757000000000000000000000000000000000000B +:1075800000000000000000000000000000000000FB +:1075900000000000000000000000000000000000EB +:1075A00000000000000000000000000000000000DB +:1075B00000000000000000000000000000000000CB +:1075C00000000000000000000000000000000000BB +:1075D00000000000000000000000000000000000AB +:1075E000000000000000000000000000000000009B +:1075F000000000000000000000000000000000008B +:10760000000000000000000000000000000000007A +:10761000000000000000000000000000000000006A +:10762000000000000000000000000000000000005A +:10763000000000000000000000000000000000004A +:10764000000000000000000000000000000000003A +:10765000000000000000000000000000000000002A +:10766000000000000000000000000000000000001A +:10767000000000000000000000000000000000000A +:1076800000000000000000000000000000000000FA +:1076900000000000000000000000000000000000EA +:1076A00000000000000000000000000000000000DA +:1076B00000000000000000000000000000000000CA +:1076C00000000000000000000000000000000000BA +:1076D00000000000000000000000000000000000AA +:1076E000000000000000000000000000000000009A +:1076F000000000000000000000000000000000008A +:107700000000000000000000000000000000000079 +:107710000000000000000000000000000000000069 +:107720000000000000000000000000000000000059 +:107730000000000000000000000000000000000049 +:107740000000000000000000000000000000000039 +:107750000000000000000000000000000000000029 +:107760000000000000000000000000000000000019 +:107770000000000000000000000000000000000009 +:1077800000000000000000000000000000000000F9 +:1077900000000000000000000000000000000000E9 +:1077A00000000000000000000000000000000000D9 +:1077B00000000000000000000000000000000000C9 +:1077C00000000000000000000000000000000000B9 +:1077D00000000000000000000000000000000000A9 +:1077E0000000000000000000000000000000000099 +:1077F0000000000000000000000000000000000089 +:107800000000000000000000000000000000000078 +:107810000000000000000000000000000000000068 +:107820000000000000000000000000000000000058 +:107830000000000000000000000000000000000048 +:107840000000000000000000000000000000000038 +:107850000000000000000000000000000000000028 +:107860000000000000000000000000000000000018 +:107870000000000000000000000000000000000008 +:1078800000000000000000000000000000000000F8 +:1078900000000000000000000000000000000000E8 +:1078A00000000000000000000000000000000000D8 +:1078B00000000000000000000000000000000000C8 +:1078C00000000000000000000000000000000000B8 +:1078D00000000000000000000000000000000000A8 +:1078E0000000000000000000000000000000000098 +:1078F0000000000000000000000000000000000088 +:107900000000000000000000000000000000000077 +:107910000000000000000000000000000000000067 +:107920000000000000000000000000000000000057 +:107930000000000000000000000000000000000047 +:107940000000000000000000000000000000000037 +:107950000000000000000000000000000000000027 +:107960000000000000000000000000000000000017 +:107970000000000000000000000000000000000007 +:1079800000000000000000000000000000000000F7 +:1079900000000000000000000000000000000000E7 +:1079A00000000000000000000000000000000000D7 +:1079B00000000000000000000000000000000000C7 +:1079C00000000000000000000000000000000000B7 +:1079D00000000000000000000000000000000000A7 +:1079E0000000000000000000000000000000000097 +:1079F0000000000000000000000000000000000087 +:107A00000000000000000000000000000000000076 +:107A10000000000000000000000000000000000066 +:107A20000000000000000000000000000000000056 +:107A30000000000000000000000000000000000046 +:107A40000000000000000000000000000000000036 +:107A50000000000000000000000000000000000026 +:107A60000000000000000000000000000000000016 +:107A70000000000000000000000000000000000006 +:107A800000000000000000000000000000000000F6 +:107A900000000000000000000000000000000000E6 +:107AA00000000000000000000000000000000000D6 +:107AB00000000000000000000000000000000000C6 +:107AC00000000000000000000000000000000000B6 +:107AD00000000000000000000000000000000000A6 +:107AE0000000000000000000000000000000000096 +:107AF0000000000000000000000000000000000086 +:107B00000000000000000000000000000000000075 +:107B10000000000000000000000000000000000065 +:107B20000000000000000000000000000000000055 +:107B30000000000000000000000000000000000045 +:107B40000000000000000000000000000000000035 +:107B50000000000000000000000000000000000025 +:107B60000000000000000000000000000000000015 +:107B70000000000000000000000000000000000005 +:107B800000000000000000000000000000000000F5 +:107B900000000000000000000000000000000000E5 +:107BA00000000000000000000000000000000000D5 +:107BB00000000000000000000000000000000000C5 +:107BC00000000000000000000000000000000000B5 +:107BD00000000000000000000000000000000000A5 +:107BE0000000000000000000000000000000000095 +:107BF0000000000000000000000000000000000085 +:107C00000000000000000000000000000000000074 +:107C10000000000000000000000000000000000064 +:107C20000000000000000000000000000000000054 +:107C30000000000000000000000000000000000044 +:107C40000000000000000000000000000000000034 +:107C50000000000000000000000000000000000024 +:107C60000000000000000000000000000000000014 +:107C70000000000000000000000000000000000004 +:107C800000000000000000000000000000000000F4 +:107C900000000000000000000000000000000000E4 +:107CA00000000000000000000000000000000000D4 +:107CB00000000000000000000000000000000000C4 +:107CC00000000000000000000000000000000000B4 +:107CD00000000000000000000000000000000000A4 +:107CE0000000000000000000000000000000000094 +:107CF0000000000000000000000000000000000084 +:107D00000000000000000000000000000000000073 +:107D10000000000000000000000000000000000063 +:107D20000000000000000000000000000000000053 +:107D30000000000000000000000000000000000043 +:107D40000000000000000000000000000000000033 +:107D50000000000000000000000000000000000023 +:107D60000000000000000000000000000000000013 +:107D70000000000000000000000000000000000003 +:107D800000000000000000000000000000000000F3 +:107D900000000000000000000000000000000000E3 +:107DA00000000000000000000000000000000000D3 +:107DB00000000000000000000000000000000000C3 +:107DC00000000000000000000000000000000000B3 +:107DD00000000000000000000000000000000000A3 +:107DE0000000000000000000000000000000000093 +:107DF0000000000000000000000000000000000083 +:107E00000000000000000000000000000000000072 +:107E10000000000000000000000000000000000062 +:107E20000000000000000000000000000000000052 +:107E30000000000000000000000000000000000042 +:107E40000000000000000000000000000000000032 +:107E50000000000000000000000000000000000022 +:107E60000000000000000000000000000000000012 +:107E70000000000000000000000000000000000002 +:107E800000000000000000000000000000000000F2 +:107E900000000000000000000000000000000000E2 +:107EA00000000000000000000000000000000000D2 +:107EB00000000000000000000000000000000000C2 +:107EC00000000000000000000000000000000000B2 +:107ED00000000000000000000000000000000000A2 +:107EE0000000000000000000000000000000000092 +:107EF0000000000000000000000000000000000082 +:107F00000000000000000000000000000000000071 +:107F10000000000000000000000000000000000061 +:107F20000000000000000000000000000000000051 +:107F30000000000000000000000000000000000041 +:107F40000000000000000000000000000000000031 +:107F50000000000000000000000000000000000021 +:107F60000000000000000000000000000000000011 +:107F70000000000000000000000000000000000001 +:107F800000000000000000000000000000000000F1 +:107F900000000000000000000000000000000000E1 +:107FA00000000000000000000000000000000000D1 +:107FB00000000000000000000000000000000000C1 +:107FC00000000000000000000000000000000000B1 +:107FD00000000000000000000000000000000000A1 +:107FE0000000000000000000000000000000000091 +:107FF0000000000000000000000000000000000081 +:108000000000000000000000000000000000000070 +:108010000000000000000000000000000000000060 +:108020000000000000000000000000000000000050 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:1080800000000000000000000000000000000000F0 +:1080900000000000000000000000000000000000E0 +:1080A00000000000000000000000000000000000D0 +:1080B00000000000000000000000000000000000C0 +:1080C00000000000000000000000000000000000B0 +:1080D00000000000000000000000000000000000A0 +:1080E0000000000000000000000000000000000090 +:1080F0000000000000000000000000000000000080 +:1081000006F0F15506F0F15506F0F15506F0F1557F +:108110001616161616161616151616161615151602 +:1081200016161516161615151616151616161616F3 +:1081300016161717161616161616161616151515E0 +:1081400016151516161616161616161616161515D3 +:1081500016161616161617161615151516161615C2 +:1081600015151616161615161616151515151516B7 +:1081700015151515161615161616161615151516A7 +:108180001516161515151616161616161716161692 +:108190001516161616161515161516151516161685 +:1081A0001516161616161616161616161616161670 +:1081B0001716151616161516161616151616161661 +:1081C0001616161616161616151616161516161552 +:1081D0001616161616161516161616161516151543 +:1081E0001515161516161616161616161616161632 +:1081F0001516161616161616161716161615151522 +:108200001515151616161616161616171615161611 +:108210001616151615161616161616161717151500 +:1082200015161616151515171616161616161717EF +:1082300016151615161615161616161616161616E1 +:1082400017171616151616151615151716161616CF +:1082500016161716161616161616161616151515C0 +:1082600016161516161616161616161616161615B0 +:1082700015151515161516151616161616161616A4 +:108280001615151515151515151516161616161598 +:108290001616161515151615161515151615161686 +:1082A0001616161616161515161516151515161674 +:1082B0001616161616161615151515151515151567 +:1082C0001616161616161616161515151516161553 +:1082D0001515161616161615161616151515151546 +:1082E0001515161516151616161616161615151535 +:1082F0001515151515161616161616161616161524 +:10830000151515151515151616151515151515151B +:108310001515151515151515151616161516161607 +:1083200016161616151515151615161616161516F3 +:1083300016151616161515151515151515151615E8 +:1083400016161616161616151516151515151615D4 +:1083500016161616161616161616151515151515C3 +:1083600015151616161616161616161615151515B3 +:1083700016151516161615161616161616151515A3 +:108380001515151515161616151616161516151695 +:10839000151616151616161616161616161616167F +:1083A0001515161515151616161616161616161672 +:1083B000161616161616161616161716161616165C +:1083C0001616161616151615161516151616161651 +:1083D000161616161616151616161616161616163E +:1083E0001616161516161616151516161516161631 +:1083F0001616151515151515151515151616161627 +:108400001616161616151616151515151515151614 +:1084100016161616161616161616161616161516FD +:1084200015161515151616161616161616161616F0 +:1084300016161616161616161617161616161616DB +:1084400016161616161616161616161616161616CC +:1084500016161616161616161616161616161616BC +:1084600015161616151616151616161616161616AF +:10847000161616161616161616161616161616169C +:10848000161715161616161615151616161616168E +:10849000161616171616161616161616161616167B +:1084A000161616161616161615161616161616166D +:1084B000161716161616171716151516161616165B +:1084C000161616161616161616171616161616164B +:1084D0001616161716161616161616161717161639 +:1084E000161616161615151515151616161617172F +:1084F0001616161616161615151515161615151523 +:108500001716161616161616161515151515151511 +:108510001515151616161616161516151515161503 +:1085200015151515151616151616161516151515F5 +:1085300016151615151516161616161616161615E0 +:1085400015151515151515161516161616161616D3 +:1085500016151515151515151516161616161616C3 +:1085600015161615151515151515151616161616B4 +:1085700016161616161515151515151515151616A4 +:108580001616161616161615151515151515151594 +:108590001616151515151515151515151515151589 +:1085A0001516161615161616161616151515151572 +:1085B0001615151516161616161616161615151561 +:1085C0001515151515151615161616161616161553 +:1085D0001516151515151615161616161616161641 +:1085E0001616151615151515161616161616161630 +:1085F000161616161616151516151516161616161F +:108600001615161616151515151615151515151614 +:1086100016161716151616161616161615161616FB +:108620001A1A1A1A1A1B1A1A1B1B1B191A1A1A19A8 +:1086300019191A1A1A1A1A1A1A1B1B1A1A1A1A1A9A +:108640001A1A1A19191A1A1A1A1B1B1B1B1A1A1A88 +:108650001A191A191919191A1A1A1A1A1A1A1A1B7E +:108660001B1B1B1A1A1A1A1A191A1A1A1A1A1A1A68 +:108670001A1A1B1A1A1A1A1A1A19191A191A191A5D +:108680001A1A1A1B1B1A1A1A1A1A1A1A19191A1A4A +:10869000191A1A1A1A1B1B1A1A1A1A191A1A1A1A3A +:1086A000191A1A1A1A1A1B1A1A1A1A1A1A1A1A1A2A +:1086B0001A1A1A1B1A1A1A1B1B1B1C1B1B1B1B1A10 +:1086C0001A1A1A1A1A1A191A1A1A1B1B1B1A1A1A08 +:1086D0001A1A19191A1A1A1A1A1A1A1B1B1B1B1BF7 +:1086E0001B1B1B1A1A191A1A1A1A1B1A1A1B1B1BE4 +:1086F0001B1B1A1B1A1A19181A1A1A1B1A1A1A1BD8 +:108700001B1C1B1B1B1B1B1A1A191A1A1A1A1A1AC2 +:108710001A1B1B1C1C1B1B1B1B1B1A1A1A1A1A1AAE +:108720001A1A1B1B1B1C1B1B1B1B1B1A1A1A1A1A9F +:108730001A1A1B1B1A1B1B1C1C1C1C1B1B1B1A1A8A +:108740001B1A1A1A1A1B1B1B1B1C1C1B1B1B1B1A7C +:108750001B1B1A1A1A1A1B1A1B1B1B1D1B1B1B1B6C +:108760001B1A1B1A1A1A1A1B1B1C1C1B1C1A1A1A5E +:108770001A1A1A1919191A1A1A1B1B1C1B1C1C1A53 +:108780001A1A191A1A1A19191A1A1B1B1B1B1B1B46 +:108790001B1A1A1A1A1A1A1919191A1A1A1A1B1A3A +:1087A0001B1B1B1A1A1A1A191A1919191A1A1A1B29 +:1087B0001B1B1B1B1C1B1A1A1A1A1A1A19191A1A14 +:1087C0001B1B1B1B1B1C1C1A1A1A1A1A1A1A191902 +:1087D0001A1A1B1B1B1B1B1B1B1B1A1A1A1A1A1AF1 +:1087E000191A1B1A1A1B1B1B1B1B1C1A1B1A1A1AE1 +:1087F0001A1A1A191B1B1B1B1C1C1C1C1C1A1A1ACC +:108800001A1A1A1919191C1B1B1B1B1C1B1C1C1BBD +:108810001A1A1A1A1A1919191B1B1B1B1B1B1B1BB3 +:108820001C1B1B1B1A1A1A1A1A1A1B1B1B1B1B1C9C +:108830001C1C1C1B1B1B1B1B1B1A1A1A1B1A1B1B89 +:108840001B1B1B1B1C1B1B1B1B1B1A1A1A191B1A7D +:108850001B1C1B1B1C1C1C1B1B1B1B1A1A1B1A1969 +:108860001B1B1B1C1C1C1C1C1C1C1B1B1B1A1B1A53 +:108870001A1A1A1B1B1C1C1C1C1C1C1C1B1B1B1A45 +:108880001B1A191A1B1A1B1B1B1B1C1C1C1C1B1B39 +:108890001B1A1A1A1A1B1A1B1A1B1C1B1B1C1C1C2A +:1088A0001C1B1A1B1B1A1A1A1B1B1C1C1C1D1D1C13 +:1088B0001C1D1C1D1C1D1B1C1C1D1B1C1C1C1C1DF5 +:1088C0001C1D1D1E1D1D1C1C1C1C1C1C1B1D1C1CE2 +:1088D0001D1D1D1D1D1D1D1C1D1B1C1B1C1C1B1CD3 +:1088E0001C1C1D1D1D1D1D1D1C1D1D1D1C1C1C1CBF +:1088F0001D1C1B1C1C1D1C1D1D1D1D1C1C1D1C1CB2 +:108900001C1B1C1C1B1C1B1C1C1C1C1D1D1D1D1DA5 +:108910001E1D1D1C1C1C1C1C1C1D1C1D1C1D1D1D8E +:108920001D1D1D1C1C1C1D1D1C1D1C1D1D1D1D1D7C +:108930001D1D1D1C1C1C1C1C1E1C1D1D1D1D1D1D6C +:108940001D1E1E1D1E1D1D1E1C1C1D1C1C1C1D1D58 +:108950001D1D1E1D1D1C1D1D1D1D1C1A1C1D1C1D4D +:108960001C1D1D1D1E1E1E1D1E1D1E1D1C1B1C1C38 +:108970001C1D1D1D1D1D1D1D1D1D1D1D1D1C1C1C2B +:108980001C1D1D1C1D1D1D1E1D1E1E1D1E1D1E1C15 +:108990001C1D1C1C1C1C1D1D1D1E1D1E1E1E1D1E07 +:1089A0001F1D1C1D1C1C1C1C1D1D1D1D1D1E1E1EF7 +:1089B0001E1F1E1D1D1C1D1D1C1D1D1E1D1D1D1FE2 +:1089C0001E1F1E1E1F1E1D1C1D1D1D1D1D1D1D1DD0 +:1089D0001E1F1F1F1E1E1F1D1D1D1D1C1D1D1D1DBD +:1089E0001E1D1D201F1E1E1F1E1D1D1E1C1C1D1DAD +:1089F0001E1E1E1E1F1D1D1C1D1D1D1C1C1D1C1EA4 +:108A00001E1E1F1E1F1F1E1C1D1E1D1C1D1D1C1B90 +:108A10001D1C1D1D1E1D1F1E1E1D1D1D1D1C1D1C84 +:108A20001C1B1D1C1C1D1E1D1E1E1F1D1D1D1D1C77 +:108A30001C1C1C1C1E1C1C1D1E1E1E1E1E1E1E1D64 +:108A40001E1D1D1C1B1C1D1D1E1E1E1E1E1E1E1D52 +:108A50001C1D1D1D1C1C1B1D1C1C1D1E1D1E1E1E49 +:108A60001E1D1C1C1C1D1C1C1B1D1E1D1C1E1D1E3A +:108A70001E1E1E1D1D1D1D1D1D1C1C1D1E1D1D1E23 +:108A80001E1E1E1E1E1C1C1D1D1C1C1C1C1D1E1E15 +:108A90001E1E1E1E1E1E1F1D1D1C1D1D1C1C1C1C03 +:108AA0001D1D1E1D1E1E1E1E1E1E1E1D1D1D1C1CF0 +:108AB0001D1D1E1E1E1E1E1E1F1E1E1E1E1D1E1DD9 +:108AC0001D1D1D1C1D1E1D1E1E1D1E1E1E1E1D1DD0 +:108AD0001D1D1D1C1D1D1D1D1E1E1E1E1E1F1F1EBD +:108AE0001E1E1D1C1D1C1D1D1F1E1E1F1E1E1E1FAB +:108AF000201E1E1E1D1D1E1D1D1D1F1E1D1E1E1E99 +:108B00001F201F1E1E1D1D1D1E1D1D1D1F1E1E1E86 +:108B10001E1E1E1E1E1E1E1E1D1E1D1D1D1E1F1E78 +:108B20001D1F1E1E1E1E1E1F1F1F1F1E1F1E1E1C62 +:108B300005020101F401D00700000000240210002A +:108B400000063B5900000000B0568EEE44230000A2 +:108B5000EB1E00000C1F00002D1F00004E1F000028 +:108B60006F1F000000000000000000001B03000059 +:108B70002088410AE6A00400000000000000000078 +:108B800000000000002800002020202020202020BD +:108B90002020000000000000010000000000000094 +:108BA000000000000000000000000000D21F3E2076 +:108BB0006A20302105224E21F621F52200B8C30794 +:108BC000D638000000000000000010055805A00580 +:108BD000E80500001040040D0F0B0D0D10000E11E4 +:108BE000A5BB031F7EF80F00130F130F0F430F4396 +:108BF0001B0300000A00000000000000000000004D +:108C0000000000000000000000040000030000005D +:108C10000000000000000000000000000200000052 +:108C20000000000000000000000000000000000044 +:108C3000D21F3E206A20302105224E21F621F52246 +:108C400000B8C307D6380000000000000000000094 +:108C500048009000D80000001040040D0F0B0D0DCF +:108C600010000E11A5BB031F7EF80F00130F130F8A +:108C70000F430F431B0300002088410AE6A00400B5 +:108C800000000000000000000000000000280000BC +:108C9000272727272727272727270000000000004E +:108CA00063666666666666666666000000000000CB +:108CB00000000000D21F3E206A20302105224E21F4 +:108CC000F621F52200B8C307D638000000000000E6 +:108CD000000010055805A005E80500001040040D2F +:108CE0000F0B0D0D10000E11A5BB031F7EF80F001A +:108CF000130F130F0F430F431B0300008B35F72097 +:108D00000000000000000000000000000000000063 +:108D100000180000202020000000000000000000DB +:108D20000000000011111100000000000000000010 +:108D30000000000000000000D21F3E206A20302109 +:108D400005224E21F621F52200B8C307D6380000CF +:108D5000000000000000000048009000D800000063 +:108D60001040040D0F0B0D0D10000E11A5BB031FBD +:108D70007EF80F00130F130F0F430F431B03000068 +:108D80008B35F7200A000000000000000000000002 +:108D900000000000001C000027272705000000003D +:108DA0000000000000000000333333020000000028 +:108DB000000000000000000000000000D21F3E2064 +:108DC0006A20302105224E21F621F52200B8C30782 +:108DD000D6380000000000000000000048009000AD +:108DE000D80000001040040D0F0B0D0D10000E11E7 +:108DF000A5BB031F7EF80F00130F130F0F430F4384 +:108E00000000000000000000000000000000000062 +:108E10000000000000000000000000000000000052 +:108E20000000000000000000000000000000000042 +:108E30000000000000000000000000000000000032 +:108E40000000000000000000000000000000000022 +:108E50000000000000000000000000000000000012 +:108E60000000000000000000000000000000000002 +:108E700000000000000000000000000000000000F2 +:108E800000000000000000000000000000000000E2 +:108E900000000000000000000000000000000000D2 +:108EA00000000000000000000000000000000000C2 +:108EB00000000000000000000000000000000000B2 +:108EC00000000000000000000000000000000000A2 +:108ED0000000000000000000000000000000000092 +:108EE0000000000000000000000000000000000082 +:108EF0000000000000000000000000000000000072 +:108F0000000000000000000000000000090901004E +:108F10000128000000D8030012000000A51D020077 +:108F200000000000000003020228000000D8030037 +:108F300011000000A61D0000000000000101030256 +:108F40000328000000D8030010000100A71D000046 +:108F500000000000020203020428000000D8030001 +:108F60000F000200A81D0000000000000303030220 +:108F70000528000000D803000E000300A91D000012 +:108F800000000000040403020628000000D80300CB +:108F90000D000400AA1D00000000000005050302EA +:108FA0000728000000D803000C000500AB1D0000DE +:108FB00000000000060603020828000000D8030095 +:108FC0000B000600AC1D00000000000007070302B4 +:108FD0000928000000D803000A000700AD1D0000AA +:108FE00000000000080803020A28000000D803005F +:108FF00009000800AE1D0000000000000A09010081 +:109000000028000000D8030092148014A51D000061 +:1090100000000000090901000028000000D803003A +:1090200012000000A51D0200000000000909010057 +:109030000028000000D80300A2009000A61D020036 +:1090400000000000090901000028000000D803000A +:1090500032012001A71D02000000000009090100E3 +:109060000028000000D80300C201B001A81D0200C2 +:1090700000000000090901000028000000D80300DA +:1090800052024002A91D020000000000090901006F +:109090000028000000D80300E202D002AA1D02004E +:1090A00000000000090901000028000000D80300AA +:1090B00092148014000002000F00000005B40500A7 +:1090C0005D4C1B00610000000C0000000500040066 +:1090D0001529000060000000000000000D004000A5 +:1090E000152900001E000000030000000DFC4300D5 +:1090F000FFFE1B001F000000000000000DFC4300ED +:10910000FFFE1B001F000000030000000DB4410023 +:109110005D4C1B001F000000000000000DB441006A +:109120005D4C1B001F0000000F00000001B4050093 +:109130005D4C1B00E10001000C0000000100040078 +:1091400015290000E0000100000000000D004000B3 +:10915000152900001E0000000F00000005FC07009C +:10916000FFFE1B006100000053579FAE558E8381A8 +:109170009F8E8887977D879271998B958279969833 +:109180001E1D1C1D1D1D1D1D1D1C1D1C1D1C1C1D13 +:109190001D1D1D1E1D1D1D1D1D1D1C1D1D1D1D1DFF +:1091A0001D1D1D1E1D1D1D1D1D1D1D1D1E1D1C1DEE +:1091B0001D1D1C1D1D1D1C1D1C1C1D1D1C1D1D1DE4 +:1091C0001D1D1D1D1D1D1D1D1D1D1C1D1C1D1D1DD1 +:1091D0001D1C1D1C1D1C1C1D1D1D1D1D1D1D1D1DC3 +:1091E0001C1D1C1D1D1D1D1D1D1D1D1E1C1C1D1DB2 +:1091F0001D1D1D1D1D1D1C1D1D1D1C1D1D1D1C1DA2 +:109200001C1C1D1D1C1D1D1D1D1D1D1D1D1D1D1D91 +:109210001D1D1C1D1D1D1D1D1D1C1D1C1D1C1C1D83 +:109220001D1D1D1D1D1D1D1D1C1D1C1D1D1D1D1D70 +:109230001D1D1D1E1C1C1D1D1D1D1D1D1D1D1C1D60 +:109240001D1D1C1D1D1D1C1D1D1C1D1D1C1D1D1D52 +:109250001D1D1D1D1D1D1D1D1D1D1C1D1C1D1D1D40 +:109260001D1C1D1C1D1C1C1D1D1D1D1D1D1C1D1D33 +:109270001C1D1C1D1D1D1D1D1D1D1D1E1C1C1D1D21 +:109280001D1D1D1D1D1D1C1D1D1D1C1D1D1D1C1D11 +:109290001C1C1D1D1C1D1D1D1D1D1D1D1D1D1D1D01 +:1092A000FF7E8D986E749899646B969A5B5F9AA115 +:1092B0005B5AA6AE5152AD8A1C1D1C1D1D1D1D1DE5 +:1092C0001D1D1D1E1C1C1D1D1D1D1D1D1D1D1C1DD0 +:1092D0001D1D1C1D1D1D1C1C1D1D1D1D1C1D1D1DC2 +:1092E0001D1D1D1D1D1D1D1D1D1D1C1D1C1D1D1DB0 +:1092F0001D1C1D1C1D1C1C1D1D1D1D1E1D1C1D1DA2 +:109300001C1D1D1D1D1D1D1D1D1D1D1E1C1C1D1D8F +:109310001D1D1D1D1D1D1C1E1D1D1C1D1D1D1C1D7F +:109320001D1D1D1D1C1D1D1D1D1D1D1D1D1D1D1D6E +:109330001D1D1C1D1C1D1D1D1D1C1D1C1D1C1C1D63 +:109340001D1D1D1E1D1D1D1D1C1D1C1D1D1D1D1D4E +:109350001D1D1D1E1C1D1D1D1D1D1D1D1D1D1C1E3D +:109360001E1D1C1D1E1D1C1D1D1D1D1D1D1D1D1D2D +:109370001E1D1D1D1E1D1D1D1E1D1C1D1D1D1D1D1B +:109380001E1C1D1C1D1C1D1D1D1D1D1E1D1D1D1D0E +:109390001D1D1D1D1E1D1D1D1D1D1E1E1C1D1D1DFB +:1093A0001D1D1E1D1D1D1D1E1E1E1E1E1E1E1E1EE3 +:1093B0001E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1ECD +:1093C0001E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EBD +:1093D0001E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EAD +:1093E0001E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E9D +:1093F000323232323232323232323232323232324D +:10940000323232323232323232323232323232323C +:10941000323232323232323232323232323232322C +:10942000323232323232323232323232323232321C +:10943000323232323232323235358B3534353435A0 +:1094400035353535353533363535353533353535CF +:1094500035353535353535353434353535353535BE +:1094600033343335333434353333353634353535B9 +:109470003535353633333536333536353373353761 +:10948000B66DB66DB605B60500000000B66DB66DDA +:10949000B60CB60C00000000B66DB66D960D960DBC +:1094A00000000000B66DB66DB20DB20D00000000F8 +:1094B000B62DB62DB60DB60D00000000B665B6652A +:1094C000B60DB60D00000000B66CB66CB60DB60D4C +:1094D00000000000966D966DB60DB60D0000000000 +:1094E000B26DB26DB60DB60D00000000922492244C +:1094F000920492040000000001100000000000002F +:1095000000000000FFFF3DDB38D4FC020200FF003A +:109510006C768A94DB060000040C0000A003570060 +:1095200036E60802010000003E03E600477EEC1428 +:10953000FFFF00801C080C570380BBBB8044220047 +:109540006415641588398A3935003500011000002A +:109550000000000000000000FFFF3DDB38D4FC02EB +:109560000200FF006C768A94DB060000040C000009 +:10957000A003570036E60802410002003E03E60061 +:10958000477EEC14FFFF00801C080C17E38EBBBB6A +:10959000805522006415641588398A3935003500F4 +:1095A00001040000000000000000000000000000B6 +:1095B000000000020200FF006C768A94DB060000C7 +:1095C000040C000024055700364709020100000082 +:1095D000C2044701477EEC14FFFF00801C040C57B7 +:1095E0000380BBBB804522006415641588398A3925 +:1095F000350035008304020001020304E0EC37FB70 +:10960000528BE4C5CF0304021E0600036C768A94D5 +:10961000DB060000014500008C0E000000EC080293 +:10962000410002000000EC00477EEC14FFFF0080C8 +:109630001C5C11970080BBBB0057220064D164D131 +:1096400088198A19350035008304020001010101DF +:10965000E0EC37FB528BE4C5CF03040202060000A6 +:109660006C768A94DB060000014500008C0E000039 +:1096700000EC0802410002000000EC00437D531A98 +:10968000FFFF00801C5C11BF0080BBBB00462200B6 +:1096900064D164D188398A393500350083040200E9 +:1096A00002020202E0EC37FB528BE4C5CF03040256 +:1096B000020600006C768A94DB060000014500007B +:1096C0008C0E000000EC0802410002000000EC00DB +:1096D000A87D6018FFFF00801C5C11BF0080BBBB31 +:1096E0000046220064D164D188398A3935003500BA +:1096F0008304020003030303E0EC37FB528BE4C551 +:10970000CF030402020600006C768A94DB06000098 +:10971000014500008C0E000000EC08024100020030 +:109720000000EC006C7E0614FFFF00801C5C11BF83 +:109730000080BBBB0046220064D164D188398A39DD +:10974000350035008304020004040404E0EC37FB18 +:10975000528BE4C5CF030402020600006C768A94A3 +:10976000DB060000014500008C0E000000EC080242 +:10977000410002000000EC00ED7E8610FFFF00803B +:109780001C5C11BF0080BBBB0046220064D164D1C9 +:1097900088398A393500350000005D3F0000DA471E +:1097A000C0CED0C716219CD1548694083C0E0F061B +:1097B00079CACDFCD820EF99FACECFC5FD962E51AF +:1097C0005361DF9F3B0F0F04F43CFA883C803CD48C +:1097D000390F0E03124C4001155870011864A00196 +:1097E0001B70D0011E7C0002218830020004200082 +:1097F00003105000061C80000928B0000C34E00063 +:109800000F40100123881002207CE0011D70B00180 +:109810001A64800117585001144C200135D03003D0 +:1098200032C400032FB8D0022CACA00229A07002D1 +:1098300026944002445985167A31E619B009471D2D +:10984000E6E1A7201CBA082452926927004840028A +:109850003620A1056CF80109A2D0620CD8A8C30F6C +:109860000E8124133281E410FCA8830DC6D0220A95 +:1098700090F8C1065A2061032448000076922925F9 +:1098800040BAC8210AE2671ED409071B9E31A617F9 +:10989000685945147692292540BAC8210AE2671E04 +:1098A000D409071B9E31A617685945143281E4106C +:1098B000FCA8830DC6D0220A90F8C1065A20610385 +:1098C000244800007796392541BED8210BE6771E43 +:1098D000D50D171B9F35B617695D55143385F410E8 +:1098E000FDAC930DC7D4320A91FCD1065B24710301 +:1098F000254C100085CE19264FF6B822191E581F88 +:10990000E345F71BAD6D96187795351541BDD4111C +:109910000BE5730ED50C130B9F34B207695C510431 +:109920003384F000789A492542C2E8210CEA871E68 +:10993000D611271BA039C6176A6165143489041132 +:10994000FEB0A30DC8D8420A9200E2065C2881034B +:109950002650200084CA09264EF2A822181A481F51 +:10996000E241E71BAC6986187691251540B9C41110 +:109970000AE1630ED408030B9E30A2076858410425 +:109980003280E000799E592543C6F8210DEE971EDE +:10999000D715371BA13DD6176B657514358D14117E +:1099A000FFB4B30DC9DC520A9304F2065D2C910397 +:1099B0002754300083C6F9E54DEE98E21716381F9C +:1099C000E13DD71BAB6576D8758D15153FB5B41144 +:1099D00009DD530ED304F30A9D2C9207675431041A +:1099E000317CD0007AA2692544CA08220EF2A71E53 +:1099F000D819471BA241E6176C69851436912411CA +:109A000000B9C30DCAE0620A940802075E30A103E0 +:109A10002858400082C2E9254CEA88221612281FE5 +:109A2000E039C71BAA616618748905153EB1A411F7 +:109A300008D9430ED200E30A9C288207665021040D +:109A40003078C0007BA6792545CE18220FF6B71EC8 +:109A5000D91D571BA345F6176D6D95143795341115 +:109A600001BDD30DCBE4720A950C12075F34B1032C +:109A7000295C500081BED9254BE67822150E181FAF +:109A8000DF35B71BA95D56187385F5143DAD9411EC +:109A900007D5330ED1FCD20A9B247207654C110402 +:109AA0002F74B0007CAA892546D2282210FAC71E3E +:109AB000DA21671BA44906186E71A5143899441160 +:109AC00002C1E30DCCE8820A961022076038C10378 +:109AD0002A60600080BAC9254AE26822140A081F79 +:109AE000DE31A71BA85946187281E5143CA98411E0 +:109AF00006D1230ED0F8C20A9A20620764480104F6 +:109B00002E70A0007DAE992547D6382211FED71EB3 +:109B1000DB25771BA54D16186F75B514399D5411AB +:109B200003C5F30DCDEC920A97143207613CD103C3 +:109B30002B6470007FB6B92549DE58221306F81E43 +:109B4000DD2D971BA7553618717DD5143BA57411D3 +:109B500005CD130ECFF4B20A991C52076344F103EA +:109B60002D6C90007EB2A92548DA48221202E81E28 +:109B7000DC29871BA65126187079C5143AA16411F7 +:109B800004C9030ECEF0A20A981842076240E1030E +:109B90002C688000000000000000000000000000B1 +:109BA00000000000000000000000000000000000B5 +:109BB00000000000000000000000000000000000A5 +:109BC0000000000000000000000000000000000095 +:109BD0000000000000000000000000000000000085 +:109BE0000000000000000000000000000000000075 +:109BF0000000000000000000000000000000000065 +:109C00000000000000000000000000000000000054 +:109C10000000000000000000000000000000000044 +:109C20000000000000000000000000000000000034 +:109C30000000000000000000000000000000000024 +:109C40000000000000000000000000000000000014 +:109C50000000000000000000000000000000000004 +:109C600000000000000000000000000000000000F4 +:109C700000000000000000000000000000000000E4 +:109C800000000000000000000000000000000000D4 +:109C900000000000000000000000000000000000C4 +:109CA00000000000000000000000000000000000B4 +:109CB00000000000000000000000000000000000A4 +:109CC0000000000000000000000000000000000094 +:109CD0000000000000000000000000000000000084 +:109CE0000000000000000000000000000000000074 +:109CF0000000000000000000000000000000000064 +:109D00000000000000000000000000000000000053 +:109D10000000000000000000000000000000000043 +:109D20000000000000000000000000000000000033 +:109D30000000000000000000000000000000000023 +:109D40000000000000000000000000000000000013 +:109D50000000000000000000000000000000000003 +:109D600000000000000000000000000000000000F3 +:109D700000000000000000000000000000000000E3 +:109D800000000000000000000000000000000000D3 +:109D900000000000000000000000000000000000C3 +:109DA00000000000000000000000000000000000B3 +:109DB00000000000000000000000000000000000A3 +:109DC0000000000000000000000000000000000093 +:109DD0000000000000000000000000000000000083 +:109DE0000000000000000000000000000000000073 +:109DF0000000000000000000000000000000000063 +:109E00000000000000000000000000000000000052 +:109E10000000000000000000000000000000000042 +:109E20000000000000000000000000000000000032 +:109E30000000000000000000000000000000000022 +:109E40000000000000000000000000000000000012 +:109E50000000000000000000000000000000000002 +:109E600000000000000000000000000000000000F2 +:109E700000000000000000000000000000000000E2 +:109E800000000000000000000000000000000000D2 +:109E900000000000000000000000000000000000C2 +:109EA00000000000000000000000000000000000B2 +:109EB00000000000000000000000000000000000A2 +:109EC0000000000000000000000000000000000092 +:109ED0000000000000000000000000000000000082 +:109EE0000000000000000000000000000000000072 +:109EF0000000000000000000000000000000000062 +:109F00000000000000000000000000000000000051 +:109F10000000000000000000000000000000000041 +:109F20000000000000000000000000000000000031 +:109F300009F61224380460090E0A00010101081212 +:109F4000240038046C090000000C00000000000030 +:109F500000004B5900000000000000000009010A49 +:109F600000013C4388020000281E21000008FC007C +:109F70000008FC000008FC000008FC000008FC00D1 +:109F80000008FC000008FC000008FC000000FC00C9 +:109F90000008FC000008FC000008FC000000FC00B9 +:109FA0000008FC000008FC000008FC0000000000A5 +:109FB000000101000000000000000000000000009F +:109FC000000000000000000000000101010101008C +:109FD0000001010101000101010100010000010077 +:109FE00001000000000000000F0000000107010355 +:109FF00002030A00320A400000003200370000006D +:10A000000000000000000000000000000000000050 +:10A010000000000000000000C800C8009600C80052 +:10A020000707800080000505000000000000000018 +:10A0300007010000DBFF00004100F1FF10001400E9 +:10A04000F9FFC4FFFF7FFF7FFF7FFF7F96002C019A +:10A0500096003C000A04CECE3232280500000000F3 +:10A0600000071600002416000000001224242424F7 +:10A0700024242424242424242424242424240000E8 +:10A0800000000000000000000000000000000000D0 +:10A090000A05000A0000000020010014111400004D +:10A0A00000000000000000000000000000000000B0 +:10A0B000000000000F23283C465000006E696664D3 +:10A0C0005050505008000000000000000F23283CB2 +:10A0D000465000006E696664505050500F141E28A0 +:10A0E000000000000A0A0A0A0A0A0A0A0F1E32467B +:10A0F00000000000645F553C3C3C3C3C000000001C +:10A1000008081A00A000EAFF15009D008300100E49 +:10A1100000000000001000003C0032009001280008 +:10A120000F000F001C023D011C02740400003704E4 +:10A1300000005F09F4010000370400005F093214D9 +:10A14000021E1E3202009B00280028007700C00378 +:10A150007700E8080000000038043000200001000B +:10A16000220000003A00520070008F00AF00CF00C4 +:10A17000EF000F012E014F016E018E01AD01CE01E6 +:10A18000EC010F022D024D026D028D02AC02CC02D9 +:10A19000EB020B032B034A036A038903AA03C903D7 +:10A1A000E703FF0337040000000000000000000088 +:10A1B000000000000000000000000000000000009F +:10A1C000000000000000000000000000000000008F +:10A1D000000000000000000000000000000000007F +:10A1E000000000000000000000000000000000006F +:10A1F000000000000000000000000000000000005F +:10A20000000000000000000000000000000000004E +:10A21000000000000000000000000000000000003E +:10A22000000000000000000000006C093000460043 +:10A230000100480000003C00430066008500A900C2 +:10A24000C800E90009012A0149016B018901AB013C +:10A25000C901EB0109022B024A026C028A02AC021C +:10A26000CA02EC020B032D034B036D038B03AE03F9 +:10A27000CB03EE030C042F044C046F048B04AF04D7 +:10A28000CC04EF040D0530054D0570058D05B005B6 +:10A29000CD05F1050D0630064E0672068E06B10696 +:10A2A000CE06F2060F073207500773079007B30771 +:10A2B000D107F40711083408520875089108B1084D +:10A2C000C608E708000000000000000000000000D1 +:10A2D000000000000000000000000000000000007E +:10A2E000000000000000000000000000000000006E +:10A2F000000000000000000000000000000000005E +:10A3000002020500F16C0000409C000000F91500FD +:10A3100029B1010010270000C4090000010101015A +:10A32000010101010101014B0F004B000000000081 +:10A33000020101010101010101010100F16C0000B4 +:10A340000200000084DE0100000000000F0F0A0A76 +:10A3500028000000000000000F0F1414010101018B +:10A36000010140003200E8030F0008000500E10091 +:10A3700000001E288C00B40019006400640028004E +:10A380007800000000000000B4007800E8034006F8 +:10A3900000000001410100000000000068010D0DF7 +:10A3A0000A093C0019006400140064002C016400D8 +:10A3B0002C010F02E8E8F800F8000804190000007A +:10A3C000DB00ED0000011401290140015801720178 +:10A3D0008D01A901C801E8010A022D0252027A0288 +:10A3E000A302CE02FB022A035C038F03C503FD0315 +:10A3F00036047304B104F10434057805BF0508067A +:10A400005306A006EF063F079207E6073B089308AE +:10A41000EB084509A009FC09580AB60A140B720B8F +:10A42000D10B2F0C8D0CEB0C490DA50D010E5B0E05 +:10A43000B40E0C0F610FB50F06105510A110EA10E5 +:10A4400031117411B411F01128125D128D12B9126C +:10A45000E112051324133E1354136513711378137B +:10A460007B13DB00ED0000011401290140015801BC +:10A4700072018D01A901C801E8010A022D025202F0 +:10A480007A02A302CE02FB022A035C038F03C503F8 +:10A49000FD0336047304B104F10434057805BF05E7 +:10A4A00008065306A006EF063F079207E6073B089B +:10A4B0009308EB084509A009FC09580AB60A140BD1 +:10A4C000720BD10B2F0C8D0CEB0C490DA50D010E51 +:10A4D0005B0EB40E0C0F610FB50F06105510A110D6 +:10A4E000EA1031117411B411F01128125D128D129D +:10A4F000B912E112051324133E135413651371139B +:10A5000078137B136A00750081008E009D00AC00FB +:10A51000BD00CF00E200F7000D01260140015C0103 +:10A5200079019901BC01E001060230025B02890257 +:10A53000BA02EE0224035D039A03D9031B046004EC +:10A54000A904F40443059505E90541069C06FA06AD +:10A550005B07BE0724088D08F8086509D409450A79 +:10A56000B80A2D0BA20B190C900C080D800DF80DDC +:10A570006F0EE60E5C0FD00F4210B31021118C113C +:10A58000F4115912BA1217137013C41313145D1473 +:10A59000A114E01418154B1577159C15BB15D4158F +:10A5A000E515EF15F3156A00750081008E009D001A +:10A5B000AC00BD00CF00E200F7000D012601400114 +:10A5C0005C0179019901BC01E001060230025B02E5 +:10A5D0008902BA02EE0224035D039A03D9031B0425 +:10A5E0006004A904F40443059505E90541069C06A9 +:10A5F000FA065B07BE0724088D08F8086509D40928 +:10A60000450AB80A2D0BA20B190C900C080D800DF1 +:10A61000F80D6F0EE60E5C0FD00F4210B310211133 +:10A620008C11F4115912BA1217137013C4131314A6 +:10A630005D14A114E01418154B1577159C15BB1566 +:10A64000D415E515EF15F315550055004B004700DF +:10A65000000000004B007D00DC001400050000003D +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000009000000B1 +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A93000050201010000000000000000240104776E +:10A940000001365900000000000000000000000077 +:10A950006726000088260000A92600001A030000D0 +:10A96000410C520C07250000000000000000000010 +:10A97000000000000024000031313131252020206A +:10A980002020000000000000000000000000000087 +:10A99000000000000000000000000000CA2642275E +:10A9A00066272C28492968283A29392A00B8C3077C +:10A9B0007E17000000000000000010055805A005EB +:10A9C000E80500001040040C0E0B0C0C10000E10DB +:10A9D000A5BA031F7CC60F00100D100D0D410D41CF +:10A9E0001A0300008B35F720514E000000000000D4 +:10A9F00000000000000000000024000020202020B3 +:10AA0000252020202020000000000000111111113D +:10AA10001100000000000000000000000000000025 +:10AA2000CA26422766272C28492968283A29392A24 +:10AA300000B8843A7E1700000000000000001005F6 +:10AA40005805A005E80500001040040C0E0B0C0C86 +:10AA500090000E10A5BB831FFCC90F00100D100D38 +:10AA60000D410D411A0300008B35F72051C9090033 +:10AA700000000000000000000000000000280000AE +:10AA80002727272725272727272700000000000042 +:10AA900066666656660000000000000000000000C8 +:10AAA00000000000CA26422766272C28492968286A +:10AAB0003A29392A00B8C3077E17000000000000B9 +:10AAC000000010055805A005E80500001040040C22 +:10AAD0000E0B0C0C90000E10A5BB831FFCC90F00C1 +:10AAE000100D100D0D410D4100000000090901007D +:10AAF0000028000000A8030000000000A51D0200BF +:10AB000000000000000003020028000080AA0300EB +:10AB100009000000A61D0000000000000101030262 +:10AB20000028000080AA03000A000100A71D000001 +:10AB300000000000020203020028000080AA0300B7 +:10AB40000B000200A81D0000000000000303030228 +:10AB50000028000080AA03000C000300A91D0000CB +:10AB600000000000040403020028000080AA030083 +:10AB70000D000400AA1D00000000000005050302EE +:10AB80000028000080AA03000E000500AB1D000095 +:10AB900000000000060603020028000080AA03004F +:10ABA0000F000600AC1D00000000000007070302B4 +:10ABB0000028000080AA030010000700AD1D00005F +:10ABC00000000000080803020028000080AA03001B +:10ABD00011000800AE1D0000000000000913010074 +:10ABE0000028000000A8030000000000A51D0200CE +:10ABF00000000000000A03020028000080A80300F3 +:10AC000009000000A61D000000000000010B030267 +:10AC10000028000080A803000A000100A71D000012 +:10AC200000000000020C03020028000080A80300BE +:10AC30000B000200A81D000000000000030D03022D +:10AC40000028000080A803000C000300A91D0000DC +:10AC500000000000040E03020028000080A803008A +:10AC60000D000400AA1D000000000000050F0302F3 +:10AC70000028000080A803000E000500AB1D0000A6 +:10AC800000000000061003020028000080A8030056 +:10AC90000F000600AC1D00000000000007110302B9 +:10ACA0000028000080A8030010000700AD1D000070 +:10ACB00000000000081203020028000080A8030022 +:10ACC00011000800AE1D00000F000000018C0614EA +:10ACD0005D161B00610000000F000000016C0414F1 +:10ACE00030441B0061000000000000000D00401413 +:10ACF00064C700001E00000000000000290070145E +:10AD0000152900001E00000000000000296C7014CE +:10AD100030441B001F000000030000000D8C421493 +:10AD20005D161B001F00000000000000296C70145D +:10AD300030441B001F0000000F000000016C0414D1 +:10AD400030441B00E10001000C000000010004146D +:10AD500015290000E00001000000000000000000D4 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF0000000000000000000000000000000000051 +:10B000000000000000000000000000000000000040 +:10B010000000000000000000000000000000000030 +:10B020000000000000000000000000000000000020 +:10B030000000000000000000000000000000000010 +:10B040000000000000000000000000000000000000 +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700022492449240924050000000014492449D8 +:10B080002409A40800000000A44824492409140944 +:10B090000000000024452449240922090000000082 +:10B0A00024292429240924090000000024492445D6 +:10B0B00022092409000000002449A4481409240995 +:10B0C0000000000024491449A408240900000000DD +:10B0D00024492249240524090000000092249224D6 +:10B0E0009204920400000000B26DB66DB60DB60574 +:10B0F00000000000966DB66DB60DB60C00000000A5 +:10B10000B66CB66DB60D960D00000000B665B66D56 +:10B11000B60DB20D00000000B62DB62DB60DB60D61 +:10B1200000000000B66DB665B20DB60D000000005F +:10B13000B66DB66C960DB60D00000000B66D966D3E +:10B14000B60CB60D00000000B66DB26DB605B60DBA +:10B150000000000092249224920492040000000057 +:10B1600001280000000000000000000000000000B6 +:10B17000000000020206FF006C768A94DB060000E5 +:10B180000106000041015700363C090201000000A1 +:10B19000E1003C01477EEC14FFFF00801C7C0F5750 +:10B1A0000380BBBB8E5C22006401640188398A394C +:10B1B0000000000001280000000000000000000066 +:10B1C00000000000000000020206FF006C768A9476 +:10B1D000DB06000001060000F100570036EC080213 +:10B1E000010000009100EC00477EEC14FFFF00809E +:10B1F0001C040C570380ABAA804422006411641124 +:10B2000088398A3905000500012800000000000087 +:10B210000000000000000000000000020206FF0025 +:10B220006C768A94DB06000001060000610057007E +:10B23000365C08020100000001005C00477EEC144F +:10B24000FFFF00801C240C570380ABAA804422001F +:10B250006411641188398A3905000500012800004D +:10B2600000000000000000000000000000000002DC +:10B270000200FF006C768A94DB06000001060000E5 +:10B28000F100570036EC0802410002009100EC008A +:10B29000477EEC14FFFF00801CC40C17E38EBBBB81 +:10B2A000805522006411641188398A39050005002F +:10B2B0000104000000000000000000000000000089 +:10B2C000000000020200FF006C768A94DB0600009A +:10B2D000040C0000B803570036EC0802010000001F +:10B2E0005803EC00477EEC14FFFF00801CE00C5775 +:10B2F0000380BBBB804522006411641188398A3900 +:10B30000050005009404020001020304D6F042FC8B +:10B310001C6005AFCF0304021E0600036C768A94FE +:10B32000DB06000001C50000D20F000000EC08029F +:10B33000410002000000EC00477EEC14FFFF00809B +:10B340001CC411170080BBBB00572200641164119C +:10B3500088198A1905000500940402000101010101 +:10B36000D6F042FC1C6005AFCF03040202060000C9 +:10B370006C768A94DB06000001C50000D20F000045 +:10B3800000EC0802410002000000EC007278512B32 +:10B39000FFFF00801CC4113F0080BBBB00462200A1 +:10B3A0006411641188398A3905000500940402008B +:10B3B00002020202D6F042FC1C6005AFCF03040279 +:10B3C000020600006C768A94DB06000001C50000CE +:10B3D000D20F000000EC0802410002000000EC0067 +:10B3E000BB7BC520FFFF00801CC4113F0080BBBB9E +:10B3F000004622006411641188398A39050005006D +:10B400009404020003030303D6F042FC1C6005AF62 +:10B41000CF030402020600006C768A94DB0600006B +:10B4200001C50000D20F000000EC0802410002003C +:10B430000000EC00197EFC15FFFF00801CC4113FCA +:10B440000080BBBB004622006411641188398A3930 +:10B45000050005009404020004040404D6F042FC34 +:10B460001C6005AFCF030402020600006C768A94CC +:10B47000DB06000001C50000D20F000000EC08024E +:10B48000410002000000EC00867F080BFFFF0080F7 +:10B490001CC4113F0080BBBB004622006411641134 +:10B4A00088398A390500050000005D3F0000DA4751 +:10B4B000C0CED0C7FFFF47020000A1503F0D3009AA +:10B4C000FFFF244B00009F30FFCEF0C7FFFFDF3BA4 +:10B4D000000047E43F0F3004FFFFABCE0000C5790A +:10B4E0003F0F300220C208001080000340400106D8 +:10B4F00070000209A0C0020CD080030F00410412AA +:10B500003001051560C105189081061BC041071E5A +:10B51000F001082120C00004508001078040020A89 +:10B52000B000030DE0C00310108104134041051664 +:10B5300070010619A0C1061CD081071F0042082215 +:10B5400030020001445985167A31E619B009471DC9 +:10B55000E6E1A7201CBA082452926927004840025D +:10B560003620A1056CF80109A2D0620CD8A8C30F3F +:10B570000E8124133281E410FCA8830DC6D0220A68 +:10B5800090F8C1065A2061032448000076922925CC +:10B5900040BAC8210AE2671ED409071B9E31A617CC +:10B5A000685945147692292540BAC8210AE2671ED7 +:10B5B000D409071B9E31A617685945143281E4103F +:10B5C000FCA8830DC6D0220A90F8C1065A20610358 +:10B5D000244800007796392541BED8210BE6771E16 +:10B5E000D50D171B9F35B617695D55143385F410BB +:10B5F000FDAC930DC7D4320A91FCD1065B247103D4 +:10B60000254C100085CE19264FF6B822191E581F5A +:10B61000E345F71BAD6D96187795351541BDD411EF +:10B620000BE5730ED50C130B9F34B207695C510404 +:10B630003384F000789A492542C2E8210CEA871E3B +:10B64000D611271BA039C6176A6165143489041105 +:10B65000FEB0A30DC8D8420A9200E2065C2881031E +:10B660002650200084CA09264EF2A822181A481F24 +:10B67000E241E71BAC6986187691251540B9C411E3 +:10B680000AE1630ED408030B9E30A20768584104F8 +:10B690003280E000799E592543C6F8210DEE971EB1 +:10B6A000D715371BA13DD6176B657514358D141151 +:10B6B000FFB4B30DC9DC520A9304F2065D2C91036A +:10B6C0002754300083C6F9E54DEE98E21716381F6F +:10B6D000E13DD71BAB6576D8758D15153FB5B41117 +:10B6E00009DD530ED304F30A9D2C920767543104ED +:10B6F000317CD0007AA2692544CA08220EF2A71E26 +:10B70000D819471BA241E6176C698514369124119C +:10B7100000B9C30DCAE0620A940802075E30A103B3 +:10B720002858400082C2E9254CEA88221612281FB8 +:10B73000E039C71BAA616618748905153EB1A411CA +:10B7400008D9430ED200E30A9C28820766502104E0 +:10B750003078C0007BA6792545CE18220FF6B71E9B +:10B76000D91D571BA345F6176D6D951437953411E8 +:10B7700001BDD30DCBE4720A950C12075F34B103FF +:10B78000295C500081BED9254BE67822150E181F82 +:10B79000DF35B71BA95D56187385F5143DAD9411BF +:10B7A00007D5330ED1FCD20A9B247207654C1104D5 +:10B7B0002F74B0007CAA892546D2282210FAC71E11 +:10B7C000DA21671BA44906186E71A5143899441133 +:10B7D00002C1E30DCCE8820A961022076038C1034B +:10B7E0002A60600080BAC9254AE26822140A081F4C +:10B7F000DE31A71BA85946187281E5143CA98411B3 +:10B8000006D1230ED0F8C20A9A20620764480104C8 +:10B810002E70A0007DAE992547D6382211FED71E86 +:10B82000DB25771BA54D16186F75B514399D54117E +:10B8300003C5F30DCDEC920A97143207613CD10396 +:10B840002B6470007FB6B92549DE58221306F81E16 +:10B85000DD2D971BA7553618717DD5143BA57411A6 +:10B8600005CD130ECFF4B20A991C52076344F103BD +:10B870002D6C90007EB2A92548DA48221202E81EFB +:10B88000DC29871BA65126187079C5143AA16411CA +:10B8900004C9030ECEF0A20A981842076240E103E1 +:10B8A0002C68800000000000000000000000000084 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C24000B42E0100C40B0000B42F01000000000058 +:10C25000B42E010080090000783B010000000000BE +:10C26000020000000000000001000000FFFFFFFFCF +:10C2700004000F0007000000000000110100000092 +:10C28000AA000000FFFFFFFF4040404040409001F7 +:10C290009001900190019001900190019001900116 +:10C2A00010001E00320023003200C70032003300AD +:10C2B0003C003C00900190019001900190019001A0 +:10C2C0000200201C01000000503D02000C3D020055 +:10C2D000503D0200103D0200AA00AA0002000F001B +:10C2E0001E000F003C0014007800780000000000E1 +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F0000009F61224380460090E0A000101010812F1 +:10F01000240038046C090000000C0000000000000F +:10F0200000004B5900000000000000000009010A28 +:10F0300000013C4388020000281E21000008FC005B +:10F040000008FC000008FC000008FC000008FC00B0 +:10F050000008FC000008FC000008FC000000FC00A8 +:10F060000008FC000008FC000008FC000000FC0098 +:10F070000008FC000008FC000008FC000000000084 +:10F08000000101000000000000000000000000007E +:10F09000000000000000000000000101010101006B +:10F0A0000001010101000101010100010000010056 +:10F0B00001000000000000000F0000000107010334 +:10F0C00002030A00320A400000003200370000004C +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000C800C8009600C80032 +:10F0F00007078000800005050000000000000000F8 +:10F1000007010000DBFF00004100F1FF10001400C8 +:10F11000F9FFC4FFFF7FFF7FFF7FFF7F96002C0179 +:10F1200096003C000A04CECE3232280500000000D2 +:10F1300000071600002416000000001224242424D6 +:10F1400024242424242424242424242424240000C7 +:10F1500000000000000000000000000000000000AF +:10F160000A05000A0000000020010014111400002C +:10F17000000000000000000000000000000000008F +:10F18000000000000F23283C465000006E696664B2 +:10F190005050505008000000000000000F23283C91 +:10F1A000465000006E696664505050500F141E287F +:10F1B000000000000A0A0A0A0A0A0A0A0F1E32465A +:10F1C00000000000645F553C3C3C3C3C00000000FB +:10F1D00008081A00A000EAFF15009D008300100E29 +:10F1E00000000000001000003C00320090012800E8 +:10F1F0000F000F001C023D011C02740400003704C4 +:10F2000000005F09F4010000370400005F093214B8 +:10F21000021E1E3202009B00280028007700C00357 +:10F220007700E808000000003804300020000100EA +:10F23000220000003A00520070008F00AF00CF00A3 +:10F24000EF000F012E014F016E018E01AD01CE01C5 +:10F25000EC010F022D024D026D028D02AC02CC02B8 +:10F26000EB020B032B034A036A038903AA03C903B6 +:10F27000E703FF0337040000000000000000000067 +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F000000000000000000000006C093000460023 +:10F300000100480000003C00430066008500A900A1 +:10F31000C800E90009012A0149016B018901AB011B +:10F32000C901EB0109022B024A026C028A02AC02FB +:10F33000CA02EC020B032D034B036D038B03AE03D8 +:10F34000CB03EE030C042F044C046F048B04AF04B6 +:10F35000CC04EF040D0530054D0570058D05B00595 +:10F36000CD05F1050D0630064E0672068E06B10675 +:10F37000CE06F2060F073207500773079007B30750 +:10F38000D107F40711083408520875089108B1082C +:10F39000C608E708000000000000000000000000B0 +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D00002020500F16C0000409C000000F91500DD +:10F3E00029B1010010270000C4090000010101013A +:10F3F000010101010101014B0F004B000000000061 +:10F40000020101010101010101010100F16C000093 +:10F410000200000084DE0100000000000F0F0A0A55 +:10F4200028000000000000000F0F1414010101016A +:10F43000010140003200E8030F0008000500E10070 +:10F4400000001E288C00B40019006400640028002D +:10F450007800000000000000B4007800E8034006D7 +:10F4600000000001410100000000000068010D0DD6 +:10F470000A093C0019006400140064002C016400B7 +:10F480002C010F02E8E8F800F80008041900000059 +:10F49000DB00ED0000011401290140015801720157 +:10F4A0008D01A901C801E8010A022D0252027A0267 +:10F4B000A302CE02FB022A035C038F03C503FD03F4 +:10F4C00036047304B104F10434057805BF05080659 +:10F4D0005306A006EF063F079207E6073B0893088E +:10F4E000EB084509A009FC09580AB60A140B720B6F +:10F4F000D10B2F0C8D0CEB0C490DA50D010E5B0EE5 +:10F50000B40E0C0F610FB50F06105510A110EA10C4 +:10F5100031117411B411F01128125D128D12B9124B +:10F52000E112051324133E1354136513711378135A +:10F530007B13DB00ED00000114012901400158019B +:10F5400072018D01A901C801E8010A022D025202CF +:10F550007A02A302CE02FB022A035C038F03C503D7 +:10F56000FD0336047304B104F10434057805BF05C6 +:10F5700008065306A006EF063F079207E6073B087A +:10F580009308EB084509A009FC09580AB60A140BB0 +:10F59000720BD10B2F0C8D0CEB0C490DA50D010E30 +:10F5A0005B0EB40E0C0F610FB50F06105510A110B5 +:10F5B000EA1031117411B411F01128125D128D127C +:10F5C000B912E112051324133E135413651371137A +:10F5D00078137B136A00750081008E009D00AC00DB +:10F5E000BD00CF00E200F7000D01260140015C01E3 +:10F5F00079019901BC01E001060230025B02890237 +:10F60000BA02EE0224035D039A03D9031B046004CB +:10F61000A904F40443059505E90541069C06FA068C +:10F620005B07BE0724088D08F8086509D409450A58 +:10F63000B80A2D0BA20B190C900C080D800DF80DBB +:10F640006F0EE60E5C0FD00F4210B31021118C111B +:10F65000F4115912BA1217137013C41313145D1452 +:10F66000A114E01418154B1577159C15BB15D4156E +:10F67000E515EF15F3156A00750081008E009D00F9 +:10F68000AC00BD00CF00E200F7000D0126014001F3 +:10F690005C0179019901BC01E001060230025B02C4 +:10F6A0008902BA02EE0224035D039A03D9031B0404 +:10F6B0006004A904F40443059505E90541069C0688 +:10F6C000FA065B07BE0724088D08F8086509D40907 +:10F6D000450AB80A2D0BA20B190C900C080D800DD1 +:10F6E000F80D6F0EE60E5C0FD00F4210B310211113 +:10F6F0008C11F4115912BA1217137013C413131486 +:10F700005D14A114E01418154B1577159C15BB1545 +:10F71000D415E515EF15F315550055004B004700BE +:10F72000000000004B007D00DC001400050000001C +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000900000090 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F860000000000000000000000000000000000098 +:10F870000000000000000000000000000000000088 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF000000000000000000000000000004E565409 +:020000022000DC +:1000000066665A4285CB2B43C3F500400C00B740CF +:100010000000000000000000000000000A000000D6 +:1000200000000000000000000000000000000000D0 +:10003000002492000000000020508B01907B0205FC +:1000400041525B14810B00000042525B14810B0093 +:10005000000043525B14810B00000046525B148188 +:100060000B00000047525B14810B000000000000F1 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:100100000000000000001101101500002002100185 +:1001100000003003000200008004000300004005DE +:10012000000400005006000000006007000000000E +:1001300070080000000090000000000000100100A6 +:100140000000022000000000030000000000040086 +:100150000000000005000000000006000000000094 +:100160000700000000000800000000000900000077 +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C00000000000000054140000000000000000C7 +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:00000001FF diff --git a/firmware/j20s_novatek_ts_mp01.bin.ihex b/firmware/j20s_novatek_ts_mp01.bin.ihex new file mode 100644 index 000000000000..3b31ac112228 --- /dev/null +++ b/firmware/j20s_novatek_ts_mp01.bin.ihex @@ -0,0 +1,8707 @@ +:100000000001000000000000032E0100008101003B +:1000100040710200EF41000042A31B91D34442E231 +:1000200000000000A000000002000000000000002E +:10003000708F020000000000309F01000C52006829 +:10004000707B020000000000308B0100DFD4CD592E +:10005000709902000000000030A90100DFD4CD59E2 +:10006000042E0100840C0000042F01007B7BE23988 +:100070000000020080090000883B0100885873C717 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F00040700200FF00000000000000804F0388F5 +:10010000480001EA400000094000000940000009E1 +:100110003AFFBFFC3A0FA83C4400000148000190A0 +:100120003AFFBFFC3A0FA83C440000024800018897 +:100130003AFFBFFC3A0FA83C44000003480001808E +:100140003AFFBFFC3A0FA83C440000044800017885 +:100150003AFFBFFC3A0FA83C44000005480001707C +:100160003AFFBFFC3A0FA83C440000064800016873 +:100170003AFFBFFC3A0FA83C44000007480001606A +:10018000480000004000000940000009400000094C +:100190003AFFBCBC3A0F943C440000004800017197 +:1001A0003AFFBCBC3A0F943C440000014800017483 +:1001B0003AFFBCBC3A0F943C440000024800016C7A +:1001C0003AFFBCBC3A0F943C44000003480001597C +:1001D0003AFFBCBC3A0F943C440000044800015C68 +:1001E0003AFFBCBC3A0F943C44000005480001496A +:1001F0003AFFBCBC3A0F943C440000064800014161 +:100200003AFFBCBC3A0F943C440000074800013957 +:100210003AFFBCBC3A0F943C44000008480001314E +:100220003AFFBCBC3A0F943C440000094800012945 +:100230003AFFBCBC3A0F943C4400000A480001213C +:100240003AFFBCBC3A0F943C4400000B4800011933 +:100250003AFFBCBC3A0F943C4400000C480001112A +:100260003AFFBCBC3A0F943C4400000D4800010921 +:100270003AFFBCBC3A0F943C4400000E4800010118 +:100280003AFFBCBC3A0F943C4400000F4800010404 +:100290003AFFBCBC3A0F943C44000010480000FCFC +:1002A0003AFFBCBC3A0F943C44000011480000E9FE +:1002B0003AFFBCBC3A0F943C44000012480000E1F5 +:1002C0003AFFBCBC3A0F943C44000013480000D9EC +:1002D0003AFFBCBC3A0F943C44000014480000DCD8 +:1002E0003AFFBCBC3A0F943C44000015480000D4CF +:1002F0003AFFBCBC3A0F943C44000016480000C1D1 +:100300003AFFBCBC3A0F943C44000017480000B9C7 +:100310003AFFBCBC3A0F943C44000018480000B1BE +:100320003AFFBCBC3A0F943C44000019480000A9B5 +:100330003AFFBCBC3A0F943C4400001A480000A1AC +:100340003AFFBCBC3A0F943C4400001B48000099A3 +:100350003AFFBCBC3A0F943C4400001C480000919A +:100360003AFFBCBC3A0F943C4400001D4800008991 +:100370003AFFBCBC3A0F943C4400001E4800008188 +:100380003AFFBCBC3A0F943C4400001F480000797F +:100390007E0500007E050000260A0000FC08000023 +:1003A000FC080000FC080000FC080000FC0800003D +:1003B000FC080000FC08000000000000E005000050 +:1003C000E8050000140C0000080D0000F405000012 +:1003D000480D00007E060000A2060000AA060000EC +:1003E000B2060000BA060000FE0D0000C2060000C2 +:1003F000180E0000CA060000EE060000C807000044 +:10040000D4070000240800002C0800002C0E000077 +:10041000460E0000600E00008E080000900E0000E6 +:10042000D8080000E0080000E2080000EA08000028 +:10043000B20E0000EC080000F40800006412A402F0 +:10044000642204023A1F883C803F442002983821ED +:100450000202643200029ED964320003DD2264028B +:100460000043640000083A1F88046412A403642255 +:1004700004033A0FA8043AFFBFC4640000044420F8 +:1004800002BC38210202DD223A0F94043AFFBC84F8 +:10049000640000046412A402642204023A1F883C2F +:1004A000442002BC38210202643200029ED9643228 +:1004B0000003DD2264020043640000083A1F880440 +:1004C0006412A403642204033A0F94043AFFBC8428 +:1004D000640000044FF2001D3A0FA83C3AFFBFFC35 +:1004E00045D2CA30801F64126402965F9E49C105DE +:1004F0003CFD4E18480000043CFD4E19E809DD2F74 +:10050000C8073AFFBFC43A0FA8046400000464029D +:100510002402441F3FFFFE0E5800400064022403E3 +:100520006400000845D2CA3045F3000044F00536A7 +:100530004EF20003DD2F3CFD4E1ADD2F640FFFEA63 +:100540003A6F98BC4402B3304462E1C49AB084204C +:1005500049009420440FFFAAAE313A6F9884DD9E83 +:100560003BFFFE3CEFFC84003C0FFAC03C0FFAC896 +:100570003C0FFACC3C0FFAD03C0FFAD93C0FFADD15 +:100580003C0FFAC63C0FFAD13C0FFACD3C0FFAD61D +:100590003C0FFACE3C0FFACA3C0FFAC73C0FFAC226 +:1005A0003C0FFADB3C0FFADF3C0FFAD43C0FFAD5D4 +:1005B0003C0FFAD23C0FFABE3C0FFADC3C0FFACFEC +:1005C0003C0FFAC53C0FFAC13C0FFABF3C0FFAC40E +:1005D0003C0FFADE3C0FFAD33C0FFADA3C0FFACBB1 +:1005E0003C0FFAC36403000364030403641224028F +:1005F0009646C103640300034400400064022403E0 +:10060000641200028419FE0E6402000364000008F4 +:10061000640304024616F7805010807CFE0F6403CA +:100620000403640200025800000164020003EC04A9 +:100630003BFFFE04DD9E4403F04B843FAE40440389 +:10064000F0EDA6405A1801048420AE404413F0DABD +:10065000A608540000F0AE088404640304034403B5 +:10066000F0498425AE404403F04A44100053AE40A4 +:10067000640304025800400064030403DD9EDD9E11 +:100680004443F114B46492784031E008FE1FB6048C +:100690004403F13844300055AC404403F13A84201F +:1006A000AE404403F1048421B6404403F1364423B0 +:1006B000F04AAE404413F134A608960EC803AED0FB +:1006C000D5FC4403F134A6009606DD9E924284A038 +:1006D000D207383016023830960A8CA1D5FADD9E42 +:1006E00084013C0FFAC0DD9E3C0DFAC88C013C0F22 +:1006F000FAC8DD9E3A6F9ABCEFFC490004C6C014EC +:100700008400490004C6490004D75A08010E3C0F72 +:10071000FAC94412B3AD3C0DFA9A4422B5103C3DDF +:10072000FAA449008F29490004A7C00784013C0F9F +:10073000FAD88400490004A4490004FCC0148400D1 +:10074000490004FC490004B85A08010E3C0FFABFE6 +:100750004412B3AD3C0DFA9A4422B5103C3DFAA4C4 +:1007600049008F0A490004DDC0078400490004DD08 +:1007700084013C0FFAC1EC043A6F9A84DD9E840137 +:100780003C0FFADD4403F082A600C00B3BFFFCBC2B +:10079000EFFC440000694900050BEC043BFFFC84BE +:1007A000DD9E84013C0FFAC6DD9E84013C0FFAD128 +:1007B000DD9E84013C0FFACDDD9E84013C0FFAD60C +:1007C000DD9E84013C0FFACADD9E4403F04B843F5A +:1007D0003BFFFCBCAE408401EFFC3C0FFAC244007E +:1007E0000069490004E5EC043BFFFC84DD9E3C0D00 +:1007F000FAC45A08010884203C1FFAC43E07E916CF +:10080000D50484023E07E9164403F04BA6405A1073 +:10081000FF05843FAE40D5FF84013C0FFAD784002A +:100820003C0FFADB3E07E9183C0DFA9A3BFFFCBC93 +:10083000A601EFFC5A00040A49002A9D5A08010645 +:10084000490046F73E07E9483C0DFA9AA6415A1876 +:1008500003392E17E9525A180135A6005A080132F9 +:100860002E07E9139600C82D3C1DFAB6A6485A1863 +:1008700001293C1DFAABA6485A1801243C0FFADCAA +:100880002E07E9255A0801064402B3A449006BC1AA +:100890002E07E97FC0042E07E948C8133C0DFA9AD9 +:1008A0008420490009813C0DFAB68420AE402E0711 +:1008B000E962C8043C1DFAABAE08840149002A7500 +:1008C000EC043BFFFC84DD9E3C0DFADB8C013C0F0D +:1008D000FADBDD9E84013C0FFACB3E00041C44038E +:1008E000F07E3BFFFCBCA640EFFC5A10010FA64077 +:1008F0005A10020CA6405A100309A6405A100406CA +:10090000A6405A101003A600844184208062808291 +:100910004400B1014900707B49007090EC043BFF3A +:10092000FC84DD9E84013C0FFADFDD9E3A6F9EBCA5 +:1009300084E14403F0643C7FFAD4A780FFBECE1E5E +:100940004413F010AF88A640FE7FAE403C0DFA9AEB +:10095000A6005A00021B49002A213C0DFA9A842E57 +:10096000AE418426AE4080274900091E84028026BD +:10097000FD13FD23490004FED508A6409646C10597 +:10098000A640541080FEAE403A6F9E84DD9E3A6FC2 +:100990009ABCEFFC4900048E5A0802143C5DFADC54 +:1009A0002E000D12D0063C0DFA9AA6015A08040A30 +:1009B0004900463F3E07E9264900081E3E07E91860 +:1009C00084013C0FFADA3C0DFADC8C013C0FFADCB6 +:1009D000EC043A6F9A84DD9E84013C0FFAC5DD9EDB +:1009E000DD9E84013C0FFAC4DD9EDD9E84013C0F38 +:1009F000FAD3DD9E84013C0FFAC3DD9E4403F04B25 +:100A0000843F3BFFFCBCAE404403F0ED8420EFFC90 +:100A1000AE4044000069490003CBEC043BFFFC847A +:100A2000DD9EEFF0F081F001441003E8FE0C500071 +:100A30007C614410009340000437F08340000009BB +:100A4000F0039E41F183C8FB4403F04A4410005573 +:100A5000AE40EC10DD9EEFF0F081F001441003E8B1 +:100A6000FE0C50007C614410009340000437F0837A +:100A700040000009F0039E41F183C8FBEC10DD9EAD +:100A8000EFF0F081F101460000F450000240FE0C4E +:100A900050007D3A4410024440000437F083F003D4 +:100AA000441186A040100417C8064403F04A4410BD +:100AB0000055AE40F0039E41F183C8F2EC10DD9E7C +:100AC0003C1DFA37A6088C01AE083C1DFA37A60873 +:100AD0009606C8063C0DFA393C0FFA36D5053C0D92 +:100AE000FA383C0FFA363C0DFA36A64880A01010B2 +:100AF000003F8420181280015000003C1812800131 +:100B0000D8FEDD9E3C2DFA36A65098D1AE199C0930 +:100B100096005CF0003BE9028400AE10A61088400D +:100B2000841FAE11DD9E3A6F9EBC84008020490078 +:100B3000029684006405E4034403F00EA440964E3C +:100B4000C90FA4409656C90CA440965EC909A4409A +:100B50009666C906A400540001004E0200BA441370 +:100B6000F00EA408960EC806A5C85473810097F924 +:100B7000C72144122D508400A7C8AC0844122CF0A1 +:100B80003E07E93AAE0844122CF197F8AE08441239 +:100B90002CF2AE0844122CF3AE0844122CF4AE082A +:100BA00044122CF5AE0844122CF6AE0844122CF771 +:100BB000AE0849FFFCC74403F00EA440964EC90896 +:100BC000A4409666C905A40054000100C00349FF73 +:100BD000FF7944022D608420AC4084C04402704000 +:100BE0003C6FFABF3C0FFAA53C6FFAC13C6FFAD7D5 +:100BF0005A78AE4384E33C0DFAA594BC8840A051DA +:100C0000C10CB4029649A09349FFFD3C5A08010665 +:100C100040001C0CFF8797B18CE15A780FEE3C2DF9 +:100C2000FAA50411003D0401003C8E2496490421DC +:100C3000003F49FFFD275A08010544008000FF8757 +:100C400044022D788420AC40C61744022D60441F16 +:100C5000FF9FAE4044022D619670AE4044022D626B +:100C600092C8AF804403F04A44100055AE4044009F +:100C700000694900029D44028F7044122D78FA5495 +:100C800049FFFD263C0DFAA544322D7C44222D7DE2 +:100C900004000009401020093E07C55D3E17C55EEF +:100CA0004010400992183E17C55F3E07C560A61860 +:100CB000A6509602964AAE58AE1044322D7E44227B +:100CC0002D7FA618A6509602964AAE58AE10441331 +:100CD000F00E3C0DFA36A6481010003C4413F00FFD +:100CE000A6481010003D4900033D9E81E6483C0F98 +:100CF000FAAEE80C84214010880C5410808FC10695 +:100D000050007FE0960049FFFEFF49008FA83A6F30 +:100D10009E84DD9E3A6F9ABCEFFC490002CB5A00DC +:100D200002243C0DFA9AA6005A00021F2E00042E3F +:100D30008C019600E606E91984003E00042E490065 +:100D4000282D3C0DFA9A842EAE418426AE40842193 +:100D50004900072A8420846184028041808180A325 +:100D600049000308D50484003E00042E3C0DFACC53 +:100D70008C013C0FFACC3C0DFA9AA6008E01E602DB +:100D8000E83D2E07E9405A0055062E07E9365A0875 +:100D9000552C3C03F4DA8C019601E60A3C0BF4DA9C +:100DA000E926840449FFFEB084013E00045C84000F +:100DB000490027FB3C0DFA9AA6005A000219490087 +:100DC00027ED3C0DFA9A842EAE418426AE40842154 +:100DD000490006EA8420846184028041808180A3E6 +:100DE000490002C8D50484003C0BF4DA44000055E5 +:100DF0003E07E9403E07E936D50484003C0BF4DAAF +:100E0000EC043A6F9A84DD9E3BFFFCBCEFFCFA10C9 +:100E100049FFFE7A84013C0FFAD0490001DB49000A +:100E200027BD3C0DFA9A8422490006BE490027D40A +:100E30008420840284468061808180A14900029AD6 +:100E4000EC043BFFFC84DD9E3A6F9ABCEFFC3C1D3A +:100E5000FAB684013C0FFAD9AE08440FFFAA3E0748 +:100E6000E940490002273C2DFA9A5A0802153C1322 +:100E7000F4EF3C03F469E220E80EA6118E03E602CB +:100E8000E80A2E0004398C213C1BF4EF5A080104B7 +:100E90003E07E94D84003C0FFAD7A611540000FD2F +:100EA0005A000406800284214900067E4900276911 +:100EB000C80A2E17E9303E07E98D5A1801113E077E +:100EC000E98BD50D840949FFFE1FFA1849FFFDABD8 +:100ED00084024900403284013E07E9622E07E97F1F +:100EE0005A0001062E07E9255A0801072E07E9894D +:100EF0008C013E07E989EC043A6F9A84DD9E3BFF42 +:100F0000FCBCEFFCFA1249FFFDFFEC0484013C0F2E +:100F1000FACE3BFFFC84DD9E3BFFFCBCEFFCFA13EA +:100F200049FFFDF2EC043BFFFC84DD9E3BFFFCBC73 +:100F3000EFFCFA1549FFFDE8EC0484013C0FFAD5FB +:100F40003BFFFC84DD9E3BFFFCBCEFFCFA1649FF37 +:100F5000FDDBEC0484013C0FFAD23BFFFC84DD9EF8 +:100F60003BFFFCBCEFFCFA1749FFFDCE84013C0FB0 +:100F7000FABE490084295A08A106440000554900D8 +:100F80000117840249003FD9EC043BFFFC84DD9E3D +:100F90003BFFFCBCEFFCFA1849FFFDB684013C0F97 +:100FA000FACF4400005549000103EC043BFFFC84E8 +:100FB000DD9E3BFFFCBCEFFCFA1949FFFDA5840157 +:100FC0003C0FFADE49003E0C490026D5C804490012 +:100FD00026E5D50349003DDBEC043BFFFC84DD9EA8 +:100FE000FC2080C14413F04A80E244200055AE88C2 +:100FF0005A08020749000090C8FE64030403440332 +:10100000F04A441000554433F04BAE40A6185A0045 +:10101000FF05841FAE18D5004443F0DA97B0A62030 +:10102000540000F0402380044403F0ED9690AEA0FD +:10103000AF80A6185A00FF05841FAE18D5004403E0 +:10104000F041AE40400000094000000940000009A6 +:101050004000000940000009FCA0944D4423F042E8 +:10106000FE0F9600A6D0AE10DD9E4413F046AE08EB +:10107000DD9E00004403F0C4A600DD9E4413F0C4CE +:101080009600AE08DD9E4403F0C3A600DD9E441327 +:10109000F0C39600AE08DD9E4403F0CE4413F0D0BA +:1010A000A400A6489407FE0F441DD30088015C00ED +:1010B0000041DD9E4403F0CE4413F0D0A400A648C6 +:1010C0009407FE0F441DD2B088015C000001DD9E34 +:1010D00044022D00DD9E4403F0CE4410045AAC407F +:1010E0004403F0D08420AE404403F0C7843FAE40B8 +:1010F000DD9E4413F0E6AC08DD9E4403F0F5842148 +:10110000AE404413F04A44200055AE88A6405A1021 +:1011100001FFDD9E4403F0F4A6009204DD9E44032B +:10112000F0F7A600DD9E4413F0F79600AE08DD9EB2 +:101130004403F0F6A600DD9E4413F0F69600AE08D8 +:10114000DD9E44522D0044122D3E18028001D9FE2E +:10115000DD9E3A6FA8BC44004000640304034400D1 +:1011600000FD49FFFFF04413F04B841FAE0844A379 +:10117000F0CE4480045A812180E04463F0681285F7 +:10118000000010748000A630520000014900003FAA +:10119000440009C449FFFC61A63052000001490027 +:1011A0000036440009C449FFFC58D5E83BFFFCBCAD +:1011B000EFFC49FFFFD092004423F0EC9606A650C6 +:1011C0009402541080FBFE0FAE10DD9E48FFFFF628 +:1011D000C80844122CF5A6088C019600AE08D50F5D +:1011E00044222CF6A6508C219648AE505A0801088D +:1011F0004413F060A60858000004D5064413F060BC +:10120000A608540000FBAE08DD9E4413F06896006B +:10121000AE08DD9E4423F0539606A650541080FE7F +:1012200088019600AE10DD9E4433F0404443F00E3A +:10123000A69884A05421001CFE579648AD60AE5875 +:101240004413F06A9606A688542100FEAE88A6884C +:1012500088029600AE08DD9E4403F061A600960F5A +:10126000DD9E4423F06DC9038425D5028424AE504D +:101270009444FE0F4413F06E9600AE084413F06FD2 +:10128000AE08DD9E4403F06D8420AE40DD9E440335 +:10129000F061A60092039606DD9E4403F061A6006D +:1012A00092029606DD9E4403F061A6009207DD9E41 +:1012B000FC0049FFFFFAC80749FFFFF15A00010689 +:1012C0008401D5048400D5028402FC802E00043AF7 +:1012D0002E5004183BFFFCBCEFFCD00FC8064400A6 +:1012E000005249FFFC11D5054400005149FFFC0C98 +:1012F0002E00043A3E0004182E0004382E50041923 +:10130000D00FC8064400005449FFFBFED505440039 +:10131000005349FFFBF92E0004383E0004192E004B +:1013200004392E50041AD00FC8064400005649FF55 +:10133000FBEBD5054400005549FFFBE62E000439C0 +:101340003E00041A2E0017955A00AA08EC048407E0 +:101350003BFFFC8448FFFBD8EC043BFFFC84DD9E94 +:1013600048003D344403F04A44100055AE40DD9E31 +:101370003BFFFCBCEFE4F081F1828005F101F283D8 +:10138000F384F48549FFFF52F002F10349FFFE6741 +:101390004403F04A44100055AE40F001F104F20558 +:1013A000EC1C3BFFFC8448FFFE1D3A6FA0BC80E0B4 +:1013B00084C0E2C7E80C8401844080208062808081 +:1013C00080A28CC149FFFFD697B0D5F43A6FA084B4 +:1013D000DD9E48FFFE7F3BFFFCBCEFFC49FFFE5E4D +:1013E000EC043BFFFC84DD9E2E000432C80A3BFF68 +:1013F000FCBCEFFC49FFFE90EC043BFFFC84DD9E4F +:101400008400DD9E48FFFF032E07C66EC8143BFF15 +:10141000FCBCEFFC2E07C54B49FFFEF9FA0949FF5A +:10142000FB022E07C54BEC04520000013BFFFC847D +:1014300048FFFEEDDD9E48003F8448003F774412A0 +:101440004000B62044124C60A84544120C60A846E7 +:1014500044121B90A84244124B40A844441237FC4B +:10146000141000114412997014100012441220A09C +:10147000141000144412662014100015DD9E3A6FFB +:10148000A4BC80C044012D8CEFDC3A201400440140 +:101490002D9CB1C43A2F94203A201400813F3A2366 +:1014A0009420490040DCC0212E17C9CB2E07E92625 +:1014B0008E21E020E8029608381482024420004879 +:1014C0001413000A381382021413000B4412D24082 +:1014D00042100873440229001403000944022C60DE +:1014E000141300131403000CEC243A6FA484DD9E43 +:1014F000842C3A6FA0BCAE4184003C0FFAD3840127 +:1015000049FFFE684463F04A447000553C0DFAD32D +:10151000C00D8420846184028041808380A33A6F5F +:10152000A0843C1FFAD348FFFF2549003CE35A083A +:1015300001F2AFF0D5EC4413F01F4433F302A64898 +:10154000542080E0A6589667E001E806A658966702 +:1015500088229A0896804403F01FAE80DD9E3BFFF0 +:10156000FCBCEFFC49003CBDEC0484013BFFFC8467 +:1015700048003CBC3BFFFCBCA740EFFCD90C8CA155 +:101580009768E6A5E90284A0AF40440FFFAA3E0792 +:10159000E936D511840649FFFAB744122CF0A608A3 +:1015A0008C019600AE088400490023FF44000055DA +:1015B00049FFFDFE44022CF0A600C00484013E0059 +:1015C000045CEC043BFFFC84DD9EA6885A28AA0834 +:1015D000A680AE888420AE4048003E97DD9E3C0D3C +:1015E000FAAE5A0804273BFFFCBCEFFC49FFFE6241 +:1015F0005A0002142E07C5DB5A08011084003E076A +:10160000E91184003C0BF4DA4412B36B4402B36476 +:1016100049FFFFDD8403D505FA003C0FFAAE8405CF +:10162000EC0484203C2DFA9A3BFFFC84480036EC05 +:10163000DD9EA6885A20AA0DAE80442FFFAAAE8850 +:10164000A6005A08010448003E5948003E5EDD9E4F +:101650008440AE808400AC08DD9E4403F5608420A5 +:10166000AE404403F5618423AE4084008020804076 +:10167000806048003ABD4403F5608423AE404403D3 +:10168000F5618420AE408400802080408060480066 +:101690003AAF4403F007A6005A08720A4403F00464 +:1016A000A6405A100C12A6005A000E0F44022D60DC +:1016B000441FFF9EAE40842084028041846180816B +:1016C00080A148FFFE57DD9E3A6FA83C44012DAC37 +:1016D000EFDC3A2014003A2F942044212DBCB004B2 +:1016E0003A2114003A2014202E27E96038400A02DB +:1016F0002E000431C83484613E30043195524432A6 +:10170000714044624510383194004472AD7096D8EF +:10171000385F8A0281203C13E2BAE201E82094415A +:1017200040A09800882702850000A44838220101C3 +:10173000964B8A22382280004224082440210C0E35 +:10174000882296491215000002150000964B4E148F +:101750000004129500008C019601D5DEEC243A6F4E +:10176000A804DD9E3C23E2BA4412451084A0D210A6 +:10177000A4080230EB408C228A0396034E04000337 +:10178000FE025EF00051E8068CA19769D5F1840055 +:10179000DD9E8401DD9E8421480044553BFFFCBC56 +:1017A000EFCC96D0FA4084A08481F2858442F58300 +:1017B000F584F586F287F588F589B67FF481F382A2 +:1017C000F48A804180A4490038ECEC343BFFFC846F +:1017D000DD9E3A6F98BC44228F70EFD00031000F2D +:1017E000FAC00041001084A18440F68584C2F283CF +:1017F000F284F286F687F288F289B67FF581F38269 +:10180000F58A8041490038CDEC303A6F9884DD9EEE +:1018100084213E17E98B540000FB84203E100431E4 +:10182000C807440200004412451048FFFFD4440298 +:10183000000044120002442245102E37C54F2E47A7 +:10184000C55084A04800394F3C1DFA9A3A6F98BCA5 +:10185000A64980C049FFFFDE5A6803092E07C66EFD +:10186000C8053A6F988448FFFF313A6F9884DD9E2F +:101870003BFFFCBCEFFC4402451044121B9049FFA7 +:10188000FFAA44021B904412400049FFFFA4EC044D +:1018900044020A2044124A20442000483BFFFC84B2 +:1018A00048FFFF7E3A6F98BC44428F70EFD00062D1 +:1018B000000F84A000420010F581F582F583F584C5 +:1018C000F586F588F58984A1B6DFF285F387F58A78 +:1018D0008066804149003865EC303A6F9884DD9E1F +:1018E0003BFFFCBCEFC484A0F38DFA608082F385DB +:1018F00084418462F281F482F387F28AB6BFF58371 +:10190000F584F586F588F58980648041F40D4900F9 +:101910003848EC3C3BFFFC84DD9E3BFFFCBCEFBC4D +:10192000F18EF08D8023F28F2E37C54FC4052E47E0 +:10193000C5508003D50380048481B61F84A1F08242 +:101940008400F083F184F085F086F088F089F08AD5 +:10195000F581F587F00DF10EF20F49003822EC44C5 +:101960003BFFFC84DD9E3A6FAABCEFFC006F802435 +:1019700001EF8020F689026F801C00FF8028F68E20 +:10198000006F803C008F802C00AF8030009F80343F +:10199000F68F23CF8020227F8022006F804815EFB2 +:1019A000800814FF800A148F800B14AF800C149FE2 +:1019B000800D15CF8010F791F692EC043A6FAA844F +:1019C000480037EF3A6F9CBCEFD444628F700073CD +:1019D000000F00630010F381B0C7F3848460B6DFAA +:1019E000F482F583808380A749003767EC2C3A6F37 +:1019F0009C84DD9E3A6FA0BC4473F423A67897883C +:101A000049FFFC47C0045413001FD505A67896670C +:101A10008E2196482E200D012E000D124000081731 +:101A20002E27E926E642E9083C2DFA9AA6915A2883 +:101A300004048C019600400004063A6FA084DD9EE9 +:101A4000FE0C4420007840000817DD9E3C23F47C07 +:101A5000FE0C40000817DD9E3A6F98BC44012DCC67 +:101A6000EFF83A200C003A2F8C2049FFFBF7385F43 +:101A700081013C13F47D3C5BF47D3C1BF47CD13C48 +:101A800050007F80960049FFF83F3C0DFA9D4900C9 +:101A90003D683C03F47D4420016844400078FE84A6 +:101AA000402110573C2BE4D63C2C01113C33F47CF4 +:101AB00044101C20FE84FE4440210C5740109037F7 +:101AC0003C2E01113C1BF4693C2C01123C13F4EF39 +:101AD000FE84FE0C40210C5740000C173C2E0112D6 +:101AE0003C0BF4EF490067B94900682DEC083A6FE8 +:101AF00098844800168BEC083A6F9884DD9E3BFF73 +:101B0000FCBCEFF45A0801173C0DF16D3C1DF16867 +:101B1000B61F3C0DF16E3C2DF169F0813C3DF16A40 +:101B20003C0DF1673C4DF16B3C5DF16C490039E6D1 +:101B3000D5153C0DF1653C1DF160B61F3C0DF166FD +:101B40003C2DF161F0813C3DF1623C0DF15F3C4D7B +:101B5000F1633C5DF164490039D18400802080400C +:101B600080604900382BEC0C3BFFFC844800380FA8 +:101B70003BFFFCBCEFFC49008B164403F705441FF8 +:101B8000FFA5AE40EC048420AE403BFFFC84DD9E0C +:101B90004423F0779606A650541080FEFE0FAE1038 +:101BA000DD9E00004423F04A3BFFFCBC443000555E +:101BB000AED0EFFC4433F380A6985A2001FF4E13B9 +:101BC000008DA6018E01E60E4EF200D544F01ADC1F +:101BD0003807810140F03C004A003C001C0096019F +:101BE000CC009200CC0092009601280028009E00B4 +:101BF0009E009200CC00D800EC0484023BFFFC84E1 +:101C00004800399B840149FFFB07840049FFFF79A5 +:101C10002E07E9212E17C9C35A0001072E07E969CB +:101C20008E04E602E811E624E8064400088E49FF27 +:101C3000F6FAD518E62DE8168E22440003E8FE0CCD +:101C400049FFF6F1D50FE624E80484018424D50485 +:101C5000E62DE808840184408062808280A049FFEC +:101C6000FB89840149FFFA03840149FFFF93EC04D7 +:101C700084003BFFFC8448003960840149FFFF8AEF +:101C8000840049FFFF3E2E07E9215A08010744005E +:101C9000088E49FFF6C8D5098440840184248062F7 +:101CA000808280A049FFFB66EC0484003BFFFC843B +:101CB00048003A5D8440840180A02E17C9C3806229 +:101CC000808249FFFB57840149FFF9D1EC0484006D +:101CD0003BFFFC84480039315A180142A6018E03AB +:101CE000E60CE84844F01BF43807800040F03C0064 +:101CF0004A003C00340C340C7E18182E2E7E3440E2 +:101D0000EC0484013BFFFC8448003917840149FF3F +:101D1000FEF88401490039114400003749FFF68379 +:101D2000D512840149FFFEEDEC0484013BFFFC84E5 +:101D300048003A1D840149FFFEE449FFFC908401FC +:101D4000490038FB840049FFFF25840049FFF98FD3 +:101D5000EC0484003BFFFC8448FFFA5E5A18020B37 +:101D60008401490038EAEC0484003BFFFC8448FF0E +:101D7000F97EEC043BFFFC84DD9E92002E07E91304 +:101D80005A08012E3A6F98BC49FFFA94C8263C0DB8 +:101D9000FAB6A6405A1801FFA6005A08011F3C0DCA +:101DA000FAABA78097B05A6801193C0DFA9A8429BA +:101DB000AE41842049FFFEF83C0DFA9A842AAE41D8 +:101DC0003C1DFAB68400AE083C1DFAABAE08800696 +:101DD0003A6F988448001FE93A6F9884DD9E3C0D65 +:101DE000FA9AA6415A1006292E17E925C9253A6FF5 +:101DF00098BC2E67E97FCE1E3C1DFAB6A6485A183D +:101E0000011A3C1DFAABA6485A18011580263C6FF2 +:101E1000FADC49FFFEC93C0DFAB6AF802E07E96235 +:101E2000C8043C1DFAABAE0884013A6F98844800A0 +:101E30001FBC3A6F9884DD9E3BFFFCBCEFFC49FF62 +:101E4000FA395A080207EC043BFFFC8448FFFFC93B +:101E50003C0DFA9AA6015A000B07EC043BFFFC84E8 +:101E600048FFFF8EEC043BFFFC84DD9EA4408C21E8 +:101E700096495CF08190AC40E9203BFFFCBCEFFC54 +:101E8000840549FFF641840049001F8F49001F86E1 +:101E90003C0DFA9A842EAE418426AE40842149FF3F +:101EA000FE83EC048420846184028041808180A3CD +:101EB0003BFFFC8448FFFA5EDD9E00003C0FFAE128 +:101EC000DD9E3C0FFAE0DD9EFC00C0085A08010BC5 +:101ED000490039AF3C0FFAE3D505490039A73C0F5B +:101EE000FAE2FC808020E6293C0DFAE3E82544F084 +:101EF0001DFC3817840040F0BC00DD0F0A3C1016B2 +:101F00001C22282E34003C0DFAE2DD9E50000050C9 +:101F1000DD9E500000A0DD9E500000F0DD9E5000D0 +:101F20000140DD9E500001E0DD9E50000280DD9EFC +:101F300050000320DD9E8400DD9E9200FC52F18C57 +:101F400044112CA0F48EB11580C381423A208C0438 +:101F50003A220C24F08DA6488125AE6044112CACA9 +:101F6000B1183A208C043A220C24A64880E6AE60D0 +:101F70008420121F80293C2DFAE33C1DFAE249001F +:101F800039283C1DFAE0A60AA64B490039465CF305 +:101F90000100E903447000FF97F9800749003950B8 +:101FA00084C03C1DFAE100008010E2C0E810800609 +:101FB00038109800490039523C0DFAE198468006E5 +:101FC00000108008490039728CC1D5EC84004900AA +:101FD000393B490039118401490039364900390C2F +:101FE0005A9801472E37C54284C044007FFF97FBB3 +:101FF0002E47C543B67FF088501F8052F00D442213 +:102000006B3080A9F681F682F683F684F685F68633 +:10201000F687F789F68A490034C42E37C542441240 +:102020006B302E47C543B67FF38280A98041F00C08 +:10203000149F8001F683F684F685F686149F800748 +:10204000F688F689149F800A490034AB3C1DFAE2F9 +:102050003C2DFAE344026B30490038BB440004B025 +:10206000490038EE8402490038EF490038C549007C +:1020700038E3F10EAE082E00040CC8092E00040847 +:102080005A000204480000D7480000E787C0F00E5D +:10209000A60040FF0006E8F304150005400F0808FD +:1020A0008801A64000800002F193A641A603F191A9 +:1020B000F092F012E2084EF300B550047FFE5CF09F +:1020C00000204EF200A940041008F090F013F08DAB +:1020D000F10DF011E2014EF3009FF00D8E02E60CBF +:1020E0004EF20095F010F10DB46A98819411985851 +:1020F000F08FA60996064E02008AA7484C5F4087DB +:102100008420440007D0B1153842041088829721FA +:1021100095218883A761E6A4E80FA7200455000352 +:1021200038529101E005E902962B0455000238422D +:102130009101E687E9088C215A1809E784204E06A8 +:102140000006D51384214E070062F30C40F0040A08 +:10215000384189114430007F42F20C7340F781F618 +:102160005EF78074E853C952F00CB15B848038602C +:102170000911B0158420383010108001886296D97A +:10218000B1D538938410F70C89234094801338F329 +:10219000A511B1D8389384108C214207A4735A1822 +:1021A00009F1AA294E670009441001F4FE0C400011 +:1021B00018161402FFFF8C815A4809DD8440B15B78 +:1021C00084DE840044312CB880209913383200100A +:1021D0005A380109383282025EF1FF38E8038C2157 +:1021E00096485A180208B46AF70F8867A7D9FFF60D +:1021F000AFD98C015A0809ECB40AF10F8801A60185 +:102200009606C0048C495A2890DEF00D8C01960089 +:1022100048FFFF5F50040001548000FF48FFFF4B60 +:1022200051EF000148FFFF358C01F10EA648E20195 +:10223000E9183C1DFAE23C2DFAE3F00C490037C9DD +:10224000840349003801490037D7490037F5F10EBA +:10225000AE088400D5458400446F800084FED5E636 +:10226000042500039441382101015CF10056E80780 +:10227000042500018822A488FEB7AC880425000547 +:1022800094428822A68800808001F28D009080030D +:10229000A68AE322E9CA41E11008F10DE301E9173A +:1022A000405F0400B48A976994E98864A71954F2DE +:1022B0000001E80A04FF800C38F795115EF780569C +:1022C000E803FF3EAF198C219648D5E98C419690E2 +:1022D000D5E10415000138508101D8078C01F10EB9 +:1022E000A648E201E9F7D52B966B4E15FFF90425B8 +:1022F00000059442956A98D18845A6DAA712E2644F +:10230000E802AED20425000598D18845A6DBA713C4 +:10231000E283E802AED30425000538310400884585 +:10232000A710E264E802AED004250005882288A246 +:10233000A649A6A9E241E8D3AE69D5D1FCD23C0FAB +:10234000FB42DD9E3C0FFB41DD9EFC41444000FC16 +:10235000420190730040001854520001CD07B4C0F0 +:102360005A600105005000E0C51E4422B7248400D5 +:1023700038010C084422B714848138410C08A48821 +:102380004442B6D8A44938220E09949A8844AC51E4 +:102390004412B6C838008C084412B6B838008C080D +:1023A0004800018A5A6802494422B7144442B6C818 +:1023B00038610C004402B6B85A68010938520C085A +:1023C00038500C0838510C08D51738200C00E6425C +:1023D000E8058C4138200C08D50338500C08382209 +:1023E0000C00CA0A38200C005A2802074422B6C83A +:1023F000848138410C0838200C008083840F4241CE +:1024000000734422B6D822508000226080018004EC +:10241000945A38410E014472B60488229B2C3843EA +:102420008209A509940288079B34AD0138510E0931 +:10243000AD89480001415A6004044800013D5442FE +:1024400000FD104000184442B7144482B7243842BB +:102450000C005A48010A38440C0095998886446259 +:10246000B5C83853110938440C004E4300DD4452BE +:10247000B6C844A2B60438628C004452B6B838924A +:102480008C005A60010680E480A487CFD521955A3C +:10249000894580C480A484E14C54C00384E222F5C1 +:1024A00000008CA14243BC7322F50001976842638F +:1024B000BC7350A5003C5A5803F084A440421496C3 +:1024C000406314D63C4FFAE53C6FFAE4D51980C35B +:1024D0004262F87338F51A1195B288CA8CA122634A +:1024E00000019768888FE32588E6E8F28D21404255 +:1024F00024964073A4F63C4FFAE53C7FFAE444622C +:10250000B5C840A18808405328003C9DFAE5848066 +:1025100038430E09AD2980A94E940004525480001E +:102520003C7DFAE483C74E74000453E380003C4DC5 +:10253000FB4240F2F800A1219281E28F004000F3BB +:10254000F481E9048E8BE682E86E4E9700094442DE +:10255000B6D838F20E1152F7843FD5074E92000ECE +:102560004442B6D838F20E114440006442479024E9 +:10257000405214B69769D5034450FFFF4E77000AC6 +:102580004442B6D8888A22F2000152F7896BD507F7 +:10259000C70E4442B6D8888A22F200014440006443 +:1025A00042479024404278969721D5034440FFFF4C +:1025B00004FF800150F7FFF55CF78002E81C4E92A3 +:1025C0000003CF764452B6D82270800038428E1174 +:1025D000229080019B3C3C4FFAE54042A8003872B3 +:1025E0008E092212000112920001401484013C1F46 +:1025F000FAE4D55EE2A44042BC1B5CF20096E8051A +:102600008C8A38430E09D50F5CF2012CE8089281C0 +:1026100038430E0988CA8C8AAD31D505441000961E +:1026200038130E09001000F3E622E9035A180608D1 +:102630004412D55838108C00C935D50A38440C00DE +:10264000945988244452B5C838728501CF05842135 +:10265000101000DED527E6824452B6D8959AE816C7 +:102660003C4DFAE538128E01FF3C44900064404234 +:102670002496888138428E093C1DFAE4992EFE7C0E +:10268000A5E14010A4368827AC610010001858104E +:1026900080021010001838028E0188A6AC10A42900 +:1026A000AC1138040C008C0138040C08D5044440EB +:1026B00000C7D5AEFCC13C0FFC44DD9E3C0FFC4383 +:1026C000DD9E84003E07F108DD9E5A00016AFC2071 +:1026D0002E57F108D02F4430004480E242708C73B2 +:1026E0005061003F84804C4000264C12001F203374 +:1026F000803F20F300008A6F4E340003FEDA8E62C2 +:10270000E662E81320F37FFF2033803E8A6F8C61FE +:10271000E663E80B9EF30253801EA4D8E2A3E8050B +:1027200084011003803AD5388C819720506300448F +:10273000D5DB44300044808242408C738460D505F0 +:102740008C6196D8502100444C3000294C11BFFABE +:10275000B4A25CF2A711E9F5005100430062004207 +:102760008CA1E0A6E9EE00520043006100428CA17A +:10277000E0A6E9E700510041006200408CA1E0A61C +:10278000E9E000520041006100408CA1E0A6E9D9D7 +:1027900084021002003A8401D5058400D503840028 +:1027A000DD9EFCA0FC42A10D94D28864F1830081DF +:1027B000800000A18001A65A40552001F1818CA122 +:1027C000A65BE4A3F1824EF200B684603C4DFC436C +:1027D00005CF8001812380E380C3F102E03CE93032 +:1027E0004E82001500F2000283C843EE3C7340FFA6 +:1027F000040839E079114FE70003893E40F03C00BE +:1028000022F7FFFF4EF70003886F01E2000250FF3E +:102810007FFFE14FE812802A421E787339E00511EC +:1028200040F084084FE7000388DE40F03C0022F7C8 +:1028300080014EF7000388EF51CE0001D5CF5A50EA +:1028400001075A58022F2EF00467E82B878A43E1CC +:10285000F02440FF2407E80E42F3F02440F79807E5 +:10286000E8094E82000800F2000250F7FFFFE14F36 +:10287000E9635A580117F502F1018AA1E4A5E804B9 +:102880002E500467C50E40FF2407E9034E83000A5B +:1028900084AAFF7CE0A6E950A7628EA14CA2804DDD +:1028A0002E500467C50884AAFEECE069E945FFECF8 +:1028B000E0E6E942F103949100A20003A04C8841B4 +:1028C0008420A75180E181218441E04AE823A7A226 +:1028D00081054281187340340408388021114E84E8 +:1028E0000004528400008928C50A40800C0022841C +:1028F0007FFF4E8400045284000088E88EC1D60811 +:102900008860223180014E340003FEDA88238C4136 +:10291000D5DD5EF487D1E90B5EF38064E902CD0773 +:102920005EF08064E909A6228E01D00684003E0094 +:1029300004678401D5028400FCC2FC40A14D94D2FE +:1029400088A3A04C9491A6E88841A7A9A72AA6919C +:10295000A76BC3049E599648D50280239491884062 +:1029600080E48460E2A7E909409394088CE13891FF +:102970002401886996DBD5F7409210084470006402 +:10298000E2C1E92F54208001CA2A5A100729408049 +:10299000A40040840408890083848142E2BCE90FDA +:1029A00002F4000051CE0001894F02F4000140A55D +:1029B0000011884F969350840020D5F1E628E80551 +:1029C000E142E80D8A4AD505E04AE80940250801B8 +:1029D000FEBC40F10DF65EF78033E8058C21D5D1C1 +:1029E0008401D5028400FCC0FC4051FFF728F1852A +:1029F0008540501F84DCF382F284F48CF18180E006 +:102A000080C1810A8461F005E340F086E851F1025B +:102A100022038000224380011203000A1203000CEB +:102A2000A04BA0391243000B1243000D1033003BA2 +:102A30001083003A381081011403000B1213001E9A +:102A4000F10240900408F486A08D9442882250033D +:102A500000408444F38349008193F0028442A0043F +:102A6000892080295003003E4900818A005480015A +:102A7000F303F406C50C3C1DFC43A60A8E01D007E7 +:102A800000548000C504A60B8E01D8041033003515 +:102A9000D503108300355EF2091C800340043C1B03 +:102AA000100300368D41506300448CE8D5AD2E876D +:102AB000F1088400148F800350AF80688020509FFD +:102AC00080A4B1F8506F811C445000444432B73C9C +:102AD000F40142201424888288433815020A3814ED +:102AE000820A3813820A3813020A8C011012002A53 +:102AF0001011002A5A080FEE4402B7BE844084C366 +:102B0000E248E83000107FB88C415A1801298082D1 +:102B10008020E288E82400507FBDE6A8E807A6C927 +:102B20009DEA4C71800B8CA3D5075A500815A6C995 +:102B30009DDAD7038C63DB0F20F0800020307FBC50 +:102B40008A6F8C61E663E8070030FFFDCB041060FC +:102B50007FB8D5058C8150108044D5DC50000044EE +:102B6000D5D04400003C42040024F08F8400F0895A +:102B7000460000F350000A703C2DFC4451EF815890 +:102B8000049F8001F091F009F105E2014EF2010489 +:102B9000F309B01A842138100E0A85404402B73C6C +:102BA000F10F4CA080F0F1052234800CE228E809F6 +:102BB0002210000E2240000F8A612214800DD508D9 +:102BC0002210000C2240000D8A612214800D8A24FC +:102BD000FE4C42118C73F1872214800C2264800D0C +:102BE000F18BF30B2210000C2240000D9A59F18852 +:102BF000F3089B34045000094212102442118C73D4 +:102C0000F58AB4605A580408005000285A58010444 +:102C1000480005AB0450000CCD71A151E2254EF3E4 +:102C20000584A551FF5CE225E82CA152E225E80AC3 +:102C3000A144A183F708FF64425398734E5605756B +:102C4000D520C31FA153E225E81CA184A143F708A6 +:102C5000FFA44263947344500064FF7440528CB7E5 +:102C6000FF6CFF5C4470271040F29DF70071002755 +:102C700044500064FFCC407394F7E2EF4EF30553E9 +:102C800000500029A790E2C5E805A194E2264EF382 +:102C9000054CC322E6A2E920F511E2A1E91DA144F9 +:102CA000A183FF2CF5084242987344500064FF64EE +:102CB00040528CB7FF6CFEEC4450271040F195F762 +:102CC0000051002744300064FF4C40528CB7E2AF03 +:102CD000E8034E46052A003100264E320546A0D3B1 +:102CE000E2234EF20542F10A5A1804044800053D59 +:102CF000F10746390000480005365A5002065A507E +:102D0000040448000532F30A5A3804044800052D2B +:102D10002230000E85E6F38D2230000FA1C3F38E22 +:102D2000846AFE5CF190A051A14442F78424F11022 +:102D3000E22F4EF304FA0011002842F38424FE6CC3 +:102D400040F78DF640108C36F30EF18A88659AF3C1 +:102D5000F60DF10B88C78A26FEDC42308473F10A37 +:102D6000FE4C4217BC73E0614EF204FFF108FF2CE9 +:102D700042409C734E4704F9F10746380000480072 +:102D800004F2F00951EF00048C01F0895094804462 +:102D900048FFFEFB8400B0E98421E208E805381111 +:102DA000820A8C01D5FBF005E60BE80BE70BE8097E +:102DB0008028B09A504F8158B15249000521D50959 +:102DC000F0058028B09A504F8158B152490004CF85 +:102DD000F0883C0DFC448500F0874605FFFF50005D +:102DE0000FFEF08D4608FFFF50000FFF8148441290 +:102DF000B73C45E2D558F08EF008E3404EF201CCE6 +:102E0000B0924005040888028061A6014420004475 +:102E1000423008730421800C5A280214B092846F47 +:102E20003821290042200C73503F815838218A02F2 +:102E30004E250008B0A984613831020A480001A972 +:102E400044300044B092808142400C733821290004 +:102E5000F60200520037504F84DC42410C7380640C +:102E6000A1B350318028F689F70950420030A1996A +:102E7000AF6738639901F70702738015E2E6E80847 +:102E8000CD07A75A58528001AF5A8461AEE744403B +:102E90000044503F84DC8121423110734290107312 +:102EA000506180182251800C2244800CF58A9B2CA2 +:102EB00022530001F58BF70B2254800D9B7D42F2CB +:102EC000942442F2107380EF81E3A95C1C778002A6 +:102ED000F70A1447800188E4ADF2F70B88A7AD73B9 +:102EE00084AF80C242601473505F8158F70D38522E +:102EF0009A024666000088C5E2E6E855F60EE2C58D +:102F0000E8520054803F50318038E6A8A6DFE8063A +:102F1000E668E8354E440034D505E668E9304E47AA +:102F2000002F4440004480614230107300618020D3 +:102F3000445000FCF70442731473005380FAC51424 +:102F4000505F84DC42511073808500528034CD176D +:102F50000251801E0242001E44300064FF5CFA6E83 +:102F6000FEE4E0A3E80C44300044504F88D84241CE +:102F70000C73806484841441FF0DD51844400044D0 +:102F8000503F84DC4231107384A21451800C80A124 +:102F90004250107380858C908C70A562A523AD5A29 +:102FA000AD1BD50484801441800C44400044503F44 +:102FB00084DC80C14231107342601073808650718E +:102FC00080108CD0225380022293000222630003DF +:102FD0008AA9A959225380038AA6A95A005200201F +:102FE0005061802010518020043200095A38037A41 +:102FF000383F14005A38010A003200288C6A103217 +:1030000000288462383F14084432D558383194007F +:103010005A38030E44300044808142400C7380646F +:10302000848110418028FA60383F1408383F14002A +:103030005A38040E44300044808142400C7380644E +:10304000848110418028FA70383F1408383F1400FA +:103050005A38022644300044504F88D842450C73F9 +:10306000F60904427F0C38631101848AFFA4808131 +:1030700042400C732272001C80648487FF3CE0C4D1 +:10308000E80784811041802844300030D5060031A3 +:1030900080285A3801058465383F140844300044BC +:1030A000504F84DC42410C73FEC4886100520037EB +:1030B000003180285A5801038E61103200284430B4 +:1030C0000044504F84DC42410C738064004200286D +:1030D00050318020CC038481D5028483A919D50680 +:1030E00084603E3004678462A8F1444000448061FB +:1030F00042301073003180345CF180C8E8038C6189 +:1031000096D8505F84DC42511073103280344432C0 +:10311000B73C42301073B4C550428028003180293A +:10312000F507AEE1A16DE2A6E805E66AE80A8C6162 +:10313000D507F507A16EE2C5E804C3038E61AEE1D1 +:1031400044500044503F84DCF40242311473A12304 +:103150000461800B8D013842190180C142601473F3 +:103160002203001CE00440403C1A1241801C004134 +:103170008020503F811C84013801920AB0F8380148 +:103180008A0AF0068E01F086F0038E01F0838D41ED +:1031900048FFFE348400509F80A44462B73CF0870F +:1031A00050AF80E02E07F108F107E220E803F003BA +:1031B000C806049F800184E0480000C23C3DFC43F7 +:1031C00000018009E300E8F60C0480015A000104C4 +:1031D0004800009F040300095A080313002300203D +:1031E000441000FCF40442410473001200FBC908BF +:1031F000F0031414FFFF8E01F0834800008A9E4103 +:10320000E622E8070403000C5A08023A8400D53E7F +:103210005A08033A00430020440000FCF104421223 +:1032200000732220807380012253001C842AFE8CAC +:103230008427FE6CE041E80D001000FBC10A00137A +:103240000037C107001000F2C1040013003AC11199 +:1032500084201013002884201414FFFFF1030000C1 +:1032600000F28E21F183C81484013E000467D5105A +:103270004402D55844100040381010083C0DFC445E +:10328000A601D504000300288E01100300280003C6 +:1032900000285A0801080013002A5810800410134F +:1032A000002A0011801984E0B09AE2E1E80938357B +:1032B0001E02CB0438311E02C3058CE1D5F784E031 +:1032C000D525C0038404D50284054420004414039A +:1032D0000009500F84DC42038873802649007D502A +:1032E00000230020501F811C840138008A0A380501 +:1032F0001E0A84001404FFFFF0038D018E01F08389 +:10330000D50738251E02C2DE8CE14C70FFFCF007A9 +:10331000506300448C01F08748FFFF46F0064E02E0 +:10332000010900130009E3014EF20104B01A38004C +:103330001E025A00010C8CE150948044F0053C6D53 +:10334000FC43E2E0E9EC480000F5B03838601E02CA +:10335000CEF3500F811C38001A024E0300E580297D +:10336000B609A809A80AA80BA80C0204800C1064CE +:1033700080201204800E0204800DF1041204800FDC +:103380003C0DFC4488080000001C10048028440008 +:1033900000FC4213007380018421101000FB2E00FA +:1033A0000411C00A49FFEF865A080207000480286A +:1033B0008C01100480280434800B00148020440009 +:1033C00000FC04AF800442A0807380433C0C027870 +:1033D000F102F38349FFFAB3100500FA1004803BB1 +:1033E000F303C80700048028C8048401100480285F +:1033F0008400100500F1F1028043F00C49FFF9D47C +:1034000000148020100500F2F204440000FC422069 +:103410008073000100F2C80700048028C8048401FA +:1034200010048028F0059678502F84DC49FFF94F6E +:1034300081405A08010B49FFEF3D5A08020700047A +:103440008028C80310A48028F00200148028A083DC +:103450000404800BC9153C3DFC44381101010231C4 +:103460008015E261E80800148036C905842114142F +:103470008009D5148423141480098421D50D3C4D72 +:10348000FC44846314348009024200153831010180 +:10349000E283E9048C2110148028004480364432F1 +:1034A000D558001480205A4801052E57E91EC50240 +:1034B0008480384184083C3DFC44382101010231BC +:1034C0008015E2628441E902844010248037F304CD +:1034D000442000FC423088738420101180F0F302F5 +:1034E00010148034101480290014802A8441A0DB39 +:1034F000FE571014802A3801810184201204801C98 +:10350000500F811C1414800C38201A0AB03889021C +:1035100038201E0AB01A38101E0AF0068E01F086F6 +:1035200048FFFF0B8CC1E2C14EF3FF1548FFFF05BA +:103530008400F104804000330009E203E808B6414A +:10354000102080E08C01501080FCD5F684003E00F5 +:1035500004113E07F108447000C88540509F80E088 +:1035600000030019E3404EF200D73804AA025A00C3 +:103570000104480000CAF001044000095A40052235 +:103580002E87F108442000444402B73C42040873EB +:10359000F101F48349007BF4F001F2048D01001085 +:1035A0000020440000FC42208073000100F03E87B0 +:1035B000F1085CF000C8F403E8048C01100100F08D +:1035C000F001048F800400100020440000FC4280C1 +:1035D0008073F0015014001CB6880000002A10040B +:1035E0000018F0010200000A12040002F0010200BB +:1035F000000B12040003F0010200000C120400048E +:10360000F0010200000D12040005F0010420000B7F +:10361000B400B641A80AF001A001A80BF001A00275 +:10362000A80CF0010400000C1404000C5A4803110B +:10363000000400F2C80D001400F18401C907100451 +:1036400000F1F102F00C49FFF8AF100400F2F001B4 +:10365000048F800400100020440000FC428080732E +:10366000B4885A400416F001F202F4830400000BFF +:10367000A09394413801010112040074F002A08467 +:10368000500400668822844249007B7AF4033C0D92 +:10369000FA9DB40092029606C00344700190220481 +:1036A000002E22F400028A0F4E040003FE02E0E026 +:1036B000E90B2204002F22F400038A0F4E040003BA +:1036C000FE02E0E0E80A000400DE5A0802075A4859 +:1036D000020584013E000409F001B4005CF02711EA +:1036E000E9085A4802072E0004118C013E0004111B +:1036F000F0010000002A9606C807000400FAC8047A +:103700008401100400FAF0018D4150000044F08162 +:1037100048FFFF282E07F1083E07E95E51FF88D8D1 +:10372000FCC04E67FAAFF10A5A18031400100034B7 +:10373000C9100010003A5A180309F1054C1400068C +:10374000F107463A0000D50EF10746310000D50AD0 +:10375000F107381F280A5000004450A5003C48FFDC +:10376000FA218823D5F7843FD5F5FC43F081810009 +:103770008400F484F182F58580E183808120848156 +:103780004E82003DC73B5A48013A84A08085855E41 +:10379000F101D122386116025A68011DF10495AA7F +:1037A00088C1F68384C0F1024C60801539E19A0229 +:1037B0005BE8010F4410003C42F30424F10338108D +:1037C000BC02E22AE80583868125809E81418CC166 +:1037D000D5EB8CA1D5DEC4D5F105954188A18C012E +:1037E00084201092800011C2800196003811260AB0 +:1037F0008F013811F20A8EE1D5C4FCC3C06EC16FCF +:10380000FC4051FFFB90E220E82F80E144A0003C07 +:10381000851F81244293A87384C038849A0A8CC17E +:103820004C607FFD8CE14C707FF680C0838180010D +:10383000802681248105F281814349002A8CB03B96 +:1038400049002A90800949002A97B00249002A9E1F +:10385000840F49002AA549002AA8844080A245E097 +:10386000003C8082D514E201E8E184E044A0003C01 +:10387000851F81244293A87380C038849A0A8CC122 +:103880004C60FFFD8CE14C70FFF6D5D0840F81E9D0 +:103890004212802442F2F87384E098F9B002383082 +:1038A0000C005A38011138379E025A37FF0D94D157 +:1038B00088688C41AFD8AF59F301969038419E0A81 +:1038C0003845160A8CE14C737FEA8CA14C5E7FE090 +:1038D000800251FF8470FCC08040D502804180028C +:1038E000DD9E3C0FFC76DD9E3C0FFC75DD9E4402A8 +:1038F000BBC084213C0FFC5084003E07F1443E07CE +:10390000F1453E07F1463E07F1473E07F1483E07C5 +:10391000F1493E07F14A3E07F1193E07F1183E070B +:10392000F11A3C1FFA1E3E07EAEB4412BB7C8400EE +:10393000845F382080088C015A0841FDDD9EFC0020 +:1039400049FFED49FC80FC0080C049FFED46C007FF +:1039500084013E07E8D48400AE34AE35FC802E07E7 +:10396000F120DD9E4432BB48AE18AE59AE9ADD9EC2 +:103970003C0FFA1EDD9E3C0DFA1EDD9E3C0DFABA90 +:10398000465FF00F50528F00FF4646001000D806E9 +:1039900084003E07EAEB8401DD9E8400DD9E2E1745 +:1039A000F1462E57F1473C0DFC764C12C0102E27E5 +:1039B000F1445A28010CA6059D49400280B697683B +:1039C0003E57F1463E57F147DD9EA6058CA14002C9 +:1039D00080B697683E57F147D90484013E07F14409 +:1039E000DD9E2E57F1462E17F147D9042E07F144DC +:1039F000C0103C0DFC768CA1A605400280B69768ED +:103A00003E57F1464C12C00584003E07F144840144 +:103A1000DD9E2E57F1462E07F147D8082E07F144B8 +:103A200084208E0140008006DD9E8401DD9E2E579D +:103A3000F1462E07F147D8072E17F14484004000C5 +:103A40000406DD9E8401DD9EFC0084A08C81E2A43E +:103A5000E8073860080438608C0C8CA1D5F9FC802C +:103A600080603C0DFA1E9E41E622E8253C2DFC7547 +:103A700084200041000AE224E809A1593852870253 +:103A80005A58010384028C21D5F7FC0084200041A0 +:103A90000009445000FCE224E80DB4434220947332 +:103AA000B4429F91E6C2E9055A2004048C21D5F462 +:103AB0008401FC80DD9EFC42F181B541843F101FF2 +:103AC000800F2E17C5D88120C1082E17F120C905F7 +:103AD00049FFFFC83C0FFA1E3C3DFA1E5A30010454 +:103AE000480001113C1DFC753DEDFC76B67F84C09D +:103AF000B45F004080098E419690E244841F4EF2EC +:103B000000FD440000FCB489FE149960B50550F432 +:103B10007FFF5CF78002E9055A800404480000E852 +:103B200000F28056E92A004280DE5A4801304442C1 +:103B3000CFC438420800E6944EF200DA4452CFC4B3 +:103B40008C8138428808B4898880B4A45A5004040F +:103B5000480000CE4452CFB8382288004E2300C817 +:103B600022520073024200748443FEA4956A969325 +:103B7000E0A2E90C480000BC5AF802090222806B5E +:103B80008880ACAE0222006CACA7002F0000B4A964 +:103B9000C209992802208009224200068E418A44E7 +:103BA000D50498A822210006004F0001C40988A06E +:103BB0000240800A225280078E818A85D50488A01F +:103BC00022428007005F0003C5300250800900FFD9 +:103BD00000028EA1E9120280800250747FFF8502EC +:103BE00040F2A1F642F11C73402794560250800A1D +:103BF00002F080038EA1D5110280800350747FFFF4 +:103C0000850240F2A1F642F11C73402794560250FF +:103C1000800A02F080028EA150F7FFFF4082A116B9 +:103C200042823C7340441496A54AE045E9029EA9AD +:103C30004E2400038440A54BE085E9029F294E44B1 +:103C40000003848084E680AA42531C73B4FF40F2D0 +:103C5000100A40838C085884000210828000007F84 +:103C600000024081100ACF0A949484F010828001EF +:103C700010F28002971FFEBED509952484F010F241 +:103C8000800110828002969FFF3EFEA7B489AEABF2 +:103C900088800222000AC2039690D502844180AA3D +:103CA00084E642531C73AEAC0222000BC203969012 +:103CB000D5028441AEAD845F1025003C1025003D47 +:103CC0000020800CE642E911B4498840002100350B +:103CD000CA0284414045180010220046B4498802B7 +:103CE000200000361002006E8CC197B0B41F8C010A +:103CF0009600B61F48FFFEFE1005003E1005003F6F +:103D0000D51C2E67F118C6192E07F11900150000F1 +:103D1000E61EE80594039657FE0FD503440000F015 +:103D2000100500002E07F11A1065000110050002B1 +:103D300084013E07F12084C02E07F1205A00FF0DB8 +:103D4000C00BCE0A841F3E07F1203C0DFC478C01BE +:103D50003C0FFC47D5033E67F1205A3801173C0D54 +:103D6000FC7500400009E2C4E810F0018426FE74EE +:103D7000B4408A868406FF0496488822500F800F3C +:103D800084408E8149FFFE62F001B420840080A14E +:103D9000502080400832800188039600DAFCFE0241 +:103DA000100080408401C60284003E07F14AFCC234 +:103DB000FC20844180624440004080E080C149FF93 +:103DC000FE453C0DFC750000000CE602E910505366 +:103DD000804650130046507380500802800118003E +:103DE00080012002802710008027DFF8FCA0A600B9 +:103DF00092038C1596275C000014DD9EFC4080C168 +:103E0000A640844081203E27F149C1312E07F1456B +:103E10005A08010C2E17F1483E27F1443E17F1468F +:103E20003E17F1473E07F14949FFFDBB3C0DFC76CB +:103E30002E77F1473C1DFC50A70484410404800107 +:103E40004213907380628E8149FFFE002E07F14A73 +:103E50005A0801063E07F1453E77F1482E07F11456 +:103E60005A00FF088C013E07F114D5033E17F114E8 +:103E70002E17F149B4065A180132A605C81849FF91 +:103E8000EAB5C80F3C0DFC76B4262E37F148A6845F +:103E90003C0DFC5042018873B42149FFFF8BD50AC9 +:103EA00049FFEA6249FFEAA2C8FED5ED49FFEA9E52 +:103EB000C80349FFEAABB42684003E07F1493E0738 +:103EC000F1458401AE0DB426AE0CB4C6B40649FF6C +:103ED000FF905A080141AE37D53EA644C90549FFB7 +:103EE000FDA8C039D50DA6055A08010849FFEA7E8C +:103EF000C83249FFEA8BD52F49FFFD8DC8F849FF2D +:103F0000EA7580E0C82849FFFD6E3C0DFC76B426BA +:103F10002E97F146A6843C0DFC50B42142048873D0 +:103F200049FFFF482E17F1455A1801112E57F14845 +:103F30004C54C00DB4063E77F145AE45B4E6B40727 +:103F400049FFFF575A080103AE3F49FFEA5FB40635 +:103F50008421AE44FCC0FC20804080E14402BB646C +:103F6000A0514462BB7CB6202E17F1203C6FFC4C64 +:103F700010100008A052A8414412BB6049FFFD9DEB +:103F80004402BB582E17F120A981AE40B4273C1F34 +:103F9000FC494412BB5449FFFF334402BB48842010 +:103FA000AE40AE41AE4249FFFD44FCA03C0FFF9D38 +:103FB000DD9E3C0FFF9CDD9EFC41F581408280111F +:103FC00041C2C00A445000FC4201947300500018E2 +:103FD0002260800054A28001221080014EA2000DB8 +:103FE0004472C7B884A038538C084472C7A83853A9 +:103FF0008C084800007301E000E15BE8030B4452C9 +:10400000C7B838A28C084452C7A838A28C08D56516 +:104010004FE300214472C7B8852338538C00814593 +:1040200042A1A473409508088CA144A2C6F4892A31 +:104030009768E6A3126480001214800138538C083C +:10404000E94C4452C7A8852138928C0839E38C0882 +:10405000D5445BE801434492C7B884E338548C00EC +:1040600081E542F19C7340F788084472C6F440F73A +:104070009C008CA197681267800012178001E6A34C +:1040800038548C084452C7A8E90539E28C0838A492 +:104090008C0838528C00CD0538548C00C51ED502D2 +:1040A00084A3842C427184738460802380C35491E0 +:1040B00080FFE325E80E40918808892738A38E0108 +:1040C0000294800188CA882997B3964B8C61D5F0F9 +:1040D000406314D640109436003F80285A38012897 +:1040E000B4005A0801253C5DFF9DA42DE280E81F25 +:1040F000403320014E340003FEDA4000F0014E044C +:104100000003FE028803A4EEE003E811A4EF9F1968 +:1041100040018409421270734262207388C0880192 +:1041200040630CD640100C3697B3964BAD90AC5113 +:10413000FCC1FC403DCDFF9D2E700439005E001691 +:10414000006E0017CF0540A280139771D50444502C +:1041500000508145446000FC42019873B50084DD45 +:1041600040F418024492C6E44462C6D44472C224A5 +:104170005AF00105000000E0C018840038048C08E3 +:10418000840138030C08FAC4FF9C220080004442DA +:10419000C21438039A0995B22210800188C738A248 +:1041A0000C08AC714800009138030C00E614E804D8 +:1041B0008C0138030C0838048C004462C6E4E61312 +:1041C000E9038400D5028C0138030C0838948C0074 +:1041D000FAC4FF9C02F0800040049800A44938F320 +:1041E000820994028807AC41021E000DE081E903B8 +:1041F00080AAD51003CE000C40FE1007E80B8B45BB +:1042000040027001420500244040F00140401096F9 +:1042100088A444A2C2145A88040438550C003845B6 +:104220000C0084038024421280738C22840440009A +:104230008016E0804482C214E8058C81E080400250 +:104240003C1B38040C084402C6D438450C00381016 +:104250000C00840AFE44E08140123C1B8540400073 +:104260008016806A808A4CA00013405498003883DE +:104270009611956A88A788882252800188654E9297 +:1042800000048F21D502FB238D41D5EE84AA420282 +:10429000142442419424403094B6C50C88C9383364 +:1042A0009A1195B288C742028C73223300014242B0 +:1042B0008C734030840A88038864400004164011DF +:1042C00084369603964BAC10AC51FCC0FC41445074 +:1042D00000FC420194734472C1D8B4A022808000D3 +:1042E00023C080014462C19C38138E02853D4094F6 +:1042F0009402F18144A2C16038130E023C5DFF9D1F +:104300005A900105000000E0C00A0202800F3883C5 +:104310008E0A39C30E0A38050E0AD54103E2801110 +:1043200040FF1007E9040202800ED51102928012AC +:104330000202800FE089E80B02F2800E8A9E8A0F4B +:10434000FF044004F80140020016880F38450E02B1 +:1043500085234240247380040252801084848C029E +:104360004000101640928001964B42148424404233 +:1043700084094210707388244010943638130E0A52 +:10438000221F800238050E0A421484244210207332 +:1043900081218924405494B638538E0A38038E0202 +:1043A000AC1038030E02AC11FCC122200000E02248 +:1043B000E8153C4DFF9C023200098E618A61E043A2 +:1043C000E80D22200001E022E8090202000A8E0125 +:1043D0008A01E04056078001DD9E8401DD9EFC01DC +:1043E00094928822F081223080009603E060E804F5 +:1043F0005231843F96DB2200800122FF8003E00FD0 +:10440000E8045200096B9603E0604001BC1BFC818C +:10441000FC0196435EF082219010E9045210844022 +:10442000964B5EF004B7E9045200096C9603E02055 +:104430004000BC1BFC81442000FC42008873B42077 +:104440005A1802058420101000F7DD9EFC41F60B7F +:10445000F081440000FC4223007300010018812217 +:10446000960EC85DB4028E01E602E8593C83F44022 +:1044700050047FFF960042732024C00B988794520B +:1044800088238E010410FFFF960038118A0AD5F6A2 +:10449000400408080474803BFE343871800A01C46B +:1044A00080F35BC0093D5CF289C4E839F0018144C6 +:1044B000B67F49FFFFAF5EF00065E80A22FF800388 +:1044C0005EF78909E92C540E00FD5A000C29840A74 +:1044D000421380244603FFFF9CB150000FFF4201AE +:1044E0002073B45F380102028447FE14E220E8170B +:1044F0004FC3000B3C0DFA9DB40092069606C8040B +:1045000044003840D50344000E1038051A0AF00A5A +:104510008426381018088409100480F3FCC1442054 +:1045200000FC42008873B4604422BD745A38051DF3 +:10453000003000F75A3801114400006438010509C1 +:104540002E07F340E603E9043E30046BD50D8C01E1 +:104550003E07F340D50984003E07F3403E00046B5C +:1045600084003801050938010501C00C8E01442280 +:10457000BD74960138010509C8053E07F3403E00A9 +:10458000046BDD9E444000FC42019073000000F388 +:104590005A0006045A08090A8823A608C0048E0196 +:1045A000AE08DD9E38010E0ADD9EFC21F381F30981 +:1045B0003C73F4418843A710E287E8238C81AF1055 +:1045C000444000FC4201907394DA998B3C13F47BD5 +:1045D0008480FE4C104000F3B626A6504C13C01247 +:1045E0008421101000F3F008B0418803844480E572 +:1045F000490073C63C03F479FE04B6068400B6078E +:10460000FCA1FC01956A8885F081222200009603B6 +:10461000E040E8045221043F96932202000122FF69 +:104620008003E00FE8045200096B96038825E04000 +:1046300040013C1BB44142300024E262E80DE40634 +:10464000E9048E05FE04B6013C03F479B441FE048E +:10465000E240E802B601FC81443000FC42010C73E8 +:10466000003000F5CB090430003B5EF19771E9049E +:104670008461103000F5003000F55A38011394D2EF +:104680008861B4835CF20E10E80444400E10B683D7 +:10469000000000F35A0801063C03F479FE04B60357 +:1046A0003C0DFA9DB400920296065A0801122E00A3 +:1046B00004575A0001052E000465C00A949288220E +:1046C000B4015CF007E9E804440007E9B601DD9EA7 +:1046D0002E30046B5A38011794D28823B4615CF1F0 +:1046E000A710E80444302710B661443000FC4201B2 +:1046F0000C73000000F35A0801063C03F479FE0431 +:10470000B601DD9EFC01F081F007444000FC421040 +:104710001073004080F9CC1D22508006C50E3C6D00 +:10472000FF9C024300098E81D40822508007C505F2 +:104730000243000A8E81DC0D8482104080F9848659 +:1047400038418008443019003831020A104080F3A3 +:10475000FC810000FC41F70AF481953A40A1100069 +:10476000B44AE241E845441000FC4203847380C02F +:10477000000000F3E602E805000300DE5A000139FC +:10478000840F100300F8B041982C84448123490021 +:1047900072F78400B60A2E000439C0028409B60AF2 +:1047A000840038049C08000300F3E60EE82144F07E +:1047B00046BC3807800040F03C00DD0F0E1232325C +:1047C0001A321E323216322232268403D50C84026B +:1047D000D50A840AD5088405D5068407D504840C37 +:1047E000D502840E100300F38401100300F6FCC10F +:1047F000442000FC42008873001000F65A1803059C +:104800008428101000F3DD9EFC003C13F47D840F1F +:1048100049FFE9183C0BF4413C13F47D840449FF43 +:10482000E9113C0BF440FC8080413C53F47C3C1388 +:10483000F47DD108FC009982A63049FFE909AE3029 +:10484000FC80DD9EFC0196CB9683903090108A010F +:104850008A43FE0442010873FC81FC41810084000C +:104860003E00046A49FFE5265A080242812884C0B6 +:104870004421869F000480F75A0001098CC197B03B +:10488000509480FC5A680AF8D527040480165A0808 +:1048900001F7814884E05034800C000500F75A0885 +:1048A000011505C500165BC801114C63800FB403E8 +:1048B00004150003F281B67F49FFFFC6F201B47F01 +:1048C000E240E9033FC0046A8CE197F850A500FC80 +:1048D0005A780AE5D5D42E00046A5A080105440026 +:1048E0000053D503440000A73C0FF245FCC1FC4334 +:1048F000F085000F803CF184E603F281810305CF4F +:10490000800E049F8010E90B2E17E971C90DE60691 +:10491000E80B44A0007884EF84C8D50A44A000784E +:1049200084E384C5D50544A0003CFAEEFAC03C0DF2 +:10493000FA9DB400920296065A08010D2E00045703 +:104940005A0001052E000465C00544A0003CFAE4AD +:10495000FAC92E000439C00544A0003CFAEEFAC0A2 +:10496000F004F105F583F48249FFFF6E5CF009C4A1 +:10497000E841F402FFB4E286F503E83941CE2400B1 +:10498000000E0000E340E825401488083822A60104 +:1049900088A1F105A42940004008FE1749FFFF54F3 +:1049A000E206E815F00549FFFD355EF00065E90F08 +:1049B000440000FC04AF800142A4807342139C2495 +:1049C00084043814260A100500F3D5148400D50C8D +:1049D000C808400488088805B0458444490071D05F +:1049E000000E00008C01100E0000D5048400380E6B +:1049F0002408FCC3FC4199DCF081A638E615E937B0 +:104A00004402BD34814138001202F10180C4812288 +:104A100049FFFF1A5CF00384E826440000FC3C33A5 +:104A2000F44042A30073840042130C248080E2838C +:104A3000E80E98A10455003B38248A028A454E248A +:104A40000003FE928C8188029720D5F28E6140F09F +:104A50000DF75CF781918401E80284003E00045761 +:104A60008400D51284003E000457D50EC80C4412B1 +:104A7000BD34022F80023820920995228881021FBE +:104A80008003AC618C01AE383C0DFA9DB4009202FB +:104A90009606C8033E000457FCC1FC4180E2812118 +:104AA0008045802480C5F0818103814449FFFC99C1 +:104AB000441000FC42730473001380F85A180F2648 +:104AC000381419018C2FE201E8048400100380F4EB +:104AD000000380F45A08011A95B28926F0010224D5 +:104AE00080010214800040214008FE5749FFFEACBF +:104AF000E604E80840051800802984444900714014 +:104B0000D5048400100380F4FCC1FC418501B61F6C +:104B100080818120838185404004A001E320405EA4 +:104B200028014C5780234074A000E2E9400E280081 +:104B30004067800040037C0892E1FFC792C1800774 +:104B4000802680478066F481490070FAF401E28192 +:104B5000E9094C124005B43FE220E904810781468F +:104B6000D5DC81278386D5D9E602E8DE8008802A55 +:104B7000FCC1FC42F60DF083440000FC423300739C +:104B8000000180F681428385048F800C81235A08BE +:104B9000016E003180F35A3802073C73F478100438 +:104BA00080F4D5195A3803053C73F478D5145A3873 +:104BB0000505100480F4D50D5A30070C5A300AF65A +:104BC000540180FD84E05A080C0744700078D50336 +:104BD000447000323C2DFA9DB402920696065A08A3 +:104BE000010495F997F92E07E984E603E80B8E6234 +:104BF000E662E808B40292069606C8048405FFC47B +:104C000097F994F24402BD14990B84408024382013 +:104C1000190940040C008444F382F481490070B007 +:104C2000F0038028804649FFFBDCE207F401F30231 +:104C3000E804380E1909D503387E19099431881C07 +:104C4000A440C9038421AC4040150C00A420A54811 +:104C50004422BCD88A05A44938011A09A4218862D3 +:104C60008A01AC198402100480F6000480F85A0806 +:104C70000F61000480F64432BD1495F25A08030F08 +:104C800040051C00B0438444F38149007079F3016E +:104C9000380E190138019909D54C004480F4CC1C18 +:104CA00038141A018907F00302240001F38240211D +:104CB0004008FE57F48149FFFDC7F401802449FFF5 +:104CC000FF26F30296013C0BF95238119901E220BC +:104CD000E80338019909957188BC38119901A42815 +:104CE000E220E9084412BD14380099098403100435 +:104CF00080F6381199014432BCD8A52838019A11A0 +:104D00009AA1FE14022F80068947400010169A10BF +:104D10001205000088E3A4A8223380019A114211F1 +:104D20008024020F8007401088369A411215000136 +:104D3000FCC2FC422240800022608001441000FC42 +:104D400042018473B520F2824412BC98955A3C7D8E +:104D5000FF9D5A980116AD10AD9138408E09A63DC1 +:104D60008825AD895A000104480000F24402BC5C69 +:104D700088A0842038100E09AC69480000E9A6BD5F +:104D800000A00018F2835A28014054050002C03CDC +:104D90004402BC5C38700E11CF0888A0220280014A +:104DA000C03338408E11D530880522000001C80577 +:104DB00088A122628001D52888A181E42242800155 +:104DC00052938000FFE438408E114250002442701C +:104DD00010754244A4244082900043C024244242DF +:104DE0003C24424E187542401C75FE0242002424A9 +:104DF000FFAC42603C7342649C7540422096406325 +:104E000020D6972397B3540500024E0200833C0D31 +:104E1000FF9C80E402A00009E08AE90838908E1126 +:104E2000E12AE80F50957FFFD50C4E4400083890DA +:104E30008E114E9500078520D50481248500D5026A +:104E400085010250000A41E18808E0C58006E90AB0 +:104E50004080F80022840001E105E8105082FFFF45 +:104E6000D50D4E6400094080F800228400014E8474 +:104E70000069D5045A88014E810639C08E1141E07F +:104E8000F80040227001B65F222F0001F28140F34A +:104E90000801B45FC20C84024001001641E4F00135 +:104EA000420F3C7340000816F2018802E80DF2013F +:104EB00084E241E40801B45F40779CF6427F0873C6 +:104EC0004073BCF688FCF2014C81003EE0EAE90543 +:104ED00052A500018947D5054E74003652A38000C3 +:104EE0004C9E000CE005E9055252800188A0D506D1 +:104EF0004E040004FF42D50284A0E0AAE805404425 +:104F000080119783D506E145E804973B4064001182 +:104F1000F203941A5A28010E38708E014452BC5C78 +:104F20009BE738728E0999C888A0A5F99BF7ADE96F +:104F300038408E098820F002AD89AD00AD81D507DB +:104F40008500D59C85404C9E7FCFD5E3FCC2FC40BC +:104F500022608000225080014412D558AD90AD519E +:104F6000387090003C6BF9143C5BF9155A780117C6 +:104F70004492D780386491094492D14838549109B9 +:104F80004492D0783864920A4462D4543853120A56 +:104F90004452BC4838729008D5665A78026544A2DB +:104FA000BC4838751000E6EAE8124482D0788CE1FB +:104FB000389412023875100889263894120A4482EF +:104FC000D4543894120289253894120A4472D78036 +:104FD00038A39111407518014E740003FFFA5EF377 +:104FE00080B54492D148E9103884911150F2800E76 +:104FF00040F7A007E8125EF380DDE9095072800FE8 +:10500000E0E8E90BD5045EF38051E90A3884911198 +:1050100050F2FFF1E10FE80484E43870900838742E +:1050200091115EF384B6E80550938028E125D508F8 +:10503000449004B64C74800950F3FFD8E0AFE80404 +:10504000852338909008389090008F23E722E80B52 +:105050004492D5448ACA386491094462D1348AA7FB +:1050600038531109385090005A5010045A582023D0 +:1050700084A03851920A4432D78038319111ACD093 +:1050800038509000443000FC42020C735A5810080B +:10509000846B103000F34400096BD508846D103028 +:1050A00000F34402D14838001111AC1184003800DB +:1050B0009008380090005A0805194402BC4838305E +:1050C00010004402D078381012024402D454401028 +:1050D0008C3638001202AC5040000C16AC11440261 +:1050E000D558842038101008FCC0FC45F0852E07E8 +:1050F000E984049F8005F08722008000F2863C0B43 +:10510000FB9622008001843D3C0BFB97440000FC91 +:1051100042918073B40980C3FE0E4482C14C44A204 +:10512000C13C5A000105000480E0C04D3C13F47BF3 +:105130004442C100FE4C840038121A0A3C13F44069 +:105140003804180838051808100480F3100480F497 +:10515000100480F5100480F68401100480F74223C7 +:10516000042484004432BF20E201E80999C204A467 +:10517000803B8C0138A19E0A9600D5F794F24472C8 +:10518000BEE498BBF00588644412C15C808649FF88 +:10519000FEE04402BEA838A39A024410003238A0B0 +:1051A0001A0A4402C15C49FFF9024412BE78100495 +:1051B00080F98400380098084412BE6838009808C6 +:1051C000480000BB4472BEA83C1DFDCB38038E02D4 +:1051D00049FFFB3AF0898026800849FFFB27FA0047 +:1051E000100480F8000480F38127E602E827B14923 +:1051F0003C3DFDCB4442BF20F0058048B6FFF68120 +:105200004412C10049FFF9D3F00580464412C100A1 +:1052100049FFFA24F00580464412C10049FFFA5ABA +:105220003C0DFDCB4412C1004422BE984432BE88DE +:10523000808780A649FFF9E7D5369E42E622E90835 +:105240005A0005079E47E622E9035A080A2DF00591 +:10525000802649FFFACFF005802649FFF8EE440288 +:10526000BE78B61FF0074412BEE4F081F6823C0D12 +:10527000FDCB38109A02F2054432C100F4094452C1 +:10528000BE2C49FFFB36B73FF6813C0DFDCBF10547 +:105290004422C1004432C13C4442BE984452BE88BC +:1052A00049FFFA323C0DFDCBF1054422BF204432C8 +:1052B000BE68808649FFFBA04442C100F5093C0D51 +:1052C000FDCB4412BEA8F2054432BF20B75FF68181 +:1052D00049FFF8BEF0054412C13C4422C10080667B +:1052E00049FFF9524472BD94F005F1094422C1000E +:1052F0004432C13C3C4DFDCB4452BEA8B6DF49FF11 +:10530000FA2B3C0DFDCB4412BDF04422BEE4F30564 +:105310004442C1004452BDD0B6FFF68149FFFC2B88 +:105320003C0DFDCB4412BDF0F2054432BDD0808768 +:1053300080A649FFFBB44412BEE4F20638009A117D +:10534000AC109432880122000001AC113C1DFDCB51 +:105350004402BDF038101A0AFCC5FC4081404400EC +:1053600000FC423280730001801880E4960680C5FC +:105370004492BC0CC009840238011408840038002F +:1053800094088400D54A41C09400000E0000E60352 +:10539000E8048C01100E0000408118000004000099 +:1053A000E602E9038400D5028C0110040000A47910 +:1053B000A4B84010C008FE5738049A0249FFFA44C6 +:1053C00044100064FE0C842049FFFBA180808463AC +:1053D00000040000FEF4880384A03845020A94DA31 +:1053E000000E0000886A8025E2A0E80638219602B7 +:1053F0008CA18822D5FA402004098841401100364A +:105400009A8C80014E240003FE925EF10051E90562 +:105410008C81882440008409A47838149A0995B2B4 +:1054200088C9A479AC71FCC0FC433C1DFF9DF0828F +:105430003C0DFA1FA44DE201E8048C013C0FFA1F59 +:10544000F00284C05070000C3C0DFF9C003000093D +:10545000E2C34EF200820403FFFDC0755A000574DA +:10546000A43A4412C7DC120F800AA43B4422C7CCE2 +:10547000120F800BF302B10580A64402C7EC49FF6E +:10548000FF6E3C9DFF9DF083B0450004800180418C +:10549000B61F8066F0023C4DFA1F3C5DFF6649FF77 +:1054A000F58D00048003C008B045F002804180669D +:1054B000F40349FFF64000048004C008B045F00240 +:1054C00080418066F40349FFF70300048002C007AF +:1054D000B045F0028041806649FFFE09B045804139 +:1054E000F002806649FFE733B045F00280418066F4 +:1054F00049FFFC21220F800A4E0400058400120F90 +:10550000800A3C1DFF9C222F800A02008009E04097 +:10551000E9048E01120F800A220F800B4E04000551 +:105520008400120F800B0200800A221F800BE020F3 +:10553000E9048E01120F800B020F800AAC38020FB3 +:10554000800BAC398026F00249FFF7EB8CC1507319 +:1055500080FC48FFFF7BF502444000FC80C54261AF +:1055600090733C27FECC3C17FECD3C0DFA1F8066A5 +:10557000D30CB4855A4805072222800622128007E0 +:105580008400505280FCD5F53C2BFECC3C1BFECD5C +:105590003C0FFA1FFCC33C0FFF9EDD9EFC20848065 +:1055A0008E4184C2E044E91198E240319876387027 +:1055B0000D019559E027E90788A0A529E024E9070E +:1055C0009D19D5F19E99D5EF841FD5028003FCA0CB +:1055D000FC423C7DFF9EF1825013800AF181508392 +:1055E00080DC51C000028540853EF002E3404EF26F +:1055F00000DB226E7FFFA43DE006E85CA53C9C2317 +:10560000940188079EA1A401E0C0E904A5B88EC159 +:10561000D552F0018026F48349FFFFC25A07FF4CA0 +:10562000A57BA4B9E2059441F403E8108827FE1491 +:10563000A4CDA44E8AC3FF94404314969B8B406232 +:1056400018D6405014B788C5D5368A858E81E204B5 +:10565000E9188827A4FAA50D886552F18001880F02 +:105660008AC4FF94FE1440001417A4F8405314B6E3 +:10567000A58E8A628AC48803406298D688C0D51BEA +:105680008827A4F84231247381E3A4CDA53A8A0582 +:105690008AC38E814267982442003C244000101740 +:1056A00040431096A58E88408AC3406218D688C2AF +:1056B000D50284C0126E7FFF0203806E226E00004E +:1056C000E006E86B0243806D5002006B940188078E +:1056D0009EA1A402E0C0E905026380698EC1D55E87 +:1056E00080088026F48349FFFF5B5A07FF58025366 +:1056F000806C0223806AE2059441F403E812882753 +:10570000FE140230806E0210806F8AC3FF94404303 +:1057100014969B8B406218D6405014B788C5D53E6E +:105720008A858E81E204E91C88270233806B02405F +:10573000806E886552F18001880F8AC4FF94FE1440 +:105740004000141702338069405314B60260806F22 +:105750008A628AC48803406298D688C0D51F882789 +:10576000023380694231247381E30230806E024348 +:10577000806B8A058AC38E814267982442003C244C +:1057800040001017404310960260806F88408AC323 +:10579000406218D688C2D50284C01A6E00048D41BA +:1057A00048FFFF25FCC23C0FFF9FDD9EFC4495CCCB +:1057B000B52488E095F940A49C0084C000850000D1 +:1057C000B6C2A9915A88FF06B70314818001D51883 +:1057D00000850000A1A138632101448000FF97AF3C +:1057E0001481800104820004B6C395B188C8008387 +:1057F00000014C044005A7B04C13008484C15080C4 +:105800007FFFB71F50800001148F8001508F8010E0 +:105810008388F082F0839E09B88200050000F1843D +:10582000B9818C21B98350007F018420400080061B +:1058300038AF8602E750E81D39C406025CFE00243A +:10584000E81841CE1008895C38F4A9005AF0FF121C +:1058500004A20001C80638053D01962FB603D508FD +:1058600038053D0104F18000962F4CF0400784017B +:105870008C215A1804DFD54A8420380F8602E6109E +:10588000E83C384406025CF20024E837952488049A +:10589000384481005A40FF3239C2811138029C11CC +:1058A000E01CE82B38451101400E000154F2003F86 +:1058B0005A60010DC6045A600214D52514F1800007 +:1058C000B48284C18804B602D518B4834CF2000CAB +:1058D00014F18001A11184C28804A811D50EB483EB +:1058E0004CF24006B4828804B602D507A1194CF2E6 +:1058F000400DA1118804A8118C215A1804C0D503A9 +:105900008401D5048006D5028403FCC4FC4A80C00F +:105910008400F283B63FB08A8060B43FE201E808B9 +:10592000944388248C01A04938310408D5F784A019 +:10593000B08A8781B41FE2A0E857942B880405E35E +:105940000001A001383F01014C30404D38010C00EE +:10595000C849945AF181D04294438824049F80011D +:10596000A1C9A07540F0A40000978002149F800296 +:1059700000978000149F80040097800100F7800347 +:10598000149F800540938808882950F78001008083 +:10599000800300A0800000908001A64A8E2140F77D +:1059A0008407E91CF1028D018E21E101E917F1055F +:1059B0008F418C21E02AE912F1048D218E21E12111 +:1059C000E90D380F1D0139C10C084C03C00C38110A +:1059D0000000C90839C10008D505B43F8C01E201B7 +:1059E000E9BB8CA1D5A885002E07E94BE3004EF258 +:1059F0000103A031385021014C5440FBB00A38005B +:105A000020005A000104480000F4A0754004080872 +:105A10008801A7C2E6E2E9048EE197F8D50284E0A6 +:105A2000A6435CF08022E8048C219648D502FA3324 +:105A3000F184A640E622E9048E219648D50284200E +:105A4000A601F181E60EE8048C019600D502840FD0 +:105A5000F085943CF082F004E0074EF300CA04AFF6 +:105A60008001F002F103880A940140908000F00563 +:105A7000E00A4EF300B9F00341C48001B406881C6B +:105A8000A6405A18FF04480000AB20000001221471 +:105A900080004E0500A54E1700A3B41FE6064EF287 +:105AA0000098800A8027B086B0C88086F50349FF39 +:105AB000FE7F5A0002044800008CB406A0F1F108F1 +:105AC000380070003851850138018101962FD93F87 +:105AD000B04A381094005A18013BF10622F48000B5 +:105AE000F2074240BC24884140120836A136D8193A +:105AF0009482996240178401B44542250475B645E5 +:105B0000F208A13794928844B48242438475B682E5 +:105B1000F2080443000894928844B4829A61D5162E +:105B2000956A88A4A137B44542250473B645F208A6 +:105B300094928844B48242438473B682F208044348 +:105B4000000894928844B4828824B622F10938511E +:105B50008501D93EB04A381094005A18013AF1072D +:105B600022348000F20642408C24884140120836DC +:105B7000A0B6D818940299509A59B40542050475F4 +:105B8000B605F009A0B794028802B4404223847598 +:105B9000B640F0090423000894028802B4409A51E8 +:105BA000D516956A88A2A0B7B40542050473B60558 +:105BB000F00994028802B44042238473B640F0098D +:105BC0000423000894028802B4408822B620B40658 +:105BD000442FFF80881CA641FE57AE418D418D2287 +:105BE00048FFFF47F0028CE18C1048FFFF358D0124 +:105BF00048FFFEFCFCCAFC403CADFF9F80C184E036 +:105C000085019B31E282E832A1470843000101C5CA +:105C1000003238F292020450000838929202A146F3 +:105C200038529202425E14244052A4B7AD58004547 +:105C300000334247902440422497AD192EF7C5E324 +:105C4000E8135052FF8797695CF2834FE80850428F +:105C50007F8797215CF2087BE80288E95CF38DADD1 +:105C6000E9033E8004688C68D5CDFCC0FC418120EE +:105C70008400B63F80E4AE28F28180C53C0DFF9FD2 +:105C800084204442C8B0E223E81104248001385142 +:105C90000501D91EA6B038120808A6B08C4196900E +:105CA000AEB000500019E245E9138009A670B45F58 +:105CB000F301808749FFFE2C8009A6B04412C8B0CA +:105CC000806749FFFF9A84004422C8B0D5038C2125 +:105CD000D5DBA670E201E80894433831000088273C +:105CE0008C01A8C9D5F7FCC1FC202E07E952FD3272 +:105CF0005A0801053C0C0180D50E9E0CE602E90411 +:105D00008E28E622E8043C0C017CD5052E07E971BB +:105D10004900082FB607B4073C1C017A4C00800AE2 +:105D20003C1C017B4C0080063C1C01874C00C004DD +:105D30008421D5028420445E000088A03C0FFAA78D +:105D400092A244027B9097693E17E930AD4044032C +:105D5000F40044101EE4AC404403F40297B0AF805A +:105D6000FCA084003C0FFAD94403F4038421AE4024 +:105D7000DD9E4403F403A6005C000001DD9E4403A5 +:105D8000F40CA6009600C8074413F3CFA6484000C1 +:105D90000406DD9E8401DD9E4413F40384003C0F61 +:105DA000FAD9AE08DD9EFC005A08011349FFDA82D9 +:105DB0005A0802074403F010441FFFAAAE4049FFEF +:105DC000FFD284003C0BF4E23E07E962D50349FFB1 +:105DD000FFE5FC804403F01DA680A641A6C040104C +:105DE000A008FE57581084009688AE809228A6819D +:105DF000AE414413F42144200055AE8844200000F5 +:105E00004430000A502100014C21FFFE8440AE883E +:105E1000442000004430000A502100014C21FFFEC4 +:105E2000A6409648AE40DD9E84004442D4E44452ED +:105E3000D2204412D16C4432D5DC38228000382282 +:105E4000000838218000382080088C015A0820F78B +:105E5000DD9EA640A7053E100D00A641A6C73E1038 +:105E60000D01A642404220083E100D02A6434031DB +:105E7000A0083E100D03A644002000088881A64615 +:105E8000972388610010000996DB4010A008882243 +:105E90003C1806840010000B0020000A4010A008E7 +:105EA00088223C1806850010000C3C4806823E10F3 +:105EB0000D0C0010000D3C3806833E100D0D001037 +:105EC000000E96463E100D0E0010000E92219646D2 +:105ED0003E100D0F0010000E922296463E100D103F +:105EE0000010000E922396463E100D110010000F78 +:105EF000965F3E100D120010000F92243E100D13FD +:105F000000100011002000104010A00888223C184A +:105F1000068A00100013002000124010A0088822FA +:105F20003C18068B0020001500100014968F4021AD +:105F30002008884196933C28068C00100015922278 +:105F40003E100D1A0010001700500016964F40101A +:105F5000A0088825964B3C18068E0050001792A288 +:105F60003E500D1E0000001E962F3E000D284002E0 +:105F70002C0A9606C006440FF000FF073C48068234 +:105F80004001AC0A9606C006440FF000FEC73C383C +:105F900006834001240AC006440FFC00FE873C280B +:105FA000068C4000A40AC006440FFC00FE473C18C3 +:105FB000068EDD9E3C1C017A440E00008801920290 +:105FC00044127B909601AC08DD9EA40044120000B0 +:105FD000940288013C0E0180DD9EFC004423F6A85B +:105FE0004413F6A95A080105AE108407D5038400AE +:105FF000AE10AE08840080208040FA6F490015F88A +:10600000FC80FC20B48084608C8484E6B4045A381C +:106010000506920A40002808D504921E4000780820 +:1060200042219C24969084A05A20200C386088003D +:106030008C414063140C8CA5880696905A581EF625 +:106040008C6196D8AA215A3806E3FCA0FC00B480E3 +:1060500084408C9C840080A098D096D8958238305B +:106060008C008C0196DF4031980C88A35A0808F602 +:106070008C489690AB615A2820EFFC80FC04A6491E +:10608000B4405A1003045A180D112E17E971542008 +:1060900080FBCA044412D710D5055A1803254412B0 +:1060A000D51849FFFFD5D51F5A180408A0578410EA +:1060B000FE0E58000003D5165030FFF6E662E80ADF +:1060C000842084463820FC088C215A1820FD803F0B +:1060D000D5E98E28E622E807A0578410FE0E580066 +:1060E0000004A817FC84FC00A68180C05A20031578 +:1060F0005A2006139E14E602E90F50017FF8E602CB +:10610000E90D50017FF6E602E9095A280D1C49FF06 +:10611000D8D15A0802048400D50284013E07E9134D +:106120002E07E913A6712E27E92984812E37E94627 +:106130004452B4E449FFFDDA4402B4E4802649FF46 +:10614000FF9FFC80FC00B48084405042002C8400FF +:1061500080A098D096D8958238308C008C0196DF3C +:106160004031980C88A35A0808F68C489690AB6189 +:106170005A2820EFFC80FC014412D4E4F08149FF4E +:10618000FF42F0014412D16C49FFFFDEFC81FC4468 +:106190002E200D124472D7108120386388004442AB +:1061A000D4E48EC25C6300014402D16C2E300D0138 +:1061B0005A18063C842A38120808E66284223810ED +:1061C0000808E96B49FFD8765A08026884005A9893 +:1061D00003182E100D0184004432D5183821800098 +:1061E000382F80088C015A0820FB2E000D12C00F9A +:1061F000881F8E228440E24110F07FFFD5083813BB +:106200008000381F80088C015A0820FB2E000D12D8 +:1062100084295A600103842A381F80084402B4E4A8 +:10622000803F49FFFF15D5398420381208085014E3 +:10623000FFFDE6228423E9028421E6623810080883 +:10624000E92C49FFD8375A08022984005A980319C3 +:106250002E000D0184285A0802038427840044324A +:10626000D51838218000382F80088C015A0820FB6F +:106270002E000D12C00C881F10107FFFD508381398 +:106280008000381F80088C015A0820FB5A6801C81A +:106290002E000D128422D5C14402B4E449FFFF6DE3 +:1062A000FCC43C4C0187442200FC54000FFF041244 +:1062B00000124000480892305410FFFF944A882290 +:1062C000462C003F0430800850210FFFFED6FEC749 +:1062D00014308008041200124432015092305410DD +:1062E000FFFF944A882304308008FE9EFE87142016 +:1062F0008008DD9EFC00441290743800811149FF33 +:10630000FFD2FC80FC4180C081223C0D98C6F08108 +:10631000CE04AF908441D50E80E15A680406800116 +:1063200049FFFFEAD504B001386004001074800012 +:10633000844384004432D16C386180088C0144125B +:10634000D16C5A0820FB2E000D1238208008440220 +:10635000B4E449FFFEF9FCC1FC0180C03E07E971CD +:106360008001B65FF38149FFFEC08006B43FF201B1 +:1063700049FFFFCAFC81FC413C0DFA9A84832E87B9 +:10638000E960A74184E0AF0144A2B390F581B69FD4 +:106390004492B4E43E77E91349FFFD482E67E97162 +:1063A0008048806A3E77E97184004472D2203C1DA7 +:1063B000FA9A49FFFFD38009802749FFFE24B49F42 +:1063C0008048806A84033C1DFA9A3E47E97149FF80 +:1063D000FFC58009802749FFFE163C0DFA9AF5019A +:1063E0003E67E9713E67E959AF41FCC1FC002E27C9 +:1063F000FE9E84C34011185744300090969044127A +:106400005F6042110C734420004849FFD9C92E0730 +:10641000FE9E8C0196004060183796484010041B81 +:106420003E17FE9EFC80FC002E27FE9D84C340117B +:10643000185744300120969044125C0042110C73AE +:106440004420009049FFD9AC2E07FE9D8C01960098 +:106450004060183796484010041B3E17FE9DFC8094 +:1064600084003C0BF4E63C0BF4D72E07E971540092 +:1064700000FBC812440228384412283AA6004422DD +:10648000283B3C0BF4D744022839A600A648A69026 +:106490003C2BF4E6D5235A080120840044522838C6 +:1064A000802044322850A7283C23F4D78CA4884469 +:1064B0003C2BF4D70022FFFD88020022FFFE0042A1 +:1064C000FFFF88223C23F4E69601884496493C2B42 +:1064D000F4E6DBEAD503840080203C23F4E688223E +:1064E0003C23F4D79649880296013C1BF4E68820A9 +:1064F0003C0BF4D73C1BF4E4DD9EFC02F082F183FC +:10650000B65F8002F1028043F38149FFD949B41F8D +:10651000F103F20149FFD944FC82FC00846080A3AE +:1065200084DF9718E282E80738500D0938608D093A +:106530008C61D5F8FC80FC56F08384C0F181F28236 +:10654000842044200090B00880E38124126F800BE7 +:10655000490064208401100F801A100F801E3C0D2A +:10656000FAA8107F8018107F801B1260000C126048 +:10657000000D3C0DFA7F109F8019107F801C106F5A +:10658000801F109F801D490011C5B0078040B04694 +:10659000490011FB3C0DFAA8FA231010000AAD8443 +:1065A0008400490012EFF001F1038040490011B767 +:1065B0004403F04A44100055AE40490011A644136C +:1065C000F140A6085A0001FFB0078040B0464900DC +:1065D00011DC3C0DFAA8FA241010000AF002F103B5 +:1065E00080404900119C4403F04A44100055AE40DD +:1065F0004900118B4413F140A6085A0001FF8401A1 +:10660000B0478041100F8019100F801DB00649005F +:1066100011BCF001F102B088490011813C0DFAA8CB +:10662000FA211010000A4403F04A44100055AE400D +:106630004900116B4413F140A6085A0001FF840081 +:10664000B047100F801E100F801F84018041100F73 +:10665000801DB006107F801C49001197501F8016C6 +:106660008041B0084900115B3C0DFAA8FA231010D4 +:10667000000A4403F04A44100055AE404900114559 +:106680004413F140A6085A0001FF020F800BFCD60C +:10669000FC004440012080C14412000042101073ED +:1066A00080018481802280434430004849FFFF45B7 +:1066B000AC30FC80FC00EED8F08184003C08021471 +:1066C000B066B00244224A204430004849FFFF1718 +:1066D000B042B0A644300048848344025F6049FF62 +:1066E000FF2C3C080214B042B0A64430004884811C +:1066F000F00149FFFF223C08021444124A20F00135 +:1067000049FFFE762E07E9715A0804153C03F4C9C7 +:106710005CF00097E90B9E8150107F6A440FFFCE1A +:106720004000801688029601D503440000963C0B79 +:10673000F4C949FFD5BF3C1DFFA85A00020A021048 +:10674000800E8403FE0C96014440FFFFD505020035 +:10675000800E0040802A3C1DFA9D2E37E8D0B441BF +:10676000924296865A280104E664E80B3C10021413 +:1067700040218409882240108C363C180214D5032D +:10678000440000A03C100214E2018402E90B2E2711 +:10679000E9712E00042CCA093C23F4E4E282E805E6 +:1067A0008C013E00042CD514C0048E013E00042C44 +:1067B0003C03F4F2E201E9093C03FF494410EA5FBB +:1067C000E220E9068C01D50284003C0BFF492E0033 +:1067D000042CE6028401E80284003E00042AED282D +:1067E000FC80944988204430FFFF84404C00800E98 +:1067F000A500E244E803A4809691A500E283E803A3 +:10680000A4C096D98C02D5F35CF180978003E9038C +:10681000440000969A109601DD9EFC4244600240BE +:10682000FF8444A20000400328008121441200029A +:10683000F381F48280E28826804044300090848195 +:10684000FAA04900115050830120838614AF8003C1 +:10685000F003FA3440AE0000800A49FFFFC40A1377 +:106860008001E220E8031203FFFFF302F101402E52 +:1068700018018822800A88438481FA7449FFFE5DEA +:106880000A148001E220E8031204FFFF51CE004801 +:106890004DC47FE0FCC2FC002E00041D2E100456E7 +:1068A000C01E3C0DF24A5A1801049201D502920210 +:1068B0003C2C01099601E2402E00042DE805E61E5D +:1068C000E80E8C01D50AC00B5CF10E10E905E60F4D +:1068D000E9038E05D5028E013E00042D5A18010DE4 +:1068E0002E00042D5A081E048405D508E6148406DB +:1068F000E8058407D503490015153C0FFA9CFC8078 +:106900003C33FF495CF18033E9109491884184A3C2 +:106910004C11000CA5080A300001FF2C90829262F5 +:1069200088641A308001D5F5DD9E84003E00042C79 +:1069300084003C0BFF49DD9EFC003C03FF495CF0FA +:106940000033E90649FFFFF384003C0BF4C83C0325 +:10695000FF485CF00033E90484003C0BFF48FC80F6 +:10696000FC0080C084003C0BF4E449FFFD7B49FF40 +:10697000D4A192C13C13E3305A0002088403FE44C0 +:1069800096494400FFFFD5053C0DFFA80000002BF1 +:106990002E20046C5A28010A84003C0BF4E4C11B2D +:1069A0002E07E984C009D50BE2C1E8153C13F4E4D5 +:1069B000E201E8F7D5102E00043AC0038401D50C9B +:1069C0003C1C01125CF08078E9093E00046C3C0B31 +:1069D000FF48D50584003E00046C8401FC80B4614E +:1069E000AE185A2802049208AE19B4018840B64184 +:1069F000DD9EFC448120B61F80C18400B1C13814E3 +:106A0000800038101C088C015A081AFB44001554E9 +:106A1000803F844249FFFFE53C0C017BB43F44A228 +:106A20000000A680AE880400001CB43F92109C8930 +:106A3000962FB65FAE09B41F803F8C01B61F84420B +:106A400044001EDC49FFFFCD3C0C017A803F04204E +:106A50000012925054217FFF94928942838A84428B +:106A6000B80C9210540007FF49FFFFBB020500124B +:106A7000803F844249FFFFB5B809803F921054001F +:106A80000FFF844249FFFFADB41F0015002044A250 +:106A90000150AE40B41F9C41B63F3C1C018704200E +:106AA0008012925054217FFF9492894284420015B3 +:106AB0000020AE41B41F803F8C01B61F0405000CBE +:106AC0009210540007FF49FFFF8C02050012803F1F +:106AD000844249FFFF8604050009803F921054005C +:106AE0000FFF844249FFFF7D440FFFAA10030051AE +:106AF0004413F04A44200055000300515A00CC04CE +:106B0000AE88D5FB840038138000381480088C01CF +:106B10005A081AFB840010030051FCC4FC205400E6 +:106B200000FBC00644725C0044600090D5054472CE +:106B30005F60446000482E07E9378E01E602E808EE +:106B400044024B4044124A20804649FFD6292E0772 +:106B5000E937540000FD5A08011095B184A0443271 +:106B60004B4098AB987D8403A5108E013840980D5A +:106B7000C8FC8CA2DEF7FCA0FC0049FFFEDF2E075C +:106B8000E971540000FBC80A44020A203C1C027749 +:106B90004420004849FFD604D50D44020A2044127F +:106BA0000A223C2C0277443000908481FAA04900EC +:106BB0000F9A2E07E937C00A49FFFEB92E07E9717F +:106BC00049FFFFAE84003E07E937FC802E100456D3 +:106BD0005A1801052E17C662D5033C13E3053C2D58 +:106BE000FA9DB442924296865A2801048C399649FD +:106BF0002E27E956CA052E27C66488229649AC403E +:106C00002E17C662AC44DD9E2E3004565A3801174A +:106C1000003000103E37C911A0053C0FF245A60A0E +:106C20003E07C95CA60B3E07C95DA4123C0BE4C33A +:106C3000A4133C0BE4C88405D514A6C03E37C91183 +:106C4000A0033C0FF245A6083E07C95CA6093E0713 +:106C5000C95DA4103C0BE4C3A4113C0BE4C8FA09C1 +:106C60003C0BE4C42E000439C008440001F43C0B82 +:106C7000E4C8840F3C0BE4C4DD9EFC405A00010ACA +:106C800044625C0080864410012044200090D509B5 +:106C900044625F6044424A2044100090442000480F +:106CA000840080A0385201098C0196C0E262E9FBA1 +:106CB000840694494432000081E080E4810384A08A +:106CC0000A94000102A380004094BD378CA1892A58 +:106CD00097681A938001DAF58E0196008861C8EEF4 +:106CE00095D194C188668423385201018E2196483B +:106CF00038519C0DC9FA8C019640E222E9F3FCC0A0 +:106D0000FC40848084FF838784C180A4814445E261 +:106D1000C8C802F00000548200FF40F788068120B6 +:106D2000E80F02F0800040F78C06E80A84C0386F54 +:106D30001008A580E2DCE80883868148D50585E156 +:106D400038FF1008D50284C0029480000AF0800148 +:106D5000892FE3278C818C024074BC1B40543C1B60 +:106D60005A4804D95A60010380AA8005FCC08020DB +:106D70003C0C017AC1195A1801053C0C0182DD9EB8 +:106D80005A1803053C0C017BDD9E5A1802053C0C89 +:106D90000183DD9E5A1804053C0C0187DD9E5A18BC +:106DA00005043C0C0188DD9EFC002E67E956CE35BB +:106DB0003C0C0112E614E9313CF7F5305EF7FFCFE9 +:106DC000E8043C6E0112D5294400007049FFCE9CB6 +:106DD0003C6BF4E08006442225B080663C13E2BAA6 +:106DE000E201E80698428C01AEC89601D5F83C0C49 +:106DF00002733C1C027549FFD4EE440000333C0B87 +:106E0000FF4944124A203C0C02774420004849FFC5 +:106E1000FD7984013E07E956FC8094D988604C01D5 +:106E200080051A200001D5FCDD9E4403F04A441081 +:106E30000055AE404413F403A608C8FFDD9EFC00D5 +:106E400084003C0FFAD93C0DFAAB8421AE4049FFD7 +:106E5000D7F54403F04A44100055AE403C2DFAAB40 +:106E6000A6505A1001FF44100055AE404413F403DD +:106E7000A6089600C8FE3C1DFAAB8441AE883C0EC5 +:106E80000112FC80FC0080C049FFFFD13C0DFA9A42 +:106E90003E67E97149FFF929FC80FC402E10046629 +:106EA0005A18011F2E10041D5A1801232E10046AAF +:106EB000C91F84223E10046644528F702E77C6D4B8 +:106EC0002E37E9712E4004662E900439842080C547 +:106ED00044A0005A4480007D45C00032D5245A1891 +:106EE00002082E10041D5A1001E98420D5E42E104A +:106EF00004655A1801FCD5DFC31A988100F10020FF +:106F000098A910F10184CC199881C314002100289C +:106F100040F304001027818C5A98010598B111C1E3 +:106F2000018C8C219688E247E9E8D50F38F00400FF +:106F3000D5E800210008D5ED5A4801051081018CE3 +:106F4000D5EC10A1018CD5E9FCC04422D018443204 +:106F50000000B482A09184A1041200129230541057 +:106F6000FFFF944A88234432015004108008944A59 +:106F70009234964B121000813C1BF4F10412001263 +:106F80000421001392305410FFFF944A88235421A7 +:106F90007FFF4432000C949288430230801B1030F3 +:106FA00001040230801B9268103001050230801A03 +:106FB000103001060230801A926810300107A4D305 +:106FC00010300108A4D3926810300109A4D1103008 +:106FD000010AA4D192681030010BA0D292785441DA +:106FE000803F0430800F9261FEEE94DFFEE71030A8 +:106FF000010CA0920410800F9248FE6E96AF944F41 +:10700000FE571010010DDD9EFC0080403C0C017B02 +:107010004432015083804402000CBC1200508104B1 +:10702000929054427FFF95228883BB1350F2003C1C +:107030005431FFFF94DA8860000081054000200889 +:10704000880596011202001B00008107005081068E +:1070500040002008880596011202001A0000810CE9 +:10706000B4CF92079541841DFE36FE2FB60F000067 +:10707000810DB4CF40501C09841EFE36FE2FB60F82 +:107080000000810900408108400020088804960122 +:10709000AC1B0000810B0040810A400020088804DE +:1070A0009601AC190040810CA01A972F405260083D +:1070B000464C0FFF50420FFFFF06FF2FA91A00108A +:1070C000810D440FC0FF966F4040A008A05AFE46B5 +:1070D000FE67A85AC2038E41969084033C1DFA9A1B +:1070E0004432B39049FFF93AFC80FC418121F081A0 +:1070F0008102814380E43C1DFAB6A60896005A0836 +:1071000001FE3C1DFAABAE0849FFD6983C0DFAB61D +:10711000A640C9FFA78097B05A6801FE00038051BE +:107120004003001B3E07E957F00149FFD38F3C0D98 +:10713000FAABAF800004812EC80649FFD39B3E679F +:10714000E957D512006380519786CE0649FFD39246 +:107150001064809ED50684003E07C66E49FFD2B6F5 +:10716000840110040000840A10050000440FFFAAE7 +:107170001003805184001003805210038053FCC11F +:107180003C1C017A54000FFF04208012041080126E +:107190004422005492305410FFFF944A8822402029 +:1071A000480804308008460C003F50000FFFFE1EC8 +:1071B000FE1714008008DD9EFC4280E0812180C221 +:1071C0008420801FFA4049005DE52E07FE94A678D2 +:1071D0004432B4204442CEA03811800840149800B4 +:1071E0009649C90284213812010984409D41449185 +:1071F0002D4C44A00BB8986A9657386184005A60A9 +:10720000FF0F38148800388209014210A82440106A +:10721000A036388F9A028828381F9A0A8C415A283B +:1072200008EC842080418061384F86029788E264B0 +:107230008C2140233C1B40323C1B5A1804F7E607C4 +:10724000E8043E57FE94D50484003E07FE94AEB891 +:10725000FCC2FC57B186B61FF181844884208006A9 +:10726000509F802049005D96842080098448490011 +:107270005D918400F1013C0802144400009040003C +:107280000416548000FF9401F08244A25F6084E001 +:10729000F0014C70003FB00AB05C804849FFF93FF4 +:1072A00050557CA08005B04AB09C80688481F583ED +:1072B00049FFF943920138131D019601E220F503BD +:1072C000E80338031D09505281204C557FEDB41F4F +:1072D000445DA0A088AA88A08005B04AB09C8068C0 +:1072E0008481F58349FFF929920138131D01960124 +:1072F000E220F503E80338031D098005802849FFD3 +:10730000FA72920138049D09F0028CE18940D5C1DE +:10731000B41F49FFF88A49FFCFCD3C1DFFA80220CA +:10732000800F5A0002058403FE84969180628026B5 +:10733000800949FFFCE78040100F8017381489014D +:10734000500F80173823090149FFFF382E07E960E5 +:10735000003F801738248101381301013C280214B2 +:10736000882238448D0138230D018844E041E80625 +:107370009A8A5CF100C8E805D5028440100F801796 +:107380009451443001F440108C37E623E807C907D4 +:10739000441000C740108806D5028423002F8017B0 +:1073A0002E57FE9CDA072E37FE9588613E37FE95F4 +:1073B000D5033E17FE952E37FE95E663E8035A186F +:1073C000030684003E07FE9580023E27FE9CFCD704 +:1073D0004412C8C8380080005A0801052E07C66547 +:1073E000DD9E8401DD9E84004412B420845F382039 +:1073F00080088C015A0808FD84003E07FE94DD9E3B +:107400005A0801068401AE088400D50E3C0DFFA881 +:107410000200000FE20440403C1BE283E9F4A410A8 +:10742000E61EE8048C01AC10DD9E8400AE08DD9EF3 +:10743000FC40810184203C1802144462C8C81081B9 +:107440000000842480E2814349FFFF058120380346 +:1074500020005A0801102E00042CE602E8048C01DA +:107460003E00042C84013E00045684003C0BF4C70B +:10747000D53084004412CE864422B3BE3C30021480 +:107480003C43F4F249FFFFBE2E00042CC0048E01E1 +:107490003E00042C5AA801128400802038230000EA +:1074A000CA038C2196498C015A0804FA5A1804061A +:1074B0003C03FF488C01D50284003C0BFF483C0391 +:1074C000FF494410EA5FE220E9048C013C0BFF49CC +:1074D00084003E00042A2E00042CC00684013E00D5 +:1074E000042A10938000FCC0FC40848140501002AC +:1074F0004062900C4470004888C1FF7C4490012099 +:10750000441200004052900C4210247380019855A0 +:10751000989D806749FFF811AC30FCC0FC4051FFDA +:10752000FDB0F081F182B67FB00444124A204430AD +:10753000009080E28440F48349FFFC714420FFFF07 +:1075400044300090500F813044124A2049FFFC67BC +:107550003C0DFAAB842184C0AE4084013C6FFADA62 +:107560004493F04A49000E154480005549FFF9DF65 +:10757000F0014C600041840085403E07E9763CAF55 +:10758000FADC49FFD45B108480002E07E976F10213 +:10759000E201E8262E17E9763C0DFADCE220E8F657 +:1075A0003CAFFADA2E07E976B43F5A780209F203C3 +:1075B000B0C4504F813049FFF932D50BB084503FF1 +:1075C00081305A78010549FFF865D50349FFFF8EE0 +:1075D0002E07E9768C0196003E07E976D5D73C0D5B +:1075E000FAAB84218CC1AE40440FFFAA3E07E936B6 +:1075F00097B0D5BF51FF8250FCC0FC038420844863 +:10760000B00249005BC784208448B00449005BC2D3 +:10761000840249FFFC39B0C2B1048401842684424B +:1076200049FFFF7EB04284448402490035A349FFEC +:10763000CE413C1DFFA80220800F5A0002058403A2 +:10764000FE849691B0428062B00449FFFB5BF081FA +:1076500049FFFECB840249FFFB1249FFFBE8F00122 +:10766000FC83FC0180C0840149FFFC0E8401842658 +:107670008040B0C1404F840049FFFF525A68010565 +:10768000800649FFFAFC49FFFBD2020F800249FF46 +:10769000F969FC81FC2149FFFA712E07E971C013D9 +:1076A0005A080453440000323C0BF4F24412CE86D4 +:1076B00084004422B3BE3C3002144440003249FFEF +:1076C000FEA1D5073E000456440000503C0BF4F2E6 +:1076D0003C0C0277842049FFF7EF3C0C0277441200 +:1076E0004A204420004849FFF90D2E07E95F5A005F +:1076F0000104480000BA2E60042A5A6001044800C0 +:1077000000B484003E0004584400004349FFC9FC13 +:1077100049FFFF7580403C1DFA9A4432B390100F28 +:107720008007840349FFF61A84003C0BF4C73E0728 +:10773000E9563E60045649FFFB8449FFF8F83E6075 +:107740000458480000924400012C3C0BF4F22E0037 +:10775000042B5A080107440000313C3C0112D505B6 +:107760008460C8052E37E94B40300C063C0C02778C +:107770002E17E960502F800749FFFE5C2E07E95F56 +:107780005A0801732E00042A5A0801242E67E94181 +:107790005A6801202E57E960000F8007D06584E009 +:1077A000440000483E70045849FFC9AE49FFFB3F02 +:1077B00084033C1DFA9A002F80074432B39049FF9E +:1077C000F5CD3E77E9563E60045849FFFB3AD54C6B +:1077D0003C03FF485CF000322E00046CE902C00854 +:1077E0005A0801433C0C01125CF00078E93D44006A +:1077F000004284C049FFC9883C6BFF4849FFFB1722 +:107800002E07E97149FFD022840149FFFF2CC823CC +:107810002E20042BCA0E3C1DFA9A4432B39049FF25 +:10782000F59D3E67E95649FFFB0C49FFF880D51CE2 +:1078300084033C1DFA9A2E27E9604432B39049FF35 +:10784000F58D3C0C01125CF00033E90E84013E071B +:10785000E964D50A84033C1DFA9A2E27E960443274 +:10786000B39049FFF57B2E07E9713E07E9593C0DBE +:10787000FFA80000002EC00B3C10021444022D543F +:10788000AC403C13F4E944022D56AC40FCA1FC0092 +:107890002E000D123C1DFADC8C01E220E80449FFA9 +:1078A000F26AC00C84003C0BF4E249FFF26AC8178C +:1078B00049FFF5D849FFFEF0D5122E07E9345A08E2 +:1078C00001064402B3F449FFD2D384408401842AE0 +:1078D0008062808080A249FFCD4DD5DBFC80FC40DA +:1078E0002E37E9712E07E9502E17E92E2E27E91DB4 +:1078F0002E400D28CB0480A080C1D50580A280C475 +:10790000804080813C7C0275FF74FEA484604492B8 +:1079100011703C03E2BAE260E81A941940102400A6 +:1079200040A3800002808000A44802050000FE649D +:107930009A08FE2C428418244000081640040001D6 +:1079400096018C611205000096D9D5E43C0C0275B5 +:107950003C1C027349FFCF3FFCC044524A204420E4 +:1079600003E844324AB05A080509A52802128048A3 +:10797000FE6440108837D5095A08010AA4680242FB +:107980008048FE54401090379649AC688CA2DBECDE +:10799000DD9EFC4180C0812181028143F4812E77EC +:1079A000E9715A080113C1049F49549280FF2E5770 +:1079B000E9604C5480092E00042B5A080105800907 +:1079C000490013798403D5095A08020F5A7804052F +:1079D000840149FFFFC484003C1DFA9A8049443267 +:1079E000B39049FFF4BB3C1DFAB6A60896005A08AE +:1079F00001FE3C1DFAABAE0849FFD2203C0DFAB6A1 +:107A0000A640C9FFA6405A1801FF2E07E97149FF99 +:107A1000CF1D2E07E971C8045A780408D5045A0806 +:107A20000405CF0349FFFF5D5A6801081064000098 +:107A3000840010650000D5095A68020A8400100409 +:107A40000000100500008401F101AE08FCC1DD9EBC +:107A5000FC0080C0C82444020A2044125F60442015 +:107A6000004849FFCE9D44020A2044125FF04420A2 +:107A7000004849FFCE9544020A2044126080442009 +:107A8000004849FFCE8D44020A2044124A20442077 +:107A9000004849FFCE853E60042AD51049FFF4E234 +:107AA00044020A20842049FFF60744020A204412B7 +:107AB0004A204420004849FFF7252E07E95FC80304 +:107AC0003E00042A2E00042AFC80FC400090800026 +:107AD0004E930008445000FF80C980E98065D52995 +:107AE0008420445000FF80C180E180659708E289CE +:107AF000E820A10138A2050197094CA2401904A071 +:107B00000005950A888A00A20002E34340353C1B29 +:107B100000A20003E2EA40753C1B00A20000A7217E +:107B2000E34540553C1BE2C440623C1B8C21D5DF41 +:107B30008400E2E3E92A8540408190088085802A1C +:107B4000E2C4E9184094100040948408892202F4A9 +:107B5000800040F780115EF78033E909E688E80489 +:107B60008C219648D5048D4154A500FF8C81972027 +:107B7000D5E8E34140153C1A9708E28040103C1BD1 +:107B80008C61960896D8D5D6E602E8028402FCC03D +:107B90003BFFFCBCEFFC49FFCB8D5A0802124403AB +:107BA000F04A44100055AE403C2DFAD7CA09840172 +:107BB00080208062808080A249FFCBDCD5F6EC0477 +:107BC0003BFFFC84DD9E3A6F9EBCEFF080C0A601B7 +:107BD000F282F3835A080408A6305A08010584008B +:107BE00049000C7C2E07E97D5A08010C4402B3AD14 +:107BF000F102F2033C3DFAA63C4DFAA4490050D3F1 +:107C0000440FFFAA3E07E9793C0DFAA43C1DFA9AFD +:107C1000B61F4422B364F302F4033C5DFAA64402A7 +:107C2000B4B0490051E996003E07E96949004D3674 +:107C30002E07E9695A00010584013C0FFABFA631FD +:107C40005A080816A6305A000204480000A83C0D45 +:107C5000FAAE5A00067C5A0009044800009649FF13 +:107C6000CB295A00020448000090D5705A08090E2A +:107C7000A6305A000204480000923C0DFAAE8E066F +:107C8000E6024EF20082D5625A080A08A6308E0239 +:107C9000E6024EF20084D55A5A08030DA7B05A687E +:107CA000017E800649000A86800649000A7284081F +:107CB000D576540000FD5A080472A6305A08016FA8 +:107CC00049000A783C0DFAAE5A08060C4403F04A03 +:107CD00044100055AE4084003C0FFAD749FFFF5ACC +:107CE000840149000A5649000CA43E07E94849FFAF +:107CF000CAB52E57E95D84203E07E9173E17E927EC +:107D0000D00649FFCEAB84013E07E9272E07E917CD +:107D1000A7F13E07E95D5A78061A2E07E9482E2793 +:107D2000E93FE240E91584003E07E93F3C0DFA9A3D +:107D300049FFF1DB2E07E971802749FFF22A840110 +:107D40003E07E98384003C0BF4DB8408D528CA0392 +:107D50003E07E93F8404AE312E000D1249000D1399 +:107D600080E0C8F4840149000BB9800649000BCDBE +:107D7000F082F102840280478461808780A749FFF6 +:107D8000CAF98408D50C844084618402FA25808372 +:107D900080A249FFCAEF8408D5028401EC103A6F33 +:107DA0009E84DD9E3BFFFCBC8401EFFC49FFEFFDA0 +:107DB0004403F04A44100055AE404413F403A608AF +:107DC0005A0001FFEC043BFFFC84DD9E3A6FA8BC27 +:107DD000C00349FFC657446000654473F04A4490AD +:107DE000005549FFCA67C0128EC1C6108421804168 +:107DF0008061848044004F004900360944000064DB +:107E000049FFC61110938000D5ED84003A6FA88415 +:107E100048FFC9E02E07E921C8072E07E9698E044B +:107E20005C000002DD9E8400DD9E0000A6C18E6322 +:107E3000E6694EF202DB3A6FA4BCEFF480E280C048 +:107E400044F07D5038378D0140F1BC004A003C00C1 +:107E500012004E0192056C0292054203AC036C04C1 +:107E600014053C0DFAAE5A08091E49FFCA235A08E8 +:107E7000021A4402B3414412B3E449FFCBEB44027B +:107E8000B3644412B36B49FFCBD6840CAE313C0DC6 +:107E9000FA9A842049FFCE888403AE31FA003C0F61 +:107EA000FAAE2E07C5DAC00F5A0001092E07C5DA4F +:107EB0005A00010448000297D5363C03E4D6A07B63 +:107EC000E220E8F54403F04A44100055AE404493E4 +:107ED000F04B3C0DFAB6A600C8EA3C0DFAABA60082 +:107EE0005A0801E62E07E9345A0801064402B3F4A1 +:107EF00049FFCFBE3C1DFADC2E07C56FE220E8EA41 +:107F0000000480004413F04B5A00FF05841FAE08A4 +:107F1000D5FF84408401842A8062808080A249FF4A +:107F2000CA29D5D80493800349000B17E320E80C35 +:107F3000A63A5A0001072E07E9875A080111D5070A +:107F40002E000413C8F949FFDD0CC8F64403F04ABB +:107F500044100055AE403C1DFAB6D50F2E07E94C33 +:107F60005A0001F649FFFF58C8F22E07E9635A008C +:107F7000010448000238D5EBA608C0FF8406AE31E4 +:107F800084023E07E98349FFC9693E07E95D49006C +:107F90000C8B3C0DFAAB8420AE40480002242E0727 +:107FA000E981C826800649000A3D2E07E918C8075E +:107FB0004402D3FC49FFCA6549000E402E07E981FF +:107FC0005A00031C84213C0DFA9A49FFCDED84012F +:107FD00049000A84800649000A98F081844084029E +:107FE000F1018461808280A249FFC9C4D5065A0884 +:107FF000030584013E07E98184003E07E9832E17CB +:10800000E969800649000EE52E07E9865A08010451 +:10801000480001E92E07E93D5A080104480000B66E +:108020002E07E9815A080304480000B0A631490030 +:108030000A8249000A123C73F4DBA63149000A8522 +:10804000E2E0E8052E07E9635A0801232E77E929C3 +:10805000440FFFAA3E07E93697F88406AE315A78F6 +:10806000011380273C0DFA9A49FFCD9E80064900F6 +:108070000A4CF08184408402F1018067808280A2F2 +:1080800049FFC9784403F06D8424AE40D5093C0D06 +:10809000FA9A842149FFCD88840149000A1F80068D +:1080A00049000A33F081F101EC0C844084028461C0 +:1080B000808280A23A6FA48448FFC95C2E07E983BE +:1080C0005A08012F49000F5A2E00043A5A08011588 +:1080D00049FFC8F05A080211490014D680C03E0773 +:1080E000E93D5A08010A840049001F4084003E60AF +:1080F00004133E00043A2E07E93D5A08010B2E678F +:10810000E963CE0749000AB33E67E97A4800016B8C +:108110003C0DFA9A842149FFCD474800012F5A00AF +:108120000204480001602E77E9635A78010B3C0D88 +:10813000FA9A842049FFCD383E77E98348000153FD +:10814000A608C80B2E07E93DC8088404AE313C0DD3 +:10815000FA9A49FFEFCAD5A149FFFE5EC8F72E077C +:10816000E9875A0001F42E07E94C5A0001F02E006D +:10817000043A5A08010649FFC89D5A0002E83C0D1E +:10818000FA9A842049FFCD10EC0C3A6FA484480081 +:108190000A6E3C0DFAAE5A08062084003E07E981BB +:1081A0003E07E9833E07E9483E07E9264402D3FC3F +:1081B00049FFC96749FFC87EC00749FFC9D23C03D0 +:1081C000E4E649FFFE05840349FFC49EEC0C3A6FC8 +:1081D000A48448000A915A0009044800010449FF98 +:1081E000C8695A000204480000FE3C0DFA9A842037 +:1081F00049FFCCDA8403AE31480000F52E97E981BF +:108200004E93001B4900090E49000D183C0DFAABB6 +:108210008421AE402E07E9815A00031480064900EC +:108220000974F08184618402F1018049808380A90E +:1082300049FFC8A0D5065A98030584013E07E98185 +:1082400080062E17E96949000DC42E07E9865A08F1 +:108250000104480000C82E07E93D5A0001062E0718 +:10826000E9815A080307EC0C3A6FA48448000A44D9 +:10827000A63149000960490008F03C93F4DBA631BF +:1082800049000963E320E91285203C0DFA9A149312 +:108290008003802949FFCC88840BAE3184013E07DE +:1082A000E9833C9BF4DB4800009E80064900092DD1 +:1082B000F081F101840284404800008DA6005A0834 +:1082C0000244A608C8042E07E93DC0082E07E93875 +:1082D000C0052E07E9875A08012EA1FB490019BDE8 +:1082E000E2E0E8082E07E938C0052E07E9875A08BA +:1082F000017A4403F04A44100055AE403C1DFAB6E2 +:10830000A608C0FFA63149000916F081F101440218 +:10831000B3B14422B40649000A9B8400842B3C0B71 +:10832000F4DBAE7184223E17E9833C1DFAABAE0844 +:10833000D5598400A83BEC0C84011003801C3A6FD3 +:10834000A4844800195D3C0DFAAE5A080709840957 +:10835000AE31490009D1FA003C0FFAAE8400100397 +:10836000801CD5402E07E9835A0801103C0DFA9A6B +:1083700049FFEEBB49FFFD1884023E07E9833C0D2F +:10838000FAAB8420AE40D52E5A08022D84003E0759 +:10839000E983A608C8042E07E93DC00A2E07E9387C +:1083A000C0072E07E9875A00010448FFFF5E8409D1 +:1083B000AE313C0DFA9A49FFEE983C0DFA9A8421B1 +:1083C00049FFCBF2840084401003801CA8BB8402C8 +:1083D000FA26EC0C8461808380A23A6FA48448FF63 +:1083E000C7C9EC0C3A6FA484DD9E92004403F04AA6 +:1083F00044100055AE404413F403A6085A0001FF90 +:10840000DD9E00003A6FA8BC812080E249FFC7E3EF +:1084100080C049FFFFED5004FFFFE60C4EF20186DD +:1084200044F083303807810140F03C004A003C00B2 +:1084300018007A0050016202BA00F802F802F8024D +:10844000F802F8028C02DE024400003049FFC35CEF +:10845000840EAE398405AE383C1DFA9D84001003AD +:108460000050B441440FBFFFFE16B6014463F04A0A +:108470004490005549FFC71E5A080205109300009A +:10848000D5FA4403F0108420AE4049FFC713C02042 +:10849000842180418061808144005AF0490032B7D4 +:1084A0004400006449FFFC94D513840EAE39840661 +:1084B000AE3884001003005080A650030041843F72 +:1084C00018128001D8FE4403F0108420AE408007CB +:1084D000842149FFCB6984208402804184618081AA +:1084E00080A13A6FA88448FFC7454400003149FF86 +:1084F000C30B4403F42985201090000049FFEF3D91 +:1085000084013E97E913AE38109300502E07E9130B +:10851000A6792E27E92984812E37E9464452B4E40E +:1085200049FFEBE42E07E971C8084402B4E44412A1 +:10853000D71049FFED8DD5095A0803084402B4E469 +:108540004412D51849FFED8484003E0004542E10D7 +:10855000045884003C0E011184013E07E92A5A1098 +:1085600001043E07E937840049000613A6398E0846 +:10857000E6044EF200DE80073A6FA88448FFC7BACF +:108580004400003249FFC2C03C1DFAAB8402AE0871 +:10859000AE38A6399E43E624E9075A000D065A086C +:1085A0000E0749FFC86A8408AE39D5038409AE397D +:1085B0008520109300503E97E9423E97E92749FFF6 +:1085C000EEDC3C0DFA9A49FFED904463F04A3E9789 +:1085D000E9054490005549FFC66D5A0802051093FD +:1085E0000000D5FA4403F0108420AE404403F4297F +:1085F000441FFFC3AE4049FFC65DC009842144004B +:108600005AF08041806180814900320184003C1D24 +:10861000FA9D3E00045484003C0E0111B441440F05 +:10862000BFFFFE16B60184013E07E92A2E07E97551 +:108630005A080306840949FFC780D504840549FF09 +:10864000C77C2E0004585A00010584013E07E93713 +:1086500084004900059E8007842049FFCAA53C0D7F +:10866000FAAE5A0004045A08070C8421844084029C +:108670008062848F80A13A6FA88448FFC67B8440C3 +:108680008402FA258062848F84A13A6FA88448FF0F +:10869000C6713C0DFA9A842049FFCA86840AAE3915 +:1086A0008403AE388400100300503C0DFA9A49FF51 +:1086B000ED1C84013A6FA88448FFD95C49FFC5FAD4 +:1086C0003C1DFA9A5A08020CA6095A0003128001AE +:1086D000842049FFCA69490007CAD50AA6095A0079 +:1086E0000A088001842049FFCA5F49000805000389 +:1086F0000051001300524422B37F4432B35144422C +:10870000B38F49FFF948840010030050D5110003CE +:1087100000515A0001055A08020584003E07E9632A +:10872000840010030050D504841B100300503A6FDE +:10873000A884DD9EE606E87544F086483807800088 +:1087400040F03C004A003C00062644D8669E441394 +:10875000F24884014423F249AE088422AE504423F7 +:10876000F24A8464AE104423F24BAE50D530441329 +:10877000F248841FAE084413F2498448AE084413FB +:10878000F24AAE084413F24BAE08D53C4413F2480B +:108790008401AE084413F249AE084413F24AAE080D +:1087A0004413F24BAE084413F24CAE08D52E4413DA +:1087B000F24884014423F249AE088424AE50442395 +:1087C000F24A846CAE104423F24BAE504423F24C78 +:1087D000AED04423F24DAE504423F24EAE104423AB +:1087E000F24FAE50D51B4413F2488400AE08441338 +:1087F000F2498441AE084413F24AAE084413F24BE6 +:10880000AE084413F24CAE884413F24DAE08441344 +:10881000F24EAE084413F24FAE084413F250AE08C5 +:10882000DD9E9200C103580000104413F2519600DF +:10883000AE08DD9E40003C084423F2449210AC1088 +:108840004010BC084403F2469230AC40DD9E440325 +:10885000F2408421AE404413F04A44200055AE88D3 +:10886000A6405A1001FFDD9E4413F258A448AC40C4 +:108870004413F25AA448AC414413F25CA448AC42FD +:108880004413F25EA448AC434413F260A6481010AF +:108890000008DD9EFC02F0818002F383F18249FF33 +:1088A000FF4BF001F10249FFFFC749FFFFD2F00380 +:1088B00049FFFFDCFC82FC02F0814403F242F182BA +:1088C000F283AF40001F80204403F243AE404403D4 +:1088D000F2528421ACC04403F254AD004403F2567A +:1088E000AC40001F80244403F241AE40000F8028BA +:1088F000001F802C49FFFF98F001F102F203F30CF6 +:1089000049FFFFCAFC824403F1408421AE40DD9E52 +:1089100084203C0FFAA8AC43DD9E3C3DFAA89201AE +:1089200092219241AC18AC59AC9ADD9E3C1DFAA83C +:10893000A6821020800CA6831020800DA680A601A0 +:108940001020800E1000800FDD9E3C1DFAA8A6822C +:1089500010208010A68310208011A680A601102070 +:10896000801210008013DD9E3C1DFAA8A682102004 +:108970008014A68310208015A680A60110208016E2 +:1089800010008017DD9EFC01B63FF28149FFFFD049 +:10899000B41F49FFFFDCF00149FFFFE8FC81FC2424 +:1089A000F081F182F283001F803C002F8038000F9D +:1089B0008040007F8060006F804C105F8016103F09 +:1089C0008014102F8017104F8015101F801A103F31 +:1089D0008018100F801B104F8019CF08105F801E69 +:1089E000103F801C102F801FD507101F801E103FC6 +:1089F000801C100F801F3C0DFA7F104F801D49FF17 +:108A0000FF89B005B046B08749FFFFBFF001F10212 +:108A1000F20349FFFF843C0DFAA8021F8028002FB3 +:108A20008044AC44001F8054FE775263001095B11F +:108A3000FF8F001F80481060000A58108040FE57CA +:108A40001010000B221F802C1210000C221F802EF1 +:108A50001210000D4403F04A44100055AE40440388 +:108A6000F1408421AE40A6405A1001FFFCA4FC0254 +:108A7000B61F2E07C54FF1812E17C55084C1100FA8 +:108A8000800A100F8009100F800D3C0DFA7F101F17 +:108A90008008101F800C101F800F106F800B106F4C +:108AA000800E49FFFF37B0438041B00249FFFF6DA0 +:108AB000F101B41F804149FFFF323C0DFAA8842226 +:108AC0001010000A84201010000B4403F04A4410D8 +:108AD0000055AE404403F140AF80A6405A1001FF5C +:108AE000FC82FC24F08194199600100F8017100F5F +:108AF000801B840184E2100F801E3C0DFA7F80C52C +:108B0000103F8014104F8015103F8018104F8019AF +:108B1000103F801C103F801F104F801DF182F28398 +:108B2000107F8016107F801A49FFFEF4B005B04612 +:108B3000B08749FFFF2AF001F102F20349FFFEEF7F +:108B40003C0DFAA82E27E9578420AC445A28010886 +:108B500095B31070000A1060000BD50684491020F0 +:108B6000000A1010000B4403F04A44100055AE40B8 +:108B70004403F1408421AE40A6405A1001FFFCA4FA +:108B80003C1DFAA81000800BDD9E4403F04A4410FF +:108B90000055AE404413F403A6085A0001FF4403F5 +:108BA000F3808421AE404413F04A44200055AE883F +:108BB000A6405A1001FFDD9E4453F381944AA72832 +:108BC0009407544200F0FEA7FE579648FE0F960009 +:108BD000AE284403F38496D8AEC0DD9E4413F386DA +:108BE0008400AE084413F387AE08DD9EFC00440306 +:108BF000F38496D8AEC049FFFFCA4403F04A44103C +:108C00000055AE404413F380A6085A0001FF4463A8 +:108C1000F3804403F386A6005A08010F49FFFFE0E2 +:108C200049FFFFB54403F04A44100055AE40A6305A +:108C30005A0001FFD5EF4403F387A6005A0001F064 +:108C4000FC804413F280A60858000001AE08DD9EA7 +:108C50004423F2809405A650FE479648AE50DD9E10 +:108C6000441E000088014413F2869681AC8892105D +:108C70004413F2889606AE08DD9EFC40810080C158 +:108C8000A4404403F28445C3F280AC4004040001D4 +:108C900049FFFFE8001400084403F2834473F04ADC +:108CA000AE4044900055001400090024000A964686 +:108CB0009409001E00003DCFFA81541080FDFE474C +:108CC000101E0000968694D2002E0000440000552D +:108CD000542100FBFE9F102E000044A3F418AE3870 +:108CE00002050000C011020500005CF00781E80CDD +:108CF0004403F2918421AE400004000B49FFFFAA17 +:108D000049FFFFA1D50649FFC2D55A0002EBD5F1B4 +:108D1000000E00009606C00410938000D5FA44139C +:108D2000F291AE084403F2813C0FFA805A680307BF +:108D3000A64092229646C1B8D5085A680105A600F9 +:108D40009202D5055A680206A60092039606C0ACA8 +:108D5000FCC09404FE4796084413F481AE08DD9EDF +:108D60004413F48396019680A6C89208AE88A6891B +:108D7000AE09DD9E4413F48596019680A6C892083C +:108D8000AE88A689AE09DD9E4413F4879680AE882E +:108D900092084413F4889600AE08DD9E4413F489CB +:108DA0009600AE08DD9E4403F48244200055A640A0 +:108DB000541080FE58108001AE404413F04AAE8833 +:108DC000A6409646C9FEDD9E3A6F98BC4463F00EFD +:108DD000A43054000100C00944122CF4A6088C01F0 +:108DE0009600AE088408D575A430960EC85FA430EE +:108DF000961EC00944122CF3A6088C019600AE08FA +:108E00008403D567A4309616C00944122CF2A60834 +:108E10008C019600AE088402D55CA4309626C00969 +:108E200044122CF1A6088C019600AE088404D5519A +:108E3000A4309606C803FA00D54C49FFBB93A43072 +:108E40009636C836A430962EC835A430963EC8341F +:108E5000A43054000200C00C4403F064A6409646BF +:108E6000C12DA640541080FEAE408409D532440383 +:108E7000F00EA44054108400C923A440541088006C +:108E8000C921A44054109000C91FA4405410A00050 +:108E9000C91DA4405410C000C91BA400920FC0CC2F +:108EA00084013E00041C840FD5148401D51284066D +:108EB000D5108405D50E8407D50C8409D50A840AFB +:108EC000D508840BD506840CD504840DD502840EF8 +:108ED0004413F00E8440AC883A6F9884DD9E4403BE +:108EE000F3228421AE40DD9E4413F323AE08DD9EC1 +:108EF0004403F323A600DD9E3A6F9C3C4463F54097 +:108F0000B6064403F544B6204403F548B64044038E +:108F1000F54CB6604403F550B6804403F554B6A052 +:108F2000F1024403F558B620F1034403F55C3A6FAF +:108F30009C04B620DD9E3A6F98BC44212D54EFF876 +:108F40003A210C003A2F8C204423F5044443F502C7 +:108F50004433F5033C2FFA834423F505803F3C4F0F +:108F6000FA863C3FFA853C2FFA825A0002044800F8 +:108F700000904453F500443C0B004403F50898ABC3 +:108F80003820880018228001D8FB4403F5074410DC +:108F90000045AE404403F50084C1AF8084008020CA +:108FA0008040806049FFFE244403F5018423AE40E5 +:108FB000840080208040806049FFFE1A3C1DFA86B4 +:108FC000A60858000002AE0884008020804080601F +:108FD00049FFFE0E440007D049FFBD253C1DFA8520 +:108FE000A60858000002AE088400802080408060FF +:108FF00049FFFDFE440003E849FFBD1584008020C1 +:109000008040806049FFFDF43C3DFA863C2DFA85A6 +:10901000A658A6105810801D5800001DAE58AE105E +:10902000840080208040806049FFFDE22E07E95BDC +:10903000C81B3C0DFA9A3E67E95BA78149FFC13A1C +:109040003C1DFA9A5A0802058404AE09D503840926 +:10905000AE093C0DFA9A49FFE848840149FFE6A5AC +:109060003C0DFA9AAF81440005AA49FFBCDC49FFD8 +:10907000E682C0FE3C2DFA86440FFFEFA650FE4666 +:10908000AE503C1DFA85A688FE16AE08D562C833E0 +:109090004403F5008421AE404403F5018423AE402F +:1090A0002E200D103C1DFA863C0DFA85CA09A688B3 +:1090B00058210001AE88A68058210001AE80A68804 +:1090C00058210002AE88A64058108002AE408400AD +:1090D00080208040806049FFFD8B3C3DFA863C2D1E +:1090E000FA85A658A6105810800C5800000CAE58EF +:1090F000AE10D52F5A080137A620A758845BFE165C +:109100008437FE0EFEAEAE20FE568400AE58804080 +:109110008020806049FFFD6C4413F5008400AE0898 +:109120004413F501AE082E100D103C2DFA863C0DAF +:10913000FA85C908A6D0843EFECEAED0A6C0FE5E9B +:10914000AE40A6D0843DFECEAED0A680FE56AE4048 +:10915000EC0884008020804080603A6F988448FF4B +:10916000FD47EC083A6F9884DD9EDD9E4610800036 +:109170006413240364230402461F7FFF50108FFFF3 +:10918000FE5640006C08FE0F64030403DD9E46108B +:1091900008006413240364230402461FF7FF5010E1 +:1091A0008FFFFE5640005C08FE0F64030403DD9E43 +:1091B000441080006413240364230402441F7FFFCF +:1091C000FE5640003C08FE0F64030403DD9E400091 +:1091D0003C084433F2009210AC184010BC08440321 +:1091E000F2029230AC4040213C084403F204925019 +:1091F000AC80DD9E4403F20A44200055A640541082 +:1092000080FE58108001AE404413F04AAE88A6405C +:109210009646C9FEDD9E4423F2069600AE10440336 +:10922000F2079648AE40DD9E440232E8DD9E4402DD +:109230002F00DD9E4403F20BA600DD9E4413F208CE +:10924000AC08DD9E4423F20A9401A6509646FE47E0 +:109250009648AE50DD9E0000E608E82544F0916C8B +:109260003807800040F03C004A003C00080E141A09 +:1092700020262C324403F20CD5154403F20ED512ED +:109280004403F210D50F4403F212D50C4403F21438 +:10929000D5094403F216D5064403F218D503440356 +:1092A000F21AAE40DD9E9200E608E82544F091BC3B +:1092B0003807800040F03C004A003C00080E141AB9 +:1092C00020262C324403F20DD5154403F20FD5129B +:1092D0004403F211D50F4403F213D50C4403F215E5 +:1092E000D5094403F217D5064403F219D503440304 +:1092F000F21BAE40DD9E92004413F050A6085800C9 +:109300000080AE08DD9E4413F050A6089637AE08E4 +:10931000DD9E4413F051A60858000001AE08DD9E02 +:109320003C0DFFA9A600DD9E4402400044124510FA +:109330003C0FFAB53C1FFA963C0FFA9BDD9EC00429 +:109340005A000209DD9E3C0DFFA9A6003C0FFA2140 +:10935000DD9E3C1FFA21DD9E40003C084433F1C4F1 +:109360009210AC184010BC084403F1C69230AC40D7 +:1093700040213C084403F1C89250AC80DD9EFC00C3 +:1093800044028F700020000F001000104403F1C24F +:10939000AE804403F1C3AE403C0DFAB53C1DFA96D5 +:1093A0003C2DFA9B49FFFFDAFC8084003C0FFAD683 +:1093B0004403F1C08421AE40DD9EFC0649FFFFE17D +:1093C0003C0DFA215A000F134413F1C19600AE0868 +:1093D00049FFFFED4403F04A44100055AE404413EA +:1093E000F1C0A6085A0001FFD51BFA202E37C54F41 +:1093F000F1858422840084A1F18744124000F08327 +:10940000F084F086F088F0892E47C550B67FF5814C +:10941000F382F58A44024510804149FFFAC2FC8676 +:10942000FC00842049FFC3C0840149FFE4BE8401DD +:109430008440842A8080806280A249FFBF9B4403CD +:10944000F04A44100055AE4049FFE495C8043C0D75 +:10945000FAD9C0FBFC802E17E9265A10FF3E2E27B2 +:10946000C9CBE022E9039E5196484422E1B4383149 +:109470000501E260E931FC208400380105093C0B5C +:10948000F4EB842084832E07C5439401E020E82375 +:109490003C3C027D3C0C027E3C5C028694898862E6 +:1094A000880288A1A598A5C0A62888074203107342 +:1094B000405008099769AD583C5C027D3C3C0286EF +:1094C00088458861A4908C2194928A029600AE18F7 +:1094D0009648D5DAFCA0DD9EFC005A0801132E1038 +:1094E0000D012E000D005A1801048E03D5028E02C4 +:1094F0002E100D1296005C10800349FFBEB4D503F8 +:1095000049FFBEC2FC80FC0049FFBED45A080210CD +:109510002E07E929C8092E07E926E6038405E8098C +:109520002E07C9AED5062E07C9AFD5032E07C9B081 +:10953000FC80540000FD5A0804053C03FF56DD9EE4 +:109540003C03E4DFDD9E5A0804053C03FF55DD9E25 +:109550003C03E4E0DD9E3C0DFA7EA400DD9EFC00B1 +:10956000B400920196065A080109440000643C0BBD +:10957000FF5644000168D5073C03E4DD3C0BFF5671 +:109580003C03E4DE3C0BFF553C13F47D3C03FF56EB +:1095900049FFC2583C0BFF563C13F47D3C03FF557A +:1095A00049FFC2503C0BFF55FC802E17E921C90A28 +:1095B00084423E17E9383E27E9583E17E93D10102E +:1095C000001CDD9EFC004403F04A44100055AE40F0 +:1095D0003C0DFAD9C8122E07E9345A080106440294 +:1095E000B3F449FFC44584018440802080628080B8 +:1095F00080A249FFBEBFD5ED3C0DFA9A8429AE4149 +:10960000842149FFC2D13C0DFA9A842AAE412E270B +:10961000EAE8CA0A84022E17C9B18461848380A251 +:1096200049FFBEA8D504840E49FFBEC1FC80FC00E2 +:1096300049FFBE405A08020E4403F4222E17C9CA3D +:10964000A600961FE220E907C0068E019600D50508 +:109650008400D503440000FFFC802E07E926842007 +:1096600050007F0140008006DD9EFC003C0DFA9A10 +:10967000842384C1AE4184253E17E9473E67E9440F +:1096800049FFE5332E07E971842349FFE5823C0D4C +:10969000FAB6AF803C0DFAABAF802E0004135A0827 +:1096A000010B84003E07E98184003C0E01113E005D +:1096B0000413D51A2E07E9815A0003082E07E9275B +:1096C000C80484043E07E9812E07E978C80A3C1DD6 +:1096D000FA7EA4485CF0803CE9055000FFC4D50246 +:1096E00084003C0E011184013E07E97A84003E07A4 +:1096F000E983FC80FC003C0DFA9AA601540000FDB1 +:109700005A0809162E07E9815A00030584043E070A +:10971000E9812E07E978C80B49000F9F5CF0003CF7 +:10972000E90649000F9A50007FC4D50284003C0E20 +:10973000011184013E0004543E07E93849000F60DE +:1097400049FFC7C13C0DFA9AA6415A180807842A56 +:10975000AE4149FFE4CAD5118429AE41842049FFB6 +:10976000C2233C0DFA9A842AAE4149FFE4BE49FF68 +:10977000F31B840E49FFBE1B3C0DFAAB8421AE40A7 +:10978000FC805C000003DD9EFC402E17E9585A184F +:10979000020B2E17E938C9072E17E9818E225C10BB +:1097A0008001D50284202E47C5433C9C027E95A1B2 +:1097B0008EC19FE184A0846144A2CEB0528000009B +:1097C000E0A6E81BD71740F284084024BC0050F7FD +:1097D000800240F4BC00A49002F780008A4F969368 +:1097E000E00238251509E903E048E8045A180103A6 +:1097F00084628CA19768D5E55A18011F9201442212 +:10980000CEB084208122FF42E027E816386105119E +:10981000E006E80740A0900038F12911E00FE908C0 +:10982000E0C5E807998C38649911E0C5E8028462C4 +:109830008C219648D5EA8003FCC084204422E1B400 +:10984000380105098C215A1808FDDD9EFC2080E0B6 +:10985000A60080C25A0804208401AE383C0DFA9A52 +:10986000A60149FFFE6849FFFFEA3C13F4CAE62A55 +:10987000E8058C213C1BF4CAD51584003C0BF4CAC6 +:10988000A470E639E805AE38840049FFFFD88400AB +:10989000AC30D508840049FFFFD28400AC303C0BCB +:1098A000F4CAFCA0FC013C0DFA9AA60149FFFE4354 +:1098B000F081F1014402B3B14422B40649FFFFC86C +:1098C0002E17E98184003C0BF4DB3E07E942C90313 +:1098D0003E07E90184003E07E9483E07E9263E07C6 +:1098E000E93F440FFFAA3E07E9363C0DFAAB84215D +:1098F000AE40FC81FC202E67E9262E07C9CB80E113 +:10990000E0C02E17E918E9038E0197805A18011854 +:1099100049FFBCD05A08021484002E17C54394494D +:10992000E001E81783879441BA09BB0B884188237B +:109930008C01A44896009649AC50D5F04402E1B49D +:109940004410FFFF38501901D1048CA13850190977 +:109950002E17E9014000980E9606C81D2E27C54314 +:109960009491E002E81283879481BB0A8C01991AD2 +:10997000BB0996008862A5589769AD60BC0BA4D856 +:10998000884496D9ACD0D5EB84014000180CFE0F6A +:109990003E07E901FCA0FC422E27E9265A28FF04D5 +:1099A0004800011A8101F0814412D3FC4402B378CB +:1099B00049FFFFA280484400FFFF8420A852A8135B +:1099C0002E07C9C2E610E804521000109648E611AE +:1099D00080A0E902FAA085409628B61F80EA800A96 +:1099E00080CA4492D5FC2E27C5433C3C027F41E10E +:1099F0000408E0DE4EF2008B3C0C027E94B199022A +:109A00003C0C027CA560880204FF8000A400FF4C8F +:109A100042503C73800592049601AC203C0C027EBF +:109A200088628802A5003C0C027D8802A4009A206E +:109A30009603AC18A4189603E140E805A41880E644 +:109A400040A000113C0DFA7EA4D8A40596DBFE02CE +:109A5000E060E82C2E07E9385A0801292E00043A64 +:109A6000C81D380498003C33E4DC8C019600E260A9 +:109A700038049808E8213C0C027E3C3C027D8802B8 +:109A80008862A4009601AC18840038049808840108 +:109A90003E07E9003E07E988D50FF183F28249FFCE +:109AA000BC09F202F1035A0802DE38049800C0042F +:109AB0008E01380498083C3C027E0404000288624F +:109AC000A518E204E804A41814040002A51804046C +:109AD0000003E280E804A41814040003F001A6C106 +:109AE0003C0DFA7E5A380904A403D502A4043C3C78 +:109AF000027F8843A4909693E002E80484413E27C5 +:109B0000E93D8CC197B048FFFF7094799919E2E262 +:109B1000A560976BE826CF078C228823887EA4480F +:109B2000970BD50B9F919F0A884788834C73400EF3 +:109B3000A4609491970B8862A458964B882488253A +:109B4000964B44200050D52E8C2288239491886215 +:109B5000A520A448A4989723964B96938824D51DB6 +:109B60004C71400A8C228823A448968BA458964BAB +:109B70008822D5E69F0A506F7FFF9ABA88834C737C +:109B80003FD9A5A09D0A888394918862A460A49877 +:109B900097B3964B9693882688228825964B442027 +:109BA00000784E170007E041E80484213E17E93DA4 +:109BB0002E17E9275A1801073E17E93D84203E1762 +:109BC000E9813C1DFA9AA6495A18090649FFFDDEAB +:109BD0003E07E958FCC2FC202E27C9CA441000FFEA +:109BE0004020880C4413F422FE93A6489690965F7A +:109BF000C1038E2196482E37C9CB84C0E223E904E5 +:109C00009E59964884C1A7C084A14042840CFF3F5E +:109C1000972296E0AEC04C71C003C60D84014C3152 +:109C2000000C88204000040CFE279600FE1D5C00FE +:109C30000001D5028005FCA0FC2184003C0BF4DB74 +:109C40003C0BF4EB120F80033E07E93D3C0DFA9A02 +:109C5000A6015A0804222E07E981C8284402B3311C +:109C600049FFFFBB80605A0801222E17C9CB2E275F +:109C7000C550500F8006FE8C96904412D24049FF8A +:109C8000BE312E07E987C8042E00043AC0038401C0 +:109C9000D5078403D5052E07E938C80584023E0799 +:109CA000E981D5042E07E987D5F22E07E9815A0804 +:109CB000020584003E07E9008400444000C880603B +:109CC0004452D5FC2E17C5439449E001E8233C6C6F +:109CD000027C944188C13C2C027EA5B0884197B19A +:109CE000AD902E70043A3C6C027E3C2C027DCF0776 +:109CF00088418826A4489649AC50D5038822AD08EF +:109D00003C1C02868820AEC8383280088C01960040 +:109D1000D5DAFCA1FC202E37E938CB59A6005A0829 +:109D200002572E17E9585A18024E2E57C5433C7C4D +:109D3000027F95694420753084818003E065E819CD +:109D400094598827A58897B3E0C2E803A48896931E +:109D5000A58897B3E086E803A5089723A448964B07 +:109D60005EF0FF9CE8038C0196008C6196D8D5E7E5 +:109D70005EF17F9CE81E8436FE8C40211056E4552F +:109D8000E918C0172E07FEA88C019600E60B3E07C7 +:109D9000FEA88400E9113E07FEA884013E07E938C9 +:109DA0002E07E9815A08021484003E07E981D50F85 +:109DB00084003E07FEA83E07E93D84003C0BF4EB1F +:109DC000D5065A1801053E17E938D5EBFCA0FC4032 +:109DD00080C1A64180E05A1804249E34E604E92696 +:109DE0005A600C252E07E9815A0003212E07E987C6 +:109DF0005A0001122E07E94C5A00010E2E07E929DC +:109E00005A08010784003C0FFAD749FFEEC38007C8 +:109E100049FFFB084402D3FC49FFBB33D5072E178B +:109E2000E9815A10030449FFFAFD3C03F4EB4412A4 +:109E3000D5048C013C0BF4EB3C03F4DB8C013C0BB4 +:109E4000F4DB800749FFFDA949FFBA345A0802151F +:109E500049FFFBEFC8112E17E97EC10E3E07E92D21 +:109E600049000F2D2E07E9435A0801043E07E91A5D +:109E700084003E07E97E2E00043A5A08012049FF7B +:109E8000BA195A08021C490005FF852080E03E07E8 +:109E9000E93D3C9BF4EB5A08010984004900106637 +:109EA0003E7004133E90043A2E07E9545A08010705 +:109EB0003C03F4DB8C143C0BF4DB2E07E93D5A0821 +:109EC000011784003E07E94284002E17C9CB4432B3 +:109ED000E1B480809680E241E805384181098C0137 +:109EE000D5FA4400005049FFB60FD5192E77E9384E +:109EF0005A7801169E34E602E9124402D5043C1356 +:109F0000E3174422B372490004A95A080209FA016E +:109F100049FFB5FA3E77E93D3E77E9883C0DFA9A6C +:109F200049FFFEFA440FFFAA3E07E9369E34E602D7 +:109F3000E810440000FF2E10046449003BD6840062 +:109F40003E07E93D84003C0BF4DB3C0BF4EBD5060B +:109F50005A68020584013E07E93D2E07E9875A0841 +:109F600001043E07E9862E07E9215A0801063E074B +:109F7000E93D3E07E938FCC0FC0084003C0FFADCF8 +:109F80003C0FFAD7840149FFDF104403F04A441024 +:109F90000055AE402E000D123C1DFADC8C01E22073 +:109FA000E80A8401844080208062808080A249FF8A +:109FB000B9E1D5F12E07E918C8154402D3FC49FFD1 +:109FC000BA603C0DFA9A4412D50449FFFCE62E070C +:109FD000E93DC8083C0DFA9AA60149FFFAAC49FFD1 +:109FE000FA3C4403F04A44100055AE4049FFDEC33A +:109FF0008040C809840180208062808080A249FF5F +:10A00000B9B9D5F52E07E93DC81C2E000D12E6039F +:10A01000E8183C0DFA9A8424AE4149FFE0663C0DF5 +:10A02000FA9A2E17E96949FFFED43C0DFA9A842664 +:10A03000AE412E07E93DC8053C03FF5649FFFA0D26 +:10A04000FC80FC4444212D5CB1843A2114003A2F59 +:10A05000942044212D6C387F82023A2114003A2347 +:10A06000142094C2442271403843020238510C003B +:10A070002E37E92E442FFF38FED4976896D98440B6 +:10A0800044612288981694010290000038011C0057 +:10A090008C41420480244000140E88030292000088 +:10A0A00096034000041688091A0200015A2A88EC17 +:10A0B000FCC4FC4544212D5CB0423A2114003A20F6 +:10A0C000942044212D7C44728F70B1863A21140073 +:10A0D0003A23142081200023800F8400120F800374 +:10A0E0003810A602500F800600338010924149FFBD +:10A0F000BBF9500F8006381326020023800F00336F +:10A10000801049FFBBEFFCC5FC072E17E92E440069 +:10A1100000C8FE0C120F801B44028F7084A1A6C2DF +:10A12000A7038400F081F082F083F084F085F0864C +:10A13000F088F089F08AB67FF58744021B90501FA3 +:10A1400080364422AD7049FFF42CFC87FC42FD3080 +:10A15000F281F38349FFB8AE5A00020545E000A042 +:10A16000D50345E000782E07C5502E57C54F8E0108 +:10A1700050A2FFFFF0828027049F8001F001F203CC +:10A18000400480019600E202E85D09C48001424E6D +:10A1900014240800800198A095D1388309118441C6 +:10A1A0008068C00698B722317FFF84428868E00A41 +:10A1B000E80788E68C4122738001969088675CFEF0 +:10A1C0000002E91B9BE540F380004077840838F3E8 +:10A1D0003D11886FC8038C41D50740F31C008C42A9 +:10A1E00022F7FFFF886FE00A9690E80788E68C4127 +:10A1F0002273800196908867F70240FE1C07E818DA +:10A200008885888095E1384311118864C8038C41A2 +:10A21000D50699378C4222427FFF8864E00A9690E7 +:10A22000E80788E68C4122038001969088604021EF +:10A230008856E450E903E51AE80740FF0C07E89F59 +:10A24000D5038400D5028401FCC2FC4084604440F4 +:10A250007D0084C22E17C550E261E86D2E17C54FF0 +:10A2600044507D004271842495F940A0840988E01F +:10A2700085008045541400FFE22AE8113893A111AB +:10A280004E92000CE122E907E0A980294012BC1B94 +:10A290008122968B80A280498D01D5EDD40588A2BC +:10A2A000405298B696AB84202E87C54F409404093F +:10A2B000E2294271A024E80C88E195F988E0225354 +:10A2C0008000C5038AA2AD788C219648D5EE445013 +:10A2D0007D0080498025E248E81340A3880038A02B +:10A2E00029114EA2000BE141E906E0AA40553C1AB3 +:10A2F0008141966B80A1802A8C419690D5EDD41433 +:10A3000088A1405298B6966BD50F80A942518873A8 +:10A3100094A9884022510000C5038AA1AD50502461 +:10A320008001549100FF2E27C54FE322E9EF8C6195 +:10A3300096D8D591FCC0FC46B188810181428380CA +:10A3400084208006FA404900452550040006F08527 +:10A3500050040007F0865005000684A08481F08731 +:10A360002E07C550E080E854500500078460F08453 +:10A370002E07C54FE060E849802342120073380E73 +:10A380000511E40DE93F84E038231D119678E04083 +:10A39000E836F2058006F283F20605EF8004F282C9 +:10A3A000F2078527F281E2298E02E817F20302F014 +:10A3B00000078F2112F0000808F17FFFF283F202FC +:10A3C000549480FF18F17FFFF282F20108F17FFFC1 +:10A3D000F28118FF7FFFD5E82E07C54F8043422248 +:10A3E0000073380E0901E6A83834040838031D0943 +:10A3F00038450408E8078CA19768D5048CE15A78A1 +:10A4000008C58C6196D8D5B58C819720D5AA8005D2 +:10A41000FCC6FC0244212D5C80C33A2114003A2F73 +:10A420009420383F9A024412714095B288C1843E0C +:10A43000A7303C53E2BA97204201847380439A5379 +:10A440009649E225E8103860091108110001FE74F0 +:10A450004010900E4E140003FE4A5EF08051E9F069 +:10A460008401D5028400FC82FC424647FFFFF28350 +:10A4700050220FFF814084618001448200003C1C17 +:10A48000017BF2822E47C56DE2834EF3009B8381F0 +:10A49000FAA8BC104460003054427FFF952242412C +:10A4A00094738888F203025200099769F581025279 +:10A4B000000840F28013A767A7E6BC1254427FFF52 +:10A4C000952242429873BD1288885452FFFF956AC4 +:10A4D0004253987388A884C05A28014E844397F049 +:10A4E0004073893797F8549480FF844A39C21E021A +:10A4F0004294882441CE240D55CE03FF5BC3FF1246 +:10A50000F20141C17000804339E571012FC7C54F89 +:10A51000422370738382F20241CE080039E0710950 +:10A5200038729E028CC14093A40D549483FF5A93B9 +:10A53000FF0B2E77C54F892FFFF4389525018AE34D +:10A5400038901D095A6824CCD5383872A6028CC1BF +:10A550004073F00D547383FF5A73FF0C2E97C54F51 +:10A5600088EF429324248B233895250138901D09C8 +:10A570005A602424844397F0409388F7549480FFD2 +:10A5800097F8844A43C38824387226024073F00D3A +:10A59000547383FF5A73FFDB2FE7C54F8043422379 +:10A5A000787383C2F20241EF0800F20139E57901C4 +:10A5B00088E239E01D09D5CA8C6196D848FFFF644E +:10A5C000802A49FFB908FCC2842080612E27C54F2C +:10A5D000E222E806383005098C219648D5F82E1776 +:10A5E000C55084802E27C550E222E81184402E37C2 +:10A5F000C54FE243E80980A242508C738C41384039 +:10A6000015099690D5F58C219648D5ED2E17C54F96 +:10A6100084602E27C54FE222E81384402E47C550A0 +:10A62000E244E80B2E47C54F80A1425110738C4184 +:10A63000383015099690D5F38C219648D5EB2E37F6 +:10A64000E8882E17E889421188738440382005096C +:10A650002E47E88A2E37C54F2E17E88B42120C730F +:10A6600038200509DD9EFC0051FFF5C880C0C936C1 +:10A67000C0463C33E2BA442237FCB186444003E88A +:10A680009609E203E80C0201068A0A510001FE2441 +:10A6900040001416380305098C21D5F3800649FFC4 +:10A6A000FF95501F85288006844149FFFEDF800604 +:10A6B00049FFFDCD8006501F8528844049FFFED606 +:10A6C000B042B084800649FFFE38F081B042800677 +:10A6D000B084F30149FFFD3CD510440245104412FB +:10A6E00037FCB0868460848149FFB919B006B04256 +:10A6F000B084806649FFFE8FF081D502F08144026C +:10A700004510441237FC49FFB866F00151FF8A3802 +:10A71000FC80FC4284C084013C6FFADC3E67E93D6A +:10A72000810649FFF53681463C6FFAD7B6DF8126B0 +:10A7300080E65A7804112E07E971842349FFDD2948 +:10A7400084003C1DFA9A80404432B39049FFDE06F3 +:10A750008481D513800749FFE63DF0813C1DFA9ABC +:10A76000840380474432B39049FFDDF82E07E97136 +:10A77000842349FFDD0EF40188899620F081F001E1 +:10A780004C90006049FFEA0649FFBB58B41FE2093C +:10A79000E831800A49FFE61EF082B41F8C01960062 +:10A7A000B61F4C6500038500500400019600F0833D +:10A7B0008028800A49FFFF595A0801162E07E95FD1 +:10A7C0005A0801123C0DFAB6A78097B05A6801FEEC +:10A7D0002E07E971842349FFDCDC4400007349FF44 +:10A7E000B193D539800AF10249FFFC2D80CA048F4C +:10A7F00080034403F04A44100055AE402E17E9711F +:10A800003C0DFAB65A180311A6405A1801FF44022B +:10A8100000004412000244224510FA62FA94FAA0A1 +:10A8200049FFF161D504A6405A1801FF5004800188 +:10A83000549000FF3C0DFAAB84218147AE40D5A077 +:10A840008CE197F85A70050448FFFF75840049FFB2 +:10A85000F4A084C08006FCC22E37C5F05A38015FD0 +:10A86000FC003C3DFA9AA6D95A3009045A38040E25 +:10A87000A1022E67E9493C33E315404218972E5751 +:10A88000C6379721A003D51F2E47E9713C33E31447 +:10A890005A4804112E47E91D523180FFFF1C2E3704 +:10A8A000E9502E600D2840420C96524200FF96E17E +:10A8B000D5032E67E92EB4802E57C636404218972E +:10A8C0009721A00140001817E2239999960197B1AA +:10A8D000E8048A6196D9D50284605CF3020180267F +:10A8E000E903441002009649E281E904A6108C01B4 +:10A8F000D504E260E8FC8400AE10A610E2A084015A +:10A90000E80C8400AE102E00045B8C013E00045B5A +:10A91000FA0549FFB0F98402FC808401DD9EFC4009 +:10A92000EF003C1DFAB68402AE083C1DFAABAE083F +:10A930004403F403A78097B0CEFE3C0DFAAD842605 +:10A94000F0853C0C017A448000483C0FFAAD2E079C +:10A95000E97149FFDC1E3C9C017A2E07C56FE2C0FD +:10A96000E83FB00950AF802084E0505F801BF08149 +:10A9700080268009502F801AB0C7504F801DB75FC6 +:10A98000F782490042C18009B05CB0AE003F801C34 +:10A99000004F801D49004306B0938009B04A003F34 +:10A9A000801B49004394FA54B11CB14A38351E0249 +:10A9B0004243A073425388738400381201015A1332 +:10A9C000FF0638F2800038F185098C015A0824F717 +:10A9D0005A70010484E1D5E98CC197B0D5BF440217 +:10A9E000000044120C6049FFB6F644020000441215 +:10A9F0004C6049FFB6F0442000484402290044124C +:10AA00002C6049FFB6CD44021B904412000049FF60 +:10AA1000B6E22E07E971842349FFDBBB3C1DFAB681 +:10AA2000F00584C03C0FFAAD8401AE083C1DFAABC2 +:10AA3000AE082E100464440000FF49003656500F43 +:10AA4000801E44120C60FA40FA74126F800F49FFA6 +:10AA5000B749500F801E44124C60FA40FA7449FF07 +:10AA6000B7412E07E9663E67E9195A0801043E67B7 +:10AA7000E9662E07E94C5A08010584003E07E94CB7 +:10AA8000ED00FCC0FC0084003E07E95484003C6CEF +:10AA9000027F8060802080409970A52897235EF215 +:10AAA0000064E9038C418C21A52897235EF27F9DE9 +:10AAB000E8038C618C418C025A0890F05A304804AB +:10AAC0005A18480584013E07E95484003C4C027E34 +:10AAD0002E10041280609960A5685CF28050E8072F +:10AAE0008C6196D8E664E903842484408C025A0879 +:10AAF00090F4E62480013E100412E90684003E0032 +:10AB000004128401D511C903E649E80E3C0DFA9AF6 +:10AB1000A6015A08060684043E000412D5048C21BE +:10AB20003E1004128400FC80A611A6909CC18A628B +:10AB300096D8E6634EF2009FE6324EF3009CFC414D +:10AB400084E040A1040894C13C4C027881278387AB +:10AB500080C780A750A502405081824040351C002C +:10AB60008864A4D896DBE466E9068CC1887C97B03B +:10AB700041C1801140341C008864A4D896DBE4668F +:10AB8000E9068CA1886997684091801150738020F4 +:10AB90005A7A40E640FE19F64034947684E04097B5 +:10ABA0008013149F8001838783C7409180134035B1 +:10ABB0001C008864A4D896DBE466E90A04FF8001DF +:10ABC0008A6F4E340003FEDA887E41E18013403400 +:10ABD0001C008864A4D896DBE466E9088A694E34D0 +:10ABE0000003FEDA887C41C18013507380205A7ABA +:10ABF00040E0E6D0E941E6B0E93F406F18D6E4D93D +:10AC0000E805405E14B6E4B9E939C21694CC88432D +:10AC1000949198E28E428844A558A590976B97B37B +:10AC2000E0C5E805A4D8A4909A9AD504A490A4D825 +:10AC30008A439691D503442000FFE60FE81F944C09 +:10AC40008801940198608C028880A4C8A42096DBB7 +:10AC50009603E003E804A408A460D503A420A44854 +:10AC60008A015CF100249601E8095CF00024E80602 +:10AC7000D5038400DD9E8400D50344008000FCC120 +:10AC8000FC0080C0440F8000E262E90F9514A175BA +:10AC9000888195218885A560976BE005E803A5204C +:10ACA00096238C419690D5F1FC805A3FFF044800D2 +:10ACB000010FFC4684204452CF5080C13862860A7E +:10ACC0008C215A1810FD84BF8420F58180A1E2A454 +:10ACD000E80FA19138631501DE09A19238631501CF +:10ACE000E226E804D3038026F5818CA1D5F181000A +:10ACF000941AF084A015F28338900E00F0019402AB +:10AD0000F085F003F104A0058820A689E3224EF225 +:10AD100000C8402480139CD140A18013F3015A370E +:10AD2000FF1DF3058803A6C0E243E904A701E28200 +:10AD3000E806E343E912A681E24AE90FA7C2A68B1F +:10AD4000E247E8048EE197F9D509A783A60AE2C095 +:10AD5000E8078CC1FAF3D507FAF384C3D50444702D +:10AD600000FF80C7B04884003800A4089A3EE4067B +:10AD7000F0824EF300939770973855C480FF80455A +:10AD800080648008803CF587F48649FFFF7B5EF095 +:10AD9000003CF406F5074EF30081501E00018008C8 +:10ADA00096488045806449FFFF6D5EF0003CE97580 +:10ADB000B04884013800A40894744020A4008400A2 +:10ADC000882A9491944980A680808060E2E5E91900 +:10ADD00005C4000540F0080040FE3C008CA102F7CD +:10ADE000800040F78011886F40F0040040FE3C0076 +:10ADF0005000002002F7800040F78011888FD5E7CF +:10AE0000F0028C014010040A8861888140152401F9 +:10AE10008540405180B6404200969449838A800A1A +:10AE2000E2E6E91C05E4000540F10400403F0800AB +:10AE300040FF3C00A4D802F7800096DB40F7801169 +:10AE40008A6540F7900142018C7343C7BC7342A1ED +:10AE5000BC738CC150210020D5E4842049000496A5 +:10AE600080C08420801C49000491C8028401CE0265 +:10AE700084C1FF84443000644003040942050C731C +:10AE800040001817402488085EF000654412CF5037 +:10AE90004001BC1A3800880A8D2148FFFF34A648BB +:10AEA000440000644442CF50E222E80CB0C838317C +:10AEB0008400C30638320602E060E802961B8C214B +:10AEC000D5F45EF00046540780FFFCC68400DD9E8A +:10AED000FC4484602E47C6D444628F7080E3975848 +:10AEE000E2A4E806995E8C611072818CD5F9A6CA3D +:10AEF0005A3001072E300409CB08A6C8CB068400BF +:10AF0000AE0884004800008B8120A005FA6E80E125 +:10AF1000504F801F802084A080C249FFB811000FCD +:10AF2000801F847FF08384008020F4039680E244B5 +:10AF3000E810A171968138528101DA09A0B2382156 +:10AF40000101E22240113C1B40303C1B8C01D5EE3C +:10AF50005A37FF1DA0B7A036945A38810E02042339 +:10AF6000000838000E0238510E02C55D3CADFA8B68 +:10AF700000250032FE8440011417F08200050033E2 +:10AF800042040024405014B7D54F84A0F5828005B8 +:10AF90008025D50EC078001F0032B45FF401FE8C0E +:10AFA00040110037002F0033FF1440020017A6B8ED +:10AFB0005A20010544A0003CD502FB58F2028A4108 +:10AFC00080224E240003FE52E341E9079AA84E2452 +:10AFD0000003FE92E342E81EA0B238210D01E659BB +:10AFE000E9138AA04E540003FF6AE0A14012BC1A84 +:10AFF0005EF08190E809800980278046F40349FFCC +:10B00000FE565A080143440000783C0802058401BA +:10B01000D5083C000205C0058E013C080205D53567 +:10B02000AE38D533F582A0353DEDFA8B8820A60BDE +:10B03000A68AF0848400F081B61FF404E282E9ABB2 +:10B04000A70900A08000F485F405E28AE91A008FC0 +:10B050000002808A04F48005424120734082040883 +:10B06000890F0284000040840011E51EE908B49FA6 +:10B070008C01888AB69FF4018882F4818D41D5E5E0 +:10B080008C41D5DC8020D594FCC4FC000400001564 +:10B09000844480208461848584A049FFB495FC8029 +:10B0A0003C1DFFAEA003A44CE201E90684003E0073 +:10B0B00004548402DD9E8400DD9E00003A6FAABC29 +:10B0C00084E0EFFC3C2DFFAE808180C780A78545E2 +:10B0D000B5244E9200118F24E722E90D0482000767 +:10B0E0000490000238F4A10100810006E30FE80398 +:10B0F00010A18002B5245084FFFFE702E9035A98AB +:10B1000004192292000702F1001EE12FE9120281C8 +:10B11000001FE109E90E2292000602F1001CE12F56 +:10B12000E9080281001DE109E9048CC197B080E5BE +:10B130008CA19768504200FC5A580ACC2EA7FEDD1D +:10B14000CE0684008420AE1A8081D51FA61A5A002C +:10B15000051B5A68011450057FFFE602E8042E57CC +:10B16000FEDADFF0440000FC4213807384012240C9 +:10B17000800622108007AE1AD50884038420AE1AF8 +:10B180008081D503842080812E00043A5A0801046E +:10B190008405AE1AA61A5A0801633C9DFFAC005400 +:10B1A00080005A5801093C5DFFAD025280098EA112 +:10B1B0009B2C9723005480015A5801093C5DFFAD38 +:10B1C0000252800A8EA19A69964B00548003008433 +:10B1D00080025A5801403C9DFFAD025480094E83C5 +:10B1E000001E50F2FFFF0254800251C2FFFF84A2F2 +:10B1F000408795164282707340443C970284800ACF +:10B20000029480038F018F21405414B64250A473DE +:10B210004012A0379723964BD52251C2FFFF02540C +:10B22000800351E2FFFF84A240FE15F642F27873DC +:10B230004047F09702F4800A0294800250F7FFFF23 +:10B240008F21405794B64250A4734012BC379723C5 +:10B25000964B5A88010580A480818025E745E8192E +:10B2600044F0B17038A7A80040F53C004A003C000B +:10B27000060C0C161C005A08010BD5105A00010CC4 +:10B28000C80C8403D50BE602E808D503C806D5062A +:10B290008400D5048402D50284043E07FEDD8E01BD +:10B2A000E60484A04EF2014844F0B1B838078101A9 +:10B2B00040F03C004A003C00080056008A0176023B +:10B2C00084A03C5FFFB53C5FFFB484A184003C5F79 +:10B2D000FA23445FFFAA3C0BFF6C3E07FEDC3E07EF +:10B2E000FEDB3E57E8903C4BFF663C1BFF673C4B48 +:10B2F000FF643C1BFF653C4BFF623C1BFF633E77DA +:10B30000FEDA3E07FEC23E07FEC0480001172E07C8 +:10B31000FEC20251001A3C4BFF62E2053C1BFF6378 +:10B32000E8048C013E07FEC23C07FF649BC44E74D8 +:10B330000003FFFA3C57FF659A294E040003FE0202 +:10B34000025100198807E0A0E80484013E07FEC00E +:10B350003C97FF66400490014E040003FE023DC787 +:10B36000FF67407E04014E740003FFFA02A100054E +:10B370009978E3454EF200E2A5562E87FEDBE20502 +:10B38000E90DE124E806854058540002812AD509D8 +:10B390005454000185408521D50480A8854285202C +:10B3A00002F10007E2EFE90DE03CE80458528001A9 +:10B3B000D508974E8D219768549480FF58A50001B9 +:10B3C0003CFDFFB488EF3C7FFFB43C7DFFB58807B0 +:10B3D0003C0FFFB55A98020E2E07FEDCC81D8401F3 +:10B3E0003E07FEDC3C0DFA2394023C0FFA23D525E0 +:10B3F0005AA803132E07FEDCC80F3C0DFA23940253 +:10B40000580000023C0FFA2384013E07FEDC840250 +:10B410003E07FEDBD5124C5400112E77FEDCE6E72A +:10B42000E80C3C0DFA238CE19402FE2F3C0FFA232A +:10B430003E77FEDC3E57FEDB3C4BFF663C1BFF6766 +:10B44000D57C2E57E8905CF28020E811A410A5115D +:10B4500040004008401010045202801F4000800E3F +:10B460009606C805440FFFAA3E07E890A410920C68 +:10B470009606C0632E07FEC35A08012A2E17FEC285 +:10B480000201001AE220E8232E17FEC10201001B70 +:10B49000E220E81D2E07FEC0C81A3C07FF623CF7F9 +:10B4A000FF5E021100198A0F4E040003FE02E00144 +:10B4B000E80E3C07FF633CF7FF5F8A0F4E04000372 +:10B4C000FE02E001E80484033E07E8902E17E890AE +:10B4D00084003E07FEC15A1003313E07FEC32E070B +:10B4E000FEC0C82B3C07FF630211001EE001E91DEE +:10B4F0000211001FE020E9193C17FF620241001C05 +:10B50000E024E9130241001DE081E90F2E57FEC23D +:10B510000241001AE2A4E81184813E47FEC33C1BAD +:10B52000FF5E3C0BFF5FD5098402AE1AD5063E577D +:10B53000FEC3D5033E57FEDD84003E07FEDE3C031E +:10B54000FF6CCE052E10043A5A180115A454E201DE +:10B55000E8058C013C0BFF6CD5272E00042BC80698 +:10B5600084013E07FEDE8404AE1A84043E07FEDD3D +:10B57000D51B2E17FEC35A18010E2E17FEC102410D +:10B58000001BE224E8058C213E17FEC1D5033E676F +:10B59000FEC3A454E201E905440FFFAA3E07E89068 +:10B5A00084003C0BFF6C2E27E8905CF10020E82122 +:10B5B0008C4C96908401E65EAE18AE998401E90544 +:10B5C000FA2E49FFC1D1D504802249FFC1CD8403A1 +:10B5D00049FFC1D08400EC043E07FEDD440FFFAA02 +:10B5E0003E07E8903A6FAA844400006048FFAA8CA6 +:10B5F000EC048400AE183A6FAA84DD9E3BFFFE3C4B +:10B60000EFFC4412B4948400442FFFAAAE08AE0AA3 +:10B61000AE8984203C1FFFB53C1FFFB43E17FEDC03 +:10B620003C1BFF6C84213E27E8903E07FEDD3C1F5B +:10B63000FA233E07FEDB3E07FEDE3E07FEDA3E074C +:10B64000FEC33E07FEC23E07FEC13E07FEC0EC043D +:10B650003BFFFE04DD9E3C0DFFAEA404DD9E2E07E5 +:10B66000FEDEDD9E84002E17C54944328F70808037 +:10B670009680E241E80698838C01104103ECD5F9ED +:10B680004400003C3C0BE49DDD9E3C13E394AC4045 +:10B69000DD9E4402CF908420AE40AE41AE42AE4328 +:10B6A000AE44AE45AE46AE47DD9EFC4046F7FFFFDA +:10B6B00050F78FFF5A18024480A0808084E0B46461 +:10B6C0005A38022280C085204C748019B4665A38DA +:10B6D000021622120006223300069ACB4E340003D3 +:10B6E000FEDA2212000722F300078A2F4E1400030D +:10B6F000FE4AFE4C42118C7381E18D21506300FCA7 +:10B700005A980AE48CE1504200FC5A780ADA500058 +:10B7100009D8B4655A380210A0EFA11594DA8864EC +:10B72000A718C414A7195A400F12A71AC40FA6DBF2 +:10B730005A30230D505280FCD8EDD50684003E07C8 +:10B74000FEE03E0004658400D50284012E300465CD +:10B750004420FDE7E04FCB0CE90C2E17FEE08C21D6 +:10B760009648E6233E17FEE0E9098421D505E8FE68 +:10B7700084203E17FEE03E100465C00684003E07AC +:10B78000FEE03E000465FCC0FC418501B61F8081DF +:10B790008120838185404004A001E320405E280190 +:10B7A0004C5780234074A000E2E9400E2800406717 +:10B7B000800040037C0892E1FFC792C18007802689 +:10B7C00080478066F48149003ABBF401E281E909CF +:10B7D0004C124005B43FE220E90481078146D5DCE4 +:10B7E00081278386D5D9E602E8DE8008802AFCC15D +:10B7F000FC204430271080C0FE5C2200002840203E +:10B80000885622130050FE1C40100436E0222243CA +:10B810000000E85340F011F6E04FE8514450007842 +:10B82000FA388083980D90015CF00051E9045230A1 +:10B8300000A0D50480605A00280552700078D50316 +:10B840004470005038330D1138731D11FEE440313F +:10B850009C76E043E8039F41D504E062E8349C41D4 +:10B86000E0A1E8E14C00800380A15CF28051E90492 +:10B87000521280A0D5028025507280285CF380513E +:10B88000E903527280788A624E340003FEDA38137C +:10B89000051144402710FF0C38131D114042049637 +:10B8A0009AA24E240003FE92E062E90DE043E90A09 +:10B8B000E2054002BC1AD507FA18D5054400007805 +:10B8C000D5028005FCA05CF00051E905523000A0D3 +:10B8D000B661D502B60150107FD85CF08051E90501 +:10B8E000520000C8B602DD9EB622DD9EA6493C434A +:10B8F000E3055A1001049660D502A6522E20045486 +:10B900005A280103A65C22F00003E02FE80484011A +:10B910003E07E968DD9E3C2DFA9A2E37C5FEA691BA +:10B920005A20060496D9D5032E37C600A6015A0818 +:10B9300001042E37C5FF2E07E9155A0801044430CB +:10B9400000782E47E9532E07C6042E27C5FDE28056 +:10B95000E9342E07E9555A0801384020080C3A6F9F +:10B96000A83C8A43EFFC969104A08002B5210470A4 +:10B97000801484A044600480408514004004940036 +:10B9800002F40000993DA400A460FE1C42013C7337 +:10B9900088012E17C5FD8CA24010040D9649121483 +:10B9A0000000021400002E87C5FD4010A00C8A0183 +:10B9B0009601AC20DEE2D5058C813E47E953DD9E41 +:10B9C000EC043A6FA804DD9E3A6F9ABCEFFC2E0798 +:10B9D000C5E75A0001048401D55884003C0BF4E00B +:10B9E0002E07E968C0052E07E93C5A0801F64617FC +:10B9F000FFDD445225B050108A508460442227F065 +:10BA000098293C4C027894018804A40096035EF0C7 +:10BA10007FC9E80EA6288C019600AE28A628E60A63 +:10BA2000E9083C03F4E08C013C0BF4E0D502AEE8FD +:10BA30008CA1DAE73C03F4E0C8052E07E93C5A087C +:10BA400001CC84003C0BF4E0445225B0441227F0B2 +:10BA500018028001D9FE2E07E93C5A08010B2E007E +:10BA6000045A8C013E00045AFA0649FFA84DD50934 +:10BA70002E0004598C013E000459FA0449FFA844E1 +:10BA800084003E07E93C8402EC043A6F9A84DD9E10 +:10BA90003A6FAABCEFBC84C0126F8018126F801975 +:10BAA000958C4083000050647FFF5074001040A3C9 +:10BAB000001350640001F28B97F997B1C906C014C6 +:10BAC0005A080F1680CAD51350947FF04094801303 +:10BAD0005A182307C00E5A080F1080CAD50DC00E81 +:10BAE0005A080F0ED50B81468127D5098127D50726 +:10BAF000814680E9D50480E9D50280CA3C0C01EE7C +:10BB0000956A88A041C40408A668A62941E50408EE +:10BB10004C1040233CAC027940057000A540400524 +:10BB20007800976BA4409431880A964BA4009A69D8 +:10BB300096034E140003FE4AE0A1E9079A284E043A +:10BB40000003FE02E0A0E8082E00042FE607E80448 +:10BB50008C013E00042F3C0C02752E87E92EF082EA +:10BB60003C0C0273F08340048408F0849439F0851F +:10BB70009431F0862E07E93C2E900434F081440085 +:10BB800000C8420400245010005050007FB0F088DC +:10BB9000440FFF3842040024F187F0898420F20228 +:10BBA000F00397C840011C1AF20438507011386035 +:10BBB0000801F205126F801B125F801A38600801BD +:10BBC000F206126F801C3860780138000801126F8D +:10BBD000801D120F801ECF0840F2A1F65EF7803262 +:10BBE000E8038401F081B00CB14D38A0051184C583 +:10BBF00022028000F207F58AE040E904F208E00240 +:10BC0000E810F20988024E040003FE02AC285A78BC +:10BC1000010B22FF801A5EF7A7114093BC1AD503CF +:10BC20008400AC28F00A8CA2220000004E0400031D +:10BC3000FE028EC1880A97B040A00011CEDAB00C87 +:10BC400038A005095A1001048421D5AA000F8004E8 +:10BC5000F10B3E07E93C3E900434220F801822FF8E +:10BC600080195A10010A5A3001082E0004345A0073 +:10BC700001098400D50A8A0F96035EF000A0E9F658 +:10BC80008401AE2044008000EC443A6FAA84DD9E1B +:10BC9000FC00842084618041808344005640490038 +:10BCA00016B65410007F84415810808080628082D4 +:10BCB00044005640490016ABFC80FC00842084619F +:10BCC00080414400DAE08083490016A144100271EB +:10BCD000FE0C441003E8400004162E1FE96E5000CD +:10BCE0007FD896025A187F043E07E96E2E1FE96E30 +:10BCF0005A107F1A8A014E040003FE02E40FE91372 +:10BD00008421E41E3E17E943E9095EF0003C3E173A +:10BD1000E924E9073E17E970D50D84003E07E924C0 +:10BD20008400D50684003E07E9433E07E9243E0728 +:10BD3000E970FC80FC43F0842E07E9705A00010A88 +:10BD40002E07E9245A08010BFAF144A000C8D509CE +:10BD50004470003244A0012CD504FAE944A00096B6 +:10BD60002E07E96B94D9F0834402C92C8860440201 +:10BD7000C9BCB61F50008480F08584C0440FF448CD +:10BD8000F08183C1808645C00BB880068126F6828B +:10BD90005A60071D225F000022FF000140F2BC0133 +:10BDA0004EF4000452F7800040F79C07E82D81E52F +:10BDB0004E54000452F2800040F7A807E825880599 +:10BDC000960338F11901A558D51B2250800722F09F +:10BDD000800640F2BC014EF4000452F7800040F7A8 +:10BDE0009C07E81281E54E54000452F2800040F7AF +:10BDF000A807E80A8805960302F18000A55788AFD6 +:10BE00008C81AD5897202A5F00014E5500068D2188 +:10BE1000549480FFD509048F800250F400015487A8 +:10BE200080FF148F8002048F8001E0BC41C2BC1BE4 +:10BE3000E1054082BC1B8CC1148F80015A6808AA9E +:10BE4000C4592251800040001016405290B6AD589F +:10BE500096035A900805F5025A580829E685E926FE +:10BE600080804E040003FF02E499E9204040700105 +:10BE70004E440003FF22E0E4E919F4018A808004C3 +:10BE80004E440003FE22E0E0E911F0045A080107E5 +:10BE9000B49F000F8010AE20D505B49F840110021E +:10BEA0000024F0038C019600F08380A25061001002 +:10BEB0002A028001224180004E0500068A044E04B9 +:10BEC0000007D5048A044E07000384001202FFFF16 +:10BED000DEF0B41F501080208C01B61FF0055021F9 +:10BEE00000208C624C107F4B000F800C3E07E96BEA +:10BEF000FCC35A9808B2D5DAC8113E07E96B443240 +:10BF0000C9BC80804412C92C804038418008382048 +:10BF100081098C015A0848FBDD9EFC008061A04E1F +:10BF20005A080105A09D8460D505A09D8C308C50D9 +:10BF3000FA7449FFFF01FC80FC0084003E07FFD437 +:10BF40002E07FFD5C00F84C13E67E93D3E60041354 +:10BF500049FFA9B05A0802043E67E93884003E0749 +:10BF6000FFD52E07FFD4FC803E07FFD584003E0797 +:10BF7000FFD48400DD9E841F3C0FFA2584003E0719 +:10BF8000FFD53E07FFD4DD9EFC42A712F383C40316 +:10BF90008E81AF123CADFA8CA753004500038E8111 +:10BFA000D4038CA1AF53A710C4038E81AF100045FA +:10BFB0000002A7518E81D4038CA1AF513C8DFA9D14 +:10BFC000B488928E97065A48010644300032B67FF4 +:10BFD000D503FA89B69FA6D18480A790F38180A467 +:10BFE000F301E266E946A6D3A7D2F382F302E26741 +:10BFF000E93E0095000283C643E3A47304908015D4 +:10C0000041CF0408893CB47F02F4800040F78011DE +:10C01000E06FE82004F00000F30338F7F90005E0D2 +:10C02000000138FF3D014CF1C00904F4000040F765 +:10C03000B80954F78001E80904F4000040F7B80992 +:10C0400054F780015AF8010702948000409480114F +:10C05000888904908005893C02F4800040F78011B3 +:10C06000E0AFE803025480008CE1D5C18CC1D5B9A2 +:10C07000C506440001F4FF04404214978004FCC24A +:10C08000FC4281403C0DFA8D80C1853FA640A7034C +:10C09000440003E8FE0CA65080E23C9FFA25408055 +:10C0A0000013C9038400D52A840080A0E0A1E81110 +:10C0B0000425000138211501DA0A0425000238217F +:10C0C0001501E2024092BC1B40013C1B8CA1D5EF44 +:10C0D0003C9FFA255A97FFE804250005401488087C +:10C0E0008822B0038444B69F4900364A800A8026DD +:10C0F000B083806949FFFF4AB49F3C1DFA9DB4217B +:10C10000922E96465A180114041500033C2DFA2568 +:10C11000381089015CF0812CE80344802AF83C1334 +:10C12000F52F5CF08051E9038400D503E300E908B2 +:10C130002E1004085A18010F2E100463C90B840135 +:10C140003E07FFD43C0DFA8D8421A6013E07FFD5A2 +:10C15000D561441003E8FE649649E220E85A808ADB +:10C160003C1DFA25A0234430006438200501FA184C +:10C17000FE1440000C169601E20380404021BC1BD7 +:10C180009611F081A025944A880184200080000344 +:10C1900000A00002A74101E00000E30A40042801DA +:10C1A0009600E902802096498460B63F805E812334 +:10C1B000E245E81D802AE228E814950C04F3000506 +:10C1C00088829521888F04FF8001A5209723E08F26 +:10C1D000E90550448001409200138C219648D5EC2B +:10C1E000B43F8C418861969096D9D5E3E662E91117 +:10C1F000441000644214842440308C7696D95CF15B +:10C200008048E9078ABE97688A058C01E603E998A9 +:10C2100084202E07FFD5C00D5A1801053E17FFD404 +:10C22000D5088E0196003E07FFD5C8033E07FFD410 +:10C230002E07FFD45A0801048420AE78FCC2FC42C9 +:10C240008400100F800F3C0C0278504F800F80202C +:10C2500084A04422D1D4FA7849FFAE728420005FD2 +:10C26000800F3CAC01EA3C6C01EB80818001968838 +:10C27000E245E80F3875050196C94C71C00938339D +:10C280000501E20340413C1B4001BC1B8C21D5F061 +:10C2900094623C9C01EEC039405484003DEC02782D +:10C2A000A629A6A8B61F3C8C01E9840041C2001350 +:10C2B000B47FE262E921A7ABA6EAF681F601E2C308 +:10C2C000E91895DC88E295B988DE02F3000040F7B2 +:10C2D00080115EF78028E90A38741D0038751D0149 +:10C2E0004C7E4005A5B097B388068C6196D8D5E7FB +:10C2F0008C419690D5DE442001F4FE143C2C01ECD8 +:10C300003821110140000817882944504E1FE2A02F +:10C31000A6CBA70AA689A648E80E8A6496D8E66B3B +:10C32000E8058A419690E64BE90844106D5F4000AD +:10C330008006D5048400D5028401FCC24403F08049 +:10C34000441FFFB6AE403C0DFA193C3DFA1892026C +:10C350008C01442200008420E220E806A311384129 +:10C36000860A8C21D5FA84013E07E9064403F08051 +:10C370008420AE40DD9EC0174E1700164E270014D5 +:10C38000980AE41FE910E02244000064E807AE18B0 +:10C39000FE0C40200856AEA0DD9EFE8440210456CF +:10C3A000AE98D50444000064AE18AE20DD9EC10BEB +:10C3B000402084094430006442200C73401104364C +:10C3C000960BDD9E8001DD9EFC5880E02E07C54265 +:10C3D0002E57C543509F8034B61F8420FA42B008C0 +:10C3E00044A000694460006AF583490034D3842086 +:10C3F000FA42800910AF802010AF802210AF802455 +:10C4000010AF802610AF802810AF802A10AF802C8C +:10C4100010AF802E106F8021106F8023106F802549 +:10C42000106F8027106F8029106F802B106F802D68 +:10C43000106F802F490034AE8420FA42B01210AF42 +:10C44000803410A4800210A4800410A4800610A4DC +:10C45000800810A4800A10A4800C10A4800E106420 +:10C4600080011064800310648005106480071064EC +:10C4700080091064800B1064800D1064800F4900E7 +:10C4800034898420FA42B01710AF804810AF804A38 +:10C4900010AF804C10AF804E10AF805010AF805264 +:10C4A00010AF805410AF8056106F8049106F804BD2 +:10C4B000106F804D106F804F106F8051106F805340 +:10C4C000106F8055106F80574900346410AF805C46 +:10C4D00010AF805E10AF806010AF806210AF8064DC +:10C4E00010AF806610AF806810AF806A840050AFD4 +:10C4F0008070100F801E100F801F8420FA42800A67 +:10C50000508F8084106F805D106F805F106F80612E +:10C51000106F8063106F8065106F8067106F806987 +:10C52000106F806B49003436440000464410005AB6 +:10C530004460006451CF809844400063100F8070C5 +:10C5400010150007101500081005000F8420FA428E +:10C550008008104500011045000EF48110650002AE +:10C5600010650003106500041065000510650006E5 +:10C57000106500091065000A1065000B1065000CBD +:10C580001065000D490034068420FA42801C106FAB +:10C5900080841064000110640002106400031064C1 +:10C5A00000041064000510640006106400071064A5 +:10C5B0000008106400091064000A1064000B106485 +:10C5C000000C1064000D1064000E1064000F490090 +:10C5D00033E1F401B0EB80038420FA42104F8098DD +:10C5E000104E000FF482F381106E0001106E0002F5 +:10C5F000106E0003106E0004106E0005106E000631 +:10C60000106E0007106E0008106E0009106E000A10 +:10C61000106E000B106E000C106E000D106E000EF0 +:10C62000490033B8F30144000055F402100F80AC08 +:10C630001001800F2E00041EAF19AF9AAF9BAF9C64 +:10C64000AF9DAF9EAF9F106180081061800910619F +:10C65000800A1061800B1061800C1061800D104108 +:10C66000800E5A08010448000120B41FF50394010C +:10C670008807B43FF0819E2AFE0C94018807F0835E +:10C680009E294260042495B1F084983EF08284C0D3 +:10C69000B43F9630E201E836380399113815180096 +:10C6A000F38549FFFE8638039909F0013814180014 +:10C6B0003800191149FFFE7DF10138009909F00396 +:10C6C000381E18003800191149FFFE73F103F305F5 +:10C6D00038009909F002381198003800191149FF03 +:10C6E000FE68F10238009909F0013814980038000A +:10C6F000191149FFFE5EF101F305380099098CC15B +:10C70000D5C88C21409084088401381385112223D8 +:10C710008001503F801E504F801F49FFFE2E002F8A +:10C72000801FFAC142011824004F801E221380008E +:10C730005034FFFE445000468867814042A2147383 +:10C74000FE444010A83602A1800045CFFFBA882AD7 +:10C75000AC582233800044AFFFEF4221282442220C +:10C7600070734211802440008816802788033800A7 +:10C77000A40D4623FFFFB41F50210FFF88404081C6 +:10C78000080884012210FFFD38238A11503F801EC3 +:10C79000504F801F8F248927F58149FFFDEE002F20 +:10C7A000801E22048000FF94001F801FF5018D026F +:10C7B0008907806642309473FE3440000C160234C0 +:10C7C0000000422128248803120400002204800073 +:10C7D0004220F073FF8440A309568940F504B41F3A +:10C7E00044100064FF449A28101F801E101F801FF1 +:10C7F000944112A4800040938400946941C3840052 +:10C80000442005DC221E0000024480004430213414 +:10C81000FE5440108C36882412148000224E0000F2 +:10C8200044101B58FF0C40420C96124E0000B49F5F +:10C8300084C08E8188A4956988A7880494012242C7 +:10C8400080008807FEA4A50040210C568844AC80D7 +:10C8500022028000B088FE4440108C36AC6850AF95 +:10C860008048508F805CB43F9630E201E81D38115B +:10C87000180038039911F28149FFFD9B380399098B +:10C88000380499113815180049FFFD9338049909A7 +:10C89000380E19113814180049FFFD8B380E19098C +:10C8A000F2018CC1D5E1FCD83A6F9ABCEFFC49FF8C +:10C8B000A5014413F0105A080206440FFFAAAE085F +:10C8C000D5038400AE083C0DFAAE9E46E622E9048C +:10C8D0008E09E605E80F3C0DFA9A4412CE683C2D0D +:10C8E000FA9D4432B5103C4DFAA449FFD96E5A0066 +:10C8F00008038401EC043A6F9A84DD9E3BFFFCBC84 +:10C90000EFFC490035FD490034CF3C0DFA9A8421F3 +:10C91000AE414900387349FFA4CD5A08020449FFCB +:10C92000F9B9440000A04900274AEC044402B4B01D +:10C930003C1DFA9A3BFFFC84480034D43BFFFCBC0E +:10C940008404EFFC3E07E905440000A149002737B5 +:10C950003C0DFA9A4412B3AD4422B5103C3DFAA402 +:10C9600049002E0A2E07E9345A08010A4402B3414D +:10C970004412B3E449FFA66E49FFE4C73C1DFAB672 +:10C980008402AE083C1DFAABAE08490035E62E071E +:10C99000E9345A08010449FFE4B1490036D444009F +:10C9A000007FEC043E07E96EFA043E07E92D3BFFE9 +:10C9B000FC84840248FFA0A83BFFFEBCEFF82E07D2 +:10C9C000E9345A0801074402B341842049FFA5D441 +:10C9D0002E07E9718E03E602E80D2E07C5DC5A0822 +:10C9E000010A49FFCF5A84023C1DFA9C49FFA52544 +:10C9F000D50849FFE497F081F101840049FFA51DA6 +:10CA00003C0DFA9AA6415A180D048423AE41440005 +:10CA100000A3490026D42E07C5DD5A08010C3C0DA1 +:10CA2000FA9AA6005A0801072E07E97149FFE4C7E0 +:10CA3000D507440245104412400049FFA6CC4402E9 +:10CA4000D3FC4412B48C44328F704422D504444247 +:10CA5000D3F0490022D43C3C027984004412D47CB7 +:10CA60009898A490382080098C025A0840FBEC0862 +:10CA70003BFFFE84DD9E84003E00041E2E07C5425F +:10CA80003C2C027994418E2488223C3004E0A44856 +:10CA90003A6FA0BC964BE061E80C94028E048802C9 +:10CAA000A40096035EF07FECE80484013E00041EBF +:10CAB00049FFA4005A08021F49FFE5BBC81B3C0DF3 +:10CAC000FA9AA6015A0803072E07E92D5A081413EB +:10CAD000D5035A08061084C03E67E92D49FFF8EFD8 +:10CAE0002E07E9435A0801043E07E91A3E67E97E2A +:10CAF000D51049FFA3DF5A08020D49FFE59AC00986 +:10CB00003C0DFA9AA6015A08060584013E07E97E03 +:10CB10002E07E92DE614E8048C013E07E92D840078 +:10CB20004412D0548040382081098C014462D05492 +:10CB30005A0812FB2E07C5DE5A08010B2E000439D5 +:10CB4000C8074402D3FC80264900259AD50E3C0C28 +:10CB500002793C1C027849FFA63E840080203813ED +:10CB600001098C015A0812FD2E77E91A5A7801162C +:10CB700049FFA3A080C05A08021184004412D3FCCC +:10CB800049FFF9BC80074412D3FC49FFF9B780067E +:10CB90004412D3FC49FFF9B284013E0004642E071D +:10CBA000E9695A08120D3C03F4DC8421490026A3EC +:10CBB0005A0801062E100464490025972E17E934FF +:10CBC0005A1801064402B34149FFA4D62E07E96969 +:10CBD0005A0812103C03F4DC84224900268C5A08BF +:10CBE000010984022E1004643A6FA0844800257D58 +:10CBF0003A6FA084DD9E2E07E9693BFFFCBCEFFC89 +:10CC00005A08120E3C03F4DC842F490026745A089B +:10CC10000107840F2E100464490025672E07C5DB29 +:10CC20005A08010C3C0DFA9AA6015A080A07EC04AE +:10CC30003BFFFC8448FFE4C8EC043BFFFC84DD9E22 +:10CC4000DD9E3A6F9ABCEFFC2E07E94F4E0300873A +:10CC50002E00043AC8042E07E968C0052E07E93CF7 +:10CC60005A08012449FFB67DC8202E07E988C81D4F +:10CC70002E07E91A5A08010CFA0249FF9F45840061 +:10CC80003E07E91A84013E07E988D50F49FFF69E61 +:10CC90005A0002F44402D5043C13E3164422B3A81C +:10CCA00049FFEDDC5A0002EA3C0DFA9AA6412E0734 +:10CCB000E9885A1006045A180B125A0001092E006E +:10CCC00004605A0001052E07E978C04884013E0738 +:10CCD000E93D3E07E9388401D5425A00010A2E0099 +:10CCE00004605A0001062E07E9645A08012544032E +:10CCF000F04A44100055AE403C1DFAB6A608C0FFED +:10CD000084003E07E9883E00046084013E0004611F +:10CD10002E07E9695A08120E3C03F4DC8425490009 +:10CD200025EA5A08010784052E100464490024DD11 +:10CD30008402D5152E07E96C5A080F1184003E00B5 +:10CD400004213E07E96C4400007149FF9EDD3C0C64 +:10CD500002733C1C027549FFA53E8401EC043A6F46 +:10CD60009A84DD9E2E07C5DC3BFFFCBCEFFC5A0815 +:10CD7000010A44029370501000285020005849FFC7 +:10CD8000CF453C0DFA9A4412CE682E27E9842E37FF +:10CD9000E9512E47E92F49000A762E07C5DB5A08CC +:10CDA00001102E0004545A08010C4402CE6849FFB9 +:10CDB000F179C806EC043BFFFC8448FFF455EC0411 +:10CDC0003BFFFC84DD9E3A6F9EBCEFF88400100FA1 +:10CDD00080073E00043484C02E07E94BE2C0E85FC0 +:10CDE0003C0C01EA95F138501901DE253C2C01ED8F +:10CDF0003C0C01EC88474432D054A651380019113C +:10CE0000A6903C4004E0490022FA3C1C01EA882735 +:10CE1000A488FE17AC083C0C01EC381019013C0347 +:10CE2000E632E220E8082E07E92F5A00FF058C01C0 +:10CE30003E07E92F3C0C01EA38501C01DE153C1C72 +:10CE400001ED2E27E91588272E30041FA609504F23 +:10CE50008007A64880A649FFF61D3C1C01EA8827EA +:10CE6000A488FE17AC083C0C01EA38501C01DE1502 +:10CE70003C0C01EC3C1C01ED3C3C01EE94B2381042 +:10CE80009C0038001C11884349FFEE503C1C01EA0D +:10CE900088E1A478FE0FAC388CC1D59F006F800765 +:10CEA0005A68012B2E0004358C013E0004354400E5 +:10CEB000007249FF9E292E000435E60BE9222E0060 +:10CEC000043484203E1004353E10042F3E67E93CB4 +:10CED0005A0801182E0004338C019600E60BE90F66 +:10CEE000440000743E10043349FF9E0E4400005578 +:10CEF00049FFA15ED50684003E0004353E000433A0 +:10CF0000EC083A6F9E84DD9E3C0DFA9A3A6F98BC0D +:10CF1000A6015A00030649FFB530E603E9072E07CC +:10CF2000E9695A0005045A08120A84003E07EAE833 +:10CF30003E07EAE93E07EAEAD5673C0DFAC15A081E +:10CF4000010984003C0FFAC14402B51449FFB4FD45 +:10CF50004402D5384412B52049FFB7FF3E07EAEA3C +:10CF600049FFB50B5A0803274402B3644412B36B5C +:10CF700049FFA32D4460005F84018440806080806D +:10CF8000842C80A249FFA1F63C0DFAC15A08010A7F +:10CF900084003C0FFAC14402B51449FFB4D6D5044D +:10CFA0008EC197B0CEEA4402B3644412B36B49FF1A +:10CFB000A34249FFB4E580C05A08011D49FFB4DD12 +:10CFC0005A080309800649FFB4D54400006149FFAF +:10CFD0009D9B49FFB4D25A080505840149FFB4CA94 +:10CFE00049FFB4CB5A08041184013A6F988448FF72 +:10CFF000B4C149FFB4C25A08030884003C0E0111B1 +:10D0000084013E07E9383A6F9884DD9E3A6F9ABCF6 +:10D01000EFF4840C490023DD4403F04A441000552A +:10D02000AE4049FFA2DE3C0DFA9D2E2004692E4041 +:10D03000043AB4608403FE14842A2E200438420289 +:10D04000047388022E200463441003E84201047331 +:10D050002E27E971441000644201047380402E00C1 +:10D0600004212E400439FA2EFE0C926284254202DD +:10D07000047396C644100032420184732E37E91EB1 +:10D08000441027104201847388023C080B9E49001B +:10D090002ACA3C0DFA9AA6415A180D072E07E92A0A +:10D0A0005A080113D5682E100454C9F94412B3B4B8 +:10D0B0004422CE6849FFD6BC2E07E9865A0801F003 +:10D0C0008401480000942E07E9695A0819044900B0 +:10D0D000233F2E07E98BC0512E07E97D5A08010E28 +:10D0E0004402B3AD3C1DFA9D4422B5103C3DFAA666 +:10D0F0003C4DFAA4490026573C0DFABF5A08015A84 +:10D100002E07E97984C03C6FFABF5A08554E3C0D92 +:10D11000FAA43C1DFA9AB61F4422B3644402B4B088 +:10D120003C3DFA9D4442B5103C5DFAA64900276497 +:10D130003E07E9692E0004305A08052C3E07E969CC +:10D1400044022D50FA32AE403E6004302E07E969A9 +:10D15000490023A196003E07E9225A0003485A08D5 +:10D1600002294403F04A44100055AE403C1DFAB673 +:10D17000A608C0FF8402D53A49FFC5FD5A0801AE92 +:10D180003C1DFA9A2E07E971A64949FFA343D5A58C +:10D190005A0804DE3E07E96944022D50FA31AE40D8 +:10D1A0003E600430D5D4440000553E07E979D5CF20 +:10D1B00049FFA6442E07E9715A0803072E07C66ED9 +:10D1C000C80349FFA2832E07E97A5A00010448FFE9 +:10D1D000FF7984003E07E97A49FFFE983C0DFAABDF +:10D1E000A640C9FF8421AE40FA03EC0C3A6F9A8442 +:10D1F000DD9E3A6FA8BC49FFA05DC0632E07C5E461 +:10D200005A0801603C0DFA9D49000C7D4412D1D4AE +:10D210004402D79449001E204402D7944412D1D42A +:10D2200049001D5B4402D7944412D1D43C2C0278AF +:10D23000490010714402D7944412D1D43C2C027896 +:10D240004900178C84804402D79484AA812484C224 +:10D2500080E4B420C13000300054C3222220002ECC +:10D260002210000652A18002FE9C42250473221067 +:10D27000002F22800007FE5C4215207340211856C3 +:10D28000401098369693964B8E61AC86AC47103022 +:10D2900000544E240003ADC64E140003ADC7041065 +:10D2A00000165A180106041000265A1001058C8138 +:10D2B0009720B7208EA1500000FCCDCC3E47E92B33 +:10D2C0003A6FA884DD9E3A6FAABCEFFC2E07E934C2 +:10D2D0005A0801074402B341842249FFA14D2E0799 +:10D2E000C5DC5A0801064402D3F049FFCC712E0771 +:10D2F000C5E25A08010A4402D3FC4412CE68442213 +:10D30000D1D449FFEDE72E07C5DB5A08010F2E00E7 +:10D3100004545A08010B4402CE6849FFEEC3C80505 +:10D320004402D3F049FFF1B3490029AA2E07E9715D +:10D33000540000FBC80C4402D1D44412B37B3C2CF3 +:10D34000027849FFD3C43E07E8D0D50484023E07E3 +:10D35000E8D03C0C027849FFF8394402D3FC44126F +:10D36000B4A844228F708460848549001E0F840015 +:10D37000442291403E07E9684412CE684402B4A8B2 +:10D380005031001449FFF2B42E07E9695A08120E11 +:10D390003C03F4DC8423490022AE5A0801078403CD +:10D3A0002E100464490021A13C1C02793C0C027837 +:10D3B0005030800E5050000E84874462D054A5E84F +:10D3C0003823110188479693AC9802728010382355 +:10D3D00011018847969312218010A4984091001162 +:10D3E0002E27C542884494918841A5D097FBE12718 +:10D3F000E804A4909693AC988CA28C625A400804DE +:10D400008488D5DE3C2C028849002B003E00046352 +:10D410002E07C5E25A0801102E0004385A08010CE4 +:10D420002E07E968C0082E000439C8054402D3FC61 +:10D4300049FFEE2D49FF9F3EC00D2E07C5E45A0857 +:10D44000010A3C0C02784412D1D43C2004E049008B +:10D450000C712E07E968C8074402CE684412D3FC59 +:10D4600049FFF25B2E07E9684E0200BC84003E07CC +:10D47000E96A3E07E9532E07E9695A08120E3C0390 +:10D48000F4DC8424490022375A08010784042E1052 +:10D4900004644900212A2E07E9445A0801073C0088 +:10D4A00004E08E0A3C0804E02E07C5DC5A000106A1 +:10D4B0002E07C5E25A0801064402910C49FFCCEF41 +:10D4C00084023E0004082E07E9515A08010E3C0D63 +:10D4D000FA9DB400920E96065A08010749FFF6B16C +:10D4E0003E000408D50484003E0004082E07E971BC +:10D4F000C80584013E00040CD50484003E00040CE1 +:10D500003C0C02883C1C02784422D1D43C3004E01C +:10D510004442B37B84A149FFA51384003E00040C60 +:10D520004402D1D449FFFC512E07C5E15A08011C21 +:10D530003C0DFA9DB40096065A0001083C0DFAA66F +:10D54000A60096065A0801102E00042CC80C4402AE +:10D55000D1D44412D3FC4422B37B49FFF5933E005F +:10D56000043AD50684003E00043A49FFF5063C0023 +:10D57000021D5A08010B3C0DFA9DB400920E96064E +:10D580005A0801043E00043C2E00043C5A08010FD6 +:10D5900049FFB1E7C80B3E00043CFA2E84048443E3 +:10D5A00049FFB1E2840549FFB1E52E00043A5A086B +:10D5B00001313C0DFA9D84203E100412B400920EFD +:10D5C00096065A0801053E000413D5033E100413C5 +:10D5D00049FF9E705A08021E84003E07E938D5199B +:10D5E0003E0004092E00043A5A08010649FFF4A639 +:10D5F0003E00043A2E07E96A2E17E91BE201E8040F +:10D600008C013E07E96A84003E07E94B3E07E92F9B +:10D610003C00021D5A0900113C0DFA9DB400920E07 +:10D6200096065A08010A84048040FA2E49FFB19CEC +:10D63000840549FFB19F2E00043A3E00043B2E07AB +:10D64000E9345A0801074402B341842349FF9F94F7 +:10D650003C53F4EF3C03F469D8052E07E94D3E072F +:10D66000C5E32E07C5E35A0801383C0DFA9D3C1D61 +:10D67000FAA6B400920196065A000107A608920184 +:10D6800096065A08012AA60892039606C8252E0077 +:10D6900004563C1DFA9A490006913C0DFA9AA601DF +:10D6A0005A0003045A0806152E07E956C0112E0029 +:10D6B0000468C80E3C0C02784412D1D44422B37BD7 +:10D6C0003C3004E0490006943E000439D505490089 +:10D6D00006403E0004392E37E94BCB043E37E9843F +:10D6E000D50D4402D1D43C1C02783C2C0279444232 +:10D6F000D5644452B3B449FFC2BB2E17E984C15567 +:10D700002E37C5722E47C573926192814402D5644B +:10D710008440E241E80BA5408C4188A3AD40A5417F +:10D720008C0888A412507FFDD5F53C0DFA9DB400FD +:10D73000920296065A0801072E07E971C8033E00B7 +:10D7400004224402D56449FFBF4584003C0E011108 +:10D750003C0E01123E07E9783E07E96A3E07E96C94 +:10D760003C0DFA9AA6015A0803172E07E9815A08B8 +:10D77000030F49FFD351C8052E07E9635A08010872 +:10D7800084033E07E981D5775A08037684003E0773 +:10D79000E981D5715A080A702E07E9815A0804F602 +:10D7A00084013E07E981D5672E00043AC8642E1033 +:10D7B000042B3E07E94B3E07E9843E00042D3C0E56 +:10D7C00001145A1001093C0C01114420EA60E240A6 +:10D7D000E9048C013C0E01113C0C01124420EA606A +:10D7E000E240E90E3C2002143C33F4F2E262E8022B +:10D7F000C1058C013C0E0112D5033C1E01122E07FF +:10D80000E9215A0801083E07E93D84003C0E011158 +:10D81000D50484003E07E93D2E0004205A08011576 +:10D8200084003C0E01112E17E9852E07E96CE201F8 +:10D83000E80E2E27E96A2E17E91BE241E9088C0160 +:10D840003E07E96CD50484003E07E96C2E000439DC +:10D850005A08010784003C0E01113C0E01122E678C +:10D86000C5DC5A68010984003E00045849FFCA9E7D +:10D870003E60045849FFF9E75A080204480000F3E3 +:10D880002E00043A5A08010784003C0E01113C0E98 +:10D89000011249FFFA694402D5642E17E984442233 +:10D8A000D7944432D1D43C4C027849FFA89F2E072C +:10D8B000E9695A08120E3C03F4DC84264900201B57 +:10D8C0005A08010784062E10046449001F0E8400C4 +:10D8D0003E07E9444412D7943C0C02782E27E98491 +:10D8E000490026B62E07E9345A0801074402B3411D +:10D8F000842449FF9E412E07C5EB5A08010A4402C1 +:10D90000D7944412D1D43C2C0278490027494402D0 +:10D91000D79449FFBD8B2E07E9695A08120E3C03C4 +:10D92000F4DC842749001FE75A08010784072E10FA +:10D93000046449001EDA49FFFC5E4402D79449FFA3 +:10D94000B78E2E07C5DB5A08011D2E0004545A0855 +:10D9500001194402CE6849FFEBA5C8134402D1D493 +:10D960004412D7942E27E9844432B49449FFEBA89B +:10D9700049FFEE775A0801064402CE6849FFDE17D8 +:10D980008400842184413E17E9723C0E01093E0760 +:10D99000E9612E67C5493C7C01EB80A04412D79415 +:10D9A0008060853D8142448000FFE266E824B481C6 +:10D9B00040F224025AF00105CC048085D51784403A +:10D9C000A10F384391015CF20100E808E69512408E +:10D9D000800AE9068C019600D5031280800A044073 +:10D9E000800912A0800BE285E9E98C61501080FC6F +:10D9F00080A4D5DC3E07E9613C5E01093E27E9725F +:10DA000049FF9C6649FF9C565A08020C4402D79471 +:10DA10002E17E9844422D1D43C3C010949FFEE474A +:10DA200049FFFA742E07E9843E00041D49FFAF99AF +:10DA3000C0093C000207E619E8078C013C08020710 +:10DA4000D5033C0802072E67C5DC5A68010E3C0D61 +:10DA5000FA9AA6015A00060A5A000B0849FFCF1984 +:10DA6000D50480C0D50284C18006EC043A6FAA8434 +:10DA7000DD9E3BFFFCBCEFF449FFDC54F081F1017B +:10DA8000840049FF9CDA440245104412400049FFDB +:10DA90009EA24402D3FC4412B48C4422D5044432E6 +:10DAA0008F704442D3F049001AAA2E07C5DE5A08E7 +:10DAB000010BEC0C4402D3FC4412D0543BFFFC8419 +:10DAC00048001DDEEC0C3C0C02793C1C02783BFF4C +:10DAD000FC8448FF9E803A6F98BC2E67E9195A6013 +:10DAE000010784003E07E9458401D51F2E07E9455B +:10DAF000C806840849FF98083E67E9454900036164 +:10DB00005A0002145A0013113C0DFAABA6009600FD +:10DB1000C80B3E000464490003865A00130649FFFF +:10DB2000FFAA4900039AFA033A6F9884DD9EFC002D +:10DB30008401842084613E07E90A8041440074A086 +:10DB40008083490007645A08AF39842184008041EA +:10DB5000806180813E07E90A4400FBA04900075725 +:10DB6000844180628082441000FA440074A049001D +:10DB7000074E844180628082441000FA44002D10D8 +:10DB800049000745844180628082441000FA4400C5 +:10DB900080104900073C844180628082441000FA72 +:10DBA0004400D510490007338441440015A0842067 +:10DBB000806280824900072BFC802E07E90AC82F6B +:10DBC000FC00844180628082441000AF440074A055 +:10DBD0004900071D844180628082441000AF4400E8 +:10DBE0002D1049000714844180628082441000AFE8 +:10DBF000440080104900070B8441806280824410F9 +:10DC000000AF4400D51049000702842180418061A3 +:10DC10008081440015A0490006FAFC80DD9EFC408E +:10DC20004423F04A443000553C1DFAB6A648C903C7 +:10DC3000AED0D5FB2E17E9895A18256284203E17ED +:10DC4000E9893E17E9743C1C0180444200003C6DA8 +:10DC5000FFF604108012844092305410FFFF944A63 +:10DC6000882480A4B461FAE8926A96F70213001A35 +:10DC7000E241E80E95119865B520A4488889FE7C9C +:10DC800040108C3796498C41AC609691D5F049FF95 +:10DC9000FF96440000FF2E10046449001D26440234 +:10DCA0001B904412000049FF9D9644021B904412B1 +:10DCB000400049FF9D904413F69284003E07E91905 +:10DCC0003E07E9253E07E952AE08840080208040E7 +:10DCD000FA6F49FFD78D49001D85840049FFDA5945 +:10DCE0003C1DFA9A2E07E91384812E27E929A649BB +:10DCF0002E37E9464452B4E449FFBFF8FCC0FC208B +:10DD000080804403F04A44100055AE403C1DFAB6F2 +:10DD1000A608C0FF2E07E9895A08022B2E07E90939 +:10DD2000C0218420445200002E07C54F9201E220FA +:10DD30004EF2008684402E07C550E240E8102E07C0 +:10DD4000C54F806142310073B40494D9880388655B +:10DD50008C41A4D8969096D9ACC0D5EE8C2196482B +:10DD6000D5E444020000B42449FF9D35D568E6039C +:10DD7000E9663C0C0180442001FF84A004100012DD +:10DD80004402005492305410FFFF944A8820440FFC +:10DD9000FE01B421B4C4922A9677FE0CFE54845638 +:10DDA00096014010883680E54440051098B5A4D00F +:10DDB000886096D9ACD0A4D096DB4E340007A4D0AE +:10DDC00096DBE023E802ADD08CA2DCF149FFFEF740 +:10DDD000440000FF2E10046449001C8744021B907D +:10DDE0004412000049FF9CF74412400044021B907B +:10DDF00049FF9CF184003E07E97F3E07E9523E0758 +:10DE0000E919840049FFD9B44413F04A442000556D +:10DE10003C0DFAB6A600C803AE88D5FB49001CE24B +:10DE20003C1DFA9A2E07E91384812E27E929A64979 +:10DE30002E37E9464452B4E449FFBF58FCA0FC40E9 +:10DE400084203C6DFFF63E17E93D84203C1BF4DB4B +:10DE50003C1BF4EB2E17E9870223001AA1455A1840 +:10DE600001082E27C5430440000C9491D5028085FB +:10DE70003C13F4DE3C33F4DDE223E9073C6DFA8F1A +:10DE80003C7DFA8E8420D56F8C2196493C1BF4DEB4 +:10DE90005A10010580048420D54C8420443FFF8023 +:10DEA0004450007F9609E202E80B3C0DFA8F3830AF +:10DEB00004083C0DFA8E385004088C21D5F42E0746 +:10DEC000E9875A0801E93C5C027D3C7C027C8420A5 +:10DED000000300109401E020E8DE94C940928C0019 +:10DEE00088678C21A4189649960112048000D5F108 +:10DEF0003C6DFA8F3C3DFA8E88C12E57E98720434E +:10DF00000000383184105A580106A540976B90A242 +:10DF1000AD40A540976BE085E910A540976BE0A365 +:10DF2000E917AF303C4DFA8E8C02383204088C2150 +:10DF300096C9E262E9DED541A50097235EF2008032 +:10DF4000E804A5009723D5EA4440007FD5E7A4C0A4 +:10DF500096DB5EF1FF81E904A4C096DBD5E3443F84 +:10DF6000FF81D5E096C9E262E813384304103833E4 +:10DF7000840040422008FF1F94C940928C008C21ED +:10DF800012448000049000068869AD18D5EC84C066 +:10DF9000440000FF2E1004643E67E95C3E67E91907 +:10DFA00049001BA32E07E9875A0801043E07E9210F +:10DFB0003E67E9873E67E986FCC0FC0084003E07B7 +:10DFC000E97B3E07E9192E07E96549FF9A1D2E10E6 +:10DFD0000464440000FF49001B882E07C54B520013 +:10DFE000000149FF9A11FC805A08040EFC0044000D +:10DFF00000FF2E10046449001B783C0DFAAB84210D +:10E00000AE40FC803C0DFAAB8421AE40DD9EFC00AE +:10E010004413F69E80C04403F69F8440AE88AE80D1 +:10E020004403F6A0AE804403F6A1AE804403F6A2FA +:10E03000AE804423F6928403AE10A6B040310C09A2 +:10E040008823969784614021880CA6C8FE9FAE88DD +:10E050004413F6AAFA4FAE884413F6ABFA6FAE0833 +:10E0600084008020804049FFD5C3A6705CF08023E7 +:10E07000E8038C21AE70FC805A10050E5A1007047C +:10E080005A18030F500000569600E602E909840270 +:10E09000AE10DD9E500000569600E605D5F8DD9ED8 +:10E0A000FC4181003C0DFAAB81218422A7C084C1D0 +:10E0B000AE4084008142F38197F83E67E9523E0703 +:10E0C000E9893E07E9743E07E95A5A28030A3E6780 +:10E0D000E92549FFFD2E840149FFD85BD5093E673C +:10E0E000E97F49FFFD265A88AD043E67E95A50048E +:10E0F00000559600E602E806840449001B9A3E8714 +:10E10000E90854048002C00E5AA8030544029990FD +:10E11000D5154402999449FFBF5A84003E07E90986 +:10E12000D50F49001B6B4E9300075AA003F1440220 +:10E130009994D5045A980105F00149FFBF483C1D48 +:10E14000FA9A2E07E91384812E27E929A6492E374A +:10E15000E9464452B4E449FFBDC93C0DFAA7A00604 +:10E16000920A962F3E07E98C3C0DFAABAFC0FCC17A +:10E17000FC2080E180C2C00D5A00041184003C0BD9 +:10E18000F4E449FFC16F44423FD844323FD6D50A38 +:10E1900044423FD244323FD0D50544423FD8443276 +:10E1A0003FDC84009680E246E8073813810138128C +:10E1B00001098C01D5F83C03F4E4AC18FCA0FC0187 +:10E1C0002E07E9665A0001062E07E94C5A08010598 +:10E1D00049FFE3A7D5222E67E9875A6801212E0758 +:10E1E000E9865A08011E4402D3FC49FFFE2A802614 +:10E1F0003C0DFA9A49FF9CD8800649FFD96F3C0D27 +:10E20000FA9A49FFD982F08184408402F101806644 +:10E21000808280A249FF98AEFAC3D50284C18006ED +:10E22000FC81FC002E07E9255A0801074402D3FCB3 +:10E2300049FFFCF7D5092E07E97F5A08010C440273 +:10E24000D3FC49FFFD5E2E07E96949FFFECFFA03C3 +:10E25000D5028401FC80FC002E67E95C5A68010746 +:10E260004402D3FC49FFFDEDD5082E67E97B84010C +:10E270005A68010849FFFEA33C0DFAABAF80FA03D0 +:10E28000FC80FC40A7002E67C5495A4001078480E6 +:10E2900044728F708124D5124442937184A0D608B1 +:10E2A000087200018CA110727FEA9768D5F9A60068 +:10E2B0003C43E6325A080149D5099760E2A6E8F8DE +:10E2C00099678C81109283ECD5F92E07E9779A1023 +:10E2D000E402E9095A3801082E07FFDEE605E807DF +:10E2E0008C01D50284003E07FFDE846084003E0777 +:10E2F000E977A609C8265A3001085A28010C3C03C0 +:10E30000F53CE614E9073C0004E08C053C0BE49D79 +:10E31000D5033C4BE49D2E07E9445A0801073C0015 +:10E3200004E08C113C0BE49D3C0DFA9DB40092027C +:10E3300096065A08010D3C0004E050000023D50564 +:10E340003C03E389D50284003C0BE49DFCC0FC0047 +:10E3500084203C1BFFF53C1BFFF43E17FFEF4410ED +:10E3600000403E17E89D3E17E89C3E17E89B3E178D +:10E37000E89A3E17E8993E17E89884203C1FFFFE74 +:10E380002E10046884003E07FFF03E07FFE03E07C2 +:10E39000FFED3E07FFEC3E07FFEE3E07FFE15A1898 +:10E3A000010B3C1DFA913C27F531A44CE041E803F8 +:10E3B0003E0004688400FC803C43FFF33C2DFA914E +:10E3C0003C33FFF2C009E68FE9038E85AD11E66F9D +:10E3D000E9058E65D502AD11ACD4A6095A0806042C +:10E3E0008401D5032E07FFE2AE10DD9EFC49F081CB +:10E3F0003C0DFA91F1842E17FFE0A5C2F288F38C50 +:10E40000A6005A1801049401D5029601F0853C0D2E +:10E41000FFFD84C2A642A603B63FF0892E07FFF097 +:10E420005A08010384C08401100F80429431960081 +:10E430005210001052000024960085209648FA40A1 +:10E44000100F8041100F80453C0DFA7F101F804057 +:10E45000102F8043101F8044129F801F109F804602 +:10E46000109F804749FFD256B0518041B01049FFFC +:10E47000D28CB41FF1018C01FE3494018801501F2D +:10E48000803E804149FFD24B3C0DFAA8FA33101070 +:10E49000000A12900004840049FFD3744403F04A38 +:10E4A00044100055AE4049FFD2304413F140A60855 +:10E4B0005A0001FF3C0DFAA8F101020000119789F2 +:10E4C0008A0692015410000F960192044090801029 +:10E4D0009642F182221F801FF1832E17FFF05A18F7 +:10E4E000010E3C1DFA9185EAF203A44A944B4010B8 +:10E4F000BC36E022E8038CF997F9F1033DEDFA917F +:10E50000E0E114FF8007F203021F0001544480FF82 +:10E51000F18640A088079E64E629E8089E44964854 +:10E52000E63DE80484213E17FFE14EA2004C2E1F79 +:10E53000E89D5A10405D2E37E8992E27E89B2E67FC +:10E54000E89AF38A2E77E89884A0E2C2E91FB47FA4 +:10E55000FED4F38BF30AE2E3E916048F800B04FF89 +:10E560008001890340840408890F028400004084EC +:10E5700000114E8400045284000088A88C61976BBF +:10E5800096D8D5EA8C419690D5E1F206E045E9357A +:10E590002E27FFE1C2322E2FE89CF3029A9A4E24D6 +:10E5A0000003FE924014840196924E140003FE4A2A +:10E5B000964AE424E803E444E92084213E17FFEF6F +:10E5C000D51C440000403E07E89D3E07E89C3E07FE +:10E5D000E89B3E07E89A3E07E8993E07E8983EA781 +:10E5E000FFEF3EA7FFE03EA7FFE1D509001F80082F +:10E5F0003E97E89D3E17E89C5AA001048400D57E12 +:10E600004E9200059F619768D50280A9B43F8E2184 +:10E61000E121E8038C81D5029708F10285004E17AD +:10E6200000059E41548080FFF1099F89F102E02698 +:10E63000E8029D81F103840440308076844096D9BD +:10E6400097B080E880228002F38DE2C7E924B47F8E +:10E650008A05FEFCF38AF08B8065F00BE283880369 +:10E660009600E916F00A04FF800188039401880FE0 +:10E6700002F00000A400882F04FF800D9603E00F35 +:10E68000964BE8038C4196908C6196D8D5E78CE147 +:10E6900097F8D5DC2E37E8995A38400A3E87E89B30 +:10E6A0003E67E89A3E57E8993E47E898F402B4BFBF +:10E6B000806942321473F40194D98864025F0005C2 +:10E6C000A518FF44846940F28DF6E02F9723E915E1 +:10E6D000025F00068A249F01FF2C964B40F20DF644 +:10E6E000E02FE90B44100064FE8C40010016E41991 +:10E6F000E98684013E07FFE084013C1DFFFE5A10BD +:10E700000131C1055A10024A480000813C17FFF44C +:10E71000F206E022E8038420D506022F0002E04141 +:10E72000E80484213E17FFEE2E17FFEEC9185AA801 +:10E730000117F107C914C8132E17FFEF5A1801105B +:10E740002E17FFEDF2058C218C4196489041E04157 +:10E750003E17FFEDE85B3CAFFFFED5188400D516F1 +:10E760005AA80118F107C915C8142E17FFEF5A1837 +:10E7700001112E17FFEDF2058C219648E2413E175C +:10E78000FFEDE84484223C1FFFFE3E07FFEDD53E2F +:10E7900084003C0FFFFED5FAF207021F00075A2043 +:10E7A00001045A0801202E07FFEC002F0001E2406F +:10E7B000E9048C013E07FFEC3C03FFF5E220E9048D +:10E7C0008C013C0BFFF52E07FFECE240E9053C0312 +:10E7D000FFF5E220E81B84003C0FFFFE3E07FFEC44 +:10E7E000D51384003E07FFEC84005AA001053C03CA +:10E7F000FFF58C013C0BFFF53C03FFF5E220E8063A +:10E8000084003C0FFFFE3C0BFFF53C0DFFFE5A0859 +:10E8100002048401D50284003E07FFF02E07FFF0BA +:10E820005A000104480000A549FF9544C00E2E0778 +:10E83000C5E45A08010B3C2DFA913C0C02784412B5 +:10E84000D1D4A494490002763C3DFA913C0C028854 +:10E850003C1C0278F204A4DCF40884A149FF9B70FC +:10E86000F008A6004E0200853C0DFA9184C0F085A8 +:10E87000B41F45EF80008E01F086F0098E01F0870D +:10E88000000F801CF08B000F8018F08DF008A600A0 +:10E89000E2C0E86EF0044083040804900001892877 +:10E8A00002548000DE62A00338001901F082F102F8 +:10E8B000F00CE201E95AF004A0048808A641A68001 +:10E8C000C1059E0954A000FFD5028141F006E02059 +:10E8D000E8048C219648D502F10DC2049F119720BF +:10E8E000D5028082F007E040E8048C419690D50282 +:10E8F000F20B84608003E244E91BB4FF8A0AFFE460 +:10E90000F789F08A80EAF00AE22788079600E90D85 +:10E91000F00904FF800188079401880F8CE1A400AE +:10E9200097F8886096DBD5F08C819720D5E5F105C6 +:10E93000A48D8429FE8440F105F6E06FE912F2020D +:10E940008E018A62F20596DBA496FE1440F005F66D +:10E95000E06FE907F004A00238002001E603E805B3 +:10E960004052F804125480008CC197B0D590020F29 +:10E9700080063C0BFFF43C0DFFFE8E025C000001A4 +:10E98000FCC94402519B4412519AA600A64840007B +:10E990002008FE0FDD9E4402519D4412519CA600AA +:10E9A000A64840002008FE0F441FAE6088205CF09F +:10E9B000805AE903440051A0DD9E44025198A6000C +:10E9C00092019606DD9E44025198A6009202960698 +:10E9D000DD9E44025199A600DD9E4412519EA60878 +:10E9E0009600C00EA60896005A00010BA6089600D5 +:10E9F0005A000207A60896005A0003038400DD9E11 +:10EA00004412519F9600AE08DD9EFC00446251986E +:10EA1000AE704412D6F8B6018401A989102080098D +:10EA2000100080081030800A1000800B80018024C4 +:10EA300049FFD125A630FC80FC00844184208062FF +:10EA400080824400B10049FFFFE284003C0FFACB12 +:10EA50003E00041CFC80FC003C13F47D4400003CA0 +:10EA600049FF97F03C0BF4613C13F47D4400003304 +:10EA700049FF97E83C0BF45F3C13F47D44000032FF +:10EA800049FF97E03C0BF45E3C13F47D440000C763 +:10EA900049FF97D83C0BF45D3C13F47D44000032F1 +:10EAA00049FF97D03C0BF45CFC8080413C53F47CE4 +:10EAB0003C13F47DD126FC00443000FC42010C7371 +:10EAC00080C00200002549FF97C3120300253C13B4 +:10EAD000F47D0203002649FF97BB120300263C1376 +:10EAE000F47D0003007449FF97B3100300743C13D6 +:10EAF000F47D0003007A49FF97AB1003007AFC8095 +:10EB0000DD9EB420922696465A180109B4409245DB +:10EB10009686CA043C1E00DFD510B4209226964685 +:10EB20005A180109B400920596065A080104840295 +:10EB3000D50284003C0E00DF3C0C00DF3E07E91EDE +:10EB4000DD9EFC003C13F47D4400003C49FF977AB5 +:10EB50003C0BF4603C13F47D4400003249FF977293 +:10EB60003C0BF45A3C13F47DFA0049FF976B3C0BC5 +:10EB7000F4583C13F47DFA1349FF97643C0BF45BA3 +:10EB80003C13F47DFA0E49FF975D3C0BF459FC8071 +:10EB900080413C53F47C3C13F47DD12EFC00443086 +:10EBA00000FC42010C7380C00200004E49FF9750E8 +:10EBB0001203004E3C13F47D000300A249FF974866 +:10EBC000100300A23C13F47D0203005049FF97405C +:10EBD000120300503C13F47D000300B449FF973842 +:10EBE000100300B43C13F47D000300B549FF9730D7 +:10EBF000100300B5FC80DD9EFC0280A1F281B421EF +:10EC0000A0A9F382F48349FFD2E48401F10149FF12 +:10EC1000D304F00249FFD31484C08006842049FF46 +:10EC2000D31D8006F1038CC149FFD3405A6808F711 +:10EC3000840049FFD30949FFD2DF840149FFD3048F +:10EC400049FFD2DA840349FFD2FF49FFD2D549FFF9 +:10EC5000D2F3FC82FC40AE888440A708E244E81A64 +:10EC6000A10138520901D214A1059592956A99E63D +:10EC70008885A7FA00F20002E2EFE802AFE2A1C540 +:10EC800088C788A7A733A7ABE2C4E802AF2B8C41A3 +:10EC9000D5E59DD984A092E1506080258125D736A5 +:10ECA000A688E2A2E82EA081382115014C22C02AB4 +:10ECB00050F00014B50F94AA8902990D00A4000326 +:10ECC000008400028D418B4810A20025B54F894277 +:10ECD00000A5000210A20037B54F884AA693102263 +:10ECE0000049A08338A115015022803494918841B5 +:10ECF00012A10003A084382115001022005BD50367 +:10ED0000109300008CA18CC1D5CB8C2184A0849F52 +:10ED1000D30FB440382115005A28FF04AF08D50599 +:10ED2000A18138230901AE888CA18C21D5F2FCC0C9 +:10ED3000FC4A2E77C5435CF100248120B63F2E6744 +:10ED4000C54250A3FFFFE909FA133C0BF4CB408303 +:10ED5000040880298400D5043C2BF4CBD5F9E207C4 +:10ED6000E808B0C23820A005382181098C01D5F807 +:10ED7000B43F80473C33F4CB44400055B00249FFD8 +:10ED8000FF3DF0814412CD18B41FF201806749FFA6 +:10ED9000FF634014A0008400E207E8090220FFFF9F +:10EDA000B0C28828382181098C01D5F7B43F80474B +:10EDB0003C33F4CB44400055B00249FFFF1FF081C3 +:10EDC0004412CC84B41FF201806749FFFF458400E0 +:10EDD000E206E80838148101B082381101098C017B +:10EDE000D5F8B43F80463C33F4CB44400032B00207 +:10EDF00049FFFF04F0814412CBF0B41FF20180669A +:10EE000049FFFF2A429428738400E206E808381478 +:10EE10008101B082381101098C01D5F8B43F8046D8 +:10EE200044400032B0023C33F4CB49FFFEE7F081AE +:10EE30004412CB5CB41FF201806649FFFF0DFCCA8F +:10EE4000FC4683C02E07C542F385F486F0812EA7C9 +:10EE5000C543C907406088068401C20984FFD508FC +:10EE6000C20484C3841FD5FB84C2841F84E1F301E0 +:10EE7000FED4808388819521F384403F10003C4379 +:10EE8000F4CB22918000F387E0894EF200F59710D1 +:10EE9000F4889708F489F308F4058883A6E1F38AD7 +:10EEA000F40AF305888320320025F409F382F3067F +:10EEB0008883A6E1F38BF40BF306888320320025C8 +:10EEC00038429800F383C404848438429808F302DB +:10EED00042938824E06AE903F3028E618923F301F7 +:10EEE00042438824FEFC048F80018C8141C1840848 +:10EEF000814142321C2442A1A073806A94D98500CA +:10EF000040AF0C00B71FE124E90B38F520114EF794 +:10EF10000005B47F886FB67F8C81891CD5F5B47FDE +:10EF2000CB038461B67FF303F40142A00424E064C0 +:10EF3000E8038943D504F4038E8189449501429006 +:10EF400004248D218064F4044244807395218780D9 +:10EF5000408F1000809CE149E90A38F470114EF7A7 +:10EF60000003888F8D2141CE0C00D5F6CC02848120 +:10EF7000F3018847FE9C4080800040912000854A34 +:10EF800039CF25113CFC00DFE91FB43FF2054230C8 +:10EF9000A824F10A40319076501080349449884179 +:10EFA0004490005AA513F204441000508848FF0C06 +:10EFB000429E24244410006440420496382F0911D4 +:10EFC00040948536D520B47F4242282440320C76C6 +:10EFD000F40B049F80065042003495218924882236 +:10EFE00002F4800344400050382F05114410005AA9 +:10EFF0004490006442479024421E042440422496D8 +:10F000004090A536F10722F08000E08FE840F10241 +:10F01000E423E804F103E423E93AE122E838E47563 +:10F0200038329800E8035A380433F103F2098E218C +:10F03000422004739652F202F4088E4142438873D0 +:10F04000852496A238929808992ECB03AEA4D510A9 +:10F050002032000442F38824FFDCE0EFE802AEA493 +:10F060002022000842F00424FE14E00FE8101012E1 +:10F070000008D50D8E84E12438029800E804C0070A +:10F080008E01D503C004840438029808FCC6FC46EF +:10F09000F1892E17C5438383F182F48AF58B2E37CD +:10F0A000C542843FC802842194D943E080243C4374 +:10F0B000F4CBF387423F0424F3818A608E8494D991 +:10F0C000F484F38895018540F302E143E862F30A92 +:10F0D0003831A8005A38014DF309886AA6D95A3048 +:10F0E000FF34B4BC383290005A30FF2FBE01BF0548 +:10F0F000B6DF38630D0197AFC80594F28867A7D9CA +:10F10000D50338739A0042338424F383F308813E95 +:10F1100088648865F38684A08060F703E0E9E915D8 +:10F12000F70188E5F785F70638F39500B4FF3883D3 +:10F13000BD015484003F4C8340055AF0FF03F305A2 +:10F140008D2188A1D5EB80602051002442608C2461 +:10F15000FF4CE0C5E809A750E6A3E9038EA1AF5034 +:10F16000A750E6A3E811103100248464D50CF30BFA +:10F1700010010024F50438319011E065E805A6D0AF +:10F18000C3038E61AED0F3078D418C418883D59D3A +:10F19000FCC6FC422E87C542F2812E77C543CD6363 +:10F1A000B0838142B181C00451C07FFFD50283800A +:10F1B0009EBAE241E8038EE1D5029DC944200032A7 +:10F1C000FF1444200064F083404208978520F50333 +:10F1D000E225E91004F50000B44642243C7338F1FE +:10F1E0008911E28FE903D003D1028D2A8CA1F58326 +:10F1F000D5EFF083B4AAB446422414733C9BF4CCFC +:10F20000382189114E270004E282E80284404C0034 +:10F21000800FF18304F50000B4A642543C733851CA +:10F2200095114E570005E285E902884515CF800308 +:10F230004DC0000CB4AAB406420414733801811105 +:10F24000E408E9038E078840F7834C708012B42AE3 +:10F25000B4064204047338018111E408E9098E07F9 +:10F260008840D506B08180E88142B183D59D840A6B +:10F27000FE144040109740022400FCC28E61E664F8 +:10F280003C53E2A93C43E2AAE826FC0022600000CD +:10F2900044F0F1A038378C0040F1BC004A003C003B +:10F2A0000410181CE026E91922100001E041D510D5 +:10F2B0008EA19A69E0C1D5F8E026D5048EA19A699D +:10F2C000E0C1E90B221000018E819A22E02056074E +:10F2D0008001D5048400DD9E8400FC80442000FC75 +:10F2E0004200887322F0000984205EF784B7E902A7 +:10F2F000842114100025DD9E442000FC4200887308 +:10F300008421141000161010005584201410000FD2 +:10F31000DD9EFC5DF084F2818101FA548420B016F8 +:10F3200049001D388420FA54B01F49001D33842041 +:10F33000FA54B02849001D2EB0318420FA544900F7 +:10F340001D292E07C542B61F2E07C543F08E3C036C +:10F35000E2A9F0953C03F4575CF00190E8048C01BD +:10F360003C0BF4573C03F4565CF00190E8048C012C +:10F370003C0BF4563C03F4555CF00190E8048C011E +:10F380003C0BF45584208041F0014432CD184442B6 +:10F39000CBF04452CA3049FFFD55F00E84209F81C6 +:10F3A00097B2F00180464432CD184442CB5C4452BF +:10F3B000CA3049FFFD47B41F84408E019602F09188 +:10F3C000F111F0014432CC844442CBF04452CA30B3 +:10F3D00049FFFD38F001F11180464432CC844442AB +:10F3E000CB5C4452CA3049FFFD2D8400F0854402B5 +:10F3F000CB14F082B016F08884004492CD18F086C9 +:10F400005004806E50648025F083854000048000A5 +:10F41000E340E82A08030001C02200030023007330 +:10F420000011F087F003F107F206A50084003C0B01 +:10F43000F4CCF301800784A049FFFEAD5CF0005BD3 +:10F440004EF20667F00288E0F002F1079A38E220F7 +:10F45000E90608038001C0F94800065BF0038D410E +:10F460008C02F083D5D4F0055A000104480006430D +:10F4700084004412CD184422CB148068B116F501E3 +:10F4800049FFFE07F0114412CC844422CACCF50196 +:10F490008068B11F49FFFDFDF0048420F0835020F7 +:10F4A00009D880A0B405C0118E04E602E90E00025E +:10F4B00080F3E602E90A0402800FC80704028020F4 +:10F4C0005CF00065E9028421505280FCDAEC5A18A5 +:10F4D000010C840A3E07FFFCB41FF6049401F0936C +:10F4E0008400F087D50D2E07FFFCC0F78E01D5F301 +:10F4F000B406C80DF007506300FC8C01F0872E079E +:10F50000C549F107E220E9F5480005875A0005F4EE +:10F510005A080404480004980003001C0414000462 +:10F52000F08A94018801A641A600F18BF086000FB5 +:10F53000802CB43F10030065000F80188E2110034B +:10F5400000640403000FC80804040005F20A380030 +:10F550000A00C010D5035A000116B41F81218E0283 +:10F56000F08F4402CA3CF08D841FF0894402CC84A1 +:10F57000D5114412CA84F18D8421F189F18F812043 +:10F58000D5074412CA84F18DF089F08F852044029A +:10F59000CD18F10A944AF192F2120414000588225F +:10F5A000B45FA7C88E41A749CF07DA07440000FF20 +:10F5B000F08C8441D550DA4AA68AB47FA74B8029C3 +:10F5C0004211887394498460E2A2E940B48888813A +:10F5D00038420C005A40FF22047400013873910134 +:10F5E0009902A7215A40FF1A04AF800A4C754016B1 +:10F5F00080248820F48C0020805B00A0803700707D +:10F6000080495012003494498801F288A5034EA322 +:10F61000000914AF8002D508F4138C418864D5D555 +:10F6200050057FFFF082F00E8E02E207E804F00E34 +:10F630008E01D5029C39F0858049800A8027F3012C +:10F6400084A049FFFDA88040D50A440000FFF08C4B +:10F65000844184E08147F788F785F782B43FF00260 +:10F66000F301FE0C4010240094498823F194F10F1B +:10F67000F4028801940141E1800084608003F390EA +:10F68000F105E024E912F11438508C114E570005B1 +:10F69000F1108825F190385F0C114E570003880552 +:10F6A000F1138C818861D5EDF3028A23FE4B8467C8 +:10F6B00042008C734E0600038401F294F210842AF7 +:10F6C000FE5440008016F08FF107F00449FFF9EF77 +:10F6D00000030018F2149606C0733C03F45D041393 +:10F6E000000F846012030034103300CBC123842147 +:10F6F00012130025842314130016103300554EA254 +:10F700000006F10E8E214C70C0058C0A12030034E5 +:10F71000000F8020F108B47F1003007D80094200B3 +:10F720008C73F10138008111122300281203003F6D +:10F73000D50E440001901203002584011403001625 +:10F74000100300551213003F121300282213000863 +:10F750005053006CF00FA869B6058485840012131D +:10F7600000671213002E0213000910030054104307 +:10F7700000571213002FF40A04140003846012339C +:10F780000026381091011003007410030075100357 +:10F79000007610030077100300781003007910033F +:10F7A000007A1003007B1003007C840012130029F0 +:10F7B00010330056A82D840110030084D573040370 +:10F7C000000FC0224EA20006F00E8E014C704007C2 +:10F7D0003C03F45D8C0A120300340003007DB47F07 +:10F7E000802942100C738001F1013800811122132D +:10F7F000003FE020E8031203003F02030028E2027A +:10F80000E80312230028020300255CF00190E80FB2 +:10F810005033006C8C0112030025F10FB4038801F2 +:10F82000B603A059220300088801A819B4065A0893 +:10F830000108A4361203002EA4371203002F02037E +:10F840000028E202E80312230028F10A040400035E +:10F850003800050122130029E020E80D9603120369 +:10F86000002944100064FE0C3C17F53140000416DA +:10F87000120300682203002E223300089AC34E347C +:10F880000003FEDA2213002F220300099A084E0417 +:10F890000003FE02041300208803E220E80314039F +:10F8A00000203CAC00DF8400100300484EA3003071 +:10F8B0000403000FC02C5A00010384034412CA3011 +:10F8C00038308000C3248801F309F40B20100008AD +:10F8D00042F19024FE5CE02FE91AF10620000004BA +:10F8E000FE4AFE02E001E913020300285CF0002951 +:10F8F000E905840110030048D50A00030057C0073A +:10F9000084218E0110130048100300572233000891 +:10F910005001FF9B96015CF00377E90444400037F7 +:10F92000D50344400064840F4EA30003FA0E001375 +:10F930000048C9620413000FC15F0413000C5A1081 +:10F94000025C041300168E22E622E85622130006FB +:10F95000E001E85252F0043FE02FE84E0203002895 +:10F96000E280E94A0403001122130067C81D9ACB04 +:10F970004E340003FEDAE67EE9170213002540311B +:10F980008477E665E9110213002F50F0FFB95CF7A8 +:10F9900088DFE80A00030055C8290003009E5A08C2 +:10F9A00001268402D51702130025E624E9048E01FE +:10F9B000E602E8053C03F45CE201E81E00030055A2 +:10F9C000C8150013009E5A180112001300F3E62216 +:10F9D000E80410030054D50A8422100300CB44002D +:10F9E00000321013005412030066F004F107F2898C +:10F9F00049FFFC84F2092E07E984F08900030048DE +:10FA0000C0070433000F4E3300834800015904033C +:10FA1000000FC0F804030011C8F50403000C5A00DD +:10FA200002F2040300165A0005058E02E602E8EA17 +:10FA30002243002F220300099AE04E340003FEDA2D +:10FA40002E77C57344500032FF7C0273002844F0C7 +:10FA500003E8FF7C4052BCB7E2A32213002E23E34D +:10FA60000008E8D05CF18029E9CD80E90053007DF1 +:10FA7000B53F85E24272A473049F800138949D11C2 +:10FA80002273003F4073BCF6E0E9E80AF702E0A702 +:10FA9000E904F705E0E5E8B65CF1812DE9B3F30987 +:10FAA00044F000C8F51040378C76E065E8AB8A3E3C +:10FAB0004E140003FE4AE435E91500130055C9123F +:10FAC0000013009E5A18010F842210130054501284 +:10FAD0007FB996495CF088DFE8058804900112033D +:10FAE000002FF004F107F28949FFFC08F10DF00244 +:10FAF000F20988018420F30DF4059AC3E2834EF3E2 +:10FB0000FF821810000110100023D5F60403001620 +:10FB10005A000304480001110213002502030034B7 +:10FB2000E201E97404030010E602E80B0203002678 +:10FB30008C0112030026000300748C011003007472 +:10FB4000000300485A08010C020300268C0112032E +:10FB50000026000300758C0110030075F00F5EF0A5 +:10FB60000029E805FE145CF007D1E90B020300262A +:10FB70008C0112030026000300768C01100300762E +:10FB8000020300285CF00047E90D4EA3000C0203BD +:10FB900000268C0112030026000300788C0110035C +:10FBA0000078040300205CF00065E90D4EA3000C12 +:10FBB000020300268C0112030026000300798C0149 +:10FBC000100300793C03F4625CF00032E8092E2750 +:10FBD000FFFCC2064EA3000584451423001604232F +:10FBE00000118E41E6424EF200A84EA300A6C803C3 +:10FBF000E622E80A3C13F45EE2014EF2009E2E0774 +:10FC0000FFFC4E02009A8405D5340403001B40001B +:10FC100004175CF00038E816FE845CF10ABFE812B5 +:10FC2000F20F8A028C0AE615E80D020300285CF048 +:10FC30000033E80802030026002300768A0212033C +:10FC400000260403001C40100436E42BE90DF015D7 +:10FC500050F07FF5E02FE80802030026001300743F +:10FC60008A011203002602030026E610E905840239 +:10FC700014030016D5615A38010722030006E41E5A +:10FC8000E9F7D5085A38020722F300065EF7842305 +:10FC9000E8EF00030055C80E0013009E5A18010B30 +:10FCA0008422100300CB44000032101300541203CE +:10FCB0000066F004F10749FFFB21D53E0403000C68 +:10FCC0005A00023B040300168E02E604E8350003E6 +:10FCD0000055C80E0013009E5A18010B8422100311 +:10FCE00000CB44000032101300541203006684015C +:10FCF00014030016100300550203002F50F07FB9C3 +:10FD00005CF787F2E8192213002E5000FFA196013C +:10FD10005CF00383E80E22030067E001E8055EF073 +:10FD2000005FE907D509E020E8075EF003E2E90497 +:10FD30008402100300CB0403000FC01EF10644022E +:10FD4000CB1438100400C109F1068801F10B200022 +:10FD50000024E0014EF201EAF1064402CACC381058 +:10FD60000400C154F106880120F00024F00BE00FDC +:10FD70004EF201DCD54BF00C5A00FF49F10644026B +:10FD8000CB1438000400C00BF00BC80904040005B4 +:10FD9000F1128801A741B41F8E01D811F106440267 +:10FDA000CACC38000400C032B41FF50B8E01D82E27 +:10FDB00004040005F10A38000600C0288404140376 +:10FDC0000016F00B4E0201B78402001F80201403BE +:10FDD000000F1013007D5A080104480001AFB41F42 +:10FDE0008E01F108B45F42008873F101380081117F +:10FDF0001203003F020300081203002E0203000951 +:10FE00001203002F840012030028040300165A086E +:10FE10000111B4068E01E602E80C00130084840090 +:10FE20003C0BF4555A180106100300843C0BF457A0 +:10FE3000A43612030030A43712030031440000320C +:10FE4000480000BC0003001896164E0200DE045362 +:10FE500000165A58010584003C0BF45600930065C7 +:10FE60008400B43F003300641003004E8009420157 +:10FE70008473F10122430029381081118403FE0CA0 +:10FE80009461E0208401E80584021003004E8400A0 +:10FE9000022300285CF10047E9083C1C00DFC9058B +:10FEA00084031003004E8001027300250413001C1C +:10FEB0005CF1003840109C36E90750F0FFEC5CF72D +:10FEC0008410E80DD5045CF1002EE91C5CF0843848 +:10FED000E91002F300745CF78046E80B3CA3F4578A +:10FEE0008F415CF50031E9042EF7FFFCE802840045 +:10FEF0005CF10049E90750F0FFF65CF78424E90261 +:10FF0000840002F300685CF78032E8095EF2009634 +:10FF1000E8069F0D5CF2042FE90284003C43F4578D +:10FF20005CF20065E90F02F300745CF78046E80AB2 +:10FF30005CF10033E90750F0FFFC5CF78430E90224 +:10FF400084005A58050384008E825CF20030E82C4D +:10FF50005EF08028E80722F3002E5EF78028E90A89 +:10FF6000D5235EF08410E92022F3002E5EF7841082 +:10FF7000E91B4442CA8438420C00C4094442CA8482 +:10FF8000888320420024E089E90284004442CA3C7C +:10FF900038420C00C4094442CA84886420F1802499 +:10FFA000E12FE90284005CF10051E90284003C3356 +:10FFB000F461E267E80684051003004E48FFFA9CEE +:10FFC0005CF1003D0433001BE90B40F19DF75CF749 +:10FFD0008038E9068E2A5CF084254EF2FA8D5A5854 +:10FFE000010448FFFA895A00010448FFFA85041306 +:10FFF0000026140300165A10010448FFFA7D10036E +:020000021000EC +:10000000005648FFFA79A43612030030A4371203D1 +:10001000003148FFFA71441000FCF20442200473DE +:10002000B0F18481B168F0034C01003DF003B400ED +:100030008E01E603E832F003020000345CF000C8F1 +:10004000E9039600D503440000C7F10304108016AD +:100050005A1002045A180507F60302630025E20647 +:10006000E9035A18041BF003041400050000001CE7 +:1000700094028801A642A783E2C1E90FF0030400BD +:10008000000F5A08010538009408D5055A080204E3 +:1000900038408C088C21D5F1F003500000FCF0832F +:1000A000D5C384004412CD184422CA848068B12884 +:1000B000F50149FFF7EEF0114412CC844422CA3C0A +:1000C0008068B131F50149FFF7E43C03F4623C1369 +:1000D000F45FE201E8048C013C0BF4623C03F4574A +:1000E000C8063C13F463C1033C0BF4623C0BF4639D +:1000F000FCDDB41F4492CC848E01F086B01FF088E2 +:100100004402CACCF0828401F08548FFF97B0003E9 +:10011000001100130023E0204EF3F9A2F2088461DD +:10012000383100088C01D5F884041403001648FF08 +:10013000FE6E840148FFFE4B840048FFFE544420BD +:1001400000FC420088738421141000261010009EC9 +:10015000842014100023DD9EFC4AF08B2E07C5423C +:100160008141F0812E07C543F287F08A3C03E2AA61 +:100170003C13E2A9F08D3C03F4545CF00190E804D8 +:100180008C013C0BF4543C03F4535CF00190E80404 +:100190008C013C0BF4533C03F4525CF00190E804F6 +:1001A0008C013C0BF4523C03F4515CF00190E804E8 +:1001B0008C013C0BF4513C03F4505CF00190E804DA +:1001C0008C013C0BF4503C03F44F5CF00190E804CC +:1001D0008C013C0BF44F4000840AF08EF00DF60BBE +:1001E0009001F0918400F0842E07C549F104E220CB +:1001F0004EF204BFB4064E0204B55A080504480086 +:1002000004B15A0804044800041D0003001C04152E +:100210000004F08894018801A641A600F192F093B1 +:1002200004030023C809F00804150005940288019E +:10023000A602C00FD5035A000111F00A4412CB5C8C +:100240008E01F082F00A8E02F08C841FF086D50BAE +:100250008421F186F18CD504F086F08C8400F08244 +:100260004412CBF0F0089402F090F210040500055F +:100270008802F20AA6C28E41A743CB04DA048103A6 +:10028000D541DA3FA680A6C1F401F002FF04E26284 +:10029000E938B4AA9814380281005A00FF1C0455AA +:1002A000000138528101980AA6015A00FF14F7088C +:1002B000DF1198885000003494010031005B880100 +:1002C00000710037F38900910049A503CF05F78538 +:1002D000D5058C41D5DD9E39F085F0018E02E2090D +:1002E000E805F00150807FFFD5035084800180072E +:1002F0008029F202F30784A149FFF74DF083D50A64 +:1003000085008401148F8005F083812880E8148F94 +:100310008009F001F1029401F30742300473F10CFB +:10032000F407844042400473F28CF005E100E90FC9 +:10033000381181114E170005F50C88A1F58C381283 +:1003400001114E17000388418C01D5F1F005842777 +:1003500040040001FE0342200473F28F4E26000485 +:100360008401F08FF00BF10449FFF414001300181E +:100370000403002396464E1200CB3C13F45B121389 +:100380000056C02384011203004E84031403002688 +:1003900084001003009EC705F0018E014C904005BB +:1003A0008C2A12130056000F8024F102F201100370 +:1003B00000A6F00942008873F1073800811112038A +:1003C0000054020F8006D50C441001901213004E09 +:1003D0008421141300261013009E120300543C3392 +:1003E000F4583C43F4542213000912030052E2640F +:1003F00084001413002C12030050100300A21003F9 +:1004000000B4100300B5100300B6100300B7E902F2 +:100410008401100300AA3C03F453E2608401E80263 +:100420008400100300AB8401100300C43C03F46794 +:10043000C82F2E30043F5A38012C3C0C00DF5A08DC +:1004400002135EF08096E82422F300085EF780969F +:10045000E81F8486144300262E47E8ECC4191433A1 +:100460000023D5145A0801155EF08096E81122F396 +:1004700000085EF783A3E90C8466143300262E3748 +:10048000E8ECC306140300238403140300253C0393 +:10049000F465C8312E00043F5A08012E3C0C00DFE1 +:1004A0005A0802145EF088CBE92622F300085EF7B2 +:1004B0008096E8218426141300262E17E8ECC11B31 +:1004C000140300238404D5155A0801165EF088CB66 +:1004D000E91222F300085EF783A3E90D84061403F2 +:1004E00000262E07E8ECC0078402140300238405CD +:1004F00014030025804AF108A01538000600F11009 +:10050000100300C8A0158801A601D556C023C70551 +:10051000F0018E014C9040073C03F45B8C0A1203FF +:100520000056F102F201000300A642008873F107B1 +:100530003800811122130054E020E8031203005414 +:1005400002030052F103E201E805020F80061203E4 +:1005500000520203004E5CF00190E80B8C01041382 +:10056000002C1203004E2203000988011403002C02 +:100570003C03F4583C13F454E201E90484211013C1 +:1005800000AA3C13F453E201E9048401100300AB18 +:10059000804AF108A01538100600000300C8880141 +:1005A0009001100300C8F110A0158801A6410003B6 +:1005B00000C9880190013C9C00DF100300C9507401 +:1005C000FFFFE6E2E913440001901203004E04131A +:1005D000002684011003009E841DFE0E5A080107A8 +:1005E000140300268400140300238400E6E21003B1 +:1005F0000048E83204130023C12F5A180108840070 +:100600005A98010E843F8402D50A5A1802075A9854 +:100610000105843F8403D503842180014422CA302C +:1006200038310000C3198802F31220400008FECCC4 +:10063000FE64E023E911F206F11320000004FE54E9 +:10064000FE14E001E909020300525CF00029E9040C +:1006500084011003004800030048C863040300231A +:10066000C0600403000C5A00025D0213004EE62B2A +:10067000E958040300265A08030704330025E662FC +:10068000E823D5035A080221A4F78E705CF1894C47 +:10069000E81B023300525CF1804CE8160003005561 +:1006A0005A08013C0003009EC838001300F3E622FC +:1006B000E9328422100300CB4400003210130054AE +:1006C00012030066D52A8E02E602E82BA4378E10AC +:1006D0005CF0094CE8263C03F45DE201E9220403E6 +:1006E00000255A00020A5A0004085A9002085A00CB +:1006F00003195A0005175A980115020300525CF0BD +:10070000004CE80F000300555A0801080003009E42 +:10071000C804840210030054F00BF10449FFFD11DA +:1007200000030048C85F04130023C15C0403000CED +:100730005A000259040300265A0006058E02E602FA +:10074000E8515A180105000300AAD5055A18024BB2 +:10075000000300ABC8472213002E220300089A08AA +:100760004E040003FE022E37C57244100032FE5CB8 +:100770000233005244F003E8FE5C4010BC37E22034 +:10078000E8315CF00029E92E001300A6F202F40122 +:10079000806142311073F207848238F10D112233E7 +:1007A000005440319076E06FE809F205E022E90359 +:1007B000E101E8185CF0012DE915000300555A0825 +:1007C000010E0003009EC80A8422100300CB4400DF +:1007D00000961013005412030066F00BF10449FF59 +:1007E000FCB004130023040300264E1200E35A0059 +:1007F0000304480000FE0233004E02030056E203E9 +:100800004EF300AD04330024CB0B000300A28C0197 +:10081000100300A2000300B58C01100300B5F20C18 +:10082000840AFE848002F20F400008165EF001C3C5 +:10083000E808F203445057E442F00824E2AFE80B22 +:10084000004300A28C81104300A2004300B78C81BA +:10085000104300B7004300485A480114005300A257 +:10086000E6628CA1105300A2005300B68CA1105375 +:1008700000B6E909021300508C2112130050D52D47 +:10088000E662E82B5A1801155A98010722F300086E +:10089000F10EE02FD5075A98021F22130008F20E1E +:1008A000E022E90F22130009E42BE815D50A5A18B3 +:1008B0000213F10D2233000950F0FFF5E06FE90B50 +:1008C000021300508C2112130050001300B48C212D +:1008D000101300B45A4001D05EF00029E806F2037C +:1008E000FE845CF107D1E906020300508C0112037B +:1008F0000050020300525CF0004CE908E6E2E80612 +:10090000020300508C0112030050040300205CF02D +:100910000065E908E6E2E80F020300508C011203CB +:1009200000505A980209040300255A0002105A0880 +:100930000460D5075A98015D040300255A0805058F +:100940003C03F464D5055A0803543C03F4663C1395 +:10095000F459E2208406E82AD54B0403002C400019 +:100960000C165A180208F10D50F0FFF5E00FE81DC3 +:10097000D5155A18011B5A98010722F30008F10EE9 +:10098000E02FD5075A98021222130008F20EE02237 +:10099000E803E41FD502E40BE9080203005000134A +:1009A00000B48A0112030050840214030026D520EB +:1009B0000413000C5A10021D9E42E622E9048E0523 +:1009C000E602E816000300555A08010E0003009ED7 +:1009D000C80A8422100300CB440000961013005470 +:1009E000120300668401140300261003009E040312 +:1009F00000265A080123040300165A08011FB406F2 +:100A00008E01E602E81AF01122F30009001300C477 +:100A1000E00F8400E90A3C0BF4545A18010F10034C +:100A200000C43C0BF452D5093C0BF4535A18010690 +:100A3000100300C43C0BF450440000324800008313 +:100A40000003001896164E02008D042300265A2833 +:100A5000010EF01122F30009E00F8400E9043C0BC1 +:100A6000F451D5063C0BF44FD5035A2006078400F9 +:100A7000100300AE8421D5058401100300AE84204C +:100A800000330064F4010003006542019073F30732 +:100A900038F18111220300298463940140000C166F +:100AA000E00FE8058402100300AE842002430052E8 +:100AB0000233004E0403002C5CF2004C40000C1684 +:100AC000E90F3C4C00DF8E81E682E80A50F07FD8C7 +:100AD0005CF7891CE9088423101300AE84205EF0C3 +:100AE0007FFCE90CF40D8C83E080E908004300A250 +:100AF000005300B58A85104300A23C43F460E283B2 +:100B0000E903E662E8058425101300AE842004336F +:100B100000205CF18065E9193C3C00DF8E61E662F3 +:100B2000E814003300A6004300C8E264E90500436E +:100B300000C9E283E80A50F07FD85CF7891CE90518 +:100B40008406100300AED50D5A20010C5A18010A74 +:100B500004030016141300265A080104101300564B +:100B6000F004506300FC8C01F08448FFFB3F3C1311 +:100B7000F454C9063C03F467C0033C1BF4663C0311 +:100B8000F4663C23F459E240E9048C013C0BF46622 +:100B90003C1BF4673C13F453C9063C03F465C003E3 +:100BA0003C1BF4643C03F464E240E9048C013C0B1C +:100BB000F4643C1BF465FCCA442000FC42008873CA +:100BC000041000265A1806243C1C00DF5A18011095 +:100BD0000210000950F0FF6A5CF78835E91822100E +:100BE0000008440003A240000407DD9E5A180210CA +:100BF0000210000950F0FF6A5CF78835E90822000E +:100C000000085EF00096540780FFDD9E8400DD9EA4 +:100C1000442000FC420088733C33F4752220000815 +:100C20008020E062E90822F000093C43F474840269 +:100C3000E08FE80C52F1843FE04FE90E224080093A +:100C40003C03F474E004E914840314008025840157 +:100C500014008023DD9EE062E9193C03F474222035 +:100C6000800952F0096BE04F8404E910D508E06276 +:100C7000E8F552F0096BE08FE9098405140080253E +:100C80008402140080238401DD9E8400DD9E4420C4 +:100C900000FC4200887304100023C10A5A18010B9B +:100CA000222000095EF17FFCE90EE45FE912842254 +:100CB000D5105A1802113C23E2AA223000099D13D4 +:100CC000E083E8038420D5058E5FE062E902842199 +:100CD00014100024DD9EFC4184C0F08181215070FD +:100CE000008C814685022E07C549E2C0E85C0013EE +:100CF000FF8C0403FFDD9646C129C028F001802641 +:100D000049FFFF88C818F001802649FFF2E9040373 +:100D1000FFE40414800594028801A642A603C906D4 +:100D20005A0023098401B607D5065A082304B707D9 +:100D3000D502B7472FC7E8EC4FC3002EF00180263D +:100D400049FFF2CE15C38000D5268E01E603E827C1 +:100D5000F001802649FFFF5E5A00011AF00180264B +:100D600049FFFF2C8380C813F001802649FFF2B8A9 +:100D70000423FFE40404800594928840A612C0076F +:100D8000A6135CF00023E80315C380002E07E8ECEF +:100D9000C802B607F001802649FFFF7B8CC1507363 +:100DA00080FCD5A2FCC1FC20442000FC42008873DA +:100DB0000470000F80C0CF05840314030010D52EEB +:100DC0005A78010E220000085EF07FF3E912E40B6E +:100DD000E91C5EF000298402E91CD51A5A78021C2D +:100DE0003C03E2A9221300085020000CE041E80374 +:100DF0008400D50F50F07FF5E02FE9038401D50979 +:100E000050F07FD7E02FE90414730010D504840359 +:100E1000140300103C0C00DFC0038400D50E5A7888 +:100E200001105003001044100064442000C8846383 +:100E300049FFF2264003801B14030011D50B5A789A +:100E4000020A5003001044100064442000C8846467 +:100E5000D5F0FCA0FC41F08183812E07C542F10151 +:100E600085205060803C80E9810950A07FFF2E07DB +:100E7000C549E320E84500137FDC04037FF1964673 +:100E8000C113C01204037FF8B90594028801A6407B +:100E9000A741C90584014C554006D5234C55402235 +:100EA0008402B606D5218E01E603E826B4065A0868 +:100EB000010D04037FF8B90594028801A640C91109 +:100EC000A7414C554012D50D5A08020F04037FF874 +:100ED000B90594028801A640C104A7414C550005FC +:100EE0008CE1B70697F82E07E8ECC802B606F001C9 +:100EF000802949FFFF5A8D21506300FCD5B9800736 +:100F0000FCC13A6FA6BCEFF880C080E2501F80069B +:100F1000B400FA40846349FF84C7020F8003A470C1 +:100F2000B6073C0DFAA844928F70FA4002000011F7 +:100F300084648A010014800F92014000043710136A +:100F40008010B406501F800649FF84AE020F800354 +:100F5000A470A8393C0DFAA83C3DFA9284810200A5 +:100F600000118A010014800F920140000437101311 +:100F70008011B406A072A0B60031800C49FF84CF66 +:100F8000EC083A6FA684DD9E3A6FA8BCEFD880E1EA +:100F900081445A480404A006D502A005001100109F +:100FA000509F801C84C0443000320051000F808369 +:100FB000B63FF6818020F682F683149F8004844534 +:100FC00049FFBC7B020F800E02148003AC38020480 +:100FD0008001AC7AAC3922048002AC3B5AA0040BED +:100FE0003C13E6343E67E951E001E80484013E0722 +:100FF000E951EC283A6FA884DD9E3A6FAABCEF5CF9 +:1010000081238460814081013E37E95149FFFF7BA4 +:101010008400003480028020B118B16044607FFFFA +:101020009680E243E80AB0903812010938110109AC +:10103000386281098C01D5F50044800344000080AA +:10104000F0830405000684C084E194598E818820D1 +:10105000B67FF382442232E8972080A7F781F68496 +:10106000F685F686F787F688F689F68A49FF847D45 +:1010700000348002440FFFE2F088FA0E004480033F +:10108000B67FF089501F803E04050006042500113C +:1010900080A7F681F682F683F684F685F786F687D2 +:1010A000F68A126F801F49FF846000448003003479 +:1010B000800244000080F0838E81440232E8804048 +:1010C000B67F501F803E972080A7F681F682F68477 +:1010D000F685F686F687F688F689F68A127F801FEF +:1010E00049FF84430044800300348002FA00F08802 +:1010F0008E81440232E88040B67F501F803E9720A8 +:1011000080A7F681F682F683F684F685F786F68761 +:10111000F689F68A126F801F49FF842700448003F6 +:10112000840800348002F087040500118E8180401D +:10113000B67FF382441232E8972080A7F781F683C6 +:10114000F684F685F686F688F689F68A49FF840DD8 +:101150000044800300348002B05084058E818041B9 +:10116000B67FF08897200405001180A7F781F682EA +:10117000F683F684F685F686F687F689F78A49FFC0 +:1011800083F4004480030034800244000080B0589F +:10119000F0838E81841B8041B67FF08997200405FF +:1011A000001180A7F781F682F684F685F686F68729 +:1011B000F688F78A49FF83D9003480028404F087D7 +:1011C000B020804000448003F3820415000680A70D +:1011D000B6DFF781F683F684F685F686F688F6891B +:1011E000F68A49FF83C2003480028411F088440FDC +:1011F000FC1800448003B67FF089501F803E040530 +:101200000006442232E880A7F681F682F683F6844F +:10121000F685F686F687F68A126F801F49FF83A54A +:101220003C0DFAA80044800280460250000E8E81D8 +:10123000976B802683C680068066E0E4E81CB19048 +:1012400038F31D015CF78012E9068C618C0196D998 +:1012500096018441B19838F31D015EF78012E908C8 +:10126000506F00018C2141E30013964984418CE1C9 +:1012700097F8D5E43E20041F84403E200421222F0D +:101280008040E450E909022F8020E64CE9058C01FA +:1012900096018441D5028440B1E038739111E4F0A5 +:1012A000E90AB19038731101E6ECE9058C418C0133 +:1012B00096919601027F8030E6EC84E0E9048C216F +:1012C000964984E1B19838431101E68CE9088C21F4 +:1012D0009649C20B8CE197F9CB04D507C205C3042C +:1012E00084413E200421C7064FE2000584413E2090 +:1012F0000421E630E803E610E90584013E000420FD +:10130000D50484003E000420800A8028804984603F +:101310008484F58D49FFFE3A22F40002F50D5EF754 +:101320008065E90484013E0004212E07E9205A0863 +:1013300001072214000344025198AC405EF280651C +:10134000E90484013E07E9152E07E9155A0801074B +:10135000E4BEE80484003E07E91522F400035EF7CA +:1013600080DCE80484013E07E95144007FA6120FA7 +:10137000801F02040000C83902040001C0362E0795 +:10138000E94E04350006C81E9481884322FF801F61 +:10139000A450964BE02FE806A4503C0BF4ED121F2E +:1013A000801F8C015A0A40F23C03F4ED94019858D6 +:1013B000A40896035EF07FC9E81D84013E07E94E4C +:1013C000D5193C13F4ED94498823A448964B5EF05C +:1013D000FFC9E80B8C019600E60B3E07E94EE90ACF +:1013E00084013E07E93CD50684003E07E94E3E07EE +:1013F000E93CECA43A6FAA84DD9E2E57E9153A6FBA +:101400009C3C97205A5001062E60041F5A68010820 +:10141000E642E9035A282304444000873831851105 +:101420008803E004E9115A5001062E00041F5A08EF +:10143000010FE642E80C949488224402D47C3800E0 +:101440000511E004E80444008000D50284003A6FEE +:101450009C04DD9E3C1C00E02E07E956A68EC816B3 +:101460002E07C5DC5A0801139411AE0AA6098E0195 +:10147000FE148442400008168E01940196033C0B32 +:10148000F4CEFE033C0BF4CDD50FA609AE8A8E0137 +:10149000FE148442400008168E0196033C0BF4CEE5 +:1014A000FE033C0BF4CD2E0004215A08010D3C0331 +:1014B000F4CE94033C0BF4CE3C03F4CD94033C0BEC +:1014C000F4CDD527C8262E07E91A5A080123A60A03 +:1014D0009401AE0A2E07E9705A08010E3C23F4CE9F +:1014E0008406FE843C2BF4CE3C23F4CDFE143C0B4E +:1014F000F4CDD50F2E07E9245A08010C3C03F4CE95 +:1015000094013C0BF4CE3C03F4CD94013C0BF4CDA0 +:10151000A6093E07E90D8C013E07E90EDD9E22205B +:101520000000223000013A6FAABCEFAC9AD3B1811F +:101530004E340003FEDAACF04637FFFF50318FFF28 +:101540005090FFFF882394C938500511984322100A +:10155000FFFF9A694E140003FE4A3CA7F4CE970B96 +:10156000E142384325093C87F4CD3C7C00E0E909A1 +:10157000E048E90722F30000A6FA8421E06FE803BF +:1015800084408022E145E90AE0A8E908A6FAE0647F +:10159000E90588458C219693964B9CC2878140FE35 +:1015A0002406E8262A0180012241800041E0100142 +:1015B0004FE4000453EF00002251FFFE9B054E4410 +:1015C0000003FF22E09E404F3C1BE140384371097D +:1015D000E90CE008E90AA77A40F20011E0AFE9055A +:1015E00088409C099693964351CE0001D5D9A63CDC +:1015F000E0018400E804400104169603EC543A6FBD +:10160000AA84DD9E3A6FA8BC51FFFAF0812080E1E8 +:10161000A006803F49FFBA2D3CAC00E084C00085A5 +:1016200000050005000BE2C0E8252E07C543802811 +:10163000FE349401881F49FFFF7494718827AC0819 +:101640008400E208E8152E27C54280664231007307 +:1016500004448006969904348005949188628844F5 +:101660008C01A490A5088A449693AC98D5EB8CC1C4 +:10167000D5D951FF85103A6FA884DD9E3BFFFCBC95 +:10168000EFF4B61FF18149FFFEE7B41FF101EC0C46 +:101690003BFFFC8448FFFFB8FC005A0806048401A5 +:1016A000D5045A08070684003E07E921D51C5A08CC +:1016B0000D0784003E07E9218421D5075A080E0B47 +:1016C00084013E07E92184203E17E95F3E07E94F88 +:1016D000D50A5A0810048401D5045A08110584005B +:1016E0003E07E920FC804433F04A444000553C2D3D +:1016F000FAB6A690CA03AF18D5FB3C2C00EB10013C +:101700000053C904440FFFA0D503440FFFA11001EB +:1017100000512E07E9715A080305440FFFB1D503A4 +:10172000440FFFB010010052443000554423F04AEA +:101730003C0C00EB001000515A10BB04AED0D5F9A0 +:1017400084201010005110100052DD9E4413F04A06 +:10175000442000553C0C00EB000000515A08A00446 +:10176000AE88D5F9DD9E4413F04A442000553C0C68 +:1017700000EB000000515A08A004AE88D5F9FC0027 +:101780005A08BB0449FF7CBB2E0004325A08A0054E +:1017900044024000D5085A08A10544021B90D50315 +:1017A00044020C604412451049FF80153C0C00EBCC +:1017B000441FFFA010100051FC803C1C00EB1000E7 +:1017C0008060DD9E3C0C00EB00000060DD9E3C1C58 +:1017D00000EB100080613C1DFA361000803EDD9E5B +:1017E0003C1C00EB0000805050007FDFE602E90463 +:1017F000840010008050DD9EFC003C0C00EB441F78 +:10180000FFCC44200055101000514413F04A3C0C0A +:1018100000EB000000515A00BB04AE88D5F944002B +:10182000007849FF790084003C0FFABFFC808421D6 +:101830003E17E9313C1C00EB8801002000523C2B94 +:10184000F4E7001000534010A00888223C1BF4E786 +:10185000001000543C1BF4E5000000554000200837 +:1018600088013C0BF4E5DD9E3C1C00EB84003C0B46 +:10187000F4DE00208052840AFE143C0BF4DD0000EC +:1018800080515A08AB07FC00840249FFFFD2FC805C +:10189000DD9EFC0080C049FFFF0184015A680305FA +:1018A00049FFA38A800650137FF3E622E9035A68B2 +:1018B00002213C0DFA9AA7815A6003185A680A0B54 +:1018C0008429AE41842049FF816F3C0DFA9AAF8193 +:1018D000D504842049FF816849FF7CEC5A08020640 +:1018E0003C0DFA9A8423AE4184013E0004618402D7 +:1018F000FC804000040E9606DD9EFC003C0C00EBD4 +:10190000441FFFAA101000513C0C00EB00000051D6 +:101910005A08AA074400007849FF7885D5F65A008E +:10192000DD048401D5028403FC800000FC01840AEC +:10193000100F80075A1001065A10020B4800008150 +:101940003C0C00EB8420101000514800007F3C3C10 +:1019500000EB000180528E05E6054EF2006D44F169 +:10196000186C3807800040F03C00DD0F06266A8ABC +:10197000B60084023E07C66E3C1DFA9A8404844079 +:101980004432B39049FFA4EA3C07F4EA49FFB0614E +:10199000D53C8400804084C03C1DFA9A4432B39008 +:1019A0003E67C66E3E67E94F49FFA4D83C07F4F195 +:1019B00049FFABE82E07E97144128F704422B37FD0 +:1019C000503F80073C4C00EB49FFAB913C0C00EBD7 +:1019D00010600052D53A84013E07C66E84008040F4 +:1019E0003C1DFA9A4432B39049FFA4B83C07E32166 +:1019F00049FFABC8D50A84033E07C66E0001805379 +:101A000044128F7049FFAB022E07E97144128F70A8 +:101A10004422B37F503F80073C4C00EB49FFAB674B +:101A2000D51444029072802349FFA7E58401100F6A +:101A30008007D50B8401100F8007AE50D5068401B6 +:101A4000100F80078402AE10000F80075A080A0D9D +:101A500049FFFF553C1DFAB6100F80078401AE0800 +:101A60003C1DFAABAE08000F8007FC815A0001084C +:101A70005A08030BB40158000004D504B441841B78 +:101A8000FE16B601DD9E8402AE10DD9EFC409F0175 +:101A9000E68B4EF2007C800144F119A83847900093 +:101AA00040F23C004A003C00E80C107EB0B6E2BEBA +:101AB000CCDADE008407D56E4473F04A44900055BA +:101AC00049FFE78D80C05A00020510938000D5F9C8 +:101AD000840149FFE79749FFE7563C0E033249FF6F +:101AE000E75C3C0E033349FFE76A3E000CD149FF37 +:101AF000E7723E000CD049FFE7683E000CD284211B +:101B00004402D6F849FFB8BB800649FFE77B44632F +:101B1000F04A4470005549FFE762C003AFF0D5FCBE +:101B200049FFE770D5183C2C00EB842EAE4184268B +:101B3000AE408420101100504423F010AE50842198 +:101B400049FF80328420840280418461808180A1A9 +:101B500049FF7C108401D51E8401AE10D51184018B +:101B6000AE10840ED5178401AE10840149FFA23750 +:101B70008402D5108401AE10840049FFA230840D88 +:101B8000D509FA00D507FA01D5058402AE18D5E3C8 +:101B90008406FCC0FC005A000142C0055A000254F1 +:101BA00048000087C915FA043C0BF47B4400003C54 +:101BB0003C0BF47A840F3C0BF479FA38FA0E3C0BA8 +:101BC000F4783E07C9823E17C9838401D5245A1888 +:101BD0000115840F3C0BF47B84083C0BF47A3C0B1E +:101BE000F479FA0E3C0BF478FA043E07C9833E07F9 +:101BF000C9823E17C96FD55C5A18025B84083C0B3A +:101C0000F47B84053C0BF47A3C0BF479FA0E3C0B24 +:101C1000F47884003E07C96FD54BC10A5A180107F2 +:101C20003E17E9123E17E921D5435A1802053E171F +:101C3000E912D5065A18033D84003E07E9123E0713 +:101C4000E921D536C9083E17E8EC3C1BF4753C1B6E +:101C5000F474D5225A18010D440000643E17E8ECD4 +:101C60003C0BF4753C0BF4743E10043FD5155A1828 +:101C700002073E17E8EC440000AAD5075A18030DE6 +:101C80003E17E8EC440000FA3C0BF4753C0BF4748E +:101C900084013E00043F2E00043F5A08010A44001C +:101CA0000E103C13F47D49FF7ECD3C0BE4D6FC8046 +:101CB000FC00E605E84344F11BC43807800040F00F +:101CC0003C00DD0F0620405A6A00B462964F400087 +:101CD000A008441FFCFFFE5EFE47B622B42284002B +:101CE0009228D50DB462964F4000A808441FF3FF18 +:101CF000FE5EFE47B622B4228401922A964F49FF27 +:101D0000FF4BD51EB462964F4000B008441FCFFF72 +:101D1000FE5EFE47B622B4228402922CD5F0B402B5 +:101D200058004000B60284003E00043BD509B422AE +:101D3000440FBFFFFE0EB602D5038402AE18FC802E +:101D4000FC00FA043C0BF47B4400003C44628F70BE +:101D50003C0BF47A840F3C0BF479FA38FA0E10132A +:101D60000443100304423C0BF478842284011003E2 +:101D7000042F3E17E8EC8400441000AA3E07E91245 +:101D80003E07E9213C1BF4753C1BF4743E00043F04 +:101D90003C13F47D4400016849FF7E54120302366F +:101DA000FC80FC4080C18420AE40B40280E29211ED +:101DB000960681245A080107B42644020000FE0F4B +:101DC000B606B40792119606C806B426440DFFFF66 +:101DD000FE0EB606B407920196065A080109B4062B +:101DE00058000002B606800649FFBBBBB40792014B +:101DF0009606C80CB426841DFE0EB60649FFE2A95D +:101E00003E000439800649FFBBACB40796065A0869 +:101E10000106B40658000001B606B4079606C805C8 +:101E2000B426841EFE0EB606B407920296065A0821 +:101E30000106B40658000004B606B40792029606DE +:101E4000C805B426841BFE0EB606B4079203960698 +:101E50005A080106B40658000008B606B4079203F3 +:101E60009606C805B4268417FE0EB606B40792047B +:101E700096065A080106B40658000010B606B407C4 +:101E800092049606C806B426440FFFEFFE0EB6066F +:101E9000B40792059606C806B426440FFFDFFE0E6F +:101EA000B606B407920596065A080106B40658000D +:101EB0000020B606B40792069606C808B426440F5A +:101EC000FFBFFE0EB60649FFFF3DB4079206960619 +:101ED0005A080106B40658000040B6060004800007 +:101EE00092075A08011600048000963710048000FB +:101EF000B42784009228964F49FFFE4EB407B4469B +:101F000054100300440FFCFFFE16FE0FB60600043B +:101F1000800196065A08011600148001541080FEB4 +:101F200010148001B427922A964F49FFFE35B4075A +:101F3000B44654100C00440FF3FFFE16FE0FB60615 +:101F400000048001920196065A08011700048001DE +:101F5000540000FD10048001B4278402922C964F97 +:101F600049FFFE1AB407B44654103000440FCFFFA7 +:101F7000FE16FE0FB606B407920E96065A08010921 +:101F8000B40658004000B60684003E00043BB40787 +:101F9000920E9606C806B426440FBFFFFE0EB60684 +:101FA000FCC05A000B135A000C1A5A080A21FC00F4 +:101FB000B441440FFFBFFE16B601B4015800002023 +:101FC000B60149FFFEBFFC80B40158000040B601D5 +:101FD000B441440FFFDFFE16D508B401580000409D +:101FE000B601B40158000020B601DD9E8402AE1097 +:101FF000DD9E0000FC42A7493C6C00EB5A580411DE +:102000002E07E9815A00010D00030050540000F032 +:102010005A001007440000553E07E979D51F000318 +:102020000050F4818123B65F80E1C0035A08FB1A97 +:102030002E000432C00784003E000432840049FFB1 +:1020400078C7B41F4412B36B49FF7AF544000055BA +:102050003E07E97984003E07E96784014800021CD5 +:102060005A50010949FF79265A080205840149FF9F +:10207000B8A1B41F4412B36B49FF7AA984003E078C +:10208000E97C3C0C00EB00600050008000518401B2 +:10209000100F800F84003C0FFAC8A67940A31009E6 +:1020A000979F5A1804212E17E9295A1801063C0F48 +:1020B000FAD749FFAD6F840149FFB86B84208007D0 +:1020C00049FF7D72840149FF9E704403F04A441029 +:1020D0000055AE4049FF9E4FC0FE4402D3FC49FF6D +:1020E00079D0D527A6785A10010A4403F04A441043 +:1020F0000055AE403C0DFAB6D5103C0FFAD744035C +:10210000F04A44100055AE403C0DFAD7C8EF49FFE5 +:1021100078D15A0002FBD5EAA640C1FFA6005A00BA +:1021200002093C0DFAABA6405A1802048420AE40C6 +:102130008F41E74B4EF2018C44F1204838A7A901AA +:1021400040F53C004A003C0016005A006801860138 +:10215000B602C402D602040304030403E6024402E6 +:10216000B3414412B3E449FF7A75B41F4412B36B10 +:1021700049FF7A2D80068028804749FFB1458400B9 +:10218000100F800F5A600F04480001393C0C00EB1F +:1021900084CC000000505A00FB0448000162480053 +:1021A000012E8EC18401E6C63E07E97C4EF2007D19 +:1021B00044F120C03867980040F33C004A003C00DE +:1021C000062442B2BE4C8400100F800F84013E07EB +:1021D000E9672E07E9214E03013F841F3C0E0111E0 +:1021E0004800013A8400100F800F84013E07E96720 +:1021F0002E07E9214E030132841F3C0E01114800D5 +:10220000012D3E07E96784C24800012B8400100FAE +:10221000800F84013E07E9673C0C00EB0010005280 +:102220005A18AA2000100053440FFFA0FE0F3E00D2 +:10223000043249FF7764840149FF77CA3C0C00EB04 +:10224000000000525A08AA0544004510D503440076 +:10225000475049FF77503C0C00EB8420101000528F +:102260002E07E9214E0300FC841F3C0E011148009B +:1022700000F74400006949FF779B480000C03C1C00 +:1022800000EB8400100F800F84013E07E967000017 +:102290008055001080544000200888013C0BF4DC7D +:1022A000FAC2480000DE84003E07E97C480000D006 +:1022B00084023E07E90580268401502F800F49FFE4 +:1022C000FB3780C084053E07E905480000CA84004A +:1022D0002E17E919100F800F84013E07E97C5A1868 +:1022E000010584C9480000BD3E07E9193E07E9051C +:1022F0009E31E60CE87144F122043807800040F07A +:102300003C00DD0F0CD24AD24AD294D2BAD21C146D +:1023100084013E07E966D56384013E07E94CD55F39 +:10232000840184C03E07E9873E67E92149FFFA9EA0 +:102330003C1DFA9D3E600454B40158000010B601E3 +:102340003C0DFAB8580000103C0FFAB8D5483C0CC8 +:1023500000EB8026502F800F0000005149FFDE8ED9 +:10236000000F800F5A00023C3C2C00EB000100558E +:10237000003100544000200800110052880344310D +:102380000000FEC70001005180463E17E93E3C3F79 +:10239000FAAA49FFDE87D5233C0C00EB8427502F97 +:1023A000800F0000005149FFDE69000F800F5A00C6 +:1023B000021784013E07E95C49FFFA58D5103C1C1E +:1023C00000EB8401100F800F001080523E07E97B64 +:1023D0003E17E965D5048402100F800F000F800FAF +:1023E0005A00020448FFFF7F3C1C00EB84003E07BC +:1023F000E97C3E07E9191000805184C1D53180067F +:102400008029502F800F49FFFB33D518FD0344224C +:10241000B3AC503F800F49FFFB3B9780D52180062E +:1024200080288049503F800F49FFFC44D507800633 +:102430008029502F800F49FFFDB6000F800F5A00F2 +:1024400002DEF101B40984CBB601D50A8402100F73 +:10245000800FD5D484C4D50484C5D502FAC9000F31 +:10246000800F84205A0001055A080207843B3C0C67 +:1024700000EB101000502E07E97CC80C4402B34159 +:102480004412B3E449FF78E6B41F4412B36B49FF2A +:1024900078D28006FCC292005A08073CE625E8651F +:1024A00044F123B03817840040F0BC004A003C00DF +:1024B000061E3A505800A660440FFF80FE0FAE2063 +:1024C000968F40012008441FFCFFB443D50BA62182 +:1024D000968F58000001AE21441FF3FF40012808E9 +:1024E000B443FE8EFE87B643DD9EA621968F58002C +:1024F0000002AE21441FCFFF40013008B443D5F2A3 +:10250000B40358004000D52FB423440FBFFFD52A91 +:102510005A080B1D5A100B0B5A100C115A180A2688 +:10252000B423440FFFBFFE0ED50CB4035800004087 +:10253000B603B423440FFFDFD515B40358000040A1 +:10254000B603B40358000020D50E5A0805135A10DC +:1025500001085A18030BB40358000004D504B4232F +:10256000841BFE0EB603DD9E44022D50843BAE401C +:10257000DD9E9200FC42814144122D50F081F28296 +:10258000F383A608A78844122D519204A7C8979FE9 +:1025900097F85A0801249E31E602E90F5A600304B5 +:1025A0005A6805403C0C00EB000000605A00A10690 +:1025B0002E0004585A0001364402B3414412B3E4D9 +:1025C00049FF78484402B3644412B36B49FF77FF74 +:1025D000FD03F20149FFAF18D5245A000B06541031 +:1025E000000D5A18051F2E27E9699E54E622E804BB +:1025F0003E200430D50484203E10043044922D50F7 +:1026000084201014800080478026F302F40349FFE1 +:10261000FF45000480005A00FB05840110050000FE +:10262000FCC244522DA0443DD2604422E16C4402DD +:102630002DDC986B381104011A128001D8FBDD9E45 +:102640003C0E00EF84003E07E910DD9EFC203C3C80 +:1026500000EF8400444000FC84A24462CFB884E1CF +:1026600000218009E202E80A8041422010731051E3 +:1026700000DE387300088C01D5F4FCA03C4C0278D5 +:102680004402D79484604452CFB8041000168E22BE +:10269000E622E910041000268E22E622E90B001043 +:1026A00000DE5A18010538128C00C104B4205A18F3 +:1026B000030D0010006600200067944C88229449A6 +:1026C0008824A448121000738C61500000FC5A3812 +:1026D0000ADEDD9EFC203C6C00FF84E1A772A7B3FC +:1026E000C20284FFC9089E69FF4442510473B6A325 +:1026F00088A7D50B9E71FE8C8020421114738847E9 +:1027000042011473B62380A0B6A4FCA0FC4484C08C +:10271000810583808141F282F38180E480A3812658 +:10272000E2E5E9148005F110F202B0C4B105F583C9 +:1027300049FFFFD2F004F503380E01118CA1892066 +:10274000F005380E011188C0D5ECF00180468AE012 +:10275000FFFB8405422380734E26000384418029B9 +:10276000800A49FFC847001400005A10FF058C2159 +:102770008801920110040000B046B08749FFC8A547 +:10278000F00638150111F0073825011184024000C8 +:1027900080164204887340000416FCC4FC4780E1A4 +:1027A0003C1C00FFF284506000200020803200803A +:1027B0008002F287002080338400F2882020803954 +:1027C000F085F2892020803AA64BF28A80018E01A2 +:1027D000F183F086200F800C44A2CDF0F08D3C0CEC +:1027E00000FFF10500000009E2204EF2010E040393 +:1027F0007FF84E0200F78E04E6024EF300F3A03499 +:102800005A080204480000EE04937FFF4004880841 +:10281000F08BF10BA03D8801A6C0CB29A642E62291 +:10282000E9029EC9A703F0038E02E080E8038C81D1 +:10283000D502F4068440B65F3C1C0100F00480A67B +:1028400049FFFF66A07EF2073810A6028A20FE54D8 +:102850000423800838212602880240008016F109EE +:10286000880122137FF29603E001D536A741501468 +:102870007FFFD939A6C240140010E662F18CE9034B +:102880008E61D5028460A703F0038E02E080E80326 +:102890008C81D502F4063C1C01008400B61F501048 +:1028A00080A28441F00480A649FFFF32A07EF20C92 +:1028B0003810A60242110073F207FE540423800868 +:1028C00038212602880240008016F109880122136F +:1028D0007FF29603E0204000BC1A12037FF8120337 +:1028E0007FF4D507841FAE3002037FF212037FF816 +:1028F000A03DF10B8801A6C2CB2DA640E622E9023D +:102900009EC9A70150047FFEE080E8038C81D503B7 +:1029100050447FFF3C1C01008401B61F50108144CD +:102920008440F0049D7149FFFEF3A07FF208381047 +:10293000A6028A20FE540423800838212602880239 +:1029400040008016F10A880122137FF39603E0010C +:10295000D532A743F106D936A6C0E662E9038E61F7 +:10296000D5028460A70150047FFEE080E8038C81DB +:10297000D50350447FFF3C1C01008441B65F5010DA +:1029800081E69972F00449FFFEC3A07FF20D381072 +:10299000A60242110073F208FE5404238008382175 +:1029A0002602880240008016F10A880122137FF374 +:1029B0009603E0204000BC1A12037FF912037FF552 +:1029C000D507841FAE3102037FF312037FF9220380 +:1029D0007FF81205000022037FF912050001D50CD3 +:1029E0002205000012037FF82205000112037FF97F +:1029F000841FAE30AE31F0058D448C01F0855063FC +:102A000000FC48FFFEEEFCC7FC48F08DFA09120FEF +:102A1000801DFA07120F801E8400120F801F2E00E7 +:102A20000439F18C8122C007840A120F801D8408AA +:102A3000120F801E2E07E984C80B020F801D8C0325 +:102A4000120F801D020F801E8C03120F801E844106 +:102A500080A2F00C44126B308460848249FF77B40A +:102A6000844180628029848280A2F00C49FF77AC87 +:102A7000842044213598443D94D044426B302E0745 +:102A8000C542E220E816980A9401994388A980C1BA +:102A9000A5688C21AD402E07C5432E57C5428E0137 +:102AA00042628073943199448809A400AC28D5E827 +:102AB00044026B30802084428461848384A049FF77 +:102AC0007783802944026B3084428461848384A0AC +:102AD00049FF777A2E37C54284C084E144026B30C7 +:102AE000B67F501F803A804080A72E47C543F681AD +:102AF000F682F683F684F685F786F787F688F689F8 +:102B0000F68A49FFAF4E2E37C5428009B67FB04FD7 +:102B1000804980A72E47C543F681F682F683F68466 +:102B2000F685F786F787F688F689F68A49FFAF3982 +:102B30002E37C5428542B67FF38214AF80068009E6 +:102B4000804980A72E47C543F781F683F684F68532 +:102B5000F687F688F689F68A44126B3049FFAF2172 +:102B60002E37C5428009B67FB04E804980A72E47D8 +:102B7000C543F681F682F683F684F685F786F687F6 +:102B8000F688F689F68A12AF801C49FFAF0A2E3705 +:102B9000C542B00EF382802980A62E47C543B6DF1A +:102BA000F781F683F684F685F786F787F688F68947 +:102BB000F78A44226B30127F801C49FFAEF22E3719 +:102BC000C542854844126B30B67FF382F00C8041D9 +:102BD00080A72E47C543F781F683F684F685F686EF +:102BE00014AF8007F688F689F68A49FFAEDA2E37E9 +:102BF000C542501F803E44007FFFB67FF088804171 +:102C000080A72E47C543F681F682F683F684F685C3 +:102C1000F686F687F789F78A44026B3049FFAEC122 +:102C20002E37C542F00D80292E47C543B67FF78168 +:102C3000F382F683F684F685F68614AF8007F6886D +:102C4000F689F78A804980A749FFAEAB020F801F43 +:102C50004410277340008006FCC8FC2049FF751B08 +:102C600049FFCE245A00081549FFCE4A4403F572A5 +:102C70008421AE404403F5738420AE4049FFAF8702 +:102C80002E07E906C80349FFCB5B49FFCE594473C1 +:102C9000F04BA6384413F04B5A00FF05841FAE08D2 +:102CA000D5FF49FFD1B55A0003E15A0002F05A009E +:102CB00013F249FFD7125A0002EA5A0013EC3C0DF6 +:102CC000FAABA78097B0CEE649FF76C83E600464B1 +:102CD00049FFCE742E07E9695A08120E3C03F4DC52 +:102CE000802649FFF6085A08010780062E10046462 +:102CF00049FFF4FB2E07E9695A0004125A08190427 +:102D000049FFF53349FFCEB949FFD2DF5A0002BF70 +:102D10002E07E9695A08050A49FFCF94440000FFCD +:102D20002E10046449FFF4E13C0DFAAB8421AE405F +:102D300084003C0FFAD749FFCF60D5AC42508824BD +:102D40004010400942500C73960140314009969161 +:102D500042F00C2442400824FE8C40078800E20226 +:102D600040F7C0084020400842F08C7340104009F2 +:102D7000882F9822E204882F984DDD9E8060C2073C +:102D8000994A0840800118418001D9FCDD9E9200DB +:102D90008060995AD30418118001D5FDDD9E920000 +:102DA000EFF0F1FF00010F1011000000FFFFFFFF27 +:102DB00008FFFFFFFF00000000000001000100000D +:102DC0000000010000000000010000000001000000 +:102DD00000010000010000000100000000000000F0 +:102DE00000010001000001000100000000000001DE +:102DF00000000000000001000000010000000001D0 +:102E000000000000000101000000010000000001BE +:102E100000000000010000000001000000010100AE +:102E2000000000000100000000010000000100009F +:102E3000000000000100010000000000000001008F +:102E40000001000000010000040506070202020361 +:102E500003030404000000000C0C00555071020034 +:102E6000D873020060760200E8780200600C02006D +:102E7000A020020000400200604C0200701102001D +:102E800080160200E0510200F0560200402B0200C2 +:102E9000D02B0200B03E0200403F0200202A020078 +:102EA000B02A0200903D0200203E02005071020054 +:102EB000D873020060760200E87802007011020008 +:102EC00080160200E0510200F0560200F000F0000F +:102ED000B4009000600C0200A0200200004002003C +:102EE000604C0200600C0200A020020000400200C2 +:102EF000604C02007011020080160200E0510200D6 +:102F0000F0560200A4C04422D0184412000094DA03 +:102F10008861B662A4C25041002094DA8861A8D2C8 +:102F2000A4C494DA8861A8D1A4C694DA8861B6648E +:102F30000230000894DA8861A8E1A4C494DA8861B8 +:102F4000A8E50200000894028820A866DD9EB4402F +:102F500084A08C449C2EA2D196005A58200680A0B2 +:102F60005A0824FADD9E5441801F384094088CA1F1 +:102F700097689265D8F3D5F4FC20B46084008C7C0B +:102F80009583A31997B08440995697688C415472E1 +:102F9000000F96903870940892845A2808F78C0194 +:102FA00096005A0804EFFCA0FC20B4608400503165 +:102FB000802C9583A31997B08440995697688C41CB +:102FC0005472000F96903870940892845A2808F72B +:102FD0008C0196005A0804EFFCA0FC003C0C017A1E +:102FE00084233C0FFAA74403F40B8440AE4044030F +:102FF000F4048426AE404413F4078401AE0844135D +:10300000F408AE084413F01EAE884413F420AE0852 +:103010002E07C5DC5A0801063C0C017A4900003134 +:103020004402D0184412D22049FFFF934402D01822 +:103030004412D71049FFFFA24402D01C4412D518F5 +:1030400049FFFF9C4412D5DC4402D01849FFFFAE73 +:103050004900004F44028F7049FF9F79FC80441063 +:1030600000963C1BF4C94412C8C884003E07E971AD +:103070003E07E959AE08AE09AE0AAE0BDD9EFC0074 +:103080000400001244120054921054007FFF940276 +:10309000880144128F700020812810200018002021 +:1030A000812910200019002081261020001B00100B +:1030B00081271010001AA08546110000FE57A84570 +:1030C000A08546120000FE57A845A08546180000BE +:1030D000FE57A845A08546140000FE57A8454402A7 +:1030E000283849000050FC803C0FFFA8DD9E3C2C96 +:1030F000017A441200A804010012921054007FFFCC +:103100009402880144120000B400920A96373E07E8 +:10311000E94904010012921054007FFF94028801D3 +:10312000B42000000020922A96773E17E92E3E0731 +:10313000E950DD9E440251703C0FFA7F4403F14296 +:10314000441028B8AC40441251888400B6013C1D9C +:10315000FA7FA80F3C1DFA7F14008008DD9EFC005A +:103160004413F381A608540000F0AE084413F3841E +:103170008400AE084413F56BAE0849FFAD08FC802F +:10318000DD9E441E0000880192024413F3CA96019A +:10319000AC08DD9E4423F054AC104403F056AC4020 +:1031A000DD9EDD9E96069404965FFE474403F04341 +:1031B000AE40DD9E4413F044AC08DD9E4423F05045 +:1031C0009617A650541080F8FE47AE50DD9E44235B +:1031D000F0509617A65094045410808FFE47AE50BE +:1031E000DD9EFC00840749FFFFEB4403F04C842084 +:1031F000AE40840749FFFFED4403F04E8421AE400A +:1032000049FFB089FC803C0FFFA9DD9E3C0FFA8985 +:10321000DD9E3C0FFA7EDD9E3C0FFA8BDD9E3C0F5F +:10322000FFAEDD9E3C0FFFADDD9E3C0FFFACDD9E93 +:103230003C0FFFB9DD9E3C0FFA8DDD9E3C0FFA8CF2 +:10324000DD9EFC003C0FFFF64900000F3C0FFA8F9B +:103250004900000B3C1DFFF6A68AA64B42010473F1 +:103260003C0FFA8EFC8044026620DD9E3BFFFCBCD6 +:10327000EFFC8401842049FFFF97EC0444000CD547 +:103280003BFFFC8448FFFF984423F01FA610541016 +:1032900000E04403F302A6C0A6009627880196002A +:1032A000AE10DD9E3BFFFCBC8400EFFC802049FF9C +:1032B000FF7349FF6F1249FFFE9249FFFFD949FF93 +:1032C000FFE549FF745749FFFF3749FFFF8C49FF6E +:1032D000FF5949FFFF46EC043BFFFC8448FF69426D +:1032E0003C0DFAAE3A6FA8BC80C15A08040D2E07F7 +:1032F000C5DBC009840249FFF26C3C0DFAAE5A08E6 +:103300000424D51149FF6FD65A0002F6840149FF03 +:10331000F2608420846184028041808180A349FF1F +:103320007029D5F149FF6FC65A00020F2E77C5DB11 +:103330005A78010B800749FFADD9840049FF9535C4 +:10334000800749FF6F474473F04A449000553C0D95 +:10335000FAD3C009840449FFF23C3C0DFAAE5A0886 +:103360000428D50B49FFADC65A0801F6840349FF6E +:10337000F23010938000D5EC49FF6F9C5A0002197F +:103380002E07C5DB5A08011549FF70EB4403F429E9 +:10339000441FFFC3AE40840049FFA51A3C0DFA9AB2 +:1033A000842049FF74018402AE314800009449FF33 +:1033B0006F815A0802328420846180418083FA1030 +:1033C00049FFDB258441541000DF80628082FA10BF +:1033D00049FFDB1D8420846180418083440046E0F6 +:1033E00049FFDB158420846180E080414400CFF0F8 +:1033F000808349FFDB0C5A78070BC80584033E071E +:10340000E975D50A84043E07E975D506CF05C804D9 +:1034100084013E07E97580468405842049FFA7F4AE +:1034200084203C0DFA9A49FF73BF8402AE318401B7 +:1034300049FFAEC0840549FFF1CC4463F06449FF05 +:103440006F398120A6305A980229540000FEAE3010 +:1034500049FF6F3080E05A08013EA6705810800185 +:10346000AE703C0DFA9AA6005A00023549FF9496B8 +:103470003C1DFA9A840EAE098406AE0880018027AE +:1034800049FF739284208009806780A780418081F2 +:103490003A6FA88448FF6F6E58000001AE303C0DB3 +:1034A000FA9AA6005A00021749FF94783C0DFA9A3E +:1034B000842EAE418426AE40842149FF737584205A +:1034C000846184028041808180A33A6FA88448FF90 +:1034D0006F513A6FA884DD9E3C0FFA91DD9E3C0F40 +:1034E000FFFDDD9E3C0DFA91A4413C1BFFF3A4447B +:1034F000A6003C1BFFF23E07FFE2DD9E3A6FAABC2E +:10350000EFFC2E57C5422E27C5722E47C54396297C +:10351000421008243C1BE2A996E12E17C573FE1C3D +:103520003C0BE2BA4261842444022D8592419221EF +:103530003E27C5793E57C54F3C6BE2AA3E17C57A78 +:103540003E47C550A6408421AE40A6418420AE41EE +:1035500044522D9C443DD9D044228F7044022DA466 +:10356000986B3811041018128001D8FB84C04402F3 +:103570007B903C6FFAA049FFFCC73C0C017A4412D7 +:103580002CFE3C0FFAAD44222CFC44022D5CB6C04C +:10359000AD90AD883C1FFAA644122CF83C1FFAB639 +:1035A00044122CF93C1FFAAB44122CFA3C1FFA9A35 +:1035B0002E17C5E33C0FFA9D3C2FFAA43E67E94F56 +:1035C0005A180107B42058108002B620D505B4401F +:1035D000843DFE56B62044122D5C440FBFFFB4411B +:1035E0008521FE16B601B401847B40002404B60197 +:1035F000B4018457FE1EB601B40184C0FE16B601A4 +:10360000B401854058000010B601B481440FFFBFDB +:10361000FE26B601B40184E058000020B601B401D2 +:1036200058000C00B601B481440FCFFFFE265800AD +:103630002000B601B40144122CFE3C0FFAB8A508D4 +:10364000841DFE26AC08A508841EFE26AC08A4082E +:10365000FEC6ACC8A408FE86AC88A44844022CFC74 +:10366000AC403E67E97D3E67E96D3E60043F3C9EAD +:1036700001102E07C5E83CABF4E03E07E934440FE7 +:10368000FFAA3E07E93B440000553E07E9403E07DC +:10369000E9363E07E9793EA7E9883E67E9783E6763 +:1036A000E9423E6004613E67E9113CABF4DA3CABB1 +:1036B000F4E23E97E9693E97E9224900024B3C0D4E +:1036C000FA9A3E67E9063CABF4DC3E67E907AF8156 +:1036D0003E67E9213E97E95F3E67E920AF803C1DE8 +:1036E000FAB684023E67E9133C9E01B53E67E9469F +:1036F0003E6004543E6004553E67E929AE083C1D17 +:10370000FAABAE0884043E07E9754402D0A03C0E33 +:1037100001CB4402D18C3C0E01CC4402D3603C0E60 +:1037200001CD4402D6683C0E01CE440000323C0874 +:1037300004E03E67E92A3C7FFAA73E67E95B3E97D3 +:10374000E9553E6004573C7BF4F03CABF4E83E673F +:10375000E91F3C0804E44402D6443C0E02714402D2 +:10376000D5D03C0FFAB2840A3E07EAB02E07C54313 +:103770003E67EAC43E07C67544028F703E67EAB1F1 +:103780003E67EAB23E6004213C7FFABB3C7FFAB759 +:103790003C7FFAB03C7FFAA23C7FFAB43C7FFAA1AE +:1037A0003C7FFABD3C7FFAB53C7FFA963C7FFA9BA2 +:1037B000490001E9800749FF7389800949FF738641 +:1037C000800749FF73913C0E01E9800949FF738C22 +:1037D0003C0E01EA840249FF73873C0E01EB84032F +:1037E00049FF73823C0E01EC840449FF737D3C0E5B +:1037F00001ED840549FF73783C0E01EE840649FF14 +:1038000073733C0E01EF840749FF736E3C0E01F0A9 +:10381000840849FF73693C0E01F13C03E2A93C13A3 +:10382000E3B63C0BE3B43C03E2AA3C7E01143C0B40 +:10383000E41D3C03E3B73E67E9474000240C8801E0 +:103840003C0BE3B83C03E4203C13E41F4000240C91 +:1038500088013E67E93D3C0BE4213E60044C49FF92 +:1038600080703C0FFAB949FF80444402D7943C0E63 +:1038700002C34402B5143E67EAE93E67EAE83E67E0 +:10388000EAEA3E600B083C7E02C43C0FFABC845F4F +:103890003C0DFAB9843F38201C088CE65A783CFA73 +:1038A0003C0DFAB984C03C6E01111010003C1010A0 +:1038B000003D2E07C54B3C6E01123E07E9653E6098 +:1038C000045B3E6004593E60045C3E60045D3E67FC +:1038D000EA643E67EA663E67EA653E67E9813E67FD +:1038E000E93D3E67E9633E67E9523E67E9663E6748 +:1038F000E9193E67E94C3E67E97F3E67E95C3E6750 +:10390000E9253E67E97B3E67E9873E67E9863E67D2 +:10391000E9453E60046049FFBEBE440000643C08C7 +:10392000054C4400005A3C08054E440000963C08F3 +:10393000054F3C080554FA183C0805558405FA293A +:103940003C08055744027B703E67E94D3C6BF4EF41 +:103950003E6004683E60045E3E600A953E600A96E2 +:103960003C68054D3C6805503C6805513C68055372 +:103970003C1805523C6805563C6805583E67E92FDF +:103980003E67E9513E67E9323E67E97749FF926356 +:103990002E07C5DC5A08010449FFFB6384013E0081 +:1039A00004583E07E9564402D3FC49FF6D4A49FFDB +:1039B0006D4684003E07E9603E07E9143E07E91AB8 +:1039C0003E07E9433E07E9243E07E9703E07E96BFD +:1039D0003E07E92D3E07E9353E07E97E840A44109B +:1039E000007F3E07E91B840F3E17E96E3E07E9851D +:1039F000EC043A6FAA84DD9E3A6F9CBC4462902826 +:103A0000EFF4800649FFFC0150037F48F081490034 +:103A100000959C34490000955003007849000097B8 +:103A2000500300A849000090500300CC49FF7248A1 +:103A300050037F48F08149FF7246500300B049FFB0 +:103A4000FBFC50037F48F08149FFFBFA50037F489D +:103A5000F08149FFFBE35003011849FFFD3F50038C +:103A60007F48F08149FFFD3D49FFFD3E5003012C99 +:103A700049FFFBD7507303A850037F48F08149FFEB +:103A8000FBD3800749FFFBD350037F48F08149FFF8 +:103A90008E8C5003017049FF8D805003031849FF3D +:103AA000760C50037F48F08149FF760A5003036487 +:103AB00049FF744750037F48F08149FF7445500324 +:103AC000037449FF827550037F48F08149FF827378 +:103AD000800749FF7F0850037F48F08149FF7F0638 +:103AE000500303B449FFFB9750037F48F08149FF1F +:103AF000FB8F3C0DFA9D49FFAD34500303D84900BC +:103B0000003C50037F48F0814900003A50030048D0 +:103B100049FFFAEC50037F48F08149FFFB945003C2 +:103B20007F48F08149FFFB8650037F48F081EC0C11 +:103B30003A6F9C8448FFF5863C0FFA94DD9E3C0F5B +:103B4000FA92DD9E3C0FFA93DD9E3C0E00E0DD9E76 +:103B5000FC0049FF6C4084203C0E00EB101000502C +:103B6000101000511010005210100053101000607F +:103B700010100061FC803C0E0100DD9E3C0E00FF39 +:103B8000DD9E3C0E0101DD9EFC40049F800A5A90A0 +:103B9000010B4462D4E44472D16C3863040038737E +:103BA0008400D50384E284CA8380FB48B910541092 +:103BB000FFFF944A4213287344A20000882ABE12D1 +:103BC0000080800792D010818000A6CE54637FFFD2 +:103BD000AEE0A6CCAEE80230002B02408009020025 +:103BE000002B0210800888648801940194D9886AA7 +:103BF000F4088940F009B664B7402E07E971C003A4 +:103C00005A98010E441000549432420384734412B3 +:103C100000008801B400920A9637D5032E000D28C3 +:103C2000AE10FCC0FC00838044600030BD12B812AE +:103C30005452FFFF54007FFF956A940242021873AA +:103C4000425198734442000044620030888088C02A +:103C50008AA0383290028C26540183FF1200FFFDA7 +:103C60004001A8099274543183FF1230FFFF5400C1 +:103C700003FFA2E11200FFFE540183FFAC104001DC +:103C8000A8099274540003FF543183FFAC11ACD2E5 +:103C90008C464C437FE0FC80FC40045000115452A1 +:103CA000FFFFC91B8380443200F0B910B8115410D3 +:103CB000FFFF944A882354007FFFA64C9648C224F5 +:103CC00094024430004842008C7344520000441275 +:103CD000004888A08801D515956A4462000088C50F +:103CE00044700048E264E8DF80A642519C73509221 +:103CF0008048181280014C54FFFE8C6196D8D5F391 +:103D000018228001D8FEFCC0040000114440004885 +:103D100054007FFF9402420190734452000088A037 +:103D2000840098C8A6D94041E0083830800040316E +:103D3000C00888649910A72140422008886438414F +:103D400000008C028864AAE95A0824EDDD9E040074 +:103D500000114440004854007FFF940242019073D8 +:103D600080604402000088608400A5193840800803 +:103D7000A75B9908AF61B483995038410008A31933 +:103D800092888C02AF295A0824F2DD9EE201E808ED +:103D9000A610E260E8039AC3D50B8400D50CE2209C +:103DA000E80BA61052F180FFE00FE8048860AED067 +:103DB000DD9E841FAE10DD9EFC40EEE85A38010700 +:103DC0003CA0028944400120D5092E500D124C50D0 +:103DD00000B93CA0028844400C602E57E903F486E9 +:103DE000E6A28481E9058EA14042140C972040424E +:103DF000040E9720F485CC038481F485F18880201B +:103E0000B00EB61FB00F505F8035F389F284F08199 +:103E1000F3828002503F8036B08D504F803749FF8B +:103E2000FEB5F004B062B0B4003F8036004F80377A +:103E300049FFFEFAF004B050B099003F803549FFC9 +:103E4000FF88B0228120B1D08500B00E3840220218 +:103E5000F0095A08010551C20090D50351C21B90C8 +:103E6000F00684C09960FA1442040024F08A3824D1 +:103E700099015A23FF552E17E9043832090100FF32 +:103E8000803405EF800894118E21F0874001BC1624 +:103E90004DE0C01CF107883C03E0800040FF3DF688 +:103EA00040F7A8014EF4000452F780008A0A4E043D +:103EB0000003FE0240F78007E903ACC8D5303802A2 +:103EC000890138039808D52BF108C904383E09093F +:103ED000D513F107883CA48840213C568A4A4E24D9 +:103EE0000003FE9240F028014EF4000452F78000D7 +:103EF000E04FE908ACC838149901382398003822FB +:103F00008509F10AB0D098B188439601802AF3055B +:103F1000F58BF48749FFFF3CF50BF4078CC15A6819 +:103F200024A850948048507380245A80010485014D +:103F3000D58DF004B050B099003F803549FFFEE6C2 +:103F4000ED18FCC0FC418401B63FF28180E349FFDB +:103F5000AF623C1DFAB68401AE083C1DFAABAE0858 +:103F600084003C0FFADA2E0004615A080104840729 +:103F7000D5085A7801052E07C631D5032E07C6305D +:103F80003E07E9032E07E90384C08C013E07E904DC +:103F90003C6FFAD744A3F04A448000552E07E90449 +:103FA000E2C08400E8373C0FFADCCF0349FFA434B9 +:103FB00049FF7586852010850000F0014C90002493 +:103FC0003C0DFADCE320E8FA2E07C5DCC0112E0711 +:103FD000C5EEC00E2E500D124C54C00BCF092E0052 +:103FE000042BC806800649FFA3775A0001178009F1 +:103FF0008026B45F806749FFFEE1505480015492EF +:1040000080FFD5DC3C0DFAAB8CC1842197B0AE406B +:10401000D5C649FFAF008400FCC1FC002E0004613E +:10402000C8063C13E3193C23E31AD504442000805E +:1040300080222E37E9713C03E3145A38040D2E37E1 +:10404000E91D520000FFFE1C2E37E95040000C16FF +:10405000520000FF3C0802883C03E31596483C08E8 +:10406000028984003E07E90296903C0DFAAD846017 +:104070002E47C56D49FFFE123C0DFA9A3C1DFAAD64 +:104080002E27C56F846049FFFF5F80C05A08010872 +:10409000FA0349FF6B7B3E60042BD53E49FF6F4C12 +:1040A0003C1DFA9A5A0802058405AE09D507840911 +:1040B000AE098001842049FF73B93C0DFA9A49FF8B +:1040C0009656844180623C1DFAAD3C0DFA9A49FF38 +:1040D000FF3B84004412CE58844149FFD68D8407AB +:1040E00049FFF1B949FF6F285A080206842D3C0D9B +:1040F000FA9AD50D3C0DFA9A842049FF73972E1732 +:10410000E9733C0DFA9A5A180203842AAE413C0D19 +:10411000FA9A49FF962CFC803BFFFCBCEFFC440262 +:10412000000044121B9049FF71983C0DFAAB8421AA +:10413000EC04AE403BFFFC84DD9E3A6FA4BCEFDC98 +:1041400044112DD4B1843A2094003A2314208120C4 +:1041500049FFA36249FFA095F08149FF9F88840031 +:10416000120F800784E038131E02500F800E2E2796 +:10417000C54F2E37C5508CE149FF71F65A7804F5CA +:10418000000480005A08012184033C1DFA9AF201C0 +:104190004432B39049FF97242E17E92E440000C8FB +:1041A000FE0C120F800744121B90500F800E2E271A +:1041B000C54F2E37C55049FF71D749FF74813C1D4B +:1041C000FAB6A608C8FF4403F04A44100055EC2490 +:1041D000AE403A6FA4848400DD9E3BFFFEBCEFF846 +:1041E000FA0049FF6AD349FF946384013E07E95707 +:1041F0003E07E92884003E00042B3E07E9413E07C4 +:10420000E90149FF6E993C1DFA9A5A08020D84048F +:10421000AE098001842049FF73093C0DFA9A842D70 +:10422000AE41D50B8409AE098001842049FF72FE9E +:104230003C0DFA9A842AAE413C0DFAB68421AE4078 +:104240002E07C5DC5A0801122E07E9713E07E9590D +:104250002E07E95FC8043E07E914D5072E07E914C5 +:104260005A0801043E00042B3C0DFA9AA6013E07B1 +:10427000E973840649FFF0EF2E00042BC8193C1D9A +:10428000FA9A2E27E9604432B39049FF96A93C0779 +:10429000F4EA49FFA2202E07C5E65A08010449FFA7 +:1042A000FEBE840A49FFF0D7840B49FFF0D42E00EC +:1042B000042B5A08010D8400120F80034412AD70C4 +:1042C000500F8006FA40FA7449FF714E2E07C5DC84 +:1042D0005A08010D2E00042B5A0001052E07E94152 +:1042E000C8054402CE5B49FFFF2A2E07C5DC5A08E9 +:1042F000011B2E00042BC81149FFB84F5A00010AB8 +:104300003C1DFA9A2E07E971A64949FF70C5D50FE1 +:104310003E07E91448FFFF663C1DFAB6A6085A0896 +:1043200001FFD5EF2E07E97149FF70D284003E00EE +:10433000046149FF6E013C1DFA9A2E27E9735A0861 +:1043400002069E12E602E804D5055A200204AE8950 +:10435000D503840DAE093C0DFA9A49FF95088400F7 +:104360003E07E9813E07E92A3E07E9282E07C604F1 +:1043700084213E07E9533C0DFAABAE4049FF73A0E0 +:10438000490000695A08020448FFFF2C84004422B7 +:1043900025B08060444220A080A03C13E2BAE20134 +:1043A000E8099842AEC8944188248C01AD48960132 +:1043B000D5F584003E07E96F84013E07E937EC0834 +:1043C0003BFFFE84DD9E440000A23A6F98BC49FF8B +:1043D000F0383C0DFA9AA6015A080D128400847F29 +:1043E0003C2DFAB9843F383100088C065A083CFA53 +:1043F0003C0DFAB91010003C1010003D49FFD5EB00 +:104400003E0004392E07C54B84C0520000013E67B0 +:10441000E91149FF6E3B84013E07E9383E07E95840 +:104420003E67E9643E67E9143E60043A3E60043B3F +:104430003E60043C49FFC3E32E07C5DC3E67E97AD2 +:104440005A0801063A6F988448FFACE53A6F9884A1 +:10445000DD9E3A6FA6BCEFE044012DE4B1843A2022 +:10446000140044012DF43A2F94203A2014002E0712 +:10447000C5DC80FF3A2314205A0801322E00042B99 +:10448000C81F2E07E97149FF6FB15A08010A2E07AC +:10449000E95F5A0801063E07E9148402D53249FF54 +:1044A000B47785203803A602381326028D2149FFF0 +:1044B0006FD45A9804F984013E07E941D5102E07BC +:1044C000E941C80D2E07E96049FF6FA92E17E96081 +:1044D000380F86023813060249FF6FBF44021B9053 +:1044E0004412451049FF6FB984C144021B90441225 +:1044F00040003E67E95649FF6FB03E6004318401D9 +:10450000EC203A6FA684DD9E000000000000000051 +:10451000000000000000000000000000000000009B +:10452000000000000000000000000000000000008B +:10453000000000000000000000000000000000007B +:10454000000000000000000000000000000000006B +:10455000000000000000000000000000000000005B +:10456000000000000000000000000000000000004B +:10457000000000000000000000000000000000003B +:10458000000000000000000000000000000000002B +:10459000000000000000000000000000000000001B +:1045A000000000000000000000000000000000000B +:1045B00000000000000000000000000000000000FB +:1045C00000000000000000000000000000000000EB +:1045D00000000000000000000000000000000000DB +:1045E00000000000000000000000000000000000CB +:1045F00000000000000000000000000000000000BB +:1046000000000000000000000000000000000000AA +:10461000000000000000000000000000000000009A +:10462000000000000000000000000000000000008A +:10463000000000000000000000000000000000007A +:10464000000000000000000000000000000000006A +:10465000000000000000000000000000000000005A +:10466000000000000000000000000000000000004A +:10467000000000000000000000000000000000003A +:10468000000000000000000000000000000000002A +:10469000000000000000000000000000000000001A +:1046A000000000000000000000000000000000000A +:1046B00000000000000000000000000000000000FA +:1046C00000000000000000000000000000000000EA +:1046D00000000000000000000000000000000000DA +:1046E00000000000000000000000000000000000CA +:1046F00000000000000000000000000000000000BA +:1047000000000000000000000000000000000000A9 +:104710000000000000000000000000000000000099 +:104720000000000000000000000000000000000089 +:104730000000000000000000000000000000000079 +:104740000000000000000000000000000000000069 +:104750000000000000000000000000000000000059 +:104760000000000000000000000000000000000049 +:104770000000000000000000000000000000000039 +:104780000000000000000000000000000000000029 +:104790000000000000000000000000000000000019 +:1047A0000000000000000000000000000000000009 +:1047B00000000000000000000000000000000000F9 +:1047C00000000000000000000000000000000000E9 +:1047D00000000000000000000000000000000000D9 +:1047E00000000000000000000000000000000000C9 +:1047F00000000000000000000000000000000000B9 +:1048000000000000000000000000000000000000A8 +:104810000000000000000000000000000000000098 +:104820000000000000000000000000000000000088 +:104830000000000000000000000000000000000078 +:104840000000000000000000000000000000000068 +:104850000000000000000000000000000000000058 +:104860000000000000000000000000000000000048 +:104870000000000000000000000000000000000038 +:104880000000000000000000000000000000000028 +:104890000000000000000000000000000000000018 +:1048A0000000000000000000000000000000000008 +:1048B00000000000000000000000000000000000F8 +:1048C00000000000000000000000000000000000E8 +:1048D00000000000000000000000000000000000D8 +:1048E00000000000000000000000000000000000C8 +:1048F00000000000000000000000000000000000B8 +:1049000000000000000000000000000000000000A7 +:104910000000000000000000000000000000000097 +:104920000000000000000000000000000000000087 +:104930000000000000000000000000000000000077 +:104940000000000000000000000000000000000067 +:104950000000000000000000000000000000000057 +:104960000000000000000000000000000000000047 +:104970000000000000000000000000000000000037 +:104980000000000000000000000000000000000027 +:104990000000000000000000000000000000000017 +:1049A0000000000000000000000000000000000007 +:1049B00000000000000000000000000000000000F7 +:1049C00000000000000000000000000000000000E7 +:1049D00000000000000000000000000000000000D7 +:1049E00000000000000000000000000000000000C7 +:1049F00000000000000000000000000000000000B7 +:104A000000000000000000000000000000000000A6 +:104A10000000000000000000000000000000000096 +:104A20000000000000000000000000000000000086 +:104A30000000000000000000000000000000000076 +:104A40000000000000000000000000000000000066 +:104A50000000000000000000000000000000000056 +:104A60000000000000000000000000000000000046 +:104A70000000000000000000000000000000000036 +:104A80000000000000000000000000000000000026 +:104A90000000000000000000000000000000000016 +:104AA0000000000000000000000000000000000006 +:104AB00000000000000000000000000000000000F6 +:104AC00000000000000000000000000000000000E6 +:104AD00000000000000000000000000000000000D6 +:104AE00000000000000000000000000000000000C6 +:104AF00000000000000000000000000000000000B6 +:104B000000000000000000000000000000000000A5 +:104B10000000000000000000000000000000000095 +:104B20000000000000000000000000000000000085 +:104B30000000000000000000000000000000000075 +:104B40000000000000000000000000000000000065 +:104B50000000000000000000000000000000000055 +:104B60000000000000000000000000000000000045 +:104B70000000000000000000000000000000000035 +:104B80000000000000000000000000000000000025 +:104B90000000000000000000000000000000000015 +:104BA0000000000000000000000000000000000005 +:104BB00000000000000000000000000000000000F5 +:104BC00000000000000000000000000000000000E5 +:104BD00000000000000000000000000000000000D5 +:104BE00000000000000000000000000000000000C5 +:104BF00000000000000000000000000000000000B5 +:104C000000000000000000000000000000000000A4 +:104C10000000000000000000000000000000000094 +:104C20000000000000000000000000000000000084 +:104C30000000000000000000000000000000000074 +:104C40000000000000000000000000000000000064 +:104C50000000000000000000000000000000000054 +:104C60000000000000000000000000000000000044 +:104C70000000000000000000000000000000000034 +:104C80000000000000000000000000000000000024 +:104C90000000000000000000000000000000000014 +:104CA0000000000000000000000000000000000004 +:104CB00000000000000000000000000000000000F4 +:104CC00000000000000000000000000000000000E4 +:104CD00000000000000000000000000000000000D4 +:104CE00000000000000000000000000000000000C4 +:104CF00000000000000000000000000000000000B4 +:104D000000000000000000000000000000000000A3 +:104D10000000000000000000000000000000000093 +:104D20000000000000000000000000000000000083 +:104D30000000000000000000000000000000000073 +:104D40000000000000000000000000000000000063 +:104D50000000000000000000000000000000000053 +:104D60000000000000000000000000000000000043 +:104D70000000000000000000000000000000000033 +:104D80000000000000000000000000000000000023 +:104D90000000000000000000000000000000000013 +:104DA0000000000000000000000000000000000003 +:104DB00000000000000000000000000000000000F3 +:104DC00000000000000000000000000000000000E3 +:104DD00000000000000000000000000000000000D3 +:104DE00000000000000000000000000000000000C3 +:104DF00000000000000000000000000000000000B3 +:104E000000000000000000000000000000000000A2 +:104E10000000000000000000000000000000000092 +:104E20000000000000000000000000000000000082 +:104E30000000000000000000000000000000000072 +:104E40000000000000000000000000000000000062 +:104E50000000000000000000000000000000000052 +:104E60000000000000000000000000000000000042 +:104E70000000000000000000000000000000000032 +:104E80000000000000000000000000000000000022 +:104E90000000000000000000000000000000000012 +:104EA0000000000000000000000000000000000002 +:104EB00000000000000000000000000000000000F2 +:104EC00000000000000000000000000000000000E2 +:104ED00000000000000000000000000000000000D2 +:104EE00000000000000000000000000000000000C2 +:104EF00000000000000000000000000000000000B2 +:104F000000000000000000000000000000000000A1 +:104F10000000000000000000000000000000000091 +:104F20000000000000000000000000000000000081 +:104F30000000000000000000000000000000000071 +:104F40000000000000000000000000000000000061 +:104F50000000000000000000000000000000000051 +:104F60000000000000000000000000000000000041 +:104F70000000000000000000000000000000000031 +:104F80000000000000000000000000000000000021 +:104F90000000000000000000000000000000000011 +:104FA0000000000000000000000000000000000001 +:104FB00000000000000000000000000000000000F1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE00000000000000000000000000000000000C1 +:104FF00000000000000000000000000000000000B1 +:1050000000000000000000000000000000000000A0 +:105010000000000000000000000000000000000090 +:105020000000000000000000000000000000000080 +:105030000000000000000000000000000000000070 +:105040000000000000000000000000000000000060 +:105050000000000000000000000000000000000050 +:105060000000000000000000000000000000000040 +:105070000000000000000000000000000000000030 +:105080000000000000000000000000000000000020 +:105090000000000000000000000000000000000010 +:1050A0000000000000000000000000000000000000 +:1050B00000000000000000000000000000000000F0 +:1050C00000000000000000000000000000000000E0 +:1050D00000000000000000000000000000000000D0 +:1050E00000000000000000000000000000000000C0 +:1050F00000000000000000000000000000000000B0 +:10510000000000000000000000000000000000009F +:10511000000000000000000000000000000000008F +:10512000000000000000000000000000000000007F +:10513000000000000000000000000000000000006F +:10514000000000000000000000000000000000005F +:10515000000000000000000000000000000000004F +:10516000000000000000000000000000000000003F +:10517000000000000000000000000000000000002F +:10518000000000000000000000000000000000001F +:10519000000000000000000000000000000000000F +:1051A00000000000000000000000000000000000FF +:1051B00000000000000000000000000000000000EF +:1051C00000000000000000000000000000000000DF +:1051D00000000000000000000000000000000000CF +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:10520000000000000000000000000000000000009E +:10521000000000000000000000000000000000008E +:10522000000000000000000000000000000000007E +:10523000000000000000000000000000000000006E +:10524000000000000000000000000000000000005E +:10525000000000000000000000000000000000004E +:10526000000000000000000000000000000000003E +:10527000000000000000000000000000000000002E +:10528000000000000000000000000000000000001E +:10529000000000000000000000000000000000000E +:1052A00000000000000000000000000000000000FE +:1052B00000000000000000000000000000000000EE +:1052C00000000000000000000000000000000000DE +:1052D00000000000000000000000000000000000CE +:1052E00000000000000000000000000000000000BE +:1052F00000000000000000000000000000000000AE +:10530000000000000000000000000000000000009D +:10531000000000000000000000000000000000008D +:10532000000000000000000000000000000000007D +:10533000000000000000000000000000000000006D +:10534000000000000000000000000000000000005D +:10535000000000000000000000000000000000004D +:10536000000000000000000000000000000000003D +:10537000000000000000000000000000000000002D +:10538000000000000000000000000000000000001D +:10539000000000000000000000000000000000000D +:1053A00000000000000000000000000000000000FD +:1053B00000000000000000000000000000000000ED +:1053C00000000000000000000000000000000000DD +:1053D00000000000000000000000000000000000CD +:1053E00000000000000000000000000000000000BD +:1053F00000000000000000000000000000000000AD +:10540000000000000000000000000000000000009C +:10541000000000000000000000000000000000008C +:10542000000000000000000000000000000000007C +:10543000000000000000000000000000000000006C +:10544000000000000000000000000000000000005C +:10545000000000000000000000000000000000004C +:10546000000000000000000000000000000000003C +:10547000000000000000000000000000000000002C +:10548000000000000000000000000000000000001C +:10549000000000000000000000000000000000000C +:1054A00000000000000000000000000000000000FC +:1054B00000000000000000000000000000000000EC +:1054C00000000000000000000000000000000000DC +:1054D00000000000000000000000000000000000CC +:1054E00000000000000000000000000000000000BC +:1054F00000000000000000000000000000000000AC +:10550000000000000000000000000000000000009B +:10551000000000000000000000000000000000008B +:10552000000000000000000000000000000000007B +:10553000000000000000000000000000000000006B +:10554000000000000000000000000000000000005B +:10555000000000000000000000000000000000004B +:10556000000000000000000000000000000000003B +:10557000000000000000000000000000000000002B +:10558000000000000000000000000000000000001B +:10559000000000000000000000000000000000000B +:1055A00000000000000000000000000000000000FB +:1055B00000000000000000000000000000000000EB +:1055C00000000000000000000000000000000000DB +:1055D00000000000000000000000000000000000CB +:1055E00000000000000000000000000000000000BB +:1055F00000000000000000000000000000000000AB +:10560000000000000000000000000000000000009A +:10561000000000000000000000000000000000008A +:10562000000000000000000000000000000000007A +:10563000000000000000000000000000000000006A +:10564000000000000000000000000000000000005A +:10565000000000000000000000000000000000004A +:10566000000000000000000000000000000000003A +:10567000000000000000000000000000000000002A +:10568000000000000000000000000000000000001A +:10569000000000000000000000000000000000000A +:1056A00000000000000000000000000000000000FA +:1056B00000000000000000000000000000000000EA +:1056C00000000000000000000000000000000000DA +:1056D00000000000000000000000000000000000CA +:1056E00000000000000000000000000000000000BA +:1056F00000000000000000000000000000000000AA +:105700000000000000000000000000000000000099 +:105710000000000000000000000000000000000089 +:105720000000000000000000000000000000000079 +:105730000000000000000000000000000000000069 +:105740000000000000000000000000000000000059 +:105750000000000000000000000000000000000049 +:105760000000000000000000000000000000000039 +:105770000000000000000000000000000000000029 +:105780000000000000000000000000000000000019 +:105790000000000000000000000000000000000009 +:1057A00000000000000000000000000000000000F9 +:1057B00000000000000000000000000000000000E9 +:1057C00000000000000000000000000000000000D9 +:1057D00000000000000000000000000000000000C9 +:1057E00000000000000000000000000000000000B9 +:1057F00000000000000000000000000000000000A9 +:105800000000000000000000000000000000000098 +:105810000000000000000000000000000000000088 +:105820000000000000000000000000000000000078 +:105830000000000000000000000000000000000068 +:105840000000000000000000000000000000000058 +:105850000000000000000000000000000000000048 +:105860000000000000000000000000000000000038 +:105870000000000000000000000000000000000028 +:105880000000000000000000000000000000000018 +:105890000000000000000000000000000000000008 +:1058A00000000000000000000000000000000000F8 +:1058B00000000000000000000000000000000000E8 +:1058C00000000000000000000000000000000000D8 +:1058D00000000000000000000000000000000000C8 +:1058E00000000000000000000000000000000000B8 +:1058F00000000000000000000000000000000000A8 +:105900000000000000000000000000000000000097 +:105910000000000000000000000000000000000087 +:105920000000000000000000000000000000000077 +:105930000000000000000000000000000000000067 +:105940000000000000000000000000000000000057 +:105950000000000000000000000000000000000047 +:105960000000000000000000000000000000000037 +:105970000000000000000000000000000000000027 +:105980000000000000000000000000000000000017 +:105990000000000000000000000000000000000007 +:1059A00000000000000000000000000000000000F7 +:1059B00000000000000000000000000000000000E7 +:1059C00000000000000000000000000000000000D7 +:1059D00000000000000000000000000000000000C7 +:1059E00000000000000000000000000000000000B7 +:1059F00000000000000000000000000000000000A7 +:105A00000000000000000000000000000000000096 +:105A10000000000000000000000000000000000086 +:105A20000000000000000000000000000000000076 +:105A30000000000000000000000000000000000066 +:105A40000000000000000000000000000000000056 +:105A50000000000000000000000000000000000046 +:105A60000000000000000000000000000000000036 +:105A70000000000000000000000000000000000026 +:105A80000000000000000000000000000000000016 +:105A90000000000000000000000000000000000006 +:105AA00000000000000000000000000000000000F6 +:105AB00000000000000000000000000000000000E6 +:105AC00000000000000000000000000000000000D6 +:105AD00000000000000000000000000000000000C6 +:105AE00000000000000000000000000000000000B6 +:105AF00000000000000000000000000000000000A6 +:105B00000000000000000000000000000000000095 +:105B10000000000000000000000000000000000085 +:105B20000000000000000000000000000000000075 +:105B30000000000000000000000000000000000065 +:105B40000000000000000000000000000000000055 +:105B50000000000000000000000000000000000045 +:105B60000000000000000000000000000000000035 +:105B70000000000000000000000000000000000025 +:105B80000000000000000000000000000000000015 +:105B90000000000000000000000000000000000005 +:105BA00000000000000000000000000000000000F5 +:105BB00000000000000000000000000000000000E5 +:105BC00000000000000000000000000000000000D5 +:105BD00000000000000000000000000000000000C5 +:105BE00000000000000000000000000000000000B5 +:105BF00000000000000000000000000000000000A5 +:105C00000000000000000000000000000000000094 +:105C10000000000000000000000000000000000084 +:105C20000000000000000000000000000000000074 +:105C30000000000000000000000000000000000064 +:105C40000000000000000000000000000000000054 +:105C50000000000000000000000000000000000044 +:105C60000000000000000000000000000000000034 +:105C70000000000000000000000000000000000024 +:105C80000000000000000000000000000000000014 +:105C90000000000000000000000000000000000004 +:105CA00000000000000000000000000000000000F4 +:105CB00000000000000000000000000000000000E4 +:105CC00000000000000000000000000000000000D4 +:105CD00000000000000000000000000000000000C4 +:105CE00000000000000000000000000000000000B4 +:105CF00000000000000000000000000000000000A4 +:105D00000000000000000000000000000000000093 +:105D10000000000000000000000000000000000083 +:105D20000000000000000000000000000000000073 +:105D30000000000000000000000000000000000063 +:105D40000000000000000000000000000000000053 +:105D50000000000000000000000000000000000043 +:105D60000000000000000000000000000000000033 +:105D70000000000000000000000000000000000023 +:105D80000000000000000000000000000000000013 +:105D90000000000000000000000000000000000003 +:105DA00000000000000000000000000000000000F3 +:105DB00000000000000000000000000000000000E3 +:105DC00000000000000000000000000000000000D3 +:105DD00000000000000000000000000000000000C3 +:105DE00000000000000000000000000000000000B3 +:105DF00000000000000000000000000000000000A3 +:105E00000000000000000000000000000000000092 +:105E10000000000000000000000000000000000082 +:105E20000000000000000000000000000000000072 +:105E30000000000000000000000000000000000062 +:105E40000000000000000000000000000000000052 +:105E50000000000000000000000000000000000042 +:105E60000000000000000000000000000000000032 +:105E70000000000000000000000000000000000022 +:105E80000000000000000000000000000000000012 +:105E90000000000000000000000000000000000002 +:105EA00000000000000000000000000000000000F2 +:105EB00000000000000000000000000000000000E2 +:105EC00000000000000000000000000000000000D2 +:105ED00000000000000000000000000000000000C2 +:105EE00000000000000000000000000000000000B2 +:105EF00000000000000000000000000000000000A2 +:105F00000000000000000000000000000000000091 +:105F10000000000000000000000000000000000081 +:105F20000000000000000000000000000000000071 +:105F30000000000000000000000000000000000061 +:105F40000000000000000000000000000000000051 +:105F50000000000000000000000000000000000041 +:105F60000000000000000000000000000000000031 +:105F70000000000000000000000000000000000021 +:105F80000000000000000000000000000000000011 +:105F90000000000000000000000000000000000001 +:105FA00000000000000000000000000000000000F1 +:105FB00000000000000000000000000000000000E1 +:105FC00000000000000000000000000000000000D1 +:105FD00000000000000000000000000000000000C1 +:105FE00000000000000000000000000000000000B1 +:105FF00000000000000000000000000000000000A1 +:106000000000000000000000000000000000000090 +:106010000000000000000000000000000000000080 +:106020000000000000000000000000000000000070 +:106030000000000000000000000000000000000060 +:106040000000000000000000000000000000000050 +:106050000000000000000000000000000000000040 +:106060000000000000000000000000000000000030 +:106070000000000000000000000000000000000020 +:106080000000000000000000000000000000000010 +:106090000000000000000000000000000000000000 +:1060A00000000000000000000000000000000000F0 +:1060B00000000000000000000000000000000000E0 +:1060C00000000000000000000000000000000000D0 +:1060D00000000000000000000000000000000000C0 +:1060E00000000000000000000000000000000000B0 +:1060F00000000000000000000000000000000000A0 +:10610000000000000000000000000000000000008F +:10611000000000000000000000000000000000007F +:10612000000000000000000000000000000000006F +:10613000000000000000000000000000000000005F +:10614000000000000000000000000000000000004F +:10615000000000000000000000000000000000003F +:10616000000000000000000000000000000000002F +:10617000000000000000000000000000000000001F +:10618000000000000000000000000000000000000F +:1061900000000000000000000000000000000000FF +:1061A00000000000000000000000000000000000EF +:1061B00000000000000000000000000000000000DF +:1061C00000000000000000000000000000000000CF +:1061D00000000000000000000000000000000000BF +:1061E00000000000000000000000000000000000AF +:1061F000000000000000000000000000000000009F +:10620000000000000000000000000000000000008E +:10621000000000000000000000000000000000007E +:10622000000000000000000000000000000000006E +:10623000000000000000000000000000000000005E +:10624000000000000000000000000000000000004E +:10625000000000000000000000000000000000003E +:10626000000000000000000000000000000000002E +:10627000000000000000000000000000000000001E +:10628000000000000000000000000000000000000E +:1062900000000000000000000000000000000000FE +:1062A00000000000000000000000000000000000EE +:1062B00000000000000000000000000000000000DE +:1062C00000000000000000000000000000000000CE +:1062D00000000000000000000000000000000000BE +:1062E00000000000000000000000000000000000AE +:1062F000000000000000000000000000000000009E +:10630000000000000000000000000000000000008D +:10631000000000000000000000000000000000007D +:10632000000000000000000000000000000000006D +:10633000000000000000000000000000000000005D +:10634000000000000000000000000000000000004D +:10635000000000000000000000000000000000003D +:10636000000000000000000000000000000000002D +:10637000000000000000000000000000000000001D +:10638000000000000000000000000000000000000D +:1063900000000000000000000000000000000000FD +:1063A00000000000000000000000000000000000ED +:1063B00000000000000000000000000000000000DD +:1063C00000000000000000000000000000000000CD +:1063D00000000000000000000000000000000000BD +:1063E00000000000000000000000000000000000AD +:1063F000000000000000000000000000000000009D +:10640000000000000000000000000000000000008C +:10641000000000000000000000000000000000007C +:10642000000000000000000000000000000000006C +:10643000000000000000000000000000000000005C +:10644000000000000000000000000000000000004C +:10645000000000000000000000000000000000003C +:10646000000000000000000000000000000000002C +:10647000000000000000000000000000000000001C +:10648000000000000000000000000000000000000C +:1064900000000000000000000000000000000000FC +:1064A00000000000000000000000000000000000EC +:1064B00000000000000000000000000000000000DC +:1064C00000000000000000000000000000000000CC +:1064D00000000000000000000000000000000000BC +:1064E00000000000000000000000000000000000AC +:1064F000000000000000000000000000000000009C +:10650000000000000000000000000000000000008B +:10651000000000000000000000000000000000007B +:10652000000000000000000000000000000000006B +:10653000000000000000000000000000000000005B +:10654000000000000000000000000000000000004B +:10655000000000000000000000000000000000003B +:10656000000000000000000000000000000000002B +:10657000000000000000000000000000000000001B +:10658000000000000000000000000000000000000B +:1065900000000000000000000000000000000000FB +:1065A00000000000000000000000000000000000EB +:1065B00000000000000000000000000000000000DB +:1065C00000000000000000000000000000000000CB +:1065D00000000000000000000000000000000000BB +:1065E00000000000000000000000000000000000AB +:1065F000000000000000000000000000000000009B +:10660000000000000000000000000000000000008A +:10661000000000000000000000000000000000007A +:10662000000000000000000000000000000000006A +:10663000000000000000000000000000000000005A +:10664000000000000000000000000000000000004A +:10665000000000000000000000000000000000003A +:10666000000000000000000000000000000000002A +:10667000000000000000000000000000000000001A +:10668000000000000000000000000000000000000A +:1066900000000000000000000000000000000000FA +:1066A00000000000000000000000000000000000EA +:1066B00000000000000000000000000000000000DA +:1066C00000000000000000000000000000000000CA +:1066D00000000000000000000000000000000000BA +:1066E00000000000000000000000000000000000AA +:1066F000000000000000000000000000000000009A +:106700000000000000000000000000000000000089 +:106710000000000000000000000000000000000079 +:106720000000000000000000000000000000000069 +:106730000000000000000000000000000000000059 +:106740000000000000000000000000000000000049 +:106750000000000000000000000000000000000039 +:106760000000000000000000000000000000000029 +:106770000000000000000000000000000000000019 +:106780000000000000000000000000000000000009 +:1067900000000000000000000000000000000000F9 +:1067A00000000000000000000000000000000000E9 +:1067B00000000000000000000000000000000000D9 +:1067C00000000000000000000000000000000000C9 +:1067D00000000000000000000000000000000000B9 +:1067E00000000000000000000000000000000000A9 +:1067F0000000000000000000000000000000000099 +:106800000000000000000000000000000000000088 +:106810000000000000000000000000000000000078 +:106820000000000000000000000000000000000068 +:106830000000000000000000000000000000000058 +:106840000000000000000000000000000000000048 +:106850000000000000000000000000000000000038 +:106860000000000000000000000000000000000028 +:106870000000000000000000000000000000000018 +:106880000000000000000000000000000000000008 +:1068900000000000000000000000000000000000F8 +:1068A00000000000000000000000000000000000E8 +:1068B00000000000000000000000000000000000D8 +:1068C00000000000000000000000000000000000C8 +:1068D00000000000000000000000000000000000B8 +:1068E00000000000000000000000000000000000A8 +:1068F0000000000000000000000000000000000098 +:106900000000000000000000000000000000000087 +:106910000000000000000000000000000000000077 +:106920000000000000000000000000000000000067 +:106930000000000000000000000000000000000057 +:106940000000000000000000000000000000000047 +:106950000000000000000000000000000000000037 +:106960000000000000000000000000000000000027 +:106970000000000000000000000000000000000017 +:106980000000000000000000000000000000000007 +:1069900000000000000000000000000000000000F7 +:1069A00000000000000000000000000000000000E7 +:1069B00000000000000000000000000000000000D7 +:1069C00000000000000000000000000000000000C7 +:1069D00000000000000000000000000000000000B7 +:1069E00000000000000000000000000000000000A7 +:1069F0000000000000000000000000000000000097 +:106A00000000000000000000000000000000000086 +:106A10000000000000000000000000000000000076 +:106A20000000000000000000000000000000000066 +:106A30000000000000000000000000000000000056 +:106A40000000000000000000000000000000000046 +:106A50000000000000000000000000000000000036 +:106A60000000000000000000000000000000000026 +:106A70000000000000000000000000000000000016 +:106A80000000000000000000000000000000000006 +:106A900000000000000000000000000000000000F6 +:106AA00000000000000000000000000000000000E6 +:106AB00000000000000000000000000000000000D6 +:106AC00000000000000000000000000000000000C6 +:106AD00000000000000000000000000000000000B6 +:106AE00000000000000000000000000000000000A6 +:106AF0000000000000000000000000000000000096 +:106B00000000000000000000000000000000000085 +:106B10000000000000000000000000000000000075 +:106B20000000000000000000000000000000000065 +:106B30000000000000000000000000000000000055 +:106B40000000000000000000000000000000000045 +:106B50000000000000000000000000000000000035 +:106B60000000000000000000000000000000000025 +:106B70000000000000000000000000000000000015 +:106B80000000000000000000000000000000000005 +:106B900000000000000000000000000000000000F5 +:106BA00000000000000000000000000000000000E5 +:106BB00000000000000000000000000000000000D5 +:106BC00000000000000000000000000000000000C5 +:106BD00000000000000000000000000000000000B5 +:106BE00000000000000000000000000000000000A5 +:106BF0000000000000000000000000000000000095 +:106C00000000000000000000000000000000000084 +:106C10000000000000000000000000000000000074 +:106C20000000000000000000000000000000000064 +:106C30000000000000000000000000000000000054 +:106C40000000000000000000000000000000000044 +:106C50000000000000000000000000000000000034 +:106C60000000000000000000000000000000000024 +:106C70000000000000000000000000000000000014 +:106C80000000000000000000000000000000000004 +:106C900000000000000000000000000000000000F4 +:106CA00000000000000000000000000000000000E4 +:106CB00000000000000000000000000000000000D4 +:106CC00000000000000000000000000000000000C4 +:106CD00000000000000000000000000000000000B4 +:106CE00000000000000000000000000000000000A4 +:106CF0000000000000000000000000000000000094 +:106D00000000000000000000000000000000000083 +:106D10000000000000000000000000000000000073 +:106D20000000000000000000000000000000000063 +:106D30000000000000000000000000000000000053 +:106D40000000000000000000000000000000000043 +:106D50000000000000000000000000000000000033 +:106D60000000000000000000000000000000000023 +:106D70000000000000000000000000000000000013 +:106D80000000000000000000000000000000000003 +:106D900000000000000000000000000000000000F3 +:106DA00000000000000000000000000000000000E3 +:106DB00000000000000000000000000000000000D3 +:106DC00000000000000000000000000000000000C3 +:106DD00000000000000000000000000000000000B3 +:106DE00000000000000000000000000000000000A3 +:106DF0000000000000000000000000000000000093 +:106E00000000000000000000000000000000000082 +:106E10000000000000000000000000000000000072 +:106E20000000000000000000000000000000000062 +:106E30000000000000000000000000000000000052 +:106E40000000000000000000000000000000000042 +:106E50000000000000000000000000000000000032 +:106E60000000000000000000000000000000000022 +:106E70000000000000000000000000000000000012 +:106E80000000000000000000000000000000000002 +:106E900000000000000000000000000000000000F2 +:106EA00000000000000000000000000000000000E2 +:106EB00000000000000000000000000000000000D2 +:106EC00000000000000000000000000000000000C2 +:106ED00000000000000000000000000000000000B2 +:106EE00000000000000000000000000000000000A2 +:106EF0000000000000000000000000000000000092 +:106F00000000000000000000000000000000000081 +:106F10000000000000000000000000000000000071 +:106F20000000000000000000000000000000000061 +:106F30000000000000000000000000000000000051 +:106F40000000000000000000000000000000000041 +:106F50000000000000000000000000000000000031 +:106F60000000000000000000000000000000000021 +:106F70000000000000000000000000000000000011 +:106F80000000000000000000000000000000000001 +:106F900000000000000000000000000000000000F1 +:106FA00000000000000000000000000000000000E1 +:106FB00000000000000000000000000000000000D1 +:106FC00000000000000000000000000000000000C1 +:106FD00000000000000000000000000000000000B1 +:106FE00000000000000000000000000000000000A1 +:106FF0000000000000000000000000000000000091 +:107000000000000000000000000000000000000080 +:107010000000000000000000000000000000000070 +:107020000000000000000000000000000000000060 +:107030000000000000000000000000000000000050 +:107040000000000000000000000000000000000040 +:107050000000000000000000000000000000000030 +:107060000000000000000000000000000000000020 +:107070000000000000000000000000000000000010 +:107080000000000000000000000000000000000000 +:1070900000000000000000000000000000000000F0 +:1070A00000000000000000000000000000000000E0 +:1070B00000000000000000000000000000000000D0 +:1070C00000000000000000000000000000000000C0 +:1070D00000000000000000000000000000000000B0 +:1070E00000000000000000000000000000000000A0 +:1070F0000000000000000000000000000000000090 +:10710000000000000000000000000000000000007F +:10711000000000000000000000000000000000006F +:10712000000000000000000000000000000000005F +:10713000000000000000000000000000000000004F +:10714000000000000000000000000000000000003F +:10715000000000000000000000000000000000002F +:10716000000000000000000000000000000000001F +:10717000000000000000000000000000000000000F +:1071800000000000000000000000000000000000FF +:1071900000000000000000000000000000000000EF +:1071A00000000000000000000000000000000000DF +:1071B00000000000000000000000000000000000CF +:1071C00000000000000000000000000000000000BF +:1071D00000000000000000000000000000000000AF +:1071E000000000000000000000000000000000009F +:1071F000000000000000000000000000000000008F +:10720000000000000000000000000000000000007E +:10721000000000000000000000000000000000006E +:10722000000000000000000000000000000000005E +:10723000000000000000000000000000000000004E +:10724000000000000000000000000000000000003E +:10725000000000000000000000000000000000002E +:10726000000000000000000000000000000000001E +:10727000000000000000000000000000000000000E +:1072800000000000000000000000000000000000FE +:1072900000000000000000000000000000000000EE +:1072A00000000000000000000000000000000000DE +:1072B00000000000000000000000000000000000CE +:1072C00000000000000000000000000000000000BE +:1072D00000000000000000000000000000000000AE +:1072E000000000000000000000000000000000009E +:1072F000000000000000000000000000000000008E +:10730000000000000000000000000000000000007D +:10731000000000000000000000000000000000006D +:10732000000000000000000000000000000000005D +:10733000000000000000000000000000000000004D +:10734000000000000000000000000000000000003D +:10735000000000000000000000000000000000002D +:10736000000000000000000000000000000000001D +:10737000000000000000000000000000000000000D +:1073800000000000000000000000000000000000FD +:1073900000000000000000000000000000000000ED +:1073A00000000000000000000000000000000000DD +:1073B00000000000000000000000000000000000CD +:1073C00000000000000000000000000000000000BD +:1073D00000000000000000000000000000000000AD +:1073E000000000000000000000000000000000009D +:1073F000000000000000000000000000000000008D +:10740000000000000000000000000000000000007C +:10741000000000000000000000000000000000006C +:10742000000000000000000000000000000000005C +:10743000000000000000000000000000000000004C +:10744000000000000000000000000000000000003C +:10745000000000000000000000000000000000002C +:10746000000000000000000000000000000000001C +:10747000000000000000000000000000000000000C +:1074800000000000000000000000000000000000FC +:1074900000000000000000000000000000000000EC +:1074A00000000000000000000000000000000000DC +:1074B00000000000000000000000000000000000CC +:1074C00000000000000000000000000000000000BC +:1074D00000000000000000000000000000000000AC +:1074E000000000000000000000000000000000009C +:1074F000000000000000000000000000000000008C +:10750000000000000000000000000000000000007B +:10751000000000000000000000000000000000006B +:10752000000000000000000000000000000000005B +:10753000000000000000000000000000000000004B +:10754000000000000000000000000000000000003B +:10755000000000000000000000000000000000002B +:10756000000000000000000000000000000000001B +:10757000000000000000000000000000000000000B +:1075800000000000000000000000000000000000FB +:1075900000000000000000000000000000000000EB +:1075A00000000000000000000000000000000000DB +:1075B00000000000000000000000000000000000CB +:1075C00000000000000000000000000000000000BB +:1075D00000000000000000000000000000000000AB +:1075E000000000000000000000000000000000009B +:1075F000000000000000000000000000000000008B +:10760000000000000000000000000000000000007A +:10761000000000000000000000000000000000006A +:10762000000000000000000000000000000000005A +:10763000000000000000000000000000000000004A +:10764000000000000000000000000000000000003A +:10765000000000000000000000000000000000002A +:10766000000000000000000000000000000000001A +:10767000000000000000000000000000000000000A +:1076800000000000000000000000000000000000FA +:1076900000000000000000000000000000000000EA +:1076A00000000000000000000000000000000000DA +:1076B00000000000000000000000000000000000CA +:1076C00000000000000000000000000000000000BA +:1076D00000000000000000000000000000000000AA +:1076E000000000000000000000000000000000009A +:1076F000000000000000000000000000000000008A +:107700000000000000000000000000000000000079 +:107710000000000000000000000000000000000069 +:107720000000000000000000000000000000000059 +:107730000000000000000000000000000000000049 +:107740000000000000000000000000000000000039 +:107750000000000000000000000000000000000029 +:107760000000000000000000000000000000000019 +:107770000000000000000000000000000000000009 +:1077800000000000000000000000000000000000F9 +:1077900000000000000000000000000000000000E9 +:1077A00000000000000000000000000000000000D9 +:1077B00000000000000000000000000000000000C9 +:1077C00000000000000000000000000000000000B9 +:1077D00000000000000000000000000000000000A9 +:1077E0000000000000000000000000000000000099 +:1077F0000000000000000000000000000000000089 +:107800000000000000000000000000000000000078 +:107810000000000000000000000000000000000068 +:107820000000000000000000000000000000000058 +:107830000000000000000000000000000000000048 +:107840000000000000000000000000000000000038 +:107850000000000000000000000000000000000028 +:107860000000000000000000000000000000000018 +:107870000000000000000000000000000000000008 +:1078800000000000000000000000000000000000F8 +:1078900000000000000000000000000000000000E8 +:1078A00000000000000000000000000000000000D8 +:1078B00000000000000000000000000000000000C8 +:1078C00000000000000000000000000000000000B8 +:1078D00000000000000000000000000000000000A8 +:1078E0000000000000000000000000000000000098 +:1078F0000000000000000000000000000000000088 +:107900000000000000000000000000000000000077 +:107910000000000000000000000000000000000067 +:107920000000000000000000000000000000000057 +:107930000000000000000000000000000000000047 +:107940000000000000000000000000000000000037 +:107950000000000000000000000000000000000027 +:107960000000000000000000000000000000000017 +:107970000000000000000000000000000000000007 +:1079800000000000000000000000000000000000F7 +:1079900000000000000000000000000000000000E7 +:1079A00000000000000000000000000000000000D7 +:1079B00000000000000000000000000000000000C7 +:1079C00000000000000000000000000000000000B7 +:1079D00000000000000000000000000000000000A7 +:1079E0000000000000000000000000000000000097 +:1079F0000000000000000000000000000000000087 +:107A00000000000000000000000000000000000076 +:107A10000000000000000000000000000000000066 +:107A20000000000000000000000000000000000056 +:107A30000000000000000000000000000000000046 +:107A40000000000000000000000000000000000036 +:107A50000000000000000000000000000000000026 +:107A60000000000000000000000000000000000016 +:107A70000000000000000000000000000000000006 +:107A800000000000000000000000000000000000F6 +:107A900000000000000000000000000000000000E6 +:107AA00000000000000000000000000000000000D6 +:107AB00000000000000000000000000000000000C6 +:107AC00000000000000000000000000000000000B6 +:107AD00000000000000000000000000000000000A6 +:107AE0000000000000000000000000000000000096 +:107AF0000000000000000000000000000000000086 +:107B00000000000000000000000000000000000075 +:107B10000000000000000000000000000000000065 +:107B20000000000000000000000000000000000055 +:107B30000000000000000000000000000000000045 +:107B40000000000000000000000000000000000035 +:107B50000000000000000000000000000000000025 +:107B60000000000000000000000000000000000015 +:107B70000000000000000000000000000000000005 +:107B800000000000000000000000000000000000F5 +:107B900000000000000000000000000000000000E5 +:107BA00000000000000000000000000000000000D5 +:107BB00000000000000000000000000000000000C5 +:107BC00000000000000000000000000000000000B5 +:107BD00000000000000000000000000000000000A5 +:107BE0000000000000000000000000000000000095 +:107BF0000000000000000000000000000000000085 +:107C00000000000000000000000000000000000074 +:107C10000000000000000000000000000000000064 +:107C20000000000000000000000000000000000054 +:107C30000000000000000000000000000000000044 +:107C40000000000000000000000000000000000034 +:107C50000000000000000000000000000000000024 +:107C60000000000000000000000000000000000014 +:107C70000000000000000000000000000000000004 +:107C800000000000000000000000000000000000F4 +:107C900000000000000000000000000000000000E4 +:107CA00000000000000000000000000000000000D4 +:107CB00000000000000000000000000000000000C4 +:107CC00000000000000000000000000000000000B4 +:107CD00000000000000000000000000000000000A4 +:107CE0000000000000000000000000000000000094 +:107CF0000000000000000000000000000000000084 +:107D00000000000000000000000000000000000073 +:107D10000000000000000000000000000000000063 +:107D20000000000000000000000000000000000053 +:107D30000000000000000000000000000000000043 +:107D40000000000000000000000000000000000033 +:107D50000000000000000000000000000000000023 +:107D60000000000000000000000000000000000013 +:107D70000000000000000000000000000000000003 +:107D800000000000000000000000000000000000F3 +:107D900000000000000000000000000000000000E3 +:107DA00000000000000000000000000000000000D3 +:107DB00000000000000000000000000000000000C3 +:107DC00000000000000000000000000000000000B3 +:107DD00000000000000000000000000000000000A3 +:107DE0000000000000000000000000000000000093 +:107DF0000000000000000000000000000000000083 +:107E00000000000000000000000000000000000072 +:107E10000000000000000000000000000000000062 +:107E20000000000000000000000000000000000052 +:107E30000000000000000000000000000000000042 +:107E40000000000000000000000000000000000032 +:107E50000000000000000000000000000000000022 +:107E60000000000000000000000000000000000012 +:107E70000000000000000000000000000000000002 +:107E800000000000000000000000000000000000F2 +:107E900000000000000000000000000000000000E2 +:107EA00000000000000000000000000000000000D2 +:107EB00000000000000000000000000000000000C2 +:107EC00000000000000000000000000000000000B2 +:107ED00000000000000000000000000000000000A2 +:107EE0000000000000000000000000000000000092 +:107EF0000000000000000000000000000000000082 +:107F00000000000000000000000000000000000071 +:107F10000000000000000000000000000000000061 +:107F20000000000000000000000000000000000051 +:107F30000000000000000000000000000000000041 +:107F40000000000000000000000000000000000031 +:107F50000000000000000000000000000000000021 +:107F60000000000000000000000000000000000011 +:107F70000000000000000000000000000000000001 +:107F800000000000000000000000000000000000F1 +:107F900000000000000000000000000000000000E1 +:107FA00000000000000000000000000000000000D1 +:107FB00000000000000000000000000000000000C1 +:107FC00000000000000000000000000000000000B1 +:107FD00000000000000000000000000000000000A1 +:107FE0000000000000000000000000000000000091 +:107FF0000000000000000000000000000000000081 +:108000000000000000000000000000000000000070 +:108010000000000000000000000000000000000060 +:108020000000000000000000000000000000000050 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:1080800000000000000000000000000000000000F0 +:1080900000000000000000000000000000000000E0 +:1080A00000000000000000000000000000000000D0 +:1080B00000000000000000000000000000000000C0 +:1080C00000000000000000000000000000000000B0 +:1080D00000000000000000000000000000000000A0 +:1080E0000000000000000000000000000000000090 +:1080F0000000000000000000000000000000000080 +:1081000006F0F15506F0F15506F0F15506F0F1557F +:108110001414141514141414141313141313141323 +:10812000141414141414141415141414141414140E +:1081300014141414141414141514151415151514FA +:1081400014141414141414141414141414141414EF +:1081500013141413131313131514141414141415E3 +:1081600013141414131413131514141414141515D0 +:1081700014141414131413141413131314141414C4 +:1081800014141413131413131414131313141414B6 +:1081900014141413131313131313131313131414AA +:1081A0001414141414141414141414131414141490 +:1081B0001414141413131314141413131414141484 +:1081C0001414141414131414141414141414141470 +:1081D0001313131313131313141414141414141566 +:1081E0001413131313131313141414141414141555 +:1081F0001414131413131314131413131313141448 +:108200001413131313131313141414141414141534 +:10821000141313131313131313131413131314142A +:108220001414131313131314141414141414141611 +:1082300015141414141514151616161615151515EF +:1082400014141414141514151515151515151515E4 +:1082500014141414141414141414141414141415DD +:1082600015151415151515151514141414141415C5 +:1082700014141415151514141414151414141415B9 +:1082800014151415151515151515151415141415A3 +:10829000141414151414141414141414141414149D +:1082A0001415141515141514151515151515151582 +:1082B0001514151515141515151515151514151571 +:1082C0001514151515151414141415151515151464 +:1082D0001515151515151515151514141515141551 +:1082E0001515151515151515141314141414141447 +:1082F0001414141414141414151415141515151538 +:10830000141514151414141413141414141414152B +:10831000141414151413131314141414141515151C +:108320001414151514141313141415151515141508 +:1083300016161616161515151515151515151516E7 +:1083400017171818171617161415151515161515CD +:10835000000000000000000000000000000000001D +:10836000000000000000000000000000000000000D +:1083700000000000000000000000000000000000FD +:1083800000000000000000000000000000000000ED +:108390000000000000000000151514151415151537 +:1083A0001514141414141514151515151415151584 +:1083B0001515151415151515151515151415141570 +:1083C0001515151515151515151515151415141460 +:1083D0001515151515151515151414141314131456 +:1083E0001514141415151515151514141314131349 +:1083F0001515151415151516151515141414141531 +:10840000141414131414151515151414131413142B +:10841000141314131414151615141413131313141E +:10842000141313121313141515151414141414140F +:1084300014141414141415161514141413131314FB +:1084400014141414141415161515141413141314E9 +:1084500014141414151415161514141313131313DC +:1084600014141414151415161515141413131313CA +:1084700014151415151415161515141413141314B6 +:1084800013141413141415161514131313131313B0 +:108490001415151515151516151414131313131398 +:1084A000131314131414151616151414131413148B +:1084B000141415141415151716151415151515156E +:1084C0001616161616161617161515151515151552 +:1084D0001515161615161616151515151515151547 +:1084E000151515151515151615161515151515153A +:1084F000151415151515151615151515151515152C +:108500001515151515151616161615161616151514 +:108510001515151515151616151515151515151509 +:1085200015141515151515161516151515151515FA +:1085300015151615151516161615161616151615E3 +:1085400015151515151516161515151515151414DB +:1085500015151615161516161616161516151515C3 +:1085600015151515151516161516161616161515B4 +:1085700014141514151515151515151515151515AE +:108580001515151516161516151515161515151597 +:10859000141514151515151615151515151515158C +:1085A0001515151516161617151516161615151573 +:1085B000151515151616161716161717171616165B +:1085C0001616161616161617171718181816171740 +:1085D00015161616161716160000000000000000EB +:1085E000000000000000000000000000000000008B +:1085F000000000000000000000000000000000007B +:10860000000000000000000000000000000000006A +:10861000000000000000000000000000000000005A +:1086200016151515151615161615141515151515F7 +:1086300016161616161615161616161616161616DB +:1086400016161616151616161616161617161717C8 +:1086500016161616151615151616161616161717BB +:1086600016161616151615161616161616161717AA +:10867000161616161515151516161616171717179A +:10868000161616161515151616151515161616178F +:10869000151616161515151516151616161617177E +:1086A0001616161615151515151515151616161771 +:1086B0001716161616161516161616161616171758 +:1086C000161616161515151516161616171617174B +:1086D0001616161616161616161616161716181736 +:1086E0001616161615151515161616161717171829 +:1086F0001716161616151515161616171717171816 +:108700001716161615161616161616161716171706 +:1087100017161616151615151616161617171718F6 +:1087200017161616151515151615171616161718E9 +:1087300017171616161616161616161616171718D3 +:1087400017171717181818171919191918181819A9 +:10875000171717181818181818181819181818189B +:108760001617171718181717171718181717171895 +:10877000171818181818181818181818181818187A +:10878000171717181818181718181818181818186D +:108790001818181919181818181819191918181953 +:1087A0001817181818181718171717181817171850 +:1087B0001818181818181818181819181918191935 +:1087C0001818181819181818181818191919181924 +:1087D0001818181819181818181819191919191912 +:1087E0001818191919191818181818181919181803 +:1087F00018191919191819181717181719181818F6 +:1088000018181818181818181818191919191919E2 +:108810001818191A181818181718181818181819D5 +:108820001819191919181818181819191919191ABD +:1088300018191A1A19191818191919191A1A191AA6 +:108840001A1A1B1B1B1A19191919191B1A1A1A1A89 +:108850001C1C1C1D1C1B1C1A191A1A1A1B1B1A1A69 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800000000000000000000000000000000000E8 +:1088900000000000000000000000000000000000D8 +:1088A000000000000000000018181718171718180B +:1088B0001816161717161717191818181718181842 +:1088C000181818181818191818181818171717172B +:1088D0001818181818191819181918181718171817 +:1088E0001918191919191919181918171717161706 +:1088F00018181819191819191919181817181717F5 +:108900001819181919191A191719181817181717E3 +:1089100018181818191819181819181817181717D7 +:108920001818181818191A1A1918181817171718C4 +:1089300018171716181819191919181818171818B8 +:1089400019171818191919191919191817171718A3 +:108950001818171819181B1A191919181717171892 +:10896000181819191A191A19191918171717161783 +:108970001918191819191A191A191918181817176E +:1089800019191919181819191A1918181818171760 +:108990001818181718181A191A1818171717161759 +:1089A00018191918191919191A1918181717161743 +:1089B000181819171818191B1A1A1918181817182F +:1089C000181819191919191B191919191B1B1A1912 +:1089D0001B1B1B1C1A1B1A1B1A191A191A1A1A1AF2 +:1089E000191A1A1B1A1A1A1A191A1A1A1B1A1A1AE7 +:1089F0001A191A1A1A1A1A1B1A1A1A1A1B1A1A1AD6 +:108A00001A1A1A1A1A1A1A1B1A1A1B1A1B1A1A1AC3 +:108A1000191A1A1B1A1A1A1B1A1A1A1B1B1A1B1AB2 +:108A20001A1A1B1A1A1A1A1B1A1A1B1A1A1A1A1AA3 +:108A30001A1A1A1B1A1A1A1A1A1A1B1B1B1A1A1A92 +:108A40001A1A1B1A1A1B1A1B1B1A1B1C1C1B1A1B7B +:108A50001A1A1B1A1B1B1B1B1A1B1B1B1B1A1A196E +:108A60001A1A1B1B1B1B1B1B1B1B1B1C1B1A1B1A59 +:108A70001A1A1A1B1B1B1B1B1A1C1B1C1C1B1C1A47 +:108A800019191A1A1C1B1A1A1A1B1B1B1A1A1A1943 +:108A90001A1B1B1B1C1B1B1B1B1B1B1B1B1B1B1A27 +:108AA0001A1A1A1B1C1B1B1C1A1C1B1C1C1B1B1B15 +:108AB0001B1C1B1C1C1D1D1D1B1C1D1D1D1C1B1BF5 +:108AC0001C1C1C1D1E1D1D1D1D1E1E1E1E1E1D1DD3 +:108AD0001C1C1D1E1E1D1D1E1F1E201F1E1E1F1EB8 +:108AE0001C1C1D1D1D1E1D1E00000000000000009E +:108AF0000000000000000000000000000000000076 +:108B00000000000000000000000000000000000065 +:108B10000000000000000000000000000000000055 +:108B20000000000000000000000000000000000045 +:108B300005020101F401D00700000000240210002A +:108B400000064A5900000000B0568EEE4423000093 +:108B5000EB1E00000C1F00002D1F00004E1F000028 +:108B60006F1F000000000000000000001B03000059 +:108B70002088410AE62000000000000000000000FC +:108B80000000000000240000202020200502020236 +:108B90005200000000000000010000000000000082 +:108BA000000000000000000000000000D21F3E2076 +:108BB0006A20302105224E21F621F52200B8C30794 +:108BC000D638000000000000000010055805A00580 +:108BD000E80500001040040D0F0B0D0D10000E11E4 +:108BE000A5BB031F7EF80F00130F130F0F430F4396 +:108BF0001B0300000A00000000000000000000004D +:108C0000000000000000000000040000030000005D +:108C10000000000000000000000000000200000052 +:108C20000000000000000000000000000000000044 +:108C3000D21F3E206A20302105224E21F621F52246 +:108C400000B8C307D6380000000000000000000094 +:108C500048009000D80000001040040D0F0B0D0DCF +:108C600010000E11A5BB031F7EF80F00130F130F8A +:108C70000F430F431B0300002088410AE620000039 +:108C800000000000000000000000000000240000C0 +:108C9000272727277572727252000000000000001B +:108CA0006366666666666666660000000000000031 +:108CB00000000000D21F3E206A20302105224E21F4 +:108CC000F621F52200B8C307D638000000000000E6 +:108CD000000010055805A005E80500001040040D2F +:108CE0000F0B0D0D10000E11A5BB031F7EF80F001A +:108CF000130F130F0F430F431B0300008B35F72097 +:108D00000000000000000000000000000000000063 +:108D100000180000202020000000000000000000DB +:108D20000000000011111100000000000000000010 +:108D30000000000000000000D21F3E206A20302109 +:108D400005224E21F621F52200B8C307D6380000CF +:108D5000000000000000000048009000D800000063 +:108D60001040040D0F0B0D0D10000E11A5BB031FBD +:108D70007EF80F00130F130F0F430F431B03000068 +:108D80008B35F7200A000000000000000000000002 +:108D900000000000001C000027272705000000003D +:108DA0000000000000000000333333020000000028 +:108DB000000000000000000000000000D21F3E2064 +:108DC0006A20302105224E21F621F52200B8C30782 +:108DD000D6380000000000000000000048009000AD +:108DE000D80000001040040D0F0B0D0D10000E11E7 +:108DF000A5BB031F7EF80F00130F130F0F430F4384 +:108E00000000000000000000000000000000000062 +:108E10000000000000000000000000000000000052 +:108E20000000000000000000000000000000000042 +:108E30000000000000000000000000000000000032 +:108E40000000000000000000000000000000000022 +:108E50000000000000000000000000000000000012 +:108E60000000000000000000000000000000000002 +:108E700000000000000000000000000000000000F2 +:108E800000000000000000000000000000000000E2 +:108E900000000000000000000000000000000000D2 +:108EA00000000000000000000000000000000000C2 +:108EB00000000000000000000000000000000000B2 +:108EC00000000000000000000000000000000000A2 +:108ED0000000000000000000000000000000000092 +:108EE0000000000000000000000000000000000082 +:108EF0000000000000000000000000000000000072 +:108F0000000000000000000000000000090900014E +:108F10000128000000D8030012000000A51D020077 +:108F200000000000000002020228000000D8030038 +:108F30000F000000A61D0000000000000101020259 +:108F40000328000000D803000E000100A71D000048 +:108F500000000000020202020428000000D8030002 +:108F60000D000200A81D0000000000000303020223 +:108F70000528000000D803000C000300A91D000014 +:108F800000000000040402020628000000D80300CC +:108F90000B000400AA1D00000000000005050202ED +:108FA0000728000000D803000A000500AB1D0000E0 +:108FB00000000000060602020828000000D8030096 +:108FC00009000600AC1D00000000000007070202B7 +:108FD0000928000000D8030008000700AD1D0000AC +:108FE00000000000080802020A28000000D8030060 +:108FF00000000000AE1D0000000000000A09000192 +:109000000028000000D8030092148014A51D000061 +:1090100000000000090900010028000000D803003A +:1090200012000000A51D0200000000000909000157 +:109030000028000000D80300A2009000A61D020036 +:1090400000000000090900010028000000D803000A +:1090500032012001A71D02000000000009090001E3 +:109060000028000000D80300C201B001A81D0200C2 +:1090700000000000090900010028000000D80300DA +:1090800052024002A91D020000000000090900016F +:109090000028000000D80300E202D002AA1D02004E +:1090A00000000000090901000028000000D80300AA +:1090B00080149214000002000F00000005B40500A7 +:1090C0005D4C1B00610000000C0000000500040066 +:1090D0001529000060000000000000000D004000A5 +:1090E000152900001E000000030000000DFC4300D5 +:1090F000FFFE1B001F000000000000000DFC4300ED +:10910000FFFE1B001F000000030000000DB4410023 +:109110005D4C1B001F000000000000000DB441006A +:109120005D4C1B001F0000000F00000001B4050093 +:109130005D4C1B00E10001000C0000000100040078 +:1091400015290000E0000100000000000D004000B3 +:10915000152900001E0000000F00000005FC07009C +:10916000FFFE1B00610000001D1D861D1C1D1D1D36 +:109170001D1D1E1E1D1D1D1E1D1D1D1D1D1D1D1D1C +:109180001D1D1D1D1D1D1D1D1C1D1D1D1E1D1D1D0F +:109190001D1D1C1D1D1D1D1D1D1C1D1E1D1D1D1D00 +:1091A0001E1D1D1D1D1D1C1D1D1D1E1D1D671D1DA4 +:1091B0001D1D1D1D1C1C1D1D1D1D1D1E1D1D1C1EE0 +:1091C0001D1D1D1D1C1D1D1D1D1D1D1D1D1D1D1DD0 +:1091D0001C1D1D1D1D1D1D1D1D1C1B1D1D1D1C1DC4 +:1091E0001C1C1D1E1D1D1D1D1D1D1D1D1D1D1C1DB1 +:1091F0001D1D1D1D1D1D1D1D1D1D1D1D1C1D1D1DA0 +:109200001D1D1D1E1D1D1C1E1D1D1D1D1D1D1D1D8D +:109210001D1D1D1D1D1D1D1D1C1D1D1D1D1D1D1D7F +:109220001D1D1B1D1D1D1C1D1C1C1D1E1D1D1D1D72 +:109230001D1D1D1D1D1D1C1D1D1D1D1D1D1D1D1D5F +:109240001D1D1D1D1C1D1D1D1D1D1D1E1D1D1C1E4E +:109250001D1D1D1D1C1D1D1D1D1D1D1D1D1D1D1D3F +:109260001C1D1D1D1D1D1D1D1D1C1B1D1D1D1C1D33 +:109270001C1C1D1E1D1D1D1D1D1D1D1D1D1D1C1D20 +:109280001D1D1E1D1D1D1D1D1D1D1D1D1C1D1D1D0E +:109290001D1D1D1E1D1D1C1E1D1D1D1D1C1D1D1DFE +:1092A0001D1D1D1D1D1D1D1D1C1D1D1D1E1D1D1DEE +:1092B0001D1D1B1D1D1D1C1D1C1C1D1E1D1D1D1DE2 +:1092C0001D1D1D1D1D1D1C1D1D1D1D1D1D1D1D1DCF +:1092D0001D1D1D1D1D1D1D1D1D1D1E1E1D1D1C1DBD +:1092E0001D1D1D1D1C1D1D1D1D1D1D1D1D1D1D1DAF +:1092F0001C1D1D1D1D1D1D1D1D1D1B1D1D1D1C1DA2 +:109300001C1C1D1E1D1D1D1D1D1C1D1D1D1C1C1D91 +:109310001D1D1E1D1D1D1D1D1D1D1D1D1D1D1D1E7B +:109320001D1D1E1E1D1D1C1E1D1D1D1D1C1D1D1D6C +:109330001D1D1D1D1D1D1D1D1C1D1D1D1D1D1D1D5E +:109340001D1D1B1D1D1D1C1D1C1C1D1E1D1D1D1D51 +:109350001D1D1D1D1D1D1C1D1D1D1E1D1D1D1D1D3D +:109360001E1D1D1D1D1D1D1E1E1D1E1E1E1D1C1E27 +:109370001E1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1C +:109380001D1D1D1D1E1D1D1D1D1D1C1D1D1D1D1D0D +:109390001D1C1D1E1D1D1D1D1D1D1D1D1D1D1D1DFD +:1093A0001D1D1E1D1D1D1E1D0000000000000000D3 +:1093B00000000000000000000000000000000000AD +:1093C000000000000000000000000000000000009D +:1093D000000000000000000000000000000000008D +:1093E000000000000000000000000000000000007D +:1093F000323232323232323232323232323232324D +:10940000323232323232323232323232323232323C +:10941000323232323232323232323232323232322C +:10942000323232323232323232323232323232321C +:10943000323232323232323235358B35353534359F +:1094400035353536353533363535353533353535CE +:1094500035353535353535353434353535353535BE +:1094600033343335333434353333353634353535B9 +:10947000353535363333353633353635339F353735 +:10948000B66DB66DB605B60500000000B66DB66DDA +:10949000B60CB60C00000000B66DB66D960D960DBC +:1094A00000000000B66DB66DB20DB20D00000000F8 +:1094B000B62DB62DB60DB60D00000000B665B6652A +:1094C000B60DB60D00000000B66CB66CB60DB60D4C +:1094D00000000000966D966DB60DB60D0000000000 +:1094E000B26DB26DB60DB60D00000000922492244C +:1094F000920492040000000001100000000000002F +:1095000000000000FFFF3DDB38D4FC020200FF003A +:109510006C768A94DB060000040C0000A003570060 +:1095200036E60802010000003E03E600477EEC1428 +:10953000FFFF00801CC40C570380BBBB804422008B +:109540006415641588398A3935003500011000002A +:109550000000000000000000FFFF3DDB38D4FC02EB +:109560000200FF006C768A94DB060000040C000009 +:10957000A003570036E60802410002003E03E60061 +:10958000477EEC14FFFF00801CC40C17E38EBBBBAE +:10959000805522006415641588398A3935003500F4 +:1095A00001040000000000000000000000000000B6 +:1095B000000000020200FF006C768A94DB060000C7 +:1095C000040C0000B803570036EC0802010000004C +:1095D0005603EC00477EEC14FFFF00801C040C5780 +:1095E0000380BBBB804522006415641588398A3925 +:1095F000350035008304020001020304E0EC37FB70 +:10960000528BE4C5CF0304021E06AA036C768A942B +:10961000DB060000014500008C0E000000EC080293 +:10962000410002000000EC00477EEC14FFFF0080C8 +:109630001C5C11970080BBBB0057220064D164D131 +:1096400088198A19350035008304020001010101DF +:10965000E0EC37FB528BE4C5CF0304020206AA00FC +:109660006C768A94DB060000014500008C0E000039 +:1096700000EC0802410002000000EC00437D531A98 +:10968000FFFF00801C5C11BF0080BBBB00462200B6 +:1096900064D164D188398A393500350083040200E9 +:1096A00002020202E0EC37FB528BE4C5CF03040256 +:1096B0000206AA006C768A94DB06000001450000D1 +:1096C0008C0E000000EC0802410002000000EC00DB +:1096D000A87D6018FFFF00801C5C11BF0080BBBB31 +:1096E0000046220064D164D188398A3935003500BA +:1096F0008304020003030303E0EC37FB528BE4C551 +:10970000CF0304020206AA006C768A94DB060000EE +:10971000014500008C0E000000EC08024100020030 +:109720000000EC006C7E0614FFFF00801C5C11BF83 +:109730000080BBBB0046220064D164D188398A39DD +:10974000350035008304020004040404E0EC37FB18 +:10975000528BE4C5CF0304020206AA006C768A94F9 +:10976000DB060000014500008C0E000000EC080242 +:10977000410002000000EC00ED7E8610FFFF00803B +:109780001C5C11BF0080BBBB0046220064D164D1C9 +:1097900088398A393500350000005D3F0000DA471E +:1097A000C0CED0C716219CD1548694083C0E0F061B +:1097B00079CACDFCD820EF99FACECFC5FD962E51AF +:1097C0005361DF9F3B0F0F04F43CFA883C803CD48C +:1097D000390F0E032494600227A090022AACC00225 +:1097E0002DB8F00230C4200333D05003124C400196 +:1097F000155870011864A0011B70D0011E7C000276 +:1098000021883002124C4001155870011864A001E3 +:109810001B70D0011E7C0002218830020004200051 +:1098200003105000061C80000928B0000C34E00032 +:109830000F40100120C10414508105178041061A01 +:10984000B001071DE0C1072010820823004000027C +:109850003000010560C001089080020BC040030E7B +:10986000F000041120C00004508001078040020A6B +:10987000B000030DE0C00310108104134041051631 +:1098800070010619A0C1061CD081071F00420822E2 +:1098900030020001004000023000010560C00108F4 +:1098A0009080020BC040030EF000041120C104148C +:1098B000508105178041061AB001071DE0C107203D +:1098C000108208237796392541BED8210BE6771EF2 +:1098D000D50D171B9F35B617695D55143385F410E8 +:1098E000FDAC930DC7D4320A91FCD1065B24710301 +:1098F000254C100085CE19264FF6B822191E581F88 +:10990000E345F71BAD6D96187795351541BDD4111C +:109910000BE5730ED50C130B9F34B207695C510431 +:109920003384F000789A492542C2E8210CEA871E68 +:10993000D611271BA039C6176A6165143489041132 +:10994000FEB0A30DC8D8420A9200E2065C2881034B +:109950002650200084CA09264EF2A822181A481F51 +:10996000E241E71BAC6986187691251540B9C41110 +:109970000AE1630ED408030B9E30A2076858410425 +:109980003280E000799E592543C6F8210DEE971EDE +:10999000D715371BA13DD6176B657514358D14117E +:1099A000FFB4B30DC9DC520A9304F2065D2C910397 +:1099B0002754300083C6F9E54DEE98E21716381F9C +:1099C000E13DD71BAB6576D8758D15153FB5B41144 +:1099D00009DD530ED304F30A9D2C9207675431041A +:1099E000317CD0007AA2692544CA08220EF2A71E53 +:1099F000D819471BA241E6176C69851436912411CA +:109A000000B9C30DCAE0620A940802075E30A103E0 +:109A10002858400082C2E9254CEA88221612281FE5 +:109A2000E039C71BAA616618748905153EB1A411F7 +:109A300008D9430ED200E30A9C288207665021040D +:109A40003078C0007BA6792545CE18220FF6B71EC8 +:109A5000D91D571BA345F6176D6D95143795341115 +:109A600001BDD30DCBE4720A950C12075F34B1032C +:109A7000295C500081BED9254BE67822150E181FAF +:109A8000DF35B71BA95D56187385F5143DAD9411EC +:109A900007D5330ED1FCD20A9B247207654C110402 +:109AA0002F74B0007CAA892546D2282210FAC71E3E +:109AB000DA21671BA44906186E71A5143899441160 +:109AC00002C1E30DCCE8820A961022076038C10378 +:109AD0002A60600080BAC9254AE26822140A081F79 +:109AE000DE31A71BA85946187281E5143CA98411E0 +:109AF00006D1230ED0F8C20A9A20620764480104F6 +:109B00002E70A0007DAE992547D6382211FED71EB3 +:109B1000DB25771BA54D16186F75B514399D5411AB +:109B200003C5F30DCDEC920A97143207613CD103C3 +:109B30002B6470007FB6B92549DE58221306F81E43 +:109B4000DD2D971BA7553618717DD5143BA57411D3 +:109B500005CD130ECFF4B20A991C52076344F103EA +:109B60002D6C90007EB2A92548DA48221202E81E28 +:109B7000DC29871BA65126187079C5143AA16411F7 +:109B800004C9030ECEF0A20A981842076240E1030E +:109B90002C688000000000000000000000000000B1 +:109BA00000000000000000000000000000000000B5 +:109BB00000000000000000000000000000000000A5 +:109BC0000000000000000000000000000000000095 +:109BD0000000000000000000000000000000000085 +:109BE0000000000000000000000000000000000075 +:109BF0000000000000000000000000000000000065 +:109C00000000000000000000000000000000000054 +:109C10000000000000000000000000000000000044 +:109C20000000000000000000000000000000000034 +:109C30000000000000000000000000000000000024 +:109C40000000000000000000000000000000000014 +:109C50000000000000000000000000000000000004 +:109C600000000000000000000000000000000000F4 +:109C700000000000000000000000000000000000E4 +:109C800000000000000000000000000000000000D4 +:109C900000000000000000000000000000000000C4 +:109CA00000000000000000000000000000000000B4 +:109CB00000000000000000000000000000000000A4 +:109CC0000000000000000000000000000000000094 +:109CD0000000000000000000000000000000000084 +:109CE0000000000000000000000000000000000074 +:109CF0000000000000000000000000000000000064 +:109D00000000000000000000000000000000000053 +:109D10000000000000000000000000000000000043 +:109D20000000000000000000000000000000000033 +:109D30000000000000000000000000000000000023 +:109D40000000000000000000000000000000000013 +:109D50000000000000000000000000000000000003 +:109D600000000000000000000000000000000000F3 +:109D700000000000000000000000000000000000E3 +:109D800000000000000000000000000000000000D3 +:109D900000000000000000000000000000000000C3 +:109DA00000000000000000000000000000000000B3 +:109DB00000000000000000000000000000000000A3 +:109DC0000000000000000000000000000000000093 +:109DD0000000000000000000000000000000000083 +:109DE0000000000000000000000000000000000073 +:109DF0000000000000000000000000000000000063 +:109E00000000000000000000000000000000000052 +:109E10000000000000000000000000000000000042 +:109E20000000000000000000000000000000000032 +:109E30000000000000000000000000000000000022 +:109E40000000000000000000000000000000000012 +:109E50000000000000000000000000000000000002 +:109E600000000000000000000000000000000000F2 +:109E700000000000000000000000000000000000E2 +:109E800000000000000000000000000000000000D2 +:109E900000000000000000000000000000000000C2 +:109EA00000000000000000000000000000000000B2 +:109EB00000000000000000000000000000000000A2 +:109EC0000000000000000000000000000000000092 +:109ED0000000000000000000000000000000000082 +:109EE0000000000000000000000000000000000072 +:109EF0000000000000000000000000000000000062 +:109F00000000000000000000000000000000000051 +:109F10000000000000000000000000000000000041 +:109F20000000000000000000000000000000000031 +:109F300008F71024380460090E0A00010100081017 +:109F4000240040046C090000000C00000000000028 +:109F500000004A590000000000000000000801094C +:109F60000001444340020000282221008004000038 +:109F700080040000800400008004000080040000D1 +:109F800080040000800400008004000000FA030048 +:109F900080040000800400008004000000FA030038 +:109FA0008004000080040000800400000000000025 +:109FB000000101000000000000000000000000009F +:109FC000000000000000000000000101010101008C +:109FD0000001010101010101010100010000010076 +:109FE00001000000000000000F0000000107010355 +:109FF00002030A00320A400000003200370000006D +:10A000000000000000000000000000000000000050 +:10A010000000000000000000C800C8009600C80052 +:10A020000707800080000505000000000000000018 +:10A0300007010000DBFF00004100F1FF10001400E9 +:10A04000F9FFC4FFFF7FFF7FFF7FFF7F96002C019A +:10A0500096003C000A04CECE3232280500000000F3 +:10A0600000070D0000240D0000000010242424240B +:10A0700024242424242424242424242424240000E8 +:10A0800000000000000000000000000000000000D0 +:10A090000A05000A0000000020010014111400004D +:10A0A00000000000000000000000000000000000B0 +:10A0B000000000000F23283C465000006E696664D3 +:10A0C0005050505008000000000000000F23283CB2 +:10A0D000465000006E696664505050500F141E28A0 +:10A0E000000000000A0A0A0A0A0A0A0A0F1E32467B +:10A0F00000000000645F553C3C3C3C3C000000001C +:10A1000008081A00A000EAFF1E009D008300100E40 +:10A1100000000000001000003C0032009001280008 +:10A120000F000F001C023D011C02740400003704E4 +:10A1300000005F09F4010000370400005F093214D9 +:10A14000021E1E3202009B00280028007700C00378 +:10A150007700E8080000000040043000050001001E +:10A1600007000000410028012402200309043F04E5 +:10A1700000000000000000000000000000000000DF +:10A1800000000000000000000000000000000000CF +:10A1900000000000000000000000000000000000BF +:10A1A00000000000000000000000000000000000AF +:10A1B000000000000000000000000000000000009F +:10A1C000000000000000000000000000000000008F +:10A1D000000000000000000000000000000000007F +:10A1E000000000000000000000000000000000006F +:10A1F000000000000000000000000000000000005F +:10A20000000000000000000000000000000000004E +:10A21000000000000000000000000000000000003E +:10A22000000000000000000000006C093000050084 +:10A230000100070000003B006E02BC040B073F0951 +:10A240006B0900000000000000000000000000009A +:10A2500000000000000000000000000000000000FE +:10A2600000000000000000000000000000000000EE +:10A2700000000000000000000000000000000000DE +:10A2800000000000000000000000000000000000CE +:10A2900000000000000000000000000000000000BE +:10A2A00000000000000000000000000000000000AE +:10A2B000000000000000000000000000000000009E +:10A2C000000000000000000000000000000000008E +:10A2D000000000000000000000000000000000007E +:10A2E000000000000000000000000000000000006E +:10A2F000000000000000000000000000000000005E +:10A3000002020500F16C0000409C000000F91500FD +:10A3100029B1010010270000C4090000010101015A +:10A32000010101010101014B0F0055000000000077 +:10A33000020101010101010101010100F16C0000B4 +:10A340000200000084DE0100000000000F0F0A0A76 +:10A3500028000000000000000F0F1414010101018B +:10A36000010140003200E8030F0008000500E10091 +:10A3700000001E288C00B40019006400640028004E +:10A380007800000000000000B4007800E8034006F8 +:10A3900000000001410100000000000068010D0DF7 +:10A3A0000A092D0019006400140064002C016400E7 +:10A3B0002C010F02E8E8F800F8000804190000007A +:10A3C000A500B300C300D400E700FA000F01260186 +:10A3D0003E01570172018F01AE01CF01F10116025A +:10A3E0003C0265029002BD02ED021E035203890386 +:10A3F000C203FE033C047C04BF0405054D0598051B +:10A40000E50535068706DB0632078A07E5074208B9 +:10A41000A10801096309C7092C0A920AF90A600B0D +:10A42000C80B310C9A0C020D6B0DD20D390E9F0E1C +:10A43000040F670FC80F27108410DE103511891123 +:10A44000DA1128127112B712F81235136D13A01316 +:10A45000CF13F8131C143B145414681476147E1490 +:10A460008114DB00ED0000011401290140015801B5 +:10A4700072018D01A901C801E8010A022D025202F0 +:10A480007A02A302CE02FB022A035C038F03C503F8 +:10A49000FD0336047304B104F10434057805BF05E7 +:10A4A00008065306A006EF063F079207E6073B089B +:10A4B0009308EB084509A009FC09580AB60A140BD1 +:10A4C000720BD10B2F0C8D0CEB0C490DA50D010E51 +:10A4D0005B0EB40E0C0F610FB50F06105510A110D6 +:10A4E000EA1031117411B411F01128125D128D129D +:10A4F000B912E112051324133E135413651371139B +:10A5000078137B136A00750081008E009D00AC00FB +:10A51000BD00CF00E200F7000D01260140015C0103 +:10A5200079019901BC01E001060230025B02890257 +:10A53000BA02EE0224035D039A03D9031B046004EC +:10A54000A904F40443059505E90541069C06FA06AD +:10A550005B07BE0724088D08F8086509D409450A79 +:10A56000B80A2D0BA20B190C900C080D800DF80DDC +:10A570006F0EE60E5C0FD00F4210B31021118C113C +:10A58000F4115912BA1217137013C41313145D1473 +:10A59000A114E01418154B1577159C15BB15D4158F +:10A5A000E515EF15F315A500B300C300D400E700CF +:10A5B000FA000F0126013E01570172018F01AE0121 +:10A5C000CF01F10116023C0265029002BD02ED02CC +:10A5D0001E0352038903C203FE033C047C04BF0430 +:10A5E00005054D059805E50535068706DB063207A6 +:10A5F0008A07E5074208A10801096309C7092C0A6F +:10A60000920AF90A600BC80B310C9A0C020D6B0D03 +:10A61000D20D390E9F0E040F670FC80F271084103C +:10A62000DE1035118911DA1128127112B712F812E1 +:10A6300035136D13A013CF13F8131C143B145414CB +:10A64000681476147E148114550055004B004700A1 +:10A650000000000055008700DC0014000500000029 +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000008000000B2 +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A93000050201010000000000000000240104776E +:10A940000002335900000000000000000000000079 +:10A950006726000088260000A92600001A030000D0 +:10A96000410C520C07010000000000000000000034 +:10A97000000000000020000031313131252020206E +:10A980002020000000000000000000000000000087 +:10A99000000000000000000000000000CA2642275E +:10A9A00066272C28492968283A29392A00B8C3077C +:10A9B0007E17000000000000000010055805A005EB +:10A9C000E80500001040040C0E0B0C0C10000E10DB +:10A9D000A5BA031F7CC60F00100D100D0D410D41CF +:10A9E0001A0300008B35F720510200000000000020 +:10A9F00000000000000000000020000020202020B7 +:10AA0000252020202020000000000000111111113D +:10AA10001100000000000000000000000000000025 +:10AA2000CA26422766272C28492968283A29392A24 +:10AA300000B8843A7E1700000000000000001005F6 +:10AA40005805A005E80500001040040C0E0B0C0C86 +:10AA500090000E10A5BB831FFCC90F00100D100D38 +:10AA60000D410D411A0300008B35F72051C9090033 +:10AA700000000000000000000000000000280000AE +:10AA80002727272725272727272700000000000042 +:10AA900066666656660000000000000000000000C8 +:10AAA00000000000CA26422766272C28492968286A +:10AAB0003A29392A00B8C3077E17000000000000B9 +:10AAC000000010055805A005E80500001040040C22 +:10AAD0000E0B0C0C90000E10A5BB831FFCC90F00C1 +:10AAE000100D100D0D410D4100000000090901007D +:10AAF0000028000000A8030000000000A51D0200BF +:10AB000000000000000002020028000080AA0300EC +:10AB100008000000A61D0000000000000101020264 +:10AB20000028000080AA030009000100A71D000002 +:10AB300000000000020202020028000080AA0300B8 +:10AB40000A000200A81D000000000000030302022A +:10AB50000028000080AA03000B000300A91D0000CC +:10AB600000000000040402020028000080AA030084 +:10AB70000C000400AA1D00000000000005050202F0 +:10AB80000028000080AA03000D000500AB1D000096 +:10AB900000000000060602020028000080AA030050 +:10ABA0000E000600AC1D00000000000007070202B6 +:10ABB0000028000080AA03000F000700AD1D000060 +:10ABC00000000000080803120028000080AA03000B +:10ABD00000000000AE1D000000000000091301008D +:10ABE0000028000000A8030000000000A51D0200CE +:10ABF00000000000000A02020028000080A80300F4 +:10AC000008000000A61D000000000000010B020269 +:10AC10000028000080A8030009000100A71D000013 +:10AC200000000000020C02020028000080A80300BF +:10AC30000A000200A81D000000000000030D02022F +:10AC40000028000080A803000B000300A91D0000DD +:10AC500000000000040E02020028000080A803008B +:10AC60000C000400AA1D000000000000050F0202F5 +:10AC70000028000080A803000D000500AB1D0000A7 +:10AC800000000000061002020028000080A8030057 +:10AC90000E000600AC1D00000000000007110202BB +:10ACA0000028000080A803000F000700AD1D000071 +:10ACB00000000000081202020028000080A8030023 +:10ACC00000000000AE1D00000F000000016C041425 +:10ACD00087F21B00610000000F000000016C0414EB +:10ACE00030441B00610000000000000029007014C7 +:10ACF00064C700001E00000000000000290070145E +:10AD0000152900001E00000000000000296C7014CE +:10AD100030441B001F00000003000000296C701469 +:10AD200030441B001F00000000000000296C70145C +:10AD300030441B001F0000000F000000016C0414D1 +:10AD400030441B00E10001000C000000010004146D +:10AD500015290000E00001000000000000000000D4 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF0000000000000000000000000000000000051 +:10B000000000000000000000000000000000000040 +:10B010000000000000000000000000000000000030 +:10B020000000000000000000000000000000000020 +:10B030000000000000000000000000000000000010 +:10B040000000000000000000000000000000000000 +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B07000144924492409240500000000A448244957 +:10B080002409A408000000002445244924091409C7 +:10B09000000000002429244924092209000000009E +:10B0A00024492429220924090000000024492445B8 +:10B0B00014092409000000002449A448A408240914 +:10B0C0000000000024491449240524090000000060 +:10B0D00024492249240524090000000092249224D6 +:10B0E0009204920400000000966DB66DB60DB60590 +:10B0F00000000000B66CB66DB60DB60C0000000086 +:10B10000B665B66DB60D960D00000000B62DB66D95 +:10B11000B60DB20D00000000B66DB62DB20DB60D25 +:10B1200000000000B66DB665960DB60D000000007B +:10B13000B66DB66CB60CB60D00000000B66D966D1F +:10B14000B605B60D00000000B66DB26DB605B60DC1 +:10B150000000000092249224920492040000000057 +:10B1600001280000000000000000000000000000B6 +:10B17000000000020206FF006C768A94DB060000E5 +:10B180000106000041015700363C090201000000A1 +:10B19000E1003C01477EEC14FFFF00801C7C0F5750 +:10B1A0000380BBBB8E5C22006401640188398A394C +:10B1B0000000000001280000000000000000000066 +:10B1C00000000000000000020206FF006C768A9476 +:10B1D000DB06000001060000F100570036EC080213 +:10B1E000010000009100EC00477EEC14FFFF00809E +:10B1F0001C040C570380ABAA804422006411641124 +:10B2000088398A3905000500012800000000000087 +:10B210000000000000000000000000020206FF0025 +:10B220006C768A94DB06000001060000610057007E +:10B23000365C08020100000001005C00477EEC144F +:10B24000FFFF00801C240C570380ABAA804422001F +:10B250006411641188398A3905000500012800004D +:10B2600000000000000000000000000000000002DC +:10B270000200FF006C768A94DB06000001060000E5 +:10B28000F100570036EC0802410002009100EC008A +:10B29000477EEC14FFFF00801CC40C17E38EBBBB81 +:10B2A000805522006411641188398A39050005002F +:10B2B0000104000000000000000000000000000089 +:10B2C000000000020200FF006C768A94DB0600009A +:10B2D000040C0000B803570036EC0802010000001F +:10B2E0005803EC00477EEC14FFFF00801CE00C5775 +:10B2F0000380BBBB804522006411641188398A3900 +:10B30000050005009404020001020304D6F042FC8B +:10B310001C6005AFCF0304021E0600036C768A94FE +:10B32000DB06000001C50000D20F000000EC08029F +:10B33000410002000000EC00477EEC14FFFF00809B +:10B340001CC411170080BBBB00572200641164119C +:10B3500088198A1905000500940402000101010101 +:10B36000D6F042FC1C6005AFCF03040202060000C9 +:10B370006C768A94DB06000001C50000D20F000045 +:10B3800000EC0802410002000000EC007278512B32 +:10B39000FFFF00801CC4113F0080BBBB00462200A1 +:10B3A0006411641188398A3905000500940402008B +:10B3B00002020202D6F042FC1C6005AFCF03040279 +:10B3C000020600006C768A94DB06000001C50000CE +:10B3D000D20F000000EC0802410002000000EC0067 +:10B3E000BB7BC520FFFF00801CC4113F0080BBBB9E +:10B3F000004622006411641188398A39050005006D +:10B400009404020003030303D6F042FC1C6005AF62 +:10B41000CF030402020600006C768A94DB0600006B +:10B4200001C50000D20F000000EC0802410002003C +:10B430000000EC00197EFC15FFFF00801CC4113FCA +:10B440000080BBBB004622006411641188398A3930 +:10B45000050005009404020004040404D6F042FC34 +:10B460001C6005AFCF030402020600006C768A94CC +:10B47000DB06000001C50000D20F000000EC08024E +:10B48000410002000000EC00867F080BFFFF0080F7 +:10B490001CC4113F0080BBBB004622006411641134 +:10B4A00088398A390500050000005D3F0000DA4751 +:10B4B000C0CED0C7FFFF47020000A1503F0D3009AA +:10B4C000FFFF244B00009F30FFCEF0C7FFFFDF3BA4 +:10B4D000000047E43F0F3004FFFFABCE0000C5790A +:10B4E0003F0F300220C208001080000340400106D8 +:10B4F00070000209A0C0020CD080030F00410412AA +:10B500003001051560C105189081061BC041071E5A +:10B51000F001082120C00004508001078040020A89 +:10B52000B000030DE0C00310108104134041051664 +:10B5300070010619A0C1061CD081071F0042082215 +:10B540003002000120C10414508105178041061A01 +:10B55000B001071DE0C1072010820823004000024F +:10B560003000010560C001089080020BC040030E4E +:10B57000F000041100486027644A09242E72A820B4 +:10B58000F899471DC2C1E6198CE985165611251395 +:10B590002039C40FEA60630CB48802097EB0A105AB +:10B5A00048D8400286D2292650FAC8221A22681F9B +:10B5B000E449071CAE71A6187899451542C1E411FB +:10B5C0000CE9830ED610230BA038C2076A60610411 +:10B5D000348800017796392541BED8210BE6771EC5 +:10B5E000D50D171B9F35B617695D55143385F410BB +:10B5F000FDAC930DC7D4320A91FCD1065B247103D4 +:10B60000254C100085CE19264FF6B822191E581F5A +:10B61000E345F71BAD6D96187795351541BDD411EF +:10B620000BE5730ED50C130B9F34B207695C510404 +:10B630003384F000789A492542C2E8210CEA871E3B +:10B64000D611271BA039C6176A6165143489041105 +:10B65000FEB0A30DC8D8420A9200E2065C2881031E +:10B660002650200084CA09264EF2A822181A481F24 +:10B67000E241E71BAC6986187691251540B9C411E3 +:10B680000AE1630ED408030B9E30A20768584104F8 +:10B690003280E000799E592543C6F8210DEE971EB1 +:10B6A000D715371BA13DD6176B657514358D141151 +:10B6B000FFB4B30DC9DC520A9304F2065D2C91036A +:10B6C0002754300083C6F9E54DEE98E21716381F6F +:10B6D000E13DD71BAB6576D8758D15153FB5B41117 +:10B6E00009DD530ED304F30A9D2C920767543104ED +:10B6F000317CD0007AA2692544CA08220EF2A71E26 +:10B70000D819471BA241E6176C698514369124119C +:10B7100000B9C30DCAE0620A940802075E30A103B3 +:10B720002858400082C2E9254CEA88221612281FB8 +:10B73000E039C71BAA616618748905153EB1A411CA +:10B7400008D9430ED200E30A9C28820766502104E0 +:10B750003078C0007BA6792545CE18220FF6B71E9B +:10B76000D91D571BA345F6176D6D951437953411E8 +:10B7700001BDD30DCBE4720A950C12075F34B103FF +:10B78000295C500081BED9254BE67822150E181F82 +:10B79000DF35B71BA95D56187385F5143DAD9411BF +:10B7A00007D5330ED1FCD20A9B247207654C1104D5 +:10B7B0002F74B0007CAA892546D2282210FAC71E11 +:10B7C000DA21671BA44906186E71A5143899441133 +:10B7D00002C1E30DCCE8820A961022076038C1034B +:10B7E0002A60600080BAC9254AE26822140A081F4C +:10B7F000DE31A71BA85946187281E5143CA98411B3 +:10B8000006D1230ED0F8C20A9A20620764480104C8 +:10B810002E70A0007DAE992547D6382211FED71E86 +:10B82000DB25771BA54D16186F75B514399D54117E +:10B8300003C5F30DCDEC920A97143207613CD10396 +:10B840002B6470007FB6B92549DE58221306F81E16 +:10B85000DD2D971BA7553618717DD5143BA57411A6 +:10B8600005CD130ECFF4B20A991C52076344F103BD +:10B870002D6C90007EB2A92548DA48221202E81EFB +:10B88000DC29871BA65126187079C5143AA16411CA +:10B8900004C9030ECEF0A20A981842076240E103E1 +:10B8A0002C68800000000000000000000000000084 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C24000042E0100840C0000042F010000000000F7 +:10C25000042E010080090000883B0100000000005E +:10C26000020000000000000001000000FFFFFFFFCF +:10C2700004000F00070000000000000F0100000094 +:10C28000AA000000FFFFFFFF4040404040409001F7 +:10C290009001900190019001900190019001900116 +:10C2A00010001E00320023003200C70032003300AD +:10C2B0003C003C00900190019001900190019001A0 +:10C2C0000200201C01000000503D02000C3D020055 +:10C2D000503D0200103D0200AA00AA0002000F001B +:10C2E0001E000F003C0014007800780000000000E1 +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F0000008F71024380460090E0A000101000810F6 +:10F01000240040046C090000000C00000000000007 +:10F0200000004A590000000000000000000801092B +:10F030000001444340020000282221008004000017 +:10F0400080040000800400008004000080040000B0 +:10F0500080040000800400008004000000FA030027 +:10F0600080040000800400008004000000FA030017 +:10F070008004000080040000800400000000000004 +:10F08000000101000000000000000000000000007E +:10F09000000000000000000000000101010101006B +:10F0A0000001010101010101010100010000010055 +:10F0B00001000000000000000F0000000107010334 +:10F0C00002030A00320A400000003200370000004C +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000C800C8009600C80032 +:10F0F00007078000800005050000000000000000F8 +:10F1000007010000DBFF00004100F1FF10001400C8 +:10F11000F9FFC4FFFF7FFF7FFF7FFF7F96002C0179 +:10F1200096003C000A04CECE3232280500000000D2 +:10F1300000070D0000240D000000001024242424EA +:10F1400024242424242424242424242424240000C7 +:10F1500000000000000000000000000000000000AF +:10F160000A05000A0000000020010014111400002C +:10F17000000000000000000000000000000000008F +:10F18000000000000F23283C465000006E696664B2 +:10F190005050505008000000000000000F23283C91 +:10F1A000465000006E696664505050500F141E287F +:10F1B000000000000A0A0A0A0A0A0A0A0F1E32465A +:10F1C00000000000645F553C3C3C3C3C00000000FB +:10F1D00008081A00A000EAFF1E009D008300100E20 +:10F1E00000000000001000003C00320090012800E8 +:10F1F0000F000F001C023D011C02740400003704C4 +:10F2000000005F09F4010000370400005F093214B8 +:10F21000021E1E3202009B00280028007700C00357 +:10F220007700E808000000004004300005000100FD +:10F2300007000000410028012402200309043F04C4 +:10F2400000000000000000000000000000000000BE +:10F2500000000000000000000000000000000000AE +:10F26000000000000000000000000000000000009E +:10F27000000000000000000000000000000000008E +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F000000000000000000000006C093000050064 +:10F300000100070000003B006E02BC040B073F0930 +:10F310006B09000000000000000000000000000079 +:10F3200000000000000000000000000000000000DD +:10F3300000000000000000000000000000000000CD +:10F3400000000000000000000000000000000000BD +:10F3500000000000000000000000000000000000AD +:10F36000000000000000000000000000000000009D +:10F37000000000000000000000000000000000008D +:10F38000000000000000000000000000000000007D +:10F39000000000000000000000000000000000006D +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D00002020500F16C0000409C000000F91500DD +:10F3E00029B1010010270000C4090000010101013A +:10F3F000010101010101014B0F0055000000000057 +:10F40000020101010101010101010100F16C000093 +:10F410000200000084DE0100000000000F0F0A0A55 +:10F4200028000000000000000F0F1414010101016A +:10F43000010140003200E8030F0008000500E10070 +:10F4400000001E288C00B40019006400640028002D +:10F450007800000000000000B4007800E8034006D7 +:10F4600000000001410100000000000068010D0DD6 +:10F470000A092D0019006400140064002C016400C6 +:10F480002C010F02E8E8F800F80008041900000059 +:10F49000A500B300C300D400E700FA000F01260165 +:10F4A0003E01570172018F01AE01CF01F101160239 +:10F4B0003C0265029002BD02ED021E035203890365 +:10F4C000C203FE033C047C04BF0405054D059805FA +:10F4D000E50535068706DB0632078A07E507420899 +:10F4E000A10801096309C7092C0A920AF90A600BED +:10F4F000C80B310C9A0C020D6B0DD20D390E9F0EFC +:10F50000040F670FC80F27108410DE103511891102 +:10F51000DA1128127112B712F81235136D13A013F5 +:10F52000CF13F8131C143B145414681476147E146F +:10F530008114DB00ED000001140129014001580194 +:10F5400072018D01A901C801E8010A022D025202CF +:10F550007A02A302CE02FB022A035C038F03C503D7 +:10F56000FD0336047304B104F10434057805BF05C6 +:10F5700008065306A006EF063F079207E6073B087A +:10F580009308EB084509A009FC09580AB60A140BB0 +:10F59000720BD10B2F0C8D0CEB0C490DA50D010E30 +:10F5A0005B0EB40E0C0F610FB50F06105510A110B5 +:10F5B000EA1031117411B411F01128125D128D127C +:10F5C000B912E112051324133E135413651371137A +:10F5D00078137B136A00750081008E009D00AC00DB +:10F5E000BD00CF00E200F7000D01260140015C01E3 +:10F5F00079019901BC01E001060230025B02890237 +:10F60000BA02EE0224035D039A03D9031B046004CB +:10F61000A904F40443059505E90541069C06FA068C +:10F620005B07BE0724088D08F8086509D409450A58 +:10F63000B80A2D0BA20B190C900C080D800DF80DBB +:10F640006F0EE60E5C0FD00F4210B31021118C111B +:10F65000F4115912BA1217137013C41313145D1452 +:10F66000A114E01418154B1577159C15BB15D4156E +:10F67000E515EF15F315A500B300C300D400E700AE +:10F68000FA000F0126013E01570172018F01AE0100 +:10F69000CF01F10116023C0265029002BD02ED02AB +:10F6A0001E0352038903C203FE033C047C04BF040F +:10F6B00005054D059805E50535068706DB06320785 +:10F6C0008A07E5074208A10801096309C7092C0A4E +:10F6D000920AF90A600BC80B310C9A0C020D6B0DE3 +:10F6E000D20D390E9F0E040F670FC80F271084101C +:10F6F000DE1035118911DA1128127112B712F812C1 +:10F7000035136D13A013CF13F8131C143B145414AA +:10F71000681476147E148114550055004B00470080 +:10F720000000000055008700DC0014000500000008 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000800000091 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F860000000000000000000000000000000000098 +:10F870000000000000000000000000000000000088 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF000000000000000000000000000004E565409 +:020000022000DC +:1000000066665A4285CB2B43C3F500400C00B740CF +:100010000000000000000000000000000A000000D6 +:1000200000000000000000000000000000000000D0 +:10003000002092000000000020508B01907B020500 +:1000400041525B14810B00000042525B14810B0093 +:10005000000043525B14810B00000046525B148188 +:100060000B00000047525B14810B000000000000F1 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:100100000000000000001101101500002002100185 +:1001100000003003000200008004000300004005DE +:10012000000400005006000000006007000000000E +:1001300070080000000090000000000000100100A6 +:100140000000022000000000030000000000040086 +:100150000000000005000000000006000000000094 +:100160000700000000000800000000000900000077 +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C00000000000000050140000000000000000CB +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:00000001FF diff --git a/firmware/j20s_novatek_ts_mp02.bin.ihex b/firmware/j20s_novatek_ts_mp02.bin.ihex new file mode 100644 index 000000000000..af93814faffe --- /dev/null +++ b/firmware/j20s_novatek_ts_mp02.bin.ihex @@ -0,0 +1,8707 @@ +:100000000001000000000000F32C0100008101004D +:1000100040710200EF41000095969240E9905843EC +:1000200000000000A000000002000000000000002E +:10003000708F020000000000309F0100BB4FC16CB8 +:10004000707B020000000000308B0100DFD4CD592E +:10005000709902000000000030A90100DFD4CD59E2 +:10006000F42C0100260C0000F42D01009254708D38 +:1000700000000200800900001A3A0100902D8B97C1 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F00040700200FF0000000000000015E86E8C58 +:10010000480001EA400000094000000940000009E1 +:100110003AFFBFFC3A0FA83C4400000148000190A0 +:100120003AFFBFFC3A0FA83C440000024800018897 +:100130003AFFBFFC3A0FA83C44000003480001808E +:100140003AFFBFFC3A0FA83C440000044800017885 +:100150003AFFBFFC3A0FA83C44000005480001707C +:100160003AFFBFFC3A0FA83C440000064800016873 +:100170003AFFBFFC3A0FA83C44000007480001606A +:10018000480000004000000940000009400000094C +:100190003AFFBCBC3A0F943C440000004800017197 +:1001A0003AFFBCBC3A0F943C440000014800017483 +:1001B0003AFFBCBC3A0F943C440000024800016C7A +:1001C0003AFFBCBC3A0F943C44000003480001597C +:1001D0003AFFBCBC3A0F943C440000044800015C68 +:1001E0003AFFBCBC3A0F943C44000005480001496A +:1001F0003AFFBCBC3A0F943C440000064800014161 +:100200003AFFBCBC3A0F943C440000074800013957 +:100210003AFFBCBC3A0F943C44000008480001314E +:100220003AFFBCBC3A0F943C440000094800012945 +:100230003AFFBCBC3A0F943C4400000A480001213C +:100240003AFFBCBC3A0F943C4400000B4800011933 +:100250003AFFBCBC3A0F943C4400000C480001112A +:100260003AFFBCBC3A0F943C4400000D4800010921 +:100270003AFFBCBC3A0F943C4400000E4800010118 +:100280003AFFBCBC3A0F943C4400000F4800010404 +:100290003AFFBCBC3A0F943C44000010480000FCFC +:1002A0003AFFBCBC3A0F943C44000011480000E9FE +:1002B0003AFFBCBC3A0F943C44000012480000E1F5 +:1002C0003AFFBCBC3A0F943C44000013480000D9EC +:1002D0003AFFBCBC3A0F943C44000014480000DCD8 +:1002E0003AFFBCBC3A0F943C44000015480000D4CF +:1002F0003AFFBCBC3A0F943C44000016480000C1D1 +:100300003AFFBCBC3A0F943C44000017480000B9C7 +:100310003AFFBCBC3A0F943C44000018480000B1BE +:100320003AFFBCBC3A0F943C44000019480000A9B5 +:100330003AFFBCBC3A0F943C4400001A480000A1AC +:100340003AFFBCBC3A0F943C4400001B48000099A3 +:100350003AFFBCBC3A0F943C4400001C480000919A +:100360003AFFBCBC3A0F943C4400001D4800008991 +:100370003AFFBCBC3A0F943C4400001E4800008188 +:100380003AFFBCBC3A0F943C4400001F480000797F +:100390007E0500007E050000160A0000EC08000043 +:1003A000EC080000EC080000EC080000EC0800007D +:1003B000EC080000EC08000000000000E005000070 +:1003C000E8050000040C0000900C0000F40500009B +:1003D000D00C00007E060000A2060000AA06000065 +:1003E000B2060000BA060000860D0000C20600003A +:1003F000A00D0000CA060000EE060000C8070000BD +:10040000D4070000240800002C080000B40D0000F0 +:10041000CE0D0000E80D00007E080000180E000060 +:10042000C8080000D0080000D2080000DA08000068 +:100430003A0E0000DC080000E40800006412A40288 +:10044000642204023A1F883C803F442002983821ED +:100450000202643200029ED964320003DD2264028B +:100460000043640000083A1F88046412A403642255 +:1004700004033A0FA8043AFFBFC4640000044420F8 +:1004800002BC38210202DD223A0F94043AFFBC84F8 +:10049000640000046412A402642204023A1F883C2F +:1004A000442002BC38210202643200029ED9643228 +:1004B0000003DD2264020043640000083A1F880440 +:1004C0006412A403642204033A0F94043AFFBC8428 +:1004D000640000044FF2001D3A0FA83C3AFFBFFC35 +:1004E00045D2CA38801F64126402965F9E49C105D6 +:1004F0003CFD4E16480000043CFD4E17E809DD2F78 +:10050000C8073AFFBFC43A0FA8046400000464029D +:100510002402441F3FFFFE0E5800400064022403E3 +:100520006400000845D2CA3845F3000044F005369F +:100530004EF20003DD2F3CFD4E18DD2F640FFFEA65 +:100540003A6F98BC4402B3304462E1CC9AB0842044 +:100550004900933E440FFFAAAE313A6F9884DD9E66 +:100560003BFFFE3CEFFC84003C0FFABE3C0FFAC69A +:100570003C0FFACA3C0FFACE3C0FFAD73C0FFADB1D +:100580003C0FFAC43C0FFACF3C0FFACB3C0FFAD425 +:100590003C0FFACC3C0FFAC83C0FFAC53C0FFAC02E +:1005A0003C0FFAD93C0FFADD3C0FFAD23C0FFAD3DC +:1005B0003C0FFAD03C0FFABC3C0FFADA3C0FFACDF4 +:1005C0003C0FFAC33C0FFABF3C0FFABD3C0FFAC216 +:1005D0003C0FFADC3C0FFAD13C0FFAD83C0FFAC9B9 +:1005E0003C0FFAC164030003640304036412240291 +:1005F0009646C103640300034400400064022403E0 +:10060000641200028419FE0E6402000364000008F4 +:10061000640304024616F7805010807CFE0F6403CA +:100620000403640200025800000164020003EC04A9 +:100630003BFFFE04DD9E4403F04B843FAE40440389 +:10064000F0EDA6405A1801048420AE404413F0DABD +:10065000A608540000F0AE088404640304034403B5 +:10066000F0498425AE404403F04A44100053AE40A4 +:10067000640304025800400064030403DD9EDD9E11 +:100680004443F114B46492784031E008FE1FB6048C +:100690004403F13844300055AC404403F13A84201F +:1006A000AE404403F1048421B6404403F1364423B0 +:1006B000F04AAE404413F134A608960EC803AED0FB +:1006C000D5FC4403F134A6009606DD9E924284A038 +:1006D000D207383016023830960A8CA1D5FADD9E42 +:1006E00084013C0FFABEDD9E3C0DFAC68C013C0F26 +:1006F000FAC6DD9E3A6F9ABCEFFC4900048AC0142A +:1007000084004900048A4900049B5A08010E3C0FEA +:10071000FAC74412B3AD3C0DFA984422B5103C3DE3 +:10072000FAA249008E414900046BC00784013C0FC6 +:10073000FAD6840049000468490004C0C01484004B +:10074000490004C04900047C5A08010E3C0FFABD60 +:100750004412B3AD3C0DFA984422B5103C3DFAA2C8 +:1007600049008E22490004A1C0078400490004A169 +:1007700084013C0FFABFEC043A6F9A84DD9E840139 +:100780003C0FFADB4403F082A600C00B3BFFFCBC2D +:10079000EFFC44000069490004CFEC043BFFFC84FB +:1007A000DD9E84013C0FFAC4DD9E84013C0FFACF2C +:1007B000DD9E84013C0FFACBDD9E84013C0FFAD410 +:1007C000DD9E84013C0FFAC8DD9E4403F04B843F5C +:1007D0003BFFFCBCAE408401EFFC3C0FFAC0440080 +:1007E0000069490004A9EC043BFFFC84DD9E3C0D3C +:1007F000FAC25A08010884203C1FFAC23E07E90EDB +:10080000D50484023E07E90E4403F04BA6405A107B +:10081000FF05843FAE40D5FF84013C0FFAD584002C +:100820003C0FFAD93E07E9103C0DFA983BFFFCBC9F +:10083000A601EFFC5A00040A490029E85A080106FB +:10084000490045E83E07E9403C0DFA98A6415A1890 +:1008500003392E17E94A5A180135A6005A08013201 +:100860002E07E90B9600C82D3C1DFAB4A6485A186D +:1008700001293C1DFAA9A6485A1801243C0FFADAAE +:100880002E07E91D5A0801064402B3A449006A185C +:100890002E07E977C0042E07E940C8133C0DFA98EB +:1008A00084204900095D3C0DFAB48420AE402E0737 +:1008B000E95AC8043C1DFAA9AE088401490029C0C0 +:1008C000EC043BFFFC84DD9E3C0DFAD98C013C0F0F +:1008D000FAD9DD9E84013C0FFAC93E00041444039A +:1008E000F07E3BFFFCBCA640EFFC5A10010FA64077 +:1008F0005A10020CA6405A100309A6405A100406CA +:10090000A6405A101003A600844184208062808291 +:100910004400B10149006ED449006EE9EC043BFF8C +:10092000FC84DD9E84013C0FFADDDD9E84013C0FDA +:10093000FAD24403F064A6409646C9194423F01045 +:10094000AE50A64058108001AE403C0DFA98A6006B +:100950008E02E602E9143BFFFCBCEFFC44000055AC +:10096000490003EAEC043BFFFC84D509A640964607 +:10097000C106A640541080FEAE40DD9EDD9E3A6F5B +:100980009ABCEFFC4900045A5A0802143C5DFADA9A +:100990002E000D12D0063C0DFA98A6015A08040A42 +:1009A000490045383E07E91E490008023E07E910A4 +:1009B00084013C0FFAD83C0DFADA8C013C0FFADACC +:1009C000EC043A6F9A84DD9E84013C0FFAC3DD9EED +:1009D000DD9E84013C0FFAC2DD9EDD9E84013C0F4A +:1009E000FAD1DD9E84013C0FFAC1DD9E4403F04B39 +:1009F000843F3BFFFCBCAE404403F0ED8420EFFCA1 +:100A0000AE404400006949000397EC043BFFFC84BE +:100A1000DD9EEFF0F081F001441003E8FE0C500081 +:100A20007C614410009340000437F08340000009CB +:100A3000F0039E41F183C8FB4403F04A4410005583 +:100A4000AE40EC10DD9EEFF0F081F001441003E8C1 +:100A5000FE0C50007C614410009340000437F0838A +:100A600040000009F0039E41F183C8FBEC10DD9EBD +:100A7000EFF0F081F101460000F450000240FE0C5E +:100A800050007D3A4410024440000437F083F003E4 +:100A9000441186A040100417C8064403F04A4410CD +:100AA0000055AE40F0039E41F183C8F2EC10DD9E8C +:100AB0003C1DFA35A6088C01AE083C1DFA35A60887 +:100AC0009606C8063C0DFA373C0FFA34D5053C0DA6 +:100AD000FA363C0FFA343C0DFA34A64880A01010C8 +:100AE000003F8420181280015000003C1812800141 +:100AF000D8FEDD9E3C2DFA34A65098D1AE199C0943 +:100B000096005CF0003BE9028400AE10A61088401D +:100B1000841FAE11DD9E3A6F9EBC84008020490088 +:100B2000026284006405E4034403F00EA440964E80 +:100B3000C90FA4409656C90CA440965EC909A440AA +:100B40009666C906A400540001004E0200BA441380 +:100B5000F00EA408960EC806A5C85473810097F934 +:100B6000C72144122D508400A7C8AC0844122CF0B1 +:100B70003E07E932AE0844122CF197F8AE08441251 +:100B80002CF2AE0844122CF3AE0844122CF4AE083A +:100B900044122CF5AE0844122CF6AE0844122CF781 +:100BA000AE0849FFFCCF4403F00EA440964EC9089E +:100BB000A4409666C905A40054000100C00349FF83 +:100BC000FF7944022D608420AC4084C04402704010 +:100BD0003C6FFABD3C0FFAA33C6FFABF3C6FFAD5ED +:100BE0005A78AE4384E33C0DFAA394BC8840A051EC +:100BF000C10CB4029649A09349FFFD445A0801066E +:100C000040001C0CFF8797B18CE15A780FEE3C2D09 +:100C1000FAA30411003D0401003C8E2496490421EE +:100C2000003F49FFFD2F5A08010544008000FF875F +:100C300044022D788420AC40C61744022D60441F26 +:100C4000FF9FAE4044022D619670AE4044022D627B +:100C500092C8AF804403F04A44100055AE404400AF +:100C600000694900026944028F7044122D78FA54D9 +:100C700049FFFD2E3C0DFAA344322D7C44222D7DEC +:100C800004000009401020093E07C5553E17C5560F +:100C90004010400992183E17C5573E07C558A61880 +:100CA000A6509602964AAE58AE1044322D7E44228B +:100CB0002D7FA618A6509602964AAE58AE10441341 +:100CC000F00E3C0DFA34A6481010003C4413F00F0F +:100CD000A6481010003D490003099E81E6483C0FDC +:100CE000FAACE80C84214010880C5410808FC106A7 +:100CF00050007FE0960049FFFEFF49008ED73A6F13 +:100D00009E84DD9E3A6F9ABCEFFC3C0DFACA8C01C2 +:100D10003C0FFACA3C0DFA98A6008E01E602E832B2 +:100D20002E07E9385A0055062E07E92E5A08552194 +:100D30003C03F4D68C019601E60A3C0BF4D6E91B81 +:100D4000840449FFFED984013E0004548400490014 +:100D500027773C0DFA98A6005A080107440000695D +:100D6000490001EAD5088E02E602E900D5048400B4 +:100D70003C0BF4D6440000553E07E9383E07E92E07 +:100D8000D50484003C0BF4D6EC043A6F9A84DD9EC3 +:100D90003BFFFCBCEFFCFA1049FFFEAE84013C0FA8 +:100DA000FACE490001DB490027443C0DFA98842221 +:100DB000490006D64900275B84208402844680616E +:100DC000808180A14900029AEC043BFFFC84DD9EF7 +:100DD0003A6F9ABCEFFC3C1DFAB484013C0FFAD781 +:100DE000AE08440FFFAA3E07E938490002273C2D10 +:100DF000FA985A0802153C13F4EB3C03F465E22020 +:100E0000E80EA6118E03E602E80A2E0004318C21BA +:100E10003C1BF4EB5A0801043E07E94584003C0FF3 +:100E2000FAD5A611540000FD5A0004068002842160 +:100E300049000696490026F0C80A2E17E9283E0701 +:100E4000E9855A1801113E07E983D50D840949FF48 +:100E5000FE53FA1849FFFDDF840249003F76840102 +:100E60003E07E95A2E07E9775A0001062E07E91DC9 +:100E70005A0801072E07E9818C013E07E981EC043D +:100E80003A6F9A84DD9E3BFFFCBCEFFCFA1249FFEF +:100E9000FE33EC0484013C0FFACC3BFFFC84DD9E66 +:100EA0003BFFFCBCEFFCFA1349FFFE26EC043BFFC2 +:100EB000FC84DD9E3BFFFCBCEFFCFA1549FFFE1CE9 +:100EC000EC0484013C0FFAD33BFFFC84DD9E3BFF26 +:100ED000FCBCEFFCFA1649FFFE0FEC0484013C0F4A +:100EE000FAD03BFFFC84DD9E3BFFFCBCEFFCFA1715 +:100EF00049FFFE0284013C0FFABC490083895A086D +:100F0000A1064400005549000117840249003F1D15 +:100F1000EC043BFFFC84DD9E3BFFFCBCEFFCFA18BD +:100F200049FFFDEA84013C0FFACD44000055490019 +:100F30000103EC043BFFFC84DD9E3BFFFCBCEFFCAB +:100F4000FA1949FFFDD984013C0FFADC49003D50F4 +:100F50004900265CC8044900266CD50349003D1FA2 +:100F6000EC043BFFFC84DD9EFC2080C14413F04A6E +:100F700080E244200055AE885A08020749000090DC +:100F8000C8FE640304034403F04A4410005544338C +:100F9000F04BAE40A6185A00FF05841FAE18D500CE +:100FA0004443F0DA97B0A620540000F040238004B8 +:100FB0004403F0ED9690AEA0AF80A6185A00FF054E +:100FC000841FAE18D5004403F041AE404000000934 +:100FD00040000009400000094000000940000009ED +:100FE000FCA0944D4423F042FE0F9600A6D0AE1014 +:100FF000DD9E4413F046AE08DD9E00004403F0C4BD +:10100000A600DD9E4413F0C49600AE08DD9E4403A6 +:10101000F0C3A600DD9E4413F0C39600AE08DD9E2B +:101020004403F0CE4413F0D0A400A6489407FE0F6A +:10103000441DD30088015C000041DD9E4403F0CED6 +:101040004413F0D0A400A6489407FE0F441DD2B06C +:1010500088015C000001DD9E44022D00DD9E4403FA +:10106000F0CE4410045AAC404403F0D08420AE408B +:101070004403F0C7843FAE40DD9E4413F0E6AC0865 +:10108000DD9E4403F0F58421AE404413F04A442031 +:101090000055AE88A6405A1001FFDD9E4403F0F4CF +:1010A000A6009204DD9E4403F0F7A600DD9E4413E3 +:1010B000F0F79600AE08DD9E4403F0F6A600DD9E34 +:1010C0004413F0F69600AE08DD9E44522D00441203 +:1010D0002D3E18028001D9FEDD9E3A6FA8BC440067 +:1010E000400064030403440000FD49FFFFF0441383 +:1010F000F04B841FAE0844A3F0CE4480045A8121F3 +:1011000080E04463F0681285000010748000A6300F +:10111000520000014900003F440009C449FFFC950A +:10112000A6305200000149000036440009C449FFBE +:10113000FC8CD5E83BFFFCBCEFFC49FFFFD09200E4 +:101140004423F0EC9606A6509402541080FBFE0F48 +:10115000AE10DD9E48FFFFF6C80844122CF5A60825 +:101160008C019600AE08D50F44222CF6A6508C2197 +:101170009648AE505A0801084413F060A60858007B +:101180000004D5064413F060A608540000FBAE0826 +:10119000DD9E4413F0689600AE08DD9E4423F053B4 +:1011A0009606A650541080FE88019600AE10DD9E73 +:1011B0004433F0404443F00EA69884A05421001C10 +:1011C000FE579648AD60AE584413F06A9606A6885E +:1011D000542100FEAE88A68888029600AE08DD9EE7 +:1011E0004403F061A600960FDD9E4423F06DC90311 +:1011F0008425D5028424AE509444FE0F4413F06E2F +:101200009600AE084413F06FAE08DD9E4403F06D07 +:101210008420AE40DD9E4403F061A6009203960652 +:10122000DD9E4403F061A60092029606DD9E440313 +:10123000F061A6009207DD9EFC0049FFFFFAC80797 +:1012400049FFFFF15A0001068401D5048400D5024C +:101250008402FC802E0004322E5004103BFFFCBCA4 +:10126000EFFCD00FC8064400005249FFFC45D505ED +:101270004400005149FFFC402E0004323E0004109F +:101280002E0004302E500411D00FC8064400005424 +:1012900049FFFC32D5054400005349FFFC2D2E00C8 +:1012A00004303E0004112E0004312E500412D00FE1 +:1012B000C8064400005649FFFC1FD50544000055F0 +:1012C00049FFFC1A2E0004313E0004122E0017952F +:1012D0005A00AA08EC0484073BFFFC8448FFFC0C7E +:1012E000EC043BFFFC84DD9E48003C784403F04A5C +:1012F00044100055AE40DD9E3BFFFCBCEFE4F081A6 +:10130000F1828005F101F283F384F48549FFFF52F5 +:10131000F002F10349FFFE674403F04A4410005510 +:10132000AE40F001F104F205EC1C3BFFFC8448FFE9 +:10133000FE1D3A6FA0BC80E084C0E2C7E80C8401C7 +:10134000844080208062808080A28CC149FFFFD6CB +:1013500097B0D5F43A6FA084DD9E48FFFE7F3BFF37 +:10136000FCBCEFFC49FFFE5EEC043BFFFC84DD9E11 +:101370002E000429C80A3BFFFCBCEFFC49FFFE908D +:10138000EC043BFFFC84DD9E8400DD9E48FFFF03F0 +:101390002E07C666C8143BFFFCBCEFFC2E07C543F6 +:1013A00049FFFEF9FA0949FFFB362E07C543EC0455 +:1013B000520000013BFFFC8448FFFEEDDD9E48002B +:1013C0003EC848003EBB44124000B62044124C6068 +:1013D000A84544120C60A84644121B90A84244122F +:1013E0004B40A844441237FC141000114412997069 +:1013F00014100012441220A014100014441266208D +:1014000014100015DD9E3A6FA4BC80C044012C7CF2 +:10141000EFDC3A20140044012C8CB1C43A2F942004 +:101420003A201400813F3A23942049004009C0210A +:101430002E17C9C32E07E91E8E21E020E802960868 +:1014400038148202442000481413000A3813820220 +:101450001413000B4412D2484210087344022900AE +:101460001403000944022C60141300131403000C2D +:10147000EC243A6FA484DD9E842C3A6FA0BCAE416C +:1014800084003C0FFAD1840149FFFE684463F04AAE +:10149000447000553C0DFAD1C00D84208461840253 +:1014A0008041808380A33A6FA0843C1FFAD148FF1B +:1014B000FF2549003C275A0801F2AFF0D5EC441350 +:1014C000F01F4433F302A648542080E0A6589667E4 +:1014D000E001E806A658966788229A089680440399 +:1014E000F01FAE80DD9E3BFFFCBCEFFC49003C01E1 +:1014F000EC0484013BFFFC8448003C00A4408C21A8 +:1015000096495CF08190AC40E9113BFFFCBCEFFCDC +:10151000840549FFFAF1840049002392EC04440059 +:1015200000693BFFFC8448FFFE07DD9E3BFFFCBCDF +:10153000A740EFFCD90C8CA19768E6A5E90284A02E +:10154000AF40440FFFAA3E07E92ED511840649FF9C +:10155000FAD344122CF0A6088C019600AE08840041 +:101560004900236E4400005549FFFDE644022CF07B +:10157000A600C00484013E000454EC043BFFFC843C +:10158000DD9EA6885A28AA08A680AE888420AE4090 +:1015900048003DC3DD9E3C0DFAAC5A0804273BFFD2 +:1015A000FCBCEFFC49FFFE4A5A0002142E07C5D3CB +:1015B0005A08011084003E07E90984003C0BF4D668 +:1015C0004412B36B4402B36449FFFFDD8403D505C5 +:1015D000FA003C0FFAAC8405EC0484203C2DFA9808 +:1015E0003BFFFC8448003652DD9EA6885A20AA0D97 +:1015F000AE80442FFFAAAE88A6005A080104480016 +:101600003D8548003D8ADD9E8440AE808400AC0864 +:10161000DD9E4403F5608420AE404403F5618423DD +:10162000AE408400802080408060480039E9440357 +:10163000F5608423AE404403F5618420AE4084000D +:10164000802080408060480039DB4403F007A6001A +:101650005A08720A4403F004A6405A100C12A6005D +:101660005A000E0F44022D60441FFF9EAE4084209E +:10167000840280418461808180A148FFFE3FDD9E1D +:101680003A6FA83C44012C9CEFDC3A2014003A2F1E +:10169000942044212CACB0043A2114003A201420A8 +:1016A0002E27E95838400A022E000428C8348461E5 +:1016B0003E3004289552443271404462451038311E +:1016C00094004472AD7096D8385F8A0281203C1332 +:1016D000E2B6E201E820944140A098008827028504 +:1016E0000000A44838220101964B8A22382280004B +:1016F0004224082440210C0E88229649121500002D +:1017000002150000964B4E140004129500008C0147 +:101710009601D5DEEC243A6FA804DD9E3C23E2B6A8 +:101720004412451084A0D210A4080230EB408C2251 +:101730008A0396034E040003FE025EF00051E806A1 +:101740008CA19769D5F18400DD9E8401DD9E842102 +:101750004800436D3BFFFCBCEFCC96D0FA4084A020 +:101760008481F2858442F583F584F586F287F588D5 +:10177000F589B67FF481F382F48A804180A4490020 +:101780003852EC343BFFFC84DD9E3A6F98BC442217 +:101790008F70EFD00031000FFAC00041001084A11B +:1017A0008440F68584C2F283F284F286F687F2885A +:1017B000F289B67FF581F382F58A8041490038339A +:1017C000EC303A6F9884DD9E84213E17E983540003 +:1017D00000FB84203E100428C80744020000441285 +:1017E000451048FFFFD44402000044120002442286 +:1017F00045102E37C5472E47C54884A04800387B82 +:101800003C1DFA983A6F98BCA64980C049FFFFDE9C +:101810005A6803092E07C666C8053A6F988448FFC0 +:10182000FF313A6F9884DD9E3BFFFCBCEFFC440225 +:10183000451044121B9049FFFFAA44021B9044121A +:10184000400049FFFFA4EC0444020A2044124A204D +:10185000442000483BFFFC8448FFFF7E3A6F98BC61 +:1018600044428F70EFD00062000F84A0004200104D +:10187000F581F582F583F584F586F588F58984A1EF +:10188000B6DFF285F387F58A80668041490037CB61 +:10189000EC303A6F9884DD9E3BFFFCBCEFC484A023 +:1018A000F38DFA608082F38584418462F281F48250 +:1018B000F387F28AB6BFF583F584F586F588F58956 +:1018C00080648041F40D490037AEEC3C3BFFFC8462 +:1018D000DD9E3BFFFCBCEFBCF18EF08D8023F28FD0 +:1018E0002E37C547C4052E47C5488003D50380045D +:1018F0008481B61F84A1F0828400F083F184F08596 +:10190000F086F088F089F08AF581F587F00DF10E08 +:10191000F20F49003788EC443BFFFC84DD9E3A6FB0 +:10192000AABCEFFC006F802401EF8020F689026FD3 +:10193000801C00FF8028F68E006F803C008F802C7A +:1019400000AF8030009F8034F68F23CF8020227F2D +:101950008022006F804815EF800814FF800A148FE2 +:10196000800B14AF800C149F800D15CF8010F79161 +:10197000F692EC043A6FAA84480037553A6F9CBC43 +:10198000EFD444628F700073000F00630010F38186 +:10199000B0C7F3848460B6DFF482F583808380A7C8 +:1019A000490036CDEC2C3A6F9C84DD9E3A6FA0BC8A +:1019B0004473F423A678978849FFFC2FC00454137E +:1019C000001FD505A67896678E2196482E200D011A +:1019D0002E000D12400008172E27E91EE642E908E6 +:1019E0003C2DFA98A6915A2804048C0196004000D8 +:1019F00004063A6FA084DD9EFE0C4420007840006F +:101A00000817DD9E3C23F478FE0C40000817DD9E8D +:101A10003A6F98BC44012CBCEFF83A200C003A2FE6 +:101A20008C2049FFFBDF385F81013C13F4793C5B7C +:101A3000F4793C1BF478D13C50007F80960049FF3C +:101A4000F85B3C0DFA9B49003C943C03F47944203C +:101A5000016844400078FE84402110573C2BE4D2BA +:101A60003C2C010F3C33F47844101C20FE84FE44CF +:101A700040210C57401090373C2E010F3C1BF46561 +:101A80003C2C01103C13F4EBFE84FE0C40210C575F +:101A900040000C173C2E01103C0BF4EB490066365D +:101AA000490066AAEC083A6F98844800170DEC08C4 +:101AB0003A6F9884DD9E3BFFFCBCEFF45A08011797 +:101AC0003C0DF16B3C1DF166B61F3C0DF16C3C2DDD +:101AD000F167F0813C3DF1683C0DF1653C4DF169E9 +:101AE0003C5DF16A49003912D5153C0DF1633C1D8E +:101AF000F15EB61F3C0DF1643C2DF15FF0813C3D81 +:101B0000F1603C0DF15D3C4DF1613C5DF1624900DD +:101B100038FD840080208040806049003757EC0CFD +:101B20003BFFFC844800373B3BFFFCBCEFFC49001B +:101B30008AB24403F705441FFFA5AE40EC0484209D +:101B4000AE403BFFFC84DD9E4423F0779606A65012 +:101B5000541080FEFE0FAE10DD9E00004423F04ABC +:101B60003A6F9CBC44300055AED0EFF44433F38060 +:101B7000A6985A2001FF4E13008DA6018E01E60E95 +:101B80004EF2018544F01A943807810140F03C0080 +:101B90004A003C001C00F602CC009200CC009200EF +:101BA000F602280028009E009E009200CC00D8007B +:101BB000EC0C84023A6F9C84480038C7840149FFCA +:101BC000FAEF840049FFFF792E07E9192E17C9BBE8 +:101BD0005A0001072E07E9618E04E602E811E624A7 +:101BE000E8064400088E49FFF716D518E62DE816DA +:101BF0008E22440003E8FE0C49FFF70DD50FE624C2 +:101C0000E80484018424D504E62DE8088401844096 +:101C10008062808280A049FFFB71840149FFF9EB5B +:101C2000840149FFFF93EC0C84003A6F9C844800C8 +:101C3000388C840149FFFF8A840049FFFF3E2E074C +:101C4000E9195A0801074400088E49FFF6E4D5094E +:101C50008440840184248062808280A049FFFB4EFE +:101C6000EC0C84003A6F9C844800398984408401DC +:101C700080A02E17C9BB8062808249FFFB3F840190 +:101C800049FFF9B9EC0C84003A6F9C844800385D38 +:101C90005A100104480000F0A6018E03E60C4EF233 +:101CA00000F644F01BB03807810140F03C00DD0F26 +:101CB0009001180090011800DA0124002400E200CD +:101CC000E200DA0190019C01EC0C84013A6F9C84E3 +:101CD0004800383B46700FC050638800808780A65C +:101CE0008007802680468066B6DFF6814900380E80 +:101CF0008400802080408060490036684900364F6B +:101D0000FA1A49FFF68850038140808080A6802619 +:101D100080468066B6DFF681490037F8840080206F +:101D2000804080604900365249003639FA1A49FF2E +:101D3000F672808780A68007802680468066B6DFA0 +:101D4000F681490037E384008020804080604900AC +:101D5000363D49003624FA1A49FFF65D50038410D7 +:101D6000808080A6802680468066B6DFF6814900A6 +:101D700037CD8400802080408060490036274900AC +:101D8000360E8401490037E14400003749FFF6432D +:101D9000D56646700FC050638800808780A6800794 +:101DA000802680468066B6DFF681490037AF840022 +:101DB00080208040806049003609490035F0FA1AD9 +:101DC00049FFF62950038140808080A68026804606 +:101DD0008066B6DFF6814900379984008020804014 +:101DE0008060490035F3490035DAFA1A49FFF613E5 +:101DF000808780A68007802680468066B6DFF681D1 +:101E0000490037848400802080408060490035DEAE +:101E1000490035C5FA1A49FFF5FE50038410808049 +:101E200080268046806680A6B6DFF6814900376E40 +:101E30008400802080408060490035C8490035AF6B +:101E4000EC0C84013A6F9C8448003899840149FF66 +:101E5000FE3449FFFBE0840149003777840049FFE5 +:101E6000FE75840049FFF8C7EC0C84003A6F9C842F +:101E700048FFF9965A18020B840149003766EC0CAA +:101E800084003A6F9C8448FFF8B6EC0C3A6F9C844F +:101E9000DD9E92002E07E90B5A0801283A6F98BC84 +:101EA00049FFF9CCC8203C0DFAB4A6405A1801FFEE +:101EB000A6005A0801193C0DFAA9A78097B05A68E4 +:101EC00001133C0DFA98842049FFFE4A3C1DFAB4E8 +:101ED0008400AE083C1DFAA9AE0880063A6F9884CB +:101EE00048001EAE3A6F9884DD9E3C0DFA98A641DC +:101EF0005A1006292E17E91DC9253A6F98BC2E677E +:101F0000E977CE1E3C1DFAB4A6485A18011A3C1DAA +:101F1000FAA9A6485A18011580263C6FFADA49FF3B +:101F2000FE1F3C0DFAB4AF802E07E95AC8043C1DD1 +:101F3000FAA9AE0884013A6F988448001E813A6F6E +:101F40009884DD9E3BFFFCBCEFFC49FFF9775A0803 +:101F50000207EC043BFFFC8448FFFFC93C0DFA98E4 +:101F6000A6015A000B07EC043BFFFC8448FFFF94DA +:101F7000EC043BFFFC84DD9E3C0FFADFDD9E3C0F52 +:101F8000FADEDD9EFC00C0085A08010B49003859F2 +:101F90003C0FFAE1D505490038513C0FFAE0FC80CE +:101FA0008020E6293C0DFAE1E82544F01EB83817F8 +:101FB000840040F0BC00DD0F0A3C10161C22282EC5 +:101FC00034003C0DFAE0DD9E50000050DD9E5000D4 +:101FD00000A0DD9E500000F0DD9E50000140DD9E1F +:101FE000500001E0DD9E50000280DD9E5000032085 +:101FF000DD9E8400DD9E9200FC52F18C44112ADCAF +:10200000F48DB11580E380C23A208C043A220C246E +:10201000F08EA6488145AE6044112AE8B1183A20F6 +:102020008C043A220C24A648AE608420121F80291A +:102030003C2DFAE13C1DFAE0490037D33C1DFADEA5 +:10204000A60AA64B490037F15CF381008007E9033B +:10205000440000FF409000138009490037F984E0F4 +:102060003C1DFADF00008010E2E0E8108007381025 +:102070009C00490037FB3C0DFADF984780070010B1 +:1020800080084900381B8CE1D5EC8400490037E416 +:10209000490037BA8401490037DF490037B55AA8EB +:1020A00001482E37C53A44007FFF84E0F0884004A1 +:1020B00080112E47C53BB67FF089501F8052F00E2D +:1020C00044226B3080AAF781F782F783F784F78583 +:1020D000F786F787F78A490033A62E37C53A4412A8 +:1020E0006B302E47C53BB67FF38280AA8041F00C4F +:1020F00014AF8001F783F784F785F78614AF800764 +:10210000F788F78914AF800A4900338D3C1DFAE047 +:102110003C2DFAE144026B3049003763440004B0BF +:10212000490037968402490037974900376D4900C6 +:10213000378BF10DAE082E000404C8092E000400F0 +:102140005A000204480000D5480000E58500F00D63 +:10215000A600E300E8F4A075400408088801A64042 +:1021600001E00002F193A641A603F191F092F01272 +:10217000E21E4EF300B6500F7FFE5CF000204EF2E0 +:1021800000AAFA02420F0024F08FF713F011E207C1 +:102190004EF300A19E3AE60E4EF20099F00FB4669F +:1021A0009847964994099898F08EA61196064E0283 +:1021B000008EA7504C54408B8440440007D0B1158A +:1021C000384208108881972195218883A761E6A469 +:1021D000E80DA720A17338529101E005E902962B82 +:1021E000A17238429101E687E9088C415A2809E931 +:1021F00084404E060006D51384414E070068F30C58 +:1022000040F0040A384185114430007F42F20C73DB +:1022100040F781F65EF78074E859CA58F00CB15B5C +:10222000848038F00511B015844038301010886172 +:102230009619F0908002B0D538A18810F310894328 +:10224000F30C40A500133891A911B0D838A188101B +:102250008C414204A8735A2809F0AA294EF70009B4 +:10226000442001F4FE1440003C161402FFFF8C8150 +:102270005A4809DB8440B15B855E840044312AF40E +:1022800080209913383200105A38010938328202FE +:102290005EF1FF38E8038C2196485A18020CB466A8 +:1022A000049F800E8923003480014031A80210343D +:1022B00080018C015A0809E8B406F10E8801A601D4 +:1022C0009606C0048C495A2890DA9C3997C048FF7A +:1022D000FF5F500F000155E000FF48FFFF4A8D01EE +:1022E00048FFFF378C01F10DA648E201E9193C1DBA +:1022F000FAE03C2DFAE1F00C490036738403490002 +:1023000036AB490036814900369FF10DAE08840096 +:10231000D545840045EF8000FAE2853ED5E5A0B3BF +:102320009441382101015CF1004CE807A0B18822FA +:10233000A48840217804AC88A0B594428822A6885D +:1023400000808001F28FA68AA64BF18EF10EE22268 +:10235000E9CA42A11C24F10FE301E9184055040029 +:10236000B486976994E98864A71954F20001E80BD0 +:1023700004FF800C38F795115EF7804CE80440426A +:102380002402AF198C219648D5E88C419690D5DF70 +:10239000A07138508101D8078C01F10DA648E201E7 +:1023A000E9F8D527966B4E15FFF9A0B59442956ACA +:1023B00098D18845A6DAA712E264E802AED2A0B5A9 +:1023C00098D18845A6DBA713E283E802AED3A0B577 +:1023D000383104008845A710E264E802AED0A0B509 +:1023E000882288A2A649A6A9E241E8D7AE69D5D538 +:1023F000FCD23C0FFB40DD9E3C0FFB3FDD9EFC41D1 +:10240000444000FC42019073004000185452000107 +:10241000CD07B4C05A600105005000E0C51E44223B +:10242000B724840038010C084422B7148481384151 +:102430000C08A4884442B6D8A44938220E09949ABC +:102440008844AC514412B6C838008C084412B6B85F +:1024500038008C084800018A5A6802494422B7149F +:102460004442B6C838610C004402B6B85A68010943 +:1024700038520C0838500C0838510C08D517382041 +:102480000C00E642E8058C4138200C08D503385092 +:102490000C0838220C00CA0A38200C005A280207FF +:1024A0004422B6C8848138410C0838200C0080834F +:1024B000840F424100734422B6D82250800022602B +:1024C00080018004945A38410E014472B604882277 +:1024D0009B2C38438209A509940288079B34AD01DF +:1024E00038510E09AD89480001415A600404480082 +:1024F000013D544200FD104000184442B71444828C +:10250000B72438420C005A48010A38440C00959907 +:1025100088864462B5C83853110938440C004E43CC +:1025200000DD4452B6C844A2B60438628C0044525E +:10253000B6B838928C005A60010680E480A487CF38 +:10254000D521955A894580C480A484E14C54C003A8 +:1025500084E222F500008CA14243BC7322F5000105 +:1025600097684263BC7350A5003C5A5803F084A49A +:1025700040421496406314D63C4FFAE33C6FFAE2B3 +:10258000D51980C34262F87338F51A1195B288CA1A +:102590008CA1226300019768888FE32588E6E8F222 +:1025A0008D21404224964073A4F63C4FFAE33C7FD1 +:1025B000FAE24462B5C840A18808405328003C9D17 +:1025C000FAE3848038430E09AD2980A94E940004B3 +:1025D000525480003C7DFAE283C74E74000453E3FA +:1025E00080003C4DFB4040F2F800A1219281E28F37 +:1025F000004000F3F481E9048E8BE682E86E4E978A +:1026000000094442B6D838F20E1152F78437D50784 +:102610004E92000E4442B6D838F20E114440006487 +:1026200042479024405214B69769D5034450FFFFA7 +:102630004E77000A4442B6D8888A22F2000152F747 +:10264000896BD507C70E4442B6D8888A22F20001AA +:102650004440006442479024404278969721D50335 +:102660004440FFFF04FF800150F7FFF55CF7800254 +:10267000E81C4E920003CF764452B6D822708000F8 +:1026800038428E11229080019B3C3C4FFAE340423D +:10269000A80038728E092212000112920001401423 +:1026A00084013C1FFAE2D55EE2A44042BC1B5CF20E +:1026B0000096E8058C8A38430E09D50F5CF2012C90 +:1026C000E808928138430E0988CA8C8AAD31D50555 +:1026D0004410009638130E09001000F3E622E903B7 +:1026E0005A1806084412D56038108C00C935D50A2E +:1026F00038440C00945988244452B5C83872850176 +:10270000CF058421101000DED527E6824452B6D8CA +:10271000959AE8163C4DFAE338128E01FF3C44903E +:10272000006440422496888138428E093C1DFAE2BA +:10273000992EFE7CA5E14010A4368827AC610010DC +:102740000018581080021010001838028E0188A658 +:10275000AC10A429AC1138040C008C0138040C080E +:10276000D504444000C7D5AEFCC13C0FFC42DD9E01 +:102770003C0FFC41DD9E84003E07F100DD9E5A00C7 +:10278000016AFC202E57F100D02F4430004480E233 +:1027900042708C735061003F84804C4000264C1284 +:1027A000001F2033803F20F300008A6F4E34000367 +:1027B000FEDA8E62E662E81320F37FFF2033803E6C +:1027C0008A6F8C61E663E80B9EF30253801EA4D8E7 +:1027D000E2A3E80584011003803AD5388C81972064 +:1027E00050630044D5DB44300044808242408C7307 +:1027F0008460D5058C6196D8502100444C30002966 +:102800004C11BFFAB4A25CF2A711E9F500510043E4 +:10281000006200428CA1E0A6E9EE00520043006194 +:1028200000428CA1E0A6E9E70051004100620040AF +:102830008CA1E0A6E9E000520041006100408CA1BB +:10284000E0A6E9D984021002003A8401D50584008B +:10285000D5038400DD9EFCA0FC42A10D94D28864C7 +:10286000F1830081800000A18001A65A405520011B +:10287000F1818CA1A65BE4A3F1824EF200B68460E4 +:102880003C4DFC4105CF8001812380E380C3F102F0 +:10289000E03CE9304E82001500F2000283C843EEAE +:1028A0003C7340FF040839E079114FE70003893E8B +:1028B00040F03C0022F7FFFF4EF70003886F01E273 +:1028C000000250FF7FFFE14FE812802A421E78731A +:1028D00039E0051140F084084FE7000388DE40F03E +:1028E0003C0022F780014EF7000388EF51CE000133 +:1028F000D5CF5A5001075A58022F2EF0045FE82B0B +:10290000878A43E1F02440FF2407E80E42F3F024D5 +:1029100040F79807E8094E82000800F2000250F7DD +:10292000FFFFE14FE9635A580117F502F1018AA14F +:10293000E4A5E8042E50045FC50E40FF2407E90318 +:102940004E83000A84AAFF7CE0A6E950A7628EA10C +:102950004CA2804D2E50045FC50884AAFEECE069AD +:10296000E945FFECE0E6E942F103949100A200039F +:10297000A04C88418420A75180E181218441E04A14 +:10298000E823A7A2810542811873403404083880E7 +:1029900021114E840004528400008928C50A408019 +:1029A0000C0022847FFF4E8400045284000088E8DB +:1029B0008EC1D6088860223180014E340003FEDAD1 +:1029C00088238C41D5DD5EF487D1E90B5EF380640A +:1029D000E902CD075EF08064E909A6228E01D006E7 +:1029E00084003E00045F8401D5028400FCC2FC40E8 +:1029F000A10D94D28864A04C9491A7988841A759BE +:102A0000A71AA691A6DBC6049E719648D502802619 +:102A10009491884080E484C0FB54E267E9094293C2 +:102A2000A8248CE13891240188C997B3D5F7FAE23C +:102A3000FFE444900064E2A1E93054208001CA2BF5 +:102A40005A10082A40809C0040840408890083842E +:102A50008142E27CE90F02F4000051CE0001894F6F +:102A600002F4000140A50011884F96935084002481 +:102A7000D5F1E629E805E142E80E8A4AD505E04AA3 +:102A8000E80A402508014221242440F119F65EF7A6 +:102A90008033E8058C21D5D08401D5028400FCC0A8 +:102AA000FC4051FFF728F1858540501F84DCF382FC +:102AB000F284F48CF18180E080C1810A8461F005A8 +:102AC000E340F086E851F1022203800022438001B6 +:102AD0001203000A1203000CA04BA0391243000B92 +:102AE0001243000D1033003B1083003A381081016F +:102AF0001403000B1213001EF10240900408F48628 +:102B0000A08D94428822500300408444F3834900FE +:102B10008055F0028442A004892080295003003EA1 +:102B20004900804C00548001F303F406C50C3C1DA1 +:102B3000FC41A60A8E01D00700548000C504A60BF4 +:102B40008E01D80410330035D503108300355EF2B2 +:102B5000091C800340043C1B100300368D41506368 +:102B600000448CE8D5AD2E87F1008400148F8003DB +:102B700050AF80688020509F80A4B1F8506F811CB6 +:102B8000445000444432B73CF4014220142488826B +:102B900088433815020A3814820A3813820A381317 +:102BA000020A8C011012002A1011002A5A080FEE96 +:102BB0004402B7BE844084C3E248E83000107FB8C6 +:102BC0008C415A18012980828020E288E824005034 +:102BD0007FBDE6A9E807A6C99DEA4C71800B8CA3CE +:102BE000D5075A500915A6C99DDAD7038C63DB0FA8 +:102BF00020F0800020307FBC8A6F8C61E663E8079C +:102C00000030FFFDCB0410607FB8D5058C815010DB +:102C10008044D5DC50000044D5D04400003C420440 +:102C20000024F08F8400F089460000F350000A7001 +:102C30003C2DFC4251EF8158049F8001F091F00936 +:102C4000F105E2014EF20104F309B01A84213810B3 +:102C50000E0A85404402B73CF10F4CA080F0F1050C +:102C60002234800CE228E8092210000E2240000FD6 +:102C70008A612214800DD5082210000C2240000D1C +:102C80008A612214800D8A24FE4C42118C73F187D4 +:102C90002214800C2264800DF18BF30B2210000CA7 +:102CA0002240000D9A59F188F3089B340450000922 +:102CB0004212102442118C73F58AB4605A580408E9 +:102CC000005000285A580104480005B30450000C75 +:102CD000CD71A151E2254EF3058CA551FF5CE22593 +:102CE000E82CA152E225E80AA144A183F708FF6479 +:102CF000425398734E56057DD520C31FA153E2253C +:102D0000E81CA184A143F708FFA4426394734450D4 +:102D10000064FF7440528CB7FF6CFF5C4470271056 +:102D200040F29DF70071002744500064FFCC4073CF +:102D300094F7E2EF4EF3055B00500029A790E2C53F +:102D4000E805A194E2264EF30554C322E6A2E92049 +:102D5000F511E2A1E91DA144A183FF2CF50842422F +:102D6000987344500064FF6440528CB7FF6CFEECD3 +:102D70004450271040F195F700510027443000647B +:102D8000FF4C40528CB7E2AFE8034E4605320031AB +:102D900000264E32054EA0D3E2234EF2054AF10A38 +:102DA0005A18040448000545F10746390000480058 +:102DB000053E5A5002065A5004044800053AF30AE8 +:102DC0005A380404480005352230000E85E6F38D9C +:102DD0002230000FA1C3F38E846AFE5CF190A051F3 +:102DE000A14442F78424F110E22F4EF305020011B2 +:102DF000002842F38424FE6C40F78DF640108C3698 +:102E0000F30EF18A88659AF3F60DF10B88C78A26CE +:102E1000FEDC42308473F10AFE4C4217BC73E06161 +:102E20004EF20507F108FF2C42409C734E47050106 +:102E3000F10746380000480004FAF00951EF000499 +:102E40008C01F0895094804448FFFEFB8400B0E977 +:102E50008421E208E8053811820A8C01D5FBF005CF +:102E6000E60BE80BE70BE8098028B09A504F815831 +:102E7000B15249000529D509F0058028B09A504F74 +:102E80008158B152490004D7F0883C0DFC428500BE +:102E9000F0874605FFFF50000FFEF08D4608FFFF4C +:102EA00050000FFF81484412B73C45E2D560F08ED8 +:102EB000F008E3404EF201CCB092400504088802CD +:102EC0008061A60144200044423008730421800C34 +:102ED0005A280214B092846F3821290042200C73C2 +:102EE000503F815838218A024E250008B0A98461DC +:102EF0003831020A480001A944300044B092808170 +:102F000042400C7338212900F60200520037504F1E +:102F100084DC42410C738064A1B350318028F6896F +:102F2000F70950420030A199AF6738639901F7075C +:102F300002738015E2E6E808CD07A75A58528001CF +:102F4000AF5A8461AEE744400044503F84DC8121A5 +:102F50004231107342901073506180182251800CDE +:102F60002244800CF58A9B2C22530001F58BF70B31 +:102F70002254800D9B7D42F2942442F2107380EF24 +:102F800081E3A95C1C778002F70A1447800188E47A +:102F9000ADF2F70B88A7AD7384AF80C242601473A3 +:102FA000505F8158F70D38529A024666000088C576 +:102FB000E2E6E855F60EE2C5E8520054803F503193 +:102FC0008038E6A9A6DFE806E669E8354E44003415 +:102FD000D505E669E9304E47002F44400044806142 +:102FE0004230107300618020445000FCF7044273AB +:102FF0001473005380FAC514505F84DC425110737F +:10300000808500528034CD170251801E0242001E7E +:1030100044300064FF5CFA6EFEE4E0A3E80C443048 +:103020000044504F88D842410C738064848414411A +:10303000FF0DD51844400044503F84DC42311073EA +:1030400084A21451800C80A14250107380858C9012 +:103050008C70A562A523AD5AAD1BD50484801441A4 +:10306000800C44400044503F84DC80C142311073E6 +:10307000426010738086507180108CD02253800281 +:1030800022930002226300038AA9A95922538003D4 +:103090008AA6A95A00520020506180201051802039 +:1030A000043200095A38037A383F14005A38010AAA +:1030B000003200288C6A103200288462383F1408DD +:1030C0004432D560383194005A38030E44300044FD +:1030D000808142400C738064848110418028FA60B2 +:1030E000383F1408383F14005A38040E4430004466 +:1030F000808142400C738064848110418028FA7082 +:10310000383F1408383F14005A380226443000442F +:10311000504F88D842450C73F60904427F0C38633F +:103120001101848AFFA4808142400C732272001C2A +:1031300080648487FF3CE0C4E807848110418028D4 +:1031400044300030D506003180285A3801058465A6 +:10315000383F140844300044504F84DC42410C7323 +:10316000FEC4886100520037003180285A5801039C +:103170008E611032002844300044504F84DC4241BC +:103180000C7380640042002850318020CC0384817D +:10319000D5028483A919D50684603E30045F846219 +:1031A000A8F1444000448061423010730031803403 +:1031B0005CF180C8E8038C6196D8505F84DC425192 +:1031C0001073103280344432B73C42301073B4C5AF +:1031D0005042802800318029F507AEE1A16DE2A6BA +:1031E000E805E66AE80A8C61D507F507A16EE2C535 +:1031F000E804C3038E61AEE144500044503F84DCD8 +:10320000F40242311473A1230461800B8D01384212 +:10321000190180C1426014732203001CE004404085 +:103220003C1A1241801C00418020503F811C8401C7 +:103230003801920AB0F838018A0AF0068E01F08649 +:10324000F0038E01F0838D4148FFFE348400509FCF +:1032500080A44462B73CF08750AF80E02E07F100B5 +:10326000F107E220E803F003C806049F800184E030 +:10327000480000C23C3DFC4100018009E300E8F643 +:103280000C0480015A0001044800009F0403000957 +:103290005A08031300230020441000FCF4044241A8 +:1032A0000473001200FBC908F0031414FFFF8E0121 +:1032B000F0834800008A9E41E622E8070403000CE0 +:1032C0005A08023A8400D53E5A08033A00430020C7 +:1032D000440000FCF104421200732220807380013C +:1032E0002253001C842AFE8C8427FE6CE041E80DEA +:1032F000001000FBC10A00130037C107001000F2E4 +:10330000C1040013003AC111842010130028842046 +:103310001414FFFFF103000000F28E21F183C814A2 +:1033200084013E00045FD5104402D5604410004083 +:10333000381010083C0DFC42A601D50400030028FB +:103340008E0110030028000300285A08010800130A +:10335000002A581080041013002A0011801984E0FC +:10336000B09AE2E1E80938351E02CB0438311E027A +:10337000C3058CE1D5F784E0D525C0038404D502CC +:1033800084054420004414030009500F84DC4203E8 +:103390008873802649007C1200230020501F811C66 +:1033A000840138008A0A38051E0A84001404FFFFCD +:1033B000F0038D018E01F083D50738251E02C2DE91 +:1033C0008CE14C70FFFCF007506300448C01F087E7 +:1033D00048FFFF46F0064E02011100130009E30109 +:1033E0004EF2010CB01A38001E025A00010C8CE19A +:1033F00050948044F0053C6DFC41E2E0E9EC48006B +:1034000000FDB03838601E02CEF3500F811C38002A +:103410001A024E0300ED8029B609A809A80AA80BD4 +:10342000A80C0204800C106480201204800E020498 +:10343000800DF1041204800F3C0DFC42880800004E +:10344000001C10048028440000FC4213007380011B +:103450008421101000FB2E000409C00A49FFEEEE83 +:103460005A080207000480288C01100480280434C4 +:10347000800B00148020440000FC04AF800442A0B4 +:10348000807380433C0C0278F102F38349FFFAB168 +:10349000100500FA1004803BF303C80700048028DD +:1034A000C8048401100480288400100500F1F10292 +:1034B0008043F00C49FFF9D200148020100500F27F +:1034C000F204440000FC42208073000100F2C807AF +:1034D00000048028C804840110048028F005967830 +:1034E000502F84DC49FFF94D81405A08010B49FFF8 +:1034F000EEA55A08020700048028C80310A48028FB +:10350000F102000480280424800BA04BC815380069 +:1035100089013C1DFC4202108015E220E8080004ED +:103520008036C805840114048009D514840314046A +:1035300080098401D50D381089013C2DFC4284633B +:103540001434800902210015E241E9048C011004C1 +:103550008028002480364412D560000480205A2838 +:1035600001052E37E916C3028440F3023820800893 +:103570004412E1B0844038208008A0DB0414800BA2 +:103580003C4DFC423831850102420015E283E802DD +:10359000844110248037F304442000FC4230087337 +:1035A0008400100180F0F30210048034100480299C +:1035B0000004802A8441A0DBFE171004802A381101 +:1035C000850184001214801C501F811C1404800C7F +:1035D00038209A0AB078890238209E0AB05A3800FA +:1035E0009E0AF0068E01F08648FFFF038CC1E2C1FF +:1035F0004EF3FF0D48FFFEFD8400F10480400033D0 +:103600000009E203E808B641102080E08C01501068 +:1036100080FCD5F684003E0004093E07F1004470AA +:1036200000C88540509F80E000030019E3404EF23F +:1036300000D73804AA025A000104480000CAF00169 +:10364000044000095A4005222E87F100442000441E +:103650004402B73C42040873F101F48349007AAE96 +:10366000F001F2048D0100100020440000FC422013 +:103670008073000100F03E87F1005CF000C8F403A5 +:10368000E8048C01100100F0F001048F80040010A8 +:103690000020440000FC42808073F0015014001CA4 +:1036A000B6880000002A10040018F0010200000A89 +:1036B00012040002F0010200000B12040003F001EA +:1036C0000200000C12040004F0010200000D1204BC +:1036D0000005F0010420000BB400B641A80AF00177 +:1036E000A001A80BF001A002A80CF0010400000C3E +:1036F0001404000C5A480311000400F2C80D001411 +:1037000000F18401C907100400F1F102F00C49FF37 +:10371000F8A5100400F2F001048F800400100020CE +:10372000440000FC42808073B4885A400416F001C3 +:10373000F202F4830400000BA093944138010101CC +:1037400012040074F002A0845004006688228442AF +:1037500049007A34F4033C0DFA9BB40092029606B9 +:10376000C003447001902204002E22F400028A0F4C +:103770004E040003FE02E0E0E90B2204002F22F4D5 +:1037800000038A0F4E040003FE02E0E0E80A000492 +:1037900000DE5A0802075A48020584013E0004016F +:1037A000F001B4005CF02711E9085A4802072E0026 +:1037B00004098C013E000409F0010000002A96066D +:1037C000C807000400FAC8048401100400FAF001DC +:1037D0008D4150000044F08148FFFF282E07F10082 +:1037E0003E07E95651FF88D8FCC04E67FAA7F10A98 +:1037F0005A18031400100034C9100010003A5A1867 +:103800000309F1054C140006F107463A0000D50EF5 +:10381000F10746310000D50AF107381F280A500089 +:10382000004450A5003C48FFFA198823D5F7843F8F +:10383000D5F5FC43F08181008400F484F182F585A4 +:1038400080E18380812084814E82003DC73B5A48BD +:10385000013A84A08085855EF101D122386116028B +:103860005A68011DF10495AA88C1F68384C0F1024B +:103870004C60801539E19A025BE8010F4410003C6E +:1038800042F30424F1033810BC02E22AE8058386DF +:103890008125809E81418CC1D5EB8CA1D5DEC4D51C +:1038A000F105954188A18C0184201092800011C2FD +:1038B000800196003811260A8F013811F20A8EE134 +:1038C000D5C4FCC3C06EC16FFC4051FFFB90E22029 +:1038D000E82F80E144A0003C851F81244293A87317 +:1038E00084C038849A0A8CC14C607FFD8CE14C7096 +:1038F0007FF680C083818001802681248105F2814A +:10390000814349002930B03B4900293480094900EE +:10391000293BB00249002942840F49002949490046 +:10392000294C844080A245E0003C8082D514E2010D +:10393000E8E184E044A0003C851F81244293A87301 +:1039400080C038849A0A8CC14C60FFFD8CE14C70B9 +:10395000FFF6D5D0840F81E94212802442F2F87339 +:1039600084E098F9B00238300C005A380111383729 +:103970009E025A37FF0D94D188688C41AFD8AF5959 +:10398000F301969038419E0A3845160A8CE14C7333 +:103990007FEA8CA14C5E7FE0800251FF8470FCC006 +:1039A0008040D50280418002DD9E3C0FFC74DD9E8C +:1039B0003C0FFC73DD9E4402BBC084213C0FFC4ED7 +:1039C00084003E07F13C3E07F13D3E07F13E3E07D5 +:1039D000F13F3E07F1403E07F1413E07F1423E070D +:1039E000F1113E07F1103E07F1123C1FFA1C3E0791 +:1039F000EAE34412BB7C8400845F382080088C0199 +:103A00005A0841FDDD9EFC0049FFECA9FC80FC004A +:103A100080C049FFECA6C00784013E07E8CC8400C3 +:103A2000AE34AE35FC802E07F118DD9E4432BB4823 +:103A3000AE18AE59AE9ADD9E3C0FFA1CDD9E3C0DD1 +:103A4000FA1CDD9E3C0DFAB8465FF00F50528F0015 +:103A5000FF4646001000D80684003E07EAE38401D2 +:103A6000DD9E8400DD9E2E17F13E2E57F13F3C0D6A +:103A7000FC744C12C0102E27F13C5A28010CA605EC +:103A80009D49400280B697683E57F13E3E57F13F50 +:103A9000DD9EA6058CA1400280B697683E57F13F97 +:103AA000D90484013E07F13CDD9E2E57F13E2E17CE +:103AB000F13FD9042E07F13CC0103C0DFC748CA1E1 +:103AC000A605400280B697683E57F13E4C12C005ED +:103AD00084003E07F13C8401DD9E2E57F13E2E0707 +:103AE000F13FD8082E07F13C84208E01400080066B +:103AF000DD9E8401DD9E2E57F13E2E07F13FD80753 +:103B00002E17F13C840040000406DD9E8401DD9EFA +:103B1000FC0084A08C81E2A4E807386008043860C7 +:103B20008C0C8CA1D5F9FC8080603C0DFA1C9E4168 +:103B3000E622E8253C2DFC7384200041000AE224A3 +:103B4000E809A159385287025A58010384028C218E +:103B5000D5F7FC00842000410009445000FCE22419 +:103B6000E80DB44342209473B4429F91E6C2E90544 +:103B70005A2004048C21D5F48401FC80DD9EFC4293 +:103B8000F181B541843F101F800F2E17C5D08120D1 +:103B9000C1082E17F118C90549FFFFC83C0FFA1CD0 +:103BA0003C3DFA1C5A300104480001113C1DFC73D5 +:103BB0003DEDFC74B67F84C0B45F004080098E4147 +:103BC0009690E244841F4EF200FD440000FCB4894C +:103BD000FE149960B50550F47FFF5CF78002E9059B +:103BE0005A800404480000E800F28056E92A0042A6 +:103BF00080DE5A4801304442CFCC38420800E69477 +:103C00004EF200DA4452CFCC8C8138428808B48915 +:103C10008880B4A45A500404480000CE4452CFC057 +:103C2000382288004E2300C82252007302420074DA +:103C30008443FEA4956A9693E0A2E90C480000BC78 +:103C40005AF802090222806B8880ACAE0222006C16 +:103C5000ACA7002F0000B4A9C2099928022080094E +:103C6000224200068E418A44D50498A822210006EB +:103C7000004F0001C40988A00240800A2252800738 +:103C80008E818A85D50488A022428007005F0003C8 +:103C9000C5300250800900FF00028EA1E9120280A7 +:103CA000800250747FFF850240F2A1F642F11C733E +:103CB000402794560250800A02F080038EA1D5114D +:103CC0000280800350747FFF850240F2A1F642F12A +:103CD0001C73402794560250800A02F080028EA185 +:103CE00050F7FFFF4082A11642823C734044149675 +:103CF000A54AE045E9029EA94E2400038440A54B55 +:103D0000E085E9029F294E440003848084E680AA6E +:103D100042531C73B4FF40F2100A40838C0858844D +:103D2000000210828000007F00024081100ACF0A4A +:103D3000949484F01082800110F28002971FFEBEDE +:103D4000D509952484F010F2800110828002969F9C +:103D5000FF3EFEA7B489AEAB88800222000AC203F0 +:103D60009690D502844180AA84E642531C73AEAC7F +:103D70000222000BC2039690D5028441AEAD845F4F +:103D80001025003C1025003D0020800CE642E91182 +:103D9000B449884000210035CA02844140451800DA +:103DA00010220046B4498802200000361002006E3E +:103DB0008CC197B0B41F8C019600B61F48FFFEFE61 +:103DC0001005003E1005003FD51C2E67F110C619E6 +:103DD0002E07F11100150000E61EE8059403965722 +:103DE000FE0FD503440000F0100500002E07F1126D +:103DF000106500011005000284013E07F11884C01F +:103E00002E07F1185A00FF0DC00BCE0A841F3E0783 +:103E1000F1183C0DFC458C013C0FFC45D5033E6779 +:103E2000F1185A3801173C0DFC7300400009E2C438 +:103E3000E810F0018426FE74B4408A868406FF04EC +:103E400096488822500F800F84408E8149FFFE6281 +:103E5000F001B420840080A150208040083280010D +:103E600088039600DAFCFE02100080408401C6023E +:103E700084003E07F142FCC2FC2084418062444041 +:103E8000004080E080C149FFFE453C0DFC7300000E +:103E9000000CE602E9105053804650130046507360 +:103EA0008050080280011800800120028027100045 +:103EB0008027DFF8FCA0A60092038C1596275C00F3 +:103EC0000014DD9EFC4080C1A640844081203E2736 +:103ED000F141C1312E07F13D5A08010C2E17F14076 +:103EE0003E27F13C3E17F13E3E17F13F3E07F141C0 +:103EF00049FFFDBB3C0DFC742E77F13F3C1DFC4E91 +:103F0000A7048441040480014213907380628E816F +:103F100049FFFE002E07F1425A0801063E07F13D17 +:103F20003E77F1402E07F10C5A00FF088C013E0746 +:103F3000F10CD5033E17F10C2E17F141B4065A18B7 +:103F40000132A605C81849FFEA15C80F3C0DFC74DC +:103F5000B4262E37F140A6843C0DFC4E42018873F6 +:103F6000B42149FFFF8BD50A49FFE9C249FFEA02A4 +:103F7000C8FED5ED49FFE9FEC80349FFEA0BB426A8 +:103F800084003E07F1413E07F13D8401AE0DB426A9 +:103F9000AE0CB4C6B40649FFFF905A080141AE37D3 +:103FA000D53EA644C90549FFFDA8C039D50DA605D3 +:103FB0005A08010849FFE9DEC83249FFE9EBD52F6D +:103FC00049FFFD8DC8F849FFE9D580E0C82849FFC1 +:103FD000FD6E3C0DFC74B4262E97F13EA6843C0D7C +:103FE000FC4EB4214204887349FFFF482E17F13D6F +:103FF0005A1801112E57F1404C54C00DB4063E77AB +:10400000F13DAE45B4E6B40749FFFF575A08010336 +:10401000AE3F49FFE9BFB4068421AE44FCC0FC209A +:10402000804080E14402BB64A0514462BB7CB62066 +:104030002E17F1183C6FFC4A10100008A052A8413E +:104040004412BB6049FFFD9D4402BB582E17F11876 +:10405000A981AE40B4273C1FFC474412BB5449FF22 +:10406000FF334402BB488420AE40AE41AE4249FF1C +:10407000FD44FCA03C0FFF9BDD9E3C0FFF9ADD9EA4 +:10408000FC41F5814082801141C2C00A445000FCCD +:1040900042019473005000182260800054A28001F5 +:1040A000221080014EA2000D4472C7B884A038537C +:1040B0008C084472C7A838538C084800007301E08C +:1040C00000E15BE8030B4452C7B838A28C084452A5 +:1040D000C7A838A28C08D5654FE300214472C7B841 +:1040E000852338538C00814542A1A473409508086C +:1040F0008CA144A2C6F4892A9768E6A312648000C2 +:104100001214800138538C08E94C4452C7A8852109 +:1041100038928C0839E38C08D5445BE8014344921B +:10412000C7B884E338548C0081E542F19C7340F7B2 +:1041300088084472C6F440F79C008CA19768126707 +:10414000800012178001E6A338548C084452C7A897 +:10415000E90539E28C0838A48C0838528C00CD056A +:1041600038548C00C51ED50284A3842C42718473FC +:104170008460802380C3549180FFE325E80E409142 +:104180008808892738A38E010294800188CA88296B +:1041900097B3964B8C61D5F0406314D6401094369B +:1041A000003F80285A380128B4005A0801253C5D98 +:1041B000FF9BA42DE280E81F403320014E34000312 +:1041C000FEDA4000F0014E040003FE028803A4EE74 +:1041D000E003E811A4EF9F194001840942127073B3 +:1041E0004262207388C0880140630CD640100C36B0 +:1041F00097B3964BAD90AC51FCC1FC403DCDFF9BBD +:104200002E700431005E0016006E0017CF0540A22C +:1042100080139771D504445000508145446000FCE0 +:1042200042019873B50084DD40F418024492C6E45C +:104230004462C6D44472C2245AF00105000000E072 +:10424000C018840038048C08840138030C08FAC4B0 +:10425000FF9C220080004442C21438039A0995B2A0 +:104260002210800188C738A20C08AC714800009168 +:1042700038030C00E614E8048C0138030C083804F9 +:104280008C004462C6E4E613E9038400D5028C0185 +:1042900038030C0838948C00FAC4FF9C02F08000AC +:1042A00040049800A44938F3820994028807AC417D +:1042B000021E000DE081E90380AAD51003CE000C98 +:1042C00040FE1007E80B8B454002700142050024B8 +:1042D0004040F0014040109688A444A2C2145A887D +:1042E000040438550C0038450C0084038024421225 +:1042F00080738C22840440008016E0804482C214C3 +:10430000E8058C81E08040023C1B38040C08440224 +:10431000C6D438450C0038100C00840AFE44E081F5 +:1043200040123C1B854040008016806A808A4CA069 +:1043300000134054980038839611956A88A788889E +:104340002252800188654E9200048F21D502FB2302 +:104350008D41D5EE84AA4202142442419424403077 +:1043600094B6C50C88C938339A1195B288C74202F1 +:104370008C732233000142428C734030840A8803DC +:10438000886440000416401184369603964BAC10A6 +:10439000AC51FCC0FC41445000FC42019473447297 +:1043A000C1D8B4A02280800023C080014462C19C97 +:1043B00038138E02853D40949402F18144A2C1607D +:1043C00038130E023C5DFF9B5A900105000000E08F +:1043D000C00A0202800F38838E0A39C30E0A3805DC +:1043E0000E0AD54103E2801140FF1007E9040202E2 +:1043F000800ED511029280120202800FE089E80B34 +:1044000002F2800E8A9E8A0FFF044004F8014002E7 +:104410000016880F38450E0285234240247380041D +:104420000252801084848C02400010164092800159 +:10443000964B4214842440428409421070738824AD +:104440004010943638130E0A221F800238050E0AD7 +:10445000421484244210207381218924405494B64C +:1044600038538E0A38038E02AC1038030E02AC119A +:10447000FCC122200000E022E8153C4DFF9A0232E8 +:1044800000098E618A61E043E80D22200001E022EC +:10449000E8090202000A8E018A01E0405607800105 +:1044A000DD9E8401DD9EFC0194928822F081223001 +:1044B00080009603E060E8045231843796DB2200E6 +:1044C000800122FF8003E00FE8045200096B96038D +:1044D000E0604001BC1BFC81FC0196435EF0821D44 +:1044E0009010E90452108438964B5EF004B7E9044A +:1044F0005200096C9603E0204000BC1BFC81442064 +:1045000000FC42008873B4205A1802058420101061 +:1045100000F7DD9EFC41F60BF081440000FC4223D5 +:104520000073000100188122960EC85AB4028E0151 +:10453000E602E8563C83F43C50047FFF9600427349 +:104540002024C00B9887945288238E010410FFFF0B +:10455000960038118A0AD5F6400408080474803B96 +:10456000FE343871800A01C480F35BC0093A5CF202 +:1045700089C4E836F0018144B67F49FFFFAF5EF0A1 +:104580000065E8074402E1B0380018005A08012924 +:10459000840A421380244603FFFF9CB150000FFFA2 +:1045A00042012073B45F380102028447FE14E22006 +:1045B000E8174FC3000B3C0DFA9BB4009206960619 +:1045C000C80444003840D50344000E1038051A0AC8 +:1045D000F00A8426381018088409100480F3FCC1FE +:1045E000442000FC42008873B4604422BD745A38F1 +:1045F000051D003000F75A380111440000643801ED +:1046000005092E07F338E603E9043E300463D50DAF +:104610008C013E07F338D50984003E07F3383E008D +:10462000046384003801050938010501C00C8E01BE +:104630004422BD74960138010509C8053E07F338C8 +:104640003E000463DD9E444000FC42019073000084 +:1046500000F35A0006045A08090A8823A608C00471 +:104660008E01AE08DD9E38010E0ADD9EFC21F3812D +:10467000F3093C73F43D8843A710E287E8238C815B +:10468000AF10444000FC4201907394DA998B3C13C4 +:10469000F4778480FE4C104000F3B626A6504C13ED +:1046A000C0128421101000F3F008B0418803844444 +:1046B00080E5490072833C03F475FE04B60684006D +:1046C000B607FCA1FC01956A8885F08122220000D2 +:1046D0009603E040E8045221043796932202000139 +:1046E00022FF8003E00FE8045200096B960388253F +:1046F000E04040013C1BB44142300024E262E80D3E +:10470000E406E9048E05FE04B6013C03F475B441E9 +:10471000FE04E240E802B601FC81443000FC4201A4 +:104720000C73003000F5CB090430003B5EF197714B +:10473000E9048461103000F5003000F55A380113A7 +:1047400094D28861B4835CF20E10E80444400E10E9 +:10475000B683000000F35A0801063C03F475FE041A +:10476000B6033C0DFA9BB400920296065A08010F5C +:104770002E00044F5A08010B94928822B4015CF079 +:1047800007E9E804440007E9B601DD9E2E30046322 +:104790005A38011794D28823B4615CF1A710E80459 +:1047A00044302710B661443000FC42010C73000015 +:1047B00000F35A0801063C03F475FE04B601DD9EC1 +:1047C000FC01F081F007444000FC421010730040EF +:1047D00080F9CC1D22508006C50E3C6DFF9A024325 +:1047E00000098E81D40822508007C5050243000AC3 +:1047F0008E81DC0D8482104080F9848638418008E7 +:10480000443019003831020A104080F3FC81000066 +:10481000FC41F70AF481953A40A11000B44AE24104 +:10482000E845441000FC4203847380C0000000F39C +:10483000E602E805000300DE5A000139840F100388 +:1048400000F8B041982C84448123490071B784005A +:10485000B60A2E000431C0028409B60A8400380466 +:104860009C08000300F3E60EE82144F0477838077F +:10487000800040F03C00DD0F0E1232321A321E3240 +:104880003216322232268403D50C8402D50A840AD9 +:10489000D5088405D5068407D504840CD502840E7A +:1048A000100300F38401100300F6FCC1442000FC57 +:1048B00042008873001000F65A180305842810106F +:1048C00000F3DD9EFC003C13F479840F49FFE89669 +:1048D0003C0BF43D3C13F479840449FFE88F3C0B16 +:1048E000F43CFC8080413C53F4783C13F479D108CB +:1048F000FC009982A63049FFE887AE30FC80DD9E3F +:10490000FC0196CB9683903090108A018A43FE0476 +:1049100042010873FC81FC41810084003E00046276 +:1049200049FFE48C5A080242812884C04421869FB2 +:10493000000480F75A0001098CC197B0509480FCA4 +:104940005A680AF8D527040480165A0801F78148E6 +:1049500084E05034800C000500F75A08011505C5A5 +:1049600000165BC801114C63800FB40304150003EB +:10497000F281B67F49FFFFC6F201B47FE240E9034E +:104980003FC004628CE197F850A500FC5A780AE514 +:10499000D5D42E0004625A08010544000053D50303 +:1049A000440000A73C0FF243FCC1FC43F085000F1C +:1049B000803CF184E603F281810305CF800EF7107D +:1049C000E90B2E17E969C90DE606E80B44A000784B +:1049D000852F84C8D50A44A00078852384C5D505D1 +:1049E00044A0003CFB2EFAC03C0DFA9BB40092029E +:1049F00096065A08010A2E00044F5A08010644A0E0 +:104A0000003CFB24FAC92E000431C00544A0003C40 +:104A1000FB2EFAC0F004F105F583F48249FFFF7222 +:104A20005CF009C4E83FF402FFB4E286F503E8371E +:104A300041CE1C00000E0000E340E824947A3822A6 +:104A40009E0188A1F105A42940004008FE1749FFF6 +:104A5000FF59E206E815F00549FFFD405EF00065EC +:104A6000E90F440000FC04AF800142A380734214AC +:104A7000A424840438141E0A100500F3D5138400FE +:104A8000D50BC807943A8805B04584444900709610 +:104A9000000E00008C01100E0000D5048400380EBA +:104AA0001C08FCC3FC4199DCF081A638E615E93707 +:104AB0004402BD34814138001202F10180C48122D8 +:104AC00049FFFF205CF00384E826440000FC3C33EF +:104AD000F43C42A30073840042130C248080E283E0 +:104AE000E80E98A10455003B38248A028A454E24DA +:104AF0000003FE928C8188029720D5F28E6140F0EF +:104B00000DF75CF781918401E80284003E00044FB8 +:104B10008400D51284003E00044FD50EC80C441208 +:104B2000BD34022F80023820920995228881021F0D +:104B30008003AC618C01AE383C0DFA9BB40092024C +:104B40009606C8033E00044FFCC1FC4180E281216F +:104B50008045802480C5F0818103814449FFFCA504 +:104B6000441000FC42730473001380F85A180F2697 +:104B7000381419018C2FE201E8048400100380F43A +:104B8000000380F45A08011A95B28926F001022424 +:104B900080010214800040214008FE5749FFFEB208 +:104BA000E609E80840051800802984444900700699 +:104BB000D5048400100380F4FCC1FC418501B61FBC +:104BC00080818120838185404004A001E320405EF4 +:104BD00028014C5780234074A000E2E9400E2800D1 +:104BE0004067800040037C0892E1FFC792C18007C4 +:104BF000802680478066F48149006FC0F401E2811D +:104C0000E9094C124005B43FE220E90481078146DE +:104C1000D5DC81278386D5D9E602E8DE8008802AA4 +:104C2000FCC1FC42F60DF083440000FC42330073EB +:104C3000000180F681428385048F800C81235A080D +:104C4000016E003180F35A3802073C73F47410048B +:104C500080F4D5195A3803053C73F474D5145A38C6 +:104C60000505100480F4D50D5A30070C5A300AF6A9 +:104C7000540180FD84E05A080C0744700078D50385 +:104C8000447000323C2DFA9BB402920696065A08F4 +:104C9000010495F997F92E07E97CE603E80B8E628B +:104CA000E662E808B40292069606C8048405FFC4CA +:104CB00097F994F24402BD14990B84408024382063 +:104CC000190940040C008444F382F48149006F7692 +:104CD000F0038028804649FFFBE8E207F401F30275 +:104CE000E804380E1909D503387E19099431881C57 +:104CF000A440C9038421AC4040150C00A420A54861 +:104D00004422BCD88A05A44938011A09A421886222 +:104D10008A01AC198402100480F6000480F85A0855 +:104D20000F61000480F64432BD1495F25A08030F57 +:104D300040051C00B0438444F38149006F3FF301F8 +:104D4000380E190138019909D54C004480F4CC1C67 +:104D500038141A018907F00302240001F38240216C +:104D60004008FE57F48149FFFDCDF401802449FF3E +:104D7000FF26F30296013C0BF94E38119901E2200F +:104D8000E80338019909957188BC38119901A42864 +:104D9000E220E9084412BD14380099098403100484 +:104DA00080F6381199014432BCD8A52838019A11EF +:104DB0009AA1FE14022F80068947400010169A100F +:104DC0001205000088E3A4A8223380019A11421141 +:104DD0008024020F8007401088369A411215000186 +:104DE000FCC2FC422240800022608001441000FC92 +:104DF00042018473B520F2824412BC98955A3C7DDE +:104E0000FF9B5A980116AD10AD9138408E09A63D12 +:104E10008825AD895A000104480000F24402BC5CB8 +:104E200088A0842038100E09AC69480000E9A6BDAE +:104E300000A00018F2835A28014054050002C03C2B +:104E40004402BC5C38700E11CF0888A02202800199 +:104E5000C03338408E11D530880522000001C805C6 +:104E600088A122628001D52888A181E422428001A4 +:104E700052938000FFE438408E114250002442706B +:104E800010754244A4244082900043C0242442422E +:104E90003C24424E187542401C75FE0242002424F8 +:104EA000FFAC42603C7342649C7540422096406374 +:104EB00020D6972397B3540500024E0200833C0D81 +:104EC000FF9A80E402A00009E08AE90838908E1178 +:104ED000E12AE80F50957FFFD50C4E44000838902A +:104EE0008E114E9500078520D50481248500D502BA +:104EF00085010250000A41E18808E0C58006E90A00 +:104F00004080F80022840001E105E8105082FFFF94 +:104F1000D50D4E6400094080F800228400014E84C3 +:104F20000069D5045A88014E810639C08E1141E0CE +:104F3000F80040227001B65F222F0001F28140F399 +:104F40000801B45FC20C84024001001641E4F00184 +:104F5000420F3C7340000816F2018802E80DF2018E +:104F600084E241E40801B45F40779CF6427F087315 +:104F70004073BCF688FCF2014C81003EE0EAE90592 +:104F800052A500018947D5054E74003652A3800012 +:104F90004C9E000CE005E9055252800188A0D50620 +:104FA0004E040004FF42D50284A0E0AAE805404474 +:104FB00080119783D506E145E804973B40640011D2 +:104FC000F203941A5A28010E38708E014452BC5CC8 +:104FD0009BE738728E0999C888A0A5F99BF7ADE9BF +:104FE00038408E098820F002AD89AD00AD81D5072B +:104FF0008500D59C85404C9E7FCFD5E3FCC2FC400C +:1050000022608000225080014412D560AD90AD51E5 +:10501000387090003C6BF9103C5BF9115A7801171D +:105020004492D788386491094492D15038549109F8 +:105030004492D0803864920A4462D45C3853120A95 +:105040004452BC4838729008D5665A78026544A22A +:10505000BC4838751000E6EAE8124482D0808CE142 +:10506000389412023875100889263894120A44823E +:10507000D45C3894120289253894120A4472D78875 +:1050800038A39111407518014E740003FFFA5EF3C6 +:1050900080B54492D150E9103884911150F2800EBD +:1050A00040F7A007E8125EF380DDE9095072800F37 +:1050B000E0E8E90BD5045EF38051E90A38849111E8 +:1050C00050F2FFF1E10FE80484E43870900838747E +:1050D00091115EF384B6E80550938028E125D50848 +:1050E000449004B64C74800950F3FFD8E0AFE80454 +:1050F000852338909008389090008F23E722E80BA2 +:105100004492D54C8ACA386491094462D13C8AA73A +:1051100038531109385090005A5010045A5820231F +:1051200084A03851920A4432D78838319111ACD0DA +:1051300038509000443000FC42020C735A5810085A +:10514000846B103000F34400096BD508846D103077 +:1051500000F34402D15038001111AC118400380022 +:105160009008380090005A08051E4402E1B08421DE +:10517000381010084402BC48383010004402D08077 +:10518000381012024402D45C40108C3638001202EF +:10519000AC5040000C16AC114402D560842038108D +:1051A0001008FCC0FC45F0852E07E97C049F8005B3 +:1051B000F08722008000F2863C0BFB9222008001E7 +:1051C000843D3C0BFB93440000FC42918073B40986 +:1051D00080C3FE0E4482C14C44A2C13C5A0001056A +:1051E000000480E0C04D3C13F4774442C100FE4C03 +:1051F000840038121A0A3C13F43C380418083805A5 +:105200001808100480F3100480F4100480F51004D2 +:1052100080F68401100480F7422304248400443281 +:10522000BF20E201E80999C204A4803B8C0138A1A7 +:105230009E0A9600D5F794F24472BEE498BBF0053E +:1052400088644412C15C808649FFFEDB4402BEA82C +:1052500038A39A024410003238A01A0A4402C15CF2 +:1052600049FFF9094412BE78100480F9840038001F +:1052700098084412BE6838009808480000BB447281 +:10528000BEA83C1DFDC938038E0249FFFB3BF089D7 +:105290008026800849FFFB28FA00100480F80004EB +:1052A00080F38127E602E827B1493C3DFDC944422D +:1052B000BF20F0058048B6FFF6814412C10049FFC7 +:1052C000F9D7F00580464412C10049FFFA28F005DD +:1052D00080464412C10049FFFA5B3C0DFDC94412EF +:1052E000C1004422BE984432BE88808780A649FF10 +:1052F000F9EBD5369E42E622E9085A0005079E479B +:10530000E622E9035A080A2DF005802649FFFAD063 +:10531000F005802649FFF8F54402BE78B61FF00775 +:105320004412BEE4F081F6823C0DFDC938109A02A9 +:10533000F2054432C100F4094452BE2C49FFFB3748 +:10534000B73FF6813C0DFDC9F1054422C10044324E +:10535000C13C4442BE984452BE8849FFFA333C0DDA +:10536000FDC9F1054422BF204432BE68808649FF52 +:10537000FB9B4442C100F5093C0DFDC94412BEA887 +:10538000F2054432BF20B75FF68149FFF8C5F0054A +:105390004412C13C4422C100806649FFF956447260 +:1053A000BD94F005F1094422C1004432C13C3C4D9A +:1053B000FDC94452BEA8B6DF49FFFA2C3C0DFDC919 +:1053C0004412BDF04422BEE4F3054442C1004452FD +:1053D000BDD0B6FFF68149FFFC263C0DFDC9441245 +:1053E000BDF0F2054432BDD0808780A649FFFBAFF7 +:1053F0004412BEE4F20638009A11AC1094328801CF +:1054000022000001AC113C1DFDC94402BDF0381062 +:105410001A0AFCC5FC408140440000FC4232807303 +:105420000001801880E4960680C54492BC0CC00937 +:105430008402380114088400380094088400D54A96 +:1054400041C09400000E0000E603E8048C01100E39 +:1054500000004081180000040000E602E903840017 +:10546000D5028C0110040000A479A4B84010C00833 +:10547000FE5738049A0249FFFA4544100064FE0CB6 +:10548000842049FFFB9C8080846300040000FEF4BC +:10549000880384A03845020A94DA000E0000886A66 +:1054A0008025E2A0E806382196028CA18822D5FA50 +:1054B000402004098841401100369A8C80014E2416 +:1054C0000003FE925EF10051E9058C8188244000C2 +:1054D0008409A47838149A0995B288C9A479AC7162 +:1054E000FCC0FC433C1DFF9BF0823C0DFA1DA44D0B +:1054F000E201E8048C013C0FFA1DF00284C05070F8 +:10550000000C3C0DFF9A00300009E2C34EF200820D +:105510000403FFFDC0755A000574A43A4412C7DCA9 +:10552000120F800AA43B4422C7CC120F800BF30257 +:10553000B10580A64402C7EC49FFFF6E3C9DFF9B6E +:10554000F083B045000480018041B61F8066F00200 +:105550003C4DFA1D3C5DFF6449FFF5940004800357 +:10556000C008B045F00280418066F40349FFF64769 +:1055700000048004C008B045F00280418066F40356 +:1055800049FFF70A00048002C007B045F0028041DD +:10559000806649FFFE09B0458041F002806649FF00 +:1055A000E730B045F0028041806649FFFC1C220FC5 +:1055B000800A4E0400058400120F800A3C1DFF9AE9 +:1055C000222F800A02008009E040E9048E01120FB8 +:1055D000800A220F800B4E0400058400120F800BFE +:1055E0000200800A221F800BE020E9048E01120FC6 +:1055F000800B020F800AAC38020F800BAC3980267A +:10560000F00249FFF7EF8CC1507380FC48FFFF7B2D +:10561000F502444000FC80C5426190733C27FEC8FF +:105620003C17FEC93C0DFA1D8066D30CB4855A4860 +:10563000050722228006221280078400505280FC37 +:10564000D5F53C2BFEC83C1BFEC93C0FFA1DFCC324 +:105650003C0FFF9CDD9E3C0FFF9DDD9EFC4483853F +:1056600080C0FAA2B5444260947340930408405548 +:10567000240084C0A7E8B6C2A9915A78FF05B6E312 +:10568000A9D9D514A7E8A1A138631D01447000FF72 +:1056900097AFA9D9A1E4B6C395B188C7A7F14C03C8 +:1056A000C005A7B04C13007884C19FC1B6FF9DC14F +:1056B000F781B1C4F082F0839E09A83AA628F1844C +:1056C000A8798C21A87B50007F01842040008006AF +:1056D00045E00012385F8602E6B2E81A3883860297 +:1056E0005CF40024E81542547873385515005A507C +:1056F000FF1004820001C80638041501962FB60376 +:10570000D50638041501B4A3962FD80684018C2140 +:105710005A1804E2D545842045E00012380F86026D +:10572000E612E835384386025CF20024E830420293 +:105730007873384501005A40FF2B385E0111380E4E +:105740002411E005E8249A2838541101976F5A6013 +:10575000010CC6045A600211D520B6A3B48284C1DC +:105760008804B602D514B483D409A959A11184C2FE +:105770008804A811D50CB483DC05B4828804B60271 +:10578000D506A119DC0CA1118804A8118C215A1886 +:1057900004C7D5038401D5048006D5028403FCC464 +:1057A000FC4A80C08400F283B63FB08A8060B43F78 +:1057B000E201E808944388248C01A04938310408A8 +:1057C000D5F784A0B08A8781B41FE2A0E857942B54 +:1057D000880405E30001A001383F01014C30404D31 +:1057E00038010C00C849945AF181D042944388246E +:1057F000049F8001A1C9A07540F0A4000097800219 +:10580000149F800200978000149F800400978001FD +:1058100000F78003149F800540938808882950F77B +:1058200080010080800300A0800000908001A64AD3 +:105830008E2140F78407E91CF1028D018E21E101E0 +:10584000E917F1058F418C21E02AE912F1048D213D +:105850008E21E121E90D380F1D0139C10C084C03DF +:10586000C00C38110000C90839C10008D505B43F83 +:105870008C01E201E9BB8CA1D5A885002E07E94384 +:10588000E3004EF20104A031385021014C5440FC99 +:10589000B00A380020005A000104480000F5A07545 +:1058A000400408088801A7C2E6E2E9048EE197F8FF +:1058B000D50284E0A6435CF08022E8048C2196485F +:1058C000D502FA33F184A640E622E9048E219648F7 +:1058D000D5028420A601F181E610E8048C0196002F +:1058E000D502FA01F085FA02FE3CF082F004E007EE +:1058F0004EF300CA04AF8001F002F103880A94015C +:1059000040908000F005E00A4EF300B9F00341C476 +:105910008001B406881CA6405A18FF04480000AB5A +:1059200020000001221480004E0500A54E1700A3A0 +:10593000B41FE6064EF20098800A8027B086B0C8F1 +:105940008086F50349FFFE8C5A0002044800008C53 +:10595000B406A0F1F1083800700038518501380113 +:105960008101962FD93FB04A381094005A18013B54 +:10597000F10622F48000F2074240BC248841401224 +:105980000836A136D8199482996240178401B4452B +:1059900042250475B645F208A13794928844B48232 +:1059A00042438475B682F208044300089492884406 +:1059B000B4829A61D516956A88A4A137B445422568 +:1059C0000473B645F20894928844B48242438473C7 +:1059D000B682F2080443000894928844B482882472 +:1059E000B622F10938518501D93EB04A38109400E9 +:1059F0005A18013AF10722348000F20642408C2402 +:105A0000884140120836A0B6D818940299509A5985 +:105A1000B40542050475B605F009A0B794028802E2 +:105A2000B44042238475B640F00904230008940270 +:105A30008802B4409A51D516956A88A2A0B7B405D9 +:105A400042050473B605F00994028802B44042236B +:105A50008473B640F0090423000894028802B4401D +:105A60008822B620B406442FFF80881CA641FE572A +:105A7000AE418D418D2248FFFF47F0028CE18C1230 +:105A800048FFFF358D0148FFFEFBFCCAFC403CADE2 +:105A9000FF9D80C184E085019B31E282E832A1470D +:105AA0000843000101C5003238F292020450000898 +:105AB00038929202A14638529202425E1424405219 +:105AC000A4B7AD5800450033424790244042249784 +:105AD000AD192EF7C5DBE8135052FF8797695CF2CA +:105AE0008347E80850427F8797215CF2087BE802F1 +:105AF00088E95CF38DADE9033E8004608C68D5CD08 +:105B0000FCC0FC4181208400B63F80E4AE28F281D5 +:105B100080C53C0DFF9D84204442C8B0E223E811BB +:105B20000424800138510501D91EA6B03812080896 +:105B3000A6B08C419690AEB000500019E245E91332 +:105B40008009A670B45FF301808749FFFE2B8009AE +:105B5000A6B04412C8B0806749FFFF9A840044226F +:105B6000C8B0D5038C21D5DBA670E201E8089443C8 +:105B70003831000088278C01A8C9D5F7FCC1FC206A +:105B80002E07E94AFD325A0801053C0C0180D50E6A +:105B90009E0CE602E9048E28E622E8043C0C017C17 +:105BA000D5052E07E9694900082DB607B4073C1C46 +:105BB000017A4C00800A3C1C017B4C0080063C1C96 +:105BC00001874C00C0048421D5028420445E00007B +:105BD00088A03C0FFAA592A244027B9097693E17D9 +:105BE000E928AD404403F40044101EE4AC404403F3 +:105BF000F40297B0AF80FCA084003C0FFAD74403B6 +:105C0000F4038421AE40DD9E4403F403A6005C004F +:105C10000001DD9E4403F40CA6009600C80744135F +:105C2000F3CFA64840000406DD9E8401DD9E4413A8 +:105C3000F40384003C0FFAD7AE08DD9EFC005A083E +:105C4000011349FFDAFB5A0802074403F010441F0E +:105C5000FFAAAE4049FFFFD284003C0BF4DE3E07B2 +:105C6000E95AD50349FFFFE5FC804403F01DA680F7 +:105C7000A641A6C04010A008FE5758108400968880 +:105C8000AE809228A681AE414413F42144200055F1 +:105C9000AE88442000004430000A502100014C210D +:105CA000FFFE8440AE88442000004430000A5021AA +:105CB00000014C21FFFEA6409648AE40DD9E8400C8 +:105CC0004442D4EC4452D2284412D1744432D5E434 +:105CD00038228000382200083821800038208008CF +:105CE0008C015A0820F7DD9EA640A7053E100D0046 +:105CF000A641A6C73E100D01A642404220083E1014 +:105D00000D02A6434031A0083E100D03A64400201A +:105D100000088881A646972388610010000996DB59 +:105D20004010A00888223C1806840010000B0020B8 +:105D3000000A4010A00888223C1806850010000CBC +:105D40003C4806823E100D0C0010000D3C380683C6 +:105D50003E100D0D0010000E96463E100D0E001068 +:105D6000000E922196463E100D0F0010000E92225A +:105D700096463E100D100010000E922396463E10DF +:105D80000D110010000F965F3E100D120010000F55 +:105D900092243E100D13001000110020001040103E +:105DA000A00888223C18068A001000130020001268 +:105DB0004010A00888223C18068B00200015001017 +:105DC0000014968F40212008884196933C28068C29 +:105DD0000010001592223E100D1A001000170050FE +:105DE0000016964F4010A0088825964B3C18068E4A +:105DF0000050001792A23E500D1E0000001E962F6C +:105E00003E000D2840022C0A9606C006440FF00002 +:105E1000FF073C4806824001AC0A9606C006440FC4 +:105E2000F000FEC73C3806834001240AC006440F38 +:105E3000FC00FE873C28068C4000A40AC006440FE4 +:105E4000FC00FE473C18068EDD9E3C1C017A440E89 +:105E500000008801920244127B909601AC08DD9EFE +:105E6000A40044120000940288013C0E0180DD9ED3 +:105E7000FC004423F6A84413F6A95A080105AE1005 +:105E80008407D5038400AE10AE08840080208040D3 +:105E9000FA6F490015B5FC80FC20B48084608C84C6 +:105EA00084E6B4045A380506920A40002808D5044E +:105EB000921E4000780842219C24969084A05A208B +:105EC000200C386088008C414063140C8CA5880637 +:105ED00096905A581EF68C6196D8AA215A3806E335 +:105EE000FCA0FC00B48084408C9C840080A098D0EE +:105EF00096D8958238308C008C0196DF4031980C12 +:105F000088A35A0808F68C489690AB615A2820EF6F +:105F1000FC80FC04A649B4405A1003045A180D1121 +:105F20002E17E969542080FBCA044412D718D505FE +:105F30005A1803254412D52049FFFFD5D51F5A18FA +:105F40000408A0578410FE0E58000003D5165030E8 +:105F5000FFF6E662E80A842084463820FC088C219B +:105F60005A1820FD803FD5E98E28E622E807A05781 +:105F70008410FE0E58000004A817FC84FC00A681C3 +:105F800080C05A2003155A2006139E14E602E90F1A +:105F900050017FF8E602E90D50017FF6E602E909BB +:105FA0005A280D1C49FFD94A5A0802048400D50218 +:105FB00084013E07E90B2E07E90BA6712E27E92184 +:105FC00084812E37E93E4452B4E449FFFDDA4402AD +:105FD000B4E4802649FFFF9FFC80FC00B48084402D +:105FE0005042002C840080A098D096D895823830FA +:105FF0008C008C0196DF4031980C88A35A0808F673 +:106000008C489690AB615A2820EFFC80FC0144122A +:10601000D4ECF08149FFFF42F0014412D17449FFF2 +:10602000FFDEFC81FC442E200D124472D718812023 +:10603000386388004442D4EC8EC25C6300014402A1 +:10604000D1742E300D015A18063C842A38120808E3 +:10605000E662842238100808E96B49FFD8EF5A0835 +:10606000026884005A9803182E100D0184004432EF +:10607000D52038218000382F80088C015A0820FB59 +:106080002E000D12C00F881F8E228440E24110F0B6 +:106090007FFFD50838138000381F80088C015A080C +:1060A00020FB2E000D1284295A600103842A381F18 +:1060B00080084402B4E4803F49FFFF15D5398420AD +:1060C000381208085014FFFDE6228423E9028421D7 +:1060D000E66238100808E92C49FFD8B05A080229AE +:1060E00084005A9803192E000D0184285A080203CF +:1060F000842784004432D52038218000382F80083E +:106100008C015A0820FB2E000D12C00C881F1010A5 +:106110007FFFD50838138000381F80088C015A088B +:1061200020FB5A6801C82E000D128422D5C14402FA +:10613000B4E449FFFF6DFCC43C4C0187442200FCE1 +:1061400054000FFF0412001240004808923054100F +:10615000FFFF944A8822462C003F043080085021DB +:106160000FFFFED6FEC7143080080412001244321E +:10617000015092305410FFFF944A88230430800865 +:10618000FE9EFE8714208008DD9EFC004412907461 +:106190003800811149FFFFD2FC80FC4180C0812280 +:1061A0003C0D9853F081CE04AF908441D50E80E130 +:1061B0005A680406800149FFFFEAD504B00138603F +:1061C000040010748000844384004432D174386128 +:1061D00080088C014412D1745A0820FB2E000D1245 +:1061E000382080084402B4E449FFFEF9FCC1FC01F8 +:1061F00080C03E07E9698001B65FF38149FFFEC0B8 +:106200008006B43FF20149FFFFCAFC81FC408400D4 +:106210003E07E90B3C0DFA9884232E67E958A7C185 +:10622000AE4149FFFD4E840080404432B3903C1D96 +:10623000FA982E97E96949FFFFDC4402B4E444125E +:10624000D22849FFFE2B84033C1DFA988046443235 +:10625000B39049FFFFCEE7228403E80284003E07A3 +:10626000E9694412D2284402B4E449FFFE172E071C +:10627000E9693C1DFA9880464432B39049FFFFB962 +:106280002E07E9693E07E9513C0DFA98AFC1FCC001 +:10629000FC002E27FE9684C340111857443000900E +:1062A000969044125F6042110C734420004849FFED +:1062B000DA532E07FE968C019600406018379648F8 +:1062C0004010041B3E17FE96FC80FC002E27FE9516 +:1062D00084C34011185744300120969044125C004A +:1062E00042110C734420009049FFDA362E07FE95C8 +:1062F0008C0196004060183796484010041B3E17EA +:10630000FE95FC8084003C0BF4E23C0BF4D32E079A +:10631000E969540000FBC812440228384412283AA4 +:10632000A6004422283B3C0BF4D344022839A600A3 +:10633000A648A6903C2BF4E2D5235A0801208400FD +:1063400044522838802044322850A7283C23F4D3D4 +:106350008CA488443C2BF4D30022FFFD8802002249 +:10636000FFFE0042FFFF88223C23F4E296018844AE +:1063700096493C2BF4E2DBEAD503840080203C23E1 +:10638000F4E288223C23F4D39649880296013C1B10 +:10639000F4E288203C0BF4D33C1BF4E0DD9EFC02CD +:1063A000F082F183B65F8002F1028043F38149FFFE +:1063B000D9D3B41FF103F20149FFD9CEFC82FC000E +:1063C000846080A384DF9718E282E80738500D09C3 +:1063D00038608D098C61D5F8FC80FC56F08384C050 +:1063E000F181F282842044200090B00880E381246F +:1063F000126F800B490063EC8401100F801A100F9C +:10640000801E3C0DFAA6107F8018107F801B126042 +:10641000000C1260000D3C0DFA7D109F8019107F5A +:10642000801C106F801F109F801D490011B5B007A0 +:106430008040B046490011EB3C0DFAA6FA2310103B +:10644000000AAD848400490012A5F001F1038040E8 +:10645000490011A74403F04A44100055AE404900DA +:1064600011964413F140A6085A0001FFB00780407E +:10647000B046490011CC3C0DFAA6FA241010000ACF +:10648000F002F10380404900118C4403F04A4410AB +:106490000055AE404900117B4413F140A6085A0054 +:1064A00001FF8401B0478041100F8019100F801D3B +:1064B000B006490011ACF001F102B0884900117139 +:1064C0003C0DFAA6FA211010000A4403F04A4410C9 +:1064D0000055AE404900115B4413F140A6085A0034 +:1064E00001FF8400B047100F801E100F801F840131 +:1064F0008041100F801DB006107F801C490011875D +:10650000501F80168041B0084900114B3C0DFAA67F +:10651000FA231010000A4403F04A44100055AE401C +:10652000490011354413F140A6085A0001FF020F3B +:10653000800BFCD6FC004440012080C144120000C6 +:1065400042101073800184818022804344300048CF +:1065500049FFFF45AC30FC80FC00EED8F0818400A0 +:106560003C080210B066B00244224A204430004881 +:1065700049FFFF17B042B0A644300048848344026C +:106580005F6049FFFF2C3C080210B042B0A64430C7 +:1065900000488481F00149FFFF223C0802104412A8 +:1065A0004A20F00149FFFE762E07E9695A080415D2 +:1065B0003C03F4C55CF00097E90B9E8150107F6AA4 +:1065C000440FFFCE4000801688029601D503440098 +:1065D00000963C0BF4C549FFD6313C1DFFA60220B6 +:1065E000800E5A0002088403FE8496914430FFFF17 +:1065F000D5030030802A2E47E8C83C000210401224 +:1066000004098801400010169601E2403C0802107F +:10661000E80584023E000424D5212E27E9692E10C6 +:106620000424CA093C23F4E0E262E8058C213E1010 +:106630000424D514C1048E213E1004243C13F4EE2E +:10664000E220E9093C03FF454410EA5FE220E90645 +:106650008C01D50284003C0BFF452E000424E60289 +:106660008401E80284003E000422ED28FC80944965 +:1066700088204430FFFF84404C00800EA500E24497 +:10668000E803A4809691A500E283E803A4C096D90C +:106690008C02D5F35CF180978003E90344000096F7 +:1066A0009A109601DD9EFC4244600240FF8444A2A1 +:1066B000000040032800812144120002F381F4828B +:1066C00080E288268040443000908481FAA049000E +:1066D000111250830120838614AF8003F003FA3433 +:1066E00040AE0000800A49FFFFC40A138001E22087 +:1066F000E8031203FFFFF302F101402E1801882284 +:10670000800A88438481FA7449FFFE690A14800173 +:10671000E220E8031204FFFF51CE00484DC47FE0A1 +:10672000FCC2FC002E0004152E10044EC01E3C0DB1 +:10673000F2485A1801049201D50292023C2C01073A +:106740009601E2402E000425E805E61EE80E8C01C5 +:10675000D50AC00B5CF10E10E905E60FE9038E05C2 +:10676000D5028E013E0004255A18010D2E00042585 +:106770005A081E048405D508E6148406E805840733 +:10678000D503490014D73C0FFA9AFC803C33FF45EF +:106790005CF18033E9109491884184A34C11000C82 +:1067A000A5080A300001FF2C9082926288641A309A +:1067B0008001D5F5DD9E84003E00042484003C0B5E +:1067C000FF45DD9EFC003C03FF455CF00033E9061D +:1067D00049FFFFF384003C0BF4C43C03FF445CF02E +:1067E0000033E90484003C0BFF44FC80FC0080C0C3 +:1067F00084003C0BF4E049FFFD872E07E8C84063A6 +:1068000000D649FFD51B3C13E32C5A000208840331 +:10681000FE4496494400FFFFD5053C0DFFA600004D +:10682000002B2E2004645A28010A84003C0BF4E05B +:10683000C11B2E07E97CC009D50BE2C1E8153C134A +:10684000F4E0E201E8F7D5102E000432C003840121 +:10685000D50C3C1C01105CF08078E9093E00046412 +:106860003C0BFF44D50584003E0004648401FC8099 +:10687000B461AE185A2802049208AE19B4018840D7 +:10688000B641DD9EFC448120B61F80C18400B1C1A9 +:106890003814800038101C088C015A081AFB440078 +:1068A0001554803F844249FFFFE53C0C017BB43F17 +:1068B00044A20000A680AE880400001CB43F9210E1 +:1068C0009C89962FB65FAE09B41F803F8C01B61F1E +:1068D000844244001EDC49FFFFCD3C0C017A803F1E +:1068E00004200012925054217FFF94928942838A9F +:1068F0008442B80C9210540007FF49FFFFBB020509 +:106900000012803F844249FFFFB5B809803F9210D2 +:1069100054000FFF844249FFFFADB41F0015002053 +:1069200044A20150AE40B41F9C41B63F3C1C0187BD +:1069300004208012925054217FFF94928942844215 +:1069400000150020AE41B41F803F8C01B61F040526 +:10695000000C9210540007FF49FFFF8C0205001243 +:10696000803F844249FFFF8604050009803F921062 +:1069700054000FFF844249FFFF7D440FFFAA10031C +:1069800000514413F04A44200055000300515A00BE +:10699000CC04AE88D5FB84003813800038148008FE +:1069A0008C015A081AFB840010030051FCC4FC201F +:1069B000540000FBC00644725C0044600090D505A2 +:1069C00044725F60446000482E07E92F8E01E602A2 +:1069D000E80844024B4044124A20804649FFD6BC96 +:1069E0002E07E92F540000FD5A08011095B184A02C +:1069F00044324B4098AB987D8403A5108E013840FB +:106A0000980DC8FC8CA2DEF7FCA0FC0049FFFEDC60 +:106A10002E07E969540000FBC80A44020A203C1C06 +:106A200002774420004849FFD697D50D44020A203A +:106A300044120A223C2C0277443000908481FAA050 +:106A400049000F592E07E92FC00A49FFFEB62E074D +:106A5000E96949FFFFAE84003E07E92FFC802E1054 +:106A6000044E5A1801052E17C65AD5033C13E301EC +:106A70003C2DFA9BB442924296865A2801048C39E6 +:106A800096492E27E94ECA052E27C65C88229649CC +:106A9000AC402E17C65AAC44DD9E2E30044E5A38F8 +:106AA0000117003000103E37C909A0053C0FF24322 +:106AB000A60A3E07C954A60B3E07C955A4123C0BB3 +:106AC000E4BFA4133C0BE4C48405D514A6C03E3730 +:106AD000C909A0033C0FF243A6083E07C954A60902 +:106AE0003E07C955A4103C0BE4BFA4113C0BE4C401 +:106AF000FA093C0BE4C02E000431C008440001F444 +:106B00003C0BE4C4840F3C0BE4C0DD9EFC405A0007 +:106B1000010A44625C0080864410012044200090F9 +:106B2000D50944625F6044424A20441000904420EA +:106B30000048840080A0385201098C0196C0E262AE +:106B4000E9FB840694494432000081E080E481033B +:106B500084A00A94000102A380004094BD378CA158 +:106B6000892A97681A938001DAF58E019600886168 +:106B7000C8EE95D194C188668423385201018E21D4 +:106B8000964838519C0DC9FA8C019640E222E9F3EF +:106B9000FCC0FC40848084FF838784C180A481443E +:106BA00045E2C8C802F00000548200FF40F78806A2 +:106BB0008120E80F02F0800040F78C06E80A84C0CC +:106BC000386F1008A580E2DCE80883868148D50587 +:106BD00085E138FF1008D50284C0029480000AF0D5 +:106BE0008001892FE3278C818C024074BC1B4054A8 +:106BF0003C1B5A4804D95A60010380AA8005FCC096 +:106C000080203C0C017AC1195A1801053C0C018204 +:106C1000DD9E5A1803053C0C017BDD9E5A180205C7 +:106C20003C0C0183DD9E5A1804053C0C0187DD9E57 +:106C30005A1805043C0C0188DD9EFC002E67E94EC5 +:106C4000CE353C0C0110E614E9313CF7F52C5EF72B +:106C5000FFCFE8043C6E0110D5294400007049FFC5 +:106C6000CF4B3C6BF4DC8006442225B080663C139D +:106C7000E2B6E201E80698428C01AEC89601D5F86A +:106C80003C0C02733C1C027549FFD5814400003363 +:106C90003C0BFF4544124A203C0C0277442000483C +:106CA00049FFFD7684013E07E94EFC8094D9886057 +:106CB0004C0180051A200001D5FCDD9E4403F04AFA +:106CC00044100055AE404413F403A608C8FFDD9EEF +:106CD000FC0084003C0FFAD73C0DFAA98421AE4099 +:106CE00049FFD9324403F04A44100055AE403C2DD0 +:106CF000FAA9A6505A1001FF44100055AE404413A3 +:106D0000F403A6089600C8FE3C1DFAA98441AE888B +:106D10003C0E0110FC80FC0080C049FFFFD13C0DFF +:106D2000FA983E67E96949FFF92BFC80FC402E1078 +:106D3000045E5A18011F2E1004155A1801232E1034 +:106D40000462C91F84223E10045E44528F702E7765 +:106D5000C6CC2E37E9692E40045E2E900431842083 +:106D600080C544A0005A4480007D45C00032D5242F +:106D70005A1802082E1004155A1001E98420D5E48F +:106D80002E10045D5A1801FCD5DFC31A988100F15A +:106D9000002098A910F10184CC199881C314002116 +:106DA000002840F304001027818C5A98010598B1FF +:106DB00011C1018C8C219688E247E9E8D50F38F0A3 +:106DC0000400D5E800210008D5ED5A4801051081DE +:106DD000018CD5EC10A1018CD5E9FCC04422D02057 +:106DE00044320000B482A09184A1041200129230B7 +:106DF0005410FFFF944A8823443201500410800845 +:106E0000944A9234964B121000813C1BF4ED04120C +:106E100000120421001392305410FFFF944A88237B +:106E200054217FFF4432000C949288430230801B2F +:106E3000103001040230801B9268103001050230CE +:106E4000801A103001060230801A92681030010753 +:106E5000A4D310300108A4D3926810300109A4D142 +:106E60001030010AA4D192681030010BA0D29278A0 +:106E70005441803F0430800F9261FEEE94DFFEE7C4 +:106E80001030010CA0920410800F9248FE6E96AF55 +:106E9000944FFE571010010DDD9EFC0080403C0C0D +:106EA000017B4432015083804402000CBC1200502C +:106EB0008104929054427FFF95228883BB1350F245 +:106EC000003C5431FFFF94DA8860000081054000E7 +:106ED0002008880596011202001B0000810700505F +:106EE000810640002008880596011202001A000061 +:106EF000810CB4CF92079541841DFE36FE2FB60F4C +:106F00000000810DB4CF40501C09841EFE36FE2FB8 +:106F1000B60F000081090040810840002008880465 +:106F20009601AC1B0000810B0040810A4000200844 +:106F300088049601AC190040810CA01A972F40528A +:106F40006008464C0FFF50420FFFFF06FF2FA91AA3 +:106F50000010810D440FC0FF966F4040A008A05A5A +:106F6000FE46FE67A85AC2038E41969084033C1DDC +:106F7000FA984432B39049FFF93CFC80FC418121EE +:106F8000F0818102814380E43C1DFAB4A60896009A +:106F90005A0801FE3C1DFAA9AE0849FFD7D53C0DA1 +:106FA000FAB4A640C9FFA78097B05A6801FE000353 +:106FB00080514003001B3E07E94FF00149FFD422F6 +:106FC0003C0DFAA9AF800004812EC80649FFD42EDB +:106FD0003E67E94FD512006380519786CE0649FF80 +:106FE000D4251064809ED50684003E07C66649FFFE +:106FF000D349840110040000840A10050000440FE6 +:10700000FFAA1003805184001003805210038053A4 +:10701000FCC13C1C017A54000FFF042080120410B4 +:1070200080124422005492305410FFFF944A882268 +:107030004020480804308008460C003F50000FFFF5 +:10704000FE1EFE1714008008DD9EFC4280E08121B8 +:1070500080C28420801FFA4049005DBA2E07FE8C52 +:10706000A6784432B4204442CEA03811800840149F +:1070700098009649C90284213812010984409D4133 +:1070800044912B8844A00BB8986A965738618400C5 +:107090005A60FF0F38148800388209014210A82472 +:1070A0004010A036388F9A028828381F9A0A8C41DF +:1070B0005A2808EC842080418061384F86029788E6 +:1070C000E2648C2140233C1B40323C1B5A1804F7DD +:1070D000E607E8043E57FE8CD50484003E07FE8C8C +:1070E000AEB8FCC2FC57B186B61FF181844884203B +:1070F0008006509F802049005D6B84208009844871 +:1071000049005D668400F1013C08021044000090D3 +:1071100040000416548000FF9401F08244A25F6096 +:1071200084E0F0014C70003FB00AB05C804849FF39 +:10713000F94850557CA08005B04AB09C8068848195 +:10714000F58349FFF94C920138131D019601E220A5 +:10715000F503E80338031D09505281204C557FED9B +:10716000B41F445DA0A088AA88A08005B04AB09C46 +:1071700080688481F58349FFF932920138131D013B +:107180009601E220F503E80338031D0980058028F5 +:1071900049FFFA6F920138049D09F0028CE18940A1 +:1071A000D5C1B41F49FFF89349FFD0483C1DFFA645 +:1071B0000220800F5A0002058403FE8496918062AB +:1071C0008026800949FFFCE78040100F80173814A3 +:1071D0008901500F80173823090149FFFF382E0716 +:1071E000E958003F801738248101381301013C28F9 +:1071F0000210882238448D0138230D018844E04173 +:10720000E8069A8A5CF100C8E805D5028440100FB0 +:1072100080179451443001F440108C37E623E8077E +:10722000C907441000C740108806D5028423002FE8 +:1072300080172E57FE94DA072E37FE8D88613E3771 +:10724000FE8DD5033E17FE8D2E37FE8DE663E803D7 +:107250005A18030684003E07FE8D80023E27FE94E6 +:10726000FCD74412C8C8380080005A0801052E0710 +:10727000C65DDD9E8401DD9E84004412B420845FDF +:10728000382080088C015A0808FD84003E07FE8CD7 +:10729000DD9E5A0801068401AE088400D50E3C0D1F +:1072A000FFA60200000FE20440403C1BE283E9F429 +:1072B000A410E61EE8048C01AC10DD9E8400AE082C +:1072C000DD9EFC40810184203C1802104462C8C845 +:1072D00010810000842480E2814349FFFF05812062 +:1072E000380320005A0801102E000424E602E804A6 +:1072F0008C013E00042484013E00044E84003C0BBB +:10730000F4C3D53084004412CE864422B3BE3C3050 +:1073100002103C43F4EE49FFFFBE2E000424C004DB +:107320008E013E0004245AA80112840080203823D4 +:107330000000CA038C2196498C015A0804FA5A1895 +:1073400004063C03FF448C01D50284003C0BFF443F +:107350003C03FF454410EA5FE220E9048C013C0B4A +:10736000FF4584003E0004222E000424C006840150 +:107370003E00042210938000FCC0FC4084814050F9 +:1073800010024062900C4470004888C1FF7C449019 +:107390000120441200004052900C421024738001DE +:1073A0009855989D806749FFF81AAC30FCC0FC40A6 +:1073B00051FFFDB0F081F182B67FB00444124A2043 +:1073C0004430009080E28440F48349FFFC71442003 +:1073D000FFFF44300090500F813044124A2049FF93 +:1073E000FC673C0DFAA9842184C0AE4084013C6F47 +:1073F000FAD84493F04A49000DD44480005549FF1F +:10740000F9DCF0014C600041840085403E07E96EE4 +:107410003CAFFADA49FFD598108480002E07E96E58 +:10742000F102E201E8262E17E96E3C0DFADAE220BD +:10743000E8F63CAFFAD82E07E96EB43F5A78020955 +:10744000F203B0C4504F813049FFF92FD50BB084FF +:10745000503F81305A78010549FFF86ED50349FF46 +:10746000FF8E2E07E96E8C0196003E07E96ED5D798 +:107470003C0DFAA984218CC1AE40440FFFAA3E07FF +:10748000E92E97B0D5BF51FF8250FCC0FC03842089 +:107490008448B00249005B9C84208448B0044900C1 +:1074A0005B97840249FFFC39B0C2B1048401842691 +:1074B000844249FFFF7EB04284448402490034B1D3 +:1074C00049FFCEBC3C1DFFA60220800F5A000205DA +:1074D0008403FE849691B0428062B00449FFFB5B56 +:1074E000F08149FFFECB840249FFFB1249FFFBE814 +:1074F000F001FC83FC0180C0840149FFFC0E840183 +:1075000084268040B0C1404F840049FFFF525A6832 +:107510000105800649FFFAFC49FFFBD2020F8002F9 +:1075200049FFF966FC81FC2149FFFA712E07E969E0 +:10753000C0135A080453440000323C0BF4EE4412CA +:10754000CE8684004422B3BE3C3002104440003258 +:1075500049FFFEA1D5073E00044E440000503C0BFD +:10756000F4EE3C0C0277842049FFF7F83C0C0277DC +:1075700044124A204420004849FFF90A2E07E957DF +:107580005A000104480000BA2E6004225A60010427 +:10759000480000B484003E0004504400004349FF0A +:1075A000CAAB49FFFF7580403C1DFA984432B39046 +:1075B000100F8007840349FFF61C84003C0BF4C3C2 +:1075C0003E07E94E3E60044E49FFFB8449FFF8F553 +:1075D0003E600450480000924400012C3C0BF4EE45 +:1075E0002E0004235A080107440000313C3C0110DE +:1075F000D5058460C8052E37E94340300C063C0CA5 +:1076000002772E17E958502F800749FFFE5C2E079E +:10761000E9575A0801732E0004225A0801242E67E4 +:10762000E9395A6801202E57E958000F8007D065C4 +:1076300084E0440000483E70045049FFCA5D49FFA1 +:10764000FB3F84033C1DFA98002F80074432B3901F +:1076500049FFF5CF3E77E94E3E60045049FFFB3AC3 +:10766000D54C3C03FF445CF000322E000464E90278 +:10767000C0085A0801433C0C01105CF00078E93D59 +:107680004400004284C049FFCA373C6BFF4449FFB5 +:10769000FB172E07E96949FFD0B5840149FFFF2C8C +:1076A000C8232E200423CA0E3C1DFA984432B390FE +:1076B00049FFF59F3E67E94E49FFFB0C49FFF87D06 +:1076C000D51C84033C1DFA982E27E9584432B39008 +:1076D00049FFF58F3C0C01105CF00033E90E84018A +:1076E0003E07E95CD50A84033C1DFA982E27E95829 +:1076F0004432B39049FFF57D2E07E9693E07E95111 +:107700003C0DFFA60000002EC00B3C1002104402EE +:107710002D54AC403C13F4E544022D56AC40FCA182 +:10772000FC002E000D123C1DFADA8C01E220E80468 +:1077300049FFF26CC00C84003C0BF4DE49FFF26C94 +:10774000C81749FFF5E149FFFEF0D5122E07E92CD5 +:107750005A0801064402B3F449FFCED284408401A2 +:10776000842A8062808080A249FFCDC8D5DBFC805E +:10777000FC402E37E9692E07E9482E17E9262E2707 +:10778000E9152E400D28CB0480A080C1D50580A22C +:1077900080C4804080813C7C0275FF74FEA48460BC +:1077A000449211703C03E2B6E260E81A941940106A +:1077B000240040A3800002808000A448020500004D +:1077C000FE649A08FE2C42841824400008164004E7 +:1077D000000196018C611205000096D9D5E43C0C9D +:1077E00002753C1C027349FFCFD2FCC044524A20B0 +:1077F000442003E844324AB05A080509A528021279 +:107800008048FE6440108837D5095A08010AA468E8 +:1078100002428048FE54401090379649AC688CA2D2 +:10782000DBECDD9EFC4180C0812181028143F4813B +:107830002E77E9695A080113C1049F49549280FFC9 +:107840002E57E9584C5480092E0004235A0801058C +:107850008009490013248403D5095A08020F5A7875 +:107860000405840149FFFFC484003C1DFA98804947 +:107870004432B39049FFF4BD3C1DFAB4A60896000B +:107880005A0801FE3C1DFAA9AE0849FFD35D3C0D24 +:10789000FAB4A640C9FFA6405A1801FF2E07E969AD +:1078A00049FFCFB02E07E969C8045A780408D50407 +:1078B0005A080405CF0349FFFF5D5A6801081064A8 +:1078C0000000840010650000D5095A68020A84008F +:1078D00010040000100500008401F101AE08FCC195 +:1078E000DD9EFC0080C0C82444020A2044125F6070 +:1078F0004420004849FFCF3044020A2044125FF080 +:107900004420004849FFCF2844020A2044126080E6 +:107910004420004849FFCF2044020A2044124A2054 +:107920004420004849FFCF183E600422D51049FF8B +:10793000F4EB44020A20842049FFF61044020A2096 +:1079400044124A204420004849FFF7222E07E957F5 +:10795000C8033E0004222E000422FC80FC40A748FD +:10796000CD07446000FF80E581258066D52984200D +:10797000446000FF80E1812180669708E285E8206D +:10798000A10138A2050197094CA2401904A00005E5 +:10799000950A888A00A20002E34340353C1B00A2FE +:1079A0000003E32A40953C1B00A20000A721E34608 +:1079B00040653C1BE2E440723C1B8C21D5DF840017 +:1079C00045C00012E323E92984804281F02480A687 +:1079D0008024E2E5E91740A4140040A50408894288 +:1079E00002F5000040F780115EF78033E908E6A950 +:1079F000E8048C219648D5038C8197208CA1976848 +:107A0000D5E9E28140123C1A9708E2804000BC1A96 +:107A10008C61960096D8D5D7E602E8028402FCC0B5 +:107A20003BFFFCBCEFFC49FFCC095A08021244039F +:107A3000F04A44100055AE403C2DFAD5CA098401E5 +:107A400080208062808080A249FFCC58D5F6EC046B +:107A50003BFFFC84DD9E3A6F9EBCEFF080C0A60128 +:107A6000F282F3835A080408A6305A0801058400FC +:107A700049000C3C2E07E9755A08010C4402B3ADCD +:107A8000F102F2033C3DFAA43C4DFAA2490050A396 +:107A9000440FFFAA3E07E9713C0DFAA23C1DFA987B +:107AA000B61F4422B364F302F4033C5DFAA444021B +:107AB000B4B0490051B996003E07E96149004D1242 +:107AC0002E07E9615A00010584013C0FFABDA63179 +:107AD0005A080816A6305A000204480000A83C0DB7 +:107AE000FAAC5A00067C5A0009044800009649FF87 +:107AF000CBA55A00020448000090D5705A08090E20 +:107B0000A6305A000204480000923C0DFAAC8E06E2 +:107B1000E6024EF20082D5625A080A08A6308E02AA +:107B2000E6024EF20084D55A5A08030DA7B05A68EF +:107B3000017E800649000A46800649000A32840810 +:107B4000D576540000FD5A080472A6305A08016F19 +:107B500049000A383C0DFAAC5A08060C4403F04AB6 +:107B600044100055AE4084003C0FFAD549FFFF5A3F +:107B7000840149000A1649000C4D3E07E94049FFBF +:107B8000CB312E57E95584203E07E90F3E17E91FF8 +:107B9000D00649FFCF3F84013E07E91F2E07E90FBA +:107BA000A7F13E07E9555A78061A2E07E9402E2715 +:107BB000E937E240E91584003E07E9373C0DFA98C1 +:107BC00049FFF1DE2E07E969802749FFF22D840184 +:107BD0003E07E97B84003C0BF4D78408D528CA0310 +:107BE0003E07E9378404AE312E000D1249000CBA6D +:107BF00080E0C8F4840149000B79800649000B8DB0 +:107C0000F082F102840280478461808780A749FF67 +:107C1000CB758408D50C844084618402FA25808366 +:107C200080A249FFCB6B8408D5028401EC103A6F27 +:107C30009E84DD9E3BFFFCBC8401EFFC49FFF0000D +:107C40004403F04A44100055AE404413F403A60820 +:107C50005A0001FFEC043BFFFC84DD9E3A6FA8BC98 +:107C6000C00349FFC707446000654473F04A44906D +:107C7000005549FFCAE3C0128EC1C610842180415D +:107C80008061848044004F004900351A440000643C +:107C900049FFC6C110938000D5ED84003A6FA884D7 +:107CA00048FFCA5C2E07E919C8072E07E9618E0450 +:107CB0005C000002DD9E8400DD9E0000A6C18E6394 +:107CC000E6694EF202D63A6FA4BCEFF480E280C0BF +:107CD00044F07BE038378D0140F1BC004A003C00A5 +:107CE00012004E0188056C0288054203AC036C0447 +:107CF00014053C0DFAAC5A08091E49FFCA9F5A08E0 +:107D0000021A4402B3414412B3E449FFCC7F440257 +:107D1000B3644412B36B49FFCC6A840CAE313C0DA2 +:107D2000FA98842049FFCF1C8403AE31FA003C0F3F +:107D3000FAAC2E07C5D2C00F5A0001092E07C5D2D2 +:107D40005A00010448000292D5363C03E4D2A07BDD +:107D5000E220E8F54403F04A44100055AE40449355 +:107D6000F04B3C0DFAB4A600C8EA3C0DFAA9A600F7 +:107D70005A0801E62E07E92C5A0801064402B3F41A +:107D800049FFCBBE3C1DFADA2E07C567E220E8EAC0 +:107D9000000480004413F04B5A00FF05841FAE0816 +:107DA000D5FF84408401842A8062808080A249FFBC +:107DB000CAA5D5D80493800349000AD7E320E80C6C +:107DC000A63A5A0001072E07E97F5A080111D50784 +:107DD0002E00040BC8F949FFDE28C8F64403F04A18 +:107DE00044100055AE403C1DFAB4D50F2E07E944AF +:107DF0005A0001F649FFFF58C8F22E07E95B5A0006 +:107E0000010448000233D5EBA608C0FF8406AE315A +:107E100084023E07E97B49FFC9E53E07E955490071 +:107E20000C323C0DFAA98420AE404800021F2E07F8 +:107E3000E979C8268006490009FD2E07E910C80720 +:107E40004402D40449FFCAE149000DEC2E07E97948 +:107E50005A00031C84213C0DFA9849FFCE8184010D +:107E600049000A44800649000A58F081844084028F +:107E7000F1018461808280A249FFCA40D5065A0878 +:107E8000030584013E07E97984003E07E97B2E174C +:107E9000E961800649000E912E07E97E5A08010427 +:107EA000480001E42E07E9355A080104480000B6ED +:107EB0002E07E9795A080304480000B0A6314900AA +:107EC0000A42490009D23C73F4D7A63149000A4559 +:107ED000E2E0E8052E07E95B5A0801232E77E92145 +:107EE000440FFFAA3E07E92E97F88406AE315A7870 +:107EF000011380273C0DFA9849FFCE3280064900D5 +:107F00000A0CF08184408402F1018067808280A2A3 +:107F100049FFC9F44403F06D8424AE40D5093C0DFB +:107F2000FA98842149FFCE1C8401490009DF8006AC +:107F3000490009F3F081F101EC0C84408402846172 +:107F4000808280A23A6FA48448FFC9D82E07E97BBB +:107F50005A08012F49000F062E0004325A08011555 +:107F600049FFC96C5A0802114900148280C03E07BB +:107F7000E9355A08010A840049001EFA84003E606F +:107F8000040B3E0004322E07E9355A08010B2E6718 +:107F9000E95BCE0749000A5C3E67E972480001666A +:107FA0003C0DFA98842149FFCDDB4800012F5A008F +:107FB00002044800015B2E77E95B5A78010B3C0D07 +:107FC000FA98842049FFCDCC3E77E97B4800014EEA +:107FD000A608C80B2E07E935C8088404AE313C0D4D +:107FE000FA9849FFEFCDD5A149FFFE5EC8F72E07ED +:107FF000E97F5A0001F42E07E9445A0001F02E00EF +:1080000004325A08010649FFC9195A0002E83C0D1A +:10801000FA98842049FFCDA4EC0C3A6FA484480060 +:108020000A173C0DFAAC5A08062084003E07E9798D +:108030003E07E97B3E07E9403E07E91E4402D404BF +:1080400049FFC9E349FFC8FAC00749FFCA4E3C03CC +:10805000E4E249FFFE05840349FFC54EEC0C3A6F8C +:10806000A48448000A3A5A000904480000FF49FF66 +:10807000C8E55A000204480000F93C0DFA98842033 +:1080800049FFCD6E8403AE31480000F02E97E979A8 +:108090004E93001B490008CE49000CC43C0DFAA9C0 +:1080A0008421AE402E07E9795A0003148006490066 +:1080B0000934F08184618402F1018049808380A9C0 +:1080C00049FFC91CD5065A98030584013E07E97982 +:1080D00080062E17E96149000D702E07E97E5A08C7 +:1080E0000104480000C32E07E9355A0001062E0797 +:1080F000E9795A080307EC0C3A6FA484480009EDAB +:10810000A63149000920490008B03C93F4D7A631B4 +:1081100049000923E320E91285203C0DFA981493C5 +:108120008003802949FFCD1C840BAE3184013E07BA +:10813000E97B3C9BF4D7480000998006490008ED94 +:10814000F081F1018402844048000088A6005A08AA +:108150000244A608C8042E07E935C0082E07E930F6 +:10816000C0052E07E97F5A08012EA1FB49001975A9 +:10817000E2E0E8082E07E930C0052E07E97F5A083B +:1081800001754403F04A44100055AE403C1DFAB45A +:10819000A608C0FFA631490008D6F081F1014402CB +:1081A000B3B14422B40649000A428400842B3C0B3C +:1081B000F4D7AE7184223E17E97B3C1DFAA9AE08C4 +:1081C000D5548400A83BEC0C84011003801C3A6F4A +:1081D000A484480019153C0DFAAC5A080709840913 +:1081E000AE314900097AFA003C0FFAAC8400100362 +:1081F000801CD53B2E07E97B5A0801103C0DFA98EC +:1082000049FFEEBE49FFFD1884023E07E97B3C0DA5 +:10821000FAA98420AE40D5295A08022884003E07D6 +:10822000E97BA608C8042E07E935C00A2E07E93005 +:10823000C0072E07E97F5A00010448FFFF5E84094A +:10824000AE313C0DFA9849FFEE9B84008440100348 +:10825000801CA8BB8402FA26EC0C8461808380A277 +:108260003A6FA48448FFC84AEC0C3A6FA484DD9EA0 +:108270004403F04A44100055AE404413F403A608EA +:108280005A0001FFDD9E00003A6FA8BC812080E209 +:1082900049FFC86580C049FFFFED5004FFFFE60CB1 +:1082A0004EF2018644F081B43807810140F03C0071 +:1082B0004A003C0018007A0050016202BA00F8023D +:1082C000F802F802F802F8028C02DE0244000030E4 +:1082D00049FFC412840EAE398405AE383C1DFA9BAA +:1082E000840010030050B441440FBFFFFE16B601D6 +:1082F0004463F04A4490005549FFC7A05A0802055C +:1083000010930000D5FA4403F0108420AE4049FFDA +:10831000C795C020842180418061808144005AF04B +:10832000490031CE4400006449FFFC9AD513840E05 +:10833000AE398406AE3884001003005080A6500386 +:108340000041843F18128001D8FE4403F0108420BD +:10835000AE408007842149FFCC0384208402804101 +:108360008461808180A13A6FA88448FFC7C7440018 +:10837000003149FFC3C14403F42985201090000057 +:1083800049FFEF4684013E97E90BAE381093005049 +:108390002E07E90BA6792E27E92184812E37E93EA5 +:1083A0004452B4E449FFEBED2E07E969C8084402E2 +:1083B000B4E44412D71849FFED96D5095A080308CA +:1083C0004402B4E44412D52049FFED8D84003E0000 +:1083D000044C2E10045084003C0E010F84013E0713 +:1083E000E9225A1001043E07E92F8400490005D90B +:1083F000A6398E08E6044EF200DE80073A6FA884A4 +:1084000048FFC83C4400003249FFC3763C1DFAA92E +:108410008402AE08AE38A6399E43E624E9075A0026 +:108420000D065A080E0749FFC9048408AE39D50362 +:108430008409AE398520109300503E97E93A3E9763 +:10844000E91F49FFEEE53C0DFA9849FFED994463B9 +:10845000F04A3E97E8FD4490005549FFC6EF5A08A0 +:10846000020510930000D5FA4403F0108420AE40BA +:108470004403F429441FFFC3AE4049FFC6DFC009CF +:10848000842144005AF08041806180814900311884 +:1084900084003C1DFA9B3E00044C84003C0E010FFE +:1084A000B441440FBFFFFE16B60184013E07E92226 +:1084B0002E07E96D5A080306840949FFC802D5044E +:1084C000840549FFC7FE2E0004505A0001058401AF +:1084D0003E07E92F8400490005648007842049FF96 +:1084E000CB3F3C0DFAAC5A0004045A08070C842117 +:1084F000844084028062848F80A13A6FA88448FF00 +:10850000C6FD84408402FA258062848F84A13A6F7C +:10851000A88448FFC6F33C0DFA98842049FFCB207D +:10852000840AAE398403AE388400100300503C0D39 +:10853000FA9849FFED2584013A6FA88448FFDA7E56 +:1085400049FFC67C3C1DFA985A08020CA6095A003D +:1085500003128001842049FFCB0349000779D50A23 +:10856000A6095A000A088001842049FFCAF9490077 +:1085700007B400030051001300524422B37F443279 +:10858000B3514442B38F49FFF94F840010030050A8 +:10859000D511000300515A0001055A080205840054 +:1085A0003E07E95B840010030050D504841B1003D0 +:1085B00000503A6FA884DD9EE606E87544F084CC4E +:1085C0003807800040F03C004A003C00062644D8B2 +:1085D000669E4413F24884014423F249AE08842283 +:1085E000AE504423F24A8464AE104423F24BAE50A2 +:1085F000D5304413F248841FAE084413F24984482E +:10860000AE084413F24AAE084413F24BAE08D53C10 +:108610004413F2488401AE084413F249AE084413EF +:10862000F24AAE084413F24BAE084413F24CAE08C3 +:10863000D52E4413F24884014423F249AE08842421 +:10864000AE504423F24A846CAE104423F24BAE5039 +:108650004423F24CAED04423F24DAE504423F24EAC +:10866000AE104423F24FAE50D51B4413F2488400A1 +:10867000AE084413F2498441AE084413F24AAE08EE +:108680004413F24BAE084413F24CAE884413F24D3F +:10869000AE084413F24EAE084413F24FAE08441332 +:1086A000F250AE08DD9E9200C10358000010441342 +:1086B000F2519600AE08DD9E40003C084423F2448F +:1086C0009210AC104010BC084403F2469230AC400B +:1086D000DD9E4403F2408421AE404413F04A44201E +:1086E0000055AE88A6405A1001FFDD9E4413F25893 +:1086F000A448AC404413F25AA448AC414413F25C81 +:10870000A448AC424413F25EA448AC434413F26064 +:10871000A64810100008DD9EFC02F0818002F38361 +:10872000F18249FFFF4BF001F10249FFFFC749FF0A +:10873000FFD2F00349FFFFDCFC82FC02F08144031E +:10874000F242F182F283AF40001F80204403F243E3 +:10875000AE404403F2528421ACC04403F254AD0055 +:108760004403F256AC40001F80244403F241AE4063 +:10877000000F8028001F802C49FFFF98F001F102B4 +:10878000F203F30C49FFFFCAFC824403F140842149 +:10879000AE40DD9E84203C0FFAA6AC43DD9E3C3DFE +:1087A000FAA6920192219241AC18AC59AC9ADD9E86 +:1087B0003C1DFAA6A6821020800CA6831020800DF6 +:1087C000A680A6011020800E1000800FDD9E3C1DAB +:1087D000FAA6A68210208010A68310208011A68001 +:1087E000A6011020801210008013DD9E3C1DFAA609 +:1087F000A68210208014A68310208015A680A601D2 +:108800001020801610008017DD9EFC01B63FF2811B +:1088100049FFFFD0B41F49FFFFDCF00149FFFFE82B +:10882000FC81FC24F081F182F283001F803C002F48 +:108830008038000F8040007F8060006F804C105FA8 +:108840008016103F8014102F8017104F8015101FB6 +:10885000801A103F8018100F801B104F8019CF080E +:10886000105F801E103F801C102F801FD507101F27 +:10887000801E103F801C100F801F3C0DFA7D104F92 +:10888000801D49FFFF89B005B046B08749FFFFBF93 +:10889000F001F102F20349FFFF843C0DFAA6021F2A +:1088A0008028002F8044AC44001F8054FE77526320 +:1088B000001095B1FF8F001F80481060000A58100B +:1088C0008040FE571010000B221F802C1210000C4D +:1088D000221F802E1210000D4403F04A4410005550 +:1088E000AE404403F1408421AE40A6405A1001FF3F +:1088F000FCA4FC24F08194199600100F8017100F2F +:10890000801B840184E2100F801E3C0DFA7D80C51F +:10891000103F8014104F8015103F8018104F8019A1 +:10892000103F801C103F801F104F801DF182F2838A +:10893000107F8016107F801A49FFFF2EB005B046C9 +:10894000B08749FFFF64F001F102F20349FFFF29FC +:108950003C0DFAA62E27E94F8420AC445A28010882 +:1089600095B31070000A1060000BD50684491020E2 +:10897000000A1010000B4403F04A44100055AE40AA +:108980004403F1408421AE40A6405A1001FFFCA4EC +:108990003C1DFAA61000800BDD9E4403F04A4410F3 +:1089A0000055AE404413F403A6085A0001FF4403E7 +:1089B000F3808421AE404413F04A44200055AE8831 +:1089C000A6405A1001FFDD9E4453F381944AA72824 +:1089D0009407544200F0FEA7FE579648FE0F9600FB +:1089E000AE284403F38496D8AEC0DD9E4413F386CC +:1089F0008400AE084413F387AE08DD9EFC004403F8 +:108A0000F38496D8AEC049FFFFCA4403F04A44102D +:108A10000055AE404413F380A6085A0001FF44639A +:108A2000F3804403F386A6005A08010F49FFFFE0D4 +:108A300049FFFFB54403F04A44100055AE40A6304C +:108A40005A0001FFD5EF4403F387A6005A0001F056 +:108A5000FC804413F280A60858000001AE08DD9E99 +:108A60004423F2809405A650FE479648AE50DD9E02 +:108A7000441E000088014413F2869681AC8892104F +:108A80004413F2889606AE08DD9EFC40810080C14A +:108A9000A4404403F28445C3F280AC4004040001C6 +:108AA00049FFFFE8001400084403F2834473F04ACE +:108AB000AE4044900055001400090024000A964678 +:108AC0009409001E00003DCFFA7F541080FDFE4740 +:108AD000101E0000968694D2002E0000440000551F +:108AE000542100FBFE9F102E000044A3F418AE3862 +:108AF00002050000C011020500005CF00781E80CCF +:108B00004403F2918421AE400004000B49FFFFAA08 +:108B100049FFFFA1D50649FFC3915A0002EBD5F1E9 +:108B2000000E00009606C00410938000D5FA44138E +:108B3000F291AE084403F2813C0FFA7E5A680307B3 +:108B4000A64092229646C1B8D5085A680105A600EB +:108B50009202D5055A680206A60092039606C0AC9A +:108B6000FCC09404FE4796084413F481AE08DD9ED1 +:108B70004413F48396019680A6C89208AE88A6890D +:108B8000AE09DD9E4413F48596019680A6C892082E +:108B9000AE88A689AE09DD9E4413F4879680AE8820 +:108BA00092084413F4889600AE08DD9E4413F489BD +:108BB0009600AE08DD9E4403F48244200055A64092 +:108BC000541080FE58108001AE404413F04AAE8825 +:108BD000A6409646C9FEDD9E3A6F98BC4463F00EEF +:108BE000A43054000100C00944122CF4A6088C01E2 +:108BF0009600AE088408D575A430960EC85FA430E0 +:108C0000961EC00944122CF3A6088C019600AE08EB +:108C10008403D567A4309616C00944122CF2A60826 +:108C20008C019600AE088402D55CA4309626C0095B +:108C300044122CF1A6088C019600AE088404D5518C +:108C4000A4309606C803FA00D54C49FFBC8BA4306B +:108C50009636C836A430962EC835A430963EC83411 +:108C6000A43054000200C00C4403F064A6409646B1 +:108C7000C12DA640541080FEAE408409D532440375 +:108C8000F00EA44054108400C923A440541088005E +:108C9000C921A44054109000C91FA4405410A00042 +:108CA000C91DA4405410C000C91BA400920FC0CC21 +:108CB00084013E000414840FD5148401D512840667 +:108CC000D5108405D50E8407D50C8409D50A840AED +:108CD000D508840BD506840CD504840DD502840EEA +:108CE0004413F00E8440AC883A6F9884DD9E4403B0 +:108CF000F3228421AE40DD9E4413F323AE08DD9EB3 +:108D00004403F323A600DD9E3A6F9C3C4463F54088 +:108D1000B6064403F544B6204403F548B640440380 +:108D2000F54CB6604403F550B6804403F554B6A044 +:108D3000F1024403F558B620F1034403F55C3A6FA1 +:108D40009C04B620DD9E3A6F98BC44212B90EFF82E +:108D50003A210C003A2F8C204423F5044443F502B9 +:108D60004433F5033C2FFA814423F505803F3C4F03 +:108D7000FA843C3FFA833C2FFA805A0002044800F0 +:108D800000904453F500443C0B004403F50898ABB5 +:108D90003820880018228001D8FB4403F5074410CE +:108DA0000045AE404403F50084C1AF8084008020BC +:108DB0008040806049FFFE244403F5018423AE40D7 +:108DC000840080208040806049FFFE1A3C1DFA84A8 +:108DD000A60858000002AE08840080208040806011 +:108DE00049FFFE0E440007D049FFBE153C1DFA8323 +:108DF000A60858000002AE088400802080408060F1 +:108E000049FFFDFE440003E849FFBE0584008020C1 +:108E10008040806049FFFDF43C3DFA843C2DFA839C +:108E2000A658A6105810801D5800001DAE58AE1050 +:108E3000840080208040806049FFFDE22E07E953D6 +:108E4000C81B3C0DFA983E67E953A78149FFC1F65C +:108E50003C1DFA985A0802058404AE09D50384091A +:108E6000AE093C0DFA9849FFE88B840149FFE6E81A +:108E70003C0DFA98AF81440005AA49FFBDCC49FFDB +:108E8000E6C5C0FE3C2DFA84440FFFEFA650FE4617 +:108E9000AE503C1DFA83A688FE16AE08D562C833D4 +:108EA0004403F5008421AE404403F5018423AE4021 +:108EB0002E200D103C1DFA843C0DFA83CA09A688A9 +:108EC00058210001AE88A68058210001AE80A688F6 +:108ED00058210002AE88A64058108002AE4084009F +:108EE00080208040806049FFFD8B3C3DFA843C2D12 +:108EF000FA83A658A6105810800C5800000CAE58E3 +:108F0000AE10D52F5A080137A620A758845BFE164D +:108F10008437FE0EFEAEAE20FE568400AE58804072 +:108F20008020806049FFFD6C4413F5008400AE088A +:108F30004413F501AE082E100D103C2DFA843C0DA3 +:108F4000FA83C908A6D0843EFECEAED0A6C0FE5E8F +:108F5000AE40A6D0843DFECEAED0A680FE56AE403A +:108F6000EC0884008020804080603A6F988448FF3D +:108F7000FD47EC083A6F9884DD9EDD9E4610800028 +:108F80006413240364230402461F7FFF50108FFFE5 +:108F9000FE5640006C08FE0F64030403DD9E46107D +:108FA00008006413240364230402461FF7FF5010D3 +:108FB0008FFFFE5640005C08FE0F64030403DD9E35 +:108FC000441080006413240364230402441F7FFFC1 +:108FD000FE5640003C08FE0F64030403DD9E400083 +:108FE0003C084433F2009210AC184010BC08440313 +:108FF000F2029230AC4040213C084403F20492500B +:10900000AC80DD9E4403F20A44200055A640541073 +:1090100080FE58108001AE404413F04AAE88A6404E +:109020009646C9FEDD9E4423F2069600AE10440328 +:10903000F2079648AE40DD9E440232E8DD9E4402CF +:109040002F00DD9E4403F20BA600DD9E4413F208C0 +:10905000AC08DD9E4423F20A9401A6509646FE47D2 +:109060009648AE50DD9E0000E608E82544F08F7C6F +:109070003807800040F03C004A003C00080E141AFB +:1090800020262C324403F20CD5154403F20ED512DF +:109090004403F210D50F4403F212D50C4403F2142A +:1090A000D5094403F216D5064403F218D503440348 +:1090B000F21AAE40DD9E9200E608E82544F08FCC1F +:1090C0003807800040F03C004A003C00080E141AAB +:1090D00020262C324403F20DD5154403F20FD5128D +:1090E0004403F211D50F4403F213D50C4403F215D7 +:1090F000D5094403F217D5064403F219D5034403F6 +:10910000F21BAE40DD9E92004413F050A6085800BA +:109110000080AE08DD9E4413F050A6089637AE08D6 +:10912000DD9E4413F051A60858000001AE08DD9EF4 +:109130003C0DFFA7A600DD9E4402400044124510EE +:109140003C0FFAB33C1FFA943C0FFA99DD9EC00421 +:109150005A000209DD9E3C0DFFA7A6003C0FFA1F36 +:10916000DD9E3C1FFA1FDD9E40003C084433F1C4E5 +:109170009210AC184010BC084403F1C69230AC40C9 +:1091800040213C084403F1C89250AC80DD9EFC00B5 +:1091900044028F700020000F001000104403F1C241 +:1091A000AE804403F1C3AE403C0DFAB33C1DFA94CB +:1091B0003C2DFA9949FFFFDAFC8084003C0FFAD479 +:1091C0004403F1C08421AE40DD9EFC0649FFFFE16F +:1091D0003C0DFA1F5A000F134413F1C19600AE085C +:1091E00049FFFFED4403F04A44100055AE404413DC +:1091F000F1C0A6085A0001FFD51BFA202E37C5473B +:10920000F1858422840084A1F18744124000F08318 +:10921000F084F086F088F0892E47C548B67FF58146 +:10922000F382F58A44024510804149FFFAFCFC862E +:10923000FC00842049FFC494840149FFE5018401B6 +:109240008440842A8080806280A249FFC057440302 +:10925000F04A44100055AE4049FFE4D8C8043C0D24 +:10926000FAD7C0FBFC802E17E91E5A10FF3E2E27AE +:10927000C9C3E022E9039E5196484422E1BC38313B +:109280000501E260E931FC208400380105093C0B4E +:10929000F4E7842084832E07C53B9401E020E82373 +:1092A0003C3C027D3C0C027E3C5C028694898862D8 +:1092B000880288A1A598A5C0A62888074203107334 +:1092C000405008099769AD583C5C027D3C3C0286E1 +:1092D00088458861A4908C2194928A029600AE18E9 +:1092E0009648D5DAFCA0DD9EFC005A0801132E102A +:1092F0000D012E000D005A1801048E03D5028E02B6 +:109300002E100D1296005C10800349FFBF70D5032C +:1093100049FFBF7EFC80FC0049FFBF905A08021045 +:109320002E07E921C8092E07E91EE6038405E8098E +:109330002E07C9A6D5062E07C9A7D5032E07C9A88B +:10934000FC80540000FD5A0804053C03FF52DD9EDA +:109350003C03E4DBDD9E5A0804053C03FF51DD9E1F +:109360003C03E4DCDD9E3C0DFA7CA400DD9EFC00A9 +:10937000B400920196065A080109440000643C0BAF +:10938000FF5244000168D5073C03E4D93C0BFF526F +:109390003C03E4DA3C0BFF513C13F4793C03FF52ED +:1093A00049FFC32C3C0BFF523C13F4793C03FF51A3 +:1093B00049FFC3243C0BFF51FC802E17E919C90A51 +:1093C00084423E17E9303E27E9503E17E935101038 +:1093D000001CDD9EFC004403F04A44100055AE40E2 +:1093E0003C0DFAD7C8122E07E92C5A080106440290 +:1093F000B3F449FFC085840184408020806280806E +:1094000080A249FFBF7BD5ED840E49FFBF94FC804D +:10941000FC0049FFBF135A08020E4403F4222E1722 +:10942000C9C2A600961FE220E907C0068E01960079 +:10943000D5058400D503440000FFFC802E07E91EFB +:10944000842050007F0140008006DD9EFC003C0D22 +:10945000FA98842384C1AE4184253E17E93F3E67D4 +:10946000E93C49FFE58D2E07E969842349FFE5DCE6 +:109470003C0DFAB4AF803C0DFAA9AF802E00040B6E +:109480005A08010B84003E07E97984003C0E010F65 +:109490003E00040BD51A2E07E9795A0003082E075F +:1094A000E91FC80484043E07E9792E07E970C80A59 +:1094B0003C1DFA7CA4485CF0803CE9055000FFC4E8 +:1094C000D50284003C0E010F84013E07E97284003E +:1094D0003E07E97BFC80FC003C0DFA98A601540095 +:1094E00000FD5A0809162E07E9795A00030584047D +:1094F0003E07E9792E07E970C80B49000FAE5CF012 +:10950000003CE90649000FA950007FC4D502840041 +:109510003C0E010F84013E00044C3E07E930490037 +:109520000F6F49FFC92A3C0DFA98A6415A1808073F +:10953000842AAE4149FFE524D50F842049FFC3109A +:109540003C0DFA98842AAE4149FFE51A49FFF374AD +:10955000840E49FFBEF03C0DFAA98421AE40FC8088 +:109560005C000003DD9EFC402E17E9505A18020BE8 +:109570002E17E930C9072E17E9798E225C10800179 +:10958000D50284202E47C53B3C9C027E95A18EC10E +:109590009FE184A0846144A2CEB052800000E0A686 +:1095A000E81BD71740F284084024BC0050F7800223 +:1095B00040F4BC00A49002F780008A4F9693E0022A +:1095C00038251509E903E048E8045A1801038462C4 +:1095D0008CA19768D5E55A18011F92014422CEB09C +:1095E00084208122FF42E027E81638610511E00659 +:1095F000E80740A0900038F12911E00FE908E0C524 +:10960000E807998C38649911E0C5E80284628C21DE +:109610009648D5EA8003FCC084204422E1BC38018E +:1096200005098C215A1808FDDD9EFC2080E0A6006B +:1096300080C25A0804208401AE383C0DFA98A60175 +:1096400049FFFE8149FFFFEA3C13F4C6E62AE8051C +:109650008C213C1BF4C6D51584003C0BF4C6A470C9 +:10966000E639E805AE38840049FFFFD88400AC3005 +:10967000D508840049FFFFD28400AC303C0BF4C60F +:10968000FCA0FC013C0DFA98A60149FFFE5CF081AC +:10969000F1014402B3B14422B40649FFFFC82E17BA +:1096A000E97984003C0BF4D73E07E93AC9033E0749 +:1096B000E8F984003E07E9403E07E91E3E07E93726 +:1096C000440FFFAA3E07E92E3C0DFAA98421AE40C3 +:1096D000FC81FC202E67E91E2E07C9C380E1E0C093 +:1096E0002E17E910E9038E0197805A18011849FFD7 +:1096F000BDA55A08021484002E17C53B9449E00109 +:10970000E81783879441BA09BB0B884188238C01F1 +:10971000A44896009649AC50D5F04402E1BC4410F0 +:10972000FFFF38501901D1048CA1385019092E17A8 +:10973000E8F94000980E9606C81D2E27C53B949167 +:10974000E002E81283879481BB0A8C01991ABB0955 +:1097500096008862A5589769AD60BC0BA4D8884470 +:1097600096D9ACD0D5EB84014000180CFE0F3E0713 +:10977000E8F9FCA0FC422E27E91E5A28FF04480005 +:10978000011F8101F0814412D4044402B37849FFDF +:10979000FFA280484400FFFF8420A852A8132E0790 +:1097A000C9BAE610E804521000109648E61180A0ED +:1097B000E902FAA085409628B61F80EA800A80CA8E +:1097C0004492D6042E27C53B3C3C027F41E104086D +:1097D000E0DE4EF2008B3C0C027E94B199023C0C10 +:1097E000027CA560880204FF8000A400FF4C425068 +:1097F0003C73800592049601AC203C0C027E88628A +:109800008802A5003C0C027D8802A4009A209603E1 +:10981000AC18A4189603E140E805A41880E640A01F +:1098200000113C0DFA7CA4D8A40596DBFE02E06092 +:10983000E82C2E07E9305A0801292E000432C81DF1 +:10984000380498003C33E4D88C019600E260380478 +:109850009808E8213C0C027E3C3C027D880288622C +:10986000A4009601AC1884003804980884013E07CF +:10987000E8F83E07E980D50FF183F28249FFBCDEAC +:10988000F202F1035A0802DE38049800C0048E0187 +:10989000380498083C3C027E040400028862A51843 +:1098A000E204E804A41814040002A5180404000348 +:1098B000E280E804A41814040003F001A6C13C0DE2 +:1098C000FA7C5A380904A403D502A4043C3C027F64 +:1098D0008843A4909693E002E80484413E27E9354A +:1098E0008CC197B048FFFF7094799919E2E2A560A6 +:1098F000976BE826CF078C228823887EA448970B95 +:10990000D50B9F919F0A884788834C73400EA460B3 +:109910009491970B8862A458964B88248825964B7F +:1099200044200050D52E8C22882394918862A52053 +:10993000A448A4989723964B96938824D51D4C71E0 +:10994000400A8C228823A448968BA458964B8822E0 +:10995000D5E69F0A506F7FFF9ABA88834C733FD930 +:10996000A5A09D0A888394918862A460A49897B367 +:10997000964B9693882688228825964B442000781B +:109980004E170007E041E80484213E17E9352E1701 +:10999000E91F5A1001062E17E9805A180108842180 +:1099A0003E17E93584203E17E9793C1DFA98A6490F +:1099B0005A18090649FFFDD93E07E950FCC2FC20B0 +:1099C0002E27C9C2441000FF4020880C4413F42203 +:1099D000FE93A6489690965FC1038E2196482E3737 +:1099E000C9C384C0E223E9049E59964884C1A7C034 +:1099F00084A14042840CFF3F972296E0AEC04C7198 +:109A0000C003C60D84014C31000C88204000040CBA +:109A1000FE279600FE1D5C000001D5028005FCA01B +:109A2000FC2184003C0BF4D73C0BF4E7120F8003BD +:109A30003E07E9353C0DFA98A6015A0804222E0784 +:109A4000E979C8284402B33149FFFFBB80605A0856 +:109A500001222E17C9C32E27C548500F8006FE8C41 +:109A600096904412D24849FFBF192E07E97FC804D7 +:109A70002E000432C0038401D5078403D5052E07C8 +:109A8000E930C80584023E07E979D5042E07E97F4D +:109A9000D5F22E07E9795A08020584003E07E8F856 +:109AA0008400444000C880604452D6042E17C53B51 +:109AB0009449E001E8233C6C027C944188C13C2C31 +:109AC000027EA5B0884197B1AD902E7004323C6CF7 +:109AD000027E3C2C027DCF0788418826A448964907 +:109AE000AC50D5038822AD083C1C02868820AEC845 +:109AF000383280088C019600D5DAFCA1FC202E3784 +:109B0000E930CB59A6005A0802572E17E9505A18C7 +:109B1000024E2E57C53B3C7C027F95694420753030 +:109B200084818003E065E81994598827A58897B354 +:109B3000E0C2E803A4889693A58897B3E086E8037B +:109B4000A5089723A448964B5EF0FF9CE8038C0180 +:109B500096008C6196D8D5E75EF17F9CE81E84362E +:109B6000FE8C40211056E455E918C0172E07FEA0C0 +:109B70008C019600E60B3E07FEA08400E9113E072B +:109B8000FEA084013E07E9302E07E9795A08021445 +:109B900084003E07E979D50F84003E07FEA03E070A +:109BA000E93584003C0BF4E7D5065A1801053E1749 +:109BB000E930D5EBFCA0FC4080C1A64180E05A18FA +:109BC00004249E34E604E9265A600C252E07E97920 +:109BD0005A0003212E07E97F5A0001122E07E9449B +:109BE0005A00010E2E07E9215A08010784003C0F94 +:109BF000FAD549FFEF17800749FFFB1C4402D40444 +:109C000049FFBC03D5072E17E9795A10030449FF11 +:109C1000FB113C03F4E74412D50C8C013C0BF4E738 +:109C20003C03F4D78C013C0BF4D7800749FFFDA41B +:109C300049FFBB045A08021549FFFBECC8112E1757 +:109C4000E976C10E3E07E92549000F3A2E07E93BA8 +:109C50005A0801043E07E91284003E07E9762E0007 +:109C600004325A08012049FFBAE95A08021C490087 +:109C700005FF852080E03E07E9353C9BF4E75A0864 +:109C800001098400490010743E70040B3E900432B8 +:109C90002E07E94C5A0801073C03F4D78C143C0BFF +:109CA000F4D72E07E9355A08011784003E07E93A30 +:109CB00084002E17C9C34432E1BC80809680E24103 +:109CC000E805384181098C01D5FA4400005049FF6C +:109CD000B713D5192E77E9305A7801169E34E6026B +:109CE000E9124402D50C3C13E3134422B372490039 +:109CF00004A95A080209FA0149FFB6FE3E77E93580 +:109D00003E77E9803C0DFA9849FFFEFA440FFFAA1E +:109D10003E07E92E9E34E602E810440000FF2E10B4 +:109D2000045C49003C0684003E07E93584003C0B96 +:109D3000F4D73C0BF4E7D5065A68020584013E07C8 +:109D4000E9352E07E97F5A0801043E07E97E2E0710 +:109D5000E9195A0801063E07E9353E07E930FCC01B +:109D6000FC0084003C0FFADA3C0FFAD5840149FF6D +:109D7000DF674403F04A44100055AE402E000D1238 +:109D80003C1DFADA8C01E220E80A8401844080203C +:109D90008062808080A249FFBAB1D5F12E07E91018 +:109DA000C8154402D40449FFBB303C0DFA98441254 +:109DB000D50C49FFFCE12E07E935C8083C0DFA989F +:109DC000A60149FFFAC049FFFA504403F04A441083 +:109DD0000055AE4049FFDF1A8040C8098401802049 +:109DE0008062808080A249FFBA89D5F52E07E935C7 +:109DF000C81C2E000D12E603E8183C0DFA988424C6 +:109E0000AE4149FFE0BD3C0DFA982E17E96149FFCC +:109E1000FED43C0DFA988426AE412E07E935C805DC +:109E20003C03FF5249FFFA21FC80FC4444212B985B +:109E3000B1843A2114003A2F942044212BA8387F72 +:109E400082023A2114003A23142094C24422714021 +:109E50003843020238510C002E37E926442FFF38D0 +:109E6000FED4976896D9844044612288981694015C +:109E70000290000038011C008C4142048024400004 +:109E8000140E88030292000096034000041688090D +:109E90001A0200015A2A88ECFCC4FC4544212B9884 +:109EA000B0423A2114003A20942044212BB8447245 +:109EB0008F70B1863A2114003A23142081200023A8 +:109EC000800F8400120F80033810A602500F800606 +:109ED00000338010924149FFBCE1500F80063813D7 +:109EE00026020023800F0033801049FFBCD7FCC539 +:109EF000FC072E17E926440000C8FE0C120F801B39 +:109F000044028F7084A1A6C2A7038400F081F0826E +:109F1000F083F084F085F086F088F089F08AB67FCF +:109F2000F58744021B90501F80364422AD7049FFD4 +:109F3000F47AFC87FC42FD30F281F38349FFB97E5D +:109F40005A00020545E000A0D50345E000782E0741 +:109F5000C5482E57C5478E0150A2FFFFF0828027CB +:109F6000049F8001F001F203400480019600E202A8 +:109F7000E85D09C48001424E14240800800198A0C5 +:109F800095D13883091184418068C00698B7223181 +:109F90007FFF84428868E00AE80788E68C412273E4 +:109FA0008001969088675CFE0002E91B9BE540F308 +:109FB00080004077840838F33D11886FC8038C41D6 +:109FC000D50740F31C008C4222F7FFFF886FE00AA0 +:109FD0009690E80788E68C41227380019690886706 +:109FE000F70240FE1C07E8188885888095E1384311 +:109FF00011118864C8038C41D50699378C422242DE +:10A000007FFF8864E00A9690E80788E68C41220387 +:10A0100080019690886040218856E450E903E51A53 +:10A02000E80740FF0C07E89FD5038400D5028401B0 +:10A03000FCC2FC40846044407D0084C22E17C548A9 +:10A04000E261E86D2E17C54744507D0042718424BB +:10A0500095F940A0840988E085008045541400FFEC +:10A06000E22AE8113893A1114E92000CE122E9078F +:10A07000E0A980294012BC1B8122968B80A28049D6 +:10A080008D01D5EDD40588A2405298B696AB8420B8 +:10A090002E87C54740940409E2294271A024E80CA8 +:10A0A00088E195F988E022538000C5038AA2AD7843 +:10A0B0008C219648D5EE44507D0080498025E248A9 +:10A0C000E81340A3880038A029114EA2000BE141FB +:10A0D000E906E0AA40553C1A8141966B80A1802A8E +:10A0E0008C419690D5EDD41488A1405298B6966BC9 +:10A0F000D50F80A94251887394A98840225100004D +:10A10000C5038AA1AD5050248001549100FF2E2731 +:10A11000C547E322E9EF8C6196D8D591FCC0FC4697 +:10A12000B18881018142838084208006FA40490001 +:10A13000454F50040006F08550040007F086500596 +:10A14000000684A08481F0872E07C548E080E8548B +:10A15000500500078460F0842E07C547E060E84999 +:10A16000802342120073380E0511E40DE93F84E0AC +:10A1700038231D119678E040E836F2058006F28318 +:10A18000F20605EF8004F282F2078527F281E229C8 +:10A190008E02E817F20302F000078F2112F0000888 +:10A1A00008F17FFFF283F202549480FF18F17FFFE1 +:10A1B000F282F20108F17FFFF28118FF7FFFD5E8FC +:10A1C0002E07C547804342220073380E0901E6A8D6 +:10A1D0003834040838031D0938450408E8078CA101 +:10A1E0009768D5048CE15A7808C58C6196D8D5B5A6 +:10A1F0008C819720D5AA8005FCC6FC0244212B98AF +:10A2000080C33A2114003A2F9420383F9A02441216 +:10A21000714095B288C1843EA7303C53E2B6972086 +:10A220004201847380439A539649E225E8103860CE +:10A23000091108110001FE744010900E4E14000325 +:10A24000FE4A5EF08051E9F08401D5028400FC8270 +:10A25000FC424647FFFFF28350220FFF814084619A +:10A260008001448200003C1C017BF2822E47C565C0 +:10A27000E2834EF3009B8381FAA8BC104460003057 +:10A2800054427FFF9522424194738888F203025220 +:10A2900000099769F5810252000840F28013A76710 +:10A2A000A7E6BC1254427FFF952242429873BD122A +:10A2B00088885452FFFF956A4253987388A884C0D7 +:10A2C0005A28014E844397F04073893797F8549485 +:10A2D00080FF844A39C21E024294882441CE240D54 +:10A2E00055CE03FF5BC3FF12F20141C170008043F2 +:10A2F00039E571012FC7C547422370738382F2028B +:10A3000041CE080039E0710938729E028CC1409339 +:10A31000A40D549483FF5A93FF0B2E77C547892FC2 +:10A32000FFF4389525018AE338901D095A6824CC3A +:10A33000D5383872A6028CC14073F00D547383FF78 +:10A340005A73FF0C2E97C54788EF429324248B2322 +:10A350003895250138901D095A602424844397F0CC +:10A36000409388F7549480FF97F8844A43C3882425 +:10A37000387226024073F00D547383FF5A73FFDB6B +:10A380002FE7C54780434223787383C2F20241EF2F +:10A390000800F20139E5790188E239E01D09D5CAE2 +:10A3A0008C6196D848FFFF64802A49FFB9F0FCC24F +:10A3B000842080612E27C547E222E806383005094F +:10A3C0008C219648D5F82E17C54884802E27C5487D +:10A3D000E222E81184402E37C547E243E80980A213 +:10A3E00042508C738C41384015099690D5F58C21DC +:10A3F0009648D5ED2E17C54784602E27C547E22223 +:10A40000E81384402E47C548E244E80B2E47C54771 +:10A4100080A1425110738C41383015099690D5F3C4 +:10A420008C219648D5EB2E37E8802E17E881421113 +:10A4300088738440382005092E47E8822E37C547A7 +:10A440002E17E88342120C7338200509DD9EFC00AC +:10A4500051FFF5C880C0C936C0463C33E2B644223D +:10A4600037FCB186444003E89609E203E80C020198 +:10A47000068A0A510001FE2440001416380305091B +:10A480008C21D5F3800649FFFF95501F8528800653 +:10A49000844149FFFEDF800649FFFDCD8006501F45 +:10A4A0008528844049FFFED6B042B084800649FF2B +:10A4B000FE38F081B0428006B084F30149FFFD3CD4 +:10A4C000D51044024510441237FCB0868460848164 +:10A4D00049FFBA01B006B042B084806649FFFE8FE2 +:10A4E000F081D502F08144024510441237FC49FF47 +:10A4F000B94EF00151FF8A38FC80FC4284C08401CF +:10A500003C6FFADA3E67E935810649FFF54A814634 +:10A510003C6FFAD5B6DF812680E65A7804112E0703 +:10A52000E969842349FFDD8084003C1DFA9880405E +:10A530004432B39049FFDE5D8481D513800749FF23 +:10A54000E692F0813C1DFA98840380474432B39030 +:10A5500049FFDE4F2E07E969842349FFDD65F401D9 +:10A5600088899620F081F0014C90006049FFEA5AFA +:10A5700049FFBCEAB41FE209E831800A49FFE673EB +:10A58000F082B41F8C019600B61F4C650003850055 +:10A59000500400019600F0838028800A49FFFF598B +:10A5A0005A0801162E07E9575A0801123C0DFAB451 +:10A5B000A78097B05A6801FE2E07E969842349FFF6 +:10A5C000DD334400007349FFB297D539800AF102A8 +:10A5D00049FFFC2D80CA048F80034403F04A4410D5 +:10A5E0000055AE402E17E9693C0DFAB45A18031114 +:10A5F000A6405A1801FF44020000441200024422FF +:10A600004510FA62FA94FAA049FFF175D504A64004 +:10A610005A1801FF50048001549000FF3C0DFAA924 +:10A6200084218147AE40D5A08CE197F85A7005048B +:10A6300048FFFF75840049FFF4B484C08006FCC263 +:10A640002E37C5E85A38015FFC003C3DFA98A6D980 +:10A650005A3009045A38040EA1022E67E9413C33EE +:10A66000E311404218972E57C62F9721A003D51FFC +:10A670002E47E9693C33E3105A4804112E47E91587 +:10A68000523180FFFF1C2E37E9482E600D284042D2 +:10A690000C96524200FF96E1D5032E67E926B4805E +:10A6A0002E57C62E404218979721A0014000181738 +:10A6B000E2239999960197B1E8048A6196D9D50267 +:10A6C00084605CF302018026E9034410020096498D +:10A6D000E281E904A6108C01D504E260E8FC840064 +:10A6E000AE10A610E2A08401E80C8400AE102E008B +:10A6F00004538C013E000453FA0549FFB1FD840266 +:10A70000FC808401DD9EFC40EF003C1DFAB4840215 +:10A71000AE083C1DFAA9AE084403F403A78097B025 +:10A72000CEFE3C0DFAAB8426F0853C0C017A4480C9 +:10A7300000483C0FFAAB2E07E96949FFDC753C9CE9 +:10A74000017A2E07C567E2C0E83FB00950AF80200C +:10A7500084E0505F801BF08180268009502F801A92 +:10A76000B0C7504F801DB75FF7824900434580094D +:10A77000B05CB0AE003F801C004F801D4900438A92 +:10A78000B0938009B04A003F801B49004418FA5436 +:10A79000B11CB14A38351E024243A073425388733C +:10A7A0008400381201015A13FF0638F2800038F194 +:10A7B00085098C015A0824F75A70010484E1D5E90F +:10A7C0008CC197B0D5BF4402000044120C6049FF11 +:10A7D000B7DE4402000044124C6049FFB7D8442061 +:10A7E00000484402290044122C6049FFB7B54402D6 +:10A7F0001B904412000049FFB7CA2E07E969842361 +:10A8000049FFDC123C1DFAB4F00584C03C0FFAABE2 +:10A810008401AE083C1DFAA9AE082E10045C440069 +:10A8200000FF49003686500F801E44120C60FA4229 +:10A83000FA74126F800F49FFB831500F801E441216 +:10A840004C60FA42FA7449FFB8292E07E95E3E6768 +:10A85000E9115A0801043E67E95E2E07E9445A08E7 +:10A86000010584003E07E944ED00FCC0FC008400C3 +:10A870003E07E94C84003C6C027F80608020804071 +:10A880009970A52897235EF20064E9038C418C211E +:10A89000A52897235EF27F9DE8038C618C418C0292 +:10A8A0005A0890F05A3048045A18480584013E0767 +:10A8B000E94C84003C4C027E2E10040A80609960B2 +:10A8C000A5685CF28050E8078C6196D8E664E903DD +:10A8D000842484408C025A0890F4E62480013E10BF +:10A8E000040AE90684003E00040A8401D511C90364 +:10A8F000E649E80E3C0DFA98A6015A0806068404BB +:10A900003E00040AD5048C213E10040A8400FC8019 +:10A91000A611A6909CC18A6296D8E6634EF200A169 +:10A92000E6324EF3009EFC4184E040A1040894C14D +:10A930003C4C02788127838780C780A750A5028876 +:10A940005081828840351C008864A4D896DBE46678 +:10A95000E9068CC1887C97B041C1801140341C004D +:10A960008864A4D896DBE466E9068CA188699768B8 +:10A9700040918011507380245A7A88E640FE19F67F +:10A980004034947684E040978013149F800183873D +:10A9900083C74091801340351C008864A4D896DB9F +:10A9A000E466E90A04FF80018A6F4E340003FEDA90 +:10A9B000887E41E1801340341C008864A4D896DB73 +:10A9C000E466E9088A694E340003FEDA887C41C1F6 +:10A9D0008013507380245A7A88E0E6D0E943E6B0C9 +:10A9E000E941406F18D6E4D9E805405E14B6E4B9F1 +:10A9F000E93BC217FA6242208C73949198E28E422E +:10AA00008844A558A590976B97B3E0C5E805A4D8EE +:10AA1000A4909A9AD504A490A4D88A439691D50379 +:10AA2000442000FFE611E820FA6242008C73940192 +:10AA300098608C028880A4C8A42096DB9603E0036B +:10AA4000E804A408A460D503A420A4488A015CF10A +:10AA500000249601E8095CF00024E806D503840090 +:10AA6000DD9E8400D50344008000FCC1FC20FAE296 +:10AA700080C0440F8000E262E9108081A1754241EC +:10AA80001C7395218885A560976BE005E803A520D8 +:10AA900096238C419690D5F0FCA05A3FFF044800C5 +:10AAA0000107FC4784204452CF5080C13862860A97 +:10AAB0008C215A1812FD84BF8420B6BF80A1E2A465 +:10AAC000E80FA19138631501DE09A19238631501E1 +:10AAD000E226E804D3038026B6BF8CA1D5F183809B +:10AAE000941AF084A015F28338900E00B41F9402DB +:10AAF000F085F003F104A0058820A689E3224EF238 +:10AB000000C0402480139CD140A18013B47F5A37E9 +:10AB1000FF1DF3058803A6C0E243E904A701E28212 +:10AB2000E806E343E912A681E24AE90FA7C2A68B31 +:10AB3000E247E8048EE197F9D509A783A60AE2C0A7 +:10AB4000E8078CC1FAF3D507FAF384C3D50444703F +:10AB500000FF80C7508F802484003804A0089A3EEC +:10AB6000E406F0814EF3008A9638544480FF9770D3 +:10AB7000F08280248045801CF302F487F58649FF2B +:10AB8000FF775EF0003CF506F407E9779C61801CD6 +:10AB900096488045F30249FFFF6B5EF0003CE96D8B +:10ABA00084013804A008FA02FE34402024008420E6 +:10ABB000880A94919401808681018061E2E4E91120 +:10ABC00004FE0005994A88AF8C81A568976B88655B +:10ABD000994888AF50108024A568976B8905D5EFF8 +:10ABE000F001401524018C014040040A886485402E +:10ABF0008888405180B6404200969449810A800A74 +:10AC0000E2E6E91C05EE000540F10400403F0800C3 +:10AC100040FF3C00A4D802F7800096DB40F780118B +:10AC20008A6540F7900142018C734287BC7342A150 +:10AC3000BC738CC150210024D5E48420490004A6B3 +:10AC400080C084208008490004A1C8028401CE028B +:10AC500084C1FF84443000644003040942050C733E +:10AC600040001817402488085EF000654412CF5059 +:10AC70004001BC1A3800880A8D2148FFFF3CA648D5 +:10AC800044000064B1094452CF50E222E80B38304E +:10AC90009000C30638328602E060E802961B8C21E1 +:10ACA000D5F55EF00046540780FFFCC78400DD9EAA +:10ACB000FC44A6CA5A30010E2E300401CB03A6C8AC +:10ACC000C30884602E47C6CC44628F7080E3D508E9 +:10ACD0008400AE0884003C080201480000D7975861 +:10ACE000E2A4E806995E8C611072818CD5F981200E +:10ACF000A005FA6E80E1504F801F802084A080C2A2 +:10AD000049FFB97C000F801F847FF083840080207E +:10AD1000F4039680E244E810A171968138528101D3 +:10AD2000DA09A0B238210101E22240113C1B403077 +:10AD30003C1B8C01D5EE5A37FF1DA0B7A036945AA4 +:10AD400038810E020423000838000E0238510E022A +:10AD5000C56A3CADFA8900250032FE844001141713 +:10AD6000F0820005003342040024405014B7D55C43 +:10AD700084A0F58280058025D50F4E020085001F36 +:10AD80000032B45FF401FE8C40110037002F003315 +:10AD9000FF1440020017A6B85A20010544A0003C49 +:10ADA000D502FB58F2028A4180224E240003FE5253 +:10ADB000E341E9079AA84E240003FE92E342E82407 +:10ADC000A0B238210D01E659E9138AA04E540003C0 +:10ADD000FF6AE0A14012BC1A5EF08190E809800988 +:10ADE00080278046F40349FFFE5A5A0801084400B0 +:10ADF00000783C0802018401AE382E17C6CC44020C +:10AE0000911484A0D5083C000201C0F78E013C08D3 +:10AE10000201D5F4D13A082000018CA110207FE76F +:10AE20009768D5F9F582A0353DEDFA898820A60B03 +:10AE3000A68AF0848400F081B61FF404E282E99EC1 +:10AE4000A70900A08000F485F405E28AE91A008FC2 +:10AE50000002808A04F48005424120734082040885 +:10AE6000890F0284000040840011E51EE908B49FA8 +:10AE70008C01888AB69FF4018882F4818D41D5E5E2 +:10AE80008C41D5DC8020D588FCC4FC000400001572 +:10AE9000844480208461848584A049FFB571FC804E +:10AEA0003C1DFFACA003A44CE201E90684003E0077 +:10AEB000044C8402DD9E8400DD9E00003A6FAABC33 +:10AEC00084E0EFFC3C2DFFAC808180C780A78545E6 +:10AED000B5244E9200118F24E722E90D0482000769 +:10AEE0000490000238F4A10100810006E30FE8039A +:10AEF00010A18002B5245084FFFFE702E9035A98AD +:10AF000004192292000702F1001EE12FE9120281CA +:10AF1000001FE109E90E2292000602F1001CE12F58 +:10AF2000E9080281001DE109E9048CC197B080E5C0 +:10AF30008CA19768504200FC5A580ACC2EA7FED527 +:10AF4000CE0684008420AE1A8081D51FA61A5A002E +:10AF5000051B5A68011450057FFFE602E8042E57CE +:10AF6000FED2DFF0440000FC4213807384012240D3 +:10AF7000800622108007AE1AD50884038420AE1AFA +:10AF80008081D503842080812E0004325A08010478 +:10AF90008405AE1AA61A5A0801633C9DFFAA005404 +:10AFA00080005A5801093C5DFFAB025280098EA116 +:10AFB0009B2C9723005480015A5801093C5DFFAB3C +:10AFC0000252800A8EA19A69964B00548003008435 +:10AFD00080025A5801403C9DFFAB025480094E83C9 +:10AFE000001E50F2FFFF0254800251C2FFFF84A2F4 +:10AFF000408795164282707340443C970284800AD1 +:10B00000029480038F018F21405414B64250A473E0 +:10B010004012A0379723964BD52251C2FFFF02540E +:10B02000800351E2FFFF84A240FE15F642F27873DE +:10B030004047F09702F4800A0294800250F7FFFF25 +:10B040008F21405794B64250A4734012BC379723C7 +:10B05000964B5A88010580A480818025E745E81930 +:10B0600044F0AF7038A7A80040F53C004A003C000F +:10B07000060C0C161C005A08010BD5105A00010CC6 +:10B08000C80C8403D50BE602E808D503C806D5062C +:10B090008400D5048402D50284043E07FED58E01C7 +:10B0A000E60484A04EF2014844F0AFB838078101AD +:10B0B00040F03C004A003C00080056008A0176023D +:10B0C00084A03C5FFFB33C5FFFB284A184003C5F7F +:10B0D000FA21445FFFAA3C0BFF683E07FED43E07FF +:10B0E000FED33E57E8883C4BFF623C1BFF633C4B62 +:10B0F000FF603C1BFF613C4BFF5E3C1BFF5F3E77EC +:10B10000FED23E07FEBA3E07FEB8480001172E07E2 +:10B11000FEBA0251001A3C4BFF5EE2053C1BFF5F8A +:10B12000E8048C013E07FEBA3C07FF609BC44E74E6 +:10B130000003FFFA3C57FF619A294E040003FE0208 +:10B14000025100198807E0A0E80484013E07FEB818 +:10B150003C97FF62400490014E040003FE023DC78D +:10B16000FF63407E04014E740003FFFA02A1000554 +:10B170009978E3454EF200E2A5562E87FED3E2050C +:10B18000E90DE124E806854058540002812AD509DA +:10B190005454000185408521D50480A8854285202E +:10B1A00002F10007E2EFE90DE03CE80458528001AB +:10B1B000D508974E8D219768549480FF58A50001BB +:10B1C0003CFDFFB288EF3C7FFFB23C7DFFB38807B8 +:10B1D0003C0FFFB35A98020E2E07FED4C81D8401FF +:10B1E0003E07FED43C0DFA2194023C0FFA21D525EE +:10B1F0005AA803132E07FED4C80F3C0DFA2194025F +:10B20000580000023C0FFA2184013E07FED484025C +:10B210003E07FED3D5124C5400112E77FED4E6E73C +:10B22000E80C3C0DFA218CE19402FE2F3C0FFA2130 +:10B230003E77FED43E57FED33C4BFF623C1BFF6380 +:10B24000D57C2E57E8885CF28020E811A410A51167 +:10B2500040004008401010045202801F4000800E41 +:10B260009606C805440FFFAA3E07E888A410920C72 +:10B270009606C0632E07FEBB5A08012A2E17FEBA97 +:10B280000201001AE220E8232E17FEB90201001B7A +:10B29000E220E81D2E07FEB8C81A3C07FF5E3CF707 +:10B2A000FF5A021100198A0F4E040003FE02E0014A +:10B2B000E80E3C07FF5F3CF7FF5B8A0F4E0400037C +:10B2C000FE02E001E80484033E07E8882E17E888C0 +:10B2D00084003E07FEB95A1003313E07FEBB2E071D +:10B2E000FEB8C82B3C07FF5F0211001EE001E91DFC +:10B2F0000211001FE020E9193C17FF5E0241001C0B +:10B30000E024E9130241001DE081E90F2E57FEBA47 +:10B310000241001AE2A4E81184813E47FEBB3C1BB7 +:10B32000FF5A3C0BFF5BD5098402AE1AD5063E5787 +:10B33000FEBBD5033E57FED584003E07FED63C0338 +:10B34000FF68CE052E1004325A180115A454E201EC +:10B35000E8058C013C0BFF68D5272E000423C806A6 +:10B3600084013E07FED68404AE1A84043E07FED54F +:10B37000D51B2E17FEBB5A18010E2E17FEB902411F +:10B38000001BE224E8058C213E17FEB9D5033E6779 +:10B39000FEBBA454E201E905440FFFAA3E07E8887A +:10B3A00084003C0BFF682E27E8885CF10020E82130 +:10B3B0008C4C96908401E65EAE18AE998401E90546 +:10B3C000FA2E49FFC335D504802249FFC3318403D7 +:10B3D00049FFC3348400EC043E07FED5440FFFAAA6 +:10B3E0003E07E8883A6FAA844400006048FFAB84B7 +:10B3F000EC048400AE183A6FAA84DD9E3BFFFE3C4D +:10B40000EFFC4412B4948400442FFFAAAE08AE0AA5 +:10B41000AE8984203C1FFFB33C1FFFB23E17FED411 +:10B420003C1BFF6884213E27E8883E07FED53C1F71 +:10B43000FA213E07FED33E07FED63E07FED23E0768 +:10B44000FEBB3E07FEBA3E07FEB93E07FEB8EC045F +:10B450003BFFFE04DD9E3C0DFFACA404DD9E2E07E9 +:10B46000FED6DD9E84002E17C54144328F70808049 +:10B470009680E241E80698838C01104103ECD5F9EF +:10B480004400003C3C0BE499DD9E3C13E390AC404F +:10B49000DD9E4402CF988420AE40AE41AE42AE4322 +:10B4A000AE44AE45AE46AE47DD9EFC4046F7FFFFDC +:10B4B00050F78FFF5A18024480A0808084E0B46463 +:10B4C0005A38022280C085204C748019B4665A38DC +:10B4D000021622120006223300069ACB4E340003D5 +:10B4E000FEDA2212000722F300078A2F4E1400030F +:10B4F000FE4AFE4C42118C7381E18D21506300FCA9 +:10B500005A980AE48CE1504200FC5A780ADA50005A +:10B5100009D8B4655A380210A0EFA11594DA8864EE +:10B52000A718C414A7195A401112A71AC40FA6DBF2 +:10B530005A30230D505280FCD8EDD50684003E07CA +:10B54000FED83E00045D8400D50284012E30045DE7 +:10B550004420FDE7E04FCB0CE90C2E17FED88C21E0 +:10B560009648E6233E17FED8E9098421D505E8FE72 +:10B5700084203E17FED83E10045DC00684003E07BE +:10B58000FED83E00045DFCC0FC418501B61F8081F1 +:10B590008120838185404004A001E320405E280192 +:10B5A0004C5780234074A000E2E9400E2800406719 +:10B5B000800040037C0892E1FFC792C1800780268B +:10B5C00080478066F48149003AD9F401E281E909B3 +:10B5D0004C124005B43FE220E90481078146D5DCE6 +:10B5E00081278386D5D9E602E8DE8008802AFCC15F +:10B5F000FC204430271080C0FE5C22000028402040 +:10B60000885622130050FE1C40100436E0222243CC +:10B610000000E85340F011F6E04FE8514450007844 +:10B62000FA388083980D90015CF00051E9045230A3 +:10B6300000A0D50480605A00280552700078D50318 +:10B640004470005038330D1138731D11FEE4403141 +:10B650009C76E043E8039F41D504E062E8349C41D6 +:10B66000E0A1E8E14C00800380A15CF28051E90494 +:10B67000521280A0D5028025507280285CF3805140 +:10B68000E903527280788A624E340003FEDA38137E +:10B69000051144402710FF0C38131D114042049639 +:10B6A0009AA24E240003FE92E062E90DE043E90A0B +:10B6B000E2054002BC1AD507FA18D5054400007807 +:10B6C000D5028005FCA05CF00051E905523000A0D5 +:10B6D000B661D502B60150107FD85CF08051E90503 +:10B6E000520000C8B602DD9EB622DD9EA6493C434C +:10B6F000E3015A1001049660D502A6522E20044C94 +:10B700005A280103A65C22F00003E02FE80484011C +:10B710003E07E960DD9E3C2DFA982E37C5F6A691CE +:10B720005A20060496D9D5032E37C5F8A6015A0823 +:10B7300001042E37C5F72E07E90D5A0801044430DD +:10B7400000782E47E94B2E07C5FC2E27C5F5E28071 +:10B75000E9342E07E94D5A0801384020080C3A6FA9 +:10B76000A83C8A43EFFC969104A08002B5210470A6 +:10B77000801484A0446005104085140040049400A7 +:10B7800002F40000993DA400A460FE1C42013C7339 +:10B7900088012E17C5F58CA24010040D964912148D +:10B7A0000000021400002E87C5F54010A00C8A018D +:10B7B0009601AC20DEE2D5058C813E47E94BDD9E4B +:10B7C000EC043A6FA804DD9E3A6F9ABCEFFC2E079A +:10B7D000C5DF5A0001048401D55884003C0BF4DC19 +:10B7E0002E07E960C0052E07E9345A0801F646170E +:10B7F000FFDD445225B050108A508460442228381E +:10B8000098293C4C027894018804A40096035EF0C9 +:10B810007FC9E80EA6288C019600AE28A628E60A65 +:10B82000E9083C03F4DC8C013C0BF4DCD502AEE807 +:10B830008CA1DAE73C03F4DCC8052E07E9345A088A +:10B8400001CC84003C0BF4DC445225B0441228386F +:10B8500018028001D9FE2E07E9345A08010B2E0088 +:10B8600004528C013E000452FA0649FFA945D5094D +:10B870002E0004518C013E000451FA0449FFA93CFA +:10B8800084003E07E9348402EC043A6F9A84DD9E1A +:10B890003A6FAABCEFBC84C0126F8018126F801977 +:10B8A0008100FAC2428098734074180050647FFF90 +:10B8B00040A3001350640001F28B97F997B1C906B9 +:10B8C000C0145A08111680CAD51350947FEE4094C4 +:10B8D00080135A182307C00E5A08111080CAD50DBC +:10B8E000C00E5A08110ED50B81468127D509812734 +:10B8F000D507814680E9D50480E9D50280CA3C0C91 +:10B9000001EE956A88A041C40408A668A62941E50D +:10B9100004084C1040233CAC027940057000A5405F +:10B9200040057800976BA4409431880A964BA40098 +:10B930009A6996034E140003FE4AE0A1E9079A288B +:10B940004E040003FE02E0A0E8082E000426E607ED +:10B95000E8048C013E0004263C0C02752E87E92683 +:10B96000F0823C0C0273F08340048408F084943924 +:10B97000F0859431F0862E07E9342E90042BF08167 +:10B98000440000C8420400245010005050007FB012 +:10B99000F088440FFF3842040024F187F0898420A6 +:10B9A000F202F00397C840011C1AF20438507011DB +:10B9B00038600801F205126F801B125F801A386030 +:10B9C0000801F206126F801C386078013800080107 +:10B9D000126F801D120F801ECF0840F2A1F65EF795 +:10B9E0008032E8038401F081B00CB14D38A005111C +:10B9F00084C522028000F207F58AE040E904F208DB +:10BA0000E002E810F20988024E040003FE02AC28AE +:10BA10005A78010B22FF801A5EF7A7114093BC1AD7 +:10BA2000D5038400AC28F00A8CA2220000004E044A +:10BA30000003FE028EC1880A97B040A00011CEDA42 +:10BA4000B00C38A005095A1001048421D5AA000FB2 +:10BA50008004F10B3E07E9343E90042B220F80183E +:10BA600022FF80195A10010A5A3001082E00042BB7 +:10BA70005A0001098400D50A8A0F96035EF000A0DF +:10BA8000E9F68401AE2044008000EC443A6FAA84B9 +:10BA9000DD9EFC0084208461804180834400564008 +:10BAA0004900160E5410007F844158108080806237 +:10BAB00080824400564049001603FC80FC0084202C +:10BAC000846180414400DAE08083490015F9441024 +:10BAD0000271FE0C441003E8400004162E1FE966B4 +:10BAE00050007FD896025A187F043E07E9662E1F41 +:10BAF000E9665A107F1A8A014E040003FE02E40F21 +:10BB0000E9138421E41E3E17E93BE9095EF0003C9D +:10BB10003E17E91CE9073E17E968D50D84003E078A +:10BB2000E91C8400D50684003E07E93B3E07E91C7A +:10BB30003E07E968FC80FC43F0842E07E9685A0060 +:10BB4000010A2E07E91C5A08010BFAF144A00085EE +:10BB5000D5094470003244A000C8D504FAE944A0D5 +:10BB600000642E07E96394D9F0834402C92C8860ED +:10BB70004402C9BCB61F50008510F08584C0440F34 +:10BB8000F448F08183C1808645C00BB880068126C9 +:10BB9000F6825A60081D225F000022FF000140F279 +:10BBA000BC014EF4000452F7800040F79C07E82ED9 +:10BBB00081E54E54000452F2800040F7A807E826C1 +:10BBC0008805960338F11901A558D51C2250800824 +:10BBD00022F0800740F2BC014EF4000452F78000CE +:10BBE00040F79C07E81381E54E54000452F28000B0 +:10BBF00040F7A807E80B8805960302F18000025180 +:10BC0000000888AF8C81AD5897202A5F00014E55FF +:10BC100000068D21549480FFD509048F800250F4D2 +:10BC20000001548780FF148F8002048F8001E0BCE4 +:10BC300041C2BC1BE1054082BC1B8CC1148F80013A +:10BC40005A6809A9C4592251800040001016405278 +:10BC500090B6AD5896035A900905F5025A5809292D +:10BC6000E686E92680804E040003FF02E499E9207D +:10BC7000404070014E440003FF22E0E4E919F40162 +:10BC80008A8080044E440003FE22E0E0E911F004C3 +:10BC90005A080107B49F000F8010AE20D505B49F4D +:10BCA000840110020024F0038C019600F08380A22E +:10BCB000506100122A028001224180004E050006D8 +:10BCC0008A044E040007D5048A044E07000384004A +:10BCD0001202FFFFDEF0B41F501080248C01B61F4B +:10BCE000F005502100248C624C107F4A000F800C1C +:10BCF0003E07E963FCC35A9809B2D5DAC8113E077A +:10BD0000E9634432C9BC80804412C92C8040384168 +:10BD10008008382081098C015A0848FBDD9EFC0010 +:10BD20008061A04E5A080105A09D8460D505A09DA4 +:10BD30008C328C52FA7449FFFF00FC80FC008400B6 +:10BD40003E07FFCC2E07FFCDC00F84C13E67E9350B +:10BD50003E60040B49FFAA725A0802043E67E930AC +:10BD600084003E07FFCD2E07FFCCFC803E07FFCDB1 +:10BD700084003E07FFCC8400DD9E841F3C0FFA2325 +:10BD800084003E07FFCD3E07FFCCDD9EFC42A7129C +:10BD9000F383C4038E81AF123CADFA8AA7530045EA +:10BDA00000038E81D4038CA1AF53A710C4038E81EE +:10BDB000AF1000450002A7518E81D4038CA1AF5172 +:10BDC0003C8DFA9BB488928E97065A4801064430FF +:10BDD0000032B67FD503FA89B69FA6D18480A7909A +:10BDE000F38180A4F301E266E946A6D3A7D2F382E9 +:10BDF000F302E267E93E0095000283C643E3A473C1 +:10BE00000490801541CF0408893CB47F02F480007F +:10BE100040F78011E06FE82004F00000F30338F7EA +:10BE2000F90005E0000138FF3D014CF1C00904F4C0 +:10BE3000000040F7B80954F78001E80904F4000055 +:10BE400040F7B80954F780015AF8010702948000BE +:10BE500040948011888904908005893C02F4800018 +:10BE600040F78011E0AFE803025480008CE1D5C1B7 +:10BE70008CC1D5B9C506440001F4FF0440421497B3 +:10BE80008004FCC2FC4281403C0DFA8B80C1853F9E +:10BE9000A640A703440003E8FE0CA65080E23C9FA6 +:10BEA000FA2340800013C9038400D52A840080A0AF +:10BEB000E0A1E8110425000138211501DA0A042562 +:10BEC000000238211501E2024092BC1B40013C1BDC +:10BED0008CA1D5EF3C9FFA235A97FFE80425000573 +:10BEE000401488088822B0038444B69F490036660F +:10BEF000800A8026B083806949FFFF4AB49F3C1DB9 +:10BF0000FA9BB421922E96465A1801140415000388 +:10BF10003C2DFA23381089015CF0812CE803448021 +:10BF20002AF83C13F52B5CF08051E9038400D5031B +:10BF3000E300E9082E1004005A18010F2E10045BCC +:10BF4000C90B84013E07FFCC3C0DFA8B8421A6016E +:10BF50003E07FFCDD563441003E8FE649649E22016 +:10BF6000E85C808A3C1DFA23A0234430006438201A +:10BF70000501FA18FE1440000C169601E2038040F9 +:10BF80004021BC1B9611F081A025944A8801842091 +:10BF90000080000300A00002A70101E00000E30A06 +:10BFA000400428019600E902802096498460B63F4B +:10BFB0008043803EE224E82080AAE2A8E817FB2222 +:10BFC00081E142F2A4734097840804F30005892FAD +:10BFD00004FF80010294800040948011E12FE90366 +:10BFE0008C4196918CA19768D5E9B4BF8C21886566 +:10BFF000964896D9D5E0E662E91044100064FE8CBC +:10C0000040310C7696D95CF18048E9078A9E9720EA +:10C010008A048C01E603E99684202E07FFCDC00D2B +:10C020005A1801053E17FFCCD5088E0196003E0731 +:10C03000FFCDC8033E07FFCC2E07FFCC5A080104F2 +:10C040008420AE78FCC2FC438400100F80173C0CA7 +:10C050000278504F8017802084A04422D1DCFA78E7 +:10C0600049FFAFCC8420005F80173C9C01EA3C6C08 +:10C0700001EB808180019688E245E80F38748501E4 +:10C0800096C94C71C00938330501E20340413C1B9D +:10C090004001BC1B8C21D5F094623C7C01EEC03D7C +:10C0A000997996E1A629A6A8F0813DEC02783DCCCD +:10C0B00001E98400FB02F383F301E262E925A7AB07 +:10C0C000A6EAF682F602E2C3E91C814242A1A0730D +:10C0D0004065040888DE02F3000040F780115EF737 +:10C0E0008028E90C38AE290004FF800338A4A90198 +:10C0F0004CA7C005A5B097B388068C6196D8D5E348 +:10C100008C419690D5DA442001F4FE143C2C01ECCD +:10C110003821110140000817882744504E1FE2A023 +:10C12000A6CBA70AA689A648E80E8A6496D8E66B2D +:10C13000E8058A419690E64BE90844106D5F40009F +:10C140008006D5048400D5028401FCC34403F0803A +:10C15000441FFFB6AE403C0DFA173C3DFA16920262 +:10C160008C01442200008420E220E806A31138411B +:10C17000860A8C21D5FA84013E07E8FE4403F0804C +:10C180008420AE40DD9EC0174E1700164E270014C7 +:10C19000980AE41FE910E02244000064E807AE18A2 +:10C1A000FE0C40200856AEA0DD9EFE8440210456C1 +:10C1B000AE98D50444000064AE18AE20DD9EC10BDD +:10C1C000402084094430006442200C73401104363E +:10C1D000960BDD9E8001DD9EFC40EEE080E0440198 +:10C1E0002BC8B0483A2014043A209424A4002E9777 +:10C1F000C53A2E87C53BAC0844012BDC80C051CF2B +:10C200008034803C3A2314043A209424A5B0AD88AD +:10C2100080203A209404B0523A209424AD88B0573C +:10C220003A2014048001B05C3A201424AD808400CC +:10C23000100F801E100F801F44012BF03A201404B1 +:10C240003A209424A400AC0844012C04B0613A20A4 +:10C2500014043A209424A400AC0844012C18B066BD +:10C260003A2014043A209424A400FA54AC08842000 +:10C27000B03F490034AD44012C2CB06B3A2014047B +:10C280003A209424A40050FF80C0AC0844012C4004 +:10C29000802F3A2014043A209424A400AC08B075EE +:10C2A00044012C5480C13A2014043A231424A400DD +:10C2B00044212C68AC30B03A80C281403A23140447 +:10C2C0003A251424A4F0123500002E2004165A2812 +:10C2D00001044800014B50247FFE42212424949104 +:10C2E00040A3880050247FFFF282422124249491AD +:10C2F00040648408884788C7F281850014FF800362 +:10C30000F184F085540400FFE209E831B06B380392 +:10C31000A1113810A00049FFFF54F1033803A1090F +:10C32000380321113810A00049FFFF4BF1043803F6 +:10C330002109380521113810A00049FFFF423805B6 +:10C340002109F105F0013810A0003800211149FF42 +:10C35000FF38F1013800A10938032111381E2000EF +:10C3600049FFFF2F380321098D01D5CDB03F814012 +:10C37000810784A09628E2094EF20089B0A1B05C42 +:10C3800039C11400B0A63810940038228800F28118 +:10C390005A180A39C0755004FFFFD81202137FFFE4 +:10C3A000A4B08C218C418401964B9693503F801E03 +:10C3B000504F801FF58349FFFEE8F503D507440081 +:10C3C0000064100F801E100F801FF301001F801FDC +:10C3D000000F801E222400004210F024FE1C98C88A +:10C3E000FE54FE1441C08F9602157FFF40300C763C +:10C3F00002050000883C886012157FFF123500009E +:10C40000D53F5A180B35C811A470A4B18C218C41AA +:10C410008401964B9693503F801E504F801FF583AA +:10C4200049FFFEB3F503D50744000064100F801EDA +:10C43000100F801FF301001F801F000F801E222499 +:10C4400000004210F024FE1C98C8FE54FE1441C0A7 +:10C450008F960215000040300C7602050001883CE2 +:10C4600088601215000012350001D50A5A180C090F +:10C4700002050000021400008801120500008CA1D2 +:10C480008D428D028CC248FFFF7784008040964029 +:10C49000E229E80BB07F3810810138138109B07FA1 +:10C4A000382081098C01D5F4F00244200064420058 +:10C4B0002424102F801E102F801F948140102401EF +:10C4C00041C388009589222E000088C7444004B0EB +:10C4D000A57044301E78FEA440210C568845ACB0AF +:10C4E000225E0000442019C8FF5440528CB6125EF0 +:10C4F00000005054FFFF8805940140838000882588 +:10C500009449220400008827FF04A40840420C96A6 +:10C510008880AD082204000050AF805CFE8440217A +:10C520000C56122400008500540400FFE209E81DA7 +:10C53000B0483803A1113810A00049FFFE42B052A4 +:10C540003803A109380321113810A00049FFFE3932 +:10C5500038032109380E21113815200049FFFE311A +:10C56000380E21098D01D5E1ED20FCC03A6F9ABC4F +:10C57000EFFC49FFA6634413F0105A080206440F6B +:10C58000FFAAAE08D5038400AE083C0DFAAC9E4667 +:10C59000E622E9048E09E605E80F3C0DFA984412FC +:10C5A000CE683C2DFA9B4432B5103C4DFAA249FFAF +:10C5B000DA545A0008038401EC043A6F9A84DD9E31 +:10C5C0003BFFFCBCEFFC490036E4490035E53C0D7F +:10C5D000FA988421AE414900395A49FFA62F5A08DA +:10C5E000020449FFFA58440000A04900280CEC045A +:10C5F0004402B4B03C1DFA983BFFFC84480035EA85 +:10C600003BFFFCBC8404EFFC3E07E8FD440000A1B6 +:10C61000490027F93C0DFA984412B3AD4422B510F5 +:10C620003C3DFAA249002EC02E07E92C5A08010A07 +:10C630004402B3414412B3E449FFA7E849FFE56D62 +:10C640003C1DFAB48402AE083C1DFAA9AE084900AC +:10C6500036FC2E07E92C5A08010449FFE55749002A +:10C6600037EA4400007FEC043E07E966FA043E071F +:10C67000E9253BFFFC84840248FFA23E3BFFFEBC51 +:10C68000EFF82E07E92C5A0801074402B341842031 +:10C6900049FFA74E2E07E9698E03E602E80D2E0733 +:10C6A000C5D45A08010A49FFD03E84023C1DFA9ABB +:10C6B00049FFA687D50849FFE53DF081F1018400D7 +:10C6C00049FFA67F3C0DFA98A6415A180D04842311 +:10C6D000AE41440000A3490027962E07C5D55A084D +:10C6E000010C3C0DFA98A6005A0801072E07E969CB +:10C6F00049FFE56DD507440245104412400049FF4B +:10C70000A8464402D4044412B48C44328F704422AC +:10C71000D50C4442D3F8490022CD3C3C0279840038 +:10C720004412D4849898A490382080098C025A0826 +:10C7300048FBEC083BFFFE84DD9E84003E000416AF +:10C740002E07C53A3C2C027994418E2488223C3035 +:10C7500004E0A4483A6FA0BC964BE061E80C940258 +:10C760008E048802A40096035EF07FECE804840146 +:10C770003E00041649FFA5625A08021F49FFE64A17 +:10C78000C81B3C0DFA98A6015A0803072E07E92595 +:10C790005A081413D5035A08061084C03E67E925C9 +:10C7A00049FFF98E2E07E93B5A0801043E07E912BA +:10C7B0003E67E976D51049FFA5415A08020D49FFA9 +:10C7C000E629C0093C0DFA98A6015A08060584011D +:10C7D0003E07E9762E07E925E614E8048C013E07BA +:10C7E000E92584004412D05C8040382081098C0106 +:10C7F0004462D05C5A0812FB2E07C5D65A08010BBA +:10C800002E000431C8074402D40480264900265C67 +:10C81000D50E3C0C02793C1C027849FFA7B8840075 +:10C820008020381301098C015A0812FD2E77E91275 +:10C830005A78011649FFA50280C05A0802118400E7 +:10C840004412D40449FFFA5C80074412D40449FF1F +:10C85000FA5780064412D40449FFFA5284013E007C +:10C86000045C2E07E9615A08120D3C03F4D88421B8 +:10C870004900275A5A0801062E10045C490026591F +:10C880002E17E92C5A1801064402B34149FFA6505D +:10C890002E07E9615A0812103C03F4D8842249009B +:10C8A00027435A08010984022E10045C3A6FA084C1 +:10C8B0004800263F3A6FA084DD9E2E07E9613BFFCA +:10C8C000FCBCEFFC5A08120E3C03F4D8842F49003C +:10C8D000272B5A080107840F2E10045C49002629D3 +:10C8E0002E07C5D35A08010C3C0DFA98A6015A0828 +:10C8F0000A07EC043BFFFC8448FFE56EEC043BFFB9 +:10C90000FC84DD9EDD9E3A6F9ABCEFFC2E07E94762 +:10C910004E0300872E000432C8042E07E960C005CC +:10C920002E07E9345A08012449FFB87FC8202E0792 +:10C93000E980C81D2E07E9125A08010CFA0249FFC6 +:10C94000A0DB84003E07E91284013E07E980D50F91 +:10C9500049FFF73C5A0002F44402D50C3C13E312A1 +:10C960004422B3A849FFEE6E5A0002EA3C0DFA9841 +:10C97000A6412E07E9805A1006045A180B125A00D5 +:10C9800001092E0004585A0001052E07E970C0481D +:10C9900084013E07E9353E07E9308401D5425A005B +:10C9A000010A2E0004585A0001062E07E95C5A08B5 +:10C9B00001254403F04A44100055AE403C1DFAB432 +:10C9C000A608C0FF84003E07E9803E0004588401A9 +:10C9D0003E0004592E07E9615A08120E3C03F4D8B0 +:10C9E0008425490026A15A08010784052E10045CFD +:10C9F0004900259F8402D5152E07E9645A080F11B6 +:10CA000084003E0004193E07E9644400007149FFB8 +:10CA1000A0733C0C02733C1C027549FFA6B884014C +:10CA2000EC043A6F9A84DD9E2E07C5D43BFFFCBC14 +:10CA3000EFFC5A08010A440293705010002850205D +:10CA4000005849FFD02C3C0DFA984412CE682E278E +:10CA5000E97C2E37E9492E47E92749000A6B2E0762 +:10CA6000C5D35A0801102E00044C5A08010C440288 +:10CA7000CE6849FFF217C806EC043BFFFC8448FF70 +:10CA8000F4F3EC043BFFFC84DD9E3A6F9EBCEFF8B0 +:10CA90008400100F80073E00042B84C02E07E9435A +:10CAA000E2C0E85F3C0C01EA95F138501901DE253F +:10CAB0003C2C01ED3C0C01EC88474432D05CA65183 +:10CAC00038001911A6903C4004E0490022F33C1CB8 +:10CAD00001EA8827A488FE17AC083C0C01EC38104A +:10CAE00019013C03E62EE220E8082E07E9275A0048 +:10CAF000FF058C013E07E9273C0C01EA38501C0178 +:10CB0000DE153C1C01ED2E27E90D88272E30041779 +:10CB1000A609504F8007A64880A649FFF6BB3C1CDB +:10CB200001EA8827A488FE17AC083C0C01EA3850BB +:10CB30001C01DE153C0C01EC3C1C01ED3C3C01EE03 +:10CB400094B238109C0038001C11884349FFEEE273 +:10CB50003C1C01EA88E1A478FE0FAC388CC1D59F5B +:10CB6000006F80075A68012B2E00042C8C013E00B8 +:10CB7000042C4400007249FF9FBF2E00042CE60BDA +:10CB8000E9222E00042B84203E10042C3E100426A3 +:10CB90003E67E9345A0801182E00042A8C019600D9 +:10CBA000E60BE90F440000743E10042A49FF9FA4DD +:10CBB0004400005549FFA2C0D50684003E00042C65 +:10CBC0003E00042AEC083A6F9E84DD9E3C0DFA98E4 +:10CBD0003A6F98BCA6015A00030649FFB732E60334 +:10CBE000E9072E07E9615A0005045A08120A840071 +:10CBF0003E07EAE03E07EAE13E07EAE2D5673C0D80 +:10CC0000FABF5A08010984003C0FFABF4402B51468 +:10CC100049FFB6FF4402D5404412B52049FFBA018E +:10CC20003E07EAE249FFB70D5A0803274402B364FE +:10CC30004412B36B49FFA4A74460005F84018440A1 +:10CC400080608080842C80A249FFA3583C0DFABFED +:10CC50005A08010A84003C0FFABF4402B51449FF88 +:10CC6000B6D8D5048EC197B0CEEA4402B36444125C +:10CC7000B36B49FFA4BC49FFB6E780C05A08011D49 +:10CC800049FFB6DF5A080309800649FFB6D74400BA +:10CC9000006149FF9F3149FFB6D45A080505840158 +:10CCA00049FFB6CC49FFB6CD5A08041184013A6F4A +:10CCB000988448FFB6C349FFB6C45A0803088400E5 +:10CCC0003C0E010F84013E07E9303A6F9884DD9EE7 +:10CCD0003A6F9ABCEFF4840C4900249F4403F04A55 +:10CCE00044100055AE4049FFA4583C0DFA9B2E203D +:10CCF00004612E400432B4608403FE14842A2E2082 +:10CD000004304202047388022E20045B441003E8BE +:10CD1000420104732E27E969441000644201047340 +:10CD200080402E0004192E400431FA2EFE0C92622F +:10CD300084254202047396C6441000324201847373 +:10CD40002E37E916441027104201847388023C08EC +:10CD50000B9E49002B803C0DFA98A6415A180D07EE +:10CD60002E07E9225A080113D5682E10044CC9F980 +:10CD70004412B3B44422CE6849FFD7A22E07E97EFD +:10CD80005A0801F08401480000942E07E9615A080E +:10CD90001904490024012E07E983C0512E07E975C3 +:10CDA0005A08010E4402B3AD3C1DFA9B4422B51053 +:10CDB0003C3DFAA43C4DFAA24900270D3C0DFABDBA +:10CDC0005A08015A2E07E97184C03C6FFABD5A080F +:10CDD000554E3C0DFAA23C1DFA98B61F4422B3648E +:10CDE0004402B4B03C3DFA9B4442B5103C5DFAA409 +:10CDF0004900281A3E07E9612E0004275A08052C2D +:10CE00003E07E96144022D50FA32AE403E600427ED +:10CE10002E07E9614900246396003E07E91A5A008B +:10CE200003485A0802294403F04A44100055AE4012 +:10CE30003C1DFAB4A608C0FF8402D53A49FFC6E6F5 +:10CE40005A0801AE3C1DFA982E07E969A64949FF28 +:10CE5000A4BDD5A55A0804DE3E07E96144022D5061 +:10CE6000FA31AE403E600427D5D4440000553E0759 +:10CE7000E971D5CF49FFA8682E07E9695A08030769 +:10CE80002E07C666C80349FFA3FD2E07E9725A00A4 +:10CE9000010448FFFF7984003E07E97249FFFE98CC +:10CEA0003C0DFAA9A640C9FF8421AE40FA03EC0C60 +:10CEB0003A6F9A84DD9E3A6FA8BC49FFA1BFC06358 +:10CEC0002E07C5DC5A0801603C0DFA9B49000C7422 +:10CED0004412D1DC4402D79C49001E194402D79C5D +:10CEE0004412D1DC49001D544402D79C4412D1DCC9 +:10CEF0003C2C0278490010694402D79C4412D1DCD2 +:10CF00003C2C02784900178584804402D79C84AA6F +:10CF1000812484C280E4B420C13000300054C32294 +:10CF20002220002E2210000652A18002FE9C4225E3 +:10CF300004732210002F22800007FE5C421520732C +:10CF400040211856401098369693964B8E61AC86C9 +:10CF5000AC47103000544E240003ADC64E140003FD +:10CF6000ADC7041000165A180106041000265A1006 +:10CF700001058C819720B7208EA1500000FCCDCCFC +:10CF80003E47E9233A6FA884DD9E3A6FAABCEFFCC6 +:10CF90002E07E92C5A0801074402B341842249FFB5 +:10CFA000A2C72E07C5D45A0801064402D3F849FF88 +:10CFB000CD582E07C5DA5A08010A4402D404441297 +:10CFC000CE684422D1DC49FFEE752E07C5D35A083E +:10CFD000010F2E00044C5A08010B4402CE6849FF91 +:10CFE000EF61C8054402D3F849FFF25149002A60B5 +:10CFF0002E07E969540000FBC80C4402D1DC44123E +:10D00000B37B3C2C027849FFD4AB3E07E8C8D5047B +:10D0100084023E07E8C83C0C027849FFF8DF44026E +:10D02000D4044412B4A844228F70846084854900DB +:10D030001E088400442291403E07E9604412CE68F5 +:10D040004402B4A85031001449FFF3522E07E9619D +:10D050005A08120E3C03F4D88423490023655A0869 +:10D06000010784032E10045C490022633C1C0279F2 +:10D070003C0C02785030801050500010848844627C +:10D08000D05CA5E83823110188479693AC980272CA +:10D090008012382311018847969312218012A49898 +:10D0A000409100112E27C53A884494918841A5D01B +:10D0B00097FBE127E804A4909693AC988CA28C622D +:10D0C0005A4009048489D5DE3C2C028849002BB8DB +:10D0D0003E00045B2E07C5DA5A0801102E0004300A +:10D0E0005A08010C2E07E960C0082E000431C8055B +:10D0F0004402D40449FFEECB49FFA0A0C00D2E0787 +:10D10000C5DC5A08010A3C0C02784412D1DC3C20F0 +:10D1100004E049000C682E07E960C8074402CE68A5 +:10D120004412D40449FFF2F92E07E9604E0200B51B +:10D1300084003E07E9623E07E94B2E07E9615A0881 +:10D14000120E3C03F4D88424490022EE5A08010749 +:10D1500084042E10045C490021EC2E07E93C5A0897 +:10D1600001073C0004E08E0A3C0804E02E07C5D409 +:10D170005A0001062E07C5DA5A0801064402910C2E +:10D1800049FFCDD684023E0004002E07E9495A0823 +:10D19000010E3C0DFA9BB400920E96065A08010748 +:10D1A00049FFF7533E000400D50484003E0004000C +:10D1B00084013E0004043C1C02783C0C028844229A +:10D1C000D1DC3C3004E04442B37B84A149FFA71684 +:10D1D00084003E0004044402D1DC49FFFC582E07C1 +:10D1E000C5D95A08011C3C0DFA9BB40096065A009A +:10D1F00001083C0DFAA4A60096065A0801102E005C +:10D200000424C80C4402D1DC4412D4044422B37B6D +:10D2100049FFF63A3E000432D50684003E0004324F +:10D2200049FFF5AD3C0002195A08010B3C0DFA9B71 +:10D23000B400920E96065A0801043E0004342E00F3 +:10D2400004345A08010F49FFB3F0C80B3E00043400 +:10D25000FA2E8404844349FFB3EB840549FFB3EEFF +:10D260002E0004325A0801313C0DFA9B84203E10F6 +:10D27000040AB400920E96065A0801053E00040BFB +:10D28000D5033E10040B49FF9FD95A08021E8400A3 +:10D290003E07E930D5193E0004012E0004325A0839 +:10D2A000010649FFF54D3E0004322E07E9622E17B4 +:10D2B000E913E201E8048C013E07E96284003E07BD +:10D2C000E9433E07E9273C0002195A0900113C0DC9 +:10D2D000FA9BB400920E96065A08010A8404804014 +:10D2E000FA2E49FFB3A5840549FFB3A82E000432E6 +:10D2F0003E0004332E07E92C5A0801074402B341CB +:10D30000842349FFA1153C53F4EB3C03F465D80595 +:10D310002E07E9453E07C5DB2E07C5DB5A08013855 +:10D320003C0DFA9B3C1DFAA4B400920196065A00EB +:10D330000107A608920196065A08012AA608920338 +:10D340009606C8252E00044E3C1DFA984900068C0E +:10D350003C0DFA98A6015A0003045A0806152E0738 +:10D36000E94EC0112E000460C80E3C0C0278441235 +:10D37000D1DC4422B37B3C3004E04900068F3E0000 +:10D380000431D5054900063B3E0004312E37E94300 +:10D39000CB043E37E97CD50D4402D1DC3C1C02783D +:10D3A0003C2C02794442D56C4452B3B449FFC3AB20 +:10D3B0002E57E97CC5512E27C56A2E37C56B924181 +:10D3C00092614402D56C8420E225E80BA5008C21F3 +:10D3D0008882AD00A5018C08888312407FFDD5F5B9 +:10D3E0003C0DFA9BB400920296065A0801072E07DC +:10D3F000E969C8033E00041A84003C0E010F3C0E8C +:10D4000001103E07E9703E07E9623E07E9643C0D02 +:10D41000FA98A6015A0803172E07E9795A08030F4C +:10D4200049FFD442C8052E07E95B5A080108840366 +:10D430003E07E979D5775A08037684003E07E979F3 +:10D44000D5715A080A702E07E9795A0804F6840142 +:10D450003E07E979D5672E000432C8642E100423F4 +:10D460003E07E9433E07E97C3E0004253C0E0112DD +:10D470005A1001093C0C010F4420EA60E240E90423 +:10D480008C013C0E010F3C0C01104420EA60E2408C +:10D49000E90E3C2002103C33F4EEE262E802C105E2 +:10D4A0008C013C0E0110D5033C1E01102E07E9191A +:10D4B0005A0801083E07E93584003C0E010FD504E7 +:10D4C00084003E07E9352E0004185A08011584002F +:10D4D0003C0E010F2E17E97D2E07E964E201E80EEC +:10D4E0002E27E9622E17E913E241E9088C013E0775 +:10D4F000E964D50484003E07E9642E0004315A082B +:10D50000010784003C0E010F3C0E01102E67C5D4AC +:10D510005A68010984003E00045049FFCB903E60E8 +:10D52000045049FFF9F25A080204480000F32E00A3 +:10D5300004325A08010784003C0E010F3C0E011012 +:10D5400049FFFA744402D56C2E17E97C4422D79C1B +:10D550004432D1DC3C4C027849FFAAA42E07E96191 +:10D560005A08120E3C03F4D88426490020DD5A08DC +:10D57000010784062E10045C49001FDB84003E076F +:10D58000E93C4412D79C3C0C02782E27E97C4900E8 +:10D5900027772E07E92C5A0801074402B341842457 +:10D5A00049FF9FC62E07C5E35A08010A4402D79CCB +:10D5B0004412D1DC3C2C02784900280C4402D79C50 +:10D5C00049FFBF912E07E9615A08120E3C03F4D8B7 +:10D5D0008427490020A95A08010784072E10045CFB +:10D5E00049001FA749FFFC694402D79C49FFB99530 +:10D5F0002E07C5D35A08011D2E00044C5A080119E4 +:10D600004402CE6849FFEC4EC8134402D1DC4412F8 +:10D61000D79C2E27E97C4432B49449FFEC5149FF52 +:10D62000EF205A0801064402CE6849FFDEC8840094 +:10D63000842184413E17E96A3C0E01073E07E959FF +:10D640002E67C5413C7C01EB80A04412D79C8060D2 +:10D65000853D8142448000FFE266E824B48140F2C7 +:10D6600024025AF00105CC048085D5178440A10F0F +:10D67000384391015CF20100E808E6951240800A07 +:10D68000E9068C019600D5031280800A04408009C7 +:10D6900012A0800BE285E9E98C61501080FC80A427 +:10D6A000D5DC3E07E9593C5E01073E27E96A49FFA0 +:10D6B0009DD349FF9DC35A08020C4402D79C2E17E4 +:10D6C000E97C4422D1DC3C3C010749FFEEF049FFF4 +:10D6D000FA7F2E07E97C3E00041549FFB1A6C00978 +:10D6E0003C000203E619E8078C013C080203D5035D +:10D6F0003C0802032E67C5D45A68010E3C0DFA9807 +:10D70000A6015A00060A5A000B0849FFD00BD5049F +:10D7100080C0D50284C18006EC043A6FAA84DD9EE5 +:10D720003BFFFCBCEFF449FFDD05F081F101840013 +:10D7300049FF9E47440245104412400049FFA0277C +:10D740004402D4044412B48C4422D50C44328F7069 +:10D750004442D3F849001AAE2E07C5D65A08010B29 +:10D76000EC0C4402D4044412D05C3BFFFC8448001F +:10D770001EABEC0C3C0C02793C1C02783BFFFC8499 +:10D7800048FFA0053A6F98BC2E67E9115A6001075F +:10D7900084003E07E93D8401D51F2E07E93DC806F8 +:10D7A000840849FF99A93E67E93D490003615A0091 +:10D7B00002145A0013113C0DFAA9A6009600C80BDA +:10D7C0003E00045C490003865A00130649FFFFAA85 +:10D7D0004900039AFA033A6F9884DD9EFC008401A5 +:10D7E000842084613E07E9028041440074A0808364 +:10D7F000490007665A08AF3984218400804180615E +:10D8000080813E07E9024400FBA04900075984419A +:10D8100080628082441000FA440074A049000750DE +:10D82000844180628082441000FA44002D10490037 +:10D830000747844180628082441000FA44008010CF +:10D840004900073E844180628082441000FA44000F +:10D85000D510490007358441440015A0842080621A +:10D8600080824900072DFC802E07E902C82FFC00AA +:10D87000844180628082441000AF440074A049005B +:10D88000071F844180628082441000AF44002D1045 +:10D8900049000716844180628082441000AF440032 +:10D8A00080104900070D844180628082441000AFDF +:10D8B0004400D510490007048421804180618081A3 +:10D8C000440015A0490006FCFC80DD9EFC4044237A +:10D8D000F04A443000553C1DFAB4A648C903AED006 +:10D8E000D5FB2E17E9815A18256284203E17E9815D +:10D8F0003E17E96C3C1C0180444200003C6DFFF483 +:10D9000004108012844092305410FFFF944A8824FF +:10D9100080A4B461FAE8926A96F70213001AE24111 +:10D92000E80E95119865B520A4488889FE7C4010C2 +:10D930008C3796498C41AC609691D5F049FFFF96A3 +:10D94000440000FF2E10045C49001DF344021B90AC +:10D950004412000049FF9F1B44021B9044124000E8 +:10D9600049FF9F154413F69284003E07E9113E07D4 +:10D97000E91D3E07E94AAE08840080208040FA6F26 +:10D9800049FFD83E49001E52840049FFDB0A3C1D76 +:10D99000FA982E07E90B84812E27E921A6492E3714 +:10D9A000E93E4452B4E449FFC0ECFCC0FC20808056 +:10D9B0004403F04A44100055AE403C1DFAB4A6089A +:10D9C000C0FF2E07E9815A08022B2E07E901C0216A +:10D9D0008420445200002E07C5479201E2204EF2F7 +:10D9E000008684402E07C548E240E8102E07C54750 +:10D9F000806142310073B40494D9880388658C41F6 +:10DA0000A4D8969096D9ACC0D5EE8C219648D5E492 +:10DA100044020000B42449FF9EBAD568E603E966D3 +:10DA20003C0C0180442001FF84A004100012440239 +:10DA3000005492305410FFFF944A8820440FFE0196 +:10DA4000B421B4C4922A9677FE0CFE5484569601F3 +:10DA50004010883680E54440051098B5A4D0886011 +:10DA600096D9ACD0A4D096DB4E340007A4D096DB78 +:10DA7000E023E802ADD08CA2DCF149FFFEF74400C0 +:10DA800000FF2E10045C49001D5444021B904412F8 +:10DA9000000049FF9E7C4412400044021B9049FF55 +:10DAA0009E7684003E07E9773E07E94A3E07E91182 +:10DAB000840049FFDA654413F04A442000553C0DC8 +:10DAC000FAB4A600C803AE88D5FB49001DAF3C1DC3 +:10DAD000FA982E07E90B84812E27E921A6492E37D3 +:10DAE000E93E4452B4E449FFC04CFCA0FC40842011 +:10DAF0003C6DFFF43E17E93584203C1BF4D73C1BFA +:10DB0000F4E72E17E97F0223001AA1455A180108ED +:10DB10002E27C53B0440000C9491D50280853C1310 +:10DB2000F4DA3C33F4D9E223E9073C6DFA8D3C7D0D +:10DB3000FA8C8420D56F8C2196493C1BF4DA5A105C +:10DB4000010580048420D54C8420443FFF8044504C +:10DB5000007F9609E202E80B3C0DFA8D383004088C +:10DB60003C0DFA8C385004088C21D5F42E07E97F3F +:10DB70005A0801E93C5C027D3C7C027C8420000365 +:10DB800000109401E020E8DE94C940928C00886780 +:10DB90008C21A4189649960112048000D5F13C6DA1 +:10DBA000FA8D3C3DFA8C88C12E57E97F2043000056 +:10DBB000383184105A580106A540976B90A2AD40A9 +:10DBC000A540976BE085E910A540976BE0A3E917A6 +:10DBD000AF303C4DFA8C8C02383204088C2196C947 +:10DBE000E262E9DED541A50097235EF20080E804F9 +:10DBF000A5009723D5EA4440007FD5E7A4C096DB73 +:10DC00005EF1FF81E904A4C096DBD5E3443FFF81C8 +:10DC1000D5E096C9E262E813384304103833840033 +:10DC200040422008FF1F94C940928C008C2112446E +:10DC30008000049000068869AD18D5EC84C04400CB +:10DC400000FF2E10045C3E67E9543E67E91149006D +:10DC50001C702E07E97F5A0801043E07E9193E6748 +:10DC6000E97F3E67E97EFCC0FC0084003E07E97363 +:10DC70003E07E9112E07E95D49FF9B8A2E10045CDF +:10DC8000440000FF49001C552E07C5435200000107 +:10DC900049FF9B7EFC805A08040EFC00440000FFF4 +:10DCA0002E10045C49001C453C0DFAA98421AE40AD +:10DCB000FC803C0DFAA98421AE40DD9EFC0044139B +:10DCC000F69E80C04403F69F8440AE88AE80440335 +:10DCD000F6A0AE804403F6A1AE804403F6A2AE8067 +:10DCE0004423F6928403AE10A6B040310C09882379 +:10DCF000969784614021880CA6C8FE9FAE88441385 +:10DD0000F6AAFA4FAE884413F6ABFA6FAE08840059 +:10DD10008020804049FFD674A6705CF08023E80321 +:10DD20008C21AE70FC805A10050E5A1007045A1848 +:10DD3000030F500000569600E602E9098402AE1077 +:10DD4000DD9E500000569600E605D5F8DD9EFC41AC +:10DD500081003C0DFAA981218422A7C084C1AE4074 +:10DD600084008142F38197F83E67E94A3E07E981E2 +:10DD70003E07E96C3E07E9525A28030A3E67E91D4F +:10DD800049FFFD2E840149FFD90CD5093E67E9778B +:10DD900049FFFD265A88AD043E67E95250040055FC +:10DDA0009600E602E806840449001C673E87E90005 +:10DDB00054048002C00E5AA8030544029990D51558 +:10DDC0004402999449FFC04E84003E07E901D50FF3 +:10DDD00049001C384E9300075AA003F1440299945D +:10DDE000D5045A980105F00149FFC03C3C1DFA9842 +:10DDF0002E07E90B84812E27E921A6492E37E93E1B +:10DE00004452B4E449FFBEBD3C0DFAA5A006920AF7 +:10DE1000962F3E07E9843C0DFAA9AFC0FCC1FC2057 +:10DE200080E180C2C00D5A00041184003C0BF4E074 +:10DE300049FFC26A44423FD844323FD6D50A4442E1 +:10DE40003FD244323FD0D50544423FD844323FDC34 +:10DE500084009680E246E8073813810138120109F0 +:10DE60008C01D5F83C03F4E0AC18FCA0FC012E07B3 +:10DE7000E95E5A0001062E07E9445A08010549FFE8 +:10DE8000E444D5222E67E97F5A6801212E07E97EF6 +:10DE90005A08011E4402D40449FFFE2A80263C0D84 +:10DEA000FA9849FF9E5D800649FFDA203C0DFA98FA +:10DEB00049FFDA33F08184408402F1018066808278 +:10DEC00080A249FF9A1BFAC3D50284C18006FC8157 +:10DED000FC002E07E91D5A0801074402D40449FF3B +:10DEE000FCF7D5092E07E9775A08010C4402D4043F +:10DEF00049FFFD5E2E07E96149FFFECFFA03D50217 +:10DF00008401FC80FC002E67E9545A680107440232 +:10DF1000D40449FFFDEDD5082E67E97384015A68E2 +:10DF2000010849FFFEA33C0DFAA9AF80FA03FC806B +:10DF3000FC40A7002E67C5415A4001078480447207 +:10DF40008F708124D5124442937184A0D608087240 +:10DF500000018CA110727FEA9768D5F9A6003C43B6 +:10DF6000E62E5A080148D5099760E2A6E8F89967B5 +:10DF70008C81109283ECD5F92E07E96F9A10E40298 +:10DF8000E9095A3801082E07FFD6E605E8078C0193 +:10DF9000D50284003E07FFD6846084003E07E96F07 +:10DFA000A609C8255A3001085A28010C3C03F53847 +:10DFB000E614E9073C0004E08C053C0BE499D5032A +:10DFC0003C4BE4992E07E93C5A0801073C0004E069 +:10DFD0008C0C3C0BE4993C0DFA9BB4009202960623 +:10DFE0005A08010C3C0004E08C19D5053C03E3857C +:10DFF000D50284003C0BE499FCC0FC0084203C1B4F +:10E00000FFF13C1BFFF03E17FFE7441000403E17B6 +:10E01000E8953E17E8943E17E8933E17E8923E17BE +:10E02000E8913E17E89084203C1FFFFC2E1004600E +:10E0300084003E07FFE83E07FFD83E07FFE53E07A6 +:10E04000FFE43E07FFE63E07FFD95A18010B3C1DCF +:10E05000FA8F3C27F52DA44CE041E8033E00046014 +:10E060008400FC803C43FFEF3C2DFA8F3C33FFEEF5 +:10E07000C009E68FE9038E85AD11E66FE9058E656F +:10E08000D502AD11ACD4A6095A0806048401D50303 +:10E090002E07FFDAAE10DD9EFC4AF0823C0DFA8FAF +:10E0A00081012E17FFD8A5C2F289F38EA6005A1857 +:10E0B00001049401D5029601F0863C0DFFFB84C259 +:10E0C000A642A603F181F08A2E07FFE85A08010351 +:10E0D00084C08401100F804A9431960052100012BF +:10E0E00052000024960085209648FA42100F80497D +:10E0F000100F804D3C0DFA7D101F8048102F804B73 +:10E10000101F804C129F8023109F804E109F804FC5 +:10E1100049FFD342B0538041B01249FFD378F00198 +:10E12000F1028C01FE3494018801501F8046804129 +:10E1300049FFD3373C0DFAA6FA331010000A1290AB +:10E140000004840049FFD4264403F04A44100055DB +:10E15000AE4049FFD31C4413F140A6085A0001FF0A +:10E160003C0DFAA6F102222F8023020000119649ED +:10E170009A4192219649FAC2401098D79631F2847A +:10E180002E27FFE8F0839649200F800C41E0801095 +:10E190005A28010E3C2DFA8F85EAF304A492949339 +:10E1A00040213C56E043E8038CF997F9F2043C9D8A +:10E1B000FA8FE0E214FF8008F30402248001006F6C +:10E1C000800CF28740A10C079EB4E64BE8089E8CB9 +:10E1D0009690E65DE80484413E27FFD94EA20050A8 +:10E1E0002E2FE8955A2040612E47E8922E37E8936B +:10E1F000F4852E47E89184A0F48B2E47E890F48CA8 +:10E20000F405E283E920F401FF1CF48DF40BF70C14 +:10E21000E2E4E916F70D40F39000F70240F78408B6 +:10E2200040F3BC0002F7800040F780114EF4000478 +:10E2300052F7800088AF8C81976B9720D5E98C616D +:10E2400096D8D5DFF307E065E9332E37FFD9C33021 +:10E250002E3FE894403F0C014E340003FEDAF403F5 +:10E2600096DA9AA24E240003FE929692E444E803C2 +:10E27000E464E91E84413E27FFE7D51A44000040CC +:10E280003E07E8953E07E8943E07E8933E07E8928C +:10E290003E07E8913E07E8903EA7FFE73EA7FFD87C +:10E2A0003EA7FFD9D5073E07E8953FE7E8945AA077 +:10E2B00001048400D57BC0039E319600F2019F517A +:10E2C000F203E045E8029D71976884404FE700043F +:10E2D0009E899690F285F20A9F9140FF1807E80206 +:10E2E0009D89F2048424404104968460972197B06C +:10E2F000F70580438023F48DE2C7E924F4018A20E6 +:10E30000FF3CF48BF18C8080F10CE2A488249648C9 +:10E31000E916F10B04FF800288249449882F02F04B +:10E320008000A448884F04FF800D964BE02F969301 +:10E33000E8038C6196D88C819720D5E78CE197F81B +:10E34000D5DC2E47E8915A48400C004F80143E67B8 +:10E35000E8923E47E8933E07E8913E57E890F40183 +:10E36000F003420F1073F4029401880402548005F4 +:10E37000A500FF4C840940F281F6E04F9723E91590 +:10E38000025480068A449F09FF2C969340F201F6BE +:10E39000E04FE90B44000064FEC440118436E439C8 +:10E3A000E98984013E07FFD884013C1DFFFC5A1017 +:10E3B0000131C1055A10024A480000813C17FFF0A4 +:10E3C000F207E022E8038420D50602248002E0411F +:10E3D000E80484213E17FFE62E17FFE6C9185AA865 +:10E3E0000117F108C914C8132E17FFE75A180110B6 +:10E3F0002E17FFE5F2068C218C4196489041E041B2 +:10E400003E17FFE5E85B3CAFFFFCD5188400D5164E +:10E410005AA80118F108C915C8142E17FFE75A1891 +:10E4200001112E17FFE5F2068C219648E2413E17B6 +:10E43000FFE5E84484223C1FFFFC3E07FFE5D53E94 +:10E4400084003C0FFFFCD5FAF208021480075A2022 +:10E4500001045A0801202E07FFE400248001E24055 +:10E46000E9048C013E07FFE43C03FFF1E220E904EC +:10E470008C013C0BFFF12E07FFE4E240E9053C0371 +:10E48000FFF1E220E81B84003C0FFFFC3E07FFE4A5 +:10E49000D51384003E07FFE484005AA001053C0325 +:10E4A000FFF18C013C0BFFF13C03FFF1E220E80699 +:10E4B00084003C0FFFFC3C0BFFF13C0DFFFC5A08B5 +:10E4C00002048401D50284003E07FFE82E07FFE81E +:10E4D0005A000104480000A649FF96B0C00E2E075E +:10E4E000C5DC5A08010B3C2DFA8F3C0C0278441213 +:10E4F000D1DCA494490002773C3DFA8F3C0C0288A1 +:10E500003C1C02788048A4DCF40984A149FF9D7674 +:10E51000F009A6004E0200863C0DFA8F84C0F087F9 +:10E52000F00145EF80008E01F088F00A8E01F08A3C +:10E53000000F8028F08D000F8020F08FF009A600DA +:10E54000E2C0E86F0494000140A30408892A025441 +:10E550008000DE640404000338001901F086F1062F +:10E56000F00EE201E95B04040004880AA641A680DB +:10E57000C1059E099600F083D502F183F008E020E2 +:10E58000E8048C219608D502F00FF085C2049F1193 +:10E590009720D5028082F00AE040E8048C419690F2 +:10E5A000D502F20D84608003E244E91BF101F70318 +:10E5B000FE648A07F18BF08CF00CF1058807E227E6 +:10E5C0009600E90CF00BF1028807940188018CE1B8 +:10E5D000A40097F8886096DBD5F08C819720D5E56C +:10E5E000F107A48D8429FE8440F105F6E06FE9125D +:10E5F000F2068E018A62F20796DBA496FE1440F0C2 +:10E6000005F6E06FE9070404000238002801E6037C +:10E61000E8054052F804125480008CC197B0D58FA1 +:10E62000020F80083C0BFFF03C0DFFFC8E025C00EB +:10E630000001FCCA4402519B4412519AA600A6480C +:10E6400040002008FE0FDD9E4402519D4412519C63 +:10E65000A600A64840002008FE0F441FAE60882098 +:10E660005CF0805AE903440051A0DD9E44025198B9 +:10E67000A60092019606DD9E44025198A6009202E1 +:10E680009606DD9E44025199A600DD9E4412519EDD +:10E69000A6089600C00EA60896005A00010BA60810 +:10E6A00096005A000207A60896005A000303840049 +:10E6B000DD9E4412519F9600AE08DD9EFC00446230 +:10E6C0005198AE704412D700B6018401A989102078 +:10E6D0008009100080081030800A1000800B800133 +:10E6E000802449FFD1D4A630FC80FC0084418420E2 +:10E6F000806280824400B10049FFFFE284003C0F49 +:10E70000FAC93E000414FC80FC003C13F479440078 +:10E71000003C49FF99733C0BF45D3C13F4794400D1 +:10E72000003349FF996B3C0BF45B3C13F4794400D4 +:10E73000003249FF99633C0BF45A3C13F4794400CE +:10E7400000C749FF995B3C0BF4593C13F479440032 +:10E75000003249FF99533C0BF458FC8080413C53F4 +:10E76000F4783C13F479D126FC00443000FC4201DB +:10E770000C7380C00200002549FF99461203002552 +:10E780003C13F4790203002649FF993E1203002648 +:10E790003C13F4790003007449FF993610030074A8 +:10E7A0003C13F4790003007A49FF992E1003007A94 +:10E7B000FC80DD9EB420922696465A180109B4408A +:10E7C00092459686CA043C1E00DDD510B4209226E0 +:10E7D00096465A180109B400920596065A08010493 +:10E7E0008402D50284003C0E00DD3C0C00DD3E07B7 +:10E7F000E916DD9EFC003C13F4794400003C49FF1F +:10E8000098FD3C0BF45C3C13F4794400003249FF62 +:10E8100098F53C0BF4563C13F479FA0049FF98EE56 +:10E820003C0BF4543C13F479FA1349FF98E73C0B82 +:10E83000F4573C13F479FA0E49FF98E03C0BF45579 +:10E84000FC8080413C53F4783C13F479D12EFC00D9 +:10E85000443000FC42010C7380C00200004E49FFAE +:10E8600098D31203004E3C13F479000300A249FF31 +:10E8700098CB100300A23C13F4790203005049FF27 +:10E8800098C3120300503C13F479000300B449FF0D +:10E8900098BB100300B43C13F479000300B549FFA2 +:10E8A00098B3100300B5FC80DD9EFC0280A1F281CC +:10E8B000B421A0A9F382F48349FFD3938401F10129 +:10E8C00049FFD3B3F00249FFD3C384C0800684203C +:10E8D00049FFD3CC8006F1038CC149FFD3EF5A68BE +:10E8E00008F7840049FFD3B849FFD38E840149FF5C +:10E8F000D3B349FFD389840349FFD3AE49FFD384FF +:10E9000049FFD3A2FC82FC40AE888440A708E244C1 +:10E91000E81AA10138520901D214A1059592956A0D +:10E9200099E68885A7FA00F20002E2EFE802AFE27A +:10E93000A1C588C788A7A733A7ABE2C4E802AF2B5D +:10E940008C41D5E59DD984A092E150608025812538 +:10E95000D736A688E2A2E82EA081382115014C22E4 +:10E96000C02A50F00014B50F94AA8902990D00A492 +:10E970000003008400028D418B4810A20025B54F92 +:10E98000894200A5000210A20037B54F884AA6931D +:10E9900010220049A08338A115015022803494919F +:10E9A000884112A10003A084382115001022005BC9 +:10E9B000D503109300008CA18CC1D5CB8C2184A0F1 +:10E9C000849FD30FB440382115005A28FF04AF08A4 +:10E9D000D505A18138230901AE888CA18C21D5F2FF +:10E9E000FCC0FC4A2E77C53B5CF100248120B63F79 +:10E9F0002E67C53A50A3FFFFE909FA133C0BF4C791 +:10EA00004083040880298400D5043C2BF4C7D5F941 +:10EA1000E207E808B0C23820A005382181098C013E +:10EA2000D5F8B43F80473C33F4C744400055B002AA +:10EA300049FFFF3DF0814412CD18B41FF2018067F9 +:10EA400049FFFF634014A0008400E207E8090220A8 +:10EA5000FFFFB0C28828382181098C01D5F7B43F67 +:10EA600080473C33F4C744400055B00249FFFF1FC4 +:10EA7000F0814412CC84B41FF201806749FFFF4546 +:10EA80008400E206E80838148101B08238110109D7 +:10EA90008C01D5F8B43F80463C33F4C74440003283 +:10EAA000B00249FFFF04F0814412CBF0B41FF20121 +:10EAB000806649FFFF2A429428738400E206E80832 +:10EAC00038148101B082381101098C01D5F8B43FA6 +:10EAD000804644400032B0023C33F4C749FFFEE7B1 +:10EAE000F0814412CB5CB41FF201806649FFFF0D38 +:10EAF000FCCAFC4683C02E07C53AF385F486F08134 +:10EB00002EA7C53BC907406088068401C20984FF5F +:10EB1000D508C20484C3841FD5FB84C2841F84E14A +:10EB2000F301FED4808388819521F384403F100057 +:10EB30003C43F4C722918000F387E0894EF200F550 +:10EB40009710F4889708F489F308F4058883A6E100 +:10EB5000F38AF40AF305888320320025F409F3824E +:10EB6000F3068883A6E1F38BF40BF3068883203247 +:10EB7000002538429800F383C404848438429808FE +:10EB8000F30242938824E06AE903F3028E61892349 +:10EB9000F30142438824FEFC048F80018C8141C133 +:10EBA0008408814142321C2442A1A073806A94D916 +:10EBB000850040AF0C00B71FE124E90B38F52011A8 +:10EBC0004EF70005B47F886FB67F8C81891CD5F520 +:10EBD000B47FCB038461B67FF303F40142A0042425 +:10EBE000E064E8038943D504F4038E8189449501E8 +:10EBF000429004248D218064F40442448073952162 +:10EC00008780408F1000809CE149E90A38F4701138 +:10EC10004EF70003888F8D2141CE0C00D5F6CC0233 +:10EC20008481F3018847FE9C408080004091200051 +:10EC3000854A39CF25113CFC00DDE91FB43FF205C0 +:10EC40004230A824F10A4031907650108034944923 +:10EC500088414490005AA513F2044410005088489B +:10EC6000FF0C429E24244410006440420496382F36 +:10EC7000091140948536D520B47F42422824403281 +:10EC80000C76F40B049F80065042003495218924B1 +:10EC9000882202F4800344400050382F05114410AC +:10ECA000005A4490006442479024421E042440428B +:10ECB00024964090A536F10722F08000E08FE840CE +:10ECC000F102E423E804F103E423E93AE122E8381D +:10ECD000E47538329800E8035A380433F103F20936 +:10ECE0008E21422004739652F202F4088E41424370 +:10ECF0008873852496A238929808992ECB03AEA4E7 +:10ED0000D5102032000442F38824FFDCE0EFE80253 +:10ED1000AEA42022000842F00424FE14E00FE81004 +:10ED200010120008D50D8E84E12438029800E80402 +:10ED3000C0078E01D503C004840438029808FCC6BD +:10ED4000FC46F1892E17C53B8383F182F48AF58B4B +:10ED50002E37C53A843FC802842194D943E08024E9 +:10ED60003C43F4C7F387423F0424F3818A608E84D6 +:10ED700094D9F484F38895018540F302E143E86275 +:10ED8000F30A3831A8005A38014DF309886AA6D928 +:10ED90005A30FF34B4BC383290005A30FF2FBE01D5 +:10EDA000BF05B6DF38630D0197AFC80594F28867D9 +:10EDB000A7D9D50338739A0042338424F383F30828 +:10EDC000813E88648865F38684A08060F703E0E96B +:10EDD000E915F70188E5F785F70638F39500B4FFE4 +:10EDE0003883BD015484003F4C8340055AF0FF0333 +:10EDF000F3058D2188A1D5EB80602051002442606D +:10EE00008C24FF4CE0C5E809A750E6A3E9038EA1D6 +:10EE1000AF50A750E6A3E811103100248464D50C4C +:10EE2000F30B10010024F50438319011E065E8057A +:10EE3000A6D0C3038E61AED0F3078D418C41888389 +:10EE4000D59DFCC6FC422E87C53AF2812E77C53B84 +:10EE5000CD63B0838142B181C00451C07FFFD50230 +:10EE600083809EBAE241E8038EE1D5029DC9442029 +:10EE70000032FF1444200064F0834042089785204C +:10EE8000F503E225E91004F50000B44642243C7382 +:10EE900038F18911E28FE903D003D1028D2A8CA1C8 +:10EEA000F583D5EFF083B4AAB446422414733C9B97 +:10EEB000F4C8382189114E270004E282E802844018 +:10EEC0004C00800FF18304F50000B4A642543C735B +:10EED000385195114E570005E285E902884515CF56 +:10EEE00080034DC0000CB4AAB40642041473380168 +:10EEF0008111E408E9038E078840F7834C70801283 +:10EF0000B42AB4064204047338018111E408E90903 +:10EF10008E078840D506B08180E88142B183D59DB7 +:10EF2000840AFE144040109740022400FCC20000F6 +:10EF30008E61E6643C53E2A53C43E2A6E826FC0071 +:10EF40002260000044F0EE5438378C0040F1BC00E1 +:10EF50004A003C000410181CE026E91922100001A8 +:10EF6000E041D5108EA19A69E0C1D5F8E026D5041C +:10EF70008EA19A69E0C1E90B221000018E819A22CC +:10EF8000E02056078001D5048400DD9E8400FC80CB +:10EF9000442000FC4200887322F0000984205EF7C0 +:10EFA00084B7E902842114100025DD9E442000FC72 +:10EFB000420088738421141000161010005584201C +:10EFC0001410000FDD9EFC5DF084F2818101FA5483 +:10EFD0008420B01649001DFC8420FA54B01F49005B +:10EFE0001DF78420FA54B02849001DF2B031842066 +:10EFF000FA5449001DED2E07C53AB61F2E07C53B32 +:10F00000F08E3C03E2A5F0953C03F4535CF00190D4 +:10F01000E8048C013C0BF4533C03F4525CF0019087 +:10F02000E8048C013C0BF4523C03F4515CF0019079 +:10F03000E8048C013C0BF45184208041F0014432FF +:10F04000CD184442CBF04452CA3049FFFD54F00E73 +:10F0500084209F8197B2F00180464432CD1844420B +:10F06000CB5C4452CA3049FFFD46B41F84408E0138 +:10F070009602F091F111F0014432CC844442CBF07D +:10F080004452CA3049FFFD37F001F1118046443245 +:10F09000CC844442CB5C4452CA3049FFFD2C8400EE +:10F0A000F0854402CB14F082B016F08884004492BC +:10F0B000CD18F0865004806E50648025F083854022 +:10F0C00000048000E340E82A08030001C022000396 +:10F0D000002300730011F087F003F107F206A5008A +:10F0E00084003C0BF4C8F301800784A049FFFEAC08 +:10F0F0005CF0005B4EF20668F00288E0F002F10777 +:10F100009A38E220E90608038001C0F94800065C4D +:10F11000F0038D418C02F083D5D4F0055A00010430 +:10F120004800064484004412CD184422CB14806861 +:10F13000B116F50149FFFE06F0114412CC844422B9 +:10F14000CACCF5018068B11F49FFFDFCF0048420A2 +:10F15000F083502009D880A0B405C0118E04E602C7 +:10F16000E90E000280F3E602E90A0402800FC807F4 +:10F17000040280205CF00065E9028421505280FC8A +:10F18000DAEC5A18010C840A3E07FFF4B41FF604A7 +:10F190009401F0938400F087D50D2E07FFF4C0F79B +:10F1A0008E01D5F3B406C80DF007506300FC8C0146 +:10F1B000F0872E07C541F107E220E9F548000588F0 +:10F1C0005A0005F45A080404480004990003001C7E +:10F1D00004140004F08A94018801A641A600F18B72 +:10F1E000F086000F802CB43F10030065000F8018DC +:10F1F0008E21100300640403000FC80804040005F6 +:10F20000F20A38000A00C010D5035A000116B41FD4 +:10F2100081218E02F08F4402CA3CF08D841FF08958 +:10F220004402CC84D5114412CA84F18D8421F18921 +:10F23000F18F8120D5074412CA84F18DF089F08FB7 +:10F2400085204402CD18F10A944AF192F212041476 +:10F2500000058822B45FA7C88E41A749CF07DA0707 +:10F26000440000FFF08C8441D550DA4AA68AB47F6E +:10F27000A74B80294211887394498460E2A2E94037 +:10F28000B488888138420C005A40FF22047400017F +:10F29000387391019902A7215A40FF1A04AF800ADE +:10F2A0004C75401680248820F48C0020805B00A0E0 +:10F2B0008037007080495012003494498801F288E8 +:10F2C000A5034EA3000914AF8002D508F4138C41A6 +:10F2D0008864D5D550057FFFF082F00E8E02E207DC +:10F2E000E804F00E8E01D5029C39F0858049800A31 +:10F2F0008027F30184A049FFFDA78040D50A440080 +:10F3000000FFF08C844184E08147F788F785F7821D +:10F31000B43FF002F301FE0C40102400944988230E +:10F32000F194F10FF4028801940141E180008460BE +:10F330008003F390F105E024E912F11438508C11A8 +:10F340004E570005F1108825F190385F0C114E578B +:10F3500000038805F1138C818861D5EDF3028A23BF +:10F36000FE4B846742008C734E0600038401F294C6 +:10F37000F210842AFE5440008016F08FF107F0044A +:10F3800049FFF9EE00030018F2149606C0733C031F +:10F39000F4590413000F846012030034103300CBBF +:10F3A000C123842112130025842314130016103363 +:10F3B00000554EA20006F10E8E214C70C0058C0A3D +:10F3C00012030034000F8020F108B47F1003007D89 +:10F3D000800942008C73F10138008111122300284A +:10F3E0001203003FD50E4400019012030025840152 +:10F3F00014030016100300551213003F12130028C7 +:10F40000221300085053006CF00FA869B6058485DC +:10F410008400121300671213002E02130009100358 +:10F420000054104300571213002FF40A0414000371 +:10F430008460123300263810910110030074100309 +:10F440000075100300761003007710030078100396 +:10F4500000791003007A1003007B1003007C840005 +:10F460001213002910330056A82D840110030084C4 +:10F47000D5730403000FC0224EA20006F00E8E01C9 +:10F480004C7040073C03F4598C0A1203003400030B +:10F49000007DB47F802942100C738001F101380097 +:10F4A00081112213003FE020E8031203003F020312 +:10F4B0000028E202E80312230028020300255CF082 +:10F4C0000190E80F5033006C8C0112030025F10FFE +:10F4D000B4038801B603A059220300088801A819C3 +:10F4E000B4065A080108A4361203002EA4371203EA +:10F4F000002F02030028E202E80312230028F10A89 +:10F50000040400033800050122130029E020E80D5F +:10F5100096031203002944100064FE0C3C17F52DDD +:10F5200040000416120300682203002E2233000854 +:10F530009AC34E340003FEDA2213002F220300097F +:10F540009A084E040003FE02041300208803E22000 +:10F55000E803140300203CAC00DD840010030048E5 +:10F560004EA300300403000FC02C5A000103840393 +:10F570004412CA3038308000C3248801F309F40BE8 +:10F580002010000842F19024FE5CE02FE91AF106F9 +:10F5900020000004FE4AFE02E001E91302030028F5 +:10F5A0005CF00029E905840110030048D50A000336 +:10F5B0000057C00784218E01101300481003005724 +:10F5C000223300085001FF9B96015CF0036FE904B1 +:10F5D00044400037D50344400064840F4EA3000329 +:10F5E000FA0E00130048C9630413000FC16004132E +:10F5F000000C5A10025D041300168E22E622E85712 +:10F6000022130006E001E85352F00437E02FE84FE0 +:10F6100002030028E280E94B040300112213006773 +:10F62000C81E9ACB4E340003FEDA5CF18028E9173D +:10F630000213002540318477E66AE9110213002F96 +:10F6400050F0FFB95CF788DFE80A00030055C829CD +:10F650000003009E5A0801268402D51702130025D4 +:10F66000E624E9048E01E602E8053C03F458E201D1 +:10F67000E81E00030055C8150013009E5A18011219 +:10F68000001300F3E622E80410030054D50A842294 +:10F69000100300CB44000032101300541203006624 +:10F6A000F004F107F28949FFFC83F2092E07E97C97 +:10F6B000F08900030048C0070433000F4E33008375 +:10F6C000480001590403000FC0F804030011C8F5F5 +:10F6D0000403000C5A0002F2040300165A00050548 +:10F6E0008E02E602E8EA2243002F220300099AE094 +:10F6F0004E340003FEDA2E77C56B44500032FF7C97 +:10F700000273002844F003E8FF7C4052BCB7E2A338 +:10F710002213002E23E30008E8D05CF18029E9CD14 +:10F7200080E90053007DB53F85E24272A473049FD7 +:10F73000800138949D112273003F4073BCF6E0E9CC +:10F74000E80AF702E0A7E904F705E0E5E8B65CF1AE +:10F75000812DE9B3F30944F000C8F51040378C76E9 +:10F76000E065E8AB8A3E4E140003FE4AE435E91535 +:10F7700000130055C9120013009E5A18010F84226D +:10F780001013005450127FB996495CF088DFE805E9 +:10F79000880490011203002FF004F107F28949FF59 +:10F7A000FC07F10DF002F20988018420F30DF40545 +:10F7B0009AC3E2834EF3FF82181000011010002359 +:10F7C000D5F6040300165A00030448000111021381 +:10F7D000002502030034E201E97404030010E6028C +:10F7E000E80B020300268C011203002600030074BC +:10F7F0008C0110030074000300485A08010C020336 +:10F8000000268C0112030026000300758C011003F2 +:10F810000075F00F5EF00029E805FE145CF007D1DA +:10F82000E90B020300268C01120300260003007678 +:10F830008C0110030076020300285CF00047E90DFC +:10F840004EA3000C020300268C01120300260003C5 +:10F8500000788C0110030078040300205CF0006540 +:10F86000E90D4EA3000C020300268C0112030026B2 +:10F87000000300798C01100300793C03F45E5CF016 +:10F880000032E8092E27FFF4C2064EA30005844586 +:10F8900014230016042300118E41E6424EF200A804 +:10F8A0004EA300A6C803E622E80A3C13F45AE2017C +:10F8B0004EF2009E2E07FFF44E02009A8405D534C6 +:10F8C0000403001B400004175CF00038E816FE84B7 +:10F8D0005CF10ABFE812F20F8A028C0AE615E80D05 +:10F8E000020300285CF00033E8080203002600232E +:10F8F00000768A02120300260403001C401004361E +:10F90000E42BE90DF01550F07FF5E02FE808020335 +:10F910000026001300748A01120300260203002649 +:10F92000E610E905840214030016D5615A38010770 +:10F9300022030006E41EE9F7D5085A38020722F32D +:10F9400000065EF7841BE8EF00030055C80E0013A5 +:10F95000009E5A18010B8422100300CB4400003291 +:10F960001013005412030066F004F10749FFFB2056 +:10F97000D53E0403000C5A00023B040300168E021D +:10F98000E604E83500030055C80E0013009E5A181F +:10F99000010B8422100300CB4400003210130054EA +:10F9A00012030066840114030016100300550203BD +:10F9B000002F50F07FB95CF787F2E8192213002E70 +:10F9C0005000FFA196015CF0037BE80E2203006764 +:10F9D000E001E8055EF0005FE907D509E020E807EF +:10F9E0005EF003DAE9048402100300CB0403000F85 +:10F9F000C01EF1064402CB1438100400C109F10600 +:10FA00008801F10B20000024E0014EF201EAF1062A +:10FA10004402CACC38100400C154F106880120F019 +:10FA20000024F00BE00F4EF201DCD54BF00C5A0035 +:10FA3000FF49F1064402CB1438000400C00BF00B60 +:10FA4000C80904040005F1128801A741B41F8E0102 +:10FA5000D811F1064402CACC38000400C032B41FE9 +:10FA6000F50B8E01D82E04040005F10A38000600BB +:10FA7000C028840414030016F00B4E0201B7840260 +:10FA8000001F80201403000F1013007D5A0801048A +:10FA9000480001AFB41F8E01F108B45F42008873C3 +:10FAA000F101380081111203003F02030008120324 +:10FAB000002E020300091203002F84001203002805 +:10FAC000040300165A080111B4068E01E602E80C80 +:10FAD0000013008484003C0BF4515A1801061003F3 +:10FAE00000843C0BF453A43612030030A4371203F5 +:10FAF000003144000032480000BC00030018961694 +:10FB00004E0200DE045300165A58010584003C0BD7 +:10FB1000F452009300658400B43F00330064100386 +:10FB2000004E800942018473F101224300293810FC +:10FB300081118403FE0C9461E0208401E8058402B5 +:10FB40001003004E8400022300285CF10047E908FE +:10FB50003C1C00DDC90584031003004E80010273C4 +:10FB600000250413001C5CF1003840109C36E907A6 +:10FB700050F0FFEC5CF78410E80DD5045CF1002E2A +:10FB8000E91C5CF08438E91002F300745CF78046ED +:10FB9000E80B3CA3F4538F415CF50031E9042EF7E8 +:10FBA000FFF4E80284005CF10049E90750F0FFF639 +:10FBB0005CF78424E902840002F300685CF7803279 +:10FBC000E8095EF20096E8069F0D5CF2042FE90258 +:10FBD00084003C43F4535CF20065E90F02F30074C7 +:10FBE0005CF78046E80A5CF10033E90750F0FFFC5F +:10FBF0005CF78430E90284005A58050384008E8241 +:10FC00005CF20030E82C5EF08028E80722F3002E3A +:10FC10005EF78028E90AD5235EF08410E92022F3FC +:10FC2000002E5EF78410E91B4442CA8438420C005F +:10FC3000C4094442CA84888320420024E089E9023E +:10FC400084004442CA3C38420C00C4094442CA847D +:10FC5000886420F18024E12FE90284005CF10051E6 +:10FC6000E90284003C33F45DE267E8068405100392 +:10FC7000004E48FFFA9B5CF1003D0433001BE90B8A +:10FC800040F19DF75CF78038E9068E2A5CF0842508 +:10FC90004EF2FA8C5A58010448FFFA885A000104BF +:10FCA00048FFFA8404130026140300165A100104B6 +:10FCB00048FFFA7C1003005648FFFA78A436120376 +:10FCC0000030A4371203003148FFFA70441000FCE2 +:10FCD000F20442200473B0F18481B168F0034C0156 +:10FCE000003DF003B4008E01E603E832F0030200A9 +:10FCF00000345CF000C8E9039600D503440000C757 +:10FD0000F103041080165A1002045A180507F6036E +:10FD100002630025E206E9035A18041BF0030414E9 +:10FD200000050000001C94028801A642A783E2C1DE +:10FD3000E90FF0030400000F5A0801053800940889 +:10FD4000D5055A08020438408C088C21D5F1F003FF +:10FD5000500000FCF083D5C384004412CD18442227 +:10FD6000CA848068B128F50149FFF7ECF01144120C +:10FD7000CC844422CA3C8068B131F50149FFF7E2E6 +:10FD80003C03F45E3C13F45BE201E8048C013C0BA1 +:10FD9000F45E3C03F453C8063C13F45FC1033C0B10 +:10FDA000F45E3C0BF45FFCDDB41F4492CC848E0106 +:10FDB000F086B01FF0884402CACCF0828401F0853E +:10FDC00048FFF97A0003001100130023E0204EF3EE +:10FDD000F9A1F2088461383100088C01D5F8840457 +:10FDE0001403001648FFFE6E840148FFFE4B84009A +:10FDF00048FFFE54442000FC420088738421141004 +:10FE000000261010009E842014100023DD9EFC4A62 +:10FE1000F08B2E07C53A8141F0812E07C53BF28752 +:10FE2000F08A3C03E2A63C13E2A5F08D3C03F450BB +:10FE30005CF00190E8048C013C0BF4503C03F44F5F +:10FE40005CF00190E8048C013C0BF44F3C03F44E51 +:10FE50005CF00190E8048C013C0BF44E3C03F44D43 +:10FE60005CF00190E8048C013C0BF44D3C03F44C35 +:10FE70005CF00190E8048C013C0BF44C3C03F44B27 +:10FE80005CF00190E8048C013C0BF44B4000840AC8 +:10FE9000F08EF00DF60B9001F0918400F0842E07A7 +:10FEA000C541F104E2204EF204BFB4064E0204B58F +:10FEB0005A080504480004B15A0804044800041D07 +:10FEC0000003001C04150004F08894018801A64179 +:10FED000A600F192F09304030023C809F00804156A +:10FEE000000594028801A602C00FD5035A00011133 +:10FEF000F00A4412CB5C8E01F082F00A8E02F08C84 +:10FF0000841FF086D50B8421F186F18CD504F08610 +:10FF1000F08C8400F0824412CBF0F0089402F09050 +:10FF2000F210040500058802F20AA6C28E41A7431A +:10FF3000CB04DA048103D541DA3FA680A6C1F401DF +:10FF4000F002FF04E262E938B4AA98143802810092 +:10FF50005A00FF1C0455000138528101980AA6017D +:10FF60005A00FF14F708DF119888500000349401FC +:10FF70000031005B880100710037F389009100496E +:10FF8000A503CF05F785D5058C41D5DD9E39F085D4 +:10FF9000F0018E02E209E805F00150807FFFD503F1 +:10FFA0005084800180078029F202F30784A149FF71 +:10FFB000F74BF083D50A85008401148F8005F08308 +:10FFC000812880E8148F8009F001F1029401F30781 +:10FFD00042300473F10CF407844042400473F28C05 +:10FFE000F005E100E90F381181114E170005F50CFD +:10FFF00088A1F58C381201114E17000388418C013D +:020000021000EC +:10000000D5F1F005842740040001FE03422004736B +:10001000F28F4E2600048401F08FF00BF10449FFAB +:10002000F412001300180403002396464E1200CB6E +:100030003C13F45712130056C02384011203004EE0 +:1000400084031403002684001003009EC705F001FA +:100050008E014C9040058C2A12130056000F80240C +:10006000F102F201100300A6F00942008873F107C3 +:100070003800811112030054020F8006D50C441081 +:1000800001901213004E8421141300261013009EB9 +:10009000120300543C33F4543C43F450221300093F +:1000A00012030052E26484001413002C1203005067 +:1000B000100300A2100300B4100300B5100300B633 +:1000C000100300B7E9028401100300AA3C03F44FB7 +:1000D000E2608401E8028400100300AB8401100395 +:1000E00000C43C03F463C82F2E3004375A38012C67 +:1000F0003C0C00DD5A0802135EF08096E82422F3DF +:1001000000085EF78096E81F8486144300262E4779 +:10011000E8E4C41914330023D5145A0801155EF01D +:100120008096E81122F300085EF783A3E90C846649 +:10013000143300262E37E8E4C30614030023840397 +:10014000140300253C03F461C8312E0004375A081B +:10015000012E3C0C00DD5A0802145EF088CBE92623 +:1001600022F300085EF78096E82184261413002607 +:100170002E17E8E4C11B140300238404D5155A0884 +:1001800001165EF088CBE91222F300085EF783A324 +:10019000E90D8406140300262E07E8E4C007840254 +:1001A00014030023840514030025804AF108A015D8 +:1001B00038000600F110100300C8A0158801A60140 +:1001C000D556C023C705F0018E014C9040073C0373 +:1001D000F4578C0A12030056F102F201000300A644 +:1001E00042008873F1073800811122130054E02087 +:1001F000E8031203005402030052F103E201E80590 +:10020000020F8006120300520203004E5CF00190C0 +:10021000E80B8C010413002C1203004E220300098A +:1002200088011403002C3C03F4543C13F450E20105 +:10023000E9048421101300AA3C13F44FE201E904FD +:100240008401100300AB804AF108A01538100600A5 +:10025000000300C888019001100300C8F110A01528 +:100260008801A641000300C9880190013C9C00DD83 +:10027000100300C95074FFFFE6E2E9134400019047 +:100280001203004E0413002684011003009E841DF7 +:10029000FE0E5A08010714030026840014030023ED +:1002A0008400E6E210030048E83204130023C12F63 +:1002B0005A18010884005A98010E843F8402D50A16 +:1002C0005A1802075A980105843F8403D5038421F4 +:1002D00080014422CA3038310000C3198802F31269 +:1002E00020400008FECCFE64E023E911F206F11381 +:1002F00020000004FE54FE14E001E909020300524C +:100300005CF00029E9048401100300480003004860 +:10031000C86304030023C0600403000C5A00025D9C +:100320000213004EE62BE958040300265A0803077F +:1003300004330025E662E823D5035A080221A4F716 +:100340008E705CF1894CE81B023300525CF1804CEA +:10035000E816000300555A08013C0003009EC83807 +:10036000001300F3E622E9328422100300CB44009C +:1003700000321013005412030066D52A8E02E602E2 +:10038000E82BA4378E105CF0094CE8263C03F459A6 +:10039000E201E922040300255A00020A5A00040877 +:1003A0005A9002085A0003195A0005175A98011565 +:1003B000020300525CF0004CE80F000300555A089D +:1003C00001080003009EC804840210030054F00BCF +:1003D000F10449FFFD1100030048C85F0413002326 +:1003E000C15C0403000C5A000259040300265A00A1 +:1003F00006058E02E602E8515A180105000300AA1C +:10040000D5055A18024B000300ABC8472213002E33 +:10041000220300089A084E040003FE022E37C56A24 +:1004200044100032FE5C0233005244F003E8FE5CEC +:100430004010BC37E220E8315CF00029E92E0013BF +:1004400000A6F202F401806142311073F207848247 +:1004500038F10D112233005440319076E06FE809F5 +:10046000F205E022E903E101E8185CF0012DE9154D +:10047000000300555A08010E0003009EC80A84229A +:10048000100300CB440000961013005412030066C2 +:10049000F00BF10449FFFCB0041300230403002611 +:1004A0004E1200E35A000304480000FE0233004EDF +:1004B00002030056E2034EF300AD04330024CB0BDD +:1004C000000300A28C01100300A2000300B58C0100 +:1004D000100300B5F20C840AFE848002F20F400083 +:1004E00008165EF001C3E808F203445057E442F0F6 +:1004F0000824E2AFE80B004300A28C81104300A265 +:10050000004300B78C81104300B7004300485A48AD +:100510000114005300A2E6628CA1105300A2005304 +:1005200000B68CA1105300B6E909021300508C21CB +:1005300012130050D52DE662E82B5A1801155A986F +:10054000010722F30008F10EE02FD5075A98021F89 +:1005500022130008F20EE022E90F22130009E42B17 +:10056000E815D50A5A180213F10D2233000950F08C +:10057000FFF5E06FE90B021300508C2112130050BD +:10058000001300B48C21101300B45A4001D05EF067 +:100590000029E806F203FE845CF107D1E9060203B4 +:1005A00000508C0112030050020300525CF0004C1A +:1005B000E908E6E2E806020300508C01120300504D +:1005C000040300205CF00065E908E6E2E80F02039E +:1005D00000508C01120300505A98020904030025B0 +:1005E0005A0002105A080460D5075A98015D0403A6 +:1005F00000255A0805053C03F460D5055A08035444 +:100600003C03F4623C13F455E2208406E82AD54BFF +:100610000403002C40000C165A180208F10D50F08B +:10062000FFF5E00FE81DD5155A18011B5A98010770 +:1006300022F30008F10EE02FD5075A980212221378 +:100640000008F20EE022E803E41FD502E40BE908FB +:1006500002030050001300B48A0112030050840208 +:1006600014030026D5200413000C5A10021D9E42CC +:10067000E622E9048E05E602E816000300555A0852 +:10068000010E0003009EC80A8422100300CB440020 +:100690000096101300541203006684011403002610 +:1006A0001003009E040300265A08012304030016C9 +:1006B0005A08011FB4068E01E602E81AF01122F36F +:1006C0000009001300C4E00F8400E90A3C0BF45059 +:1006D0005A18010F100300C43C0BF44ED5093C0B13 +:1006E000F44F5A180106100300C43C0BF44C4400AC +:1006F0000032480000830003001896164E02008D59 +:10070000042300265A28010EF01122F30009E00FFD +:100710008400E9043C0BF44DD5063C0BF44BD503A7 +:100720005A2006078400100300AE8421D5058401F9 +:10073000100300AE842000330064F4010003006560 +:1007400042019073F30738F1811122030029846379 +:10075000940140000C16E00FE8058402100300AE7F +:100760008420024300520233004E0403002C5CF24A +:10077000004C40000C16E90F3C4C00DD8E81E682F7 +:10078000E80A50F07FD85CF7891CE908842310132D +:1007900000AE84205EF07FFCE90CF40D8C83E080D9 +:1007A000E908004300A2005300B58A85104300A267 +:1007B0003C43F45CE283E903E662E8058425101318 +:1007C00000AE8420043300205CF18065E9193C3CD4 +:1007D00000DD8E61E662E814003300A6004300C825 +:1007E000E264E905004300C9E283E80A50F07FD8DB +:1007F0005CF7891CE9058406100300AED50D5A206C +:10080000010C5A18010A04030016141300265A0892 +:10081000010410130056F004506300FC8C01F084B6 +:1008200048FFFB3F3C13F450C9063C03F463C0038C +:100830003C1BF4623C03F4623C23F455E240E904BF +:100840008C013C0BF4623C1BF4633C13F44FC9066F +:100850003C03F461C0033C1BF4603C03F460E240E1 +:10086000E9048C013C0BF4603C1BF461FCCA44209D +:1008700000FC42008873041000265A1806243C1C11 +:1008800000DD5A1801100210000950F0FF6A5CF7F1 +:100890008835E91822100008440003A2400004072C +:1008A000DD9E5A1802100210000950F0FF6A5CF732 +:1008B0008835E908220000085EF00096540780FFA2 +:1008C000DD9E8400DD9E442000FC420088733C33A2 +:1008D000F471222000088020E062E90822F000097B +:1008E0003C43F4708402E08FE80C52F18437E04F0F +:1008F000E90E224080093C03F470E004E91484030B +:1009000014008025840114008023DD9EE062E91933 +:100910003C03F4702220800952F0096BE04F8404FC +:10092000E910D508E062E8F552F0096BE08FE909BB +:100930008405140080258402140080238401DD9E38 +:100940008400DD9E442000FC4200887304100023D4 +:10095000C10A5A18010B222000095EF17FFCE90E42 +:10096000E45FE9128422D5105A1802113C23E2A652 +:10097000223000099D13E083E8038420D5058E5FB3 +:10098000E062E902842114100024DD9EFC4184C051 +:10099000F08181215070008C814685022E07C5416F +:1009A000E2C0E85C0013FF8C0403FFDD9646C1291A +:1009B000C028F001802649FFFF88C818F001802672 +:1009C00049FFF2E80403FFE404148005940288015F +:1009D000A642A603C9065A0023098401B607D50614 +:1009E0005A082304B707D502B7472FC7E8E44FC317 +:1009F000002EF001802649FFF2CD15C38000D526D8 +:100A00008E01E603E827F001802649FFFF5E5A00C9 +:100A1000011AF001802649FFFF2C8380C813F001E2 +:100A2000802649FFF2B70423FFE404048005949272 +:100A30008840A612C007A6135CF00023E80315C384 +:100A400080002E07E8E4C802B607F001802649FFBF +:100A5000FF7B8CC1507380FCD5A2FCC1FC204420DC +:100A600000FC420088730470000F80C0CF0584032F +:100A700014030010D52E5A78010E220000085EF0F3 +:100A80007FF3E912E40BE91C5EF000298402E91C03 +:100A9000D51A5A78021C3C03E2A522130008502004 +:100AA000000CE041E8038400D50F50F07FF5E02F03 +:100AB000E9038401D50950F07FD7E02FE9041473CE +:100AC0000010D5048403140300103C0C00DDC003A7 +:100AD0008400D50E5A7801105003001044100064B1 +:100AE000442000C8846349FFF2254003801B14039F +:100AF0000011D50B5A78020A50030010441000640C +:100B0000442000C88464D5F0FCA0FC41F0818381BE +:100B10002E07C53AF10185205060803C80E98109AB +:100B200050A07FFF2E07C541E320E84500137FDC7E +:100B300004037FF19646C113C01204037FF8B90580 +:100B400094028801A640A741C90584014C5540067E +:100B5000D5234C5540228402B606D5218E01E603EA +:100B6000E826B4065A08010D04037FF8B90594027B +:100B70008801A640C911A7414C554012D50D5A080D +:100B8000020F04037FF8B90594028801A640C1044E +:100B9000A7414C5500058CE1B70697F82E07E8E40D +:100BA000C802B606F001802949FFFF5A8D21506323 +:100BB00000FCD5B98007FCC13A6FA6BCEFF880C035 +:100BC00080E2501F8006B400FA40846349FF8648E3 +:100BD000020F8003A470B6073C0DFAA644928F70F2 +:100BE000FA400200001184648A010014800F92010F +:100BF0004000043710138010B406501F800649FFD0 +:100C0000862F020F8003A470A8393C0DFAA63C3D44 +:100C1000FA908481020000118A010014800F920171 +:100C20004000043710138011B406A072A0B6003142 +:100C3000800C49FF8650EC083A6FA684DD9E3A6F1F +:100C4000A8BCEFD880E181445A480404A006D5022C +:100C5000A00500110010509F801C84C04430003259 +:100C60000051000F8083B63FF6818020F682F68324 +:100C7000149F8004844549FFBD62020F800E021458 +:100C80008003AC3802048001AC7AAC3922048002C3 +:100C9000AC3B5AA0040B3C13E6303E67E949E00147 +:100CA000E80484013E07E949EC283A6FA884DD9EF8 +:100CB0003A6FAABCEF5481238460814081013E37A2 +:100CC000E94949FFFF7B8400003480028020B1188D +:100CD000B16144607FFF9680E243E80AB08F38122A +:100CE000010938110109386281098C01D5F50044E8 +:100CF000800344000080F0830405000684C084E182 +:100D000094598E818820B67FF382442232E897205E +:100D100080A7F781F684F685F686F787F688F68948 +:100D2000F68A49FF85FE00348002440FFFE2F08816 +:100D3000FA0E00448003B67FF089501F803A040504 +:100D400000060425001180A7F681F682F683F6845A +:100D5000F685F786F687F68A126F801D49FF85E1D2 +:100D6000004480030034800244000080F0838E81C0 +:100D7000440232E88040B67F501F803A972080A717 +:100D8000F681F682F684F685F686F687F688F68989 +:100D9000F68A127F801D49FF85C400448003003419 +:100DA0008002FA00F0888E81440232E88040B67FEB +:100DB000501F803A972080A7F681F682F683F6844A +:100DC000F685F786F687F689F68A126F801D49FF49 +:100DD00085A800448003840800348002F08704055D +:100DE00000118E818040B67FF382441232E8972052 +:100DF00080A7F781F683F684F685F686F688F6896D +:100E0000F68A49FF858E0044800300348002B04F8B +:100E100084058E818041B67FF088972004050011FB +:100E200080A7F781F682F683F684F685F686F68744 +:100E3000F689F78A49FF85750044800300348002F3 +:100E400044000080B058F0838E81841B8041B67FBF +:100E5000F08997200405001180A7F781F682F684B7 +:100E6000F685F686F687F688F78A49FF855A0034B4 +:100E700080028404F087B021804000448003F38224 +:100E80000415000680A7B6DFF781F683F684F685A1 +:100E9000F686F688F689F68A49FF85430034800293 +:100EA0008411F088440FFC1800448003B67FF08959 +:100EB000501F803A04050006442232E880A7F681DC +:100EC000F682F683F684F685F686F687F68A126F42 +:100ED000801D49FF85263C0DFAA60044800280460D +:100EE0000250000E8E81976B802683C68006806636 +:100EF000E0E4E81CB18F38F31D015CF78012E906CD +:100F00008C618C0196D996018441B19838F31D010A +:100F10005EF78012E908506F00018C2141E3001355 +:100F2000964984418CE197F8D5E43E20041784402B +:100F30003E200419222F8042E450E909022F801E2E +:100F4000E64CE9058C0196018441D5028440B1E16B +:100F500038739111E4F0E90AB18F38731101E6ECAE +:100F6000E9058C418C0196919601027F8030E6EC78 +:100F700084E0E9048C21964984E1B1983843110159 +:100F8000E68CE9088C219649C20B8CE197F9CB04D9 +:100F9000D507C205C30484413E200419C7064FE2A9 +:100FA000000584413E200419E630E803E610E90517 +:100FB00084013E000418D50484003E000418800A11 +:100FC0008028804984608484F58D49FFFE3A22F4AC +:100FD0000002F50D5EF78065E90484013E00041906 +:100FE0002E07E9185A0801072214000344025198F9 +:100FF000AC405EF28065E90484013E07E90D2E07EE +:10100000E90D5A080107E4BEE80484003E07E90D33 +:1010100022F400035EF780DCE80484013E07E9491E +:1010200044007FA6120F801D02040000C83902048C +:101030000001C0362E07E94604350006C81E94811B +:10104000884322FF801DA450964BE02FE806A45051 +:101050003C0BF4E9121F801D8C015A0A88F23C03F4 +:10106000F4E994019858A40896035EF07FC9E81D3E +:1010700084013E07E946D5193C13F4E994498823D5 +:10108000A448964B5EF0FFC9E80B8C019600E60B76 +:101090003E07E946E90A84013E07E934D5068400A3 +:1010A0003E07E9463E07E934ECAC3A6FAA84DD9E80 +:1010B0002E57E90D3A6F9C3C97205A5001062E603E +:1010C00004175A680108E642E9035A2823044440F9 +:1010D000007D383185118803E004E9125A50010679 +:1010E0002E0004175A080110E642E80DFA024211D8 +:1010F00000734402D48438000511E004E80444007D +:101100008000D50284003A6F9C04DD9E3C1C00DE0A +:101110002E07E94EA68EC8162E07C5D45A0801130D +:101120009411AE0AA6098E01FE14844240000816EE +:101130008E01940196033C0BF4CAFE033C0BF4C9E8 +:10114000D50FA609AE8A8E01FE148442400008160F +:101150008E0196033C0BF4CAFE033C0BF4C92E002F +:1011600004195A08010D3C03F4CA94033C0BF4CA59 +:101170003C03F4C994033C0BF4C9D52CC82B2E07AF +:10118000E9125A080128A60A9401AE0A2E07E96856 +:101190005A08010E3C23F4CA8406FE843C2BF4CA90 +:1011A0003C23F4C9FE143C0BF4C9D5142E07E91CEA +:1011B0005A08010D3C03F4CA94013C0BF4CA3C03E9 +:1011C000F4C994013C0BF4C9D5052E07E9695A000E +:1011D00003F3A6093E07E9058C013E07E906DD9EFB +:1011E0003A6FAABC51FFFAAC2E37C5472E47C54807 +:1011F00084C08521F18D83829459442000808E81A2 +:101200008820B67FF382F2839720442232E880A9B7 +:10121000149F8001F684F685F686149F8007F68871 +:10122000F689F68A814049FF837C2E37C5472E47D1 +:10123000C548440000804021A40C448232E8F08379 +:10124000B1D084038E82F08797204001200080A9CE +:10125000B67F149F8001F382F684F685F686F688C1 +:10126000F689F68A8028884749FF835B126F801FC2 +:10127000808880A62E37C54796B3E0438CC197B1CE +:10128000E81A4091040838049001380389092E07B0 +:10129000C5489E414201842498428A03880238024C +:1012A000010138038509F00D892012548000385E51 +:1012B0000909D5E1840184C0120F801FB010B67FE8 +:1012C000F681F682F683F684F685F686F687F6884A +:1012D000F689F68A501F803E80402E47C54884A17B +:1012E00049FF831F2E37C5473C0C00DE84E1B67FE3 +:1012F000F681F682F683F684F685F786F687A602EF +:10130000501F803E8C02F088B010F689F68A80402B +:1013100080A72E47C548126F801F49FF83023C07F4 +:10132000F4C92E37C547F0883C07F4CA44900080C2 +:10133000B67FF681F682149F8003F684F685F786E1 +:10134000F687F089F68A800A501F803E80A72E47D4 +:10135000C548442232E8126F801F49FF82E22E37CF +:10136000C547440232E8B67FF681F682149F8003B7 +:10137000F684F685F686F787F688F689F68A501F92 +:10138000803E804080A72E47C548127F801F49FFBE +:1013900082C82E37C547B0508528B67FF781F382C3 +:1013A000F683F684F685F686149F8007F688F6891C +:1013B000F68A804180A72E47C548440232E849FF9B +:1013C00082B02E37C547F781B67FF682F683F68462 +:1013D000F685F686F687F688F689F78AB010803C9F +:1013E000805C80A72E47C54849FF829B2E37C547A2 +:1013F000B050B67FF781F382F683F684F685F686E1 +:10140000149F8007F688F689F68A800A804180A7B3 +:101410002E47C54849FF8285F10D2E37C547F78114 +:10142000F682F683F684F685F686F687F688F689E0 +:10143000F78AB67FB01080A72E47C548804149FF84 +:10144000827051FF85543A6FAA84DD9E3A6FA4BC26 +:10145000EF9CB1CF804780C0A006F18D49FFFEC24E +:1014600084803C2C00DEF50D81242E37C547E283B5 +:10147000E81238039111A654E020E808A468964BBE +:1014800040108036964BAC68D503129280008C8158 +:101490008CA2D5EC842084A1F182F183F184F185C2 +:1014A000F186F188F189F18AB67FF581F587A0365A +:1014B000F10DA0B52E47C54849FF8233EC643A6F61 +:1014C000A484DD9E3BFFFCBCEFF4B61FF18149FF15 +:1014D000FE1FB41FF101EC0C3BFFFC8448FFFFB87A +:1014E000FC005A0806048401D5045A080706840043 +:1014F0003E07E919D51C5A080D0784003E07E91973 +:101500008421D5075A080E0B84013E07E91984206F +:101510003E17E9573E07E947D50A5A0810048401E7 +:10152000D5045A08110584003E07E918FC804433AD +:10153000F04A444000553C2DFAB4A690CA03AF18B7 +:10154000D5FB3C2C00E910010053C904440FFFA057 +:10155000D503440FFFA1100100512E07E9695A0875 +:101560000305440FFFB1D503440FFFB01001005233 +:10157000443000554423F04A3C0C00E9001000516F +:101580005A10BB04AED0D5F98420101000511010B1 +:101590000052DD9E4413F04A442000553C0C00E903 +:1015A000000000515A08A004AE88D5F9DD9E44130E +:1015B000F04A442000553C0C00E9000000515A0854 +:1015C000A004AE88D5F9FC005A08BB0449FF7D5B36 +:1015D0002E0004295A08A00544024000D5085A08E4 +:1015E000A10544021B90D50344020C60441245102F +:1015F00049FF80CD3C0C00E9441FFFA010100051B2 +:10160000FC803C1C00E910008060DD9E3C0C00E981 +:1016100000000060DD9E3C1C00E9100080613C1D64 +:10162000FA341000803EDD9E3C1C00E90000805032 +:1016300050007FDFE602E904840010008050DD9E48 +:10164000FC003C0C00E9441FFFCC44200055101066 +:1016500000514413F04A3C0C00E9000000515A00CC +:10166000BB04AE88D5F94400007849FF79D48400E2 +:101670003C0FFABDFC8084213E17E9293C1C00E99F +:101680008801002000523C2BF4E30010005340106E +:10169000A00888223C1BF4E3001000543C1BF4E13A +:1016A000000000554000200888013C0BF4E1DD9E5D +:1016B0003C1C00E984003C0BF4DA00208052840AD0 +:1016C000FE143C0BF4D9000080515A08AB07FC0013 +:1016D000840249FFFFD2FC80DD9EFC0080C049FFF0 +:1016E000FF0184015A68030549FFA3B18006501326 +:1016F0007FF3E622E9035A6802163C0DFA98A641E8 +:101700005A10030D842049FF822B49FF7D975A0808 +:1017100002063C0DFA988423AE4184013E00045930 +:101720008402FC804000040E9606DD9EFC003C0C0A +:1017300000E9441FFFAA101000513C0C00E9000012 +:1017400000515A08AA074400007849FF7964D5F689 +:101750005A00DD048401D5028403FC80FC01840A64 +:10176000100F80075A1001065A10020B4800008122 +:101770003C0C00E98420101000514800007F3C3CE4 +:1017800000E9000180528E05E6054EF2006D44F13D +:10179000169C3807800040F03C00DD0F06266A8A60 +:1017A000B60084023E07C6663C1DFA988404844055 +:1017B0004432B39049FFA51D3C07F4E649FFB092BF +:1017C000D53C8400804084C03C1DFA984432B390DC +:1017D0003E67C6663E67E94749FFA50B3C07F4ED47 +:1017E00049FFAC192E07E96944128F704422B37F78 +:1017F000503F80073C4C00E949FFABC23C0C00E97C +:1018000010600052D53A84013E07C66684008040CD +:101810003C1DFA984432B39049FFA4EB3C07E31D0A +:1018200049FFABF9D50A84033E07C6660001805321 +:1018300044128F7049FFAB332E07E96944128F7051 +:101840004422B37F503F80073C4C00E949FFAB98EE +:10185000D51444029072802349FFA8168401100F0A +:101860008007D50B8401100F8007AE50D506840188 +:10187000100F80078402AE10000F80075A080A0D6F +:1018800049FFFF563C1DFAB4100F80078401AE08D3 +:101890003C1DFAA9AE08000F8007FC815A00010820 +:1018A0005A08030BB40158000004D504B441841B4A +:1018B000FE16B601DD9E8402AE10DD9EFC409F0147 +:1018C000E68B4EF2007C800144F117D83847900037 +:1018D00040F23C004A003C00E80C107EB0B6E2BE8C +:1018E000CCDADE008407D56E4473F04A449000558C +:1018F00049FFE6CE80C05A00020510938000D5F95A +:10190000840149FFE6D849FFE6973C0E033249FFC0 +:10191000E69D3C0E033349FFE6AB3E000CD149FF88 +:10192000E6B33E000CD049FFE6A93E000CD284216C +:101930004402D70049FFB8AB800649FFE6BC4463C8 +:10194000F04A4470005549FFE6A3C003AFF0D5FC50 +:1019500049FFE6B1D5183C2C00E9842EAE4184261F +:10196000AE408420101100504423F010AE5084216A +:1019700049FF80F68420840280418461808180A1B7 +:1019800049FF7CBC8401D51E8401AE10D5118401B1 +:10199000AE10840ED5178401AE10840149FFA26AEF +:1019A0008402D5108401AE10840049FFA263840D27 +:1019B000D509FA00D507FA01D5058402AE18D5E39A +:1019C0008406FCC0FC005A000142C0055A000254C3 +:1019D00048000087C915FA043C0BF4774400003C2A +:1019E0003C0BF476840F3C0BF475FA38FA0E3C0B82 +:1019F000F4743E07C97A3E17C97B8401D5245A186E +:101A00000115840F3C0BF47784083C0BF4763C0BF7 +:101A1000F475FA0E3C0BF474FA043E07C97B3E07DA +:101A2000C97A3E17C967D55C5A18025B84083C0B1B +:101A3000F47784053C0BF4763C0BF475FA0E3C0B02 +:101A4000F47484003E07C967D54BC10A5A180107D0 +:101A50003E17E90A3E17E919D5435A1802053E1701 +:101A6000E90AD5065A18033D84003E07E90A3E07F5 +:101A7000E919D536C9083E17E8E43C1BF4713C1B54 +:101A8000F470D5225A18010D440000643E17E8E4B2 +:101A90003C0BF4713C0BF4703E100437D5155A180A +:101AA00002073E17E8E4440000AAD5075A18030DC0 +:101AB0003E17E8E4440000FA3C0BF4713C0BF47070 +:101AC00084013E0004372E0004375A08010A4400FE +:101AD0000E103C13F47949FF7F913C0BE4D2FC805B +:101AE000FC00E605E84344F119F43807800040F0B3 +:101AF0003C00DD0F0620405A6A00B462964F400059 +:101B0000A008441FFCFFFE5EFE47B622B4228400FC +:101B10009228D50DB462964F4000A808441FF3FFE9 +:101B2000FE5EFE47B622B4228401922A964F49FFF8 +:101B3000FF4BD51EB462964F4000B008441FCFFF44 +:101B4000FE5EFE47B622B4228402922CD5F0B40287 +:101B500058004000B60284003E000433D509B42288 +:101B6000440FBFFFFE0EB602D5038402AE18FC8000 +:101B7000FC00FA043C0BF4774400003C44628F7094 +:101B80003C0BF476840F3C0BF475FA38FA0E101304 +:101B90000443100304423C0BF474842284011003B8 +:101BA000042F3E17E8E48400441000AA3E07E90A27 +:101BB0003E07E9193C1BF4713C1BF4703E000437EE +:101BC0003C13F4794400016849FF7F181203023680 +:101BD000FC80FC4080C18420AE40B40280E29211BF +:101BE000960681245A080107B42644020000FE0F1D +:101BF000B606B40792119606C806B426440DFFFF38 +:101C0000FE0EB606B407920196065A080109B406FC +:101C100058000002B606800649FFBBABB40792012C +:101C20009606C80CB426841DFE0EB60649FFE1E7F1 +:101C30003E000431800649FFBB9CB40796065A0853 +:101C40000106B40658000001B606B4079606C8059A +:101C5000B426841EFE0EB606B407920296065A08F3 +:101C60000106B40658000004B606B40792029606B0 +:101C7000C805B426841BFE0EB606B407920396066A +:101C80005A080106B40658000008B606B4079203C5 +:101C90009606C805B4268417FE0EB606B40792044D +:101CA00096065A080106B40658000010B606B40796 +:101CB00092049606C806B426440FFFEFFE0EB60641 +:101CC000B40792059606C806B426440FFFDFFE0E41 +:101CD000B606B407920596065A080106B4065800DF +:101CE0000020B606B40792069606C808B426440F2C +:101CF000FFBFFE0EB60649FFFF3DB40792069606EB +:101D00005A080106B40658000040B60600048000D8 +:101D100092075A08011600048000963710048000CC +:101D2000B42784009228964F49FFFE4EB407B4466C +:101D300054100300440FFCFFFE16FE0FB60600040D +:101D4000800196065A08011600148001541080FE86 +:101D500010148001B427922A964F49FFFE35B4072C +:101D6000B44654100C00440FF3FFFE16FE0FB606E7 +:101D700000048001920196065A08011700048001B0 +:101D8000540000FD10048001B4278402922C964F69 +:101D900049FFFE1AB407B44654103000440FCFFF79 +:101DA000FE16FE0FB606B407920E96065A080109F3 +:101DB000B40658004000B60684003E000433B40761 +:101DC000920E9606C806B426440FBFFFFE0EB60656 +:101DD000FCC05A000B135A000C1A5A080A21FC00C6 +:101DE000B441440FFFBFFE16B601B40158000020F5 +:101DF000B60149FFFEBFFC80B40158000040B601A7 +:101E0000B441440FFFDFFE16D508B401580000406E +:101E1000B601B40158000020B601DD9E8402AE1068 +:101E2000DD9E0000FC42A7493C6C00E95A580411B1 +:101E30002E07E9795A00010D00030050540000F00C +:101E40005A001007440000553E07E971D51F0003F2 +:101E50000050F4818123B65F80E1C0035A08FB1A69 +:101E60002E000429C00784003E000429840049FF95 +:101E70007973B41F4412B36B49FF7BB9440000551A +:101E80003E07E97184003E07E95F84014800021CB7 +:101E90005A50010949FF79D25A080205840149FFC5 +:101EA000B891B41F4412B36B49FF7B6D84003E07A9 +:101EB000E9743C0C00E9006000500080005184018E +:101EC000100F800F84003C0FFAC6A67940A31009BA +:101ED000979F5A1804212E17E9215A1801063C0F22 +:101EE000FAD549FFAD9F840149FFB85B8420800784 +:101EF00049FF7E36840149FF9EA34403F04A441003 +:101F00000055AE4049FF9E82C0FE4402D40449FF02 +:101F10007A7CD527A6785A10010A4403F04A441067 +:101F20000055AE403C0DFAB4D5103C0FFAD5440331 +:101F3000F04A44100055AE403C0DFAD5C8EF49FFB9 +:101F4000797D5A0002FBD5EAA640C1FFA6005A00DF +:101F500002093C0DFAA9A6405A1802048420AE409A +:101F60008F41E74B4EF2018C44F11E7838A7A9014E +:101F700040F53C004A003C0016005A00680186010A +:101F8000B602C402D602040304030403E6024402B8 +:101F9000B3414412B3E449FF7B39B41F4412B36B1D +:101FA00049FF7AF180068028804749FFB16F84009D +:101FB000100F800F5A600F04480001393C0C00E9F3 +:101FC00084CC000000505A00FB0448000162480025 +:101FD000012E8EC18401E6C63E07E9744EF2007DF3 +:101FE00044F11EF03867980040F33C004A003C0082 +:101FF000062442B2BE4C8400100F800F84013E07BD +:10200000E95F2E07E9194E03013F841F3C0E010FC3 +:102010004800013A8400100F800F84013E07E95FF9 +:102020002E07E9194E030132841F3C0E010F4800B0 +:10203000012D3E07E95F84C24800012B8400100F88 +:10204000800F84013E07E95F3C0C00E9001000525C +:102050005A18AA2000100053440FFFA0FE0F3E00A4 +:10206000042949FF7810840149FF78763C0C00E987 +:10207000000000525A08AA0544004510D503440048 +:10208000479849FF77FC3C0C00E98420101000526F +:102090002E07E9194E0300FC841F3C0E010F480077 +:1020A00000F74400006949FF7847480000C03C1C25 +:1020B00000E98400100F800F84013E07E95F0000F3 +:1020C0008055001080544000200888013C0BF4D853 +:1020D000FAC2480000DE84003E07E974480000D0E0 +:1020E00084023E07E8FD80268401502F800F49FFBF +:1020F000FB3780C084053E07E8FD480000CA840025 +:102100002E17E911100F800F84013E07E9745A1849 +:10211000010584C9480000BD3E07E9113E07E8FDFE +:102120009E31E60CE87144F120343807800040F01D +:102130003C00DD0F0CD24AD24AD294D2BAD21C143F +:1021400084013E07E95ED56384013E07E944D55F1B +:10215000840184C03E07E97F3E67E91949FFFAAA76 +:102160003C1DFA9B3E60044CB40158000010B601BF +:102170003C0DFAB6580000103C0FFAB6D5483C0C9E +:1021800000E98026502F800F0000005149FFDDCD6F +:10219000000F800F5A00023C3C2C00E90001005562 +:1021A00000310054400020080011005288034431DF +:1021B0000000FEC70001005180463E17E9363C3F53 +:1021C000FAA849FFDDC6D5233C0C00E98427502F2F +:1021D000800F0000005149FFDDA8000F800F5A005A +:1021E000021784013E07E95449FFFA64D5103C1CEC +:1021F00000E98401100F800F001080523E07E97340 +:102200003E17E95DD5048402100F800F000F800F88 +:102210005A00020448FFFF7F3C1C00E984003E078F +:10222000E9743E07E9111000805184C1D531800660 +:102230008029502F800F49FFFB33D518FD0344221E +:10224000B3AC503F800F49FFFB3B9780D521800600 +:1022500080288049503F800F49FFFC44D507800605 +:102260008029502F800F49FFFDB6000F800F5A00C4 +:1022700002DEF101B40984CBB601D50A8402100F45 +:10228000800FD5D484C4D50484C5D502FAC9000F03 +:10229000800F84205A0001055A080207843B3C0C39 +:1022A00000E9101000502E07E974C80C4402B34135 +:1022B0004412B3E449FF79AAB41F4412B36B49FF37 +:1022C00079968006FCC292005A08073CE625E8652C +:1022D00044F121E03817840040F0BC004A003C0083 +:1022E000061E3A505800A660440FFF80FE0FAE2035 +:1022F000968F40012008441FFCFFB443D50BA62154 +:10230000968F58000001AE21441FF3FF40012808BA +:10231000B443FE8EFE87B643DD9EA621968F5800FD +:102320000002AE21441FCFFF40013008B443D5F274 +:10233000B40358004000D52FB423440FBFFFD52A63 +:102340005A080B1D5A100B0B5A100C115A180A265A +:10235000B423440FFFBFFE0ED50CB4035800004059 +:10236000B603B423440FFFDFD515B4035800004073 +:10237000B603B40358000020D50E5A0805135A10AE +:1023800001085A18030BB40358000004D504B42301 +:10239000841BFE0EB603DD9E44022D50843BAE40EE +:1023A000DD9E9200FC42814144122D50F081F28268 +:1023B000F383A608A78844122D519204A7C8979FBB +:1023C00097F85A0801249E31E602E90F5A60030487 +:1023D0005A6805403C0C00E9000000605A00A10664 +:1023E0002E0004505A0001364402B3414412B3E4B3 +:1023F00049FF790C4402B3644412B36B49FF78C3BC +:10240000FD03F20149FFAF42D5245A000B065410D8 +:10241000000D5A18051F2E27E9619E54E622E80494 +:102420003E200427D50484203E10042744922D50DA +:1024300084201014800080478026F302F40349FFB3 +:10244000FF45000480005A00FB05840110050000D0 +:10245000FCC244522DA0443DD2604422E1744402A7 +:102460002DDC986B381104011A128001D8FBDD9E17 +:102470003C0E00ED84003E07E908DD9EFC203C3C5C +:1024800000ED8400444000FC84A24462CFC084E19B +:1024900000218009E202E80A8041422010731051B5 +:1024A00000DE387300088C01D5F4FCA0FC003C3C35 +:1024B00002784402D79C8440FA824452CFC0041070 +:1024C00000168E22E622E910041000268E22E62253 +:1024D000E90B001000DE5A18010538128800C1040B +:1024E000B4205A18030D0060006600100067421304 +:1024F000107394498823A448121000738C41500033 +:1025000000FC5A280ADEFC80FC203C6C00FD84E1C3 +:10251000A772A7B3C20284FFC9089E69FF44425153 +:102520000473B6A388A7D50B9E71FE8C8020421140 +:102530001473884742011473B62380A0B6A4FCA08C +:10254000FC4484C0810583808141F282F38180E470 +:1025500080A38126E2E5E9148005F110F202B0C4FF +:10256000B105F58349FFFFD2F004F503380E0111E0 +:102570008CA18920F005380E011188C0D5ECF0013E +:1025800080468AE0FFFB8405422380734E260003C9 +:1025900084418029800A49FFC82D001400005A1088 +:1025A000FF058C218801920110040000B046B0871D +:1025B00049FFC88BF00638150111F00738250111C5 +:1025C0008402400080164204887340000416FCC454 +:1025D000FC4780E13C1C00FDF2845060002000209C +:1025E000803200808002F287002080338400F288ED +:1025F00020208039F085F2892020803AA64BF28A8B +:1026000080018E01F183F086200F800C44A2CDF072 +:10261000F08D3C0C00FDF10500000009E2204EF2B7 +:10262000010E04037FF84E0200F78E04E6024EF31B +:1026300000F3A0345A080204480000EE04937FFF20 +:1026400040048808F08BF10BA03D8801A6C0CB297F +:10265000A642E622E9029EC9A703F0038E02E080AB +:10266000E8038C81D502F4068440B65F3C1C00FE72 +:10267000F00480A649FFFF66A07EF2073810A6028C +:102680008A20FE5404238008382126028802400054 +:102690008016F109880122137FF29603E001D536F6 +:1026A000A74150147FFFD939A6C240140010E6623A +:1026B000F18CE9038E61D5028460A703F0038E02DA +:1026C000E080E8038C81D502F4063C1C00FE840007 +:1026D000B61F501080A28441F00480A649FFFF324B +:1026E000A07EF20C3810A60242110073F207FE54CD +:1026F0000423800838212602880240008016F10950 +:10270000880122137FF29603E0204000BC1A1203D6 +:102710007FF812037FF4D507841FAE3002037FF2E7 +:1027200012037FF8A03DF10B8801A6C2CB2DA64075 +:10273000E622E9029EC9A70150047FFEE080E8037B +:102740008C81D50350447FFF3C1C00FE8401B61FE2 +:10275000501081448440F0049D7149FFFEF3A07F36 +:10276000F2083810A6028A20FE540423800838217B +:102770002602880240008016F10A880122137FF3A6 +:102780009603E001D532A743F106D936A6C0E6622A +:10279000E9038E61D5028460A70150047FFEE080CA +:1027A000E8038C81D50350447FFF3C1C00FE84412C +:1027B000B65F501081E69972F00449FFFEC3A07F16 +:1027C000F20D3810A60242110073F208FE540423E1 +:1027D000800838212602880240008016F10A88010C +:1027E00022137FF39603E0204000BC1A12037FF906 +:1027F00012037FF5D507841FAE3102037FF3120366 +:102800007FF922037FF81205000022037FF91205E9 +:102810000001D50C2205000012037FF822050001FB +:1028200012037FF9841FAE30AE31F0058D448C0168 +:10283000F085506300FC48FFFEEEFCC7FC48F08DBD +:10284000FA04120F801DFA02120F801E8400120F6C +:10285000801F2E000431F18C8122C007840A120FE0 +:10286000801D8408120F801E3C0DFA9BB400920E4E +:1028700096065A080108840A120F801D8408120F58 +:10288000801E2E07E97CC80B020F801D8C03120FDF +:10289000801D020F801E8C03120F801E844180A2B7 +:1028A000F00C44126B308460848249FF7869844163 +:1028B00080628029848280A2F00C49FF78618420A4 +:1028C00044213598443D94D044426B302E07C53A9C +:1028D000E220E816980A9401994388A980C1A56866 +:1028E0008C21AD402E07C53B2E57C53A8E01426262 +:1028F0008073943199448809A400AC28D5E8440237 +:102900006B30802084428461848384A049FF7838BE +:10291000802944026B3084428461848384A049FF0F +:10292000782F2E37C53A84C084E144026B30B67FDD +:10293000501F803A804080A72E47C53BF681F68223 +:10294000F683F684F685F786F787F688F689F68AA1 +:1029500049FFAF692E37C53A8009B67FB04F80492D +:1029600080A72E47C53BF681F682F683F684F6856E +:10297000F786F787F688F689F68A49FFAF542E372F +:10298000C53A8542B67FF38214AF8006800980493C +:1029900080A72E47C53BF781F683F684F685F68738 +:1029A000F688F689F68A44126B3049FFAF3C2E3721 +:1029B000C53A8009B67FB04E804980A72E47C53BF7 +:1029C000F681F682F683F684F685F786F687F68832 +:1029D000F689F68A12AF801C49FFAF252E37C53A1B +:1029E000B00EF382802980A62E47C53BB6DFF78163 +:1029F000F683F684F685F786F787F688F689F78AF0 +:102A000044226B30127F801C49FFAF0D2E37C53A30 +:102A1000854844126B30B67FF382F00C804180A76A +:102A20002E47C53BF781F683F684F685F68614AF0C +:102A30008007F688F689F68A49FFAEF52E37C53A43 +:102A4000501F803E44007FFFB67FF088804180A702 +:102A50002E47C53BF681F682F683F684F685F68628 +:102A6000F687F789F78A44026B3049FFAEDC2E37D0 +:102A7000C53AF00D80292E47C53BB67FF781F3821A +:102A8000F683F684F685F68614AF8007F688F68915 +:102A9000F78A804980A749FFAEC6020F801F441005 +:102AA000277340008006FCC8FC2049FF75D049FF11 +:102AB000CD5F5A00080B49FFCD852E07E8FEC803FD +:102AC00049FFCB4649FFCD9E4473F04BA6384413D3 +:102AD000F04B5A00FF05841FAE08D5FF49FFD0FA1E +:102AE0005A0003EB5A0002F05A0013F249FFD64C89 +:102AF0005A0002EA5A0013EC3C0DFAA9A78097B0DD +:102B0000CEE649FF77873E60045C49FFCDB92E07CA +:102B1000E9615A08120E3C03F4D8802649FFF604F6 +:102B20005A08010780062E10045C49FFF5022E07A3 +:102B3000E9615A0004125A08190449FFF53A49FF9D +:102B4000CDFE49FFD2245A0002BF2E07E9615A0880 +:102B5000050A49FFCED9440000FF2E10045C49FF4E +:102B6000F4E83C0DFAA98421AE4084003C0FFAD56C +:102B700049FFCEA5D5AC0000425088244010400942 +:102B800042500C73960140314009969142F00C245A +:102B900042400824FE8C40078800E20240F7C0084B +:102BA0004020400842F08C7340104009882F982242 +:102BB000E204882F984DDD9E8060C207994A084044 +:102BC000800118418001D9FCDD9E92008060995AF5 +:102BD000D30418118001D5FDDD9E9200EDEEEFFFCC +:102BE0000001111213000000FFFFFFFF08FFFFFFAD +:102BF000FF000000000000010001000000000100D3 +:102C000000000000010000000001000000010000C1 +:102C100001000000010000000000000000010001B0 +:102C200000000100010000000000000100000000A1 +:102C30000000010000000100000000010000000091 +:102C40000001010000000100000000010000000080 +:102C50000100000000010000000101000000000070 +:102C60000100000000010000000100000000000061 +:102C70000100010000000000000001000001000050 +:102C80000001000004050607020202030303040416 +:102C9000000000000C0C005550710200D8730200B7 +:102CA00060760200E8780200600C0200A0200200BA +:102CB00000400200604C0200701102008016020009 +:102CC000E0510200F0560200676767676767676751 +:102CD000676767676767676767670000646464645E +:102CE000646464646464646464646464646400006C +:102CF0000B0B0B0B0B0B0C0C0A0B0C0C0A0A0A0A25 +:102D00000A0A00003C2C2F3133350000083C00003B +:102D10000306080A0D100000100D0A080603000043 +:102D20003C0800003533312F2C3C000040636464C4 +:102D3000646464644F4F646464646464634000006A +:102D400062646464646464645A5A64646464646459 +:102D500064620000636464646464646464646464FE +:102D600064646464646300003F6464646464646411 +:102D70006464646464646464643F0000402B020023 +:102D8000D02B0200B03E0200403F0200202A020089 +:102D9000B02A0200903D0200203E02005071020065 +:102DA000D873020060760200E87802007011020019 +:102DB00080160200E0510200F0560200F000F00020 +:102DC000B4009000600C0200A0200200004002004D +:102DD000604C0200600C0200A020020000400200D3 +:102DE000604C02007011020080160200E0510200E7 +:102DF000F0560200A4C04422D0204412000094DA0D +:102E00008861B662A4C25041002094DA8861A8D2D9 +:102E1000A4C494DA8861A8D1A4C694DA8861B6649F +:102E20000230000894DA8861A8E1A4C494DA8861C9 +:102E3000A8E50200000894028820A866DD9EB44040 +:102E400084A08C449C2EA2D196005A58200680A0C3 +:102E50005A0824FADD9E5441801F384094088CA102 +:102E600097689265D8F3D5F4FC20B46084008C7C1C +:102E70009583A31997B08440995697688C415472F2 +:102E8000000F96903870940892845A2808F78C01A5 +:102E900096005A0804EFFCA0FC20B4608400503176 +:102EA000802C9583A31997B08440995697688C41DC +:102EB0005472000F96903870940892845A2808F73C +:102EC0008C0196005A0804EFFCA0FC003C0C017A2F +:102ED00084233C0FFAA54403F40B8440AE40440322 +:102EE000F4048426AE404413F4078401AE0844136E +:102EF000F408AE084413F01EAE884413F420AE0864 +:102F00002E07C5D45A0801063C0C017A490000314D +:102F10004402D0204412D22849FFFF934402D0201B +:102F20004412D71849FFFFA24402D0244412D520EE +:102F300049FFFF9C4412D5E44402D02049FFFFAE74 +:102F40004900004F44028F7049FF9F4AFC804410A3 +:102F500000963C1BF4C54412C8C884003E07E969CA +:102F60003E07E951AE08AE09AE0AAE0BDD9EFC008D +:102F70000400001244120054921054007FFF940287 +:102F8000880144128F700020812810200018002032 +:102F9000812910200019002081261020001B00101C +:102FA00081271010001AA08546110000FE57A84581 +:102FB000A08546120000FE57A845A08546180000CF +:102FC000FE57A845A08546140000FE57A8454402B8 +:102FD000283849000050FC803C0FFFA6DD9E3C2CA9 +:102FE000017A441200A804010012921054007FFFDD +:102FF0009402880144120000B400920A96373E07FA +:10300000E94104010012921054007FFF94028801EC +:10301000B42000000020922A96773E17E9263E074A +:10302000E948DD9E440251703C0FFA7D4403F142B1 +:10303000441028B8AC40441251888400B6013C1DAD +:10304000FA7DA80F3C1DFA7D14008008DD9EFC006F +:103050004413F381A608540000F0AE084413F3842F +:103060008400AE084413F56BAE0849FFAC98FC80B1 +:10307000DD9E441E0000880192024413F3CA9601AB +:10308000AC08DD9E4423F054AC104403F056AC4031 +:10309000DD9EDD9E96069404965FFE474403F04352 +:1030A000AE40DD9E4413F044AC08DD9E4423F05056 +:1030B0009617A650541080F8FE47AE50DD9E44236C +:1030C000F0509617A65094045410808FFE47AE50CF +:1030D000DD9EFC00840749FFFFEB4403F04C842095 +:1030E000AE40840749FFFFED4403F04E8421AE401B +:1030F00049FFB019FC803C0FFFA7DD9E3C0FFA870B +:10310000DD9E3C0FFA7CDD9E3C0FFA89DD9E3C0F74 +:10311000FFACDD9E3C0FFFABDD9E3C0FFFAADD9EAA +:103120003C0FFFB7DD9E3C0FFA8BDD9E3C0FFA8A09 +:10313000DD9EFC003C0FFFF44900000F3C0FFA8DB0 +:103140004900000B3C1DFFF4A68AA64B4201047304 +:103150003C0FFA8CFC8044026620DD9E3BFFFCBCE9 +:10316000EFFC8401842049FFFF97EC0444000CD558 +:103170003BFFFC8448FFFF984423F01FA610541027 +:1031800000E04403F302A6C0A6009627880196003B +:10319000AE10DD9E3BFFFCBC8400EFFC802049FFAD +:1031A000FF7349FF6F5E49FFFE9249FFFFD949FF58 +:1031B000FFE549FF74BB49FFFF3749FFFF8C49FF1B +:1031C000FF5949FFFF46EC043BFFFC8448FF69CAF6 +:1031D0003C0DFAAC3A6FA8BC80C15A08040D2E070A +:1031E000C5D3C009840249FFF2183C0DFAAC5A0855 +:1031F0000424D51149FF70225A0002F6840149FFC8 +:10320000F20C8420846184028041808180A349FF84 +:103210007075D5F149FF70125A00020F2E77C5D391 +:103220005A78010B800749FFAD69840049FF950872 +:10323000800749FF6F934473F04A449000553C0D5A +:10324000FAD1C009840449FFF1E83C0DFAAC5A08F0 +:103250000427D50B49FFAD565A0801F6840349FFF0 +:10326000F1DC10938000D5EC49FF6FE85A0002189A +:103270002E07C5D35A08011449FF71374403F429B6 +:10328000441FFFC3AE40840049FFA4EA3C0DFA98F6 +:10329000842049FF74658402AE31D56549FF6FCE45 +:1032A0005A0802328420846180418083FA1049FFE9 +:1032B000DA078441541000DF80628082FA1049FFEF +:1032C000D9FF8420846180418083440046E049FF27 +:1032D000D9F78420846180E080414400CFF080836E +:1032E00049FFD9EE5A78070BC80584033E07E96DFC +:1032F000D50A84043E07E96DD506CF05C8048401CC +:103300003E07E96D80468405842049FFA7BF8420DD +:103310003C0DFA9849FF74248402AE31840149FFC0 +:10332000AE51840549FFF17949FF6F884463F06429 +:103330005A08020AA630540000FEAE3049FF6F7EE4 +:103340005A080112A63058000001AE303C0DFA9820 +:10335000A6008E02E602E907440000553A6FA884F1 +:1033600048FF6EEA3A6FA884DD9E3C0FFA8FDD9E1F +:103370003C0FFFFBDD9E3C0DFA8FA4413C1BFFEF91 +:10338000A444A6003C1BFFEE3E07FFDADD9E3A6F29 +:10339000AABCEFFC2E57C53A2E27C56A2E47C53B5F +:1033A0009629421008243C1BE2A596E12E17C56B16 +:1033B000FE1C3C0BE2B64261842444022D859241FE +:1033C00092213E27C5713E57C5473C6BE2A63E178A +:1033D000C5723E47C548A6408421AE40A641842020 +:1033E000AE4144522D9C443DD9D044228F704402BA +:1033F0002DA4986B3811041018128001D8FB84C0DA +:1034000044027B903C6FFA9E49FFFCF63C0C017A2B +:1034100044122CFE3C0FFAAB44222CFC44022D5CDF +:10342000B6C0AD90AD883C1FFAA444122CF83C1FE6 +:10343000FAB444122CF93C1FFAA944122CFA3C1F8E +:10344000FA982E17C5DB3C0FFA9B3C2FFAA23E6779 +:10345000E9475A180107B42058108002B620D50554 +:10346000B440843DFE56B62044122D5C440FBFFF8D +:10347000B4418521FE16B601B401847B40002404CA +:10348000B601B4018457FE1EB601B40184C0FE1615 +:10349000B601B401854058000010B601B481440F54 +:1034A000FFBFFE26B601B40184E058000020B6013B +:1034B000B40158000C00B601B481440FCFFFFE26C2 +:1034C00058002000B601B40144122CFE3C0FFAB69D +:1034D000A508841DFE26AC08A508841EFE26AC089F +:1034E000A408FEC6ACC8A408FE86AC88A448440262 +:1034F0002CFCAC403E67E9753E67E9653E600437E9 +:103500003C9E010E2E07C5E03CABF4DC3E07E92CE7 +:10351000440FFFAA3E07E933440000553E07E9384F +:103520003E07E92E3E07E9713EA7E9803E67E97054 +:103530003E67E93A3E6004593E67E9093CABF4D680 +:103540003CABF4DE3E97E9613E97E91A4900024B35 +:103550003C0DFA983E67E8FE3CABF4D83E67E8FFC6 +:10356000AF813E67E9193E97E9573E67E918AF809A +:103570003C1DFAB484023E67E90B3C9E01B53E67F0 +:10358000E93E3E60044C3E60044D3E67E921AE08D2 +:103590003C1DFAA9AE0884043E07E96D4402D0A898 +:1035A0003C0E01CB4402D1943C0E01CC4402D368C2 +:1035B0003C0E01CD4402D6703C0E01CE44000032D8 +:1035C0003C0804E03E67E9223C7FFAA53E67E953E8 +:1035D0003E97E94D3E60044F3C7BF4EC3CABF4E499 +:1035E0003E67E9173C0804E44402D64C3C0E0271E5 +:1035F0004402D5D83C0FFAB0840A3E07EAA82E0749 +:10360000C53B3E67EABC3E07C66D44028F703E670D +:10361000EAA93E67EAAA3E6004193C7FFAB93C7FFA +:10362000FAB53C7FFAAE3C7FFAA03C7FFAB23C7F11 +:10363000FA9F3C7FFABB3C7FFAB33C7FFA943C7F15 +:10364000FA99490001E9800749FF749E800949FF02 +:10365000749B800749FF74A63C0E01E9800949FF6D +:1036600074A13C0E01EA840249FF749C3C0E01EBFC +:10367000840349FF74973C0E01EC840449FF749263 +:103680003C0E01ED840549FF748D3C0E01EE84066D +:1036900049FF74883C0E01EF840749FF74833C0E98 +:1036A00001F0840849FF747E3C0E01F13C03E2A561 +:1036B0003C13E3B23C0BE3B03C03E2A63C7E0112B8 +:1036C0003C0BE4193C03E3B33E67E93F4000240CA4 +:1036D00088013C0BE3B43C03E41C3C13E41B4000B6 +:1036E000240C88013E67E9353C0BE41D3E60044430 +:1036F00049FF818B3C0FFAB749FF815F4402D79C99 +:103700003C0E02C34402B5143E67EAE13E67EAE0BC +:103710003E67EAE23E600B083C7E02C43C0FFABA08 +:10372000845F3C0DFAB7843F38201C088CE65A7839 +:103730003CFA3C0DFAB784C03C6E010F1010003CFF +:103740001010003D2E07C5433C6E01103E07E95D99 +:103750003E6004533E6004513E6004543E60045594 +:103760003E67EA5C3E67EA5E3E67EA5D3E67E9798E +:103770003E67E9353E67E95B3E67E94A3E67E95ED9 +:103780003E67E9113E67E9443E67E9773E67E954E1 +:103790003E67E91D3E67E9733E67E97F3E67E97E64 +:1037A0003E67E93D3E60045849FFBE754400006431 +:1037B0003C08054C4400005A3C08054E4400009665 +:1037C0003C08054F3C080554FA183C08055584058B +:1037D000FA293C08055744027B703E67E9453C6B7B +:1037E000F4EB3E6004603E6004563E600A953E6025 +:1037F0000A963C68054D3C6805503C6805513C689C +:1038000005533C1805523C6805563C6805583E6710 +:10381000E9273E67E9493E67E92A3E67E96F49FFC4 +:1038200092652E07C5D45A08010449FFFB92840112 +:103830003E0004503E07E94E4402D40449FF6DC5E2 +:1038400049FF6DC184003E07E9583E07E90C3E0779 +:10385000E9123E07E93B3E07E91C3E07E9683E07DF +:10386000E9633E07E9253E07E92D3E07E976840A2C +:103870004410007F3E07E913840F3E17E9663E07B8 +:10388000E97DEC043A6FAA84DD9E3A6F9CBC4462E9 +:103890009028EFF4800649FFFC3050037F48F08108 +:1038A000490000959C344900009550030078490078 +:1038B0000097500300A849000090500300CC49FF36 +:1038C000735D50037F48F08149FF735B500300B084 +:1038D00049FFFC2B50037F48F08149FFFC2950032E +:1038E0007F48F08149FFFC125003011849FFFD3F5A +:1038F00050037F48F08149FFFD3D49FFFD3E5003E5 +:10390000012C49FFFC06507303A850037F48F08147 +:1039100049FFFC02800749FFFC0250037F48F08109 +:1039200049FF8E9B5003017049FF8E94500303188A +:1039300049FF771D50037F48F08149FF771B5003F3 +:10394000036449FF755850037F48F08149FF75565D +:103950005003037449FF839050037F48F08149FF6F +:10396000838E800749FF802350037F48F08149FF01 +:103970008021500303B449FFFBC650037F48F08108 +:1039800049FFFBBE3C0DFA9B49FFACF3500303D843 +:103990004900003C50037F48F0814900003A500341 +:1039A000004849FFFB1B50037F48F08149FFFBC3E0 +:1039B00050037F48F08149FFFBB550037F48F081F9 +:1039C000EC0C3A6F9C8448FFF5553C0FFA92DD9E53 +:1039D0003C0FFA90DD9E3C0FFA91DD9E3C0E00DE1E +:1039E000DD9EFC0049FF6CBB84203C0E00E91010FA +:1039F0000050101000511010005210100053101001 +:103A0000006010100061FC803C0E00FEDD9E3C0E4C +:103A100000FDDD9E3C0E00FFDD9EFC40049F800A01 +:103A20005A90010B4462D4EC4472D17438630400A0 +:103A300038738400D50384E284CA8380FB48B910BC +:103A40005410FFFF944A4213287344A20000882AAE +:103A5000BE120080800792D010818000A6CE5463F1 +:103A60007FFFAEE0A6CCAEE80230002B024080091A +:103A70000200002B0210800888648801940194D908 +:103A8000886AF4088940F009B664B7402E07E969EE +:103A9000C0035A98010E44100054943242038473B8 +:103AA000441200008801B400920A9637D5032E0014 +:103AB0000D28AE10FCC0FC00838044600030BD12B5 +:103AC000B8125452FFFF54007FFF956A94024202DD +:103AD0001873425198734442000044620030888059 +:103AE00088C08AA0383290028C26540183FF1200CD +:103AF000FFFD4001A8099274543183FF1230FFFF8B +:103B0000540003FFA2E11200FFFE540183FFAC103A +:103B10004001A8099274540003FF543183FFAC1193 +:103B2000ACD28C464C437FE0FC80FC40045000113A +:103B30005452FFFFC91B8380443200F0B910B81102 +:103B40005410FFFF944A882354007FFFA64C9648E8 +:103B5000C22494024430004842008C734452000056 +:103B60004412004888A08801D515956A4462000077 +:103B700088C544700048E264E8DF80A642519C7327 +:103B800050928048181280014C54FFFE8C6196D8E8 +:103B9000D5F318228001D8FEFCC004000011444077 +:103BA000004854007FFF9402420190734452000089 +:103BB00088A0840098C8A6D94041E0083830800029 +:103BC0004031C00888649910A721404220088864C9 +:103BD000384100008C028864AAE95A0824EDDD9E71 +:103BE000040000114440004854007FFF9402420149 +:103BF000907380604402000088608400A5193840FA +:103C00008008A75B9908AF61B483995038410008D8 +:103C1000A31992888C02AF295A0824F2DD9EE20192 +:103C2000E808A610E260E8039AC3D50B8400D50C1F +:103C3000E220E80BA61052F180FFE00FE804886054 +:103C4000AED0DD9E841FAE10DD9EFC40EEE85A38FB +:103C500001073CA0028544400120D5092E500D12D9 +:103C60004C5000B93CA0028444400C602E57E8FB45 +:103C7000F486E6A28481E9058EA14042140C9720C7 +:103C80004042040E9720F485CC038481F485F188AA +:103C90008020B00EB61FB00F505F8035F389F284DC +:103CA000F081F3828002503F8036B08D504F8037D4 +:103CB00049FFFEB5F004B062B0B4003F8036004F5B +:103CC000803749FFFEFAF004B050B099003F8035CC +:103CD00049FFFF88B0228120B1D08500B00E384066 +:103CE0002202F0095A08010551C20090D50351C2C1 +:103CF0001B90F00684C09960FA1442040024F08AF4 +:103D0000382499015A23FF552E17E8FC383209014F +:103D100000FF803405EF800894118E21F087400168 +:103D2000BC164DE0C01CF107883C03E0800040FF5A +:103D30003DF640F7A8014EF4000452F780008A0ACD +:103D40004E040003FE0240F78007E903ACC8D530FB +:103D50003802890138039808D52BF108C904383E88 +:103D60000909D513F107883CA48840213C568A4AAA +:103D70004E240003FE9240F028014EF4000452F756 +:103D80008000E04FE908ACC8381499013823980046 +:103D900038228509F10AB0D098B188439601802A6B +:103DA000F305F58BF48749FFFF3CF50BF4078CC155 +:103DB0005A6824A850948048507380245A80010483 +:103DC0008501D58DF004B050B099003F803549FF92 +:103DD000FEE6ED18FCC0FC418401B63FF28180E3B1 +:103DE00049FFAEF23C1DFAB48401AE083C1DFAA9AD +:103DF000AE0884003C0FFAD82E0004595A0801047A +:103E00008407D5085A7801052E07C629D5032E0741 +:103E1000C6283E07E8FB2E07E8FB84C08C013E075E +:103E2000E8FC3C6FFAD544A3F04A448000552E07C5 +:103E3000E8FCE2C08400E8373C0FFADACF0349FF20 +:103E4000A40449FF7694852010850000F0014C9071 +:103E500000243C0DFADAE320E8FA2E07C5D4C0119D +:103E60002E07C5E6C00E2E500D124C54C00BCF09C4 +:103E70002E000423C806800649FFA3485A000117F4 +:103E800080098026B45F806749FFFEE150548001BD +:103E9000549280FFD5DC3C0DFAA98CC1842197B0E7 +:103EA000AE40D5C649FFAE908400FCC1FC002E0098 +:103EB0000459C8063C13E3153C23E316D5044420FB +:103EC000008080222E37E9693C03E3105A38040D44 +:103ED0002E37E915520000FFFE1C2E37E94840003E +:103EE0000C16520000FF3C0802843C03E311964884 +:103EF0003C08028584003E07E8FA96903C0DFAAB38 +:103F000084602E47C56549FFFE123C0DFA983C1DA2 +:103F1000FAAB2E27C567846049FFFF5F80C05A084F +:103F20000108FA0349FF6BFB3E600423D53E49FFBD +:103F30006F983C1DFA985A0802058405AE09D5070A +:103F40008409AE098001842049FF741D3C0DFA9854 +:103F500049FF9629844180623C1DFAAB3C0DFA98DA +:103F600049FFFF3B84004412CE58844149FFD56C81 +:103F7000840749FFF16549FF6F745A080206842DD2 +:103F80003C0DFA98D50D3C0DFA98842049FF73FB3F +:103F90002E17E96B3C0DFA985A180203842AAE4199 +:103FA0003C0DFA9849FF95FFFC803BFFFCBCEFFC01 +:103FB0004402000044121B9049FF71FC3C0DFAA919 +:103FC0008421EC04AE403BFFFC84DD9E3A6FA4BC30 +:103FD000EFDC44112CC4B1843A2094003A2314201D +:103FE000812049FFA33249FFA066F08149FF9F5914 +:103FF0008400120F800784E038131E02500F800ED9 +:104000002E27C5472E37C5488CE149FF725A5A788A +:1040100004F5000480005A08012184033C1DFA982D +:10402000F2014432B39049FF96F72E17E926440077 +:1040300000C8FE0C120F800744121B90500F800E18 +:104040002E27C5472E37C54849FF723B49FF758F5C +:104050003C1DFAB4A608C8FF4403F04A44100055BA +:10406000EC24AE403A6FA4848400DD9E3BFFFEBC8E +:10407000EFF8FA0049FF6B5349FF943684013E077D +:10408000E94F3E07E92084003E0004233E07E9395A +:104090003E07E8F949FF6EE53C1DFA985A08020D03 +:1040A0008404AE098001842049FF736D3C0DFA98A9 +:1040B000842DAE41D50B8409AE098001842049FFCF +:1040C00073623C0DFA98842AAE413C0DFAB4842107 +:1040D000AE402E07C5D45A0801122E07E9693E07E3 +:1040E000E9512E07E957C8043E07E90CD5072E070A +:1040F000E90C5A0801043E0004233C0DFA98A6017D +:104100003E07E96B840649FFF09B2E000423C81983 +:104110003C1DFA982E27E9584432B39049FF967C0B +:104120003C07F4E649FFA1F12E07C5DE5A08010459 +:1041300049FFFEBE840A49FFF083840B49FFF080EB +:104140002E0004235A08010D8400120F800344122C +:10415000AD70500F8006FA42FA7449FF71B22E0713 +:10416000C5D45A08010D2E0004235A0001052E075C +:10417000E939C8054402CE5B49FFFF2A2E07C5D4A2 +:104180005A08011B2E000423C81149FFB7CB5A005F +:10419000010A3C1DFA982E07E969A64949FF7129D1 +:1041A000D50F3E07E90C48FFFF663C1DFAB4A60890 +:1041B0005A0801FFD5EF2E07E96949FF71368400DF +:1041C0003E00045949FF6E4D3C1DFA982E27E96BBD +:1041D0005A0802069E12E602E804D5055A20020497 +:1041E000AE89D503840DAE093C0DFA9849FF94DBE6 +:1041F00084003E07E9793E07E9223E07E9202E07C1 +:10420000C5FC84213E07E94B3C0DFAA9AE4049FFAD +:1042100074AE490000695A08020448FFFF2C84006C +:10422000442225B08060444220A080A03C13E2B626 +:10423000E201E8099842AEC8944188248C01AD4857 +:104240009601D5F584003E07E96784013E07E92F12 +:10425000EC083BFFFE84DD9E440000A23A6F98BC50 +:1042600049FFEFE43C0DFA98A6015A080D128400AC +:10427000847F3C2DFAB7843F383100088C065A08F9 +:104280003CFA3C0DFAB71010003C1010003D49FFFD +:10429000D4C93E0004312E07C54384C0520000013A +:1042A0003E67E90949FF6E8784013E07E9303E0712 +:1042B000E9503E67E95C3E67E90C3E6004323E60CF +:1042C00004333E60043449FFC36D2E07C5D43E67F6 +:1042D000E9725A0801063A6F988448FFAC753A6F44 +:1042E0009884DD9E3A6FA6BCEFE044012CD4B184E3 +:1042F0003A20140044012CE43A2F94203A20140070 +:104300002E07C5D480FF3A2314205A0801322E000C +:104310000423C81F2E07E96949FF70155A08010ACE +:104320002E07E9575A0801063E07E90C8402D532E8 +:1043300049FFB3F385203803A602381326028D21E6 +:1043400049FF70385A9804F984013E07E939D510BD +:104350002E07E939C80D2E07E95849FF700D2E17B1 +:10436000E958380F86023813060249FF70234402C9 +:104370001B904412451049FF701D84C144021B90DC +:10438000441240003E67E94E49FF70143E60042825 +:104390008401EC203A6FA684DD9E0000000000003E +:1043A000000000000000000000000000000000000D +:1043B00000000000000000000000000000000000FD +:1043C00000000000000000000000000000000000ED +:1043D00000000000000000000000000000000000DD +:1043E00000000000000000000000000000000000CD +:1043F00000000000000000000000000000000000BD +:1044000000000000000000000000000000000000AC +:10441000000000000000000000000000000000009C +:10442000000000000000000000000000000000008C +:10443000000000000000000000000000000000007C +:10444000000000000000000000000000000000006C +:10445000000000000000000000000000000000005C +:10446000000000000000000000000000000000004C +:10447000000000000000000000000000000000003C +:10448000000000000000000000000000000000002C +:10449000000000000000000000000000000000001C +:1044A000000000000000000000000000000000000C +:1044B00000000000000000000000000000000000FC +:1044C00000000000000000000000000000000000EC +:1044D00000000000000000000000000000000000DC +:1044E00000000000000000000000000000000000CC +:1044F00000000000000000000000000000000000BC +:1045000000000000000000000000000000000000AB +:10451000000000000000000000000000000000009B +:10452000000000000000000000000000000000008B +:10453000000000000000000000000000000000007B +:10454000000000000000000000000000000000006B +:10455000000000000000000000000000000000005B +:10456000000000000000000000000000000000004B +:10457000000000000000000000000000000000003B +:10458000000000000000000000000000000000002B +:10459000000000000000000000000000000000001B +:1045A000000000000000000000000000000000000B +:1045B00000000000000000000000000000000000FB +:1045C00000000000000000000000000000000000EB +:1045D00000000000000000000000000000000000DB +:1045E00000000000000000000000000000000000CB +:1045F00000000000000000000000000000000000BB +:1046000000000000000000000000000000000000AA +:10461000000000000000000000000000000000009A +:10462000000000000000000000000000000000008A +:10463000000000000000000000000000000000007A +:10464000000000000000000000000000000000006A +:10465000000000000000000000000000000000005A +:10466000000000000000000000000000000000004A +:10467000000000000000000000000000000000003A +:10468000000000000000000000000000000000002A +:10469000000000000000000000000000000000001A +:1046A000000000000000000000000000000000000A +:1046B00000000000000000000000000000000000FA +:1046C00000000000000000000000000000000000EA +:1046D00000000000000000000000000000000000DA +:1046E00000000000000000000000000000000000CA +:1046F00000000000000000000000000000000000BA +:1047000000000000000000000000000000000000A9 +:104710000000000000000000000000000000000099 +:104720000000000000000000000000000000000089 +:104730000000000000000000000000000000000079 +:104740000000000000000000000000000000000069 +:104750000000000000000000000000000000000059 +:104760000000000000000000000000000000000049 +:104770000000000000000000000000000000000039 +:104780000000000000000000000000000000000029 +:104790000000000000000000000000000000000019 +:1047A0000000000000000000000000000000000009 +:1047B00000000000000000000000000000000000F9 +:1047C00000000000000000000000000000000000E9 +:1047D00000000000000000000000000000000000D9 +:1047E00000000000000000000000000000000000C9 +:1047F00000000000000000000000000000000000B9 +:1048000000000000000000000000000000000000A8 +:104810000000000000000000000000000000000098 +:104820000000000000000000000000000000000088 +:104830000000000000000000000000000000000078 +:104840000000000000000000000000000000000068 +:104850000000000000000000000000000000000058 +:104860000000000000000000000000000000000048 +:104870000000000000000000000000000000000038 +:104880000000000000000000000000000000000028 +:104890000000000000000000000000000000000018 +:1048A0000000000000000000000000000000000008 +:1048B00000000000000000000000000000000000F8 +:1048C00000000000000000000000000000000000E8 +:1048D00000000000000000000000000000000000D8 +:1048E00000000000000000000000000000000000C8 +:1048F00000000000000000000000000000000000B8 +:1049000000000000000000000000000000000000A7 +:104910000000000000000000000000000000000097 +:104920000000000000000000000000000000000087 +:104930000000000000000000000000000000000077 +:104940000000000000000000000000000000000067 +:104950000000000000000000000000000000000057 +:104960000000000000000000000000000000000047 +:104970000000000000000000000000000000000037 +:104980000000000000000000000000000000000027 +:104990000000000000000000000000000000000017 +:1049A0000000000000000000000000000000000007 +:1049B00000000000000000000000000000000000F7 +:1049C00000000000000000000000000000000000E7 +:1049D00000000000000000000000000000000000D7 +:1049E00000000000000000000000000000000000C7 +:1049F00000000000000000000000000000000000B7 +:104A000000000000000000000000000000000000A6 +:104A10000000000000000000000000000000000096 +:104A20000000000000000000000000000000000086 +:104A30000000000000000000000000000000000076 +:104A40000000000000000000000000000000000066 +:104A50000000000000000000000000000000000056 +:104A60000000000000000000000000000000000046 +:104A70000000000000000000000000000000000036 +:104A80000000000000000000000000000000000026 +:104A90000000000000000000000000000000000016 +:104AA0000000000000000000000000000000000006 +:104AB00000000000000000000000000000000000F6 +:104AC00000000000000000000000000000000000E6 +:104AD00000000000000000000000000000000000D6 +:104AE00000000000000000000000000000000000C6 +:104AF00000000000000000000000000000000000B6 +:104B000000000000000000000000000000000000A5 +:104B10000000000000000000000000000000000095 +:104B20000000000000000000000000000000000085 +:104B30000000000000000000000000000000000075 +:104B40000000000000000000000000000000000065 +:104B50000000000000000000000000000000000055 +:104B60000000000000000000000000000000000045 +:104B70000000000000000000000000000000000035 +:104B80000000000000000000000000000000000025 +:104B90000000000000000000000000000000000015 +:104BA0000000000000000000000000000000000005 +:104BB00000000000000000000000000000000000F5 +:104BC00000000000000000000000000000000000E5 +:104BD00000000000000000000000000000000000D5 +:104BE00000000000000000000000000000000000C5 +:104BF00000000000000000000000000000000000B5 +:104C000000000000000000000000000000000000A4 +:104C10000000000000000000000000000000000094 +:104C20000000000000000000000000000000000084 +:104C30000000000000000000000000000000000074 +:104C40000000000000000000000000000000000064 +:104C50000000000000000000000000000000000054 +:104C60000000000000000000000000000000000044 +:104C70000000000000000000000000000000000034 +:104C80000000000000000000000000000000000024 +:104C90000000000000000000000000000000000014 +:104CA0000000000000000000000000000000000004 +:104CB00000000000000000000000000000000000F4 +:104CC00000000000000000000000000000000000E4 +:104CD00000000000000000000000000000000000D4 +:104CE00000000000000000000000000000000000C4 +:104CF00000000000000000000000000000000000B4 +:104D000000000000000000000000000000000000A3 +:104D10000000000000000000000000000000000093 +:104D20000000000000000000000000000000000083 +:104D30000000000000000000000000000000000073 +:104D40000000000000000000000000000000000063 +:104D50000000000000000000000000000000000053 +:104D60000000000000000000000000000000000043 +:104D70000000000000000000000000000000000033 +:104D80000000000000000000000000000000000023 +:104D90000000000000000000000000000000000013 +:104DA0000000000000000000000000000000000003 +:104DB00000000000000000000000000000000000F3 +:104DC00000000000000000000000000000000000E3 +:104DD00000000000000000000000000000000000D3 +:104DE00000000000000000000000000000000000C3 +:104DF00000000000000000000000000000000000B3 +:104E000000000000000000000000000000000000A2 +:104E10000000000000000000000000000000000092 +:104E20000000000000000000000000000000000082 +:104E30000000000000000000000000000000000072 +:104E40000000000000000000000000000000000062 +:104E50000000000000000000000000000000000052 +:104E60000000000000000000000000000000000042 +:104E70000000000000000000000000000000000032 +:104E80000000000000000000000000000000000022 +:104E90000000000000000000000000000000000012 +:104EA0000000000000000000000000000000000002 +:104EB00000000000000000000000000000000000F2 +:104EC00000000000000000000000000000000000E2 +:104ED00000000000000000000000000000000000D2 +:104EE00000000000000000000000000000000000C2 +:104EF00000000000000000000000000000000000B2 +:104F000000000000000000000000000000000000A1 +:104F10000000000000000000000000000000000091 +:104F20000000000000000000000000000000000081 +:104F30000000000000000000000000000000000071 +:104F40000000000000000000000000000000000061 +:104F50000000000000000000000000000000000051 +:104F60000000000000000000000000000000000041 +:104F70000000000000000000000000000000000031 +:104F80000000000000000000000000000000000021 +:104F90000000000000000000000000000000000011 +:104FA0000000000000000000000000000000000001 +:104FB00000000000000000000000000000000000F1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE00000000000000000000000000000000000C1 +:104FF00000000000000000000000000000000000B1 +:1050000000000000000000000000000000000000A0 +:105010000000000000000000000000000000000090 +:105020000000000000000000000000000000000080 +:105030000000000000000000000000000000000070 +:105040000000000000000000000000000000000060 +:105050000000000000000000000000000000000050 +:105060000000000000000000000000000000000040 +:105070000000000000000000000000000000000030 +:105080000000000000000000000000000000000020 +:105090000000000000000000000000000000000010 +:1050A0000000000000000000000000000000000000 +:1050B00000000000000000000000000000000000F0 +:1050C00000000000000000000000000000000000E0 +:1050D00000000000000000000000000000000000D0 +:1050E00000000000000000000000000000000000C0 +:1050F00000000000000000000000000000000000B0 +:10510000000000000000000000000000000000009F +:10511000000000000000000000000000000000008F +:10512000000000000000000000000000000000007F +:10513000000000000000000000000000000000006F +:10514000000000000000000000000000000000005F +:10515000000000000000000000000000000000004F +:10516000000000000000000000000000000000003F +:10517000000000000000000000000000000000002F +:10518000000000000000000000000000000000001F +:10519000000000000000000000000000000000000F +:1051A00000000000000000000000000000000000FF +:1051B00000000000000000000000000000000000EF +:1051C00000000000000000000000000000000000DF +:1051D00000000000000000000000000000000000CF +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:10520000000000000000000000000000000000009E +:10521000000000000000000000000000000000008E +:10522000000000000000000000000000000000007E +:10523000000000000000000000000000000000006E +:10524000000000000000000000000000000000005E +:10525000000000000000000000000000000000004E +:10526000000000000000000000000000000000003E +:10527000000000000000000000000000000000002E +:10528000000000000000000000000000000000001E +:10529000000000000000000000000000000000000E +:1052A00000000000000000000000000000000000FE +:1052B00000000000000000000000000000000000EE +:1052C00000000000000000000000000000000000DE +:1052D00000000000000000000000000000000000CE +:1052E00000000000000000000000000000000000BE +:1052F00000000000000000000000000000000000AE +:10530000000000000000000000000000000000009D +:10531000000000000000000000000000000000008D +:10532000000000000000000000000000000000007D +:10533000000000000000000000000000000000006D +:10534000000000000000000000000000000000005D +:10535000000000000000000000000000000000004D +:10536000000000000000000000000000000000003D +:10537000000000000000000000000000000000002D +:10538000000000000000000000000000000000001D +:10539000000000000000000000000000000000000D +:1053A00000000000000000000000000000000000FD +:1053B00000000000000000000000000000000000ED +:1053C00000000000000000000000000000000000DD +:1053D00000000000000000000000000000000000CD +:1053E00000000000000000000000000000000000BD +:1053F00000000000000000000000000000000000AD +:10540000000000000000000000000000000000009C +:10541000000000000000000000000000000000008C +:10542000000000000000000000000000000000007C +:10543000000000000000000000000000000000006C +:10544000000000000000000000000000000000005C +:10545000000000000000000000000000000000004C +:10546000000000000000000000000000000000003C +:10547000000000000000000000000000000000002C +:10548000000000000000000000000000000000001C +:10549000000000000000000000000000000000000C +:1054A00000000000000000000000000000000000FC +:1054B00000000000000000000000000000000000EC +:1054C00000000000000000000000000000000000DC +:1054D00000000000000000000000000000000000CC +:1054E00000000000000000000000000000000000BC +:1054F00000000000000000000000000000000000AC +:10550000000000000000000000000000000000009B +:10551000000000000000000000000000000000008B +:10552000000000000000000000000000000000007B +:10553000000000000000000000000000000000006B +:10554000000000000000000000000000000000005B +:10555000000000000000000000000000000000004B +:10556000000000000000000000000000000000003B +:10557000000000000000000000000000000000002B +:10558000000000000000000000000000000000001B +:10559000000000000000000000000000000000000B +:1055A00000000000000000000000000000000000FB +:1055B00000000000000000000000000000000000EB +:1055C00000000000000000000000000000000000DB +:1055D00000000000000000000000000000000000CB +:1055E00000000000000000000000000000000000BB +:1055F00000000000000000000000000000000000AB +:10560000000000000000000000000000000000009A +:10561000000000000000000000000000000000008A +:10562000000000000000000000000000000000007A +:10563000000000000000000000000000000000006A +:10564000000000000000000000000000000000005A +:10565000000000000000000000000000000000004A +:10566000000000000000000000000000000000003A +:10567000000000000000000000000000000000002A +:10568000000000000000000000000000000000001A +:10569000000000000000000000000000000000000A +:1056A00000000000000000000000000000000000FA +:1056B00000000000000000000000000000000000EA +:1056C00000000000000000000000000000000000DA +:1056D00000000000000000000000000000000000CA +:1056E00000000000000000000000000000000000BA +:1056F00000000000000000000000000000000000AA +:105700000000000000000000000000000000000099 +:105710000000000000000000000000000000000089 +:105720000000000000000000000000000000000079 +:105730000000000000000000000000000000000069 +:105740000000000000000000000000000000000059 +:105750000000000000000000000000000000000049 +:105760000000000000000000000000000000000039 +:105770000000000000000000000000000000000029 +:105780000000000000000000000000000000000019 +:105790000000000000000000000000000000000009 +:1057A00000000000000000000000000000000000F9 +:1057B00000000000000000000000000000000000E9 +:1057C00000000000000000000000000000000000D9 +:1057D00000000000000000000000000000000000C9 +:1057E00000000000000000000000000000000000B9 +:1057F00000000000000000000000000000000000A9 +:105800000000000000000000000000000000000098 +:105810000000000000000000000000000000000088 +:105820000000000000000000000000000000000078 +:105830000000000000000000000000000000000068 +:105840000000000000000000000000000000000058 +:105850000000000000000000000000000000000048 +:105860000000000000000000000000000000000038 +:105870000000000000000000000000000000000028 +:105880000000000000000000000000000000000018 +:105890000000000000000000000000000000000008 +:1058A00000000000000000000000000000000000F8 +:1058B00000000000000000000000000000000000E8 +:1058C00000000000000000000000000000000000D8 +:1058D00000000000000000000000000000000000C8 +:1058E00000000000000000000000000000000000B8 +:1058F00000000000000000000000000000000000A8 +:105900000000000000000000000000000000000097 +:105910000000000000000000000000000000000087 +:105920000000000000000000000000000000000077 +:105930000000000000000000000000000000000067 +:105940000000000000000000000000000000000057 +:105950000000000000000000000000000000000047 +:105960000000000000000000000000000000000037 +:105970000000000000000000000000000000000027 +:105980000000000000000000000000000000000017 +:105990000000000000000000000000000000000007 +:1059A00000000000000000000000000000000000F7 +:1059B00000000000000000000000000000000000E7 +:1059C00000000000000000000000000000000000D7 +:1059D00000000000000000000000000000000000C7 +:1059E00000000000000000000000000000000000B7 +:1059F00000000000000000000000000000000000A7 +:105A00000000000000000000000000000000000096 +:105A10000000000000000000000000000000000086 +:105A20000000000000000000000000000000000076 +:105A30000000000000000000000000000000000066 +:105A40000000000000000000000000000000000056 +:105A50000000000000000000000000000000000046 +:105A60000000000000000000000000000000000036 +:105A70000000000000000000000000000000000026 +:105A80000000000000000000000000000000000016 +:105A90000000000000000000000000000000000006 +:105AA00000000000000000000000000000000000F6 +:105AB00000000000000000000000000000000000E6 +:105AC00000000000000000000000000000000000D6 +:105AD00000000000000000000000000000000000C6 +:105AE00000000000000000000000000000000000B6 +:105AF00000000000000000000000000000000000A6 +:105B00000000000000000000000000000000000095 +:105B10000000000000000000000000000000000085 +:105B20000000000000000000000000000000000075 +:105B30000000000000000000000000000000000065 +:105B40000000000000000000000000000000000055 +:105B50000000000000000000000000000000000045 +:105B60000000000000000000000000000000000035 +:105B70000000000000000000000000000000000025 +:105B80000000000000000000000000000000000015 +:105B90000000000000000000000000000000000005 +:105BA00000000000000000000000000000000000F5 +:105BB00000000000000000000000000000000000E5 +:105BC00000000000000000000000000000000000D5 +:105BD00000000000000000000000000000000000C5 +:105BE00000000000000000000000000000000000B5 +:105BF00000000000000000000000000000000000A5 +:105C00000000000000000000000000000000000094 +:105C10000000000000000000000000000000000084 +:105C20000000000000000000000000000000000074 +:105C30000000000000000000000000000000000064 +:105C40000000000000000000000000000000000054 +:105C50000000000000000000000000000000000044 +:105C60000000000000000000000000000000000034 +:105C70000000000000000000000000000000000024 +:105C80000000000000000000000000000000000014 +:105C90000000000000000000000000000000000004 +:105CA00000000000000000000000000000000000F4 +:105CB00000000000000000000000000000000000E4 +:105CC00000000000000000000000000000000000D4 +:105CD00000000000000000000000000000000000C4 +:105CE00000000000000000000000000000000000B4 +:105CF00000000000000000000000000000000000A4 +:105D00000000000000000000000000000000000093 +:105D10000000000000000000000000000000000083 +:105D20000000000000000000000000000000000073 +:105D30000000000000000000000000000000000063 +:105D40000000000000000000000000000000000053 +:105D50000000000000000000000000000000000043 +:105D60000000000000000000000000000000000033 +:105D70000000000000000000000000000000000023 +:105D80000000000000000000000000000000000013 +:105D90000000000000000000000000000000000003 +:105DA00000000000000000000000000000000000F3 +:105DB00000000000000000000000000000000000E3 +:105DC00000000000000000000000000000000000D3 +:105DD00000000000000000000000000000000000C3 +:105DE00000000000000000000000000000000000B3 +:105DF00000000000000000000000000000000000A3 +:105E00000000000000000000000000000000000092 +:105E10000000000000000000000000000000000082 +:105E20000000000000000000000000000000000072 +:105E30000000000000000000000000000000000062 +:105E40000000000000000000000000000000000052 +:105E50000000000000000000000000000000000042 +:105E60000000000000000000000000000000000032 +:105E70000000000000000000000000000000000022 +:105E80000000000000000000000000000000000012 +:105E90000000000000000000000000000000000002 +:105EA00000000000000000000000000000000000F2 +:105EB00000000000000000000000000000000000E2 +:105EC00000000000000000000000000000000000D2 +:105ED00000000000000000000000000000000000C2 +:105EE00000000000000000000000000000000000B2 +:105EF00000000000000000000000000000000000A2 +:105F00000000000000000000000000000000000091 +:105F10000000000000000000000000000000000081 +:105F20000000000000000000000000000000000071 +:105F30000000000000000000000000000000000061 +:105F40000000000000000000000000000000000051 +:105F50000000000000000000000000000000000041 +:105F60000000000000000000000000000000000031 +:105F70000000000000000000000000000000000021 +:105F80000000000000000000000000000000000011 +:105F90000000000000000000000000000000000001 +:105FA00000000000000000000000000000000000F1 +:105FB00000000000000000000000000000000000E1 +:105FC00000000000000000000000000000000000D1 +:105FD00000000000000000000000000000000000C1 +:105FE00000000000000000000000000000000000B1 +:105FF00000000000000000000000000000000000A1 +:106000000000000000000000000000000000000090 +:106010000000000000000000000000000000000080 +:106020000000000000000000000000000000000070 +:106030000000000000000000000000000000000060 +:106040000000000000000000000000000000000050 +:106050000000000000000000000000000000000040 +:106060000000000000000000000000000000000030 +:106070000000000000000000000000000000000020 +:106080000000000000000000000000000000000010 +:106090000000000000000000000000000000000000 +:1060A00000000000000000000000000000000000F0 +:1060B00000000000000000000000000000000000E0 +:1060C00000000000000000000000000000000000D0 +:1060D00000000000000000000000000000000000C0 +:1060E00000000000000000000000000000000000B0 +:1060F00000000000000000000000000000000000A0 +:10610000000000000000000000000000000000008F +:10611000000000000000000000000000000000007F +:10612000000000000000000000000000000000006F +:10613000000000000000000000000000000000005F +:10614000000000000000000000000000000000004F +:10615000000000000000000000000000000000003F +:10616000000000000000000000000000000000002F +:10617000000000000000000000000000000000001F +:10618000000000000000000000000000000000000F +:1061900000000000000000000000000000000000FF +:1061A00000000000000000000000000000000000EF +:1061B00000000000000000000000000000000000DF +:1061C00000000000000000000000000000000000CF +:1061D00000000000000000000000000000000000BF +:1061E00000000000000000000000000000000000AF +:1061F000000000000000000000000000000000009F +:10620000000000000000000000000000000000008E +:10621000000000000000000000000000000000007E +:10622000000000000000000000000000000000006E +:10623000000000000000000000000000000000005E +:10624000000000000000000000000000000000004E +:10625000000000000000000000000000000000003E +:10626000000000000000000000000000000000002E +:10627000000000000000000000000000000000001E +:10628000000000000000000000000000000000000E +:1062900000000000000000000000000000000000FE +:1062A00000000000000000000000000000000000EE +:1062B00000000000000000000000000000000000DE +:1062C00000000000000000000000000000000000CE +:1062D00000000000000000000000000000000000BE +:1062E00000000000000000000000000000000000AE +:1062F000000000000000000000000000000000009E +:10630000000000000000000000000000000000008D +:10631000000000000000000000000000000000007D +:10632000000000000000000000000000000000006D +:10633000000000000000000000000000000000005D +:10634000000000000000000000000000000000004D +:10635000000000000000000000000000000000003D +:10636000000000000000000000000000000000002D +:10637000000000000000000000000000000000001D +:10638000000000000000000000000000000000000D +:1063900000000000000000000000000000000000FD +:1063A00000000000000000000000000000000000ED +:1063B00000000000000000000000000000000000DD +:1063C00000000000000000000000000000000000CD +:1063D00000000000000000000000000000000000BD +:1063E00000000000000000000000000000000000AD +:1063F000000000000000000000000000000000009D +:10640000000000000000000000000000000000008C +:10641000000000000000000000000000000000007C +:10642000000000000000000000000000000000006C +:10643000000000000000000000000000000000005C +:10644000000000000000000000000000000000004C +:10645000000000000000000000000000000000003C +:10646000000000000000000000000000000000002C +:10647000000000000000000000000000000000001C +:10648000000000000000000000000000000000000C +:1064900000000000000000000000000000000000FC +:1064A00000000000000000000000000000000000EC +:1064B00000000000000000000000000000000000DC +:1064C00000000000000000000000000000000000CC +:1064D00000000000000000000000000000000000BC +:1064E00000000000000000000000000000000000AC +:1064F000000000000000000000000000000000009C +:10650000000000000000000000000000000000008B +:10651000000000000000000000000000000000007B +:10652000000000000000000000000000000000006B +:10653000000000000000000000000000000000005B +:10654000000000000000000000000000000000004B +:10655000000000000000000000000000000000003B +:10656000000000000000000000000000000000002B +:10657000000000000000000000000000000000001B +:10658000000000000000000000000000000000000B +:1065900000000000000000000000000000000000FB +:1065A00000000000000000000000000000000000EB +:1065B00000000000000000000000000000000000DB +:1065C00000000000000000000000000000000000CB +:1065D00000000000000000000000000000000000BB +:1065E00000000000000000000000000000000000AB +:1065F000000000000000000000000000000000009B +:10660000000000000000000000000000000000008A +:10661000000000000000000000000000000000007A +:10662000000000000000000000000000000000006A +:10663000000000000000000000000000000000005A +:10664000000000000000000000000000000000004A +:10665000000000000000000000000000000000003A +:10666000000000000000000000000000000000002A +:10667000000000000000000000000000000000001A +:10668000000000000000000000000000000000000A +:1066900000000000000000000000000000000000FA +:1066A00000000000000000000000000000000000EA +:1066B00000000000000000000000000000000000DA +:1066C00000000000000000000000000000000000CA +:1066D00000000000000000000000000000000000BA +:1066E00000000000000000000000000000000000AA +:1066F000000000000000000000000000000000009A +:106700000000000000000000000000000000000089 +:106710000000000000000000000000000000000079 +:106720000000000000000000000000000000000069 +:106730000000000000000000000000000000000059 +:106740000000000000000000000000000000000049 +:106750000000000000000000000000000000000039 +:106760000000000000000000000000000000000029 +:106770000000000000000000000000000000000019 +:106780000000000000000000000000000000000009 +:1067900000000000000000000000000000000000F9 +:1067A00000000000000000000000000000000000E9 +:1067B00000000000000000000000000000000000D9 +:1067C00000000000000000000000000000000000C9 +:1067D00000000000000000000000000000000000B9 +:1067E00000000000000000000000000000000000A9 +:1067F0000000000000000000000000000000000099 +:106800000000000000000000000000000000000088 +:106810000000000000000000000000000000000078 +:106820000000000000000000000000000000000068 +:106830000000000000000000000000000000000058 +:106840000000000000000000000000000000000048 +:106850000000000000000000000000000000000038 +:106860000000000000000000000000000000000028 +:106870000000000000000000000000000000000018 +:106880000000000000000000000000000000000008 +:1068900000000000000000000000000000000000F8 +:1068A00000000000000000000000000000000000E8 +:1068B00000000000000000000000000000000000D8 +:1068C00000000000000000000000000000000000C8 +:1068D00000000000000000000000000000000000B8 +:1068E00000000000000000000000000000000000A8 +:1068F0000000000000000000000000000000000098 +:106900000000000000000000000000000000000087 +:106910000000000000000000000000000000000077 +:106920000000000000000000000000000000000067 +:106930000000000000000000000000000000000057 +:106940000000000000000000000000000000000047 +:106950000000000000000000000000000000000037 +:106960000000000000000000000000000000000027 +:106970000000000000000000000000000000000017 +:106980000000000000000000000000000000000007 +:1069900000000000000000000000000000000000F7 +:1069A00000000000000000000000000000000000E7 +:1069B00000000000000000000000000000000000D7 +:1069C00000000000000000000000000000000000C7 +:1069D00000000000000000000000000000000000B7 +:1069E00000000000000000000000000000000000A7 +:1069F0000000000000000000000000000000000097 +:106A00000000000000000000000000000000000086 +:106A10000000000000000000000000000000000076 +:106A20000000000000000000000000000000000066 +:106A30000000000000000000000000000000000056 +:106A40000000000000000000000000000000000046 +:106A50000000000000000000000000000000000036 +:106A60000000000000000000000000000000000026 +:106A70000000000000000000000000000000000016 +:106A80000000000000000000000000000000000006 +:106A900000000000000000000000000000000000F6 +:106AA00000000000000000000000000000000000E6 +:106AB00000000000000000000000000000000000D6 +:106AC00000000000000000000000000000000000C6 +:106AD00000000000000000000000000000000000B6 +:106AE00000000000000000000000000000000000A6 +:106AF0000000000000000000000000000000000096 +:106B00000000000000000000000000000000000085 +:106B10000000000000000000000000000000000075 +:106B20000000000000000000000000000000000065 +:106B30000000000000000000000000000000000055 +:106B40000000000000000000000000000000000045 +:106B50000000000000000000000000000000000035 +:106B60000000000000000000000000000000000025 +:106B70000000000000000000000000000000000015 +:106B80000000000000000000000000000000000005 +:106B900000000000000000000000000000000000F5 +:106BA00000000000000000000000000000000000E5 +:106BB00000000000000000000000000000000000D5 +:106BC00000000000000000000000000000000000C5 +:106BD00000000000000000000000000000000000B5 +:106BE00000000000000000000000000000000000A5 +:106BF0000000000000000000000000000000000095 +:106C00000000000000000000000000000000000084 +:106C10000000000000000000000000000000000074 +:106C20000000000000000000000000000000000064 +:106C30000000000000000000000000000000000054 +:106C40000000000000000000000000000000000044 +:106C50000000000000000000000000000000000034 +:106C60000000000000000000000000000000000024 +:106C70000000000000000000000000000000000014 +:106C80000000000000000000000000000000000004 +:106C900000000000000000000000000000000000F4 +:106CA00000000000000000000000000000000000E4 +:106CB00000000000000000000000000000000000D4 +:106CC00000000000000000000000000000000000C4 +:106CD00000000000000000000000000000000000B4 +:106CE00000000000000000000000000000000000A4 +:106CF0000000000000000000000000000000000094 +:106D00000000000000000000000000000000000083 +:106D10000000000000000000000000000000000073 +:106D20000000000000000000000000000000000063 +:106D30000000000000000000000000000000000053 +:106D40000000000000000000000000000000000043 +:106D50000000000000000000000000000000000033 +:106D60000000000000000000000000000000000023 +:106D70000000000000000000000000000000000013 +:106D80000000000000000000000000000000000003 +:106D900000000000000000000000000000000000F3 +:106DA00000000000000000000000000000000000E3 +:106DB00000000000000000000000000000000000D3 +:106DC00000000000000000000000000000000000C3 +:106DD00000000000000000000000000000000000B3 +:106DE00000000000000000000000000000000000A3 +:106DF0000000000000000000000000000000000093 +:106E00000000000000000000000000000000000082 +:106E10000000000000000000000000000000000072 +:106E20000000000000000000000000000000000062 +:106E30000000000000000000000000000000000052 +:106E40000000000000000000000000000000000042 +:106E50000000000000000000000000000000000032 +:106E60000000000000000000000000000000000022 +:106E70000000000000000000000000000000000012 +:106E80000000000000000000000000000000000002 +:106E900000000000000000000000000000000000F2 +:106EA00000000000000000000000000000000000E2 +:106EB00000000000000000000000000000000000D2 +:106EC00000000000000000000000000000000000C2 +:106ED00000000000000000000000000000000000B2 +:106EE00000000000000000000000000000000000A2 +:106EF0000000000000000000000000000000000092 +:106F00000000000000000000000000000000000081 +:106F10000000000000000000000000000000000071 +:106F20000000000000000000000000000000000061 +:106F30000000000000000000000000000000000051 +:106F40000000000000000000000000000000000041 +:106F50000000000000000000000000000000000031 +:106F60000000000000000000000000000000000021 +:106F70000000000000000000000000000000000011 +:106F80000000000000000000000000000000000001 +:106F900000000000000000000000000000000000F1 +:106FA00000000000000000000000000000000000E1 +:106FB00000000000000000000000000000000000D1 +:106FC00000000000000000000000000000000000C1 +:106FD00000000000000000000000000000000000B1 +:106FE00000000000000000000000000000000000A1 +:106FF0000000000000000000000000000000000091 +:107000000000000000000000000000000000000080 +:107010000000000000000000000000000000000070 +:107020000000000000000000000000000000000060 +:107030000000000000000000000000000000000050 +:107040000000000000000000000000000000000040 +:107050000000000000000000000000000000000030 +:107060000000000000000000000000000000000020 +:107070000000000000000000000000000000000010 +:107080000000000000000000000000000000000000 +:1070900000000000000000000000000000000000F0 +:1070A00000000000000000000000000000000000E0 +:1070B00000000000000000000000000000000000D0 +:1070C00000000000000000000000000000000000C0 +:1070D00000000000000000000000000000000000B0 +:1070E00000000000000000000000000000000000A0 +:1070F0000000000000000000000000000000000090 +:10710000000000000000000000000000000000007F +:10711000000000000000000000000000000000006F +:10712000000000000000000000000000000000005F +:10713000000000000000000000000000000000004F +:10714000000000000000000000000000000000003F +:10715000000000000000000000000000000000002F +:10716000000000000000000000000000000000001F +:10717000000000000000000000000000000000000F +:1071800000000000000000000000000000000000FF +:1071900000000000000000000000000000000000EF +:1071A00000000000000000000000000000000000DF +:1071B00000000000000000000000000000000000CF +:1071C00000000000000000000000000000000000BF +:1071D00000000000000000000000000000000000AF +:1071E000000000000000000000000000000000009F +:1071F000000000000000000000000000000000008F +:10720000000000000000000000000000000000007E +:10721000000000000000000000000000000000006E +:10722000000000000000000000000000000000005E +:10723000000000000000000000000000000000004E +:10724000000000000000000000000000000000003E +:10725000000000000000000000000000000000002E +:10726000000000000000000000000000000000001E +:10727000000000000000000000000000000000000E +:1072800000000000000000000000000000000000FE +:1072900000000000000000000000000000000000EE +:1072A00000000000000000000000000000000000DE +:1072B00000000000000000000000000000000000CE +:1072C00000000000000000000000000000000000BE +:1072D00000000000000000000000000000000000AE +:1072E000000000000000000000000000000000009E +:1072F000000000000000000000000000000000008E +:10730000000000000000000000000000000000007D +:10731000000000000000000000000000000000006D +:10732000000000000000000000000000000000005D +:10733000000000000000000000000000000000004D +:10734000000000000000000000000000000000003D +:10735000000000000000000000000000000000002D +:10736000000000000000000000000000000000001D +:10737000000000000000000000000000000000000D +:1073800000000000000000000000000000000000FD +:1073900000000000000000000000000000000000ED +:1073A00000000000000000000000000000000000DD +:1073B00000000000000000000000000000000000CD +:1073C00000000000000000000000000000000000BD +:1073D00000000000000000000000000000000000AD +:1073E000000000000000000000000000000000009D +:1073F000000000000000000000000000000000008D +:10740000000000000000000000000000000000007C +:10741000000000000000000000000000000000006C +:10742000000000000000000000000000000000005C +:10743000000000000000000000000000000000004C +:10744000000000000000000000000000000000003C +:10745000000000000000000000000000000000002C +:10746000000000000000000000000000000000001C +:10747000000000000000000000000000000000000C +:1074800000000000000000000000000000000000FC +:1074900000000000000000000000000000000000EC +:1074A00000000000000000000000000000000000DC +:1074B00000000000000000000000000000000000CC +:1074C00000000000000000000000000000000000BC +:1074D00000000000000000000000000000000000AC +:1074E000000000000000000000000000000000009C +:1074F000000000000000000000000000000000008C +:10750000000000000000000000000000000000007B +:10751000000000000000000000000000000000006B +:10752000000000000000000000000000000000005B +:10753000000000000000000000000000000000004B +:10754000000000000000000000000000000000003B +:10755000000000000000000000000000000000002B +:10756000000000000000000000000000000000001B +:10757000000000000000000000000000000000000B +:1075800000000000000000000000000000000000FB +:1075900000000000000000000000000000000000EB +:1075A00000000000000000000000000000000000DB +:1075B00000000000000000000000000000000000CB +:1075C00000000000000000000000000000000000BB +:1075D00000000000000000000000000000000000AB +:1075E000000000000000000000000000000000009B +:1075F000000000000000000000000000000000008B +:10760000000000000000000000000000000000007A +:10761000000000000000000000000000000000006A +:10762000000000000000000000000000000000005A +:10763000000000000000000000000000000000004A +:10764000000000000000000000000000000000003A +:10765000000000000000000000000000000000002A +:10766000000000000000000000000000000000001A +:10767000000000000000000000000000000000000A +:1076800000000000000000000000000000000000FA +:1076900000000000000000000000000000000000EA +:1076A00000000000000000000000000000000000DA +:1076B00000000000000000000000000000000000CA +:1076C00000000000000000000000000000000000BA +:1076D00000000000000000000000000000000000AA +:1076E000000000000000000000000000000000009A +:1076F000000000000000000000000000000000008A +:107700000000000000000000000000000000000079 +:107710000000000000000000000000000000000069 +:107720000000000000000000000000000000000059 +:107730000000000000000000000000000000000049 +:107740000000000000000000000000000000000039 +:107750000000000000000000000000000000000029 +:107760000000000000000000000000000000000019 +:107770000000000000000000000000000000000009 +:1077800000000000000000000000000000000000F9 +:1077900000000000000000000000000000000000E9 +:1077A00000000000000000000000000000000000D9 +:1077B00000000000000000000000000000000000C9 +:1077C00000000000000000000000000000000000B9 +:1077D00000000000000000000000000000000000A9 +:1077E0000000000000000000000000000000000099 +:1077F0000000000000000000000000000000000089 +:107800000000000000000000000000000000000078 +:107810000000000000000000000000000000000068 +:107820000000000000000000000000000000000058 +:107830000000000000000000000000000000000048 +:107840000000000000000000000000000000000038 +:107850000000000000000000000000000000000028 +:107860000000000000000000000000000000000018 +:107870000000000000000000000000000000000008 +:1078800000000000000000000000000000000000F8 +:1078900000000000000000000000000000000000E8 +:1078A00000000000000000000000000000000000D8 +:1078B00000000000000000000000000000000000C8 +:1078C00000000000000000000000000000000000B8 +:1078D00000000000000000000000000000000000A8 +:1078E0000000000000000000000000000000000098 +:1078F0000000000000000000000000000000000088 +:107900000000000000000000000000000000000077 +:107910000000000000000000000000000000000067 +:107920000000000000000000000000000000000057 +:107930000000000000000000000000000000000047 +:107940000000000000000000000000000000000037 +:107950000000000000000000000000000000000027 +:107960000000000000000000000000000000000017 +:107970000000000000000000000000000000000007 +:1079800000000000000000000000000000000000F7 +:1079900000000000000000000000000000000000E7 +:1079A00000000000000000000000000000000000D7 +:1079B00000000000000000000000000000000000C7 +:1079C00000000000000000000000000000000000B7 +:1079D00000000000000000000000000000000000A7 +:1079E0000000000000000000000000000000000097 +:1079F0000000000000000000000000000000000087 +:107A00000000000000000000000000000000000076 +:107A10000000000000000000000000000000000066 +:107A20000000000000000000000000000000000056 +:107A30000000000000000000000000000000000046 +:107A40000000000000000000000000000000000036 +:107A50000000000000000000000000000000000026 +:107A60000000000000000000000000000000000016 +:107A70000000000000000000000000000000000006 +:107A800000000000000000000000000000000000F6 +:107A900000000000000000000000000000000000E6 +:107AA00000000000000000000000000000000000D6 +:107AB00000000000000000000000000000000000C6 +:107AC00000000000000000000000000000000000B6 +:107AD00000000000000000000000000000000000A6 +:107AE0000000000000000000000000000000000096 +:107AF0000000000000000000000000000000000086 +:107B00000000000000000000000000000000000075 +:107B10000000000000000000000000000000000065 +:107B20000000000000000000000000000000000055 +:107B30000000000000000000000000000000000045 +:107B40000000000000000000000000000000000035 +:107B50000000000000000000000000000000000025 +:107B60000000000000000000000000000000000015 +:107B70000000000000000000000000000000000005 +:107B800000000000000000000000000000000000F5 +:107B900000000000000000000000000000000000E5 +:107BA00000000000000000000000000000000000D5 +:107BB00000000000000000000000000000000000C5 +:107BC00000000000000000000000000000000000B5 +:107BD00000000000000000000000000000000000A5 +:107BE0000000000000000000000000000000000095 +:107BF0000000000000000000000000000000000085 +:107C00000000000000000000000000000000000074 +:107C10000000000000000000000000000000000064 +:107C20000000000000000000000000000000000054 +:107C30000000000000000000000000000000000044 +:107C40000000000000000000000000000000000034 +:107C50000000000000000000000000000000000024 +:107C60000000000000000000000000000000000014 +:107C70000000000000000000000000000000000004 +:107C800000000000000000000000000000000000F4 +:107C900000000000000000000000000000000000E4 +:107CA00000000000000000000000000000000000D4 +:107CB00000000000000000000000000000000000C4 +:107CC00000000000000000000000000000000000B4 +:107CD00000000000000000000000000000000000A4 +:107CE0000000000000000000000000000000000094 +:107CF0000000000000000000000000000000000084 +:107D00000000000000000000000000000000000073 +:107D10000000000000000000000000000000000063 +:107D20000000000000000000000000000000000053 +:107D30000000000000000000000000000000000043 +:107D40000000000000000000000000000000000033 +:107D50000000000000000000000000000000000023 +:107D60000000000000000000000000000000000013 +:107D70000000000000000000000000000000000003 +:107D800000000000000000000000000000000000F3 +:107D900000000000000000000000000000000000E3 +:107DA00000000000000000000000000000000000D3 +:107DB00000000000000000000000000000000000C3 +:107DC00000000000000000000000000000000000B3 +:107DD00000000000000000000000000000000000A3 +:107DE0000000000000000000000000000000000093 +:107DF0000000000000000000000000000000000083 +:107E00000000000000000000000000000000000072 +:107E10000000000000000000000000000000000062 +:107E20000000000000000000000000000000000052 +:107E30000000000000000000000000000000000042 +:107E40000000000000000000000000000000000032 +:107E50000000000000000000000000000000000022 +:107E60000000000000000000000000000000000012 +:107E70000000000000000000000000000000000002 +:107E800000000000000000000000000000000000F2 +:107E900000000000000000000000000000000000E2 +:107EA00000000000000000000000000000000000D2 +:107EB00000000000000000000000000000000000C2 +:107EC00000000000000000000000000000000000B2 +:107ED00000000000000000000000000000000000A2 +:107EE0000000000000000000000000000000000092 +:107EF0000000000000000000000000000000000082 +:107F00000000000000000000000000000000000071 +:107F10000000000000000000000000000000000061 +:107F20000000000000000000000000000000000051 +:107F30000000000000000000000000000000000041 +:107F40000000000000000000000000000000000031 +:107F50000000000000000000000000000000000021 +:107F60000000000000000000000000000000000011 +:107F70000000000000000000000000000000000001 +:107F800000000000000000000000000000000000F1 +:107F900000000000000000000000000000000000E1 +:107FA00000000000000000000000000000000000D1 +:107FB00000000000000000000000000000000000C1 +:107FC00000000000000000000000000000000000B1 +:107FD00000000000000000000000000000000000A1 +:107FE0000000000000000000000000000000000091 +:107FF0000000000000000000000000000000000081 +:108000000000000000000000000000000000000070 +:108010000000000000000000000000000000000060 +:108020000000000000000000000000000000000050 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:1080800000000000000000000000000000000000F0 +:1080900000000000000000000000000000000000E0 +:1080A00000000000000000000000000000000000D0 +:1080B00000000000000000000000000000000000C0 +:1080C00000000000000000000000000000000000B0 +:1080D00000000000000000000000000000000000A0 +:1080E0000000000000000000000000000000000090 +:1080F0000000000000000000000000000000000080 +:1081000006F0F15506F0F15506F0F15506F0F1557F +:108110001616161616161616151616161615151602 +:1081200016161516161615151616151616161616F3 +:1081300016161717161616161616161616151515E0 +:1081400016151516161616161616161616161515D3 +:1081500016161616161617161615151516161615C2 +:1081600015151616161615161616151515151516B7 +:1081700015151515161615161616161615151516A7 +:108180001516161515151616161616161716161692 +:108190001516161616161515161516151516161685 +:1081A0001516161616161616161616161616161670 +:1081B0001716151616161516161616151616161661 +:1081C0001616161616161616151616161516161552 +:1081D0001616161616161516161616161516151543 +:1081E0001515161516161616161616161616161632 +:1081F0001516161616161616161716161615151522 +:108200001515151616161616161616171615161611 +:108210001616151615161616161616161717151500 +:1082200015161616151515171616161616161717EF +:1082300016151615161615161616161616161616E1 +:1082400017171616151616151615151716161616CF +:1082500016161716161616161616161616151515C0 +:1082600016161516161616161616161616161615B0 +:1082700015151515161516151616161616161616A4 +:108280001615151515151515151516161616161598 +:108290001616161515151615161515151615161686 +:1082A0001616161616161515161516151515161674 +:1082B0001616161616161615151515151515151567 +:1082C0001616161616161616161515151516161553 +:1082D0001515161616161615161616151515151546 +:1082E0001515161516151616161616161615151535 +:1082F0001515151515161616161616161616161524 +:10830000151515151515151616151515151515151B +:108310001515151515151515151616161516161607 +:1083200016161616151515151615161616161516F3 +:1083300016151616161515151515151515151615E8 +:1083400016161616161616151516151515151615D4 +:1083500016161616161616161616151515151515C3 +:1083600015151616161616161616161615151515B3 +:1083700016151516161615161616161616151515A3 +:108380001515151515161616151616161516151695 +:10839000151616151616161616161616161616167F +:1083A0001515161515151616161616161616161672 +:1083B000161616161616161616161716161616165C +:1083C0001616161616151615161516151616161651 +:1083D000161616161616151616161616161616163E +:1083E0001616161516161616151516161516161631 +:1083F0001616151515151515151515151616161627 +:108400001616161616151616151515151515151614 +:1084100016161616161616161616161616161516FD +:1084200015161515151616161616161616161616F0 +:1084300016161616161616161617161616161616DB +:1084400016161616161616161616161616161616CC +:1084500016161616161616161616161616161616BC +:1084600015161616151616151616161616161616AF +:10847000161616161616161616161616161616169C +:10848000161715161616161615151616161616168E +:10849000161616171616161616161616161616167B +:1084A000161616161616161615161616161616166D +:1084B000161716161616171716151516161616165B +:1084C000161616161616161616171616161616164B +:1084D0001616161716161616161616161717161639 +:1084E000161616161615151515151616161617172F +:1084F0001616161616161615151515161615151523 +:108500001716161616161616161515151515151511 +:108510001515151616161616161516151515161503 +:1085200015151515151616151616161516151515F5 +:1085300016151615151516161616161616161615E0 +:1085400015151515151515161516161616161616D3 +:1085500016151515151515151516161616161616C3 +:1085600015161615151515151515151616161616B4 +:1085700016161616161515151515151515151616A4 +:108580001616161616161615151515151515151594 +:108590001616151515151515151515151515151589 +:1085A0001516161615161616161616151515151572 +:1085B0001615151516161616161616161615151561 +:1085C0001515151515151615161616161616161553 +:1085D0001516151515151615161616161616161641 +:1085E0001616151615151515161616161616161630 +:1085F000161616161616151516151516161616161F +:108600001615161616151515151615151515151614 +:1086100016161716151616161616161615161616FB +:108620001A1A1A1A1A1B1A1A1B1B1B191A1A1A19A8 +:1086300019191A1A1A1A1A1A1A1B1B1A1A1A1A1A9A +:108640001A1A1A19191A1A1A1A1B1B1B1B1A1A1A88 +:108650001A191A191919191A1A1A1A1A1A1A1A1B7E +:108660001B1B1B1A1A1A1A1A191A1A1A1A1A1A1A68 +:108670001A1A1B1A1A1A1A1A1A19191A191A191A5D +:108680001A1A1A1B1B1A1A1A1A1A1A1A19191A1A4A +:10869000191A1A1A1A1B1B1A1A1A1A191A1A1A1A3A +:1086A000191A1A1A1A1A1B1A1A1A1A1A1A1A1A1A2A +:1086B0001A1A1A1B1A1A1A1B1B1B1C1B1B1B1B1A10 +:1086C0001A1A1A1A1A1A191A1A1A1B1B1B1A1A1A08 +:1086D0001A1A19191A1A1A1A1A1A1A1B1B1B1B1BF7 +:1086E0001B1B1B1A1A191A1A1A1A1B1A1A1B1B1BE4 +:1086F0001B1B1A1B1A1A19181A1A1A1B1A1A1A1BD8 +:108700001B1C1B1B1B1B1B1A1A191A1A1A1A1A1AC2 +:108710001A1B1B1C1C1B1B1B1B1B1A1A1A1A1A1AAE +:108720001A1A1B1B1B1C1B1B1B1B1B1A1A1A1A1A9F +:108730001A1A1B1B1A1B1B1C1C1C1C1B1B1B1A1A8A +:108740001B1A1A1A1A1B1B1B1B1C1C1B1B1B1B1A7C +:108750001B1B1A1A1A1A1B1A1B1B1B1D1B1B1B1B6C +:108760001B1A1B1A1A1A1A1B1B1C1C1B1C1A1A1A5E +:108770001A1A1A1919191A1A1A1B1B1C1B1C1C1A53 +:108780001A1A191A1A1A19191A1A1B1B1B1B1B1B46 +:108790001B1A1A1A1A1A1A1919191A1A1A1A1B1A3A +:1087A0001B1B1B1A1A1A1A191A1919191A1A1A1B29 +:1087B0001B1B1B1B1C1B1A1A1A1A1A1A19191A1A14 +:1087C0001B1B1B1B1B1C1C1A1A1A1A1A1A1A191902 +:1087D0001A1A1B1B1B1B1B1B1B1B1A1A1A1A1A1AF1 +:1087E000191A1B1A1A1B1B1B1B1B1C1A1B1A1A1AE1 +:1087F0001A1A1A191B1B1B1B1C1C1C1C1C1A1A1ACC +:108800001A1A1A1919191C1B1B1B1B1C1B1C1C1BBD +:108810001A1A1A1A1A1919191B1B1B1B1B1B1B1BB3 +:108820001C1B1B1B1A1A1A1A1A1A1B1B1B1B1B1C9C +:108830001C1C1C1B1B1B1B1B1B1A1A1A1B1A1B1B89 +:108840001B1B1B1B1C1B1B1B1B1B1A1A1A191B1A7D +:108850001B1C1B1B1C1C1C1B1B1B1B1A1A1B1A1969 +:108860001B1B1B1C1C1C1C1C1C1C1B1B1B1A1B1A53 +:108870001A1A1A1B1B1C1C1C1C1C1C1C1B1B1B1A45 +:108880001B1A191A1B1A1B1B1B1B1C1C1C1C1B1B39 +:108890001B1A1A1A1A1B1A1B1A1B1C1B1B1C1C1C2A +:1088A0001C1B1A1B1B1A1A1A1B1B1C1C1C1D1D1C13 +:1088B0001C1D1C1D1C1D1B1C1C1D1B1C1C1C1C1DF5 +:1088C0001C1D1D1E1D1D1C1C1C1C1C1C1B1D1C1CE2 +:1088D0001D1D1D1D1D1D1D1C1D1B1C1B1C1C1B1CD3 +:1088E0001C1C1D1D1D1D1D1D1C1D1D1D1C1C1C1CBF +:1088F0001D1C1B1C1C1D1C1D1D1D1D1C1C1D1C1CB2 +:108900001C1B1C1C1B1C1B1C1C1C1C1D1D1D1D1DA5 +:108910001E1D1D1C1C1C1C1C1C1D1C1D1C1D1D1D8E +:108920001D1D1D1C1C1C1D1D1C1D1C1D1D1D1D1D7C +:108930001D1D1D1C1C1C1C1C1E1C1D1D1D1D1D1D6C +:108940001D1E1E1D1E1D1D1E1C1C1D1C1C1C1D1D58 +:108950001D1D1E1D1D1C1D1D1D1D1C1A1C1D1C1D4D +:108960001C1D1D1D1E1E1E1D1E1D1E1D1C1B1C1C38 +:108970001C1D1D1D1D1D1D1D1D1D1D1D1D1C1C1C2B +:108980001C1D1D1C1D1D1D1E1D1E1E1D1E1D1E1C15 +:108990001C1D1C1C1C1C1D1D1D1E1D1E1E1E1D1E07 +:1089A0001F1D1C1D1C1C1C1C1D1D1D1D1D1E1E1EF7 +:1089B0001E1F1E1D1D1C1D1D1C1D1D1E1D1D1D1FE2 +:1089C0001E1F1E1E1F1E1D1C1D1D1D1D1D1D1D1DD0 +:1089D0001E1F1F1F1E1E1F1D1D1D1D1C1D1D1D1DBD +:1089E0001E1D1D201F1E1E1F1E1D1D1E1C1C1D1DAD +:1089F0001E1E1E1E1F1D1D1C1D1D1D1C1C1D1C1EA4 +:108A00001E1E1F1E1F1F1E1C1D1E1D1C1D1D1C1B90 +:108A10001D1C1D1D1E1D1F1E1E1D1D1D1D1C1D1C84 +:108A20001C1B1D1C1C1D1E1D1E1E1F1D1D1D1D1C77 +:108A30001C1C1C1C1E1C1C1D1E1E1E1E1E1E1E1D64 +:108A40001E1D1D1C1B1C1D1D1E1E1E1E1E1E1E1D52 +:108A50001C1D1D1D1C1C1B1D1C1C1D1E1D1E1E1E49 +:108A60001E1D1C1C1C1D1C1C1B1D1E1D1C1E1D1E3A +:108A70001E1E1E1D1D1D1D1D1D1C1C1D1E1D1D1E23 +:108A80001E1E1E1E1E1C1C1D1D1C1C1C1C1D1E1E15 +:108A90001E1E1E1E1E1E1F1D1D1C1D1D1C1C1C1C03 +:108AA0001D1D1E1D1E1E1E1E1E1E1E1D1D1D1C1CF0 +:108AB0001D1D1E1E1E1E1E1E1F1E1E1E1E1D1E1DD9 +:108AC0001D1D1D1C1D1E1D1E1E1D1E1E1E1E1D1DD0 +:108AD0001D1D1D1C1D1D1D1D1E1E1E1E1E1F1F1EBD +:108AE0001E1E1D1C1D1C1D1D1F1E1E1F1E1E1E1FAB +:108AF000201E1E1E1D1D1E1D1D1D1F1E1D1E1E1E99 +:108B00001F201F1E1E1D1D1D1E1D1D1D1F1E1E1E86 +:108B10001E1E1E1E1E1E1E1E1D1E1D1D1D1E1F1E78 +:108B20001D1F1E1E1E1E1E1F1F1F1F1E1F1E1E1C62 +:108B300005020101F401D00700000000240210002A +:108B400000063B5900000000B0568EEE44230000A2 +:108B5000EB1E00000C1F00002D1F00004E1F000028 +:108B60006F1F000000000000000000001B03000059 +:108B70002088410AE6A00400000000000000000078 +:108B800000000000002800002020202020202020BD +:108B90002020000000000000010000000000000094 +:108BA000000000000000000000000000D21F3E2076 +:108BB0006A20302105224E21F621F52200B8C30794 +:108BC000D638000000000000000010055805A00580 +:108BD000E80500001040040D0F0B0D0D10000E11E4 +:108BE000A5BB031F7EF80F00130F130F0F430F4396 +:108BF0001B0300000A00000000000000000000004D +:108C0000000000000000000000040000030000005D +:108C10000000000000000000000000000200000052 +:108C20000000000000000000000000000000000044 +:108C3000D21F3E206A20302105224E21F621F52246 +:108C400000B8C307D6380000000000000000000094 +:108C500048009000D80000001040040D0F0B0D0DCF +:108C600010000E11A5BB031F7EF80F00130F130F8A +:108C70000F430F431B0300002088410AE6A00400B5 +:108C800000000000000000000000000000280000BC +:108C9000272727272727272727270000000000004E +:108CA00063666666666666666666000000000000CB +:108CB00000000000D21F3E206A20302105224E21F4 +:108CC000F621F52200B8C307D638000000000000E6 +:108CD000000010055805A005E80500001040040D2F +:108CE0000F0B0D0D10000E11A5BB031F7EF80F001A +:108CF000130F130F0F430F431B0300008B35F72097 +:108D00000000000000000000000000000000000063 +:108D100000180000202020000000000000000000DB +:108D20000000000011111100000000000000000010 +:108D30000000000000000000D21F3E206A20302109 +:108D400005224E21F621F52200B8C307D6380000CF +:108D5000000000000000000048009000D800000063 +:108D60001040040D0F0B0D0D10000E11A5BB031FBD +:108D70007EF80F00130F130F0F430F431B03000068 +:108D80008B35F7200A000000000000000000000002 +:108D900000000000001C000027272705000000003D +:108DA0000000000000000000333333020000000028 +:108DB000000000000000000000000000D21F3E2064 +:108DC0006A20302105224E21F621F52200B8C30782 +:108DD000D6380000000000000000000048009000AD +:108DE000D80000001040040D0F0B0D0D10000E11E7 +:108DF000A5BB031F7EF80F00130F130F0F430F4384 +:108E00000000000000000000000000000000000062 +:108E10000000000000000000000000000000000052 +:108E20000000000000000000000000000000000042 +:108E30000000000000000000000000000000000032 +:108E40000000000000000000000000000000000022 +:108E50000000000000000000000000000000000012 +:108E60000000000000000000000000000000000002 +:108E700000000000000000000000000000000000F2 +:108E800000000000000000000000000000000000E2 +:108E900000000000000000000000000000000000D2 +:108EA00000000000000000000000000000000000C2 +:108EB00000000000000000000000000000000000B2 +:108EC00000000000000000000000000000000000A2 +:108ED0000000000000000000000000000000000092 +:108EE0000000000000000000000000000000000082 +:108EF0000000000000000000000000000000000072 +:108F0000000000000000000000000000090901004E +:108F10000128000000D8030012000000A51D020077 +:108F200000000000000003020228000000D8030037 +:108F300011000000A61D0000000000000101030256 +:108F40000328000000D8030010000100A71D000046 +:108F500000000000020203020428000000D8030001 +:108F60000F000200A81D0000000000000303030220 +:108F70000528000000D803000E000300A91D000012 +:108F800000000000040403020628000000D80300CB +:108F90000D000400AA1D00000000000005050302EA +:108FA0000728000000D803000C000500AB1D0000DE +:108FB00000000000060603020828000000D8030095 +:108FC0000B000600AC1D00000000000007070302B4 +:108FD0000928000000D803000A000700AD1D0000AA +:108FE00000000000080803020A28000000D803005F +:108FF00009000800AE1D0000000000000A09010081 +:109000000028000000D8030092148014A51D000061 +:1090100000000000090901000028000000D803003A +:1090200012000000A51D0200000000000909010057 +:109030000028000000D80300A2009000A61D020036 +:1090400000000000090901000028000000D803000A +:1090500032012001A71D02000000000009090100E3 +:109060000028000000D80300C201B001A81D0200C2 +:1090700000000000090901000028000000D80300DA +:1090800052024002A91D020000000000090901006F +:109090000028000000D80300E202D002AA1D02004E +:1090A00000000000090901000028000000D80300AA +:1090B00092148014000002000F00000005B40500A7 +:1090C0005D4C1B00610000000C0000000500040066 +:1090D0001529000060000000000000000D004000A5 +:1090E000152900001E000000030000000DFC4300D5 +:1090F000FFFE1B001F000000000000000DFC4300ED +:10910000FFFE1B001F000000030000000DB4410023 +:109110005D4C1B001F000000000000000DB441006A +:109120005D4C1B001F0000000F00000001B4050093 +:109130005D4C1B00E10001000C0000000100040078 +:1091400015290000E0000100000000000D004000B3 +:10915000152900001E0000000F00000005FC07009C +:10916000FFFE1B006100000053579FAE558E8381A8 +:109170009F8E8887977D879271998B958279969833 +:109180001E1D1C1D1D1D1D1D1D1C1D1C1D1C1C1D13 +:109190001D1D1D1E1D1D1D1D1D1D1C1D1D1D1D1DFF +:1091A0001D1D1D1E1D1D1D1D1D1D1D1D1E1D1C1DEE +:1091B0001D1D1C1D1D1D1C1D1C1C1D1D1C1D1D1DE4 +:1091C0001D1D1D1D1D1D1D1D1D1D1C1D1C1D1D1DD1 +:1091D0001D1C1D1C1D1C1C1D1D1D1D1D1D1D1D1DC3 +:1091E0001C1D1C1D1D1D1D1D1D1D1D1E1C1C1D1DB2 +:1091F0001D1D1D1D1D1D1C1D1D1D1C1D1D1D1C1DA2 +:109200001C1C1D1D1C1D1D1D1D1D1D1D1D1D1D1D91 +:109210001D1D1C1D1D1D1D1D1D1C1D1C1D1C1C1D83 +:109220001D1D1D1D1D1D1D1D1C1D1C1D1D1D1D1D70 +:109230001D1D1D1E1C1C1D1D1D1D1D1D1D1D1C1D60 +:109240001D1D1C1D1D1D1C1D1D1C1D1D1C1D1D1D52 +:109250001D1D1D1D1D1D1D1D1D1D1C1D1C1D1D1D40 +:109260001D1C1D1C1D1C1C1D1D1D1D1D1D1C1D1D33 +:109270001C1D1C1D1D1D1D1D1D1D1D1E1C1C1D1D21 +:109280001D1D1D1D1D1D1C1D1D1D1C1D1D1D1C1D11 +:109290001C1C1D1D1C1D1D1D1D1D1D1D1D1D1D1D01 +:1092A000FF7E8D986E749899646B969A5B5F9AA115 +:1092B0005B5AA6AE5152AD8A1C1D1C1D1D1D1D1DE5 +:1092C0001D1D1D1E1C1C1D1D1D1D1D1D1D1D1C1DD0 +:1092D0001D1D1C1D1D1D1C1C1D1D1D1D1C1D1D1DC2 +:1092E0001D1D1D1D1D1D1D1D1D1D1C1D1C1D1D1DB0 +:1092F0001D1C1D1C1D1C1C1D1D1D1D1E1D1C1D1DA2 +:109300001C1D1D1D1D1D1D1D1D1D1D1E1C1C1D1D8F +:109310001D1D1D1D1D1D1C1E1D1D1C1D1D1D1C1D7F +:109320001D1D1D1D1C1D1D1D1D1D1D1D1D1D1D1D6E +:109330001D1D1C1D1C1D1D1D1D1C1D1C1D1C1C1D63 +:109340001D1D1D1E1D1D1D1D1C1D1C1D1D1D1D1D4E +:109350001D1D1D1E1C1D1D1D1D1D1D1D1D1D1C1E3D +:109360001E1D1C1D1E1D1C1D1D1D1D1D1D1D1D1D2D +:109370001E1D1D1D1E1D1D1D1E1D1C1D1D1D1D1D1B +:109380001E1C1D1C1D1C1D1D1D1D1D1E1D1D1D1D0E +:109390001D1D1D1D1E1D1D1D1D1D1E1E1C1D1D1DFB +:1093A0001D1D1E1D1D1D1D1E1E1E1E1E1E1E1E1EE3 +:1093B0001E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1ECD +:1093C0001E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EBD +:1093D0001E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EAD +:1093E0001E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E9D +:1093F000323232323232323232323232323232324D +:10940000323232323232323232323232323232323C +:10941000323232323232323232323232323232322C +:10942000323232323232323232323232323232321C +:10943000323232323232323235358B3534353435A0 +:1094400035353535353533363535353533353535CF +:1094500035353535353535353434353535353535BE +:1094600033343335333434353333353634353535B9 +:109470003535353633333536333536353373353761 +:10948000B66DB66DB605B60500000000B66DB66DDA +:10949000B60CB60C00000000B66DB66D960D960DBC +:1094A00000000000B66DB66DB20DB20D00000000F8 +:1094B000B62DB62DB60DB60D00000000B665B6652A +:1094C000B60DB60D00000000B66CB66CB60DB60D4C +:1094D00000000000966D966DB60DB60D0000000000 +:1094E000B26DB26DB60DB60D00000000922492244C +:1094F000920492040000000001100000000000002F +:1095000000000000FFFF3DDB38D4FC020200FF003A +:109510006C768A94DB060000040C0000A003570060 +:1095200036E60802010000003E03E600477EEC1428 +:10953000FFFF00801C080C570380BBBB8044220047 +:109540006415641588398A3935003500011000002A +:109550000000000000000000FFFF3DDB38D4FC02EB +:109560000200FF006C768A94DB060000040C000009 +:10957000A003570036E60802410002003E03E60061 +:10958000477EEC14FFFF00801C080C17E38EBBBB6A +:10959000805522006415641588398A3935003500F4 +:1095A00001040000000000000000000000000000B6 +:1095B000000000020200FF006C768A94DB060000C7 +:1095C000040C000024055700364709020100000082 +:1095D000C2044701477EEC14FFFF00801C040C57B7 +:1095E0000380BBBB804522006415641588398A3925 +:1095F000350035008304020001020304E0EC37FB70 +:10960000528BE4C5CF0304021E0600036C768A94D5 +:10961000DB060000014500008C0E000000EC080293 +:10962000410002000000EC00477EEC14FFFF0080C8 +:109630001C5C11970080BBBB0057220064D164D131 +:1096400088198A19350035008304020001010101DF +:10965000E0EC37FB528BE4C5CF03040202060000A6 +:109660006C768A94DB060000014500008C0E000039 +:1096700000EC0802410002000000EC00437D531A98 +:10968000FFFF00801C5C11BF0080BBBB00462200B6 +:1096900064D164D188398A393500350083040200E9 +:1096A00002020202E0EC37FB528BE4C5CF03040256 +:1096B000020600006C768A94DB060000014500007B +:1096C0008C0E000000EC0802410002000000EC00DB +:1096D000A87D6018FFFF00801C5C11BF0080BBBB31 +:1096E0000046220064D164D188398A3935003500BA +:1096F0008304020003030303E0EC37FB528BE4C551 +:10970000CF030402020600006C768A94DB06000098 +:10971000014500008C0E000000EC08024100020030 +:109720000000EC006C7E0614FFFF00801C5C11BF83 +:109730000080BBBB0046220064D164D188398A39DD +:10974000350035008304020004040404E0EC37FB18 +:10975000528BE4C5CF030402020600006C768A94A3 +:10976000DB060000014500008C0E000000EC080242 +:10977000410002000000EC00ED7E8610FFFF00803B +:109780001C5C11BF0080BBBB0046220064D164D1C9 +:1097900088398A393500350000005D3F0000DA471E +:1097A000C0CED0C716219CD1548694083C0E0F061B +:1097B00079CACDFCD820EF99FACECFC5FD962E51AF +:1097C0005361DF9F3B0F0F04F43CFA883C803CD48C +:1097D000390F0E03124C4001155870011864A00196 +:1097E0001B70D0011E7C0002218830020004200082 +:1097F00003105000061C80000928B0000C34E00063 +:109800000F40100123881002207CE0011D70B00180 +:109810001A64800117585001144C200135D03003D0 +:1098200032C400032FB8D0022CACA00229A07002D1 +:1098300026944002445985167A31E619B009471D2D +:10984000E6E1A7201CBA082452926927004840028A +:109850003620A1056CF80109A2D0620CD8A8C30F6C +:109860000E8124133281E410FCA8830DC6D0220A95 +:1098700090F8C1065A2061032448000076922925F9 +:1098800040BAC8210AE2671ED409071B9E31A617F9 +:10989000685945147692292540BAC8210AE2671E04 +:1098A000D409071B9E31A617685945143281E4106C +:1098B000FCA8830DC6D0220A90F8C1065A20610385 +:1098C000244800007796392541BED8210BE6771E43 +:1098D000D50D171B9F35B617695D55143385F410E8 +:1098E000FDAC930DC7D4320A91FCD1065B24710301 +:1098F000254C100085CE19264FF6B822191E581F88 +:10990000E345F71BAD6D96187795351541BDD4111C +:109910000BE5730ED50C130B9F34B207695C510431 +:109920003384F000789A492542C2E8210CEA871E68 +:10993000D611271BA039C6176A6165143489041132 +:10994000FEB0A30DC8D8420A9200E2065C2881034B +:109950002650200084CA09264EF2A822181A481F51 +:10996000E241E71BAC6986187691251540B9C41110 +:109970000AE1630ED408030B9E30A2076858410425 +:109980003280E000799E592543C6F8210DEE971EDE +:10999000D715371BA13DD6176B657514358D14117E +:1099A000FFB4B30DC9DC520A9304F2065D2C910397 +:1099B0002754300083C6F9E54DEE98E21716381F9C +:1099C000E13DD71BAB6576D8758D15153FB5B41144 +:1099D00009DD530ED304F30A9D2C9207675431041A +:1099E000317CD0007AA2692544CA08220EF2A71E53 +:1099F000D819471BA241E6176C69851436912411CA +:109A000000B9C30DCAE0620A940802075E30A103E0 +:109A10002858400082C2E9254CEA88221612281FE5 +:109A2000E039C71BAA616618748905153EB1A411F7 +:109A300008D9430ED200E30A9C288207665021040D +:109A40003078C0007BA6792545CE18220FF6B71EC8 +:109A5000D91D571BA345F6176D6D95143795341115 +:109A600001BDD30DCBE4720A950C12075F34B1032C +:109A7000295C500081BED9254BE67822150E181FAF +:109A8000DF35B71BA95D56187385F5143DAD9411EC +:109A900007D5330ED1FCD20A9B247207654C110402 +:109AA0002F74B0007CAA892546D2282210FAC71E3E +:109AB000DA21671BA44906186E71A5143899441160 +:109AC00002C1E30DCCE8820A961022076038C10378 +:109AD0002A60600080BAC9254AE26822140A081F79 +:109AE000DE31A71BA85946187281E5143CA98411E0 +:109AF00006D1230ED0F8C20A9A20620764480104F6 +:109B00002E70A0007DAE992547D6382211FED71EB3 +:109B1000DB25771BA54D16186F75B514399D5411AB +:109B200003C5F30DCDEC920A97143207613CD103C3 +:109B30002B6470007FB6B92549DE58221306F81E43 +:109B4000DD2D971BA7553618717DD5143BA57411D3 +:109B500005CD130ECFF4B20A991C52076344F103EA +:109B60002D6C90007EB2A92548DA48221202E81E28 +:109B7000DC29871BA65126187079C5143AA16411F7 +:109B800004C9030ECEF0A20A981842076240E1030E +:109B90002C688000000000000000000000000000B1 +:109BA00000000000000000000000000000000000B5 +:109BB00000000000000000000000000000000000A5 +:109BC0000000000000000000000000000000000095 +:109BD0000000000000000000000000000000000085 +:109BE0000000000000000000000000000000000075 +:109BF0000000000000000000000000000000000065 +:109C00000000000000000000000000000000000054 +:109C10000000000000000000000000000000000044 +:109C20000000000000000000000000000000000034 +:109C30000000000000000000000000000000000024 +:109C40000000000000000000000000000000000014 +:109C50000000000000000000000000000000000004 +:109C600000000000000000000000000000000000F4 +:109C700000000000000000000000000000000000E4 +:109C800000000000000000000000000000000000D4 +:109C900000000000000000000000000000000000C4 +:109CA00000000000000000000000000000000000B4 +:109CB00000000000000000000000000000000000A4 +:109CC0000000000000000000000000000000000094 +:109CD0000000000000000000000000000000000084 +:109CE0000000000000000000000000000000000074 +:109CF0000000000000000000000000000000000064 +:109D00000000000000000000000000000000000053 +:109D10000000000000000000000000000000000043 +:109D20000000000000000000000000000000000033 +:109D30000000000000000000000000000000000023 +:109D40000000000000000000000000000000000013 +:109D50000000000000000000000000000000000003 +:109D600000000000000000000000000000000000F3 +:109D700000000000000000000000000000000000E3 +:109D800000000000000000000000000000000000D3 +:109D900000000000000000000000000000000000C3 +:109DA00000000000000000000000000000000000B3 +:109DB00000000000000000000000000000000000A3 +:109DC0000000000000000000000000000000000093 +:109DD0000000000000000000000000000000000083 +:109DE0000000000000000000000000000000000073 +:109DF0000000000000000000000000000000000063 +:109E00000000000000000000000000000000000052 +:109E10000000000000000000000000000000000042 +:109E20000000000000000000000000000000000032 +:109E30000000000000000000000000000000000022 +:109E40000000000000000000000000000000000012 +:109E50000000000000000000000000000000000002 +:109E600000000000000000000000000000000000F2 +:109E700000000000000000000000000000000000E2 +:109E800000000000000000000000000000000000D2 +:109E900000000000000000000000000000000000C2 +:109EA00000000000000000000000000000000000B2 +:109EB00000000000000000000000000000000000A2 +:109EC0000000000000000000000000000000000092 +:109ED0000000000000000000000000000000000082 +:109EE0000000000000000000000000000000000072 +:109EF0000000000000000000000000000000000062 +:109F00000000000000000000000000000000000051 +:109F10000000000000000000000000000000000041 +:109F20000000000000000000000000000000000031 +:109F300009F61224380460090E0A00010100081213 +:109F4000240038046C090000000C00000000000030 +:109F500000004B5900000000000000000009010A49 +:109F600000013C4388020000281E21000008FC007C +:109F70000008FC000008FC000008FC000008FC00D1 +:109F80000008FC000008FC000008FC000000FC00C9 +:109F90000008FC000008FC000008FC000000FC00B9 +:109FA0000008FC000008FC000008FC0000000000A5 +:109FB000000101000000000000000000000000009F +:109FC000000000000000000000000101010101008C +:109FD0000001010101000101010100010000010077 +:109FE00001000000000000000F0000000107010355 +:109FF00002030A00320A400000003200370000006D +:10A000000000000000000000000000000000000050 +:10A010000000000000000000C800C8009600C80052 +:10A020000707800080000505000000000000000018 +:10A0300007010000DBFF00004100F1FF10001400E9 +:10A04000F9FFC4FFFF7FFF7FFF7FFF7F96002C019A +:10A0500096003C000A04CECE3232280500000000F3 +:10A0600000071600002416000000001224242424F7 +:10A0700024242424242424242424242424240000E8 +:10A0800000000000000000000000000000000000D0 +:10A090000A05000A0000000020010014111400004D +:10A0A00000000000000000000000000000000000B0 +:10A0B000000000000F23283C465000006E696664D3 +:10A0C0005050505008000000000000000F23283CB2 +:10A0D000465000006E696664505050500F141E28A0 +:10A0E000000000000A0A0A0A0A0A0A0A0F1E32467B +:10A0F00000000000645F553C3C3C3C3C000000001C +:10A1000008081A00A000EAFF15009D008300100E49 +:10A1100000000000001000003C0032009001280008 +:10A120000F000F001C023D011C02740400003704E4 +:10A1300000005F09F4010000370400005F093214D9 +:10A14000021E1E3202009B00280028007700C00378 +:10A150007700E8080000000038043000200001000B +:10A16000220000003A00520070008F00AF00CF00C4 +:10A17000EF000F012E014F016E018E01AD01CE01E6 +:10A18000EC010F022D024D026D028D02AC02CC02D9 +:10A19000EB020B032B034A036A038903AA03C903D7 +:10A1A000E703FF0337040000000000000000000088 +:10A1B000000000000000000000000000000000009F +:10A1C000000000000000000000000000000000008F +:10A1D000000000000000000000000000000000007F +:10A1E000000000000000000000000000000000006F +:10A1F000000000000000000000000000000000005F +:10A20000000000000000000000000000000000004E +:10A21000000000000000000000000000000000003E +:10A22000000000000000000000006C093000460043 +:10A230000100480000003C00430066008500A900C2 +:10A24000C800E90009012A0149016B018901AB013C +:10A25000C901EB0109022B024A026C028A02AC021C +:10A26000CA02EC020B032D034B036D038B03AE03F9 +:10A27000CB03EE030C042F044C046F048B04AF04D7 +:10A28000CC04EF040D0530054D0570058D05B005B6 +:10A29000CD05F1050D0630064E0672068E06B10696 +:10A2A000CE06F2060F073207500773079007B30771 +:10A2B000D107F40711083408520875089108B1084D +:10A2C000C608E708000000000000000000000000D1 +:10A2D000000000000000000000000000000000007E +:10A2E000000000000000000000000000000000006E +:10A2F000000000000000000000000000000000005E +:10A3000002020500F16C0000409C000000F91500FD +:10A3100029B1010010270000C4090000010101015A +:10A32000010101010101014B0F004B000000000081 +:10A33000020101010101010101010100F16C0000B4 +:10A340000200000084DE0100000000000F0F0A0A76 +:10A3500028000000000000000F0F1414010101018B +:10A36000010140003200E8030F0008000500E10091 +:10A3700000001E288C00B40019006400640028004E +:10A380007800000000000000B4007800E8034006F8 +:10A3900000000001410100000000000068010D0DF7 +:10A3A0000A093C0019006400140064002C016400D8 +:10A3B0002C010F02E8E8F800F8000804190000007A +:10A3C000DB00ED0000011401290140015801720178 +:10A3D0008D01A901C801E8010A022D0252027A0288 +:10A3E000A302CE02FB022A035C038F03C503FD0315 +:10A3F00036047304B104F10434057805BF0508067A +:10A400005306A006EF063F079207E6073B089308AE +:10A41000EB084509A009FC09580AB60A140B720B8F +:10A42000D10B2F0C8D0CEB0C490DA50D010E5B0E05 +:10A43000B40E0C0F610FB50F06105510A110EA10E5 +:10A4400031117411B411F01128125D128D12B9126C +:10A45000E112051324133E1354136513711378137B +:10A460007B13DB00ED0000011401290140015801BC +:10A4700072018D01A901C801E8010A022D025202F0 +:10A480007A02A302CE02FB022A035C038F03C503F8 +:10A49000FD0336047304B104F10434057805BF05E7 +:10A4A00008065306A006EF063F079207E6073B089B +:10A4B0009308EB084509A009FC09580AB60A140BD1 +:10A4C000720BD10B2F0C8D0CEB0C490DA50D010E51 +:10A4D0005B0EB40E0C0F610FB50F06105510A110D6 +:10A4E000EA1031117411B411F01128125D128D129D +:10A4F000B912E112051324133E135413651371139B +:10A5000078137B136A00750081008E009D00AC00FB +:10A51000BD00CF00E200F7000D01260140015C0103 +:10A5200079019901BC01E001060230025B02890257 +:10A53000BA02EE0224035D039A03D9031B046004EC +:10A54000A904F40443059505E90541069C06FA06AD +:10A550005B07BE0724088D08F8086509D409450A79 +:10A56000B80A2D0BA20B190C900C080D800DF80DDC +:10A570006F0EE60E5C0FD00F4210B31021118C113C +:10A58000F4115912BA1217137013C41313145D1473 +:10A59000A114E01418154B1577159C15BB15D4158F +:10A5A000E515EF15F3156A00750081008E009D001A +:10A5B000AC00BD00CF00E200F7000D012601400114 +:10A5C0005C0179019901BC01E001060230025B02E5 +:10A5D0008902BA02EE0224035D039A03D9031B0425 +:10A5E0006004A904F40443059505E90541069C06A9 +:10A5F000FA065B07BE0724088D08F8086509D40928 +:10A60000450AB80A2D0BA20B190C900C080D800DF1 +:10A61000F80D6F0EE60E5C0FD00F4210B310211133 +:10A620008C11F4115912BA1217137013C4131314A6 +:10A630005D14A114E01418154B1577159C15BB1566 +:10A64000D415E515EF15F315550055004B004700DF +:10A65000000000004B007D00DC001400050000003D +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000009000000B1 +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A93000050201010000000000000000240104776E +:10A940000001365900000000000000000000000077 +:10A950006726000088260000A92600001A030000D0 +:10A96000410C520C07250000000000000000000010 +:10A97000000000000024000031313131252020206A +:10A980002020000000000000000000000000000087 +:10A99000000000000000000000000000CA2642275E +:10A9A00066272C28492968283A29392A00B8C3077C +:10A9B0007E17000000000000000010055805A005EB +:10A9C000E80500001040040C0E0B0C0C10000E10DB +:10A9D000A5BA031F7CC60F00100D100D0D410D41CF +:10A9E0001A0300008B35F720514E000000000000D4 +:10A9F00000000000000000000024000020202020B3 +:10AA0000252020202020000000000000111111113D +:10AA10001100000000000000000000000000000025 +:10AA2000CA26422766272C28492968283A29392A24 +:10AA300000B8843A7E1700000000000000001005F6 +:10AA40005805A005E80500001040040C0E0B0C0C86 +:10AA500090000E10A5BB831FFCC90F00100D100D38 +:10AA60000D410D411A0300008B35F72051C9090033 +:10AA700000000000000000000000000000280000AE +:10AA80002727272725272727272700000000000042 +:10AA900066666656660000000000000000000000C8 +:10AAA00000000000CA26422766272C28492968286A +:10AAB0003A29392A00B8C3077E17000000000000B9 +:10AAC000000010055805A005E80500001040040C22 +:10AAD0000E0B0C0C90000E10A5BB831FFCC90F00C1 +:10AAE000100D100D0D410D4100000000090901007D +:10AAF0000028000000A8030000000000A51D0200BF +:10AB000000000000000003020028000080AA0300EB +:10AB100009000000A61D0000000000000101030262 +:10AB20000028000080AA03000A000100A71D000001 +:10AB300000000000020203020028000080AA0300B7 +:10AB40000B000200A81D0000000000000303030228 +:10AB50000028000080AA03000C000300A91D0000CB +:10AB600000000000040403020028000080AA030083 +:10AB70000D000400AA1D00000000000005050302EE +:10AB80000028000080AA03000E000500AB1D000095 +:10AB900000000000060603020028000080AA03004F +:10ABA0000F000600AC1D00000000000007070302B4 +:10ABB0000028000080AA030010000700AD1D00005F +:10ABC00000000000080803020028000080AA03001B +:10ABD00011000800AE1D0000000000000913010074 +:10ABE0000028000000A8030000000000A51D0200CE +:10ABF00000000000000A03020028000080A80300F3 +:10AC000009000000A61D000000000000010B030267 +:10AC10000028000080A803000A000100A71D000012 +:10AC200000000000020C03020028000080A80300BE +:10AC30000B000200A81D000000000000030D03022D +:10AC40000028000080A803000C000300A91D0000DC +:10AC500000000000040E03020028000080A803008A +:10AC60000D000400AA1D000000000000050F0302F3 +:10AC70000028000080A803000E000500AB1D0000A6 +:10AC800000000000061003020028000080A8030056 +:10AC90000F000600AC1D00000000000007110302B9 +:10ACA0000028000080A8030010000700AD1D000070 +:10ACB00000000000081203020028000080A8030022 +:10ACC00011000800AE1D00000F000000018C0614EA +:10ACD0005D161B00610000000F000000016C0414F1 +:10ACE00030441B0061000000000000000D00401413 +:10ACF00064C700001E00000000000000290070145E +:10AD0000152900001E00000000000000296C7014CE +:10AD100030441B001F000000030000000D8C421493 +:10AD20005D161B001F00000000000000296C70145D +:10AD300030441B001F0000000F000000016C0414D1 +:10AD400030441B00E10001000C000000010004146D +:10AD500015290000E00001000000000000000000D4 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF0000000000000000000000000000000000051 +:10B000000000000000000000000000000000000040 +:10B010000000000000000000000000000000000030 +:10B020000000000000000000000000000000000020 +:10B030000000000000000000000000000000000010 +:10B040000000000000000000000000000000000000 +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700022492449240924050000000014492449D8 +:10B080002409A40800000000A44824492409140944 +:10B090000000000024452449240922090000000082 +:10B0A00024292429240924090000000024492445D6 +:10B0B00022092409000000002449A4481409240995 +:10B0C0000000000024491449A408240900000000DD +:10B0D00024492249240524090000000092249224D6 +:10B0E0009204920400000000B26DB66DB60DB60574 +:10B0F00000000000966DB66DB60DB60C00000000A5 +:10B10000B66CB66DB60D960D00000000B665B66D56 +:10B11000B60DB20D00000000B62DB62DB60DB60D61 +:10B1200000000000B66DB665B20DB60D000000005F +:10B13000B66DB66C960DB60D00000000B66D966D3E +:10B14000B60CB60D00000000B66DB26DB605B60DBA +:10B150000000000092249224920492040000000057 +:10B1600001280000000000000000000000000000B6 +:10B17000000000020206FF006C768A94DB060000E5 +:10B180000106000041015700363C090201000000A1 +:10B19000E1003C01477EEC14FFFF00801C7C0F5750 +:10B1A0000380BBBB8E5C22006401640188398A394C +:10B1B0000000000001280000000000000000000066 +:10B1C00000000000000000020206FF006C768A9476 +:10B1D000DB06000001060000F100570036EC080213 +:10B1E000010000009100EC00477EEC14FFFF00809E +:10B1F0001C040C570380ABAA804422006411641124 +:10B2000088398A3905000500012800000000000087 +:10B210000000000000000000000000020206FF0025 +:10B220006C768A94DB06000001060000610057007E +:10B23000365C08020100000001005C00477EEC144F +:10B24000FFFF00801C240C570380ABAA804422001F +:10B250006411641188398A3905000500012800004D +:10B2600000000000000000000000000000000002DC +:10B270000200FF006C768A94DB06000001060000E5 +:10B28000F100570036EC0802410002009100EC008A +:10B29000477EEC14FFFF00801CC40C17E38EBBBB81 +:10B2A000805522006411641188398A39050005002F +:10B2B0000104000000000000000000000000000089 +:10B2C000000000020200FF006C768A94DB0600009A +:10B2D000040C0000B803570036EC0802010000001F +:10B2E0005803EC00477EEC14FFFF00801CE00C5775 +:10B2F0000380BBBB804522006411641188398A3900 +:10B30000050005009404020001020304D6F042FC8B +:10B310001C6005AFCF0304021E0600036C768A94FE +:10B32000DB06000001C50000D20F000000EC08029F +:10B33000410002000000EC00477EEC14FFFF00809B +:10B340001CC411170080BBBB00572200641164119C +:10B3500088198A1905000500940402000101010101 +:10B36000D6F042FC1C6005AFCF03040202060000C9 +:10B370006C768A94DB06000001C50000D20F000045 +:10B3800000EC0802410002000000EC007278512B32 +:10B39000FFFF00801CC4113F0080BBBB00462200A1 +:10B3A0006411641188398A3905000500940402008B +:10B3B00002020202D6F042FC1C6005AFCF03040279 +:10B3C000020600006C768A94DB06000001C50000CE +:10B3D000D20F000000EC0802410002000000EC0067 +:10B3E000BB7BC520FFFF00801CC4113F0080BBBB9E +:10B3F000004622006411641188398A39050005006D +:10B400009404020003030303D6F042FC1C6005AF62 +:10B41000CF030402020600006C768A94DB0600006B +:10B4200001C50000D20F000000EC0802410002003C +:10B430000000EC00197EFC15FFFF00801CC4113FCA +:10B440000080BBBB004622006411641188398A3930 +:10B45000050005009404020004040404D6F042FC34 +:10B460001C6005AFCF030402020600006C768A94CC +:10B47000DB06000001C50000D20F000000EC08024E +:10B48000410002000000EC00867F080BFFFF0080F7 +:10B490001CC4113F0080BBBB004622006411641134 +:10B4A00088398A390500050000005D3F0000DA4751 +:10B4B000C0CED0C7FFFF47020000A1503F0D3009AA +:10B4C000FFFF244B00009F30FFCEF0C7FFFFDF3BA4 +:10B4D000000047E43F0F3004FFFFABCE0000C5790A +:10B4E0003F0F300220C208001080000340400106D8 +:10B4F00070000209A0C0020CD080030F00410412AA +:10B500003001051560C105189081061BC041071E5A +:10B51000F001082120C00004508001078040020A89 +:10B52000B000030DE0C00310108104134041051664 +:10B5300070010619A0C1061CD081071F0042082215 +:10B5400030020001445985167A31E619B009471DC9 +:10B55000E6E1A7201CBA082452926927004840025D +:10B560003620A1056CF80109A2D0620CD8A8C30F3F +:10B570000E8124133281E410FCA8830DC6D0220A68 +:10B5800090F8C1065A2061032448000076922925CC +:10B5900040BAC8210AE2671ED409071B9E31A617CC +:10B5A000685945147692292540BAC8210AE2671ED7 +:10B5B000D409071B9E31A617685945143281E4103F +:10B5C000FCA8830DC6D0220A90F8C1065A20610358 +:10B5D000244800007796392541BED8210BE6771E16 +:10B5E000D50D171B9F35B617695D55143385F410BB +:10B5F000FDAC930DC7D4320A91FCD1065B247103D4 +:10B60000254C100085CE19264FF6B822191E581F5A +:10B61000E345F71BAD6D96187795351541BDD411EF +:10B620000BE5730ED50C130B9F34B207695C510404 +:10B630003384F000789A492542C2E8210CEA871E3B +:10B64000D611271BA039C6176A6165143489041105 +:10B65000FEB0A30DC8D8420A9200E2065C2881031E +:10B660002650200084CA09264EF2A822181A481F24 +:10B67000E241E71BAC6986187691251540B9C411E3 +:10B680000AE1630ED408030B9E30A20768584104F8 +:10B690003280E000799E592543C6F8210DEE971EB1 +:10B6A000D715371BA13DD6176B657514358D141151 +:10B6B000FFB4B30DC9DC520A9304F2065D2C91036A +:10B6C0002754300083C6F9E54DEE98E21716381F6F +:10B6D000E13DD71BAB6576D8758D15153FB5B41117 +:10B6E00009DD530ED304F30A9D2C920767543104ED +:10B6F000317CD0007AA2692544CA08220EF2A71E26 +:10B70000D819471BA241E6176C698514369124119C +:10B7100000B9C30DCAE0620A940802075E30A103B3 +:10B720002858400082C2E9254CEA88221612281FB8 +:10B73000E039C71BAA616618748905153EB1A411CA +:10B7400008D9430ED200E30A9C28820766502104E0 +:10B750003078C0007BA6792545CE18220FF6B71E9B +:10B76000D91D571BA345F6176D6D951437953411E8 +:10B7700001BDD30DCBE4720A950C12075F34B103FF +:10B78000295C500081BED9254BE67822150E181F82 +:10B79000DF35B71BA95D56187385F5143DAD9411BF +:10B7A00007D5330ED1FCD20A9B247207654C1104D5 +:10B7B0002F74B0007CAA892546D2282210FAC71E11 +:10B7C000DA21671BA44906186E71A5143899441133 +:10B7D00002C1E30DCCE8820A961022076038C1034B +:10B7E0002A60600080BAC9254AE26822140A081F4C +:10B7F000DE31A71BA85946187281E5143CA98411B3 +:10B8000006D1230ED0F8C20A9A20620764480104C8 +:10B810002E70A0007DAE992547D6382211FED71E86 +:10B82000DB25771BA54D16186F75B514399D54117E +:10B8300003C5F30DCDEC920A97143207613CD10396 +:10B840002B6470007FB6B92549DE58221306F81E16 +:10B85000DD2D971BA7553618717DD5143BA57411A6 +:10B8600005CD130ECFF4B20A991C52076344F103BD +:10B870002D6C90007EB2A92548DA48221202E81EFB +:10B88000DC29871BA65126187079C5143AA16411CA +:10B8900004C9030ECEF0A20A981842076240E103E1 +:10B8A0002C68800000000000000000000000000084 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C24000F42C0100260C0000F42D01000000000079 +:10C25000F42C0100800900001A3A010000000000DF +:10C26000020000000000000001000000FFFFFFFFCF +:10C2700004000F0007000000000000110100000092 +:10C28000AA000000FFFFFFFF4040404040409001F7 +:10C290009001900190019001900190019001900116 +:10C2A00010001E00320023003200C70032003300AD +:10C2B0003C003C00900190019001900190019001A0 +:10C2C0000200201C01000000503D02000C3D020055 +:10C2D000503D0200103D0200AA00AA0002000F001B +:10C2E0001E000F003C0014007800780000000000E1 +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F0000009F61224380460090E0A000101000812F2 +:10F01000240038046C090000000C0000000000000F +:10F0200000004B5900000000000000000009010A28 +:10F0300000013C4388020000281E21000008FC005B +:10F040000008FC000008FC000008FC000008FC00B0 +:10F050000008FC000008FC000008FC000000FC00A8 +:10F060000008FC000008FC000008FC000000FC0098 +:10F070000008FC000008FC000008FC000000000084 +:10F08000000101000000000000000000000000007E +:10F09000000000000000000000000101010101006B +:10F0A0000001010101000101010100010000010056 +:10F0B00001000000000000000F0000000107010334 +:10F0C00002030A00320A400000003200370000004C +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000C800C8009600C80032 +:10F0F00007078000800005050000000000000000F8 +:10F1000007010000DBFF00004100F1FF10001400C8 +:10F11000F9FFC4FFFF7FFF7FFF7FFF7F96002C0179 +:10F1200096003C000A04CECE3232280500000000D2 +:10F1300000071600002416000000001224242424D6 +:10F1400024242424242424242424242424240000C7 +:10F1500000000000000000000000000000000000AF +:10F160000A05000A0000000020010014111400002C +:10F17000000000000000000000000000000000008F +:10F18000000000000F23283C465000006E696664B2 +:10F190005050505008000000000000000F23283C91 +:10F1A000465000006E696664505050500F141E287F +:10F1B000000000000A0A0A0A0A0A0A0A0F1E32465A +:10F1C00000000000645F553C3C3C3C3C00000000FB +:10F1D00008081A00A000EAFF15009D008300100E29 +:10F1E00000000000001000003C00320090012800E8 +:10F1F0000F000F001C023D011C02740400003704C4 +:10F2000000005F09F4010000370400005F093214B8 +:10F21000021E1E3202009B00280028007700C00357 +:10F220007700E808000000003804300020000100EA +:10F23000220000003A00520070008F00AF00CF00A3 +:10F24000EF000F012E014F016E018E01AD01CE01C5 +:10F25000EC010F022D024D026D028D02AC02CC02B8 +:10F26000EB020B032B034A036A038903AA03C903B6 +:10F27000E703FF0337040000000000000000000067 +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F000000000000000000000006C093000460023 +:10F300000100480000003C00430066008500A900A1 +:10F31000C800E90009012A0149016B018901AB011B +:10F32000C901EB0109022B024A026C028A02AC02FB +:10F33000CA02EC020B032D034B036D038B03AE03D8 +:10F34000CB03EE030C042F044C046F048B04AF04B6 +:10F35000CC04EF040D0530054D0570058D05B00595 +:10F36000CD05F1050D0630064E0672068E06B10675 +:10F37000CE06F2060F073207500773079007B30750 +:10F38000D107F40711083408520875089108B1082C +:10F39000C608E708000000000000000000000000B0 +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D00002020500F16C0000409C000000F91500DD +:10F3E00029B1010010270000C4090000010101013A +:10F3F000010101010101014B0F004B000000000061 +:10F40000020101010101010101010100F16C000093 +:10F410000200000084DE0100000000000F0F0A0A55 +:10F4200028000000000000000F0F1414010101016A +:10F43000010140003200E8030F0008000500E10070 +:10F4400000001E288C00B40019006400640028002D +:10F450007800000000000000B4007800E8034006D7 +:10F4600000000001410100000000000068010D0DD6 +:10F470000A093C0019006400140064002C016400B7 +:10F480002C010F02E8E8F800F80008041900000059 +:10F49000DB00ED0000011401290140015801720157 +:10F4A0008D01A901C801E8010A022D0252027A0267 +:10F4B000A302CE02FB022A035C038F03C503FD03F4 +:10F4C00036047304B104F10434057805BF05080659 +:10F4D0005306A006EF063F079207E6073B0893088E +:10F4E000EB084509A009FC09580AB60A140B720B6F +:10F4F000D10B2F0C8D0CEB0C490DA50D010E5B0EE5 +:10F50000B40E0C0F610FB50F06105510A110EA10C4 +:10F5100031117411B411F01128125D128D12B9124B +:10F52000E112051324133E1354136513711378135A +:10F530007B13DB00ED00000114012901400158019B +:10F5400072018D01A901C801E8010A022D025202CF +:10F550007A02A302CE02FB022A035C038F03C503D7 +:10F56000FD0336047304B104F10434057805BF05C6 +:10F5700008065306A006EF063F079207E6073B087A +:10F580009308EB084509A009FC09580AB60A140BB0 +:10F59000720BD10B2F0C8D0CEB0C490DA50D010E30 +:10F5A0005B0EB40E0C0F610FB50F06105510A110B5 +:10F5B000EA1031117411B411F01128125D128D127C +:10F5C000B912E112051324133E135413651371137A +:10F5D00078137B136A00750081008E009D00AC00DB +:10F5E000BD00CF00E200F7000D01260140015C01E3 +:10F5F00079019901BC01E001060230025B02890237 +:10F60000BA02EE0224035D039A03D9031B046004CB +:10F61000A904F40443059505E90541069C06FA068C +:10F620005B07BE0724088D08F8086509D409450A58 +:10F63000B80A2D0BA20B190C900C080D800DF80DBB +:10F640006F0EE60E5C0FD00F4210B31021118C111B +:10F65000F4115912BA1217137013C41313145D1452 +:10F66000A114E01418154B1577159C15BB15D4156E +:10F67000E515EF15F3156A00750081008E009D00F9 +:10F68000AC00BD00CF00E200F7000D0126014001F3 +:10F690005C0179019901BC01E001060230025B02C4 +:10F6A0008902BA02EE0224035D039A03D9031B0404 +:10F6B0006004A904F40443059505E90541069C0688 +:10F6C000FA065B07BE0724088D08F8086509D40907 +:10F6D000450AB80A2D0BA20B190C900C080D800DD1 +:10F6E000F80D6F0EE60E5C0FD00F4210B310211113 +:10F6F0008C11F4115912BA1217137013C413131486 +:10F700005D14A114E01418154B1577159C15BB1545 +:10F71000D415E515EF15F315550055004B004700BE +:10F72000000000004B007D00DC001400050000001C +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000900000090 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F860000000000000000000000000000000000098 +:10F870000000000000000000000000000000000088 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF000000000000000000000000000004E565409 +:020000022000DC +:1000000066665A4285CB2B43C3F500400C00B740CF +:100010000000000000000000000000000A000000D6 +:1000200000000000000000000000000000000000D0 +:10003000002492000000000020508B01907B0205FC +:1000400041525B14810B00000042525B14810B0093 +:10005000000043525B14810B00000046525B148188 +:100060000B00000047525B14810B000000000000F1 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:100100000000000000001101101500002002100185 +:1001100000003003000200008004000300004005DE +:10012000000400005006000000006007000000000E +:1001300070080000000090000000000000100100A6 +:100140000000022000000000030000000000040086 +:100150000000000005000000000006000000000094 +:100160000700000000000800000000000900000077 +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C00000000000000054140000000000000000C7 +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:00000001FF diff --git a/firmware/ndt_fw.bin.ihex b/firmware/ndt_fw.bin.ihex new file mode 100644 index 000000000000..c3b623bcbe67 --- /dev/null +++ b/firmware/ndt_fw.bin.ihex @@ -0,0 +1,1249 @@ +:10000000A55A0001100C00410020000000004D0026 +:10001000EFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:1000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:1000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:100100000813002081010000890100008B0100001C +:1001100000000000000000000000000000000000DF +:100120000000000000000000000000008D01000041 +:1001300000000000000000008F010000910100009D +:1001400093010000930100001D35000093010000A1 +:10015000930100000D240000AD0700009301000092 +:10016000930100009301000093010000930100003F +:10017000930100009301000093010000930100002F +:10018000930100009301000093010000930100001F +:10019000930100009301000093010000930100000F +:1001A00093010000930100009301000093010000FF +:1001B00093010000930100009301000093010000EF +:1001C00000F002F800F030F80CA030C8083824180D +:1001D0002D18A246671EAB4654465D46AC4201D17F +:1001E00000F022F87E460F3E0FCCB6460126334281 +:1001F00000D0FB1AA246AB4633431847084B000019 +:10020000284B00000023002400250026103A01D3CB +:1002100078C1FBD8520700D330C100D50B607047BE +:100220001FB51FBD10B510BD00F0B6FA1146FFF79F +:10023000F7FF03F0D7FC00F0CEFA03B4FFF7F2FFAC +:1002400003BC00F001FB000070B505460C461646E5 +:1002500002E00FCC0FC5103E102EFAD2082E02D3AA +:1002600003CC03C5083E042E07D301CC01C5361FBD +:1002700003E021782970641C6D1C761EF9D270BDD4 +:100280000748804707480047FEE7FEE7FEE7FEE72E +:10029000FEE7FEE704480549034A054B70470000A6 +:1002A00085320000C1000000080F00200813002064 +:1002B000080F0020F8B5042A2CD3830712D00B783E +:1002C000491C0370401C521E83070BD00B78491C3D +:1002D0000370401C521E830704D00B78491C037026 +:1002E000401C521E8B079B0F05D0C91ADF0020232C +:1002F000DE1B08C90AE0FFF7A7FFF8BD1D4608C9C5 +:10030000FD401C46B4402C4310C0121F042AF5D2F5 +:10031000F308C91A521EF0D40B78491C0370401C14 +:10032000521EEAD40B78491C0370401C012AE4D405 +:1003300009780170F8BDD2B210B513029A181304EF +:100340009A1800F0C3F910BD002203098B422CD388 +:10035000030A8B4211D300239C464EE003460B4315 +:100360003CD4002243088B4231D303098B421CD377 +:10037000030A8B4201D394463FE0C3098B4201D369 +:10038000CB01C01A524183098B4201D38B01C01AA1 +:10039000524143098B4201D34B01C01A5241030918 +:1003A0008B4201D30B01C01A5241C3088B4201D3C7 +:1003B000CB00C01A524183088B4201D38B00C01A74 +:1003C000524143088B4201D34B00C01A5241411A9B +:1003D00000D201465241104670475DE0CA0F00D07E +:1003E0004942031000D34042534000229C46030977 +:1003F0008B422DD3030A8B4212D3FC22890112BAFD +:10040000030A8B420CD3890192118B4208D38901D4 +:1004100092118B4204D389013AD0921100E08909EC +:10042000C3098B4201D3CB01C01A524183098B42CD +:1004300001D38B01C01A524143098B4201D34B01B6 +:10044000C01A524103098B4201D30B01C01A524119 +:10045000C3088B4201D3CB00C01A524183088B42A0 +:1004600001D38B00C01A5241D9D243088B4201D329 +:100470004B00C01A5241411A00D201466346524114 +:100480005B10104601D34042002B00D54942704713 +:1004900063465B1000D3404201B50020C046C04611 +:1004A00002BD704770477047F0B5FF252D04C6099F +:1004B000C209FF2704462E400137CB093E4348407E +:1004C0002A402B400746002A6BD0002B69D0AA4255 +:1004D00067D0AB4265D0002800DA32460125ED0531 +:1004E00029432C4309022002090AD21A4B0C7F240B +:1004F000E31A434C000A7C44E35C7D242404121973 +:1005000014145B00A218884201D3521C00E0400082 +:1005100049420C465C4324115C43DB016415E3183B +:10052000040A5C43C502200D0C4644436419250AA5 +:100530005D432303EC0C0D46654300030019EB18E3 +:100540004C42A34201D35B18401CD4052018002B59 +:1005500007D05B00C91804D3401C002901D1400812 +:1005600040003F2189048A4209D3002A08DC110691 +:10057000090F04D0032149074018C00FC007F0BD80 +:1005800001224100120689187F2252069142F6D2BA +:1005900005214907C84201D59010F0BDFF20C005D4 +:1005A000F0BD002F00DA32461648AA4207D2AB420D +:1005B00005D21902090E17D0F80FC007F0BDFF25AC +:1005C00063002D06AB42F9D84900A942F6D8AB42E8 +:1005D00001D1A942F2D0A94201D1002101E061007C +:1005E0004908D0050843F0BD1102090EFBD0FF20D9 +:1005F0000243D005F0BD0A460146104654E700000C +:10060000C84700000000C07F10B501469E240002CC +:10061000CA15A307002A02D01843002A04DBA21A35 +:10062000002A0CDDD04010BD1206120E01D1400090 +:100630004008A21A03D4D04040420028F3DDFF2234 +:1006400048001206904201D9002010BDC817C043CF +:10065000584010BD1F22030C02D10F2200041CD0F1 +:10066000030E01D10002083A030F01D10001121F4D +:10067000830F01D18000921E002801DB4000521E32 +:10068000D2055118021251181922904004D3491C66 +:10069000002801D14908490008467047C10FC90721 +:1006A00000D04042012292071143D3E7012189077C +:1006B000D0E701E004C0091F0429FBD28B0701D554 +:1006C0000280801CC90700D00270704700290BD03F +:1006D000C30702D00270401C491E022904D38307BD +:1006E00002D50280801C891EE3E70022EEE700228B +:1006F000DFE7000010B5FF231B0644009C421DD815 +:100700004C009C421AD80346124A0B4307D4401AA5 +:1007100002D3EFF3008010BDEFF3008010BD081A84 +:1007200006D2EFF3008001219043C907084302E09D +:10073000EFF30080904380F3008810BD0D231B046D +:100740001A4204D01146002000F006F810BD00F057 +:100750001BF810BD00000090CA0211D54A03520FC9 +:10076000002A04D0C803C043012188407047054ACD +:10077000EFF3008108010009104380F300887047FF +:10078000002070470000003010B5024800F029F842 +:1007900010BD00000000C07F754600F051F8AE4665 +:1007A000050069465346C008C000854618B020B50C +:1007B000FFF770FD60BC00274908B6460026C0C59B +:1007C000C0C5C0C5C0C5C0C5C0C5C0C5C0C5403D09 +:1007D00049008D4670470446C046C0462046FFF794 +:1007E0002CFD10B50C461107090F092904D00A2960 +:1007F0000AD008290CD104E011460820FFF7ACFF0D +:1008000006E0510606D501E0510601D50120C007DA +:10081000214610BDD10607D501010909CC084907B9 +:10082000000E0006044309E0410F20024907000AB8 +:100830000143200E00061D22D14101430846E7E78F +:1008400000487047A40E002001491820ABBEFEE707 +:1008500026000200704770B58C180578401C6B07A5 +:100860005B0F01D10378401C2A1106D10278401C8D +:1008700003E00678401C0E70491C5B1EF9D12B0763 +:1008800005D40023521E0DD40B70491CFAE70378DF +:10089000401CCB1A921C03E01D780D70491C5B1C98 +:1008A000521EF9D5A142D8D3002070BD044840693A +:1008B000012108430249486101200249087070473C +:1008C00080000E400C00002070B502460020C87861 +:1008D00000010D7928438D78AD052843034600209B +:1008E0004D79ED0628438D792D072D0A28430D7A81 +:1008F000ED042843CD792D0428430D78AD0028431D +:100900004D786D00284304464D7A80263543054EC8 +:100910003563FF250135AB508025AC504E898425C9 +:10092000AE5070BD0020005010B502461346FF3394 +:1009300065330907090F8C001C5BA0B210BD30B5F0 +:10094000044600230907090F8D0063591D052D0D6D +:10095000158030BD10B50346FF3365330907090F15 +:100960008C001A5110BD0146002094225258D20723 +:10097000D20F002A06D001209422525801231A4394 +:1009800094235A507047000070B5002400250120C0 +:1009900001F0AAFA012002F07DFC0446022001F0D9 +:1009A000A3FA022002F076FC0546002C01DD204669 +:1009B00000E0604201214902884210DD002D01DD86 +:1009C000284600E0684201214902884207DA0220F5 +:1009D0000C4908700C4908700C49087007E00120A8 +:1009E000084908700849087003200849087006493A +:1009F0004C702004000E8870CD702804000E087121 +:100A000070BD0000130000206402002034000020AC +:100A10003CB502461046104C246801940E4C241D2F +:100A2000246800940023002900DD00BF0B4CA24283 +:100A300007DD0A4C8234A24203DA5C006D46285F6F +:100A400009E0074CA24206DD054C8234A24202DADC +:100A50005C0001AD285F3CBD883E0000FF0C00003B +:100A6000FF04000010B5234800680078212823D037 +:100A70000EDC102823D006DC012811D0042812D067 +:100A80000F2834D112E011281CD020282FD110E0DB +:100A90003038030003F00EF806191C1F2225282BFE +:100AA00000F028FC24E000F027F821E000F0B2FA82 +:100AB0001EE000F09BF81BE000F06CF818E000F07E +:100AC000D7FA15E000F000F912E000F0B5FC0FE0F5 +:100AD00000F032FC0CE000F0FBFC09E000F06CFCE4 +:100AE00006E000F0CDF803E000F0AAF800E000BF57 +:100AF00000BF10BD74020020002021490968097858 +:100B000000293CD11E4A126811701E49C978090794 +:100B1000090E1C4A127911431B4A126811700121F7 +:100B2000194A1268517000BF23E04100174A525C15 +:100B30008100891C144B1B685A544100134A515AB6 +:100B40000A128100C91C104B1B685A544100104AFC +:100B5000525C8100091D0C4B1B685A5441000C4A21 +:100B6000515A0A128100491D074B1B685A54411CF7 +:100B7000C8B20128D9DB0621014A126811707047FA +:100B8000780200200D0000207C02002014000020CC +:100B90001600002070B50024002011490968087073 +:100BA00000BF0AE060000F4909684518A0000E491F +:100BB000085A00B22880601CC4B2012CF2DB60002D +:100BC00008490968451802210648006802F09CFFA0 +:100BD00000B22880042002490968087070BD000036 +:100BE000780200207C0200203800002070B500242C +:100BF000002010490968087000BF09E060000E4934 +:100C00000968451860000D49085A2880601CC4B264 +:100C1000012CF3DB600008490968451802210648E9 +:100C2000006802F071FF00B22880042001490968C1 +:100C3000087070BD780200207C0200203C0000207B +:100C400070B500250C4800680078022813D10B48C5 +:100C50000068407800020949096809780843054698 +:100C6000284600F07DFF0446044800680470012017 +:100C700001490968087070BD780200207C020020DC +:100C800070B500250E4800680078032817D10D487C +:100C90000068407800020B49096809780843054656 +:100CA0000848006884782146284600F069FF002043 +:100CB000044909680870012001490968087070BD7D +:100CC000780200207C02002030B500200021924AEA +:100CD0001278002A7ED000BF52E0DC2242438F4BC4 +:100CE000D2188032936DDC2242438C4C1219803230 +:100CF000526D991A002901DD0A4600E04A4283003C +:100D0000874CE3589A4205DD002901DD0A4604E0DC +:100D10004A4202E08200824B9A588300804CE250A3 +:100D2000002901DD0A4600E04A42524383007D4C1F +:100D3000E358D2188300E2507B4A1278012A1ED170 +:100D4000DC224243754BD2188032926D5243D31746 +:100D5000C400764D2D1930CD12196B41C400734D6E +:100D60002C190CC48200724B9B58DC2242436B4C02 +:100D700012198032926D9A1883006D4CE250401C1B +:100D80000128AADB6B4A1288521C12B2694B1A80E6 +:100D900000229A5E684B00241C5FA2424FDB0022B7 +:100DA0005D4B1A70604A1278002A47D100203EE05D +:100DB00082005B4B9B5C06224243604C2468A35438 +:100DC0008200574B9A5A1204130E06224243521CB9 +:100DD0005A4C00E034E02468A3548200514B9B5CE1 +:100DE00006224243921C554C2468A35482004D4B6A +:100DF0009A5A1204130E06224243D21C4F4C246806 +:100E0000A3548200474B9A581202130E0622424303 +:100E1000121D4A4C2468A3548200424B9A58130E68 +:100E200006224243521D454C2468A354401C01280D +:100E3000BEDB0622424B1B681A7000E000BF69E06F +:100E40003F4A12681278022A29D10122324B1A70C5 +:100E50003A4A12685278384B1A801A4612781202AF +:100E600012B21A80354A126812781B88D21812B250 +:100E7000314B1A8000222C4B1A702E4B1A80002006 +:100E800007E000228300264CE2508300254CE2500C +:100E9000401C0128F5DB0022284B1B681A70284AE9 +:100EA00012681278032A35D101221B4B1A70234A8B +:100EB00012685278204B1A801A461278120212B227 +:100EC0001A801E4A126812781B88D21812B21A4B66 +:100ED0001A801A4A12689278134B1A700022154B26 +:100EE0001A80002010E0002283000D4CE2508300A5 +:100EF0000C4CE2500023C4000C4D2C19236063609D +:100F000083000B4CE250401C0128ECDB00220B4B11 +:100F10001B681A7030BD0000B0020020C00600201F +:100F2000980200209C020020B1020020A0020020B4 +:100F3000A8020020AC020020AE0200207C020020AB +:100F40007802002010B521480078012802D100F075 +:100F5000BDF80CE01D481E4908601E481E49086087 +:100F60001E4800681E490860FFF77CFD00BF00BFF7 +:100F70001C48174908601C48174908601B48184955 +:100F80000860FFF76FFD1A481149086019481249B7 +:100F90000860194812490860FFF764FD17480C49BA +:100FA000086017480C49086016480D490860FFF7AB +:100FB00059FD154806490860144807490860144857 +:100FC00007490860FFF74EFD10BD00001C0100201E +:100FD000740200201D010020780200202001002062 +:100FE0007C020020F4010020F5010020980A002076 +:100FF000F6010020F7010020980B0020F8010020E6 +:10100000F9010020980C0020FA010020FB010020CB +:10101000980D002070B5002400201249096808705E +:1010200000BF0DE06000104909684518DC206043EE +:101030000E4940188030806D00B22880601CC4B218 +:10104000012CEFDB600008490968451802210648B9 +:10105000006802F059FD00B22880042001490968A7 +:10106000087070BD780200207C020020C0060020BD +:1010700070B50024002012490968087000BF0DE017 +:101080006000104909684518DC2060430E4940188B +:101090008030806D00B22880601CC4B2012CEFDB70 +:1010A000600008490968451802210648006802F0F6 +:1010B0002BFD00B22880042001490968087070BD2A +:1010C000780200207C0200209C07002000B500214F +:1010D00000226B4B1A7000BFCBE00B0002F0EAFC61 +:1010E00008051C354C657C95ACC5664A1268664B94 +:1010F0009A4208D16548664A926D12B20280024651 +:10110000604B1A6007E06048614A926D12B202803B +:1011100002465C4B1A60A9E05E4A12685E4B9A4236 +:1011200009D15E485A4ADC32926D12B20280024600 +:10113000584B1A6008E05848554ADC32926D12B29A +:1011400002800246534B1A6090E0554A1268554B94 +:101150009A4208D15448554A926D12B20280024612 +:101160004F4B1A6007E04F48504A926D12B202800E +:1011700002464B4B1A6079E04D4A12684D4B9A4239 +:1011800009D14D48494ADC32926D12B202800246C2 +:10119000474B1A6008E04748444ADC32926D12B26D +:1011A00002800246424B1A6060E0444A1268444B97 +:1011B0009A4208D14348444A926D12B202800246D4 +:1011C0003E4B1A6007E03E483F4A926D12B20280E1 +:1011D00002463A4B1A6049E03C4A12683C4B9A423C +:1011E00009D13C48384ADC32926D12B20280024684 +:1011F000364B1A6008E03648334ADC32926D12B240 +:1012000002800246314B1A6030E0334A1268334B99 +:101210009A4208D13248334A926D12B20280024695 +:101220002D4B1A6007E02D482E4A926D12B20280B3 +:101230000246294B1A6019E02B4A12682B4B9A423E +:1012400009D12B48274ADC32926D12B20280024645 +:10125000254B1A6008E02548224ADC32926D12B212 +:1012600002800246204B1A6000E000BF00BF4A1C0B +:10127000D1B2012900DA30E70122014B1A7000BD1A +:101280001D0100202001002098080020980900205E +:101290001C0800202C01002024010020280100202F +:1012A000380100203001002034010020D409002042 +:1012B000440100203C01002040010020500100209A +:1012C000480100204C0100208C0B00205C01002014 +:1012D0005401002058010020680100206001002016 +:1012E00064010020440D0020740100206C010020E6 +:1012F00070010020002000220C4B1B681A7000BFF8 +:101300000DE042000A4B1B68D118DC224243094B16 +:10131000D2188032926D12B20A80421CD0B20128DB +:10132000EFDB0222014B1B681A7070477802002025 +:101330007C0200209C07002038B500251C4800686E +:101340000078022832D11B480068447824021948EA +:1013500000680078001984B26946204602F0FAF964 +:101360000546144900980968087000980004000EAA +:1013700010490968487000980002000E0D4909687C +:1013800088700098000E0B490968C870681C002816 +:1013900008D1EE200749096808700120044909684E +:1013A000087003E0042002490968087038BD000095 +:1013B000780200207C02002038B500251C48006817 +:1013C0000078022832D11B4800684478240219486A +:1013D00000680078001984B26946204602F020FABD +:1013E0000546144900980968087000980004000E2A +:1013F00010490968487000980002000E0D490968FC +:1014000088700098000E0B490968C870681C002895 +:1014100008D1EE20074909680870012004490968CD +:10142000087003E0042002490968087038BD000014 +:10143000780200207C020020F8B5002620480068D1 +:10144000007806283AD11F48006845782D021D48CB +:1014500000680078401985B21A480068447924026F +:101460001848006800790419240216480068C078FA +:10147000041924021348006880780419214628467C +:1014800002F096F90646701C002804D1EE200D49A2 +:10149000096808700EE000200A49096808702046B3 +:1014A000FFF7FCF8074608493846FEF7FDFFA9009C +:1014B000064A50500120024909680870F8BD000032 +:1014C000780200207C02002000007A444C000020BA +:1014D00070B500261C4800680078062833D11B48E8 +:1014E000006845782D02194800680078401985B2D7 +:1014F00016480068447924021448006800790419E9 +:10150000240212480068C078041924020F480068B9 +:10151000807804192146284602F0B0F90646701C6E +:10152000002804D1EE2009490968087007E000206E +:1015300006490968087020B26900054A5052012026 +:1015400001490968087070BD780200207C02002003 +:101550008C000020F0B589B0054600200890079067 +:1015600000240026069005900390039880005449BB +:101570000F585448405D02908420C05980B20190B9 +:101580000120029988400199084000908421009828 +:10159000C8514D480068022188434B4908600398B0 +:1015A00000F000FD039800F047FE284600F018FC0C +:1015B00000B2069000BF00BF38460299FFF7B4F9A9 +:1015C00004B20120C002844203DA401E001B06B2AE +:1015D00000E026460121C9020698081A00B20790C9 +:1015E0003A4841790798FEF7B9FE00B2089000200A +:1015F00004903DE000BF00BF00BF00BF0498401C46 +:10160000C0B204900898301806B20120C002864289 +:1016100003DA401E801B04B200E0344600BF00BF66 +:101620002B480078012804D120460799FFF7F0F9EC +:10163000044600BF00BFA2B20299039800F0C0FCAC +:10164000039800F0AFFC039800F0F6FD284600F088 +:10165000C7FB00B206900121C9020698081A00B221 +:1016600007901A4841790798FEF778FE00B2089073 +:101670000898002802D004980A28BBDB00BF00BFEE +:101680000121C9022046884305900846844204DDB2 +:101690000598C043401C00B2059069000D4A0598AA +:1016A000505269000C4A0798505284210198C85141 +:1016B00005480068022108430349086009B0F0BDED +:1016C000040000201300002080000E400D000020C8 +:1016D00000000020140000201600002010B501F0CA +:1016E00065FD2E4800680121C90388432B49086025 +:1016F00008460068890208432849086028480069AC +:10170000042108432649086124480068012149054D +:1017100008432249086001F053FD2248006B402134 +:101720000840002839D11F48C06A400840001D49C0 +:10173000C8621C48403800684021084319494039B4 +:10174000086008460068402188431649403908600F +:101750001448C06A012108431249C8620120124995 +:10176000087030BF0F48C06A400840000D49C86289 +:101770000C4840380068402108430A494039086055 +:1017800008460068402188430649403908600548FA +:10179000C06A012108430349C86210BD00200050FF +:1017A00000ED00E0400002401900002010B501F0FB +:1017B000FDFC0B4800680121C90388430849086003 +:1017C00008460068890288430549086005480069A1 +:1017D000042188430349086101F0F2FC30BF10BDC9 +:1017E0000020005000ED00E070B504460026002502 +:1017F00001F0DCFC00BF16480069C007C00F0028DC +:10180000F9D1134880694021084311498861222099 +:10181000C86060198008800048600120086100BF2E +:1018200000BF0B480069C007C00F0028F9D1084865 +:10183000806940210840002805D005488069084398 +:1018400003498861012601F0BBFC304670BD0000F1 +:1018500000C0005010B501F0A9FC0E48006801213D +:1018600008430C49086008460068FF21013108431D +:101870000849086008460068802108430549086057 +:1018800008460068082108430249086001F098FCF6 +:1018900010BD000000C00050FEB505460C461646BF +:1018A000009601F083FC00200190E01C800880007D +:1018B00084B200BF20480069C007C00F0028F9D1DA +:1018C0001D488069402108431B49886100272BE09F +:1018D00000201949C86001982818800880004860D5 +:1018E000002088600120086100BF00BF1248006925 +:1018F000C007C00F0028F9D10F4880694021084077 +:10190000002805D00C48806908430B4988610DE028 +:10191000094882683846791C8FB28100009842508D +:101920002D1D361D201F84B2002CD1D100BF01F027 +:1019300047FC2846FEBD000000C00050F8B5054633 +:101940000C46164600270020009001F02FFCE01CFA +:101950008008800084B200BF1C480069C007C00F27 +:101960000028F9D119488069402108431749886146 +:1019700024E021201549C860E819800880004860EB +:10198000306888600120086100BF00BF0F4800690F +:10199000C007C00F0028F9D10C48806940210840D9 +:1019A000002807D009488069084308498861012058 +:1019B000009005E02D1D361D201F84B2002CD8D1CB +:1019C00000BF01F0FDFB0098F8BD000000C0005012 +:1019D00010B50121022001F0E3FAFFF73BFF10BD33 +:1019E00000200A49097800290ED100BF0AE0DC2155 +:1019F0004143074A89188031896D8200054B99500F +:101A0000411CC8B20128F2DB70470000FC01002035 +:101A10009C070020380000200021174A1180002078 +:101A200026E0DC214143154A89188031896D820006 +:101A3000134B9A58891A002901DA002109E0DC21A8 +:101A400041430E4A89188031896D82000C4B9A58A7 +:101A5000891A09B242000B4B995241001A46515A59 +:101A6000054A1288891809B2034A1180411CC8B27C +:101A70000128D6DB70470000F40000209C070020FE +:101A8000380000203C00002070B50025002601F041 +:101A900039FD00BF2FE001F0E5FB002425E02046E2 +:101AA00000F040F90646DC20604314494018A900C4 +:101AB00046502146304602F00BF8DC216143104AC3 +:101AC0008918AA008850342D0DDBDC2060430C49B6 +:101AD0004018A90041580C2060430A4A8218284641 +:101AE000343880001150601CC4B2012CD7DB01F0E7 +:101AF000ABFF681CC5B2372DCDDB70BDC006002022 +:101B00009C070020B406002010B513480078002878 +:101B100021D011480068000A00020F4908600F48F0 +:101B20000068401E0D49086008460068002806D17C +:101B300001F0AEFD01F0E6FC64200849086001F008 +:101B400045FBFFF74DFFFFF767FF01F0BDF9FFF71A +:101B5000F9F901F0DDFE10BD30000020F00000209A +:101B600070B50446022C06DA600004490D5A284676 +:101B700000F096F80646304670BD00002A000020AE +:101B8000F8B504460D46022C36DA60001B490E5AA1 +:101B90002B0001F08FFF0504090E17202F000221F2 +:101BA000304602F07BF826E00021304602F076F85D +:101BB00021E00121304602F071F80021304600F0AA +:101BC000A1F818E00121304602F068F80121304602 +:101BD00000F098F80FE00121304602F05FF830463F +:101BE00000F05EF80746012047403946304600F0D5 +:101BF00089F800E000BF00BFF8BD00002A00002007 +:101C000010B50246002100200AE013460341DB071D +:101C1000DB0F002B02D0012383401943431CD8B2B1 +:101C20001028F2DB0904034B5B680B43014C636033 +:101C300010BD000000400050014600200EE00A46A2 +:101C40000241D207D20F002A06D0064A526A012367 +:101C500083409A43034B5A62421CD0B21028EEDBF9 +:101C6000704700000040005010B502460B4B596809 +:101C7000090C00200CE013460341DB07DB0F002BAF +:101C800004D0012383400C469C432146431CD8B218 +:101C90001028F0DB0904014B596010BD00400050D2 +:101CA00001460548806882B210460840002801D0ED +:101CB000012070470020FCE70040005030B502468C +:101CC00000201AE013460341DB07DB0F002B12D084 +:101CD000012908D10A4B1B6845000124AC4023436D +:101CE000074C236007E0064B1B6845000124AC400D +:101CF000A343034C2360431CD8B21028E2DB30BD61 +:101D000000400050002905D0054A92680243044B68 +:101D10009A6004E0024A92688243014B9A607047DD +:101D20000040005070B5044600250026204601F012 +:101D3000DFF90546002D01DD284600E06842032159 +:101D40004902884229DD00F09FFA2046FFF702FC95 +:101D500000F080FA204601F0CBF90646A0001149B8 +:101D60000858A91B4018A1000E4A5050A000114667 +:101D70000858002802DDA000085803E0A000094927 +:101D8000085840420849884203DB0020A100054A68 +:101D900050503546052005490870A00001490858F3 +:101DA000401970BDF8000020606D0000AC000020FC +:101DB00010B5002404E0204600F02CF9601CC4B2E9 +:101DC000012CF8DB0448006802210843024908603E +:101DD00000200249087010BD80000E400C00002059 +:101DE000F8B50446002100910025A80005490E58C9 +:101DF0000548075D6A4639463046FEF7A0FD68464D +:101E00000088F8BD04000020130000203EB5002526 +:101E10000121102001F00CF90021062001F086F8C4 +:101E20000121080701F0DEF80121042001F0B8F8D3 +:101E3000402001F033F80121402000F0CDFF0021C7 +:101E400068464170012181700221C1700421017135 +:101E5000417101210172072181710221C17101705B +:101E60001D480078022800D100E001206946487230 +:101E7000002407E01948015D01208840284385B20D +:101E8000601CC4B2012CF5DB684645811449086822 +:101E90006946FEF719FD134800680121C90508438A +:101EA000104908600F484030006AC90508430D49D1 +:101EB000403108620846006A0121090708430949C0 +:101EC000403108620748803800680121084305490D +:101ED0008039086000203EBD34000020130000203F +:101EE0000400002000010E403EB5044600250121FB +:101EF000102001F09DF80021062001F017F80121C3 +:101F0000080701F06FF80121042001F049F8402092 +:101F100000F0C4FF0121402000F05EFF0021684670 +:101F20004170012181700221C17004210171417150 +:101F300001210172072181710221C171017001210A +:101F400041720120A040284385B26846458113496B +:101F500008686946FEF7B8FC114800680121C90508 +:101F600008430F4908600E484030006AC90508431D +:101F70000B49403108620846006A012109070843FD +:101F8000074940310862064880380068012108434B +:101F900003498039086000203EBD00000400002095 +:101FA00000010E408200054B9958802252580123AF +:101FB000DB021A4380235A507047000004000020BF +:101FC000F8B504460D461646A00004490F5832469F +:101FD00029463846FEF7BEFCF8BD0000040000208C +:101FE00070B503468C009D00094E7059FF250135E0 +:101FF0002D580726A640B543FF26013635503546F5 +:102000002D581646A6403543FF260136355070BD83 +:1020100004000020F1B58EB000BF00200D90002418 +:102020000C9000250B900590059880007B4908587E +:1020300004907B490E98085C0390049880304068B7 +:1020400080B20290012003998840029908400190D3 +:102050000498803001994160002201210598FFF722 +:10206000BFFF002211460598FFF7BAFF0598FFF75A +:1020700099FF059800F0E0F80E98FFF7B1FE05B261 +:102080000120C002281A002803DD0120C002281AFE +:1020900002E00120C002401B06B21B200002704378 +:1020A0000A907D20C000099007AB08AA09990A98F8 +:1020B00000F016FAFF21F5310798884202D30898FC +:1020C000401C0890089800B20D900D9C0120C002A1 +:1020D000854203DA201804B20C9403E05148001B37 +:1020E00000B20C90A2B203990598FFF769FF00BFF8 +:1020F00000BF002771E0780038184B490A5C0121C5 +:102100000598FFF76DFF7800381847494018427866 +:1021100000210598FFF764FF0598FFF743FF059836 +:1021200000F08AF80E98FFF75BFE05B20120C002AE +:10213000401B06B2780038183B4A80188178304638 +:10214000FEF70CF900B20D9000BF00BF0020069012 +:102150003BE00698401CC0B206900D990C984018C0 +:1021600000B20C900121C9020C98884204DA491E81 +:102170000C98081A04B200E00C9C2C480078012846 +:1021800004D131462046FEF743FC044600BF00BFA1 +:10219000A2B203990598FFF713FF0598FFF702FF16 +:1021A000059800F049F80E98FFF71AFE05B20120D5 +:1021B000C002401B06B2780038181B4A801881788C +:1021C0003046FEF7CBF800B20D900D98002802D0F3 +:1021D00006980A28BDDB781CC7B2022F8BDB00BF34 +:1021E00000BF0121C902204688430B900846844263 +:1021F00004DD0B98C043401C00B20B900B9881B2D9 +:102200000E9840000A4A11520E984000094A165290 +:1022100004988030029941600FB0F0BD04000020A6 +:1022200013000020FF0700000D0000200000002028 +:10223000140000201600002070B50446A0000449D8 +:102240000D5800BF2846FEF78EFB0028FAD070BD5F +:10225000040000200A4800680121890588430849D4 +:102260000860074880380068400840000449803909 +:1022700008600448006B8021884302490863704766 +:1022800000010E40002000500A48006B80210843E6 +:10229000084908630848006849020843064908607D +:1022A00005488038006801210843034980390860E7 +:1022B000704700000020005000010E4010B50024BF +:1022C0000D480068FF2109028843FF3001300A49A8 +:1022D000086008460068000A0002086000200749FC +:1022E000087007490870642404480078054908709C +:1022F000204601F06FFB10BD300000201B000020C5 +:102300001A0000204A02002010B504460A2C01DD04 +:10231000012010BD204600F081F8012802D120469E +:1023200000F054F80020F4E710B5002400BF04E0EA +:102330002046FFF7E9FF601CC4B20A2CF8DD00203C +:1023400010BD000010B50D480D4909680160FF225D +:102350000421001DFDF7EFFFFF220421074808308C +:10236000FDF7E9FFFF22FD21890004480C30FDF74D +:10237000E2FFFFF72DFB002010BD0000B40200209B +:10238000903E0000F8B504460D4616461F460A2C3E +:1023900001DD0120F8BDA819FD218900884201D97D +:1023A0000120F7E720463030074B0122920200213E +:1023B00001F0EFFB04480C30411932463846FDF776 +:1023C00079FF0020E6E70000B402002070B5044663 +:1023D00000250A2C01DD012070BD0E480E49096858 +:1023E0000160FF22FD2189000C30FDF7A4FFFD21D3 +:1023F000890008480C3001F09FFB05460548456000 +:1024000020463030034B01229202002101F0D1FB23 +:102410000020E1E7B4020020903E000070B50446C1 +:1024200000250A2C01DD012070BD204630300E4B06 +:1024300001229202002101F0ACFB0B4800680B491D +:10244000884201D00120EFE7FD21890006480C30C9 +:1024500001F072FB054604484068A84201D0012003 +:10246000E2E70020E0E70000B4020020A55A5AA5E8 +:10247000F8B504460D4616461F46002000900A2C6B +:1024800001DD0120F8BDA819FD218900884201D98C +:102490000120F7E720463030104B01229202002144 +:1024A00001F077FB0D490C31481932463946FDF7EA +:1024B00001FFFD21890009480C3001F03DFB00902F +:1024C000064900984860204630300B4601229202AF +:1024D000002101F06EFB0020D4E70000B4020020D0 +:1024E00030B50446084804604160806810600648C2 +:1024F000C06818600448006902252840002801D0FF +:10250000002030BD0120FCE70040015070B5FF24E1 +:10251000FF250120514908705148C06A0121C903B3 +:102520000840002808D04E488030006BC407E40FF4 +:1025300000204C4908708FE04948C06A20210840BB +:1025400000282DD0464840300069474800784100B7 +:102550004018464940184078012808D04248007881 +:1025600041004018414940184078112814D13E4894 +:102570000078410040183D49401880783C4909786E +:10258000884209DD3B48006839490978455C38488C +:102590000078401C36490870E8B200F0BBFB5BE0F5 +:1025A0002F48C06A0421084000283FD02C48046905 +:1025B00031480078C007C00F00280FD02E480068AF +:1025C000400840002C49086027490C7008460078F4 +:1025D00000F06EF80020294908703DE0224800789C +:1025E00041004018214940184078102808D01E4862 +:1025F0000078410040181D494018407811282BD11F +:1026000019480078410040181849401880781B4943 +:102610000978884220DD17490968184A12788C54D5 +:1026200016480078401C1549087015E00C48C06A2F +:1026300001214902084000280ED009484030006AB4 +:102640000D48006840084000401C0B49086000200D +:102650000A4908700649087070BD00001800002083 +:10266000000002401900002070020020D447000042 +:10267000280000206C0200202400002029000020F7 +:102680000348C06A012108430149C862704700003D +:1026900040000240002001490863704700000240EA +:1026A0000249096B0143014A11637047000002406F +:1026B00010B5044660002018F849085C65286FD002 +:1026C0003ADC1F286DD011DC030001F0F3F91B6B1D +:1026D0006C72767A7E8387928B9492929292929881 +:1026E0009CA4A8ACB0B4B8BDC1C592002A2870D0D3 +:1026F00009DC2038030001F0DDF90AB9BDC4C8CCFB +:10270000D0D4D8DCE07C602870D00CDC50286ED0AF +:1027100004DC2B286CD02C286BD1DAE0512869D04E +:102720005228F9D1E1E0612871D0622870D0632885 +:102730006FD06428F0D10DE17B286BD00FDC6638B8 +:10274000030001F0B7F915EEEDECEBEAE9E8E7E696 +:10275000E5E4E3E2E1E0DFDEDDDCDBDA56008628FB +:1027600071D009DC7C38030001F0A4F90AEEEDEC2D +:10277000EBEAE9E8E7E6E543D02871D007DC8738E3 +:10278000030001F097F905F0EFEEEDEC3600D128EB +:1027900067D0D22873D0D32872D0D428BCD13EE2DF +:1027A000E2E05FE045E20120BD49087000F0DEFD97 +:1027B0003FE2BC48BC4908603BE2BC48BA490860FB +:1027C00037E2BB48B849086033E2BA48B649086006 +:1027D0002FE276E00120B84908702AE20120B749CB +:1027E000087026E20120B649087022E281E074E018 +:1027F0006BE018E275E0B348AB49086019E2B248F3 +:10280000A949086015E2B148A749086011E289E0CA +:102810008CE09AE00DE1AE48A349086009E2AD48BA +:10282000A149086005E2AC489F49086001E2AB4855 +:102830009D490860FDE1AA489B490860F9E1A94863 +:1028400099490860F5E120E1A74897490860F0E15F +:10285000A64895490860ECE1A54893490860E8E17D +:10286000CAE1D0E1A34890490860E2E1A2488E495C +:102870000860DEE1A14800688B490860D9E1C6E143 +:10288000C9E19F4888490860D3E19E4886490860AD +:10289000CFE19D4884490860CBE19C4882490860AB +:1028A000C7E19B4880490860C3E19A487E490860B7 +:1028B000BFE199487C490860BBE198487A490860C3 +:1028C000B7E1974878490860B3E1964876490860CF +:1028D000AFE1954874490860ABE1944872490860DB +:1028E000A7E1934870490860A3E192486E490860E7 +:1028F0009FE191486C4908609BE196E091E08CE093 +:1029000087E082E07DE078E073E06EE068E062E01E +:102910005CE056E050E04AE044E03EE038E032E07F +:102920002CE026E085486049086082E18448006820 +:102930005D4908607DE1A4E09FE09AE095E090E0C9 +:102940008BE086E081E07CE077E07E4800685649D5 +:1029500008606EE17C4800685349086069E147E11E +:1029600042E13DE138E194E0784800684E49086072 +:102970005FE1774800684C4908605AE17548006893 +:102980004949086055E1744800684749086050E1CA +:1029900072480068444908604BE171480068424948 +:1029A000086046E16F4800683F49086041E16E48B1 +:1029B00000683D4908603CE16C4800683A4908609D +:1029C00037E16B4800683849086032E169480068BF +:1029D000354908602DE1684800683349086028E1FE +:1029E000664800683049086023E165482E49086060 +:1029F0001FE164482C4908601BE163482A490860CC +:102A000017E162482849086013E1614826490860D7 +:102A10000FE16048244908600BE15F4822490860E3 +:102A200007E15E482049086003E15D481E490860EF +:102A3000FFE05C481C490860FBE05B481A490860FD +:102A4000F7E05A4818490860F3E059481649086009 +:102A5000EFE0584814490860EBE057481249086015 +:102A6000E7E0564810490860E3E055480E49086021 +:102A7000DFE054480C490860DBE053480A4908602D +:102A8000D7E0524808490860D3E051480649086039 +:102A9000CFE0504804490860CBE00000D447000074 +:102AA000800200208C0800206C020020140100200D +:102AB000160100201801002082020020810200205F +:102AC000830200201A010020FC010020FD010020EB +:102AD00002020020070200200C0200201102002048 +:102AE000160200201B0200202002002025020020E8 +:102AF0002A020020620200202F020020340200205F +:102B0000380200203A0200203C0200203E02002051 +:102B10004002002042020020440200204602002021 +:102B20004802002063020020640200204A020020C4 +:102B30004B0200204D0200201C0100201D0100203E +:102B4000200100202C010020380100204401002039 +:102B5000500100205C010020680100207401002069 +:102B6000800100208C01002098010020A401002099 +:102B7000B0010020BC010020C8010020D4010020C9 +:102B8000D8010020DA010020DC010020DE01002055 +:102B9000E0010020E2010020E4010020E601002025 +:102BA000E8010020EA010020EC010020EE010020F5 +:102BB000F0010020F2010020F4010020F5010020C6 +:102BC000980A0020F6010020F7010020980B002051 +:102BD000F8010020F901002017481849086028E092 +:102BE00017481649086024E016481449086020E098 +:102BF0001548124908601CE0012014490870144867 +:102C00000E49086015E001201249087011E01248D1 +:102C10000A4908600DE011480849086009E01048B9 +:102C20000649086005E00F480449086000BF00BF7E +:102C300000BF00BF10BD0000980C00206C020020F7 +:102C4000FA010020FB010020980D002085020020E1 +:102C50005102002084020020520200205402002071 +:102C600056020020980E002070B500F08DFB05463E +:102C700000F090FB0446094805604460601C002891 +:102C800002D1012006490870BE2004490872EF20D5 +:102C9000487204480449086070BD00008C08002098 +:102CA00000000020980E00206C0200201849C96A1C +:102CB000C907C90F164AD1620178154A403A916096 +:102CC000002111601146096880221143104A403AE0 +:102CD00011604178082901DD0821417041780029FF +:102CE00001D1012141704178491E094A403A91635E +:102CF0008178082901DD082181708178002901D1BE +:102D0000012181708178491E014A403AD1637047A0 +:102D100040000240034A5269D1B2024A403A10616F +:102D200000BF70474000024009480068400840006A +:102D3000401C07490860084600680221884304498E +:102D4000086008460068042188430149086070470C +:102D50002400002010B50121084600F021F90548A3 +:102D6000FEF74EFF002000F05DFF0221880200F018 +:102D700095FF10BDFF070000F8B506460C4600257C +:102D800000BF002700BF16E00C2060431149411826 +:102D9000681C800009580C2060430E4A8018AA0065 +:102DA00081500C2060430B494118681C8000085872 +:102DB000C719681CC5B2022DE6DB0C20604305492B +:102DC00040188660BF1903213846FDF7C7FA009006 +:102DD0000098F8BDB406002010B50246032900DDB6 +:102DE00003210846102A30D008DC012A11D0022A1B +:102DF00016D0042A1BD0082A4AD11FE0202A2BD043 +:102E0000402A30D0802A35D0D31FF93B002B3FD148 +:102E100037E0214B1B68840123431F4C236038E0BB +:102E20001D4B1B68840323431B4C236031E01A4B6A +:102E30001B6884052343184C23602AE0164B1B684B +:102E400084072343144C236023E0134B5B68840105 +:102E50002343114C63601CE00F4B5B6884032343E6 +:102E60000D4C636015E00C4B5B68840523430A4CF2 +:102E700063600EE0084B5B6884072343064C636085 +:102E800007E0054B9B6884012343034CA36000E0EB +:102E900000BF00BF10BD000000E400E001460020BC +:102EA0000DE0012282400A40002A06D0054A12683D +:102EB000012383401A43034B1A60421CD0B20928F5 +:102EC000EFDB704700E100E010B5124800781249CE +:102ED0000870124800681249884208D18C1C1149B8 +:102EE0000020085E208020460C49086007E00C4C5A +:102EF0000C490020085E20802046084908600A49E5 +:102F00000020085E074900228A5E904201DA00F044 +:102F1000EAFE10BDFC0100202F0200203402002038 +:102F200030020020F40000208C00002030B5024662 +:102F30001A4CA069012A15D0022A1AD0042A0AD0F4 +:102F4000062A1BD120250446AC4320461025044602 +:102F5000AC43204613E020250446AC432046102411 +:102F600020430CE02024204310250446AC43204697 +:102F700005E0202420431024204300E000BF00BFD0 +:102F8000064CA061E0690B46FF252D040446AC43C6 +:102F900020461C042043014CE06130BD0028005055 +:102FA00010B50246002018E01346C340DB07DB0FD4 +:102FB000002B10D0012907D1094B5B680124844004 +:102FC0002343074C636006E0054B5B6801248440A3 +:102FD000A343034C6360431CD8B20528E4DB10BD57 +:102FE0000028005070B505460E4600F0DFF80024BA +:102FF00017E00120A0402840002810D0012E07D162 +:103000000A4880680121A14008430849886006E019 +:10301000064880680121A140884304498860601CFB +:10302000C4B2202CE5DB00F0CBF870BD00280050C6 +:1030300070B505460E4600F0B9F8002417E00120EF +:10304000A0402840002810D0012E07D10A4800686F +:103050000121A14008430849086006E006480068CD +:103060000121A140884304490860601CC4B2052CBA +:10307000E5DB00F0A5F870BD0028005001460129ED +:1030800004D0022904D0032906D103E0022004E081 +:10309000032002E0072000E000BF00BF034A52699E +:1030A000F0231A401043014A506170470028005035 +:1030B00070B5054600F07AF80C488469032D02D0FB +:1030C000052D0CD106E00221204688430446640801 +:1030D000640005E0022004436408640000E000BFCF +:1030E00000BF0248846100F06BF870BD00280050FA +:1030F00070B504462046FEF773FE0121C902401A4E +:1031000005B2284670BD10B5002403E0A0B200F05F +:103110000FF8641C102CF9DB10BD10B5002403E07F +:10312000A0B200F025F8641C012CF9DB10BD0000F2 +:10313000F8B50446102C00DBF8BD6946204600F0C7 +:1031400009FB0546681C002800D1F5E70098FDF74B +:10315000A5FA064604493046FDF7A6F9A100034A40 +:10316000505000BFE8E7000000007A444C00002007 +:1031700038B50446102C00DB38BD6946204600F007 +:103180004FFB0546681C002800D1F5E7009800B207 +:103190006100024A505200BFEEE700008C000020A0 +:1031A00010B5FFF7B0FFFFF7B8FF10BD5920034976 +:1031B00008601620086088200860704700010050F1 +:1031C00000200149086070470001005070B50024DC +:1031D00000250026FFF758F800F044F8FFF73AF80A +:1031E00000BF37E0DC2262431C4BD218111DDC22E9 +:1031F0006243D018D822FDF727F8DC226243184B2F +:10320000D218111DDC226243D018D822FDF71CF819 +:10321000E0B2FEF787FD0546DC2060430F49401809 +:1032200080308565E1B2284600F052FC0546DC207E +:1032300060430B49401880308565E1B22846FFF7AE +:103240009BFD0646DC2060430549401880308665BA +:10325000601C84B2012CC5DB70BD0000C0060020DC +:103260009C07002010B5094800680121C9020843E5 +:103270000649086000BFFEF799FA05480078002863 +:10328000F9D000200249087010BD000080000E40F7 +:103290000C000020F0B585B004463048406880B28C +:1032A00002902E48803801902C48E43000902B4842 +:1032B0000068049029488030006803900021A20033 +:1032C000009881502648006B8021084324490863F8 +:1032D0001F20000521498031086022481F490860ED +:1032E0000120A040486008460068C91408431B49F3 +:1032F000086000BF19488038FDF735FB0028F9D079 +:10330000A1000198405A0605360D1748134980312F +:10331000086012480068C91408431049086000BFDB +:103320000E488038FDF71FFB0028F9D0A100019856 +:10333000405A07053F0D0949803103980860074945 +:1033400002984860049808600548006B8021884313 +:1033500003490863F51B28B205B0F0BD80000E409C +:103360000020005009004A200000F010BFF3408FF9 +:1033700002480349C860BFF3408F70470400FA0554 +:1033800000ED00E070470000014908687047000048 +:1033900000ED00E005210907086870470149496907 +:1033A00088B270474000005010B5024605231B0745 +:1033B0005868130000F07EFB06040E183B5C677330 +:1033C000012902D11023184303E010240346A3432C +:1033D000184665E0022902D14023184303E0402447 +:1033E0000346A34318465BE0052903D103239B044E +:1033F00018431BE0022906D18B0418434C040346F2 +:10340000A343184612E0032907D10124E40403462C +:10341000A34318466310184308E00124E40403465C +:10342000A343184664100346A343184638E0062910 +:1034300002D1CB0418431AE0012906D14B051843E9 +:103440000C050346A343184611E0042906D1CC0419 +:103450000346A34318468B04184308E0012464057F +:103460000346A343184664100346A343184617E0D7 +:10347000082902D1CB04184304E00124A405034623 +:10348000A34318460CE0072903D101231B06184368 +:1034900004E0012424060346A343184600E000BFCD +:1034A00000BF05231B07586010BD000005480069D8 +:1034B000C1B280200840002801D0002070470120C0 +:1034C000FCE70000400000500246012904D19306A9 +:1034D000180E0123184300E00020014B18617047CB +:1034E00040000050064800690221884304490861F1 +:1034F000084600690221084301490861704700003D +:1035000040000050F0B585B03F4909783E4A5278F6 +:1035100012028818FDF7C2F807463C49FCF7C4FFC1 +:10352000064600255DE044206843394A115830467C +:1035300000F034FC54D2002D0FD100240AE04420C6 +:10354000684333494018001DA1004058A100314A8A +:103550005050641C102CF2DB41E000243DE06A1E58 +:1035600044235A432A4B995844226A43985800F0FE +:10357000A3FC44216943264A03905058314600F089 +:103580009BFC0090681E44225043214A8018001D75 +:10359000A2008158009800F02BFC0746681E4422C8 +:1035A00050431B4A1158304600F086FC00904420DE +:1035B0006843174A8018001DA2008158009800F047 +:1035C00017FC3946019000F0A3FB02900399FCF729 +:1035D0006BFFA1000F4A5050641C102CBFDB02E0AF +:1035E0006D1C0B2D9FDB00BF0B2D0ADB002406E0BA +:1035F000A10009484058A100064A5050641C102CF4 +:10360000F6DB05B0F0BD00004D02002000002041B7 +:10361000E8440000B00000209447000010B51848AE +:10362000007800281DD01748C06A4008400015499E +:10363000C8621448403800684021084311494039A5 +:10364000086008460068402188430E4940390860F8 +:103650000C48C06A012108430A49C8620020084991 +:103660000870094800F059F808480068000A00028C +:1036700006490978491CC9B208430449086010BDCD +:1036800019000020400002400000014030000020EE +:10369000F8B500F02FF80446204600F017F806466B +:1036A0000849304600F0A4FB0746FCF7ADFF05B221 +:1036B00005490D702804000E48708C702012C870E7 +:1036C000F8BD0000000020414D020020F8B504467E +:1036D0002046FCF7EBFF07460449FCF7E5FE0646EB +:1036E000034900F0DDFB05462846F8BD0000864290 +:1036F0000000D84310B5FFF7F5FE00BFFFF7D6FE78 +:103700000028FBD1FFF74AFE0446204610BD10B545 +:1037100001210020FFF7D8FE10BD8168012211436E +:103720008160704701680122920711430160704770 +:10373000024600200B785B0718434B78DB061843E2 +:103740008B781B051843CB78184310604B68536087 +:10375000704700003EB504460D46102C02DB0020E9 +:10376000C0433EBD062060430E4A811806226846CB +:10377000FCF7A0FD0C480290684607C800F0B6F8B8 +:1037800009480078EE2805D1074840780749095DC7 +:10379000884202D00020C043E3E703484068286025 +:1037A0000020DEE7E24A000088020020424B0000D1 +:1037B0003EB504460D46102C02DB0020C0433EBD42 +:1037C00006206043134A811806226846FCF772FD02 +:1037D00011480290EE20104908701048005D4870B2 +:1037E00008464560684607C800F089F8684607C87B +:1037F00000F07CF808480078EE2805D106484078AB +:103800000649095D884202D00020C043D7E7002066 +:10381000D5E70000E24A000088020020424B000089 +:103820003EB504460D46102C02DB0020C0433EBDD1 +:10383000062060430E4A811806226846FCF73AFDCE +:103840000C480290684607C800F050F80948007814 +:10385000EE2805D1074840780749095D884202D023 +:103860000020C043E3E70348406828600020DEE70B +:10387000524B000090020020B24B00003EB50446BF +:103880000D46102C02DB0020C0433EBD06206043E5 +:10389000134A811806226846FCF70CFD1148029075 +:1038A000EE20104908701048005D487008464560D9 +:1038B000684607C800F023F8684607C800F016F805 +:1038C00008480078EE2805D1064840780649095D89 +:1038D000884202D00020C043D7E70020D5E700008F +:1038E000524B000090020020B24B000037B56C46EE +:1038F000A28861882078029BFEF744FD3EBD37B563 +:103900006C46A28861882078029BFEF7B1FD3EBD1F +:1039100010B517480078002804D0012809D00228E3 +:1039200022D117E013480078002801D0FDF7D6FE19 +:103930001BE011480078002801D1642000E0C82075 +:1039400001460E48FCF70AFD0D49086002200849AF +:1039500008700AE00A480068401E0949086000280B +:1039600001D10349087000E000BF00BF10BD000096 +:10397000180000201A0100201A00002030750000F5 +:103980002000002008B501210802FFF72BFB2020B2 +:10399000FFF784FA00212020FFF71EFA04210320FC +:1039A000FFF702FD03210220FFF7FEFCFEF772FE87 +:1039B00089208000FEF774FE5021684601700121C5 +:1039C000417008218170FFF771F9FFF7ADF9FEF73B +:1039D00057FE08BD1CB504460420FFF75FFA02211C +:1039E0000420FFF7F9F901210804FFF7FBFA03208F +:1039F000FFF744FB01216846017041700021C1704E +:103A0000019469460348FFF793FE0248FFF78AFED8 +:103A10001CBD0000000001401CB501210846FFF755 +:103A2000E1FA0320FFF744FB0521684601700021FD +:103A3000C1700121017103214171002181700121B7 +:103A4000417000F005F81CBD10B500F025F810BD60 +:103A500070B5044625782D026078012801D18020B8 +:103A60000543A078012801D140200543E0780128D2 +:103A700001D1102005432079012801D102200543FE +:103A8000FFF794FB03480560607902494860FFF73F +:103A900097FB70BD0040004010B5FFF787FB04485E +:103AA00000680121084302490860FFF789FB10BD47 +:103AB0000040004030B47446641E2578641CAB425C +:103AC00004D3635D5B00E31830BC18471D46F8E77C +:103AD000F8B505460C462846FCF7E0FD0090A0002E +:103AE000074A1158009800F083F90746A000054ADC +:103AF0001158384600F07CF90646FCF785FDF8BD04 +:103B00004C000020B000002030B5024600201346D3 +:103B10000AE01C785B1C05126C402406E40D054D80 +:103B20002C5B05026C40A0B20C46491E002CF0D163 +:103B300030BD00009442000030B502460C46002122 +:103B40001346C94309E018785B1C48400006800D05 +:103B5000054D28580D0A684001462046641E00287D +:103B6000F1D1C84330BD0000943E000070B504465A +:103B70000026A5022846FDF737FE002806D1E81DDD +:103B8000FF30FA30FDF730FE002800D00126304625 +:103B900070BDFEB504460D4616461F46A0024019EC +:103BA00000903A4631460098FDF776FE0190019864 +:103BB000FEBDFFB581B004460D461646A002401971 +:103BC00000902046FFF7D2FF0746012F02D138466A +:103BD00005B0F0BD3146049A0098FDF7AFFE0746E8 +:103BE0003846F5E7FFF740F8FFF7CCFEFFF7B2F8ED +:103BF000FCF7CAFEFEF70AF9FEF7DAF8FFF70CFF4A +:103C0000FEF7A0FBFEF790FBFFF7CAFAFFF77FFD78 +:103C1000FDF73AFFFEF752FB03E0FFF715FFFDF754 +:103C200073FFFAE7002802D0012831D11EE00521F8 +:103C30000907496801229205914305221207516044 +:103C4000114649680122120691430522120751606C +:103C5000114909680122920511430F4A116011466A +:103C60000968920211430C4A116012E0052109070C +:103C7000496801229205114305221207516011463D +:103C8000496801221206114305221207516000E023 +:103C900000BF00BF704700000040005070B50546EF +:103CA0000C46002C09D0012C02D0022C18D10CE0BB +:103CB00001212846FEF702F813E000212846FDF70F +:103CC000FDFF2846FDF7D0FF0BE02846FDF7B4FFC7 +:103CD00000212846FDF7F2FF2846FDF791FF00E09E +:103CE00000BF00BF70BD10B50121C802FFF7D6FFAD +:103CF00000210120C002FEF705F8002400E0641C4A +:103D00000A2CFCDB02218802FFF7C8FF10BD00006F +:103D100070B501250400ED074C4020D4441A01D2AF +:103D2000001B0919C60D4B00F2B2FF2A29D01B0E49 +:103D30002CD000020C02D31A2C43DC402843051976 +:103D400010D2280A02D3401C6D0611D0761EF6054B +:103D50008019FF2A00DA70BDC00DC00570BD694032 +:103D600000F0B0F801200543C541521C761CE8E77D +:103D700064089C40C90161408900E7D10124A04347 +:103D8000E4E71B0E440200D0034870BD002AFCD1BA +:103D9000C00FC00770BD00BF0000C07F012302003C +:103DA000DB050A430DD4DA4203D49A4207D4884291 +:103DB0007047D84214D4D94212D488427047804206 +:103DC0007047DA4203D59A42F9D5814270475B00C9 +:103DD0004200DA4204D24A00DA4201D281427047FC +:103DE00010B5024AFCF786FC10BD00BF090016049E +:103DF00070B5420064414B005C41120E39D01B0E7D +:103E000038D0FF2A3CD0FF2B3AD040024902400A6A +:103E1000490A060045184E43000A090AD2184843C9 +:103E2000ED017F3A0104731A4019190C4318990FD8 +:103E300004D001215B0849075B1A521CD80904D33E +:103E4000401CF50301D19D0607D0FF2A08D2D505F5 +:103E500006D0E4072043401970BD0125A843F4E7CC +:103E6000002A01DCE00770BD2402FF202043C005CA +:103E700070BD1B0EFF2A03D0FF2B01D0E00770BDE1 +:103E8000FF2645003606B54206D84D00B54203D898 +:103E9000D218FF2A00D0E7E7004870BD0000C07FBD +:103EA00070B50125ED07684004004C4002D569401B +:103EB00000F008F8FFF732FF70B501250400ED07A8 +:103EC0004C4022D4441A02D26C40001B0919C60D82 +:103ED0004B00F2B2FF2A4BD01B0E50D000020C0256 +:103EE000D31A2C43DC40A843051B05D5AD0019D3DC +:103EF0006D08761E521E37D0F605280A01D28019A9 +:103F000070BD70416D0603D070BD6940FFF706FFBC +:103F10009C4009026140490001D0401E70BD01244F +:103F2000A04370BD6D081DD001202B0C01D12D04C4 +:103F300010302B0E01D12D0208302B0F01D12D0195 +:103F4000001DAB0F01D1AD00801CEB0F01D16D0046 +:103F5000401C6D00361A121A680AF5054019012A2C +:103F600002DB70BD002070BDC036300AC00770BDD6 +:103F70001B0E440201D1FF2B00D1024870BD002A64 +:103F8000F0D070BD0000C07FFF048105810DFF0CE3 +:103F9000A55A5AA500000000963007772C610EEE56 +:103FA000BA51099919C46D078FF46A7035A563E990 +:103FB000A395649E3288DB0EA4B8DC791EE9D5E0B7 +:103FC00088D9D2972B4CB609BD7CB17E072DB8E7B6 +:103FD000911DBF906410B71DF220B06A4871B9F30B +:103FE000DE41BE847DD4DA1AEBE4DD6D51B5D4F444 +:103FF000C785D38356986C13C0A86B647AF962FDA9 +:10400000ECC9658A4F5C0114D96C0663633D0FFAF5 +:10401000F50D088DC8206E3B5E10694CE44160D5FB +:10402000727167A2D1E4033C47D4044BFD850DD2E5 +:104030006BB50AA5FAA8B5356C98B242D6C9BBDBF8 +:1040400040F9BCACE36CD832755CDF45CF0DD6DCF3 +:10405000593DD1ABAC30D9263A00DE518051D7C89A +:104060001661D0BFB5F4B42123C4B3569995BACF25 +:104070000FA5BDB89EB802280888055FB2D90CC646 +:1040800024E90BB1877C6F2F114C6858AB1D61C1BF +:104090003D2D66B69041DC760671DB01BC20D298DE +:1040A0002A10D5EF8985B1711FB5B606A5E4BF9F6B +:1040B00033D4B8E8A2C9077834F9000F8EA809965E +:1040C00018980EE1BB0D6A7F2D3D6D08976C6491C9 +:1040D000015C63E6F4516B6B62616C1CD8306585E2 +:1040E0004E0062F2ED95066C7BA5011BC1F40882BF +:1040F00057C40FF5C6D9B06550E9B712EAB8BE8B00 +:104100007C88B9FCDF1DDD62492DDA15F37CD38C88 +:10411000654CD4FB5861B24DCE51B53A7400BCA386 +:10412000E230BBD441A5DF4AD795D83D6DC4D1A4B8 +:10413000FBF4D6D36AE96943FCD96E34468867AD8F +:10414000D0B860DA732D0444E51D03335F4C0AAA2E +:10415000C97C0DDD3C710550AA41022710100BBE31 +:1041600086200CC925B56857B3856F2009D466B978 +:104170009FE461CE0EF9DE5E98C9D9292298D0B0AD +:10418000B4A8D7C7173DB359810DB42E3B5CBDB75A +:10419000AD6CBAC02083B8EDB6B3BF9A0CE2B603DB +:1041A0009AD2B1743947D5EAAF77D29D1526DB0490 +:1041B0008316DC73120B63E3843B64943E6A6D0DDB +:1041C000A85A6A7A0BCF0EE49DFF099327AE000A26 +:1041D000B19E077D44930FF0D2A3088768F2011EB9 +:1041E000FEC206695D5762F7CB67658071366C1950 +:1041F000E7066B6E761BD4FEE02BD3895A7ADA1071 +:10420000CC4ADD676FDFB9F9F9EFBE8E43BEB71751 +:10421000D58EB060E8A3D6D67E93D1A1C4C2D838DB +:1042200052F2DF4FF167BBD16757BCA6DD06B53F41 +:104230004B36B248DA2B0DD84C1B0AAFF64A033680 +:10424000607A0441C3EF60DF55DF67A8EF8E6E31FF +:1042500079BE69468CB361CB1A8366BCA0D26F2548 +:1042600036E2685295770CCC03470BBBB916022295 +:104270002F260555BE3BBAC5280BBDB2925AB42BAA +:10428000046AB35CA7FFD7C231CFD0B58B9ED92CBF +:104290001DAEDE5BB0C2649B26F263EC9CA36A7524 +:1042A0000A936D02A906099C3F360EEB85670772DB +:1042B00013570005824ABF95147AB8E2AE2BB17B42 +:1042C000381BB60C9B8ED2920DBED5E5B7EFDC7CC9 +:1042D00021DFDB0BD4D2D38642E2D4F1F8B3DD6820 +:1042E0006E83DA1FCD16BE815B26B9F6E177B06F1B +:1042F0007747B718E65A0888706A0FFFCA3B066608 +:104300005C0B0111FF9E658F69AE62F8D3FF6B6194 +:1043100045CF6C1678E20AA0EED20DD75483044E36 +:10432000C2B30339612667A7F71660D04D476949C4 +:10433000DB776E3E4A6AD1AEDC5AD6D9660BDF40D7 +:10434000F03BD83753AEBCA9C59EBBDE7FCFB2478A +:10435000E9FFB5301CF2BDBD8AC2BACA3093B3536F +:10436000A6A3B4240536D0BA9306D7CD2957DE5478 +:10437000BF67D9232E7A66B3B84A61C4021B685D51 +:10438000942B6F2A37BE0BB4A18E0CC31BDF055ACA +:104390008DEF022D00002110422063308440A55093 +:1043A000C660E770088129914AA16BB18CC1ADD17B +:1043B000CEE1EFF13112100273325222B552944223 +:1043C000F772D662399318837BB35AA3BDD39CC3CB +:1043D000FFF3DEE36224433420040114E664C7746F +:1043E000A44485546AA54BB528850995EEE5CFF51B +:1043F000ACC58DD55336722611163006D776F666C3 +:104400009556B4465BB77AA719973887DFF7FEE76A +:104410009DD7BCC7C448E5588668A778400861188E +:1044200002282338CCC9EDD98EE9AFF948896999BA +:104430000AA92BB9F55AD44AB77A966A711A500A62 +:10444000333A122AFDDBDCCBBFFB9EEB799B588B0A +:104450003BBB1AABA66C877CE44CC55C222C033CAE +:10446000600C411CAEED8FFDECCDCDDD2AAD0BBD5A +:10447000688D499D977EB66ED55EF44E133E322E02 +:10448000511E700E9FFFBEEFDDDFFCCF1BBF3AAFAA +:10449000599F788F8891A981CAB1EBA10CD12DC108 +:1044A0004EF16FE18010A100C230E320045025409E +:1044B00046706760B9839893FBA3DAB33DC31CD3FE +:1044C0007FE35EF3B1029012F322D23235421452EE +:1044D00077625672EAB5CBA5A89589856EF54FE54A +:1044E0002CD50DC5E234C324A0148104667447643E +:1044F00024540544DBA7FAB79987B8975FE77EF79E +:104500001DC73CD7D326F2369106B016576676768D +:10451000154634564CD96DC90EF92FE9C899E98969 +:104520008AB9ABA94458654806782768C018E108DD +:104530008238A3287DCB5CDB3FEB1EFBF98BD89B3D +:10454000BBAB9ABB754A545A376A167AF10AD01A2D +:10455000B32A923A2EFD0FED6CDD4DCDAABD8BAD89 +:10456000E89DC98D267C076C645C454CA23C832C7D +:10457000E01CC10C1FEF3EFF5DCF7CDF9BAFBABFDD +:10458000D98FF89F176E367E554E745E932EB23ECD +:10459000D10EF01E0000000017B7D13852499D39E6 +:1045A000FAED6B3A0AD7233BAC8BDB3BE2E9953C57 +:1045B00016FB4B3D158C0A3E645DBC3E0000803FFF +:1045C000A1F82D408273EC401BAFA0418F645A428A +:1045D000C7691443E3B6C94343148944544F3A4569 +:1045E000AC38FD45EE14AC460000A0C10000803F91 +:1045F0000000803F0000803F0000803F0000803FBF +:104600000000803F0000803F0000803F0000803FAE +:104610000000803F0000803F0000803F0000803F9E +:104620000000803F0000803F0000803F000020C16C +:104630000000803F0000803F0000803F0000803F7E +:104640000000803F0000803F0000803F0000803F6E +:104650000000803F0000803F0000803F0000803F5E +:104660000000803F0000803F0000803F0000803F4E +:10467000000000000000803F0000803F0000803FFD +:104680000000803F0000803F0000803F0000803F2E +:104690000000803F0000803F0000803F0000803F1E +:1046A0000000803F0000803F0000803F0000803F0E +:1046B0000000803F000020410000803F0000803F5C +:1046C0000000803F0000803F0000803F0000803FEE +:1046D0000000803F0000803F0000803F0000803FDE +:1046E0000000803F0000803F0000803F0000803FCE +:1046F0000000803F0000803F0000A0410000803F9C +:104700000000803F0000803F0000803F0000803FAD +:104710000000803F0000803F0000803F0000803F9D +:104720000000803F0000803F0000803F0000803F8D +:104730000000803F0000803F0000803F0000F0410B +:104740000000803F0000803F0000803F0000803F6D +:104750000000803F0000803F0000803F0000803F5D +:104760000000803F0000803F0000803F0000803F4D +:104770000000803F0000803F0000803F0000803F3D +:10478000000020420000803F0000803F0000803F8A +:104790000000803F0000803F0000803F0000803F1D +:1047A0000000803F0000803F0000803F0000803F0D +:1047B0000000803F0000803F0000803F0000803FFD +:1047C0000000803F000048420000803F0000803F22 +:1047D0000000803F0000803F0000803F0000803FDD +:1047E0000000803F0000803F0000803F0000803FCD +:1047F0000000803F0000803F0000803F0000803FBD +:104800000000803F0000803F000070420000803FB9 +:104810000000803F0000803F0000803F0000803F9C +:104820000000803F0000803F0000803F0000803F8C +:104830000000803F0000803F0000803F0000803F7C +:104840000000803F0000803F0000803F00008C425D +:104850000000803F0000803F0000803F0000803F5C +:104860000000803F0000803F0000803F0000803F4C +:104870000000803F0000803F0000803F0000803F3C +:104880000000803F0000803F0000803F0000803F2C +:104890000000A0420000803F0000803F0000803FF9 +:1048A0000000803F0000803F0000803F0000803F0C +:1048B0000000803F0000803F0000803F0000803FFC +:1048C0000000803F0000803F0000803F0000803FEC +:1048D0000000803F00000001000002010A03010205 +:1048E000040102050102060000070000080000099B +:1048F00000000A11020B00000C00000D00000E0069 +:10490000000F0000101101111105121105131105FE +:1049100014110515110516110517110518110519A2 +:1049200011051A11051B00001C00001D00001E00CF +:10493000001F1101201101210102220102230102A5 +:104940002401022501022601022701022801022971 +:1049500001022A01022B01012C01052D00002E006D +:10496000002F000030000031000032000033000052 +:1049700034000035000036000037000038000039F0 +:1049800000003A00003B00003C00003D00003E00FB +:10499000003F0000400000410000420000430000D2 +:1049A0004400004500004600004700004800004960 +:1049B00000004A00004B00004C00004D00004E007B +:1049C000004F000050110151110252110453000018 +:1049D00054000055000056000057000058000059D0 +:1049E00000005A00005B00005C00005D00005E00FB +:1049F000005F00006011016111016211FF6311028B +:104A000064110265110266110267110268110269E0 +:104A100011026A11026B11026C11026D11026E110A +:104A2000026F1102701102711102721102731102F0 +:104A30007411027511027611027711027811027950 +:104A400011027A11027B11027C11027D11027E118A +:104A5000027F11028011018111018211FF83110176 +:104A60008411018511FF8611018711018811FF89C9 +:104A700011018A11018B11FF8C00008D00008E0046 +:104A8000008F000090000091000092000093000051 +:104A9000940000950000960000970000980000998F +:104AA00000009A00009B00009C00009D00009E00FA +:104AB000009F0000A00000A10000A20000A30000D1 +:104AC000A40000A50000A60000A70000A80000A9FF +:104AD0000000AA0000AB0000AC0000AD0000AE007A +:104AE00000AF0000B00000B10000B20000B3000051 +:104AF000B40000B50000B60000B70000B80000B96F +:104B00000000BA0000BB0000BC0000BD0000BE00F9 +:104B100000BF0000C00000C10000C20000C30000D0 +:104B2000C40000C50000C60000C70000C80000C9DE +:104B30000000CA0000CB0000CC0000CD0000CE0079 +:104B400000CF0000D01101D10000D21102D3110218 +:104B5000D41102D50000D60000D70000D80000D93B +:104B60000000DA0000DB0000DC0000DD0000DE00F9 +:104B700000DF0000E00000E10000E20000E30000D0 +:104B8000E40000E50000E60000E70000E80000E9BE +:104B90000000EA0000EB0000EC0000ED0000EE0079 +:104BA00000EF0000F00000F10000F20000F3000050 +:104BB000F40000F50000F60000F70000F80000F92E +:104BC0000000FA0000FB0000FC0000FD0000FE00F9 +:104BD00000FF0000000000000C0000000C000C00B2 +:104BE0000102070000000800070008000800070095 +:104BF0001000080007001800080007002000080047 +:104C000007002800080007003000080007003800EF +:104C100008000700400008000700480008000700DF +:104C20005000080007005800080007006000080056 +:104C300007006800080007007000080007007800FF +:104C40000800000102030405060708090A0B0C0D01 +:104C50000E0F080000000800080008000800080007 +:104C600010000800080018000800080020000800D4 +:104C7000080028000800080030000800080038007C +:104C8000080008004000080008004800080008006C +:104C900050000800080058000800080060000800E4 +:104CA000080068000800080070000800080078008C +:104CB0000800000102030405060708090A0B0C0D91 +:104CC0000E0F8182838485868788898B8C8D8E8F59 +:104CD000919293959697999A9C9D9FA0A2A3A5A720 +:104CE000A8AAACAEB0B2B3B5B7B9BCBEC0C2C5C756 +:104CF000C9CCCED1D4D7D9DCDFE2E6E9ECF0F3F7CA +:104D0000FAFE0000244C000000000020B402000065 +:104D100056070000B04C0000B40200205410000000 +:104D20000401000061130E401A4004120206160529 +:104D3000030325013A080341D203A92F0B3A803F10 +:104D400004124612460A1964020942646946A9BE61 +:104D500016CDCC4C3D10921E140D1041122043FF75 +:104D6000FF1B98080B718B24010C9A300C9A3C0C99 +:104D70009A480C9A540C9A600C9A6C0C9A780C9A7B +:104D8000840C9A900C9A9C0C9AA80C9AB40C9AC019 +:104D90000C9ACC0C01501A01021330022A2008C9C7 +:104DA00002311AFF01490539064901491B014C002E +:104DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:104DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:104DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:104DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:104DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:00000001FF diff --git a/firmware/novatek_nt36523_fw01.bin.ihex b/firmware/novatek_nt36523_fw01.bin.ihex new file mode 100644 index 000000000000..28f601f8e53d --- /dev/null +++ b/firmware/novatek_nt36523_fw01.bin.ihex @@ -0,0 +1,12291 @@ +:1000000000020000000000008F9E0100002002009E +:100010000000020077C1000036F990DF1DC75FE2E3 +:1000200003000000000000000000000000000000CD +:10003000000002000000000000200200AA5F9B0BED +:10004000000A020000000000002A0200CB94D02029 +:100050000032020000000000005202000C52006852 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F00078C10200FF00000000000000739B9C5AC2 +:1001000000020000000000008F9E0100002002009D +:100110000000020077C1000036F990DF1DC75FE2E2 +:1001200001000000000000000000000000000000CE +:10013000000002000000000000200200AA5F9B0BEC +:10014000004A020000000000006A0200AF0FDC1548 +:100150000072020000000000009202000C520068D1 +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00078C20200FF00000000010000A9C19F7941 +:10020000480001A2EABF0000EABF0000EABF000008 +:10021000EABF0000EABF0000EABF0000EABF00003A +:1002200048000000DD4D0000EABB0000EABB000012 +:10023000DD4D0000EABB0000DD4D0000DD4D00009B +:10024000DD4D0000DD4D0000DD4D0000DD4D000006 +:10025000DD4D0000DD4D0000DD4D0000DD4D0000F6 +:10026000EABB0000EABB0000DD4D0000DD4D0000F0 +:10027000DD4D0000EABB0000EABB0000DD4D0000E0 +:10028000DD4D0000DD4D0000DD4D0000DD4D0000C6 +:10029000DD4D0000DD4D0000DD4D0000DD4D0000B6 +:1002A000DD4D0000DD4D0000DD4D0000DD4D0000A6 +:1002B000DD4D0000DD4D0000DD4D00004800000078 +:1002C00048000000DD4D0000DD4D0000DD4D000068 +:1002D000DD4D00004800000048000000480000001C +:1002E00048000000480000004800000048000000EE +:1002F00048000000480000004800000048000000DE +:1003000048000000480000004800000048000000CD +:1003100048000000480000004800000048000000BD +:1003200048000000EA040000EA0400005A07000048 +:100330008415000084150000841500008415000059 +:1003400084150000841500008415000000000000E2 +:100350001C09000024090000E8090000620A0000EE +:10036000AA0A0000580B0000B80B0000D60B0000D2 +:10037000DE0B0000E60B0000EE0B0000F60B0000A9 +:10038000080C0000100C00001C0C00000A110000FA +:100390002E0C0000180D0000600D0000680D00001C +:1003A000A60D0000B80D0000CA0D0000F00D000001 +:1003B000900E00000C0F0000140F0000260F00002C +:1003C000BC120000BE120000E2120000EA1200009F +:1003D000F2120000021300000413000010130000CA +:1003E0001E1300003A13000000000000000000008F +:1003F000B8140000D4140000201500006615000099 +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:100450003A0FEFFC421E80203A1F883C6412A4022F +:10046000642204023A1F883C803F640264029205C1 +:1004700096374420012C38210202643200029ED9B2 +:1004800064320003DD2264020043640000083A1F66 +:1004900088046412A403642204033A1F8804421EE1 +:1004A00080213A0FEFC4640000043AFFECBC3A0F1D +:1004B000943C421E80203A1F883C640264029205EC +:1004C00096374420012C382102028E09DD223A1F82 +:1004D0008804421E80213A0F94043AFFEC846400A1 +:1004E00000043AFFECBC3A0F943C421E80203A1FB5 +:1004F000883C6412A402642204023A1F883C64020D +:100500006402920596374420012C382102028E099C +:10051000643200029ED964320003DD22640200438B +:10052000640000083A1F88046412A40364220403D0 +:100530003A1F8804421E80213A0F94043AFFEC844B +:10054000640000044FF200223A0FEFFC421E8020AC +:100550003A1F883C45D2D7F0801F64126402965F30 +:100560009E49C1053CFD4A4D480000043CFD4A4EF1 +:10057000E80CDD2F4E03000A3A1F8804421E80213A +:100580003A0FEFC464000004640224024410C00067 +:10059000FE0FFE0D640224036400000845D2D7F06C +:1005A00045F2FE006400800292189604C0054401E2 +:1005B0007010420E002144F004BCE802DD2F3CFD27 +:1005C0004A4FDD2F640FFFEAFC004462EEEC440268 +:1005D000C37884209AB0EA33EA38AE31FC80FC005C +:1005E00084003C0FFB5BEBFB3C0FFB6A3C0FFB6E9C +:1005F000EBCC3C0FFB7F3C0FFB643C0FFB6F3C0FD5 +:10060000FB6B3C0FFB773C0FFB6C3C0FFB683C0F1C +:10061000FB653C0FFB5E3C0FFB7D3C0FFB823C0F00 +:10062000FB753C0FFB763C0FFB733C0FFB59EB6BF0 +:100630003C0FFB6D3C0FFB633C0FFB5DEADA3C0FAC +:10064000FB603C0FFB623C0FFB813C0FFB743C0FDB +:10065000FB7C3C0FFB693C0FFB5F3C0FFB713C0FCD +:10066000FB613C0FFB703C0FFB783E07EC0764031B +:100670000003EA7AEB6D64122402964C8040C103B9 +:10068000640300036422240364020002660000067F +:1006900064020003640000086403040246029C1024 +:1006A0005000007CEA7A6403080244000633EB6DD4 +:1006B00064020002EA4364020003FC804403F0ED9C +:1006C000A6405A1801048420AE404413F0DAA6086C +:1006D000EB21AE088404EA7A84254403F049AE4055 +:1006E00044100053DD43AE40DD9EDD9E4443F114D3 +:1006F000B464927840000F04B6044403F138AC406F +:1007000084204403F13AAE404403F104B64084210E +:100710004403F136AE40F808A640964CC103AED073 +:10072000D5FC4413F134EA36EA3183FFA608960E6D +:10073000C803AED0D5FC4403F134A6009604DD9E78 +:1007400084A0D20738301400383094088CA1D5FA30 +:10075000DD9EFC00DD42C00C8407DD4A8400DD4ADA +:100760004412C2788402804144300100DD45FC809F +:10077000FC0080C0DD42C012441FFF9FEBC3AE40AF +:1007800096304412FE61AE08EB734412FE62AE086E +:10079000DD43DD44C603AE40D5FEFC80FC403C7D1D +:1007A000FB308140DD42C05B852384C03C2DFB30A3 +:1007B00040212480A051C108F85C5A08010640106D +:1007C000240CFF8F97B18D215A980FF2F85F5A08C9 +:1007D000010442633C088387B97DB87C8E24964926 +:1007E000BA7FF85C5A08010558630001D502C605B6 +:1007F0005AA8AE048006F8118420EB1DAE404402D6 +:10080000FE63A6408420AE40A681AE414900112976 +:100810005A0801065803000249FFFFACEA66EA40A5 +:10082000EA28A78097B05A600204AE88D5FB4472CC +:10083000FEF1A6385A008608440000C1DD41F87F69 +:10084000AE40D5FF49003CC384003E07EE0180273F +:1008500080064422C5F18461DD45FCC05AA8AE4B38 +:1008600084E380C03C2DFB3040211C80A051C10B93 +:10087000B4029649A093F8125A08010640001C0CD5 +:10088000FF8797B18CE15A780FEF3C2DFB308382C4 +:10089000B93DB83C8E249649BA3F49FFFF295A0812 +:1008A0000105EA6542633C0884204402FE78AC40BE +:1008B0004412FEF1EA66C619442FFFEEAE88842288 +:1008C000AE404412FE60440FFF8FAE084422FE612A +:1008D0009630AE10EB7396004422FE62AE10846335 +:1008E00080418402DD45D520442FFF86AE888422D6 +:1008F000D507441FFF86EB1DAE408422EA66AE405A +:100900004403F007A6004412FE639600AE084403B9 +:10091000F004A6004422FE649600AE1084028041DA +:100920008060DD4584C04412FEF180418461840210 +:10093000DD45EA21804184028461DD45DD43DD44FB +:1009400083FFC603AE40D5FE4412FEF1EA36EA311B +:10095000A608C003AED0D5FDFCC03A6FA0BC840091 +:10096000802049006B5384006405E403EBADA44090 +:1009700096669649C102D5004422FEF6AE50A440C8 +:10098000964EC910A4409656C90DA440965EC90A59 +:10099000A4409666C907A4405410810096494E129F +:1009A00000864413F00EA408960EC806A58854636A +:1009B000010097B1C6208400EAACA788AC084413B4 +:1009C0008D203E07EBB4AE0844138D21AE084413CE +:1009D0008D22AE0844138D23AE0844138D24AE0837 +:1009E00044138D25AE0844138D26AE0844138D277D +:1009F00097B0AE0849FFFDEA49000EBFEBADA44039 +:100A0000964EC908A4409666C905A400540001008A +:100A1000C00349003A12EBC38420AC404472C17851 +:100A20008400EADA3C7FFB303C0FFB5D3C0FFB7936 +:100A3000DD42C805507381003C7FFB3049FFFE8BCF +:100A4000800649FFFEAD8423EA66AE40840144136C +:100A5000F7D3AE084413F7D9AE08FA56EA9D44120C +:100A6000FE7849FFFE6F3C0DFB304432FE7C0400F3 +:100A700000093E07282D401020093E17282E40105F +:100A8000400992183E17282F3E0728304422FE7D49 +:100A9000F8054432FE7E4422FE7FA618A650960238 +:100AA000964AAE58AE1083FFD508A4005400020049 +:100AB000C0048402490010704413F029A608EAB467 +:100AC000AE088400EA5B3C0DFA4A4413F00EA648D7 +:100AD000EB904413F00FA6481010003D49003A1562 +:100AE0003C0FFB3EFA044900546CFA044900546977 +:100AF0002E07ECF8DD4AEA3F9E81E648E80B8421A8 +:100B00004010880C5410808FC10550007FE0960083 +:100B1000DD41490006613A6FA084DD9E84013C0FEF +:100B2000FB5BDD9E3BFFFEBC3C0DFB668C01EBFBE3 +:100B3000DD465A080246DD40A6015A08033EDD5A4A +:100B40005A08023BDD42C03C2E07EB8CE603E8036B +:100B50008C01D50284003E07EB8C2E37EB8C4402CF +:100B6000E6C8EB1A40000CE0EAA3EA7BEAA3EA7BC2 +:100B7000EAA3EA7B3B0044003B00C4205A3801064C +:100B80008400EAE8EBB3D5098406EBBA4400007DA3 +:100B9000EB878401EAE8EBA6EA979E41E622E903A7 +:100BA0005A08040F49004B054900A046C0098400BB +:100BB000EA2AEAD1D505DD42C0038400EB532E07B3 +:100BC000EEE65A0801103C1DFB662E07EEE5E2201A +:100BD000E803EBA6D507EBB38400EAE884003E0700 +:100BE000EEE63BFFFE84DD9E3BFFFEBC3C0DFB6A58 +:100BF0008C013C0FFB6ADD40A6008E01E602E82D69 +:100C00002E07EBB95A08550A3C03F6138C019601DE +:100C1000E60AEBB9E91DD508DD42C0182E07EBB096 +:100C20005A085515D5F28404DD4184013E07EF32A0 +:100C30008400EA25DD40A6005A080105EAA8EA6119 +:100C4000D5078E02E602E900D5038400EBB9EA3944 +:100C50003E07EBB9EA8BD5038400EBB93BFFFE847A +:100C6000DD9E3A6F98BC4403F06BA6003E07EC058E +:100C7000DD46C8062E07EC05961F5A000F16FA101F +:100C8000DD4184013C0FFB6EEB6949006FE2DD4002 +:100C90008422DD5749006FF78420840284468061F6 +:100CA000808180A1DD56EA20DD9E3A6F9EBC49001E +:100CB0006A68C017840049006A68F82280C05A0830 +:100CC0000111DD465A0802043C6FFB6744000080B6 +:100CD000DD41DD40EBCBEAC9EBCF848149002397AE +:100CE00049006A46C00784013C0FFB7A8400490032 +:100CF0006A4349006A76C025840049006A76490043 +:100D00006AC35A08011FEA7EA6005A08130EDD5274 +:100D1000A6088E02E603E904A6095A0808068420FC +:100D2000EA7EAE40D51784C1440000803C6FFB5A78 +:100D3000DD41DD40EBCBEAC9EBCF8086490023677C +:100D400049006A46C007840049006A4684013C0F96 +:100D5000FB5D3A6F9E84DD9E3BFFFEBCDD59842126 +:100D60003C1FFB7BAE40EA3844238D433E07EBB982 +:100D7000A6108801AE10DD40A681542100FD5A2046 +:100D80000403DD5749006F58C00A8409DD41FA1891 +:100D9000EA418403EAA584013E07EBDC2E07EEAFAF +:100DA0008C0196003E07EEAFDD42C80484013E0789 +:100DB000EE9D3BFFFE84DD9E3A6F98BC84013C0FA4 +:100DC000FB7FFA11DD414403F082A600C003EAA8CC +:100DD000EA61EA20DD9E84013C0FFB64DD9E840114 +:100DE0003C0FFB6FDD9E84013C0FFB6BDD9E84019D +:100DF0003C0FFB77DD9E3A6F98BCFA12DD4184010F +:100E00003C0FFB6CEA20DD9E84013C0FFB68DD9EFD +:100E10003A6F98BCFA13DD41EA20DD9E3A6F98BC28 +:100E2000FA14DD4184013C0FFB5EEA20DD9E3A6F3F +:100E30009ABCEFF43C0DFB7DC81EEBE1C01CDD420B +:100E40002E17EE965CF080A0C80BE915441358905D +:100E50004423806844300C808402EA60D50CE90B9E +:100E60002E07EE93C8038401D5045A0801058402B5 +:100E70003E07EE93490017953C0DFB7D8C013C0F1E +:100E8000FB7DEA5A8C013C0FFB712E17EE9AEA5A51 +:100E9000E220E805EA5A96003E07EE9AEA5AEA5E30 +:100EA0009600EBE9EB3449001482000F8006EA5EFD +:100EB000490014923E07EBB7DD42C005EBF3C803CF +:100EC0008401D508DD42C805EBF396005A00010302 +:100ED00084003E07EB9BEBFC5A08010B84003C0F9F +:100EE000FB58440124F83C0E031E4900170D3C6DCD +:100EF000FB7D5A68020F3C0DFB625A08010BDD4274 +:100F0000C80880064413970044238D54EA87EA609A +:100F1000EC0C3A6F9A84DD9E3A6F98BC84013C0FCA +:100F2000FB693E07EEDC4403F07EA6405A10010F39 +:100F3000A6405A10020CA6405A100309A6405A10A7 +:100F40000406A6405A101003A60084418420806243 +:100F500080824400B101EAB349003355EA20DD9EA6 +:100F600084013C0FFB82DD9E84013C0FFB75440332 +:100F7000F064A640964CC910A64058108001AE40BF +:100F8000DD40A6008E02E602E90E3A6F98BCEA390F +:100F9000EA61EA20D508A640964CC105A640EAD6EB +:100FA000AE40DD9EDD9E3A6F98BCFA15DD418401AE +:100FB0003C0FFB76EA20DD9E3A6F98BCFA16DD41C5 +:100FC00084013C0FFB73EA20DD9E3A6F98BCFA1750 +:100FD000DD41FA04DD4A84013C0FFB59490019B791 +:100FE0005A08A104EA39EA618403EAA5EA20DD9EF1 +:100FF0003BFFFEBC84013C0FFB7CEB7F44138D4622 +:101000008C01EB6BA6088C01AE0849000F38EBFC95 +:10101000C815DD42C005EBF396005A000107DD421A +:10102000C806EBF3C80484013E07EB9B84003C0F29 +:10103000FB58440061A83C0E031E49001226DD4205 +:10104000C021DD555A08201F2E07EE935A08020CC6 +:10105000EB7F5A080114EB14442019004402988CC9 +:10106000DD48D50C5A08030B845F4452988C80628B +:101070004402B18C3A228C24D8FE84018420490099 +:101080001B4EDD42C803490016933BFFFE84DD9EE4 +:101090003A6F98BCFA18DD414403F00AA600DD411E +:1010A0004403F00DA600DD41EBADA600DD41440395 +:1010B000F00FA600DD414403F01AA600DD41440311 +:1010C000F01BA600DD414403F082A600DD4144038D +:1010D000F353A600DD414403F369A600DD41440358 +:1010E000F386A600DD414403F387A600DD414403F7 +:1010F000F3CFA600DD414403F40CA600DD418401DA +:101100003C0FFB6DEA39EA61EA20DD9E84013C0F69 +:10111000FB63DD9E4403F403A60096005A08010415 +:101120003C0FFB60DD9E84013C0FFB62DD9EFC20DA +:1011300084013C0FFB6284003C0FFB713C0FFB61A0 +:10114000DD40A6419E8BE642E9055A1006045A1876 +:101150000D52DD54A6485A18014EEA3A2E07EBF715 +:10116000C80C2E07EB9DC809EBF93C0DFFF9D00523 +:101170004402C4B849006BAEDD40A6015A00030426 +:101180005A080D19EB31C8162E07EBF7C8132E07B6 +:10119000EB9DC810DD4BA600C805802044238D417F +:1011A000D5079E43E622E80644238D41A650490018 +:1011B0007127EA97C0048E04E602E80784203C0DFC +:1011C000FB3B80418061D514DD42C0043C64082EA5 +:1011D000D5033C64086EDD42C0043C24082FD503CF +:1011E0003C24086F3C0DFB3B96719691846149004D +:1011F000721DDD42C003490011ABDD52A6095A0041 +:101200000D079E82E642E9035A080726A6885A2857 +:1012100001232E67EB8A97B0CE3ADD59A6005A0813 +:101220000137DD4CA7C097F85A780132800180263B +:10123000EAD8DD578007EA25DD59AF80DD4CAF8065 +:10124000840AEA3E8404DD4A2E07E920DD4A80074D +:10125000EA7DD51D5A08041C2E67EEA3CE18DD5B6F +:10126000A6485A100215DD4AEB0704000008962F25 +:10127000DD4ADD408026EAD8DD578401EA25DD59C4 +:10128000AF80DD4CAF8084013E07EEA3EB225A080D +:101290000104490016D9FCA0FC20EB073C5DFFF3DC +:1012A000D0043C5DFFF4D80CEAFFC80ADD59A60063 +:1012B0009600C806DD5BA6885A280103AE082E07F3 +:1012C000EBA9C023EB47EACFD8202E67EB8A840036 +:1012D00097B03E07EBA9CE19DD59A6005A080116B2 +:1012E000DD4CA7C097F85A7801118026DD40EAD876 +:1012F000DD578405DD4A8007EA25DD59AF802E07DA +:10130000EBDCC803DD5BAE08FCA03A6F9EBC490075 +:10131000098ADD42C80A2E07EC075A080104480072 +:1013200000CC84013E07EC0744138D45A6088C01D0 +:10133000AE08EBE1C0178401DD4ADD4280C0C00782 +:1013400049000AA6840049001592D50C4412C478BD +:10135000804184648402DD45800649001588490087 +:10136000092FDD42C02C3C53F7A03C03F79FD00E61 +:101370002E07EF3C8C0196003E07EF3C2E07EF3C1A +:1013800050007F909600DD41D50484003E07EF3C7D +:101390003C03F6A0C8083C03F6A1C8052E07EF3CA5 +:1013A000E605E90D84013C0BF7A284003E07EF3C03 +:1013B0004412C734840280418060DD45EBE1C009FE +:1013C00084013C0FFB723E07EB8D49FFFEB2D5094D +:1013D00084023E07EB8D49FFFF61DD59A600F8B698 +:1013E000840184C03C0FFB793C6FFB7D3E67EC07BA +:1013F000490009403C03F7A25A0801263C6BF7A2BA +:101400002E07EF425A00FF082E07EF428C0196008C +:101410003E07EF423C03F6A04412FE6A9600AE0877 +:101420003C03F6A14412FE6B9600AE088441840092 +:101430003C0BF6A0FA313C0BF6A180624400D1B01F +:101440008082EAB3DD465A080238EBE1C035DD4060 +:10145000A6015A08032E3C6DFB225A68022ADD427F +:10146000C02B3E67EB8CEB1A4402E7C8EAA3EA7B89 +:10147000EAA3EA7BEAA3EA7B3B0044003B00C420EA +:101480008406EBBA4400007DEB878401EAE8EBA612 +:10149000EA979E41E622E9035A08040F490046896B +:1014A00049009BCAC0098400EA2AEAD1D505DD4279 +:1014B000C0038400EB533A6F9E84DD9EDD9E3A6F3D +:1014C00098BCFA19DD4184013C0FFB814900612081 +:1014D000EA9EC80449006BBDD503490060E4EA20D8 +:1014E000DD9E84013C0FFB74DD9E84013C0FFB5F9D +:1014F000DD9E3A6F98BC8403DD4A8401EA7DEA20D0 +:10150000DD9EDD9E3A6F98BC8401F806EA20DD9EE0 +:101510003A6F98BC84004900105BEA20DD9E3A6F68 +:1015200098BCFA1BDD418400842A490034EDDD4279 +:10153000C003EAA8EA61EA20DD9E3A6F9EBC44033C +:10154000F41CA600E6024EF200AE4900100ADD428D +:10155000C012DD40A6015A08030F2E07EBA3C00BF3 +:1015600084004412DFD43E07EBA380418402443060 +:101570000320EA60DD42C01CEBA4A6C096D85A380E +:101580000118842084C044002330804180833C6B58 +:10159000F6A03E37EF43EAB396013C0BF7A02E07C7 +:1015A000EF435A000203F80D3C6BF7A0F80ADD4246 +:1015B00080C04E030078EBA4A7C097F85A700104CE +:1015C000480000714400BB908026FD1380873E7761 +:1015D000EF43EAB33E07EF482E07EF435A08020BEA +:1015E0003E67EF4C3E67EF4D3E67EF4E3C6BF79F1B +:1015F000D51A8026FD1380874400AB00EAB33E076E +:10160000EF498026FD1380874400AB01EAB33E0713 +:10161000EF4A802644002330FD138087EAB3960109 +:101620003C0BF79F84003E07EF434412C72E840211 +:1016300080418060DD453C03F6A1C8342E07EF48A9 +:10164000C80A2E07EF49960EC8062E07EF4A9602E3 +:101650004E04002984013C0BF6A12E07EF48C00779 +:101660004400009DDD412E07EF48DD412E07EF4984 +:10167000960EC0074400009EDD412E07EF49DD4174 +:101680002E07EF4A96024E0400084400009FDD41F9 +:101690002E07EF4ADD4184024412C532804180604A +:1016A000DD452E07EBD9C0068401EB7284003E07AE +:1016B000EBD93A6F9E84DD9E3A6F98BC4413F7EEE7 +:1016C000A60896009684C203EAA6AE088400F857DE +:1016D000EA20DD9E3BFFFEBC84013C0FFB784413F7 +:1016E000F7EFA60896009684C203EAA6AE08840126 +:1016F000F846F829EBFC5A08010C3C0DFB53C006D8 +:101700008402490009933C0FFB53490012FD2E0748 +:10171000EE9DC0048E013E07EE9D3BFFFE84DD9EE4 +:101720003BFFFEBCDD465A08020584013C0FFB70FE +:101730004413F7C9A60896009684C203EAA6AE0829 +:101740008400F81D49000CFADD42C80BEA7EA600B1 +:10175000C008DD40EBCBEAC9EBCF848149001E57BE +:101760003BFFFE84DD9E3A6F98BC4413F7CAA6087F +:1017700096009684C203EAA6AE088401490008DFF9 +:10178000EA20DD9E3BFFFEBC2E07EC08C81DB4011D +:10179000A6003C0FFBD5640264024412FFF03C0F2C +:1017A000FBD4B6013C1DFBD54402FFF4B620460134 +:1017B0001223500003444412FFF8B6012E07EC0830 +:1017C0008C013E07EC08FA1ADD41EAA8EA613BFF0A +:1017D000FE84DD9EFC6384003C0FFB4B49003B898B +:1017E0005A00081749003C082E07EF58441000A083 +:1017F0008C013E07EF588403DD47840DDD4A490024 +:101800003C39840EDD4A8403441000A1DD47B1C396 +:101810004492E93E44A0012CDD424E0200793C1C7A +:101820000323442397EC40110420A448440397D891 +:10183000964BAC403C0C0324441397DA4001002043 +:10184000A4009603AC08F86349003C4E5A0003CC50 +:101850005A080207840444100060DD47D5C65A00C8 +:1018600013DDF869F86DDD4CA78097B0CED62EB7A2 +:10187000EC035AB801D38403EBB6DD47DD5A3E676B +:10188000EF3A5A080206490041D53EB7EBA349009A +:101890003D4FDD555A081209EA728420EA9A5A0827 +:1018A00001048400F82FDD555A080408490043C597 +:1018B000EB89F8B2F826D5285A081406EB89F8B552 +:1018C000F820D5225A0819068400802049001727DD +:1018D00049003D7C490044B95A08020448FFFF868C +:1018E000DD555A080508490043A7EB89F8F3F809C4 +:1018F000D50B5A08150AEB898403441000A9DD476B +:10190000EAE2EA4DEA6349004374F948840344106B +:1019100000A2DD474900470F80C08401EBE75A0869 +:10192000010448FFFF995A68030448FFFF5D5A68A5 +:101930001303F9348403441000A3DD47EB3F840311 +:10194000441000A4DD47DD4CA600C807DD40A641D9 +:101950005A180D048423AE41440000A3EBB72E07B0 +:10196000EBC64E0301012E17EBA2440297E8490093 +:101970002043F081EBB68403DD473C6DFB478006D6 +:1019800049003FB25A6806132E07EF055A08010FA7 +:101990002E07EF04C80BEA88C8092EB7EBCF4EB369 +:1019A0000006490072763EB7EF052E07EF06C82EF7 +:1019B000EA88C02CE6C2E82A3C0C03275A00070537 +:1019C000EA4F5A0809248404EACE800649003D5BA8 +:1019D000EA884E6300E6EA94EBE0EA885CF00030C7 +:1019E000E9152E100C848401EBA5C90684273C1E42 +:1019F0000327F805D50B8407EA6484003E000C84B5 +:101A0000EBF6EBE083FF8405EACE80064900415007 +:101A1000DD555A0814098403441000A6DD47F85E1A +:101A20004800009F5A68040D8403441000A7DD4756 +:101A300084003C0FFB5449003D10EACED5545A684F +:101A4000050EEB135A08035049003D075A08034C92 +:101A50008401EACE8400EA99D546EA88C844E6C201 +:101A6000E83680064900418A5A68013280064900FA +:101A700042743C0DFB545CF00BB8E8048C013C0F45 +:101A8000FB5484003E07EB96EB138E04E602DD5513 +:101A9000E90F5A00150E3C1C04365A100503C905FF +:101AA00084203C1E0320D50484223C1E03208E1477 +:101AB000E602E90BEBC6C8073C0008A4C0068E018D +:101AC000EA99D5033CA808A48400EB53DD555A08D5 +:101AD000150B8403441000A8DD473C0DFB35EB0BD0 +:101AE00049003E54F001EB1A4422E49049002128B9 +:101AF000DD558E14E602E90AEB22C808EA8CC00420 +:101B00002E07EB89C803EBE2C005EAAAC803EB364F +:101B1000C027EB139E42E623E80A84223C1FFB22E7 +:101B20005A08031F8401EB538401D50F5A08050797 +:101B30008400EA9984013E07EB893C1008A4C9108F +:101B40008401EA903E10114EAC3814938002149335 +:101B500080014402E4083A138C004900103D8401DE +:101B60003E07EBC62E07EBEA5A080512DD59A60020 +:101B70005A08010EEA965A08090B2E17ECD42E27A4 +:101B8000EBE42E07EBEA49000D7FF8082E07EBEA9D +:101B90005A000603F8038400EAF748FFFE3FEA858F +:101BA000EBE048FFFF1C3C0FFBEADD9E3C0FFBE92E +:101BB000DD9E4402B7F43C0FFBD9DD9EFC4180E181 +:101BC0008123CC09B400C2090260001F0220001E5C +:101BD00097B3D50CA001CA05A580A48197B3D506FB +:101BE000026000310220003097B380269693800770 +:101BF0004900496A001480005A10FF058C218801B1 +:101C00009201EA83803FB081490049C5B41F38136F +:101C10008111F001382381118402EABE4203087366 +:101C2000EA8FFCC1FC60B480C311C4079F64E6A2C4 +:101C3000E90484A01050007D2E57EBCA2E67EB8E6E +:101C40005C5280015CA30001D503814380A34E4216 +:101C500002848E84E6824EF3028080C0A60C81232B +:101C6000816280E14E0300854E530083EB5FC32801 +:101C7000A0D13C5DFB3CA498A51902018031023142 +:101C80008030EBEB96939723960396DBE807EBEE19 +:101C90005A58010550108510F81100538008CD04E2 +:101CA0008A44EBC8D5055A5831088A03EB1CE9046D +:101CB0008401EBA8F803501082884800025A5010A3 +:101CC00088465033006E84408082800BEBFF3C439B +:101CD000586C3C53588C97219B6540421406806099 +:101CE00041107C0AA03DA07CFF2294019521412057 +:101CF00007F5404217F50423800A0503800B944939 +:101D000095694E9200254208942442020C73424287 +:101D10008C69884388A0980CEB4440491400EAD9A8 +:101D20004058C00088248865EA4AEBF5EB4CC004B3 +:101D300044F007D0D50344F00BB8EB3AE20F4EF273 +:101D40000090EB824E03008D4800008A3C07F47639 +:101D50003D37F47AFE1C40004C1641307C0A433972 +:101D6000942443320073424280694800008CA63DAF +:101D70005A001F04480000934E530091EB5F4E92AF +:101D8000002C043580013C5DFB3CA498A5190201A0 +:101D9000803102318030EBEB96939723960396DBEC +:101DA000E807EBEE5A580105501085B2F8130053BE +:101DB0008008CD048A44EBC8D5055A58310A8A03F5 +:101DC000EB1CE9068401501080A2EBA8F803501028 +:101DD000832A480001D2501087A45033006E8441FA +:101DE0008480800BEBFF3C53588B3C4358AB976986 +:101DF00088858060A03DA07C4052140694019569BE +:101E0000412007F5EBA30423800A0503800B411151 +:101E1000FC0A944995214E920027420890244202E0 +:101E20008C7342420C69884388A0980CEB4440496B +:101E30001400EAD94058C00088248865EA4AEBF5C6 +:101E4000EB4CC00444F00708D50344F00AF0EB3A29 +:101E5000E20FE806EB82C80444000C7FEBF50203B6 +:101E60000008D5243C07F4773D37F47AFE1C400087 +:101E70004C1641307C0A43399024433280734242ED +:101E8000006988B3980C884388B2EAD94048C000FA +:101E9000EB4488258864EA4AD510841F4E92000AD4 +:101EA0001003006C22030004EBF512030018D507A1 +:101EB0001003006E0203000C1203000EA63E4E0338 +:101EC00000954EA30093EB5F4E92002BB46B3C5DEC +:101ED000FB48A498A5190201801F0231801EEBEB7C +:101EE00096939723960396DBE807EBEE5A58010585 +:101EF00050108654F81300538009CD048A44EBC86F +:101F0000D5055A581F0A8A03EB1CE90684015010B4 +:101F10008144EBA8F803501083CC480001325010E4 +:101F200088465033006F84408481800BEBFF8060D3 +:101F300041007C0AA03F3C535808A07E3C43583ADD +:101F400094010423800C0473800D4E92002F976936 +:101F50009B2CE2A4525780009569EBA39521411078 +:101F600007F54208102442028C7342420C699449DE +:101F700088A08843980CEB4440489400EAD988F044 +:101F800088248867EA4AEB99EB4CC00444F007D0F8 +:101F9000D50344F00C80EA74E20F4EF2009EEB820F +:101FA0004E03009B48000098413007F53C07F47849 +:101FB00097699B2CFE1C3D17F47AE2A4411046362B +:101FC000525780009569EBA34008FC0A9521FE2436 +:101FD0004202C47342424469944988A0980CEB447D +:101FE00040F9940048000090A63F5A003104480090 +:101FF00000924EA30090EB5F4E92002BB46B3C5DC1 +:10200000FB48A498A5190201801F0231801EEBEB4A +:1020100096939723960396DBE807EBEE5A58010553 +:10202000501086F6F81300538009CD048A44EBC89B +:10203000D5055A581F0A8A03EB1CE9068401501083 +:1020400081E6EBA8F8035010846E4800009E501003 +:1020500087A45033006F84418082800BEBFF3C5398 +:1020600058393C43586B97698885A07F80604052FF +:102070001406A03E944995690423800CEBA30473D5 +:10208000800D4101FC0A401083F5411004089521A0 +:102090004E9200264208102442028C7342420C6980 +:1020A000884388A040089000E2118825EAD988F08A +:1020B000882F8867EA4AEB99EB4CC00444F00898F3 +:1020C000D50344F00C80EA74E20FE806EB82C80402 +:1020D000440013FFEB9902030009D5243C07F4796F +:1020E0003D27F47AFE1C4000481641207C0A432913 +:1020F0001024432280734242006988B24008900055 +:10210000E21188258843EAD988F0882F8867EA4A4F +:10211000D518841F4E9200121003006D2203000593 +:10212000EB9912030019020300083C0BF7B00203FD +:1021300000093C0BF7B1D52C1003006F0203000D12 +:102140001203000F0203000C3C0BF7AE0203000D5C +:102150003C0BF7AFD51D843FC3061010006C101068 +:10216000006DD5161010006E1010006FD511503391 +:10217000006C48FFFDAA5033006C48FFFE3250331C +:10218000006D48FFFED25033006D48FFFF66FCE053 +:10219000FC203C6DFBE984E1A772A7B3C20284FF77 +:1021A000C9089E69FF4442510473B6A388A7D50BA2 +:1021B0009E71FE8C80204211147388474201147373 +:1021C000B62380A0B6A4FCA0FC6384C081A081419A +:1021D000F281818380E4816581038126E2E8E9124E +:1021E0008008F112F201B0C2B10349FFFFD3F0023F +:1021F0008D01380681118920F0033806811188C0CD +:10220000D5EE8AEC8405FFFB426380738441422350 +:102210000800800A802949004657002580005A207E +:10222000FF068C41884040010409EADDB044B085D6 +:10223000490046B1F00438150111F00538250111A7 +:102240008402EABE42048873EA8FFCE3FC658121C4 +:102250003C1DFBE9F28200208032F28400208033B2 +:10226000F28520D08039A68A20E0803AA64B5080A3 +:1022700000209E09F083960AF0889E12F08696123E +:10228000F0899E0A4472C758854050C17FFFF0878D +:102290003C0DFBE900000009E3404EF200EBB218F0 +:1022A0004E0200D58E04E6024EF300D10404000471 +:1022B0005A080204480000CBB37F0404800540653F +:1022C00088088806A6C0CB24A642E622E9029EC959 +:1022D000A703F007E080E8038C81D502F403844073 +:1022E000B65FEB9EF00280A8F88C04148006F2041E +:1022F000EBC18A20FE540424800838212E02880273 +:10230000EABE22147FF2880D9603E001D52DA74185 +:102310004C56402DA6C2E662E9038E61D502846068 +:10232000A703F007E080E8038C81D502F403EB9E5D +:102330008400B61F501080A28441F00280A8F8618A +:1023400004148006F209EBC142110073F204FE543A +:102350000424800838212E028802EABE22147FF26B +:10236000880D9603E020EB74D506841F100400004E +:1023700002047FF212047FF60404800588C0A6F2EE +:10238000CB28A630E602E9029EC1A731F006E08024 +:10239000E8038C81D502808CEB9E8401B61F50101F +:1023A00081448440F00250540001F82B041480074B +:1023B000F205EBC18A20FE540424800838212E0245 +:1023C0008802EABE22147FF3880E9603E001D52E20 +:1023D000A773F003D82DA6F0E662E9038E61D5025B +:1023E0008460A731F006E080E8038C81D502808C00 +:1023F000EB9E8441B65F501081E640540800F00225 +:1024000049FFFEE4041480073820AE02F1084220A0 +:102410008073F105FE8C04148008EBC18801EBA2E7 +:1024200022147FF3880E9603E020EB74D506841FF8 +:102430001004000102047FF312047FF722047FF6E8 +:10244000AC3822047FF7AC39D50E22038000120489 +:102450007FF62203800112047FF7841F100400001E +:10246000100400018D418CE45084004C48FFFF12A1 +:10247000FCE55A0001054403F7DED5034403F7DD0C +:1024800044100069AE40EA2D8420AE40DD9E8401F8 +:10249000DD9EFC204473F080A7B897B05433001F32 +:1024A000583180A0AEF8DD48AFB8FCA0DD588E01F1 +:1024B000EAD0DD9E44100055DD43AE404413F7F1F1 +:1024C000A6089604C003EA2DD5FCDD9E44100055F5 +:1024D000DD43AE404413F7F0A6089604C003EA2D8E +:1024E000D5FCDD9E4443F7FDA72097205A0801053F +:1024F00058020008D503540200F75A180104EA5F95 +:10250000D503540000FB5A280104EA91D502EB29B7 +:102510005A380104EA43D502EAA64413F7FDAE088F +:10252000DD9EFC2180E08400EA2384008020844139 +:102530008060506F8007F837C703EA38EA238421A8 +:102540004403F7C0AE40442FFFE74403F7C3AE8017 +:1025500096B04403F7C6AE8084404403F7C1AE8012 +:1025600084774403F7C4AEC0EB7396004433F7C7D7 +:10257000AE184403F7C2AE8092D084434403F7C53B +:10258000AE8097B0EBBDAF804403F7CCAE40EA36E7 +:102590008020EA31A6089600C003AED0D5FC80208A +:1025A0008040806049FFFFA0FCA184004412D7B0A6 +:1025B000845FEB028C015A0809FEDD9EFC2084201A +:1025C0004432D7B04442FE5D4452FE5C44638D41C8 +:1025D00044738D403801840096885A00FF20E649F4 +:1025E000E81D44F023F03827880040F13C00DD0F5F +:1025F0000A12161A1E2A2A2226003C2DFB37AE107C +:10260000D50DAE38D50BAE30D509AE28D507AE20E6 +:10261000D505EB59D5033E07E9398C215A1809DC59 +:10262000FCA04403F7C0A6404402ED1CAE40441396 +:10263000F7C3A648AE434413F7C6A648AE464413B4 +:10264000F7C1A648AE414413F7C4A648AE444413AC +:10265000F7C7A648AE474413F7C2A648AE42441394 +:10266000F7C5A648AE454413F7C8A648EBD7DD9E8C +:10267000FC00EA6A4402ED1CA6804413F7C0AE8851 +:10268000A6834413F7C3AE88A6864413F7C6AE8864 +:10269000A6814413F7C1AE88A6844413F7C4AE885C +:1026A000A6874413F7C7AE88A6824413F7C2AE8844 +:1026B000A6854413F7C5AE8800100008EBBDAE40F8 +:1026C000FC80FC4081405400807F80C180E28123F7 +:1026D0005A087F05440000C8DD41EA6A5AA8010A89 +:1026E0008400F9B4EB858420AE404403F7CBD503D6 +:1026F0004403F7CC542480FF4413F7C0AE8896B04F +:102700004413F7C3AE8896B84413F7C6AE88401496 +:10271000A00996484423F7C1AE50401320099648BB +:102720004423F7C4AE504013A00996484423F7C78A +:10273000AE504014C00996484423F7C292D0AE5020 +:1027400097B04413F7C592F0AF8897F84413F7C8D1 +:10275000AFC88421AE40EA36EA31A640C103AED00C +:10276000D5FD5AA80108800AF971441FFFAAEB851C +:10277000AE408401FCC0FC004403F02CA78044134D +:10278000F3EC8401AE0884474413F3EDAE884413A0 +:10279000F3EEAE084413F3EFAE084423F3F08420C5 +:1027A000AE5084644423F3F1AED04423F3F2846248 +:1027B000AED04423F3F3AE5097B04413F3F4AE0815 +:1027C0009674C9455413000296484423F439C1064F +:1027D0003E07EFAF8403AE10D5043E37EFAFAE50E7 +:1027E000EA6A97968401F8D697B08400F8D3C605B4 +:1027F00084013E07E944D5033E67E944DD585A08A1 +:1028000002074413F02DA608EA43AE084401D8009D +:1028100044128E10442025A049FFFE3D441FFF8630 +:10282000EB1DAE408420EA66AE40441000404403F5 +:10283000F6CAAE40FA214403F697AE40FA2F44039D +:10284000F384AE4084214403F380AE40DD585A0047 +:10285000011E4605555A4412C12C50000AAA3C0FCD +:10286000FA4F804184028464DD45DD43DD44AE409F +:102870004605A5AA500005A53C5DFA50D8FE4601C4 +:102880002345500006783C0FFA50FC80FC0049FFBD +:10289000FE8EDD4C4412D7B0A600AE08DD4BA6007C +:1028A000AE09EBB1A600AE0A4402FE5CA600AE0B78 +:1028B0004402FE5DA600AE0CEBE2AE0FEB3310005F +:1028C0008008804184698402DD45FC80FC2044004E +:1028D00000C6DD414403F7C0A600DD414403F7C153 +:1028E000A600DD414403F7C2A600DD414403F7C35F +:1028F000A600DD414403F7C4A600DD414403F7C54B +:10290000A600DD414403F7C6A600DD414403F7C736 +:10291000A600DD41EBBDA600DD414462FE504472DD +:10292000FE5608030001DD414C63FFFDEBA4A60049 +:10293000DD41440000C7DD41FCA0FC004423F7F06A +:10294000C80380A2D5034453F7F1A6689648DA1766 +:10295000540080029780C609440000C3DD41F81787 +:102960008400F8188400FC809656C118440000C406 +:10297000DD41F80D8006F80E8006FC80546080FE74 +:10298000C60D440000C5DD418006DD4149FFFFA0C2 +:10299000840149FFFD708400FC808401FC80FC40C0 +:1029A000814080E180C28123EA6A5405007F5A0891 +:1029B000010A8400F84B8420EB85AE404413F7CB2A +:1029C000D5034413F7CC542480FF4403F7C0AE80F2 +:1029D00096B84403F7C3AE8096B04403F7C6AE8002 +:1029E0004004A00996004423F7C1AE104003A0099B +:1029F00096004423F7C4AE10EB7396004423F7C748 +:102A00004034C009AE1096D84403F7C292F0AEC06D +:102A100097F84403F7C592D0AFC097B0EBBDAF8035 +:102A20008401AE088401FCC05A0001054413F7CCB0 +:102A3000D5034413F7CB4433F04AEB77A688C2039F +:102A4000AF18D5FD5A08010BFC0049FFFD6C441F6F +:102A5000FFAAEB85AE408402FC808402DD9EFC412F +:102A6000DD5884C15A0001044800008B4413F7F17B +:102A7000EA36EA31A6089604C003AED0D5FC3C6D18 +:102A8000FB304413F1289CB484638402DD45441375 +:102A9000F1185023000884638402DD454413F100DB +:102AA0005023001884648402DD454413F12C502324 +:102AB000001084638402DD454413F1305023001478 +:102AC00084638402DD454413F1045023001C8464B4 +:102AD0008402DD4584014413F30EEAAE8060DD45D7 +:102AE000001F8007440FFF80FE0FEA234413F30EFC +:102AF000EAAE84618402DD45440FFFAEEA23EAAC0E +:102B0000EAAE84618402DD458401EA234413F10DB9 +:102B10008402EAAE8461DD45DD43DD44AE40460516 +:102B2000555A50000AAA3C5DFA4FD8FE460123458B +:102B3000500006783C0FFA4FEA6FEA75840AEA41C2 +:102B40008401EA534413F133EAAE8060DD45006F3F +:102B5000800754030004C0F3978FC606440000C2E8 +:102B6000DD4184C1D50D4605A5AA500005A5441236 +:102B7000C1303C0FFA50804184028464DD458006F8 +:102B8000FCC1DD585A00010544024A00DD9E4402A2 +:102B90000A00DD9EFC405A000203F818840880C138 +:102BA000DD4A4403F31CA600C0064413F33FA60805 +:102BB000EAE6AE084403F369A6009604C009FA22C7 +:102BC000EA66AE408420EB1DAE40480000EC4413A2 +:102BD000F36CA608EB215800000AAE082E97EFAF61 +:102BE0002E77EFAE5A90010448000080CF1E800976 +:102BF000DD4A4413F374A60858000003AE08C61259 +:102C000084053E97EFAEDD4A2E07EFAD80478C017D +:102C10003E07EFAD840280208069808780A7DD5663 +:102C2000D50444000898EA4184003E07EFAECE1D6B +:102C30004463F36A8402DD4AA630EB29EA5FAE30D2 +:102C4000440001C2EA41EA21FA00AE0880418461F1 +:102C50008402DD458403DD4AA6304413F369EA4368 +:102C6000AE30EA36EA31D51E8400F809844080A2ED +:102C70008062848384228401DD568401490059588E +:102C8000EAA7FA0380268046AE3084618402DD45DF +:102C90008401EAF3EA40EA28A6305A0014CBAE8851 +:102CA000D5FCA6089604C803AED0D5FC8404DD4A42 +:102CB0004422FEF04433F04AEB77A610EA215A0092 +:102CC0001104AF18D5FBFA02AE088440EB1DAE80AC +:102CD000840280418060DD458405DD4A2E07EFAC2B +:102CE0008C013E07EFACD55ECF0EC60D84013E07CA +:102CF000EFAE8405DD4A84028027804780678483A5 +:102D000080A7DD5684003E07EFAEC61E4472FEF07B +:102D10004493F04A44A00055A638EAA75A00130C81 +:102D20008440840110A4800080208062848380A27B +:102D3000DD56D5F38401EAF3FA04AE30802684022E +:102D400080468461DD45EA21EA36EA31A6085A0068 +:102D50001004AED0D5FC8403DD4A4413F36AA60800 +:102D6000EA36EA43AE08EA314413F369A60896044A +:102D7000C803AED0D5FC8404DD4AEAA7FA01AE3020 +:102D80008026804684028461DD45EA40EA28A63038 +:102D90005A001204AE88D5FC2E07EFAC8C013E071A +:102DA000EFACFCC04423F02BA6502E37EFAF964873 +:102DB0005A380109C00458008008D50A540080F729 +:102DC000D507C00458008010D503540080EFAE1022 +:102DD000DD9E4403F02AA600EBE596005A18010494 +:102DE000EA57DD9EEAD4DD9EC807FC008401EA5B59 +:102DF0008405DD4AFC80DD9EFC00EA9E5A0801093C +:102E00004403F7F0A600560000019604FC808400FD +:102E1000FC80DD59A6009600C004EABD5E000001FA +:102E2000DD9EFC4097808402DD4A8006DD4A441224 +:102E3000FEF28401AE084402FEF3AF8084028041BA +:102E40008060DD45EA92EABC4492FEF649FFFFC38A +:102E50005A00010B8404441000F2DD47EB3FAFF051 +:102E6000EABA5A08ECF58403DD4A84004412FEF203 +:102E7000AE084412FEF3AE08FCC0FC403C6DFB7E85 +:102E800097B0DD465A000207DD40A6015A0009034B +:102E9000F8D0EB47EA67D003EA8ED8292E57F01016 +:102EA000D6042E57F011DE0CDD585A0001078408B5 +:102EB000EA2B2E001163EA814472C800F8BA2E078B +:102EC000F014E2C0E9FAEBE55A1801F88429EB2D79 +:102ED0002E1011603E17EEA04C6000052E57F01525 +:102EE000DEEC840AEA3E4472C800F8A33C0DFFFB06 +:102EF000D0043C0DFFFCD8272E07F000E2C0E90FFC +:102F0000DD585A000103F8158409EA2B840AEA3EC9 +:102F10002E00116DEA6B4472C7E8F88B2E57EFF85C +:102F2000D6052E57EFF94C5340E5DD585A080104F9 +:102F3000480000E08408EA2B2E001163EA81447205 +:102F4000C7E8F8773C0C0004D0043C0C0005D850CE +:102F50002E57EFE2DE0CDD585A080103F83E8408D4 +:102F6000EA2B2E001162EA81EBFEF8632E57EFED9B +:102F7000D6162E57EFEFD6132E57EFF1D6102E5749 +:102F8000EFF3D60D2E57EFEED60A2E57EFF0D607F9 +:102F90002E57EFF2D6042E57EFF4DE0CDD585A0808 +:102FA0000103F81B8408EA2B2E001164EA81EBFE72 +:102FB000F8402E57EFE8D60E2E57EFE9D60B2E57D6 +:102FC000EFEAD6082E57EFEBD6052E57EFEC4C5311 +:102FD0004094DD585A0001044800008F8409EA2B10 +:102FE000840AEA3E2E00116DEA6BEBFEF822EBC07C +:102FF000D0043C0C0003D84B2E57EFCFDE0CDD582D +:103000005A000103F80E8409EA2B2E001160EA6BC6 +:10301000EB49F80F2E57EFCADE0EDD585A080104AF +:103020004800006D8408EA2B2E001162EA81EB490A +:10303000480000692E57EFCCDE08DD585A08015FC2 +:10304000840AEA3EEB49D55E2E57EFD5D6162E57A9 +:10305000EFD7D6132E57EFD9D6102E57EFDBD60D5C +:103060002E57EFD6D60A2E57EFD8D6072E57EFDABF +:10307000D6042E57EFDCDE42DD585A0001408408AA +:10308000EA2B2E001164EA81EB49D53C3C0DFFF59B +:103090004C02C00E2E27EFAF84292E001161EB2DBC +:1030A0005A280104EA6BD52EEA81D52CEAEA4C02B3 +:1030B000C0132E57EFB0D6042E57EFB1DE21DD58E6 +:1030C0005A00011F8408EA2B2E001163EA81447222 +:1030D000C7A0D518EACF4C02C016DD585A08011314 +:1030E0008409EA2B2E001160EA6B840AEA3ED50AB5 +:1030F0004472C7E8D507EBFED505EB49D50344720A +:10310000C7A044A3F01DEAABEAE7DD5A5A0802154E +:10311000DD465A080212A77A9E319600DE065894C0 +:10312000800110950000D50800538013D8055494F1 +:1031300080FE10950000FCC0FC003C6DFB7E3C0D49 +:10314000FB465A0009083C0DFB465A00080448009B +:10315000019BDD465A000208DD40A6015A00090421 +:103160004800016D3C1DFB323C2DFFF39770DD588C +:103170004C1100063C2DFFF44C1140132E17F01695 +:103180004C12809F2E17F0174C12809B2E27F010A8 +:103190004C5101252E17F0114E120146F8163C2D08 +:1031A000FFFB4C1100063C2DFFFC4C1140112E176B +:1031B000F000E2A14EF200852E27EFF84C51010FEE +:1031C0002E17EFF94C12C130480001093C2C0004C5 +:1031D0004C1100063C2C00054C1140672E17EFE205 +:1031E0004C12C0125A080103F898EA344E17000432 +:1031F0008E21EAB5EA344E13011784463C2FFB4773 +:10320000EAECF8A12E27EFEDD20D2E17EFEF4C12BE +:10321000800A2E17EFF14C1280062E17EFF34C1296 +:10322000C01F5A080103F879EA344E1700048E21B2 +:10323000EAB5EA344E1300F8EAFDEAEC4C51007BA3 +:103240002E17EFEF4C12807E2E17EFF14C1280827A +:103250002E17EFF34C12C0E8480000832E17EFEE54 +:103260004C1280922E17EFF04C12808E2E17EFF238 +:103270004C12808A2E17EFF44C1280862E17EFE83E +:103280004C12801F2E17EFE94C12801B2E17EFEA0D +:103290004C1280172E17EFEB4C1280132E17EFEC09 +:1032A0004C12C0C2D50D3C2C00024C1100063C2C27 +:1032B00000034C1140772E17EFCF4C12C0075A0075 +:1032C0000103F841480000A62E17EFCA4C12C015A2 +:1032D0005A080103F822EA344E1700048E21EAB599 +:1032E000EA344E1300A184463C2FFB4784413E271D +:1032F000EF05EAECF8282E27EFD5D20D2E17EFD7E1 +:103300004C12800A2E17EFD94C1280062E17EFDBD5 +:103310004C12C02A5A08010448000088EA344E17AB +:1033200000048E21EAB5EA344E13007EEAFDEAEC91 +:10333000DA04842BEB3DF8072E17EFD74C12C006AA +:10334000842CEB3D480000702E17EFD94C12C005BD +:10335000842DEB3DD5682E17EFDB4C12C065842E13 +:10336000EB3DD5612E17EFD64C12800E2E17EFD8FD +:103370004C12800A2E17EFDA4C1280062E17EFDC63 +:103380004C12C0525A000152EA344E1700048E21EA +:10339000EAB5EA34C94884413C2FFB47EAECD543FF +:1033A0003C2DFFF54C1140105A080108EABD4E07AC +:1033B000003D8E01EA6BD539EA344E1700358E2177 +:1033C000EAB5D5313C2C000B4C20C01B2E27EFB0AA +:1033D000D2052E17EFB14C12C0275A000127EA344C +:1033E0004E1700048E21EAB5EA34C91DDA0484249C +:1033F000EAFDD5038425EAFD8420EAECD5143C5C83 +:10340000000AD9115A0801104403F403A600C80D9C +:10341000EABD4E0700048E01EA6BEABDC8068407C8 +:10342000EA3ED5035A080105EABDC82DD5042E0F82 +:10343000EE9FC829840BEA2BD526DD465A000224CC +:10344000EB47EACFD820DD585A08010EEABD4E07F7 +:1034500000048E01EA6BEABDC8168407EA3E8404C4 +:10346000DD4AD5118402DD4A2E0FEE9E4E0700057F +:103470008E013E07EE9E2E0FEE9EC8058407EA3EA3 +:103480008403DD4AFC80FC00EB7F96005A080103B0 +:10349000F8062E57EFD5D8058400EAA24800005759 +:1034A0002E57EFD6D80D8401EAA2DD585A00014FFD +:1034B0004412E6C8EB10EA878402DD45D5472E5753 +:1034C000EFD7D8048402EAA2D5412E57EFD8D80D01 +:1034D0008403EAA2DD585A00013A4412E748EB108F +:1034E000EA878402DD45D5322E57EFD9D80484040B +:1034F000EAA2D52C2E57EFDAD80D8405EAA2DD58C2 +:103500005A0001254412E7C8EB10EA878402DD4522 +:10351000D51D2E57EFDBD80C8406EAA2DD585A00E1 +:103520000116EBF18041FA788402DD45D50F2E5764 +:10353000EFDCD80C8407EAA2DD585A0001088402A7 +:103540004412E848EB10EA87DD45FC80440396808E +:10355000A600961F8E01E6013EF7EBFEDD9EFC20E5 +:103560002E07EBFE97805A6801314413968144037D +:103570009680A600A68844139682A648407010093B +:103580004010A00840108A0444239683A690FE575A +:1035900044239684A6D096D85A7001075A78020B15 +:1035A000F8038006D508800744239690DD45800700 +:1035B000D5028403842044239680AE504423968F02 +:1035C000AE103E17EBFEFCA08401FCA02E07EC0918 +:1035D000C005FC008403DD4AFC80DD9EFC00C802BF +:1035E00084263E17EBEA49005487FC80FC03B61F93 +:1035F000F181F282F383B45F4412A50AEA228402C5 +:10360000F484F585DD45F2014412A69AF838F202F9 +:103610004412A82AF834F2034412A9BAF830F2048A +:1036200044129ECAF82CF2054412A05AF828F20A55 +:103630004412A1EAF824F20B4412A37AF820F20C07 +:103640004412988AF81CF20D44129A1AF818F20ED5 +:1036500044129BAAF814F20F44129D3AF810F2108B +:103660004412AB4AF80CF2114412ABAEF808F21255 +:103670004412AC12F8044412AC76F213EA2284022B +:10368000DD45FC832E27EFAF5A2801044800008D4A +:10369000FC4580E08121840480273C6DFB7EDD4772 +:1036A0005A7005075A78060448000066F804EA963E +:1036B0005A00090448000077EBA4A6008E02E60633 +:1036C0004EF20071E724E916E730E83F44437A28D8 +:1036D000F831EAC444137578F486F487F488F489E1 +:1036E000B65FF381F082F183F284F385FD20F82B3D +:1036F000D52C44038388B61F44038518F081EB81E1 +:10370000F08244037BB8F08344037D48F084440393 +:103710007ED8F085440386A8F08644038838F08775 +:10372000440389C8F08844038B58F08944137578A2 +:10373000EAC4442377084433789883FF444380687D +:10374000445381F849FFFF54EB1AF823EBF1804111 +:10375000FA78F821441397DC80418464F81C8404CF +:10376000441000CEDD47490004598404441000CFC2 +:10377000DD47D5189630661000088E26E622E90847 +:1037800050107FF6E622E9048E12E602E80BEB1AEF +:103790008041EA878402DD45EBF184028041FA78BA +:1037A000DD458401FCC58401DD9EFC0084858E011D +:1037B0004050109684C68CA138509602FF34404287 +:1037C000900D972FAF10041080114000800D9604CB +:1037D000AE18FC8004108012FA58FE14EA984010CB +:1037E0000440EA9D882004008009EA46DD9E04101A +:1037F0008012FA58FE14EA9840100440EA9D88208E +:10380000040080089600DD9EFC60816004000008D2 +:10381000858185C081215480003F81AC80CC80EEC1 +:1038200050A58004879FE3064EF300AF9E319600BB +:10383000802A49005DA38E015CF000234EF200A1B6 +:1038400044F036503827810140F13C004A003C00EA +:103850006C002E012E012E012E012E012E0196004C +:10386000280164004C00E800F000F80000010801A5 +:103870001001180120014600C000C800D000D80087 +:10388000E0002E012E012E012E012E0146004600E1 +:103890004600460046008CE197F8D5729AB74EE391 +:1038A00000081024800011C4800185C1D56910244E +:1038B0008001D5669A3710048002D562EA674CB061 +:1038C000400D9AB75AD801061024800485A0D55817 +:1038D0001024800585A0D554EBC04CB040529A37D7 +:1038E00010048004D54DEA674CB0400D9AB75AC811 +:1038F0000106102480068580D5431024800785802A +:10390000D53FEBC04CB0403D9A3710048007D53806 +:103910009A3710048008D5349A3710048009D530BE +:103920009A371004800AD52C9A371004800BD528BA +:103930009A371004800CD5249A371004800DD520B6 +:103940009A371004800ED51C9A371004800FD518B2 +:103950009A3710048010D5149A3710048011D510AE +:103960009A3710048012D50C9A3710048013D508AA +:103970009A3710048014D5049A37100480038CC140 +:1039800097B048FFFF52FCE0FC61F081F101840038 +:10399000F8323E00115884003E07EE9984C04492EC +:1039A000E9489DF1F1019638F8262E17EE9988C95D +:1039B000AE3188013E07EE9980C75A7808F4F101CC +:1039C0008409F8193E001161F101840AF8143E00DF +:1039D0001162F101840BF80F3E001163F101840CB8 +:1039E000F80A3E001164F101840DF8053E001165EE +:1039F000F101FA0549FFFEFD3C7C00023E00116D1D +:103A000084C04493978050A3800404038008962FB9 +:103A1000E0C0E80B8006802A40B3240049005CAE79 +:103A20008CC1EADD97B0D5F2FCE1FC004462D7BC62 +:103A3000B4064412C800F8118386B8084412C7E8D7 +:103A4000F80CB8114412C7D0F808B80F4412C7B820 +:103A5000F804B8184412C7A049FFFED8FC804423DC +:103A6000F7DAA6509648C00458108020D5035410A9 +:103A700080DFAE50DD9EFC4084014900523D840150 +:103A8000F8272E17EE9946008B3B88014413F7F870 +:103A9000B60184014413F7FCAE084413F7CDAE0819 +:103AA00084293E07EE9E8404EB2D446000C8DD4A65 +:103AB000EA6FEA752E0FEE9E4E0700088EC1EA539C +:103AC000840A97B1EA41CEF78405DD4A840049FFB4 +:103AD000FFC8FCC0FC20DD465A0802174473F41CE2 +:103AE000A7B8DD44DD43AE40840A4410009997B086 +:103AF000DD47DD59A600C806A7B897B0EA2DEB3F11 +:103B0000D5F95A6802FBFCA0FC21F081DD585A0867 +:103B1000011FF8354412FEF0A608EAA75A0850FE25 +:103B2000F81644000051F825F82AA6304472FEF039 +:103B30005A0852FDF0014900703F44000053AE386E +:103B40008027804784618402DD45FCA1490022A1D1 +:103B5000EAA7EA58F80E4403F04ADD44AE40800676 +:103B6000A640EAA75A1851FEF00149007025EB5A09 +:103B7000AE308026840280468461DD45DD44DD432D +:103B8000AE4083FFA6305A0853FFFCA1FC20DD584D +:103B9000EA92EABC5A080113AFF0EA21A6085A08D3 +:103BA00052FF8401EB69DD44DD43AE40DD46C0FFDA +:103BB00044100053EA66AE40FCA08401EB69AFF00C +:103BC000DD46C0FFEA21EB5AAE08804184618402E1 +:103BD000DD45FCA0FC4280C0B0013A100C2022AFB1 +:103BE0008002F702049F8003DD465A000209802705 +:103BF0008049806A8402DD458401FCC200030065BF +:103C0000001300648A015A00082F000300650013A6 +:103C10000065E608840CE80FF80812A10000F8031C +:103C2000149100020013006580464220807383FFD8 +:103C3000A9D1D5118E284E00FFF912A10000F8037A +:103C4000149100020013006580468E284220807384 +:103C500083FFA9D1000300658C0196001003006565 +:103C60008401FCC28400FCC2FC000060806400206F +:103C700080654C61002900308064844C8081424121 +:103C80008873003080642252000080814241887332 +:103C900080C1A0E20040806442620873002080641A +:103CA000A1318C41969010208064002080645A28B5 +:103CB000080B844010208064002080658E48969018 +:103CC00010208065AD40A901A8C2FC803C1DFB58B6 +:103CD0003C1DFB5800300064844C42018873501036 +:103CE00087A3222000004400004B42110073800192 +:103CF0003C1C031EE201E8053C0FFB588401DD9EDD +:103D00008400DD9EFC023C6DFB71EBFCC0489630EC +:103D10009E43E631E806DD54A648C9035A080B065F +:103D200084003E07EB9BD53B2E500C7D2E000C7C77 +:103D3000D824EBE597B03C0DFB535A0003083C0335 +:103D4000F6288C0196013C0BF6285A68020E5A1090 +:103D5000010C3C03F6285A0001F084003C0BF628C5 +:103D600084003C0FFB53840084203C0BF6283C1F4E +:103D7000FB533E07EB9BD5134402E40849FFFFA821 +:103D8000C0D9B0014412E40849FFFF708402F10277 +:103D9000F203223F8002EA603C0FFB53FC824403A3 +:103DA000F7C9A640C1038420AE40DD9EFC01DD586A +:103DB0005A000148EB47EBC0D0043C0C0003D8414B +:103DC000EA5AEA5E8C019600B081503F800549FFB7 +:103DD000FCEEEA5E000F80040460800849FFFCFCF2 +:103DE000001F800597AFC11CEA5AEA5E8C0296005C +:103DF000EBE9EB3449FFFCDB000F8006EA5E49FF8C +:103E0000FCEBC80AEA5AE206E807EB4EC805840153 +:103E10003E07EBD9D51A84003E07EBD9D516C80A60 +:103E2000EA5AE206E8072E07EBEEC8048401EB72BB +:103E3000D50C840AEA418400EB723E07EBAED5054F +:103E40008400EB723E07EBAEFC81EBE55A180106ED +:103E50004412C4D4F804DD9E4412C46438008101C5 +:103E600050007F5BEAD083FFDD9EFC40DD4480C0D4 +:103E7000DD43AE40EA80A608C8FF2E37EFAF44A26C +:103E8000C464440000A5947150737FA04492C4D4CC +:103E90005A380116882A8041380519098402DD45FF +:103EA000EA6AF815380499015A08A5FEF81C44126C +:103EB000C4D43805190938009909FCC08829804103 +:103EC0003804990984618402DD45EA6ADD43DD44F2 +:103ED000AE4097F844038D44AFC083FF3805190105 +:103EE0005A08A5FE50037FB0960044138D44AE08D7 +:103EF000840083FF4412C464380099093804990986 +:103F0000FCC0FC008400441000C1DD47EA96C803F1 +:103F10008407EAF7DD530060005184018026DD4705 +:103F20005A680212EB63EA99DD53EB430000005339 +:103F3000C8038400D53C5A00013B5A0002395A0894 +:103F400003FAD5355A6803378402EA90EB63EA999D +:103F5000DD530010005300000054968C4210840B77 +:103F6000C914CA0AC8038404D5225A080104840665 +:103F7000D51E8408D51CC8038405D5195A08010428 +:103F80008407D5158409D513CA0AC803840AD50F36 +:103F90005A080104840CD50B840ED509C803840B80 +:103FA000D5065A080104840DD502840F3C0FFB3559 +:103FB000D50E5A68040D84003E07EBCF3E07EF0490 +:103FC000DD42C8118401EA908426D50B84003E07A7 +:103FD000EF0484013E07EBCFDD42C8058401842550 +:103FE00049FFFAFEFC80FC0180C08400EA23DD4228 +:103FF000C8133E67EBBE4412C3AE804184618402A5 +:10400000DD4584014412C3AEEAAE8060DD45EA9628 +:10401000005F8007D8F1FC81FC00DD42C010EA9609 +:104020005A000305EA965A080AFF84004412C3AEF8 +:10403000EAF7804184618402DD45FC80840A49FFFF +:10404000FFD4FC80FC00DD42C80AEA965A08080446 +:104050008409D504EA96C8038407EAF7FC80FC00CB +:10406000EB9B84203C0FFC0C10100050EAA1EBA14C +:10407000101000531010006010100061FC80FC0054 +:10408000DD42C825EA6D001080F25A180121EA28A5 +:10409000EA40AE883C2DFC0C001100F2C902D500AC +:1040A0004412FEF3A64896485A10040C5A10030A0C +:1040B0005A1006085A100A065A1009045A180B0812 +:1040C0003E17EEA2100100F2100100F38401FC8003 +:1040D0002E07EEADC80FEA6D3E07EEAF002080510F +:1040E0003E07EEAE1000805184013E27EEAC3E0745 +:1040F000EEADDD9EFC005A0806048401D5045A0882 +:10410000070684003E07EB97D51C5A080D0784006C +:104110003E07EB978421D5075A080E0B84013E0712 +:10412000EB9784203E17EBDA3E07EBC7D50A5A0817 +:1041300010048401D5045A08110584003E07EB944D +:10414000FC80FC002E07EEAEC8312E07EEAC5A08FC +:1041500010053C0C01DDD50A5A0811053C0C01D7AD +:10416000D5055A0812073C0C01D9441320D0EA485F +:10417000EA4DDD53C904441FFFA0D503441FFFA12E +:10418000EAA1EB37A6485A180305441FFFB1D5032F +:10419000441FFFB0EBA1DD40A6015A0804058401CD +:1041A0003E07EBE684013E07EEAEDD53EAAF5A0868 +:1041B000BB1B2E07EEAFE614E8062E07EEAFE60AAD +:1041C000E912D50FDD465A0802FAEA6D84001000A4 +:1041D0008051100080523E07EEAF3E07EEAED50391 +:1041E000DD46C0F4FC80FC408120DD402E27EE9BA4 +:1041F000A601E64180E13EF7EE9BEA925A08034BA6 +:104200008408441000B1DD47EA39AE3044A38D4044 +:1042100084CADD54A608C8133C2DFB225A2801FC91 +:10422000EA305A0807F93C6FFB472E07EE9BC0F3B4 +:104230003E27EC03EAAB4900205FD5EC840844102C +:1042400000B2DD47DD42C80B2E07EE9BC813840188 +:10425000EA32DD4BA6004900204FD50CDD44DD439A +:10426000AE402E17EB8FEA305A0007F05A1801FDC6 +:10427000D5EC8408441000B3DD47DD5A5A08020625 +:10428000EB22C00349FFFECA8408441000B4DD4796 +:10429000D508EA39AE30DD54A608C803EA2DD5FDAD +:1042A0008408441000B5DD472E07EEAC3C2DFC0C15 +:1042B0008E10E60310910053E80449FFFF44D541F6 +:1042C000CF04440FFFA0D503440FFFA110010051FC +:1042D000DD4BA6005A080305440FFFB1D503440F78 +:1042E000FFB010010052DD40A6015A080405840108 +:1042F0003E07EBE6441000B68408DD47EA40EA28B2 +:10430000DD53EAAF5A00BB04AE88D5FB84084410E5 +:1043100000B7DD47DD42C0068402EAAC8041806020 +:10432000DD458400EA5B8408441000B8DD47EB8972 +:10433000DD538420EAA1EBA18408441000B9DD47D5 +:10434000FCC0EA6D10008060DD9EDD53000000605F +:10435000DD9EEA6D100080613C1DFA4A1000803E2F +:10436000DD9EFC0080C049FFFEC784015A6803053A +:10437000490055BC800650137FF3E622E9035A68D2 +:10438000021B8401EAE1DD40A7815A68030484022C +:10439000D5125A680A098429AE418420DD57DD40D0 +:1043A000AF81D5038420DD57DD465A0802F2DD5285 +:1043B0008443AE89FC804000040E9604DD9EFC021E +:1043C000DD42C021DD53441FFFAAEAA1DD530010E6 +:1043D00000515A18AA0AEAC3EA418407441000317E +:1043E000DD47EB3FD5F4B041500000518441F083EC +:1043F000122F8002A8093A108C004402E40849FFF9 +:10440000FBEBD50CDD53EAAFC809EAC3EA418407E8 +:1044100044100031DD47EB3FD5F68407EA70DD47F5 +:10442000DD53EAAF5A00DD048401D5028403FC8227 +:10443000FC01840A8061EA235A1001055A10020720 +:10444000D544DD538420EAA1D544EA6D00008052B2 +:104450008E06E604E83644F04260EA7FEA42DD0F69 +:10446000040E26528400EBAB10008052D53284013A +:10447000EBAB84008040DD52EA4BEA933C07948921 +:1044800049006183D50B8403EBAB8401EA90000003 +:10449000805344120000490060C1DD4BA600441265 +:1044A00000004422C3B7EB343C4DFC0C4900612BA7 +:1044B000D5104402010249005D278401EA23D50991 +:1044C0008401EA23AED0D5058401EA238402AE102C +:1044D000EB4E5A080A0A49FFFF74DD54EA238401AF +:1044E000AE08DD5BAE08EB4EFC815A0001075A08AE +:1044F0000309B401EA5FD503B401EAB2B601DD9E57 +:104500008402AE10DD9EFC00DD53EAAF5A08040CB5 +:10451000DD46C809DD42C00484013E07F028DD53B2 +:104520008420EAA1FC809200FC409F01E68F4EF2BD +:10453000008980C2800144F043443847910140F231 +:104540003C00DD0F24002E0038009600BC00C200A5 +:10455000FC00D400E00002011E00EE00FC00FC00A4 +:10456000F600FA014800007284003E07EEAD8406B2 +:10457000D56C84003E07EEAD8407D567EA6FEA7517 +:10458000F82580C05A000204EA53D5FB8401F823C1 +:10459000490017E23C0E045E490017E73C0E045F39 +:1045A000490017F43E001181490017FA3E001180BE +:1045B000490017F13E00118284214402E968490054 +:1045C00048FF8006F808EA92EABC490017EDC003EC +:1045D000AFF0D5FC490017FBD512842EAE418426DE +:1045E000AE40EA6D8440102080508421DD57842045 +:1045F000840280418461808180A1DD568401D525BB +:104600008401AE10D515840044100066DD47840196 +:10461000AE30DD46840ED5198401AE108401F80653 +:104620008402D5138401AE10840049005469840DBE +:10463000D50C840049004E24D5E249FFFF66D5DF42 +:104640008402AE18D5DCFA00FCC09200DD533C10A9 +:1046500003A8101000A09228101000A13C17F62704 +:10466000101000A29028101000A32E17EBFD1010C0 +:1046700000A4EBD5A688102000A5A68A102000A6CD +:10468000A08B102000A79248102000A80020801EB8 +:10469000102000A944238D41A690102000AA844038 +:1046A000102000AB3C23F77E102000AC9248102075 +:1046B00000AD3C33F6113C23F6218843102000AEB8 +:1046C0009048102000AF00208020102000B0002073 +:1046D0008021102000B100208022102000B20010A4 +:1046E0008023101000B33C1DFB2B101000B5EB37DE +:1046F000A648101000B6EBF1A08BA04C102000B71C +:10470000101000B8DD9E4413F04AEA28DD53EAAFEA +:104710005A00BB04AE88D5FBDD9EFC0080C0DD5393 +:10472000EAAF5A08BB2549004D46DD530010005042 +:10473000C1035A18FB122E17EE97C9042E17EE96D6 +:10474000C1128400EBB03E07EE96840049004D98FC +:104750008401EAE1D51ACE08EB365A08A00B4403CF +:104760000FA0D50DC60B441FFFA0D50EC6F6D50D64 +:104770005A08A10544036510D502EAC4EAB7EA481D +:10478000441FFFA0DD53EAA1FC809200FC00E60A72 +:104790004EF2007944F045A0EA7FEA424A003C002C +:1047A0000A4468E2E2E2E2E27CBCC903FA13D50FF4 +:1047B0005A18010BFA0E3C0BF48E3C0BF48C840C53 +:1047C0003C0BF48DD55F5A180207FA093C0BF48EA6 +:1047D000FA0ED5F45A180304FA04D5F9840F5A18BE +:1047E0000452D5F58401C1045A18010684023E071B +:1047F000EE90D54884005A1002FC5A1003045A184F +:1048000004423E17EE90D53EC1075A1001065A10D9 +:1048100002045A1803383C1BF488D534C903FA0E35 +:10482000D5055A1801084400003C3C0BF48AFA13E1 +:10483000D5135A180207EA583C0BF48AFA09D50C2A +:104840005A180304EADED5055A18041D44000082F4 +:104850003C0BF48AFA043C0BF489D514840AC11089 +:104860005A180104FA04D50C5A180204FA0ED50895 +:104870005A180304FA18D5045A180405EA8A3C0B9E +:10488000F48BFC809200FC00FA093C0BF48E3C0B8C +:10489000F48984023C0BF488FA2E84003E07EE90E3 +:1048A0003C1BF48C3C1BF48BEA89844C4410005074 +:1048B0003C1BF48A3C2BF48DB440441E7FFFFE5613 +:1048C000B620B4206610F0005810A000B620B44006 +:1048D000461FF1FF50108FFFFE564210D808B62039 +:1048E000B440461F8FFF50108FFFFE564210E40861 +:1048F000B620B42066108E0058108400B620FC80CC +:10490000FC4080C18420AE40B40280E24200740BBF +:1049100081245A080106B40642007408B606B4079A +:104920004200740BC805B40642007409B606B40709 +:10493000EACA5A080107B406EA91B6068006EBA057 +:10494000B407EACAC80AB406EA4FB606490019B65F +:104950003E07EF118006EBA0B40796045A08010544 +:10496000B406EA43B606B4079604C804B406EB518D +:10497000B606B407EA465A080105B406EA5FB60669 +:10498000B407EA46C804B406EAB2B606B407EAD4E5 +:104990005A080105B406EAB4B606B407EAD4C80456 +:1049A000B406EB2EB606B407EA575A080105B4065A +:1049B000EA94B606B407EA57C804B406EACCB606C9 +:1049C000B407920596175A080106B406EA44EA8528 +:1049D000B606B407920596175A080207B406EA44C9 +:1049E00058000040B606B407920596175A08030708 +:1049F000B406EA4458000060B606B407920596175C +:104A00005A080406B406EA44EAE6B606EA84EA5717 +:104A1000C807B40642006C09B606EB7DFCC0B406BC +:104A200042006C08B606EABA92075A080111EABABF +:104A30009637EA83B427840092299657F939B40748 +:104A400054100E00B40666000E00F840EA84960486 +:104A50005A080112EB5B6610800110148001B42724 +:104A6000922C9657F925B40754107000B4066600CE +:104A70007000F82CEA84EA465A080112EA84EAB285 +:104A8000EA62B427840892359657F912B427460093 +:104A90000E00FE46B446460FF1FFF81500048001F3 +:104AA000EAD45A080117EA84EB2EEA62B427840993 +:104AB00092389657F8FDB42746007000FE46B4467B +:104AC000460F8FFF50000FFFFE16FE0FB60683FF46 +:104AD000EA84EACA5A080113EA84EA4FEA62B42770 +:104AE0008402922F964FF8E4B42744018000B44624 +:104AF000FE46440E7FFF4E00FFE9FCC08E01E60D2E +:104B0000E84BFC0080C144F04910EA7FEA42DD0F27 +:104B10000E162A30363C4248804E5A647000B4016A +:104B2000EA91B601D508B401EA4FB601490018C6AA +:104B30003E07EF118006EBA0FC80B401EA43D51FCD +:104B4000B401EB51D51CB401EAB4D519B401EB2E74 +:104B5000D516B401EA94D513B401EACCD510B4014A +:104B6000EA44EA85B601EB7DFC80B401EA445800D2 +:104B70000040D505B401EA4458000060B606FC8048 +:104B8000B401EA44EAE6B601440000BDDD41FC8020 +:104B90008402AE10FC808402AE10DD9E9200920072 +:104BA000FC20E60C4EF200D080E280C144F049B80F +:104BB000EBAFEA424A003C001800440072008C014E +:104BC0008C018C018C016E01A400D4000601360119 +:104BD000B402EA294E0200BAB422979766108E00FA +:104BE00040609924B6C2B422840092299657F86096 +:104BF00044000070DD41B4079209D516B402EA29D9 +:104C00004E0200A4B42297976610F0004060998489 +:104C1000B6C2B4228401922C9657F84A440000711F +:104C2000DD41B407920C9617F818B402EA294E0237 +:104C3000008DB4C2440E7FFF964FFF86406305E4AB +:104C4000B6C2B4228402922F964FF832440000720A +:104C5000DD41B407920F960F48000074B402EA29B0 +:104C60004E020074B402466FF1FF50630FFF965777 +:104C7000FF86406306A4B6C2B422840892359657D4 +:104C8000F817EAC3DD41B4079215D5CEB402EA297C +:104C9000C05CB402466F8FFF50630FFF9657FF86CC +:104CA00040630704B6C2B42284099238965749FF7C +:104CB000FD6F44000079DD41B4079218D5B5978C9B +:104CC000B4224210EC0940609B64B6C2B402EA29E7 +:104CD000C805EB7D44100168D50344100E10EA7C32 +:104CE000AC404400007ADD41B407EA29D52ADD4210 +:104CF000C02CB42797B44210F00940609B84B6C71B +:104D0000B407EB6FC8062E17E9395A180108D50405 +:104D1000EB33C80484013E07E9394400007BDD41E0 +:104D2000B407EB6FD50E978CB42244000077421085 +:104D3000D00940609A84B6C2DD41B4074200500BEE +:104D4000DD41D5038402AE18FCA09200FC62A609E6 +:104D50008121F281814381845A08040584003E0741 +:104D6000EBE6DD42C007EAF05A08AA052E07ED542B +:104D7000D504DD53000000504E02020B5A08FB041C +:104D800048000207F001EAE9490019BD8400EB96EA +:104D9000DD42C00CEAF05A08AA0A2E67ED542EB77D +:104DA000ED5540731009979FD509DD530060005001 +:104DB00000B0005140731009979F8401EA508400AD +:104DC000EBFBEB5B5A1804182E17EEA1C1043E074B +:104DD000EEA1D54A2E07EB9F5A080103EB958420DC +:104DE0008009DD578401EA25DD44DD43AE40EA9EBB +:104DF000C0FFD53ADD44DD43AE40DD42C804DD42AC +:104E0000C820D527DD465A000204DD54D5162E07EA +:104E1000EE9AC00B3C1DFB712E07EE9A8E01E2014B +:104E2000E904EA5AE602E8F24400008ADD4184011E +:104E3000EADADD55480001C1A608C8E2EA2DD5FD31 +:104E4000EAF05A085507EAAC840280418466DD45E1 +:104E5000DD59A6005A0002093C0DFB37A6405A183E +:104E600002048420AE402E07EC0B8C013E07EC0BB5 +:104E700040031C848EE1E6EC3E07EC0A4EF2015E34 +:104E800044F04C9038779D0140F3BC004A003C0050 +:104E900018005200C201DA0140024E026A02A80262 +:104EA000A802A8027A0296024402C378EB5D490088 +:104EB0001962F001EAE9490019268006802B804931 +:104EC000EB928400EA505A600F0448000101DD5360 +:104ED00084CC000000505A00FB0448000142480006 +:104EE00000F78EC18401E6C6EB964EF200AD44F0A9 +:104EF0004CFC3867990140F33C00DD0F0C00340096 +:104F00005E0026012C0164008400EA508401EAFA64 +:104F1000FA318404DD47EB22C8078404FA3ADD47FE +:104F200084C4F814D5598404FA3BDD47FAC4D55437 +:104F30008400EA508401EAFAFA318404DD47EB2266 +:104F4000C8088404FA3ADD4784C549FFF8C3D5444C +:104F50008404FA3BDD47FAC5D53FEAFA84C2F88FEC +:104F6000DD42EA6DC03F8401EAFA0000805284C04D +:104F7000106F800F5A08AA294900491D8401490071 +:104F8000497FDD530010005300200054440FFFA060 +:104F9000FE0F5A2801103E07EE964400988C3E679B +:104FA000EE97F80DDD53441FFFBB3E67EE93EAA179 +:104FB000D508EBB0440062383E67EE964900497070 +:104FC000DD538420EBA1EB36C806EAAA84C1C004F5 +:104FD000FAD0D502FAC9EA8C4E0300C3841FEA2A2C +:104FE000F84E2E27EE96C202EA50000080525A0870 +:104FF000AA160020805484005A28010B00308053E8 +:10500000442FFFA0FE9FEA503E27EE96D5033E07B1 +:10501000EE96EBB0840010008052EAAA4E0300A086 +:10502000D556EAA8EA61D5538400EA6DEA508401B6 +:10503000EAFA0000805500108054EBED3C0BF615A9 +:10504000FAC2F81D8404FA3FDD478400EB9648005D +:1050500000728402EB0A80268401502F800F49FFE2 +:10506000F9E980C08405EB0AF80A84002E17EB8F5B +:10507000EA508401EB965A18010584C94800007172 +:105080003E07EB8FEB0A5A68010D84004410004183 +:10509000DD47DD5A3C0FFB4D3E67EBE2EB43D503AA +:1050A0008402EA50000F800F5A0802E9DD5384C0E1 +:1050B000106000513E67EBF53E67EB8FDD465A000E +:1050C00002053E67EC13D5038405EB0A84C1D5487D +:1050D0008006802A502F800F49FFFA09D51D8400D1 +:1050E00044100060DD47800680294422C3E5503F1C +:1050F000800F49FFFA1B9780D5338006802B804AAA +:10510000503F800F49FFFD4ED5078006802A502F63 +:10511000800F49FFFCF5000F800F5A0002D9B40A36 +:10512000B60C84CBD51D5A68010649FFF6ECFAC3CC +:10513000D5178402EA50D5CB840284C1EA503E6779 +:10514000EBD7DD42C0073E67EBD7840F441000FB6E +:10515000D504840F441000EBDD47D5B9FAD0000F19 +:10516000800F84205A0001055A080206843BDD5353 +:10517000101000502E07EBF5C8094402C378EB5D10 +:10518000490017F9F001EAE9F8108006D515EB3669 +:10519000C803EAAAC0088400EBB03E07EE9684007C +:1051A0004900486EF001EAE9490017D3EA39EB45B6 +:1051B0008400EAFA8401FCE2FC2080E280C35A0009 +:1051C0000704480000D2E62C4EF2011C44F04FDCEC +:1051D0003817850140F0BC004A003C00180044002C +:1051E000720024022402240224026E019E00CC00DC +:1051F000FA003401A621EA574E020107A660440FC7 +:10520000FF80FE0FAE20B44397D766210E00407199 +:105210001D24440000B0B6E3DD41B4069209D51464 +:10522000A621EA574E0200F1A62197D7EA43AE2104 +:10523000B443440000B16621700040711D84B6E3A0 +:10524000DD41B406920C9617DD41480000DEA62130 +:10525000EA574E0200DAA62197CFEA91AE21B44375 +:10526000440E7FFFFE8640711DE4440000B2B6E3A9 +:10527000DD41B406920F960FD5E8A621EA574E02FB +:1052800000C4A621461FF1FFEA5FAE21B40350100F +:105290008FFFFE0E97D740001EA4B603440000B84F +:1052A000DD41B4069215D5D0A621EA574E0200ADD5 +:1052B000A621461F8FFFEAB4AE21B40350108FFF22 +:1052C000FE0E97D740001F04B603440000B9DD412D +:1052D000B4069218D5B9A62197D4EACC40001C8414 +:1052E000AE21B44342216C0940711F64B6E3B4039C +:1052F000EA29C805EB7D44100168D50344100E105F +:10530000EA7CAC40440000BADD41B406EA29D59DF0 +:10531000DD424E02007AB44697FC4221700940718A +:105320001F84B6E6B406EB6FC8062E17E9395A1883 +:105330000108D504EB33C80484013E07E939440071 +:10534000007BDD41B406EB6FF84D97D4B4434400C5 +:1053500000B74221500940711E84B6E3DD41B40616 +:105360004200500BF83F5A080B408E21E62DE849C9 +:1053700044F0517CEB3840F0BC00DD0F0E141A20D5 +:10538000262C3238843E46505A00B403EA91D53771 +:10539000B403EA4FD534B403EA43D531B403EB5137 +:1053A000D52EB403EAB4D52BB403EB2ED528B40321 +:1053B000EA94D525B403EACCD522B403EA44EA85BD +:1053C000D51EB403EA4458000040D519B403EA449A +:1053D00058000060D514B403EA44EAE6B60344007A +:1053E00000BD48FFFF335A0805105A1001075A182C +:1053F0000309B403EA5FD503B403EAB2B606D504E1 +:10540000843BEA7EAE40FCA09200FC62F081F28216 +:10541000F383EA7EA7C0A7804402FE51A60092E46F +:10542000979FEAE75A700104480000709E31E60336 +:10543000E90E5A600503F80EDD53000000605A00C3 +:10544000A1072E07EF2F5A080103F804EAF05A08C3 +:10545000AA04480000774E420075DD42C00ADD40D4 +:10546000A601EB295A08040644000088DD41FCE24D +:105470004402C378EB5D4900167E4402C39CEAE90E +:10548000490016415A60050584004900452BEA8011 +:10549000EA36EA31A6085A080104AED0D5FCDD424E +:1054A000C024F81A44000082DD412E1FEEA02E0F0A +:1054B000EE9F4423F41C4E170006A6D05A3802FD76 +:1054C000D5034E06FFFCEAAC804184668402DD45CC +:1054D00044000083DD41DD44DD43AE4083FFEA212B +:1054E000A6085A08E1FFD50C44000084DD41EA21FA +:1054F000440FFFE1AE08804184028461DD458006EF +:105500008029F201EB92FCE281615A700B06540390 +:10551000800D5A080517DD42C014EAF05A00AA129D +:1055200044A2FE508400EAD3802680078049F3021B +:10553000F40349FFFE43EAAB5A00FB048401EADDB1 +:10554000FCE23C0FFC0EDD9EFC67F08D81A18182A8 +:10555000C407C30CFA10846684A180C0D510C30BA5 +:10556000EB03840180A384C4D50AFA70840180A36C +:1055700084C6D505EA8A846484A180C040E3001310 +:105580009781F8284082801397D9F08A4492ED8C55 +:105590002E07DD8A44B2ED2844A2EDF0F08B4422C0 +:1055A00055B88400F30DF820842BF8348400806C07 +:1055B0008040381481114E17000822518000EB986A +:1055C000976BAD58D502AC988C019641E22E8C6257 +:1055D000E9F13C07F631F0893C07F63083FFF08AA9 +:1055E0002E07DD8AF08B14CF8000149F800114BF3A +:1055F000800214AF800314DF800414EF8005148F41 +:105600008006F787F68883FF8400842D442255B8EE +:10561000F30D808C44527200F91EFCE7FC01F0810E +:10562000440004733C0BF631440FFB8C3C0BF6300A +:105630002E07DD893E07EC0D8C0180C13E07EC0E84 +:10564000C921F8058481F80B8066F83244029ECAAD +:105650008441802080624900165C846144029ECAB5 +:105660004412A50AF20183FF8083F8224412A1EAC2 +:105670004402A82AEA27DD4844529ECA4412A04A9E +:10568000D5205A180149F80584608083F809F8107C +:105690004402A05A8020804680664900163AF201F2 +:1056A0004402A05A4412A69A83FF8066848049FF70 +:1056B000FF4D4412A37ADD5D4402A9BADD48FC81A6 +:1056C000A428505280409603120283000202817087 +:1056D0009603120284900202FFFD96031202831DBC +:1056E0000202818D9603120284AD0202FFE196034D +:1056F0001202830102028171960312028491020256 +:10570000FFFE96031202831E0202818E960312028E +:1057100084AED9D7FC81381105118820E023E90A2D +:10572000EBB25A08010B3C03F8CCC0085EF080785D +:10573000E80444008000DD9E8400DD9E3C1DFC0EDC +:105740002E07EBCEA68EC80CEA355A08010A941132 +:10575000AE0AA6098E01F8079401F80BD511A60927 +:10576000AE8A8E01FE148442400008168E0183FF2B +:1057700096033C0BF631FE033C0BF63083FFA60983 +:105780003E07EC0D8C013E07EC0EDD9EFC672E679C +:105790002813F08D81C181022E072812CB058020AD +:1057A00080408401D5048026844180C097C1F832AE +:1057B00040B080134091001344D2ED2844C2EDF074 +:1057C0003C0DFC0E97B144A2ED8CB71FEBDA14DF51 +:1057D000800214CF8003F82CF838842BF83C8460C6 +:1057E0008008820D808C80439659E22BE81338158F +:1057F0000D114E17000C22500000EB98976BAD4036 +:10580000A440964B5EF0FFECE802AC808C618C0209 +:10581000D5EC3C07F631F0893C07F630F08A83FF7F +:105820003C0DFC0EF483B71FEBDA150F800214EF6A +:10583000800414BF8005F786F687149F8008A602AF +:10584000F08B840083FF842D442255B8F30D8088AB +:1058500080A083FF49003D76FCE7FC0180C0F18118 +:1058600049FFFF6EA036A075F201846049FFFF90EA +:10587000FC813C0FFB85DD9E3C0FFB83DD9E3C0FD6 +:10588000FB84DD9EFC41846380C080E2501F800663 +:10589000FA50B400EB58EA54B607F80FA4704492DB +:1058A0000000F81010138010B406501F8006FA5044 +:1058B0008464EB58EA54A83949003EECA4703C3D9E +:1058C000FB838A010014800292014000043783FFA9 +:1058D00010138011B406A072A0B60031800C848130 +:1058E0004900156BFCC1FC6580E1842080C4121F57 +:1058F000800D5A48040504900006D5030490000565 +:1059000002310439A613854050BF801CA752808302 +:10591000B61F802980098445EBDA14AF800214AFEA +:10592000800314BF800449003CE4020F800EAC38B1 +:1059300002058001AC39501F801A8009804A8463B7 +:10594000EB58020F800D5A6804053C0BF62CD50568 +:105950005A6805043C0BF627AC3B501F801A80099F +:1059600084408464EB58020F800D5A6804053C0B98 +:10597000F616D5055A6805043C0BF612AC3A5A6087 +:10598000040E84003E07EBC9221380033C039840B9 +:10599000E020E80484013E07EBC9FCE5FC0180C17E +:1059A000F3818460B61F3E37EBC949FFFF6DB41F1A +:1059B0008026F2018460848449FFFF972E07EB94D0 +:1059C0005A08010722130003440395B4AC40FC813C +:1059D000B460B42080A0927096098440986AB48123 +:1059E0009290E264E804B421806496098C445A28B9 +:1059F00020F7DD9EFC2080E180C049FFFFEBE6E858 +:105A0000E85544F0581038779C0040F3BC00DD0F97 +:105A1000081A2C3E54647486961F96433C1BF82546 +:105A2000964F3E17EC028400D5423C13F8259404AF +:105A30009600FE0F3C0BF8258400D5393C13F82561 +:105A4000961F400081043C0BF8258400D5303C13A0 +:105A5000F825400081849643EB283C1BF825AC4098 +:105A60008401D525961F9643EB8D964F3E17EC0289 +:105A70008400D51D940496403C03F824FE47EB8D2A +:105A80008400D5155410000F3C03F8244010050481 +:105A9000EB8D8400D50C3C13F82440108184964B88 +:105AA000EAE0EB8DAC408402D5028400842FB62658 +:105AB000FCA09200C9104020380954003FFFC006E6 +:105AC00096C4882396489201D5FB964FFE555C00FC +:105AD0008001DD9E8401DD9E5450000C848090A2E4 +:105AE000E28510F0800054100030540000C0902473 +:105AF0009006E2814002000610F10000AE18DD9E23 +:105B0000FC0180C1B42380A0C951847F3E37F0449A +:105B10003E17F043C41AC215402020095401000C5E +:105B20009002E22054010003EB482E27F04240008F +:105B30003C244C2000523E17F0413E07F042D56312 +:105B400012230025480000A1541000032E07F04244 +:105B50004C00C013EBC7E602E8038C01EB27EBC750 +:105B6000E602E90310130040EA74EB11E80984002F +:105B7000EB27EBD9D5053E47F0413E17F042545292 +:105B8000BFFF44000FFF92A2D00A02130026840335 +:105B90004250807390A212530025D5031253002562 +:105BA0000203002512030026F8465A100403F843A6 +:105BB0004E420081920896015410000C9022C23D82 +:105BC0008440960F40110406E240400784242E17BB +:105BD000F0424C1040152E17F041E624E8048C21C9 +:105BE0003E17F0412E17F041E624E902EBD9EA74A2 +:105BF000EB11E8098400EB27EBD9D5053E27F041EE +:105C00003E07F04202030025120300268400EBBF8A +:105C1000501F80058005EBE9EB34F83A000F800651 +:105C2000001F8007940140000440001F8005880188 +:105C30003E07F04048000083960F40110406E24002 +:105C4000400784242E17F0444C1040182E17F043C0 +:105C5000E622E8048C213E17F0432E17F043E6229B +:105C6000E802841FEAD2EA74EB11E80B84003E07D5 +:105C7000F043841FEAD2D5053E27F0433E07F044A7 +:105C80008400EBBF8005501F8005EBE9EB3449FF32 +:105C9000FF25EB4E001F8006940540000480001F86 +:105CA0008005400004602E17F040FE0F10030059DD +:105CB000D545541000032E07F0424C00C013EBC72B +:105CC000E602E8038C01EB27EBC7E602E9031013B9 +:105CD0000040EA74EB11E8098400EB27EBD9D50505 +:105CE0003E47F0413E17F042540280FC92021003FE +:105CF0000059CA2492A82E07F044974F4C02C01BAB +:105D00002E07F043E602E8048C013E07F0432E071D +:105D1000F043E602E90410530041D503841FEAD2A0 +:105D2000EA74EB11E80B84003E07F043841FEAD2CB +:105D3000D5053E27F0433E57F044FC81FC6080C10E +:105D40002E10115581625A10010544A00708D50391 +:105D500044A003E85A0001055A00023EF80C44131F +:105D600097DCA4483C2C0436964BC2035A280506FF +:105D70008400EB2A4800009AB44B662100044E23AD +:105D8000009540C08013542600039FD35C738001AC +:105D90003E77F0463E70111ACF0C2E37F047CB0BF2 +:105DA0002E57F045DA063C2DFB3C5CF103E8E80297 +:105DB0008400EB2A54908003800C80273E97F045A6 +:105DC000F838CF5C2E17F047C13E3C1DFB3CE34149 +:105DD000E955D539EAE0A440EA97964BC0CA5A0083 +:105DE00005C9EB7FE60AE961B40BEAB2C85E40C0C0 +:105DF0008013540600039FC35C7380013E77F04616 +:105E00003E70111ACF0E2E27F047CA0D2E57F045BF +:105E1000D808EB3A5CF003E9E9048401EB2AD503E6 +:105E20008400EB2A54908003800C80273E97F04535 +:105E300049FFFE42CF2E2E17F047C1053C1DFB3C0B +:105E4000E341E92784013E07F0468400EBBFEA976F +:105E50005A00042C00030045100300462E07F046AC +:105E600010030045C82202030025C8058401EBBFCA +:105E7000120300268401EB2AD518C0EA840012031D +:105E8000001F8026800C8441806B8087F80BD5E052 +:105E9000C0DF84001203001F8026800C8440806BCA +:105EA000808749FFFE2FD5D4FCE0DD9EDD9E442295 +:105EB000AB4AB6404432AC764422ABAEA881A8C906 +:105EC0004422AC128460B641ACC4ACC5ACCCACCD01 +:105ED0008420B4A080619929ACE0990A8C22ACE0BE +:105EE0005A1840FBA101840080204432AC7698A06F +:105EF000AC5098838C02AC505A0864FBDD9EFC21A8 +:105F0000A4C0842096DB121F80033C57EEA9848036 +:105F100084CF447001EA96615CF08064E80A402016 +:105F2000840903000000A44052210031964BD50A99 +:105F30000300000050227F9CA4409041964B5221C8 +:105F40000031FEB49691FE54EAB98830964BAC40CD +:105F5000A440964BE061E803A4C096DB8C818C02E0 +:105F60005A48C8DB123F8003EA5496034002800778 +:105F7000FCA1C80E3E07EBCAA40EC80684013E076A +:105F8000EBCA8400DD9E5A001FFB8401DD9E840065 +:105F90003E07EB8EA40FC80684013E07EB8E8400FB +:105FA000DD9E5A0831F4D5F9FC442E401150802072 +:105FB00080022E27DD7AE282E8043C57EEB6D50354 +:105FC0003C57EEB8E282125F8000E8052E47DD7490 +:105FD0009723D5042E47DD7597238440124F800107 +:105FE000122F8002C8065090800CB4E1FB90D506B9 +:105FF0005090800EA1C945000032225480004E937B +:1060000000079CA940238820A490F80C4647FFFF76 +:1060100050420FFF50287FFF8885DA0840439020C8 +:10602000A4A09693122F8002D517952141139000BA +:106030008C84888702688000A4A097B39693E0467A +:10604000E807024880009723124F8002D505A5205B +:106050009723124F8002952998BCA590022F8002A9 +:106060008AC297B3126F80035A3001044800006659 +:10607000EA54EAB69603964BE02050287FFFE81CCE +:10608000E0A2E8078C828887A420F805F808AC20F5 +:10609000F8318EE29643EAEF960383FFFE0CEB069F +:1060A000EA8F40307C0AF082F383F002F10396031A +:1060B00083FFAC38D53EEAEFE0A296C3EA5496439C +:1060C000EB0F97835001FF9CFE0C40001816500008 +:1060D000006441107C0AF084151F8005E80B8C8257 +:1060E00099BCA430F810F086F187F006F10796030A +:1060F000AC30220480004E07001D40738020020354 +:10610000FFFF83FFF404F50596034222802440102C +:106110007C0AEBF04200106984608822442000640D +:10612000EA4AF086F187F0068EE29603F107AC3872 +:1061300084013E07EBCAFCC449FFFF1DC01B2E10A3 +:1061400011503C07EEC25CF080248420E902EA7022 +:10615000022F80038801969322148000443000644B +:10616000FE9C407384209603A478EBA29A089603C1 +:10617000AC38FCC4FC208480C83AA4D61030800916 +:10618000847FA90CA90D8381BC8ABC8BAECCAE0DDB +:1061900080C0451188C8B482F83B4E37001CF83FD8 +:1061A00005008004A0CDF845A8CDA6CC8CC1A90CD3 +:1061B00097B35A38FF03AE0CA6CDE003E902AE0D4B +:1061C000B4628381BC0B88E3A4F8BF0AF849BB8A98 +:1061D000BC8B8C015A0820E184004E670007A4168E +:1061E000B44240010020A400AC08FCA0A417100099 +:1061F0008008841FAE0E8400AE0F8400A90EA90F84 +:106200008381BC8CBC8D80C045118800A11195C1D3 +:106210008887A4E096DB83FF4E37002DA520383811 +:10622000810197234241906883FF05008006A0CF3B +:106230008890E2908865886F83FFA8CFA6CE8CC136 +:10624000A90E97B35A38FF03AE0EA6CFE003E902BA +:10625000AE0FA0D18381BC0D88E3A4F8BF0C96DB00 +:106260004051FC0A8867E2678885888F83FFBB8C72 +:10627000BC8D8C015A0832CC84004E670007A417ED +:10628000A09140010020A4005CF00191AC09E90557 +:1062900084013E00114FFCA084003E00114FFCA081 +:1062A000FC6080C12E16B15E4E120099814680E4DA +:1062B000953140901000020480002EB728122E67FE +:1062C00028349603C34CF87DF84B4E0200884E7379 +:1062D000008640152CD7808797B1964980074421C6 +:1062E0008948E201E808383100008C018883972151 +:1062F0009601D5F88400806044218948E223E908AA +:1063000038510C008C618805960196D9D5F82E106D +:10631000023E8E01E2814040BC1B2E10023F9601DE +:106320008460420080013C7C019B80A3E204E90D73 +:1063300040239020A450964BE061E804A4D080A4B0 +:1063400096DB8C819721D5F302248000405314A062 +:1063500044117EB0961338209400D533F83296035A +:10636000EB0EEBC683FFC03ACF39406518572E10AD +:10637000023C94939691E2419C174020BC1B2E1046 +:10638000023D96014200800197B13D0C019A808741 +:106390008027E202E90D40580820A4E896DBE0835C +:1063A000E804A528802297238C419691D5F30224F6 +:1063B0008000406098A044117870961338209800AF +:1063C0004220086850010032E2028023882F846056 +:1063D00044200064EA4A9603EB0EFCE0FC658180F1 +:1063E000220F8030F0832E072812F0822E072834E7 +:1063F000F0842E072813F1818162F38681C4049F03 +:106400008016227F802E006F8064F08540A10408F2 +:106410004E420086F0024011001654D000FF55C0D5 +:1064200000FFF00250807FFDC60F440186805CF6BD +:106430008002382009018481E90340447007800C00 +:10644000802B806EF8DEF8824020F020A450F8E522 +:10645000F8EEAC50B429421070735CF68002B62995 +:1064600040A470078401E902800A96005CF680026D +:10647000F0848401E902800A9600F0858541448118 +:106480008680F006E20AE94A405E28014E55001473 +:106490004165A801C607F817F404F81DF508056F53 +:1064A0008007F820F8B9E020E806F8244026A80183 +:1064B000F8BEF829F002405E2800E0A0E82B416514 +:1064C000A800C610401B001338245901800C806EB0 +:1064D00083FFF405F588156F8007F893F508056FBD +:1064E000800741665820020B000083FFF895E020EA +:1064F000E811F10141509420021A800083FF4025E9 +:106500003400F895121A8000B42942100873B62995 +:1065100083FF50050001EBDFD5B5FCE5F004EBA2ED +:106520009640548000FFF005F18251C07FFDC60EF9 +:10653000440184F0E62238200901E804404E200797 +:10654000D501800C802B8460F85C894C020500002A +:10655000F10183FF4020A020A450F85FF868AC5000 +:10656000B42942102073F002B629E60240AE20079B +:106570008400E802800A9600F087F00285A144E1D9 +:1065800084F05DC00002F006E20DE9604054340181 +:106590004E550022F00443568024C6104025D401F5 +:1065A0009651800C382709018460F407F589155F3E +:1065B0008008F827F509055F80084005D401F82810 +:1065C000E020E809F82F121B0000F1024020B4017E +:1065D0004E00FF9CF00540543400E0A0E832F00487 +:1065E00043068024C6134005C000808A96413827A0 +:1065F00001018460800C404E701AF589150F8008E7 +:1066000049FFFE50F509050F80084005C0004156BE +:106610000020020A8000F10396038A0783FFE0202E +:10662000E810F10141609420021B00008820964B85 +:1066300083FF121B0000F102402684004E00FF661B +:106640005006800154D000FFD59FFCE5FC688120F6 +:10665000EA3B8101F387838585405A0001042EA718 +:10666000DD5C3C13EEACF1868420F18EF18FC41218 +:106670005A0801053C17EEB1D5033C17EEB0121FC6 +:10668000801A5A0801053C07EEB2D5143C07EEAF5C +:10669000D5112E07EBCA5A0001092E07EB8E5A00BE +:1066A00001053C07EEB4D5028004120F801A3C07A6 +:1066B000EEB3120F801B4E83001F84001281000472 +:1066C000A814A8152E7728122E0728355111000876 +:1066D0005131000C04C10000F0852ED7DD765061E9 +:1066E000001081C7FAB0455000C050BF8038443117 +:1066F0008680D51C8400AC158400A816A8172E77B8 +:1067000028345111000A5131000E04C100012ED766 +:10671000DD7750610018F78544500032455000C8BD +:1067200085C150BF803C443184F084001208800051 +:10673000840080203A030420842082C982018041A1 +:1067400002F88000020B000040F4BC2002F7800039 +:10675000960341278011E1C0E803122880000A0B4C +:1067600000018C41960340F07C0A880141700406C8 +:10677000898F9691802089974C2AFFE4B606840081 +:1067800015030001802C80408C0196011A208001A5 +:106790004C02FFFC2E06B15E026880005A08011C04 +:1067A00040049820A40038119901960342008068A3 +:1067B000442000648460F48BF58A153F8009151F1E +:1067C0008008EA4A9603051F8008053F8009F50AFC +:1067D000F40BD50540049820A4009603F106E001CF +:1067E000E805F1078400AC08FCE84E83000C406328 +:1067F0001C16120980000208800040701CF697F8F1 +:10680000D509EBE4126980000208800040001CF604 +:1068100097F8C41602098000C0099E694C008007E1 +:106820005A0001058EA24C02C0072E07DD55100F3D +:106830008033D50A2E07DD54100F8033D5052E077F +:10684000DD56100F8033EA3B5A080108000F8033F1 +:106850008C019600100F8033F83B52640001964B78 +:10686000960397B0022880008086F84F80AD151FF0 +:106870008006F856051F800602388000CF044027A6 +:106880000C00D507F0058E014C70400D4021B80179 +:10689000969140048820A4009603E140F82DF83E2C +:1068A000FCE84051B8014021B800404494204034F5 +:1068B0008820A420A4589603964BE020400500139E +:1068C000E816A460A4988A229649E201E82B003FCA +:1068D0008033021F801A020F801B83FF964B9603A2 +:1068E000F181F08296A9F813F819FCE8A458A4E005 +:1068F0008A239649E201E816003F8033021F801A7E +:10690000020F801B964B9603F181F082B77F15CF63 +:1069100080038009802C83FF9691808680AD49FF9B +:10692000FD5FFCE8FC4081408400EAD38400AC08B1 +:106930008121AC108024A01D80E280C4442000325C +:10694000806A8481EAFB84A0EAABE2A0E817A03168 +:10695000946938001501D810A03202248000380054 +:106960001501E240E802EB0EA03338000401A478E0 +:10697000E220E802AC388CA1D5E884003E07EEEEB8 +:10698000EAAB5A08011102148000E628E80CA4784A +:106990005CF080B4E808EBC9B4215EF08209E90339 +:1069A0003E07EEEEFCC03C23F77996415000806430 +:1069B000EB789601E8242E27EEEB5A2801065010BA +:1069C000805A9609DD9E5A2002062E37EEF45A3878 +:1069D0000206501080509609DD9E5A2003045A3852 +:1069E0000306501080469609DD9E8E44E649E90470 +:1069F0008E64E669E804501080329609DD9EFC0042 +:106A00002E17EE915A1801122E17F03C8C21964841 +:106A1000E62BE8043E17F03CD50E842A3E17F03CE6 +:106A200084203E17EE91D507EB65C9053E17F03C73 +:106A30003E17EE913C13946DAC40AC442E1728AC3D +:106A40005A180114EB37A6485A180310EB65E625CF +:106A5000E8082E172932AC402E172932AC44D50550 +:106A600044100078AC40AC442E1728C35A18014299 +:106A70003C1DFB2BC93E2E2728AC5A28013B80C069 +:106A8000DD4BA6005A080306840AF804AC30D53161 +:106A9000800149FFFF8AAC302E07EE925A080104AC +:106AA000EA58AC30EAF4B401920596175A00010591 +:106AB000B401EA29C81E2E07EEF45A08011B3C0C4B +:106AC00000C3A4005CF00051E9142E07F03CE60A74 +:106AD000E8103C0C00C4A641C1035A181F0BA600C5 +:106AE0008E0BE61DE80684013E07EE91EA58AC30B5 +:106AF000FC80E602E8093C03F4A6E020E807E6860D +:106B0000E80B8401DD9E5A080206E686E805840249 +:106B1000DD9EE607E8028407DD9EFC203C43F48806 +:106B200080A0C4105A4001095A4002095A48030A79 +:106B3000444000FAD507EB19D505444000AAD50218 +:106B4000848097915CF30024E807E6B08401E905AE +:106B500084025A581003840097D95CF38024E80813 +:106B6000E639E803EA5FD5045A101903EAB45CF386 +:106B70000064E81E3C6DFA525A680109E63AE918C9 +:106B8000F809E9145A501017D50D5A680412E6395D +:106B9000E80F5EF180C8E80E4E35002AE6B083FFAC +:106BA000E803EA85D5075A501006EA94D5034E3516 +:106BB000001FE064E81C3C3DFA525A380209E6B175 +:106BC000E916F809E9135A101913D50C5A380310AD +:106BD000E6B0E80DE044E80B4E25000AE63983FFF5 +:106BE000E803EA94FCA05A101903EA85FCA0FC62B1 +:106BF000230F802022BF8022810481A0FA13004F3E +:106C000080503C0BF8393C0BF8388121800380C25E +:106C100080288050806BF583F482150F800122CF8D +:106C20008024F91000AF804C44E2C890050F800129 +:106C3000F402F5034E9300043807360A3C7DFA52FD +:106C4000380736025A7001045A7804145400003090 +:106C5000C02A3C03F4A6E005E805E6C3E824E6867E +:106C6000E9035A680221EBD884C8C81D84C2D51B29 +:106C700054100030C11C3C13F4A6E025E805E6C31F +:106C8000E816E686E9035A6802133C3DFC245411D9 +:106C90008002C10454100010C97796D6C377962E8F +:106CA000C075D5725A7001085A700406EA89B4009A +:106CB000EA29C82D38073602960FC0275EF8002350 +:106CC000E9035A9801234EA20007EADEFE24409011 +:106CD0002936D502812A800680258050806CF58176 +:106CE000F82B80C0F5015A0802115A780405E7050F +:106CF000E854D5065A78010E5CF4002DE94E5CF498 +:106D0000815FE94684C7D5445A7001485A700446E9 +:106D1000389736025404800CC0405EF580232E87DD +:106D2000F074E9054E82003AE746E937800680258F +:106D3000804B806C808A49FFFEDE80C04E82002E30 +:106D4000E746E92BEBD854100002C10E5A78020531 +:106D500054148008D5055A78030854148004C104DB +:106D6000E6C7E80284C79616C0185A78020554048C +:106D70008004D5055A78031254048008C00EE6C773 +:106D8000E80C84C7D50A84C8D59284C2D590EBD8C4 +:106D9000C0045CF480FBE8F68006FCE2FC6184C081 +:106DA0003C6FFC243E67F08C2E7728193C9C00C475 +:106DB0003CAC00C33CEDFA523CBC00C250C0000ADF +:106DC0004442C6A49630E207E86350067FF6B4005A +:106DD000C05B5A00055A38021A025A000156500682 +:106DE000001204D0000022267FFF4014B420A60920 +:106DF00000808000E60638153501E905E61AE90548 +:106E0000522106409691D502EB23E7062236000078 +:106E1000E9065CF4002CE90552318A2896D9D5039D +:106E20004430FFFF9F43E6BAE82F50547FFD5CF2E9 +:106E3000802CE82A5CF08033E91F8028969396DB4B +:106E4000F48149FFFE6CF401C8173C2DFC24580165 +:106E500000013C0FFC245AE80205E71AE909D505B0 +:106E60005AE8030BE719E80458210003D503582119 +:106E700000053C2FFC243805B5012E17F08CE220CC +:106E8000E8033E07F08C8CC150C6004CD59C2E0701 +:106E9000F08CE615840AE8052E07F074C0048E0114 +:106EA0003E07F074FCE1EA898427B400400080BE0C +:106EB0003C0FFA52DD9E3C0DFA525A0001065A0070 +:106EC00004048400D502840F441000FF3C5C01DC04 +:106ED000FD10404288C0A5209723E48BE9095A3869 +:106EE000FF0580228062D504E22240113C1B8C41C8 +:106EF00096905A2832F08A23442000FF96488062F8 +:106F0000404280C05042003EA5209723E48BE9090F +:106F10005A30FF06E24040203C1BD5038040806091 +:106F20008C0196005A0832EE8A43E6243E27F12C63 +:106F30003E17F12DE8049610E604E9082E07EEB09E +:106F40005CF0003CE8068C01D50284003E07EEB000 +:106F5000DD9EFC204422C890385106025412800F56 +:106F60009E8DE642E90A8E29E622E90754528030D6 +:106F7000842040509406D50284A13C1C00C5EA4EF2 +:106F80008460A642A7C33D0C01DC8083E2E1E923D3 +:106F9000A6800110000141209408E3A2E91940698C +:106FA000080040681820A5B097B3C505C2075A2845 +:106FB0001F0BD504C2065A201F05C1035A183104FD +:106FC000424310008C4142330C009690D5E78C214F +:106FD0009648D5DDEADEFE248C6140000C1696034F +:106FE000FCA05CF180334422C83CE90E4430004CE4 +:106FF0004412E9E042100C73A0CF3C1C00C23810D0 +:107000008D01E62BE80438110000C1134412C8B802 +:1070100038108202E623E8073C1DFA525A10010A92 +:107020005A100408842A3811000844100050D50270 +:10703000FA2438210000C2068E414432C83C38216F +:1070400080088001DD9EFA24FECC3C1DFC24C10397 +:1070500094D996D94412C86838208101E243E803E4 +:107060003830810938008101DD9EFC662270800085 +:1070700022B080013C1003A8F2875010803C3C1BDA +:10708000F4A6EAB84201847380C381A0B400C04F63 +:107090005A000550040680073C1C00C4EBAC00C03D +:1070A0008001008080003C1C00C35CF60006385064 +:1070B00081113C1C00C8383082023C1C00C54010C5 +:1070C0008040A68951110001A6884028880154916A +:1070D00000FFA68BA64A8C419A519648F186E80398 +:1070E0009739D50A5CF6001AE90552438640972184 +:1070F000D5034440FFFFE706E80440258013D50987 +:107100005CF4002CE90552258A289691D502EB23E0 +:1071100096008026F28BF48AF589F38849FFFF1BDD +:10712000EBDFF308F509F40AF20BD50E8140D50226 +:107130008540EB23448000FF808214AF8006812AC3 +:10714000818880AA806A4522C6A438191A02C943D8 +:107150004402C8E0EAD5ADC012B000014402C9083B +:10716000EBEAB5CD4402C89044A2C8B838101A0A58 +:107170004402C86838151A0AEBEA5B280124EBD8E8 +:1071800081D240E0801B4522C85438E918084402E7 +:10719000C8488648392018084402C83C38101808E6 +:1071A0009723F006969396DBB69FF281F382F084E4 +:1071B000149F800380068041806C8088F826380503 +:1071C0001A0A38051A024E02018684014412C6A426 +:1071D000EB35D5615A1001044800013A5AC0FF1A34 +:1071E000B40D5A080217F0069723969396DBB69FC4 +:1071F000F382F08444E2C8B8F281149F80038006D1 +:1072000038271A02806C808849FFFCF338071A0A75 +:107210004402C908381019115EF08032E80F8C2141 +:10722000EBEA4412C854382098005A2801083C2D33 +:10723000FC24C204845E38209808B42D4E12011636 +:107240005A180504480001125A18042A4412C8B8F2 +:1072500038109A025A1002045A18081E38F01911F0 +:107260005EF78032E8184412C6A484004422C85451 +:10727000EB35381118005A10FE03F80F4412C8906D +:1072800038109A02541080304E120125B60D380184 +:107290001808F8038400B60D4800011D8E21E6226F +:1072A0004EF201194412C8B838109A0244E2C8904C +:1072B0005A1002045A18083938171A02541080302C +:1072C000C13338F019115EF78032E92E4402C854F8 +:1072D000380018005A08FE04480000AB3C0DFA5272 +:1072E0005A0001045A0804095013FFDD96495CF066 +:1072F00085FB4EF2009E8E02E602E80F5005FFDD90 +:1073000096015CF009BB4EF200945003FFDD96013C +:107310005CF005FB4EF2008D84204402C8843810D6 +:107320001808480000813C0DFA525A0001045A081E +:10733000040738071A02960FC007D51138071A023A +:107340005400000CC00C802CFD148006F813812022 +:10735000802C80068048806AF806D50E802C8048F4 +:10736000806A800649FFFE3F8120802C800680488D +:10737000F30649FFFE6A2E47EE925A48011022F6A4 +:107380008004221680068A2FEB64E435E9075A98B8 +:10739000140385255A08140384054412C8E03820D4 +:1073A0009A11401098408A47EB5096D122208001D4 +:1073B000E3238A4BEB509651E903E201E83944227A +:1073C000C88486203911180804268009EB78E80360 +:1073D0005A48010786034422C848390118083C2D41 +:1073E000FA522F0FF06E5A2001085A20040638571F +:1073F0001A02974FC50DE3238440E8028442E2015C +:1074000040F83C0440113C043E17F06ED50C40247B +:107410008C06E2019692E80284A240214004FF57C4 +:107420003E57F06E84024412C6A4EB35D5038400A7 +:10743000B60D2E07F06EE602E94D4402C8E040604A +:1074400018402273000022B30001D5445A180243A9 +:107450004402C88438301800B44D8C6196583810F6 +:107460001808C2035A28050784004412C6A4EB3545 +:10747000D5314402C84838001800E220E8252E37EC +:10748000F06EE662E9278A019602964A5A280306B8 +:10749000002680189696CA1E4422C8E038411A1168 +:1074A000406118402223000198C1FFCC421584247A +:1074B000427200734211007340738CF6EB1B97FB12 +:1074C00040B08011D50784003E07F06E8400380973 +:1074D0001A0AF007ADC012B00001FCE6FC61814061 +:1074E00084C049FFFCE249FFFCE8800A49FFFC58E0 +:1074F0005095000880E644B2C6A43A048000B0412A +:107500003A0080208041800A96F849FFFDB0B00122 +:10751000EB6A3A04802038059E02C0038CC197B004 +:107520008CE15094804C5A780AEA3E67EEB1FCE157 +:10753000EAF4B42192259657C10DFC0080C0DD46C7 +:107540005A0802082E0728C7C804800649FFFFC84A +:10755000FC80DD9E440395B7A640440395B6A60083 +:1075600040000504DD9E440395B9A600441395B878 +:10757000A64840008104441F6A4488205CF0805A79 +:10758000E903440095BCDD9E440395B4A600EACA15 +:10759000DD9E440395B4A600EA46DD9E440395B5FE +:1075A000A600DD9E441395BAA6089600C00EA60854 +:1075B00096005A00010BA60896005A000207A6087A +:1075C00096005A0003038400DD9E9600441395BB89 +:1075D000AE08DD9EFC00446395B4AE704412E968C9 +:1075E000B6018401A989102080091000800810309C +:1075F000800A1000800B80018024490030E1A63011 +:10760000FC80FC0084414400B100842080628082C0 +:10761000EAB384003C0FFB693E07EEDCFC80FC40D3 +:107620002E0728122E2728422E372813421008240E +:107630003C1B94112E172843924142418424FE1C86 +:1076400092213E2728493C4B94123C0B94223E1732 +:10765000284A4402FE85A640842184C0AE40A6414B +:10766000AF813C6FFB2BEB565000002049003BF4F0 +:10767000EA673C0FFB3B49FFE18949FFE1D844033E +:107680008D364412FE5C44238D34B6C1AD90AD807E +:107690003C0FFB3144038D303C0FFB4944038D31DB +:1076A0003C0FFB3744038D323C0FFB232E0728B3DE +:1076B0003C1FFB283C2FFB2F3E67EBC75A080106F7 +:1076C000B401EA91B601D504B401EA4FB601B401A0 +:1076D000852140002404B601B40184C0EAB2B60199 +:1076E000B4018540EB2EB601B40184E0EA94B60102 +:1076F000B401EA44EA85B601B4013C0FFB4C4403F3 +:107700008D36A440EB94AC40A44066108001AC40A0 +:10771000A44066108008AC40A44044038D34AC40C3 +:107720002E0728B83E07EBACEA383E07EBB5EA393E +:107730003E67EBF63E67EBE73E97E9393C9FFBC6B9 +:107740003CABF61B3EA7EC003E67EBF13E67EBBBA4 +:107750003E67EF373E67EB883E07EBB9EA8BEB45B8 +:107760003CABF6133CABF61E3E97EBE43E97EB9A30 +:1077700049FFE477DD403E67EC143CABF6153E670D +:10778000EC15AF813E67EB973E97EBDA3E67EB94E3 +:10779000AF80DD5484023E67EB8A3C9E00823E67E8 +:1077A000EBBF3E67EF2C3E67EB9F3E67EF2DAE08C9 +:1077B000DD5BAE083E07EBC6EAC33C0803A83C0805 +:1077C00003AC4402E5603C0E01D54402E3DC3C0F0F +:1077D000FB4284083E07ECE03E67EBA03C7FFB32B7 +:1077E0003E67EBD43E97EBCD3C7BF62D3CABF624CD +:1077F0003E67EB953E67ED043E67ECE12E072813EC +:107800003E07294580073E67ECE23E67EEED3C7F90 +:10781000FB513C7FFB4A3C7FFB403C7FFB2D3C7F88 +:10782000FB443C7FFB2C3C7FFB573C7FFB453C7F74 +:10783000FB1C3C7FFB24F8028009490075928007FD +:10784000F8203C0E00C08009F81C3C0E00C18402E8 +:10785000F8183C0E00C28403F8143C0E00C38404E4 +:10786000F8103C0E00C48405F80C3C0E00C58406DC +:10787000F8083C0E00C68407F8043C0E00C78408D4 +:107880004900757E3C0E00C83C0394113C0B951CCE +:107890003C0394123C0B95853C03951F3C13951EAD +:1078A000400080203C0B95203C0395883C13958735 +:1078B000400080203C7FFBCA3C0B95893E67EF244B +:1078C000490069AB3C0FFB4E49006981EAA93C0EB7 +:1078D00002CFEA5C3C0E02D14402C5283E67ED3D72 +:1078E0003E67ED3C3E67ED3E3E600B383C7E02D08D +:1078F0003E600B483C0FFB52845F3C0DFB4E843FC7 +:1079000038201C088CE65A783CFA3C0DFB4E84C0AB +:10791000EB901010003D3C6FFBC73C6FFBC83E670F +:10792000EF313E67EF303E67EF323E67EF333E6741 +:10793000EC843E67EC863E67EC853E67EBE63E678F +:10794000EBF93E67EBB63E67EBDD3E67EBCB3E67A0 +:10795000EBE23E67EB8F3E67EBBC3E67EF364900DC +:107960001B303E67EF343E67EBA53E67EBC93E67D1 +:10797000EBA73E67EBF0EB56490039DDDD4BAF80FE +:10798000EA355A08010449003F4B8401EB17EAAD80 +:10799000EA694900031B84C14900031484004413AD +:1079A0008D41AE08EB43EBEC3C1FFB4D842BEB2DE4 +:1079B000842AEAFDEBF63E07EBFE8420440061A832 +:1079C0003C1FFB5884E63C1FFB533C1BF6283E172C +:1079D000EB9B3E17EBB73E100C7C3E100C7D3C0E33 +:1079E000031E8404EB3D3C6E00AC3E17EBBE3C1E18 +:1079F00000AD3C7E00AE3C0E00AFDD42C030441016 +:107A00000190440397ECAC404410011D440397EEF1 +:107A1000AC40441000E4440397F0AC40441000C76D +:107A2000440397F2AC40441000AA440397F4AC40DE +:107A30004410008E440397F6AC4044100072440397 +:107A400097F8AC40DD44440397FAAC40EAE24413B3 +:107A500097FCAC08441397FEAC08D504FD0349FF1E +:107A6000DDBF8401EA64EBE0840584C084E0441255 +:107A7000E9A0EA474402DE583E77EBC43E77EBCFFD +:107A80003E77EBEE3C6FFB543E77EBAE3C6E032251 +:107A90003E77EBD93E600C8449FFF20BEB63EA9929 +:107AA0004402FEFC3E7011313E77EBABAFC04402A6 +:107AB000FEFDAFC049000A05EB553C6BF6263E774C +:107AC000EBD73C6BF61C80263E67EB8984463E670D +:107AD000EE9AAF804402C464EA33802684464402AE +:107AE000C4D4EA3344038D45AF8044038D46AF8050 +:107AF000FCC0FC21446200B8800649003422EA2E12 +:107B0000F08149FFEEB89C3449FFEEB8500300788D +:107B100049FFED19500300A849FFEEB3500300CC14 +:107B200049007419EA2EF08149007418500300B01E +:107B3000490016BBEA2EF081490016BAEA2EF08100 +:107B400049001EE450030118490000B2EA2EF081FA +:107B5000490000B1490000CD5003012C49001C6FC1 +:107B6000507303A0EA2EF08149001C6C8007490085 +:107B70001C6CEA2EF081490051E15003017049006C +:107B8000562F5003031849006BACEA2EF0814900D0 +:107B90006BAB5003036449007136EA2EF081490053 +:107BA00071355003037449005623EA2EF0814900D1 +:107BB0005622800749006805EA2EF08149006804D2 +:107BC000500303AC49002497EA2EF0814900249029 +:107BD000EA89EBA0500303D049FFCFE7EA2EF081FA +:107BE00049FFCFE65003004849004281EA2EF08168 +:107BF000490019E449FFF15B49FFF15A490055F387 +:107C000049006F6C49FFCFD7490072084900568D73 +:107C1000FCA1FC00DD54840284C03C6FFBC7AE08AD +:107C2000DD5BAE08440000A2EBB7DD40A6015A08B8 +:107C30000D118006847F3C2DFB4E843F38310008B7 +:107C40008C065A083CFA3C0DFB4EEB901010003DA0 +:107C5000490000343E07EF112E07281B84C0520054 +:107C600000013E67EB88490001938401EA773E07F3 +:107C7000EBD1EB59EA353E67EBDE3E67EBAD3E6795 +:107C8000EBF35A080103EA7DFC80FC018401EAADB4 +:107C9000EB9A44036510EA488400EA553C1C01EB6A +:107CA000EB25FA50EB03EBD68401FC813C0FFC5131 +:107CB000DD9E3C0FFC50DD9EFC00840084203E07CE +:107CC000F13E3E07F13B3E07F13A3C1BF89C3C1B62 +:107CD000F89B3E17F13D3E07F13C44100040840004 +:107CE0003E17E9513E17E9503C0FFC52FC803C0D19 +:107CF000FC51A4413C1BF89AA444A6003C1BF899F3 +:107D00003E07F130DD9EFC20A7002E6728195A405F +:107D100001078480447200008204D52A4442040191 +:107D200084A0D608087200018CA110727FEA9768BF +:107D3000D5F92E4FEEB14E46000C3C4DFB28B4A4B5 +:107D40003C43983E4252880B5A580125D5198EA1C2 +:107D5000976844720000E0A4E9F19BAC88C7010376 +:107D600003EC99BD8EA1110303EC9768D5F59760DC +:107D7000E2A6E8E49967110283EC8C81D5F98C8F37 +:107D80003C5003A89721E285E80B5042800F9721D1 +:107D9000D5072E57EE915A58010444400050A600D2 +:107DA0005A0801472E07EBF09A10E402E8052E0767 +:107DB000EEEE5A08010A5A3801082E07F14CC8089D +:107DC0003E37F14CD50484003E07F14C84608400BA +:107DD0003E07EBF0A609C82F2E0728C35A0801104A +:107DE0005A3001085A28010C3C03F652E614E90700 +:107DF0003C0003A88C0F3C0B9605D5033C4B960525 +:107E00002E07EE90C0185A080105EBF28E14D5111A +:107E10005A080205EBF28E0AD50C5A080305EBF25C +:107E20008C0AD5075A080408EBF28C14D50284009A +:107E30003C0B9605FCA0FC003C1DFA4BA6088C01EF +:107E4000AE083C1DFA4BA6089604C8063C0DFA4D38 +:107E50003C0FFA4AD5053C0DFA4C3C0FFA4A3C0D52 +:107E6000FA4AA6481010003F80A08420EAEE500095 +:107E7000003CEAEED8FFFC803C2DFA4AA65098D18F +:107E8000AE199C0996005CF0003BE9028400AE103C +:107E9000A6108840841FAE11DD9EFC00EA732E57A9 +:107EA000EEA8D00BC804EB5ADD41D50444000051C4 +:107EB000DD41EA733E07EEA8EBB22E57EEA9D00CD7 +:107EC000C80544000054DD41D50444000053DD41A1 +:107ED000EBB23E07EEA92E07EF112E57EEAAD00CFB +:107EE000C80544000056DD41D503EA39DD412E07BF +:107EF000EF113E07EEAA2E0016FD5A00AA048407D1 +:107F0000DD41FC80DD9EFC0049002D67FC804410B3 +:107F10000055DD43AE40DD9EFC03F0818005F28319 +:107F2000F182F384F48549002CCEF002F10349007C +:107F3000306DDD44DD43AE40F001F104F20549004F +:107F40003005FC83FC2084C080E0E2C7E80B84019C +:107F5000844080208062808080A28CC1DD5697B0F2 +:107F6000D5F5FCA0FC0049003123FC80FC00490051 +:107F70003111FC80EB36C8082E17EE96C907FC00BD +:107F800049003121FC808400DD9EDD9EFC0049001B +:107F90002C8CFC80EB31C80FFC002E07281B4900FD +:107FA0002C84FA09EA412E07281B520000014900DF +:107FB0002C7CFC80DD9EDD9EFC00490031D3FC80E2 +:107FC000FC00490031C5FC8044130FA0B6204413C7 +:107FD0008068A845441373E8A846EB42A8424413BE +:107FE0000C80A84444133F9050200044B622441211 +:107FF0003200A851441274F8A853DD9EFC4480C09E +:10800000440178103B004C0044017820EBF8B1C4E7 +:108010003B004C003B03CC20EB882E172C92813F79 +:10802000420004019640C1038E219648EB058386E9 +:10803000B88A38038602B88B442000C84402DB3477 +:1080400042008873B89344031F40B88944038DD419 +:10805000B88CFCC4FC20842CAE4184003C0FFB7423 +:10806000EA9249FFDD95EABC3C0DFB74C00B84200D +:10807000846184028041808380A33C1FFB74DD56B1 +:10808000FCA049002D415A0801F4AFF0D5EEFC00E8 +:1080900049002D31840149002D33FC80A4408C21FE +:1080A00096495CF08190AC40E909FC008405DD4113 +:1080B0008400EA25EAA8EA61FC80DD9EFC20FD3010 +:1080C000DD42C01FA770DF0A8CA19768E6A5E90210 +:1080D00084A0EA38AF70EA8BD50D8406DD414413E5 +:1080E0008D20A6088C019600AE088400EA25EA39A6 +:1080F000EA6144038D20A600C00484013E07EF32EC +:10810000FCA0A6885A28AA0AFC00A680AE88842073 +:10811000AE40490030D0FC80DD9EFC00EA3F5A08AA +:108120000417DD465A000214EA9C5A080111840023 +:108130003E07EB888400EBB9EAE94402C39C49FF9F +:10814000FFE2840384203C2DFB23EB92FC80A68875 +:108150005A20AA10FC00AE80442FFFAAAE88A600C9 +:108160005A080105490030A1FC80490030A4FC8078 +:10817000DD9E8440AE808400AC08DD9EFC005A0881 +:10818000010549002EE1FC8049002EDFFC80FC0047 +:1081900084204403F560AE4084234403F561AE407F +:1081A0008400802080408060EA2CFC80FC008423D6 +:1081B0004403F560AE4084204403F561AE40840082 +:1081C000802080408060EA2CFC80FC004402FE633A +:1081D000A7404403F007A600D8084402FE64A74065 +:1081E0004403F004A600D006441FFF8EEBC3AE404C +:1081F000F80A4403F007A6005A002311441FFF9E0B +:10820000EBC3AE40843F4402FE61AE408420840252 +:1082100080418461808180A1DD56FC80FC24440182 +:1082200078403B004C0044217850EBF8B004EBB5AB +:108230003B004C2044238D41A6904411D8004010AF +:108240008840A6C838500A028400384F8A0296D85F +:108250004462623880E03C139422E201E818402333 +:108260000020030100003812800042180424390263 +:10827000010140108C0E8A309649AC50A450964BA8 +:108280004E140003ADD08C019601D5E6FCA4FC0190 +:10829000F08194918001F101DD48FC81FC064422CB +:1082A0000000FAD0A6D2A71384A18440F68584C228 +:1082B000F283F284F286F288F289B67FF581F38246 +:1082C000F687F58A8041EA3DFC86FC00C805EAB0E5 +:1082D000EAB7EA48FC8049FFD0DC80A0C8F9EAB0E0 +:1082E0004413000244226238EB572E4728134900FA +:1082F0002990FC80FC00DD5280C0A64949FFFFE7C1 +:108300005A680306EB31C80349FFFF8AFC80FC264C +:1083100097D0FA5084C084A1F28584429718F287DE +:10832000B6FFF581F782F683F684F686F688F6893D +:10833000F58A80418067EA3DFCA6FC0644420000C5 +:10834000A7A284A0A723F581F582F583F584F5869D +:10835000F588F58984A1F285F387B6DFF58A804137 +:108360008066EA3DFC86FC07F38DFA7084A080826B +:10837000F38584418462F281F482F387F28A806417 +:10838000B6BFF583F584F586F588F5898041F40D4F +:10839000EA3DFC87FC01EB7AEB42EA4844036510B6 +:1083A000EB9AEA488400EA553C1C01EBEB25FA50B5 +:1083B000EB03EBD6FC81FC08F18EF08D8023F28F6D +:1083C000EB57C4052E4728138003D503800484810E +:1083D00084A1B61FF0828400F083F184F085F086DA +:1083E000F088F089F08AF581F587F00DF10EF20F33 +:1083F000EA3DFC88FC01DD465A08021A8400EA5571 +:108400008481EB7AEB42442373E8846049FFFFD513 +:10841000501F8006EAC484408463EB58220F800317 +:1084200044100096EB3B40008007FC818400FC81F7 +:10843000FC2544620000A7F2A7B3F381B0C7F38420 +:108440008460F482F583B6DF808380A749002751DA +:10845000FCA5FC008401842049002DE044000CD5DB +:1084600049002DE4FC804403F01F4423F302A600DE +:10847000A650540000E096678C225EF08020E8074A +:10848000A650966788018C029600D5038C1F960033 +:108490004413F01FAE08DD9EFC00840080204900DC +:1084A0002A1E49002ED5490035AA49FFFFD449FFAD +:1084B000FFDC49002D48490027ED49002F284900DD +:1084C000295A4900290349FFC08CFC803C03F4AAC7 +:1084D0003C1DFA564423F540B4423820820A442316 +:1084E000F544B4629C819691EAC04423F548B46295 +:1084F0009C829691EAC04423F54CB4629C83969189 +:10850000EAC04423F550B4629C849691EAC04423A7 +:10851000F554B4629C859691EAC04423F558B46240 +:108520009C869691EAC0502000083C2BF4AA8C0748 +:108530004423F55CB44296013820820ADD9EFC019A +:108540005A0801163C0DCA21B61F3C0DCA22F08103 +:108550003C1DCA1C3C0DCA1B3C2DCA1D3C3DCA1EFD +:108560003C4DCA1F3C5DCA20F815D516C8153C0DF8 +:10857000CA19B61F3C0DCA1AF0813C1DCA143C0D25 +:10858000CA133C2DCA153C3DCA163C4DCA173C5D6A +:10859000CA1849002ABDEAD75A0801093C03F4AABF +:1085A0005CF00080E80349FFFF9384008020804056 +:1085B00080604900289B49002876FC814423F0779D +:1085C000A6509604EAD6FE0FAE10DD9EFC2080E099 +:1085D00080C1DD46A6B9C80650017FF6E6028409CF +:1085E000E9028002EA28EA40AE884423F380A650DC +:1085F0005A1001FF4E6300668E01E60E4EF200CA6D +:1086000044F0840CEBAF40F03C00DD0F1C00840113 +:108610002200AC002200AC00AC00280028005E0064 +:108620005E00AC002200A8008403EAA5F84884009C +:10863000F895F84584014900293D8400F895EA8CB5 +:108640005A0801064400088EEA41D5088440840196 +:1086500084248062808280A0DD568401EAF3840154 +:10866000F88ADD46C82AEB68D528EAE3C005EAD7D0 +:10867000C0038400EB608401F87E8400F875EA8C06 +:108680005A0801064400088EEA41D5088440840156 +:1086900084248062808280A0DD56EB688400F85ECE +:1086A000EAE34E020077EAD74E0300748401EB60E0 +:1086B000480000708401EAF38400EAA54800006ADB +:1086C0005A6801628E03E60CE86444F084D8EA7FBD +:1086D00040F03C004A003C000C120C1212181870BA +:1086E00070B80C8C8401F83AD5548401EAA5D551B0 +:1086F000EAE3C011EAD7C00F8400EB603E07F02820 +:108700003C03F4AA3C1DFA568E019402B601840182 +:108710003C0BF4AAEAE3C80D8401F8268401EAA51B +:1087200044000037EA418400F8268400F829D53156 +:10873000EAD7C8F33C5DFA5684213E17F14D50123A +:108740008200AA29D9FFD5E9EAD7C005EAE3C00328 +:108750008400EB608401F808840149002BA4EAE35B +:10876000C8A3D517840149FFFEEC49FFFD1284011F +:10877000EAA5840049FFFF248400EAF3840049004D +:108780002899D5075A6802068401EAA58400EAF30D +:10879000FCA0FC40EA3F80C15A08040BEA9CC008D8 +:1087A000DD465A080213842049FFD1F6D50EDD4676 +:1087B0005A0002F88401DD508420846184028041E3 +:1087C000808180A3DD56D5F48402DD5084414400CD +:1087D00001A04410003080628082EAB3842084616A +:1087E000440001A080418083EAB35A00300E8441E6 +:1087F0004410003080628082440001A0EAB344004B +:1088000000D7DD41D5ECEA3F5A080410DD465A0096 +:10881000020D2E7728AB5A7801098007490029708C +:108820008400EA258007EB69EA6FEA753C0DFB746A +:10883000C0078404DD50EA3F5A08041FD5094900E7 +:1088400029635A0801F88403DD50EA53D5F0DD4668 +:108850005A000213EA9C5A080110840049FFD956B5 +:10886000441FFFC34403F429AE40DD408420DD579C +:108870008402AE31D50F804684058420EB92DD4022 +:108880008420DD578402AE31840149002B2B8405FE +:10889000DD50FCC0FC20EAFF5A080152DD46C84FFB +:1088A000DD59A6405A1801FFA6005A080149DD4CBF +:1088B000A78097B05A680144DD408429AE418420E6 +:1088C000DD57DD40842AAE41DD4280E0DD59C70D31 +:1088D0008420AE40DD4CAE408006EA258409EA2BB8 +:1088E0002E07EE99EA6BD52BAFC0DD4CAFC08006EA +:1088F000EA254402FEF2AFC0DD44DD43AE40EA9E0D +:10890000C0FF49FFD8BAEA21EA8AAE0880418461F3 +:108910008402DD45DD40EB8CDD4C8421AE408401DA +:10892000EBE75A00010DEA9C5A080108DD40A60158 +:108930005A080A0449001F9D8400EA5BFCA0FC431E +:10894000441178608140A600B1823B00CC003B031B +:108950004C2085205A0801054900415A8120840095 +:10896000EA5584E0EB3038031E02842094918CE1B8 +:10897000EA335A7804F9EAAB5A08011C8403DD5241 +:108980008049EA4BEA932E17EBA4440000C8FE0C82 +:10899000EA55EB42F80344130FA0EB252E272812CB +:1089A0002E372813EBD649FFFF77DD54A608C8FF02 +:1089B000DD44DD43AE408400FCC3FC2184C0FA00EA +:1089C0003E67EB8B44738D40DD414900318184016A +:1089D0003E67EBD03E07EB9E3E07EEEA3E67EF02B6 +:1089E0003E67EBBA3E67EBBDAFB8DD46DD525A08D5 +:1089F000020B8404AE0980018420DD57DD40842D04 +:108A0000AE41D50A8409AE0980018420DD57DD40DE +:108A1000842AAE41AFB8DD598421AE40EA355A0808 +:108A2000010EDD4BA6003E07EBD2EBB1A6003E07E0 +:108A3000EB98EBBEC8033E07EF02DD40A6013E0700 +:108A4000EBEB8406DD50EB04C814DD40EA3A2E0758 +:108A500028B65A08010449001BE5840ADD50490084 +:108A60001C53EA35C04BDD465A080249840BDD50E1 +:108A7000EA355A080110DD42C00DEB045A00010529 +:108A80002E07EBBAC8074402C6F2501F800749FF01 +:108A9000FF58EA355A08012BEB04C80B4400006666 +:108AA000DD5049001CA55A08010C3E07EB8BD50888 +:108AB00044000067DD50DD54A6085A0801FF440059 +:108AC0000068DD50DD42C008EA305A0807FFEAB00E +:108AD000EAB7EA48D505DD54A6085A0801FFDD5477 +:108AE0008402AE08DD5BAE08D509DD42C007EAA806 +:108AF000DD50DD4BA60049FFFBFF84003E07EEEA98 +:108B0000DD46DD522E27EBEB5A0802089E12E602E4 +:108B1000E806840DAE09D5075A200204AE89D503B4 +:108B2000840BAE09DD40EA3A8400EA45EB5E3E077D +:108B3000EBA03E07EB9E84C14400006ADD503E6717 +:108B4000EBBADD42C00349FFF8A23E67EBB2DD4657 +:108B5000C80484013E07EEE44400006FDD50FCA130 +:108B6000FC00EAFF5A08011FDD46C81CDD59A6407B +:108B70005A1801FFA6005A080116DD4CA78097B0CD +:108B80005A680111DD408429AE418420DD57DD4063 +:108B9000842AAE41DD548400AE08DD5BAE08800659 +:108BA000EA25FC80FC00DD40A6415A10061C2E1769 +:108BB000EB9DC9182E67EBF7CE15DD54A6485A1861 +:108BC0000112DD5BA6485A18010E8026EAD8DD574F +:108BD000DD59AF802E07EBDCC803DD5BAE088401F6 +:108BE000EA25FC802E07EBAF8421EB48DD9E440391 +:108BF000F07FA600EA57DD9EFC0049FFFFFAFC80EB +:108C0000FC4080C2812080E1EBB349002B964420D8 +:108C10001900FE14E206E8138AC0442186A040230E +:108C2000085710248000440E7960969042610073CA +:108C300044001388406300D7AFB8FCC084201014F0 +:108C40008000AE78FCC0FC00EBB3EBA6FC80FC011E +:108C500080C08001F281EBBAF001EB8784013E070E +:108C6000EEE6A6303E07EEE58400EBFB8401EAE881 +:108C7000F8F12E07EEE65A08010984408020806250 +:108C8000808080A2DD56D5F6FC81FC0080C080018A +:108C9000A648C1058421442000CDF807A630C007AE +:108CA000800684244420008249FFFFD38407EBBA66 +:108CB0008400EB878400EAE8FC80FC20A78080E049 +:108CC000E6CBE9068ECA840A97B0AE38D50284C0D6 +:108CD000A638C0038C01AE38A638E603E9038C0140 +:108CE000AE38A638C8038401AE38A608C004EA70BE +:108CF000FE0CEA41C6059431EAA649FFF925A6789B +:108D0000C107844084028461848380A2DD56FCA074 +:108D1000FC02F08180C1F80CF201F8725A68020975 +:108D200084013E07EEE0EAF2EAFCF862D505EAFCCF +:108D3000EAF283FFF869F88EFC82FC21FD30F281B3 +:108D4000DD46C82C5A700907461000F450008240D6 +:108D5000D505461000C3500085005A60011DC604A9 +:108D60005A600205FCA1F876FCA12E27EEDF2E3713 +:108D7000EEDECA02C310441186A0FE5C846AEB1BBF +:108D8000443FE70042010C738A0184203E17EEDE67 +:108D90003E17EEDFF10149FFFFBDFCA1FC2080E0A2 +:108DA00080C1DD465A08020ACF1ADD40A6415A109A +:108DB000041349FFFEF9D513DD40A6415A100B10EC +:108DC0005A6004068006844349FFFFB9DD40A6418E +:108DD0005A180904EBAED50349FFFEC4FCA0FC02FF +:108DE000F081EAF2EAFCF201F80BEAFCEAF249FF50 +:108DF000FF66FC82FC02F081EAF2EAFCF20149FF24 +:108E0000FF01EAFCEAF249FFFF42FC82FC00460057 +:108E100000A650000040F80DFC80FC00F81BFC8010 +:108E2000FC00F818FC80FC00460000A65000004042 +:108E300049FFFFD7FC80FC00EBF4EBDCEB4FFC8040 +:108E4000FC00F808FC80FC00EBF4EBDCEB4FFC8052 +:108E5000FC0049FFFEFAFC80FC00EBF4EBDCEB4F7E +:108E6000FC80EB33DD9EFC2080E180C2C00D5A0007 +:108E7000041184003C0BF61F49003592444395AC25 +:108E8000443395AAD50A444395A6443395A4D50501 +:108E9000444395AC443395B084009680E246E8079D +:108EA00038138101381201098C01D5F83C03F61FF3 +:108EB000AC18FCA04422FF5038100808DD9E445234 +:108EC000FF5084204402FF70EAEED8FFDD9E3C0391 +:108ED000F8A88C0196015CF000FFE90284003C0BCD +:108EE000F8A83C13F8A84402FF52AE40DD9EFC40B7 +:108EF00049FFD757EA3F9E46E622E90A50107FF71E +:108F0000E625E9065A001105840148000074DD4099 +:108F1000A6015A0804148404441000BDDD4744002F +:108F200000D0DD50DD42C01F840049FFCF5F8401C7 +:108F3000DD4AEAA7EA6FEA75D50B8E08E604E9EC8C +:108F4000DD465A0802EAFA31EA66AE40D521A6307B +:108F50005A002105EB3FEA53D5FB8402DD4A840029 +:108F6000EA5BD5162E07EFAEC808840244139700BB +:108F700044238D54EA87EA608406DD4AEA21FA1127 +:108F8000AE08804184028461DD458400EAC6840322 +:108F9000DD4ADD4084C0A601DD4A490024B9440011 +:108FA00000D1DD50DD469E4240130406840249FF95 +:108FB000CDF3DD465A08010B80064900277580066F +:108FC00049002790800649002783440000D2DD50E5 +:108FD000DD40EBD53C2DFB284432C520490041B68D +:108FE00080C05A00080448FFFF91440000D3DD50C0 +:108FF0008006FCC0FC40EB8949FFF31349FFFA4EA1 +:10900000DD4084C1AF8149FFF576440000A0EBB795 +:10901000EBE8DD5249FFFBBF44000051DD50EA6F31 +:10902000EA7549FFFDE6C8053E67EF0DEA53D5FA3C +:1090300084003E07EF0DEB5ADD50FCC0FC00840FAE +:10904000DD41840444100062DD47DD44DD43AE4071 +:10905000EA80A608C8FF44000082DD504400008377 +:10906000DD50840149FFD70344000084DD50FC80BB +:10907000FC00840444100061DD4744100067840450 +:10908000DD478404EB0A440000A1EBB7DD40EBCBE5 +:10909000EAC9EBCF848049FFE1BAEA6E5A080109B8 +:1090A0004402C378EB5D49FFF86649002904DD54AA +:1090B0008402AE08DD5BAE0849FFFFC284044410A1 +:1090C0000068DD4749FFFC7BEA6E5A08010449004D +:1090D00028EC49FFF5A08402DD41840444100069B6 +:1090E000DD47FC80FC00EB9B80C0840CDD5044031A +:1090F0008D47A6408C219648AE40DD44DD43AE400E +:109100008409441000A1DD4749FFF809840944108F +:1091100000A2DD4749FFDA9C8409441000A3DD4723 +:10912000DD40A6415A100D0B2E17EF2CC907441233 +:10913000C3ED4422C700490042438409441000A4FF +:10914000DD472E07EBA05A080107FA05DD4184C26E +:10915000480000EC8409EBB6DD472E07EE9BC00A01 +:10916000EA7EA6405A102105A6005A08220484016E +:10917000EA32DD555A08190449FFDAC7EBE25A080A +:10918000011CEA305A0807198400EB59EA355A08DD +:109190000112DD4BA60049FFF92F5A080107EBBE6B +:1091A0005A0801043E07EB8B2E07EB8BC003FA062F +:1091B000DD418401EAAD84003E07EBC12E07EC03DC +:1091C000C810EA305A08070E840AEA3EDD528401CC +:1091D000EA323E07EBC1DD4BA600A64949FFF8770E +:1091E0002E07EBF65A08010C4402C3E6EAF4EAC97A +:1091F0003C3DFB313C4DFB2F49FFDB84DD42C0137E +:10920000840C00130050DD47840D00130051DD472E +:10921000840E00130052DD472E07EB8F5A0801041D +:109220008400EADA3C0DFB5A5A080142DD59A600D7 +:1092300096005A08013D84203C1FFB5A2E17EBF282 +:109240005A18551B2E17EE9CC104EADAEAE1D5162E +:10925000EA7EA6005A08130544000086DD41EBE8CB +:10926000DD524422C39C3C3DFB284442C52049FFBB +:10927000DD6FEAE1D503EA39EB45DD5549FFD873E7 +:1092800096003E07EB9ADD4A2E67EB9A5A60034E32 +:109290005A68020EFA04DD412E07EC0ADD41DD4476 +:1092A000DD43AE40DD54A608C0FFD53FDD54A6081F +:1092B0005A08020EDD4CA6005A08020A8401AE08C4 +:1092C000DD5BAE08DD46C80349FFFDC8DD40A601F1 +:1092D0005A080A08DD46C80349FFFDA149FFFADC28 +:1092E0002E07EBC15A08010DDD4BA6005A080309F1 +:1092F000EB31C80684023E07EBC149FFF791DD550B +:109300005A080404490036802E07EBF384C15A083A +:10931000010D84003E07EBF3DD5BA6089600C8FE56 +:109320008441AE88FAC3EA328006FC80FC01EA6E12 +:109330005A0801064402C3788420EB46EA355A08ED +:10934000010449003883DD4BA6005A08030CEA35B6 +:109350005A080109490034E884023C1DFB27F80E35 +:10936000D50F490027F1F081F1018400F8072E079D +:10937000EE915A0801068402842F49FFF61FDD4052 +:10938000A6415A180D048423AE41440000A3EBB754 +:109390002E0728AD5A08010BDD40A6005A08010728 +:1093A000DD4BA6004900291AD504EB7AEB9AEA486E +:1093B000EA694412C46C4422E2F44432000044429C +:1093C000DF4049FFE2EDFC81FC002E0728AE5A0881 +:1093D0000108EA694412D82849FFE241D5053C0C4E +:1093E00001DDEBB4EA482E0728C35A08010E4402F7 +:1093F000C6E44412C6E24422C6E04432DF4C444292 +:10940000DAF049FFEA91EA89B400EA465A0001031A +:1094100084003C0FFB2B84013E07EF3ADD555A08D0 +:109420001209EA728421EA9A5A080104EA4DEA63B1 +:109430002E17EBAC5A1801054402C378EB46DD55F4 +:109440005A08120AEA728422EA9A5A08010584022A +:10945000EA4DEA63FC80FC0049FFFD05C00384017E +:10946000FC80EA88C004DD5A5A00020B44033070C5 +:1094700049FFE547C0F5FA18EA998403FC808404A3 +:10948000FC80FC6680C0EA372EA728122E8728357C +:109490002E9728342EB72813C00944C3343C44D334 +:1094A00033D844233374EBB8D50844C21B3044D2BC +:1094B00019A044221810EB12CE2F84E1FB708522F4 +:1094C000806A808880A78041F80B44034C10EA3DF5 +:1094D000EB14EA2744035890DD48802D804DB75F98 +:1094E000F78114AF8002F683F68414BF8005F686F8 +:1094F000149F8007F688F689F78A83FF44034F306C +:10950000806A808880A7EA3D44134F30EA274403ED +:109510005BB0DD48FCE65A68012F84E0FB10854211 +:1095200080228069808B80A644034DA0F80BEA3D21 +:10953000EBA7DD5D44035A20DD48440350C0802C76 +:10954000804CB73FF681149F8002F783F784148F15 +:109550008005F78614AF8007F788F789F68A83FFBE +:109560008069808B80A6EA3D44035D40441350C06F +:10957000DD5DDD48FCE6FC004E02005DEAC4EA2742 +:109580005A181421EB14DD4844134F30F8204412CC +:109590009ECAF823440383884412A1EAF82DEA37CF +:1095A000C003EBB8D502EB12F826EA37C004441327 +:1095B00033D8D503441219A0EA2744037D48DD4877 +:1095C000FC8044135890DD4844135BB0EA27440301 +:1095D0007708DD484412A50AEA2744038068DD487D +:1095E000440383884412A82AF807EA37C003EBB87B +:1095F000D502EB12EB81EA27DD48EA37C0044413B9 +:1096000033D8D503441219A044037D484E00FFF51A +:10961000441386A84402AB4AF86AF8064402AC1226 +:10962000441389C8F8643B0054003B00D42083FFF6 +:10963000FC8044037578DD5D5A181420EBA7DD48E3 +:10964000441350C0F81F4412A05AF822440385184E +:109650004412A37AF825EA37C00444133374D503BF +:1096600044121810F826EA37C0044413343CD503DA +:1096700044121B30F829FC8044135A20DD4844135F +:109680005D40DD5D44037898DD484412A69ADD5DB7 +:10969000440381F8DD48440385184412A9BADD5D0E +:1096A000DD48EA37C00444133374D503441218105C +:1096B00044037BB8DD5DDD48EA37C0044413343C25 +:1096C000D50344121B30DD5D44037ED8DD484423BE +:1096D000883880224402ABAEEAA344238B58EA7B4D +:1096E000F806F8084402AC768022F801EAA3EA7B87 +:1096F00083FF3B0050003B00D02083FFFC80FC40F8 +:10970000C8053C5DFB47C508D53F5A08013E3C5D96 +:10971000FB475A58013A2E57EB9984C38EABE2C5EA +:1097200084C0E9052E67EB998ECB97B1C0085A0823 +:10973000010B4470003280A78604D508FAF084A695 +:109740008207D50484E080A782078124EAC44440CC +:10975000019042581424420310735A1814068022B0 +:1097600094A9DD48D504802394A9DD48EB06EB815C +:109770004203047394B98029DD482E07EB995A08F7 +:109780000E048408EAF7FCC0FC012E27EBBE5A2029 +:109790000704480000A7E6104EF200A4F18144F04F +:1097A00095AC3817810140F0BC00DD0F200020008F +:1097B000200020004C006000740086009800AC007F +:1097C000C000D400E800FA000C0120012E57EB99EC +:1097D0008C0B4C504087EA30C8048401F101F80733 +:1097E000EA305A000103F8078400F10149FFFEC581 +:1097F0008408EAF7480000768400F10144234C1005 +:10980000443358904442AB4AF86AD56B8401F10165 +:1098100044234DA044335A204442ABAEF860D56196 +:10982000442216808400F10180624442AB4AF8571A +:10983000D558442218108401F10180624442ABAE35 +:10984000F84ED54F8400F10144229ECA4432A50A45 +:109850004442AB4AF844D5458401F1014422A05A60 +:109860004432A69A4442ABAEF83AD53B8400F101AB +:1098700044234F3044335BB04442AC12F830D5310E +:109880008401F101442350C044335D404442AC762E +:10989000F826D527442219A08400F10180624442B1 +:1098A000AC12F81DD51E44221B308401F1018062E8 +:1098B0004442AC76F814D5158400F1014422A1EAA3 +:1098C0004432A82A4442AC12F80AD50B8401F101B3 +:1098D0004422A37A4432A9BA4442AC7649FFFF112C +:1098E000FC819200FC602E4728122E2728352E3747 +:1098F00028342E1728134E0300F442320824405215 +:10990000040990618020449320D044A3226044B392 +:10991000271044C328A045234C1045334F30E02383 +:10992000E82C4020949797209489CC0296104041CF +:109930002400A5208C214112001140412800A520BF +:1099400096484102001140412C00A5E0884C950149 +:10995000A590402248001311000098859491411170 +:10996000480097FB97B3889388538C0113088000B5 +:109970009600ADE0AD90D5D4EAAA5CF000A04EF31D +:1099800001585A00A0095A00A10B4462A1EA4412EE +:109990009ECAD50844634F30EB14D504446219A025 +:1099A000EB122E07EBA2E602E82D3C0DFB4B5CF020 +:1099B0001388E90584003C0FFB4BD5048C013C0F58 +:1099C000FB4BEA27EAC4DD488026EA274403757882 +:1099D000DD48441000C144037572AC40EB28A4007C +:1099E000441375749603AC08EAE0A400441375763A +:1099F0009603AC08442373E8EB14EA228402EA607D +:109A0000F8719E82E642E821EA27EB81DD48802654 +:109A1000EA2744037BB8DD48441000C244037BB20C +:109A2000AC40EB28A40044137BB49603AC08EAE0F6 +:109A3000A40044137BB69603AC0844237578EBA7C7 +:109A4000EA228402EA60F84E9E84E642E823EA278E +:109A500044038068DD488026EA27440381F8DD4816 +:109A6000441000C3440381F2AC40EB28A40044132B +:109A700081F49603AC08EAE0A400441381F696034F +:109A8000AC084423770844134F30EA228402EA608A +:109A9000F8298E06E6024EF200CCEA27440386A897 +:109AA000DD488026EA2744038838DD48441000C496 +:109AB00044038832AC40EB28A40044138834960356 +:109AC000AC08EAE0A400441388369603AC084423AB +:109AD0007898441350C0EA228402EA60F8035A00DE +:109AE0000104480000A640518409FECC8420906106 +:109AF0008001449323F044A3258044B32A3044C317 +:109B00002BC045234DA0453350C0E003E82C402036 +:109B1000149797209481CC02965040412400A520B0 +:109B20008C014112001140412800A52096004102FD +:109B3000001140412C00A5E0884C9509A5904022D9 +:109B4000480013110000988D94914111480097FB33 +:109B500097B3889388538C21130880009648ADE012 +:109B6000AD90D5D4EAAA5CF000A0E9625A00A00941 +:109B70005A00A10B4462A37A4412A05AD509446347 +:109B800050C0EBA7D50544621B30441218102E07B5 +:109B9000EBA2E602E812DD5D44037708DD4880268B +:109BA000DD5D44037898DD484413525044237A28FD +:109BB000EA228402EA60D53C9E82E642E812DD5D3C +:109BC00044037D48DD488026DD5D44037ED8DD48C2 +:109BD000441353E044237BB8EA228402EA60D52888 +:109BE0009E84E642E812DD5D44038388DD488026DA +:109BF000DD5D44038518DD484413557044237D48DA +:109C0000EA228402EA60D5148E06E602E811DD5DE0 +:109C1000440389C8DD488026DD5D44038B58DD4858 +:109C200084024413570044237ED8EA22EA60FCE011 +:109C300084004412DFD48040382081098C014432F2 +:109C4000DFD45A08C0FB8400804098588C02122050 +:109C500080C85A0990FCFC203C4C01DD84A084C3E0 +:109C600044700640A4205412801F4022A0094020C6 +:109C700088A0960339018901400018168810380120 +:109C80008909400294090A22000194024000047CE0 +:109C90009693500000C840111836382181018CA1DC +:109CA0008822976938118109DFDEFCA0FC662EA7A7 +:109CB000281280C02E8728352E9728342EB72813D7 +:109CC000C0035A08010449002388EA37C00944C385 +:109CD000343C44D333D844233374EBB8D50844C25E +:109CE0001B3044D219A044221810EB12CE2284E17A +:109CF000806A808880A7F8064403589044229ECA50 +:109D0000EA3DB75FF78114AF8002F683F684F685EB +:109D1000F686F787F688F689F68A83FF44035BB0F8 +:109D2000802D4422A1EA806A808880A7EA3DFCE673 +:109D30005A68012384E0802244035A204422A05A16 +:109D40008069808B80A6F802EA3DB73FF681149FB8 +:109D50008002F783F784F785F786F687F788F78917 +:109D6000F78A83FF44035D40802C4422A37A8069F4 +:109D7000808B80A6EA3DFCE6FC2080C08020440267 +:109D8000D82849FFDC4DCE584452A50A443D5AF626 +:109D90004442DFD484E34422A68A982B381200116F +:109DA000A4284462DFD49603E020E908EA3BC80215 +:109DB000EAB9A4288A019603AC288CA2DAEF848140 +:109DC00080A44402A50A4432DA288420EB2FF8BC90 +:109DD00084003C0FFB3C3C4C019A806080A02E200C +:109DE000111D9860C20FA48896934E27000CA4887A +:109DF00050217FCE9693AC88A48896934E2400037E +:109E0000AD48A4488C02964B88615A0840EA8440C9 +:109E10003C3FFB3C4402DE5880628421F85BEB2F20 +:109E20008400EBD3F8964452A82A444D57D6846058 +:109E30004422A9AAD55D5A6001044800008D44520D +:109E4000A69A443D5AF64442DFD484E34422A82A29 +:109E5000982B38120011A4284462DFD49603E02026 +:109E6000E908EA3BC802EAB9A4288A019603AC28AB +:109E70008CA2DAEF84214402A69A4432DA28808147 +:109E800080A1EB2FF86184003C0FFB483C4C019B08 +:109E9000806080A02E20111D9860C20FA488969328 +:109EA0004E27000CA48850217FCE9693AC88A488BE +:109EB00096934E240003AD48A4488C02964B8861CB +:109EC0005A0864EA842180413C3FFB484402DE5842 +:109ED000846049FFE06BEB2F8401EBD3F83A4452E6 +:109EE000A9BA444D57D684604422AB4AD51A80257E +:109EF00038009005381304119603E020E902ACE81D +:109F00008CA2DAF6842080814402A82AEB414432F4 +:109F1000D9B084A1F8198400EB66EB41F81AD51B7F +:109F2000802538009005381304119603E020E902DB +:109F3000ACE88CA2DAF684214402A9BAEB4180A1F4 +:109F40004432D9B0848049FFE3838401EB66EB415E +:109F500049FFE112FCA0FC004432C3B24402DA28FB +:109F6000EB66EB1049004042EA5CEBD32E27EBC2D4 +:109F700049005DB9EA5CEBD3EB2F8461F805EB4156 +:109F80008460EB66EA5C49FFBE4FEA5C4900452FFE +:109F90002E17DDC1EA5C49006046EA5C4900525771 +:109FA000EA5C4900456DEA5C49005575EA97C003D3 +:109FB0005A08050D84013E00111E3E00111D84004B +:109FC0003C080891841F3E0011192E0011195A00F7 +:109FD000FF0684003E001154D50484013E00115454 +:109FE000EA5C2E17DDC14900611A8401FC80FC0087 +:109FF0002E07EBADC803EA32D5068401EA328400AD +:10A000003E07EBADDD555A08120AEA72842FEA9A30 +:10A010005A080105840FEA4DEA63DD4C8421AE4005 +:10A02000EA9C5A080108DD40A6015A080A044900C2 +:10A030001420FC80DD9EDD9EFC002E07EBC7C8418E +:10A040002E67EB8B5A68010BEB40C808490055F1AD +:10A05000C805EAF8C8033E67EC00EA73C81EEB4087 +:10A06000C81C2E07EC00C8192E07EB8B5A000116EE +:10A07000490006DD5A080208FA02DD4184013E0764 +:10A08000EC00D50B4402E2F43C13947E4422C3E17D +:10A0900049000DD65A0002F2DD40A6412E07EC0021 +:10A0A0005A1006045A180B105A0001092E07EF36F1 +:10A0B0005A0001052E07EBF1C0048401EA49EA7752 +:10A0C0008401D5245A00010A2E07EF365A000106F2 +:10A0D0002E07EBDE5A0801F6DD44DD43AE40DD54C9 +:10A0E000A608C0FF84003E07EC003E07EF3684015F +:10A0F000EB5EDD555A08120AEA728425EA9A5A087C +:10A1000001058405EA4DEA638402FC80FC00EA351F +:10A110005A08010A44020400501000285020005040 +:10A1200049002FE8DD40EBD52E27EBFD2E37EBC99C +:10A130002E47EBA549FFEDE9EA9C5A080107EBAA77 +:10A140005A08010449000B32FC80FC2084C02E0711 +:10A15000EBC5E2C0E82C3C0C00C195F13850190168 +:10A16000DE243C0C00C44422D82898473C0C00C391 +:10A17000A649380019113C3003A849FFDACE3C1C2F +:10A1800000C188E1A478FE0FAC383C0C00C3381045 +:10A1900019013C03983EE220E8082E07EBA55A007F +:10A1A000FF058C013E07EBA58CC1D5D2FCA0FC00BD +:10A1B000DD40A6015A000305F83EE603E906DD5539 +:10A1C0005A0005045A08120A84003E07ED3C3E0777 +:10A1D000ED3D3E07ED3ED5373C0DFB5D5A080109CC +:10A1E00084003C0FFB5D4402C52849005519440218 +:10A1F000E3284412C538490058413E07ED3EF81B9C +:10A200005A08030784003E07ED3C3E07ED3D490038 +:10A21000552280C05A080110F80E5A08030780061C +:10A22000EB6244000061DD41F8065A08040D840128 +:10A23000EB62D5094900550C5A0803068400EA2A46 +:10A240008401EA77FC80FC20EA6E5A080106440289 +:10A25000C3788422EB462E0728B25A080108EA691F +:10A26000EBD54422DAF049000B544402DF4049FFA9 +:10A27000E3C8EA9C5A080109EBAA5A0801064402FD +:10A28000DF4049000AAFEA694412C4944422000046 +:10A290008460848549FFDB29DD555A08120AEA7279 +:10A2A0008423EA9A5A0801058403EA4DEA632E07DB +:10A2B00028B25A08010AEBB25A080107EBEFC004B2 +:10A2C000EA6949000CAF8400441201D03E07EBE577 +:10A2D000502080144402C7004900053EEBEFC80738 +:10A2E0004402C7004412DF4C49000551EBEF4E0217 +:10A2F000006584003E07EBCCDD555A08120AEA726D +:10A300008424EA9A5A0801058404EA4DEA63EA358E +:10A310005A0001062E0728B25A0801064402019C81 +:10A32000490030FC84003E07EEEC4412DAF03C0CAD +:10A3300001DC3C2003A84432C3B58481EAFB2E072C +:10A3400028B15A080119EA89B40096045A00010894 +:10A350003C0DFB31A60096045A08010EEBCEC80B4B +:10A36000EB244412DF4C4422C3B5490003EA3E0704 +:10A37000EF12D50684003E07EF12490002A649FFFE +:10A38000FEE62E0728C45A080229DD4BA600C80F96 +:10A39000EAF8E602E90CEB24EBB44422C3B54432FC +:10A3A000E37C4442C3ED490007D7D51784003E073C +:10A3B000EF3849000606D511EA735A08010649002C +:10A3C000027A3E07EF12490005FC84003E07EF3891 +:10A3D0003E07EBC53E07EBA5EA6E5A0801064402AC +:10A3E000C3788423EB462E17EBC5EB403E07EEEB1C +:10A3F000C9043E17EBFDD508EB244422E37C44322C +:10A40000C3ED49003F32DD465A080211DD4BA6007C +:10A41000C80D2E37EBFDE664E809EB24EBB42E27DC +:10A42000EBC54442E37C490040532E57EBFDC53D4C +:10A430002E2728422E372843924192614402E37C22 +:10A440008420E225E80BA5008C218882AD00A501BF +:10A450008C08888312407FFDD5F58400EA2AEAD172 +:10A460003E07EBF1EBDBDD40A6015A080317DD5E8A +:10A470005A080411EA8CC805DD558E04E602E90588 +:10A480002E07EBDD5A0801078404EA45D5655A0812 +:10A4900004648400EA45D5605A080A5FDD5E5A0804 +:10A4A00005F88401EA45D558EA73C8562E17EF021D +:10A4B0003E07EBC53E07EBFDEB5C3C0FFBCA5A10B9 +:10A4C00001093C0DFBC74420EA60E240E9038C012E +:10A4D000EA2A3C0DFBC84420EA60E240E90D3C2337 +:10A4E000F77E3C33F62FE262E802C1048C01EAD128 +:10A4F000D5033C1FFBC8EA8C5A08010F84203C1F7F +:10A50000FBC72E17EEF5EA495CF08032E80A8C2191 +:10A510003E17EEF5D50684203E17EBB63E17EEF556 +:10A520002E1728AC5A180119DD52A6495A100304F7 +:10A530005A180A132E17EEF65A1801093C1DFBC8CB +:10A54000E622E804C8033E07EEF68400EB17490054 +:10A550002EB68401EB17DD5A5A0802074900536CE6 +:10A56000C0038400EA2A49FFFD695A080204480032 +:10A5700000DDEA735A0801058400EA2AEAD149FF9E +:10A58000FDC74402E37C2E17EBFD4422E9E0443290 +:10A59000DAF0490056ACDD555A08120AEA728426F0 +:10A5A000EA9A5A0801058406EA4DEA63EA6E5A08F7 +:10A5B00001064402C3788424EB462E0728BB5A00C8 +:10A5C00001072E272819EAA98420D511EAA94412E7 +:10A5D000DAF03C2C01DC49FFBE3BD50BB460C3056F +:10A5E000A4C2ACC6A4C3ACC78C21EB08E222E9F735 +:10A5F000EA73C806EAA92E172BE149005C0AEAA90A +:10A6000049004A4EDD555A08120AEA728427EA9A2E +:10A610005A0801058407EA4DEA63EAA949FFE78A77 +:10A62000EA9C5A080116EBAA5A080113EB244412BB +:10A63000E9E02E27EBFD4432C474490007094900C4 +:10A6400008B25A0801064402C700490011068420D6 +:10A650003C1FFBBE2E6728193C7C00C23D0C00C38A +:10A66000EAA9808186214520FFFF453000FFE28670 +:10A67000E83AB440C22BA147383395011310000BC0 +:10A680005CF181004039BC1A1230000A0430000924 +:10A69000E2234011BC1B5A2003245A200522022029 +:10A6A000001E0230001FE262E8031220001F122089 +:10A6B000001D38281501025000201220001E4C59A0 +:10A6C00000108CA112500020D50B1220000A12207D +:10A6D000001D1220001E1220001F122000208C815D +:10A6E000EB08D5C63C1FFBBE49FFEBD9EA979E415C +:10A6F000E622E9065A00040549FFFD5BD504DD4664 +:10A700005A0802FC2E6728AC5A680112EB31C810B7 +:10A71000DD5A5A08010EDD40A6015A00060A5A0009 +:10A720000B08490033ECD50480C0D50284C18006F3 +:10A73000FCA0FC00EB9B80C0840CDD50DD44DD43BD +:10A74000AE408409441000A1DD4749FFECE88409CC +:10A75000441000A2DD47DD40A6415A100D0B2E1714 +:10A76000EF2CC9074412C3ED4422C7004900372823 +:10A770008409441000A3DD472E07EBA05A08010B03 +:10A78000DD44DD43AE408401EBE7C0FE84024800B7 +:10A79000008B8409441000A4DD474402FEF2A600A9 +:10A7A000C007DD40A6415A18030449FFCC6A84095A +:10A7B000EBB6DD472E07EBF65A08010C4402C3E660 +:10A7C000EAF4EAC93C3DFB313C4DFB2F49FFD09AEE +:10A7D000840C00130050DD47840D00130051DD4749 +:10A7E000840E00130052DD473C0DFB70C035840B16 +:10A7F00044100087DD478400EADA3C0FFB70EAF082 +:10A800005A08550EEBE8DD524422C39C3C3DFB2820 +:10A810004442C52049FFD29CEAE1D503EA39EB4521 +:10A82000DD5549FFCDA096003E07EB9A5A00033C48 +:10A830005A080213DD44DD43AE40DD54A608C0FFD4 +:10A84000DD465A0002A5DD44DD43AE408401EBE75E +:10A85000C0FE48FFFF9D8409441000A6DD47DD547B +:10A86000A6085A080206DD4CA6005A000205EBE2D3 +:10A870005A08010F8401AE08DD5BAE08DD465A00C0 +:10A8800002048400EB59DD46C80349FFF2E7DD40CE +:10A89000A6015A000B0449FFEFFF8409441000A7EA +:10A8A000DD478401FC803C0FFB8BDD9E3C0FFB8A67 +:10A8B000DD9E2E07F1598E019600EBF7C802EB9D45 +:10A8C0002E07F158DD9E841F3C0FFA578400EBF7EA +:10A8D000EB9DDD9EFC63A105402208400131000094 +:10A8E0000091000100A1000200B100038620E1A355 +:10A8F0004EF200E0A081385145014C58C0D8A10566 +:10A90000415888088895A7A0E4C3E9038EC3D502FF +:10A9100084C0A7612E2728128CA3E0A2E9029F51D0 +:10A92000A6A2E443E9038E43D5028440A7232E77F1 +:10A9300028138C83E087E9029F39E1264EF300B7A4 +:10A94000E0B34EF300B4E1624EF300B1E08A4EF39F +:10A9500000AE42634C004252A40142422C01F681F7 +:10A96000F58242212800F483F403E0824EF3009F35 +:10A97000E44485A0E90350D17FFD9D13F701F485E0 +:10A98000F402E0874EF30090EB774453F04AAF288F +:10A990003C4DFB8A80A70082000205600000425106 +:10A9A0002073385B15005A50FF7C05700001385B3E +:10A9B00095114E540076E4E484C0E9029FBB058003 +:10A9C0000005A763410C540000E8000140F7180798 +:10A9D000E9679D3B51247FFF83C44242480101281F +:10A9E0000000E092E95D00C8000340F63407E95832 +:10A9F00004FF80058EA10108000242579401E0B0D7 +:10AA0000E94F43E238013C4003A84306C000838479 +:10AA100042482024432348004252B001F4848680F7 +:10AA2000E0B0E93EF40481D288948892952140FFF9 +:10AA30003807E932386B10005A60FF2B419B982091 +:10AA400002CC800040F600114EF5002304F0800592 +:10AA500040F7900002F7800040F7801140F7F007C0 +:10AA6000E917442F800040260804122C8000406C17 +:10AA70001840A6B043398801A6B142948800A6B216 +:10AA800042A50801A6B342B5880048FFFF3150E750 +:10AA900000018C82D5CD8D81414A2000D5C28CE148 +:10AAA00048FFFF708C4148FFFF618DA148FFFF21E7 +:10AAB000FCE3FC20A612C0038E01AE123C7DFB8A93 +:10AAC000A753A63B8E01D0038CA1AF53A610C003A1 +:10AAD0008E01AE10A63AA7518E01D0038CA1AF51C2 +:10AAE0008400A750011100018060E3A5E922A7922C +:10AAF00001210003E3C6E91BA73A81E542F3107385 +:10AB00000500800540483C20EB8641080011E59A8D +:10AB1000E90CEB8602F200004108001140F78011B9 +:10AB2000E06F8810E802A4E08CC1D5E58CA1D5DEE9 +:10AB3000C306441001F4FE0C40000C17FCA0FC629C +:10AB400080E0841F3C0FFA573C0DFB8BF181A6433C +:10AB500081625CF08042E90444100041AE43A640AB +:10AB60005CF08042E90444100041AE40A683A60098 +:10AB7000441003E8FE8C00658000FE444081001311 +:10AB800040908013C63C84203C0DFA5780A1E0A67B +:10AB9000E80FA0B938211501DA09A0BA382115014A +:10ABA000E2224002BC1B40113C1B8CA1D5F13C1B96 +:10ABB000F618A07D3C0FFA57EA4EEB6AB0433A0014 +:10ABC0008020006F800C004F800D001F800F983494 +:10ABD000900140A00010000F800E8C218A2044308C +:10ABE00000648C819649FE5C9BA697B1406098D624 +:10ABF0008007F101B08397B1F880D503855F8006A7 +:10AC000050157FFC9648E638E90A4EA500095CF32A +:10AC10000079E90544907D0044806978E3203EA7EF +:10AC2000EC16E9102E17F1585A180109001580008A +:10AC3000C1053C13F618E63FE8052E17EC175A1825 +:10AC4000010684003E07EC17D55CE300E90384208D +:10AC5000D56D3C6DFA57442F80008400FEB7003557 +:10AC60008000E003E808A079EBACA548DE02AC88E0 +:10AC70008C01D5F68007F10196B049FFFE2DA03D6D +:10AC8000401018403A108400B0833A110420003577 +:10AC900080008C038420E023E82DA0B93851050101 +:10ACA00096AB4E2400255452FFFFD621D920002018 +:10ACB0007FFD004F800CE282E903102F800C002002 +:10ACC0007FFE004F800DE244E903102F800D00202D +:10ACD0007FFF004F800EE282E903102F800EA680D6 +:10ACE000004F800FE244E903102F800F8C218C0469 +:10ACF000D5D38007F101B08349FFFEDDE320E809E9 +:10AD00008401EB9D3C0DFB8B8421A601EBF7D50E56 +:10AD1000840000158000E001E89BA079EBACA488DA +:10AD20008C0154217FFFAC88D5F52E07F159C00B5B +:10AD30005A1801053E17F158D5068E019600EBF71B +:10AD4000C802EB9D2E07F1585A0801058420101502 +:10AD50008000FCE2FC002E17EF1080022E273082CC +:10AD60005A1801073C13F8CCC103442000782E1771 +:10AD7000EF2C5A180103A6843C0C01DC4412DAF0D3 +:10AD80004432C3D58480EAFBFC80DD402E4728CEC8 +:10AD9000A6015A0006049721D5032E4728D02E0776 +:10ADA000EBE82E2728D5E202E8068C013C43946BA1 +:10ADB0003E07EBE82E27EBCC2E0728D42E3728CDE4 +:10ADC000E240E92F2E07EBCD5A080130FC2040006D +:10ADD0000C0C8A04960184E0EB30E2E2E821A18ABF +:10ADE000B44194F988C388430303000004508014DD +:10ADF000A49088A3FEA4A4E8422040738CE1884379 +:10AE00002E3728CD40310C0D96D9ACF0A4F02E672A +:10AE100028CD4031980C8A439691ACA8D5DEFCA091 +:10AE20008C413E27EBCCDD9EDD9E2E1728B75A10B5 +:10AE300001048401DD9EEBEFC84144326EB880808E +:10AE40003C139422E201E81FEBB4EBACA4883C1362 +:10AE5000946E9693FE4AE041E8119883A6508C21A7 +:10AE60009648AE50A6903C139469E241E9093C1320 +:10AE7000F61B8C213C1BF61BD5039843AF088C01B5 +:10AE80009601D5DF3C03F61B3C13946FE220E8D219 +:10AE900084203C1BF61B840044326EB8EB30E20287 +:10AEA000E80698838C01AE509601D5F92E07EF3055 +:10AEB0008C013E07EF308402DD9E84003C0BF61BC4 +:10AEC0008001DD9EFC204440271080C0FE642200EB +:10AED000002840208856FE24221300502233000010 +:10AEE000EACBE022E85140F00DF6E04FE84F445045 +:10AEF0000078FA788024991D4002040A5CF0005121 +:10AF0000E904524000A0D50480805A002805527000 +:10AF10000078D503447000503843111138731D1167 +:10AF2000FF0C40421C96E044E8039F41D504E082B8 +:10AF3000E8309CC1E0A3E8E04C01800380A35CF210 +:10AF40008051E904521280A0D502802550728028D9 +:10AF50005CF38051E9035272807838130511443054 +:10AF60002710FECC38131D118A82403184769A9ABC +:10AF700042420003EB50E082E90CE044E909E205BB +:10AF80004002BC1AFCA0FA18FCA0EAC3FCA0800591 +:10AF9000FCA05CF00051E905523000A0B661D5027A +:10AFA000B60150107FD85CF08051E905520000C80E +:10AFB000B602DD9EB622DD9E3C0FFC57DD9E4402AC +:10AFC000EE548420AE42AE43AE46AE47DD9EFC6DED +:10AFD0008140440189503B0044004607FFFF84C084 +:10AFE00051CF806050000FFF3B0E44208121F2873B +:10AFF000F68F81A680A6510F805845E000564590F7 +:10B000000064F08DA618E2A04EF20108040480014D +:10B01000380015014C02C0FF0404800540001440B4 +:10B02000A640F181A68200E0000301400001F0018A +:10B03000401708018A148801EB3BE4034EF200EB51 +:10B0400045507FFF40F708064EF300E5F70140FA50 +:10B050001C064EF300DD2F372812B409F08242019E +:10B060004C24F4029847944941220400011900013C +:10B0700054F880044EF300C9044480010119000013 +:10B08000F48338B245014CB2C0C0882A23608000E6 +:10B090004F6700BBC20B51117FFF80874248CC73C2 +:10B0A0003915110113180000D50313580000C70B00 +:10B0B000822743114C73F40D89A4391545011318E7 +:10B0C0000001D5031358000150F9FFFFE2EFE80635 +:10B0D0000310800113180002D503135800022F1724 +:10B0E00028138FA1E251E8094113CC0088113805DB +:10B0F000010112080003D503135800039F39420BC6 +:10B100007824F4899D11F48A9D3940006416F48BEB +:10B110009F11F08854B580FF8400F48C391E010023 +:10B1200004CF800838484511F484E08CE866411E5D +:10B1300000200118800138484511F485E08CE85D55 +:10B140005A00020E5A00030F5A00010504CF80096D +:10B15000D50304CF800B048F800CD50804CF800961 +:10B16000D50304CF800B048F800A822C43144C73C8 +:10B17000F40241188408889101220001F4865529BF +:10B180000004552900FF4F23003989AA2388800035 +:10B19000F404437C7824417BE6F6E097E82EF4053E +:10B1A000E097E82BF40600F20000F40338F23D00CB +:10B1B0004CB7C02440FC5807B010E90C387019098E +:10B1C000B01238201909F80B3960190913208000D2 +:10B1D000D50F38C01909B01238801909B00F38B02E +:10B1E0001808B01483FF3980190913288000E6C4B9 +:10B1F000E8088CC197B0D5058C015A080491D50494 +:10B20000804E80F485A18CE148FFFF238C4148FFEC +:10B21000FF1B8CA148FFFEF85AD001044800007FB4 +:10B22000808DF207800A8029EAFB84404717FFFFE0 +:10B2300080E2808250CF804850DF8040508F805025 +:10B2400051188FFF85C2E286E864380691013856AE +:10B2500011012E17281280604232847382C080232D +:10B2600038341101383505092F2728129E694360AB +:10B27000C873826580628560441000FF515280016E +:10B2800051707FFF518000015029FFFF40FA88066E +:10B29000E9294025D800860041414400402BC000E8 +:10B2A00040FC0806E91C04F48000402A40004027C6 +:10B2B000882000F100015AF8021101910000B08FBE +:10B2C00038F110004CFCC0058CE197F8D5065A18EF +:10B2D000FF0380399C9996D08D81D5E18DE18972EB +:10B2E000D5D4804380604232C873B58940380C2081 +:10B2F00010E18001EB57E2E242028C73B469400135 +:10B300008020E904B04F38109000AE408C81D59C6D +:10B3100084013E07EF388401FCED2E07EEEC5A085D +:10B3200001192E4729A44422018C84204450007323 +:10B33000E224E80AA6108C218C0A9600420014012F +:10B3400018010001D5F6800A8029F2078481EAFB02 +:10B350008400FCEDFC20848080C0A7D0800480A401 +:10B360004502C950E2A7E816A0F1383195014C32E8 +:10B37000C0100513000296E83918950138381008F6 +:10B380008C81E7A697204001BC1AE68CE8038CA1CB +:10B39000D5EA2E57EEEBA0F2E6A238018101E90FC3 +:10B3A000E683E80D8C81DC0B8E06E612E8088062ED +:10B3B00080013C2003A8802649FFFE0BFCA0FC0175 +:10B3C000F081F80740000009F0019E41F181C8FBBF +:10B3D000DD43DD44AE4083FFFC81FC02F081F001DF +:10B3E000441003E8FE0C50107C5E4603A19650000A +:10B3F0000B1F4200806940009409F083F001C802ED +:10B40000D509EA2DF0039E41F183C8FCDD43DD44FC +:10B41000AE40FC82FC02F0818400F083D50ADD435B +:10B42000DD44AE40440003E8EA41F0038C01F083C0 +:10B43000F103F001E220E9F4FC823C0FFC5FDD9EA9 +:10B440003C0FFC5EDD9E3C0FFC5DDD9EFC4084E01D +:10B450003C2DFC5F80C1808780A7862504F3000017 +:10B46000E81250F7FFFC5CF78002E90D05230007A6 +:10B470000500000238F8490101210006E3CFE80386 +:10B4800011118002B58651287FFFE7C2E9035B08EE +:10B4900004058C81972080E58CA197685063004C4F +:10B4A0005A580ADE2F17F193CC0684008420AE1A76 +:10B4B00080A1D51FA61A5A00051B5A48011450082E +:10B4C000FFFFE602E8042E57F192DFF04400004C43 +:10B4D0004213807384012250800422108005AE1A2A +:10B4E000D50884038420AE1A80A1D503842080A1CE +:10B4F000A61A5A0801263C6DFC5DA7B35A680121C3 +:10B500003D2DFC5E0269000951337FFF0269000294 +:10B5100050937FFF84C241099A164302A473405896 +:10B520004CB70309000A032900038F818FC14068CB +:10B5300018D64260C873976B40134037964BE7A507 +:10B54000E81844F0B3503917C40040F8BC00DD0FD0 +:10B55000060C0C161C005A08010BD5105A00010CE1 +:10B56000C80C8403D50BE602E808D503C806D50647 +:10B570008400D5048402D5028404EB838E01E604A2 +:10B5800084C04EF2008D44F0B394EBAF40F03C0029 +:10B590004A003C0008003400500002018400446F5F +:10B5A000FFAA3C0BF8C83E67E9603C5BF8C63C1B51 +:10B5B000F8C73C5BF8C43C1BF8C53E07F1863E77F4 +:10B5C000F1923E07F184D56D2E07F1860261001AD3 +:10B5D000E206E8048C013E07F1863C5BF8C43C1BA4 +:10B5E000F8C5D55F2E07F1875A0801262E17F18678 +:10B5F0000201001AE220E81F2E17F1850201001B4C +:10B60000E220E8192E07F184C8163CF7F8C03C0781 +:10B61000F8C4021100198A0FEB3BE001E80C3CF77B +:10B62000F8C13C07F8C58A0FEB3BE001E80484034E +:10B630003E07E9602E17E96084003E07F1855A1045 +:10B6400003313E07F1872E07F184C82B3C07F8C56C +:10B650000211001EE001E91D0211001FE020E9199E +:10B660003C17F8C40251001CE025E9130251001DEB +:10B67000E0A1E90F2E67F1860251001AE2C5E81138 +:10B6800084A13E57F1873C1BF8C03C0BF8C1D5099B +:10B690008402AE1AD5063E67F187D5033E67F19363 +:10B6A00084003E07F1943C03F8C8CC052E17EF1236 +:10B6B0005A180110A454E201E8058C013C0BF8C8AB +:10B6C000D52184013E07F1948404AE1AEB83D51A88 +:10B6D0002E17F1875A18010E2E17F1850251001B03 +:10B6E000E225E8058C213E17F185D5033E47F18719 +:10B6F000A454E201E904EA383E07E96084003C0B07 +:10B70000F8C82E27E9605CF10020E81F8C4C969069 +:10B710008401E65EAE18AE998401E904FA2EF803BE +:10B72000D504802249004A8B8403EB628400EB83BA +:10B73000EA383E07E96044000060DD412E07F17001 +:10B740008C013E07F170D5038400AE183C0DFC5F00 +:10B750003C1DFBC7A404E220E90484003E07EF2C53 +:10B76000FCC0FC0084004412C474442FFFAAAE083D +:10B77000AE0AAE8984203E27E960EB833C1BF8C803 +:10B780003E17F1943E07F1873E07F1863E07F185AB +:10B790003E07F1923E07F184FC803C0DFC5FA4045F +:10B7A000DD9E2E07F194DD9E2E1728198400443269 +:10B7B000000084819680E241E8069883104103EC02 +:10B7C0008C01D5F9EA89B400EA465A080107440019 +:10B7D00000B43C0B9605DD9EEAC33C0B9605DD9E4E +:10B7E0003C1394FCAC40DD9EFC60A612C0038E01AD +:10B7F000AE12A6135A0031048C01AE13A610C0037A +:10B800008E01AE10A6115A001F048C01AE110091DA +:10B8100000010131000301010000A69250348001B3 +:10B82000507980018A708AE284C096D897F842B332 +:10B830008C24823080868006E331E9218242E3F263 +:10B84000E91C04A080054058C8A040551420F80900 +:10B850005EF78024E91002A2800040A50011888ACA +:10B8600002A2800040F5001183FFE00FE802A42847 +:10B870008CC197B18DC1D5E48DA1D5DFC0064450F0 +:10B8800001F4FF2C4042009744500064FFAC40F3A9 +:10B890002DF65EF78026E838E669E936E6E9E93410 +:10B8A000EAF8E603E831DD4BA600C82E5CF21F4142 +:10B8B000E92B88534004C00090414030040A94159D +:10B8C000A10D9858F8059C59F8029E5988204012FD +:10B8D0000420A448964B5EF08023E81683FF5010A6 +:10B8E000002088234E00FFF550107FE09819400299 +:10B8F0000020A40096035EF00023E806EB33C804A2 +:10B9000084013E07EC17FCE03C0FFB8DDD9EFC63E1 +:10B910008180EAF8816180C25A0801122E07EBC5C6 +:10B920005A08020E3C0C00C480200910800200D08E +:10B93000000100E0800100900002D506449000FF65 +:10B94000822981C981A984002E1729A444320000CC +:10B9500080809680E241E80698831041018C8C013A +:10B96000D5F9FA53503F80138480040600058026E1 +:10B97000B7BFEAFB8460005F80138263810380832A +:10B980008243804384FFB5BF9618E205E81E050395 +:10B990000001965939080D0194194D00C015A07287 +:10B9A00038108D01E241E80BA0B480E38802012049 +:10B9B0000001A700A03380410330000050040001C3 +:10B9C000548000FF8C61D5E18400151F80033E0781 +:10B9D000EC175A7FFF044800011EA03540A38808D9 +:10B9E000153F8002F481B7DF880AEB6AB0453A0060 +:10B9F0008020B0858006802C49FFFEF8A036B5DF98 +:10BA000038301E02A037F40138501E02040300082B +:10BA1000053F800238001E02051F8003C00E3C2D2A +:10BA2000FB8D00110032FECC001100334101821762 +:10BA3000FF4C405280B7D50380A08200A0B5884A51 +:10BA4000A61000A1000240F68006A6D3A651E91C6C +:10BA5000E22DE91AE3AAE918E271E91640F70006B7 +:10BA6000E913E22EE911E32AE90FE269E90D5CF935 +:10BA700080C9E90A2E07F19D5CF000C8E80D8C0131 +:10BA80003E07F19DD50984003E07F19D5CF9807861 +:10BA9000E90C5A77FF0B2E07F19C5CF000C8E80513 +:10BAA0008C013E07F19CD50984003E07F19C841F60 +:10BAB0003E07F19B3E07F19A2E07F19C5A08010DB3 +:10BAC0005CF2002EE90950197FFCE639E8053F27B2 +:10BAD000F19B3E47F19A2E17F19B5A10FF1F2E271C +:10BAE000F19A5A20FF1BE614E8188A44EB50E4420E +:10BAF000E914000F8013E602E910DD4BA6C0CB0D60 +:10BB0000EB655A18010B440001E0E7053C0BF8CF48 +:10BB100010158000E84DD5093C03F8CCC008E705B6 +:10BB2000E8038E01D50284003C0BF8CC5A7FFF0558 +:10BB300084008060D536A0B540711C4084C0A6BA90 +:10BB4000012380033C1DFB8D80068066E3C2E91E55 +:10BB5000A73801338001E3E4E91701108002812452 +:10BB6000429144738229049600054114C42002F8CE +:10BB7000800040F780115EF78023E9048864880222 +:10BB80008CC18C81D5E98C41D5E2C6D3004080328E +:10BB900000208033FF1CFE844032187740011817C4 +:10BBA000001580005A10010844100050D5055A7F36 +:10BBB000FFC48003EA702E27F19DE646E905442381 +:10BBC0008D40A690C20C40380C0142F18003E22F58 +:10BBD000E9069A2842F00003E22FE80D440001E054 +:10BBE0003C0BF8CF8401EADD2E1729A4440201A4FE +:10BBF00084A0D5083C03F8CFC0F78E013C0BF8CFEA +:10BC0000D5F4D10E082000018CA110207FE79768A1 +:10BC1000D5F984A03E07F19D820548FFFF39FCE37A +:10BC2000FC0080C0A046A0058444846F848584A065 +:10BC300049FFE400A036A075EA48FC80FC002E57BE +:10BC400028C05A5001048401FC803C3DFB23A6D946 +:10BC50005A3009045A3804193C33947D994BE22335 +:10BC60009769E8049A599649D50284202E47EBC07B +:10BC7000A0C2A003403190774000101796D99601DA +:10BC80002E472907D51B44338D40A718CCDD3C3304 +:10BC9000947C994BE2239769E8049A599649D50216 +:10BCA00080242E67EBA4B460A00140319877400057 +:10BCB00018172E47290696D9960144F002004252E1 +:10BCC000BC01E2A3E805A6108C01AE10D505E20187 +:10BCD000E9FB8400AE10DD40A6015A08040484008C +:10BCE000AE10A610E280E8B08400AE102E07EF314F +:10BCF0008C013E07EF318402FC80FC20050080139C +:10BD0000006F8018011F801C55087FFFCA0F8381B8 +:10BD1000BE1244220168B913EA65406118405420FC +:10BD2000FFFFA6749648CB16D52444720000410349 +:10BD3000C04045200064E2D1E8EB80F042734873D4 +:10BD400051338064182380014C79FFFE8CC197B079 +:10BD5000D5F344600064FE7440108840446200647F +:10BD60004422000088418826183100014C20FFFE43 +:10BD7000AD00AD41FCA0FC20F6085A60010B446206 +:10BD8000DFB4387304004462DA6039130400D50369 +:10BD9000862284E98380B912450200005460FFFFC7 +:10BDA000FA38FE7CBF14401098404063C0095473B9 +:10BDB0007FFF4460006088304268982440631C40E4 +:10BDC000A7CFAFD8A6CEAEE0A6CCAEE802400030FA +:10BDD0000230800D020000300210800C886488015F +:10BDE000F406F1074008002088D040380C20B664E3 +:10BDF000B601B406920A9637AE10FCA0FC408380D0 +:10BE0000BD14B814446000485452FFFFEA4CFEF4DD +:10BE1000FF3440420040403194404452000088A426 +:10BE200084008A6438619400386081090862800166 +:10BE3000386101098C015A0832F7440200348880C5 +:10BE400084A0852339319002411094000D22000115 +:10BE50004101140084E04203A42402A88000406948 +:10BE6000800D9797406519001A6880014009000D00 +:10BE7000026800009617400301008CE11A080001D7 +:10BE80005A780AEB8CB45A5864DFFCC004000013E3 +:10BE9000EB19FEE4EA4C4001804044320000886027 +:10BEA00084009908A7613840800040424008404221 +:10BEB00017009950A76940421500385100008C02C4 +:10BEC0008885AB195A0832EFDD9E04000013EB1988 +:10BED000EA4CFEE440318040EA9D88608400A51968 +:10BEE00038408008A75B9908AF61B48338410008E7 +:10BEF000A319995092888C02AF295A0832F2DD9E1C +:10BF00004412DFB4380080008E015C000009DD9E21 +:10BF1000E201E80AA610E260E8049AC3AED0DD9E12 +:10BF20008400AE10DD9EE220E80BA61052F180FFE7 +:10BF3000E00FE8048860AED0DD9E841FAE10DD9E69 +:10BF4000FC60EEA8F0858141F28480E35A38010557 +:10BF50003C800B47D506F9154E0200A43C800B46E9 +:10BF60002E07EC1984C1E602E9058E014063000C3E +:10BF700097B04063280E97B0CE0284C1B00A50BF7C +:10BF80008024505F8021F081F105F004B088503F9B +:10BF90008022504F8023B77FF78249FFFEEEF004E6 +:10BFA000B064B0BD003F8022004F802349FFFF28CE +:10BFB000F86F49FFFF8CB0248120B00B838085800F +:10BFC00044D000323855B20244006510992844002C +:10BFD00073E840E2800042063424F08584E03904AE +:10BFE0009D015CF807FFE8492E17EC1A3932C101B0 +:10BFF000003F80208E214028040840098C164CA068 +:10C00000C0158844A4508A0840308C768A68EB4B6F +:10C0100042F00003E06FE90413310000D52E380729 +:10C020004101380E1C08D5294EA3000639324109BA +:10C03000F810D5168844A45040308C76401020016A +:10C040008A68EB4B42F08003E06FE90A133100008D +:10C0500038149D01382E1C003827050983FFF1058F +:10C06000B0CB98B98843960180288066F487F5861E +:10C0700049FFFF50F407F5068CE15A7832B250942C +:10C08000806451CE00325AC001048581D59CF004F1 +:10C09000B04B502F805E003F802183FF49FFFEF8A8 +:10C0A000ED58FCE0FC61F0818401B63F814280C321 +:10C0B000EA7DDD465A0002048400EA5BDD54840117 +:10C0C000AE08DD5BAE0884003C0FFB7C2E07EF372B +:10C0D0005A08010684073E07EC19D50C5A68010777 +:10C0E0002E0729013E07EC19D5052E0729003E072A +:10C0F000EC192E07EC198C013E07EC1A4400006085 +:10C10000DD50DD465A08024C5A6801074413F423F7 +:10C11000EA36EA31D50B440000618520DD508169A3 +:10C1200044C3F04AEB9C85A1D510A6085A0002F53D +:10C13000AED0D5FC3C0DFB7CC81CE9FD5004800151 +:10C14000EAE7DD4C10D000002E07EC1AE320E8658A +:10C150003CBFFB7E108600005A600107440000626D +:10C16000DD5084E0D5188006EA25EA9EC0FFD5F7A9 +:10C170003CBFFB7CCE12EA5A8E0154E000FF800ED9 +:10C1800049FFFEC0C008800E8029B45F80668CE144 +:10C19000F82D97F8E2EAD5D28007D5F746B000F43B +:10C1A00084E044C3F04AEB9C85A150B582402E0741 +:10C1B000EC1AE2E0E83210860000F8BF44000061AB +:10C1C000DD505A680105F001EBAED506DD40842054 +:10C1D000DD57490029C944000062DD5085204C9597 +:10C1E000000D80098027B45F806649FFFEAB505484 +:10C1F0008001549280FFD5F4DD4C8CE1549380FF94 +:10C2000010D000005A6801062E77EC1A4C93BFD16B +:10C21000800BEB4F80E9D5CC8400EA7D8400FCE103 +:10C22000FC212E07EF37C8063C2394813C339482CF +:10C23000D503EA8780432E07283F84C0EA5E3C434B +:10C24000947C3C53947DF08196904402EE7C96D889 +:10C25000B6DF49FFFD54DD4680E0EA5EDD405A78F6 +:10C26000021B84488066F8255A0801053E07EF0244 +:10C27000D549DD408425AE4184213E17EEA33E77AB +:10C28000EEEAEA3A8441DD40EA5E8062F8123E67F7 +:10C29000EEA3D5182E27283F8066F80BDD408429B1 +:10C2A000AE413E67EF2CEA3A8441EA5EDD408062AF +:10C2B00049FFFEFADD40842AAE4184213E17EF2C6F +:10C2C000EA3A84013E07EBA984033E07EEEA8407BD +:10C2D000DD508400EB5EDD465A080206DD40842D09 +:10C2E000AE41D50BDD408420DD572E17EBEBDD4052 +:10C2F0005A180203842AAE41DD40EA3A4400006F36 +:10C30000DD50FCA1FC00DD465A0802158400EB6BF1 +:10C310008401EA7DDD43DD44AE40DD59A640C9FF1E +:10C32000A6405A1801FFDD4C8422AE408400EA7D0D +:10C33000D50BEBF4EBDCEB4F49FFE58CDD408420C3 +:10C34000DD574900291144000065DD50DD42C00D74 +:10C35000DD44DD43AE4049FFB55EC0FEEAB0EB42CE +:10C36000FA50EB0349FFDFD5FC80FC2444218958B7 +:10C37000EBB544418968B084EBF83B024C003B01CB +:10C380004C20390102024421D80040210040A790EE +:10C3900080E197B0381F82028480451365104522E2 +:10C3A0006238EB30E282E81994E14021C4000331A5 +:10C3B00000004021C800994BA490383810008C81AF +:10C3C000FE9CA4E84021180E8A53969340211C56E7 +:10C3D0008843ACA89721D5E644200C804431A200C4 +:10C3E00042300873800349FFB056FCA4FC6184C04E +:10C3F0008401EAD83E67EBB68126EA7D80E68504B3 +:10C4000085A644E38D405A78040B8400DD528040B9 +:10C41000EA4B3ED7EEEA8581EA93D50B80073E874B +:10C42000EEEAF8198180DD5284038047EA4BEA93F3 +:10C43000DD4C8421AE409E39854054B000FF4CA6AF +:10C44000002FDD59A640C9FFDD42C00EE2C9E80C4D +:10C45000C70B800B490022E3F0818CC1800BF101F6 +:10C4600097B049FFFF8400170000DD595A180311E7 +:10C47000A6405A1801FFDD42C007EA305A0807FFFC +:10C48000EAB0EAB7EA4850048001EAE7D504A640DA +:10C490005A1801FF50050001EBDFD5D28CE197F867 +:10C4A0005A7805B38400EA7D8400FCE1FC45442110 +:10C4B000897844720000EBB5B042442189883B0082 +:10C4C000CC20EBB5A6BA81208400B186EA5538109D +:10C4D000A602EB25A6FB92413B034C20EBD6EB25B5 +:10C4E00038132602A6BAA6FBEBD6FCC53C0FFB8E82 +:10C4F000DD9E3C0FFB90DD9EFC008420DD57DD546B +:10C500008400AE08DD5BAE088401EA258401844026 +:10C51000842A8080806280A2DD56DD44DD43AE4007 +:10C52000EA9EC8043C0DFB7BC0FCDD42C0168401C2 +:10C53000DD4ADD44DD43AE4049FFB46DC0FE8402F8 +:10C54000DD4ADD465A000214EA21EA8AAE0880413B +:10C5500084618402DD45D50BDD465A000209DD44C5 +:10C56000DD43AE40EA21A6085A0832FFDD465A08EC +:10C5700002072E07EBAF8C013E07EBAFFC80FC20DF +:10C5800080A03C0DFB8E3C4C01E3A68394E9E2A223 +:10C59000E825F87BE906A4309783982AF87FF864A9 +:10C5A0009222CD0DA421F83140220820A410960338 +:10C5B000E0204EF200C98401EA49FCA09E1A8804DA +:10C5C000A400964996039F91E020DE04E9F5884592 +:10C5D000F835F82CF81B8845F8318403FE14E2A0E6 +:10C5E000E93599E3A5B897B3E026E90CA5B897F328 +:10C5F0009BAA40621820A5B097B388C7E0264EF2E8 +:10C6000000A39222D808F81396499603E020E9D4B3 +:10C6100083FFF8139E1A8804A40095929603964906 +:10C620008EC1E020DE03E9C8F808E9C68C628864A0 +:10C63000A41883FF4E00FFEB9AAA40220820A41002 +:10C640009603E020E9B9FCA083FFD2039591DE199F +:10C65000F81CE910F82096038807E020E90BA430C5 +:10C660009783982AF81B96038806E0204EF2006C08 +:10C6700083FF8C62F825F811F826F82EF824FCA028 +:10C680008EC1D6038E01D83099A3A4309603E02042 +:10C6900083FFE915A43097C39A2A40020020A40022 +:10C6A00083FF96038807E020E90AA4309783982A3D +:10C6B0004E00FFF596038806E020E8458E62886408 +:10C6C000A41892229603E0204EF3FF7783FF4E00DA +:10C6D000FFE54E00FFF9884540220820A41083FFA3 +:10C6E0004E00FFF2FCA09F9A982341221800A4005C +:10C6F000026900008C624103001188649BAA40F02B +:10C700000011A5D841121820982A02688000402202 +:10C71000002097FB4007C000A51097B38807972318 +:10C72000880688049D0DE080E80E020900004E0096 +:10C73000FFCAA4184E00FFC8020880004E00FFC4C4 +:10C7400048FFFF36FCA02E17EB92C1092E272C9232 +:10C75000E241E9048E219648D50284204422ED0C62 +:10C7600038310501E260E92BFC208400380105091D +:10C77000EAF6842084A33C3C01E13C0C01E23C4C01 +:10C7800001EA9489886288028881A598A5C0A620BC +:10C79000880742031473404008099721AD183C4CA8 +:10C7A00001E13C3C01EA8844A490886140000841D2 +:10C7B00096008C21AE185A18C8E0FCA0DD9EFC0043 +:10C7C0005A0801122E1011D12E0011D05A1801044E +:10C7D0008E03D5028E02960084408020806249003C +:10C7E0000885FC8049000894FC80A641EA7C5A1820 +:10C7F00004112E17EB9FC903A602D502A6032E171C +:10C80000EBFB5A180208E604E9058E039600DD9E4C +:10C81000A604DD9E540000FD5A0804053C03F8D12F +:10C82000DD9EEA7C02000009DD9E5A0804053C03F7 +:10C83000F8D0DD9EEA7C0200000ADD9EEA7CA400BE +:10C84000DD9EB400EA7CA447020000083C1BF8D13E +:10C850003C0BF8D0DD9E2E17EB97C90984423E179A +:10C86000E9383E27EBD13E17EBB6EA51DD9EFC00DE +:10C87000DD44DD43AE403C0DFB7BC810EA6E5A0838 +:10C8800001064402C42C49FFDC0B84018440802053 +:10C890008062808080A2DD56D5EF8406DD4ADD42CD +:10C8A000C01CEA21EA36EA31A6085A003204AED0AA +:10C8B000D5FCEA40EA28EA305A000704AE88D5FCE5 +:10C8C0004412C52C840280418461DD45EBAAC0037B +:10C8D000840AD5028409EA3CEA6644100033AE407B +:10C8E0002E07ED3CC81149FFBD325A00A10EDD42B2 +:10C8F0008020C807840280418061848380A1DD5646 +:10C9000049FFE286FC80840E49FFDB1EFC80FC00B0 +:10C91000DD465A0802074403F422A600961FFC8055 +:10C920008400FC80FC2084003C0BF633DD40842333 +:10C930003C7DFB2284C1AE41EB43EA3ADD4BA600CD +:10C94000842397F84900146D3C7FFB22EB91C80AC1 +:10C950002E07EBD8C8078409DD4A3E67EBE93E673E +:10C96000EBA9DD40EA3ADD5484003E07EBD88401B0 +:10C97000AE08DD5BAE08DD5E5A0004048405EA45BE +:10C980002E07EBF18420C8093C1DFB90A448E62249 +:10C99000E9038E22D50280203C1FFBC7EBEC5A181E +:10C9A000020FC8093C1DFB90A448E62AE905500087 +:10C9B000FFF6D5028400EA2AFA18EA9984013E07B4 +:10C9C000EBF38400EAC7FCA0FC0084C03C6FFB6072 +:10C9D000EAD8EB95EB883E07EB928401EA25DD5916 +:10C9E000AF80EB95FC80FC00DD40A601EB295A08E6 +:10C9F0000911DD5E5A0004048405EA452E07EBF1B7 +:10CA0000C808F803E602E90549FFF6C98E02D50217 +:10CA10008400EA2AF81849FFE202DD408429AE4189 +:10CA20008420DD57DD40842AAE41EA3A4900259C46 +:10CA300084008421EA323E17EF2CEAC749FFF693BF +:10CA40004900484849FFE1F9FC80EA7C3C3C01E3AD +:10CA5000A503842084019899A4909693E082E8022B +:10CA600084008C225A1990F9DD9EFC202E17EBD100 +:10CA70005A18020B2E17E938C9072E17EBF98E2228 +:10CA80005C108001D50284203C6DFB8E3C4DFA5930 +:10CA90003C7C01E284A08461864353300000A6B34D +:10CAA0005113800251017FFF4C58001D41010408C1 +:10CAB0008F814C580018430148248F814C58001333 +:10CAC00094928E41D20FA4B8027880008A47969340 +:10CAD000E00238221509E903E053E8045A1801037B +:10CAE00084628CA180F15A58C7DC5A18011C40108E +:10CAF00004098440FF4A38720911E027E807A63389 +:10CB0000880238F20111E02FE909E0E5E808A633D0 +:10CB1000880238020111E005E80284628C415A283B +:10CB200095EC8003FCA084204422ED0C380105091B +:10CB30008C215A1808FDDD9EFC4080E0A60080C2D2 +:10CB40005A08051E8401AE38DD4085203C9BF774F1 +:10CB5000A601EAF1F8153C13F632E62AE8058C2125 +:10CB60003C1BF632D5133C9BF632A430E619E804A0 +:10CB7000EA538400F8058400AC30D508840049FFEE +:10CB8000FFD48400AC303C0BF632FCC0FC01DD402D +:10CB9000A601EAF1F081F1014402C3E94422C44450 +:10CBA00049FFFFCC2E17EBF98400EA9B3E07EBBB55 +:10CBB000C9033E07EBBD84003E07EB92EA38EA8BDF +:10CBC000FC81FC20FD30EB8880A0A630AF70C50949 +:10CBD0002E172C9284C0E225E9059FA997B0D502B3 +:10CBE00080C5D01DDD465A08021B3C3DFB8E8400EB +:10CBF000A65B9449E001E80D8387BA09BC0B944118 +:10CC000088418824A4488C019649AC509600D5F1FF +:10CC10003C03F614C00E8E01EA9BD50B4402ED0CCA +:10CC2000385019014410FFFFD1048CA13850190964 +:10CC30002E17EBBD4000980E9604C81B0513800A02 +:10CC4000050380090453800B40380000A498404835 +:10CC500080009691ACA0A498992896918C02ACA0E3 +:10CC60005A0990F484014060180CFE773E17EBBD22 +:10CC7000FCA0FC002E272C92441000FF4020880CC2 +:10CC80004413F422A648FE93965F9690C1038E212A +:10CC90009648A78084A14042840CFF37972296E0F3 +:10CCA000AEC04C61800D4C31000B88254052840C85 +:10CCB000FF679768FF5D5C028001FC808005FC8057 +:10CCC000FC008400EA9BEAF6EA49DD40A6015A0826 +:10CCD0000423DD5EC8094402C3AD49FFFFCC5A08F6 +:10CCE00001048403EA45DD5E5A08031F4402DB3475 +:10CCF000842044200320EA332E07EBFFC807EA7E96 +:10CD0000A600962EC8038404D50A8401EA4584004F +:10CD1000EB4DD50A2E07E938C8048402EA45D5044C +:10CD20002E07EBFFD5F0DD5E5A08020584003E07B2 +:10CD3000EC1B840080804452E4983C3C01E0944128 +:10CD40008861A4D83C2C01E296D98841ACD03C2C17 +:10CD500001E13C3C01E288418823A4489649AC505B +:10CD60003C1C01EA8820AF08384280088C015A0830 +:10CD7000C8E6FC80FC208407DD4A84C0DD403E67B5 +:10CD8000EEA3EA3ADD4C84213E67EBAFAE4084006F +:10CD90003C0FFB72EA92EABC3C2DFB72CA0984018B +:10CDA000AFF080208062808080A2DD56D5F6DD4421 +:10CDB000DD43AE40EA9EC80B3C2DFB7BCA088401D4 +:10CDC00084278062808080A2DD56D5F58421DD40F5 +:10CDD000DD57DD42EA40EA28C00E8400EA90AE88C2 +:10CDE0003C2DFB22CA26840180208062808080A2A4 +:10CDF000DD56D5F7AE882E07EBC6C0098401844006 +:10CE000080208062808080A2DD56D5F649FFE32530 +:10CE1000EACE5A0803048402D5028401EA9044123F +:10CE2000C47884013E07EBC6804184028461DD45FD +:10CE30008408DD4ADD40EA3AFCA0FC4084E381211D +:10CE400042709C2484203E17EBB640A0080890E373 +:10CE500084C0E0CAE8153C2C01E340211820A490CE +:10CE60009693E0E2E80A8006802949FFFB8AEAB14E +:10CE7000C0043E67EE3CFCC08CC197B0D5EBFCC053 +:10CE8000FC60812180E04412DF4C4402C38249FFF0 +:10CE9000FE9A4400FFFF84A03C1DFB908049A952EC +:10CEA000A81300008016E610E8045250001097689E +:10CEB00084C0FB80430040013CADFB8E3CBC01E2E2 +:10CEC0003C8C01E03CCC01E33CDC01E12EE7E9389D +:10CED0002F47EBF92F27EC1B3D3DFB2880464512E1 +:10CEE000E49882A60005000394C2E043E8689591A7 +:10CEF00040459800A4E040041800A400FEEC423035 +:10CF00004073926496D9ACE04036180088CDA420D6 +:10CF100002F300008A0F9603AC18A4D8A40D96DB88 +:10CF2000FE02E060E81A5AE001045B480217380884 +:10CF300088008C01960038088808A4CEE260E813C7 +:10CF4000A42086419601AC302E07EE3D3958880862 +:10CF50008C013E07EE3DD50738088800C0048E01DD +:10CF600038088808A4E004048002E203E804A4204E +:10CF700014048002A4E004048003E260E804A42016 +:10CF800014048003040480023C37F633E260E803B3 +:10CF90003C0BF633A6395A080908B413EA465A007E +:10CFA000010AA58BD509B413EA465A000104A58CE1 +:10CFB000D503446000648C419690D59580263F2728 +:10CFC000EC1B49FFFF3CDD40A6015A08090780061B +:10CFD00049FFFD4D3E07EBD1FCE0FC4080E0A6019F +:10CFE00080C15A08041F9E0CE604E90C5A100C0B71 +:10CFF000DD5E5A0004082E07EB9F5A08010BEB95E3 +:10D00000D508DD42C80B3C03F7745A080108D5F473 +:10D010008007EBAEEA69EBBBEB618400EB4DD50812 +:10D02000DD5E5A00040649FFDEFD8007EBAEDD42FF +:10D030004E0200853C03F62A4412E2F48C01EAF623 +:10D040003C03F6148C01EA9B800749FFFF1BEB555C +:10D05000A600C0058401EA498400EA2AEAB15A0818 +:10D06000011584003E07EBBB84002E172C9244323E +:10D07000ED0C80809680E241E805384181098C0101 +:10D08000D5FAEA58DD41D5242E97E9385A9801158A +:10D090009E34E602E9114402E2F43C13947F4422F8 +:10D0A000C3AB49FFF5CD5A080208FA01DD413E97AE +:10D0B000EBB63E97EC004412FEFCA6085A08A50900 +:10D0C0008401EB5EEA493E07EC008400AE082E07BF +:10D0D000E938C834A6385A080232DD5E5A00010F1A +:10D0E0002E07EC1B5A0801062E07EBD15A00010748 +:10D0F0003CF7F6415EF78078E81849FFFCA8C809BC +:10D100003CF7F6415EF78078E904EA49EAF6D50D86 +:10D11000840184E0EA773E77EF1249FFEBD6DD5ECB +:10D120005A0802043E77EBF9DD5E5A0802082E0722 +:10D13000EBD15A0802048400EA49EA38EA8B9E34AB +:10D14000E602E80CDD42C004EAE2EA4DEA6384004C +:10D15000EA498400EA9BEAF6D5055A68020484018C +:10D16000EA49EA8C5A080104EA49EA77FCC09200CD +:10D17000E60F4EF2007744F0CF80EA7FEA42DD0FFF +:10D18000102E48E0669CE0E0E0E0E0E0E0E0A8008F +:10D190008401EACDAE084423F2498422AE504423F0 +:10D1A000F24AAE104423F24BAE508464D52B841F58 +:10D1B000EACDAE08EBC4AE084413F24AAE084413FD +:10D1C000F24BAE088448D53E8401EACDAE08EBC4EC +:10D1D000AE084413F24AAE084413F24BAE084413AF +:10D1E000F24CAE08D5328401EACDAE084423F249B0 +:10D1F0008424AE504423F24AAE104423F24BAE5086 +:10D20000846C4423F24CAED04423F24DAE50442300 +:10D21000F24EAE104423F24FAE50D5208400EACD3A +:10D22000AE08EBC4AE08D507EACD8400AE08845F33 +:10D23000EBC4AE884413F24AAE084413F24BAE0876 +:10D2400084414413F24CAE884413F24DAE084413AB +:10D25000F24EAE084413F24FAE084413F250AE083B +:10D26000DD9E9200C102EA9496004413F251AE088A +:10D27000DD9E40003C0892104423F2444010BC085C +:10D28000AC1092304403F246AC40DD9E842144034E +:10D29000F240AE40EA28EA40AE88A6405A1001FFAC +:10D2A000DD9E4413F258A448AC404413F25AA448FB +:10D2B000AC414413F25CA448AC424413F25EA4486F +:10D2C000AC434413F260A648EBD7DD9EFC02F0812C +:10D2D0008002F383F18249FFFF4DF001F10249FF23 +:10D2E000FFCA49FFFFD5F00349FFFFDDFC82FC02C6 +:10D2F000F0814403F242F182F283AF40001F8020AC +:10D300004403F243AE404403F252ACC04403F2542F +:10D31000AD0084214403F256AC40001F8024440336 +:10D32000F241AE40000F8028001F802C49FFFF9C77 +:10D33000F001F102F203F30C49FFFFCAFC829200F4 +:10D34000FC203C6DFB9197C4050300025510800F33 +:10D3500043085C0940781EE44273D809470FFF0F69 +:10D360004273D40951080FFF4073C0028E2A8640D1 +:10D370004073C604E625A9F2132300031123000B12 +:10D380004EF2007C012F8038011F8030010F803465 +:10D39000007F802C44F0D1A0EB38EA784A003C00B2 +:10D3A000060606767600C003EB8ED5034021BC0846 +:10D3B000F00792509201AC32F00692A19201120352 +:10D3C000000BF008926192011203000EF009ACB05C +:10D3D00092011203000F220F801E1203000C220F75 +:10D3E00080201203000D020F8022AD718C01ACF47D +:10D3F0001123000C1113000D1103000E1073000F08 +:10D4000011230010111300111103001210730013E7 +:10D410001203000AD532C003EB8ED5034021BC08AD +:10D42000F00A92509201AC32840010030010840183 +:10D4300092819261100300118400ACB0AD31ACF464 +:10D440001123000C1113000D1103000E1073000FB7 +:10D45000110300121073001311230014111300158F +:10D4600011030016107300171203000C1203000DB5 +:10D470001203000E1203000F4403F1408421AE405A +:10D48000EA36EA31A6405A180104AED0D5FCFCA019 +:10D4900044038CF03C0FFB91441FC6784403F142D7 +:10D4A000AC40840044138D08B6013C1DFB91A80FCD +:10D4B0003C1DFB9114008008DD9E84203C0FFB3353 +:10D4C000AC43DD9E3C3DFB33920192219241AC186E +:10D4D000AC59AC9ADD9E3C1DFB33A6821020800C1B +:10D4E000A6831020800DA680A6011020800E1000BB +:10D4F000800FDD9E3C1DFB33A68210208010A6838A +:10D5000010208011A680A601102080121000801328 +:10D51000DD9E3C1DFB33A68210208014A6831020C4 +:10D520008015A680A6011020801610008017DD9EB1 +:10D53000FC01B63FF28149FFFFD0B41F49FFFFDC79 +:10D54000F00149FFFFE8FC81FC24007F8060F0814E +:10D55000F182F283001F803C002F8038000F804052 +:10D56000006F804C105F8016103F8014102F8017C2 +:10D57000104F8015101F801A103F8018100F801B4D +:10D58000104F8019CF08105F801E103F801C102F95 +:10D59000801FD507101F801E103F801C100F801F9A +:10D5A0003C0DFB91104F801DF855B005B046B0877B +:10D5B000F856F001F102F203F8573C0DFB33021F5D +:10D5C0008028AC44001F8054002F8044FE775263B3 +:10D5D000002040609824001F80481060000A581006 +:10D5E0008040FE571010000B221F802C1210000CE0 +:10D5F000221F802E1210000DDD44DD43AE40440397 +:10D60000F1408421AE40A6405A1001FFFCA4FC0466 +:10D61000F08194199600F182100F80178422100F68 +:10D62000801B84C13C0DFB91103F8014104F80156E +:10D63000103F8018104F8019103F801C103F801F32 +:10D64000104F801DF283101F8016101F801A106F5C +:10D65000801E49FFFF34B005B046B08749FFFF6A1E +:10D66000F001F102F20349FFFF2F3C0DFB33842050 +:10D670008449AC441010000B1020000ADD44DD4347 +:10D68000AE404403F140AF80A6405A1001FFFC8435 +:10D690004403F148A6404403F149A600EBED96018E +:10D6A000DD9E44100055DD43AE40EA80A6085A00D6 +:10D6B00001FF84214403F380AE40EA28EA40AE88AB +:10D6C000A6405A1001FFDD9EFC004413F381A6081A +:10D6D000EB21AE0884004413F384AE084413F56BC9 +:10D6E000AE0849FFFFE0FC804453F381A72896D899 +:10D6F000544200F0FEA7401104449688400100E423 +:10D7000096804403F384AEA8AEC0DD9E840044132B +:10D71000F386AE084413F387AE08DD9EFC60440335 +:10D72000F38496D8AEC049FFFFBEDD44DD43AE4072 +:10D730004413F380A6085A0001FF4473F386446340 +:10D74000F3874493F04A44A0005544B3F380A638CD +:10D750005A08010D49FFFFDC49FFFFA510A4800016 +:10D76000000580005A0001FED5F3A6305A0001F4EE +:10D77000FCE0DD9E441E00008801920296014413E5 +:10D78000F3CAAC08DD9E4413F280A608EA43AE0853 +:10D79000DD9E4423F280A650400080A49600AE1087 +:10D7A000DD9E441E0000880196814413F286AC88F9 +:10D7B0004200400B4413F288AE08DD9EFC608141BC +:10D7C000001000094473F280968CA67880C0EB9418 +:10D7D0000000000A401088243C7FFB93AE789684BA +:10D7E000A638A470EAB240000844AE384403F2847C +:10D7F000AC40A03149FFFFD7001300084403F28377 +:10D80000AE40852044B3F04AEB9C0003000B49FF77 +:10D81000FFC249FFFFBAA6389604C01384011085E1 +:10D82000800049FFEDCE50048001EAE7E72FE9F4DC +:10D830002E07EF435A0801F184023E07EF43D51744 +:10D840004403F2813C0FFB925AA80307A640421002 +:10D85000880BC1DCD5095AA80106A600EA46C8070C +:10D86000D5D55AA80205A600EAD4C0D0FCE0C80865 +:10D8700044138D25A6088C019600AE08D50E4423CE +:10D880008D26A6508C219648AE505A0801074413A5 +:10D89000F060A608EA5FD5064413F060A6085400BD +:10D8A00000FBAE08DD9E96004413F068AE08DD9ED6 +:10D8B0004423F053A6509604EAD688019600AE1091 +:10D8C000DD9E4413F06AA6889604542100FEAE88BB +:10D8D000A68888029600AE08DD9E4423F054AC1062 +:10D8E0004403F056AC40DD9E4031C8084021898099 +:10D8F0008802401004C084A54443F06D4403F06ED8 +:10D90000AF603C1FFB943A100420DD9E842044034A +:10D91000F06DAE40DD9E4403F061A600EA46DD9E58 +:10D920004403F061A6009207DD9EFC0049FFFFFA68 +:10D93000C80749FFFFF25A0001068401FC808400F9 +:10D94000FC808402FC804000808496004413F481B3 +:10D95000AE08DD9E96814413F48396D0A7089248C2 +:10D96000AEC8A6C9AE89EB16880192109600441382 +:10D97000F485AE08DD9E96814413F486AC88EB16E0 +:10D980008801921096004413F488AE08DD9E9681BB +:10D990004413F48996D0A7089248AEC8A6C9AE89A8 +:10D9A000EB168801921096004413F48BAE08DD9EAE +:10D9B00096004413F48CAE08DD9E4403F482A64026 +:10D9C000EA28EAD658108001AE40EA40AE88A64068 +:10D9D000964CC9FEDD9EFC004463F00EA43042006C +:10D9E000200BC00744138D24F81C84084800007BDA +:10D9F000A430EACAC859A430EAD4C00644138D231F +:10DA0000F8108403D56FA430EA46C00644138D2273 +:10DA1000F8088402D567A430EA57C00A44138D2160 +:10DA2000A6088C019600AE0883FF8404D55BA43061 +:10DA30009604C04E49FF95D5A4304200180BC83655 +:10DA4000A4304200140BC834A43042001C0BC8326E +:10DA5000A4304200240BC00B4403F064A640964C53 +:10DA6000C12BA640EAD6AE408409D53CEBADA4401C +:10DA70004210A80BC923A4404210AC0BC921A440FA +:10DA80004210B00BC91FA4404210B40BC91DA440E2 +:10DA90004210B80BC91BA400920FC01A84013E07A4 +:10DAA000EEDC840FD51F8401D51D8406D51B8405AB +:10DAB000D5198407D5178409D515840AD513840B85 +:10DAC000D511840CD50F840DD50D840ED50B4403D0 +:10DAD000F01AA400EACAC00549FF9583FA01D502ED +:10DAE000FA0884204423F00EAC504423F01AAC50C2 +:10DAF000FC8084214403F322AE40DD9E4413F323D3 +:10DB0000AE08DD9E4403F323A600DD9EFC004463C3 +:10DB1000F540B6064403F544B6204403F548B64044 +:10DB20004403F54CB6604403F550B6804403F55405 +:10DB3000B6A0F1044403F558B620F1054403F55CA2 +:10DB4000B620FC80FC614433F5044423F502441301 +:10DB5000F5033C3FFB964433F50580C03C2FFB9911 +:10DB60003C1FFB983C3FFB955A00030448000145CD +:10DB7000DD424413F51AC0048401AE08D502AE0894 +:10DB80004403F5788420AE40843FAE40442FFFAA82 +:10DB90004403F579AE8084C1AE404403F500AF8004 +:10DBA0008400802080408060EA2C84234403F501B7 +:10DBB000AE408400802080408060EA2CEB26A608DE +:10DBC000EA91AE088400802080408060EA2C440006 +:10DBD0000802EA413C1DFB98A608EA91AE088400C1 +:10DBE000802080408060EA2C4400041AEA41DD4431 +:10DBF0004403F509AE408400802080408060EA2C18 +:10DC0000EB26A608EA43AE083C0DFB98A6805821F7 +:10DC10000001AE80A68858210004AE88A680582155 +:10DC20000004AE80A68858210008AE88A68058213E +:10DC30000008AE80A68858210010AE88A640581073 +:10DC40008010AE408400802080408060EA2C440038 +:10DC500005AAEA41EB26A608EACCAE083C1DFB98D3 +:10DC6000A608EACCAE088400802080408060EA2CC0 +:10DC70002E07EBD44E030116DD403E67EBD4A60120 +:10DC8000B61FDD46DD525A0802058404AE09D503ED +:10DC90008409AE098501DD403E87EEA3EA3A3C2DBA +:10DCA000FB3B44020168046100128420EA65406085 +:10DCB000184004A30003049300034005100954A076 +:10DCC000000340049809960F3E17EEA3F081A1F3DC +:10DCD000A03344B3F68066000030EA85A833A03351 +:10DCE000FA6F660000C0EAE6A833A03392E8660047 +:10DCF000030058000200A83304410013844C9290A2 +:10DD000054027FFFA73597CFFF1440420040EA9DA1 +:10DD100040E2000004D700004608000804C70001E4 +:10DD200040068002B60E460F000F400600021407A0 +:10DD300000014423F683841F10858000AE10442325 +:10DD4000F684AE104423F685AE104423F686AE105A +:10DD50004403F687AE404403F688AE404403F68998 +:10DD6000AE404403F68AAE40840080208040EA2C16 +:10DD70004403F40BA64044200039548080FF441330 +:10DD8000F415AE888424AE408401EA25440005AA37 +:10DD9000EA41DD44DD43AE40EA9EC0FF84008520B9 +:10DDA0008020109580008040FA6FEA2C4403F4151F +:10DDB000EB9F4403F40B10800000A033660000309A +:10DDC00040A0288414A30003A033F101660000C022 +:10DDD000409004C414930003A03366000300407015 +:10DDE0001D04A9F3DD40001F800014D7000014C7F4 +:10DDF0000001AE41D556C83184414413F500AE88C8 +:10DE000084434413F501AE883C2DFB998060A650F5 +:10DE100058108002AE503C2DFB98A650581080023E +:10DE2000AE5080208040EA2CEB268066A608EA5F90 +:10DE3000AE083C0DFB98A68058210004AE80A68851 +:10DE400058210008AE88A640804658108008AE4091 +:10DE500080068026EA2CD5255A080124A6D0A608DB +:10DE6000543180F3540000F3AED0AE08840080201B +:10DE700080408060EA2C84004413F500AE0844130F +:10DE8000F501AE08EB26A608EA4FAE083C1DFB984C +:10DE9000A608EA4FAE088400802080408060EA2C0B +:10DEA000FCE1DD9E46108000EB32EAFE4210EC09F8 +:10DEB00040008364EA7ADD9E46100800EB32EAFEF9 +:10DEC0004210DC09400082E4EA7ADD9E4411000041 +:10DED000EB32EAFE4210C00940008204EA7ADD9E7D +:10DEE00044108000EB32EAFE4210BC09400081E49D +:10DEF000EA7ADD9E441002006413280364130802CA +:10DF00006610820040008124EB6D4413F7EFA608F1 +:10DF100096009684C203EAA6AE08DD9E8422EB3208 +:10DF2000EAFEEB9440008024EA7ADD9E641200024F +:10DF3000C00458008001D50366008001640200031C +:10DF4000DD9EDD9EDD9EDD9EFC4080E04403F040D2 +:10DF5000A780812181425463001C5A780225DD424A +:10DF6000C0144422FEF64433F04AEB77A610441264 +:10DF7000FEF65A00EC04AF18D5FA8400AE088041D2 +:10DF800084618402DD45D50A4412FEF6440FFFEC9D +:10DF9000AE08804180078461DD45EA66FA30AE4014 +:10DFA0008400EA5B84004413F00EAC08FFBF441306 +:10DFB000F01AAC0897B04403F040AF80DD44DD4375 +:10DFC000AE405A78020A4410005AAE40490000FBA5 +:10DFD000C8FEEA7AEB6D4413F0DAA608EB2140257F +:10DFE00000049690AE88540480FF4413F0EDAE0810 +:10DFF000DD444403F041AE40EA2DEA2DEA2DEA2D3E +:10E00000EA2DEA2DEA2DFCC0400004A44423F0428E +:10E010009600A6D0AE10DD9E965F960440008084E8 +:10E020004413F043AE08DD9E4413F044AC08DD9E7B +:10E03000540000FD4413F046AE08DD9E40003C084D +:10E0400092104433F2004010BC08AC1892304403E4 +:10E05000F202EB8EAC4092504403F204AC80DD9EA1 +:10E060004403F20AA640EA28EAD658108001AE40DE +:10E07000EA40AE88A640964CC9FEDD9E9600442339 +:10E08000F206AE1096484403F207AE40DD9EFC0057 +:10E09000DD42C004440255B8FC80440215B8FC803F +:10E0A000FC00DD42C00444024A00FC8044020A0035 +:10E0B000FC804403F20BA600DD9E4413F208AC087A +:10E0C000DD9E4423F20AA650964C40008024960020 +:10E0D000AE10DD9EE608E82344F0DEE4EA7FEA4283 +:10E0E0004A003C00080E141A20262C324403F20C7D +:10E0F000D5154403F20ED5124403F210D50F440394 +:10E10000F212D50C4403F214D5094403F216D506D5 +:10E110004403F218D5034403F21AAE40DD9E920088 +:10E12000E608E82344F0DF30EA7FEA424A003C0098 +:10E13000080E141A20262C324403F20DD515440380 +:10E14000F20FD5124403F211D50F4403F213D50C8C +:10E150004403F215D5094403F217D5064403F21916 +:10E16000D5034403F21BAE40DD9E92004403F0C48D +:10E17000A600DD9E96004413F0C4AE08DD9E440365 +:10E18000F0C3A600DD9E96004413F0C3AE08DD9EEA +:10E190004403F0CEA4004413F0D0A648400080E42D +:10E1A000441D020088015C000080DD9E4402FE00E8 +:10E1B000DD9E84214403F0F5AE40DD44DD43AE40F6 +:10E1C000DD9E4403F0F4A6009204DD9E4403F0F7C4 +:10E1D000A600DD9E96004413F0F7AE08DD9E4403D2 +:10E1E000F0F6A600DD9E96004413F0F6AE08DD9E24 +:10E1F0004452FE004412FE3E18028001D9FEDD9E0C +:10E20000FC40440000FD49FFFFF54463F068EA6FFD +:10E21000EA75F803FA09EA41A6305200000149FF05 +:10E22000FB4444000492EA41EA53D5F4FC0049FF60 +:10E23000FFE992004423F0C7A65096485A0801050A +:10E24000581080C0D502966FAE50DD9EFC00441081 +:10E2500005FC4403F0CEAC4084204403F0D0AE4033 +:10E26000840149FFFFE9FC804423F0ECA6509604AA +:10E27000541080FB40008044AE10DD9EFC0049FF3E +:10E28000FFF5FC804403F0CEA4004413F0D0A64870 +:10E29000400080E4EAACFE0DEAD0DD9E9202441319 +:10E2A000F0E6AC08DD9E4413F050A608EAE6AE089E +:10E2B000DD9E4413F050A6089637AE08DD9E442339 +:10E2C000F050A6509617541080F8FE47AE50DD9ED1 +:10E2D0004423F050A65096175410808F400080843D +:10E2E000AE10DD9E4413F050A608EAB4AE08DD9EE1 +:10E2F0004413F050A608540000F7AE08DD9E441306 +:10E30000F051A608EA43AE08DD9EFC008407EBBA94 +:10E3100084204403F04CAE40840749FFFFDB842196 +:10E320004403F04EAE4049FFFFECFC8096004413DE +:10E33000F04CAE08DD9E4403F04DA600DD9E3C0F80 +:10E34000FC6ADD9E3C0DFC6AA600DD9E44030FA026 +:10E35000EAB73C0FFB453C1FFB1C3C0FFB24DD9E3A +:10E36000C0045A000209DD9E3C0DFC6AA6003C0F69 +:10E37000FA5ADD9E3C1FFA5ADD9E40003C0892107E +:10E380004433F1C44010BC08AC1892304403F1C6C9 +:10E39000EB8EAC4092504403F1C8AC80DD9EFC0093 +:10E3A00044020000A682A6434403F1C2AE804403A7 +:10E3B000F1C3AE403C0DFB453C1DFB1C3C2DFB243A +:10E3C00049FFFFDDFC8084003C0FFB778421440380 +:10E3D000F1C0AE40DD9EFC602EB728122EA7283576 +:10E3E0002E9728342E7728134E030087EBC6C03DA6 +:10E3F0003C0DFB54E615E9392E00111AC8113C00FA +:10E40000087250F07FB05CF78BE0E8083C000873BE +:10E4100050F07FB05CF79360E9038401D50284007B +:10E42000EB00EB3A5CF00708E807EA3BC019EADFCB +:10E4300084CCC017D5155CF008FCE807EA3BC01097 +:10E44000EADF84C4C00ED50C5CF00A8CE807EA3B16 +:10E45000C007EADF84C5C005D5038400EB0084CF84 +:10E460002E17EC028006C905840084CFEB008006DD +:10E470004413F1C210B080004413F1C310A0800017 +:10E480004423F1C4441FAC48AC50443FA608442385 +:10E49000F1C6ACD04423F1C8AC5096004413F1C18E +:10E4A000AE08F8A6DD44DD43AE40EB20A6085A00D6 +:10E4B00001FF4403F1C210B000004403F1C310A0F7 +:10E4C00000004413F1C4440FADD8AC08442FA79802 +:10E4D0004413F1C6AC884413F1C8AC0897B04403A8 +:10E4E000F1C1AF80F885DD44DD43AE40EB20A608E6 +:10E4F0005A0001FFF8035A0001044800006EEBC601 +:10E50000C0283C0DFB54E615E924EA745CF00708CA +:10E51000E807EA3BC019EADF84CCC017D5155CF0E8 +:10E5200008FCE807EA3BC010EADF84C4C00ED50C43 +:10E530005CF00A8CE807EA3BC007EADF84C5C00547 +:10E54000D5038400EB0084CF2E17EC028006C905AA +:10E55000840084CFEB0080064413F1C21090800049 +:10E560004413F1C3AFC84423F1C4441FAD10AC50F1 +:10E57000443FA6D04423F1C6ACD04423F1C8AC50EC +:10E5800096004413F1C1AE08F833DD44DD43AE40DC +:10E59000EB20A6085A0001FF4403F1C2EB9F44039D +:10E5A000F1C3AFC04413F1C4440FAEA0AC08442F74 +:10E5B000A8604413F1C6AC884413F1C8AC0897B006 +:10E5C0004403F1C1AF80F814DD44DD43AE40EB20DD +:10E5D000A6085A0001FFFCE0FC0649FFFEE23C0DE4 +:10E5E000FA5A5A000F1096004413F1C1AE0849FFC1 +:10E5F000FEECDD44DD43AE40EB20A6085A0001FFEF +:10E60000FC86FA30F18584228400EB5784A1F187DF +:10E61000EB9AF083F084F086F088F0892E47281377 +:10E62000B67FF581F382F58AEB7A8041EA3DFC867C +:10E63000FC212E07EBCB80E480C55A08010A840632 +:10E64000441000E1DD473C0DFFF9B606D55A9E0C9B +:10E65000E6025000FFF8E9049680E642E81D9600C5 +:10E66000E602E92E2E07EEA3C00B8405DD478406E3 +:10E67000441000E2DD473C0DFFF5B606D542F181BE +:10E68000DD46F1015A0802F38406441000E3DD4739 +:10E69000EAEAB606D5365A180D268406441000E478 +:10E6A000DD472E07EEEA8E01E606E81144F0E4B8F5 +:10E6B000EA7F40F03C00DD0F1A060E24141A3C0DD0 +:10E6C000FFF5B606D51EEACFB606D51BDD4BA60074 +:10E6D000C804EA67B606D5155A080314EA8EB606CA +:10E6E000D5108E2AE622E808EACFB605441000E5E8 +:10E6F0008406DD47D506DD4BA60049000D9BB60616 +:10E70000DD42C016EAAA5CF000A0E912DD5A5A0800 +:10E71000010684033E07EE93D50BDD5A5A08020921 +:10E720002E07EE935A08030584003E07EE9349FF37 +:10E73000D39AB4A63C2DFFF33C5FFB32C01BD20B37 +:10E74000EA8ED0093C0DFFFCD00F3C0DFFFBD00C36 +:10E75000EAEAD829A029962F5A081426A029920C53 +:10E76000962F5A080B2104028011EA4314028011EB +:10E77000D51AD214EA8ED0123C0DFFFCD00F3C0DFE +:10E78000FFFBD00CEAEAD80FA029962F5A08140CE8 +:10E790000402801196045A08010704028011EB510B +:10E7A00014028011B4064412FF80402008093C0F77 +:10E7B000FB32B641041000084422FF84966FB62253 +:10E7C000A0014412FF88962FAE08EB074412FF8980 +:10E7D000A0014452FF909206962FAE08EB07441218 +:10E7E000FF8AA001443D0070920C962FAE08EB0703 +:10E7F0004412FF8BA0014422C6609212962FAE08ED +:10E800004402FF98986B38110400EAEED8FCEB56EE +:10E81000B446EB16882292229649EBA9EB56441E89 +:10E8200000208801920296014413F400AC0897F886 +:10E830004403F402AFC0FCA19200FC20447189C4DF +:10E8400038138602463000FF40608C0292CC106084 +:10E850000009406090091060000A38638A0246206F +:10E8600000F04073080292F040138484FEE6926C3C +:10E870001010000B4410FF00407304021030000E13 +:10E88000FEAE40321009FE6E952492E840220A1531 +:10E8900092281070000C1060000D1030000F102036 +:10E8A00000101010001110500012FCA0FC02444196 +:10E8B00089983B024C00EBF8380F8000FE45380F7A +:10E8C0008400FE85380F88005600000FFC829200FD +:10E8D000FC41B4A0EA67D050EA8ED04EEAEAD04CB0 +:10E8E0003C0C0327E608E84844F0E6F4EA7F40F0F1 +:10E8F0003C00DD0F127826485A3C7008EA88C83E72 +:10E900008400EA64D53B84003E07F1ADEB138E0230 +:10E91000E602E8348402EA64D5312E07F1AD8C01B9 +:10E920009600E6063E07F1ADE9298405EA64D5269E +:10E930002E001154C8238406EA64D5203C0C032819 +:10E940005A08030F3C10088BE622E8F6D5163C0C5B +:10E9500003285A0803F23C00088BE602E8ED840421 +:10E96000EA64D50CEB13E602E809D5CBEA88C0C906 +:10E970008407EA64D5038401EA6404028014441223 +:10E9800003009210EA4CEA4E3C1C0327E62D4EF29F +:10E99000011444F0E7A038178501EA784A003C00EA +:10E9A0001A008C00EC002C016801A801B201BC0126 +:10E9B000CE010602D8010C0212022E17EF065A18D9 +:10E9C000010584203E17EF068420EA51841F3E0093 +:10E9D0001131EA37C8083C0C00ACEBCA3C0C00AD66 +:10E9E000EB70D5095A0801083C0C00AEEBCA3C0C90 +:10E9F00000AFEB703C1C0323449189C497C8964830 +:10EA0000EB05EB0D842AB61F84468007F88938048D +:10EA10008202F081EA65EA9DB49FEAD5F501842679 +:10EA2000844A8067F88D8400EA47F84F8421EA51D0 +:10EA3000EA37C8083C0C00ACEBCA3C0C00ADEB70EC +:10EA4000D5095A0801083C0C00AEEBCA3C0C00AFDB +:10EA5000EB703C1C0322449189C497C89648EB058F +:10EA6000EB0D8423B61F84428007F85A38048202D3 +:10EA7000F081EA6544020040B49FEAD5F5018422A2 +:10EA800084438067F85D8405EA47F81F8422EA51D1 +:10EA90003C1C0324449189C497C89648EB05EB0DB0 +:10EAA0008421B61F84428007F83B38048202F0813B +:10EAB000EA6544020080B49FEAD5F50184228441CE +:10EAC0008067F83E8400EA47480000778423EA51D3 +:10EAD000460000CC500002BCEB0D8426B61F8442D9 +:10EAE0008401F81E441189C438008202F081EA656D +:10EAF000440200C0B49FEAD5F501842284468461B3 +:10EB0000F81F8401EA47D5588423EA514600009350 +:10EB1000500000AFEB0D8426B61F8442840349FFEA +:10EB2000FEC7441189C438008202F081EA654402BC +:10EB300000C0B49FEAD5F50184228446846349FF6E +:10EB4000FE7E8402EA47D5388424EA518404EA47E9 +:10EB5000D5338425EA518400EA47D52E8426EA512C +:10EB60002E07EF065A0801218400EBA5D51D842746 +:10EB7000EA518405EA47D5208428EA510402801628 +:10EB800044120200EA4CEA4E4624259F4613DA60FE +:10EB900050108E45502101BAA841A842A883A8442C +:10EBA000A845A846A8478405EA47D5068407EA474A +:10EBB000D5038406EA47FCC19200DD40A6019E44CD +:10EBC000E622E9075A000906DD4BA600E602E8093D +:10EBD0008405F815AE08F81AA6405A1001FFDD9E0C +:10EBE000EBB1A600C8058401F80AAE08D50F5A009B +:10EBF00001065A0002045A08030A84004413F572FD +:10EC0000AE084413F57383FFAE084403F3808421F8 +:10EC1000AE4083FFA6405A1001FFDD9E8400EBCC7E +:10EC200084214403F403AE40DD9E4403F403A600B4 +:10EC3000EAD0DD9E4403F40CA6009600C8074413F6 +:10EC4000F3CFA64840000406DD9E8401DD9E8400CB +:10EC5000EA80EBCCAE08DD9EFC005A08011149FFAA +:10EC6000FFAE49FFFFDD842B8400EB2D44138D465E +:10EC70003C0BF61E3E07EBDCAE08FC8049FFFFE9CB +:10EC8000FC804403F01DA680A641A6C040110504E7 +:10EC9000581084009688AE809228A681AE41EA285A +:10ECA0004413F421F806502100014C21FFFE84405A +:10ECB000AE88442000004430000A83FF5021000148 +:10ECC0004C21FFFEA6409648AE40DD9EFC20DD466E +:10ECD0004432DFB4EB6C4422E35C5A080214840033 +:10ECE0004472DB144462E3E84452E980F81238408D +:10ECF000800838428000384100088C015A0820F80A +:10ED0000FCA084004472E33C4462ECEC4452DA80A0 +:10ED100038438000384180083843000083FF384181 +:10ED2000000838428000384080088C015A0820F2E0 +:10ED3000FCA0A6403E1011D0A6413E1011D1A64223 +:10ED40003E1011D2A6433E1011D3A645A684402101 +:10ED50000500A647A6C64011850000300009004006 +:10ED60000008EAED3C3808EC0030000B0040000AD7 +:10ED7000EAED3C3808ED0030000C3E3011DC00308C +:10ED8000000D3E3011DDEBD4969396DC3E3011DE63 +:10ED9000EBD4964B4231840B3E3011DFEBD43C2850 +:10EDA00008EA4231880B3E3011E0EBD43C1808EB06 +:10EDB00042318C0B3E3011E10030000F96DF3E30C7 +:10EDC00011E20030000F92643E3011E30030001178 +:10EDD00000400010EAED3C3808F20030001300401B +:10EDE0000012EAED3C3808F3003000150040001432 +:10EDF00096CFEAED3C3808F40030001592623E30C0 +:10EE000011EA003000170040001696CFEAED3C38BA +:10EE100008F60030001792623E3011EE0000001E2E +:10EE2000962F3E0011EF42012C0BC006440FF0005C +:10EE3000FE873C2808EA4200AC0BC006440FF000F5 +:10EE4000FE473C1808EB84093E0011E2FA063E003A +:10EE500011E3DD9EA4C0442200004412D7BCEA2F77 +:10EE6000B661A4C2EA2F1430800FA4C4EA2FA8CA46 +:10EE7000A4C6EA2FA8C902300008EA2F1430801077 +:10EE80000230000AEA2F143080080230000CEA2F0A +:10EE9000143080090230000EEA2F14308011023045 +:10EEA0000010EA2F1430801202300012EA2F1430C2 +:10EEB000801302300014EA2F143080140230001640 +:10EEC000EA2F1430801502300018EA2F1430801613 +:10EED0000230001AEA2F143080170200001C402173 +:10EEE000004014208018DD9EFC00EB563C2DFFF303 +:10EEF000EB16882292229649EBA9FC80FC00442361 +:10EF0000F6AC4413F6AD5A080106AE108407AE08FD +:10EF1000D5048400AE10AE08840080208040FA6FD3 +:10EF2000EA2CFC80B44084A08C449C2DA2D1960095 +:10EF30005A58200680A05A0823FADD9E5441803F8B +:10EF4000384094088CA197689266D8F3D5F4FC20D9 +:10EF5000B48084608C8484E5B4045A380605660065 +:10EF60000FFFD504921E4000780842219C2484A003 +:10EF700096905A20200C386088008C414063140C15 +:10EF80008CA6880696905A581EF68C6196D8AA21AF +:10EF90005A3807E4FCA0FC20B4608400503180247F +:10EFA0009583A31997B0844099568C415472000FF1 +:10EFB000976896903870940892845A2808F78C01C4 +:10EFC00096005A0804EFFCA0FC20B4608400503185 +:10EFD00080349583A31997B0844099568C4154721C +:10EFE000000F976896903870940892845A2808F712 +:10EFF0008C0196005A0804EFFCA0FC45EA673C0F20 +:10F00000FB3284234403F40BAE4084264403F4040F +:10F01000AE4084014413F407AE084413F408AE086C +:10F0200084404413F01EAE884413F420AE08EA3541 +:10F030005A080105EA67490008274402D7BC441270 +:10F04000DB1449FFFF714402D7BC4412E980F80584 +:10F050004402D7C04412E30849FFFF9F4412E3E88B +:10F060004402D7BC49FFFFB249000A06440200002F +:10F0700049000A79B1C1440189A83B0044048027B2 +:10F080003B00C424A600AE08B184440189B43B000F +:10F09000440480263B00C424A600509F801CAE0878 +:10F0A000844984208009EA33840110048006842086 +:10F0B0004442E33C4432ECEC4402DA8038238400DE +:10F0C00038220408382304003821840838248400B6 +:10F0D000382004088C215A1809F3FCC5FC00B480C0 +:10F0E000844050420024840080A098D096D83830C4 +:10F0F0008C00958296DF4031980C8C0188A35A08C9 +:10F1000008F68C489690AB615A2820EFFC80FC04EE +:10F11000A649B4405A1003045A180D0FEB37A648FD +:10F12000C9054412E980EA6CFC845A18032544128C +:10F13000E308EA6CFC845A180407F8165800000328 +:10F14000B889FC845030FFF6E662E80B84208446E0 +:10F150003820FC088C215A1820FD803FEA6CFC8482 +:10F160008E28E622E8088382B8096600000F83FF34 +:10F17000EA5FB889FC84FC00A68180C05A20031491 +:10F180005A2006129E14E602E90E50017FF8E602AC +:10F19000E90E50017FF6E602E90A5A280D1EDD4607 +:10F1A0005A08020684003E07EB8AD50484013E0714 +:10F1B000EB8AEAFFA6712E27EB9F84812E37EBBFE7 +:10F1C0004452C4DC49FFFA36DD465A000206EA52D0 +:10F1D000802649FFFF9EFC80FC00B48084405042A2 +:10F1E0000034840080A098D096D838308C00958266 +:10F1F00096DF4031980C8C0188A35A0808F68C4899 +:10F200009690AB615A2820EFFC80FC014412DFB4D9 +:10F21000F08149FFFE9EF001EB6CF9B9FC81FC2402 +:10F2200080E180C049FFFD542E2011E24442DFB44A +:10F230004402DA602E3011D15A780635842938120A +:10F240000808E662842238100808E924DD465A08D6 +:10F25000022284005A6803122E1011D14432E308AE +:10F26000F83C5A0820FFEAA4C00D8E228440881F73 +:10F27000E24110F07FFFD5064422E980F83F5A08AA +:10F2800020FFEAA48429381F8008EA52803FEA6CF4 +:10F29000D54CEAA44412E35C8443EB02EA52EA6CE4 +:10F2A000D5448420381208085A68030538600808D5 +:10F2B000D504842138100808E662E930DD465A0892 +:10F2C000022E5A6803192E0011D184285A0802030D +:10F2D000842784004432E30838218000382F8008D6 +:10F2E0008C0183FF5A0820FAEAA4C010881F10106E +:10F2F0007FFFD50C84004422E98038110000381FBC +:10F3000080088C0183FF5A0820FAEAA48422381F5F +:10F310008008EA52803FEA6CD508EAA44412E35C14 +:10F320008445EB02EA52EA6CEA5249FFFF70FCA402 +:10F33000EBF93C1C0002D10C3C1C0003D1093C1C25 +:10F340000004D1063C0C0005FE2DEAD0DD9E8401B0 +:10F35000DD9EEBF93C1DFFF3D10E3C1DFFF4D10BFC +:10F360003C1DFFFBD1083C1DFFFCD105EAEAFE2D48 +:10F37000EAD0DD9E8401DD9E8445403008178486F6 +:10F3800096D8FE2438108E024000800D962FDD9E08 +:10F39000EBEC3C3C00005A1802043C3C0002EB8FB2 +:10F3A000442201209230EA98401104400440800A2F +:10F3B000462C003F50210FFF54000FFF400048082B +:10F3C000FF16FF071440800AEB8F44320180923011 +:10F3D000EA98EB750430800AFE9EFE171400800A3E +:10F3E000DD9EFC0044620104406300202203000013 +:10F3F00049FFFFD0A4303C0BF629FC80FC4180C0C3 +:10F400003C0DAC74F081EB47EACF80E181224C5097 +:10F4100000C1CE04AF9084E1D50F5A680409800181 +:10F4200049FFFFE11074800084E3D506B001386025 +:10F430000400AE5084E38400EB6C386080088C01DB +:10F440004492DA605A0820FB49FFFF85C0123C0D48 +:10F45000FB3B441203C0040000149210EA4CEA4E35 +:10F460003C1C03228C259648AE44AE45AE46AE47C2 +:10F4700049FFFF60C0693C2C000244120420508107 +:10F480000050B408443397809210EA4CEA4E3C1C7A +:10F49000032384888C259648AE443C1C032484A214 +:10F4A0008C259648AE46B408441203609210EA4C8C +:10F4B000EA4E3C1C00AC84CB8C259648AE443C1CE8 +:10F4C00000AE86098C259648AE453C1C00AD8C25C7 +:10F4D0009648AE463C1C00AF8C259648AE47B40813 +:10F4E000441203C09210EA4CEA4E3C1C03223C2D0D +:10F4F000FB328C259648AE44AE45AE46AE478400FE +:10F5000004110008966FE001E8409843A648964829 +:10F51000E634E809E62CE810C1125A180A13390437 +:10F520008008D50F5A10140650F0FFE0E2AFE90949 +:10F5300038448008D50638648008D50338748008BC +:10F540008C019600D5DEEBF9EA67D003EA8ED81D70 +:10F5500084283E100270842A3E1002723E10027C03 +:10F560002E1011E24422DFB4382104004402DA6094 +:10F570005A280906844238200408D5073870040840 +:10F580002E1011E338700408EA52EB6C49FFFE2696 +:10F59000FCC144138D40AE08AE98DD9EFC0180C0D6 +:10F5A000DD4BB65FF381AF808001EA3A8006B43F5D +:10F5B000F20149FFFF25FC81FC6084003E07EB8AD5 +:10F5C000DD40842300A0000144738D41AE410093CF +:10F5D000800049FFFB7D840080408067DD524463EA +:10F5E0008D4000B30000EB7CEA524412DB1449FF6B +:10F5F000FCB08403DD5280498067EB7CE7628403C2 +:10F60000E8028400AE304412DB14EA5249FFFCA148 +:10F61000A630DD528049EA4BEB7CA6303E07EBD2A8 +:10F62000DD4010A00001FCE0FC208380BA12BF1373 +:10F6300054217FFF444203204022084092F05403AB +:10F64000FFFFA7D5844CFFD440738040EA9D88E03B +:10F65000C3239221520086409641EA8A40008017D7 +:10F6600096009E45E637E81384614061800C9F4117 +:10F67000842088039AA94041880C98814021880CF5 +:10F68000FEA78C21FF975A1805F7D51AE605E9164B +:10F69000466FF800D5152E07F1ACC8098401466CF9 +:10F6A000CCCC3E07F1AC50630CCCD50A4663333367 +:10F6B0003E37F1AC50630333D503446001FF2E079E +:10F6C000EBD6C0093C03F6173C13F6199201E22071 +:10F6D000E80284DFFFB3DD42C00292D042033C0B5C +:10F6E000F80E464FE3FFF827A8394203380BF80716 +:10F6F00050420FFFF829A8394203340B8C065410EE +:10F700000007A03983FF66000007FE0FA8394203F7 +:10F71000300BF8226600700040000584B6074203F3 +:10F720002C0BF81A66000E0040000524B6074203B1 +:10F73000280BF812660001C0400004C483FFB6071E +:10F740004203240BF809660000384000046483FF7C +:10F75000B6074203200B8C0654100007B40783FF42 +:10F7600066000007FE0FB60742031C0B8C065420F0 +:10F770000007B4074418FFFFFE0E40000A044223AE +:10F78000180BB6078C4654310007460FFC7FB44770 +:10F7900050000FFFFE8640210E64B6474223140B33 +:10F7A0008C4654310007B447FEA640210EC4B6472C +:10F7B0004223100BF80B462F1FFF50210FFFFEAE08 +:10F7C00040210F24B64742230C0B8C46B4A754317A +:10F7D000000783FF4628FFFF50210FFFFEAE4021A8 +:10F7E0000F84B647A0F94223080B8C469697FE5E1D +:10F7F00040108A04A879A0B94213040B8C269657AE +:10F80000FE164000066497B4A8398CC6540300075E +:10F81000A1B9FFA6406302C4A9B9FCA08400EB37DC +:10F82000AE08EA703C1BF6374412C9B43E07EBD26F +:10F83000AE08AE09AE0AAE0BDD9EFC60847FAED092 +:10F8400084DF846084A18246808382034532C9A814 +:10F850008125814302B0000097D8E3618220E80A45 +:10F8600038A98C08A540E2B2E8098245820784A045 +:10F87000D50638998C08AFD0D50284A00318800033 +:10F880008C61E3A68C024068BC1B4043BC1B5A3809 +:10F8900004E35A50010380908004FCE0FC42FA40EB +:10F8A000812080E1801F8420EA332E27F1B4443286 +:10F8B000C668EABA3801880880834462EEC4C70487 +:10F8C00038730909D50484013803090984209C117F +:10F8D00045018AE445100BB89941975738721400D6 +:10F8E0005A70FF0F38380400385315014231C424D0 +:10F8F00040319476385F9E028865383F9E0A8C219D +:10F900005A1808EC842080618081385F86029788CD +:10F91000E2858C2140333C1B4042BC1B5A1804F743 +:10F92000E647E90284003E07F1B410348000FCC2CF +:10F93000FC002E27F1CA84C340111857443003201D +:10F9400096904412817842110C73DD5DEB7B2E079B +:10F95000F1CA8C0196004060183796484010041B8D +:10F960003E17F1CAFC80FC002E27F1C984C3401168 +:10F9700018574430032096904412817842110C733A +:10F98000DD5DEB7B2E07F1C98C01960040601837D6 +:10F9900096484010041B3E17F1C9FC8084003C0BC4 +:10F9A000F6213C0BF611DD4BA600C0049E43E62277 +:10F9B000E81244037320A6003C0BF6114413732293 +:10F9C0004403732144237323A600A648A6903C2B2E +:10F9D000F621D5269E41E622E9035A080520840037 +:10F9E00044537320802044337334A7283C23F611FA +:10F9F0008CA488443C2BF6110022FFFD88020022D3 +:10FA0000FFFE0042FFFF88223C23F6219601884436 +:10FA100096493C2BF621DBEAD503840080203C2369 +:10FA2000F62188223C23F6119649880296013C1B58 +:10FA3000F62188203C0BF6113C1BF61FDD9EFC00D6 +:10FA4000846080A384DF9718E282E80738500D09AC +:10FA500038608D098C61D5F8FC80FC0084A04030B2 +:10FA60008C204C118018A500A588E2C4E803A500ED +:10FA7000AD08A580A510E2C4E803A500AD100A40BA +:10FA800080010A6100018A86E0A4E80297618C0285 +:10FA9000D5E98005FC80FC2084A0826041214009DA +:10FAA0008082800597E9E2E3E83C5CF38064E90644 +:10FAB00050F3FF385CF78064E8304069942002F32B +:10FAC000000003108000E3AFE8050303000013000B +:10FAD00080000313000002F20000E3AFE805030317 +:10FAE00000001302000003108000EB864108C001F3 +:10FAF000E010E8133D180B6240080013EB863D0848 +:10FB00000B63A5B03C680B643C780B653C080B6646 +:10FB10003C280B673D280B688CA18C228C82D5C3B6 +:10FB2000FCA0FC004440032080C1441300004210AC +:10FB300010738001802280434430012CEBBCAC3038 +:10FB4000FC80401004204430FFFF84404C00800EB5 +:10FB5000A500E244E803A4809691A500E283E803AF +:10FB6000A4C096D98C02D5F34400009642018001CE +:10FB70009A109601DD9EFC7BB182818084204490A6 +:10FB800000C880068448EA334014B036856040904F +:10FB9000840844732D5085404CA60014B004B05D19 +:10FBA0004420003249FFFF4DEA708007EB01381313 +:10FBB0002901E220E803380329098D4188E9D5EDC0 +:10FBC00044732EE05AB001048561D5E64422C3A1F6 +:10FBD000441007D0800649FFFE32EA2338130101A2 +:10FBE000EB5249FFFE5D2E07EB90EB9338130101BA +:10FBF00038230901E241E8059A8AEB78E804D50246 +:10FC00008440EA239451443001F440108C37E623B9 +:10FC1000E807C907441000C740108806D5028423AE +:10FC2000EB932E57F1CBDA072E37F1B588613E37CB +:10FC3000F1B5D5033E17F1B52E37F1B5E663E8030C +:10FC40005A18030684003E07F1B580023E27F1CB27 +:10FC5000FCFBFC2080C180E0AE08840449FFFF8DDE +:10FC60004412C9A838109C002E27EF085A18010822 +:10FC7000E642E8098C413E27EF08D505C2048E41D3 +:10FC80003E27EF0884203E17EF072E17EF08C10527 +:10FC900084213E17EF07AE30FCA0FC6044600320D7 +:10FCA000FE34448301904463000050B1819050A21F +:10FCB000019080E18122890088C0EA708006EB0112 +:10FCC0000214800081A9E220E802EB0E50C30190EB +:10FCD000EA70800CEB01021680008D22E220E8031E +:10FCE0001204FFFF5015FE70800650257E70F80943 +:10FCF000A47881A7E220E802AC38802B800C804AEF +:10FD0000EB03EB18021680008CE2E220E8031203FA +:10FD1000FFFF5063006450B5806450A500644C64DC +:10FD20007FCEFCE0FC00EAF82E17EF2EC0203C0D41 +:10FD3000CAFE5A18010592019601D5039202960156 +:10FD40003C2DFBBEE2402E07EF0AE806E61EE80F58 +:10FD50008C01EB5CD50CC00B5CF10E10E906E60FD4 +:10FD6000E9048E05EB5CD5038E01EB5C5A1801119A +:10FD70002E07EF0A5A081E058405EBFDD50CE61484 +:10FD8000E9048406EBFDD5078407EBFDD50449FFA4 +:10FD9000F2DBEBFDFC803C33F8DF5CF18033E913F0 +:10FDA000FC00848084C3E282E80D40301020A55816 +:10FDB000A4C88C81FEF490624031945C1A308001BA +:10FDC000D5F3FC80DD9E84003E07EF098400EADC69 +:10FDD000DD9EFC003C03F8DFEB2CE905EAC884005B +:10FDE0003C0BF636EB71EB2CE9038400EAC2FC8095 +:10FDF00084003E07EF0884003C0BF8D9DD9E3C03ED +:10FE0000F8D9EB2CE905FC0049FFFFF4FC80DD9EEE +:10FE1000FC012E07F1CCC0048E013E07F1CC49FF56 +:10FE2000FFF02E07EB90501F800749FFFF142E07AD +:10FE3000EBB15A00FF2D84023E07F1CC2E07EF03F1 +:10FE40008C013E07EF034400004ADD412E17EBB161 +:10FE5000E624E81DEA3744F0FC60EB38EA78DD0F71 +:10FE600004180418C81484018427EBA53C1E03273A +:10FE70003E000C84EBF6D50B5A08010A8401EBA571 +:10FE80008407EA6484003E000C84EBF6FC81DD40CC +:10FE9000A6015A080309DD5A5A080206FC0049FF68 +:10FEA000FFB9FC80DD9EFC0080C084003C0BF61F87 +:10FEB00049FFFD762E07EBA4406300D6DD463C23C8 +:10FEC00094985A0002088423FE549649E2C1E90B33 +:10FED000D50EEBE3E2C20010002BE8093C03F61F4D +:10FEE000E220E9058400EAC28400D5028401FC8096 +:10FEF000B461AE185A2802049208AE19B4018840C1 +:10FF0000B641DD9EFC448140B61F81218400B1C111 +:10FF10003815000038101C088C015A081AFB4400E0 +:10FF20001900F844EA8EB43FA680AE880400001E93 +:10FF3000B43F92109C89962FB65FAE09F82B84428D +:10FF400044000280F835EA67803F04600014EA9DAF +:10FF500092D0EA65406018408386B80E8442F8214A +:10FF6000F823B80BF829F823B41F00130028AE407B +:10FF7000B41F84429C41B63F3C1C000004608014C6 +:10FF80004412018092D0EA65406098400013002836 +:10FF9000AE41B41F803F8C01B61F83FF0403000EE7 +:10FFA00092109605F80502030016803F844249FF2F +:10FFB000FFA10403000B803F921054000FFF83FF4A +:10FFC0004E00FFF6440FFFAA10048051EA40EA28D1 +:10FFD000000480515A00CC04AE88D5FBDD42C00736 +:10FFE0004412FE51840280418461DD45840038134F +:10FFF0008000381500088C015A081AFB8400100490 +:020000021000EC +:100000008051FCC4FC0044030C803C1C01DB4420F8 +:1000100000C8EB7BFC80FC002E07EBB28E01E602F1 +:10002000E808DD5D44030C80EA763C2FFBA0EB7B07 +:100030002E07EBB2EB295A08011644530C80442FCB +:1000400074F84430096044430FA08400986AA5A85E +:1000500038608009500003204C01FFFB8CA2DCF6C5 +:10006000FC80FC80FC0049FFFEB649FFFFCD2E0757 +:10007000EBB2C008EAC8DD4BA60049FFFFCE840002 +:10008000EB8BFC80FC000400001444120060921012 +:10009000EA4CEA4E2E172938101000182E1729396D +:1000A000101000192E1729361010001B2E17293793 +:1000B0001010001AA0454210F008A845A0454210B3 +:1000C000F408A845A0454210FC08A845A0454210E8 +:1000D000F808A845DD42C00544037320F804FC80FD +:1000E0004403738449FFEB48FC803C0FFC74DD9EA5 +:1000F0002E37EF2E5A3001062E37EC1C5A38011CD1 +:1001000084603E37EC1C003000103E372BE1A00528 +:100110003C0FCAF9A60A3E072C2CA60B3E072C2D35 +:10012000A4123C0B962BA4133C0B962CFA043E070E +:100130002C5ADD9EA6C03E372BE1A0033C0FCAF926 +:10014000A6083E072C2CA6093E072C2DA4103C0B1C +:10015000962BA4113C0B962C84043E072C5ADD9E52 +:100160005A00010544128178D502EA765040832076 +:1001700080A184001A028001DCFEFC2044530000B0 +:1001800044630C80800180650A218001A5C0402362 +:10019000885C1A2000014C027FF950528320DEF364 +:1001A0008400443281784440096084A09883386098 +:1001B00080013861140950528320DCFA8C025A0BFA +:1001C00020F6FCA0FC60848084FF84C1826780A448 +:1001D00082244492C9B48166810403000000552240 +:1001E00000FFE3828140E80E03008000E383E80A19 +:1001F00038849008A580E2D3E8088266823284C001 +:10020000D50538B49008D50284C00B00800102A542 +:1002100000008C81898AE3878C0240783C1B40591E +:100220003C1B5A4804DC5A60010380B18005FCE0A5 +:10023000FC002E17EBE93C6DFFF3C10B84003E0779 +:10024000EBE9441000E684063C6C000ADD47D53437 +:10025000C80ADD5A5A000131DD5A5A08022E3C6C98 +:100260000002D52A5A08030EDD5A5A0801053C6DD2 +:10027000FFF4D522DD5A5A0802203C6C0003D51C3D +:100280005A08010EDD5A5A0801053C6DFFFBD514D2 +:10029000DD5A5A0802123C6C0004D50E5A08020DB1 +:1002A000DD5A5A0801053C6DFFFCD506DD5A5A0897 +:1002B00002043C6C00058006FC80FC002E07EBCE9F +:1002C000C82B3C0DFBC85CF00032E9042E07EEF6AB +:1002D000C0062E07EEF55CF00032E91E84203C1BC0 +:1002E000F61B840044326EB8EB30E202E8069883D5 +:1002F0008C01AE509601D5F93C0C01D73C1C01D9BC +:10030000EA4844000033EADCEA76EB76DD5D49FF3B +:10031000FD448401EAADFC8040300C204C01800596 +:100320001A200001D5FCDD9EFC4051FFF9B8F08198 +:100330008400EB39EA76B0028440EA22EB6E500F7B +:100340008328EA76EB23EA22EB6E84C044A00320E4 +:10035000449281784472EE9C800942032873B04233 +:10036000502F8328EA22EBBC380399098CC1EB3962 +:100370005A6803F4B042502F8328EA22F001EBBC04 +:10038000EB393C080B5AEA76F00149FFFAD3DD4B12 +:10039000A6008E03E602E8113C03F6374460003203 +:1003A000EB2CE9089E4150007FCE406018D69B8E12 +:1003B00097B13C6BF637D504EBE30260000EDD46E7 +:1003C0005A0002058403FF8497B13C03F77E3C107A +:1003D0000B5C3C080B5BE220E8033C080B5CE2C0D2 +:1003E0003C680B5D3C080A783C680A79E8058402A1 +:1003F0003E07EF09D5162E17EF09C1048E213E17CF +:10040000EF093C13F62FE220E90A3C03F8DF441021 +:10041000EA5FE220E9068C01EADCD5038400EADC2D +:10042000EBCEE602E9078401EAA084003E07F1B0C2 +:10043000D5098400EAA02E07F1B0C0048E013E0762 +:10044000F1B051FF8648FCC044038D40A6402E0702 +:10045000EBE1C1062E17EBE05A1801038C013E07B1 +:1004600028D8DD9E44100055DD43AE40EA80A60842 +:10047000C8FFDD9E3C1DFFF3442200C00400801431 +:100480009210EA4C40010040B400920A96373E07B1 +:10049000EBC004008014441200009210EA4CEA4EB3 +:1004A000B42000000028922A96773E17EBA43E075E +:1004B000EBC8DD9EFC008400EBCCDD4C8421AE401B +:1004C00084018020EBFADD43DD44AE403C2DFB3758 +:1004D000A6505A1001FFDD44AE40840AEA3EDD4CCE +:1004E0008421AE408400EAD1EBDBFC80FC00840375 +:1004F000EB8BEA9584008040DD52EA4BEA9384005E +:10050000EAADEBDB84013E07EEF6EB4ADD4BA600DD +:1005100049FFBEF2EAC8FC80FC20444200002E677E +:1005200029A4842044338D4080E49688E246E8196B +:10053000A7589881C50400510020D5033850040005 +:100540004102040010580184A758C5040021002866 +:10055000D5030021000899791022818C8C21D5E6E1 +:10056000FCA04422D7BCB46244420000EB8FA091AF +:100570009230EA98401204400410800A92325410DB +:100580008FFF964B121000813C1BF62EEB8F04213F +:100590000015923044320180EA98EB7554217FFFB8 +:1005A0004432000C402188400230801F103001048A +:1005B0000230801F9268103001050230801E10301A +:1005C00001060230801E926810300107A4D310305B +:1005D0000108A4D3926810300109A4D11030010A97 +:1005E000A4D192681030010BA112846192985452E8 +:1005F000003F044080114041903E404290E4104052 +:10060000010CA09204108011924896AFFECE4031AA +:100610000CE41030010DDD9EFC2080E080C1DD4245 +:10062000C00C501301048041846A8402DD45EA6AEB +:10063000840249FF9C1CD504840249FF9C18EA8E61 +:10064000442201808380B914BB1592304402000C0F +:100650005431FFFF40300C40EA980003010540117F +:100660000440002301044001010096011200801F94 +:10067000000301070023010640010100960112005A +:10068000801E0003010C40201C0950408044B4042B +:10069000EA4F40000824B604B4040023010DEB51D6 +:1006A000400008F5B6040003010900130108EBED52 +:1006B0009601AC1B0003010B0013010AEBED960140 +:1006C000AC190003010CA09A5410003F460C0FFF18 +:1006D00050000FFFFE1640000704A81A0003010D8A +:1006E0005410003FA01A66003F0040000504A81AFD +:1006F000C7038EE197F88403DD528047EA4BEB7C19 +:10070000FCA0FC6081218162814380C4DD54A60885 +:1007100096005A0801FEDD5BAE088020EBFADD5939 +:10072000A640C9FFA6405A1801FF84003E07EBD03F +:10073000DD42C020EA305A0807FFEAB0EAB7EA48CB +:10074000DD4C8421AE400074812ECF05F8083E7741 +:10075000EBD0D5100073005197FCCF0649FFBE1CAB +:100760001074809ED5058400EBAB49FFBD59840110 +:10077000EADD840AEAD3840010030051100300521A +:1007800010030053FCE03C1DFFF344220000041062 +:100790008014463C003F9230EA9840110440042007 +:1007A000800A50318FFF54000FFFFE9E402102440B +:1007B0001420800ADD9EFC4280C2812080E1FA4044 +:1007C0008420801FEA33987E2E27F1C04432C674FD +:1007D000EABA96493801880880834462EE8CC104E5 +:1007E00038130909D50484013803090984209C11B0 +:1007F00045018AE445100BB89941975738721400A7 +:100800005A70FF0F38380400385315014231C424A0 +:1008100040319476385F9E028865383F9E0A8C216D +:100820005A1808EC842080618081385F860297889E +:10083000E2858C2140333C1B4042BC1B5A1804F714 +:10084000E647E90284003E07F1C010348000FCC294 +:10085000FC60EE38509F8028F082F1838448842029 +:100860008009B1CCEA33800784208448EA338400CD +:10087000EB39F003446000C8406300D654D300FF56 +:10088000400684089600F08485809431F081048FBE +:1008900080028169814C97B1F0034CA0005FB00EDB +:1008A000501F8100F20449FFF8CC44528178444241 +:1008B0008AD840E61400888C14BF8005B04E502FB3 +:1008C00081008066800EF487EB18F086B0675007D1 +:1008D0000190502F81648066EB18F50602158000A8 +:1008E000E20540503C1A9629E220F407E80312552D +:1008F000800050E703204CE27FE3B04E502F810090 +:1009000080668008EB1850E40190F086B067800E96 +:10091000502F81648066EB18F406F105E204404034 +:100920003C1AA4489621E2208D62E8031245FFFF9D +:10093000802D8008EB013803A909802D800EEB0182 +:100940003813A901E220E8033803A909F0018D4119 +:10095000890040C60000D5A1F00249FFF806DD4637 +:100960003C1DFC740220800F5A0002058403FE84A3 +:100970009691806280298007F97B38138101100FDE +:10098000802738248101500F802749FFFF16441328 +:100990008D41A608004F802738038101EB39A6C896 +:1009A0003853910138238D0138048D018802382491 +:1009B00091018845E040E8059A82EB78E805D50288 +:1009C0008440103F8027A608443001F49451401021 +:1009D0008C37E623E807C907441000C74010880693 +:1009E000D5028423002F80272E57F1C8DA072E372F +:1009F000F1C188613E37F1C1D5033E17F1C12E37F1 +:100A0000F1C1E663E8035A18030684003E07F1C10A +:100A100080023E27F1C8EDC8FCE08401DD9E840021 +:100A20004412C674845FEB028C015A0808FE8400ED +:100A30003E07F1C0DD9E5A0801078401AE0884001C +:100A4000AC10DD9EEBE30200000F42420001E283A6 +:100A5000E9F5A410E61EE8048C01AC10DD9E8400CC +:100A6000AE08DD9EFC40812184203C1BF77E109166 +:100A70000000842480C2814349FFFEEC80E04402F0 +:100A8000C9B43810240081205A18010FEBCEE602B9 +:100A9000E8048C013E07EF0984013E07EF2E840035 +:100AA0003C0BF635D52E4412C71E84004422C45A8E +:100AB0003C33F77E3C43F62FF9152E17EF09C1049E +:100AC0008E213E17EF095AA8011284608023380452 +:100AD0008C00C8038C2196498C615A3804FA5A1844 +:100AE0000406EB718C01EAC2D5038400EAC23C1310 +:100AF000F8DF4400EA5FE201E9048C213C1BF8DFE7 +:100B00008400EAA0EBCEC0048401EAA0AFF0FCC0F0 +:100B1000FC0097844060982044100640FE0C44136B +:100B200000004000803C80228043EA22EBBCAC30D5 +:100B3000FC80FC6051FFF9B8B67F8160EA22B00208 +:100B4000818180E2EA768440F481EB6EEB23EA2235 +:100B5000500F8328EA76EB6EDD4C8421AE4084C0D2 +:100B600084013C6FFB7C4493F04AEA7D44A000552D +:100B7000EAC844D3F4234C65804784003E07EBEF7A +:100B80008400EB6B84018020EBFA840A10A48000BF +:100B9000EA3E000680005A00040510A48000D5FA41 +:100BA000850A85C02E07EBEFE20CE825EA305A08EB +:100BB00007FF3C8FFB473CEFFB7C2E07EBEFB43F7E +:100BC0005A780209F201B0C2504F832849FFF867F2 +:100BD000D50BB082503F83285A78010549FFF7A30F +:100BE000D50349FFFF972E07EBEF8C0196003E07D8 +:100BF000EBEFD5D9DD4C8421AE408CC1EA38EA8BCD +:100C000097B0D5BAEA9551FF8648FCE0FC438420B2 +:100C10008448B002EA3384208448B004EA33EA9579 +:100C20008422DD4BAE40844284018425F80C446369 +:100C30008D42EA6FEA75A6305A088F0AEA5384019A +:100C400084258442B0C2B104F829D5F6B042844468 +:100C50008402F859DD463C1DFC740220800F5A00C6 +:100C600002058403FE849691B0428062B00449FF7D +:100C7000FAABF08149FFFED58402F815EA95F00140 +:100C8000FCC3FC0180C0EA958421DD4BAE408401A9 +:100C900084258040B0C1504F800649FFFF4C5A6800 +:100CA0000105800649FFFA5EEA95EB8449FFF8FDED +:100CB000FC81FC418400EA2349FFF9D6DD4BA60004 +:100CC000C0145A00040448000061EA583C0BF62F97 +:100CD0004412C71E84004422C45A3C33F77E444069 +:100CE000005049FFFEAAD5063E07EF2EEA583C0BFE +:100CF000F62FEB76842049FFFB19DD4BA60044124A +:100D0000C6EC844149FFC0B1EB55A60096424E1493 +:100D1000000F5A0888098400EAA03C03F8DF8C0120 +:100D2000EADCD5058401EAA08400EADCEB76EA7609 +:100D3000DD5D49FFF832EBBE5A000103F8622E0771 +:100D4000EEFE5A000103F85D8400EB1744000043F7 +:100D5000DD4149FFFF5DEA23EB55A60096424E14A4 +:100D60000004960FEA23DD52EB93EA4B8403EA93E7 +:100D700084C184003C0BF635EAAD3E67EF2EEB4AAA +:100D8000EAC83E67EF2FF83D440000963C0BF62F73 +:100D9000EB045A0801093C3DFBC8440000314030D7 +:100DA0000C06D5078460C8052E37EBC540300C060D +:100DB00044138D41EB76A648EAAE49FFFE55441335 +:100DC0008D42200080004E04001A8400EAA0A6088C +:100DD0009636C00F8400EAC2A60854200020C20E36 +:100DE00066200020960FAE88EA238401EAA0D5068B +:100DF000EB71E61EE803FA0EEAC2EBBE5A000104EC +:100E00004800006E2E07EEFE5A08011D2E77EBBA41 +:100E10005A78011944938D4100548000EB4ED05F05 +:100E200084C03E67EF2FEA958403DD52EB9380691F +:100E3000EA933E67EBCE3E67EEF53E77EF2FEB4A47 +:100E4000D54EEB71E61EE94B44000042DD418400C3 +:100E5000EAC2EA95DD42C008EA305A0807FFDD4BD6 +:100E6000A60049FFBA49840149FFFF0D44238D4282 +:100E7000A6508062970A4E4400089666C106440F49 +:100E8000FFC0AE10D521C82084E0AFD82E67EF0296 +:100E9000EA4BCE0E8006DD528046EA933E67EBCEEB +:100EA0003C6FFBC83E77EEF5EB4AEAC8D5188403E1 +:100EB000DD52A698EA933C0DFBC8EB2CE9108401A7 +:100EC0003E07EBDED50CEA4B8403DD52A698EA938D +:100ED0008400EAADEBDB8401EB17EB4AEBE30000A7 +:100EE000002EC00B3C13F77E4402FE54AC403C1372 +:100EF000F6254402FE56AC40FCC1FC00DD465A0813 +:100F0000022C3C1DFB7EEAA4E220E803EA9EC00C12 +:100F100084003C0BF61E49FFEE8FC81E49FFF540CA +:100F200049FFFEC9D519EA6E5A0801064402C42CCD +:100F300049FFB8B6840184408080842A806280A200 +:100F4000DD56DD5A5A08020549FFC933D5DB2E07A5 +:100F5000EB8D5A0801D8FC80FC20DD4BA6802E17B3 +:100F6000EBA42E07EBC82E37EB932E5011EFCA05DA +:100F7000804082018003D5048205804380A14271B4 +:100F800040243D1C01D94220142484804523331081 +:100F90003C039422E280E81595A140034800A4C0D8 +:100FA000A44088D1A430FE6C4231C0249A08FE3C93 +:100FB0008C81400008169A189601AC309721D5E92B +:100FC0003C0C01D93C1C01D7EA48FCA044531C202E +:100FD000442003E844331DB05A08050BA52802122B +:100FE00091B8FE64401088379649AC68D50B5A0812 +:100FF000010AA468024291B8FE5440109037964905 +:10100000AC688CA2DBEADD9EFC6080E0DD4B80C139 +:10101000818281638144009000005A780114C103E9 +:101020008EC197B0EBB1A740D607EB045A08010573 +:10103000800649FFDA3D8403DD528046EA4BEA939D +:10104000D50D5A78020C5A980405840149FFFFC057 +:101050008400DD528046EA4BEA93840149FFE7426F +:10106000DD54A60896005A0801FEDD5BAE0880201C +:10107000EBFADD59A640C9FFA6405A1801FFDD4230 +:10108000C016EA305A0807FFEAB0EAB7EA48DD4B73 +:10109000A600C8045A980409D5055A0804064E93B8 +:1010A000000449FFFF5BDD4C8421AE405A78010902 +:1010B00084001076000010758000EAD3D5095A78B4 +:1010C0000208840010060000EADD8401EAD3FCE097 +:1010D000FC202E67EBDD3C73F614A60149FFDBA76D +:1010E0008EC1E2E05C630001E904EB91C00284C1BF +:1010F0008006FCA0FC00DD40A6415A1004058424B3 +:10110000AE41EA3A840A441000B5DD47EB91C803CA +:10111000F80AE80349FFDE30840A441000B6DD47D0 +:10112000DD42C024DD558E04E60283FFE8172E075A +:10113000E96C5A08010A4410003F8408804180612C +:1011400049FFE3D4D5155A0802144400003F842611 +:101150008040806049FFE3CAD50B4420003F8408EB +:101160008426806249FFE3C2D50349FFE3D14410DE +:1011700000B7840ADD478405DD4AEA6A49FF89A889 +:101180008406DD4A840A441000B8DD47DD4C842122 +:10119000AE408420840280418461808180A1DD563C +:1011A000FC80FC418120EA38EA8B84063C7DFB22EE +:1011B000EA6284C1DD40EB43EA3ADD4BA6008426B7 +:1011C00049FFF02F8400EA9BDD5997F83C7FFB2212 +:1011D0003E67EBFBAF80DD4CAF802E67EB9F97B097 +:1011E0005A6801108026DD40DD57800949FFDAFF8B +:1011F000F08184408402F1018066808280A2DD5605 +:10120000FCC1FC2080C0DD44DD43AE404472FEF2F0 +:101210002E07EEA2C8198404441000F3DD47EB3F0B +:101220008401EBE75A080103F822A6B89690C2059C +:10123000DD4049FF9726D5ED8401802080628080C3 +:1012400080A2DD56D5E68401EA5B840ADD4A2E07DA +:10125000EEA2DD4A2E27EEA25A28030C8401EA32C0 +:1012600049FFDB628400EA5B8400EAC64800006D47 +:101270005A280409DD408421DD57EB3E8400EAC68C +:10128000D5635A28060D800649FFFF8D84013E076D +:10129000EE9C8400EA5B8400EAC6D5565A280A13FD +:1012A000A63184C15A080A0784003E67EF2CEAC6BB +:1012B000D54BEAE4DD4C3E67E938AF808400EAC6EE +:1012C000D5435A28092DA63184E05A080A09840218 +:1012D0003E77EF2C3E77EEA2AE30D5365A080B148F +:1012E000AEB1DD403E77EEA2EA3ADD408421DD5723 +:1012F0008400EA2A3E77EF2C49FFBDA784013E0710 +:10130000EEDDD5228405DD4AEA6A49FF88E18406DC +:10131000DD4A3E77EEA284028420D5115A280B15AF +:1013200084203C1FFBC7AEB13C2DFB378401EAC7CC +:101330003C1BF6143E17EEA2AE108402804184617D +:10134000808180A1DD56FCA0FC6180C0A601B65F53 +:10135000F3815A080408A6305A080105840049FFA1 +:10136000DA302E07EBF65A08010C4402C3E6B43F0C +:10137000F2013C3DFB313C4DFB2F49FF9AC3EA385B +:10138000EB45DD42C805EA21EA36EA31D56685201B +:1013900044A2FE5044C2C54444DD01B044B2FE56EE +:1013A000DD5E5A000121A6315A08041EEAAB4472E0 +:1013B000FE50EB215A0010188401EB4DA6388540F1 +:1013C000EAE780278047846610A380008402DD4519 +:1013D00084024412C6D880418060DD45EA533EA7AE +:1013E000ED54D52C3B0540003B0640204402FE5402 +:1013F000A6403E17ED58A6013E07ED59EAAC84021F +:101400004422C5448466DD454452FE504412C5441E +:10141000800538203404380080004C01000D5074E1 +:101420008001E72597F8E80644000089DD4181271F +:10143000D5B881278CA14C55FFEDEA21FA12AE08F0 +:10144000804184028461DD452E07ED545A08130F54 +:1014500044000085DD41D50AA6085A002204AED01A +:10146000D5FCEA7EA6005A0013F5DD524422C39C47 +:10147000B47FF401EBE849FF9C6B9600EAE149FF79 +:10148000963BDD555A00010984E13C7FFB5ADD4261 +:10149000C8033C7FFB70A6315A080812A6305A08D0 +:1014A000024FEA3F5A00063E5A000906EA3F5A0830 +:1014B000113ED514DD465A0802FBD533541000FD09 +:1014C0005A180910A6705A18020D8401EA7DEA3FE5 +:1014D0009E46E622E9265A08112ADD42C022D52678 +:1014E0005A080A07A6308E02E602E829D51A5A08D9 +:1014F000030CA7B05A680124800649FFE4F3800674 +:10150000EA7D8408D51D5A08040FA7B05A6801184F +:10151000800649FFE4E78006EA7DEB883E07EB9210 +:101520008408D50E5A0006E7D50A844084618402F7 +:10153000FA25808380A2DD568408D5028401FCE16F +:10154000FC0084003C0FFB79DD44DD43AE403C2DC4 +:10155000FB79CA08840180208062808080A2DD56E9 +:10156000D5F7FC80FC00DD548400AE08DD5BAE08DE +:101570008401EA258409EA2B2E07EE99EA6BDD4403 +:10158000DD43AE40EA80A6085A0001FFDD42C00AF2 +:10159000EA21A6085A0832FF8407EA3E8401DD4AA0 +:1015A000D50C49FF926AEA21EA8AAE08804184029A +:1015B0008461DD458402DD4AFC809200FC6180C0CC +:1015C00081618406A67180E28520DD47854944C398 +:1015D000F04AEB9CA6313E97EEDD8E03E6094EF213 +:1015E00002EA44F113ECEBAFEA42DD0F12005201C4 +:1015F000C6053802C6054203A0037A04E204DD42B0 +:101600002E0728AAC809DD44DD43AE4084094410F2 +:101610000091DD47D5295A08013F04938003F8481B +:10162000E320E9F2D538DD59A600C824DD4CA60038 +:101630005A080121DD5A5A08021BEA6E5A080106AF +:101640004402C42C49FFB52C2E07283F3C1DFB7ECD +:101650008C019401E220E80884408401842A80629D +:10166000808080A2DD56DD42C005D5DEDD5A5A00FD +:1016700001E6DD42C80CDD59A600C8092E07EB8F34 +:101680005A0001062E07EBC65A0001D984094410FE +:101690000092DD472E0728AA5A000103DD5FDD42D4 +:1016A000C01BEB55A600C0038400EA2AA1FB49FF3A +:1016B000D8C7E207E904EA8CC006D50949001AB97F +:1016C000C8FBD510DD558E04E602E90C2E07EBDDD4 +:1016D0005A000109DD5F2E17EEA25A100403DD5FE8 +:1016E000EAC6DD44DD43AE40DD54A608C0FFDD425E +:1016F000C808DD4BA6005A08030949FFF6F9D505CD +:1017000049FF8B89C0FED5F68404AE3184003E07C4 +:10171000EEA3DD40EA3A49FFDA3BDD42C008840629 +:10172000441000D5DD478404EA3CD5038401EA5B1C +:10173000840EDD4A84023E07EBAFEB3EDD5F840B97 +:10174000441000BADD47DD42C812840B441000BBD0 +:10175000DD478006EB0BF9478405DD4A840444101D +:1017600000F1DD47EB3F8006EB8CDD5F840B44101E +:1017700000BCDD47DD5EC8388401DD4ADD559E448E +:10178000E624E90E5A000C0DDD5E5A00040A3C0303 +:10179000F7745A0801048006EBAE8400EB4DEB8829 +:1017A0002E57EB92D805EA69EBBBEB61F904EA38F6 +:1017B000EA8BDD558E04E602E809EAE2EA4DEA63C7 +:1017C0008400EA498400EA9BEAF6DD5E5A000413CD +:1017D000441000D28406DD478404EA3CDD408421C5 +:1017E000DD57EB3ED5075A0804068401EA4584001C +:1017F000EB4D8400EAC7EB0B8006F8F58401EA3272 +:10180000EAB15A080103F804DD5E5A0804044800EE +:1018100001AADD5A5A000203F804EB914E0301A31A +:10182000480001A82ED7EBFB5AD8011349FFD8CEA8 +:101830008402EAC7DD4CEB9F84053E97EC03DD4A4A +:10184000DD424E02FEC9EA305A0807FFDD5F5AD07A +:101850000203DD5F8400EA90DD42C028EAA48C0226 +:101860003C1DFB7E8C22E220E8053C1DFB605A18E3 +:1018700001F9EA69EBBBEB61DD404412E2F449FF98 +:10188000DB01EAB1C805DD40A601EAF1F97684067C +:10189000DD4ADD43DD44AE4080C049FF8AAFC0FE73 +:1018A000EA39AE30DD5AC0FFD52249FFBDD6EACEB7 +:1018B0005A0803053CDFFB22D5038401EA90DD448E +:1018C000DD43AE404493F7F1EA9E80605A0801FE82 +:1018D0000074800097FCCFF94412C47880418402E0 +:1018E000DD458006EB8C3E77EE9CDD5F2E67EBDD01 +:1018F00084003E07EE9C5A680108DD408420DD57D5 +:101900003E67EBFBDD5F000580004E03012EEAB170 +:101910004E03012BDD5A5A000104480001264410F1 +:1019200000D48406DD478404EA3CEB3EDD5FEA3FF9 +:101930005A0806108400EA45EAC7EBBBEA69EB6186 +:10194000DD46C00CEA7C0200001049FF90DFD5069E +:101950005A081110DD42C0EFD50C8403DD41EAE4E2 +:10196000DD5B8401EA32EA77AE08840FDD4ADD5F91 +:10197000EA3F5A000903DD5FDD465A000203DD5FDE +:10198000DD408420DD578403AE31DD5F8401DD4A14 +:10199000DD42C8098006EB0BF8268405DD4A800687 +:1019A000EB8CDD5FDD5EC8178402DD4A49FFBA3A81 +:1019B0008006EBAE49FFD986DD4C8421AE40DD5E6A +:1019C0005A00040E8409EA3C8403DD4ADD42C00764 +:1019D000F835D5055A0804048401EA458404DD4A33 +:1019E0008006EB0B49FFDAFBEAB185213E97EC0359 +:1019F0005A000105DD5E5A08040A840AEA3CEAE45A +:101A0000DD5B8401EA77AE08DD5FA631EAF1F8B567 +:101A10003CA3F614A63149FFD70AE340E912840B30 +:101A2000EA3C8400842BA83BAE71EA9BDD4C3E97D8 +:101A3000EBFBEB9FDD424E0200BE49FFB9F6DD5FD6 +:101A40008409EA3C8405DD4AEA6A49FF8541840647 +:101A5000DD4ADD428020C8F28402804184618081B9 +:101A600080A1DD56DD5FDD42C802EA77A6305A0864 +:101A7000021F10860000DD54A608C0FFA631EAF15F +:101A8000F08185A04402C3E9F1014422C44449FF26 +:101A9000D8553CDBF61410A30001DD40EA3A84007F +:101AA00010D3801CA83B3ED7EBFBF853EA3F5A0803 +:101AB000070C8409AE31EAE4DD5B8401EA77AE0805 +:101AC000FA083C0FFB3E84001003801CDD5F2E07EC +:101AD000EBFB5A080119DD40EA3A49FFB9B3DD4092 +:101AE0008429AE418420DD57DD40842BAE4149FF7F +:101AF000FD3B8402DD5BEAC78400AE08EA32840362 +:101B0000DD4AD5585A0802578404DD4A3E97EBFB5C +:101B1000DD42C8088006EB8C2E07EEDD4E03FD5C2F +:101B2000D54900058000C803EAB1C0042E07E93892 +:101B3000C8128409EA3C10A30001DD40EA3ADD4006 +:101B40008421DD5784001093801CA83B49FFB97D98 +:101B500048FFFD42840AEA3CEAE4DD4C8421AE40C1 +:101B6000D5298402DD4A8403EA3C49FFD6DDD5222B +:101B70008403DD4AA631EAF149FFD5E7DD4049FF9C +:101B8000FAA9C00E8404DD4A84013E07EE9C840657 +:101B9000EA3C800649FFFB078405DD4AD50B44106B +:101BA00000D38406DD478404EA3CDD408421DD5710 +:101BB000EB3EFCE1FC40C002F93C44600065EA6F8A +:101BC000EA75DD46C00E8EC1C60C8421804180615D +:101BD000848044004F00EAB3EADEEA41EA53D5F2DA +:101BE0008400EB69FCC044100055DD43AE40EA8040 +:101BF000A6085A0001FFDD9EFC4080E08122EB9B9D +:101C000080C049FFFFF29E79E62F4EF2019344F126 +:101C10001A1C38178501EA784A003C001E00720041 +:101C200020014C02920014031403140314036E02E7 +:101C3000A202F6021403140318038404FA21DD47F8 +:101C400044000030DD41840EEA628405EA838400AA +:101C5000EA82EABCEA92DD465A080204AFF0D5FCFB +:101C6000DD46C00B842144005AF0804180618081B0 +:101C7000EAB3EADE49FFFFA080098421DD57842012 +:101C8000840280418461808180A1DD56F8EC840467 +:101C9000FA22DD47840EEA628406EA838400EA823F +:101CA00080A650030041843FEAEED8FFD5E6FA252E +:101CB0008404DD4744000031DD4184E04403F4291D +:101CC000AFC0F87084013E77EB8AEA83107300504E +:101CD000EAFFEB5B2E27EB9F84812E37EBBF44524C +:101CE000C4DC49FFE4A7DD4BA600C806EA52441253 +:101CF000E980EA6CD5075A080306EA524412E30861 +:101D0000EA6C84003E07EF2C2E17EF2F8400EA2A9E +:101D100084013E07EBA05A100103EB8B8400EA7D9F +:101D2000DD548402AE08DD5BAE08EA848E08E6046A +:101D30004EF20102800949FFB18FF8958404FA231D +:101D4000DD47EA8ADD41DD4C8442AE80EABA8E028C +:101D5000E603E906EB5B540080FD5A08080784009F +:101D6000EA82EAC3DD41F87F102480002E07EF0DE0 +:101D7000C8099E0BE604E90C5A100D0B5A180E0CFC +:101D8000D5035A180E06EB68840049FFB1F98408A0 +:101D9000EA62D5038409EA6284E0107300503E775A +:101DA000EBBB49FFEC0BDD40EA3A84043E77EC13D1 +:101DB000EA92DD4AEABCDD465A080205EB3FAFF085 +:101DC000D5FB4413F3D1A608EAA6AE08441FFFC30F +:101DD0004403F429AE40DD46C008842144005AF093 +:101DE000804180618081EAB384003E07EF2C2E178A +:101DF000EF2F8400EA2A84013E07EBA05A1001036A +:101E0000EB8B8400EA7D840049FFE04E842080094A +:101E1000DD578405DD4A44000033DD41EA3F5A00C6 +:101E200004045A080706440001F4EA41D504EA58BC +:101E300049FFCAF2DD46C004840049FF8E67EB68A3 +:101E400044000034DD41DD428020848F8402C107DC +:101E500084408020806280A2DD56F8058041806148 +:101E600080A1DD56480000688404FA24DD47842000 +:101E7000DD40DD57840AEA628403EA838400EA8253 +:101E8000DD40EA3A8401EB62D5568404FA2ADD4744 +:101E9000840EEA628406EA8380A650030041843FF0 +:101EA000EAEED8FF80098421DD5784208400846114 +:101EB000EA8280418402808380A1DD56D53CFA2BE2 +:101EC0008404DD47DD46DD525A08020DA6095A009A +:101ED000031380018420DD5749FFD5268401EA32AF +:101EE000D50AA6095A000A0880018420DD57EAE4D1 +:101EF0008401EA3200030051001300524422C3B7A8 +:101F00004432C3874442C3CA49FFF8808400EA824E +:101F1000D5128404FA2CDD47000300515A00010554 +:101F20005A08020584003E07EBDD8400EA82D503EF +:101F3000841BEA82FCC092003C0FFC75DD9EFC60B5 +:101F400004EF800DC80AB461A04994199449401067 +:101F50008FF5EA56EA4AD5469521981C9E628C82F6 +:101F6000A40088238864A5C8A5989603814597FB9B +:101F700097B34E070006EB54F812FD60D503858039 +:101F800081AC4E7700078007EB54F809FD40D5037C +:101F9000850081284E6700088006EB544900228A9C +:101FA000FD30D50384C080E640050408EB54FD50A5 +:101FB000FD13FD04EA59FD10FD05EA24FD50FD1353 +:101FC000FD04EA26FD16EA59FD16EA59FD10FD0545 +:101FD000490026DE49002842021F80189201400075 +:101FE000042012070000FCE0FC6380E03C03EEDE0E +:101FF000EA9FEA8DA63C812180C28143C009A63DAB +:102000005A001F07A63EC004A63F5A08310A000323 +:1020100000455A08010644000096EA9FEA8D000335 +:102020008009C0085A001F0700038008C0035A082F +:10203000310DEBCDC006B4065A080508EBD0C80533 +:1020400044000834EA9FEA8DA57CCD0BEBCDC00699 +:10205000B4065A080524EBD0C82144000A8CD51CCC +:1020600044001F00D80BEBCDC006B4065A08051774 +:10207000EBD0C81444000960D50F5A503105440014 +:102080001F31D80CEBCDC006B4065A080508EBD0BA +:10209000C80544000640EA9FEA8D3C0C019F4E06AD +:1020A00000BCC8083C0C019E4410C34FE2204EF314 +:1020B00000B43C0C01A14E0600B0C8083C0C01A0C5 +:1020C0004410C34FE2204EF300A8A4384E0200A5EE +:1020D000A4394E0200A22E07EF064E03009E021FF7 +:1020E000800AEB3AE2204EF20098021F800BEA745D +:1020F000E2204EF2009249FFB6B64E03008E8421D4 +:1021000010150000EBD23C40033AC907C405500249 +:102110007FE1EB48D50280044411890838509101D1 +:10212000441188C838109101B63F9C74F181EB06C8 +:10213000F18250238028501380103C3C019AF822F1 +:10214000EA3B3C40033BC807C40850127FCF400025 +:102150000406D5048400D5028004441188643850F4 +:1021600091014411880038109101B63F9C76F181AD +:1021700044100068F182502380303C3C019B501396 +:10218000801849FFFEDE0434800B0424800A4E369A +:102190000006CB3E5CF105DDE93B04A4800D04B4F0 +:1021A000800C4EA600074EA300345CF585DDE930B7 +:1021B0003C0C03278E02E605E82B80E9A03DA13CFC +:1021C0009441401093F59421EA4AA07FA0BE97C3A2 +:1021D00094491273000C941140108BF5806A804B67 +:1021E000EA4A22F3000296438AEF42F38003840115 +:1021F0005EF780F11003007A1213000D2203000332 +:10220000E8078A2042F080035EF780F1E907840046 +:102210001003007AD5038400EAD3FCE3FC203D0DD3 +:10222000FC7580C19B31E282E81E087300010450F6 +:1022300000080128003239129E02A146A107385237 +:102240009E0238421E02425914248C684052C4B780 +:102250001251FFFC00580033FF2C404244971241BA +:10226000FFFDD5E1FCA0FC6081A1EBEC81208400A6 +:10227000818280C3AE185A18025084E044E2C9C873 +:10228000E2EDE86B0404800138501D01DF43505437 +:102290008018A02A3C2DFC7538101E02B4050031B0 +:1022A000003238001E023C44086EFE1C0021003340 +:1022B00040A00557A029908138001E02404510011A +:1022C000FE1442F200033C44086F40B00577908151 +:1022D0004045900142420003888F5EF20032E917C8 +:1022E000A6303C1DFC7538A60309A63040060060E8 +:1022F00012B00001A63038770008A6308C01960095 +:10230000AE3000108019E201E905D5274900149488 +:10231000C0E88CE1D5B63C1DFC7584004422C9C8D8 +:10232000E20DE8110434800138518101D814A6F07F +:1023300038010C08A7308C819720AF30003080190D +:10234000E283E90980094412C9C8A6B0806C49FF3C +:10235000FF67D5038C01D5E584004422C9C8A67067 +:10236000E201E8084016006038310000A8C98C017D +:10237000D5F7FCE0FC442F07281280C04260C073F0 +:10238000B5C441130408409944000074800084C01F +:102390002F372813A991B6C25A78FF05B6E3A9D9F9 +:1023A000D51500748000A1A138631D01447000FFA1 +:1023B00097AFA9D9A1E4B6C340639820A7F14C0315 +:1023C000C005A7B04C13007E84C19FC1B6FF9DC15C +:1023D000F781F082B1C4F0839E09A83AEABAF18489 +:1023E000A8798C21A87B50007F018420EB48389F7E +:1023F00086024E95001FE130E81C38A386024EA5E8 +:102400000019E153E8164295407338A925005AA0F7 +:10241000FF1104920001C8063804A901962FB603E3 +:10242000D5073804A901B543962F4CA04007840175 +:102430008C215A1804DEFCC48480380F92024E05A9 +:10244000003DE010E83A381392024E150037E033B1 +:10245000E8344200C073381901005A10FF2F3802C7 +:10246000811138A2C411E140E828381485018A0A94 +:10247000966F5A60010CC6045A600212D524B62326 +:10248000B42284C18801B602D518B5434C15000B9F +:10249000A859A05184C28801A811D50FB5434C1585 +:1024A0004006B4228801B602D50804A180014C156B +:1024B000400DA0518801A8118C815A4804C0D50351 +:1024C0008401FCC48006FCC48403FCC4FC7280C08C +:1024D0002E072813B61F2E072842F0812E07284307 +:1024E000F0828400F28482A483812F372812B09076 +:1024F0008080B15AE203E80A401A8060A04938029D +:102500008408384104088C01D5F68440B110822239 +:102510008501E243E85E400A8860A00104C300012F +:1025200038560101D85438021400C85140D28808E6 +:102530004C20004B401A806005208001A075407936 +:1025400008084100B40088270178000200980000C4 +:1025500000E800010180800300B0800000A080013D +:1025600001080003A64A8D818E21E181E92D510CDD +:102570000001501BFFFFE181E9278F615017000127 +:10258000E02BE9228D418F21E149E91E04930006E9 +:1025900005030007EBC93914960A38821408391864 +:1025A000160A3910960A385649014C59401138021A +:1025B0001400C80D38049C0A3882140838081C0A14 +:1025C00038009C0AD5048C01E203E9B38C41D5A202 +:1025D0008500459FFF80F004E3004EF20100A0312A +:1025E000385021014C5440F8B010380400005A0013 +:1025F0000104480000F1A075B01A4104080838042D +:1026000000008830F083A60A8460E602E9038E01A8 +:1026100096C0B45FA60B8E42E002E8038C01D5039E +:10262000B41F8E01EBDFA6088580E602E9048E0167 +:1026300054C000FFA6095019FFFEE001E8038C0119 +:10264000D5035009FFFF54B000FF812342E1CC24A1 +:10265000E1494EF300AD4007300081AC411E00203F +:10266000518F8040E16D4EF3009EB4064128F00189 +:102670008812200000012A7880014E0500888EFE15 +:1026800097FB4E770084800D8029B08CB0CE808679 +:1026900080BC159F800B158F800A155F8009150F70 +:1026A0008008152F8007151F8006153F800549FFFC +:1026B000FE63053F8005051F8006052F8007050F77 +:1026C0008008055F8009058F800A059F800B5A08E6 +:1026D0000113F00EA07138508101D858380C140045 +:1026E0005A080155F83DF00EF84442149C73B62088 +:1026F000F00ED5475A08024BA0B1F00E3851010137 +:10270000D821380C14005A08011EF00CF10D42308B +:102710001C248801A0764001801640509440B425C6 +:1027200042168073B625F10EA0F7EB75B461423402 +:102730008073B661F10E04330008EB75B461880351 +:10274000B601F00F38510101D821380C14005A0895 +:10275000011EF10DF00CFFCC8801407380F6A0360D +:1027600040501440B40542069C73B60583FFF00F39 +:10277000A077EA4EB42083FF42149C73B620F00F7A +:10278000EBC94E00FFF888E1B6E0B40650D68001F0 +:1027900089C000090001400064041009000148FFDD +:1027A000FF638D2140E74C0048FFFF54F003F10127 +:1027B00040EA8060A036F80512070000A037F10259 +:1027C00038004002FE0CEBC93810C002EA8F83FFCC +:1027D000120700018D0148FFFF00FCF23C0FFC7A5C +:1027E000DD9E4402B64C3C0FFC79DD9E3C0FFEACF6 +:1027F000DD9E3C0FFEABDD9E22200000EADB2200C6 +:102800000001EA868A438A01FE0442010873DD9EC4 +:102810008060804084019A50E622E90A9850922113 +:1028200042F08424E26FEB744020BC1BD5F5DD9EA2 +:102830003C4DFEAB842A0232000922200000FE5CDF +:102840009EC99061E062E8038A22968B0232000AF8 +:1028500022100001840AFE1C9EC19061E061E80321 +:102860008A01964342108801840A42008000DD9E5E +:10287000FC608141EAB84201047380C2B42044C2C2 +:10288000D28844B2D27C95D24492D24CC10D000081 +:1028900000189604C0098403380608088400380527 +:1028A00088088400D53838059800E604E8068C01CD +:1028B0004412D27C38009808380618004412D28896 +:1028C000E603E9038400D5028C0138009808802AC9 +:1028D00040049C0049FFFF92EB06FE0CEB1E4421D6 +:1028E000000038161800E24040013C1B8827444293 +:1028F000D1EC846038020509804338059800E26015 +:10290000E807985F381205018C618841D5F94021AC +:10291000003CEBA22215000038149A0988E9221520 +:102920000001AC79FCE04402B5E43C0FFEAA500083 +:1029300000343C0FFEA9DD9EFC2051FFFD1880C035 +:10294000121F800380E244118AECEBE6B002DD48FE +:1029500044118BA4EBE6B030DD4844118C5CEBE60F +:10296000500F8178DD48500F823044118D14EBE612 +:10297000DD485A6002095A60030A5A68010BB0F038 +:1029800084C0D509503F8178D505503F8230D502AB +:10299000B0C284C1C722FA5D4450005A848084E2E8 +:1029A000EA54381189119603E001E803C607D50BF4 +:1029B000EA549603E020E816C6069855EAB98082E4 +:1029C000960BD5059862EAB980A2960BE005E80B54 +:1029D000E080E8098040D5E5EA549603380181118A +:1029E000D502800251FF82E8FCA03C1C03275A1844 +:1029F00002160010003C5A1801128420EB900210BD +:102A000000181210001A021000191210001B0210F8 +:102A1000000EEBA90210000FD5252210001AFA8330 +:102A200022200018EBF0FA642210001B40210C5603 +:102A30001220001A22200019EBF022100010402171 +:102A40000C561220001B2220000EEBF02210000F6B +:102A500040210C5612200010222000114211107348 +:102A6000EB1B121000110010007AC9080210001AA6 +:102A7000EBA90210001B12100011DD9EFC010210D8 +:102A800000100220001A0230001B9A8A0210001166 +:102A900096938A2322300008964B5EF1803C904149 +:102AA0009021E8044E240008D50E5EF18C44E90321 +:102AB0004E26000A00400078E694E905848940210A +:102AC0001056D5028440122F8000222000095EF1AA +:102AD000003CE8044E140008D50E5EF113C4E9036F +:102AE0004E16000A00400078E694E90584894010FB +:102AF0009036D5028420121F80013C1DFB485CF0FB +:102B00008708E8068420121F8000121F800104102D +:102B10000011EAF9EAC1FF4E44110000D1203C1C2B +:102B2000044D3C67FCF7E6263C57FCF6E906126FBD +:102B30008000125F8001D513EAB68487964B42135A +:102B400010739023964B121F8000021F8001964B3A +:102B5000421290739023964B121F8001EAB6964B57 +:102B60004031842196DB123F8002021F8001964B88 +:102B7000402104219693122F8003021F800212101D +:102B8000000A021F80031210000BEB0F3C0BFCF736 +:102B9000EAEF3C0BFCF6FC81FC61F58141328011CF +:102BA0004122C00A22708001EBC5EAB84201847359 +:102BB000009F803800100018854154F08001446265 +:102BC000D1704412D140E8114502D1C438580D09E2 +:102BD000EB1F4502D1AC4452D1A038780D093870B2 +:102BE0008E0A38A28C08D55EB5805B08031F3903B6 +:102BF0000E024512D1A088B039008E02EB1F8987E2 +:102C000038788C0039008E0A8CE197F8E6EF387836 +:102C10008C08E94840529CB640781CF6EB1F38708F +:102C20008E0A38A88C08D53E5B08013A4502D1C40B +:102C30003D1DFEAC38B80D114502D1AC38A80D11C0 +:102C4000010880005B08016A40F5940141051C0100 +:102C500042F780034308000302888004898FE31051 +:102C6000E85C03188003E171E803E0B1E86A3C8D99 +:102C7000FEAB030400098F818B91E18BE803E185B2 +:102C8000E860E151E803E0F1E85C0304000A8F81A9 +:102C90008B91E18AE842E187E854D53FEB1F387019 +:102CA0008E0A5A980134B4005A0801313D0DFEAC29 +:102CB00002080005E280E82A38030E0238708E020E +:102CC00040504C0142F280034053C80142528003FD +:102CD0000248000688AFE0A4E81902580007451230 +:102CE000D1705102FFFF42084C7340428409427880 +:102CF0004873880440001416888738088E0A4042BA +:102D000014964402D14038400E0A38030E02AC102B +:102D100038008E02AC11FCE139030E024512D1A03D +:102D200088B039008E02898738788C008CE197F85A +:102D300040529CB638788C08EB1F40781CF6D5B012 +:102D400038B30E0A38A08E0AD5ADFC604460004C42 +:102D5000420198733CADFEACB400EBC5EA4FEA8685 +:102D6000010500163C93F48A4512D1344522D1283E +:102D700095DC4462CE284532CE1C5A08011084806E +:102D800038531E0940630CC038488C0838090C08B9 +:102D9000AC7139098C084800009138090C00E61024 +:102DA000E8048C0138090C0838088C0044B2D1348E +:102DB000E60FE9038400D5028C0138058C08391828 +:102DC0008C0040089C003853020940030040AC418D +:102DD0000215000DE081E8100255000CE0A4E80B9C +:102DE000400824018A85FE244100940141004216D6 +:102DF0008989D502820938498C00840380244218CD +:102E0000007384048C22EABEE0804452CE1CE805A4 +:102E10008C81E08040023C1B38028C0838190C0081 +:102E200038498C00846AFE5CE024E905E283802452 +:102E30004011BC1B84A0860A4100C2168005806533 +:102E40004C58001340489C00392312114043104055 +:102E500022420001887288044F1200048FA1D5021B +:102E6000862F8CA1D5EE848AFEE4FE24404090B6E5 +:102E7000C50C88F138431E1140731C4042329073D8 +:102E800022438001420290734E3500064050840A6E +:102E900088A3D50584A2405094B69B5DEB98976BB0 +:102EA0004E0500064030840A8803D5058462403010 +:102EB0008C768A03EACB964BAD50AC51FCE0FC20FB +:102EC0004460004C42019873EBC5B400EA86EA4FB7 +:102ED0004462CDEC95DA4502CDE05A08010A9837F4 +:102EE000AC41EADE38530E0938080C08D54B5EF2C7 +:102EF0000029E8043C43F489D5135EF2012CE80F65 +:102F00003C03F48950427FD8531000644248902417 +:102F100045100104404244968880D502EB193808D8 +:102F20000C0086234202447384848C0240001016F5 +:102F300038080C089937960039230E112312000126 +:102F400053000064424014244248487344500064D3 +:102F50004E45000550420032D50350427FCEFE0C54 +:102F6000420844734042149638430E09EB064E055E +:102F7000000550000032D50350007FCEEA8F9877CD +:102F8000AC0938030E0188C7AC10A431AC11FCA009 +:102F9000FC61EB65F081EB40048F800EE220F60FC0 +:102FA000E80484043E07F3CC2E07F3CCC0048E0162 +:102FB0003E07F3CCEB15422300730001001880E2BA +:102FC000960EC857B4025A000455400198808C0CE4 +:102FD0004091988004107FFF1C107FFF4C907FFC75 +:102FE000A03F3C1C00C244A2EED438108101382519 +:102FF0001901E241E803381519093C1C00C838C022 +:10300000820214C48000000380435A0009335EF238 +:1030100081F4E82FB001816449FFFC0C5EF001F5FA +:10302000E928840A42160024040480038446FE141E +:10303000E220E81F2E07F3CCC81CEAF4B401EA2909 +:103040005A08010B38051901E609E906EB63380552 +:103050009A0A8403D509B401EA29C80B440001F493 +:1030600038059A0A84063804180884091003804336 +:10307000FCE14440004C42019073000000435A00C0 +:1030800006045A08090C8823A608C0048E01AE085D +:10309000DD9E3C03F48B38010E0ADD9EFC213C6D65 +:1030A000FB28F381B4E6F3084273EC0B860A5A78E6 +:1030B000010386058843A7D0E2F0E8268CE144604E +:1030C000004CAFD0420198733D23F48E84C0106051 +:1030D0000043862A959A99CE43194424B7A7A6900F +:1030E0004C284013844110200043B001EB6A88C58E +:1030F0003A0300203C03F48BE004E8048C94B68788 +:10310000D5038C14B6072E07EE925A080105EA8AF9 +:1031100038008E0AFCA1FC0194DAF0818843224138 +:10312000000022FF8002E08FE80A3C0DFEAB025057 +:103130000009FE23848A4202907397032201000152 +:1031400022FF8003E00FE80A3C2DFEABFE03025194 +:10315000000A844A4202887396038823B4414200DD +:103160001001E002E80EEB1CE90450007FCEB6012E +:103170003C23F48D840AFE14B441E040E802B60119 +:10318000FC814430004C42010C7300300045CB0CF4 +:10319000A1073C3C00C8383192025EF19771E90406 +:1031A000846110300045003000455A38010F3C332F +:1031B000F48C40208840842AFE5CB462E061E8051B +:1031C00000000043C802B622DD9EFC01F006EAB80A +:1031D00042200473001100435A18083000110046C1 +:1031E00088A05A18031AEB799A61E435E915A668A4 +:1031F0005CF08064E8038C21AE68A668E635E91DC2 +:1032000040018040B4203C23F48BE041E916E42BDC +:10321000E9148E21D511A668C1048E21AE68FC8107 +:1032200040018040B4208A814E4400083C23F48B46 +:10323000E022E8038C21B620FC8122200000E0225D +:10324000E819FC003C4DFEAB846A02520009FF8B7A +:1032500042628C73E046E81022200001E022E80C74 +:103260000202000AFE4B42100C73E0415607800137 +:10327000FC808401DD9E8401FC80FC004430004C15 +:1032800042110C7380C1441001F449FFFFD81003B0 +:103290000049FC80FC01F08140108840EADB22FFFD +:1032A0008002E06FE80A3C0DFEABFEDB0220000965 +:1032B000840A4231007396DB2200800122FF8003E2 +:1032C000E00FE80A3C1DFEABFE030220800A842AC0 +:1032D00042010473960342000C01FC81FC21F08141 +:1032E000EB154212007300008049C821227080044F +:1032F000C7123C6DFEAB840A02530009FF448EA145 +:103300004C72800A22508005C5060263000AFE3412 +:103310008E01D80D8402100080498406380190087F +:10332000443002583831120A10008043FCA1920048 +:10333000FC21F608F48195328844B4E2E0E1E830FB +:10334000EAB842030473842B10100048B0413A10CD +:10335000840088853A120420EB79E027E802B6223F +:1033600084203811980800100043E62AE81944F137 +:103370003178EB38EA78DD0F0A0E262616261A2653 +:1033800026128423D5088422D506842AD5048425D0 +:10339000D502842710100043842110100046FCA1A0 +:1033A0004420004C42008873001000465A18030560 +:1033B000842810100043DD9EFC6180E2812180455D +:1033C000802480C5F08181638144F872EAB8427339 +:1033D0000473001380485A180B213825990150F1C5 +:1033E0000096E20FE8048400100380440003804448 +:1033F0005A08011495B28926B001802949FFF9FEC7 +:103400005CF000E1E80788CA3A0480003A03002033 +:10341000FCE1840010038044FCE1FC61F610F081C3 +:10342000EB1542330073818200218046816481451F +:10343000F70E048F800F81235A2801610001804319 +:103440005A08020CF80E5A08010684001001804444 +:10345000D51C10218044D5195A0003185A080511AB +:10346000EA89B400EA2983FF5A08010684001001A2 +:103470008044D5031021804444D0012CD5085A0043 +:10348000070585A05A080A0444D001F48440440288 +:10349000CBA440E3080838201909882E40043800DE +:1034A0003A1084003A100420F0018028804649FF39 +:1034B000FEF3E20DE808960140139820C80284014B +:1034C000AC08D50338D3990940363800A458EB84AA +:1034D000A4D99A41EA54964B4422CB748A033811FA +:1034E0001A099603884EAC11FE0442008473EB1E49 +:1034F0004412CB44EB358402EBC200148048000434 +:1035000080465A100B04480000B444E2CBA440D3D8 +:10351000080845C2CB445A08030A8400380E1A0A28 +:103520003803990138071909D53500048044C810BB +:1035300040143400B00149FFF961EB1E381719013E +:103540009601E2203C0BF9A8E803380719094073FB +:103550009820A43838171901E220E9074412CBA4B7 +:10356000380099098403EBC24025B400380E1A02D2 +:10357000B422E020E80FA4F8381719019A59FE0C7C +:10358000EB7940000C16E001B602E8048403EBC2BC +:10359000B62238159A028405FE0CE20AE80A4006B3 +:1035A0003400021F8002AC40021F8003AC41FCE1EA +:1035B000E141E97340B6340022D58000220F800239 +:1035C00022C580018A0D225F8003424000038AAC3D +:1035D000C40842328003844AFE9C40911136D502D1 +:1035E000812442600424FE6C406328D640A0A95682 +:1035F0009B868AAA8405FF84FE2C84E4EBE4407059 +:103600001CF642039C2442031873EB1E5014FFFB6C +:10361000E630E818E40BE9238F29E723E822E40FDA +:10362000E8204203000342138003E020E805FFC4C2 +:10363000407384F6D516E001E814FF8C406300D691 +:10364000D510E40AE80384E080C79C35E60BE80265 +:1036500084C09C3DE60BE80584E0D50384E080C788 +:1036600088CD88EC1265800012758001FCE15A0853 +:103670000215EB79E02AE9114422CB4438011A0201 +:103680008E0138011A0A40659840B4068E01E001A7 +:10369000B606E8038403EBC2FCE1FC63F08422007D +:1036A00080003C0BFAF6220080013C0BFAF7F7048D +:1036B000EB15427180738162B42780C3EB9444821E +:1036C000CDC44492CD6440A188085A1801408400BA +:1036D0004422CDD038010C0838040C083C2DFD7B69 +:1036E0004432CD9438219A0A38249A0A3C23F48E25 +:1036F00010138047842AFE54EBDD38111A0A441255 +:10370000CD2838009808100380431003804410032C +:103710008045100380463C4C00C884004412CC68AD +:10372000A0FF4020280038320E028C01EAC05A085F +:1037300004F984204402EED4EBEA80464402CDDC56 +:10374000F10449FFFD9C4800009844C2CC38441263 +:10375000CDDC4006280049FFF851EB1EF085840CB3 +:10376000100380480003804380ECE602E81DF0046B +:103770003C3DFD7BF4054452CD94B6DF4412CD347C +:103780004422CDD049FFFC8CF00480464412CD3455 +:1037900049FFFCF9EAEB4412CD344422CD94806613 +:1037A00049FFFCBBD5239E42E622E9085A000507E3 +:1037B0009E47E622E9035A080A1AF004802649FFC8 +:1037C000FDF1EAEBF104EBDD4432CDC4808649FF24 +:1037D000FD87B6DFEAEB38149A02F2044432CD34A6 +:1037E000F4054452CD2849FFFCF24442CD34F5059E +:1037F000B71FEAEB4412CD94F2044432CC68F68150 +:1038000049FFFBC8F0044412CDC4EBDD806649FFDC +:10381000FC3244C2CBF0F004F105EBDD4432CDC400 +:103820003C4DFD7B4452CD944482CBC0B6DF49FF72 +:10383000FD81EAEB4412CC08F204806C808880A6FB +:1038400049FFFDBCEAEB4412CC0814CF8000148F72 +:103850008001F6824422CC38F3044442CD34F5058D +:1038600049FFFDDD38039A0188EA38049A09A479F2 +:103870004004A800AC4138049A018949120580002F +:1038800002050001120580013C1DFD7B4402CC08AD +:1038900038101A0A38149A024402CC3838101A0A1E +:1038A000FCE3FC602240800022508001EAB8420123 +:1038B00084734472CB10B4C0411188083C1DFEAC27 +:1038C0005A680112AD10AD51A60DF8DC5A00010482 +:1038D000480000E54472CAE0840038038E0988F18C +:1038E000AC39FCE001208005013000185B28013E66 +:1038F00054098002C03A4402CAE038600E118811AF +:1039000022000001CE05C03138438E11D52EC806E5 +:103910004003C40022500001D5284013C400EA86A9 +:1039200053030000FF8C38138E11814442600475EC +:10393000424840244210002442B04024409090006D +:10394000424228244245947542401875FE024200C6 +:103950004024FE6C42102873421818754042249689 +:103960004010A4369723974B54098002C07C3C0D2D +:10397000FEAB802402600009E086E90839338E112D +:10398000E1E6E80F51337FFFD50C4E440008393390 +:103990008E114F3500078660D50482648520D502DC +:1039A00085210300000A8005E0B0E90A4093C400C5 +:1039B00022948001E130E81150987FFFD50E4E54DB +:1039C000000A4093C40022A480018520429524016E +:1039D000D5045A980149812538A38E1140B3C400FB +:1039E00022B5800140D2280140C2AC014ED2000C69 +:1039F000840240E9A8014006801642073073400067 +:103A00003416880B4EC2000C842240E4AC014016F0 +:103A10000436421734734010B036882A4C95803BE8 +:103A2000E026E9055263000188C1D5044E14003335 +:103A3000FF8A4D35000DE010E9055308000189802B +:103A4000D5074E04000553000000D5028600E1862C +:103A5000E805404980119743D506E0D0E804970B6C +:103A6000405480115B28010F38138E014402CAE0D4 +:103A70009A6138100E094013C400A44988119A694C +:103A8000AC4138438E0988F1AD7983FFAD10AD515B +:103A9000FCE04D353FE984C0D5CFFCE0FC6380C03D +:103AA000EA735A00010E3CBDFEAC3C0DFA5E0215F5 +:103AB0008005E201E8178C013C0FFA5ED5133C3D0E +:103AC000FEAB8006842000218009E222E8EDB440AC +:103AD0005A280406A484AC82A485AC838C21EB080C +:103AE000D5F3840084E03E07EE925093000844C270 +:103AF000E9E085AA85CA81073CADFEAB0005000957 +:103B0000E2E04EF200BD0404FFFE4E0200B25A088D +:103B10000504480000AE02048002EA9F020480030C +:103B2000EA8DB0458047800649FFF6A4F083B04592 +:103B300000058001B61F8041800680673C4DFA5E1B +:103B40003C5DFE7E49FFF82AEAF4B401920596171F +:103B50005A000105B401EA29C82F0206000450F0FA +:103B60007FDD5CF785FBE9190206000550F07E0B4E +:103B70005CF78617E812EAF85A08011004260007D5 +:103B80003C1C00C238108901E62BE8072E17F9F417 +:103B9000E62FE8033E07EE922E07EE925A0801093F +:103BA0002E07F9F45CF00064E8078C01D503EB40C4 +:103BB000C8033E07F9F4020F800A42003424EA9F4A +:103BC000020F800B42003424EA8D00058003C008F8 +:103BD000B045800680418067F40349FFF8B80005CE +:103BE0008004C008B045800680418067F40349FF27 +:103BF000F96800058002C007B045800680418067F3 +:103C000049FFFD4D220F800AB0458C054000381653 +:103C1000EA9F220F800B80418C0540003816EA8D08 +:103C20008067800649FFFE3F220F800A4E04000491 +:103C3000128F800A02050009221F800AE020E90392 +:103C40008E01EA9F220F800B4E040004128F800B1E +:103C50000205000A221F800BE020E9038E01EA8D95 +:103C6000020F800AEB0E020F800B120480018CE120 +:103C70005094804C50C6004C48FFFF40EA735A08ED +:103C8000011380068420D50BB4408E44E642E8053B +:103C9000A482AC84A483AC858C21EB0800250009A8 +:103CA000E222E9F3004500093C37FCFC3C27FCFD1F +:103CB0003C1DFA5E8400D50CB4A65A580507223381 +:103CC00000042223000584208C015063004CE20490 +:103CD000E9F43C3BFCFC3C2BFCFD3C1FFA5EFCE3A6 +:103CE000FC41F481411200114102400A0040005A97 +:103CF000226080009724EA868641C4073C6BF96EF7 +:103D00003C1BF96DEB3CD517B4805A4803193C7D38 +:103D1000FCB43C4DFCB588272E77F2D888C48CE1E2 +:103D200097F8E6EFEB3CEB8A3E77F2D8E945EBE417 +:103D3000EB3CEAB9EB8A3F27F2D8D53E5A48013B23 +:103D40003C7DFEAA3D37F96EA7383D27F96D5A48EC +:103D500001654049980142F2000302938004404902 +:103D6000040142420003888F40948408E324E8550C +:103D70000293800340748408E1E7E803E0C7E86049 +:103D80003CADFEAB024500098E818A899521E09306 +:103D9000E803E086E855E1C7E803E027E85102754B +:103DA000000A8EE18AE995F9E0F2E837E0E1E848B7 +:103DB000D534EB3CEB8A5A58012AB4005A08012743 +:103DC0003C1DFEAAA40DE260E8213C0DFCB53C4D73 +:103DD000FCB44030440142F18003A54E4032400122 +:103DE000EB4B886F9569E065E811A4CF9F594202BB +:103DF000C4734242C0734011840988018824400082 +:103E00000C16EB1B3C0FFCB5EB8A3C0DFCB5AC1063 +:103E10003C0DFCB4AC11FCC13C7DFCB43C4DFCB58C +:103E200088272E77F2D888C48CE197F8EBE43E77A8 +:103E3000F2D840709CF6EB3C3C7FFCB4D5BD3D3FD6 +:103E4000FCB53D2FFCB4D5B8FC2004600011EAF9A4 +:103E5000EAC1FF76446100002270800022408001A8 +:103E60003C3DFCB23C1DFCB3D604B4005A08010A28 +:103E700084003C7FFCB33C4FFCB23C0FFCB1D53A14 +:103E8000978B975B41139801410214013C1DFEA9D9 +:103E9000420880034238000388600200800E3C3FE5 +:103EA000FCB1E060E8230010801E80E09F094272B0 +:103EB0000C73FE0C80674213C4244040040A4F1563 +:103EC00000048824D5028A244010803688263C1FAE +:103ED000FCB34211C0244F0500048824D5028A2473 +:103EE000EABE88053C0FFCB2D5053C7FFCB33C4FD5 +:103EF000FCB23C0DFCB3AC103C0DFCB2AC11FCA010 +:103F0000FC2022608000225080013C7DFEAAEBD282 +:103F10003D27F9603D07F95E0243800EC10E3C3D2E +:103F2000FB48842A403184770413800996D9EB1B1F +:103F30000433800AFE5CD51150137FEC96495CF087 +:103F40008C58E80A5012FFEC96495CF093D8E804CC +:103F50000013801ED502EA70B4005A08010A8400DA +:103F60003C6FFCB03C5FFCAF3C0FFCAED532411364 +:103F700048014072C00142088003423380038860D8 +:103F80009521E0643C3FFCAEE8209E0980A44250AD +:103F90000C73FE6480654202C4244040840A4F15BD +:103FA00000048804D5028A04EA8F88123C0FFCB012 +:103FB00042019C244E7500048804D5028A04EACB91 +:103FC00088303C1FFCAFD5053C6FFCB03C5FFCAFBC +:103FD0003C0DFCB0AC103C0DFCAFAC11FCA0FC20C7 +:103FE0003C6DFEAAEADB0073001023008001CF02C3 +:103FF00084E1EBD2C1113C1DFB48848A401090370C +:10400000044300099649401204370443000AFF0C98 +:104010003C4FFCA7D5060213000994493C1FFCA79E +:10402000B4205A18011384003E07F28C3E07F28A2E +:10403000020300093C3BF94C94013D0BF94B3E1740 +:10404000F29A3C0FFCA7D5553D17F94B3D37F94C7B +:104050004048C00140098C01FF24424000733C0DE0 +:10406000FCA74522CA7CE2802E57F29A8400E9021E +:104070008401380914089E39D80884003E07F29A52 +:1040800084013E07F28AD5048CA13E57F29A2E177E +:10409000F28AC90C2E47F29A8001E204E8313859BD +:1040A0000000CD028C218C01D5F984808004E207C8 +:1040B000E80738590000CD028C818C01D5F95A18D7 +:1040C0000109E087E8060203000A94013C0FFCA7FF +:1040D0009A7CFECC42324C734210C024421244738C +:1040E00040319C763C3BF94C40009C163C0BF94B14 +:1040F0003C03F94CAC103C03F94BAC11FCA09B7C8D +:104100008A8188A1FEE44232CC73420240244202FA +:10411000C47340319C763C3BF94C40001C16D5E7FB +:10412000FC20EBC522408001EBD23C3DFEAAC1053C +:1041300000618022FA24D5165012FFCE96495CF019 +:104140008C1CE80750127FCE96495CF0939CE906E0 +:10415000021180108C239648D50300118020006145 +:104160008022B4005A0801073C5BF9443C4BF943F8 +:10417000D52D3C37F9433C07F9448A648A05FEDCB7 +:10418000423000739409FE042E77F285E2605A787B +:10419000010DE91E84003E07F2853C5BF9443C4B6F +:1041A000F9433E07F284D514E8082E07F284E206AC +:1041B000E8048C013E07F2842E07F2843C5BF9444C +:1041C000E2063C4BF943E90484013E07F2853C03D7 +:1041D000F944AC103C03F943AC11FCA0FC00B480E2 +:1041E000EADBEA865A400503CC0AFA0E3C0FFCA033 +:1041F000841F3C0BF93F3C0BF93ED5375A4801165A +:1042000000000045C8063C0DFCA0C80A8405D50284 +:10421000FA0E3C0FFCA03C3BF93F3C1BF93E3C37FF +:10422000F93F3C17F93ED5213C4DFCA0C4048E81DA +:104230003C4FFCA03C4DFCA0C418000000455A08AF +:1042400001063C3BF93F3C1BF93E3C57F93E3C47DD +:10425000F93F9A299BA3FE04420318735EF003E81A +:104260004012BC1B40323C1BACD0AC51FC80FC402B +:104270003C9DFEA922408000005480162230000898 +:1042800022700009EA868621C506E6A98628E80389 +:1042900041128013005480178601C506E6A98608DE +:1042A000E80341028013B5405AA0010A040000113E +:1042B000EAF9EAC1FF4644010000D81784003C0F28 +:1042C000FC9E3C0FFC9D84013D1FFC9C3D1FFC9B04 +:1042D0003C3BF9263C7BF9273C4BF9163C1BF91774 +:1042E0003C0FFC8A480000B05AA80304480000AA0A +:1042F0003C0DFC8A51287FFF8C01420040013C0F9D +:10430000FC8A3C0DFC9DE012E8038C01D502840080 +:104310003C0FFC9D3C0DFC9E3C5DFC9DC8064C5931 +:10432000400584013C0FFC9E4462CA3C942A413300 +:104330000000127980014532CA1C38499609881359 +:104340003C4DFC9C38331609AC413C4FFC9B4E570E +:1043500000099E6938030611406304409AC3D506DC +:1043600038034A11406348409AC3221300014201B6 +:1043700080038A27EB640264800D8801E2C08026F6 +:10438000E9060214800CE20140103C1A3C0DFC9E30 +:10439000C8043D1FFC9CD5105AA0040F0204800CD9 +:1043A000403844018A20FE5C9A3040008017400863 +:1043B00000013C0FFC9C3C0DFC9C8423806442303B +:1043C0008073842480038C02EA8FE080E9043C0F30 +:1043D000FC9CD5048C813C4FFC9C3C0DFC9CE0116A +:1043E000E8043D1FFC9CD505E180E8033D0FFC9CE3 +:1043F0003C0DFC8A3C1DFC9CE001E8033C0FFC9C4E +:1044000084203C0DFC9C80C180814C100010383908 +:1044100096118883403994402231800188C3C503B6 +:104420008EA1D50280B28C21D5F1846240008C1619 +:104430008880880640420496EACB9723964BD503A2 +:1044400084208081AD10AC51FCC0FC6B80C0EAF9C7 +:1044500004000011EAC1FF4644010000D804841F93 +:104460003C0FFA5D3C1DFEA93C0DFA5DA44DE20136 +:10447000E8048C013C0FFA5DB4064E02014B5A0869 +:104480000504480001472E0001C4C00C2E0001C6DF +:10449000C0092E0001C55A001F062E0001C75A0888 +:1044A000310A00030045C8060003005A96044E0274 +:1044B0000137021300180203000E449000648A01C1 +:1044C0009603EB7E021300190203000F85418A0157 +:1044D0009603EBDEEB0F96039001EB7EEAEF96037B +:1044E0009001EBDEEAB6960BEAB6023F8001964BEE +:1044F000022F8001FE44421188738403964B84414D +:10450000F82E80E0420024244410005AEACB97F9A8 +:10451000FFFC964B84418400F82252139FA41003A1 +:104520000078964B84418403F81AEAB642B028001A +:10453000964BEB644210A424804A4010AC368402AF +:10454000964BF80D023F800180E096DBEB4B423149 +:10455000A42484024011AC36804A964B49FFF1EE08 +:10456000EAB6964B4E160005FE7A974BD50280A709 +:10457000021F800112530012964B4E160004FE02D9 +:10458000960344418DCC8044B0C23B014804802353 +:104590003B00C824120300130291000044218DDC6B +:1045A000129080008262B0463B09C80480E13B0360 +:1045B000C8240339800013338000B1CA3B02480489 +:1045C00080873B02482412920000509F80383B01B4 +:1045D000480480493B01482413310000513F804882 +:1045E00044218DEC3B01480480933B024824A49075 +:1045F000ACA0002300785CF10028E9575CF10032A0 +:10460000E803EB19D5034440006D4302800342A048 +:104610000003402828019693EB5096938621392970 +:10462000C511E1C2E8058DA141188013D5F9864D69 +:10463000431944015128FFFFE15041290013E903C8 +:104640008209D50380E182033899C91138184911CC +:104650008A4996D13829C51141312401382845119C +:104660003903C9118A41FE9C969340214C568841DA +:104670003813C51196938A30FECCFEA4965B403069 +:10468000CC76887096DBFF1C4470006440211C5679 +:1046900040421C9642128824FE24EAB940001C16AF +:1046A0001213001212030013EB0F96035EF0005179 +:1046B000E903EA58EB7EEB0F96035EF07FB0E80467 +:1046C000440FFFB0EB7EEAEF96035EF00051E90382 +:1046D000EA58EBDEEAEF96035EF07FB0E804440FA1 +:1046E000FFB0EBDE02030012B041EB0C020300133B +:1046F0008041EA55800649FFFDBCB04180068041FB +:1047000049FFFBA4EB8412030014EA5412030015C2 +:10471000B4065A08050584003C0FFA5DFCEBFC402A +:104720003D2DFEAAEADB00690016EA86C605E6C949 +:10473000E80597B1D50484C1D50284C800490017A3 +:10474000C405E689E8059721D5048481D5028488CB +:10475000B5E084A05B3801123C5FFC893C5FFC88BB +:104760003C6FFC873C6FFC863C3BF8FC3C1BF8FD37 +:104770003D3FFC7D480000AC5B380304480000A6C8 +:104780003C0DFC7D51027FFF8C01420010013C0F6B +:10479000FC7D3C0DFC88E010E8058C013C0FFC889A +:1047A000D5033C5FFC883C0DFC893C5DFC88C80659 +:1047B0004C58400584013C0FFC894472C9E8400311 +:1047C00094403D1DFC8738339609AC413D1FFC8663 +:1047D0004E57000C5092FFFF3803A6114093A4409F +:1047E0009AC322048001D5083803C2119AC340033A +:1047F000C040220000019A41EB4BEB648823023950 +:10480000000D94D9E2618003E9060209000C9401CD +:10481000E220EB743C1DFC89C9043C6FFC87D51079 +:104820005B30040F0219000C412084088A129A663A +:10483000FE0C8A7240000C179A203C0FFC873C0D3E +:10484000FC878423807142308073842480038C022F +:10485000EA8FE1A0E9043C0FFC87D5048DA13D1F40 +:10486000FC873C0DFC87E006E8043C6FFC87D5051F +:10487000E080E8033C4FFC873C0DFC7D3C1DFC8741 +:10488000E001E8033C0FFC8784203C0DFC8780C1DD +:1048900080814C1000103833961188834033944047 +:1048A0002231800188C3C5038EA1D50280B08C213E +:1048B000D5F1846240008C1698E0880640318476F9 +:1048C000EACB96DB964BD50380258065ACD0AC5106 +:1048D000FCC0FC40B480EADB227080013C1DFEAAD3 +:1048E0005A480113ACD0ADD1A60D3C3BF8F83C7B47 +:1048F000F8F95A000104480000CD84003C0BF8F69A +:104900003C0BF8F7FCC0A78D0100005A5A6801352E +:1049100054080002C0313C47F8F63C07F8F7CC05D4 +:10492000C02B3C37F8F8D5283C17F8F9C80380E1CC +:10493000D523FF62FF0C3C17F8F882434240047510 +:1049400042329424421000244330142441108C003D +:104950004231C82442399C7542301075FE02FE2C4B +:10496000FE7C42104873421290754031C47640106C +:10497000C43696DB97CB54080002C06E5EF18C8083 +:10498000E9093C57F8F85EF28C80E80F44500C7F40 +:10499000D50C4E3400083C57F8F84E55000784A05B +:1049A000D50480A38400D50284015EF39400E90756 +:1049B0003C47F8F95EF21400E962D50C4E74000829 +:1049C0003C07F8F9848042401001D5045A0801459B +:1049D00080873D17F8F83D07F8F940F1C4018023BE +:1049E00080074123C001E80B84024092C4014007C4 +:1049F00080164204C87340003C1688104F22000CF9 +:104A0000842240924001401904364214BC73401085 +:104A1000C83688314C48003A5EF08C80E904510079 +:104A2000F381D5054E140032530080004C58800E9F +:104A30005EF01400E90451106C01D5054E0400230A +:104A400053100000E1B0E80496EB97C3D505E1915F +:104A5000E80396CB97E35A68010C3C03F8F89A18E0 +:104A60003C0BF8F63C03F8F99A383C0BF8F73C3B62 +:104A7000F8F83C7BF8F9ACD0ADD1FCC0444013FF52 +:104A8000D5A94F02FFEAD5E186004C58FFD3D5E403 +:104A9000FCC0FC2180C0EAF904000011EAC1FF4615 +:104AA00044010000D80984003C0BFCF83C0BFCF9E5 +:104AB000841F3C0FFA5C3C7DFEAA3C0DFA5CA47D91 +:104AC000E201E8048C013C0FFA5CB406C06C5A00A9 +:104AD000056B0203000AB041EB0C0203000B80419E +:104AE000EA55800649FFFB7CB041800680413C3D91 +:104AF000FA5C3C4DFE7CA77949FFF8F4A63AC00663 +:104B0000B0418006804149FFFA6CA63BC006B04127 +:104B10008006804149FFFE05A63CC006B0418006E4 +:104B2000804149FFF9EFEB4C5A00010A2E07EBCA0E +:104B30005A0001062E07EB8E5A080107B041800685 +:104B4000804149FFFAEF0003005A960EC0070203A6 +:104B5000000AEB0C0203000BEA55B04180068041CD +:104B600049FFFEB9220F80024E0400048400EB0CC2 +:104B700022FF80025EF78C80E90444000C7FEB0C7E +:104B8000220F80034E0400048400EA5522FF8003B4 +:104B90005EF79400E904440013FFEA55EB84AC3659 +:104BA000EA54AC37B4065A08050BA4363C0BFCF8A3 +:104BB000A4373C0BFCF984003C0FFA5CFCA13C0FD1 +:104BC000FEE7DD9E3C0FFEE6DD9E4402D3388421E5 +:104BD0003C0FFEBB84003E07FAF03E07FAF13E07A9 +:104BE000FAF23E07FAF33E07FAF4EB973E07FAF6BD +:104BF0003E07FAB93E07FAB83E07FABA3C1FFA5F19 +:104C00003E07ED3F4412D2E88400845FEB028C0142 +:104C10005A084FFEDD9EFC00EB9BFC80FC0080C030 +:104C200049FF99A6C0048400AE34AE35FC802E073F +:104C3000FAC0DD9E2E07FAB4DD9E4432D2A8AE182B +:104C4000AE59AE9ADD9E3C0FFA5FDD9E3C0DFA5FD9 +:104C5000DD9E3C0DFB4F465FF00FEAC1FF4646006C +:104C60001000D80684003E07ED3F8401DD9E8400DD +:104C7000DD9E2E17FAF22E57FAF3EB094C12C010F4 +:104C80002E27FAF05A28010CA6059D49400280B64D +:104C900097683E57FAF23E57FAF3DD9EA6058CA1BF +:104CA000400280B697683E57FAF3D90484013E0764 +:104CB000FAF0DD9E2E57FAF22E17FAF3D9042E07DA +:104CC000FAF0C00FEB098CA1A605400280B69768E8 +:104CD0003E57FAF24C12C00584003E07FAF08401F8 +:104CE000DD9E2E57FAF22E07FAF3D8072E07FAF0B8 +:104CF00084208E01EB48DD9E8401DD9E2E57FAF262 +:104D00002E07FAF3D8072E17FAF0840040000406A5 +:104D1000DD9E8401DD9EFC0084A08C81E2A4E80776 +:104D20003860080438608C0C8CA1D5F9FC80FC61DB +:104D30003CADFA5F84BF81608121B4C1105F800700 +:104D40005AA001044800009B84E03C3DFEE62F177A +:104D5000FAB43D2C04363D3DFEE7802A44C0004CA9 +:104D600081A781C7850686029E89000180099690E9 +:104D7000E240E81243413024B40B41505000B415D6 +:104D80009E81E642E9035A08047604058003B400D4 +:104D90009E81E642E808841F1003003E1003003F96 +:104DA000480000865A0004F9DD5A5A0802052E0010 +:104DB000114FC8F25B1801045B2005EF0009800366 +:104DC000222A8004224A8005037180020361800345 +:104DD000C01702018009518BFFFF8E0140F041F6A0 +:104DE00042F16073518B7FFF402780560201800A99 +:104DF0008E0140F041F642F2607340478096E057E2 +:104E0000E903502BFFFFE09642013400E903504BC9 +:104E10007FFF81E642F3A073844240210464424252 +:104E20003800102780004020100A102780014022FF +:104E3000100A10278002971F40420084020A800A4D +:104E400010478003C006B44B885400010014D502FB +:104E5000840110078004020A800BC0039600D5026B +:104E600084018CE11007800597F81053003C105323 +:104E7000003D8C21964848FFFF792E77FAB8C71776 +:104E80002E07FAB95A001913E61EA670E8059657C0 +:104E900040008064D503440000F0AE302E07FABA1B +:104EA000AE328401AFF13E07FAC084E02E07FAC0AB +:104EB0005A00FF0DC00BCF0A841F3E07FAC03C0DFD +:104EC000FEAF8C013C0FFEAFD5033E77FAC05AA867 +:104ED00001153C0DFEE600400009E2E4E80E8426E0 +:104EE0008406FE7C8A87B449FF0496488822EB52E8 +:104EF0008440806A8E81F944B409842080A05020C7 +:104F000000400832800188239648DAFCFE4A1010DF +:104F100000405AA00104480000CC04058003B420DE +:104F20009E89E642E9055A100404480000B922307F +:104F30000006221000075EF18C80E80584404231B3 +:104F40008800D50344300C7F5EF09400E80584406F +:104F500042108800D503441013FF000000725A006D +:104F600001048401D503440000F0EAD20425800343 +:104F70005A08F02E840010010072041580034420AA +:104F8000FF000400801404308015401008029228AD +:104F900010130042401060091013004446100FF037 +:104FA00010030043FE0E9210FE9EFE5E10030045AD +:104FB00092484001E0099230102300461033004728 +:104FC00010030048101300498489D55F4001A00AEE +:104FD000100300424000A00A1033004310030044B5 +:104FE0001013004500010043C80702010025C8094D +:104FF00002010026D5045A0801058400120100258B +:10500000020100253C3DFEE7401020091013004638 +:1050100010030047A618C00602010014FE02960302 +:10502000D50322010014A659C10602110015FE4A3B +:10503000964BD50322110015A6DACB0610030048C3 +:1050400010130049D50510130048100300498400CF +:105050001003004A000100431003004B84001003BA +:10506000004C000100415A0001085A0002085A0889 +:105070000309EAE2D507FA10D50544000040D5023D +:10508000FA001003004D848DB4495012004188226B +:10509000EB52844084615242000DD518B429EB5282 +:1050A0005010804184408461848DF86AD5125AA8DA +:1050B00003112E07FAB95A0819F3EAD2B429EB52B0 +:1050C0005010804284408461848CF85A8401D50257 +:1050D0008400B4498420505100415031004E0842B0 +:1050E000800188249648DBFCFE4A1011004E2E17E2 +:1050F000FAB45A10FF0AC108C807841F3E07FAB461 +:10510000CF078401D5063E07FAB4CF02C0FB840066 +:105110003E07FAF6FCE1FC00844180624440004E08 +:10512000F82FFC80A60092038C1596275C000014D3 +:10513000DD9EFC4080E08400EB97A63880C1C80467 +:1051400000038008C0312E07FAF15A08010C2E170F +:10515000FAF43E17FAF23E17FAF384203E17FAF0FB +:10516000EB9749FFFD88EB092E97FAF3A7043C1D46 +:10517000FEBB8441A0394214907380628E8149FF46 +:10518000FDCC2E07FAF65A0801063E07FAF13E97C3 +:10519000FAF42E07FAB55A00FF058C013E07FAB55E +:1051A0008401EB53D5033E07FAB52E17FAF5B40682 +:1051B0005A18012AA605C814F835C80DEB092E3770 +:1051C000FAF4A684B4263C0DFEBB42018873B421D8 +:1051D000F839D50849FF969DF825C8FFD5F0F82283 +:1051E000C802F845B4268400EB973E07FAF1840123 +:1051F000AE0DB426AE0CB4C6B406F8345A08013D60 +:10520000AE37D53AA644C904F868C036D50BA60512 +:105210005A080106F807C830F82AD52E49FFFD6361 +:10522000C8FA49FF96A980E0C82749FFFD45EB0968 +:105230002E97FAF2A684B4263C0DFEBBB42142049C +:10524000887349FFFF6A2E17FAF15A1801112E5779 +:10525000FAF44C54C00DB4063E77FAF1AE45B4E60C +:10526000B40749FFFF615A080103AE3F49FF969416 +:10527000B4068421AE44FCC0FC20804080E144029E +:10528000D2C8A051B6202E17FAC0EBD7A052A84121 +:10529000A053A8432E17FAB44462D2E810100010AD +:1052A0004412D2C43C6FFEB549FFFD434402D2B85C +:1052B0002E17FAC0AE402E17FAB4EBD7B4273C1F16 +:1052C000FEB14412D2B4A98149FFFF3584204402C3 +:1052D000D2A8AE40AE41AE4249FFFD12FCA03C0F49 +:1052E000FFA2DD9E3C0FFFA1DD9EFC6051FFFA286E +:1052F000F385506F83388460F182F2863C5DFFA1B4 +:10530000802686018223F202F284E262E82A2240A9 +:105310000000222000011240800A1240800CF40597 +:105320001220800B1220800DA081A1241420800B5C +:1053300040220820A7D1C70BA72A8E814C720008F3 +:10534000A710C405A6AB8E414C4140051100803525 +:10535000D503111080358C61501080388C08D5D45D +:105360002E17FE808400F18150EF80388040509FDE +:105370008068511F8098510F80C844700038EB2B13 +:1053800042301C243827020A99733824820A3828AC +:10539000820A3828020A88648C011022802A10218F +:1053A000802A5A080CEFF0023C3DFFA2E20180E6A1 +:1053B000856014FF800386FF4781000086CA47E9A5 +:1053C000000045902710F002E3604EF200DF8401F8 +:1053D00038072E0AB03E41002C4085804402D3C8D5 +:1053E00040F604064EF200CDF2032243800CC209BF +:1053F0002220000E2250000F8A822223800DD50821 +:105400002220000C2250000D8A822223800D8A4522 +:10541000FE94422210732343800C2240000C23533D +:10542000800D412A10012240000D04800009413AFC +:1054300090014259CC2442594873B5405A88040718 +:10544000004000285A480103F8610440000CCC5980 +:10545000A119E2A44EF3032DA51942451024E2A49C +:10546000E830A11AE2A4E80BA10404A00003424919 +:105470009024424928734E46031CD523A11BE2A465 +:10548000E820A104051000034249902442494473D6 +:1054900044D00064432234240111802741292A5733 +:1054A000432948244312C424432928244118B637E9 +:1054B00040F965F7E3AFE8054E4700044EA302F953 +:1054C0000040002901118000E3A4E805A11CE2A42A +:1054D0004EF302EF004180264E4202F5A11BFF244D +:1054E000E2A44EF202F05A880403F810004380351B +:1054F0004E4302E9004000354E4302E5885ED53751 +:105500005A400203F8035A880404480002DC04F1FC +:10551000800122A0000EE2AF04D000032240000F61 +:10552000051000044EF302C5005180288891428680 +:10553000942442589424408459164052D8B6404A84 +:105540009001894D40AA2801FF24FF6C4245287331 +:1055500042542073E0854EF202B64249C4244249C7 +:1055600034734E4702B0464800008844B65050C6D7 +:105570000001510800305000003848FFFF338D61B2 +:105580005073803848FFFF2184008441E201E80520 +:105590003824820A8C01D5FBF002E60BE80AE62BE0 +:1055A000E808804E8069B13EB148490003BAD50889 +:1055B000F002804E8069B13EB1484900036F3C1D46 +:1055C000FFA24658FFFFF183442000388420504258 +:1055D0008FFF806144D2D3C8870CF487810251EFDA +:1055E00080C88541519F8098868286E3E26044B2FC +:1055F000D3C84EF200F6B10840520C20A76980EDE6 +:10560000427288730473800C5A78020F38720D004E +:105610004272E073B13E38721E024E75000638A425 +:10562000960A480000DBB10838720D00EB2B4242AD +:1056300088738206EB8001220036F4055118003091 +:105640005108002804B8000105320003F40338F9BA +:10565000AD0102B2001511288006E36FE80C4F235C +:10566000000B012800028481592900011128000241 +:10567000104880068206EB80EB2B4242887350F87C +:10568000001822B780012322000D22C8000C4125FA +:10569000C8012332000C436948241528000489CB33 +:1056A00013278003824741364C014322E07382B0C6 +:1056B0004369CC738224B13E1D6A800239224A02BA +:1056C000F407153A800189EC13378002E2925158B1 +:1056D0000010E80D8DB01548000C03088002130A75 +:1056E000800203088003130A8003D50484801448D1 +:1056F000000C8206EB2BEB804242887350B80010FE +:105700005132001022C980022325800223398003F0 +:105710008BCC15280001232580038BD30132002078 +:1057200011380020053200091528000251280020F8 +:105730005B38031701280036011200285B2801039B +:105740008FA1111800288206EB80808A011800289A +:1057500051080020404BC41B14480001D5031549D3 +:105760000001820D43028873010800345CF800C810 +:10577000E8048D81550800FF8246EB2B4323A0737C +:105780004242A0731109003401020029F4035119A7 +:105790000028A165B5D211088001E2B2E805E78AC8 +:1057A000E80C8D81D508F403A166E3C5E8064F0235 +:1057B00000058F8111088001F40480A68E81425378 +:1057C0008873F484F401005280208E8138AF160A69 +:1057D00038AC9E0AF4818C218C6148FFFF0984A0BB +:1057E0008069800B8145B1E644C00038852185A5DC +:1057F00085042E27FE80E2A23C2DFFA1E803F401E0 +:10580000CC0A8460860180068143822381108583CF +:105810004800009300F10009E22FE8F40D01800137 +:105820005B080179050000095B080308F20114A177 +:10583000FFFF8E41F281D56E8F81E782E80D050072 +:10584000000C5B080206848010400028D50AF4038F +:1058500001020001D504010000288F8111000028F9 +:10586000010000285B0801080110002A5918800473 +:105870001110002A0021001987C040FF0806E82304 +:1058800038F3FA02E91D38F77A02E91A804840260F +:10589000C01A1420000981E080463B07E404422F2F +:1058A00030733B0164243B07CC003B014C200020BB +:1058B0000020B13238920A0A3893FA0AD52551EFFE +:1058C0000001D5DC85E0D50350F780014CF10023C1 +:1058D0003843BE02CCFA80484026C01A1420000982 +:1058E00083C080463B0F64044227B0733B016424AD +:1058F0003B0F4C003B014C2000200020B13238927D +:105900000A0A3893BE0AF20114A1FFFF8E41F28108 +:105910008C218CA15000003848FFFF6DF404C47046 +:1059200001210009E232E86C38570E025A50010991 +:105930008C6150000038F402E264E9F1D561B126CF +:1059400038520E02CDF6B13238721602CF55F4033A +:10595000B6E0A9C1A9C2A9C3A9C40270000C127003 +:10596000000E0270000D1270000F99E1F405007333 +:10597000801C05320003F403105000201070002832 +:105980000490000B03220015CF0D3879A501E3C761 +:10599000E80415000009D50F14C000091080002884 +:1059A000D50A38F9A50114C00009E3CFE9048CE158 +:1059B000107000283879A501B132E3C780E840783B +:1059C000BC1A3902160AB1261070003639020E0AC6 +:1059D0000070002AF404587380018E811110003485 +:1059E000111000291070002A14A0000C38A70E0A0C +:1059F000F4848C21D59E8CA1E2B2E9A6D59A8400CC +:105A00004430004C808000110009E201E808421097 +:105A10000C24F5068C013842840AD5F684003E0732 +:105A2000FE808420509F809844A0004C44C00038E1 +:105A300000010019E220E84AEB055A080136047318 +:105A400000095A7005132E37FE80800B80A63B029A +:105A5000E4044201B0738C613B0064243B02CC003F +:105A60003B004C203E37FE8000030020F30642300E +:105A700028738003B6E30033002A10300018023385 +:105A8000000AACC20233000BACC30433000BA8C73E +:105A9000B46650400024B664A0F1A8E1A0F2A8E2E8 +:105AA0000433000CA8E38C2150630038D5C25A801F +:105AB0000303F806004000344E43FD5A885848FF5F +:105AC000FD571578000048FFFD5451FF85D8FCE0D4 +:105AD00084003E07FE80DD9E4402B5B03C0FFF9F70 +:105AE000DD9EFC6700608009230000022310000394 +:105AF000C6103C5DFFA1A6EA8E614C61800B0030B0 +:105B00008008C307A7AB8EC1FF9D5C630001D5026F +:105B100084C184603E37FBCAEAF904300011EAC14F +:105B2000FF5E447100004432D390DF0D84A53C5FDA +:105B3000FEF184A03C5BFDDC3C5BFDDD3C5BFDDA03 +:105B40003C5BFDDB3C5DFEF1C231C50485605A580B +:105B500005093C7DFF9F85610073801C3E77FBC873 +:105B60003C77FDDC41281C013C77FDDD40789C0141 +:105B7000FFFC427948735A500307C5055A50050483 +:105B8000480000873C4DFF9F02520011A508E2A487 +:105B90002E47FBC8E807A449E2A1E804C4038E81AC +:105BA000972084A3CC7684A1D5749E69E622E8056B +:105BB0003C1DFF9FA649D5095A5803043E27FBC840 +:105BC0002E17FBC8C1048E213E17FBC82E47FBC809 +:105BD0005A48010684243E17FBCAD5038425C40213 +:105BE00084243C1FFEF180C3803F3B036404EA7BB6 +:105BF0003B034C003B00CC203C7DFEE83CADFEE985 +:105C00003C9DFEEA3C87FDDA80B93CC7FDDB3D07E1 +:105C1000FDDC3D17FDDD2EB7FBCA2E67FBD58420CA +:105C2000B6205A50051EB6FFEBDA149F8002128F81 +:105C3000800A12CF800B130F800C131F800DF58983 +:105C4000104F802810BF802A106F8035803F3B00A6 +:105C5000E4043B01E4243B00CC003B01CC203E2784 +:105C6000FE78B6A010B0005A1280000412C00005E1 +:105C70001470001714A00018149000191420001AB2 +:105C80005A58010B1280001C12C0001DD50584A2B9 +:105C900081918110D5C5FCE7FC6081608220840081 +:105CA00082418120826084E1810044E000304F1213 +:105CB00000374F2200355A78013384C080E6855E74 +:105CC0004C65801E39011A025B08011841421840D8 +:105CD00086004D00801338D1C2025AD8010D42C847 +:105CE000382438CA300240F62806E805813082663A +:105CF00080ED814C8D81D5EE8CC1D5E3C7D9406252 +:105D0000802011330000109300019D8138814E0ADC +:105D100096303881A60A8FA18FC1D5CAFCE0FC60FD +:105D200051FFFD3080C0C06AC168E220E83080E1E8 +:105D300045100030865F82044303C4738400392811 +:105D4000020A8C014C037FFD8CE14C737FF68001CD +:105D500081C1802681A581448183816249FFBDF58F +:105D6000B02449FFBDF9800A49FFBE07801F49FFE3 +:105D7000BE108126840C84C049FFBE1C49FFBE1F93 +:105D800080A6862C443000308046D520E201E8E031 +:105D900084E045100030865F82044303C4738006AC +:105DA0003928020A8C014C00FFFD8CE14C70FFF693 +:105DB000D5CF40081000380F80005A00010F8D81A8 +:105DC0004D04FFF98CA14C57001A802A4242C4248A +:105DD00042128C738600D5EE3800C2025A07FFF1DA +:105DE000400698209DF111000000AF4197B838257A +:105DF000C20A3826160AD5E480C1800651FF82D037 +:105E0000FCE03C0FFFEADD9E3C0FFFE9DD9EFC60FD +:105E10002E27EE923C6DFFEA5A280106844AA8B16B +:105E2000FA4ED503FA44A8B1AEB0AEB15090FFFF20 +:105E300085823D4DFFE93C4DFFD83C2DFFD740C446 +:105E4000B1964532D7848C0C4432D7544472D7343F +:105E50004522D7408620850144A2D6A485AC85C4BE +:105E6000001A0009E3A14EF200D404507FFD4E5207 +:105E700000C800B0000C54158001C10B10898000CF +:105E800022100000AC5822100001AC59480000B9A3 +:105E90005A5004044800008200298000CA3B0019BF +:105EA00000005A100106A77880828022D51E015377 +:105EB000800040154440808280A286014C5AC00375 +:105EC000860222F080008CA142483C7322F08001BF +:105ED000976842283C73501080305A5803F0404273 +:105EE000389640213856D51882114300B4738C215E +:105EF00038F5421141054040230800019648888F3B +:105F0000E2A18850E8F28CA1404214964021145638 +:105F1000D50380418081421100034252000388A1D1 +:105F2000A071E225E86D54158004A770016300029A +:105F3000C10DFF64A4584052D8B688A1AD58A671CF +:105F4000A773FE5440109436D51A401B3000410010 +:105F5000A616015300034258140140FAB000A6717E +:105F600040F7A5F6FF64030180004052D8B64217FF +:105F70008401FE5488B0AD584010D436A55958B5A8 +:105F800080028825AC5922118000AC40221180018A +:105F9000AC4110B0000CD5345A5005330059800084 +:105FA0005A58010810190000AE7810198000D51059 +:105FB000A778E6A2E8048CA1AF78D502AE780019E4 +:105FC0000000C906A6785A18020410890000A678B5 +:105FD00080B14250B47322B000008025A5584055CE +:105FE00094013855060923000001A55940150440C5 +:105FF00040581401AD4912B18000130180018DA1F8 +:106000008DE1EB088C648CE18DC148FFFF2B3C4F88 +:10601000FFD83C2FFFD7FCE04402B5D83C0FFFE887 +:10602000DD9EFC40B4404E2200F90070005A96FC00 +:10603000C30E84213E17FEB00210000802000009C2 +:106040003C1BFF563C0BFF57480000E85A20040455 +:10605000480000AC2E27EF064E2300E02E37FEB09E +:106060003C2FFFAA3C2FFFA9CB412E27FEA12E5784 +:10607000FEA04462D6845A20010580438083D52146 +:1060800080838043550200FF4D02C0048602D50282 +:1060900086013913121142384473411310402318FA +:1060A00080018C81422844735A4803EE8484403135 +:1060B0009076402110563C3FFFAA3C2FFFA9D516F1 +:1060C000390312118870410310408C8123080001AC +:1060D0009720E2A48850E8F58CA140319476405195 +:1060E00014B63C3FFFAA3C5FFFA93C5DFFE83C4D76 +:1060F000FFAA3D2DFFA9A0E942F2000342290003B7 +:10610000884F94D9E2624EF200893D33FF56A6E8EB +:1061100050F9FF105CF78AA0E90294D93D03FF57BC +:10612000A6A950F87F105CF79220E902949154637D +:1061300080040092800201128003C60FFF1C4219E6 +:106140000824404224964010C436403990003C3B1D +:10615000FF5640280400D51A8E2184C2406098D68C +:1061600040549800EB9888D1401304364251940172 +:1061700042110401FF2C42190424403224764020AD +:10618000C45688733C3BFF5688503C13FF563C2B4B +:10619000FF5712100008587380023C13FF5712106B +:1061A00000091070005AD5395A2005382E17FEB054 +:1061B0005A1801093E37FEA13E37FEA03E37FEB019 +:1061C000D5152E17FEA0E622E8058C213E17FEA06D +:1061D000D5033E37FEA02E17FEA1C9082E17FEA03C +:1061E0005A18020584213E17FEA1223000083C23E4 +:1061F000FF562E17FEA04442D6849A9A38220609EA +:10620000222000093C03FF57401204409A10AC09B9 +:106210003C3BFF563C2BFF57FCC0FC0000100043EA +:106220001010004400100045101000433C1C0447AF +:1062300046000FFF50000F00FE0E5A090009841F90 +:106240003E07FE933E07FE923E07E980EA975A0812 +:10625000015CEA3B5A0801313C04087250107ED4BC +:1062600096495CF08A28E8083C10087350F0FED488 +:106270005CF791A8E96E84403C1408735EF0012C31 +:106280003E27FE933C0BFF483C1BFF46E8043E279D +:10629000E980D55F5EF00B548401E8055EF0812C47 +:1062A000E80584023E07E980D5545EF092D4840369 +:1062B000E8FA841FD5F82E07E980C0035A080109BF +:1062C0003C0408722E27FE934412D680D50B5A0048 +:1062D00002045A08033F3C0408732E27FE9344121D +:1062E000D67C38F089118A0FEB3B96015CF0006593 +:1062F000E9302E07FE935A00FF2D3E07FE928400E0 +:106300003E07FE93D51A5A080225EA3B5A08010EA9 +:1063100084003E07FE933C0008723C0BFF483C00A3 +:1063200008733C0BFF46D5152E07FE925A00FF124C +:1063300084203E17FE93C00A3C03FF483C080872C5 +:106340003C03FF463C080873D504841F3E07FE92B9 +:10635000FC803C0FFFECDD9E3C0FFFEBDD9EFC0064 +:10636000C0045A000108FC8049FFBE933C0FFFEDBA +:10637000FC8049FFBE973C0FFFEEFC808020E609C1 +:106380003C0DFFEEE82344F16190EB38EA78DD0F35 +:106390000A3C10161C22282E34003C0DFFEDDD9E19 +:1063A000500000F0DD9E500001E0DD9E500002D064 +:1063B000DD9E500003C0DD9E500005A0DD9E500014 +:1063C0000780DD9E50000960DD9E8400DD9E920006 +:1063D000FC4080C280E13C2DFFEE3C1DFFED81239F +:1063E000814449FFBE2D3C1DFFEBA60AA64B49FF89 +:1063F000BE47EAE24203000149FFBE6184C03C1D82 +:10640000FFEC00008010E2C0E81080063810980011 +:1064100049FFBE623C0DFFEC9846001080088006E4 +:1064200049FFBE808CC1D5EC8400F80BF80C8401C8 +:10643000F808F8095AA801058402F803F80484034F +:1064400049FFBE4149FFBE0E49FFBE35EA83848144 +:10645000840000148000E201E82BA079385081010B +:10646000D025A07D9482956A98CA8825A6DAA78A45 +:10647000E266E802AECAA07D98CA8825A6DBA78B93 +:10648000E2C3E802AECBA07D383088008825A7881B +:10649000E266E802AEC8A0FD884388A3A651A6A97B +:1064A000E241E802AE693E47EEEC8C01D5D3FCC078 +:1064B000FC62464C01208881446308FFE2C48040AE +:1064C00080A14030C0094EF30082C8054603FF009A +:1064D0004C500121808280A1FD028440463BFF0098 +:1064E000EA26FD10FD30EA24FD60FD10F8EE44219F +:1064F0008E48FD50EA56F8E944218E40F8F54421D3 +:106500008E50FD40EA56FD06EA24F8D444218E6000 +:10651000EA56FD40F8DA44218E58F8E644218E68A8 +:10652000F8DBFD06EA243A4F9400FD10FD02EA264E +:1065300044218E78F8C744218E70F8D644218E808D +:10654000F8CBFD06EA24F8D544218E88FD60EA5692 +:10655000F8CEFD10FD06EA26F8C9F8D0EA26F8C6FE +:10656000F8A9F8C4F082F183844046341A00F8ADEB +:10657000FD50F80BFD15EA59FD10FD50EA244421A9 +:106580008E38EA56EA24FD40FD10FD03EA26FD6040 +:10659000FD10FD03EA59FD14EA26FD40FD15FD033B +:1065A000EA59FD1044018E383A000400EA243A0FFB +:1065B0008420FD13FD05EA263B0FC400FD10FD08F5 +:1065C000EA24F878F89B480000A250F1FFF04460FC +:1065D0007FDFE2CFE8289509404203F540420024DE +:1065E000CC058401490000A6F813C8054607FF0042 +:1065F0004C5000944001BC098082C8065451FFF001 +:1066000044007FF0D80780A1FD02490000A848009F +:10661000008680A1FD02844046343300EA24465FB0 +:10662000CC0088A1469C01A089254064B40997B795 +:106630004014D00944718E004043988040228681E6 +:106640000432022540A39880802204220224EA59C1 +:106650000425022604350227EA59042500240435BE +:106660000025EA24FD304004D00AEB5444218E007A +:10667000F833EA240425002604350027EA26FD1312 +:10668000FD40EA26FD60FD13F820FD50FD16FD04D7 +:10669000EA59FD13EA263A4F940044218E08FD4042 +:1066A000EA56FD02EA24F80644218E10FD40EA561F +:1066B000F81EFD10FD04EA26FD40FD15F8064421F4 +:1066C0008E20EA56F082F183FD03EA2444218E18DD +:1066D000F80B44218E30EA563A0F842083FF4E0097 +:1066E000FFF544218E28EA56EA26FD10FD05EA242E +:1066F0003B0FC400FD10FD08EA26F402F503FD106F +:10670000FD0283FFEA24FD10FD04EA26FD16EA26B9 +:10671000D50584008020D5028002FD10FD01FCE239 +:10672000FC40FD30812249000503B720FD03FCC079 +:10673000FC01C80584004613FF00D5048400461BF5 +:10674000FF00B61F8440F181B41F8062F10149004F +:10675000031FFA5249FFFFE6FC81FC60FD10FD506B +:10676000EA59FD1049000314FD30FD054900000AF7 +:10677000C006FD03FA5149FFFFD5FCE0FD03FCE034 +:10678000C10446580000D904C8038402DD9E465F58 +:10679000FF004647FE009F2198CDE283E80646575A +:1067A000FF0098CDE283E9038404DD9E46400100AA +:1067B0009F21E281E8064658000098CDE283E90374 +:1067C0008403DD9E4657FF00D104465FFF00D902D7 +:1067D000C0038400DD9E8401DD9E92003A6F98BC68 +:1067E00040608C0390DF4E340006FEDAC203FE9256 +:1067F0009ED94E140006FE4AC003FE029E498480C4 +:106800004900003AC60840408004C405FE4AC0035F +:10681000FE029E493A6F9884DD9E920041414009F4 +:10682000974192104040D03796D14010C008FE47A3 +:1068300042020C24E220E8099F21984AE222E9055D +:10684000E220E8039F21984A9A484010D017400060 +:106850004008FE2FFECCE203E80998029E49E202BE +:10686000E905E203E80398029E499A034042400882 +:10687000FE67DD9E3BFFFEBCFD80FD918384CB4D1A +:10688000E3B2E8194209000782A0C00D4129000CBB +:10689000525000204058140D4118800C41189404A7 +:1068A0004108000CFD08805249FFFFBA82C18200F6 +:1068B00086E0D523C2284209000782A0C8048BB213 +:1068C00086E1D51452F000204129000C8052404846 +:1068D0003C0D4058800C4108000C400290044018C8 +:1068E000BC0D49FFFF9D82E18220FD08805249FFD7 +:1068F000FF9782C1510000004FC20053862041081B +:10690000540DD54B41194A17842084004FC2004CC6 +:10691000B79C151E0001D547E3B3E9F7420980078C +:1069200082A0C044524000204059100D4029800CE4 +:10693000FEAF82624129000C4038100D4108000C66 +:106940004008800C4018900DFE1F49FFFF6982C16E +:1069500082204200C869E3A1E9054C18C00CE3801D +:10696000E809516B7FFF8A3340304801E2038A2FE8 +:10697000800386E04FC200154008000140188401E2 +:10698000E3808A2F524A80204110900C4100540D20 +:10699000410844044110D40DB79C151E0001801617 +:1069A000501B80003BFFFE84DD9EE3F1E903E39290 +:1069B000E90986C1404848018BB3E3848BAF820468 +:1069C000D50286C086E04FC3FFE9D5EA4231FC0A12 +:1069D00095093A6FA8BC959947E80000E286E90559 +:1069E0004C434009E202E806FD40FD01FD14950913 +:1069F0009599FECD4031F8024072540940A35409E4 +:106A00004092280840832808445007FF4C5380C414 +:106A100040F200044EF200BC40F308044EF2009233 +:106A20004063A8015CF300404EF2008C40505409D2 +:106A30004094940440002C084051540940841404AC +:106A400040212C08E6E2E9274094F8044EA2000415 +:106A5000408478049F714062A81AC61D52530020DA +:106A60004E57000C4041140C4054140C4084180D37 +:106A70004021180DFEAFD50CFFAA50528020404493 +:106A8000140CFF174043181A4024180D8500C40346 +:106A900058210002C3594C7540064C9440044C01E7 +:106AA0000078E328E9054C94400AE202E8079FF9E0 +:106AB00040447C0893019241FEA780809A02E280C4 +:106AC0008B2F8B28E6E2E9494E93000BFA90404366 +:106AD000900680A7CC0D812084005073FFE04254C3 +:106AE0008007E2A75247800142529C01C50D9BFDE1 +:106AF0009B6C526280204040180D4094940C4000E2 +:106B0000140C40949004500004005CF00400892FA1 +:106B1000E32F88EF40502C09976C80C09A05E2C0A3 +:106B20008B2F409484084054D008932C920BFE2F56 +:106B30004053D008409494044010F8024010A4043C +:106B40003A6FA884DD9E9802E202892FE32F8928FC +:106B5000E90AE328E908CFD8920B4044D408932BE4 +:106B6000FE27D5EB525387FEC50E54F00001585056 +:106B700000024002BC1B4044FC0893219201FE2706 +:106B80009DF9D5C284004697FF00D5D7C3DA8400AB +:106B90008420D5D7409480044C9F40054C557FD22B +:106BA000C3D0840044180000D5CC9200FC42950963 +:106BB00092954070AC0840605409FFF740602C0883 +:106BC00047C80000955992B54091AC0840815409DE +:106BD0004094A00440812C08FECD40A1F002443036 +:106BE00007FFC4584C3200754073F0044E520087C2 +:106BF0004C3280794094F00414AF80035002FC02C0 +:106C000099204223A4694203246940910400E321AE +:106C100040A1BC004223A06999D0E2E0892FE32F74 +:106C2000894F8923E323894F4203206999F9E2E1DF +:106C3000892FE32F40153C00FFC758048001400412 +:106C40009C1AE420E90781E09800E20F9849882F18 +:106C50009F2104AF80034E470071525207FF4E57E9 +:106C60000046500004005CF00400E804882FE22F86 +:106C7000888F40202C0996949A02920B4020D408C9 +:106C8000FE179449922C40525008FE6F4010A80401 +:106C9000FCC240F39804E81940F37C0999FF88EF9F +:106CA00099B6CF0580E684C050427FE0420380075A +:106CB000C09E9B20522000204023080D4063000C02 +:106CC0004073800CFFD7D593D315802AFCC2FFF701 +:106CD0004C7E4011CD064024840840212004C20A85 +:106CE000DB054094A0044C9E400684004617FF003C +:106CF000D5CE840044180000FCC24004A004C0E6C5 +:106D000040F47C098929892F89084E93000681283F +:106D100085005052FFE0420480074E02FF6F9B68DF +:106D2000522000204024080D4084000C4094800C28 +:106D30004094880448FFFF6284C0523200015CF135 +:106D40008020E90A80C0800184205031FFE0C00427 +:106D50005CF18020E81AC310522180204070880C1A +:106D60004050080C40000C0D40108C0DFE3FFFAF52 +:106D7000C60358000001500004005CF00400882F96 +:106D80004040FC0948FFFF778400D5A0FC429509EC +:106D900092954070AC0840605409FFF740602C08A1 +:106DA00047C80000955992B54091AC0840815409FC +:106DB0004094A00440812C08FECD40A1F002443054 +:106DC00007FF4E4200C54C3200EF4073F0044E52B4 +:106DD00000FB4C3280F34094F0049B25504203FFAB +:106DE00092C14013FC08FF8F92E14024C009403358 +:106DF00088F74014801342508C244073C00840032D +:106E00004009FFC780079BFDE207E8059ED988E996 +:106E1000E2E9E8FD402388F7425088244073C00827 +:106E20009631FFC780079BFDE207E8059E9188E940 +:106E3000E2E9E8FD4031C00898DA4201A069FF822A +:106E400080079BF9E207C60580079FF9E903E2077F +:106E5000E80C9ED988C84003200688E9E2E9C0040E +:106E60009DF9E903E6E1E8F64C74C007802880E666 +:106E700084408400D52B4014C009402384F740048B +:106E8000801342F008244073C00840534009FFEFCC +:106E900080A78AEFE2A7E8059E9188E9E2E9E8FD8C +:106EA000401384F7425004244073C0089631FFC752 +:106EB00080079BFDE207E8059E4988E9E2E9E8FDD5 +:106EC00040214008989142012069FF8280079BF988 +:106ED000E207C60580079FF9E903E207E80C9E91E7 +:106EE00088C84003200688E9E2E9C0049DF9E90367 +:106EF000E6E1E8F6E460E90781E29892E24F98DB88 +:106F0000886F9F21FFF75801000140011C1A802360 +:106F10004E470079525207FF4E57004A5000040076 +:106F20005CF00400E804882FE22F888F40202C09B1 +:106F300096949A02920B4020D408FE179449922C02 +:106F400040525008FE6F4010A804FCC240F3980461 +:106F5000E81B40F37C0999FF88EF99B6CF0580E6DE +:106F600084C050427FE0420380074E02FF329B20E4 +:106F7000522000204023080D4063000C4073800C19 +:106F8000FFD748FFFF26D307CD0440F4A004E8074D +:106F9000802AFCC24094A0044C9E3FFC840044180C +:106FA0000000FCC2FFF74C7E7FFBD3F9840046173C +:106FB000FF004010A804FCC24094A0044C9E7FF047 +:106FC0008400D5E740F4A004E8F240F47C09892964 +:106FD000892F89084E930006812885005052FFE0D2 +:106FE000420480074E02FEFB9B6852200020402492 +:106FF000080D4084000C4094800C4094880448FFA5 +:10700000FEEE84C0523200015CF18020E90A80C0AB +:10701000800184205031FFE0C0045CF18020E81A38 +:10702000C310522180204070880C4050080C400052 +:107030000C0D40108C0DFE3FFFAFC6035800000141 +:10704000500004005CF00400882F4040FC0948FF19 +:10705000FF6F8400D59E92003A6F983C954992B597 +:107060004040AC0840605409FF3740302C08466867 +:107070000000FF375CF2843EE8215222843EFAD0C1 +:10708000E246E9068064848050217FE0CBF9C20BA0 +:1070900080044031880D4042080D522100204000FC +:1070A000080CFEC7E420E805FF22C303FEDA8E8148 +:1070B000800380243A6F9804DD9EE420E90752F2B1 +:1070C00087FFE90895A1FF9FC60546480000846038 +:1070D000D5F04647FFFF58420FFF847FD5EA920064 +:1070E0003A6F983C842080A180618040C210E440C7 +:1070F000E80746580000FE92C103FE4A8E41443024 +:10710000041E424100079ADC4021100C4040AC09AB +:1071100040615408FF37959192CCFF774061D008C9 +:10712000FF77800480253A6F9804DD9E4402D7AC37 +:10713000DD9E92008060E644E9285441800354506B +:107140008003C50B525280049A95996908408001CA +:10715000184180014C12FFFC40511409C50A956D7D +:10716000996996A73B00DC043B01DC244C12FFFC30 +:1071700040510809C50A956A9969968F3A4090046A +:107180003A4190244C12FFFCC208994A0840800101 +:10719000184180014C12FFFCDD9E92008060E644A5 +:1071A000E93054518003C509525280049A95996878 +:1071B000181180014C32FFFE96484040A008FE673F +:1071C0004040C008FE67405114094E520011956DB1 +:1071D000996B96A78201822182418261828182A17C +:1071E00082C182E13B01DC244C32FFFE40510809A0 +:1071F000C508956A996B968F3A1184244C32FFFE2C +:10720000C206995A181180014C32FFFEDD9E920091 +:107210003C0DFB2349003E3C490011564403F04A13 +:10722000441000554900126149006B954900465AC7 +:107230004900B79A4900465A49003EDB44038D4055 +:107240003C0DFB374800015549003E3C49003EDB00 +:10725000490020A9490011563C1DFB233C0DFC0CA4 +:107260003C1DFB492E07EBE449003E8C490041E6FA +:107270002E07EFAF3C0DFB493C0DFB223C1DFB37BD +:1072800049006B95442001902E07EBF948008CD9FA +:107290003A6F98844412FEF044300190100F80073A +:1072A0004900B4D64900752C4900B3E84420018058 +:1072B0004420005542006C0B3C0FFBC73C0FFB46C3 +:1072C00049006A8E4000000950037F4840310C405D +:1072D0003C0DFB47443000553E07EC034900B7CE58 +:1072E0002E1FEE9F2E0728AC4423F04A2E000C845C +:1072F000440FFFAA44000055490077BB2E00111D22 +:1073000049001611490069A43C0FFB473C0DFB3EA8 +:107310004413F04A490058ED40F03C005800000189 +:10732000660000E03E07EBF94200080B3C0E032824 +:107330004900404E3E07EBB64900B2EE44338D4162 +:1073400054007FFF2E17EF3A400080406600000295 +:10735000100F800F1010001C4402C4DC109380003A +:10736000020F8003120F80033A210C004200100B21 +:10737000440000504900B3E63C0DFB71490015D2B2 +:107380004402E8C8490077BB3C1DFB3B58000004A1 +:10739000490013CF490070161004800149001FF303 +:1073A0003C0E032754637FFF4402FEF03C0DFFF3C5 +:1073B000490012614402DF4C4900115A3E07EEA019 +:1073C0004900776E3C1DFC0C2E07EBAC4473F04A71 +:1073D00044100032490058ED3C03F6152E07EF1219 +:1073E0003C0DFB484490005544131C203E07E938EF +:1073F00040F0BC00490041E6640304033B00E42480 +:107400003C0DFB9049006E5C4402FE503807800042 +:107410004413F4033E07EE9F100300501004800055 +:1074200000048001580000202210800144300080B8 +:107430002E000CA43C0DFB28440000323E07EBB0AC +:107440002E07EB97120F800B3C0DFFF44000041643 +:107450003C0FFB22580000024463F04A490079C9FE +:1074600058000010490081322E07EBBE3C0C043658 +:107470005410FFFF3C0808A4490020DB3C0BF61425 +:107480002E0728AB4402000049007515120F800A30 +:107490003E07EEFE101000513E07EBA23B006404D5 +:1074A0002E0011E249006CA2540000FE4462FEF07E +:1074B000440000694402E9E02E07EE960005000052 +:1074C0004412FE503E07EBCE502F800700000051C3 +:1074D000440300002E07EBB666000004490039EAB9 +:1074E000580000083E17EE9F021F800044126238C9 +:1074F0004410004C40109C3600048000480001718C +:10750000447000552E0FEEA0400080164800012860 +:1075100038308A0A50528F003C0BF8DE4400007865 +:10752000440373E8490039EA3E07EEA23E07EBFB4D +:1075300049007DE34422C5204200040B401004367C +:10754000660000104413F2483C0E03203C0C000A75 +:107550005C0000013C0FFBC8100300411005000057 +:1075600042000C0B40001840541080FE2E07F14DD5 +:107570003C6FFB7E40310C063C0FFB5A22308000F2 +:107580003C0BF8DF10058000440000642E07F1A4D6 +:10759000440397DE3E07EBE4440000FF2E07F0288B +:1075A000490063F349006E5C58000080549000FF6E +:1075B00049006E8E4412C3A53C0C000B3C0DFD7BB4 +:1075C0003E17EBC640320D0018128001020F8001F9 +:1075D0002E07EBF24900630A501F800F49006F1815 +:1075E0003C1DFB2849003E8C3C0BF62A3E07EBBEB7 +:1075F0002E07EEEB46500FFF3E07EBE34900B0E8E5 +:10760000500F800E3C1FFB47641304022E07EB8AC9 +:107610003E07F1A449007CA13820800844300032A4 +:107620002E07EF0238048602441000643C0DFB3242 +:107630005000004C3C0DFEE73E07EC132E17EBE428 +:10764000120F80020462801612048000020F800074 +:107650004422E8C85CF003E8441216803C0C032086 +:1076600044134C104400004C441E00003E07EF2F12 +:1076700049007C2D444000644412E8C840108C3618 +:107680005EF000334402FEF14900930838530E0ABD +:107690004413F1C0540000F02E07EBCF4420FFFF4D +:1076A0004402DAF0500F80063C1DFB993E07F04182 +:1076B000440397DC540000FD3E07F0474442D3C822 +:1076C0005CF000333C1FFB46660000084422DE5895 +:1076D0003C2394222E07293E641324032E07E93904 +:1076E000503F800738009A0A2E07EE9744138D40CA +:1076F000381784003C0BF77E3C0DFB3C4200000336 +:107700003C6FFCB53E17EB994900877A4900466704 +:107710002E07EBFD4422E9A0441365103C6FFB22C9 +:10772000401004063E07EBF249003F5E3C5DFB3231 +:10773000400080064472C7B84900815A4231800334 +:107740000003007D3C0BF774000F8007490045FAE9 +:107750004221000366000001500F80073E00114ED9 +:107760004900B77044038D42490014C12E372812D6 +:107770004900409D3E07EF0E440000520014800176 +:107780003E07EF0A4412C4163E07EF373C1DFBD9F3 +:107790003E07F14D49003EFE4900A5234400012C5F +:1077A000421080032E17EEEB4412D9B0490079C97C +:1077B00049003FD649006B373A0000003C0FFB7E82 +:1077C0004412DA60640308034900808C4200700BA5 +:1077D0003C0E03243C03F8DE3E07EBEE4003200999 +:1077E0004000BC1A401184403C0C01DB4440005571 +:1077F0005CF100C83C13F48B4402623849004047F6 +:10780000490079CE49002343120F80003C0DFB7ED6 +:107810004303887344037A282E07EC023E07F19352 +:10782000020F80024403F7CE030200004900709665 +:107830004900638749001C6A3C1FFCB43E07EBB259 +:10784000490088013C1BF82440213C0804118014A5 +:107850001010003C490044F249008CFC002F8007C6 +:1078600066108002490089A03E07EBF53E07FAF555 +:10787000405284B61203000944130FA049003EB2DF +:10788000448000553E07F1583C1DFBEA1090000073 +:10789000490063211010005240010016405293F538 +:1078A0004403F41C3E07EF064900707244134DA0D8 +:1078B0001003007D121000102E07EF2C3E07293E0A +:1078C000401080204403F00E4900617C380781019C +:1078D0003E07EE9744038D412E07EF104900707864 +:1078E0003C1C01DC3B014C00441000A5490020A1D8 +:1078F000441333103C0BF6134900705F4412C382EB +:1079000049007C4B4403F7C82E07EBDA120300252D +:107910003C0C00023810AE02100480464402FE60A7 +:107920004413F249225080002E07EBC22E07F0418B +:107930005EF10033041300083C0E03234412C3E637 +:107940003C0FFB7B000300422E07EF093C3DFB2F61 +:1079500000030046490046672E10111D4412DA2824 +:107960000030000E4412C700490040B31010000858 +:107970003C0DFC241003004014AF80013E07EEF5DF +:10798000500002404422CD34120F800154A000FF69 +:107990003E000CA4490044FC2E07EF0E3C0DFC7485 +:1079A00040631CD62E17EFAF442000B649001E25B9 +:1079B0004402C49C502F8006381019095CF28708D5 +:1079C0003C1DFB22400081002E50111D2E07EBE5CF +:1079D000422090734412E4703C0396052E07EBB7E7 +:1079E000460000F4120300083E07EB903E07F159F1 +:1079F0003B0FCC203C5DFB3B490045CE3C0FFB667A +:107A00002E07EB9B3C0FFB274472C7D049000CDECE +:107A10008492030014940300FAAF02008AB10200BA +:107A2000648F0300F4900300DAAC02006AAE020037 +:107A300010330300903F0300104C030090580300E4 +:107A400000A2010080AE010000BB010080C7010060 +:107A500010D8010050DE010090E40100D0EA0100DE +:107A6000E8730300F8740200A00F030068800300AD +:107A700064686A7170737A81B1A5948873647DA01B +:107A80006564676F6F72777CB5A4938A74647C9F1A +:107A900064686A7170737A81B1A5948873647DA0FB +:107AA0006564676F6F72777CB5A4938A74647C9FFA +:107AB00064686A7170737A81B1A5948873647DA0DB +:107AC0006564676F6F72777CB5A4938A74647C9FDA +:107AD00064686A7170737A81B1A5948873647DA0BB +:107AE0006564676F6F72777CB5A4938A74647C9FBA +:107AF00064686A7170737A81B1A5948873647DA09B +:107B00006564676F6F72777CB5A4938A74647C9F99 +:107B100064686A7170737A81B1A5948873647DA07A +:107B20006564676F6F72777CB5A4938A74647C9F79 +:107B300064686A7170737A81B1A5948873647DA05A +:107B40006564676F6F72777CB5A4938A74647C9F59 +:107B500064686A7170737A81B1A5948873647DA03A +:107B60006564676F6F72777CB5A4938A74647C9F39 +:107B70006564696E6D6E757AA49A8B806F647B996B +:107B80006664696F6D707479A9978C8270647A9855 +:107B90006564696E6D6E757AA49A8B806F647B994B +:107BA0006664696F6D707479A9978C8270647A9835 +:107BB0006564696E6D6E757AA49A8B806F647B992B +:107BC0006664696F6D707479A9978C8270647A9815 +:107BD0006564696E6D6E757AA49A8B806F647B990B +:107BE0006664696F6D707479A9978C8270647A98F5 +:107BF0006564696E6D6E757AA49A8B806F647B99EB +:107C00006664696F6D707479A9978C8270647A98D4 +:107C10006564696E6D6E757AA49A8B806F647B99CA +:107C20006664696F6D707479A9978C8270647A98B4 +:107C30006564696E6D6E757AA49A8B806F647B99AA +:107C40006664696F6D707479A9978C8270647A9894 +:107C50006564696E6D6E757AA49A8B806F647B998A +:107C60006664696F6D707479A9978C8270647A9874 +:107C70006467686C6E717677A8988E7E6E647D9F5F +:107C800064656B6C70717579AA998A7C70647FA049 +:107C90006467686C6E717677A8988E7E6E647D9F3F +:107CA00064656B6C70717579AA998A7C70647FA029 +:107CB0006467686C6E717677A8988E7E6E647D9F1F +:107CC00064656B6C70717579AA998A7C70647FA009 +:107CD0006467686C6E717677A8988E7E6E647D9FFF +:107CE00064656B6C70717579AA998A7C70647FA0E9 +:107CF0006467686C6E717677A8988E7E6E647D9FDF +:107D000064656B6C70717579AA998A7C70647FA0C8 +:107D10006467686C6E717677A8988E7E6E647D9FBE +:107D200064656B6C70717579AA998A7C70647FA0A8 +:107D30006467686C6E717677A8988E7E6E647D9F9E +:107D400064656B6C70717579AA998A7C70647FA088 +:107D50006467686C6E717677A8988E7E6E647D9F7E +:107D600064656B6C70717579AA998A7C70647FA068 +:107D70006467686C6E717677A8988E7E6E647D9F5E +:107D800064656B6C70717579AA998A7C70647FA048 +:107D900064676B6D74777C7EB3A596806E6484A9EE +:107DA00064666D6F73757E7FB6A3937F6E6481A7E3 +:107DB00064676B6D74777C7EB3A596806E6484A9CE +:107DC00064666D6F73757E7FB6A3937F6E6481A7C3 +:107DD00064676B6D74777C7EB3A596806E6484A9AE +:107DE00064666D6F73757E7FB6A3937F6E6481A7A3 +:107DF00064676B6D74777C7EB3A596806E6484A98E +:107E000064666D6F73757E7FB6A3937F6E6481A782 +:107E100064676B6D74777C7EB3A596806E6484A96D +:107E200064666D6F73757E7FB6A3937F6E6481A762 +:107E300064676B6D74777C7EB3A596806E6484A94D +:107E400064666D6F73757E7FB6A3937F6E6481A742 +:107E500064676B6D74777C7EB3A596806E6484A92D +:107E600064666D6F73757E7FB6A3937F6E6481A722 +:107E700064676B6D74777C7EB3A596806E6484A90D +:107E800064666D6F73757E7FB6A3937F6E6481A702 +:107E9000646469676E727777AA998E756C6482A63E +:107EA00064656A6973717879B09C8F77706482A712 +:107EB000646469676E727777AA998E756C6482A61E +:107EC00064656A6973717879B09C8F77706482A7F2 +:107ED000646469676E727777AA998E756C6482A6FE +:107EE00064656A6973717879B09C8F77706482A7D2 +:107EF000646469676E727777AA998E756C6482A6DE +:107F000064656A6973717879B09C8F77706482A7B1 +:107F1000646469676E727777AA998E756C6482A6BD +:107F200064656A6973717879B09C8F77706482A791 +:107F3000646469676E727777AA998E756C6482A69D +:107F400064656A6973717879B09C8F77706482A771 +:107F5000646469676E727777AA998E756C6482A67D +:107F600064656A6973717879B09C8F77706482A751 +:107F7000646469676E727777AA998E756C6482A65D +:107F800064656A6973717879B09C8F77706482A731 +:107F900064666D6F74777F80B19D91786A6483ACFD +:107FA00064646C6C74757D7DB29E8D76696483A902 +:107FB00064666D6F74777F80B19D91786A6483ACDD +:107FC00064646C6C74757D7DB29E8D76696483A9E2 +:107FD00064666D6F74777F80B19D91786A6483ACBD +:107FE00064646C6C74757D7DB29E8D76696483A9C2 +:107FF00064666D6F74777F80B19D91786A6483AC9D +:1080000064646C6C74757D7DB29E8D76696483A9A1 +:1080100064666D6F74777F80B19D91786A6483AC7C +:1080200064646C6C74757D7DB29E8D76696483A981 +:1080300064666D6F74777F80B19D91786A6483AC5C +:1080400064646C6C74757D7DB29E8D76696483A961 +:1080500064666D6F74777F80B19D91786A6483AC3C +:1080600064646C6C74757D7DB29E8D76696483A941 +:1080700064666D6F74777F80B19D91786A6483AC1C +:1080800064646C6C74757D7DB29E8D76696483A921 +:1080900064666D6F74777F80B19D91786A6483ACFC +:1080A00064646C6C74757D7DB29E8D76696483A901 +:1080B00072727272727272727171717171717171A8 +:1080C0007272727272727272737373737373737388 +:1080D0006E6E6E6E6E6E6E6E7070707070707070B0 +:1080E0006E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6EB0 +:1080F0006B6B6B6B6B6B6B6B6A6A6A6A6A6A6A6AD8 +:108100006C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6CAF +:1081100068686868686868686969696969696969D7 +:108120006B6B6B6B6B6B6B6B6A6A6A6A6A6A6A6AA7 +:1081300068686868686868686868686868686868BF +:10814000696969696969696969696969696969699F +:1081500068686868686868686767676767676767A7 +:108160006868686868686868676767676767676797 +:1081700064646464646464646464646464646464BF +:1081800064646464646464646464646464646464AF +:10819000646464646464646466666666666666668F +:1081A0006666666666666666676767676767676767 +:1081B0006F6F6F6F6F6F6F6F7272727272727272B7 +:1081C0007373737373737373747474747474747477 +:1081D0006F6F6F6F6F6F6F6F6D6D6D6D6D6D6D6DBF +:1081E0006D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6DBF +:1081F0006B6B6B6B6B6B6B6B6D6D6D6D6D6D6D6DBF +:108200006B6B6B6B6B6B6B6B6D6D6D6D6D6D6D6DAE +:108210006B6B6B6B6B6B6B6B6969696969696969BE +:108220006A6A6A6A6A6A6A6A6B6B6B6B6B6B6B6BA6 +:1082300069696969696969696A6A6A6A6A6A6A6AA6 +:108240006A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A8E +:1082500068686868686868686767676767676767A6 +:108260006969696969696969666666666666666696 +:1082700065656565656565656464646464646464B6 +:10828000646464646464646466666666666666669E +:108290006565656565656565646464646464646496 +:1082A0006565656565656565646464646464646486 +:1082B000767676767676767674747474747474746E +:1082C0007676767676767676757575757575757556 +:1082D0007272727272727272717171717171717186 +:1082E00073737373737373736E6E6E6E6E6E6E6E86 +:1082F0007272727272727272717171717171717166 +:1083000073737373737373736F6F6F6F6F6F6F6F5D +:108310006E6E6E6E6E6E6E6E70707070707070706D +:1083200070707070707070706D6D6D6D6D6D6D6D65 +:108330007272727272727272717171717171717125 +:1083400072727272727272726F6F6F6F6F6F6F6F25 +:108350006F6F6F6F6F6F6F6F6C6C6C6C6C6C6C6C45 +:108360006E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E2D +:108370006B6B6B6B6B6B6B6B686868686868686865 +:108380006B6B6B6B6B6B6B6B6D6D6D6D6D6D6D6D2D +:108390006A6A6A6A6A6A6A6A696969696969696945 +:1083A0006969696969696969666666666666666655 +:1083B000666666666666666666666666666666665D +:1083C0006767676767676767666666666666666645 +:1083D0006F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6FAD +:1083E0006C6C6C6C6C6C6C6C6E6E6E6E6E6E6E6EBD +:1083F000727272727272727272727272727272725D +:108400007070707070707070717171717171717164 +:108410006F6F6F6F6F6F6F6F6B6B6B6B6B6B6B6B8C +:108420006C6C6C6C6C6C6C6C6B6B6B6B6B6B6B6B94 +:108430006D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6C +:108440006C6C6C6C6C6C6C6C6D6D6D6D6D6D6D6D64 +:108450006B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6C +:1084600069696969696969696B6B6B6B6B6B6B6B6C +:108470006C6C6C6C6C6C6C6C6B6B6B6B6B6B6B6B44 +:108480006969696969696969686868686868686864 +:1084900069696969696969696A6A6A6A6A6A6A6A44 +:1084A00069696969696969696B6B6B6B6B6B6B6B2C +:1084B000676767676767676767676767676767674C +:1084C0006666666666666666676767676767676744 +:1084D0006E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6EBC +:1084E00072727272727272726F6F6F6F6F6F6F6F84 +:1084F0006D6D6D6D6D6D6D6D6F6F6F6F6F6F6F6F9C +:1085000070707070707070706F6F6F6F6F6F6F6F73 +:108510006C6C6C6C6C6C6C6C6D6D6D6D6D6D6D6D93 +:108520006E6E6E6E6E6E6E6E6B6B6B6B6B6B6B6B83 +:108530006C6C6C6C6C6C6C6C6D6D6D6D6D6D6D6D73 +:108540006D6D6D6D6D6D6D6D6F6F6F6F6F6F6F6F4B +:1085500068686868686868686B6B6B6B6B6B6B6B83 +:108560006A6A6A6A6A6A6A6A68686868686868687B +:108570006666666666666666696969696969696983 +:108580006767676767676767686868686868686873 +:108590006565656565656565646464646464646493 +:1085A000666666666666666666666666666666666B +:1085B0006666666666666666676767676767676753 +:1085C000676767676767676767676767676767673B +:1085D0007D7D7D7D7D7D7D7D7979797979797979EB +:1085E0007878787878787878777777777777777713 +:1085F0007777777777777777767676767676767613 +:108600007777777777777777767676767676767602 +:1086100076767676767676767676767676767676FA +:10862000747474747474747474747474747474740A +:1086300074747474747474747474747474747474FA +:108640007373737373737373727272727272727202 +:1086500077777777777777777575757575757575BA +:1086600071717171717171717575757575757575DA +:1086700074747474747474747171717171717171D2 +:1086800071717171717171716E6E6E6E6E6E6E6EF2 +:108690006C6C6C6C6C6C6C6C696969696969696932 +:1086A0006C6C6C6C6C6C6C6C6A6A6A6A6A6A6A6A1A +:1086B0006C6C6C6C6C6C6C6C6A6A6A6A6A6A6A6A0A +:1086C00069696969696969696A6A6A6A6A6A6A6A12 +:1086D0006868686868686868676767676767676722 +:1086E0006565656565656565646464646464646442 +:1086F000A600A200A700A6009F00A100A2009F0064 +:108700009B0098009F009B00970097009D00990098 +:10871000970096009A0097009700940099009500A2 +:1087200091009000930090009100930096009400B7 +:1087300091008C008F008C008C008C008C008C00D1 +:108740008C0087008B0089008A0089008B008800DC +:1087500088008500890083008400810083008300F5 +:1087600084008100840080008300820083008300F5 +:108770007E007F0080007B007F007F0080007C0007 +:108780007A007D007C007A007E007E007E007C0006 +:108790007B0079007A007B007700750077007A0013 +:1087A000760076007500720071007200720072002F +:1087B0006F0070006F007000720073007300730030 +:1087C0006F006C006F006D006D006E006F006F0039 +:1087D0006B006C006C006D006C006C006C006A003B +:1087E00069006B006C006D0067006800690069003B +:1087F000640065006700660063006600650066004F +:10880000620064006300620062006400620066004F +:108810005F0062005F0060005D0061005D0060005D +:108820005C005C005C005E005D005F005D005F005E +:108830005B005D005A005C0057005B0059005B0064 +:1088400056005B005700590055005900560058006B +:1088500057005A0055005A00550057005500550062 +:108860004F005100510052004F0052004F00520083 +:108870004C004F004C004D0049004D004B004F0094 +:108880008B00900093009D009C00A000AA00B30004 +:10889000DC00CC00B800A9008E007C009B00C70063 +:1088A000910090009500A000A000A400AB00B200D1 +:1088B000E000CB00B600AB0090007C009A00C50041 +:1088C0008300820088008F008E008F0098009F0038 +:1088D000C200B600A4009700830076009100B500A6 +:1088E00085008300890091008F00930098009F000D +:1088F000C900B400A7009B00850077009100B50077 +:1089000078007B007D008100840087008D008F004F +:10891000BA00A9009E008C007A006F008B00B000A6 +:10892000770078007F008100850087008B00900031 +:10893000BB00A800980088007B006E008C00B0008F +:108940006C006F00740076007D0081008600880056 +:10895000B800AA009A008400710067008800AE0089 +:108960006D006F00770079007D00800089008A002B +:10897000BB00A80097008300710067008500AC0071 +:1089800062006200670065006C0070007500750091 +:10899000A300930088007000680060007D009F00C5 +:1089A000620063006800670071006F007600770066 +:1089B000A50093008600700069005E007A009D00AB +:1089C000550057005D005E00630065006C006D009F +:1089D0009C008A0080006A005D00580073009700C8 +:1089E000580058005F005F00660067006E006E0070 +:1089F0009D008B007C0068005C00580073009500AF +:108A00001A004D008000B300E6001A014D018001FC +:108A1000B301E6011A024D028002B302E6021A0314 +:108A20004D038003B303E6031A044D048004B3042A +:108A3000E6041A054D058005B305E6051A064D0640 +:108A40008006B306E6061A074D078007B307E60758 +:108A50001A084D088008B308E6081A094D0980096C +:108A6000B309E60934003200340032003400340027 +:108A7000320034003200340034003200340032005E +:108A8000340034003200340032003400340032004C +:108A9000340032003400340032003400320034003C +:108AA000340032003400320034003400320034002C +:108AB000320034003400320034003200340034001C +:108AC000320034003200340019004B007D00AF004A +:108AD000E100130145017701A901DB010D023F020D +:108AE0007102A302D502070339036B039D03CF0371 +:108AF0000104330465049704C904FB042D055F05D4 +:108B00009105C305F5052706320032003200320018 +:108B100032003200320032003200320032003200C5 +:108B200032003200320032003200320032003200B5 +:108B300032003200320032003200320032003200A5 +:108B4000320032003200320008080908080901002A +:108B50000001000201030203E8730300F87402003D +:108B6000A00F03006880030010D8010050DE010050 +:108B700090E40100D0EA0100208E0200609402001F +:108B8000A09A0200E0A0020010330300903F03000F +:108B9000104C03009058030000090B020F06040D4F +:108BA000070E0C050801030A01020304050600076D +:108BB0000800000006060606060606060600000077 +:108BC00004050607F20A0B00BCC20C002B4C0E0079 +:108BD000AF3009004C5E090030790D000A930F0098 +:108BE000C2E40D000DF50400433D0300D4B30100C1 +:108BF00050CF0600B3A10600CF860200F56C00003E +:108C00003D1B02000DF50400F56C00004C5E0900F0 +:108C10002B4C0E00000000000000000000000000CF +:108C200000000000BCC20C00AF30090030790D001C +:108C3000C2E40D0000000000000000000000000081 +:108C400000000000D4B30100433D0300B3A10600BF +:108C50003D1B02000A930F0030790D00F20A0B0051 +:108C6000AF3009000DF5040050CF0600F56C000090 +:108C7000CF8602004C5E0900C2E40D002B4C0E00B2 +:108C8000BCC20C003D1B0200B3A10600433D030023 +:108C9000D4B30100AF300900F20A0B0030790D00A7 +:108CA0000A930F00CF860200F56C000050CF06003B +:108CB0000DF50400BCC20C002B4C0E00C2E40D00EC +:108CC0004C5E0900F20A0B00BCC20C002B4C0E00DB +:108CD000AF3009004C5E090030790D000A930F0097 +:108CE000C2E40D00020202030303040400000200B8 +:108CF00003000500070009000A000C000E00100028 +:108D0000110013001500160018001A001C001D00A9 +:108D10001F002100220024002500270029002A002E +:108D20002C002D002F0030003200340035003600BA +:108D3000380039003B003C003E003F00400042004C +:108D40004300440045004700480049004A004B00EA +:108D50004D004E004F00500051005200530054008F +:108D60005500560057005700580059005A005B0044 +:108D70005B005C005D005D005E005F005F00600006 +:108D800060006100610061006200620062006300D7 +:108D900063006300630064006400640064006400B6 +:108DA0006400000064006400640064006400640007 +:108DB00063006300630063006200620062006100A0 +:108DC00061006100600060005F005F005E005D00A8 +:108DD0005D005C005B005B005A00590058005700C2 +:108DE00057005600550054005300520051005000E7 +:108DF0004F004E004D004B004A004900480047001C +:108E0000450044004300420040003F003E003C005B +:108E10003B003900380036003500340032003000A5 +:108E20002F002D002C002A002900270025002400F7 +:108E3000220021001F001D001C001A00180016004F +:108E400015001300110010000E000C000A000900AC +:108E500007000500030002000000000000000200FF +:108E600003000500070009000B000C000E001000B5 +:108E7000120013001500170019001B001D001F0031 +:108E8000200022002400260028002A002D002F00A8 +:108E900031003300350037003A003C003E0041000D +:108EA0004300460049004B004E005100540057005B +:108EB0005A005D006100640068006B006F00730081 +:108EC00077007B00800085008A008F0094009A0064 +:108ED000A000A600AD00B400BC00C400CD00D600C8 +:108EE000E100EC00F8000501130122013401470103 +:108EF0005D0175019101B101D601020237027702CD +:108F0000C8022E03B703770496057407300B611669 +:108F100010270000000001000400090010001900E3 +:108F20002400310040005100640079009000A90045 +:108F3000C400E10000012101440169019001B9016F +:108F4000E401110240027102A402D9021003490394 +:108F50008403C103000441048404C90410055905B5 +:108F6000A405F10540069106E40639079007E907D4 +:108F70004408A10800096109C409290A900AF90AEC +:108F8000640BD10B400CB10C240D990D100E890E01 +:108F9000040F810F00108110041189111012991211 +:108FA0002413B1134014D1146415F9159016291720 +:108FB000C41761180019A119441AE91A901B391C29 +:108FC000E41C911D401EF11EA41F00006D006D00E9 +:108FD0006E00700071007100710000006D006D0086 +:108FE0006B00690068006800670000000000050071 +:108FF0000A001300190028003C00000000000000D7 +:109000000038FAFE422EE63F3067C79357F32E3DF5 +:10901000010000000000E0BF5B3051555555D53FC1 +:109020009045EBFFFFFFCFBF1101F124B399C93F7A +:109030009FC806E57555C5BF000000000000E0BFF1 +:10904000775555555555D53FCBFDFFFFFFFFCFBF9A +:109050000CDD95999999C93FA74567555555C5BFE9 +:1090600030DE44A32449C23F653D42A4FFFFBFBF99 +:10907000CAD62A288471BC3FFF68B043EB99B9BFB8 +:1090800085D0AFF78281B73FCD45D1751352B5BFBB +:109090009FDEE0C3F034F73F0090E6797FCCD7BF86 +:1090A0001FE92C6A7813F73F00000DC2EE6FD7BF9F +:1090B000A0B5FA0860F2F63F00E05113E313D7BF02 +:1090C0007D8C131FA6D1F63F007828385BB8D6BF39 +:1090D000D1B4C50B49B1F63F00788090555DD6BF3D +:1090E000BA0C2F334791F63F00001876D002D6BF56 +:1090F000234222189F71F63F00909086CAA8D5BFE0 +:10910000D91EA5994F52F63F00500356434FD5BF85 +:10911000C4248FAA5633F63F00406BC337F6D4BF42 +:1091200014DC9D6BB314F63F0050A8FDA79DD4BF7F +:109130004C5CC65264F6F53F00A889399245D4BF0D +:109140004F2C91B567D8F53F00B8B039F4EDD3BFD7 +:10915000DE905BCBBCBAF53F00708F44CE96D3BF98 +:10916000781AD9F2619DF53F00A0BD171E40D3BF0C +:10917000875646125680F53F008046EFE2E9D2BF9F +:10918000D36BE7CE9763F53F00E030381B94D2BF36 +:10919000937FA7E22547F53F0088DA8CC53ED2BF12 +:1091A00083450642FF2AF53F00902729E1E9D1BF18 +:1091B000DFBDB2DB220FF53F00F8482B6D95D1BF24 +:1091C000D7DE34478FF3F43F00F8B99A6741D1BF37 +:1091D0004028DECF43D8F43F0098EF94D0EDD0BFC5 +:1091E000C8A378C03EBDF43F0010DB18A59AD0BFDD +:1091F0008A25E0C37FA2F43F00B86352E647D0BFA0 +:109200003484D4240588F43F00F0864522EBCFBF98 +:109210000B2D191BCE6DF43F00B017754A47CFBF19 +:10922000541839D3D953F43F0030103D44A4CEBF75 +:109230005A84B444273AF43F00B0E9440D02CEBF4B +:10924000FBF81541B520F43F00F07729A260CDBFAF +:10925000B1F43EDA8207F43F0090950401C0CCBF20 +:109260008FFE575D8FEEF33F001089562920CCBF4B +:10927000E94C0BA0D9D5F33F0010818D1781CBBFEE +:109280002BC110C060BDF33F00D0D3CCC9E2CABF30 +:10929000B8DA752B24A5F33F0090122E4045CABFC3 +:1092A00002D09FCD228DF33F00F01D6877A8C9BF83 +:1092B0001C7A84C55B75F33F003048696D0CC9BFEB +:1092C000E236AD49CE5DF33F00C045A62071C8BF70 +:1092D00040D44D987946F33F003014B48FD6C7BFC1 +:1092E00024CBFFCE5C2FF33F0070623CB83CC7BF7D +:1092F000490DA1757718F33F0060379B9AA3C6BF4D +:1093000090393E37C801F33F00A0B754310BC6BFB8 +:1093100041F895BB4EEBF23F003024767D73C5BF1C +:10932000D1A919020AD5F23F0030C28F7BDCC4BF3D +:109330002AFDB7A8F9BEF23F0000D2512C46C4BFA7 +:10934000AB1B0C7A1CA9F23F000083BC8AB0C3BFE0 +:1093500030B514607293F23F0000496B991BC3BF94 +:10936000F5A15757FA7DF23F0040A4905487C2BF41 +:10937000BF3B1D9BB368F23F00A079F8B9F3C1BFB2 +:10938000BDF58F839D53F23F00A02C25C860C1BF5F +:109390003B08C9AAB73EF23F0020F7577FCEC0BFB7 +:1093A000B640A92B012AF23F00A0FE49DC3CC0BF19 +:1093B0003241CC967915F23F00804BBCBD57BFBF00 +:1093C0009BFCD21D2001F23F004040960837BEBFF3 +:1093D0000B484D49F4ECF13F0040F93E9817BDBFF2 +:1093E00069658F52F5D8F13F00A0D84E67F9BBBF31 +:1093F0007C7E571123C5F13F00602F2079DCBABF76 +:10940000E926CB747CB1F13F008028E7C3C0B9BF27 +:10941000B61A2C0C019EF13F00C072B346A6B8BF2D +:10942000BD70B67BB08AF13F0000ACB3018DB7BF11 +:10943000B6BCEF258A77F13F00003845F174B6BF1E +:10944000DA314C358D64F13F0080876D0E5EB5BF1B +:10945000DD5F2790B951F13F00E0A1DE5C48B4BF69 +:109460004CD232A40E3FF13F00A06A4DD933B3BFB6 +:10947000DAF910728B2CF13F0060C5F87920B2BF89 +:1094800031B5EC28301AF13F00206298460EB1BF8A +:10949000AF3484DAFB07F13F0000D26A6CFAAFBF49 +:1094A000B36B4E0FEEF5F03F0040774A8DDAADBF5B +:1094B000CE9F2A5D06E4F03F000085E4ECBCABBF24 +:1094C00021A52C6344D2F03F00C0124089A1A9BF5E +:1094D0001A98E27CA7C0F03F00C002335888A7BFAB +:1094E000D136C6832FAFF03F0080D6675E71A5BF2F +:1094F0003913A098DB9DF03F008065498A5CA3BFCB +:10950000DFE752AFAB8CF03F00401564E349A1BFE9 +:10951000FB284E2F9F7BF03F0080EB82C0729EBFE6 +:10952000198F358CB56AF03F00805252F1559ABFC1 +:109530002CF9ECA5EE59F03F008081CF623D96BF3B +:10954000902CD1CD4949F03F0000AA8CFB2892BF56 +:10955000A9ADF0C6C638F03F0000F9207B318CBFC2 +:10956000A93279136528F03F0000AA5D351984BF40 +:109570004873EA272418F03F0000ECC2031278BFBA +:1095800095B114060408F03F00002479090460BF77 +:109590001AFA26F71FE0EF3F00009084F3EF6F3FC9 +:1095A00074EA61C21CA1EF3F00003D3541DC873FFA +:1095B0002E9981B01063EF3F0080C2C4A3CE933FC9 +:1095C000CDADEE3CF625EF3F00008914C19F9B3FD7 +:1095D000E7139103C8E9EE3F000011CED8B0A13FD8 +:1095E000ABB1CB7880AEEE3F00C001D05B8AA53F27 +:1095F0009B0C9DA21A74EE3F0080D840835CA93F6B +:10960000B5990A83913AEE3F008057EF6A27AD3F44 +:10961000569A6009E001EE3F00C098E59875B03FAA +:1096200098BB77E501CAED3F00200DE3F553B23F4B +:1096300003917C0BF292ED3F0000388BDD2EB43F9E +:10964000CE5CFB66AC5CED3F00C057875906B63F69 +:109650009DDE5EAA2C27ED3F00006A3576DAB73F23 +:10966000CD2C6B3E6EF2EC3F00601C4E43ABB93F1D +:109670000279A7A26DBEEC3F00600DBBC778BB3F6F +:109680006D08376D268BEC3F0020E7321343BD3F5A +:1096900004585DBD9458EC3F0060DE71310ABF3F55 +:1096A0008C9FBB33B526EC3F0040912B1567C03F24 +:1096B0003FE7ECEE83F5EB3F00B092828547C13F78 +:1096C000C196DB75FDC4EB3F0030CACD6E26C23FAC +:1096D000284A860C1E95EB3F0050C5A6D703C33F12 +:1096E0002C3EEFC5E265EB3F0010333CC3DFC33FC8 +:1096F0008B88C9674837EB3F00807A6B36BAC43F26 +:109700004A301D214B09EB3F00F0D1283993C53F6A +:109710007EEFF285E8DBEA3F00F01824CD6AC63F11 +:10972000A23D60311DAFEA3F009066ECF840C73FB4 +:10973000A758D33FE682EA3F00F01AF5C015C83FAC +:109740008B7309EF4057EA3F0080F65429E9C83F80 +:10975000274BAB902A2CEA3F0040F80236BBC93FAA +:10976000D1F29313A001EA3F00002C1CED8BCA3FFD +:109770001B3CDB249FD7E93F00D0015C515BCB3F12 +:1097800090B1C70525AEE93F00C0BCCC6729CC3FEE +:109790002FCE97F22E85E93F006048D535F6CC3FB5 +:1097A000754BA4EEBA5CE93F00C04634BDC1CD3F65 +:1097B0003848E79DC634E93F00E0CFB8018CCE3F82 +:1097C000E652672F4F0DE93F009017C00955CF3F74 +:1097D0009DD7FF8E52E6E83F00B81F126C0ED03FB7 +:1097E0007C00CC9FCEBFE83F00D0930EB871D03F35 +:1097F0000EC3BEDAC099E83F0070869E6BD4D03F9E +:10980000FB1723AA2774E83F00D04B338736D13F9C +:10981000089AB3AC004FE83F004823670D98D13F4A +:10982000553E65E8492AE83F0080CCE0FFF8D13F8B +:109830006002F4950106E83F006863D75F59D23FA4 +:1098400029A3E06325E2E73F00A8140930B9D23F1D +:10985000ADB5DC77B3BEE73F006043107218D33F6D +:10986000C2259767AA9BE73F0018EC6D2677D33F88 +:10987000570617F20779E73F0030AFFB4FD5D33FCC +:109880000C13D6DBCA56E73F00E02FE3EE32D43F9D +:109890006BB64F010010E63F3C5B42916C027E3C90 +:1098A00095B44D030030E63F415D0048EABF8D3C72 +:1098B00078D4940D0050E63FB7A5D686A77F8E3C9E +:1098C000AD6F4E070070E63F4C25546BEAFC613CDF +:1098D000AE0FDFFEFF8FE63FFD0E594C277E7CBCAE +:1098E000BCC5630700B0E63F01DADC4868C18ABC4A +:1098F000F6C15C1E00D0E63F1193499D1C3F833C9E +:109900003EF605EBFFEFE63F532DE21A04807EBCE6 +:109910008097860E0010E73F5279097166FF7B3C05 +:1099200012E967FCFF2FE73F2487BD26E2008C3C4D +:109930006A1181DFFF4FE73FD201F16E91026EBCE9 +:10994000909C670F0070E73F749C54CD71FC67BC1E +:1099500035C87EFAFF8FE73F8304F59EC1BE813C88 +:10996000E6C220FEFFAFE73F6564CC29177E70BCDE +:1099700000C93FEDFFCFE73F1C8B7B08728080BCA6 +:10998000761A26E9FFEFE73FAEF99D6D28C08D3CC2 +:10999000E8A39C040010E83F334CE551D27F893C9A +:1099A0008F2C93170030E83F81F330B6E9FE8ABC74 +:1099B0009C7333060050E83FBC35656BBFBF893CE4 +:1099C000C68942200070E83F757B11F365BF8BBCF0 +:1099D0000479F5EBFF8FE83F57CB3DA26E0089BCC1 +:1099E000DF04BC2200B0E83F0A4BE038DF007DBC5A +:1099F0008A1B0CE5FFCFE83F059FFF46710088BC3E +:109A0000438E91FCFFEFE83F38707AD07B81833C36 +:109A1000C75FFA1E0010E93F03B4DF76913E893C30 +:109A2000B97B46130030E93F7602984B4E807F3C6D +:109A30006F07EEE6FF4FE93F2E62FFD9F07E8FBC45 +:109A4000D1123CDEFF6FE93FBA382696AA8270BC7D +:109A50000D8A45F4FF8FE93FEFA864911B8087BC16 +:109A60003E2E98DDFFAFE93F37935A8AE04087BC2E +:109A700066FB49EDFFCFE93F00E09BC108CE3F3CCC +:109A8000519CF12000F0E93F0A5B8827AA3F8ABC7D +:109A900006B045110010EA3F56DA589948FF743C69 +:109AA000FAF6BB070030EA3F186D2B8AABBE8C3C40 +:109AB000791D97100050EA3F307978DDCAFE883C66 +:109AC000482EF51D0070EA3FDBABD83D76418FBCD8 +:109AD0005233591C0090EA3F1276C28402BF8EBCFA +:109AE0004B3E4F2A00B0EA3F5F3FFF3C04FD69BC9C +:109AF000D11EAED7FFCFEA3FB4709012E73E82BCD2 +:109B0000780451EEFFEFEA3FA3DE0EE03E066A3C2A +:109B10005B0D65DBFF0FEB3FB90A1F38C8065A3CE7 +:109B200057CAAAFEFF2FEB3F1D3C23741E0179BCD0 +:109B3000DCBA95D9FF4FEB3F9F2A866810FF79BCAE +:109B40009C659E240070EB3F3E4F86D045FF8A3CCB +:109B5000401687F9FF8FEB3FF9C3C29677FE7C3C36 +:109B60004FCB04D2FFAFEB3FC42BF2EE27FF63BC19 +:109B7000455C41D2FFCFEB3F21EA3BEEB7FF6CBC27 +:109B8000DF0963F8FFEFEB3F5C0B2E97034181BCCD +:109B90005376B5E1FF0FEC3F196AB79464C18B3C73 +:109BA000E357FAF1FF2FEC3FEDC6308DEFFE64BCBA +:109BB00024E4BFDCFF4FEC3F7547ECBC683F84BC3E +:109BC000F7B954EDFF6FEC3FECE053F0A37E843C1B +:109BD000D58F99EBFF8FEC3FF192F98D0683733CA3 +:109BE0009A21252100B0EC3F040E18648EFD68BC5C +:109BF0009C4694DDFFCFEC3F72EAC71CBE7E8E3CD4 +:109C000076C4FDEAFFEFEC3FFE889FAD39BE8E3C87 +:109C10002BF89A160010ED3F715AB9A8917D753C4A +:109C20001DF70F0D0030ED3FDAC7706990C1893C18 +:109C3000C40F79EAFF4FED3F0CFE58C5370E58BCF4 +:109C4000E587DC2E0070ED3F440FC14DD6807FBC10 +:109C5000AA82DC210090ED3F5C5CFD948F7C74BC9B +:109C600083026BD8FFAFED3F7E6121C51D7F8C3C29 +:109C700039476C2900D0ED3F53B1FFB29E01883CBB +:109C8000F59044E5FFEFED3F89CC52C6D2006E3C23 +:109C900094F6ABCDFF0FEE3FD2692D2040837FBC01 +:109CA000DDC852DBFF2FEE3F64081BCAC1007B3CBE +:109CB000EF1642F2FF4FEE3F51AB94B0A8FF723C5B +:109CC000115E8AE8FF6FEE3F59BEEFB173F657BCE5 +:109CD0000DFF9E110090EE3F01C80B5E8D8084BC8D +:109CE0004417A5DFFFAFEE3FB52043D50600783C13 +:109CF000A17F121A00D0EE3F925C5660F80250BC71 +:109D0000C4BCBA0700F0EE3F11E6355D444085BCA7 +:109D1000028D7AF5FF0FEF3F0591EF3931FB4FBC14 +:109D2000C78AE51E0030EF3F551173F2AC818A3CC3 +:109D3000943482F5FF4FEF3F43C7D7D4413F8A3C6D +:109D40006B4CA9FCFF6FEF3F7578981CF40262BC66 +:109D500041C4F9E1FF8FEF3F4BE777F4D17D773CCA +:109D60007EE3E0D2FFAFEF3F31A37C9A19016FBCD5 +:109D70009EE4771C00D0EF3FB1ACCE4BEE81713C3E +:109D800031C3E0F7FFEFEF3F5A87700137056EBC34 +:109D90006E6065F4FF0FF03FDA0A1C49AD7E8ABCA5 +:109DA000587A86F3FF2FF03FE0B2FCC3697F97BC7F +:109DB000170DFCFDFF4FF03F5B94CB34FEBF973C8B +:109DC000824DCD030070F03FCB56E4C08300823C4F +:109DD000E8CBF2F9FF8FF03F1A7537BEDFFF6DBC9D +:109DE00065DA0C0100B0F03FEB26E6AE7F3F91BC98 +:109DF00038D3A40100D0F03FF79F4879FA7D803C2A +:109E0000FDFDDAFAFFEFF03FC06BD670050477BCBA +:109E100096FDBA0B0010F13F620B6D84D4808E3C2E +:109E20005DF4E5FAFF2FF13FEF36FD64FABF9D3C8C +:109E3000D99AD50D0050F13FAE50127077009A3C80 +:109E40009A55210F0070F13FEEDEE3E2F9FD8D3C03 +:109E5000265427FCFF8FF13F73723BDC3000913CAE +:109E6000593C3D1200B0F13F88010380797F993C55 +:109E7000B79E29F8FFCFF13F678C9FAB32F965BCE5 +:109E800000D48AF4FFEFF13FEB5BA79DBF7F933CCB +:109E9000A4868B0C0010F23F225BFD916B809F3CEF +:109EA000034385030030F23F33BF9FEBC2FF933C77 +:109EB00084F6BCFFFF4FF23F722E2E7EE701763C08 +:109EC000D92129F5FF6FF23F610C7F76BBFC7F3C07 +:109ED0003C3A93140090F23F2B41023CCA0272BC00 +:109EE0001363551400B0F23F021FF233828092BC1C +:109EF0003B52FEEBFFCFF23FF2DC4F387EFF88BCD7 +:109F000096ADB80B00F0F23FC541305051FF85BC13 +:109F1000AFE27AFBFF0FF33F9D285E88710081BCA2 +:109F20007F5FACFEFF2FF33F15B7B73F5DFF91BCDE +:109F30005667A60C0050F33FBD828B22827F953C72 +:109F400021F7FB110070F33FCCD50DC4BA00803C63 +:109F5000B92F59F9FF8FF33F51A7B22D9D3F94BC04 +:109F600042D2DD0400B0F33FE13876706B7F853C70 +:109F700057C9B2F5FFCFF33F3112BF103A027A3C16 +:109F800018B4B0EAFFEFF33FB052B1666D7F983C72 +:109F9000F4AF32150010F43F2485195F37F8673CA1 +:109FA000298B47170030F43F4351DC72E601833CB4 +:109FB00063B495E7FF4FF43F5A89B2B869FF893C13 +:109FC000E07504E8FF6FF43F54F2C29BB1C095BC4A +:109FD000E7C16FEFFF8FF43F722A3AF209409B3CD2 +:109FE00004A7BEE5FFAFF43F457D0DBFB7FF94BCAE +:109FF000DE27101700D0F43F3D6ADC7164C099BCC5 +:10A00000E23EF00F00F0F43F1C53850B897F973C34 +:10A01000D14BDC120010F53F36A466716504603C3C +:10A020007A2705160030F53F093223CECEBF96BC05 +:10A030004C70DBECFF4FF53FD7A10505720289BCE0 +:10A04000A9545FEFFF6FF53F1264C90EE6BF9B3C5A +:10A050001210E6170090F53F90EFAF81C57E883C67 +:10A06000923EC90300B0F53FC00CBF0A08419FBC37 +:10A07000BC19491D00D0F53F294725FB2A8198BC12 +:10A08000897AB8E7FFEFF53F0469ED80B77E94BCAD +:10A0900000000000000000000000000000000000C0 +:10A0A00000000000000000000000000000000000B0 +:10A0B00000000000000000000000000000000000A0 +:10A0C0000000000000000000000000000000000090 +:10A0D0000000000000000000000000000000000080 +:10A0E0000000000000000000000000000000000070 +:10A0F0000000000000000000000000000000000060 +:10A10000000000000000000000000000000000004F +:10A11000000000000000000000000000000000003F +:10A12000000000000000000000000000000000002F +:10A13000000000000000000000000000000000001F +:10A14000000000000000000000000000000000000F +:10A1500000000000000000000000000000000000FF +:10A1600000000000000000000000000000000000EF +:10A1700000000000000000000000000000000000DF +:10A1800000000000000000000000000000000000CF +:10A1900000000000000000000000000000000000BF +:10A1A00000000000000000000000000000000000AF +:10A1B000000000000000000000000000000000009F +:10A1C000000000000000000000000000000000008F +:10A1D000000000000000000000000000000000007F +:10A1E000000000000000000000000000000000006F +:10A1F000000000000000000000000000000000005F +:10A20000000000000000000000000000000000004E +:10A21000000000000000000000000000000000003E +:10A22000000000000000000000000000000000002E +:10A23000000000000000000000000000000000001E +:10A24000000000000000000000000000000000000E +:10A2500000000000000000000000000000000000FE +:10A2600000000000000000000000000000000000EE +:10A2700000000000000000000000000000000000DE +:10A2800000000000000000000000000000000000CE +:10A2900000000000000000000000000000000000BE +:10A2A00000000000000000000000000000000000AE +:10A2B000000000000000000000000000000000009E +:10A2C000000000000000000000000000000000008E +:10A2D000000000000000000000000000000000007E +:10A2E000000000000000000000000000000000006E +:10A2F000000000000000000000000000000000005E +:10A30000000000000000000000000000000000004D +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000000000000000000076 +:10AAE0000000000000000000000000000000000066 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB20000000000000000000000000000000000025 +:10AB30000000000000000000000000000000000015 +:10AB40000000000000000000000000000000000005 +:10AB500000000000000000000000000000000000F5 +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00000000000000000000000000000000000A5 +:10ABB0000000000000000000000000000000000095 +:10ABC0000000000000000000000000000000000085 +:10ABD0000000000000000000000000000000000075 +:10ABE0000000000000000000000000000000000065 +:10ABF0000000000000000000000000000000000055 +:10AC00000000000000000000000000000000000044 +:10AC10000000000000000000000000000000000034 +:10AC20000000000000000000000000000000000024 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF0000000000000000000000000000000000051 +:10B000000000000000000000000000000000000040 +:10B010000000000000000000000000000000000030 +:10B020000000000000000000000000000000000020 +:10B030000000000000000000000000000000000010 +:10B040000000000000000000000000000000000000 +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B0900000000000000000000000000000000000B0 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F000000000000000000000000000000000000000 +:10F0100000000000000000000000000000000000F0 +:10F0200000000000000000000000000000000000E0 +:10F0300000000000000000000000000000000000D0 +:10F0400000000000000000000000000000000000C0 +:10F0500000000000000000000000000000000000B0 +:10F0600000000000000000000000000000000000A0 +:10F070000000000000000000000000000000000090 +:10F080000000000000000000000000000000000080 +:10F090000000000000000000000000000000000070 +:10F0A0000000000000000000000000000000000060 +:10F0B0000000000000000000000000000000000050 +:10F0C0000000000000000000000000000000000040 +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000000000000000000020 +:10F0F0000000000000000000000000000000000010 +:10F1000000000000000000000000000000000000FF +:10F1100000000000000000000000000000000000EF +:10F1200000000000000000000000000000000000DF +:10F1300000000000000000000000000000000000CF +:10F1400000000000000000000000000000000000BF +:10F1500000000000000000000000000000000000AF +:10F16000000000000000000000000000000000009F +:10F17000000000000000000000000000000000008F +:10F18000000000000000000000000000000000007F +:10F19000000000000000000000000000000000006F +:10F1A000000000000000000000000000000000005F +:10F1B000000000000000000000000000000000004F +:10F1C000000000000000000000000000000000003F +:10F1D000000000000000000000000000000000002F +:10F1E000000000000000000000000000000000001F +:10F1F000000000000000000000000000000000000F +:10F2000000000000000000000000000000000000FE +:10F2100000000000000000000000000000000000EE +:10F2200000000000000000000000000000000000DE +:10F2300000000000000000000000000000000000CE +:10F2400000000000000000000000000000000000BE +:10F2500000000000000000000000000000000000AE +:10F26000000000000000000000000000000000009E +:10F27000000000000000000000000000000000008E +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F000000000000000000000000000000000000E +:10F3000000000000000000000000000000000000FD +:10F3100000000000000000000000000000000000ED +:10F3200000000000000000000000000000000000DD +:10F3300000000000000000000000000000000000CD +:10F3400000000000000000000000000000000000BD +:10F3500000000000000000000000000000000000AD +:10F36000000000000000000000000000000000009D +:10F37000000000000000000000000000000000008D +:10F38000000000000000000000000000000000007D +:10F39000000000000000000000000000000000006D +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D000000000000000000000000000000000002D +:10F3E000000000000000000000000000000000001D +:10F3F000000000000000000000000000000000000D +:10F4000000000000000000000000000000000000FC +:10F4100000000000000000000000000000000000EC +:10F4200000000000000000000000000000000000DC +:10F4300000000000000000000000000000000000CC +:10F4400000000000000000000000000000000000BC +:10F4500000000000000000000000000000000000AC +:10F46000000000000000000000000000000000009C +:10F47000000000000000000000000000000000008C +:10F48000000000000000000000000000000000007C +:10F49000000000000000000000000000000000006C +:10F4A000000000000000000000000000000000005C +:10F4B000000000000000000000000000000000004C +:10F4C000000000000000000000000000000000003C +:10F4D000000000000000000000000000000000002C +:10F4E000000000000000000000000000000000001C +:10F4F000000000000000000000000000000000000C +:10F5000000000000000000000000000000000000FB +:10F5100000000000000000000000000000000000EB +:10F5200000000000000000000000000000000000DB +:10F5300000000000000000000000000000000000CB +:10F5400000000000000000000000000000000000BB +:10F5500000000000000000000000000000000000AB +:10F56000000000000000000000000000000000009B +:10F57000000000000000000000000000000000008B +:10F58000000000000000000000000000000000007B +:10F59000000000000000000000000000000000006B +:10F5A000000000000000000000000000000000005B +:10F5B000000000000000000000000000000000004B +:10F5C000000000000000000000000000000000003B +:10F5D000000000000000000000000000000000002B +:10F5E000000000000000000000000000000000001B +:10F5F000000000000000000000000000000000000B +:10F6000000000000000000000000000000000000FA +:10F6100000000000000000000000000000000000EA +:10F6200000000000000000000000000000000000DA +:10F6300000000000000000000000000000000000CA +:10F6400000000000000000000000000000000000BA +:10F6500000000000000000000000000000000000AA +:10F66000000000000000000000000000000000009A +:10F67000000000000000000000000000000000008A +:10F68000000000000000000000000000000000007A +:10F69000000000000000000000000000000000006A +:10F6A000000000000000000000000000000000005A +:10F6B000000000000000000000000000000000004A +:10F6C000000000000000000000000000000000003A +:10F6D000000000000000000000000000000000002A +:10F6E000000000000000000000000000000000001A +:10F6F000000000000000000000000000000000000A +:10F7000000000000000000000000000000000000F9 +:10F7100000000000000000000000000000000000E9 +:10F7200000000000000000000000000000000000D9 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000000000099 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F860000000000000000000000000000000000098 +:10F870000000000000000000000000000000000088 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF0000000000000000000000000000000000001 +:020000022000DC +:1000000000000000000000000000000000000000F0 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:1020000012ED20324006000A0E0A000103010810FA +:1020100032004006280A0000000C01000000000009 +:1020200000135359040600000000000000080109D5 +:10203000000132344006000028191A000000080090 +:102040000000080000000800000008000000080070 +:10205000000008000000080000000800F0EF000089 +:10206000000008000000080000000800F0EF000079 +:102070000000080000000800000008000000000048 +:10208000000101000000000000000000000000004E +:10209000000000000000000000000101010101003B +:1020A0000001010000000101010100010000000029 +:1020B0000100000102000000070000000107010309 +:1020C000020314000A0A4000000078003C000000EF +:1020D0000000000000000000000000000000000000 +:1020E0000000000000000000C800C8009600C80002 +:1020F00007078000800005050000000000000000C8 +:1021000006010000000017003900910010001400C3 +:10211000F9FFC4FFFF7FFF7FFF7FFF7FFA002C01E5 +:102120003200C8000A04B4B43232230500000000B3 +:1021300000070D0000320D00000000203232323264 +:1021400032323232323232323232323232320000D3 +:10215000000000000000000000000000000000007F +:102160000A05000A00000000140F001210120000FF +:10217000000000000000000000000000000000005F +:10218000000000000F233246500000006A645046F1 +:102190003C3C3C3C08000000000000000F2332469D +:1021A000500000006A6450463C3C3C3C0F141E2822 +:1021B000000000000A0A0A0A0A0A0A0A0C192D413C +:1021C0005000000046554B4646464646000000007B +:1021D0000A0314005F00F1FF14000F000A00BC02A4 +:1021E00000000000F8FF00007800320064002800C2 +:1021F0000F000F001C023D011C02740400003F068A +:102200000000FF09F40100003F060000FF0932143E +:10221000021E1E32020096003C003C007700C805FA +:10222000770088090000000040063000200001000F +:10223000220000003A00520070008F00AF00CF0073 +:10224000EF000F012E014F016E018E01AD01CE0195 +:10225000EC010F022D024D026D028D02AC02CC0288 +:10226000EB020B032B034A036A038903AA03C90386 +:10227000E703FF0337040000000000000000000037 +:10228000000000000000000000000000000000004E +:10229000000000000000000000000000000000003E +:1022A000000000000000000000000000000000002E +:1022B000000000000000000000000000000000001E +:1022C000000000000000000000000000000000000E +:1022D00000000000000000000000000000000000FE +:1022E00000000000000000000000000000000000EE +:1022F00000000000000000000000280A3000460036 +:102300000100480000003C00430066008500A90071 +:10231000C800E90009012A0149016B018901AB01EB +:10232000C901EB0109022B024A026C028A02AC02CB +:10233000CA02EC020B032D034B036D038B03AE03A8 +:10234000CB03EE030C042F044C046F048B04AF0486 +:10235000CC04EF040D0530054D0570058D05B00565 +:10236000CD05F1050D0630064E0672068E06B10645 +:10237000CE06F2060F073207500773079007B30720 +:10238000D107F40711083408520875089108B108FC +:10239000C608E70800000000000000000000000080 +:1023A000000000000000000000000000000000002D +:1023B000000000000000000000000000000000001D +:1023C000000000000000000000000000000000000D +:1023D0000201200019450000F16C000084D90600BC +:1023E00029B1010010270000C4090000000101010B +:1023F000010102020202014B0F00A00000000000D8 +:102400000100010101010102020202001945000060 +:1024100002000000A46B00000000000014140A0A6F +:102420001400000000000000141414140101010144 +:10243000010040003200E8030F0008000500900092 +:1024400000001E502800B4005000040000000000EE +:10245000B4005000FA00A000000000014F0100008D +:102460000000000068010D0D0A094B004B006400DC +:102470000A003200C800640064000F02E8E8F800B7 +:10248000F8000200190000006A00750081008E004B +:102490009D00AC00BD00CF00E200F7000D01260159 +:1024A00040015C0179019901BC01E00106023002A2 +:1024B0005B028902BA02EE0224035D039A03D90388 +:1024C0001B046004A904F40443059505E9054106CD +:1024D0009C06FA065B07BE0724088D08F808650904 +:1024E000D409450AB80A2D0BA20B190C900C080D43 +:1024F000800DF80D6F0EE60E5C0FD00F4210B3107A +:1025000021118C11F4115912BA1217137013C4133C +:1025100013145D14A114E01418154B1577159C15B0 +:10252000BB15D415E515EF15F31536003D00440035 +:102530004C00560060006B00770085009300A400FB +:10254000B500C900DE00F5000E0129014601650154 +:102550008701AC01D401FE012B025B028F02C6028F +:1025600001033F038003C6030F045D04AE040305AB +:102570005D05BA051B068106EA065707C9073D082F +:10258000B6083109B009320AB70A3E0BC70B520C24 +:10259000DF0C6D0DFC0D8B0E1A0FA80F3610C3103B +:1025A0004D11D6115B12DE125C13D7134D14BD14FE +:1025B00028158D15EC1544169516DE161F1758179D +:1025C0008917B117D117E717F517FA174E005600FC +:1025D00060006B00760083009100A000B100C20093 +:1025E000D600EB0002011A01350152017001910180 +:1025F000B501DB0103022E025C028D02C102F8026A +:1026000032036F03B003F4033B048604D4042605AD +:102610007C05D50532069206F5065C07C607330829 +:10262000A30816098C09040A7E0AFA0A790BF80B2A +:10263000790CFB0C7E0D010E830E060F870F071021 +:10264000861003117D11F5116912DA124713AF13C9 +:1026500013147214CB141E156B15B215F2152C162B +:102660005E168916AC16C716DB16E716EB166A005F +:10267000750081008E009D00AC00BD00CF00E2001F +:10268000F7000D01260140015C0179019901BC01AF +:10269000E001060230025B028902BA02EE02240364 +:1026A0005D039A03D9031B046004A904F4044305E1 +:1026B0009505E90541069C06FA065B07BE07240856 +:1026C0008D08F8086509D409450AB80A2D0BA20B34 +:1026D000190C900C080D800DF80D6F0EE60E5C0FB6 +:1026E000D00F4210B31021118C11F4115912BA12EB +:1026F00017137013C41313145D14A114E0141815E8 +:102700004B1577159C15BB15D415E515EF15F3156D +:102710005500550045004200000000000000000088 +:1027200000000000000000000000000000000000A9 +:102730000000000000000000000000000000000099 +:102740000000000000000000000000000000000089 +:102750000000000000000000000000000000000079 +:102760000000000000000000000000000000000069 +:102770000000000000000000000000000000000059 +:102780000000000000000000000000000000000049 +:102790000000000000000000000000000000000039 +:1027A0000000000000000000000000000000000029 +:1027B0000000000000000000000000000000000019 +:1027C0000000000000000000000000000000000009 +:1027D00000000000000000000000000000000000F9 +:1027E00000000000000000000000000000000000E9 +:1027F00000000000000000000000000000000000D9 +:1028000000000000000000000000000000000000C8 +:1028100000000000000000000000000000000000B8 +:1028200000000000000000000000000000000000A8 +:102830000000000000000000000000000000000098 +:102840000000000000000000000000000000000088 +:102850000000000000000000000000000000000078 +:10286000000000000000000000000000A000D200F6 +:1028700004013C0005000000000000000000000012 +:102880000000000000000000000000000000000048 +:102890000000000000000000000000000000000038 +:1028A0000000000000000000000000000000000028 +:1028B0000000000000000000000000000000000018 +:1028C0000000000000000000000000000000000008 +:1028D00000000000000000000000000000000000F8 +:1028E00000000000000000000000000000000000E8 +:1028F00000000000000000000000000000000000D8 +:1029000000000000000000000000000000000000C7 +:1029100000000000000000000000000000000000B7 +:1029200000000000000000000000000000000000A7 +:102930000000000000000000000000000000000097 +:102940000000000000000000000000000000000087 +:102950000000000000000000000000000000000077 +:102960000000000000000000000000000000000067 +:102970000000000000000000000000000000000057 +:102980000000000000000000000000000000000047 +:102990000000000000000000000000000000000037 +:1029A0000000000000000000000000000000000027 +:1029B0000000000000000000000000000000000017 +:1029C0000000000000000000000000000000000007 +:1029D00000000000000000000000000000000000F7 +:1029E00000000000000000000000000000000000E7 +:1029F00000000000000000000000000000000000D7 +:102A000019010200000000000000000032021092D4 +:102A10000303535900000000000000000000000004 +:102A200099020000BC020000DF0200000203000067 +:102A300025030000480300006B0300008E03000024 +:102A4000B1030000D4030000F70300001A040000E3 +:102A50003D0400006004000083040000A6040000A0 +:102A6000C904000020030000D4B804020351180078 +:102A700007B28C2363200C0485011C0800000000B1 +:102A800000000000190000005B555555555555557F +:102A90005555555505000000080A000010000A00B1 +:102AA000000000010000000002E00000EC045406F9 +:102AB00084067E07410AA2076A099109B1097E17B7 +:102AC00007B8C30700800000208300000080328028 +:102AD000648096802DB4040F110C0F0F10000F139B +:102AE000A5BA830A18C80F0015101510104310431B +:102AF00020030000D4A8040C42330E0EC4338E23EE +:102B000063011911E32101132302000000000000FA +:102B10001B0000005B555555555555555555555598 +:102B20005505000098090B0BB0B00000B0B0001BB9 +:102B30000B00000082F01002EC04540684067E07AD +:102B4000410AA2076A099109B1097E1707B8C307AC +:102B50000080000020830000008032806480968026 +:102B60002DB4040F110C0F0F10000F13A5BA830A18 +:102B700018C80F0015101510104310432003000053 +:102B8000090000000000000000000000000000003C +:102B90000000000000000000000000000100000034 +:102BA0000300000000000000000000000000000022 +:102BB0000200000000000000000000000000000013 +:102BC00000000000EC04540684067E07410AA207B8 +:102BD0006A099109B1097E1707B8C3070080000090 +:102BE0002083000000803280648096802DB4040F22 +:102BF000110C0F0F10000F13A5BA830A18C80F008D +:102C0000151015101043104320030000D4B804021F +:102C10000351180007B28C2363200C0485011C08A3 +:102C20000000000000000000190000005B55555531 +:102C3000555555555555555555000000086A666659 +:102C400036666A66666666636600000002E000003B +:102C5000EC04540684067E07410AA2076A0991091A +:102C6000B1097E1707B8C307008000002083000069 +:102C700000803280648096802DB4040F110C0F0FF9 +:102C800010000F13A5BA830A18C80F0015101510ED +:102C90001043104320030000D4A8040C42330E0E4E +:102CA000C4338E2363011911E321011323020000B1 +:102CB000000000001B0000005B555555555555554B +:102CC000555555555505000098696B6BB6B6666647 +:102CD000B6B6663B6B06000082F01002EC045406A8 +:102CE00084067E07410AA2076A099109B1097E1785 +:102CF00007B8C307008000002083000000803280F6 +:102D0000648096802DB4040F110C0F0F10000F1368 +:102D1000A5BA830A18C80F001510151010431043E8 +:102D200020030000D4B854161796010000000000DC +:102D30000000000000000000000000000000000093 +:102D4000080000005B555555000000000000000021 +:102D500000000000081A111100000000000000002F +:102D60000000000002000000EC04540684067E0708 +:102D7000410AA2076A099109B1097E1707B8C3077A +:102D800000800000208300000080328064809680F4 +:102D90002DB4040F110C0F0F10000F13A5BA830AE6 +:102DA00018C80F0015101510104310432003000021 +:102DB000D4B854161796010000000000000000006F +:102DC00000000000000000000000000008000000FB +:102DD0005B55555500000000000000000000000099 +:102DE000083A33330000000000000000000000003B +:102DF00002000000EC04540684067E07410AA20784 +:102E00006A099109B1097E1707B8C307008000005D +:102E10002083000000803280648096802DB4040FEF +:102E2000110C0F0F10000F13A5BA830A18C80F005A +:102E3000151015101043104320030000D4A8540CA3 +:102E4000567339184F068D11A3344E000000000050 +:102E50000000000000000000130000005B55555505 +:102E600055555555550500000000000008191B1B5D +:102E70001B1B0B0B0B0B00000000000002A002004C +:102E8000EC04540684067E07410AA2076A099109E8 +:102E9000B1097E1707B8C307008000002083000037 +:102EA00000803280648096802DB4040F110C0F0FC7 +:102EB00010000F13A5BA830A18C80F0015101510BB +:102EC0001043104320030000D4A8540C5673391843 +:102ED0004F068D11A3344E000000000000000000DA +:102EE00000000000130000005B5555555555555521 +:102EF000550500000000000008393B3B3B3B0B0B35 +:102F00000B0B00000000000002A00200EC045406BD +:102F100084067E07410AA2076A099109B1097E1752 +:102F200007B8C307008000002083000000803280C3 +:102F3000648096802DB4040F110C0F0F10000F1336 +:102F4000A5BA830A18C80F001510151010431043B6 +:102F500020030000D4A8051B023774045E311A2335 +:102F6000C7088C08000000000000000000000000FE +:102F7000140000005B5555555555555555550000E5 +:102F800000000000080909090909000010000000FC +:102F90000000000002500500EC04540684067E0781 +:102FA000410AA2076A099109B1097E1707B8C30748 +:102FB00000800000208300000080328064809680C2 +:102FC0002DB4040F110C0F0F10000F13A5BA830AB4 +:102FD00018C80F00151015101043104320030000EF +:102FE000D4A8051B023774045E311A23C7088C0865 +:102FF00000000000000000000000000014000000BD +:103000005B55555555555555555500000000000068 +:10301000086969696969606030600000000000004B +:1030200002500500EC04540684067E07410AA207FC +:103030006A099109B1097E1707B8C307008000002B +:103040002083000000803280648096802DB4040FBD +:10305000110C0F0F10000F13A5BA830A18C80F0028 +:10306000151015101043104320030000D4A8551B61 +:10307000167775185E0600000000000000000000D2 +:1030800000000000000000000C0000005B555555DA +:103090005555000000000000000000000819191933 +:1030A00019190000000000000000000002000000EC +:1030B000EC04540684067E07410AA2076A099109B6 +:1030C000B1097E1707B8C307008000002083000005 +:1030D00000803280648096802DB4040F110C0F0F95 +:1030E00010000F13A5BA830A18C80F001510151089 +:1030F0001043104320030000D4A8551B1677751801 +:103100005E0600000000000000000000000000005B +:10311000000000000C0000005B555555555500009F +:10312000000000000000000008393939393900007A +:10313000000000000000000002000000EC04540643 +:1031400084067E07410AA2076A099109B1097E1720 +:1031500007B8C30700800000208300000080328091 +:10316000648096802DB4040F110C0F0F10000F1304 +:10317000A5BA830A18C80F00151015101043104384 +:1031800020030000E3180803446100070800000062 +:10319000000000000000000000000000000000002F +:1031A0000B00000055555555550500000000000066 +:1031B000000000000000000001000000000000000E +:1031C0000000000003000000EC04540684067E07A3 +:1031D000410AA2076A099109B1097E1707B8C30716 +:1031E0000080000020830000008032806480968090 +:1031F0002DB4040F110C0F0F10000F13A5BA830A82 +:1032000018C80F00151015101043104320030000BC +:10321000D4B8000000000000000000000000000022 +:10322000000000000000000000000000030000009B +:103230005B0500000000000000000000000000002E +:10324000080A00000000000000000000000000006C +:1032500002000000EC04540684067E07410AA2071F +:103260006A099109B1097E1707B8C30700800000F9 +:103270002083000000803280648096802DB4040F8B +:10328000110C0F0F10000F13A5BA830A18C80F00F6 +:10329000151015101043104320030000090500000D +:1032A00000000000C002000000000000000000005C +:1032B0000000000000000000020000006466666676 +:1032C00066660000000000000000000082000000B0 +:1032D00000A000000000000000000000FC0700004B +:1032E000EC04540684067E07410AA2076A09910984 +:1032F000B1097E1707B8C3070080000020830000D3 +:1033000000803280648096802DB4040F110C0F0F62 +:1033100010000F13A5BA830A18C80F001510151056 +:103320001043104320030000813010050670200078 +:10333000000000000000000000000000000000008D +:10334000000000000900000055555555050000001B +:10335000000000000000000000000001000000006C +:10336000000000000000000000000000EC04540613 +:1033700084067E07410AA2076A099109B1097E17EE +:1033800007B8C3070080000020830000008032805F +:10339000648096802DB4040F110C0F0F10000F13D2 +:1033A000A5BA830A18C80F00151015101043104352 +:1033B0000000000000000001000003000000FC000D +:1033C000000000000D000D0040065906000000003E +:1033D0000155B400020000000000000001010302DA +:1033E000000001000000FC00000000000D000D00C6 +:1033F00000000F000000000004B0B3000000001047 +:103400000000000002020302000001000000FC00B6 +:10341000000000000D000D0001000E000000000083 +:1034200004C4B30000000010000000000303030206 +:10343000000001000000FC00000000000D000D0075 +:1034400002000D000000000004D8B30000000010CE +:103450000000000004040302000001000000FC0062 +:10346000000000000D000D0003000C000000000033 +:1034700004ECB3000000001000000000050503028A +:10348000000001000000FC00000000000D000D0025 +:1034900004000B00000000000400B4000000001055 +:1034A0000000000006060302000001000000FC000E +:1034B000000000000D000D0005000A0000000000E3 +:1034C0000414B4000000001000000000070703020D +:1034D000000001000000FC00000000000D000D00D5 +:1034E00006000900000000000428B40000000010DD +:1034F0000000000008080302000005000000FC00B6 +:10350000000000000D000D00070008000000000092 +:10351000043CB4000000001000000000090000019D +:10352000000007000000FC00000000000D000D007E +:10353000A00FB90F000000000150B400000000000F +:103540000000000000000001000003000000FC007B +:10355000000000000D000D00C116A81600000000BC +:1035600001A0B400060000000000000000001717D2 +:10357000000003000000FC00000000000D000D0032 +:103580003818391800000000019BB4000400000046 +:103590000000000000001616010003000000FD00FE +:1035A000000000000D000D00681070100000FA25EA +:1035B0000473B400040000000000000000001717AE +:1035C000020003000000FC00000000000D000D00E0 +:1035D000F811F9110000FA250487B4000400000076 +:1035E0000000000000001616030003000000FD00AC +:1035F000000000000D000D00681070100000FA259A +:103600000473B4000400000000000000000017175D +:10361000040003000000FC00000000000D000D008D +:10362000F811F9110000FA250487B4000400000025 +:103630000000000000001616050003000000FD0059 +:10364000000000000D000D00681070100000FA2549 +:103650000473B4000400000000000000000017170D +:10366000060003000000FC00000000000D000D003B +:10367000F811F9110000FA250487B40004000000D5 +:103680000000000000001616070003000000FD0007 +:10369000000000000D000D00681070100000FA25F9 +:1036A0000473B400040000000000000000001717BD +:1036B000080003000000FC00000000000D000D00E9 +:1036C000F811F9110000FA250487B4000400000085 +:1036D00000000000000A1414002802000000FC0092 +:1036E00000000000050005000000000000000000D0 +:1036F000010097030000000000000000000001002E +:10370000002802000000FC00000000000D000D0079 +:103710000000190000000000015AB400020000007F +:103720000000000000000100002802000000FC0072 +:10373000000000000D000D009001A9010000000034 +:10374000015FB40002000000000000000000010062 +:10375000002802000000FC00000000000D000D0029 +:1037600020033903000000000164B40002000000DF +:103770000000000000000100002802000000FC0022 +:10378000000000000D000D00B004C904000000009E +:103790000169B40002000000000000000000010008 +:1037A000002802000000FC00000000000D000D00D9 +:1037B0004006590600000000016EB400020000003F +:1037C0000000000000000100002802000000FC00D2 +:1037D000000000000D000D006810811000000000C6 +:1037E00001A5B40006000000000000000000010078 +:1037F000002802000000FC00000000000D000D0089 +:10380000F81111120000000001AAB4000600000027 +:103810000000000000000100002802000000FC0081 +:10382000000000000D000D008813A113000000002F +:1038300001AFB4000600000000000000000001001D +:10384000002802000000FC00000000000D000D0038 +:10385000181531150000000001B4B4000600000086 +:103860000000000000000100002802000000FC0031 +:10387000000000000D000D00A816C1160000000099 +:1038800001B9B400060000000000000000000100C3 +:10389000002802000000FC000000000009000900F0 +:1038A0000000000000000000010097030600000077 +:1038B00000000000000B1414002802000000FC00AF +:1038C000000000000C000C000000000000000000E0 +:1038D000010097030000000000000000000B14141A +:1038E000002802000000FC003F0000000C000C005B +:1038F000000000000000000001009703000000002D +:1039000000000000000B1515002802000000CC008C +:10391000000000000C000C0000000000000000008F +:1039200001009703000000000000000000000100FB +:10393000002802000000FC00000000000D000D0047 +:1039400000000000000000000100970306000000D6 +:103950004F00000001F4040068931B0060000000A9 +:103960000C000000010004001428000060000000AA +:10397000300000002D008400142800001C0000000E +:10398000730000002DF4840068931B001C000000ED +:10399000700000002DF4840068931B001C000000E0 +:1039A0007300000023F4840068931B001C000000D7 +:1039B000600000002DF4840068931B001C000000D0 +:1039C0004F00000001F4040068931B00E0000100B8 +:1039D0000C0000000100040014280000E0000100B9 +:1039E000300000002D008400142800001C0000009E +:1039F000700000002DF4840068931B001C00000080 +:103A0000730000002DF4840051651B001C000000B1 +:103A1000010128010101010101010101010101016F +:103A20000101010101010101010101010101010186 +:103A30000101010101010101010101010101010176 +:103A40000101010101010101010101010101010166 +:103A50000101010101010101010101010101010156 +:103A60000101010101010101010101010101010146 +:103A70000101010133323C333533353534333534CC +:103A800033333335353434343434323433343433FB +:103A900033333433353333343334333334343434ED +:103AA00033343335353234343233323232333233E5 +:103AB00032323232323132323233323232323232E6 +:103AC00033323132313133323232333233313332D5 +:103AD000323332342F2F303033323C3335333535B7 +:103AE0003433353433333335353434343434333498 +:103AF000333434333333343335333334333433338F +:103B0000343434343334333535323434323333327D +:103B10003233323332323232323232323233323282 +:103B20003232323233323132313133323232333275 +:103B300033313332323332342F2E302F333233336A +:103B40003333333434333534333333353534343439 +:103B5000343433343334343333333433353333342C +:103B6000333433333334343433343335353234331C +:103B70003233323232333233323232323231323223 +:103B80003133323232323232323231323131333217 +:103B90003232333232313232323232332F2E302F10 +:103BA00033323333333333343433353433333335DF +:103BB00035343434343433343334343333333433CA +:103BC00035333334333433333334343433343335BB +:103BD00035323433323333323233323332323232BB +:103BE00032323232323332323232323232323132B5 +:103BF00031323332323233323331333232323233A2 +:103C00002F2E302F32323333333333343433353491 +:103C10003333333535343434343433343333343369 +:103C2000333334333533333433343333333434345C +:103C30003334333534323433323332323233323355 +:103C40003232313232313232313232323232323257 +:103C50003232313131313332323232323331323247 +:103C6000323232332F2E302F323233333333333438 +:103C70003433353433333335353434343434333406 +:103C800033333433333334333533333433343333FE +:103C900033343434333433353532343332333232EF +:103CA00032333233323231323231323232333232F3 +:103CB00032323232323231323131333232323232E6 +:103CC00033313232323232332F2E302F32323333DD +:103CD00033333334343335343333333535343434A8 +:103CE000343433343334343333333433343333349C +:103CF000333433333334343433343335343234338C +:103D00003233323232323233323231323231323293 +:103D10003132323232323232323231323131333286 +:103D20003132323232313232313232332F2E302F81 +:103D3000333233333333333434333534333333354D +:103D40003534343434343334333434333333343338 +:103D5000343333343334333333343434333433352A +:103D6000343234333233323232323233323231322D +:103D70003231323231323232323232323232313226 +:103D80003131333231323232323132323232323315 +:103D90002F2E302F4B4D5351514F4F514F4F534FAB +:103DA000534F4F51534F4E4D53514D4F4F4F534F14 +:103DB0004F4F4F4F514D4F51514F4F4F534F4F4F0B +:103DC00051534F53554F51514F4F4F4D4F514D4FF1 +:103DD0004F4D4D4D4D4D4F4D4F4F4F4F4F4F4D4F01 +:103DE000514D4D4D4D4F4D4D4F4B4F4D51494D4FF9 +:103DF0004F4F4B4F4B494B4B9224922492009200D1 +:103E000000000000B66DB66DB600B6000000000000 +:103E1000B66DB66D9601960100000000B66DB66DE8 +:103E2000B201B20100000000B62DB62DB601B601F8 +:103E300000000000B665B665B601B60100000000DE +:103E4000B66CB66CB601B60100000000966D966DBA +:103E5000B601B60100000000B26DB26DB601B60148 +:103E600000000000FF7FFF7FFF01FF010000000056 +:103E7000B66DB66DB601B601000000009224922422 +:103E800092009200000000000110000000000000FD +:103E900000000000FFFF3DDB38D4FC020200AA0056 +:103EA0006C768A940001060000000000DB0600002A +:103EB000040C000060056E40415639030100009A71 +:103EC000EC045661000000000000000010C40C501B +:103ED0000390BBBB80442278641164118A3989390C +:103EE00085E00FE06612641201100000000000007F +:103EF00000000000FFFF3DDB38D4FC020200AA00F6 +:103F00006C768A940001060000000000DB060000C9 +:103F1000040C000060056E40415639030100009A10 +:103F2000EC045661000000000000000010C40C10FA +:103F3000E39EBBBB80552278641164118A398939AC +:103F400085E00FE06612641201040000000000002A +:103F50000000000000000000000000020200AA00B3 +:103F60006C768A940001060000000000DB06000069 +:103F7000040C000020066E40418639030100009ABF +:103F8000AC058661000000000000000010C40C5069 +:103F90000390BBBB80442278641164118A3989394B +:103FA00085E00FE066126412C904020001020304F6 +:103FB000EAF7FAFD3001A880CF0304021E000003D7 +:103FC0006C768A940001060000000000DB06000009 +:103FD000014600002B1A0040006B39034100029A91 +:103FE00000006B616478792BCF8A00801C54119893 +:103FF0000080BBBB00572278641164118A3989396B +:1040000085F00FF066126412C9040200010101017B +:10401000EAF7FAFD3001A880CF0304020200000095 +:104020006C768A940001060000000000DB060000A8 +:10403000014600002B1A0040006B39034100029A30 +:1040400000006B61BB7DFC17FFFF00801C541198C2 +:104050000380BBBB80462278641164118A39893998 +:1040600085F00FF066126412C90402000202020217 +:10407000EAF7FAFD3001A880CF0304020200000035 +:104080006C768A940001060000000000DB06000048 +:10409000014600002B1A0040006B39034100029AD0 +:1040A00000006B610F7E3416FFFF00801C541198D6 +:1040B0000380BBBB80462278641164118A39893938 +:1040C00085F00FF066126412C904020003030303B3 +:1040D000EAF7FAFD3001A880CF03040202000000D5 +:1040E0006C768A940001060000000000DB060000E8 +:1040F000014600002B1A0040006B39034100029A70 +:1041000000006B61B17E3C12FFFF00801C541198CF +:104110000380BBBB80462278641164118A398939D7 +:1041200085F00FF066126412C9040200040404044E +:10413000EAF7FAFD3001A880CF0304020200000074 +:104140006C768A940001060000000000DB06000087 +:10415000014600002B1A0040006B39034100029A0F +:1041600000006B611C7F0B0FFFFF00801C54119837 +:104170000380BBBB80462278641164118A39893977 +:1041800085F00FF0661264120104000400000000C4 +:10419000CCF57AFDED20BF8FCF03040202060000AC +:1041A0006C768A940001060000000000DB06000027 +:1041B00001060000093C0040006B39034100029AEF +:1041C00000006B616478792BCF8A00801CC41018C2 +:1041D0000380ABAA00C6227864116411803980394B +:1041E0000F000F00550D550DC904020006070A0BFC +:1041F000EAF7FAFD3001A880CF0304021E0600038F +:104200006C768A940001060000000000DB060000C6 +:10421000014600002B1A0040006B39034100029A4E +:1042200000006B616478792BCF8A00801C54119850 +:104230000080BBBB00572218641164118A39893988 +:1042400085F00FF066126412C90402000606060625 +:10425000EAF7FAFD3001A880CF030402020600004D +:104260006C768A940001060000000000DB06000066 +:10427000014600002B1A0040006B39034100029AEE +:1042800000006B616478792BCF8A00801C541198F0 +:104290000080BBBB00572218641164118A39893928 +:1042A00085F00FF066126412C904020006060A0ABD +:1042B00073EDFAFD5985A880CF0304020A060100B8 +:1042C0006C768A940043060100000000DB060000C3 +:1042D000014600002B1A0040006B39034100029A8E +:1042E00000006B619367CBB40000008012541198FA +:1042F0000080BBBB00562218641164118A398939C9 +:1043000085F00FF066126412C904020007070B0B58 +:1043100073EDFAFD5985A880CF0304020A06010057 +:104320006C768A940043060100000000DB06000062 +:10433000014600002B1A0040006B39034100029A2D +:1043400000006B6155737BC8000000801254119807 +:104350000080BBBB00562218641164118A39893968 +:1043600085F00FF066126412C904020009090C0CF2 +:1043700073EDFAFD5985A880CF0304020A060100F7 +:104380006C768A940043060100000000DB06000002 +:10439000014600002B1A0040006B39034100029ACD +:1043A00000006B61D9770ED3000000801254119881 +:1043B0000080BBBB00562218641164118A39893908 +:1043C00085F00FF066126412C90402000A0A06069C +:1043D00073EDFAFD5985A880CF0304020A06010097 +:1043E0006C768A940043060100000000DB060000A2 +:1043F000014600002B1A0040006B39034100029A6D +:1044000000006B61BD7977D80000008012541198CC +:104410000080BBBB00562218641164118A398939A7 +:1044200085F00FF066126412C90402000B0B070737 +:1044300073EDFAFD5985A880CF0304020A06010036 +:104440006C768A940043060100000000DB06000041 +:10445000014600002B1A0040006B39034100029A0C +:1044600000006B61757B34DE0000008012541198EF +:104470000080BBBB00562218641164118A39893947 +:1044800085F00FF066126412C90402000A0A0606DB +:1044900073EDFAFD5985A880CF0304020A060100D6 +:1044A0006C768A940043060100000000DB060000E1 +:1044B000014600002B1A0040006B39034100029AAC +:1044C00000006B61CB7C87E30000008012541198E0 +:1044D0000080BBBB00562218641164118A398939E7 +:1044E00085F00FF066126412C90402000B0B070777 +:1044F00073EDFAFD5985A880CF0304020A06010076 +:104500006C768A940043060100000000DB06000080 +:10451000014600002B1A0040006B39034100029A4B +:1045200000006B61F27D29E90000008012541198AF +:104530000080BBBB00562218641164118A39893986 +:1045400085F00FF066126412C90402000C0C090910 +:1045500073EDFAFD5985A880CF0304020A06010015 +:104560006C768A940043060100000000DB06000020 +:10457000014600002B1A0040006B39034100029AEB +:1045800000006B61D57EC2EE0000008012541198CD +:104590000080BBBB00562218641164118A39893926 +:1045A00085F00FF0661264120000000000000000A9 +:1045B00000101000000056CE00009910100E0006EA +:1045C0000000FDF900006FA1100E00050000464F2D +:1045D000000029A6100F00040000AD8700007DD95F +:1045E000100F00030000C15A00009C9A0004103014 +:1045F0000000BCA00000903800091033000083D0F8 +:104600000000D635000B10350000C9C200001A5951 +:10461000000C103600008CA100002C9F000D1037FC +:1046200000009851000044DC000E10380000BEEA83 +:104630000000A536000E103A000026620000DD9949 +:10464000000F103B00000000B5000000BF0000009C +:10465000DF000000EC00000019010000280100004C +:1046600043010000530100000000000000000000B2 +:10467000000000000000000000000000000000003A +:10468000000000000000000000000000000000002A +:10469000000000000000000000000000000000001A +:1046A000000000000000000000000000000000000A +:1046B00000000000000000000000000000000000FA +:1046C00000000000870700008579385793F930A172 +:1046D000B3D4CC2BCB0AF200000000000000000095 +:1046E00000000000000000000000000000000000CA +:1046F00000000000000000000000000000000000BA +:1047000080220022870700008579385793E4C2B9D8 +:1047100030AFCC2BC5A1B3000000000000000000AA +:104720000000000000000000000000000000000089 +:104730000000000000000000000000000000000079 +:1047400080220022870700008579385793E4C2BC95 +:10475000C2BCD7930D7930000000000000000000BB +:104760000000000000000000000000000000000049 +:104770000000000000000000000000000000000039 +:1047800080220022870700008579385793E4C2BF52 +:10479000930ACC2BC4F50D000000000000000000BF +:1047A0000000000000000000000000000000000009 +:1047B00000000000000000000000000000000000F9 +:1047C00080220022870700008579385793E4C2BF12 +:1047D000930AE4C2B286CF0000000000000000008F +:1047E00000000000000000000000000000000000C9 +:1047F00000000000000000000000000000000000B9 +:1048000080220022870700008579385793E4C2BFD1 +:10481000930AB0AF26CF5000000000000000000057 +:104820000000000000000000000000000000000088 +:104830000000000000000000000000000000000078 +:1048400080220022870700008579385793E4C2BB95 +:104850000AF2E4C2BE4C2B00000000000000000081 +:104860000000000000000000000000000000000048 +:104870000000000000000000000000000000000038 +:1048800080220022870700008579385793E4C2BB55 +:104890000AF2B0AF295E4C000000000000000000EA +:1048A0000000000000000000000000000000000008 +:1048B00000000000000000000000000000000000F8 +:1048C00080220022C8060000450EA63D450EA63DEA +:1048D000BAF15942450EA63D450EA63D450EA63DF0 +:1048E000450EA63D00000000000000000000000092 +:1048F00000000000000000000000000000000000B8 +:104900008022002231302F2E2D2C2B2A29282726D9 +:104910002524232221201F1E1D1C1B1A19181716BF +:104920001514131211100F0E0D0C0B0A09080706AF +:104930000504030201000000000000000000000068 +:104940000000000000000000000000004A49484745 +:10495000464544434241403F3E3D3C3B3A3938376F +:10496000363534333231302F2E2D2C2B2A2928275F +:10497000262524232221201F1E1D1C1B1A1900007E +:104980000000000000000000000000000000000027 +:10499000000000002000E0C0A08060402000E0C0D7 +:1049A000A08060402000E0C0A08060402000E0C007 +:1049B000A08060402000E0C0A08060402000E0C0F7 +:1049C000A08060402000000076DBB62D2449921BB9 +:1049D000DBB6491292942409090000002000E0C0CF +:1049E000A08060402000E0C0A08060402000E0C0C7 +:1049F000A08060402000E0C0A08060402000E0C0B7 +:104A0000A08060402000E0C0A08060402000000046 +:104A100076DBB62D2449921BDBB649129294240909 +:104A2000090000002021E0E1A0A160612021E0E177 +:104A3000A0A160612021E0E1A0A160612021E0E16E +:104A4000A0A160612021E0E1A0A160612021E0E15E +:104A5000A0A160612021000076DBB62D2449921BC5 +:104A6000DBB6491292942409090000000100C1C07C +:104A7000818041400100C1C0818041400100C1C02E +:104A8000818041400100C1C0818041400100C1C01E +:104A9000818041400100C1C081804140010000008F +:104AA00076DBB62D2449921BDBB649129294240979 +:104AB000090000002120E1E0A1A061602120E1E0E7 +:104AC000A1A061602120E1E0A1A061602120E1E0DE +:104AD000A1A061602120E1E0A1A061602120E1E0CE +:104AE000A1A061602120000076DBB62D2449921B35 +:104AF000DBB64912929424090900000063432303A2 +:104B0000E2C2A28262422202E2C2A2826242220285 +:104B1000E2C2A28262422202E2C2A2826242220275 +:104B2000E2C2A28262422202E2C2A2826242000089 +:104B300000D0B62D2D499224DBB66D1292242509A2 +:104B4000490200002C0CECCCAC8C6C4C2C0CECCC4A +:104B5000AC8C6C4C2C0CECCCAC8C6C4C2C0CECCC95 +:104B6000AC8C6C4C2C0CECCCAC8C6C4C2C0CEBCB87 +:104B7000AB8B6B4B2B0B00002D499224DBB66D12D7 +:104B8000922425094902000040DBB62DA484644428 +:104B90002404E3C3A38363432303E3C3A3836343E3 +:104BA0002303E3C3A38363432303E3C3A3836343D5 +:104BB0002303E3C3A38363432303E3C3A38300006B +:104BC0000000B42D6D4B9224E4B66D1B922449096C +:104BD00049920000EBCBAB8B6B4B2B0BEBCBAB8B36 +:104BE0006B4B2B0BEBCBAB8B6B4B2B0BEBCBAB8B15 +:104BF0006B4B2B0BEBCBAB8B6B4B2B0BEACAAA8A09 +:104C00006A4A2A0AEACA00002449921BDBB6491202 +:104C100092942409090000006DDBB624E5C5A58542 +:104C200065452505E4C4A48464442404E4C4A48440 +:104C300064442404E4C4A48464442404E4C4A48434 +:104C400064442404E4C4A48464442404E4C400004C +:104C50000000002D6DDB922424B96D1B9B244912AA +:104C600049922400AA8A6A4A2A0AEACAAA8A6A4A8D +:104C70002A0AEACAAA8A6A4A2A0AEACAAA8A6A4A94 +:104C80002A0AEACAAA8A6A4A2A0AE9C9A98969498A +:104C90002909E9C9A989000024496E1BDB264912AC +:104CA000529224090000002D6DDB92242606E6C6F0 +:104CB000A68666462606E5C5A58565452505E5C59E +:104CC000A58565452505E5C5A58565452505E5C594 +:104CD000A58565452505E5C5A5856545250500002E +:104CE000090000006DDBB62424496E1BDB26491247 +:104CF0005292240969492909E9C9A98969492909F7 +:104D0000E9C9A98969492909E9C9A9896949290913 +:104D1000E9C9A98969492909E8C8A888684828080B +:104D2000E8C8A8886848000024B96D1B9B24491274 +:104D3000499224000000B42D6D4B92246747270749 +:104D4000E7C7A78767472707E6C6A68666462606FB +:104D5000E6C6A68666462606E6C6A68666462606F3 +:104D6000E6C6A68666462606E6C6A686664600000F +:104D70004902000040DBB62D2449921BDBB64912E4 +:104D8000929424092808E8C8A88868482808E8C830 +:104D9000A88868482808E8C8A88868482808E8C893 +:104DA000A88868482808FFFFFFFFFFFFFFFFFFFFFD +:104DB000FFFFFFFFFFFF0000E4B66D1B92244909CF +:104DC0004992000000F0FF3FFFFFFF3FFFFFFFFFA2 +:104DD000FFFFFFFFFFFFFFFFFFFFE7C7A787674753 +:104DE0002707E7C7A78767472707E7C7A787674753 +:104DF0002707E7C7A78767472707E7C7A7870000F1 +:104E0000FFFFFF3FFFDFB62D2D499224DBB66D1269 +:104E100092242509636261605F5E5D5C5B5A59584C +:104E200057565554535251504F4E4D4C4B4A49488A +:104E300047464544434241403F3E3D3C3B3A39387A +:104E40003736353433320000000000000000000027 +:104E500000000000000000000000000031302F2E94 +:104E60002D2C2B2A292827262524232221201F1EEA +:104E70001D1C1B1A191817161514131211100F0EDA +:104E80000D0C0B0A090807060504030201000000C7 +:104E90000000000000000000000000000000000012 +:104EA00000000000FFFFFFFFFFFFFFFFFFFFFFFF0E +:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:104ED000FFFFFFFFFFFF0000FFFFFF3FFFFFFF3F60 +:104EE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFFFF12 +:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:104F0000FFFFFFFFFFFFFFFFFFFF000000000000AB +:104F10000000000000000000000000000000000091 +:104F2000FFFFFF3FFFFFFF3FFFFFFF3F00000000CD +:104F30000000000057473727170756463626160643 +:104F4000554535251505544434241404534333235F +:104F500013035242322212025141312111015040B9 +:104F600030201000FFFF00000000000000000000E3 +:104F700000000000000000000000003F62605E5C76 +:104F80005A58565452504E4C4A48464442403E3C71 +:104F90003A38363432302E2C2A28262422201E1C61 +:104FA0001A18161412100E0C0A080604020000004B +:104FB00000000000000000000000000000000000F1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE00000000000000000000000000000000000C1 +:104FF00000000000000000000000000000000000B1 +:1050000000000000000000000000000000000000A0 +:105010000000000000000000000000000000000090 +:105020000000000000000000000000000000000080 +:105030000000000000000000000000000000000070 +:105040000000000000000000000000000000000060 +:105050000000000000000000000000000000000050 +:105060000000000000000000000000000000000040 +:105070000000000000000000000000000000000030 +:105080000000000000000000000000000000000020 +:105090000000000000000000000000000000000010 +:1050A0000000000000000000000000000000000000 +:1050B00000000000000000000000000000000000F0 +:1050C00000000000000000000000000000000000E0 +:1050D00000000000000000000000000000000000D0 +:1050E00000000000000000000000000000000000C0 +:1050F00000000000000000000000000000000000B0 +:10510000000000000000000000000000000000009F +:10511000000000000000000000000000000000008F +:10512000000000000000000000000000000000007F +:10513000000000000000000000000000000000006F +:10514000000000000000000000000000000000005F +:10515000000000000000000000000000000000004F +:10516000000000000000000000000000000000003F +:10517000000000000000000000000000000000002F +:10518000000000000000000000000000000000001F +:10519000000000000000000000000000000000000F +:1051A00000000000000000000000000000000000FF +:1051B00000000000000000000000000000000000EF +:1051C00000000000000000000000000000000000DF +:1051D00000000000000000000000000000000000CF +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:105200000801010000000000000000003202100050 +:105210001B00000000000000000000000000000073 +:105220008C0C0000AF0C0000D20C0000F50C00004C +:10523000200300004110080344611C080000000026 +:10524000000000000000000000000000000000005E +:105250000A00000066666666560000000000000056 +:10526000000000000000000000000000000000003E +:105270000000000003000000180DD60D060E1F0EE2 +:10528000530F580E300F420F430F7E1707B8C30756 +:1052900000800000208300000080328064809680BF +:1052A0002DB4040F110C0F0F10000F13A5BA030A31 +:1052B00018C80F00151015101043104320030000EC +:1052C000CBB2300DCE0345120000000000000000FC +:1052D0000000000000000000000000000A000000C4 +:1052E00066666666560000000000000000000000D0 +:1052F00011111111111111111111000000000010F4 +:1053000003000000180DD60D060E1F0E530F580E89 +:10531000300F420F430F7E1707B80733008000009D +:105320002083000000803280648096802DB4040FBA +:10533000110C0F0F90000F13A5BA830A18C80F00A5 +:10534000151015101043104345097E1707B8C30701 +:105350000080008020F3000C00803280648096FE84 +:105360002DB4FFFF11FDFFFFD0FF0F13A5BA830A75 +:1053700018C80F00130F130F0F410F411F03000038 +:105380000900000000000000000000000000000014 +:10539000188DD68D068E1F8E538F588E308F428F6C +:1053A000438F0000000000C000000000000000006B +:1053B00002000000000000000000000000000000EB +:1053C00000E60000EC0454E7E4077EE75509A20775 +:1053D0000A09250945097E1707B8C30700800000A0 +:1053E0002083000000803280648096802DB4048F7A +:1053F00011FDFFFFD0FF0F93A5BA830A18E80FE055 +:10540000130F13FF0F410F411F030000D4B8040214 +:105410000351188748F00C0C85011C08188DD68D97 +:10542000068E1F8E538F588E308F428F438F555567 +:10543000555555D55555000000000018086A666698 +:1054400066666666366600270000000002E6008099 +:10545000EC0C54EFE4877EE75509A2070AE925E939 +:105460000000000000000100002802000000FC0015 +:10547000000000000D000D0059064006000000006D +:105480000155970102000000000000000001020227 +:10549000002800008002FC00FFFFFF010D000D004E +:1054A00007000F000000000004B0B300000000106F +:1054B0000000000000020202002800008002FC0040 +:1054C000FFFFFF010D000D0006000E0000000000B0 +:1054D00004C4B3000000001000000000000302023A +:1054E000002800008002FC00FFFFFF010D000D00FE +:1054F00005000D000000000004D8B30000000010FB +:105500000000000000040202002800008002FC00ED +:10551000FFFFFF010D000D0004000C000000000063 +:1055200004ECB300000000100000000000050202BF +:10553000002800008002FC00FFFFFF010D000D00AD +:1055400003000B00000000000400B4000000001085 +:105550000000000000060202002800008002FC009B +:10556000FFFFFF010D000D0002000A000000000017 +:105570000414B40000000010000000000007020244 +:10558000002800008002FC00FFFFFF010D000D005D +:1055900001000900000000000428B4000000001011 +:1055A0000000000000080202002804008002FC0045 +:1055B000FFFFFF010D000D000000080000000000CB +:1055C00020B0B30000000010000000000000000048 +:1055D000002806000000FC00000000000D000D0087 +:1055E000D20FA00F00000000015097010000000042 +:1055F0000000000000000000002802000000FC0085 +:10560000000000000D000D00C116A81600000000EB +:10561000018C97010600000000000000000B020250 +:10562000002800008000FC00000000000D000D00BC +:1056300007000F000000000004B0B30000000010DD +:1056400000000000000C0202002800008000FC00A6 +:10565000000000000D000D0006000E00000000001C +:1056600004C4B3000000001000000000000D02029E +:10567000002800008000FC00000000000D000D006C +:1056800005000D000000000004D8B3000000001069 +:1056900000000000000E0202002800008000FC0054 +:1056A000000000000D000D0004000C0000000000D0 +:1056B00004ECB3000000001000000000000F020224 +:1056C000002800008000FC00000000000D000D001C +:1056D00003000B00000000000400B40000000010F4 +:1056E0000000000000100202002800008000FC0002 +:1056F000000000000D000D0002000A000000000084 +:105700000414B400000000100000000000110202A8 +:10571000002800008000FC00000000000D000D00CB +:1057200001000900000000000428B400000000107F +:105730000000000000120202002804008000FC00AB +:10574000000000000D000D00000008000000000037 +:1057500020B0B300000000104F00000001F404006E +:1057600068931B00600000000C00000001000400B2 +:105770001428000060000000300000002D008400AC +:10578000142800001C000000730000002DF48400A9 +:1057900068931B001C000000700000002DF48400C2 +:1057A00068931B001C000000730000002DF48400AF +:1057B00068931B001C000000630000002DF48400AF +:1057C00068931B001C0000004F00000001F404005F +:1057D00068931B00E00001000C00000001000400C1 +:1057E00014280000E0000100300000002D008400BB +:1057F000142800001C000000700000002DF484003C +:1058000068931B001C000000000000000000000066 +:105810000000000000000000000000000000000088 +:105820000000000000000000000000000000000078 +:105830000000000000000000000000000000000068 +:105840000000000000000000000000000000000058 +:105850000000000000000000000000000000000048 +:105860000000000000000000000000000000000038 +:1058700000000000000000000000000092249224BC +:105880009200920000000000224924492401A40053 +:105890000000000014492449240114010000000004 +:1058A000A4482449240122010000000024452429A1 +:1058B000240124010000000024292445240124019E +:1058C000000000002449A448220124010000000037 +:1058D00024491449140124010000000024492249EC +:1058E000A400240100000000FF7FFF7FFF01FF01F3 +:1058F00000000000B66DB66DB601B60100000000F4 +:10590000B26DB66DB601B60000000000966DB66DC2 +:10591000B601960100000000B66CB66DB601B2018A +:1059200000000000B665B62DB601B601000000000B +:10593000B62DB665B601B60100000000B66DB66CB6 +:10594000B201B60100000000B66D966D9601B60179 +:1059500000000000B66DB26DB600B6010000000098 +:10596000012800000000000000000000000000000E +:10597000000000020206AA006C768A94000106006C +:1059800000000000DB0600000106000091016E40EF +:10599000418C39030100009A1D018C610000000058 +:1059A0000000000010100D100390BBBB8E5A22188F +:1059B000641164118A39893985E00FE06612641236 +:1059C00001200000000000000000000000000000B6 +:1059D000000000020206AA006C768A94000106000C +:1059E00000000000DB0600000106000091016E408F +:1059F000418C39030100009A1D018C6100000000F8 +:105A00000000000010000C100380ABAA8044227834 +:105A1000641164118A39893985E005E066126412DF +:105A20000104000000000000000000000000000071 +:105A3000000000020200AA006C768A9400010600B1 +:105A400000000000DB060000040C000038066E2099 +:105A5000418C390301000084C4058C610000000002 +:105A60000000000010C40C500390BBBB804422789F +:105A7000641164118A39893985E00FE06612641275 +:105A8000D004020001020304CCF57AFDED20BF8FA3 +:105A9000CF0304021E0600036C768A940001060000 +:105AA00000000000DB06000001460000121B002081 +:105AB000006B39034100028400006B616478792B2C +:105AC000CF8A00801C5411980080BBBB00572278FD +:105AD000641164118A39893985E00FE06612641215 +:105AE0000100000001010101CCF57AFDED20BF8F1E +:105AF000CF030402020600006C768A9400010600BF +:105B000000000000DB060000000C0000401A00202E +:105B10004100380341000284000000606478792B62 +:105B2000CF8A00801C5410180380BBBB80462278AB +:105B3000641164118A39893985E00FE066126412B4 +:105B4000D004020002020202CCF57AFDED20BF8FE4 +:105B5000CF030402020600006C768A94000106005E +:105B600000000000DB06000001460000121B0020C0 +:105B7000006B39034100028400006B616478792B6B +:105B8000CF8A00801C5411980380BBBB80462278CA +:105B9000641164118A39893985E00FE06612641254 +:105BA0000100000003030303CCF57AFDED20BF8F55 +:105BB000CF030402020600006C768A9400010600FE +:105BC00000000000DB060000000C0000401A00206E +:105BD0004100380341000284000000606478792BA2 +:105BE000CF8A00801C5410180380BBBB80462278EB +:105BF000641164118A39893985E00FE066126412F4 +:105C0000D004020004040404CCF57AFDED20BF8F1B +:105C1000CF030402020600006C768A94000106009D +:105C200000000000DB06000001460000121B0020FF +:105C3000006B39034100028400006B616478792BAA +:105C4000CF8A00801C5411980380BBBB8046227809 +:105C5000641164118A39893985E00FE06612641293 +:105C60000100000000000000CCF57AFDED20BF8FA0 +:105C7000CF030402020600006C768A94000106003D +:105C800000000000DB060000000C0000FF3B0020CD +:105C90004100380341000284000000606478792BE1 +:105CA000CF8A00801CC410180300000000C62278B0 +:105CB000641164118039803905000F0055105510AA +:105CC000000000000000000000101000000092CD55 +:105CD0000000C180100F0002000087370000BBF1F8 +:105CE000100F00040000904100008B43100E0007CD +:105CF0000000BBF100009167100C000900001DFBC3 +:105D00000000709E100E000500000000C806000094 +:105D1000BAF15942BAF15942450EA63D1122334417 +:105D20005566778899AABBCCDDEEFF6900000000BC +:105D30000000000000000000000000000000000063 +:105D40000000000000000000C022C0224A4948476D +:105D5000464544434241403F3E3D3C3B3A3938375B +:105D6000363534333231302F2E2D2C2B2A2928274B +:105D7000262524232221201F1E1D1C1B1A1900006A +:105D80000000000000000000000000000000000013 +:105D90000000000031302F2E2D2C2B2A29282726F9 +:105DA0002524232221201F1E1D1C1B1A191817161B +:105DB0001514131211100F0E0D0C0B0A090807060B +:105DC00005040302010000000000000000000000C4 +:105DD0000000000000000000000000002000E0C003 +:105DE000A08060402000E0C0A08060402000E0C0B3 +:105DF000A08060402000E0C0A08060402000E0C0A3 +:105E0000A08060402000E0C0A08060402000000032 +:105E100076DBB62D2449921BDBB6491292942409F5 +:105E200009000000826446280AECCEB0927456380D +:105E30001AFCDEC0A28466482A0CEED0B2947658D2 +:105E40003A1CFEE0C2A486684A2C0EF0D2B49678C2 +:105E50005A3C1E00FFFF00006D5B922424B76D1BAF +:105E60009B244912499224010000003F533517F941 +:105E7000DBBD9F8163452709EBCDAF917355371982 +:105E8000FBDDBFA1836547290BEDCFB19375573972 +:105E90001BFDDFC1A38567492B0D8E7052340000B6 +:105EA0006D499224E4B66D1B9224490A499204007C +:105EB0000000B42D2002836547290BEDCFB1937507 +:105EC00057391BFDDFC1A38567492B0DEFD1B39572 +:105ED00077593B1DFFE1C3A587694B2D0FF1D3B562 +:105EE00097795B3D1F01000040DB962424C96D1BA0 +:105EF000DB264912529224090100000016F8DABC90 +:105F00009E8062442608EACCAE9072543618FADCC1 +:105F1000BEA0826446280AECCEB0927456381AFCB1 +:105F2000DEC0A28466482A0C8D6F513315F700003D +:105F300025499224DBB66D129224290949120000EA +:105F400000D0B6255D3F21038466482A0CEED0B20E +:105F50009476583A1CFEE0C2A486684A2C0EF0D211 +:105F6000B496785A3C1E00E2C4A6886A4C2E10F201 +:105F7000D4B6987A5C3E000000D0B6252449721B46 +:105F8000DBB6491292A4240949000000D9BB9D7FC9 +:105F900061432507E9CBAD8F71533517F9DBBD9F01 +:105FA0008163452709EBCDAF9173553719FBDDBFF1 +:105FB000A1836547290B8C6E503214F6D8BA0000C5 +:105FC0002449921BDBB6491292A42409490000001F +:105FD00040DB96249A7C5E4022048567492B0DEFB6 +:105FE000D1B39577593B1DFFE1C3A587694B2D0FB1 +:105FF000F1D3B597795B3D1F01E3C5A7896B4D2FA1 +:1060000011F3D5B7997B00000000B42D2549921CEF +:10601000DBB66D1292242909491200009C7E604271 +:106020002406E8CAAC8E70523416F8DABC9E806240 +:10603000442608EACCAE9072543618FADCBEA08230 +:106040006446280A8B6D4F3113F5D7B99B7D00004C +:1060500024496E1BDB26491292922409010000009C +:106060006D5B9224D7B99B7D5F41230586684A2CDE +:106070000EF0D2B496785A3C1E00E2C4A6886A4C50 +:106080002E10F2D4B6987A5C3E2002E4C6A88A6C40 +:106090004E3012F4D6B800000000002D6D49922455 +:1060A000E4B66D1B9224490A499204005F4123051E +:1060B000E7C9AB8D6F513315F7D9BB9D7F61432580 +:1060C00007E9CBAD8F71533517F9DBBD9F81634570 +:1060D00027098A6C4E3012F4D6B89A7C5E400000D4 +:1060E00024B96D1B9B2449124A9224010000002D03 +:1060F0006D49922414F6D8BA9C7E604224068769C2 +:106100004B2D0FF1D3B597795B3D1F01E3C5A789EF +:106110006B4D2F11F3D5B7997B5D3F2103E5C7A9DF +:106120008B6D4F3113F50000010000006D5B922470 +:1061300024B96D1B9B2449124A9224012204E6C80B +:10614000AA8C6E503214F6D8BA9C7E60422406E8BF +:10615000CAAC8E70523416F8DABC9E8062442608AF +:10616000FFFFFFFFFFFFFFFFFFFFFFFF2103000017 +:10617000E4B66D1B9224490A499204000000FC3FDA +:10618000FFFFFF24513315F7D9BB9D7F61432507DE +:10619000886A4C2E10F2D4B6987A5C3E2002E4C68F +:1061A000A88A6C4E3012F4D6B89A7C5E402204E67F +:1061B000C8AA8C6E503200004900000040DB9624D3 +:1061C00024496E1BDB26491292922409E5C7A98B4C +:1061D0006D4F3113F5D7B99B7D5F412305E7C9ABFF +:1061E0008D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:1061F000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000AD +:10620000DBB66D1292242909C9FFFF3FFFFFFF3F54 +:10621000FFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFF4E +:10622000FFFF896B4D2F11F3D5B7997B5D3FFFFFC2 +:10623000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:10624000FFFFFFFFFFFF0000FFFFFF3FFFDFB6255F +:106250002449FE3FFFFFFF3FFFFFFF3F5F5E5D5CA6 +:106260005B5A595857565554535251504F4E4D4CF6 +:106270004B4A494847464544434241403F3E3D3CE6 +:106280003B3A39383736353433323130FFFF00008E +:1062900000000000000000000000000000000000FE +:1062A0000000003F2F2E2D2C2B2A292827262524BD +:1062B000232221201F1E1D1C1B1A19181716151426 +:1062C000131211100F0E0D0C0B0A09080706050416 +:1062D00003020100FFFF00000000000000000000BA +:1062E00000000000000000000000003F000000006F +:1062F000000000000000000000000000000000009E +:10630000000000000000000000000000000000008D +:10631000000000000000000000000000000000007D +:10632000000000000000000000000000000000006D +:10633000000000000000000000000000000000005D +:10634000000000000000000000000000000000004D +:10635000000000000000000000000000000000003D +:10636000000000000000000000000000000000002D +:10637000000000000000000000000000000000001D +:10638000000000000000000000000000000000000D +:1063900000000000000000000000000000000000FD +:1063A00000000000000000000000000000000000ED +:1063B00000000000000000000000000000000000DD +:1063C00000000000000000000000000000000000CD +:1063D00000000000000000000000000000000000BD +:1063E00000000000000000000000000000000000AD +:1063F000000000000000000000000000000000009D +:10640000000000000000000000000000000000008C +:10641000000000000000000000000000000000007C +:10642000000000000000000000000000000000006C +:10643000000000000000000000000000000000005C +:10644000000000000000000000000000000000004C +:10645000000000000000000000000000000000003C +:10646000000000000000000000000000000000002C +:10647000000000000000000000000000000000001C +:10648000000000000000000000000000000000000C +:1064900000000000000000000000000000000000FC +:1064A00000000000000000000000000000000000EC +:1064B00000000000000000000000000000000000DC +:1064C00000000000000000000000000000000000CC +:1064D00000000000000000000000000000000000BC +:1064E00000000000000000000000000000000000AC +:1064F000000000000000000000000000000000009C +:10650000000000000000000000000000000000008B +:10651000000000000000000000000000000000007B +:10652000000000000000000000000000000000006B +:10653000000000000000000000000000000000005B +:10654000000000000000000000000000000000004B +:10655000000000000000000000000000000000003B +:10656000000000000000000000000000000000002B +:10657000000000000000000000000000000000001B +:10658000000000000000000000000000000000000B +:1065900000000000000000000000000000000000FB +:1065A00000000000000000000000000000000000EB +:1065B00000000000000000000000000000000000DB +:1065C00000000000000000000000000000000000CB +:1065D00000000000000000000000000000000000BB +:1065E00000000000000000000000000000000000AB +:1065F000000000000000000000000000000000009B +:10660000000000000000000000000000000000008A +:10661000000000000000000000000000000000007A +:10662000000000000000000000000000000000006A +:10663000000000000000000000000000000000005A +:10664000000000000000000000000000000000004A +:10665000000000000000000000000000000000003A +:10666000000000000000000000000000000000002A +:10667000000000000000000000000000000000001A +:10668000000000000000000000000000000000000A +:1066900000000000000000000000000000000000FA +:1066A00000000000000000000000000000000000EA +:1066B00000000000000000000000000000000000DA +:1066C00000000000000000000000000000000000CA +:1066D00000000000000000000000000000000000BA +:1066E00000000000000000000000000000000000AA +:1066F000000000000000000000000000000000009A +:106700000000000000000000000000000000000089 +:106710000000000000000000000000000000000079 +:106720000000000000000000000000000000000069 +:106730000000000000000000000000000000000059 +:106740000000000000000000000000000000000049 +:106750000000000000000000000000000000000039 +:106760000000000000000000000000000000000029 +:106770000000000000000000000000000000000019 +:106780000000000000000000000000000000000009 +:1067900000000000000000000000000000000000F9 +:1067A00000000000000000000000000000000000E9 +:1067B00000000000000000000000000000000000D9 +:1067C00000000000000000000000000000000000C9 +:1067D00000000000000000000000000000000000B9 +:1067E00000000000000000000000000000000000A9 +:1067F0000000000000000000000000000000000099 +:106800000000000000000000000000000000000088 +:106810000000000000000000000000000000000078 +:106820000000000000000000000000000000000068 +:106830000000000000000000000000000000000058 +:106840000000000000000000000000000000000048 +:106850000000000000000000000000000000000038 +:106860000000000000000000000000000000000028 +:106870000000000000000000000000000000000018 +:106880000000000000000000000000000000000008 +:1068900000000000000000000000000000000000F8 +:1068A00000000000000000000000000000000000E8 +:1068B00000000000000000000000000000000000D8 +:1068C00000000000000000000000000000000000C8 +:1068D00000000000000000000000000000000000B8 +:1068E00000000000000000000000000000000000A8 +:1068F0000000000000000000000000000000000098 +:106900000000000000000000000000000000000087 +:106910000000000000000000000000000000000077 +:106920000000000000000000000000000000000067 +:106930000000000000000000000000000000000057 +:106940000000000000000000000000000000000047 +:106950000000000000000000000000000000000037 +:106960000000000000000000000000000000000027 +:106970000000000000000000000000000000000017 +:106980000000000000000000000000000000000007 +:1069900000000000000000000000000000000000F7 +:1069A00000000000000000000000000000000000E7 +:1069B00000000000000000000000000000000000D7 +:1069C00000000000000000000000000000000000C7 +:1069D00000000000000000000000000000000000B7 +:1069E00000000000000000000000000000000000A7 +:1069F0000000000000000000000000000000000097 +:106A0000150101000000000000000000320210002B +:106A10001000000000000000000000000000000066 +:106A200099120000BC120000DF12000002130000E7 +:106A300025130000481300006B1300008E130000A4 +:106A4000B1130000D4130000F71300001A14000063 +:106A50003D1400006014000083140000A614000020 +:106A6000C914000020030000D4B804020351180028 +:106A700007B28C2363200C0485011C080000000071 +:106A800000000000190000005B555555555555553F +:106A90005555555505000000080A000010000A0071 +:106AA000000000010000000002E00000EC14541699 +:106AB00084167E17411AA2176A199119B1197E1707 +:106AC00007B8C307008000002083000000803280E8 +:106AD000648096802DB4040F110C0F0F10000F135B +:106AE000A5BA830A18C80F001510151010431043DB +:106AF00020030000D4A8040C42330E0EC4338E23AE +:106B000063011911E32101132302000000000000BA +:106B10001B0000005B555555555555555555555558 +:106B20005505000098090B0BB0B00000B0B0001B79 +:106B30000B00000082F01002EC14541684167E172D +:106B4000411AA2176A199119B1197E1707B8C3071C +:106B500000800000208300000080328064809680E6 +:106B60002DB4040F110C0F0F10000F13A5BA830AD8 +:106B700018C80F0015101510104310432003000013 +:106B800009000000000000000000000000000000FC +:106B900000000000000000000000000001000000F4 +:106BA00003000000000000000000000000000000E2 +:106BB00002000000000000000000000000000000D3 +:106BC00000000000EC14541684167E17411AA21718 +:106BD0006A199119B1197E1707B8C3070080000020 +:106BE0002083000000803280648096802DB4040FE2 +:106BF000110C0F0F10000F13A5BA830A18C80F004D +:106C0000151015101043104320030000D4B80402DF +:106C10000351180007B28C2363200C0485011C0863 +:106C20000000000000000000190000005B555555F1 +:106C3000555555555555555555000000086A666619 +:106C400036666A66666666636600000002E00000FB +:106C5000EC14541684167E17411AA2176A1991195A +:106C6000B1197E1707B8C307008000002083000019 +:106C700000803280648096802DB4040F110C0F0FB9 +:106C800010000F13A5BA830A18C80F0015101510AD +:106C90001043104320030000D4A8040C42330E0E0E +:106CA000C4338E2363011911E32101132302000071 +:106CB000000000001B0000005B555555555555550B +:106CC000555555555505000098696B6BB6B6666607 +:106CD000B6B6663B6B06000082F01002EC14541648 +:106CE00084167E17411AA2176A199119B1197E17D5 +:106CF00007B8C307008000002083000000803280B6 +:106D0000648096802DB4040F110C0F0F10000F1328 +:106D1000A5BA830A18C80F001510151010431043A8 +:106D200020030000D4B8541617960100000000009C +:106D30000000000000000000000000000000000053 +:106D4000080000005B5555550000000000000000E1 +:106D500000000000081A11110000000000000000EF +:106D60000000000002000000EC14541684167E1788 +:106D7000411AA2176A199119B1197E1707B8C307EA +:106D800000800000208300000080328064809680B4 +:106D90002DB4040F110C0F0F10000F13A5BA830AA6 +:106DA00018C80F00151015101043104320030000E1 +:106DB000D4B854161796010000000000000000002F +:106DC00000000000000000000000000008000000BB +:106DD0005B55555500000000000000000000000059 +:106DE000083A3333000000000000000000000000FB +:106DF00002000000EC14541684167E17411AA217E4 +:106E00006A199119B1197E1707B8C30700800000ED +:106E10002083000000803280648096802DB4040FAF +:106E2000110C0F0F10000F13A5BA830A18C80F001A +:106E3000151015101043104320030000D4A8540C63 +:106E4000567339184F068D11A3344E000000000010 +:106E50000000000000000000130000005B555555C5 +:106E600055555555550500000000000008191B1B1D +:106E70001B1B0B0B0B0B00000000000002A002000C +:106E8000EC14541684167E17411AA2176A19911928 +:106E9000B1197E1707B8C3070080000020830000E7 +:106EA00000803280648096802DB4040F110C0F0F87 +:106EB00010000F13A5BA830A18C80F00151015107B +:106EC0001043104320030000D4A8540C5673391803 +:106ED0004F068D11A3344E0000000000000000009A +:106EE00000000000130000005B55555555555555E1 +:106EF000550500000000000008393B3B3B3B0B0BF5 +:106F00000B0B00000000000002A00200EC1454165D +:106F100084167E17411AA2176A199119B1197E17A2 +:106F200007B8C30700800000208300000080328083 +:106F3000648096802DB4040F110C0F0F10000F13F6 +:106F4000A5BA830A18C80F00151015101043104376 +:106F500020030000D4A8051B023774045E311A23F5 +:106F6000C7088C08000000000000000000000000BE +:106F7000140000005B5555555555555555550000A5 +:106F800000000000080909090909000010000000BC +:106F90000000000002500500EC14541684167E1701 +:106FA000411AA2176A199119B1197E1707B8C307B8 +:106FB0000080000020830000008032806480968082 +:106FC0002DB4040F110C0F0F10000F13A5BA830A74 +:106FD00018C80F00151015101043104320030000AF +:106FE000D4A8051B023774045E311A23C7088C0825 +:106FF000000000000000000000000000140000007D +:107000005B55555555555555555500000000000028 +:10701000086969696969606030600000000000000B +:1070200002500500EC14541684167E17411AA2175C +:107030006A199119B1197E1707B8C30700800000BB +:107040002083000000803280648096802DB4040F7D +:10705000110C0F0F10000F13A5BA830A18C80F00E8 +:10706000151015101043104320030000D4A8551B21 +:10707000167775185E060000000000000000000092 +:1070800000000000000000000C0000005B5555559A +:1070900055550000000000000000000008191919F3 +:1070A00019190000000000000000000002000000AC +:1070B000EC14541684167E17411AA2176A199119F6 +:1070C000B1197E1707B8C3070080000020830000B5 +:1070D00000803280648096802DB4040F110C0F0F55 +:1070E00010000F13A5BA830A18C80F001510151049 +:1070F0001043104320030000D4A8551B16777518C1 +:107100005E0600000000000000000000000000001B +:10711000000000000C0000005B555555555500005F +:10712000000000000000000008393939393900003A +:10713000000000000000000002000000EC145416E3 +:1071400084167E17411AA2176A199119B1197E1770 +:1071500007B8C30700800000208300000080328051 +:10716000648096802DB4040F110C0F0F10000F13C4 +:10717000A5BA830A18C80F00151015101043104344 +:1071800020030000E3180803446100070800000022 +:1071900000000000000000000000000000000000EF +:1071A0000B00000055555555550500000000000026 +:1071B00000000000000000000100000000000000CE +:1071C0000000000003000000EC14541684167E1723 +:1071D000411AA2176A199119B1197E1707B8C30786 +:1071E0000080000020830000008032806480968050 +:1071F0002DB4040F110C0F0F10000F13A5BA830A42 +:1072000018C80F001510151010431043200300007C +:10721000D4B80000000000000000000000000000E2 +:10722000000000000000000000000000030000005B +:107230005B050000000000000000000000000000EE +:10724000080A00000000000000000000000000002C +:1072500002000000EC14541684167E17411AA2177F +:107260006A199119B1197E1707B8C3070080000089 +:107270002083000000803280648096802DB4040F4B +:10728000110C0F0F10000F13A5BA830A18C80F00B6 +:1072900015101510104310432003000009050000CD +:1072A00000000000C002000000000000000000001C +:1072B0000000000000000000020000006466666636 +:1072C0006666000000000000000000008200000070 +:1072D00000A000000000000000000000FC0700000B +:1072E000EC14541684167E17411AA2176A199119C4 +:1072F000B1197E1707B8C307008000002083000083 +:1073000000803280648096802DB4040F110C0F0F22 +:1073100010000F13A5BA830A18C80F001510151016 +:107320001043104320030000813010050670200038 +:10733000000000000000000000000000000000004D +:1073400000000000090000005555555505000000DB +:10735000000000000000000000000001000000002C +:10736000000000000000000000000000EC145416B3 +:1073700084167E17411AA2176A199119B1197E173E +:1073800007B8C3070080000020830000008032801F +:10739000648096802DB4040F110C0F0F10000F1392 +:1073A000A5BA830A18C80F00151015101043104312 +:1073B0000000000000000001000003000000FC00CD +:1073C000000000000D000D0008072107000000006C +:1073D0000155B4000200000000000000010103029A +:1073E000000001000000FC00000000000D000D0086 +:1073F00010001F000000000004B0B30000000010E7 +:107400000000000002020302000001000000FC0076 +:10741000000000000D000D0011001E000000000023 +:1074200004C4B300000000100000000003030302C6 +:10743000000001000000FC00000000000D000D0035 +:1074400012001D000000000004D8B300000000106E +:107450000000000004040302000001000000FC0022 +:10746000000000000D000D0013001C0000000000D3 +:1074700004ECB3000000001000000000050503024A +:10748000000001000000FC00000000000D000D00E5 +:1074900014001B00000000000400B40000000010F5 +:1074A0000000000006060302000001000000FC00CE +:1074B000000000000D000D0015001A000000000083 +:1074C0000414B400000000100000000007070302CD +:1074D000000001000000FC00000000000D000D0095 +:1074E00016001900000000000428B400000000107D +:1074F0000000000008080302000005000000FC0076 +:10750000000000000D000D00170018000000000032 +:10751000043CB4000000001000000000090000015D +:10752000000007000000FC00000000000D000D003E +:1075300004101D10000000000150B4000000000005 +:107540000000000000000001000003000000FC003B +:10755000000000000D000D008917701700000000EA +:1075600001A0B40006000000000000000000171792 +:10757000000003000000FC00000000000D000D00F2 +:107580009C189D1800000000019BB400040000003E +:107590000000000000001616010003000000FD00BE +:1075A000000000000D000D00301138110000FE2514 +:1075B0000473B4000400000000000000000017176E +:1075C000020003000000FC00000000000D000D00A0 +:1075D000C012C1120000FE250487B40004000000A0 +:1075E0000000000000001616030003000000FD006C +:1075F000000000000D000D00301138110000FE25C4 +:107600000473B4000400000000000000000017171D +:10761000040003000000FC00000000000D000D004D +:10762000C012C1120000FE250487B400040000004F +:107630000000000000001616050003000000FD0019 +:10764000000000000D000D00301138110000FE2573 +:107650000473B400040000000000000000001717CD +:10766000060003000000FC00000000000D000D00FB +:10767000C012C1120000FE250487B40004000000FF +:107680000000000000001616070003000000FD00C7 +:10769000000000000D000D00301138110000FE2523 +:1076A0000473B4000400000000000000000017177D +:1076B000080003000000FC00000000000D000D00A9 +:1076C000C012C1120000FE250487B40004000000AF +:1076D00000000000000A1414002802000000FC0052 +:1076E0000000000005000500000000000000000090 +:1076F00001009703000000000000000000000100EE +:10770000002802000000FC00000000000D000D0039 +:10771000C800E10000000000015AB40002000000AF +:107720000000000000000100002802000000FC0032 +:10773000000000000D000D00580271020000000062 +:10774000015FB40002000000000000000000010022 +:10775000002802000000FC00000000000D000D00E9 +:10776000E8030104000000000164B400020000000E +:107770000000000000000100002802000000FC00E2 +:10778000000000000D000D007805910500000000CC +:107790000169B400020000000000000000000100C8 +:1077A000002802000000FC00000000000D000D0099 +:1077B0000807210700000000016EB400020000006D +:1077C0000000000000000100002802000000FC0092 +:1077D000000000000D000D003011491100000000F4 +:1077E00001A5B40006000000000000000000010038 +:1077F000002802000000FC00000000000D000D0049 +:10780000C012D9120000000001AAB4000600000056 +:107810000000000000000100002802000000FC0041 +:10782000000000000D000D0050146914000000005D +:1078300001AFB400060000000000000000000100DD +:10784000002802000000FC00000000000D000D00F8 +:10785000E015F9150000000001B4B40006000000B6 +:107860000000000000000100002802000000FC00F1 +:10787000000000000D000D007017891700000000C7 +:1078800001B9B40006000000000000000000010083 +:10789000002802000000FC000000000009000900B0 +:1078A0000000000000000000010097030600000037 +:1078B00000000000000B1414002802000000FC006F +:1078C000000000000C000C000000000000000000A0 +:1078D000010097030000000000000000000B1414DA +:1078E000002802000000FC003F0000000C000C001B +:1078F00000000000000000000100970300000000ED +:1079000000000000000B1515002802000000CC004C +:10791000000000000C000C0000000000000000004F +:1079200001009703000000000000000000000100BB +:10793000002802000000FC00000000000D000D0007 +:107940000000000000000000010097030600000096 +:107950004F00000001F4040068931B006000000069 +:107960000C0000000100040014280000600000006A +:10797000300000002D008400142800001C000000CE +:10798000730000002DF4840068931B001C000000AD +:10799000700000002DF4840068931B001C000000A0 +:1079A0007300000023F4840068931B001C00000097 +:1079B000600000002DF4840068931B001C00000090 +:1079C0004F00000001F4040068931B00E000010078 +:1079D0000C0000000100040014280000E000010079 +:1079E000300000002D008400142800001C0000005E +:1079F000700000002DF4840068931B001C00000040 +:107A0000730000002DF4840051651B001C00000071 +:107A10000101010101010101010101010101010156 +:107A20000101010101010101010101010101010146 +:107A30000101010101010101010101010101010136 +:107A40000101010101010101010101010101010126 +:107A50000101010101010101010101010101010116 +:107A60000101010101010101010101010101010106 +:107A70000101010133343A3335333534333433358E +:107A800033343233343334333334333334333333C2 +:107A900034343233343433333334323334333433B1 +:107AA00033343334353233333332323233333233A7 +:107AB00032333231333232323033323331323232A6 +:107AC0003231323232323232323231323332313298 +:107AD000313432342F2F2F3033343A333533353479 +:107AE0003334333533343233343334333334333360 +:107AF0003433333334333233343433333334323353 +:107B00003333333333353334353233333332323244 +:107B10003333323332333231333232323033323341 +:107B20003132323232313232323232323232313238 +:107B300033323132313432342F2F2F303334333328 +:107B400034333434333333353334333334333433FD +:107B500033343333343333333434333334343333EF +:107B600033343233343333333335333434323332E2 +:107B700033333232333332323233323133323232E0 +:107B800030333232313232313231323132323132DB +:107B90003232313232323132313332332F2F2E30D2 +:107BA000333433333433343433333335333433339E +:107BB000343334333334333334333333343433338F +:107BC0003434333333343233333333333335333480 +:107BD000343233323333323233333233323332317D +:107BE0003332323231333233313232323231323176 +:107BF0003232313232323132333231323133323366 +:107C00002F2F2E3033343233343334333333333550 +:107C10003334333334333433333433333333333330 +:107C20003433333234343333333432333333333322 +:107C30003335333434323332333232323333323217 +:107C40003233323133323232303332323132323116 +:107C50003231323132323132323231323332313208 +:107C6000313332332F2F2E2F3334323334333434F5 +:107C700033333335333433333433343333343333CE +:107C800034333333343333333434333333343233C0 +:107C900033333333333533343432333233323232B5 +:107CA00033333233323332313332323231333233AF +:107CB00031323231323132323232313232323132A9 +:107CC00033323132313332332F2F2E2F333532329C +:107CD000343333333334333433343333343334336E +:107CE000333433333433333334343332343433335F +:107CF0003334323333333333333533343432333252 +:107D00003332323233333232323232313332323250 +:107D1000303332333132313132313131323231324A +:107D20003232313232323132313332332F2F2E3040 +:107D3000333532323433333333343334333433330F +:107D400034333433333433333333333334343332FF +:107D500034343333333432333333333333353334EE +:107D600034323332333232323333323232333231ED +:107D700033323232303332333132323232313232E4 +:107D800032323132323231323232313231333233D5 +:107D90002F2F2E2F4F51534F4F4D514D4F4F4D5170 +:107DA0004D4F4F514F4F534F4B515151534D534DD9 +:107DB0004F4D4F515151514F4F4F4F4F514D514FCB +:107DC0004F515153534F5151514F514F4F4E4F4FB0 +:107DD0004B4F4F4F4F4D4F514B4F4F514F4D4F51B9 +:107DE0004D4F4F4D4F4B4D51514F4F4F4F4D4D4FAD +:107DF0004B4D4F514D494B4D92249224920092008D +:107E000000000000B66DB66DB600B60000000000C0 +:107E1000B66DB66D9601960100000000B66DB66DA8 +:107E2000B201B20100000000B62DB62DB601B601B8 +:107E300000000000B665B665B601B601000000009E +:107E4000B66CB66CB601B60100000000966D966D7A +:107E5000B601B60100000000B26DB26DB601B60108 +:107E600000000000FF7FFF7FFF01FF010000000016 +:107E7000B66DB66DB601B6010000000092249224E2 +:107E800092009200000000000110000000000000BD +:107E900000000000FFFF3DDB38D4FC020200AA0016 +:107EA0006C768A940001060000000000DB060000EA +:107EB000040C000060056E40415639030100009A31 +:107EC000EC045661000000000000000010C40C50DB +:107ED0000390BBBB804422786411641189398939CD +:107EE0000FE00FE0641264120110000000000000B7 +:107EF00000000000FFFF3DDB38D4FC020200AA00B6 +:107F00006C768A940001060000000000DB06000089 +:107F1000040C000060056E40415639030100009AD0 +:107F2000EC045661000000000000000010C40C10BA +:107F3000E39EBBBB8055227864116411893989396D +:107F40000FE00FE064126412010400000000000062 +:107F50000000000000000000000000020200AA0073 +:107F60006C768A940001060000000000DB06000029 +:107F7000040C000020066E40418639030100009A7F +:107F8000AC058661000000000000000010C40C5029 +:107F90000390BBBB8044227864116411893989390C +:107FA0000FE00FE064126412C9040200010203042E +:107FB000EAF7FAFD3001A880CF0304021E00000397 +:107FC0006C768A940001060000000000DB060000C9 +:107FD000014600002B1A0040006B39034100029A51 +:107FE00000006B616478792BCF8A00801C54119853 +:107FF0000080BBBB0057227864116411893989392C +:108000000FF00FF064126412C904020001010101B3 +:10801000EAF7FAFD3001A880CF0304020200000055 +:108020006C768A940001060000000000DB06000068 +:10803000014600002B1A0040006B39034100029AF0 +:1080400000006B61BB7DFC17FFFF00801C54119882 +:108050000380BBBB80462278641164118939893959 +:108060000FF00FF064126412C9040200020202024F +:10807000EAF7FAFD3001A880CF03040202000000F5 +:108080006C768A940001060000000000DB06000008 +:10809000014600002B1A0040006B39034100029A90 +:1080A00000006B610F7E3416FFFF00801C54119896 +:1080B0000380BBBB804622786411641189398939F9 +:1080C0000FF00FF064126412C904020003030303EB +:1080D000EAF7FAFD3001A880CF0304020200000095 +:1080E0006C768A940001060000000000DB060000A8 +:1080F000014600002B1A0040006B39034100029A30 +:1081000000006B61B17E3C12FFFF00801C5411988F +:108110000380BBBB80462278641164118939893998 +:108120000FF00FF064126412C90402000404040486 +:10813000EAF7FAFD3001A880CF0304020200000034 +:108140006C768A940001060000000000DB06000047 +:10815000014600002B1A0040006B39034100029ACF +:1081600000006B611C7F0B0FFFFF00801C541198F7 +:108170000380BBBB80462278641164118939893938 +:108180000FF00FF0641264120104000400000000FC +:10819000CCF57AFDED20BF8FCF030402020600006C +:1081A0006C768A940001060000000000DB060000E7 +:1081B00001060000093C0040006B39034100029AAF +:1081C00000006B616478792BCF8A00801CC4101882 +:1081D0000380ABAA00C6227864116411803980390B +:1081E0000F000F00550D550DC904020006070A0BBC +:1081F000EAF7FAFD3001A880CF0304021E0600034F +:108200006C768A940001060000000000DB06000086 +:10821000014600002B1A0040006B39034100029A0E +:1082200000006B616478792BCF8A00801C54119810 +:108230000080BBBB00572218641164118939893949 +:108240000FF00FF064126412C9040200060606065D +:10825000EAF7FAFD3001A880CF030402020600000D +:108260006C768A940001060000000000DB06000026 +:10827000014600002B1A0040006B39034100029AAE +:1082800000006B616478792BCF8A00801C541198B0 +:108290000080BBBB005722186411641189398939E9 +:1082A0000FF00FF064126412C904020006060A0AF5 +:1082B00073EDFAFD5985A880CF0304020A06010078 +:1082C0006C768A940043060100000000DB06000083 +:1082D000014600002B1A0040006B39034100029A4E +:1082E00000006B619367CBB40000008012541198BA +:1082F0000080BBBB0056221864116411893989398A +:108300000FF00FF064126412C904020007070B0B90 +:1083100073EDFAFD5985A880CF0304020A06010017 +:108320006C768A940043060100000000DB06000022 +:10833000014600002B1A0040006B39034100029AED +:1083400000006B6155737BC80000008012541198C7 +:108350000080BBBB00562218641164118939893929 +:108360000FF00FF064126412C904020009090C0C2A +:1083700073EDFAFD5985A880CF0304020A060100B7 +:108380006C768A940043060100000000DB060000C2 +:10839000014600002B1A0040006B39034100029A8D +:1083A00000006B61D9770ED3000000801254119841 +:1083B0000080BBBB005622186411641189398939C9 +:1083C0000FF00FF064126412C90402000A0A0606D4 +:1083D00073EDFAFD5985A880CF0304020A06010057 +:1083E0006C768A940043060100000000DB06000062 +:1083F000014600002B1A0040006B39034100029A2D +:1084000000006B61BD7977D800000080125411988C +:108410000080BBBB00562218641164118939893968 +:108420000FF00FF064126412C90402000B0B07076F +:1084300073EDFAFD5985A880CF0304020A060100F6 +:108440006C768A940043060100000000DB06000001 +:10845000014600002B1A0040006B39034100029ACC +:1084600000006B61757B34DE0000008012541198AF +:108470000080BBBB00562218641164118939893908 +:108480000FF00FF064126412C90402000A0A060613 +:1084900073EDFAFD5985A880CF0304020A06010096 +:1084A0006C768A940043060100000000DB060000A1 +:1084B000014600002B1A0040006B39034100029A6C +:1084C00000006B61CB7C87E30000008012541198A0 +:1084D0000080BBBB005622186411641189398939A8 +:1084E0000FF00FF064126412C90402000B0B0707AF +:1084F00073EDFAFD5985A880CF0304020A06010036 +:108500006C768A940043060100000000DB06000040 +:10851000014600002B1A0040006B39034100029A0B +:1085200000006B61F27D29E900000080125411986F +:108530000080BBBB00562218641164118939893947 +:108540000FF00FF064126412C90402000C0C090948 +:1085500073EDFAFD5985A880CF0304020A060100D5 +:108560006C768A940043060100000000DB060000E0 +:10857000014600002B1A0040006B39034100029AAB +:1085800000006B61D57EC2EE00000080125411988D +:108590000080BBBB005622186411641189398939E7 +:1085A0000FF00FF0641264120000000000000000E1 +:1085B00000101000000056CE00009910100E0006AA +:1085C0000000FDF900006FA1100E00050000464FED +:1085D000000029A6100F00040000AD8700007DD91F +:1085E000100F00030000C15A00009C9A00041030D4 +:1085F0000000BCA00000903800091033000083D0B8 +:108600000000D635000B10350000C9C200001A5911 +:10861000000C103600008CA100002C9F000D1037BC +:1086200000009851000044DC000E10380000BEEA43 +:108630000000A536000E103A000026620000DD9909 +:10864000000F103B00000000B5000000BF0000005C +:10865000DF000000EC00000019010000280100000C +:108660004301000053010000000000000000000072 +:1086700000000000000000000000000000000000FA +:1086800000000000000000000000000000000000EA +:1086900000000000000000000000000000000000DA +:1086A00000000000000000000000000000000000CA +:1086B00000000000000000000000000000000000BA +:1086C00000000000870700008579385793F930A132 +:1086D000B3D4CC2BCB0AF200000000000000000055 +:1086E000000000000000000000000000000000008A +:1086F000000000000000000000000000000000007A +:1087000080220022870700008579385793E4C2B998 +:1087100030AFCC2BC5A1B30000000000000000006A +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:1087400080220022870700008579385793E4C2BC55 +:10875000C2BCD7930D79300000000000000000007B +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800080220022870700008579385793E4C2BF12 +:10879000930ACC2BC4F50D0000000000000000007F +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00080220022870700008579385793E4C2BFD2 +:1087D000930AE4C2B286CF0000000000000000004F +:1087E0000000000000000000000000000000000089 +:1087F0000000000000000000000000000000000079 +:1088000080220022870700008579385793E4C2BF91 +:10881000930AB0AF26CF5000000000000000000017 +:108820000000000000000000000000000000000048 +:108830000000000000000000000000000000000038 +:1088400080220022870700008579385793E4C2BB55 +:108850000AF2E4C2BE4C2B00000000000000000041 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800080220022870700008579385793E4C2BB15 +:108890000AF2B0AF295E4C000000000000000000AA +:1088A00000000000000000000000000000000000C8 +:1088B00000000000000000000000000000000000B8 +:1088C00080220022C8060000450EA63D450EA63DAA +:1088D000BAF15942450EA63D450EA63D450EA63DB0 +:1088E000450EA63D00000000000000000000000052 +:1088F0000000000000000000000000000000000078 +:108900008022002231302F2E2D2C2B2A2928272699 +:108910002524232221201F1E1D1C1B1A191817167F +:108920001514131211100F0E0D0C0B0A090807066F +:108930000504030201000000000000000000000028 +:108940000000000000000000000000004A49484705 +:10895000464544434241403F3E3D3C3B3A3938372F +:10896000363534333231302F2E2D2C2B2A2928271F +:10897000262524232221201F1E1D1C1B1A1900003E +:1089800000000000000000000000000000000000E7 +:10899000000000002000E0C0A08060402000E0C097 +:1089A000A08060402000E0C0A08060402000E0C0C7 +:1089B000A08060402000E0C0A08060402000E0C0B7 +:1089C000A08060402000000076DBB62D2449921B79 +:1089D000DBB6491292942409090000002000E0C08F +:1089E000A08060402000E0C0A08060402000E0C087 +:1089F000A08060402000E0C0A08060402000E0C077 +:108A0000A08060402000E0C0A08060402000000006 +:108A100076DBB62D2449921BDBB6491292942409C9 +:108A2000090000002021E0E1A0A160612021E0E137 +:108A3000A0A160612021E0E1A0A160612021E0E12E +:108A4000A0A160612021E0E1A0A160612021E0E11E +:108A5000A0A160612021000076DBB62D2449921B85 +:108A6000DBB6491292942409090000000100C1C03C +:108A7000818041400100C1C0818041400100C1C0EE +:108A8000818041400100C1C0818041400100C1C0DE +:108A9000818041400100C1C081804140010000004F +:108AA00076DBB62D2449921BDBB649129294240939 +:108AB000090000002120E1E0A1A061602120E1E0A7 +:108AC000A1A061602120E1E0A1A061602120E1E09E +:108AD000A1A061602120E1E0A1A061602120E1E08E +:108AE000A1A061602120000076DBB62D2449921BF5 +:108AF000DBB6491292942409090000007353331322 +:108B0000F2D2B29272523212F2D2B2927252321245 +:108B1000F2D2B29272523212F2D2B2927252321235 +:108B2000F2D2B29272523212F2D2B2927252000069 +:108B300000D0B62D2D499224DBB66D129224250962 +:108B4000490200003C1CFCDCBC9C7C5C3C1CFCDC4A +:108B5000BC9C7C5C3C1CFCDCBC9C7C5C3C1CFCDC55 +:108B6000BC9C7C5C3C1CFCDCBC9C7C5C3C1CFBDB47 +:108B7000BB9B7B5B3B1B00002D499224DBB66D1237 +:108B8000922425094902000040DBB62DB4947454A8 +:108B90003414F3D3B39373533313F3D3B3937353A3 +:108BA0003313F3D3B39373533313F3D3B393735395 +:108BB0003313F3D3B39373533313F3D3B39300004B +:108BC0000000B42D6D4B9224E4B66D1B922449092C +:108BD00049920000FBDBBB9B7B5B3B1BFBDBBB9B36 +:108BE0007B5B3B1BFBDBBB9B7B5B3B1BFBDBBB9BD5 +:108BF0007B5B3B1BFBDBBB9B7B5B3B1BFADABA9AC9 +:108C00007A5A3A1AFADA00002449921BDBB6491262 +:108C100092942409090000006DDBB624F5D5B595C2 +:108C200075553515F4D4B49474543414F4D4B49400 +:108C300074543414F4D4B49474543414F4D4B494F4 +:108C400074543414F4D4B49474543414F4D400002C +:108C50000000002D6DDB922424B96D1B9B2449126A +:108C600049922400BA9A7A5A3A1AFADABA9A7A5A8D +:108C70003A1AFADABA9A7A5A3A1AFADABA9A7A5A54 +:108C80003A1AFADABA9A7A5A3A1AF9D9B99979594A +:108C90003919F9D9B999000024496E1BDB2649120C +:108CA000529224090000002D6DDB92243616F6D670 +:108CB000B69676563616F5D5B59575553515F5D55E +:108CC000B59575553515F5D5B59575553515F5D554 +:108CD000B59575553515F5D5B5957555351500000E +:108CE000090000006DDBB62424496E1BDB26491207 +:108CF0005292240979593919F9D9B99979593919F7 +:108D0000F9D9B99979593919F9D9B99979593919D3 +:108D1000F9D9B99979593919F8D8B89878583818CB +:108D2000F8D8B8987858000024B96D1B9B244912D4 +:108D3000499224000000B42D6D4B922477573717C9 +:108D4000F7D7B79777573717F6D6B69676563616BB +:108D5000F6D6B69676563616F6D6B69676563616B3 +:108D6000F6D6B69676563616F6D6B69676560000EF +:108D70004902000040DBB62D2449921BDBB64912A4 +:108D8000929424093818F8D8B89878583818F8D830 +:108D9000B89878583818F8D8B89878583818F8D853 +:108DA000B89878583818FFFFFFFFFFFFFFFFFFFF5D +:108DB000FFFFFFFFFFFF0000E4B66D1B922449098F +:108DC0004992000000F0FF3FFFFFFF3FFFFFFFFF62 +:108DD000FFFFFFFFFFFFFFFFFFFFF7D7B7977757B3 +:108DE0003717F7D7B79777573717F7D7B797775713 +:108DF0003717F7D7B79777573717F7D7B7970000D1 +:108E0000FFFFFF3FFFDFB62D2D499224DBB66D1229 +:108E100092242509636261605F5E5D5C5B5A59580C +:108E200057565554535251504F4E4D4C4B4A49484A +:108E300047464544434241403F3E3D3C3B3A39383A +:108E400037363534333200000000000000000000E7 +:108E500000000000000000000000000031302F2E54 +:108E60002D2C2B2A292827262524232221201F1EAA +:108E70001D1C1B1A191817161514131211100F0E9A +:108E80000D0C0B0A09080706050403020100000087 +:108E900000000000000000000000000000000000D2 +:108EA00000000000FFFFFFFFFFFFFFFFFFFFFFFFCE +:108EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:108EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:108ED000FFFFFFFFFFFF0000FFFFFF3FFFFFFF3F20 +:108EE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFFFFD2 +:108EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:108F0000FFFFFFFFFFFFFFFFFFFF0000000000006B +:108F10000000000000000000000000000000000051 +:108F2000FFFFFF3FFFFFFF3FFFFFFF3F000000008D +:108F30000000000057473727170756463626160603 +:108F4000554535251505544434241404534333231F +:108F50001303524232221202514131211101504079 +:108F600030201000FFFF00000000000000000000A3 +:108F700000000000000000000000003F62605E5C36 +:108F80005A58565452504E4C4A48464442403E3C31 +:108F90003A38363432302E2C2A28262422201E1C21 +:108FA0001A18161412100E0C0A080604020000000B +:108FB00000000000000000000000000000000000B1 +:108FC00000000000000000000000000000000000A1 +:108FD0000000000000000000000000000000000091 +:108FE0000000000000000000000000000000000081 +:108FF0000000000000000000000000000000000071 +:109000000000000000000000000000000000000060 +:109010000000000000000000000000000000000050 +:109020000000000000000000000000000000000040 +:109030000000000000000000000000000000000030 +:109040000000000000000000000000000000000020 +:109050000000000000000000000000000000000010 +:109060000000000000000000000000000000000000 +:1090700000000000000000000000000000000000F0 +:1090800000000000000000000000000000000000E0 +:1090900000000000000000000000000000000000D0 +:1090A00000000000000000000000000000000000C0 +:1090B00000000000000000000000000000000000B0 +:1090C00000000000000000000000000000000000A0 +:1090D0000000000000000000000000000000000090 +:1090E0000000000000000000000000000000000080 +:1090F0000000000000000000000000000000000070 +:10910000000000000000000000000000000000005F +:10911000000000000000000000000000000000004F +:10912000000000000000000000000000000000003F +:10913000000000000000000000000000000000002F +:10914000000000000000000000000000000000001F +:10915000000000000000000000000000000000000F +:1091600000000000000000000000000000000000FF +:1091700000000000000000000000000000000000EF +:1091800000000000000000000000000000000000DF +:1091900000000000000000000000000000000000CF +:1091A00000000000000000000000000000000000BF +:1091B00000000000000000000000000000000000AF +:1091C000000000000000000000000000000000009F +:1091D000000000000000000000000000000000008F +:1091E000000000000000000000000000000000007F +:1091F000000000000000000000000000000000006F +:109200000801010000000000000000003202100010 +:109210001B00000000000000000000000000000033 +:109220008C1C0000AF1C0000D21C0000F51C0000CC +:10923000200300004110080344611C0800000000E6 +:10924000000000000000000000000000000000001E +:109250000A00000066666666560000000000000016 +:1092600000000000000000000000000000000000FE +:109270000000000003000000181DD61D061E1F1E62 +:10928000531F581E301F421F431F7E1707B8C307C6 +:10929000008000002083000000803280648096807F +:1092A0002DB4040F110C0F0F10000F13A5BA030AF1 +:1092B00018C80F00151015101043104320030000AC +:1092C000CBB2300DCE0345120000000000000000BC +:1092D0000000000000000000000000000A00000084 +:1092E0006666666656000000000000000000000090 +:1092F00011111111111111111111000000000010B4 +:1093000003000000181DD61D061E1F1E531F581EE9 +:10931000301F421F431F7E1707B80733008000002D +:109320002083000000803280648096802DB4040F7A +:10933000110C0F0F90000F13A5BA830A18C80F0065 +:10934000151015101043104345097E1707B8C307C1 +:109350000080008020F3000C00803280648096FE44 +:109360002DB4FFFF11FDFFFFD0FF0F13A5BA830A35 +:1093700018C80F00130F130F0F410F411F030000F8 +:1093800009000000000000000000000000000000D4 +:10939000189DD69D069E1F9E539F589E309F429FAC +:1093A000439F0000000000C000000000000000001B +:1093B00002000000000000000000000000000000AB +:1093C00000E60000EC0454E7E4077EE75509A20735 +:1093D0000A09250945097E1707B8C3070080000060 +:1093E0002083000000803280648096802DB4048F3A +:1093F00011FDFFFFD0FF0F93A5BA830A18E80FE015 +:10940000130F13FF0F410F411F030000D4B80402D4 +:109410000351188748F00C0C85011C08189DD69D37 +:10942000069E1F9E539F589E309F429F439F5555B7 +:10943000555555D55555000000000018086A666658 +:1094400066666666366600270000000002E6008059 +:10945000EC0C54EFE4877EE75509A2070AE925E9F9 +:109460000000000000000100002802000000FC00D5 +:10947000000000000D000D0059064006000000002D +:1094800001559701020000000000000000010202E7 +:10949000002800008002FC00FFFFFF010D000D000E +:1094A00017001F000000000004B0B300000000100F +:1094B0000000000000020202002800008002FC0000 +:1094C000FFFFFF010D000D0016001E000000000050 +:1094D00004C4B300000000100000000000030202FA +:1094E000002800008002FC00FFFFFF010D000D00BE +:1094F00015001D000000000004D8B300000000109B +:109500000000000000040202002800008002FC00AD +:10951000FFFFFF010D000D0014001C000000000003 +:1095200004ECB3000000001000000000000502027F +:10953000002800008002FC00FFFFFF010D000D006D +:1095400013001B00000000000400B4000000001025 +:109550000000000000060202002800008002FC005B +:10956000FFFFFF010D000D0012001A0000000000B7 +:109570000414B40000000010000000000007020204 +:10958000002800008002FC00FFFFFF010D000D001D +:1095900011001900000000000428B40000000010B1 +:1095A0000000000000080202002804008002FC0005 +:1095B000FFFFFF010D000D0010001800000000006B +:1095C00020B0B30000000010000000000000000008 +:1095D000002806000000FC00000000000D000D0047 +:1095E000D20FA00F00000000015097010000000002 +:1095F0000000000000000000002802000000FC0045 +:10960000000000000D000D00C116A81600000000AB +:10961000018C97010600000000000000000B020210 +:10962000002800008000FC00000000000D000D007C +:1096300017001F000000000004B0B300000000107D +:1096400000000000000C0202002800008000FC0066 +:10965000000000000D000D0016001E0000000000BC +:1096600004C4B3000000001000000000000D02025E +:10967000002800008000FC00000000000D000D002C +:1096800015001D000000000004D8B3000000001009 +:1096900000000000000E0202002800008000FC0014 +:1096A000000000000D000D0014001C000000000070 +:1096B00004ECB3000000001000000000000F0202E4 +:1096C000002800008000FC00000000000D000D00DC +:1096D00013001B00000000000400B4000000001094 +:1096E0000000000000100202002800008000FC00C2 +:1096F000000000000D000D0012001A000000000024 +:109700000414B40000000010000000000011020268 +:10971000002800008000FC00000000000D000D008B +:1097200011001900000000000428B400000000101F +:109730000000000000120202002804008000FC006B +:10974000000000000D000D001000180000000000D7 +:1097500020B0B300000000104F00000001F404002E +:1097600068931B00600000000C0000000100040072 +:109770001428000060000000300000002D0084006C +:10978000142800001C000000730000002DF4840069 +:1097900068931B001C000000700000002DF4840082 +:1097A00068931B001C000000730000002DF484006F +:1097B00068931B001C000000630000002DF484006F +:1097C00068931B001C0000004F00000001F404001F +:1097D00068931B00E00001000C0000000100040081 +:1097E00014280000E0000100300000002D0084007B +:1097F000142800001C000000700000002DF48400FC +:1098000068931B001C000000000000000000000026 +:109810000000000000000000000000000000000048 +:109820000000000000000000000000000000000038 +:109830000000000000000000000000000000000028 +:109840000000000000000000000000000000000018 +:109850000000000000000000000000000000000008 +:1098600000000000000000000000000000000000F8 +:10987000000000000000000000000000922492247C +:109880009200920000000000224924492401A40013 +:1098900000000000144924492401140100000000C4 +:1098A000A448244924012201000000002445242961 +:1098B000240124010000000024292445240124015E +:1098C000000000002449A4482201240100000000F7 +:1098D00024491449140124010000000024492249AC +:1098E000A400240100000000FF7FFF7FFF01FF01B3 +:1098F00000000000B66DB66DB601B60100000000B4 +:10990000B26DB66DB601B60000000000966DB66D82 +:10991000B601960100000000B66CB66DB601B2014A +:1099200000000000B665B62DB601B60100000000CB +:10993000B62DB665B601B60100000000B66DB66C76 +:10994000B201B60100000000B66D966D9601B60139 +:1099500000000000B66DB26DB600B6010000000058 +:1099600001280000000000000000000000000000CE +:10997000000000020206AA006C768A94000106002C +:1099800000000000DB0600000106000091016E40AF +:10999000418C39030100009A1D018C610000000018 +:1099A0000000000010100D100390BBBB8E5A22184F +:1099B00064116411893989390AE00FE06412641274 +:1099C0000120000000000000000000000000000076 +:1099D000000000020206AA006C768A9400010600CC +:1099E00000000000DB0600000106000091016E404F +:1099F000418C39030100009A1D018C6100000000B8 +:109A00000000000010000C100380ABAA80442278F4 +:109A1000641164118939893905E005E06412641222 +:109A20000104000000000000000000000000000031 +:109A3000000000020200AA006C768A940001060071 +:109A400000000000DB060000040C000038066E2059 +:109A5000418C390301000084C4058C6100000000C2 +:109A60000000000010C40C500390BBBB804422785F +:109A7000641164118A39893905E00FE064126412B7 +:109A8000D004020001020304CCF57AFDED20BF8F63 +:109A9000CF0304021E0600036C768A9400010600C0 +:109AA00000000000DB06000001460000121B002041 +:109AB000006B39034100028400006B616478792BEC +:109AC000CF8A00801C5411980080BBBB00572278BD +:109AD000641164118A39893905E00FE06412641257 +:109AE0000100000001010101CCF57AFDED20BF8FDE +:109AF000CF030402020600006C768A94000106007F +:109B000000000000DB060000000C0000401A0020EE +:109B10004100380341000284000000606478792B22 +:109B2000CF8A00801C5410180380BBBB804622786B +:109B3000641164118A39893905E00FE064126412F6 +:109B4000D004020002020202CCF57AFDED20BF8FA4 +:109B5000CF030402020600006C768A94000106001E +:109B600000000000DB06000001460000121B002080 +:109B7000006B39034100028400006B616478792B2B +:109B8000CF8A00801C5411980380BBBB804622788A +:109B9000641164118A39893905E00FE06412641296 +:109BA0000100000003030303CCF57AFDED20BF8F15 +:109BB000CF030402020600006C768A9400010600BE +:109BC00000000000DB060000000C0000401A00202E +:109BD0004100380341000284000000606478792B62 +:109BE000CF8A00801C5410180380BBBB80462278AB +:109BF000641164118A39893905E00FE06412641236 +:109C0000D004020004040404CCF57AFDED20BF8FDB +:109C1000CF030402020600006C768A94000106005D +:109C200000000000DB06000001460000121B0020BF +:109C3000006B39034100028400006B616478792B6A +:109C4000CF8A00801C5411980380BBBB80462278C9 +:109C5000641164118A39893905E00FE064126412D5 +:109C60000100000000000000CCF57AFDED20BF8F60 +:109C7000CF030402020600006C768A9400010600FD +:109C800000000000DB060000000C0000FF3B00208D +:109C90004100380341000284000000606478792BA1 +:109CA000CF8A00801CC410180300000000C6227870 +:109CB000641164118039803905000F00551055106A +:109CC000000000000000000000101000000092CD15 +:109CD0000000C180100F0002000087370000BBF1B8 +:109CE000100F00040000904100008B43100E00078D +:109CF0000000BBF100009167100C000900001DFB83 +:109D00000000709E100E000500000000C806000054 +:109D1000BAF15942BAF15942450EA63D11223344D7 +:109D20005566778899AABBCCDDEEFF69000000007C +:109D30000000000000000000000000000000000023 +:109D40000000000000000000C022C0224A4948472D +:109D5000464544434241403F3E3D3C3B3A3938371B +:109D6000363534333231302F2E2D2C2B2A2928270B +:109D7000262524232221201F1E1D1C1B1A1900002A +:109D800000000000000000000000000000000000D3 +:109D90000000000031302F2E2D2C2B2A29282726B9 +:109DA0002524232221201F1E1D1C1B1A19181716DB +:109DB0001514131211100F0E0D0C0B0A09080706CB +:109DC0000504030201000000000000000000000084 +:109DD0000000000000000000000000002000E0C0C3 +:109DE000A08060402000E0C0A08060402000E0C073 +:109DF000A08060402000E0C0A08060402000E0C063 +:109E0000A08060402000E0C0A080604020000000F2 +:109E100076DBB62D2449921BDBB6491292942409B5 +:109E2000090000009173553719FBDDBFA183654719 +:109E3000290BEDCFB1937557391BFDDFC1A38567A2 +:109E4000492B0DEFD1B39577593B1DFFE1C3A58792 +:109E5000694B2D0FFFFF00006D5B922424B96D1B31 +:109E60009B2449124A9224010000003F62442608C4 +:109E7000EACCAE9072543618FADCBEA08264462852 +:109E80000AECCEB0927456381AFCDEC0A284664842 +:109E90002A0CEED0B29476583A1C9D7F61430000A4 +:109EA0006D4B9224E4B66D1B9324490A4992240019 +:109EB0000000B42D2F11927456381AFCDEC0A28413 +:109EC00066482A0CEED0B29476583A1CFEE0C2A442 +:109ED00086684A2C0EF0D2B496785A3C1E00E2C432 +:109EE000A6886A4C2E10000040DB962424496E1B85 +:109EF000DB26491292922409090000002507E9CBCC +:109F0000AD8F71533517F9DBBD9F8163452709EB91 +:109F1000CDAF9173553719FBDDBFA1836547290B81 +:109F2000EDCFB1937557391B9C7E6042240600002B +:109F30002D499224DBB66D13922429094992000021 +:109F400000D0B62D6C4E3012937557391BFDDFC112 +:109F5000A38567492B0DEFD1B39577593B1DFFE1E1 +:109F6000C3A587694B2D0FF1D3B597795B3D1F01D1 +:109F7000E3C5A7896B4D000000D0B6252449921B8C +:109F8000DBB6491292A4240949020000E8CAAC8E4B +:109F900070523416F8DABC9E8062442608EACCAED1 +:109FA0009072543618FADCBEA0826446280AECCEC1 +:109FB000B0927456381A9B7D5F412305E7C90000B3 +:109FC0002449921BDBB64D1292A4240949020000D9 +:109FD00040DBB624A98B6D4F31139476583A1CFEA2 +:109FE000E0C2A486684A2C0EF0D2B496785A3C1E81 +:109FF00000E2C4A6886A4C2E10F2D4B6987A5C3E71 +:10A000002002E4C6A88A00000000B42D254992244D +:10A01000DBB66D139224290949920000AB8D6F5174 +:10A020003315F7D9BB9D7F61432507E9CBAD8F7110 +:10A03000533517F9DBBD9F8163452709EBCDAF9100 +:10A04000735537199A7C5E402204E6C8AA8C00003A +:10A0500024496E1BDB364912929224090900000044 +:10A060006DDB9224E6C8AA8C6E5032149577593B6A +:10A070001DFFE1C3A587694B2D0FF1D3B597795B20 +:10A080003D1F01E3C5A7896B4D2F11F3D5B7997B10 +:10A090005D3F2103E5C700000000002D6D499224BB +:10A0A000E4B66D1B9324490A499224006E50321481 +:10A0B000F6D8BA9C7E60422406E8CAAC8E70523450 +:10A0C00016F8DABC9E8062442608EACCAE90725440 +:10A0D0003618997B5D3F2103E5C7A98B6D4F0000C2 +:10A0E00024B96D1BDB2449124A9224090000002D7B +:10A0F0006D4B92242305E7C9AB8D6F5133159678CC +:10A100005A3C1E00E2C4A6886A4C2E10F2D4B698BF +:10A110007A5C3E2002E4C6A88A6C4E3012F4D6B8AF +:10A120009A7C5E4022040000090000006DDB92244E +:10A1300024B96D1BDB2449124A9224093113F5D747 +:10A14000B99B7D5F412305E7C9AB8D6F513315F78F +:10A15000D9BB9D7F61432507E9CBAD8F715335177F +:10A16000FFFFFFFFFFFFFFFFFFFFFFFF30120000B9 +:10A17000E4B66D1B9324490A499224000000FC3F79 +:10A18000FFFFFF2460422406E8CAAC8E70523416EA +:10A1900097795B3D1F01E3C5A7896B4D2F11F3D55F +:10A1A000B7997B5D3F2103E5C7A98B6D4F3113F54F +:10A1B000D7B99B7D5F4100004902000040DBB62417 +:10A1C00024496E1BDB36491292922409F4D6B89AC0 +:10A1D0007C5E402204E6C8AA8C6E503214F6D8BACF +:10A1E0009C7EFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:10A1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00006D +:10A20000DBB66D1392242909C9FFFF3FFFFFFF3F13 +:10A21000FFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFF0E +:10A22000FFFF987A5C3E2002E4C6A88A6C4EFFFFCE +:10A23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:10A24000FFFFFFFFFFFF0000FFFFFF3FFFDFB62D17 +:10A250002449FE3FFFFFFF3FFFFFFF3F2000E0C01C +:10A26000A08060402000E0C0A08060402000E0C0EE +:10A27000A08060402000E0C0A08060402000E0C0DE +:10A28000A08060402000E0C0A0806040200000006E +:10A2900076DBB62D2449921BDBB649129294240931 +:10A2A000090000002000E0C0A08060402000E0C065 +:10A2B000A08060402000E0C0A08060402000E0C09E +:10A2C000A08060402000E0C0A08060402000E0C08E +:10A2D000A08060402000000076DBB62D2449921B50 +:10A2E000DBB6491292942409090000000000000026 +:10A2F000000000000000000000000000000000005E +:10A30000000000000000000000000000000000004D +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000C822050CE8220F0C56 +:10AAE0000000001002000000000000000000000054 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB2000C00BBC0DEE0B0000400BBC0FEC0B040087 +:10AB3000C02ABC0FEA0B0C00404ABC0FE80B140003 +:10AB4000C069BC0FE60B1C004089BC0FE40B24005D +:10AB5000C0A8BC0FE2082C004C48BE00000000005A +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00029292A2A2A2A29292A2A2A2A29292A2A0B +:10ABB0002A2A29292A2A2A2A2A2A2A2A29292A2AF9 +:10ABC0002A2A29292A2A2A2A29292A2A2A2A2929EB +:10ABD0000000000029292A2A2A2A29292A2A2A2A81 +:10ABE0000000000000000000000000000000000065 +:10ABF00000000000000000002A2A2A2A29292A2A07 +:10AC00002A2A29290000000000000000000000009E +:10AC10000000000029292A2A2A2A29292A2A2A2A40 +:10AC20002A2A2A2A29292A2A2A2A29290000000030 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE100006F0F15506F0F15506F0F15506F0F15542 +:10AE20001B1A1A191919191816171818181818189A +:10AE30001B1B1A1919191818171818181919191A83 +:10AE40001B1A19191918181716171718181818197E +:10AE50001D1A1A1919181817171717181819191A67 +:10AE60001B1A1A191A1A1919171818181819191A51 +:10AE70001B1B1A1A19181918171717171818191948 +:10AE80001A1A1A1919191817171818181819191B36 +:10AE90001C1A191818181817161717181819191A2C +:10AEA0001B1A1A1A191A1919171819181818191A11 +:10AEB0001B1A19181919181816171717181919190C +:10AEC0001B1A1B1918191918171718181818181AF7 +:10AED0001B1A1918181818181717161718181919EF +:10AEE00019191A1918181817171718181818181ADE +:10AEF0001B191918181718171617161617171819D7 +:10AF00001B191A1918191818181819191919191BB1 +:10AF10001C1A1918181818181617171717181819AF +:10AF200019181918181818171717171818181819A2 +:10AF30001A19181817171717171716171817181997 +:10AF40001A18191918181817171717181818191A7E +:10AF50001B1A191817171717171716171818181973 +:10AF60001918191818181817171717181818181962 +:10AF70001A1A191817171717171717171818181953 +:10AF80001918191818171716161617171818181948 +:10AF90001A1A18181717161716161717171718183A +:10AFA0001918191818171817161717171818181925 +:10AFB0001A1918181717161716161617171718181C +:10AFC0001919181817171716161717171718181909 +:10AFD0001A1A1918171717171616161717171719F9 +:10AFE00019181818171717161617171718181819E9 +:10AFF00019191817171716161616161717161718E1 +:10B0000019181918171717161616161717181819CA +:10B010001A191918171716171716161717171718BA +:10B0200018181817171716161617171717181719AD +:10B03000191918171716161617161617181617189F +:10B040001919181817171616161617171718191989 +:10B05000191919171716161616161616171717197F +:10B060001818181717161616151616161717181873 +:10B070001817181716161616161616161716161867 +:10B08000181818171616161515171717171819194F +:10B09000191918181716161616161617171717193E +:10B0A000191818171616161615171818181819192A +:10B0B0001918181716161616161616161716171824 +:10B0C0001917171716161615151516171717181915 +:10B0D0001A18181716161615151515161617161808 +:10B0E00018181717161616151516171717171818F4 +:10B0F00019181817161615151516151617171618E8 +:10B1000018181717161615151515161717171818D6 +:10B1100019181717161615151515151616171718C9 +:10B1200018171716161615151515161717171718B9 +:10B1300019181717161616151515151616171617AA +:10B140001918171716161615151516171717181993 +:10B150001818171716161515151615161717171888 +:10B160001817171716161515151516171717171878 +:10B170001817171615151515151515151617161771 +:10B18000181717161615151515151516171718195A +:10B19000191717171616151515161515161717184A +:10B1A000171716161515151515151616171717183E +:10B1B0001817161716151515151515151516161633 +:10B1C0001817171716151515151615161717181819 +:10B1D000191817171615151515151515161617170D +:10B1E00018181717161515151515161616171718FA +:10B1F00018171616161515141515151515161717F3 +:10B2000017171616151514141415151616161718E3 +:10B2100018161616161515151515151516161717D1 +:10B2200017171616151514151515151616161717C2 +:10B2300017161515141415141515141515151617BC +:10B2400017171616151414141414151516161718A6 +:10B2500017161515141414141414141415151617A0 +:10B260001717161615151414141414151516161789 +:10B27000171616151515151414141414151516177C +:10B280001716161615141414141415151616171867 +:10B290001817151515151414141414151616171758 +:10B2A0001817161515141414141415151516171748 +:10B2B000161615141514131414141515151616173F +:10B2C0001816151515141413141415161516171829 +:10B2D0001716151415151414141415161516171819 +:10B2E000171616151514141314141515151616180B +:10B2F0001716151414141413141414151515161701 +:10B3000017161615151514141414151515161718E7 +:10B3100018161515151514141414151515161717D8 +:10B3200017161615151414141414141515151618CB +:10B3300017161515141414141414151516161717BA +:10B3400015151515141413131414141515161618B1 +:10B3500017161514141414131414141515151617A0 +:10B360001615151514141414131414151515161791 +:10B37000161515141514141414141415151617177E +:10B38000161615151414131314141414151617186F +:10B390001615141514141413141414151416161861 +:10B3A0001515151514141413141414141515161753 +:10B3B000161616151514141314141414151516173F +:10B3C0001615151414131313131414141415161737 +:10B3D0001515151514141413141414151515161722 +:10B3E000161515141313131313131314141515161C +:10B3F000151414141414141313141414141515160A +:10B4000016151514131313131313141415151618F6 +:10B4100016151515141414131314141414151617E3 +:10B4200015151414131313131414141414151617D8 +:10B4300016141414141413131314141414141517C9 +:10B4400015151414131313131313131415151618B9 +:10B4500016151415141313131314141414141517A8 +:10B460001A19191817171716151616161718181867 +:10B470001A1A18181818171817161718181718194D +:10B480001A19181817171716161617171818191942 +:10B490001B19191818171717161616171717181833 +:10B4A0001A1A19191A191818171817171819191913 +:10B4B0001B19191818171817161616181717181811 +:10B4C0001A191818191918181818171718181919F7 +:10B4D0001A181817171717161516171818181818F6 +:10B4E0001A1A1918191A19191718181818181919D1 +:10B4F0001A191918181818171517181818181818CD +:10B500001A191918181919181717171718191819B7 +:10B510001A191818181817171616171718181818B0 +:10B52000191918181819181817171717171818189D +:10B530001918181817171717161716171717171897 +:10B540001A19191819181918181817171819191974 +:10B550001A19191818171717171616171717171873 +:10B56000191818181818191817171716171818185F +:10B57000191818171716171716161616171817185A +:10B58000191818191818181718171817181819193A +:10B590001A18181717171617171616161718171838 +:10B5A000191819181818191717171717171818181E +:10B5B0001918181717171717161716171717181817 +:10B5C00019181819181818171717171717181818FF +:10B5D00019181817171616161616161617171718FD +:10B5E00019181819181818171717181617181818DF +:10B5F00019181717171716161616161616171718DE +:10B6000019181718181717161616171617171818C7 +:10B6100019181717171716161616161617171818BB +:10B6200018171718181718171717171617181818A4 +:10B63000181817171717171616161616161717189D +:10B640001818171818171716161617171718191885 +:10B650001818181817171616161716171717181878 +:10B660001817171717171716171717171717181769 +:10B67000181717171617161616161616171718185E +:10B680001817181818171716161617171617181848 +:10B69000181818171716161616161616171818183B +:10B6A000181718171717171616161717161718172B +:10B6B0001717171616161515161616161617171726 +:10B6C0001818181717171616161717171718181807 +:10B6D00018171717161616161616161617171818FF +:10B6E00018181817171717161617181717171818E6 +:10B6F00018171717171716161617161616161717E0 +:10B7000018171817171616161516171716161718CE +:10B7100018171717161716161516151616161717C3 +:10B7200018171817171616161616161616161717B0 +:10B73000181717161617161616161616171717189F +:10B740001817171717161616161516161617171890 +:10B750001817171616161615161615161617171883 +:10B760001717171716161616161616171716171771 +:10B770001817171616161616161616161617171762 +:10B78000181717171716161716161617171717184C +:10B790001817171616151615161616161617181842 +:10B7A0001817171717161616161616161716161830 +:10B7B0001817161615161515151616161617171727 +:10B7C0001817161716161616151616161616171813 +:10B7D0001917161716161615151616161616171803 +:10B7E00017171616161516161516161616161717F7 +:10B7F00018161616161515151516151516161617EC +:10B8000019181717161616161516151616161718D0 +:10B8100019171616161516151516151616161718C5 +:10B8200019181717171616171516161616161717AE +:10B8300018171616161515151516151516161717A9 +:10B840001817161616151515151515161616171997 +:10B85000181715161615151515151515161617188A +:10B860001818171616151515151515161616171876 +:10B87000171716161515151515151515151517186D +:10B880001817171616151515141515161616171957 +:10B89000181716161615151514151415151517184D +:10B8A0001917171616151515141515161616171837 +:10B8B000181716161615151414151515151516172F +:10B8C0001817171615151516141515161616171917 +:10B8D000181716161615151415151415151617180C +:10B8E00018171716161515151414151516161718FA +:10B8F00017161615151514141515151515161617F2 +:10B9000018171616151514151414151616161718DB +:10B9100017171615151514141514141516161718CF +:10B9200018171616151515151414151515161618BD +:10B9300017161515151514141515141515161717B2 +:10B94000181716161515141514141515151617189D +:10B95000181716151515141414151415151617188F +:10B96000171716161515151614141515151616187D +:10B970001716151515151414151514151516171772 +:10B980001716161515141414141415161516171960 +:10B990001716151515151414141414141516161855 +:10B9A0001716161515141415141415151516171841 +:10B9B0001716151515151514151414151516161733 +:10B9C0001716161514141414151415151516171822 +:10B9D0001615151515141414141514151516161717 +:10B9E0001716161514141414141414151516161706 +:10B9F00016161515151515141415141414151617F7 +:10BA000017161515141414141414141515161717E5 +:10BA100016151515151514141415141515161617D5 +:10BA200016161515141414141414141415151617C9 +:10BA300015151514151414141414141414151616BD +:10BA400017161515141414141414151515161718A3 +:10BA5000161515151414141414141414141516179B +:10BA6000151615141414131414141414151516188B +:10BA7000161515141414141414141514141516177B +:10BA80001616151514141414141314141516171867 +:10BA9000171515151414141414141414141516175A +:10BAA0001B1B1A1919191918171818181818191909 +:10BAB0001B1A1A1A1A191819191919181919191AF1 +:10BAC0001B1A1A1919191817171818181919191AE9 +:10BAD0001B1A1A1919181818181818181819191AD9 +:10BAE0001B1B1A1A1A1A19181818191919191A1ABF +:10BAF0001B1A1A1A191819191817181818191919B8 +:10BB00001A1A1A191A1A19181819191919191A1B9F +:10BB10001A19191918181818171818181919191A9C +:10BB20001B1B1B1A1A1A1A1918191919191A1A1A79 +:10BB30001B1A1919191919181718181919191A1976 +:10BB40001A1A1A1A1A1A1A19181819191919191A5F +:10BB50001A1A191919191819171818181919191959 +:10BB60001A1A191919191918181819191919191A45 +:10BB70001A1919191918191917181818181819193C +:10BB80001B1A191A1919191918181919191A191A21 +:10BB90001B1A191919191919181818181819191917 +:10BBA0001A19191919191919181818191919181908 +:10BBB0001A191918181918181818181818181919FE +:10BBC0001A191919191919181818181919191919E8 +:10BBD0001A191918181918181818181718191919DE +:10BBE0001A1A1919191919181818181819191919C8 +:10BBF0001A191918181818181818181818181919BF +:10BC00001A19191919191918181718181919191AA8 +:10BC10001A1A19181818181818181818181819199D +:10BC20001A1A1A1919191918181818181819191987 +:10BC30001919181818181818171818171718181885 +:10BC40001A1919191918181818171718181919196D +:10BC50001A1919191818181818181818181819195D +:10BC60001A19191919191918191818181919191947 +:10BC70001A19181818181818181818181818181940 +:10BC80001A1919191919191818181718181919192A +:10BC90001A1919191919181818181918181819191A +:10BCA0001919181818181817181817181819191911 +:10BCB00019191919181818191819191818181919FB +:10BCC0001A191918181918181818181818191A1AEA +:10BCD00019181918181818181818181818191919DF +:10BCE00019191818181818171818181718181919D2 +:10BCF00019191818181717181818181818181919C2 +:10BD00001A19181818181817181918181818191AAD +:10BD10001A19191818171818181818181818191A9D +:10BD20001A19181818181818181918181818191A8C +:10BD30001A19181818181818181818171818181980 +:10BD40001A19181818181817171718181718191A71 +:10BD50001A19181818181818181718181818181960 +:10BD60001A19191818181818171718171818181951 +:10BD70001A19181817181718181818181818181941 +:10BD80001A19181818181818171717181818191A30 +:10BD90001A19181818181717181717181718181924 +:10BDA0001919181818181817181718181818191911 +:10BDB0001A19181817181717181818181718181903 +:10BDC0001A19181818181818181718181818191AEE +:10BDD00019191818171717171818181818181919E3 +:10BDE0001A191818181818171818171818181919D0 +:10BDF00019191818171817171818181818181819C3 +:10BE00001A19181818171817171717171818191AB2 +:10BE10001A1919181817181718181818181818199F +:10BE20001919181817171717171817171818191995 +:10BE30001918181818181817171718171818181984 +:10BE40001A19191818171717171818171718191A71 +:10BE50001A19191818181817171718181818181960 +:10BE60001A19181818181818171818171718181951 +:10BE70001919181818171717171818181817181944 +:10BE8000191817171717171717171717181818193A +:10BE90001918181817171717171717181817191927 +:10BEA000191817171817171717171717171818191A +:10BEB000191817171717161617171717171718180F +:10BEC00019181818181717171716171717181819F9 +:10BED00019181817171616161617171717171819EF +:10BEE00019181818181717171617171717171819DA +:10BEF00019181818171717161617171717171818CD +:10BF000019181817171716171617171817181819BA +:10BF100019181717171717161717171818181919A8 +:10BF2000191818171817161616161717171718199D +:10BF3000181817161717161617171818181818188C +:10BF4000181817171717161616161717171818197F +:10BF5000181817161717161617171718181819196B +:10BF60001818171717171616161617171717181960 +:10BF7000181817161717161617171717181819194C +:10BF8000181817171717161617171717161718193F +:10BF90001918181717171717171717171818191927 +:10BFA000181817171717171616171717161718191F +:10BFB000181817171717161617171717181819190B +:10BFC0001817171716161616161717171717181902 +:10BFD0001918171717171716171716171718191AEA +:10BFE00018181717161617161616171717171819E1 +:10BFF00018181717171717161717161717181819CD +:10C0000018181717161616161616171717171819C1 +:10C0100018171717171717161717171717181919AB +:10C0200018181717171717161616161717171818A0 +:10C03000181717171717171717171717171718188D +:10C040001817171716171616161616171717181982 +:10C05000171717171716171617171717171818196E +:10C060001818171716171716161616161717181862 +:10C070001717161616161616171717161617181856 +:10C080001818171716161616171616161717181942 +:10C09000181717171616171717171717171718192E +:10C0A0001817171616171616171616171717181922 +:10C0B0001817171616161717171717161717181910 +:10C0C0001817171716161616161516171817181903 +:10C0D00019181817161617171617171717171819EC +:10C0E0001B1C1C1B1A1B1B1A191A1A1A1A1A1A1AA9 +:10C0F0001C1B1A1A1B1A1A1B1B1B1B1B1B1B1B1B93 +:10C100001C1C1C1B1B1A1A1A1A1B1B1B1A1A1B1B82 +:10C110001C1B1B1B1A191A1A1A1A191A1B1B1B1B78 +:10C120001C1C1C1B1C1B1B1B1A1B1B1B1A1A1B1B5E +:10C130001C1B1B1B1C1B1B1B1A1A1A1B1B1B1B1B50 +:10C140001C1C1C1B1C1B1B1B1B1B1C1B1A1B1C1B3A +:10C150001B1A1B1B1A1A1A1B191B1B1B1B1B1C1B34 +:10C160001C1C1C1C1C1C1B1B1A1B1C1B1A1A1B1B1B +:10C170001C1B1B1B1B1A1A1B1A1B1B1B1B1B1C1B10 +:10C180001B1C1D1C1B1C1B1B1A1A1C1B1A1A1B1BFD +:10C190001B1B1B1A1A1A1A1B1A1A1B1B1B1B1B1BF5 +:10C1A0001B1C1C1C1B1B1B1B1A1B1C1C1A1A1B1BDD +:10C1B0001B1B1B1A1B1A1A1C1A1A1B1A1B1B1B1BD4 +:10C1C0001B1B1C1C1B1B1B1A1B1B1B1C1B1B1B1CBC +:10C1D0001C1B1C1B1A1A1B1B1A1A1A1A1B1B1B1BB3 +:10C1E0001B1B1C1C1B1B1B1A1A1A1B1B1A1A1B1BA2 +:10C1F0001C1B1B1A1A1A1A1B1B1B1A1B1B1B1B1B93 +:10C200001B1B1C1C1B1B1B1A1A1A1B1B1B1A1A1B81 +:10C210001C1B1B1A1A1A1A1B1B1B1A1A1B1B1B1B73 +:10C220001B1C1C1C1B1B1B1A1A1A1B1B1A1B1A1B60 +:10C230001C1C1B1B1A1A1A1B1B1B1B1B1B1B1B1B4F +:10C240001B1B1B1C1B1B1B1A1A1A1B1A1A1C1B1B41 +:10C250001C1C1B1B1A1A1A1B1B1B1B1A1B1A1A1B32 +:10C260001B1B1C1C1C1B1B1A1A1A1B1A1A1B1B1A21 +:10C270001B1B1B1A1A1A1A1B1B1A1A1A1A1A1A1B18 +:10C280001B1B1B1C1B1B1B1A1A1A1A1A1B1B1A1A04 +:10C290001B1B1B1A1B1B1A1B1B1B1A1A1B1B1B1BF2 +:10C2A0001B1B1B1B1B1B1B1A1A1A1B1B1A1C1B1BE1 +:10C2B0001B1B1B1A1A1A1A1A1B1A1A1A1A1B1B1BD7 +:10C2C0001B1B1B1B1B1B1B1A191A1A1A1B1C1B1BC3 +:10C2D0001B1C1B1B1A1A1A1A1A1A1A1A1A1B1B1CB5 +:10C2E0001B1A1B1B1B1B1B1A1A1B1B1A1A1C1C1BA1 +:10C2F0001B1B1B1B1A1A1A1A1A1A1A1A1A1B1B1B97 +:10C300001B1B1B1B1B1B1B1B1A1A1A1A1A1B1C1C80 +:10C310001B1C1B1A1B1A1A1B1B1A1B1A1B1B1B1B71 +:10C320001B1B1A1A1B1B1B1A1A1A1A1A1A1A1B1B66 +:10C330001B1B1B1A1A1A191A1A1A1A1A1A1B1B1B58 +:10C340001B1A1A1A1A1A1A1A1A1A1B1A1A1B1B1C47 +:10C350001B1B1B1B1B1A1A1A1B1B1A1A1B1B1B1B32 +:10C360001C1C1B1A1B1B1B1A1A1A1B1B1B1B1B1C1E +:10C370001B1B1B1A1B1B1A1A1A1A1A1A1B1A1A1A17 +:10C380001C1B1A1A1A1B1B1B19191A1A1A1A1B1B07 +:10C390001C1B1B1B1B1B1A1A1A1A1A1B1B1B1B1BF1 +:10C3A0001B1B1B1A1A1B1B1B1A19191A1B1A1B1BE6 +:10C3B0001C1B1B1B1A1B1A1A1A1A1A1B1B1B1B1BD2 +:10C3C0001B1B1A1A1A1B1A1A1A1A1A1A1A1A1B1BC8 +:10C3D0001B1B1A1B1B1A1A1A1A1A1A1B1B1B1B1BB4 +:10C3E0001B1B1A1A1B1B1A1A1B1A1A1A1A1B1B1BA5 +:10C3F0001B1B1B1B1B1A1A1A1A1A1A1B1A1B1B1B94 +:10C400001B1C1C1B1C1B1B1B1B1A1A1B1C1C1B1C78 +:10C410001B1B1B1B1A1A1A1A1A1A1A1B1B1B1B1C72 +:10C420001B1C1C1A1C1A1B1B1B1A1A1B1C1C1B1C5A +:10C430001B1B1A1B1A1A1A191A1A1B1B1B1B1B1B54 +:10C440001B1B1B1A1B1A1A1A1A1A191A1C1C1B1C42 +:10C450001B1B1B1B1B1A1A1A1B1A1A1B1B1B1B1B31 +:10C460001B1B1C1A1B191A1A1A1B1A1A1C1B1B1C21 +:10C470001B1B1A1B1B1A1A1A1A1B1A1A1A1A1A1B16 +:10C480001B1C1C1C1C1B1A1A1B1B1A1B1B1C1B1CF9 +:10C490001C1B1B1B1B1B1A1A1A1A1A1B1A1A1B1BF2 +:10C4A0001C1D1D1C1D1C1C1B1B1C1A1A1B1C1B1CD1 +:10C4B0001C1B1B1B1B1A1A1A1A1A1A1B1B1A1B1BD2 +:10C4C0001C1B1B1B1D1C1B1A1A1B1A1A1B1C1C1CB9 +:10C4D0001C1B1B1B1B1A1A1A1A1A1A1A1B1B1B1BB2 +:10C4E0001C1C1C1C1C1B1B1A1A1B1A1A1B1B1B1C9A +:10C4F0001C1B1A1A1A19191A1A1A1A1A1A1A1B1B99 +:10C500001B1B1B1B1B1A1A191A1A1A1A1A1B1B1C83 +:10C510001C1B1A1A1A1A19191A19191A1A1A1A1B7B +:10C520001B1B1B1B1B1B1A1A191A191A1A1B1B1C63 +:10C530001C1B1B1B1B1B1A1919191A1A1A1A1A1B56 +:10C540001B1B1B1B1B1B1A1A191A1B1A1A1D1C1C3E +:10C550001C1B1A1A1A1A1A1A1A1A1A1A1B1A1B1B35 +:10C560001B1B1D1C1C1B1B1A1A1A1B1A1A1B1C1C1A +:10C570001C1B1A191A1A19191A1A1A1B1B1B1B1B16 +:10C580001B1C1B1B1A1B1A1A191A1B1A1A1B1C1C00 +:10C590001C1B1A191A1A1A1A1A191A1B1B1B1B1BF5 +:10C5A0001B1B1B1B1B1B1A19191A1B1A1A1B1B1CE2 +:10C5B0001C1B1A191A1A1A1A1A1A1A1B1B1B1B1BD4 +:10C5C0001B1B1B1B1B1B1A191A1A1B1A1A1A1B1CC2 +:10C5D0001D1E1B1A1A1B1B1B1A1A1A1B1B1B1B1BAB +:10C5E0001B1B1B1B1A1B1B1A191A1B1A1A1B1C1CA0 +:10C5F0001C1B1A1A1A1A1B1A1A1A1A1B1B1B1B1B92 +:10C600001A1A1A1A1A1A1A191A1A1A1A1A1B1B1D86 +:10C610001D1A1A1A1A1A1B1A1A1A191A1A1A1B1B75 +:10C620001B1A1A1B1A1A1A1A191A1A1A1A1A1B1B67 +:10C630001C1B1A1A1A1A1A1A1A1A191A1A1A1B1B56 +:10C640001B1A1A1B1A1A1A1A1A1A1A1A1A1B1B1C44 +:10C650001B1A1A1A1A1A1A191A1A1A191B1A1B1B38 +:10C660001B1B1B1B1A1C1A1A1A1A1A1A1A1B1B1B21 +:10C670001B1C1A1A1A1A1B1A1A1A1A1A1A1A1B1B14 +:10C680001A1A1A1B1A1919191A1A1A1A1A1A1B1C09 +:10C690001B1B1A1A19191A1A1A1B1A1A1A1B1B1CF5 +:10C6A0001B1A1B1B1A1A1A1A1A1A1A1A1A1A1B1BE5 +:10C6B0001A1B1A1A1A1A1A1A1A1A1A1A1A1A1A1BD8 +:10C6C0001B1B1A1A1A1A19191A191A1A1A1B1B1CC7 +:10C6D0001B1A1B1A1A1A1A1B1A1A1A1A1A1A1B1BB5 +:10C6E0001A1A1A1A191919191A1A1A1A1A1A1C1CAA +:10C6F0001C1A1A1A1A1A1A1A1A1A1B1B1B1B1A1B93 +:10C700001B1A1A1A19191A1B1A191A1A1B1B1C1C84 +:10C710001C1B1B1B19191A1A1A1B1C1B1B1B1B1C6D +:10C7200006F0F15506F0F15506F0F15506F0F15519 +:10C73000402C2B2B2A2F2F2C2C34333131313134F8 +:10C740003040322F2E2C2B2A2B2C2C3131302F31F4 +:10C750003231322F322C2C2C2B2B2B2C2C313331F1 +:10C7600030333131312E312B2C2C2B2B2A2B2B2FEC +:10C77000312F2F302F2F2F2F2F2C2B2A2A2A2A2BE5 +:10C780002A2E2F302F302F2F2F2C2F2A2A282A2ADB +:10C7900029282A2D3030302F2F30312D2C2C2B2AC8 +:10C7A0002B2B2B2B282F2C2E2F2D2F2E2C2E2C2BC2 +:10C7B0002A292A2B2A2B2A2F302F2F2E2E2C2D2DB3 +:10C7C0002B2B2B292A2B2A2C2B333130312F2F2F97 +:10C7D0002D2B2B2A2A2A29292A282B2D2F2E2D2DA5 +:10C7E0002E2D2C2C2D2B2C2C2D2B2B2C2C2D30307E +:10C7F0002F2E2F2D2B2B2A2B2B2B2A2B2C2D2A3077 +:10C800002F30302F2D2D2C2A2C2A2A292A2A2A2C67 +:10C810002D2F2F2D2E2E2C2D2B2C2C29282A282A5B +:10C820002B2B2C2E2D2B2D2D2C2D2C2A2C29292851 +:10C83000282B2D2C2B2E2E2E2D2D2C2B2C2B292640 +:10C840002928292A2928292B2B2B2C2A2B2A2C2D45 +:10C850002C2A29292828282927292B292B2B2B2B3F +:10C860002A2C2B28272728282A29292C2C2C2C2A2B +:10C870002C2B2C2E2A2A292828292929292B2A2918 +:10C88000282929292B2F2A2A2A2928282A2A29290E +:10C890002928282828282B2C292929282728292B0A +:10C8A0002B2C2A2929292A2A292B292929292929EE +:10C8B0002929292A2929292828292A2C2A292828E6 +:10C8C00029292A2B2A2C292829282A29282C2A2ACE +:10C8D000292928292929292A292928292929292AC8 +:10C8E0002A292728292929292B2A2B2B2A292A2AB0 +:10C8F0002B2C292A29282829282929292A2A282AA3 +:10C90000292A2A2B292A272829282928292827279C +:10C91000292929292A2C2529282726272828272894 +:10C92000272827272827282A28282729272827298A +:10C930002926282A29282728272B2728272626277B +:10C9400026262627272626242727272B262928267A +:10C95000262728272725292628262627282A272963 +:10C960002827272727272827262527262627272A57 +:10C970002727272627272827282628262726262749 +:10C980002829262726262524262627272626252544 +:10C990002627272A25272626262626262625252534 +:10C9A0002525252526274025262524252526272615 +:10C9B0002523242525252640402A2D2D2E2E2F2CBB +:10C9C0002C313230303231343240302F30312E2F52 +:10C9D0002E2E2D323131323232343332312E2F2E4F +:10C9E000302E2B2D2C3230312F333334342F332F44 +:10C9F0002F2C2C2C2B2C2B3231303132343435313E +:10CA0000302E2F2E2E2D2D2C2C313331323432322C +:10CA1000312F312D2C2D2E2D2C2C2D2F333030302D +:10CA2000323233302D2F2F2F2D2F2E2D2D34313309 +:10CA3000353333322F2E2E2D2F2E2E2E2E2C2F31FE +:10CA4000313032323230302E2D2D2E2E2D2F2C2DF6 +:10CA50002F323230323231302F2D2F2E2E2F2F2EDB +:10CA60002E2E2F32313231313030302F2E2F2D2ECD +:10CA70002F2F2D2F2E2F3233323131302E2F2E2DBE +:10CA80002E2E2C2D2F2F3031333231302F2F2D2CB5 +:10CA9000312D2E2C2D2F302F30333031323231309A +:10CAA000302E2F2D2E2F2E2E2E2F2E313330313093 +:10CAB0002F31312D302D2F2F303032333034343070 +:10CAC00030302F2E2E2E2B2B2E2D2E2F2D2D2D2D8B +:10CAD0002F2C302E302D2F31312E2E2D2F2D302F6B +:10CAE000303331323030313231302F2D2D2E2D2E4A +:10CAF0002F2F30343132312F302F2E322F2D2D2D3C +:10CB00002C2E2D2D2D302F2D2F2F2E2E30312D2E42 +:10CB10002E2E2D2E2F2F2F2F2F2E2F2E2F2E2D2F2F +:10CB20002E2D2D2B2C2C303030312F2F2F2F2E2E21 +:10CB30002F312D2E2E2D2E2E2F2E2E2D2E2E2F2D13 +:10CB40002F2D2E302E2D2E2F302F3031312F2D2EF8 +:10CB50002F2D2E2D2C2E2E2E2D2D2E2F2F2E3030F4 +:10CB60002F302D2E2D2E2F2F2E2D2D2E2D2E2E2EE5 +:10CB70002F2D2E2E2E2C2E2D2D302D2D2D2C2D2EDD +:10CB80002E2E2E2E2E2E2F2E2F2F2F2E2D2E2E2DC3 +:10CB90002F302D2F302F2E2C2E2D2E2E2E30282DB7 +:10CBA0002E2B2C2C2D2C2D2C2E2E2D2C2E2D2C2EB8 +:10CBB0002D2C2B2D2C2B2C2D2E2D2D2E2D2C2D2EAA +:10CBC0002D2F2B2E2C2B2B2C2C2D2E2D2C2C2C2AA0 +:10CBD0002E2C2E2D2E2E2E2E2E2F2E2F2E2C2D2C7B +:10CBE0002B2B2E2E2C2D2C2E2D2D2D2D2D2D2F2C77 +:10CBF0002A2B2C2B2B2E2E302B2D2C2C2C2B2C2B74 +:10CC00002E2C2C2C2C2C2D2C2D2E2B2D2D2D2C2C5C +:10CC10002E2C2D2B2B2D2B2C2C2E2C2E2A2D2C2C50 +:10CC20002D2E2D2C2E2D2C2D2D2D2D2C2D2E402D21 +:10CC30002D2D2E2C2C2F32302D2C2F2D2F2C2D4006 +:10CC4000402D3231323334313234343335343538A7 +:10CC500034403032333333313231303133323536A0 +:10CC60003635363533323432323131312F32343396 +:10CC700031363536363534323232313130322F3783 +:10CC80003535353638363735343332323433313260 +:10CC90003034343436353634353434313030323063 +:10CCA000312E313335333435343435343235343450 +:10CCB000353437333335333636363635343532332B +:10CCC0003332323332313435363336353534343429 +:10CCD000303132333233323333363636363635331B +:10CCE00034333134343434353633383534343637FC +:10CCF00037353333323334343534343334363837EC +:10CD000035353636343530323434343534363735DB +:10CD1000353536353534322F3534333334323334D8 +:10CD200035373634353935353734383434343436AC +:10CD30003839373737373537373835313333353496 +:10CD40003435373536373936353735353333302F97 +:10CD50003232333333333135333635343634353498 +:10CD60003432343132343537343535373637373578 +:10CD7000363534313232343335353436363834366C +:10CD80003535353532343436363736363334373355 +:10CD9000323635343436323235353534333735354D +:10CDA000353533383533333434343432343438363B +:10CDB0003636353536353634333334343434353429 +:10CDC000363436353734333634323434333434341D +:10CDD0003536363836363635343636353334333400 +:10CDE0003333353433343435363436363333333500 +:10CDF00035353335333934393635383435363634DC +:10CE000034333434363635353535363333353535D8 +:10CE100035353432343434333635343735373734C6 +:10CE200036393636343430333333333333333333C4 +:10CE300034333435363333353333333537333538AC +:10CE4000363335333335343434342F3535333636A1 +:10CE50003435353533313232333333353335343499 +:10CE60003436353433343532343334353334333681 +:10CE7000353436353537343432323434343534356C +:10CE80003335333333353434343435333433343366 +:10CE90003435333437343435353333343332343452 +:10CEA0003335363637343434343637353434363433 +:10CEB000363434343534403D373937393C463935EA +:10CEC0003638333339333340403A353638363736EF +:10CED00034393A373A3A3A3D3D403E3F3F3E3738A3 +:10CEE000373636383837383D3D3A3A3937383A36BA +:10CEF0003635333535383837373C3A3B3B393937B7 +:10CF0000383637363637353A3B38383B3B3A38389F +:10CF100039393938393B363936393D3B3C3B3C3A77 +:10CF20003C38393538383737383536363B38393884 +:10CF3000383A3938353A393A393B3837353E393F5E +:10CF40003A3C3D3B383A373739393A38383A373A4C +:10CF50003A393C3B3C3C3A3834373837393B38383F +:10CF6000373A3C3D3C3E3E3C3A353739393B39391E +:10CF700037383B393B393B3E3B3B393A3739393B14 +:10CF8000393A3A3B3D3A3F3D3D3B3C3B393A3539F6 +:10CF9000393A3A3A3938393A3C3C3B3C3C3A3736F4 +:10CFA0003A39393A38393A3A3F3A3C3B3C3C3B3CD7 +:10CFB00039383B3A393C3A3D3A3B3D3C3C3D3B3DC0 +:10CFC0003E3B3C363A393C3A393C3C3B3D3A3C3AB4 +:10CFD0003D3B3D3D3C3A34373B393B3B39393839B1 +:10CFE0003B3B3B3C3E3B3A383A393A3A3B383738A0 +:10CFF000383B3B38393B3E3B38393A383A393A3896 +:10D00000373A3C3C3B3D3D393D3C383A393B3B3A75 +:10D010003C3D373A3A3A3A3A3B3D3C3C3C3A393A65 +:10D020003B3C3B3A393C3C3B3A3B3D3B3E3A3B3A4E +:10D03000393A3A3A383C3B3E3D3C3B3C3C3C3D3C3B +:10D040003B3A393C3D3B3B3E3A3C3A3C3A393C3B2F +:10D050003B3A3B3A3C3A3B3C3A3A3B3D403C3D3E16 +:10D060003B3B3D3A3A3A393A3B3B3A3A393A393A1C +:10D07000393A3B3E3C3C3B3B3C3C3A393B3B3A3CFF +:10D080003D3E393C3C3B3D3C39393B3B3D3D3B3BE8 +:10D090003A3B3D3A3A3A3B3B3B3A3B373B3A3B3BE8 +:10D0A0003E3B3A3D3A3B393B3C3B3E3C3A3B353DCF +:10D0B0003C3839383A39363C3C3A3C3C3D3B3B3CC9 +:10D0C0003A3B3A3B3A393B393D393A3E3C3B3A3CB4 +:10D0D0003B39373D3B3B38393A383B3A38383C3AB4 +:10D0E0003E3A3A3A373E3D3C3C3C3C3F3B3B3C3B86 +:10D0F0003A3A3D3B3B3C3A3E3C3D3C3B3D3C3B3D74 +:10D1000039393B3B3B3B3C3D393B3C393E393C3C70 +:10D110003D3B3A3C3C3A3C3D3B3A3A3D3A3D3B385C +:10D120003E393D3C3B3D3C3C3C3D3B3A393D3F403C +:10D130003F3E3D3C3E3B3B3C3E3F3F3D3D3B404117 +:10D14000404444474041403F3E3D3D3D413F3D40DE +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000004806108000488610800048061F800044 +:10D3C00048861F800048061180004886118000486A +:10D3D000061E800048861E8000480612800048868F +:10D3E00012800048061D800048861D8000480613F4 +:10D3F0008000488613800048061C800048861C80F8 +:10D40000004806148000488614800048061B8000EF +:10D4100048861B8000480615800048861580004815 +:10D42000061A800048861A80004806168000488642 +:10D4300016800048061980004886198000480617A3 +:10D4400080004886178000480618800048861880AB +:10D4500020001904902000320887200032C8802064 +:10D4600000325882200032E8832000327885200084 +:10D470003208872000196890200019889320000244 +:10D48000F44B200002044C200019F89120001918D8 +:10D4900095200002F44B200002044C20001938981B +:10D4A000200032A8962000326890200032F89120A7 +:10D4B000003288932000321895200032A896000090 +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D54000010090010201060A640028324600000032 +:10D5500000000000000000003C0000004006000049 +:10D5600034080000A0A0010101011900010014000D +:10D5700001001600E4000A00001478000032780070 +:10D580000000002032323232323232323232323223 +:10D59000323232323232000000000000000000005F +:10D5A000000000000000000034083408F40100000E +:10D5B0000209200019450000F16C000084D9060022 +:10D5C00029B1010010270000C409000000014B0F21 +:10D5D00000000000000000003C3C0A0A02000000BD +:10D5E0000000000001010101010040003200E803D9 +:10D5F0000F0008000A0010001000020202000300E1 +:10D6000003000A0006006400E803000004000000B4 +:10D6100000000000000000000101010101004000C5 +:10D620003200E80314000F000A00E10000000808BF +:10D630000A0028001E001E0006006400E803000027 +:10D640000400000000000000000000004006300060 +:10D6500020000100220000003A00520070008F00FC +:10D66000AF00CF00EF000F012E014F016E018E01C0 +:10D67000AD01CE01EC010F022D024D026D028D02B3 +:10D68000AC02CC02EB020B032B034A036A038903AF +:10D69000AA03C903E703FF033704000000000000EA +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000280AD7 +:10D72000300046000100480000003C004300660055 +:10D730008500A900C800E90009012A0149016B011F +:10D740008901AB01C901EB0109022B024A026C02FB +:10D750008A02AC02CA02EC020B032D034B036D03D9 +:10D760008B03AE03CB03EE030C042F044C046F04B5 +:10D770008B04AF04CC04EF040D0530054D05700596 +:10D780008D05B005CD05F1050D0630064E06720675 +:10D790008E06B106CE06F2060F0732075007730752 +:10D7A0009007B307D107F407110834085208750829 +:10D7B0009108B108C608E70800000000000000005A +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F00000000000080009000B000D000F001200DF +:10D80000150018001D00210027002D0034003C00E9 +:10D81000450050005C006900780089009C00B10060 +:10D82000C900E3000001210145016C019701C70116 +:10D83000FB0134027102B402FD024B03A003FA03A0 +:10D840005C04C3043205A7052406A8063207C407F2 +:10D850005C08FC08A2094E0A000BB80B750C360DCB +:10D86000FC0DC50E910F5F102E11FD11CC129A13F5 +:10D8700065142C15EF15AD1664171418BB1859193B +:10D88000ED19761AF21A621BC41B191C5E1C951C3A +:10D89000BC1CD41CDC1C080009000B000D000F0090 +:10D8A0001200150018001D00210027002D00340073 +:10D8B0003C00450050005C006900780089009C0035 +:10D8C000B100C900E3000001210145016C0197018D +:10D8D000C701FB0134027102B402FD024B03A00335 +:10D8E000FA035C04C3043205A7052406A806320720 +:10D8F000C4075C08FC08A2094E0A000BB80B750CA3 +:10D90000360DFC0DC50E910F5F102E11FD11CC12BE +:10D910009A1365142C15EF15AD1664171418BB185F +:10D920005919ED19761AF21A621BC41B191C5E1CD8 +:10D93000951CBC1CD41CDC1C080009000B000D004D +:10D940000F001200150018001D00210027002D00F7 +:10D9500034003C00450050005C00690078008900FC +:10D960009C00B100C900E3000001210145016C01E8 +:10D970009701C701FB0134027102B402FD024B039F +:10D98000A003FA035C04C3043205A7052406A80615 +:10D990003207C4075C08FC08A2094E0A000BB80B4A +:10D9A000750C360DFC0DC50E910F5F102E11FD117B +:10D9B000CC129A1365142C15EF15AD1664171418B4 +:10D9C000BB185919ED19761AF21A621BC41B191CDF +:10D9D0005E1C951CBC1CD41CDC1C080009000B0040 +:10D9E0000D000F001200150018001D002100270077 +:10D9F0002D0034003C00450050005C0069007800B8 +:10DA000089009C00B100C900E3000001210145012B +:10DA10006C019701C701FB0134027102B402FD02DF +:10DA20004B03A003FA035C04C3043205A7052406D4 +:10DA3000A8063207C4075C08FC08A2094E0A000BBE +:10DA4000B80B750C360DFC0DC50E910F5F102E1125 +:10DA5000FD11CC129A1365142C15EF15AD16641731 +:10DA60001418BB185919ED19761AF21A621BC41B47 +:10DA7000191C5E1C951CBC1CD41CDC1C0A000B0071 +:10DA80000E0010001300160019001D0022002800CF +:10DA90002E0035003D00460051005C006900780012 +:10DAA00089009B00B000C700E100FD001C013F01A0 +:10DAB00065018E01BC01EE0124025F029F02E402B7 +:10DAC0002F037F03D60332049504FE046D05E3059E +:10DAD0006006E3066D07FE0795083309D609800A3C +:10DAE0002F0BE30B9B0C580D180EDB0EA10F6810CB +:10DAF0002F11F711BE12841346140515C0157516A3 +:10DB00002417CC176B1801198E190F1A851AEF1AE2 +:10DB10004D1B9D1BDF1B121C381C4E1C551C0A0084 +:10DB20000B000E0010001300160019001D0022004B +:10DB300028002E0035003D00460051005C006900C1 +:10DB4000780089009B00B000C700E100FD001C01C7 +:10DB50003F0165018E01BC01EE0124025F029F02BC +:10DB6000E4022F037F03D60332049504FE046D05FF +:10DB7000E3056006E3066D07FE0795083309D6093D +:10DB8000800A2F0BE30B9B0C580D180EDB0EA10F18 +:10DB900068102F11F711BE12841346140515C01515 +:10DBA00075162417CC176B1801198E190F1A851AC0 +:10DBB000EF1A4D1B9D1BDF1B121C381C4E1C551CE5 +:10DBC0000A000B000E0010001300160019001D00C3 +:10DBD000220028002E0035003D00460051005C0068 +:10DBE0006900780089009B00B000C700E100FD00DB +:10DBF0001C013F0165018E01BC01EE0124025F02A0 +:10DC00009F02E4022F037F03D60332049504FE042F +:10DC10006D05E3056006E3066D07FE079508330909 +:10DC2000D609800A2F0BE30B9B0C580D180EDB0E48 +:10DC3000A10F68102F11F711BE1284134614051599 +:10DC4000C01575162417CC176B1801198E190F1AE9 +:10DC5000851AEF1A4D1B9D1BDF1B121C381C4E1C16 +:10DC6000551C0A000B000E001000130016001900CE +:10DC70001D00220028002E0035003D004600510006 +:10DC80005C006900780089009B00B000C700E100DB +:10DC9000FD001C013F0165018E01BC01EE01240263 +:10DCA0005F029F02E4022F037F03D6033204950430 +:10DCB000FE046D05E3056006E3066D07FE079508A3 +:10DCC0003309D609800A2F0BE30B9B0C580D180E55 +:10DCD000DB0EA10F68102F11F711BE12841346142A +:10DCE0000515C01575162417CC176B1801198E1958 +:10DCF0000F1A851AEF1A4D1B9D1BDF1B121C381CB7 +:10DD00004E1C551C29002F0035003B0043004C00E1 +:10DD100055005F006B00780086009500A600B900F2 +:10DD2000CD00E300FC00160133015201740199019A +:10DD3000C001EA01180249027D02B602F102310374 +:10DD40007503BC0308045804AD0406056305C50546 +:10DD50002B06960605077807EF076B08EB086E0998 +:10DD6000F4097F0A0C0B9B0B2E0CC20C580DEF0D07 +:10DD7000870E1F0FB80F4F10E6107B110E129E1268 +:10DD80002B13B4133814B8143315A71516167D16B3 +:10DD9000DD1635178517CD170B1841186D1890181B +:10DDA000A918B718BC1829002F0035003B00430004 +:10DDB0004C0055005F006B00780086009500A600BF +:10DDC000B900CD00E300FC001601330152017401DB +:10DDD0009901C001EA01180249027D02B602F1026E +:10DDE00031037503BC0308045804AD04060563053C +:10DDF000C5052B06960605077807EF076B08EB08A5 +:10DE00006E09F4097F0A0C0B9B0B2E0CC20C580DEB +:10DE1000EF0D870E1F0FB80F4F10E6107B110E127B +:10DE20009E122B13B4133814B8143315A7151616F5 +:10DE30007D16DD1635178517CD170B1841186D188F +:10DE40009018A918B718BC1829002F0035003B00FE +:10DE500043004C0055005F006B0078008600950081 +:10DE6000A600B900CD00E300FC0016013301520109 +:10DE700074019901C001EA01180249027D02B6024B +:10DE8000F10231037503BC0308045804AD04060510 +:10DE90006305C5052B06960605077807EF076B088F +:10DEA000EB086E09F4097F0A0C0B9B0B2E0CC20CBD +:10DEB000580DEF0D870E1F0FB80F4F10E6107B1196 +:10DEC0000E129E122B13B4133814B8143315A71561 +:10DED00016167D16DD1635178517CD170B18411848 +:10DEE0006D189018A918B718BC1829002F00350014 +:10DEF0003B0043004C0055005F006B00780086003B +:10DF00009500A600B900CD00E300FC001601330126 +:10DF1000520174019901C001EA01180249027D020F +:10DF2000B602F10231037503BC0308045804AD04C2 +:10DF300006056305C5052B06960605077807EF0756 +:10DF40006B08EB086E09F4097F0A0C0B9B0B2E0C77 +:10DF5000C20C580DEF0D870E1F0FB80F4F10E610B3 +:10DF60007B110E129E122B13B4133814B8143315F0 +:10DF7000A71516167D16DD1635178517CD170B1844 +:10DF800041186D189018A918B718BC1855005500FD +:10DF900045004200000000001C02370254027202D9 +:10DFA0009002B002D102F30216033A035F03850325 +:10DFB000AC03D503FF03290455048204B004DF0435 +:10DFC0000F0540057205A505D9050E0644067A061B +:10DFD000B206EA0622075C079607D0070B08470837 +:10DFE0008308BF08FB0837097409B009ED09290A3D +:10DFF000650AA10ADC0A170B510B8B0BC30BFB0B39 +:10E00000330C690C9E0CD20C040D360D650D940D6D +:10E01000C10DEC0D150E3D0E630E870EA80EC80E39 +:10E02000E60E010F1B0F320F460F590F690F760FC7 +:10E03000820F8A0F900F940F950FBA04C904D80469 +:10E04000E704F604050514052305320541055005CE +:10E050005F056E057D058B059A05A805B705C50505 +:10E06000D405E205F005FE050C0619062706340660 +:10E0700042064F065C066906760682068F069B06F8 +:10E08000A706B306BE06CA06D506E006EB06F606E8 +:10E0900000070B0715071E07280731073A07430734 +:10E0A0004C0754075C0764076C0773077A078107FE +:10E0B00087078D07930799079E07A307A807AC0753 +:10E0C000B107B407B807BB07BE07C107C307C50739 +:10E0D000C707C807C907CA07CB07CB07FA006C00F8 +:10E0E000FA006B006400D007000028000000000068 +:10E0F0000000000000000000000000000000000020 +:10E100000200190050001E001E000C001900000043 +:10E110000100000001000000948D0300508D0300F9 +:10E12000948D0300548D03000101000078563412D1 +:10E130007856341201000000010000008C0000003D +:10E14000404000000100000070AD0200FFFFFFFF33 +:10E15000AA000000103303000700000001000000C7 +:10E16000FFFFFFFFFFFFFFFFFFFFFFFF01000000BA +:10E17000FF000000000000000000000000000000A0 +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F0000012ED20324006000A0E0A0001030108102A +:10F0100032004006280A0000000C01000000000039 +:10F020000013535904060000000000000008010905 +:10F03000000132344006000028191A0000000800C0 +:10F0400000000800000008000000080000000800A0 +:10F05000000008000000080000000800F0EF0000B9 +:10F06000000008000000080000000800F0EF0000A9 +:10F070000000080000000800000008000000000078 +:10F08000000101000000000000000000000000007E +:10F09000000000000000000000000101010101006B +:10F0A0000001010000000101010100010000000059 +:10F0B0000100000102000000070000000107010339 +:10F0C000020314000A0A4000000078003C0000001F +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000C800C8009600C80032 +:10F0F00007078000800005050000000000000000F8 +:10F1000006010000000017003900910010001400F3 +:10F11000F9FFC4FFFF7FFF7FFF7FFF7FFA002C0115 +:10F120003200C8000A04B4B43232230500000000E3 +:10F1300000070D0000320D00000000203232323294 +:10F140003232323232323232323232323232000003 +:10F1500000000000000000000000000000000000AF +:10F160000A05000A00000000140F0012101200002F +:10F17000000000000000000000000000000000008F +:10F18000000000000F233246500000006A64504621 +:10F190003C3C3C3C08000000000000000F233246CD +:10F1A000500000006A6450463C3C3C3C0F141E2852 +:10F1B000000000000A0A0A0A0A0A0A0A0C192D416C +:10F1C0005000000046554B464646464600000000AB +:10F1D0000A0314005F00F1FF14000F000A00BC02D4 +:10F1E00000000000F8FF00007800320064002800F2 +:10F1F0000F000F001C023D011C02740400003F06BA +:10F200000000FF09F40100003F060000FF0932146E +:10F21000021E1E32020096003C003C007700C8052A +:10F22000770088090000000040063000200001003F +:10F23000220000003A00520070008F00AF00CF00A3 +:10F24000EF000F012E014F016E018E01AD01CE01C5 +:10F25000EC010F022D024D026D028D02AC02CC02B8 +:10F26000EB020B032B034A036A038903AA03C903B6 +:10F27000E703FF0337040000000000000000000067 +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F00000000000000000000000280A3000460066 +:10F300000100480000003C00430066008500A900A1 +:10F31000C800E90009012A0149016B018901AB011B +:10F32000C901EB0109022B024A026C028A02AC02FB +:10F33000CA02EC020B032D034B036D038B03AE03D8 +:10F34000CB03EE030C042F044C046F048B04AF04B6 +:10F35000CC04EF040D0530054D0570058D05B00595 +:10F36000CD05F1050D0630064E0672068E06B10675 +:10F37000CE06F2060F073207500773079007B30750 +:10F38000D107F40711083408520875089108B1082C +:10F39000C608E708000000000000000000000000B0 +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D0000201200019450000F16C000084D90600EC +:10F3E00029B1010010270000C4090000000101013B +:10F3F000010102020202014B0F00A0000000000008 +:10F400000100010101010102020202001945000090 +:10F4100002000000A46B00000000000014140A0A9F +:10F420001400000000000000141414140101010174 +:10F43000010040003200E8030F00080005009000C2 +:10F4400000001E502800B40050000400000000001E +:10F45000B4005000FA00A000000000014F010000BD +:10F460000000000068010D0D0A094B004B0064000C +:10F470000A003200C800640064000F02E8E8F800E7 +:10F48000F8000200190000006A00750081008E007B +:10F490009D00AC00BD00CF00E200F7000D01260189 +:10F4A00040015C0179019901BC01E00106023002D2 +:10F4B0005B028902BA02EE0224035D039A03D903B8 +:10F4C0001B046004A904F40443059505E9054106FD +:10F4D0009C06FA065B07BE0724088D08F808650934 +:10F4E000D409450AB80A2D0BA20B190C900C080D73 +:10F4F000800DF80D6F0EE60E5C0FD00F4210B310AA +:10F5000021118C11F4115912BA1217137013C4136C +:10F5100013145D14A114E01418154B1577159C15E0 +:10F52000BB15D415E515EF15F31536003D00440065 +:10F530004C00560060006B00770085009300A4002B +:10F54000B500C900DE00F5000E0129014601650184 +:10F550008701AC01D401FE012B025B028F02C602BF +:10F5600001033F038003C6030F045D04AE040305DB +:10F570005D05BA051B068106EA065707C9073D085F +:10F58000B6083109B009320AB70A3E0BC70B520C54 +:10F59000DF0C6D0DFC0D8B0E1A0FA80F3610C3106B +:10F5A0004D11D6115B12DE125C13D7134D14BD142E +:10F5B00028158D15EC1544169516DE161F175817CD +:10F5C0008917B117D117E717F517FA174E0056002C +:10F5D00060006B00760083009100A000B100C200C3 +:10F5E000D600EB0002011A013501520170019101B0 +:10F5F000B501DB0103022E025C028D02C102F8029A +:10F6000032036F03B003F4033B048604D4042605DD +:10F610007C05D50532069206F5065C07C607330859 +:10F62000A30816098C09040A7E0AFA0A790BF80B5A +:10F63000790CFB0C7E0D010E830E060F870F071051 +:10F64000861003117D11F5116912DA124713AF13F9 +:10F6500013147214CB141E156B15B215F2152C165B +:10F660005E168916AC16C716DB16E716EB166A008F +:10F67000750081008E009D00AC00BD00CF00E2004F +:10F68000F7000D01260140015C0179019901BC01DF +:10F69000E001060230025B028902BA02EE02240394 +:10F6A0005D039A03D9031B046004A904F404430511 +:10F6B0009505E90541069C06FA065B07BE07240886 +:10F6C0008D08F8086509D409450AB80A2D0BA20B64 +:10F6D000190C900C080D800DF80D6F0EE60E5C0FE6 +:10F6E000D00F4210B31021118C11F4115912BA121B +:10F6F00017137013C41313145D14A114E014181518 +:10F700004B1577159C15BB15D415E515EF15F3159D +:10F7100055005500450042000000000000000000B8 +:10F7200000000000000000000000000000000000D9 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000000000099 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F86000000000000000000000000000A000D20026 +:10F8700004013C0005000000000000000000000042 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF000000000000000000000000000004E565409 +:00000001FF diff --git a/firmware/novatek_nt36523_fw02.bin.ihex b/firmware/novatek_nt36523_fw02.bin.ihex new file mode 100644 index 000000000000..77a150e880ad --- /dev/null +++ b/firmware/novatek_nt36523_fw02.bin.ihex @@ -0,0 +1,12291 @@ +:1000000000020000000000008F9E0100002002009E +:100010000000020077C10000F607C29633C77E5485 +:1000200003000000000000000000000000000000CD +:10003000000002000000000000200200D5744365AB +:10004000000A020000000000002A0200CB94D02029 +:10005000003202000000000000520200AF0FDC1569 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F00078C10200FF00000000000000B48B5542F0 +:1001000000020000000000008F9E0100002002009D +:100110000000020077C10000F607C29633C77E5484 +:1001200001000000000000000000000000000000CE +:10013000000002000000000000200200D5744365AA +:10014000004A020000000000006A0200AF0FDC1548 +:10015000007202000000000000920200AF0FDC15E8 +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00078C20200FF000000000100006ED15661CD +:10020000480001A2EABF0000EABF0000EABF000008 +:10021000EABF0000EABF0000EABF0000EABF00003A +:1002200048000000DD4D0000EABB0000EABB000012 +:10023000DD4D0000EABB0000DD4D0000DD4D00009B +:10024000DD4D0000DD4D0000DD4D0000DD4D000006 +:10025000DD4D0000DD4D0000DD4D0000DD4D0000F6 +:10026000EABB0000EABB0000DD4D0000DD4D0000F0 +:10027000DD4D0000EABB0000EABB0000DD4D0000E0 +:10028000DD4D0000DD4D0000DD4D0000DD4D0000C6 +:10029000DD4D0000DD4D0000DD4D0000DD4D0000B6 +:1002A000DD4D0000DD4D0000DD4D0000DD4D0000A6 +:1002B000DD4D0000DD4D0000DD4D00004800000078 +:1002C00048000000DD4D0000DD4D0000DD4D000068 +:1002D000DD4D00004800000048000000480000001C +:1002E00048000000480000004800000048000000EE +:1002F00048000000480000004800000048000000DE +:1003000048000000480000004800000048000000CD +:1003100048000000480000004800000048000000BD +:1003200048000000EA040000EA0400005A07000048 +:100330008415000084150000841500008415000059 +:1003400084150000841500008415000000000000E2 +:100350001C09000024090000E8090000620A0000EE +:10036000AA0A0000580B0000B80B0000D60B0000D2 +:10037000DE0B0000E60B0000EE0B0000F60B0000A9 +:10038000080C0000100C00001C0C00000A110000FA +:100390002E0C0000180D0000600D0000680D00001C +:1003A000A60D0000B80D0000CA0D0000F00D000001 +:1003B000900E00000C0F0000140F0000260F00002C +:1003C000BC120000BE120000E2120000EA1200009F +:1003D000F2120000021300000413000010130000CA +:1003E0001E1300003A13000000000000000000008F +:1003F000B8140000D4140000201500006615000099 +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:100450003A0FEFFC421E80203A1F883C6412A4022F +:10046000642204023A1F883C803F640264029205C1 +:1004700096374420012C38210202643200029ED9B2 +:1004800064320003DD2264020043640000083A1F66 +:1004900088046412A403642204033A1F8804421EE1 +:1004A00080213A0FEFC4640000043AFFECBC3A0F1D +:1004B000943C421E80203A1F883C640264029205EC +:1004C00096374420012C382102028E09DD223A1F82 +:1004D0008804421E80213A0F94043AFFEC846400A1 +:1004E00000043AFFECBC3A0F943C421E80203A1FB5 +:1004F000883C6412A402642204023A1F883C64020D +:100500006402920596374420012C382102028E099C +:10051000643200029ED964320003DD22640200438B +:10052000640000083A1F88046412A40364220403D0 +:100530003A1F8804421E80213A0F94043AFFEC844B +:10054000640000044FF200223A0FEFFC421E8020AC +:100550003A1F883C45D2D7F0801F64126402965F30 +:100560009E49C1053CFD4A4D480000043CFD4A4EF1 +:10057000E80CDD2F4E03000A3A1F8804421E80213A +:100580003A0FEFC464000004640224024410C00067 +:10059000FE0FFE0D640224036400000845D2D7F06C +:1005A00045F2FE006400800292189604C0054401E2 +:1005B000700C420E002144F004BCE802DD2F3CFD2B +:1005C0004A4FDD2F640FFFEAFC004462EEEC440268 +:1005D000C37884209AB0EA3DEA3AAE31FC80FC0050 +:1005E00084003C0FFB5BEBFC3C0FFB6A3C0FFB6E9B +:1005F000EBC73C0FFB7F3C0FFB643C0FFB6F3C0FDA +:10060000FB6B3C0FFB773C0FFB6C3C0FFB683C0F1C +:10061000FB653C0FFB5E3C0FFB7D3C0FFB823C0F00 +:10062000FB753C0FFB763C0FFB733C0FFB59EB68F3 +:100630003C0FFB6D3C0FFB633C0FFB5DEADD3C0FA9 +:10064000FB603C0FFB623C0FFB813C0FFB743C0FDB +:10065000FB7C3C0FFB693C0FFB5F3C0FFB713C0FCD +:10066000FB613C0FFB703C0FFB783E07EC0764031B +:100670000003EA7BEB6A64122402964C8040C103BB +:10068000640300036422240364020002660000067F +:1006900064020003640000086403040246029C1024 +:1006A0005000007CEA7B6403080244000633EB6AD6 +:1006B00064020002EA4264020003FC804403F0ED9D +:1006C000A6405A1801048420AE404413F0DAA6086C +:1006D000EBA1AE088404EA7B84254403F049AE40D4 +:1006E00044100053DD43AE40DD9EDD9E4443F114D3 +:1006F000B464927840000F04B6044403F138AC406F +:1007000084204403F13AAE404403F104B64084210E +:100710004403F136AE40F808A640964CC103AED073 +:10072000D5FC4413F134EA37EA3183FFA608960E6C +:10073000C803AED0D5FC4403F134A6009604DD9E78 +:1007400084A0D20738301400383094088CA1D5FA30 +:10075000DD9EFC00DD42C00C8407DD4A8400DD4ADA +:100760004412C2788402804144300100DD44FC80A0 +:10077000FC0080C0DD42C012441FFF9FEBBEAE40B4 +:1007800096304412FE61AE08EB734412FE62AE086E +:10079000DD43DD45C603AE40D5FEFC80FC403C7D1C +:1007A000FB308140DD42C05B852384C03C2DFB30A3 +:1007B00040212480A051C108F85C5A08010640106D +:1007C000240CFF8F97B18D215A980FF2F85F5A08C9 +:1007D000010442633C088387B97DB87C8E24964926 +:1007E000BA7FF85C5A08010558630001D502C605B6 +:1007F0005AA8AE048006F8118420EB1FAE404402D4 +:10080000FE63A6408420AE40A681AE41490011257A +:100810005A0801065803000249FFFFACEA67EA40A4 +:10082000EA28A78097B05A600204AE88D5FB4472CC +:10083000FEF1A6385A008608440000C1DD41F87F69 +:10084000AE40D5FF49003CCB84003E07EE01802737 +:1008500080064422C5F18461DD44FCC05AA8AE4B39 +:1008600084E380C03C2DFB3040211C80A051C10B93 +:10087000B4029649A093F8125A08010640001C0CD5 +:10088000FF8797B18CE15A780FEF3C2DFB308382C4 +:10089000B93DB83C8E249649BA3F49FFFF295A0812 +:1008A0000105EA6642633C0884204402FE78AC40BD +:1008B0004412FEF1EA67C619442FFFEEAE88842287 +:1008C000AE404412FE60440FFF8FAE084422FE612A +:1008D0009630AE10EB7396004422FE62AE10846335 +:1008E00080418402DD44D520442FFF86AE888422D7 +:1008F000D507441FFF86EB1FAE408422EA67AE4057 +:100900004403F007A6004412FE639600AE084403B9 +:10091000F004A6004422FE649600AE1084028041DA +:100920008060DD4484C04412FEF180418461840211 +:10093000DD44EA21804184028461DD44DD43DD45FC +:1009400083FFC603AE40D5FE4412FEF1EA37EA311A +:10095000A608C003AED0D5FDFCC03A6FA0BC840091 +:10096000802049006B5D84006405E403EBAAA44089 +:1009700096669649C102D5004422FEF6AE50A440C8 +:10098000964EC910A4409656C90DA440965EC90A59 +:10099000A4409666C907A4405410810096494E129F +:1009A00000864413F00EA408960EC806A58854636A +:1009B000010097B1C6208400EAACA788AC084413B4 +:1009C0008D203E07EBB4AE0844138D21AE084413CE +:1009D0008D22AE0844138D23AE0844138D24AE0837 +:1009E00044138D25AE0844138D26AE0844138D277D +:1009F00097B0AE0849FFFDEA49000EBBEBAAA44040 +:100A0000964EC908A4409666C905A400540001008A +:100A1000C00349003A1AEBBE8420AC404472C1784E +:100A20008400EADD3C7FFB303C0FFB5D3C0FFB7933 +:100A3000DD42C805507381003C7FFB3049FFFE8BCF +:100A4000800649FFFEAD8423EA67AE40840144136B +:100A5000F7D3AE084413F7D9AE08FA56EA9D44120C +:100A6000FE7849FFFE6F3C0DFB304432FE7C0400F3 +:100A700000093E07282D401020093E17282E40105F +:100A8000400992183E17282F3E0728304422FE7D49 +:100A9000F8054432FE7E4422FE7FA618A650960238 +:100AA000964AAE58AE1083FFD508A4005400020049 +:100AB000C00484024900106C4413F029A608EAB36C +:100AC000AE088400EA633C0DFA4A4413F00EA648CF +:100AD000EB8E4413F00FA6481010003D49003A1D5C +:100AE0003C0FFB3EFA0449005476FA044900547363 +:100AF0002E07ECF8DD4AEA3F9E81E648E80B8421A8 +:100B00004010880C5410808FC10550007FE0960083 +:100B1000DD41490006613A6FA084DD9E84013C0FEF +:100B2000FB5BDD9E3BFFFEBC3C0DFB668C01EBFCE2 +:100B3000DD465A080246DD40A6015A08033EDD5A4A +:100B40005A08023BDD42C03C2E07EB8CE603E8036B +:100B50008C01D50284003E07EB8C2E37EB8C4402CF +:100B6000E6C8EB1C40000CE0EAA3EA7CEAA3EA7CBE +:100B7000EAA3EA7C3B0044003B00C4205A3801064B +:100B80008400EAFCEB82D5098406EB6F4400007D0B +:100B9000EB728401EAFCEBE6EA979E41E622E90368 +:100BA0005A08040F49004B0F4900A044C0098400B3 +:100BB000EA2AEAD2D505DD42C0038400EB542E07B1 +:100BC000EEE65A0801103C1DFB662E07EEE5E2201A +:100BD000E803EBE6D507EB828400EAFC84003E07DD +:100BE000EEE63BFFFE84DD9E3BFFFEBC3C0DFB6A58 +:100BF0008C013C0FFB6ADD40A6008E01E602E82D69 +:100C00002E07EBB95A08550A3C03F6138C019601DE +:100C1000E60AEBB5E91DD508DD42C0182E07EBB09A +:100C20005A085515D5F28404DD4184013E07EF32A0 +:100C30008400EA26DD40A6005A080105EAA8EA6A0F +:100C4000D5078E02E602E900D5038400EBB5EA3B46 +:100C50003E07EBB9EA8BD5038400EBB53BFFFE847E +:100C6000DD9E3A6F98BC4403F06BA6003E07EC058E +:100C7000DD46C8062E07EC05961F5A000F16FA101F +:100C8000DD4184013C0FFB6EEBD749006FE8DD408E +:100C90008422DD5649006FFD8420840284468061F1 +:100CA000808180A1DD57EA20DD9E3A6F9EBC49001D +:100CB0006A72C017840049006A72F82280C05A081C +:100CC0000111DD465A0802043C6FFB6744000080B6 +:100CD000DD41DD40EBC6EAC9EBCA84814900239FB0 +:100CE00049006A50C00784013C0FFB7A8400490028 +:100CF0006A4D49006A80C025840049006A80490025 +:100D00006ACD5A08011FEA7EA6005A08130EDD526A +:100D1000A6088E02E603E904A6095A0808068420FC +:100D2000EA7EAE40D51784C1440000803C6FFB5A78 +:100D3000DD41DD40EBC6EAC9EBCA80864900236F7E +:100D400049006A50C007840049006A5084013C0F82 +:100D5000FB5D3A6F9E84DD9E3BFFFEBCDD59842126 +:100D60003C1FFB7BAE40EA3A44238D433E07EBB980 +:100D7000A6108801AE10DD40A681542100FD5A2046 +:100D80000403DD5649006F5EC00A8409DD41FA188C +:100D9000EA328403EA9884013E07EBDC2E07EEAFCB +:100DA0008C0196003E07EEAFDD42C80484013E0789 +:100DB000EE9D3BFFFE84DD9E3A6F98BC84013C0FA4 +:100DC000FB7FFA11DD414403F082A600C003EAA8CC +:100DD000EA6AEA20DD9E84013C0FFB64DD9E84010B +:100DE0003C0FFB6FDD9E84013C0FFB6BDD9E84019D +:100DF0003C0FFB77DD9E3A6F98BCFA12DD4184010F +:100E00003C0FFB6CEA20DD9E84013C0FFB68DD9EFD +:100E10003A6F98BCFA13DD41EA20DD9E3A6F98BC28 +:100E2000FA14DD4184013C0FFB5EEA20DD9E3A6F3F +:100E30009ABCEFF43C0DFB7DC81EEB9EC01CDD424E +:100E40002E17EE965CF080A0C80BE915441358905D +:100E50004423806844300C808402EA62D50CE90B9C +:100E60002E07EE93C8038401D5045A0801058402B5 +:100E70003E07EE934900178F3C0DFB7D8C013C0F24 +:100E8000FB7DEA5A8C013C0FFB712E17EE9AEA5A51 +:100E9000E220E805EA5A96003E07EE9AEA5AEA5E30 +:100EA0009600EBE8EB354900147B000F8006EA5E04 +:100EB0004900148B3E07EBB7DD42C005EBF3C803D6 +:100EC0008401D508DD42C805EBF396005A00010302 +:100ED00084003E07EB9BEBFE5A08010B84003C0F9D +:100EE000FB58440124F83C0E031E490017073C6DD3 +:100EF000FB7D5A68020F3C0DFB625A08010BDD4274 +:100F0000C80880064413970044238D54EA87EA6298 +:100F1000EC0C3A6F9A84DD9E3A6F98BC84013C0FCA +:100F2000FB693E07EEDC4403F07EA6405A10010F39 +:100F3000A6405A10020CA6405A100309A6405A10A7 +:100F40000406A6405A101003A60084418420806243 +:100F500080824400B101EAB84900335DEA20DD9E99 +:100F600084013C0FFB82DD9E84013C0FFB75440332 +:100F7000F064A640964CC910A64058108001AE40BF +:100F8000DD40A6008E02E602E90E3A6F98BCEA3B0D +:100F9000EA6AEA20D508A640964CC105A640EAD9DF +:100FA000AE40DD9EDD9E3A6F98BCFA15DD418401AE +:100FB0003C0FFB76EA20DD9E3A6F98BCFA16DD41C5 +:100FC00084013C0FFB73EA20DD9E3A6F98BCFA1750 +:100FD000DD41FA04DD4A84013C0FFB59490019C484 +:100FE0005A08A104EA3BEA6A8403EA98EA20DD9EF3 +:100FF0003BFFFEBC84013C0FFB7CEB7D44138D4624 +:101000008C01EB68A6088C01AE0849000F2DEBFEA1 +:10101000C815DD42C005EBF396005A000107DD421A +:10102000C806EBF3C80484013E07EB9B84003C0F29 +:10103000FB58440061A83C0E031E4900121FDD420C +:10104000C021DD555A08201F2E07EE935A08020CC6 +:10105000EB7D5A080114EB16442019004402988CC9 +:10106000DD48D50C5A08030B845F4452988C80628B +:101070004402B18C3A228C24D8FE84018420490099 +:101080001B59DD42C8034900168D3BFFFE84DD9EDF +:101090003A6F98BCFA18DD414403F00AA600DD411E +:1010A0004403F00DA600DD41EBAAA600DD41440398 +:1010B000F00FA600DD414403F01AA600DD41440311 +:1010C000F01BA600DD414403F082A600DD4144038D +:1010D000F353A600DD414403F369A600DD41440358 +:1010E000F386A600DD414403F387A600DD414403F7 +:1010F000F3CFA600DD414403F40CA600DD418401DA +:101100003C0FFB6DEA3BEA6AEA20DD9E84013C0F5E +:10111000FB63DD9E4403F403A60096005A08010415 +:101120003C0FFB60DD9E84013C0FFB62DD9EFC20DA +:1011300084013C0FFB6284003C0FFB713C0FFB61A0 +:10114000DD40A6419E8BE642E9055A1006045A1876 +:101150000D52DD54A6485A18014EEA342E07EBF71B +:10116000C80C2E07EB9DC809EBFA3C0DFFF9D00522 +:101170004402C4B849006BB8DD40A6015A0003041C +:101180005A080D19EB32C8162E07EBF7C8132E07B5 +:10119000EB9DC810DD4BA600C805802044238D417F +:1011A000D5079E43E622E80644238D41A650490018 +:1011B000712DEA97C0048E04E602E80784203C0DF6 +:1011C000FB3B80418061D514DD42C0043C64082EA5 +:1011D000D5033C64086EDD42C0043C24082FD503CF +:1011E0003C24086F3C0DFB3B96719691846149004D +:1011F0007226DD42C003490011A4DD52A6095A003F +:101200000D079E82E642E9035A080726A6885A2857 +:1012100001232E67EB8A97B0CE3ADD59A6005A0813 +:101220000137DD4CA7C097F85A780132800180263B +:10123000EADBDD568007EA26DD59AF80DD4CAF8062 +:10124000840AEA3E8404DD4A2E07E920DD4A80074D +:10125000EA70D51D5A08041C2E67EEA3CE18DD5B7C +:10126000A6485A100215DD4AEB0804000008962F24 +:10127000DD4ADD408026EADBDD568401EA26DD59C1 +:10128000AF80DD4CAF8084013E07EEA3EA925A089E +:101290000104490016D0FCA0FC20EB083C5DFFF3E4 +:1012A000D0043C5DFFF4D80CEB01C80ADD59A60060 +:1012B0009600C806DD5BA6885A280103AE082E07F3 +:1012C000EBA9C023EB48EACFD8202E67EB8A840035 +:1012D00097B03E07EBA9CE19DD59A6005A080116B2 +:1012E000DD4CA7C097F85A7801118026DD40EADB73 +:1012F000DD568405DD4A8007EA26DD59AF802E07DA +:10130000EBDCC803DD5BAE08FCA03A6F9EBC490075 +:101310000986DD42C80A2E07EC075A080104480076 +:1013200000CC84013E07EC0744138D45A6088C01D0 +:10133000AE08EB9EC0178401DD4ADD4280C0C007C5 +:1013400049000AA284004900158CD50C4412C478C7 +:10135000804184648402DD4480064900158249008E +:10136000092BDD42C02C3C53F7A03C03F79FD00E65 +:101370002E07EF3C8C0196003E07EF3C2E07EF3C1A +:1013800050007F909600DD41D50484003E07EF3C7D +:101390003C03F6A0C8083C03F6A1C8052E07EF3CA5 +:1013A000E605E90D84013C0BF7A284003E07EF3C03 +:1013B0004412C734840280418060DD44EB9EC00942 +:1013C00084013C0FFB723E07EB8D49FFFEB2D5094D +:1013D00084023E07EB8D49FFFF61DD59A600F8B698 +:1013E000840184C03C0FFB793C6FFB7D3E67EC07BA +:1013F0004900093C3C03F7A25A0801263C6BF7A2BE +:101400002E07EF425A00FF082E07EF428C0196008C +:101410003E07EF423C03F6A04412FE6A9600AE0877 +:101420003C03F6A14412FE6B9600AE088441840092 +:101430003C0BF6A0FA313C0BF6A180624400D1B01F +:101440008082EAB8DD465A080238EB9EC035DD409E +:10145000A6015A08032E3C6DFB225A68022ADD427F +:10146000C02B3E67EB8CEB1C4402E7C8EAA3EA7C86 +:10147000EAA3EA7CEAA3EA7C3B0044003B00C420E8 +:101480008406EB6F4400007DEB728401EAFCEBE61E +:10149000EA979E41E622E9035A08040F4900469361 +:1014A00049009BC8C0098400EA2AEAD2D505DD427A +:1014B000C0038400EB543A6F9E84DD9EDD9E3A6F3C +:1014C00098BCFA19DD4184013C0FFB814900612A77 +:1014D000EAA5C80449006BC3D503490060EEEA20C1 +:1014E000DD9E84013C0FFB74DD9E84013C0FFB5F9D +:1014F000DD9E3A6F98BC8403DD4A8401EA70EA20DD +:10150000DD9EDD9E3A6F98BC8401F806EA20DD9EE0 +:101510003A6F98BC840049001054EA20DD9E3A6F6F +:1015200098BCFA1BDD418400842A490034F5DD4271 +:10153000C003EAA8EA6AEA20DD9E3A6F9EBC440333 +:10154000F41CA600E6024EF200AE49001003DD4294 +:10155000C012DD40A6015A08030F2E07EBA3C00BF3 +:1015600084004412DFD43E07EBA380418402443060 +:101570000320EA62DD42C01CEBA2A6C096D85A380E +:101580000118842084C044002330804180833C6B58 +:10159000F6A03E37EF43EAB896013C0BF7A02E07C2 +:1015A000EF435A000203F80D3C6BF7A0F80ADD4246 +:1015B00080C04E030078EBA2A7C097F85A700104D0 +:1015C000480000714400BB908026FD1380873E7761 +:1015D000EF43EAB83E07EF482E07EF435A08020BE5 +:1015E0003E67EF4C3E67EF4D3E67EF4E3C6BF79F1B +:1015F000D51A8026FD1380874400AB00EAB83E0769 +:10160000EF498026FD1380874400AB01EAB83E070E +:10161000EF4A802644002330FD138087EAB8960104 +:101620003C0BF79F84003E07EF434412C72E840211 +:1016300080418060DD443C03F6A1C8342E07EF48AA +:10164000C80A2E07EF49960EC8062E07EF4A9602E3 +:101650004E04002984013C0BF6A12E07EF48C00779 +:101660004400009DDD412E07EF48DD412E07EF4984 +:10167000960EC0074400009EDD412E07EF49DD4174 +:101680002E07EF4A96024E0400084400009FDD41F9 +:101690002E07EF4ADD4184024412C532804180604A +:1016A000DD442E07EBD9C0068401EB7184003E07B0 +:1016B000EBD93A6F9E84DD9E3A6F98BC4413F7EEE7 +:1016C000A60896009684C203EAA6AE088400F857DE +:1016D000EA20DD9E3BFFFEBC84013C0FFB784413F7 +:1016E000F7EFA60896009684C203EAA6AE08840126 +:1016F000F846F829EBFE5A08010C3C0DFB53C006D6 +:1017000084024900098F3C0FFB53490012F72E0752 +:10171000EE9DC0048E013E07EE9D3BFFFE84DD9EE4 +:101720003BFFFEBCDD465A08020584013C0FFB70FE +:101730004413F7C9A60896009684C203EAA6AE0829 +:101740008400F81D49000CF3DD42C80BEA7EA600B8 +:10175000C008DD40EBC6EAC9EBCA848149001E5FC0 +:101760003BFFFE84DD9E3A6F98BC4413F7CAA6087F +:1017700096009684C203EAA6AE088401490008DBFD +:10178000EA20DD9E3BFFFEBC2E07EC08C81DB4011D +:10179000A6003C0FFBD5640264024412FFF03C0F2C +:1017A000FBD4B6013C1DFBD54402FFF4B620460134 +:1017B0001223500003444412FFF8B6012E07EC0830 +:1017C0008C013E07EC08FA1ADD41EAA8EA6A3BFF01 +:1017D000FE84DD9EFC6384003C0FFB4B49003B9183 +:1017E0005A00081749003C102E07EF58441000A07B +:1017F0008C013E07EF588403DD47840DDD4A490024 +:101800003C42840EDD4A8403441000A1DD47B1C38D +:101810004492E93E44A0012CDD424E0200753C1C7E +:101820000323442397EC40110420A448440397D891 +:10183000964BAC403C0C0324441397DA4001002043 +:10184000A4009603AC08F85F49003C575A0003CC4B +:101850005A080207840444100060DD47D5C65A00C8 +:1018600013DDF865F869DD4CA78097B0CED62EB7AA +:10187000EC035AB801D38403EBB2DD47DD5A3E676F +:10188000EF3A5A080206490041DF3EB7EBA3490090 +:101890003D58DD555A081209EA718420EA9E5A081B +:1018A00001048400F82BDD555A080407490043CF92 +:1018B000F8AFF823D5255A081405F8B3F81ED5203B +:1018C0005A081906840080204900173449003D87D2 +:1018D000490044C55A08020448FFFF88DD555A08EC +:1018E0000507490043B3F8F2F808D50A5A08150964 +:1018F0008403441000A9DD47EAE8EA4CEA5C4900A9 +:101900004382F9488403441000A2DD474900471D83 +:1019100080C08401EBFD5A08010448FFFF9D5A680E +:10192000030448FFFF615A681303F9348403441029 +:1019300000A3DD47EB198403441000A4DD47DD4C10 +:10194000A600C807DD40A6415A180D048423AE4105 +:10195000440000A3EBDD2E07EBC64E0301012E175A +:10196000EBA2440297E84900204FF081EBB28403D8 +:10197000DD473C6DFB47800649003FC05A680613AF +:101980002E07EF055A08010F2E07EF04C80BEA884F +:10199000C8092EB7EBCF4EB30006490072783EB7A8 +:1019A000EF052E07EF06C82EEA88C02CE6C2E82A0B +:1019B0003C0C03275A000705EA4F5A0809248404FF +:1019C000EACE800649003D68EA884E6300E6EA9563 +:1019D000EBDBEA885CF00030E9152E100C84840102 +:1019E000EBA3C90684273C1E0327F805D50B840703 +:1019F000EA6584003E000C84EBF6EBDB83FF840594 +:101A0000EACE80064900415EDD555A081409840378 +:101A1000441000A6DD47F85E4800009F5A68040D98 +:101A20008403441000A7DD4784003C0FFB544900A9 +:101A30003D1DEACED5545A68050EEB155A080350E1 +:101A400049003D145A08034C8401EACE8400EA9A06 +:101A5000D546EA88C844E6C2E8368006490041987F +:101A60005A6801328006490042823C0DFB545CF00A +:101A70000BB8E8048C013C0FFB5484003E07EB9646 +:101A8000EB158E04E602DD55E90F5A00150E3C1CDD +:101A900004365A100503C90584203C1E0320D504D2 +:101AA00084223C1E03208E14E602E90BEBC1C8071A +:101AB0003C0008A4C0068E01EA9AD5033CA808A4FD +:101AC0008400EB54DD555A08150B8403441000A81C +:101AD000DD473C0DFB35EB0C49003E62F001EB1C91 +:101AE0004422E49049002134DD558E14E602E90ACF +:101AF000EA92C808EA8CC0042E07EB89C803EBE021 +:101B0000C005EAAAC803EB37C027EB159E42E623BF +:101B1000E80A84223C1FFB225A08031F8401EB546D +:101B20008401D50F5A0805078400EA9A84013E070C +:101B3000EB893C1008A4C9108401EA903E10114EB4 +:101B4000AC3814938002149380014402E4083A13E1 +:101B50008C004900103B84013E07EBC62E07EBEAE0 +:101B60005A080512DD59A6005A08010EEA965A08CD +:101B7000090B2E17ECD42E27EBE42E07EBEA4900D5 +:101B80000D7CF8082E07EBEA5A000603F8038400E0 +:101B9000EAF848FFFE43EA85EBDB48FFFF1C3C0FF9 +:101BA000FBEADD9E3C0FFBE9DD9E4402B7F43C0FEF +:101BB000FBD9DD9EFC4180E18123CC09B400C20940 +:101BC0000260001F0220001E97B3D50CA001CA05B9 +:101BD000A580A48197B3D5060260003102200030B1 +:101BE00097B38026969380074900497800148000B7 +:101BF0005A10FF058C2188019201EA83803FB08151 +:101C0000490049D3B41F38138111F00138238111E1 +:101C10008402EABE42030873EA8FFCC1FC60B48010 +:101C2000C311C4079F64E6A2E90484A01050007D9C +:101C30002E57EBCA2E67EB8E5C5280015CA300012D +:101C4000D503814380A34E4202848E84E6824EF304 +:101C5000028080C0A60C8123816280E14E03008552 +:101C60004E530083EB5FC328A0D13C5DFB3CA4989E +:101C7000A5190201803102318030EBEA9693972357 +:101C8000960396DBE807EBED5A58010550108510D6 +:101C9000F81100538008CD048A44EBC3D5055A5887 +:101CA00031088A03EB1EE9048401EBA5F803501008 +:101CB00082884800025A501088465033006E844093 +:101CC0008082800BEB8D3C43586C3C53588C9721A1 +:101CD0009B6540421406806041107C0AA03DA07CB8 +:101CE000FF2294019521412007F5404217F5042376 +:101CF000800A0503800B944995694E92002542089D +:101D0000942442020C7342428C69884388A0980C48 +:101D1000EB4640491400EADC4058C000882488653E +:101D2000EA48EBF5EB4DC00444F007D0D50344F08E +:101D30000BB8EB3BE20F4EF20090EB814E03008DAF +:101D40004800008A3C07F4763D37F47AFE1C4000D8 +:101D50004C1641307C0A433994244332007342428A +:101D600080694800008CA63D5A001F04480000937B +:101D70004E530091EB5F4E92002C043580013C5D88 +:101D8000FB3CA498A5190201803102318030EBEAB6 +:101D900096939723960396DBE807EBED5A580105D7 +:101DA000501085B2F81300538008CD048A44EBC369 +:101DB000D5055A58310A8A03EB1EE90684015010F2 +:101DC00080A2EBA5F8035010832A480001D25010DE +:101DD00087A45033006E84418480800BEB8D3C538C +:101DE000588B3C4358AB976988858060A03DA07CA8 +:101DF0004052140694019569412007F5EBA0042395 +:101E0000800A0503800B4111FC0A944995214E92EA +:101E100000274208902442028C7342420C69884396 +:101E200088A0980CEB4640491400EADC4058C000FA +:101E300088248865EA48EBF5EB4DC00444F00708B8 +:101E4000D50344F00AF0EB3BE20FE806EB81C8044F +:101E500044000C7FEBF502030008D5243C07F4771F +:101E60003D37F47AFE1C40004C1641307C0A433961 +:101E70009024433280734242006988B3980C8843AF +:101E800088B2EADC4048C000EB4688258864EA480E +:101E9000D510841F4E92000A1003006C2203000428 +:101EA000EBF512030018D5071003006E0203000CB7 +:101EB0001203000EA63E4E0300954EA30093EB5F67 +:101EC0004E92002BB46B3C5DFB48A498A51902010F +:101ED000801F0231801EEBEA96939723960396DBD0 +:101EE000E807EBED5A58010550108654F8130053DB +:101EF0008009CD048A44EBC3D5055A581F0A8A03CA +:101F0000EB1EE906840150108144EBA5F803501044 +:101F100083CC48000132501088465033006F844013 +:101F20008481800BEB8D806041007C0AA03F3C5394 +:101F30005808A07E3C43583A94010423800C047353 +:101F4000800D4E92002F97699B2CE2A4525780007F +:101F50009569EBA09521411007F542081024420233 +:101F60008C7342420C69944988A08843980CEB46D4 +:101F700040489400EADC88F088248867EA48EB97B8 +:101F8000EB4DC00444F007D0D50344F00C80EA7355 +:101F9000E20F4EF2009EEB814E03009B480000983A +:101FA000413007F53C07F47897699B2CFE1C3D17E0 +:101FB000F47AE2A441104636525780009569EBA0AE +:101FC0004008FC0A9521FE244202C473424244693F +:101FD000944988A0980CEB4640F994004800009082 +:101FE000A63F5A003104480000924EA30090EB5FD8 +:101FF0004E92002BB46B3C5DFB48A498A5190201DE +:10200000801F0231801EEBEA96939723960396DB9E +:10201000E807EBED5A580105501086F6F813005307 +:102020008009CD048A44EBC3D5055A581F0A8A0398 +:10203000EB1EE9068401501081E6EBA5F803501071 +:10204000846E4800009E501087A45033006F844176 +:102050008082800BEB8D3C5358393C43586B976919 +:102060008885A07F806040521406A03E94499569FF +:102070000423800CEBA00473800D4101FC0A401086 +:1020800083F54110040895214E9200264208102441 +:1020900042028C7342420C69884388A04008900039 +:1020A000E2118825EADC88F0882F8867EA48EB97F8 +:1020B000EB4DC00444F00898D50344F00C80EA735B +:1020C000E20FE806EB81C804440013FFEB9702031C +:1020D0000009D5243C07F4793D27F47AFE1C400022 +:1020E000481641207C0A432910244322807342422F +:1020F000006988B240089000E21188258843EADC34 +:1021000088F0882F8867EA48D518841F4E920012FD +:102110001003006D22030005EB9712030019020360 +:1021200000083C0BF7B0020300093C0BF7B1D52CBB +:102130001003006F0203000D1203000F0203000CD6 +:102140003C0BF7AE0203000D3C0BF7AFD51D843FEF +:10215000C3061010006C1010006DD5161010006E24 +:102160001010006FD5115033006C48FFFDAA50339A +:10217000006C48FFFE325033006D48FFFED25033F2 +:10218000006D48FFFF66FCE0FC203C6DFBE984E14C +:10219000A772A7B3C20284FFC9089E69FF444251D7 +:1021A0000473B6A388A7D50B9E71FE8C80204211C4 +:1021B0001473884742011473B62380A0B6A4FCA010 +:1021C000FC6384C081A08141F281818380E48165C8 +:1021D00081038126E2E8E9128008F112F201B0C21F +:1021E000B10349FFFFD3F0028D0138068111892028 +:1021F000F0033806811188C0D5EE8AEC8405FFFB18 +:1022000042638073844142230800800A8029490088 +:102210004665002580005A20FF068C418840400119 +:102220000409EAE0B044B085490046BFF00438151F +:102230000111F005382501118402EABE42048873B9 +:10224000EA8FFCE3FC6581213C1DFBE9F282002062 +:102250008032F28400208033F28520D08039A68A33 +:1022600020E0803AA64B508000209E09F083960A19 +:10227000F0889E12F0869612F0899E0A4472C75822 +:10228000854050C17FFFF0873C0DFBE9000000094D +:10229000E3404EF200EBB2184E0200D58E04E60287 +:1022A0004EF300D1040400045A080204480000CB95 +:1022B000B37F04048005406588088806A6C0CB2447 +:1022C000A642E622E9029EC9A703F007E080E803E0 +:1022D0008C81D502F4038440B65FEB9BF00280A8AA +:1022E000F88C04148006F204EBBC8A20FE5404240B +:1022F000800838212E028802EABE22147FF2880D5F +:102300009603E001D52DA7414C56402DA6C2E662AA +:10231000E9038E61D5028460A703F007E080E8033B +:102320008C81D502F403EB9B8400B61F501080A271 +:102330008441F00280A8F86104148006F209EBBC25 +:1023400042110073F204FE540424800838212E0246 +:102350008802EABE22147FF2880D9603E020EB7417 +:10236000D506841F1004000002047FF212047FF6D9 +:102370000404800588C0A6F2CB28A630E602E90254 +:102380009EC1A731F006E080E8038C81D502808CE5 +:10239000EB9B8401B61F501081448440F0025054DE +:1023A0000001F82B04148007F205EBBC8A20FE54D0 +:1023B0000424800838212E028802EABE22147FF30A +:1023C000880E9603E001D52EA773F003D82DA6F052 +:1023D000E662E9038E61D5028460A731F006E080F1 +:1023E000E8038C81D502808CEB9B8441B65F501052 +:1023F00081E640540800F00249FFFEE4041480071F +:102400003820AE02F10842208073F105FE8C0414DE +:102410008008EBBC8801EB9F22147FF3880E9603A3 +:10242000E020EB74D506841F1004000102047FF342 +:1024300012047FF722047FF6AC3822047FF7AC3910 +:10244000D50E2203800012047FF6220380011204BD +:102450007FF7841F10040000100400018D418CE4FC +:102460005084004C48FFFF12FCE55A00010544036C +:10247000F7DED5034403F7DD44100069AE40EA2DD2 +:102480008420AE40DD9E8401DD9EFC204473F080FC +:10249000A7B897B05433001F583180A0AEF8DD487C +:1024A000AFB8FCA0DD588E01EAD0DD9E4410005587 +:1024B000DD43AE404413F7F1A6089604C003EA2DAD +:1024C000D5FCDD9E44100055DD43AE404413F7F0CB +:1024D000A6089604C003EA2DD5FCDD9E4443F7FD13 +:1024E000A72097205A08010558020008D503540276 +:1024F00000F75A180104EA60D503540000FB5A287B +:102500000104EA91D502EB295A380104EA42D502C6 +:10251000EAA64413F7FDAE08DD9EFC2180E08400AE +:10252000EA238400802084418060506F8007F83760 +:10253000C703EA3AEA2384214403F7C0AE40442F9C +:10254000FFE74403F7C3AE8096B04403F7C6AE80FE +:1025500084404403F7C1AE8084774403F7C4AEC01F +:10256000EB7396004433F7C7AE184403F7C2AE804E +:1025700092D084434403F7C5AE8097B0EBB8AF80E8 +:102580004403F7CCAE40EA378020EA31A608960033 +:10259000C003AED0D5FC80208040806049FFFFA002 +:1025A000FCA184004412D7B0845FEB038C015A086D +:1025B00009FEDD9EFC2084204432D7B04442FE5DFB +:1025C0004452FE5C44638D4144738D403801840065 +:1025D00096885A00FF20E649E81D44F023E8382792 +:1025E000880040F13C00DD0F0A12161A1E2A2A222A +:1025F00026003C2DFB37AE10D50DAE38D50BAE30D6 +:10260000D509AE28D507AE20D505EB58D5033E0732 +:10261000E9398C215A1809DCFCA04403F7C0A64014 +:102620004402ED1CAE404413F7C3A648AE43441326 +:10263000F7C6A648AE464413F7C1A648AE414413B8 +:10264000F7C4A648AE444413F7C7A648AE474413A0 +:10265000F7C2A648AE424413F7C5A648AE45441398 +:10266000F7C8A648EBD1DD9EFC00EA694402ED1CE8 +:10267000A6804413F7C0AE88A6834413F7C3AE8880 +:10268000A6864413F7C6AE88A6814413F7C1AE8868 +:10269000A6844413F7C4AE88A6874413F7C7AE8850 +:1026A000A6824413F7C2AE88A6854413F7C5AE8848 +:1026B00000100008EBB8AE40FC80FC4081405400A4 +:1026C000807F80C180E281235A087F05440000C8D2 +:1026D000DD41EA695AA8010A8400F9B4EB85842037 +:1026E000AE404403F7CBD5034403F7CC542480FF1A +:1026F0004413F7C0AE8896B04413F7C3AE8896B8BB +:102700004413F7C6AE884014A00996484423F7C185 +:10271000AE504013200996484423F7C4AE504013EE +:10272000A00996484423F7C7AE504014C009964804 +:102730004423F7C292D0AE5097B04413F7C592F03D +:10274000AF8897F84413F7C8AFC88421AE40EA3782 +:10275000EA31A640C103AED0D5FD5AA80108800ACF +:10276000F971441FFFAAEB85AE408401FCC0FC0058 +:102770004403F02CA7804413F3EC8401AE08844793 +:102780004413F3EDAE884413F3EEAE084413F3EFB5 +:10279000AE084423F3F08420AE5084644423F3F164 +:1027A000AED04423F3F28462AED04423F3F3AE50B0 +:1027B00097B04413F3F4AE089674C945541300025D +:1027C00096484423F439C1063E07EFAF8403AE10A8 +:1027D000D5043E37EFAFAE50EA6997968401F8D63C +:1027E00097B08400F8D3C60584013E07E944D503B9 +:1027F0003E67E944DD585A0802074413F02DA60845 +:10280000EA42AE084401D80044128E10442025A0AC +:1028100049FFFE3D441FFF86EB1FAE408420EA6760 +:10282000AE40441000404403F6CAAE40FA214403CF +:10283000F697AE40FA2F4403F384AE40842144035C +:10284000F380AE40DD585A00011E4605555A441229 +:10285000C12C50000AAA3C0FFA4F804184028464C4 +:10286000DD44DD43DD45AE404605A5AA500005A583 +:102870003C5DFA50D8FE46012345500006783C0FD7 +:10288000FA50FC80FC0049FFFE8EDD4C4412D7B0AC +:10289000A600AE08DD4BA600AE09EBAEA600AE0A60 +:1028A0004402FE5CA600AE0B4402FE5DA600AE0C28 +:1028B000EBE0AE0FEB3410008008804184698402A5 +:1028C000DD44FC80FC20440000C6DD414403F7C029 +:1028D000A600DD414403F7C1A600DD414403F7C271 +:1028E000A600DD414403F7C3A600DD414403F7C45D +:1028F000A600DD414403F7C5A600DD414403F7C649 +:10290000A600DD414403F7C7A600DD41EBB8A600F1 +:10291000DD414462FE504472FE5608030001DD4171 +:102920004C63FFFDEBA2A600DD41440000C7DD4182 +:10293000FCA0FC004423F7F0C80380A2D503445355 +:10294000F7F1A6689648DA17540080029780C60906 +:10295000440000C3DD41F8178400F8188400FC80AF +:102960009656C118440000C4DD41F80D8006F80EEB +:102970008006FC80546080FEC60D440000C5DD4129 +:102980008006DD4149FFFFA0840149FFFD708400FE +:10299000FC808401FC80FC40814080E180C2812376 +:1029A000EA695405007F5A08010A8400F84B842024 +:1029B000EB85AE404413F7CBD5034413F7CC542436 +:1029C00080FF4403F7C0AE8096B84403F7C3AE80DF +:1029D00096B04403F7C6AE804004A0099600442395 +:1029E000F7C1AE104003A00996004423F7C4AE100F +:1029F000EB7396004423F7C74034C009AE1096D855 +:102A00004403F7C292F0AEC097F84403F7C592D0E2 +:102A1000AFC097B0EBB8AF808401AE088401FCC0B2 +:102A20005A0001054413F7CCD5034413F7CB4433C4 +:102A3000F04AEB78A688C203AF18D5FD5A08010BFF +:102A4000FC0049FFFD6C441FFFAAEB85AE408402E9 +:102A5000FC808402DD9EFC41DD5884C15A000104E3 +:102A60004800008B4413F7F1EA37EA31A6089604D0 +:102A7000C003AED0D5FC3C6DFB304413F1289CB4B0 +:102A800084638402DD444413F118502300088463F6 +:102A90008402DD444413F10050230018846484024E +:102AA000DD444413F12C5023001084638402DD4480 +:102AB0004413F1305023001484638402DD44441332 +:102AC000F1045023001C84648402DD448401441317 +:102AD000F30EEAAE8060DD44001F8007440FFF80E4 +:102AE000FE0FEA234413F30EEAAE84618402DD4450 +:102AF000440FFFAEEA23EAACEAAE84618402DD440F +:102B00008401EA234413F10D8402EAAE8461DD44BA +:102B1000DD43DD45AE404605555A50000AAA3C5DEE +:102B2000FA4FD8FE46012345500006783C0FFA4F75 +:102B3000EA6EEA74840AEA328401EA534413F133F8 +:102B4000EAAE8060DD44006F800754030004C0F3E8 +:102B5000978FC606440000C2DD4184C1D50D4605ED +:102B6000A5AA500005A54412C1303C0FFA5080417F +:102B700084028464DD448006FCC1DD585A000105EE +:102B800044024A00DD9E44020A00DD9EFC405A00D9 +:102B90000203F818840880C1DD4A4403F31CA60030 +:102BA000C0064413F33FA608EAEBAE084403F369FA +:102BB000A6009604C009FA22EA67AE408420EB1F03 +:102BC000AE40480000E52E97EFAF2E77EFAE5A905B +:102BD000010448000080CF1E8009DD4A4413F374CD +:102BE000A60858000003AE08C61284053E97EFAE53 +:102BF000DD4A2E07EFAD80478C013E07EFAD840222 +:102C000080208069808780A7DD57D504440008981C +:102C1000EA3284003E07EFAECE1D4463F36A8402BD +:102C2000DD4AA630EB29EA60AE30440001C2EA3248 +:102C3000EA21FA00AE08804184618402DD44840305 +:102C4000DD4AA6304413F369EA42AE30EA37EA318E +:102C5000D51E8400F809844080A280628483842287 +:102C60008401DD5784014900596DEAA7FA038026E3 +:102C70008046AE3084618402DD448401EAD7EA40B4 +:102C8000EA28A6305A0014CBAE88D5FCA6089604D4 +:102C9000C803AED0D5FC8404DD4A4422FEF04433A0 +:102CA000F04AEB78A610EA215A001104AF18D5FBC0 +:102CB000FA02AE088440EB1FAE808402804180603F +:102CC000DD448405DD4A2E07EFAC8C013E07EFACF6 +:102CD000D55ECF0EC60D84013E07EFAE8405DD4AFA +:102CE0008402802780478067848380A7DD57840023 +:102CF0003E07EFAEC61E4472FEF04493F04A44A075 +:102D00000055A638EAA75A00130C8440840110A489 +:102D1000800080208062848380A2DD57D5F3840107 +:102D2000EAD7FA04AE308026840280468461DD440E +:102D3000EA21EA37EA31A6085A001004AED0D5FCE1 +:102D40008403DD4A4413F36AA608EA37EA42AE0870 +:102D5000EA314413F369A6089604C803AED0D5FC43 +:102D60008404DD4AEAA7FA01AE3080268046840258 +:102D70008461DD44EA40EA28A6305A001204AE8895 +:102D8000D5FC2E07EFAC8C013E07EFACFCC0442312 +:102D9000F02BA6502E37EFAF96485A380109C004E1 +:102DA00058008008D50A540080F7D507C0045800A1 +:102DB0008010D503540080EFAE10DD9E4403F02A4E +:102DC000A600EBE496005A180104EA57DD9EEAD605 +:102DD000DD9EC807FC008401EA638405DD4AFC80AF +:102DE000DD9EFC00EAA55A0801094403F7F0A6009D +:102DF000560000019604FC808400FC80DD59A6008A +:102E00009600C004EABD5E000001DD9EFC40978094 +:102E10008402DD4A8006DD4A4412FEF28401AE08D7 +:102E20004402FEF3AF80840280418060DD44EA9377 +:102E3000EABC4492FEF649FFFFC35A00010B84042A +:102E4000441000F2DD47EB19AFF0EABA5A08ECF58E +:102E50008403DD4A84004412FEF2AE084412FEF3FD +:102E6000AE08FCC0FC403C6DFB7E97B0DD465A00CE +:102E70000207DD40A6015A000903F8D3EB48EA68CF +:102E8000D003EA8ED8292E57F010D6042E57F01111 +:102E9000DE0CDD585A0001078408EA2C2E0011636D +:102EA000EA814472C800F8BD2E07F014E2C0E9FAC6 +:102EB000EBE45A1801F88429EB2D2E1011603E170F +:102EC000EEA04C6000052E57F015DEEC840AEA3EB9 +:102ED0004472C800F8A63C0DFFFBD0043C0DFFFC7B +:102EE000D8272E07F000E2C0E90FDD585A00010391 +:102EF000F8158409EA2C840AEA3E2E00116DEA6C6A +:102F00004472C7E8F88E2E57EFF8D6052E57EFF922 +:102F10004C5340E8DD585A080104480000E3840897 +:102F2000EA2C2E001163EA814472C7E8F87A3C0C5F +:102F30000004D0043C0C0005D8532E57EFE2DE0D00 +:102F4000DD585A080103F8408408EA2C2E0011626B +:102F5000EA814472C7D0F8652E57EFEDD6162E578A +:102F6000EFEFD6132E57EFF1D6102E57EFF3D60D05 +:102F70002E57EFEED60A2E57EFF0D6072E57EFF268 +:102F8000D6042E57EFF4DE0DDD585A080103F81C65 +:102F90008408EA2C2E001164EA814472C7D0F841FB +:102FA0002E57EFE8D60E2E57EFE9D60B2E57EFEA45 +:102FB000D6082E57EFEBD6052E57EFEC4C53409525 +:102FC000DD585A000104480000908409EA2C840A64 +:102FD000EA3E2E00116DEA6C4472C7D0F822EBBBBA +:102FE000D0043C0C0003D84B2E57EFCFDE0CDD583D +:102FF0005A000103F80E8409EA2C2E001160EA6CD5 +:10300000EB4AF80F2E57EFCADE0EDD585A080104BE +:103010004800006E8408EA2C2E001162EA81EB4A17 +:103020004800006A2E57EFCCDE08DD585A080160D0 +:10303000840AEA3EEB4AD55F2E57EFD5D6162E57B7 +:10304000EFD7D6132E57EFD9D6102E57EFDBD60D6C +:103050002E57EFD6D60A2E57EFD8D6072E57EFDACF +:10306000D6042E57EFDCDE43DD585A0001418408B8 +:10307000EA2C2E001164EA81EB4AD53D3C0DFFF5A8 +:103080004C02C00E2E27EFAF84292E001161EB2DCC +:103090005A280104EA6CD52FEA81D52DEAEE4C02BC +:1030A000C0132E57EFB0D6042E57EFB1DE22DD58F5 +:1030B0005A0001208408EA2C2E001163EA81447230 +:1030C000C7A0D519EACF4C02C017DD585A08011421 +:1030D0008409EA2C2E001160EA6C840AEA3ED50BC2 +:1030E0004472C7E8D5084472C7D0D505EB4AD5036A +:1030F0004472C7A044A3F01DEAABEAECDD5A5A08BB +:103100000215DD465A080212A77A9E319600DE06A5 +:103110005894800110950000D50800538013D805FD +:10312000549480FE10950000FCC0FC003C6DFB7EBA +:103130003C0DFB465A0009083C0DFB465A000804AA +:103140004800019BDD465A000208DD40A6015A00F6 +:1031500009044800016D3C1DFB323C2DFFF39770C4 +:10316000DD584C1100063C2DFFF44C1140132E1776 +:10317000F0164C12809F2E17F0174C12809B2E27B2 +:10318000F0104C5101252E17F0114E120146F81681 +:103190003C2DFFFB4C1100063C2DFFFC4C11401157 +:1031A0002E17F000E2A14EF200852E27EFF84C51C9 +:1031B000010F2E17EFF94C12C130480001093C2CC9 +:1031C00000044C1100063C2C00054C1140672E17E2 +:1031D000EFE24C12C0125A080103F898EA354E1774 +:1031E00000048E21EAB4EA354E13011784463C2FC1 +:1031F000FB47EAF0F8A12E27EFEDD20D2E17EFEFE7 +:103200004C12800A2E17EFF14C1280062E17EFF3A6 +:103210004C12C01F5A080103F879EA354E17000412 +:103220008E21EAB4EA354E1300F8EAFEEAF04C517A +:10323000007B2E17EFEF4C12807E2E17EFF14C1211 +:1032400080822E17EFF34C12C0E8480000832E173F +:10325000EFEE4C1280922E17EFF04C12808E2E174C +:10326000EFF24C12808A2E17EFF44C1280862E1744 +:10327000EFE84C12801F2E17EFE94C12801B2E171F +:10328000EFEA4C1280172E17EFEB4C1280132E171B +:10329000EFEC4C12C0C2D50D3C2C00024C110006C4 +:1032A0003C2C00034C1140772E17EFCF4C12C00777 +:1032B0005A000103F841480000A62E17EFCA4C122D +:1032C000C0155A080103F822EA354E1700048E2172 +:1032D000EAB4EA354E1300A184463C2FFB478441F3 +:1032E0003E27EF05EAF0F8282E27EFD5D20D2E174E +:1032F000EFD74C12800A2E17EFD94C1280062E17EA +:10330000EFDB4C12C02A5A08010448000088EA3555 +:103310004E1700048E21EAB4EA354E13007EEAFE11 +:10332000EAF0DA04842BEB3EF8072E17EFD74C12A5 +:10333000C006842CEB3E480000702E17EFD94C12CB +:10334000C005842DEB3ED5682E17EFDB4C12C0650F +:10335000842EEB3ED5612E17EFD64C12800E2E1721 +:10336000EFD84C12800A2E17EFDA4C1280062E1777 +:10337000EFDC4C12C0525A000152EA354E170004DD +:103380008E21EAB4EA35C94884413C2FFB47EAF074 +:10339000D5433C2DFFF54C1140105A080108EABDF9 +:1033A0004E07003D8E01EA6CD539EA354E170035DF +:1033B0008E21EAB4D5313C2C000B4C20C01B2E27AB +:1033C000EFB0D2052E17EFB14C12C0275A000127DB +:1033D000EA354E1700048E21EAB4EA35C91DDA0435 +:1033E0008424EAFED5038425EAFE8420EAF0D5147D +:1033F0003C5C000AD9115A0801104403F403A600EA +:10340000C80DEABD4E0700048E01EA6CEABDC8068D +:103410008407EA3ED5035A080105EABDC82DD50444 +:103420002E0FEE9FC829840BEA2CD526DD465A00C4 +:103430000224EB48EACFD820DD585A08010EEABD35 +:103440004E0700048E01EA6CEABDC8168407EA3E06 +:103450008404DD4AD5118402DD4A2E0FEE9E4E070C +:1034600000058E013E07EE9E2E0FEE9EC8058407D6 +:10347000EA3E8403DD4AFC80FC00EB7D96005A089E +:103480000103F8062E57EFD5D8058400EAA24800BC +:1034900000572E57EFD6D80D8401EAA2DD585A0006 +:1034A000014F4412E6C8EB12EA878402DD44D54797 +:1034B0002E57EFD7D8048402EAA2D5412E57EFD871 +:1034C000D80D8403EAA2DD585A00013A4412E748B5 +:1034D000EB12EA878402DD44D5322E57EFD9D804A7 +:1034E0008404EAA2D52C2E57EFDAD80D8405EAA27F +:1034F000DD585A0001254412E7C8EB12EA8784021E +:10350000DD44D51D2E57EFDBD80C8406EAA2DD582A +:103510005A000116EBF18041FA788402DD44D50FA0 +:103520002E57EFDCD80C8407EAA2DD585A000108B8 +:1035300084024412E848EB12EA87DD44FC8044032D +:103540009680A600961F8E01E6013EF7EBFEDD9EFB +:10355000FC202E07EBFE97805A68013144139681B8 +:1035600044039680A600A68844139682A64840701D +:1035700010094010A00840108A0444239683A690A6 +:10358000FE5744239684A6D096D85A7001075A78DD +:10359000020BF8038006D508800744239690DD448B +:1035A0008007D5028403842044239680AE504423B0 +:1035B000968FAE103E17EBFEFCA08401FCA02E07F8 +:1035C000EC09C005FC008403DD4AFC80DD9EFC00A4 +:1035D000C80284263E17EBEA49005498FC80FC039D +:1035E000B61FF181F282F383B45F4412A50AEA2286 +:1035F0008402F484F585DD44F2014412A69AF83879 +:10360000F2024412A82AF834F2034412A9BAF8309C +:10361000F20444129ECAF82CF2054412A05AF8286B +:10362000F20A4412A1EAF824F20B4412A37AF82019 +:10363000F20C4412988AF81CF20D44129A1AF818E7 +:10364000F20E44129BAAF814F20F44129D3AF8109D +:10365000F2104412AB4AF80CF2114412ABAEF80867 +:10366000F2124412AC12F8044412AC76F213EA22BD +:103670008402DD44FC832E27EFAF5A280104480062 +:10368000008DFC4580E08121840480273C6DFB7E19 +:10369000DD475A7005075A78060448000066F804AA +:1036A000EA965A00090448000077EBA2A6008E02B1 +:1036B000E6064EF20071E724E916E730E83F44439E +:1036C0007A28F831EAC644137578F486F487F488CA +:1036D000F489B65FF381F082F183F284F385FD20F3 +:1036E000F82BD52C44038388B61F44038518F0813A +:1036F000EB80F08244037BB8F08344037D48F08480 +:1037000044037ED8F085440386A8F08644038838B5 +:10371000F087440389C8F08844038B58F089441328 +:103720007578EAC6442377084433789883FF444386 +:103730008068445381F849FFFF54EB1CF823EBF1F8 +:103740008041FA78F821441397DC80418464F81CA6 +:103750008404441000CEDD4749000458840444101A +:1037600000CFDD47D5189630661000088E26E62279 +:10377000E90850107FF6E622E9048E12E602E80B13 +:10378000EB1C8041EA878402DD44EBF18402804136 +:10379000FA78DD448401FCC58401DD9EFC0084854B +:1037A0008E014050109684C68CA138509602FF348A +:1037B0004042900D972FAF10041080114000800DF3 +:1037C0009604AE18FC8004108012FA58FE14EA9990 +:1037D00040100440EA9D882004008009EA46DD9EEE +:1037E00004108012FA58FE14EA9940100440EA9D31 +:1037F0008820040080089600DD9E9200FC608160B5 +:1038000004000008858185C081215480003F81AC7F +:1038100080CC80EE50A58004879FE3064EF300AF76 +:103820009E319600802A49005DAF8E015CF0002336 +:103830004EF200A144F036443827810140F13C00AB +:103840004A003C006C002E012E012E012E012E019B +:103850002E019600280164004C00E800F000F800FA +:10386000000108011001180120014600C000C80035 +:10387000D000D800E0002E012E012E012E012E01D5 +:10388000460046004600460046008CE197F8D57297 +:103890009AB74EE300081024800011C4800185C14E +:1038A000D56910248001D5669A3710048002D5624C +:1038B000EA684CB0400D9AB75AD80106102480042B +:1038C00085A0D5581024800585A0D554EBBB4CB0FD +:1038D00040529A3710048004D54DEA684CB0400D30 +:1038E0009AB75AC80106102480068580D543102453 +:1038F00080078580D53FEBBB4CB0403D9A37100424 +:103900008007D5389A3710048008D5349A371004C8 +:103910008009D5309A371004800AD52C9A371004C4 +:10392000800BD5289A371004800CD5249A371004C0 +:10393000800DD5209A371004800ED51C9A371004BC +:10394000800FD5189A3710048010D5149A371004B8 +:103950008011D5109A3710048012D50C9A371004B4 +:103960008013D5089A3710048014D5049A371004B0 +:1039700080038CC197B048FFFF52FCE0FC61F081EE +:10398000F1018400F8323E00115884003E07EE99A0 +:1039900084C04492E9489DF1F1019638F8262E172B +:1039A000EE9988C9AE3188013E07EE9980C75A78F2 +:1039B00008F4F1018409F8193E001161F101840A4B +:1039C000F8143E001162F101840BF80F3E00116300 +:1039D000F101840CF80A3E001164F101840DF80530 +:1039E0003E001165F101FA0549FFFEFC3C7C000236 +:1039F0003E00116D84C04493978050A3800404035B +:103A00008008962FE0C0E80B8006802A40B324008F +:103A100049005CBA8CC1EAE097B0D5F2FCE1FC0049 +:103A20004462D7BCB4064412C800F8118386B808B3 +:103A30004412C7E8F80CB8114412C7D0F808B80F00 +:103A40004412C7B8F804B8184412C7A049FFFED8FA +:103A5000FC804423F7DAA6509648C0045810802012 +:103A6000D503541080DFAE50DD9EFC408401490038 +:103A7000524D8401F8272E17EE9946008B3B8801A2 +:103A80004413F7F8B60184014413F7FCAE0844135D +:103A9000F7CDAE0884293E07EE9E8404EB2D4460EA +:103AA00000C8DD4AEA6EEA742E0FEE9E4E0700084B +:103AB0008EC1EA53840A97B1EA32CEF78405DD4A13 +:103AC000840049FFFFC8FCC0FC20DD465A080217ED +:103AD0004473F41CA7B8DD45DD43AE40840A4410AE +:103AE000009997B0DD47DD59A600C806A7B897B082 +:103AF000EA2DEB19D5F95A6802FBFCA0FC21F081F4 +:103B0000DD585A08011FF8354412FEF0A608EAA74E +:103B10005A0850FEF81644000051F825F82AA6303D +:103B20004472FEF05A0852FDF0014900704344000F +:103B30000053AE388027804784618402DD44FCA1B5 +:103B4000490022AFEAA7EA58F80E4403F04ADD45DF +:103B5000AE408006A640EAA75A1851FEF00149007F +:103B60007029EB59AE308026840280468461DD44A2 +:103B7000DD45DD43AE4083FFA6305A0853FFFCA16C +:103B8000FC20DD58EA93EABC5A080113AFF0EA21A1 +:103B9000A6085A0852FF8401EBD7DD45DD43AE404D +:103BA000DD46C0FF44100053EA67AE40FCA084012C +:103BB000EBD7AFF0DD46C0FFEA21EB59AE088041FC +:103BC00084618402DD44FCA0FC4280C0B0013A1054 +:103BD0000C2022AF8002F702049F8003DD465A00CA +:103BE000020980278049806A8402DD448401FCC286 +:103BF00000030065001300648A015A00082F0003C7 +:103C0000006500130065E608840CE80FF80812A1AF +:103C10000000F80314910002001300658046422062 +:103C2000807383FFA9D1D5118E284E00FFF912A110 +:103C30000000F803149100020013006580468E28EE +:103C40004220807383FFA9D1000300658C01960098 +:103C5000100300658401FCC28400FCC2FC0000600B +:103C60008064002080654C61002900308064844CB1 +:103C7000808142418873003080642252000080813C +:103C80004241887380C1A0E20040806442620873B0 +:103C900000208064A1318C41969010208064002027 +:103CA00080645A28080B84401020806400208065BE +:103CB0008E48969010208065AD40A901A8C2FC8076 +:103CC0003C1DFB583C1DFB5800300064844C4201F5 +:103CD0008873501087A3222000004400004B42113B +:103CE000007380013C1C031EE201E8053C0FFB58F9 +:103CF0008401DD9E8400DD9EFC023C6DFB71EBFEC9 +:103D0000C04896309E43E631E806DD54A648C90314 +:103D10005A080B0684003E07EB9BD53B2E500C7DCA +:103D20002E000C7CD824EBE497B03C0DFB535A00DA +:103D300003083C03F6288C0196013C0BF6285A68D0 +:103D4000020E5A10010C3C03F6285A0001F08400C0 +:103D50003C0BF62884003C0FFB53840084203C0B72 +:103D6000F6283C1FFB533E07EB9BD5134402E408A7 +:103D700049FFFFA8C0D9B0014412E40849FFFF7011 +:103D80008402F102F203223F8002EA623C0FFB53FD +:103D9000FC824403F7C9A640C1038420AE40DD9EE7 +:103DA000FC01DD585A000148EB48EBBBD0043C0C49 +:103DB0000003D841EA5AEA5E8C019600B081503F78 +:103DC000800549FFFCEDEA5E000F80040460800876 +:103DD00049FFFCFB001F800597AFC11CEA5AEA5E51 +:103DE0008C029600EBE8EB3549FFFCDA000F800609 +:103DF000EA5E49FFFCEAC80AEA5AE206E807EB5025 +:103E0000C80584013E07EBD9D51A84003E07EBD9DB +:103E1000D516C80AEA5AE206E8072E07EBEEC804F0 +:103E20008401EB71D50C840AEA328400EB713E0701 +:103E3000EBAED5058400EB713E07EBAEFC81EBE405 +:103E40005A1801064412C4D4F804DD9E4412C46416 +:103E50003800810150007F5BEAD083FFDD9EFC408B +:103E6000DD4580C0DD43AE40EA80A608C8FF2E379E +:103E7000EFAF44A2C464440000A5947150737FA0C6 +:103E80004492C4D45A380116882A80413805190949 +:103E90008402DD44EA69F815380499015A08A5FE40 +:103EA000F81C4412C4D43805190938009909FCC01B +:103EB000882980413804990984618402DD44EA69D3 +:103EC000DD43DD45AE4097F844038D44AFC083FF2A +:103ED000380519015A08A5FE50037FB09600441317 +:103EE0008D44AE08840083FF4412C46438009909ED +:103EF00038049909FCC0FC008400441000C1DD476F +:103F0000EA96C8038407EAF8DD5300600051840193 +:103F10008026DD475A680212EB61EA9ADD53EB44D2 +:103F200000000053C8038400D53C5A00013B5A00EE +:103F300002395A0803FAD5355A6803378402EA90E1 +:103F4000EB61EA9ADD530010005300000054968C98 +:103F50004210840BC914CA0AC8038404D5225A0823 +:103F600001048406D51E8408D51CC8038405D51910 +:103F70005A0801048407D5158409D513CA0AC80351 +:103F8000840AD50F5A080104840CD50B840ED50978 +:103F9000C803840BD5065A080104840DD502840F8A +:103FA0003C0FFB35D50E5A68040D84003E07EBCF5D +:103FB0003E07EF04DD42C8118401EA908426D50B48 +:103FC00084003E07EF0484013E07EBCFDD42C805C5 +:103FD0008401842549FFFAFDFC80FC0180C0840037 +:103FE000EA23DD42C8113E67EBBEEBE1804184610C +:103FF0008402DD448401EBE1EAAE8060DD44EA96B0 +:10400000005F8007D8F3FC81FC00DD42C00FEA9618 +:104010005A000305EA965A080AFF8403EBE1EAF81E +:10402000804184618402DD44FC80840A49FFFFD71B +:10403000FC80FC00DD42C80AEA965A08080484099C +:10404000D504EA96C8038407EAF8FC80FC00EBDF9D +:1040500084203C0FFC0C10100050EAC4EB9D1010A3 +:1040600000531010006010100061FC80FC00DD4265 +:10407000C825EA5B001080F25A180121EA28EA40BC +:10408000AE883C2DFC0C001100F2C902D500441290 +:10409000FEF3A64896485A10040C5A10030A5A1008 +:1040A00006085A100A065A1009045A180B083E1737 +:1040B000EEA2100100F2100100F38401FC802E0733 +:1040C000EEADC80FEA5B3E07EEAF002080513E0721 +:1040D000EEAE1000805184013E27EEAC3E07EEADFF +:1040E000DD9EFC005A0806048401D5045A08070620 +:1040F00084003E07EB97D51C5A080D0784003E0745 +:10410000EB978421D5075A080E0B84013E07EB97E5 +:1041100084203E17EBDA3E07EBC7D50A5A08100495 +:104120008401D5045A08110584003E07EB94FC80F5 +:10413000FC002E07EEAEC8312E07EEAC5A08100573 +:104140003C0C01DDD50A5A0811053C0C01D7D505F8 +:104150005A0812073C0C01D9441320D0EA4DEA4C0E +:10416000DD53C904441FFFA0D503441FFFA1EAC4C7 +:10417000EB38A6485A180305441FFFB1D503441F66 +:10418000FFB0EB9DDD40A6015A08040584013E07FF +:10419000EBE684013E07EEAEDD53EAAF5A08BB1AE8 +:1041A0002E07EEAFE614E8062E07EEAFE60AE91199 +:1041B000D50EDD465A0802FAEA5B840010008051F1 +:1041C000EBFB3E07EEAF3E07EEAED503DD46C0F596 +:1041D000FC80FC408120DD402E27EE9BA601E641BD +:1041E00080E13EF7EE9BEA935A08034B84084410A3 +:1041F00000B1DD47EA3BAE3044A38D4084CADD54B4 +:10420000A608C8133C2DFB225A2801FCEA305A08A4 +:1042100007F93C6FFB472E07EE9BC0F33E27EC03EC +:10422000EAAB49002071D5EC8408441000B2DD47A8 +:10423000DD42C80B2E07EE9BC8138401EA33DD4B29 +:10424000A60049002061D50CDD45DD43AE402E17A8 +:10425000EB8FEA305A0007F05A1801FDD5EC8408BC +:10426000441000B3DD47DD5A5A080206EA92C00343 +:1042700049FFFECC8408441000B4DD47D508EA3B72 +:10428000AE30DD54A608C803EA2DD5FD84084410DD +:1042900000B5DD472E07EEAC3C2DFC0C8E10E6037E +:1042A00010910053E80449FFFF45D558EA92C01128 +:1042B000000100515A08BB0FEBE184C08402804129 +:1042C00084613E67EBBEDD44DD5310600051D509CB +:1042D000CF04440FFFA0D503440FFFA110010051EC +:1042E000DD4BA640DD535A180305441FFFB1D5032B +:1042F000441FFFB0EB9DDD40A6015A080405840170 +:104300003E07EBE68408441000B6DD47EA92C80495 +:10431000EA40EA28D50D8408441000B7DD47DD42A5 +:10432000C00DEAAC840280418060DD44D507DD53D6 +:10433000EAAF5A00BBF2AE88D5FB8400EA6384087A +:10434000441000B8DD47EA92C805EA5B10008051CE +:10435000EBFB8408441000B9DD47FCC0EA5B1000A9 +:104360008060DD9EDD5300000060DD9EEA5B100092 +:1043700080613C1DFA4A1000803EDD9EFC0080C03A +:1043800049FFFEB184015A680305490055B580060E +:1043900050137FF3E622E9035A68021B8401EAE71F +:1043A000DD40A7815A6803048402D5125A680A09BD +:1043B0008429AE418420DD56DD40AF81D5038420C1 +:1043C000DD56DD465A0802F2DD528443AE89FC8098 +:1043D0004000040E9604DD9EFC02DD42C021DD5348 +:1043E000441FFFAAEAC4DD53001000515A18AA0A5C +:1043F000EAC5EA32840744100031DD47EB19D5F4F1 +:10440000B041500000518441F083122F8002A8096E +:104410003A108C004402E40849FFFBD8D50CDD5368 +:10442000EAAFC809EAC5EA32840744100031DD4723 +:10443000EB19D5F68407EA6FDD47DD53EAAF5A0082 +:10444000DD048401D5028403FC829200FC01840A0D +:104450008061EA235A1001055A100207D543DD5343 +:104460008420EAC4D543EA5B000080528E06E6044D +:10447000E83544F0427CEA7FEA41DD0F040C245029 +:104480008400EBA8EBFBD5328401EBA884008040CC +:10449000DD52EA4AEAA13C07948949006175D50BCF +:1044A0008403EBA88401EA900000805344120000CA +:1044B000490060B2DD4BA600441200004422C3B79D +:1044C000EB353C4DFC0C4900611DD5104402010246 +:1044D00049005D188401EA23D5098401EA23AED09E +:1044E000D5058401EA238402AE10EB505A080A0A6B +:1044F00049FFFF74DD54EA238401AE08DD5BAE089A +:10450000EB50FC815A0001075A080309B401EA6024 +:10451000D503B401EAB2B601DD9E8402AE10DD9E81 +:10452000FC00DD53EAAF5A08040CDD46C809DD4241 +:10453000C00484013E07F028DD538420EAC4FC80D7 +:10454000FC409F01E68F4EF2008880C2800144F05B +:10455000435C3847910140F23C00DD0F24002E00FF +:1045600038009600BC00C200FA00D400E000000150 +:104570001E00EE00FA00FA00F400FA014800007193 +:1045800084003E07EEAD8406D56B84003E07EEAD99 +:104590008407D566EA6EEA74F82580C05A000204E2 +:1045A000EA53D5FB8401F823490017DE3C0E045E74 +:1045B000490017E33C0E045F490017F03E001181EB +:1045C000490017F63E001180490017ED3E001182A8 +:1045D00084214402E968490048FD8006F808EA930E +:1045E000EABC490017E9C003AFF0D5FC490017F752 +:1045F000D512842EAE418426AE40EA5B8440102062 +:1046000080508421DD568420840280418461808131 +:1046100080A1DD578401D5248401AE10D515840016 +:1046200044100066DD478401AE30DD46840ED518A7 +:104630008401AE108401F8068402D5128401AE1004 +:10464000840049005463840DD50B8400EB94D5E3BA +:1046500049FFFF68D5E08402AE18D5DDFA00FCC042 +:104660009200DD533C1003A8101000A092281010F7 +:1046700000A13C17F627101000A29028101000A3EC +:104680002E17EBFD101000A4EBCFA688102000A57C +:10469000A68A102000A6A08B102000A79248102008 +:1046A00000A80020801E102000A944238D41A69060 +:1046B000102000AA8440102000AB3C23F77E10207D +:1046C00000AC9248102000AD3C33F6113C23F6219B +:1046D0008843102000AE9048102000AF00208020BA +:1046E000102000B000208021102000B10020802286 +:1046F000102000B200108023101000B33C1DFB2BD3 +:10470000101000B5EB38A648101000B6EBF1A08BE6 +:10471000A04C102000B7101000B8DD9E4413F04AE2 +:10472000EA28DD53EAAF5A00BB04AE88D5FBDD9E14 +:10473000FC0080C0DD53EAAF5A08BB2449004D4558 +:10474000DD5300100050C1035A18FB112E17EE97CD +:10475000C9042E17EE96C1118400EBAD3E07EE960C +:104760008400EB948401EAE7D51ACE08EB375A08A7 +:10477000A00B44030FA0D50DC60B441FFFA0D50E00 +:10478000C6F6D50D5A08A10544036510D502EAC640 +:10479000EAB6EA4D441FFFA0DD53EAC4FC80920054 +:1047A000FC00E60A4EF2007944F045B4EA7FEA41A3 +:1047B0004A003C000A4468E2E2E2E2E27CBCC9034F +:1047C000FA13D50F5A18010BFA0E3C0BF48E3C0B62 +:1047D000F48C840C3C0BF48DD55F5A180207FA094F +:1047E0003C0BF48EFA0ED5F45A180304FA04D5F9EA +:1047F000840F5A180452D5F58401C1045A180106D1 +:1048000084023E07EE90D54884005A1002FC5A10EC +:1048100003045A1804423E17EE90D53EC1075A10C1 +:1048200001065A1002045A1803383C1BF488D53488 +:10483000C903FA0ED5055A1801084400003C3C0B88 +:10484000F48AFA13D5135A180207EA583C0BF48A73 +:10485000FA09D50C5A180304EAE2D5055A18041DC2 +:10486000440000823C0BF48AFA043C0BF489D51412 +:10487000840AC1105A180104FA04D50C5A1802040B +:10488000FA0ED5085A180304FA18D5045A18040564 +:10489000EA8A3C0BF48BFC809200FC00FA093C0B8A +:1048A000F48E3C0BF48984023C0BF488FA2E8400CD +:1048B0003E07EE903C1BF48C3C1BF48BEA89844C45 +:1048C000441000503C1BF48A3C2BF48DB440441E31 +:1048D0007FFFFE56B620B4206610F0005810A000EE +:1048E000B620B440461FF1FF50108FFFFE56421015 +:1048F000D808B620B440461F8FFF50108FFFFE56D9 +:104900004210E408B620B42066108E0058108400CF +:10491000B620FC80FC4080C18420AE40B40280E21E +:104920004200740B81245A080106B4064200740840 +:10493000B606B4074200740BC805B40642007409F9 +:10494000B606B407EACA5A080107B406EA91B606E1 +:104950008006EB56B407EACAC80AB406EA4FB606A0 +:10496000490019B43E07EF118006EB56B4079604D0 +:104970005A080105B406EA42B606B4079604C8040C +:10498000B406EB52B606B407EA465A080105B40667 +:10499000EA60B606B407EA46C804B406EAB2B60648 +:1049A000B407EAD65A080105B406EAB3B606B40756 +:1049B000EAD6C804B406EB2EB606B407EA575A087E +:1049C0000105B406EA95B606B407EA57C804B4066A +:1049D000EACCB606B407920596175A080106B40643 +:1049E000EA43EA85B606B407920596175A08020705 +:1049F000B406EA4358000040B606B407920596177D +:104A00005A080307B406EA4358000060B606B40724 +:104A1000920596175A080406B406EA43EAEBB6066E +:104A2000EA84EA57C807B40642006C09B606EBAB45 +:104A3000FCC0B40642006C08B606EABA92075A08EF +:104A40000111EABA9637EA83B4278400922996576F +:104A5000F939B40754100E00B40666000E00F84091 +:104A6000EA8496045A080112EB5B66108001101468 +:104A70008001B427922C9657F925B4075410700082 +:104A8000B40666007000F82CEA84EA465A0801125F +:104A9000EA84EAB2EA64B427840892359657F91298 +:104AA000B42746000E00FE46B446460FF1FFF81547 +:104AB00000048001EAD65A080117EA84EB2EEA6462 +:104AC000B427840992389657F8FDB4274600700041 +:104AD000FE46B446460F8FFF50000FFFFE16FE0F36 +:104AE000B60683FFEA84EACA5A080113EA84EA4F49 +:104AF000EA64B4278402922F964FF8E4B427440165 +:104B00008000B446FE46440E7FFF4E00FFE9FCC025 +:104B10008E01E60DE84BFC0080C144F04924EA7F99 +:104B2000EA41DD0F0E162A30363C4248804E5A6468 +:104B30007000B401EA91B601D508B401EA4FB6019C +:104B4000490018C43E07EF118006EB56FC80B40103 +:104B5000EA42D51FB401EB52D51CB401EAB3D51912 +:104B6000B401EB2ED516B401EA95D513B401EACC05 +:104B7000D510B401EA43EA85B601EBABFC80B40181 +:104B8000EA4358000040D505B401EA4358000060EC +:104B9000B606FC80B401EA43EAEBB601440000BD6E +:104BA000DD41FC808402AE10FC808402AE10DD9EEC +:104BB00092009200FC20E60C4EF200D080E280C110 +:104BC00044F049CCEBACEA414A003C0018004400F8 +:104BD00072008C018C018C018C016E01A400D40048 +:104BE00006013601B402EA294E0200BAB4229797B0 +:104BF00066108E0040609924B6C2B42284009229C7 +:104C00009657F86044000070DD41B4079209D5164C +:104C1000B402EA294E0200A4B42297976610F0006D +:104C200040609984B6C2B4228401922C9657F84A07 +:104C300044000071DD41B407920C9617F818B402D5 +:104C4000EA294E02008DB4C2440E7FFF964FFF86C4 +:104C5000406305E4B6C2B4228402922F964FF83224 +:104C600044000072DD41B407920F960F48000074B3 +:104C7000B402EA294E020074B402466FF1FF506399 +:104C80000FFF9657FF86406306A4B6C2B42284087D +:104C900092359657F817EAC5DD41B4079215D5CE7F +:104CA000B402EA29C05CB402466F8FFF50630FFF65 +:104CB0009657FF8640630704B6C2B422840992382F +:104CC000965749FFFD6F44000079DD41B407921803 +:104CD000D5B5978CB4224210EC0940609B64B6C2F3 +:104CE000B402EA29C805EBAB44100168D5034410AF +:104CF0000E10EA7DAC404400007ADD41B407EA2999 +:104D0000D52ADD42C02CB42797B44210F009406088 +:104D10009B84B6C7B407EB6DC8062E17E9395A183D +:104D20000108D504EB34C80484013E07E939440086 +:104D3000007BDD41B407EB6DD50E978CB4224400A7 +:104D400000774210D00940609A84B6C2DD41B407B2 +:104D50004200500BDD41D5038402AE18FCA0920046 +:104D6000FC62A6098121F281814381845A080405ED +:104D700084003E07EBE6DD42C007EAF45A08AA05C4 +:104D80002E07ED54D504DD53000000504E020209F9 +:104D90005A08FB0448000205F001EAED490019BB7E +:104DA0008400EB93DD42C00CEAF45A08AA0A2E678D +:104DB000ED542EB7ED5540731009979FD509DD537B +:104DC0000060005000B0005140731009979F8401AB +:104DD000EA508400EBFCEB5B5A1804182E17EEA186 +:104DE000C1043E07EEA1D54A2E07EB9F5A080103E6 +:104DF000EB9284208009DD568401EA26DD45DD43FF +:104E0000AE40EAA5C0FFD53ADD45DD43AE40DD4208 +:104E1000C804DD42C820D527DD465A000204DD540F +:104E2000D5162E07EE9AC00B3C1DFB712E07EE9A8D +:104E30008E01E201E904EA5AE602E8F24400008A3F +:104E4000DD418401EADDDD55480001BEA608C8E267 +:104E5000EA2DD5FDEAF45A085507EAAC84028041F0 +:104E60008466DD44DD59A6005A0002093C0DFB377B +:104E7000A6405A1802048420AE402E07EC0B8C0189 +:104E80003E07EC0B40031C848EE1E6EC3E07EC0A87 +:104E90004EF2015C44F04CA438779D0140F3BC0015 +:104EA0004A003C0018005200BE01D6013C024A02F2 +:104EB0006602A402A402A402760292024402C3780B +:104EC000EB5D49001960F001EAED49001924800604 +:104ED000802B8049EBDE8400EA505A600F044800C2 +:104EE00000FFDD5384CC000000505A00FB04480052 +:104EF0000140480000F58EC18401E6C6EB934EF2F6 +:104F000000AB44F04D103867990140F33C00DD0FD1 +:104F10000C0034005E002201280164008400EA5085 +:104F20008401EAFBFA318404DD47EA92C80784046D +:104F3000FA3ADD4784C4F814D5588404FA3BDD47B7 +:104F4000FAC4D5538400EA508401EAFBFA318404A0 +:104F5000DD47EA92C8088404FA3ADD4784C549FF70 +:104F6000F8B0D5438404FA3BDD47FAC5D53EEAFBE9 +:104F700084C2F88DDD42EA5BC03E8401EAFB00009A +:104F8000805284C0106F800F5A08AA284900491D1A +:104F90008401EB94DD530010005300200054440FB3 +:104FA000FFA0FE0F5A2801103E07EE964400988C91 +:104FB0003E67EE97F80DDD53441FFFBB3E67EE934F +:104FC000EAC4D508EBAD440062383E67EE9649006E +:104FD0004971DD538420EB9DEB37C806EAAA84C1F2 +:104FE000C004FAD0D502FAC9EA8C4E0300C2841F6D +:104FF000EA2AF84D2E27EE96C202EA5000008052AF +:105000005A08AA150020805484005A28010B003049 +:105010008053442FFFA0FE9FEA503E27EE96D50313 +:105020003E07EE96EBAD8400EBFBEAAA4E0300A030 +:10503000D556EAA8EA6AD5538400EA5BEA508401AF +:10504000EAFB0000805500108054EBEC3C0BF61599 +:10505000FAC2F81D8404FA3FDD478400EB93480050 +:1050600000728402EB0B80268401502F800F49FFD1 +:10507000F9EF80C08405EB0BF80A84002E17EB8F44 +:10508000EA508401EB935A18010584C94800007165 +:105090003E07EB8FEB0B5A68010D84004410004172 +:1050A000DD47DD5A3C0FFB4D3E67EBE2EB44D50399 +:1050B0008402EA50000F800F5A0802E9DD5384C0D1 +:1050C000106000513E67EBF53E67EB8FDD465A00FE +:1050D00002053E67EC13D5038405EB0B84C1D5486C +:1050E0008006802A502F800F49FFFA0ED51D8400BC +:1050F00044100060DD47800680294422C3E5503F0C +:10510000800F49FFFA1F9780D5338006802B804A95 +:10511000503F800F49FFFD50D5078006802A502F51 +:10512000800F49FFFCF7000F800F5A0002D9B40A24 +:10513000B60C84CBD51D5A68010649FFF6DEFAC3CA +:10514000D5178402EA50D5CB840284C1EA503E6769 +:10515000EBD7DD42C0073E67EBD7840F441000FB5E +:10516000D504840F441000EBDD47D5B9FAD0000F09 +:10517000800F84205A0001055A080206843BDD5343 +:10518000101000502E07EBF5C8094402C378EB5D00 +:10519000490017F9F001EAEDF80F8006D514EB3756 +:1051A000C803EAAAC0078400EBAD3E07EE96840070 +:1051B000EB94F001EAED490017D4EA3BEB47840099 +:1051C000EAFB8401FCE29200FC2080E280C35A00EA +:1051D0000704480000D2E62C4EF2011C44F04FECCC +:1051E0003817850140F0BC004A003C00180044001C +:1051F000720024022402240224026E019E00CC00CC +:10520000FA003401A621EA574E020107A660440FB6 +:10521000FF80FE0FAE20B44397D766210E00407189 +:105220001D24440000B0B6E3DD41B4069209D51454 +:10523000A621EA574E0200F1A62197D7EA42AE21F5 +:10524000B443440000B16621700040711D84B6E390 +:10525000DD41B406920C9617DD41480000DEA62120 +:10526000EA574E0200DAA62197CFEA91AE21B44365 +:10527000440E7FFFFE8640711DE4440000B2B6E399 +:10528000DD41B406920F960FD5E8A621EA574E02EB +:1052900000C4A621461FF1FFEA60AE21B4035010FE +:1052A0008FFFFE0E97D740001EA4B603440000B83F +:1052B000DD41B4069215D5D0A621EA574E0200ADC5 +:1052C000A621461F8FFFEAB3AE21B40350108FFF13 +:1052D000FE0E97D740001F04B603440000B9DD411D +:1052E000B4069218D5B9A62197D4EACC40001C8404 +:1052F000AE21B44342216C0940711F64B6E3B4038C +:10530000EA29C805EBAB44100168D50344100E1020 +:10531000EA7DAC40440000BADD41B406EA29D59DDF +:10532000DD424E02007AB44697FC4221700940717A +:105330001F84B6E6B406EB6DC8062E17E9395A1875 +:105340000108D504EB34C80484013E07E939440060 +:10535000007BDD41B406EB6DF84D97D4B4434400B7 +:1053600000B74221500940711E84B6E3DD41B40606 +:105370004200500BF83F5A080B408E21E62DE849B9 +:1053800044F0518CEB3940F0BC00DD0F0E141A20B4 +:10539000262C3238843E46505A00B403EA91D53761 +:1053A000B403EA4FD534B403EA42D531B403EB5227 +:1053B000D52EB403EAB3D52BB403EB2ED528B40312 +:1053C000EA95D525B403EACCD522B403EA43EA85AD +:1053D000D51EB403EA4358000040D519B403EA438C +:1053E00058000060D514B403EA43EAEBB603440066 +:1053F00000BD48FFFF335A0805105A1001075A181C +:105400000309B403EA60D503B403EAB2B606D504CF +:10541000843BEA7EAE40FCA09200FC62F081F28206 +:10542000F383EA7EA7C0A7804402FE51A60092E45F +:10543000979FEAEC5A700104480000709E31E60321 +:10544000E90E5A600503F80EDD53000000605A00B3 +:10545000A1072E07EF2F5A080103F804EAF45A08AF +:10546000AA04480000774E420075DD42C00ADD40C4 +:10547000A601EB295A08040644000088DD41FCE23D +:105480004402C378EB5D4900167E4402C39CEAEDFA +:10549000490016415A60050584004900452DEA80FF +:1054A000EA37EA31A6085A080104AED0D5FCDD423D +:1054B000C024F81A44000082DD412E1FEEA02E0FFA +:1054C000EE9F4423F41C4E170006A6D05A3802FD66 +:1054D000D5034E06FFFCEAAC804184668402DD44BD +:1054E00044000083DD41DD45DD43AE4083FFEA211A +:1054F000A6085A08E1FFD50C44000084DD41EA21EA +:10550000440FFFE1AE08804184028461DD448006DF +:105510008029F201EBDEFCE281615A700B06540334 +:10552000800D5A080517DD42C014EAF45A00AA1289 +:1055300044A2FE508400EAD5802680078049F30209 +:10554000F40349FFFE43EAAB5A00FB048401EAE09E +:10555000FCE23C0FFC0EDD9EFC67F08D81A1818298 +:10556000C407C30CFA10846684A180C0D510C30B95 +:10557000EB04840180A384C4D50AFA70840180A35B +:1055800084C6D505EA8A846484A180C040E3001300 +:105590009781F8284082801397D9F08A4492ED8C45 +:1055A0002E07DD8A44B2ED2844A2EDF0F08B4422B0 +:1055B00055B88400F30DF820842BF8348400806CF7 +:1055C0008040381481114E17000822518000EB965C +:1055D000976BAD58D502AC988C019641E22E8C6247 +:1055E000E9F13C07F631F0893C07F63083FFF08A99 +:1055F0002E07DD8AF08B14CF8000149F800114BF2A +:10560000800214AF800314DF800414EF8005148F30 +:105610008006F787F68883FF8400842D442255B8DE +:10562000F30D808C44527200F91EFCE7FC01F081FE +:10563000440004733C0BF631440FFB8C3C0BF630FA +:105640002E07DD893E07EC0D8C0180C13E07EC0E74 +:10565000C921F8058481F80B8066F83244029ECA9D +:105660008441802080624900165C846144029ECAA5 +:105670004412A50AF20183FF8083F8224412A1EAB2 +:105680004402A82AEA27DD4844529ECA4412A04A8E +:10569000D5205A180149F80584608083F809F8106C +:1056A0004402A05A8020804680664900163AF201E2 +:1056B0004402A05A4412A69A83FF8066848049FF60 +:1056C000FF4D4412A37ADD5D4402A9BADD48FC8196 +:1056D000A428505280409603120283000202817077 +:1056E0009603120284900202FFFD96031202831DAC +:1056F0000202818D9603120284AD0202FFE196033D +:105700001202830102028171960312028491020245 +:10571000FFFE96031202831E0202818E960312027E +:1057200084AED9D7FC81381105118820E023E90A1D +:10573000EBAF5A08010B3C03F8CCC0085EF0807850 +:10574000E80444008000DD9E8400DD9E3C1DFC0ECC +:105750002E07EBCEA68EC80CEA365A08010A941121 +:10576000AE0AA6098E01F8079401F80BD511A60917 +:10577000AE8A8E01FE148442400008168E0183FF1B +:1057800096033C0BF631FE033C0BF63083FFA60973 +:105790003E07EC0D8C013E07EC0EDD9EFC672E678C +:1057A0002813F08D81C181022E072812CB0580209D +:1057B00080408401D5048026844180C097C1F8329E +:1057C00040B080134091001344D2ED2844C2EDF064 +:1057D0003C0DFC0E97B144A2ED8CB71FEBD414DF47 +:1057E000800214CF8003F82CF838842BF83C8460B6 +:1057F0008008820D808C80439659E22BE81338157F +:105800000D114E17000C22500000EB96976BAD4027 +:10581000A440964B5EF0FFECE802AC808C618C02F9 +:10582000D5EC3C07F631F0893C07F630F08A83FF6F +:105830003C0DFC0EF483B71FEBD4150F800214EF60 +:10584000800414BF8005F786F687149F8008A6029F +:10585000F08B840083FF842D442255B8F30D80889B +:1058600080A083FF49003D78FCE7FC0180C0F18106 +:1058700049FFFF6EA036A075F201846049FFFF90DA +:10588000FC813C0FFB85DD9E3C0FFB83DD9E3C0FC6 +:10589000FB84DD9EFC41846380C080E2501F800653 +:1058A000FA50B400EBB6EA54B607F80FA47044926D +:1058B0000000F81010138010B406501F8006FA5034 +:1058C0008464EBB6EA54A83949003EEEA4703C3D2E +:1058D000FB838A010014800292014000043783FF99 +:1058E00010138011B406A072A0B60031800C848120 +:1058F0004900156BFCC1FC6580E1842080C4121F47 +:10590000800D5A48040504900006D5030490000554 +:1059100002310439A613854050BF801CA7528083F2 +:10592000B61F802980098445EBD414AF800214AFE0 +:10593000800314BF800449003CE6020F800EAC389F +:1059400002058001AC39501F801A8009804A8463A7 +:10595000EBB6020F800D5A6804053C0BF62CD505FA +:105960005A6805043C0BF627AC3B501F801A80098F +:1059700084408464EBB6020F800D5A6804053C0B2A +:10598000F616D5055A6805043C0BF612AC3A5A6077 +:10599000040E84003E07EBC9221380033C039840A9 +:1059A000E020E80484013E07EBC9FCE5FC0180C16E +:1059B000F3818460B61F3E37EBC949FFFF6DB41F0A +:1059C0008026F2018460848449FFFF972E07EB94C0 +:1059D0005A08010722130003440395B4AC40FC812C +:1059E000B460B42080A0927096098440986AB48113 +:1059F0009290E264E804B421806496098C445A28A9 +:105A000020F7DD9EFC2080E180C049FFFFEBE6E847 +:105A1000E85544F0582038779C0040F3BC00DD0F77 +:105A2000081A2C3E54647486961F96433C1BF82536 +:105A3000964F3E17EC028400D5423C13F82594049F +:105A40009600FE0F3C0BF8258400D5393C13F82551 +:105A5000961F400081043C0BF8258400D5303C1390 +:105A6000F825400081849643EB283C1BF825AC4088 +:105A70008401D525961F9643EB89964F3E17EC027D +:105A80008400D51D940496403C03F824FE47EB891E +:105A90008400D5155410000F3C03F8244010050471 +:105AA000EB898400D50C3C13F82440108184964B7C +:105AB000EAE5EB89AC408402D5028400842FB62647 +:105AC000FCA09200C9104020380954003FFFC006D6 +:105AD00096C4882396489201D5FB964FFE555C00EC +:105AE0008001DD9E8401DD9E5450000C848090A2D4 +:105AF000E28510F0800054100030540000C0902463 +:105B00009006E2814002000610F10000AE18DD9E12 +:105B1000FC0180C1B42380A0C951847F3E37F0448A +:105B20003E17F043C41AC215402020095401000C4E +:105B30009002E22054010003EB492E27F04240007E +:105B40003C244C2000523E17F0413E07F042D56302 +:105B500012230025480000A1541000032E07F04234 +:105B60004C00C013EBC2E602E8038C01EB27EBC24A +:105B7000E602E90310130040EA73EB13E80984001E +:105B8000EB27EBD3D5053E47F0413E17F042545288 +:105B9000BFFF44000FFF92A2D00A02130026840325 +:105BA0004250807390A212530025D5031253002552 +:105BB0000203002512030026F8465A100403F84396 +:105BC0004E420081920896015410000C9022C23D72 +:105BD0008440960F40110406E240400784242E17AB +:105BE000F0424C1040152E17F041E624E8048C21B9 +:105BF0003E17F0412E17F041E624E902EBD3EA7399 +:105C0000EB13E8098400EB27EBD3D5053E27F041E1 +:105C10003E07F04202030025120300268400EBBA7F +:105C2000501F80058005EBE8EB35F83A000F800641 +:105C3000001F8007940140000440001F8005880178 +:105C40003E07F04048000083960F40110406E240F2 +:105C5000400784242E17F0444C1040182E17F043B0 +:105C6000E622E8048C213E17F0432E17F043E6228B +:105C7000E802841FEAD3EA73EB13E80B84003E07C3 +:105C8000F043841FEAD3D5053E27F0433E07F04496 +:105C90008400EBBA8005501F8005EBE8EB3549FF27 +:105CA000FF25EB50001F8006940540000480001F74 +:105CB0008005400004602E17F040FE0F10030059CD +:105CC000D545541000032E07F0424C00C013EBC220 +:105CD000E602E8038C01EB27EBC2E602E9031013AE +:105CE0000040EA73EB13E8098400EB27EBD3D505FA +:105CF0003E47F0413E17F042540280FC92021003EE +:105D00000059CA2492A82E07F044974F4C02C01B9A +:105D10002E07F043E602E8048C013E07F0432E070D +:105D2000F043E602E90410530041D503841FEAD38F +:105D3000EA73EB13E80B84003E07F043841FEAD3B9 +:105D4000D5053E27F0433E57F044FC81FC6080C1FE +:105D50002E10115581625A10010544A00708D50381 +:105D600044A003E85A0001055A00023EF80C44130F +:105D700097DCA4483C2C0436964BC2035A280506EF +:105D80008400EB2A4800009AB44B662100044E239D +:105D9000009540C08013542600039FD35C7380019C +:105DA0003E77F0463E70111ACF0C2E37F047CB0BE2 +:105DB0002E57F045DA063C2DFB3C5CF103E8E80287 +:105DC0008400EB2A54908003800C80273E97F04596 +:105DD000F838CF5C2E17F047C13E3C1DFB3CE34139 +:105DE000E955D539EAE5A440EA97964BC0CA5A006E +:105DF00005C9EB7DE60AE961B40BEAB2C85E40C0B2 +:105E00008013540600039FC35C7380013E77F04605 +:105E10003E70111ACF0E2E27F047CA0D2E57F045AF +:105E2000D808EB3B5CF003E9E9048401EB2AD503D5 +:105E30008400EB2A54908003800C80273E97F04525 +:105E400049FFFE42CF2E2E17F047C1053C1DFB3CFB +:105E5000E341E92784013E07F0468400EBBAEA9764 +:105E60005A00042C00030045100300462E07F0469C +:105E700010030045C82202030025C8058401EBBABF +:105E8000120300268401EB2AD518C0EA840012030D +:105E9000001F8026800C8441806B8087F80BD5E042 +:105EA000C0DF84001203001F8026800C8440806BBA +:105EB000808749FFFE2FD5D4FCE0DD9EDD9E442285 +:105EC000AB4AB6404432AC764422ABAEA881A8C9F6 +:105ED0004422AC128460B641ACC4ACC5ACCCACCDF1 +:105EE0008420B4A080619929ACE0990A8C22ACE0AE +:105EF0005A1840FBA101840080204432AC7698A05F +:105F0000AC5098838C02AC505A0864FBDD9EFC2197 +:105F1000A4C0842096DB121F80033C57EEA9848026 +:105F200084CF447001EA96615CF08064E80A402006 +:105F3000840903000000A44052210031964BD50A89 +:105F40000300000050227F9CA4409041964B5221B8 +:105F50000031FEB49691FE54EAB98830964BAC40BD +:105F6000A440964BE061E803A4C096DB8C818C02D0 +:105F70005A48C8DB123F8003EA5496034002800768 +:105F8000FCA1C80E3E07EBCAA40EC80684013E075A +:105F9000EBCA8400DD9E5A001FFB8401DD9E840055 +:105FA0003E07EB8EA40FC80684013E07EB8E8400EB +:105FB000DD9E5A0831F4D5F9FC442E401150802062 +:105FC00080022E27DD7AE282E8043C57EEB6D50344 +:105FD0003C57EEB8E282125F8000E8052E47DD7480 +:105FE0009723D5042E47DD7597238440124F8001F7 +:105FF000122F8002C8065090800CB4E1FB90D506A9 +:106000005090800EA1C945000032225480004E936A +:1060100000079CA940238820A490F80C4647FFFF66 +:1060200050420FFF50287FFF8885DA0840439020B8 +:10603000A4A09693122F8002D517952141139000AA +:106040008C84888702688000A4A097B39693E0466A +:10605000E807024880009723124F8002D505A5204B +:106060009723124F8002952998BCA590022F800299 +:106070008AC297B3126F80035A3001044800006649 +:10608000EA54EAB59603964BE02050287FFFE81CBF +:10609000E0A2E8078C828887A420F805F808AC20E5 +:1060A000F8318EE29643EAF3960383FFFE0CEB078A +:1060B000EA8F40307C0AF082F383F002F10396030A +:1060C00083FFAC38D53EEAF3E0A296C3EA54964388 +:1060D000EB1197835001FF9CFE0C400018165000F6 +:1060E000006441107C0AF084151F8005E80B8C8247 +:1060F00099BCA430F810F086F187F006F1079603FA +:10610000AC30220480004E07001D40738020020343 +:10611000FFFF83FFF404F50596034222802440101C +:106120007C0AEBF0420010698460882244200064FD +:10613000EA48F086F187F0068EE29603F107AC3864 +:1061400084013E07EBCAFCC449FFFF1DC01B2E1093 +:1061500011503C07EEC25CF080248420E902EA6F13 +:10616000022F80038801969322148000443000643B +:10617000FE9C407384209603A478EB9F9A089603B4 +:10618000AC38FCC4FC208480C83AA4D61030800906 +:10619000847FA90CA90D8381BC8ABC8BAECCAE0DCB +:1061A00080C0451188C8B482F83B4E37001CF83FC8 +:1061B00005008004A0CDF845A8CDA6CC8CC1A90CC3 +:1061C00097B35A38FF03AE0CA6CDE003E902AE0D3B +:1061D000B4628381BC0B88E3A4F8BF0AF849BB8A88 +:1061E000BC8B8C015A0820E184004E670007A4167E +:1061F000B44240010020A400AC08FCA0A417100089 +:106200008008841FAE0E8400AE0F8400A90EA90F73 +:106210008381BC8CBC8D80C045118800A11195C1C3 +:106220008887A4E096DB83FF4E37002DA520383801 +:10623000810197234241906883FF05008006A0CF2B +:106240008890E2908865886F83FFA8CFA6CE8CC126 +:10625000A90E97B35A38FF03AE0EA6CFE003E902AA +:10626000AE0FA0D18381BC0D88E3A4F8BF0C96DBF0 +:106270004051FC0A8867E2678885888F83FFBB8C62 +:10628000BC8D8C015A0832CC84004E670007A417DD +:10629000A09140010020A4005CF00191AC09E90547 +:1062A00084013E00114FFCA084003E00114FFCA071 +:1062B000FC6080C12E16B15E4E120099814680E4CA +:1062C000953140901000020480002EB728122E67EE +:1062D00028349603C34CF87DF84B4E0200884E7369 +:1062E000008640152CD7808797B1964980074421B6 +:1062F0008948E201E808383100008C018883972141 +:106300009601D5F88400806044218948E223E90899 +:1063100038510C008C618805960196D9D5F82E105D +:10632000023E8E01E2814040BC1B2E10023F9601CE +:106330008460420080013C7C019B80A3E204E90D63 +:1063400040239020A450964BE061E804A4D080A4A0 +:1063500096DB8C819721D5F302248000405314A052 +:1063600044117EB0961338209400D533F83296034A +:10637000EB10EBC183FFC03ACF39406518572E10A0 +:10638000023C94939691E2419C174020BC1B2E1036 +:10639000023D96014200800197B13D0C019A808731 +:1063A0008027E202E90D40580820A4E896DBE0834C +:1063B000E804A528802297238C419691D5F30224E6 +:1063C0008000406098A0441178709613382098009F +:1063D0004220086850010032E2028023882F846046 +:1063E00044200064EA489603EB10FCE0FC658180E1 +:1063F000220F8030F0832E072812F0822E072834D7 +:10640000F0842E072813F1818162F38681C4049FF2 +:106410008016227F802E006F8064F08540A10408E2 +:106420004E420086F0024011001654D000FF55C0C5 +:1064300000FFF00250807FFDC60F440186805CF6AD +:106440008002382009018481E90340447007800CF0 +:10645000802B806EF8DEF8824020F020A450F8E512 +:10646000F8EEAC50B429421070735CF68002B62985 +:1064700040A470078401E902800A96005CF680025D +:10648000F0848401E902800A9600F0858541448108 +:106490008680F006E20AE94A405E28014E55001463 +:1064A0004165A801C607F817F404F81DF508056F43 +:1064B0008007F820F8B9E020E806F8244026A80173 +:1064C000F8BEF829F002405E2800E0A0E82B416504 +:1064D000A800C610401B001338245901800C806EA0 +:1064E00083FFF405F588156F8007F893F508056FAD +:1064F000800741665820020B000083FFF895E020DA +:10650000E811F10141509420021A800083FF4025D8 +:106510003400F895121A8000B42942100873B62985 +:1065200083FF50050001EBDAD5B5FCE5F004EB9FE5 +:106530009640548000FFF005F18251C07FFDC60EE9 +:10654000440184F0E62238200901E804404E200787 +:10655000D501800C802B8460F85C894C020500001A +:10656000F10183FF4020A020A450F85FF868AC50F0 +:10657000B42942102073F002B629E60240AE20078B +:106580008400E802800A9600F087F00285A144E1C9 +:1065900084F05DC00002F006E20DE9604054340171 +:1065A0004E550022F00443568024C6104025D401E5 +:1065B0009651800C382709018460F407F589155F2E +:1065C0008008F827F509055F80084005D401F82800 +:1065D000E020E809F82F121B0000F1024020B4016E +:1065E0004E00FF9CF00540543400E0A0E832F00477 +:1065F00043068024C6134005C000808A9641382790 +:1066000001018460800C404E701AF589150F8008D6 +:1066100049FFFE50F509050F80084005C0004156AE +:106620000020020A8000F10396038A0783FFE0201E +:10663000E810F10141609420021B00008820964B75 +:1066400083FF121B0000F102402684004E00FF660B +:106650005006800154D000FFD59FFCE5FC688120E6 +:10666000EA3C8101F387838585405A0001042EA707 +:10667000DD5C3C13EEACF1868420F18EF18FC41208 +:106680005A0801053C17EEB1D5033C17EEB0121FB6 +:10669000801A5A0801053C07EEB2D5143C07EEAF4C +:1066A000D5112E07EBCA5A0001092E07EB8E5A00AE +:1066B00001053C07EEB4D5028004120F801A3C0796 +:1066C000EEB3120F801B4E83001F84001281000462 +:1066D000A814A8152E7728122E0728355111000866 +:1066E0005131000C04C10000F0852ED7DD765061D9 +:1066F000001081C7FAB0455000C050BF8038443107 +:106700008680D51C8400AC158400A816A8172E77A7 +:1067100028345111000A5131000E04C100012ED756 +:10672000DD7750610018F78544500032455000C8AD +:1067300085C150BF803C443184F084001208800041 +:10674000840080203A030420842082C98201804191 +:1067500002F88000020B000040F4BC2002F7800029 +:10676000960341278011E1C0E803122880000A0B3C +:1067700000018C41960340F07C0A880141700406B8 +:10678000898F9691802089974C2AFFE4B606840071 +:1067900015030001802C80408C0196011A20800195 +:1067A0004C02FFFC2E06B15E026880005A08011CF4 +:1067B00040049820A4003811990196034200806893 +:1067C000442000648460F48BF58A153F8009151F0E +:1067D0008008EA489603051F8008053F8009F50AEE +:1067E000F40BD50540049820A4009603F106E001BF +:1067F000E805F1078400AC08FCE84E83000C406318 +:106800001C16120980000208800040701CF697F8E0 +:10681000D509EBE3126980000208800040001CF6F5 +:1068200097F8C41602098000C0099E694C008007D1 +:106830005A0001058EA24C02C0072E07DD55100F2D +:106840008033D50A2E07DD54100F8033D5052E076F +:10685000DD56100F8033EA3C5A080108000F8033E0 +:106860008C019600100F8033F83B52640001964B68 +:10687000960397B0022880008086F84F80AD151FE0 +:106880008006F856051F800602388000CF04402796 +:106890000C00D507F0058E014C70400D4021B80169 +:1068A000969140048820A4009603E140F82DF83E1C +:1068B000FCE84051B8014021B800404494204034E5 +:1068C0008820A420A4589603964BE020400500138E +:1068D000E816A460A4988A229649E201E82B003FBA +:1068E0008033021F801A020F801B83FF964B960392 +:1068F000F181F08296A9F813F819FCE8A458A4E0F5 +:106900008A239649E201E816003F8033021F801A6D +:10691000020F801B964B9603F181F082B77F15CF53 +:1069200080038009802C83FF9691808680AD49FF8B +:10693000FD5FFCE8FC4081408400EAD58400AC089F +:106940008121AC108024A01D80E280C4442000324C +:10695000806A8481EAD484A0EAABE2A0E817A0317F +:10696000946938001501D810A03202248000380044 +:106970001501E240E802EB10A03338000401A478CE +:10698000E220E802AC388CA1D5E884003E07EEEEA8 +:10699000EAAB5A08011102148000E628E80CA4783A +:1069A0005CF080B4E808EBC4B4215EF08209E9032E +:1069B0003E07EEEEFCC03C23F77996415000806420 +:1069C000EB799601E8242E27EEEB5A2801065010A9 +:1069D000805A9609DD9E5A2002062E37EEF45A3868 +:1069E0000206501080509609DD9E5A2003045A3842 +:1069F0000306501080469609DD9E8E44E649E90460 +:106A00008E64E669E804501080329609DD9EFC0031 +:106A10002E17EE915A1801122E17F03C8C21964831 +:106A2000E62BE8043E17F03CD50E842A3E17F03CD6 +:106A300084203E17EE91D507EB64C9053E17F03C64 +:106A40003E17EE913C13946DAC40AC442E1728AC2D +:106A50005A180114EB38A6485A180310EB64E625BF +:106A6000E8082E172932AC402E172932AC44D50540 +:106A700044100078AC40AC442E1728C35A18014289 +:106A80003C1DFB2BC93E2E2728AC5A28013B80C059 +:106A9000DD4BA6005A080306840AF804AC30D53151 +:106AA000800149FFFF8AAC302E07EE925A0801049C +:106AB000EA58AC30EAF6B401920596175A0001057F +:106AC000B401EA29C81E2E07EEF45A08011B3C0C3B +:106AD00000C3A4005CF00051E9142E07F03CE60A64 +:106AE000E8103C0C00C4A641C1035A181F0BA600B5 +:106AF0008E0BE61DE80684013E07EE91EA58AC30A5 +:106B0000FC80E602E8093C03F4A6E020E807E686FC +:106B1000E80B8401DD9E5A080206E686E805840239 +:106B2000DD9EE607E8028407DD9EFC203C43F488F6 +:106B300080A0C4105A4001095A4002095A48030A69 +:106B4000444000FAD507EB1BD505444000AAD50206 +:106B5000848097915CF30024E807E6B08401E9059E +:106B600084025A581003840097D95CF38024E80803 +:106B7000E639E803EA60D5045A101903EAB35CF376 +:106B80000064E81E3C6DFA525A680109E63AE918B9 +:106B9000F809E9145A501017D50D5A680412E6394D +:106BA000E80F5EF180C8E80E4E35002AE6B083FF9C +:106BB000E803EA85D5075A501006EA95D5034E3505 +:106BC000001FE064E81C3C3DFA525A380209E6B165 +:106BD000E916F809E9135A101913D50C5A3803109D +:106BE000E6B0E80DE044E80B4E25000AE63983FFE5 +:106BF000E803EA95FCA05A101903EA85FCA0FC62A0 +:106C0000230F802022BF8022810481A0FA13004F2D +:106C100080503C0BF8393C0BF8388121800380C24E +:106C200080288050806BF583F482150F800122CF7D +:106C30008024F91000AF804C44E2C890050F800119 +:106C4000F402F5034E9300043807360A3C7DFA52ED +:106C5000380736025A7001045A7804145400003080 +:106C6000C02A3C03F4A6E005E805E6C3E824E6866E +:106C7000E9035A680221EBD284C8C81D84C2D51B1F +:106C800054100030C11C3C13F4A6E025E805E6C30F +:106C9000E816E686E9035A6802133C3DFC245411C9 +:106CA0008002C10454100010C97796D6C377962E7F +:106CB000C075D5725A7001085A700406EA89B4008A +:106CC000EA29C82D38073602960FC0275EF8002340 +:106CD000E9035A9801234EA20007EAE2FE244090FD +:106CE0002936D502812A800680258050806CF58166 +:106CF000F82B80C0F5015A0802115A780405E705FF +:106D0000E854D5065A78010E5CF4002DE94E5CF487 +:106D1000815FE94684C7D5445A7001485A700446D9 +:106D2000389736025404800CC0405EF580232E87CD +:106D3000F074E9054E82003AE746E937800680257F +:106D4000804B806C808A49FFFEDE80C04E82002E20 +:106D5000E746E92BEBD254100002C10E5A78020527 +:106D600054148008D5055A78030854148004C104CB +:106D7000E6C7E80284C79616C0185A78020554047C +:106D80008004D5055A78031254048008C00EE6C763 +:106D9000E80C84C7D50A84C8D59284C2D590EBD2BA +:106DA000C0045CF480FBE8F68006FCE2FC6184C071 +:106DB0003C6FFC243E67F08C2E7728193C9C00C465 +:106DC0003CAC00C33CEDFA523CBC00C250C0000ACF +:106DD0004442C6A49630E207E86350067FF6B4004A +:106DE000C05B5A00055A38021A025A000156500672 +:106DF000001204D0000022267FFF4014B420A60910 +:106E000000808000E60638153501E905E61AE90537 +:106E1000522106409691D502EB23E7062236000068 +:106E2000E9065CF4002CE905523189F696D9D503C0 +:106E30004430FFFF9F43E6BAE82F50547FFD5CF2D9 +:106E4000802CE82A5CF08033E91F8028969396DB3B +:106E5000F48149FFFE6CF401C8173C2DFC24580155 +:106E600000013C0FFC245AE80205E71AE909D505A0 +:106E70005AE8030BE719E80458210003D503582109 +:106E800000053C2FFC243805B5012E17F08CE220BC +:106E9000E8033E07F08C8CC150C6004CD59C2E07F1 +:106EA000F08CE615840AE8052E07F074C0048E0104 +:106EB0003E07F074FCE1EA898427B400400080BEFC +:106EC0003C0FFA52DD9E3C0DFA525A0001065A0060 +:106ED00004048400D502840F441000FF3C5C01DCF4 +:106EE000FD10404288C0A5209723E48BE9095A3859 +:106EF000FF0580228062D504E22240113C1B8C41B8 +:106F000096905A2832F08A23442000FF96488062E7 +:106F1000404280C05042003EA5209723E48BE909FF +:106F20005A30FF06E24040203C1BD5038040806081 +:106F30008C0196005A0832EE8A43E6243E27F12C53 +:106F40003E17F12DE8049610E604E9082E07EEB08E +:106F50005CF0003CE8068C01D50284003E07EEB0F0 +:106F6000DD9EFC204422C890385106025412800F46 +:106F70009E8DE642E90A8E29E622E90754528030C6 +:106F8000842040509406D50284A13C1C00C5EA4EE2 +:106F90008460A642A7C33D0C01DC8083E2E1E923C3 +:106FA000A6800110000141209408E3A2E91940697C +:106FB000080040681820A5B097B3C505C2075A2835 +:106FC0001F0BD504C2065A201F05C1035A183104ED +:106FD000424310008C4142330C009690D5E78C213F +:106FE0009648D5DDEAE2FE248C6140000C1696033B +:106FF000FCA05CF180334422C83CE90E4430004CD4 +:107000004412E9E042100C73A0CF3C1C00C23810BF +:107010008D01E62BE80438110000C1134412C8B8F2 +:1070200038108202E623E8073C1DFA525A10010A82 +:107030005A100408842A3811000844100050D50260 +:10704000FA2438210000C2068E414432C83C38215F +:1070500080088001DD9EFA24FECC3C1DFC24C10387 +:1070600094D996D94412C86838208101E243E803D4 +:107070003830810938008101DD9EFC662270800075 +:1070800022B080013C1003A8F2875010803C3C1BCA +:10709000F4A6EAB74201847380C381A0B400C04F54 +:1070A0005A000550040680073C1C00C4EBA900C030 +:1070B0008001008080003C1C00C35CF60006385054 +:1070C00081113C1C00C8383082023C1C00C54010B5 +:1070D0008040A68951110001A6884028880154915A +:1070E00000FFA68BA64A8C419A519648F186E80388 +:1070F0009739D50A5CF6001AE90552438640972174 +:10710000D5034440FFFFE706E80440258013D50976 +:107110005CF4002CE905522589F69691D502EB2303 +:1071200096008026F28BF48AF589F38849FFFF1BCD +:10713000EBDAF308F509F40AF20BD50E8140D5021B +:107140008540EB23448000FF808214AF8006812AB3 +:10715000818880AA806A4522C6A438191A02C943C8 +:107160004402C8E0EAD8ADC012B000014402C90828 +:10717000EBE9B5CD4402C89044A2C8B838101A0A49 +:107180004402C86838151A0AEBE95B280124EBD2DF +:1071900081D240E0801B4522C85438E918084402D7 +:1071A000C8488648392018084402C83C38101808D6 +:1071B0009723F006969396DBB69FF281F382F084D4 +:1071C000149F800380068041806C8088F8263805F3 +:1071D0001A0A38051A024E02018684014412C6A416 +:1071E000EB36D5615A1001044800013A5AC0FF1A23 +:1071F000B40D5A080217F0069723969396DBB69FB4 +:10720000F382F08444E2C8B8F281149F80038006C0 +:1072100038271A02806C808849FFFCF338071A0A65 +:107220004402C908381019115EF08032E80F8C2131 +:10723000EBE94412C854382098005A2801083C2D24 +:10724000FC24C204845E38209808B42D4E12011626 +:107250005A180504480001125A18042A4412C8B8E2 +:1072600038109A025A1002045A18081E38F01911E0 +:107270005EF78032E8184412C6A484004422C85441 +:10728000EB36381118005A10FE03F80F4412C8905C +:1072900038109A02541080304E120125B60D380174 +:1072A0001808F8038400B60D4800011D8E21E6225F +:1072B0004EF201194412C8B838109A0244E2C8903C +:1072C0005A1002045A18083938171A02541080301C +:1072D000C13338F019115EF78032E92E4402C854E8 +:1072E000380018005A08FE04480000AB3C0DFA5262 +:1072F0005A0001045A0804095013FFDD96495CF056 +:1073000085FB4EF2009E8E02E602E80F5005FFDD7F +:1073100096015CF009BB4EF200945003FFDD96012C +:107320005CF005FB4EF2008D84204402C8843810C6 +:107330001808480000813C0DFA525A0001045A080E +:10734000040738071A02960FC007D51138071A022A +:107350005400000CC00C802CFD148006F813812012 +:10736000802C80068048806AF806D50E802C8048E4 +:10737000806A800649FFFE3F8120802C800680487D +:10738000F30649FFFE6A2E47EE925A48011022F694 +:107390008004221680068A2FEB63E435E9075A98A9 +:1073A000140385255A08140384054412C8E03820C4 +:1073B0009A11401098408A47EB5196D122208001C3 +:1073C000E3238A4BEB519651E903E201E839442269 +:1073D000C88486203911180804268009EB79E8034F +:1073E0005A48010786034422C848390118083C2D31 +:1073F000FA522F0FF06E5A2001085A20040638570F +:107400001A02974FC50DE3238440E8028442E2014B +:1074100040F83C0440113C043E17F06ED50C40246B +:107420008C06E2019692E80284A240214004FF57B4 +:107430003E57F06E84024412C6A4EB36D503840096 +:10744000B60D2E07F06EE602E94D4402C8E040603A +:1074500018402273000022B30001D5445A18024399 +:107460004402C88438301800B44D8C6196583810E6 +:107470001808C2035A28050784004412C6A4EB3634 +:10748000D5314402C84838001800E220E8252E37DC +:10749000F06EE662E9278A019602964A5A280306A8 +:1074A000002680189696CA1E4422C8E038411A1158 +:1074B000406118402223000198C1FFCC421584246A +:1074C000427200734211007340738CF6EB1D97FB00 +:1074D00040B08011D50784003E07F06E8400380963 +:1074E0001A0AF007ADC012B00001FCE6FC61814051 +:1074F00084C049FFFCE249FFFCE8800A49FFFC58D0 +:107500005095000880E644B2C6A43A048000B04119 +:107510003A0080208041800A96F849FFFDB0B00112 +:10752000EB673A04802038059E02C0038CC197B0F7 +:107530008CE15094804C5A780AEA3E67EEB1FCE147 +:10754000EAF6B42192259657C10DFC0080C0DD46B5 +:107550005A0802082E0728C7C804800649FFFFC83A +:10756000FC80DD9E440395B7A640440395B6A60073 +:1075700040000504DD9E440395B9A600441395B868 +:10758000A64840008104441F6A4488205CF0805A69 +:10759000E903440095BCDD9E440395B4A600EACA05 +:1075A000DD9E440395B4A600EA46DD9E440395B5EE +:1075B000A600DD9E441395BAA6089600C00EA60844 +:1075C00096005A00010BA60896005A000207A6086A +:1075D00096005A0003038400DD9E9600441395BB79 +:1075E000AE08DD9EFC00446395B4AE704412E968B9 +:1075F000B6018401A989102080091000800810308C +:10760000800A1000800B80018024490030E3A630FE +:10761000FC80FC0084414400B100842080628082B0 +:10762000EAB884003C0FFB693E07EEDCFC80FC40BE +:107630002E0728122E2728422E37281342100824FE +:107640003C1B94112E172843924142418424FE1C76 +:1076500092213E2728493C4B94123C0B94223E1722 +:10766000284A4402FE85A640842184C0AE40A6413B +:10767000AF813C6FFB2BEB405000002049003BF2F8 +:10768000EA683C0FFB3B49FFE17B49FFE1CA440349 +:107690008D364412FE5C44238D34B6C1AD90AD806E +:1076A0003C0FFB3144038D303C0FFB4944038D31CB +:1076B0003C0FFB3744038D323C0FFB232E0728B3CE +:1076C0003C1FFB283C2FFB2F3E67EBC75A080106E7 +:1076D000B401EA91B601D504B401EA4FB601B40190 +:1076E000852140002404B601B40184C0EAB2B60189 +:1076F000B4018540EB2EB601B40184E0EA95B601F1 +:10770000B401EA43EA85B601B4013C0FFB4C4403E3 +:107710008D36A440EB91AC40A44066108001AC4093 +:10772000A44066108008AC40A44044038D34AC40B3 +:107730002E0728B83E07EBACEA3A3E07EBB5EA3B2A +:107740003E67EBF63E67EBE73E97E9393C9FFBC6A9 +:107750003CABF61B3EA7EC003E67EBF13E67EBBB94 +:107760003E67EF373E67EB883E07EBB9EA8BEB47A6 +:107770003CABF6133CABF61E3E97EBE43E97EB9A20 +:1077800049FFE466DD403E67EC143CABF6153E670E +:10779000EC15AF813E67EB973E97EBDA3E67EB94D3 +:1077A000AF80DD5484023E67EB8A3C9E00823E67D8 +:1077B000EBBF3E67EF2C3E67EB9F3E67EF2DAE08B9 +:1077C000DD5BAE083E07EBC6EAC53C0803A83C08F3 +:1077D00003AC4402E5603C0E01D54402E3DC3C0FFF +:1077E000FB4284083E07ECE03E67EBA03C7FFB32A7 +:1077F0003E67EBD43E97EBCD3C7BF62D3CABF624BD +:107800003E67EB953E67ED043E67ECE12E072813DB +:107810003E07294580073E67ECE23E67EEED3C7F80 +:10782000FB513C7FFB4A3C7FFB403C7FFB2D3C7F78 +:10783000FB443C7FFB2C3C7FFB573C7FFB453C7F64 +:10784000FB1C3C7FFB24F8028009490075888007F7 +:10785000F8203C0E00C08009F81C3C0E00C18402D8 +:10786000F8183C0E00C28403F8143C0E00C38404D4 +:10787000F8103C0E00C48405F80C3C0E00C58406CC +:10788000F8083C0E00C68407F8043C0E00C78408C4 +:10789000490075743C0E00C83C0394113C0B951CC8 +:1078A0003C0394123C0B95853C03951F3C13951E9D +:1078B000400080203C0B95203C0395883C13958725 +:1078C000400080203C7FFBCA3C0B95893E67EF243B +:1078D000490069A13C0FFB4E49006977EAA93C0EBB +:1078E00002CFEA5D3C0E02D14402C5283E67ED3D61 +:1078F0003E67ED3C3E67ED3E3E600B383C7E02D07D +:107900003E600B483C0FFB52845F3C0DFB4E843FB6 +:1079100038201C088CE65A783CFA3C0DFB4E84C09B +:10792000EB8E1010003D3C6FFBC73C6FFBC83E6701 +:10793000EF313E67EF303E67EF323E67EF333E6731 +:10794000EC843E67EC863E67EC853E67EBE63E677F +:10795000EBF93E67EBB63E67EBDD3E67EBCB3E6790 +:10796000EBE23E67EB8F3E67EBBC3E67EF364900CC +:107970001B323E67EF343E67EBA53E67EBC93E67BF +:10798000EBA73E67EBF0EB40490039DBDD4BAF8006 +:10799000EA365A08010449003F418401EB1AEAAD76 +:1079A000EA6B4900031B84C149000314840044139B +:1079B0008D41AE08EB44EBEB3C1FFB4D842BEB2DD4 +:1079C000842AEAFEEBF63E07EBFE8420440061A821 +:1079D0003C1FFB5884E63C1FFB533C1BF6283E171C +:1079E000EB9B3E17EBB73E100C7C3E100C7D3C0E23 +:1079F000031E8404EB3E3C6E00AC3E17EBBE3C1E07 +:107A000000AD3C7E00AE3C0E00AFDD42C030441005 +:107A10000190440397ECAC404410011D440397EEE1 +:107A2000AC40441000E4440397F0AC40441000C75D +:107A3000440397F2AC40441000AA440397F4AC40CE +:107A40004410008E440397F6AC4044100072440387 +:107A500097F8AC40DD45440397FAAC40EAE844139C +:107A600097FCAC08441397FEAC08D504FD0349FF0E +:107A7000DDB08401EA65EBDB840584C084E0441258 +:107A8000E9A0EA474402DE583E77EBC43E77EBCFED +:107A90003E77EBEE3C6FFB543E77EBAE3C6E032241 +:107AA0003E77EBD93E600C8449FFF20BEB61EA9A1A +:107AB0004402FEFC3E7011313E77EBABAFC0440296 +:107AC000FEFDAFC049000A05EB553C6BF6263E773C +:107AD000EBD73C6BF61C80263E67EB8984463E67FD +:107AE000EE9AAF804402C464EA3D80268446440294 +:107AF000C4D4EA3D44038D45AF8044038D46AF8036 +:107B0000FCC0FC21446200B8800649003424EA2EFF +:107B1000F08149FFEEB89C3449FFEEB8500300787D +:107B200049FFED19500300A849FFEEB3500300CC04 +:107B30004900740FEA2EF0814900740E500300B022 +:107B4000490016BDEA2EF081490016BCEA2EF081EC +:107B500049001EE650030118490000B2EA2EF081E8 +:107B6000490000B1490000CD5003012C49001C71AF +:107B7000507303A0EA2EF08149001C6E8007490073 +:107B80001C6EEA2EF081490051D750030170490064 +:107B900056255003031849006BA2EA2EF0814900D4 +:107BA0006BA1500303644900712CEA2EF081490057 +:107BB000712B5003037449005619EA2EF0814900D5 +:107BC00056188007490067FBEA2EF081490067FAE2 +:107BD000500303AC49002499EA2EF0814900249215 +:107BE000EA89EB56500303D049FFCFDBEA2EF08140 +:107BF00049FFCFDA5003004849004277EA2EF0816E +:107C0000490019E649FFF15B49FFF15A490055E97E +:107C100049006F6249FFCFCB490071FE490056838E +:107C2000FCA1FC00DD54840284C03C6FFBC7AE089D +:107C3000DD5BAE08440000A2EBDDDD40A6015A0882 +:107C40000D118006847F3C2DFB4E843F38310008A7 +:107C50008C065A083CFA3C0DFB4EEB8E1010003D92 +:107C6000490000343E07EF112E07281B84C0520044 +:107C700000013E67EB88490001938401EA773E07E3 +:107C8000EBD1EB58EA363E67EBDE3E67EBAD3E6785 +:107C9000EBF35A080103EA70FC80FC018401EAADB1 +:107CA000EB9844036510EA4D8400EA553C1C01EB57 +:107CB000EB25FA50EB04EB628401FC813C0FFC5194 +:107CC000DD9E3C0FFC50DD9EFC00840084203E07BE +:107CD000F13E3E07F13B3E07F13A3C1BF89C3C1B52 +:107CE000F89B3E17F13D3E07F13C441000408400F4 +:107CF0003E17E9513E17E9503C0FFC52FC803C0D09 +:107D0000FC51A4413C1BF89AA444A6003C1BF899E2 +:107D10003E07F130DD9EFC20A7002E6728195A404F +:107D200001078480447200008204D52A4442040181 +:107D300084A0D608087200018CA110727FEA9768AF +:107D4000D5F92E4FEEB14E46000C3C4DFB28B4A4A5 +:107D50003C43983E4252880B5A580125D5198EA1B2 +:107D6000976844720000E0A4E9F19BAC88C7010366 +:107D700003EC99BD8EA1110303EC9768D5F59760CC +:107D8000E2A6E8E49967110283EC8C81D5F98C8F27 +:107D90003C5003A89721E285E80B5042800F9721C1 +:107DA000D5072E57EE915A58010444400050A600C2 +:107DB0005A0801472E07EBF09A10E402E8052E0757 +:107DC000EEEE5A08010A5A3801082E07F14CC8088D +:107DD0003E37F14CD50484003E07F14C84608400AA +:107DE0003E07EBF0A609C82F2E0728C35A0801103A +:107DF0005A3001085A28010C3C03F652E614E907F0 +:107E00003C0003A88C0F3C0B9605D5033C4B960514 +:107E10002E07EE90C0185A080105EBF28E14D5110A +:107E20005A080205EBF28E0AD50C5A080305EBF24C +:107E30008C0AD5075A080408EBF28C14D50284008A +:107E40003C0B9605FCA0FC003C1DFA4BA6088C01DF +:107E5000AE083C1DFA4BA6089604C8063C0DFA4D28 +:107E60003C0FFA4AD5053C0DFA4C3C0FFA4A3C0D42 +:107E7000FA4AA6481010003F80A08420EAF2500081 +:107E8000003CEAF2D8FFFC803C2DFA4AA65098D17B +:107E9000AE199C0996005CF0003BE9028400AE102C +:107EA000A6108840841FAE11DD9EFC00EA722E579A +:107EB000EEA8D00BC804EB59DD41D50444000051B5 +:107EC000DD41EA723E07EEA8EBAF2E57EEA9D00CCB +:107ED000C80544000054DD41D50444000053DD4191 +:107EE000EBAF3E07EEA92E07EF112E57EEAAD00CEE +:107EF000C80544000056DD41D503EA3BDD412E07AD +:107F0000EF113E07EEAA2E0016FD5A00AA048407C0 +:107F1000DD41FC80DD9EFC0049002D69FC804410A1 +:107F20000055DD43AE40DD9EFC03F0818005F28309 +:107F3000F182F384F48549002CD0F002F10349006A +:107F4000306FDD45DD43AE40F001F104F20549003C +:107F50003007FC83FC2084C080E0E2C7E80B84018A +:107F6000844080208062808080A28CC1DD5797B0E1 +:107F7000D5F5FCA0FC0049003125FC80FC0049003F +:107F80003113FC80EB37C8082E17EE96C907FC00AA +:107F900049003123FC808400DD9EDD9EFC00490009 +:107FA0002C8EFC80EB32C80FFC002E07281B4900EA +:107FB0002C86FA09EA322E07281B520000014900DC +:107FC0002C7EFC80DD9EDD9EFC00490031D5FC80CE +:107FD000FC00490031C7FC8044130FA0B6204413B5 +:107FE0008068A845441373E8A846EB43A8424413AD +:107FF0000C80A84444133F9050200044B622441201 +:108000003200A851441274F8A853DD9EFC4480C08D +:10801000440178103B004C0044017820EBF9B1C4D6 +:108020003B004C003B03CC20EB762E172C92813F7B +:10803000420004019640C1038E219648EB068386D8 +:10804000B88A38038602B88B442000C84402DB3467 +:1080500042008873B89344031F40B88944038DD409 +:10806000B88CFCC4FC20842CAE4184003C0FFB7413 +:10807000EA9349FFDD87EABC3C0DFB74C00B84200A +:10808000846184028041808380A33C1FFB74DD57A0 +:10809000FCA049002D435A0801F4AFF0D5EEFC00D6 +:1080A00049002D33840149002D35FC80A4408C21EA +:1080B00096495CF08190AC40E909FC008405DD4103 +:1080C0008400EA26EAA8EA6AFC80DD9EFC20FD30F6 +:1080D000DD42C01FA770DF0A8CA19768E6A5E90200 +:1080E00084A0EA3AAF70EA8BD50D8406DD414413D3 +:1080F0008D20A6088C019600AE088400EA26EA3B93 +:10810000EA6A44038D20A600C00484013E07EF32D2 +:10811000FCA0A6885A28AA0AFC00A680AE88842063 +:10812000AE40490030D2FC80DD9EFC00EA3F5A0898 +:108130000417DD465A000214EA9C5A080111840013 +:108140003E07EB888400EBB5EAED4402C39C49FF8F +:10815000FFE2840384203C2DFB23EBDEFC80A68819 +:108160005A20AA10FC00AE80442FFFAAAE88A600B9 +:108170005A080105490030A3FC80490030A6FC8064 +:10818000DD9E8440AE808400AC08DD9EFC005A0871 +:10819000010549002EE3FC8049002EE1FC80FC0033 +:1081A00084204403F560AE4084234403F561AE406F +:1081B0008400802080408060EA2BFC80FC008423C7 +:1081C0004403F560AE4084204403F561AE40840072 +:1081D000802080408060EA2BFC80FC004402FE632B +:1081E000A7404403F007A600D8084402FE64A74055 +:1081F0004403F004A600D006441FFF8EEBBEAE4041 +:10820000F80A4403F007A6005A002311441FFF9EFA +:10821000EBBEAE40843F4402FE61AE408420840247 +:1082200080418461808180A1DD57FC80FC24440171 +:1082300078403B004C0044217850EBF9B004EBB19E +:108240003B004C2044238D41A6904411D80040109F +:108250008840A6C838500A028400384F8A0296D84F +:108260004462623880E03C139422E201E818402323 +:108270000020030100003812800042180424390253 +:10828000010140108C0E8A309649AC50A450964B98 +:108290004E140003ADD08C019601D5E6FCA4FC0180 +:1082A000F08194918001F101DD48FC81FC064422BB +:1082B0000000FAD0A6D2A71384A18440F68584C218 +:1082C000F283F284F286F288F289B67FF581F38236 +:1082D000F687F58A8041EA44FC86FC00C805EAB0CE +:1082E000EAB6EA4DFC8049FFD0D080A0C8F9EAB0D8 +:1082F0004413000244226238EB572E4728134900EA +:108300002992FC80FC00DD5280C0A64949FFFFE7AE +:108310005A680306EB32C80349FFFF8AFC80FC263B +:1083200097D0FA5084C084A1F28584429718F287CE +:10833000B6FFF581F782F683F684F686F688F6892D +:10834000F58A80418067EA44FCA6FC0644420000AE +:10835000A7A284A0A723F581F582F583F584F5868D +:10836000F588F58984A1F285F387B6DFF58A804127 +:108370008066EA44FC86FC07F38DFA7084A0808254 +:10838000F38584418462F281F482F387F28A806407 +:10839000B6BFF583F584F586F588F5898041F40D3F +:1083A000EA44FC87FC01EB7BEB43EA4D4403651098 +:1083B000EB98EA4D8400EA553C1C01EBEB25FA50A2 +:1083C000EB04EB62FC81FC08F18EF08D8023F28FD0 +:1083D000EB57C4052E4728138003D50380048481FE +:1083E00084A1B61FF0828400F083F184F085F086CA +:1083F000F088F089F08AF581F587F00DF10EF20F23 +:10840000EA44FC88FC01DD465A08021A8400EA5559 +:108410008481EB7BEB43442373E8846049FFFFD501 +:10842000501F8006EAC684408463EBB6220F8003A7 +:1084300044100096EB3C40008007FC818400FC81E6 +:10844000FC2544620000A7F2A7B3F381B0C7F38410 +:108450008460F482F583B6DF808380A749002753C8 +:10846000FCA5FC008401842049002DE244000CD5C9 +:1084700049002DE6FC804403F01F4423F302A600CC +:10848000A650540000E096678C225EF08020E8073A +:10849000A650966788018C029600D5038C1F960023 +:1084A0004413F01FAE08DD9EFC00840080204900CC +:1084B0002A2049002ED7490035A849FFFFD449FF9B +:1084C000FFDC49002D4A490027EF49002F2A4900C7 +:1084D000295C4900290549FFC084FC803C03F4AABB +:1084E0003C1DFA564423F540B4423820820A442306 +:1084F000F544B4629C819691EAC04423F548B46285 +:108500009C829691EAC04423F54CB4629C83969178 +:10851000EAC04423F550B4629C849691EAC0442397 +:10852000F554B4629C859691EAC04423F558B46230 +:108530009C869691EAC0502000083C2BF4AA8C0738 +:108540004423F55CB44296013820820ADD9EFC018A +:108550005A0801163C0DCA21B61F3C0DCA22F081F3 +:108560003C1DCA1C3C0DCA1B3C2DCA1D3C3DCA1EED +:108570003C4DCA1F3C5DCA20F815D516C8153C0DE8 +:10858000CA19B61F3C0DCA1AF0813C1DCA143C0D15 +:10859000CA133C2DCA153C3DCA163C4DCA173C5D5A +:1085A000CA1849002ABFEADA5A0801093C03F4AAAA +:1085B0005CF00080E80349FFFF9384008020804046 +:1085C00080604900289D49002878FC814423F07789 +:1085D000A6509604EAD9FE0FAE10DD9EFC2080E086 +:1085E00080C1DD46A6B9C80650017FF6E6028409BF +:1085F000E9028002EA28EA40AE884423F380A650CC +:108600005A1001FF4E6300668E01E60E4EF200CA5C +:1086100044F0841CEBAC40F03C00DD0F1C008401F6 +:108620002200AC002200AC00AC00280028005E0054 +:108630005E00AC002200A8008403EA98F848840099 +:10864000F895F84584014900293F8400F895EA8CA3 +:108650005A0801064400088EEA32D5088440840195 +:1086600084248062808280A0DD578401EAD784015F +:10867000F88ADD46C82AEBDCD528EAE9C005EADA43 +:10868000C0038400EB608401F87E8400F875EA8CF6 +:108690005A0801064400088EEA32D5088440840155 +:1086A00084248062808280A0DD57EBDC8400F85E49 +:1086B000EAE94E020077EADA4E0300748401EB60C7 +:1086C000480000708401EAD78400EA984800006AF4 +:1086D0005A6801628E03E60CE86444F084E8EA7F9D +:1086E00040F03C004A003C000C120C1212181870AA +:1086F00070B80C8C8401F83AD5548401EA98D551AD +:10870000EAE9C011EADAC00F8400EB603E07F02806 +:108710003C03F4AA3C1DFA568E019402B601840172 +:108720003C0BF4AAEAE9C80D8401F8268401EA9812 +:1087300044000037EA328400F8268400F829D53155 +:10874000EADAC8F33C5DFA5684213E17F14D501227 +:108750008200AA29D9FFD5E9EADAC005EAE9C0030F +:108760008400EB608401F808840149002BA6EAE943 +:10877000C8A3D517840149FFFEEC49FFFD1284010F +:10878000EA98840049FFFF248400EAD78400490066 +:10879000289BD5075A6802068401EA988400EAD724 +:1087A000FCA0FC40EA3F80C15A08040BEA9CC008C8 +:1087B000DD465A080213842049FFD1EAD50EDD4672 +:1087C0005A0002F88401DD4F8420846184028041D4 +:1087D000808180A3DD57D5F48402DD4F84414400BD +:1087E00001A04410003080628082EAB88420846155 +:1087F000440001A080418083EAB85A00300E8441D1 +:108800004410003080628082440001A0EAB8440035 +:1088100000D7DD41D5ECEA3F5A080410DD465A0086 +:10882000020D2E7728AB5A7801098007490029727A +:108830008400EA268007EBD7EA6EEA743C0DFB74ED +:10884000C0078404DD4FEA3F5A08041FD5094900D8 +:1088500029655A0801F88403DD4FEA53D5F0DD4657 +:108860005A000213EA9C5A080110840049FFD948B3 +:10887000441FFFC34403F429AE40DD408420DD568D +:108880008402AE31D50F804684058420EBDEDD40C6 +:108890008420DD568402AE31840149002B2D8405ED +:1088A000DD4FFCC0FC20EB015A080152DD46C84FE9 +:1088B000DD59A6405A1801FFA6005A080149DD4CAF +:1088C000A78097B05A680144DD408429AE418420D6 +:1088D000DD56DD40842AAE41DD4280E0DD59C70D22 +:1088E0008420AE40DD4CAE408006EA268409EA2CA6 +:1088F0002E07EE99EA6CD52BAFC0DD4CAFC08006D9 +:10890000EA264402FEF2AFC0DD45DD43AE40EAA5F3 +:10891000C0FF49FFD8ACEA21EA8AAE0880418461F1 +:108920008402DD44DD40EB8ADD4C8421AE408401CD +:10893000EBFD5A00010DEA9C5A080108DD40A60132 +:108940005A080A0449001F9F8400EA63FCA0FC4304 +:10895000441178608140A600B1823B00CC003B030B +:108960004C2085205A08010549004151812084008E +:10897000EA5584E0EB3038031E02842094918CE1A8 +:10898000EA3D5A7804F9EAAB5A08011C8403DD5227 +:108990008049EA4AEAA12E17EBA4440000C8FE0C65 +:1089A000EA55EB43F80344130FA0EB252E272812BA +:1089B0002E372813EB6249FFFF77DD54A608C8FF66 +:1089C000DD45DD43AE408400FCC3FC2184C0FA00D9 +:1089D0003E67EB8B44738D40DD414900317F84015C +:1089E0003E67EBD03E07EB9E3E07EEEA3E67EF02A6 +:1089F0003E67EBBA3E67EBBDAFB8DD46DD525A08C5 +:108A0000020B8404AE0980018420DD56DD40842DF4 +:108A1000AE41D50A8409AE0980018420DD56DD40CF +:108A2000842AAE41AFB8DD598421AE40EA365A08F7 +:108A3000010EDD4BA6003E07EBD2EBAEA6003E07D3 +:108A4000EB98EBB9C8033E07EF02DD40A6013E07F5 +:108A5000EBEB8406DD4FEB05C814DD40EA342E074E +:108A600028B65A08010449001BE7840ADD4F490073 +:108A70001C55EA36C04BDD465A080249840BDD4FCF +:108A8000EA365A080110DD42C00DEB055A00010517 +:108A90002E07EBBAC8074402C6F2501F800749FFF1 +:108AA000FF58EA365A08012BEB05C80B4400006654 +:108AB000DD4F49001CA75A08010C3E07EB8BD50877 +:108AC00044000067DD4FDD54A6085A0801FF44004A +:108AD0000068DD4FDD42C008EA305A0807FFEAB0FF +:108AE000EAB6EA4DD505DD54A6085A0801FFDD5463 +:108AF0008402AE08DD5BAE08D509DD42C007EAA8F6 +:108B0000DD4FDD4BA60049FFFBFF84003E07EEEA88 +:108B1000DD46DD522E27EBEB5A0802089E12E602D4 +:108B2000E806840DAE09D5075A200204AE89D503A4 +:108B3000840BAE09DD40EA348400EA45EB5E3E0773 +:108B4000EBA03E07EB9E84C14400006ADD4F3E6708 +:108B5000EBBADD42C00349FFF8A23E67EBB2DD4647 +:108B6000C80484013E07EEE44400006FDD4FFCA121 +:108B7000FC00EB015A08011FDD46C81CDD59A64068 +:108B80005A1801FFA6005A080116DD4CA78097B0BD +:108B90005A680111DD408429AE418420DD56DD4054 +:108BA000842AAE41DD548400AE08DD5BAE08800649 +:108BB000EA26FC80FC00DD40A6415A10061C2E1758 +:108BC000EB9DC9182E67EBF7CE15DD54A6485A1851 +:108BD0000112DD5BA6485A18010E8026EADBDD563D +:108BE000DD59AF802E07EBDCC803DD5BAE088401E6 +:108BF000EA26FC802E07EBAF8421EB49DD9E44037F +:108C0000F07FA600EA57DD9EFC0049FFFFFAFC80DA +:108C1000FC4080C2812080E1EB8249002B984420F7 +:108C20001900FE14E206E8138AC0442186A04023FE +:108C3000085710248000440E7960969042610073BA +:108C400044001388406300D7AFB8FCC084201014E0 +:108C50008000AE78FCC0FC00EB82EBE6FC80FC01FF +:108C600080C08001F281EB6FF001EB7284013E075E +:108C7000EEE6A6303E07EEE58400EBFC8401EAFC5C +:108C8000F8F12E07EEE65A08010984408020806240 +:108C9000808080A2DD57D5F6FC81FC0080C0800179 +:108CA000A648C1058421442000CDF807A630C0079E +:108CB000800684244420008249FFFFD38407EB6FA1 +:108CC0008400EB728400EAFCFC80FC20A78080E03A +:108CD000E6CBE9068ECA840A97B0AE38D50284C0C6 +:108CE000A638C0038C01AE38A638E603E9038C0130 +:108CF000AE38A638C8038401AE38A608C004EA6FAF +:108D0000FE0CEA32C6059431EAA649FFF925A67899 +:108D1000C107844084028461848380A2DD57FCA063 +:108D2000FC02F08180C1F80CF201F8725A68020965 +:108D300084013E07EEE0EAF5EAFDF862D505EAFDBA +:108D4000EAF583FFF869F88EFC82FC21FD30F281A0 +:108D5000DD46C82C5A700907461000F450008240C6 +:108D6000D505461000C3500085005A60011DC60499 +:108D70005A600205FCA1F876FCA12E27EEDF2E3703 +:108D8000EEDECA02C310441186A0FE5C846AEB1DAD +:108D9000443FE70042010C738A0184203E17EEDE57 +:108DA0003E17EEDFF10149FFFFBDFCA1FC2080E092 +:108DB00080C1DD465A08020ACF1ADD40A6415A108A +:108DC000041349FFFEF9D513DD40A6415A100B10DC +:108DD0005A6004068006844349FFFFB9DD40A6417E +:108DE0005A180904EBEED50349FFFEC4FCA0FC02AF +:108DF000F081EAF5EAFDF201F80BEAFDEAF549FF38 +:108E0000FF66FC82FC02F081EAF5EAFDF20149FF0F +:108E1000FF01EAFDEAF549FFFF42FC82FC00460043 +:108E200000A650000040F80DFC80FC00F81BFC8000 +:108E3000FC00F818FC80FC00460000A65000004032 +:108E400049FFFFD7FC80FC00EBF4EBD6EB4FFC8036 +:108E5000FC00F808FC80FC00EBF4EBD6EB4FFC8048 +:108E6000FC0049FFFEFAFC80FC00EBF4EBD6EB4F74 +:108E7000FC80EB34DD9EFC2080E180C2C00D5A00F6 +:108E8000041184003C0BF61F49003588444395AC1F +:108E9000443395AAD50A444395A6443395A4D505F1 +:108EA000444395AC443395B084009680E246E8078D +:108EB00038138101381201098C01D5F83C03F61FE3 +:108EC000AC18FCA04422FF5038100808DD9E445224 +:108ED000FF5084204402FF70EAF2D8FFDD9E3C037D +:108EE000F8A88C0196015CF000FFE90284003C0BBD +:108EF000F8A83C13F8A84402FF52AE40DD9EFC40A7 +:108F000049FFD749EA3F9E46E622E90A50107FF71B +:108F1000E625E9065A001105840148000074DD4089 +:108F2000A6015A0804148404441000BDDD4744001F +:108F300000D0DD4FDD42C01F840049FFCF4C8401CB +:108F4000DD4AEAA7EA6EEA74D50B8E08E604E9EC7E +:108F5000DD465A0802EAFA31EA67AE40D521A6306A +:108F60005A002105EB19EA53D5FB8402DD4A84003F +:108F7000EA63D5162E07EFAEC808840244139700A3 +:108F800044238D54EA87EA628406DD4AEA21FA1115 +:108F9000AE08804184028461DD448400EAC7840312 +:108FA000DD4ADD4084C0A601DD4A490024BB4400FF +:108FB00000D1DD4FDD469E4240130406840249FF86 +:108FC000CDE7DD465A08010B800649002777800669 +:108FD00049002792800649002785440000D2DD4FD2 +:108FE000DD40EBCF3C2DFB284432C520490041AD8C +:108FF00080C05A00080448FFFF91440000D3DD4FB1 +:109000008006FCC0FC4049FFD56149FFF31249FFCF +:10901000FA4DDD4084C1AF8149FFF575440000A0E1 +:10902000EBDDEBE7DD5249FFFBBE44000051DD4FB5 +:10903000EA6EEA7449FFFDE5C8053E67EF0DEA53A5 +:10904000D5FA84003E07EF0DEB59DD4FFCC0FC0064 +:10905000840FDD41840444100062DD47DD45DD43BB +:10906000AE40EA80A608C8FF44000082DD4F4400FD +:109070000083DD4F840149FFD6F444000084DD4FB6 +:10908000FC80FC00840444100061DD47441000674C +:109090008404DD478404EB0B440000A1EBDDDD40DC +:1090A000EBC6EAC9EBCA848049FFE1B9EA6D5A0808 +:1090B00001094402C378EB5D49FFF86549002905C1 +:1090C000DD548402AE08DD5BAE0849FFFFC28404B4 +:1090D00044100068DD4749FFFC7AEA6D5A08010434 +:1090E000490028ED49FFF59F8402DD4184044410C6 +:1090F0000069DD47FC80FC00EBDF80C0840CDD4FA5 +:1091000044038D47A6408C219648AE40DD45DD43A3 +:10911000AE408409441000A1DD4749FFF8088409E6 +:10912000441000A2DD4749FFDA9E8409441000A3E1 +:10913000DD47DD40A6415A100D0B2E17EF2CC90755 +:109140004412C3ED4422C700490042388409441048 +:1091500000A4DD472E07EBA05A080107FA05DD4100 +:1091600084C2480000EC8409EBB2DD472E07EE9B79 +:10917000C00AEA7EA6405A102105A6005A08220419 +:109180008401EA33DD555A08190449FFDAC9EBE0D6 +:109190005A08011CEA305A0807198400EB58EA36CD +:1091A0005A080112DD4BA60049FFF92E5A080107A3 +:1091B000EBB95A0801043E07EB8B2E07EB8BC0037B +:1091C000FA06DD418401EAAD84003E07EBC12E07BB +:1091D000EC03C810EA305A08070E840AEA3EDD5252 +:1091E0008401EA333E07EBC1DD4BA600A64949FFE7 +:1091F000F8762E07EBF65A08010C4402C3E6EAF6AD +:10920000EAC93C3DFB313C4DFB2F49FFDB85DD428C +:10921000C013840C00130050DD47840D001300516F +:10922000DD47840E00130052DD472E07EB8F5A08EE +:1092300001048400EADD3C0DFB5A5A080142DD5965 +:10924000A60096005A08013D84203C1FFB5A2E17A9 +:10925000EBF25A18551B2E17EE9CC104EADDEAE723 +:10926000D516EA7EA6005A08130544000086DD41A3 +:10927000EBE7DD524422C39C3C3DFB284442C52021 +:1092800049FFDD70EAE7D503EA3BEB47DD5549FFCF +:10929000D87796003E07EB9ADD4A2E67EB9A5A6024 +:1092A000034E5A68020EFA04DD412E07EC0ADD4136 +:1092B000DD45DD43AE40DD54A608C0FFD53FDD549B +:1092C000A6085A08020EDD4CA6005A08020A8401BC +:1092D000AE08DD5BAE08DD46C80349FFFDC7DD40D3 +:1092E000A6015A080A08DD46C80349FFFDA049FF48 +:1092F000FADB2E07EBC15A08010DDD4BA6005A0818 +:109300000309EB32C80684023E07EBC149FFF79020 +:10931000DD555A080404490036752E07EBF384C165 +:109320005A08010D84003E07EBF3DD5BA6089600AA +:10933000C8FE8441AE88FAC3EA338006FC80FC0193 +:10934000EA6D5A0801064402C3788420EB0FEA361E +:109350005A08010449003878DD4BA6005A08030C6E +:10936000EA365A080109490034DD84023C1DFB2716 +:10937000F80ED50F490027F2F081F1018400F807BB +:109380002E07EE915A0801068402842F49FFF61E2B +:10939000DD40A6415A180D048423AE41440000A3C9 +:1093A000EBDD2E0728AD5A08010BDD40A6005A0858 +:1093B0000107DD4BA6004900291BD504EB7BEB9888 +:1093C000EA4DEA6B4412C46C4422E2F444320000D9 +:1093D0004442DF4049FFE2ECFC81FC002E0728AE4E +:1093E0005A080108EA6B4412D82849FFE240D50523 +:1093F0003C0C01DDEBB0EA4D2E0728C35A08010EE4 +:109400004402C6E44412C6E24422C6E04432DF4CC1 +:109410004442DAF049FFEA90EA89B400EA465A0089 +:10942000010384003C0FFB2B84013E07EF3ADD551E +:109430005A081209EA718421EA9E5A080104EA4C8A +:10944000EA5C2E17EBAC5A1801054402C378EB0F07 +:10945000DD555A08120AEA718422EA9E5A0801056B +:109460008402EA4CEA5CFC80FC0049FFFD04C00376 +:109470008401FC80EA88C004DD5A5A00020B4403D0 +:10948000307049FFE546C0F5FA18EA9A8403FC807B +:109490008404FC80FC6680C0EA382EA728122E8740 +:1094A00028352E9728342EB72813C00944C3343CDE +:1094B00044D333D844233374EBB4D50844C21B30AF +:1094C00044D219A044221810EB14CE2F84E1FB7073 +:1094D0008522806A808880A78041F80B44034C1065 +:1094E000EA44EB16EA2744035890DD48802D804D6E +:1094F000B75FF78114AF8002F683F68414BF80054E +:10950000F686149F8007F688F689F78A83FF44035E +:109510004F30806A808880A7EA4444134F30EA279E +:1095200044035BB0DD48FCE65A68012F84E0FB1081 +:10953000854280228069808B80A644034DA0F80B71 +:10954000EA44EBA4DD5D44035A20DD48440350C0E7 +:10955000802C804CB73FF681149F8002F783F784FC +:10956000148F8005F78614AF8007F788F789F68A8D +:1095700083FF8069808B80A6EA4444035D404413E6 +:1095800050C0DD5DDD48FCE6FC004E02005DEAC631 +:10959000EA275A181421EB16DD4844134F30F820FF +:1095A00044129ECAF823440383884412A1EAF82D8A +:1095B000EA38C003EBB4D502EB14F826EA38C0044D +:1095C000441333D8D503441219A0EA2744037D4835 +:1095D000DD48FC8044135890DD4844135BB0EA2713 +:1095E00044037708DD484412A50AEA27440380684B +:1095F000DD48440383884412A82AF807EA38C003E8 +:10960000EBB4D502EB14EB80EA27DD48EA38C0045E +:10961000441333D8D503441219A044037D484E00A7 +:10962000FFF5441386A84402AB4AF86AF8064402E0 +:10963000AC12441389C8F8643B0054003B00D420AA +:1096400083FFFC8044037578DD5D5A181420EBA479 +:10965000DD48441350C0F81F4412A05AF8224403B6 +:1096600085184412A37AF825EA38C00444133374E9 +:10967000D50344121810F826EA38C0044413343CC9 +:10968000D50344121B30F829FC8044135A20DD48CE +:1096900044135D40DD5D44037898DD484412A69A8A +:1096A000DD5D440381F8DD48440385184412A9BAFE +:1096B000DD5DDD48EA38C00444133374D503441239 +:1096C000181044037BB8DD5DDD48EA38C00444135C +:1096D000343CD50344121B30DD5D44037ED8DD48A5 +:1096E0004423883880224402ABAEEAA344238B583B +:1096F000EA7CF806F8084402AC768022F801EAA376 +:10970000EA7C83FF3B0050003B00D02083FFFC80BD +:10971000FC40C8053C5DFB47C508D53F5A08013EE3 +:109720003C5DFB475A58013A2E57EB9984C38EABE8 +:10973000E2C584C0E9052E67EB998ECB97B1C008CE +:109740005A08010B4470003280A78604D508FAF04D +:1097500084A68207D50484E080A782078124EAC614 +:109760004440019042581424420310735A181406BE +:10977000802294A9DD48D504802394A9DD48EB0715 +:10978000EB804203047394B98029DD482E07EB99DE +:109790005A080E048408EAF8FCC09200FC012E2747 +:1097A000EBBE5A200704480000A7E6104EF200A4C2 +:1097B000F18144F095C03817810140F0BC00DD0F05 +:1097C00020002000200020004C0060007400860073 +:1097D0009800AC00C000D400E800FA000C012001A1 +:1097E0002E57EB998C0B4C504087EA30C80484010B +:1097F000F101F807EA305A000103F8078400F1018B +:1098000049FFFEC48408EAF8480000768400F101AC +:1098100044234C10443358904442AB4AF86AD56B09 +:109820008401F10144234DA044335A204442ABAE9D +:10983000F860D561442216808400F10180624442C0 +:10984000AB4AF857D558442218108401F1018062C0 +:109850004442ABAEF84ED54F8400F10144229ECA7B +:109860004432A50A4442AB4AF844D5458401F1018B +:109870004422A05A4432A69A4442ABAEF83AD53BB1 +:109880008400F10144234F3044335BB04442AC12B6 +:10989000F830D5318401F101442350C044335D4098 +:1098A0004442AC76F826D527442219A08400F10161 +:1098B00080624442AC12F81DD51E44221B30840144 +:1098C000F10180624442AC76F814D5158400F101B0 +:1098D0004422A1EA4432A82A4442AC12F80AD50B29 +:1098E0008401F1014422A37A4432A9BA4442AC76FD +:1098F00049FFFF10FC819200FC602E4728122E27A2 +:1099000028352E3728342E1728134E0300F4423200 +:1099100008244052040990618020449320D044A33D +:10992000226044B3271044C328A045234C1045337C +:109930004F30E023E82C4020949797209489CC0264 +:10994000961040412400A5208C2141120011404175 +:109950002800A52096484102001140412C00A5E0B6 +:10996000884C9501A590402248001311000098856D +:1099700094914111480097FB97B3889388538C01C9 +:10998000130880009600ADE0AD90D5D4EAAA5CF053 +:1099900000A04EF301585A00A0095A00A10B4462DE +:1099A000A1EA44129ECAD50844634F30EB16D50491 +:1099B000446219A0EB142E07EBA2E602E82D3C0D41 +:1099C000FB4B5CF01388E90584003C0FFB4BD5048E +:1099D0008C013C0FFB4BEA27EAC6DD488026EA27CC +:1099E00044037578DD48441000C144037572AC40EF +:1099F000EB28A400441375749603AC08EAE5A400B0 +:109A0000441375769603AC08442373E8EB16EA22F8 +:109A10008402EA62F8719E82E642E821EA27EB803E +:109A2000DD488026EA2744037BB8DD48441000C2A5 +:109A300044037BB2AC40EB28A40044137BB49603F0 +:109A4000AC08EAE5A40044137BB69603AC084423B3 +:109A50007578EBA4EA228402EA62F84E9E84E6421C +:109A6000E823EA2744038068DD488026EA27440388 +:109A700081F8DD48441000C3440381F2AC40EB2878 +:109A8000A400441381F49603AC08EAE5A40044134F +:109A900081F69603AC084423770844134F30EA223A +:109AA0008402EA62F8298E06E6024EF200CCEA272A +:109AB000440386A8DD488026EA2744038838DD4829 +:109AC000441000C444038832AC40EB28A400441383 +:109AD00088349603AC08EAE5A4004413883696035C +:109AE000AC0844237898441350C0EA228402EA6206 +:109AF000F8035A000104480000A640518409FECC36 +:109B0000842090618001449323F044A3258044B3D2 +:109B10002A3044C32BC045234DA0453350C0E00339 +:109B2000E82C4020149797209481CC029650404115 +:109B30002400A5208C014112001140412800A520DD +:109B400096004102001140412C00A5E0884C950987 +:109B5000A5904022480013110000988D9491411166 +:109B6000480097FB97B3889388538C211308800093 +:109B70009648ADE0AD90D5D4EAAA5CF000A0E962C9 +:109B80005A00A0095A00A10B4462A37A4412A05AB9 +:109B9000D509446350C0EBA4D50544621B30441280 +:109BA00018102E07EBA2E602E812DD5D44037708E9 +:109BB000DD488026DD5D44037898DD48441352502B +:109BC00044237A28EA228402EA62D53C9E82E64255 +:109BD000E812DD5D44037D48DD488026DD5D4403F9 +:109BE0007ED8DD48441353E044237BB8EA22840244 +:109BF000EA62D5289E84E642E812DD5D440383884C +:109C0000DD488026DD5D44038518DD48441355702A +:109C100044237D48EA228402EA62D5148E06E602D5 +:109C2000E811DD5D440389C8DD488026DD5D44031D +:109C30008B58DD4884024413570044237ED8EA221F +:109C4000EA62FCE084004412DFD4804038208109BD +:109C50008C014432DFD45A08C0FB840080409858FD +:109C60008C02122080C85A0990FCFC203C4C01DD7B +:109C700084A084C344700640A4205412801F402254 +:109C8000A009402088A096033901890140001816D8 +:109C9000881038018909400294090A2200019402BF +:109CA0004000047C9693500000C8401118363821BB +:109CB00081018CA18822976938118109DFDEFCA01F +:109CC000FC662EA7281280C02E8728352E972834B0 +:109CD0002EB72813C0035A08010449002388EA3824 +:109CE000C00944C3343C44D333D844233374EBB465 +:109CF000D50844C21B3044D219A044221810EB14DA +:109D0000CE2284E1806A808880A7F80644035890B8 +:109D100044229ECAEA44B75FF78114AF8002F683FB +:109D2000F684F685F686F787F688F689F68A83FF45 +:109D300044035BB0802D4422A1EA806A808880A71A +:109D4000EA44FCE65A68012384E0802244035A2056 +:109D50004422A05A8069808B80A6F802EA44B73F6B +:109D6000F681149F8002F783F784F785F786F687DC +:109D7000F788F789F78A83FF44035D40802C4422EB +:109D8000A37A8069808B80A6EA44FCE6FC2080C030 +:109D900080204402D82849FFDC4BCE584452A50A03 +:109DA000443D5AF64442DFD484E34422A68A982BE9 +:109DB00038120011A4284462DFD49603E020E90899 +:109DC000EA3CC802EAB9A4288A019603AC288CA20E +:109DD000DAEF848180A44402A50A4432DA28842080 +:109DE000EB2FF8BC84003C0FFB3C3C4C019A80609C +:109DF00080A02E20111D9860C20FA48896934E2734 +:109E0000000CA48850217FCE9693AC88A4889693AA +:109E10004E240003AD48A4488C02964B88615A0832 +:109E200040EA84403C3FFB3C4402DE58806284218F +:109E3000F85BEB2F8400EBCDF8964452A82A444DF2 +:109E400057D684604422A9AAD55D5A60010448000F +:109E5000008D4452A69A443D5AF64442DFD484E32E +:109E60004422A82A982B38120011A4284462DFD477 +:109E70009603E020E908EA3CC802EAB9A4288A016E +:109E80009603AC288CA2DAEF84214402A69A4432CD +:109E9000DA28808180A1EB2FF86184003C0FFB4819 +:109EA0003C4C019B806080A02E20111D9860C20F49 +:109EB000A48896934E27000CA48850217FCE9693B9 +:109EC000AC88A48896934E240003AD48A4488C0225 +:109ED000964B88615A0864EA842180413C3FFB48E4 +:109EE0004402DE58846049FFE069EB2F8401EBCD2A +:109EF000F83A4452A9BA444D57D684604422AB4A3A +:109F0000D51A802538009005381304119603E020F7 +:109F1000E902ACE88CA2DAF6842080814402A82A07 +:109F2000EB424432D9B084A1F8198400EB65EB42CE +:109F3000F81AD51B802538009005381304119603B4 +:109F4000E020E902ACE88CA2DAF684214402A9BA46 +:109F5000EB4280A14432D9B0848049FFE38184017F +:109F6000EB65EB4249FFE110FCA0FC004432C3B2B8 +:109F70004402DA28EB65EB1249004036EA5DEBCD8E +:109F80002E27EBC249005DADEA5DEBCDEB2F84617E +:109F9000F805EB428460EB65EA5D49FFBE41EA5D8E +:109FA000490045232E17DDC1EA5D4900603AEA5DAC +:109FB0004900524BEA5D49004561EA5D4900556937 +:109FC000EA97C0035A08050D84013E00111E3E00A9 +:109FD000111D84003C080891841F3E0011192E00B9 +:109FE00011195A00FF0684003E001154D504840163 +:109FF0003E001154EA5D2E17DDC14900610E840157 +:10A00000FC80FC002E07EBADC803EA33D5068401C3 +:10A01000EA3384003E07EBADDD555A08120AEA71B7 +:10A02000842FEA9E5A080105840FEA4CEA5CDD4C55 +:10A030008421AE40EA9C5A080108DD40A6015A0876 +:10A040000A0449001420FC80DD9EDD9EFC002E07E2 +:10A05000EBC7C8412E67EB8B5A68010BEB41C80870 +:10A06000490055E5C805EAF9C8033E67EC00EA7205 +:10A07000C81EEB41C81C2E07EC00C8192E07EB8B3D +:10A080005A000116490006DD5A080208FA02DD41AD +:10A0900084013E07EC00D50B4402E2F43C13947EAD +:10A0A0004422C3E149000DD65A0002F2DD40A64128 +:10A0B0002E07EC005A1006045A180B105A0001091A +:10A0C0002E07EF365A0001052E07EBF1C00484017C +:10A0D000EA49EA778401D5245A00010A2E07EF36AF +:10A0E0005A0001062E07EBDE5A0801F6DD45DD4376 +:10A0F000AE40DD54A608C0FF84003E07EC003E07DA +:10A10000EF368401EB5EDD555A08120AEA718425A8 +:10A11000EA9E5A0801058405EA4CEA5C8402FC8048 +:10A12000FC00EA365A08010A4402040050100028D4 +:10A130005020005049002FDCDD40EBCF2E27EBFDF7 +:10A140002E37EBC92E47EBA549FFEDE7EA9C5A08ED +:10A150000107EBA75A08010449000B32FC80FC20E0 +:10A1600084C02E07EBC5E2C0E82C3C0C00C195F181 +:10A1700038501901DE243C0C00C44422D8289847EA +:10A180003C0C00C3A649380019113C3003A849FF14 +:10A19000DACC3C1C00C188E1A478FE0FAC383C0C42 +:10A1A00000C3381019013C03983EE220E8082E074E +:10A1B000EBA55A00FF058C013E07EBA58CC1D5D25B +:10A1C000FCA0FC00DD40A6015A000305F83EE603B2 +:10A1D000E906DD555A0005045A08120A84003E07B4 +:10A1E000ED3C3E07ED3D3E07ED3ED5373C0DFB5DBA +:10A1F0005A08010984003C0FFB5D4402C528490050 +:10A20000550D4402E3284412C538490058353E072D +:10A21000ED3EF81B5A08030784003E07ED3C3E075D +:10A22000ED3D4900551680C05A080110F80E5A0835 +:10A2300003078006EB6C44000061DD41F8065A0814 +:10A24000040D8401EB6CD509490055005A0803063A +:10A250008400EA2A8401EA77FC80FC20EA6D5A082F +:10A2600001064402C3788422EB0F2E0728B25A0855 +:10A270000108EA6BEBCF4422DAF049000B544402A8 +:10A28000DF4049FFE3C6EA9C5A080109EBA75A08D8 +:10A2900001064402DF4049000AAFEA6B4412C4944D +:10A2A000442200008460848549FFDB27DD555A087D +:10A2B000120AEA718423EA9E5A0801058403EA4CD3 +:10A2C000EA5C2E0728B25A08010AEBAF5A080107C8 +:10A2D000EBEFC004EA6B49000CAF8400441201D0DC +:10A2E0003E07EBE5502080144402C7004900053EBC +:10A2F000EBEFC8074402C7004412DF4C4900055188 +:10A30000EBEF4E02006584003E07EBCCDD555A08AA +:10A31000120AEA718424EA9E5A0801058404EA4C70 +:10A32000EA5CEA365A0001062E0728B25A080106EE +:10A330004402019C490030F084003E07EEEC4412D8 +:10A34000DAF03C0C01DC3C2003A84432C3B5848124 +:10A35000EAD42E0728B15A080119EA89B4009604F4 +:10A360005A0001083C0DFB31A60096045A08010E64 +:10A37000EBC9C80BEB244412DF4C4422C3B549009F +:10A3800003EA3E07EF12D50684003E07EF124900AC +:10A3900002A649FFFEE62E0728C45A080229DD4B13 +:10A3A000A600C80FEAF9E602E90CEB24EBB0442260 +:10A3B000C3B54432E37C4442C3ED490007D7D51707 +:10A3C00084003E07EF3849000606D511EA725A08A4 +:10A3D00001064900027A3E07EF12490005FC84009D +:10A3E0003E07EF383E07EBC53E07EBA5EA6D5A087E +:10A3F00001064402C3788423EB0F2E17EBC5EB4113 +:10A400003E07EEEBC9043E17EBFDD508EB244422D2 +:10A41000E37C4432C3ED49003F26DD465A08021171 +:10A42000DD4BA600C80D2E37EBFDE664E809EB24F2 +:10A43000EBB02E27EBC54442E37C490040472E5742 +:10A44000EBFDC53D2E2728422E37284392419261CD +:10A450004402E37C8420E225E80BA5008C2188825D +:10A46000AD00A5018C08888312407FFDD5F58400DE +:10A47000EA2AEAD23E07EBF1EBD5DD40A6015A0805 +:10A480000317DD5E5A080411EA8CC805DD558E04F9 +:10A49000E602E9052E07EBDD5A0801078404EA45C8 +:10A4A000D5655A0804648400EA45D5605A080A5FF5 +:10A4B000DD5E5A0805F88401EA45D558EA72C856A7 +:10A4C0002E17EF023E07EBC53E07EBFDEB5C3C0FA2 +:10A4D000FBCA5A1001093C0DFBC74420EA60E24068 +:10A4E000E9038C01EA2A3C0DFBC84420EA60E24003 +:10A4F000E90D3C23F77E3C33F62FE262E802C1040B +:10A500008C01EAD2D5033C1FFBC8EA8C5A08010F24 +:10A5100084203C1FFBC72E17EEF5EA495CF0803221 +:10A52000E80A8C213E17EEF5D50684203E17EBB6DF +:10A530003E17EEF52E1728AC5A180119DD52A64920 +:10A540005A1003045A180A132E17EEF65A18010966 +:10A550003C1DFBC8E622E804C8033E07EEF6840073 +:10A56000EB1A49002EAA8401EB1ADD5A5A08020799 +:10A5700049005360C0038400EA2A49FFFD695A0874 +:10A580000204480000DDEA725A0801058400EA2A44 +:10A59000EAD249FFFDC74402E37C2E17EBFD4422BB +:10A5A000E9E04432DAF0490056A0DD555A08120AB3 +:10A5B000EA718426EA9E5A0801058406EA4CEA5CA0 +:10A5C000EA6D5A0801064402C3788424EB0F2E0773 +:10A5D00028BB5A0001072E272819EAA98420D51183 +:10A5E000EAA94412DAF03C2C01DC49FFBE2DD50B60 +:10A5F000B460C305A4C2ACC6A4C3ACC78C21EB092C +:10A60000E222E9F7EA72C806EAA92E172BE149000F +:10A610005BFEEAA949004A42DD555A08120AEA716E +:10A620008427EA9E5A0801058407EA4CEA5CEAA9F5 +:10A6300049FFE788EA9C5A080116EBA75A0801135C +:10A64000EB244412E9E02E27EBFD4432C4744900A8 +:10A650000709490008B25A0801064402C700490028 +:10A66000110684203C1FFBBE2E6728193C7C00C2CB +:10A670003D0C00C3EAA9808186214520FFFF4530BB +:10A6800000FFE286E83AB440C22BA1473833950177 +:10A690001310000B5CF181004039BC1A1230000A23 +:10A6A00004300009E2234011BC1B5A2003245A2025 +:10A6B00005220220001E0230001FE262E803122081 +:10A6C000001F1220001D3828150102500020122002 +:10A6D000001E4C5900108CA112500020D50B1220E6 +:10A6E000000A1220001D1220001E1220001F12203E +:10A6F00000208C81EB09D5C63C1FFBBE49FFEBD780 +:10A70000EA979E41E622E9065A00040549FFFD5BEF +:10A71000D504DD465A0802FC2E6728AC5A6801129F +:10A72000EB32C810DD5A5A08010EDD40A6015A006E +:10A73000060A5A000B08490033E1D50480C0D5024F +:10A7400084C18006FCA0FC00EBDF80C0840CDD4FE0 +:10A75000DD45DD43AE408409441000A1DD4749FFDB +:10A76000ECE68409441000A2DD47DD40A6415A1002 +:10A770000D0B2E17EF2CC9074412C3ED4422C7005E +:10A780004900371C8409441000A3DD472E07EBA0C5 +:10A790005A08010BDD45DD43AE408401EBFDC0FEF0 +:10A7A00084024800008B8409441000A4DD47440261 +:10A7B000FEF2A600C007DD40A6415A18030449FF77 +:10A7C000CC578409EBB2DD472E07EBF65A08010C93 +:10A7D0004402C3E6EAF6EAC93C3DFB313C4DFB2F9F +:10A7E00049FFD09A840C00130050DD47840D0013FC +:10A7F0000051DD47840E00130052DD473C0DFB7015 +:10A80000C035840B44100087DD478400EADD3C0F2F +:10A81000FB70EAF45A08550EEBE7DD524422C39C64 +:10A820003C3DFB284442C52049FFD29CEAE7D503C2 +:10A83000EA3BEB47DD5549FFCDA396003E07EB9A77 +:10A840005A00033C5A080213DD45DD43AE40DD5497 +:10A85000A608C0FFDD465A0002A5DD45DD43AE4037 +:10A860008401EBFDC0FE48FFFF9D8409441000A653 +:10A87000DD47DD54A6085A080206DD4CA6005A0042 +:10A880000205EBE05A08010F8401AE08DD5BAE085B +:10A89000DD465A0002048400EB58DD46C80349FF38 +:10A8A000F2E5DD40A6015A000B0449FFEFFD8409E3 +:10A8B000441000A7DD478401FC803C0FFB8BDD9E2C +:10A8C0003C0FFB8ADD9E2E07F1598E019600EBF7B7 +:10A8D000C802EB9A2E07F158DD9E841F3C0FFA57F1 +:10A8E0008400EBF7EB9ADD9EFC63A1054022084053 +:10A8F000013100000091000100A1000200B100033D +:10A900008620E1A34EF200E0A081385145014C5869 +:10A91000C0D8A105415888088895A7A0E4C3E903D9 +:10A920008EC3D50284C0A7612E2728128CA3E0A273 +:10A93000E9029F51A6A2E443E9038E43D502844075 +:10A94000A7232E7728138C83E087E9029F39E1261D +:10A950004EF300B7E0B34EF300B4E1624EF300B142 +:10A96000E08A4EF300AE42634C004252A4014242E0 +:10A970002C01F681F58242212800F483F403E08261 +:10A980004EF3009FE44485A0E90350D17FFD9D1361 +:10A99000F701F485F402E0874EF30090EB7844531E +:10A9A000F04AAF283C4DFB8A80A700820002056078 +:10A9B000000042512073385B15005A50FF7C05702F +:10A9C0000001385B95114E540076E4E484C0E9023E +:10A9D0009FBB05800005A763410C540000E80001FF +:10A9E00040F71807E9679D3B51247FFF83C442422B +:10A9F000480101280000E092E95D00C8000340F62C +:10AA00003407E95804FF80058EA10108000242576F +:10AA10009401E0B0E94F43E238013C4003A843060B +:10AA2000C000838442482024432348004252B0019E +:10AA3000F4848680E0B0E93EF40481D28894889260 +:10AA4000952140FF3807E932386B10005A60FF2B20 +:10AA5000419B982002CC800040F600114EF5002367 +:10AA600004F0800540F7900002F7800040F7801165 +:10AA700040F7F007E917442F800040260804122C05 +:10AA80008000406C1840A6B043398801A6B14294BA +:10AA90008800A6B242A50801A6B342B5880048FFC7 +:10AAA000FF3150E700018C82D5CD8D81414A2000D5 +:10AAB000D5C28CE148FFFF708C4148FFFF618DA13A +:10AAC00048FFFF21FCE3FC20A612C0038E01AE125A +:10AAD0003C7DFB8AA753A63B8E01D0038CA1AF53CC +:10AAE000A610C0038E01AE10A63AA7518E01D00366 +:10AAF0008CA1AF518400A750011100018060E3A533 +:10AB0000E922A79201210003E3C6E91BA73A81E5E8 +:10AB100042F310730500800540483C20EB86410855 +:10AB20000011E59AE90CEB8602F2000041080011E1 +:10AB300040F78011E06F8810E802A4E08CC1D5E5F1 +:10AB40008CA1D5DEC306441001F4FE0C40000C17A6 +:10AB5000FCA0FC6280E0841F3C0FFA573C0DFB8B8D +:10AB6000F181A64381625CF08042E9044410004117 +:10AB7000AE43A6405CF08042E90444100041AE4080 +:10AB8000A683A600441003E8FE8C00658000FE4406 +:10AB90004081001340908013C63C84203C0DFA573E +:10ABA00080A1E0A6E80FA0B938211501DA09A0BA02 +:10ABB00038211501E2224002BC1B40113C1B8CA134 +:10ABC000D5F13C1BF618A07D3C0FFA57EA4EEB6717 +:10ABD000B0433A008020006F800C004F800D001FB2 +:10ABE000800F9834900140A00010000F800E8C213F +:10ABF0008A20443000648C819649FE5C9BA697B104 +:10AC0000406098D68007F101B08397B1F880D503F2 +:10AC1000855F800650157FFC9648E638E90A4EA508 +:10AC200000095CF30079E90544907D00448069786F +:10AC3000E3203EA7EC16E9102E17F1585A18010927 +:10AC400000158000C1053C13F618E63FE8052E17F5 +:10AC5000EC175A18010684003E07EC17D55CE30098 +:10AC6000E9038420D56D3C6DFA57442F80008400A1 +:10AC7000FEB700358000E003E808A079EBA9A548FD +:10AC8000DE02AC888C01D5F68007F10196B049FF51 +:10AC9000FE2DA03D401018403A108400B0833A11B8 +:10ACA0000420003580008C038420E023E82DA0B927 +:10ACB0003851050196AB4E2400255452FFFFD62192 +:10ACC000D92000207FFD004F800CE282E903102F85 +:10ACD000800C00207FFE004F800DE244E903102F1E +:10ACE000800D00207FFF004F800EE282E903102FCD +:10ACF000800EA680004F800FE244E903102F800FE2 +:10AD00008C218C04D5D38007F101B08349FFFEDD8F +:10AD1000E320E8098401EB9A3C0DFB8B8421A6011A +:10AD2000EBF7D50E840000158000E001E89BA079C8 +:10AD3000EBA9A4888C0154217FFFAC88D5F52E07A0 +:10AD4000F159C00B5A1801053E17F158D5068E016E +:10AD50009600EBF7C802EB9A2E07F1585A08010546 +:10AD6000842010158000FCE2FC002E17EF108002FA +:10AD70002E2730825A1801073C13F8CCC103442017 +:10AD800000782E17EF2C5A180103A6843C0C01DC26 +:10AD90004412DAF04432C3D58480EAD4FC80DD402A +:10ADA0002E4728CEA6015A0006049721D5032E4728 +:10ADB00028D02E07EBE82E2728D5E202E8068C01E2 +:10ADC0003C43946B3E07EBE82E27EBCC2E0728D4B0 +:10ADD0002E3728CDE240E92F2E07EBCD5A0801305F +:10ADE000FC2040000C0C8A04960184E0EB30E2E287 +:10ADF000E821A18AB44194F988C388430303000081 +:10AE000004508014A49088A3FEA4A4E842204073B8 +:10AE10008CE188432E3728CD40310C0D96D9ACF00B +:10AE2000A4F02E6728CD4031980C8A439691ACA8A7 +:10AE3000D5DEFCA08C413E27EBCCDD9EDD9E2E179F +:10AE400028B75A1001048401DD9EEBEFC84144325B +:10AE50006EB880803C139422E201E81FEBB0EBA9AE +:10AE6000A4883C13946E9693FE4AE041E8119883BF +:10AE7000A6508C219648AE50A6903C139469E241AE +:10AE8000E9093C13F61B8C213C1BF61BD5039843A8 +:10AE9000AF088C019601D5DF3C03F61B3C13946F81 +:10AEA000E220E8D284203C1BF61B840044326EB8BA +:10AEB000EB30E202E80698838C01AE509601D5F99A +:10AEC0002E07EF308C013E07EF308402DD9E8400B8 +:10AED0003C0BF61B8001DD9EFC204440271080C007 +:10AEE000FE642200002840208856FE2422130050D1 +:10AEF00022330000EACBE022E85140F00DF6E04FAB +:10AF0000E84F44500078FA788024991D4002040AE2 +:10AF10005CF00051E904524000A0D50480805A0042 +:10AF2000280552700078D503447000503843111141 +:10AF300038731D11FF0C40421C96E044E8039F410A +:10AF4000D504E082E8309CC1E0A3E8E04C01800336 +:10AF500080A35CF28051E904521280A0D5028025C2 +:10AF6000507280285CF38051E90352728078381364 +:10AF7000051144302710FECC38131D118A82403150 +:10AF800084769A9A42420003EB51E082E90CE04455 +:10AF9000E909E2054002BC1AFCA0FA18FCA0EAC5C7 +:10AFA000FCA08005FCA05CF00051E905523000A037 +:10AFB000B661D502B60150107FD85CF08051E9052A +:10AFC000520000C8B602DD9EB622DD9E3C0FFC5743 +:10AFD000DD9E4402EE548420AE42AE43AE46AE4700 +:10AFE000DD9EFC6D8140440189503B0044004607D2 +:10AFF000FFFF84C051CF806050000FFF3B0E442004 +:10B000008121F287F68F81A680A6510F805845E0F6 +:10B01000005645900064F08DA618E2A04EF201089B +:10B0200004048001380015014C02C0FF04048005AF +:10B0300040001440A640F181A68200E000030140D8 +:10B040000001F001401708018A148801EB3CE40379 +:10B050004EF200EB45507FFF40F708064EF300E547 +:10B06000F70140FA1C064EF300DD2F372812B40911 +:10B07000F08242014C24F402984794494122040092 +:10B080000119000154F880044EF300C90444800102 +:10B0900001190000F48338B245014CB2C0C0882ABF +:10B0A000236080004F6700BBC20B51117FFF808778 +:10B0B0004248CC733915110113180000D5031358F9 +:10B0C0000000C70B822743114C73F40D89A4391576 +:10B0D000450113180001D5031358000150F9FFFF73 +:10B0E000E2EFE8060310800113180002D50313589D +:10B0F00000022F1728138FA1E251E8094113CC0059 +:10B1000088113805010112080003D5031358000304 +:10B110009F39420B7824F4899D11F48A9D394000AF +:10B120006416F48B9F11F08854B580FF8400F48C72 +:10B13000391E010004CF800838484511F484E08CA2 +:10B14000E866411E00200118800138484511F48549 +:10B15000E08CE85D5A00020E5A00030F5A00010508 +:10B1600004CF8009D50304CF800B048F800CD50851 +:10B1700004CF8009D50304CF800B048F800A822C72 +:10B1800043144C73F4024118840888910122000191 +:10B19000F48655290004552900FF4F23003989AA58 +:10B1A00023888000F404437C7824417BE6F6E09712 +:10B1B000E82EF405E097E82BF40600F20000F40313 +:10B1C00038F23D004CB7C02440FC5807B010E90CE1 +:10B1D00038701909B01238201909F80B39601909AB +:10B1E00013208000D50F38C01909B0123880190912 +:10B1F000B00F38B01808B01483FF3980190913282C +:10B200008000E6C4E8088CC197B0D5058C015A08C7 +:10B210000491D504804E80F485A18CE148FFFF2382 +:10B220008C4148FFFF1B8CA148FFFEF85AD0010457 +:10B230004800007F808DF207800A8029EAD484408C +:10B240004717FFFF80E2808250CF804850DF804068 +:10B25000508F805051188FFF85C2E286E86438060F +:10B260009101385611012E172812806042328473E2 +:10B2700082C0802338341101383505092F27281260 +:10B280009E694360C873826580628560441000FFD8 +:10B290005152800151707FFF518000015029FFFF02 +:10B2A00040FA8806E9294025D8008600414144003B +:10B2B000402BC00040FC0806E91C04F48000402A32 +:10B2C00040004027882000F100015AF80211019146 +:10B2D0000000B08F38F110004CFCC0058CE197F8ED +:10B2E000D5065A18FF0380399C9996D08D81D5E1F7 +:10B2F0008DE18972D5D4804380604232C873B589AC +:10B3000040380C2010E18001EB57E2E242028C73DE +:10B31000B46940018020E904B04F38109000AE407D +:10B320008C81D59C84013E07EF388401FCED2E070B +:10B33000EEEC5A0801192E4729A44422018C8420DE +:10B3400044500073E224E80AA6108C218C0A96006F +:10B350004200140118010001D5F6800A8029F20785 +:10B360008481EAD48400FCEDFC20848080C0A7D0D6 +:10B37000800480A44502C950E2A7E816A0F1383144 +:10B3800095014C32C0100513000296E8391895015A +:10B39000383810088C81E7A697204001BC1AE68C4B +:10B3A000E8038CA1D5EA2E57EEEBA0F2E6A2380115 +:10B3B0008101E90FE683E80D8C81DC0B8E06E61235 +:10B3C000E808806280013C2003A8802649FFFE0B2C +:10B3D000FCA0FC01F081F80740000009F0019E414B +:10B3E000F181C8FBDD43DD45AE4083FFFC81FC02FB +:10B3F000F081F001441003E8FE0C50107C5E46031F +:10B40000A19650000B1F4200806940009409F08310 +:10B41000F001C802D509EA2DF0039E41F183C8FC72 +:10B42000DD43DD45AE40FC82FC02F0818400F08308 +:10B43000D50ADD43DD45AE40440003E8EA32F003BF +:10B440008C01F083F103F001E220E9F4FC823C0F6F +:10B45000FC5FDD9E3C0FFC5EDD9E3C0FFC5DDD9ED7 +:10B46000FC4084E03C2DFC5F80C1808780A786255E +:10B4700004F30000E81250F7FFFC5CF78002E90DCE +:10B48000052300070500000238F8490101210006E4 +:10B49000E3CFE80311118002B58651287FFFE7C290 +:10B4A000E9035B0804058C81972080E58CA19768EF +:10B4B0005063004C5A580ADE2F17F193CC068400D3 +:10B4C0008420AE1A80A1D51FA61A5A00051B5A481F +:10B4D00001145008FFFFE602E8042E57F192DFF056 +:10B4E0004400004C421380738401225080042210D7 +:10B4F0008005AE1AD50884038420AE1A80A1D50336 +:10B50000842080A1A61A5A0801263C6DFC5DA7B3D1 +:10B510005A6801213D2DFC5E0269000951337FFF0D +:10B520000269000250937FFF84C241099A164302C8 +:10B53000A47340584CB70309000A032900038F8104 +:10B540008FC1406818D64260C873976B401340376C +:10B55000964BE7A5E81844F0B3643917C40040F8E7 +:10B56000BC00DD0F060C0C161C005A08010BD51090 +:10B570005A00010CC80C8403D50BE602E808D50379 +:10B58000C806D5068400D5048402D5028404EB8362 +:10B590008E01E60484C04EF2008D44F0B3A8EBACFB +:10B5A00040F03C004A003C0008003400500002011A +:10B5B0008400446FFFAA3C0BF8C83E67E9603C5B1F +:10B5C000F8C63C1BF8C73C5BF8C43C1BF8C53E07FB +:10B5D000F1863E77F1923E07F184D56D2E07F18614 +:10B5E0000261001AE206E8048C013E07F1863C5B2A +:10B5F000F8C43C1BF8C5D55F2E07F1875A08012611 +:10B600002E17F1860201001AE220E81F2E17F1859D +:10B610000201001BE220E8192E07F184C8163CF74E +:10B62000F8C03C07F8C4021100198A0FEB3CE00196 +:10B63000E80C3CF7F8C13C07F8C58A0FEB3CE00189 +:10B64000E80484033E07E9602E17E96084003E07A2 +:10B65000F1855A1003313E07F1872E07F184C82B7C +:10B660003C07F8C50211001EE001E91D0211001F90 +:10B67000E020E9193C17F8C40251001CE025E91349 +:10B680000251001DE0A1E90F2E67F1860251001A58 +:10B69000E2C5E81184A13E57F1873C1BF8C03C0B82 +:10B6A000F8C1D5098402AE1AD5063E67F187D503E5 +:10B6B0003E67F19384003E07F1943C03F8C8CC0543 +:10B6C0002E17EF125A180110A454E201E8058C015C +:10B6D0003C0BF8C8D52184013E07F1948404AE1ACE +:10B6E000EB83D51A2E17F1875A18010E2E17F18504 +:10B6F0000251001BE225E8058C213E17F185D50398 +:10B700003E47F187A454E201E904EA3A3E07E960C2 +:10B7100084003C0BF8C82E27E9605CF10020E81F8C +:10B720008C4C96908401E65EAE18AE998401E904D3 +:10B73000FA2EF803D504802249004A7F8403EB6C7B +:10B740008400EB83EA3A3E07E96044000060DD4193 +:10B750002E07F1708C013E07F170D5038400AE18FE +:10B760003C0DFC5F3C1DFBC7A404E220E9048400FF +:10B770003E07EF2CFCC0FC0084004412C474442F2C +:10B78000FFAAAE08AE0AAE8984203E27E960EB83AB +:10B790003C1BF8C83E17F1943E07F1873E07F1863F +:10B7A0003E07F1853E07F1923E07F184FC803C0D97 +:10B7B000FC5FA404DD9E2E07F194DD9E2E17281950 +:10B7C00084004432000084819680E241E806988338 +:10B7D000104103EC8C01D5F9EA89B400EA465A0815 +:10B7E0000107440000B43C0B9605DD9EEAC53C0B06 +:10B7F0009605DD9E3C1394FCAC40DD9EFC60A612D9 +:10B80000C0038E01AE12A6135A0031048C01AE1390 +:10B81000A610C0038E01AE10A6115A001F048C01A1 +:10B82000AE11009100010131000301010000A69258 +:10B8300050348001507980018A708AE284C096D8A1 +:10B8400097F842B38C24823080868006E331E92168 +:10B850008242E3F2E91C04A080054058C8A040558C +:10B860001420F8095EF78024E91002A2800040A5A8 +:10B870000011888A02A2800040F5001183FFE00FCA +:10B88000E802A4288CC197B18DC1D5E48DA1D5DF84 +:10B89000C006445001F4FF2C40420097445000641D +:10B8A000FFAC40F32DF65EF78026E838E669E9360E +:10B8B000E6E9E934EAF9E603E831DD4BA600C82EF3 +:10B8C0005CF21F41E92B88534004C0009041403096 +:10B8D000040A9415A10D9858F8059C59F8029E5930 +:10B8E000882040120420A448964B5EF08023E8167E +:10B8F00083FF5010002088234E00FFF550107FE09A +:10B90000981940020020A40096035EF00023E80688 +:10B91000EB34C80484013E07EC17FCE03C0FFB8DC0 +:10B92000DD9EFC638180EAF9816180C25A080112C0 +:10B930002E07EBC55A08020E3C0C00C480200910EB +:10B94000800200D0000100E0800100900002D506D6 +:10B95000449000FF822981C981A984002E1729A45F +:10B960004432000080809680E241E80698831041CE +:10B97000018C8C01D5F9FA53503F80138480040662 +:10B9800000058026B7BFEAD48460005F801382631D +:10B99000810380838243804384FFB5BF9618E2050C +:10B9A000E81E05030001965939080D0194194D0050 +:10B9B000C015A07238108D01E241E80BA0B480E3FD +:10B9C000880201200001A700A0338041033000005D +:10B9D00050040001548000FF8C61D5E18400151FE4 +:10B9E00080033E07EC175A7FFF044800011EA03574 +:10B9F00040A38808153F8002F481B7DF880AEB670F +:10BA0000B0453A008020B0858006802C49FFFEF8C2 +:10BA1000A036B5DF38301E02A037F40138501E02C0 +:10BA200004030008053F800238001E02051F800342 +:10BA3000C00E3C2DFB8D00110032FECC00110033F6 +:10BA400041018217FF4C405280B7D50380A082008D +:10BA5000A0B5884AA61000A1000240F68006A6D331 +:10BA6000A651E91CE22DE91AE3AAE918E271E916E8 +:10BA700040F70006E913E22EE911E32AE90FE26933 +:10BA8000E90D5CF980C9E90A2E07F19D5CF000C858 +:10BA9000E80D8C013E07F19DD50984003E07F19D1C +:10BAA0005CF98078E90C5A77FF0B2E07F19C5CF06B +:10BAB00000C8E8058C013E07F19CD50984003E07CB +:10BAC000F19C841F3E07F19B3E07F19A2E07F19CE3 +:10BAD0005A08010D5CF2002EE90950197FFCE63985 +:10BAE000E8053F27F19B3E47F19A2E17F19B5A102C +:10BAF000FF1F2E27F19A5A20FF1BE614E8188A44EC +:10BB0000EB51E442E914000F8013E602E910DD4B2B +:10BB1000A6C0CB0DEB645A18010B440001E0E70509 +:10BB20003C0BF8CF10158000E84DD5093C03F8CC4C +:10BB3000C008E705E8038E01D50284003C0BF8CC71 +:10BB40005A7FFF0584008060D536A0B540711C4047 +:10BB500084C0A6BA012380033C1DFB8D800680664D +:10BB6000E3C2E91EA73801338001E3E4E9170110BD +:10BB70008002812442914473822904960005411475 +:10BB8000C42002F8800040F780115EF78023E904AA +:10BB9000886488028CC18C81D5E98C41D5E2C6D3FA +:10BBA0000040803200208033FF1CFE844032187732 +:10BBB00040011817001580005A1001084410005069 +:10BBC000D5055A7FFFC48003EA6F2E27F19DE64614 +:10BBD000E90544238D40A690C20C40380C0142F187 +:10BBE0008003E22FE9069A2842F00003E22FE80DD5 +:10BBF000440001E03C0BF8CF8401EAE02E1729A4B1 +:10BC0000440201A484A0D5083C03F8CFC0F78E01FC +:10BC10003C0BF8CFD5F4D10E082000018CA11020E8 +:10BC20007FE79768D5F984A03E07F19D820548FF1C +:10BC3000FF39FCE3FC0080C0A046A0058444846F6B +:10BC4000848584A049FFE3FEA036A075EA4DFC8000 +:10BC5000FC002E5728C05A5001048401FC803C3D52 +:10BC6000FB23A6D95A3009045A3804193C33947D71 +:10BC7000994BE2239769E8049A599649D5028420A2 +:10BC80002E47EBC0A0C2A0034031907740001017B0 +:10BC900096D996012E472907D51B44338D40A71806 +:10BCA000CCDD3C33947C994BE2239769E8049A59A4 +:10BCB0009649D50280242E67EBA4B460A0014031E0 +:10BCC0009877400018172E47290696D9960144F018 +:10BCD00002004252BC01E2A3E805A6108C01AE109E +:10BCE000D505E201E9FB8400AE10DD40A6015A084B +:10BCF00004048400AE10A610E280E8B08400AE1008 +:10BD00002E07EF318C013E07EF318402FC80FC20CE +:10BD100005008013006F8018011F801C55087FFFED +:10BD2000CA0F8381BE1244220168B913EA664061DA +:10BD300018405420FFFFA6749648CB16D5244472B1 +:10BD400000004103C04045200064E2D1E8EB80F0F0 +:10BD50004273487351338064182380014C79FFFE8D +:10BD60008CC197B0D5F344600064FE7440108840E5 +:10BD70004462006444220000884188261831000192 +:10BD80004C20FFFEAD00AD41FCA0FC20F6085A603F +:10BD9000010B4462DFB4387304004462DA60391383 +:10BDA0000400D503862284E98380B912450200008D +:10BDB0005460FFFFFA38FE7CBF1440109840406387 +:10BDC000C00954737FFF4460006088304268982443 +:10BDD00040631C40A7CFAFD8A6CEAEE0A6CCAEE85D +:10BDE000024000300230800D020000300210800C52 +:10BDF00088648801F406F1074008002088D04038A4 +:10BE00000C20B664B601B406920A9637AE10FCA0B8 +:10BE1000FC408380BD14B814446000485452FFFFB6 +:10BE2000EA4BFEF4FF34404200404031944044521B +:10BE3000000088A484008A64386194003860810915 +:10BE400008628001386101098C015A0832F7440206 +:10BE50000034888084A085233931900241109400F9 +:10BE60000D2200014101140084E04203A42402A831 +:10BE700080004069800D9797406519001A6880011D +:10BE80004009000D026800009617400301008CE194 +:10BE90001A0800015A780AEB8CB45A5864DFFCC0C7 +:10BEA00004000013EB1BFEE4EA4B400180404432E7 +:10BEB0000000886084009908A761384080004042F3 +:10BEC0004008404217009950A76940421500385178 +:10BED00000008C028885AB195A0832EFDD9E040001 +:10BEE0000013EB1BEA4BFEE440318040EA9D886082 +:10BEF0008400A51938408008A75B9908AF61B48316 +:10BF000038410008A319995092888C02AF295A0829 +:10BF100032F2DD9E4412DFB4380080008E015C00F6 +:10BF20000009DD9EE201E80AA610E260E8049AC377 +:10BF3000AED0DD9E8400AE10DD9EE220E80BA610A0 +:10BF400052F180FFE00FE8048860AED0DD9E841FD0 +:10BF5000AE10DD9EFC60EEA8F0858141F28480E3A6 +:10BF60005A3801053C800B47D506F9154E0200A44E +:10BF70003C800B462E07EC1984C1E602E9058E01D0 +:10BF80004063000C97B04063280E97B0CE0284C186 +:10BF9000B00A50BF8024505F8021F081F105F00489 +:10BFA000B088503F8022504F8023B77FF78249FFEF +:10BFB000FEEEF004B064B0BD003F8022004F80234D +:10BFC00049FFFF28F86F49FFFF8CB0248120B00B98 +:10BFD0008380858044D000323855B2024400651019 +:10BFE0009928440073E840E2800042063424F0853A +:10BFF00084E039049D015CF807FFE8492E17EC1A2C +:10C000003932C101003F80208E21402804084009B8 +:10C010008C164CA0C0158844A4508A0840308C76F9 +:10C020008A68EB4C42F00003E06FE9041331000032 +:10C03000D52E38074101380E1C08D5294EA300061D +:10C0400039324109F810D5168844A45040308C7616 +:10C05000401020018A68EB4C42F08003E06FE90A4F +:10C060001331000038149D01382E1C0038270509B3 +:10C0700083FFF105B0CB98B988439601802880668C +:10C08000F487F58649FFFF50F407F5068CE15A78EE +:10C0900032B25094806451CE00325AC0010485817E +:10C0A000D59CF004B04B502F805E003F802183FF71 +:10C0B00049FFFEF8ED58FCE0FC61F0818401B63FD9 +:10C0C000814280C3EA70DD465A0002048400EA63BC +:10C0D000DD548401AE08DD5BAE0884003C0FFB7CC0 +:10C0E0002E07EF375A08010684073E07EC19D50CD6 +:10C0F0005A6801072E0729013E07EC19D5052E07BE +:10C1000029003E07EC192E07EC198C013E07EC1AAA +:10C1100044000060DD4FDD465A08024C5A680107B2 +:10C120004413F423EA37EA31D50B4400006185203B +:10C13000DD4F816944C3F04AEB9985A1D510A6086B +:10C140005A0002F5AED0D5FC3C0DFB7CC81CE9FDC5 +:10C1500050048001EAECDD4C10D000002E07EC1AF0 +:10C16000E320E8653CBFFB7E108600005A600107B3 +:10C1700044000062DD4F84E0D5188006EA26EAA577 +:10C18000C0FFD5F73CBFFB7CCE12EA5A8E0154E0CB +:10C1900000FF800E49FFFEC0C008800E8029B45FFA +:10C1A00080668CE1F82D97F8E2EAD5D28007D5F7C2 +:10C1B00046B000F484E044C3F04AEB9985A150B541 +:10C1C00082402E07EC1AE2E0E83210860000F8BF49 +:10C1D00044000061DD4F5A680105F001EBEED50621 +:10C1E000DD408420DD56490029BE44000062DD4F59 +:10C1F00085204C95000D80098027B45F806649FF3B +:10C20000FEAB50548001549280FFD5F4DD4C8CE19C +:10C21000549380FF10D000005A6801062E77EC1A64 +:10C220004C93BFD1800BEB4F80E9D5CC8400EA70F2 +:10C230008400FCE1FC212E07EF37C8063C239481E3 +:10C240003C339482D503EA8780432E07283F84C07D +:10C25000EA5E3C43947C3C53947DF081969044028A +:10C26000EE7C96D8B6DF49FFFD54DD4680E0EA5EFD +:10C27000DD405A78021B84488066F8255A0801057B +:10C280003E07EF02D549DD408425AE4184213E17AB +:10C29000EEA33E77EEEAEA348441DD40EA5E806256 +:10C2A000F8123E67EEA3D5182E27283F8066F80BBC +:10C2B000DD408429AE413E67EF2CEA348441EA5EDA +:10C2C000DD40806249FFFEFADD40842AAE418421D0 +:10C2D0003E17EF2CEA3484013E07EBA984033E07A6 +:10C2E000EEEA8407DD4F8400EB5EDD465A08020665 +:10C2F000DD40842DAE41D50BDD408420DD562E1768 +:10C30000EBEBDD405A180203842AAE41DD40EA34EB +:10C310004400006FDD4FFCA1FC00DD465A08021509 +:10C320008400EB688401EA70DD43DD45AE40DD59F1 +:10C33000A640C9FFA6405A1801FFDD4C8422AE403A +:10C340008400EA70D50BEBF4EBD6EB4F49FFE58A9E +:10C35000DD408420DD564900290644000065DD4F9C +:10C36000DD42C00DDD45DD43AE4049FFB549C0FEAD +:10C37000EAB0EB43FA50EB0449FFDFD3FC80FC2426 +:10C3800044218958EBB144418968B084EBF93B0200 +:10C390004C003B014C20390102024421D8004021CD +:10C3A0000040A79080E197B0381F82028480451337 +:10C3B000651045226238EB30E282E81994E14021B1 +:10C3C000C400033100004021C800994BA4903838C4 +:10C3D00010008C81FE9CA4E84021180E8A5396938D +:10C3E00040211C568843ACA89721D5E644200C80F8 +:10C3F0004431A20042300873800349FFB048FCA4D6 +:10C40000FC6184C08401EADB3E67EBB68126EA70FA +:10C4100080E6850485A644E38D405A78040B8400A9 +:10C42000DD528040EA4A3ED7EEEA8581EAA1D50B8B +:10C4300080073E87EEEAF8198180DD528403804749 +:10C44000EA4AEAA1DD4C8421AE409E39854054B0D1 +:10C4500000FF4CA6002FDD59A640C9FFDD42C00EEB +:10C46000E2C9E80CC70B800B490022D8F0818CC1CF +:10C47000800BF10197B049FFFF8400170000DD59E0 +:10C480005A180311A6405A1801FFDD42C007EA30CE +:10C490005A0807FFEAB0EAB6EA4D50048001EAEC18 +:10C4A000D504A6405A1801FF50050001EBDAD5D299 +:10C4B0008CE197F85A7805B38400EA708400FCE1B7 +:10C4C000FC454421897844720000EBB1B04244211C +:10C4D00089883B00CC20EBB1A6BA81208400B186CC +:10C4E000EA553810A602EB25A6FB92413B034C20EF +:10C4F000EB62EB2538132602A6BAA6FBEB62FCC55D +:10C500003C0FFB8EDD9E3C0FFB90DD9EFC008420EB +:10C51000DD56DD548400AE08DD5BAE088401EA26FA +:10C5200084018440842A8080806280A2DD57DD45BA +:10C53000DD43AE40EAA5C8043C0DFB7BC0FCDD42F8 +:10C54000C0168401DD4ADD45DD43AE4049FFB458E5 +:10C55000C0FE8402DD4ADD465A000214EA21EA8A5E +:10C56000AE08804184618402DD44D50BDD465A006B +:10C570000209DD45DD43AE40EA21A6085A0832FF34 +:10C58000DD465A0802072E07EBAF8C013E07EBAFE2 +:10C59000FC80FC2080A03C0DFB8E3C4C01E3A6837C +:10C5A00094E9E2A2E825F87BE906A4309783982A6B +:10C5B000F87FF8649222CD0DA421F83140220820A2 +:10C5C000A4109603E0204EF200C98401EA49FCA0C1 +:10C5D0009E1A8804A400964996039F91E020DE04E9 +:10C5E000E9F58845F835F82CF81B8845F8318403BF +:10C5F000FE14E2A0E93599E3A5B897B3E026E90C6B +:10C60000A5B897F39BAA40621820A5B097B388C736 +:10C61000E0264EF200A39222D808F813964996031A +:10C62000E020E9D483FFF8139E1A8804A4009592B1 +:10C63000960396498EC1E020DE03E9C8F808E9C6F2 +:10C640008C628864A41883FF4E00FFEB9AAA4022F4 +:10C650000820A4109603E020E9B9FCA083FFD203D0 +:10C660009591DE19F81CE910F82096038807E02060 +:10C67000E90BA4309783982AF81B96038806E020DC +:10C680004EF2006C83FF8C62F825F811F826F82E24 +:10C69000F824FCA08EC1D6038E01D83099A3A43013 +:10C6A0009603E02083FFE915A43097C39A2A40023D +:10C6B0000020A40083FF96038807E020E90AA43045 +:10C6C0009783982A4E00FFF596038806E020E845F8 +:10C6D0008E628864A41892229603E0204EF3FF77BE +:10C6E00083FF4E00FFE54E00FFF9884540220820F9 +:10C6F000A41083FF4E00FFF2FCA09F9A98234122D2 +:10C700001800A400026900008C62410300118864D3 +:10C710009BAA40F00011A5D841121820982A02685F +:10C7200080004022002097FB4007C000A51097B36F +:10C7300088079723880688049D0DE080E80E02098B +:10C7400000004E00FFCAA4184E00FFC80208800077 +:10C750004E00FFC448FFFF36FCA02E17EB92C10924 +:10C760002E272C92E241E9048E219648D50284209E +:10C770004422ED0C38310501E260E92BFC208400F5 +:10C7800038010509EAF7842084A33C3C01E13C0C14 +:10C7900001E23C4C01EA9489886288028881A5986C +:10C7A000A5C0A620880742031473404008099721BA +:10C7B000AD183C4C01E13C3C01EA8844A4908861FE +:10C7C0004000084196008C21AE185A18C8E0FCA021 +:10C7D000DD9EFC005A0801122E1011D12E0011D03E +:10C7E0005A1801048E03D5028E02960084408020E0 +:10C7F000806249000885FC8049000894FC80A641BD +:10C80000EA7D5A1804112E17EB9FC903A602D50220 +:10C81000A6032E17EBFB5A180208E604E9058E035F +:10C820009600DD9EA604DD9E540000FD5A08040516 +:10C830003C03F8D1DD9EEA7D02000009DD9E5A0826 +:10C8400004053C03F8D0DD9EEA7D0200000ADD9E6F +:10C85000EA7DA400DD9EB400EA7DA4470200000842 +:10C860003C1BF8D13C0BF8D0DD9E2E17EB97C90985 +:10C8700084423E17E9383E27EBD13E17EBB6EA512A +:10C88000DD9EFC00DD45DD43AE403C0DFB7BC8106A +:10C89000EA6D5A0801064402C42C49FFDC098401F0 +:10C8A000844080208062808080A2DD57D5EF84069E +:10C8B000DD4ADD42C01CEA21EA37EA31A6085A0007 +:10C8C0003204AED0D5FCEA40EA28EA305A00070428 +:10C8D000AE88D5FC4412C52C840280418461DD44BD +:10C8E000EBA7C003840AD5028409EA39EA67441039 +:10C8F0000033AE402E07ED3CC81149FFBD355A004C +:10C90000A10EDD428020C8078402804180618483BB +:10C9100080A1DD5749FFE284FC80840E49FFDB1CC7 +:10C92000FC80FC00DD465A0802074403F422A600FE +:10C93000961FFC808400FC80FC2084003C0BF633B6 +:10C94000DD4084233C7DFB2284C1AE41EB44EA34CC +:10C95000DD4BA600842397F8490014693C7FFB2235 +:10C96000EBF8C80A2E07EBD8C8078409DD4A3E67F2 +:10C97000EBE93E67EBA9DD40EA34DD5484003E0775 +:10C98000EBD88401AE08DD5BAE08DD5E5A0004041E +:10C990008405EA452E07EBF18420C8093C1DFB9075 +:10C9A000A448E622E9038E22D50280203C1FFBC763 +:10C9B000EBEB5A18020FC8093C1DFB90A448E62A6D +:10C9C000E9055000FFF6D5028400EA2AFA18EA9A2F +:10C9D00084013E07EBF38400EAC8FCA0FC0084C09D +:10C9E0003C6FFB60EADBEB92EB763E07EB92840157 +:10C9F000EA26DD59AF80EB92FC80FC00DD40A60109 +:10CA0000EB295A080911DD5E5A0004048405EA4541 +:10CA10002E07EBF1C808F803E602E90549FFF6C95D +:10CA20008E02D5028400EA2AF81849FFE200DD40B0 +:10CA30008429AE418420DD56DD40842AAE41EA34AB +:10CA40004900259184008421EA333E17EF2CEAC87F +:10CA500049FFF6934900483C49FFE1F7FC80EA7D35 +:10CA60003C3C01E3A503842084019899A49096930B +:10CA7000E082E80284008C225A1990F9DD9EFC20A5 +:10CA80002E17EBD15A18020B2E17E938C9072E17AB +:10CA9000EBF98E225C108001D50284203C6DFB8E68 +:10CAA0003C4DFA593C7C01E284A0846186435330BA +:10CAB0000000A6B35113800251017FFF4C58001DA6 +:10CAC000410104088F814C580018430148248F818C +:10CAD0004C58001394928E41D20FA4B80278800073 +:10CAE0008A479693E00238221509E903E053E804E7 +:10CAF0005A18010384628CA180F15A58C7DC5A1875 +:10CB0000011C401004098440FF4A38720911E027D3 +:10CB1000E807A633880238F20111E02FE909E0E5C1 +:10CB2000E808A633880238020111E005E8028462B1 +:10CB30008C415A2895EC8003FCA084204422ED0C03 +:10CB4000380105098C215A1808FDDD9EFC4080E063 +:10CB5000A60080C25A08051E8401AE38DD4085203B +:10CB60003C9BF774A601EAD1F8153C13F632E62A8D +:10CB7000E8058C213C1BF632D5133C9BF632A430E1 +:10CB8000E619E804EA538400F8058400AC30D508BF +:10CB9000840049FFFFD48400AC303C0BF632FCC06B +:10CBA000FC01DD40A601EAD1F081F1014402C3E9B4 +:10CBB0004422C44449FFFFCC2E17EBF98400EA9BC2 +:10CBC0003E07EBBBC9033E07EBBD84003E07EB927B +:10CBD000EA3AEA8BFC81FC20FD30EB7680A0A6309F +:10CBE000AF70C5092E172C9284C0E225E9059FA9D4 +:10CBF00097B0D50280C5D01DDD465A08021B3C3DCA +:10CC0000FB8E8400A65B9449E001E80D8387BA0996 +:10CC1000BC0B944188418824A4488C019649AC50AF +:10CC20009600D5F13C03F614C00E8E01EA9BD50B9D +:10CC30004402ED0C385019014410FFFFD1048CA1BF +:10CC4000385019092E17EBBD4000980E9604C81BEA +:10CC50000513800A050380090453800B4038000047 +:10CC6000A498404880009691ACA0A49899289691E9 +:10CC70008C02ACA05A0990F484014060180CFE7735 +:10CC80003E17EBBDFCA0FC002E272C92441000FFA9 +:10CC90004020880C4413F422A648FE93965F969099 +:10CCA000C1038E219648A78084A14042840CFF379F +:10CCB000972296E0AEC04C61800D4C31000B882568 +:10CCC0004052840CFF679768FF5D5C028001FC8026 +:10CCD0008005FC80FC008400EA9BEAF7EA49DD401D +:10CCE000A6015A080423DD5EC8094402C3AD49FF0A +:10CCF000FFCC5A0801048403EA45DD5E5A08031F8D +:10CD00004402DB34842044200320EA3D2E07EBFF5D +:10CD1000C807EA7EA600962EC8038404D50A8401BB +:10CD2000EA458400EB4ED50A2E07E938C804840290 +:10CD3000EA45D5042E07EBFFD5F0DD5E5A08020563 +:10CD400084003E07EC1B840080804452E4983C3C05 +:10CD500001E094418861A4D83C2C01E296D9884135 +:10CD6000ACD03C2C01E13C3C01E288418823A44842 +:10CD70009649AC503C1C01EA8820AF083842800834 +:10CD80008C015A08C8E6FC80FC208407DD4A84C078 +:10CD9000DD403E67EEA3EA34DD4C84213E67EBAF15 +:10CDA000AE4084003C0FFB72EA93EABC3C2DFB7260 +:10CDB000CA098401AFF080208062808080A2DD57A4 +:10CDC000D5F6DD45DD43AE40EAA5C80B3C2DFB7B27 +:10CDD000CA08840184278062808080A2DD57D5F54F +:10CDE0008421DD40DD56DD42EA40EA28C00E8400A1 +:10CDF000EA90AE883C2DFB22CA2684018020806206 +:10CE0000808080A2DD57D5F7AE882E07EBC6C0091B +:10CE10008401844080208062808080A2DD57D5F626 +:10CE200049FFE324EACE5A0803048402D5028401B0 +:10CE3000EA904412C47884013E07EBC68041840224 +:10CE40008461DD448408DD4ADD40EA34FCA0FC4016 +:10CE500084E3812142709C2484203E17EBB640A0DD +:10CE6000080890E384C0E0CAE8153C2C01E34021A7 +:10CE70001820A4909693E0E2E80A8006802949FFF2 +:10CE8000FB8AEAB1C0043E67EE3CFCC08CC197B09F +:10CE9000D5EBFCC0FC60812180E04412DF4C4402F1 +:10CEA000C38249FFFE9A4400FFFF84A03C1DFB9013 +:10CEB0008049A952A81300008016E610E8045250D9 +:10CEC0000010976884C0FB80430040013CADFB8E9E +:10CED0003CBC01E23C8C01E03CCC01E33CDC01E1E8 +:10CEE0002EE7E9382F47EBF92F27EC1B3D3DFB28B8 +:10CEF00080464512E49882A60005000394C2E043F0 +:10CF0000E868959140459800A4E040041800A4000A +:10CF1000FEEC42304073926496D9ACE04036180083 +:10CF200088CDA42002F300008A0F9603AC18A4D881 +:10CF3000A40D96DBFE02E060E81A5AE001045B48AB +:10CF40000217380888008C01960038088808A4CE9B +:10CF5000E260E813A42086419601AC302E07EE3D36 +:10CF6000395888088C013E07EE3DD50738088800FF +:10CF7000C0048E0138088808A4E004048002E2039B +:10CF8000E804A42014048002A4E004048003E26006 +:10CF9000E804A42014048003040480023C37F63320 +:10CFA000E260E8033C0BF633A6395A080908B413CB +:10CFB000EA465A00010AA58BD509B413EA465A007D +:10CFC0000104A58CD503446000648C419690D595EE +:10CFD00080263F27EC1B49FFFF3CDD40A6015A0895 +:10CFE0000907800649FFFD4D3E07EBD1FCE0FC4000 +:10CFF00080E0A60180C15A08041F9E0CE604E90CDB +:10D000005A100C0BDD5E5A0004082E07EB9F5A08DD +:10D01000010BEB92D508DD42C80B3C03F7745A08AC +:10D020000108D5F48007EBEEEA6BEBB7EB908400D8 +:10D03000EB4ED508DD5E5A00040649FFDEFB800793 +:10D04000EBEEDD424E0200853C03F62A4412E2F488 +:10D050008C01EAF73C03F6148C01EA9B800749FF38 +:10D06000FF1BEB55A600C0058401EA498400EA2AAB +:10D07000EAB15A08011584003E07EBBB84002E1765 +:10D080002C924432ED0C80809680E241E8053841D4 +:10D0900081098C01D5FAEA58DD41D5242E97E9386B +:10D0A0005A9801159E34E602E9114402E2F43C1359 +:10D0B000947F4422C3AB49FFF5CD5A080208FA0118 +:10D0C000DD413E97EBB63E97EC004412FEFCA6080D +:10D0D0005A08A5098401EB5EEA493E07EC0084008A +:10D0E000AE082E07E938C834A6385A080232DD5E89 +:10D0F0005A00010F2E07EC1B5A0801062E07EBD130 +:10D100005A0001073CF7F6415EF78078E81849FFBE +:10D11000FCA8C8093CF7F6415EF78078E904EA49C3 +:10D12000EAF7D50D840184E0EA773E77EF1249FFF4 +:10D13000EBD6DD5E5A0802043E77EBF9DD5E5A0855 +:10D1400002082E07EBD15A0802048400EA49EA3AA1 +:10D15000EA8B9E34E602E80CDD42C004EAE8EA4CC1 +:10D16000EA5C8400EA498400EA9BEAF7D5055A683C +:10D1700002048401EA49EA8C5A080104EA49EA7780 +:10D18000FCC09200E60F4EF2007744F0CF94EA7FA5 +:10D19000EA41DD0F102E48E0669CE0E0E0E0E0E0D0 +:10D1A000E0E0A8008401EACDAE084423F2498422DD +:10D1B000AE504423F24AAE104423F24BAE50846486 +:10D1C000D52B841FEACDAE08EBBFAE084413F24A5C +:10D1D000AE084413F24BAE088448D53E8401EACD34 +:10D1E000AE08EBBFAE084413F24AAE084413F24B4C +:10D1F000AE084413F24CAE08D5328401EACDAE0835 +:10D200004423F2498424AE504423F24AAE1044230E +:10D21000F24BAE50846C4423F24CAED04423F24D1A +:10D22000AE504423F24EAE104423F24FAE50D52000 +:10D230008400EACDAE08EBBFAE08D507EACD840086 +:10D24000AE08845FEBBFAE884413F24AAE084413C5 +:10D25000F24BAE0884414413F24CAE884413F24DB5 +:10D26000AE084413F24EAE084413F24FAE08441316 +:10D27000F250AE08DD9E9200C102EA95960044137A +:10D28000F251AE08DD9E40003C0892104423F24467 +:10D290004010BC08AC1092304403F246AC40DD9E16 +:10D2A00084214403F240AE40EA28EA40AE88A6401A +:10D2B0005A1001FFDD9E4413F258A448AC404413B9 +:10D2C000F25AA448AC414413F25CA448AC42441363 +:10D2D000F25EA448AC434413F260A648EBD1DD9E55 +:10D2E000FC02F0818002F383F18249FFFF4DF001DF +:10D2F000F10249FFFFCA49FFFFD5F00349FFFFDDF7 +:10D30000FC82FC02F0814403F242F182F283AF40DE +:10D31000001F80204403F243AE404403F252ACC0ED +:10D320004403F254AD0084214403F256AC40001F84 +:10D3300080244403F241AE40000F8028001F802C5F +:10D3400049FFFF9CF001F102F203F30C49FFFFCA11 +:10D35000FC829200FC203C6DFB9197C40503000207 +:10D360005510800F43085C0940781EE44273D809C9 +:10D37000470FFF0F4273D40951080FFF4073C002DB +:10D380008E2A86404073C604E625A9F213230003C3 +:10D390001123000B4EF2007C012F8038011F8030DA +:10D3A000010F8034007F802C44F0D1B4EB39EA784F +:10D3B0004A003C00060606767600C003EB8BD503D8 +:10D3C0004021BC08F00792509201AC32F00692A1C5 +:10D3D00092011203000BF008926192011203000EF9 +:10D3E000F009ACB092011203000F220F801E12034D +:10D3F000000C220F80201203000D020F8022AD715D +:10D400008C01ACF41123000C1113000D1103000E5C +:10D410001073000F112300101113001111030012DB +:10D42000107300131203000AD532C003EB8BD5032F +:10D430004021BC08F00A92509201AC3284001003E3 +:10D440000010840192819261100300118400ACB03D +:10D45000AD31ACF41123000C1113000D1103000EBB +:10D460001073000F11030012107300131123001426 +:10D470001113001511030016107300171203000C8E +:10D480001203000D1203000E1203000F4403F140BB +:10D490008421AE40EA37EA31A6405A180104AED0E2 +:10D4A000D5FCFCA044038CF03C0FFB91441FC678D4 +:10D4B0004403F142AC40840044138D08B6013C1D86 +:10D4C000FB91A80F3C1DFB9114008008DD9E842079 +:10D4D0003C0FFB33AC43DD9E3C3DFB33920192217C +:10D4E0009241AC18AC59AC9ADD9E3C1DFB33A68230 +:10D4F0001020800CA6831020800DA680A60110208D +:10D50000800E1000800FDD9E3C1DFB33A682102094 +:10D510008010A68310208011A680A6011020801202 +:10D5200010008013DD9E3C1DFB33A682102080146A +:10D53000A68310208015A680A6011020801610005A +:10D540008017DD9EFC01B63FF28149FFFFD0B41F7A +:10D5500049FFFFDCF00149FFFFE8FC81FC24007F6C +:10D560008060F081F182F283001F803C002F8038C0 +:10D57000000F8040006F804C105F8016103F8014B9 +:10D58000102F8017104F8015101F801A103F801821 +:10D59000100F801B104F8019CF08105F801E103FA6 +:10D5A000801C102F801FD507101F801E103F801C6D +:10D5B000100F801F3C0DFB91104F801DF855B005DA +:10D5C000B046B087F856F001F102F203F8573C0D6F +:10D5D000FB33021F8028AC44001F8054002F80447E +:10D5E000FE775263002040609824001F804810603E +:10D5F000000A58108040FE571010000B221F802C8C +:10D600001210000C221F802E1210000DDD45DD438C +:10D61000AE404403F1408421AE40A6405A1001FFC1 +:10D62000FCA4FC04F08194199600F182100F80177D +:10D630008422100F801B84C13C0DFB91103F80148D +:10D64000104F8015103F8018104F8019103F801C1C +:10D65000103F801F104F801DF283101F8016101F77 +:10D66000801A106F801E49FFFF34B005B046B087A6 +:10D6700049FFFF6AF001F102F20349FFFF2F3C0D61 +:10D68000FB3384208449AC441010000B1020000AA6 +:10D69000DD45DD43AE404403F140AF80A6405A1063 +:10D6A00001FFFC844403F148A6404403F149A6006D +:10D6B000EBEC9601DD9E44100055DD43AE40EA8060 +:10D6C000A6085A0001FF84214403F380AE40EA28F3 +:10D6D000EA40AE88A6405A1001FFDD9EFC004413CC +:10D6E000F381A608EBA1AE0884004413F384AE08CE +:10D6F0004413F56BAE0849FFFFE0FC804453F3810F +:10D70000A72896D8544200F0FEA7401104449688FA +:10D71000400100E496804403F384AEA8AEC0DD9ED1 +:10D7200084004413F386AE084413F387AE08DD9EED +:10D73000FC604403F38496D8AEC049FFFFBEDD45CC +:10D74000DD43AE404413F380A6085A0001FF447342 +:10D75000F3864463F3874493F04A44A0005544B3EE +:10D76000F380A6385A08010D49FFFFDC49FFFFA5E9 +:10D7700010A48000000580005A0001FED5F3A630F9 +:10D780005A0001F4FCE0DD9E441E00008801920274 +:10D7900096014413F3CAAC08DD9E4413F280A60838 +:10D7A000EA42AE08DD9E4423F280A650400080A4E9 +:10D7B0009600AE10DD9E441E000088019681441341 +:10D7C000F286AC884200400B4413F288AE08DD9E1E +:10D7D000FC608141001000094473F280968CA678A9 +:10D7E00080C0EB910000000A401088243C7FFB932E +:10D7F000AE789684A638A470EAB240000844AE38E9 +:10D800004403F284AC40A03149FFFFD70013000865 +:10D810004403F283AE40852044B3F04AEB99000301 +:10D82000000B49FFFFC249FFFFBAA6389604C01398 +:10D8300084011085800049FFEDCE50048001EAECA0 +:10D84000E72FE9F42E07EF435A0801F184023E075F +:10D85000EF43D5174403F2813C0FFB925AA803070C +:10D86000A6404210880BC1DCD5095AA80106A600C3 +:10D87000EA46C807D5D55AA80205A600EAD6C0D000 +:10D88000FCE0C80844138D25A6088C019600AE085C +:10D89000D50E44238D26A6508C219648AE505A08AA +:10D8A00001074413F060A608EA60D5064413F0604F +:10D8B000A608540000FBAE08DD9E96004413F068F5 +:10D8C000AE08DD9E4423F053A6509604EAD98801A1 +:10D8D0009600AE10DD9E4413F06AA688960454218B +:10D8E00000FEAE88A68888029600AE08DD9E44231E +:10D8F000F054AC104403F056AC40DD9E4031C808F3 +:10D90000402189808802401004C084A54443F06D02 +:10D910004403F06EAF603C1FFB943A100420DD9E80 +:10D9200084204403F06DAE40DD9E4403F061A60008 +:10D93000EA46DD9E4403F061A6009207DD9EFC00EE +:10D9400049FFFFFAC80749FFFFF25A0001068401A8 +:10D95000FC808400FC808402FC804000808496006F +:10D960004413F481AE08DD9E96814413F48396D06F +:10D97000A7089248AEC8A6C9AE89EB1888019210D4 +:10D9800096004413F485AE08DD9E96814413F48618 +:10D99000AC88EB188801921096004413F488AE0806 +:10D9A000DD9E96814413F48996D0A7089248AEC8AC +:10D9B000A6C9AE89EB188801921096004413F48B27 +:10D9C000AE08DD9E96004413F48CAE08DD9E440341 +:10D9D000F482A640EA28EAD958108001AE40EA4015 +:10D9E000AE88A640964CC9FEDD9EFC004463F00E56 +:10D9F000A4304200200BC00744138D24F81C840877 +:10DA00004800007BA430EACAC859A430EAD6C00650 +:10DA100044138D23F8108403D56FA430EA46C00662 +:10DA200044138D22F8088402D567A430EA57C00A4F +:10DA300044138D21A6088C019600AE0883FF840450 +:10DA4000D55BA4309604C04E49FF95CBA43042006C +:10DA5000180BC836A4304200140BC834A43042005E +:10DA60001C0BC832A4304200240BC00B4403F064EA +:10DA7000A640964CC12BA640EAD9AE408409D53CBD +:10DA8000EBAAA4404210A80BC923A4404210AC0B3F +:10DA9000C921A4404210B00BC91FA4404210B40BCE +:10DAA000C91DA4404210B80BC91BA400920FC01A94 +:10DAB00084013E07EEDC840FD51F8401D51D84064A +:10DAC000D51B8405D5198407D5178409D515840A73 +:10DAD000D513840BD511840CD50F840DD50D840E70 +:10DAE000D50B4403F01AA400EACAC00549FF957992 +:10DAF000FA01D502FA0884204423F00EAC504423E6 +:10DB0000F01AAC50FC8084214403F322AE40DD9E29 +:10DB10004413F323AE08DD9E4403F323A600DD9EE9 +:10DB2000FC004463F540B6064403F544B6204403C4 +:10DB3000F548B6404403F54CB6604403F550B68052 +:10DB40004403F554B6A0F1044403F558B620F1059A +:10DB50004403F55CB620FC80FC614433F5044423A7 +:10DB6000F5024413F5033C3FFB964433F50580C0B2 +:10DB70003C2FFB993C1FFB983C3FFB955A0003044C +:10DB800048000145DD424413F51AC0048401AE0883 +:10DB9000D502AE084403F5788420AE40843FAE4001 +:10DBA000442FFFAA4403F579AE8084C1AE404403FC +:10DBB000F500AF808400802080408060EA2B8423C1 +:10DBC0004403F501AE408400802080408060EA2B51 +:10DBD000EB26A608EA91AE08840080208040806091 +:10DBE000EA2B44000802EA323C1DFB98A608EA91A1 +:10DBF000AE088400802080408060EA2B4400041A34 +:10DC0000EA32DD454403F509AE40840080208040BF +:10DC10008060EA2BEB26A608EA42AE083C0DFB9892 +:10DC2000A68058210001AE80A68858210004AE8845 +:10DC3000A68058210004AE80A68858210008AE882E +:10DC4000A68058210008AE80A68858210010AE8812 +:10DC5000A64058108010AE40840080208040806034 +:10DC6000EA2B440005AAEA32EB26A608EACCAE0865 +:10DC70003C1DFB98A608EACCAE08840080208040BA +:10DC80008060EA2B2E07EBD44E030116DD403E6781 +:10DC9000EBD4A601B61FDD46DD525A080205840406 +:10DCA000AE09D5038409AE098501DD403E87EEA3A8 +:10DCB000EA343C2DFB3B44020168046100128420DD +:10DCC000EA664060184004A3000304930003400583 +:10DCD000100954A0000340049809960F3E17EEA3C4 +:10DCE000F081A1F3A03344B3F68066000030EA85EA +:10DCF000A833A033FA6F660000C0EAEBA833A03364 +:10DD000092E86600030058000200A83304410013A3 +:10DD1000844C929054027FFFA73597CFFF14404266 +:10DD20000040EA9D40E2000004D7000046080008D9 +:10DD300004C7000140068002B60E460F000F4006E1 +:10DD40000002140700014423F683841F108580001D +:10DD5000AE104423F684AE104423F685AE1044235F +:10DD6000F686AE104403F687AE404403F688AE4014 +:10DD70004403F689AE404403F68AAE408400802016 +:10DD80008040EA2B4403F40BA64044200039548021 +:10DD900080FF4413F415AE888424AE408401EA2643 +:10DDA000440005AAEA32DD45DD43AE40EAA5C0FFE6 +:10DDB000840085208020109580008040FA6FEA2B37 +:10DDC0004403F415EB9C4403F40B10800000A033D3 +:10DDD0006600003040A0288414A30003A033F101A2 +:10DDE000660000C0409004C414930003A033660092 +:10DDF000030040701D04A9F3DD40001F800014D70C +:10DE0000000014C70001AE41D556C8318441441307 +:10DE1000F500AE8884434413F501AE883C2DFB9990 +:10DE20008060A65058108002AE503C2DFB98A65042 +:10DE300058108002AE5080208040EA2BEB2680668E +:10DE4000A608EA60AE083C0DFB98A68058210004A5 +:10DE5000AE80A68858210008AE88A640804658109B +:10DE60008008AE4080068026EA2BD5255A0801247A +:10DE7000A6D0A608543180F3540000F3AED0AE080B +:10DE80008400802080408060EA2B84004413F500E9 +:10DE9000AE084413F501AE08EB26A608EA4FAE081B +:10DEA0003C1DFB98A608EA4FAE0884008020804005 +:10DEB0008060EA2BFCE1DD9E46108000EB33EB0036 +:10DEC0004210EC0940008364EA7BDD9E46100800A6 +:10DED000EB33EB004210DC09400082E4EA7BDD9E7C +:10DEE00044110000EB33EB004210C00940008204F3 +:10DEF000EA7BDD9E44108000EB33EB004210BC094E +:10DF0000400081E4EA7BDD9E441002006413280394 +:10DF1000641308026610820040008124EB6A4413F7 +:10DF2000F7EFA60896009684C203EAA6AE08DD9E27 +:10DF30008422EB33EB00EB9140008024EA7BDD9EF2 +:10DF400064120002C00458008001D50366008001FD +:10DF500064020003DD9EDD9EDD9EDD9EFC4080E0D0 +:10DF60004403F040A780812181425463001C5A7809 +:10DF70000225DD42C0144422FEF64433F04AEB7819 +:10DF8000A6104412FEF65A00EC04AF18D5FA84002D +:10DF9000AE08804184618402DD44D50A4412FEF655 +:10DFA000440FFFECAE08804180078461DD44EA67DE +:10DFB000FA30AE408400EA6384004413F00EAC08EB +:10DFC000FFBF4413F01AAC0897B04403F040AF8091 +:10DFD000DD45DD43AE405A78020A4410005AAE4097 +:10DFE000490000FBC8FEEA7BEB6A4413F0DAA6089E +:10DFF000EBA1402500049690AE88540480FF4413A2 +:10E00000F0EDAE08DD454403F041AE40EA2DEA2DC7 +:10E01000EA2DEA2DEA2DEA2DEA2DFCC0400004A4E9 +:10E020004423F0429600A6D0AE10DD9E965F960483 +:10E03000400080844413F043AE08DD9E4413F04456 +:10E04000AC08DD9E540000FD4413F046AE08DD9E92 +:10E0500040003C0892104433F2004010BC08AC1859 +:10E0600092304403F202EB8BAC4092504403F20432 +:10E07000AC80DD9E4403F20AA640EA28EAD9581093 +:10E080008001AE40EA40AE88A640964CC9FEDD9EB7 +:10E0900096004423F206AE1096484403F207AE40C1 +:10E0A000DD9EFC00DD42C004440255B8FC80440201 +:10E0B00015B8FC80FC00DD42C00444024A00FC802C +:10E0C00044020A00FC804403F20BA600DD9E4413C8 +:10E0D000F208AC08DD9E4423F20AA650964C40009C +:10E0E00080249600AE10DD9EE608E82344F0DEF8BA +:10E0F000EA7FEA414A003C00080E141A20262C321E +:10E100004403F20CD5154403F20ED5124403F21069 +:10E11000D50F4403F212D50C4403F214D50944037D +:10E12000F216D5064403F218D5034403F21AAE40A2 +:10E13000DD9E9200E608E82344F0DF44EA7FEA41EE +:10E140004A003C00080E141A20262C324403F20D1B +:10E15000D5154403F20FD5124403F211D50F440331 +:10E16000F213D50C4403F215D5094403F217D50672 +:10E170004403F219D5034403F21BAE40DD9E920026 +:10E180004403F0C4A600DD9E96004413F0C4AE081C +:10E19000DD9E4403F0C3A600DD9E96004413F0C349 +:10E1A000AE08DD9E4403F0CEA4004413F0D0A64890 +:10E1B000400080E4441D020088015C000080DD9E78 +:10E1C0004402FE00DD9E84214403F0F5AE40DD45AF +:10E1D000DD43AE40DD9E4403F0F4A6009204DD9ED4 +:10E1E0004403F0F7A600DD9E96004413F0F7AE0856 +:10E1F000DD9E4403F0F6A600DD9E96004413F0F683 +:10E20000AE08DD9E4452FE004412FE3E180280011C +:10E21000D9FEDD9EFC40440000FD49FFFFF544634C +:10E22000F068EA6EEA74F803FA09EA32A63052009E +:10E23000000149FFFB4444000492EA32EA53D5F45A +:10E24000FC0049FFFFE992004423F0C7A65096481E +:10E250005A080105581080C0D502966FAE50DD9E59 +:10E26000FC00441005FC4403F0CEAC408420440381 +:10E27000F0D0AE40840149FFFFE9FC804423F0EC7C +:10E28000A6509604541080FB40008044AE10DD9EE2 +:10E29000FC0049FFFFF5FC804403F0CEA4004413CA +:10E2A000F0D0A648400080E4EAACFE0DEAD0DD9E46 +:10E2B00092024413F0E6AC08DD9E4413F050A60829 +:10E2C000EAEBAE08DD9E4413F050A6089637AE0880 +:10E2D000DD9E4423F050A6509617541080F8FE4758 +:10E2E000AE50DD9E4423F050A65096175410808FF8 +:10E2F00040008084AE10DD9E4413F050A608EAB3BF +:10E30000AE08DD9E4413F050A608540000F7AE0896 +:10E31000DD9E4413F051A608EA42AE08DD9EFC00E3 +:10E320008407EB6F84204403F04CAE40840749FF20 +:10E33000FFDB84214403F04EAE4049FFFFECFC803C +:10E3400096004413F04CAE08DD9E4403F04DA60049 +:10E35000DD9E3C0FFC6ADD9E3C0DFC6AA600DD9E46 +:10E3600044030FA0EAB63C0FFB453C1FFB1C3C0FCF +:10E37000FB24DD9EC0045A000209DD9E3C0DFC6AB0 +:10E38000A6003C0FFA5ADD9E3C1FFA5ADD9E400063 +:10E390003C0892104433F1C44010BC08AC189230D1 +:10E3A0004403F1C6EB8BAC4092504403F1C8AC80FF +:10E3B000DD9EFC0044020000A682A6434403F1C295 +:10E3C000AE804403F1C3AE403C0DFB453C1DFB1C3D +:10E3D0003C2DFB2449FFFFDDFC8084003C0FFB77D4 +:10E3E00084214403F1C0AE40DD9EFC602EB72812AC +:10E3F0002EA728352E9728342E7728134E03008712 +:10E40000EBC1C03D3C0DFB54E615E9392E00111A55 +:10E41000C8113C00087250F07FB05CF78BE0E80850 +:10E420003C00087350F07FB05CF79360E90384010F +:10E43000D5028400EB02EB3B5CF00708E807EA3CFE +:10E44000C019EAE384CCC017D5155CF008FCE807D6 +:10E45000EA3CC010EAE384C4C00ED50C5CF00A8C20 +:10E46000E807EA3CC007EAE384C5C005D503840099 +:10E47000EB0284CF2E17EC028006C905840084CFFE +:10E48000EB0280064413F1C210B080004413F1C3C4 +:10E4900010A080004423F1C4441FAC48AC50443F5A +:10E4A000A6084423F1C6ACD04423F1C8AC50960072 +:10E4B0004413F1C1AE08F8A6DD45DD43AE40EB21C3 +:10E4C000A6085A0001FF4403F1C210B00000440343 +:10E4D000F1C310A000004413F1C4440FADD8AC0840 +:10E4E000442FA7984413F1C6AC884413F1C8AC0874 +:10E4F00097B04403F1C1AF80F885DD45DD43AE4000 +:10E50000EB21A6085A0001FFF8035A000104480055 +:10E51000006EEBC1C0283C0DFB54E615E924EA73FC +:10E520005CF00708E807EA3CC019EAE384CCC017AE +:10E53000D5155CF008FCE807EA3CC010EAE384C4A7 +:10E54000C00ED50C5CF00A8CE807EA3CC007EAE391 +:10E5500084C5C005D5038400EB0284CF2E17EC02DE +:10E560008006C905840084CFEB0280064413F1C203 +:10E57000109080004413F1C3AFC84423F1C4441F7A +:10E58000AD10AC50443FA6D04423F1C6ACD04423D8 +:10E59000F1C8AC5096004413F1C1AE08F833DD4524 +:10E5A000DD43AE40EB21A6085A0001FF4403F1C24F +:10E5B000EB9C4403F1C3AFC04413F1C4440FAEA0BD +:10E5C000AC08442FA8604413F1C6AC884413F1C8CA +:10E5D000AC0897B04403F1C1AF80F814DD45DD43CA +:10E5E000AE40EB21A6085A0001FFFCE0FC0649FF03 +:10E5F000FEE23C0DFA5A5A000F1096004413F1C186 +:10E60000AE0849FFFEECDD45DD43AE40EB21A60838 +:10E610005A0001FFFC86FA30F18584228400EB5712 +:10E6200084A1F187EB98F083F084F086F088F0897C +:10E630002E472813B67FF581F382F58AEB7B804164 +:10E64000EA44FC86FC212E07EBCB80E480C55A0807 +:10E65000010A8406441000E1DD473C0DFFF9B606CF +:10E66000D55A9E0CE6025000FFF8E9049680E64277 +:10E67000E81D9600E602E92E2E07EEA3C00B8405E6 +:10E68000DD478406441000E2DD473C0DFFF5B60689 +:10E69000D542F181DD46F1015A0802F384064410A7 +:10E6A00000E3DD47EAEEB606D5365A180D26840695 +:10E6B000441000E4DD472E07EEEA8E01E606E8117D +:10E6C00044F0E4CCEA7F40F03C00DD0F1A060E2453 +:10E6D000141A3C0DFFF5B606D51EEACFB606D51BBB +:10E6E000DD4BA600C804EA68B606D5155A0803141F +:10E6F000EA8EB606D5108E2AE622E808EACFB605DD +:10E70000441000E58406DD47D506DD4BA600490030 +:10E710000D8FB606DD42C016EAAA5CF000A0E91231 +:10E72000DD5A5A08010684033E07EE93D50BDD5AE5 +:10E730005A0802092E07EE935A08030584003E0783 +:10E74000EE9349FFD398B4A63C2DFFF33C5FFB3218 +:10E75000C01BD20BEA8ED0093C0DFFFCD00F3C0D44 +:10E76000FFFBD00CEAEED829A029962F5A081426D0 +:10E77000A029920C962F5A080B2104028011EA421C +:10E7800014028011D51AD214EA8ED0123C0DFFFC6F +:10E79000D00F3C0DFFFBD00CEAEED80FA029962F2E +:10E7A0005A08140C0402801196045A080107040246 +:10E7B0008011EB5214028011B4064412FF804020F5 +:10E7C00008093C0FFB32B641041000084422FF84C4 +:10E7D000966FB622A0014412FF88962FAE08EB0870 +:10E7E0004412FF89A0014452FF909206962FAE0872 +:10E7F000EB084412FF8AA001443D0070920C962F52 +:10E80000AE08EB084412FF8BA0014422C6609212AE +:10E81000962FAE084402FF98986B38110400EAF274 +:10E82000D8FCEB40B446EB18882292229649EBA61E +:10E83000EB40441E00208801920296014413F4002C +:10E84000AC0897F84403F402AFC0FCA19200FC208E +:10E85000447189C438138602463000FF40608C0240 +:10E8600092CC10600009406090091060000A386383 +:10E870008A02462000F04073080292F0401384841C +:10E88000FEE6926C1010000B4410FF00407304026F +:10E890001030000EFEAE40321009FE6E952492E854 +:10E8A00040220A1592281070000C1060000D1030E4 +:10E8B000000F102000101010001110500012FCA0CA +:10E8C000FC02444189983B024C00EBF9380F800070 +:10E8D000FE45380F8400FE85380F88005600000F73 +:10E8E000FC829200FC41B4A0EA68D050EA8ED04E7F +:10E8F000EAEED04C3C0C0327E608E84844F0E70871 +:10E90000EA7F40F03C00DD0F127826485A3C700840 +:10E91000EA88C83E8400EA65D53B84003E07F1AD35 +:10E92000EB158E02E602E8348402EA65D5312E0743 +:10E93000F1AD8C019600E6063E07F1ADE9298405AC +:10E94000EA65D5262E001154C8238406EA65D52031 +:10E950003C0C03285A08030F3C10088BE622E8F60B +:10E96000D5163C0C03285A0803F23C00088BE6023B +:10E97000E8ED8404EA65D50CEB15E602E809D5CB91 +:10E98000EA88C0C98407EA65D5038401EA65040200 +:10E990008014441203009210EA4BEA4E3C1C0327F9 +:10E9A000E62D4EF2011444F0E7B438178501EA78F9 +:10E9B0004A003C001A008C00EC002C016801A80100 +:10E9C000B201BC01CE010602D8010C0212022E17C0 +:10E9D000EF065A18010584203E17EF068420EA51FD +:10E9E000841F3E001131EA38C8083C0C00ACEBC56E +:10E9F0003C0C00ADEB6ED5095A0801083C0C00AE8A +:10EA0000EBC53C0C00AFEB6E3C1C0323449189C466 +:10EA100097C89648EB06EB0E842AB61F84468007FB +:10EA2000F88938048202F081EA66EA9DB49FEAD848 +:10EA3000F5018426844A8067F88D8400EA47F84F00 +:10EA40008421EA51EA38C8083C0C00ACEBC53C0C08 +:10EA500000ADEB6ED5095A0801083C0C00AEEBC5C1 +:10EA60003C0C00AFEB6E3C1C0322449189C497C858 +:10EA70009648EB06EB0E8423B61F84428007F85AB3 +:10EA800038048202F081EA6644020040B49FEAD86A +:10EA9000F501842284438067F85D8405EA47F81F06 +:10EAA0008422EA513C1C0324449189C497C89648A7 +:10EAB000EB06EB0E8421B61F84428007F83B380436 +:10EAC0008202F081EA6644020080B49FEAD8F50130 +:10EAD000842284418067F83E8400EA47480000773A +:10EAE0008423EA51460000CC500002BCEB0E842681 +:10EAF000B61F84428401F81E441189C43800820282 +:10EB0000F081EA66440200C0B49FEAD8F50184228D +:10EB100084468461F81F8401EA47D5588423EA516A +:10EB200046000093500000AFEB0E8426B61F8442CF +:10EB3000840349FFFEC7441189C438008202F08172 +:10EB4000EA66440200C0B49FEAD8F50184228446F4 +:10EB5000846349FFFE7E8402EA47D5388424EA5163 +:10EB60008404EA47D5338425EA518400EA47D52E48 +:10EB70008426EA512E07EF065A0801218400EBA3F0 +:10EB8000D51D8427EA518405EA47D5208428EA5117 +:10EB90000402801644120200EA4BEA4E4624259FE6 +:10EBA0004613DA6050108E45502101BAA841A842A0 +:10EBB000A883A844A845A846A8478405EA47D506DF +:10EBC0008407EA47D5038406EA47FCC19200DD408A +:10EBD000A6019E44E622E9075A000906DD4BA6007D +:10EBE000E602E8098400F811AE08F816A6405A10AB +:10EBF00001FFDD9EEBAEA600C0085A0001065A00D8 +:10EC000002045A08030A84004413F572AE08441340 +:10EC1000F57383FFAE084403F3808421AE4083FF85 +:10EC2000A6405A1001FFDD9E8400EBC784214403F7 +:10EC3000F403AE40DD9E4403F403A600EAD0DD9E5B +:10EC40004403F40CA6009600C8074413F3CFA6486B +:10EC500040000406DD9E8401DD9E8400EA80EBC74F +:10EC6000AE08DD9EFC005A08011149FFFFB249FFC2 +:10EC7000FFDD842B8400EB2D44138D463C0BF61EE8 +:10EC80003E07EBDCAE08FC8049FFFFE9FC80440353 +:10EC9000F01DA680A641A6C04011050458108400AE +:10ECA0009688AE809228A681AE41EA284413F421CA +:10ECB000F806502100014C21FFFE8440AE8844201C +:10ECC00000004430000A83FF502100014C21FFFE68 +:10ECD000A6409648AE40DD9EFC20DD464432DFB4BF +:10ECE000EB694422E35C5A08021484004472DB148A +:10ECF0004462E3E84452E980F81238408008384220 +:10ED00008000384100088C015A0820F8FCA08400DB +:10ED10004472E33C4462ECEC4452DA8038438000B5 +:10ED2000384180083843000083FF384100083842EA +:10ED30008000384080088C015A0820F2FCA0A640D0 +:10ED40003E1011D0A6413E1011D1A6423E1011D264 +:10ED5000A6433E1011D3A645A68440210500A64730 +:10ED6000A6C6401185000030000900400008EAF105 +:10ED70003C3808EC0030000B0040000AEAF13C3857 +:10ED800008ED0030000C3E3011DC0030000D3E304C +:10ED900011DDEBCE969396DC3E3011DEEBCE964B3A +:10EDA0004231840B3E3011DFEBCE3C2808EA423181 +:10EDB000880B3E3011E0EBCE3C1808EB42318C0B57 +:10EDC0003E3011E10030000F96DF3E3011E200309E +:10EDD000000F92643E3011E300300011004000103B +:10EDE000EAF13C3808F20030001300400012EAF16A +:10EDF0003C3808F3003000150040001496CFEAF1CB +:10EE00003C3808F40030001592623E3011EA0030C0 +:10EE100000170040001696CFEAF13C3808F60030A3 +:10EE2000001792623E3011EE0000001E962F3E0049 +:10EE300011EF42012C0BC006440FF000FE873C2866 +:10EE400008EA4200AC0BC006440FF000FE473C1835 +:10EE500008EB84093E0011E2FA063E0011E3DD9E54 +:10EE6000A4C0442200004412D7BCEA2FB661A4C259 +:10EE7000EA2F1430800FA4C4EA2FA8CAA4C6EA2F30 +:10EE8000A8C902300008EA2F143080100230000AAE +:10EE9000EA2F143080080230000CEA2F1430800969 +:10EEA0000230000EEA2F1430801102300010EA2FD9 +:10EEB0001430801202300012EA2F14308013023016 +:10EEC0000014EA2F1430801402300016EA2F143098 +:10EED000801502300018EA2F143080160230001A14 +:10EEE000EA2F143080170200001C4021004014203B +:10EEF0008018DD9EFC00EB403C2DFFF3EB188822D0 +:10EF000092229649EBA6FC80FC004423F6AC441305 +:10EF1000F6AD5A080106AE108407AE08D504840089 +:10EF2000AE10AE08840080208040FA6FEA2BFC808F +:10EF3000B44084A08C449C2DA2D196005A5820063F +:10EF400080A05A0823FADD9E5441803F384094083F +:10EF50008CA197689266D8F3D5F4FC20B4808460C5 +:10EF60008C8484E5B4045A38060566000FFFD50486 +:10EF7000921E4000780842219C2484A096905A203A +:10EF8000200C386088008C414063140C8CA68806E5 +:10EF900096905A581EF68C6196D8AA215A3807E4E2 +:10EFA000FCA0FC20B4608400503180249583A31918 +:10EFB00097B0844099568C415472000F9768969090 +:10EFC0003870940892845A2808F78C0196005A08E1 +:10EFD00004EFFCA0FC20B4608400503180349583A1 +:10EFE000A31997B0844099568C415472000F9768CA +:10EFF00096903870940892845A2808F78C019600ED +:10F000005A0804EFFCA0FC45EA683C0FFB3284235D +:10F010004403F40BAE4084264403F404AE40840160 +:10F020004413F407AE084413F408AE0884404413B4 +:10F03000F01EAE884413F420AE08EA365A080105E3 +:10F04000EA684900081F4402D7BC4412DB1449FF98 +:10F05000FF714402D7BC4412E980F8054402D7C0CE +:10F060004412E30849FFFF9F4412E3E84402D7BC7F +:10F0700049FFFFB2490009FE4402000049000A713D +:10F08000B1C1440189A83B00440480273B00C4244B +:10F09000A600AE08B184440189B43B004404802634 +:10F0A0003B00C424A600509F801CAE0884498420E5 +:10F0B0008009EA3D84011004800684204442E33C38 +:10F0C0004432ECEC4402DA8038238400382204080D +:10F0D00038230400382184083824840038200408A8 +:10F0E0008C215A1809F3FCC5FC00B48084405042BE +:10F0F0000024840080A098D096D838308C00958267 +:10F1000096DF4031980C8C0188A35A0808F68C4889 +:10F110009690AB615A2820EFFC80FC04A649B440CD +:10F120005A1003045A180D0FEB38A648C9054412AB +:10F13000E980EA7AFC845A1803254412E308EA7A43 +:10F14000FC845A180407F81658000003B889FC8498 +:10F150005030FFF6E662E80B842084463820FC0835 +:10F160008C215A1820FD803FEA7AFC848E28E62202 +:10F17000E8088382B8096600000F83FFEA60B88957 +:10F18000FC84FC00A68180C05A2003145A20061279 +:10F190009E14E602E90E50017FF8E602E90E5001E6 +:10F1A0007FF6E602E90A5A280D1EDD465A080206D5 +:10F1B00084003E07EB8AD50484013E07EB8AEB010D +:10F1C000A6712E27EB9F84812E37EBBF4452C4DCFF +:10F1D00049FFFA3ADD465A000206EA52802649FF04 +:10F1E000FF9EFC80FC00B4808440504200348400C8 +:10F1F00080A098D096D838308C00958296DF403128 +:10F20000980C8C0188A35A0808F68C489690AB613C +:10F210005A2820EFFC80FC014412DFB4F08149FF42 +:10F22000FE9EF001EB69F9B9FC81FC2480E180C00D +:10F2300049FFFD542E2011E24442DFB44402DA605B +:10F240002E3011D15A780635842938120808E66222 +:10F25000842238100808E924DD465A080222840076 +:10F260005A6803122E1011D14432E308F83C5A08B0 +:10F2700020FFEAA4C00D8E228440881FE24110F0D6 +:10F280007FFFD5064422E980F83F5A0820FFEAA410 +:10F290008429381F8008EA52803FEA7AD54CEAA4D4 +:10F2A0004412E35C8443EB03EA52EA7AD5448420B7 +:10F2B000381208085A68030538600808D504842104 +:10F2C00038100808E662E930DD465A08022E5A680E +:10F2D00003192E0011D184285A08020384278400C0 +:10F2E0004432E30838218000382F80088C0183FFE6 +:10F2F0005A0820FAEAA4C010881F10107FFFD50C0E +:10F3000084004422E98038110000381F80088C01F5 +:10F3100083FF5A0820FAEAA48422381F8008EA52A0 +:10F32000803FEA7AD508EAA44412E35C8445EB0303 +:10F33000EA52EA7AEA5249FFFF70FCA4EBFA3C1C5D +:10F340000002D10C3C1C0003D1093C1C0004D10676 +:10F350003C0C0005FE2DEAD0DD9E8401DD9EEBFA1B +:10F360003C1DFFF3D10E3C1DFFF4D10B3C1DFFFBF8 +:10F37000D1083C1DFFFCD105EAEEFE2DEAD0DD9E52 +:10F380008401DD9E844540300817848696D8FE248B +:10F3900038108E024000800D962FDD9EEBEB3C3C3A +:10F3A00000005A1802043C3C0002EB8C442201206D +:10F3B0009230EA99401104400440800A462C003FF4 +:10F3C00050210FFF54000FFF40004808FF16FF07B1 +:10F3D0001440800AEB8C443201809230EA99EB753C +:10F3E0000430800AFE9EFE171400800ADD9EFC0099 +:10F3F00044620104406300202203000049FFFFD063 +:10F40000A4303C0BF629FC80FC4180C03C0DAC7460 +:10F41000F081EB48EACF80E181224C5000C1CE045C +:10F42000AF9084E1D50F5A680409800149FFFFE1DC +:10F430001074800084E3D506B00138600400AE503B +:10F4400084E38400EB69386080088C014492DA60C0 +:10F450005A0820FB49FFFF85C0123C0DFB3B4412BC +:10F4600003C0040000149210EA4BEA4E3C1C032235 +:10F470008C259648AE44AE45AE46AE4749FFFF6088 +:10F48000C0693C2C00024412042050810050B40892 +:10F49000443397809210EA4BEA4E3C1C0323848845 +:10F4A0008C259648AE443C1C032484A28C259648A7 +:10F4B000AE46B408441203609210EA4BEA4E3C1C7C +:10F4C00000AC84CB8C259648AE443C1C00AE86092B +:10F4D0008C259648AE453C1C00AD8C259648AE4622 +:10F4E0003C1C00AF8C259648AE47B408441203C0BC +:10F4F0009210EA4BEA4E3C1C03223C2DFB328C2539 +:10F500009648AE44AE45AE46AE47840004110008AE +:10F51000966FE001E8409843A6489648E634E8092B +:10F52000E62CE810C1125A180A1339048008D50FC6 +:10F530005A10140650F0FFE0E2AFE90938448008A1 +:10F54000D50638648008D503387480088C0196008D +:10F55000D5DEEBFAEA68D003EA8ED81D84283E1087 +:10F560000270842A3E1002723E10027C2E1011E2BC +:10F570004422DFB4382104004402DA605A28090624 +:10F58000844238200408D507387004082E1011E38F +:10F5900038700408EA52EB6949FFFE26FCC14413A7 +:10F5A0008D40AE08AE98DD9EFC0180C0DD4BB65F9D +:10F5B000F381AF808001EA348006B43FF20149FF55 +:10F5C000FF25FC81FC6084003E07EB8ADD4084233C +:10F5D00000A0000144738D41AE410093800049FFBB +:10F5E000FB7D840080408067DD5244638D4000B322 +:10F5F000000049FFFFDBEA524412DB1449FFFCAF75 +:10F600008403DD528049806749FFFFD0E7628403AD +:10F61000E8028400AE304412DB14EA5249FFFC9F3A +:10F62000A630DD528049EA4A49FFFFC0A6303E07B6 +:10F63000EBD2DD4010A00001FCE0FC208380BA1278 +:10F64000BF1354217FFF444203204022084092F020 +:10F650005403FFFFA7D5844CFFD440738040EA9D3C +:10F6600088E0C3239221520086409641EA8A4000F6 +:10F67000801796009E45E637E81384614061800C50 +:10F680009F41842088039AA94041880C9881402199 +:10F69000880CFEA78C21FF975A1805F7D51AE605A6 +:10F6A000E916466FF800D5152E07F1ACC80984019C +:10F6B000466CCCCC3E07F1AC50630CCCD50A46630B +:10F6C00033333E37F1AC50630333D503446001FF5D +:10F6D000FFB3DD42C00292D042033C0BF80E464F0E +:10F6E000E3FFF827A8394203380BF80750420FFF11 +:10F6F000F829A8394203340B8C0654100007A039AE +:10F7000083FF66000007FE0FA8394203300BF82282 +:10F710006600700040000584B60742032C0BF81AFF +:10F7200066000E0040000524B6074203280BF812BD +:10F73000660001C0400004C483FFB6074203240BE7 +:10F74000F809660000384000046483FFB6074203EE +:10F75000200B8C0654100007B40783FF66000007D7 +:10F76000FE0FB60742031C0B8C0654200007B4079B +:10F770004418FFFFFE0E40000A044223180BB60790 +:10F780008C4654310007460FFC7FB44750000FFFF2 +:10F79000FE8640210E64B6474223140B8C4654313A +:10F7A0000007B447FEA640210EC4B6474223100B03 +:10F7B000F80B462F1FFF50210FFFFEAE40210F24F4 +:10F7C000B64742230C0B8C46B4A75431000783FF85 +:10F7D0004628FFFF50210FFFFEAE40210F84B647A1 +:10F7E000A0F94223080B8C469697FE5E40108A04CF +:10F7F000A879A0B94213040B8C269657FE16400038 +:10F80000066497B4A8398CC654030007A1B9FFA6B3 +:10F81000406302C4A9B9FCA08400EB38AE08EA6FCB +:10F820003C1BF6374412C9B43E07EBD2AE08AE0912 +:10F83000AE0AAE0BDD9EFC60847FAED084DF8460B8 +:10F8400084A18246808382034532C9A881258143F1 +:10F8500002B0000097D8E3618220E80A38A98C083A +:10F86000A540E2B2E8098245820784A0D50638990E +:10F870008C08AFD0D50284A0031880008C61E3A669 +:10F880008C024068BC1B4043BC1B5A3804E35A50EE +:10F89000010380908004FCE0FC42FA40812080E17A +:10F8A000801F8420EA3D2E27F1B44432C668EABAAC +:10F8B0003801880880834462EEC4C704387309099C +:10F8C000D50484013803090984209C1145018AE488 +:10F8D00045100BB899419757387214005A70FF0FB2 +:10F8E00038380400385315014231C424403194762D +:10F8F000385F9E028865383F9E0A8C215A1808ECB2 +:10F90000842080618081385F86029788E2858C211F +:10F9100040333C1B4042BC1B5A1804F7E647E9023F +:10F9200084003E07F1B410348000FCC2FC002E2796 +:10F93000F1CA84C3401118574430032096904412F2 +:10F94000817842110C73DD5DEB7F2E07F1CA8C01CB +:10F9500096004060183796484010041B3E17F1CAC5 +:10F96000FC80FC002E27F1C984C340111857443095 +:10F97000032096904412817842110C73DD5DEB7F79 +:10F980002E07F1C98C019600406018379648401048 +:10F99000041B3E17F1C9FC8084003C0BF6213C0B94 +:10F9A000F611DD4BA600C0049E43E622E812440394 +:10F9B0007320A6003C0BF6114413732244037321F9 +:10F9C00044237323A600A648A6903C2BF621D526F7 +:10F9D0009E41E622E9035A0805208400445373201F +:10F9E000802044337334A7283C23F6118CA4884428 +:10F9F0003C2BF6110022FFFD88020022FFFE004290 +:10FA0000FFFF88223C23F6219601884496493C2B2F +:10FA1000F621DBEAD503840080203C23F6218822EE +:10FA20003C23F6119649880296013C1BF62188205A +:10FA30003C0BF6113C1BF61FDD9EFC00846080A38E +:10FA400084DF9718E282E80738500D0938608D0985 +:10FA50008C61D5F8FC80FC0084A040308C204C11D7 +:10FA60008018A500A588E2C4E803A500AD08A5801C +:10FA7000A510E2C4E803A500AD100A4080010A61A8 +:10FA800000018A86E0A4E80297618C02D5E980052E +:10FA9000FC80FC2084A08260412140098082800596 +:10FAA00097E9E2E3E83C5CF38064E90650F3FF3851 +:10FAB0005CF78064E8304069942002F30000031092 +:10FAC0008000E3AFE8050303000013008000031388 +:10FAD000000002F20000E3AFE80503030000130298 +:10FAE000000003108000EB864108C001E010E8131D +:10FAF0003D180B6240080013EB863D080B63A5B070 +:10FB00003C680B643C780B653C080B663C280B6733 +:10FB10003D280B688CA18C228C82D5C3FCA0FC00F4 +:10FB20004440032080C14413000042101073800140 +:10FB3000802280434430012CEB66AC30FC804010C6 +:10FB400004204430FFFF84404C00800EA500E244B6 +:10FB5000E803A4809691A500E283E803A4C096D9A7 +:10FB60008C02D5F344000096420180019A10960160 +:10FB7000DD9EFC7BB18281808420449000C8800699 +:10FB80008448EA3D4014B036856040908408447350 +:10FB90002D5085404CA60014B004B05D44200032C6 +:10FBA00049FFFF4DEA6F8007EB3138132901E2204E +:10FBB000E803380329098D4188E9D5ED44732EE027 +:10FBC0005AB001048561D5E64422C3A1441007D090 +:10FBD000800649FFFE32EA2338130101EB5349FF47 +:10FBE000FE5D2E07EB90EB8F3813010138230901DE +:10FBF000E241E8059A8AEB79E804D5028440EA23D9 +:10FC00009451443001F440108C37E623E807C907CB +:10FC1000441000C740108806D5028423EB8F2E576E +:10FC2000F1CBDA072E37F1B588613E37F1B5D50350 +:10FC30003E17F1B52E37F1B5E663E8035A1803060F +:10FC400084003E07F1B580023E27F1CBFCFBFC208F +:10FC500080C180E0AE08840449FFFF8D4412C9A82A +:10FC600038109C002E27EF085A180108E642E809D0 +:10FC70008C413E27EF08D505C2048E413E27EF0890 +:10FC800084203E17EF072E17EF08C10584213E1789 +:10FC9000EF07AE30FCA0FC6044600320FE344483D8 +:10FCA00001904463000050B1819050A2019080E126 +:10FCB0008122890088C0EA6F8006EB31021480003F +:10FCC00081A9E220E802EB1050C30190EA6F800C9A +:10FCD000EB31021680008D22E220E8031204FFFFC0 +:10FCE0005015FE70800650257E70F809A47881A713 +:10FCF000E220E802AC38802B800C804AEB04EB4514 +:10FD0000021680008CE2E220E8031203FFFF50633A +:10FD1000006450B5806450A500644C647FCEFCE064 +:10FD2000FC00EAF92E17EF2EC0203C0DCAFE5A182F +:10FD3000010592019601D503920296013C2DFBBE6E +:10FD4000E2402E07EF0AE806E61EE80F8C01EB5CA6 +:10FD5000D50CC00B5CF10E10E906E60FE9048E0528 +:10FD6000EB5CD5038E01EB5C5A1801112E07EF0AEC +:10FD70005A081E058405EBFFD50CE614E904840639 +:10FD8000EBFFD5078407EBFFD50449FFF2E7EBFF54 +:10FD9000FC803C33F8DF5CF18033E913FC008480A5 +:10FDA00084C3E282E80D40301020A558A4C88C819D +:10FDB000FEF490624031945C1A308001D5F3FC80EF +:10FDC000DD9E84003E07EF098400EADFDD9EFC0033 +:10FDD0003C03F8DFEB2CE905EAEA84003C0BF6363D +:10FDE000EB70EB2CE9038400EAC3FC8084003E073F +:10FDF000EF0884003C0BF8D9DD9E3C03F8D9EB2CCE +:10FE0000E905FC0049FFFFF4FC80DD9EFC012E07A4 +:10FE1000F1CCC0048E013E07F1CC49FFFFF02E0764 +:10FE2000EB90501F800749FFFF142E07EBB15A00DB +:10FE3000FF2D84023E07F1CC2E07EF038C013E0715 +:10FE4000EF034400004ADD412E17EBB1E624E81D24 +:10FE5000EA3844F0FC5CEB39EA78DD0F041804184A +:10FE6000C81484018427EBA33C1E03273E000C84A6 +:10FE7000EBF6D50B5A08010A8401EBA38407EA6567 +:10FE800084003E000C84EBF6FC81DD40A6015A089C +:10FE90000309DD5A5A080206FC0049FFFFB9FC803D +:10FEA000DD9EFC0080C084003C0BF61F49FFFD7600 +:10FEB0002E07EBA4406300D6DD463C2394985A00FD +:10FEC00002088423FE549649E2C1E90BD50EEBE209 +:10FED000E2C20010002BE8093C03F61FE220E9050E +:10FEE0008400EAC38400D5028401FC80B461AE18AA +:10FEF0005A2802049208AE19B4018840B641DD9E2A +:10FF0000FC448140B61F81218400B1C13815000036 +:10FF100038101C088C015A081AFB44001900F844D8 +:10FF2000EA8EB43FA680AE880400001EB43F921053 +:10FF30009C89962FB65FAE09F82B8442440002805C +:10FF4000F835EA68803F04600014EA9D92D0EA66C2 +:10FF5000406018408386B80E8442F821F823B80B1D +:10FF6000F829F823B41F00130028AE40B41F8442C0 +:10FF70009C41B63F3C1C0000046080144412018088 +:10FF800092D0EA664060984000130028AE41B41F4A +:10FF9000803F8C01B61F83FF0403000E921096056C +:10FFA000F80502030016803F844249FFFFA10403C5 +:10FFB000000B803F921054000FFF83FF4E00FFF6AE +:10FFC000440FFFAA10048051EA40EA28000480513F +:10FFD0005A00CC04AE88D5FBDD42C0074412FE5166 +:10FFE000840280418461DD44840038138000381528 +:10FFF00000088C015A081AFB840010048051FCC4CC +:020000021000EC +:10000000FC0044030C803C1C01DB442000C8EB7F57 +:10001000FC80FC002E07EBB28E01E602E808DD5DF5 +:1000200044030C80EA753C2FFBA0EB7F2E07EBB25C +:10003000EB295A08011644530C80442F74F84430BD +:10004000096044430FA08400986AA5A8386080091D +:10005000500003204C01FFFB8CA2DCF6FC80FC80EE +:10006000FC0049FFFEB649FFFFCD2E07EBB2C008EA +:10007000EAEADD4BA60049FFFFCE8400EB88FC8056 +:10008000FC0004000014441200609210EA4BEA4E97 +:100090002E172938101000182E17293910100019A2 +:1000A0002E1729361010001B2E1729371010001A92 +:1000B000A0454210F008A845A0454210F408A84504 +:1000C000A0454210FC08A845A0454210F808A845E4 +:1000D000DD42C00544037320F804FC8044037384AC +:1000E00049FFEB54FC803C0FFC74DD9E2E37EF2E55 +:1000F0005A3001062E37EC1C5A38011C84603E37FA +:10010000EC1C003000103E372BE1A0053C0FCAF973 +:10011000A60A3E072C2CA60B3E072C2DA4123C0B46 +:10012000962BA4133C0B962CFA043E072C5ADD9E0A +:10013000A6C03E372BE1A0033C0FCAF9A6083E0734 +:100140002C2CA6093E072C2DA4103C0B962BA41199 +:100150003C0B962C84043E072C5ADD9E5A00010568 +:1001600044128178D502EA755040832080A1840032 +:100170001A028001DCFEFC204453000044630C8022 +:10018000800180650A218001A5C04023885C1A2077 +:1001900000014C027FF950528320DEF38400443288 +:1001A00081784440096084A0988338608001386178 +:1001B000140950528320DCFA8C025A0B20F6FCA062 +:1001C000FC60848084FF84C1826780A4822444927E +:1001D000C9B48166810403000000552200FFE38258 +:1001E0008140E80E03008000E383E80A3884900829 +:1001F000A580E2D3E8088266823284C0D50538B48F +:100200009008D50284C00B00800102A500008C81FB +:10021000898AE3878C0240783C1B40593C1B5A4832 +:1002200004DC5A60010380B18005FCE0FC002E175D +:10023000EBE93C6DFFF3C10B84003E07EBE9441092 +:1002400000E684063C6C000ADD47D534C80ADD5A56 +:100250005A000131DD5A5A08022E3C6C0002D52AA0 +:100260005A08030EDD5A5A0801053C6DFFF4D522E9 +:10027000DD5A5A0802203C6C0003D51C5A08010EB6 +:10028000DD5A5A0801053C6DFFFBD514DD5A5A08AA +:1002900002123C6C0004D50E5A08020DDD5A5A08B1 +:1002A00001053C6DFFFCD506DD5A5A0802043C6C82 +:1002B00000058006FC80FC002E07EBCEC82B3C0D11 +:1002C000FBC85CF00032E9042E07EEF6C0062E07EC +:1002D000EEF55CF00032E91E84203C1BF61B840026 +:1002E00044326EB8EB30E202E80698838C01AE50DF +:1002F0009601D5F93C0C01D73C1C01D9EA4D4400CC +:100300000033EADFEA75EB77DD5D49FFFD448401E8 +:10031000EAADFC8040300C204C0180051A20000121 +:10032000D5FCDD9EFC4051FFF9B8F0818400EB3A2A +:10033000EA75B0028440EA22EB6B500F8328EA751D +:10034000EB23EA22EB6B84C044A003204492817823 +:100350004472EE9C800942032873B042502F8328D8 +:10036000EA22EB66380399098CC1EB3A5A6803F428 +:10037000B042502F8328EA22F001EB66EB3A3C08AA +:100380000B5AEA75F00149FFFAD3DD4BA6008E0344 +:10039000E602E8113C03F63744600032EB2CE90832 +:1003A0009E4150007FCE406018D69B8E97B13C6B2B +:1003B000F637D504EBE20260000EDD465A00020576 +:1003C0008403FF8497B13C03F77E3C100B5C3C0830 +:1003D0000B5BE220E8033C080B5CE2C03C680B5D71 +:1003E0003C080A783C680A79E80584023E07EF0970 +:1003F000D5162E17EF09C1048E213E17EF093C13C5 +:10040000F62FE220E90A3C03F8DF4410EA5FE2201D +:10041000E9068C01EADFD5038400EADFEBC9E602D6 +:10042000E9078401EAA084003E07F1B0D509840001 +:10043000EAA02E07F1B0C0048E013E07F1B051FFD3 +:100440008648FCC044038D40A6402E07EBE1C10660 +:100450002E17EBE05A1801038C013E0728D8DD9EC9 +:1004600044100055DD43AE40EA80A608C8FFDD9E7B +:100470003C1DFFF3442200C0040080149210EA4B9C +:1004800040010040B400920A96373E07EBC00400DA +:100490008014441200009210EA4BEA4EB42000008F +:1004A0000028922A96773E17EBA43E07EBC8DD9E04 +:1004B000FC008400EBC7DD4C8421AE408401802029 +:1004C000EBB3DD43DD45AE403C2DFB37A6505A1063 +:1004D00001FFDD45AE40840AEA3EDD4C8421AE409A +:1004E0008400EAD2EBD5FC80FC008403EB88EA941C +:1004F00084008040DD52EA4AEAA18400EAADEBD5EF +:1005000084013E07EEF6EB4BDD4BA60049FFBEFC37 +:10051000EAEAFC80FC20444200002E6729A48420E3 +:1005200044338D4080E49688E246E819A7589881C4 +:10053000C50400510020D5033850040041020400D6 +:1005400010580184A758C50400210028D5030021B4 +:10055000000899791022818C8C21D5E6FCA04422D8 +:10056000D7BCB46244420000EB8CA0919230EA996F +:10057000401204400410800A923254108FFF964BB0 +:10058000121000813C1BF62EEB8C042100159230DA +:1005900044320180EA99EB7554217FFF4432000C0C +:1005A000402188400230801F103001040230801F3B +:1005B0009268103001050230801E103001060230B2 +:1005C000801E926810300107A4D310300108A4D314 +:1005D000926810300109A4D11030010AA4D19268A8 +:1005E0001030010BA112846192985452003F0440D4 +:1005F00080114041903E404290E41040010CA09296 +:1006000004108011924896AFFECE40310CE41030B9 +:10061000010DDD9EFC2080E080C1DD42C00C501346 +:1006200001048041846A8402DD44EA69840249FF4E +:100630009C18D504840249FF9C14EA8E4422018050 +:100640008380B914BB1592304402000C5431FFFF73 +:1006500040300C40EA99000301054011044000239A +:1006600001044001010096011200801F00030107F0 +:10067000002301064001010096011200801E0003C4 +:10068000010C40201C0950408044B404EA4F400053 +:100690000824B604B4040023010DEB52400008F511 +:1006A000B6040003010900130108EBEC9601AC1B32 +:1006B0000003010B0013010AEBEC9601AC190003D7 +:1006C000010CA09A5410003F460C0FFF50000FFF82 +:1006D000FE1640000704A81A0003010D5410003F45 +:1006E000A01A66003F0040000504A81AC7038EE167 +:1006F00097F88403DD528047EA4A49FFF757FCA088 +:10070000FC6081218162814380C4DD54A60896008B +:100710005A0801FEDD5BAE088020EBB3DD59A64030 +:10072000C9FFA6405A1801FF84003E07EBD0DD4206 +:10073000C020EA305A0807FFEAB0EAB6EA4DDD4CBD +:100740008421AE400074812ECF05F8083E77EBD0AF +:10075000D5100073005197FCCF0649FFBE251074D9 +:10076000809ED5058400EBA849FFBD628401EAE0C4 +:10077000840AEAD5840010030051100300521003CC +:100780000053FCE03C1DFFF34422000004108014E1 +:10079000463C003F9230EA99401104400420800A10 +:1007A00050318FFF54000FFFFE9E40210244142061 +:1007B000800ADD9EFC4280C2812080E1FA408420D4 +:1007C000801FEA3D987E2E27F1C04432C674EABAF3 +:1007D00096493801880880834462EE8CC10438133E +:1007E0000909D50484013803090984209C114501B5 +:1007F0008AE445100BB899419757387214005A7023 +:10080000FF0F38380400385315014231C4244031F9 +:100810009476385F9E028865383F9E0A8C215A186C +:1008200008EC842080618081385F86029788E285A9 +:100830008C2140333C1B4042BC1B5A1804F7E6474E +:10084000E90284003E07F1C010348000FCC2FC6065 +:10085000EE38509F8028F082F183844884208009FC +:10086000B1CCEA3D800784208448EA3D8400EB3A1D +:10087000F003446000C8406300D654D300FF400634 +:1008800084089600F08485809431F081048F800282 +:100890008169814C97B1F0034CA0005FB00E501FEE +:1008A0008100F20449FFF8CB4452817844428AD84F +:1008B00040E61400888C14BF8005B04E502F810094 +:1008C0008066800EF487EB45F086B0675007019094 +:1008D000502F81648066EB45F50602158000E20525 +:1008E00040503C1A9629E220F407E8031255800094 +:1008F00050E703204CE27FE3B04E502F810080662A +:100900008008EB4550E40190F086B067800E502FD0 +:1009100081648066EB45F406F105E20440403C1A30 +:10092000A4489621E2208D62E8031245FFFF802D46 +:100930008008EB313803A909802D800EEB31381384 +:10094000A901E220E8033803A909F0018D418900DB +:1009500040C60000D5A1F00249FFF805DD463C1D68 +:10096000FC740220800F5A0002058403FE849691D5 +:10097000806280298007F97B38138101100F80275E +:1009800038248101500F802749FFFF1644138D4101 +:10099000A608004F802738038101EB3AA6C83853D8 +:1009A000910138238D0138048D018802382491018A +:1009B0008845E040E8059A82EB79E805D502844055 +:1009C000103F8027A608443001F4945140108C3722 +:1009D000E623E807C907441000C740108806D5027F +:1009E0008423002F80272E57F1C8DA072E37F1C154 +:1009F00088613E37F1C1D5033E17F1C12E37F1C1F1 +:100A0000E663E8035A18030684003E07F1C180023A +:100A10003E27F1C8EDC8FCE08401DD9E840044124D +:100A2000C674845FEB038C015A0808FE84003E07FD +:100A3000F1C0DD9E5A0801078401AE088400AC10A5 +:100A4000DD9EEBE20200000F42420001E283E9F585 +:100A5000A410E61EE8048C01AC10DD9E8400AE08F4 +:100A6000DD9EFC40812184203C1BF77E109100001C +:100A7000842480C2814349FFFEEC80E04402C9B473 +:100A80003810240081205A18010FEBC9E602E8044F +:100A90008C013E07EF0984013E07EF2E84003C0BDA +:100AA000F635D52E4412C71E84004422C45A3C3366 +:100AB000F77E3C43F62FF9152E17EF09C1048E215E +:100AC0003E17EF095AA801128460802338048C0075 +:100AD000C8038C2196498C615A3804FA5A180406C6 +:100AE000EB708C01EAC3D5038400EAC33C13F8DF42 +:100AF0004400EA5FE201E9048C213C1BF8DF84003A +:100B0000EAA0EBC9C0048401EAA0AFF0FCC0FC007D +:100B100097844060982044100640FE0C4413000067 +:100B20004000803C80228043EA22EB66AC30FC80AF +:100B3000FC6051FFF9B8B67F8160EA22B002818182 +:100B400080E2EA758440F481EB6BEB23EA22500FDC +:100B50008328EA75EB6BDD4C8421AE4084C08401B0 +:100B60003C6FFB7C4493F04AEA7044A00055EAEAEB +:100B700044D3F4234C65804784003E07EBEF8400A8 +:100B8000EB6884018020EBB3840A10A48000EA3E65 +:100B9000000680005A00040510A48000D5FA850ADA +:100BA00085C02E07EBEFE20CE825EA305A0807FF74 +:100BB0003C8FFB473CEFFB7C2E07EBEFB43F5A78B2 +:100BC0000209F201B0C2504F832849FFF866D50BE5 +:100BD000B082503F83285A78010549FFF7A2D50318 +:100BE00049FFFF972E07EBEF8C0196003E07EBEFD6 +:100BF000D5D9DD4C8421AE408CC1EA3AEA8B97B05E +:100C0000D5BAEA9451FF8648FCE0FC43842084482E +:100C1000B002EA3D84208448B004EA3DEA9484228C +:100C2000DD4BAE40844284018425F80C44638D4240 +:100C3000EA6EEA74A6305A088F0AEA5384018425C2 +:100C40008442B0C2B104F829D5F6B042844484028B +:100C5000F859DD463C1DFC740220800F5A00020545 +:100C60008403FE849691B0428062B00449FFFAAAE0 +:100C7000F08149FFFED58402F815EA94F001FCC327 +:100C8000FC0180C0EA948421DD4BAE4084018425C0 +:100C90008040B0C1504F800649FFFF4C5A680105A3 +:100CA000800649FFFA5DEA94EB8449FFF8FCFC8179 +:100CB000FC418400EA2349FFF9D5DD4BA600C014AE +:100CC0005A00040448000061EA583C0BF62F441215 +:100CD000C71E84004422C45A3C33F77E444000506F +:100CE00049FFFEAAD5063E07EF2EEA583C0BF62F29 +:100CF000EB77842049FFFB18DD4BA6004412C6ECBD +:100D0000844149FFC0BAEB55A60096424E14000F2D +:100D10005A0888098400EAA03C03F8DF8C01EADF66 +:100D2000D5058401EAA08400EADFEB77EA75DD5D92 +:100D300049FFF831EBB95A000103F8622E07EEFEC5 +:100D40005A000103F85D8400EB1A44000043DD41C2 +:100D500049FFFF5DEA23EB55A60096424E140004BE +:100D6000960FEA23DD52EB8FEA4A8403EAA184C19D +:100D700084003C0BF635EAAD3E67EF2EEB4BEAEA1A +:100D80003E67EF2FF83D440000963C0BF62FEB0535 +:100D90005A0801093C3DFBC84400003140300C06B4 +:100DA000D5078460C8052E37EBC540300C064413C8 +:100DB0008D41EB77A648EAAE49FFFE5544138D42BC +:100DC000200080004E04001A8400EAA0A60896368F +:100DD000C00F8400EAC3A60854200020C20E66207B +:100DE0000020960FAE88EA238401EAA0D506EB70B6 +:100DF000E61EE803FA0EEAC3EBB95A000104480004 +:100E0000006E2E07EEFE5A08011D2E77EBBA5A78B7 +:100E1000011944938D4100548000EB50D05F84C091 +:100E20003E67EF2FEA948403DD52EB8F8069EAA1DD +:100E30003E67EBCE3E67EEF53E77EF2FEB4BD54EA0 +:100E4000EB70E61EE94B44000042DD418400EAC33A +:100E5000EA94DD42C008EA305A0807FFDD4BA600DD +:100E600049FFBA52840149FFFF0D44238D42A65029 +:100E70008062970A4E4400089666C106440FFFC080 +:100E8000AE10D521C82084E0AFD82E67EF02EA4A21 +:100E9000CE0E8006DD528046EAA13E67EBCE3C6F67 +:100EA000FBC83E77EEF5EB4BEAEAD5188403DD523A +:100EB000A698EAA13C0DFBC8EB2CE91084013E0783 +:100EC000EBDED50CEA4A8403DD52A698EAA1840041 +:100ED000EAADEBD58401EB1AEB4BEBE20000002E00 +:100EE000C00B3C13F77E4402FE54AC403C13F62585 +:100EF0004402FE56AC40FCC1FC00DD465A08022C00 +:100F00003C1DFB7EEAA4E220E803EAA5C00C8400B5 +:100F10003C0BF61E49FFEE96C81E49FFF53F49FF00 +:100F2000FEC9D519EA6D5A0801064402C42C49FFCE +:100F3000B8BF840184408080842A806280A2DD570B +:100F4000DD5A5A08020549FFC93ED5DB2E07EB8D55 +:100F50005A0801D8FC80FC20DD4BA6802E17EBA49C +:100F60002E07EBC82E37EB932E5011EFCA058040A9 +:100F700082018003D5048205804380A14271402410 +:100F80003D1C01D9422014248480452333103C03A6 +:100F90009422E280E81595A140034800A4C0A44033 +:100FA00088D1A430FE6C4231C0249A08FE3C8C816A +:100FB000400008169A189601AC309721D5E93C0CF0 +:100FC00001D93C1C01D7EA4DFCA044531C2044200D +:100FD00003E844331DB05A08050BA528021291B846 +:100FE000FE64401088379649AC68D50B5A08010A50 +:100FF000A468024291B8FE54401090379649AC68FC +:101000008CA2DBEADD9EFC6080E0DD4B80C181824A +:1010100081638144009000005A780114C1038EC19D +:1010200097B0EBAEA740D607EB055A08010580063E +:1010300049FFDA488403DD528046EA4AEAA1D50D29 +:101040005A78020C5A980405840149FFFFC08400B5 +:10105000DD528046EA4AEAA1840149FFE74DDD54AA +:10106000A60896005A0801FEDD5BAE088020EBB3AF +:10107000DD59A640C9FFA6405A1801FFDD42C0163F +:10108000EA305A0807FFEAB0EAB6EA4DDD4BA6009F +:10109000C8045A980409D5055A0804064E9300045A +:1010A00049FFFF5BDD4C8421AE405A780109840082 +:1010B0001076000010758000EAD5D5095A7802082C +:1010C000840010060000EAE08401EAD5FCE0FC2080 +:1010D0002E67EBDD3C73F614A60149FFDBB28EC12F +:1010E000E2E05C630001E904EBF8C00284C1800621 +:1010F000FCA0FC00DD40A6415A1004058424AE414A +:10110000EA34840A441000B5DD47EBF8C803F80A56 +:10111000E80349FFDE3B840A441000B6DD47DD42A8 +:10112000C024DD558E04E60283FFE8172E07E96C24 +:101130005A08010A4410003F84088041806149FF39 +:10114000E3DFD5155A0802144400003F842680408E +:10115000806049FFE3D5D50B4420003F84088426F6 +:10116000806249FFE3CDD50349FFE3DC441000B7BB +:10117000840ADD478405DD4AEA6949FF89A58406BA +:10118000DD4A840A441000B8DD47DD4C8421AE40BE +:101190008420840280418461808180A1DD57FC80AD +:1011A000FC418120EA3AEA8B84063C7DFB22EA641A +:1011B00084C1DD40EB44EA34DD4BA600842649FFC0 +:1011C000F0368400EA9BDD5997F83C7FFB223E67AE +:1011D000EBFBAF80DD4CAF802E67EB9F97B05A687A +:1011E00001108026DD40DD56800949FFDB0AF081D1 +:1011F00084408402F1018066808280A2DD57FCC1B8 +:10120000FC2080C0DD45DD43AE404472FEF22E0777 +:10121000EEA2C8198404441000F3DD47EB198401E1 +:10122000EBFD5A080103F822A6B89690C205DD40EE +:1012300049FF971ED5ED840180208062808080A2C6 +:10124000DD57D5E68401EA63840ADD4A2E07EEA263 +:10125000DD4A2E27EEA25A28030C8401EA3349FF07 +:10126000DB6D8400EA638400EAC74800006D5A28F9 +:101270000409DD408421DD56EAFF8400EAC7D56316 +:101280005A28060D800649FFFF8D84013E07EE9C1B +:101290008400EA638400EAC7D5565A280A13A631A7 +:1012A00084C15A080A0784003E67EF2CEAC7D54B71 +:1012B000EAE1DD4C3E67E938AF808400EAC7D543F8 +:1012C0005A28092DA63184E05A080A0984023E777B +:1012D000EF2C3E77EEA2AE30D5365A080B14AEB1E5 +:1012E000DD403E77EEA2EA34DD408421DD56840005 +:1012F000EA2A3E77EF2C49FFBDB084013E07EEDDC0 +:10130000D5228405DD4AEA6949FF88DE8406DD4A84 +:101310003E77EEA284028420D5115A280B15842032 +:101320003C1FFBC7AEB13C2DFB378401EAC83C1B18 +:10133000F6143E17EEA2AE108402804184618081D3 +:1013400080A1DD57FCA0FC6180C0A601B65FF381DF +:101350005A080408A6305A080105840049FFDA3B00 +:101360002E07EBF65A08010C4402C3E6B43FF20123 +:101370003C3DFB313C4DFB2F49FF9ACEEA3AEB470F +:10138000DD42C805EA21EA37EA31D566852044A264 +:10139000FE5044C2C54444DD01B044B2FE56DD5E99 +:1013A0005A000121A6315A08041EEAAB4472FE50CD +:1013B000EBA15A0010188401EB4EA6388540EAECE8 +:1013C00080278047846610A380008402DD44840265 +:1013D0004412C6D880418060DD44EA533EA7ED54F4 +:1013E000D52C3B0540003B0640204402FE54A6405D +:1013F0003E17ED58A6013E07ED59EAAC840244229F +:10140000C5448466DD444452FE504412C544800500 +:1014100038203404380080004C01000D50748001E5 +:10142000E72597F8E80644000089DD418127D5B813 +:1014300081278CA14C55FFEDEA21FA12AE088041BC +:1014400084028461DD442E07ED545A08130F4400D2 +:101450000085DD41D50AA6085A002204AED0D5FC8D +:10146000EA7EA6005A0013F5DD524422C39CB47FE5 +:10147000F401EBE749FF9C769600EAE749FF9633D3 +:10148000DD555A00010984E13C7FFB5ADD42C80367 +:101490003C7FFB70A6315A080812A6305A08024F4A +:1014A000EA3F5A00063E5A000906EA3F5A08113E32 +:1014B000D514DD465A0802FBD533541000FD5A18E6 +:1014C0000910A6705A18020D8401EA70EA3F9E4680 +:1014D000E622E9265A08112ADD42C022D5265A08FA +:1014E0000A07A6308E02E602E829D51A5A08030C2C +:1014F000A7B05A680124800649FFE4FE8006EA701E +:101500008408D51D5A08040FA7B05A680118800630 +:1015100049FFE4F28006EA70EB763E07EB9284081E +:10152000D50E5A0006E7D50A844084618402FA2564 +:10153000808380A2DD578408D5028401FCE1FC0091 +:1015400084003C0FFB79DD45DD43AE403C2DFB794B +:10155000CA08840180208062808080A2DD57D5F790 +:10156000FC80FC00DD548400AE08DD5BAE08840125 +:10157000EA268409EA2C2E07EE99EA6CDD45DD4364 +:10158000AE40EA80A6085A0001FFDD42C00AEA2107 +:10159000A6085A0832FF8407EA3E8401DD4AD50CCA +:1015A00049FF9265EA21EA8AAE088041840284619B +:1015B000DD448402DD4AFC80FC6180C081618406D8 +:1015C000A67180E28520DD47854944C3F04AEB9946 +:1015D000A6313E97EEDD8E03E6094EF202EA44F1B3 +:1015E00013E8EBACEA41DD0F12005201C6053802E8 +:1015F000C6054203A0037A04E204DD422E0728AAAE +:10160000C809DD45DD43AE40840944100091DD4743 +:10161000D5295A08013F04938003F848E320E9F2F2 +:10162000D538DD59A600C824DD4CA6005A08012192 +:10163000DD5A5A08021BEA6D5A0801064402C42CFE +:1016400049FFB5362E07283F3C1DFB7E8C019401D7 +:10165000E220E80884408401842A8062808080A29D +:10166000DD57DD42C005D5DEDD5A5A0001E6DD4218 +:10167000C80CDD59A600C8092E07EB8F5A000106D9 +:101680002E07EBC65A0001D9840944100092DD47A9 +:101690002E0728AA5A000103DD5FDD42C01BEB556F +:1016A000A600C0038400EA2AA1FB49FFD8D3E207C1 +:1016B000E904EA8CC006D50949001AB9C8FBD5105F +:1016C000DD558E04E602E90C2E07EBDD5A00010918 +:1016D000DD5F2E17EEA25A100403DD5FEAC7DD4579 +:1016E000DD43AE40DD54A608C0FFDD42C808DD4B37 +:1016F000A6005A08030949FFF6F9D50549FF8B8072 +:10170000C0FED5F68404AE3184003E07EEA3DD4072 +:10171000EA3449FFDA47DD42C0088406441000D5A8 +:10172000DD478404EA39D5038401EA63840EDD4A87 +:1017300084023E07EBAFEAFFDD5F840B441000BA82 +:10174000DD47DD42C812840B441000BBDD47800634 +:10175000EB0CF9478405DD4A8404441000F1DD47B1 +:10176000EB198006EB8ADD5F840B441000BCDD477B +:10177000DD5EC8388401DD4ADD559E44E624E90E6D +:101780005A000C0DDD5E5A00040A3C03F7745A0837 +:1017900001048006EBEE8400EB4EEB762E57EB92C5 +:1017A000D805EA6BEBB7EB90F904EA3AEA8BDD5522 +:1017B0008E04E602E809EAE8EA4CEA5C8400EA49B9 +:1017C0008400EA9BEAF7DD5E5A000413441000D25D +:1017D0008406DD478404EA39DD408421DD56EAFFD2 +:1017E000D5075A0804068401EA458400EB4E8400BC +:1017F000EAC8EB0C8006F8F58401EA33EAB15A082E +:101800000103F804DD5E5A080404480001AADD5A09 +:101810005A000203F804EBF84E0301A3480001A8A4 +:101820002ED7EBFB5AD8011349FFD8DA8402EAC855 +:10183000DD4CEB9C84053E97EC03DD4ADD424E0215 +:10184000FEC9EA305A0807FFDD5F5AD00203DD5FA8 +:101850008400EA90DD42C028EAA48C023C1DFB7E95 +:101860008C22E220E8053C1DFB605A1801F9EA6B66 +:10187000EBB7EB90DD404412E2F449FFDB0DEAB137 +:10188000C805DD40A601EAD1F9768406DD4ADD43CC +:10189000DD45AE4080C049FF8AA6C0FEEA3BAE30BF +:1018A000DD5AC0FFD52249FFBDE1EACE5A08030543 +:1018B0003CDFFB22D5038401EA90DD45DD43AE40E9 +:1018C0004493F7F1EAA580605A0801FE0074800095 +:1018D00097FCCFF94412C47880418402DD4480062D +:1018E000EB8A3E77EE9CDD5F2E67EBDD84003E07E2 +:1018F000EE9C5A680108DD408420DD563E67EBFB14 +:10190000DD5F000580004E03012EEAB14E03012B7E +:10191000DD5A5A00010448000126441000D4840610 +:10192000DD478404EA39EAFFDD5FEA3F5A08061022 +:101930008400EA45EAC8EBB7EA6BEB90DD46C00CE1 +:10194000EA7D0200001049FF90DBD5065A0811100D +:10195000DD42C0EFD50C8403DD41EAE1DD5B8401AB +:10196000EA33EA77AE08840FDD4ADD5FEA3F5A00CA +:101970000903DD5FDD465A000203DD5FDD408420A0 +:10198000DD568403AE31DD5F8401DD4ADD42C809E6 +:101990008006EB0CF8268405DD4A8006EB8ADD5FC5 +:1019A000DD5EC8178402DD4A49FFBA448006EBEECB +:1019B00049FFD992DD4C8421AE40DD5E5A00040E11 +:1019C0008409EA398403DD4ADD42C007F835D505CC +:1019D0005A0804048401EA458404DD4A8006EB0CBD +:1019E00049FFDB07EAB185213E97EC035A00010568 +:1019F000DD5E5A08040A840AEA39EAE1DD5B840103 +:101A0000EA77AE08DD5FA631EAD1F8B53CA3F6145B +:101A1000A63149FFD716E340E912840BEA39840066 +:101A2000842BA83BAE71EA9BDD4C3E97EBFBEB9C15 +:101A3000DD424E0200BE49FFBA00DD5F8409EA398B +:101A40008405DD4AEA6949FF853F8406DD4ADD42B7 +:101A50008020C8F2840280418461808180A1DD57AA +:101A6000DD5FDD42C802EA77A6305A08021F108601 +:101A70000000DD54A608C0FFA631EAD1F08185A0A0 +:101A80004402C3E9F1014422C44449FFD8613CDB6C +:101A9000F61410A30001DD40EA34840010D3801C4A +:101AA000A83B3ED7EBFBF853EA3F5A08070C8409E2 +:101AB000AE31EAE1DD5B8401EA77AE08FA083C0F5B +:101AC000FB3E84001003801CDD5F2E07EBFB5A08F1 +:101AD0000119DD40EA3449FFB9BDDD408429AE413A +:101AE0008420DD56DD40842BAE4149FFFD3C84025D +:101AF000DD5BEAC88400AE08EA338403DD4AD558CA +:101B00005A0802578404DD4A3E97EBFBDD42C808C1 +:101B10008006EB8A2E07EEDD4E03FD5CD5490005FD +:101B20008000C803EAB1C0042E07E938C81284094E +:101B3000EA3910A30001DD40EA34DD408421DD569E +:101B400084001093801CA83B49FFB98748FFFD42E1 +:101B5000840AEA39EAE1DD4C8421AE40D5298402C9 +:101B6000DD4A8403EA3949FFD6E9D5228403DD4AF8 +:101B7000A631EAD149FFD5F3DD4049FFFAAAC00EEC +:101B80008404DD4A84013E07EE9C8406EA3980061F +:101B900049FFFB088405DD4AD50B441000D38406B9 +:101BA000DD478404EA39DD408421DD56EAFFFCE1AB +:101BB000FC40C002F93C44600065EA6EEA74DD4610 +:101BC000C00E8EC1C60C8421804180618480440097 +:101BD0004F00EAB8EAE2EA32EA53D5F28400EBD7E2 +:101BE000FCC044100055DD43AE40EA80A6085A0010 +:101BF00001FFDD9EFC4080E08122EBDF80C049FFD9 +:101C0000FFF29E79E62F4EF2019344F11A1838172D +:101C10008501EA784A003C001E00720020014C0257 +:101C2000920014031403140314036E02A202F602BA +:101C30001403140318038404FA21DD474400003020 +:101C4000DD41840EEA648405EA838400EA82EABC0A +:101C5000EA93DD465A080204AFF0D5FCDD46C00B1E +:101C6000842144005AF0804180618081EAB8EAE230 +:101C700049FFFFA080098421DD5684208402804131 +:101C80008461808180A1DD57F8EC8404FA22DD476D +:101C9000840EEA648406EA838400EA8280A6500304 +:101CA0000041843FEAF2D8FFD5E6FA258404DD47F7 +:101CB00044000031DD4184E04403F429AFC0F870F2 +:101CC00084013E77EB8AEA8310730050EB01EB5BF3 +:101CD0002E27EB9F84812E37EBBF4452C4DC49FF93 +:101CE000E4B3DD4BA600C806EA524412E980EA7A62 +:101CF000D5075A080306EA524412E308EA7A840038 +:101D00003E07EF2C2E17EF2F8400EA2A84013E07AE +:101D1000EBA05A100103EB888400EA70DD548402C2 +:101D2000AE08DD5BAE08EA848E08E6044EF20102DE +:101D3000800949FFB199F8958404FA23DD47EA8ABE +:101D4000DD41DD4C8442AE80EABA8E02E603E9064C +:101D5000EB5B540080FD5A0808078400EA82EAC55C +:101D6000DD41F87F102480002E07EF0DC8099E0B7F +:101D7000E604E90C5A100D0B5A180E0CD5035A182C +:101D80000E06EBDC840049FFB2038408EA64D50345 +:101D90008409EA6484E0107300503E77EBBB49FF8E +:101DA000EC13DD40EA3484043E77EC13EA93DD4A19 +:101DB000EABCDD465A080205EB19AFF0D5FB441327 +:101DC000F3D1A608EAA6AE08441FFFC34403F429D2 +:101DD000AE40DD46C008842144005AF08041806155 +:101DE0008081EAB884003E07EF2C2E17EF2F840085 +:101DF000EA2A84013E07EBA05A100103EB88840015 +:101E0000EA70840049FFE05A84208009DD56840589 +:101E1000DD4A44000033DD41EA3F5A0004045A0819 +:101E20000706440001F4EA32D504EA5849FFCAFE25 +:101E3000DD46C004840049FF8E63EBDC44000034BF +:101E4000DD41DD428020848F8402C10784408020F0 +:101E5000806280A2DD57F8058041806180A1DD5756 +:101E6000480000688404FA24DD478420DD40DD5604 +:101E7000840AEA648403EA838400EA82DD40EA3467 +:101E80008401EB6CD5568404FA2ADD47840EEA649B +:101E90008406EA8380A650030041843FEAF2D8FF1B +:101EA00080098421DD56842084008461EA82804197 +:101EB0008402808380A1DD57D53CFA2B8404DD4762 +:101EC000DD46DD525A08020DA6095A0003138001AF +:101ED0008420DD5649FFD5328401EA33D50AA609AC +:101EE0005A000A0880018420DD56EAE18401EA33C1 +:101EF00000030051001300524422C3B74432C38789 +:101F00004442C3CA49FFF8818400EA82D51284049E +:101F1000FA2CDD47000300515A0001055A0802055A +:101F200084003E07EBDD8400EA82D503841BEA824D +:101F3000FCC092003C0FFC75DD9EFC6004EF800D40 +:101F4000C80AB461A0499419944940108FF5EA5623 +:101F5000EA48D5469521981C9E628C82A40088236D +:101F60008864A5C8A5989603814597FB97B34E074B +:101F70000006EB22F812FD60D503858081AC4E7718 +:101F800000078007EB22F809FD40D5038500812872 +:101F90004E6700088006EB224900228AFD30D503F7 +:101FA00084C080E640050408EB22FD50FD13FD04CB +:101FB000EA59FD10FD05EA25FD50FD13FD04EA2454 +:101FC000FD16EA59FD16EA59FD10FD05490026DE09 +:101FD00049002842021F8018920140000420120785 +:101FE0000000FCE0FC6380E03C03EEDEEA9FEA8D4B +:101FF000A63C812180C28143C009A63D5A001F072B +:10200000A63EC004A63F5A08310A000300455A08FC +:10201000010644000096EA9FEA8D00038009C0088B +:102020005A001F0700038008C0035A08310DEBC88F +:10203000C006B4065A080508EBCBC80544000834AE +:10204000EA9FEA8DA57CCD0BEBC8C006B4065A0802 +:102050000524EBCBC82144000A8CD51C44001F008A +:10206000D80BEBC8C006B4065A080517EBCBC8144A +:1020700044000960D50F5A50310544001F31D80C77 +:10208000EBC8C006B4065A080508EBCBC8054400E7 +:102090000640EA9FEA8D3C0C019F4E0600BCC80832 +:1020A0003C0C019E4410C34FE2204EF300B43C0CA4 +:1020B00001A14E0600B0C8083C0C01A04410C34F5B +:1020C000E2204EF300A8A4384E0200A5A4394E0227 +:1020D00000A22E07EF064E03009E021F800AEB3B74 +:1020E000E2204EF20098021F800BEA73E2204EF2CB +:1020F000009249FFB6C04E03008E842110150000E7 +:10210000EBCC3C40033AC907C40550027FE1EB49E0 +:10211000D50280044411890838509101441188C8BF +:1021200038109101B63F9C74F181EB07F182502386 +:102130008028501380103C3C019AF822EA3C3C4035 +:10214000033BC807C40850127FCF40000406D504E3 +:102150008400D502800444118864385091014411F0 +:10216000880038109101B63F9C76F18144100066DA +:10217000F182502380303C3C019B5013801849FF72 +:10218000FEDE0434800B0424800A4E360006CB3E6B +:102190005CF105DDE93B04A4800D04B4800C4EA67F +:1021A00000074EA300345CF585DDE9303C0C0327C5 +:1021B0008E02E605E82B80E9A03DA13C9441401049 +:1021C00093F59421EA48A07FA0BE97C39449127367 +:1021D000000C941140108BF5806A804BEA4822F382 +:1021E000000296438AEF42F3800384015EF780F198 +:1021F0001003007A1213000D22030003E8078A205F +:1022000042F080035EF780F1E90784001003007A52 +:10221000D5038400EAD5FCE3FC203D0DFC7580C1AC +:102220009B31E282E81E0873000104500008012877 +:10223000003239129E02A146A10738529E0238424E +:102240001E02425914248C684052C4B71251FFFC3C +:1022500000580033FF2C404244971241FFFDD5E166 +:10226000FCA0FC6081A1EBEB81208400818280C313 +:10227000AE185A18025084E044E2C9C8E2EDE86B97 +:102280000404800138501D01DF4350548018A02AF7 +:102290003C2DFC7538101E02B405003100323800A8 +:1022A0001E023C44086EFE1C0021003340A005576E +:1022B000A029908138001E0240451001FE1442F210 +:1022C00000033C44086F40B0057790814045900181 +:1022D00042420003888F5EF20032E917A6303C1DAF +:1022E000FC7538A60309A6304006006012B0000154 +:1022F000A63038770008A6308C019600AE3000106A +:102300008019E201E905D52749001494C0E88CE161 +:10231000D5B63C1DFC7584004422C9C8E20DE81105 +:102320000434800138518101D814A6F038010C081A +:10233000A7308C819720AF3000308019E283E90903 +:1023400080094412C9C8A6B0806C49FFFF67D50355 +:102350008C01D5E584004422C9C8A670E201E808D2 +:102360004016006038310000A8C98C01D5F7FCE0A8 +:10237000FC442F07281280C04260C073B5C44113CB +:102380000408409944000074800084C02F3728134B +:10239000A991B6C25A78FF05B6E3A9D9D51500743C +:1023A0008000A1A138631D01447000FF97AFA9D937 +:1023B000A1E4B6C340639820A7F14C03C005A7B0C1 +:1023C0004C13007E84C19FC1B6FF9DC1F781F0828E +:1023D000B1C4F0839E09A83AEABAF184A8798C21A5 +:1023E000A87B50007F018420EB49389F86024E95E0 +:1023F000001FE130E81C38A386024EA50019E15306 +:10240000E8164295407338A925005AA0FF1104929E +:102410000001C8063804A901962FB603D507380471 +:10242000A901B543962F4CA0400784018C215A186E +:1024300004DEFCC48480380F92024E05003DE0109B +:10244000E83A381392024E150037E033E834420080 +:10245000C073381901005A10FF2F3802811138A2B9 +:10246000C411E140E828381485018A0A966F5A6041 +:10247000010CC6045A600212D524B623B42284C1CA +:102480008801B602D518B5434C15000BA859A051C8 +:1024900084C28801A811D50FB5434C154006B4225B +:1024A0008801B602D50804A180014C15400DA05149 +:1024B0008801A8118C815A4804C0D5038401FCC44A +:1024C0008006FCC48403FCC4FC7280C02E07281361 +:1024D000B61F2E072842F0812E072843F082840081 +:1024E000F28482A483812F372812B0908080B15A61 +:1024F000E203E80A401A8060A049380284083841A3 +:1025000004088C01D5F68440B11082228501E24393 +:10251000E85E400A8860A00104C30001385601014A +:10252000D85438021400C85140D288084C20004BBF +:10253000401A806005208001A0754079080841009C +:10254000B4008827017800020098000000E800012C +:102550000180800300B0800000A08001010800031A +:10256000A64A8D818E21E181E92D510C0001501B7D +:10257000FFFFE181E9278F6150170001E02BE9227D +:102580008D418F21E149E91E0493000605030007F0 +:10259000EBC43914960A388214083918160A39100F +:1025A000960A385649014C59401138021400C80D9A +:1025B00038049C0A3882140838081C0A38009C0A1F +:1025C000D5048C01E203E9B38C41D5A28500459F77 +:1025D000FF80F004E3004EF20100A03138502101E9 +:1025E0004C5440F8B010380400005A000104480070 +:1025F00000F1A075B01A41040808380400008830C2 +:10260000F083A60A8460E602E9038E0196C0B45FF7 +:10261000A60B8E42E002E8038C01D503B41F8E01A5 +:10262000EBDAA6088580E602E9048E0154C000FFBB +:10263000A6095019FFFEE001E8038C01D5035009FB +:10264000FFFF54B000FF812342E1CC24E1494EF367 +:1026500000AD4007300081AC411E0020518F80400A +:10266000E16D4EF3009EB4064128F001881220006F +:1026700000012A7880014E0500888EFE97FB4E7778 +:102680000084800D8029B08CB0CE808680BC159FE0 +:10269000800B158F800A155F8009150F8008152F94 +:1026A0008007151F8006153F800549FFFE63053F23 +:1026B0008005051F8006052F8007050F8008055F30 +:1026C0008009058F800A059F800B5A080113F00EC0 +:1026D000A07138508101D858380C14005A0801559F +:1026E000F83DF00EF84442149C73B620F00ED54726 +:1026F0005A08024BA0B1F00E38510101D821380C14 +:1027000014005A08011EF00CF10D42301C248801FF +:10271000A0764001801640509440B4254216807344 +:10272000B625F10EA0F7EB75B46142348073B66143 +:10273000F10E04330008EB75B4618803B601F00FA5 +:1027400038510101D821380C14005A08011EF10D2E +:10275000F00CFFCC8801407380F6A0364050144046 +:10276000B40542069C73B60583FFF00FA077EA4ECE +:10277000B42083FF42149C73B620F00FEBC44E00CC +:10278000FFF888E1B6E0B40650D6800189C00009A0 +:102790000001400064041009000148FFFF638D211F +:1027A00040E74C0048FFFF54F003F10140EA80602D +:1027B000A036F80512070000A037F10238004002E9 +:1027C000FE0CEBC43810C002EA8F83FF1207000131 +:1027D0008D0148FFFF00FCF23C0FFC7ADD9E4402B5 +:1027E000B64C3C0FFC79DD9E3C0FFEACDD9E3C0FF1 +:1027F000FEABDD9E22200000EADE22000001EA8618 +:102800008A438A01FE0442010873DD9E8060804095 +:1028100084019A50E622E90A9850922142F08424D9 +:10282000E26FEB744020BC1BD5F5DD9E3C4DFEAB4A +:10283000842A0232000922200000FE5C9EC99061B9 +:10284000E062E8038A22968B0232000A221000011D +:10285000840AFE1C9EC19061E061E8038A019643F0 +:1028600042108801840A42008000DD9EFC608141A4 +:10287000EAB74201047380C2B42044C2D28844B291 +:10288000D27C95D24492D24CC10D0000001896041F +:10289000C0098403380608088400380588088400C5 +:1028A000D53838059800E604E8068C014412D27C3D +:1028B00038009808380618004412D288E603E90365 +:1028C0008400D5028C0138009808802A40049C00BE +:1028D00049FFFF92EB07FE0CEB3F44210000381646 +:1028E0001800E24040013C1B88274442D1EC846040 +:1028F00038020509804338059800E260E807985FD0 +:10290000381205018C618841D5F94021003CEB9FCC +:102910002215000038149A0988E922150001AC79C3 +:10292000FCE04402B5E43C0FFEAA500000343C0F2A +:10293000FEA9DD9EFC2051FFFD1880C0121F800300 +:1029400080E244118AECEBE5B002DD4844118BA42F +:10295000EBE5B030DD4844118C5CEBE5500F81783D +:10296000DD48500F823044118D14EBE5DD485A608C +:1029700002095A60030A5A68010BB0F084C0D509F5 +:10298000503F8178D505503F8230D502B0C284C116 +:10299000C722FA5D4450005A848084E2EA54381118 +:1029A00089119603E001E803C607D50BEA549603A4 +:1029B000E020E816C6069855EAB98082960BD50540 +:1029C0009862EAB980A2960BE005E80BE080E8097E +:1029D0008040D5E5EA54960338018111D502800282 +:1029E00051FF82E8FCA03C1C03275A180216001075 +:1029F000003C5A1801128420EB8E021000181210AD +:102A0000001A021000191210001B0210000EEBA693 +:102A10000210000FD5252210001AFA832220001878 +:102A2000EBF0FA642210001B40210C561220001A11 +:102A300022200019EBF02210001040210C56122029 +:102A4000001B2220000EEBF02210000F40210C563C +:102A5000122000102220001142111073EB1D1210E1 +:102A600000110010007AC9080210001AEBA602102B +:102A7000001B12100011DD9EFC010210001002204C +:102A8000001A0230001B9A8A0210001196938A23C2 +:102A900022300008964B5EF1803C90419021E80482 +:102AA0004E240008D50E5EF18C44E9034E26000A40 +:102AB00000400078E694E905848940211056D5024B +:102AC0008440122F8000222000095EF1003CE804BF +:102AD0004E140008D50E5EF113C4E9034E16000A29 +:102AE00000400078E694E905848940109036D502CC +:102AF0008420121F80013C1DFB485CF08708E8061B +:102B00008420121F8000121F800104100011EAFAB5 +:102B1000EAC2FF4E44110000D1203C1C044D3C672A +:102B2000FCF7E6263C57FCF6E906126F8000125FC0 +:102B30008001D513EAB58487964B42131073902316 +:102B4000964B121F8000021F8001964B4212907319 +:102B50009023964B121F8001EAB5964B4031842199 +:102B600096DB123F8002021F8001964B4021042118 +:102B70009693122F8003021F80021210000A021F78 +:102B800080031210000BEB113C0BFCF7EAF33C0B3B +:102B9000FCF6FC81FC61F581413280114122C00AC2 +:102BA00022708001EBC0EAB742018473009F803835 +:102BB00000100018854154F080014462D170441225 +:102BC000D140E8114502D1C438580D09EB20450227 +:102BD000D1AC4452D1A038780D0938708E0A38A291 +:102BE0008C08D55EB5805B08031F39030E024512C1 +:102BF000D1A088B039008E02EB20898738788C000C +:102C000039008E0A8CE197F8E6EF38788C08E948AD +:102C100040529CB640781CF6EB2038708E0A38A8DB +:102C20008C08D53E5B08013A4502D1C43D1DFEAC7F +:102C300038B80D114502D1AC38A80D11010880003B +:102C40005B08016A40F5940141051C0142F78003CD +:102C50004308000302888004898FE310E85C0318AE +:102C60008003E171E803E0B1E86A3C8DFEAB030448 +:102C700000098F818B91E18BE803E185E860E151E8 +:102C8000E803E0F1E85C0304000A8F818B91E18A9C +:102C9000E842E187E854D53FEB2038708E0A5A9815 +:102CA0000134B4005A0801313D0DFEAC02080005A4 +:102CB000E280E82A38030E0238708E0240504C0140 +:102CC00042F280034053C80142528003024800068A +:102CD00088AFE0A4E819025800074512D1705102EC +:102CE000FFFF42084C7340428409427848738804CD +:102CF00040001416888738088E0A40421496440211 +:102D0000D14038400E0A38030E02AC1038008E0253 +:102D1000AC11FCE139030E024512D1A088B0390094 +:102D20008E02898738788C008CE197F840529CB6E7 +:102D300038788C08EB2040781CF6D5B038B30E0AF2 +:102D400038A08E0AD5ADFC604460004C42019873F7 +:102D50003CADFEACB400EBC0EA4FEA8601050016BC +:102D60003C93F48A4512D1344522D12895DC446243 +:102D7000CE284532CE1C5A080110848038531E09D3 +:102D800040630CC038488C0838090C08AC7139090C +:102D90008C084800009138090C00E610E8048C010A +:102DA00038090C0838088C0044B2D134E60FE90326 +:102DB0008400D5028C0138058C0839188C00400835 +:102DC0009C003853020940030040AC410215000D3D +:102DD000E081E8100255000CE0A4E80B4008240153 +:102DE0008A85FE2441009401410042168989D5025A +:102DF000820938498C0084038024421800738404BB +:102E00008C22EABEE0804452CE1CE8058C81E08032 +:102E100040023C1B38028C0838190C0038498C00E1 +:102E2000846AFE5CE024E905E28380244011BC1B37 +:102E300084A0860A4100C216800580654C580013A4 +:102E400040489C00392312114043104022420001A7 +:102E5000887288044F1200048FA1D502862F8CA19E +:102E6000D5EE848AFEE4FE24404090B6C50C88F17D +:102E700038431E1140731C4042329073224380013C +:102E8000420290734E3500064050840A88A3D5054F +:102E900084A2405094B69B5DEB96976B4E0500065E +:102EA0004030840A8803D505846240308C768A03DA +:102EB000EACB964BAD50AC51FCE0FC204460004C9A +:102EC00042019873EBC0B400EA86EA4F4462CDEC4D +:102ED00095DA4502CDE05A08010A9837AC41EAE29A +:102EE00038530E0938080C08D54B5EF20029E80467 +:102EF0003C43F489D5135EF2012CE80F3C03F489BE +:102F000050427FD853100064424890244510010479 +:102F1000404244968880D502EB1B38080C0086237B +:102F20004202447384848C024000101638080C0856 +:102F30009937960039230E112312000153000064C3 +:102F40004240142442484873445000644E450005F2 +:102F500050420032D50350427FCEFE0C42084473EB +:102F60004042149638430E09EB074E050005500009 +:102F70000032D50350007FCEEA8F9877AC09380332 +:102F80000E0188C7AC10A431AC11FCA0FC61EB644D +:102F9000F081EB41048F800EE220F60FE8048404F8 +:102FA0003E07F3CC2E07F3CCC0048E013E07F3CCD2 +:102FB000EB17422300730001001880E2960EC857F9 +:102FC000B4025A000455400198808C0C40919880BE +:102FD00004107FFF1C107FFF4C907FFCA03F3C1C27 +:102FE00000C244A2EED43810810138251901E24113 +:102FF000E803381519093C1C00C838C0820214C403 +:103000008000000380435A0009335EF281F4E82F08 +:10301000B001816449FFFC0C5EF001F5E928840AE7 +:1030200042160024040480038446FE14E220E81FB4 +:103030002E07F3CCC81CEAF6B401EA295A08010BA2 +:1030400038051901E609E906EB6138059A0A840397 +:10305000D509B401EA29C80B440001F438059A0ADD +:10306000840638041808840910038043FCE14440B6 +:10307000004C42019073000000435A0006045A08B5 +:10308000090C8823A608C0048E01AE08DD9E3C030F +:10309000F48B38010E0ADD9EFC213C6DFB28F38188 +:1030A000B4E6F3084273EC0B860A5A7801038605EE +:1030B0008843A7D0E2F0E8268CE14460004CAFD012 +:1030C000420198733D23F48E84C010600043862A29 +:1030D000959A99CE43194424B7A7A6904C2840133B +:1030E000844110200043B001EB6788C53A030020FB +:1030F0003C03F48BE004E8048C94B687D5038C146D +:10310000B6072E07EE925A080105EA8A38008E0AA1 +:10311000FCA1FC0194DAF08188432241000022FFE7 +:103120008002E08FE80A3C0DFEAB02500009FE234E +:10313000848A4202907397032201000122FF8003D8 +:10314000E00FE80A3C2DFEABFE030251000A844A60 +:103150004202887396038823B44142001001E002C2 +:10316000E80EEB1EE90450007FCEB6013C23F48D3F +:10317000840AFE14B441E040E802B601FC81443008 +:10318000004C42010C7300300045CB0CA1073C3CC5 +:1031900000C8383192025EF19771E9048461103001 +:1031A0000045003000455A38010F3C33F48C402074 +:1031B0008840842AFE5CB462E061E80500000043B8 +:1031C000C802B622DD9EFC01F006EAB74220047375 +:1031D000001100435A1808300011004688A05A1800 +:1031E000031AEB7A9A61E435E915A6685CF080640D +:1031F000E8038C21AE68A668E635E91D40018040F1 +:10320000B4203C23F48BE041E916E42BE9148E2131 +:10321000D511A668C1048E21AE68FC8140018040B2 +:10322000B4208A814E4400083C23F48BE022E8035A +:103230008C21B620FC8122200000E022E819FC004D +:103240003C4DFEAB846A02520009FF8B42628C73D4 +:10325000E046E81022200001E022E80C0202000A09 +:10326000FE4B42100C73E04156078001FC80840144 +:10327000DD9E8401FC80FC004430004C42110C7344 +:1032800080C1441001F449FFFFD810030049FC80BD +:10329000FC01F08140108840EADE22FF8002E06FEE +:1032A000E80A3C0DFEABFEDB02200009840A423135 +:1032B000007396DB2200800122FF8003E00FE80A02 +:1032C0003C1DFEABFE030220800A842A42010473E7 +:1032D000960342000C01FC81FC21F081EB174212A5 +:1032E000007300008049C82122708004C7123C6D21 +:1032F000FEAB840A02530009FF448EA14C72800A7F +:1033000022508005C5060263000AFE348E01D80DE6 +:103310008402100080498406380190084430025825 +:103320003831120A10008043FCA19200FC21F608FB +:10333000F48195328844B4E2E0E1E830EAB7420330 +:103340000473842B10100048B0413A108400888523 +:103350003A120420EB7AE027E802B62284203811E2 +:10336000980800100043E62AE81944F13174EB395B +:10337000EA78DD0F0A0E262616261A262612842340 +:10338000D5088422D506842AD5048425D50284272D +:1033900010100043842110100046FCA14420004C72 +:1033A00042008873001000465A1803058428101044 +:1033B0000043DD9EFC6180E281218045802480C540 +:1033C000F08181638144F872EAB742730473001399 +:1033D00080485A180B213825990150F10096E20FC8 +:1033E000E804840010038044000380445A08011458 +:1033F00095B28926B001802949FFF9FE5CF000E111 +:10340000E80788CA3A0480003A030020FCE18400FF +:1034100010038044FCE1FC61F610F081EB174233AD +:10342000007381820021804681648145F70E048FFC +:10343000800F81235A280161000180435A08020C41 +:10344000F80E5A080106840010018044D51C102192 +:103450008044D5195A0003185A080511EA89B400A6 +:10346000EA2983FF5A080106840010018044D5032D +:103470001021804444D0012CD5085A00070585A0AE +:103480005A080A0444D001F484404402CBA440E327 +:10349000080838201909882E400438003A108400A2 +:1034A0003A100420F0018028804649FFFEF3E20D27 +:1034B000E808960140139820C8028401AC08D5039F +:1034C00038D3990940363800A458EB84A4D99A41DE +:1034D000EA54964B4422CB748A0338111A09960396 +:1034E000884EAC11FE0442008473EB3F4412CB447F +:1034F000EB368402EBBD00148048000480465A106D +:103500000B04480000B444E2CBA440D3080845C2F1 +:10351000CB445A08030A8400380E1A0A380399016A +:1035200038071909D53500048044C8104014340008 +:10353000B00149FFF961EB3F381719019601E2200C +:103540003C0BF9A8E8033807190940739820A43800 +:1035500038171901E220E9074412CBA43800990971 +:103560008403EBBD4025B400380E1A02B422E020DB +:10357000E80FA4F8381719019A59FE0CEB7A4000AD +:103580000C16E001B602E8048403EBBDB622381540 +:103590009A028405FE0CE20AE80A40063400021F83 +:1035A0008002AC40021F8003AC41FCE1E141E973C1 +:1035B00040B6340022D58000220F800222C580014F +:1035C0008A0D225F8003424000038AACC408423265 +:1035D0008003844AFE9C40911136D50281244260CA +:1035E0000424FE6C406328D640A0A9569B868AAA74 +:1035F0008405FF84FE2C84E4EBE340701CF6420358 +:103600009C2442031873EB3F5014FFFBE630E8188C +:10361000E40BE9238F29E723E822E40FE8204203A3 +:10362000000342138003E020E805FFC4407384F6E2 +:10363000D516E001E814FF8C406300D6D510E40AEB +:10364000E80384E080C79C35E60BE80284C09C3D1B +:10365000E60BE80584E0D50384E080C788CD88ECDC +:103660001265800012758001FCE15A080215EB7AA0 +:10367000E02AE9114422CB4438011A028E013801B4 +:103680001A0A40659840B4068E01E001B606E803C8 +:103690008403EBBDFCE1FC63F084220080003C0B62 +:1036A000FAF6220080013C0BFAF7F704EB1742719F +:1036B00080738162B42780C3EB914482CDC444926D +:1036C000CD6440A188085A18014084004422CDD01E +:1036D00038010C0838040C083C2DFD7B4432CD9495 +:1036E00038219A0A38249A0A3C23F48E1013804712 +:1036F000842AFE54EBD838111A0A4412CD28380017 +:103700009808100380431003804410038045100381 +:1037100080463C4C00C884004412CC68A0FF402086 +:10372000280038320E028C01EAC05A0804F98420BD +:103730004402EED4EBE980464402CDDCF10449FFBB +:10374000FD9C4800009844C2CC384412CDDC4006B1 +:10375000280049FFF851EB3FF085840C10038048A6 +:103760000003804380ECE602E81DF0043C3DFD7B55 +:10377000F4054452CD94B6DF4412CD344422CDD06A +:1037800049FFFC8CF00480464412CD3449FFFCF91B +:10379000EAEF4412CD344422CD94806649FFFCBB4D +:1037A000D5239E42E622E9085A0005079E47E622F5 +:1037B000E9035A080A1AF004802649FFFDF1EAEFEE +:1037C000F104EBD84432CDC4808649FFFD87B6DFD3 +:1037D000EAEF38149A02F2044432CD34F40544522C +:1037E000CD2849FFFCF24442CD34F505B71FEAEF7E +:1037F0004412CD94F2044432CC68F68149FFFBC8F0 +:10380000F0044412CDC4EBD8806649FFFC3244C2B8 +:10381000CBF0F004F105EBD84432CDC43C4DFD7B38 +:103820004452CD944482CBC0B6DF49FFFD81EAEF1C +:103830004412CC08F204806C808880A649FFFDBC4D +:10384000EAEF4412CC0814CF8000148F8001F68276 +:103850004422CC38F3044442CD34F50549FFFDDD64 +:1038600038039A0188EA38049A09A4794004A80028 +:10387000AC4138049A018949120580000205000113 +:10388000120580013C1DFD7B4402CC0838101A0A49 +:1038900038149A024402CC3838101A0AFCE3FC604F +:1038A0002240800022508001EAB7420184734472B2 +:1038B000CB10B4C0411188083C1DFEAC5A680112FF +:1038C000AD10AD51A60DF8DC5A000104480000E52A +:1038D0004472CAE0840038038E0988F1AC39FCE0F8 +:1038E00001208005013000185B28013E5409800248 +:1038F000C03A4402CAE038600E118811220000016B +:10390000CE05C03138438E11D52EC8064003C40001 +:1039100022500001D5284013C400EA86530300005A +:10392000FF8C38138E118144426004754248402454 +:103930004210002442B0402440909000424228248B +:103940004245947542401875FE0242004024FE6CC8 +:103950004210287342181875404224964010A4362D +:103960009723974B54098002C07C3C0DFEAB80240A +:1039700002600009E086E90839338E11E1E6E80FBC +:1039800051337FFFD50C4E44000839338E114F352B +:1039900000078660D50482648520D5028521030056 +:1039A000000A8005E0B0E90A4093C4002294800137 +:1039B000E130E81150987FFFD50E4E54000A409335 +:1039C000C40022A48001852042952401D5045A9880 +:1039D0000149812538A38E1140B3C40022B580016E +:1039E00040D2280140C2AC014ED2000C840240E912 +:1039F000A801400680164207307340003416880B39 +:103A00004EC2000C842240E4AC014016043642173A +:103A100034734010B036882A4C95803BE026E90587 +:103A20005263000188C1D5044E140033FF8A4D351E +:103A3000000DE010E905530800018980D5074E0408 +:103A4000000553000000D5028600E186E8054049E4 +:103A500080119743D506E0D0E804970B40548011BD +:103A60005B28010F38138E014402CAE09A613810B6 +:103A70000E094013C400A44988119A69AC41384327 +:103A80008E0988F1AD7983FFAD10AD51FCE04D3565 +:103A90003FE984C0D5CFFCE0FC6380C0EA725A00E5 +:103AA000010E3CBDFEAC3C0DFA5E02158005E20144 +:103AB000E8178C013C0FFA5ED5133C3DFEAB800647 +:103AC000842000218009E222E8EDB4405A2804064F +:103AD000A484AC82A485AC838C21EB09D5F384004B +:103AE00084E03E07EE925093000844C2E9E085AAC4 +:103AF00085CA81073CADFEAB00050009E2E04EF24D +:103B000000BD0404FFFE4E0200B25A08050448003E +:103B100000AE02048002EA9F02048003EA8DB045F1 +:103B20008047800649FFF6A4F083B0450005800178 +:103B3000B61F8041800680673C4DFA5E3C5DFE7E8C +:103B400049FFF82AEAF6B401920596175A000105D2 +:103B5000B401EA29C82F0206000450F07FDD5CF7AB +:103B600085FBE9190206000550F07E0B5CF786170D +:103B7000E812EAF95A080110042600073C1C00C2AA +:103B800038108901E62BE8072E17F9F4E62FE80331 +:103B90003E07EE922E07EE925A0801092E07F9F41D +:103BA0005CF00064E8078C01D503EB41C8033E07D5 +:103BB000F9F4020F800A42003424EA9F020F800BBE +:103BC00042003424EA8D00058003C008B045800619 +:103BD00080418067F40349FFF8B800058004C008FD +:103BE000B045800680418067F40349FFF96800050D +:103BF0008002C007B04580068041806749FFFD4DC7 +:103C0000220F800AB0458C0540003816EA9F220F2B +:103C1000800B80418C0540003816EA8D8067800655 +:103C200049FFFE3F220F800A4E040004128F800AD3 +:103C300002050009221F800AE020E9038E01EA9FA5 +:103C4000220F800B4E040004128F800B0205000A25 +:103C5000221F800BE020E9038E01EA8D020F800A0B +:103C6000EB10020F800B120480018CE15094804C09 +:103C700050C6004C48FFFF40EA725A080113800604 +:103C80008420D50BB4408E44E642E805A482AC847F +:103C9000A483AC858C21EB0900250009E222E9F31D +:103CA000004500093C37FCFC3C27FCFD3C1DFA5E4E +:103CB0008400D50CB4A65A580507223300042223E9 +:103CC000000584208C015063004CE204E9F43C3B85 +:103CD000FCFC3C2BFCFD3C1FFA5EFCE3FC41F48148 +:103CE000411200114102400A0040005A2260800047 +:103CF0009724EA868641C4073C6BF96E3C1BF96D3C +:103D0000EB3DD517B4805A4803193C7DFCB43C4DBB +:103D1000FCB588272E77F2D888C48CE197F8E6EFB7 +:103D2000EB3DEB873E77F2D8E945EBE3EB3DEAB9B3 +:103D3000EB873F27F2D8D53E5A48013B3C7DFEAA8F +:103D40003D37F96EA7383D27F96D5A48016540495E +:103D5000980142F200030293800440490401424268 +:103D60000003888F40948408E324E855029380037D +:103D700040748408E1E7E803E0C7E8603CADFEABCF +:103D8000024500098E818A899521E093E803E08647 +:103D9000E855E1C7E803E027E8510275000A8EE123 +:103DA0008AE995F9E0F2E837E0E1E848D534EB3DFF +:103DB000EB875A58012AB4005A0801273C1DFEAA75 +:103DC000A40DE260E8213C0DFCB53C4DFCB4403054 +:103DD000440142F18003A54E40324001EB4C886F14 +:103DE0009569E065E811A4CF9F594202C47342422D +:103DF000C073401184098801882440000C16EB1D13 +:103E00003C0FFCB5EB873C0DFCB5AC103C0DFCB495 +:103E1000AC11FCC13C7DFCB43C4DFCB588272E7731 +:103E2000F2D888C48CE197F8EBE33E77F2D8407083 +:103E30009CF6EB3D3C7FFCB4D5BD3D3FFCB53D2F32 +:103E4000FCB4D5B8FC2004600011EAFAEAC2FF769F +:103E50004461000022708000224080013C3DFCB2A1 +:103E60003C1DFCB3D604B4005A08010A84003C7F10 +:103E7000FCB33C4FFCB23C0FFCB1D53A978B975B3F +:103E800041139801410214013C1DFEA94208800320 +:103E90004238000388600200800E3C3FFCB1E060C5 +:103EA000E8230010801E80E09F0942720C73FE0C14 +:103EB00080674213C4244040040A4F15000488243C +:103EC000D5028A244010803688263C1FFCB342115C +:103ED000C0244F0500048824D5028A24EABE880540 +:103EE0003C0FFCB2D5053C7FFCB33C4FFCB23C0D13 +:103EF000FCB3AC103C0DFCB2AC11FCA0FC20226069 +:103F00008000225080013C7DFEAAEBCC3D27F96069 +:103F10003D07F95E0243800EC10E3C3DFB48842AFA +:103F2000403184770413800996D9EB1D0433800A4D +:103F3000FE5CD51150137FEC96495CF08C58E80A72 +:103F40005012FFEC96495CF093D8E8040013801EF1 +:103F5000D502EA6FB4005A08010A84003C6FFCB035 +:103F60003C5FFCAF3C0FFCAED532411348014072C0 +:103F7000C001420880034233800388609521E064D9 +:103F80003C3FFCAEE8209E0980A442500C73FE64C6 +:103F900080654202C4244040840A4F15000488040E +:103FA000D5028A04EA8F88123C0FFCB042019C249F +:103FB0004E7500048804D5028A04EACB88303C1F81 +:103FC000FCAFD5053C6FFCB03C5FFCAF3C0DFCB0DA +:103FD000AC103C0DFCAFAC11FCA0FC203C6DFEAA6B +:103FE000EADE0073001023008001CF0284E1EBCCF5 +:103FF000C1113C1DFB48848A4010903704430009DE +:104000009649401204370443000AFF0C3C4FFCA7BA +:10401000D5060213000994493C1FFCA7B4205A1886 +:10402000011384003E07F28C3E07F28A0203000966 +:104030003C3BF94C94013D0BF94B3E17F29A3C0F77 +:10404000FCA7D5553D17F94B3D37F94C4048C00109 +:1040500040098C01FF24424000733C0DFCA745221F +:10406000CA7CE2802E57F29A8400E9028401380962 +:1040700014089E39D80884003E07F29A84013E074E +:10408000F28AD5048CA13E57F29A2E17F28AC90CF7 +:104090002E47F29A8001E204E83138590000CD023F +:1040A0008C218C01D5F984808004E207E807385917 +:1040B0000000CD028C818C01D5F95A180109E087E6 +:1040C000E8060203000A94013C0FFCA79A7CFECC90 +:1040D00042324C734210C0244212447340319C76E9 +:1040E0003C3BF94C40009C163C0BF94B3C03F94C13 +:1040F000AC103C03F94BAC11FCA09B7C8A8188A1DD +:10410000FEE44232CC73420240244202C473403186 +:104110009C763C3BF94C40001C16D5E7FC20EBC0DC +:1041200022408001EBCC3C3DFEAAC105006180220B +:10413000FA24D5165012FFCE96495CF08C1CE80785 +:1041400050127FCE96495CF0939CE90602118010D4 +:104150008C239648D5030011802000618022B40092 +:104160005A0801073C5BF9443C4BF943D52D3C37D9 +:10417000F9433C07F9448A648A05FEDC4230007347 +:104180009409FE042E77F285E2605A78010DE91E4B +:1041900084003E07F2853C5BF9443C4BF9433E0703 +:1041A000F284D514E8082E07F284E206E8048C01B4 +:1041B0003E07F2842E07F2843C5BF944E2063C4B56 +:1041C000F943E90484013E07F2853C03F944AC104D +:1041D0003C03F943AC11FCA0FC00B480EADEEA86A3 +:1041E0005A400503CC0AFA0E3C0FFCA0841F3C0B7E +:1041F000F93F3C0BF93ED5375A48011600000045FF +:10420000C8063C0DFCA0C80A8405D502FA0E3C0F76 +:10421000FCA03C3BF93F3C1BF93E3C37F93F3C17C7 +:10422000F93ED5213C4DFCA0C4048E813C4FFCA03E +:104230003C4DFCA0C418000000455A0801063C3B58 +:10424000F93F3C1BF93E3C57F93E3C47F93F9A2960 +:104250009BA3FE04420318735EF003E84012BC1BEC +:1042600040323C1BACD0AC51FC80FC403C9DFEA9D4 +:10427000224080000054801622300008227000097D +:10428000EA868621C506E6A98628E803411280133E +:10429000005480178601C506E6A98608E803410296 +:1042A0008013B5405AA0010A04000011EAFAEAC2DC +:1042B000FF4644010000D81784003C0FFC9E3C0FD1 +:1042C000FC9D84013D1FFC9C3D1FFC9B3C3BF92653 +:1042D0003C7BF9273C4BF9163C1BF9173C0FFC8A39 +:1042E000480000B05AA80304480000AA3C0DFC8A0C +:1042F00051287FFF8C01420040013C0FFC8A3C0D9D +:10430000FC9DE012E8038C01D50284003C0FFC9D6B +:104310003C0DFC9E3C5DFC9DC8064C59400584014B +:104320003C0FFC9E4462CA3C942A4133000012793F +:1043300080014532CA1C3849960988133C4DFC9CC3 +:1043400038331609AC413C4FFC9B4E5700099E691F +:1043500038030611406304409AC3D50638034A1156 +:10436000406348409AC322130001420180038A2718 +:10437000EB630264800D8801E2C08026E906021426 +:10438000800CE20140103C1A3C0DFC9EC8043D1F0D +:10439000FC9CD5105AA0040F0204800C4038440144 +:1043A0008A20FE5C9A3040008017400800013C0FD4 +:1043B000FC9C3C0DFC9C84238064423080738424EC +:1043C00080038C02EA8FE080E9043C0FFC9CD5045A +:1043D0008C813C4FFC9C3C0DFC9CE011E8043D1F93 +:1043E000FC9CD505E180E8033D0FFC9C3C0DFC8A5C +:1043F0003C1DFC9CE001E8033C0FFC9C84203C0D30 +:10440000FC9C80C180814C10001038399611888343 +:10441000403994402231800188C3C5038EA1D50262 +:1044200080B28C21D5F1846240008C168880880689 +:1044300040420496EACB9723964BD5038420808193 +:10444000AD10AC51FCC0FC6B80C0EAFA0400001156 +:10445000EAC2FF4644010000D804841F3C0FFA5D05 +:104460003C1DFEA93C0DFA5DA44DE201E8048C015F +:104470003C0FFA5DB4064E02014B5A080504480091 +:1044800001472E0001C4C00C2E0001C6C0092E0039 +:1044900001C55A001F062E0001C75A08310A000341 +:1044A0000045C8060003005A96044E020137021365 +:1044B00000180203000E449000648A019603EB7C0E +:1044C000021300190203000F85418A019603EBD9FC +:1044D000EB1196039001EB7CEAF396039001EBD984 +:1044E000EAB5960BEAB5023F8001964B022F800198 +:1044F000FE44421188738403964B8441F82E80E079 +:10450000420024244410005AEACB97F9FFFC964B52 +:1045100084418400F82252139FA410030078964B24 +:1045200084418403F81AEAB542B02800964BEB6345 +:104530004210A424804A4010AC368402964BF80DF9 +:10454000023F800180E096DBEB4C4231A4248402E0 +:104550004011AC36804A964B49FFF1EEEAB5964BD6 +:104560004E160005FE7A974BD50280A7021F8001E8 +:1045700012530012964B4E160004FE02960344415D +:104580008DCC8044B0C23B01480480233B00C8244A +:10459000120300130291000044218DDC1290800070 +:1045A0008262B0463B09C80480E13B03C82403395A +:1045B000800013338000B1CA3B02480480873B026D +:1045C000482412920000509F80383B0148048049E3 +:1045D0003B01482413310000513F804844218DECB9 +:1045E0003B01480480933B024824A490ACA00023E4 +:1045F00000785CF10028E9575CF10032E803EB1B1E +:10460000D5034440006D4302800342A000034028CC +:1046100028019693EB51969386213929C511E1C261 +:10462000E8058DA141188013D5F9864D4319440141 +:104630005128FFFFE15041290013E9038209D50306 +:1046400080E182033899C911381849118A4996D1F5 +:104650003829C51141312401382845113903C911C0 +:104660008A41FE9C969340214C5688413813C511CF +:1046700096938A30FECCFEA4965B4030CC76887050 +:1046800096DBFF1C4470006440211C5640421C967F +:1046900042128824FE24EAB940001C1612130012AC +:1046A00012030013EB1196035EF00051E903EA5880 +:1046B000EB7CEB1196035EF07FB0E804440FFFB093 +:1046C000EB7CEAF396035EF00051E903EA58EBD97C +:1046D000EAF396035EF07FB0E804440FFFB0EBD935 +:1046E00002030012B041EB0D020300138041EA55B2 +:1046F000800649FFFDBCB0418006804149FFFBA414 +:10470000EB8412030014EA5412030015B4065A088D +:10471000050584003C0FFA5DFCEBFC403D2DFEAA34 +:10472000EADE00690016EA86C605E6C9E80597B123 +:10473000D50484C1D50284C800490017C405E689A0 +:10474000E8059721D5048481D5028488B5E084A04A +:104750005B3801123C5FFC893C5FFC883C6FFC8746 +:104760003C6FFC863C3BF8FC3C1BF8FD3D3FFC7D70 +:10477000480000AC5B380304480000A63C0DFC7DFB +:1047800051027FFF8C01420010013C0FFC7D3C0D6B +:10479000FC88E010E8058C013C0FFC88D5033C5FE9 +:1047A000FC883C0DFC893C5DFC88C8064C584005E3 +:1047B00084013C0FFC894472C9E8400394403D1DCC +:1047C000FC8738339609AC413D1FFC864E57000CE0 +:1047D0005092FFFF3803A6114093A4409AC32204CD +:1047E0008001D5083803C2119AC34003C04022009B +:1047F00000019A41EB4CEB6388230239000D94D9F8 +:10480000E2618003E9060209000C9401E220EB74E6 +:104810003C1DFC89C9043C6FFC87D5105B30040F3C +:104820000219000C412084088A129A66FE0C8A72D2 +:1048300040000C179A203C0FFC873C0DFC8784231A +:10484000807142308073842480038C02EA8FE1A05F +:10485000E9043C0FFC87D5048DA13D1FFC873C0D6E +:10486000FC87E006E8043C6FFC87D505E080E803A0 +:104870003C4FFC873C0DFC7D3C1DFC87E001E803C0 +:104880003C0FFC8784203C0DFC8780C180814C104C +:1048900000103833961188834033944022318001D0 +:1048A00088C3C5038EA1D50280B08C21D5F1846266 +:1048B00040008C1698E0880640318476EACB96DB7F +:1048C000964BD50380258065ACD0AC51FCC0FC4034 +:1048D000B480EADE227080013C1DFEAA5A48011312 +:1048E000ACD0ADD1A60D3C3BF8F83C7BF8F95A00B2 +:1048F0000104480000CD84003C0BF8F63C0BF8F7AF +:10490000FCC0A78D0100005A5A6801355408000206 +:10491000C0313C47F8F63C07F8F7CC05C02B3C37D4 +:10492000F8F8D5283C17F8F9C80380E1D523FF62D1 +:10493000FF0C3C17F8F8824342400475423294243D +:10494000421000244330142441108C004231C8240A +:1049500042399C7542301075FE02FE2CFE7C4210DE +:104960004873421290754031C4764010C43696DBCD +:1049700097CB54080002C06E5EF18C80E9093C5769 +:10498000F8F85EF28C80E80F44500C7FD50C4E3462 +:1049900000083C57F8F84E55000784A0D50480A3C2 +:1049A0008400D50284015EF39400E9073C47F8F9DE +:1049B0005EF21400E962D50C4E7400083C07F8F969 +:1049C000848042401001D5045A08014580873D1774 +:1049D000F8F83D07F8F940F1C4018023800741232E +:1049E000C001E80B84024092C401400780164204D3 +:1049F000C87340003C1688104F22000C842240925D +:104A00004001401904364214BC734010C836883146 +:104A10004C48003A5EF08C80E9045100F381D505E2 +:104A20004E140032530080004C58800E5EF014008B +:104A3000E90451106C01D5054E0400235310000009 +:104A4000E1B0E80496EB97C3D505E191E80396CB76 +:104A500097E35A68010C3C03F8F89A183C0BF8F6F7 +:104A60003C03F8F99A383C0BF8F73C3BF8F83C7BF0 +:104A7000F8F9ACD0ADD1FCC0444013FFD5A94F022A +:104A8000FFEAD5E186004C58FFD3D5E4FCC0FC21F9 +:104A900080C0EAFA04000011EAC2FF4644010000A7 +:104AA000D80984003C0BFCF83C0BFCF9841F3C0F3C +:104AB000FA5C3C7DFEAA3C0DFA5CA47DE201E804B0 +:104AC0008C013C0FFA5CB406C06C5A00056B020303 +:104AD000000AB041EB0D0203000B8041EA5580064D +:104AE00049FFFB7CB041800680413C3DFA5C3C4D77 +:104AF000FE7CA77949FFF8F4A63AC006B0418006CB +:104B0000804149FFFA6CA63BC006B0418006804157 +:104B100049FFFE05A63CC006B0418006804149FF22 +:104B2000F9EFEB4D5A00010A2E07EBCA5A000106B5 +:104B30002E07EB8E5A080107B0418006804149FFDD +:104B4000FAEF0003005A960EC0070203000AEB0DAD +:104B50000203000BEA55B0418006804149FFFEB9CF +:104B6000220F80024E0400048400EB0D22FF80021D +:104B70005EF78C80E90444000C7FEB0D220F80036C +:104B80004E0400048400EA5522FF80035EF794007F +:104B9000E904440013FFEA55EB84AC36EA54AC3721 +:104BA000B4065A08050BA4363C0BFCF8A4373C0BA2 +:104BB000FCF984003C0FFA5CFCA13C0FFEE7DD9E93 +:104BC0003C0FFEE6DD9E4402D33884213C0FFEBB41 +:104BD00084003E07FAF03E07FAF13E07FAF23E077C +:104BE000FAF33E07FAF4EB953E07FAF63E07FAB9F8 +:104BF0003E07FAB83E07FABA3C1FFA5F3E07ED3FA0 +:104C00004412D2E88400845FEB038C015A084FFE03 +:104C1000DD9EFC00EBDFFC80FC0080C049FF99B00A +:104C2000C0048400AE34AE35FC802E07FAC0DD9E91 +:104C30002E07FAB4DD9E4432D2A8AE18AE59AE9A11 +:104C4000DD9E3C0FFA5FDD9E3C0DFA5FDD9E3C0D64 +:104C5000FB4F465FF00FEAC2FF4646001000D80641 +:104C600084003E07ED3F8401DD9E8400DD9E2E170B +:104C7000FAF22E57FAF3EB0A4C12C0102E27FAF074 +:104C80005A28010CA6059D49400280B697683E57F8 +:104C9000FAF23E57FAF3DD9EA6058CA1400280B6DB +:104CA00097683E57FAF3D90484013E07FAF0DD9E77 +:104CB0002E57FAF22E17FAF3D9042E07FAF0C00F86 +:104CC000EB0A8CA1A605400280B697683E57FAF21F +:104CD0004C12C00584003E07FAF08401DD9E2E5779 +:104CE000FAF22E07FAF3D8072E07FAF084208E0185 +:104CF000EB49DD9E8401DD9E2E57FAF22E07FAF372 +:104D0000D8072E17FAF0840040000406DD9E8401C7 +:104D1000DD9EFC0084A08C81E2A4E80738600804D2 +:104D200038608C0C8CA1D5F9FC80FC613CADFA5F3D +:104D300084BF81608121B4C1105F80075AA0010443 +:104D40004800009B84E03C3DFEE62F17FAB43D2C62 +:104D500004363D3DFEE7802A44C0004C81A781C750 +:104D6000850686029E89000180099690E240E8123D +:104D700043413024B40B41505000B4159E81E642AB +:104D8000E9035A08047604058003B4009E81E642D4 +:104D9000E808841F1003003E1003003F480000860F +:104DA0005A0004F9DD5A5A0802052E00114FC8F2C4 +:104DB0005B1801045B2005EF00098003222A8004B0 +:104DC000224A80050371800203618003C01702013B +:104DD0008009518BFFFF8E0140F041F642F1607374 +:104DE000518B7FFF402780560201800A8E0140F0E0 +:104DF00041F642F2607340478096E057E903502B3A +:104E0000FFFFE09642013400E903504B7FFF81E64B +:104E100042F3A073844240210464424238001027C8 +:104E200080004020100A102780014022100A10271D +:104E30008002971F40420084020A800A10478003C4 +:104E4000C006B44B885400010014D5028401100739 +:104E50008004020A800BC0039600D50284018CE115 +:104E60001007800597F81053003C1053003D8C212B +:104E7000964848FFFF792E77FAB8C7172E07FAB978 +:104E80005A001913E61EA670E80596574000806484 +:104E9000D503440000F0AE302E07FABAAE328401DA +:104EA000AFF13E07FAC084E02E07FAC05A00FF0DAA +:104EB000C00BCF0A841F3E07FAC03C0DFEAF8C0129 +:104EC0003C0FFEAFD5033E77FAC05AA801153C0D42 +:104ED000FEE600400009E2E4E80E84268406FE7C3B +:104EE0008A87B449FF0496488822EB538440806A3D +:104EF0008E81F944B409842080A0502000400832FB +:104F0000800188239648DAFCFE4A101000405AA01F +:104F10000104480000CC04058003B4209E89E642C9 +:104F2000E9055A100404480000B922300006221096 +:104F300000075EF18C80E805844042318800D5038B +:104F400044300C7F5EF09400E805844042108800F5 +:104F5000D503441013FF000000725A0001048401BD +:104F6000D503440000F0EAD3042580035A08F02E4C +:104F7000840010010072041580034420FF00040027 +:104F8000801404308015401008029228101300424B +:104F9000401060091013004446100FF01003004346 +:104FA000FE0E9210FE9EFE5E1003004592484001E8 +:104FB000E0099230102300461033004710030048E8 +:104FC000101300498489D55F4001A00A10030042F4 +:104FD0004000A00A103300431003004410130045A2 +:104FE00000010043C80702010025C809020100268C +:104FF000D5045A080105840012010025020100258C +:105000003C3DFEE740102009101300461003004706 +:10501000A618C00602010014FE029603D503220161 +:105020000014A659C10602110015FE4A964BD5037D +:1050300022110015A6DACB06100300481013004910 +:10504000D505101300481003004984001003004ADE +:10505000000100431003004B84001003004C0001CA +:1050600000415A0001085A0002085A080309EAE8F8 +:10507000D507FA10D50544000040D502FA00100308 +:10508000004D848DB449501200418822EB53844076 +:1050900084615242000DD518B429EB535010804161 +:1050A00084408461848DF86AD5125AA803112E07B2 +:1050B000FAB95A0819F3EAD3B429EB5350108042D5 +:1050C00084408461848CF85A8401D5028400B449F8 +:1050D0008420505100415031004E08428001882404 +:1050E0009648DBFCFE4A1011004E2E17FAB45A10F7 +:1050F000FF0AC108C807841F3E07FAB4CF0784011E +:10510000D5063E07FAB4CF02C0FB84003E07FAF68C +:10511000FCE1FC00844180624440004EF82FFC809A +:10512000A60092038C1596275C000014DD9EFC40BF +:1051300080E08400EB95A63880C1C8040003800895 +:10514000C0312E07FAF15A08010C2E17FAF43E1757 +:10515000FAF23E17FAF384203E17FAF0EB9549FF76 +:10516000FD88EB0A2E97FAF3A7043C1DFEBB844191 +:10517000A0394214907380628E8149FFFDCC2E07C6 +:10518000FAF65A0801063E07FAF13E97FAF42E079E +:10519000FAB55A00FF058C013E07FAB58401EB54BD +:1051A000D5033E07FAB52E17FAF5B4065A18012AA8 +:1051B000A605C814F835C80DEB0A2E37FAF4A684F4 +:1051C000B4263C0DFEBB42018873B421F839D508E2 +:1051D00049FF96A7F825C8FFD5F0F822C802F84580 +:1051E000B4268400EB953E07FAF18401AE0DB42697 +:1051F000AE0CB4C6B406F8345A08013DAE37D53A01 +:10520000A644C904F868C036D50BA6055A0801069D +:10521000F807C830F82AD52E49FFFD63C8FA49FFC0 +:1052200096B380E0C82749FFFD45EB0A2E97FAF2B6 +:10523000A684B4263C0DFEBBB4214204887349FF0A +:10524000FF6A2E17FAF15A1801112E57FAF44C542E +:10525000C00DB4063E77FAF1AE45B4E6B40749FF97 +:10526000FF615A080103AE3F49FF969EB4068421B0 +:10527000AE44FCC0FC20804080E14402D2C8A05172 +:10528000B6202E17FAC0EBD1A052A841A053A843D4 +:105290002E17FAB44462D2E8101000104412D2C49F +:1052A0003C6FFEB549FFFD434402D2B82E17FAC049 +:1052B000AE402E17FAB4EBD1B4273C1FFEB1441216 +:1052C000D2B4A98149FFFF3584204402D2A8AE4060 +:1052D000AE41AE4249FFFD12FCA03C0FFFA2DD9E95 +:1052E0003C0FFFA1DD9EFC6051FFFA28F385506F53 +:1052F00083388460F182F2863C5DFFA180268601BE +:105300008223F202F284E262E82A22400000222094 +:1053100000011240800A1240800CF4051220800B1C +:105320001220800DA081A1241420800B402208208F +:10533000A7D1C70BA72A8E814C720008A710C405FD +:10534000A6AB8E414C41400511008035D5031110AC +:1053500080358C61501080388C08D5D42E17FE8093 +:105360008400F18150EF80388040509F8068511F49 +:105370008098510F80C844700038EB2B42301C24B9 +:105380003827020A99733824820A3828820A382872 +:10539000020A88648C011022802A1021802A5A086F +:1053A0000CEFF0023C3DFFA2E20180E6856014FFB5 +:1053B000800386FF4781000086CA47E900004590C8 +:1053C0002710F002E3604EF200DF840138072E0A56 +:1053D000B03E41002C4085804402D3C840F604060C +:1053E0004EF200CDF2032243800CC2092220000EAF +:1053F0002250000F8A822223800DD5082220000C23 +:105400002250000D8A822223800D8A45FE9442227A +:1054100010732343800C2240000C2353800D412A3B +:1054200010012240000D04800009413A90014259C8 +:10543000CC2442594873B5405A88040700400028DC +:105440005A480103F8610440000CCC59A119E2A4A8 +:105450004EF3032DA51942451024E2A4E830A11A09 +:10546000E2A4E80BA10404A00003424990244249AD +:1054700028734E46031CD523A11BE2A4E820A104F7 +:1054800005100003424990244249447344D000640B +:10549000432234240111802741292A5743294824D3 +:1054A0004312C424432928244118B63740F965F72C +:1054B000E3AFE8054E4700044EA302F9004000297F +:1054C00001118000E3A4E805A11CE2A44EF302EF61 +:1054D000004180264E4202F5A11BFF24E2A44EF2B9 +:1054E00002F05A880403F810004380354E4302E965 +:1054F000004000354E4302E5885ED5375A4002032E +:10550000F8035A880404480002DC04F1800122A058 +:10551000000EE2AF04D000032240000F051000048B +:105520004EF302C500518028889142869424425847 +:105530009424408459164052D8B6404A9001894D6F +:1055400040AA2801FF24FF6C42452873425420736F +:10555000E0854EF202B64249C424424934734E47B4 +:1055600002B0464800008844B65050C600015108B9 +:1055700000305000003848FFFF338D615073803891 +:1055800048FFFF2184008441E201E8053824820AB3 +:105590008C01D5FBF002E60BE80AE62BE808804E0A +:1055A0008069B13EB148490003BAD508F002804E87 +:1055B0008069B13EB1484900036F3C1DFFA24658C7 +:1055C000FFFFF18344200038842050428FFF806128 +:1055D00044D2D3C8870CF487810251EF80C885413B +:1055E000519F8098868286E3E26044B2D3C84EF22F +:1055F00000F6B10840520C20A76980ED4272887312 +:105600000473800C5A78020F38720D004272E073F6 +:10561000B13E38721E024E75000638A4960A480044 +:1056200000DBB10838720D00EB2B42428873820612 +:10563000EB7E01220036F405511800305108002895 +:1056400004B8000105320003F40338F9AD0102B2D9 +:10565000001511288006E36FE80C4F23000B01288A +:105660000002848159290001112800021048800697 +:105670008206EB7EEB2B4242887350F8001822B76B +:1056800080012322000D22C8000C4125C8012332CD +:10569000000C436948241528000489CB1327800394 +:1056A000824741364C014322E07382B04369CC7398 +:1056B0008224B13E1D6A800239224A02F407153A5B +:1056C000800189EC13378002E29251580010E80DF6 +:1056D0008DB01548000C03088002130A80020308ED +:1056E0008003130A8003D50484801448000C8206CA +:1056F000EB2BEB7E4242887350B800105132001001 +:1057000022C9800223258002233980038BCC1528EF +:105710000001232580038BD30132002011380020A3 +:105720000532000915280002512800205B380317B4 +:1057300001280036011200285B2801038FA11118EF +:1057400000288206EB7E808A01180028510800207C +:10575000404BC41B14480001D50315490001820DBC +:1057600043028873010800345CF800C8E8048D81A6 +:10577000550800FF8246EB2B4323A0734242A073DF +:105780001109003401020029F40351190028A16510 +:10579000B5D211088001E2B2E805E78AE80C8D81F4 +:1057A000D508F403A166E3C5E8064F0200058F8122 +:1057B00011088001F40480A68E8142538873F4841A +:1057C000F401005280208E8138AF160A38AC9E0A50 +:1057D000F4818C218C6148FFFF0984A08069800BD3 +:1057E0008145B1E644C00038852185A585042E2772 +:1057F000FE80E2A23C2DFFA1E803F401CC0A846004 +:1058000086018006814382238110858348000093AE +:1058100000F10009E22FE8F40D0180015B08017935 +:10582000050000095B080308F20114A1FFFF8E4187 +:10583000F281D56E8F81E782E80D0500000C5B08D0 +:105840000206848010400028D50AF40301020001FA +:10585000D504010000288F811100002801000028D4 +:105860005B0801080110002A591880041110002A51 +:105870000021001987C040FF0806E82338F3FA0228 +:10588000E91D38F77A02E91A80484026C01A142028 +:10589000000981E080463B07E404422F30733B015E +:1058A00064243B07CC003B014C2000200020B13297 +:1058B00038920A0A3893FA0AD52551EF0001D5DC4F +:1058C00085E0D50350F780014CF100233843BE0238 +:1058D000CCFA80484026C01A1420000983C08046B4 +:1058E0003B0F64044227B0733B0164243B0F4C0020 +:1058F0003B014C2000200020B13238920A0A389334 +:10590000BE0AF20114A1FFFF8E41F2818C218CA10D +:105910005000003848FFFF6DF404C47001210009F5 +:10592000E232E86C38570E025A5001098C6150007F +:105930000038F402E264E9F1D561B12638520E0272 +:10594000CDF6B13238721602CF55F403B6E0A9C1D4 +:10595000A9C2A9C3A9C40270000C1270000E027083 +:10596000000D1270000F99E1F4050073801C0532E0 +:105970000003F40310500020107000280490000B66 +:1059800003220015CF0D3879A501E3C7E8041500FF +:105990000009D50F14C0000910800028D50A38F975 +:1059A000A50114C00009E3CFE9048CE110700028C0 +:1059B0003879A501B132E3C780E84078BC1A3902D2 +:1059C000160AB1261070003639020E0A0070002A3D +:1059D000F404587380018E811110003411100029D5 +:1059E0001070002A14A0000C38A70E0AF4848C2131 +:1059F000D59E8CA1E2B2E9A6D59A84004430004C31 +:105A0000808000110009E201E80842100C24F5062C +:105A10008C013842840AD5F684003E07FE8084203B +:105A2000509F809844A0004C44C0003800010019E9 +:105A3000E220E84AEB065A080136047300095A705E +:105A400005132E37FE80800B80A63B02E404420142 +:105A5000B0738C613B0064243B02CC003B004C20C3 +:105A60003E37FE8000030020F30642302873800397 +:105A7000B6E30033002A103000180233000AACC22B +:105A80000233000BACC30433000BA8C7B46650400C +:105A90000024B664A0F1A8E1A0F2A8E20433000C4F +:105AA000A8E38C2150630038D5C25A800303F8065E +:105AB000004000344E43FD5A885848FFFD57157882 +:105AC000000048FFFD5451FF85D8FCE084003E07EC +:105AD000FE80DD9E4402B5B03C0FFF9FDD9EFC675B +:105AE000006080092300000223100003C6103C5D03 +:105AF000FFA1A6EA8E614C61800B00308008C307CD +:105B0000A7AB8EC1FF9D5C630001D50284C1846098 +:105B10003E37FBCAEAFA04300011EAC2FF5E447164 +:105B200000004432D390DF0D84A53C5FFEF184A0D9 +:105B30003C5BFDDC3C5BFDDD3C5BFDDA3C5BFDDBA7 +:105B40003C5DFEF1C231C50485605A5805093C7DB3 +:105B5000FF9F85610073801C3E77FBC83C77FDDCAE +:105B600041281C013C77FDDD40789C01FFFC427917 +:105B700048735A500307C5055A500504480000876A +:105B80003C4DFF9F02520011A508E2A42E47FBC81E +:105B9000E807A449E2A1E804C4038E81972084A306 +:105BA000CC7684A1D5749E69E622E8053C1DFF9F52 +:105BB000A649D5095A5803043E27FBC82E17FBC82F +:105BC000C1048E213E17FBC82E47FBC85A48010668 +:105BD00084243E17FBCAD5038425C40284243C1FB9 +:105BE000FEF180C3803F3B036404EA7C3B034C002E +:105BF0003B00CC203C7DFEE83CADFEE93C9DFEEA4E +:105C00003C87FDDA80B93CC7FDDB3D07FDDC3D1775 +:105C1000FDDD2EB7FBCA2E67FBD58420B6205A5077 +:105C2000051EB6FFEBD4149F8002128F800A12CF9C +:105C3000800B130F800C131F800DF589104F8028E7 +:105C400010BF802A106F8035803F3B00E4043B0189 +:105C5000E4243B00CC003B01CC203E27FE78B6A0DC +:105C600010B0005A1280000412C000051470001712 +:105C700014A00018149000191420001A5A58010B8F +:105C80001280001C12C0001DD50584A281918110D4 +:105C9000D5C5FCE7FC6081608220840082418120C0 +:105CA000826084E1810044E000304F1200374F22CF +:105CB00000355A78013384C080E6855E4C65801ECD +:105CC00039011A025B0801184142184086004D0054 +:105CD000801338D1C2025AD8010D42C8382438CABC +:105CE000300240F62806E8058130826680ED814C5E +:105CF0008D81D5EE8CC1D5E3C7D9406280201133A8 +:105D00000000109300019D8138814E0A9630388141 +:105D1000A60A8FA18FC1D5CAFCE0FC6051FFFD30FF +:105D200080C0C06AC168E220E83080E145100030E0 +:105D3000865F82044303C47384003928020A8C01FD +:105D40004C037FFD8CE14C737FF6800181C180267E +:105D500081A581448183816249FFBE01B02449FF4E +:105D6000BE05800A49FFBE13801F49FFBE1C812665 +:105D7000840C84C049FFBE2849FFBE2B80A6862C18 +:105D8000443000308046D520E201E8E084E0451050 +:105D90000030865F82044303C47380063928020AF8 +:105DA0008C014C00FFFD8CE14C70FFF6D5CF400814 +:105DB0001000380F80005A00010F8D814D04FFF94B +:105DC0008CA14C57001A802A4242C42442128C7380 +:105DD0008600D5EE3800C2025A07FFF1400698202F +:105DE0009DF111000000AF4197B83825C20A38264E +:105DF000160AD5E480C1800651FF82D0FCE03C0F3A +:105E0000FFEADD9E3C0FFFE9DD9EFC602E27EE924F +:105E10003C6DFFEA5A280106844AA8B1FA4ED50320 +:105E2000FA44A8B1AEB0AEB15090FFFF85823D4DAF +:105E3000FFE93C4DFFD83C2DFFD740C4B196453219 +:105E4000D7848C0C4432D7544472D7344522D7407F +:105E50008620850144A2D6A485AC85C4001A000919 +:105E6000E3A14EF200D404507FFD4E5200C800B0B2 +:105E7000000C54158001C10B108980002210000015 +:105E8000AC5822100001AC59480000B95A50040423 +:105E90004800008200298000CA3B001900005A1007 +:105EA0000106A77880828022D51E0153800040150C +:105EB0004440808280A286014C5AC003860222F0B0 +:105EC00080008CA142483C7322F0800197684228F0 +:105ED0003C73501080305A5803F0404238964021AD +:105EE0003856D51882114300B4738C2138F542110D +:105EF00041054040230800019648888FE2A1885060 +:105F0000E8F28CA14042149640211456D5038041FA +:105F10008081421100034252000388A1A071E22552 +:105F2000E86D54158004A77001630002C10DFF6481 +:105F3000A4584052D8B688A1AD58A671A773FE5494 +:105F400040109436D51A401B30004100A61601536C +:105F500000034258140140FAB000A67140F7A5F6BC +:105F6000FF64030180004052D8B642178401FE54FA +:105F700088B0AD584010D436A55958B58002882550 +:105F8000AC5922118000AC4022118001AC4110B00C +:105F9000000CD5345A500533005980005A58010876 +:105FA00010190000AE7810198000D510A778E6A26D +:105FB000E8048CA1AF78D502AE7800190000C906BC +:105FC000A6785A18020410890000A67880B14250C1 +:105FD000B47322B000008025A5584055940138556F +:105FE000060923000001A55940150440405814013A +:105FF000AD4912B18000130180018DA18DE1EB0943 +:106000008C648CE18DC148FFFF2B3C4FFFD83C2FA7 +:10601000FFD7FCE04402B5D83C0FFFE8DD9EFC4012 +:10602000B4404E2200F90070005A96FCC30E842141 +:106030003E17FEB002100008020000093C1BFF568C +:106040003C0BFF57480000E85A200404480000AC0D +:106050002E27EF064E2300E02E37FEB03C2FFFAA7E +:106060003C2FFFA9CB412E27FEA12E57FEA0446254 +:10607000D6845A20010580438083D52180838043C4 +:10608000550200FF4D02C0048602D5028601391375 +:1060900012114238447341131040231880018C813F +:1060A000422844735A4803EE84844031907640215C +:1060B00010563C3FFFAA3C2FFFA9D51639031211F9 +:1060C0008870410310408C81230800019720E2A4CE +:1060D0008850E8F58CA140319476405114B63C3F8D +:1060E000FFAA3C5FFFA93C5DFFE83C4DFFAA3D2DA8 +:1060F000FFA9A0E942F2000342290003884F94D986 +:10610000E2624EF200893D33FF56A6E850F9FF10D7 +:106110005CF78AA0E90294D93D03FF57A6A950F87D +:106120007F105CF79220E9029491546380040092FE +:10613000800201128003C60FFF1C4219082440424E +:1061400024964010C436403990003C3BFF5640280E +:106150000400D51A8E2184C2406098D6405498001D +:10616000EB9688D140130436425194014211040148 +:10617000FF2C42190424403224764020C4568873F0 +:106180003C3BFF5688503C13FF563C2BFF571210E8 +:106190000008587380023C13FF571210000910705A +:1061A000005AD5395A2005382E17FEB05A18010961 +:1061B0003E37FEA13E37FEA03E37FEB0D5152E1766 +:1061C000FEA0E622E8058C213E17FEA0D5033E374F +:1061D000FEA02E17FEA1C9082E17FEA05A18020510 +:1061E00084213E17FEA1223000083C23FF562E17C3 +:1061F000FEA04442D6849A9A382206092220000939 +:106200003C03FF57401204409A10AC093C3BFF5638 +:106210003C2BFF57FCC0FC00001000431010004452 +:1062200000100045101000433C1C044746000FFFBF +:1062300050000F00FE0E5A090009841F3E07FE930E +:106240003E07FE923E07E980EA975A08015CEA3C65 +:106250005A0801313C04087250107ED496495CF013 +:106260008A28E8083C10087350F0FED45CF791A827 +:10627000E96E84403C1408735EF0012C3E27FE93C7 +:106280003C0BFF483C1BFF46E8043E27E980D55FF6 +:106290005EF00B548401E8055EF0812CE805840271 +:1062A0003E07E980D5545EF092D48403E8FA841F57 +:1062B000D5F82E07E980C0035A0801093C0408728A +:1062C0002E27FE934412D680D50B5A0002045A089A +:1062D000033F3C0408732E27FE934412D67C38F00B +:1062E00089118A0FEB3C96015CF00065E9302E07BE +:1062F000FE935A00FF2D3E07FE9284003E07FE9358 +:10630000D51A5A080225EA3C5A08010E84003E07B5 +:10631000FE933C0008723C0BFF483C0008733C0BAA +:10632000FF46D5152E07FE925A00FF1284203E1715 +:10633000FE93C00A3C03FF483C0808723C03FF463A +:106340003C080873D504841F3E07FE92FC803C0F76 +:10635000FFECDD9E3C0FFFEBDD9EFC00C0045A000D +:106360000108FC8049FFBE9F3C0FFFEDFC8049FF08 +:10637000BEA33C0FFFEEFC808020E6093C0DFFEE43 +:10638000E82344F1618CEB39EA78DD0F0A3C101602 +:106390001C22282E34003C0DFFEDDD9E500000F045 +:1063A000DD9E500001E0DD9E500002D0DD9E5000D9 +:1063B00003C0DD9E500005A0DD9E50000780DD9EDD +:1063C00050000960DD9E8400DD9E9200FC4080C28A +:1063D00080E13C2DFFEE3C1DFFED8123814449FF10 +:1063E000BE393C1DFFEBA60AA64B49FFBE53EAE8A7 +:1063F0004203000149FFBE6D84C03C1DFFEC00005C +:106400008010E2C0E81080063810980049FFBE6E88 +:106410003C0DFFEC984600108008800649FFBE8CBA +:106420008CC1D5EC8400F80BF80C8401F808F8094D +:106430005AA801058402F803F804840349FFBE4DFD +:1064400049FFBE1A49FFBE41EA83848184000014DB +:106450008000E201E82BA07938508101D025A07D91 +:106460009482956A98CA8825A6DAA78AE266E80225 +:10647000AECAA07D98CA8825A6DBA78BE2C3E80236 +:10648000AECBA07D383088008825A788E266E80278 +:10649000AEC8A0FD884388A3A651A6A9E241E802A0 +:1064A000AE693E47EEEC8C01D5D3FCC0FC62464C95 +:1064B00001208881446308FFE2C4804080A140300D +:1064C000C0094EF30082C8054603FF004C5001216D +:1064D000808280A1FD028440463BFF00EA24FD103B +:1064E000FD30EA25FD60FD10F8EE44218E48FD5098 +:1064F000EA56F8E944218E40F8F544218E50FD40DB +:10650000EA56FD06EA25F8D444218E60EA56FD409D +:10651000F8DA44218E58F8E644218E68F8DBFD064F +:10652000EA253A4F9400FD10FD02EA2444218E78BA +:10653000F8C744218E70F8D644218E80F8CBFD0632 +:10654000EA25F8D544218E88FD60EA56F8CEFD1084 +:10655000FD06EA24F8C9F8D0EA24F8C6F8A9F8C478 +:10656000F082F183844046341A00F8ADFD50F80BF8 +:10657000FD15EA59FD10FD50EA2544218E38EA56F2 +:10658000EA25FD40FD10FD03EA24FD60FD10FD033A +:10659000EA59FD14EA24FD40FD15FD03EA59FD10FA +:1065A00044018E383A000400EA253A0F8420FD1396 +:1065B000FD05EA243B0FC400FD10FD08EA25F8782C +:1065C000F89B480000A250F1FFF044607FDFE2CF6B +:1065D000E8289509404203F540420024CC05840197 +:1065E000490000A6F813C8054607FF004C50009468 +:1065F0004001BC098082C8065451FFF044007FF07E +:10660000D80780A1FD02490000A84800008680A1AB +:10661000FD02844046343300EA25465FCC0088A161 +:10662000469C01A089254064B40997B74014D0095D +:1066300044718E00404398804022868104320225B6 +:1066400040A39880802204220224EA5904250226CD +:1066500004350227EA590425002404350025EA25DB +:10666000FD304004D00AEB2244218E00F833EA25A5 +:106670000425002604350027EA24FD13FD40EA2402 +:10668000FD60FD13F820FD50FD16FD04EA59FD13D1 +:10669000EA243A4F940044218E08FD40EA56FD0258 +:1066A000EA25F80644218E10FD40EA56F81EFD103A +:1066B000FD04EA24FD40FD15F80644218E20EA562B +:1066C000F082F183FD03EA2544218E18F80B442162 +:1066D0008E30EA563A0F842083FF4E00FFF54421A6 +:1066E0008E28EA56EA24FD10FD05EA253B0FC4007A +:1066F000FD10FD08EA24F402F503FD10FD0283FFFE +:10670000EA25FD10FD04EA24FD16EA24D5058400DF +:106710008020D5028002FD10FD01FCE2FC40FD302E +:10672000812249000503B720FD03FCC0FC01C80518 +:1067300084004613FF00D5048400461BFF00B61FEB +:106740008440F181B41F8062F1014900031FFA52B5 +:1067500049FFFFE6FC81FC60FD10FD50EA59FD1089 +:1067600049000314FD30FD054900000AC006FD0381 +:10677000FA5149FFFFD5FCE0FD03FCE0C104465897 +:106780000000D904C8038402DD9E465FFF0046472F +:10679000FE009F2198CDE283E8064657FF0098CD82 +:1067A000E283E9038404DD9E464001009F21E281EB +:1067B000E8064658000098CDE283E9038403DD9E95 +:1067C0004657FF00D104465FFF00D902C003840092 +:1067D000DD9E8401DD9E92003A6F98BC40608C0380 +:1067E00090DF4E340006FEDAC203FE929ED94E14AC +:1067F0000006FE4AC003FE029E4984804900003A1A +:10680000C60840408004C405FE4AC003FE029E49FB +:106810003A6F9884DD9E9200414140099741921061 +:106820004040D03796D14010C008FE4742020C24A9 +:10683000E220E8099F21984AE222E905E220E803E4 +:106840009F21984A9A484010D01740004008FE2FD8 +:10685000FECCE203E80998029E49E202E905E20360 +:10686000E80398029E499A0340424008FE67DD9E75 +:106870003BFFFEBCFD80FD918384CB4DE3B2E81964 +:106880004209000782A0C00D4129000C525000208F +:106890004058140D4118800C411894044108000C14 +:1068A000FD08805249FFFFBA82C1820086E0D523ED +:1068B000C2284209000782A0C8048BB286E1D51421 +:1068C00052F000204129000C805240483C0D4058B5 +:1068D000800C4108000C400290044018BC0D49FF98 +:1068E000FF9D82E18220FD08805249FFFF9782C10F +:1068F000510000004FC2005386204108540DD54B73 +:1069000041194A17842084004FC2004CB79C151EC1 +:106910000001D547E3B3E9F74209800782A0C044EC +:10692000524000204059100D4029800CFEAF826279 +:106930004129000C4038100D4108000C4008800C23 +:106940004018900DFE1F49FFFF6982C1822042005E +:10695000C869E3A1E9054C18C00CE380E809516B54 +:106960007FFF8A3340304801E2038A2F800386E0AC +:106970004FC200154008000140188401E3808A2FAF +:10698000524A80204110900C4100540D41084404AB +:106990004110D40DB79C151E00018016501B8000BD +:1069A0003BFFFE84DD9EE3F1E903E392E90986C142 +:1069B000404848018BB3E3848BAF8204D50286C084 +:1069C00086E04FC3FFE9D5EA4231FC0A95093A6FE8 +:1069D000A8BC959947E80000E286E9054C434009C8 +:1069E000E202E806FD40FD01FD1495099599FECDF2 +:1069F0004031F8024072540940A3540940922808DB +:106A000040832808445007FF4C5380C440F20004E0 +:106A10004EF200BC40F308044EF200924063A8011D +:106A20005CF300404EF2008C4050540940949404B2 +:106A300040002C08405154094084140440212C0883 +:106A4000E6E2E9274094F8044EA20004408478046A +:106A50009F714062A81AC61D525300204E57000C69 +:106A60004041140C4054140C4084180D4021180D62 +:106A7000FEAFD50CFFAA505280204044140CFF17E3 +:106A80004043181A4024180D8500C4035821000201 +:106A9000C3594C7540064C9440044C010078E328DF +:106AA000E9054C94400AE202E8079FF940447C085B +:106AB00093019241FEA780809A02E2808B2F8B285F +:106AC000E6E2E9494E93000BFA904043900680A716 +:106AD000CC0D812084005073FFE042548007E2A770 +:106AE0005247800142529C01C50D9BFD9B6C526236 +:106AF00080204040180D4094940C4000140C4094A9 +:106B00009004500004005CF00400892FE32F88EF0C +:106B100040502C09976C80C09A05E2C08B2F40949E +:106B200084084054D008932C920BFE2F4053D00879 +:106B3000409494044010F8024010A4043A6FA884D2 +:106B4000DD9E9802E202892FE32F8928E90AE328D3 +:106B5000E908CFD8920B4044D408932BFE27D5EBFD +:106B6000525387FEC50E54F00001585000024002F7 +:106B7000BC1B4044FC0893219201FE279DF9D5C21D +:106B800084004697FF00D5D7C3DA84008420D5D788 +:106B9000409480044C9F40054C557FD2C3D0840064 +:106BA00044180000D5CC9200FC42950992954070A3 +:106BB000AC0840605409FFF740602C0847C800004B +:106BC000955992B54091AC08408154094094A00475 +:106BD00040812C08FECD40A1F002443007FFC4588C +:106BE0004C3200754073F0044E5200874C3280796D +:106BF0004094F00414AF80035002FC029920422319 +:106C0000A4694203246940910400E32140A1BC002F +:106C10004223A06999D0E2E0892FE32F894F89238D +:106C2000E323894F4203206999F9E2E1892FE32F99 +:106C300040153C00FFC75804800140049C1AE42022 +:106C4000E90781E09800E20F9849882F9F2104AF5F +:106C500080034E470071525207FF4E5700465000C6 +:106C600004005CF00400E804882FE22F888F4020A5 +:106C70002C0996949A02920B4020D408FE1794494E +:106C8000922C40525008FE6F4010A804FCC240F302 +:106C90009804E81940F37C0999FF88EF99B6CF056D +:106CA00080E684C050427FE042038007C09E9B2064 +:106CB000522000204023080D4063000C4073800CDC +:106CC000FFD7D593D315802AFCC2FFF74C7E401125 +:106CD000CD064024840840212004C20ADB054094EC +:106CE000A0044C9E400684004617FF00D5CE8400C9 +:106CF00044180000FCC24004A004C0E640F47C0933 +:106D00008929892F89084E930006812885005052D1 +:106D1000FFE0420480074E02FF6F9B685220002074 +:106D20004024080D4084000C4094800C409488045A +:106D300048FFFF6284C0523200015CF18020E90A02 +:106D400080C0800184205031FFE0C0045CF18020CD +:106D5000E81AC310522180204070880C4050080C63 +:106D600040000C0D40108C0DFE3FFFAFC6035800D5 +:106D70000001500004005CF00400882F4040FC0932 +:106D800048FFFF778400D5A0FC429509929540709A +:106D9000AC0840605409FFF740602C0847C8000069 +:106DA000955992B54091AC08408154094094A00493 +:106DB00040812C08FECD40A1F002443007FF4E4236 +:106DC00000C54C3200EF4073F0044E5200FB4C32D1 +:106DD00080F34094F0049B25504203FF92C140137E +:106DE000FC08FF8F92E14024C009403388F740142B +:106DF000801342508C244073C00840034009FFC7F1 +:106E000080079BFDE207E8059ED988E9E2E9E8FDF5 +:106E1000402388F7425088244073C0089631FFC74A +:106E200080079BFDE207E8059E9188E9E2E9E8FD1D +:106E30004031C00898DA4201A069FF8280079BF9BF +:106E4000E207C60580079FF9E903E207E80C9ED92F +:106E500088C84003200688E9E2E9C0049DF9E903F7 +:106E6000E6E1E8F64C74C007802880E684408400A0 +:106E7000D52B4014C009402384F74004801342F00E +:106E800008244073C00840534009FFEF80A78AEFF1 +:106E9000E2A7E8059E9188E9E2E9E8FD401384F75E +:106EA000425004244073C0089631FFC780079BFD01 +:106EB000E207E8059E4988E9E2E9E8FD402140084B +:106EC000989142012069FF8280079BF9E207C6057D +:106ED00080079FF9E903E207E80C9E9188C8400308 +:106EE000200688E9E2E9C0049DF9E903E6E1E8F655 +:106EF000E460E90781E29892E24F98DB886F9F2176 +:106F0000FFF75801000140011C1A80234E47007909 +:106F1000525207FF4E57004A500004005CF0040034 +:106F2000E804882FE22F888F40202C0996949A023B +:106F3000920B4020D408FE179449922C40525008DE +:106F4000FE6F4010A804FCC240F39804E81B40F315 +:106F50007C0999FF88EF99B6CF0580E684C050423E +:106F60007FE0420380074E02FF329B205220002028 +:106F70004023080D4063000C4073800CFFD748FF8E +:106F8000FF26D307CD0440F4A004E807802AFCC202 +:106F90004094A0044C9E3FFC840044180000FCC2B6 +:106FA000FFF74C7E7FFBD3F984004617FF004010AB +:106FB000A804FCC24094A0044C9E7FF08400D5E756 +:106FC00040F4A004E8F240F47C098929892F89085B +:106FD0004E930006812885005052FFE0420480074E +:106FE0004E02FEFB9B68522000204024080D408486 +:106FF000000C4094800C4094880448FFFEEE84C04E +:10700000523200015CF18020E90A80C080018420B6 +:107010005031FFE0C0045CF18020E81AC310522117 +:1070200080204070880C4050080C40000C0D40102F +:107030008C0DFE3FFFAFC603580000015000040056 +:107040005CF00400882F4040FC0948FFFF6F84007B +:10705000D59E92003A6F983C954992B54040AC0855 +:1070600040605409FF3740302C0846680000FF3765 +:107070005CF2843EE8215222843EFAD0E246E906E0 +:107080008064848050217FE0CBF9C20B80044031C2 +:10709000880D4042080D522100204000080CFEC718 +:1070A000E420E805FF22C303FEDA8E8180038024FA +:1070B0003A6F9804DD9EE420E90752F287FFE90861 +:1070C00095A1FF9FC605464800008460D5F046475D +:1070D000FFFF58420FFF847FD5EA92003A6F983C39 +:1070E000842080A180618040C210E440E8074658B7 +:1070F0000000FE92C103FE4A8E414430041E42410C +:1071000000079ADC4021100C4040AC094061540853 +:10711000FF37959192CCFF774061D008FF778004CC +:1071200080253A6F9804DD9E4402D7ACDD9E920024 +:107130008060E644E9285441800354508003C50B25 +:10714000525280049A959969084080011841800143 +:107150004C12FFFC40511409C50A956D996996A718 +:107160003B00DC043B01DC244C12FFFC40510809CD +:10717000C50A956A9969968F3A4090043A419024DD +:107180004C12FFFCC208994A084080011841800156 +:107190004C12FFFCDD9E92008060E644E9305451C1 +:1071A0008003C509525280049A959968181180018C +:1071B0004C32FFFE96484040A008FE674040C008A1 +:1071C000FE67405114094E520011956D996B96A7B8 +:1071D0008201822182418261828182A182C182E117 +:1071E0003B01DC244C32FFFE40510809C508956A7A +:1071F000996B968F3A1184244C32FFFEC206995A3D +:10720000181180014C32FFFEDD9E92003C0DFB23E5 +:1072100049003E44490011524403F04A4900125DBE +:107220004410005549006B9F490046624900B798D9 +:107230004900466249003EE344038D403C0DFB3764 +:107240004800015549003E44490020B649003EE34C +:10725000490011523C1DFB233C0DFC0C3C1DFB491D +:107260002E07EBE4490041EE49003E942E07EFAFB4 +:107270003C0DFB493C0DFB223C1DFB3749006B9F3D +:10728000442001902E07EBF948008CD73A6F988480 +:107290004412FEF044300190100F80074900B3E61D +:1072A0004900B4D44900753244200180442000557F +:1072B00042006C0B3C0FFBC749006A983C0FFB4631 +:1072C0004000000950037F4840310C403C0DFB4713 +:1072D00044300055490058F73E07EC03490077C198 +:1072E0002E1FEE9F2E0728AC4423F04A2E000C845C +:1072F00049001606440FFFAA440000552E00111D38 +:107300004900B7CC3C0FFB473C0DFB3E4413F04A11 +:1073100040F03C0058000001660000E0490069AE02 +:107320003E07EBF94200080B3C0E03284900B2EC83 +:107330003E07EBB644338D4154007FFF2E17EF3AE2 +:10734000490040564000804066000002100F800F48 +:107350001010001C4402C4DC10938000020F800354 +:10736000120F80033A210C004200100B4400005021 +:107370004900B3E43C0DFB713C1DFC0C49001FE9C6 +:107380004402E8C83C1DFB3B4900125D5800000464 +:10739000490077C1490013CB490015C7100480018B +:1073A0003C0E032754637FFF4402FEF03C0DFFF3C5 +:1073B00049001156490070204402DF4C3E07EEA000 +:1073C0002E07EBAC4473F04A4410003249006E665D +:1073D0003C03F6152E07EF123C0DFB484490005578 +:1073E00044131C20490041EE3E07E93840F0BC0040 +:1073F000490058F749007774640304033B00E42410 +:107400003C0DFB904402FE50380780004413F40307 +:107410003E07EE9F1003005010048000000480011E +:107420005800002022108001443000802E000CA45F +:107430003C0DFB28440000323E07EBB02E07EB97D3 +:10744000120F800B3C0DFFF4400004163C0FFB2292 +:10745000580000022E07EBCF4463F04A4900813008 +:10746000580000102E07EBBE3C0C043649006CACF3 +:107470005410FFFF3C0808A43C0BF6142E0728AB61 +:1074800044020000490020E8120F800A3E07EEFE89 +:10749000490079CF3E07EBA23B0064042E0011E2C5 +:1074A0004900751B540000FE4462FEF04400006970 +:1074B0004402E9E02E07EE96000500004412FE505B +:1074C0003E07EBCE502F8007000000514403000020 +:1074D0002E07EBB666000004580000083E17EE9F2A +:1074E000021F8000441262384410004C490039F2F7 +:1074F00040109C3600048000480001714470005523 +:107500002E0FEEA0400080164800012838308A0A6D +:10751000490039F250528F003C0BF8DE1010005138 +:1075200044000078440373E83E07EEA23E07EBFBFD +:107530004422C5204200040B4010043666000010AF +:107540004413F2483C0E03203C0C000A5C0000018E +:10755000490063143C0FFBC8100300414900B0E62A +:107560001005000042000C0B49006F22400018403B +:10757000541080FE2E07F14D3C6FFB7E40310C060F +:107580003C0FFB5A223080003C0BF8DF10058000D6 +:10759000490063FD440000642E07F1A449006E66B3 +:1075A000440397DE49003E943E07EBE4440000FFAD +:1075B0002E07F02849007DE158000080549000FF1C +:1075C0004412C3A53C0C000B3C0DFD7B3E17EBC6E3 +:1075D00040320D0018128001020F80012E07EBF2DD +:1075E000501F800F3C1DFB283C0BF62A3E07EBBECC +:1075F0002E07EEEB46500FFF3E07EBE349006E9877 +:10760000500F800E3C1FFB4749008779641304022A +:107610002E07EB8A3E07F1A4382080084430003260 +:107620002E07EF0238048602441000643C0DFB3242 +:107630005000004C3C0DFEE73E07EC132E17EBE428 +:10764000120F80020462801649003F661204800017 +:10765000020F80004422E8C85CF003E84412168060 +:107660003C0C032044134C104400004C441E00000A +:107670004900466F3E07EF2F444000644412E8C8BB +:1076800040108C365EF000334402FEF138530E0A8F +:107690004413F1C04900B76E4420FFFF4402DAF002 +:1076A000500F80063C1DFB993E07F041440397DCD8 +:1076B000540000FD3E07F0474442D3C85CF000335D +:1076C0003C1FFB46660000084422DE583C239422FF +:1076D00049007C9F2E07293E641324032E07E939B5 +:1076E000503F800738009A0A2E07EE9744138D40CA +:1076F000381784003C0BF77E3C0DFB3C4200000336 +:107700003C6FFCB53E17EB9949009306490014BD48 +:107710002E07EBFD4422E9A0441365103C6FFB22C9 +:1077200049007C2B401004063E07EBF23C5DFB3227 +:10773000400080064472C7B8490081584231800336 +:107740000003007D3C0BF77449004602000F8007E0 +:107750004221000366000001500F80073E00114ED9 +:1077600044038D424900632B2E3728123E07EF0E4B +:10777000440000524900466F001480013E07EF0AA2 +:107780004412C4163E07EF373C1DFBD93E07F14DAE +:107790004400012C490040BB421080032E17EEEB41 +:1077A0004412D9B049007C493A0000003C0FFB7EEE +:1077B0004412DA60640308034900808A4900A52165 +:1077C0004200700B3C0E0324490070693C03F8DE54 +:1077D0003E07EBEE490070A0400320094000BC1AB0 +:1077E00040118440490063913C0C01DB444000554A +:1077F0005CF100C83C13F48B44026238120F800025 +:107800003C0DFB7E430388734900404F44037A28B4 +:107810002E07EC02490070823E07F193020F8002AE +:107820004403F7CE030200003C1FFCB43E07EBB25A +:107830003C1BF8244900880040213C0804118014B6 +:1078400049000CDA1010003C002F800749003F0669 +:10785000661080024900899F3E07EBF54900704899 +:107860003E07FAF5405284B61203000944130FA0F4 +:10787000448000553E07F1583C1DFBEA1090000083 +:10788000101000524900450440010016405293F583 +:10789000540000F04403F41C3E07EF0644134DA0CF +:1078A0001003007D121000102E07EF2C3E07293E1A +:1078B000401080204403F00E4900234D3807810119 +:1078C0003E07EE9744038D412E07EF103C1C01DC70 +:1078D0003B014C00441000A5490045D64413331029 +:1078E0003C0BF613490040A54412C3824403F7C879 +:1078F0002E07EBDA120300253C0C00023810AE0212 +:10790000100480464402FE604413F2492250800075 +:107910002E07EBC22E07F0415EF10033041300087E +:107920003C0E03234412C3E63C0FFB7B00030042E2 +:107930002E07EF093C3DFB2F000300462E10111DC2 +:107940004412DA280030000E4412C700490079CFF3 +:10795000101000083C0DFC241003004014AF8001FF +:107960003E07EEF55000024049006B414422CD3401 +:10797000120F800154A000FF3E000CA449003FDE1E +:10798000490020AE49008CFA49003EBA2E07EF0E9E +:107990004412C3AE3C0DFC7440631CD62E17EFAFEF +:1079A000442000B64900707C4402C49C502F8006DD +:1079B000381019095CF287083C1DFB224000810049 +:1079C0002E50111D490061862E07EBE54220907371 +:1079D0004412E4703C0396052E07EBB7460000F412 +:1079E000120300083E07EB903E07F159490044FAA4 +:1079F0003B0FCC203C5DFB3B100080523C0FFB66F4 +:107A000049001E1F2E07EB9B3C0FFB2700000000C8 +:107A10008492030014940300FAAF02008AB10200BA +:107A2000648F0300F4900300DAAC02006AAE020037 +:107A300010330300903F0300104C030090580300E4 +:107A400000A2010080AE010000BB010080C7010060 +:107A500010D8010050DE010090E40100D0EA0100DE +:107A6000E8730300F8740200A00F030068800300AD +:107A70006464696A6C6E71718A827C6F68647690E6 +:107A8000646467696B6D70718E837A6D6664758FDF +:107A90006464696A6C6E71718A827C6F68647690C6 +:107AA000646467696B6D70718E837A6D6664758FBF +:107AB0006464696A6C6E71718A827C6F68647690A6 +:107AC000646467696B6D70718E837A6D6664758F9F +:107AD0006464696A6C6E71718A827C6F6864769086 +:107AE000646467696B6D70718E837A6D6664758F7F +:107AF0006464696A6C6E71718A827C6F6864769066 +:107B0000646467696B6D70718E837A6D6664758F5E +:107B10006464696A6C6E71718A827C6F6864769045 +:107B2000646467696B6D70718E837A6D6664758F3E +:107B30006464696A6C6E71718A827C6F6864769025 +:107B4000646467696B6D70718E837A6D6664758F1E +:107B50006464696A6C6E71718A827C6F6864769005 +:107B6000646467696B6D70718E837A6D6664758FFE +:107B7000646468666C6C71709086806F6B647891D9 +:107B8000646467686B6C707092857D6E68647590D4 +:107B9000646468666C6C71709086806F6B647891B9 +:107BA000646467686B6C707092857D6E68647590B4 +:107BB000646468666C6C71709086806F6B64789199 +:107BC000646467686B6C707092857D6E6864759094 +:107BD000646468666C6C71709086806F6B64789179 +:107BE000646467686B6C707092857D6E6864759074 +:107BF000646468666C6C71709086806F6B64789159 +:107C0000646467686B6C707092857D6E6864759053 +:107C1000646468666C6C71709086806F6B64789138 +:107C2000646467686B6C707092857D6E6864759033 +:107C3000646468666C6C71709086806F6B64789118 +:107C4000646467686B6C707092857D6E6864759013 +:107C5000646468666C6C71709086806F6B647891F8 +:107C6000646467686B6C707092857D6E68647590F3 +:107C700064656B6B6F707678A1958A7A6C647B9B78 +:107C800066646E6B71737678A5988A7C6E647D9B52 +:107C900064656B6B6F707678A1958A7A6C647B9B58 +:107CA00066646E6B71737678A5988A7C6E647D9B32 +:107CB00064656B6B6F707678A1958A7A6C647B9B38 +:107CC00066646E6B71737678A5988A7C6E647D9B12 +:107CD00064656B6B6F707678A1958A7A6C647B9B18 +:107CE00066646E6B71737678A5988A7C6E647D9BF2 +:107CF00064656B6B6F707678A1958A7A6C647B9BF8 +:107D000066646E6B71737678A5988A7C6E647D9BD1 +:107D100064656B6B6F707678A1958A7A6C647B9BD7 +:107D200066646E6B71737678A5988A7C6E647D9BB1 +:107D300064656B6B6F707678A1958A7A6C647B9BB7 +:107D400066646E6B71737678A5988A7C6E647D9B91 +:107D500064656B6B6F707678A1958A7A6C647B9B97 +:107D600066646E6B71737678A5988A7C6E647D9B71 +:107D700064656B6B6F707678A1958A7A6C647B9B77 +:107D800066646E6B71737678A5988A7C6E647D9B51 +:107D900064656A6A6E707377A6958D7C70647E9E4A +:107DA00064666A6C6E707476A7998B7E72647E9E30 +:107DB00064656A6A6E707377A6958D7C70647E9E2A +:107DC00064666A6C6E707476A7998B7E72647E9E10 +:107DD00064656A6A6E707377A6958D7C70647E9E0A +:107DE00064666A6C6E707476A7998B7E72647E9EF0 +:107DF00064656A6A6E707377A6958D7C70647E9EEA +:107E000064666A6C6E707476A7998B7E72647E9ECF +:107E100064656A6A6E707377A6958D7C70647E9EC9 +:107E200064666A6C6E707476A7998B7E72647E9EAF +:107E300064656A6A6E707377A6958D7C70647E9EA9 +:107E400064666A6C6E707476A7998B7E72647E9E8F +:107E500064656A6A6E707377A6958D7C70647E9E89 +:107E600064666A6C6E707476A7998B7E72647E9E6F +:107E700064656A6A6E707377A6958D7C70647E9E69 +:107E800064666A6C6E707476A7998B7E72647E9E4F +:107E9000646468706C71757AA99B8C806E647DA136 +:107EA000676469706F72747BAF9E918571647DA108 +:107EB000646468706C71757AA99B8C806E647DA116 +:107EC000676469706F72747BAF9E918571647DA1E8 +:107ED000646468706C71757AA99B8C806E647DA1F6 +:107EE000676469706F72747BAF9E918571647DA1C8 +:107EF000646468706C71757AA99B8C806E647DA1D6 +:107F0000676469706F72747BAF9E918571647DA1A7 +:107F1000646468706C71757AA99B8C806E647DA1B5 +:107F2000676469706F72747BAF9E918571647DA187 +:107F3000646468706C71757AA99B8C806E647DA195 +:107F4000676469706F72747BAF9E918571647DA167 +:107F5000646468706C71757AA99B8C806E647DA175 +:107F6000676469706F72747BAF9E918571647DA147 +:107F7000646468706C71757AA99B8C806E647DA155 +:107F8000676469706F72747BAF9E918571647DA127 +:107F900064656A736E747A80CCB9A493786485B290 +:107FA00064646A7270757881D5C1AA987C6487B759 +:107FB00064656A736E747A80CCB9A493786485B270 +:107FC00064646A7270757881D5C1AA987C6487B739 +:107FD00064656A736E747A80CCB9A493786485B250 +:107FE00064646A7270757881D5C1AA987C6487B719 +:107FF00064656A736E747A80CCB9A493786485B230 +:1080000064646A7270757881D5C1AA987C6487B7F8 +:1080100064656A736E747A80CCB9A493786485B20F +:1080200064646A7270757881D5C1AA987C6487B7D8 +:1080300064656A736E747A80CCB9A493786485B2EF +:1080400064646A7270757881D5C1AA987C6487B7B8 +:1080500064656A736E747A80CCB9A493786485B2CF +:1080600064646A7270757881D5C1AA987C6487B798 +:1080700064656A736E747A80CCB9A493786485B2AF +:1080800064646A7270757881D5C1AA987C6487B778 +:1080900064656A736E747A80CCB9A493786485B28F +:1080A00064646A7270757881D5C1AA987C6487B758 +:1080B00066666666666666666C6C6C6C6C6C6C6C30 +:1080C0006767676767676767686868686868686838 +:1080D0006565656565656565676767676767676740 +:1080E0006868686868686868666666666666666620 +:1080F0006565656565656565686868686868686818 +:1081000067676767676767676868686868686868F7 +:1081100066666666666666666767676767676767F7 +:1081200066666666666666666464646464646464FF +:1081300065656565656565656868686868686868D7 +:1081400066666666666666666767676767676767C7 +:1081500064646464646464646868686868686868BF +:108160006868686868686868676767676767676797 +:1081700064646464646464646767676767676767A7 +:1081800064646464646464646464646464646464AF +:10819000646464646464646464646464646464649F +:1081A0006565656565656565646464646464646487 +:1081B0006C6C6C6C6C6C6C6C6E6E6E6E6E6E6E6EEF +:1081C0006A6A6A6A6A6A6A6A6D6D6D6D6D6D6D6DF7 +:1081D00069696969696969696B6B6B6B6B6B6B6BFF +:1081E00069696969696969696B6B6B6B6B6B6B6BEF +:1081F00068686868686868686B6B6B6B6B6B6B6BE7 +:1082000069696969696969696B6B6B6B6B6B6B6BCE +:1082100069696969696969696D6D6D6D6D6D6D6DAE +:1082200068686868686868686B6B6B6B6B6B6B6BB6 +:1082300067676767676767676969696969696969BE +:1082400066666666666666666666666666666666CE +:1082500066666666666666666868686868686868AE +:10826000656565656565656569696969696969699E +:108270006666666666666666676767676767676796 +:10828000656565656565656567676767676767678E +:108290006464646464646464676767676767676786 +:1082A000646464646464646464646464646464648E +:1082B0006E6E6E6E6E6E6E6E6A6A6A6A6A6A6A6AFE +:1082C0006C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6CEE +:1082D0006D6D6D6D6D6D6D6D6C6C6C6C6C6C6C6CD6 +:1082E0006C6C6C6C6C6C6C6C6B6B6B6B6B6B6B6BD6 +:1082F0006C6C6C6C6C6C6C6C6868686868686868DE +:108300006A6A6A6A6A6A6A6A6B6B6B6B6B6B6B6BC5 +:108310006B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6BAD +:1083200067676767676767676A6A6A6A6A6A6A6AC5 +:108330006B6B6B6B6B6B6B6B6A6A6A6A6A6A6A6A95 +:1083400067676767676767676868686868686868B5 +:10835000696969696969696967676767676767679D +:1083600069696969696969696B6B6B6B6B6B6B6B6D +:108370006A6A6A6A6A6A6A6A68686868686868686D +:1083800069696969696969696A6A6A6A6A6A6A6A55 +:10839000676767676767676765656565656565657D +:1083A000666666666666666668686868686868685D +:1083B000646464646464646464646464646464647D +:1083C0006464646464646464656565656565656565 +:1083D0006D6D6D6D6D6D6D6D6F6F6F6F6F6F6F6FBD +:1083E00072727272727272726D6D6D6D6D6D6D6D95 +:1083F0006A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6ADD +:108400006D6D6D6D6D6D6D6D6969696969696969BC +:1084100068686868686868686B6B6B6B6B6B6B6BC4 +:1084200069696969696969696A6A6A6A6A6A6A6AB4 +:1084300066666666666666666969696969696969C4 +:1084400069696969696969696868686868686868A4 +:1084500069696969696969696666666666666666A4 +:10846000696969696969696969696969696969697C +:10847000686868686868686868686868686868687C +:10848000696969696969696969696969696969695C +:10849000686868686868686868686868686868685C +:1084A0006767676767676767686868686868686854 +:1084B000666666666666666668686868686868684C +:1084C0006464646464646464656565656565656564 +:1084D0006C6C6C6C6C6C6C6C6F6F6F6F6F6F6F6FC4 +:1084E0006D6D6D6D6D6D6D6D7070707070707070A4 +:1084F0006C6C6C6C6C6C6C6C6E6E6E6E6E6E6E6EAC +:108500006B6B6B6B6B6B6B6B6E6E6E6E6E6E6E6EA3 +:1085100068686868686868686B6B6B6B6B6B6B6BC3 +:108520006B6B6B6B6B6B6B6B6F6F6F6F6F6F6F6F7B +:1085300069696969696969696B6B6B6B6B6B6B6B9B +:1085400068686868686868686C6C6C6C6C6C6C6C8B +:108550006868686868686868696969696969696993 +:10856000676767676767676769696969696969698B +:10857000676767676767676767676767676767678B +:108580006565656565656565686868686868686883 +:10859000676767676767676767676767676767676B +:1085A00065656565656565656B6B6B6B6B6B6B6B4B +:1085B0006464646464646464656565656565656573 +:1085C000656565656565656567676767676767674B +:1085D0006D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6DCB +:1085E0006D6D6D6D6D6D6D6D6B6B6B6B6B6B6B6BCB +:1085F0006B6B6B6B6B6B6B6B6A6A6A6A6A6A6A6AD3 +:1086000068686868686868686A6A6A6A6A6A6A6ADA +:1086100068686868686868686B6B6B6B6B6B6B6BC2 +:108620006B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B9A +:108630006A6A6A6A6A6A6A6A6868686868686868AA +:1086400068686868686868686A6A6A6A6A6A6A6A9A +:10865000686868686868686868686868686868689A +:108660006A6A6A6A6A6A6A6A68686868686868687A +:108670006565656565656565686868686868686892 +:108680006868686868686868676767676767676772 +:108690006767676767676767646464646464646482 +:1086A0006767676767676767646464646464646472 +:1086B000646464646464646464646464646464647A +:1086C0006767676767676767646464646464646452 +:1086D000656565656565656565656565656565654A +:1086E0006464646464646464676767676767676732 +:1086F0006A006F0066006D0069006A0067006B0029 +:1087000069006B0066006D006A006A006500690020 +:1087100069006B0065006C0068006B0067006C000E +:1087200068006A006300690068006700640069000F +:108730006500650063006700640065006300670012 +:10874000650066006200670063006300600062000D +:10875000620062005F006500620061005F0063000C +:10876000600061005E00600061005E005E0060000D +:10877000600060005E005F005F005D005C005F0005 +:108780005E005F005A005E005E005E005A005D0001 +:108790005C005C005B005F005D005D005B005E00F4 +:1087A0005B005A0059005D005800590057005A00FC +:1087B00059005A005B0059005700560057005600F8 +:1087C0005500570054005700540055005400550000 +:1087D00056005300540056005500540054005600F3 +:1087E00055005400520055005400540050005300EE +:1087F00052005100520052005200500050005000F0 +:108800004F004E005000510050004E004E004F00EF +:108810004F004D004D004D004E004B004C004C00F1 +:108820004E004B004C004E004C004A004C004B00E8 +:108830004C0049004B0049004B00470048004800ED +:10884000490048004A0049004A00460048004800E4 +:1088500049004600490047004700460048004600DE +:1088600048004300470044004600430047004400DE +:1088700047004400450046004700440045004500CD +:108880006A006A006F00700072007500780078005E +:1088900092008A00830076006E006A007D009900D5 +:1088A000690069006C006E0070007200760077004D +:1088B00099008D00840076006E006C007E009A00A6 +:1088C00064006400680066006C006C007100700059 +:1088D0008C0082007C006C006800610074008D00D8 +:1088E000620062006500660069006A006E006E004A +:1088F000910084007C006D006700630074008F00AD +:108900005E005F0065006500680069006F0071002F +:108910008E00830079006B005F0058006C008800B7 +:108920005E005C006500620068006A006D006E0019 +:108930009100860079006D00610058006E0088008B +:1089400054005500590059005C005E00610064004D +:108950007E0071006B005E0055004C0060007800E6 +:108960005300550058005A005B005D006000620033 +:108970007F0074006A00600057004C0060007800BF +:108980004C004C004F0055005200560059005D004D +:10899000710068005E0056004A00430054006C00FD +:1089A0004C004A004E0053005200540056005B0039 +:1089B00075006A00610059004C00430054006C00CF +:1089C0004300440047004D004A004E00520056004C +:1089D000700066005A0051004200370049006200F2 +:1089E0004200420046004B004A004D004F00550037 +:1089F000730068005C0052004300360049006300C9 +:108A000019004B007D00AF00E10013014501770123 +:108A1000A901DB010D023F027102A302D502070387 +:108A200039036B039D03CF03020436046A049E04DA +:108A3000D20406053A056E05A205D6050A063E06CD +:108A40007206A606DA060E0742077607AA07DE07B1 +:108A5000120846087A08AE08E20816094A097E0993 +:108A6000B209E60932003200320032003200320030 +:108A70003200320032003200320032003200320066 +:108A80003200320032003200320032003400340052 +:108A90003400340034003400340034003400340036 +:108AA0003400340034003400340034003400340026 +:108AB0003400340034003400340034003400340016 +:108AC000340034003400340019004B007D00AF0046 +:108AD000E100130145017701A901DB010D023F020D +:108AE0007102A302D502070339036B039D03CF0371 +:108AF0000104330465049704C904FB042D055F05D4 +:108B00009105C305F5052706320032003200320018 +:108B100032003200320032003200320032003200C5 +:108B200032003200320032003200320032003200B5 +:108B300032003200320032003200320032003200A5 +:108B4000320032003200320008080908080901002A +:108B50000001000201030203E8730300F87402003D +:108B6000A00F03006880030010D8010050DE010050 +:108B700090E40100D0EA0100208E0200609402001F +:108B8000A09A0200E0A0020010330300903F03000F +:108B9000104C03009058030000090B020F06040D4F +:108BA000070E0C050801030A01020304050600076D +:108BB0000800000006060606060606060600000077 +:108BC00004050607F20A0B00BCC20C002B4C0E0079 +:108BD000AF3009004C5E090030790D000A930F0098 +:108BE000C2E40D000DF50400433D0300D4B30100C1 +:108BF00050CF0600B3A10600CF860200F56C00003E +:108C00003D1B02000DF50400F56C00004C5E0900F0 +:108C10002B4C0E00000000000000000000000000CF +:108C200000000000BCC20C00AF30090030790D001C +:108C3000C2E40D0000000000000000000000000081 +:108C400000000000D4B30100433D0300B3A10600BF +:108C50003D1B02000A930F0030790D00F20A0B0051 +:108C6000AF3009000DF5040050CF0600F56C000090 +:108C7000CF8602004C5E0900C2E40D002B4C0E00B2 +:108C8000BCC20C003D1B0200B3A10600433D030023 +:108C9000D4B30100AF300900F20A0B0030790D00A7 +:108CA0000A930F00CF860200F56C000050CF06003B +:108CB0000DF50400BCC20C002B4C0E00C2E40D00EC +:108CC0004C5E0900F20A0B00BCC20C002B4C0E00DB +:108CD000AF3009004C5E090030790D000A930F0097 +:108CE000C2E40D00020202030303040400000200B8 +:108CF00003000500070009000A000C000E00100028 +:108D0000110013001500160018001A001C001D00A9 +:108D10001F002100220024002500270029002A002E +:108D20002C002D002F0030003200340035003600BA +:108D3000380039003B003C003E003F00400042004C +:108D40004300440045004700480049004A004B00EA +:108D50004D004E004F00500051005200530054008F +:108D60005500560057005700580059005A005B0044 +:108D70005B005C005D005D005E005F005F00600006 +:108D800060006100610061006200620062006300D7 +:108D900063006300630064006400640064006400B6 +:108DA0006400000064006400640064006400640007 +:108DB00063006300630063006200620062006100A0 +:108DC00061006100600060005F005F005E005D00A8 +:108DD0005D005C005B005B005A00590058005700C2 +:108DE00057005600550054005300520051005000E7 +:108DF0004F004E004D004B004A004900480047001C +:108E0000450044004300420040003F003E003C005B +:108E10003B003900380036003500340032003000A5 +:108E20002F002D002C002A002900270025002400F7 +:108E3000220021001F001D001C001A00180016004F +:108E400015001300110010000E000C000A000900AC +:108E500007000500030002000000000000000200FF +:108E600003000500070009000B000C000E001000B5 +:108E7000120013001500170019001B001D001F0031 +:108E8000200022002400260028002A002D002F00A8 +:108E900031003300350037003A003C003E0041000D +:108EA0004300460049004B004E005100540057005B +:108EB0005A005D006100640068006B006F00730081 +:108EC00077007B00800085008A008F0094009A0064 +:108ED000A000A600AD00B400BC00C400CD00D600C8 +:108EE000E100EC00F8000501130122013401470103 +:108EF0005D0175019101B101D601020237027702CD +:108F0000C8022E03B703770496057407300B611669 +:108F100010270000000001000400090010001900E3 +:108F20002400310040005100640079009000A90045 +:108F3000C400E10000012101440169019001B9016F +:108F4000E401110240027102A402D9021003490394 +:108F50008403C103000441048404C90410055905B5 +:108F6000A405F10540069106E40639079007E907D4 +:108F70004408A10800096109C409290A900AF90AEC +:108F8000640BD10B400CB10C240D990D100E890E01 +:108F9000040F810F00108110041189111012991211 +:108FA0002413B1134014D1146415F9159016291720 +:108FB000C41761180019A119441AE91A901B391C29 +:108FC000E41C911D401EF11EA41F00006D006D00E9 +:108FD0006E00700071007100710000006D006D0086 +:108FE0006B00690068006800670000000000050071 +:108FF0000A001300190028003C00000000000000D7 +:109000000038FAFE422EE63F3067C79357F32E3DF5 +:10901000010000000000E0BF5B3051555555D53FC1 +:109020009045EBFFFFFFCFBF1101F124B399C93F7A +:109030009FC806E57555C5BF000000000000E0BFF1 +:10904000775555555555D53FCBFDFFFFFFFFCFBF9A +:109050000CDD95999999C93FA74567555555C5BFE9 +:1090600030DE44A32449C23F653D42A4FFFFBFBF99 +:10907000CAD62A288471BC3FFF68B043EB99B9BFB8 +:1090800085D0AFF78281B73FCD45D1751352B5BFBB +:109090009FDEE0C3F034F73F0090E6797FCCD7BF86 +:1090A0001FE92C6A7813F73F00000DC2EE6FD7BF9F +:1090B000A0B5FA0860F2F63F00E05113E313D7BF02 +:1090C0007D8C131FA6D1F63F007828385BB8D6BF39 +:1090D000D1B4C50B49B1F63F00788090555DD6BF3D +:1090E000BA0C2F334791F63F00001876D002D6BF56 +:1090F000234222189F71F63F00909086CAA8D5BFE0 +:10910000D91EA5994F52F63F00500356434FD5BF85 +:10911000C4248FAA5633F63F00406BC337F6D4BF42 +:1091200014DC9D6BB314F63F0050A8FDA79DD4BF7F +:109130004C5CC65264F6F53F00A889399245D4BF0D +:109140004F2C91B567D8F53F00B8B039F4EDD3BFD7 +:10915000DE905BCBBCBAF53F00708F44CE96D3BF98 +:10916000781AD9F2619DF53F00A0BD171E40D3BF0C +:10917000875646125680F53F008046EFE2E9D2BF9F +:10918000D36BE7CE9763F53F00E030381B94D2BF36 +:10919000937FA7E22547F53F0088DA8CC53ED2BF12 +:1091A00083450642FF2AF53F00902729E1E9D1BF18 +:1091B000DFBDB2DB220FF53F00F8482B6D95D1BF24 +:1091C000D7DE34478FF3F43F00F8B99A6741D1BF37 +:1091D0004028DECF43D8F43F0098EF94D0EDD0BFC5 +:1091E000C8A378C03EBDF43F0010DB18A59AD0BFDD +:1091F0008A25E0C37FA2F43F00B86352E647D0BFA0 +:109200003484D4240588F43F00F0864522EBCFBF98 +:109210000B2D191BCE6DF43F00B017754A47CFBF19 +:10922000541839D3D953F43F0030103D44A4CEBF75 +:109230005A84B444273AF43F00B0E9440D02CEBF4B +:10924000FBF81541B520F43F00F07729A260CDBFAF +:10925000B1F43EDA8207F43F0090950401C0CCBF20 +:109260008FFE575D8FEEF33F001089562920CCBF4B +:10927000E94C0BA0D9D5F33F0010818D1781CBBFEE +:109280002BC110C060BDF33F00D0D3CCC9E2CABF30 +:10929000B8DA752B24A5F33F0090122E4045CABFC3 +:1092A00002D09FCD228DF33F00F01D6877A8C9BF83 +:1092B0001C7A84C55B75F33F003048696D0CC9BFEB +:1092C000E236AD49CE5DF33F00C045A62071C8BF70 +:1092D00040D44D987946F33F003014B48FD6C7BFC1 +:1092E00024CBFFCE5C2FF33F0070623CB83CC7BF7D +:1092F000490DA1757718F33F0060379B9AA3C6BF4D +:1093000090393E37C801F33F00A0B754310BC6BFB8 +:1093100041F895BB4EEBF23F003024767D73C5BF1C +:10932000D1A919020AD5F23F0030C28F7BDCC4BF3D +:109330002AFDB7A8F9BEF23F0000D2512C46C4BFA7 +:10934000AB1B0C7A1CA9F23F000083BC8AB0C3BFE0 +:1093500030B514607293F23F0000496B991BC3BF94 +:10936000F5A15757FA7DF23F0040A4905487C2BF41 +:10937000BF3B1D9BB368F23F00A079F8B9F3C1BFB2 +:10938000BDF58F839D53F23F00A02C25C860C1BF5F +:109390003B08C9AAB73EF23F0020F7577FCEC0BFB7 +:1093A000B640A92B012AF23F00A0FE49DC3CC0BF19 +:1093B0003241CC967915F23F00804BBCBD57BFBF00 +:1093C0009BFCD21D2001F23F004040960837BEBFF3 +:1093D0000B484D49F4ECF13F0040F93E9817BDBFF2 +:1093E00069658F52F5D8F13F00A0D84E67F9BBBF31 +:1093F0007C7E571123C5F13F00602F2079DCBABF76 +:10940000E926CB747CB1F13F008028E7C3C0B9BF27 +:10941000B61A2C0C019EF13F00C072B346A6B8BF2D +:10942000BD70B67BB08AF13F0000ACB3018DB7BF11 +:10943000B6BCEF258A77F13F00003845F174B6BF1E +:10944000DA314C358D64F13F0080876D0E5EB5BF1B +:10945000DD5F2790B951F13F00E0A1DE5C48B4BF69 +:109460004CD232A40E3FF13F00A06A4DD933B3BFB6 +:10947000DAF910728B2CF13F0060C5F87920B2BF89 +:1094800031B5EC28301AF13F00206298460EB1BF8A +:10949000AF3484DAFB07F13F0000D26A6CFAAFBF49 +:1094A000B36B4E0FEEF5F03F0040774A8DDAADBF5B +:1094B000CE9F2A5D06E4F03F000085E4ECBCABBF24 +:1094C00021A52C6344D2F03F00C0124089A1A9BF5E +:1094D0001A98E27CA7C0F03F00C002335888A7BFAB +:1094E000D136C6832FAFF03F0080D6675E71A5BF2F +:1094F0003913A098DB9DF03F008065498A5CA3BFCB +:10950000DFE752AFAB8CF03F00401564E349A1BFE9 +:10951000FB284E2F9F7BF03F0080EB82C0729EBFE6 +:10952000198F358CB56AF03F00805252F1559ABFC1 +:109530002CF9ECA5EE59F03F008081CF623D96BF3B +:10954000902CD1CD4949F03F0000AA8CFB2892BF56 +:10955000A9ADF0C6C638F03F0000F9207B318CBFC2 +:10956000A93279136528F03F0000AA5D351984BF40 +:109570004873EA272418F03F0000ECC2031278BFBA +:1095800095B114060408F03F00002479090460BF77 +:109590001AFA26F71FE0EF3F00009084F3EF6F3FC9 +:1095A00074EA61C21CA1EF3F00003D3541DC873FFA +:1095B0002E9981B01063EF3F0080C2C4A3CE933FC9 +:1095C000CDADEE3CF625EF3F00008914C19F9B3FD7 +:1095D000E7139103C8E9EE3F000011CED8B0A13FD8 +:1095E000ABB1CB7880AEEE3F00C001D05B8AA53F27 +:1095F0009B0C9DA21A74EE3F0080D840835CA93F6B +:10960000B5990A83913AEE3F008057EF6A27AD3F44 +:10961000569A6009E001EE3F00C098E59875B03FAA +:1096200098BB77E501CAED3F00200DE3F553B23F4B +:1096300003917C0BF292ED3F0000388BDD2EB43F9E +:10964000CE5CFB66AC5CED3F00C057875906B63F69 +:109650009DDE5EAA2C27ED3F00006A3576DAB73F23 +:10966000CD2C6B3E6EF2EC3F00601C4E43ABB93F1D +:109670000279A7A26DBEEC3F00600DBBC778BB3F6F +:109680006D08376D268BEC3F0020E7321343BD3F5A +:1096900004585DBD9458EC3F0060DE71310ABF3F55 +:1096A0008C9FBB33B526EC3F0040912B1567C03F24 +:1096B0003FE7ECEE83F5EB3F00B092828547C13F78 +:1096C000C196DB75FDC4EB3F0030CACD6E26C23FAC +:1096D000284A860C1E95EB3F0050C5A6D703C33F12 +:1096E0002C3EEFC5E265EB3F0010333CC3DFC33FC8 +:1096F0008B88C9674837EB3F00807A6B36BAC43F26 +:109700004A301D214B09EB3F00F0D1283993C53F6A +:109710007EEFF285E8DBEA3F00F01824CD6AC63F11 +:10972000A23D60311DAFEA3F009066ECF840C73FB4 +:10973000A758D33FE682EA3F00F01AF5C015C83FAC +:109740008B7309EF4057EA3F0080F65429E9C83F80 +:10975000274BAB902A2CEA3F0040F80236BBC93FAA +:10976000D1F29313A001EA3F00002C1CED8BCA3FFD +:109770001B3CDB249FD7E93F00D0015C515BCB3F12 +:1097800090B1C70525AEE93F00C0BCCC6729CC3FEE +:109790002FCE97F22E85E93F006048D535F6CC3FB5 +:1097A000754BA4EEBA5CE93F00C04634BDC1CD3F65 +:1097B0003848E79DC634E93F00E0CFB8018CCE3F82 +:1097C000E652672F4F0DE93F009017C00955CF3F74 +:1097D0009DD7FF8E52E6E83F00B81F126C0ED03FB7 +:1097E0007C00CC9FCEBFE83F00D0930EB871D03F35 +:1097F0000EC3BEDAC099E83F0070869E6BD4D03F9E +:10980000FB1723AA2774E83F00D04B338736D13F9C +:10981000089AB3AC004FE83F004823670D98D13F4A +:10982000553E65E8492AE83F0080CCE0FFF8D13F8B +:109830006002F4950106E83F006863D75F59D23FA4 +:1098400029A3E06325E2E73F00A8140930B9D23F1D +:10985000ADB5DC77B3BEE73F006043107218D33F6D +:10986000C2259767AA9BE73F0018EC6D2677D33F88 +:10987000570617F20779E73F0030AFFB4FD5D33FCC +:109880000C13D6DBCA56E73F00E02FE3EE32D43F9D +:109890006BB64F010010E63F3C5B42916C027E3C90 +:1098A00095B44D030030E63F415D0048EABF8D3C72 +:1098B00078D4940D0050E63FB7A5D686A77F8E3C9E +:1098C000AD6F4E070070E63F4C25546BEAFC613CDF +:1098D000AE0FDFFEFF8FE63FFD0E594C277E7CBCAE +:1098E000BCC5630700B0E63F01DADC4868C18ABC4A +:1098F000F6C15C1E00D0E63F1193499D1C3F833C9E +:109900003EF605EBFFEFE63F532DE21A04807EBCE6 +:109910008097860E0010E73F5279097166FF7B3C05 +:1099200012E967FCFF2FE73F2487BD26E2008C3C4D +:109930006A1181DFFF4FE73FD201F16E91026EBCE9 +:10994000909C670F0070E73F749C54CD71FC67BC1E +:1099500035C87EFAFF8FE73F8304F59EC1BE813C88 +:10996000E6C220FEFFAFE73F6564CC29177E70BCDE +:1099700000C93FEDFFCFE73F1C8B7B08728080BCA6 +:10998000761A26E9FFEFE73FAEF99D6D28C08D3CC2 +:10999000E8A39C040010E83F334CE551D27F893C9A +:1099A0008F2C93170030E83F81F330B6E9FE8ABC74 +:1099B0009C7333060050E83FBC35656BBFBF893CE4 +:1099C000C68942200070E83F757B11F365BF8BBCF0 +:1099D0000479F5EBFF8FE83F57CB3DA26E0089BCC1 +:1099E000DF04BC2200B0E83F0A4BE038DF007DBC5A +:1099F0008A1B0CE5FFCFE83F059FFF46710088BC3E +:109A0000438E91FCFFEFE83F38707AD07B81833C36 +:109A1000C75FFA1E0010E93F03B4DF76913E893C30 +:109A2000B97B46130030E93F7602984B4E807F3C6D +:109A30006F07EEE6FF4FE93F2E62FFD9F07E8FBC45 +:109A4000D1123CDEFF6FE93FBA382696AA8270BC7D +:109A50000D8A45F4FF8FE93FEFA864911B8087BC16 +:109A60003E2E98DDFFAFE93F37935A8AE04087BC2E +:109A700066FB49EDFFCFE93F00E09BC108CE3F3CCC +:109A8000519CF12000F0E93F0A5B8827AA3F8ABC7D +:109A900006B045110010EA3F56DA589948FF743C69 +:109AA000FAF6BB070030EA3F186D2B8AABBE8C3C40 +:109AB000791D97100050EA3F307978DDCAFE883C66 +:109AC000482EF51D0070EA3FDBABD83D76418FBCD8 +:109AD0005233591C0090EA3F1276C28402BF8EBCFA +:109AE0004B3E4F2A00B0EA3F5F3FFF3C04FD69BC9C +:109AF000D11EAED7FFCFEA3FB4709012E73E82BCD2 +:109B0000780451EEFFEFEA3FA3DE0EE03E066A3C2A +:109B10005B0D65DBFF0FEB3FB90A1F38C8065A3CE7 +:109B200057CAAAFEFF2FEB3F1D3C23741E0179BCD0 +:109B3000DCBA95D9FF4FEB3F9F2A866810FF79BCAE +:109B40009C659E240070EB3F3E4F86D045FF8A3CCB +:109B5000401687F9FF8FEB3FF9C3C29677FE7C3C36 +:109B60004FCB04D2FFAFEB3FC42BF2EE27FF63BC19 +:109B7000455C41D2FFCFEB3F21EA3BEEB7FF6CBC27 +:109B8000DF0963F8FFEFEB3F5C0B2E97034181BCCD +:109B90005376B5E1FF0FEC3F196AB79464C18B3C73 +:109BA000E357FAF1FF2FEC3FEDC6308DEFFE64BCBA +:109BB00024E4BFDCFF4FEC3F7547ECBC683F84BC3E +:109BC000F7B954EDFF6FEC3FECE053F0A37E843C1B +:109BD000D58F99EBFF8FEC3FF192F98D0683733CA3 +:109BE0009A21252100B0EC3F040E18648EFD68BC5C +:109BF0009C4694DDFFCFEC3F72EAC71CBE7E8E3CD4 +:109C000076C4FDEAFFEFEC3FFE889FAD39BE8E3C87 +:109C10002BF89A160010ED3F715AB9A8917D753C4A +:109C20001DF70F0D0030ED3FDAC7706990C1893C18 +:109C3000C40F79EAFF4FED3F0CFE58C5370E58BCF4 +:109C4000E587DC2E0070ED3F440FC14DD6807FBC10 +:109C5000AA82DC210090ED3F5C5CFD948F7C74BC9B +:109C600083026BD8FFAFED3F7E6121C51D7F8C3C29 +:109C700039476C2900D0ED3F53B1FFB29E01883CBB +:109C8000F59044E5FFEFED3F89CC52C6D2006E3C23 +:109C900094F6ABCDFF0FEE3FD2692D2040837FBC01 +:109CA000DDC852DBFF2FEE3F64081BCAC1007B3CBE +:109CB000EF1642F2FF4FEE3F51AB94B0A8FF723C5B +:109CC000115E8AE8FF6FEE3F59BEEFB173F657BCE5 +:109CD0000DFF9E110090EE3F01C80B5E8D8084BC8D +:109CE0004417A5DFFFAFEE3FB52043D50600783C13 +:109CF000A17F121A00D0EE3F925C5660F80250BC71 +:109D0000C4BCBA0700F0EE3F11E6355D444085BCA7 +:109D1000028D7AF5FF0FEF3F0591EF3931FB4FBC14 +:109D2000C78AE51E0030EF3F551173F2AC818A3CC3 +:109D3000943482F5FF4FEF3F43C7D7D4413F8A3C6D +:109D40006B4CA9FCFF6FEF3F7578981CF40262BC66 +:109D500041C4F9E1FF8FEF3F4BE777F4D17D773CCA +:109D60007EE3E0D2FFAFEF3F31A37C9A19016FBCD5 +:109D70009EE4771C00D0EF3FB1ACCE4BEE81713C3E +:109D800031C3E0F7FFEFEF3F5A87700137056EBC34 +:109D90006E6065F4FF0FF03FDA0A1C49AD7E8ABCA5 +:109DA000587A86F3FF2FF03FE0B2FCC3697F97BC7F +:109DB000170DFCFDFF4FF03F5B94CB34FEBF973C8B +:109DC000824DCD030070F03FCB56E4C08300823C4F +:109DD000E8CBF2F9FF8FF03F1A7537BEDFFF6DBC9D +:109DE00065DA0C0100B0F03FEB26E6AE7F3F91BC98 +:109DF00038D3A40100D0F03FF79F4879FA7D803C2A +:109E0000FDFDDAFAFFEFF03FC06BD670050477BCBA +:109E100096FDBA0B0010F13F620B6D84D4808E3C2E +:109E20005DF4E5FAFF2FF13FEF36FD64FABF9D3C8C +:109E3000D99AD50D0050F13FAE50127077009A3C80 +:109E40009A55210F0070F13FEEDEE3E2F9FD8D3C03 +:109E5000265427FCFF8FF13F73723BDC3000913CAE +:109E6000593C3D1200B0F13F88010380797F993C55 +:109E7000B79E29F8FFCFF13F678C9FAB32F965BCE5 +:109E800000D48AF4FFEFF13FEB5BA79DBF7F933CCB +:109E9000A4868B0C0010F23F225BFD916B809F3CEF +:109EA000034385030030F23F33BF9FEBC2FF933C77 +:109EB00084F6BCFFFF4FF23F722E2E7EE701763C08 +:109EC000D92129F5FF6FF23F610C7F76BBFC7F3C07 +:109ED0003C3A93140090F23F2B41023CCA0272BC00 +:109EE0001363551400B0F23F021FF233828092BC1C +:109EF0003B52FEEBFFCFF23FF2DC4F387EFF88BCD7 +:109F000096ADB80B00F0F23FC541305051FF85BC13 +:109F1000AFE27AFBFF0FF33F9D285E88710081BCA2 +:109F20007F5FACFEFF2FF33F15B7B73F5DFF91BCDE +:109F30005667A60C0050F33FBD828B22827F953C72 +:109F400021F7FB110070F33FCCD50DC4BA00803C63 +:109F5000B92F59F9FF8FF33F51A7B22D9D3F94BC04 +:109F600042D2DD0400B0F33FE13876706B7F853C70 +:109F700057C9B2F5FFCFF33F3112BF103A027A3C16 +:109F800018B4B0EAFFEFF33FB052B1666D7F983C72 +:109F9000F4AF32150010F43F2485195F37F8673CA1 +:109FA000298B47170030F43F4351DC72E601833CB4 +:109FB00063B495E7FF4FF43F5A89B2B869FF893C13 +:109FC000E07504E8FF6FF43F54F2C29BB1C095BC4A +:109FD000E7C16FEFFF8FF43F722A3AF209409B3CD2 +:109FE00004A7BEE5FFAFF43F457D0DBFB7FF94BCAE +:109FF000DE27101700D0F43F3D6ADC7164C099BCC5 +:10A00000E23EF00F00F0F43F1C53850B897F973C34 +:10A01000D14BDC120010F53F36A466716504603C3C +:10A020007A2705160030F53F093223CECEBF96BC05 +:10A030004C70DBECFF4FF53FD7A10505720289BCE0 +:10A04000A9545FEFFF6FF53F1264C90EE6BF9B3C5A +:10A050001210E6170090F53F90EFAF81C57E883C67 +:10A06000923EC90300B0F53FC00CBF0A08419FBC37 +:10A07000BC19491D00D0F53F294725FB2A8198BC12 +:10A08000897AB8E7FFEFF53F0469ED80B77E94BCAD +:10A0900000000000000000000000000000000000C0 +:10A0A00000000000000000000000000000000000B0 +:10A0B00000000000000000000000000000000000A0 +:10A0C0000000000000000000000000000000000090 +:10A0D0000000000000000000000000000000000080 +:10A0E0000000000000000000000000000000000070 +:10A0F0000000000000000000000000000000000060 +:10A10000000000000000000000000000000000004F +:10A11000000000000000000000000000000000003F +:10A12000000000000000000000000000000000002F +:10A13000000000000000000000000000000000001F +:10A14000000000000000000000000000000000000F +:10A1500000000000000000000000000000000000FF +:10A1600000000000000000000000000000000000EF +:10A1700000000000000000000000000000000000DF +:10A1800000000000000000000000000000000000CF +:10A1900000000000000000000000000000000000BF +:10A1A00000000000000000000000000000000000AF +:10A1B000000000000000000000000000000000009F +:10A1C000000000000000000000000000000000008F +:10A1D000000000000000000000000000000000007F +:10A1E000000000000000000000000000000000006F +:10A1F000000000000000000000000000000000005F +:10A20000000000000000000000000000000000004E +:10A21000000000000000000000000000000000003E +:10A22000000000000000000000000000000000002E +:10A23000000000000000000000000000000000001E +:10A24000000000000000000000000000000000000E +:10A2500000000000000000000000000000000000FE +:10A2600000000000000000000000000000000000EE +:10A2700000000000000000000000000000000000DE +:10A2800000000000000000000000000000000000CE +:10A2900000000000000000000000000000000000BE +:10A2A00000000000000000000000000000000000AE +:10A2B000000000000000000000000000000000009E +:10A2C000000000000000000000000000000000008E +:10A2D000000000000000000000000000000000007E +:10A2E000000000000000000000000000000000006E +:10A2F000000000000000000000000000000000005E +:10A30000000000000000000000000000000000004D +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000000000000000000076 +:10AAE0000000000000000000000000000000000066 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB20000000000000000000000000000000000025 +:10AB30000000000000000000000000000000000015 +:10AB40000000000000000000000000000000000005 +:10AB500000000000000000000000000000000000F5 +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00000000000000000000000000000000000A5 +:10ABB0000000000000000000000000000000000095 +:10ABC0000000000000000000000000000000000085 +:10ABD0000000000000000000000000000000000075 +:10ABE0000000000000000000000000000000000065 +:10ABF0000000000000000000000000000000000055 +:10AC00000000000000000000000000000000000044 +:10AC10000000000000000000000000000000000034 +:10AC20000000000000000000000000000000000024 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF0000000000000000000000000000000000051 +:10B000000000000000000000000000000000000040 +:10B010000000000000000000000000000000000030 +:10B020000000000000000000000000000000000020 +:10B030000000000000000000000000000000000010 +:10B040000000000000000000000000000000000000 +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B0900000000000000000000000000000000000B0 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F000000000000000000000000000000000000000 +:10F0100000000000000000000000000000000000F0 +:10F0200000000000000000000000000000000000E0 +:10F0300000000000000000000000000000000000D0 +:10F0400000000000000000000000000000000000C0 +:10F0500000000000000000000000000000000000B0 +:10F0600000000000000000000000000000000000A0 +:10F070000000000000000000000000000000000090 +:10F080000000000000000000000000000000000080 +:10F090000000000000000000000000000000000070 +:10F0A0000000000000000000000000000000000060 +:10F0B0000000000000000000000000000000000050 +:10F0C0000000000000000000000000000000000040 +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000000000000000000020 +:10F0F0000000000000000000000000000000000010 +:10F1000000000000000000000000000000000000FF +:10F1100000000000000000000000000000000000EF +:10F1200000000000000000000000000000000000DF +:10F1300000000000000000000000000000000000CF +:10F1400000000000000000000000000000000000BF +:10F1500000000000000000000000000000000000AF +:10F16000000000000000000000000000000000009F +:10F17000000000000000000000000000000000008F +:10F18000000000000000000000000000000000007F +:10F19000000000000000000000000000000000006F +:10F1A000000000000000000000000000000000005F +:10F1B000000000000000000000000000000000004F +:10F1C000000000000000000000000000000000003F +:10F1D000000000000000000000000000000000002F +:10F1E000000000000000000000000000000000001F +:10F1F000000000000000000000000000000000000F +:10F2000000000000000000000000000000000000FE +:10F2100000000000000000000000000000000000EE +:10F2200000000000000000000000000000000000DE +:10F2300000000000000000000000000000000000CE +:10F2400000000000000000000000000000000000BE +:10F2500000000000000000000000000000000000AE +:10F26000000000000000000000000000000000009E +:10F27000000000000000000000000000000000008E +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F000000000000000000000000000000000000E +:10F3000000000000000000000000000000000000FD +:10F3100000000000000000000000000000000000ED +:10F3200000000000000000000000000000000000DD +:10F3300000000000000000000000000000000000CD +:10F3400000000000000000000000000000000000BD +:10F3500000000000000000000000000000000000AD +:10F36000000000000000000000000000000000009D +:10F37000000000000000000000000000000000008D +:10F38000000000000000000000000000000000007D +:10F39000000000000000000000000000000000006D +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D000000000000000000000000000000000002D +:10F3E000000000000000000000000000000000001D +:10F3F000000000000000000000000000000000000D +:10F4000000000000000000000000000000000000FC +:10F4100000000000000000000000000000000000EC +:10F4200000000000000000000000000000000000DC +:10F4300000000000000000000000000000000000CC +:10F4400000000000000000000000000000000000BC +:10F4500000000000000000000000000000000000AC +:10F46000000000000000000000000000000000009C +:10F47000000000000000000000000000000000008C +:10F48000000000000000000000000000000000007C +:10F49000000000000000000000000000000000006C +:10F4A000000000000000000000000000000000005C +:10F4B000000000000000000000000000000000004C +:10F4C000000000000000000000000000000000003C +:10F4D000000000000000000000000000000000002C +:10F4E000000000000000000000000000000000001C +:10F4F000000000000000000000000000000000000C +:10F5000000000000000000000000000000000000FB +:10F5100000000000000000000000000000000000EB +:10F5200000000000000000000000000000000000DB +:10F5300000000000000000000000000000000000CB +:10F5400000000000000000000000000000000000BB +:10F5500000000000000000000000000000000000AB +:10F56000000000000000000000000000000000009B +:10F57000000000000000000000000000000000008B +:10F58000000000000000000000000000000000007B +:10F59000000000000000000000000000000000006B +:10F5A000000000000000000000000000000000005B +:10F5B000000000000000000000000000000000004B +:10F5C000000000000000000000000000000000003B +:10F5D000000000000000000000000000000000002B +:10F5E000000000000000000000000000000000001B +:10F5F000000000000000000000000000000000000B +:10F6000000000000000000000000000000000000FA +:10F6100000000000000000000000000000000000EA +:10F6200000000000000000000000000000000000DA +:10F6300000000000000000000000000000000000CA +:10F6400000000000000000000000000000000000BA +:10F6500000000000000000000000000000000000AA +:10F66000000000000000000000000000000000009A +:10F67000000000000000000000000000000000008A +:10F68000000000000000000000000000000000007A +:10F69000000000000000000000000000000000006A +:10F6A000000000000000000000000000000000005A +:10F6B000000000000000000000000000000000004A +:10F6C000000000000000000000000000000000003A +:10F6D000000000000000000000000000000000002A +:10F6E000000000000000000000000000000000001A +:10F6F000000000000000000000000000000000000A +:10F7000000000000000000000000000000000000F9 +:10F7100000000000000000000000000000000000E9 +:10F7200000000000000000000000000000000000D9 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000000000099 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F860000000000000000000000000000000000098 +:10F870000000000000000000000000000000000088 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF0000000000000000000000000000000000001 +:020000022000DC +:1000000000000000000000000000000000000000F0 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:102000000BF420324006000A0E0A000103010810FA +:1020100032004006F6090000000C0100000000003C +:1020200000135759040600000000000000080109D1 +:10203000000132334006000028191900000E00008C +:10204000000E0000000E0000000E0000000E000058 +:10205000000E0000000E0000000E0000000D030046 +:10206000000E0000000E0000000E0000000D030036 +:10207000000E0000000E0000000E00000000000036 +:10208000000101000000000000000000000000004E +:10209000000000000000000000000101010101003B +:1020A0000001010000000101010100010000000029 +:1020B0000100000102000000070000000107010309 +:1020C000020314000A0A4000000078003C000000EF +:1020D0000000000000000000000000000000000000 +:1020E0000000000000000000C800C8009600C80002 +:1020F00007078000800005050000000000000000C8 +:1021000006010000000017003900910010001400C3 +:10211000F9FFC4FFFF7FFF7FFF7FFF7FFA002C01E5 +:102120003200C8000A04B4B43232230500000000B3 +:1021300000070D0000320D00000000203232323264 +:1021400032323232323232323232323232320000D3 +:10215000000000000000000000000000000000007F +:102160000A05000A00000000140F001210120000FF +:10217000000000000000000000000000000000005F +:10218000000000000F233246500000006A645046F1 +:102190003C3C3C3C08000000000000000F2332469D +:1021A000500000006A6450463C3C3C3C0F141E2822 +:1021B000000000000A0A0A0A0A0A0A0A0C192D413C +:1021C0005000000046554B4646464646000000007B +:1021D0000A0314005F00F1FF14000F000A00BC02A4 +:1021E00000000000F8FF00007800320064002800C2 +:1021F0000F000F001C023D011C02740400003F068A +:102200000000FF09F40100003F060000FF0932143E +:10221000021E1E32020096003C003C007700C805FA +:10222000770088090000000040063000200001000F +:10223000220000003A00520070008F00AF00CF0073 +:10224000EF000F012E014F016E018E01AD01CE0195 +:10225000EC010F022D024D026D028D02AC02CC0288 +:10226000EB020B032B034A036A038903AA03C90386 +:10227000E703FF0337040000000000000000000037 +:10228000000000000000000000000000000000004E +:10229000000000000000000000000000000000003E +:1022A000000000000000000000000000000000002E +:1022B000000000000000000000000000000000001E +:1022C000000000000000000000000000000000000E +:1022D00000000000000000000000000000000000FE +:1022E00000000000000000000000000000000000EE +:1022F00000000000000000000000F6093000460069 +:102300000100480000003C00430066008500A90071 +:10231000C800E90009012A0149016B018901AB01EB +:10232000C901EB0109022B024A026C028A02AC02CB +:10233000CA02EC020B032D034B036D038B03AE03A8 +:10234000CB03EE030C042F044C046F048B04AF0486 +:10235000CC04EF040D0530054D0570058D05B00565 +:10236000CD05F1050D0630064E0672068E06B10645 +:10237000CE06F2060F073207500773079007B30720 +:10238000D107F40711083408520875089108B108FC +:10239000C608E70800000000000000000000000080 +:1023A000000000000000000000000000000000002D +:1023B000000000000000000000000000000000001D +:1023C000000000000000000000000000000000000D +:1023D0000201200019450000F16C000084D90600BC +:1023E00029B1010010270000C4090000000101010B +:1023F000010102020202014B0F00A00000000000D8 +:102400000100010101010102020202001945000060 +:1024100002000000A46B00000000000014140A0A6F +:102420001400000000000000141414140101010144 +:10243000010040003200E8030F0008000500900092 +:1024400000001E502800B4005000040000000000EE +:10245000B4005000FA00A000000000014F0100008D +:102460000000000068010D0D0A094B004B006400DC +:102470000A003200C800640064000F02E8E8F800B7 +:10248000F8000200190000006A00750081008E004B +:102490009D00AC00BD00CF00E200F7000D01260159 +:1024A00040015C0179019901BC01E00106023002A2 +:1024B0005B028902BA02EE0224035D039A03D90388 +:1024C0001B046004A904F40443059505E9054106CD +:1024D0009C06FA065B07BE0724088D08F808650904 +:1024E000D409450AB80A2D0BA20B190C900C080D43 +:1024F000800DF80D6F0EE60E5C0FD00F4210B3107A +:1025000021118C11F4115912BA1217137013C4133C +:1025100013145D14A114E01418154B1577159C15B0 +:10252000BB15D415E515EF15F31536003D00440035 +:102530004C00560060006B00770085009300A400FB +:10254000B500C900DE00F5000E0129014601650154 +:102550008701AC01D401FE012B025B028F02C6028F +:1025600001033F038003C6030F045D04AE040305AB +:102570005D05BA051B068106EA065707C9073D082F +:10258000B6083109B009320AB70A3E0BC70B520C24 +:10259000DF0C6D0DFC0D8B0E1A0FA80F3610C3103B +:1025A0004D11D6115B12DE125C13D7134D14BD14FE +:1025B00028158D15EC1544169516DE161F1758179D +:1025C0008917B117D117E717F517FA174E005600FC +:1025D00060006B00760083009100A000B100C20093 +:1025E000D600EB0002011A01350152017001910180 +:1025F000B501DB0103022E025C028D02C102F8026A +:1026000032036F03B003F4033B048604D4042605AD +:102610007C05D50532069206F5065C07C607330829 +:10262000A30816098C09040A7E0AFA0A790BF80B2A +:10263000790CFB0C7E0D010E830E060F870F071021 +:10264000861003117D11F5116912DA124713AF13C9 +:1026500013147214CB141E156B15B215F2152C162B +:102660005E168916AC16C716DB16E716EB166A005F +:10267000750081008E009D00AC00BD00CF00E2001F +:10268000F7000D01260140015C0179019901BC01AF +:10269000E001060230025B028902BA02EE02240364 +:1026A0005D039A03D9031B046004A904F4044305E1 +:1026B0009505E90541069C06FA065B07BE07240856 +:1026C0008D08F8086509D409450AB80A2D0BA20B34 +:1026D000190C900C080D800DF80D6F0EE60E5C0FB6 +:1026E000D00F4210B31021118C11F4115912BA12EB +:1026F00017137013C41313145D14A114E0141815E8 +:102700004B1577159C15BB15D415E515EF15F3156D +:102710005500550045004200000000000000000088 +:1027200000000000000000000000000000000000A9 +:102730000000000000000000000000000000000099 +:102740000000000000000000000000000000000089 +:102750000000000000000000000000000000000079 +:102760000000000000000000000000000000000069 +:102770000000000000000000000000000000000059 +:102780000000000000000000000000000000000049 +:102790000000000000000000000000000000000039 +:1027A0000000000000000000000000000000000029 +:1027B0000000000000000000000000000000000019 +:1027C0000000000000000000000000000000000009 +:1027D00000000000000000000000000000000000F9 +:1027E00000000000000000000000000000000000E9 +:1027F00000000000000000000000000000000000D9 +:1028000000000000000000000000000000000000C8 +:1028100000000000000000000000000000000000B8 +:1028200000000000000000000000000000000000A8 +:102830000000000000000000000000000000000098 +:102840000000000000000000000000000000000088 +:102850000000000000000000000000000000000078 +:10286000000000000000000000000000A000D200F6 +:1028700004013C0005000000000000000000000012 +:102880000000000000000000000000000000000048 +:102890000000000000000000000000000000000038 +:1028A0000000000000000000000000000000000028 +:1028B0000000000000000000000000000000000018 +:1028C0000000000000000000000000000000000008 +:1028D00000000000000000000000000000000000F8 +:1028E00000000000000000000000000000000000E8 +:1028F00000000000000000000000000000000000D8 +:1029000000000000000000000000000000000000C7 +:1029100000000000000000000000000000000000B7 +:1029200000000000000000000000000000000000A7 +:102930000000000000000000000000000000000097 +:102940000000000000000000000000000000000087 +:102950000000000000000000000000000000000077 +:102960000000000000000000000000000000000067 +:102970000000000000000000000000000000000057 +:102980000000000000000000000000000000000047 +:102990000000000000000000000000000000000037 +:1029A0000000000000000000000000000000000027 +:1029B0000000000000000000000000000000000017 +:1029C0000000000000000000000000000000000007 +:1029D00000000000000000000000000000000000F7 +:1029E00000000000000000000000000000000000E7 +:1029F00000000000000000000000000000000000D7 +:102A00001901010000000000000000003202300047 +:102A10000000575900000000000000000000000006 +:102A200099020000BC020000DF0200000203000067 +:102A300025030000480300006B0300008E03000024 +:102A4000B1030000D4030000F70300001A040000E3 +:102A50003D0400006004000083040000A6040000A0 +:102A6000C904000020030000D4B804020351180078 +:102A700007B28C2363200C0485011C0800000000B1 +:102A800000000000190000005B555555555555557F +:102A90005555555505000000080A000010000A00B1 +:102AA000000000010000000002E00000EC045406F9 +:102AB00084067E07410AA2076A099109B1097E17B7 +:102AC00007B8C30700800000208300000080328028 +:102AD000648096802DB4040F110C0F0F10000F139B +:102AE000A5BA830A18C80F0015101510104310431B +:102AF00020030000D4A8040C42330E0EC4338E23EE +:102B000063011911E32101132302000000000000FA +:102B10001B0000005B555555555555555555555598 +:102B20005505000098090B0BB0B00000B0B0001BB9 +:102B30000B00000082F01002EC04540684067E07AD +:102B4000410AA2076A099109B1097E1707B8C307AC +:102B50000080000020830000008032806480968026 +:102B60002DB4040F110C0F0F10000F13A5BA830A18 +:102B700018C80F0015101510104310432003000053 +:102B8000090000000000000000000000000000003C +:102B90000000000000000000000000000100000034 +:102BA0000300000000000000000000000000000022 +:102BB0000200000000000000000000000000000013 +:102BC00000000000EC04540684067E07410AA207B8 +:102BD0006A099109B1097E1707B8C3070080000090 +:102BE0002083000000803280648096802DB4040F22 +:102BF000110C0F0F10000F13A5BA830A18C80F008D +:102C0000151015101043104320030000D4B804021F +:102C10000351180007B28C2363200C0485011C08A3 +:102C20000000000000000000190000005B55555531 +:102C3000555555555555555555000000086A666659 +:102C400036666A66666666636600000002E000003B +:102C5000EC04540684067E07410AA2076A0991091A +:102C6000B1097E1707B8C307008000002083000069 +:102C700000803280648096802DB4040F110C0F0FF9 +:102C800010000F13A5BA830A18C80F0015101510ED +:102C90001043104320030000D4A8040C42330E0E4E +:102CA000C4338E2363011911E321011323020000B1 +:102CB000000000001B0000005B555555555555554B +:102CC000555555555505000098696B6BB6B6666647 +:102CD000B6B6663B6B06000082F01002EC045406A8 +:102CE00084067E07410AA2076A099109B1097E1785 +:102CF00007B8C307008000002083000000803280F6 +:102D0000648096802DB4040F110C0F0F10000F1368 +:102D1000A5BA830A18C80F001510151010431043E8 +:102D200020030000D4B854161796010000000000DC +:102D30000000000000000000000000000000000093 +:102D4000080000005B555555000000000000000021 +:102D500000000000081A111100000000000000002F +:102D60000000000002000000EC04540684067E0708 +:102D7000410AA2076A099109B1097E1707B8C3077A +:102D800000800000208300000080328064809680F4 +:102D90002DB4040F110C0F0F10000F13A5BA830AE6 +:102DA00018C80F0015101510104310432003000021 +:102DB000D4B854161796010000000000000000006F +:102DC00000000000000000000000000008000000FB +:102DD0005B55555500000000000000000000000099 +:102DE000083A33330000000000000000000000003B +:102DF00002000000EC04540684067E07410AA20784 +:102E00006A099109B1097E1707B8C307008000005D +:102E10002083000000803280648096802DB4040FEF +:102E2000110C0F0F10000F13A5BA830A18C80F005A +:102E3000151015101043104320030000D4A8540CA3 +:102E4000567339184F068D11A3344E000000000050 +:102E50000000000000000000130000005B55555505 +:102E600055555555550500000000000008191B1B5D +:102E70001B1B0B0B0B0B00000000000002A002004C +:102E8000EC04540684067E07410AA2076A099109E8 +:102E9000B1097E1707B8C307008000002083000037 +:102EA00000803280648096802DB4040F110C0F0FC7 +:102EB00010000F13A5BA830A18C80F0015101510BB +:102EC0001043104320030000D4A8540C5673391843 +:102ED0004F068D11A3344E000000000000000000DA +:102EE00000000000130000005B5555555555555521 +:102EF000550500000000000008393B3B3B3B0B0B35 +:102F00000B0B00000000000002A00200EC045406BD +:102F100084067E07410AA2076A099109B1097E1752 +:102F200007B8C307008000002083000000803280C3 +:102F3000648096802DB4040F110C0F0F10000F1336 +:102F4000A5BA830A18C80F001510151010431043B6 +:102F500020030000D4A8051B023774045E311A2335 +:102F6000C7088C08000000000000000000000000FE +:102F7000140000005B5555555555555555550000E5 +:102F800000000000080909090909000010000000FC +:102F90000000000002500500EC04540684067E0781 +:102FA000410AA2076A099109B1097E1707B8C30748 +:102FB00000800000208300000080328064809680C2 +:102FC0002DB4040F110C0F0F10000F13A5BA830AB4 +:102FD00018C80F00151015101043104320030000EF +:102FE000D4A8051B023774045E311A23C7088C0865 +:102FF00000000000000000000000000014000000BD +:103000005B55555555555555555500000000000068 +:10301000086969696969606030600000000000004B +:1030200002500500EC04540684067E07410AA207FC +:103030006A099109B1097E1707B8C307008000002B +:103040002083000000803280648096802DB4040FBD +:10305000110C0F0F10000F13A5BA830A18C80F0028 +:10306000151015101043104320030000D4A8551B61 +:10307000167775185E0600000000000000000000D2 +:1030800000000000000000000C0000005B555555DA +:103090005555000000000000000000000819191933 +:1030A00019190000000000000000000002000000EC +:1030B000EC04540684067E07410AA2076A099109B6 +:1030C000B1097E1707B8C307008000002083000005 +:1030D00000803280648096802DB4040F110C0F0F95 +:1030E00010000F13A5BA830A18C80F001510151089 +:1030F0001043104320030000D4A8551B1677751801 +:103100005E0600000000000000000000000000005B +:10311000000000000C0000005B555555555500009F +:10312000000000000000000008393939393900007A +:10313000000000000000000002000000EC04540643 +:1031400084067E07410AA2076A099109B1097E1720 +:1031500007B8C30700800000208300000080328091 +:10316000648096802DB4040F110C0F0F10000F1304 +:10317000A5BA830A18C80F00151015101043104384 +:1031800020030000E3180803446100070800000062 +:10319000000000000000000000000000000000002F +:1031A0000B00000055555555550500000000000066 +:1031B000000000000000000001000000000000000E +:1031C0000000000003000000EC04540684067E07A3 +:1031D000410AA2076A099109B1097E1707B8C30716 +:1031E0000080000020830000008032806480968090 +:1031F0002DB4040F110C0F0F10000F13A5BA830A82 +:1032000018C80F00151015101043104320030000BC +:10321000D4B8000000000000000000000000000022 +:10322000000000000000000000000000030000009B +:103230005B0500000000000000000000000000002E +:10324000080A00000000000000000000000000006C +:1032500002000000EC04540684067E07410AA2071F +:103260006A099109B1097E1707B8C30700800000F9 +:103270002083000000803280648096802DB4040F8B +:10328000110C0F0F10000F13A5BA830A18C80F00F6 +:10329000151015101043104320030000090500000D +:1032A00000000000C002000000000000000000005C +:1032B0000000000000000000020000006466666676 +:1032C00066660000000000000000000082000000B0 +:1032D00000A000000000000000000000FC0700004B +:1032E000EC04540684067E07410AA2076A09910984 +:1032F000B1097E1707B8C3070080000020830000D3 +:1033000000803280648096802DB4040F110C0F0F62 +:1033100010000F13A5BA830A18C80F001510151056 +:103320001043104320030000813010050670200078 +:10333000000000000000000000000000000000008D +:10334000000000000900000055555555050000001B +:10335000000000000000000000000001000000006C +:10336000000000000000000000000000EC04540613 +:1033700084067E07410AA2076A099109B1097E17EE +:1033800007B8C3070080000020830000008032805F +:10339000648096802DB4040F110C0F0F10000F13D2 +:1033A000A5BA830A18C80F00151015101043104352 +:1033B0000000000000000001000003000000FC000D +:1033C000000000000D000D0040065906000000003E +:1033D0000155B400020000000000000001010302DA +:1033E000000001000000FC00000000000D000D00C6 +:1033F00000000F000000000004B0B3000000001047 +:103400000000000002020302000001000000FC00B6 +:10341000000000000D000D0001000E000000000083 +:1034200004C4B30000000010000000000303030206 +:10343000000001000000FC00000000000D000D0075 +:1034400002000D000000000004D8B30000000010CE +:103450000000000004040302000001000000FC0062 +:10346000000000000D000D0003000C000000000033 +:1034700004ECB3000000001000000000050503028A +:10348000000001000000FC00000000000D000D0025 +:1034900004000B00000000000400B4000000001055 +:1034A0000000000006060302000001000000FC000E +:1034B000000000000D000D0005000A0000000000E3 +:1034C0000414B4000000001000000000070703020D +:1034D000000001000000FC00000000000D000D00D5 +:1034E00006000900000000000428B40000000010DD +:1034F0000000000008080302000005000000FC00B6 +:10350000000000000D000D00070008000000000092 +:10351000043CB4000000001000000000090000019D +:10352000000007000000FC00000000000D000D007E +:10353000A00FB90F000000000150B400000000000F +:103540000000000000000001000003000000FC007B +:10355000000000000D000D00C116A81600000000BC +:1035600001A0B400060000000000000000001717D2 +:10357000000003000000FC00000000000D000D0032 +:103580003818391800000000019BB4000400000046 +:103590000000000000001616010003000000FD00FE +:1035A000000000000D000D00681070100000FA25EA +:1035B0000473B400040000000000000000001717AE +:1035C000020003000000FC00000000000D000D00E0 +:1035D000F811F9110000FA250487B4000400000076 +:1035E0000000000000001616030003000000FD00AC +:1035F000000000000D000D00681070100000FA259A +:103600000473B4000400000000000000000017175D +:10361000040003000000FC00000000000D000D008D +:10362000F811F9110000FA250487B4000400000025 +:103630000000000000001616050003000000FD0059 +:10364000000000000D000D00681070100000FA2549 +:103650000473B4000400000000000000000017170D +:10366000060003000000FC00000000000D000D003B +:10367000F811F9110000FA250487B40004000000D5 +:103680000000000000001616070003000000FD0007 +:10369000000000000D000D00681070100000FA25F9 +:1036A0000473B400040000000000000000001717BD +:1036B000080003000000FC00000000000D000D00E9 +:1036C000F811F9110000FA250487B4000400000085 +:1036D00000000000000A1414092802000000FC0089 +:1036E00000000000050005000000000000000000D0 +:1036F000010097030000000000000000000000012E +:10370000000003000000FC00000000000D000D00A0 +:103710000000190000000000015AB400020000007F +:103720000000000000000001000003000000FC0099 +:10373000000000000D000D009001A9010000000034 +:10374000015FB40002000000000000000000000162 +:10375000000003000000FC00000000000D000D0050 +:1037600020033903000000000164B40002000000DF +:103770000000000000000001000003000000FC0049 +:10378000000000000D000D00B004C904000000009E +:103790000169B40002000000000000000000000108 +:1037A000000003000000FC00000000000D000D0000 +:1037B0004006590600000000016EB400020000003F +:1037C0000000000000000100000003000000FC00F9 +:1037D000000000000D000D006810811000000000C6 +:1037E00001A5B40006000000000000000000010078 +:1037F000000003000000FC00000000000D000D00B0 +:10380000F81111120000000001AAB4000600000027 +:103810000000000000000100000003000000FC00A8 +:10382000000000000D000D008813A113000000002F +:1038300001AFB4000600000000000000000001001D +:10384000000003000000FC00000000000D000D005F +:10385000181531150000000001B4B4000600000086 +:103860000000000000000100000003000000FC0058 +:10387000000000000D000D00A816C1160000000099 +:1038800001B9B400060000000000000000000100C3 +:10389000002802000000FC000000000009000900F0 +:1038A0000000000000000000010097030600000077 +:1038B00000000000000B1414002802000000FC00AF +:1038C000000000000C000C000000000000000000E0 +:1038D000010097030000000000000000000B14141A +:1038E000002802000000FC003F0000000C000C005B +:1038F000000000000000000001009703000000002D +:1039000000000000000B1515002802000000CC008C +:10391000000000000C000C0000000000000000008F +:1039200001009703000000000000000000000100FB +:10393000002802000000FC00000000000D000D0047 +:1039400000000000000000000100970306000000D6 +:103950004F00000001F4040068931B0060000000A9 +:103960000C000000010004001428000060000000AA +:10397000300000002D008400142800001C0000000E +:10398000730000002DF4840068931B001C000000ED +:10399000700000002DF4840068931B001C000000E0 +:1039A0007300000023F4840068931B001C000000D7 +:1039B0006000000050F4840094EB1B001C00000029 +:1039C0004F00000001F4040068931B00E0000100B8 +:1039D0000C0000000100040014280000E0000100B9 +:1039E000300000002D008400142800001C0000009E +:1039F000700000002DF4840068931B001C00000080 +:103A0000730000002DF4840051651B001C000000B1 +:103A1000010128010101010101010101010101016F +:103A20000101010101010101010101010101010186 +:103A30000101010101010101010101010101010176 +:103A40000101010101010101010101010101010166 +:103A50000101010101010101010101010101010156 +:103A60000101010101010101010101010101010146 +:103A7000010101012B2B2C2E2D2C2E2E2B2E2E2C2A +:103A80002C2D2E2C2D2C2D2D2C2D2D2E2D2C2E2E67 +:103A90002D2C2D2E2E2D2D2D2C2D2E2E2D2E2E2D52 +:103AA0002D2E2D2E2F2D2D2F2E2D2E2F2D2E2F2E38 +:103AB0002D2E2E2E2E2D2F2F2D2E2E2F2E2D2E2E27 +:103AC0002E2E2D2E2F2D2E2E2D2F2F2F2E2E2E2E15 +:103AD0002E2F2E303D2A2B2B2B2B2B2D2B2C2D2D0F +:103AE0002B2E2E2C2B2C2E2C2C2C2D2D2C2D2C2E0D +:103AF0002D2C2E2E2D2C2D2E2E2D2D2D2C2D2E2EF3 +:103B00002D2D2E2D2D2E2D2E2E2D2D2E2D2D2E2FDD +:103B10002D2E2F2E2D2E2E2E2E2D2F2F2D2E2E2FC5 +:103B20002E2D2E2E2E2D2E2E2F2D2F2E2D2F2F2FB4 +:103B30002D2E2E2E2E2E2E2F2B292B2B2B2B2B2DBD +:103B40002B2B2D2D2B2E2E2C2B2C2E2C2C2C2D2DAF +:103B50002C2D2C2E2D2C2D2E2D2C2D2E2E2C2D2D96 +:103B60002C2D2E2E2D2D2E2D2D2E2D2E2E2D2D2E7F +:103B70002D2D2E2F2D2E2F2E2C2E2E2E2E2D2F2E68 +:103B80002D2E2E2F2E2D2E2E2E2D2E2E2F2C2E2E58 +:103B90002D2F2F2F2D2E2E2E2E2E2E2F2A292B2B52 +:103BA0002B2B2B2D2B2B2D2D2B2E2E2C2B2C2E2C53 +:103BB0002C2C2D2D2C2D2C2E2D2C2D2E2D2C2D2E38 +:103BC0002E2C2D2D2C2D2E2E2D2D2E2D2D2E2D2E21 +:103BD0002E2D2D2E2D2D2E2F2D2E2F2E2D2E2E2E09 +:103BE0002E2D2F2E2D2E2E2F2E2D2E2E2E2D2E2EF7 +:103BF0002F2C2E2E2D2F2F2F2D2E2E2E2E2E2E2FE4 +:103C00002B292B2B2B2B2B2D2B2B2C2D2B2E2E2CFA +:103C10002B2C2E2C2C2C2D2D2C2D2C2E2D2C2D2EDA +:103C20002D2C2D2E2E2C2D2D2C2D2E2E2D2D2E2DC2 +:103C30002D2E2D2E2E2D2D2E2D2D2E2F2D2E2F2EA9 +:103C40002D2E2E2E2E2D2F2E2D2E2E2F2E2D2E2E96 +:103C50002E2D2E2E2F2D2E2E2D2F2F2F2D2E2E2E84 +:103C60002E2E2E2F2B292B2B2B2B2B2D2B2B2C2D94 +:103C70002B2E2E2C2B2C2E2C2C2C2D2D2C2D2C2E7B +:103C80002D2C2D2E2D2C2D2E2E2C2D2D2C2D2E2E63 +:103C90002D2D2E2D2D2E2D2E2E2D2D2E2D2D2E2F4C +:103CA0002D2E2F2E2D2E2E2E2E2D2F2E2D2E2E2F35 +:103CB0002E2D2E2E2E2D2E2E2F2D2E2E2D2F2F2F24 +:103CC0002D2E2E2E2E2E2E2F2B292B2B2B2B2B2D2C +:103CD0002B2B2C2D2B2E2E2C2B2C2E2C2C2C2D2D1F +:103CE0002C2D2C2E2D2C2D2E2D2C2D2E2E2C2D2D05 +:103CF0002C2D2E2E2D2D2E2D2D2E2D2E2E2D2D2EEE +:103D00002D2D2E2F2D2E2F2E2D2E2E2E2E2D2F2ED5 +:103D10002D2E2E2F2E2D2E2E2F2D2E2E2F2D2E2EC4 +:103D20002D2F2F2F2D2E2E2E2E2E2E2F2B292B2BBF +:103D30002B2B2B2D2B2C2C2D2B2E2E2C2B2C2E2CC1 +:103D40002D2C2D2D2C2D2C2E2D2C2D2E2D2C2D2EA5 +:103D50002E2D2D2D2C2D2E2E2D2E2E2D2D2E2D2E8D +:103D60002E2D2D2E2D2D2E2F2D2E2F2E2D2E2F2E76 +:103D70002E2D2F2F2D2E2E302E2D2E2F2F2E2E2F5F +:103D80002F2D2F2E2D2F2F2F2D2E2E2E2E2E2E2F50 +:103D90002B292B2C4D4D4D4D4D4D4D4D4D4D4D4DDC +:103DA0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D43 +:103DB0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D33 +:103DC0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D23 +:103DD0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D13 +:103DE0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D03 +:103DF0004D4D4D4D4D4D4D4D9224922492009200CB +:103E000000000000B66DB66DB600B6000000000000 +:103E1000B66DB66D9601960100000000B66DB66DE8 +:103E2000B201B20100000000B62DB62DB601B601F8 +:103E300000000000B665B665B601B60100000000DE +:103E4000B66CB66CB601B60100000000966D966DBA +:103E5000B601B60100000000B26DB26DB601B60148 +:103E600000000000FF7FFF7FFF01FF010000000056 +:103E7000B66DB66DB601B601000000009224922422 +:103E800092009200000000000110000000000000FD +:103E900000000000FFFF3DDB38D4FC020200AA0056 +:103EA0006C768A940001060000000000DB0600002A +:103EB000040C000060056E40415639030100009A71 +:103EC000EC045661000000000000000010C40C501B +:103ED0000390BBBB80442278641164118A3989390C +:103EE00085E00FE06612641201100000000000007F +:103EF00000000000FFFF3DDB38D4FC020200AA00F6 +:103F00006C768A940001060000000000DB060000C9 +:103F1000040C000060056E40415639030100009A10 +:103F2000EC045661000000000000000010C40C10FA +:103F3000E39EBBBB80552278641164118A398939AC +:103F400085E00FE06612641201040000000000002A +:103F50000000000000000000000000020200AA00B3 +:103F60006C768A940001060000000000DB06000069 +:103F7000040C000020066E40418639030100009ABF +:103F8000AC058661000000000000000010C40C5069 +:103F90000390BBBB80442278641164118A3989394B +:103FA00085E00FE066126412C904020001020304F6 +:103FB000EAF7FAFD3001A880CF0304021E000003D7 +:103FC0006C768A940001060000000000DB06000009 +:103FD000014600002B1A0040006B39034100029A91 +:103FE00000006B616478792BCF8A00801C54119893 +:103FF0000080BBBB00572278641164118A3989396B +:1040000085F00FF066126412C9040200010101017B +:10401000EAF7FAFD3001A880CF0304020200000095 +:104020006C768A940001060000000000DB060000A8 +:10403000014600002B1A0040006B39034100029A30 +:1040400000006B61BB7DFC17FFFF00801C541198C2 +:104050000380BBBB80462278641164118A39893998 +:1040600085F00FF066126412C90402000202020217 +:10407000EAF7FAFD3001A880CF0304020200000035 +:104080006C768A940001060000000000DB06000048 +:10409000014600002B1A0040006B39034100029AD0 +:1040A00000006B610F7E3416FFFF00801C541198D6 +:1040B0000380BBBB80462278641164118A39893938 +:1040C00085F00FF066126412C904020003030303B3 +:1040D000EAF7FAFD3001A880CF03040202000000D5 +:1040E0006C768A940001060000000000DB060000E8 +:1040F000014600002B1A0040006B39034100029A70 +:1041000000006B61B17E3C12FFFF00801C541198CF +:104110000380BBBB80462278641164118A398939D7 +:1041200085F00FF066126412C9040200040404044E +:10413000EAF7FAFD3001A880CF0304020200000074 +:104140006C768A940001060000000000DB06000087 +:10415000014600002B1A0040006B39034100029A0F +:1041600000006B611C7F0B0FFFFF00801C54119837 +:104170000380BBBB80462278641164118A39893977 +:1041800085F00FF0661264120104000400000000C4 +:10419000CCF57AFDED20BF8FCF03040202060000AC +:1041A0006C768A940001060000000000DB06000027 +:1041B00001060000093C0040006B39034100029AEF +:1041C00000006B616478792BCF8A00801CC41018C2 +:1041D0000380AAAA00C6227864116411803980394C +:1041E0000F000F00550D550DC904020006070A0BFC +:1041F000EAF7FAFD3001A880CF0304021E0600038F +:104200006C768A940001060000000000DB060000C6 +:10421000014600002B1A0040006B39034100029A4E +:1042200000006B616478792BCF8A00801C54119850 +:104230000080BBBB00572218641164118A39893988 +:1042400085F00FF066126412C90402000606060625 +:10425000EAF7FAFD3001A880CF030402020600004D +:104260006C768A940001060000000000DB06000066 +:10427000014600002B1A0040006B39034100029AEE +:1042800000006B616478792BCF8A00801C541198F0 +:104290000080BBBB00572218641164118A39893928 +:1042A00085F00FF066126412C904020006060A0ABD +:1042B000EAF7FAFD3001A880CF0304020A060100E4 +:1042C0006C768A940043060100000000DB060000C3 +:1042D000014600002B1A0040006B39034100029A8E +:1042E00000006B619367CBB40000008012541198FA +:1042F0000080BBBB00562218641164118A398939C9 +:1043000085F00FF066126412C904020007070B0B58 +:10431000EAF7FAFD3001A880CF0304020A06010083 +:104320006C768A940043060100000000DB06000062 +:10433000014600002B1A0040006B39034100029A2D +:1043400000006B6155737BC8000000801254119807 +:104350000080BBBB00562218641164118A39893968 +:1043600085F00FF066126412C904020009090C0CF2 +:10437000EAF7FAFD3001A880CF0304020A06010023 +:104380006C768A940043060100000000DB06000002 +:10439000014600002B1A0040006B39034100029ACD +:1043A00000006B61D9770ED3000000801254119881 +:1043B0000080BBBB00562218641164118A39893908 +:1043C00085F00FF066126412C90402000A0A06069C +:1043D000EAF7FAFD3001A880CF0304020A060100C3 +:1043E0006C768A940043060100000000DB060000A2 +:1043F000014600002B1A0040006B39034100029A6D +:1044000000006B61BD7977D80000008012541198CC +:104410000080BBBB00562218641164118A398939A7 +:1044200085F00FF066126412C90402000B0B070737 +:10443000EAF7FAFD3001A880CF0304020A06010062 +:104440006C768A940043060100000000DB06000041 +:10445000014600002B1A0040006B39034100029A0C +:1044600000006B61757B34DE0000008012541198EF +:104470000080BBBB00562218641164118A39893947 +:1044800085F00FF066126412C90402000A0A0606DB +:10449000EAF7FAFD3001A880CF0304020A06010002 +:1044A0006C768A940043060100000000DB060000E1 +:1044B000014600002B1A0040006B39034100029AAC +:1044C00000006B61CB7C87E30000008012541198E0 +:1044D0000080BBBB00562218641164118A398939E7 +:1044E00085F00FF066126412C90402000B0B070777 +:1044F000EAF7FAFD3001A880CF0304020A060100A2 +:104500006C768A940043060100000000DB06000080 +:10451000014600002B1A0040006B39034100029A4B +:1045200000006B61F27D29E90000008012541198AF +:104530000080BBBB00562218641164118A39893986 +:1045400085F00FF066126412C90402000C0C090910 +:10455000EAF7FAFD3001A880CF0304020A06010041 +:104560006C768A940043060100000000DB06000020 +:10457000014600002B1A0040006B39034100029AEB +:1045800000006B61D57EC2EE0000008012541198CD +:104590000080BBBB00562218641164118A39893926 +:1045A00085F00FF0661264120000000000000000A9 +:1045B00000101000FFFF56CE000099103F0E30068D +:1045C000FFFFFDF900006FA13F0E3005FFFF464FD2 +:1045D000000029A63F0F3004FFFFAD8700007DD902 +:1045E0003F0F30030000C15A00009C9A00041030B5 +:1045F0000000BCA00000903800091033000083D0F8 +:104600000000D635000B10350000C9C200001A5951 +:10461000000C103600008CA100002C9F000D1037FC +:1046200000009851000044DC000E10380000BEEA83 +:104630000000A536000E103A000026620000DD9949 +:10464000000F103B0000000064000000700000003C +:104650008900000098000000C9000000D700000099 +:10466000F100000000010000400000000000000018 +:10467000000000000000000000000000000000003A +:10468000000000000000000000000000000000002A +:10469000000000000000000000000000000000001A +:1046A000000000000000000000000000000000000A +:1046B00000000000000000000000000000000000FA +:1046C00000000000870700008579385793F930A172 +:1046D000B3D4CC2BCB0AF200000000000000000095 +:1046E00000000000000000000000000000000000CA +:1046F00000000000000000000000000000000000BA +:1047000080220022870700008579385793E4C2B9D8 +:1047100030AFCC2BC5A1B3000000000000000000AA +:104720000000000000000000000000000000000089 +:104730000000000000000000000000000000000079 +:1047400080220022870700008579385793E4C2BC95 +:10475000C2BCD7930D7930000000000000000000BB +:104760000000000000000000000000000000000049 +:104770000000000000000000000000000000000039 +:1047800080220022870700008579385793E4C2BF52 +:10479000930ACC2BC4F50D000000000000000000BF +:1047A0000000000000000000000000000000000009 +:1047B00000000000000000000000000000000000F9 +:1047C00080220022870700008579385793E4C2BF12 +:1047D000930AE4C2B286CF0000000000000000008F +:1047E00000000000000000000000000000000000C9 +:1047F00000000000000000000000000000000000B9 +:1048000080220022870700008579385793E4C2BFD1 +:10481000930AB0AF26CF5000000000000000000057 +:104820000000000000000000000000000000000088 +:104830000000000000000000000000000000000078 +:1048400080220022870700008579385793E4C2BB95 +:104850000AF2E4C2BE4C2B00000000000000000081 +:104860000000000000000000000000000000000048 +:104870000000000000000000000000000000000038 +:1048800080220022870700008579385793E4C2BB55 +:104890000AF2B0AF295E4C000000000000000000EA +:1048A0000000000000000000000000000000000008 +:1048B00000000000000000000000000000000000F8 +:1048C00080220022C8060000450EA63D450EA63DEA +:1048D000BAF15942450EA63D450EA63D450EA63DF0 +:1048E000450EA63D00000000000000000000000092 +:1048F00000000000000000000000000000000000B8 +:1049000080220022000102030405060708090A0BA1 +:104910000C0D0E0F101112131415161718191A1B5F +:104920001C1D1E1F202122232425262728292A2B4F +:104930002C2D2E2F30310000000000000000000060 +:10494000000000000000000000000000191A1B1CFD +:104950001D1E1F202122232425262728292A2B2C0F +:104960002D2E2F303132333435363738393A3B3CFF +:104970003D3E3F404142434445464748494A000086 +:104980000000000000000000000000000000000027 +:10499000000000000020406080A0C0E000204060D7 +:1049A00080A0C0E00020406080A0C0E00020406007 +:1049B00080A0C0E00020406080A0C0E000204060F7 +:1049C00080A0C0E0002000000000000949924812C9 +:1049D00092B46D1B1B4992246DDBB63600204060FB +:1049E00080A0C0E00020406080A0C0E000204060C7 +:1049F00080A0C0E00020406080A0C0E000204060B7 +:104A000080A0C0E00020406080A0C0E00020000046 +:104A1000000000094992481292B46D1B1B49922470 +:104A20006DDBB6362021E0E1A0A160612021E0E14C +:104A3000A0A160612021E0E1A0A160612021E0E16E +:104A4000A0A160612021E0E1A0A160612021E0E15E +:104A5000A0A160612021000076DBB62D2449921BC5 +:104A6000DBB6491292942409090000000100C1C07C +:104A7000818041400100C1C0818041400100C1C02E +:104A8000818041400100C1C0818041400100C1C01E +:104A9000818041400100C1C081804140010000008F +:104AA00076DBB62D2449921BDBB649129294240979 +:104AB000090000002120E1E0A1A061602120E1E0E7 +:104AC000A1A061602120E1E0A1A061602120E1E0DE +:104AD000A1A061602120E1E0A1A061602120E1E0CE +:104AE000A1A061602120000076DBB62D2449921B35 +:104AF000DBB64912929424090900000063432303A2 +:104B0000E2C2A28262422202E2C2A2826242220285 +:104B1000E2C2A28262422202E2C2A2826242220275 +:104B2000E2C2A28262422202E2C2A2826242000089 +:104B300000D0B62D2D499224DBB66D1292242509A2 +:104B4000490200002C0CECCCAC8C6C4C2C0CECCC4A +:104B5000AC8C6C4C2C0CECCCAC8C6C4C2C0CECCC95 +:104B6000AC8C6C4C2C0CECCCAC8C6C4C2C0CEBCB87 +:104B7000AB8B6B4B2B0B00002D499224DBB66D12D7 +:104B8000922425094902000040DBB62DA484644428 +:104B90002404E3C3A38363432303E3C3A3836343E3 +:104BA0002303E3C3A38363432303E3C3A3836343D5 +:104BB0002303E3C3A38363432303E3C3A38300006B +:104BC0000000B42D6D4B9224E4B66D1B922449096C +:104BD00049920000EBCBAB8B6B4B2B0BEBCBAB8B36 +:104BE0006B4B2B0BEBCBAB8B6B4B2B0BEBCBAB8B15 +:104BF0006B4B2B0BEBCBAB8B6B4B2B0BEACAAA8A09 +:104C00006A4A2A0AEACA00002449921BDBB6491202 +:104C100092942409090000006DDBB624E5C5A58542 +:104C200065452505E4C4A48464442404E4C4A48440 +:104C300064442404E4C4A48464442404E4C4A48434 +:104C400064442404E4C4A48464442404E4C400004C +:104C50000000002D6DDB922424B96D1B9B244912AA +:104C600049922400AA8A6A4A2A0AEACAAA8A6A4A8D +:104C70002A0AEACAAA8A6A4A2A0AEACAAA8A6A4A94 +:104C80002A0AEACAAA8A6A4A2A0AE9C9A98969498A +:104C90002909E9C9A989000024496E1BDB264912AC +:104CA000529224090000002D6DDB92242606E6C6F0 +:104CB000A68666462606E5C5A58565452505E5C59E +:104CC000A58565452505E5C5A58565452505E5C594 +:104CD000A58565452505E5C5A5856545250500002E +:104CE000090000006DDBB62424496E1BDB26491247 +:104CF0005292240969492909E9C9A98969492909F7 +:104D0000E9C9A98969492909E9C9A9896949290913 +:104D1000E9C9A98969492909E8C8A888684828080B +:104D2000E8C8A8886848000024B96D1B9B24491274 +:104D3000499224000000B42D6D4B92246747270749 +:104D4000E7C7A78767472707E6C6A68666462606FB +:104D5000E6C6A68666462606E6C6A68666462606F3 +:104D6000E6C6A68666462606E6C6A686664600000F +:104D70004902000040DBB62D2449921BDBB64912E4 +:104D8000929424092808E8C8A88868482808E8C830 +:104D9000A88868482808E8C8A88868482808E8C893 +:104DA000A88868482808FFFFFFFFFFFFFFFFFFFFFD +:104DB000FFFFFFFFFFFF0000E4B66D1B92244909CF +:104DC0004992000000F0FF3FFFFFFF3FFFFFFFFFA2 +:104DD000FFFFFFFFFFFFFFFFFFFFE7C7A787674753 +:104DE0002707E7C7A78767472707E7C7A787674753 +:104DF0002707E7C7A78767472707E7C7A7870000F1 +:104E0000FFFFFF3FFFDFB62D2D499224DBB66D1269 +:104E100092242509636261605F5E5D5C5B5A59584C +:104E200057565554535251504F4E4D4C4B4A49488A +:104E300047464544434241403F3E3D3C3B3A39387A +:104E40003736353433320000000000000000000027 +:104E500000000000000000000000000031302F2E94 +:104E60002D2C2B2A292827262524232221201F1EEA +:104E70001D1C1B1A191817161514131211100F0EDA +:104E80000D0C0B0A090807060504030201000000C7 +:104E90000000000000000000000000000000000012 +:104EA00000000000FFFFFFFFFFFFFFFFFFFFFFFF0E +:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:104ED000FFFFFFFFFFFF0000FFFFFF3FFFFFFF3F60 +:104EE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFFFF12 +:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:104F0000FFFFFFFFFFFFFFFFFFFF000000000000AB +:104F10000000000000000000000000000000000091 +:104F2000FFFFFF3FFFFFFF3FFFFFFF3F00000000CD +:104F30000000000007172737475706162636465643 +:104F400005152535455504142434445403132333DF +:104F500043530212223242520111213141510010B9 +:104F600020304050FFFF0000000000000000000063 +:104F700000000000000000000000003F00020406E6 +:104F8000080A0C0E10121416181A1C1E20222426B1 +:104F9000282A2C2E30323436383A3C3E40424446A1 +:104FA000484A4C4E50525456585A5C5E606200005B +:104FB00000000000000000000000000000000000F1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE00000000000000000000000000000000000C1 +:104FF00000000000000000000000000000000000B1 +:1050000000000000000000000000000000000000A0 +:105010000000000000000000000000000000000090 +:105020000000000000000000000000000000000080 +:105030000000000000000000000000000000000070 +:105040000000000000000000000000000000000060 +:105050000000000000000000000000000000000050 +:105060000000000000000000000000000000000040 +:105070000000000000000000000000000000000030 +:105080000000000000000000000000000000000020 +:105090000000000000000000000000000000000010 +:1050A0000000000000000000000000000000000000 +:1050B00000000000000000000000000000000000F0 +:1050C00000000000000000000000000000000000E0 +:1050D00000000000000000000000000000000000D0 +:1050E00000000000000000000000000000000000C0 +:1050F00000000000000000000000000000000000B0 +:10510000000000000000000000000000000000009F +:10511000000000000000000000000000000000008F +:10512000000000000000000000000000000000007F +:10513000000000000000000000000000000000006F +:10514000000000000000000000000000000000005F +:10515000000000000000000000000000000000004F +:10516000000000000000000000000000000000003F +:10517000000000000000000000000000000000002F +:10518000000000000000000000000000000000001F +:10519000000000000000000000000000000000000F +:1051A00000000000000000000000000000000000FF +:1051B00000000000000000000000000000000000EF +:1051C00000000000000000000000000000000000DF +:1051D00000000000000000000000000000000000CF +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:105200001501010000000000000000003202100043 +:105210001B00000000000000000000000000000073 +:105220008C0C0000AF0C0000D20C0000F50C00004C +:10523000200300004110080344611C080000000026 +:10524000000000000000000000000000000000005E +:105250000A00000066666666560000000000000056 +:10526000000000000000000000000000000000003E +:105270000000000003080000180DD60D060E1F0EDA +:10528000530F580E300F420F430F7E1707B8C30756 +:1052900000800000208300000080328064809680BF +:1052A0002DB4040F110C0F0F10000F1325BD830A2E +:1052B00018C80F00130E130E0E410E4120030000FC +:1052C000CBB2300DCE0345120000000000000000FC +:1052D0000000000000000000000000000A000000C4 +:1052E00066666666560000000000000000000000D0 +:1052F0001111111111111111111100000000000004 +:1053000003080000180DD60D060E1F0E530F580E81 +:10531000300F420F430FAE0B07B80F330080000071 +:105320002083000000803280648096802DB4040FBA +:10533000110C0F0F90000F13A5BA830A18C80F00A5 +:10534000130E130E0E410E4145097E1707B8C30711 +:105350000080008020F3000C00803280648096FE84 +:105360002DB4FFFF11FDFFFFD0FF0F13A5BA830A75 +:1053700018C80F00130F130F0F410F411F03000038 +:105380000900000000000000000000000000000014 +:10539000188DD68D068E1F8E538F588E308F428F6C +:1053A000438F0000000000C000000000000000006B +:1053B00002000000000000000000000000000000EB +:1053C00000E60000EC0454E7E4077EE75509A20775 +:1053D0000A09250945097E1707B8C30700800000A0 +:1053E0002083000000803280648096802DB4048F7A +:1053F00011FDFFFFD0FF0F93A5BA830A18E80FE055 +:10540000130F13FF0F410F411F030000D4B8040214 +:105410000351188748F00C0C85011C08188DD68D97 +:10542000068E1F8E538F588E308F428F438F555567 +:10543000555555D55555000000000018086A666698 +:1054400066666666366600270000000002E6008099 +:10545000EC0C54EFE4877EE75509A2070AE925E939 +:105460000000000000000100002802000000FC0015 +:10547000000000000D000D0059064006000000006D +:105480000155970102000000000000000001020227 +:10549000002800008002FC00FFFFFF010D000D004E +:1054A00007000F000000000004B0B300000000106F +:1054B0000000000000020202002800008002FC0040 +:1054C000FFFFFF010D000D0006000E0000000000B0 +:1054D00004C4B3000000001000000000000302023A +:1054E000002800008002FC00FFFFFF010D000D00FE +:1054F00005000D000000000004D8B30000000010FB +:105500000000000000040202002800008002FC00ED +:10551000FFFFFF010D000D0004000C000000000063 +:1055200004ECB300000000100000000000050202BF +:10553000002800008002FC00FFFFFF010D000D00AD +:1055400003000B00000000000400B4000000001085 +:105550000000000000060202002800008002FC009B +:10556000FFFFFF010D000D0002000A000000000017 +:105570000414B40000000010000000000007020244 +:10558000002800008002FC00FFFFFF010D000D005D +:1055900001000900000000000428B4000000001011 +:1055A0000000000000080202002804008002FC0045 +:1055B000FFFFFF010D000D000000080000000000CB +:1055C00020B0B30000000010000000000000000048 +:1055D000002806000000FC00000000000D000D0087 +:1055E000D20FA00F00000000015097010000000042 +:1055F0000000000000000000002802000000FC0085 +:10560000000000000D000D00C116A81600000000EB +:10561000018C97010600000000000000000B020250 +:10562000002800008000FC00000000000D000D00BC +:1056300007000F000000000004B0B30000000010DD +:1056400000000000000C0202002800008000FC00A6 +:10565000000000000D000D0006000E00000000001C +:1056600004C4B3000000001000000000000D02029E +:10567000002800008000FC00000000000D000D006C +:1056800005000D000000000004D8B3000000001069 +:1056900000000000000E0202002800008000FC0054 +:1056A000000000000D000D0004000C0000000000D0 +:1056B00004ECB3000000001000000000000F020224 +:1056C000002800008000FC00000000000D000D001C +:1056D00003000B00000000000400B40000000010F4 +:1056E0000000000000100202002800008000FC0002 +:1056F000000000000D000D0002000A000000000084 +:105700000414B400000000100000000000110202A8 +:10571000002800008000FC00000000000D000D00CB +:1057200001000900000000000428B400000000107F +:105730000000000000120202002804008000FC00AB +:10574000000000000D000D00000008000000000037 +:1057500020B0B300000000104F00000001F404006E +:1057600068931B00600000000C00000001000400B2 +:105770001428000060000000300000002D008400AC +:10578000142800001C000000730000002DF48400A9 +:1057900068931B001C000000700000002DF48400C2 +:1057A00068931B001C000000630000002DF48400BF +:1057B00068931B001C000000630000002DF48400AF +:1057C00068931B001C0000004F00000001F404005F +:1057D00068931B00E00001000C00000001000400C1 +:1057E00014280000E0000100300000002D008400BB +:1057F000142800001C000000700000002DF484003C +:1058000068931B001C000000000000000000000066 +:105810000000000000000000000000000000000088 +:105820000000000000000000000000000000000078 +:105830000000000000000000000000000000000068 +:105840000000000000000000000000000000000058 +:105850000000000000000000000000000000000048 +:105860000000000000000000000000000000000038 +:1058700000000000000000000000000092249224BC +:105880009200920000000000224924492401A40053 +:105890000000000014492449240114010000000004 +:1058A000A4482449240122010000000024452429A1 +:1058B000240124010000000024292445240124019E +:1058C000000000002449A448220124010000000037 +:1058D00024491449140124010000000024492249EC +:1058E000A400240100000000FF7FFF7FFF01FF01F3 +:1058F00000000000B66DB66DB601B60100000000F4 +:10590000B26DB66DB601B60000000000966DB66DC2 +:10591000B601960100000000B66CB66DB601B2018A +:1059200000000000B665B62DB601B601000000000B +:10593000B62DB665B601B60100000000B66DB66CB6 +:10594000B201B60100000000B66D966D9601B60179 +:1059500000000000B66DB26DB600B6010000000098 +:10596000012800000000000000000000000000000E +:10597000000000020206AA006C768A94000106006C +:1059800000000000DB0600000106000091016E200F +:10599000418C3903010000C61D018C61000000002C +:1059A0000000000010100D100390BBBB8E5A22188F +:1059B000641164118A39893985E00FE06612641236 +:1059C00001280000000000000000000000000000AE +:1059D000000000020206AA006C768A94000106000C +:1059E00000000000DB0600000106000091016E20AF +:1059F000418C3903010000C61D018C6100000000CC +:105A00000000000010000C100380ABAA8044227834 +:105A1000641164118A39893985E005E066126412DF +:105A20000104000000000000000000000000000071 +:105A3000000000020200AA006C768A9400010600B1 +:105A400000000000DB060000040C000038066E2099 +:105A5000418C390301000084C4058C610000000002 +:105A60000000000010C40C500390BBBB804422789F +:105A7000641164118A39893985E00FE06612641275 +:105A8000D004020001020304CCF57AFDED20BF8FA3 +:105A9000CF0304021E0600036C768A940001060000 +:105AA00000000000DB06000001460000121B002081 +:105AB000006B39034100028400006B616478792B2C +:105AC000CF8A00801C5411980080BBBB00572278FD +:105AD000641164118A39893985E00FE06612641215 +:105AE0000100000001010101CCF57AFDED20BF8F1E +:105AF000CF030402020600006C768A9400010600BF +:105B000000000000DB060000000C0000401A00202E +:105B10004100380341000284000000606478792B62 +:105B2000CF8A00801C5410180380BBBB80462278AB +:105B3000641164118A39893985E00FE066126412B4 +:105B4000D004020002020202CCF57AFDED20BF8FE4 +:105B5000CF030402020600006C768A94000106005E +:105B600000000000DB06000001460000121B0020C0 +:105B7000006B39034100028400006B616478792B6B +:105B8000CF8A00801C5411980380BBBB80462278CA +:105B9000641164118A39893985E00FE06612641254 +:105BA0000100000003030303CCF57AFDED20BF8F55 +:105BB000CF030402020600006C768A9400010600FE +:105BC00000000000DB060000000C0000401A00206E +:105BD0004100380341000284000000606478792BA2 +:105BE000CF8A00801C5410180380BBBB80462278EB +:105BF000641164118A39893985E00FE066126412F4 +:105C0000D004020004040404CCF57AFDED20BF8F1B +:105C1000CF030402020600006C768A94000106009D +:105C200000000000DB06000001460000121B0020FF +:105C3000006B39034100028400006B616478792BAA +:105C4000CF8A00801C5411980380BBBB8046227809 +:105C5000641164118A39893985E00FE06612641293 +:105C60000100000000000000CCF57AFDED20BF8FA0 +:105C7000CF030402020600006C768A94000106003D +:105C800000000000DB060000000C0000FF3B0020CD +:105C90004100380341000284000000606478792BE1 +:105CA000CF8A00801CC410180300000000C62278B0 +:105CB000641164118039803905000F0055105510AA +:105CC000000000000000000000101000000092CD55 +:105CD0000000C180100F0002000087370000BBF1F8 +:105CE000100F00040000904100008B43100E0007CD +:105CF0000000BBF100009167100C000900001DFBC3 +:105D00000000709E100E000500000000C806000094 +:105D1000BAF15942BAF15942450EA63D1122334417 +:105D20005566778899AABBCCDDEEFF6900000000BC +:105D30000000000000000000000000000000000063 +:105D40000000000000000000C022C0224A4948476D +:105D5000464544434241403F3E3D3C3B3A3938375B +:105D6000363534333231302F2E2D2C2B2A2928274B +:105D7000262524232221201F1E1D1C1B1A1900006A +:105D80000000000000000000000000000000000013 +:105D90000000000031302F2E2D2C2B2A29282726F9 +:105DA0002524232221201F1E1D1C1B1A191817161B +:105DB0001514131211100F0E0D0C0B0A090807060B +:105DC00005040302010000000000000000000000C4 +:105DD0000000000000000000000000000020406003 +:105DE00080A0C0E00020406080A0C0E000204060B3 +:105DF00080A0C0E00020406080A0C0E000204060A3 +:105E000080A0C0E00020406080A0C0E00020000032 +:105E1000000000094992481292B46D1B1B4992245C +:105E20006DDBB6362000E0C0A08060402000E0C0FE +:105E3000A08060402000E0C0A08060402000E0C062 +:105E4000A08060402000E0C0A08060402000E0C052 +:105E5000A08060402000000076DBB62D2449921B14 +:105E6000DBB649129294240909000000533517F952 +:105E7000DBBD9F8163452709EBCDAF917355371982 +:105E8000FBDDBFA1836547290BEDCFB19375573972 +:105E90001BFDDFC1A38567492B0D8E7052340000B6 +:105EA0006D499224E4B66D1B9224490A499204007C +:105EB0000000B42D2002836547290BEDCFB1937507 +:105EC00057391BFDDFC1A38567492B0DEFD1B39572 +:105ED00077593B1DFFE1C3A587694B2D0FF1D3B562 +:105EE00097795B3D1F01000040DB962424C96D1BA0 +:105EF000DB264912529224090100000016F8DABC90 +:105F00009E8062442608EACCAE9072543618FADCC1 +:105F1000BEA0826446280AECCEB0927456381AFCB1 +:105F2000DEC0A28466482A0C8D6F513315F700003D +:105F300025499224DBB66D129224290949120000EA +:105F400000D0B6255D3F21038466482A0CEED0B20E +:105F50009476583A1CFEE0C2A486684A2C0EF0D211 +:105F6000B496785A3C1E00E2C4A6886A4C2E10F201 +:105F7000D4B6987A5C3E000000D0B6252449721B46 +:105F8000DBB6491292A4240949000000D9BB9D7FC9 +:105F900061432507E9CBAD8F71533517F9DBBD9F01 +:105FA0008163452709EBCDAF9173553719FBDDBFF1 +:105FB000A1836547290B8C6E503214F6D8BA0000C5 +:105FC0002449921BDBB6491292A42409490000001F +:105FD00040DB96249A7C5E4022048567492B0DEFB6 +:105FE000D1B39577593B1DFFE1C3A587694B2D0FB1 +:105FF000F1D3B597795B3D1F01E3C5A7896B4D2FA1 +:1060000011F3D5B7997B00000000B42D2549921CEF +:10601000DBB66D1292242909491200009C7E604271 +:106020002406E8CAAC8E70523416F8DABC9E806240 +:10603000442608EACCAE9072543618FADCBEA08230 +:106040006446280A8B6D4F3113F5D7B99B7D00004C +:1060500024496E1BDB26491292922409010000009C +:106060006D5B9224D7B99B7D5F41230586684A2CDE +:106070000EF0D2B496785A3C1E00E2C4A6886A4C50 +:106080002E10F2D4B6987A5C3E2002E4C6A88A6C40 +:106090004E3012F4D6B800000000002D6D49922455 +:1060A000E4B66D1B9224490A499204005F4123051E +:1060B000E7C9AB8D6F513315F7D9BB9D7F61432580 +:1060C00007E9CBAD8F71533517F9DBBD9F81634570 +:1060D00027098A6C4E3012F4D6B89A7C5E400000D4 +:1060E00024B96D1B9B2449124A9224010000002D03 +:1060F0006D49922414F6D8BA9C7E604224068769C2 +:106100004B2D0FF1D3B597795B3D1F01E3C5A789EF +:106110006B4D2F11F3D5B7997B5D3F2103E5C7A9DF +:106120008B6D4F3113F50000010000006D5B922470 +:1061300024B96D1B9B2449124A9224012204E6C80B +:10614000AA8C6E503214F6D8BA9C7E60422406E8BF +:10615000CAAC8E70523416F8DABC9E8062442608AF +:10616000FFFFFFFFFFFFFFFFFFFFFFFF2103000017 +:10617000E4B66D1B9224490A499204000000FC3FDA +:10618000FFFFFF24513315F7D9BB9D7F61432507DE +:10619000886A4C2E10F2D4B6987A5C3E2002E4C68F +:1061A000A88A6C4E3012F4D6B89A7C5E402204E67F +:1061B000C8AA8C6E503200004900000040DB9624D3 +:1061C00024496E1BDB26491292922409E5C7A98B4C +:1061D0006D4F3113F5D7B99B7D5F412305E7C9ABFF +:1061E0008D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:1061F000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000AD +:10620000DBB66D1292242909C9FFFF3FFFFFFF3F54 +:10621000FFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFF4E +:10622000FFFF896B4D2F11F3D5B7997B5D3FFFFFC2 +:10623000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:10624000FFFFFFFFFFFF0000FFFFFF3FFFDFB6255F +:106250002449FE3FFFFFFF3FFFFFFF3F5F5E5D5CA6 +:106260005B5A595857565554535251504F4E4D4CF6 +:106270004B4A494847464544434241403F3E3D3CE6 +:106280003B3A39383736353433323130FFFF00008E +:1062900000000000000000000000000000000000FE +:1062A0000000003F2F2E2D2C2B2A292827262524BD +:1062B000232221201F1E1D1C1B1A19181716151426 +:1062C000131211100F0E0D0C0B0A09080706050416 +:1062D00003020100FFFF00000000000000000000BA +:1062E00000000000000000000000003F000000006F +:1062F000000000000000000000000000000000009E +:10630000000000000000000000000000000000008D +:10631000000000000000000000000000000000007D +:10632000000000000000000000000000000000006D +:10633000000000000000000000000000000000005D +:10634000000000000000000000000000000000004D +:10635000000000000000000000000000000000003D +:10636000000000000000000000000000000000002D +:10637000000000000000000000000000000000001D +:10638000000000000000000000000000000000000D +:1063900000000000000000000000000000000000FD +:1063A00000000000000000000000000000000000ED +:1063B00000000000000000000000000000000000DD +:1063C00000000000000000000000000000000000CD +:1063D00000000000000000000000000000000000BD +:1063E00000000000000000000000000000000000AD +:1063F000000000000000000000000000000000009D +:10640000000000000000000000000000000000008C +:10641000000000000000000000000000000000007C +:10642000000000000000000000000000000000006C +:10643000000000000000000000000000000000005C +:10644000000000000000000000000000000000004C +:10645000000000000000000000000000000000003C +:10646000000000000000000000000000000000002C +:10647000000000000000000000000000000000001C +:10648000000000000000000000000000000000000C +:1064900000000000000000000000000000000000FC +:1064A00000000000000000000000000000000000EC +:1064B00000000000000000000000000000000000DC +:1064C00000000000000000000000000000000000CC +:1064D00000000000000000000000000000000000BC +:1064E00000000000000000000000000000000000AC +:1064F000000000000000000000000000000000009C +:10650000000000000000000000000000000000008B +:10651000000000000000000000000000000000007B +:10652000000000000000000000000000000000006B +:10653000000000000000000000000000000000005B +:10654000000000000000000000000000000000004B +:10655000000000000000000000000000000000003B +:10656000000000000000000000000000000000002B +:10657000000000000000000000000000000000001B +:10658000000000000000000000000000000000000B +:1065900000000000000000000000000000000000FB +:1065A00000000000000000000000000000000000EB +:1065B00000000000000000000000000000000000DB +:1065C00000000000000000000000000000000000CB +:1065D00000000000000000000000000000000000BB +:1065E00000000000000000000000000000000000AB +:1065F000000000000000000000000000000000009B +:10660000000000000000000000000000000000008A +:10661000000000000000000000000000000000007A +:10662000000000000000000000000000000000006A +:10663000000000000000000000000000000000005A +:10664000000000000000000000000000000000004A +:10665000000000000000000000000000000000003A +:10666000000000000000000000000000000000002A +:10667000000000000000000000000000000000001A +:10668000000000000000000000000000000000000A +:1066900000000000000000000000000000000000FA +:1066A00000000000000000000000000000000000EA +:1066B00000000000000000000000000000000000DA +:1066C00000000000000000000000000000000000CA +:1066D00000000000000000000000000000000000BA +:1066E00000000000000000000000000000000000AA +:1066F000000000000000000000000000000000009A +:106700000000000000000000000000000000000089 +:106710000000000000000000000000000000000079 +:106720000000000000000000000000000000000069 +:106730000000000000000000000000000000000059 +:106740000000000000000000000000000000000049 +:106750000000000000000000000000000000000039 +:106760000000000000000000000000000000000029 +:106770000000000000000000000000000000000019 +:106780000000000000000000000000000000000009 +:1067900000000000000000000000000000000000F9 +:1067A00000000000000000000000000000000000E9 +:1067B00000000000000000000000000000000000D9 +:1067C00000000000000000000000000000000000C9 +:1067D00000000000000000000000000000000000B9 +:1067E00000000000000000000000000000000000A9 +:1067F0000000000000000000000000000000000099 +:106800000000000000000000000000000000000088 +:106810000000000000000000000000000000000078 +:106820000000000000000000000000000000000068 +:106830000000000000000000000000000000000058 +:106840000000000000000000000000000000000048 +:106850000000000000000000000000000000000038 +:106860000000000000000000000000000000000028 +:106870000000000000000000000000000000000018 +:106880000000000000000000000000000000000008 +:1068900000000000000000000000000000000000F8 +:1068A00000000000000000000000000000000000E8 +:1068B00000000000000000000000000000000000D8 +:1068C00000000000000000000000000000000000C8 +:1068D00000000000000000000000000000000000B8 +:1068E00000000000000000000000000000000000A8 +:1068F0000000000000000000000000000000000098 +:106900000000000000000000000000000000000087 +:106910000000000000000000000000000000000077 +:106920000000000000000000000000000000000067 +:106930000000000000000000000000000000000057 +:106940000000000000000000000000000000000047 +:106950000000000000000000000000000000000037 +:106960000000000000000000000000000000000027 +:106970000000000000000000000000000000000017 +:106980000000000000000000000000000000000007 +:1069900000000000000000000000000000000000F7 +:1069A00000000000000000000000000000000000E7 +:1069B00000000000000000000000000000000000D7 +:1069C00000000000000000000000000000000000C7 +:1069D00000000000000000000000000000000000B7 +:1069E00000000000000000000000000000000000A7 +:1069F0000000000000000000000000000000000097 +:106A0000150101000000000000000000320210002B +:106A10001000000000000000000000000000000066 +:106A200099120000BC120000DF12000002130000E7 +:106A300025130000481300006B1300008E130000A4 +:106A4000B1130000D4130000F71300001A14000063 +:106A50003D1400006014000083140000A614000020 +:106A6000C914000020030000D4B804020351180028 +:106A700007B28C2363200C0485011C080000000071 +:106A800000000000190000005B555555555555553F +:106A90005555555505000000080A000010000A0071 +:106AA000000000010000000002E00000EC14541699 +:106AB00084167E17411AA2176A199119B1197E1707 +:106AC00007B8C307008000002083000000803280E8 +:106AD000648096802DB4040F110C0F0F10000F135B +:106AE000A5BA830A18C80F001510151010431043DB +:106AF00020030000D4A8040C42330E0EC4338E23AE +:106B000063011911E32101132302000000000000BA +:106B10001B0000005B555555555555555555555558 +:106B20005505000098090B0BB0B00000B0B0001B79 +:106B30000B00000082F01002EC14541684167E172D +:106B4000411AA2176A199119B1197E1707B8C3071C +:106B500000800000208300000080328064809680E6 +:106B60002DB4040F110C0F0F10000F13A5BA830AD8 +:106B700018C80F0015101510104310432003000013 +:106B800009000000000000000000000000000000FC +:106B900000000000000000000000000001000000F4 +:106BA00003000000000000000000000000000000E2 +:106BB00002000000000000000000000000000000D3 +:106BC00000000000EC14541684167E17411AA21718 +:106BD0006A199119B1197E1707B8C3070080000020 +:106BE0002083000000803280648096802DB4040FE2 +:106BF000110C0F0F10000F13A5BA830A18C80F004D +:106C0000151015101043104320030000D4B80402DF +:106C10000351180007B28C2363200C0485011C0863 +:106C20000000000000000000190000005B555555F1 +:106C3000555555555555555555000000086A666619 +:106C400036666A66666666636600000002E00000FB +:106C5000EC14541684167E17411AA2176A1991195A +:106C6000B1197E1707B8C307008000002083000019 +:106C700000803280648096802DB4040F110C0F0FB9 +:106C800010000F13A5BA830A18C80F0015101510AD +:106C90001043104320030000D4A8040C42330E0E0E +:106CA000C4338E2363011911E32101132302000071 +:106CB000000000001B0000005B555555555555550B +:106CC000555555555505000098696B6BB6B6666607 +:106CD000B6B6663B6B06000082F01002EC14541648 +:106CE00084167E17411AA2176A199119B1197E17D5 +:106CF00007B8C307008000002083000000803280B6 +:106D0000648096802DB4040F110C0F0F10000F1328 +:106D1000A5BA830A18C80F001510151010431043A8 +:106D200020030000D4B8541617960100000000009C +:106D30000000000000000000000000000000000053 +:106D4000080000005B5555550000000000000000E1 +:106D500000000000081A11110000000000000000EF +:106D60000000000002000000EC14541684167E1788 +:106D7000411AA2176A199119B1197E1707B8C307EA +:106D800000800000208300000080328064809680B4 +:106D90002DB4040F110C0F0F10000F13A5BA830AA6 +:106DA00018C80F00151015101043104320030000E1 +:106DB000D4B854161796010000000000000000002F +:106DC00000000000000000000000000008000000BB +:106DD0005B55555500000000000000000000000059 +:106DE000083A3333000000000000000000000000FB +:106DF00002000000EC14541684167E17411AA217E4 +:106E00006A199119B1197E1707B8C30700800000ED +:106E10002083000000803280648096802DB4040FAF +:106E2000110C0F0F10000F13A5BA830A18C80F001A +:106E3000151015101043104320030000D4A8540C63 +:106E4000567339184F068D11A3344E000000000010 +:106E50000000000000000000130000005B555555C5 +:106E600055555555550500000000000008191B1B1D +:106E70001B1B0B0B0B0B00000000000002A002000C +:106E8000EC14541684167E17411AA2176A19911928 +:106E9000B1197E1707B8C3070080000020830000E7 +:106EA00000803280648096802DB4040F110C0F0F87 +:106EB00010000F13A5BA830A18C80F00151015107B +:106EC0001043104320030000D4A8540C5673391803 +:106ED0004F068D11A3344E0000000000000000009A +:106EE00000000000130000005B55555555555555E1 +:106EF000550500000000000008393B3B3B3B0B0BF5 +:106F00000B0B00000000000002A00200EC1454165D +:106F100084167E17411AA2176A199119B1197E17A2 +:106F200007B8C30700800000208300000080328083 +:106F3000648096802DB4040F110C0F0F10000F13F6 +:106F4000A5BA830A18C80F00151015101043104376 +:106F500020030000D4A8051B023774045E311A23F5 +:106F6000C7088C08000000000000000000000000BE +:106F7000140000005B5555555555555555550000A5 +:106F800000000000080909090909000010000000BC +:106F90000000000002500500EC14541684167E1701 +:106FA000411AA2176A199119B1197E1707B8C307B8 +:106FB0000080000020830000008032806480968082 +:106FC0002DB4040F110C0F0F10000F13A5BA830A74 +:106FD00018C80F00151015101043104320030000AF +:106FE000D4A8051B023774045E311A23C7088C0825 +:106FF000000000000000000000000000140000007D +:107000005B55555555555555555500000000000028 +:10701000086969696969606030600000000000000B +:1070200002500500EC14541684167E17411AA2175C +:107030006A199119B1197E1707B8C30700800000BB +:107040002083000000803280648096802DB4040F7D +:10705000110C0F0F10000F13A5BA830A18C80F00E8 +:10706000151015101043104320030000D4A8551B21 +:10707000167775185E060000000000000000000092 +:1070800000000000000000000C0000005B5555559A +:1070900055550000000000000000000008191919F3 +:1070A00019190000000000000000000002000000AC +:1070B000EC14541684167E17411AA2176A199119F6 +:1070C000B1197E1707B8C3070080000020830000B5 +:1070D00000803280648096802DB4040F110C0F0F55 +:1070E00010000F13A5BA830A18C80F001510151049 +:1070F0001043104320030000D4A8551B16777518C1 +:107100005E0600000000000000000000000000001B +:10711000000000000C0000005B555555555500005F +:10712000000000000000000008393939393900003A +:10713000000000000000000002000000EC145416E3 +:1071400084167E17411AA2176A199119B1197E1770 +:1071500007B8C30700800000208300000080328051 +:10716000648096802DB4040F110C0F0F10000F13C4 +:10717000A5BA830A18C80F00151015101043104344 +:1071800020030000E3180803446100070800000022 +:1071900000000000000000000000000000000000EF +:1071A0000B00000055555555550500000000000026 +:1071B00000000000000000000100000000000000CE +:1071C0000000000003000000EC14541684167E1723 +:1071D000411AA2176A199119B1197E1707B8C30786 +:1071E0000080000020830000008032806480968050 +:1071F0002DB4040F110C0F0F10000F13A5BA830A42 +:1072000018C80F001510151010431043200300007C +:10721000D4B80000000000000000000000000000E2 +:10722000000000000000000000000000030000005B +:107230005B050000000000000000000000000000EE +:10724000080A00000000000000000000000000002C +:1072500002000000EC14541684167E17411AA2177F +:107260006A199119B1197E1707B8C3070080000089 +:107270002083000000803280648096802DB4040F4B +:10728000110C0F0F10000F13A5BA830A18C80F00B6 +:1072900015101510104310432003000009050000CD +:1072A00000000000C002000000000000000000001C +:1072B0000000000000000000020000006466666636 +:1072C0006666000000000000000000008200000070 +:1072D00000A000000000000000000000FC0700000B +:1072E000EC14541684167E17411AA2176A199119C4 +:1072F000B1197E1707B8C307008000002083000083 +:1073000000803280648096802DB4040F110C0F0F22 +:1073100010000F13A5BA830A18C80F001510151016 +:107320001043104320030000813010050670200038 +:10733000000000000000000000000000000000004D +:1073400000000000090000005555555505000000DB +:10735000000000000000000000000001000000002C +:10736000000000000000000000000000EC145416B3 +:1073700084167E17411AA2176A199119B1197E173E +:1073800007B8C3070080000020830000008032801F +:10739000648096802DB4040F110C0F0F10000F1392 +:1073A000A5BA830A18C80F00151015101043104312 +:1073B0000000000000000001000003000000FC00CD +:1073C000000000000D000D0008072107000000006C +:1073D0000155B4000200000000000000010103029A +:1073E000000001000000FC00000000000D000D0086 +:1073F00010001F000000000004B0B30000000010E7 +:107400000000000002020302000001000000FC0076 +:10741000000000000D000D0011001E000000000023 +:1074200004C4B300000000100000000003030302C6 +:10743000000001000000FC00000000000D000D0035 +:1074400012001D000000000004D8B300000000106E +:107450000000000004040302000001000000FC0022 +:10746000000000000D000D0013001C0000000000D3 +:1074700004ECB3000000001000000000050503024A +:10748000000001000000FC00000000000D000D00E5 +:1074900014001B00000000000400B40000000010F5 +:1074A0000000000006060302000001000000FC00CE +:1074B000000000000D000D0015001A000000000083 +:1074C0000414B400000000100000000007070302CD +:1074D000000001000000FC00000000000D000D0095 +:1074E00016001900000000000428B400000000107D +:1074F0000000000008080302000005000000FC0076 +:10750000000000000D000D00170018000000000032 +:10751000043CB4000000001000000000090000015D +:10752000000007000000FC00000000000D000D003E +:1075300004101D10000000000150B4000000000005 +:107540000000000000000001000003000000FC003B +:10755000000000000D000D008917701700000000EA +:1075600001A0B40006000000000000000000171792 +:10757000000003000000FC00000000000D000D00F2 +:107580009C189D1800000000019BB400040000003E +:107590000000000000001616010003000000FD00BE +:1075A000000000000D000D00301138110000FE2514 +:1075B0000473B4000400000000000000000017176E +:1075C000020003000000FC00000000000D000D00A0 +:1075D000C012C1120000FE250487B40004000000A0 +:1075E0000000000000001616030003000000FD006C +:1075F000000000000D000D00301138110000FE25C4 +:107600000473B4000400000000000000000017171D +:10761000040003000000FC00000000000D000D004D +:10762000C012C1120000FE250487B400040000004F +:107630000000000000001616050003000000FD0019 +:10764000000000000D000D00301138110000FE2573 +:107650000473B400040000000000000000001717CD +:10766000060003000000FC00000000000D000D00FB +:10767000C012C1120000FE250487B40004000000FF +:107680000000000000001616070003000000FD00C7 +:10769000000000000D000D00301138110000FE2523 +:1076A0000473B4000400000000000000000017177D +:1076B000080003000000FC00000000000D000D00A9 +:1076C000C012C1120000FE250487B40004000000AF +:1076D00000000000000A1414092802000000FC0049 +:1076E0000000000005000500000000000000000090 +:1076F00001009703000000000000000000000001EE +:10770000000003000000FC00000000000D000D0060 +:10771000C800E10000000000015AB40002000000AF +:107720000000000000000001000003000000FC0059 +:10773000000000000D000D00580271020000000062 +:10774000015FB40002000000000000000000000122 +:10775000000003000000FC00000000000D000D0010 +:10776000E8030104000000000164B400020000000E +:107770000000000000000001000003000000FC0009 +:10778000000000000D000D007805910500000000CC +:107790000169B400020000000000000000000001C8 +:1077A000000003000000FC00000000000D000D00C0 +:1077B0000807210700000000016EB400020000006D +:1077C0000000000000000100000003000000FC00B9 +:1077D000000000000D000D003011491100000000F4 +:1077E00001A5B40006000000000000000000010038 +:1077F000000003000000FC00000000000D000D0070 +:10780000C012D9120000000001AAB4000600000056 +:107810000000000000000100000003000000FC0068 +:10782000000000000D000D0050146914000000005D +:1078300001AFB400060000000000000000000100DD +:10784000000003000000FC00000000000D000D001F +:10785000E015F9150000000001B4B40006000000B6 +:107860000000000000000100000003000000FC0018 +:10787000000000000D000D007017891700000000C7 +:1078800001B9B40006000000000000000000010083 +:10789000002802000000FC000000000009000900B0 +:1078A0000000000000000000010097030600000037 +:1078B00000000000000B1414002802000000FC006F +:1078C000000000000C000C000000000000000000A0 +:1078D000010097030000000000000000000B1414DA +:1078E000002802000000FC003F0000000C000C001B +:1078F00000000000000000000100970300000000ED +:1079000000000000000B1515002802000000CC004C +:10791000000000000C000C0000000000000000004F +:1079200001009703000000000000000000000100BB +:10793000002802000000FC00000000000D000D0007 +:107940000000000000000000010097030600000096 +:107950004F00000001F4040068931B006000000069 +:107960000C0000000100040014280000600000006A +:10797000300000002D008400142800001C000000CE +:10798000730000002DF4840068931B001C000000AD +:10799000700000002DF4840068931B001C000000A0 +:1079A0007300000023F4840068931B001C00000097 +:1079B0006000000050F4840094EB1B001C000000E9 +:1079C0004F00000001F4040068931B00E000010078 +:1079D0000C0000000100040014280000E000010079 +:1079E000300000002D008400142800001C0000005E +:1079F000700000002DF4840068931B001C00000040 +:107A0000730000002DF4840051651B001C00000071 +:107A10000101010101010101010101010101010156 +:107A20000101010101010101010101010101010146 +:107A30000101010101010101010101010101010136 +:107A40000101010101010101010101010101010126 +:107A50000101010101010101010101010101010116 +:107A60000101010101010101010101010101010106 +:107A7000010101012B2B2B2D2C2B2C2D2B2C2D2DF3 +:107A80002C2D2D2D2B2B2D2D2B2D2C2F2C2D2D2D2D +:107A90002C2B2D2E2D2C2D2D2C2C2E2D2D2C2F2D19 +:107AA0002C2D2D2E2D2C2D2E2D2C2D2E2D2D2E2E04 +:107AB0002C2D2E2E2C2C2F2E2C2D2E2F2D2C2E2EF1 +:107AC0002D2C2E2E2E2D2D2F2C2D2F2E2D2D2F2FDC +:107AD0002D2F2D312B2A2B2B2B2B2B2C2B2B2B2CE7 +:107AE0002B2C2D2C2C2D2D2C2B2B2D2D2B2D2C2ED2 +:107AF0002C2D2D2D2C2B2D2D2D2C2D2D2C2C2E2DBC +:107B00002D2C2F2D2C2D2D2E2C2C2D2D2D2C2D2EA6 +:107B10002D2D2E2E2D2D2E2E2C2C2E2D2C2D2E2F90 +:107B20002D2C2D2E2D2C2E2E2E2D2D2F2C2D2F2E7F +:107B30002D2D2E2F2D2E2D302A2A2A2B2B2B2B2C80 +:107B40002B2B2B2C2A2B2D2C2B2D2D2C2B2B2D2D79 +:107B50002B2D2C2E2C2C2D2D2C2B2D2D2D2C2D2D5D +:107B60002C2C2E2D2D2C2F2D2C2D2D2E2C2C2C2D48 +:107B70002D2B2D2E2D2D2E2D2C2D2D2E2C2C2E2D36 +:107B80002C2D2E2F2D2C2D2E2D2C2D2E2D2D2D2F21 +:107B90002C2D2F2E2D2D2E2F2D2E2D2F2A2A2A2B18 +:107BA0002B2B2B2C2B2B2B2C2A2B2D2C2B2D2C2C1D +:107BB0002B2B2D2D2B2D2C2E2C2C2D2C2C2B2D2D01 +:107BC0002D2C2D2D2C2C2E2D2D2C2F2D2C2D2D2EE6 +:107BD0002C2C2D2D2D2C2D2E2D2D2E2E2C2D2E2ED4 +:107BE0002C2C2E2D2C2D2E2F2D2C2D2E2D2C2E2EC3 +:107BF0002E2D2D2E2C2D2F2E2D2D2E2F2D2E2D2FAB +:107C00002A2A2A2B2B2B2B2C2B2B2B2C2A2B2C2CC4 +:107C10002B2D2C2C2B2B2D2D2B2D2C2E2C2C2D2CA1 +:107C20002C2B2D2D2D2C2D2D2C2C2E2D2D2C2F2C89 +:107C30002B2D2D2E2C2C2C2D2D2B2D2E2D2D2E2D78 +:107C40002C2D2D2E2C2C2E2D2C2D2E2E2D2C2D2E64 +:107C50002D2C2E2E2D2D2D2E2C2D2F2E2D2D2E2F4D +:107C60002D2E2D2F2A2A2A2B2B2B2B2C2B2B2B2C5A +:107C70002A2B2D2C2B2D2C2C2B2B2D2D2B2D2C2E44 +:107C80002C2C2D2C2C2B2D2D2D2C2D2D2C2C2E2D2C +:107C90002D2C2F2D2C2D2D2E2C2C2C2D2D2C2D2E16 +:107CA0002D2D2E2D2C2D2E2E2C2C2E2D2C2D2E2E02 +:107CB0002D2C2D2E2D2C2E2E2D2D2D2F2C2D2F2EEF +:107CC0002D2D2E2F2D2E2D2F2A2A2A2B2B2B2B2CF0 +:107CD0002B2B2B2C2A2B2D2C2B2D2C2C2B2B2D2DE9 +:107CE0002B2D2C2E2C2C2D2C2C2B2D2D2D2C2D2DCD +:107CF0002C2C2E2D2D2C2F2C2C2D2D2E2C2C2C2DB8 +:107D00002D2B2D2E2D2D2E2E2C2D2D2E2C2C2E2DA3 +:107D10002C2D2E2E2D2C2D2E2D2C2D2E2D2D2D2E91 +:107D20002C2D2F2E2D2D2E2F2D2E2D2F2A2A2A2B86 +:107D30002B2B2B2C2B2B2B2C2B2C2D2C2C2D2C2C88 +:107D40002B2B2D2D2B2D2C2E2C2D2D2C2C2B2D2D6E +:107D50002D2C2D2D2C2C2E2D2D2C2F2C2C2D2D2E55 +:107D60002C2C2C2D2D2C2D2E2D2D2E2E2C2D2E2E43 +:107D70002C2C2E2E2C2D2E2F2D2C2D2E2D2C2E2E30 +:107D80002E2D2D2F2C2D2F2E2D2D2E2F2D2E2D3017 +:107D90002A2A2B2B4D4D4D4D4D4D4D4D4D4D4D4D9D +:107DA0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D03 +:107DB0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4DF3 +:107DC0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4DE3 +:107DD0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4DD3 +:107DE0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4DC3 +:107DF0004D4D4D4D4D4D4D4D92249224920092008B +:107E000000000000B66DB66DB600B60000000000C0 +:107E1000B66DB66D9601960100000000B66DB66DA8 +:107E2000B201B20100000000B62DB62DB601B601B8 +:107E300000000000B665B665B601B601000000009E +:107E4000B66CB66CB601B60100000000966D966D7A +:107E5000B601B60100000000B26DB26DB601B60108 +:107E600000000000FF7FFF7FFF01FF010000000016 +:107E7000B66DB66DB601B6010000000092249224E2 +:107E800092009200000000000110000000000000BD +:107E900000000000FFFF3DDB38D4FC020200AA0016 +:107EA0006C768A940001060000000000DB060000EA +:107EB000040C000060056E40415639030100009A31 +:107EC000EC045661000000000000000010C40C50DB +:107ED0000390BBBB804422786411641189398939CD +:107EE0000FE00FE0641264120110000000000000B7 +:107EF00000000000FFFF3DDB38D4FC020200AA00B6 +:107F00006C768A940001060000000000DB06000089 +:107F1000040C000060056E40415639030100009AD0 +:107F2000EC045661000000000000000010C40C10BA +:107F3000E39EBBBB8055227864116411893989396D +:107F40000FE00FE064126412010400000000000062 +:107F50000000000000000000000000020200AA0073 +:107F60006C768A940001060000000000DB06000029 +:107F7000040C000020066E40418639030100009A7F +:107F8000AC058661000000000000000010C40C5029 +:107F90000390BBBB8044227864116411893989390C +:107FA0000FE00FE064126412C9040200010203042E +:107FB000EAF7FAFD3001A880CF0304021E00000397 +:107FC0006C768A940001060000000000DB060000C9 +:107FD000014600002B1A0040006B39034100029A51 +:107FE00000006B616478792BCF8A00801C54119853 +:107FF0000080BBBB0057227864116411893989392C +:108000000FF00FF064126412C904020001010101B3 +:10801000EAF7FAFD3001A880CF0304020200000055 +:108020006C768A940001060000000000DB06000068 +:10803000014600002B1A0040006B39034100029AF0 +:1080400000006B61BB7DFC17FFFF00801C54119882 +:108050000380BBBB80462278641164118939893959 +:108060000FF00FF064126412C9040200020202024F +:10807000EAF7FAFD3001A880CF03040202000000F5 +:108080006C768A940001060000000000DB06000008 +:10809000014600002B1A0040006B39034100029A90 +:1080A00000006B610F7E3416FFFF00801C54119896 +:1080B0000380BBBB804622786411641189398939F9 +:1080C0000FF00FF064126412C904020003030303EB +:1080D000EAF7FAFD3001A880CF0304020200000095 +:1080E0006C768A940001060000000000DB060000A8 +:1080F000014600002B1A0040006B39034100029A30 +:1081000000006B61B17E3C12FFFF00801C5411988F +:108110000380BBBB80462278641164118939893998 +:108120000FF00FF064126412C90402000404040486 +:10813000EAF7FAFD3001A880CF0304020200000034 +:108140006C768A940001060000000000DB06000047 +:10815000014600002B1A0040006B39034100029ACF +:1081600000006B611C7F0B0FFFFF00801C541198F7 +:108170000380BBBB80462278641164118939893938 +:108180000FF00FF0641264120104000400000000FC +:10819000CCF57AFDED20BF8FCF030402020600006C +:1081A0006C768A940001060000000000DB060000E7 +:1081B00001060000093C0040006B39034100029AAF +:1081C00000006B616478792BCF8A00801CC4101882 +:1081D0000380AAAA00C6227864116411803980390C +:1081E0000F000F00550D550DC904020006070A0BBC +:1081F000EAF7FAFD3001A880CF0304021E0600034F +:108200006C768A940001060000000000DB06000086 +:10821000014600002B1A0040006B39034100029A0E +:1082200000006B616478792BCF8A00801C54119810 +:108230000080BBBB00572218641164118939893949 +:108240000FF00FF064126412C9040200060606065D +:10825000EAF7FAFD3001A880CF030402020600000D +:108260006C768A940001060000000000DB06000026 +:10827000014600002B1A0040006B39034100029AAE +:1082800000006B616478792BCF8A00801C541198B0 +:108290000080BBBB005722186411641189398939E9 +:1082A0000FF00FF064126412C904020006060A0AF5 +:1082B000EAF7FAFD3001A880CF0304020A060100A4 +:1082C0006C768A940043060100000000DB06000083 +:1082D000014600002B1A0040006B39034100029A4E +:1082E00000006B619367CBB40000008012541198BA +:1082F0000080BBBB0056221864116411893989398A +:108300000FF00FF064126412C904020007070B0B90 +:10831000EAF7FAFD3001A880CF0304020A06010043 +:108320006C768A940043060100000000DB06000022 +:10833000014600002B1A0040006B39034100029AED +:1083400000006B6155737BC80000008012541198C7 +:108350000080BBBB00562218641164118939893929 +:108360000FF00FF064126412C904020009090C0C2A +:10837000EAF7FAFD3001A880CF0304020A060100E3 +:108380006C768A940043060100000000DB060000C2 +:10839000014600002B1A0040006B39034100029A8D +:1083A00000006B61D9770ED3000000801254119841 +:1083B0000080BBBB005622186411641189398939C9 +:1083C0000FF00FF064126412C90402000A0A0606D4 +:1083D000EAF7FAFD3001A880CF0304020A06010083 +:1083E0006C768A940043060100000000DB06000062 +:1083F000014600002B1A0040006B39034100029A2D +:1084000000006B61BD7977D800000080125411988C +:108410000080BBBB00562218641164118939893968 +:108420000FF00FF064126412C90402000B0B07076F +:10843000EAF7FAFD3001A880CF0304020A06010022 +:108440006C768A940043060100000000DB06000001 +:10845000014600002B1A0040006B39034100029ACC +:1084600000006B61757B34DE0000008012541198AF +:108470000080BBBB00562218641164118939893908 +:108480000FF00FF064126412C90402000A0A060613 +:10849000EAF7FAFD3001A880CF0304020A060100C2 +:1084A0006C768A940043060100000000DB060000A1 +:1084B000014600002B1A0040006B39034100029A6C +:1084C00000006B61CB7C87E30000008012541198A0 +:1084D0000080BBBB005622186411641189398939A8 +:1084E0000FF00FF064126412C90402000B0B0707AF +:1084F000EAF7FAFD3001A880CF0304020A06010062 +:108500006C768A940043060100000000DB06000040 +:10851000014600002B1A0040006B39034100029A0B +:1085200000006B61F27D29E900000080125411986F +:108530000080BBBB00562218641164118939893947 +:108540000FF00FF064126412C90402000C0C090948 +:10855000EAF7FAFD3001A880CF0304020A06010001 +:108560006C768A940043060100000000DB060000E0 +:10857000014600002B1A0040006B39034100029AAB +:1085800000006B61D57EC2EE00000080125411988D +:108590000080BBBB005622186411641189398939E7 +:1085A0000FF00FF0641264120000000000000000E1 +:1085B00000101000FFFF56CE000099103F0E30064D +:1085C000FFFFFDF900006FA13F0E3005FFFF464F92 +:1085D000000029A63F0F3004FFFFAD8700007DD9C2 +:1085E0003F0F30030000C15A00009C9A0004103075 +:1085F0000000BCA00000903800091033000083D0B8 +:108600000000D635000B10350000C9C200001A5911 +:10861000000C103600008CA100002C9F000D1037BC +:1086200000009851000044DC000E10380000BEEA43 +:108630000000A536000E103A000026620000DD9909 +:10864000000F103B000000006400000070000000FC +:108650008900000098000000C9000000D700000059 +:10866000F1000000000100004000000000000000D8 +:1086700000000000000000000000000000000000FA +:1086800000000000000000000000000000000000EA +:1086900000000000000000000000000000000000DA +:1086A00000000000000000000000000000000000CA +:1086B00000000000000000000000000000000000BA +:1086C00000000000870700008579385793F930A132 +:1086D000B3D4CC2BCB0AF200000000000000000055 +:1086E000000000000000000000000000000000008A +:1086F000000000000000000000000000000000007A +:1087000080220022870700008579385793E4C2B998 +:1087100030AFCC2BC5A1B30000000000000000006A +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:1087400080220022870700008579385793E4C2BC55 +:10875000C2BCD7930D79300000000000000000007B +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800080220022870700008579385793E4C2BF12 +:10879000930ACC2BC4F50D0000000000000000007F +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00080220022870700008579385793E4C2BFD2 +:1087D000930AE4C2B286CF0000000000000000004F +:1087E0000000000000000000000000000000000089 +:1087F0000000000000000000000000000000000079 +:1088000080220022870700008579385793E4C2BF91 +:10881000930AB0AF26CF5000000000000000000017 +:108820000000000000000000000000000000000048 +:108830000000000000000000000000000000000038 +:1088400080220022870700008579385793E4C2BB55 +:108850000AF2E4C2BE4C2B00000000000000000041 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800080220022870700008579385793E4C2BB15 +:108890000AF2B0AF295E4C000000000000000000AA +:1088A00000000000000000000000000000000000C8 +:1088B00000000000000000000000000000000000B8 +:1088C00080220022C8060000450EA63D450EA63DAA +:1088D000BAF15942450EA63D450EA63D450EA63DB0 +:1088E000450EA63D00000000000000000000000052 +:1088F0000000000000000000000000000000000078 +:1089000080220022000102030405060708090A0B61 +:108910000C0D0E0F101112131415161718191A1B1F +:108920001C1D1E1F202122232425262728292A2B0F +:108930002C2D2E2F30310000000000000000000020 +:10894000000000000000000000000000191A1B1CBD +:108950001D1E1F202122232425262728292A2B2CCF +:108960002D2E2F303132333435363738393A3B3CBF +:108970003D3E3F404142434445464748494A000046 +:1089800000000000000000000000000000000000E7 +:10899000000000000020406080A0C0E00020406097 +:1089A00080A0C0E00020406080A0C0E000204060C7 +:1089B00080A0C0E00020406080A0C0E000204060B7 +:1089C00080A0C0E000200000000000094992481289 +:1089D00092B46D1B1B4992246DDBB63600204060BB +:1089E00080A0C0E00020406080A0C0E00020406087 +:1089F00080A0C0E00020406080A0C0E00020406077 +:108A000080A0C0E00020406080A0C0E00020000006 +:108A1000000000094992481292B46D1B1B49922430 +:108A20006DDBB6362021E0E1A0A160612021E0E10C +:108A3000A0A160612021E0E1A0A160612021E0E12E +:108A4000A0A160612021E0E1A0A160612021E0E11E +:108A5000A0A160612021000076DBB62D2449921B85 +:108A6000DBB6491292942409090000000100C1C03C +:108A7000818041400100C1C0818041400100C1C0EE +:108A8000818041400100C1C0818041400100C1C0DE +:108A9000818041400100C1C081804140010000004F +:108AA00076DBB62D2449921BDBB649129294240939 +:108AB000090000002120E1E0A1A061602120E1E0A7 +:108AC000A1A061602120E1E0A1A061602120E1E09E +:108AD000A1A061602120E1E0A1A061602120E1E08E +:108AE000A1A061602120000076DBB62D2449921BF5 +:108AF000DBB6491292942409090000007353331322 +:108B0000F2D2B29272523212F2D2B2927252321245 +:108B1000F2D2B29272523212F2D2B2927252321235 +:108B2000F2D2B29272523212F2D2B2927252000069 +:108B300000D0B62D2D499224DBB66D129224250962 +:108B4000490200003C1CFCDCBC9C7C5C3C1CFCDC4A +:108B5000BC9C7C5C3C1CFCDCBC9C7C5C3C1CFCDC55 +:108B6000BC9C7C5C3C1CFCDCBC9C7C5C3C1CFBDB47 +:108B7000BB9B7B5B3B1B00002D499224DBB66D1237 +:108B8000922425094902000040DBB62DB4947454A8 +:108B90003414F3D3B39373533313F3D3B3937353A3 +:108BA0003313F3D3B39373533313F3D3B393735395 +:108BB0003313F3D3B39373533313F3D3B39300004B +:108BC0000000B42D6D4B9224E4B66D1B922449092C +:108BD00049920000FBDBBB9B7B5B3B1BFBDBBB9B36 +:108BE0007B5B3B1BFBDBBB9B7B5B3B1BFBDBBB9BD5 +:108BF0007B5B3B1BFBDBBB9B7B5B3B1BFADABA9AC9 +:108C00007A5A3A1AFADA00002449921BDBB6491262 +:108C100092942409090000006DDBB624F5D5B595C2 +:108C200075553515F4D4B49474543414F4D4B49400 +:108C300074543414F4D4B49474543414F4D4B494F4 +:108C400074543414F4D4B49474543414F4D400002C +:108C50000000002D6DDB922424B96D1B9B2449126A +:108C600049922400BA9A7A5A3A1AFADABA9A7A5A8D +:108C70003A1AFADABA9A7A5A3A1AFADABA9A7A5A54 +:108C80003A1AFADABA9A7A5A3A1AF9D9B99979594A +:108C90003919F9D9B999000024496E1BDB2649120C +:108CA000529224090000002D6DDB92243616F6D670 +:108CB000B69676563616F5D5B59575553515F5D55E +:108CC000B59575553515F5D5B59575553515F5D554 +:108CD000B59575553515F5D5B5957555351500000E +:108CE000090000006DDBB62424496E1BDB26491207 +:108CF0005292240979593919F9D9B99979593919F7 +:108D0000F9D9B99979593919F9D9B99979593919D3 +:108D1000F9D9B99979593919F8D8B89878583818CB +:108D2000F8D8B8987858000024B96D1B9B244912D4 +:108D3000499224000000B42D6D4B922477573717C9 +:108D4000F7D7B79777573717F6D6B69676563616BB +:108D5000F6D6B69676563616F6D6B69676563616B3 +:108D6000F6D6B69676563616F6D6B69676560000EF +:108D70004902000040DBB62D2449921BDBB64912A4 +:108D8000929424093818F8D8B89878583818F8D830 +:108D9000B89878583818F8D8B89878583818F8D853 +:108DA000B89878583818FFFFFFFFFFFFFFFFFFFF5D +:108DB000FFFFFFFFFFFF0000E4B66D1B922449098F +:108DC0004992000000F0FF3FFFFFFF3FFFFFFFFF62 +:108DD000FFFFFFFFFFFFFFFFFFFFF7D7B7977757B3 +:108DE0003717F7D7B79777573717F7D7B797775713 +:108DF0003717F7D7B79777573717F7D7B7970000D1 +:108E0000FFFFFF3FFFDFB62D2D499224DBB66D1229 +:108E100092242509636261605F5E5D5C5B5A59580C +:108E200057565554535251504F4E4D4C4B4A49484A +:108E300047464544434241403F3E3D3C3B3A39383A +:108E400037363534333200000000000000000000E7 +:108E500000000000000000000000000031302F2E54 +:108E60002D2C2B2A292827262524232221201F1EAA +:108E70001D1C1B1A191817161514131211100F0E9A +:108E80000D0C0B0A09080706050403020100000087 +:108E900000000000000000000000000000000000D2 +:108EA00000000000FFFFFFFFFFFFFFFFFFFFFFFFCE +:108EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:108EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:108ED000FFFFFFFFFFFF0000FFFFFF3FFFFFFF3F20 +:108EE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFFFFD2 +:108EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:108F0000FFFFFFFFFFFFFFFFFFFF0000000000006B +:108F10000000000000000000000000000000000051 +:108F2000FFFFFF3FFFFFFF3FFFFFFF3F000000008D +:108F30000000000007172737475706162636465603 +:108F4000051525354555041424344454031323339F +:108F50004353021222324252011121314151001079 +:108F600020304050FFFF0000000000000000000023 +:108F700000000000000000000000003F00020406A6 +:108F8000080A0C0E10121416181A1C1E2022242671 +:108F9000282A2C2E30323436383A3C3E4042444661 +:108FA000484A4C4E50525456585A5C5E606200001B +:108FB00000000000000000000000000000000000B1 +:108FC00000000000000000000000000000000000A1 +:108FD0000000000000000000000000000000000091 +:108FE0000000000000000000000000000000000081 +:108FF0000000000000000000000000000000000071 +:109000000000000000000000000000000000000060 +:109010000000000000000000000000000000000050 +:109020000000000000000000000000000000000040 +:109030000000000000000000000000000000000030 +:109040000000000000000000000000000000000020 +:109050000000000000000000000000000000000010 +:109060000000000000000000000000000000000000 +:1090700000000000000000000000000000000000F0 +:1090800000000000000000000000000000000000E0 +:1090900000000000000000000000000000000000D0 +:1090A00000000000000000000000000000000000C0 +:1090B00000000000000000000000000000000000B0 +:1090C00000000000000000000000000000000000A0 +:1090D0000000000000000000000000000000000090 +:1090E0000000000000000000000000000000000080 +:1090F0000000000000000000000000000000000070 +:10910000000000000000000000000000000000005F +:10911000000000000000000000000000000000004F +:10912000000000000000000000000000000000003F +:10913000000000000000000000000000000000002F +:10914000000000000000000000000000000000001F +:10915000000000000000000000000000000000000F +:1091600000000000000000000000000000000000FF +:1091700000000000000000000000000000000000EF +:1091800000000000000000000000000000000000DF +:1091900000000000000000000000000000000000CF +:1091A00000000000000000000000000000000000BF +:1091B00000000000000000000000000000000000AF +:1091C000000000000000000000000000000000009F +:1091D000000000000000000000000000000000008F +:1091E000000000000000000000000000000000007F +:1091F000000000000000000000000000000000006F +:109200001501010000000000000000003202100003 +:109210001B00000000000000000000000000000033 +:109220008C1C0000AF1C0000D21C0000F51C0000CC +:10923000200300004110080344611C0800000000E6 +:10924000000000000000000000000000000000001E +:109250000A00000066666666560000000000000016 +:1092600000000000000000000000000000000000FE +:109270000000000003080000181DD61D061E1F1E5A +:10928000531F581E301F421F431F7E1707B8C307C6 +:10929000008000002083000000803280648096807F +:1092A0002DB4040F110C0F0F10000F1325BD830AEE +:1092B00018C80F00130E130E0E410E4120030000BC +:1092C000CBB2300DCE0345120000000000000000BC +:1092D0000000000000000000000000000A00000084 +:1092E0006666666656000000000000000000000090 +:1092F00011111111111111111111000000000000C4 +:1093000003080000181DD61D061E1F1E531F581EE1 +:10931000301F421F431FAE0B07B80F330080000001 +:109320002083000000803280648096802DB4040F7A +:10933000110C0F0F90000F13A5BA830A18C80F0065 +:10934000130E130E0E410E4145097E1707B8C307D1 +:109350000080008020F3000C00803280648096FE44 +:109360002DB4FFFF11FDFFFFD0FF0F13A5BA830A35 +:1093700018C80F00130F130F0F410F411F030000F8 +:1093800009000000000000000000000000000000D4 +:10939000189DD69D069E1F9E539F589E309F429FAC +:1093A000439F0000000000C000000000000000001B +:1093B00002000000000000000000000000000000AB +:1093C00000E60000EC0454E7E4077EE75509A20735 +:1093D0000A09250945097E1707B8C3070080000060 +:1093E0002083000000803280648096802DB4048F3A +:1093F00011FDFFFFD0FF0F93A5BA830A18E80FE015 +:10940000130F13FF0F410F411F030000D4B80402D4 +:109410000351188748F00C0C85011C08189DD69D37 +:10942000069E1F9E539F589E309F429F439F5555B7 +:10943000555555D55555000000000018086A666658 +:1094400066666666366600270000000002E6008059 +:10945000EC0C54EFE4877EE75509A2070AE925E9F9 +:109460000000000000000100002802000000FC00D5 +:10947000000000000D000D0059064006000000002D +:1094800001559701020000000000000000010202E7 +:10949000002800008002FC00FFFFFF010D000D000E +:1094A00017001F000000000004B0B300000000100F +:1094B0000000000000020202002800008002FC0000 +:1094C000FFFFFF010D000D0016001E000000000050 +:1094D00004C4B300000000100000000000030202FA +:1094E000002800008002FC00FFFFFF010D000D00BE +:1094F00015001D000000000004D8B300000000109B +:109500000000000000040202002800008002FC00AD +:10951000FFFFFF010D000D0014001C000000000003 +:1095200004ECB3000000001000000000000502027F +:10953000002800008002FC00FFFFFF010D000D006D +:1095400013001B00000000000400B4000000001025 +:109550000000000000060202002800008002FC005B +:10956000FFFFFF010D000D0012001A0000000000B7 +:109570000414B40000000010000000000007020204 +:10958000002800008002FC00FFFFFF010D000D001D +:1095900011001900000000000428B40000000010B1 +:1095A0000000000000080202002804008002FC0005 +:1095B000FFFFFF010D000D0010001800000000006B +:1095C00020B0B30000000010000000000000000008 +:1095D000002806000000FC00000000000D000D0047 +:1095E000D20FA00F00000000015097010000000002 +:1095F0000000000000000000002802000000FC0045 +:10960000000000000D000D00C116A81600000000AB +:10961000018C97010600000000000000000B020210 +:10962000002800008000FC00000000000D000D007C +:1096300017001F000000000004B0B300000000107D +:1096400000000000000C0202002800008000FC0066 +:10965000000000000D000D0016001E0000000000BC +:1096600004C4B3000000001000000000000D02025E +:10967000002800008000FC00000000000D000D002C +:1096800015001D000000000004D8B3000000001009 +:1096900000000000000E0202002800008000FC0014 +:1096A000000000000D000D0014001C000000000070 +:1096B00004ECB3000000001000000000000F0202E4 +:1096C000002800008000FC00000000000D000D00DC +:1096D00013001B00000000000400B4000000001094 +:1096E0000000000000100202002800008000FC00C2 +:1096F000000000000D000D0012001A000000000024 +:109700000414B40000000010000000000011020268 +:10971000002800008000FC00000000000D000D008B +:1097200011001900000000000428B400000000101F +:109730000000000000120202002804008000FC006B +:10974000000000000D000D001000180000000000D7 +:1097500020B0B300000000104F00000001F404002E +:1097600068931B00600000000C0000000100040072 +:109770001428000060000000300000002D0084006C +:10978000142800001C000000730000002DF4840069 +:1097900068931B001C000000700000002DF4840082 +:1097A00068931B001C000000730000002DF484006F +:1097B00068931B001C000000630000002DF484006F +:1097C00068931B001C0000004F00000001F404001F +:1097D00068931B00E00001000C0000000100040081 +:1097E00014280000E0000100300000002D0084007B +:1097F000142800001C000000700000002DF48400FC +:1098000068931B001C000000000000000000000026 +:109810000000000000000000000000000000000048 +:109820000000000000000000000000000000000038 +:109830000000000000000000000000000000000028 +:109840000000000000000000000000000000000018 +:109850000000000000000000000000000000000008 +:1098600000000000000000000000000000000000F8 +:10987000000000000000000000000000922492247C +:109880009200920000000000224924492401A40013 +:1098900000000000144924492401140100000000C4 +:1098A000A448244924012201000000002445242961 +:1098B000240124010000000024292445240124015E +:1098C000000000002449A4482201240100000000F7 +:1098D00024491449140124010000000024492249AC +:1098E000A400240100000000FF7FFF7FFF01FF01B3 +:1098F00000000000B66DB66DB601B60100000000B4 +:10990000B26DB66DB601B60000000000966DB66D82 +:10991000B601960100000000B66CB66DB601B2014A +:1099200000000000B665B62DB601B60100000000CB +:10993000B62DB665B601B60100000000B66DB66C76 +:10994000B201B60100000000B66D966D9601B60139 +:1099500000000000B66DB26DB600B6010000000058 +:1099600001280000000000000000000000000000CE +:10997000000000020206AA006C768A94000106002C +:1099800000000000DB0600000106000091016E20CF +:10999000418C3903010000C61D018C6100000000EC +:1099A0000000000010100D100390BBBB8E5A22184F +:1099B00064116411893989390AE00FE06412641274 +:1099C000012800000000000000000000000000006E +:1099D000000000020206AA006C768A9400010600CC +:1099E00000000000DB0600000106000091016E206F +:1099F000418C3903010000C61D018C61000000008C +:109A00000000000010000C100380ABAA80442278F4 +:109A1000641164118939893905E005E06412641222 +:109A20000104000000000000000000000000000031 +:109A3000000000020200AA006C768A940001060071 +:109A400000000000DB060000040C000038066E2059 +:109A5000418C390301000084C4058C6100000000C2 +:109A60000000000010C40C500390BBBB804422785F +:109A7000641164118A39893905E00FE064126412B7 +:109A8000D004020001020304CCF57AFDED20BF8F63 +:109A9000CF0304021E0600036C768A9400010600C0 +:109AA00000000000DB06000001460000121B002041 +:109AB000006B39034100028400006B616478792BEC +:109AC000CF8A00801C5411980080BBBB00572278BD +:109AD000641164118A39893905E00FE06412641257 +:109AE0000100000001010101CCF57AFDED20BF8FDE +:109AF000CF030402020600006C768A94000106007F +:109B000000000000DB060000000C0000401A0020EE +:109B10004100380341000284000000606478792B22 +:109B2000CF8A00801C5410180380BBBB804622786B +:109B3000641164118A39893905E00FE064126412F6 +:109B4000D004020002020202CCF57AFDED20BF8FA4 +:109B5000CF030402020600006C768A94000106001E +:109B600000000000DB06000001460000121B002080 +:109B7000006B39034100028400006B616478792B2B +:109B8000CF8A00801C5411980380BBBB804622788A +:109B9000641164118A39893905E00FE06412641296 +:109BA0000100000003030303CCF57AFDED20BF8F15 +:109BB000CF030402020600006C768A9400010600BE +:109BC00000000000DB060000000C0000401A00202E +:109BD0004100380341000284000000606478792B62 +:109BE000CF8A00801C5410180380BBBB80462278AB +:109BF000641164118A39893905E00FE06412641236 +:109C0000D004020004040404CCF57AFDED20BF8FDB +:109C1000CF030402020600006C768A94000106005D +:109C200000000000DB06000001460000121B0020BF +:109C3000006B39034100028400006B616478792B6A +:109C4000CF8A00801C5411980380BBBB80462278C9 +:109C5000641164118A39893905E00FE064126412D5 +:109C60000100000000000000CCF57AFDED20BF8F60 +:109C7000CF030402020600006C768A9400010600FD +:109C800000000000DB060000000C0000FF3B00208D +:109C90004100380341000284000000606478792BA1 +:109CA000CF8A00801CC410180300000000C6227870 +:109CB000641164118039803905000F00551055106A +:109CC000000000000000000000101000000092CD15 +:109CD0000000C180100F0002000087370000BBF1B8 +:109CE000100F00040000904100008B43100E00078D +:109CF0000000BBF100009167100C000900001DFB83 +:109D00000000709E100E000500000000C806000054 +:109D1000BAF15942BAF15942450EA63D11223344D7 +:109D20005566778899AABBCCDDEEFF69000000007C +:109D30000000000000000000000000000000000023 +:109D40000000000000000000C022C0224A4948472D +:109D5000464544434241403F3E3D3C3B3A3938371B +:109D6000363534333231302F2E2D2C2B2A2928270B +:109D7000262524232221201F1E1D1C1B1A1900002A +:109D800000000000000000000000000000000000D3 +:109D90000000000031302F2E2D2C2B2A29282726B9 +:109DA0002524232221201F1E1D1C1B1A19181716DB +:109DB0001514131211100F0E0D0C0B0A09080706CB +:109DC0000504030201000000000000000000000084 +:109DD00000000000000000000000000000204060C3 +:109DE00080A0C0E00020406080A0C0E00020406073 +:109DF00080A0C0E00020406080A0C0E00020406063 +:109E000080A0C0E00020406080A0C0E000200000F2 +:109E1000000000094992481292B46D1B1B4992241C +:109E20006DDBB6362000E0C0A08060402000E0C0BE +:109E3000A08060402000E0C0A08060402000E0C022 +:109E4000A08060402000E0C0A08060402000E0C012 +:109E5000A08060402000000076DBB62D2449921BD4 +:109E6000DBB64912929424090900000062442608D6 +:109E7000EACCAE9072543618FADCBEA08264462852 +:109E80000AECCEB0927456381AFCDEC0A284664842 +:109E90002A0CEED0B29476583A1C9D7F61430000A4 +:109EA0006D4B9224E4B66D1B9324490A4992240019 +:109EB0000000B42D2F11927456381AFCDEC0A28413 +:109EC00066482A0CEED0B29476583A1CFEE0C2A442 +:109ED00086684A2C0EF0D2B496785A3C1E00E2C432 +:109EE000A6886A4C2E10000040DB962424496E1B85 +:109EF000DB26491292922409090000002507E9CBCC +:109F0000AD8F71533517F9DBBD9F8163452709EB91 +:109F1000CDAF9173553719FBDDBFA1836547290B81 +:109F2000EDCFB1937557391B9C7E6042240600002B +:109F30002D499224DBB66D13922429094992000021 +:109F400000D0B62D6C4E3012937557391BFDDFC112 +:109F5000A38567492B0DEFD1B39577593B1DFFE1E1 +:109F6000C3A587694B2D0FF1D3B597795B3D1F01D1 +:109F7000E3C5A7896B4D000000D0B6252449921B8C +:109F8000DBB6491292A4240949020000E8CAAC8E4B +:109F900070523416F8DABC9E8062442608EACCAED1 +:109FA0009072543618FADCBEA0826446280AECCEC1 +:109FB000B0927456381A9B7D5F412305E7C90000B3 +:109FC0002449921BDBB64D1292A4240949020000D9 +:109FD00040DBB624A98B6D4F31139476583A1CFEA2 +:109FE000E0C2A486684A2C0EF0D2B496785A3C1E81 +:109FF00000E2C4A6886A4C2E10F2D4B6987A5C3E71 +:10A000002002E4C6A88A00000000B42D254992244D +:10A01000DBB66D139224290949920000AB8D6F5174 +:10A020003315F7D9BB9D7F61432507E9CBAD8F7110 +:10A03000533517F9DBBD9F8163452709EBCDAF9100 +:10A04000735537199A7C5E402204E6C8AA8C00003A +:10A0500024496E1BDB364912929224090900000044 +:10A060006DDB9224E6C8AA8C6E5032149577593B6A +:10A070001DFFE1C3A587694B2D0FF1D3B597795B20 +:10A080003D1F01E3C5A7896B4D2F11F3D5B7997B10 +:10A090005D3F2103E5C700000000002D6D499224BB +:10A0A000E4B66D1B9324490A499224006E50321481 +:10A0B000F6D8BA9C7E60422406E8CAAC8E70523450 +:10A0C00016F8DABC9E8062442608EACCAE90725440 +:10A0D0003618997B5D3F2103E5C7A98B6D4F0000C2 +:10A0E00024B96D1BDB2449124A9224090000002D7B +:10A0F0006D4B92242305E7C9AB8D6F5133159678CC +:10A100005A3C1E00E2C4A6886A4C2E10F2D4B698BF +:10A110007A5C3E2002E4C6A88A6C4E3012F4D6B8AF +:10A120009A7C5E4022040000090000006DDB92244E +:10A1300024B96D1BDB2449124A9224093113F5D747 +:10A14000B99B7D5F412305E7C9AB8D6F513315F78F +:10A15000D9BB9D7F61432507E9CBAD8F715335177F +:10A16000FFFFFFFFFFFFFFFFFFFFFFFF30120000B9 +:10A17000E4B66D1B9324490A499224000000FC3F79 +:10A18000FFFFFF2460422406E8CAAC8E70523416EA +:10A1900097795B3D1F01E3C5A7896B4D2F11F3D55F +:10A1A000B7997B5D3F2103E5C7A98B6D4F3113F54F +:10A1B000D7B99B7D5F4100004902000040DBB62417 +:10A1C00024496E1BDB36491292922409F4D6B89AC0 +:10A1D0007C5E402204E6C8AA8C6E503214F6D8BACF +:10A1E0009C7EFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:10A1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00006D +:10A20000DBB66D1392242909C9FFFF3FFFFFFF3F13 +:10A21000FFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFF0E +:10A22000FFFF987A5C3E2002E4C6A88A6C4EFFFFCE +:10A23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:10A24000FFFFFFFFFFFF0000FFFFFF3FFFDFB62D17 +:10A250002449FE3FFFFFFF3FFFFFFF3F2000E0C01C +:10A26000A08060402000E0C0A08060402000E0C0EE +:10A27000A08060402000E0C0A08060402000E0C0DE +:10A28000A08060402000E0C0A0806040200000006E +:10A2900076DBB62D2449921BDBB649129294240931 +:10A2A000090000002000E0C0A08060402000E0C065 +:10A2B000A08060402000E0C0A08060402000E0C09E +:10A2C000A08060402000E0C0A08060402000E0C08E +:10A2D000A08060402000000076DBB62D2449921B50 +:10A2E000DBB6491292942409090000000000000026 +:10A2F000000000000000000000000000000000005E +:10A30000000000000000000000000000000000004D +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000C822050CE8220F0C56 +:10AAE0000000001002000000000000000000000054 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB2000C00BBC0DEE0B0000400BBC0FEC0B040087 +:10AB3000C02ABC0FEA0B0C00404ABC0FE80B140003 +:10AB4000C069BC0FE60B1C004089BC0FE40B24005D +:10AB5000C0A8BC0FE2082C004C48BE00000000005A +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00029292A2A2A2A29292A2A2A2A29292A2A0B +:10ABB0002A2A29292A2A2A2A2A2A2A2A29292A2AF9 +:10ABC0002A2A29292A2A2A2A29292A2A2A2A2929EB +:10ABD0000000000029292A2A2A2A29292A2A2A2A81 +:10ABE0000000000000000000000000000000000065 +:10ABF00000000000000000002A2A2A2A29292A2A07 +:10AC00002A2A29290000000000000000000000009E +:10AC10000000000029292A2A2A2A29292A2A2A2A40 +:10AC20002A2A2A2A29292A2A2A2A29290000000030 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE100006F0F15506F0F15506F0F15506F0F15542 +:10AE20001D1D1B181B1A1A1A1D1C1D1D1D1D1F235D +:10AE30001F201E1C1B1C1B1B1D1D1E1D1D1D1E1F40 +:10AE40001D1D1C1A1C1C1A1A1D1D1D1D1E1C212433 +:10AE5000201F1E1D1D1C1C1B1D1B1D1C1D1C1F1F20 +:10AE60001C1B1B1A1B1A1A1A1C1B1C1D1D1E21231E +:10AE7000201E1D1C1C1A1B1B1C1B1D1D1D1C1E1F08 +:10AE80001C1C1A1A1A1A1A191A1B1A1C1C1D1F220A +:10AE90001F1E1C1B1C1B1B1B1B1C1C1C1E1C1D1EED +:10AEA0001C1B1A191A1918191B1B1C1C1C1E2022EA +:10AEB0001F1D1C1B1B1A19181A1B1C1B1E1C1E1ED7 +:10AEC0001D1C191A1A1918191A1A1A1B1B1B1D20D6 +:10AED0001D1C1B1A1A19191819191A1A1C1B1C1EC9 +:10AEE0001B1B1A1A1A1818191C1B1C1C1C1D1C20B1 +:10AEF0001D1C1B1A1B191918191A1A1B1C1B1C1EA6 +:10AF00001B1B191919181918191A1B1B1A1C1B1F9E +:10AF10001D1D1A191B19191819191A1A1C1B1C1D89 +:10AF20001B1A1919191818191A1A1B1B1B1B1C207C +:10AF30001D1B1A1A1A191918191A1A1A1B1B1C1D6B +:10AF40001B1A1819191817171819191A1A1B1B2068 +:10AF50001D1B1B191919181818191A191B1A1B1D52 +:10AF60001B1A19191A17161717181819191A1A1F50 +:10AF70001D1B1A191818181819191B1A1A1A1B1C34 +:10AF80001A1A18191918181818171818181A1B202F +:10AF90001C1A1A1A18191817181819191A1A1A1B1C +:10AFA0001B1A18191918171819191919181A1B1F0B +:10AFB0001C1B1A1A18191919191A1A1B1A1A1B1CF0 +:10AFC0001A1918191918171819181919181A1A1EF0 +:10AFD0001B1B1A191819191819191A1A191A1A1CD7 +:10AFE0001A1817181817161719191919191B1A1CD6 +:10AFF0001C1B1A191819191819191A191A1A1B1BB6 +:10B000001A191718191817171919191A181A191CB3 +:10B010001D1B1A19171819181818191819191A1B9D +:10B020001A181718181716171818181A18191A1C9A +:10B030001C1A1919181818181919191A1A1A1A1C79 +:10B04000191817181717161617181819181A1B1B7E +:10B050001C1A1919181818171818191819191A1B61 +:10B060001918161817161616171718181819191A66 +:10B070001B19181818161717181819181A19191B48 +:10B080001918161817161616161717181718191A4A +:10B090001B191818171718161717191819191A1B2A +:10B0A0001918161717161516171718191818191A28 +:10B0B0001C19191918181817171718181A19191A06 +:10B0C000181816171716151517171719181A191A09 +:10B0D0001B19181818181817171819171A19191AE8 +:10B0E00018171617161514151616161717181718F9 +:10B0F0001A19181717161716171818171A19191AD0 +:10B1000018171616161515141616161716181818D9 +:10B110001A181817171717161717181719181819B4 +:10B1200018171616161514141616161716171818BB +:10B130001A18171717171616161718171918181997 +:10B1400017161516151414141516161616161717A5 +:10B15000191717161716161516161717191818197E +:10B160001716151515141414151516161616171886 +:10B170001917161616161615161617161817171865 +:10B18000171715151414141415151516151517176A +:10B190001817171616161715161616161817171845 +:10B1A000171615151413131315151616161617174B +:10B1B0001918171616161616151617151817171824 +:10B1C0001616151515141314151515171516171829 +:10B1D0001818161716171716151617161716171804 +:10B1E0001716151414141315151516161616171709 +:10B1F00018171616161615151515161517161616F0 +:10B2000016161515141413141415151615151616EF +:10B2100018171616151615161515161516161617CF +:10B2200016151414141412131414141514141616D9 +:10B2300017161516151515151415161517151616B6 +:10B2400016151414141313131414141514151617B7 +:10B250001716161515171514141515141615161698 +:10B26000161513141413121313141415141515169C +:10B27000171615151514151414151515161616167A +:10B28000161413141413131313141414141415167E +:10B290001615151514141514131414141515151565 +:10B2A0001514131413131313131313141414151662 +:10B2B0001615151514141514141415141614161641 +:10B2C0001514131313131213131213141314151547 +:10B2D0001615141414141514141414141614151526 +:10B2E0001514131313131212131313141314141528 +:10B2F0001616151515141514141414141515141503 +:10B30000141313141212121212121213131314150F +:10B3100015151514141315141313141315131414ED +:10B3200014131313121312121212121313131416EE +:10B3300015141414141414131314141415141414CD +:10B3400014131213121212121212121313131416D0 +:10B3500014141414141314131314141314131314B3 +:10B3600013131213121212121212121313131415B2 +:10B370001414131414131313131414131513131494 +:10B380001313121212121210121212121212131599 +:10B390001414131314131413131314131514131474 +:10B3A000131212121212111012121213121213157A +:10B3B000141413131313131312131413141313135A +:10B3C000131312121211121012121213121213145A +:10B3D000141313131312141313141313141313133A +:10B3E000131212121111111111121212121213143E +:10B3F0001414141313121413131313131413141417 +:10B400001212121211101111121212121212121320 +:10B4100012131313131313131313121313131414FC +:10B4200013131212121111121213121313121313F7 +:10B4300013131313141413131414131313141415D4 +:10B4400014141212131311121313131313131313CF +:10B4500014131313141414141314141414151414AF +:10B4600019191916181717161A1A1A191A1A1B1E4B +:10B470001B1B1A181817171718191A191B1C1C1D33 +:10B480001A191918191918171B1B1A1A1B1B1E2118 +:10B490001C1B1A191819181819181A1A1C1B1D1D0B +:10B4A0001A19191819181818191A1A1B1B1C1E20FA +:10B4B0001C1B1B191918181819191A1A1B1B1C1DEB +:10B4C0001A1A1918191818171819191A1A1A1C1FE4 +:10B4D0001D1C1A191A191818191A1A191B1B1C1DC8 +:10B4E0001A1A191819181717191919191A1B1C1EC5 +:10B4F0001C1C1A191A18181719191A1A1B1B1D1DAA +:10B500001A1918181917171718191919191A1B1EAB +:10B510001C1A19191A171818181819191A1A1B1C95 +:10B520001B1A181819171618181A191919191B1E89 +:10B530001B1B19191A1718181818191A1A1A1B1C74 +:10B540001A1A1818191817181718181818181A1C72 +:10B550001B1B19191A171818181819191A1A1B1B56 +:10B560001A191818181616171819191818191A1E52 +:10B570001C1A1919191718171818191919191B1B3A +:10B580001A19171818161517171717181718191E3C +:10B590001C1B1919181718171817181819181A1B1F +:10B5A0001A19171718161517161717171719181D20 +:10B5B0001B1A181817171817171719191918191B04 +:10B5C0001919171817161517161717171618181C04 +:10B5D0001A19181817171717171718181817191AEC +:10B5E0001A18171717161516171717171618181CE5 +:10B5F0001A19181817171717181718181918191AC9 +:10B600001918171717161517161616171618181BC8 +:10B610001A19171716171716171718181918191AAD +:10B6200019171617171514161617171817191819AA +:10B630001A1A171716161716161717181917181A91 +:10B64000181716171716151616171717161818188D +:10B650001A19171716161716161617161917191A74 +:10B66000181716171615151616171718161818186E +:10B670001A18171617161716161617161917181A56 +:10B680001717171716151516151616171618181852 +:10B690001A18171617161716161616151817181A39 +:10B6A0001716161716151416151616171618181835 +:10B6B0001A1816161715161516161716181718191C +:10B6C0001716161617151415151616171518181817 +:10B6D00019181616171516151615161718171819FE +:10B6E00017161616161514151616161715181717F9 +:10B6F0001A191716171617161616171618171818D8 +:10B7000016151616151514141616161716191817D9 +:10B7100019181616171516161615171618171719BD +:10B7200016151616151414141516151615171716C2 +:10B7300019181616161516151615171518171719A0 +:10B7400016151616151514141516151615171716A1 +:10B750001817161516151615161516161716171886 +:10B760001615161515141414151515161516171685 +:10B770001817161516151615151516161716171768 +:10B78000151415151514141414151415141616166D +:10B79000171616151615161515141616171617184A +:10B7A000151415151413131414151515141616164F +:10B7B0001717151516151514151416151715161730 +:10B7C0001514151514141314141514151415161630 +:10B7D0001717161516151515151415141715161710 +:10B7E0001514151514131213141514151415161514 +:10B7F00017171615161415141515151517151616F1 +:10B8000015141415141313131414141514151616F3 +:10B8100016171615161515141414151417151616D3 +:10B8200015141315141312141415141514151615D4 +:10B8300016161514151414131414141416151516BD +:10B8400014141313131312141314141414141615BC +:10B85000161615141514141414131413161515169E +:10B86000151413131312121413141414131415159E +:10B870001615151414141414131314141614151582 +:10B88000141413141312121314141414141515157C +:10B890001514151414141513131314131514151566 +:10B8A0001413121312121212131313141314151467 +:10B8B0001514141414131413141314131514141549 +:10B8C0001413121312121213131313131314141448 +:10B8D000151415141413141313131313141414142C +:10B8E0001413121412121213121313131313141429 +:10B8F000141414131313141313131313151415150D +:10B90000141312131212121312121213121314140C +:10B9100014141313131314131313131215131414F1 +:10B9200013131213121212121212121313141414EC +:10B9300014141313131213131313141315131414D1 +:10B9400014121213121212121212121212131314D0 +:10B9500014141313131214131213131314131414B3 +:10B9600014131213121212121213121313131314AC +:10B970001413131312131312121313131413141397 +:10B980001312111311121212121212121213131493 +:10B990001313131313121312121213131413141478 +:10B9A0001212111212121111121212121213131476 +:10B9B0001313131313121212121313131413131459 +:10B9C0001212111312111211121212121212131456 +:10B9D0001313131313121313121313131413131338 +:10B9E0001212121311111111121212121212131437 +:10B9F000131313131312131212121312141313131B +:10BA00001312121311111211121212121212131414 +:10BA100013131212121213121213131214121313FD +:10BA200012121112111111101212121212121313FA +:10BA300013131313121113121313131314121313DA +:10BA400012121112111111101212121212131314D8 +:10BA500013131313131313121313131313131313B7 +:10BA600013131111111011101112121212121313BB +:10BA7000131312121313131212131312131313139B +:10BA8000131211111211101112121212121213129A +:10BA9000131312121312121212131313131212137E +:10BAA00018191917191819181A1A1A1B1A1A1C1EFC +:10BAB0001B1C1B1A181918191A1A1B1A1A1B1B1CE3 +:10BAC000181819181A1A19191B1B1B1C1C1B1E21CC +:10BAD0001C1B1B1A191A1A1A1A191B1B1C1B1C1CBB +:10BAE00019191919191919191A1A1B1C1C1B1E1FAF +:10BAF0001C1B1B1A1A191A191A1A1B1A1C1B1B1B9E +:10BB00001A1A1919191919181919191A1C1B1C1E96 +:10BB10001C1B1A191A191A191A1A1B1A1D1B1B1B7E +:10BB20001919181A1A1918191A1A1B1B1C1C1C1E71 +:10BB30001C1B1A1A1B1A1A191A1A1A1B1D1B1C1C59 +:10BB4000191918191A191819191A1A1A1B1A1B1E59 +:10BB50001C1A1A191B1919191A191A1A1C1A1A1B44 +:10BB6000191918191A1918191A1B1B1B1A1B1B1E35 +:10BB70001B1A1A191A19191919191A1A1B1A1A1A29 +:10BB80001A19181819191919191A19191A191A1D1F +:10BB90001B1A1A191A1919191A191A1B1C191A1B06 +:10BBA00019181819191818181A1A1B1A1A191A1FFD +:10BBB0001B1A1A1B1B191A191A191A1A1B191A1AE5 +:10BBC00019181818191718181818191919191A1EE8 +:10BBD0001B1A1A1A19191919191919191B19191ACD +:10BBE00019191718181817171818181818191A1ECD +:10BBF0001B1A1919181819181A1919191A181919B4 +:10BC00001918171818171817181818181819191DAF +:10BC10001919191918191918191919191A18191996 +:10BC2000191A181818171717181818181719191C8F +:10BC30001A1A1919181919181A1919191A19191972 +:10BC40001919191917181718181818191719181C6D +:10BC50001919181917181818191819191A1918195B +:10BC60001818171817171717191818191719181A55 +:10BC70001A19181818181817181819181A1818193E +:10BC80001919171818171717191717181618181938 +:10BC90001919181817181918191818181A1818191E +:10BCA0001818171818171717181819191719191914 +:10BCB0001A19181718171817191819181A191919FD +:10BCC00017171718181817171818181918191919F5 +:10BCD0001A181818181818171818181719181819E2 +:10BCE00017181718181716171818181817191819D9 +:10BCF0001A181717181717171818191819181818C5 +:10BD000019191718181716171717181817191819B7 +:10BD10001A181818181718171817181819181819A2 +:10BD2000181717181716161718171819171918189B +:10BD30001B19181819181818181719171A1818187D +:10BD4000171717181716161617171818171918187F +:10BD50001A18181819171818181718171918171863 +:10BD60001818161816161516171717181718171863 +:10BD70001A18181718171717181818171A18181844 +:10BD80001817161816161616171717171718181843 +:10BD90001A18181818171717181718171917181727 +:10BDA0001716161717161616171717181718171825 +:10BDB000191817171817171718171817191817170A +:10BDC0001717161716161516171716171717171809 +:10BDD00019171717181718171717181719171717EC +:10BDE00018161517161615161716161817171717EB +:10BDF00019181717171718161717181718171617CF +:10BE000017161617161616161616161716161617CE +:10BE100019171817171717161717171619171617B0 +:10BE200016161517161514161717171716171717AE +:10BE30001917171717161717171717161917161791 +:10BE40001616161716151515161617171616171790 +:10BE50001917171717171717161617161816161675 +:10BE60001616151616151516161616171616171772 +:10BE70001818161617171716161617161816161658 +:10BE80001615151616151516161616171616161754 +:10BE90001818161617161617161617161816161639 +:10BEA0001615151615151517161616161616171635 +:10BEB000181716161616161616161716181616161C +:10BEC0001615151715151516161615171616161715 +:10BED00017171617161616161616161518161616FE +:10BEE00017151416151515151516151615161716FA +:10BEF00017171616161617161616161517161516E0 +:10BF000015151416151515141516161615161616DC +:10BF100016161616161617161515161517151515C5 +:10BF200015141416151515141515151515161616C0 +:10BF300016161616151617151516161517151616A4 +:10BF400015151416151515141515151515151616A0 +:10BF50001616151516151715151516151715151688 +:10BF60001514141614151514151514161515161682 +:10BF70001616151616151615151516161716151567 +:10BF80001414141615141514151515151514151665 +:10BF90001616161615141716151516151715161547 +:10BFA0001514141614151514151515151515151643 +:10BFB000161516151515161515151614161515142E +:10BFC0001413131514141514151414151515151729 +:10BFD000161515151614151515151615161515150E +:10BFE0001414131514141513151414151515151709 +:10BFF00016151515151516151515161517151514ED +:10C0000014141415141414131414141515151516EA +:10C0100016151515161516151515161517151515CA +:10C0200014141315141415131514141515151517C8 +:10C0300015151515151415141515151416151514B3 +:10C0400014141315141414131515141515151516A9 +:10C050001515141415141514151615141615151494 +:10C06000141413151314141314141415151515158D +:10C07000161516151514151515161615161615156B +:10C08000141413151313131314141415161615156D +:10C09000151515151615151616161616151515154A +:10C0A000151414141313131314141514151415154F +:10C0B000151515151515151515151515161515152F +:10C0C0001515131414131313141414141415141431 +:10C0D0001615141515151515141515151615151510 +:10C0E0001B1B1B191C1B1A1B1D1C1D1C1C1C1D1F94 +:10C0F0001C1E1D1B1B1C1B1B1C1D1D1B1C1D1D1D7D +:10C100001B1B1B1A1D1D1B1C1E1D1E1E1E1D202160 +:10C110001D1E1D1C1B1C1C1C1D1C1D1D1D1C1D1C57 +:10C120001A1B1B1B1B1B1C1B1C1D1D1D1D1D1E1F4D +:10C130001D1D1C1C1B1B1C1B1C1C1E1C1D1C1C1D3C +:10C140001B1B1A1B1C1C1B1B1B1C1B1D1D1D1D1F31 +:10C150001E1D1B1B1C1C1C1C1C1C1D1C1E1D1D1D18 +:10C160001A1B1A1B1C1B1A1B1C1D1C1C1D1D1E1F11 +:10C170001D1C1B1B1C1B1B1B1C1C1C1B1E1D1D1DFF +:10C180001B1A1A1B1C1B1B1B1C1C1C1C1C1C1C1FF5 +:10C190001D1C1B1B1C1A1B1B1C1C1D1C1E1C1C1CE1 +:10C1A0001B1B1B1D1C1B1B1C1C1D1D1C1C1C1C1FCE +:10C1B0001D1B1B1B1C1B1B1B1B1C1C1C1E1C1C1DC2 +:10C1C0001B1B1A1C1C1B1A1B1B1C1B1B1B1B1C1EBA +:10C1D0001D1C1B1A1C1A1B1B1B1C1C1B1D1C1C1BA7 +:10C1E0001A1A1A1B1B1B1A1B1C1D1D1C1A1B1C1F99 +:10C1F0001D1B1C1B1C1B1B1B1C1B1C1B1E1C1C1C83 +:10C200001B1B191B1B1A1A1B1B1B1B1C1B1B1B1F7D +:10C210001C1B1B1B1A1B1B1A1B1B1C1B1D1C1C1D68 +:10C220001A1A1A1B1C1A1A1B1A191A1A191B1B1F65 +:10C230001C1C1B1B191A1B1A1B1B1C1B1D1B1C1D4A +:10C240001A1A1A1B1B1A1A1C1A1A1A1A191A1B1F45 +:10C250001B1B1B1B191B1B1B1B1B1B1B1D1B1A1B2F +:10C260001A1A1A1B1C1B1B1C1A1A1A1A181A1B1E24 +:10C270001C1B1B1B191B1B1A1B1B1C1B1D1C1C1C0A +:10C280001A1A1A1B1B1A1A1B1A1A1A1A191B1A1D08 +:10C290001B1B1A1A191B1B1A1A1B1B1B1D1B1A1BF3 +:10C2A0001A19191B1A1A1A1B1A1B1A1A191B1B1BEB +:10C2B0001C1B1B1A191B1B1A1B1B1B1A1D1B1B1BD0 +:10C2C0001A1A191B1B1A191A1B1A191B191B1B1ACC +:10C2D0001B1B1A1A191A1B1A1B1B1C1A1D1C1B1CB0 +:10C2E0001A191A1A1A1A1A1B1B1B1A1B191B1A1BAA +:10C2F0001B1B1A1A191A1B1A1B1B1B1A1D1C1C1C90 +:10C30000191A1A1B1A1A1A1A1A1A191A191B1A1A8E +:10C310001B1A1A1A191A1A1A1A1A1B1A1D1B1B1C75 +:10C320001919191B1A1A191B1A1A1B1B1A1B1A1B6B +:10C330001C1A1A1919191A1A1A1B1B1A1E1B1A1B56 +:10C340001919191B1A1A191A1A1A1A1B191B1A1B4E +:10C350001C1A191919191A1A1A1A1C1A1D1C1B1C35 +:10C360001A19191A1A1919191A1A1B1A191B1A1932 +:10C370001C1B1A1A1A1A1A1A1A1A1B1A1C1B1B1B14 +:10C380001A1A181A191A19191A1A1A1B1A1B1A1A10 +:10C390001C1A1A1A1A191A191A1A1B1A1C1B1B1BF7 +:10C3A0001A1A191A191818181A19191A191B191AF8 +:10C3B0001B1A191919181A191A1B1A191C1B1A1BDE +:10C3C0001919191A19191818191A191A191A1A19DA +:10C3D0001B1A1A19191919181A1A1A1A1C1B1B1BBD +:10C3E000191A191A19191819191A191A191A1A19B8 +:10C3F0001B191A1919191A191A1A1B1A1C1B1B1B9B +:10C40000191A1919191818181A1A1A1A19191A1999 +:10C410001A1A191919191A191A191B1A1C1B1B1B7C +:10C4200019191919191818191A19191A1A1919197B +:10C430001A19191919191A191A191A191B1A1A1B62 +:10C440001A1918191818181919191A1A191819195E +:10C450001A1A1919191A1A1919191A191B1B1B1B3F +:10C4600019191819181818181A1A1A1A191919193D +:10C470001B1919191A19191919191A181C1A1B1B21 +:10C4800018181819181818181918181A1918191925 +:10C490001A1A1A19191A191918191A191B1A1A1A03 +:10C4A00019181719191817191919191A19181A1901 +:10C4B0001A1A19181919191919191A181A191A1AE8 +:10C4C00018171718181818191919191A19181918E6 +:10C4D0001A1A19191918191919191A181B1A191AC7 +:10C4E00018171819171717191819191918181919C9 +:10C4F0001918181918191918181819191A19191AB0 +:10C5000018191818181717181919191A18181918A6 +:10C510001919181818191918181919181919191991 +:10C5200018171717171717171918181A181819198D +:10C530001919181918181918191919181A1919196F +:10C54000181818181718171818181819171819186C +:10C550001918191818181918181818171918181957 +:10C560001818181817171717171818181718191850 +:10C570001818181818181918181819181919191935 +:10C58000171717181817181818181718181719192F +:10C590001818171818181918181818171919191918 +:10C5A0001717171817171717181717181717181816 +:10C5B00018181718181718181818191819191919F8 +:10C5C00017171718171717171817171818171819F4 +:10C5D00018181818181618181718181819181818DD +:10C5E00017181718171717181818171817171819D2 +:10C5F00018171818171819181818191819191818B9 +:10C6000017171617161717171817171818171819B6 +:10C61000181717171816181718181818191818189F +:10C62000161616171717171617161717171717199D +:10C63000171717171817171717181918191918187F +:10C640001717161717171716181717181717171978 +:10C650001717171818171817181818181A1918195B +:10C660001616161817161615171717171616181A5E +:10C67000181817171717181718181817191818183F +:10C68000161616171616171517171717171717193F +:10C69000181717171717181718181818191818181F +:10C6A000161616181616161517171819171717181D +:10C6B0001817181717161818191A191819181818FA +:10C6C0001716161715151615171717171717171802 +:10C6D00017171818181819181818181818181818DB +:10C6E00017171717161516161718171717181718DC +:10C6F00017171717181818171818181718181818C0 +:10C7000018171617181716161817181718171717B7 +:10C710001818171818181818181919191918181896 +:10C7200006F0F15506F0F15506F0F15506F0F15519 +:10C73000402C2B2B2A2F2F2C2C34333131313134F8 +:10C740003040322F2E2C2B2A2B2C2C3131302F31F4 +:10C750003231322F322C2C2C2B2B2B2C2C313331F1 +:10C7600030333131312E312B2C2C2B2B2A2B2B2FEC +:10C77000312F2F302F2F2F2F2F2C2B2A2A2A2A2BE5 +:10C780002A2E2F302F302F2F2F2C2F2A2A282A2ADB +:10C7900029282A2D3030302F2F30312D2C2C2B2AC8 +:10C7A0002B2B2B2B282F2C2E2F2D2F2E2C2E2C2BC2 +:10C7B0002A292A2B2A2B2A2F302F2F2E2E2C2D2DB3 +:10C7C0002B2B2B292A2B2A2C2B333130312F2F2F97 +:10C7D0002D2B2B2A2A2A29292A282B2D2F2E2D2DA5 +:10C7E0002E2D2C2C2D2B2C2C2D2B2B2C2C2D30307E +:10C7F0002F2E2F2D2B2B2A2B2B2B2A2B2C2D2A3077 +:10C800002F30302F2D2D2C2A2C2A2A292A2A2A2C67 +:10C810002D2F2F2D2E2E2C2D2B2C2C29282A282A5B +:10C820002B2B2C2E2D2B2D2D2C2D2C2A2C29292851 +:10C83000282B2D2C2B2E2E2E2D2D2C2B2C2B292640 +:10C840002928292A2928292B2B2B2C2A2B2A2C2D45 +:10C850002C2A29292828282927292B292B2B2B2B3F +:10C860002A2C2B28272728282A29292C2C2C2C2A2B +:10C870002C2B2C2E2A2A292828292929292B2A2918 +:10C88000282929292B2F2A2A2A2928282A2A29290E +:10C890002928282828282B2C292929282728292B0A +:10C8A0002B2C2A2929292A2A292B292929292929EE +:10C8B0002929292A2929292828292A2C2A292828E6 +:10C8C00029292A2B2A2C292829282A29282C2A2ACE +:10C8D000292928292929292A292928292929292AC8 +:10C8E0002A292728292929292B2A2B2B2A292A2AB0 +:10C8F0002B2C292A29282829282929292A2A282AA3 +:10C90000292A2A2B292A272829282928292827279C +:10C91000292929292A2C2529282726272828272894 +:10C92000272827272827282A28282729272827298A +:10C930002926282A29282728272B2728272626277B +:10C9400026262627272626242727272B262928267A +:10C95000262728272725292628262627282A272963 +:10C960002827272727272827262527262627272A57 +:10C970002727272627272827282628262726262749 +:10C980002829262726262524262627272626252544 +:10C990002627272A25272626262626262625252534 +:10C9A0002525252526274025262524252526272615 +:10C9B0002523242525252640402A2D2D2E2E2F2CBB +:10C9C0002C313230303231343240302F30312E2F52 +:10C9D0002E2E2D323131323232343332312E2F2E4F +:10C9E000302E2B2D2C3230312F333334342F332F44 +:10C9F0002F2C2C2C2B2C2B3231303132343435313E +:10CA0000302E2F2E2E2D2D2C2C313331323432322C +:10CA1000312F312D2C2D2E2D2C2C2D2F333030302D +:10CA2000323233302D2F2F2F2D2F2E2D2D34313309 +:10CA3000353333322F2E2E2D2F2E2E2E2E2C2F31FE +:10CA4000313032323230302E2D2D2E2E2D2F2C2DF6 +:10CA50002F323230323231302F2D2F2E2E2F2F2EDB +:10CA60002E2E2F32313231313030302F2E2F2D2ECD +:10CA70002F2F2D2F2E2F3233323131302E2F2E2DBE +:10CA80002E2E2C2D2F2F3031333231302F2F2D2CB5 +:10CA9000312D2E2C2D2F302F30333031323231309A +:10CAA000302E2F2D2E2F2E2E2E2F2E313330313093 +:10CAB0002F31312D302D2F2F303032333034343070 +:10CAC00030302F2E2E2E2B2B2E2D2E2F2D2D2D2D8B +:10CAD0002F2C302E302D2F31312E2E2D2F2D302F6B +:10CAE000303331323030313231302F2D2D2E2D2E4A +:10CAF0002F2F30343132312F302F2E322F2D2D2D3C +:10CB00002C2E2D2D2D302F2D2F2F2E2E30312D2E42 +:10CB10002E2E2D2E2F2F2F2F2F2E2F2E2F2E2D2F2F +:10CB20002E2D2D2B2C2C303030312F2F2F2F2E2E21 +:10CB30002F312D2E2E2D2E2E2F2E2E2D2E2E2F2D13 +:10CB40002F2D2E302E2D2E2F302F3031312F2D2EF8 +:10CB50002F2D2E2D2C2E2E2E2D2D2E2F2F2E3030F4 +:10CB60002F302D2E2D2E2F2F2E2D2D2E2D2E2E2EE5 +:10CB70002F2D2E2E2E2C2E2D2D302D2D2D2C2D2EDD +:10CB80002E2E2E2E2E2E2F2E2F2F2F2E2D2E2E2DC3 +:10CB90002F302D2F302F2E2C2E2D2E2E2E30282DB7 +:10CBA0002E2B2C2C2D2C2D2C2E2E2D2C2E2D2C2EB8 +:10CBB0002D2C2B2D2C2B2C2D2E2D2D2E2D2C2D2EAA +:10CBC0002D2F2B2E2C2B2B2C2C2D2E2D2C2C2C2AA0 +:10CBD0002E2C2E2D2E2E2E2E2E2F2E2F2E2C2D2C7B +:10CBE0002B2B2E2E2C2D2C2E2D2D2D2D2D2D2F2C77 +:10CBF0002A2B2C2B2B2E2E302B2D2C2C2C2B2C2B74 +:10CC00002E2C2C2C2C2C2D2C2D2E2B2D2D2D2C2C5C +:10CC10002E2C2D2B2B2D2B2C2C2E2C2E2A2D2C2C50 +:10CC20002D2E2D2C2E2D2C2D2D2D2D2C2D2E402D21 +:10CC30002D2D2E2C2C2F32302D2C2F2D2F2C2D4006 +:10CC4000402D3231323334313234343335343538A7 +:10CC500034403032333333313231303133323536A0 +:10CC60003635363533323432323131312F32343396 +:10CC700031363536363534323232313130322F3783 +:10CC80003535353638363735343332323433313260 +:10CC90003034343436353634353434313030323063 +:10CCA000312E313335333435343435343235343450 +:10CCB000353437333335333636363635343532332B +:10CCC0003332323332313435363336353534343429 +:10CCD000303132333233323333363636363635331B +:10CCE00034333134343434353633383534343637FC +:10CCF00037353333323334343534343334363837EC +:10CD000035353636343530323434343534363735DB +:10CD1000353536353534322F3534333334323334D8 +:10CD200035373634353935353734383434343436AC +:10CD30003839373737373537373835313333353496 +:10CD40003435373536373936353735353333302F97 +:10CD50003232333333333135333635343634353498 +:10CD60003432343132343537343535373637373578 +:10CD7000363534313232343335353436363834366C +:10CD80003535353532343436363736363334373355 +:10CD9000323635343436323235353534333735354D +:10CDA000353533383533333434343432343438363B +:10CDB0003636353536353634333334343434353429 +:10CDC000363436353734333634323434333434341D +:10CDD0003536363836363635343636353334333400 +:10CDE0003333353433343435363436363333333500 +:10CDF00035353335333934393635383435363634DC +:10CE000034333434363635353535363333353535D8 +:10CE100035353432343434333635343735373734C6 +:10CE200036393636343430333333333333333333C4 +:10CE300034333435363333353333333537333538AC +:10CE4000363335333335343434342F3535333636A1 +:10CE50003435353533313232333333353335343499 +:10CE60003436353433343532343334353334333681 +:10CE7000353436353537343432323434343534356C +:10CE80003335333333353434343435333433343366 +:10CE90003435333437343435353333343332343452 +:10CEA0003335363637343434343637353434363433 +:10CEB000363434343534403D373937393C463935EA +:10CEC0003638333339333340403A353638363736EF +:10CED00034393A373A3A3A3D3D403E3F3F3E3738A3 +:10CEE000373636383837383D3D3A3A3937383A36BA +:10CEF0003635333535383837373C3A3B3B393937B7 +:10CF0000383637363637353A3B38383B3B3A38389F +:10CF100039393938393B363936393D3B3C3B3C3A77 +:10CF20003C38393538383737383536363B38393884 +:10CF3000383A3938353A393A393B3837353E393F5E +:10CF40003A3C3D3B383A373739393A38383A373A4C +:10CF50003A393C3B3C3C3A3834373837393B38383F +:10CF6000373A3C3D3C3E3E3C3A353739393B39391E +:10CF700037383B393B393B3E3B3B393A3739393B14 +:10CF8000393A3A3B3D3A3F3D3D3B3C3B393A3539F6 +:10CF9000393A3A3A3938393A3C3C3B3C3C3A3736F4 +:10CFA0003A39393A38393A3A3F3A3C3B3C3C3B3CD7 +:10CFB00039383B3A393C3A3D3A3B3D3C3C3D3B3DC0 +:10CFC0003E3B3C363A393C3A393C3C3B3D3A3C3AB4 +:10CFD0003D3B3D3D3C3A34373B393B3B39393839B1 +:10CFE0003B3B3B3C3E3B3A383A393A3A3B383738A0 +:10CFF000383B3B38393B3E3B38393A383A393A3896 +:10D00000373A3C3C3B3D3D393D3C383A393B3B3A75 +:10D010003C3D373A3A3A3A3A3B3D3C3C3C3A393A65 +:10D020003B3C3B3A393C3C3B3A3B3D3B3E3A3B3A4E +:10D03000393A3A3A383C3B3E3D3C3B3C3C3C3D3C3B +:10D040003B3A393C3D3B3B3E3A3C3A3C3A393C3B2F +:10D050003B3A3B3A3C3A3B3C3A3A3B3D403C3D3E16 +:10D060003B3B3D3A3A3A393A3B3B3A3A393A393A1C +:10D07000393A3B3E3C3C3B3B3C3C3A393B3B3A3CFF +:10D080003D3E393C3C3B3D3C39393B3B3D3D3B3BE8 +:10D090003A3B3D3A3A3A3B3B3B3A3B373B3A3B3BE8 +:10D0A0003E3B3A3D3A3B393B3C3B3E3C3A3B353DCF +:10D0B0003C3839383A39363C3C3A3C3C3D3B3B3CC9 +:10D0C0003A3B3A3B3A393B393D393A3E3C3B3A3CB4 +:10D0D0003B39373D3B3B38393A383B3A38383C3AB4 +:10D0E0003E3A3A3A373E3D3C3C3C3C3F3B3B3C3B86 +:10D0F0003A3A3D3B3B3C3A3E3C3D3C3B3D3C3B3D74 +:10D1000039393B3B3B3B3C3D393B3C393E393C3C70 +:10D110003D3B3A3C3C3A3C3D3B3A3A3D3A3D3B385C +:10D120003E393D3C3B3D3C3C3C3D3B3A393D3F403C +:10D130003F3E3D3C3E3B3B3C3E3F3F3D3D3B404117 +:10D14000404444474041403F3E3D3D3D413F3D40DE +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000004806108000488610800048061F800044 +:10D3C00048861F800048061180004886118000486A +:10D3D000061E800048861E8000480612800048868F +:10D3E00012800048061D800048861D8000480613F4 +:10D3F0008000488613800048061C800048861C80F8 +:10D40000004806148000488614800048061B8000EF +:10D4100048861B8000480615800048861580004815 +:10D42000061A800048861A80004806168000488642 +:10D4300016800048061980004886198000480617A3 +:10D4400080004886178000480618800048861880AB +:10D4500020001904902000320887200032C8802064 +:10D4600000325882200032E8832000327885200084 +:10D470003208872000196890200019889320000244 +:10D48000F44B200002044C200019F89120001918D8 +:10D4900095200002F44B200002044C20001938981B +:10D4A000200032A8962000326890200032F89120A7 +:10D4B000003288932000321895200032A896000090 +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D54000010090010201060A640028324600000032 +:10D5500000000000000000003C0000004006000049 +:10D5600034080000A0A0010101011900010014000D +:10D5700001001600E4000A00001478000032780070 +:10D580000000002032323232323232323232323223 +:10D59000323232323232000000000000000000005F +:10D5A000000000000000000034083408F40100000E +:10D5B0000209200019450000F16C000084D9060022 +:10D5C00029B1010010270000C409000000014B0F21 +:10D5D00000000000000000003C3C0A0A02000000BD +:10D5E0000000000001010101010040003200E803D9 +:10D5F0000F0008000A0010001000020202000300E1 +:10D6000003000A0006006400E803000004000000B4 +:10D6100000000000000000000101010101004000C5 +:10D620003200E80314000F000A00E10000000808BF +:10D630000A0028001E001E0006006400E803000027 +:10D640000400000000000000000000004006300060 +:10D6500020000100220000003A00520070008F00FC +:10D66000AF00CF00EF000F012E014F016E018E01C0 +:10D67000AD01CE01EC010F022D024D026D028D02B3 +:10D68000AC02CC02EB020B032B034A036A038903AF +:10D69000AA03C903E703FF033704000000000000EA +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000F6090A +:10D72000300046000100480000003C004300660055 +:10D730008500A900C800E90009012A0149016B011F +:10D740008901AB01C901EB0109022B024A026C02FB +:10D750008A02AC02CA02EC020B032D034B036D03D9 +:10D760008B03AE03CB03EE030C042F044C046F04B5 +:10D770008B04AF04CC04EF040D0530054D05700596 +:10D780008D05B005CD05F1050D0630064E06720675 +:10D790008E06B106CE06F2060F0732075007730752 +:10D7A0009007B307D107F407110834085208750829 +:10D7B0009108B108C608E70800000000000000005A +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F00000000000080009000B000D000F001200DF +:10D80000150018001D00210027002D0034003C00E9 +:10D81000450050005C006900780089009C00B10060 +:10D82000C900E3000001210145016C019701C70116 +:10D83000FB0134027102B402FD024B03A003FA03A0 +:10D840005C04C3043205A7052406A8063207C407F2 +:10D850005C08FC08A2094E0A000BB80B750C360DCB +:10D86000FC0DC50E910F5F102E11FD11CC129A13F5 +:10D8700065142C15EF15AD1664171418BB1859193B +:10D88000ED19761AF21A621BC41B191C5E1C951C3A +:10D89000BC1CD41CDC1C080009000B000D000F0090 +:10D8A0001200150018001D00210027002D00340073 +:10D8B0003C00450050005C006900780089009C0035 +:10D8C000B100C900E3000001210145016C0197018D +:10D8D000C701FB0134027102B402FD024B03A00335 +:10D8E000FA035C04C3043205A7052406A806320720 +:10D8F000C4075C08FC08A2094E0A000BB80B750CA3 +:10D90000360DFC0DC50E910F5F102E11FD11CC12BE +:10D910009A1365142C15EF15AD1664171418BB185F +:10D920005919ED19761AF21A621BC41B191C5E1CD8 +:10D93000951CBC1CD41CDC1C080009000B000D004D +:10D940000F001200150018001D00210027002D00F7 +:10D9500034003C00450050005C00690078008900FC +:10D960009C00B100C900E3000001210145016C01E8 +:10D970009701C701FB0134027102B402FD024B039F +:10D98000A003FA035C04C3043205A7052406A80615 +:10D990003207C4075C08FC08A2094E0A000BB80B4A +:10D9A000750C360DFC0DC50E910F5F102E11FD117B +:10D9B000CC129A1365142C15EF15AD1664171418B4 +:10D9C000BB185919ED19761AF21A621BC41B191CDF +:10D9D0005E1C951CBC1CD41CDC1C080009000B0040 +:10D9E0000D000F001200150018001D002100270077 +:10D9F0002D0034003C00450050005C0069007800B8 +:10DA000089009C00B100C900E3000001210145012B +:10DA10006C019701C701FB0134027102B402FD02DF +:10DA20004B03A003FA035C04C3043205A7052406D4 +:10DA3000A8063207C4075C08FC08A2094E0A000BBE +:10DA4000B80B750C360DFC0DC50E910F5F102E1125 +:10DA5000FD11CC129A1365142C15EF15AD16641731 +:10DA60001418BB185919ED19761AF21A621BC41B47 +:10DA7000191C5E1C951CBC1CD41CDC1C0A000B0071 +:10DA80000E0010001300160019001D0022002800CF +:10DA90002E0035003D00460051005C006900780012 +:10DAA00089009B00B000C700E100FD001C013F01A0 +:10DAB00065018E01BC01EE0124025F029F02E402B7 +:10DAC0002F037F03D60332049504FE046D05E3059E +:10DAD0006006E3066D07FE0795083309D609800A3C +:10DAE0002F0BE30B9B0C580D180EDB0EA10F6810CB +:10DAF0002F11F711BE12841346140515C0157516A3 +:10DB00002417CC176B1801198E190F1A851AEF1AE2 +:10DB10004D1B9D1BDF1B121C381C4E1C551C0A0084 +:10DB20000B000E0010001300160019001D0022004B +:10DB300028002E0035003D00460051005C006900C1 +:10DB4000780089009B00B000C700E100FD001C01C7 +:10DB50003F0165018E01BC01EE0124025F029F02BC +:10DB6000E4022F037F03D60332049504FE046D05FF +:10DB7000E3056006E3066D07FE0795083309D6093D +:10DB8000800A2F0BE30B9B0C580D180EDB0EA10F18 +:10DB900068102F11F711BE12841346140515C01515 +:10DBA00075162417CC176B1801198E190F1A851AC0 +:10DBB000EF1A4D1B9D1BDF1B121C381C4E1C551CE5 +:10DBC0000A000B000E0010001300160019001D00C3 +:10DBD000220028002E0035003D00460051005C0068 +:10DBE0006900780089009B00B000C700E100FD00DB +:10DBF0001C013F0165018E01BC01EE0124025F02A0 +:10DC00009F02E4022F037F03D60332049504FE042F +:10DC10006D05E3056006E3066D07FE079508330909 +:10DC2000D609800A2F0BE30B9B0C580D180EDB0E48 +:10DC3000A10F68102F11F711BE1284134614051599 +:10DC4000C01575162417CC176B1801198E190F1AE9 +:10DC5000851AEF1A4D1B9D1BDF1B121C381C4E1C16 +:10DC6000551C0A000B000E001000130016001900CE +:10DC70001D00220028002E0035003D004600510006 +:10DC80005C006900780089009B00B000C700E100DB +:10DC9000FD001C013F0165018E01BC01EE01240263 +:10DCA0005F029F02E4022F037F03D6033204950430 +:10DCB000FE046D05E3056006E3066D07FE079508A3 +:10DCC0003309D609800A2F0BE30B9B0C580D180E55 +:10DCD000DB0EA10F68102F11F711BE12841346142A +:10DCE0000515C01575162417CC176B1801198E1958 +:10DCF0000F1A851AEF1A4D1B9D1BDF1B121C381CB7 +:10DD00004E1C551C29002F0035003B0043004C00E1 +:10DD100055005F006B00780086009500A600B900F2 +:10DD2000CD00E300FC00160133015201740199019A +:10DD3000C001EA01180249027D02B602F102310374 +:10DD40007503BC0308045804AD0406056305C50546 +:10DD50002B06960605077807EF076B08EB086E0998 +:10DD6000F4097F0A0C0B9B0B2E0CC20C580DEF0D07 +:10DD7000870E1F0FB80F4F10E6107B110E129E1268 +:10DD80002B13B4133814B8143315A71516167D16B3 +:10DD9000DD1635178517CD170B1841186D1890181B +:10DDA000A918B718BC1829002F0035003B00430004 +:10DDB0004C0055005F006B00780086009500A600BF +:10DDC000B900CD00E300FC001601330152017401DB +:10DDD0009901C001EA01180249027D02B602F1026E +:10DDE00031037503BC0308045804AD04060563053C +:10DDF000C5052B06960605077807EF076B08EB08A5 +:10DE00006E09F4097F0A0C0B9B0B2E0CC20C580DEB +:10DE1000EF0D870E1F0FB80F4F10E6107B110E127B +:10DE20009E122B13B4133814B8143315A7151616F5 +:10DE30007D16DD1635178517CD170B1841186D188F +:10DE40009018A918B718BC1829002F0035003B00FE +:10DE500043004C0055005F006B0078008600950081 +:10DE6000A600B900CD00E300FC0016013301520109 +:10DE700074019901C001EA01180249027D02B6024B +:10DE8000F10231037503BC0308045804AD04060510 +:10DE90006305C5052B06960605077807EF076B088F +:10DEA000EB086E09F4097F0A0C0B9B0B2E0CC20CBD +:10DEB000580DEF0D870E1F0FB80F4F10E6107B1196 +:10DEC0000E129E122B13B4133814B8143315A71561 +:10DED00016167D16DD1635178517CD170B18411848 +:10DEE0006D189018A918B718BC1829002F00350014 +:10DEF0003B0043004C0055005F006B00780086003B +:10DF00009500A600B900CD00E300FC001601330126 +:10DF1000520174019901C001EA01180249027D020F +:10DF2000B602F10231037503BC0308045804AD04C2 +:10DF300006056305C5052B06960605077807EF0756 +:10DF40006B08EB086E09F4097F0A0C0B9B0B2E0C77 +:10DF5000C20C580DEF0D870E1F0FB80F4F10E610B3 +:10DF60007B110E129E122B13B4133814B8143315F0 +:10DF7000A71516167D16DD1635178517CD170B1844 +:10DF800041186D189018A918B718BC1855005500FD +:10DF900045004200000000001C02370254027202D9 +:10DFA0009002B002D102F30216033A035F03850325 +:10DFB000AC03D503FF03290455048204B004DF0435 +:10DFC0000F0540057205A505D9050E0644067A061B +:10DFD000B206EA0622075C079607D0070B08470837 +:10DFE0008308BF08FB0837097409B009ED09290A3D +:10DFF000650AA10ADC0A170B510B8B0BC30BFB0B39 +:10E00000330C690C9E0CD20C040D360D650D940D6D +:10E01000C10DEC0D150E3D0E630E870EA80EC80E39 +:10E02000E60E010F1B0F320F460F590F690F760FC7 +:10E03000820F8A0F900F940F950FBA04C904D80469 +:10E04000E704F604050514052305320541055005CE +:10E050005F056E057D058B059A05A805B705C50505 +:10E06000D405E205F005FE050C0619062706340660 +:10E0700042064F065C066906760682068F069B06F8 +:10E08000A706B306BE06CA06D506E006EB06F606E8 +:10E0900000070B0715071E07280731073A07430734 +:10E0A0004C0754075C0764076C0773077A078107FE +:10E0B00087078D07930799079E07A307A807AC0753 +:10E0C000B107B407B807BB07BE07C107C307C50739 +:10E0D000C707C807C907CA07CB07CB07FA006C00F8 +:10E0E000FA006B006400D007000028000000000068 +:10E0F0000000000000000000000000000000000020 +:10E100000200190050001E001E000C001900000043 +:10E110000100000001000000948D0300508D0300F9 +:10E12000948D0300548D03000101000078563412D1 +:10E130007856341201000000010000008C0000003D +:10E14000404000000100000070AD0200FFFFFFFF33 +:10E15000AA000000103303000700000001000000C7 +:10E16000FFFFFFFFFFFFFFFFFFFFFFFF01000000BA +:10E17000FF000000000000000000000000000000A0 +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F000000BF420324006000A0E0A0001030108102A +:10F0100032004006F6090000000C0100000000006C +:10F020000013575904060000000000000008010901 +:10F03000000132334006000028191900000E0000BC +:10F04000000E0000000E0000000E0000000E000088 +:10F05000000E0000000E0000000E0000000D030076 +:10F06000000E0000000E0000000E0000000D030066 +:10F07000000E0000000E0000000E00000000000066 +:10F08000000101000000000000000000000000007E +:10F09000000000000000000000000101010101006B +:10F0A0000001010000000101010100010000000059 +:10F0B0000100000102000000070000000107010339 +:10F0C000020314000A0A4000000078003C0000001F +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000C800C8009600C80032 +:10F0F00007078000800005050000000000000000F8 +:10F1000006010000000017003900910010001400F3 +:10F11000F9FFC4FFFF7FFF7FFF7FFF7FFA002C0115 +:10F120003200C8000A04B4B43232230500000000E3 +:10F1300000070D0000320D00000000203232323294 +:10F140003232323232323232323232323232000003 +:10F1500000000000000000000000000000000000AF +:10F160000A05000A00000000140F0012101200002F +:10F17000000000000000000000000000000000008F +:10F18000000000000F233246500000006A64504621 +:10F190003C3C3C3C08000000000000000F233246CD +:10F1A000500000006A6450463C3C3C3C0F141E2852 +:10F1B000000000000A0A0A0A0A0A0A0A0C192D416C +:10F1C0005000000046554B464646464600000000AB +:10F1D0000A0314005F00F1FF14000F000A00BC02D4 +:10F1E00000000000F8FF00007800320064002800F2 +:10F1F0000F000F001C023D011C02740400003F06BA +:10F200000000FF09F40100003F060000FF0932146E +:10F21000021E1E32020096003C003C007700C8052A +:10F22000770088090000000040063000200001003F +:10F23000220000003A00520070008F00AF00CF00A3 +:10F24000EF000F012E014F016E018E01AD01CE01C5 +:10F25000EC010F022D024D026D028D02AC02CC02B8 +:10F26000EB020B032B034A036A038903AA03C903B6 +:10F27000E703FF0337040000000000000000000067 +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F00000000000000000000000F6093000460099 +:10F300000100480000003C00430066008500A900A1 +:10F31000C800E90009012A0149016B018901AB011B +:10F32000C901EB0109022B024A026C028A02AC02FB +:10F33000CA02EC020B032D034B036D038B03AE03D8 +:10F34000CB03EE030C042F044C046F048B04AF04B6 +:10F35000CC04EF040D0530054D0570058D05B00595 +:10F36000CD05F1050D0630064E0672068E06B10675 +:10F37000CE06F2060F073207500773079007B30750 +:10F38000D107F40711083408520875089108B1082C +:10F39000C608E708000000000000000000000000B0 +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D0000201200019450000F16C000084D90600EC +:10F3E00029B1010010270000C4090000000101013B +:10F3F000010102020202014B0F00A0000000000008 +:10F400000100010101010102020202001945000090 +:10F4100002000000A46B00000000000014140A0A9F +:10F420001400000000000000141414140101010174 +:10F43000010040003200E8030F00080005009000C2 +:10F4400000001E502800B40050000400000000001E +:10F45000B4005000FA00A000000000014F010000BD +:10F460000000000068010D0D0A094B004B0064000C +:10F470000A003200C800640064000F02E8E8F800E7 +:10F48000F8000200190000006A00750081008E007B +:10F490009D00AC00BD00CF00E200F7000D01260189 +:10F4A00040015C0179019901BC01E00106023002D2 +:10F4B0005B028902BA02EE0224035D039A03D903B8 +:10F4C0001B046004A904F40443059505E9054106FD +:10F4D0009C06FA065B07BE0724088D08F808650934 +:10F4E000D409450AB80A2D0BA20B190C900C080D73 +:10F4F000800DF80D6F0EE60E5C0FD00F4210B310AA +:10F5000021118C11F4115912BA1217137013C4136C +:10F5100013145D14A114E01418154B1577159C15E0 +:10F52000BB15D415E515EF15F31536003D00440065 +:10F530004C00560060006B00770085009300A4002B +:10F54000B500C900DE00F5000E0129014601650184 +:10F550008701AC01D401FE012B025B028F02C602BF +:10F5600001033F038003C6030F045D04AE040305DB +:10F570005D05BA051B068106EA065707C9073D085F +:10F58000B6083109B009320AB70A3E0BC70B520C54 +:10F59000DF0C6D0DFC0D8B0E1A0FA80F3610C3106B +:10F5A0004D11D6115B12DE125C13D7134D14BD142E +:10F5B00028158D15EC1544169516DE161F175817CD +:10F5C0008917B117D117E717F517FA174E0056002C +:10F5D00060006B00760083009100A000B100C200C3 +:10F5E000D600EB0002011A013501520170019101B0 +:10F5F000B501DB0103022E025C028D02C102F8029A +:10F6000032036F03B003F4033B048604D4042605DD +:10F610007C05D50532069206F5065C07C607330859 +:10F62000A30816098C09040A7E0AFA0A790BF80B5A +:10F63000790CFB0C7E0D010E830E060F870F071051 +:10F64000861003117D11F5116912DA124713AF13F9 +:10F6500013147214CB141E156B15B215F2152C165B +:10F660005E168916AC16C716DB16E716EB166A008F +:10F67000750081008E009D00AC00BD00CF00E2004F +:10F68000F7000D01260140015C0179019901BC01DF +:10F69000E001060230025B028902BA02EE02240394 +:10F6A0005D039A03D9031B046004A904F404430511 +:10F6B0009505E90541069C06FA065B07BE07240886 +:10F6C0008D08F8086509D409450AB80A2D0BA20B64 +:10F6D000190C900C080D800DF80D6F0EE60E5C0FE6 +:10F6E000D00F4210B31021118C11F4115912BA121B +:10F6F00017137013C41313145D14A114E014181518 +:10F700004B1577159C15BB15D415E515EF15F3159D +:10F7100055005500450042000000000000000000B8 +:10F7200000000000000000000000000000000000D9 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000000000099 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F86000000000000000000000000000A000D20026 +:10F8700004013C0005000000000000000000000042 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF000000000000000000000000000004E565409 +:00000001FF diff --git a/firmware/novatek_nt36523_mp01.bin.ihex b/firmware/novatek_nt36523_mp01.bin.ihex new file mode 100644 index 000000000000..8ee0e4fe3d69 --- /dev/null +++ b/firmware/novatek_nt36523_mp01.bin.ihex @@ -0,0 +1,12291 @@ +:100000000002000000000000877B010000200200C9 +:100010000000020067C100009766A2F78588D9F347 +:1000200003000000000000000000000000000000CD +:1000300000000200000000000020020044BF9762A0 +:10004000000A020000000000002A0200CB94D02029 +:100050000032020000000000005202000C52006852 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F00068C10200FF00000000000000E4C826B54F +:100100000002000000000000877B010000200200C8 +:100110000000020067C100009766A2F78588D9F346 +:1001200001000000000000000000000000000000CE +:1001300000000200000000000020020044BF97629F +:10014000004A020000000000006A0200AF0FDC1548 +:100150000072020000000000009202000C520068D1 +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00068C20200FF000000000100003E92259648 +:10020000480001A2EABD0000EABD0000EABD00000E +:10021000EABD0000EABD0000EABD0000EABD000042 +:1002200048000000DD4E0000EABA0000EABA000013 +:10023000DD4E0000EABA0000DD4E0000DD4E000099 +:10024000DD4E0000DD4E0000DD4E0000DD4E000002 +:10025000DD4E0000DD4E0000DD4E0000DD4E0000F2 +:10026000EABA0000EABA0000DD4E0000DD4E0000F0 +:10027000DD4E0000EABA0000EABA0000DD4E0000E0 +:10028000DD4E0000DD4E0000DD4E0000DD4E0000C2 +:10029000DD4E0000DD4E0000DD4E0000DD4E0000B2 +:1002A000DD4E0000DD4E0000DD4E0000DD4E0000A2 +:1002B000DD4E0000DD4E0000DD4E00004800000075 +:1002C00048000000DD4E0000DD4E0000DD4E000065 +:1002D000DD4E00004800000048000000480000001B +:1002E00048000000480000004800000048000000EE +:1002F00048000000480000004800000048000000DE +:1003000048000000480000004800000048000000CD +:1003100048000000480000004800000048000000BD +:1003200048000000E8040000E8040000580700004E +:10033000C2150000C2150000C2150000C215000061 +:10034000C2150000C2150000C21500000000000028 +:100350001809000020090000E40900005E0A0000FE +:10036000A60A0000560B0000B60B0000D40B0000DC +:10037000DC0B0000E40B0000EC0B0000F40B0000B1 +:10038000060C00000E0C00001A0C00000411000006 +:100390002C0C0000100D0000580D0000600D000036 +:1003A0009E0D0000B00D0000C20D0000E80D000021 +:1003B000860E0000020F00000A0F00001C0F000054 +:1003C000F8120000FA1200001E13000026130000AD +:1003D0002E1300003E130000401300004C130000D9 +:1003E0005A13000076130000000000000000000017 +:1003F000F4140000101500005C150000A4150000A6 +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:100450003A0FEFFC421E80203A1F883C6412A4022F +:10046000642204023A1F883C803F640264029205C1 +:1004700096374420012C38210202643200029ED9B2 +:1004800064320003DD2264020043640000083A1F66 +:1004900088046412A403642204033A1F8804421EE1 +:1004A00080213A0FEFC4640000043AFFECBC3A0F1D +:1004B000943C421E80203A1F883C640264029205EC +:1004C00096374420012C382102028E09DD223A1F82 +:1004D0008804421E80213A0F94043AFFEC846400A1 +:1004E00000043AFFECBC3A0F943C421E80203A1FB5 +:1004F000883C6412A402642204023A1F883C64020D +:100500006402920596374420012C382102028E099C +:10051000643200029ED964320003DD22640200438B +:10052000640000083A1F88046412A40364220403D0 +:100530003A1F8804421E80213A0F94043AFFEC844B +:10054000640000044FF200223A0FEFFC421E8020AC +:100550003A1F883C45D2D770801F64126402965FB0 +:100560009E49C1053CFD4A6D480000043CFD4A6EB1 +:10057000E80CDD2F4E03000A3A1F8804421E80213A +:100580003A0FEFC464000004640224024410C00067 +:10059000FE0FFE0D640224036400000845D2D770EC +:1005A00045F2FE006400800292189604C0054401E2 +:1005B0004D04420E002144F004BAE802DD2F3CFD58 +:1005C0004A6FDD2F640FFFEAFC004462EDE4440251 +:1005D000C36884209AB0EA3FEA40AE31FC80FC0058 +:1005E00084003C0FFB78EB6E3C0FFB873C0FFB8BD2 +:1005F000EB7A3C0FFB9C3C0FFB813C0FFB8C3C0FD0 +:10060000FB883C0FFB943C0FFB893C0FFB853C0FA8 +:10061000FB823C0FFB7B3C0FFB9A3C0FFB9F3C0F8C +:10062000FB923C0FFB933C0FFB903C0FFB76EB20C7 +:100630003C0FFB8A3C0FFB80EB67EAA63C0FFB7D7F +:100640003C0FFB7F3C0FFB9E3C0FFB913C0FFB994B +:100650003C0FFB863C0FFB7C3C0FFB8E3C0FFB7E74 +:100660003C0FFB8D3C0FFB953E07EC7964030003C8 +:10067000EA81EB6564122402964C8040C103640356 +:100680000003642224036402000266000006640280 +:100690000003640000086403040246029C1050003A +:1006A000007CEA816403080244000633EB656402BF +:1006B0000002EA5464020003FC804403F0EDA6400B +:1006C0005A1801048420AE404413F0DAA608EB2641 +:1006D000AE088404EA8184254403F049AE40441006 +:1006E0000053DD46AE40DD9EDD9E4443F114B4640C +:1006F000927840000F04B6044403F138AC408420E3 +:100700004403F13AAE404403F104B640842144036B +:10071000F136AE40F808A640964CC103AED0D5FCE9 +:100720004413F134EA38EA3783FFA608960EC8036B +:10073000AED0D5FC4403F134A6009604DD9E84A01F +:10074000D20738301400383094088CA1D5FADD9ED9 +:10075000FC00DD41C00C8407DD4A8400DD4A441200 +:10076000C2688402804144300100DD44FC80FC000A +:1007700080C0DD41C012441FFF9FEBBBAE409630EE +:100780004412FE61AE08EB684412FE62AE08DD461C +:10079000DD47C603AE40D5FEFC80FC403C7DFB4DF2 +:1007A0008140DD41C05B852384C03C2DFB4D402151 +:1007B0002480A051C108F85C5A0801064010240C9E +:1007C000FF8F97B18D215A980FF2F85F5A080104F4 +:1007D00042633C088387B97DB87C8E249649BA7FF2 +:1007E000F85C5A08010558630001D502C6055AA8ED +:1007F000AE048006F8118420EB1FAE404402FE6375 +:10080000A6408420AE40A681AE4149000FD55A08CB +:1008100001065803000249FFFFACEA6FEA28EA210B +:10082000A78097B05A600204AE88D5FB4472FEF1EF +:10083000A6385A008608440000C1DD42F87FAE4069 +:10084000D5FF490036F784003E07EE758027800605 +:100850004422C5E58461DD44FCC05AA8AE4B84E364 +:1008600080C03C2DFB4D40211C80A051C10BB40227 +:100870009649A093F8125A08010640001C0CFF8705 +:1008800097B18CE15A780FEF3C2DFB4D8382B93D37 +:10089000B83C8E249649BA3F49FFFF295A08010502 +:1008A000EA6D42633C0884204402FE78AC40441266 +:1008B000FEF1EA6FC619442FFFEEAE888422AE40E7 +:1008C0004412FE60440FFF8FAE084422FE61963052 +:1008D000AE10EB6896004422FE62AE108463804145 +:1008E0008402DD44D520442FFF86AE888422D507BC +:1008F000441FFF86EB1FAE408422EA6FAE404403E4 +:10090000F007A6004412FE639600AE084403F0040C +:10091000A6004422FE649600AE10840280418060EE +:10092000DD4484C04412FEF1804184618402DD44D0 +:10093000EA26804184028461DD44DD46DD4783FF91 +:10094000C603AE40D5FE4412FEF1EA38EA37A608E7 +:10095000C003AED0D5FDFCC03A6FA0BC840080209F +:1009600049006BBB84006405E403EBA0A4409666D9 +:100970009649C102D5004422FEF6AE50A440964EE0 +:10098000C910A4409656C90DA440965EC90AA44059 +:100990009666C907A4405410810096494E120085FE +:1009A0004413F00EA408960EC806A58854630100EF +:1009B00097B1C6208400EAB0A788AC0844138D2004 +:1009C0003E07EC25AE0844138D21AE0844138D225A +:1009D000AE0844138D23AE0844138D24AE0844138F +:1009E0008D25AE0844138D26AE0844138D2797B08D +:1009F000AE0849FFFDEB49000D6FEBA0A440964EF9 +:100A0000C908A4409666C905A40054000100C003AB +:100A100049003446EBBB8420AC404472C16884007A +:100A2000EAA63C7FFB4DEB673C0FFB96DD41C8051A +:100A3000507381003C7FFB4D49FFFE8C800649FFCF +:100A4000FEAE8423EA6FAE4084014413F7D3AE08B0 +:100A50004413F7D9AE08FA56EA824412FE7849FFE9 +:100A6000FE703C0DFB4D4432FE7C040000093E0745 +:100A700028AD401020093E1728AE401040099218BA +:100A80003E1728AF3E0728B04422FE7DF8054432C9 +:100A9000FE7E4422FE7FA618A6509602964AAE58C5 +:100AA000AE1083FFD508A40054000200C0048402E5 +:100AB00049000F1D4413F029A608EAE0AE0884009F +:100AC000EA633C0DFA6A4413F00EA648EB87441320 +:100AD000F00FA6481010003D4900344A3C0FFB5B64 +:100AE000FA0449005448FA04490054452E07ED6CB5 +:100AF000DD4AEA429E81E648E80B84214010880CDA +:100B00005410808FC10550007FE09600DD424900FF +:100B100006823A6FA084DD9E84013C0FFB78DD9E47 +:100B20003BFFFEBC3C0DFB838C01EB6EDD455A08A0 +:100B30000246DD40A6015A08033EDD535A08023B37 +:100B4000DD41C03C2E07EBFCE603E8038C01D50237 +:100B500084003E07EBFC2E37EBFC4402E5D8EB5556 +:100B600040000CE0EAA0EA85EAA0EA85EAA0EA856E +:100B70003B0044003B00C4205A3801068400EAF6DA +:100B8000EBF8D5098406EB614400007DEBA28401FB +:100B9000EAF6EBF5EAA19E41E622E9035A08040FC2 +:100BA00049004AAF4900946AC0098400EA3CEB134B +:100BB000D505DD41C0038400EB192E07EF565A0816 +:100BC00001103C1DFB832E07EF55E220E803EBF5F7 +:100BD000D507EBF88400EAF684003E07EF563BFFAA +:100BE000FE84DD9E3BFFFEBC3C0DFB878C013C0F71 +:100BF000FB87DD40A6008E01E602E82D2E07EC2AD9 +:100C00005A08550A3C03F64C8C019601E60AEBBCE7 +:100C1000E91DD508DD41C0182E07EC215A085515ED +:100C2000D5F28404DD4284013E07EFA28400EA2C61 +:100C3000DD40A6005A080105EAAAEA6CD5078E0233 +:100C4000E602E900D5038400EBBCEA433E07EC2A48 +:100C5000EA9FD5038400EBBC3BFFFE84DD9E3A6F28 +:100C600098BC4403F06BA6003E07EC77DD45C80650 +:100C70002E07EC77961F5A000F16FA10DD428401FA +:100C80003C0FFB8BEB844900700DDD408422DD5767 +:100C9000490070228420840284468061808180A182 +:100CA000DD56EA23DD9E3A6F9EBC49006AD2C01829 +:100CB000840049006AD2F82380C05A080112DD4539 +:100CC0005A0802043C6FFB8444000080DD42DD4092 +:100CD0004412C3D8EAD5EB9184814900234E4900E0 +:100CE0006AAFC00784013C0FFB97840049006AACDF +:100CF00049006ADFC026840049006ADF49006B2B87 +:100D00005A080120EA89A6005A08130EDD55A608E4 +:100D10008E02E603E904A6095A0808068420EA8937 +:100D2000AE40D51784C1440000803C6FFB77DD42A4 +:100D3000DD404412C3D8EAD5EB9180864900231DDB +:100D400049006AAEC006840049006AAE8401EB67C0 +:100D50003A6F9E84DD9E3BFFFEBCDD5984213C1F23 +:100D6000FB98AE40EA4044238D433E07EC2AA61090 +:100D70008801AE10DD40A681542100FD5A200403F5 +:100D8000DD5749006F82C00A8409DD42FA18EA3251 +:100D90008403EA9684013E07EC4E2E07EF1F8C0178 +:100DA00096003E07EF1FDD41C80484013E07EF0DAA +:100DB0003BFFFE84DD9E3A6F98BC84013C0FFB9C98 +:100DC000FA11DD424403F082A600C003EAAAEA6CED +:100DD000EA23DD9E84013C0FFB81DD9E84013C0FF4 +:100DE000FB8CDD9E84013C0FFB88DD9E84013C0F63 +:100DF000FB94DD9E3A6F98BCFA12DD4284013C0FF1 +:100E0000FB89EA23DD9E84013C0FFB85DD9E3A6F62 +:100E100098BCFA13DD42EA23DD9E3A6F98BCFA14BF +:100E2000DD4284013C0FFB7BEA23DD9E3A6F9ABCD6 +:100E3000EFF43C0DFB9AC81EEBC4C01CDD412E171D +:100E4000EF065CF080A0C80BE915441358904423CA +:100E5000806844300C808402EA71D50CE90B2E07BF +:100E6000EF03C8038401D5045A08010584023E0734 +:100E7000EF034900168C3C0DFB9A8C013C0FFB9A4A +:100E8000EA678C013C0FFB8E2E17EF0AEA67E2201F +:100E9000E805EA6796003E07EF0AEA67EA66960009 +:100EA000EAF1EAB9EB9EEB29EA664900133D3E07F9 +:100EB000EC28DD41C005EBA9C8038401D508DD415C +:100EC000C805EBA996005A0001038400EBC9EB8A20 +:100ED0005A08010B84003C0FFB75440124F83C0EBA +:100EE00003024900160A3C6DFB9A5A68020F3C0D3A +:100EF000FB7F5A08010BDD41C808800644139700A8 +:100F000044238D54EA90EA71EC0C3A6F9A84DD9E8A +:100F10003A6F98BC84013C0FFB863E07EF4C4403BC +:100F2000F07EA6405A10010FA6405A10020CA640AF +:100F30005A100309A6405A100406A6405A1010037E +:100F4000A60084418420806280824400B101EAA925 +:100F500049002E11EA23DD9E84013C0FFB9FDD9E9C +:100F600084013C0FFB924403F064A640964CC910E8 +:100F7000A64058108001AE40DD40A6008E02E60279 +:100F8000E90E3A6F98BCEA43EA6CEA23D508A6401A +:100F9000964CC105A640EB1BAE40DD9EDD9E3A6F30 +:100FA00098BCFA15DD4284013C0FFB93EA23DD9ED9 +:100FB0003A6F98BCFA16DD4284013C0FFB90EA239D +:100FC000DD9E3A6F98BCFA17DD42FA04DD4A8401CF +:100FD0003C0FFB76490018B05A08A104EA43EA6CBA +:100FE0008403EA96EA23DD9E3BFFFEBC84013C0FAE +:100FF000FB99EBFE44138D468C01EB20A6088C0177 +:10100000AE0849000DE6EB8AC814DD41C005EBA926 +:1010100096005A000107DD41C805EBA9C803840109 +:10102000EBC984003C0FFB75440061A83C0E030231 +:10103000490010D5DD41C021DD5B5A08201F2E0775 +:10104000EF035A08020CEBFE5A080114EB1544207A +:1010500019004402988CDD49D50C5A08030B845FB3 +:101060004452988C80624402B18C3A228C24D8FE7F +:101070008401842049001A9CDD41C8034900158E73 +:101080003BFFFE84DD9E3A6F98BCFA18DD424403B4 +:10109000F00AA600DD424403F00DA600DD42EBA0FD +:1010A000A600DD424403F00FA600DD424403F01A1F +:1010B000A600DD424403F01BA600DD424403F0829B +:1010C000A600DD424403F353A600DD424403F36966 +:1010D000A600DD424403F386A600DD424403F38705 +:1010E000A600DD424403F3CFA600DD424403F40C26 +:1010F000A600DD4284013C0FFB8AEA43EA6CEA2346 +:10110000DD9E84013C0FFB80DD9E4403F403A600BA +:1011100096005A0801043C0FFB7DDD9E84013C0FC4 +:10112000FB7FDD9EFC0084013C0FFB7F84003C0FB5 +:10113000FB8E3C0FFB7EDD40A6419E8BE642E9051F +:101140005A1006045A180D4BDD54A6485A18014788 +:10115000EA41EBA6C80AEB8BC808EBB4EB69D005F3 +:101160004402C4AC49006BDEDD40A6015A00030412 +:101170005A080D15EB3FC812EBA6C810EB8BC80E32 +:10118000DD4CA600C8048020EBFAD5069E43E6227B +:10119000E805EBFAA65049007165EAA1C0048E0487 +:1011A000E602E80784203C0DFB5880418061D5149D +:1011B000DD41C0043C6407F6D5033C640836DD41DC +:1011C000C0043C2407F7D5033C2408373C0DFB58EA +:1011D0009671969184614900725BDD41C0034900BC +:1011E0001061DD55A6095A000D079E82E642E9030B +:1011F0005A08072CA6485A180129EADA9600C8416D +:10120000DD54A6485A18013EDD58A6485A18013A3E +:10121000EB20EB8B5A0801064402C3CF49003890FB +:101220008420DD40DD578401EA2CDD548400AE08C3 +:10123000DD58AE08840AEA498404DD4A2E07E9A095 +:10124000DD4A8401EA7FD51D5A08041C2E67EF137E +:10125000CE18DD58A6485A100215DD4AEB3A0400B4 +:101260000008962FDD4ADD408026EB3BDD578401E8 +:10127000EA2CDD59AF80DD4BAF8084013E07EF13D0 +:10128000EB0C5A080104490015D4FC80FC20EB3A11 +:101290003C5DFFD7D0073C5DFFD8D004EBA65A08D1 +:1012A000010DEADAC80ADD59A6009600C806DD5825 +:1012B000A6885A280103AE082E07EC1AC023EB17A4 +:1012C000EACAD8202E67EBFA840097B03E07EC1AE2 +:1012D000CE19DD59A6005A080116DD4BA7C097F8B4 +:1012E0005A7801118026DD40EB3BDD578405DD4A4D +:1012F0008007EA2CDD59AF802E07EC4EC803DD587D +:10130000AE08FCA03A6FA6BC4900083DDD41C80A02 +:101310002E07EC795A080104480000ED84013E07CD +:10132000EC794900391580C0EA8380E044038D459B +:10133000A6808C41AE80EBC4C0178401DD4ADD413C +:101340008120C00749000953840049001483D50C4B +:101350004412C46C804184648402DD4480094900E5 +:101360001479490007E1DD41C02C3C53F7D83C0318 +:10137000F7D7D00E2E27EFAC8C4196903E27EFACDE +:101380002E27EFAC50017F909600DD42D5048400FB +:101390003E07EFAC3C03F6DAC8083C03F6DBC805B1 +:1013A0002E07EFACE605E90D84013C0BF7DA84006B +:1013B0003E07EFAC4412C724840280418060DD44C4 +:1013C000EBC4C00984013C0FFB8F3E07EBFD49FFD6 +:1013D000FEABD50984023E07EBFD49FFFF59DD59FD +:1013E000A600F8D2840085213C9FFB963C0FFB9A17 +:1013F0002E07EC49C014DD41C0060003000F1003A6 +:101400008051D5088402501380515023000F806909 +:10141000DD4484003E07EC491003000FDD41C803A2 +:1014200049003D1284003E07EC79490007D33C0394 +:10143000F7DA5A08012784003C0BF7DA2E07EFB2DF +:101440005A00FF082E07EFB28C0196003E07EFB25C +:101450003C03F6DA4412FE6A9600AE083C03F6DB63 +:101460004412FE6B9600AE08844184003C0BF6DA11 +:10147000FA313C0BF6DB80624400D1B08082EAA9ED +:10148000DD455A080238EBC4C035DD40A6015A08D4 +:10149000032E3C6DFB3F5A68022ADD41C02B3E679C +:1014A000EBFCEB554402E6D8EAA0EA85EAA0EA851F +:1014B000EAA0EA853B0044003B00C4208406EB61BF +:1014C0004400007DEBA28401EAF6EBF5EAA19E411F +:1014D000E622E9035A08040F4900461349008FCE5B +:1014E000C0098400EA3CEB13D505DD41C00384004C +:1014F000EB193A6FA684DD9EDD9E3A6F98BCFA190F +:10150000DD4284013C0FFB9E490061B0EAA2C804A1 +:1015100049006BC8D50349006174EA23DD9E84014C +:101520003C0FFB91DD9E84013C0FFB7CDD9E3A6FFE +:1015300098BC8403DD4A8401EA7FEA23DD9EDD9EB8 +:101540003A6F98BC8401F806EA23DD9E3A6F98BC96 +:10155000840049000EE7EA23DD9E3A6F98BCFA1B2F +:10156000DD428400842A49002F02DD41C003EAAA3B +:10157000EA6CEA23DD9E3A6F9EBC4403F41CA6008D +:10158000E6024EF200AE49000E96DD41C012DD408B +:10159000A6015A08030F2E07EC13C00B8400441257 +:1015A000DEE43E07EC138041840244300320EA71FC +:1015B000DD41C01CEB27A6C096D85A3801188420FC +:1015C00084C044002330804180833C6BF6DA3E3790 +:1015D000EFB3EAA996013C0BF7D82E07EFB35A00F8 +:1015E0000203F80D3C6BF7D8F80ADD4180C04E03CA +:1015F0000078EB27A7C097F85A70010448000071E3 +:101600004400BB908026FD1380873E77EFB3EAA9A4 +:101610003E07EFB82E07EFB35A08020B3E67EFBC48 +:101620003E67EFBD3E67EFBE3C6BF7D7D51A80260D +:10163000FD1380874400AB00EAA93E07EFB980267E +:10164000FD1380874400AB01EAA93E07EFBA80266C +:1016500044002330FD138087EAA996013C0BF7D79D +:1016600084003E07EFB34412C71E840280418060AD +:10167000DD443C03F6DBC8342E07EFB8C80A2E075A +:10168000EFB9960EC8062E07EFBA96024E0400294F +:1016900084013C0BF6DB2E07EFB8C0074400009D29 +:1016A000DD422E07EFB8DD422E07EFB9960EC007D8 +:1016B0004400009EDD422E07EFB9DD422E07EFBA4F +:1016C00096024E0400084400009FDD422E07EFBA48 +:1016D000DD4284024412C52680418060DD442E072D +:1016E000EC4BC0068401EBD984003E07EC4B3A6F0B +:1016F0009E84DD9E3A6F98BC4413F7EEA6089600D0 +:101700009684C203EAA4AE088400F858EA23DD9E5A +:101710003BFFFEBC84013C0FFB954413F7EFA6088A +:1017200096009684C203EAA4AE088401F847F8291B +:10173000EB8A5A08010C3C0DFB70C006840249007C +:1017400008213C0FFB70490011D82E07EF0DC00493 +:101750008E013E07EF0D3BFFFE84DD9E3BFFFEBC8E +:10176000DD455A08020584013C0FFB8D4413F7C97F +:10177000A60896009684C203EAA4AE088400F81E68 +:1017800049000B86DD41C80CEA89A600C009DD408E +:101790004412C3D8EAD5EB91848149001DEE3BFF8A +:1017A000FE84DD9E3A6F98BC4413F7CAA6089600E3 +:1017B0009684C203EAA4AE0884014900076CEA23B8 +:1017C000DD9E3BFFFEBC2E07EC7AC81DB401A600CF +:1017D0003C0FFBF1640264024412FFF03C0FFBF08B +:1017E000B6013C1DFBF14402FFF4B6204601122372 +:1017F000500003444412FFF8B6012E07EC7A8C0126 +:101800003E07EC7AFA1ADD42EAAAEA6C3BFFFE8454 +:10181000DD9EFC6384003C0FFB6849003B305A00AE +:10182000081749003BB02E07EFC8441000A08C01F8 +:101830003E07EFC88403DD43840DDD4A49003BE1E8 +:10184000840EDD4A8403441000A1DD43B1C34492F9 +:10185000E84E44A0012CDD414E02007E3C1C0307F3 +:10186000442397EC40110420A448440397D8964B96 +:10187000AC403C0C0308441397DA40010020A4005C +:101880009603AC08F86849003BF75A0003CC5A08A5 +:101890000207840444100060DD43D5C65A0013DDFE +:1018A000F86EF8725A0002C15A0013D7F872DD4B75 +:1018B000A78097B0CED12EB7EC755AB801CE84036D +:1018C000EBADDD43DD533E67EFAA5A08020649003F +:1018D00041763EB7EC1349003CF9DD5B5A0812092A +:1018E000EAAC8420EAC95A0801048400F82FDD5BC1 +:1018F0005A08040849004366EAC5F8B7F826D5280F +:101900005A081406EAC5F8BAF820D5225A0819066A +:10191000840080204900164C49003D254900443C84 +:101920005A08020448FFFF81DD5B5A080508490098 +:101930004348EAC5F8F8F809D50B5A08150AEAC56C +:101940008403441000A9DD43EA50EA2EEA3A490034 +:101950004315F94B8403441000A2DD43490046BF00 +:1019600080C08401EBFC5A08010448FFFF945A68C8 +:10197000030448FFFF585A681303F93784034410DF +:1019800000A3DD43EB034900462F5A081303F92D4A +:101990008403441000A4DD43DD4BA600C807DD40EE +:1019A000A6415A180D048423AE41440000A3EB75F0 +:1019B000EB634E0301002E17EC12440297E8490036 +:1019C0001FFBF081EBAD8403DD433C6DFB648006BF +:1019D00049003F505A6806132E07EF755A08010F49 +:1019E0002E07EF74C80BEA4BC8092EB7EC414EB373 +:1019F0000006490072803EB7EF752E07EF76C82FBC +:101A0000EA4BC02DE6C2E82B3C0C030B5A0007053D +:101A1000EA7B5A0809258404EAF5800649003CFB64 +:101A2000EA4B4E6300E5EA7DEAC1EA4B5CF0003028 +:101A3000E9162E100C1484013E07EF76C9068427A0 +:101A40003C1E030BF805D50B8407EA6284003E00B8 +:101A50000C14EBB9EAC183FF8405EAF5800649005E +:101A600040ECDD5B5A0814098403441000A6DD43F2 +:101A7000F85E4800009E5A68040D8403441000A7D5 +:101A8000DD4384003C0FFB7149003CB5EAF5D554B9 +:101A90005A68050EEB365A08035049003CAC5A0808 +:101AA000034C8401EAF58400EA93D546EA4BC84426 +:101AB000E6C2E8368006490041265A6801328006AF +:101AC000490042103C0DFB715CF00BB8E8048C013E +:101AD0003C0FFB7184003E07EC06EB368E04E602F9 +:101AE000DD5BE90F5A00150E3C1C041A5A10050361 +:101AF000C90584203C1E0304D50484223C1E030433 +:101B00008E14E602E90BEBBEC8073C00086CC00669 +:101B10008E01EA93D5033CA8086C8400EB19DD5BC9 +:101B20005A08150B8403441000A8DD433C0DFB52FA +:101B3000EB0849003DF1F001EB554422E3A04900D8 +:101B400020E3DD5B8E14E602E90AEB0CC808EABC70 +:101B5000C0042E07EBF9C803EBDBC005EAADC803F0 +:101B6000EB42C026EB369E42E623E80A84223C1F65 +:101B7000FB3F5A08031E8401EB198401D50F5A0854 +:101B800005078400EA9384013E07EBF93C10086CDA +:101B9000C90F8401EA353E1010DEAC381493800280 +:101BA00014938001EB283A138C0049000F0E840136 +:101BB000EADD2E07EC5C5A080512DD59A6005A082A +:101BC000010EEA9A5A08090B2E17ED482E27EC56FB +:101BD0002E07EC5C49000C01F8082E07EC5C5A005B +:101BE0000603F8038400EADE48FFFE37EAAEEAC1E6 +:101BF00048FFFF1D3C0FFC06DD9E3C0FFC05DD9EF3 +:101C00004402B7F43C0FFBF5DD9EFC4180E18123EB +:101C1000CC09B400C2090260001F0220001E97B365 +:101C2000D50CA001CA05A580A48197B3D506026092 +:101C300000310220003097B3802696938007490038 +:101C4000491E001480005A10FF058C218801920162 +:101C5000EA34803FB0814900497AB41F38138111BA +:101C6000F00138238111840240008016420308737A +:101C7000EB24FCC1FC60B480C311C4079F64E6A2DE +:101C8000E90484A01050007D2E57EC3C2E67EBFE3B +:101C90005C5280015CA30001D503814380A34E42C6 +:101CA00002818E84E6824EF3027D80C0A60C8123E1 +:101CB000816280E14E0300854E530083EB7FC32891 +:101CC000A0D13C5DFB59A498A519020180310231D5 +:101CD0008030EBE196939723960396DBE807EBDCE5 +:101CE0005A58010550108510F81100538008CD0492 +:101CF0008A44EBC1D5055A5831088A03EB86E904BA +:101D00008401EB9CF8035010828848000257501061 +:101D100088465033006E84408082800BEBD43C4375 +:101D200047283C53474897219B65404214068060F2 +:101D300041107C0AA03DA07CFF2294019521412006 +:101D400007F5404217F50423800A0503800B9449E8 +:101D500095694E9200254208942442020C73424237 +:101D60008C69884388A0980CEB4E40491400EADC4B +:101D70004058C00088248865EA53EBE8EB53C00460 +:101D800044F007D0D50344F00BB8EBEEE20F4EF26F +:101D9000008FEBB84E03008C480000893C07F4B676 +:101DA0003D37F4BAFE1C40004C1641307C0A4339E2 +:101DB000942443320073424280694800008BA63D60 +:101DC0005A001F04480000924E530090EB7F4E9241 +:101DD000002C043580013C5DFB59A498A519020133 +:101DE000803102318030EBE196939723960396DBA6 +:101DF000E807EBDC5A580105501085B2F813005380 +:101E00008008CD048A44EBC1D5055A58310A8A03AB +:101E1000EB86E9068401501080A2EB9CF803501079 +:101E2000832A480001CF501087A45033006E8441AC +:101E30008480800BEBD43C5347473C43476797690A +:101E400088858060A03DA07C40521406940195696D +:101E5000412007F5EB970423800A0503800B41110D +:101E6000FC0A944995214E92002642089024EBF6F4 +:101E700042420C69884388A0980CEB4E40491400FC +:101E8000EADC4058C00088248865EA53EBE8EB534D +:101E9000C00444F00708D50344F00AF0EBEEE20F6B +:101EA000E806EBB8C80444000C7FEBE80203000826 +:101EB000D5243C07F4B73D37F4BAFE1C40004C165D +:101EC00041307C0A43399024433280734242006996 +:101ED00088B3980C884388B2EADC4048C000EB4ED7 +:101EE00088258864EA53D510841F4E92000A100397 +:101EF000006C22030004EBE812030018D50710035E +:101F0000006E0203000C1203000EA63E4E03009466 +:101F10004EA30092EB7F4E92002BB46B3C5DFB65B1 +:101F2000A498A5190201801F0231801EEBE196934F +:101F30009723960396DBE807EBDC5A58010550100F +:101F40008654F81300538009CD048A44EBC1D505AB +:101F50005A581F0A8A03EB86E9068401501081440F +:101F6000EB9CF803501083CC480001305010884699 +:101F70005033006F84408481800BEBD4806041003B +:101F80007C0AA03F3C5346C4A07E3C4346F69401E5 +:101F90000423800C0473800D4E92002E97699B2CB5 +:101FA000E2A4525780009569EB979521411007F5FF +:101FB00042081024EBF642420C69944988A08843F9 +:101FC000980CEB4E40489400EADC88F0882488673F +:101FD000EA53EB8FEB53C00444F007D0D50344F031 +:101FE0000C80EA92E20F4EF2009DEBB84E03009A8D +:101FF00048000097413007F53C07F4B897699B2CDF +:10200000FE1C3D17F4BAE2A4411046365257800038 +:102010009569EB974008FC0A9521FE244202C4739F +:1020200042424469944988A0980CEB4E40F99400D0 +:102030004800008FA63F5A003104480000914EA38B +:10204000008FEB7F4E92002BB46B3C5DFB65A49838 +:10205000A5190201801F0231801EEBE196939723A0 +:10206000960396DBE807EBDC5A580105501086F61C +:10207000F81300538009CD048A44EBC1D5055A58A2 +:102080001F0A8A03EB86E9068401501081E6EB9C67 +:10209000F8035010846E4800009D501087A4503300 +:1020A000006F84418082800BEBD43C5346F53C4367 +:1020B000472797698885A07F806040521406A03E1C +:1020C000944995690423800CEB970473800D4101BA +:1020D000FC0A401083F54110040895214E9200251A +:1020E00042081024EBF642420C69884388A040085D +:1020F0009000E2118825EADC88F0882F8867EA538F +:10210000EB8FEB53C00444F00898D50344F00C80E7 +:10211000EA92E20FE806EBB8C804440013FFEB8F25 +:1021200002030009D5243C07F4B93D27F4BAFE1C8C +:102130004000481641207C0A432910244322807322 +:102140004242006988B240089000E2118825884325 +:10215000EADC88F0882F8867EA53D518841F4E92EE +:1021600000121003006D22030005EB8F120300190B +:10217000020300083C0BF7E8020300093C0BF7E9F7 +:10218000D52C1003006F0203000D1203000F020391 +:10219000000C3C0BF7E60203000D3C0BF7E7D51DE6 +:1021A000843FC3061010006C1010006DD51610107F +:1021B000006E1010006FD5115033006C48FFFDAD5C +:1021C0005033006C48FFFE355033006D48FFFED49D +:1021D0005033006D48FFFF67FCE05A0001054403DF +:1021E000F7DED5034403F7DD44100069AE40EA2969 +:1021F0008420AE40DD9E8401DD9EFC204473F0808F +:10220000A7B897B05433001F583180A0AEF8DD490D +:10221000AFB8FCA0DD5A8E01EAD4DD9E4410005513 +:10222000DD46AE404413F7F1A6089604C003EA2940 +:10223000D5FCDD9E44100055DD46AE404413F7F05A +:10224000A6089604C003EA29D5FCDD9E4443F7FDA9 +:10225000A72097205A08010558020008D503540208 +:1022600000F75A180104EA7AD503540000FB5A28F3 +:102270000104EA95D502EB2D5A380104EA54D5023F +:10228000EAA44413F7FDAE08DD9EFC2180E0840043 +:10229000EA2A8400802084418060506F8007F837EC +:1022A000C703EA40EA2A84214403F7C0AE40442F22 +:1022B000FFE74403F7C3AE8096B04403F7C6AE8091 +:1022C00084404403F7C1AE8084774403F7C4AEC0B2 +:1022D000EB6896004433F7C7AE184403F7C2AE80EC +:1022E00092D084434403F7C5AE8097B0EBB5AF807E +:1022F0004403F7CCAE40EA388020EA37A6089600BF +:10230000C003AED0D5FC80208040806049FFFFA094 +:10231000FCA184004412D6C0845FEACD8C015A0827 +:1023200009FEDD9EFC2084204432D6C04442FE5D7E +:102330004452FE5C44638D4144738D4038018400F7 +:1023400096885A00FF1CE648E81944F021583827BF +:10235000880040F13C00DD0F081014181C222220D8 +:102360003C2DFB54AE10D50AAE38D508AE30D5069C +:10237000AE28D504AE20D502EBC08C215A1809E056 +:10238000FCA04403F7C0A6404402EC2CAE4044132A +:10239000F7C3A648AE434413F7C6A648AE46441357 +:1023A000F7C1A648AE414413F7C4A648AE4444134F +:1023B000F7C7A648AE474413F7C2A648AE42441337 +:1023C000F7C5A648AE454413F7C8A648EBCBDD9E3B +:1023D000FC00EA4C4402EC2CA6804413F7C0AE8803 +:1023E000A6834413F7C3AE88A6864413F7C6AE8807 +:1023F000A6814413F7C1AE88A6844413F7C4AE88FF +:10240000A6874413F7C7AE88A6824413F7C2AE88E6 +:10241000A6854413F7C5AE8800100008EBB5AE40A2 +:10242000FC80FC4081405400807F80C180E2812399 +:102430005A087F05440000C8DD42EA4C5AA8010A48 +:102440008400F9B0EB748420AE404403F7CBD5038D +:102450004403F7CC542480FF4413F7C0AE8896B0F1 +:102460004413F7C3AE8896B84413F7C6AE88401439 +:10247000A00996484423F7C1AE504013200996485E +:102480004423F7C4AE504013A00996484423F7C72D +:10249000AE504014C00996484423F7C292D0AE50C3 +:1024A00097B04413F7C592F0AF8897F84413F7C874 +:1024B000AFC88421AE40EA38EA37A640C103AED0A7 +:1024C000D5FD5AA80107800AF96DEBF4EB74AE4014 +:1024D0008401FCC0FC004403F02CA7804413F3ECFF +:1024E0008401AE0884474413F3EDAE884413F3EE41 +:1024F000AE084413F3EFAE084423F3F08420AE504B +:1025000084644423F3F1AED04423F3F28462AED06A +:102510004423F3F3AE5097B04413F3F4AE0896742B +:10252000C9455413000296484423F439C1063E07B6 +:10253000F01F8403AE10D5043E37F01FAE50EA4CB6 +:1025400097968401F8D397B08400F8D0C60584012B +:102550003E07E9C4D5033E67E9C4DD5A5A080207BD +:102560004413F02DA608EA54AE084401D8004412E2 +:102570008E10442025A049FFFE42441FFF86EB1F1A +:10258000AE408420EA6FAE40441000404403F6CAD7 +:10259000AE40FA214403F697AE40FA2F4403F38489 +:1025A000AE4084214403F380AE40DD5A5A00011E40 +:1025B0004605555A4412C12C50000AAA3C0FFA6F26 +:1025C000804184028464DD44DD46DD47AE4046053B +:1025D000A5AA500005A53C5DFA70D8FE460123452A +:1025E000500006783C0FFA70FC80FC0049FFFE9317 +:1025F000DD4B4412D6C0A600AE08DD4CA600AE09E5 +:10260000EBAAA600AE0A4402FE5CA600AE0B440292 +:10261000FE5DA600AE0CEBDBAE0F80418469840248 +:10262000DD44FC80FC20440000C6DD424403F7C0CA +:10263000A600DD424403F7C1A600DD424403F7C211 +:10264000A600DD424403F7C3A600DD424403F7C4FD +:10265000A600DD424403F7C5A600DD424403F7C6E9 +:10266000A600DD424403F7C7A600DD42EBB5A60095 +:10267000DD424462FE504472FE5608030001DD4212 +:102680004C63FFFDEB27A600DD42440000C7DD429E +:10269000FCA0FC004423F7F0C80380A2D5034453F8 +:1026A000F7F1A6689648DA17540080029780C609A9 +:1026B000440000C3DD42F8178400F8188400FC8051 +:1026C0009656C118440000C4DD42F80D8006F80E8D +:1026D0008006FC80546080FEC60D440000C5DD42CB +:1026E0008006DD4249FFFFA0840149FFFD78840098 +:1026F000FC808401FC80FC40814080E180C2812319 +:10270000EA4C5405007F5A08010A8400F84B8420E3 +:10271000EB74AE404413F7CBD5034413F7CC5424E9 +:1027200080FF4403F7C0AE8096B84403F7C3AE8081 +:1027300096B04403F7C6AE804004A0099600442337 +:10274000F7C1AE104003A00996004423F7C4AE10B1 +:10275000EB6896004423F7C74034C009AE1096D802 +:102760004403F7C292F0AEC097F84403F7C592D085 +:10277000AFC097B0EBB5AF808401AE088401FCC058 +:102780005A0001054413F7CCD5034413F7CB443367 +:10279000F04AEB6BA688C203AF18D5FD5A08010AB0 +:1027A000FC0049FFFD74EBF4EB74AE408402FC8046 +:1027B0008402DD9EFC41DD5A84C15A0001044800B8 +:1027C000008B4413F7F1EA38EA37A6089604C003F1 +:1027D000AED0D5FC3C6DFB4D4413F1289CB4846312 +:1027E0008402DD444413F1185023000884638402FA +:1027F000DD444413F1005023001884648402DD4456 +:102800004413F12C5023001084638402DD444413EC +:10281000F1305023001484638402DD444413F10436 +:102820005023001C84648402DD4484014413F30EAD +:10283000EAB28060DD44001F8007440FFF80FE0F76 +:10284000EA2A4413F30EEAB284618402DD44440FA1 +:10285000FFAEEA2AEAB0EAB284618402DD44840170 +:10286000EA2A4413F10D8402EAB28461DD44DD46B4 +:10287000DD47AE404605555A50000AAA3C5DFA6F46 +:10288000D8FE46012345500006783C0FFA6FEA74E3 +:10289000EA7C840AEA328401EA594413F133EAB249 +:1028A0008060DD44006F800754030004C0F3978FFD +:1028B000C606440000C2DD4284C1D50D4605A5AA66 +:1028C000500005A54412C1303C0FFA7080418402CB +:1028D0008464DD448006FCC1DD5A5A0001054402CF +:1028E0004A00DD9E44020A00DD9EFC405A000203BD +:1028F000F818840880C1DD4A4403F31CA600C00612 +:102900004413F33FA608EAE3AE084403F369A600C4 +:102910009604C009FA22EA6FAE408420EB1FAE4055 +:10292000480000EB4413F36CA608EB265800000A9D +:10293000AE082E97F01F2E77F01E5A900104480023 +:102940000080CF1E8009DD4A4413F374A6085800A6 +:102950000003AE08C61284053E97F01EDD4A2E071E +:10296000F01D80478C013E07F01D840280208069A5 +:10297000808780A7DD56D50444000898EA32840099 +:102980003E07F01ECE1D4463F36A8402DD4AA63082 +:10299000EB2DEA7AAE30440001C2EA32EA26FA00B0 +:1029A000AE08804184618402DD448403DD4AA630A0 +:1029B0004413F369EA54AE30EA38EA37D51E84008E +:1029C000F809844080A28062848384228401DD56D9 +:1029D000840149005B14EAA8FA0380268046AE30E1 +:1029E00084618402DD448401EAF3EA28EA21A63006 +:1029F0005A0014CBAE88D5FCA6089604C803AED006 +:102A0000D5FC8404DD4A4422FEF04433F04AEB6BEB +:102A1000A610EA265A001104AF18D5FBFA02AE0838 +:102A20008440EB1FAE80840280418060DD448405D9 +:102A3000DD4A2E07F01C8C013E07F01CD55DCF0E41 +:102A4000C60D84013E07F01E8405DD4A84028027FE +:102A500080478067848380A7DD5684003E07F01E90 +:102A6000C61D4472FEF04493F04A44A00055A638B7 +:102A7000EAA85A00130B84408401EBF9802080629D +:102A8000848380A2DD56D5F48401EAF3FA04AE30E3 +:102A90008026840280468461DD44EA26EA38EA37EB +:102AA000A6085A001004AED0D5FC8403DD4A4413B6 +:102AB000F36AA608EA38EA54AE08EA374413F36921 +:102AC000A6089604C803AED0D5FC8404DD4AEAA863 +:102AD000FA01AE308026804684028461DD44EA2813 +:102AE000EA21A6305A001204AE88D5FC2E07F01C4D +:102AF0008C013E07F01CFCC04423F02BA6502E375F +:102B0000F01F96485A380109C00458008008D50AB9 +:102B1000540080F7D507C00458008010D503540036 +:102B200080EFAE10DD9E4403F02AA600EB04960071 +:102B30005A180104EA5EDD9EEAD9DD9EC807FC0052 +:102B40008401EA638405DD4AFC80DD9EFC00EAA284 +:102B50005A0801094403F7F0A60056000001960444 +:102B6000FC808400FC80DD59A6009600C004EAA524 +:102B70005E000001DD9EFC4097808402DD4A8006F5 +:102B8000DD4A4412FEF28401AE084402FEF3AF8037 +:102B9000840280418060DD44EA98EABB4492FEF6FC +:102BA00049FFFFC35A00010B8404441000F2DD43C7 +:102BB000EB03AFF0EAB85A08ECF58403DD4A840071 +:102BC0004412FEF2AE084412FEF3AE08FCC0FC4014 +:102BD0003C6DFB9B97B0DD455A000207DD40A60126 +:102BE0005A000903F8D0EB17EA58D003EAD0D829E5 +:102BF0002E57F080D6042E57F081DE0CDD5A5A0095 +:102C000001078408EA392E0010F3EA994472C7F0EC +:102C1000F8BA2E07F084E2C0E9FAEB045A1801F87A +:102C20008429EB182E1010F03E17EF104C600005B1 +:102C30002E57F085DEEC840AEA494472C7F0F8A307 +:102C40003C0DFFDFD0043C0DFFE0D8272E07F070CD +:102C5000E2C0E90FDD5A5A000103F8158409EA3988 +:102C6000840AEA492E0010FDEA6E4472C7D8F88B38 +:102C70002E57F068D6052E57F0694C5340E5DD5AC3 +:102C80005A080104480000E08408EA392E0010F3D5 +:102C9000EA994472C7D8F8773C0DFFE8D0043C0DA0 +:102CA000FFE9D8502E57F052DE0CDD5A5A080103C6 +:102CB000F83E8408EA392E0010F2EA99EB7DF863B9 +:102CC0002E57F05DD6162E57F05FD6132E57F061B3 +:102CD000D6102E57F063D60D2E57F05ED60A2E571B +:102CE000F060D6072E57F062D6042E57F064DE0C43 +:102CF000DD5A5A080103F81B8408EA392E0010F443 +:102D0000EA99EB7DF8402E57F058D60E2E57F05921 +:102D1000D60B2E57F05AD6082E57F05BD6052E57F5 +:102D2000F05C4C534094DD5A5A0001044800008F77 +:102D30008409EA39840AEA492E0010FDEA6EEB7D27 +:102D4000F822EBA4D0043C0DFFE7D84B2E57F03F00 +:102D5000DE0CDD5A5A000103F80E8409EA392E0010 +:102D600010F0EA6EEB11F80F2E57F03ADE0EDD5A36 +:102D70005A0801044800006D8408EA392E0010F258 +:102D8000EA99EB11480000692E57F03CDE08DD5A45 +:102D90005A08015F840AEA49EB11D55E2E57F045C7 +:102DA000D6162E57F047D6132E57F049D6102E5769 +:102DB000F04BD60D2E57F046D60A2E57F048D607C0 +:102DC0002E57F04AD6042E57F04CDE42DD5A5A00F8 +:102DD00001408408EA392E0010F4EA99EB11D53C41 +:102DE0003C0DFFD94C02C00E2E27F01F84292E0067 +:102DF00010F1EB185A280104EA6ED52EEA99D52C69 +:102E0000EBB04C02C0132E57F020D6042E57F02101 +:102E1000DE21DD5A5A00011F8408EA392E0010F322 +:102E2000EA994472C790D518EACA4C02C016DD5A16 +:102E30005A0801138409EA392E0010F0EA6E840A58 +:102E4000EA49D50A4472C7D8D507EB7DD505EB1101 +:102E5000D5034472C79044A3F01DEAAFEAB7DD532F +:102E60005A080215DD455A080212A77A9E319600CB +:102E7000DE065894800110950000D5080053801399 +:102E8000D805549480FE10950000FCC0FC003C6DF9 +:102E9000FB9B3C0DFB635A0009083C0DFB635A0089 +:102EA00008044800019BDD455A000208DD40A601E8 +:102EB0005A0009044800016D3C1DFB4F3C2DFFD713 +:102EC0009770DD5A4C1100063C2DFFD84C11401371 +:102ED0002E17F0864C12809F2E17F0874C12809B85 +:102EE0002E27F0804C5101252E17F0814E120146FD +:102EF000F8163C2DFFDF4C1100063C2DFFE04C1175 +:102F000040112E17F070E2A14EF200852E27F068D6 +:102F10004C51010F2E17F0694C12C13048000109C5 +:102F20003C2DFFE84C1100063C2DFFE94C11406799 +:102F30002E17F0524C12C0125A080103F898EA45B5 +:102F40004E1700048E21EABFEA454E13011784464E +:102F50003C2FFB64EAEEF8A12E27F05DD20D2E1770 +:102F6000F05F4C12800A2E17F0614C1280062E176B +:102F7000F0634C12C01F5A080103F879EA454E1756 +:102F800000048E21EABFEA454E1300F8EB4AEAEE50 +:102F90004C51007B2E17F05F4C12807E2E17F06193 +:102FA0004C1280822E17F0634C12C0E84800008358 +:102FB0002E17F05E4C1280922E17F0604C12808E0D +:102FC0002E17F0624C12808A2E17F0644C12808605 +:102FD0002E17F0584C12801F2E17F0594C12801BE0 +:102FE0002E17F05A4C1280172E17F05B4C128013DC +:102FF0002E17F05C4C12C0C2D50D3C2DFFE64C11D3 +:1030000000063C2DFFE74C1140772E17F03F4C1285 +:10301000C0075A000103F841480000A62E17F03AF5 +:103020004C12C0155A080103F822EA454E17000455 +:103030008E21EABFEA454E1300A184463C2FFB6473 +:1030400084413E27EF75EAEEF8282E27F045D20D91 +:103050002E17F0474C12800A2E17F0494C128006AA +:103060002E17F04B4C12C02A5A0801044800008861 +:10307000EA454E1700048E21EABFEA454E13007E52 +:10308000EB4AEAEEDA04842BEB0AF8072E17F04736 +:103090004C12C006842CEB0A480000702E17F04931 +:1030A0004C12C005842DEB0AD5682E17F04B4C123C +:1030B000C065842EEB0AD5612E17F0464C12800EA7 +:1030C0002E17F0484C12800A2E17F04A4C12800638 +:1030D0002E17F04C4C12C0525A000152EA454E17BE +:1030E00000048E21EABFEA45C94884413C2FFB64B5 +:1030F000EAEED5433C2DFFD94C1140105A08010887 +:10310000EAA54E07003D8E01EA6ED539EA454E1715 +:1031100000358E21EABFD5313C2DFFEF4C20C01B7E +:103120002E27F020D2052E17F0214C12C0275A006E +:103130000127EA454E1700048E21EABFEA45C91D62 +:10314000DA048424EB4AD5038425EB4A8420EAEE92 +:10315000D5143C5DFFEED9115A0801104403F40365 +:10316000A600C80DEAA54E0700048E01EA6EEAA586 +:10317000C8068407EA49D5035A080105EAA5C82DFF +:10318000D5042E0FEF0FC829840BEA39D526DD456B +:103190005A000224EB17EACAD820DD5A5A08010E59 +:1031A000EAA54E0700048E01EA6EEAA5C816840758 +:1031B000EA498404DD4AD5118402DD4A2E0FEF0E60 +:1031C0004E0700058E013E07EF0E2E0FEF0EC805CD +:1031D0008407EA498403DD4AFC80FC00EBFE96008C +:1031E0005A080103F8062E57F045D8058400EA9DD9 +:1031F000480000572E57F046D80D8401EA9DDD5A4D +:103200005A00014F4412E5D8EB54EA908402DD44A1 +:10321000D5472E57F047D8048402EA9DD5412E5752 +:10322000F048D80D8403EA9DDD5A5A00013A441251 +:10323000E658EB54EA908402DD44D5322E57F0492B +:10324000D8048404EA9DD52C2E57F04AD80D840565 +:10325000EA9DDD5A5A0001254412E6D8EB54EA9063 +:103260008402DD44D51D2E57F04BD80C8406EA9D10 +:10327000DD5A5A000116EBA18041FA788402DD4440 +:10328000D50F2E57F04CD80C8407EA9DDD5A5A0012 +:10329000010884024412E758EB54EA90DD44FC80B4 +:1032A00044039680A600961F8E01E6013EF7EC705F +:1032B000DD9EFC202E07EC7097805A680131441384 +:1032C000968144039680A600A68844139682A64859 +:1032D000407010094010A00840108A0444239683CF +:1032E000A690FE5744239684A6D096D85A7001071C +:1032F0005A78020BF8038006D5088007442396907D +:10330000DD448007D5028403842044239680AE5098 +:103310004423968FAE103E17EC70FCA08401FCA0F5 +:103320002E07EC7BC005FC008403DD4AFC80DD9E9B +:10333000FC00C80284263E17EC5C49005643FC8022 +:10334000FC03B61FF181F282F383B45FEB62EA24DF +:103350008402F484F585DD44F2014412A69AF8381B +:10336000F2024412A82AF834F2034412A9BAF8303F +:10337000F20444129ECAF82CF2054412A05AF8280E +:10338000F20A4412A1EAF824F20B4412A37AF820BC +:10339000F20C4412988AF81CF20D44129A1AF8188A +:1033A000F20E44129BAAF814F20F44129D3AF81040 +:1033B000F2104412AB4AF80CF2114412ABAEF8080A +:1033C000F2124412AC12F8044412AC76F213EA245E +:1033D0008402DD44FC832E27F01F5A280104480094 +:1033E000008CFC4580E08121840480273C6DFB9BA0 +:1033F000DD435A7005075A78060448000065F80452 +:10340000EA9A5A00090448000076EB27A6008E02CB +:10341000E6064EF20070E724E916E730E83E444342 +:103420007A28F830EAC644137578F486F487F4886D +:10343000F489B65FF381F082F183F284F385FD2095 +:10344000F82AD52B44038388B61F44038518F081DE +:10345000EB71F08244037BB8F083EBFFF08444030C +:103460007ED8F085440386A8F08644038838F08728 +:10347000440389C8F08844038B58F0894413757855 +:10348000EAC6442377084433789883FF444380682E +:10349000445381F849FFFF56EB55F823EBA18041D7 +:1034A000FA78F821441397DC80418464F81C840482 +:1034B000441000CEDD43490004A68404441000CF2C +:1034C000DD43D5189630661000088E26E622E908FE +:1034D00050107FF6E622E9048E12E602E80BEB5567 +:1034E0008041EA908402DD44EBA184028041FA78B5 +:1034F000DD448401FCC58401DD9EFC0084858E01D1 +:103500004050109684C68CA138509602FF34404239 +:10351000900D972FAF10041080114000800D96047D +:10352000AE18FC8004108012FA58FE14EA6AEB8090 +:10353000EA82882004008009EA55DD9E041080128A +:10354000FA58FE14EA6AEB80EA82882004008008B8 +:103550009600DD9EFC60816004000008858185C0C6 +:1035600081215480003F81AC80CC80EE50A5800446 +:10357000879FE3064EF300AF9E319600802A4900F4 +:103580005F2D8E015CF000234EF200A144F0339CCD +:103590003827810140F13C004A003C006C002E01BC +:1035A0002E012E012E012E012E019600280164000D +:1035B0004C00E800F000F8000001080110011801BB +:1035C00020014600C000C800D000D800E0002E0155 +:1035D0002E012E012E012E01460046004600460017 +:1035E00046008CE197F8D5729AB74EE30008102494 +:1035F000800011C4800185C1D56910248001D56681 +:103600009A3710048002D562EA584CB0400D9AB740 +:103610005AD801061024800485A0D55810248005AE +:1036200085A0D554EBA44CB040529A3710048004C6 +:10363000D54DEA584CB0400D9AB75AC8010610242F +:1036400080068580D543102480078580D53FEBA474 +:103650004CB0403D9A3710048007D5389A37100493 +:103660008008D5349A3710048009D5309A37100471 +:10367000800AD52C9A371004800BD5289A3710046D +:10368000800CD5249A371004800DD5209A37100469 +:10369000800ED51C9A371004800FD5189A37100465 +:1036A0008010D5149A3710048011D5109A37100461 +:1036B0008012D50C9A3710048013D5089A3710045D +:1036C0008014D5049A37100480038CC197B048FF4A +:1036D000FF52FCE0FC61F081F1018400F8323E0011 +:1036E00010E884003E07EF0984C04492E8589DF139 +:1036F000F1019638F8262E17EF0988C9AE318801F6 +:103700003E07EF0980C75A7808F4F1018409F819D7 +:103710003E0010F1F101840AF8143E0010F2F101AC +:10372000840BF80F3E0010F3F101840CF80A3E0000 +:1037300010F4F101840DF8053E0010F5F101FA05D1 +:1037400049FFFEFE3C7DFFE63E0010FD84C0449331 +:10375000978050A3800404038008962FE0C0E80BF4 +:103760008006802A40B3240049005E388CC1EB21DA +:1037700097B0D5F2FCE1FC004462D6CCB40644120A +:10378000C7F0F8118386B8084412C7D8F80CB811EE +:103790004412C7C0F808B80F4412C7A8F804B818F4 +:1037A0004412C79049FFFED8FC804423F7DAA650A4 +:1037B0009648C00458108020D503541080DFAE50C6 +:1037C000DD9EFC408401490053FD8401F8272E173B +:1037D000EF0946008B3B88014413F7F8B6018401DA +:1037E0004413F7FCAE084413F7CDAE0884293E0716 +:1037F000EF0E8404EB18446000C8DD4AEA74EA7CEA +:103800002E0FEF0E4E0700088EC1EA59840A97B1B9 +:10381000EA32CEF78405DD4A840049FFFFC8FCC0C8 +:10382000FC4080E0DD4580605A08024EEB045A18E7 +:103830000128F83044A2FEFC4492FEFD0055000031 +:103840004412FEFCD70F0015000000648000840ABB +:1038500097B0DD438026840BDD43840AEA32EA29EF +:10386000D5EEEAB85A08AAF1EBDEAE08844044026D +:10387000FEFDAE80840280418060DD44FCC0446275 +:10388000FEFCAFF0EBF44472FEFDAE78804680267D +:10389000DD44DD47DD46AE4083FFA63096005A008A +:1038A000460CA670A638EAB7840ADD43840B80294B +:1038B000DD43EA29D5F34412FEFCAE084402FEFDC6 +:1038C0008420AE40FCC0FC20DD455A08021744733A +:1038D000F41CA7B8DD47DD46AE40840A44100099C9 +:1038E00097B0DD43DD59A600C806A7B897B0EA290E +:1038F000EB03D5F95A6802FBFCA0FC21F081DD5AEC +:103900005A08011FF8354412FEF0A608EAA85A0822 +:1039100050FEF81644000051F825F82AA6304472EB +:10392000FEF05A0852FDF0014900716F4400005347 +:10393000AE388027804784618402DD44FCA14900C1 +:103940001DDBEAA8EA5FF80E4403F04ADD47AE400B +:103950008006A640EAA85A1851FEF00149007155A8 +:10396000EB5BAE308026840280468461DD44DD4717 +:10397000DD46AE4083FFA6305A0853FFFCA1FC2071 +:10398000DD5AEA98EABB5A080113AFF0EA26A60806 +:103990005A0852FF8401EB84DD47DD46AE40DD4529 +:1039A000C0FF44100053EA6FAE40FCA08401EB84DA +:1039B000AFF0DD45C0FFEA26EB5BAE0880418461D5 +:1039C0008402DD44FCA0FC4280C0B0013A100C200F +:1039D00022AF8002F702049F8003DD455A000209EE +:1039E00080278049806A8402DD448401FCC2000390 +:1039F0000065001300648A015A00082F0003006567 +:103A000000130065E608840CE80FF80812A1000016 +:103A1000F803149100020013006580464220807371 +:103A200083FFA9D1D5118E284E00FFF912A1000005 +:103A3000F803149100020013006580468E2842208E +:103A4000807383FFA9D1000300658C0196001003E9 +:103A500000658401FCC28400FCC2FC00006080643C +:103A6000002080654C61002900308064844C808196 +:103A700042418873003080642252000080814241BC +:103A8000887380C1A0E20040806442620873002015 +:103A90008064A1318C419690102080640020806465 +:103AA0005A28080B844010208064002080658E48CE +:103AB000969010208065AD40A901A8C2FC803C1DF5 +:103AC000FB753C1DFB7500300064844C420188731B +:103AD000501087A3222000004400004B42110073C5 +:103AE00080013C1C0302E201E8053C0FFB758401E8 +:103AF000DD9E8400DD9EFC023C6DFB8EEB8AC045A2 +:103B000096309E43E631E806DD54A648C9035A08BC +:103B10000B058400EBC9D5392E500C0D2E000C0C72 +:103B2000D823EB0497B03C0DFB705A0003083C030C +:103B3000F6618C0196013C0BF6615A68020E5A1030 +:103B4000010C3C03F6615A0001F084003C0BF66165 +:103B500084003C0FFB70840084203C0BF6613C1F0A +:103B6000FB70EBC9D512EB2849FFFFABC0DBB001FE +:103B70004412E31849FFFF738402F102F203223F6B +:103B80008002EA713C0FFB70FC824403F7C9A64037 +:103B9000C1038420AE40DD9EFC01DD5A5A00014580 +:103BA000EB17EBA4D0043C0DFFE7D83EEA67EA66CA +:103BB0008C019600B081503F8005EB9EEA66000FB5 +:103BC00080040460800849FFFCAF001F800597AFA8 +:103BD000C11AEA67EA668C029600EAF1EAB9EB9E3E +:103BE000EB29EA6649FFFCA0C80AEA67E206E80793 +:103BF000EB56C80584013E07EC4BD51A84003E07FE +:103C0000EC4BD516C80AEA67E206E8072E07EC6017 +:103C1000C8048401EBD9D50C840AEA328400EBD9BC +:103C20003E07EC1FD5058400EBD93E07EC1FFC8155 +:103C3000EB045A1801064412C4C8F804DD9E44126D +:103C4000C4583800810150007F5BEAD483FFDD9EB9 +:103C5000FC40DD4780C0DD46AE40EA8CA608C8FFC8 +:103C60002E37F01F44A2C458440000A5947150732D +:103C70007FA04492C4C85A380116882A804138056A +:103C800019098402DD44EA4CF815380499015A08F0 +:103C9000A5FEF81C4412C4C8380519093800990952 +:103CA000FCC0882980413804990984618402DD447C +:103CB000EA4CDD46DD47AE4097F844038D44AFC083 +:103CC00083FF380519015A08A5FE50037FB09600FE +:103CD00044138D44AE08840083FF4412C458380056 +:103CE000990938049909FCC0FC008400441000C103 +:103CF000DD43EA9AC8038407EADEDD4F0060005125 +:103D000084018026DD435A6802134400012CEA93A3 +:103D1000DD4FEB7E00000053C8038400D53D5A0000 +:103D2000013C5A00023A5A0803FAD5365A68033859 +:103D30008402EA354400012CEA93DD4F0010005361 +:103D400000000054968C4210840BC914CA0AC803A0 +:103D50008404D5225A0801048406D51E8408D51C83 +:103D6000C8038405D5195A0801048407D5158409A8 +:103D7000D513CA0AC803840AD50F5A080104840C53 +:103D8000D50B840ED509C803840BD5065A08010447 +:103D9000840DD502840F3C0FFB52D50E5A68040DDA +:103DA00084003E07EC413E07EF74DD41C8118401F9 +:103DB000EA358426D50B84003E07EF7484013E0764 +:103DC000EC41DD41C8058401842549FFFAB3FC803C +:103DD000FC0180C08400EA2ADD41C8133E67EC2F55 +:103DE0004412C39F804184618402DD4484014412F3 +:103DF000C39FEAB28060DD44EA9A005F8007D8F191 +:103E0000FC81FC00DD41C010EA9A5A000305EA9AE1 +:103E10005A080AFF84004412C39FEADE804184618D +:103E20008402DD44FC80840A49FFFFD4FC80FC004E +:103E3000DD41C80AEA9A5A0808048409D504EA9AB6 +:103E4000C8038407EADEFC80FC00EA8384203C0F80 +:103E5000FC2810100050EA88EB9510100053101049 +:103E6000006010100061FC80FC00DD41C825EA33D1 +:103E7000001080F25A180121EA21EA28AE883C2D70 +:103E8000FC28001100F2C902D5004412FEF3A64836 +:103E900096485A10040C5A10030A5A1006085A1071 +:103EA0000A065A1009045A180B083E17EF1210019F +:103EB00000F2100100F38401FC802E07EF1DC80FF3 +:103EC000EA333E07EF1F002080513E07EF1E10002F +:103ED000805184013E27EF1C3E07EF1DDD9EFC0054 +:103EE0005A0806048401D5045A08070684003E07D0 +:103EF000EC07D51C5A080D0784003E07EC07842107 +:103F0000D5075A080E0B84013E07EC0784203E17A4 +:103F1000EC4C3E07EC39D50A5A0810048401D5044C +:103F20005A08110584003E07EC04FC80FC002E07B3 +:103F3000EF1EC8312E07EF1C5A0810053C0C01C1BA +:103F4000D50A5A0811053C0C01BBD5055A081207C1 +:103F50003C0C01BD441320D0EA20EA2EDD4FC904F9 +:103F6000441FFFA0D503441FFFA1EA88EB45A648E4 +:103F70005A180305441FFFB1D503441FFFB0EB954A +:103F8000DD40A6015A08040584013E07EC5884016F +:103F90003E07EF1EDD4FEA565A08BB1B2E07EF1FE8 +:103FA000E614E8062E07EF1FE60AE912D50FDD45F5 +:103FB0005A0802FAEA33840010008051100080523F +:103FC0003E07EF1F3E07EF1ED503DD45C0F4FC8022 +:103FD000FC408120DD402E27EF0BA601E64180E169 +:103FE0003EF7EF0BEA985A08034B8408441000B1DF +:103FF000DD43EA43AE3044A38D4084CADD54A608B5 +:10400000C8133C2DFB3F5A2801FCDD5C5A0807F918 +:104010003C6FFB642E07EF0BC0F33E27EC75EAAF55 +:1040200049001B9CD5EC8408441000B2DD43DD41FF +:10403000C80B2E07EF0BC8138401EA30DD4CA60035 +:1040400049001B8CD50CDD47DD46AE402E17EBFF3B +:10405000DD5C5A0007F05A1801FDD5EC84084410C5 +:1040600000B3DD43DD535A080206EB0CC00349FFE1 +:10407000FECA8408441000B4DD43D508EA43AE30DC +:10408000DD54A608C803EA29D5FD8408441000B50C +:10409000DD432E07EF1C3C2DFC288E10E60310910B +:1040A0000053E80449FFFF44D541CF04440FFFA06B +:1040B000D503440FFFA110010051DD4CA6005A08A2 +:1040C0000305440FFFB1D503440FFFB010010052A8 +:1040D000DD40A6015A08040584013E07EC5844104F +:1040E00000B68408DD43EA28EA21DD4FEA565A008B +:1040F000BB04AE88D5FB8408441000B7DD43DD4126 +:10410000C0068402EAB080418060DD448400EA6336 +:104110008408441000B8DD43EAC5DD4F8420EA88F6 +:10412000EB958408441000B9DD43FCC0EA3310006D +:104130008060DD9EDD4F00000060DD9EEA331000F0 +:1041400080613C1DFA6A1000803EDD9EEA3300006B +:10415000805050007FDFE602E904840010008050A8 +:10416000DD9EFC00DD4F441FFFCCEA88EA21EA28EF +:10417000DD4FEA565A00BB04AE88D5FBEAC4EA32EA +:104180008400EAA6FC8084213E17EC16EA338801FD +:10419000002000523C2BF65C00100053401105003B +:1041A0003C1BF65C001000543C1BF6590000005507 +:1041B000EB4C3C0BF659DD9EFC008400EBA7EAFBC0 +:1041C0003C0BF652DD535A080106DD4F0010005239 +:1041D000D506DD41EA3300108052C003840AD502BF +:1041E000FA18FE0C3C0BF650DD4FEA565A08AB05A8 +:1041F000840249FFFFCAFC80FC0080C049FFFE71B9 +:1042000084015A6803054900569A800650137FF3CB +:10421000E622E9035A68021B8401EAD3DD40A78144 +:104220005A6803048402D5125A680A098429AE41E7 +:104230008420DD57DD40AF81D5038420DD57DD4587 +:104240005A0802F2DD558443AE89FC804000040E1A +:104250009604DD9EFC02DD41C01FDD4FEBF4EA88D1 +:10426000DD4F001000515A18AA0AEAC4EA32840746 +:1042700044100031DD43EB03D5F4B0415000005150 +:104280008441F083122F8002A8093A108C00EB2899 +:1042900049FFFB9BD50CDD4FEA56C809EAC4EA3258 +:1042A000840744100031DD43EB03D5F68407EA763A +:1042B000DD43DD4FEA565A00DD048401D502840354 +:1042C000FC829200FC01840A8061EA2A5A100105EE +:1042D0005A100207D544DD4F8420EA88D544EA33DA +:1042E000000080528E06E604E83644F040F4EA8B83 +:1042F000EA3DDD0F040E26528400EBA81000805228 +:10430000D5328401EBA884008040DD55EA4DEA9E59 +:104310003C0794C949006237D50B8403EBA884019C +:10432000EA35000080534412000049006175DD4CFD +:10433000A600441200004422C3A9EAB93C4DFC285F +:10434000490061DED5104402010249005E0F84017C +:10435000EA2AD5098401EA2AAED0D5058401EA2AE1 +:104360008402AE10EB565A080A0A49FFFF75DD5465 +:10437000EA2A8401AE08DD58AE08EB56FC815A00EB +:1043800001075A080309B401EA7AD503B401EAB374 +:10439000B601DD9E8402AE10DD9EFC00DD4FEA56C4 +:1043A0005A08040CDD45C809DD41C00484013E07FC +:1043B000F098DD4F8420EA88FC809200FC409F0149 +:1043C000E68F4EF2008880C2800144F041D8384721 +:1043D000910140F23C00DD0F24002E0038009600D1 +:1043E000BC00C200FA00D400E00000011E00EE0094 +:1043F000FA00FA00F400FA014800007184003E0758 +:10440000EF1D8406D56B84003E07EF1D8407D5663B +:10441000EA74EA7CF82580C05A000204EA59D5FB08 +:104420008401F823490013503C0E044249001355FF +:104430003C0E0443490013623E0011114900136809 +:104440003E0011104900135F3E0011128421440206 +:10445000E87849004A628006F808EA98EABB490011 +:10446000135BC003AFF0D5FC49001369D512842E4D +:10447000AE418426AE40EA3384401020805084212F +:10448000DD578420840280418461808180A1DD56D3 +:104490008401D5248401AE10D51584004410006633 +:1044A000DD438401AE30DD45840ED5188401AE10A5 +:1044B0008401F8068402D5128401AE1084004900FC +:1044C0005550840DD50B8400EBB2D5E349FFFF674F +:1044D000D5E08402AE18D5DDFA00FCC09200DD4FB5 +:1044E0003C100370101000A09228101000A13C177F +:1044F000F660101000A29028101000A32E17EC6F89 +:10450000101000A44412C6F0A688102000A5A68AA8 +:10451000102000A6A08B102000A79248102000A811 +:104520000020801E102000A9EBFAA690102000AAFF +:104530008440102000AB3C23F7B6102000AC92481A +:10454000102000AD3C33F64A3C23F65A8843102035 +:1045500000AE9048102000AF00208020102000B056 +:1045600000208021102000B100208022102000B205 +:1045700000108023101000B33C1DFB48101000B544 +:10458000EB45A648101000B6EBA1A08BA04C102064 +:1045900000B7101000B8DD9E4413F04AEA21DD4F49 +:1045A000EA565A00BB04AE88D5FBDD9EFC0080C0F5 +:1045B000DD4FEA565A08BB2349004E65DD4F001017 +:1045C0000050C1035A18FB102E17EF07C9042E170D +:1045D000EF06C1108400EBECEB998400EBB2840190 +:1045E000EAD3D519CE08EB425A08A00B44030FA01A +:1045F000D50CC60A441FFFA0D50DC6F6D50C5A0827 +:10460000A104EA8DD502EAC6EAB5EA20441FFFA05C +:10461000DD4FEA88FC809200FC00E60A4EF2007A48 +:1046200044F0442CEA8BEA3D4A003C000A4468E42A +:10463000E4E4E4E47CBEC903FA13D50F5A18010B75 +:10464000FA0E3C0BF4CE3C0BF4CC840C3C0BF4CDBA +:10465000D5605A180207FA093C0BF4CEFA0ED5F4CD +:104660005A180304FA04D5F9840F5A180453D5F5DF +:104670008401C1045A18010684023E07EF00D5499F +:1046800084005A1002FC5A1003045A1804433E17BF +:10469000EF00D53FC1075A1001065A1002045A18FC +:1046A00003393C1BF4C8D535C903FA0ED5055A1891 +:1046B00001084400003C3C0BF4CAFA13D5145A1804 +:1046C0000207EA5F3C0BF4CAFA09D50D5A18030534 +:1046D00044000064D5055A18041D440000823C0BB8 +:1046E000F4CAFA043C0BF4C9D514840AC1105A1850 +:1046F0000104FA04D50C5A180204FA0ED5085A1807 +:104700000304FA18D5045A180405EAB13C0BF4CB9B +:10471000FC809200FC00FA093C0BF4CE3C0BF4C97F +:1047200084023C0BF4C8FA2E84003E07EF003C1BC9 +:10473000F4CC3C1BF4CB3C0DFB45844C44100050A6 +:104740003C1BF4CA3C2BF4CDB440441E7FFFFE5604 +:10475000B620B4206610F0005810A000B620B44077 +:10476000461FF1FFEBF1FE564210D808B620B440C8 +:10477000461F8FFFEBF1FE564210E408B620B4202E +:1047800066108E0058108400B620FC80FC4080C16A +:104790008420AE40B40280E24200740B81245A08A7 +:1047A0000106B40642007408B606B4074200740B52 +:1047B000C805B40642007409B606B407EAC85A0828 +:1047C0000107B406EA95B6068006EBD7B407EAC837 +:1047D000C80AB406EA7BB6064900153B3E07EF81DE +:1047E0008006EBD7B40796045A080105B406EA54CC +:1047F000B606B4079604C804B406EBF0B606B407D0 +:10480000EA555A080105B406EA7AB606B407EA552D +:10481000C804B406EAB3B606B407EAD95A080105D3 +:10482000B406EAE0B606B407EAD9C804B406EB3425 +:10483000B606B407EA5E5A080105B406EA7DB60674 +:10484000B407EA5EC804B406EACBB606B40792051C +:1048500096175A080106B406EA4AEAAEB606B40745 +:10486000920596175A080207B406EA4A5800004013 +:10487000B606B407920596175A080307B406EA4A23 +:1048800058000060B606B407920596175A08040649 +:10489000B406EA4AEAE3B606EA73EA5EC807B40673 +:1048A00042006C09B606EB64FCC0B40642006C081A +:1048B000B606EAB892075A080111EAB89637EA3400 +:1048C000B427840092299657F932B40754100E0089 +:1048D000B40666000E00F83FEA7396045A08011207 +:1048E000EB5F6610800110148001B427922C96575C +:1048F000F91EB40754107000B40666007000F82B5F +:10490000EA73EA555A080112EA73EAB3EA68B4276F +:10491000840892359657F90BB42746000E00FE46E0 +:10492000B446460FF1FFF81500048001EAD95A0891 +:104930000116EA73EB34EA68B42784099238965773 +:10494000F8F6B42746007000FE46B446460F8FFFC7 +:10495000EAF7FE16FE0FB60683FFEA73EAC85A08A6 +:104960000113EA73EA7BEA68B4278402922F964F18 +:10497000F8DEB42744018000B446FE46440E7FFFB3 +:104980004E00FFE9FCC092008E01E60DE84BFC00F2 +:1049900080C144F0479CEA8BEA3DDD0F0E162A30B9 +:1049A000363C4248804E5A647000B401EA95B60124 +:1049B000D508B401EA7BB6014900144B3E07EF81EC +:1049C0008006EBD7FC80B401EA54D51FB401EBF0AC +:1049D000D51CB401EAE0D519B401EB34D516B40105 +:1049E000EA7DD513B401EACBD510B401EA4AEAAEA8 +:1049F000B601EB64FC80B401EA4A58000040D505DA +:104A0000B401EA4A58000060B606FC80B401EA4AE4 +:104A1000EAE3B601440000BDDD42FC808402AE1032 +:104A2000FC808402AE10DD9E92009200E60C4EF2F5 +:104A300000C1FC0080C244F04840EB2BEA3DDD0F92 +:104A40001800440070006A016A016A016A014C01A1 +:104A5000A000CC00FE002E01B402EA704E0200A9B4 +:104A6000B402965766000E0040100524B622B42208 +:104A7000840092299657F85B44000070DD42B4062A +:104A80009209D55CB402EA704E020093B4029657C4 +:104A90006600700040100584B622B4228401922C76 +:104AA0009657F84544000071DD42B406920CD54695 +:104AB000B402EA704E02007DB442440E7FFFFE163F +:104AC000964F401005E4B626B4268402922F964FE6 +:104AD000F82E44000072DD42B406920F960FD564A2 +:104AE000B402EA70C065B442460FF1FFEAF7FE1661 +:104AF0009657401006A4B626B426840892359657D9 +:104B0000F816EAC4DD42B4069215D518B402EA706C +:104B1000C04FB442460F8FFFEAF7FE16965740107B +:104B20000704B626B42684099238965749FFFD76C5 +:104B300044000079DD42B40692189617D535B402C8 +:104B4000964C42006C0940100764B622B402EA7029 +:104B5000C805EB6444100168D50344100E10EA77D1 +:104B6000AC404400007ADD42B406EA70D51DB402C0 +:104B7000964C4200700940100784B622B4024400EB +:104B8000007BDD42B4064200700BD50EB402964C99 +:104B90004200500940100684B62244000077DD42EE +:104BA000B4064200500BDD42FC808402AE18FC804B +:104BB0008402AE18DD9E9200FC62A6098121F2817A +:104BC000814381845A08040584003E07EC58DD4186 +:104BD000C007EAF85A08AA052E07EDC8D504DD4F2C +:104BE000000000504E02029A5A08FB044800029648 +:104BF000F001EAD6490014BA8400EB7BDD41C00C19 +:104C0000EAF85A08AA0A2E67EDC82EB7EDC9407314 +:104C10001009979FD509DD4F0060005000B000518A +:104C200040731009979F8401EA4F8400EB6EEB5F9D +:104C30005A1804192E17EF11C1043E07EF11D54A77 +:104C40002E07EC0F5A08010449006486842080096D +:104C5000DD578401EA2CDD47DD46AE40EAA2C0FF05 +:104C6000D539DD47DD46AE40DD41C804DD41C82011 +:104C7000D527DD455A000204DD54D5162E07EF0A6C +:104C8000C00B3C1DFB8E2E07EF0A8E01E201E904EA +:104C9000EA67E602E8F24400008ADD428401EAA6FF +:104CA000DD5B4800024DA608C8E2EA29D5FDEAF816 +:104CB0005A085507EAB0840280418466DD44DD5914 +:104CC000A6005A000208DD4BA6405A1802048420B0 +:104CD000AE402E07EC7D8C013E07EC7D40031C842A +:104CE0008EE1E6EC3E07EC7C4EF201EE44F04AFC2D +:104CF00038779D0140F3BC004A003C0018004E008C +:104D0000C001D601660372038E03C803C803C8033B +:104D10009E03B6034402C368EBC84900145FF00168 +:104D2000EAD6490014238006802B8049EBE08400FA +:104D3000EA4F5A600F03F8ACDD4F84CC00000050FE +:104D40005A00FB04480001D3F8A38EC18401E6C6D3 +:104D5000EB7B4EF200AE44F04B643867990140F3B0 +:104D60003C00DD0F0C003600600026012E016600BD +:104D70008400EA4F8401EAE7FA318404DD43EB0C56 +:104D8000C8088404FA3ADD4384C449FFF898D5582A +:104D90008404FA3BDD43FAC4D5538400EA4F84010E +:104DA000EAE7FA318404DD43EB0CC8088404FA3ADC +:104DB000DD4384C549FFF883D5438404FA3BDD43D2 +:104DC000FAC5D53EEAE784C2F88EDD41EA33C03E3B +:104DD0008401EAE70000805284C0106F800F5A08F7 +:104DE000AA2849004A508401EBB2DD4F001000535D +:104DF00000200054440FFFA0FE0F5A280110EB9929 +:104E00004400988C3E67EF0749004AB1DD4F441FCC +:104E1000FFBB3E67EF03EA88D508EBEC440062383D +:104E20003E67EF0649004AA3DD4F8420EB95EB4235 +:104E3000C806EAAD84C1C004FAD0D502FAC9EABCFA +:104E40004E030155841FEA3CF84E2E27EF06C2029E +:104E5000EA4F000080525A08AA15002080548400AE +:104E60005A28010B00308053442FFFA0FE9FEA4FC9 +:104E70003E27EF06D502EB99EBEC84001000805240 +:104E8000EAAD4E030133480000ECEAAAEA6C4800A0 +:104E900000E88400EA33EA4F8401EAE70000805525 +:104EA00000108054EB4C3C0BF64EFAC2F81C840404 +:104EB000FA3FDD438400EB7B480001038402EAFDF6 +:104EC00080268401EB5049FFF9FF80C08405EAFD8C +:104ED000F80A84002E17EBFFEA4F8401EB7B5A1887 +:104EE000010584C9480001033E07EBFFEAFD9E313E +:104EF000E60C4EF2009F44F04D04EB2B40F03C00DA +:104F00004A003C0018002C0182002C0182002C0178 +:104F1000CE002C011801820042002E008400EB9389 +:104F2000DD4384013E07EC54DD53EBAB8401EA35ED +:104F3000F8098400EBB1DD4384013E07EC54DD53F6 +:104F4000EBAB4800007984004410004BDD43EA33AA +:104F5000840100108051DD4384C084013E07EC7160 +:104F60003E67EC07F859EBB7EBCCB401EA7DB6012C +:104F70003C0DFB693E67EC27EA7D3C0FFB69840032 +:104F8000EA61EA94D558EA33DD53EBAB0010805167 +:104F90008401EA35DD43DD4F8026EA56EB50F837D1 +:104FA000EB2E5A0002493C2DFC280001005500312F +:104FB000005440318100001100524231C00800010C +:104FC000005180463E17EC293C3FFB5349001A1A1A +:104FD000D532840044100047DD43EA3384010010D9 +:104FE0008051DD43DD53EBABEA735A080308DD4C17 +:104FF000A6005A0003048402D5028401EA35840124 +:105000003E07EC48DD4F8427EA56EB50490019D2A1 +:10501000EB2E5A00021149FFF8D1D50DEA33840175 +:1050200000108052EA4F3E17EC513E07EC66D50364 +:105030008402EA4FEB2E5A00020448FFFF54DD4F72 +:1050400084C0106000513E67EC673E67EBFFDD45B2 +:105050005A0002053E67EC85D5038405EAFD84C14C +:10506000D5458006802AEB5049FFF98BD51C84007A +:1050700044100060DD43800680294422C3D7503F9E +:10508000800F49FFF99D9780D5318006802B804A9B +:10509000503F800F49FFFCCCD5068006802AEB509C +:1050A00049FFFC74EB2E5A0002DCB40AB60C84CB28 +:1050B000D51D5A68010649FFF619FAC3D5178402AF +:1050C000EA4FD5CE840284C1EA4F3E67EC49DD4108 +:1050D000C0073E67EC49840F441000FBD504840FE1 +:1050E000441000EBDD43D5BCFAD0EB2E84205A00EF +:1050F00001055A080206843BDD4F101000502E07B0 +:10510000EC67C8094402C368EBC849001267F001A4 +:10511000EAD6F80E8006D513EB42C803EAADC00606 +:105120008400EBECEB998400EBB2F001EAD6490085 +:105130001243EA43EB488400EAE78401FCE2920070 +:10514000FC2080C35A000704480000C5E62C4EF23C +:10515000010F80E244F04F643817850140F0BC0035 +:105160004A003C00180044007000080208020802CF +:10517000080252019C00C800F4002E01A621EA5E3C +:105180004E0200F9A660440FFF80FE0FAE20B4432C +:1051900097D766210E0040711D24440000B0B6E38D +:1051A000DD42B4069209D514A621EA5E4E0200E360 +:1051B000A62197D7EA54AE21B443440000B166213A +:1051C000700040711D84B6E3DD42B406920C961760 +:1051D000DD42FCA0A621EA5E4E0200CDA62197CFBB +:1051E000EA95AE21B443440E7FFFFE8640711DE474 +:1051F000440000B2B6E3DD42B406920F960FD5E943 +:10520000A621EA5E4E0200B7A621461FF1FFEA7A08 +:10521000AE21B403EBF1FE0E97D740001EA4B603F7 +:10522000440000B8DD42B4069215D5D2A621EA5E4C +:105230004E0200A1A621461F8FFFEAE0AE21B40373 +:10524000EBF1FE0E97D740001F04B603440000B9EF +:10525000DD42B4069218D5BCA62197D4EACB400013 +:105260001C84AE21B44342216C0940711F64B6E333 +:10527000B403EA70C805EB6444100168D503441018 +:105280000E10EA77AC40440000BADD42B406EA7082 +:10529000D5A0DD414E02006FB44697FC4221700953 +:1052A00040711F84B6E6B4064400007BDD42B406BC +:1052B0004200700BF84D97D4B443440000B742212C +:1052C000500940711E84B6E3DD42B4064200500B23 +:1052D000F83F5A080B408E21E62DE84944F050E88B +:1052E000EBC6EA9C4A003C000E141A20262C3238E9 +:1052F000843E46505A00B403EA95D537B403EA7B9E +:10530000D534B403EA54D531B403EBF0D52EB4034D +:10531000EAE0D52BB403EB34D528B403EA7DD525D8 +:10532000B403EACBD522B403EA4AEAAED51EB403ED +:10533000EA4A58000040D519B403EA4A5800006010 +:10534000D514B403EA4AEAE3B603440000BD48FFBB +:10535000FF415A0805105A1001075A180309B403EF +:10536000EA7AD503B403EAB3B606FCA0843BEA8923 +:10537000AE40FCA09200FC62F081F282F383EA89E5 +:10538000A7C0A7804402FE51A60092E48161979FC6 +:10539000EAB75A700104480000989E31E603E90E0E +:1053A0005A600503F81BDD4F000000605A00A1079A +:1053B0002E07EF9F5A080103F811EAF85A08AA03CA +:1053C000F80D4E42009DDD41C00BDD40A601EB2DE6 +:1053D0005A08040744000088DD4248000091440256 +:1053E000C368EBC8490010FA4402C38DEAD64900ED +:1053F00010BD5A6005058400490045DAEA8CEA3898 +:10540000EA37A6085A080104AED0D5FCDD41C04CED +:1054100044A3F04A44B000554400008210B5000097 +:10542000DD42DD455A08021F2E1FEF102E0FEF0F31 +:105430004423F41C4E170014A6D05A3802FDEAB0DB +:10544000804184668402DD4444000083DD42DD4700 +:10545000DD46AE40DD455A080218D5214E06FFEE66 +:10546000D5EF44700064EAA54E07000A8EE110B53E +:105470000000840A97F9EA32CFF7D5E22E0FEF0F3A +:105480004E06FFF6D5DD4402FEF6A6005A08EC08EB +:10549000DD40A6015A080A0449001702EA26A608B8 +:1054A0005A08E1FFD50C44000084DD42EA26440F8F +:1054B000FFE1AE08804184028461DD4480068029DA +:1054C000F201EBE0D51C5A700B065403800D5A080C +:1054D0000517DD41C014EAF85A00AA1244A2FE5092 +:1054E0008400EB0D802680078049F302F40349FF16 +:1054F000FE29EAAF5A00FB048401EB21FCE23C0FD9 +:10550000FC2ADD9EFC67F08D81A18182C407C30C5B +:10551000FA10846684A180C0D510C30BEB06840109 +:1055200080A384C4D50AFA70840180A384C6D505FB +:10553000EAB1846484A180C040E300139781F82914 +:105540004082801397D9F08A4492EC9C2E07DE0AA1 +:1055500044B2EC3844A2ED00F08B442255B88400EC +:10556000F30DF821842BF8358400806C80403814CA +:1055700081114E17000922518000405284B6976B6A +:10558000AD58D502AC988C019641E22E8C62E9F0C0 +:105590003C07F66AF0893C07F66983FFF08A2E071C +:1055A000DE0AF08B14CF8000149F800114BF8002AC +:1055B00014AF800314DF800414EF8005148F80067D +:1055C000F787F68883FF8400842D442255B8F30DB5 +:1055D000808C44527200F91EFCE7FC01F08144000B +:1055E00004733C0BF66A440FFB8C3C0BF6692E07E8 +:1055F000DE093E07EC7F8C0180C13E07EC80C920AC +:10560000F8058481F80B8066F83144029ECA844113 +:1056100080208062490010AF846144029ECAEB6220 +:10562000F20183FF8083F8224412A1EA4402A82AEF +:10563000EA31DD4944529ECA4412A04AD5205A1884 +:105640000149F80584608083F809F8104402A05AE3 +:105650008020804680664900108EF2014402A05AE4 +:105660004412A69A83FF8066848049FFFF4D44124E +:10567000A37ADD5E4402A9BADD49FC81A428505218 +:105680008040960312028300020281709603120288 +:1056900084900202FFFD96031202831D0202818D97 +:1056A0009603120284AD0202FFE196031202830107 +:1056B000020281719603120284910202FFFE960398 +:1056C0001202831E0202818E9603120284AED9D783 +:1056D000FC81381105118820E023E90AEBB35A0850 +:1056E000010B3C03F894C0085EF08078E8044400A5 +:1056F0008000DD9E8400DD9E3C1DFC2A2E07EC40D0 +:10570000A68EC80CEA4E5A08010A9411AE0AA609E0 +:105710008E01F8079401F80BD511A609AE8A8E0107 +:10572000FE148442400008168E0183FF96033C0B52 +:10573000F66AFE033C0BF66983FFA6093E07EC7F81 +:105740008C013E07EC80DD9EFC672E672893F08D70 +:1057500081C181022E072892CB05802080408401E0 +:10576000D5048026844180C097C1F83340B08013AF +:105770004091001344D2EC3844C2ED003C0DFC2AA9 +:1057800097B144A2EC9CB71FEBD014DF800214CF7A +:105790008003F82DF839842BF83D84608008820D51 +:1057A000808C80439659E22BE81438150D114E1762 +:1057B000000D22500000405284B6976BAD40A440CB +:1057C000964B5EF0FFECE802AC808C618C02D5EB6E +:1057D0003C07F66AF0893C07F669F08A83FF3C0DC6 +:1057E000FC2AF483B71FEBD0150F800214EF80045E +:1057F00014BF8005F786F687149F8008A602F08BF9 +:10580000840083FF842D442255B8F30D808880A046 +:1058100083FF49003E45FCE7FC0180C0F18149FF60 +:10582000FF6DA036A075F201846049FFFF8FFC81F7 +:105830003C0FFBA2DD9E3C0FFBA0DD9E3C0FFBA1BD +:10584000DD9EFC41846380C080E2501F8006FA50D8 +:10585000B400EBE6EA6BB607F80FA47044920000C0 +:10586000F81010138010B406501F8006FA5084649C +:10587000EBE6EA6BA83949003FBBA4703C3DFBA0B6 +:105880008A010014800292014000043783FF101344 +:105890008011B406A072A0B60031800C848149004A +:1058A0000FBDFCC1FC6580E1842080C4121F800D07 +:1058B0005A48040504900006D503049000050231FF +:1058C0000439A613854050BF801CA7528083B61FA1 +:1058D000802980098445EBD014AF800214AF800387 +:1058E00014BF800449003DB3020F800EAC3802059E +:1058F0008001AC39501F801A8009804A8463EBE62E +:10590000020F800D5A6804053C0BF665D5055A68F0 +:1059100005043C0BF660AC3B501F801A80098440A4 +:105920008464EBE6020F800D5A6804053C0BF64FC9 +:10593000D5055A6805043C0BF64BAC3A5A60040E88 +:1059400084003E07EC3B221380033C039880E02058 +:10595000E80484013E07EC3BFCE5FC0180C1F381D7 +:105960008460B61F3E37EC3B49FFFF6DB41F8026B5 +:10597000F2018460848449FFFF972E07EC045A08E3 +:10598000010722130003440395B4AC40FC81B460CA +:10599000B42080A0927096098440986AB481929055 +:1059A000E264E804B421806496098C445A2820F704 +:1059B000DD9E9200FC2080E180C049FFFFEAE6E81E +:1059C000E85944F057D038779C0040F3BC00DD0F15 +:1059D000081A2C3E5466788C961F96433C1BF85D43 +:1059E000964F3E17EC748400D5463C13F85D940442 +:1059F0009600FE0F3C0BF85D8400D53D3C13F85D2E +:105A0000961F400081043C0BF85D8400D5343C13A4 +:105A1000F85D400081849643EB2C3C1BF85DAC4064 +:105A20008401D529961F96433C1BF85C964F3E1780 +:105A3000EC748400D520940496403C03F85CFE4747 +:105A40003C1BF85C8400D5175410000F3C03F85C35 +:105A5000401005043C1BF85C8400D50D3C13F85C39 +:105A600040108184964BEADF3C1BF85CAC4084021A +:105A7000D5028400842FB626FCA09200C9104020D5 +:105A8000380954003FFFC00696C488239648920107 +:105A9000D5FB964FFE555C008001DD9E8401DD9EA6 +:105AA0005450000C848090A2E28510F080005410C5 +:105AB0000030540000C090249006E28140020006AD +:105AC00010F10000AE18DD9EFC0180C1B42380A05F +:105AD000C952847F3E37F0B43E17F0B3C41BC216E0 +:105AE000402020095401000C9002E22054010003E0 +:105AF000400080062E27F0B240003C244C2000528B +:105B00003E17F0B13E07F0B2D563122300254800DE +:105B100000A0541000032E07F0B24C00C013EB8E0F +:105B2000E602E8038C01EB32EB8EE602E903101388 +:105B30000040EA92EB12E8098400EB32EBCED50587 +:105B40003E47F0B13E17F0B25452BFFF44000FFF82 +:105B500092A2D00A0213002684034250807390A2BE +:105B600012530025D503125300250203002512030A +:105B70000026F8455A100403F8424E42008092086D +:105B800096015410000C9022C23C8440960F4011A4 +:105B90000406E240400784242E17F0B24C10401552 +:105BA0002E17F0B1E624E8048C213E17F0B12E1731 +:105BB000F0B1E624E902EBCEEA92EB12E8098400A8 +:105BC000EB32EBCED5053E27F0B13E07F0B2020333 +:105BD0000025120300268400EBB6501F80058005C7 +:105BE000EAF1EAB9F839EB29001F80079401400077 +:105BF0000440001F800588013E07F0B04800008384 +:105C0000960F40110406E240400784242E17F0B49A +:105C10004C1040182E17F0B3E622E8048C213E17F2 +:105C2000F0B32E17F0B3E622E802841FEAD7EA9217 +:105C3000EB12E80B84003E07F0B3841FEAD7D505CA +:105C40003E27F0B33E07F0B48400EBB68005501F4A +:105C50008005EAF1EAB949FFFF25EB56001F8006EF +:105C6000940540000480001F8005400004602E174A +:105C7000F0B0FE0F10030059D545541000032E0755 +:105C8000F0B24C00C013EB8EE602E8038C01EB325D +:105C9000EB8EE602E90310130040EA92EB12E809EA +:105CA0008400EB32EBCED5053E47F0B13E17F0B2A3 +:105CB000540280FC920210030059CA2492A82E07B5 +:105CC000F0B4974F4C02C01B2E07F0B3E602E80475 +:105CD0008C013E07F0B32E07F0B3E602E90410533F +:105CE0000041D503841FEAD7EA92EB12E80B840047 +:105CF0003E07F0B3841FEAD7D5053E27F0B33E57E1 +:105D0000F0B4FC81FC6080C12E1010E581625A1055 +:105D1000010544A00708D50344A003E85A00010583 +:105D20005A00023EF80C441397DCA4483C2C041A99 +:105D3000964BC2035A2805068400EB314800009AAE +:105D4000B44B662100044E23009540C080135426B6 +:105D500000039FD35C7380013E77F0B63E7010AABB +:105D6000CF0C2E37F0B7CB0B2E57F0B5DA063C2D03 +:105D7000FB595CF103E8E8028400EB3154908003A6 +:105D8000800C80273E97F0B5F838CF5C2E17F0B71F +:105D9000C13E3C1DFB59E341E955D539EADFA4403A +:105DA000EAA1964BC0CA5A0005C9EBFEE60AE961B2 +:105DB000B40BEAB3C85E40C08013540600039FC30F +:105DC0005C7380013E77F0B63E7010AACF0E2E278E +:105DD000F0B7CA0D2E57F0B5D808EBEE5CF003E92A +:105DE000E9048401EB31D5038400EB315490800346 +:105DF000800C80273E97F0B549FFFE42CF2E2E172C +:105E0000F0B7C1053C1DFB59E341E92784013E077A +:105E1000F0B68400EBB6EAA15A00042C000300455A +:105E2000100300462E07F0B610030045C8220203F7 +:105E30000025C8058401EBB6120300268401EB316E +:105E4000D518C0EA84001203001F8026800C84410C +:105E5000806B8087F80BD5E0C0DF84001203001F41 +:105E60008026800C8440806B808749FFFE2FD5D42C +:105E7000FCE0DD9EDD9E4422AB4AB6404432AC7667 +:105E80004422ABAEA881A8C94422AC128460B641BA +:105E9000ACC4ACC5ACCCACCD8420B4A08061992995 +:105EA000ACE0990A8C22ACE05A1840FBA1018400B6 +:105EB00080204432AC7698A0AC5098838C02AC50D1 +:105EC0005A0864FBDD9EFC21A4C0842096DB121FCF +:105ED00080033C57EEE9848084CF447001EA9661E8 +:105EE0005CF08064E80A4020840903000000A440BC +:105EF00052210031964BD50A0300000050227F9CAE +:105F0000A4409041964B52210031FEB49691FE542C +:105F1000EAB68830964BAC40A440964BE061E8036B +:105F2000A4C096DB8C818C025A48C8DB123F8003E8 +:105F3000EA6B960340028007FCA1C80E3E07EC3CCA +:105F4000A40EC80684013E07EC3C8400DD9E5A0086 +:105F50001FFB8401DD9E84003E07EBFEA40FC806F4 +:105F600084013E07EBFE8400DD9E5A0831F4D5F92A +:105F7000FC442E4010E0802080022E27DDFAE282D1 +:105F8000E8043C57EEF6D5033C57EEF8E282125F88 +:105F90008000E8052E47DDF49723D5042E47DDF574 +:105FA00097238440124F8001122F8002C806509020 +:105FB000800CB4E1FB90D5065090800EA1C945003D +:105FC0000032225480004E9300079CA94023882071 +:105FD000A490F80C4647FFFF50420FFF50287FFF68 +:105FE0008885DA0840439020A4A09693122F80025F +:105FF000D5179521411390008C8488870268800012 +:10600000A4A097B39693E046E80702488000972340 +:10601000124F8002D505A5209723124F80029529A3 +:1060200098BCA590022F80028AC297B3126F80039A +:106030005A30010448000067EA6BEAB49603964BB5 +:10604000E02050287FFFE81DE0A2E8078C828887C7 +:10605000A420F805F808AC20F8328EE29643EAEA6C +:10606000960383FFFE0C44100064EB2440307C0A4E +:10607000F082F383F002F103960383FFAC38D53E40 +:10608000EAEAE0A296C3EA6B9643EB1097835001CD +:10609000FF9CFE0C400018165000006441107C0A62 +:1060A000F084151F8005E80B8C8299BCA430F81091 +:1060B000F086F187F006F1079603AC3022048000E9 +:1060C0004E07001D407380200203FFFF83FFF4048E +:1060D000F50596034222802440107C0AEBE542003D +:1060E00010698460882244200064EA53F086F187B6 +:1060F000F0068EE29603F107AC3884013E07EC3CD3 +:10610000FCC449FFFF1CC01C2E1010E03C07EF022E +:106110005CF080248420E902EA76022F8003880163 +:1061200096932214800044300064FE9C40738420C7 +:106130009603A478400100169A089603AC38FCC474 +:10614000FC208480C83AA4D610308009847FA90C32 +:10615000A90D8381BC8ABC8BAECCAE0D80C045112D +:1061600065C0B482F83B4E37001CF83F0500800440 +:10617000A0CDF845A8CDA6CC8CC1A90C97B35A38B0 +:10618000FF03AE0CA6CDE003E902AE0DB46283813D +:10619000BC0B88E3A4F8BF0AF849BB8ABC8B8C010E +:1061A0005A0820E184004E670007A416B44240015B +:1061B0000020A400AC08FCA0A41710008008841FD5 +:1061C000AE0E8400AE0F8400A90EA90F8381BC8C93 +:1061D000BC8D80C0451164F8A11195C18887A4E0E9 +:1061E00096DB83FF4E37002DA52038388101972399 +:1061F0004241906883FF05008006A0CF8890E2901E +:106200008865886F83FFA8CFA6CE8CC1A90E97B3EF +:106210005A38FF03AE0EA6CFE003E902AE0FA0D1BD +:106220008381BC0D88E3A4F8BF0C96DB4051FC0AC7 +:106230008867E2678885888F83FFBB8CBC8D8C0163 +:106240005A0832CC84004E670007A417A091400181 +:106250000020A4005CF00191AC09E90584013E0036 +:1062600010DFFCA084003E0010DFFCA0FC6080C1B9 +:106270002E168ED64E120099814680E495314090BC +:106280001000020480002EB728922E6728B49603CF +:10629000C34CF87DF84B4E0200884E7300864015C3 +:1062A0002CD7808797B19649800744216640E20148 +:1062B000E808383100008C01888397219601D5F8D1 +:1062C0008400806044216640E223E90838510C00D4 +:1062D0008C618805960196D9D5F82E1001CE8E01D5 +:1062E000E2814040BC1B2E1001CF96018460420029 +:1062F00080013C7C017F80A3E204E90D40239020D3 +:10630000A450964BE061E804A4D080A496DB8C8175 +:106310009721D5F302248000405314A044115BA8B8 +:10632000961338209400D533F8329603EB73EBBE06 +:1063300083FFC03ACF39406518572E1001CC949393 +:106340009691E2419C174020BC1B2E1001CD960176 +:106350004200800197B13D0C017E80878027E202D8 +:10636000E90D40580820A4E896DBE083E804A5285E +:10637000802297238C419691D5F3022480004060BF +:1063800098A0441155689613382098004220086858 +:1063900050010032E2028023882F84604420006490 +:1063A000EA539603EB73FCE0FC658180220F80309A +:1063B000F0832E072892F0822E0728B4F0842E074F +:1063C0002893F1818162F38681C4049F8016227F25 +:1063D000802E006F8064F08540A104084E42008743 +:1063E000F0024011001654D000FF55C000FFF0022B +:1063F00050807FFDC60F440163785CF68002382030 +:1064000009018481E90340447007800C802B806E71 +:10641000F8E0F8844020F020A450F8E7F8F0AC5001 +:10642000B429421070735CF68002B62940A470074C +:106430008401E902800A96005CF68002F0848401FF +:10644000E902800A9600F085854144816378F00670 +:10645000E20AE94B405E28014E5500144165A8014F +:10646000C607F817F404F81DF508056F8007F82033 +:10647000F8BBE020E806F8244026A801F8C0F82977 +:10648000F002405E2800E0A0E82B4165A800C6109D +:10649000401B001338245901800C806E83FFF405E3 +:1064A000F588156F8007F895F508056F8007416638 +:1064B0005820020B000083FFF897E020E811F1015B +:1064C00041509420021A800083FF40253400F89741 +:1064D000121A8000B42942100873B62983FF5005B0 +:1064E000000154A000FFD5B4FCE5F0044001001603 +:1064F0009640548000FFF005F18251C07FFDC60E2A +:10650000440161E8E62238200901E804404E2007F2 +:10651000D501800C802B8460F85C894C020500005A +:10652000F10183FF4020A020A450F85FF868AC5030 +:10653000B42942102073F002B629E60240AE2007CB +:106540008400E802800A9600F087F00285A144E109 +:1065500061E85DC00002F006E20DE96040543401DC +:106560004E550022F00443568024C6104025D40125 +:106570009651800C382709018460F407F589155F6E +:106580008008F827F509055F80084005D401F82840 +:10659000E020E809F82F121B0000F1024020B401AE +:1065A0004E00FF9AF00540543400E0A0E832F004B9 +:1065B00043068024C6134005C000808A96413827D0 +:1065C00001018460800C404E701AF589150F800817 +:1065D00049FFFE4EF509050F80084005C0004156F1 +:1065E0000020020A8000F10396038A0783FFE0205F +:1065F000E810F10141609420021B00008820964BB6 +:1066000083FF121B0000F102402684004E00FF644D +:106610005006800154D000FFD59FFCE5FC68812026 +:10662000EA448101F387838585405A0001042EA73F +:10663000DDDC3C13EEECF1868420F18EF18FC41288 +:106640005A0801053C17EEF1D5033C17EEF0121F76 +:10665000801A5A0801053C07EEF2D5143C07EEEF0C +:10666000D5112E07EC3C5A0001092E07EBFE5A000B +:1066700001053C07EEF4D5028004120F801A3C0796 +:10668000EEF3120F801B4E83001F84001281000462 +:10669000A814A8152E7728922E0728B551110008A6 +:1066A0005131000C04C10000F0852ED7DDF6506199 +:1066B000001081C7FAB0455000C050BF8038443147 +:1066C0006378D51C8400AC158400A816A8172E7713 +:1066D00028B45111000A5131000E04C100012ED717 +:1066E000DDF750610018F78544500032455000C86E +:1066F00085C150BF803C443161E8840012088000AD +:10670000840080203A030420842082C982018041D1 +:1067100002F88000020B000040F4BC2002F7800069 +:10672000960341278011E1C0E803122880000A0B7C +:1067300000018C41960340F07C0A880141700406F8 +:10674000898F9691802089974C2AFFE4B6068400B1 +:1067500015030001802C80408C0196011A208001D5 +:106760004C02FFFC2E068ED6026880005A08011CDF +:1067700040049820A40038119901960342008068D3 +:10678000442000648460F48BF58A153F8009151F4E +:106790008008EA539603051F8008053F8009F50A23 +:1067A000F40BD50540049820A4009603F106E001FF +:1067B000E805F1078400AC08FCE84E83000C406358 +:1067C0001C16120980000208800040701CF697F821 +:1067D000D50A40631CD61269800002088000400080 +:1067E0001CF697F8C41402098000C0099E694C0089 +:1067F00080075A0001058EA24C02C0062E07DDD587 +:10680000EBFBD5082E07DDD4EBFBD5042E07DDD638 +:10681000EBFBEA445A080107000F80338C01960015 +:10682000EBFBF83B52640001964B960397B00228AD +:1068300080008086F84F80AD151F8006F856051F32 +:10684000800602388000CF0440270C00D507F005F1 +:106850008E014C70400D4021B80196914004882073 +:10686000A4009603E140F82DF83EFCE84051B80141 +:106870004021B8004044942040348820A420A458EB +:106880009603964BE02040050013E816A460A498F8 +:106890008A229649E201E82B003F8033021F801ACA +:1068A000020F801B83FF964B9603F181F08296A91D +:1068B000F813F819FCE8A458A4E08A239649E201E9 +:1068C000E816003F8033021F801A020F801B964B90 +:1068D0009603F181F082B77F15CF80038009802C69 +:1068E00083FF9691808680AD49FFFD60FCE8FC4007 +:1068F00081408400EB0D8400AC088121AC10802421 +:10690000A01D80E280C444200032806A8481EAF2C3 +:1069100084A0EAAFE2A0E817A0319469380015011D +:10692000D810A0320224800038001501E240E802AD +:10693000EB73A03338000401A478E220E802AC38FD +:106940008CA1D5E884003E07EF5EEAAF5A08011239 +:1069500002148000E628E80DA4785CF080B4E80911 +:1069600004130008B4215EF08209E9033E07EF5EDC +:10697000FCC03C23F7B19641500080645CF100C834 +:106980009601E8242E27EF5B5A2801065010805A02 +:106990009609DD9E5A2002062E37EF645A38020609 +:1069A000501080509609DD9E5A2003045A38030681 +:1069B000501080469609DD9E8E44E649E9048E64B7 +:1069C000E669E804501080329609DD9EFC002E171F +:1069D000EF015A1801122E17F0AC8C219648E62BC5 +:1069E000E8043E17F0ACD50F842A3E17F0AC8420A3 +:1069F0003E17EF01D5082E17EF5BC9053E17F0AC27 +:106A00003E17EF013C1394ADAC40AC442E17292C3B +:106A10005A180115EB45A6485A1803112E17EF5BBB +:106A2000E625E8082E1729B2AC402E1729B2AC444F +:106A3000D50544100078AC40AC442E1729435A18B1 +:106A400001423C1DFB48C93E2E27292C5A28013BF8 +:106A500080C0DD4CA6005A080306840AF804AC3056 +:106A6000D531800149FFFF87AC302E07EF025A086D +:106A70000104EA5FAC30EBB7B401920596175A00F7 +:106A80000105B401EA70C81E2E07EF645A08011B05 +:106A90003C0C00A7A4005CF00051E9142E07F0ACF8 +:106AA000E60AE8103C0C00A8A641C1035A181F0BC7 +:106AB000A6008E0BE61DE80684013E07EF01EA5FA3 +:106AC000AC30FC80440395B7A640440395B6A600BD +:106AD00040000504DD9E440395B9A600441395B813 +:106AE000A64840008104441F6A4488205CF0805A14 +:106AF000E903440095BCDD9E440395B4A600EAC8B2 +:106B0000DD9E440395B4A600EA55DD9E440395B589 +:106B1000A600DD9E441395BAA6089600C00EA608EE +:106B200096005A00010BA60896005A000207A60814 +:106B300096005A0003038400DD9E9600441395BB23 +:106B4000AE08DD9EFC00446395B4AE704412E87854 +:106B5000B6018401A9891020800910008008103036 +:106B6000800A1000800B80018024490036D6A630B0 +:106B7000FC80FC0084414400B1008420806280825B +:106B8000EAA984003C0FFB863E07EF4CFC80FC40EA +:106B90002E0728922E2728C22E3728934210082429 +:106BA0003C1B94512E1728C3924142418424FE1C61 +:106BB00092213E2728C93C4B94523C0B94623E17CD +:106BC00028CA4402FE85A640842184C0AE40A64166 +:106BD000AF813C6FFB48EB37500000204900416516 +:106BE000EA583C0FFB5849FFE57749FFE5C64403E7 +:106BF0008D364412FE5C44238D34B6C1AD90AD8019 +:106C00003C0FFB4E44038D303C0FFB6644038D313B +:106C10003C0FFB5444038D323C0FFB402E072933BD +:106C20003C1FFB453C2FFB4C3E67EC395A080106E4 +:106C3000B401EA95B601D504B401EA7BB601B4010A +:106C4000852140002404B601B40184C0EAB3B60132 +:106C5000B4018540EB34B601B40184E0EA7DB601AD +:106C6000B401EA4AEAAEB601B4013C0FFB69440341 +:106C70008D36A44066108002AC40A44066108001AE +:106C8000AC40A44066108008AC40A44044038D345E +:106C9000AC402E0729383E07EC1DEA403E07EC26A3 +:106CA000EA433E07EC2A3E67EC683E67EC593C9F9E +:106CB000FBE23CABF6543EA7EC723E67EC633E67EA +:106CC000EC2C3E67EFA73E67EBF8EA9FEB483CAB46 +:106CD000F64C3CABF6573E97EC563E97EC0A49FF14 +:106CE000E8B5DD403E67EC863CABF64E3E67EC8790 +:106CF000AF813E67EC073E97EC4C3E67EC04AF80FB +:106D0000DD5484023E67EBFA3C9E00663E67EC3041 +:106D1000EBCC3E67EC0F3E67EF9DAE08DD58AE084A +:106D2000EADDEAC43C0803703C0803744402E470E2 +:106D30003C0E01B94402E2EC3C0FFB5F84083E07C5 +:106D4000ED543E67EC103C7FFB4F3E67EC463E97B0 +:106D5000EC3F3C7BF6663CABF65D3E67EC053E6780 +:106D6000ED783E67ED552E0728933E0729C580072D +:106D70003E67ED563E67EF5D3C7FFB6E3C7FFB67F9 +:106D80003C7FFB5D3C7FFB4A3C7FFB613C7FFB49DA +:106D90003C7FFB743C7FFB623C7FFB393C7FFB41CB +:106DA000F8028009490069578007F8203C0E00A4CA +:106DB0008009F81C3C0E00A58402F8183C0E00A6C1 +:106DC0008403F8143C0E00A78404F8103C0E00A8BD +:106DD0008405F80C3C0E00A98406F8083C0E00AAB5 +:106DE0008407F8043C0E00AB8408490069433C0E5C +:106DF00000AC3C0394513C0B955C3C0394523C0B1F +:106E000095C53C03955F3C13955E400080203C0B8C +:106E100095603C0395C83C1395C7400080203C7F9B +:106E2000FBE63C0B95C93E67EF94490063183C0FA5 +:106E3000FB6B490062ED4402E8F03C0E02B3EA72DB +:106E40003C0E02B54402C51C3E67EDB13E67EDB095 +:106E50003E67EDB23E600AC83C7E02B43E600AD88E +:106E60003C0FFB6F845F3C0DFB6B843F38201C089C +:106E70008CE65A783CFA3C0DFB6B84C0EB87101013 +:106E8000003DEB413E07EC513C6FFBE33C6FFBE404 +:106E90003E67EFA13E67EFA03E67EFA23E67EFA31C +:106EA0003E67ECF83E67ECFA3E67ECF93E67EC585B +:106EB0003E67EC6B3E67EC273E67EC4F3E67EC3D70 +:106EC0003E67EC543E67EBFF3E67EC373E67EC698C +:106ED0003E67EC483E67EC0D3E67EC663E67EC7142 +:106EE0003E67EC183E67EC2D3E67EFA64900204553 +:106EF0003E67EFA43E67EC153E67EC3B3E67EC1740 +:106F00003E67EC62EB3749003F3FDD4CAF80EA4E15 +:106F10005A080104490044B38401EB4FEAA7EA2769 +:106F20004900028784C14900027D840044138D41D9 +:106F3000AE08EB7E3C1DFB3F3C1FFB6A842BEB182D +:106F4000842AEB4AEBB93E07EC708420440061A828 +:106F50003C1FFB7584E63C1FFB703C1BF6613E1733 +:106F6000EC0B3E17EC283E100C0C3E100C0D3C0EAA +:106F700003028404EB0A3C6E00903E17EC2F3C1E8B +:106F800000913C7E00923C0E0093DD41C0304410E5 +:106F90000190440397ECAC404410011D440397EE6C +:106FA000AC40441000E4440397F0AC40441000C7E8 +:106FB000440397F2AC40441000AA440397F4AC4059 +:106FC0004410008E440397F6AC4044100072440312 +:106FD00097F8AC40DD47440397FAAC40EA504413BD +:106FE00097FCAC08441397FEAC08D504FD0349FF99 +:106FF000E1A18401EA62EAC1840584C084E044120C +:10700000E8B0EA524402DD683E77EC353E77EC4169 +:107010003E77EC603C6FFB713E77EC1F3C6E0306E5 +:107020003E77EC4B3E600C1449FFF7274400012CDF +:10703000EA934402FEFC3E7010C13E77EC1CAFC0E8 +:107040004402FEFDAFC049000A8BEB583C6BF65F73 +:107050003E77EC493C6BF65580263E67EBF984465B +:107060003E67EF0AAF804402C458EA3F8026844658 +:107070004402C4C8EA3F44038D45AF8044038D46B3 +:10708000AF80FCC0FC21446200B88006490039C0D2 +:10709000EA36F08149FFF3CE9C3449FFF3CE50032A +:1070A000007849FFF22E500300A849FFF3C95003AE +:1070B00000CC490067CAEA36F081490067C950032D +:1070C00000B049001BCBEA36F08149001BCAEA3602 +:1070D000F081490023D750030118490000B4EA3673 +:1070E000F081490000B3490000CF5003012C490052 +:1070F0002180507303A0EA36F0814900217D80078A +:107100004900217DEA36F081490057435003017060 +:10711000490058B35003031849006509EA36F08165 +:107120004900650850030364490065EBEA36F081C5 +:10713000490065EA50030374490058A7EA36F08114 +:10714000490058A680074900615DEA36F081490090 +:10715000615C500303AC49002A67EA36F0814900BC +:107160002A603C0DFB45EBD7500303D049FFD544C3 +:10717000EA36F08149FFD54350030048490047E90A +:10718000EA36F081490008C5EA36F08149001EF26E +:1071900049FFF67149FFF67049005872490064D101 +:1071A00049FFD530490065B349005875FCA1FC0082 +:1071B000DD54840284C03C6FFBE3AE08DD58AE08AA +:1071C000440000A2EB75DD40A6015A080D118006AF +:1071D000847F3C2DFB6B843F383100088C065A08B5 +:1071E0003CFA3C0DFB6BEB871010003D4900003171 +:1071F0003E07EF81EB4184C0EBC73E67EBF84900E7 +:1072000000FA8401EA753E07EC43EBC0EA4E3E67A4 +:10721000EC503E67EC1E3E67EC655A080103EA7FBE +:10722000FC80FC018401EAA7EB22EA8DEA208400BD +:10723000EA5B3C1C01CFEB2AFA50EB06EBCD840154 +:10724000FC813C0FFC34DD9E3C0FFC33DD9EFC00DA +:10725000840084203E07F0CA3E07F0C73E07F0C610 +:107260003C1BF8623C1BF8613E17F0C93E07F0C8B2 +:107270004410004084003E17E9C63E17E9C53C0FA4 +:10728000FC35FC803C0DFC34A4413C1BF860A4445C +:10729000A6003C1BF85F3E07F0BCDD9EFC003C1DD9 +:1072A000FA6BA6088C01AE083C1DFA6BA608960482 +:1072B000C8063C0DFA6D3C0FFA6AD5053C0DFA6C18 +:1072C0003C0FFA6A3C0DFA6AA6481010003F80A0F5 +:1072D0008420EAE95000003CEAE9D8FFFC803C2D1C +:1072E000FA6AA65098D1AE199C0996005CF0003B52 +:1072F000E9028400AE10A6108840841FAE11DD9E06 +:10730000FC00EAE12E57EF18D00BC804EB5BDD421E +:10731000D50444000051DD42EAE13E07EF18EBB32B +:107320002E57EF19D00CC80544000054DD42D50497 +:1073300044000053DD42EBB33E07EF192E07EF8107 +:107340002E57EF1AD00CC80544000056DD42D50375 +:10735000EA43DD422E07EF813E07EF1A2E00167535 +:107360005A00AA048407DD42FC80DD9EFC0049002F +:10737000339AFC8044100055DD46AE40DD9EFC0390 +:10738000F0818005F283F182F384F485490033496A +:10739000F002F103490036A1DD47DD46AE40F001C1 +:1073A000F104F20549003639FC83FC2084C080E0FA +:1073B000E2C7E80B8401844080208062808080A244 +:1073C0008CC1DD5697B0D5F5FCA0FC0049003758BC +:1073D000FC80FC0049003746FC80EB42C8082E17B1 +:1073E000EF06C907FC0049003756FC808400DD9E8B +:1073F000DD9EFC0049003307FC80EB3FC80CFC001D +:10740000EB4149003300FA09EA32EB41EBC749008E +:1074100032FAFC80DD9EDD9EFC004900380AFC80CB +:10742000FC00490037FCFC804401F120DD9E441340 +:107430000FA0B62044138068A845441373E8A846FB +:10744000EB4DA84244130C80A84444133F905020B5 +:107450000044B62244123200A851441274F8A853D2 +:10746000DD9EFC4480C0440155083B004C004401B3 +:107470005518EBE9B1C43B004C003B03CC20EBCFEB +:107480002E172D12813F420004019640C1038E2128 +:107490009648EB668386B88A38038602B88B442008 +:1074A00000C84402DA4442008873B89344031F4082 +:1074B000B88944038DD4B88CFCC4FC20842CAE4124 +:1074C00084003C0FFB91EA9849FFE25BEABB3C0D6C +:1074D000FB91C00B8420846184028041808380A35F +:1074E0003C1FFB91DD56FCA0490033745A0801F49F +:1074F000AFF0D5EEFC0049003364840149003366E7 +:10750000FC80A4408C2196495CF08190AC40E90954 +:10751000FC008405DD428400EA2CEAAAEA6CFC80C7 +:10752000DD9EFC20FD30DD41C01FA770DF0A8CA16D +:107530009768E6A5E90284A0EA40AF70EA9FD50DFE +:107540008406DD4244138D20A6088C019600AE0807 +:107550008400EA2CEA43EA6C44038D20A600C004B0 +:1075600084013E07EFA2FCA0A6885A28AA0AFC00C4 +:10757000A680AE888420AE4049003704FC80DD9EA2 +:10758000FC00EA425A080417DD455A000214EAA337 +:107590005A08011184003E07EBF88400EBBCEAD6E0 +:1075A0004402C38D49FFFFE2840384203C2DFB404D +:1075B000EBE0FC80A6885A20AA10FC00AE80442F85 +:1075C000FFAAAE88A6005A080105490036D5FC80FE +:1075D000490036D8FC80DD9E8440AE808400AC0833 +:1075E000DD9EFC005A08010549003515FC80490064 +:1075F0003513FC80FC0084204403F560AE408423F6 +:107600004403F561AE408400802080408060EA3B06 +:10761000FC80FC0084234403F560AE4084204403D6 +:10762000F561AE408400802080408060EA3BFC80B1 +:10763000FC004402FE63A7404403F007A600D808FC +:107640004402FE64A7404403F004A600D006441F91 +:10765000FF8EEBBBAE40F80A4403F007A6005A00C9 +:107660002311441FFF9EEBBBAE40843F4402FE61EA +:10767000AE408420840280418461808180A1DD56F7 +:10768000FC80FC24440155383B004C004421554803 +:10769000EBE9B004EBAC3B004C20EBFAA6904411B4 +:1076A000D80040108840A6C838500A028400384FDD +:1076B0008A0296D84462623880E03C139462E20108 +:1076C000E81840230020030100003812800042180F +:1076D00004243902010140108C0E8A309649AC50C6 +:1076E000A450964B4E140003ADD08C019601D5E604 +:1076F000FCA4FC01F08194918001F101DD49FC8141 +:10770000FC0644220000FAD0A6D2A71384A184402C +:10771000F68584C2F283F284F286F288F289B67F1B +:10772000F581F382F687F58A8041EA48FC86FC0001 +:10773000C805EA79EAB5EA20FC8049FFD55E80A059 +:10774000C8F9EA794413000244226238EBF22E476A +:1077500028934900300CFC80FC00DD5580C0A64910 +:1077600049FFFFE75A680306EB3FC80349FFFF8B59 +:10777000FC80FC2697D0FA5084C084A1F285844214 +:107780009718F287B6FFF581F782F683F684F686BE +:10779000F688F689F58A80418067EA48FCA6FC06EF +:1077A00044420000A7A284A0A723F581F582F583B7 +:1077B000F584F586F588F58984A1F285F387B6DF2F +:1077C000F58A80418066EA48FC86FC07F38DFA70F2 +:1077D00084A08082F38584418462F281F482F387FD +:1077E000F28A8064B6BFF583F584F586F588F5895D +:1077F0008041F40DEA48FC87FC01EB0BEB4DEA20DD +:10780000EA8DEB22EA208400EA5B3C1C01CFEB2AE4 +:10781000FA50EB06EBCDFC81FC08F18EF08D802355 +:10782000F28FEBF2C4052E4728938003D503800422 +:10783000848184A1B61FF0828400F083F184F085F6 +:10784000F086F088F089F08AF581F587F00DF10E69 +:10785000F20FEA48FC88FC01DD455A08021A840050 +:10786000EA5B8481EB0BEB4D442373E8846049FFB2 +:10787000FFD5501F8006EAC684408463EBE6220FE2 +:10788000800344100096EB4740008007FC81840091 +:10789000FC81FC2544620000A7F2A7B3F381B0C7C6 +:1078A000F3848460F482F583B6DF808380A7490087 +:1078B0002DCEFCA5FC008401842049003416440030 +:1078C0000CD54900341AFC804403F01F4423F30212 +:1078D000A600A650540000E096678C225EF080203F +:1078E000E807A650966788018C029600D5038C1F86 +:1078F00096004413F01FAE08DD9EFC00840080203B +:107900004900309B4900350B49003BAA49FFFFD491 +:1079100049FFFFDC4900337E49002E6A4900355E8D +:1079200049002FD649002F8049FFC65BFC803C03ED +:10793000F4E43C1DFA734423F540B4423820820A33 +:107940004423F544B4629C819691EAEF4423F548C0 +:10795000B4629C829691EAEF4423F54CB4629C8316 +:107960009691EAEF4423F550B4629C849691EAEF35 +:107970004423F554B4629C859691EAEF4423F5586C +:10798000B4629C869691EAEF502000083C2BF4E408 +:107990008C074423F55CB44296013820820ADD9EB0 +:1079A000FC015A0801163C0DCA41B61F3C0DCA42E3 +:1079B000F0813C1DCA3C3C0DCA3B3C2DCA3D3C3DC0 +:1079C000CA3E3C4DCA3F3C5DCA40F815D516C815A5 +:1079D0003C0DCA39B61F3C0DCA3AF0813C1DCA3471 +:1079E0003C0DCA333C2DCA353C3DCA363C4DCA37E6 +:1079F0003C5DCA38490030F2EAE45A0801093C0308 +:107A0000F4E45CF00080E80349FFFF9384008020E9 +:107A10008040806049002F1849002EF3FC814423E8 +:107A2000F077A6509604EB1BFE0FAE10DD9E920081 +:107A3000FC2080E080C1DD45A6B9C80650017FF674 +:107A4000E6028409E9028002EA21EA28AE8844239A +:107A5000F380A6505A1001FF4E6300668E01E60EB9 +:107A60004EF200CA44F07870EB2B40F03C00DD0F82 +:107A70001C0084012200AC002200AC00AC002800F5 +:107A800028005E005E00AC002200A8008403EA9695 +:107A9000F8488400F895F845840149002FB984001E +:107AA000F895EABC5A0801064400088EEA32D50867 +:107AB0008440840184248062808280A0DD56840119 +:107AC000EAF38401F88ADD45C82AEBDAD528EAEB27 +:107AD000C005EAE4C0038400EB728401F87E8400F0 +:107AE000F875EABC5A0801064400088EEA32D50847 +:107AF0008440840184248062808280A0DD56EBDA99 +:107B00008400F85EEAEB4E020077EAE44E0300746C +:107B10008401EB72480000708401EAF38400EA9665 +:107B20004800006A5A6801628E03E60CE86444F07B +:107B3000793CEA8B40F03C004A003C000C120C12ED +:107B40001218187070B80C8C8401F83AD55484015E +:107B5000EA96D551EAEBC011EAE4C00F8400EB725B +:107B60003E07F0983C03F4E43C1DFA738E01940246 +:107B7000B60184013C0BF4E4EAEBC80D8401F8265D +:107B80008401EA9644000037EA328400F826840033 +:107B9000F829D531EAE4C8F33C5DFA7384213E1735 +:107BA000F0D850128200AA29D9FFD5E9EAE4C0052D +:107BB000EAEBC0038400EB728401F80884014900F9 +:107BC00031D8EAEBC8A3D517840149FFFEEB49FF82 +:107BD000FD138401EA96840049FFFF238400EAF341 +:107BE000840049002F15D5075A6802068401EA96D9 +:107BF0008400EAF3FCA0FC40EA4280C15A08040B6E +:107C0000EAA3C008DD455A080213842049FFD66F55 +:107C1000D50EDD455A0002F88401DD5084208461D0 +:107C200084028041808180A3DD56D5F48402DD503A +:107C30008441440001A04410003080628082EAA99F +:107C400084208461440001A080418083EAA95A0015 +:107C5000300E84414410003080628082440001A0D4 +:107C6000EAA9440000D7DD42D5ECEA425A080410E4 +:107C7000DD455A00020D2E77292B5A78010980071D +:107C800049002FA48400EA2C8007EB84EA74EA7C84 +:107C90003C0DFB91C0078404DD50EA425A08041FE2 +:107CA000D50949002F975A0801F88403DD50EA5995 +:107CB000D5F0DD455A000213EAA35A0801108400EA +:107CC00049FFDE1D441FFFC34403F429AE40DD40DD +:107CD0008420DD578402AE31D50F80468405842090 +:107CE000EBE0DD408420DD578402AE3184014900A1 +:107CF000315F8405DD50FCC0FC20EADA5A00010443 +:107D000048000065DD454E030062DD59A6405A1863 +:107D100001FFA6005A08015BDD4BA78097B05A68A7 +:107D20000156DD408429AE418420DD57DD40842AA0 +:107D3000AE41DD4180E0DD59C70D8420AE40DD4B12 +:107D4000AE408006EA2C8409EA392E07EF09EA6E74 +:107D5000D53DAFC0DD4BAFC08006EA2C4402FEF239 +:107D6000AFC0DD47DD46AE40EAA2C0FF49FFDD2BD4 +:107D7000EA26EAB1AE08804184618402DD44DD4038 +:107D8000EBD22E07EBFF5A0801102E07EC485A08D9 +:107D9000010CEB30C009EA2B5A0801068403EA25DE +:107DA0004900265CEA78DD4B8421AE408401EBFC7F +:107DB0005A00010DEAA35A080108DD40A6015A083D +:107DC0000A04490025EF8400EA63FCA0FC43441147 +:107DD00055588140A600B1823B00CC003B034C20AB +:107DE00085205A0801054900471081208400EA5B7C +:107DF00084E0EB5138031E02842094918CE1EA3F29 +:107E00005A7804F9EAAF5A08011C8403DD55804909 +:107E1000EA4DEA9E2E17EC14440000C8FE0CEA5B03 +:107E2000EB4DF80344130FA0EB2A2E2728922E3790 +:107E30002893EBCD49FFFF62DD54A608C8FFDD475C +:107E4000DD46AE408400FCC3FC2184C0FA003E67DE +:107E5000EBFB44738D40DD424900376384013E678C +:107E6000EC423E07EC0E3E07EF5A3E67EF723E676C +:107E7000EC2B3E67EC2EAFB8DD45DD555A08020B02 +:107E80008404AE0980018420DD57DD40842DAE419D +:107E9000D50A8409AE0980018420DD57DD40842A9B +:107EA000AE41AFB8DD598421AE40EA4E5A08010E0A +:107EB000DD4CA6003E07EC44EBAAA6003E07EC080A +:107EC000EB7CC8033E07EF72DD40A6013E07EC5D88 +:107ED0008406DD50EB09C814DD40EA412E0729363F +:107EE0005A0801044900215D840ADD50490022A49A +:107EF000EA4EC04BDD455A080249840BDD50EA4E7C +:107F00005A080110DD41C00DEB095A0001052E078A +:107F1000EC2BC8074402C6E2501F800749FFFF58F8 +:107F2000EA4E5A08012BEB09C80B44000066DD50ED +:107F3000490022F65A08010C3E07EBFBD508440025 +:107F40000067DD50DD54A6085A0801FF44000068B0 +:107F5000DD50DD41C008DD5C5A0807FFEA79EAB56B +:107F6000EA20D505DD54A6085A0801FFDD54840235 +:107F7000AE08DD58AE08D509DD41C007EAAADD50DC +:107F8000DD4CA60049FFFBEA84003E07EF5ADD45C1 +:107F9000DD552E27EC5D5A0802089E12E602E8061F +:107FA000840DAE09D5075A200204AE89D503840B8F +:107FB000AE09DD40EA418400EA87EB983E07EC1009 +:107FC0003E07EC0E84C14400006ADD503E67EC2B96 +:107FD000DD41C00349FFF9273E67EC23DD45C804B6 +:107FE00084013E07EF544400006FDD50FCA1FC000B +:107FF000EADA5A08011FDD45C81CDD59A6405A18A7 +:1080000001FFA6005A080116DD4BA78097B05A68F9 +:108010000111DD408429AE418420DD57DD40842AF2 +:10802000AE41DD548400AE08DD58AE088006EA2C6F +:10803000FC80FC00DD40A6415A10061C2E17EC0DFA +:10804000C9182E67EC69CE15DD54A6485A180112DE +:10805000DD58A6485A18010E8026EB3BDD57DD5946 +:10806000AF802E07EC4EC803DD58AE088401EA2C21 +:10807000FC802E07EC20842140008006DD9E440316 +:10808000F07FA600EA5EDD9EFC0049FFFFFAFC805F +:10809000FC4080C2812080E1EBF8490031B54420EA +:1080A0001900FE14E206E8138AC0442186A040238A +:1080B000085710248000440E796096904261007346 +:1080C00044001388406300D7AFB8FCC0842010146C +:1080D0008000AE78FCC0FC00EBF8EBF5FC80FC0106 +:1080E00080C08001F281EB61F001EBA284013E07C8 +:1080F000EF56A6303E07EF558400EB6E8401EAF69A +:10810000F8F12E07EF565A0801098440802080625A +:10811000808080A2DD56D5F6FC81FC0080C0800105 +:10812000A648C1058421442000CDF807A630C00729 +:10813000800684244420008249FFFFD38407EB613A +:108140008400EBA28400EAF6FC80FC20A78080E09B +:10815000E6CBE9068ECA840A97B0AE38D50284C051 +:10816000A638C0038C01AE38A638E603E9038C01BB +:10817000AE38A638C8038401AE38A608C004EA7633 +:10818000FE0CEA32C6059431EAA449FFF910A6783C +:10819000C107844084028461848380A2DD56FCA0F0 +:1081A000FC02F08180C1F80CF201F8725A680209F1 +:1081B00084013E07EF50EAF0EAFAF862D505EAFAE0 +:1081C000EAF083FFF869F88EFC82FC21FD30F28131 +:1081D000DD45C82C5A700907461000F45000824053 +:1081E000D505461000C3500085005A60011DC60425 +:1081F0005A600205FCA1F876FCA12E27EF4F2E371E +:10820000EF4ECA02C310441186A0FE5C846AEB855F +:10821000443FE70042010C738A0184203E17EF4E71 +:108220003E17EF4FF10149FFFFBDFCA1FC2080E0AC +:1082300080C1DD455A08020ACF1ADD40A6415A1016 +:10824000041349FFFEF8D513DD40A6415A100B1068 +:108250005A6004068006844349FFFFB9DD40A64109 +:108260005A180904EBEBD50349FFFEC3FCA0FC023E +:10827000F081EAF0EAFAF201F80BEAFAEAF049FFD3 +:10828000FF66FC82FC02F081EAF0EAFAF20149FFA3 +:10829000FF01EAFAEAF049FFFF42FC82FC004600D7 +:1082A00000A650000040F80DFC80FC00F81BFC808C +:1082B000FC00F818FC80FC00460000A650000040BE +:1082C00049FFFFD7FC80FC00EBE7EBD1EB05FC801E +:1082D000FC00F808FC80FC00EBE7EBD1EB05FC8030 +:1082E000FC0049FFFEFAFC80FC00EBE7EBD1EB055C +:1082F000FC805A080408FC00EA50EA2EEA3AF80228 +:10830000FC80DD588401AE08EADD83FFDD9EFC00C1 +:108310003C0FFC39DD41C805F8073C0FFBA5D50E25 +:10832000F8033C0FFBA649FFF8813C1DFC39A68AE7 +:10833000A64B420104733C0FFBA4FC80FC004413D9 +:10834000F69280C08403AE08FA4F4413F6AEAE88AE +:108350004413F6AFAE084423F6A084204403F6A1EC +:10836000AE50AE404403F6A2AE404403F6A3AE4086 +:108370004403F6A4AE404403F6A5AE404403F6A67B +:10838000AE40A6F040110C7CA60854218007846101 +:108390004021880CFE878400AE88FA6F80208040E0 +:1083A000EA3BA6705CF08032E8038C21AE70FC8062 +:1083B0008E239648E628E824FC0080C284414011C0 +:1083C000040C543080B1CB049656C914FC80500084 +:1083D00000569600E602E9133E27EC49DD41843F52 +:1083E000C803441FFFEF4402FF5FAE408402AE307B +:1083F000FC80500000569600E605D5EEFC80DD9E20 +:10840000FC418140F381840084613E07EC733E07A8 +:10841000EC5F3E07EC4580E181223E37EC3D3E3784 +:10842000EC754402FF505A280307EB94AE403E37E8 +:10843000EC0DD50A44100045AE403E37EC695AA811 +:10844000AD043E37EC454432FF57EAD1AE18500533 +:1084500000559600E60280C3E806840449FFDE95D5 +:108460003EA7EC82EB44AE3054038002C01BEB9479 +:108470004402FF57AE405A98030ADD41C00444024B +:108480003220D53344027220D530DD41C00444028D +:108490003224D50344027224F82884003E07EC837A +:1084A000D52684013E07EC49DD414412FF5FC0033D +:1084B0008411D503440FFFE1AE084462FF57EB4639 +:1084C000AE3049FFDE5044000045AE30CF0B5A902D +:1084D00003D6DD41C00444023224D507440272248D +:1084E000D5045A780105F00149003534DD4B84216B +:1084F000AE40441000474402FF57AE40FCC1FC2090 +:1085000080E180C2C00D5A00041184003C0BF65873 +:1085100049003A75444395AC443395AAD50A44437F +:1085200095A6443395A4D505444395AC443395B002 +:1085300084009680E246E807381381013812010969 +:108540008C01D5F83C03F658AC18FCA04402FF504F +:10855000DD9E4422FF5038100808DD9E4452FF5033 +:1085600084204402FF70EAE9D8FFDD9EFC00EA8324 +:108570002E17EC715A18010784403E27EC583E171D +:10858000EC078420101000503E17EBFF3E17EC5410 +:108590003E17EC6E3E17EC0D3E17EC713E17EC45A6 +:1085A0003E17EC693E17EC4D3E17EC483E17EC6663 +:1085B0003E17EC373E17EC1849FFFFD2FC80FC4019 +:1085C00080C0EA8380E04492FF54EB44EA342E17E3 +:1085D000EC734402FF55AE402E07EC735CF00032A2 +:1085E0004EF3006EEAD2EA34EAC584003E07EC732B +:1085F0003E07EC5FEB46EA34DD41C80F4492FF547E +:10860000EBDEEA34EAD1EA9744000047EA34DD4180 +:10861000C826EA28EA21D527EB693C4DFC3904102D +:108620000014EA829230EA6AEB80B4418400924AF4 +:1086300096B744530000FB880212001AE201E8DFFB +:1086400094C1985DA448B5A64210C024887140101A +:1086500088378C019649AC589601D5EFEA50EA2E3E +:10866000EA3AD507000380515A00BB04AE88D5FB17 +:1086700044100048EA69AE40DD4B8421AE408400DE +:108680004413F692AE084413F6AEAE084413F6AFA8 +:10869000AE08840080208040FA6FEA3BEA78DD4132 +:1086A000C007EA8DEAE5EA20EA8DB426EA208400D4 +:1086B0003E07EC3D8401EA35EA30F895FCC0FC4009 +:1086C00080C0EA8380E044100042EA69AE402E1781 +:1086D000EC735A180218EB94AE40DD414E0200864E +:1086E000EB27A640EA37EA389648AED05A100C0677 +:1086F000A6409648EA29D5FBEA79B426EA20480044 +:108700000075E6234EF3007244100044AE40EAC503 +:10871000DD41C80844100045EA69AE40DD41C82388 +:10872000D5133C0DFC3984A00200001A443300002C +:1087300092019401D0F098ABB426A490882596912C +:10874000AC888CA2D5F84492FF5444000047EA3428 +:10875000EB44EA9744000048EA34DD41C824EA28A3 +:10876000EA21D525EB69442FFE01041000144402D0 +:1087700000609230EA6AEB80B4213C0DFC39922A09 +:108780009677FE540240001A964984409611E204FE +:10879000E8DBB46640318820A4188C41880196013A +:1087A000AC18D5F5EA50EA2EEA3AD5070003805115 +:1087B0005A00BB04AE88D5FB44100049EA69AE40BC +:1087C000DD4B8421AE40EA78DD41C007EA8DEAE561 +:1087D000EA20EA8DB426EA2084003E07EC3D8401BD +:1087E000EA35EA3049FFDCB48401FCC0FC00EB8BC5 +:1087F0005A080109EB02EAD1AE30EA2749FFFEE14F +:10880000D50AEBA65A080117EAD1EB02AE30EA27E7 +:1088100049FFFF5744000048AE30DD5BF986440055 +:108820000049AE302E07EC738C013E07EC73FA035F +:10883000FC808401FC80FC4381203C0DFC390464F5 +:1088400080050270001AEA2B5A0801072E77289338 +:108850000464800C95FAEB1E4402FF55AE40EBA574 +:10886000EB1EE2204EF20078EA6944100042AE406E +:108870003C03F6528C013C0BF6528400EB8CDD413C +:108880004E0200B83C53F6525A580120EBDFA64086 +:1088900096483E17F0E09667581080A0AE40EBD89F +:1088A00049FFFD378400442FFF804430007F96410C +:1088B000E2274EF2009F3C1DFBA6EACD3C1DFBA427 +:1088C000383080088C01D5F4EBA59201D0068C01DC +:1088D000D00480268400D52549FFF7904800008AFF +:1088E0003C5DFBA63C2DFBA42E47EC7188A02032FA +:1088F0008000382100105A480106A508972390826D +:10890000AD08A5089723E064E910A5089723E08245 +:10891000E917AEE83C3DFBA48C22382180088C018D +:108920009681E247E9DED565A4C896DB5EF18080DA +:10893000E804A4C896DBD5EA4430007FD5E7A488D4 +:1089400096935EF17F81E904A4889693D5E3442F42 +:10895000FF81D5E0DD535A000105EA2B5A08012FAB +:10896000DD41C00BEA2B5A000106DD40A6015A0882 +:108970000A268401EAFBD522EB595A000112840130 +:10898000EAFB8402120F8006B0434402C41AF08549 +:10899000A8093A108C00EB2849FFD817D52A2E07D2 +:1089A000F0E18C019600E602EB8CE805DD59A600AB +:1089B0005A0801208401EBA7D51AEB305A00010BAD +:1089C0008401EBA78402120F8006B0434402C42E38 +:1089D000D5DF2E07F0E18C019600E602EB8CE8056E +:1089E000DD59A6005A0801068401EAFB8400EB8CDD +:1089F000EB30C05FEB59C05DEAC5EB94EA69AE406D +:108A0000DD41C01D3C4DFBA63C5DFBA484209609C6 +:108A1000E207E811380204103822840080C9A0F56A +:108A20004021010494098860AC98A0F68C21880349 +:108A3000AC80D5EE2E17F0E0EBDFAE40EB46EB025C +:108A4000AE30EA2B5A000104EAD2EA97440000450E +:108A5000AE30EA2EEA50EA3AEBDEAE30EA2B5A08A4 +:108A60000125DD455A0802078403EA2549001FF65F +:108A7000D51C2E67292B5A680119DD40A6015A081A +:108A80000915EA258405DD4AEA4CEB3E8406DD4AF9 +:108A9000EA78DD4049001F44F08184408402F101FE +:108AA0008066808680A2DD56EA788401EA35D52E7C +:108AB0002E67EC715A68012BDD455A08020E441FDF +:108AC000FFD14402FF56AE408404EA25DD408026F3 +:108AD000DD57EB1AD51B2E67292B5A680118DD408C +:108AE000A6015A080914EA258405DD4AEA4CEB3E42 +:108AF0008406DD4ADD4049001F13F0818440840272 +:108B0000F1018066808680A2DD56FCC3FC002E0742 +:108B1000EC545A08010FEAD1EB02AE30EAC5490025 +:108B20001BF4EB44AE30DD5B49FFFBE5EAD2D51523 +:108B3000EA2B5A0801162E17EC185A180113440F85 +:108B4000FFB1EB02AE308400EA468400EA61EA94A9 +:108B5000EA27F946440FFFB9AE30FA03D502840183 +:108B6000FC80FC22EA8380C0EB1E4402FF55AE402D +:108B7000EBA5EB1EE2204EF200B644100042EA697B +:108B8000AE403C03F65284208C0196013C0BF65219 +:108B90003E17F0DF5A08013BEBDFA64096483E1730 +:108BA000F0DE9667581080A0AE40EBD849FFFBB1CD +:108BB0003C1DFBA584408001806180E2445F800011 +:108BC00044407FFF5CF100C0E809AD5812418320AA +:108BD00012518190124184B0D508ADC012700320AB +:108BE00012700190127004B08C419691125080C89E +:108BF000124083E812508258124085788C628C2291 +:108C00008C025A28C8E1480000913C1DFBA5840055 +:108C1000804145029ECA447F80004512A1EA40502F +:108C20004000A56822310320976B22410000E0A399 +:108C300042429000E806DF04443F8001D50280658F +:108C4000AD101231032040504400A568223104B019 +:108C5000976B22410190E0A342429000E806DF04B6 +:108C6000443F8001D50280658C021241019012318F +:108C700004B08C425A0980D584004472A05A444FF3 +:108C800080004502A37A9947A568222083E8976B64 +:108C9000223080C8E0A242328C00E806DC04442F77 +:108CA0008001D5028045123080C8122083E84050F0 +:108CB0004000A56822208578976B22308258E0A278 +:108CC00042328C00E806DC04442F8001D502804546 +:108CD0008C0212308258122085788C225A0990D545 +:108CE000D524EB595A0001118401EAFB8402B041FA +:108CF000EAD84402C41AF083A8093A108C00EB2881 +:108D000049FFD663D5122E07F0DF8C019600E605E9 +:108D10003E07F0DFE805DD59A6005A080107840187 +:108D2000EBA784003E07F0DFEB30C036EB59C034D0 +:108D3000EAC54472FF54EAD2AE3844129ECA3C2DB2 +:108D4000FBA5443006408402DD4444000045AE38B3 +:108D50003C2DFBA5EB6250210640443006408402C6 +:108D6000DD44EBDEAE38EAD2EA9744000047AE3885 +:108D7000EA28EA21000300515A00BB04AE88D5FB63 +:108D80002E17F0DEEBDFAE40EA6944100048AE403B +:108D9000EA788401EA35FCA22E07EC485A0801154E +:108DA000FC00EA69EB93AE403C1DFB6480C05A189E +:108DB0000105EA2749FFFED744000049AE3084018F +:108DC000EADDFA03FC808401DD9EFC202E67EC487E +:108DD0005A68011D4472FF54EAD1AE38EA2749FFB0 +:108DE000FD2C44000049AE388400EA30DD4BAF80F2 +:108DF000DD455A000225EAA35A080122DD40A601FA +:108E00005A080A1E49001DCED51A2E07EC665A08CC +:108E10000119441FFF90EA69AE40EA782E07EC5131 +:108E200049FFF2E9DD41C004EA50EA2EEA3AEB419B +:108E3000EBC749FFF2E0DD4B8421AE40FA03D502D7 +:108E40008401FCA0FC00DD41C80884024412FF60DC +:108E50004422FF50FA60DD44FC803C03F86E8C0134 +:108E600096015CF000FFE90284003C0BF86E3C13B5 +:108E7000F86E4402FF52AE40DD9EFC4049FFD687AB +:108E8000EA429E46E622E90A50107FF7E625E90607 +:108E90005A001105840148000075DD40A6015A08FA +:108EA00004148404441000BDDD43440000D0DD50B0 +:108EB000DD41C01F840049FFCE438401DD4AEAA89A +:108EC000EA74EA7CD50B8E08E604E9ECDD455A0825 +:108ED00002EAFA31EA6FAE40D521A6305A002105E8 +:108EE000EB03EA59D5FB8402DD4A8400EA63D51618 +:108EF0002E07F01EC80884024413970044238D54A3 +:108F0000EA90EA718406DD4AEA26FA11AE08804149 +:108F100084028461DD448400EABE8403DD4ADD40CE +:108F200084C0A601DD4A490025A1440000D1DD50DE +:108F3000DD459E4240130406840249FFCCD8DD453E +:108F40005A08010B80064900281580064900283080 +:108F5000800649002823440000D2DD50DD40441241 +:108F6000C6F03C2DFB454432C514490041F980C090 +:108F70005A00080448FFFF90440000D3DD508006EB +:108F8000FCC0FC40EAC549FFEE0449FFF4B8DD40EF +:108F900084C1AF8149FFF078440000A0EB75EB7706 +:108FA000DD5549FFF62A44000051DD50EA74EA7CA1 +:108FB00049FFF867C8053E67EF7DEA59D5FA840096 +:108FC0003E07EF7DEB5BDD50FCC0FC00840FDD4213 +:108FD000840444100062DD43DD47DD46AE40EA8C88 +:108FE000A608C8FF44000082DD5044000083DD5025 +:108FF000840149FFD62F44000084DD50FC80FC0032 +:10900000840444100061DD43441000678404DD43A0 +:109010008404EAFD440000A1EB75DD404412C3D88E +:10902000EAD5EB91848049FFE1A8EA8A5A08010950 +:109030004402C368EBC849FFF2D1490029A3DD54BB +:109040008402AE08DD58AE0849FFFFC18404441015 +:109050000068DD4349FFF6FAEA8A5A08010449002C +:10906000298B49FFF0A68402DD4284044410006984 +:10907000DD43FC80FC00EA8380C0840CDD504403A7 +:109080008D47A6408C219648AE40DD47DD46AE4078 +:109090008409441000A1DD4349FFF274840944109F +:1090A00000A2DD4349FFDA1D8409441000A3DD431B +:1090B000DD40A6415A180D0E8409441000A4DD437A +:1090C0002E07EC105A080115FA05DD4284C2F80E8D +:1090D0002E17EF9CC9F24412C3DF4422C6F04900A8 +:1090E0004279EAF45A0801EA84C1480000ED840993 +:1090F000EBADDD432E07EF0BC00AEA89A6405A10FC +:109100002105A6005A0822048401EA30DD5B5A08D2 +:10911000190449FFDA43EBDB5A08011CDD5C5A08ED +:1091200007198400EBC0EA4E5A080112DD4CA60074 +:1091300049FFF3935A080107EB7C5A0801043E07E4 +:10914000EBFB2E07EBFBC003FA06DD428401EAA726 +:1091500084003E07EC322E07EC75C810DD5C5A081F +:10916000070E840AEA49DD558401EA303E07EC32F5 +:10917000DD4CA600A64949FFF2DC2E07EC685A0830 +:10918000010C4402C3D8EBB7EAD53C3DFB4E3C4D45 +:10919000FB4C49FFDAFDDD41C013840C0013005085 +:1091A000DD43840D00130051DD43840E0013005293 +:1091B000DD432E07EBFF5A0801048400EAA63C0DAC +:1091C000FB775A080142DD59A60096005A08013D76 +:1091D00084203C1FFB772E17EC645A18551B2E1762 +:1091E000EF0CC104EAA6EAD3D516EA89A6005A080C +:1091F000130544000086DD42EB77DD554422C38D24 +:109200003C3DFB454442C51449FFDCD8EAD3D503B5 +:10921000EA43EB48DD5B49FFD7F196003E07EC0AD5 +:10922000DD4A2E67EC0A5A60034F5A68020EFA04B0 +:10923000DD422E07EC7CDD42DD47DD46AE40DD54ED +:10924000A608C0FFD540DD54A6085A08020EDD4B23 +:10925000A6005A08020A8401AE08DD58AE08DD45B2 +:10926000C80349FFF843DD40A6015A080A08DD4556 +:10927000C80349FFF81C49FFF5412E07EC325A0894 +:10928000010DDD4CA6005A080309EB3FC806840215 +:109290003E07EC3249FFF1F7DD5B5A080404490050 +:1092A00036E52E07EC655A00010448FFFF1F8400D5 +:1092B0003E07EC65DD58A6089600C8FE8441AE88DE +:1092C000FAC3EA308006FC80FC01EA8A5A080106EB +:1092D0004402C3688420EB01EA4E5A0801044900A5 +:1092E00038B0DD4CA6005A08030CEA4E5A080109B2 +:1092F0004900354984023C1DFB44EB60D50E490012 +:10930000288AF081F1018400EB602E07EF015A08F2 +:1093100001058402842FEB60DD40A6415A180D043C +:109320008423AE41440000A3EB752E07292D5A0873 +:10933000010BDD40A6005A080107DD4CA6004900DC +:1093400029B3D504EB0BEB22EA20EA274412C460D0 +:109350004422E204443200004442DE5049FFE2FF6E +:10936000FC81FC002E07292E5A080108EA27441226 +:10937000D73849FFE253D5053C0C01C1EBEAEA209E +:109380002E0729435A08010E4402C6D44412C6D2FD +:109390004422C6D04432DE5C4442DA0049FFEAA9E6 +:1093A0003C0DFB45B400EA555A00010384003C0F14 +:1093B000FB4884013E07EFAADD5B5A081209EAACBC +:1093C0008421EAC95A080104EA2EEA3A2E17EC1D54 +:1093D0005A1801054402C368EB01DD5B5A08120A02 +:1093E000EAAC8422EAC95A0801058402EA2EEA3A64 +:1093F000FC80EA4BC80BFC004403307049FFE56574 +:10940000C007FA18EA938403FC808404DD9E84017B +:10941000FC80FC6680C0EA472EA728922E8728B5DC +:109420002E9728B42EB72893C00944C3343C44D3A4 +:1094300033D844233374EBAFD50844C21B3044D235 +:1094400019A044221810EB14CE2F84E1FB70852262 +:10945000806A808880A78041F80B44034C10EA485A +:10946000EB15EA3144035890DD49802D804DB75FFC +:10947000F78114AF8002F683F68414BF8005F68668 +:10948000149F8007F688F689F78A83FF44034F30DC +:10949000806A808880A7EA4844134F30EA31440349 +:1094A0005BB0DD49FCE65A68012F84E0FB10854281 +:1094B00080228069808B80A644034DA0F80BEA4887 +:1094C000EB9ADD5E44035A20DD49440350C0802CF2 +:1094D000804CB73FF681149F8002F783F784148F86 +:1094E0008005F78614AF8007F788F789F68A83FF2F +:1094F0008069808B80A6EA4844035D40441350C0D5 +:10950000DD5EDD49FCE6FC004E02005AEAC6EA31A7 +:109510005A181420EB15DD4944134F30F81F44123C +:109520009ECAF821440383884412A1EAF82BEA4733 +:10953000C003EBAFD502EB14F824EA47C004441390 +:1095400033D8D503441219A0EA31EBFFDD49FC8082 +:1095500044135890DD4944135BB0EA314403770863 +:10956000DD49EB62EA3144038068DD4944038388C6 +:109570004412A82AF807EA47C003EBAFD502EB1460 +:10958000EB71EA31DD49EA47C004441333D8D5030F +:10959000441219A0EBFF4E00FFF6441386A84402C4 +:1095A000AB4AF86AF8064402AC12441389C8F8645E +:1095B0003B0054003B00D42083FFFC8044037578BB +:1095C000DD5E5A181420EB9ADD49441350C0F81F91 +:1095D0004412A05AF822440385184412A37AF825AD +:1095E000EA47C00444133374D50344121810F82614 +:1095F000EA47C0044413343CD50344121B30F82915 +:10960000FC8044135A20DD4944135D40DD5E440371 +:109610007898DD494412A69ADD5E440381F8DD495D +:10962000440385184412A9BADD5EDD49EA47C00447 +:1096300044133374D5034412181044037BB8DD5E21 +:10964000DD49EA47C0044413343CD50344121B30BF +:10965000DD5E44037ED8DD494423883880224402FD +:10966000ABAEEAA044238B58EA85F806F80844021A +:10967000AC768022F801EAA0EA8583FF3B00500027 +:109680003B00D02083FFFC80FC40C8053C5DFB64B0 +:10969000C508D5405A08013F3C5DFB645A58013B60 +:1096A0002E57EC0984C38EABE2C584C0E9052E6752 +:1096B000EC098ECB97B1C0085A08010B44700032F8 +:1096C00080A78604D508FAF084A68207D50484E032 +:1096D00080A782078124EAC644400190425814249E +:1096E000420310735A181406802294A9DD49D50448 +:1096F000802394A9DD4944100064EB714203047394 +:1097000094B98029DD492E07EC095A080E04840813 +:10971000EADEFCC0FC012E27EC2F5A20070448008B +:1097200000A7E6104EF200A4F18144F095383817F6 +:10973000810140F0BC00DD0F20002000200020004F +:109740004C006000740086009800AC00C000D4009B +:10975000E800FA000C0120012E57EC098C0B4C504C +:109760004087DD5CC8048401F101F807DD5C5A0024 +:109770000103F8078400F10149FFFEC78408EADE0F +:10978000480000768400F10144234C104433589083 +:109790004442AB4AF86AD56B8401F10144234DA0E1 +:1097A00044335A204442ABAEF860D561442216805F +:1097B0008400F10180624442AB4AF857D5584422F4 +:1097C00018108401F10180624442ABAEF84ED54FCF +:1097D0008400F10144229ECA4432A50A4442AB4AA5 +:1097E000F844D5458401F1014422A05A4432A69A96 +:1097F0004442ABAEF83AD53B8400F10144234F30EC +:1098000044335BB04442AC12F830D5318401F101ED +:10981000442350C044335D404442AC76F826D527FB +:10982000442219A08400F10180624442AC12F81D68 +:10983000D51E44221B308401F10180624442AC7683 +:10984000F814D5158400F1014422A1EA4432A82A73 +:109850004442AC12F80AD50B8401F1014422A37AE8 +:109860004432A9BA4442AC7649FFFF10FC81920011 +:10987000FC602E4728922E2728B52E3728B42E17A5 +:1098800028934E0300F442320824405204099061A8 +:109890008020449320D044A3226044B3271044C3C3 +:1098A00028A045234C1045334F30E023E82C4020BE +:1098B000949797209489CC02961040412400A520CB +:1098C0008C214112001140412800A52096484102F8 +:1098D000001140412C00A5E0884C9501A590402244 +:1098E000480013110000988594914111480097FB9E +:1098F00097B3889388538C01130880009600ADE0DD +:10990000AD90D5D4EAAD5CF000A04EF301575A00FB +:10991000A0095A00A10B4462A1EA44129ECAD508CC +:1099200044634F30EB15D504446219A0EB142E07A5 +:10993000EC12E602E82D3C0DFB685CF01388E905AB +:1099400084003C0FFB68D5048C013C0FFB68EA31B6 +:10995000EAC6DD498026EA3144037578DD494410C2 +:1099600000C144037572AC40EB2CA4004413757421 +:109970009603AC08EADFA400441375769603AC089E +:10998000442373E8EB15EA248402EA71F8719E829D +:10999000E642E821EA31EB71DD498026EA314403F1 +:1099A0007BB8DD49441000C244037BB2AC40EB2CD1 +:1099B000A40044137BB49603AC08EADFA40044136C +:1099C0007BB69603AC0844237578EB9AEA248402AC +:1099D000EA71F84E9E84E642E823EA314403806847 +:1099E000DD498026EA31440381F8DD49441000C393 +:1099F000440381F2AC40EB2CA400441381F49603A1 +:109A0000AC08EADFA400441381F69603AC084423B3 +:109A1000770844134F30EA248402EA71F8298E064D +:109A2000E6024EF200CBEA31440386A8DD498026E7 +:109A3000EA3144038838DD49441000C444038832C5 +:109A4000AC40EB2CA400441388349603AC08EADF46 +:109A5000A400441388369603AC0844237898441332 +:109A600050C0EA248402EA71F8035A000104480055 +:109A700000A540518409FECC84209061800144936C +:109A800023F044A3258044B32A3044C32BC045238C +:109A90004DA0453350C0E003E82C40201497972098 +:109AA0009481CC02965040412400A5208C014112A3 +:109AB000001140412800A5209600410200114041BC +:109AC0002C00A5E0884C9509A59040224800131170 +:109AD0000000988D94914111480097FB97B38893AB +:109AE00088538C21130880009648ADE0AD90D5D402 +:109AF000EAAD5CF000A0E9615A00A0095A00A10B90 +:109B00004462A37A4412A05AD509446350C0EB9A28 +:109B1000D50544621B30441218102E07EC12E602E1 +:109B2000E812DD5E44037708DD498026DD5E4403EC +:109B30007898DD494413525044237A28EA24840259 +:109B4000EA71D53B9E82E642E811DD5EEBFFDD491E +:109B50008026DD5E44037ED8DD49441353E0442370 +:109B60007BB8EA248402EA71D5289E84E642E81292 +:109B7000DD5E44038388DD498026DD5E440385186D +:109B8000DD494413557044237D48EA248402EA7178 +:109B9000D5148E06E602E811DD5E440389C8DD496E +:109BA0008026DD5E44038B58DD4984024413570050 +:109BB00044237ED8EA24EA71FCE084004412DEE407 +:109BC0008040382081098C014432DEE45A08C0FB11 +:109BD0008400804098588C02122080C85A0990FC5A +:109BE000FC203C4C01C184A084C344700640A420E6 +:109BF0005412801F4022A009402088A096033901FA +:109C0000890140001816881038018909400294091A +:109C10000A22000194024000047C9693500000C880 +:109C200040111836382181018CA18822976938119A +:109C30008109DFDEFCA0FC662EA7289280C02E875B +:109C400028B52E9728B42EB72893C0035A080104CC +:109C500049002429EA47C00944C3343C44D333D8DB +:109C600044233374EBAFD50844C21B3044D219A04F +:109C700044221810EB14CE2284E1806A808880A7E9 +:109C8000F8064403589044229ECAEA48B75FF78119 +:109C900014AF8002F683F684F685F686F787F68899 +:109CA000F689F68A83FF44035BB0802D4422A1EA43 +:109CB000806A808880A7EA48FCE65A68012384E02D +:109CC000802244035A204422A05A8069808B80A6B7 +:109CD000F802EA48B73FF681149F8002F783F784C1 +:109CE000F785F786F687F788F789F78A83FF4403B5 +:109CF0005D40802C4422A37A8069808B80A6EA484C +:109D0000FCE6FC2080C080204402D73849FFDC6795 +:109D1000CE584452A50A443D5AF64442DEE484E358 +:109D20004422A68A982B38120011A4284462DEE44B +:109D30009603E020E908EA44C802EAB6A4288A01AA +:109D40009603AC288CA2DAEF848180A44402A50A91 +:109D50004432D9388420EB43F8BC84003C0FFB59D3 +:109D60003C4C017E806080A02E2010AD9860C20F18 +:109D7000A48896934E27000CA48850217FCE9693FA +:109D8000AC88A48896934E240003AD48A4488C0266 +:109D9000964B88615A0840EA84403C3FFB59440294 +:109DA000DD6880628421F85BEB438400EBC3F896A6 +:109DB0004452A82A444D57D684604422A9AAD55DAE +:109DC0005A6001044800008D4452A69A443D5AF658 +:109DD0004442DEE484E34422A82A982B381200117E +:109DE000A4284462DEE49603E020E908EA44C802BD +:109DF000EAB6A4288A019603AC288CA2DAEF842163 +:109E00004402A69A4432D938808180A1EB43F8619C +:109E100084003C0FFB653C4C017F806080A02E20BD +:109E200010AD9860C20FA48896934E27000CA488AA +:109E300050217FCE9693AC88A48896934E2400033D +:109E4000AD48A4488C02964B88615A0864EA842184 +:109E500080413C3FFB654402DD68846049FFE08A45 +:109E6000EB438401EBC3F83A4452A9BA444D57D6A8 +:109E700084604422AB4AD51A8025380090053813F7 +:109E800004119603E020E902ACE88CA2DAF6842003 +:109E900080814402A82AEB0F4432D8C084A1F8196B +:109EA0008400EBBAEB0FF81AD51B8025380090051B +:109EB000381304119603E020E902ACE88CA2DAF62C +:109EC00084214402A9BAEB0F80A14432D8C0848017 +:109ED00049FFE3A68401EBBAEB0F49FFE133FCA095 +:109EE000FC004432C3A34402D938EBBAEB54490016 +:109EF00040A8EA72EBC32E27EC3349004E27EA72E2 +:109F0000EBC3EB438461F805EB0F8460EBBAEA72B4 +:109F100049FFBEB2EA72490042202E17DE41EA72C2 +:109F200049004EFAEA72490046ACEA724900425EC4 +:109F3000EA72490049D0EAA1C0035A08050D84011C +:109F40003E0010AE3E0010AD84003C080859841F4E +:109F50003E0010A92E0010A95A00FF0684003E0002 +:109F600010E4D50484013E0010E4EA722E17DE41AD +:109F700049004FCF8401FC80FC002E07EC1EC80373 +:109F8000EA30D5068401EA3084003E07EC1EDD5B32 +:109F90005A08120AEAAC842FEAC95A080105840F4C +:109FA000EA2EEA3ADD4B8421AE40EAA35A080108C2 +:109FB000DD40A6015A080A04490014F4FC80DD9E25 +:109FC000DD9EFC002E07EC39C8432E67EBFB5A6878 +:109FD000010C2E07EC6FC80849004A4DC805EB3547 +:109FE000C8033E67EC72EAE1C81F2E07EC6FC81C7D +:109FF0002E07EC72C8192E07EBFB5A000116490018 +:10A0000006F05A080208FA02DD4284013E07EC72AB +:10A01000D50B4402E2043C1394BE4422C3D349004E +:10A020000DCE5A0002F2DD40A6412E07EC725A1006 +:10A0300006045A180B105A0001092E07EFA65A0001 +:10A0400001052E07EC63C0048401EA46EA75840129 +:10A05000D5245A00010A2E07EFA65A0001062E0742 +:10A06000EC505A0801F6DD47DD46AE40DD54A60847 +:10A07000C0FF84003E07EC723E07EFA68401EB9818 +:10A08000DD5B5A08120AEAAC8425EAC95A080105C0 +:10A090008405EA2EEA3A8402FC80FC2084C02E0764 +:10A0A000EC36E2C0E82C3C0C00A595F138501901C3 +:10A0B000DE243C0C00A84422D73898473C0C00A76B +:10A0C000A649380019113C30037049FFDB043C1CE1 +:10A0D00000A588E1A478FE0FAC383C0C00A738102E +:10A0E00019013C03987EE220E8082E07EC155A007F +:10A0F000FF058C013E07EC158CC1D5D2FCA0FC00FD +:10A10000DD40A6015A000305F83DE603E906DD5BE4 +:10A110005A0005045A08120A84003E07EDB03E07B3 +:10A12000EDB13E07EDB2D5363C0DFB7A5A08010879 +:10A130008400EB674402C51C490049944402E2389C +:10A140004412C52C49004CC03E07EDB2F81B5A081A +:10A15000030784003E07EDB03E07EDB14900499D7D +:10A1600080C05A080110F80E5A0803078006EBFD5C +:10A1700044000061DD42F8065A08040D8401EBFD3D +:10A18000D509490049875A0803068400EA3C84013E +:10A19000EA75FC80FC20EA8A5A0801064402C3687A +:10A1A0008422EB012E0729325A080109EA274412BA +:10A1B000C6F04422DA0049000B684402DE5049FF31 +:10A1C000E407EAA35A08010A2E07EF9C5A08010681 +:10A1D0004402DE5049000AC4EA274412C4884422DB +:10A1E00000008460848549FFDB5FDD5B5A08120A4A +:10A1F000EAAC8423EAC95A0801058403EA2EEA3A44 +:10A200002E0729325A08010AEBB35A080107EBE47A +:10A21000C004EA2749000CC58400441201D03E075F +:10A22000EC57502080144402C6F04900056FEBE45F +:10A23000C8074402C6F04412DE5C49000582EBE424 +:10A240004E02006884003E07EC3EDD5B5A08120AAD +:10A25000EAAC8424EAC95A0801058404EA2EEA3AE1 +:10A26000EA4E5A0001062E0729325A080106440216 +:10A27000019C4900315084003E07EF5C4412DA0033 +:10A280003C0C01C03C2003704432C3A68481EAF236 +:10A290002E0729315A08011B3C0DFB45B4009604DA +:10A2A0005A0001083C0DFB4EA60096045A08010F07 +:10A2B000EBC2C80C4402DA004412DE5C4422C3A69E +:10A2C000490004183E07EF82D50684003E07EF825E +:10A2D000490002D449FFFEE32E0729445A08022A06 +:10A2E000DD4CA600C810EB35E602E90D4402DA00A9 +:10A2F000EBEA4422C3A64432E28C4442C3DF490065 +:10A300000805D51784003E07EFA849000636D51189 +:10A31000EAE15A080106490002A73E07EF82490018 +:10A32000062C84003E07EFA83E07EC363E07EC15EE +:10A33000EA8A5A0801064402C3688423EB012E0707 +:10A34000EC6F3E07EF5B84003E07EC363E07EC6F98 +:10A35000EAE1C8522E17EF72EBC53C0FFBE65A102C +:10A3600001093C0DFBE34420EA60E240E9038C0173 +:10A37000EA3C3C0DFBE44420EA60E240E90D3C236A +:10A38000F7B63C33F668E262E802C1048C01EB13D5 +:10A39000D5033C1FFBE4EABC5A08010F84203C1F94 +:10A3A000FBE32E17EF65EA465CF08032E80A8C2169 +:10A3B0003E17EF65D50684203E17EC273E17EF6564 +:10A3C0002E17292C5A180119DD55A6495A100304D5 +:10A3D0005A180A132E17EF665A1801093C1DFBE4A0 +:10A3E000E622E804C8033E07EF668400EB4F49000D +:10A3F0002F608401EB4FDD535A0802074900483EA5 +:10A40000C0038400EA3C49FFFDDE5A08020448000C +:10A410000097EAE15A0801058400EA3CEB13EA8A56 +:10A420005A0801064402C3688424EB01EAA35A08CF +:10A4300001182E07EF9C5A0801144402DA00441256 +:10A44000E8F02E27EC6F4432C468490007DB49006E +:10A4500009845A0801064402C6F049001297842074 +:10A460003C1FFBDA2E6728993C7C00A63D0C00A718 +:10A470004402E8F0808186214520FFFF453000FF3F +:10A48000E286E83BB440C22BA14738339501131054 +:10A49000000B5CF181004039BC1A1230000A043014 +:10A4A0000009E2234011BC1B5A2003245A20052234 +:10A4B0000220001E0230001FE262E8031220001F8B +:10A4C0001220001D38281501025000201220001E05 +:10A4D0004C5900108CA112500020D50B1220000AFC +:10A4E0001220001D1220001E1220001F122000202A +:10A4F0008C815000004CD5C53C1FFBDA49FFE702B8 +:10A50000EAA19E41E622E9065A00040549FFFDF949 +:10A51000D504DD455A0802FC2E67292C5A68011221 +:10A52000EB3FC810DD535A08010EDD40A6015A006A +:10A53000060A5A000B08490034DFD50480C0D50252 +:10A5400084C18006FCA0FC0149001F65F081F10177 +:10A550008400EB60EB0BEB22EA20EA274412C46094 +:10A560004422E204443200004442DE5049FFD9F75D +:10A570002E07292E5A080108EA274412D73849FF26 +:10A58000D94DFC813C0C01C1EBEAEA20FC81FC00C6 +:10A59000DD5C49FFF96FEA4BC01ADD5CC004DD5C8D +:10A5A0005A080116DD5C49FFF736DD5CC804EA4B4A +:10A5B000EA7DEAC1DD5C5A080105EA4BEAAEEAC170 +:10A5C000EA4B5CF00030E9038400EAC1DD5C49FF3E +:10A5D000FB34DD5CC004DD5C5A080105DD5C49FF2D +:10A5E000FB92FC80FC002E67EBFF5A6001088400A0 +:10A5F0003E07EC2D840148000071840444100040A3 +:10A60000DD432E07EC2DC8058408DD423E67EC2DA6 +:10A6100084044410004ADD43EB0349FFF2795A00F9 +:10A62000025D5A00132C84044410004BDD43DD53BB +:10A630005A0801278404441000AADD43DD4BA7809B +:10A6400097B0CE1C8404EBB1DD433E67EFAA49FF0F +:10A65000F0CF5A00131484044410004DDD43DD4153 +:10A66000C0062E07EC755A08010AF81DF81E5A009C +:10A67000130684044410004EDD43FA03D52E8404EF +:10A68000441000BBDD4384003E07EFAADD41C01744 +:10A69000DD4BA600C8F32E07EC755A0801F08404C0 +:10A6A000EBB1DD4349FFFF5149FFF3915A0013E736 +:10A6B00084044410004DDD43FA03D50FEB63C0035F +:10A6C000EB59C0DC8404EBB1DD4349FFFF6249FF75 +:10A6D000F3655A0813EFD5D2FC80FC00EA8380C0F2 +:10A6E000840CDD50DD47DD46AE408409441000A1F6 +:10A6F000DD4349FFE7478409441000A2DD43DD4004 +:10A70000A6415A180D0E8409441000A3DD432E07FC +:10A71000EC105A080119DD47DD46AE40D50E2E1764 +:10A72000EF9CC9F24412C3DF4422C6F049003752FD +:10A73000EAF45A0801EAF8058401EBFCC0FE840241 +:10A740004800008B8409441000A4DD434402FEF25B +:10A75000A600C007DD40A6415A18030449FFCB8676 +:10A760008409EBADDD432E07EC685A08010C440266 +:10A77000C3D8EBB7EAD53C3DFB4E3C4DFB4C49FF03 +:10A78000D007840C00130050DD43840D00130051EA +:10A79000DD43840E00130052DD433C0DFB8DC035BC +:10A7A000840B44100087DD438400EAA63C0FFB8D38 +:10A7B000EAF85A08550EEB77DD554422C38D3C3D2F +:10A7C000FB454442C51449FFD1F9EAD3D503EA4316 +:10A7D000EB48DD5B49FFCD1296003E07EC0A5A00BC +:10A7E000033C5A080213DD47DD46AE40DD54A6089F +:10A7F000C0FFDD455A0002A5DD47DD46AE408401BD +:10A80000EBFCC0FE48FFFF9D8409441000A6DD4319 +:10A81000DD54A6085A080206DD4BA6005A000205C0 +:10A82000EBDB5A08010F8401AE08DD58AE08DD45A8 +:10A830005A0002048400EBC0DD45C80349FFED5611 +:10A84000DD40A6015A000B0449FFEA588409441070 +:10A8500000A7DD438401FC803C0FFBA8DD9E3C0F7C +:10A86000FBA7DD9E2E07F0E98E019600EBAEC80235 +:10A87000EB5A2E07F0E8DD9E841F3C0FFA7484002B +:10A88000EBAEEB5ADD9EFC63A1054022084001318E +:10A8900000000091000100A1000200B10003862029 +:10A8A000E1A34EF200E0A081385145014C58C0D8D8 +:10A8B000A105415888088895A7A0E4C3E9038EC381 +:10A8C000D50284C0A7612E2728928CA3E0A2E902BA +:10A8D0009F51A6A2E443E9038E43D5028440A723F7 +:10A8E0002E7728938C83E087E9029F39E1264EF387 +:10A8F00000B7E0B34EF300B4E1624EF300B1E08A7A +:10A900004EF300AE42634C004252A40142422C017D +:10A91000F681F58242212800F483F403E0824EF3AD +:10A92000009FE44485A0E90350D17FFD9D13F7010A +:10A93000F485F402E0874EF30090EB6B4453F04A49 +:10A94000AF283C4DFBA780A70082000205600000F5 +:10A9500042512073385B15005A50FF7C057000018E +:10A96000385B95114E540076E4E484C0E9029FBB45 +:10A9700005800005A763410C540000E8000140F782 +:10A980001807E9679D3B51247FFF83C44242480179 +:10A9900001280000E092E95D00C8000340F634079A +:10A9A000E95804FF80058EA1010800024257940176 +:10A9B000E0B0E94F43E238013C4003704306C00079 +:10A9C000838442482024432348004252B001F48447 +:10A9D0008680E0B0E93EF40481D288948892952183 +:10A9E00040FF3807E932386B10005A60FF2B419B5B +:10A9F000982002CC800040F600114EF5002304F0B0 +:10AA0000800540F7900002F7800040F7801140F782 +:10AA1000F007E917442F800040260804122C80001C +:10AA2000406C1840A6B043398801A6B14294880012 +:10AA3000A6B242A50801A6B342B5880048FFFF317F +:10AA400050E700018C82D5CD8D81414A2000D5C2CE +:10AA50008CE148FFFF708C4148FFFF618DA148FFEA +:10AA6000FF21FCE3FC20A612C0038E01AE123C7D48 +:10AA7000FBA7A753A63B8E01D0038CA1AF53A61012 +:10AA8000C0038E01AE10A63AA7518E01D0038CA14F +:10AA9000AF518400A750011100018060E3A5E922B5 +:10AAA000A79201210003E3C6E91BA73A81E542F31F +:10AAB00010730500800540483C20EB7641080011EA +:10AAC000E59AE90CEB7602F200004108001140F72C +:10AAD0008011E06F8810E802A4E08CC1D5E58CA15C +:10AAE000D5DEC306441001F4FE0C40000C17FCA098 +:10AAF000FC6280E0841F3C0FFA743C0DFBA8F181DE +:10AB0000A64381625CF08042E903EB93AE43A6402A +:10AB10005CF08042E903EB93AE40A683A6004410AC +:10AB200003E8FE8C00658000FE44408100134090E5 +:10AB30008013C63D84203C0DFA7480A1E0A6E80F86 +:10AB4000A0B938211501DA09A0BA38211501E2228D +:10AB50004002BC1B40113C1B8CA1D5F13C1BF651A3 +:10AB6000A07D3C0FFA74EA643A000000B0433A005A +:10AB70008020006F800C004F800D001F800F9834E4 +:10AB8000900140A00010000F800E8C218A204430DC +:10AB900000648C819649FE5C9BA697B1406098D674 +:10ABA0008007F101B08397B1F881D503855F8006F6 +:10ABB00050157FFC9648E638E90A4EA500095CF37B +:10ABC0000079E90544907D0044806978E3203EA740 +:10ABD000EC88E9102E17F0E85A18010900158000DA +:10ABE000C1053C13F651E63FE8052E17EC895A18CB +:10ABF000010684003E07EC89D55DE300E90384206B +:10AC0000D56F3C6DFA74442F80008400FEB7003588 +:10AC10008000E003E809A07940108020A548DE020A +:10AC2000AC888C01D5F58007F10196B049FFFE2D67 +:10AC3000A03D401018403A108400B0833A1104201F +:10AC4000003580008C038420E023E82DA0B9385122 +:10AC5000050196AB4E2400255452FFFFD621D92082 +:10AC600000207FFD004F800CE282E903102F800C52 +:10AC700000207FFE004F800DE244E903102F800D7D +:10AC800000207FFF004F800EE282E903102F800E2C +:10AC9000A680004F800FE244E903102F800F8C2123 +:10ACA0008C04D5D38007F101B08349FFFEDDE3209A +:10ACB000E8098401EB5A3C0DFBA88421A601EBAE08 +:10ACC000D50F840000158000E001E89AA0794010BB +:10ACD0008020A4888C0154217FFFAC88D5F42E07F6 +:10ACE000F0E9C00B5A1801053E17F0E8D5068E01B1 +:10ACF0009600EBAEC802EB5A2E07F0E85A080105A1 +:10AD0000842010158000FCE2FC002E17EF808002EA +:10AD10002E2731025A1801073C13F894C10344202E +:10AD200000782E17EF9C5A180103A6843C0C01C032 +:10AD30004412DA004432C3C78480EAF2FC80DD406A +:10AD40002E47294EA6015A0006049721D5032E4707 +:10AD500029502E07EC5A2E272955E202E8068C01CD +:10AD60003C4394AB3E07EC5A2E27EC3E2E07295469 +:10AD70002E37294DE240E92F2E07EC3F5A080130CB +:10AD8000FC2040000C0C8A04960184E0EB51E2E2C6 +:10AD9000E821A18AB44194F988C3884303030000E1 +:10ADA00004508014A49088A3FEA4A4E84220407319 +:10ADB0008CE188432E37294D40310C0D96D9ACF0EB +:10ADC000A4F02E67294D4031980C8A439691ACA887 +:10ADD000D5DEFCA08C413E27EC3EDD9EDD9E2E178D +:10ADE00029375A1001048401DD9EEBE4C842443245 +:10ADF0006EB880803C139462E201E820EBEA4010D8 +:10AE00008020A4883C1394AE9693FE4AE041E8115A +:10AE10009883A6508C219648AE50A6903C1394A9D6 +:10AE2000E241E9093C13F6548C213C1BF654D5034E +:10AE30009843AF088C019601D5DE3C03F6543C13D1 +:10AE400094AFE220E8D184203C1BF65484004432C5 +:10AE50006EB8EB51E202E80698838C01AE50960181 +:10AE6000D5F92E07EFA08C013E07EFA08402DD9EEE +:10AE700084003C0BF6548001DD9EFC2044402710EA +:10AE800080C0FE642200002840208856FE24221341 +:10AE9000005022330000EAFCE022E85240F00DF6B8 +:10AEA000E04FE85044500078FA788024991D400221 +:10AEB000040A5CF00051E904524000A0D5048080EF +:10AEC0005A00280552700078D5034470005038436A +:10AED000111138731D11FF0C40421C96E044E80329 +:10AEE0009F41D504E082E8319CC1E0A3E8E04C0139 +:10AEF000800380A35CF28051E904521280A0D50245 +:10AF00008025507280285CF38051E903527280786A +:10AF10003813051144302710FECC38131D118A82D6 +:10AF2000403184769A9A4242000342210003E08233 +:10AF3000E90CE044E909E2054002BC1AFCA0FA1859 +:10AF4000FCA0EAC4FCA08005FCA05CF00051E9056F +:10AF5000523000A0B661D502B60150107FD85CF027 +:10AF60008051E905520000C8B602DD9EB622DD9E82 +:10AF70003C0FFC3BDD9E4402ED648420AE42AE43B8 +:10AF8000AE46AE47DD9EFC6D8140440166483B0005 +:10AF900044004607FFFF84C051CF8060EAF73B0EB4 +:10AFA00044208121F287F68F81A680A6510F805818 +:10AFB00045E0005645900064F08DA618E2A04EF2E0 +:10AFC000010804048001380015014C02C0FF04048C +:10AFD000800540001440A640F181A68200E00003F5 +:10AFE00001400001F001401708018A148801EB4775 +:10AFF000E4034EF200EB45507FFF40F708064EF3A6 +:10B0000000E5F70140FA1C064EF300DD2F372892C9 +:10B01000B409F08242014C24F40298479449412239 +:10B0200004000119000154F880044EF300C90444DF +:10B03000800101190000F48338B245014CB2C0C050 +:10B04000882A236080004F6700BBC20B51117FFF2D +:10B0500080874248CC733915110113180000D503BD +:10B0600013580000C70B822743114C73F40D89A4B9 +:10B070003915450113180001D5031358000150F983 +:10B08000FFFFE2EFE8060310800113180002D5036A +:10B09000135800022F1728938FA1E251E80941139A +:10B0A000CC0088113805010112080003D50313589C +:10B0B00000039F39420B7824F4899D11F48A9D394D +:10B0C00040006416F48B9F11F08854B580FF840013 +:10B0D000F48C391E010004CF800838484511F484EF +:10B0E000E08CE866411E00200118800138484511B7 +:10B0F000F485E08CE85D5A00020E5A00030F5A00F6 +:10B10000010504CF8009D50304CF800B048F800C88 +:10B11000D50804CF8009D50304CF800B048F800AA3 +:10B12000822C43144C73F402411884088891012244 +:10B130000001F48655290004552900FF4F230039EA +:10B1400089AA23888000F404437C7824417BE6F6B6 +:10B15000E097E82EF405E097E82BF40600F20000F3 +:10B16000F40338F23D004CB7C02440FC5807B0103F +:10B17000E90C38701909B01238201909F80B396038 +:10B18000190913208000D50F38C01909B012388072 +:10B190001909B00F38B01808B01483FF39801909A5 +:10B1A00013288000E6C4E8088CC197B0D5058C014F +:10B1B0005A080491D504804E80F485A18CE148FFA3 +:10B1C000FF238C4148FFFF1B8CA148FFFEF85AD09B +:10B1D00001044800007E808DF207800A8029EAF28F +:10B1E00084404717FFFF80E2808250CF804850DFC5 +:10B1F0008040508F805051188FFF85C2E286E863EF +:10B2000038069101385611012E172892806042327B +:10B21000847382C0802338341101383505092F2703 +:10B2200028929E694360C87382658062856044107D +:10B2300000FF5152800151707FFF51800001502961 +:10B24000FFFF40FA8806E9294025D80086004141E1 +:10B250004400402BC00040FC0806E91C04F48000B8 +:10B26000402A40004027882000F100015AF80211CE +:10B2700001910000B08F38F110004CFCC0058CE14A +:10B2800097F8D5065A18FF0380399C9996D08D817E +:10B29000D5E18DE18972D5D4804380604232C87394 +:10B2A000B58940380C2010E18001EBF2E2E2EBF6C8 +:10B2B000B46940018020E904B04F38109000AE40DE +:10B2C0008C81D59D84013E07EFA88401FCED2E07FB +:10B2D000EF5C5A0801192E472A244422018C84204D +:10B2E00044500073E224E80AA6108C218C0A9600D0 +:10B2F0004200140118010001D5F6800A8029F207E6 +:10B300008481EAF28400FCEDFC20848080C0A7D018 +:10B31000800480A44502C860E2A7E816A0F1383195 +:10B3200095014C32C0100513000296E839189501BA +:10B33000383810088C81E7A697204001BC1AE68CAB +:10B34000E8038CA1D5EA2E57EF5BA0F2E6A2380104 +:10B350008101E90FE683E80D8C81DC0B8E06E61295 +:10B36000E808806280013C200370802649FFFE0DC2 +:10B37000FCA0FC01F081F80740000009F0019E41AB +:10B38000F181C8FBDD46DD47AE4083FFFC81FC0256 +:10B39000F081F001441003E8FE0C50107C5E46037F +:10B3A000A19650000B1F4200806940009409F08371 +:10B3B000F001C802D509EA29F0039E41F183C8FCD7 +:10B3C000DD46DD47AE40FC82FC02F0818400F08364 +:10B3D000D50ADD46DD47AE40440003E8EA32F0031B +:10B3E0008C01F083F103F001E220E9F4FC823C0FD0 +:10B3F000FC43DD9E3C0FFC42DD9E3C0FFC41DD9E8C +:10B40000FC4084E03C2DFC4380C1808780A78625DA +:10B4100004F30000E81250F7FFFC5CF78002E90D2E +:10B42000052300070500000238F849010121000644 +:10B43000E3CFE80311118002B58651287FFFE7C2F0 +:10B44000E9035B0804058C81972080E58CA197684F +:10B450005063004C5A580ADE2F17F123CC068400A3 +:10B460008420AE1A80A1D51FA61A5A00051B5A487F +:10B4700001145008FFFFE602E8042E57F122DFF026 +:10B480004400004C42138073840122508004221037 +:10B490008005AE1AD50884038420AE1A80A1D50396 +:10B4A000842080A1A61A5A0801263C6DFC41A7B34E +:10B4B0005A6801213D2DFC420269000951337FFF8A +:10B4C0000269000250937FFF84C241099A16430229 +:10B4D000A47340584CB70309000A032900038F8165 +:10B4E0008FC1406818D64260C873976B40134037CD +:10B4F000964BE7A5E81844F0B3043917C40040F8A8 +:10B50000BC00DD0F060C0C161C005A08010BD510F0 +:10B510005A00010CC80C8403D50BE602E808D503D9 +:10B52000C806D5068400D5048402D5028404EBD66F +:10B530008E01E60484C04EF2008D44F0B348EB2B3C +:10B5400040F03C004A003C0008003400500002017A +:10B550008400446FFFAA3C0BF8903E67E9D43C5B43 +:10B56000F88E3C1BF88F3C5BF88C3C1BF88D3E073B +:10B57000F1163E77F1223E07F114D56D2E07F11634 +:10B580000261001AE206E8048C013E07F1163C5BFA +:10B59000F88C3C1BF88DD55F2E07F1175A08012651 +:10B5A0002E17F1160201001AE220E81F2E17F115DE +:10B5B0000201001BE220E8192E07F114C8163CF71F +:10B5C000F8883C07F88C021100198A0FEB47E0015C +:10B5D000E80C3CF7F8893C07F88D8A0FEB47E0014F +:10B5E000E80484033E07E9D42E17E9D484003E071B +:10B5F000F1155A1003313E07F1172E07F114C82B2D +:10B600003C07F88D0211001EE001E91D0211001F28 +:10B61000E020E9193C17F88C0251001CE025E913E1 +:10B620000251001DE0A1E90F2E67F1160251001A28 +:10B63000E2C5E81184A13E57F1173C1BF8883C0B8A +:10B64000F889D5098402AE1AD5063E67F117D503ED +:10B650003E67F12384003E07F1243C03F890CC05BB +:10B660002E17EF825A180110A454E201E8058C014C +:10B670003C0BF890D52184013E07F1248404AE1AD6 +:10B68000EBD6D51A2E17F1175A18010E2E17F115F1 +:10B690000251001BE225E8058C213E17F115D50368 +:10B6A0003E47F117A454E201E904EA403E07E9D419 +:10B6B00084003C0BF8902E27E9D45CF10020E81FB1 +:10B6C0008C4C96908401E65EAE18AE998401E90434 +:10B6D000FA2EF803D504802249003ED38403EBFD03 +:10B6E0008400EBD6EA403E07E9D444000060DD4226 +:10B6F0002E07F1008C013E07F100D5038400AE183F +:10B700003C0DFC433C1DFBE3A404E220E90484005F +:10B710003E07EF9CFCC0FC0084004412C468442F28 +:10B72000FFAAAE08AE0AAE8984203E27E9D4EBD644 +:10B730003C1BF8903E17F1243E07F1173E07F11627 +:10B740003E07F1153E07F1223E07F114FC803C0D47 +:10B75000FC43A404DD9E2E07F124DD9E3C13953CA2 +:10B76000AC40DD9EFC60A612C0038E01AE12A61393 +:10B770005A0031048C01AE13A610C0038E01AE1026 +:10B78000A6115A001F048C01AE1100910001013175 +:10B79000000301010000A69250348001507980011D +:10B7A0008A708AE284C096D897F842B38C2482309B +:10B7B00080868006E331E9218242E3F2E91C04A09D +:10B7C00080054058C8A040551420F8095EF7802431 +:10B7D000E91002A2800040A50011888A02A2800020 +:10B7E00040F5001183FFE00FE802A4288CC197B157 +:10B7F0008DC1D5E48DA1D5DFC006445001F4FF2CE6 +:10B800004042009744500064FFAC40F32DF65EF7D1 +:10B810008026E836E669E934E6E9E932EB35E60305 +:10B82000E82FDD4CA600C82C5CF21F41E9298853A3 +:10B830004004C00090414030040A9415A10D98586E +:10B84000F8059C59F8029E59882040120420A4480B +:10B85000964B5EF08023E81483FF5010002088236D +:10B860004E00FFF550107FE0981940020020A40020 +:10B8700096035EF00023E80484013E07EC89FCE0B7 +:10B880003C0FFBAADD9EFC638180EB35816180C2A9 +:10B890005A0801122E07EC365A08020E3C0C00A87A +:10B8A00080200910800200D0000100E0800100909B +:10B8B0000002D506449000FF822981C981A9840035 +:10B8C0002E172A244432000080809680E241E80648 +:10B8D00098831041018C8C01D5F9FA53503F8013A5 +:10B8E0008480040600058026B7BFEAF28460005F0A +:10B8F00080138263810380838243804384FFB5BFCA +:10B900009618E205E81E05030001965939080D0155 +:10B9100094194D00C015A07238108D01E241E80B5A +:10B92000A0B480E3880201200001A700A033804179 +:10B930000330000050040001548000FF8C61D5E109 +:10B940008400151F80033E07EC895A7FFF044800DE +:10B950000121A03540A38808153F8002F481B7DF9C +:10B96000880A3A000000B0453A008020B085800681 +:10B97000802C49FFFEF9A036B5DF38301E02A03713 +:10B98000F40138501E0204030008053F800238000D +:10B990001E02051F8003C00E3C2DFBAA00110032C1 +:10B9A000FECC0011003341018217FF4C405280B79A +:10B9B000D50380A08200A0B5884AA61000A100028D +:10B9C00040F68006A6D3A651E91CE22DE91AE3AAA7 +:10B9D000E918E271E91640F70006E913E22EE911D1 +:10B9E000E32AE90FE269E90D5CF980C9E90A2E074B +:10B9F000F12D5CF000C8E80D8C013E07F12DD50952 +:10BA000084003E07F12D5CF98078E90C5A77FF0B32 +:10BA10002E07F12C5CF000C8E8058C013E07F12CE4 +:10BA2000D50984003E07F12C841F3E07F12B3E0709 +:10BA3000F12A2E07F12C5A08010D5CF2002EE909BB +:10BA400050197FFCE639E8053F27F12B3E47F12AE4 +:10BA50002E17F12B5A10FF212E27F12A5A20FF1DF5 +:10BA6000E614E81A8A4442210003E442E915000F73 +:10BA70008013E602E911DD4CA6C0CB0E2E17EF5B5A +:10BA80005A18010B440001E0E7053C0BF89710152C +:10BA90008000E84DD5093C03F894C008E705E803A9 +:10BAA0008E01D50284003C0BF8945A7FFF05840078 +:10BAB0008060D536A0B540711C4084C0A6BA012371 +:10BAC00080033C1DFBAA80068066E3C2E91EA738FE +:10BAD00001338001E3E4E9170110800281244291DF +:10BAE00044738229049600054114C42002F88000A2 +:10BAF00040F780115EF78023E904886488028CC1D6 +:10BB00008C81D5E98C41D5E2C6D30040803200203B +:10BB10008033FF1CFE84403218774001181700154F +:10BB200080005A10010844100050D5055A7FFFC408 +:10BB30008003EA762E27F12DE646E90544238D4061 +:10BB4000A690C20C40380C0142F18003E22FE906B6 +:10BB50009A2842F00003E22FE80D440001E03C0B7C +:10BB6000F8978401EB212E172A24440201A484A013 +:10BB7000D5083C03F897C0F78E013C0BF897D5F435 +:10BB8000D10E082000018CA110207FE79768D5F91D +:10BB900084A03E07F12D820548FFFF37FCE3FC003F +:10BBA00080C0A046A0058444846F848584A049FF9A +:10BBB000DE72A036A075EA20FC80FC002E572940DA +:10BBC0005A5001048401FC803C3DFB40A6D95A3008 +:10BBD00009045A3804193C3394BD994BE223976900 +:10BBE000E8049A599649D50284202E47EC31A0C228 +:10BBF000A003403190774000101796D996012E4748 +:10BC00002987D51B44338D40A718CCDD3C3394BC29 +:10BC1000994BE2239769E8049A599649D502802402 +:10BC20002E67EC14B460A0014031987740001817DB +:10BC30002E47298696D9960144F002004252BC0153 +:10BC4000E2A3E805A6108C01AE10D505E201E9FBE0 +:10BC50008400AE10DD40A6015A0804048400AE1032 +:10BC6000A610E280E8B08400AE102E07EFA18C0190 +:10BC70003E07EFA18402FC80FC2005008013006FCA +:10BC80008018011F801C55087FFFCA0F8381BE12D8 +:10BC900044220168B913EA6D406118405420FFFF47 +:10BCA000A6749648CB16D524447200004103C040C8 +:10BCB00045200064E2D1E8EB80F0427348735133D1 +:10BCC0008064182380014C79FFFE8CC197B0D5F3B6 +:10BCD00044600064FE744010884044620064442262 +:10BCE000000088418826183100014C20FFFEAD007D +:10BCF000AD41FCA0FC20F6085A60010B4462DEC492 +:10BD0000387304004462D97039130400D5038622C5 +:10BD100084E98380B912450200005460FFFFFA38BD +:10BD2000FE7CBF14401098404063C00954737FFFED +:10BD30004460006088304268982440631C40A7CF6C +:10BD4000AFD8A6CEAEE0A6CCAEE8024000300230BE +:10BD5000800D020000300210800C88648801F40617 +:10BD6000F1074008002088D040380C20B664B601A6 +:10BD7000B406920A9637AE10FCA0FC408380BD1436 +:10BD8000B814446000485452FFFFEA51FEF4FF34F7 +:10BD900040420040403194404452000088A4840056 +:10BDA0008A643861940038608109086280013861D2 +:10BDB00001098C015A0832F744020034888084A0BB +:10BDC000852339319002411094000D220001410178 +:10BDD000140084E04203A42402A880004069800D7E +:10BDE0009797406519001A6880014009000D0268A4 +:10BDF00000009617400301008CE11A0800015A78F0 +:10BE00000AEB8CB45A5864DFFCC0040000134440B1 +:10BE10000064FEE4EA514001804044320000886042 +:10BE200084009908A76138408000404240084042A1 +:10BE300017009950A76940421500385100008C0244 +:10BE40008885AB195A0832EFDD9E04000013444088 +:10BE50000064EA51FEE440318040EA828860840058 +:10BE6000A51938408008A75B9908AF61B4833841B1 +:10BE70000008A319995092888C02AF295A0832F20F +:10BE8000DD9E4412DEC4380080008E015C00000993 +:10BE9000DD9EE201E80AA610E260E8049AC3AED093 +:10BEA000DD9E8400AE10DD9EE220E80BA61052F16C +:10BEB00080FFE00FE8048860AED0DD9E841FAE10E6 +:10BEC000DD9EFC60EEA8F0858141F28480E35A3863 +:10BED00001053C800B0FD506F9134E0200A23C80F1 +:10BEE0000B0E2E07EC8B84C1E602E9058E01406340 +:10BEF000000C97B04063280E97B0CE0284C1B00A00 +:10BF000050BF8024505F8021F081F105F004B0889B +:10BF1000503F8022504F8023B77FF782F9C1F00451 +:10BF2000B064B0BD003F8022004F8023F9C2F86F9B +:10BF300049FFFF8DB0248120B00B8380858044D0E1 +:10BF400000323855B202440065109928440073E865 +:10BF500040E2800042063424F08584E039049D01EB +:10BF60005CF807FFE8492E17EC8C3932C101003F1D +:10BF700080208E214028040840098C164CA0C01552 +:10BF80008844A4508A0840308C768A68EB5242F08C +:10BF90000003E06FE90413310000D52E380741019A +:10BFA000380E1C08D5294EA3000639324109F81075 +:10BFB000D5168844A45040308C76401020018A6801 +:10BFC000EB5242F08003E06FE90A133100003814AD +:10BFD0009D01382E1C003827050983FFF105B0CBE1 +:10BFE00098B98843960180288066F487F58649FFD2 +:10BFF000FF52F407F5068CE15A7832B2509480640F +:10C0000051CE00325AC001048581D59CF004B04B5A +:10C01000502F805E003F802183FF49FFFEF8ED58DE +:10C02000FCE0FC61F0818401B63F814280C3EA7F7D +:10C03000DD455A0002048400EA63DD548401AE0841 +:10C04000DD58AE0884003C0FFB992E07EFA75A0875 +:10C05000010684073E07EC8BD50C5A6801072E07B2 +:10C0600029813E07EC8BD5052E0729803E07EC8BF6 +:10C070002E07EC8B8C013E07EC8C44000060DD50F9 +:10C08000DD455A08024C5A6801074413F423EA3884 +:10C09000EA37D50B440000618520DD50816944C337 +:10C0A000F04AEB9085A1D510A6085A0002F5AED053 +:10C0B000D5FC3C0DFB99C81CE9FD50048001EAB792 +:10C0C000DD4B10D000002E07EC8CE320E8653CBF70 +:10C0D000FB9B108600005A60010744000062DD509F +:10C0E00084E0D5188006EA2CEAA2C0FFD5F73CBF51 +:10C0F000FB99CE12EA678E0154E000FF800E49FFE3 +:10C10000FEC2C008800E8029B45F80668CE1F82DE5 +:10C1100097F8E2EAD5D28007D5F746B000F484E07C +:10C1200044C3F04AEB9085A150B582402E07EC8CB9 +:10C13000E2E0E83210860000F99844000061DD502A +:10C140005A680105F001EBEBD506DD408420DD5790 +:10C1500049002A1444000062DD5085204C95000DF2 +:10C1600080098027B45F806649FFFEAD505480018E +:10C17000549280FFD5F4DD4B8CE1549380FF10D0B6 +:10C1800000005A6801062E77EC8C4C93BFD1800BCF +:10C19000EB0580E9D5CC8400EA7F8400FCE1FC213A +:10C1A0002E07EFA7C8063C2394C13C3394C2D503A5 +:10C1B000EA9080432E0728BF84C0EA663C4394BCC3 +:10C1C0003C5394BDF08196904402ED8C96D8B6DF36 +:10C1D00049FFFD54DD4580E0EA66DD405A78021BE8 +:10C1E00084488066F8245A0801053E07EF72D54856 +:10C1F000DD408425AE4184213E17EF133E77EF5A90 +:10C20000EA418441DD40EA668062F8113E67EF133F +:10C21000D5172E2728BF8066F80ADD408429AE4155 +:10C22000EBCCEA418441EA66DD40806249FFFEFBD7 +:10C23000DD40842AAE4184213E17EF9CEA4184010F +:10C240003E07EC1A84033E07EF5A8407DD50840052 +:10C25000EB98DD455A080206DD40842DAE41D50B32 +:10C26000DD408420DD572E17EC5DDD405A180203B7 +:10C27000842AAE41DD40EA414400006FDD50FCA15C +:10C28000FC20EEB0B0C8B187505F8019F381F28214 +:10C29000503F801AB086504F801BB6DFF08549FFB3 +:10C2A000FD2B004F801BF005B062B0BB003F801A31 +:10C2B00049FFFD65F005003F8019B049502F8056B9 +:10C2C00049FFFDC584004430006444400032B04959 +:10C2D00042101073B1E282013853020242700C73B3 +:10C2E0008420382385015CF107FFE8053918040034 +:10C2F000391289098C215A1832F65A000104840136 +:10C30000D5E7ED50FCA0FC61EA838120FA2184048A +:10C31000DD438404FA22DD43EA583CADFB583C0F70 +:10C32000FB58DD41C00444000040EA978404FA232E +:10C33000DD4384C03CBDFFD79DF197F8EAF180074B +:10C34000802BEAB9EB9E002F80068E41E648E90576 +:10C3500080C75A7820F3D508800B80268440F814D3 +:10C36000EB295A0808F73CBDFFD984C09DF197F826 +:10C370008007802BEAF1EAB9EB9EEB295A080908FD +:10C38000800B8026844149FFFF7DD50480C75A7801 +:10C3900020EF8404FA24DD43DD41C81AEAE5804138 +:10C3A00044300C808402DD4444131F408041EA2461 +:10C3B0008402DD4444000040EA9784024412988AD3 +:10C3C0004422168044300640DD44EB46EA9784045C +:10C3D000FA25DD43DD41C00EEA79441373E8EA2013 +:10C3E00044031F4044138DD4442000C8EB1DEB468A +:10C3F000EA978404FA26DD433CAFFB58DD41C804CC +:10C40000EA28EA21D505EA50EA2EEA3AD5070004DF +:10C4100080515A00BB04AE88D5FBEA78DD41C004E8 +:10C42000EA8DEAE5EA20DD41C80510048050840168 +:10C43000EADDFCE1FC00DD455A0802158400EB2032 +:10C440008401EA7FDD46DD47AE40DD59A640C9FFE5 +:10C45000A6405A1801FFDD4B8422AE408400EA7FDB +:10C46000D50BEBE7EBD1EB0549FFDF3CDD4084204A +:10C47000DD574900288344000065DD50DD41C00DD3 +:10C48000DD47DD46AE4049FFB370C0FEEA79EB4DB3 +:10C49000FA50EB0649FFD96FFC80FC24442166501A +:10C4A000EBAC44416660B084EBE93B024C003B01DD +:10C4B0004C20390102024421D80040210040A790BD +:10C4C00080E197B0381F82028480451365104522B1 +:10C4D0006238EB51E282E81994E14021C400033153 +:10C4E00000004021C800994BA490383810008C817E +:10C4F000FE9CA4E84021180E8A53969340211C56B6 +:10C500008843ACA89721D5E644200C804431A20092 +:10C5100042300873800349FFAE72FCA4FC6184C002 +:10C520008401EB3B3E67EC278126EA7F80E68504A9 +:10C5300085A644E38D405A78040B8400DD55804085 +:10C54000EA4D3ED7EF5A8581EA9ED50B80073E879C +:10C55000EF5AF8198180DD5584038047EA4DEA9E41 +:10C56000DD4B8421AE409E39854054B000FF4CA67F +:10C570000030DD59A640C9FFDD41C00EE2C9E80C1C +:10C58000C70B800B4900224AF0818CC1800BF1015E +:10C5900097B049FFFF8400170000DD595A180311B6 +:10C5A000A6405A1801FFDD41C007DD5C5A0807FFAD +:10C5B000EA79EAB5EA2050048001EAB7D504A6403A +:10C5C0005A1801FF5005000154A000FFD5D18CE19D +:10C5D00097F85A7805B28400EA7F8400FCE1FC45B4 +:10C5E0004421667044720000EBACB0424421668086 +:10C5F0003B00CC20EBACA6BA81208400B186EA5B7C +:10C600003810A602EB2AA6FB92413B034C20EBCD4F +:10C61000EB2A38132602A6BAA6FBEBCDFCC53C0FCD +:10C62000FBABDD9E3C0FFBADDD9EFC008420DD57A7 +:10C63000DD548400AE08DD58AE088401EA2C840184 +:10C640008440842A8080806280A2DD56DD47DD46FA +:10C65000AE40EAA2C8043C0DFB98C0FCDD41C01608 +:10C660008401DD4ADD47DD46AE4049FFB27EC0FEB3 +:10C670008402DD4ADD455A000214EA26EAB1AE081A +:10C68000804184618402DD44D50BDD455A000209F6 +:10C69000DD47DD46AE40EA26A6085A0832FFDD45F2 +:10C6A0005A0802072E07EC208C013E07EC20FC8084 +:10C6B000FC2080A03C0DFBAB3C4C01C7A68394E959 +:10C6C000E2A2E825F87BE906A4309783982AF87F50 +:10C6D000F8649222CD0DA421F83140220820A41044 +:10C6E0009603E0204EF200C98401EA46FCA09E1A9F +:10C6F0008804A400964996039F91E020DE04E9F5A2 +:10C700008845F835F82CF81B8845F8318403FE1469 +:10C71000E2A0E93599E3A5B897B3E026E90CA5B8FE +:10C7200097F39BAA40621820A5B097B388C7E0266C +:10C730004EF200A39222D808F81396499603E020FF +:10C74000E9D483FFF8139E1A8804A40095929603F7 +:10C7500096498EC1E020DE03E9C8F808E9C68C627C +:10C760008864A41883FF4E00FFEB9AAA4022082099 +:10C77000A4109603E020E9B9FCA083FFD2039591B1 +:10C78000DE19F81CE910F82096038807E020E90B71 +:10C79000A4309783982AF81B96038806E0204EF26F +:10C7A000006C83FF8C62F825F811F826F82EF82427 +:10C7B000FCA08EC1D6038E01D83099A3A430960375 +:10C7C000E02083FFE915A43097C39A2A4002002095 +:10C7D000A40083FF96038807E020E90AA43097832A +:10C7E000982A4E00FFF596038806E020E8458E6201 +:10C7F0008864A41892229603E0204EF3FF7783FF0B +:10C800004E00FFE54E00FFF9884540220820A410A5 +:10C8100083FF4E00FFF2FCA09F9A9823412218004C +:10C82000A400026900008C624103001188649BAA85 +:10C8300040F00011A5D841121820982A0268800003 +:10C840004022002097FB4007C000A51097B388073F +:10C850009723880688049D0DE080E80E02090000F9 +:10C860004E00FFCAA4184E00FFC8020880004E0008 +:10C87000FFC448FFFF36FCA02E17EC02C1092E278B +:10C880002D12E241E9048E219648D50284204422EB +:10C89000EC1C38310501E260E92BFC2084003801F2 +:10C8A0000509EA94842084A33C3C01C53C0C01C6E4 +:10C8B0003C4C01CE9489886288028881A598A5C0E5 +:10C8C000A620880742031473404008099721AD1839 +:10C8D0003C4C01C53C3C01CE8844A490886140009A +:10C8E000084196008C21AE185A18C8E0FCA0DD9EC5 +:10C8F000FC005A0801122E1011612E0011605A1806 +:10C9000001048E03D5028E0296008440802080624E +:10C910004900089AFC80490008A9FC80A641EA77F2 +:10C920005A1804112E17EC0FC903A602D502A6034C +:10C930002E17EC6D5A180208E604E9058E039600DE +:10C94000DD9EA604DD9E540000FD5A0804053C034C +:10C95000F899DD9EEA7702000009DD9E5A08040579 +:10C960003C03F898DD9EEA770200000ADD9EEA7734 +:10C97000A400DD9EB400EA77A447020000083C1B37 +:10C98000F8993C0BF898DD9E2E17EC07C9098442F4 +:10C990003E17E9B83E27EC433E17EC27EA57DD9EE9 +:10C9A000FC00DD47DD46AE403C0DFB98C810EA8A2E +:10C9B0005A0801064402C41E49FFD5A584018440DB +:10C9C00080208062808080A2DD56D5EF8406DD4A1B +:10C9D000DD41C01DEA26EA38EA37A6085A003204CB +:10C9E000AED0D5FCEA28EA21DD5C5A000704AE8807 +:10C9F000D5FC4412C520840280418461DD442E07A9 +:10CA0000EF9CC003840AD5028409EA25EA6F44102A +:10CA10000033AE402E07EDB0C81149FFBB8D5A0060 +:10CA2000A10EDD418020C80784028041806184839B +:10CA300080A1DD5649FFDC34FC80840E49FFD4B769 +:10CA4000FC80FC00DD455A0802074403F422A600DE +:10CA5000961FFC808400FC80FC2084003C0BF66C5C +:10CA6000DD4084233C7DFB3F84C1AE41EB7EEA4147 +:10CA7000DD4CA600842397F8490014033C7FFB3F5C +:10CA8000EBD5C80A2E07EC4AC8078409DD4A3E6781 +:10CA9000EC5B3E67EC1ADD40EA41DD5484003E0762 +:10CAA000EC4A8401AE08DD58AE08EA225A000404BC +:10CAB0008405EA872E07EC638420C8093C1DFBAD82 +:10CAC000A448E622E9038E22D50280203C1FFBE326 +:10CAD0003C1DFB3F5A18020FC8093C1DFBADA44882 +:10CAE000E62AE9055000FFF6D5028400EA3CFA1870 +:10CAF000EA9384013E07EC658400EAC3FCA0FC00D5 +:10CB000084C03C6FFB7DEB3B49002526EBCF3E0705 +:10CB1000EC028401EA2CDD59AF804900251DFC8020 +:10CB2000FC00DD40A601EB2D5A080911EA225A004B +:10CB300004048405EA872E07EC63C808F803E602BC +:10CB4000E90549FFF6068E02D5028400EA3CF81892 +:10CB500049FFDBADDD408429AE418420DD57DD4057 +:10CB6000842AAE41EA414900250984008421EA3043 +:10CB70003E17EF9CEAC349FFF5D0490037DE49FF75 +:10CB8000DBA4FC80EA773C3C01C7A5038420840138 +:10CB90009899A4909693E082E80284008C225A1916 +:10CBA00090F9DD9EFC202E17EC435A18020B2E172D +:10CBB000E9B8C9072E17EC6B8E225C108001D502F4 +:10CBC00084203C6DFBAB3C4DFA763C7C01C684A0D6 +:10CBD0008461864353300000A6B351138002510193 +:10CBE0007FFF4C58001D410104088F814C580018EC +:10CBF000430148248F814C58001394928E41D20FE8 +:10CC0000A4B8027880008A479693E002382215097A +:10CC1000E903E053E8045A18010384628CA180F10F +:10CC20005A58C7DC5A18011C401004098440FF4AB6 +:10CC300038720911E027E807A633880238F201119B +:10CC4000E02FE909E0E5E808A6338802380201117F +:10CC5000E005E80284628C415A2895EC8003FCA030 +:10CC600084204422EC1C380105098C215A1808FD47 +:10CC7000DD9EFC4080E0A60080C25A08051E8401AB +:10CC8000AE38DD4085203C9BF7ACA601EAE2F81502 +:10CC90003C13F66BE62AE8058C213C1BF66BD5139A +:10CCA0003C9BF66BA430E619E804EA598400F805C9 +:10CCB0008400AC30D508840049FFFFD48400AC3038 +:10CCC0003C0BF66BFCC0FC01DD40A601EAE2F08102 +:10CCD000F1014402C3DB4422C43649FFFFCC2E17C6 +:10CCE000EC6B8400EA613E07EC2CC9033E07EC2E96 +:10CCF00084003E07EC02EA40EA9FFC81FC20FD3004 +:10CD0000EBCF80A0A630AF70C5092E172D1284C0BE +:10CD1000E225E9059FA997B0D50280C5D01DDD4564 +:10CD20005A08021B3C3DFBAB8400A65B9449E00122 +:10CD3000E80D8387BA09BC0B944188418824A44834 +:10CD40008C019649AC509600D5F13C03F64DC00ECF +:10CD50008E01EA61D50B4402EC1C385019014410D5 +:10CD6000FFFFD1048CA1385019092E17EC2E40007A +:10CD7000980E9604C81B0513800A05038009045306 +:10CD8000800B40380000A498404880009691ACA0E9 +:10CD9000A498992896918C02ACA05A0990F4840129 +:10CDA0004060180CFE773E17EC2EFCA0FC002E27EE +:10CDB0002D12441000FF4020880C4413F422A64892 +:10CDC000FE93965F9690C1038E219648A78084A11A +:10CDD0004042840CFF37972296E0AEC04C61800D34 +:10CDE0004C31000B88254052840CFF679768FF5D2B +:10CDF0005C028001FC808005FC80FC008400EA610C +:10CE0000EA94EA46DD40A6015A080422EA22C8094B +:10CE10004402C39E49FFFFCC5A0801048403EA87F9 +:10CE2000EA225A08031D4402DA44842044200320E5 +:10CE3000EA3FEA2BC807EA89A600962EC8038404B5 +:10CE4000D50A8401EA878400EB00D5092E07E9B8EA +:10CE5000C8048402EA87D503EA2BD5F1EA225A08EE +:10CE6000020584003E07EC8D840080804452E3A8D4 +:10CE70003C3C01C494418861A4D83C2C01C696D99D +:10CE80008841ACD03C2C01C53C3C01C6884188237C +:10CE9000A4489649AC503C1C01CE8820AF083842CB +:10CEA00080088C015A08C8E6FC80FC208407DD4A13 +:10CEB00084C0DD403E67EF13EA41DD4B84213E67CD +:10CEC000EC20AE4084003C0FFB8FEA98EABB3C2D7F +:10CED000FB8FCA098401AFF080208062808080A22D +:10CEE000DD56D5F6DD47DD46AE40EAA2C80B3C2D47 +:10CEF000FB98CA08840184278062808080A2DD5666 +:10CF0000D5F58421DD40DD57DD41EA28EA21C00E58 +:10CF10008400EA35AE883C2DFB3FCA248401802082 +:10CF20008062808080A2DD56D5F7AE88EB63C009B1 +:10CF30008401844080208062808080A2DD56D5F705 +:10CF400049FFE259EAF55A0803048402D502840134 +:10CF5000EA354412C46C8401EADD804184028461B4 +:10CF6000DD448408DD4ADD40EA41FCA0FC4084E366 +:10CF7000812142709C2484203E17EC2740A00808A1 +:10CF800090E384C0E0CAE8153C2C01C7402118207A +:10CF9000A4909693E0E2E80A8006802949FFFB8A84 +:10CFA000EAC7C0043E67EEB0FCC08CC197B0D5EBB9 +:10CFB000FCC0FC60812180E04412DE5C4402C3724C +:10CFC00049FFFE9E4400FFFF84A03C1DFBAD80494D +:10CFD000A952A81300008016E610E8045250001071 +:10CFE000976884C0FB80430040013CADFBAB3CBC78 +:10CFF00001C63C8C01C43CCC01C73CDC01C52EE71A +:10D00000E9B82F47EC6B2F27EC8D3D3DFB45804663 +:10D010004512E3A882A60005000394C2E043E86835 +:10D02000959140459800A4E040041800A400FEEC4F +:10D0300042304073926496D9ACE04036180088CDF7 +:10D04000A42002F300008A0F9603AC18A4D8A40D04 +:10D0500096DBFE02E060E81A5AE001045B48021722 +:10D06000380888008C01960038088808A4CEE26051 +:10D07000E813A42086419601AC302E07EEB1395852 +:10D0800088088C013E07EEB1D50738088800C00437 +:10D090008E0138088808A4E004048002E203E80452 +:10D0A000A42014048002A4E004048003E260E804E5 +:10D0B000A42014048003040480023C37F66CE26070 +:10D0C000E8033C0BF66CA6395A080908B413EA5574 +:10D0D0005A00010AA58BD509B413EA555A00010478 +:10D0E000A58CD503446000648C419690D59580262C +:10D0F0003F27EC8D49FFFF3CDD40A6015A08090798 +:10D10000800649FFFD513E07EC43FCE0FC4080E017 +:10D11000A60180C15A08042C9E0CE604E90A5A10A4 +:10D120000C09EA225A000406EA2B5A08010AD50B18 +:10D13000DD41C81A3C03F7AC5A080117D5F6EB3DA0 +:10D140005A080108DD41C80D3C03F7AC5A08010A32 +:10D150002E07EC0F5A080104490021FE8007EBEB73 +:10D16000EA27EB9FEBBF8400EB00D508EA225A00C8 +:10D17000040649FFD89F8007EBEBDD414E02008596 +:10D180003C03F6634412E2048C01EA943C03F64D3E +:10D190008C01EA61800749FFFF0EEB58A600C0052D +:10D1A0008401EA468400EA3CEAC75A080115840073 +:10D1B0003E07EC2C84002E172D124432EC1C80808C +:10D1C0009680E241E805384181098C01D5FAEA5F91 +:10D1D000DD42D5242E97E9B85A9801159E34E6020F +:10D1E000E9114402E2043C1394BF4422C39C49FF6A +:10D1F000F4E65A080208FA01DD423E97EC273E9712 +:10D20000EC724412FEFCA6085A08A5098401EB98AA +:10D21000EA463E07EC728400AE082E07E9B8C8342F +:10D22000A6385A080232EA225A00010F2E07EC8D66 +:10D230005A0801062E07EC435A0001073CF7F67B1B +:10D240005EF78078E81849FFFC9FC8093CF7F67B39 +:10D250005EF78078E904EA46EA94D50D840184E01B +:10D26000EA753E77EF8249FFEB09EA225A08020489 +:10D270003E77EC6BEA225A0802082E07EC435A0864 +:10D2800002048400EA46EA40EA9F9E34E602E80C83 +:10D29000DD41C004EA50EA2EEA3A8400EA468400FE +:10D2A000EA61EA94D5055A6802048401EA46EB3D36 +:10D2B0005A000105EA2B5A08010584013E07EC18C3 +:10D2C000EABC5A080104EA46EA75FCC0E60F4EF2D1 +:10D2D000007744F0D0DCEA8BEA3DDD0F102E48E009 +:10D2E000669CE0E0E0E0E0E0E0E0A8008401EACF56 +:10D2F000AE084423F2498422AE504423F24AAE10D1 +:10D300004423F24BAE508464D52B841FEACFAE0881 +:10D31000EBBDAE084413F24AAE084413F24BAE081C +:10D320008448D53E8401EACFAE08EBBDAE08441375 +:10D33000F24AAE084413F24BAE084413F24CAE0866 +:10D34000D5328401EACFAE084423F2498424AE509A +:10D350004423F24AAE104423F24BAE50846C442373 +:10D36000F24CAED04423F24DAE504423F24EAE10F8 +:10D370004423F24FAE50D5208400EACFAE08EBBD77 +:10D38000AE08D507EACF8400AE08845FEBBDAE8857 +:10D390004413F24AAE084413F24BAE0884414413DE +:10D3A000F24CAE884413F24DAE084413F24EAE0870 +:10D3B0004413F24FAE084413F250AE08DD9E9200C3 +:10D3C000C102EA7D96004413F251AE08DD9E400092 +:10D3D0003C0892104423F2444010BC08AC10923038 +:10D3E0004403F246AC40DD9E84214403F240AE404B +:10D3F000EA21EA28AE88A6405A1001FFDD9E4413B8 +:10D40000F258A448AC404413F25AA448AC41441327 +:10D41000F25CA448AC424413F25EA448AC4344130B +:10D42000F260A648EBCBDD9EFC02F0818002F38324 +:10D43000F18249FFFF4DF001F10249FFFFCA49FFA8 +:10D44000FFD5F00349FFFFDDFC82FC02F0814403BD +:10D45000F242F182F283AF40001F80204403F24386 +:10D46000AE404403F252ACC04403F254AD008421F8 +:10D470004403F256AC40001F80244403F241AE4006 +:10D48000000F8028001F802C49FFFF9CF001F10253 +:10D49000F203F30C49FFFFCAFC829200FC203C6DB2 +:10D4A000FBAE97C4050300025510800F43085C09CA +:10D4B00040781EE44273D809470FFF0F4273D40926 +:10D4C00051080FFF4073C0028E2A86404073C60485 +:10D4D000E625A9F2132300031123000B4EF2007C72 +:10D4E000012F8038011F8030010F8034007F802C95 +:10D4F00044F0D2FCEBC6EA9C4A003C0006060676E5 +:10D500007600C003EB81D5034021BC08F0079250A0 +:10D510009201AC32F00692A192011203000BF008C6 +:10D52000926192011203000EF009ACB09201120355 +:10D53000000F220F801E1203000C220F8020120306 +:10D54000000D020F8022AD718C01ACF41123000C90 +:10D550001113000D1103000E1073000F11230010A2 +:10D560001113001111030012107300131203000AAB +:10D57000D532C003EB81D5034021BC08F00A92509C +:10D580009201AC32840010030010840192819261F8 +:10D59000100300118400ACB0AD31ACF41123000CC9 +:10D5A0001113000D1103000E1073000F1103001270 +:10D5B000107300131123001411130015110300162A +:10D5C000107300171203000C1203000D1203000E5B +:10D5D0001203000F4403F1408421AE40EA38EA37D9 +:10D5E000A6405A180104AED0D5FCFCA044038CF030 +:10D5F0003C0FFBAE441FC6784403F142AC408400AC +:10D6000044138D08B6013C1DFBAEA80F3C1DFBAEBC +:10D6100014008008DD9E84203C0FFB50AC43DD9E4F +:10D620003C3DFB50920192219241AC18AC59AC9A0E +:10D63000DD9E3C1DFB50A6821020800CA68310208E +:10D64000800DA680A6011020800E1000800FDD9EA8 +:10D650003C1DFB50A68210208010A6831020801154 +:10D66000A680A6011020801210008013DD9E3C1DB4 +:10D67000FB50A68210208014A68310208015A6805F +:10D68000A6011020801610008017DD9EFC01B63F19 +:10D69000F28149FFFFD0B41F49FFFFDCF00149FFD1 +:10D6A000FFE8FC81FC24007F8060F081F182F2833E +:10D6B000001F803C002F8038000F8040006F804C9E +:10D6C000105F8016103F8014102F8017104F8015A8 +:10D6D000101F801A103F8018100F801B104F8019E8 +:10D6E000CF08105F801E103F801C102F801FD507B1 +:10D6F000101F801E103F801C100F801F3C0DFBAEC2 +:10D70000104F801DF855B005B046B087F856F001AF +:10D71000F102F203F8573C0DFB50021F8028AC4485 +:10D72000001F8054002F8044FE7752630020406029 +:10D730009824001F80481060000A58108040FE574F +:10D740001010000B221F802C1210000C221F802EA4 +:10D750001210000DDD47DD46AE404403F140842148 +:10D76000AE40A6405A1001FFFCA4FC04F0819419BD +:10D770009600F182100F80178422100F801B84C145 +:10D780003C0DFBAE103F8014104F8015103F8018E9 +:10D79000104F8019103F801C103F801F104F801DBC +:10D7A000F283101F8016101F801A106F801E49FF11 +:10D7B000FF34B005B046B08749FFFF6AF001F102BF +:10D7C000F20349FFFF2F3C0DFB5084208449AC44F9 +:10D7D0001010000B1020000ADD47DD46AE40440368 +:10D7E000F140AF80A6405A1001FFFC844403F14889 +:10D7F000A6404403F149A600EB4C9601DD9E44107F +:10D800000055DD46AE40EA8CA6085A0001FF84218F +:10D810004403F380AE40EA21EA28AE88A6405A10BD +:10D8200001FFDD9EFC004413F381A608EB26AE0841 +:10D8300084004413F384AE084413F56BAE0849FF2B +:10D84000FFE0FC804453F381A72896D8544200F0AF +:10D85000FEA7401104449688400100E496804403EA +:10D86000F384AEA8AEC0DD9E84004413F386AE08F8 +:10D870004413F387AE08DD9EFC604403F38496D81E +:10D88000AEC049FFFFBEDD47DD46AE404413F38026 +:10D89000A6085A0001FF4473F3864463F387449358 +:10D8A000F04A44A0005544B3F380A6385A08010C4E +:10D8B00049FFFFDC49FFFFA5EBF9000580005A0096 +:10D8C00001FED5F4A6305A0001F5FCE0DD9E441EB1 +:10D8D00000008801920296014413F3CAAC08DD9E51 +:10D8E0004413F280A608EA54AE08DD9E4423F28079 +:10D8F000A650400080A49600AE10DD9E441E00009D +:10D90000880196814413F286AC884200400B441390 +:10D91000F288AE08DD9EFC6081410010000944736E +:10D92000F280968CA67880C0661080020000000A03 +:10D93000401088243C7FFBB0AE789684A638A47053 +:10D94000EAB340000844AE384403F284AC40A0314E +:10D9500049FFFFD6001300084403F283AE40852040 +:10D9600044B3F04AEB900003000B49FFFFC149FFAD +:10D97000FFB9A6389604C01384011085800049FFC2 +:10D98000ECFA50048001EAB7E72FE9F42E07EFB371 +:10D990005A0801F184023E07EFB3D5174403F28120 +:10D9A0003C0FFBAF5AA80307A6404210880BC1DC0E +:10D9B000D5095AA80106A600EA55C807D5D55AA820 +:10D9C0000205A600EAD9C0D0FCE0C80844138D25A2 +:10D9D000A6088C019600AE08D50E44238D26A650CD +:10D9E0008C219648AE505A0801074413F060A608EF +:10D9F000EA7AD5064413F060A608540000FBAE088E +:10DA0000DD9E96004413F068AE08DD9E4423F0537B +:10DA1000A6509604EB1B88019600AE10DD9E4413C1 +:10DA2000F06AA6889604542100FEAE88A688880273 +:10DA30009600AE08DD9E4423F054AC104403F0562B +:10DA4000AC40DD9E4031C8084021898088024010EA +:10DA500004C084A54443F06D4403F06EAF603C1FE6 +:10DA6000FBB13A100420DD9E84204403F06DAE40EB +:10DA7000DD9E4403F061A600EA55DD9E4403F0619B +:10DA8000A6009207DD9EFC0049FFFFFAC80749FF88 +:10DA9000FFF25A0001068401FC808400FC808402AD +:10DAA000FC80FC004463F00EA4304200200BC00751 +:10DAB00044138D24F81C84084800007BA430EAC875 +:10DAC000C859A430EAD9C00644138D23F810840342 +:10DAD000D56FA430EA55C00644138D22F80884029D +:10DAE000D567A430EA5EC00A44138D21A6088C01D4 +:10DAF0009600AE0883FF8404D55BA4309604C04E24 +:10DB000049FF956FA4304200180BC836A43042007C +:10DB1000140BC834A43042001C0BC832A43042009D +:10DB2000240BC00B4403F064A640964CC12BA640C6 +:10DB3000EB1BAE408409D53CEBA0A4404210A80BDF +:10DB4000C923A4404210AC0BC921A4404210B00B21 +:10DB5000C91FA4404210B40BC91DA4404210B80B09 +:10DB6000C91BA400920FC01A84013E07EF4C840F1A +:10DB7000D51F8401D51D8406D51B8405D5198407BE +:10DB8000D5178409D515840AD513840BD511840CB7 +:10DB9000D50F840DD50D840ED50B4403F01AA400C7 +:10DBA000EAC8C00549FF951DFA01D502FA0884208C +:10DBB0004423F00EAC504423F01AAC50FC80842176 +:10DBC0004403F322AE40DD9E4413F323AE08DD9EF2 +:10DBD0004403F323A600DD9EFC004463F540B60633 +:10DBE0004403F544B6204403F548B6404403F54CDD +:10DBF000B6604403F550B6804403F554B6A0F10472 +:10DC00004403F558B620F1054403F55CB620FC80CA +:10DC1000FC614433F5044423F5024413F5033C3F0F +:10DC2000FBB34433F50580C03C2FFBB63C1FFBB56E +:10DC30003C3FFBB25A00030448000145DD41441358 +:10DC4000F51AC0048401AE08D502AE084403F57885 +:10DC50008420AE40843FAE40442FFFAA4403F579B0 +:10DC6000AE8084C1AE404403F500AF8084008020C4 +:10DC700080408060EA3B84234403F501AE40840089 +:10DC8000802080408060EA3BEB1CA608EA95AE0845 +:10DC90008400802080408060EA3B44000802EA3231 +:10DCA0003C1DFBB5A608EA95AE08840080208040A4 +:10DCB0008060EA3B4400041AEA32DD474403F50978 +:10DCC000AE408400802080408060EA3BEB1CA608C8 +:10DCD000EA54AE083C0DFBB5A68058210001AE8089 +:10DCE000A68858210004AE88A68058210004AE8082 +:10DCF000A68858210008AE88A68058210008AE806A +:10DD0000A68858210010AE88A64058108010AE405A +:10DD10008400802080408060EA3B440005AAEA320B +:10DD2000EB1CA608EACBAE083C1DFBB5A608EACB67 +:10DD3000AE088400802080408060EA3B2E07EC46DD +:10DD40004E030116DD403E67EC46A601B61FDD45D9 +:10DD5000DD555A0802058404AE09D5038409AE09CD +:10DD60008501DD403E87EF13EA413C2DFB5844021C +:10DD70000168046100128420EA6D4060184004A329 +:10DD80000003049300034005100954A0000340045D +:10DD90009809960F3E17EF13F081A1F3A03344B317 +:10DDA000F68066000030EAAEA833A033FA6F660052 +:10DDB00000C0EAE3A833A03392E8660003005800ED +:10DDC0000200A83304410013844C929054027FFF58 +:10DDD000A73597CFFF1440420040EA8240E200009E +:10DDE00004D700004608000804C70001400680026E +:10DDF000B60E460F000F4006000214070001442330 +:10DE0000F683841F10858000AE104423F684AE1084 +:10DE10004423F685AE104423F686AE104403F687FD +:10DE2000AE404403F688AE404403F689AE40440356 +:10DE3000F68AAE40840080208040EA3B4403F40B25 +:10DE4000A64044200039548080FF4413F415AE8866 +:10DE50008424AE408401EA2C440005AAEA32DD475E +:10DE6000DD46AE40EAA2C0FF8400852080201095E8 +:10DE700080008040FA6FEA3B4403F415EB924403C0 +:10DE8000F40B10800000A0336600003040A028840E +:10DE900014A30003A033F101660000C0409004C445 +:10DEA00014930003A0336600030040701D04A9F31F +:10DEB000DD40001F800014D7000014C70001AE41F0 +:10DEC000D556C83184414413F500AE8884434413C9 +:10DED000F501AE883C2DFBB68060A650581080023C +:10DEE000AE503C2DFBB5A65058108002AE5080209D +:10DEF0008040EA3BEB1C8066A608EA7AAE083C0D3F +:10DF0000FBB5A68058210004AE80A68858210008E1 +:10DF1000AE88A640804658108008AE408006802615 +:10DF2000EA3BD5255A080124A6D0A608543180F32F +:10DF3000540000F3AED0AE088400802080408060A2 +:10DF4000EA3B84004413F500AE084413F501AE0823 +:10DF5000EB1CA608EA7BAE083C1DFBB5A608EA7BD5 +:10DF6000AE088400802080408060EA3BFCE1DD9EBA +:10DF700046108000EB3CEAFF4210EC09400083644D +:10DF8000EA81DD9E46100800EB3CEAFF4210DC0906 +:10DF9000400082E4EA81DD9E44110000EB3CEAFF90 +:10DFA0004210C00940008204EA81DD9E44108000D6 +:10DFB000EB3CEAFF4210BC09400081E4EA81DD9EAF +:10DFC00044100200641328036413080266108200E0 +:10DFD00040008124EB654413F7EFA6089600968471 +:10DFE000C203EAA4AE08DD9E8422EB3CEAFF661081 +:10DFF000800240008024EA81DD9E64120002C00499 +:10E0000058008001D5036600800164020003DD9E94 +:10E01000DD9EDD9EDD9EFC4080E04403F040A78055 +:10E02000812181425463001C5A780225DD41C014CD +:10E030004422FEF64433F04AEB6BA6104412FEF67F +:10E040005A00EC04AF18D5FA8400AE088041846110 +:10E050008402DD44D50A4412FEF6440FFFECAE08FC +:10E06000804180078461DD44EA6FFA30AE4084006D +:10E07000EA6384004413F00EAC08FFBF4413F01AA7 +:10E08000AC0897B04403F040AF80DD47DD46AE40BA +:10E090005A78020A4410005AAE40490000FCC8FEFB +:10E0A000EA81EB654413F0DAA608EB26402500046C +:10E0B0009690AE88540480FF4413F0EDAE08DD471F +:10E0C0004403F041AE40EA29EA29EA29EA29EA298B +:10E0D000EA29EA29FCC0400004A44423F042960047 +:10E0E000A6D0AE10DD9E965F960440008084441357 +:10E0F000F043AE08DD9E4413F044AC08DD9E5400AE +:10E1000000FD4413F046AE08DD9E40003C0892102E +:10E110004433F2004010BC08AC1892304403F202C1 +:10E12000EB81AC4092504403F204AC80DD9E44038A +:10E13000F20AA640EA21EB1B58108001AE40EA2803 +:10E14000AE88A640964CC9FEDD9E96004423F2069A +:10E15000AE1096484403F207AE40DD9EFC00DD4160 +:10E16000C004440255B8FC80440215B8FC80FC0091 +:10E17000DD41C00444024A00FC8044020A00FC80E5 +:10E180004403F20BA600DD9E4413F208AC08DD9EAA +:10E190004423F20AA650964C400080249600AE100C +:10E1A000DD9E9200E608E82344F0DFB4EA8BEA3D06 +:10E1B0004A003C00080E141A20262C324403F20CAC +:10E1C000D5154403F20ED5124403F210D50F4403C3 +:10E1D000F212D50C4403F214D5094403F216D50605 +:10E1E0004403F218D5034403F21AAE40DD9E9200B8 +:10E1F000E608E82344F0E000EA8BEA3D4A003C00F0 +:10E20000080E141A20262C324403F20DD5154403AF +:10E21000F20FD5124403F211D50F4403F213D50CBB +:10E220004403F215D5094403F217D5064403F21945 +:10E23000D5034403F21BAE40DD9E92004403F0C4BC +:10E24000A600DD9E96004413F0C4AE08DD9E440394 +:10E25000F0C3A600DD9E96004413F0C3AE08DD9E19 +:10E260004403F0CEA4004413F0D0A648400080E45C +:10E27000441D020088015C000080DD9E4402FE0017 +:10E28000DD9E84214403F0F5AE40DD47DD46AE401F +:10E29000DD9E4403F0F4A6009204DD9E4403F0F7F3 +:10E2A000A600DD9E96004413F0F7AE08DD9E440301 +:10E2B000F0F6A600DD9E96004413F0F6AE08DD9E53 +:10E2C0004452FE004412FE3E18028001D9FEDD9E3B +:10E2D000FC40440000FD49FFFFF54463F068EA7428 +:10E2E000EA7CF803FA09EA32A630EBC749FFFB8B58 +:10E2F00044000492EA32EA59D5F5FC0049FFFFEAEE +:10E3000092004423F0C7A65096485A0801055810B9 +:10E3100080C0D502966FAE50DD9EFC00441005FC17 +:10E320004403F0CEAC4084204403F0D0AE408401DE +:10E3300049FFFFE9FC804423F0ECA65096045410FA +:10E3400080FB40008044AE10DD9EFC0049FFFFF5DD +:10E35000FC804403F0CEA4004413F0D0A648400053 +:10E3600080E4EAB0FE0DEAD4DD9E92024413F0E6AA +:10E37000AC08DD9E4413F050A608EAE3AE08DD9E2B +:10E380004413F050A6089637AE08DD9E4423F050A3 +:10E39000A6509617541080F8FE47AE50DD9E4423D9 +:10E3A000F050A65096175410808F40008084AE1015 +:10E3B000DD9E4413F050A608EAE0AE08DD9E44134B +:10E3C000F050A608540000F7AE08DD9E4413F0514B +:10E3D000A608EA54AE08DD9EFC008407EB618420A9 +:10E3E0004403F04CAE40840749FFFFDB8421440323 +:10E3F000F04EAE4049FFFFECFC8096004413F04C19 +:10E40000AE08DD9E4403F04DA600DD9E3C0FFC4EA1 +:10E41000DD9E3C0DFC4EA600DD9E44030FA0EAB538 +:10E420003C0FFB623C1FFB393C0FFB41DD9EC004EF +:10E430005A000209DD9E3C0DFC4EA6003C0FFA7707 +:10E44000DD9E3C1FFA77DD9E40003C08921044336D +:10E45000F1C44010BC08AC1892304403F1C6EB8103 +:10E46000AC4092504403F1C8AC80DD9EFC00EBD878 +:10E47000A682A6434403F1C2AE804403F1C3AE407A +:10E480003C0DFB623C1DFB393C2DFB4149FFFFDE8F +:10E49000FC8084003C0FFB9484214403F1C0AE4017 +:10E4A000DD9EFC602EB728922EA728B52E9728B4A3 +:10E4B0002E7728934E030087EBBEC03D3C0DFB71C9 +:10E4C000E615E9392E0010AAC8113C00083A50F0B0 +:10E4D0007FB05CF78BE0E8083C00083B50F07FB071 +:10E4E0005CF79360E9038401D5028400EB40EBEE16 +:10E4F0005CF00708E807EA44C019EAED84CCC017CD +:10E50000D5155CF008FCE807EA44C010EAED84C4C5 +:10E51000C00ED50C5CF00A8CE807EA44C007EAEDAF +:10E5200084C5C005D5038400EB4084CF2E17EC745E +:10E530008006C905840084CFEB4080064413F1C2F5 +:10E5400010B080004413F1C310A080004423F1C434 +:10E55000441FAC48AC50443FA6084423F1C6ACD09D +:10E560004423F1C8AC5096004413F1C1AE08F8A69C +:10E57000DD47DD46AE40EB25A6085A0001FF440307 +:10E58000F1C210B000004403F1C310A00000441316 +:10E59000F1C4440FADD8AC08442FA7984413F1C67A +:10E5A000AC884413F1C8AC0897B04403F1C1AF8004 +:10E5B000F885DD47DD46AE40EB25A6085A0001FF91 +:10E5C000F8035A0001044800006EEBBEC0283C0D61 +:10E5D000FB71E615E924EA925CF00708E807EA44D3 +:10E5E000C019EAED84CCC017D5155CF008FCE8072B +:10E5F000EA44C010EAED84C4C00ED50C5CF00A8C6D +:10E60000E807EA44C007EAED84C5C005D5038400E5 +:10E61000EB4084CF2E17EC748006C905840084CFAC +:10E62000EB4080064413F1C2109080004413F1C304 +:10E63000AFC84423F1C4441FAD10AC50443FA6D032 +:10E640004423F1C6ACD04423F1C8AC509600441327 +:10E65000F1C1AE08F833DD47DD46AE40EB25A60834 +:10E660005A0001FF4403F1C2EB924403F1C3AFC06F +:10E670004413F1C4440FAEA0AC08442FA860441367 +:10E68000F1C6AC884413F1C8AC0897B04403F1C19B +:10E69000AF80F814DD47DD46AE40EB25A6085A00F2 +:10E6A00001FFFCE0FC0649FFFEE33C0DFA775A004F +:10E6B0000F1096004413F1C1AE0849FFFEECDD4790 +:10E6C000DD46AE40EB25A6085A0001FFFC86FA3075 +:10E6D000F18584228400EBF284A1F187EB22F083A0 +:10E6E000F084F086F088F0892E472893B67FF58174 +:10E6F000F382F58AEB0B8041EA48FC86FC212E0769 +:10E70000EC3D80E480C55A0801098406441000E10C +:10E71000DD43EB69B606D5599E0CE6025000FFF8C2 +:10E72000E9049680E642E81D9600E602E92D2E07F0 +:10E73000EF13C00B8405DD438406441000E2DD4383 +:10E740003C0DFFD9B606D541F181DD45F1015A08EE +:10E7500002F38406441000E3DD43EBB0B606D53582 +:10E760005A180D258406441000E4DD432E07EF5AA5 +:10E770008E01E606E81044F0E580EA8BEA3DDD0F05 +:10E780001A060E24141A3C0DFFD9B606D51EEACA85 +:10E79000B606D51BDD4CA600C804EA58B606D5154A +:10E7A0005A080314EAD0B606D5108E2AE622E808E5 +:10E7B000EACAB605441000E58406DD43D506DD4C03 +:10E7C000A60049000D31B606DD41C016EAAD5CF089 +:10E7D00000A0E912DD535A08010684033E07EF0347 +:10E7E000D50BDD535A0802092E07EF035A0803051B +:10E7F00084003E07EF03B4064412FF80402008095E +:10E800003C0FFB4FB641041000084422FF84966F72 +:10E81000B622A0014412FF88962FAE08EB3A4412AC +:10E82000FF89A0014452FF909206962FAE08EB3A62 +:10E830004412FF8AA001443D0070920C962FAE084E +:10E84000EB3A4412FF8BA0014422C6549212962F39 +:10E85000AE084402FF98986B38110400EAE9D8FC2E +:10E86000EB37B446441E0000882292229649EB9D65 +:10E87000EB37441E00208801920296014413F400F5 +:10E88000AC0897F84403F402AFC0FCA1FC2044712B +:10E8900066BC38138602463000FF40608C0292CC82 +:10E8A00010600009406090091060000A38638A0215 +:10E8B000462000F04073080292F040138484FEE684 +:10E8C000926C1010000B4410FF00407304021030D3 +:10E8D000000EFEAE40321009FE6E952492E84022F2 +:10E8E0000A1592281070000C1060000D1030000FF7 +:10E8F000102000101010001110500012FCA0FC029B +:10E90000444166903B024C00EBE9380F8000FE4525 +:10E91000380F8400FE85380F88005600000FFC82F7 +:10E92000FC41B4A0EA58D050EAD0D04EEBB0D04C65 +:10E930003C0C030BE608E84844F0E744EA8B40F05F +:10E940003C00DD0F127826485A3C7008EA4BC83E5E +:10E950008400EA62D53B84003E07F13DEB368E022F +:10E96000E602E8348402EA62D5312E07F13D8C01DB +:10E970009600E6063E07F13DE9298405EA62D526C0 +:10E980002E0010E4C8238406EA62D5203C0C030C58 +:10E990005A08030F3C100853E622E8F6D5163C0C43 +:10E9A000030C5A0803F23C000853E602E8ED840425 +:10E9B000EA62D50CEB36E602E809D5CBEA4BC0C9D2 +:10E9C0008407EA62D5038401EA62040280144412D7 +:10E9D00003009210EA51EA643C1C030BE62D4EF250 +:10E9E000011544F0E7F038178501EA9C4A003C0025 +:10E9F0001A008C00EC002C016801A801B201BC01D6 +:10EA0000D0010802DA010E0214022E17EF765A180E +:10EA1000010584203E17EF768420EA57841F3E00CC +:10EA200010C1EA47C8083C0C0090EB9B3C0C0091DD +:10EA3000EBEDD5095A0801083C0C0092EB9B3C0C0D +:10EA40000093EBED3C1C0307449166BC97C89648C5 +:10EA5000EB66EB0E842AB61F84468007F8893804DB +:10EA60008202F081EA6DEA82B49FEB16F5018426FA +:10EA7000844A8067F88D8400EA52F84F8421EA576F +:10EA8000EA47C8083C0C0090EB9B3C0C0091EBED76 +:10EA9000D5095A0801083C0C0092EB9B3C0C0093F2 +:10EAA000EBED3C1C0306449166BC97C89648EB66A8 +:10EAB000EB0E8423B61F84428007F85A3804820282 +:10EAC000F081EA6D44020040B49FEB16F501842208 +:10EAD00084438067F85D8405EA52F81F8422EA5770 +:10EAE0003C1C0308449166BC97C89648EB66EB0E45 +:10EAF0008421B61F84428007F83B38048202F081EB +:10EB0000EA6D44020080B49FEB16F5018422844133 +:10EB10008067F83E8400EA52480000788423EA5770 +:10EB2000460000CC500002BCEB0E8426B61F844287 +:10EB30008401F81E441166BC38008202F081EA6D3F +:10EB4000440200C0B49FEB16F50184228446846120 +:10EB5000F81F8401EA52D5598423EA5746000093EE +:10EB6000500000AFEB0E8426B61F8442840349FF99 +:10EB7000FEC8441166BC38008202F081EA6D44028E +:10EB800000C0B49FEB16F50184228446846349FFDC +:10EB9000FE7F8402EA52D5398424EA578404EA527B +:10EBA000D5348425EA578400EA52D52F8426EA57C3 +:10EBB0002E07EF765A08012284003E07EF76D51D16 +:10EBC0008427EA578405EA52D5208428EA570402AC +:10EBD000801644120200EA51EA644624259F461337 +:10EBE000DA6050108E45502101BAA841A842A8838E +:10EBF000A844A845A846A8478405EA52D506840734 +:10EC0000EA52D5038406EA52FCC19200DD40A60117 +:10EC10009E44E622E9075A000906DD4CA600E602FA +:10EC2000E8098405F815AE08F81AA6405A1001FF45 +:10EC3000DD9EEBAAA600C8058401F80AAE08D50F30 +:10EC40005A0001065A0002045A08030A84004413B9 +:10EC5000F572AE084413F57383FFAE084403F380E6 +:10EC60008421AE4083FFA6405A1001FFDD9E840040 +:10EC7000EB7A84214403F403AE40DD9E4403F403A5 +:10EC8000A600EAD4DD9E4403F40CA6009600C80753 +:10EC90004413F3CFA64840000406DD9E8401DD9EA8 +:10ECA0008400EA8CEB7AAE08DD9EFC005A08011164 +:10ECB00049FFFFAE49FFFFDD842B8400EB184413AE +:10ECC0008D463C0BF6573E07EC4EAE08FC8049FFE4 +:10ECD000FFE9FC804403F01DA680A641A6C04011B8 +:10ECE0000504581084009688AE809228A681AE4113 +:10ECF000EA214413F421F806502100014C21FFFEC3 +:10ED00008440AE88442000004430000A83FF502134 +:10ED100000014C21FFFEA6409648AE40DD9EFC203F +:10ED2000DD454432DEC4EB5C4422E26C5A08021436 +:10ED300084004472DA244462E2F84452E890F81203 +:10ED40003840800838428000384100088C015A0859 +:10ED500020F8FCA084004472E24C4462EBFC445274 +:10ED6000D99038438000384180083843000083FF41 +:10ED70003841000838428000384080088C015A0829 +:10ED800020F2FCA0A6403E101160A6413E10116189 +:10ED9000A6423E101162A6433E101163A645A6840A +:10EDA00040210500A647A6C6401185000030000995 +:10EDB00000400008EAE83C3808B40030000B00408E +:10EDC000000AEAE83C3808B50030000C3E30116C0F +:10EDD0000030000D3E30116DEBCA969396DC3E304C +:10EDE000116EEBCA964B4231840B3E30116FEBCA69 +:10EDF0003C2808B24231880B3E301170EBCA3C18F7 +:10EE000008B342318C0B3E3011710030000F96DF99 +:10EE10003E3011720030000F92643E3011730030AA +:10EE2000001100400010EAE83C3808BA0030001336 +:10EE300000400012EAE83C3808BB003000150040F2 +:10EE4000001496CFEAE83C3808BC00300015926206 +:10EE50003E30117A003000170040001696CFEAE8E5 +:10EE60003C3808BE0030001792623E30117E000030 +:10EE7000001E962F3E00117F42012C0BC006440F4E +:10EE8000F000FE873C2808B24200AC0BC006440FDD +:10EE9000F000FE473C1808B384093E001172FA06E0 +:10EEA0003E001173DD9EA4C0442200004412D6CC63 +:10EEB000EA3EB661A4C2EA3E1430800FA4C4EA3E22 +:10EEC000A8CAA4C6EA3EA8C902300008EA3E143027 +:10EED00080100230000AEA3E143080080230000C34 +:10EEE000EA3E143080090230000EEA3E14308011F0 +:10EEF00002300010EA3E1430801202300012EA3E66 +:10EF00001430801302300014EA3E143080140230B2 +:10EF10000016EA3E1430801502300018EA3E143024 +:10EF200080160230001AEA3E143080170200001CDE +:10EF30004021004014208018DD9EFC00EB373C2D62 +:10EF4000FFD7441E0000882292229649EB9DFC8048 +:10EF5000A40044120000EA643C0FFFDDDD9EFC00CB +:10EF60004423F6AC4413F6AD5A080106AE108407EC +:10EF7000AE08D5048400AE10AE0884008020804026 +:10EF8000FA6FEA3BFC80B44084A08C449C2DA2D153 +:10EF900096005A58200680A05A0823FADD9E544154 +:10EFA000803F384094088CA197689266D8F3D5F4D6 +:10EFB000FC20B48084608C8484E5B4045A3806054F +:10EFC00066000FFFD504921E4000780842219C2461 +:10EFD00084A096905A20200C386088008C414063B1 +:10EFE000140C8CA6880696905A581EF68C6196D8FA +:10EFF000AA215A3807E4FCA0FC20B46084005031F8 +:10F0000080249583A31997B0844099568C415472FB +:10F01000000F976896903870940892845A2808F7E1 +:10F020008C0196005A0804EFFCA0FC20B460840018 +:10F03000503180349583A31997B0844099568C4100 +:10F040005472000F976896903870940892845A28EA +:10F0500008F78C0196005A0804EFFCA0FC45EA581A +:10F060003C0FFB4F84234403F40BAE40842644033F +:10F07000F404AE4084014413F407AE084413F408CA +:10F08000AE0884404413F01EAE884413F420AE084A +:10F09000EA4E5A080105EA58490008284402D6CC2D +:10F0A0004412DA2449FFFF714402D6CC4412E8909E +:10F0B000F8054402D6D04412E21849FFFF9F4412DB +:10F0C000E2F84402D6CC49FFFFB2490009D0EBD8A0 +:10F0D00049000A46B1C1440166A03B0044048027B0 +:10F0E0003B00C424A600AE08B184440166AC3B00DA +:10F0F000440480263B00C424A600509F801CAE0818 +:10F10000844984208009EA3F840110048006842019 +:10F110004442E24C4432EBFC4402D9903823840050 +:10F120003822040838230400382184083824840055 +:10F13000382004088C215A1809F3FCC5FC00B4805F +:10F14000844050420024840080A098D096D8383063 +:10F150008C00958296DF4031980C8C0188A35A0868 +:10F1600008F68C489690AB615A2820EFFC80FC048E +:10F17000A649B4405A1003045A180D0FEB45A6488F +:10F18000C9054412E890EA80FC845A180325441209 +:10F19000E218EA80FC845A180407F81658000003A5 +:10F1A000B889FC845030FFF6E662E80B8420844680 +:10F1B0003820FC088C215A1820FD803FEA80FC840E +:10F1C0008E28E622E8088382B8096600000F83FFD4 +:10F1D000EA7AB889FC84FC00A68180C05A20031416 +:10F1E0005A2006129E14E602E90E50017FF8E6024C +:10F1F000E90E50017FF6E602E90A5A280D1EDD45A8 +:10F200005A08020684003E07EBFAD50484013E0743 +:10F21000EBFAEADAA6712E27EC0F84812E37EC3058 +:10F220004452C4D049FFFA6CDD455A000206EA5D3B +:10F23000802649FFFF9EFC80FC00B4808440504241 +:10F240000034840080A098D096D838308C00958205 +:10F2500096DF4031980C8C0188A35A0808F68C4838 +:10F260009690AB615A2820EFFC80FC014412DEC46A +:10F27000F08149FFFE9FF001EB5CF9BBFC81FC24AF +:10F2800080E180C049FFFD4D2E2011724442DEC452 +:10F290004402D9702E3011615A780635842938120B +:10F2A0000808E662842238100808E924DD455A0877 +:10F2B000022284005A6803122E1011614432E218AF +:10F2C000F83C5A0820FFEA8FC00D8E228440881F28 +:10F2D000E24110F07FFFD5064422E890F83F5A083B +:10F2E00020FFEA8F8429381F8008EA5D803FEA808A +:10F2F000D54CEA8F4412E26C8443EACDEA5DEA80A1 +:10F30000D5448420381208085A6803053860080874 +:10F31000D504842138100808E662E930DD455A0832 +:10F32000022E5A6803192E00116184285A0802031C +:10F33000842784004432E21838218000382F800866 +:10F340008C0183FF5A0820FAEA8FC010881F101022 +:10F350007FFFD50C84004422E89038110000381F4C +:10F3600080088C0183FF5A0820FAEA8F8422381F14 +:10F370008008EA5D803FEA80D508EA8F4412E26C9B +:10F380008445EACDEA5DEA80EA5D49FFFF70FCA4AE +:10F39000EBB43C1DFFE6D10C3C1DFFE7D1093C1D41 +:10F3A000FFE8D1063C0DFFE9FE2DEAD4DD9E840185 +:10F3B000DD9EEBB43C1DFFD7D10E3C1DFFD8D10B19 +:10F3C0003C1DFFDFD1083C1DFFE0D105EBB0FE2D59 +:10F3D000EAD4DD9E8401DD9E844540300817848692 +:10F3E00096D8FE2438108E024000800D962FDD9EA8 +:10F3F0003C1DFB3F3C3DFFE45A1802043C3DFFE648 +:10F40000EB82442201209230EA6A40110440044019 +:10F41000800A462C003F50210FFF54000FFF400090 +:10F420004808FF16FF071440800AEB82443201802F +:10F430009230EA6A401184400430800AFE9EFE1732 +:10F440001400800ADD9EFC00446201044063002039 +:10F450002203000049FFFFCEA4303C0BF662FC8083 +:10F46000FC4180C03C0DA3D2F081EB17EACA80E1D9 +:10F4700081224C5000C1CE04AF9084E1D50F5A6870 +:10F480000409800149FFFFE11074800084E3D50680 +:10F49000B00138600400AE5084E38400EB5C386057 +:10F4A00080088C014492D9705A0820FB49FFFF83E1 +:10F4B000C0123C0DFB58441203C00400001492100B +:10F4C000EA51EA643C1C03068C259648AE44AE45DE +:10F4D000AE46AE4749FFFF5EC0693C2DFFE64412D1 +:10F4E000042050810050B408443397809210EA51B0 +:10F4F000EA643C1C030784888C259648AE443C1C77 +:10F50000030884A28C259648AE46B40844120360D2 +:10F510009210EA51EA643C1C009084CB8C259648FA +:10F52000AE443C1C009286098C259648AE453C1C96 +:10F5300000918C259648AE463C1C00938C2596483D +:10F54000AE47B408441203C09210EA51EA643C1C6E +:10F5500003063C2DFB4F8C259648AE44AE45AE4687 +:10F56000AE47840004110008966FE001E84098431C +:10F57000A6489648E634E809E62CE810C1125A1865 +:10F580000A1339048008D50F5A10140650F0FFE012 +:10F59000E2AFE90938448008D50638648008D5030D +:10F5A000387480088C019600D5DEEBB4EA58D0039D +:10F5B000EAD0D81D84283E100200842A3E100202A0 +:10F5C0003E10020C2E1011724422DEC438210400B9 +:10F5D0004402D9705A280906844238200408D50705 +:10F5E000387004082E10117338700408EA5DEB5C63 +:10F5F00049FFFE24FCC144138D40AE08AE98DD9E49 +:10F60000FC0180C0DD4CB65FF381AF808001EA4130 +:10F610008006B43FF20149FFFF25FC81FC608400B5 +:10F620003E07EBFADD40842300A0000144738D41C6 +:10F63000AE410093800049FFFB74840080408067E6 +:10F64000DD5544638D4000B30000EBA3EA5D441236 +:10F65000DA2449FFFCAF8403DD5580498067EBA3C2 +:10F66000E7628403E8028400AE304412DA24EA5DE3 +:10F6700049FFFCA0A630DD558049EA4DEBA3A6303A +:10F680003E07EC44DD4010A00001FCE0FC2083803C +:10F69000BA12BF1354217FFF444203204022084086 +:10F6A00092F05403FFFFA7D5844CFFD440738040F1 +:10F6B000EA8288E0C3239221520086409641EAB153 +:10F6C0004000801796009E45E637E813846140614C +:10F6D000800C9F41842088039AA94041880C98811E +:10F6E0004021880CFEA78C21FF975A1805F7D51AE0 +:10F6F000E605E916466FF800D5152E07F13CC80956 +:10F700008401466CCCCC3E07F13C50630CCCD50A4E +:10F71000466333333E37F13C50630333D5034460D3 +:10F7200001FF2E07EC48C007EBA5EB1E9201E2207B +:10F73000E80284DFFFB3DD41C00292D042033C0BFC +:10F74000F80E464FE3FFF827A8394203380BF807B5 +:10F7500050420FFFF829A8394203340B8C0654108D +:10F760000007A03983FF66000007FE0FA839420397 +:10F77000300BF8226600700040000584B607420393 +:10F780002C0BF81A66000E0040000524B607420351 +:10F79000280BF812660001C0400004C483FFB607BE +:10F7A0004203240BF809660000384000046483FF1C +:10F7B000B6074203200B8C0654100007B40783FFE2 +:10F7C00066000007FE0FB60742031C0B8C06542090 +:10F7D0000007B4074418FFFFFE0E40000A0442234E +:10F7E000180BB6078C4654310007460FFC7FB44710 +:10F7F000EAF7FE8640210E64B6474223140B8C467E +:10F8000054310007B447FEA640210EC4B647422338 +:10F81000100BF80B462F1FFF50210FFFFEAE4021AB +:10F820000F24B64742230C0B8C46B4A75431000773 +:10F8300083FF4628FFFF50210FFFFEAE40210F84BB +:10F84000B647A0F94223080B8C469697FE5E4010FF +:10F850008A04A879A0B94213040B8C269657FE1689 +:10F860004000066497B4A8398CC654030007A1B9B8 +:10F87000FFA6406302C4A9B9FCA08400EB45AE0812 +:10F88000EA763C1BF6704412C8C43E07EC44AE084E +:10F89000AE09AE0AAE0BDD9EFC60847FAED084DF85 +:10F8A000846084A18246808382034532C8B8812562 +:10F8B000814302B0000097D8E3618220E80A38A9AA +:10F8C0008C08A540E2B2E8098245820784A0D506EB +:10F8D00038998C08AFD0D50284A0031880008C61C1 +:10F8E000E3A68C024068BC1B4043BC1B5A3804E3AF +:10F8F0005A50010380908004FCE0FC42FA408120D1 +:10F9000080E1801F8420EA3F2E27F1444432C65C08 +:10F91000EAB83801880880834462EDD4C70438739C +:10F920000909D50484013803090984209C11450183 +:10F9300067DC45100BB899419757387214005A701C +:10F94000FF0F38380400385315014231C4244031C8 +:10F950009476385F9E028865383F9E0A8C215A183B +:10F9600008EC842080618081385F86029788E28578 +:10F970008C2140333C1B4042BC1B5A1804F7E6471D +:10F98000E90284003E07F14410348000FCC2FC0010 +:10F990002E27F15A84C34011185744300320969003 +:10F9A0004412817842110C73DD5EEB1D2E07F15A73 +:10F9B0008C0196004060183796484010041B3E1793 +:10F9C000F15AFC80FC002E27F15984C340111857CE +:10F9D0004430032096904412817842110C73DD5E0E +:10F9E000EB1D2E07F1598C019600406018379648A0 +:10F9F0004010041B3E17F159FC8084003C0BF65A62 +:10FA00003C0BF64ADD4CA600C0049E43E622E812F9 +:10FA100044037320A6003C0BF64A441373224403AC +:10FA2000732144237323A600A648A6903C2BF65AC4 +:10FA3000D5269E41E622E9035A0805208400445356 +:10FA40007320802044337334A7283C23F64A8CA4C7 +:10FA500088443C2BF64A0022FFFD88020022FFFE6C +:10FA60000042FFFF88223C23F65A960188449649BB +:10FA70003C2BF65ADBEAD503840080203C23F65A5F +:10FA800088223C23F64A9649880296013C1BF65A86 +:10FA900088203C0BF64A3C1BF658DD9EFC00846037 +:10FAA00080A384DF9718E282E80738500D09386098 +:10FAB0008D098C61D5F8FC80FC0084A040308C203E +:10FAC0004C118018A500A588E2C4E803A500AD0884 +:10FAD000A580A510E2C4E803A500AD100A4080018E +:10FAE0000A6100018A86E0A4E80297618C02D5E9E8 +:10FAF0008005FC80FC2084A0826041214009808236 +:10FB0000800597E9E2E3E83C5CF38064E90650F3A2 +:10FB1000FF385CF78064E8304069942002F300000D +:10FB200003108000E3AFE80503030000130080002A +:10FB30000313000002F20000E3AFE8050303000036 +:10FB40001302000003108000EB764108C001E010B2 +:10FB5000E8133D180B2A40080013EB763D080B2BE9 +:10FB6000A5B03C680B2C3C780B2D3C080B2E3C2898 +:10FB70000B2F3D280B308CA18C228C82D5C3FCA08E +:10FB8000FC004440032080C1EAE54210107380016C +:10FB9000802280434430012CEB79AC30FC80401053 +:10FBA00004204430FFFF84404C00800EA500E24456 +:10FBB000E803A4809691A500E283E803A4C096D947 +:10FBC0008C02D5F344000096420180019A10960100 +:10FBD000DD9EFC7BB18281808420449000C8800639 +:10FBE0008448EA3F4014B0368560409084084473EE +:10FBF0002D5085404CA60014B004B05D4420003266 +:10FC000049FFFF4EEA768007EB4938132901E220CD +:10FC1000E803380329098D4188E9D5ED44732EE0C6 +:10FC20005AB001048561D5E64422C392441007D03E +:10FC3000800649FFFE33EA2A38130101EB5749FFDA +:10FC4000FE5E2E07EC00EB89381301013823090111 +:10FC5000E241E8069A8A5CF100C8E804D5028440D3 +:10FC6000EA2A9451443001F440108C37E623E80727 +:10FC7000C907441000C740108806D5028423EB89C9 +:10FC80002E57F15BDA072E37F14588613E37F14593 +:10FC9000D5033E17F1452E37F145E663E8035A18C0 +:10FCA000030684003E07F14580023E27F15BFCFB22 +:10FCB000FC2080C180E0AE08840449FFFF8C441220 +:10FCC000C8B838109C002E27EF785A180108E64271 +:10FCD000E8098C413E27EF78D505C2048E413E27C6 +:10FCE000EF7884203E17EF772E17EF78C105842137 +:10FCF0003E17EF77AE30FCA0FC6044600320FE347A +:10FD0000448301904463000050B1819050A201905F +:10FD100080E18122890088C0EA768006EB490214DE +:10FD2000800081A9E220E802EB7350C30190EA76DB +:10FD3000800CEB49021680008D22E220E8031204B9 +:10FD4000FFFF5015FE70800650257E70F809A478DC +:10FD500081A7E220E802AC38802B800C804AEB06B9 +:10FD6000EB33021680008CE2E220E8031203FFFF6F +:10FD70005063006450B5806450A500644C647FCE2D +:10FD8000FCE0FC00EB352E17EF9EC0203C0DCB1E97 +:10FD90005A18010592019601D503920296013C2D55 +:10FDA000FBDAE2402E07EF7AE806E61EE80F8C0148 +:10FDB000EBC5D50CC00B5CF10E10E906E60FE904AB +:10FDC0008E05EBC5D5038E01EBC55A1801112E0720 +:10FDD000EF7A5A081E058405EB6DD50CE614E9048C +:10FDE0008406EB6DD5078407EB6DD50449FFF3134B +:10FDF000EB6DFC803C33F8A75CF18033E913FC0029 +:10FE0000848084C3E282E80D40301020A558A4C845 +:10FE10008C81FEF490624031945C1A308001D5F3FD +:10FE2000FC80DD9E84003E07EF798400EAE6DD9EDB +:10FE3000FC003C03F8A7EB2FE905EADB84003C0B50 +:10FE4000F66FEB96EB2FE9038400EAABFC808400AD +:10FE50003E07EF7884003C0BF8A1DD9E3C03F8A13F +:10FE6000EB2FE905FC0049FFFFF4FC80DD9E9200CA +:10FE7000FC012E07F15CC0048E013E07F15C49FFD6 +:10FE8000FFEF2E07EC00501F800749FFFF132E07DE +:10FE9000EC225A00FF2F84023E07F15C2E07EF731D +:10FEA0008C013E07EF734400004ADD422E17EC221E +:10FEB000E624E81FEA4744F0FCC0EBC6EA9CDD0FED +:10FEC000041A041AC816840184273E07EF763C1EE4 +:10FED000030B3E000C14EBB9D50C5A08010B84013E +:10FEE0003E07EF768407EA6284003E000C14EBB90B +:10FEF000FC81DD40A6015A080309DD535A080206B9 +:10FF0000FC0049FFFFB7FC80DD9EFC0080C0840040 +:10FF10003C0BF65849FFFD732E07EC14406300D6E6 +:10FF2000DD453C2394D85A0002088423FE549649A8 +:10FF3000E2C1E90BD50EEB5DE2C20010002BE8092F +:10FF40003C03F658E220E9058400EAAB8400D502C0 +:10FF50008401FC80B461AE185A2802049208AE19DC +:10FF6000B4018840B641DD9EFC448140B61F81212A +:10FF70008400B1C13815000038101C088C015A08E3 +:10FF80001AFB44001900F844EAD0B43FA680AE88BA +:10FF90000400001EB43F92109C89962FB65FAE09F4 +:10FFA000F82B844244000280F835EA58803F046010 +:10FFB0000014EA8292D0EA6D406018408386B80E41 +:10FFC0008442F821F823B80BF829F823B41F001352 +:10FFD0000028AE40B41F84429C41B63F3C1DFFE464 +:10FFE000046080144412018092D0EA6D4060984011 +:10FFF00000130028AE41B41F803F8C01B61F83FF61 +:020000021000EC +:100000000403000E92109605F80502030016803FC7 +:10001000844249FFFFA10403000B803F921054006B +:100020000FFF83FF4E00FFF6440FFFAA100480511C +:10003000EA28EA21000480515A00CC04AE88D5FB9E +:10004000DD41C0074412FE51840280418461DD44D9 +:10005000840038138000381500088C015A081AFBF8 +:10006000840010048051FCC4FC0044030C803C1C40 +:1000700001BF442000C8EB1DFC80FC002E07EC23D0 +:100080008E01E602E808DD5E44030C80EA7E3C2F28 +:10009000FBBDEB1D2E07EC23EB2D5A080116445334 +:1000A0000C80442F74F84430096044430FA084004E +:1000B000986AA5A838608009500003204C01FFFB16 +:1000C0008CA2DCF6FC80FC80FC0049FFFEB349FFFB +:1000D000FFCD2E07EC23C008EADBDD4CA60049FF6C +:1000E000FFCE8400EBE2FC80FC000400001444120C +:1000F00000609210EA51EA642E1729B81010001817 +:100100002E1729B9101000192E1729B61010001B30 +:100110002E1729B71010001AA0454210F008A84564 +:10012000A0454210F408A845A0454210FC08A84587 +:10013000A0454210F808A845DD41C00544037320DE +:10014000F804FC804403738449FFEBC3FC803C0F3C +:10015000FC58DD9E5A00010544128178D502EA7EE2 +:100160005040832080A184001A028001DCFEFC2024 +:100170004453000044630C80800180650A218001A3 +:10018000A5C04023885C1A2000014C027FF9505220 +:100190008320DEF38400443281784440096084A0E7 +:1001A0009883386080013861140950528320DCFA4A +:1001B0008C025A0B20F6FCA0FC60848084FF84C172 +:1001C000826780A482244492C8C4816681040300AB +:1001D0000000552200FFE3828140E80E030080000A +:1001E000E383E80A38849008A580E2D3E8088266B1 +:1001F000823284C0D50538B49008D50284C00B0083 +:10020000800102A500008C81898AE3878C024078F6 +:100210003C1B40593C1B5A4804DC5A60010380B126 +:100220008005FCE0FC002E17EC5B3C6DFFD7C10B9A +:1002300084003E07EC5B441000E684063C6DFFEE54 +:10024000DD43D534C80ADD535A000131DD535A0865 +:10025000022E3C6DFFE6D52A5A08030EDD535A08DC +:1002600001053C6DFFD8D522DD535A0802203C6DB4 +:10027000FFE7D51C5A08010EDD535A0801053C6DF5 +:10028000FFDFD514DD535A0802123C6DFFE8D50E8E +:100290005A08020DDD535A0801053C6DFFE0D506F2 +:1002A000DD535A0802043C6DFFE98006FC80FC0027 +:1002B0002E07EC40C82B3C0DFBE45CF00032E90457 +:1002C0002E07EF66C0062E07EF655CF00032E91ED0 +:1002D00084203C1BF654840044326EB8EB51E20299 +:1002E000E80698838C01AE509601D5F93C0C01BB11 +:1002F0003C1C01BDEA2044000033EAE6EA7EEBF74D +:10030000DD5E49FFFD798401EAA7FC8040300C20C6 +:100310004C0180051A200001D5FCDD9EFC4051FFF8 +:10032000F9B8F0818400EAFEEA7EB0028440EA2453 +:10033000EBF3500F8328EA7E4420FFFFEA24EBF31F +:1003400084C044A00320449281784472EDAC8009BB +:1003500042032873B042502F8328EA24EB793803F4 +:1003600099098CC1EAFE5A6803F4B042502F8328E1 +:10037000EA24F001EB79EAFE3C080B22EA7EF00168 +:1003800049FFFB07DD4CA6008E03E602E8113C03A3 +:10039000F67044600032EB2FE9089E4150007FCE9A +:1003A000406018D69B8E97B13C6BF670D504EB5D20 +:1003B0000260000EDD455A0002058403FF8497B1F8 +:1003C0003C03F7B63C100B243C080B23E220E80367 +:1003D0003C080B24E2C03C680B253C080A403C6802 +:1003E0000A41E80584023E07EF79D5162E17EF790A +:1003F000C1048E213E17EF793C13F668E220E90A2A +:100400003C03F8A74410EA5FE220E9068C01EAE623 +:10041000D5038400EAE6EBC2E602E9078401EA912B +:1004200084003E07F140D5098400EA912E07F1408F +:10043000C0048E013E07F14051FF8648FCC04403D2 +:100440008D40A6402E07EC53C1062E17EC525A18C9 +:1004500001038C013E072958DD9E44100055DD46FE +:10046000AE40EA8CA608C8FFDD9E3C1DFFD74422A3 +:1004700000C0040080149210EA5140010040B40012 +:10048000920A96373E07EC310400801444120000B3 +:100490009210EA51EA64B42000000028922A96776C +:1004A0003E17EC143E07EC3ADD9EFC008400EB7A2C +:1004B000DD4B8421AE4084018020EBEFDD46DD473B +:1004C000AE403C2DFB54A6505A1001FFDD47AE4014 +:1004D000840AEA49DD4B8421AE408400EB133E07D9 +:1004E000EF65FC80FC008403EBE2EA9B8400804023 +:1004F000DD55EA4DEA9E8400EAA73E07EF658401D8 +:100500003E07EF66EB23DD4CA60049FFB927EADB87 +:10051000FC80FC20444200002E672A2484204433BF +:100520008D4080E49688E246E819A7589881C50472 +:1005300000510020D5033850040041020400105837 +:100540000184A758C50400210028D5030021000814 +:1005500099791022818C8C21D5E6FCA04422D6CC3E +:10056000B46244420000EB82A0919230EA6A4012E9 +:1005700004400410800A923254108FFF964B1210E0 +:1005800000813C1BF667EB82042100159230443257 +:100590000180EA6A4011844054217FFF4432000CFC +:1005A000402188400230801F103001040230801F3B +:1005B0009268103001050230801E103001060230B2 +:1005C000801E926810300107A4D310300108A4D314 +:1005D000926810300109A4D11030010AA4D19268A8 +:1005E0001030010BA112846192985452003F0440D4 +:1005F00080114041903E404290E41040010CA09296 +:1006000004108011924896AFFECE40310CE41030B9 +:10061000010DDD9EFC2080E080C1DD41C00C501347 +:1006200001048041846A8402DD44EA4C840249FF6B +:100630009B11D504840249FF9B0DEAD0442201801E +:100640008380B914BB1592304402000C5431FFFF73 +:1006500040300C40EA6A00030105401104400023C9 +:1006600001044001010096011200801F00030107F0 +:10067000002301064001010096011200801E0003C4 +:10068000010C40201C0950408044B404EA7B400027 +:100690000824B604B4040023010DEBF0400008F573 +:1006A000B6040003010900130108EB4C9601AC1BD2 +:1006B0000003010B0013010AEB4C9601AC19000377 +:1006C000010CA09A5410003F460C0FFFEAF7FE16EB +:1006D00040000704A81A0003010D5410003FA01A9F +:1006E00066003F0040000504A81AC7038EE197F892 +:1006F0008403DD558047EA4DEBA3FCA0FC6081211B +:100700008162814380C4DD54A60896005A0801FE28 +:10071000DD58AE088020EBEFDD59A640C9FFA640AA +:100720005A1801FF84003E07EC42DD41C021DD5C28 +:100730005A0807FFEA79EAB5EA20DD4B8421AE408A +:100740000074812ECF0649FFB8593E77EC42D51090 +:100750000073005197FCCF0649FFB8501074809E7B +:10076000D5058400EBA849FFB78E8401EB21840AEC +:10077000EB0D8400100300511003005210030053CE +:10078000FCE03C1DFFD74422000004108014463CCE +:10079000003F9230EA6A401104400420800A503140 +:1007A0008FFF54000FFFFE9E402102441420800A58 +:1007B000DD9EFC4280C2812080E1FA408420801FBF +:1007C000EA3F987E2E27F1504432C668EAB896492F +:1007D0003801880880834462ED9CC10438130909FC +:1007E000D50484013803090984209C11450167DC84 +:1007F00045100BB899419757387214005A70FF0F83 +:1008000038380400385315014231C42440319476FD +:10081000385F9E028865383F9E0A8C215A1808EC82 +:10082000842080618081385F86029788E2858C21F0 +:1008300040333C1B4042BC1B5A1804F7E647E90210 +:1008400084003E07F15010348000FCC2FC60EE389A +:10085000509F8028F082F183844884208009B1CCA5 +:10086000EA3F800784208448EA3F8400EAFEF003E0 +:10087000446000C8406300D654D300FF400684089B +:100880009600F08485809431F081048F8002816924 +:10089000814C97B1F0034CA0005FB00E501F810057 +:1008A000F20449FFF8FD4452817844428AD840E678 +:1008B0001400888C14BF8005B04E502F81008066D4 +:1008C000800EF487EB33F086B06750070190502F0D +:1008D00081648066EB33F50602158000E205405026 +:1008E0003C1A9629E220F407E8031255800050E7ED +:1008F00003204CE27FE3B04E502F810080668008D9 +:10090000EB3350E40190F086B067800E502F816485 +:100910008066EB33F406F105E20440403C1AA4483B +:100920009621E2208D62E8031245FFFF802D8008AA +:10093000EB493803A909802D800EEB493813A90132 +:10094000E220E8033803A909F0018D41890040C67F +:100950000000D5A1F00249FFF837DD453C1DFC58E9 +:100960000220800F5A0002058403FE849691806263 +:1009700080298007F97A38138101100F80273824E5 +:100980008101500F802749FFFF1644138D41A608AF +:10099000004F802738038101EAFEA6C83853910131 +:1009A00038238D0138048D0188023824910188454F +:1009B000E040E8069A825CF100C8E805D502844070 +:1009C000103F8027A608443001F4945140108C3722 +:1009D000E623E807C907441000C740108806D5027F +:1009E0008423002F80272E57F158DA072E37F15134 +:1009F00088613E37F151D5033E17F1512E37F15141 +:100A0000E663E8035A18030684003E07F1518002AA +:100A10003E27F158EDC8FCE08401DD9E84004412BD +:100A2000C668845FEACD8C015A0808FE84003E0740 +:100A3000F150DD9E5A0801078401AE088400AC1015 +:100A4000DD9EEB5D0200000F42420001E283E9F50A +:100A5000A410E61EE8048C01AC10DD9E8400AE08F4 +:100A6000DD9EFC40812184203C1BF7B610910000E4 +:100A7000842480C2814349FFFEEB80E04402C8C465 +:100A80003810240081205A18010FEBC2E602E80456 +:100A90008C013E07EF7984013E07EF9E84003C0BFA +:100AA000F66ED52E4412C70E84004422C44C3C334B +:100AB000F7B63C43F668F9142E17EF79C1048E217E +:100AC0003E17EF795AA801128460802338048C0005 +:100AD000C8038C2196498C615A3804FA5A180406C6 +:100AE000EB968C01EAABD5038400EAAB3C13F8A784 +:100AF0004400EA5FE201E9048C213C1BF8A7840072 +:100B0000EA91EBC2C0048401EA91AFF0FCC0FC00A2 +:100B100097844060982044100640FE0CEAE54000AF +:100B2000803C80228043EA24EB79AC30FC80FC607E +:100B300051FFF9B8B67F8160EA24B002818180E27A +:100B4000EA7E8440F481EBF34420FFFFEA24500F57 +:100B50008328EA7EEBF3DD4B8421AE4084C0840120 +:100B60003C6FFB994493F04AEA7F44A00055EADBCE +:100B700044D3F4234C65804584003E07EC61840037 +:100B8000EB2084018020EBEF840AEBF9EA490006B0 +:100B900080005A000404EBF9D5FB850A85C02E07B6 +:100BA000EC61E20CE825DD5C5A0807FF3C8FFB6432 +:100BB0003CEFFB992E07EC61B43F5A780209F20131 +:100BC000B0C2504F832849FFF899D50BB082503FEF +:100BD00083285A78010549FFF7D5D50349FFFF99C6 +:100BE0002E07EC618C0196003E07EC61D5D9DD4BF8 +:100BF0008421AE408CC1EA40EA9F97B0D5BCEA9B05 +:100C000051FF8648FCE0FC4384208448B002EA3F60 +:100C100084208448B004EA3FEA9B8422DD4CAE4045 +:100C2000844284018425F80C44638D42EA74EA7C92 +:100C3000A6305A088F0AEA59840184258442B0C23A +:100C4000B104F829D5F6B04284448402F85ADD454F +:100C50003C1DFC580220800F5A0002058403FE84CC +:100C60009691B0428062B00449FFFAA8F08149FF32 +:100C7000FED78402F815EA9BF001FCC3FC0180C09A +:100C8000EA9B8421DD4CAE40840184258040B0C1C4 +:100C9000504F800649FFFF4D5A680105800649FF05 +:100CA000FA5BEA9B020F800249FFF931FC81FC41AB +:100CB0008400EA2A49FFFA0ADD4CA600C0145A0053 +:100CC000040448000060EA5F3C0BF6684412C70E5B +:100CD00084004422C44C3C33F7B64440005049FFE2 +:100CE000FEABD5063E07EF9EEA5F3C0BF668EBF7DE +:100CF000842049FFFB15DD4CA6004412C6DC84416C +:100D000049FFBBFFEB58A60096424E14000F5A084D +:100D100088098400EA913C03F8A78C01EAE6D5052E +:100D20008401EA918400EAE6EBF7EA7EDD5E49FFA2 +:100D3000F863EB7C5A000103F8612E07EF6E5A004E +:100D40000103F85C8400EB4FEAD2DD4249FFFF5D0E +:100D5000EA2AEB58A60096424E140004960FEA2A9F +:100D6000DD55EB89EA4D8403EA9E84C184003C0B87 +:100D7000F66EEAA73E67EF9EEB23EADB3E67EF9F46 +:100D8000F83D440000963C0BF668EB095A0801094F +:100D90003C3DFBE44400003140300C06D507846044 +:100DA000C8052E37EC3640300C0644138D41EBF766 +:100DB000A648EAB249FFFE5744138D422000800046 +:100DC0004E04001A8400EA91A6089636C00F8400EB +:100DD000EAABA60854200020C20E66200020960F21 +:100DE000AE88EA2A8401EA91D506EB96E61EE8036E +:100DF000FA0EEAABEB7C5A0001044800006E2E07A5 +:100E0000EF6E5A08011D2E77EC2B5A780119449386 +:100E10008D4100548000EB56D05F84C03E67EF9F49 +:100E2000EA9B8403DD55EB898069EA9E3E67EC40CE +:100E30003E67EF653E77EF9FEB23D54EEB96E61EC0 +:100E4000E94BEB44DD428400EAABEA9BDD41C0089C +:100E5000DD5C5A0807FFDD4CA60049FFB47F840122 +:100E600049FFFF0E44238D42A6508062970A4E44EC +:100E700000089666C106440FFFC0AE10D521C820F9 +:100E800084E0AFD82E67EF72EA4DCE0E8006DD55B6 +:100E90008046EA9E3E67EC403C6FFBE43E77EF65A0 +:100EA000EB23EADBD5198403DD55A698EA9E3C0DB9 +:100EB000FBE4EB2FE91184013E07EC50D50DEA4D20 +:100EC0008403DD55A698EA9E8400EAA73E07EF65F5 +:100ED0008401EB4FEB23EB5D0000002EC00B3C13B5 +:100EE000F7B64402FE54AC403C13F65E4402FE5694 +:100EF000AC40FCC1FC00DD455A08022C3C1DFB9BAC +:100F0000EA8FE220E803EAA2C00C84003C0BF6570B +:100F100049FFEEBBC81E49FFF57249FFFECAD5194D +:100F2000EA8A5A0801064402C41E49FFB2EC840151 +:100F300084408080842A806280A2DD56DD535A0876 +:100F4000020549FFC8DED5DB2E07EBFD5A0801D8A4 +:100F5000FC80FC20DD4CA6802E17EC142E07EC3A0A +:100F60002E37EC032E50117FCA058040820180038A +:100F7000D5048205804380A1427140243D1C01BDFF +:100F8000422014248480452333103C039462E28081 +:100F9000E81595A140034800A4C0A44088D1A4301E +:100FA000FE6C4231C0249A08FE3C8C814000081639 +:100FB0009A189601AC309721D5E93C0C01BD3C1C38 +:100FC00001BBEA20FCA044531C20442003E8443326 +:100FD0001DB05A08050BA528021291B8FE644010F6 +:100FE00088379649AC68D50B5A08010AA4680242B2 +:100FF00091B8FE54401090379649AC688CA2DBEA59 +:10100000DD9EFC6080E0DD4C80C181828163814493 +:10101000009000005A780114C1038EC197B0EBAA6A +:10102000A740D607EB095A080105800649FFDAD91F +:101030008403DD558046EA4DEA9ED50D5A78020CB0 +:101040005A980405840149FFFFC08400DD5580469D +:10105000EA4DEA9E840149FFE7ABDD54A6089600FD +:101060005A0801FEDD58AE088020EBEFDD59A6409E +:10107000C9FFA6405A1801FFDD41C016DD5C5A08C1 +:1010800007FFEA79EAB5EA20DD4CA600C8045A98C1 +:101090000409D5055A0804064E93000449FFFF5B76 +:1010A000DD4B8421AE405A7801098400107600009F +:1010B00010758000EB0DD5095A78020884001006DF +:1010C0000000EB218401EB0DFCE0FC202E67EC4FCF +:1010D0003C73F64DA60149FFDC438EC1E2E05C6340 +:1010E0000001E904EBD5C00284C18006FCA0FC002D +:1010F000DD40A6415A1004058424AE41EA41840A29 +:10110000441000B5DD43EBD5C803F80AE80349FFF6 +:10111000DECE840A441000B6DD43DD41C024DD5B31 +:101120008E04E60283FFE8172E07E9E05A08010A59 +:101130004410003F84088041806149FFE485D51553 +:101140005A0802144400003F84268040806049FF12 +:10115000E47BD50B4420003F84088426806249FF4D +:10116000E473D50349FFE482441000B7840ADD43E9 +:101170008405DD4AEA4CEB3E8406DD4A840A4410CD +:1011800000B8DD43DD4B8421AE40842084028041E1 +:101190008461808180A1DD56FC80FC418120EA4091 +:1011A000EA9F84063C7DFB3FEA6884C1DD40EB7E1C +:1011B000EA41DD4CA600842649FFF0638400EA6121 +:1011C000DD5997F83C7FFB3F3E67EC6DAF80DD4B10 +:1011D000AF802E67EC0F97B05A6801108026DD4073 +:1011E000DD57800949FFDB9CF08184408402F101D6 +:1011F0008066808280A2DD56FCC1FC2080C0DD4775 +:10120000DD46AE404472FEF22E07EF12C819840488 +:10121000441000F3DD43EB038401EBFC5A080103A7 +:10122000F832A6B89690C205DD4049FF961FD5ED6D +:10123000840180208062808080A2DD56D5E6840112 +:10124000EA63840ADD4A2E07EF12DD4AEA2B5A08C8 +:101250000108EAF45A080105EB30C002EA782E27AB +:10126000EF125A280313EA2B5A080106EAF45A0827 +:101270000103EA788401EA3049FFDBF08400EA6385 +:101280008400EABE4800006B5A280409DD4084212E +:10129000DD57EB1A8400EABED5615A28060D800698 +:1012A00049FFFF7D84013E07EF0C8400EA63840060 +:1012B000EABED5545A280A12A63184C15A080A0631 +:1012C0008400EBCCEABED54AEACCDD4B3E67E9B8F8 +:1012D000AF808400EABED5425A28092CA63184E0AA +:1012E0005A080A0984023E77EF9C3E77EF12AE302F +:1012F000D5355A080B14AEB1DD403E77EF12EA4106 +:10130000DD408421DD578400EA3C3E77EF9C49FFB5 +:10131000B7E484013E07EF4DD5218405DD4AEA4C50 +:10132000EB3E8406DD4A3E77EF1284028420D5111D +:101330005A280B1584203C1FFBE3AEB13C2DFB5417 +:101340008401EAC33C1BF64D3E17EF12AE10840237 +:1013500080418461808180A1DD56FCA0FC6180C059 +:10136000A601B65FF3815A080408A6305A080105A1 +:10137000840049FFDABF2E07EC685A08010C4402CA +:10138000C3D8B43FF2013C3DFB4E3C4DFB4C49FF02 +:1013900099FFEA40EB48DD41C805EA26EA38EA371A +:1013A000D566852044A2FE5044C2C53844DD01B054 +:1013B00044B2FE56EA225A000121A6315A08041E00 +:1013C000EAAF4472FE50EB265A0010188401EB007D +:1013D000A6388540EAB780278047846610A380003E +:1013E0008402DD4484024412C6C880418060DD442A +:1013F000EA593EA7EDC8D52C3B0540003B064020EE +:101400004402FE54A6403E17EDCCA6013E07EDCDAA +:10141000EAB084024422C5388466DD444452FE505A +:101420004412C538800538203404380080004C014F +:10143000000D50748001E72597F8E8064400008904 +:10144000DD428127D5B881278CA14C55FFEDEA26D6 +:10145000FA12AE08804184028461DD442E07EDC893 +:101460005A08130F44000085DD42D50AA6085A0029 +:101470002204AED0D5FCEA89A6005A0013F5DD554A +:101480004422C38DB47FF401EB7749FF9B9796000C +:10149000EAD349FF9526DD5B5A00010984E13C7FD0 +:1014A000FB77DD41C8033C7FFB8DA6315A0808124B +:1014B000A6305A08024FEA425A00063E5A00090670 +:1014C000EA425A08113ED514DD455A0802FBD533CD +:1014D000541000FD5A180910A6705A18020D840104 +:1014E000EA7FEA429E46E622E9265A08112ADD41B1 +:1014F000C022D5265A080A07A6308E02E602E8293D +:10150000D51A5A08030CA7B05A680124800649FF6F +:10151000E54F8006EA7F8408D51D5A08040FA7B05E +:101520005A680118800649FFE5438006EA7FEBCF41 +:101530003E07EC028408D50E5A0006E7D50A84401F +:1015400084618402FA25808380A2DD568408D50256 +:101550008401FCE1FC0084003C0FFB96DD47DD4686 +:10156000AE403C2DFB96CA088401802080628080BA +:1015700080A2DD56D5F7FC80FC00DD548400AE0867 +:10158000DD58AE088401EA2C8409EA392E07EF09F8 +:10159000EA6EDD47DD46AE40EA8CA6085A0001FF40 +:1015A000DD41C00AEA26A6085A0832FF8407EA4944 +:1015B0008401DD4AD50C49FF9106EA26EAB1AE085E +:1015C000804184028461DD448402DD4AFC80920013 +:1015D000FC6180C081618406A67180E28520DD43C4 +:1015E000854944C3F04AEB90A6313E97EF4D8E03F8 +:1015F000E6094EF2030944F11400EB2BEA3DDD0F3E +:1016000012005C010406700204067A03D803B804D1 +:101610002005DD412E07292AC809DD47DD46AE40F9 +:10162000840944100091DD43D5295A08013E0493F2 +:101630008003F847E320E9F2D537DD59A600C82436 +:10164000DD4BA6005A080121DD535A08021BEA8A25 +:101650005A0801064402C41E49FFAF552E0728BF91 +:101660003C1DFB9B8C019401E220E808844084012E +:10167000842A8062808080A2DD56DD41C005D5DEEF +:10168000DD535A0001E6DD41C80BDD59A600C8084C +:101690002E07EBFF5A000105EB635A0001DA8409BB +:1016A00044100092DD432E07292A5A000103DD5F12 +:1016B000DD41C021EB58A600C0038400EA3CA1FB39 +:1016C00049FFD957E2E0E805EA2B5A080107D51986 +:1016D00049000ED1C8FAD515EB3D5A000113EABCFA +:1016E000C805DD5B8E04E602E90C2E07EC4F5A00BC +:1016F0000109DD5F2E17EF125A100403DD5FEABE09 +:10170000DD47DD46AE40DD54A608C0FFDD41C80818 +:10171000DD4CA6005A08030949FFF6E6D50549FF46 +:101720008A24C0FED5F68404AE3184003E07EF1350 +:10173000DD40EA4149FFDAC9DD41C00884064410B2 +:1017400000D5DD438404EA25D5038401EA63840ED1 +:10175000DD4A84023E07EC20EB1ADD5F840B441067 +:1017600000BADD43DD41C81F840B441000BBDD43DC +:101770008006EB08F95E8405DD4AEB3D5A00010561 +:10178000EA2B5A0801098408441000D2DD43840181 +:101790003E07EC188404441000F1DD43EB0380069F +:1017A000EBD2DD5F840B441000BCDD43EA22C83E6F +:1017B0008401DD4ADD5B9E44E624E9145A000C13E3 +:1017C000EA225A000410EA2B5A000105EB3D5A08A0 +:1017D00001063C03F7AC5A0801048006EBEB8400D9 +:1017E000EB00EBCF2E57EC02D805EA27EB9FEBBFBF +:1017F000F908EA40EA9FDD5B8E04E602E809EA5058 +:10180000EA2EEA3A8400EA468400EA61EA94EA228F +:101810005A000413441000D28406DD438404EA25F0 +:10182000DD408421DD57EB1AD5075A0804068401F0 +:10183000EA878400EB008400EAC3EB088006F8F92D +:10184000EAF45A080103DD5F8401EA30EAC75A0866 +:101850000103F804EA225A080404480001ADDD53EC +:101860005A000203F804EBD54E0301A6480001AB71 +:101870002ED7EC6D5AD8011349FFD9438402EAC32D +:10188000DD4BEB9284053E97EC75DD4ADD414E025F +:10189000FEADDD5C5A0807FFDD5F5AD00203DD5F55 +:1018A0008400EA35DD41C028EA8F8C023C1DFB9B99 +:1018B0008C22E220E8053C1DFB7D5A1801F9EA273D +:1018C000EB9FEBBFDD404412E20449FFDB74EAC743 +:1018D000C805DD40A601EAE2F9798406DD4ADD4665 +:1018E000DD47AE4080C049FF8933C0FEEA43AE30D9 +:1018F000DD53C0FFD52249FFBD7EEAF55A08030536 +:101900003CDFFB3FD5038401EA35DD47DD46AE40D1 +:101910004493F7F1EAA280605A0801FE0074800047 +:1019200097FCCFF94412C46C80418402DD448006E8 +:10193000EBD23E77EF0CDD5F2E67EC4F84003E0765 +:10194000EF0C5A680108DD408420DD573E67EC6DDE +:10195000DD5F000580004E030131EAC74E03012E12 +:10196000DD535A00010448000129441000D48406C4 +:10197000DD438404EA25EB1ADD5FEA425A080610CB +:101980008400EA87EAC3EB9FEA27EBBFDD45C00C82 +:10199000EA770200001049FF8FB2D5065A081110ED +:1019A000DD41C0EFD50C8403DD42EACCDD58840173 +:1019B000EA30EA75AE08840FDD4ADD5FEA425A007C +:1019C0000903DD5FDD455A000203DD5FDD40842051 +:1019D000DD578403AE31DD5F8401DD4ADD41C80996 +:1019E0008006EB08F8268405DD4A8006EBD2DD5F31 +:1019F000EA22C8178402DD4A49FFB45C8006EBEB9B +:101A000049FFD9FDDD4B8421AE40EA225A00040E85 +:101A10008409EA258403DD4ADD41C007F839D5058C +:101A20005A0804048401EA878404DD4A8006EB082E +:101A300049FFDB6EEAF45A080103DD5FEAC785213E +:101A40003E97EC755A000105EA225A08040A840AF6 +:101A5000EA25EACCDD588401EA75AE08DD5FA631DF +:101A6000EAE2F8B43CA3F64DA63149FFD779E3404A +:101A7000E912840BEA258400842BA83BAE71EA614D +:101A8000DD4B3E97EC6DEB92DD414E0200BD49FF10 +:101A9000B414DD5F8409EA258405DD4AEA4CEB3E97 +:101AA0008406DD4ADD418020C8F3840280418461E0 +:101AB000808180A1DD56DD5FDD41C802EA75A63078 +:101AC0005A08021F10860000DD54A608C0FFA63188 +:101AD000EAE2F08185A04402C3DBF1014422C4366E +:101AE00049FFD8C93CDBF64D10A30001DD40EA41B7 +:101AF000840010D3801CA83B3ED7EC6DF853EA421B +:101B00005A08070C8409AE31EACCDD588401EA7525 +:101B1000AE08FA083C0FFB5B84001003801CDD5FFD +:101B20002E07EC6D5A080119DD40EA4149FFB3D296 +:101B3000DD408429AE418420DD57DD40842BAE4159 +:101B400049FFFD1C8402DD58EAC38400AE08EA3078 +:101B50008403DD4AD5585A0802578404DD4A3E976B +:101B6000EC6DDD41C8088006EBD22E07EF4D4E0329 +:101B7000FD3DD54900058000C803EAC7C0042E0713 +:101B8000E9B8C8128409EA2510A30001DD40EA4142 +:101B9000DD408421DD5784001093801CA83B49FF61 +:101BA000B39C48FFFD23840AEA25EACCDD4B84215F +:101BB000AE40D5298402DD4A8403EA2549FFD74E89 +:101BC000D5228403DD4AA631EAE249FFD657DD403B +:101BD00049FFFA7DC00E8404DD4A84013E07EF0C04 +:101BE0008406EA25800649FFFADA8405DD4AD50B2A +:101BF000441000D38406DD438404EA25DD408421BB +:101C0000DD57EB1AFCE1FC40C002F93E4460006580 +:101C1000EA74EA7CDD45C00F8EC1C60D8421804187 +:101C20008061848044004F00EAA944000064EA32E5 +:101C3000EA59D5F18400EB84FCC044100055DD4620 +:101C4000AE40EA8CA6085A0001FFDD9EFC4080E011 +:101C50008122EA8380C049FFFFF29E79E62F4EF28F +:101C6000019444F11A7038178501EA9C4A003C003F +:101C70001E00740022014E02940016031603160380 +:101C800016037002A402F802160316031A03840452 +:101C9000FA21DD4344000030DD42840EEA68840509 +:101CA000EA348400EA8EEABBEA98DD455A08020469 +:101CB000AFF0D5FCDD45C00C842144005AF08041D2 +:101CC00080618081EAA94400006449FFFF9E800989 +:101CD0008421DD578420840280418461808180A139 +:101CE000DD56F8EC8404FA22DD43840EEA688406AB +:101CF000EA348400EA8E80A650030041843FEAE97A +:101D0000D8FFD5E6FA258404DD4344000031DD42E6 +:101D100084E04403F429AFC0F87084013E77EBFA05 +:101D2000EA3410730050EADAEB5F2E27EC0F84815F +:101D30002E37EC304452C4D049FFE4E2DD4CA6001B +:101D4000C806EA5D4412E890EA80D5075A080306FF +:101D5000EA5D4412E218EA8084003E07EF9C2E17E9 +:101D6000EF9F8400EA3C84013E07EC105A10010307 +:101D7000EBE28400EA7FDD548402AE08DD58AE0851 +:101D8000EA738E08E6044EF20102800949FFAB9720 +:101D9000F8958404FA23DD43EAB1DD42DD4B844249 +:101DA000AE80EAB88E02E603E906EB5F540080FDE0 +:101DB0005A0808078400EA8EEAC4DD42F87F10243E +:101DC00080002E07EF7DC8099E0BE604E90C5A102F +:101DD0000D0B5A180E0CD5035A180E06EBDA8400B8 +:101DE00049FFAC018408EA68D5038409EA6884E005 +:101DF000107300503E77EC2C49FFEC12DD40EA41B5 +:101E000084043E77EC85EA98DD4AEABBDD455A0852 +:101E10000205EB03AFF0D5FB4413F3D1A608EAA407 +:101E2000AE08441FFFC34403F429AE40DD45C0089B +:101E3000842144005AF0804180618081EAA98400B5 +:101E40003E07EF9C2E17EF9F8400EA3C84013E077B +:101E5000EC105A100103EBE28400EA7F840049FF92 +:101E6000E08984208009DD578405DD4A4400003381 +:101E7000DD42EA425A0004045A080706440001F40D +:101E8000EA32D504EA5F49FFCAA1DD45C0048400F7 +:101E900049FF8D35EBDA44000034DD42DD4180201E +:101EA000848F8402C10784408020806280A2DD5636 +:101EB000F8058041806180A1DD56480000688404F7 +:101EC000FA24DD438420DD40DD57840AEA68840378 +:101ED000EA348400EA8EDD40EA418401EBFDD55608 +:101EE0008404FA2ADD43840EEA688406EA3480A674 +:101EF00050030041843FEAE9D8FF80098421DD577F +:101F0000842084008461EA8E80418402808380A1E1 +:101F1000DD56D53CFA2B8404DD43DD45DD555A08FA +:101F2000020DA6095A00031380018420DD5749FFE2 +:101F3000D5958401EA30D50AA6095A000A0880011D +:101F40008420DD57EACC8401EA30000300510013FD +:101F500000524422C3A94432C3774442C3BC49FF60 +:101F6000F8528400EA8ED5128404FA2CDD43000373 +:101F700000515A0001055A08020584003E07EC4F43 +:101F80008400EA8ED503841BEA8EFCC092003C0FCD +:101F9000FC59DD9EFC6004EF800DC80AB461A049C5 +:101FA0009419944940108FF5EA5CEA53D54695217F +:101FB000981C9E628C82A40088238864A5C8A5987A +:101FC0009603814597FB97B34E070006EB39F8124D +:101FD000FD60D503858081AC4E7700078007EB3923 +:101FE000F809FD40D503850081284E67000880066A +:101FF000EB39490010D9FD30D50384C080E6400597 +:102000000408EB39FD50FD13FD04EA65FD10FD05E4 +:10201000EA2DFD50FD13FD04EA2FFD16EA65FD16BD +:10202000EA65FD10FD054900152D49001691021FB6 +:10203000801892014000042012070000FCE0FC63BD +:1020400080A03C03EF1EEBE3EB88A62CC009A62D75 +:102050005A001F07A62EC004A62F5A08310A0001F5 +:1020600000455A08010644000096EBE3EB880002A5 +:102070008009C0085A001F0700028008C0035A08E0 +:10208000310DEB6AC006B4025A080508EB83C80597 +:1020900044000834EBE3EB88A42CC80BEB6AC006C1 +:1020A000B4025A080526EB83C82344000A8CD51EC7 +:1020B00044401F004C02400CEB6AC006B4025A08B0 +:1020C0000518EB83C81544000960D5105A00310685 +:1020D00044401F314C02400DEB6AC006B4025A085E +:1020E0000508EB83C80544000640EBE3EB883C0C95 +:1020F00001834E0600BFC8083C0C01824440C34F18 +:10210000E2804EF300B73C0C01854E0600B3C808D0 +:102110003C0C01844440C34FE2804EF300ABA42842 +:102120004E0200A8A4294E0200A52E07EF764E030A +:1021300000A1026F800A3C4DFB59E2C44EF2009AA6 +:10214000026F800B3C4DFB65E2C44EF2009384812C +:10215000AF182E3010AD3C400302CB08C40650022D +:102160007FE140018006D502800481214411660090 +:1021700080E538509101441165C038109101B63F97 +:102180009C54F18144100064F18280C2501380108D +:10219000502380283C3C017EF822EA443C40030363 +:1021A000C807C40850127FCF40000406D50484003D +:1021B000D50280044411655C38509101441164F8E3 +:1021C00038109101B63F9C76F18144100068F1828D +:1021D000502380303C3C017F5013801849FFFEDCC7 +:1021E0000434800B0424800A4E360006CB3E5CF19A +:1021F00005DDE93B04A4800D04B4800C4EA6000765 +:102200004EA300345CF585DDE9303C0C030B8E02F7 +:10221000E605E82B80E9A03DA13C9441401093F5F0 +:102220009421EA53A07FA0BE97C394491273000C77 +:10223000941140108BF5806A804BEA5322F3000220 +:1022400096438AEF42F3800384015EF780F1100326 +:10225000007A1213000D22030003E8078A2042F0DF +:1022600080035EF780F1E90784001003007AD5034C +:102270008400AE18FCE33C0FFC5EDD9E4402B64CCD +:102280003C0FFC5DDD9E3C0FFE90DD9E3C0FFE8F03 +:10229000DD9E4402B5E43C0FFE8E500000343C0F3E +:1022A000FE8DDD9EFC2051FFFD1880C0121F8003B3 +:1022B00080E2441167E4EBDDB002DD494411689C23 +:1022C000EBDDB030DD4944116954EBDD500F81780E +:1022D000DD49500F823044116A0CEBDDDD495A6054 +:1022E00002095A60030A5A68010BB0F084C0D5098C +:1022F000503F8178D505503F8230D502B0C284C1AD +:10230000C722FA5D4450005A848084E2EA6B381197 +:1023100089119603E001E803C607D50BEA6B960323 +:10232000E020E816C6069855EAB68082960BD505D9 +:102330009862EAB680A2960BE005E80BE080E80917 +:102340008040D5E5EA6B960338018111D502800201 +:1023500051FF82E8FCA03C1C030B5A180216001027 +:10236000003C5A1801128420EB870210001812104A +:10237000001A021000191210001B0210000EEB9D33 +:102380000210000FD5252210001AFA83222000180F +:10239000EBE5FA642210001B40210C561220001AB3 +:1023A00022200019EBE52210001040210C561220CB +:1023B000001B2220000EEBE52210000F40210C56DE +:1023C000122000102220001142111073EB85121010 +:1023D00000110010007AC9080210001AEB9D0210CB +:1023E000001B12100011DD9EFC01021000100220E3 +:1023F000001A0230001B9A8A0210001196938A2359 +:1024000022300008964B5EF1803C90419021E80418 +:102410004E240008D50E5EF18C44E9034E26000AD6 +:1024200000400078E694E905848940211056D502E1 +:102430008440122F8000222000095EF1003CE80455 +:102440004E140008D50E5EF113C4E9034E16000ABF +:1024500000400078E694E905848940109036D50262 +:102460008420121F80013C1DFB655CF08708E80694 +:102470008420121F8000121F800104100011EAF94D +:10248000EAC2FF4E44110000D1203C1C04313C67DD +:10249000FCBFE6263C57FCBEE906126F8000125FC7 +:1024A0008001D513EAB48487964B421310739023AE +:1024B000964B121F8000021F8001964B42129073B0 +:1024C0009023964B121F8001EAB4964B4031842131 +:1024D00096DB123F8002021F8001964B40210421AF +:1024E0009693122F8003021F80021210000A021F0F +:1024F00080031210000BEB103C0BFCBFEAEA3C0B14 +:10250000FCBEFC81FC41F481411200114102400AF1 +:102510000040005A226080009724EB6C8641C4077B +:102520003C6BF9363C1BF935EB07D518B4805A489B +:10253000031A3C7DFC983C4DFC9988272E77F26865 +:1025400088C48CE197F8E6EFEB07EB703E77F26812 +:10255000E94640631CD6EB07EAB6EB703F27F2680A +:10256000D53E5A48013B3C7DFE8E3D37F936A738B3 +:102570003D27F9355A4801654049980142F2000368 +:10258000029380044049040142420003888F409432 +:102590008408E324E8550293800340748408E1E74B +:1025A000E803E0C7E8613CADFE8F024500098E817B +:1025B0008A899521E093E803E086E856E1C7E803BD +:1025C000E027E8520275000A8EE18AE995F9E0F207 +:1025D000E837E0E1E849D534EB07EB705A58012AB7 +:1025E000B4005A0801273C1DFE8EA40DE260E821CC +:1025F0003C0DFC993C4DFC984030440142F1800375 +:10260000A54E40324001EB52886F9569E065E811B4 +:10261000A4CF9F594202C4734242C073401184093F +:102620008801882440000C16EB853C0FFC99EB7068 +:102630003C0DFC99AC103C0DFC98AC11FCC13C7DF0 +:10264000FC983C4DFC9988272E77F26888C48CE171 +:1026500097F840631CD63E77F26840709CF6EB0713 +:102660003C7FFC98D5BC3D3FFC993D2FFC98D5B7ED +:10267000FC2004600011EAF9EAC2FF764461000020 +:1026800022708000224080013C3DFC963C1DFC975E +:10269000D604B4005A08010A84003C7FFC973C4FE2 +:1026A000FC963C0FFC95D53B978B975B41139801AB +:1026B000410214013C1DFE8D420880034238000394 +:1026C00088600200800E3C3FFC95E060E82400102A +:1026D000801E80E09F0942720C73FE0C80674213DB +:1026E000C4244040040A4F1500048824D5028A24DB +:1026F0004010803688263C1FFC974211C0244F05AD +:1027000000048824D5028A244000801688053C0FE6 +:10271000FC96D5053C7FFC973C4FFC963C0DFC9706 +:10272000AC103C0DFC96AC11FCA0FC20226080009B +:10273000225080013C7DFE8E2E1010AD3D27F928E1 +:102740003D07F9260243800EC10E3C3DFB65842AFD +:10275000403184770413800996D9EB850433800ACD +:10276000FE5CD51150137FEC96495CF08C58E80A5A +:102770005012FFEC96495CF093D8E8040013801ED9 +:10278000D502EA76B4005A08010A84003C6FFC9432 +:102790003C5FFC933C0FFC92D532411348014072E0 +:1027A000C001420880034233800388609521E064C1 +:1027B0003C3FFC92E8209E0980A442500C73FE64CA +:1027C00080654202C4244040840A4F1500048804F6 +:1027D000D5028A04EB2488123C0FFC9442019C240D +:1027E0004E7500048804D5028A04EAFC88303C1F38 +:1027F000FC93D5053C6FFC943C5FFC933C0DFC9432 +:10280000AC103C0DFC93AC11FCA0FC203C6DFE8E8A +:10281000EB8D0073001023008001CF0284E12E10A5 +:1028200010ADC1113C1DFB65848A401090370443F4 +:1028300000099649401204370443000AFF0C3C4F3C +:10284000FC8BD5060213000994493C1FFC8BB42075 +:102850005A18011384003E07F21C3E07F21A0203C5 +:1028600000093C3BF91494013D0BF9133E17F22A81 +:102870003C0FFC8BD5553D17F9133D37F9144048F3 +:10288000C00140098C01FF24424000733C0DFC8BC9 +:102890004522C98CE2802E57F22A8400E902840185 +:1028A000380914089E39D80884003E07F22A8401AA +:1028B0003E07F21AD5048CA13E57F22A2E17F21ABF +:1028C000C90C2E47F22A8001E204E8313859000091 +:1028D000CD028C218C01D5F984808004E207E807C1 +:1028E00038590000CD028C818C01D5F95A180109A4 +:1028F000E087E8060203000A94013C0FFC8B9A7CF7 +:10290000FECC42324C734210C02442124473403118 +:102910009C763C3BF91440009C163C0BF9133C039D +:10292000F914AC103C03F913AC11FCA09B7C8A8118 +:1029300088A1FEE44232CC73420240244202C473B6 +:1029400040319C763C3BF91440001C16D5E7FC2036 +:1029500022508000224080012E1010AD3C3DFE8EA2 +:10296000C10500618022FA24D5165012FFCE964987 +:102970005CF08C1CE80750127FCE96495CF0939C6B +:10298000E906021180108C239648D503001180209F +:1029900000618022B4005A0801073C5BF90C3C4BF3 +:1029A000F90BD52D3C37F90B3C07F90C8A648A05E5 +:1029B000FEDC423000739409FE042E77F215E260CB +:1029C0005A78010DE91E84003E07F2153C5BF90CB4 +:1029D0003C4BF90B3E07F214D514E8082E07F2140D +:1029E000E206E8048C013E07F2142E07F2143C5B69 +:1029F000F90CE2063C4BF90BE90484013E07F215A1 +:102A00003C03F90CAC103C03F90BAC11FCA0FC002E +:102A1000B480EB8DEB6C5A400503CC0AFA0E3C0FE8 +:102A2000FC84841F3C0BF9073C0BF906D5375A4848 +:102A3000011600000045C8063C0DFC84C80A840548 +:102A4000D502FA0E3C0FFC843C3BF9073C1BF9060F +:102A50003C37F9073C17F906D5213C4DFC84C404EA +:102A60008E813C4FFC843C4DFC84C4180000004522 +:102A70005A0801063C3BF9073C1BF9063C57F9068E +:102A80003C47F9079A299BA3FE04420318735EF0A2 +:102A900003E84012BC1B40323C1BACD0AC51FC8064 +:102AA000FC403C9DFE8D2240800000548016223068 +:102AB000000822700009EB6C8621C506E6A986286D +:102AC000E80341128013005480178601C506E6A969 +:102AD0008608E80341028013B5405AA0010A0400A9 +:102AE0000011EAF9EAC2FF4644010000D817840049 +:102AF0003C0FFC823C0FFC8184013D1FFC803D1F8C +:102B0000FC7F3C3BF8EE3C7BF8EF3C4BF8DE3C1B9B +:102B1000F8DF3C0FFC6E480000B15AA803044800DF +:102B200000AB3C0DFC6E51287FFF8C014200400140 +:102B30003C0FFC6E3C0DFC81E012E8038C01D502D9 +:102B400084003C0FFC813C0DFC823C5DFC81C8068E +:102B50004C59400584013C0FFC824462C94C942AC4 +:102B600041330000127980014532C92C3849960959 +:102B700088133C4DFC8038331609AC413C4FFC7F38 +:102B80004E5700099E6938030611406304409AC3FA +:102B9000D50638034A11406348409AC32213000106 +:102BA000420180038A27421080030264800D88015D +:102BB000E2C08026E9060214800CE20140103C1AB3 +:102BC0003C0DFC82C8043D1FFC80D5105AA0040FA8 +:102BD0000204800C403844018A20FE5C9A30400098 +:102BE0008017400800013C0FFC803C0DFC808423D2 +:102BF000806442308073842480038C02EB24E08064 +:102C0000E9043C0FFC80D5048C813C4FFC803C0DDA +:102C1000FC80E011E8043D1FFC80D505E180E8035D +:102C20003D0FFC803C0DFC6E3C1DFC80E001E80388 +:102C30003C0FFC8084203C0DFC8080C180814C10C6 +:102C40000010383996118883403994402231800130 +:102C500088C3C5038EA1D50280B28C21D5F18462D0 +:102C600040008C168880880640420496EAFC972330 +:102C7000964BD50384208081AD10AC51FCC0FC6B19 +:102C800080C0EAF904000011EAC2FF4644010000D6 +:102C9000D804841F3C0FFA7A3C1DFE8D3C0DFA7A55 +:102CA000A44DE201E8048C013C0FFA7AB4064E020E +:102CB000014F5A0805044800014B2E000154C00C76 +:102CC0002E000156C0092E0001555A001F062E0085 +:102CD00001575A08310A00030045C8060003005A8C +:102CE00096044E02013B021300180203000E4490AA +:102CF00000648A019603EB6F021300190203000FB0 +:102D000085418A019603EBD3EB1096039001EB6F9C +:102D1000EAEA96039001EBD3EAB4960BEAB4023FD9 +:102D20008001964B022F8001FE4442118873840378 +:102D3000964B8441F82F80E0420024244410005A2E +:102D4000EAFC97F9FFFC964B84418400F823521368 +:102D50009FA410030078964B84418403F81BEAB4C7 +:102D600042B02800964B421080034210A424804AAF +:102D70004010AC368402964BF80D023F800180E093 +:102D800096DBEB524231A42484024011AC36804AD7 +:102D9000964B49FFFA89EAB4964B4E160005FE7A27 +:102DA000974BD50280A7021F800112530012964B49 +:102DB0004E160004FE02960344416AC48044B0C229 +:102DC0003B01480480233B00C824120300130291F6 +:102DD000000044216AD4129080008262B0463B0910 +:102DE000C80480E13B03C82403398000133380000A +:102DF000B1CA3B02480480873B024824129200007B +:102E0000509F80383B01480480493B0148241331DE +:102E10000000513F804844216AE43B01480480930C +:102E20003B024824A490ACA0002300785CF1002869 +:102E3000E9595CF10032E80444400064D5034440A1 +:102E4000006D4302800342A00003402828019693AE +:102E500042210003969386213929C511E1C2E80574 +:102E60008DA141188013D5F9864D4319440151288D +:102E7000FFFFE15041290013E9038209D50380E1F6 +:102E800082033899C911381849118A4996D13829CD +:102E9000C51141312401382845113903C9118A412E +:102EA000FE9C969340214C5688413813C511969349 +:102EB0008A30FECCFEA4965B4030CC76887096DBE0 +:102EC000FF1C4470006440211C5640421C96421274 +:102ED0008824FE24EAB640001C16121300121203C6 +:102EE0000013EB1096035EF00051E903EA5FEB6F0D +:102EF000EB1096035EF07FB0E804440FFFB0EB6F79 +:102F0000EAEA96035EF00051E903EA5FEBD3EAEAEE +:102F100096035EF07FB0E804440FFFB0EBD30203EA +:102F20000012B041EAD8020300138041EA5B800638 +:102F300049FFFDB8B0418006804149FFFB9B020F6D +:102F4000800212030014EA6B12030015B4065A083B +:102F5000050584003C0FFA7AFCEBFC403D2DFE8E0B +:102F6000EB8D00690016EB6CC605E6C9E80597B164 +:102F7000D50484C1D50284C800490017C405E68978 +:102F8000E8059721D5048481D5028488B5E084A022 +:102F90005B3801123C5FFC6D3C5FFC6C3C6FFC6B72 +:102FA0003C6FFC6A3C3BF8C43C1BF8C53D3FFC61F0 +:102FB000480000AE5B380304480000A83C0DFC61EB +:102FC00051027FFF8C01420010013C0FFC613C0D5F +:102FD000FC6CE010E8058C013C0FFC6CD5033C5FF9 +:102FE000FC6C3C0DFC6D3C5DFC6CC8064C5840050F +:102FF00084013C0FFC6D4472C8F8400394403D1DB1 +:10300000FC6B38339609AC413D1FFC6A4E57000CEF +:103010005092FFFF3803A6114093A4409AC32204A4 +:103020008001D5083803C2119AC34003C040220072 +:1030300000019A41EB524210800388230239000DAF +:1030400094D9E2618003E9070209000C9401E220AF +:103050004000BC1A3C1DFC6DC9043C6FFC6BD510D4 +:103060005B30040F0219000C412084088A129A6612 +:10307000FE0C8A7240000C179A203C0FFC6B3C0D32 +:10308000FC6B8423807142308073842480038C0223 +:10309000EB24E1A0E9043C0FFC6BD5048DA13D1F9E +:1030A000FC6B3C0DFC6BE006E8043C6FFC6BD5054B +:1030B000E080E8033C4FFC6B3C0DFC613C1DFC6B6D +:1030C000E001E8033C0FFC6B84203C0DFC6B80C1ED +:1030D00080814C100010383396118883403394401F +:1030E0002231800188C3C5038EA1D50280B08C2116 +:1030F000D5F1846240008C1698E0880640318476D1 +:10310000EAFC96DB964BD50380258065ACD0AC51AC +:10311000FCC0FC40B480EB8D227080013C1DFE8E13 +:103120005A480113ACD0ADD1A60D3C3BF8C03C7B56 +:10313000F8C15A000104480000CD84003C0BF8BEE1 +:103140003C0BF8BFFCC0A78D0100005A5A6801353E +:1031500054080002C0313C47F8BE3C07F8BFCC051C +:10316000C02B3C37F8C0D5283C17F8C1C80380E114 +:10317000D523FF62FF0C3C17F8C082434240047520 +:1031800042329424421000244330142441108C0015 +:103190004231C82442399C7542301075FE02FE2C23 +:1031A000FE7C42104873421290754031C476401044 +:1031B000C43696DB97CB54080002C06E5EF18C805B +:1031C000E9093C57F8C05EF28C80E80F44500C7F50 +:1031D000D50C4E3400083C57F8C04E55000784A06B +:1031E000D50480A38400D50284015EF39400E9072E +:1031F0003C47F8C15EF21400E962D50C4E74000839 +:103200003C07F8C1848042401001D5045A080145AA +:1032100080873D17F8C03D07F8C140F1C401802305 +:1032200080074123C001E80B84024092C40140079B +:1032300080164204C87340003C1688104F22000CD0 +:10324000842240924001401904364214BC7340105D +:10325000C83688314C48003A5EF08C80E904510051 +:10326000F381D5054E140032530080004C58800E77 +:103270005EF01400E90451106C01D5054E040023E2 +:1032800053100000E1B0E80496EB97C3D505E19137 +:10329000E80396CB97E35A68010C3C03F8C09A18F0 +:1032A0003C0BF8BE3C03F8C19A383C0BF8BF3C3BE2 +:1032B000F8C03C7BF8C1ACD0ADD1FCC0444013FF9A +:1032C000D5A94F02FFEAD5E186004C58FFD3D5E4DB +:1032D000FCC0FC2180C0EAF904000011EAC2FF46EC +:1032E00044010000D80984003C0BFCC03C0BFCC12D +:1032F000841F3C0FFA793C7DFE8E3C0DFA79A47D4B +:10330000E201E8048C013C0FFA79B406C06D5A0062 +:10331000056C0203000AB041EAD80203000B8041A9 +:10332000EA5B800649FFFB75B041800680413C3D69 +:10333000FA793C4DFE60A77949FFF8E6A63AC00647 +:10334000B0418006804149FFFA62A63BC006B04109 +:103350008006804149FFFE03A63CC006B0418006BE +:10336000804149FFF9E4EB535A00010A2E07EC3C77 +:103370005A0001062E07EBFE5A080107B0418006ED +:10338000804149FFFAE60003005A960EC007020387 +:10339000000AEAD80203000BEA5BB04180068041D4 +:1033A00049FFFEB9220F80024E0400048400EAD8CF +:1033B00022FF80025EF78C80E90444000C7FEAD88B +:1033C000220F80034E0400048400EA5B22FF800386 +:1033D0005EF79400E904440013FFEA5B020F8002E9 +:1033E000AC36EA6BAC37B4065A08050BA4363C0B76 +:1033F000FCC0A4373C0BFCC184003C0FFA79FCA153 +:103400003C0FFECBDD9E3C0FFECADD9E4402D2483F +:1034100084213C0FFE9F84003E07FA803E07FA811C +:103420003E07FA823E07FA833E07FA843E07FA8592 +:103430003E07FA863E07FA493E07FA483E07FA4A2F +:103440003C1FFA7C3E07EDB34412D1F88400845F40 +:10345000EACD8C015A084FFEDD9EFC00EA83FC8019 +:10346000FC0080C049FF9FB7C0048400AE34AE3575 +:10347000FC802E07FA50DD9E2E07FA44DD9E443272 +:10348000D1B8AE18AE59AE9ADD9E3C0FFA7CDD9EE7 +:103490003C0DFA7CDD9E3C0DFB6C465FF00FEAC2F2 +:1034A000FF4646001000D80684003E07EDB38401B5 +:1034B000DD9E8400DD9E2E17FA822E57FA83EB38AC +:1034C0004C12C0102E27FA805A28010CA6059D49DF +:1034D000400280B697683E57FA823E57FA83DD9ED7 +:1034E000A6058CA1400280B697683E57FA83D9049E +:1034F00084013E07FA80DD9E2E57FA822E17FA834A +:10350000D9042E07FA80C00FEB388CA1A605400223 +:1035100080B697683E57FA824C12C00584003E0779 +:10352000FA808401DD9E2E57FA822E07FA83D8088E +:103530002E07FA8084208E0140008006DD9E8401E3 +:10354000DD9E2E57FA822E07FA83D8072E17FA80AF +:10355000840040000406DD9E8401DD9EFC0084A002 +:103560008C81E2A4E8073860080438608C0C8CA1D8 +:10357000D5F9FC80FC613CADFA7C84BF816081217F +:10358000B4C1105F80075AA001044800009B84E08A +:103590003C3DFECA2F17FA443D2C041A3D3DFECB9C +:1035A000802A44C0004C81A781C7850686029E8977 +:1035B000000180099690E240E81243413024B40BA8 +:1035C00041505000B4159E81E642E9035A08047642 +:1035D00004058003B4009E81E642E808841F1003BE +:1035E000003E1003003F480000865A0004F9DD53F6 +:1035F0005A0802052E0010DFC8F25B1801045B2098 +:1036000005EF00098003222A8004224A8005037105 +:10361000800203618003C01702018009518BFFFF04 +:103620008E0140F041F642F16073518B7FFF4027DD +:1036300080560201800A8E0140F041F642F260732A +:1036400040478096E057E903502BFFFFE096420188 +:103650003400E903504B7FFF81E642F3A0738442BC +:103660004021046442423800102780004020100AA4 +:10367000102780014022100A10278002971F404225 +:103680000084020A800A10478003C006B44B8854A5 +:1036900000010014D502840110078004020A800B87 +:1036A000C0039600D50284018CE11007800597F8CD +:1036B0001053003C1053003D8C21964848FFFF7981 +:1036C0002E77FA48C7172E07FA495A001913E61E33 +:1036D000A670E805965740008064D503440000F0CA +:1036E000AE302E07FA4AAE328401AFF13E07FA50EF +:1036F00084E02E07FA505A00FF0DC00BCF0A841F3A +:103700003E07FA503C0DFE938C013C0FFE93D5030F +:103710003E77FA505AA801153C0DFECA0040000938 +:10372000E2E4E80E84268406FE7C8A87B449FF041E +:1037300096488822EB578440806A8E81F946B40906 +:10374000842080A0502000400832800188239648C1 +:10375000DAFCFE4A101000405AA00104480000CCD8 +:1037600004058003B4209E89E642E9055A1004044A +:10377000480000B922300006221000075EF18C805C +:10378000E805844042318800D50344300C7F5EF068 +:103790009400E805844042108800D503441013FFCC +:1037A000000000725A0001048401D503440000F0B7 +:1037B000EAD7042580035A08F02E84001001007215 +:1037C000041580034420FF00040080140430801599 +:1037D0004010080292281013004240106009101394 +:1037E000004446100FF010030043FE0E9210FE9EA0 +:1037F000FE5E1003004592484001E009923010231C +:103800000046103300471003004810130049848914 +:10381000D55F4001A00A100300424000A00A103307 +:103820000043100300441013004500010043C80783 +:1038300002010025C80902010026D5045A08010525 +:10384000840012010025020100253C3DFECB401002 +:1038500020091013004610030047A618C0060201F5 +:103860000014FE029603D50322010014A659C106D6 +:1038700002110015FE4A964BD50322110015A6DA57 +:10388000CB061003004810130049D505101300485B +:103890001003004984001003004A00010043100394 +:1038A000004B84001003004C000100415A00010845 +:1038B0005A0002085A080309EA50D507FA10D5053C +:1038C00044000040D502FA001003004D848DB44935 +:1038D000501200418822EB57844084615242000D0F +:1038E000D518B429EB575010804184408461848DF1 +:1038F000F86CD5125AA803112E07FA495A0819F381 +:10390000EAD7B429EB575010804284408461848CFC +:10391000F85C8401D5028400B449842050510041F0 +:103920005031004E0842800188249648DBFCFE4A54 +:103930001011004E2E17FA445A10FF0AC108C8078A +:10394000841F3E07FA44CF078401D5063E07FA4498 +:10395000CF02C0FB84003E07FA86FCE1FC008441F4 +:1039600080624440004EF831FC80A60092038C1522 +:1039700096275C000014DD9EFC4080E084003E073A +:10398000FA85A63880C1C80400038008C0322E071B +:10399000FA815A08010D2E17FA843E17FA823E1753 +:1039A000FA8384203E17FA803E07FA8549FFFD8599 +:1039B000EB382E97FA83A7043C1DFE9F8441A03963 +:1039C0004214907380628E8149FFFDCA2E07FA86E9 +:1039D0005A0801063E07FA813E97FA842E07FA45F7 +:1039E0005A00FF058C013E07FA458401EB19D50307 +:1039F0003E07FA452E17FA85B4065A18012BA6057C +:103A0000C814F836C80DEB382E37FA84A684B426CD +:103A10003C0DFE9F42018873B421F83AD50849FF56 +:103A20009CABF826C8FFD5F0F823C802F846B426A8 +:103A300084003E07FA853E07FA818401AE0DB42664 +:103A4000AE0CB4C6B406F8345A08013DAE37D53AC8 +:103A5000A644C904F868C036D50BA6055A08010665 +:103A6000F807C830F82AD52E49FFFD5FC8FA49FF8C +:103A70009CB680E0C82749FFFD41EB382E97FA82BB +:103A8000A684B4263C0DFE9FB4214204887349FFEE +:103A9000FF672E17FA815A1801112E57FA844C54D9 +:103AA000C00DB4063E77FA81AE45B4E6B40749FFCF +:103AB000FF5E5A080103AE3F49FF9CA1B406842172 +:103AC000AE44FCC0FC20804080E14402D1D8A0512B +:103AD000B6202E17FA50EBCBA052A841A053A84312 +:103AE0002E17FA444462D1F8101000104412D1D4B9 +:103AF0003C6FFE9949FFFD404402D1C82E17FA5091 +:103B0000AE402E17FA44EBCBB4273C1FFE9544126F +:103B1000D1C4A98149FFFF3284204402D1B8AE400C +:103B2000AE41AE4249FFFD0FFCA03C0FFF86DD9E7B +:103B30003C0FFF85DD9E84003E07FE10DD9E4402A3 +:103B4000B5B03C0FFF83DD9EFC6700608009230059 +:103B5000000223100003C6103C5DFF85A6EA8E61BB +:103B60004C61800B00308008C307A7AB8EC1FF9D5E +:103B70005C630001D50284C184603E37FB5AEAF9D8 +:103B800004300011EAC2FF5E447100004432D2A04A +:103B9000DF0D84A53C5FFED584A03C5BFDA43C5BAF +:103BA000FDA53C5BFDA23C5BFDA33C5DFED5C231A7 +:103BB000C50485605A5805093C7DFF838561007303 +:103BC000801C3E77FB583C77FDA441281C013C77C4 +:103BD000FDA540789C01FFFC427948735A500307C9 +:103BE000C5055A500504480000873C4DFF8302522A +:103BF0000011A508E2A42E47FB58E807A449E2A15A +:103C0000E804C4038E81972084A3CC7684A1D57464 +:103C10009E69E622E8053C1DFF83A649D5095A584E +:103C200003043E27FB582E17FB58C1048E213E1774 +:103C3000FB582E47FB585A48010684243E17FB5A6E +:103C4000D5038425C40284243C1FFED580C3803F55 +:103C50003B036404EA853B034C003B00CC203C7DE5 +:103C6000FECC3CADFECD3C9DFECE3C87FDA280B996 +:103C70003CC7FDA33D07FDA43D17FDA52EB7FB5A8C +:103C80002E67FB658420B6205A50051EB6FFEBD088 +:103C9000149F8002128F800A12CF800B130F800CAA +:103CA000131F800DF589104F802810BF802A106FD8 +:103CB0008035803F3B00E4043B01E4243B00CC0022 +:103CC0003B01CC203E27FE08B6A010B0005A12805F +:103CD000000412C000051470001714A000181490FE +:103CE00000191420001A5A58010B1280001C12C02F +:103CF000001DD50584A281918110D5C5FCE73C0F3C +:103D0000FFCEDD9E3C0FFFCDDD9E4402B5D83C0FBB +:103D1000FFCCDD9EFC40B4404E2200FA0070005AF9 +:103D200096FCC30E84213E17FE40021000080200DC +:103D300000093C1BFF1E3C0BFF1F480000E95A20F6 +:103D40000404480000AD2E27EF764E2300E12E3705 +:103D5000FE403C2FFF8E3C2FFF8DCB412E27FE31A6 +:103D60002E57FE304462D5945A200105804380834B +:103D7000D52180838043550200FF4D02C004860296 +:103D8000D502860139131211423844734113104091 +:103D9000231880018C81422844735A4803EE84849E +:103DA00040319076402110563C3FFF8E3C2FFF8DD6 +:103DB000D516390312118870410310408C812308F5 +:103DC00000019720E2A48850E8F58CA14031947658 +:103DD000405114B63C3FFF8E3C5FFF8D3C5DFFCCF5 +:103DE0003C4DFF8E3D2DFF8DA0E942F2000342299C +:103DF0000003884F94D9E2624EF2008A3D33FF1EE1 +:103E0000A6E850F9FF105CF78AA0E90294D93D03B7 +:103E1000FF1FA6A950F87F105CF79220E902949149 +:103E2000546380040092800201128003C60FFF1CBD +:103E300042190824404224964010C436403990006C +:103E40003C3BFF1E40280400D51B8E2184C24060ED +:103E500098D640549800405284B688D14013043616 +:103E60004251940142110401FF2C421904244032B2 +:103E700024764020C45688733C3BFF1E88503C1378 +:103E8000FF1E3C2BFF1F12100008587380023C13CA +:103E9000FF1F121000091070005AD5395A2005383A +:103EA0002E17FE405A1801093E37FE313E37FE30CC +:103EB0003E37FE40D5152E17FE30E622E8058C2150 +:103EC0003E17FE30D5033E37FE302E17FE31C908AF +:103ED0002E17FE305A18020584213E17FE3122307B +:103EE00000083C23FF1E2E17FE304442D5949A9AB8 +:103EF00038220609222000093C03FF1F401204401B +:103F00009A10AC093C3BFF1E3C2BFF1FFCC0FC0081 +:103F10000010004310100044001000451010004332 +:103F20003C1C042B46000FFF50000F00FE0E5A09E8 +:103F30000009841F3E07FE233E07FE223E07E9F4E8 +:103F4000EAA15A08015CEA445A0801313C04083AE3 +:103F500050107ED496495CF08A28E8083C10083B53 +:103F600050F0FED45CF791A8E96E84403C14083B05 +:103F70005EF0012C3E27FE233C0BFF103C1BFF0E86 +:103F8000E8043E27E9F4D55F5EF00B548401E805B0 +:103F90005EF0812CE80584023E07E9F4D5545EF01A +:103FA00092D48403E8FA841FD5F82E07E9F4C003FD +:103FB0005A0801093C04083A2E27FE234412D590E2 +:103FC000D50B5A0002045A08033F3C04083B2E2735 +:103FD000FE234412D58C38F089118A0FEB479601E5 +:103FE0005CF00065E9302E07FE235A00FF2D3E07E6 +:103FF000FE2284003E07FE23D51A5A080225EA4411 +:104000005A08010E84003E07FE233C00083A3C0B90 +:10401000FF103C00083B3C0BFF0ED5152E07FE227F +:104020005A00FF1284203E17FE23C00A3C03FF10F3 +:104030003C08083A3C03FF0E3C08083BD504841FAB +:104040003E07FE22FC803C0FFFD0DD9E3C0FFFCFE1 +:10405000DD9EFC00C0045A000108FC8049FFD080AE +:104060003C0FFFD1FC8049FFD0843C0FFFD2FC8085 +:104070008020E6093C0DFFD2E82344F13E84EBC6E4 +:10408000EA9CDD0F0A3C10161C22282E34003C0D41 +:10409000FFD1DD9E500000F0DD9E500001E0DD9E6E +:1040A000500002D0DD9E500003C0DD9E500005A0F0 +:1040B000DD9E50000780DD9E50000960DD9E84007B +:1040C000DD9E9200FC4080C280E13C2DFFD23C1D71 +:1040D000FFD18123814449FFD01A3C1DFFCFA60A9E +:1040E000A64B49FFD034EA504203000149FFD04EAD +:1040F00084C03C1DFFD000008010E2C0E8108006A4 +:104100003810980049FFD0503C0DFFD09846001061 +:104110008008800649FFD06E8CC1D5EC8400F80B76 +:10412000F80C8401F808F8095AA801058402F8037C +:10413000F804840349FFD02E49FFCFFB49FFD0226A +:10414000EA348481840000148000E201E82BA07925 +:1041500038508101D025A07D9482956A98CA88251F +:10416000A6DAA78AE266E802AECAA07D98CA8825C8 +:10417000A6DBA78BE2C3E802AECBA07D3830880077 +:104180008825A788E266E802AEC8A0FD884388A318 +:10419000A651A6A9E241E802AE693E47EF5C8C0158 +:1041A000D5D3FCC0FC62464C01208881446308FFE3 +:1041B000E2C4804080A14030C0094EF30082C805AF +:1041C0004603FF004C500121808280A1FD02844003 +:1041D000463BFF00EA2FFD10FD30EA2DFD60FD108B +:1041E000F8EE44216B40FD50EA5CF8E944216B385D +:1041F000F8F544216B48FD40EA5CFD06EA2DF8D451 +:1042000044216B58EA5CFD40F8DA44216B50F8E633 +:1042100044216B60F8DBFD06EA2D3A4F9400FD1057 +:10422000FD02EA2F44216B70F8C744216B68F8D671 +:1042300044216B78F8CBFD06EA2DF8D544216B803C +:10424000FD60EA5CF8CEFD10FD06EA2FF8C9F8D053 +:10425000EA2FF8C6F8A9F8C4F082F1838440463406 +:104260001A00F8ADFD50F80BFD15EA65FD10FD5084 +:10427000EA2D44216B30EA5CEA2DFD40FD10FD0380 +:10428000EA2FFD60FD10FD03EA65FD14EA2FFD40F5 +:10429000FD15FD03EA65FD1044016B303A00040092 +:1042A000EA2D3A0F8420FD13FD05EA2F3B0FC400D1 +:1042B000FD10FD08EA2DF878F89B480000A250F1A7 +:1042C000FFF044607FDFE2CFE8289509404203F524 +:1042D00040420024CC058401490000A6F813C8051B +:1042E0004607FF004C5000944001BC098082C8067C +:1042F0005451FFF044007FF0D80780A1FD0249002F +:1043000000A84800008680A1FD02844046343300A6 +:10431000EA2D465FCC0088A1469C01A08925406417 +:10432000B40997B74014D00944716AF840439880A3 +:10433000402286810432022540A3988080220422F4 +:104340000224EA650425022604350227EA650425CD +:10435000002404350025EA2DFD304004D00AEB3955 +:1043600044216AF8F833EA2D042500260435002795 +:10437000EA2FFD13FD40EA2FFD60FD13F820FD50EC +:10438000FD16FD04EA65FD13EA2F3A4F940044211F +:104390006B00FD40EA5CFD02EA2DF80644216B0843 +:1043A000FD40EA5CF81EFD10FD04EA2FFD40FD15FE +:1043B000F80644216B18EA5CF082F183FD03EA2DD4 +:1043C00044216B10F80B44216B28EA5C3A0F8420DF +:1043D00083FF4E00FFF544216B20EA5CEA2FFD10BD +:1043E000FD05EA2D3B0FC400FD10FD08EA2FF40285 +:1043F000F503FD10FD0283FFEA2DFD10FD04EA2FF9 +:10440000FD16EA2FD50584008020D5028002FD101C +:10441000FD01FCE2FC40FD30812249000503B7208C +:10442000FD03FCC0FC01C80584004613FF00D50451 +:104430008400461BFF00B61F8440F181B41F8062D8 +:10444000F1014900031FFA5249FFFFE6FC81FC60BD +:10445000FD10FD50EA65FD1049000314FD30FD0517 +:104460004900000AC006FD03FA5149FFFFD5FCE0F0 +:10447000FD03FCE0C10446580000D904C8038402CF +:10448000DD9E465FFF004647FE009F2198CDE283F8 +:10449000E8064657FF0098CDE283E9038404DD9ED9 +:1044A000464001009F21E281E8064658000098CD71 +:1044B000E283E9038403DD9E4657FF00D104465F93 +:1044C000FF00D902C0038400DD9E8401DD9E9200BE +:1044D0003A6F98BC40608C0390DF4E340006FEDAE1 +:1044E000C203FE929ED94E140006FE4AC003FE028D +:1044F0009E4984804900003AC60840408004C405B3 +:10450000FE4AC003FE029E493A6F9884DD9E9200E7 +:1045100041414009974192104040D03796D1401018 +:10452000C008FE4742020C24E220E8099F21984A75 +:10453000E222E905E220E8039F21984A9A484010C8 +:10454000D01740004008FE2FFECCE203E809980295 +:104550009E49E202E905E203E80398029E499A03B4 +:1045600040424008FE67DD9E3BFFFEBCFD80FD91A2 +:104570008384CB4DE3B2E8194209000782A0C00D45 +:104580004129000C525000204058140D4118800C55 +:10459000411894044108000CFD08805249FFFFBAFD +:1045A00082C1820086E0D523C2284209000782A08A +:1045B000C8048BB286E1D51452F000204129000CCA +:1045C000805240483C0D4058800C4108000C40028D +:1045D00090044018BC0D49FFFF9D82E18220FD0838 +:1045E000805249FFFF9782C1510000004FC2005323 +:1045F00086204108540DD54B41194A178420840068 +:104600004FC2004CB79C151E0001D547E3B3E9F734 +:104610004209800782A0C044524000204059100D3A +:104620004029800CFEAF82624129000C4038100DF9 +:104630004108000C4008800C4018900DFE1F49FFF7 +:10464000FF6982C182204200C869E3A1E9054C18D4 +:10465000C00CE380E809516B7FFF8A33403048018A +:10466000E2038A2F800386E04FC200154008000154 +:1046700040188401E3808A2F524A80204110900C18 +:104680004100540D410844044110D40DB79C151E3F +:1046900000018016501B80003BFFFE84DD9EE3F18D +:1046A000E903E392E90986C1404848018BB3E384FA +:1046B0008BAF8204D50286C086E04FC3FFE9D5EAFE +:1046C0004231FC0A95093A6FA8BC959947E8000069 +:1046D000E286E9054C434009E202E806FD40FD019F +:1046E000FD1495099599FECD4031F80240725409A8 +:1046F00040A354094092280840832808445007FFEB +:104700004C5380C440F200044EF200BC40F3080455 +:104710004EF200924063A8015CF300404EF2008C20 +:10472000405054094094940440002C0840515409CE +:104730004084140440212C08E6E2E9274094F80460 +:104740004EA20004408478049F714062A81AC61DDE +:10475000525300204E57000C4041140C4054140C8E +:104760004084180D4021180DFEAFD50CFFAA505201 +:1047700080204044140CFF174043181A4024180DA1 +:104780008500C40358210002C3594C7540064C945F +:1047900040044C010078E328E9054C94400AE20209 +:1047A000E8079FF940447C0893019241FEA780806E +:1047B0009A02E2808B2F8B28E6E2E9494E93000BA8 +:1047C000FA904043900680A7CC0D8120840050735E +:1047D000FFE042548007E2A75247800142529C0109 +:1047E000C50D9BFD9B6C526280204040180D40948B +:1047F000940C4000140C40949004500004005CF0B1 +:104800000400892FE32F88EF40502C09976C80C05B +:104810009A05E2C08B2F409484084054D008932C12 +:10482000920BFE2F4053D008409494044010F8029D +:104830004010A4043A6FA884DD9E9802E202892FFA +:10484000E32F8928E90AE328E908CFD8920B4044EE +:10485000D408932BFE27D5EB525387FEC50E54F098 +:104860000001585000024002BC1B4044FC08932148 +:104870009201FE279DF9D5C284004697FF00D5D747 +:10488000C3DA84008420D5D7409480044C9F40052F +:104890004C557FD2C3D0840044180000D5CC920080 +:1048A000FC42950992954070AC0840605409FFF7AE +:1048B00040602C0847C80000955992B54091AC085B +:1048C000408154094094A00440812C08FECD40A1B1 +:1048D000F002443007FFC4584C3200754073F004B6 +:1048E0004E5200874C3280794094F00414AF80031C +:1048F0005002FC0299204223A4694203246940919A +:104900000400E32140A1BC004223A06999D0E2E069 +:10491000892FE32F894F8923E323894F420320699D +:1049200099F9E2E1892FE32F40153C00FFC75804B5 +:10493000800140049C1AE420E90781E09800E20F1E +:104940009849882F9F2104AF80034E47007152522F +:1049500007FF4E570046500004005CF00400E804D6 +:10496000882FE22F888F40202C0996949A02920B70 +:104970004020D408FE179449922C40525008FE6FF4 +:104980004010A804FCC240F39804E81940F37C09E5 +:1049900099FF88EF99B6CF0580E684C050427FE04A +:1049A00042038007C09E9B20522000204023080D18 +:1049B0004063000C4073800CFFD7D593D315802A39 +:1049C000FCC2FFF74C7E4011CD06402484084021F4 +:1049D0002004C20ADB054094A0044C9E40068400DB +:1049E0004617FF00D5CE840044180000FCC24004E6 +:1049F000A004C0E640F47C098929892F89084E93D8 +:104A00000006812885005052FFE0420480074E02D4 +:104A1000FF6F9B68522000204024080D4084000C4A +:104A20004094800C4094880448FFFF6284C0523256 +:104A300000015CF18020E90A80C0800184205031AF +:104A4000FFE0C0045CF18020E81AC31052218020EE +:104A50004070880C4050080C40000C0D40108C0D2C +:104A6000FE3FFFAFC60358000001500004005CF099 +:104A70000400882F4040FC0948FFFF778400D5A040 +:104A8000FC42950992954070AC0840605409FFF7CC +:104A900040602C0847C80000955992B54091AC0879 +:104AA000408154094094A00440812C08FECD40A1CF +:104AB000F002443007FF4E4200C54C3200EF407315 +:104AC000F0044E5200FB4C3280F34094F0049B25DE +:104AD000504203FF92C14013FC08FF8F92E1402433 +:104AE000C009403388F74014801342508C2440732F +:104AF000C00840034009FFC780079BFDE207E805A7 +:104B00009ED988E9E2E9E8FD402388F742508824ED +:104B10004073C0089631FFC780079BFDE207E80598 +:104B20009E9188E9E2E9E8FD4031C00898DA420147 +:104B3000A069FF8280079BF9E207C60580079FF9FD +:104B4000E903E207E80C9ED988C84003200688E9FB +:104B5000E2E9C0049DF9E903E6E1E8F64C74C00718 +:104B6000802880E684408400D52B4014C00940236F +:104B700084F74004801342F008244073C008405377 +:104B80004009FFEF80A78AEFE2A7E8059E9188E938 +:104B9000E2E9E8FD401384F7425004244073C00862 +:104BA0009631FFC780079BFDE207E8059E4988E92B +:104BB000E2E9E8FD40214008989142012069FF8226 +:104BC00080079BF9E207C60580079FF9E903E20722 +:104BD000E80C9E9188C84003200688E9E2E9C004F9 +:104BE0009DF9E903E6E1E8F6E460E90781E29892DD +:104BF000E24F98DB886F9F21FFF7580100014001C9 +:104C00001C1A80234E470079525207FF4E57004A24 +:104C1000500004005CF00400E804882FE22F888F25 +:104C200040202C0996949A02920B4020D408FE173B +:104C30009449922C40525008FE6F4010A804FCC2C8 +:104C400040F39804E81B40F37C0999FF88EF99B67C +:104C5000CF0580E684C050427FE0420380074E02C9 +:104C6000FF329B20522000204023080D4063000C9F +:104C70004073800CFFD748FFFF26D307CD0440F4D4 +:104C8000A004E807802AFCC24094A0044C9E3FFC8C +:104C9000840044180000FCC2FFF74C7E7FFBD3F970 +:104CA00084004617FF004010A804FCC24094A004F2 +:104CB0004C9E7FF08400D5E740F4A004E8F240F475 +:104CC0007C098929892F89084E930006812885004F +:104CD0005052FFE0420480074E02FEFB9B685220C8 +:104CE00000204024080D4084000C4094800C409427 +:104CF000880448FFFEEE84C0523200015CF180203F +:104D0000E90A80C0800184205031FFE0C0045CF1DA +:104D10008020E81AC310522180204070880C405037 +:104D2000080C40000C0D40108C0DFE3FFFAFC60379 +:104D300058000001500004005CF00400882F40403F +:104D4000FC0948FFFF6F8400D59E92003A6F983CA3 +:104D5000954992B54040AC0840605409FF37403057 +:104D60002C0846680000FF375CF2843EE82152229E +:104D7000843EFAD0E246E9068064848050217FE0D8 +:104D8000CBF9C20B80044031880D4042080D5221FE +:104D900000204000080CFEC7E420E805FF22C30302 +:104DA000FEDA8E81800380243A6F9804DD9EE42031 +:104DB000E90752F287FFE90895A1FF9FC60546481B +:104DC00000008460D5F04647FFFF58420FFF847F04 +:104DD000D5EA92003A6F983C842080A1806180409F +:104DE000C210E440E80746580000FE92C103FE4AA4 +:104DF0008E414430041E424100079ADC4021100CD1 +:104E00004040AC0940615408FF37959192CCFF7740 +:104E10004061D008FF77800480253A6F9804DD9EBA +:104E20004402D6BCDD9E92008060E644E9285441ED +:104E3000800354508003C50B525280049A9599699F +:104E400008408001184180014C12FFFC40511409B8 +:104E5000C50A956D996996A73B00DC043B01DC24EB +:104E60004C12FFFC40510809C50A956A9969968F52 +:104E70003A4090043A4190244C12FFFCC208994AEF +:104E800008408001184180014C12FFFCDD9E920019 +:104E90008060E644E93054518003C50952528004D1 +:104EA0009A959968181180014C32FFFE964840404F +:104EB000A008FE674040C008FE67405114094E52EA +:104EC0000011956D996B96A78201822182418261C2 +:104ED000828182A182C182E13B01DC244C32FFFE4F +:104EE00040510809C508956A996B968F3A11842438 +:104EF0004C32FFFEC206995A181180014C32FFFE57 +:104F0000DD9E92003C0DFB404900100A4900386FBD +:104F1000490041A94900111149006C434403F04A7A +:104F200044100055490041A94900A6144900390B15 +:104F30003C0DFB5444038D404900386F4800015537 +:104F40003C0DFC2849001F9E4900390B4900100AFE +:104F50003C0DFB3F3C1DFB663C1DFB40490038BF40 +:104F600049003C183C1DFB543C0DFB662E07F01F0E +:104F70002E07EC563C0DFB6449006C434420019025 +:104F800048008D0249003A80442000552E07EC6B02 +:104F90003A6F988444300190490014BB4412FEF0EB +:104FA0004402DE5C4413F04A40000009100F800701 +:104FB0002E07EC71490075554900A3502E17EFAA32 +:104FC0004900A2623E07EC7544200180490058C7A1 +:104FD0003C1DFC28100480003C0FFB3F50037F4821 +:104FE000443000554423F04A3C0FFB6349001EE85F +:104FF00049006B3C3C0FFBE340F03C0040310C406F +:105000004900A648440FFFAA490077EB3C0DFB5B23 +:10501000440000552E0010AD2E1FEF0F3E07EC2769 +:105020002E000C1449006A523C0FFB64660000E03D +:105030002E000C344900100E44338D412E07292CCC +:10504000100F800F440000FF54007FFF3C0E030C44 +:105050004900A168580000014200080B00000051FF +:105060001010001C3C0DFFD7109380004900111157 +:10507000120F80033A210C004402C4D04200100BEE +:1050800044000050490077EB3C0BF64D3C0E030BFF +:105090004900147C400080404900A2603C1DFB5840 +:1050A0003C0DFB8E100480014402FF545410FFFF9E +:1050B000020F80034900707D54637FFF3E07EF10AD +:1050C0004402FEF042006C0B4900127B4402E7D818 +:1050D000000480014473F04A3E07E9B844100032EE +:1050E0003C0DFBAD490041B64403000058000004EC +:1050F00066000002449000555800001044131C2024 +:1051000049006EC24900779E640304034402000014 +:10511000490038E549003C183B00E424490058C7E1 +:105120003E07EC6B101000514402FE502E07EC1DA0 +:10513000380780004413F403440365101003005043 +:105140002E001172443000803E07EF6E3C0DFB656F +:105150003C08086C3C0BF6635800000249006D08DF +:1051600049001B104463F04A3E07EF0F2E07EC2F57 +:105170004900812D40F0BC003E07EC12490079FB4C +:105180003E07EC213B0064043C0C041A4900753EC8 +:105190002E07292B540000FE2E0FEF103C0FFB773B +:1051A0003E07EC404462FEF0490034A2440000692E +:1051B0003C0BF8A63C03F64E2E07EF0658000020E5 +:1051C000000500004412FE5044000032502F8007BA +:1051D00066000004021F80004412623840109C36B2 +:1051E000549000FF00048000503F80074800017188 +:1051F000447000552E07EC07480001283E07EF12C7 +:105200003E17EF0F490034A23E000C3450528F007D +:105210003E07EC6D4400007849001B63440373E8CB +:105220002E07EC274200040B490020263C0DFFEE20 +:10523000660000104900649038208008490038BF9B +:105240004413F2483C0DFFD84400004144000043A1 +:105250003E07EC565C0000014422C5144412C3967C +:1052600010030041120F800242000C0B2E07EBFAD4 +:1052700049007E1240310C063E07EC383E07EC2F09 +:10528000440397DE580000082E07EF82490063A30D +:10529000580000802E07F0D8441300003C0BF8A7FC +:1052A0003E07EC5540320D0018128001020F8001BC +:1052B0002E07F09849006EC22E07F1343E17EC38E5 +:1052C00038308A0A501F800F502F800649009F6295 +:1052D00049006F7F2E07EC183C0E030449006EF462 +:1052E00050000FFF2E07EC6446500FFF500F800E4A +:1052F0003C0BF655401004363E07EC853C0BF7B6E8 +:10530000641304023C0BF7AC490039914462FF542A +:105310004900462D2E17F01F49004042443000320C +:105320003C6FFC992E17EC562E07EF723E17EC09D6 +:10533000440262382E07EC4110050000046280161A +:105340004422E8B0020F80004472C7A85CF003E872 +:105350003C0FFBE44412168044134C1040001840EC +:105360003C5DFB4F3C1FFB633E0010DE490087772E +:10537000541080FE3C1DFBB649003A793C13F652AE +:105380004402FEF13C0FFB9B1005800044130FA06C +:1053900049008155400004164413F1C0540000F048 +:1053A0004403F41C4402E318000F8006500F8006EB +:1053B00038078101440397DC540000FD000F800F83 +:1053C0005CF000333C03F65F3E07F0B73E07F0B1F8 +:1053D00049007C5C660000082E07EF5B3C0C030470 +:1053E0004900136C3C0DFECB4900A5EA3C0DFB4F78 +:1053F0003C6FFB9B641324032E07EC374900101A03 +:105400002E0729BE3E07F1342E07289B2E07EF07F3 +:105410004422DD684400004244138D4044000044AF +:10542000420000033E07EC6449007CCF3C1FFB6454 +:105430004900462D400081004413651040100406C9 +:105440003E07EF9F502F800F3C2394624231800330 +:105450000003007D4422E7D84412E7D8000F8007FC +:10546000500F800744038D423C03F6553E07F0E899 +:10547000440000524412D9703C0DFC5849006B3C6A +:10548000001480014900390C490070C64412A50A75 +:105490002E07EC384900228A640308033804860288 +:1054A0003C0FFB7A400320093C0DFFDD0001004268 +:1054B00044400055221080013C0FFB443C0FFB830D +:1054C000120F80003C1FFC9844037A283E07F0D856 +:1054D000120480004403F7CE49001F960302000027 +:1054E0004402C49049001B6349007C7A3C0FFB983E +:1054F0003E07EC672E07EC4C4472C7C03C6FFB3F85 +:105500003C1DFBF54010044040213C080411801470 +:105510000001004649006BE540108C365EF0003318 +:105520001010003C120F800B002F80072E07EC0B91 +:105530002E07EC0D3E07F0E1223080002E07F0B17F +:1055400012030009448000553C3DFB4C10900000C4 +:105550004410004144100043101000523C03F8A6D0 +:10556000405293F53E07EFA73E07EF0644134DA0C8 +:105570003C0E03071003007D121000104900197D36 +:105580004412C3724403F00E4412E380490070FDDC +:1055900049007A003C0DFFE63C03F6502E07EC690B +:1055A0003C0BF65F3E0729BE2E07EC2844038D41D5 +:1055B0003C0FFB6A3B014C00441000A53E07F0E99C +:1055C000441333103C0DFFEF4410004C490070A50C +:1055D0002E07EF803C5DFB584403F7C812030025FB +:1055E0003C1DFB452E07EC743E07EC004412D8C06E +:1055F0004402FE603C0BF64C4413F2492E07EC3398 +:10560000490039313E07EF7E5EF100332E07EF7916 +:105610004412D93849003F443E07EF7A38178400D6 +:10562000520000014412C4083E07EC0B0030000E8B +:10563000101000083E67EF9C49003AE51003004057 +:105640004900642114AF800150000240490087FDE9 +:10565000120F800149000D0549003F393E07F12333 +:10566000490063BA440200003E07EC6049003A0971 +:105670002E07EF7E2E5010AD442000B644000046A9 +:105680004403F08049008D265CF287083E07EC2336 +:10569000120F800A2E07EC574220907349003ACF30 +:1056A000460000F4120300083B0FCC203C1C01C054 +:1056B000490062153E07EF073C0E03083C0DFB59FD +:1056C000490040166600000150108FFF2E372892C7 +:1056D00049008086441FFFAA490070D942028C739A +:1056E0003C0C01BF490070DF10A4800044238D41B1 +:1056F000100F803349001D18490099453C0DFB9B54 +:1057000044037D48000000008492030014940300C9 +:10571000FAAF02008AB10200648F0300F490030024 +:10572000DAAC02006AAE020010330300903F0300BF +:10573000104C03009058030000A2010080AE01004D +:1057400000BB010080C7010010D8010050DE01003D +:1057500090E40100D0EA0100E8730300F87402004D +:10576000A00F03006880030064686A7170737A8117 +:10577000B1A5948873647DA06564676F6F72777C50 +:10578000B5A4938A74647C9F64686A7170737A812B +:10579000B1A5948873647DA06564676F6F72777C30 +:1057A000B5A4938A74647C9F64686A7170737A810B +:1057B000B1A5948873647DA06564676F6F72777C10 +:1057C000B5A4938A74647C9F64686A7170737A81EB +:1057D000B1A5948873647DA06564676F6F72777CF0 +:1057E000B5A4938A74647C9F64686A7170737A81CB +:1057F000B1A5948873647DA06564676F6F72777CD0 +:10580000B5A4938A74647C9F64686A7170737A81AA +:10581000B1A5948873647DA06564676F6F72777CAF +:10582000B5A4938A74647C9F64686A7170737A818A +:10583000B1A5948873647DA06564676F6F72777C8F +:10584000B5A4938A74647C9F64686A7170737A816A +:10585000B1A5948873647DA06564676F6F72777C6F +:10586000B5A4938A74647C9F6564696E6D6E757A65 +:10587000A49A8B806F647B996664696F6D7074798C +:10588000A9978C8270647A986564696E6D6E757A7A +:10589000A49A8B806F647B996664696F6D7074796C +:1058A000A9978C8270647A986564696E6D6E757A5A +:1058B000A49A8B806F647B996664696F6D7074794C +:1058C000A9978C8270647A986564696E6D6E757A3A +:1058D000A49A8B806F647B996664696F6D7074792C +:1058E000A9978C8270647A986564696E6D6E757A1A +:1058F000A49A8B806F647B996664696F6D7074790C +:10590000A9978C8270647A986564696E6D6E757AF9 +:10591000A49A8B806F647B996664696F6D707479EB +:10592000A9978C8270647A986564696E6D6E757AD9 +:10593000A49A8B806F647B996664696F6D707479CB +:10594000A9978C8270647A986564696E6D6E757AB9 +:10595000A49A8B806F647B996664696F6D707479AB +:10596000A9978C8270647A986467686C6E71767798 +:10597000A8988E7E6E647D9F64656B6C707175797E +:10598000AA998A7C70647FA06467686C6E71767770 +:10599000A8988E7E6E647D9F64656B6C707175795E +:1059A000AA998A7C70647FA06467686C6E71767750 +:1059B000A8988E7E6E647D9F64656B6C707175793E +:1059C000AA998A7C70647FA06467686C6E71767730 +:1059D000A8988E7E6E647D9F64656B6C707175791E +:1059E000AA998A7C70647FA06467686C6E71767710 +:1059F000A8988E7E6E647D9F64656B6C70717579FE +:105A0000AA998A7C70647FA06467686C6E717677EF +:105A1000A8988E7E6E647D9F64656B6C70717579DD +:105A2000AA998A7C70647FA06467686C6E717677CF +:105A3000A8988E7E6E647D9F64656B6C70717579BD +:105A4000AA998A7C70647FA06467686C6E717677AF +:105A5000A8988E7E6E647D9F64656B6C707175799D +:105A6000AA998A7C70647FA06467686C6E7176778F +:105A7000A8988E7E6E647D9F64656B6C707175797D +:105A8000AA998A7C70647FA064676B6D74777C7E52 +:105A9000B3A596806E6484A964666D6F73757E7F0E +:105AA000B6A3937F6E6481A764676B6D74777C7E09 +:105AB000B3A596806E6484A964666D6F73757E7FEE +:105AC000B6A3937F6E6481A764676B6D74777C7EE9 +:105AD000B3A596806E6484A964666D6F73757E7FCE +:105AE000B6A3937F6E6481A764676B6D74777C7EC9 +:105AF000B3A596806E6484A964666D6F73757E7FAE +:105B0000B6A3937F6E6481A764676B6D74777C7EA8 +:105B1000B3A596806E6484A964666D6F73757E7F8D +:105B2000B6A3937F6E6481A764676B6D74777C7E88 +:105B3000B3A596806E6484A964666D6F73757E7F6D +:105B4000B6A3937F6E6481A764676B6D74777C7E68 +:105B5000B3A596806E6484A964666D6F73757E7F4D +:105B6000B6A3937F6E6481A764676B6D74777C7E48 +:105B7000B3A596806E6484A964666D6F73757E7F2D +:105B8000B6A3937F6E6481A7646469676E7277774A +:105B9000AA998E756C6482A664656A697371787956 +:105BA000B09C8F77706482A7646469676E72777740 +:105BB000AA998E756C6482A664656A697371787936 +:105BC000B09C8F77706482A7646469676E72777720 +:105BD000AA998E756C6482A664656A697371787916 +:105BE000B09C8F77706482A7646469676E72777700 +:105BF000AA998E756C6482A664656A6973717879F6 +:105C0000B09C8F77706482A7646469676E727777DF +:105C1000AA998E756C6482A664656A6973717879D5 +:105C2000B09C8F77706482A7646469676E727777BF +:105C3000AA998E756C6482A664656A6973717879B5 +:105C4000B09C8F77706482A7646469676E7277779F +:105C5000AA998E756C6482A664656A697371787995 +:105C6000B09C8F77706482A7646469676E7277777F +:105C7000AA998E756C6482A664656A697371787975 +:105C8000B09C8F77706482A764666D6F74777F8035 +:105C9000B19D91786A6483AC64646C6C74757D7D2D +:105CA000B29E8D76696483A964666D6F74777F8018 +:105CB000B19D91786A6483AC64646C6C74757D7D0D +:105CC000B29E8D76696483A964666D6F74777F80F8 +:105CD000B19D91786A6483AC64646C6C74757D7DED +:105CE000B29E8D76696483A964666D6F74777F80D8 +:105CF000B19D91786A6483AC64646C6C74757D7DCD +:105D0000B29E8D76696483A964666D6F74777F80B7 +:105D1000B19D91786A6483AC64646C6C74757D7DAC +:105D2000B29E8D76696483A964666D6F74777F8097 +:105D3000B19D91786A6483AC64646C6C74757D7D8C +:105D4000B29E8D76696483A964666D6F74777F8077 +:105D5000B19D91786A6483AC64646C6C74757D7D6C +:105D6000B29E8D76696483A964666D6F74777F8057 +:105D7000B19D91786A6483AC64646C6C74757D7D4C +:105D8000B29E8D76696483A964666D6F74777F8037 +:105D9000B19D91786A6483AC64646C6C74757D7D2C +:105DA000B29E8D76696483A9727272727272727217 +:105DB00071717171717171717272727272727272CB +:105DC00073737373737373736E6E6E6E6E6E6E6ECB +:105DD00070707070707070706E6E6E6E6E6E6E6ED3 +:105DE0006E6E6E6E6E6E6E6E6B6B6B6B6B6B6B6BEB +:105DF0006A6A6A6A6A6A6A6A6C6C6C6C6C6C6C6CF3 +:105E00006C6C6C6C6C6C6C6C6868686868686868F2 +:105E100069696969696969696B6B6B6B6B6B6B6BE2 +:105E20006A6A6A6A6A6A6A6A6868686868686868E2 +:105E300068686868686868686969696969696969DA +:105E400069696969696969696868686868686868CA +:105E500067676767676767676868686868686868CA +:105E600067676767676767676464646464646464DA +:105E700064646464646464646464646464646464E2 +:105E800064646464646464646464646464646464D2 +:105E900066666666666666666666666666666666A2 +:105EA00067676767676767676F6F6F6F6F6F6F6F42 +:105EB00072727272727272727373737373737373BA +:105EC00074747474747474746F6F6F6F6F6F6F6FBA +:105ED0006D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6DF2 +:105EE0006D6D6D6D6D6D6D6D6B6B6B6B6B6B6B6BF2 +:105EF0006D6D6D6D6D6D6D6D6B6B6B6B6B6B6B6BE2 +:105F00006D6D6D6D6D6D6D6D6B6B6B6B6B6B6B6BD1 +:105F100069696969696969696A6A6A6A6A6A6A6AE9 +:105F20006B6B6B6B6B6B6B6B6969696969696969D1 +:105F30006A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6AC1 +:105F40006A6A6A6A6A6A6A6A6868686868686868C1 +:105F500067676767676767676969696969696969C1 +:105F600066666666666666666565656565656565D9 +:105F700064646464646464646464646464646464E1 +:105F800066666666666666666565656565656565B9 +:105F900064646464646464646565656565656565B9 +:105FA0006464646464646464767676767676767621 +:105FB0007474747474747474767676767676767691 +:105FC0007575757575757575727272727272727299 +:105FD00071717171717171717373737373737373A1 +:105FE0006E6E6E6E6E6E6E6E7272727272727272B1 +:105FF0007171717171717171737373737373737381 +:106000006F6F6F6F6F6F6F6F6E6E6E6E6E6E6E6EA8 +:106010007070707070707070707070707070707080 +:106020006D6D6D6D6D6D6D6D727272727272727278 +:106030007171717171717171727272727272727248 +:106040006F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F60 +:106050006C6C6C6C6C6C6C6C6E6E6E6E6E6E6E6E70 +:106060006E6E6E6E6E6E6E6E6B6B6B6B6B6B6B6B68 +:1060700068686868686868686B6B6B6B6B6B6B6B88 +:106080006D6D6D6D6D6D6D6D6A6A6A6A6A6A6A6A58 +:106090006969696969696969696969696969696970 +:1060A0006666666666666666666666666666666690 +:1060B0006666666666666666676767676767676778 +:1060C00066666666666666666F6F6F6F6F6F6F6F28 +:1060D0006F6F6F6F6F6F6F6F6C6C6C6C6C6C6C6CE8 +:1060E0006E6E6E6E6E6E6E6E7272727272727272B0 +:1060F0007272727272727272707070707070707090 +:1061000071717171717171716F6F6F6F6F6F6F6F8F +:106110006B6B6B6B6B6B6B6B6C6C6C6C6C6C6C6CC7 +:106120006B6B6B6B6B6B6B6B6D6D6D6D6D6D6D6DAF +:106130006D6D6D6D6D6D6D6D6C6C6C6C6C6C6C6C97 +:106140006D6D6D6D6D6D6D6D6B6B6B6B6B6B6B6B8F +:106150006B6B6B6B6B6B6B6B69696969696969699F +:106160006B6B6B6B6B6B6B6B6C6C6C6C6C6C6C6C77 +:106170006B6B6B6B6B6B6B6B69696969696969697F +:106180006868686868686868696969696969696987 +:106190006A6A6A6A6A6A6A6A696969696969696967 +:1061A0006B6B6B6B6B6B6B6B67676767676767675F +:1061B0006767676767676767666666666666666677 +:1061C00067676767676767676E6E6E6E6E6E6E6E27 +:1061D0006E6E6E6E6E6E6E6E7272727272727272BF +:1061E0006F6F6F6F6F6F6F6F6D6D6D6D6D6D6D6DCF +:1061F0006F6F6F6F6F6F6F6F7070707070707070A7 +:106200006F6F6F6F6F6F6F6F6C6C6C6C6C6C6C6CB6 +:106210006D6D6D6D6D6D6D6D6E6E6E6E6E6E6E6EA6 +:106220006B6B6B6B6B6B6B6B6C6C6C6C6C6C6C6CB6 +:106230006D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D8E +:106240006F6F6F6F6F6F6F6F686868686868686896 +:106250006B6B6B6B6B6B6B6B6A6A6A6A6A6A6A6A96 +:1062600068686868686868686666666666666666BE +:10627000696969696969696967676767676767679E +:1062800068686868686868686565656565656565A6 +:1062900064646464646464646666666666666666AE +:1062A000666666666666666666666666666666668E +:1062B000676767676767676767676767676767676E +:1062C00067676767676767677D7D7D7D7D7D7D7DAE +:1062D0007979797979797979787878787878787836 +:1062E000777777777777777777777777777777773E +:1062F0007676767676767676777777777777777736 +:10630000767676767676767676767676767676762D +:10631000767676767676767674747474747474742D +:10632000747474747474747474747474747474742D +:106330007474747474747474737373737373737325 +:106340007272727272727272777777777777777705 +:10635000757575757575757571717171717171710D +:1063600075757575757575757474747474747474E5 +:10637000717171717171717171717171717171710D +:106380006E6E6E6E6E6E6E6E6C6C6C6C6C6C6C6C3D +:1063900069696969696969696C6C6C6C6C6C6C6C55 +:1063A0006A6A6A6A6A6A6A6A6C6C6C6C6C6C6C6C3D +:1063B0006A6A6A6A6A6A6A6A696969696969696945 +:1063C0006A6A6A6A6A6A6A6A68686868686868683D +:1063D000676767676767676765656565656565655D +:1063E0006464646464646464A600A200A700A600F8 +:1063F0009F00A100A2009F009B0098009F009B00AF +:10640000970097009D009900970096009A009700CA +:1064100097009400990095009100900093009000DF +:10642000910093009600940091008C008F008C00E6 +:106430008C008C008C008C008C0087008B00890005 +:106440008A0089008B00880088008500890083000D +:106450008400810083008300840081008400800028 +:1064600083008200830083007E007F0080007B0029 +:106470007F007F0080007C007A007D007C007A0035 +:106480007E007E007E007C007B0079007A007B002D +:106490007700750077007A0076007600750072004C +:1064A00071007200720072006F0070006F00700067 +:1064B00072007300730073006F006C006F006D005A +:1064C0006D006E006F006F006B006C006C006D0063 +:1064D0006C006C006C006A0069006B006C006D0061 +:1064E0006700680069006900640065006700660075 +:1064F000630066006500660062006400630062007D +:1065000062006400620066005F0062005F0060007D +:106510005D0061005D0060005C005C005C005E008E +:106520005D005F005D005F005B005D005A005C0085 +:1065300057005B0059005B0056005B005700590094 +:10654000550059005600580057005A0055005A008F +:1065500055005700550055004F00510051005200A2 +:106560004F0052004F0052004C004F004C004D00B5 +:1065700049004D004B004F008B00900093009D00A0 +:106580009C00A000AA00B300DC00CC00B800A90069 +:106590008E007C009B00C700910090009500A00039 +:1065A000A000A400AB00B200E000CB00B600AB003E +:1065B00090007C009A00C5008300820088008F0054 +:1065C0008E008F0098009F00C200B600A4009700C4 +:1065D000830076009100B50085008300890091005A +:1065E0008F00930098009F00C900B400A7009B0093 +:1065F000850077009100B50078007B007D00810068 +:10660000840087008D008F00BA00A9009E008C00D6 +:106610007A006F008B00B000770078007F00810067 +:10662000850087008B009000BB00A80098008800C0 +:106630007B006E008C00B0006C006F007400760070 +:106640007D00810086008800B800AA009A008400BE +:10665000710067008800AE006D006F007700790060 +:106660007D00800089008A00BB00A800970083009D +:10667000710067008500AC00620062006700650081 +:106680006C00700075007500A30093008800700016 +:10669000680060007D009F00620063006800670082 +:1066A00071006F0076007700A500930086007000EF +:1066B00069005E007A009D00550057005D005E0095 +:1066C000630065006C006D009C008A0080006A0019 +:1066D0005D00580073009700580058005F005F008D +:1066E000660067006E006E009D008B007C006800F5 +:1066F0005C005800730095001A004D008000B30044 +:10670000E6001A014D018001B301E6011A024D02B3 +:106710008002B302E6021A034D038003B303E603CB +:106720001A044D048004B304E6041A054D058005DF +:10673000B305E6051A064D068006B306E6061A07F7 +:106740004D078007B307E6071A084D088008B3080D +:10675000E6081A094D098009B309E6093400320038 +:10676000340032003400340032003400320034008F +:10677000340032003400320034003400320034007F +:10678000320034003400320034003200340034006F +:106790003200340032003400340032003400320061 +:1067A000340034003200340032003400340032004F +:1067B000340032003400340032003400320034003F +:1067C00019004B007D00AF00E10013014501770186 +:1067D000A901DB010D023F027102A302D5020703EA +:1067E00039036B039D03CF0301043304650497044D +:1067F000C904FB042D055F059105C305F5052706B2 +:1068000032003200320032003200320032003200F8 +:1068100032003200320032003200320032003200E8 +:1068200032003200320032003200320032003200D8 +:1068300032003200320032003200320032003200C8 +:106840000808090808090100000100020103020309 +:10685000E8730300F8740200A00F030068800300CF +:1068600010D8010050DE010090E40100D0EA0100E0 +:10687000208E020060940200A09A0200E0A00200B4 +:1068800010330300903F0300104C030090580300A6 +:1068900000090B020F06040D070E0C050801030A80 +:1068A00001020304050600070800000006060606AC +:1068B000060606060600000004050607F20A0B009D +:1068C000BCC20C002B4C0E00AF3009004C5E09001E +:1068D00030790D000A930F00C2E40D000DF504009D +:1068E000433D0300D4B3010050CF0600B3A106001E +:1068F000CF860200F56C00003D1B02000DF5040080 +:10690000F56C00004C5E09002B4C0E0000000000EE +:10691000000000000000000000000000BCC20C00ED +:10692000AF30090030790D00C2E40D000000000016 +:10693000000000000000000000000000D4B30100CF +:10694000433D0300B3A106003D1B02000A930F0064 +:1069500030790D00F20A0B00AF3009000DF504008C +:1069600050CF0600F56C0000CF8602004C5E090097 +:10697000C2E40D002B4C0E00BCC20C003D1B0200FB +:10698000B3A10600433D0300D4B30100AF300900BA +:10699000F20A0B0030790D000A930F00CF86020037 +:1069A000F56C000050CF06000DF50400BCC20C00D1 +:1069B0002B4C0E00C2E40D004C5E0900F20A0B00E5 +:1069C000BCC20C002B4C0E00AF3009004C5E09001D +:1069D00030790D000A930F00C2E40D000202020399 +:1069E000030304040000020003000500070009007F +:1069F0000A000C000E001000110013001500160014 +:106A000018001A001C001D001F0021002200240095 +:106A10002500270029002A002C002D002F0030001F +:106A20003200340035003600380039003B003C00AD +:106A30003E003F0040004200430044004500470044 +:106A4000480049004A004B004D004E004F005000E6 +:106A50005100520053005400550056005700570093 +:106A6000580059005A005B005B005C005D005D004F +:106A70005E005F005F006000600061006100610017 +:106A800062006200620063006300630063006400F0 +:106A9000640064006400640064000000640064003A +:106AA00064006400640064006300630063006300CA +:106AB00062006200620061006100610060006000CD +:106AC0005F005F005E005D005D005C005B005B00DE +:106AD0005A005900580057005700560055005400FE +:106AE00053005200510050004F004E004D004B002B +:106AF0004A00490048004700450044004300420066 +:106B000040003F003E003C003B00390038003600AA +:106B100035003400320030002F002D002C002A00F8 +:106B20002900270025002400220021001F001D004D +:106B30001C001A00180016001500130011001000A8 +:106B40000E000C000A000900070005000300020007 +:106B5000000000000000020003000500070009001B +:106B60000B000C000E00100012001300150017009F +:106B700019001B001D001F00200022002400260019 +:106B800028002A002D002F00310033003500370087 +:106B90003A003C003E0041004300460049004B00E3 +:106BA0004E005100540057005A005D00610064001F +:106BB00068006B006F00730077007B008000850029 +:106BC0008A008F0094009A00A000A600AD00B400D7 +:106BD000BC00C400CD00D600E100EC00F8000501C7 +:106BE00013012201340147015D0175019101B101D9 +:106BF000D601020237027702C8022E03B7037704D8 +:106C000096057407300B6116102700000000010084 +:106C10000400090010001900240031004000510058 +:106C2000640079009000A900C400E1000001210186 +:106C3000440169019001B901E401110240027102AD +:106C4000A402D902100349038403C10300044104D0 +:106C50008404C90410055905A405F10540069106F0 +:106C6000E40639079007E9074408A108000961090B +:106C7000C409290A900AF90A640BD10B400CB10C23 +:106C8000240D990D100E890E040F810F0010811034 +:106C900004118911101299122413B1134014D11444 +:106CA0006415F91590162917C41761180019A11950 +:106CB000441AE91A901B391CE41C911D401EF11E58 +:106CC000A41F00006D006D006E0070007100710067 +:106CD000710000006D006D006B00690068006800C5 +:106CE00067000000000005000A00130019002800DA +:106CF0003C000000000000000038FAFE422EE63F93 +:106D00003067C79357F32E3D010000000000E0BF3D +:106D10005B3051555555D53F9045EBFFFFFFCFBF39 +:106D20001101F124B399C93F9FC806E57555C5BF48 +:106D3000000000000000E0BF775555555555D53F80 +:106D4000CBFDFFFFFFFFCFBF0CDD95999999C93FA0 +:106D5000A74567555555C5BF30DE44A32449C23FFA +:106D6000653D42A4FFFFBFBFCAD62A288471BC3F3D +:106D7000FF68B043EB99B9BF85D0AFF78281B73FC9 +:106D8000CD45D1751352B5BF9FDEE0C3F034F73F58 +:106D90000090E6797FCCD7BF1FE92C6A7813F73FC4 +:106DA00000000DC2EE6FD7BFA0B5FA0860F2F63F43 +:106DB00000E05113E313D7BF7D8C131FA6D1F63F1C +:106DC000007828385BB8D6BFD1B4C50B49B1F63FBF +:106DD00000788090555DD6BFBA0C2F334791F63FAF +:106DE00000001876D002D6BF234222189F71F63FCA +:106DF00000909086CAA8D5BFD91EA5994F52F63FDC +:106E000000500356434FD5BFC4248FAA5633F63FD4 +:106E100000406BC337F6D4BF14DC9D6BB314F63F50 +:106E20000050A8FDA79DD4BF4C5CC65264F6F53F48 +:106E300000A889399245D4BF4F2C91B567D8F53F4A +:106E400000B8B039F4EDD3BFDE905BCBBCBAF53FF0 +:106E500000708F44CE96D3BF781AD9F2619DF53F6A +:106E600000A0BD171E40D3BF875646125680F53F7F +:106E7000008046EFE2E9D2BFD36BE7CE9763F53FE0 +:106E800000E030381B94D2BF937FA7E22547F53F3F +:106E90000088DA8CC53ED2BF83450642FF2AF53F03 +:106EA00000902729E1E9D1BFDFBDB2DB220FF53F1A +:106EB00000F8482B6D95D1BFD7DE34478FF3F43FF0 +:106EC00000F8B99A6741D1BF4028DECF43D8F43FDC +:106ED0000098EF94D0EDD0BFC8A378C03EBDF43F7A +:106EE0000010DB18A59AD0BF8A25E0C37FA2F43F2B +:106EF00000B86352E647D0BF3484D4240588F43FF9 +:106F000000F0864522EBCFBF0B2D191BCE6DF43F51 +:106F100000B017754A47CFBF541839D3D953F43F3F +:106F20000030103D44A4CEBF5A84B444273AF43F05 +:106F300000B0E9440D02CEBFFBF81541B520F43F87 +:106F400000F07729A260CDBFB1F43EDA8207F43FAA +:106F50000090950401C0CCBF8FFE575D8FEEF33FCC +:106F6000001089562920CCBFE94C0BA0D9D5F33F9E +:106F70000010818D1781CBBF2BC110C060BDF33FC6 +:106F800000D0D3CCC9E2CABFB8DA752B24A5F33F31 +:106F90000090122E4045CABF02D09FCD228DF33FF4 +:106FA00000F01D6877A8C9BF1C7A84C55B75F33FE4 +:106FB000003048696D0CC9BFE236AD49CE5DF33F84 +:106FC00000C045A62071C8BF40D44D987946F33F14 +:106FD000003014B48FD6C7BF24CBFFCE5C2FF33F55 +:106FE0000070623CB83CC7BF490DA1757718F33FEC +:106FF0000060379B9AA3C6BF90393E37C801F33F64 +:1070000000A0B754310BC6BF41F895BB4EEBF23F21 +:10701000003024767D73C5BFD1A919020AD5F23F8D +:107020000030C28F7BDCC4BF2AFDB7A8F9BEF23F97 +:107030000000D2512C46C4BFAB1B0C7A1CA9F23FF6 +:10704000000083BC8AB0C3BF30B514607293F23FB6 +:107050000000496B991BC3BFF5A15757FA7DF23F5A +:107060000040A4905487C2BFBF3B1D9BB368F23F52 +:1070700000A079F8B9F3C1BFBDF58F839D53F23FEE +:1070800000A02C25C860C1BF3B08C9AAB73EF23F8B +:107090000020F7577FCEC0BFB640A92B012AF23F90 +:1070A00000A0FE49DC3CC0BF3241CC967915F23FCE +:1070B00000804BBCBD57BFBF9BFCD21D2001F23FDF +:1070C000004040960837BEBF0B484D49F4ECF13FF5 +:1070D0000040F93E9817BDBF69658F52F5D8F13F62 +:1070E00000A0D84E67F9BBBF7C7E571123C5F13F86 +:1070F00000602F2079DCBABFE926CB747CB1F13F68 +:10710000008028E7C3C0B9BFB61A2C0C019EF13F1E +:1071100000C072B346A6B8BFBD70B67BB08AF13F5F +:107120000000ACB3018DB7BFB6BCEF258A77F13F45 +:1071300000003845F174B6BFDA314C358D64F13F4B +:107140000080876D0E5EB5BFDD5F2790B951F13FBE +:1071500000E0A1DE5C48B4BF4CD232A40E3FF13F48 +:1071600000A06A4DD933B3BFDAF910728B2CF13F0E +:107170000060C5F87920B2BF31B5EC28301AF13F74 +:1071800000206298460EB1BFAF3484DAFB07F13FAE +:107190000000D26A6CFAAFBFB36B4E0FEEF5F03F52 +:1071A0000040774A8DDAADBFCE9F2A5D06E4F03FFE +:1071B000000085E4ECBCABBF21A52C6344D2F03FBA +:1071C00000C0124089A1A9BF1A98E27CA7C0F03F75 +:1071D00000C002335888A7BFD136C6832FAFF03F17 +:1071E0000080D6675E71A5BF3913A098DB9DF03F84 +:1071F000008065498A5CA3BFDFE752AFAB8CF03FEC +:1072000000401564E349A1BFFB284E2F9F7BF03F50 +:107210000080EB82C0729EBF198F358CB56AF03F3B +:1072200000805252F1559ABF2CF9ECA5EE59F03F6F +:10723000008081CF623D96BF902CD1CD4949F03F6F +:107240000000AA8CFB2892BFA9ADF0C6C638F03F5B +:107250000000F9207B318CBFA93279136528F03FFB +:107260000000AA5D351984BF4873EA272418F03F4F +:107270000000ECC2031278BF95B114060408F03F79 +:1072800000002479090460BF1AFA26F71FE0EF3FD7 +:1072900000009084F3EF6F3F74EA61C21CA1EF3FDE +:1072A00000003D3541DC873F2E9981B01063EF3FF0 +:1072B0000080C2C4A3CE933FCDADEE3CF625EF3F98 +:1072C00000008914C19F9B3FE7139103C8E9EE3F7B +:1072D000000011CED8B0A13FABB1CB7880AEEE3F6D +:1072E00000C001D05B8AA53F9B0C9DA21A74EE3FA3 +:1072F0000080D840835CA93FB5990A83913AEE3F5C +:10730000008057EF6A27AD3F569A6009E001EE3FD3 +:1073100000C098E59875B03F98BB77E501CAED3F8E +:1073200000200DE3F553B23F03917C0BF292ED3F49 +:107330000000388BDD2EB43FCE5CFB66AC5CED3FCD +:1073400000C057875906B63F9DDE5EAA2C27ED3F49 +:1073500000006A3576DAB73FCD2C6B3E6EF2EC3F1B +:1073600000601C4E43ABB93F0279A7A26DBEEC3F53 +:1073700000600DBBC778BB3F6D08376D268BEC3FB7 +:107380000020E7321343BD3F04585DBD9458EC3FE5 +:107390000060DE71310ABF3F8C9FBB33B526EC3FE6 +:1073A0000040912B1567C03F3FE7ECEE83F5EB3FC4 +:1073B00000B092828547C13FC196DB75FDC4EB3FAB +:1073C0000030CACD6E26C23F284A860C1E95EB3F80 +:1073D0000050C5A6D703C33F2C3EEFC5E265EB3F87 +:1073E0000010333CC3DFC33F8B88C9674837EB3F8E +:1073F00000807A6B36BAC43F4A301D214B09EB3FFF +:1074000000F0D1283993C53F7EEFF285E8DBEA3FF3 +:1074100000F01824CD6AC63FA23D60311DAFEA3F9F +:10742000009066ECF840C73FA758D33FE682EA3F9A +:1074300000F01AF5C015C83F8B7309EF4057EA3FBB +:107440000080F65429E9C83F274BAB902A2CEA3F2D +:107450000040F80236BBC93FD1F29313A001EA3FC6 +:1074600000002C1CED8BCA3F1B3CDB249FD7E93F5F +:1074700000D0015C515BCB3F90B1C70525AEE93F21 +:1074800000C0BCCC6729CC3F2FCE97F22E85E93FB8 +:10749000006048D535F6CC3F754BA4EEBA5CE93FA9 +:1074A00000C04634BDC1CD3F3848E79DC634E93FF2 +:1074B00000E0CFB8018CCE3FE652672F4F0DE93F79 +:1074C000009017C00955CF3F9DD7FF8E52E6E83F89 +:1074D00000B81F126C0ED03F7C00CC9FCEBFE83F9F +:1074E00000D0930EB871D03F0EC3BEDAC099E83F0A +:1074F0000070869E6BD4D03FFB1723AA2774E83F09 +:1075000000D04B338736D13F089AB3AC004FE83FE9 +:10751000004823670D98D13F553E65E8492AE83F6A +:107520000080CCE0FFF8D13F6002F4950106E83F0F +:10753000006863D75F59D23F29A3E06325E2E73FA4 +:1075400000A8140930B9D23FADB5DC77B3BEE73F30 +:10755000006043107218D33FC2259767AA9BE73F8C +:107560000018EC6D2677D33F570617F20779E73FEF +:107570000030AFFB4FD5D33F0C13D6DBCA56E73FE5 +:1075800000E02FE3EE32D43F6BB64F010010E63F30 +:107590003C5B42916C027E3C95B44D030030E63F6B +:1075A000415D0048EABF8D3C78D4940D0050E63F21 +:1075B000B7A5D686A77F8E3CAD6F4E070070E63F1D +:1075C0004C25546BEAFC613CAE0FDFFEFF8FE63FBB +:1075D000FD0E594C277E7CBCBCC5630700B0E63F5E +:1075E00001DADC4868C18ABCF6C15C1E00D0E63F07 +:1075F0001193499D1C3F833C3EF605EBFFEFE63FB0 +:10760000532DE21A04807EBC8097860E0010E73F5F +:107610005279097166FF7B3C12E967FCFF2FE73F57 +:107620002487BD26E2008C3C6A1181DFFF4FE73FD3 +:10763000D201F16E91026EBC909C670F0070E73F23 +:10764000749C54CD71FC67BC35C87EFAFF8FE73F50 +:107650008304F59EC1BE813CE6C220FEFFAFE73F3A +:107660006564CC29177E70BC00C93FEDFFCFE73FB2 +:107670001C8B7B08728080BC761A26E9FFEFE73FFF +:10768000AEF99D6D28C08D3CE8A39C040010E83F36 +:10769000334CE551D27F893C8F2C93170030E83F63 +:1076A00081F330B6E9FE8ABC9C7333060050E83F94 +:1076B000BC35656BBFBF893CC68942200070E83F7E +:1076C000757B11F365BF8BBC0479F5EBFF8FE83F49 +:1076D00057CB3DA26E0089BCDF04BC2200B0E83F5E +:1076E0000A4BE038DF007DBC8A1B0CE5FFCFE83F8A +:1076F000059FFF46710088BC438E91FCFFEFE83F79 +:1077000038707AD07B81833CC75FFA1E0010E93F56 +:1077100003B4DF76913E893CB97B46130030E93FE4 +:107720007602984B4E807F3C6F07EEE6FF4FE93FB5 +:107730002E62FFD9F07E8FBCD1123CDEFF6FE93F95 +:10774000BA382696AA8270BC0D8A45F4FF8FE93FAD +:10775000EFA864911B8087BC3E2E98DDFFAFE93F08 +:1077600037935A8AE04087BC66FB49EDFFCFE93F7B +:1077700000E09BC108CE3F3C519CF12000F0E93F66 +:107780000A5B8827AA3F8ABC06B045110010EA3F71 +:1077900056DA589948FF743CFAF6BB070030EA3FC6 +:1077A000186D2B8AABBE8C3C791D97100050EA3FB8 +:1077B000307978DDCAFE883C482EF51D0070EA3F1E +:1077C000DBABD83D76418FBC5233591C0090EA3F69 +:1077D0001276C28402BF8EBC4B3E4F2A00B0EA3FF5 +:1077E0005F3FFF3C04FD69BCD11EAED7FFCFEA3F2F +:1077F000B4709012E73E82BC780451EEFFEFEA3F8E +:10780000A3DE0EE03E066A3C5B0D65DBFF0FEB3F3F +:10781000B90A1F38C8065A3C57CAAAFEFF2FEB3FC9 +:107820001D3C23741E0179BCDCBA95D9FF4FEB3F98 +:107830009F2A866810FF79BC9C659E240070EB3FF0 +:107840003E4F86D045FF8A3C401687F9FF8FEB3FBD +:10785000F9C3C29677FE7C3C4FCB04D2FFAFEB3F1F +:10786000C42BF2EE27FF63BC455C41D2FFCFEB3F58 +:1078700021EA3BEEB7FF6CBCDF0963F8FFEFEB3F9B +:107880005C0B2E97034181BC5376B5E1FF0FEC3FB3 +:10789000196AB79464C18B3CE357FAF1FF2FEC3FB0 +:1078A000EDC6308DEFFE64BC24E4BFDCFF4FEC3F3F +:1078B0007547ECBC683F84BCF7B954EDFF6FEC3FF3 +:1078C000ECE053F0A37E843CD58F99EBFF8FEC3F27 +:1078D000F192F98D0683733C9A21252100B0EC3F8B +:1078E000040E18648EFD68BC9C4694DDFFCFEC3F0F +:1078F00072EAC71CBE7E8E3C76C4FDEAFFEFEC3F09 +:10790000FE889FAD39BE8E3C2BF89A160010ED3FD5 +:10791000715AB9A8917D753C1DF70F0D0030ED3FF0 +:10792000DAC7706990C1893CC40F79EAFF4FED3F17 +:107930000CFE58C5370E58BCE587DC2E0070ED3FB5 +:10794000440FC14DD6807FBCAA82DC210090ED3F60 +:107950005C5CFD948F7C74BC83026BD8FFAFED3F01 +:107960007E6121C51D7F8C3C39476C2900D0ED3FDD +:1079700053B1FFB29E01883CF59044E5FFEFED3F27 +:1079800089CC52C6D2006E3C94F6ABCDFF0FEE3FD1 +:10799000D2692D2040837FBCDDC852DBFF2FEE3F34 +:1079A00064081BCAC1007B3CEF1642F2FF4FEE3F5A +:1079B00051AB94B0A8FF723C115E8AE8FF6FEE3FB6 +:1079C00059BEEFB173F657BC0DFF9E110090EE3F0C +:1079D00001C80B5E8D8084BC4417A5DFFFAFEE3F6E +:1079E000B52043D50600783CA17F121A00D0EE3FA7 +:1079F000925C5660F80250BCC4BCBA0700F0EE3F7F +:107A000011E6355D444085BC028D7AF5FF0FEF3FEE +:107A10000591EF3931FB4FBCC78AE51E0030EF3FBF +:107A2000551173F2AC818A3C943482F5FF4FEF3FDD +:107A300043C7D7D4413F8A3C6B4CA9FCFF6FEF3F53 +:107A40007578981CF40262BC41C4F9E1FF8FEF3FE6 +:107A50004BE777F4D17D773C7EE3E0D2FFAFEF3F99 +:107A600031A37C9A19016FBC9EE4771C00D0EF3FD4 +:107A7000B1ACCE4BEE81713C31C3E0F7FFEFEF3F8D +:107A80005A87700137056EBC6E6065F4FF0FF03FDA +:107A9000DA0A1C49AD7E8ABC587A86F3FF2FF03F84 +:107AA000E0B2FCC3697F97BC170DFCFDFF4FF03FB0 +:107AB0005B94CB34FEBF973C824DCD030070F03F0A +:107AC000CB56E4C08300823CE8CBF2F9FF8FF03F55 +:107AD0001A7537BEDFFF6DBC65DA0C0100B0F03FF0 +:107AE000EB26E6AE7F3F91BC38D3A40100D0F03F37 +:107AF000F79F4879FA7D803CFDFDDAFAFFEFF03F11 +:107B0000C06BD670050477BC96FDBA0B0010F13F30 +:107B1000620B6D84D4808E3C5DF4E5FAFF2FF13F5B +:107B2000EF36FD64FABF9D3CD99AD50D0050F13F68 +:107B3000AE50127077009A3C9A55210F0070F13FB9 +:107B4000EEDEE3E2F9FD8D3C265427FCFF8FF13F8A +:107B500073723BDC3000913C593C3D1200B0F13F68 +:107B600088010380797F993CB79E29F8FFCFF13FC8 +:107B7000678C9FAB32F965BC00D48AF4FFEFF13F0C +:107B8000EB5BA79DBF7F933CA4868B0C0010F23F5C +:107B9000225BFD916B809F3C034385030030F23FE5 +:107BA00033BF9FEBC2FF933C84F6BCFFFF4FF23F15 +:107BB000722E2E7EE701763CD92129F5FF6FF23F28 +:107BC000610C7F76BBFC7F3C3C3A93140090F23F03 +:107BD0002B41023CCA0272BC1363551400B0F23F41 +:107BE000021FF233828092BC3B52FEEBFFCFF23F8A +:107BF000F2DC4F387EFF88BC96ADB80B00F0F23F48 +:107C0000C541305051FF85BCAFE27AFBFF0FF33F17 +:107C10009D285E88710081BC7F5FACFEFF2FF33F23 +:107C200015B7B73F5DFF91BC5667A60C0050F33FF8 +:107C3000BD828B22827F953C21F7FB110070F33FC0 +:107C4000CCD50DC4BA00803CB92F59F9FF8FF33F52 +:107C500051A7B22D9D3F94BC42D2DD0400B0F33F4A +:107C6000E13876706B7F853C57C9B2F5FFCFF33FA3 +:107C70003112BF103A027A3C18B4B0EAFFEFF33F7A +:107C8000B052B1666D7F983CF4AF32150010F43FEE +:107C90002485195F37F8673C298B47170030F43F7C +:107CA0004351DC72E601833C63B495E7FF4FF43F38 +:107CB0005A89B2B869FF893CE07504E8FF6FF43F68 +:107CC00054F2C29BB1C095BCE7C16FEFFF8FF43F88 +:107CD000722A3AF209409B3C04A7BEE5FFAFF43F8D +:107CE000457D0DBFB7FF94BCDE27101700D0F43FD1 +:107CF0003D6ADC7164C099BCE23EF00F00F0F43FD5 +:107D00001C53850B897F973CD14BDC120010F53F4B +:107D100036A466716504603C7A2705160030F53F8D +:107D2000093223CECEBF96BC4C70DBECFF4FF53F43 +:107D3000D7A10505720289BCA9545FEFFF6FF53F1B +:107D40001264C90EE6BF9B3C1210E6170090F53F87 +:107D500090EFAF81C57E883C923EC90300B0F53FED +:107D6000C00CBF0A08419FBCBC19491D00D0F53F9B +:107D7000294725FB2A8198BC897AB8E7FFEFF53FB0 +:107D80000469ED80B77E94BC000000000000000094 +:107D900000000000000000000000000000000000E3 +:107DA00000000000000000000000000000000000D3 +:107DB00000000000000000000000000000000000C3 +:107DC00000000000000000000000000000000000B3 +:107DD00000000000000000000000000000000000A3 +:107DE0000000000000000000000000000000000093 +:107DF0000000000000000000000000000000000083 +:107E00000000000000000000000000000000000072 +:107E10000000000000000000000000000000000062 +:107E20000000000000000000000000000000000052 +:107E30000000000000000000000000000000000042 +:107E40000000000000000000000000000000000032 +:107E50000000000000000000000000000000000022 +:107E60000000000000000000000000000000000012 +:107E70000000000000000000000000000000000002 +:107E800000000000000000000000000000000000F2 +:107E900000000000000000000000000000000000E2 +:107EA00000000000000000000000000000000000D2 +:107EB00000000000000000000000000000000000C2 +:107EC00000000000000000000000000000000000B2 +:107ED00000000000000000000000000000000000A2 +:107EE0000000000000000000000000000000000092 +:107EF0000000000000000000000000000000000082 +:107F00000000000000000000000000000000000071 +:107F10000000000000000000000000000000000061 +:107F20000000000000000000000000000000000051 +:107F30000000000000000000000000000000000041 +:107F40000000000000000000000000000000000031 +:107F50000000000000000000000000000000000021 +:107F60000000000000000000000000000000000011 +:107F70000000000000000000000000000000000001 +:107F800000000000000000000000000000000000F1 +:107F900000000000000000000000000000000000E1 +:107FA00000000000000000000000000000000000D1 +:107FB00000000000000000000000000000000000C1 +:107FC00000000000000000000000000000000000B1 +:107FD00000000000000000000000000000000000A1 +:107FE0000000000000000000000000000000000091 +:107FF0000000000000000000000000000000000081 +:108000000000000000000000000000000000000070 +:108010000000000000000000000000000000000060 +:108020000000000000000000000000000000000050 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:1080800000000000000000000000000000000000F0 +:1080900000000000000000000000000000000000E0 +:1080A00000000000000000000000000000000000D0 +:1080B00000000000000000000000000000000000C0 +:1080C00000000000000000000000000000000000B0 +:1080D00000000000000000000000000000000000A0 +:1080E0000000000000000000000000000000000090 +:1080F0000000000000000000000000000000000080 +:10810000000000000000000000000000000000006F +:10811000000000000000000000000000000000005F +:10812000000000000000000000000000000000004F +:10813000000000000000000000000000000000003F +:10814000000000000000000000000000000000002F +:10815000000000000000000000000000000000001F +:10816000000000000000000000000000000000000F +:1081700000000000000000000000000000000000FF +:1081800000000000000000000000000000000000EF +:1081900000000000000000000000000000000000DF +:1081A00000000000000000000000000000000000CF +:1081B00000000000000000000000000000000000BF +:1081C00000000000000000000000000000000000AF +:1081D000000000000000000000000000000000009F +:1081E000000000000000000000000000000000008F +:1081F000000000000000000000000000000000007F +:10820000000000000000000000000000000000006E +:10821000000000000000000000000000000000005E +:10822000000000000000000000000000000000004E +:10823000000000000000000000000000000000003E +:10824000000000000000000000000000000000002E +:10825000000000000000000000000000000000001E +:10826000000000000000000000000000000000000E +:1082700000000000000000000000000000000000FE +:1082800000000000000000000000000000000000EE +:1082900000000000000000000000000000000000DE +:1082A00000000000000000000000000000000000CE +:1082B00000000000000000000000000000000000BE +:1082C00000000000000000000000000000000000AE +:1082D000000000000000000000000000000000009E +:1082E000000000000000000000000000000000008E +:1082F000000000000000000000000000000000007E +:10830000000000000000000000000000000000006D +:10831000000000000000000000000000000000005D +:10832000000000000000000000000000000000004D +:10833000000000000000000000000000000000003D +:10834000000000000000000000000000000000002D +:10835000000000000000000000000000000000001D +:10836000000000000000000000000000000000000D +:1083700000000000000000000000000000000000FD +:1083800000000000000000000000000000000000ED +:1083900000000000000000000000000000000000DD +:1083A00000000000000000000000000000000000CD +:1083B00000000000000000000000000000000000BD +:1083C00000000000000000000000000000000000AD +:1083D000000000000000000000000000000000009D +:1083E000000000000000000000000000000000008D +:1083F000000000000000000000000000000000007D +:10840000000000000000000000000000000000006C +:10841000000000000000000000000000000000005C +:10842000000000000000000000000000000000004C +:10843000000000000000000000000000000000003C +:10844000000000000000000000000000000000002C +:10845000000000000000000000000000000000001C +:10846000000000000000000000000000000000000C +:1084700000000000000000000000000000000000FC +:1084800000000000000000000000000000000000EC +:1084900000000000000000000000000000000000DC +:1084A00000000000000000000000000000000000CC +:1084B00000000000000000000000000000000000BC +:1084C00000000000000000000000000000000000AC +:1084D000000000000000000000000000000000009C +:1084E000000000000000000000000000000000008C +:1084F000000000000000000000000000000000007C +:10850000000000000000000000000000000000006B +:10851000000000000000000000000000000000005B +:10852000000000000000000000000000000000004B +:10853000000000000000000000000000000000003B +:10854000000000000000000000000000000000002B +:10855000000000000000000000000000000000001B +:10856000000000000000000000000000000000000B +:1085700000000000000000000000000000000000FB +:1085800000000000000000000000000000000000EB +:1085900000000000000000000000000000000000DB +:1085A00000000000000000000000000000000000CB +:1085B00000000000000000000000000000000000BB +:1085C00000000000000000000000000000000000AB +:1085D000000000000000000000000000000000009B +:1085E000000000000000000000000000000000008B +:1085F000000000000000000000000000000000007B +:10860000000000000000000000000000000000006A +:10861000000000000000000000000000000000005A +:10862000000000000000000000000000000000004A +:10863000000000000000000000000000000000003A +:10864000000000000000000000000000000000002A +:10865000000000000000000000000000000000001A +:10866000000000000000000000000000000000000A +:1086700000000000000000000000000000000000FA +:1086800000000000000000000000000000000000EA +:1086900000000000000000000000000000000000DA +:1086A00000000000000000000000000000000000CA +:1086B00000000000000000000000000000000000BA +:1086C00000000000000000000000000000000000AA +:1086D000000000000000000000000000000000009A +:1086E000000000000000000000000000000000008A +:1086F000000000000000000000000000000000007A +:108700000000000000000000000000000000000069 +:108710000000000000000000000000000000000059 +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:108740000000000000000000000000000000000029 +:108750000000000000000000000000000000000019 +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800000000000000000000000000000000000E9 +:1087900000000000000000000000000000000000D9 +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00000000000000000000000000000000000A9 +:1087D0000000000000000000000000000000000099 +:1087E0000000000000000000000000000000000089 +:1087F0000000000000000000000000000000000079 +:108800000000000000000000000000000000000068 +:108810000000000000000000000000000000000058 +:108820000000000000000000000000000000000048 +:108830000000000000000000000000000000000038 +:108840000000000000000000000000000000000028 +:108850000000000000000000000000000000000018 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800000000000000000000000000000000000E8 +:1088900000000000000000000000000000000000D8 +:1088A00000000000000000000000000000000000C8 +:1088B00000000000000000000000000000000000B8 +:1088C00000000000000000000000000000000000A8 +:1088D0000000000000000000000000000000000098 +:1088E0000000000000000000000000000000000088 +:1088F0000000000000000000000000000000000078 +:108900000000000000000000000000000000000067 +:108910000000000000000000000000000000000057 +:108920000000000000000000000000000000000047 +:108930000000000000000000000000000000000037 +:108940000000000000000000000000000000000027 +:108950000000000000000000000000000000000017 +:108960000000000000000000000000000000000007 +:1089700000000000000000000000000000000000F7 +:1089800000000000000000000000000000000000E7 +:1089900000000000000000000000000000000000D7 +:1089A00000000000000000000000000000000000C7 +:1089B00000000000000000000000000000000000B7 +:1089C00000000000000000000000000000000000A7 +:1089D0000000000000000000000000000000000097 +:1089E0000000000000000000000000000000000087 +:1089F0000000000000000000000000000000000077 +:108A00000000000000000000000000000000000066 +:108A10000000000000000000000000000000000056 +:108A20000000000000000000000000000000000046 +:108A30000000000000000000000000000000000036 +:108A40000000000000000000000000000000000026 +:108A50000000000000000000000000000000000016 +:108A60000000000000000000000000000000000006 +:108A700000000000000000000000000000000000F6 +:108A800000000000000000000000000000000000E6 +:108A900000000000000000000000000000000000D6 +:108AA00000000000000000000000000000000000C6 +:108AB00000000000000000000000000000000000B6 +:108AC00000000000000000000000000000000000A6 +:108AD0000000000000000000000000000000000096 +:108AE0000000000000000000000000000000000086 +:108AF0000000000000000000000000000000000076 +:108B00000000000000000000000000000000000065 +:108B10000000000000000000000000000000000055 +:108B20000000000000000000000000000000000045 +:108B30000000000000000000000000000000000035 +:108B40000000000000000000000000000000000025 +:108B50000000000000000000000000000000000015 +:108B60000000000000000000000000000000000005 +:108B700000000000000000000000000000000000F5 +:108B800000000000000000000000000000000000E5 +:108B900000000000000000000000000000000000D5 +:108BA00000000000000000000000000000000000C5 +:108BB00000000000000000000000000000000000B5 +:108BC00000000000000000000000000000000000A5 +:108BD0000000000000000000000000000000000095 +:108BE0000000000000000000000000000000000085 +:108BF0000000000000000000000000000000000075 +:108C00000000000000000000000000000000000064 +:108C10000000000000000000000000000000000054 +:108C20000000000000000000000000000000000044 +:108C30000000000000000000000000000000000034 +:108C40000000000000000000000000000000000024 +:108C50000000000000000000000000000000000014 +:108C60000000000000000000000000000000000004 +:108C700000000000000000000000000000000000F4 +:108C800000000000000000000000000000000000E4 +:108C900000000000000000000000000000000000D4 +:108CA00000000000000000000000000000000000C4 +:108CB00000000000000000000000000000000000B4 +:108CC00000000000000000000000000000000000A4 +:108CD0000000000000000000000000000000000094 +:108CE0000000000000000000000000000000000084 +:108CF0000000000000000000000000000000000074 +:108D00000000000000000000000000000000000063 +:108D10000000000000000000000000000000000053 +:108D20000000000000000000000000000000000043 +:108D30000000000000000000000000000000000033 +:108D40000000000000000000000000000000000023 +:108D50000000000000000000000000000000000013 +:108D60000000000000000000000000000000000003 +:108D700000000000000000000000000000000000F3 +:108D800000000000000000000000000000000000E3 +:108D900000000000000000000000000000000000D3 +:108DA00000000000000000000000000000000000C3 +:108DB00000000000000000000000000000000000B3 +:108DC00000000000000000000000000000000000A3 +:108DD0000000000000000000000000000000000093 +:108DE0000000000000000000000000000000000083 +:108DF0000000000000000000000000000000000073 +:108E00000000000000000000000000000000000062 +:108E10000000000000000000000000000000000052 +:108E20000000000000000000000000000000000042 +:108E30000000000000000000000000000000000032 +:108E40000000000000000000000000000000000022 +:108E50000000000000000000000000000000000012 +:108E60000000000000000000000000000000000002 +:108E700000000000000000000000000000000000F2 +:108E800000000000000000000000000000000000E2 +:108E900000000000000000000000000000000000D2 +:108EA00000000000000000000000000000000000C2 +:108EB00000000000000000000000000000000000B2 +:108EC00000000000000000000000000000000000A2 +:108ED0000000000000000000000000000000000092 +:108EE0000000000000000000000000000000000082 +:108EF0000000000000000000000000000000000072 +:108F00000000000000000000000000000000000061 +:108F10000000000000000000000000000000000051 +:108F20000000000000000000000000000000000041 +:108F30000000000000000000000000000000000031 +:108F40000000000000000000000000000000000021 +:108F50000000000000000000000000000000000011 +:108F60000000000000000000000000000000000001 +:108F700000000000000000000000000000000000F1 +:108F800000000000000000000000000000000000E1 +:108F900000000000000000000000000000000000D1 +:108FA00000000000000000000000000000000000C1 +:108FB00000000000000000000000000000000000B1 +:108FC00000000000000000000000000000000000A1 +:108FD0000000000000000000000000000000000091 +:108FE0000000000000000000000000000000000081 +:108FF0000000000000000000000000000000000071 +:109000000000000000000000000000000000000060 +:109010000000000000000000000000000000000050 +:109020000000000000000000000000000000000040 +:109030000000000000000000000000000000000030 +:109040000000000000000000000000000000000020 +:109050000000000000000000000000000000000010 +:109060000000000000000000000000000000000000 +:1090700000000000000000000000000000000000F0 +:1090800000000000000000000000000000000000E0 +:1090900000000000000000000000000000000000D0 +:1090A00000000000000000000000000000000000C0 +:1090B00000000000000000000000000000000000B0 +:1090C00000000000000000000000000000000000A0 +:1090D0000000000000000000000000000000000090 +:1090E0000000000000000000000000000000000080 +:1090F0000000000000000000000000000000000070 +:10910000000000000000000000000000000000005F +:10911000000000000000000000000000000000004F +:10912000000000000000000000000000000000003F +:10913000000000000000000000000000000000002F +:10914000000000000000000000000000000000001F +:10915000000000000000000000000000000000000F +:1091600000000000000000000000000000000000FF +:1091700000000000000000000000000000000000EF +:1091800000000000000000000000000000000000DF +:1091900000000000000000000000000000000000CF +:1091A00000000000000000000000000000000000BF +:1091B00000000000000000000000000000000000AF +:1091C000000000000000000000000000000000009F +:1091D000000000000000000000000000000000008F +:1091E000000000000000000000000000000000007F +:1091F000000000000000000000000000000000006F +:10920000000000000000000000000000000000005E +:10921000000000000000000000000000000000004E +:10922000000000000000000000000000000000003E +:10923000000000000000000000000000000000002E +:10924000000000000000000000000000000000001E +:10925000000000000000000000000000000000000E +:1092600000000000000000000000000000000000FE +:1092700000000000000000000000000000000000EE +:1092800000000000000000000000000000000000DE +:1092900000000000000000000000000000000000CE +:1092A00000000000000000000000000000000000BE +:1092B00000000000000000000000000000000000AE +:1092C000000000000000000000000000000000009E +:1092D000000000000000000000000000000000008E +:1092E000000000000000000000000000000000007E +:1092F000000000000000000000000000000000006E +:10930000000000000000000000000000000000005D +:10931000000000000000000000000000000000004D +:10932000000000000000000000000000000000003D +:10933000000000000000000000000000000000002D +:10934000000000000000000000000000000000001D +:10935000000000000000000000000000000000000D +:1093600000000000000000000000000000000000FD +:1093700000000000000000000000000000000000ED +:1093800000000000000000000000000000000000DD +:1093900000000000000000000000000000000000CD +:1093A00000000000000000000000000000000000BD +:1093B00000000000000000000000000000000000AD +:1093C000000000000000000000000000000000009D +:1093D000000000000000000000000000000000008D +:1093E000000000000000000000000000000000007D +:1093F000000000000000000000000000000000006D +:10940000000000000000000000000000000000005C +:10941000000000000000000000000000000000004C +:10942000000000000000000000000000000000003C +:10943000000000000000000000000000000000002C +:10944000000000000000000000000000000000001C +:10945000000000000000000000000000000000000C +:1094600000000000000000000000000000000000FC +:1094700000000000000000000000000000000000EC +:1094800000000000000000000000000000000000DC +:1094900000000000000000000000000000000000CC +:1094A00000000000000000000000000000000000BC +:1094B00000000000000000000000000000000000AC +:1094C000000000000000000000000000000000009C +:1094D000000000000000000000000000000000008C +:1094E000000000000000000000000000000000007C +:1094F000000000000000000000000000000000006C +:10950000000000000000000000000000000000005B +:10951000000000000000000000000000000000004B +:10952000000000000000000000000000000000003B +:10953000000000000000000000000000000000002B +:10954000000000000000000000000000000000001B +:10955000000000000000000000000000000000000B +:1095600000000000000000000000000000000000FB +:1095700000000000000000000000000000000000EB +:1095800000000000000000000000000000000000DB +:1095900000000000000000000000000000000000CB +:1095A00000000000000000000000000000000000BB +:1095B00000000000000000000000000000000000AB +:1095C000000000000000000000000000000000009B +:1095D000000000000000000000000000000000008B +:1095E000000000000000000000000000000000007B +:1095F000000000000000000000000000000000006B +:10960000000000000000000000000000000000005A +:10961000000000000000000000000000000000004A +:10962000000000000000000000000000000000003A +:10963000000000000000000000000000000000002A +:10964000000000000000000000000000000000001A +:10965000000000000000000000000000000000000A +:1096600000000000000000000000000000000000FA +:1096700000000000000000000000000000000000EA +:1096800000000000000000000000000000000000DA +:1096900000000000000000000000000000000000CA +:1096A00000000000000000000000000000000000BA +:1096B00000000000000000000000000000000000AA +:1096C000000000000000000000000000000000009A +:1096D000000000000000000000000000000000008A +:1096E000000000000000000000000000000000007A +:1096F000000000000000000000000000000000006A +:109700000000000000000000000000000000000059 +:109710000000000000000000000000000000000049 +:109720000000000000000000000000000000000039 +:109730000000000000000000000000000000000029 +:109740000000000000000000000000000000000019 +:109750000000000000000000000000000000000009 +:1097600000000000000000000000000000000000F9 +:1097700000000000000000000000000000000000E9 +:1097800000000000000000000000000000000000D9 +:1097900000000000000000000000000000000000C9 +:1097A00000000000000000000000000000000000B9 +:1097B00000000000000000000000000000000000A9 +:1097C0000000000000000000000000000000000099 +:1097D0000000000000000000000000000000000089 +:1097E0000000000000000000000000000000000079 +:1097F0000000000000000000000000000000000069 +:109800000000000000000000000000000000000058 +:109810000000000000000000000000000000000048 +:109820000000000000000000000000000000000038 +:109830000000000000000000000000000000000028 +:109840000000000000000000000000000000000018 +:109850000000000000000000000000000000000008 +:1098600000000000000000000000000000000000F8 +:1098700000000000000000000000000000000000E8 +:1098800000000000000000000000000000000000D8 +:1098900000000000000000000000000000000000C8 +:1098A00000000000000000000000000000000000B8 +:1098B00000000000000000000000000000000000A8 +:1098C0000000000000000000000000000000000098 +:1098D0000000000000000000000000000000000088 +:1098E0000000000000000000000000000000000078 +:1098F0000000000000000000000000000000000068 +:109900000000000000000000000000000000000057 +:109910000000000000000000000000000000000047 +:109920000000000000000000000000000000000037 +:109930000000000000000000000000000000000027 +:109940000000000000000000000000000000000017 +:109950000000000000000000000000000000000007 +:1099600000000000000000000000000000000000F7 +:1099700000000000000000000000000000000000E7 +:1099800000000000000000000000000000000000D7 +:1099900000000000000000000000000000000000C7 +:1099A00000000000000000000000000000000000B7 +:1099B00000000000000000000000000000000000A7 +:1099C0000000000000000000000000000000000097 +:1099D0000000000000000000000000000000000087 +:1099E0000000000000000000000000000000000077 +:1099F0000000000000000000000000000000000067 +:109A00000000000000000000000000000000000056 +:109A10000000000000000000000000000000000046 +:109A20000000000000000000000000000000000036 +:109A30000000000000000000000000000000000026 +:109A40000000000000000000000000000000000016 +:109A50000000000000000000000000000000000006 +:109A600000000000000000000000000000000000F6 +:109A700000000000000000000000000000000000E6 +:109A800000000000000000000000000000000000D6 +:109A900000000000000000000000000000000000C6 +:109AA00000000000000000000000000000000000B6 +:109AB00000000000000000000000000000000000A6 +:109AC0000000000000000000000000000000000096 +:109AD0000000000000000000000000000000000086 +:109AE0000000000000000000000000000000000076 +:109AF0000000000000000000000000000000000066 +:109B00000000000000000000000000000000000055 +:109B10000000000000000000000000000000000045 +:109B20000000000000000000000000000000000035 +:109B30000000000000000000000000000000000025 +:109B40000000000000000000000000000000000015 +:109B50000000000000000000000000000000000005 +:109B600000000000000000000000000000000000F5 +:109B700000000000000000000000000000000000E5 +:109B800000000000000000000000000000000000D5 +:109B900000000000000000000000000000000000C5 +:109BA00000000000000000000000000000000000B5 +:109BB00000000000000000000000000000000000A5 +:109BC0000000000000000000000000000000000095 +:109BD0000000000000000000000000000000000085 +:109BE0000000000000000000000000000000000075 +:109BF0000000000000000000000000000000000065 +:109C00000000000000000000000000000000000054 +:109C10000000000000000000000000000000000044 +:109C20000000000000000000000000000000000034 +:109C30000000000000000000000000000000000024 +:109C40000000000000000000000000000000000014 +:109C50000000000000000000000000000000000004 +:109C600000000000000000000000000000000000F4 +:109C700000000000000000000000000000000000E4 +:109C800000000000000000000000000000000000D4 +:109C900000000000000000000000000000000000C4 +:109CA00000000000000000000000000000000000B4 +:109CB00000000000000000000000000000000000A4 +:109CC0000000000000000000000000000000000094 +:109CD0000000000000000000000000000000000084 +:109CE0000000000000000000000000000000000074 +:109CF0000000000000000000000000000000000064 +:109D00000000000000000000000000000000000053 +:109D10000000000000000000000000000000000043 +:109D20000000000000000000000000000000000033 +:109D30000000000000000000000000000000000023 +:109D40000000000000000000000000000000000013 +:109D50000000000000000000000000000000000003 +:109D600000000000000000000000000000000000F3 +:109D700000000000000000000000000000000000E3 +:109D800000000000000000000000000000000000D3 +:109D900000000000000000000000000000000000C3 +:109DA00000000000000000000000000000000000B3 +:109DB00000000000000000000000000000000000A3 +:109DC0000000000000000000000000000000000093 +:109DD0000000000000000000000000000000000083 +:109DE0000000000000000000000000000000000073 +:109DF0000000000000000000000000000000000063 +:109E00000000000000000000000000000000000052 +:109E10000000000000000000000000000000000042 +:109E20000000000000000000000000000000000032 +:109E30000000000000000000000000000000000022 +:109E40000000000000000000000000000000000012 +:109E50000000000000000000000000000000000002 +:109E600000000000000000000000000000000000F2 +:109E700000000000000000000000000000000000E2 +:109E800000000000000000000000000000000000D2 +:109E900000000000000000000000000000000000C2 +:109EA00000000000000000000000000000000000B2 +:109EB00000000000000000000000000000000000A2 +:109EC0000000000000000000000000000000000092 +:109ED0000000000000000000000000000000000082 +:109EE0000000000000000000000000000000000072 +:109EF0000000000000000000000000000000000062 +:109F00000000000000000000000000000000000051 +:109F10000000000000000000000000000000000041 +:109F20000000000000000000000000000000000031 +:109F30000000000000000000000000000000000021 +:109F40000000000000000000000000000000000011 +:109F50000000000000000000000000000000000001 +:109F600000000000000000000000000000000000F1 +:109F700000000000000000000000000000000000E1 +:109F800000000000000000000000000000000000D1 +:109F900000000000000000000000000000000000C1 +:109FA00000000000000000000000000000000000B1 +:109FB00000000000000000000000000000000000A1 +:109FC0000000000000000000000000000000000091 +:109FD0000000000000000000000000000000000081 +:109FE0000000000000000000000000000000000071 +:109FF0000000000000000000000000000000000061 +:10A000000000000000000000000000000000000050 +:10A010000000000000000000000000000000000040 +:10A020000000000000000000000000000000000030 +:10A030000000000000000000000000000000000020 +:10A040000000000000000000000000000000000010 +:10A050000000000000000000000000000000000000 +:10A0600000000000000000000000000000000000F0 +:10A0700000000000000000000000000000000000E0 +:10A0800000000000000000000000000000000000D0 +:10A0900000000000000000000000000000000000C0 +:10A0A00000000000000000000000000000000000B0 +:10A0B00000000000000000000000000000000000A0 +:10A0C0000000000000000000000000000000000090 +:10A0D0000000000000000000000000000000000080 +:10A0E0000000000000000000000000000000000070 +:10A0F0000000000000000000000000000000000060 +:10A10000000000000000000000000000000000004F +:10A11000000000000000000000000000000000003F +:10A12000000000000000000000000000000000002F +:10A13000000000000000000000000000000000001F +:10A14000000000000000000000000000000000000F +:10A1500000000000000000000000000000000000FF +:10A1600000000000000000000000000000000000EF +:10A1700000000000000000000000000000000000DF +:10A1800000000000000000000000000000000000CF +:10A1900000000000000000000000000000000000BF +:10A1A00000000000000000000000000000000000AF +:10A1B000000000000000000000000000000000009F +:10A1C000000000000000000000000000000000008F +:10A1D000000000000000000000000000000000007F +:10A1E000000000000000000000000000000000006F +:10A1F000000000000000000000000000000000005F +:10A20000000000000000000000000000000000004E +:10A21000000000000000000000000000000000003E +:10A22000000000000000000000000000000000002E +:10A23000000000000000000000000000000000001E +:10A24000000000000000000000000000000000000E +:10A2500000000000000000000000000000000000FE +:10A2600000000000000000000000000000000000EE +:10A2700000000000000000000000000000000000DE +:10A2800000000000000000000000000000000000CE +:10A2900000000000000000000000000000000000BE +:10A2A00000000000000000000000000000000000AE +:10A2B000000000000000000000000000000000009E +:10A2C000000000000000000000000000000000008E +:10A2D000000000000000000000000000000000007E +:10A2E000000000000000000000000000000000006E +:10A2F000000000000000000000000000000000005E +:10A30000000000000000000000000000000000004D +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000000000000000000076 +:10AAE0000000000000000000000000000000000066 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB20000000000000000000000000000000000025 +:10AB30000000000000000000000000000000000015 +:10AB40000000000000000000000000000000000005 +:10AB500000000000000000000000000000000000F5 +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00000000000000000000000000000000000A5 +:10ABB0000000000000000000000000000000000095 +:10ABC0000000000000000000000000000000000085 +:10ABD0000000000000000000000000000000000075 +:10ABE0000000000000000000000000000000000065 +:10ABF0000000000000000000000000000000000055 +:10AC00000000000000000000000000000000000044 +:10AC10000000000000000000000000000000000034 +:10AC20000000000000000000000000000000000024 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF0000000000000000000000000000000000051 +:10B000000000000000000000000000000000000040 +:10B010000000000000000000000000000000000030 +:10B020000000000000000000000000000000000020 +:10B030000000000000000000000000000000000010 +:10B040000000000000000000000000000000000000 +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B0900000000000000000000000000000000000B0 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F000000000000000000000000000000000000000 +:10F0100000000000000000000000000000000000F0 +:10F0200000000000000000000000000000000000E0 +:10F0300000000000000000000000000000000000D0 +:10F0400000000000000000000000000000000000C0 +:10F0500000000000000000000000000000000000B0 +:10F0600000000000000000000000000000000000A0 +:10F070000000000000000000000000000000000090 +:10F080000000000000000000000000000000000080 +:10F090000000000000000000000000000000000070 +:10F0A0000000000000000000000000000000000060 +:10F0B0000000000000000000000000000000000050 +:10F0C0000000000000000000000000000000000040 +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000000000000000000020 +:10F0F0000000000000000000000000000000000010 +:10F1000000000000000000000000000000000000FF +:10F1100000000000000000000000000000000000EF +:10F1200000000000000000000000000000000000DF +:10F1300000000000000000000000000000000000CF +:10F1400000000000000000000000000000000000BF +:10F1500000000000000000000000000000000000AF +:10F16000000000000000000000000000000000009F +:10F17000000000000000000000000000000000008F +:10F18000000000000000000000000000000000007F +:10F19000000000000000000000000000000000006F +:10F1A000000000000000000000000000000000005F +:10F1B000000000000000000000000000000000004F +:10F1C000000000000000000000000000000000003F +:10F1D000000000000000000000000000000000002F +:10F1E000000000000000000000000000000000001F +:10F1F000000000000000000000000000000000000F +:10F2000000000000000000000000000000000000FE +:10F2100000000000000000000000000000000000EE +:10F2200000000000000000000000000000000000DE +:10F2300000000000000000000000000000000000CE +:10F2400000000000000000000000000000000000BE +:10F2500000000000000000000000000000000000AE +:10F26000000000000000000000000000000000009E +:10F27000000000000000000000000000000000008E +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F000000000000000000000000000000000000E +:10F3000000000000000000000000000000000000FD +:10F3100000000000000000000000000000000000ED +:10F3200000000000000000000000000000000000DD +:10F3300000000000000000000000000000000000CD +:10F3400000000000000000000000000000000000BD +:10F3500000000000000000000000000000000000AD +:10F36000000000000000000000000000000000009D +:10F37000000000000000000000000000000000008D +:10F38000000000000000000000000000000000007D +:10F39000000000000000000000000000000000006D +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D000000000000000000000000000000000002D +:10F3E000000000000000000000000000000000001D +:10F3F000000000000000000000000000000000000D +:10F4000000000000000000000000000000000000FC +:10F4100000000000000000000000000000000000EC +:10F4200000000000000000000000000000000000DC +:10F4300000000000000000000000000000000000CC +:10F4400000000000000000000000000000000000BC +:10F4500000000000000000000000000000000000AC +:10F46000000000000000000000000000000000009C +:10F47000000000000000000000000000000000008C +:10F48000000000000000000000000000000000007C +:10F49000000000000000000000000000000000006C +:10F4A000000000000000000000000000000000005C +:10F4B000000000000000000000000000000000004C +:10F4C000000000000000000000000000000000003C +:10F4D000000000000000000000000000000000002C +:10F4E000000000000000000000000000000000001C +:10F4F000000000000000000000000000000000000C +:10F5000000000000000000000000000000000000FB +:10F5100000000000000000000000000000000000EB +:10F5200000000000000000000000000000000000DB +:10F5300000000000000000000000000000000000CB +:10F5400000000000000000000000000000000000BB +:10F5500000000000000000000000000000000000AB +:10F56000000000000000000000000000000000009B +:10F57000000000000000000000000000000000008B +:10F58000000000000000000000000000000000007B +:10F59000000000000000000000000000000000006B +:10F5A000000000000000000000000000000000005B +:10F5B000000000000000000000000000000000004B +:10F5C000000000000000000000000000000000003B +:10F5D000000000000000000000000000000000002B +:10F5E000000000000000000000000000000000001B +:10F5F000000000000000000000000000000000000B +:10F6000000000000000000000000000000000000FA +:10F6100000000000000000000000000000000000EA +:10F6200000000000000000000000000000000000DA +:10F6300000000000000000000000000000000000CA +:10F6400000000000000000000000000000000000BA +:10F6500000000000000000000000000000000000AA +:10F66000000000000000000000000000000000009A +:10F67000000000000000000000000000000000008A +:10F68000000000000000000000000000000000007A +:10F69000000000000000000000000000000000006A +:10F6A000000000000000000000000000000000005A +:10F6B000000000000000000000000000000000004A +:10F6C000000000000000000000000000000000003A +:10F6D000000000000000000000000000000000002A +:10F6E000000000000000000000000000000000001A +:10F6F000000000000000000000000000000000000A +:10F7000000000000000000000000000000000000F9 +:10F7100000000000000000000000000000000000E9 +:10F7200000000000000000000000000000000000D9 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000000000099 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F860000000000000000000000000000000000098 +:10F870000000000000000000000000000000000088 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF0000000000000000000000000000000000001 +:020000022000DC +:1000000000000000000000000000000000000000F0 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:10200000926D20324006000A0E0A000103010810FA +:1020100032004006280A0000000C01000000000009 +:1020200000135359040600000000000000080109D5 +:10203000000132344006000028191A000000080090 +:102040000000080000000800000008000000080070 +:10205000000008000000080000000800F0EF000089 +:10206000000008000000080000000800F0EF000079 +:102070000000080000000800000008000000000048 +:10208000000101000000000000000000000000004E +:10209000000000000000000000000101010101003B +:1020A0000001010000000101010100010000000029 +:1020B0000100000102000000070000000107010309 +:1020C000020314000A0A4000000078003C000000EF +:1020D0000000000000000000000000000000000000 +:1020E0000000000000000000C800C8009600C80002 +:1020F00007078000800005050000000000000000C8 +:1021000006010000000017003900910010001400C3 +:10211000F9FFC4FFFF7FFF7FFF7FFF7FFA002C01E5 +:102120003200C8000A04B4B43232230500000000B3 +:1021300000070D0000320D00000000203232323264 +:1021400032323232323232323232323232320000D3 +:10215000000000000000000000000000000000007F +:102160000A05000A00000000140F001210120000FF +:10217000000000000000000000000000000000005F +:10218000000000000F233246500000006A645046F1 +:102190003C3C3C3C08000000000000000F2332469D +:1021A000500000006A6450463C3C3C3C0F141E2822 +:1021B000000000000A0A0A0A0A0A0A0A0C192D413C +:1021C0005000000046554B4646464646000000007B +:1021D0000A0314005F00F1FF14000F000A00BC02A4 +:1021E00000000000F8FF00007800320064002800C2 +:1021F0000F000F001C023D011C02740400003F068A +:102200000000FF09F40100003F060000FF0932143E +:10221000021E1E32020096003C003C007700C805FA +:10222000770088090000000040063000200001000F +:10223000220000003A00520070008F00AF00CF0073 +:10224000EF000F012E014F016E018E01AD01CE0195 +:10225000EC010F022D024D026D028D02AC02CC0288 +:10226000EB020B032B034A036A038903AA03C90386 +:10227000E703FF0337040000000000000000000037 +:10228000000000000000000000000000000000004E +:10229000000000000000000000000000000000003E +:1022A000000000000000000000000000000000002E +:1022B000000000000000000000000000000000001E +:1022C000000000000000000000000000000000000E +:1022D00000000000000000000000000000000000FE +:1022E00000000000000000000000000000000000EE +:1022F00000000000000000000000280A3000460036 +:102300000100480000003C00430066008500A90071 +:10231000C800E90009012A0149016B018901AB01EB +:10232000C901EB0109022B024A026C028A02AC02CB +:10233000CA02EC020B032D034B036D038B03AE03A8 +:10234000CB03EE030C042F044C046F048B04AF0486 +:10235000CC04EF040D0530054D0570058D05B00565 +:10236000CD05F1050D0630064E0672068E06B10645 +:10237000CE06F2060F073207500773079007B30720 +:10238000D107F40711083408520875089108B108FC +:10239000C608E70800000000000000000000000080 +:1023A000000000000000000000000000000000002D +:1023B000000000000000000000000000000000001D +:1023C000000000000000000000000000000000000D +:1023D0000201200019450000F16C000084D90600BC +:1023E00029B1010010270000C4090000000101010B +:1023F000010102020202014B0F00A00000000000D8 +:102400000100010101010102020202001945000060 +:1024100002000000A46B00000000000014140A0A6F +:102420001400000000000000141414140101010144 +:10243000010040003200E8030F0008000500900092 +:1024400000001E502800B4005000040000000000EE +:10245000B4005000FA00A000000000014F0100008D +:102460000000000068010D0D0A094B004B006400DC +:102470000A003200C800640064000F02E8E8F800B7 +:10248000F8000200190000006A00750081008E004B +:102490009D00AC00BD00CF00E200F7000D01260159 +:1024A00040015C0179019901BC01E00106023002A2 +:1024B0005B028902BA02EE0224035D039A03D90388 +:1024C0001B046004A904F40443059505E9054106CD +:1024D0009C06FA065B07BE0724088D08F808650904 +:1024E000D409450AB80A2D0BA20B190C900C080D43 +:1024F000800DF80D6F0EE60E5C0FD00F4210B3107A +:1025000021118C11F4115912BA1217137013C4133C +:1025100013145D14A114E01418154B1577159C15B0 +:10252000BB15D415E515EF15F31536003D00440035 +:102530004C00560060006B00770085009300A400FB +:10254000B500C900DE00F5000E0129014601650154 +:102550008701AC01D401FE012B025B028F02C6028F +:1025600001033F038003C6030F045D04AE040305AB +:102570005D05BA051B068106EA065707C9073D082F +:10258000B6083109B009320AB70A3E0BC70B520C24 +:10259000DF0C6D0DFC0D8B0E1A0FA80F3610C3103B +:1025A0004D11D6115B12DE125C13D7134D14BD14FE +:1025B00028158D15EC1544169516DE161F1758179D +:1025C0008917B117D117E717F517FA174E005600FC +:1025D00060006B00760083009100A000B100C20093 +:1025E000D600EB0002011A01350152017001910180 +:1025F000B501DB0103022E025C028D02C102F8026A +:1026000032036F03B003F4033B048604D4042605AD +:102610007C05D50532069206F5065C07C607330829 +:10262000A30816098C09040A7E0AFA0A790BF80B2A +:10263000790CFB0C7E0D010E830E060F870F071021 +:10264000861003117D11F5116912DA124713AF13C9 +:1026500013147214CB141E156B15B215F2152C162B +:102660005E168916AC16C716DB16E716EB166A005F +:10267000750081008E009D00AC00BD00CF00E2001F +:10268000F7000D01260140015C0179019901BC01AF +:10269000E001060230025B028902BA02EE02240364 +:1026A0005D039A03D9031B046004A904F4044305E1 +:1026B0009505E90541069C06FA065B07BE07240856 +:1026C0008D08F8086509D409450AB80A2D0BA20B34 +:1026D000190C900C080D800DF80D6F0EE60E5C0FB6 +:1026E000D00F4210B31021118C11F4115912BA12EB +:1026F00017137013C41313145D14A114E0141815E8 +:102700004B1577159C15BB15D415E515EF15F3156D +:102710005500550045004200000000000000000088 +:1027200000000000000000000000000000000000A9 +:102730000000000000000000000000000000000099 +:102740000000000000000000000000000000000089 +:102750000000000000000000000000000000000079 +:102760000000000000000000000000000000000069 +:102770000000000000000000000000000000000059 +:102780000000000000000000000000000000000049 +:102790000000000000000000000000000000000039 +:1027A0000000000000000000000000000000000029 +:1027B0000000000000000000000000000000000019 +:1027C0000000000000000000000000000000000009 +:1027D00000000000000000000000000000000000F9 +:1027E00000000000000000000000000000000000E9 +:1027F00000000000000000000000000000000000D9 +:1028000000000000000000000000000000000000C8 +:1028100000000000000000000000000000000000B8 +:1028200000000000000000000000000000000000A8 +:102830000000000000000000000000000000000098 +:102840000000000000000000000000000000000088 +:102850000000000000000000000000000000000078 +:10286000000000000000000000000000A000D200F6 +:1028700004013C0005000000000000000000000012 +:102880000000000000000000000000000000000048 +:102890000000000000000000000000000000000038 +:1028A0000000000000000000000000000000000028 +:1028B0000000000000000000000000000000000018 +:1028C0000000000000000000000000000000000008 +:1028D00000000000000000000000000000000000F8 +:1028E00000000000000000000000000000000000E8 +:1028F00000000000000000000000000000000000D8 +:1029000000000000000000000000000000000000C7 +:1029100000000000000000000000000000000000B7 +:1029200000000000000000000000000000000000A7 +:102930000000000000000000000000000000000097 +:102940000000000000000000000000000000000087 +:102950000000000000000000000000000000000077 +:102960000000000000000000000000000000000067 +:102970000000000000000000000000000000000057 +:102980000000000000000000000000000000000047 +:102990000000000000000000000000000000000037 +:1029A0000000000000000000000000000000000027 +:1029B0000000000000000000000000000000000017 +:1029C0000000000000000000000000000000000007 +:1029D00000000000000000000000000000000000F7 +:1029E00000000000000000000000000000000000E7 +:1029F00000000000000000000000000000000000D7 +:102A000019010200000000000000000032021092D4 +:102A10000303535900000000000000000000000004 +:102A200099020000BC020000DF0200000203000067 +:102A300025030000480300006B0300008E03000024 +:102A4000B1030000D4030000F70300001A040000E3 +:102A50003D0400006004000083040000A6040000A0 +:102A6000C904000020030000D4B804020351180078 +:102A700007B28C2363200C0485011C0800000000B1 +:102A800000000000190000005B555555555555557F +:102A90005555555505000000080A000010000A00B1 +:102AA000000000010000000002E00000EC045406F9 +:102AB00084067E07410AA2076A099109B1097E17B7 +:102AC00007B8C30700800000208300000080328028 +:102AD000648096802DB4040F110C0F0F10000F139B +:102AE000A5BA830A18C80F0015101510104310431B +:102AF00020030000D4A8040C42330E0EC4338E23EE +:102B000063011911E32101132302000000000000FA +:102B10001B0000005B555555555555555555555598 +:102B20005505000098090B0BB0B00000B0B0001BB9 +:102B30000B00000082F01002EC04540684067E07AD +:102B4000410AA2076A099109B1097E1707B8C307AC +:102B50000080000020830000008032806480968026 +:102B60002DB4040F110C0F0F10000F13A5BA830A18 +:102B700018C80F0015101510104310432003000053 +:102B8000090000000000000000000000000000003C +:102B90000000000000000000000000000100000034 +:102BA0000300000000000000000000000000000022 +:102BB0000200000000000000000000000000000013 +:102BC00000000000EC04540684067E07410AA207B8 +:102BD0006A099109B1097E1707B8C3070080000090 +:102BE0002083000000803280648096802DB4040F22 +:102BF000110C0F0F10000F13A5BA830A18C80F008D +:102C0000151015101043104320030000D4B804021F +:102C10000351180007B28C2363200C0485011C08A3 +:102C20000000000000000000190000005B55555531 +:102C3000555555555555555555000000086A666659 +:102C400036666A66666666636600000002E000003B +:102C5000EC04540684067E07410AA2076A0991091A +:102C6000B1097E1707B8C307008000002083000069 +:102C700000803280648096802DB4040F110C0F0FF9 +:102C800010000F13A5BA830A18C80F0015101510ED +:102C90001043104320030000D4A8040C42330E0E4E +:102CA000C4338E2363011911E321011323020000B1 +:102CB000000000001B0000005B555555555555554B +:102CC000555555555505000098696B6BB6B6666647 +:102CD000B6B6663B6B06000082F01002EC045406A8 +:102CE00084067E07410AA2076A099109B1097E1785 +:102CF00007B8C307008000002083000000803280F6 +:102D0000648096802DB4040F110C0F0F10000F1368 +:102D1000A5BA830A18C80F001510151010431043E8 +:102D200020030000D4B854161796010000000000DC +:102D30000000000000000000000000000000000093 +:102D4000080000005B555555000000000000000021 +:102D500000000000081A111100000000000000002F +:102D60000000000002000000EC04540684067E0708 +:102D7000410AA2076A099109B1097E1707B8C3077A +:102D800000800000208300000080328064809680F4 +:102D90002DB4040F110C0F0F10000F13A5BA830AE6 +:102DA00018C80F0015101510104310432003000021 +:102DB000D4B854161796010000000000000000006F +:102DC00000000000000000000000000008000000FB +:102DD0005B55555500000000000000000000000099 +:102DE000083A33330000000000000000000000003B +:102DF00002000000EC04540684067E07410AA20784 +:102E00006A099109B1097E1707B8C307008000005D +:102E10002083000000803280648096802DB4040FEF +:102E2000110C0F0F10000F13A5BA830A18C80F005A +:102E3000151015101043104320030000D4A8540CA3 +:102E4000567339184F068D11A3344E000000000050 +:102E50000000000000000000130000005B55555505 +:102E600055555555550500000000000008191B1B5D +:102E70001B1B0B0B0B0B00000000000002A002004C +:102E8000EC04540684067E07410AA2076A099109E8 +:102E9000B1097E1707B8C307008000002083000037 +:102EA00000803280648096802DB4040F110C0F0FC7 +:102EB00010000F13A5BA830A18C80F0015101510BB +:102EC0001043104320030000D4A8540C5673391843 +:102ED0004F068D11A3344E000000000000000000DA +:102EE00000000000130000005B5555555555555521 +:102EF000550500000000000008393B3B3B3B0B0B35 +:102F00000B0B00000000000002A00200EC045406BD +:102F100084067E07410AA2076A099109B1097E1752 +:102F200007B8C307008000002083000000803280C3 +:102F3000648096802DB4040F110C0F0F10000F1336 +:102F4000A5BA830A18C80F001510151010431043B6 +:102F500020030000D4A8051B023774045E311A2335 +:102F6000C7088C08000000000000000000000000FE +:102F7000140000005B5555555555555555550000E5 +:102F800000000000080909090909000010000000FC +:102F90000000000002500500EC04540684067E0781 +:102FA000410AA2076A099109B1097E1707B8C30748 +:102FB00000800000208300000080328064809680C2 +:102FC0002DB4040F110C0F0F10000F13A5BA830AB4 +:102FD00018C80F00151015101043104320030000EF +:102FE000D4A8051B023774045E311A23C7088C0865 +:102FF00000000000000000000000000014000000BD +:103000005B55555555555555555500000000000068 +:10301000086969696969606030600000000000004B +:1030200002500500EC04540684067E07410AA207FC +:103030006A099109B1097E1707B8C307008000002B +:103040002083000000803280648096802DB4040FBD +:10305000110C0F0F10000F13A5BA830A18C80F0028 +:10306000151015101043104320030000D4A8551B61 +:10307000167775185E0600000000000000000000D2 +:1030800000000000000000000C0000005B555555DA +:103090005555000000000000000000000819191933 +:1030A00019190000000000000000000002000000EC +:1030B000EC04540684067E07410AA2076A099109B6 +:1030C000B1097E1707B8C307008000002083000005 +:1030D00000803280648096802DB4040F110C0F0F95 +:1030E00010000F13A5BA830A18C80F001510151089 +:1030F0001043104320030000D4A8551B1677751801 +:103100005E0600000000000000000000000000005B +:10311000000000000C0000005B555555555500009F +:10312000000000000000000008393939393900007A +:10313000000000000000000002000000EC04540643 +:1031400084067E07410AA2076A099109B1097E1720 +:1031500007B8C30700800000208300000080328091 +:10316000648096802DB4040F110C0F0F10000F1304 +:10317000A5BA830A18C80F00151015101043104384 +:1031800020030000E3180803446100070800000062 +:10319000000000000000000000000000000000002F +:1031A0000B00000055555555550500000000000066 +:1031B000000000000000000001000000000000000E +:1031C0000000000003000000EC04540684067E07A3 +:1031D000410AA2076A099109B1097E1707B8C30716 +:1031E0000080000020830000008032806480968090 +:1031F0002DB4040F110C0F0F10000F13A5BA830A82 +:1032000018C80F00151015101043104320030000BC +:10321000D4B8000000000000000000000000000022 +:10322000000000000000000000000000030000009B +:103230005B0500000000000000000000000000002E +:10324000080A00000000000000000000000000006C +:1032500002000000EC04540684067E07410AA2071F +:103260006A099109B1097E1707B8C30700800000F9 +:103270002083000000803280648096802DB4040F8B +:10328000110C0F0F10000F13A5BA830A18C80F00F6 +:10329000151015101043104320030000090500000D +:1032A00000000000C002000000000000000000005C +:1032B0000000000000000000020000006466666676 +:1032C00066660000000000000000000082000000B0 +:1032D00000A000000000000000000000FC0700004B +:1032E000EC04540684067E07410AA2076A09910984 +:1032F000B1097E1707B8C3070080000020830000D3 +:1033000000803280648096802DB4040F110C0F0F62 +:1033100010000F13A5BA830A18C80F001510151056 +:103320001043104320030000813010050670200078 +:10333000000000000000000000000000000000008D +:10334000000000000900000055555555050000001B +:10335000000000000000000000000001000000006C +:10336000000000000000000000000000EC04540613 +:1033700084067E07410AA2076A099109B1097E17EE +:1033800007B8C3070080000020830000008032805F +:10339000648096802DB4040F110C0F0F10000F13D2 +:1033A000A5BA830A18C80F00151015101043104352 +:1033B0000000000000000001000003000000FC000D +:1033C000000000000D000D0040065906000000003E +:1033D0000155B400020000000000000001010302DA +:1033E000000001000000FC00000000000D000D00C6 +:1033F00000000F000000000004B0B3000000001047 +:103400000000000002020302000001000000FC00B6 +:10341000000000000D000D0001000E000000000083 +:1034200004C4B30000000010000000000303030206 +:10343000000001000000FC00000000000D000D0075 +:1034400002000D000000000004D8B30000000010CE +:103450000000000004040302000001000000FC0062 +:10346000000000000D000D0003000C000000000033 +:1034700004ECB3000000001000000000050503028A +:10348000000001000000FC00000000000D000D0025 +:1034900004000B00000000000400B4000000001055 +:1034A0000000000006060302000001000000FC000E +:1034B000000000000D000D0005000A0000000000E3 +:1034C0000414B4000000001000000000070703020D +:1034D000000001000000FC00000000000D000D00D5 +:1034E00006000900000000000428B40000000010DD +:1034F0000000000008080302000005000000FC00B6 +:10350000000000000D000D00070008000000000092 +:10351000043CB4000000001000000000090000019D +:10352000000007000000FC00000000000D000D007E +:10353000A00FB90F000000000150B400000000000F +:103540000000000000000001000003000000FC007B +:10355000000000000D000D00C116A81600000000BC +:1035600001A0B400060000000000000000001717D2 +:10357000000003000000FC00000000000D000D0032 +:103580003818391800000000019BB4000400000046 +:103590000000000000001616010003000000FD00FE +:1035A000000000000D000D00681070100000FA25EA +:1035B0000473B400040000000000000000001717AE +:1035C000020003000000FC00000000000D000D00E0 +:1035D000F811F9110000FA250487B4000400000076 +:1035E0000000000000001616030003000000FD00AC +:1035F000000000000D000D00681070100000FA259A +:103600000473B4000400000000000000000017175D +:10361000040003000000FC00000000000D000D008D +:10362000F811F9110000FA250487B4000400000025 +:103630000000000000001616050003000000FD0059 +:10364000000000000D000D00681070100000FA2549 +:103650000473B4000400000000000000000017170D +:10366000060003000000FC00000000000D000D003B +:10367000F811F9110000FA250487B40004000000D5 +:103680000000000000001616070003000000FD0007 +:10369000000000000D000D00681070100000FA25F9 +:1036A0000473B400040000000000000000001717BD +:1036B000080003000000FC00000000000D000D00E9 +:1036C000F811F9110000FA250487B4000400000085 +:1036D00000000000000A1414002802000000FC0092 +:1036E00000000000050005000000000000000000D0 +:1036F000010097030000000000000000000001002E +:10370000002802000000FC00000000000D000D0079 +:103710000000190000000000015AB400020000007F +:103720000000000000000100002802000000FC0072 +:10373000000000000D000D009001A9010000000034 +:10374000015FB40002000000000000000000010062 +:10375000002802000000FC00000000000D000D0029 +:1037600020033903000000000164B40002000000DF +:103770000000000000000100002802000000FC0022 +:10378000000000000D000D00B004C904000000009E +:103790000169B40002000000000000000000010008 +:1037A000002802000000FC00000000000D000D00D9 +:1037B0004006590600000000016EB400020000003F +:1037C0000000000000000100002802000000FC00D2 +:1037D000000000000D000D006810811000000000C6 +:1037E00001A5B40006000000000000000000010078 +:1037F000002802000000FC00000000000D000D0089 +:10380000F81111120000000001AAB4000600000027 +:103810000000000000000100002802000000FC0081 +:10382000000000000D000D008813A113000000002F +:1038300001AFB4000600000000000000000001001D +:10384000002802000000FC00000000000D000D0038 +:10385000181531150000000001B4B4000600000086 +:103860000000000000000100002802000000FC0031 +:10387000000000000D000D00A816C1160000000099 +:1038800001B9B400060000000000000000000100C3 +:10389000002802000000FC000000000009000900F0 +:1038A0000000000000000000010097030600000077 +:1038B00000000000000B1414002802000000FC00AF +:1038C000000000000C000C000000000000000000E0 +:1038D000010097030000000000000000000B14141A +:1038E000002802000000FC003F0000000C000C005B +:1038F000000000000000000001009703000000002D +:1039000000000000000B1515002802000000CC008C +:10391000000000000C000C0000000000000000008F +:1039200001009703000000000000000000000100FB +:10393000002802000000FC00000000000D000D0047 +:1039400000000000000000000100970306000000D6 +:103950004F00000001F4040068931B0060000000A9 +:103960000C000000010004001428000060000000AA +:10397000300000002D008400142800001C0000000E +:10398000730000002DF4840068931B001C000000ED +:10399000700000002DF4840068931B001C000000E0 +:1039A0007300000023F4840068931B001C000000D7 +:1039B000600000002DF4840068931B001C000000D0 +:1039C0004F00000001F4040068931B00E0000100B8 +:1039D0000C0000000100040014280000E0000100B9 +:1039E000300000002D008400142800001C0000009E +:1039F000700000002DF4840068931B001C00000080 +:103A0000730000002DF4840051651B001C000000B1 +:103A1000010128010101010101010101010101016F +:103A20000101010101010101010101010101010186 +:103A30000101010101010101010101010101010176 +:103A40000101010101010101010101010101010166 +:103A50000101010101010101010101010101010156 +:103A60000101010101010101010101010101010146 +:103A70000101010133323C333533353534333534CC +:103A800033333335353434343434323433343433FB +:103A900033333433353333343334333334343434ED +:103AA00033343335353234343233323232333233E5 +:103AB00032323232323132323233323232323232E6 +:103AC00033323132313133323232333233313332D5 +:103AD000323332342F2F303033323C3335333535B7 +:103AE0003433353433333335353434343434333498 +:103AF000333434333333343335333334333433338F +:103B0000343434343334333535323434323333327D +:103B10003233323332323232323232323233323282 +:103B20003232323233323132313133323232333275 +:103B300033313332323332342F2E302F333233336A +:103B40003333333434333534333333353534343439 +:103B5000343433343334343333333433353333342C +:103B6000333433333334343433343335353234331C +:103B70003233323232333233323232323231323223 +:103B80003133323232323232323231323131333217 +:103B90003232333232313232323232332F2E302F10 +:103BA00033323333333333343433353433333335DF +:103BB00035343434343433343334343333333433CA +:103BC00035333334333433333334343433343335BB +:103BD00035323433323333323233323332323232BB +:103BE00032323232323332323232323232323132B5 +:103BF00031323332323233323331333232323233A2 +:103C00002F2E302F32323333333333343433353491 +:103C10003333333535343434343433343333343369 +:103C2000333334333533333433343333333434345C +:103C30003334333534323433323332323233323355 +:103C40003232313232313232313232323232323257 +:103C50003232313131313332323232323331323247 +:103C6000323232332F2E302F323233333333333438 +:103C70003433353433333335353434343434333406 +:103C800033333433333334333533333433343333FE +:103C900033343434333433353532343332333232EF +:103CA00032333233323231323231323232333232F3 +:103CB00032323232323231323131333232323232E6 +:103CC00033313232323232332F2E302F32323333DD +:103CD00033333334343335343333333535343434A8 +:103CE000343433343334343333333433343333349C +:103CF000333433333334343433343335343234338C +:103D00003233323232323233323231323231323293 +:103D10003132323232323232323231323131333286 +:103D20003132323232313232313232332F2E302F81 +:103D3000333233333333333434333534333333354D +:103D40003534343434343334333434333333343338 +:103D5000343333343334333333343434333433352A +:103D6000343234333233323232323233323231322D +:103D70003231323231323232323232323232313226 +:103D80003131333231323232323132323232323315 +:103D90002F2E302F4B4D5351514F4F514F4F534FAB +:103DA000534F4F51534F4E4D53514D4F4F4F534F14 +:103DB0004F4F4F4F514D4F51514F4F4F534F4F4F0B +:103DC00051534F53554F51514F4F4F4D4F514D4FF1 +:103DD0004F4D4D4D4D4D4F4D4F4F4F4F4F4F4D4F01 +:103DE000514D4D4D4D4F4D4D4F4B4F4D51494D4FF9 +:103DF0004F4F4B4F4B494B4B9224922492009200D1 +:103E000000000000B66DB66DB600B6000000000000 +:103E1000B66DB66D9601960100000000B66DB66DE8 +:103E2000B201B20100000000B62DB62DB601B601F8 +:103E300000000000B665B665B601B60100000000DE +:103E4000B66CB66CB601B60100000000966D966DBA +:103E5000B601B60100000000B26DB26DB601B60148 +:103E600000000000FF7FFF7FFF01FF010000000056 +:103E7000B66DB66DB601B601000000009224922422 +:103E800092009200000000000110000000000000FD +:103E900000000000FFFF3DDB38D4FC020200AA0056 +:103EA0006C768A940001060000000000DB0600002A +:103EB000040C000060056E40415639030100009A71 +:103EC000EC045661000000000000000010C40C501B +:103ED0000390BBBB80442278641164118A3989390C +:103EE00085E00FE06612641201100000000000007F +:103EF00000000000FFFF3DDB38D4FC020200AA00F6 +:103F00006C768A940001060000000000DB060000C9 +:103F1000040C000060056E40415639030100009A10 +:103F2000EC045661000000000000000010C40C10FA +:103F3000E39EBBBB80552278641164118A398939AC +:103F400085E00FE06612641201040000000000002A +:103F50000000000000000000000000020200AA00B3 +:103F60006C768A940001060000000000DB06000069 +:103F7000040C000020066E40418639030100009ABF +:103F8000AC058661000000000000000010C40C5069 +:103F90000390BBBB80442278641164118A3989394B +:103FA00085E00FE066126412C904020001020304F6 +:103FB000EAF7FAFD3001A880CF0304021E000003D7 +:103FC0006C768A940001060000000000DB06000009 +:103FD000014600002B1A0040006B39034100029A91 +:103FE00000006B616478792BCF8A00801C54119893 +:103FF0000080BBBB00572278641164118A3989396B +:1040000085F00FF066126412C9040200010101017B +:10401000EAF7FAFD3001A880CF0304020200000095 +:104020006C768A940001060000000000DB060000A8 +:10403000014600002B1A0040006B39034100029A30 +:1040400000006B61BB7DFC17FFFF00801C541198C2 +:104050000380BBBB80462278641164118A39893998 +:1040600085F00FF066126412C90402000202020217 +:10407000EAF7FAFD3001A880CF0304020200000035 +:104080006C768A940001060000000000DB06000048 +:10409000014600002B1A0040006B39034100029AD0 +:1040A00000006B610F7E3416FFFF00801C541198D6 +:1040B0000380BBBB80462278641164118A39893938 +:1040C00085F00FF066126412C904020003030303B3 +:1040D000EAF7FAFD3001A880CF03040202000000D5 +:1040E0006C768A940001060000000000DB060000E8 +:1040F000014600002B1A0040006B39034100029A70 +:1041000000006B61B17E3C12FFFF00801C541198CF +:104110000380BBBB80462278641164118A398939D7 +:1041200085F00FF066126412C9040200040404044E +:10413000EAF7FAFD3001A880CF0304020200000074 +:104140006C768A940001060000000000DB06000087 +:10415000014600002B1A0040006B39034100029A0F +:1041600000006B611C7F0B0FFFFF00801C54119837 +:104170000380BBBB80462278641164118A39893977 +:1041800085F00FF0661264120104000400000000C4 +:10419000CCF57AFDED20BF8FCF03040202060000AC +:1041A0006C768A940001060000000000DB06000027 +:1041B00001060000093C0040006B39034100029AEF +:1041C00000006B616478792BCF8A00801CC41018C2 +:1041D0000380ABAA00C6227864116411803980394B +:1041E0000F000F00550D550DC904020006070A0BFC +:1041F000EAF7FAFD3001A880CF0304021E0600038F +:104200006C768A940001060000000000DB060000C6 +:10421000014600002B1A0040006B39034100029A4E +:1042200000006B616478792BCF8A00801C54119850 +:104230000080BBBB00572218641164118A39893988 +:1042400085F00FF066126412C90402000606060625 +:10425000EAF7FAFD3001A880CF030402020600004D +:104260006C768A940001060000000000DB06000066 +:10427000014600002B1A0040006B39034100029AEE +:1042800000006B616478792BCF8A00801C541198F0 +:104290000080BBBB00572218641164118A39893928 +:1042A00085F00FF066126412C904020006060A0ABD +:1042B00073EDFAFD5985A880CF0304020A060100B8 +:1042C0006C768A940043060100000000DB060000C3 +:1042D000014600002B1A0040006B39034100029A8E +:1042E00000006B619367CBB40000008012541198FA +:1042F0000080BBBB00562218641164118A398939C9 +:1043000085F00FF066126412C904020007070B0B58 +:1043100073EDFAFD5985A880CF0304020A06010057 +:104320006C768A940043060100000000DB06000062 +:10433000014600002B1A0040006B39034100029A2D +:1043400000006B6155737BC8000000801254119807 +:104350000080BBBB00562218641164118A39893968 +:1043600085F00FF066126412C904020009090C0CF2 +:1043700073EDFAFD5985A880CF0304020A060100F7 +:104380006C768A940043060100000000DB06000002 +:10439000014600002B1A0040006B39034100029ACD +:1043A00000006B61D9770ED3000000801254119881 +:1043B0000080BBBB00562218641164118A39893908 +:1043C00085F00FF066126412C90402000A0A06069C +:1043D00073EDFAFD5985A880CF0304020A06010097 +:1043E0006C768A940043060100000000DB060000A2 +:1043F000014600002B1A0040006B39034100029A6D +:1044000000006B61BD7977D80000008012541198CC +:104410000080BBBB00562218641164118A398939A7 +:1044200085F00FF066126412C90402000B0B070737 +:1044300073EDFAFD5985A880CF0304020A06010036 +:104440006C768A940043060100000000DB06000041 +:10445000014600002B1A0040006B39034100029A0C +:1044600000006B61757B34DE0000008012541198EF +:104470000080BBBB00562218641164118A39893947 +:1044800085F00FF066126412C90402000A0A0606DB +:1044900073EDFAFD5985A880CF0304020A060100D6 +:1044A0006C768A940043060100000000DB060000E1 +:1044B000014600002B1A0040006B39034100029AAC +:1044C00000006B61CB7C87E30000008012541198E0 +:1044D0000080BBBB00562218641164118A398939E7 +:1044E00085F00FF066126412C90402000B0B070777 +:1044F00073EDFAFD5985A880CF0304020A06010076 +:104500006C768A940043060100000000DB06000080 +:10451000014600002B1A0040006B39034100029A4B +:1045200000006B61F27D29E90000008012541198AF +:104530000080BBBB00562218641164118A39893986 +:1045400085F00FF066126412C90402000C0C090910 +:1045500073EDFAFD5985A880CF0304020A06010015 +:104560006C768A940043060100000000DB06000020 +:10457000014600002B1A0040006B39034100029AEB +:1045800000006B61D57EC2EE0000008012541198CD +:104590000080BBBB00562218641164118A39893926 +:1045A00085F00FF0661264120000000000000000A9 +:1045B00000101000000056CE00009910100E0006EA +:1045C0000000FDF900006FA1100E00050000464F2D +:1045D000000029A6100F00040000AD8700007DD95F +:1045E000100F00030000C15A00009C9A0004103014 +:1045F0000000BCA00000903800091033000083D0F8 +:104600000000D635000B10350000C9C200001A5951 +:10461000000C103600008CA100002C9F000D1037FC +:1046200000009851000044DC000E10380000BEEA83 +:104630000000A536000E103A000026620000DD9949 +:10464000000F103B00000000B5000000BF0000009C +:10465000DF000000EC00000019010000280100004C +:1046600043010000530100000000000000000000B2 +:10467000000000000000000000000000000000003A +:10468000000000000000000000000000000000002A +:10469000000000000000000000000000000000001A +:1046A000000000000000000000000000000000000A +:1046B00000000000000000000000000000000000FA +:1046C00000000000870700008579385793F930A172 +:1046D000B3D4CC2BCB0AF200000000000000000095 +:1046E00000000000000000000000000000000000CA +:1046F00000000000000000000000000000000000BA +:1047000080220022870700008579385793E4C2B9D8 +:1047100030AFCC2BC5A1B3000000000000000000AA +:104720000000000000000000000000000000000089 +:104730000000000000000000000000000000000079 +:1047400080220022870700008579385793E4C2BC95 +:10475000C2BCD7930D7930000000000000000000BB +:104760000000000000000000000000000000000049 +:104770000000000000000000000000000000000039 +:1047800080220022870700008579385793E4C2BF52 +:10479000930ACC2BC4F50D000000000000000000BF +:1047A0000000000000000000000000000000000009 +:1047B00000000000000000000000000000000000F9 +:1047C00080220022870700008579385793E4C2BF12 +:1047D000930AE4C2B286CF0000000000000000008F +:1047E00000000000000000000000000000000000C9 +:1047F00000000000000000000000000000000000B9 +:1048000080220022870700008579385793E4C2BFD1 +:10481000930AB0AF26CF5000000000000000000057 +:104820000000000000000000000000000000000088 +:104830000000000000000000000000000000000078 +:1048400080220022870700008579385793E4C2BB95 +:104850000AF2E4C2BE4C2B00000000000000000081 +:104860000000000000000000000000000000000048 +:104870000000000000000000000000000000000038 +:1048800080220022870700008579385793E4C2BB55 +:104890000AF2B0AF295E4C000000000000000000EA +:1048A0000000000000000000000000000000000008 +:1048B00000000000000000000000000000000000F8 +:1048C00080220022C8060000450EA63D450EA63DEA +:1048D000BAF15942450EA63D450EA63D450EA63DF0 +:1048E000450EA63D00000000000000000000000092 +:1048F00000000000000000000000000000000000B8 +:104900008022002231302F2E2D2C2B2A29282726D9 +:104910002524232221201F1E1D1C1B1A19181716BF +:104920001514131211100F0E0D0C0B0A09080706AF +:104930000504030201000000000000000000000068 +:104940000000000000000000000000004A49484745 +:10495000464544434241403F3E3D3C3B3A3938376F +:10496000363534333231302F2E2D2C2B2A2928275F +:10497000262524232221201F1E1D1C1B1A1900007E +:104980000000000000000000000000000000000027 +:10499000000000002000E0C0A08060402000E0C0D7 +:1049A000A08060402000E0C0A08060402000E0C007 +:1049B000A08060402000E0C0A08060402000E0C0F7 +:1049C000A08060402000000076DBB62D2449921BB9 +:1049D000DBB6491292942409090000002000E0C0CF +:1049E000A08060402000E0C0A08060402000E0C0C7 +:1049F000A08060402000E0C0A08060402000E0C0B7 +:104A0000A08060402000E0C0A08060402000000046 +:104A100076DBB62D2449921BDBB649129294240909 +:104A2000090000002021E0E1A0A160612021E0E177 +:104A3000A0A160612021E0E1A0A160612021E0E16E +:104A4000A0A160612021E0E1A0A160612021E0E15E +:104A5000A0A160612021000076DBB62D2449921BC5 +:104A6000DBB6491292942409090000000100C1C07C +:104A7000818041400100C1C0818041400100C1C02E +:104A8000818041400100C1C0818041400100C1C01E +:104A9000818041400100C1C081804140010000008F +:104AA00076DBB62D2449921BDBB649129294240979 +:104AB000090000002120E1E0A1A061602120E1E0E7 +:104AC000A1A061602120E1E0A1A061602120E1E0DE +:104AD000A1A061602120E1E0A1A061602120E1E0CE +:104AE000A1A061602120000076DBB62D2449921B35 +:104AF000DBB64912929424090900000063432303A2 +:104B0000E2C2A28262422202E2C2A2826242220285 +:104B1000E2C2A28262422202E2C2A2826242220275 +:104B2000E2C2A28262422202E2C2A2826242000089 +:104B300000D0B62D2D499224DBB66D1292242509A2 +:104B4000490200002C0CECCCAC8C6C4C2C0CECCC4A +:104B5000AC8C6C4C2C0CECCCAC8C6C4C2C0CECCC95 +:104B6000AC8C6C4C2C0CECCCAC8C6C4C2C0CEBCB87 +:104B7000AB8B6B4B2B0B00002D499224DBB66D12D7 +:104B8000922425094902000040DBB62DA484644428 +:104B90002404E3C3A38363432303E3C3A3836343E3 +:104BA0002303E3C3A38363432303E3C3A3836343D5 +:104BB0002303E3C3A38363432303E3C3A38300006B +:104BC0000000B42D6D4B9224E4B66D1B922449096C +:104BD00049920000EBCBAB8B6B4B2B0BEBCBAB8B36 +:104BE0006B4B2B0BEBCBAB8B6B4B2B0BEBCBAB8B15 +:104BF0006B4B2B0BEBCBAB8B6B4B2B0BEACAAA8A09 +:104C00006A4A2A0AEACA00002449921BDBB6491202 +:104C100092942409090000006DDBB624E5C5A58542 +:104C200065452505E4C4A48464442404E4C4A48440 +:104C300064442404E4C4A48464442404E4C4A48434 +:104C400064442404E4C4A48464442404E4C400004C +:104C50000000002D6DDB922424B96D1B9B244912AA +:104C600049922400AA8A6A4A2A0AEACAAA8A6A4A8D +:104C70002A0AEACAAA8A6A4A2A0AEACAAA8A6A4A94 +:104C80002A0AEACAAA8A6A4A2A0AE9C9A98969498A +:104C90002909E9C9A989000024496E1BDB264912AC +:104CA000529224090000002D6DDB92242606E6C6F0 +:104CB000A68666462606E5C5A58565452505E5C59E +:104CC000A58565452505E5C5A58565452505E5C594 +:104CD000A58565452505E5C5A5856545250500002E +:104CE000090000006DDBB62424496E1BDB26491247 +:104CF0005292240969492909E9C9A98969492909F7 +:104D0000E9C9A98969492909E9C9A9896949290913 +:104D1000E9C9A98969492909E8C8A888684828080B +:104D2000E8C8A8886848000024B96D1B9B24491274 +:104D3000499224000000B42D6D4B92246747270749 +:104D4000E7C7A78767472707E6C6A68666462606FB +:104D5000E6C6A68666462606E6C6A68666462606F3 +:104D6000E6C6A68666462606E6C6A686664600000F +:104D70004902000040DBB62D2449921BDBB64912E4 +:104D8000929424092808E8C8A88868482808E8C830 +:104D9000A88868482808E8C8A88868482808E8C893 +:104DA000A88868482808FFFFFFFFFFFFFFFFFFFFFD +:104DB000FFFFFFFFFFFF0000E4B66D1B92244909CF +:104DC0004992000000F0FF3FFFFFFF3FFFFFFFFFA2 +:104DD000FFFFFFFFFFFFFFFFFFFFE7C7A787674753 +:104DE0002707E7C7A78767472707E7C7A787674753 +:104DF0002707E7C7A78767472707E7C7A7870000F1 +:104E0000FFFFFF3FFFDFB62D2D499224DBB66D1269 +:104E100092242509636261605F5E5D5C5B5A59584C +:104E200057565554535251504F4E4D4C4B4A49488A +:104E300047464544434241403F3E3D3C3B3A39387A +:104E40003736353433320000000000000000000027 +:104E500000000000000000000000000031302F2E94 +:104E60002D2C2B2A292827262524232221201F1EEA +:104E70001D1C1B1A191817161514131211100F0EDA +:104E80000D0C0B0A090807060504030201000000C7 +:104E90000000000000000000000000000000000012 +:104EA00000000000FFFFFFFFFFFFFFFFFFFFFFFF0E +:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:104ED000FFFFFFFFFFFF0000FFFFFF3FFFFFFF3F60 +:104EE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFFFF12 +:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:104F0000FFFFFFFFFFFFFFFFFFFF000000000000AB +:104F10000000000000000000000000000000000091 +:104F2000FFFFFF3FFFFFFF3FFFFFFF3F00000000CD +:104F30000000000057473727170756463626160643 +:104F4000554535251505544434241404534333235F +:104F500013035242322212025141312111015040B9 +:104F600030201000FFFF00000000000000000000E3 +:104F700000000000000000000000003F62605E5C76 +:104F80005A58565452504E4C4A48464442403E3C71 +:104F90003A38363432302E2C2A28262422201E1C61 +:104FA0001A18161412100E0C0A080604020000004B +:104FB00000000000000000000000000000000000F1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE00000000000000000000000000000000000C1 +:104FF00000000000000000000000000000000000B1 +:1050000000000000000000000000000000000000A0 +:105010000000000000000000000000000000000090 +:105020000000000000000000000000000000000080 +:105030000000000000000000000000000000000070 +:105040000000000000000000000000000000000060 +:105050000000000000000000000000000000000050 +:105060000000000000000000000000000000000040 +:105070000000000000000000000000000000000030 +:105080000000000000000000000000000000000020 +:105090000000000000000000000000000000000010 +:1050A0000000000000000000000000000000000000 +:1050B00000000000000000000000000000000000F0 +:1050C00000000000000000000000000000000000E0 +:1050D00000000000000000000000000000000000D0 +:1050E00000000000000000000000000000000000C0 +:1050F00000000000000000000000000000000000B0 +:10510000000000000000000000000000000000009F +:10511000000000000000000000000000000000008F +:10512000000000000000000000000000000000007F +:10513000000000000000000000000000000000006F +:10514000000000000000000000000000000000005F +:10515000000000000000000000000000000000004F +:10516000000000000000000000000000000000003F +:10517000000000000000000000000000000000002F +:10518000000000000000000000000000000000001F +:10519000000000000000000000000000000000000F +:1051A00000000000000000000000000000000000FF +:1051B00000000000000000000000000000000000EF +:1051C00000000000000000000000000000000000DF +:1051D00000000000000000000000000000000000CF +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:105200000801010000000000000000003202100050 +:105210001B00000000000000000000000000000073 +:105220008C0C0000AF0C0000D20C0000F50C00004C +:10523000200300004110080344611C080000000026 +:10524000000000000000000000000000000000005E +:105250000A00000066666666560000000000000056 +:10526000000000000000000000000000000000003E +:105270000000000003000000180DD60D060E1F0EE2 +:10528000530F580E300F420F430F7E1707B8C30756 +:1052900000800000208300000080328064809680BF +:1052A0002DB4040F110C0F0F10000F13A5BA030A31 +:1052B00018C80F00151015101043104320030000EC +:1052C000CBB2300DCE0345120000000000000000FC +:1052D0000000000000000000000000000A000000C4 +:1052E00066666666560000000000000000000000D0 +:1052F00011111111111111111111000000000010F4 +:1053000003000000180DD60D060E1F0E530F580E89 +:10531000300F420F430F7E1707B80733008000009D +:105320002083000000803280648096802DB4040FBA +:10533000110C0F0F90000F13A5BA830A18C80F00A5 +:10534000151015101043104345097E1707B8C30701 +:105350000080008020F3000C00803280648096FE84 +:105360002DB4FFFF11FDFFFFD0FF0F13A5BA830A75 +:1053700018C80F00130F130F0F410F411F03000038 +:105380000900000000000000000000000000000014 +:10539000188DD68D068E1F8E538F588E308F428F6C +:1053A000438F0000000000C000000000000000006B +:1053B00002000000000000000000000000000000EB +:1053C00000E60000EC0454E7E4077EE75509A20775 +:1053D0000A09250945097E1707B8C30700800000A0 +:1053E0002083000000803280648096802DB4048F7A +:1053F00011FDFFFFD0FF0F93A5BA830A18E80FE055 +:10540000130F13FF0F410F411F030000D4B8040214 +:105410000351188748F00C0C85011C08188DD68D97 +:10542000068E1F8E538F588E308F428F438F555567 +:10543000555555D55555000000000018086A666698 +:1054400066666666366600270000000002E6008099 +:10545000EC0C54EFE4877EE75509A2070AE925E939 +:105460000000000000000100002802000000FC0015 +:10547000000000000D000D0059064006000000006D +:105480000155970102000000000000000001020227 +:10549000002800008002FC00FFFFFF010D000D004E +:1054A00007000F000000000004B0B300000000106F +:1054B0000000000000020202002800008002FC0040 +:1054C000FFFFFF010D000D0006000E0000000000B0 +:1054D00004C4B3000000001000000000000302023A +:1054E000002800008002FC00FFFFFF010D000D00FE +:1054F00005000D000000000004D8B30000000010FB +:105500000000000000040202002800008002FC00ED +:10551000FFFFFF010D000D0004000C000000000063 +:1055200004ECB300000000100000000000050202BF +:10553000002800008002FC00FFFFFF010D000D00AD +:1055400003000B00000000000400B4000000001085 +:105550000000000000060202002800008002FC009B +:10556000FFFFFF010D000D0002000A000000000017 +:105570000414B40000000010000000000007020244 +:10558000002800008002FC00FFFFFF010D000D005D +:1055900001000900000000000428B4000000001011 +:1055A0000000000000080202002804008002FC0045 +:1055B000FFFFFF010D000D000000080000000000CB +:1055C00020B0B30000000010000000000000000048 +:1055D000002806000000FC00000000000D000D0087 +:1055E000D20FA00F00000000015097010000000042 +:1055F0000000000000000000002802000000FC0085 +:10560000000000000D000D00C116A81600000000EB +:10561000018C97010600000000000000000B020250 +:10562000002800008000FC00000000000D000D00BC +:1056300007000F000000000004B0B30000000010DD +:1056400000000000000C0202002800008000FC00A6 +:10565000000000000D000D0006000E00000000001C +:1056600004C4B3000000001000000000000D02029E +:10567000002800008000FC00000000000D000D006C +:1056800005000D000000000004D8B3000000001069 +:1056900000000000000E0202002800008000FC0054 +:1056A000000000000D000D0004000C0000000000D0 +:1056B00004ECB3000000001000000000000F020224 +:1056C000002800008000FC00000000000D000D001C +:1056D00003000B00000000000400B40000000010F4 +:1056E0000000000000100202002800008000FC0002 +:1056F000000000000D000D0002000A000000000084 +:105700000414B400000000100000000000110202A8 +:10571000002800008000FC00000000000D000D00CB +:1057200001000900000000000428B400000000107F +:105730000000000000120202002804008000FC00AB +:10574000000000000D000D00000008000000000037 +:1057500020B0B300000000104F00000001F404006E +:1057600068931B00600000000C00000001000400B2 +:105770001428000060000000300000002D008400AC +:10578000142800001C000000730000002DF48400A9 +:1057900068931B001C000000700000002DF48400C2 +:1057A00068931B001C000000730000002DF48400AF +:1057B00068931B001C000000630000002DF48400AF +:1057C00068931B001C0000004F00000001F404005F +:1057D00068931B00E00001000C00000001000400C1 +:1057E00014280000E0000100300000002D008400BB +:1057F000142800001C000000700000002DF484003C +:1058000068931B001C000000000000000000000066 +:105810000000000000000000000000000000000088 +:105820000000000000000000000000000000000078 +:105830000000000000000000000000000000000068 +:105840000000000000000000000000000000000058 +:105850000000000000000000000000000000000048 +:105860000000000000000000000000000000000038 +:1058700000000000000000000000000092249224BC +:105880009200920000000000224924492401A40053 +:105890000000000014492449240114010000000004 +:1058A000A4482449240122010000000024452429A1 +:1058B000240124010000000024292445240124019E +:1058C000000000002449A448220124010000000037 +:1058D00024491449140124010000000024492249EC +:1058E000A400240100000000FF7FFF7FFF01FF01F3 +:1058F00000000000B66DB66DB601B60100000000F4 +:10590000B26DB66DB601B60000000000966DB66DC2 +:10591000B601960100000000B66CB66DB601B2018A +:1059200000000000B665B62DB601B601000000000B +:10593000B62DB665B601B60100000000B66DB66CB6 +:10594000B201B60100000000B66D966D9601B60179 +:1059500000000000B66DB26DB600B6010000000098 +:10596000012800000000000000000000000000000E +:10597000000000020206AA006C768A94000106006C +:1059800000000000DB0600000106000091016E40EF +:10599000418C39030100009A1D018C610000000058 +:1059A0000000000010100D100390BBBB8E5A22188F +:1059B000641164118A39893985E00FE06612641236 +:1059C00001200000000000000000000000000000B6 +:1059D000000000020206AA006C768A94000106000C +:1059E00000000000DB0600000106000091016E408F +:1059F000418C39030100009A1D018C6100000000F8 +:105A00000000000010000C100380ABAA8044227834 +:105A1000641164118A39893985E005E066126412DF +:105A20000104000000000000000000000000000071 +:105A3000000000020200AA006C768A9400010600B1 +:105A400000000000DB060000040C000038066E2099 +:105A5000418C390301000084C4058C610000000002 +:105A60000000000010C40C500390BBBB804422789F +:105A7000641164118A39893985E00FE06612641275 +:105A8000D004020001020304CCF57AFDED20BF8FA3 +:105A9000CF0304021E0600036C768A940001060000 +:105AA00000000000DB06000001460000121B002081 +:105AB000006B39034100028400006B616478792B2C +:105AC000CF8A00801C5411980080BBBB00572278FD +:105AD000641164118A39893985E00FE06612641215 +:105AE0000100000001010101CCF57AFDED20BF8F1E +:105AF000CF030402020600006C768A9400010600BF +:105B000000000000DB060000000C0000401A00202E +:105B10004100380341000284000000606478792B62 +:105B2000CF8A00801C5410180380BBBB80462278AB +:105B3000641164118A39893985E00FE066126412B4 +:105B4000D004020002020202CCF57AFDED20BF8FE4 +:105B5000CF030402020600006C768A94000106005E +:105B600000000000DB06000001460000121B0020C0 +:105B7000006B39034100028400006B616478792B6B +:105B8000CF8A00801C5411980380BBBB80462278CA +:105B9000641164118A39893985E00FE06612641254 +:105BA0000100000003030303CCF57AFDED20BF8F55 +:105BB000CF030402020600006C768A9400010600FE +:105BC00000000000DB060000000C0000401A00206E +:105BD0004100380341000284000000606478792BA2 +:105BE000CF8A00801C5410180380BBBB80462278EB +:105BF000641164118A39893985E00FE066126412F4 +:105C0000D004020004040404CCF57AFDED20BF8F1B +:105C1000CF030402020600006C768A94000106009D +:105C200000000000DB06000001460000121B0020FF +:105C3000006B39034100028400006B616478792BAA +:105C4000CF8A00801C5411980380BBBB8046227809 +:105C5000641164118A39893985E00FE06612641293 +:105C60000100000000000000CCF57AFDED20BF8FA0 +:105C7000CF030402020600006C768A94000106003D +:105C800000000000DB060000000C0000FF3B0020CD +:105C90004100380341000284000000606478792BE1 +:105CA000CF8A00801CC410180300000000C62278B0 +:105CB000641164118039803905000F0055105510AA +:105CC000000000000000000000101000000092CD55 +:105CD0000000C180100F0002000087370000BBF1F8 +:105CE000100F00040000904100008B43100E0007CD +:105CF0000000BBF100009167100C000900001DFBC3 +:105D00000000709E100E000500000000C806000094 +:105D1000BAF15942BAF15942450EA63D1122334417 +:105D20005566778899AABBCCDDEEFF6900000000BC +:105D30000000000000000000000000000000000063 +:105D40000000000000000000C022C0224A4948476D +:105D5000464544434241403F3E3D3C3B3A3938375B +:105D6000363534333231302F2E2D2C2B2A2928274B +:105D7000262524232221201F1E1D1C1B1A1900006A +:105D80000000000000000000000000000000000013 +:105D90000000000031302F2E2D2C2B2A29282726F9 +:105DA0002524232221201F1E1D1C1B1A191817161B +:105DB0001514131211100F0E0D0C0B0A090807060B +:105DC00005040302010000000000000000000000C4 +:105DD0000000000000000000000000002000E0C003 +:105DE000A08060402000E0C0A08060402000E0C0B3 +:105DF000A08060402000E0C0A08060402000E0C0A3 +:105E0000A08060402000E0C0A08060402000000032 +:105E100076DBB62D2449921BDBB6491292942409F5 +:105E200009000000826446280AECCEB0927456380D +:105E30001AFCDEC0A28466482A0CEED0B2947658D2 +:105E40003A1CFEE0C2A486684A2C0EF0D2B49678C2 +:105E50005A3C1E00FFFF00006D5B922424B76D1BAF +:105E60009B244912499224010000003F533517F941 +:105E7000DBBD9F8163452709EBCDAF917355371982 +:105E8000FBDDBFA1836547290BEDCFB19375573972 +:105E90001BFDDFC1A38567492B0D8E7052340000B6 +:105EA0006D499224E4B66D1B9224490A499204007C +:105EB0000000B42D2002836547290BEDCFB1937507 +:105EC00057391BFDDFC1A38567492B0DEFD1B39572 +:105ED00077593B1DFFE1C3A587694B2D0FF1D3B562 +:105EE00097795B3D1F01000040DB962424C96D1BA0 +:105EF000DB264912529224090100000016F8DABC90 +:105F00009E8062442608EACCAE9072543618FADCC1 +:105F1000BEA0826446280AECCEB0927456381AFCB1 +:105F2000DEC0A28466482A0C8D6F513315F700003D +:105F300025499224DBB66D129224290949120000EA +:105F400000D0B6255D3F21038466482A0CEED0B20E +:105F50009476583A1CFEE0C2A486684A2C0EF0D211 +:105F6000B496785A3C1E00E2C4A6886A4C2E10F201 +:105F7000D4B6987A5C3E000000D0B6252449721B46 +:105F8000DBB6491292A4240949000000D9BB9D7FC9 +:105F900061432507E9CBAD8F71533517F9DBBD9F01 +:105FA0008163452709EBCDAF9173553719FBDDBFF1 +:105FB000A1836547290B8C6E503214F6D8BA0000C5 +:105FC0002449921BDBB6491292A42409490000001F +:105FD00040DB96249A7C5E4022048567492B0DEFB6 +:105FE000D1B39577593B1DFFE1C3A587694B2D0FB1 +:105FF000F1D3B597795B3D1F01E3C5A7896B4D2FA1 +:1060000011F3D5B7997B00000000B42D2549921CEF +:10601000DBB66D1292242909491200009C7E604271 +:106020002406E8CAAC8E70523416F8DABC9E806240 +:10603000442608EACCAE9072543618FADCBEA08230 +:106040006446280A8B6D4F3113F5D7B99B7D00004C +:1060500024496E1BDB26491292922409010000009C +:106060006D5B9224D7B99B7D5F41230586684A2CDE +:106070000EF0D2B496785A3C1E00E2C4A6886A4C50 +:106080002E10F2D4B6987A5C3E2002E4C6A88A6C40 +:106090004E3012F4D6B800000000002D6D49922455 +:1060A000E4B66D1B9224490A499204005F4123051E +:1060B000E7C9AB8D6F513315F7D9BB9D7F61432580 +:1060C00007E9CBAD8F71533517F9DBBD9F81634570 +:1060D00027098A6C4E3012F4D6B89A7C5E400000D4 +:1060E00024B96D1B9B2449124A9224010000002D03 +:1060F0006D49922414F6D8BA9C7E604224068769C2 +:106100004B2D0FF1D3B597795B3D1F01E3C5A789EF +:106110006B4D2F11F3D5B7997B5D3F2103E5C7A9DF +:106120008B6D4F3113F50000010000006D5B922470 +:1061300024B96D1B9B2449124A9224012204E6C80B +:10614000AA8C6E503214F6D8BA9C7E60422406E8BF +:10615000CAAC8E70523416F8DABC9E8062442608AF +:10616000FFFFFFFFFFFFFFFFFFFFFFFF2103000017 +:10617000E4B66D1B9224490A499204000000FC3FDA +:10618000FFFFFF24513315F7D9BB9D7F61432507DE +:10619000886A4C2E10F2D4B6987A5C3E2002E4C68F +:1061A000A88A6C4E3012F4D6B89A7C5E402204E67F +:1061B000C8AA8C6E503200004900000040DB9624D3 +:1061C00024496E1BDB26491292922409E5C7A98B4C +:1061D0006D4F3113F5D7B99B7D5F412305E7C9ABFF +:1061E0008D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:1061F000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000AD +:10620000DBB66D1292242909C9FFFF3FFFFFFF3F54 +:10621000FFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFF4E +:10622000FFFF896B4D2F11F3D5B7997B5D3FFFFFC2 +:10623000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:10624000FFFFFFFFFFFF0000FFFFFF3FFFDFB6255F +:106250002449FE3FFFFFFF3FFFFFFF3F5F5E5D5CA6 +:106260005B5A595857565554535251504F4E4D4CF6 +:106270004B4A494847464544434241403F3E3D3CE6 +:106280003B3A39383736353433323130FFFF00008E +:1062900000000000000000000000000000000000FE +:1062A0000000003F2F2E2D2C2B2A292827262524BD +:1062B000232221201F1E1D1C1B1A19181716151426 +:1062C000131211100F0E0D0C0B0A09080706050416 +:1062D00003020100FFFF00000000000000000000BA +:1062E00000000000000000000000003F000000006F +:1062F000000000000000000000000000000000009E +:10630000000000000000000000000000000000008D +:10631000000000000000000000000000000000007D +:10632000000000000000000000000000000000006D +:10633000000000000000000000000000000000005D +:10634000000000000000000000000000000000004D +:10635000000000000000000000000000000000003D +:10636000000000000000000000000000000000002D +:10637000000000000000000000000000000000001D +:10638000000000000000000000000000000000000D +:1063900000000000000000000000000000000000FD +:1063A00000000000000000000000000000000000ED +:1063B00000000000000000000000000000000000DD +:1063C00000000000000000000000000000000000CD +:1063D00000000000000000000000000000000000BD +:1063E00000000000000000000000000000000000AD +:1063F000000000000000000000000000000000009D +:10640000000000000000000000000000000000008C +:10641000000000000000000000000000000000007C +:10642000000000000000000000000000000000006C +:10643000000000000000000000000000000000005C +:10644000000000000000000000000000000000004C +:10645000000000000000000000000000000000003C +:10646000000000000000000000000000000000002C +:10647000000000000000000000000000000000001C +:10648000000000000000000000000000000000000C +:1064900000000000000000000000000000000000FC +:1064A00000000000000000000000000000000000EC +:1064B00000000000000000000000000000000000DC +:1064C00000000000000000000000000000000000CC +:1064D00000000000000000000000000000000000BC +:1064E00000000000000000000000000000000000AC +:1064F000000000000000000000000000000000009C +:10650000000000000000000000000000000000008B +:10651000000000000000000000000000000000007B +:10652000000000000000000000000000000000006B +:10653000000000000000000000000000000000005B +:10654000000000000000000000000000000000004B +:10655000000000000000000000000000000000003B +:10656000000000000000000000000000000000002B +:10657000000000000000000000000000000000001B +:10658000000000000000000000000000000000000B +:1065900000000000000000000000000000000000FB +:1065A00000000000000000000000000000000000EB +:1065B00000000000000000000000000000000000DB +:1065C00000000000000000000000000000000000CB +:1065D00000000000000000000000000000000000BB +:1065E00000000000000000000000000000000000AB +:1065F000000000000000000000000000000000009B +:10660000000000000000000000000000000000008A +:10661000000000000000000000000000000000007A +:10662000000000000000000000000000000000006A +:10663000000000000000000000000000000000005A +:10664000000000000000000000000000000000004A +:10665000000000000000000000000000000000003A +:10666000000000000000000000000000000000002A +:10667000000000000000000000000000000000001A +:10668000000000000000000000000000000000000A +:1066900000000000000000000000000000000000FA +:1066A00000000000000000000000000000000000EA +:1066B00000000000000000000000000000000000DA +:1066C00000000000000000000000000000000000CA +:1066D00000000000000000000000000000000000BA +:1066E00000000000000000000000000000000000AA +:1066F000000000000000000000000000000000009A +:106700000000000000000000000000000000000089 +:106710000000000000000000000000000000000079 +:106720000000000000000000000000000000000069 +:106730000000000000000000000000000000000059 +:106740000000000000000000000000000000000049 +:106750000000000000000000000000000000000039 +:106760000000000000000000000000000000000029 +:106770000000000000000000000000000000000019 +:106780000000000000000000000000000000000009 +:1067900000000000000000000000000000000000F9 +:1067A00000000000000000000000000000000000E9 +:1067B00000000000000000000000000000000000D9 +:1067C00000000000000000000000000000000000C9 +:1067D00000000000000000000000000000000000B9 +:1067E00000000000000000000000000000000000A9 +:1067F0000000000000000000000000000000000099 +:106800000000000000000000000000000000000088 +:106810000000000000000000000000000000000078 +:106820000000000000000000000000000000000068 +:106830000000000000000000000000000000000058 +:106840000000000000000000000000000000000048 +:106850000000000000000000000000000000000038 +:106860000000000000000000000000000000000028 +:106870000000000000000000000000000000000018 +:106880000000000000000000000000000000000008 +:1068900000000000000000000000000000000000F8 +:1068A00000000000000000000000000000000000E8 +:1068B00000000000000000000000000000000000D8 +:1068C00000000000000000000000000000000000C8 +:1068D00000000000000000000000000000000000B8 +:1068E00000000000000000000000000000000000A8 +:1068F0000000000000000000000000000000000098 +:106900000000000000000000000000000000000087 +:106910000000000000000000000000000000000077 +:106920000000000000000000000000000000000067 +:106930000000000000000000000000000000000057 +:106940000000000000000000000000000000000047 +:106950000000000000000000000000000000000037 +:106960000000000000000000000000000000000027 +:106970000000000000000000000000000000000017 +:106980000000000000000000000000000000000007 +:1069900000000000000000000000000000000000F7 +:1069A00000000000000000000000000000000000E7 +:1069B00000000000000000000000000000000000D7 +:1069C00000000000000000000000000000000000C7 +:1069D00000000000000000000000000000000000B7 +:1069E00000000000000000000000000000000000A7 +:1069F0000000000000000000000000000000000097 +:106A0000150101000000000000000000320210002B +:106A10001000000000000000000000000000000066 +:106A200099120000BC120000DF12000002130000E7 +:106A300025130000481300006B1300008E130000A4 +:106A4000B1130000D4130000F71300001A14000063 +:106A50003D1400006014000083140000A614000020 +:106A6000C914000020030000D4B804020351180028 +:106A700007B28C2363200C0485011C080000000071 +:106A800000000000190000005B555555555555553F +:106A90005555555505000000080A000010000A0071 +:106AA000000000010000000002E00000EC14541699 +:106AB00084167E17411AA2176A199119B1197E1707 +:106AC00007B8C307008000002083000000803280E8 +:106AD000648096802DB4040F110C0F0F10000F135B +:106AE000A5BA830A18C80F001510151010431043DB +:106AF00020030000D4A8040C42330E0EC4338E23AE +:106B000063011911E32101132302000000000000BA +:106B10001B0000005B555555555555555555555558 +:106B20005505000098090B0BB0B00000B0B0001B79 +:106B30000B00000082F01002EC14541684167E172D +:106B4000411AA2176A199119B1197E1707B8C3071C +:106B500000800000208300000080328064809680E6 +:106B60002DB4040F110C0F0F10000F13A5BA830AD8 +:106B700018C80F0015101510104310432003000013 +:106B800009000000000000000000000000000000FC +:106B900000000000000000000000000001000000F4 +:106BA00003000000000000000000000000000000E2 +:106BB00002000000000000000000000000000000D3 +:106BC00000000000EC14541684167E17411AA21718 +:106BD0006A199119B1197E1707B8C3070080000020 +:106BE0002083000000803280648096802DB4040FE2 +:106BF000110C0F0F10000F13A5BA830A18C80F004D +:106C0000151015101043104320030000D4B80402DF +:106C10000351180007B28C2363200C0485011C0863 +:106C20000000000000000000190000005B555555F1 +:106C3000555555555555555555000000086A666619 +:106C400036666A66666666636600000002E00000FB +:106C5000EC14541684167E17411AA2176A1991195A +:106C6000B1197E1707B8C307008000002083000019 +:106C700000803280648096802DB4040F110C0F0FB9 +:106C800010000F13A5BA830A18C80F0015101510AD +:106C90001043104320030000D4A8040C42330E0E0E +:106CA000C4338E2363011911E32101132302000071 +:106CB000000000001B0000005B555555555555550B +:106CC000555555555505000098696B6BB6B6666607 +:106CD000B6B6663B6B06000082F01002EC14541648 +:106CE00084167E17411AA2176A199119B1197E17D5 +:106CF00007B8C307008000002083000000803280B6 +:106D0000648096802DB4040F110C0F0F10000F1328 +:106D1000A5BA830A18C80F001510151010431043A8 +:106D200020030000D4B8541617960100000000009C +:106D30000000000000000000000000000000000053 +:106D4000080000005B5555550000000000000000E1 +:106D500000000000081A11110000000000000000EF +:106D60000000000002000000EC14541684167E1788 +:106D7000411AA2176A199119B1197E1707B8C307EA +:106D800000800000208300000080328064809680B4 +:106D90002DB4040F110C0F0F10000F13A5BA830AA6 +:106DA00018C80F00151015101043104320030000E1 +:106DB000D4B854161796010000000000000000002F +:106DC00000000000000000000000000008000000BB +:106DD0005B55555500000000000000000000000059 +:106DE000083A3333000000000000000000000000FB +:106DF00002000000EC14541684167E17411AA217E4 +:106E00006A199119B1197E1707B8C30700800000ED +:106E10002083000000803280648096802DB4040FAF +:106E2000110C0F0F10000F13A5BA830A18C80F001A +:106E3000151015101043104320030000D4A8540C63 +:106E4000567339184F068D11A3344E000000000010 +:106E50000000000000000000130000005B555555C5 +:106E600055555555550500000000000008191B1B1D +:106E70001B1B0B0B0B0B00000000000002A002000C +:106E8000EC14541684167E17411AA2176A19911928 +:106E9000B1197E1707B8C3070080000020830000E7 +:106EA00000803280648096802DB4040F110C0F0F87 +:106EB00010000F13A5BA830A18C80F00151015107B +:106EC0001043104320030000D4A8540C5673391803 +:106ED0004F068D11A3344E0000000000000000009A +:106EE00000000000130000005B55555555555555E1 +:106EF000550500000000000008393B3B3B3B0B0BF5 +:106F00000B0B00000000000002A00200EC1454165D +:106F100084167E17411AA2176A199119B1197E17A2 +:106F200007B8C30700800000208300000080328083 +:106F3000648096802DB4040F110C0F0F10000F13F6 +:106F4000A5BA830A18C80F00151015101043104376 +:106F500020030000D4A8051B023774045E311A23F5 +:106F6000C7088C08000000000000000000000000BE +:106F7000140000005B5555555555555555550000A5 +:106F800000000000080909090909000010000000BC +:106F90000000000002500500EC14541684167E1701 +:106FA000411AA2176A199119B1197E1707B8C307B8 +:106FB0000080000020830000008032806480968082 +:106FC0002DB4040F110C0F0F10000F13A5BA830A74 +:106FD00018C80F00151015101043104320030000AF +:106FE000D4A8051B023774045E311A23C7088C0825 +:106FF000000000000000000000000000140000007D +:107000005B55555555555555555500000000000028 +:10701000086969696969606030600000000000000B +:1070200002500500EC14541684167E17411AA2175C +:107030006A199119B1197E1707B8C30700800000BB +:107040002083000000803280648096802DB4040F7D +:10705000110C0F0F10000F13A5BA830A18C80F00E8 +:10706000151015101043104320030000D4A8551B21 +:10707000167775185E060000000000000000000092 +:1070800000000000000000000C0000005B5555559A +:1070900055550000000000000000000008191919F3 +:1070A00019190000000000000000000002000000AC +:1070B000EC14541684167E17411AA2176A199119F6 +:1070C000B1197E1707B8C3070080000020830000B5 +:1070D00000803280648096802DB4040F110C0F0F55 +:1070E00010000F13A5BA830A18C80F001510151049 +:1070F0001043104320030000D4A8551B16777518C1 +:107100005E0600000000000000000000000000001B +:10711000000000000C0000005B555555555500005F +:10712000000000000000000008393939393900003A +:10713000000000000000000002000000EC145416E3 +:1071400084167E17411AA2176A199119B1197E1770 +:1071500007B8C30700800000208300000080328051 +:10716000648096802DB4040F110C0F0F10000F13C4 +:10717000A5BA830A18C80F00151015101043104344 +:1071800020030000E3180803446100070800000022 +:1071900000000000000000000000000000000000EF +:1071A0000B00000055555555550500000000000026 +:1071B00000000000000000000100000000000000CE +:1071C0000000000003000000EC14541684167E1723 +:1071D000411AA2176A199119B1197E1707B8C30786 +:1071E0000080000020830000008032806480968050 +:1071F0002DB4040F110C0F0F10000F13A5BA830A42 +:1072000018C80F001510151010431043200300007C +:10721000D4B80000000000000000000000000000E2 +:10722000000000000000000000000000030000005B +:107230005B050000000000000000000000000000EE +:10724000080A00000000000000000000000000002C +:1072500002000000EC14541684167E17411AA2177F +:107260006A199119B1197E1707B8C3070080000089 +:107270002083000000803280648096802DB4040F4B +:10728000110C0F0F10000F13A5BA830A18C80F00B6 +:1072900015101510104310432003000009050000CD +:1072A00000000000C002000000000000000000001C +:1072B0000000000000000000020000006466666636 +:1072C0006666000000000000000000008200000070 +:1072D00000A000000000000000000000FC0700000B +:1072E000EC14541684167E17411AA2176A199119C4 +:1072F000B1197E1707B8C307008000002083000083 +:1073000000803280648096802DB4040F110C0F0F22 +:1073100010000F13A5BA830A18C80F001510151016 +:107320001043104320030000813010050670200038 +:10733000000000000000000000000000000000004D +:1073400000000000090000005555555505000000DB +:10735000000000000000000000000001000000002C +:10736000000000000000000000000000EC145416B3 +:1073700084167E17411AA2176A199119B1197E173E +:1073800007B8C3070080000020830000008032801F +:10739000648096802DB4040F110C0F0F10000F1392 +:1073A000A5BA830A18C80F00151015101043104312 +:1073B0000000000000000001000003000000FC00CD +:1073C000000000000D000D0008072107000000006C +:1073D0000155B4000200000000000000010103029A +:1073E000000001000000FC00000000000D000D0086 +:1073F00010001F000000000004B0B30000000010E7 +:107400000000000002020302000001000000FC0076 +:10741000000000000D000D0011001E000000000023 +:1074200004C4B300000000100000000003030302C6 +:10743000000001000000FC00000000000D000D0035 +:1074400012001D000000000004D8B300000000106E +:107450000000000004040302000001000000FC0022 +:10746000000000000D000D0013001C0000000000D3 +:1074700004ECB3000000001000000000050503024A +:10748000000001000000FC00000000000D000D00E5 +:1074900014001B00000000000400B40000000010F5 +:1074A0000000000006060302000001000000FC00CE +:1074B000000000000D000D0015001A000000000083 +:1074C0000414B400000000100000000007070302CD +:1074D000000001000000FC00000000000D000D0095 +:1074E00016001900000000000428B400000000107D +:1074F0000000000008080302000005000000FC0076 +:10750000000000000D000D00170018000000000032 +:10751000043CB4000000001000000000090000015D +:10752000000007000000FC00000000000D000D003E +:1075300004101D10000000000150B4000000000005 +:107540000000000000000001000003000000FC003B +:10755000000000000D000D008917701700000000EA +:1075600001A0B40006000000000000000000171792 +:10757000000003000000FC00000000000D000D00F2 +:107580009C189D1800000000019BB400040000003E +:107590000000000000001616010003000000FD00BE +:1075A000000000000D000D00301138110000FE2514 +:1075B0000473B4000400000000000000000017176E +:1075C000020003000000FC00000000000D000D00A0 +:1075D000C012C1120000FE250487B40004000000A0 +:1075E0000000000000001616030003000000FD006C +:1075F000000000000D000D00301138110000FE25C4 +:107600000473B4000400000000000000000017171D +:10761000040003000000FC00000000000D000D004D +:10762000C012C1120000FE250487B400040000004F +:107630000000000000001616050003000000FD0019 +:10764000000000000D000D00301138110000FE2573 +:107650000473B400040000000000000000001717CD +:10766000060003000000FC00000000000D000D00FB +:10767000C012C1120000FE250487B40004000000FF +:107680000000000000001616070003000000FD00C7 +:10769000000000000D000D00301138110000FE2523 +:1076A0000473B4000400000000000000000017177D +:1076B000080003000000FC00000000000D000D00A9 +:1076C000C012C1120000FE250487B40004000000AF +:1076D00000000000000A1414002802000000FC0052 +:1076E0000000000005000500000000000000000090 +:1076F00001009703000000000000000000000100EE +:10770000002802000000FC00000000000D000D0039 +:10771000C800E10000000000015AB40002000000AF +:107720000000000000000100002802000000FC0032 +:10773000000000000D000D00580271020000000062 +:10774000015FB40002000000000000000000010022 +:10775000002802000000FC00000000000D000D00E9 +:10776000E8030104000000000164B400020000000E +:107770000000000000000100002802000000FC00E2 +:10778000000000000D000D007805910500000000CC +:107790000169B400020000000000000000000100C8 +:1077A000002802000000FC00000000000D000D0099 +:1077B0000807210700000000016EB400020000006D +:1077C0000000000000000100002802000000FC0092 +:1077D000000000000D000D003011491100000000F4 +:1077E00001A5B40006000000000000000000010038 +:1077F000002802000000FC00000000000D000D0049 +:10780000C012D9120000000001AAB4000600000056 +:107810000000000000000100002802000000FC0041 +:10782000000000000D000D0050146914000000005D +:1078300001AFB400060000000000000000000100DD +:10784000002802000000FC00000000000D000D00F8 +:10785000E015F9150000000001B4B40006000000B6 +:107860000000000000000100002802000000FC00F1 +:10787000000000000D000D007017891700000000C7 +:1078800001B9B40006000000000000000000010083 +:10789000002802000000FC000000000009000900B0 +:1078A0000000000000000000010097030600000037 +:1078B00000000000000B1414002802000000FC006F +:1078C000000000000C000C000000000000000000A0 +:1078D000010097030000000000000000000B1414DA +:1078E000002802000000FC003F0000000C000C001B +:1078F00000000000000000000100970300000000ED +:1079000000000000000B1515002802000000CC004C +:10791000000000000C000C0000000000000000004F +:1079200001009703000000000000000000000100BB +:10793000002802000000FC00000000000D000D0007 +:107940000000000000000000010097030600000096 +:107950004F00000001F4040068931B006000000069 +:107960000C0000000100040014280000600000006A +:10797000300000002D008400142800001C000000CE +:10798000730000002DF4840068931B001C000000AD +:10799000700000002DF4840068931B001C000000A0 +:1079A0007300000023F4840068931B001C00000097 +:1079B000600000002DF4840068931B001C00000090 +:1079C0004F00000001F4040068931B00E000010078 +:1079D0000C0000000100040014280000E000010079 +:1079E000300000002D008400142800001C0000005E +:1079F000700000002DF4840068931B001C00000040 +:107A0000730000002DF4840051651B001C00000071 +:107A10000101010101010101010101010101010156 +:107A20000101010101010101010101010101010146 +:107A30000101010101010101010101010101010136 +:107A40000101010101010101010101010101010126 +:107A50000101010101010101010101010101010116 +:107A60000101010101010101010101010101010106 +:107A70000101010133343A3335333534333433358E +:107A800033343233343334333334333334333333C2 +:107A900034343233343433333334323334333433B1 +:107AA00033343334353233333332323233333233A7 +:107AB00032333231333232323033323331323232A6 +:107AC0003231323232323232323231323332313298 +:107AD000313432342F2F2F3033343A333533353479 +:107AE0003334333533343233343334333334333360 +:107AF0003433333334333233343433333334323353 +:107B00003333333333353334353233333332323244 +:107B10003333323332333231333232323033323341 +:107B20003132323232313232323232323232313238 +:107B300033323132313432342F2F2F303334333328 +:107B400034333434333333353334333334333433FD +:107B500033343333343333333434333334343333EF +:107B600033343233343333333335333434323332E2 +:107B700033333232333332323233323133323232E0 +:107B800030333232313232313231323132323132DB +:107B90003232313232323132313332332F2F2E30D2 +:107BA000333433333433343433333335333433339E +:107BB000343334333334333334333333343433338F +:107BC0003434333333343233333333333335333480 +:107BD000343233323333323233333233323332317D +:107BE0003332323231333233313232323231323176 +:107BF0003232313232323132333231323133323366 +:107C00002F2F2E3033343233343334333333333550 +:107C10003334333334333433333433333333333330 +:107C20003433333234343333333432333333333322 +:107C30003335333434323332333232323333323217 +:107C40003233323133323232303332323132323116 +:107C50003231323132323132323231323332313208 +:107C6000313332332F2F2E2F3334323334333434F5 +:107C700033333335333433333433343333343333CE +:107C800034333333343333333434333333343233C0 +:107C900033333333333533343432333233323232B5 +:107CA00033333233323332313332323231333233AF +:107CB00031323231323132323232313232323132A9 +:107CC00033323132313332332F2F2E2F333532329C +:107CD000343333333334333433343333343334336E +:107CE000333433333433333334343332343433335F +:107CF0003334323333333333333533343432333252 +:107D00003332323233333232323232313332323250 +:107D1000303332333132313132313131323231324A +:107D20003232313232323132313332332F2F2E3040 +:107D3000333532323433333333343334333433330F +:107D400034333433333433333333333334343332FF +:107D500034343333333432333333333333353334EE +:107D600034323332333232323333323232333231ED +:107D700033323232303332333132323232313232E4 +:107D800032323132323231323232313231333233D5 +:107D90002F2F2E2F4F51534F4F4D514D4F4F4D5170 +:107DA0004D4F4F514F4F534F4B515151534D534DD9 +:107DB0004F4D4F515151514F4F4F4F4F514D514FCB +:107DC0004F515153534F5151514F514F4F4E4F4FB0 +:107DD0004B4F4F4F4F4D4F514B4F4F514F4D4F51B9 +:107DE0004D4F4F4D4F4B4D51514F4F4F4F4D4D4FAD +:107DF0004B4D4F514D494B4D92249224920092008D +:107E000000000000B66DB66DB600B60000000000C0 +:107E1000B66DB66D9601960100000000B66DB66DA8 +:107E2000B201B20100000000B62DB62DB601B601B8 +:107E300000000000B665B665B601B601000000009E +:107E4000B66CB66CB601B60100000000966D966D7A +:107E5000B601B60100000000B26DB26DB601B60108 +:107E600000000000FF7FFF7FFF01FF010000000016 +:107E7000B66DB66DB601B6010000000092249224E2 +:107E800092009200000000000110000000000000BD +:107E900000000000FFFF3DDB38D4FC020200AA0016 +:107EA0006C768A940001060000000000DB060000EA +:107EB000040C000060056E40415639030100009A31 +:107EC000EC045661000000000000000010C40C50DB +:107ED0000390BBBB804422786411641189398939CD +:107EE0000FE00FE0641264120110000000000000B7 +:107EF00000000000FFFF3DDB38D4FC020200AA00B6 +:107F00006C768A940001060000000000DB06000089 +:107F1000040C000060056E40415639030100009AD0 +:107F2000EC045661000000000000000010C40C10BA +:107F3000E39EBBBB8055227864116411893989396D +:107F40000FE00FE064126412010400000000000062 +:107F50000000000000000000000000020200AA0073 +:107F60006C768A940001060000000000DB06000029 +:107F7000040C000020066E40418639030100009A7F +:107F8000AC058661000000000000000010C40C5029 +:107F90000390BBBB8044227864116411893989390C +:107FA0000FE00FE064126412C9040200010203042E +:107FB000EAF7FAFD3001A880CF0304021E00000397 +:107FC0006C768A940001060000000000DB060000C9 +:107FD000014600002B1A0040006B39034100029A51 +:107FE00000006B616478792BCF8A00801C54119853 +:107FF0000080BBBB0057227864116411893989392C +:108000000FF00FF064126412C904020001010101B3 +:10801000EAF7FAFD3001A880CF0304020200000055 +:108020006C768A940001060000000000DB06000068 +:10803000014600002B1A0040006B39034100029AF0 +:1080400000006B61BB7DFC17FFFF00801C54119882 +:108050000380BBBB80462278641164118939893959 +:108060000FF00FF064126412C9040200020202024F +:10807000EAF7FAFD3001A880CF03040202000000F5 +:108080006C768A940001060000000000DB06000008 +:10809000014600002B1A0040006B39034100029A90 +:1080A00000006B610F7E3416FFFF00801C54119896 +:1080B0000380BBBB804622786411641189398939F9 +:1080C0000FF00FF064126412C904020003030303EB +:1080D000EAF7FAFD3001A880CF0304020200000095 +:1080E0006C768A940001060000000000DB060000A8 +:1080F000014600002B1A0040006B39034100029A30 +:1081000000006B61B17E3C12FFFF00801C5411988F +:108110000380BBBB80462278641164118939893998 +:108120000FF00FF064126412C90402000404040486 +:10813000EAF7FAFD3001A880CF0304020200000034 +:108140006C768A940001060000000000DB06000047 +:10815000014600002B1A0040006B39034100029ACF +:1081600000006B611C7F0B0FFFFF00801C541198F7 +:108170000380BBBB80462278641164118939893938 +:108180000FF00FF0641264120104000400000000FC +:10819000CCF57AFDED20BF8FCF030402020600006C +:1081A0006C768A940001060000000000DB060000E7 +:1081B00001060000093C0040006B39034100029AAF +:1081C00000006B616478792BCF8A00801CC4101882 +:1081D0000380ABAA00C6227864116411803980390B +:1081E0000F000F00550D550DC904020006070A0BBC +:1081F000EAF7FAFD3001A880CF0304021E0600034F +:108200006C768A940001060000000000DB06000086 +:10821000014600002B1A0040006B39034100029A0E +:1082200000006B616478792BCF8A00801C54119810 +:108230000080BBBB00572218641164118939893949 +:108240000FF00FF064126412C9040200060606065D +:10825000EAF7FAFD3001A880CF030402020600000D +:108260006C768A940001060000000000DB06000026 +:10827000014600002B1A0040006B39034100029AAE +:1082800000006B616478792BCF8A00801C541198B0 +:108290000080BBBB005722186411641189398939E9 +:1082A0000FF00FF064126412C904020006060A0AF5 +:1082B00073EDFAFD5985A880CF0304020A06010078 +:1082C0006C768A940043060100000000DB06000083 +:1082D000014600002B1A0040006B39034100029A4E +:1082E00000006B619367CBB40000008012541198BA +:1082F0000080BBBB0056221864116411893989398A +:108300000FF00FF064126412C904020007070B0B90 +:1083100073EDFAFD5985A880CF0304020A06010017 +:108320006C768A940043060100000000DB06000022 +:10833000014600002B1A0040006B39034100029AED +:1083400000006B6155737BC80000008012541198C7 +:108350000080BBBB00562218641164118939893929 +:108360000FF00FF064126412C904020009090C0C2A +:1083700073EDFAFD5985A880CF0304020A060100B7 +:108380006C768A940043060100000000DB060000C2 +:10839000014600002B1A0040006B39034100029A8D +:1083A00000006B61D9770ED3000000801254119841 +:1083B0000080BBBB005622186411641189398939C9 +:1083C0000FF00FF064126412C90402000A0A0606D4 +:1083D00073EDFAFD5985A880CF0304020A06010057 +:1083E0006C768A940043060100000000DB06000062 +:1083F000014600002B1A0040006B39034100029A2D +:1084000000006B61BD7977D800000080125411988C +:108410000080BBBB00562218641164118939893968 +:108420000FF00FF064126412C90402000B0B07076F +:1084300073EDFAFD5985A880CF0304020A060100F6 +:108440006C768A940043060100000000DB06000001 +:10845000014600002B1A0040006B39034100029ACC +:1084600000006B61757B34DE0000008012541198AF +:108470000080BBBB00562218641164118939893908 +:108480000FF00FF064126412C90402000A0A060613 +:1084900073EDFAFD5985A880CF0304020A06010096 +:1084A0006C768A940043060100000000DB060000A1 +:1084B000014600002B1A0040006B39034100029A6C +:1084C00000006B61CB7C87E30000008012541198A0 +:1084D0000080BBBB005622186411641189398939A8 +:1084E0000FF00FF064126412C90402000B0B0707AF +:1084F00073EDFAFD5985A880CF0304020A06010036 +:108500006C768A940043060100000000DB06000040 +:10851000014600002B1A0040006B39034100029A0B +:1085200000006B61F27D29E900000080125411986F +:108530000080BBBB00562218641164118939893947 +:108540000FF00FF064126412C90402000C0C090948 +:1085500073EDFAFD5985A880CF0304020A060100D5 +:108560006C768A940043060100000000DB060000E0 +:10857000014600002B1A0040006B39034100029AAB +:1085800000006B61D57EC2EE00000080125411988D +:108590000080BBBB005622186411641189398939E7 +:1085A0000FF00FF0641264120000000000000000E1 +:1085B00000101000000056CE00009910100E0006AA +:1085C0000000FDF900006FA1100E00050000464FED +:1085D000000029A6100F00040000AD8700007DD91F +:1085E000100F00030000C15A00009C9A00041030D4 +:1085F0000000BCA00000903800091033000083D0B8 +:108600000000D635000B10350000C9C200001A5911 +:10861000000C103600008CA100002C9F000D1037BC +:1086200000009851000044DC000E10380000BEEA43 +:108630000000A536000E103A000026620000DD9909 +:10864000000F103B00000000B5000000BF0000005C +:10865000DF000000EC00000019010000280100000C +:108660004301000053010000000000000000000072 +:1086700000000000000000000000000000000000FA +:1086800000000000000000000000000000000000EA +:1086900000000000000000000000000000000000DA +:1086A00000000000000000000000000000000000CA +:1086B00000000000000000000000000000000000BA +:1086C00000000000870700008579385793F930A132 +:1086D000B3D4CC2BCB0AF200000000000000000055 +:1086E000000000000000000000000000000000008A +:1086F000000000000000000000000000000000007A +:1087000080220022870700008579385793E4C2B998 +:1087100030AFCC2BC5A1B30000000000000000006A +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:1087400080220022870700008579385793E4C2BC55 +:10875000C2BCD7930D79300000000000000000007B +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800080220022870700008579385793E4C2BF12 +:10879000930ACC2BC4F50D0000000000000000007F +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00080220022870700008579385793E4C2BFD2 +:1087D000930AE4C2B286CF0000000000000000004F +:1087E0000000000000000000000000000000000089 +:1087F0000000000000000000000000000000000079 +:1088000080220022870700008579385793E4C2BF91 +:10881000930AB0AF26CF5000000000000000000017 +:108820000000000000000000000000000000000048 +:108830000000000000000000000000000000000038 +:1088400080220022870700008579385793E4C2BB55 +:108850000AF2E4C2BE4C2B00000000000000000041 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800080220022870700008579385793E4C2BB15 +:108890000AF2B0AF295E4C000000000000000000AA +:1088A00000000000000000000000000000000000C8 +:1088B00000000000000000000000000000000000B8 +:1088C00080220022C8060000450EA63D450EA63DAA +:1088D000BAF15942450EA63D450EA63D450EA63DB0 +:1088E000450EA63D00000000000000000000000052 +:1088F0000000000000000000000000000000000078 +:108900008022002231302F2E2D2C2B2A2928272699 +:108910002524232221201F1E1D1C1B1A191817167F +:108920001514131211100F0E0D0C0B0A090807066F +:108930000504030201000000000000000000000028 +:108940000000000000000000000000004A49484705 +:10895000464544434241403F3E3D3C3B3A3938372F +:10896000363534333231302F2E2D2C2B2A2928271F +:10897000262524232221201F1E1D1C1B1A1900003E +:1089800000000000000000000000000000000000E7 +:10899000000000002000E0C0A08060402000E0C097 +:1089A000A08060402000E0C0A08060402000E0C0C7 +:1089B000A08060402000E0C0A08060402000E0C0B7 +:1089C000A08060402000000076DBB62D2449921B79 +:1089D000DBB6491292942409090000002000E0C08F +:1089E000A08060402000E0C0A08060402000E0C087 +:1089F000A08060402000E0C0A08060402000E0C077 +:108A0000A08060402000E0C0A08060402000000006 +:108A100076DBB62D2449921BDBB6491292942409C9 +:108A2000090000002021E0E1A0A160612021E0E137 +:108A3000A0A160612021E0E1A0A160612021E0E12E +:108A4000A0A160612021E0E1A0A160612021E0E11E +:108A5000A0A160612021000076DBB62D2449921B85 +:108A6000DBB6491292942409090000000100C1C03C +:108A7000818041400100C1C0818041400100C1C0EE +:108A8000818041400100C1C0818041400100C1C0DE +:108A9000818041400100C1C081804140010000004F +:108AA00076DBB62D2449921BDBB649129294240939 +:108AB000090000002120E1E0A1A061602120E1E0A7 +:108AC000A1A061602120E1E0A1A061602120E1E09E +:108AD000A1A061602120E1E0A1A061602120E1E08E +:108AE000A1A061602120000076DBB62D2449921BF5 +:108AF000DBB6491292942409090000007353331322 +:108B0000F2D2B29272523212F2D2B2927252321245 +:108B1000F2D2B29272523212F2D2B2927252321235 +:108B2000F2D2B29272523212F2D2B2927252000069 +:108B300000D0B62D2D499224DBB66D129224250962 +:108B4000490200003C1CFCDCBC9C7C5C3C1CFCDC4A +:108B5000BC9C7C5C3C1CFCDCBC9C7C5C3C1CFCDC55 +:108B6000BC9C7C5C3C1CFCDCBC9C7C5C3C1CFBDB47 +:108B7000BB9B7B5B3B1B00002D499224DBB66D1237 +:108B8000922425094902000040DBB62DB4947454A8 +:108B90003414F3D3B39373533313F3D3B3937353A3 +:108BA0003313F3D3B39373533313F3D3B393735395 +:108BB0003313F3D3B39373533313F3D3B39300004B +:108BC0000000B42D6D4B9224E4B66D1B922449092C +:108BD00049920000FBDBBB9B7B5B3B1BFBDBBB9B36 +:108BE0007B5B3B1BFBDBBB9B7B5B3B1BFBDBBB9BD5 +:108BF0007B5B3B1BFBDBBB9B7B5B3B1BFADABA9AC9 +:108C00007A5A3A1AFADA00002449921BDBB6491262 +:108C100092942409090000006DDBB624F5D5B595C2 +:108C200075553515F4D4B49474543414F4D4B49400 +:108C300074543414F4D4B49474543414F4D4B494F4 +:108C400074543414F4D4B49474543414F4D400002C +:108C50000000002D6DDB922424B96D1B9B2449126A +:108C600049922400BA9A7A5A3A1AFADABA9A7A5A8D +:108C70003A1AFADABA9A7A5A3A1AFADABA9A7A5A54 +:108C80003A1AFADABA9A7A5A3A1AF9D9B99979594A +:108C90003919F9D9B999000024496E1BDB2649120C +:108CA000529224090000002D6DDB92243616F6D670 +:108CB000B69676563616F5D5B59575553515F5D55E +:108CC000B59575553515F5D5B59575553515F5D554 +:108CD000B59575553515F5D5B5957555351500000E +:108CE000090000006DDBB62424496E1BDB26491207 +:108CF0005292240979593919F9D9B99979593919F7 +:108D0000F9D9B99979593919F9D9B99979593919D3 +:108D1000F9D9B99979593919F8D8B89878583818CB +:108D2000F8D8B8987858000024B96D1B9B244912D4 +:108D3000499224000000B42D6D4B922477573717C9 +:108D4000F7D7B79777573717F6D6B69676563616BB +:108D5000F6D6B69676563616F6D6B69676563616B3 +:108D6000F6D6B69676563616F6D6B69676560000EF +:108D70004902000040DBB62D2449921BDBB64912A4 +:108D8000929424093818F8D8B89878583818F8D830 +:108D9000B89878583818F8D8B89878583818F8D853 +:108DA000B89878583818FFFFFFFFFFFFFFFFFFFF5D +:108DB000FFFFFFFFFFFF0000E4B66D1B922449098F +:108DC0004992000000F0FF3FFFFFFF3FFFFFFFFF62 +:108DD000FFFFFFFFFFFFFFFFFFFFF7D7B7977757B3 +:108DE0003717F7D7B79777573717F7D7B797775713 +:108DF0003717F7D7B79777573717F7D7B7970000D1 +:108E0000FFFFFF3FFFDFB62D2D499224DBB66D1229 +:108E100092242509636261605F5E5D5C5B5A59580C +:108E200057565554535251504F4E4D4C4B4A49484A +:108E300047464544434241403F3E3D3C3B3A39383A +:108E400037363534333200000000000000000000E7 +:108E500000000000000000000000000031302F2E54 +:108E60002D2C2B2A292827262524232221201F1EAA +:108E70001D1C1B1A191817161514131211100F0E9A +:108E80000D0C0B0A09080706050403020100000087 +:108E900000000000000000000000000000000000D2 +:108EA00000000000FFFFFFFFFFFFFFFFFFFFFFFFCE +:108EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:108EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:108ED000FFFFFFFFFFFF0000FFFFFF3FFFFFFF3F20 +:108EE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFFFFD2 +:108EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:108F0000FFFFFFFFFFFFFFFFFFFF0000000000006B +:108F10000000000000000000000000000000000051 +:108F2000FFFFFF3FFFFFFF3FFFFFFF3F000000008D +:108F30000000000057473727170756463626160603 +:108F4000554535251505544434241404534333231F +:108F50001303524232221202514131211101504079 +:108F600030201000FFFF00000000000000000000A3 +:108F700000000000000000000000003F62605E5C36 +:108F80005A58565452504E4C4A48464442403E3C31 +:108F90003A38363432302E2C2A28262422201E1C21 +:108FA0001A18161412100E0C0A080604020000000B +:108FB00000000000000000000000000000000000B1 +:108FC00000000000000000000000000000000000A1 +:108FD0000000000000000000000000000000000091 +:108FE0000000000000000000000000000000000081 +:108FF0000000000000000000000000000000000071 +:109000000000000000000000000000000000000060 +:109010000000000000000000000000000000000050 +:109020000000000000000000000000000000000040 +:109030000000000000000000000000000000000030 +:109040000000000000000000000000000000000020 +:109050000000000000000000000000000000000010 +:109060000000000000000000000000000000000000 +:1090700000000000000000000000000000000000F0 +:1090800000000000000000000000000000000000E0 +:1090900000000000000000000000000000000000D0 +:1090A00000000000000000000000000000000000C0 +:1090B00000000000000000000000000000000000B0 +:1090C00000000000000000000000000000000000A0 +:1090D0000000000000000000000000000000000090 +:1090E0000000000000000000000000000000000080 +:1090F0000000000000000000000000000000000070 +:10910000000000000000000000000000000000005F +:10911000000000000000000000000000000000004F +:10912000000000000000000000000000000000003F +:10913000000000000000000000000000000000002F +:10914000000000000000000000000000000000001F +:10915000000000000000000000000000000000000F +:1091600000000000000000000000000000000000FF +:1091700000000000000000000000000000000000EF +:1091800000000000000000000000000000000000DF +:1091900000000000000000000000000000000000CF +:1091A00000000000000000000000000000000000BF +:1091B00000000000000000000000000000000000AF +:1091C000000000000000000000000000000000009F +:1091D000000000000000000000000000000000008F +:1091E000000000000000000000000000000000007F +:1091F000000000000000000000000000000000006F +:109200000801010000000000000000003202100010 +:109210001B00000000000000000000000000000033 +:109220008C1C0000AF1C0000D21C0000F51C0000CC +:10923000200300004110080344611C0800000000E6 +:10924000000000000000000000000000000000001E +:109250000A00000066666666560000000000000016 +:1092600000000000000000000000000000000000FE +:109270000000000003000000181DD61D061E1F1E62 +:10928000531F581E301F421F431F7E1707B8C307C6 +:10929000008000002083000000803280648096807F +:1092A0002DB4040F110C0F0F10000F13A5BA030AF1 +:1092B00018C80F00151015101043104320030000AC +:1092C000CBB2300DCE0345120000000000000000BC +:1092D0000000000000000000000000000A00000084 +:1092E0006666666656000000000000000000000090 +:1092F00011111111111111111111000000000010B4 +:1093000003000000181DD61D061E1F1E531F581EE9 +:10931000301F421F431F7E1707B80733008000002D +:109320002083000000803280648096802DB4040F7A +:10933000110C0F0F90000F13A5BA830A18C80F0065 +:10934000151015101043104345097E1707B8C307C1 +:109350000080008020F3000C00803280648096FE44 +:109360002DB4FFFF11FDFFFFD0FF0F13A5BA830A35 +:1093700018C80F00130F130F0F410F411F030000F8 +:1093800009000000000000000000000000000000D4 +:10939000189DD69D069E1F9E539F589E309F429FAC +:1093A000439F0000000000C000000000000000001B +:1093B00002000000000000000000000000000000AB +:1093C00000E60000EC0454E7E4077EE75509A20735 +:1093D0000A09250945097E1707B8C3070080000060 +:1093E0002083000000803280648096802DB4048F3A +:1093F00011FDFFFFD0FF0F93A5BA830A18E80FE015 +:10940000130F13FF0F410F411F030000D4B80402D4 +:109410000351188748F00C0C85011C08189DD69D37 +:10942000069E1F9E539F589E309F429F439F5555B7 +:10943000555555D55555000000000018086A666658 +:1094400066666666366600270000000002E6008059 +:10945000EC0C54EFE4877EE75509A2070AE925E9F9 +:109460000000000000000100002802000000FC00D5 +:10947000000000000D000D0059064006000000002D +:1094800001559701020000000000000000010202E7 +:10949000002800008002FC00FFFFFF010D000D000E +:1094A00017001F000000000004B0B300000000100F +:1094B0000000000000020202002800008002FC0000 +:1094C000FFFFFF010D000D0016001E000000000050 +:1094D00004C4B300000000100000000000030202FA +:1094E000002800008002FC00FFFFFF010D000D00BE +:1094F00015001D000000000004D8B300000000109B +:109500000000000000040202002800008002FC00AD +:10951000FFFFFF010D000D0014001C000000000003 +:1095200004ECB3000000001000000000000502027F +:10953000002800008002FC00FFFFFF010D000D006D +:1095400013001B00000000000400B4000000001025 +:109550000000000000060202002800008002FC005B +:10956000FFFFFF010D000D0012001A0000000000B7 +:109570000414B40000000010000000000007020204 +:10958000002800008002FC00FFFFFF010D000D001D +:1095900011001900000000000428B40000000010B1 +:1095A0000000000000080202002804008002FC0005 +:1095B000FFFFFF010D000D0010001800000000006B +:1095C00020B0B30000000010000000000000000008 +:1095D000002806000000FC00000000000D000D0047 +:1095E000D20FA00F00000000015097010000000002 +:1095F0000000000000000000002802000000FC0045 +:10960000000000000D000D00C116A81600000000AB +:10961000018C97010600000000000000000B020210 +:10962000002800008000FC00000000000D000D007C +:1096300017001F000000000004B0B300000000107D +:1096400000000000000C0202002800008000FC0066 +:10965000000000000D000D0016001E0000000000BC +:1096600004C4B3000000001000000000000D02025E +:10967000002800008000FC00000000000D000D002C +:1096800015001D000000000004D8B3000000001009 +:1096900000000000000E0202002800008000FC0014 +:1096A000000000000D000D0014001C000000000070 +:1096B00004ECB3000000001000000000000F0202E4 +:1096C000002800008000FC00000000000D000D00DC +:1096D00013001B00000000000400B4000000001094 +:1096E0000000000000100202002800008000FC00C2 +:1096F000000000000D000D0012001A000000000024 +:109700000414B40000000010000000000011020268 +:10971000002800008000FC00000000000D000D008B +:1097200011001900000000000428B400000000101F +:109730000000000000120202002804008000FC006B +:10974000000000000D000D001000180000000000D7 +:1097500020B0B300000000104F00000001F404002E +:1097600068931B00600000000C0000000100040072 +:109770001428000060000000300000002D0084006C +:10978000142800001C000000730000002DF4840069 +:1097900068931B001C000000700000002DF4840082 +:1097A00068931B001C000000730000002DF484006F +:1097B00068931B001C000000630000002DF484006F +:1097C00068931B001C0000004F00000001F404001F +:1097D00068931B00E00001000C0000000100040081 +:1097E00014280000E0000100300000002D0084007B +:1097F000142800001C000000700000002DF48400FC +:1098000068931B001C000000000000000000000026 +:109810000000000000000000000000000000000048 +:109820000000000000000000000000000000000038 +:109830000000000000000000000000000000000028 +:109840000000000000000000000000000000000018 +:109850000000000000000000000000000000000008 +:1098600000000000000000000000000000000000F8 +:10987000000000000000000000000000922492247C +:109880009200920000000000224924492401A40013 +:1098900000000000144924492401140100000000C4 +:1098A000A448244924012201000000002445242961 +:1098B000240124010000000024292445240124015E +:1098C000000000002449A4482201240100000000F7 +:1098D00024491449140124010000000024492249AC +:1098E000A400240100000000FF7FFF7FFF01FF01B3 +:1098F00000000000B66DB66DB601B60100000000B4 +:10990000B26DB66DB601B60000000000966DB66D82 +:10991000B601960100000000B66CB66DB601B2014A +:1099200000000000B665B62DB601B60100000000CB +:10993000B62DB665B601B60100000000B66DB66C76 +:10994000B201B60100000000B66D966D9601B60139 +:1099500000000000B66DB26DB600B6010000000058 +:1099600001280000000000000000000000000000CE +:10997000000000020206AA006C768A94000106002C +:1099800000000000DB0600000106000091016E40AF +:10999000418C39030100009A1D018C610000000018 +:1099A0000000000010100D100390BBBB8E5A22184F +:1099B00064116411893989390AE00FE06412641274 +:1099C0000120000000000000000000000000000076 +:1099D000000000020206AA006C768A9400010600CC +:1099E00000000000DB0600000106000091016E404F +:1099F000418C39030100009A1D018C6100000000B8 +:109A00000000000010000C100380ABAA80442278F4 +:109A1000641164118939893905E005E06412641222 +:109A20000104000000000000000000000000000031 +:109A3000000000020200AA006C768A940001060071 +:109A400000000000DB060000040C000038066E2059 +:109A5000418C390301000084C4058C6100000000C2 +:109A60000000000010C40C500390BBBB804422785F +:109A7000641164118A39893905E00FE064126412B7 +:109A8000D004020001020304CCF57AFDED20BF8F63 +:109A9000CF0304021E0600036C768A9400010600C0 +:109AA00000000000DB06000001460000121B002041 +:109AB000006B39034100028400006B616478792BEC +:109AC000CF8A00801C5411980080BBBB00572278BD +:109AD000641164118A39893905E00FE06412641257 +:109AE0000100000001010101CCF57AFDED20BF8FDE +:109AF000CF030402020600006C768A94000106007F +:109B000000000000DB060000000C0000401A0020EE +:109B10004100380341000284000000606478792B22 +:109B2000CF8A00801C5410180380BBBB804622786B +:109B3000641164118A39893905E00FE064126412F6 +:109B4000D004020002020202CCF57AFDED20BF8FA4 +:109B5000CF030402020600006C768A94000106001E +:109B600000000000DB06000001460000121B002080 +:109B7000006B39034100028400006B616478792B2B +:109B8000CF8A00801C5411980380BBBB804622788A +:109B9000641164118A39893905E00FE06412641296 +:109BA0000100000003030303CCF57AFDED20BF8F15 +:109BB000CF030402020600006C768A9400010600BE +:109BC00000000000DB060000000C0000401A00202E +:109BD0004100380341000284000000606478792B62 +:109BE000CF8A00801C5410180380BBBB80462278AB +:109BF000641164118A39893905E00FE06412641236 +:109C0000D004020004040404CCF57AFDED20BF8FDB +:109C1000CF030402020600006C768A94000106005D +:109C200000000000DB06000001460000121B0020BF +:109C3000006B39034100028400006B616478792B6A +:109C4000CF8A00801C5411980380BBBB80462278C9 +:109C5000641164118A39893905E00FE064126412D5 +:109C60000100000000000000CCF57AFDED20BF8F60 +:109C7000CF030402020600006C768A9400010600FD +:109C800000000000DB060000000C0000FF3B00208D +:109C90004100380341000284000000606478792BA1 +:109CA000CF8A00801CC410180300000000C6227870 +:109CB000641164118039803905000F00551055106A +:109CC000000000000000000000101000000092CD15 +:109CD0000000C180100F0002000087370000BBF1B8 +:109CE000100F00040000904100008B43100E00078D +:109CF0000000BBF100009167100C000900001DFB83 +:109D00000000709E100E000500000000C806000054 +:109D1000BAF15942BAF15942450EA63D11223344D7 +:109D20005566778899AABBCCDDEEFF69000000007C +:109D30000000000000000000000000000000000023 +:109D40000000000000000000C022C0224A4948472D +:109D5000464544434241403F3E3D3C3B3A3938371B +:109D6000363534333231302F2E2D2C2B2A2928270B +:109D7000262524232221201F1E1D1C1B1A1900002A +:109D800000000000000000000000000000000000D3 +:109D90000000000031302F2E2D2C2B2A29282726B9 +:109DA0002524232221201F1E1D1C1B1A19181716DB +:109DB0001514131211100F0E0D0C0B0A09080706CB +:109DC0000504030201000000000000000000000084 +:109DD0000000000000000000000000002000E0C0C3 +:109DE000A08060402000E0C0A08060402000E0C073 +:109DF000A08060402000E0C0A08060402000E0C063 +:109E0000A08060402000E0C0A080604020000000F2 +:109E100076DBB62D2449921BDBB6491292942409B5 +:109E2000090000009173553719FBDDBFA183654719 +:109E3000290BEDCFB1937557391BFDDFC1A38567A2 +:109E4000492B0DEFD1B39577593B1DFFE1C3A58792 +:109E5000694B2D0FFFFF00006D5B922424B96D1B31 +:109E60009B2449124A9224010000003F62442608C4 +:109E7000EACCAE9072543618FADCBEA08264462852 +:109E80000AECCEB0927456381AFCDEC0A284664842 +:109E90002A0CEED0B29476583A1C9D7F61430000A4 +:109EA0006D4B9224E4B66D1B9324490A4992240019 +:109EB0000000B42D2F11927456381AFCDEC0A28413 +:109EC00066482A0CEED0B29476583A1CFEE0C2A442 +:109ED00086684A2C0EF0D2B496785A3C1E00E2C432 +:109EE000A6886A4C2E10000040DB962424496E1B85 +:109EF000DB26491292922409090000002507E9CBCC +:109F0000AD8F71533517F9DBBD9F8163452709EB91 +:109F1000CDAF9173553719FBDDBFA1836547290B81 +:109F2000EDCFB1937557391B9C7E6042240600002B +:109F30002D499224DBB66D13922429094992000021 +:109F400000D0B62D6C4E3012937557391BFDDFC112 +:109F5000A38567492B0DEFD1B39577593B1DFFE1E1 +:109F6000C3A587694B2D0FF1D3B597795B3D1F01D1 +:109F7000E3C5A7896B4D000000D0B6252449921B8C +:109F8000DBB6491292A4240949020000E8CAAC8E4B +:109F900070523416F8DABC9E8062442608EACCAED1 +:109FA0009072543618FADCBEA0826446280AECCEC1 +:109FB000B0927456381A9B7D5F412305E7C90000B3 +:109FC0002449921BDBB64D1292A4240949020000D9 +:109FD00040DBB624A98B6D4F31139476583A1CFEA2 +:109FE000E0C2A486684A2C0EF0D2B496785A3C1E81 +:109FF00000E2C4A6886A4C2E10F2D4B6987A5C3E71 +:10A000002002E4C6A88A00000000B42D254992244D +:10A01000DBB66D139224290949920000AB8D6F5174 +:10A020003315F7D9BB9D7F61432507E9CBAD8F7110 +:10A03000533517F9DBBD9F8163452709EBCDAF9100 +:10A04000735537199A7C5E402204E6C8AA8C00003A +:10A0500024496E1BDB364912929224090900000044 +:10A060006DDB9224E6C8AA8C6E5032149577593B6A +:10A070001DFFE1C3A587694B2D0FF1D3B597795B20 +:10A080003D1F01E3C5A7896B4D2F11F3D5B7997B10 +:10A090005D3F2103E5C700000000002D6D499224BB +:10A0A000E4B66D1B9324490A499224006E50321481 +:10A0B000F6D8BA9C7E60422406E8CAAC8E70523450 +:10A0C00016F8DABC9E8062442608EACCAE90725440 +:10A0D0003618997B5D3F2103E5C7A98B6D4F0000C2 +:10A0E00024B96D1BDB2449124A9224090000002D7B +:10A0F0006D4B92242305E7C9AB8D6F5133159678CC +:10A100005A3C1E00E2C4A6886A4C2E10F2D4B698BF +:10A110007A5C3E2002E4C6A88A6C4E3012F4D6B8AF +:10A120009A7C5E4022040000090000006DDB92244E +:10A1300024B96D1BDB2449124A9224093113F5D747 +:10A14000B99B7D5F412305E7C9AB8D6F513315F78F +:10A15000D9BB9D7F61432507E9CBAD8F715335177F +:10A16000FFFFFFFFFFFFFFFFFFFFFFFF30120000B9 +:10A17000E4B66D1B9324490A499224000000FC3F79 +:10A18000FFFFFF2460422406E8CAAC8E70523416EA +:10A1900097795B3D1F01E3C5A7896B4D2F11F3D55F +:10A1A000B7997B5D3F2103E5C7A98B6D4F3113F54F +:10A1B000D7B99B7D5F4100004902000040DBB62417 +:10A1C00024496E1BDB36491292922409F4D6B89AC0 +:10A1D0007C5E402204E6C8AA8C6E503214F6D8BACF +:10A1E0009C7EFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:10A1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00006D +:10A20000DBB66D1392242909C9FFFF3FFFFFFF3F13 +:10A21000FFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFF0E +:10A22000FFFF987A5C3E2002E4C6A88A6C4EFFFFCE +:10A23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:10A24000FFFFFFFFFFFF0000FFFFFF3FFFDFB62D17 +:10A250002449FE3FFFFFFF3FFFFFFF3F2000E0C01C +:10A26000A08060402000E0C0A08060402000E0C0EE +:10A27000A08060402000E0C0A08060402000E0C0DE +:10A28000A08060402000E0C0A0806040200000006E +:10A2900076DBB62D2449921BDBB649129294240931 +:10A2A000090000002000E0C0A08060402000E0C065 +:10A2B000A08060402000E0C0A08060402000E0C09E +:10A2C000A08060402000E0C0A08060402000E0C08E +:10A2D000A08060402000000076DBB62D2449921B50 +:10A2E000DBB6491292942409090000000000000026 +:10A2F000000000000000000000000000000000005E +:10A30000000000000000000000000000000000004D +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000C822050CE8220F0C56 +:10AAE0000000001002000000000000000000000054 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB2000C00BBC0DEE0B0000400BBC0FEC0B040087 +:10AB3000C02ABC0FEA0B0C00404ABC0FE80B140003 +:10AB4000C069BC0FE60B1C004089BC0FE40B24005D +:10AB5000C0A8BC0FE2082C004C48BE00000000005A +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00029292A2A2A2A29292A2A2A2A29292A2A0B +:10ABB0002A2A29292A2A2A2A2A2A2A2A29292A2AF9 +:10ABC0002A2A29292A2A2A2A29292A2A2A2A2929EB +:10ABD0000000000029292A2A2A2A29292A2A2A2A81 +:10ABE0000000000000000000000000000000000065 +:10ABF00000000000000000002A2A2A2A29292A2A07 +:10AC00002A2A29290000000000000000000000009E +:10AC10000000000029292A2A2A2A29292A2A2A2A40 +:10AC20002A2A2A2A29292A2A2A2A29290000000030 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE100006F0F15506F0F15506F0F15506F0F15542 +:10AE20001B1A1A191919191816171818181818189A +:10AE30001B1B1A1919191818171818181919191A83 +:10AE40001B1A19191918181716171718181818197E +:10AE50001D1A1A1919181817171717181819191A67 +:10AE60001B1A1A191A1A1919171818181819191A51 +:10AE70001B1B1A1A19181918171717171818191948 +:10AE80001A1A1A1919191817171818181819191B36 +:10AE90001C1A191818181817161717181819191A2C +:10AEA0001B1A1A1A191A1919171819181818191A11 +:10AEB0001B1A19181919181816171717181919190C +:10AEC0001B1A1B1918191918171718181818181AF7 +:10AED0001B1A1918181818181717161718181919EF +:10AEE00019191A1918181817171718181818181ADE +:10AEF0001B191918181718171617161617171819D7 +:10AF00001B191A1918191818181819191919191BB1 +:10AF10001C1A1918181818181617171717181819AF +:10AF200019181918181818171717171818181819A2 +:10AF30001A19181817171717171716171817181997 +:10AF40001A18191918181817171717181818191A7E +:10AF50001B1A191817171717171716171818181973 +:10AF60001918191818181817171717181818181962 +:10AF70001A1A191817171717171717171818181953 +:10AF80001918191818171716161617171818181948 +:10AF90001A1A18181717161716161717171718183A +:10AFA0001918191818171817161717171818181925 +:10AFB0001A1918181717161716161617171718181C +:10AFC0001919181817171716161717171718181909 +:10AFD0001A1A1918171717171616161717171719F9 +:10AFE00019181818171717161617171718181819E9 +:10AFF00019191817171716161616161717161718E1 +:10B0000019181918171717161616161717181819CA +:10B010001A191918171716171716161717171718BA +:10B0200018181817171716161617171717181719AD +:10B03000191918171716161617161617181617189F +:10B040001919181817171616161617171718191989 +:10B05000191919171716161616161616171717197F +:10B060001818181717161616151616161717181873 +:10B070001817181716161616161616161716161867 +:10B08000181818171616161515171717171819194F +:10B09000191918181716161616161617171717193E +:10B0A000191818171616161615171818181819192A +:10B0B0001918181716161616161616161716171824 +:10B0C0001917171716161615151516171717181915 +:10B0D0001A18181716161615151515161617161808 +:10B0E00018181717161616151516171717171818F4 +:10B0F00019181817161615151516151617171618E8 +:10B1000018181717161615151515161717171818D6 +:10B1100019181717161615151515151616171718C9 +:10B1200018171716161615151515161717171718B9 +:10B1300019181717161616151515151616171617AA +:10B140001918171716161615151516171717181993 +:10B150001818171716161515151615161717171888 +:10B160001817171716161515151516171717171878 +:10B170001817171615151515151515151617161771 +:10B18000181717161615151515151516171718195A +:10B19000191717171616151515161515161717184A +:10B1A000171716161515151515151616171717183E +:10B1B0001817161716151515151515151516161633 +:10B1C0001817171716151515151615161717181819 +:10B1D000191817171615151515151515161617170D +:10B1E00018181717161515151515161616171718FA +:10B1F00018171616161515141515151515161717F3 +:10B2000017171616151514141415151616161718E3 +:10B2100018161616161515151515151516161717D1 +:10B2200017171616151514151515151616161717C2 +:10B2300017161515141415141515141515151617BC +:10B2400017171616151414141414151516161718A6 +:10B2500017161515141414141414141415151617A0 +:10B260001717161615151414141414151516161789 +:10B27000171616151515151414141414151516177C +:10B280001716161615141414141415151616171867 +:10B290001817151515151414141414151616171758 +:10B2A0001817161515141414141415151516171748 +:10B2B000161615141514131414141515151616173F +:10B2C0001816151515141413141415161516171829 +:10B2D0001716151415151414141415161516171819 +:10B2E000171616151514141314141515151616180B +:10B2F0001716151414141413141414151515161701 +:10B3000017161615151514141414151515161718E7 +:10B3100018161515151514141414151515161717D8 +:10B3200017161615151414141414141515151618CB +:10B3300017161515141414141414151516161717BA +:10B3400015151515141413131414141515161618B1 +:10B3500017161514141414131414141515151617A0 +:10B360001615151514141414131414151515161791 +:10B37000161515141514141414141415151617177E +:10B38000161615151414131314141414151617186F +:10B390001615141514141413141414151416161861 +:10B3A0001515151514141413141414141515161753 +:10B3B000161616151514141314141414151516173F +:10B3C0001615151414131313131414141415161737 +:10B3D0001515151514141413141414151515161722 +:10B3E000161515141313131313131314141515161C +:10B3F000151414141414141313141414141515160A +:10B4000016151514131313131313141415151618F6 +:10B4100016151515141414131314141414151617E3 +:10B4200015151414131313131414141414151617D8 +:10B4300016141414141413131314141414141517C9 +:10B4400015151414131313131313131415151618B9 +:10B4500016151415141313131314141414141517A8 +:10B460001A19191817171716151616161718181867 +:10B470001A1A18181818171817161718181718194D +:10B480001A19181817171716161617171818191942 +:10B490001B19191818171717161616171717181833 +:10B4A0001A1A19191A191818171817171819191913 +:10B4B0001B19191818171817161616181717181811 +:10B4C0001A191818191918181818171718181919F7 +:10B4D0001A181817171717161516171818181818F6 +:10B4E0001A1A1918191A19191718181818181919D1 +:10B4F0001A191918181818171517181818181818CD +:10B500001A191918181919181717171718191819B7 +:10B510001A191818181817171616171718181818B0 +:10B52000191918181819181817171717171818189D +:10B530001918181817171717161716171717171897 +:10B540001A19191819181918181817171819191974 +:10B550001A19191818171717171616171717171873 +:10B56000191818181818191817171716171818185F +:10B57000191818171716171716161616171817185A +:10B58000191818191818181718171817181819193A +:10B590001A18181717171617171616161718171838 +:10B5A000191819181818191717171717171818181E +:10B5B0001918181717171717161716171717181817 +:10B5C00019181819181818171717171717181818FF +:10B5D00019181817171616161616161617171718FD +:10B5E00019181819181818171717181617181818DF +:10B5F00019181717171716161616161616171718DE +:10B6000019181718181717161616171617171818C7 +:10B6100019181717171716161616161617171818BB +:10B6200018171718181718171717171617181818A4 +:10B63000181817171717171616161616161717189D +:10B640001818171818171716161617171718191885 +:10B650001818181817171616161716171717181878 +:10B660001817171717171716171717171717181769 +:10B67000181717171617161616161616171718185E +:10B680001817181818171716161617171617181848 +:10B69000181818171716161616161616171818183B +:10B6A000181718171717171616161717161718172B +:10B6B0001717171616161515161616161617171726 +:10B6C0001818181717171616161717171718181807 +:10B6D00018171717161616161616161617171818FF +:10B6E00018181817171717161617181717171818E6 +:10B6F00018171717171716161617161616161717E0 +:10B7000018171817171616161516171716161718CE +:10B7100018171717161716161516151616161717C3 +:10B7200018171817171616161616161616161717B0 +:10B73000181717161617161616161616171717189F +:10B740001817171717161616161516161617171890 +:10B750001817171616161615161615161617171883 +:10B760001717171716161616161616171716171771 +:10B770001817171616161616161616161617171762 +:10B78000181717171716161716161617171717184C +:10B790001817171616151615161616161617181842 +:10B7A0001817171717161616161616161716161830 +:10B7B0001817161615161515151616161617171727 +:10B7C0001817161716161616151616161616171813 +:10B7D0001917161716161615151616161616171803 +:10B7E00017171616161516161516161616161717F7 +:10B7F00018161616161515151516151516161617EC +:10B8000019181717161616161516151616161718D0 +:10B8100019171616161516151516151616161718C5 +:10B8200019181717171616171516161616161717AE +:10B8300018171616161515151516151516161717A9 +:10B840001817161616151515151515161616171997 +:10B85000181715161615151515151515161617188A +:10B860001818171616151515151515161616171876 +:10B87000171716161515151515151515151517186D +:10B880001817171616151515141515161616171957 +:10B89000181716161615151514151415151517184D +:10B8A0001917171616151515141515161616171837 +:10B8B000181716161615151414151515151516172F +:10B8C0001817171615151516141515161616171917 +:10B8D000181716161615151415151415151617180C +:10B8E00018171716161515151414151516161718FA +:10B8F00017161615151514141515151515161617F2 +:10B9000018171616151514151414151616161718DB +:10B9100017171615151514141514141516161718CF +:10B9200018171616151515151414151515161618BD +:10B9300017161515151514141515141515161717B2 +:10B94000181716161515141514141515151617189D +:10B95000181716151515141414151415151617188F +:10B96000171716161515151614141515151616187D +:10B970001716151515151414151514151516171772 +:10B980001716161515141414141415161516171960 +:10B990001716151515151414141414141516161855 +:10B9A0001716161515141415141415151516171841 +:10B9B0001716151515151514151414151516161733 +:10B9C0001716161514141414151415151516171822 +:10B9D0001615151515141414141514151516161717 +:10B9E0001716161514141414141414151516161706 +:10B9F00016161515151515141415141414151617F7 +:10BA000017161515141414141414141515161717E5 +:10BA100016151515151514141415141515161617D5 +:10BA200016161515141414141414141415151617C9 +:10BA300015151514151414141414141414151616BD +:10BA400017161515141414141414151515161718A3 +:10BA5000161515151414141414141414141516179B +:10BA6000151615141414131414141414151516188B +:10BA7000161515141414141414141514141516177B +:10BA80001616151514141414141314141516171867 +:10BA9000171515151414141414141414141516175A +:10BAA0001B1B1A1919191918171818181818191909 +:10BAB0001B1A1A1A1A191819191919181919191AF1 +:10BAC0001B1A1A1919191817171818181919191AE9 +:10BAD0001B1A1A1919181818181818181819191AD9 +:10BAE0001B1B1A1A1A1A19181818191919191A1ABF +:10BAF0001B1A1A1A191819191817181818191919B8 +:10BB00001A1A1A191A1A19181819191919191A1B9F +:10BB10001A19191918181818171818181919191A9C +:10BB20001B1B1B1A1A1A1A1918191919191A1A1A79 +:10BB30001B1A1919191919181718181919191A1976 +:10BB40001A1A1A1A1A1A1A19181819191919191A5F +:10BB50001A1A191919191819171818181919191959 +:10BB60001A1A191919191918181819191919191A45 +:10BB70001A1919191918191917181818181819193C +:10BB80001B1A191A1919191918181919191A191A21 +:10BB90001B1A191919191919181818181819191917 +:10BBA0001A19191919191919181818191919181908 +:10BBB0001A191918181918181818181818181919FE +:10BBC0001A191919191919181818181919191919E8 +:10BBD0001A191918181918181818181718191919DE +:10BBE0001A1A1919191919181818181819191919C8 +:10BBF0001A191918181818181818181818181919BF +:10BC00001A19191919191918181718181919191AA8 +:10BC10001A1A19181818181818181818181819199D +:10BC20001A1A1A1919191918181818181819191987 +:10BC30001919181818181818171818171718181885 +:10BC40001A1919191918181818171718181919196D +:10BC50001A1919191818181818181818181819195D +:10BC60001A19191919191918191818181919191947 +:10BC70001A19181818181818181818181818181940 +:10BC80001A1919191919191818181718181919192A +:10BC90001A1919191919181818181918181819191A +:10BCA0001919181818181817181817181819191911 +:10BCB00019191919181818191819191818181919FB +:10BCC0001A191918181918181818181818191A1AEA +:10BCD00019181918181818181818181818191919DF +:10BCE00019191818181818171818181718181919D2 +:10BCF00019191818181717181818181818181919C2 +:10BD00001A19181818181817181918181818191AAD +:10BD10001A19191818171818181818181818191A9D +:10BD20001A19181818181818181918181818191A8C +:10BD30001A19181818181818181818171818181980 +:10BD40001A19181818181817171718181718191A71 +:10BD50001A19181818181818181718181818181960 +:10BD60001A19191818181818171718171818181951 +:10BD70001A19181817181718181818181818181941 +:10BD80001A19181818181818171717181818191A30 +:10BD90001A19181818181717181717181718181924 +:10BDA0001919181818181817181718181818191911 +:10BDB0001A19181817181717181818181718181903 +:10BDC0001A19181818181818181718181818191AEE +:10BDD00019191818171717171818181818181919E3 +:10BDE0001A191818181818171818171818181919D0 +:10BDF00019191818171817171818181818181819C3 +:10BE00001A19181818171817171717171818191AB2 +:10BE10001A1919181817181718181818181818199F +:10BE20001919181817171717171817171818191995 +:10BE30001918181818181817171718171818181984 +:10BE40001A19191818171717171818171718191A71 +:10BE50001A19191818181817171718181818181960 +:10BE60001A19181818181818171818171718181951 +:10BE70001919181818171717171818181817181944 +:10BE8000191817171717171717171717181818193A +:10BE90001918181817171717171717181817191927 +:10BEA000191817171817171717171717171818191A +:10BEB000191817171717161617171717171718180F +:10BEC00019181818181717171716171717181819F9 +:10BED00019181817171616161617171717171819EF +:10BEE00019181818181717171617171717171819DA +:10BEF00019181818171717161617171717171818CD +:10BF000019181817171716171617171817181819BA +:10BF100019181717171717161717171818181919A8 +:10BF2000191818171817161616161717171718199D +:10BF3000181817161717161617171818181818188C +:10BF4000181817171717161616161717171818197F +:10BF5000181817161717161617171718181819196B +:10BF60001818171717171616161617171717181960 +:10BF7000181817161717161617171717181819194C +:10BF8000181817171717161617171717161718193F +:10BF90001918181717171717171717171818191927 +:10BFA000181817171717171616171717161718191F +:10BFB000181817171717161617171717181819190B +:10BFC0001817171716161616161717171717181902 +:10BFD0001918171717171716171716171718191AEA +:10BFE00018181717161617161616171717171819E1 +:10BFF00018181717171717161717161717181819CD +:10C0000018181717161616161616171717171819C1 +:10C0100018171717171717161717171717181919AB +:10C0200018181717171717161616161717171818A0 +:10C03000181717171717171717171717171718188D +:10C040001817171716171616161616171717181982 +:10C05000171717171716171617171717171818196E +:10C060001818171716171716161616161717181862 +:10C070001717161616161616171717161617181856 +:10C080001818171716161616171616161717181942 +:10C09000181717171616171717171717171718192E +:10C0A0001817171616171616171616171717181922 +:10C0B0001817171616161717171717161717181910 +:10C0C0001817171716161616161516171817181903 +:10C0D00019181817161617171617171717171819EC +:10C0E0001B1C1C1B1A1B1B1A191A1A1A1A1A1A1AA9 +:10C0F0001C1B1A1A1B1A1A1B1B1B1B1B1B1B1B1B93 +:10C100001C1C1C1B1B1A1A1A1A1B1B1B1A1A1B1B82 +:10C110001C1B1B1B1A191A1A1A1A191A1B1B1B1B78 +:10C120001C1C1C1B1C1B1B1B1A1B1B1B1A1A1B1B5E +:10C130001C1B1B1B1C1B1B1B1A1A1A1B1B1B1B1B50 +:10C140001C1C1C1B1C1B1B1B1B1B1C1B1A1B1C1B3A +:10C150001B1A1B1B1A1A1A1B191B1B1B1B1B1C1B34 +:10C160001C1C1C1C1C1C1B1B1A1B1C1B1A1A1B1B1B +:10C170001C1B1B1B1B1A1A1B1A1B1B1B1B1B1C1B10 +:10C180001B1C1D1C1B1C1B1B1A1A1C1B1A1A1B1BFD +:10C190001B1B1B1A1A1A1A1B1A1A1B1B1B1B1B1BF5 +:10C1A0001B1C1C1C1B1B1B1B1A1B1C1C1A1A1B1BDD +:10C1B0001B1B1B1A1B1A1A1C1A1A1B1A1B1B1B1BD4 +:10C1C0001B1B1C1C1B1B1B1A1B1B1B1C1B1B1B1CBC +:10C1D0001C1B1C1B1A1A1B1B1A1A1A1A1B1B1B1BB3 +:10C1E0001B1B1C1C1B1B1B1A1A1A1B1B1A1A1B1BA2 +:10C1F0001C1B1B1A1A1A1A1B1B1B1A1B1B1B1B1B93 +:10C200001B1B1C1C1B1B1B1A1A1A1B1B1B1A1A1B81 +:10C210001C1B1B1A1A1A1A1B1B1B1A1A1B1B1B1B73 +:10C220001B1C1C1C1B1B1B1A1A1A1B1B1A1B1A1B60 +:10C230001C1C1B1B1A1A1A1B1B1B1B1B1B1B1B1B4F +:10C240001B1B1B1C1B1B1B1A1A1A1B1A1A1C1B1B41 +:10C250001C1C1B1B1A1A1A1B1B1B1B1A1B1A1A1B32 +:10C260001B1B1C1C1C1B1B1A1A1A1B1A1A1B1B1A21 +:10C270001B1B1B1A1A1A1A1B1B1A1A1A1A1A1A1B18 +:10C280001B1B1B1C1B1B1B1A1A1A1A1A1B1B1A1A04 +:10C290001B1B1B1A1B1B1A1B1B1B1A1A1B1B1B1BF2 +:10C2A0001B1B1B1B1B1B1B1A1A1A1B1B1A1C1B1BE1 +:10C2B0001B1B1B1A1A1A1A1A1B1A1A1A1A1B1B1BD7 +:10C2C0001B1B1B1B1B1B1B1A191A1A1A1B1C1B1BC3 +:10C2D0001B1C1B1B1A1A1A1A1A1A1A1A1A1B1B1CB5 +:10C2E0001B1A1B1B1B1B1B1A1A1B1B1A1A1C1C1BA1 +:10C2F0001B1B1B1B1A1A1A1A1A1A1A1A1A1B1B1B97 +:10C300001B1B1B1B1B1B1B1B1A1A1A1A1A1B1C1C80 +:10C310001B1C1B1A1B1A1A1B1B1A1B1A1B1B1B1B71 +:10C320001B1B1A1A1B1B1B1A1A1A1A1A1A1A1B1B66 +:10C330001B1B1B1A1A1A191A1A1A1A1A1A1B1B1B58 +:10C340001B1A1A1A1A1A1A1A1A1A1B1A1A1B1B1C47 +:10C350001B1B1B1B1B1A1A1A1B1B1A1A1B1B1B1B32 +:10C360001C1C1B1A1B1B1B1A1A1A1B1B1B1B1B1C1E +:10C370001B1B1B1A1B1B1A1A1A1A1A1A1B1A1A1A17 +:10C380001C1B1A1A1A1B1B1B19191A1A1A1A1B1B07 +:10C390001C1B1B1B1B1B1A1A1A1A1A1B1B1B1B1BF1 +:10C3A0001B1B1B1A1A1B1B1B1A19191A1B1A1B1BE6 +:10C3B0001C1B1B1B1A1B1A1A1A1A1A1B1B1B1B1BD2 +:10C3C0001B1B1A1A1A1B1A1A1A1A1A1A1A1A1B1BC8 +:10C3D0001B1B1A1B1B1A1A1A1A1A1A1B1B1B1B1BB4 +:10C3E0001B1B1A1A1B1B1A1A1B1A1A1A1A1B1B1BA5 +:10C3F0001B1B1B1B1B1A1A1A1A1A1A1B1A1B1B1B94 +:10C400001B1C1C1B1C1B1B1B1B1A1A1B1C1C1B1C78 +:10C410001B1B1B1B1A1A1A1A1A1A1A1B1B1B1B1C72 +:10C420001B1C1C1A1C1A1B1B1B1A1A1B1C1C1B1C5A +:10C430001B1B1A1B1A1A1A191A1A1B1B1B1B1B1B54 +:10C440001B1B1B1A1B1A1A1A1A1A191A1C1C1B1C42 +:10C450001B1B1B1B1B1A1A1A1B1A1A1B1B1B1B1B31 +:10C460001B1B1C1A1B191A1A1A1B1A1A1C1B1B1C21 +:10C470001B1B1A1B1B1A1A1A1A1B1A1A1A1A1A1B16 +:10C480001B1C1C1C1C1B1A1A1B1B1A1B1B1C1B1CF9 +:10C490001C1B1B1B1B1B1A1A1A1A1A1B1A1A1B1BF2 +:10C4A0001C1D1D1C1D1C1C1B1B1C1A1A1B1C1B1CD1 +:10C4B0001C1B1B1B1B1A1A1A1A1A1A1B1B1A1B1BD2 +:10C4C0001C1B1B1B1D1C1B1A1A1B1A1A1B1C1C1CB9 +:10C4D0001C1B1B1B1B1A1A1A1A1A1A1A1B1B1B1BB2 +:10C4E0001C1C1C1C1C1B1B1A1A1B1A1A1B1B1B1C9A +:10C4F0001C1B1A1A1A19191A1A1A1A1A1A1A1B1B99 +:10C500001B1B1B1B1B1A1A191A1A1A1A1A1B1B1C83 +:10C510001C1B1A1A1A1A19191A19191A1A1A1A1B7B +:10C520001B1B1B1B1B1B1A1A191A191A1A1B1B1C63 +:10C530001C1B1B1B1B1B1A1919191A1A1A1A1A1B56 +:10C540001B1B1B1B1B1B1A1A191A1B1A1A1D1C1C3E +:10C550001C1B1A1A1A1A1A1A1A1A1A1A1B1A1B1B35 +:10C560001B1B1D1C1C1B1B1A1A1A1B1A1A1B1C1C1A +:10C570001C1B1A191A1A19191A1A1A1B1B1B1B1B16 +:10C580001B1C1B1B1A1B1A1A191A1B1A1A1B1C1C00 +:10C590001C1B1A191A1A1A1A1A191A1B1B1B1B1BF5 +:10C5A0001B1B1B1B1B1B1A19191A1B1A1A1B1B1CE2 +:10C5B0001C1B1A191A1A1A1A1A1A1A1B1B1B1B1BD4 +:10C5C0001B1B1B1B1B1B1A191A1A1B1A1A1A1B1CC2 +:10C5D0001D1E1B1A1A1B1B1B1A1A1A1B1B1B1B1BAB +:10C5E0001B1B1B1B1A1B1B1A191A1B1A1A1B1C1CA0 +:10C5F0001C1B1A1A1A1A1B1A1A1A1A1B1B1B1B1B92 +:10C600001A1A1A1A1A1A1A191A1A1A1A1A1B1B1D86 +:10C610001D1A1A1A1A1A1B1A1A1A191A1A1A1B1B75 +:10C620001B1A1A1B1A1A1A1A191A1A1A1A1A1B1B67 +:10C630001C1B1A1A1A1A1A1A1A1A191A1A1A1B1B56 +:10C640001B1A1A1B1A1A1A1A1A1A1A1A1A1B1B1C44 +:10C650001B1A1A1A1A1A1A191A1A1A191B1A1B1B38 +:10C660001B1B1B1B1A1C1A1A1A1A1A1A1A1B1B1B21 +:10C670001B1C1A1A1A1A1B1A1A1A1A1A1A1A1B1B14 +:10C680001A1A1A1B1A1919191A1A1A1A1A1A1B1C09 +:10C690001B1B1A1A19191A1A1A1B1A1A1A1B1B1CF5 +:10C6A0001B1A1B1B1A1A1A1A1A1A1A1A1A1A1B1BE5 +:10C6B0001A1B1A1A1A1A1A1A1A1A1A1A1A1A1A1BD8 +:10C6C0001B1B1A1A1A1A19191A191A1A1A1B1B1CC7 +:10C6D0001B1A1B1A1A1A1A1B1A1A1A1A1A1A1B1BB5 +:10C6E0001A1A1A1A191919191A1A1A1A1A1A1C1CAA +:10C6F0001C1A1A1A1A1A1A1A1A1A1B1B1B1B1A1B93 +:10C700001B1A1A1A19191A1B1A191A1A1B1B1C1C84 +:10C710001C1B1B1B19191A1A1A1B1C1B1B1B1B1C6D +:10C7200006F0F15506F0F15506F0F15506F0F15519 +:10C73000402C2B2B2A2F2F2C2C34333131313134F8 +:10C740003040322F2E2C2B2A2B2C2C3131302F31F4 +:10C750003231322F322C2C2C2B2B2B2C2C313331F1 +:10C7600030333131312E312B2C2C2B2B2A2B2B2FEC +:10C77000312F2F302F2F2F2F2F2C2B2A2A2A2A2BE5 +:10C780002A2E2F302F302F2F2F2C2F2A2A282A2ADB +:10C7900029282A2D3030302F2F30312D2C2C2B2AC8 +:10C7A0002B2B2B2B282F2C2E2F2D2F2E2C2E2C2BC2 +:10C7B0002A292A2B2A2B2A2F302F2F2E2E2C2D2DB3 +:10C7C0002B2B2B292A2B2A2C2B333130312F2F2F97 +:10C7D0002D2B2B2A2A2A29292A282B2D2F2E2D2DA5 +:10C7E0002E2D2C2C2D2B2C2C2D2B2B2C2C2D30307E +:10C7F0002F2E2F2D2B2B2A2B2B2B2A2B2C2D2A3077 +:10C800002F30302F2D2D2C2A2C2A2A292A2A2A2C67 +:10C810002D2F2F2D2E2E2C2D2B2C2C29282A282A5B +:10C820002B2B2C2E2D2B2D2D2C2D2C2A2C29292851 +:10C83000282B2D2C2B2E2E2E2D2D2C2B2C2B292640 +:10C840002928292A2928292B2B2B2C2A2B2A2C2D45 +:10C850002C2A29292828282927292B292B2B2B2B3F +:10C860002A2C2B28272728282A29292C2C2C2C2A2B +:10C870002C2B2C2E2A2A292828292929292B2A2918 +:10C88000282929292B2F2A2A2A2928282A2A29290E +:10C890002928282828282B2C292929282728292B0A +:10C8A0002B2C2A2929292A2A292B292929292929EE +:10C8B0002929292A2929292828292A2C2A292828E6 +:10C8C00029292A2B2A2C292829282A29282C2A2ACE +:10C8D000292928292929292A292928292929292AC8 +:10C8E0002A292728292929292B2A2B2B2A292A2AB0 +:10C8F0002B2C292A29282829282929292A2A282AA3 +:10C90000292A2A2B292A272829282928292827279C +:10C91000292929292A2C2529282726272828272894 +:10C92000272827272827282A28282729272827298A +:10C930002926282A29282728272B2728272626277B +:10C9400026262627272626242727272B262928267A +:10C95000262728272725292628262627282A272963 +:10C960002827272727272827262527262627272A57 +:10C970002727272627272827282628262726262749 +:10C980002829262726262524262627272626252544 +:10C990002627272A25272626262626262625252534 +:10C9A0002525252526274025262524252526272615 +:10C9B0002523242525252640402A2D2D2E2E2F2CBB +:10C9C0002C313230303231343240302F30312E2F52 +:10C9D0002E2E2D323131323232343332312E2F2E4F +:10C9E000302E2B2D2C3230312F333334342F332F44 +:10C9F0002F2C2C2C2B2C2B3231303132343435313E +:10CA0000302E2F2E2E2D2D2C2C313331323432322C +:10CA1000312F312D2C2D2E2D2C2C2D2F333030302D +:10CA2000323233302D2F2F2F2D2F2E2D2D34313309 +:10CA3000353333322F2E2E2D2F2E2E2E2E2C2F31FE +:10CA4000313032323230302E2D2D2E2E2D2F2C2DF6 +:10CA50002F323230323231302F2D2F2E2E2F2F2EDB +:10CA60002E2E2F32313231313030302F2E2F2D2ECD +:10CA70002F2F2D2F2E2F3233323131302E2F2E2DBE +:10CA80002E2E2C2D2F2F3031333231302F2F2D2CB5 +:10CA9000312D2E2C2D2F302F30333031323231309A +:10CAA000302E2F2D2E2F2E2E2E2F2E313330313093 +:10CAB0002F31312D302D2F2F303032333034343070 +:10CAC00030302F2E2E2E2B2B2E2D2E2F2D2D2D2D8B +:10CAD0002F2C302E302D2F31312E2E2D2F2D302F6B +:10CAE000303331323030313231302F2D2D2E2D2E4A +:10CAF0002F2F30343132312F302F2E322F2D2D2D3C +:10CB00002C2E2D2D2D302F2D2F2F2E2E30312D2E42 +:10CB10002E2E2D2E2F2F2F2F2F2E2F2E2F2E2D2F2F +:10CB20002E2D2D2B2C2C303030312F2F2F2F2E2E21 +:10CB30002F312D2E2E2D2E2E2F2E2E2D2E2E2F2D13 +:10CB40002F2D2E302E2D2E2F302F3031312F2D2EF8 +:10CB50002F2D2E2D2C2E2E2E2D2D2E2F2F2E3030F4 +:10CB60002F302D2E2D2E2F2F2E2D2D2E2D2E2E2EE5 +:10CB70002F2D2E2E2E2C2E2D2D302D2D2D2C2D2EDD +:10CB80002E2E2E2E2E2E2F2E2F2F2F2E2D2E2E2DC3 +:10CB90002F302D2F302F2E2C2E2D2E2E2E30282DB7 +:10CBA0002E2B2C2C2D2C2D2C2E2E2D2C2E2D2C2EB8 +:10CBB0002D2C2B2D2C2B2C2D2E2D2D2E2D2C2D2EAA +:10CBC0002D2F2B2E2C2B2B2C2C2D2E2D2C2C2C2AA0 +:10CBD0002E2C2E2D2E2E2E2E2E2F2E2F2E2C2D2C7B +:10CBE0002B2B2E2E2C2D2C2E2D2D2D2D2D2D2F2C77 +:10CBF0002A2B2C2B2B2E2E302B2D2C2C2C2B2C2B74 +:10CC00002E2C2C2C2C2C2D2C2D2E2B2D2D2D2C2C5C +:10CC10002E2C2D2B2B2D2B2C2C2E2C2E2A2D2C2C50 +:10CC20002D2E2D2C2E2D2C2D2D2D2D2C2D2E402D21 +:10CC30002D2D2E2C2C2F32302D2C2F2D2F2C2D4006 +:10CC4000402D3231323334313234343335343538A7 +:10CC500034403032333333313231303133323536A0 +:10CC60003635363533323432323131312F32343396 +:10CC700031363536363534323232313130322F3783 +:10CC80003535353638363735343332323433313260 +:10CC90003034343436353634353434313030323063 +:10CCA000312E313335333435343435343235343450 +:10CCB000353437333335333636363635343532332B +:10CCC0003332323332313435363336353534343429 +:10CCD000303132333233323333363636363635331B +:10CCE00034333134343434353633383534343637FC +:10CCF00037353333323334343534343334363837EC +:10CD000035353636343530323434343534363735DB +:10CD1000353536353534322F3534333334323334D8 +:10CD200035373634353935353734383434343436AC +:10CD30003839373737373537373835313333353496 +:10CD40003435373536373936353735353333302F97 +:10CD50003232333333333135333635343634353498 +:10CD60003432343132343537343535373637373578 +:10CD7000363534313232343335353436363834366C +:10CD80003535353532343436363736363334373355 +:10CD9000323635343436323235353534333735354D +:10CDA000353533383533333434343432343438363B +:10CDB0003636353536353634333334343434353429 +:10CDC000363436353734333634323434333434341D +:10CDD0003536363836363635343636353334333400 +:10CDE0003333353433343435363436363333333500 +:10CDF00035353335333934393635383435363634DC +:10CE000034333434363635353535363333353535D8 +:10CE100035353432343434333635343735373734C6 +:10CE200036393636343430333333333333333333C4 +:10CE300034333435363333353333333537333538AC +:10CE4000363335333335343434342F3535333636A1 +:10CE50003435353533313232333333353335343499 +:10CE60003436353433343532343334353334333681 +:10CE7000353436353537343432323434343534356C +:10CE80003335333333353434343435333433343366 +:10CE90003435333437343435353333343332343452 +:10CEA0003335363637343434343637353434363433 +:10CEB000363434343534403D373937393C463935EA +:10CEC0003638333339333340403A353638363736EF +:10CED00034393A373A3A3A3D3D403E3F3F3E3738A3 +:10CEE000373636383837383D3D3A3A3937383A36BA +:10CEF0003635333535383837373C3A3B3B393937B7 +:10CF0000383637363637353A3B38383B3B3A38389F +:10CF100039393938393B363936393D3B3C3B3C3A77 +:10CF20003C38393538383737383536363B38393884 +:10CF3000383A3938353A393A393B3837353E393F5E +:10CF40003A3C3D3B383A373739393A38383A373A4C +:10CF50003A393C3B3C3C3A3834373837393B38383F +:10CF6000373A3C3D3C3E3E3C3A353739393B39391E +:10CF700037383B393B393B3E3B3B393A3739393B14 +:10CF8000393A3A3B3D3A3F3D3D3B3C3B393A3539F6 +:10CF9000393A3A3A3938393A3C3C3B3C3C3A3736F4 +:10CFA0003A39393A38393A3A3F3A3C3B3C3C3B3CD7 +:10CFB00039383B3A393C3A3D3A3B3D3C3C3D3B3DC0 +:10CFC0003E3B3C363A393C3A393C3C3B3D3A3C3AB4 +:10CFD0003D3B3D3D3C3A34373B393B3B39393839B1 +:10CFE0003B3B3B3C3E3B3A383A393A3A3B383738A0 +:10CFF000383B3B38393B3E3B38393A383A393A3896 +:10D00000373A3C3C3B3D3D393D3C383A393B3B3A75 +:10D010003C3D373A3A3A3A3A3B3D3C3C3C3A393A65 +:10D020003B3C3B3A393C3C3B3A3B3D3B3E3A3B3A4E +:10D03000393A3A3A383C3B3E3D3C3B3C3C3C3D3C3B +:10D040003B3A393C3D3B3B3E3A3C3A3C3A393C3B2F +:10D050003B3A3B3A3C3A3B3C3A3A3B3D403C3D3E16 +:10D060003B3B3D3A3A3A393A3B3B3A3A393A393A1C +:10D07000393A3B3E3C3C3B3B3C3C3A393B3B3A3CFF +:10D080003D3E393C3C3B3D3C39393B3B3D3D3B3BE8 +:10D090003A3B3D3A3A3A3B3B3B3A3B373B3A3B3BE8 +:10D0A0003E3B3A3D3A3B393B3C3B3E3C3A3B353DCF +:10D0B0003C3839383A39363C3C3A3C3C3D3B3B3CC9 +:10D0C0003A3B3A3B3A393B393D393A3E3C3B3A3CB4 +:10D0D0003B39373D3B3B38393A383B3A38383C3AB4 +:10D0E0003E3A3A3A373E3D3C3C3C3C3F3B3B3C3B86 +:10D0F0003A3A3D3B3B3C3A3E3C3D3C3B3D3C3B3D74 +:10D1000039393B3B3B3B3C3D393B3C393E393C3C70 +:10D110003D3B3A3C3C3A3C3D3B3A3A3D3A3D3B385C +:10D120003E393D3C3B3D3C3C3C3D3B3A393D3F403C +:10D130003F3E3D3C3E3B3B3C3E3F3F3D3D3B404117 +:10D14000404444474041403F3E3D3D3D413F3D40DE +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000004806108000488610800048061F800044 +:10D3C00048861F800048061180004886118000486A +:10D3D000061E800048861E8000480612800048868F +:10D3E00012800048061D800048861D8000480613F4 +:10D3F0008000488613800048061C800048861C80F8 +:10D40000004806148000488614800048061B8000EF +:10D4100048861B8000480615800048861580004815 +:10D42000061A800048861A80004806168000488642 +:10D4300016800048061980004886198000480617A3 +:10D4400080004886178000480618800048861880AB +:10D4500020001904902000320887200032C8802064 +:10D4600000325882200032E8832000327885200084 +:10D470003208872000196890200019889320000244 +:10D48000F44B200002044C200019F89120001918D8 +:10D4900095200002F44B200002044C20001938981B +:10D4A000200032A8962000326890200032F89120A7 +:10D4B000003288932000321895200032A896000090 +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D54000010090010201060A640028324600000032 +:10D5500000000000000000003C0000004006000049 +:10D5600034080000A0A0010101011900010014000D +:10D5700001001600E4000A00001478000032780070 +:10D580000000002032323232323232323232323223 +:10D59000323232323232000000000000000000005F +:10D5A000000000000000000034083408F40100000E +:10D5B0000209200019450000F16C000084D9060022 +:10D5C00029B1010010270000C409000000014B0F21 +:10D5D00000000000000000003C3C0A0A02000000BD +:10D5E0000000000001010101010040003200E803D9 +:10D5F0000F0008000A0010001000020202000300E1 +:10D6000003000A0006006400E803000004000000B4 +:10D6100000000000000000000101010101004000C5 +:10D620003200E80314000F000A00E10000000808BF +:10D630000A0028001E001E0006006400E803000027 +:10D640000400000000000000000000004006300060 +:10D6500020000100220000003A00520070008F00FC +:10D66000AF00CF00EF000F012E014F016E018E01C0 +:10D67000AD01CE01EC010F022D024D026D028D02B3 +:10D68000AC02CC02EB020B032B034A036A038903AF +:10D69000AA03C903E703FF033704000000000000EA +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000280AD7 +:10D72000300046000100480000003C004300660055 +:10D730008500A900C800E90009012A0149016B011F +:10D740008901AB01C901EB0109022B024A026C02FB +:10D750008A02AC02CA02EC020B032D034B036D03D9 +:10D760008B03AE03CB03EE030C042F044C046F04B5 +:10D770008B04AF04CC04EF040D0530054D05700596 +:10D780008D05B005CD05F1050D0630064E06720675 +:10D790008E06B106CE06F2060F0732075007730752 +:10D7A0009007B307D107F407110834085208750829 +:10D7B0009108B108C608E70800000000000000005A +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F00000000000080009000B000D000F001200DF +:10D80000150018001D00210027002D0034003C00E9 +:10D81000450050005C006900780089009C00B10060 +:10D82000C900E3000001210145016C019701C70116 +:10D83000FB0134027102B402FD024B03A003FA03A0 +:10D840005C04C3043205A7052406A8063207C407F2 +:10D850005C08FC08A2094E0A000BB80B750C360DCB +:10D86000FC0DC50E910F5F102E11FD11CC129A13F5 +:10D8700065142C15EF15AD1664171418BB1859193B +:10D88000ED19761AF21A621BC41B191C5E1C951C3A +:10D89000BC1CD41CDC1C080009000B000D000F0090 +:10D8A0001200150018001D00210027002D00340073 +:10D8B0003C00450050005C006900780089009C0035 +:10D8C000B100C900E3000001210145016C0197018D +:10D8D000C701FB0134027102B402FD024B03A00335 +:10D8E000FA035C04C3043205A7052406A806320720 +:10D8F000C4075C08FC08A2094E0A000BB80B750CA3 +:10D90000360DFC0DC50E910F5F102E11FD11CC12BE +:10D910009A1365142C15EF15AD1664171418BB185F +:10D920005919ED19761AF21A621BC41B191C5E1CD8 +:10D93000951CBC1CD41CDC1C080009000B000D004D +:10D940000F001200150018001D00210027002D00F7 +:10D9500034003C00450050005C00690078008900FC +:10D960009C00B100C900E3000001210145016C01E8 +:10D970009701C701FB0134027102B402FD024B039F +:10D98000A003FA035C04C3043205A7052406A80615 +:10D990003207C4075C08FC08A2094E0A000BB80B4A +:10D9A000750C360DFC0DC50E910F5F102E11FD117B +:10D9B000CC129A1365142C15EF15AD1664171418B4 +:10D9C000BB185919ED19761AF21A621BC41B191CDF +:10D9D0005E1C951CBC1CD41CDC1C080009000B0040 +:10D9E0000D000F001200150018001D002100270077 +:10D9F0002D0034003C00450050005C0069007800B8 +:10DA000089009C00B100C900E3000001210145012B +:10DA10006C019701C701FB0134027102B402FD02DF +:10DA20004B03A003FA035C04C3043205A7052406D4 +:10DA3000A8063207C4075C08FC08A2094E0A000BBE +:10DA4000B80B750C360DFC0DC50E910F5F102E1125 +:10DA5000FD11CC129A1365142C15EF15AD16641731 +:10DA60001418BB185919ED19761AF21A621BC41B47 +:10DA7000191C5E1C951CBC1CD41CDC1C0A000B0071 +:10DA80000E0010001300160019001D0022002800CF +:10DA90002E0035003D00460051005C006900780012 +:10DAA00089009B00B000C700E100FD001C013F01A0 +:10DAB00065018E01BC01EE0124025F029F02E402B7 +:10DAC0002F037F03D60332049504FE046D05E3059E +:10DAD0006006E3066D07FE0795083309D609800A3C +:10DAE0002F0BE30B9B0C580D180EDB0EA10F6810CB +:10DAF0002F11F711BE12841346140515C0157516A3 +:10DB00002417CC176B1801198E190F1A851AEF1AE2 +:10DB10004D1B9D1BDF1B121C381C4E1C551C0A0084 +:10DB20000B000E0010001300160019001D0022004B +:10DB300028002E0035003D00460051005C006900C1 +:10DB4000780089009B00B000C700E100FD001C01C7 +:10DB50003F0165018E01BC01EE0124025F029F02BC +:10DB6000E4022F037F03D60332049504FE046D05FF +:10DB7000E3056006E3066D07FE0795083309D6093D +:10DB8000800A2F0BE30B9B0C580D180EDB0EA10F18 +:10DB900068102F11F711BE12841346140515C01515 +:10DBA00075162417CC176B1801198E190F1A851AC0 +:10DBB000EF1A4D1B9D1BDF1B121C381C4E1C551CE5 +:10DBC0000A000B000E0010001300160019001D00C3 +:10DBD000220028002E0035003D00460051005C0068 +:10DBE0006900780089009B00B000C700E100FD00DB +:10DBF0001C013F0165018E01BC01EE0124025F02A0 +:10DC00009F02E4022F037F03D60332049504FE042F +:10DC10006D05E3056006E3066D07FE079508330909 +:10DC2000D609800A2F0BE30B9B0C580D180EDB0E48 +:10DC3000A10F68102F11F711BE1284134614051599 +:10DC4000C01575162417CC176B1801198E190F1AE9 +:10DC5000851AEF1A4D1B9D1BDF1B121C381C4E1C16 +:10DC6000551C0A000B000E001000130016001900CE +:10DC70001D00220028002E0035003D004600510006 +:10DC80005C006900780089009B00B000C700E100DB +:10DC9000FD001C013F0165018E01BC01EE01240263 +:10DCA0005F029F02E4022F037F03D6033204950430 +:10DCB000FE046D05E3056006E3066D07FE079508A3 +:10DCC0003309D609800A2F0BE30B9B0C580D180E55 +:10DCD000DB0EA10F68102F11F711BE12841346142A +:10DCE0000515C01575162417CC176B1801198E1958 +:10DCF0000F1A851AEF1A4D1B9D1BDF1B121C381CB7 +:10DD00004E1C551C29002F0035003B0043004C00E1 +:10DD100055005F006B00780086009500A600B900F2 +:10DD2000CD00E300FC00160133015201740199019A +:10DD3000C001EA01180249027D02B602F102310374 +:10DD40007503BC0308045804AD0406056305C50546 +:10DD50002B06960605077807EF076B08EB086E0998 +:10DD6000F4097F0A0C0B9B0B2E0CC20C580DEF0D07 +:10DD7000870E1F0FB80F4F10E6107B110E129E1268 +:10DD80002B13B4133814B8143315A71516167D16B3 +:10DD9000DD1635178517CD170B1841186D1890181B +:10DDA000A918B718BC1829002F0035003B00430004 +:10DDB0004C0055005F006B00780086009500A600BF +:10DDC000B900CD00E300FC001601330152017401DB +:10DDD0009901C001EA01180249027D02B602F1026E +:10DDE00031037503BC0308045804AD04060563053C +:10DDF000C5052B06960605077807EF076B08EB08A5 +:10DE00006E09F4097F0A0C0B9B0B2E0CC20C580DEB +:10DE1000EF0D870E1F0FB80F4F10E6107B110E127B +:10DE20009E122B13B4133814B8143315A7151616F5 +:10DE30007D16DD1635178517CD170B1841186D188F +:10DE40009018A918B718BC1829002F0035003B00FE +:10DE500043004C0055005F006B0078008600950081 +:10DE6000A600B900CD00E300FC0016013301520109 +:10DE700074019901C001EA01180249027D02B6024B +:10DE8000F10231037503BC0308045804AD04060510 +:10DE90006305C5052B06960605077807EF076B088F +:10DEA000EB086E09F4097F0A0C0B9B0B2E0CC20CBD +:10DEB000580DEF0D870E1F0FB80F4F10E6107B1196 +:10DEC0000E129E122B13B4133814B8143315A71561 +:10DED00016167D16DD1635178517CD170B18411848 +:10DEE0006D189018A918B718BC1829002F00350014 +:10DEF0003B0043004C0055005F006B00780086003B +:10DF00009500A600B900CD00E300FC001601330126 +:10DF1000520174019901C001EA01180249027D020F +:10DF2000B602F10231037503BC0308045804AD04C2 +:10DF300006056305C5052B06960605077807EF0756 +:10DF40006B08EB086E09F4097F0A0C0B9B0B2E0C77 +:10DF5000C20C580DEF0D870E1F0FB80F4F10E610B3 +:10DF60007B110E129E122B13B4133814B8143315F0 +:10DF7000A71516167D16DD1635178517CD170B1844 +:10DF800041186D189018A918B718BC1855005500FD +:10DF900045004200000000001C02370254027202D9 +:10DFA0009002B002D102F30216033A035F03850325 +:10DFB000AC03D503FF03290455048204B004DF0435 +:10DFC0000F0540057205A505D9050E0644067A061B +:10DFD000B206EA0622075C079607D0070B08470837 +:10DFE0008308BF08FB0837097409B009ED09290A3D +:10DFF000650AA10ADC0A170B510B8B0BC30BFB0B39 +:10E00000330C690C9E0CD20C040D360D650D940D6D +:10E01000C10DEC0D150E3D0E630E870EA80EC80E39 +:10E02000E60E010F1B0F320F460F590F690F760FC7 +:10E03000820F8A0F900F940F950FBA04C904D80469 +:10E04000E704F604050514052305320541055005CE +:10E050005F056E057D058B059A05A805B705C50505 +:10E06000D405E205F005FE050C0619062706340660 +:10E0700042064F065C066906760682068F069B06F8 +:10E08000A706B306BE06CA06D506E006EB06F606E8 +:10E0900000070B0715071E07280731073A07430734 +:10E0A0004C0754075C0764076C0773077A078107FE +:10E0B00087078D07930799079E07A307A807AC0753 +:10E0C000B107B407B807BB07BE07C107C307C50739 +:10E0D000C707C807C907CA07CB07CB07FA006C00F8 +:10E0E000FA006B006400D007000028000000000068 +:10E0F0000000000000000000000000000000000020 +:10E100000200190050001E001E000C001900000043 +:10E110000100000001000000948D0300508D0300F9 +:10E12000948D0300548D03000100000078563412D2 +:10E1300078563412014040000100000070AD02002A +:10E14000FFFFFFFFAA0000001033030007000000DC +:10E1500001000000FFFFFFFFFFFFFFFFFFFFFFFFCA +:10E1600001000000FF0000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F00000926D20324006000A0E0A0001030108102A +:10F0100032004006280A0000000C01000000000039 +:10F020000013535904060000000000000008010905 +:10F03000000132344006000028191A0000000800C0 +:10F0400000000800000008000000080000000800A0 +:10F05000000008000000080000000800F0EF0000B9 +:10F06000000008000000080000000800F0EF0000A9 +:10F070000000080000000800000008000000000078 +:10F08000000101000000000000000000000000007E +:10F09000000000000000000000000101010101006B +:10F0A0000001010000000101010100010000000059 +:10F0B0000100000102000000070000000107010339 +:10F0C000020314000A0A4000000078003C0000001F +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000C800C8009600C80032 +:10F0F00007078000800005050000000000000000F8 +:10F1000006010000000017003900910010001400F3 +:10F11000F9FFC4FFFF7FFF7FFF7FFF7FFA002C0115 +:10F120003200C8000A04B4B43232230500000000E3 +:10F1300000070D0000320D00000000203232323294 +:10F140003232323232323232323232323232000003 +:10F1500000000000000000000000000000000000AF +:10F160000A05000A00000000140F0012101200002F +:10F17000000000000000000000000000000000008F +:10F18000000000000F233246500000006A64504621 +:10F190003C3C3C3C08000000000000000F233246CD +:10F1A000500000006A6450463C3C3C3C0F141E2852 +:10F1B000000000000A0A0A0A0A0A0A0A0C192D416C +:10F1C0005000000046554B464646464600000000AB +:10F1D0000A0314005F00F1FF14000F000A00BC02D4 +:10F1E00000000000F8FF00007800320064002800F2 +:10F1F0000F000F001C023D011C02740400003F06BA +:10F200000000FF09F40100003F060000FF0932146E +:10F21000021E1E32020096003C003C007700C8052A +:10F22000770088090000000040063000200001003F +:10F23000220000003A00520070008F00AF00CF00A3 +:10F24000EF000F012E014F016E018E01AD01CE01C5 +:10F25000EC010F022D024D026D028D02AC02CC02B8 +:10F26000EB020B032B034A036A038903AA03C903B6 +:10F27000E703FF0337040000000000000000000067 +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F00000000000000000000000280A3000460066 +:10F300000100480000003C00430066008500A900A1 +:10F31000C800E90009012A0149016B018901AB011B +:10F32000C901EB0109022B024A026C028A02AC02FB +:10F33000CA02EC020B032D034B036D038B03AE03D8 +:10F34000CB03EE030C042F044C046F048B04AF04B6 +:10F35000CC04EF040D0530054D0570058D05B00595 +:10F36000CD05F1050D0630064E0672068E06B10675 +:10F37000CE06F2060F073207500773079007B30750 +:10F38000D107F40711083408520875089108B1082C +:10F39000C608E708000000000000000000000000B0 +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D0000201200019450000F16C000084D90600EC +:10F3E00029B1010010270000C4090000000101013B +:10F3F000010102020202014B0F00A0000000000008 +:10F400000100010101010102020202001945000090 +:10F4100002000000A46B00000000000014140A0A9F +:10F420001400000000000000141414140101010174 +:10F43000010040003200E8030F00080005009000C2 +:10F4400000001E502800B40050000400000000001E +:10F45000B4005000FA00A000000000014F010000BD +:10F460000000000068010D0D0A094B004B0064000C +:10F470000A003200C800640064000F02E8E8F800E7 +:10F48000F8000200190000006A00750081008E007B +:10F490009D00AC00BD00CF00E200F7000D01260189 +:10F4A00040015C0179019901BC01E00106023002D2 +:10F4B0005B028902BA02EE0224035D039A03D903B8 +:10F4C0001B046004A904F40443059505E9054106FD +:10F4D0009C06FA065B07BE0724088D08F808650934 +:10F4E000D409450AB80A2D0BA20B190C900C080D73 +:10F4F000800DF80D6F0EE60E5C0FD00F4210B310AA +:10F5000021118C11F4115912BA1217137013C4136C +:10F5100013145D14A114E01418154B1577159C15E0 +:10F52000BB15D415E515EF15F31536003D00440065 +:10F530004C00560060006B00770085009300A4002B +:10F54000B500C900DE00F5000E0129014601650184 +:10F550008701AC01D401FE012B025B028F02C602BF +:10F5600001033F038003C6030F045D04AE040305DB +:10F570005D05BA051B068106EA065707C9073D085F +:10F58000B6083109B009320AB70A3E0BC70B520C54 +:10F59000DF0C6D0DFC0D8B0E1A0FA80F3610C3106B +:10F5A0004D11D6115B12DE125C13D7134D14BD142E +:10F5B00028158D15EC1544169516DE161F175817CD +:10F5C0008917B117D117E717F517FA174E0056002C +:10F5D00060006B00760083009100A000B100C200C3 +:10F5E000D600EB0002011A013501520170019101B0 +:10F5F000B501DB0103022E025C028D02C102F8029A +:10F6000032036F03B003F4033B048604D4042605DD +:10F610007C05D50532069206F5065C07C607330859 +:10F62000A30816098C09040A7E0AFA0A790BF80B5A +:10F63000790CFB0C7E0D010E830E060F870F071051 +:10F64000861003117D11F5116912DA124713AF13F9 +:10F6500013147214CB141E156B15B215F2152C165B +:10F660005E168916AC16C716DB16E716EB166A008F +:10F67000750081008E009D00AC00BD00CF00E2004F +:10F68000F7000D01260140015C0179019901BC01DF +:10F69000E001060230025B028902BA02EE02240394 +:10F6A0005D039A03D9031B046004A904F404430511 +:10F6B0009505E90541069C06FA065B07BE07240886 +:10F6C0008D08F8086509D409450AB80A2D0BA20B64 +:10F6D000190C900C080D800DF80D6F0EE60E5C0FE6 +:10F6E000D00F4210B31021118C11F4115912BA121B +:10F6F00017137013C41313145D14A114E014181518 +:10F700004B1577159C15BB15D415E515EF15F3159D +:10F7100055005500450042000000000000000000B8 +:10F7200000000000000000000000000000000000D9 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000000000099 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F86000000000000000000000000000A000D20026 +:10F8700004013C0005000000000000000000000042 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF000000000000000000000000000004E565409 +:00000001FF diff --git a/firmware/novatek_nt36523_mp02.bin.ihex b/firmware/novatek_nt36523_mp02.bin.ihex new file mode 100644 index 000000000000..4151fb12ed4f --- /dev/null +++ b/firmware/novatek_nt36523_mp02.bin.ihex @@ -0,0 +1,12291 @@ +:100000000002000000000000DF7B01000020020071 +:100010000000020067C10000E3F6EFD77D4DB56B2D +:1000200003000000000000000000000000000000CD +:100030000000020000000000002002003B944F0C72 +:10004000000A020000000000002A0200CB94D02029 +:10005000003202000000000000520200AF0FDC1569 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F00068C10200FF00000000000000052A356111 +:100100000002000000000000DF7B01000020020070 +:100110000000020067C10000E3F6EFD77D4DB56B2C +:1001200001000000000000000000000000000000CE +:100130000000020000000000002002003B944F0C71 +:10014000004A020000000000006A0200AF0FDC1548 +:10015000007202000000000000920200AF0FDC15E8 +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00068C20200FF00000000010000DF7036420C +:10020000480001A2EAC20000EAC20000EAC20000FF +:10021000EAC20000EAC20000EAC20000EAC200002E +:1002200048000000DD4E0000EAC00000EAC0000007 +:10023000DD4E0000EAC00000DD4E0000DD4E000093 +:10024000DD4E0000DD4E0000DD4E0000DD4E000002 +:10025000DD4E0000DD4E0000DD4E0000DD4E0000F2 +:10026000EAC00000EAC00000DD4E0000DD4E0000E4 +:10027000DD4E0000EAC00000EAC00000DD4E0000D4 +:10028000DD4E0000DD4E0000DD4E0000DD4E0000C2 +:10029000DD4E0000DD4E0000DD4E0000DD4E0000B2 +:1002A000DD4E0000DD4E0000DD4E0000DD4E0000A2 +:1002B000DD4E0000DD4E0000DD4E00004800000075 +:1002C00048000000DD4E0000DD4E0000DD4E000065 +:1002D000DD4E00004800000048000000480000001B +:1002E00048000000480000004800000048000000EE +:1002F00048000000480000004800000048000000DE +:1003000048000000480000004800000048000000CD +:1003100048000000480000004800000048000000BD +:1003200048000000E8040000E8040000580700004E +:100330001E1600001E1600001E1600001E160000ED +:100340001E1600001E1600001E1600000000000011 +:100350001809000020090000E4090000A80A0000B4 +:10036000EE0A00009A0B0000FA0B0000180C0000C7 +:10037000200C0000280C0000300C0000380C00009D +:100380004A0C0000520C00005E0C000064110000DA +:10039000700C0000580D0000A00D0000A80D00001A +:1003A000FA0D00000C0E00001E0E0000440E0000AE +:1003B000E60E0000620F00006A0F00007C0F0000D4 +:1003C000581300005A1300007C130000841300002F +:1003D0008C1300009C1300009E130000AA13000061 +:1003E000B8130000D413000000000000000000005B +:1003F000521500006E150000BA150000001600002E +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:100450003A0FEFFC421E80203A1F883C6412A4022F +:10046000642204023A1F883C803F640264029205C1 +:1004700096374420012C38210202643200029ED9B2 +:1004800064320003DD2264020043640000083A1F66 +:1004900088046412A403642204033A1F8804421EE1 +:1004A00080213A0FEFC4640000043AFFECBC3A0F1D +:1004B000943C421E80203A1F883C640264029205EC +:1004C00096374420012C382102028E09DD223A1F82 +:1004D0008804421E80213A0F94043AFFEC846400A1 +:1004E00000043AFFECBC3A0F943C421E80203A1FB5 +:1004F000883C6412A402642204023A1F883C64020D +:100500006402920596374420012C382102028E099C +:10051000643200029ED964320003DD22640200438B +:10052000640000083A1F88046412A40364220403D0 +:100530003A1F8804421E80213A0F94043AFFEC844B +:10054000640000044FF200223A0FEFFC421E8020AC +:100550003A1F883C45D2D770801F64126402965FB0 +:100560009E49C1053CFD4A6D480000043CFD4A6EB1 +:10057000E80CDD2F4E03000A3A1F8804421E80213A +:100580003A0FEFC464000004640224024410C00067 +:10059000FE0FFE0D640224036400000845D2D770EC +:1005A00045F2FE006400800292189604C0054401E2 +:1005B0004D5C420E002144F004BAE802DD2F3CFD00 +:1005C0004A6FDD2F640FFFEAFC004462EDE4440251 +:1005D000C36884209AB0EA41EA43AE31FC80FC0053 +:1005E00084003C0FFB78EB733C0FFB873C0FFB8BCD +:1005F000EB7D3C0FFB9C3C0FFB813C0FFB8C3C0FCD +:10060000FB883C0FFB943C0FFB893C0FFB853C0FA8 +:10061000FB823C0FFB7B3C0FFB9A3C0FFB9F3C0F8C +:10062000FB923C0FFB933C0FFB903C0FFB76EB1DCA +:100630003C0FFB8A3C0FFB80EB69EAA93C0FFB7D7A +:100640003C0FFB7F3C0FFB9E3C0FFB913C0FFB994B +:100650003C0FFB863C0FFB7C3C0FFB8E3C0FFB7E74 +:100660003C0FFB8D3C0FFB953E07EC7B64030003C6 +:10067000EA6BEB6664122402964C8040C10364036B +:100680000003642224036402000266000006640280 +:100690000003640000086403040246029C1050003A +:1006A000007CEA6B6403080244000633EB666402D4 +:1006B0000002EA5464020003FC804403F0EDA6400B +:1006C0005A1801048420AE404413F0DAA608EBA0C7 +:1006D000AE088404EA6B84254403F049AE4044101C +:1006E0000053DD46AE40DD9EDD9E4443F114B4640C +:1006F000927840000F04B6044403F138AC408420E3 +:100700004403F13AAE404403F104B640842144036B +:10071000F136AE40F808A640964CC103AED0D5FCE9 +:100720004413F134EA38EA3783FFA608960EC8036B +:10073000AED0D5FC4403F134A6009604DD9E84A01F +:10074000D20738301400383094088CA1D5FADD9ED9 +:10075000FC00DD41C00C8407DD4A8400DD4A441200 +:10076000C2688402804144300100DD44FC80FC000A +:1007700080C0DD41C012441FFF9FEBBDAE409630EC +:100780004412FE61AE08EB6A4412FE62AE08DD461A +:10079000DD47C603AE40D5FEFC80FC403C7DFB4DF2 +:1007A0008140DD41C05B852384C03C2DFB4D402151 +:1007B0002480A051C108F85C5A0801064010240C9E +:1007C000FF8F97B18D215A980FF2F85F5A080104F4 +:1007D00042633C088387B97DB87C8E249649BA7FF2 +:1007E000F85C5A08010558630001D502C6055AA8ED +:1007F000AE048006F8118420EB1BAE404402FE6379 +:10080000A6408420AE40A681AE41490010095A0896 +:1008100001065803000249FFFFACEA70EA28EA210A +:10082000A78097B05A600204AE88D5FB4472FEF1EF +:10083000A6385A008608440000C1DD42F87FAE4069 +:10084000D5FF4900372384003E07EE7580278006D8 +:100850004422C5E58461DD44FCC05AA8AE4B84E364 +:1008600080C03C2DFB4D40211C80A051C10BB40227 +:100870009649A093F8125A08010640001C0CFF8705 +:1008800097B18CE15A780FEF3C2DFB4D8382B93D37 +:10089000B83C8E249649BA3F49FFFF295A08010502 +:1008A000EA6E42633C0884204402FE78AC40441265 +:1008B000FEF1EA70C619442FFFEEAE888422AE40E6 +:1008C0004412FE60440FFF8FAE084422FE61963052 +:1008D000AE10EB6A96004422FE62AE108463804143 +:1008E0008402DD44D520442FFF86AE888422D507BC +:1008F000441FFF86EB1BAE408422EA70AE404403E7 +:10090000F007A6004412FE639600AE084403F0040C +:10091000A6004422FE649600AE10840280418060EE +:10092000DD4484C04412FEF1804184618402DD44D0 +:10093000EA25804184028461DD44DD46DD4783FF92 +:10094000C603AE40D5FE4412FEF1EA38EA37A608E7 +:10095000C003AED0D5FDFCC03A6FA0BC840080209F +:1009600049006BF184006405E403EBA6A44096669D +:100970009649C102D5004422FEF6AE50A440964EE0 +:10098000C910A4409656C90DA440965EC90AA44059 +:100990009666C907A4405410810096494E120085FE +:1009A0004413F00EA408960EC806A58854630100EF +:1009B00097B1C6208400EAB2A788AC0844138D2002 +:1009C0003E07EC26AE0844138D21AE0844138D2259 +:1009D000AE0844138D23AE0844138D24AE0844138F +:1009E0008D25AE0844138D26AE0844138D2797B08D +:1009F000AE0849FFFDEB49000DA3EBA6A440964EBF +:100A0000C908A4409666C905A40054000100C003AB +:100A100049003472EBBD8420AC404472C16884004C +:100A2000EAA93C7FFB4DEB693C0FFB96DD41C80515 +:100A3000507381003C7FFB4D49FFFE8C800649FFCF +:100A4000FEAE8423EA70AE4084014413F7D3AE08AF +:100A50004413F7D9AE08FA56EA854412FE7849FFE6 +:100A6000FE703C0DFB4D4432FE7C040000093E0745 +:100A700028AD401020093E1728AE401040099218BA +:100A80003E1728AF3E0728B04422FE7DF8054432C9 +:100A9000FE7E4422FE7FA618A6509602964AAE58C5 +:100AA000AE1083FFD508A40054000200C0048402E5 +:100AB00049000F514413F029A608EAE0AE0884006B +:100AC000EA613C0DFA6A4413F00EA648EB8C44131D +:100AD000F00FA6481010003D490034763C0FFB5B38 +:100AE000FA044900546DFA044900546A2E07ED6C6B +:100AF000DD4AEA449E81E648E80B84214010880CD8 +:100B00005410808FC10550007FE09600DD424900FF +:100B100006B03A6FA084DD9E84013C0FFB78DD9E19 +:100B20003BFFFEBC3C0DFB838C01EB73DD455A089B +:100B30000246DD40A6015A08033EDD535A08023B37 +:100B4000DD41C03C2E07EBFDE603E8038C01D50236 +:100B500084003E07EBFD2E37EBFD4402E5D8EB5158 +:100B600040000CE0EAA2EA86EAA2EA86EAA2EA8665 +:100B70003B0044003B00C4205A3801068400EAD9F7 +:100B8000EBD4D5098406EB764400007DEBF18401BB +:100B9000EAD9EBBEEAA49E41E622E9035A08040F13 +:100BA00049004AD449009496C0098400EA3BEB11FD +:100BB000D505DD41C0038400EB182E07EF565A0817 +:100BC00001103C1DFB832E07EF55E220E803EBBE2E +:100BD000D507EBD48400EAD984003E07EF563BFFEB +:100BE000FE84DD9E3BFFFEBC3C0DFB878C013C0F71 +:100BF000FB87DD455A000221DD40A6005A00021D98 +:100C00005A00051B2E07EC2E8C019600E606E9150E +:100C100084003E07EC2EEBAADD40842EAE418426F4 +:100C2000AE408421DD57842084618402804180812C +:100C300080A3DD55D50484003E07EC2EDD40A600E0 +:100C40008E01E602E82D2E07EC2B5A08550A3C03CC +:100C5000F64D8C019601E60AEB62E91DD508DD41EF +:100C6000C0182E07EC225A085515D5F28404DD422F +:100C700084013E07EFA28400EA31DD40A6005A0855 +:100C80000105EAACEA76D5078E02E602E900D50353 +:100C90008400EB62EA4F3E07EC2BEA97D503840011 +:100CA000EB623BFFFE84DD9E3A6F98BC4403F06B21 +:100CB000A6003E07EC79DD45C8062E07EC79961FA5 +:100CC0005A000F15FA10DD4284013C0FFB8BEB5EDE +:100CD000EBAADD408422DD574900702F8420840276 +:100CE00084468061808180A1DD55EA27DD9E3A6FD0 +:100CF0009EBC49006AE4C017840049006AE4F822F7 +:100D000080C05A080111DD455A0802043C6FFB847B +:100D100044000080DD42DD40EBC7EAD6EB988481D9 +:100D20004900235749006AC2C00784013C0FFB9762 +:100D3000840049006ABF49006AF2C0258400490066 +:100D40006AF249006B3E5A08011FEA8BA6005A0856 +:100D5000130EDD56A6088E02E603E904A6095A081A +:100D600008068420EA8BAE40D51684C1440000807A +:100D70003C6FFB77DD42DD40EBC7EAD6EB9880861F +:100D80004900232749006AC2C006840049006AC29C +:100D90008401EB693A6F9E84DD9E3BFFFEBCDD590A +:100DA00084213C1FFB98AE40EA4344238D433E0719 +:100DB000EC2BA6108801AE10DD40A681542100FD69 +:100DC0005A200403DD5749006F92C00A8409DD42AE +:100DD000FA18EA2D8403EAA084013E07EC502E079E +:100DE000EF1F8C0196003E07EF1FDD41C804840110 +:100DF0003E07EF0D3BFFFE84DD9E3A6F98BC8401F9 +:100E00003C0FFB9CFA11DD424403F082A600C003B4 +:100E1000EAACEA76EA27DD9E84013C0FFB81DD9E89 +:100E200084013C0FFB8CDD9E84013C0FFB88DD9E22 +:100E300084013C0FFB94DD9E3A6F98BCFA12DD42B0 +:100E400084013C0FFB89EA27DD9E84013C0FFB8572 +:100E5000DD9E3A6F98BCFA13DD42EA27DD9E3A6FB9 +:100E600098BCFA14DD4284013C0FFB7BEA27DD9E2F +:100E70003A6F9ABCEFF43C0DFB9AC81EEBCDC01C38 +:100E8000DD412E17EF065CF080A0C80BE915441376 +:100E900058904423806844300C808402EA64D50C66 +:100EA000E90B2E07EF03C8038401D5045A08010596 +:100EB00084023E07EF03490016983C0DFB9A8C0113 +:100EC0003C0FFB9AEA678C013C0FFB8E2E17EF0A52 +:100ED000EA67E220E805EA6796003E07EF0AEA675C +:100EE000EA659600EAF5EABEEBA8EB25EA6549005B +:100EF00013493E07EC29DD41C0062E07EC29C80343 +:100F00008401D509DD41C8062E07EC2996005A0058 +:100F100001038400EB70EBE25A08010B84003C0FE4 +:100F2000FB75440124F83C0E0302490016143C6D85 +:100F3000FB9A5A68020F3C0DFB7F5A08010BDD41FA +:100F4000C80880064413970044238D54EA94EA6449 +:100F5000EC0C3A6F9A84DD9E3A6F98BC84013C0F8A +:100F6000FB863E07EF4C4403F07EA6405A10010F6B +:100F7000A6405A10020CA6405A100309A6405A1067 +:100F80000406A6405A101003A60084418420806203 +:100F900080824400B101EAA849002E17EA27DD9EAD +:100FA00084013C0FFB9FDD9E3A6FA0BC84C13C6F67 +:100FB000FB924403F064A640FE76C917A640FE7774 +:100FC000AE402E77EBF8CF17EBAADD40842EAE4172 +:100FD0008426AE408026DD578402802780478066C5 +:100FE000808780A7DD55D507A640964CC104A64052 +:100FF000EADCAE403A6FA084DD9E3A6F98BCFA15E9 +:10100000DD4284013C0FFB93EA27DD9E3A6F98BCDA +:10101000FA16DD4284013C0FFB90EA27DD9E3A6F11 +:1010200098BCFA17DD42FA04DD4A84013C0FFB76D6 +:10103000490018B05A08A104EA4FEA768403EAA0EE +:10104000EA27DD9E3BFFFEBC84013C0FFB99EBFED3 +:1010500044138D468C01EB1DA6088C01AE08490097 +:101060000DE5EBE2C816DD41C0062E07EC2996001F +:101070005A000108DD41C8062E07EC29C803840187 +:10108000EB7084003C0FFB75440061A83C0E03022A +:10109000490010D2DD41C021DD5B5A08201F2E0718 +:1010A000EF035A08020CEBFE5A080114EB1344201C +:1010B00019004402988CDD49D50C5A08030B845F53 +:1010C0004452988C80624402B18C3A228C24D8FE1F +:1010D0008401842049001A9ADD41C8034900158C17 +:1010E0003BFFFE84DD9E3A6F98BCFA18DD42440354 +:1010F000F00AA600DD424403F00DA600DD42EBA697 +:10110000A600DD424403F00FA600DD424403F01ABE +:10111000A600DD424403F01BA600DD424403F0823A +:10112000A600DD424403F353A600DD424403F36905 +:10113000A600DD424403F386A600DD424403F387A4 +:10114000A600DD424403F3CFA600DD424403F40CC5 +:10115000A600DD4284013C0FFB8AEA4FEA76EA27CB +:10116000DD9E84013C0FFB80DD9E4403F403A6005A +:1011700096005A0801043C0FFB7DDD9E84013C0F64 +:10118000FB7FDD9EFC0084013C0FFB7F84003C0F55 +:10119000FB8E3C0FFB7EDD40A6419E8BE642E905BF +:1011A0005A1006045A180D4BDD54A6485A18014728 +:1011B000EA40EB5CC80AEBE4C808EBB7EB6BD00580 +:1011C0004402C4AC49006BE4DD40A6015A000304AC +:1011D0005A080D15EB39C812EB5CC810EBE4C80EC9 +:1011E000DD4CA600C8048020EBFCD5069E43E62219 +:1011F000E805EBFCA65049007166EAA4C0048E0421 +:10120000E602E80784203C0DFB5880418061D5143C +:10121000DD41C0043C6407F6D5033C640836DD417B +:10122000C0043C2407F7D5033C2408373C0DFB5889 +:101230009671969184614900725CDD41C00349005A +:10124000105EDD56A6095A000D079E82E642E903AC +:101250005A08072CA6485A180129EAF39600C841F3 +:10126000DD54A6485A18013EDD58A6485A18013ADE +:10127000EB1DEBE45A0801064402C3D14900388C47 +:101280008420DD40DD578401EA31DD548400AE085E +:10129000DD58AE08840AEA488404DD4A2E07E9A036 +:1012A000DD4A8401EA75D51D5A08041C2E67EF1328 +:1012B000CE18DD58A6485A100215DD4AEB36040058 +:1012C0000008962FDD4ADD408026EB37DD5784018C +:1012D000EA31DD59AF80DD4BAF8084013E07EF136B +:1012E000EB0A5A080104490015D2FC80FC20EB36B9 +:1012F0003C5DFFD7D0073C5DFFD8D004EB5C5A08BB +:10130000010DEAF3C80ADD59A6009600C806DD58AB +:10131000A6885A280103AE082E07EC1BC023EB1643 +:10132000EACCD8202E67EBFB840097B03E07EC1B7D +:10133000CE19DD59A6005A080116DD4BA7C097F853 +:101340005A7801118026DD40EB37DD578405DD4AF0 +:101350008007EA31DD59AF802E07EC50C803DD5815 +:10136000AE08FCA03A6FA6BC49000841DD41C80A9E +:101370002E07EC7B5A080104480000ED84013E076B +:10138000EC7B4900391180C0EA8880E044038D4538 +:10139000A6808C41AE80EBCDC0178401DD4ADD41D3 +:1013A0008120C00749000957840049001481D50CE9 +:1013B0004412C46C804184648402DD448009490085 +:1013C0001477490007E5DD41C02C3C53F7D83C03B6 +:1013D000F7D7D00E2E27EFAC8C4196903E27EFAC7E +:1013E0002E27EFAC50017F909600DD42D50484009B +:1013F0003E07EFAC3C03F6DAC8083C03F6DBC80551 +:101400002E07EFACE605E90D84013C0BF7DA84000A +:101410003E07EFAC4412C724840280418060DD4463 +:10142000EBCDC00984013C0FFB8F3E07EBFE49FF6B +:10143000FEABD50984023E07EBFE49FFFF59DD599B +:10144000A600F8D1840085213C9FFB963C0FFB9AB7 +:101450002E07EC4BC014DD41C0060003000F100343 +:101460008051D5088402501380515023000F8069A9 +:10147000DD4484003E07EC4B1003000FDD41C80340 +:1014800049003D0684003E07EC7B490007D73C033A +:10149000F7DA5A08012784003C0BF7DA2E07EFB27F +:1014A0005A00FF082E07EFB28C0196003E07EFB2FC +:1014B0003C03F6DA4412FE6A9600AE083C03F6DB03 +:1014C0004412FE6B9600AE08844184003C0BF6DAB1 +:1014D000FA313C0BF6DB80624400D1B08082EAA88E +:1014E000DD455A080238EBCDC035DD40A6015A086B +:1014F000032E3C6DFB3F5A68022ADD41C02B3E673C +:10150000EBFDEB514402E6D8EAA2EA86EAA2EA86BB +:10151000EAA2EA863B0044003B00C4208406EB7646 +:101520004400007DEBF18401EAD9EBBEEAA49E41C0 +:10153000E622E9035A08040F4900460849008FCA09 +:10154000C0098400EA3BEB11D505DD41C0038400EE +:10155000EB183A6FA684DD9EDD9E3A6F98BCFA19AF +:10156000DD4284013C0FFB9E490061A4EA98C80358 +:10157000EBAAD50349006169EA27DD9E84013C0F8F +:10158000FB91DD9E84013C0FFB7CDD9E3A6F98BC95 +:101590008403DD4A8401EA75EA27DD9EDD9E3A6F09 +:1015A00098BC8401F806EA27DD9E3A6F98BC840057 +:1015B00049000EE5EA27DD9E3A6F98BCFA1BDD4232 +:1015C0008400842A49002EFFDD41C003EAACEA769C +:1015D000EA27DD9E3A6F9EBC4403F41CA600E60297 +:1015E0004EF200AE49000E94DD41C012DD40A6016E +:1015F0005A08030F2E07EC14C00B84004412DEE4DB +:101600003E07EC148041840244300320EA64DD414B +:10161000C01CEB23A6C096D85A380118842084C079 +:1016200044002330804180833C6BF6DA3E37EFB3D1 +:10163000EAA896013C0BF7D82E07EFB35A00020335 +:10164000F80D3C6BF7D8F80ADD4180C04E030078F6 +:10165000EB23A7C097F85A700104480000714400BA +:10166000BB908026FD1380873E77EFB3EAA83E0744 +:10167000EFB82E07EFB35A08020B3E67EFBC3E6788 +:10168000EFBD3E67EFBE3C6BF7D7D51A8026FD1342 +:1016900080874400AB00EAA83E07EFB98026FD131F +:1016A00080874400AB01EAA83E07EFBA80264400D9 +:1016B0002330FD138087EAA896013C0BF7D78400FE +:1016C0003E07EFB34412C71E840280418060DD44B0 +:1016D0003C03F6DBC8342E07EFB8C80A2E07EFB973 +:1016E000960EC8062E07EFBA96024E040029840112 +:1016F0003C0BF6DB2E07EFB8C0074400009DDD422F +:101700002E07EFB8DD422E07EFB9960EC007440052 +:10171000009EDD422E07EFB9DD422E07EFBA96029A +:101720004E0400084400009FDD422E07EFBADD4260 +:1017300084024412C52680418060DD442E07EC4DB2 +:10174000C0068401EBD884003E07EC4D3A6F9E84BE +:10175000DD9E3A6F98BC4413F7EEA6089600968477 +:10176000C203EAA6AE088400F857EA27DD9E3BFFD5 +:10177000FEBC84013C0FFB954413F7EFA6089600CE +:101780009684C203EAA6AE088401F846F829EBE283 +:101790005A08010C3C0DFB70C00684024900082663 +:1017A0003C0FFB70490011D72E07EF0DC0048E01CE +:1017B0003E07EF0D3BFFFE84DD9E3BFFFEBCDD459B +:1017C0005A08020584013C0FFB8D4413F7C9A60893 +:1017D00096009684C203EAA6AE088400F81D49006C +:1017E0000B84DD41C80BEA8BA600C008DD40EBC7C7 +:1017F000EAD6EB98848149001DEC3BFFFE84DD9E18 +:101800003A6F98BC4413F7CAA60896009684C203A0 +:10181000EAA6AE08840149000772EA27DD9E3BFF75 +:10182000FEBC2E07EC7CC81DB401A6003C0FFBF1EA +:10183000640264024412FFF03C0FFBF0B6013C1D51 +:10184000FBF14402FFF4B62046011223500003448A +:101850004412FFF8B6012E07EC7C8C013E07EC7CAD +:10186000FA1ADD42EAACEA763BFFFE84DD9EFC63B9 +:1018700084003C0FFB6849003B265A00081D4900C4 +:101880003BA62E07EFC8441000A08C013E07EFC80E +:101890008403DD43840DDD4A49003BD7840EDD4AD5 +:1018A0008403441000A1DD438401490063D4840013 +:1018B0004900611DB1C34492E84E44A0012CDD41B2 +:1018C0004E02007E3C1C0307442397EC4011042089 +:1018D000A448440397D8964BAC403C0C03084413EF +:1018E00097DA40010020A4009603AC08F86849008C +:1018F0003BE55A0003C65A080207840444100060FE +:10190000DD43D5C05A0013DDF86EF8725A0002BBF1 +:101910005A0013D7F872DD4BA78097B0CED12EB7FF +:10192000EC775AB801CE8403EBB0DD43DD533E675C +:10193000EFAA5A080206490041673EB7EC14490075 +:101940003CE7DD5B5A081209EABF8420EAF85A082E +:1019500001048400F82FDD5B5A080408490043574E +:10196000EAADF8B7F826D5285A081406EAADF8BA51 +:10197000F820D5225A08190684008020490016460E +:1019800049003D134900442D5A08020448FFFF7BDB +:10199000DD5B5A08050849004339EAADF8F8F80953 +:1019A000D50B5A08150AEAAD8403441000A9DD439B +:1019B000EA4EEA2CEA3A49004306F94B8403441004 +:1019C00000A2DD43490046B080C08401EB725A0892 +:1019D000010448FFFF945A68030448FFFF525A6805 +:1019E0001303F9378403441000A3DD43EB1A4900C5 +:1019F00046205A081303F92D8403441000A4DD4344 +:101A0000DD4BA600C807DD40A6415A180D0484230B +:101A1000AE41440000A3EB8BEBCA4E0301002E172E +:101A2000EC13440297E849001FF1F081EBB0840306 +:101A3000DD433C6DFB64800649003F405A68061355 +:101A40002E07EF755A08010F2E07EF74C80BEA4AEC +:101A5000C8092EB7EC434EB30006490072743EB776 +:101A6000EF752E07EF76C82FEA4AC02DE6C2E82BA5 +:101A70003C0C030B5A000705EA805A080925840428 +:101A8000EAFA800649003CE9EA4A4E6300E5EA8347 +:101A9000EAC5EA4A5CF00030E9162E100C14840105 +:101AA0003E07EF76C90684273C1E030BF805D50BCD +:101AB0008407EA6284003E000C14EB61EAC583FFF0 +:101AC0008405EAFA8006490040DDDD5B5A08140906 +:101AD0008403441000A6DD43F85E4800009E5A6867 +:101AE000040D8403441000A7DD4384003C0FFB7108 +:101AF00049003CA3EAFAD5545A68050EEB335A085C +:101B0000035049003C9A5A08034C8401EAFA8400C5 +:101B1000EA99D546EA4AC844E6C2E8368006490052 +:101B200041175A6801328006490042013C0DFB71A1 +:101B30005CF00BB8E8048C013C0FFB7184003E079D +:101B4000EC07EB338E04E602DD5BE90F5A00150E5D +:101B50003C1C041A5A100503C90584203C1E0304CA +:101B6000D50484223C1E03048E14E602E90BEBC16B +:101B7000C8073C00086CC0068E01EA99D5033CA852 +:101B8000086C8400EB18DD5B5A08150B84034410C5 +:101B900000A8DD433C0DFB52EB1549003DE1F0018F +:101BA000EB514422E3A0490020D9DD5B8E14E6020C +:101BB000E90AEB0AC808EAB3C0042E07EBFAC80327 +:101BC000EBD9C005EAAFC803EB3CC026EB339E421D +:101BD000E623E80A84223C1FFB3F5A08031E8401C7 +:101BE000EB188401D50F5A0805078400EA9984018F +:101BF0003E07EBFA3C10086CC90F8401EA353E1031 +:101C000010DEAC381493800214938001EB243A1355 +:101C10008C0049000F088401EACB2E07EC5E5A08BD +:101C20000512DD59A6005A08010EEA9D5A08090B53 +:101C30002E17ED482E27EC582E07EC5E49000BFAC4 +:101C4000F8082E07EC5E5A000603F8038400EAF950 +:101C500048FFFE37EAB0EAC548FFFF1D3C0FFC060F +:101C6000DD9E3C0FFC05DD9E4402B7F43C0FFBF506 +:101C7000DD9EFC4180E18123CC09B400C2090260F1 +:101C8000001F0220001E97B3D50CA001CA05A58035 +:101C9000A48197B3D506026000310220003097B3CB +:101CA0008026969380074900490F001480005A103F +:101CB000FF058C2188019201EA34803FB081490000 +:101CC000496BB41F38138111F0013823811184024C +:101CD0004000801642030873EB21FCC1FC60B48015 +:101CE000C311C4079F64E6A2E90484A01050007DDC +:101CF0002E57EC3E2E67EBFF5C5280015CA3000187 +:101D0000D503814380A34E4202818E84E6824EF346 +:101D1000027D80C0A60C8123816280E14E03008594 +:101D20004E530083EB80C328A0D13C5DFB59A4989F +:101D3000A5190201803102318030EBDE96939723A2 +:101D4000960396DBE807EBDA5A5801055010851028 +:101D5000F81100538008CD048A44EBC2D5055A58C7 +:101D600031088A03EB8AE9048401EBA4F8035010DC +:101D7000828848000257501088465033006E8440D5 +:101D80008082800BEBD33C4347543C5347749721EC +:101D90009B6540421406806041107C0AA03DA07CF7 +:101DA000FF2294019521412007F5404217F50423B5 +:101DB000800A0503800B944995694E9200254208DC +:101DC000942442020C7342428C69884388A0980C88 +:101DD000EB4840491400EADD4058C000882488657B +:101DE000EA51EBE8EB4EC00444F007D0D50344F0D1 +:101DF0000BB8EBF0E20F4EF2008FEBBB4E03008C02 +:101E0000480000893C07F4B63D37F4BAFE1C400098 +:101E10004C1641307C0A43399424433200734242C9 +:101E200080694800008BA63D5A001F0448000092BC +:101E30004E530090EB804E92002C043580013C5DA7 +:101E4000FB59A498A5190201803102318030EBDEE4 +:101E500096939723960396DBE807EBDA5A58010529 +:101E6000501085B2F81300538008CD048A44EBC2A9 +:101E7000D5055A58310A8A03EB8AE90684015010C5 +:101E800080A2EBA4F8035010832A480001CF501021 +:101E900087A45033006E84418480800BEBD33C5385 +:101EA00047733C434793976988858060A03DA07C39 +:101EB0004052140694019569412007F5EB9E0423D6 +:101EC000800A0503800B4111FC0A944995214E922A +:101ED000002642089024EBF842420C69884388A00F +:101EE000980CEB4840491400EADD4058C0008824B3 +:101EF0008865EA51EBE8EB4EC00444F00708D503CF +:101F000044F00AF0EBF0E20FE806EBBBC804440033 +:101F10000C7FEBE802030008D5243C07F4B73D37FB +:101F2000F4BAFE1C40004C1641307C0A4339902420 +:101F3000433280734242006988B3980C884388B268 +:101F4000EADD4048C000EB4888258864EA51D51096 +:101F5000841F4E92000A1003006C22030004EBE879 +:101F600012030018D5071003006E0203000C1203C1 +:101F7000000EA63E4E0300944EA30092EB804E92BC +:101F8000002BB46B3C5DFB65A498A5190201801F72 +:101F90000231801EEBDE96939723960396DBE807CB +:101FA000EBDA5A58010550108654F8130053800993 +:101FB000CD048A44EBC2D5055A581F0A8A03EB8A1E +:101FC000E906840150108144EBA4F803501083CC3F +:101FD00048000130501088465033006F844084819F +:101FE000800BEBD3806041007C0AA03F3C5346F05D +:101FF000A07E3C43472294010423800C0473800D8F +:102000004E92002E97699B2CE2A45257800095694E +:10201000EB9E9521411007F542081024EBF842424F +:102020000C69944988A08843980CEB484048940078 +:10203000EADD88F088248867EA51EB94EB4EC0040F +:1020400044F007D0D50344F00C80EA96E20F4EF23C +:10205000009DEBBB4E03009A48000097413007F506 +:102060003C07F4B897699B2CFE1C3D17F4BAE2A418 +:1020700041104636525780009569EB9E4008FC0A95 +:102080009521FE244202C47342424469944988A0C7 +:10209000980CEB4840F994004800008FA63F5A0086 +:1020A0003104480000914EA3008FEB804E92002B2C +:1020B000B46B3C5DFB65A498A5190201801F023139 +:1020C000801EEBDE96939723960396DBE807EBDA08 +:1020D0005A580105501086F6F81300538009CD04B4 +:1020E0008A44EBC2D5055A581F0A8A03EB8AE906CF +:1020F0008401501081E6EBA4F8035010846E480070 +:10210000009D501087A45033006F84418082800B63 +:10211000EBD33C5347213C43475397698885A07FC5 +:10212000806040521406A03E944995690423800CB7 +:10213000EB9E0473800D4101FC0A401083F54110B1 +:10214000040895214E92002542081024EBF84242E3 +:102150000C69884388A040089000E2118825EADDD8 +:1021600088F0882F8867EA51EB94EB4EC00444F066 +:102170000898D50344F00C80EA96E20FE806EBBB22 +:10218000C804440013FFEB9402030009D5243C0764 +:10219000F4B93D27F4BAFE1C4000481641207C0AE1 +:1021A00043291024432280734242006988B24008C8 +:1021B0009000E21188258843EADD88F0882F88673F +:1021C000EA51D518841F4E9200121003006D2203AD +:1021D0000005EB9412030019020300083C0BF7E81A +:1021E000020300093C0BF7E9D52C1003006F020332 +:1021F000000D1203000F0203000C3C0BF7E6020374 +:10220000000D3C0BF7E7D51D843FC3061010006C92 +:102210001010006DD5161010006E1010006FD51143 +:102220005033006C48FFFDAD5033006C48FFFE3565 +:102230005033006D48FFFED45033006D48FFFF67F8 +:10224000FCE05A0001054403F7DED5034403F7DD43 +:1022500044100069AE40EA298420AE40DD9E84012E +:10226000DD9EFC204473F080A7B897B05433001F64 +:10227000583180A0AEF8DD49AFB8FCA0DD5A8E0120 +:10228000EAD5DD9E44100055DD46AE404413F7F11B +:10229000A6089604C003EA29D5FCDD9E441000552B +:1022A000DD46AE404413F7F0A6089604C003EA29C1 +:1022B000D5FCDD9E4443F7FDA72097205A08010571 +:1022C00058020008D503540200F75A180104EA7FA7 +:1022D000D503540000FB5A280104EA9AD502EB29E1 +:1022E0005A380104EA54D502EAA64413F7FDAE08B1 +:1022F000DD9EFC2180E08400EA2A84008020844165 +:102300008060506F8007F837C703EA43EA2A8421C8 +:102310004403F7C0AE40442FFFE74403F7C3AE8049 +:1023200096B04403F7C6AE8084404403F7C1AE8044 +:1023300084774403F7C4AEC0EB6A96004433F7C712 +:10234000AE184403F7C2AE8092D084434403F7C56D +:10235000AE8097B0EBB8AF804403F7CCAE40EA381C +:102360008020EA37A6089600C003AED0D5FC8020B6 +:102370008040806049FFFFA0FCA184004412D6C0C9 +:10238000845FEACF8C015A0809FEDD9EFC20842080 +:102390004432D6C04442FE5D4452FE5C44638D41EB +:1023A00044738D403801840096885A00FF1CE6482B +:1023B000E81944F021C03827880040F13C00DD0FC7 +:1023C000081014181C2222203C2DFB54AE10D50AF4 +:1023D000AE38D508AE30D506AE28D504AE20D5022D +:1023E000EBC08C215A1809E0FCA04403F7C0A640BA +:1023F0004402EC2CAE404413F7C3A648AE4344134A +:10240000F7C6A648AE464413F7C1A648AE414413EA +:10241000F7C4A648AE444413F7C7A648AE474413D2 +:10242000F7C2A648AE424413F7C5A648AE454413CA +:10243000F7C8A648EBCEDD9EFC00EA524402EC2C25 +:10244000A6804413F7C0AE88A6834413F7C3AE88B2 +:10245000A6864413F7C6AE88A6814413F7C1AE889A +:10246000A6844413F7C4AE88A6874413F7C7AE8882 +:10247000A6824413F7C2AE88A6854413F7C5AE887A +:1024800000100008EBB8AE40FC80FC4081405400D6 +:10249000807F80C180E281235A087F05440000C804 +:1024A000DD42EA525AA8010A8400F9B0EB7A84208E +:1024B000AE404403F7CBD5034403F7CC542480FF4C +:1024C0004413F7C0AE8896B04413F7C3AE8896B8ED +:1024D0004413F7C6AE884014A00996484423F7C1B8 +:1024E000AE504013200996484423F7C4AE50401321 +:1024F000A00996484423F7C7AE504014C009964837 +:102500004423F7C292D0AE5097B04413F7C592F06F +:10251000AF8897F84413F7C8AFC88421AE40EA38B3 +:10252000EA37A640C103AED0D5FD5AA80107800AFC +:10253000F96DEBF7EB7AAE408401FCC0FC0044037C +:10254000F02CA7804413F3EC8401AE0884474413B5 +:10255000F3EDAE884413F3EEAE084413F3EFAE0888 +:102560004423F3F08420AE5084644423F3F1AED0CE +:102570004423F3F28462AED04423F3F3AE5097B019 +:102580004413F3F4AE089674C945541300029648F8 +:102590004423F439C1063E07F01F8403AE10D5046E +:1025A0003E37F01FAE50EA5297968401F8D397B0A9 +:1025B0008400F8D0C60584013E07E9C4D5033E6710 +:1025C000E9C4DD5A5A0802074413F02DA608EA545C +:1025D000AE084401D80044128E10442025A049FFC3 +:1025E000FE42441FFF86EB1BAE408420EA70AE40E3 +:1025F000441000404403F6CAAE40FA214403F69763 +:10260000AE40FA2F4403F384AE4084214403F380A8 +:10261000AE40DD5A5A00011E4605555A4412C12CDF +:1026200050000AAA3C0FFA6F804184028464DD44A2 +:10263000DD46DD47AE404605A5AA500005A53C5D38 +:10264000FA70D8FE46012345500006783C0FFA7018 +:10265000FC80FC0049FFFE93DD4B4412D6C0A6006F +:10266000AE08DD4CA600AE09EBACA600AE0A4402F3 +:10267000FE5CA600AE0B4402FE5DA600AE0CEBD9DC +:10268000AE0F804184698402DD44FC80FC2044005C +:1026900000C6DD424403F7C0A600DD424403F7C193 +:1026A000A600DD424403F7C2A600DD424403F7C39F +:1026B000A600DD424403F7C4A600DD424403F7C58B +:1026C000A600DD424403F7C6A600DD424403F7C777 +:1026D000A600DD42EBB8A600DD424462FE50447223 +:1026E000FE5608030001DD424C63FFFDEB23A6000C +:1026F000DD42440000C7DD42FCA0FC004423F7F0AB +:10270000C80380A2D5034453F7F1A6689648DA17A8 +:10271000540080029780C609440000C3DD42F817C8 +:102720008400F8188400FC809656C118440000C448 +:10273000DD42F80D8006F80E8006FC80546080FEB5 +:10274000C60D440000C5DD428006DD4249FFFFA002 +:10275000840149FFFD788400FC808401FC80FC40FA +:10276000814080E180C28123EA525405007F5A08EB +:10277000010A8400F84B8420EB7AAE404413F7CB77 +:10278000D5034413F7CC542480FF4403F7C0AE8034 +:1027900096B84403F7C3AE8096B04403F7C6AE8044 +:1027A0004004A00996004423F7C1AE104003A009DD +:1027B00096004423F7C4AE10EB6A96004423F7C793 +:1027C0004034C009AE1096D84403F7C292F0AEC0B0 +:1027D00097F84403F7C592D0AFC097B0EBB8AF807D +:1027E0008401AE088401FCC05A0001054413F7CCF3 +:1027F000D5034413F7CB4433F04AEB6EA688C203EB +:10280000AF18D5FD5A08010AFC0049FFFD74EBF72B +:10281000EB7AAE408402FC808402DD9EFC41DD5AEE +:1028200084C15A0001044800008B4413F7F1EA38D0 +:10283000EA37A6089604C003AED0D5FC3C6DFB4D2C +:102840004413F1289CB484638402DD444413F118DA +:102850005023000884638402DD444413F1005023B4 +:10286000001884648402DD444413F12C50230010CA +:1028700084638402DD444413F130502300148463E4 +:102880008402DD444413F1045023001C8464840258 +:10289000DD4484014413F30EEAB58060DD44001F7B +:1028A0008007440FFF80FE0FEA2A4413F30EEAB5B7 +:1028B00084618402DD44440FFFAEEA2AEAB2EAB53D +:1028C00084618402DD448401EA2A4413F10D840208 +:1028D000EAB58461DD44DD46DD47AE404605555A24 +:1028E00050000AAA3C5DFA6FD8FE4601234550000D +:1028F00006783C0FFA6FEA77EA82840AEA2D8401AF +:10290000EA5B4413F133EAB58060DD44006F800771 +:1029100054030004C0F3978FC606440000C2DD4292 +:1029200084C1D50D4605A5AA500005A54412C130A5 +:102930003C0FFA70804184028464DD448006FCC14F +:10294000DD5A5A00010544024A00DD9E44020A0095 +:10295000DD9EFC405A000203F818840880C1DD4A5D +:102960004403F31CA600C0064413F33FA608EAE3A1 +:10297000AE084403F369A6009604C009FA22EA707F +:10298000AE408420EB1BAE40480000E42E97F01FC1 +:102990002E77F01E5A90010448000080CF1E800957 +:1029A000DD4A4413F374A60858000003AE08C612AB +:1029B00084053E97F01EDD4A2E07F01D80478C01EE +:1029C0003E07F01D840280208069808780A7DD5546 +:1029D000D50444000898EA2D84003E07F01ECE1D61 +:1029E0004463F36A8402DD4AA630EB29EA7FAE3005 +:1029F000440001C2EA2DEA25FA00AE088041846154 +:102A00008402DD448403DD4AA6304413F369EA54AA +:102A1000AE30EA38EA37D51E8400F809844080A237 +:102A20008062848384228401DD55840149005B1D1A +:102A3000EAAAFA0380268046AE3084618402DD442F +:102A40008401EAF6EA28EA21A6305A0014CBAE88BF +:102A5000D5FCA6089604C803AED0D5FC8404DD4A94 +:102A60004422FEF04433F04AEB6EA610EA255A00E9 +:102A70001104AF18D5FBFA02AE088440EB1BAE8000 +:102A8000840280418060DD448405DD4A2E07F01C0D +:102A90008C013E07F01CD55DCF0EC60D84013E07AC +:102AA000F01E8405DD4A8402802780478067848386 +:102AB00080A7DD5584003E07F01EC61D4472FEF05F +:102AC0004493F04A44A00055A638EAAA5A00130BD2 +:102AD00084408401EBFA80208062848380A2DD55EB +:102AE000D5F48401EAF6FA04AE30802684028046EA +:102AF0008461DD44EA25EA38EA37A6085A00100462 +:102B0000AED0D5FC8403DD4A4413F36AA608EA3844 +:102B1000EA54AE08EA374413F369A6089604C803DA +:102B2000AED0D5FC8404DD4AEAAAFA01AE30802694 +:102B3000804684028461DD44EA28EA21A6305A00F6 +:102B40001204AE88D5FC2E07F01C8C013E07F01C49 +:102B5000FCC04423F02BA6502E37F01F96485A385D +:102B60000109C00458008008D50A540080F7D50731 +:102B7000C00458008010D503540080EFAE10DD9ED5 +:102B80004403F02AA600EB0496005A180104EA5FF9 +:102B9000DD9EEADADD9EC807FC008401EA61840557 +:102BA000DD4AFC80DD9EFC00EA985A0801094403D6 +:102BB000F7F0A600560000019604FC808400FC801B +:102BC000DD59A6009600C004EAA75E000001DD9E64 +:102BD000FC4097808402DD4A8006DD4A4412FEF202 +:102BE0008401AE084402FEF3AF808402804180601D +:102BF000DD44EA9BEAC14492FEF649FFFFC35A0056 +:102C0000010B8404441000F2DD43EB1AAFF0EABD7F +:102C10005A08ECF58403DD4A84004412FEF2AE0843 +:102C20004412FEF3AE08FCC0FC403C6DFB9B97B029 +:102C3000DD455A000207DD40A6015A000903F8D01D +:102C4000EB16EA5AD003EAD1D8292E57F080D604E1 +:102C50002E57F081DE0CDD5A5A0001078408EA394C +:102C60002E0010F3EA9C4472C7F0F8BA2E07F084E5 +:102C7000E2C0E9FAEB045A1801F88429EB172E1088 +:102C800010F03E17EF104C6000052E57F085DEEC7B +:102C9000840AEA484472C7F0F8A33C0DFFDFD00471 +:102CA0003C0DFFE0D8272E07F070E2C0E90FDD5A97 +:102CB0005A000103F8158409EA39840AEA482E000B +:102CC00010FDEA6F4472C7D8F88B2E57F068D6050E +:102CD0002E57F0694C5340E5DD5A5A08010448006C +:102CE00000E08408EA392E0010F3EA9C4472C7D849 +:102CF000F8773C0DFFE8D0043C0DFFE9D8502E5783 +:102D0000F052DE0CDD5A5A080103F83E8408EA3915 +:102D10002E0010F2EA9CEB7EF8632E57F05DD6167B +:102D20002E57F05FD6132E57F061D6102E57F06352 +:102D3000D60D2E57F05ED60A2E57F060D6072E57C6 +:102D4000F062D6042E57F064DE0CDD5A5A080103F7 +:102D5000F81B8408EA392E0010F4EA9CEB7EF84058 +:102D60002E57F058D60E2E57F059D60B2E57F05A34 +:102D7000D6082E57F05BD6052E57F05C4C53409486 +:102D8000DD5A5A0001044800008F8409EA39840A98 +:102D9000EA482E0010FDEA6FEB7EF822EBA9D00482 +:102DA0003C0DFFE7D84B2E57F03FDE0CDD5A5A00A2 +:102DB0000103F80E8409EA392E0010F0EA6FEB0FD8 +:102DC000F80F2E57F03ADE0EDD5A5A08010448007B +:102DD000006D8408EA392E0010F2EA9CEB0F4800DF +:102DE00000692E57F03CDE08DD5A5A08015F840A5C +:102DF000EA48EB0FD55E2E57F045D6162E57F04712 +:102E0000D6132E57F049D6102E57F04BD60D2E570D +:102E1000F046D60A2E57F048D6072E57F04AD60469 +:102E20002E57F04CDE42DD5A5A0001408408EA3940 +:102E30002E0010F4EA9CEB0FD53C3C0DFFD94C0260 +:102E4000C00E2E27F01F84292E0010F1EB175A28F0 +:102E50000104EA6FD52EEA9CD52CEBB44C02C013CA +:102E60002E57F020D6042E57F021DE21DD5A5A00CD +:102E7000011F8408EA392E0010F3EA9C4472C790BF +:102E8000D518EACC4C02C016DD5A5A080113840941 +:102E9000EA392E0010F0EA6F840AEA48D50A447233 +:102EA000C7D8D507EB7ED505EB0FD5034472C79085 +:102EB00044A3F01DEAB1EABCDD535A080215DD4512 +:102EC0005A080212A77A9E319600DE0658948001B5 +:102ED00010950000D50800538013D805549480FE47 +:102EE00010950000FCC0FC003C6DFB9B3C0DFB639F +:102EF0005A0009083C0DFB635A0008044800019B76 +:102F0000DD455A000208DD40A6015A0009044800C8 +:102F1000016D3C1DFB4F3C2DFFD79770DD5A4C11C6 +:102F200000063C2DFFD84C1140132E17F0864C1292 +:102F3000809F2E17F0874C12809B2E27F0804C51DB +:102F400001252E17F0814E120146F8163C2DFFDFA9 +:102F50004C1100063C2DFFE04C1140112E17F07073 +:102F6000E2A14EF200852E27F0684C51010F2E177A +:102F7000F0694C12C130480001093C2DFFE84C11AA +:102F800000063C2DFFE94C1140672E17F0524C1201 +:102F9000C0125A080103F898EA464E1700048E2121 +:102FA000EAC4EA464E13011784463C2FFB64EAEB61 +:102FB000F8A12E27F05DD20D2E17F05F4C12800A7B +:102FC0002E17F0614C1280062E17F0634C12C01FB2 +:102FD0005A080103F879EA464E1700048E21EAC424 +:102FE000EA464E1300F8EB45EAEB4C51007B2E17F6 +:102FF000F05F4C12807E2E17F0614C1280822E17EB +:10300000F0634C12C0E8480000832E17F05E4C12AB +:1030100080922E17F0604C12808E2E17F0624C12A8 +:10302000808A2E17F0644C1280862E17F0584C12AE +:10303000801F2E17F0594C12801B2E17F05A4C127D +:1030400080172E17F05B4C1280132E17F05C4C1279 +:10305000C0C2D50D3C2DFFE64C1100063C2DFFE70C +:103060004C1140772E17F03F4C12C0075A00010355 +:10307000F841480000A62E17F03A4C12C0155A0825 +:103080000103F822EA464E1700048E21EAC4EA46FC +:103090004E1300A184463C2FFB6484413E27EF750C +:1030A000EAEBF8282E27F045D20D2E17F0474C12E8 +:1030B000800A2E17F0494C1280062E17F04B4C1246 +:1030C000C02A5A08010448000088EA464E17000446 +:1030D0008E21EAC4EA464E13007EEB45EAEBDA04A1 +:1030E000842BEB35F8072E17F0474C12C006842CC2 +:1030F000EB35480000702E17F0494C12C005842DA6 +:10310000EB35D5682E17F04B4C12C065842EEB358D +:10311000D5612E17F0464C12800E2E17F0484C1237 +:10312000800A2E17F04A4C1280062E17F04C4C12D3 +:10313000C0525A000152EA464E1700048E21EAC4DA +:10314000EA46C94884413C2FFB64EAEBD5433C2D59 +:10315000FFD94C1140105A080108EAA74E07003D5C +:103160008E01EA6FD539EA464E1700358E21EAC442 +:10317000D5313C2DFFEF4C20C01B2E27F020D2056F +:103180002E17F0214C12C0275A000127EA464E178D +:1031900000048E21EAC4EA46C91DDA048424EB4502 +:1031A000D5038425EB458420EAEBD5143C5DFFEE86 +:1031B000D9115A0801104403F403A600C80DEAA768 +:1031C0004E0700048E01EA6FEAA7C8068407EA48A2 +:1031D000D5035A080105EAA7C82DD5042E0FEF0F15 +:1031E000C829840BEA39D526DD455A000224EB169E +:1031F000EACCD820DD5A5A08010EEAA74E0700048F +:103200008E01EA6FEAA7C8168407EA488404DD4AFB +:10321000D5118402DD4A2E0FEF0E4E0700058E01F8 +:103220003E07EF0E2E0FEF0EC8058407EA48840311 +:10323000DD4AFC80FC00EBFE96005A080103F8060C +:103240002E57F045D8058400EA93480000572E57C2 +:10325000F046D80D8401EA93DD5A5A00014F44121A +:10326000E5D8EB4FEA948402DD44D5472E57F0476A +:10327000D8048402EA93D5412E57F048D80D840330 +:10328000EA93DD5A5A00013A4412E658EB4FEA94A9 +:103290008402DD44D5322E57F049D8048404EA93E1 +:1032A000D52C2E57F04AD80D8405EA93DD5A5A00E2 +:1032B00001254412E6D8EB4FEA948402DD44D51D83 +:1032C0002E57F04BD80C8406EA93DD5A5A000116AB +:1032D000EBA78041FA788402DD44D50F2E57F04CDD +:1032E000D80C8407EA93DD5A5A000108840244127C +:1032F000E758EB4FEA94DD44FC8044039680A60037 +:10330000961F8E01E6013EF7EC72DD9EFC202E0733 +:10331000EC7297805A680131441396814403968079 +:10332000A600A68844139682A64840701009401053 +:10333000A00840108A0444239683A690FE57442395 +:103340009684A6D096D85A7001075A78020BF803D3 +:103350008006D508800744239690DD448007D50277 +:103360008403842044239680AE504423968FAE106D +:103370003E17EC72FCA08401FCA02E07EC7DC0057A +:10338000FC008403DD4AFC80DD9EFC00C80284262C +:103390003E17EC5E49005642FC80FC03B61FF181EB +:1033A000F282F383B45FEB64EA248402F484F5854B +:1033B000DD44F2014412A69AF838F2024412A82A17 +:1033C000F834F2034412A9BAF830F20444129ECA47 +:1033D000F82CF2054412A05AF828F20A4412A1EA85 +:1033E000F824F20B4412A37AF820F20C4412988AC3 +:1033F000F81CF20D44129A1AF818F20E44129BAA05 +:10340000F814F20F44129D3AF810F2104412AB4A2D +:10341000F80CF2114412ABAEF808F2124412AC12DE +:10342000F8044412AC76F213EA248402DD44FC83EF +:103430002E27F01F5A2801044800008DFC4580E02B +:103440008121840480273C6DFB9BDD435A70050776 +:103450005A78060448000066F804EA9D5A000904F8 +:1034600048000077EB23A6008E02E6064EF20071BC +:10347000E724E916E730E83F44437A28F831EAC9FF +:1034800044137578F486F487F488F489B65FF38181 +:10349000F082F183F284F385FD20F82BD52C4403D0 +:1034A0008388B61F44038518F081EB77F0824403CC +:1034B0007BB8F08344037D48F08444037ED8F085D4 +:1034C000440386A8F08644038838F087440389C8FB +:1034D000F08844038B58F08944137578EAC9442373 +:1034E00077084433789883FF44438068445381F8D5 +:1034F00049FFFF55EB51F823EBA78041FA78F821FB +:10350000441397DC80418464F81C8404441000CE8A +:10351000DD43490004A68404441000CFDD43D518E0 +:103520009630661000088E26E622E90850107FF6D5 +:10353000E622E9048E12E602E80BEB518041EA94A0 +:103540008402DD44EBA784028041FA78DD448401E3 +:10355000FCC58401DD9EFC0084858E0140501096E0 +:1035600084C68CA138509602FF344042900D972FAC +:10357000AF10041080114000800D9604AE18FC803E +:1035800004108012FA58FE14EA6AEB83EA85882058 +:1035900004008009EA55DD9E04108012FA58FE14DA +:1035A000EA6AEB83EA858820040080089600DD9EA5 +:1035B000FC60816004000008858185C08121548001 +:1035C000003F81AC80CC80EE50A58004879FE3064D +:1035D0004EF300AF9E319600802A49005F308E0185 +:1035E0005CF000234EF200A144F033F8382781014B +:1035F00040F13C004A003C006C002E012E012E01DF +:103600002E012E012E019600280164004C00E800D6 +:10361000F000F80000010801100118012001460027 +:10362000C000C800D000D800E0002E012E012E01FD +:103630002E012E01460046004600460046008CE161 +:1036400097F8D5729AB74EE300081024800011C491 +:10365000800185C1D56910248001D5669A37100490 +:103660008002D562EA5A4CB0400D9AB75AD801068A +:103670001024800485A0D5581024800585A0D55439 +:10368000EBA94CB040529A3710048004D54DEA5A49 +:103690004CB0400D9AB75AC80106102480068580A8 +:1036A000D543102480078580D53FEBA94CB0403D21 +:1036B0009A3710048007D5389A3710048008D5341B +:1036C0009A3710048009D5309A371004800AD52C17 +:1036D0009A371004800BD5289A371004800CD52413 +:1036E0009A371004800DD5209A371004800ED51C0F +:1036F0009A371004800FD5189A3710048010D5140B +:103700009A3710048011D5109A3710048012D50C06 +:103710009A3710048013D5089A3710048014D50402 +:103720009A37100480038CC197B048FFFF52FCE029 +:10373000FC61F081F1018400F8323E0010E8840061 +:103740003E07EF0984C04492E8589DF1F101963894 +:10375000F8262E17EF0988C9AE3188013E07EF0918 +:1037600080C75A7808F4F1018409F8193E0010F175 +:10377000F101840AF8143E0010F2F101840BF80FF5 +:103780003E0010F3F101840CF80A3E0010F4F10140 +:10379000840DF8053E0010F5F101FA0549FFFEFE23 +:1037A0003C7DFFE63E0010FD84C04493978050A30B +:1037B000800404038008962FE0C0E80B8006802A6E +:1037C00040B3240049005E3B8CC1EB1F97B0D5F29B +:1037D000FCE1FC004462D6CCB4064412C7F0F811F8 +:1037E0008386B8084412C7D8F80CB8114412C7C071 +:1037F000F808B80F4412C7A8F804B8184412C790C4 +:1038000049FFFED8FC804423F7DAA6509648C0044E +:1038100058108020D503541080DFAE50DD9EFC4050 +:103820008401490053FB8401F8272E17EF09460055 +:103830008B3B88014413F7F8B60184014413F7FC6D +:10384000AE084413F7CDAE0884293E07EF0E84047A +:10385000EB17446000C8DD4AEA77EA822E0FEF0ECC +:103860004E0700088EC1EA5B840A97B1EA2DCEF7B5 +:103870008405DD4A840049FFFFC8FCC0FC4080E0AD +:10388000DD4580605A08024EEB045A180128F830D2 +:1038900044A2FEFC4492FEFD005500004412FEFCD2 +:1038A000D70F0015000000648000840A97B0DD4344 +:1038B0008026840BDD43840AEA2DEA29D5EEEABD91 +:1038C0005A08AAF1EBDCAE0884404402FEFDAE804B +:1038D000840280418060DD44FCC04462FEFCAFF0A5 +:1038E000EBF74472FEFDAE7880468026DD44DD476E +:1038F000DD46AE4083FFA63096005A00460CA67007 +:10390000A638EABC840ADD43840B8029DD43EA291A +:10391000D5F34412FEFCAE084402FEFD8420AE4006 +:10392000FCC0FC20DD455A0802174473F41CA7B8FC +:10393000DD47DD46AE40840A4410009997B0DD4370 +:10394000DD59A600C806A7B897B0EA29EB1AD5F941 +:103950005A6802FBFCA0FC21F081DD5A5A08011FC5 +:10396000F8354412FEF0A608EAAA5A0850FEF816E6 +:1039700044000051F825F82AA6304472FEF05A0897 +:1039800052FDF0014900716B44000053AE388027AE +:10399000804784618402DD44FCA149001DD9EAAA64 +:1039A000EA60F80E4403F04ADD47AE408006A640C8 +:1039B000EAAA5A1851FEF00149007151EB59AE3094 +:1039C0008026840280468461DD44DD47DD46AE40CA +:1039D00083FFA6305A0853FFFCA1FC20DD5AEA9B66 +:1039E000EAC15A080113AFF0EA25A6085A0852FFA7 +:1039F0008401EB5EDD47DD46AE40DD45C0FF44108F +:103A00000053EA70AE40FCA08401EB5EAFF0DD45F0 +:103A1000C0FFEA25EB59AE08804184618402DD4491 +:103A2000FCA0FC4280C0B0013A100C2022AF800202 +:103A3000F702049F8003DD455A0002098027804970 +:103A4000806A8402DD448401FCC200030065001327 +:103A500000648A015A00082F000300650013006506 +:103A6000E608840CE80FF80812A10000F80314918E +:103A700000020013006580464220807383FFA9D1B5 +:103A8000D5118E284E00FFF912A10000F803149101 +:103A900000020013006580468E284220807383FF59 +:103AA000A9D1000300658C01960010030065840114 +:103AB000FCC28400FCC2FC000060806400208065C1 +:103AC0004C61002900308064844C808142418873BD +:103AD000003080642252000080814241887380C19E +:103AE000A0E2004080644262087300208064A1313B +:103AF0008C41969010208064002080645A28080B26 +:103B0000844010208064002080658E4896901020AC +:103B10008065AD40A901A8C2FC803C1DFB753C1D21 +:103B2000FB7500300064844C42018873501087A3F9 +:103B3000222000004400004B4211007380013C1C15 +:103B40000302E201E8053C0FFB758401DD9E840061 +:103B5000DD9EFC023C6DFB8EEBE2C04596309E4341 +:103B6000E631E806DD54A648C9035A080B0584006F +:103B7000EB70D5392E500C0D2E000C0CD823EB0415 +:103B800097B03C0DFB705A0003083C03F6628C01B1 +:103B900096013C0BF6625A68020E5A10010C3C0367 +:103BA000F6625A0001F084003C0BF66284003C0F80 +:103BB000FB70840084203C0BF6623C1FFB70EB70B2 +:103BC000D512EB2449FFFFABC0DBB0014412E31870 +:103BD00049FFFF738402F102F203223F8002EA648C +:103BE0003C0FFB70FC824403F7C9A640C10384204C +:103BF000AE40DD9EFC01DD5A5A000145EB16EBA9F3 +:103C0000D0043C0DFFE7D83EEA67EA658C019600D8 +:103C1000B081503F8005EBA8EA65000F8004046086 +:103C2000800849FFFCAF001F800597AFC11AEA6703 +:103C3000EA658C029600EAF5EABEEBA8EB25EA6598 +:103C400049FFFCA0C80AEA67E206E807EB53C8058B +:103C500084013E07EC4DD51A84003E07EC4DD51685 +:103C6000C80AEA67E206E8072E07EC62C804840186 +:103C7000EBD8D50C840AEA2D8400EBD83E07EC2063 +:103C8000D5058400EBD83E07EC20FC81EB045A18E4 +:103C900001064412C4C8F804DD9E4412C45838001A +:103CA000810150007F5BEAD583FFDD9EFC40DD474C +:103CB00080C0DD46AE40EA8DA608C8FF2E37F01F53 +:103CC00044A2C458440000A5947150737FA044924C +:103CD000C4C85A380116882A804138051909840257 +:103CE000DD44EA52F815380499015A08A5FEF81C7B +:103CF0004412C4C83805190938009909FCC088293C +:103D000080413804990984618402DD44EA52DD4629 +:103D1000DD47AE4097F844038D44AFC083FF3805BC +:103D200019015A08A5FE50037FB0960044138D4434 +:103D3000AE08840083FF4412C4583800990938043F +:103D40009909FCC0FC008400441000C1DD43EA9DD9 +:103D5000C8038407EAF9DD4F006000518401802622 +:103D6000DD435A6802134400012CEA99DD4FEB7FD2 +:103D700000000053C8038400D53D5A00013C5A009E +:103D8000023A5A0803FAD5365A6803388402EA35EB +:103D90004400012CEA99DD4F00100053000000544C +:103DA000968C4210840BC914CA0AC8038404D52215 +:103DB0005A0801048406D51E8408D51CC80384054E +:103DC000D5195A0801048407D5158409D513CA0AE0 +:103DD000C803840AD50F5A080104840CD50B840E3D +:103DE000D509C803840BD5065A080104840DD502F1 +:103DF000840F3C0FFB52D50E5A68040D84003E0719 +:103E0000EC433E07EF74DD41C8118401EA35842696 +:103E1000D50B84003E07EF7484013E07EC43DD417F +:103E2000C8058401842549FFFAB2FC80FC0180C0EA +:103E30008400EA2ADD41C8133E67EC314412C3A175 +:103E4000804184618402DD4484014412C3A1EAB547 +:103E50008060DD44EA9D005F8007D8F1FC81FC00B2 +:103E6000DD41C010EA9D5A000305EA9D5A080AFF89 +:103E700084004412C3A1EAF9804184618402DD44D4 +:103E8000FC80840A49FFFFD4FC80FC00DD41C80AA5 +:103E9000EA9D5A0808048409D504EA9DC8038407EA +:103EA000EAF9FC80FC00EA8884203C0FFC28101012 +:103EB0000050EA8AEB9C10100053101000601010A4 +:103EC0000061FC80FC00DD41C825EA33001080F26F +:103ED0005A180121EA21EA28AE883C2DFC2800115D +:103EE00000F2C902D5004412FEF3A64896485A10C3 +:103EF000040C5A10030A5A1006085A100A065A10DF +:103F000009045A180B083E17EF12100100F21001B5 +:103F100000F38401FC802E07EF1DC80FEA333E0733 +:103F2000EF1F002080513E07EF1E100080518401DA +:103F30003E27EF1C3E07EF1DDD9EFC005A080604DD +:103F40008401D5045A08070684003E07EC08D51CF6 +:103F50005A080D0784003E07EC088421D5075A084B +:103F60000E0B84013E07EC0884203E17EC4E3E0702 +:103F7000EC3BD50A5A0810048401D5045A081105EF +:103F800084003E07EC05FC80FC002E07EF1EC831C4 +:103F90002E07EF1C5A0810053C0C01C1D50A5A081F +:103FA00011053C0C01BBD5055A0812073C0C01BD9C +:103FB000441320D0EA20EA2CDD4FC904441FFFA09F +:103FC000D503441FFFA1EA8AEB3FA6485A18030510 +:103FD000441FFFB1D503441FFFB0EB9CDD40A60199 +:103FE0005A08040584013E07EC5A84013E07EF1E7F +:103FF000DD4FEA575A08BB1B2E07EF1FE614E806F1 +:104000002E07EF1FE60AE912D50FDD455A0802FA1E +:10401000EA33840010008051100080523E07EF1FE9 +:104020003E07EF1ED503DD45C0F4FC80FC40812037 +:10403000DD402E27EF0BA601E64180E13EF7EF0BB6 +:10404000EA9B5A08034B8408441000B1DD43EA4F51 +:10405000AE3044A38D4084CADD54A608C8133C2D5D +:10406000FB3F5A2801FCDD5C5A0807F93C6FFB64F2 +:104070002E07EF0BC0F33E27EC77EAB149001B9AFD +:10408000D5EC8408441000B2DD43DD41C80B2E0797 +:10409000EF0BC8138401EA2EDD4CA60049001B8AF1 +:1040A000D50CDD47DD46AE402E17EC00DD5C5A0036 +:1040B00007F05A1801FDD5EC8408441000B3DD4325 +:1040C000DD535A080206EB0AC00349FFFECA840802 +:1040D000441000B4DD43D508EA4FAE30DD54A608E5 +:1040E000C803EA29D5FD8408441000B5DD432E0736 +:1040F000EF1C3C2DFC288E10E60310910053E804C1 +:1041000049FFFF44D541CF04440FFFA0D503440F1E +:10411000FFA110010051DD4CA6005A080305440F11 +:10412000FFB1D503440FFFB010010052DD40A601DE +:104130005A08040584013E07EC5A441000B684086E +:10414000DD43EA28EA21DD4FEA575A00BB04AE8876 +:10415000D5FB8408441000B7DD43DD41C00684026E +:10416000EAB280418060DD448400EA618408441042 +:1041700000B8DD43EAADDD4F8420EA8AEB9C840879 +:10418000441000B9DD43FCC0EA3310008060DD9EBE +:10419000DD4F00000060DD9EEA33100080613C1DB1 +:1041A000FA6A1000803EDD9EEA3300008050500025 +:1041B0007FDFE602E904840010008050DD9EFC00F1 +:1041C000DD4F441FFFCCEA8AEA21EA28DD4FEA5797 +:1041D0005A00BB04AE88D5FBEAC8EA2D8400EAA9E0 +:1041E000FC8084213E17EC17EA338801002000523E +:1041F0003C2BF65D00100053401105003C1BF65DA2 +:10420000001000543C1BF65A00000055EB463C0BD6 +:10421000F65ADD9EFC008400EBECEB2F3C0BF653D2 +:10422000DD535A080106DD4F00100052D506DD416E +:10423000EA3300108052C003840AD502FA18FE0C3B +:104240003C0BF651DD4FEA575A08AB05840249FF93 +:10425000FFCAFC80FC0080C049FFFE7184015A68DF +:1042600003054900569D800650137FF3E622E903BB +:104270005A68021B8401EAD4DD40A7815A6803040E +:104280008402D5125A680A098429AE418420DD5778 +:10429000DD40AF81D5038420DD57DD455A0802F2A9 +:1042A000DD568443AE89FC804000040E9604DD9EFA +:1042B000FC02DD41C01FDD4FEBF7EA8ADD4F001045 +:1042C00000515A18AA0AEAC8EA2D8407441000319E +:1042D000DD43EB1AD5F4B041500000518441F08326 +:1042E000122F8002A8093A108C00EB2449FFFB9B97 +:1042F000D50CDD4FEA57C809EAC8EA2D84074410F7 +:104300000031DD43EB1AD5F68407EA7BDD43DD4F50 +:10431000EA575A00DD048401D5028403FC8292002E +:10432000FC01840A8061EA2A5A1001055A1002072A +:10433000D544DD4F8420EA8AD544EA330000805218 +:104340008E06E604E83644F04150EA8CEA3DDD0F83 +:10435000040E26528400EBAB10008052D53284014B +:10436000EBAB84008040DD56EA4BEA913C0794C9F0 +:1043700049006232D50B8403EBAB8401EA350000BF +:1043800080534412000049006171DD4CA6004412C4 +:1043900000004422C3ABEABE3C4DFC28490061DA70 +:1043A000D5104402010249005E098401EA2AD509B8 +:1043B0008401EA2AAED0D5058401EA2A8402AE102F +:1043C000EB535A080A0A49FFFF75DD54EA2A8401B3 +:1043D000AE08DD58AE08EB53FC815A0001075A08BD +:1043E0000309B401EA7FD503B401EAB6B601DD9E44 +:1043F0008402AE10DD9EFC00DD4FEA575A08040C23 +:10440000DD45C809DD41C00484013E07F098DD4F59 +:104410008420EA8AFC809200FC409F01E68F4EF2E5 +:10442000008880C2800144F042343847910140F254 +:104430003C00DD0F24002E0038009600BC00C200B6 +:10444000FA00D400E00000011E00EE00FA00FA00BD +:10445000F400FA014800007184003E07EF1D840655 +:10446000D56B84003E07EF1D8407D566EA77EA82A4 +:10447000F82580C05A000204EA5BD5FB8401F823CA +:104480004900134C3C0E0442490013513C0E0443B6 +:104490004900135E3E001111490013643E001110E3 +:1044A0004900135B3E00111284214402E878490060 +:1044B0004A588006F808EA9BEAC149001357C0032E +:1044C000AFF0D5FC49001365D512842EAE41842689 +:1044D000AE40EA338440102080508421DD57842090 +:1044E000840280418461808180A1DD558401D524CE +:1044F0008401AE10D515840044100066DD438401AC +:10450000AE30DD45840ED5188401AE108401F80666 +:104510008402D5128401AE10840049005553840DE5 +:10452000D50B8400EBFBD5E349FFFF67D5E08402A0 +:10453000AE18D5DDFA00FCC09200DD4F3C100370D0 +:10454000101000A09228101000A13C17F661101066 +:1045500000A29028101000A32E17EC71101000A4D8 +:104560004412C6F0A688102000A5A68A102000A636 +:10457000A08B102000A79248102000A80020801EC9 +:10458000102000A9EBFCA690102000AA8440102067 +:1045900000AB3C23F7B6102000AC9248102000ADD1 +:1045A0003C33F64B3C23F65B8843102000AE90482A +:1045B000102000AF00208020102000B000208021BB +:1045C000102000B100208022102000B200108023B3 +:1045D000101000B33C1DFB48101000B5EB3FA6487F +:1045E000101000B6EBA7A08BA04C102000B7101045 +:1045F00000B8DD9E4413F04AEA21DD4FEA575A0025 +:10460000BB04AE88D5FBDD9EFC0080C0DD4FEA57C1 +:104610005A08BB2349004E6DDD4F00100050C10306 +:104620005A18FB102E17EF07C9042E17EF06C110FA +:104630008400EBEEEBA18400EBFB8401EAD4D519F6 +:10464000CE08EB3C5A08A00B44030FA0D50CC60AB9 +:10465000441FFFA0D50DC6F6D50C5A08A104EA8E5A +:10466000D502EAC9EABAEA20441FFFA0DD4FEA8A70 +:10467000FC809200FC00E60A4EF2007A44F0448886 +:10468000EA8CEA3D4A003C000A4468E4E4E4E4E4DD +:104690007CBEC903FA13D50F5A18010BFA0E3C0B56 +:1046A000F4CE3C0BF4CC840C3C0BF4CDD5605A1802 +:1046B0000207FA093C0BF4CEFA0ED5F45A1803049B +:1046C000FA04D5F9840F5A180453D5F58401C104AE +:1046D0005A18010684023E07EF00D54984005A109B +:1046E00002FC5A1003045A1804433E17EF00D53F4A +:1046F000C1075A1001065A1002045A1803393C1B0C +:10470000F4C8D535C903FA0ED5055A180108440076 +:10471000003C3C0BF4CAFA13D5145A180207EA609D +:104720003C0BF4CAFA09D50D5A180305440000647D +:10473000D5055A18041D440000823C0BF4CAFA0443 +:104740003C0BF4C9D514840AC1105A180104FA04A8 +:10475000D50C5A180204FA0ED5085A180304FA1890 +:10476000D5045A180405EAB43C0BF4CBFC80920043 +:10477000FC00FA093C0BF4CE3C0BF4C984023C0B60 +:10478000F4C8FA2E84003E07EF003C1BF4CC3C1B1F +:10479000F4CB3C0DFB45844C441000503C1BF4CA48 +:1047A0003C2BF4CDB440441E7FFFFE56B620B4200F +:1047B0006610F0005810A000B620B440461FF1FF6C +:1047C000EBF4FE564210D808B620B440461F8FFFC7 +:1047D000EBF4FE564210E408B620B42066108E00BA +:1047E00058108400B620FC80FC4080C18420AE407C +:1047F000B40280E24200740B81245A080106B40618 +:1048000042007408B606B4074200740BC805B4062B +:1048100042007409B606B407EACA5A080107B4068A +:10482000EA9AB6068006EB60B407EACAC80AB4067C +:10483000EA80B606490015393E07EF818006EB6035 +:10484000B40796045A080105B406EA54B606B4073C +:104850009604C804B406EBF3B606B407EA555A0842 +:104860000105B406EA7FB606B407EA55C804B406E3 +:10487000EAB6B606B407EADA5A080105B406EAE071 +:10488000B606B407EADAC804B406EB30B606B407D5 +:10489000EA5F5A080105B406EA83B606B407EA5F80 +:1048A000C804B406EACEB606B407920596175A08AD +:1048B0000106B406EA49EAB0B606B40792059617AF +:1048C0005A080207B406EA4958000040B606B40781 +:1048D000920596175A080307B406EA495800006083 +:1048E000B606B407920596175A080406B406EA49B4 +:1048F000EAE3B606EA74EA5FC807B40642006C0948 +:10490000B606EBE7FCC0B40642006C08B606EABD8A +:1049100092075A080111EABD9637EA34B427840099 +:1049200092299657F932B40754100E00B406660067 +:104930000E00F83FEA7496045A080112EB5F661005 +:10494000800110148001B427922C9657F91EB407E9 +:1049500054107000B40666007000F82BEA74EA5533 +:104960005A080112EA74EAB6EA68B4278408923554 +:104970009657F90BB42746000E00FE46B446460F84 +:10498000F1FFF81500048001EADA5A080116EA740A +:10499000EB30EA68B427840992389657F8F6B427C2 +:1049A00046007000FE46B446460F8FFFEAFBFE1637 +:1049B000FE0FB60683FFEA74EACA5A080113EA74C6 +:1049C000EA80EA68B4278402922F964FF8DEB42773 +:1049D00044018000B446FE46440E7FFF4E00FFE9CE +:1049E000FCC092008E01E60DE84BFC0080C144F053 +:1049F00047F8EA8CEA3DDD0F0E162A30363C424875 +:104A0000804E5A647000B401EA9AB601D508B40128 +:104A1000EA80B601490014493E07EF818006EB6049 +:104A2000FC80B401EA54D51FB401EBF3D51CB401EA +:104A3000EAE0D519B401EB30D516B401EA83D513F9 +:104A4000B401EACED510B401EA49EAB0B601EBE709 +:104A5000FC80B401EA4958000040D505B401EA4998 +:104A600058000060B606FC80B401EA49EAE3B601EA +:104A7000440000BDDD42FC808402AE10FC80840254 +:104A8000AE10DD9E92009200E60C4EF200C1FC00DA +:104A900080C244F0489CEB27EA3DDD0F180044003B +:104AA00070006A016A016A016A014C01A000CC0031 +:104AB000FE002E01B402EA714E0200A9B40296571C +:104AC00066000E0040100524B622B422840092290C +:104AD0009657F85B44000070DD42B4069209D55C3D +:104AE000B402EA714E020093B40296576600700059 +:104AF00040100584B622B4228401922C9657F845C2 +:104B000044000071DD42B406920CD546B402EA714D +:104B10004E02007DB442440E7FFFFE16964F4010B9 +:104B200005E4B626B4268402922F964FF82E440050 +:104B30000072DD42B406920F960FD564B402EA719A +:104B4000C065B442460FF1FFEAFBFE1696574010CF +:104B500006A4B626B426840892359657F816EAC8F5 +:104B6000DD42B4069215D518B402EA71C04FB442C2 +:104B7000460F8FFFEAFBFE16965740100704B62635 +:104B8000B42684099238965749FFFD76440000798F +:104B9000DD42B40692189617D535B402964C420001 +:104BA0006C0940100764B622B402EA71C805EBE74D +:104BB00044100168D50344100E10EA7CAC40440058 +:104BC000007ADD42B406EA71D51DB402964C42006B +:104BD000700940100784B622B4024400007BDD4215 +:104BE000B4064200700BD50EB402964C4200500938 +:104BF00040100684B62244000077DD42B40642002D +:104C0000500BDD42FC808402AE18FC808402AE189A +:104C1000DD9E9200FC62A6098121F281814381849C +:104C20005A08040584003E07EC5ADD41C007EAFC3F +:104C30005A08AA052E07EDC8D504DD4F0000005024 +:104C40004E0202995A08FB0448000295F001EAEA74 +:104C5000490014B88400EB82DD41C00CEAFC5A081C +:104C6000AA0A2E67EDC82EB7EDC940731009979FA9 +:104C7000D509DD4F0060005000B0005140731009AD +:104C8000979F8401EA4D8400EB73EB5F5A18041878 +:104C90002E17EF11C1043E07EF11D54A2E07EC1075 +:104CA0005A080103EBEB84208009DD578401EA31C7 +:104CB000DD47DD46AE40EA98C0FFD53ADD47DD4628 +:104CC000AE40DD41C804DD41C820D527DD455A008E +:104CD0000204DD54D5162E07EF0AC00B3C1DFB8ED7 +:104CE0002E07EF0A8E01E201E904EA67E602E8F224 +:104CF0004400008ADD428401EAA9DD5B4800024DE0 +:104D0000A608C8E2EA29D5FDEAFC5A085507EAB226 +:104D1000840280418466DD44DD59A6005A00020900 +:104D20003C0DFB54A6405A1802048420AE402E07C6 +:104D3000EC7F8C013E07EC7F40031C848EE1E6ECA7 +:104D40003E07EC7E4EF201EE44F04B5838779D0161 +:104D500040F3BC004A003C0018004C00C001D601E2 +:104D6000660372038E03C803C803C8039E03B60319 +:104D7000EA78EB674900145EF001EAEA4900142280 +:104D80008006802B8049EB848400EA4D5A600F0333 +:104D9000F8ADDD4F84CC000000505A00FB04480001 +:104DA00001D4F8A48EC18401E6C63E07EC694EF238 +:104DB00000AE44F04BC03867990140F33C00DD0F72 +:104DC0000C003600600026012E0166008400EA4DCA +:104DD0008401EAE8FA318404DD43EB0AC80884045C +:104DE000FA3ADD4384C449FFF898D5588404FA3B65 +:104DF000DD43FAC4D5538400EA4D8401EAE8FA3170 +:104E00008404DD43EB0AC8088404FA3ADD4384C510 +:104E100049FFF883D5438404FA3BDD43FAC5D53E08 +:104E2000EAE884C2F88EDD41EA33C03E8401EAE854 +:104E30000000805284C0106F800F5A08AA284900D1 +:104E40004A588401EBFBDD4F001000530020005452 +:104E5000440FFFA0FE0F5A280110EBA14400988CCC +:104E60003E67EF0749004AB9DD4F441FFFBB3E676D +:104E7000EF03EA8AD508EBEE440062383E67EF069E +:104E800049004AABDD4F8420EB9CEB3CC806EAAFFF +:104E900084C1C004FAD0D502FAC9EAB34E03015561 +:104EA000841FEA3BF84E2E27EF06C202EA4D0000AF +:104EB00080525A08AA150020805484005A28010BF9 +:104EC00000308053442FFFA0FE9FEA4D3E27EF069F +:104ED000D502EBA1EBEE840010008052EAAF4E0346 +:104EE0000133480000ECEAACEA76480000E88400B0 +:104EF000EA33EA4D8401EAE800008055001080544E +:104F0000EB463C0BF64FFAC2F81C8404FA3FDD4333 +:104F10008400EB82480001038402EB0080268401B8 +:104F2000EB4B49FFF9FF80C08405EB00F80A8400D1 +:104F30002E17EC00EA4D8401EB825A18010584C952 +:104F4000480001033E07EC00EB009E31E60C4EF2F8 +:104F5000009F44F04D60EB2740F03C004A003C00CD +:104F600018002C0182002C0182002C01CE002C01A3 +:104F70001801820042002E008400EB9ADD43840178 +:104F80003E07EC56DD53EBAD8401EA35F8098400A9 +:104F9000EBB5DD4384013E07EC56DD53EBAD480035 +:104FA000007984004410004BDD43EA338401001093 +:104FB0008051DD4384C084013E07EC733E67EC08FA +:104FC000F859EBBAEBCFB401EA83B6013C0DFB69AB +:104FD0003E67EC28EA833C0FFB698400EA66EAA39B +:104FE000D558EA33DD53EBAD001080518401EA352A +:104FF000DD43DD4F8026EA57EB4BF837EB2A5A00AA +:1050000002493C2DFC28000100550031005440317C +:105010008100001100524231C00800010051804659 +:105020003E17EC2A3C3FFB5349001A18D532840046 +:1050300044100047DD43EA33840100108051DD4312 +:10504000DD53EBADEA745A080308DD4CA6005A00A4 +:1050500003048402D5028401EA3584013E07EC4A48 +:10506000DD4F8427EA57EB4B490019D0EB2A5A0051 +:10507000021149FFF8D1D50DEA33840100108052A6 +:10508000EA4D3E17EC533E07EC68D5038402EA4D27 +:10509000EB2A5A00020448FFFF54DD4F84C0106021 +:1050A00000513E67EC693E67EC00DD455A000205A1 +:1050B0003E67EC87D5038405EB0084C1D5458006A7 +:1050C000802AEB4B49FFF98BD51C8400441000600B +:1050D000DD43800680294422C3D9503F800F49FF19 +:1050E000F99D9780D5318006802B804A503F800FF4 +:1050F00049FFFCCCD5068006802AEB4B49FFFC74A7 +:10510000EB2A5A0002DCB40AB60C84CBD51D5A68CF +:10511000010649FFF619FAC3D5178402EA4DD5CE28 +:10512000840284C1EA4D3E67EC4BDD41C0073E6717 +:10513000EC4B840F441000FBD504840F441000EBAB +:10514000DD43D5BCFAD0EB2A84205A0001055A0869 +:105150000206843BDD4F101000502E07EC69C80892 +:10516000EA78EB6749001266F001EAEAF80E800679 +:10517000D513EB3CC803EAAFC0068400EBEEEBA10D +:105180008400EBFBF001EAEA49001242EA4FEB44EB +:105190008400EAE88401FCE2FC2080C35A00070492 +:1051A000480000C5E62C4EF2010F80E244F04FBCEF +:1051B0003817850140F0BC004A003C00180044004C +:1051C0007000080208020802080252019C00C80090 +:1051D000F4002E01A621EA5F4E0200F9A660440FFA +:1051E000FF80FE0FAE20B44397D766210E004071BA +:1051F0001D24440000B0B6E3DD42B4069209D51484 +:10520000A621EA5F4E0200E3A62197D7EA54AE2119 +:10521000B443440000B16621700040711D84B6E3C0 +:10522000DD42B406920C9617DD42FCA0A621EA5F8F +:105230004E0200CDA62197CFEA9AAE21B443440E88 +:105240007FFFFE8640711DE4440000B2B6E3DD42FC +:10525000B406920F960FD5E9A621EA5F4E0200B779 +:10526000A621461FF1FFEA7FAE21B403EBF4FE0E48 +:1052700097D740001EA4B603440000B8DD42B40630 +:105280009215D5D2A621EA5F4E0200A1A621461FA3 +:105290008FFFEAE0AE21B403EBF4FE0E97D7400097 +:1052A0001F04B603440000B9DD42B4069218D5BC11 +:1052B000A62197D4EACE40001C84AE21B4434221FB +:1052C0006C0940711F64B6E3B403EA71C805EBE7EB +:1052D00044100168D50344100E10EA7CAC40440031 +:1052E00000BADD42B406EA71D5A0DD414E02006F7E +:1052F000B44697FC4221700940711F84B6E6B4069B +:105300004400007BDD42B4064200700BF84D97D498 +:10531000B443440000B74221500940711E84B6E3F3 +:10532000DD42B4064200500BF83F5A080B408E2174 +:10533000E62DE84944F05140EBC8EA9E4A003C00A3 +:105340000E141A20262C3238843E46505A00B403DC +:10535000EA9AD537B403EA80D534B403EA54D53198 +:10536000B403EBF3D52EB403EAE0D52BB403EB3052 +:10537000D528B403EA83D525B403EACED522B403F5 +:10538000EA49EAB0D51EB403EA4958000040D519ED +:10539000B403EA4958000060D514B403EA49EAE3CB +:1053A000B603440000BD48FFFF415A0805105A10DB +:1053B00001075A180309B403EA7FD503B403EAB618 +:1053C000B606FCA0843BEA8BAE40FCA09200FC62D7 +:1053D000F081F282F383EA8BA7C0A7804402FE51DA +:1053E000A60092E48161979FEABC5A7001044800CC +:1053F00000979E31E603E90E5A600503F81BDD4F66 +:10540000000000605A00A1072E07EF9F5A08010311 +:10541000F811EAFC5A08AA03F80D4E42009CDD413F +:10542000C00BDD40A601EB295A08040744000088A0 +:10543000DD4248000090EA78EB67490010FB440227 +:10544000C38EEAEA490010BE5A600505840049008F +:1054500045DBEA8DEA38EA37A6085A080104AED0DF +:10546000D5FCDD41C04C44A3F04A44B00055440093 +:10547000008210B50000DD42DD455A08021F2E1FD4 +:10548000EF102E0FEF0F4423F41C4E170014A6D07C +:105490005A3802FDEAB2804184668402DD44440049 +:1054A0000083DD42DD47DD46AE40DD455A08021887 +:1054B000D5214E06FFEED5EF44700064EAA74E07F3 +:1054C000000A8EE110B50000840A97F9EA2DCFF7A3 +:1054D000D5E22E0FEF0F4E06FFF6D5DD4402FEF6A5 +:1054E000A6005A08EC08DD40A6015A080A04490043 +:1054F0001703EA25A6085A08E1FFD50C44000084EA +:10550000DD42EA25440FFFE1AE0880418402846158 +:10551000DD4480068029F201EB84D51C5A700B060D +:105520005403800D5A080517DD41C014EAFC5A00E7 +:10553000AA1244A2FE508400EB0B8026800780490B +:10554000F302F40349FFFE2AEAB15A00FB04840186 +:10555000EB1FFCE23C0FFC2ADD9EFC67F08D81A175 +:105560008182C407C30CFA10846684A180C0D51060 +:10557000C30BEB05840180A384C4D50AFA708401AF +:1055800080A384C6D505EAB4846484A180C040E3C6 +:1055900000139781F8294082801397D9F08A4492AA +:1055A000EC9C2E07DE0A44B2EC3844A2ED00F08BEE +:1055B000442255B88400F30DF821842BF83584007B +:1055C000806C8040381481114E17000922518000F0 +:1055D000405284B6976BAD58D502AC988C01964179 +:1055E000E22E8C62E9F03C07F66BF0893C07F66A24 +:1055F00083FFF08A2E07DE0AF08B14CF8000149F01 +:10560000800114BF800214AF800314DF800414EF04 +:105610008005148F8006F787F68883FF8400842D29 +:10562000442255B8F30D808C44527200F91EFCE7F9 +:10563000FC01F081440004733C0BF66B440FFB8CBF +:105640003C0BF66A2E07DE093E07EC818C0180C117 +:105650003E07EC82C920F8058481F80B8066F8319A +:1056600044029ECA844180208062490010B0846157 +:1056700044029ECAEB64F20183FF8083F822441245 +:10568000A1EA4402A82AEA32DD4944529ECA4412E1 +:10569000A04AD5205A180149F80584608083F8098A +:1056A000F8104402A05A8020804680664900108F7E +:1056B000F2014402A05A4412A69A83FF80668480B5 +:1056C00049FFFF4D4412A37ADD5E4402A9BADD49C9 +:1056D000FC81A428505280409603120283000202EB +:1056E00081709603120284900202FFFD960312025B +:1056F000831D0202818D9603120284AD0202FFE136 +:1057000096031202830102028171960312028491B0 +:105710000202FFFE96031202831E0202818E96038E +:10572000120284AED9D7FC81381105118820E023FC +:10573000E90AEBB65A08010B3C03F894C0085EF086 +:105740008078E80444008000DD9E8400DD9E3C1DDE +:10575000FC2A2E07EC42A68EC80CEA4C5A08010A15 +:105760009411AE0AA6098E01F8079401F80BD51121 +:10577000A609AE8A8E01FE148442400008168E01EE +:1057800083FF96033C0BF66BFE033C0BF66A83FF2C +:10579000A6093E07EC818C013E07EC82DD9EFC678A +:1057A0002E672893F08D81C181022E072892CB05A8 +:1057B000802080408401D5048026844180C097C128 +:1057C000F83340B080134091001344D2EC3844C207 +:1057D000ED003C0DFC2A97B144A2EC9CB71FEBD125 +:1057E00014DF800214CF8003F82DF839842BF83DA4 +:1057F00084608008820D808C80439659E22BE814E7 +:1058000038150D114E17000D22500000405284B67D +:10581000976BAD40A440964B5EF0FFECE802AC8085 +:105820008C618C02D5EB3C07F66BF0893C07F66A7D +:10583000F08A83FF3C0DFC2AF483B71FEBD1150FD0 +:10584000800214EF800414BF8005F786F687149F4A +:105850008008A602F08B840083FF842D442255B873 +:10586000F30D808880A083FF49003E3EFCE7FC01E9 +:1058700080C0F18149FFFF6DA036A075F201846000 +:1058800049FFFF8FFC813C0FFBA2DD9E3C0FFBA07C +:10589000DD9E3C0FFBA1DD9EFC41846380C080E265 +:1058A000501F8006FA50B400EBE9EA6CB607F80F17 +:1058B000A47044920000F81010138010B406501F1A +:1058C0008006FA508464EBE9EA6CA83949003FB4D9 +:1058D000A4703C3DFBA08A010014800292014000AC +:1058E000043783FF10138011B406A072A0B60031F4 +:1058F000800C848149000FBEFCC1FC6580E18420DE +:1059000080C4121F800D5A48040504900006D50378 +:105910000490000502310439A613854050BF801C55 +:10592000A7528083B61F802980098445EBD114AF2C +:10593000800214AF800314BF800449003DAC020F05 +:10594000800EAC3802058001AC39501F801A8009E6 +:10595000804A8463EBE9020F800D5A6804053C0B12 +:10596000F666D5055A6805043C0BF661AC3B501F42 +:10597000801A800984408464EBE9020F800D5A6824 +:1059800004053C0BF650D5055A6805043C0BF64C53 +:10599000AC3A5A60040E84003E07EC3D22138003AB +:1059A0003C039880E020E80484013E07EC3DFCE5E0 +:1059B000FC0180C1F3818460B61F3E37EC3D49FF96 +:1059C000FF6DB41F8026F2018460848449FFFF9735 +:1059D0002E07EC055A08010722130003440395B46F +:1059E000AC40FC81B460B42080A0927096098440E1 +:1059F000986AB4819290E264E804B42180649609C4 +:105A00008C445A2820F7DD9EFC2080E180C049FFAD +:105A1000FFEBE6E8E85944F0582438779C0040F35F +:105A2000BC00DD0F081A2C3E5466788C961F9643F6 +:105A30003C1BF85D964F3E17EC768400D5463C1330 +:105A4000F85D94049600FE0F3C0BF85D8400D53D94 +:105A50003C13F85D961F400081043C0BF85D840008 +:105A6000D5343C13F85D400081849643EB283C1B01 +:105A7000F85DAC408401D529961F96433C1BF85C29 +:105A8000964F3E17EC768400D520940496403C0354 +:105A9000F85CFE473C1BF85C8400D5175410000FDF +:105AA0003C03F85C401005043C1BF85C8400D50DF9 +:105AB0003C13F85C40108184964BEADF3C1BF85C99 +:105AC000AC408402D5028400842FB626FCA092004C +:105AD000C9104020380954003FFFC00696C48823EF +:105AE00096489201D5FB964FFE555C008001DD9EE5 +:105AF0008401DD9E5450000C848090A2E28510F059 +:105B0000800054100030540000C090249006E281C0 +:105B10004002000610F10000AE18DD9EFC0180C1BD +:105B2000B42380A0C952847F3E37F0B43E17F0B34F +:105B3000C41BC216402020095401000C9002E22030 +:105B400054010003400080062E27F0B240003C24A0 +:105B50004C2000523E17F0B13E07F0B2D56312233D +:105B60000025480000A0541000032E07F0B24C009E +:105B7000C013EB92E602E8038C01EB2EEB92E602F7 +:105B8000E90310130040EA96EB10E8098400EB2EBD +:105B9000EBD0D5053E47F0B13E17F0B25452BFFFEF +:105BA00044000FFF92A2D00A021300268403425041 +:105BB000807390A212530025D503125300250203CF +:105BC000002512030026F8455A100403F8424E42FD +:105BD0000080920896015410000C9022C23C844030 +:105BE000960F40110406E240400784242E17F0B2BD +:105BF0004C1040152E17F0B1E624E8048C213E1716 +:105C0000F0B12E17F0B1E624E902EBD0EA96EB10E2 +:105C1000E8098400EB2EEBD0D5053E27F0B13E0716 +:105C2000F0B202030025120300268400EBB9501FD6 +:105C300080058005EAF5EABEF839EB25001F8007EC +:105C4000940140000440001F800588013E07F0B029 +:105C500048000083960F40110406E2404007842468 +:105C60002E17F0B44C1040182E17F0B3E622E804BB +:105C70008C213E17F0B32E17F0B3E622E802841F02 +:105C8000EAD7EA96EB10E80B84003E07F0B3841FD6 +:105C9000EAD7D5053E27F0B33E07F0B48400EBB950 +:105CA0008005501F8005EAF5EABE49FFFF25EB534A +:105CB000001F8006940540000480001F80054000FE +:105CC00004602E17F0B0FE0F10030059D545541094 +:105CD00000032E07F0B24C00C013EB92E602E8037B +:105CE0008C01EB2EEB92E602E90310130040EA96DA +:105CF000EB10E8098400EB2EEBD0D5053E47F0B160 +:105D00003E17F0B2540280FC920210030059CA24DC +:105D100092A82E07F0B4974F4C02C01B2E07F0B389 +:105D2000E602E8048C013E07F0B32E07F0B3E6026A +:105D3000E90410530041D503841FEAD7EA96EB101B +:105D4000E80B84003E07F0B3841FEAD7D5053E2751 +:105D5000F0B33E57F0B4FC81FC6080C12E1010E51A +:105D600081625A10010544A00708D50344A003E846 +:105D70005A0001055A00023EF80C441397DCA4486F +:105D80003C2C041A964BC2035A2805068400EB2DBE +:105D90004800009AB44B662100044E23009540C091 +:105DA0008013542600039FD35C7380013E77F0B6C6 +:105DB0003E7010AACF0C2E37F0B7CB0B2E57F0B594 +:105DC000DA063C2DFB595CF103E8E8028400EB2D78 +:105DD00054908003800C80273E97F0B5F838CF5C54 +:105DE0002E17F0B7C13E3C1DFB59E341E955D539AB +:105DF000EADFA440EAA4964BC0CA5A0005C9EBFEEC +:105E0000E60AE961B40BEAB6C85E40C080135406E6 +:105E100000039FC35C7380013E77F0B63E7010AA0A +:105E2000CF0E2E27F0B7CA0D2E57F0B5D808EBF0DD +:105E30005CF003E9E9048401EB2DD5038400EB2D2C +:105E400054908003800C80273E97F0B549FFFE42B6 +:105E5000CF2E2E17F0B7C1053C1DFB59E341E927B2 +:105E600084013E07F0B68400EBB9EAA45A00042C82 +:105E700000030045100300462E07F0B6100300454E +:105E8000C82202030025C8058401EBB912030026CD +:105E90008401EB2DD518C0EA84001203001F802670 +:105EA000800C8441806B8087F80BD5E0C0DF8400D4 +:105EB0001203001F8026800C8440806B808749FF7E +:105EC000FE2FD5D4FCE0DD9EDD9E4422AB4AB640D9 +:105ED0004432AC764422ABAEA881A8C94422AC12AD +:105EE0008460B641ACC4ACC5ACCCACCD8420B4A00D +:105EF00080619929ACE0990A8C22ACE05A1840FBE9 +:105F0000A101840080204432AC7698A0AC509883E4 +:105F10008C02AC505A0864FBDD9EFC21A4C0842096 +:105F200096DB121F80033C57EEE9848084CF4470D7 +:105F300001EA96615CF08064E80A4020840903006D +:105F40000000A44052210031964BD50A0300000006 +:105F500050227F9CA4409041964B52210031FEB4C8 +:105F60009691FE54EABB8830964BAC40A440964BC9 +:105F7000E061E803A4C096DB8C818C025A48C8DB40 +:105F8000123F8003EA6C960340028007FCA1C80E12 +:105F90003E07EC3EA40EC80684013E07EC3E84009A +:105FA000DD9E5A001FFB8401DD9E84003E07EBFF4F +:105FB000A40FC80684013E07EBFF8400DD9E5A084B +:105FC00031F4D5F9FC442E4010E0802080022E27C9 +:105FD000DDFAE282E8043C57EEF6D5033C57EEF8D2 +:105FE000E282125F8000E8052E47DDF49723D50496 +:105FF0002E47DDF597238440124F8001122F800237 +:10600000C8065090800CB4E1FB90D5065090800EED +:10601000A1C945000032225480004E9300079CA97C +:1060200040238820A490F80C4647FFFF50420FFF02 +:1060300050287FFF8885DA0840439020A4A09693DB +:10604000122F8002D5179521411390008C848887E8 +:1060500002688000A4A097B39693E046E807024840 +:1060600080009723124F8002D505A5209723124F59 +:106070008002952998BCA590022F80028AC297B30E +:10608000126F80035A30010448000067EA6CEAB9D5 +:106090009603964BE02050287FFFE81DE0A2E8071A +:1060A0008C828887A420F805F808AC20F8328EE2AC +:1060B0009643EAEF960383FFFE0C44100064EB2145 +:1060C00040307C0AF082F383F002F103960383FFF1 +:1060D000AC38D53EEAEFE0A296C3EA6C9643EB0EED +:1060E00097835001FF9CFE0C40001816500000647E +:1060F00041107C0AF084151F8005E80B8C8299BC46 +:10610000A430F810F086F187F006F1079603AC3062 +:10611000220480004E07001D407380200203FFFF11 +:1061200083FFF404F50596034222802440107C0A84 +:10613000EBE5420010698460882244200064EA5143 +:10614000F086F187F0068EE29603F107AC38840101 +:106150003E07EC3EFCC449FFFF1CC01C2E1010E0A3 +:106160003C07EF025CF080248420E902EA7B022FE6 +:106170008003880196932214800044300064FE9CC2 +:10618000407384209603A478400100169A08960371 +:10619000AC38FCC4FC208480C83AA4D610308009F6 +:1061A000847FA90CA90D8381BC8ABC8BAECCAE0DBB +:1061B00080C045116618B482F83B4E37001CF83F8A +:1061C00005008004A0CDF845A8CDA6CC8CC1A90CB3 +:1061D00097B35A38FF03AE0CA6CDE003E902AE0D2B +:1061E000B4628381BC0B88E3A4F8BF0AF849BB8A78 +:1061F000BC8B8C015A0820E184004E670007A4166E +:10620000B44240010020A400AC08FCA0A417100078 +:106210008008841FAE0E8400AE0F8400A90EA90F63 +:106220008381BC8CBC8D80C045116550A11195C186 +:106230008887A4E096DB83FF4E37002DA5203838F1 +:10624000810197234241906883FF05008006A0CF1B +:106250008890E2908865886F83FFA8CFA6CE8CC116 +:10626000A90E97B35A38FF03AE0EA6CFE003E9029A +:10627000AE0FA0D18381BC0D88E3A4F8BF0C96DBE0 +:106280004051FC0A8867E2678885888F83FFBB8C52 +:10629000BC8D8C015A0832CC84004E670007A417CD +:1062A000A09140010020A4005CF00191AC09E90537 +:1062B00084013E0010DFFCA084003E0010DFFCA043 +:1062C000FC6080C12E168F2E4E120099814680E40C +:1062D000953140901000020480002EB728922E675E +:1062E00028B49603C34CF87DF84B4E0200884E73D9 +:1062F000008640152CD7808797B1964980074421A6 +:106300006698E201E808383100008C018883972103 +:106310009601D5F88400806044216698E223E9085C +:1063200038510C008C618805960196D9D5F82E104D +:1063300001CE8E01E2814040BC1B2E1001CF9601A0 +:106340008460420080013C7C017F80A3E204E90D6F +:1063500040239020A450964BE061E804A4D080A490 +:1063600096DB8C819721D5F302248000405314A042 +:1063700044115C00961338209400D533F83296030C +:10638000EB79EBC183FFC03ACF39406518572E1027 +:1063900001CC94939691E2419C174020BC1B2E1097 +:1063A00001CD96014200800197B13D0C017E8087AE +:1063B0008027E202E90D40580820A4E896DBE0833C +:1063C000E804A528802297238C419691D5F30224D6 +:1063D0008000406098A0441155C096133820980062 +:1063E0004220086850010032E2028023882F846036 +:1063F00044200064EA519603EB79FCE0FC6581805F +:10640000220F8030F0832E072892F0822E0728B4C6 +:10641000F0842E072893F1818162F38681C4049F62 +:106420008016227F802E006F8064F08540A10408D2 +:106430004E420087F0024011001654D000FF55C0B4 +:1064400000FFF00250807FFDC60F440163D05CF670 +:106450008002382009018481E90340447007800CE0 +:10646000802B806EF8E0F8844020F020A450F8E7FC +:10647000F8F0AC50B429421070735CF68002B62973 +:1064800040A470078401E902800A96005CF680024D +:10649000F0848401E902800A9600F08585414481F8 +:1064A00063D0F006E20AE94B405E28014E55001425 +:1064B0004165A801C607F817F404F81DF508056F33 +:1064C0008007F820F8BBE020E806F8244026A80161 +:1064D000F8C0F829F002405E2800E0A0E82B4165F2 +:1064E000A800C610401B001338245901800C806E90 +:1064F00083FFF405F588156F8007F895F508056F9B +:10650000800741665820020B000083FFF897E020C7 +:10651000E811F10141509420021A800083FF4025C8 +:106520003400F897121A8000B42942100873B62973 +:1065300083FF5005000154A000FFD5B4FCE5F00432 +:10654000400100169640548000FFF005F18251C0D2 +:106550007FFDC60E44016240E62238200901E804AE +:10656000404E2007D501800C802B8460F85C894C5C +:1065700002050000F10183FF4020A020A450F85F35 +:10658000F868AC50B42942102073F002B629E60234 +:1065900040AE20078400E802800A9600F087F002EF +:1065A00085A144E162405DC00002F006E20DE960B1 +:1065B000405434014E550022F00443568024C61046 +:1065C0004025D4019651800C382709018460F407D6 +:1065D000F589155F8008F827F509055F80084005F3 +:1065E000D401F828E020E809F82F121B0000F1027E +:1065F0004020B4014E00FF9AF00540543400E0A062 +:10660000E832F00443068024C6134005C000808AA7 +:106610009641382701018460800C404E701AF5893C +:10662000150F800849FFFE4EF509050F800840054B +:10663000C00041560020020A8000F10396038A0739 +:1066400083FFE020E810F10141609420021B00006C +:106650008820964B83FF121B0000F1024026840025 +:106660004E00FF645006800154D000FFD59FFCE52A +:10667000FC688120EA458101F387838585405A00C3 +:1066800001042EA7DDDC3C13EEECF1868420F18EB4 +:10669000F18FC4125A0801053C17EEF1D5033C17DF +:1066A000EEF0121F801A5A0801053C07EEF2D514CD +:1066B0003C07EEEFD5112E07EC3E5A0001092E07DC +:1066C000EBFF5A0001053C07EEF4D5028004120FDF +:1066D000801A3C07EEF3120F801B4E83001F8400CC +:1066E00012810004A814A8152E7728922E0728B529 +:1066F000511100085131000C04C10000F0852ED763 +:10670000DDF65061001081C7FAB0455000C050BF9F +:106710008038443163D0D51C8400AC158400A816A1 +:10672000A8172E7728B45111000A5131000E04C168 +:1067300000012ED7DDF750610018F7854450003274 +:10674000455000C885C150BF803C44316240840040 +:1067500012088000840080203A030420842082C92B +:106760008201804102F88000020B000040F4BC204E +:1067700002F78000960341278011E1C0E803122848 +:1067800080000A0B00018C41960340F07C0A8801CE +:1067900041700406898F9691802089974C2AFFE4E6 +:1067A000B606840015030001802C80408C01960100 +:1067B0001A2080014C02FFFC2E068F2E02688000FA +:1067C0005A08011C40049820A4003811990196032E +:1067D00042008068442000648460F48BF58A153F91 +:1067E0008009151F8008EA519603051F8008053FA0 +:1067F0008009F50AF40BD50540049820A4009603FF +:10680000F106E001E805F1078400AC08FCE84E83DE +:10681000000C40631C1612098000020880004070C2 +:106820001CF697F8D50A40631CD61269800002084E +:10683000800040001CF697F8C41402098000C009CB +:106840009E694C0080075A0001058EA24C02C006CA +:106850002E07DDD5EBFDD5082E07DDD4EBFDD504E5 +:106860002E07DDD6EBFDEA455A080107000F8033FD +:106870008C019600EBFDF83B52640001964B9603A9 +:1068800097B0022880008086F84F80AD151F8006E3 +:10689000F856051F800602388000CF0440270C0000 +:1068A000D507F0058E014C70400D4021B80196913E +:1068B00040048820A4009603E140F82DF83EFCE84F +:1068C0004051B8014021B800404494204034882011 +:1068D000A420A4589603964BE02040050013E81628 +:1068E000A460A4988A229649E201E82B003F8033F5 +:1068F000021F801A020F801B83FF964B9603F181C3 +:10690000F08296A9F813F819FCE8A458A4E08A23A9 +:106910009649E201E816003F8033021F801A020FF9 +:10692000801B964B9603F181F082B77F15CF8003D1 +:106930008009802C83FF9691808680AD49FFFD60A1 +:10694000FCE8FC4081408400EB0B8400AC08812112 +:10695000AC108024A01D80E280C444200032806AF4 +:106960008481EAE984A0EAB1E2A0E817A031946941 +:1069700038001501D810A03202248000380015011B +:10698000E240E802EB79A03338000401A478E22069 +:10699000E802AC388CA1D5E884003E07EF5EEAB18E +:1069A0005A08011202148000E628E80DA4785CF071 +:1069B00080B4E80904130008B4215EF08209E903F9 +:1069C0003E07EF5EFCC03C23F7B196415000806467 +:1069D0005CF100C89601E8242E27EF5B5A280106D7 +:1069E0005010805A9609DD9E5A2002062E37EF6419 +:1069F0005A380206501080509609DD9E5A20030432 +:106A00005A380306501080469609DD9E8E44E649AA +:106A1000E9048E64E669E804501080329609DD9E30 +:106A2000FC002E17EF015A1801122E17F0AC8C2122 +:106A30009648E62BE8043E17F0ACD50F842A3E17A3 +:106A4000F0AC84203E17EF01D5082E17EF5BC90587 +:106A50003E17F0AC3E17EF013C1394ADAC40AC4494 +:106A60002E17292C5A180115EB3FA6485A18031166 +:106A70002E17EF5BE625E8082E1729B2AC402E173B +:106A800029B2AC44D50544100078AC40AC442E1774 +:106A900029435A1801423C1DFB48C93E2E27292C88 +:106AA0005A28013B80C0DD4CA6005A080306840A20 +:106AB000F804AC30D531800149FFFF87AC302E0798 +:106AC000EF025A080104EA60AC30EBBAB401920557 +:106AD00096175A000105B401EA71C81E2E07EF642B +:106AE0005A08011B3C0C00A7A4005CF00051E914FB +:106AF0002E07F0ACE60AE8103C0C00A8A641C10342 +:106B00005A181F0BA6008E0BE61DE80684013E07EF +:106B1000EF01EA60AC30FC80440395B7A640440323 +:106B200095B6A60040000504DD9E440395B9A60075 +:106B3000441395B8A64840008104441F6A44882045 +:106B40005CF0805AE903440095BCDD9E440395B493 +:106B5000A600EACADD9E440395B4A600EA55DD9E70 +:106B6000440395B5A600DD9E441395BAA608960089 +:106B7000C00EA60896005A00010BA60896005A00FF +:106B80000207A60896005A0003038400DD9E9600C3 +:106B9000441395BBAE08DD9EFC00446395B4AE7013 +:106BA0004412E878B6018401A989102080091000F8 +:106BB00080081030800A1000800B8001802449007A +:106BC00036D0A630FC80FC0084414400B100842013 +:106BD00080628082EAA884003C0FFB863E07EF4C6F +:106BE000FC80FC402E0728922E2728C22E3728939F +:106BF000421008243C1B94512E1728C39241424155 +:106C00008424FE1C92213E2728C93C4B94523C0B05 +:106C100094623E1728CA4402FE85A640842184C09F +:106C2000AE40A641AF813C6FFB48EB09500000200D +:106C30004900416CEA5A3C0FFB5849FFE57B49FF8C +:106C4000E5CA44038D364412FE5C44238D34B6C13C +:106C5000AD90AD803C0FFB4E44038D303C0FFB6686 +:106C600044038D313C0FFB5444038D323C0FFB40F9 +:106C70002E0729333C1FFB453C2FFB4C3E67EC3B6A +:106C80005A080106B401EA9AB601D504B401EA80B3 +:106C9000B601B401852140002404B601B40184C0CA +:106CA000EAB6B601B4018540EB30B601B40184E028 +:106CB000EA83B601B401EA49EAB0B601B4013C0F77 +:106CC000FB6944038D36A44066108002AC40A440AA +:106CD00066108001AC40A44066108008AC40A4401F +:106CE00044038D34AC402E0729383E07EC1EEA439E +:106CF0003E07EC27EA4F3E07EC2B3E67EC6A3E6707 +:106D0000EC5B3C9FFBE23CABF6553EA7EC743E6768 +:106D1000EC653E67EC2D3E67EFA73E67EBF9EA971F +:106D2000EB443CABF64D3CABF6583E97EC583E97E7 +:106D3000EC0B49FFE8B9DD403E67EC883CABF64F11 +:106D40003E67EC89AF813E67EC083E97EC4E3E67AC +:106D5000EC05AF80DD5484023E67EBFB3C9E006691 +:106D60003E67EC32EBCF3E67EC103E67EF9DAE081E +:106D7000DD58AE08EACBEAC83C0803703C0803744F +:106D80004402E4703C0E01B94402E2EC3C0FFB5FAC +:106D900084083E07ED543E67EC113C7FFB4F3E6795 +:106DA000EC483E97EC413C7BF6673CABF65E3E67B9 +:106DB000EC063E67ED783E67ED552E0728933E07BB +:106DC00029C580073E67ED563E67EF5D3C7FFB6E51 +:106DD0003C7FFB673C7FFB5D3C7FFB4A3C7FFB616C +:106DE0003C7FFB493C7FFB743C7FFB623C7FFB3973 +:106DF0003C7FFB41F8028009490069598007F8206F +:106E00003C0E00A48009F81C3C0E00A58402F81872 +:106E10003C0E00A68403F8143C0E00A78404F8106E +:106E20003C0E00A88405F80C3C0E00A98406F80866 +:106E30003C0E00AA8407F8043C0E00AB840849000D +:106E400069453C0E00AC3C0394513C0B955C3C0303 +:106E500094523C0B95C53C03955F3C13955E4000F6 +:106E600080203C0B95603C0395C83C1395C74000BF +:106E700080203C7FFBE63C0B95C93E67EF944900C0 +:106E8000631A3C0FFB6B490062EF4402E8F03C0ED2 +:106E900002B3EA723C0E02B54402C51C3E67EDB176 +:106EA0003E67EDB03E67EDB23E600AC83C7E02B47C +:106EB0003E600AD83C0FFB6F845F3C0DFB6B843F48 +:106EC00038201C088CE65A783CFA3C0DFB6B84C0D9 +:106ED000EB8C1010003DEB3B3E07EC533C6FFBE3AB +:106EE0003C6FFBE43E67EFA13E67EFA03E67EFA279 +:106EF0003E67EFA33E67ECF83E67ECFA3E67ECF9BD +:106F00003E67EC5A3E67EC6D3E67EC283E67EC51FD +:106F10003E67EC3F3E67EC563E67EC003E67EC395F +:106F20003E67EC6B3E67EC4A3E67EC0E3E67EC68F2 +:106F30003E67EC733E67EC193E67EC2F3E67EBF85B +:106F40003E67EFA64900203E3E67EFA43E67EC1681 +:106F50003E67EC3D3E67EC183E67EC64EB09490088 +:106F60003F44DD4CAF80EA4C5A080104490044AF6D +:106F70008401EB49EAABEA264900028784C1490053 +:106F8000027D840044138D41AE08EB7F3C1DFB3F26 +:106F90003C1FFB6A842BEB17842AEB45EB613E0711 +:106FA000EC728420440061A83C1FFB7584E63C1F02 +:106FB000FB703C1BF6623E17EC0C3E17EC293E10B2 +:106FC0000C0C3E100C0D3C0E03028404EB353C6EA1 +:106FD00000903E17EC313C1E00913C7E00923C0E2E +:106FE0000093DD41C03044100190440397ECAC4065 +:106FF0004410011D440397EEAC40441000E44403E8 +:1070000097F0AC40441000C7440397F2AC404410E2 +:1070100000AA440397F4AC404410008E440397F652 +:10702000AC4044100072440397F8AC40DD47440381 +:1070300097FAAC40EA4E441397FCAC08441397FE11 +:10704000AC08D504FD0349FFE1A28401EA62EAC568 +:10705000840584C084E04412E8B0EA534402DD6849 +:107060003E77EC373E77EC433E77EC623C6FFB714A +:107070003E77EC203C6E03063E77EC4D3E600C14F0 +:1070800049FFF7254400012CEA994402FEFC3E70BA +:1070900010C13E77EC1DAFC04402FEFDAFC04900F9 +:1070A0000A8BEB563C6BF6603E77EC4B3C6BF6562E +:1070B00080263E67EBFA84463E67EF0AAF804402C3 +:1070C000C458EA41802684464402C4C8EA414403C5 +:1070D0008D45AF8044038D46AF80FCC0FC214462E7 +:1070E00000B88006490039CAEA36F08149FFF3CD7D +:1070F0009C3449FFF3CD5003007849FFF22D500333 +:1071000000A849FFF3C8500300CC490067CAEA361B +:10711000F081490067C9500300B049001BC4EA363A +:10712000F08149001BC3EA36F081490023D15003A6 +:107130000118490000B4EA36F081490000B3490063 +:1071400000CF5003012C49002179507303A0EA3687 +:10715000F08149002176800749002176EA36F081E6 +:107160004900574350030170490058B350030318B6 +:1071700049006509EA36F081490065085003036457 +:10718000490065EBEA36F081490065EA5003037473 +:10719000490058A7EA36F081490058A680074900FF +:1071A000615DEA36F0814900615C500303AC49003F +:1071B0002A61EA36F08149002A5A3C0DFB45EB6012 +:1071C000500303D049FFD54CEA36F08149FFD54B37 +:1071D00050030048490047E5EA36F081490008C5F8 +:1071E000EA36F08149001EEB49FFF66F49FFF66E63 +:1071F00049005872490064D149FFD538490065B348 +:1072000049005875FCA1FC00DD54840284C03C6F29 +:10721000FBE3AE08DD58AE08440000A2EB8BDD4076 +:10722000A6015A080D118006847F3C2DFB6B843F1C +:10723000383100088C065A083CFA3C0DFB6BEB8C8D +:107240001010003D490000313E07EF81EB3B84C048 +:10725000EBCB3E67EBF9490000FA8401EA793E077F +:10726000EC45EBC0EA4C3E67EC523E67EC1F3E67D4 +:10727000EC675A080103EA75FC80FC018401EAAB63 +:10728000EB20EA8EEA208400EA5C3C1C01CFEB266E +:10729000FA50EB05EBE18401FC813C0FFC34DD9EF0 +:1072A0003C0FFC33DD9EFC00840084203E07F0CAC6 +:1072B0003E07F0C73E07F0C63C1BF8623C1BF86176 +:1072C0003E17F0C93E07F0C84410004084003E1746 +:1072D000E9C63E17E9C53C0FFC35FC803C0DFC348B +:1072E000A4413C1BF860A444A6003C1BF85F3E0789 +:1072F000F0BCDD9EFC003C1DFA6BA6088C01AE08BC +:107300003C1DFA6BA6089604C8063C0DFA6D3C0FAE +:10731000FA6AD5053C0DFA6C3C0FFA6A3C0DFA6A24 +:10732000A6481010003F80A08420EAEE5000003CE8 +:10733000EAEED8FFFC803C2DFA6AA65098D1AE192F +:107340009C0996005CF0003BE9028400AE10A61098 +:107350008840841FAE11DD9EFC00EAE22E57EF1834 +:10736000D00BC804EB59DD42D50444000051DD4286 +:10737000EAE23E07EF18EBB62E57EF19D00CC8051E +:1073800044000054DD42D50444000053DD42EBB616 +:107390003E07EF192E07EF812E57EF1AD00CC805C4 +:1073A00044000056DD42D503EA4FDD422E07EF814F +:1073B0003E07EF1A2E0016755A00AA048407DD4214 +:1073C000FC80DD9EFC004900339AFC80441000558F +:1073D000DD46AE40DD9EFC03F0818005F283F18244 +:1073E000F384F48549003341F002F103490036ABE0 +:1073F000DD47DD46AE40F001F104F20549003643B9 +:10740000FC83FC2084C080E0E2C7E80B8401844058 +:1074100080208062808080A28CC1DD5597B0D5F538 +:10742000FCA0FC0049003762FC80FC00490037509A +:10743000FC80EB3CC8082E17EF06C907FC0049008A +:107440003760FC808400DD9EDD9EFC00490032FF39 +:10745000FC80EB39C80CFC00EB3B490032F8FA0920 +:10746000EA2DEB3BEBCB490032F2FC80DD9EDD9E4A +:10747000FC0049003814FC80FC0049003806FC8000 +:107480004401F120DD9E44130FA0B6204413806810 +:10749000A845441373E8A846EB47A84244130C8060 +:1074A000A84444133F9050200044B62244123200B6 +:1074B000A851441274F8A853DD9EFC4480C04401D6 +:1074C00055603B004C0044015570EBEAB1C43B00F1 +:1074D0004C003B03CC20EB932E172D12813F420032 +:1074E00004019640C1038E219648EB688386B88AD2 +:1074F00038038602B88B442000C84402DA444200B4 +:107500008873B89344031F40B88944038DD4B88C62 +:10751000FCC4FC20842CAE4184003C0FFB91EA9B10 +:1075200049FFE25DEAC13C0DFB91C00B8420846100 +:1075300084028041808380A33C1FFB91DD55FCA029 +:10754000490033745A0801F4AFF0D5EEFC0049004D +:107550003364840149003366FC80A4408C21964941 +:107560005CF08190AC40E909FC008405DD428400B8 +:10757000EA31EAACEA76FC80DD9EFC20FD30DD419C +:10758000C01FA770DF0A8CA19768E6A5E90284A056 +:10759000EA43AF70EA97D50D8406DD4244138D208F +:1075A000A6088C019600AE088400EA31EA4FEA761C +:1075B00044038D20A600C00484013E07EFA2FCA076 +:1075C000A6885A28AA0AFC00A680AE888420AE406D +:1075D0004900370EFC80DD9EFC00EA445A0804177F +:1075E000DD455A000214EAA55A08011184003E073D +:1075F000EBF98400EB62EAEA4402C38E49FFFFE242 +:10760000840384203C2DFB40EB84FC80A6885A2018 +:10761000AA10FC00AE80442FFFAAAE88A6005A082C +:107620000105490036DFFC80490036E2FC80DD9E22 +:107630008440AE808400AC08DD9EFC005A08010541 +:107640004900351FFC804900351DFC80FC0084206A +:107650004403F560AE4084234403F561AE408400EA +:10766000802080408060EA3CFC80FC00842344034E +:10767000F560AE4084204403F561AE408400802074 +:1076800080408060EA3CFC80FC004402FE63A7402E +:107690004403F007A600D8084402FE64A740440350 +:1076A000F004A600D006441FFF8EEBBDAE40F80AE2 +:1076B0004403F007A6005A002311441FFF9EEBBDB0 +:1076C000AE40843F4402FE61AE408420840280418B +:1076D0008461808180A1DD55FC80FC2444015590AB +:1076E0003B004C00442155A0EBEAB004EBAF3B005B +:1076F0004C20EBFCA6904411D80040108840A6C84E +:1077000038500A028400384F8A0296D844626238A0 +:1077100080E03C139462E201E8184023002003015A +:107720000000381280004218042439020101401080 +:107730008C0E8A309649AC50A450964B4E140003E0 +:10774000ADD08C019601D5E6FCA4FC01F0819491AA +:107750008001F101DD49FC81FC0644220000FAD0E1 +:10776000A6D2A71384A18440F68584C2F283F28452 +:10777000F286F288F289B67FF581F382F687F58A80 +:107780008041EA3FFC86FC00C805EA7EEABAEA20AE +:10779000FC8049FFD56680A0C8F9EA7E4413000248 +:1077A00044226238EBF62E47289349003004FC80CF +:1077B000FC00DD5680C0A64949FFFFE75A68030672 +:1077C000EB39C80349FFFF8BFC80FC2697D0FA50A9 +:1077D00084C084A1F28584429718F287B6FFF581B0 +:1077E000F782F683F684F686F688F689F58A804174 +:1077F0008067EA3FFCA6FC0644420000A7A284A0E2 +:10780000A723F581F582F583F584F586F588F5895A +:1078100084A1F285F387B6DFF58A80418066EA3F6E +:10782000FC86FC07F38DFA7084A08082F385844186 +:107830008462F281F482F387F28A8064B6BFF583B2 +:10784000F584F586F588F5898041F40DEA3FFC87DB +:10785000FC01EB08EB47EA20EA8EEB20EA208400EB +:10786000EA5C3C1C01CFEB26FA50EB05EBE1FC8116 +:10787000FC08F18EF08D8023F28FEBF6C4052E47C5 +:1078800028938003D5038004848184A1B61FF082ED +:107890008400F083F184F085F086F088F089F08A26 +:1078A000F581F587F00DF10EF20FEA3FFC88FC013F +:1078B000DD455A08021A8400EA5C8481EB08EB4734 +:1078C000442373E8846049FFFFD5501F8006EAC94E +:1078D00084408463EBE9220F800344100096EB425E +:1078E00040008007FC818400FC81FC25446200008C +:1078F000A7F2A7B3F381B0C7F3848460F482F58361 +:10790000B6DF808380A749002DC6FCA5FC0084015A +:1079100084204900342044000CD549003424FC80E4 +:107920004403F01F4423F302A600A650540000E0D5 +:1079300096678C225EF08020E807A6509667880143 +:107940008C029600D5038C1F96004413F01FAE08DE +:10795000DD9EFC00840080204900309349003515ED +:1079600049003BAF49FFFFD449FFFFDC49003388A2 +:1079700049002E624900356849002FCE49002F7812 +:1079800049FFC62FFC803C03F4E43C1DFA734423FA +:10799000F540B4423820820A4423F544B4629C8105 +:1079A0009691EAF24423F548B4629C829691EAF2F9 +:1079B0004423F54CB4629C839691EAF24423F5503B +:1079C000B4629C849691EAF24423F554B4629C8597 +:1079D0009691EAF24423F558B4629C869691EAF2B5 +:1079E000502000083C2BF4E48C074423F55CB4429F +:1079F00096013820820ADD9EFC015A0801163C0DD2 +:107A0000CA41B61F3C0DCA42F0813C1DCA3C3C0D28 +:107A1000CA3B3C2DCA3D3C3DCA3E3C4DCA3F3C5D45 +:107A2000CA40F815D516C8153C0DCA39B61F3C0D0D +:107A3000CA3AF0813C1DCA343C0DCA333C2DCA35CC +:107A40003C3DCA363C4DCA373C5DCA38490030F22D +:107A5000EAE55A0801093C03F4E45CF00080E8031D +:107A600049FFFF93840080208040806049002F10F0 +:107A700049002EEBFC814423F077A6509604EADC03 +:107A8000FE0FAE10DD9E9200FC2080E080C1DD453F +:107A9000A6B9C80650017FF6E6028409E902800211 +:107AA000EA21EA28AE884423F380A6505A1001FF49 +:107AB0004E6300668E01E60E4EF200CA44F078C8AE +:107AC000EB2740F03C00DD0F1C0084012200AC00DD +:107AD0002200AC00AC00280028005E005E00AC0074 +:107AE0002200A8008403EAA0F8488400F895F8452D +:107AF000840149002FB18400F895EAB35A080106C1 +:107B00004400088EEA2DD5088440840184248062D4 +:107B1000808280A0DD558401EAF68401F88ADD4583 +:107B2000C82AEB6CD528EAF0C005EAE5C00384005A +:107B3000EB788401F87E8400F875EAB35A080106F0 +:107B40004400088EEA2DD508844084018424806294 +:107B5000808280A0DD55EB6C8400F85EEAF04E0276 +:107B60000077EAE54E0300748401EB78480000706A +:107B70008401EAF68400EAA04800006A5A680162BB +:107B80008E03E60CE86444F07994EA8C40F03C0003 +:107B90004A003C000C120C121218187070B80C8CB1 +:107BA0008401F83AD5548401EAA0D551EAF0C01115 +:107BB000EAE5C00F8400EB783E07F0983C03F4E45C +:107BC0003C1DFA738E019402B60184013C0BF4E46F +:107BD000EAF0C80D8401F8268401EAA044000037C9 +:107BE000EA2D8400F8268400F829D531EAE5C8F3A7 +:107BF0003C5DFA7384213E17F0D850128200AA2906 +:107C0000D9FFD5E9EAE5C005EAF0C0038400EB78C6 +:107C10008401F8088401490031D8EAF0C8A3D517D7 +:107C2000840149FFFEEB49FFFD138401EAA08400B3 +:107C300049FFFF238400EAF6840049002F0DD50791 +:107C40005A6802068401EAA08400EAF6FCA0FC401F +:107C5000EA4480C15A08040BEAA5C008DD455A0869 +:107C60000213842049FFD677D50EDD455A0002F86D +:107C70008401DD508420846184028041808180A35E +:107C8000DD55D5F48402DD508441440001A0441048 +:107C9000003080628082EAA884208461440001A0D0 +:107CA00080418083EAA85A00300E8441441000309D +:107CB00080628082440001A0EAA8440000D7DD422F +:107CC000D5ECEA445A080410DD455A00020D2E771F +:107CD000292B5A780109800749002FA48400EA3132 +:107CE0008007EB5EEA77EA823C0DFB91C0078404D3 +:107CF000DD50EA445A08041FD50949002F975A0855 +:107D000001F88403DD50EA5BD5F0DD455A0002132B +:107D1000EAA55A080110840049FFDE1F441FFFC373 +:107D20004403F429AE40DD408420DD578402AE31A7 +:107D3000D50F804684058420EB84DD408420DD5708 +:107D40008402AE3184014900315F8405DD50FCC0FE +:107D5000FC20EAF35A00010448000065DD454E03AB +:107D60000062DD59A6405A1801FFA6005A08015BBF +:107D7000DD4BA78097B05A680156DD408429AE419B +:107D80008420DD57DD40842AAE41DD4180E0DD59AD +:107D9000C70D8420AE40DD4BAE408006EA31840939 +:107DA000EA392E07EF09EA6FD53DAFC0DD4BAFC012 +:107DB0008006EA314402FEF2AFC0DD47DD46AE4048 +:107DC000EA98C0FF49FFDD2DEA25EAB4AE088041FC +:107DD00084618402DD44DD40EBC52E07EC005A08C7 +:107DE00001102E07EC4A5A08010CEB4AC009EA2B95 +:107DF0005A0801068403EA2349002656EA7DDD4B32 +:107E00008421AE408401EB725A00010DEAA55A08A4 +:107E10000108DD40A6015A080A04490025E984004A +:107E2000EA61FCA0FC43441155B08140A600B18238 +:107E30003B00CC003B034C2085205A08010549003B +:107E4000470E81208400EA5C84E0EB4C38031E027C +:107E5000842094918CE1EA415A7804F9EAB15A08F5 +:107E6000011C8403DD568049EA4BEA912E17EC157C +:107E7000440000C8FE0CEA5CEB47F80344130FA073 +:107E8000EB262E2728922E372893EBE149FFFF623D +:107E9000DD54A608C8FFDD47DD46AE408400FCC3C4 +:107EA000FC2184C0FA003E67EBFC44738D40DD4248 +:107EB0004900376884013E67EC443E07EC0F3E07FB +:107EC000EF5A3E67EF723E67EC2C3E67EC30AFB87E +:107ED000DD45DD565A08020B8404AE09800184207A +:107EE000DD57DD40842DAE41D50A8409AE098001FD +:107EF0008420DD57DD40842AAE41AFB8DD598421AE +:107F0000AE40EA4C5A08010EDD4CA6003E07EC4696 +:107F1000EBACA6003E07EC09EB8FC8033E07EF72FF +:107F2000DD40A6013E07EC5F8406DD50EB07C81478 +:107F3000DD40EA402E0729365A080104490021573E +:107F4000840ADD504900229EEA4CC04BDD455A08A8 +:107F50000249840BDD50EA4C5A080110DD41C00D86 +:107F6000EB075A0001052E07EC2CC8074402C6E2B5 +:107F7000501F800749FFFF58EA4C5A08012BEB07B6 +:107F8000C80B44000066DD50490022F05A08010C7D +:107F90003E07EBFCD50844000067DD50DD54A60821 +:107FA0005A0801FF44000068DD50DD41C008DD5C77 +:107FB0005A0807FFEA7EEABAEA20D505DD54A6088A +:107FC0005A0801FFDD548402AE08DD58AE08D50919 +:107FD000DD41C007EAACDD50DD4CA60049FFFBEAFD +:107FE00084003E07EF5ADD45DD562E27EC5F5A0828 +:107FF00002089E12E602E806840DAE09D5075A2053 +:108000000204AE89D503840BAE09DD40EA4084004A +:10801000EA89EB9F3E07EC113E07EC0F84C1440058 +:10802000006ADD503E67EC2CDD41C00349FFF927B3 +:108030003E67EC24DD45C80484013E07EF5444004C +:10804000006FDD50FCA1FC00EAF35A08011FDD457A +:10805000C81CDD59A6405A1801FFA6005A0801168F +:10806000DD4BA78097B05A680111DD408429AE41ED +:108070008420DD57DD40842AAE41DD548400AE0803 +:10808000DD58AE088006EA31FC80FC00DD40A641E8 +:108090005A10061C2E17EC0EC9182E67EC6BCE1565 +:1080A000DD54A6485A180112DD58A6485A18010E88 +:1080B0008026EB37DD57DD59AF802E07EC50C80323 +:1080C000DD58AE088401EA31FC802E07EC218421C2 +:1080D00040008006DD9E4403F07FA600EA5FDD9E3F +:1080E000FC0049FFFFFAFC80FC4080C2812080E157 +:1080F000EBD4490031BF44201900FE14E206E81316 +:108100008AC0442186A04023085710248000440ED2 +:10811000796096904261007344001388406300D7F1 +:10812000AFB8FCC0842010148000AE78FCC0FC0006 +:10813000EBD4EBBEFC80FC0180C08001F281EB76C9 +:10814000F001EBF184013E07EF56A6303E07EF55F4 +:108150008400EB738401EAD9F8F12E07EF565A0830 +:108160000109844080208062808080A2DD55D5F6A0 +:10817000FC81FC0080C08001A648C1058421442008 +:1081800000CDF807A630C007800684244420008272 +:1081900049FFFFD38407EB768400EBF18400EAD932 +:1081A000FC80FC20A78080E0E6CBE9068ECA840A2A +:1081B00097B0AE38D50284C0A638C0038C01AE3863 +:1081C000A638E603E9038C01AE38A638C80384015B +:1081D000AE38A608C004EA7BFE0CEA2DC605943131 +:1081E000EAA649FFF910A678C10784408402846199 +:1081F000848380A2DD55FCA0FC02F08180C1F80CD4 +:10820000F201F8725A68020984013E07EF50EAF45D +:10821000EAFEF862D505EAFEEAF483FFF869F88E13 +:10822000FC82FC21FD30F281DD45C82C5A70090723 +:10823000461000F450008240D505461000C350009F +:1082400085005A60011DC6045A600205FCA1F8763B +:10825000FCA12E27EF4F2E37EF4ECA02C310441158 +:1082600086A0FE5C846AEB89443FE70042010C7300 +:108270008A0184203E17EF4E3E17EF4FF10149FF70 +:10828000FFBDFCA1FC2080E080C1DD455A08020A48 +:10829000CF1ADD40A6415A10041349FFFEF8D5134A +:1082A000DD40A6415A100B105A6004068006844334 +:1082B00049FFFFB9DD40A6415A180904EB5DD5031B +:1082C00049FFFEC3FCA0FC02F081EAF4EAFEF201E1 +:1082D000F80BEAFEEAF449FFFF66FC82FC02F0813B +:1082E000EAF4EAFEF20149FFFF01EAFEEAF449FF7F +:1082F000FF42FC82FC00460000A650000040F80D42 +:10830000FC80FC00F81BFC80FC00F818FC80FC00E2 +:10831000460000A65000004049FFFFD7FC80FC004B +:10832000EBE6EBD2EB55FC80FC00F808FC80FC008F +:10833000EBE6EBD2EB55FC80FC0049FFFEFAFC803B +:10834000FC00EBE6EBD2EB55FC805A080408FC007D +:10835000EA4EEA2CEA3AF802FC80DD588401AE08C5 +:10836000EACB83FFDD9EFC003C0FFC39DD41C805F4 +:10837000F8073C0FFBA5D50EF8033C0FFBA649FF01 +:10838000F8813C1DFC39A68AA64B420104733C0FC0 +:10839000FBA4FC80FC004413F69280C08403AE086A +:1083A000FA4F4413F6AEAE884413F6AFAE0844233A +:1083B000F6A084204403F6A1AE50AE404403F6A2DA +:1083C000AE404403F6A3AE404403F6A4AE404403DB +:1083D000F6A5AE404403F6A6AE40A6F040110C7CD4 +:1083E000A6085421800784614021880CFE87840000 +:1083F000AE88FA6F80208040EA3CA6705CF0803244 +:10840000E8038C21AE70FC808E239648E628E82491 +:10841000FC0080C284414011040C543080B1CB0474 +:108420009656C914FC80500000569600E602E913E7 +:108430003E27EC4BDD41843FC803441FFFEF44025D +:10844000FF5FAE408402AE30FC80500000569600C4 +:10845000E605D5EEFC80DD9EFC418140F381840081 +:1084600084613E07EC753E07EC613E07EC4780E116 +:1084700081223E37EC3F3E37EC774402FF505A28CA +:108480000307EB9BAE403E37EC0ED50A4410004587 +:10849000AE403E37EC6B5AA8AD043E37EC47443251 +:1084A000FF57EAD2AE18500500559600E60280C389 +:1084B000E806840449FFDE973EA7EC84EB3EAE302D +:1084C00054038002C01BEB9B4402FF57AE405A98F6 +:1084D000030ADD41C00444023220D5334402722035 +:1084E000D530DD41C00444023224D5034402722455 +:1084F000F82884003E07EC85D52684013E07EC4B26 +:10850000DD414412FF5FC0038411D503440FFFE136 +:10851000AE084462FF57EB40AE3049FFDE524400E4 +:108520000045AE30CF0B5A9003D6DD41C004440263 +:108530003224D50744027224D5045A780105F0018B +:1085400049003539DD4B8421AE40441000474402D8 +:10855000FF57AE40FCC1FC2080E180C2C00D5A0034 +:10856000041184003C0BF65949003A71444395AC20 +:10857000443395AAD50A444395A6443395A4D5051A +:10858000444395AC443395B084009680E246E807B6 +:1085900038138101381201098C01D5F83C03F659D2 +:1085A000AC18FCA04402FF50DD9E4422FF5038105E +:1085B0000808DD9E4452FF5084204402FF70EAEE1A +:1085C000D8FFDD9EFC00EA882E17EC735A180107CD +:1085D00084403E27EC5A3E17EC08842010100050CF +:1085E0003E17EC003E17EC563E17EC703E17EC0EB3 +:1085F0003E17EC733E17EC473E17EC6B3E17EC4F03 +:108600003E17EC4A3E17EC683E17EC393E17EC1962 +:1086100049FFFFD2FC80FC4080C0EA8880E04492A1 +:10862000FF54EB3EEA342E17EC754402FF55AE4082 +:108630002E07EC755CF000324EF3006EEAD3EA349C +:10864000EAAD84003E07EC753E07EC61EB40EA348E +:10865000DD41C80F4492FF54EBDCEA34EAD2EA8FE2 +:1086600044000047EA34DD41C826EA28EA21D5273C +:10867000EB6B3C4DFC3904100014EA859230EA6A39 +:10868000EB83B4418400924A96B744530000FB88C0 +:108690000212001AE201E8DF94C1985DA448B5A671 +:1086A0004210C0248871401088378C019649AC581C +:1086B0009601D5EFEA4EEA2CEA3AD507000380513D +:1086C0005A00BB04AE88D5FB44100048EA69AE40AE +:1086D000DD4B8421AE4084004413F692AE0844136F +:1086E000F6AEAE084413F6AFAE088400802080409A +:1086F000FA6FEA3CEA7DDD41C007EA8EEAE6EA204D +:10870000EA8EB426EA2084003E07EC3F8401EA3575 +:10871000EA2EF895FCC0FC4080C0EA8880E0441056 +:108720000042EA69AE402E17EC755A180218EB9B0E +:10873000AE40DD414E020086EB23A640EA37EA3820 +:108740009648AED05A100C06A6409648EA29D5FBAA +:10875000EA7EB426EA2048000075E6234EF3007254 +:1087600044100044AE40EAADDD41C8084410004565 +:10877000EA69AE40DD41C823D5133C0DFC3984A025 +:108780000200001A4433000092019401D0F098AB2B +:10879000B426A49088259691AC888CA2D5F84492F2 +:1087A000FF5444000047EA34EB3EEA8F440000489F +:1087B000EA34DD41C824EA28EA21D525EB6B442FB1 +:1087C000FE0104100014440200609230EA6AEB8358 +:1087D000B4213C0DFC39922A9677FE540240001ACF +:1087E000964984409611E204E8DBB4664031882063 +:1087F000A4188C4188019601AC18D5F5EA4EEA2CF4 +:10880000EA3AD507000380515A00BB04AE88D5FB75 +:1088100044100049EA69AE40DD4B8421AE40EA7D58 +:10882000DD41C007EA8EEAE6EA20EA8EB426EA20B5 +:1088300084003E07EC3F8401EA35EA2E49FFDCB6AE +:108840008401FCC0FC00EBE45A080109EB03EAD206 +:10885000AE30EA2649FFFEE1D50AEB5C5A08011763 +:10886000EAD2EB03AE30EA2649FFFF574400004846 +:10887000AE30DD5BF97D44000049AE302E07EC756B +:108880008C013E07EC75FA03FC808401FC80FC43FC +:1088900081203C0DFC39046480050270001AEA2B2B +:1088A0005A0801072E7728930464800C95FAEBDFB1 +:1088B0004402FF55AE403C03F651EBDFE220E86E88 +:1088C000EA6944100042AE403C03F6538C013C0B75 +:1088D000F6538400EB90DD414E0200AF3C03F653AB +:1088E0005A00010580268400D53FEBDDA64096485E +:1088F0003E17F0E09667581080A0AE40EBD749FFD6 +:10890000FD348400442FFF804430007F9641E227ED +:108910004EF200933C1DFBA6EACF3C1DFBA4383071 +:1089200080088C01D5F43C5DFBA63C2DFBA42E47B2 +:10893000EC7388A020328000382100105A480106CC +:10894000A50897239082AD08A5089723E064E91055 +:10895000A5089723E082E917AEE83C3DFBA48C22F2 +:10896000382180088C019681E247E9DED565A4C8EC +:1089700096DB5EF18080E804A4C896DBD5EA44303B +:10898000007FD5E7A48896935EF17F81E904A488EF +:108990009693D5E3442FFF81D5E0DD535A000105BE +:1089A000EA2B5A08012FDD41C00BEA2B5A000106C1 +:1089B000DD40A6015A080A268401EB2FD522EB2CB4 +:1089C0005A0001128401EB2F8402120F8006B0437B +:1089D0004402C41CF085A8093A108C00EB2449FF1E +:1089E000D822D52A2E07F0E18C019600E602EB9002 +:1089F000E805DD59A6005A0801208401EBECD51AE0 +:108A0000EB4A5A00010B8401EBEC8402120F800642 +:108A1000B0434402C430D5DF2E07F0E18C0196004C +:108A2000E602EB90E805DD59A6005A08010684012C +:108A3000EB2F8400EB90EB4AC05FEB2CC05DEAADFE +:108A4000EB9BEA69AE40DD41C01D3C4DFBA63C5DA1 +:108A5000FBA484209609E207E811380204103822AA +:108A6000840080C9A0F54021010494098860AC9875 +:108A7000A0F68C218803AC80D5EE2E17F0E0EBDD5C +:108A8000AE40EB40EB03AE30EA2B5A000104EAD3D0 +:108A9000EA8F44000045AE30EA2CEA4EEA3AEBDCBD +:108AA000AE30EA2B5A080125DD455A080207840337 +:108AB000EA2349001FF9D51C2E67292B5A68011992 +:108AC000DD40A6015A080915EA238405DD4AEA5269 +:108AD000EB578406DD4AEA7DDD4049001F47F081FF +:108AE00084408402F1018066808680A2DD55EA7DA3 +:108AF0008401EA35D52E2E67EC735A68012BDD45CB +:108B00005A08020E441FFFD14402FF56AE408404AF +:108B1000EA23DD408026DD57EB52D51B2E67292B3B +:108B20005A680118DD40A6015A080914EA23840591 +:108B3000DD4AEA52EB578406DD4ADD4049001F1644 +:108B4000F08184408402F1018066808680A2DD5538 +:108B5000FCC3FC002E07EC565A08010FEAD2EB03C7 +:108B6000AE30EAAD49001BF7EB3EAE30DD5B49FFAE +:108B7000FBEEEAD3D515EA2B5A0801162E17EC198D +:108B80005A180113440FFFB1EB03AE308400EA42E0 +:108B90008400EA66EAA3EA26F947440FFFB9AE303B +:108BA000FA03D5028401FC80FC22EA8880C0EBDF56 +:108BB0004402FF55AE403C03F651EBDFE2204EF29B +:108BC00000B644100042EA69AE403C03F6538420EC +:108BD0008C0196013C0BF6533E17F0DF5A08013B1F +:108BE000EBDDA64096483E17F0DE9667581080A051 +:108BF000AE40EBD749FFFBB93C1DFBA5844080018B +:108C0000806180E2445F800044407FFF5CF100C0EF +:108C1000E809AD581241832012518190124184B06D +:108C2000D508ADC01270032012700190127004B00C +:108C30008C419691125080C8124083E8125082589D +:108C4000124085788C628C228C025A28C8E1480038 +:108C500000913C1DFBA58400804145029ECA447FD3 +:108C600080004512A1EA40504000A568223103204F +:108C7000976B22410000E0A342429000E806DF0427 +:108C8000443F8001D5028065AD1012310320405071 +:108C90004400A568223104B0976B22410190E0A303 +:108CA00042429000E806DF04443F8001D50280651F +:108CB0008C0212410190123104B08C425A0980D5C5 +:108CC00084004472A05A444F80004502A37A994719 +:108CD000A568222083E8976B223080C8E0A2423248 +:108CE0008C00E806DC04442F8001D5028045123058 +:108CF00080C8122083E840504000A5682220857873 +:108D0000976B22308258E0A242328C00E806DC04E5 +:108D1000442F8001D50280458C02123082581220E7 +:108D200085788C225A0990D5D524EB2C5A00011154 +:108D30008401EB2F8402B041EAD84402C41CF083C2 +:108D4000A8093A108C00EB2449FFD66DD5122E07E6 +:108D5000F0DF8C019600E6053E07F0DFE805DD59FF +:108D6000A6005A0801078401EBEC84003E07F0DFFF +:108D7000EB4AC036EB2CC034EAAD4472FF54EAD360 +:108D8000AE3844129ECA3C2DFBA5443006408402F6 +:108D9000DD4444000045AE383C2DFBA5EB6450217A +:108DA0000640443006408402DD44EBDCAE38EAD3B2 +:108DB000EA8F44000047AE38EA28EA210003005158 +:108DC0005A00BB04AE88D5FB2E17F0DEEBDDAE40BB +:108DD000EA6944100048AE40EA7D8401EA35FCA20D +:108DE0002E07EC4A5A080115FC00EA69EB9AAE40DE +:108DF0003C1DFB6480C05A180105EA2649FFFED6D7 +:108E000044000049AE308401EACBFA03FC808401BF +:108E1000DD9EFC202E67EC4A5A68011D4472FF5407 +:108E2000EAD2AE38EA2649FFFD3444000049AE38A4 +:108E30008400EA2EDD4BAF80DD455A000225EAA50D +:108E40005A080122DD40A6015A080A1E49001DD019 +:108E5000D51A2E07EC685A080119441FFF90EA69D9 +:108E6000AE40EA7D2E07EC5349FFF2F1DD41C0042C +:108E7000EA4EEA2CEA3AEB3BEBCB49FFF2E8DD4B5A +:108E80008421AE40FA03D5028401FCA0FC00DD4140 +:108E9000C80884024412FF604422FF50FA60DD4497 +:108EA000FC803C03F86E8C0196015CF000FFE90247 +:108EB00084003C0BF86E3C13F86E4402FF52AE4047 +:108EC000DD9EFC4049FFD691EA449E46E622E90A2F +:108ED00050107FF7E625E9065A0011058401480085 +:108EE0000075DD40A6015A0804148404441000BD36 +:108EF000DD43440000D0DD50DD41C01F840049FF48 +:108F0000CE4C8401DD4AEAAAEA77EA82D50B8E08C4 +:108F1000E604E9ECDD455A0802EAFA31EA70AE40AF +:108F2000D521A6305A002105EB1AEA5BD5FB840255 +:108F3000DD4A8400EA61D5162E07F01EC8088402B7 +:108F40004413970044238D54EA94EA648406DD4A6E +:108F5000EA25FA11AE08804184028461DD44840070 +:108F6000EAC38403DD4ADD4084C0A601DD4A49002E +:108F700025A1440000D1DD50DD459E42401304068A +:108F8000840249FFCCE8DD455A08010B8006490000 +:108F9000281D80064900283880064900282B4400F7 +:108FA00000D2DD50DD404412C6F03C2DFB4544327A +:108FB000C514490041FF80C05A00080448FFFF90D3 +:108FC000440000D3DD508006FCC0FC40EAAD49FF00 +:108FD000EE0A49FFF4C0DD4084C1AF8149FFF08053 +:108FE000440000A0EB8BEB7CDD5649FFF6324400D9 +:108FF0000051DD50EA77EA8249FFF86FC8053E6705 +:10900000EF7DEA5BD5FA84003E07EF7DEB59DD503A +:10901000FCC0FC00840FDD42840444100062DD4388 +:10902000DD47DD46AE40EA8DA608C8FF4400008259 +:10903000DD5044000083DD50840149FFD6394400EF +:109040000084DD50FC80FC00840444100061DD439A +:10905000441000678404DD438404EB00440000A155 +:10906000EB8BDD40EBC7EAD6EB98848049FFE1B19A +:10907000EA815A080108EA78EB6749FFF2DB490008 +:1090800029B7DD548402AE08DD58AE0849FFFFC39E +:10909000840444100068DD4349FFF704EA815A085C +:1090A00001044900299F49FFF0B08402DD42840495 +:1090B00044100069DD43FC80FC00EA8880C0840C19 +:1090C000DD5044038D47A6408C219648AE40DD47D5 +:1090D000DD46AE408409441000A1DD4349FFF27E25 +:1090E0008409441000A2DD4349FFDA2984094410B1 +:1090F00000A3DD43DD40A6415A180D0E840944103B +:1091000000A4DD432E07EC115A080115FA05DD42D3 +:1091100084C2F80E2E17EF9CC9F24412C3E1442218 +:10912000C6F049004281EADE5A0801EA84C14800DB +:1091300000ED8409EBB0DD432E07EF0BC00AEA8B8C +:10914000A6405A102105A6005A0822048401EA2EDE +:10915000DD5B5A08190449FFDA4FEBD95A08011CA4 +:10916000DD5C5A0807198400EBC0EA4C5A0801126A +:10917000DD4CA60049FFF39D5A080107EB8F5A0802 +:1091800001043E07EBFC2E07EBFCC003FA06DD42B0 +:109190008401EAAB84003E07EC342E07EC77C8105C +:1091A000DD5C5A08070E840AEA48DD568401EA2E7F +:1091B0003E07EC34DD4CA600A64949FFF2E62E0737 +:1091C000EC6A5A08010C4402C3DAEBBAEAD63C3D19 +:1091D000FB4E3C4DFB4C49FFDB09DD41C013840CC9 +:1091E00000130050DD43840D00130051DD43840E55 +:1091F00000130052DD432E07EC005A0801048400DE +:10920000EAA93C0DFB775A080142DD59A6009600F9 +:109210005A08013D84203C1FFB772E17EC665A1834 +:10922000551B2E17EF0CC104EAA9EAD4D516EA8B18 +:10923000A6005A08130544000086DD42EB7CDD568B +:109240004422C38E3C3DFB454442C51449FFDCE447 +:10925000EAD4D503EA4FEB44DD5B49FFD7FD960026 +:109260003E07EC0BDD4A2E67EC0B5A60034F5A6841 +:10927000020EFA04DD422E07EC7EDD42DD47DD46BC +:10928000AE40DD54A608C0FFD540DD54A6085A08FC +:10929000020EDD4BA6005A08020A8401AE08DD5812 +:1092A000AE08DD45C80349FFF84DDD40A6015A0868 +:1092B0000A08DD45C80349FFF82649FFF54B2E078C +:1092C000EC345A08010DDD4CA6005A080309EB39AD +:1092D000C80684023E07EC3449FFF201DD5B5A0800 +:1092E0000404490036EB2E07EC675A00010448FFDE +:1092F000FF1F84003E07EC67DD58A6089600C8FEF5 +:109300008441AE88FAC3EA2E8006FC80FC01EA8123 +:109310005A080106EA78842049FFF131EA4C5A08DC +:109320000104490038B8DD4CA6005A08030CEA4C89 +:109330005A0801094900355084023C1DFB44EBFFEB +:10934000D50E4900289EF081F1018400EBFF2E0725 +:10935000EF015A0801058402842FEBFFDD40A6418E +:109360005A180D048423AE41440000A3EB8B2E0752 +:10937000292D5A08010BDD40A6005A080107DD4CD3 +:10938000A600490029C7D504EB08EB20EA20EA260D +:109390004412C4604422E204443200004442DE50DD +:1093A00049FFE308FC81FC002E07292E5A0801081A +:1093B000EA264412D73849FFE25CD5053C0C01C1CE +:1093C000EBEDEA202E0729435A08010E4402C6D4C9 +:1093D0004412C6D24422C6D04432DE5C4442DA0093 +:1093E00049FFEAB13C0DFB45B400EA555A000103C0 +:1093F00084003C0FFB4884013E07EFAADD5B5A085E +:109400001209EABF8421EAF85A080104EA2CEA3A70 +:109410002E17EC1E5A180105EA7849FFF0B0DD5B03 +:109420005A08120AEABF8422EAF85A08010584029F +:10943000EA2CEA3AFC80EA4AC80BFC00440330708C +:1094400049FFE56DC007FA18EA998403FC8084049B +:10945000DD9E8401FC80FC6680C0EA472EA728922E +:109460002E8728B52E9728B42EB72893C00944C359 +:10947000343C44D333D844233374EBB2D50844C2CC +:109480001B3044D219A044221810EB12CE2F84E1D5 +:10949000FB708522806A808880A78041F80B440396 +:1094A0004C10EA3FEB13EA3244035890DD49802D1B +:1094B000804DB75FF78114AF8002F683F68414BF46 +:1094C0008005F686149F8007F688F689F78A83FF61 +:1094D00044034F30806A808880A7EA3F44134F30AE +:1094E000EA3244035BB0DD49FCE65A68012F84E0B0 +:1094F000FB10854280228069808B80A644034DA0AA +:10950000F80BEA3FEBA2DD5E44035A20DD49440339 +:1095100050C0802C804CB73FF681149F8002F783A7 +:10952000F784148F8005F78614AF8007F788F789D2 +:10953000F68A83FF8069808B80A6EA3F44035D4002 +:10954000441350C0DD5EDD49FCE6FC004E02005CC9 +:10955000EAC9EA325A181421EB13DD4944134F309B +:10956000F82044129ECAF822440383884412A1EAD8 +:10957000F82CEA47C003EBB2D502EB12F825EA4714 +:10958000C004441333D8D503441219A0EA3244036B +:109590007D48DD49FC8044135890DD4944135BB09D +:1095A000EA3244037708DD49EB64EA324403806819 +:1095B000DD49440383884412A82AF807EA47C00318 +:1095C000EBB2D502EB12EB77EA32DD49EA47C00491 +:1095D000441333D8D503441219A044037D484E00E8 +:1095E000FFF5441386A84402AB4AF86AF806440221 +:1095F000AC12441389C8F8643B0054003B00D420EB +:1096000083FFFC8044037578DD5E5A181420EBA2BA +:10961000DD49441350C0F81F4412A05AF8224403F5 +:1096200085184412A37AF825EA47C004441333741A +:10963000D50344121810F826EA47C0044413343CFA +:10964000D50344121B30F829FC8044135A20DD490D +:1096500044135D40DD5E44037898DD494412A69AC8 +:10966000DD5E440381F8DD49440385184412A9BA3C +:10967000DD5EDD49EA47C00444133374D503441268 +:10968000181044037BB8DD5EDD49EA47C00444138B +:10969000343CD50344121B30DD5E44037ED8DD49E3 +:1096A0004423883880224402ABAEEAA244238B587C +:1096B000EA86F806F8084402AC768022F801EAA2AD +:1096C000EA8683FF3B0050003B00D02083FFFC80F4 +:1096D000FC40C8053C5DFB64C508D5405A08013F05 +:1096E0003C5DFB645A58013B2E57EC0A84C38EAB99 +:1096F000E2C584C0E9052E67EC0A8ECB97B1C0089D +:109700005A08010B4470003280A78604D508FAF08D +:1097100084A68207D50484E080A782078124EAC951 +:109720004440019042581424420310735A181406FE +:10973000802294A9DD49D504802394A9DD494410F1 +:109740000064EB774203047394B98029DD492E0746 +:10975000EC0A5A080E048408EAF9FCC0FC012E2722 +:10976000EC315A200704480000A7E6104EF200A48E +:10977000F18144F095803817810140F0BC00DD0F85 +:1097800020002000200020004C00600074008600B3 +:109790009800AC00C000D400E800FA000C012001E1 +:1097A0002E57EC0A8C0B4C504087DD5CC8048401BA +:1097B000F101F807DD5C5A000103F8078400F101AC +:1097C00049FFFEC58408EAF9480000768400F101EB +:1097D00044234C10443358904442AB4AF86AD56B4A +:1097E0008401F10144234DA044335A204442ABAEDE +:1097F000F860D561442216808400F1018062444201 +:10980000AB4AF857D558442218108401F101806200 +:109810004442ABAEF84ED54F8400F10144229ECABB +:109820004432A50A4442AB4AF844D5458401F101CB +:109830004422A05A4432A69A4442ABAEF83AD53BF1 +:109840008400F10144234F3044335BB04442AC12F6 +:10985000F830D5318401F101442350C044335D40D8 +:109860004442AC76F826D527442219A08400F101A1 +:1098700080624442AC12F81DD51E44221B30840184 +:10988000F10180624442AC76F814D5158400F101F0 +:109890004422A1EA4432A82A4442AC12F80AD50B69 +:1098A0008401F1014422A37A4432A9BA4442AC763D +:1098B00049FFFF10FC819200FC602E4728922E2762 +:1098C00028B52E3728B42E1728934E0300F44232C1 +:1098D00008244052040990618020449320D044A37E +:1098E000226044B3271044C328A045234C104533BD +:1098F0004F30E023E82C4020949797209489CC02A5 +:10990000961040412400A5208C21411200114041B5 +:109910002800A52096484102001140412C00A5E0F6 +:10992000884C9501A59040224800131100009885AD +:1099300094914111480097FB97B3889388538C0109 +:10994000130880009600ADE0AD90D5D4EAAF5CF08E +:1099500000A04EF301585A00A0095A00A10B44621E +:10996000A1EA44129ECAD50844634F30EB13D504D4 +:10997000446219A0EB122E07EC13E602E82D3C0D11 +:10998000FB685CF01388E90584003C0FFB68D50494 +:109990008C013C0FFB68EA32EAC9DD498026EA32D5 +:1099A00044037578DD49441000C144037572AC402E +:1099B000EB28A400441375749603AC08EADFA400F6 +:1099C000441375769603AC08442373E8EB13EA243A +:1099D0008402EA64F8719E82E642E821EA32EB777B +:1099E000DD498026EA3244037BB8DD49441000C2D9 +:1099F00044037BB2AC40EB28A40044137BB4960331 +:109A0000AC08EADFA40044137BB69603AC084423F9 +:109A10007578EBA2EA248402EA64F84E9E84E6425A +:109A2000E823EA3244038068DD498026EA324403B1 +:109A300081F8DD49441000C3440381F2AC40EB28B7 +:109A4000A400441381F49603AC08EADFA400441395 +:109A500081F69603AC084423770844134F30EA2478 +:109A60008402EA64F8298E06E6024EF200CCEA325D +:109A7000440386A8DD498026EA3244038838DD495C +:109A8000441000C444038832AC40EB28A4004413C3 +:109A900088349603AC08EADFA400441388369603A2 +:109AA000AC0844237898441350C0EA248402EA6442 +:109AB000F8035A000104480000A640518409FECC76 +:109AC000842090618001449323F044A3258044B313 +:109AD0002A3044C32BC045234DA0453350C0E0037A +:109AE000E82C4020149797209481CC029650404156 +:109AF0002400A5208C014112001140412800A5201E +:109B000096004102001140412C00A5E0884C9509C7 +:109B1000A5904022480013110000988D94914111A6 +:109B2000480097FB97B3889388538C2113088000D3 +:109B30009648ADE0AD90D5D4EAAF5CF000A0E96204 +:109B40005A00A0095A00A10B4462A37A4412A05AF9 +:109B5000D509446350C0EBA2D50544621B304412C2 +:109B600018102E07EC13E602E812DD5E44037708B6 +:109B7000DD498026DD5E44037898DD494413525068 +:109B800044237A28EA248402EA64D53C9E82E64291 +:109B9000E812DD5E44037D48DD498026DD5E440336 +:109BA0007ED8DD49441353E044237BB8EA24840281 +:109BB000EA64D5289E84E642E812DD5E4403838889 +:109BC000DD498026DD5E44038518DD494413557068 +:109BD00044237D48EA248402EA64D5148E06E60212 +:109BE000E811DD5E440389C8DD498026DD5E44035B +:109BF0008B58DD4984024413570044237ED8EA245D +:109C0000EA64FCE084004412DEE4804038208109EC +:109C10008C014432DEE45A08C0FB8400804098582E +:109C20008C02122080C85A0990FCFC203C4C01C1D7 +:109C300084A084C344700640A4205412801F402294 +:109C4000A009402088A09603390189014000181618 +:109C5000881038018909400294090A2200019402FF +:109C60004000047C9693500000C8401118363821FB +:109C700081018CA18822976938118109DFDEFCA05F +:109C8000FC662EA7289280C02E8728B52E9728B470 +:109C90002EB72893C0035A0801044900243AEA4722 +:109CA000C00944C3343C44D333D844233374EBB2A7 +:109CB000D50844C21B3044D219A044221810EB121C +:109CC000CE2284E1806A808880A7F80644035890F9 +:109CD00044229ECAEA3FB75FF78114AF8002F68341 +:109CE000F684F685F686F787F688F689F68A83FF86 +:109CF00044035BB0802D4422A1EA806A808880A75B +:109D0000EA3FFCE65A68012384E0802244035A209B +:109D10004422A05A8069808B80A6F802EA3FB73FB0 +:109D2000F681149F8002F783F784F785F786F6871C +:109D3000F788F789F78A83FF44035D40802C44222B +:109D4000A37A8069808B80A6EA3FFCE6FC2080C075 +:109D500080204402D73849FFDC6DCE584452A50A12 +:109D6000443D5AF64442DEE484E34422A68A982B1A +:109D700038120011A4284462DEE49603E020E908CA +:109D8000EA45C802EABBA4288A019603AC288CA243 +:109D9000DAEF848180A44402A50A4432D9388420B1 +:109DA000EB3DF8BC84003C0FFB593C4C017E8060CD +:109DB00080A02E2010AD9860C20FA48896934E27E5 +:109DC000000CA48850217FCE9693AC88A4889693EB +:109DD0004E240003AD48A4488C02964B88615A0873 +:109DE00040EA84403C3FFB594402DD6880628421A4 +:109DF000F85BEB3D8400EBC4F8964452A82A444D2E +:109E000057D684604422A9AAD55D5A60010448004F +:109E1000008D4452A69A443D5AF64442DEE484E35F +:109E20004422A82A982B38120011A4284462DEE4A8 +:109E30009603E020E908EA45C802EABBA4288A01A3 +:109E40009603AC288CA2DAEF84214402A69A44320D +:109E5000D938808180A1EB3DF86184003C0FFB651F +:109E60003C4C017F806080A02E2010AD9860C20F16 +:109E7000A48896934E27000CA48850217FCE9693F9 +:109E8000AC88A48896934E240003AD48A4488C0265 +:109E9000964B88615A0864EA842180413C3FFB6507 +:109EA0004402DD68846049FFE08FEB3D8401EBC430 +:109EB000F83A4452A9BA444D57D684604422AB4A7A +:109EC000D51A802538009005381304119603E02038 +:109ED000E902ACE88CA2DAF6842080814402A82A48 +:109EE000EB0D4432D8C084A1F8198400EBBCEB0D13 +:109EF000F81AD51B802538009005381304119603F5 +:109F0000E020E902ACE88CA2DAF684214402A9BA86 +:109F1000EB0D80A14432D8C0848049FFE3AB8401BB +:109F2000EBBCEB0D49FFE138FCA0FC004432C3A5BB +:109F30004402D938EBBCEB4F490040AFEA72EBC4A6 +:109F40002E27EC3549004E2EEA72EBC4EB3D8461BE +:109F5000F805EB0D8460EBBCEA7249FFBEC1EA7202 +:109F6000490042272E17DE41EA7249004F01EA728A +:109F7000490046B3EA7249004265EA72490049D78E +:109F8000EAA4C0035A08050D84013E0010AE3E004D +:109F900010AD84003C080859841F3E0010A92E0013 +:109FA00010A95A00FF0684003E0010E4D504840185 +:109FB0003E0010E4EA722E17DE4149004FD68401BC +:109FC000FC80FC002E07EC1FC803EA2ED506840196 +:109FD000EA2E84003E07EC1FDD5B5A08120AEABF36 +:109FE000842FEAF85A080105840FEA2CEA3ADD4B7F +:109FF0008421AE40EAA55A080108DD40A6015A08AE +:10A000000A04490014F5FC80DD9EDD9EFC002E074D +:10A01000EC3BC8432E67EBFC5A68010C2E07EC7131 +:10A02000C80849004A54C805EB31C8033E67EC74C0 +:10A03000EAE2C81F2E07EC71C81C2E07EC74C81981 +:10A040002E07EBFC5A000116490006F05A080208D8 +:10A05000FA02DD4284013E07EC74D50B4402E204AF +:10A060003C1394BE4422C3D549000DCF5A0002F2DE +:10A07000DD40A6412E07EC745A1006045A180B1046 +:10A080005A0001092E07EFA65A0001052E07EC65BC +:10A09000C0048401EA42EA798401D5245A00010A05 +:10A0A0002E07EFA65A0001062E07EC525A0801F6B9 +:10A0B000DD47DD46AE40DD54A608C0FF84003E0704 +:10A0C000EC743E07EFA68401EB9FDD5B5A08120A91 +:10A0D000EABF8425EAF85A0801058405EA2CEA3A21 +:10A0E0008402FC80FC2084C02E07EC38E2C0E82CFF +:10A0F0003C0C00A595F138501901DE243C0C00A859 +:10A100004422D73898473C0C00A7A64938001911BB +:10A110003C30037049FFDB0A3C1C00A588E1A478B1 +:10A12000FE0FAC383C0C00A7381019013C03987E98 +:10A13000E220E8082E07EC165A00FF058C013E07C6 +:10A14000EC168CC1D5D2FCA0FC00DD40A6015A0063 +:10A150000305F83DE603E906DD5B5A0005045A08ED +:10A16000120A84003E07EDB03E07EDB13E07EDB2A6 +:10A17000D5363C0DFB7A5A0801088400EB6944028D +:10A18000C51C4900499B4402E2384412C52C4900D1 +:10A190004CC73E07EDB2F81B5A08030784003E0780 +:10A1A000EDB03E07EDB1490049A480C05A08011046 +:10A1B000F80E5A0803078006EB9544000061DD4263 +:10A1C000F8065A08040D8401EB95D5094900498E1B +:10A1D0005A0803068400EA3B8401EA79FC80FC20EB +:10A1E000EA815A080106EA78842249FFE9C82E0765 +:10A1F00029325A080109EA264412C6F04422DA003C +:10A2000049000B694402DE5049FFE40CEAA55A08F4 +:10A21000010A2E07EF9C5A0801064402DE5049004D +:10A220000AC5EA264412C48844220000846084855A +:10A2300049FFDB65DD5B5A08120AEABF8423EAF8AE +:10A240005A0801058403EA2CEA3A2E0729325A08F3 +:10A25000010AEBB65A080107EBE3C004EA264900FD +:10A260000CC68400441201D03E07EC5950208014E3 +:10A270004402C6F04900056FEBE3C8074402C6F08C +:10A280004412DE5C49000582EBE34E020068840064 +:10A290003E07EC40DD5B5A08120AEABF8424EAF864 +:10A2A0005A0801058404EA2CEA3AEA4C5A000106ED +:10A2B0002E0729325A0801064402019C49003155F3 +:10A2C00084003E07EF5C4412DA003C0C01C03C20E5 +:10A2D00003704432C3A88481EAE92E0729315A0861 +:10A2E000011B3C0DFB45B40096045A0001083C0DCF +:10A2F000FB4EA60096045A08010FEBC3C80C44029B +:10A30000DA004412DE5C4422C3A8490004183E0768 +:10A31000EF82D50684003E07EF82490002D449FF50 +:10A32000FEE32E0729445A08022ADD4CA600C81075 +:10A33000EB31E602E90D4402DA00EBED4422C3A85A +:10A340004432E28C4442C3E149000805D517840039 +:10A350003E07EFA849000636D511EAE25A08010681 +:10A36000490002A73E07EF824900062C84003E0701 +:10A37000EFA83E07EC383E07EC16EA815A080106C2 +:10A38000EA78842349FFE8FB2E07EC713E07EF5B78 +:10A3900084003E07EC383E07EC71EAE2C8522E1703 +:10A3A000EF72EBC63C0FFBE65A1001093C0DFBE3D4 +:10A3B0004420EA60E240E9038C01EA3B3C0DFBE407 +:10A3C0004420EA60E240E90D3C23F7B63C33F669ED +:10A3D000E262E802C1048C01EB11D5033C1FFBE4EF +:10A3E000EAB35A08010F84203C1FFBE32E17EF65E8 +:10A3F000EA425CF08032E80A8C213E17EF65D50610 +:10A4000084203E17EC283E17EF652E17292C5A188A +:10A410000119DD56A6495A1003045A180A132E17BB +:10A42000EF665A1801093C1DFBE4E622E804C80364 +:10A430003E07EF668400EB4949002F638401EB4936 +:10A44000DD535A08020749004845C0038400EA3B2F +:10A4500049FFFDDE5A08020448000097EAE25A0864 +:10A4600001058400EA3BEB11EA815A080106EA780B +:10A47000842449FFE884EAA55A0801182E07EF9CB6 +:10A480005A0801144402DA004412E8F02E27EC7155 +:10A490004432C468490007DC490009855A080106AE +:10A4A0004402C6F04900129884203C1FFBDA2E6754 +:10A4B00028993C7C00A63D0C00A74402E8F080816E +:10A4C00086214520FFFF453000FFE286E83BB4408F +:10A4D000C22BA147383395011310000B5CF18100AA +:10A4E0004039BC1A1230000A04300009E22340113E +:10A4F000BC1B5A2003245A2005220220001E0230D1 +:10A50000001FE262E8031220001F1220001D3828FD +:10A510001501025000201220001E4C5900108CA181 +:10A5200012500020D50B1220000A1220001D12200C +:10A53000001E1220001F122000208C815000004CB1 +:10A54000D5C53C1FFBDA49FFE709EAA49E41E62294 +:10A55000E9065A00040549FFFDF9D504DD455A080E +:10A5600002FC2E67292C5A680112EB39C810DD5302 +:10A570005A08010EDD40A6015A00060A5A000B08CF +:10A58000490034E4D50480C0D50284C18006FCA013 +:10A59000FC0149001F76F081F1018400EBFFEB081C +:10A5A000EB20EA20EA264412C4604422E20444324A +:10A5B00000004442DE5049FFD9FD2E07292E5A08DB +:10A5C0000108EA264412D73849FFD953FC813C0CD4 +:10A5D00001C1EBEDEA20FC81FC00DD5C49FFF96E76 +:10A5E000EA4AC01ADD5CC004DD5C5A080116DD5C75 +:10A5F00049FFF733DD5CC804EA4AEA83EAC5DD5C5B +:10A600005A080105EA4AEAB0EAC5EA4A5CF00030B5 +:10A61000E9038400EAC5DD5C49FFFB34DD5CC0046E +:10A62000DD5C5A080105DD5C49FFFB92FC80FC0003 +:10A630002E67EC005A60010884003E07EC2F84016D +:10A6400048000071840444100040DD432E07EC2FC5 +:10A65000C8058408DD423E67EC2F84044410004A9C +:10A66000DD43EB1A49FFF2775A00025D5A00132CC2 +:10A6700084044410004BDD43DD535A080127840451 +:10A68000441000AADD43DD4BA78097B0CE1C8404A4 +:10A69000EBB5DD433E67EFAA49FFF0D65A0013142D +:10A6A00084044410004DDD43DD41C0062E07EC77E5 +:10A6B0005A08010AF81DF81E5A00130684044410B3 +:10A6C000004EDD43FA03D52E8404441000BBDD4365 +:10A6D00084003E07EFAADD41C017DD4BA600C8F39A +:10A6E0002E07EC775A0801F08404EBB5DD4349FFEF +:10A6F000FF5149FFF3905A0013E784044410004DC2 +:10A70000DD43FA03D50FEBCAC003EB2CC0DC840495 +:10A71000EBB5DD4349FFFF6249FFF3645A0813EFCD +:10A72000D5D2FC80FC00EA8880C0840CDD50DD4777 +:10A73000DD46AE408409441000A1DD4349FFE74EE9 +:10A740008409441000A2DD43DD40A6415A180D0ED5 +:10A750008409441000A3DD432E07EC115A080119A7 +:10A76000DD47DD46AE40D50E2E17EF9CC9F24412F0 +:10A77000C3E14422C6F049003757EADE5A0801EA2D +:10A78000F8058401EB72C0FE84024800008B840946 +:10A79000441000A4DD434402FEF2A600C007DD40E1 +:10A7A000A6415A18030449FFCB8F8409EBB0DD435F +:10A7B0002E07EC6A5A08010C4402C3DAEBBAEAD657 +:10A7C0003C3DFB4E3C4DFB4C49FFD010840C00132C +:10A7D0000050DD43840D00130051DD43840E00134F +:10A7E0000052DD433C0DFB8DC035840B44100087C7 +:10A7F000DD438400EAA93C0FFB8DEAFC5A08550EA4 +:10A80000EB7CDD564422C38E3C3DFB454442C514DF +:10A8100049FFD202EAD4D503EA4FEB44DD5B49FF9E +:10A82000CD1B96003E07EC0B5A00033C5A0802135E +:10A83000DD47DD46AE40DD54A608C0FFDD455A00C9 +:10A8400002A5DD47DD46AE408401EB72C0FE48FF45 +:10A85000FF9D8409441000A6DD43DD54A6085A0874 +:10A860000206DD4BA6005A000205EBD95A08010F7B +:10A870008401AE08DD58AE08DD455A0002048400AC +:10A88000EBC0DD45C80349FFED5DDD40A6015A0080 +:10A890000B0449FFEA5F8409441000A7DD438401EB +:10A8A000FC803C0FFBA8DD9E3C0FFBA7DD9E2E0726 +:10A8B000F0E98E019600EBB1C802EB582E07F0E8E4 +:10A8C000DD9E841F3C0FFA748400EBB1EB58DD9ED3 +:10A8D000FC63A10540220840013100000091000105 +:10A8E00000A1000200B100038620E1A34EF200E0C7 +:10A8F000A081385145014C58C0D8A105415888085D +:10A900008895A7A0E4C3E9038EC3D50284C0A761DC +:10A910002E2728928CA3E0A2E9029F51A6A2E4432D +:10A92000E9038E43D5028440A7232E7728938C8396 +:10A93000E087E9029F39E1264EF300B7E0B34EF31A +:10A9400000B4E1624EF300B1E08A4EF300AE426320 +:10A950004C004252A40142422C01F681F582422170 +:10A960002800F483F403E0824EF3009FE44485A0C2 +:10A97000E90350D17FFD9D13F701F485F402E087D0 +:10A980004EF30090EB6E4453F04AAF283C4DFBA7CA +:10A9900080A7008200020560000042512073385BEE +:10A9A00015005A50FF7C05700001385B95114E541C +:10A9B0000076E4E484C0E9029FBB05800005A7633C +:10A9C000410C540000E8000140F71807E9679D3B7F +:10A9D00051247FFF83C44242480101280000E092D5 +:10A9E000E95D00C8000340F63407E95804FF80051C +:10A9F0008EA10108000242579401E0B0E94F43E202 +:10AA000038013C4003704306C00083844248202440 +:10AA1000432348004252B001F4848680E0B0E93E0E +:10AA2000F40481D288948892952140FF3807E93256 +:10AA3000386B10005A60FF2B419B982002CC80009D +:10AA400040F600114EF5002304F0800540F7900019 +:10AA500002F7800040F7801140F7F007E917442F14 +:10AA6000800040260804122C8000406C1840A6B0DC +:10AA700043398801A6B142948800A6B242A50801D4 +:10AA8000A6B342B5880048FFFF3150E700018C8231 +:10AA9000D5CD8D81414A2000D5C28CE148FFFF70A1 +:10AAA0008C4148FFFF618DA148FFFF21FCE3FC20A2 +:10AAB000A612C0038E01AE123C7DFBA7A753A63B96 +:10AAC0008E01D0038CA1AF53A610C0038E01AE102F +:10AAD000A63AA7518E01D0038CA1AF518400A75094 +:10AAE000011100018060E3A5E922A7920121000382 +:10AAF000E3C6E91BA73A81E542F310730500800520 +:10AB000040483C20EB7B41080011E59AE90CEB7BC7 +:10AB100002F200004108001140F78011E06F881038 +:10AB2000E802A4E08CC1D5E58CA1D5DEC3064410B3 +:10AB300001F4FE0C40000C17FCA0FC6280E0841FB6 +:10AB40003C0FFA743C0DFBA8F181A64381625CF0D6 +:10AB50008042E903EB9AAE43A6405CF08042E903F1 +:10AB6000EB9AAE40A683A600441003E8FE8C006575 +:10AB70008000FE444081001340908013C63D842035 +:10AB80003C0DFA7480A1E0A6E80FA0B938211501A8 +:10AB9000DA09A0BA38211501E2224002BC1B40119B +:10ABA0003C1B8CA1D5F13C1BF652A07D3C0FFA74E6 +:10ABB000EA633A000000B0433A008020006F800C46 +:10ABC000004F800D001F800F9834900140A00010AE +:10ABD000000F800E8C218A20443000648C819649BD +:10ABE000FE5C9BA697B1406098D68007F101B083C8 +:10ABF00097B1F881D503855F800650157FFC964894 +:10AC0000E638E90A4EA500095CF30079E9054490AD +:10AC10007D0044806978E3203EA7EC8AE9102E1776 +:10AC2000F0E85A18010900158000C1053C13F652DE +:10AC3000E63FE8052E17EC8B5A18010684003E0704 +:10AC4000EC8BD55DE300E9038420D56F3C6DFA748D +:10AC5000442F80008400FEB700358000E003E8093F +:10AC6000A07940108020A548DE02AC888C01D5F583 +:10AC70008007F10196B049FFFE2DA03D401018401D +:10AC80003A108400B0833A110420003580008C0310 +:10AC90008420E023E82DA0B93851050196AB4E245D +:10ACA00000255452FFFFD621D92000207FFD004F00 +:10ACB000800CE282E903102F800C00207FFE004F01 +:10ACC000800DE244E903102F800D00207FFF004F2C +:10ACD000800EE282E903102F800EA680004F800FC5 +:10ACE000E244E903102F800F8C218C04D5D3800718 +:10ACF000F101B08349FFFEDDE320E8098401EB5850 +:10AD00003C0DFBA88421A601EBB1D50F84000015F2 +:10AD10008000E001E89AA07940108020A4888C018E +:10AD200054217FFFAC88D5F42E07F0E9C00B5A18E8 +:10AD300001053E17F0E8D5068E019600EBB1C8027A +:10AD4000EB582E07F0E85A08010584201015800002 +:10AD5000FCE2FC002E17EF8080022E2731025A18E9 +:10AD600001073C13F894C103442000782E17EF9C90 +:10AD70005A180103A6843C0C01C04412DA00443284 +:10AD8000C3C98480EAE9FC80DD402E47294EA60134 +:10AD90005A0006049721D5032E4729502E07EC5C54 +:10ADA0002E272955E202E8068C013C4394AB3E076E +:10ADB000EC5C2E27EC402E0729542E37294DE2401B +:10ADC000E92F2E07EC415A080130FC2040000C0C02 +:10ADD0008A04960184E0EB4CE2E2E821A18AB441C6 +:10ADE00094F988C388430303000004508014A4909E +:10ADF00088A3FEA4A4E8422040738CE188432E3748 +:10AE0000294D40310C0D96D9ACF0A4F02E67294D98 +:10AE10004031980C8A439691ACA8D5DEFCA08C41B9 +:10AE20003E27EC40DD9EDD9E2E1729375A10010487 +:10AE30008401DD9EEBE3C84244326EB880803C134F +:10AE40009462E201E820EBED40108020A4883C13DE +:10AE500094AE9693FE4AE041E8119883A6508C2167 +:10AE60009648AE50A6903C1394A9E241E9093C13E0 +:10AE7000F6558C213C1BF655D5039843AF088C0141 +:10AE80009601D5DE3C03F6553C1394AFE220E8D1A1 +:10AE900084203C1BF655840044326EB8EB4CE20231 +:10AEA000E80698838C01AE509601D5F92E07EFA0E5 +:10AEB0008C013E07EFA08402DD9E84003C0BF6551A +:10AEC0008001DD9EFC204440271080C0FE642200EB +:10AED000002840208856FE24221300502233000010 +:10AEE000EAFFE022E85240F00DF6E04FE85044500F +:10AEF0000078FA788024991D4002040A5CF0005121 +:10AF0000E904524000A0D50480805A002805527000 +:10AF10000078D503447000503843111138731D1167 +:10AF2000FF0C40421C96E044E8039F41D504E082B8 +:10AF3000E8319CC1E0A3E8E04C01800380A35CF20F +:10AF40008051E904521280A0D502802550728028D9 +:10AF50005CF38051E9035272807838130511443054 +:10AF60002710FECC38131D118A82403184769A9ABC +:10AF70004242000342210003E082E90CE044E90977 +:10AF8000E2054002BC1AFCA0FA18FCA0EAC8FCA02A +:10AF90008005FCA05CF00051E905523000A0B661CC +:10AFA000D502B60150107FD85CF08051E9055200FF +:10AFB00000C8B602DD9EB622DD9E3C0FFC3BDD9E46 +:10AFC0004402ED648420AE42AE43AE46AE47DD9E01 +:10AFD000FC6D8140440166A03B0044004607FFFF32 +:10AFE00084C051CF8060EAFB3B0E44208121F28770 +:10AFF000F68F81A680A6510F805845E000564590F7 +:10B000000064F08DA618E2A04EF20108040480014D +:10B01000380015014C02C0FF0404800540001440B4 +:10B02000A640F181A68200E0000301400001F0018A +:10B03000401708018A148801EB42E4034EF200EB4A +:10B0400045507FFF40F708064EF300E5F70140FA50 +:10B050001C064EF300DD2F372892B409F08242011E +:10B060004C24F4029847944941220400011900013C +:10B0700054F880044EF300C9044480010119000013 +:10B08000F48338B245014CB2C0C0882A23608000E6 +:10B090004F6700BBC20B51117FFF80874248CC73C2 +:10B0A0003915110113180000D50313580000C70B00 +:10B0B000822743114C73F40D89A4391545011318E7 +:10B0C0000001D5031358000150F9FFFFE2EFE80635 +:10B0D0000310800113180002D503135800022F1724 +:10B0E00028938FA1E251E8094113CC00881138055B +:10B0F000010112080003D503135800039F39420BC6 +:10B100007824F4899D11F48A9D3940006416F48BEB +:10B110009F11F08854B580FF8400F48C391E010023 +:10B1200004CF800838484511F484E08CE866411E5D +:10B1300000200118800138484511F485E08CE85D55 +:10B140005A00020E5A00030F5A00010504CF80096D +:10B15000D50304CF800B048F800CD50804CF800961 +:10B16000D50304CF800B048F800A822C43144C73C8 +:10B17000F40241188408889101220001F4865529BF +:10B180000004552900FF4F23003989AA2388800035 +:10B19000F404437C7824417BE6F6E097E82EF4053E +:10B1A000E097E82BF40600F20000F40338F23D00CB +:10B1B0004CB7C02440FC5807B010E90C387019098E +:10B1C000B01238201909F80B3960190913208000D2 +:10B1D000D50F38C01909B01238801909B00F38B02E +:10B1E0001808B01483FF3980190913288000E6C4B9 +:10B1F000E8088CC197B0D5058C015A080491D50494 +:10B20000804E80F485A18CE148FFFF238C4148FFEC +:10B21000FF1B8CA148FFFEF85AD001044800007EB5 +:10B22000808DF207800A8029EAE984404717FFFFF2 +:10B2300080E2808250CF804850DF8040508F805025 +:10B2400051188FFF85C2E286E863380691013856AF +:10B2500011012E17289280604232847382C08023AD +:10B2600038341101383505092F2728929E6943602B +:10B27000C873826580628560441000FF515280016E +:10B2800051707FFF518000015029FFFF40FA88066E +:10B29000E9294025D800860041414400402BC000E8 +:10B2A00040FC0806E91C04F48000402A40004027C6 +:10B2B000882000F100015AF8021101910000B08FBE +:10B2C00038F110004CFCC0058CE197F8D5065A18EF +:10B2D000FF0380399C9996D08D81D5E18DE18972EB +:10B2E000D5D4804380604232C873B58940380C2081 +:10B2F00010E18001EBF6E2E2EBF8B4694001802056 +:10B30000E904B04F38109000AE408C81D59D840187 +:10B310003E07EFA88401FCED2E07EF5C5A080119E7 +:10B320002E472A244422018C842044500073E224B6 +:10B33000E80AA6108C218C0A96004200140118011C +:10B340000001D5F6800A8029F2078481EAE98400A9 +:10B35000FCEDFC20848080C0A7D0800480A445023E +:10B36000C860E2A7E816A0F1383195014C32C01050 +:10B370000513000296E839189501383810088C81B9 +:10B38000E7A697204001BC1AE68CE8038CA1D5EA19 +:10B390002E57EF5BA0F2E6A238018101E90FE683A8 +:10B3A000E80D8C81DC0B8E06E612E80880628001D5 +:10B3B0003C200370802649FFFE0DFCA0FC01F081BB +:10B3C000F80740000009F0019E41F181C8FBDD460D +:10B3D000DD47AE4083FFFC81FC02F081F0014410A8 +:10B3E00003E8FE0C50107C5E4603A19650000B1F34 +:10B3F0004200806940009409F083F001C802D50939 +:10B40000EA29F0039E41F183C8FCDD46DD47AE40EA +:10B41000FC82FC02F0818400F083D50ADD46DD4722 +:10B42000AE40440003E8EA2DF0038C01F083F10301 +:10B43000F001E220E9F4FC823C0FFC43DD9E3C0F6E +:10B44000FC42DD9E3C0FFC41DD9E9200FC4084E00E +:10B450003C2DFC4380C1808780A7862504F3000033 +:10B46000E81250F7FFFC5CF78002E90D05230007A6 +:10B470000500000238F8490101210006E3CFE80386 +:10B4800011118002B58651287FFFE7C2E9035B08EE +:10B4900004058C81972080E58CA197685063004C4F +:10B4A0005A580ADE2F17F123CC0684008420AE1AE6 +:10B4B00080A1D51FA61A5A00051B5A48011450082E +:10B4C000FFFFE602E8042E57F122DFF04400004CB3 +:10B4D0004213807384012250800422108005AE1A2A +:10B4E000D50884038420AE1A80A1D503842080A1CE +:10B4F000A61A5A0801263C6DFC41A7B35A680121DF +:10B500003D2DFC420269000951337FFF02690002B0 +:10B5100050937FFF84C241099A164302A473405896 +:10B520004CB70309000A032900038F818FC14068CB +:10B5300018D64260C873976B40134037964BE7A507 +:10B54000E81844F0B3503917C40040F8BC00DD0FD0 +:10B55000060C0C161C005A08010BD5105A00010CE1 +:10B56000C80C8403D50BE602E808D503C806D50647 +:10B570008400D5048402D5028404EBD68E01E6044F +:10B5800084C04EF2008D44F0B394EB2740F03C00B1 +:10B590004A003C0008003400500002018400446F5F +:10B5A000FFAA3C0BF8903E67E9D43C5BF88E3C1B4D +:10B5B000F88F3C5BF88C3C1BF88D3E07F1163E770C +:10B5C000F1223E07F114D56D2E07F1160261001A23 +:10B5D000E206E8048C013E07F1163C5BF88C3C1B4C +:10B5E000F88DD55F2E07F1175A0801262E17F11690 +:10B5F0000201001AE220E81F2E17F1150201001BBC +:10B60000E220E8192E07F114C8163CF7F8883C0729 +:10B61000F88C021100198A0FEB42E001E80C3CF7AC +:10B62000F8893C07F88D8A0FEB42E001E8048403B7 +:10B630003E07E9D42E17E9D484003E07F1155A10CD +:10B6400003313E07F1172E07F114C82B3C07F88D84 +:10B650000211001EE001E91D0211001FE020E9199E +:10B660003C17F88C0251001CE025E9130251001D23 +:10B67000E0A1E90F2E67F1160251001AE2C5E811A8 +:10B6800084A13E57F1173C1BF8883C0BF889D5097B +:10B690008402AE1AD5063E67F117D5033E67F12343 +:10B6A00084003E07F1243C03F890CC052E17EF826E +:10B6B0005A180110A454E201E8058C013C0BF890E3 +:10B6C000D52184013E07F1248404AE1AEBD6D51AA5 +:10B6D0002E17F1175A18010E2E17F1150251001BE3 +:10B6E000E225E8058C213E17F115D5033E47F117F9 +:10B6F000A454E201E904EA433E07E9D484003C0B88 +:10B70000F8902E27E9D45CF10020E81F8C4C96902D +:10B710008401E65EAE18AE998401E904FA2EF803BE +:10B72000D504802249003ED98403EB958400EBD6F2 +:10B73000EA433E07E9D444000060DD422E07F100F1 +:10B740008C013E07F100D5038400AE183C0DFC438C +:10B750003C1DFBE3A404E220E90484003E07EF9CC7 +:10B76000FCC0FC0084004412C468442FFFAAAE0849 +:10B77000AE0AAE8984203E27E9D4EBD63C1BF89074 +:10B780003E17F1243E07F1173E07F1163E07F1156B +:10B790003E07F1223E07F114FC803C0DFC43A4045B +:10B7A000DD9E2E07F124DD9E3C13953CAC40DD9ED2 +:10B7B000FC60A612C0038E01AE12A6135A0031041B +:10B7C0008C01AE13A610C0038E01AE10A6115A0054 +:10B7D0001F048C01AE110091000101310003010131 +:10B7E0000000A69250348001507980018A708AE26C +:10B7F00084C096D897F842B38C2482308086800625 +:10B80000E331E9218242E3F2E91C04A080054058BB +:10B81000C8A040551420F8095EF78024E91002A260 +:10B82000800040A50011888A02A2800040F5001126 +:10B8300083FFE00FE802A4288CC197B18DC1D5E445 +:10B840008DA1D5DFC006445001F4FF2C4042009783 +:10B8500044500064FFAC40F32DF65EF78026E836D6 +:10B86000E669E934E6E9E932EB31E603E82FDD4C3D +:10B87000A600C82C5CF21F41E92988534004C0008F +:10B8800090414030040A9415A10D9858F8059C5930 +:10B89000F8029E59882040120420A448964B5EF07E +:10B8A0008023E81483FF5010002088234E00FFF50A +:10B8B00050107FE0981940020020A40096035EF02B +:10B8C0000023E80484013E07EC8BFCE03C0FFBAA5C +:10B8D000DD9EFC638180EB31816180C25A080112D8 +:10B8E0002E07EC385A08020E3C0C00A880200910E4 +:10B8F000800200D0000100E0800100900002D50627 +:10B90000449000FF822981C981A984002E172A242E +:10B910004432000080809680E241E806988310411E +:10B92000018C8C01D5F9FA53503F801384800406B2 +:10B9300000058026B7BFEAE98460005F8013826358 +:10B94000810380838243804384FFB5BF9618E2055C +:10B95000E81E05030001965939080D0194194D00A0 +:10B96000C015A07238108D01E241E80BA0B480E34D +:10B97000880201200001A700A033804103300000AD +:10B9800050040001548000FF8C61D5E18400151F34 +:10B9900080033E07EC8B5A7FFF0448000121A0354D +:10B9A00040A38808153F8002F481B7DF880A3A0077 +:10B9B0000000B0453A008020B0858006802C49FF09 +:10B9C000FEF9A036B5DF38301E02A037F40138503A +:10B9D0001E0204030008053F800238001E02051FF6 +:10B9E0008003C00E3C2DFBAA00110032FECC0011DA +:10B9F000003341018217FF4C405280B7D50380A02D +:10BA00008200A0B5884AA61000A1000240F6800678 +:10BA1000A6D3A651E91CE22DE91AE3AAE918E271BE +:10BA2000E91640F70006E913E22EE911E32AE90FCF +:10BA3000E269E90D5CF980C9E90A2E07F12D5CF095 +:10BA400000C8E80D8C013E07F12DD50984003E07A2 +:10BA5000F12D5CF98078E90C5A77FF0B2E07F12C59 +:10BA60005CF000C8E8058C013E07F12CD509840084 +:10BA70003E07F12C841F3E07F12B3E07F12A2E07CB +:10BA8000F12C5A08010D5CF2002EE90950197FFCD7 +:10BA9000E639E8053F27F12B3E47F12A2E17F12B17 +:10BAA0005A10FF212E27F12A5A20FF1DE614E81A0A +:10BAB0008A4442210003E442E915000F8013E602A4 +:10BAC000E911DD4CA6C0CB0E2E17EF5B5A18010B07 +:10BAD000440001E0E7053C0BF89710158000E84DA5 +:10BAE000D5093C03F894C008E705E8038E01D502A8 +:10BAF00084003C0BF8945A7FFF0584008060D536A3 +:10BB0000A0B540711C4084C0A6BA012380033C1D2F +:10BB1000FBAA80068066E3C2E91EA73801338001D4 +:10BB2000E3E4E917011080028124429144738229E1 +:10BB3000049600054114C42002F8800040F78011EB +:10BB40005EF78023E904886488028CC18C81D5E982 +:10BB50008C41D5E2C6D30040803200208033FF1CE8 +:10BB6000FE844032187740011817001580005A10E3 +:10BB7000010844100050D5055A7FFFC48003EA7BBA +:10BB80002E27F12DE646E90544238D40A690C20CF0 +:10BB900040380C0142F18003E22FE9069A2842F076 +:10BBA0000003E22FE80D440001E03C0BF89784010C +:10BBB000EB1F2E172A24440201A484A0D5083C03BD +:10BBC000F897C0F78E013C0BF897D5F4D10E0820FA +:10BBD00000018CA110207FE79768D5F984A03E076B +:10BBE000F12D820548FFFF37FCE3FC0080C0A04632 +:10BBF000A0058444846F848584A049FFDE78A03644 +:10BC0000A075EA20FC80FC002E5729405A50010400 +:10BC10008401FC803C3DFB40A6D95A3009045A38C7 +:10BC200004193C3394BD994BE2239769E8049A596F +:10BC30009649D50284202E47EC33A0C2A0034031A0 +:10BC400090774000101796D996012E472987D51B6B +:10BC500044338D40A718CCDD3C3394BC994BE22390 +:10BC60009769E8049A599649D50280242E67EC1505 +:10BC7000B460A00140319877400018172E472986FC +:10BC800096D9960144F002004252BC01E2A3E805B5 +:10BC9000A6108C01AE10D505E201E9FB8400AE10C0 +:10BCA000DD40A6015A0804048400AE10A610E2800C +:10BCB000E8B08400AE102E07EFA18C013E07EFA183 +:10BCC0008402FC80FC2005008013006F8018011F97 +:10BCD000801C55087FFFCA0F8381BE124422016871 +:10BCE000B913EA6E406118405420FFFFA6749648CD +:10BCF000CB16D524447200004103C04045200064A7 +:10BD0000E2D1E8EB80F0427348735133806418232A +:10BD100080014C79FFFE8CC197B0D5F3446000647C +:10BD2000FE74401088404462006444220000884150 +:10BD30008826183100014C20FFFEAD00AD41FCA06B +:10BD4000FC20F6085A60010B4462DEC4387304001C +:10BD50004462D97039130400D503862284E98380B4 +:10BD6000B912450200005460FFFFFA38FE7CBF1490 +:10BD7000401098404063C00954737FFF44600060E6 +:10BD800088304268982440631C40A7CFAFD8A6CE25 +:10BD9000AEE0A6CCAEE8024000300230800D0200DA +:10BDA00000300210800C88648801F406F107400816 +:10BDB000002088D040380C20B664B601B406920A40 +:10BDC0009637AE10FCA0FC408380BD14B8144460CC +:10BDD00000485452FFFFEA50FEF4FF344042004056 +:10BDE000403194404452000088A484008A64386141 +:10BDF00094003860810908628001386101098C0172 +:10BE00005A0832F744020034888084A085233931EF +:10BE10009002411094000D2200014101140084E0C1 +:10BE20004203A42402A880004069800D97974065D2 +:10BE300019001A6880014009000D02680000961779 +:10BE4000400301008CE11A0800015A780AEB8CB417 +:10BE50005A5864DFFCC00400001344400064FEE450 +:10BE6000EA50400180404432000088608400990814 +:10BE7000A761384080004042400840421700995076 +:10BE8000A76940421500385100008C028885AB1923 +:10BE90005A0832EFDD9E0400001344400064EA506B +:10BEA000FEE440318040EA8588608400A51938406E +:10BEB0008008A75B9908AF61B48338410008A319D3 +:10BEC000995092888C02AF295A0832F2DD9E4412B2 +:10BED000DEC4380080008E015C000009DD9EE201B6 +:10BEE000E80AA610E260E8049AC3AED0DD9E8400A2 +:10BEF000AE10DD9EE220E80BA61052F180FFE00FAD +:10BF0000E8048860AED0DD9E841FAE10DD9EFC602C +:10BF1000EEA8F0858141F28480E35A3801053C8027 +:10BF20000B0FD506F9134E0200A23C800B0E2E0714 +:10BF3000EC8D84C1E602E9058E014063000C97B0E8 +:10BF40004063280E97B0CE0284C1B00A50BF80244F +:10BF5000505F8021F081F105F004B088503F8022CD +:10BF6000504F8023B77FF782F9C1F004B064B0BDB1 +:10BF7000003F8022004F8023F9C2F86F49FFFF8DF8 +:10BF8000B0248120B00B8380858044D000323855A6 +:10BF9000B202440065109928440073E840E2800032 +:10BFA00042063424F08584E039049D015CF807FFE3 +:10BFB000E8492E17EC8E3932C101003F80208E21D6 +:10BFC0004028040840098C164CA0C0158844A45091 +:10BFD0008A0840308C768A68EB4D42F00003E06FAF +:10BFE000E90413310000D52E38074101380E1C0832 +:10BFF000D5294EA3000639324109F810D5168844D8 +:10C00000A45040308C76401020018A68EB4D42F0FD +:10C010008003E06FE90A1331000038149D01382EC7 +:10C020001C003827050983FFF105B0CB98B9884378 +:10C03000960180288066F487F58649FFFF52F40751 +:10C04000F5068CE15A7832B25094806451CE0032B9 +:10C050005AC001048581D59CF004B04B502F805EFE +:10C06000003F802183FF49FFFEF8ED58FCE0FC61B2 +:10C07000F0818401B63F814280C3EA75DD455A00F4 +:10C0800002048400EA61DD548401AE08DD58AE0884 +:10C0900084003C0FFB992E07EFA75A08010684077E +:10C0A0003E07EC8DD50C5A6801072E0729813E0703 +:10C0B000EC8DD5052E0729803E07EC8D2E07EC8DE3 +:10C0C0008C013E07EC8E44000060DD50DD455A08CF +:10C0D000024C5A6801074413F423EA38EA37D50BB7 +:10C0E000440000618520DD50816944C3F04AEB972C +:10C0F00085A1D510A6085A0002F5AED0D5FC3C0D9E +:10C10000FB99C81CE9FD50048001EABCDD4B10D04E +:10C1100000002E07EC8EE320E8653CBFFB9B1086F9 +:10C1200000005A60010744000062DD5084E0D51829 +:10C130008006EA31EA98C0FFD5F73CBFFB99CE12E2 +:10C14000EA678E0154E000FF800E49FFFEC2C0087E +:10C15000800E8029B45F80668CE1F82D97F8E2EAC2 +:10C16000D5D28007D5F746B000F484E044C3F04A46 +:10C17000EB9785A150B582402E07EC8EE2E0E832C5 +:10C1800010860000F99844000061DD505A680105EE +:10C19000F001EB5DD506DD408420DD5749002A180B +:10C1A00044000062DD5085204C95000D80098027F9 +:10C1B000B45F806649FFFEAD50548001549280FF09 +:10C1C000D5F4DD4B8CE1549380FF10D000005A6809 +:10C1D00001062E77EC8E4C93BFD1800BEB5580E996 +:10C1E000D5CC8400EA758400FCE1FC212E07EFA782 +:10C1F000C8063C2394C13C3394C2D503EA948043DF +:10C200002E0728BF84C0EA653C4394BC3C5394BDD0 +:10C21000F08196904402ED8C96D8B6DF49FFFD542C +:10C22000DD4580E0EA65DD405A78021B844880667F +:10C23000F8245A0801053E07EF72D548DD408425F1 +:10C24000AE4184213E17EF133E77EF5AEA40844116 +:10C25000DD40EA658062F8113E67EF13D5172E279F +:10C2600028BF8066F80ADD408429AE41EBCFEA4062 +:10C270008441EA65DD40806249FFFEFBDD40842A9F +:10C28000AE4184213E17EF9CEA4084013E07EC1B3F +:10C2900084033E07EF5A8407DD508400EB9FDD45A1 +:10C2A0005A080206DD40842DAE41D50BDD408420C6 +:10C2B000DD572E17EC5FDD405A180203842AAE4189 +:10C2C000DD40EA404400006FDD50FCA1FC20EEB0F0 +:10C2D000B0C8B187505F8019F381F282503F801A55 +:10C2E000B086504F801BB6DFF08549FFFD2B004F15 +:10C2F000801BF005B062B0BB003F801A49FFFD65AE +:10C30000F005003F8019B049502F805649FFFDC508 +:10C3100084004430006444400032B049421010733D +:10C32000B1E282013853020242700C738420382338 +:10C3300085015CF107FFE805391804003912890905 +:10C340008C215A1832F65A0001048401D5E7ED50C9 +:10C35000FCA0FC61EA888120FA218404DD43840486 +:10C36000FA22DD43EA5A3CADFB583C0FFB58DD4155 +:10C37000C00444000040EA8F8404FA23DD4384C0F3 +:10C380003CBDFFD79DF197F8EAF58007802BEABE08 +:10C39000EBA8002F80068E41E648E90580C75A7851 +:10C3A00020F3D508800B80268440F814EB255A082A +:10C3B00008F73CBDFFD984C09DF197F88007802B1A +:10C3C000EAF5EABEEBA8EB255A080908800B80269F +:10C3D000844149FFFF7DD50480C75A7820EF84044B +:10C3E000FA24DD43DD41C81AEAE6804144300C807E +:10C3F0008402DD4444131F408041EA248402DD446A +:10C4000044000040EA8F84024412988A4422168035 +:10C4100044300640DD44EB40EA8F8404FA25DD43D6 +:10C42000DD41C00EEA7E441373E8EA2044031F4056 +:10C4300044138DD4442000C8EB1EEB40EA8F8404E3 +:10C44000FA26DD433CAFFB58DD41C804EA28EA2167 +:10C45000D505EA4EEA2CEA3AD507000480515A0085 +:10C46000BB04AE88D5FBEA7DDD41C004EA8EEAE676 +:10C47000EA20DD41C805100480508401EACBFCE1CC +:10C48000FC00DD455A0802158400EB1D8401EA75A5 +:10C49000DD46DD47AE40DD59A640C9FFA6405A182B +:10C4A00001FFDD4B8422AE408400EA75D50BEBE63C +:10C4B000EBD2EB5549FFDF42DD408420DD574900D8 +:10C4C000288744000065DD50DD41C00DDD47DD46B5 +:10C4D000AE4049FFB377C0FEEA7EEB47FA50EB056A +:10C4E00049FFD975FC80FC24442166A8EBAF444188 +:10C4F00066B8B084EBEA3B024C003B014C203901AA +:10C5000002024421D80040210040A79080E197B06A +:10C51000381F820284804513651045226238EB4C37 +:10C52000E282E81994E14021C40003310000402177 +:10C53000C800994BA490383810008C81FE9CA4E868 +:10C540004021180E8A53969340211C568843ACA86C +:10C550009721D5E644200C804431A2004230087374 +:10C56000800349FFAE80FCA4FC6184C08401EB37EA +:10C570003E67EC288126EA7580E6850485A644E3BB +:10C580008D405A78040B8400DD568040EA4B3ED73C +:10C59000EF5A8581EA91D50B80073E87EF5AF8194B +:10C5A0008180DD5684038047EA4BEA91DD4B84218C +:10C5B000AE409E39854054B000FF4CA60030DD5996 +:10C5C000A640C9FFDD41C00EE2C9E80CC70B800BD5 +:10C5D0004900224DF0818CC1800BF10197B049FFD9 +:10C5E000FF8400170000DD595A180311A6405A189D +:10C5F00001FFDD41C007DD5C5A0807FFEA7EEABAA9 +:10C60000EA2050048001EABCD504A6405A1801FF74 +:10C610005005000154A000FFD5D18CE197F85A785D +:10C6200005B28400EA758400FCE1FC45442166C83B +:10C6300044720000EBAFB042442166D83B00CC20EE +:10C64000EBAFA6BA81208400B186EA5C3810A6025E +:10C65000EB26A6FB92413B034C20EBE1EB26381383 +:10C660002602A6BAA6FBEBE1FCC53C0FFBABDD9EA8 +:10C670003C0FFBADDD9EFC008420DD57DD548400C3 +:10C68000AE08DD58AE088401EA3184018440842A72 +:10C690008080806280A2DD55DD47DD46AE40EA98AD +:10C6A000C8043C0DFB98C0FCDD41C0168401DD4A86 +:10C6B000DD47DD46AE4049FFB285C0FE8402DD4A5B +:10C6C000DD455A000214EA25EAB4AE0880418461CF +:10C6D0008402DD44D50BDD455A000209DD47DD4605 +:10C6E000AE40EA25A6085A0832FFDD455A0802077F +:10C6F0002E07EC218C013E07EC21FC80FC2080A061 +:10C700003C0DFBAB3C4C01C7A68394E9E2A2E825B3 +:10C71000F87BE906A4309783982AF87FF864922280 +:10C72000CD0DA421F83140220820A4109603E0206A +:10C730004EF200C98401EA42FCA09E1A8804A400BB +:10C74000964996039F91E020DE04E9F58845F83587 +:10C75000F82CF81B8845F8318403FE14E2A0E93573 +:10C7600099E3A5B897B3E026E90CA5B897F39BAA7F +:10C7700040621820A5B097B388C7E0264EF200A308 +:10C780009222D808F81396499603E020E9D483FF53 +:10C79000F8139E1A8804A4009592960396498EC1B8 +:10C7A000E020DE03E9C8F808E9C68C628864A418B2 +:10C7B00083FF4E00FFEB9AAA40220820A4109603A4 +:10C7C000E020E9B9FCA083FFD2039591DE19F81CA3 +:10C7D000E910F82096038807E020E90BA43097833E +:10C7E000982AF81B96038806E0204EF2006C83FF1F +:10C7F0008C62F825F811F826F82EF824FCA08EC1DA +:10C80000D6038E01D83099A3A4309603E02083FF8D +:10C81000E915A43097C39A2A40020020A40083FFA0 +:10C8200096038807E020E90AA4309783982A4E00EF +:10C83000FFF596038806E020E8458E628864A41818 +:10C8400092229603E0204EF3FF7783FF4E00FFE530 +:10C850004E00FFF9884540220820A41083FF4E00B7 +:10C86000FFF2FCA09F9A982341221800A4000269BD +:10C8700000008C624103001188649BAA40F0001103 +:10C88000A5D841121820982A026880004022002072 +:10C8900097FB4007C000A51097B388079723880629 +:10C8A00088049D0DE080E80E020900004E00FFCADA +:10C8B000A4184E00FFC8020880004E00FFC448FFC5 +:10C8C000FF36FCA02E17EC03C1092E272D12E241E2 +:10C8D000E9048E219648D50284204422EC1C38318C +:10C8E0000501E260E92BFC20840038010509EAA378 +:10C8F000842084A33C3C01C53C0C01C63C4C01CEC9 +:10C900009489886288028881A598A5C0A620880796 +:10C9100042031473404008099721AD183C4C01C5EF +:10C920003C3C01CE8844A4908861400008419600B8 +:10C930008C21AE185A18C8E0FCA0DD9EFC005A08F5 +:10C9400001122E1011612E0011605A1801048E037D +:10C95000D5028E02960084408020806249000898AB +:10C96000FC80490008A7FC80A641EA7C5A18041103 +:10C970002E17EC10C903A602D502A6032E17EC6FE2 +:10C980005A180208E604E9058E039600DD9EA60407 +:10C99000DD9E540000FD5A0804053C03F899DD9E15 +:10C9A000EA7C02000009DD9E5A0804053C03F89861 +:10C9B000DD9EEA7C0200000ADD9EEA7CA400DD9E8A +:10C9C000B400EA7CA447020000083C1BF8993C0B29 +:10C9D000F898DD9E2E17EC08C90984423E17E9B885 +:10C9E0003E27EC453E17EC28EA59DD9EFC00DD476A +:10C9F000DD46AE403C0DFB98C810EA815A0801069E +:10CA00004402C42049FFD5AB840184408020806269 +:10CA1000808080A2DD55D5EF8406DD4ADD41C01D52 +:10CA2000EA25EA38EA37A6085A003204AED0D5FC27 +:10CA3000EA28EA21DD5C5A000704AE88D5FC4412DE +:10CA4000C520840280418461DD442E07EF9CC00331 +:10CA5000840AD5028409EA23EA7044100033AE4008 +:10CA60002E07EDB0C81149FFBB955A00A10EDD415C +:10CA70008020C807840280418061848380A1DD55C5 +:10CA800049FFDC3AFC80840E49FFD4BDFC80FC00E9 +:10CA9000DD455A0802074403F422A600961FFC80D5 +:10CAA0008400FC80FC2084003C0BF66DDD40842378 +:10CAB0003C7DFB3F84C1AE41EB7FEA40DD4CA600EC +:10CAC000842397F84900140E3C7FFB3FEBB3C80A60 +:10CAD0002E07EC4CC8078409DD4A3E67EC5D3E67D3 +:10CAE000EC1BDD40EA40DD5484003E07EC4C840141 +:10CAF000AE08DD58AE08EA225A0004048405EA892B +:10CB00002E07EC658420C8093C1DFBADA448E62235 +:10CB1000E9038E22D50280203C1FFBE33C1DFB3F36 +:10CB20005A18020FC8093C1DFBADA448E62AE905C6 +:10CB30005000FFF6D5028400EA3BFA18EA99840116 +:10CB40003E07EC678400EAC7FCA0FC0084C03C6F91 +:10CB5000FB7DEB37EBEBEB933E07EC038401EA3113 +:10CB6000DD59AF80EBEBFC80FC00DD40A601EB293A +:10CB70005A080911EA225A0004048405EA892E079A +:10CB8000EC65C808F803E602E90549FFF6088E02DD +:10CB9000D5028400EA3BF81849FFDBB5DD40842963 +:10CBA000AE418420DD57DD40842AAE41EA40490091 +:10CBB000250F84008421EA2E3E17EF9CEAC749FF27 +:10CBC000F5D2490037E649FFDBACFC80EA7C3C3C0F +:10CBD00001C7A503842084019899A4909693E082CC +:10CBE000E80284008C225A1990F9DD9EFC202E1751 +:10CBF000EC455A18020B2E17E9B8C9072E17EC6D31 +:10CC00008E225C108001D50284203C6DFBAB3C4D34 +:10CC1000FA763C7C01C684A08461864353300000D0 +:10CC2000A6B35113800251017FFF4C58001D4101F2 +:10CC300004088F814C580018430148248F814C58B8 +:10CC4000001394928E41D20FA4B8027880008A47D4 +:10CC50009693E00238221509E903E053E8045A18D4 +:10CC6000010384628CA180F15A58C7DC5A18011C58 +:10CC7000401004098440FF4A38720911E027E80790 +:10CC8000A633880238F20111E02FE909E0E5E8084F +:10CC9000A633880238020111E005E80284628C4163 +:10CCA0005A2895EC8003FCA084204422EC1C380117 +:10CCB00005098C215A1808FDDD9EFC4080E0A60085 +:10CCC00080C25A08051E8401AE38DD4085203C9B99 +:10CCD000F7ACA601EADBF8153C13F66CE62AE8058A +:10CCE0008C213C1BF66CD5133C9BF66CA430E619EA +:10CCF000E804EA5B8400F8058400AC30D5088400C1 +:10CD000049FFFFD48400AC303C0BF66CFCC0FC0146 +:10CD1000DD40A601EADBF081F1014402C3DD4422DB +:10CD2000C43849FFFFCC2E17EC6D8400EA663E073D +:10CD3000EC2DC9033E07EC3084003E07EC03EA43C8 +:10CD4000EA97FC81FC20FD30EB9380A0A630AF7009 +:10CD5000C5092E172D1284C0E225E9059FA997B0B9 +:10CD6000D50280C5D01DDD455A08021B3C3DFBABFA +:10CD70008400A65B9449E001E80D8387BA09BC0BE7 +:10CD8000944188418824A4488C019649AC5096006F +:10CD9000D5F13C03F64EC00E8E01EA66D50B440277 +:10CDA000EC1C385019014410FFFFD1048CA13850FD +:10CDB00019092E17EC304000980E9604C81B051375 +:10CDC000800A050380090453800B40380000A498B2 +:10CDD000404880009691ACA0A498992896918C0226 +:10CDE000ACA05A0990F484014060180CFE773E17FD +:10CDF000EC30FCA0FC002E272D12441000FF402038 +:10CE0000880C4413F422A648FE93965F9690C103C3 +:10CE10008E219648A78084A14042840CFF37972238 +:10CE200096E0AEC04C61800D4C31000B882540521D +:10CE3000840CFF679768FF5D5C028001FC808005C1 +:10CE4000FC80FC008400EA66EAA3EA42DD40A60119 +:10CE50005A080422EA22C8094402C3A049FFFFCCB1 +:10CE60005A0801048403EA89EA225A08031D44028D +:10CE7000DA44842044200320EA41EA2BC807EA8BE5 +:10CE8000A600962EC8038404D50A8401EA8984008A +:10CE9000EB02D5092E07E9B8C8048402EA89D50354 +:10CEA000EA2BD5F1EA225A08020584003E07EC8FEE +:10CEB000840080804452E3A83C3C01C494418861D2 +:10CEC000A4D83C2C01C696D98841ACD03C2C01C5D5 +:10CED0003C3C01C688418823A4489649AC503C1C80 +:10CEE00001CE8820AF08384280088C015A08C8E675 +:10CEF000FC80FC208407DD4A84C0DD403E67EF13E0 +:10CF0000EA40DD4B84213E67EC21AE4084003C0FBB +:10CF1000FB8FEA9BEAC13C2DFB8FCA098401AFF06D +:10CF200080208062808080A2DD55D5F6DD47DD4619 +:10CF3000AE40EA98C80B3C2DFB98CA0884018427B0 +:10CF40008062808080A2DD55D5F58421DD40DD57EB +:10CF5000DD41EA28EA21C00E8400EA35AE883C2D86 +:10CF6000FB3FCA24840180208062808080A2DD553E +:10CF7000D5F7AE88EBCAC009840184408020806266 +:10CF8000808080A2DD55D5F749FFE257EAFA5A08BA +:10CF900003048402D5028401EA354412C46C84017E +:10CFA000EACB804184028461DD448408DD4ADD40AF +:10CFB000EA40FCA0FC4084E3812142709C24842050 +:10CFC0003E17EC2840A0080890E384C0E0CAE815AA +:10CFD0003C2C01C740211820A4909693E0E2E80A77 +:10CFE0008006802949FFFB8CEAB8C0043E67EEB09A +:10CFF000FCC08CC197B0D5EBFCC0FC60812180E007 +:10D000004412DE5C4402C37349FFFE9E4400FFFFEE +:10D0100084A03C1DFBAD8049A952A81300008016D6 +:10D02000E610E80452500010976884C0FB8043006B +:10D0300040013CADFBAB3CBC01C63C8C01C43CCCCC +:10D0400001C73CDC01C52EE7E9B82F47EC6D2F275F +:10D05000EC8F3D3DFB4580464512E3A882A60005C6 +:10D06000000394C2E043E868959140459800A4E02D +:10D0700040041800A400FEEC42304073926496D93C +:10D08000ACE04036180088CDA42002F300008A0FDF +:10D090009603AC18A4D8A40D96DBFE02E060E81A53 +:10D0A0005AE001045B480217380888008C0196009A +:10D0B00038088808A4CEE260E813A42086419601CF +:10D0C000AC302E07EEB1395888088C013E07EEB11E +:10D0D000D50738088800C0048E0138088808A4E005 +:10D0E00004048002E203E804A42014048002A4E003 +:10D0F00004048003E260E804A42014048003040410 +:10D1000080023C37F66DE260E8033C0BF66DA63911 +:10D110005A080908B413EA555A00010AA58BD50923 +:10D12000B413EA555A000104A58CD5034460006489 +:10D130008C419690D59580263F27EC8F49FFFF3C88 +:10D14000DD40A6015A080907800649FFFD513E0748 +:10D15000EC45FCE0FC4080E0A60180C15A08042BAD +:10D160009E0CE604E90A5A100C09EA225A00040649 +:10D17000EA2B5A08010AD50BDD41C8193C03F7AC6C +:10D180005A080116D5F6EB385A080108DD41C80CDB +:10D190003C03F7AC5A0801092E07EC105A080103AA +:10D1A000EBEB8007EB5DEA26EBF2EBC98400EB02C8 +:10D1B000D508EA225A00040649FFD8A88007EB5D8B +:10D1C000DD414E0200853C03F6644412E2048C010A +:10D1D000EAA33C03F64E8C01EA66800749FFFF0F85 +:10D1E000EB56A600C0058401EA428400EA3BEAB897 +:10D1F0005A08011584003E07EC2D84002E172D12CD +:10D200004432EC1C80809680E241E8053841810977 +:10D210008C01D5FAEA60DD42D5242E97E9B85A98F8 +:10D2200001159E34E602E9114402E2043C1394BF66 +:10D230004422C39D49FFF4E95A080208FA01DD427D +:10D240003E97EC283E97EC744412FEFCA6085A0860 +:10D25000A5098401EB9FEA423E07EC748400AE0806 +:10D260002E07E9B8C834A6385A080232EA225A0012 +:10D27000010F2E07EC8F5A0801062E07EC455A00C5 +:10D2800001073CF7F67B5EF78078E81849FFFCA0C1 +:10D29000C8093CF7F67B5EF78078E904EA42EAA326 +:10D2A000D50D840184E0EA793E77EF8249FFEB0BEC +:10D2B000EA225A0802043E77EC6DEA225A08020874 +:10D2C0002E07EC455A0802048400EA42EA43EA9732 +:10D2D0009E34E602E80CDD41C004EA4EEA2CEA3A4C +:10D2E0008400EA428400EA66EAA3D5055A6802048B +:10D2F0008401EA42EB385A000105EA2B5A0801057D +:10D3000084013E07EC19EAB35A080104EA42EA79BB +:10D31000FCC09200E60F4EF2007744F0D124EA8C74 +:10D32000EA3DDD0F102E48E0669CE0E0E0E0E0E042 +:10D33000E0E0A8008401EAD0AE084423F249842248 +:10D34000AE504423F24AAE104423F24BAE508464F4 +:10D35000D52B841FEAD0AE08EBBFAE084413F24AC7 +:10D36000AE084413F24BAE088448D53E8401EAD09F +:10D37000AE08EBBFAE084413F24AAE084413F24BBA +:10D38000AE084413F24CAE08D5328401EAD0AE08A0 +:10D390004423F2498424AE504423F24AAE1044237D +:10D3A000F24BAE50846C4423F24CAED04423F24D89 +:10D3B000AE504423F24EAE104423F24FAE50D5206F +:10D3C0008400EAD0AE08EBBFAE08D507EAD08400EF +:10D3D000AE08845FEBBFAE884413F24AAE08441334 +:10D3E000F24BAE0884414413F24CAE884413F24D24 +:10D3F000AE084413F24EAE084413F24FAE08441385 +:10D40000F250AE08DD9E9200C102EA8396004413FA +:10D41000F251AE08DD9E40003C0892104423F244D5 +:10D420004010BC08AC1092304403F246AC40DD9E84 +:10D4300084214403F240AE40EA21EA28AE88A640A7 +:10D440005A1001FFDD9E4413F258A448AC40441327 +:10D45000F25AA448AC414413F25CA448AC424413D1 +:10D46000F25EA448AC434413F260A648EBCEDD9EC6 +:10D47000FC02F0818002F383F18249FFFF4DF0014D +:10D48000F10249FFFFCA49FFFFD5F00349FFFFDD65 +:10D49000FC82FC02F0814403F242F182F283AF404D +:10D4A000001F80204403F243AE404403F252ACC05C +:10D4B0004403F254AD0084214403F256AC40001FF3 +:10D4C00080244403F241AE40000F8028001F802CCE +:10D4D00049FFFF9CF001F102F203F30C49FFFFCA80 +:10D4E000FC829200FC203C6DFBAE97C40503000259 +:10D4F0005510800F43085C0940781EE44273D80938 +:10D50000470FFF0F4273D40951080FFF4073C00249 +:10D510008E2A86404073C604E625A9F21323000331 +:10D520001123000B4EF2007C012F8038011F803048 +:10D53000010F8034007F802C44F0D344EBC8EA9E76 +:10D540004A003C00060606767600C003EB85D5034C +:10D550004021BC08F00792509201AC32F00692A133 +:10D5600092011203000BF008926192011203000E67 +:10D57000F009ACB092011203000F220F801E1203BB +:10D58000000C220F80201203000D020F8022AD71CB +:10D590008C01ACF41123000C1113000D1103000ECB +:10D5A0001073000F1123001011130011110300124A +:10D5B000107300131203000AD532C003EB85D503A4 +:10D5C0004021BC08F00A92509201AC328400100352 +:10D5D0000010840192819261100300118400ACB0AC +:10D5E000AD31ACF41123000C1113000D1103000E2A +:10D5F0001073000F11030012107300131123001495 +:10D600001113001511030016107300171203000CFC +:10D610001203000D1203000E1203000F4403F14029 +:10D620008421AE40EA38EA37A6405A180104AED049 +:10D63000D5FCFCA044038CF03C0FFBAE441FC67825 +:10D640004403F142AC40840044138D08B6013C1DF4 +:10D65000FBAEA80F3C1DFBAE14008008DD9E8420AD +:10D660003C0FFB50AC43DD9E3C3DFB5092019221B0 +:10D670009241AC18AC59AC9ADD9E3C1DFB50A68281 +:10D680001020800CA6831020800DA680A6011020FB +:10D69000800E1000800FDD9E3C1DFB50A6821020E6 +:10D6A0008010A68310208011A680A6011020801271 +:10D6B00010008013DD9E3C1DFB50A68210208014BC +:10D6C000A68310208015A680A601102080161000C9 +:10D6D0008017DD9EFC01B63FF28149FFFFD0B41FE9 +:10D6E00049FFFFDCF00149FFFFE8FC81FC24007FDB +:10D6F0008060F081F182F283001F803C002F80382F +:10D70000000F8040006F804C105F8016103F801427 +:10D71000102F8017104F8015101F801A103F80188F +:10D72000100F801B104F8019CF08105F801E103F14 +:10D73000801C102F801FD507101F801E103F801CDB +:10D74000100F801F3C0DFBAE104F801DF855B0052B +:10D75000B046B087F856F001F102F203F8573C0DDD +:10D76000FB50021F8028AC44001F8054002F8044CF +:10D77000FE775263002040609824001F80481060AC +:10D78000000A58108040FE571010000B221F802CFA +:10D790001210000C221F802E1210000DDD47DD46F6 +:10D7A000AE404403F1408421AE40A6405A1001FF30 +:10D7B000FCA4FC04F08194199600F182100F8017EC +:10D7C0008422100F801B84C13C0DFBAE103F8014DF +:10D7D000104F8015103F8018104F8019103F801C8B +:10D7E000103F801F104F801DF283101F8016101FE6 +:10D7F000801A106F801E49FFFF34B005B046B08715 +:10D8000049FFFF6AF001F102F20349FFFF2F3C0DCF +:10D81000FB5084208449AC441010000B1020000AF7 +:10D82000DD47DD46AE404403F140AF80A6405A10CC +:10D8300001FFFC844403F148A6404403F149A600DB +:10D84000EB469601DD9E44100055DD46AE40EA8D64 +:10D85000A6085A0001FF84214403F380AE40EA2168 +:10D86000EA28AE88A6405A1001FFDD9EFC00441352 +:10D87000F381A608EBA0AE0884004413F384AE083D +:10D880004413F56BAE0849FFFFE0FC804453F3817D +:10D89000A72896D8544200F0FEA740110444968869 +:10D8A000400100E496804403F384AEA8AEC0DD9E40 +:10D8B00084004413F386AE084413F387AE08DD9E5C +:10D8C000FC604403F38496D8AEC049FFFFBEDD4739 +:10D8D000DD46AE404413F380A6085A0001FF4473AE +:10D8E000F3864463F3874493F04A44A0005544B35D +:10D8F000F380A6385A08010C49FFFFDC49FFFFA559 +:10D90000EBFA000580005A0001FED5F4A6305A005B +:10D9100001F5FCE0DD9E441E0000880192029601A4 +:10D920004413F3CAAC08DD9E4413F280A608EA54FF +:10D93000AE08DD9E4423F280A650400080A49600ED +:10D94000AE10DD9E441E0000880196814413F286CD +:10D95000AC884200400B4413F288AE08DD9EFC60A8 +:10D960008141001000094473F280968CA67880C033 +:10D97000661080020000000A401088243C7FFBB043 +:10D98000AE789684A638A470EAB640000844AE3853 +:10D990004403F284AC40A03149FFFFD600130008D5 +:10D9A0004403F283AE40852044B3F04AEB97000372 +:10D9B000000B49FFFFC149FFFFB9A6389604C01309 +:10D9C00084011085800049FFECFB50048001EABC13 +:10D9D000E72FE9F42E07EFB35A0801F184023E075E +:10D9E000EFB3D5174403F2813C0FFBAF5AA80307EE +:10D9F000A6404210880BC1DCD5095AA80106A60032 +:10DA0000EA55C807D5D55AA80205A600EADAC0D05B +:10DA1000FCE0C80844138D25A6088C019600AE08CA +:10DA2000D50E44238D26A6508C219648AE505A0818 +:10DA300001074413F060A608EA7FD5064413F0609E +:10DA4000A608540000FBAE08DD9E96004413F06863 +:10DA5000AE08DD9E4423F053A6509604EADC88010C +:10DA60009600AE10DD9E4413F06AA68896045421F9 +:10DA700000FEAE88A68888029600AE08DD9E44238C +:10DA8000F054AC104403F056AC40DD9E4031C80861 +:10DA9000402189808802401004C084A54443F06D71 +:10DAA0004403F06EAF603C1FFBB13A100420DD9ED2 +:10DAB00084204403F06DAE40DD9E4403F061A60077 +:10DAC000EA55DD9E4403F061A6009207DD9EFC004E +:10DAD00049FFFFFAC80749FFFFF25A000106840117 +:10DAE000FC808400FC808402FC804423F064A65007 +:10DAF000EADCFE0F9600AE10DD9EFC004463F00EE3 +:10DB0000A4304200200BC00744138D24F81C840865 +:10DB10004800007BA430EACAC859A430EADAC0063B +:10DB200044138D23F8108403D56FA430EA55C00642 +:10DB300044138D22F8088402D567A430EA5FC00A36 +:10DB400044138D21A6088C019600AE0883FF84043F +:10DB5000D55BA4309604C04E49FF9543A4304200E3 +:10DB6000180BC836A4304200140BC834A43042004D +:10DB70001C0BC832A4304200240BC00B4403F064D9 +:10DB8000A640964CC12BA640EADCAE408409D53CA9 +:10DB9000EBA6A4404210A80BC923A4404210AC0B32 +:10DBA000C921A4404210B00BC91FA4404210B40BBD +:10DBB000C91DA4404210B80BC91BA400920FC01A83 +:10DBC00084013E07EF4C840FD51F8401D51D8406C8 +:10DBD000D51B8405D5198407D5178409D515840A62 +:10DBE000D513840BD511840CD50F840DD50D840E5F +:10DBF000D50B4403F01AA400EACAC00549FF94F10A +:10DC0000FA01D502FA0884204423F00EAC504423D4 +:10DC1000F01AAC50FC8084214403F322AE40DD9E18 +:10DC20004413F323AE08DD9E4403F323A600DD9ED8 +:10DC3000FC004463F540B6064403F544B6204403B3 +:10DC4000F548B6404403F54CB6604403F550B68041 +:10DC50004403F554B6A0F1044403F558B620F10589 +:10DC60004403F55CB620FC80FC614433F504442396 +:10DC7000F5024413F5033C3FFBB34433F50580C084 +:10DC80003C2FFBB63C1FFBB53C3FFBB25A000304E4 +:10DC900048000145DD414413F51AC0048401AE0873 +:10DCA000D502AE084403F5788420AE40843FAE40F0 +:10DCB000442FFFAA4403F579AE8084C1AE404403EB +:10DCC000F500AF808400802080408060EA3C84239F +:10DCD0004403F501AE408400802080408060EA3C2F +:10DCE000EB19A608EA9AAE08840080208040806084 +:10DCF000EA3C44000802EA2D3C1DFBB5A608EA9A5E +:10DD0000AE088400802080408060EA3C4400041A11 +:10DD1000EA2DDD474403F509AE40840080208040B1 +:10DD20008060EA3CEB19A608EA54AE083C0DFBB54E +:10DD3000A68058210001AE80A68858210004AE8834 +:10DD4000A68058210004AE80A68858210008AE881D +:10DD5000A68058210008AE80A68858210010AE8801 +:10DD6000A64058108010AE40840080208040806023 +:10DD7000EA3C440005AAEA2DEB19A608EACEAE0853 +:10DD80003C1DFBB5A608EACEAE088400802080408A +:10DD90008060EA3C2E07EC484E030116DD403E67EA +:10DDA000EC48A601B61FDD45DD565A08020584047D +:10DDB000AE09D5038409AE098501DD403E87EF1326 +:10DDC000EA403C2DFB5844020168046100128420A3 +:10DDD000EA6E4060184004A300030493000340056A +:10DDE000100954A0000340049809960F3E17EF1342 +:10DDF000F081A1F3A03344B3F68066000030EAB0AE +:10DE0000A833A033FA6F660000C0EAE3A833A0335A +:10DE100092E86600030058000200A8330441001392 +:10DE2000844C929054027FFFA73597CFFF14404255 +:10DE30000040EA8540E2000004D7000046080008E0 +:10DE400004C7000140068002B60E460F000F4006D0 +:10DE50000002140700014423F683841F108580000C +:10DE6000AE104423F684AE104423F685AE1044234E +:10DE7000F686AE104403F687AE404403F688AE4003 +:10DE80004403F689AE404403F68AAE408400802005 +:10DE90008040EA3C4403F40BA640442000395480FF +:10DEA00080FF4413F415AE888424AE408401EA3127 +:10DEB000440005AAEA2DDD47DD46AE40EA98C0FFE2 +:10DEC000840085208020109580008040FA6FEA3C15 +:10DED0004403F415EB994403F40B10800000A033C5 +:10DEE0006600003040A0288414A30003A033F10191 +:10DEF000660000C0409004C414930003A033660081 +:10DF0000030040701D04A9F3DD40001F800014D7FA +:10DF1000000014C70001AE41D556C83184414413F6 +:10DF2000F500AE8884434413F501AE883C2DFBB662 +:10DF30008060A65058108002AE503C2DFBB5A65014 +:10DF400058108002AE5080208040EA3CEB19806679 +:10DF5000A608EA7FAE083C0DFBB5A6805821000458 +:10DF6000AE80A68858210008AE88A640804658108A +:10DF70008008AE4080068026EA3CD5255A08012458 +:10DF8000A6D0A608543180F3540000F3AED0AE08FA +:10DF90008400802080408060EA3C84004413F500C7 +:10DFA000AE084413F501AE08EB19A608EA80AE08E6 +:10DFB0003C1DFBB5A608EA80AE08840080208040A6 +:10DFC0008060EA3CFCE1DD9E46108000EAE4EACD98 +:10DFD0004210EC0940008364EA6BDD9E46100800A5 +:10DFE000EAE4EACD4210DC09400082E4EA6BDD9EFF +:10DFF00044110000EAE4EACD4210C0094000820466 +:10E00000EA6BDD9E44108000EAE4EACD4210BC09D0 +:10E01000400081E4EA6BDD9E441002006413280393 +:10E02000641308026610820040008124EB664413EA +:10E03000F7EFA60896009684C203EAA6AE08DD9E16 +:10E040008422EAE4EACD6610800240008024EA6B74 +:10E05000DD9E46100080EAE4EACD4210CC09400083 +:10E060008264EA6BDD9E64120002C00458008001E5 +:10E07000D5036600800164020003DD9EDD9EDD9E07 +:10E08000DD9EFC4080E04403F040A7808121814276 +:10E090005463001C5A780225DD41C0144422FEF668 +:10E0A0004433F04AEB6EA6104412FEF65A00EC041C +:10E0B000AF18D5FA8400AE08804184618402DD4443 +:10E0C000D50A4412FEF6440FFFECAE0880418007EB +:10E0D0008461DD44EA70FA30AE408400EA61840075 +:10E0E0004413F00EAC08FFBF4413F01AAC0897B00D +:10E0F0004403F040AF80DD47DD46AE405A78020A67 +:10E100004410005AAE40490000FCC8FEEA6BEB66C2 +:10E110004413F0DAA608EBA0402500049690AE88E0 +:10E12000540480FF4413F0EDAE08DD474403F04192 +:10E13000AE40EA29EA29EA29EA29EA29EA29EA296C +:10E14000FCC0400004A44423F0429600A6D0AE10C8 +:10E15000DD9E965F9604400080844413F043AE0831 +:10E16000DD9E4413F044AC08DD9E540000FD4413D2 +:10E17000F046AE08DD9E40003C0892104433F200A9 +:10E180004010BC08AC1892304403F202EB85AC405E +:10E1900092504403F204AC80DD9E4403F20AA64090 +:10E1A000EA21EADC58108001AE40EA28AE88A64099 +:10E1B000964CC9FEDD9E96004423F206AE109648AA +:10E1C0004403F207AE40DD9EFC00DD41C004440282 +:10E1D00055B8FC80440215B8FC80FC00DD41C00449 +:10E1E00044024A00FC8044020A00FC804403F20B13 +:10E1F000A600DD9E4413F208AC08DD9E4423F20A1B +:10E20000A650964C400080249600AE10DD9E9200F1 +:10E21000E608E82344F0E020EA8CEA3D4A003C00AE +:10E22000080E141A20262C324403F20CD515440390 +:10E23000F20ED5124403F210D50F4403F212D50C9E +:10E240004403F214D5094403F216D5064403F21828 +:10E25000D5034403F21AAE40DD9E9200E608E8239F +:10E2600044F0E06CEA8CEA3D4A003C00080E141AC7 +:10E2700020262C324403F20DD5154403F20FD5129B +:10E280004403F211D50F4403F213D50C4403F215E5 +:10E29000D5094403F217D5064403F219D503440304 +:10E2A000F21BAE40DD9E92004403F0C4A600DD9E4A +:10E2B00096004413F0C4AE08DD9E4403F0C3A600EC +:10E2C000DD9E96004413F0C3AE08DD9E4403F0CEFD +:10E2D000A4004413F0D0A648400080E4441D02008E +:10E2E00088015C000080DD9E4402FE00DD9E8421EA +:10E2F0004403F0F5AE40DD47DD46AE40DD9E44030D +:10E30000F0F4A6009204DD9E4403F0F7A600DD9E23 +:10E3100096004413F0F7AE08DD9E4403F0F6A60025 +:10E32000DD9E96004413F0F6AE08DD9E4452FE00DA +:10E330004412FE3E18028001D9FEDD9EFC404400DE +:10E3400000FD49FFFFF54463F068EA77EA82F803CD +:10E35000FA09EA2DA630EBCB49FFFB794400049281 +:10E36000EA2DEA5BD5F5FC0049FFFFEA9200442361 +:10E37000F0C7A65096485A080105581080C0D5022B +:10E38000966FAE50DD9EFC00441005FC4403F0CEB9 +:10E39000AC4084204403F0D0AE40840149FFFFE943 +:10E3A000FC804423F0ECA6509604541080FB4000FF +:10E3B0008044AE10DD9EFC0049FFFFF5FC80440365 +:10E3C000F0CEA4004413F0D0A648400080E4EAB2A6 +:10E3D000FE0DEAD5DD9E92024413F0E6AC08DD9E08 +:10E3E0004413F050A608EAE3AE08DD9E4413F05053 +:10E3F000A6089637AE08DD9E4423F050A650961727 +:10E40000541080F8FE47AE50DD9E4423F050A650D5 +:10E4100096175410808F40008084AE10DD9E441308 +:10E42000F050A608EAE0AE08DD9E4413F050A608BE +:10E43000540000F7AE08DD9E4413F051A608EA54DC +:10E44000AE08DD9EFC008407EB7684204403F04C8C +:10E45000AE40840749FFFFDB84214403F04EAE4009 +:10E4600049FFFFECFC8096004413F04CAE08DD9EA3 +:10E470004403F04DA600DD9E3C0FFC4EDD9E3C0D9E +:10E48000FC4EA600DD9E44030FA0EABA3C0FFB62DF +:10E490003C1FFB393C0FFB41DD9EC0045A000209C2 +:10E4A000DD9E3C0DFC4EA6003C0FFA77DD9E3C1F26 +:10E4B000FA77DD9E40003C0892104433F1C44010CE +:10E4C000BC08AC1892304403F1C6EB85AC409250C6 +:10E4D0004403F1C8AC80DD9EFC00EBD7A682A643C6 +:10E4E0004403F1C2AE804403F1C3AE403C0DFB6275 +:10E4F0003C1DFB393C2DFB4149FFFFDEFC808400C5 +:10E500003C0FFB9484214403F1C0AE40DD9EFC60CF +:10E510002EB728922EA728B52E9728B42E772893A9 +:10E520004E030087EBC1C03D3C0DFB71E615E93998 +:10E530002E0010AAC8113C00083A50F07FB05CF7DA +:10E540008BE0E8083C00083B50F07FB05CF793603C +:10E55000E9038401D5028400EB3AEBF05CF0070894 +:10E56000E807EA45C019EAF184CCC017D5155CF07C +:10E5700008FCE807EA45C010EAF184C4C00ED50CD7 +:10E580005CF00A8CE807EA45C007EAF184C5C005DB +:10E59000D5038400EB3A84CF2E17EC768006C905AC +:10E5A000840084CFEB3A80064413F1C210B080009F +:10E5B0004413F1C310A080004423F1C4441FAC48AD +:10E5C000AC50443FA6084423F1C6ACD04423F1C864 +:10E5D000AC5096004413F1C1AE08F8A6DD47DD4605 +:10E5E000AE40EB22A6085A0001FF4403F1C210B06E +:10E5F00000004403F1C310A000004413F1C4440F11 +:10E60000ADD8AC08442FA7984413F1C6AC88441386 +:10E61000F1C8AC0897B04403F1C1AF80F885DD477D +:10E62000DD46AE40EB22A6085A0001FFF8035A006F +:10E6300001044800006EEBC1C0283C0DFB71E615DB +:10E64000E924EA965CF00708E807EA45C019EAF110 +:10E6500084CCC017D5155CF008FCE807EA45C0106B +:10E66000EAF184C4C00ED50C5CF00A8CE807EA45D8 +:10E67000C007EAF184C5C005D5038400EB3A84CF16 +:10E680002E17EC768006C905840084CFEB3A80060D +:10E690004413F1C2109080004413F1C3AFC8442367 +:10E6A000F1C4441FAD10AC50443FA6D04423F1C682 +:10E6B000ACD04423F1C8AC5096004413F1C1AE086D +:10E6C000F833DD47DD46AE40EB22A6085A0001FFD5 +:10E6D0004403F1C2EB994403F1C3AFC04413F1C446 +:10E6E000440FAEA0AC08442FA8604413F1C6AC8818 +:10E6F0004413F1C8AC0897B04403F1C1AF80F814DB +:10E70000DD47DD46AE40EB22A6085A0001FFFCE0E3 +:10E71000FC0649FFFEE33C0DFA775A000F10960005 +:10E720004413F1C1AE0849FFFEECDD47DD46AE40C3 +:10E73000EB22A6085A0001FFFC86FA30F1858422FC +:10E740008400EBF684A1F187EB20F083F084F0865F +:10E75000F088F0892E472893B67FF581F382F58AF9 +:10E76000EB088041EA3FFC86FC212E07EC3F80E469 +:10E7700080C55A0801098406441000E1DD43EB6BB3 +:10E78000B606D5599E0CE6025000FFF8E9049680C3 +:10E79000E642E81D9600E602E92D2E07EF13C00BB6 +:10E7A0008405DD438406441000E2DD433C0DFFD9BF +:10E7B000B606D541F181DD45F1015A0802F3840620 +:10E7C000441000E3DD43EBB4B606D5355A180D25E9 +:10E7D0008406441000E4DD432E07EF5A8E01E6065E +:10E7E000E81044F0E5ECEA8CEA3DDD0F1A060E2451 +:10E7F000141A3C0DFFD9B606D51EEACCB606D51BB9 +:10E80000DD4CA600C804EA5AB606D5155A0803140A +:10E81000EAD1B606D5108E2AE622E808EACCB6057B +:10E82000441000E58406DD43D506DD4CA600490012 +:10E830000D23B606DD41C016EAAF5CF000A0E91278 +:10E84000DD535A08010684033E07EF03D50BDD5361 +:10E850005A0802092E07EF035A08030584003E07F1 +:10E86000EF03B4064412FF80402008093C0FFB4F21 +:10E87000B641041000084422FF84966FB622A0011E +:10E880004412FF88962FAE08EB364412FF89A00190 +:10E890004452FF909206962FAE08EB364412FF8A40 +:10E8A000A001443D0070920C962FAE08EB36441246 +:10E8B000FF8BA0014422C6549212962FAE08440248 +:10E8C000FF98986B38110400EAEED8FCEB09B446C7 +:10E8D000441E0000882292229649EBA5EB09441EB3 +:10E8E00000208801920296014413F400AC0897F8C6 +:10E8F0004403F402AFC0FCA1FC2044716714381338 +:10E900008602463000FF40608C0292CC1060000905 +:10E91000406090091060000A38638A02462000F0C7 +:10E920004073080292F040138484FEE6926C10104B +:10E93000000B4410FF00407304021030000EFEAEC6 +:10E9400040321009FE6E952492E840220A15922862 +:10E950001070000C1060000D1030000F102000101F +:10E960001010001110500012FCA0FC02444166E897 +:10E970003B024C00EBEA380F8000FE45380F840064 +:10E98000FE85380F88005600000FFC82FC41B4A0C1 +:10E99000EA5AD050EAD1D04EEBB4D04C3C0C030B29 +:10E9A000E608E84844F0E7B0EA8C40F03C00DD0FB0 +:10E9B000127826485A3C7008EA4AC83E8400EA6247 +:10E9C000D53B84003E07F13DEB338E02E602E8348E +:10E9D0008402EA62D5312E07F13D8C019600E606ED +:10E9E0003E07F13DE9298405EA62D5262E0010E4B0 +:10E9F000C8238406EA62D5203C0C030C5A08030F96 +:10EA00003C100853E622E8F6D5163C0C030C5A08D5 +:10EA100003F23C000853E602E8ED8404EA62D50CF8 +:10EA2000EB33E602E809D5CBEA4AC0C98407EA62BB +:10EA3000D5038401EA620402801444120300921098 +:10EA4000EA50EA633C1C030BE62D4EF2011544F03C +:10EA5000E85C38178501EA9E4A003C001A008C00E9 +:10EA6000EC002C016801A801B201BC01D001080230 +:10EA7000DA010E0214022E17EF765A1801058420CF +:10EA80003E17EF768420EA59841F3E0010C1EA4702 +:10EA9000C8083C0C0090EBA33C0C0091EBEFD509AF +:10EAA0005A0801083C0C0092EBA33C0C0093EBEFDE +:10EAB0003C1C03074491671497C89648EB68EB0C1D +:10EAC000842AB61F84468007F88938048202F081C0 +:10EAD000EA6EEA85B49FEB14F5018426844A8067C8 +:10EAE000F88D8400EA53F84F8421EA59EA47C808B0 +:10EAF0003C0C0090EBA33C0C0091EBEFD5095A08BD +:10EB000001083C0C0092EBA33C0C0093EBEF3C1C87 +:10EB100003064491671497C89648EB68EB0C84236E +:10EB2000B61F84428007F85A38048202F081EA6EE8 +:10EB300044020040B49FEB14F501842284438067B3 +:10EB4000F85D8405EA53F81F8422EA593C1C030847 +:10EB50004491671497C89648EB68EB0C8421B61F64 +:10EB600084428007F83B38048202F081EA6E440256 +:10EB70000080B49FEB14F501842284418067F83E45 +:10EB80008400EA53480000788423EA59460000CC08 +:10EB9000500002BCEB0C8426B61F84428401F81E90 +:10EBA0004411671438008202F081EA6E440200C00A +:10EBB000B49FEB14F501842284468461F81F84011C +:10EBC000EA53D5598423EA5946000093500000AF18 +:10EBD000EB0C8426B61F8442840349FFFEC844110F +:10EBE000671438008202F081EA6E440200C0B49FCC +:10EBF000EB14F50184228446846349FFFE7F84027E +:10EC0000EA53D5398424EA598404EA53D534842557 +:10EC1000EA598400EA53D52F8426EA592E07EF7665 +:10EC20005A08012284003E07EF76D51D8427EA5951 +:10EC30008405EA53D5208428EA5904028016441238 +:10EC40000200EA50EA634624259F4613DA6050101A +:10EC50008E45502101BAA841A842A883A844A845DE +:10EC6000A846A8478405EA53D5068407EA53D50386 +:10EC70008406EA53FCC19200DD40A6019E44E622D0 +:10EC8000E9075A000906DD4CA600E602E8098400FF +:10EC9000F811AE08F816A6405A1001FFDD9EEBAC45 +:10ECA000A600C0085A0001065A0002045A08030AC6 +:10ECB00084004413F572AE084413F57383FFAE0865 +:10ECC0004403F3808421AE4083FFA6405A1001FF25 +:10ECD000DD9E8400EB7D84214403F403AE40DD9E81 +:10ECE0004403F403A600EAD5DD9E4403F40CA60019 +:10ECF0009600C8074413F3CFA64840000406DD9EE3 +:10ED00008401DD9E8400EA8DEB7DAE08DD9EFC0073 +:10ED10005A08011149FFFFB249FFFFDD842B84002F +:10ED2000EB1744138D463C0BF6583E07EC50AE08EB +:10ED3000FC80EBAAFC804403F01DA680A641A6C07F +:10ED400040110504581084009688AE809228A68150 +:10ED5000AE41EA214413F421F806502100014C2170 +:10ED6000FFFE8440AE88442000004430000A83FF48 +:10ED7000502100014C21FFFEA6409648AE40DD9E8A +:10ED8000FC20DD454432DEC4EB5A4422E26C5A08D2 +:10ED9000021484004472DA244462E2F84452E89097 +:10EDA000F8123840800838428000384100088C0151 +:10EDB0005A0820F8FCA084004472E24C4462EBFC48 +:10EDC0004452D990384380003841800838430000CD +:10EDD00083FF3841000838428000384080088C01A9 +:10EDE0005A0820F2FCA0A6403E101160A6413E1039 +:10EDF0001161A6423E101162A6433E101163A64562 +:10EE0000A68440210500A647A6C640118500003013 +:10EE1000000900400008EAED3C3808B40030000B5F +:10EE20000040000AEAED3C3808B50030000C3E30E6 +:10EE3000116C0030000D3E30116DEBCC969396DCDA +:10EE40003E30116EEBCC964B4231840B3E30116F4D +:10EE5000EBCC3C2808B24231880B3E301170EBCC31 +:10EE60003C1808B342318C0B3E3011710030000F5A +:10EE700096DF3E3011720030000F92643E30117305 +:10EE80000030001100400010EAED3C3808BA0030B4 +:10EE9000001300400012EAED3C3808BB00300015BA +:10EEA0000040001496CFEAED3C3808BC0030001555 +:10EEB00092623E30117A003000170040001696CF63 +:10EEC000EAED3C3808BE0030001792623E30117EF9 +:10EED0000000001E962F3E00117F42012C0BC00641 +:10EEE000440FF000FE873C2808B24200AC0BC0067D +:10EEF000440FF000FE473C1808B384093E0011722D +:10EF0000FA063E001173DD9EA4C0442200004412A4 +:10EF1000D6CCEA3EB661A4C2EA3E1430800FA4C447 +:10EF2000EA3EA8CAA4C6EA3EA8C902300008EA3EE2 +:10EF3000143080100230000AEA3E1430800802309B +:10EF4000000CEA3E143080090230000EEA3E143014 +:10EF5000801102300010EA3E14308012023000129C +:10EF6000EA3E1430801302300014EA3E143080145C +:10EF700002300016EA3E1430801502300018EA3ED6 +:10EF8000143080160230001AEA3E14308017020056 +:10EF9000001C4021004014208018DD9EFC00EB097D +:10EFA0003C2DFFD7441E0000882292229649EBA5F3 +:10EFB000FC80A40044120000EA633C0FFFDDDD9EEC +:10EFC000FC004423F6AC4413F6AD5A080106AE101B +:10EFD0008407AE08D5048400AE10AE0884008020FB +:10EFE0008040FA6FEA3CFC80B44084A08C449C2DA5 +:10EFF000A2D196005A58200680A05A0823FADD9E16 +:10F000005441803F384094088CA197689266D8F3A9 +:10F01000D5F4FC20B48084608C8484E5B4045A3830 +:10F02000060566000FFFD504921E400078084221B5 +:10F030009C2484A096905A20200C386088008C4133 +:10F040004063140C8CA6880696905A581EF68C6164 +:10F0500096D8AA215A3807E4FCA0FC20B4608400AA +:10F06000503180249583A31997B0844099568C41E0 +:10F070005472000F976896903870940892845A28BA +:10F0800008F78C0196005A0804EFFCA0FC20B4603D +:10F090008400503180349583A31997B084409956E9 +:10F0A0008C415472000F976896903870940892843F +:10F0B0005A2808F78C0196005A0804EFFCA0FC457A +:10F0C000EA5A3C0FFB4F84234403F40BAE408426E2 +:10F0D0004403F404AE4084014413F407AE0844131F +:10F0E000F408AE0884404413F01EAE884413F420A4 +:10F0F000AE08EA4C5A080105EA5A4900081F4402C2 +:10F10000D6CC4412DA2449FFFF714402D6CC441213 +:10F11000E890F8054402D6D04412E21849FFFF9F58 +:10F120004412E2F84402D6CC49FFFFB2490009C9B3 +:10F13000EBD749000A3FB1C1440166F83B004404E3 +:10F1400080273B00C424A600AE08B18444016704B4 +:10F150003B00440480263B00C424A600509F801C32 +:10F16000AE08844984208009EA41840110048006A5 +:10F1700084204442E24C4432EBFC4402D9903823D0 +:10F1800084003822040838230400382184083824F5 +:10F190008400382004088C215A1809F3FCC5FC00AF +:10F1A000B480844050420024840080A098D096D837 +:10F1B00038308C00958296DF4031980C8C0188A302 +:10F1C0005A0808F68C489690AB615A2820EFFC80CC +:10F1D000FC04A649B4405A1003045A180D0FEB3F23 +:10F1E000A648C9054412E890EA87FC845A1803250A +:10F1F0004412E218EA87FC845A180407F8165800EB +:10F200000003B889FC845030FFF6E662E80B8420E6 +:10F2100084463820FC088C215A1820FD803FEA875C +:10F22000FC848E28E622E8088382B8096600000F75 +:10F2300083FFEA7FB889FC84FC00A68180C05A2045 +:10F2400003145A2006129E14E602E90E50017FF8BC +:10F25000E602E90E50017FF6E602E90A5A280D1E81 +:10F26000DD455A08020684003E07EBFBD504840105 +:10F270003E07EBFBEAF3A6712E27EC1084812E37B4 +:10F28000EC324452C4D049FFFA71DD455A000206FF +:10F29000EA5E802649FFFF9EFC80FC00B48084402B +:10F2A00050420034840080A098D096D838308C002A +:10F2B000958296DF4031980C8C0188A35A0808F695 +:10F2C0008C489690AB615A2820EFFC80FC014412D8 +:10F2D000DEC4F08149FFFE9FF001EB5AF9BBFC81CF +:10F2E000FC2480E180C049FFFD4D2E201172444274 +:10F2F000DEC44402D9702E3011615A780635842953 +:10F3000038120808E662842238100808E924DD452E +:10F310005A08022284005A6803122E1011614432E6 +:10F32000E218F83C5A0820FFEA92C00D8E22844071 +:10F33000881FE24110F07FFFD5064422E890F83F95 +:10F340005A0820FFEA928429381F8008EA5E803F2D +:10F35000EA87D54CEA924412E26C8443EACFEA5E33 +:10F36000EA87D5448420381208085A6803053860B3 +:10F370000808D504842138100808E662E930DD4524 +:10F380005A08022E5A6803192E00116184285A085F +:10F390000203842784004432E21838218000382F89 +:10F3A00080088C0183FF5A0820FAEA92C010881F57 +:10F3B00010107FFFD50C84004422E8903811000023 +:10F3C000381F80088C0183FF5A0820FAEA928422B1 +:10F3D000381F8008EA5E803FEA87D508EA92441227 +:10F3E000E26C8445EACFEA5EEA87EA5E49FFFF7095 +:10F3F000FCA4EBB73C1DFFE6D10C3C1DFFE7D10997 +:10F400003C1DFFE8D1063C0DFFE9FE2DEAD5DD9E4F +:10F410008401DD9EEBB73C1DFFD7D10E3C1DFFD80C +:10F42000D10B3C1DFFDFD1083C1DFFE0D105EBB443 +:10F43000FE2DEAD5DD9E8401DD9E8445403008170F +:10F44000848696D8FE2438108E024000800D962FB8 +:10F45000DD9E3C1DFB3F3C3DFFE45A1802043C3D51 +:10F46000FFE6EB86442201209230EA6A4011044014 +:10F470000440800A462C003F50210FFF54000FFF2C +:10F4800040004808FF16FF071440800AEB8644320C +:10F4900001809230EA6A401184400430800AFE9E66 +:10F4A000FE171400800ADD9EFC00446201044063E4 +:10F4B00000202203000049FFFFCEA4303C0BF6637E +:10F4C000FC80FC4180C03C0DA3E8F081EB16EACC47 +:10F4D00080E181224C5000C1CE04AF9084E1D50F71 +:10F4E0005A680409800149FFFFE11074800084E339 +:10F4F000D506B00138600400AE5084E38400EB5AB6 +:10F50000386080088C014492D9705A0820FB49FF6A +:10F51000FF83C0123C0DFB58441203C004000014CA +:10F520009210EA50EA633C1C03068C259648AE44D0 +:10F53000AE45AE46AE4749FFFF5EC0693C2DFFE6D3 +:10F540004412042050810050B40844339780921034 +:10F55000EA50EA633C1C030784888C259648AE4435 +:10F560003C1C030884A28C259648AE46B40844127D +:10F5700003609210EA50EA633C1C009084CB8C2517 +:10F580009648AE443C1C009286098C259648AE45B0 +:10F590003C1C00918C259648AE463C1C00938C2563 +:10F5A0009648AE47B408441203C09210EA50EA638A +:10F5B0003C1C03063C2DFB4F8C259648AE44AE45C3 +:10F5C000AE46AE47840004110008966FE001E840A3 +:10F5D0009843A6489648E634E809E62CE810C1129C +:10F5E0005A180A1339048008D50F5A10140650F01F +:10F5F000FFE0E2AFE90938448008D50638648008A6 +:10F60000D503387480088C019600D5DEEBB7EA5A32 +:10F61000D003EAD1D81D84283E100200842A3E106F +:10F6200002023E10020C2E1011724422DEC4382158 +:10F6300004004402D9705A2809068442382004087C +:10F64000D507387004082E10117338700408EA5E6C +:10F65000EB5A49FFFE24FCC144138D40AE08AE981E +:10F66000DD9EFC0180C0DD4CB65FF381AF80800180 +:10F67000EA408006B43FF20149FFFF25FC81FC60AF +:10F6800084003E07EBFBDD40842300A000014473AF +:10F690008D41AE410093800049FFFB74840080409F +:10F6A0008067DD5644638D4000B30000EB81EA5E65 +:10F6B0004412DA2449FFFCAF8403DD568049806799 +:10F6C000EB81E7628403E8028400AE304412DA245E +:10F6D000EA5E49FFFCA0A630DD568049EA4BEB818B +:10F6E000A6303E07EC46DD4010A00001FCE0FC2007 +:10F6F0008380BA12BF1354217FFF4442032040226B +:10F70000084092F05403FFFFA7D5844CFFD4407308 +:10F710008040EA8588E0C3239221520086409641CA +:10F72000EAB44000801796009E45E637E8138461EE +:10F730004061800C9F41842088039AA94041880C35 +:10F7400098814021880CFEA78C21FF975A1805F755 +:10F75000D51AE605E916466FF800D5152E07F13CD7 +:10F76000C8098401466CCCCC3E07F13C50630CCCFC +:10F77000D50A466333333E37F13C50630333D50338 +:10F78000446001FFFFB3DD41C00292D042033C0B55 +:10F79000F80E464FE3FFF827A8394203380BF80765 +:10F7A00050420FFFF829A8394203340B8C0654103D +:10F7B0000007A03983FF66000007FE0FA839420347 +:10F7C000300BF8226600700040000584B607420343 +:10F7D0002C0BF81A66000E0040000524B607420301 +:10F7E000280BF812660001C0400004C483FFB6076E +:10F7F0004203240BF809660000384000046483FFCC +:10F80000B6074203200B8C0654100007B40783FF91 +:10F8100066000007FE0FB60742031C0B8C0654203F +:10F820000007B4074418FFFFFE0E40000A044223FD +:10F83000180BB6078C4654310007460FFC7FB447BF +:10F84000EAFBFE8640210E64B6474223140B8C4629 +:10F8500054310007B447FEA640210EC4B6474223E8 +:10F86000100BF80B462F1FFF50210FFFFEAE40215B +:10F870000F24B64742230C0B8C46B4A75431000723 +:10F8800083FF4628FFFF50210FFFFEAE40210F846B +:10F89000B647A0F94223080B8C469697FE5E4010AF +:10F8A0008A04A879A0B94213040B8C269657FE1639 +:10F8B0004000066497B4A8398CC654030007A1B968 +:10F8C000FFA6406302C4A9B9FCA08400EB3FAE08C8 +:10F8D000EA7B3C1BF6714412C8C43E07EC46AE08F6 +:10F8E000AE09AE0AAE0BDD9EFC60847FAED084DF35 +:10F8F000846084A18246808382034532C8B8812512 +:10F90000814302B0000097D8E3618220E80A38A959 +:10F910008C08A540E2B2E8098245820784A0D5069A +:10F9200038998C08AFD0D50284A0031880008C6170 +:10F93000E3A68C024068BC1B4043BC1B5A3804E35E +:10F940005A50010380908004FCE0FC42FA40812080 +:10F9500080E1801F8420EA412E27F1444432C65CB6 +:10F96000EABD3801880880834462EDD4C704387347 +:10F970000909D50484013803090984209C11450133 +:10F98000683445100BB899419757387214005A7073 +:10F99000FF0F38380400385315014231C424403178 +:10F9A0009476385F9E028865383F9E0A8C215A18EB +:10F9B00008EC842080618081385F86029788E28528 +:10F9C0008C2140333C1B4042BC1B5A1804F7E647CD +:10F9D000E90284003E07F14410348000FCC2FC00C0 +:10F9E0002E27F15A84C340111857443003209690B3 +:10F9F0004412817842110C73DD5EEB1E2E07F15A22 +:10FA00008C0196004060183796484010041B3E1742 +:10FA1000F15AFC80FC002E27F15984C3401118577D +:10FA20004430032096904412817842110C73DD5EBD +:10FA3000EB1E2E07F1598C0196004060183796484E +:10FA40004010041B3E17F159FC8084003C0BF65B10 +:10FA50003C0BF64BDD4CA600C0049E43E622E812A8 +:10FA600044037320A6003C0BF64B4413732244035B +:10FA7000732144237323A600A648A6903C2BF65B73 +:10FA8000D5269E41E622E9035A0805208400445306 +:10FA90007320802044337334A7283C23F64B8CA476 +:10FAA00088443C2BF64B0022FFFD88020022FFFE1B +:10FAB0000042FFFF88223C23F65B9601884496496A +:10FAC0003C2BF65BDBEAD503840080203C23F65B0D +:10FAD00088223C23F64B9649880296013C1BF65B34 +:10FAE00088203C0BF64B3C1BF659DD9EFC008460E5 +:10FAF00080A384DF9718E282E80738500D09386048 +:10FB00008D098C61D5F8FC80FC0084A040308C20ED +:10FB10004C118018A500A588E2C4E803A500AD0833 +:10FB2000A580A510E2C4E803A500AD100A4080013D +:10FB30000A6100018A86E0A4E80297618C02D5E997 +:10FB40008005FC80FC2084A08260412140098082E5 +:10FB5000800597E9E2E3E83C5CF38064E90650F352 +:10FB6000FF385CF78064E8304069942002F30000BD +:10FB700003108000E3AFE8050303000013008000DA +:10FB80000313000002F20000E3AFE80503030000E6 +:10FB90001302000003108000EB7B4108C001E0105D +:10FBA000E8133D180B2A40080013EB7B3D080B2B94 +:10FBB000A5B03C680B2C3C780B2D3C080B2E3C2848 +:10FBC0000B2F3D280B308CA18C228C82D5C3FCA03E +:10FBD000FC004440032080C1EAE64210107380011B +:10FBE000802280434430012C49FFFFAEAC30FC80C2 +:10FBF000401004204430FFFF84404C00800EA500DC +:10FC0000E244E803A4809691A500E283E803A4C03F +:10FC100096D98C02D5F344000096420180019A10D7 +:10FC20009601DD9EFC7BB18281808420449000C8D7 +:10FC300080068448EA414014B036856040908408CC +:10FC400044732D5085404CA60014B004B05D442090 +:10FC5000003249FFFF4DEA7B8007EB43381329014F +:10FC6000E220E803380329098D4188E9D5ED447382 +:10FC70002EE05AB001048561D5E64422C3934410B6 +:10FC800007D0800649FFFE32EA2A38130101EB54FF +:10FC900049FFFE5D2E07EC01EB8E3813010138237E +:10FCA0000901E241E8069A8A5CF100C8E804D5023D +:10FCB0008440EA2A9451443001F440108C37E62302 +:10FCC000E807C907441000C740108806D5028423FE +:10FCD000EB8E2E57F15BDA072E37F14588613E3700 +:10FCE000F145D5033E17F1452E37F145E663E803AC +:10FCF0005A18030684003E07F14580023E27F15B57 +:10FD0000FCFBFC2080C180E0AE08840449FFFF8C2E +:10FD10004412C8B838109C002E27EF785A180108F2 +:10FD2000E642E8098C413E27EF78D505C2048E41B2 +:10FD30003E27EF7884203E17EF772E17EF78C10526 +:10FD400084213E17EF77AE30FCA0FC6044600320B6 +:10FD5000FE34448301904463000050B1819050A26E +:10FD6000019080E18122890088C0EA7B8006EB4314 +:10FD70000214800081A9E220E802EB7950C30190CF +:10FD8000EA7B800CEB43021680008D22E220E80320 +:10FD90001204FFFF5015FE70800650257E70F80992 +:10FDA000A47881A7E220E802AC38802B800C804A3E +:10FDB000EB05EB50021680008CE2E220E803120310 +:10FDC000FFFF5063006450B5806450A500644C642C +:10FDD0007FCEFCE0FC00EB312E17EF9EC0203C0DE7 +:10FDE000CB1E5A18010592019601D5039202960185 +:10FDF0003C2DFBDAE2402E07EF7AE806E61EE80F1C +:10FE00008C01EBC6D50CC00B5CF10E10E906E60FB9 +:10FE1000E9048E05EBC6D5038E01EBC65A18011115 +:10FE20002E07EF7A5A081E058405EB71D50CE614EF +:10FE3000E9048406EB71D5078407EB71D50449FF0B +:10FE4000F320EB71FC803C33F8A75CF18033E913BD +:10FE5000FC00848084C3E282E80D40301020A55865 +:10FE6000A4C88C81FEF490624031945C1A30800109 +:10FE7000D5F3FC80DD9E84003E07EF798400EAE73D +:10FE8000DD9EFC003C03F8A7EB2BE905EAEC8400BF +:10FE90003C0BF670EB9DEB2BE9038400EAAEFC8093 +:10FEA00084003E07EF7884003C0BF8A1DD9E3C0304 +:10FEB000F8A1EB2BE905FC0049FFFFF4FC80DD9E77 +:10FEC000FC012E07F15CC0048E013E07F15C49FF86 +:10FED000FFF02E07EC01501F800749FFFF142E078B +:10FEE000EC235A00FF2F84023E07F15C2E07EF73CC +:10FEF0008C013E07EF734400004ADD422E17EC23CD +:10FF0000E624E81FEA4744F0FD10EBC8EA9EDD0F47 +:10FF1000041A041AC816840184273E07EF763C1E93 +:10FF2000030B3E000C14EB61D50C5A08010B840145 +:10FF30003E07EF768407EA6284003E000C14EB6112 +:10FF4000FC81DD40A6015A080309DD535A08020668 +:10FF5000FC0049FFFFB7FC80DD9EFC0080C08400F0 +:10FF60003C0BF65949FFFD732E07EC15406300D694 +:10FF7000DD453C2394D85A0002088423FE54964958 +:10FF8000E2C1E90BD50EEB5BE2C20010002BE809E1 +:10FF90003C03F659E220E9058400EAAE8400D5026C +:10FFA0008401FC80B461AE185A2802049208AE198C +:10FFB000B4018840B641DD9EFC448140B61F8121DA +:10FFC0008400B1C13815000038101C088C015A0893 +:10FFD0001AFB44001900F844EAD1B43FA680AE8869 +:10FFE0000400001EB43F92109C89962FB65FAE09A4 +:10FFF000F82B844244000280F835EA5A803F0460BE +:020000021000EC +:100000000014EA8592D0EA6E406018408386B80EEC +:100010008442F821F823B80BF829F823B41F001301 +:100020000028AE40B41F84429C41B63F3C1DFFE413 +:10003000046080144412018092D0EA6E40609840BF +:1000400000130028AE41B41F803F8C01B61F83FF10 +:100050000403000E92109605F80502030016803F77 +:10006000844249FFFFA10403000B803F921054001B +:100070000FFF83FF4E00FFF6440FFFAA10048051CC +:10008000EA28EA21000480515A00CC04AE88D5FB4E +:10009000DD41C0074412FE51840280418461DD4489 +:1000A000840038138000381500088C015A081AFBA8 +:1000B000840010048051FCC4FC0044030C803C1CF0 +:1000C00001BF442000C8EB1EFC80FC002E07EC247E +:1000D0008E01E602E808DD5E44030C80EA843C2FD2 +:1000E000FBBDEB1E2E07EC24EB295A0801164453E6 +:1000F0000C80442F74F84430096044430FA08400FE +:10010000986AA5A838608009500003204C01FFFBC5 +:100110008CA2DCF6FC80FC80FC0049FFFEB449FFA9 +:10012000FFCD2E07EC24C008EAECDD4CA60049FF09 +:10013000FFCE8400EB88FC80FC0004000014441215 +:1001400000609210EA50EA632E1729B810100018C8 +:100150002E1729B9101000192E1729B61010001BE0 +:100160002E1729B71010001AA0454210F008A84514 +:10017000A0454210F408A845A0454210FC08A84537 +:10018000A0454210F808A845DD41C005440373208E +:10019000F804FC804403738449FFEBBFFC803C0FF0 +:1001A000FC58DD9E5A00010544128178D502EA848C +:1001B0005040832080A184001A028001DCFEFC20D4 +:1001C0004453000044630C80800180650A21800153 +:1001D000A5C04023885C1A2000014C027FF95052D0 +:1001E0008320DEF38400443281784440096084A097 +:1001F0009883386080013861140950528320DCFAFA +:100200008C025A0B20F6FCA0FC60848084FF84C121 +:10021000826780A482244492C8C48166810403005A +:100220000000552200FFE3828140E80E03008000B9 +:10023000E383E80A38849008A580E2D3E808826660 +:10024000823284C0D50538B49008D50284C00B0032 +:10025000800102A500008C81898AE3878C024078A6 +:100260003C1B40593C1B5A4804DC5A60010380B1D6 +:100270008005FCE0FC002E17EC5D3C6DFFD7C10B48 +:1002800084003E07EC5D441000E684063C6DFFEE02 +:10029000DD43D534C80ADD535A000131DD535A0815 +:1002A000022E3C6DFFE6D52A5A08030EDD535A088C +:1002B00001053C6DFFD8D522DD535A0802203C6D64 +:1002C000FFE7D51C5A08010EDD535A0801053C6DA5 +:1002D000FFDFD514DD535A0802123C6DFFE8D50E3E +:1002E0005A08020DDD535A0801053C6DFFE0D506A2 +:1002F000DD535A0802043C6DFFE98006FC80FC00D7 +:100300002E07EC42C82B3C0DFBE45CF00032E90404 +:100310002E07EF66C0062E07EF655CF00032E91E7F +:1003200084203C1BF655840044326EB8EB4CE2024C +:10033000E80698838C01AE509601D5F93C0C01BBC0 +:100340003C1C01BDEA2044000033EAE7EA84EBF9F3 +:10035000DD5E49FFFD7A8401EAABFC8040300C2071 +:100360004C0180051A200001D5FCDD9EFC4051FFA8 +:10037000F9B8F0818400EB01EA84B0028440EA24F9 +:10038000EB96500F8328EA844420FFFFEA24EB9683 +:1003900084C044A00320449281784472EDAC80096B +:1003A00042032873B042502F8328EA2449FFFBCC34 +:1003B000380399098CC1EB015A6803F3B042502FFE +:1003C0008328EA24F00149FFFBBFEB013C080B2224 +:1003D000EA84F00149FFFB05DD4CA6008E03E6022E +:1003E000E8113C03F67144600032EB2BE9089E41B2 +:1003F00050007FCE406018D69B8E97B13C6BF67153 +:10040000D504EB5B0260000EDD455A000205840353 +:10041000FF8497B13C03F7B63C100B243C080B2338 +:10042000E220E8033C080B24E2C03C680B253C08B2 +:100430000A403C680A41E80584023E07EF79D51678 +:100440002E17EF79C1048E213E17EF793C13F66920 +:10045000E220E90A3C03F8A74410EA5FE220E9063B +:100460008C01EAE7D5038400EAE7EBC3E602E9077B +:100470008401EA9584003E07F140D5098400EA959D +:100480002E07F140C0048E013E07F14051FF86481F +:10049000FCC044038D40A6402E07EC55C1062E1724 +:1004A000EC545A1801038C013E072958DD9E441074 +:1004B0000055DD46AE40EA8DA608C8FFDD9E3C1D16 +:1004C000FFD7442200C0040080149210EA5040017B +:1004D0000040B400920A96373E07EC3304008014C3 +:1004E000441200009210EA50EA63B4200000002891 +:1004F000922A96773E17EC153E07EC3CDD9EFC00F9 +:100500008400EB7DDD4B8421AE4084018020EB63D1 +:10051000DD46DD47AE403C2DFB54A6505A1001FF8E +:10052000DD47AE40840AEA48DD4B8421AE408400BA +:10053000EB113E07EF65FC80FC008403EB88EAA129 +:1005400084008040DD56EA4BEA918400EAAB3E0726 +:10055000EF6584013E07EF66EB32DD4CA60049FFF4 +:10056000B929EAECFC80FC20444200002E672A24D2 +:10057000842044338D4080E49688E246E819A758E9 +:100580009881C50400510020D50338500400410271 +:10059000040010580184A758C50400210028D50381 +:1005A0000021000899791022818C8C21D5E6FCA0CD +:1005B0004422D6CCB46244420000EB86A091923033 +:1005C000EA6A401204400410800A923254108FFFED +:1005D000964B121000813C1BF668EB860421001537 +:1005E000923044320180EA6A4011844054217FFFF6 +:1005F0004432000C402188400230801F103001043A +:100600000230801F9268103001050230801E1030C9 +:1006100001060230801E926810300107A4D310300A +:100620000108A4D3926810300109A4D11030010A46 +:10063000A4D192681030010BA11284619298545297 +:10064000003F044080114041903E404290E4104001 +:10065000010CA09204108011924896AFFECE40315A +:100660000CE41030010DDD9EFC2080E080C1DD41F6 +:10067000C00C501301048041846A8402DD44EA52B4 +:10068000840249FF9B15D504840249FF9B11EAD1DE +:10069000442201808380B914BB1592304402000CBF +:1006A0005431FFFF40300C40EA6A0003010540115D +:1006B0000440002301044001010096011200801F44 +:1006C000000301070023010640010100960112000A +:1006D000801E0003010C40201C0950408044B404DB +:1006E000EA8040000824B604B4040023010DEBF3B3 +:1006F000400008F5B6040003010900130108EB46A9 +:100700009601AC1B0003010B0013010AEB46960196 +:10071000AC190003010CA09A5410003F460C0FFFC7 +:10072000EAFBFE1640000704A81A0003010D54104E +:10073000003FA01A66003F0040000504A81AC70346 +:100740008EE197F88403DD568047EA4BEB81FCA0ED +:10075000FC6081218162814380C4DD54A60896003B +:100760005A0801FEDD58AE088020EB63DD59A64033 +:10077000C9FFA6405A1801FF84003E07EC44DD4142 +:10078000C020DD5C5A0807FFEA7EEABAEA20DD4BAA +:100790008421AE400074812ECF05F8083E77EC44EA +:1007A000D5100073005197FCCF0649FFB853107461 +:1007B000809ED5058400EBAB49FFB7918401EB1F08 +:1007C000840AEB0B84001003005110030052100345 +:1007D0000053FCE03C1DFFD74422000004108014AD +:1007E000463C003F9230EA6A401104400420800AEF +:1007F00050318FFF54000FFFFE9E40210244142011 +:10080000800ADD9EFC4280C2812080E1FA40842083 +:10081000801FEA41987E2E27F1504432C668EABD17 +:1008200096493801880880834462ED9CC1043813DE +:100830000909D50484013803090984209C11450164 +:10084000683445100BB899419757387214005A70A4 +:10085000FF0F38380400385315014231C4244031A9 +:100860009476385F9E028865383F9E0A8C215A181C +:1008700008EC842080618081385F86029788E28559 +:100880008C2140333C1B4042BC1B5A1804F7E647FE +:10089000E90284003E07F15010348000FCC2FC6085 +:1008A000EE38509F8028F082F183844884208009AC +:1008B000B1CCEA41800784208448EA418400EB01FE +:1008C000F003446000C8406300D654D300FF4006E4 +:1008D00084089600F08485809431F081048F800232 +:1008E0008169814C97B1F0034CA0005FB00E501F9E +:1008F0008100F20449FFF8FC4452817844428AD8CE +:1009000040E61400888C14BF8005B04E502F810043 +:100910008066800EF487EB50F086B0675007019038 +:10092000502F81648066EB50F50602158000E205C9 +:1009300040503C1A9629E220F407E8031255800043 +:1009400050E703204CE27FE3B04E502F81008066D9 +:100950008008EB5050E40190F086B067800E502F75 +:1009600081648066EB50F406F105E20440403C1AD5 +:10097000A4489621E2208D62E8031245FFFF802DF6 +:100980008008EB433803A909802D800EEB43381310 +:10099000A901E220E8033803A909F0018D4189008B +:1009A00040C60000D5A1F00249FFF836DD453C1DE8 +:1009B000FC580220800F5A0002058403FE849691A1 +:1009C000806280298007F97B38138101100F80270E +:1009D00038248101500F802749FFFF1644138D41B1 +:1009E000A608004F802738038101EB01A6C83853C1 +:1009F000910138238D0138048D018802382491013A +:100A00008845E040E8069A825CF100C8E805D50216 +:100A10008440103F8027A608443001F494514010D0 +:100A20008C37E623E807C907441000C74010880642 +:100A3000D5028423002F80272E57F158DA072E374E +:100A4000F15188613E37F151D5033E17F1512E37F0 +:100A5000F151E663E8035A18030684003E07F1519A +:100A600080023E27F158EDC8FCE08401DD9E840041 +:100A70004412C668845FEACF8C015A0808FE8400DD +:100A80003E07F150DD9E5A0801078401AE0884003C +:100A9000AC10DD9EEB5B0200000F42420001E283DE +:100AA000E9F5A410E61EE8048C01AC10DD9E84007C +:100AB000AE08DD9EFC40812184203C1BF7B61091DE +:100AC0000000842480C2814349FFFEEB80E04402A1 +:100AD000C8C43810240081205A18010FEBC3E60265 +:100AE000E8048C013E07EF7984013E07EF9E840005 +:100AF0003C0BF66FD52E4412C70E84004422C44E20 +:100B00003C33F7B63C43F669F9152E17EF79C1046B +:100B10008E213E17EF795AA8011284608023380491 +:100B20008C00C8038C2196498C615A3804FA5A18F3 +:100B30000406EB9D8C01EAAED5038400EAAE3C13BB +:100B4000F8A74400EA5FE201E9048C213C1BF8A706 +:100B50008400EA95EBC3C0048401EA95AFF0FCC0C1 +:100B6000FC0097844060982044100640FE0CEAE6A2 +:100B70004000803C80228043EA2449FFF7E5AC3006 +:100B8000FC80FC6051FFF9B8B67F8160EA24B002B6 +:100B9000818180E2EA848440F481EB964420FFFF67 +:100BA000EA24500F8328EA84EB96DD4B8421AE4083 +:100BB00084C084013C6FFB994493F04AEA7544A0D9 +:100BC0000055EAEC44D3F4234C65804584003E078D +:100BD000EC638400EB1D84018020EB63840AEBFA54 +:100BE000EA48000680005A000404EBFAD5FB850AA7 +:100BF00085C02E07EC63E20CE825DD5C5A0807FF90 +:100C00003C8FFB643CEFFB992E07EC63B43F5A78B2 +:100C10000209F201B0C2504F832849FFF898D50B62 +:100C2000B082503F83285A78010549FFF7D3D50396 +:100C300049FFFF982E07EC638C0196003E07EC639A +:100C4000D5D9DD4B8421AE408CC1EA43EA9797B0F9 +:100C5000D5BCEAA151FF8648FCE0FC4384208448CF +:100C6000B002EA4184208448B004EA41EAA1842227 +:100C7000DD4CAE40844284018425F80C44638D42EF +:100C8000EA77EA82A6305A088F0AEA5B8401842553 +:100C90008442B0C2B104F829D5F6B042844484023B +:100CA000F85ADD453C1DFC580220800F5A00020511 +:100CB0008403FE849691B0428062B00449FFFAA694 +:100CC000F08149FFFED68402F815EAA1F001FCC3C9 +:100CD000FC0180C0EAA18421DD4CAE408401842562 +:100CE0008040B0C1504F800649FFFF4D5A68010552 +:100CF000800649FFFA59EAA1020F800249FFF92F45 +:100D0000FC81FC418400EA2A49FFFA08DD4CA60078 +:100D1000C0145A00040448000060EA603C0BF66905 +:100D20004412C70E84004422C44E3C33F7B64440FC +:100D3000005049FFFEAAD5063E07EF9EEA603C0B35 +:100D4000F669EBF9842049FFFB13DD4CA600441241 +:100D5000C6DC844149FFBC01EB56A60096424E1406 +:100D6000000F5A0888098400EA953C03F8A78C0113 +:100D7000EAE7D5058401EA958400EAE7EBF9EA841D +:100D8000DD5E49FFF862EB8F5A000103F8612E0720 +:100D9000EF6E5A000103F85C8400EB49EAD3DD42B0 +:100DA00049FFFF5DEA2AEB56A60096424E14000466 +:100DB000960FEA2ADD56EB8EEA4B8403EA9184C152 +:100DC00084003C0BF66FEAAB3E67EF9EEB32EAEC39 +:100DD0003E67EF9FF83D440000963C0BF669EB0739 +:100DE0005A0801093C3DFBE44400003140300C0648 +:100DF000D5078460C8052E37EC3840300C06441304 +:100E00008D41EBF9A648EAB549FFFE5644138D42E1 +:100E1000200080004E04001A8400EA95A608963649 +:100E2000C00F8400EAAEA60854200020C20E66203F +:100E30000020960FAE88EA2A8401EA95D506EB9D3C +:100E4000E61EE803FA0EEAAEEB8F5A0001044800F2 +:100E5000006E2E07EF6E5A08011D2E77EC2C5A7883 +:100E6000011944938D4100548000EB53D05F84C03E +:100E70003E67EF9FEAA18403DD56EB8E8069EA911D +:100E80003E67EC423E67EF653E77EF9FEB32D54E13 +:100E9000EB9DE61EE94BEB3EDD428400EAAEEAA1A3 +:100EA000DD41C008DD5C5A0807FFDD4CA60049FFA4 +:100EB000B481840149FFFF0E44238D42A650806215 +:100EC000970A4E4400089666C106440FFFC0AE1054 +:100ED000D521C82084E0AFD82E67EF72EA4BCE0E42 +:100EE0008006DD568046EA913E67EC423C6FFBE4AB +:100EF0003E77EF65EB32EAECD5198403DD56A69810 +:100F0000EA913C0DFBE4EB2BE91184013E07EC5226 +:100F1000D50DEA4B8403DD56A698EA918400EAAB2E +:100F20003E07EF658401EB49EB32EB5B0000002EDE +:100F3000C00B3C13F7B64402FE54AC403C13F65FC2 +:100F40004402FE56AC40FCC1FC00DD455A08022CB0 +:100F50003C1DFB9BEA92E220E803EA98C00C840067 +:100F60003C0BF65849FFEEC3C81E49FFF57049FF18 +:100F7000FECAD519EA815A0801064402C42049FF75 +:100F8000B2EE840184408080842A806280A2DD5594 +:100F9000DD535A08020549FFC8D9D5DB2E07EBFE01 +:100FA0005A0801D8FC80FC20DD4CA6802E17EC15D9 +:100FB0002E07EC3C2E37EC042E50117FCA058040E2 +:100FC00082018003D5048205804380A142714024C0 +:100FD0003D1C01BD422014248480452333103C0372 +:100FE0009462E280E81595A140034800A4C0A440A3 +:100FF00088D1A430FE6C4231C0249A08FE3C8C811A +:10100000400008169A189601AC309721D5E93C0C9F +:1010100001BD3C1C01BBEA20FCA044531C20442021 +:1010200003E844331DB05A08050BA528021291B8F5 +:10103000FE64401088379649AC68D50B5A08010AFF +:10104000A468024291B8FE54401090379649AC68AB +:101050008CA2DBEADD9EFC6080E0DD4C80C18182F9 +:1010600081638144009000005A780114C1038EC14D +:1010700097B0EBACA740D607EB075A0801058006EE +:1010800049FFDAD58403DD568046EA4BEA91D50D57 +:101090005A78020C5A980405840149FFFFC0840065 +:1010A000DD568046EA4BEA91840149FFE7ADDD5405 +:1010B000A60896005A0801FEDD58AE088020EB63B2 +:1010C000DD59A640C9FFA6405A1801FFDD41C016F0 +:1010D000DD5C5A0807FFEA7EEABAEA20DD4CA6008A +:1010E000C8045A980409D5055A0804064E9300040A +:1010F00049FFFF5BDD4B8421AE405A780109840033 +:101100001076000010758000EB0BD5095A780208A4 +:10111000840010060000EB1F8401EB0BFCE0FC20B8 +:101120002E67EC513C73F64EA60149FFDC3F8EC1A1 +:10113000E2E05C630001E904EBB3C00284C1800615 +:10114000FCA0FC00DD40A6415A1004058424AE41F9 +:10115000EA40840A441000B5DD43EBB3C803F80A43 +:10116000E80349FFDEC8840A441000B6DD43DD41D0 +:10117000C024DD5B8E04E60283FFE8172E07E9E05A +:101180005A08010A4410003F84088041806149FFE9 +:10119000E47FD5155A0802144400003F842680409D +:1011A000806049FFE475D50B4420003F8408842605 +:1011B000806249FFE46DD50349FFE47C441000B729 +:1011C000840ADD438405DD4AEA52EB578406DD4A92 +:1011D000840A441000B8DD43DD4B8421AE408420F6 +:1011E000840280418461808180A1DD55FC80FC41C6 +:1011F0008120EA43EA9784063C7DFB3FEA6884C18C +:10120000DD40EB7FEA40DD4CA600842649FFF06A12 +:101210008400EA66DD5997F83C7FFB3F3E67EC6F40 +:10122000AF80DD4BAF802E67EC1097B05A6801108D +:101230008026DD40DD57800949FFDB98F08184403E +:101240008402F1018066808280A2DD55FCC1FC2011 +:1012500080C0DD47DD46AE404472FEF22E07EF123D +:10126000C8198404441000F3DD43EB1A8401EB72C7 +:101270005A080103F832A6B89690C205DD4049FF2E +:101280009623D5ED840180208062808080A2DD5588 +:10129000D5E68401EA61840ADD4A2E07EF12DD4AB1 +:1012A000EA2B5A080108EADE5A080105EB4AC00297 +:1012B000EA7D2E27EF125A280313EA2B5A0801065B +:1012C000EADE5A080103EA7D8401EA2E49FFDBECDD +:1012D0008400EA618400EAC34800006B5A280409CC +:1012E000DD408421DD57EB528400EAC3D5615A28E2 +:1012F000060D800649FFFF7D84013E07EF0C840048 +:10130000EA618400EAC3D5545A280A12A63184C17E +:101310005A080A068400EBCFEAC3D54AEAF7DD4B48 +:101320003E67E9B8AF808400EAC3D5425A28092C49 +:10133000A63184E05A080A0984023E77EF9C3E7782 +:10134000EF12AE30D5355A080B14AEB1DD403E7702 +:10135000EF12EA40DD408421DD578400EA3B3E770E +:10136000EF9C49FFB7E684013E07EF4DD521840588 +:10137000DD4AEA52EB578406DD4A3E77EF128402DB +:101380008420D5115A280B1584203C1FFBE3AEB1F5 +:101390003C2DFB548401EAC73C1BF64E3E17EF126E +:1013A000AE10840280418461808180A1DD55FCA063 +:1013B000FC6180C0A601B65FF3815A080408A6301C +:1013C0005A080105840049FFDABB2E07EC6A5A0867 +:1013D000010C4402C3DAB43FF2013C3DFB4E3C4DEC +:1013E000FB4C49FF9A03EA43EB44DD41C805EA257B +:1013F000EA38EA37D566852044A2FE5044C2C53893 +:1014000044DD01B044B2FE56EA225A000121A63161 +:101410005A08041EEAB14472FE50EBA05A0010189C +:101420008401EB02A6388540EABC802780478466A9 +:1014300010A380008402DD4484024412C6C88041A7 +:101440008060DD44EA5B3EA7EDC8D52C3B0540003B +:101450003B0640204402FE54A6403E17EDCCA601B8 +:101460003E07EDCDEAB284024422C5388466DD44ED +:101470004452FE504412C5388005382034043800E8 +:1014800080004C01000D50748001E72597F8E806B4 +:1014900044000089DD428127D5B881278CA14C55B5 +:1014A000FFEDEA25FA12AE08804184028461DD4432 +:1014B0002E07EDC85A08130F44000085DD42D50AF7 +:1014C000A6085A002204AED0D5FCEA8BA6005A002A +:1014D00013F5DD564422C38EB47FF401EB7C49FF43 +:1014E0009B9B9600EAD449FF952ADD5B5A000109CF +:1014F00084E13C7FFB77DD41C8033C7FFB8DA63157 +:101500005A080812A6305A08024FEA445A00063E0A +:101510005A000906EA445A08113ED514DD455A0816 +:1015200002FBD533541000FD5A180910A6705A1842 +:10153000020D8401EA75EA449E46E622E9265A082D +:10154000112ADD41C022D5265A080A07A6308E028C +:10155000E602E829D51A5A08030CA7B05A680124F4 +:10156000800649FFE5518006EA758408D51D5A08B2 +:10157000040FA7B05A680118800649FFE5458006A8 +:10158000EA75EB933E07EC038408D50E5A0006E794 +:10159000D50A844084618402FA25808380A2DD55C7 +:1015A0008408D5028401FCE1FC0084003C0FFB961A +:1015B000DD47DD46AE403C2DFB96CA088401802005 +:1015C0008062808080A2DD55D5F7FC80FC00DD5470 +:1015D0008400AE08DD58AE088401EA318409EA3996 +:1015E0002E07EF09EA6FDD47DD46AE40EA8DA6081B +:1015F0005A0001FFDD41C00AEA25A6085A0832FF59 +:101600008407EA488401DD4AD50C49FF910AEA259E +:10161000EAB4AE08804184028461DD448402DD4A7C +:10162000FC809200FC6180C081618406A67180E22A +:101630008520DD43854944C3F04AEB97A6313E97A8 +:10164000EF4D8E03E6094EF2030944F11454EB27E3 +:10165000EA3DDD0F12005C010406700204067A0305 +:10166000D803B8042005DD412E07292AC809DD4723 +:10167000DD46AE40840944100091DD43D5295A0867 +:10168000013E04938003F847E320E9F2D537DD59A2 +:10169000A600C824DD4BA6005A080121DD535A08D4 +:1016A000021BEA815A0801064402C42049FFAF57D1 +:1016B0002E0728BF3C1DFB9B8C019401E220E8080B +:1016C00084408401842A8062808080A2DD55DD41CF +:1016D000C005D5DEDD535A0001E6DD41C80BDD59FA +:1016E000A600C8082E07EC005A000105EBCA5A00F4 +:1016F00001DA840944100092DD432E07292A5A009A +:101700000103DD5FDD41C021EB56A600C00384006C +:10171000EA3BA1FB49FFD953E2E0E805EA2B5A086E +:101720000107D51949000ED3C8FAD515EB385A0070 +:101730000113EAB3C805DD5B8E04E602E90C2E074F +:10174000EC515A000109DD5F2E17EF125A10040305 +:10175000DD5FEAC3DD47DD46AE40DD54A608C0FFCD +:10176000DD41C808DD4CA6005A08030949FFF6E62A +:10177000D50549FF8A27C0FED5F68404AE31840022 +:101780003E07EF13DD40EA4049FFDAC3DD41C00800 +:101790008406441000D5DD438404EA23D503840184 +:1017A000EA61840EDD4A84023E07EC21EB52DD5FE4 +:1017B000840B441000BADD43DD41C81F840B441084 +:1017C00000BBDD438006EB15F95E8405DD4AEB388E +:1017D0005A000105EA2B5A0801098408441000D276 +:1017E000DD4384013E07EC198404441000F1DD431D +:1017F000EB1A8006EBC5DD5F840B441000BCDD43B3 +:10180000EA22C83E8401DD4ADD5B9E44E624E914F9 +:101810005A000C13EA225A000410EA2B5A00010560 +:10182000EB385A0801063C03F7AC5A08010480065D +:10183000EB5D8400EB02EB932E57EC03D805EA2610 +:10184000EBF2EBC9F908EA43EA97DD5B8E04E602A6 +:10185000E809EA4EEA2CEA3A8400EA428400EA66A1 +:10186000EAA3EA225A000413441000D28406DD439E +:101870008404EA23DD408421DD57EB52D5075A0862 +:1018800004068401EA898400EB028400EAC7EB15B0 +:101890008006F8F9EADE5A080103DD5F8401EA2ECA +:1018A000EAB85A080103F804EA225A080404480076 +:1018B00001ADDD535A000203F804EBB34E0301A659 +:1018C000480001AB2ED7EC6F5AD8011349FFD93F1E +:1018D0008402EAC7DD4BEB9984053E97EC77DD4A3D +:1018E000DD414E02FEADDD5C5A0807FFDD5F5AD0D8 +:1018F0000203DD5F8400EA35DD41C028EA928C02F4 +:101900003C1DFB9B8C22E220E8053C1DFB7D5A1808 +:1019100001F9EA26EBF2EBC9DD404412E20449FF8B +:10192000DB6EEAB8C805DD40A601EADBF97984067A +:10193000DD4ADD46DD47AE4080C049FF8936C0FE46 +:10194000EA4FAE30DD53C0FFD52249FFBD76EAFA3B +:101950005A0803053CDFFB3FD5038401EA35DD4728 +:10196000DD46AE404493F7F1EA9880605A0801FEE4 +:101970000074800097FCCFF94412C46C804184024B +:10198000DD448006EBC53E77EF0CDD5F2E67EC5142 +:1019900084003E07EF0C5A680108DD408420DD57C3 +:1019A0003E67EC6FDD5F000580004E030131EAB851 +:1019B0004E03012EDD535A00010448000129441052 +:1019C00000D48406DD438404EA23EB52DD5FEA445D +:1019D0005A0806108400EA89EAC7EBF2EA26EBC946 +:1019E000DD45C00CEA7C0200001049FF8FB6D50629 +:1019F0005A081110DD41C0EFD50C8403DD42EAF72F +:101A0000DD588401EA2EEA79AE08840FDD4ADD5FF5 +:101A1000EA445A000903DD5FDD455A000203DD5F39 +:101A2000DD408420DD578403AE31DD5F8401DD4A73 +:101A3000DD41C8098006EB15F8268405DD4A8006DD +:101A4000EBC5DD5FEA22C8178402DD4A49FFB45EB8 +:101A50008006EB5D49FFD9F7DD4B8421AE40EA22D9 +:101A60005A00040E8409EA238403DD4ADD41C007DD +:101A7000F839D5055A0804048401EA898404DD4A4A +:101A80008006EB1549FFDB68EADE5A080103DD5FDB +:101A9000EAB885213E97EC775A000105EA225A08F8 +:101AA000040A840AEA23EAF7DD588401EA79AE08D9 +:101AB000DD5FA631EADBF8B43CA3F64EA63149FF60 +:101AC000D775E340E912840BEA238400842BA83BFA +:101AD000AE71EA66DD4B3E97EC6FEB99DD414E024D +:101AE00000BD49FFB416DD5F8409EA238405DD4AA1 +:101AF000EA52EB578406DD4ADD418020C8F38402B8 +:101B000080418461808180A1DD55DD5FDD41C802B7 +:101B1000EA79A6305A08021F10860000DD54A60894 +:101B2000C0FFA631EADBF08185A04402C3DDF101EC +:101B30004422C43849FFD8C33CDBF64E10A3000151 +:101B4000DD40EA40840010D3801CA83B3ED7EC6FF8 +:101B5000F853EA445A08070C8409AE31EAF7DD5815 +:101B60008401EA79AE08FA083C0FFB5B840010039D +:101B7000801CDD5F2E07EC6F5A080119DD40EA403A +:101B800049FFB3D4DD408429AE418420DD57DD40D8 +:101B9000842BAE4149FFFD1C8402DD58EAC7840056 +:101BA000AE08EA2E8403DD4AD5585A080257840449 +:101BB000DD4A3E97EC6FDD41C8088006EBC52E0775 +:101BC000EF4D4E03FD3DD54900058000C803EAB83E +:101BD000C0042E07E9B8C8128409EA2310A3000143 +:101BE000DD40EA40DD408421DD5784001093801CF5 +:101BF000A83B49FFB39E48FFFD23840AEA23EAF786 +:101C0000DD4B8421AE40D5298402DD4A8403EA23DA +:101C100049FFD74AD5228403DD4AA631EADB49FFD2 +:101C2000D653DD4049FFFA7DC00E8404DD4A8401AD +:101C30003E07EF0C8406EA23800649FFFADA8405A2 +:101C4000DD4AD50B441000D38406DD438404EA2327 +:101C5000DD408421DD57EB52FCE1FC40C002F9413C +:101C600044600065EA77EA82DD45C00F8EC1C60D8B +:101C7000842180418061848044004F00EAA84400B0 +:101C80000064EA2DEA5BD5F18400EB5EFCC04410F1 +:101C90000055DD46AE40EA8DA6085A0001FFDD9EE4 +:101CA000FC4080E08122EA8880C049FFFFF29E79F3 +:101CB000E62F4EF2019744F11AC438178501EA9EC7 +:101CC0004A003C001E0074002201540294001C03D0 +:101CD0001C031C031C037602AA02FE021C031C0345 +:101CE00020038404FA21DD4344000030DD42840EE9 +:101CF000EA688405EA348400EA90EAC1EA9BDD459B +:101D00005A080204AFF0D5FCDD45C00C8421440024 +:101D10005AF0804180618081EAA84400006449FF54 +:101D2000FF9E80098421DD578420840280418461E4 +:101D3000808180A1DD55F8EF8404FA22DD43840E12 +:101D4000EA688406EA348400EA9080A650030041E1 +:101D5000843FEAEED8FFD5E6FA258404DD4344004B +:101D60000031DD4284E04403F429AFC0F8738401FC +:101D70003E77EBFBEA3410730050EAF3EB5F2E275B +:101D8000EC1084812E37EC324452C4D049FFE4EE8B +:101D9000DD4CA600C806EA5E4412E890EA87D50743 +:101DA0005A080306EA5E4412E218EA8784003E07F6 +:101DB000EF9C2E17EF9F8400EA3B84013E07EC1155 +:101DC0005A100103EB888400EA75DD548402AE08E2 +:101DD000DD58AE08EA748E08E6044EF2010580096B +:101DE00049FFAB99F8988404FA23DD43EAB4DD4255 +:101DF00084013E07EBF8DD4B8442AE80EABD8E02E3 +:101E0000E603E906EB5F540080FD5A0808078400EA +:101E1000EA90EAC8DD42F87F102480002E07EF7DAB +:101E2000C8099E0BE604E90C5A100D0B5A180E0C4B +:101E3000D5035A180E06EB6C840049FFAC008408E9 +:101E4000EA68D5038409EA6884E0107300503E779D +:101E5000EC2D49FFEC16DD40EA4084043E77EC8728 +:101E6000EA9BDD4AEAC1DD455A080205EB1AAFF0EC +:101E7000D5FB4413F3D1A608EAA6AE08441FFFC35E +:101E80004403F429AE40DD45C008842144005AF0E3 +:101E9000804180618081EAA884003E07EF9C2E1774 +:101EA000EF9F8400EA3B84013E07EC115A100103C6 +:101EB000EB888400EA75840049FFE088842080096B +:101EC000DD578405DD4A44000033DD42EA445A0010 +:101ED00004045A080706440001F4EA2DD504EA6018 +:101EE00049FFCA99DD45C004840049FF8D36EB6C7B +:101EF00044000034DD42DD418020848F8402C1072C +:101F000084408020806280A2DD55F8058041806198 +:101F100080A1DD55480000688404FA24DD43842054 +:101F2000DD40DD57840AEA688403EA348400EA90DD +:101F3000DD40EA408401EB95D5568404FA2ADD435E +:101F4000840EEA688406EA3480A650030041843F88 +:101F5000EAEED8FF80098421DD5784208400846163 +:101F6000EA9080418402808380A1DD55D53CFA2B24 +:101F70008404DD43DD45DD565A08020DA6095A00EA +:101F8000031380018420DD5749FFD58E8401EA2E9A +:101F9000D50AA6095A000A0880018420DD57EAF70D +:101FA0008401EA2E00030051001300524422C3AB07 +:101FB0004432C3784442C3BE49FFF84F8400EA90DC +:101FC000D5128404FA2CDD43000300515A000105A8 +:101FD0005A08020584003E07EC518400EA90D503BC +:101FE000841BEA90FCC03C0FFC59DD9EFC6004EFB2 +:101FF000800DC80AB461A0499419944940108FF526 +:10200000EA5DEA51D5469521981C9E628C82A40017 +:1020100088238864A5C8A5989603814597FB97B344 +:102020004E070006EB1CF812FD60D503858081ACDD +:102030004E7700078007EB1CF809FD40D5038500AB +:1020400081284E6700088006EB1C490010D9FD303E +:10205000D50384C080E640050408EB1CFD50FD1349 +:10206000FD04EA73FD10FD05EA30FD50FD13FD048B +:10207000EA2FFD16EA73FD16EA73FD10FD0549000F +:10208000152D49001691021F80189201400004206E +:1020900012070000FCE0FC6380A03C03EF1EEBE0B5 +:1020A000EB8DA62CC009A62D5A001F07A62EC00432 +:1020B000A62F5A08310A000100455A0801064400BB +:1020C0000096EBE0EB8D00028009C0085A001F0764 +:1020D00000028008C0035A08310DEB6DC006B4023F +:1020E0005A080508EB87C80544000834EBE0EB8D7F +:1020F000A42CC80BEB6DC006B4025A080526EB876A +:10210000C82344000A8CD51E44401F004C02400CDA +:10211000EB6DC006B4025A080518EB87C8154400D9 +:102120000960D5105A00310644401F314C02400D61 +:10213000EB6DC006B4025A080508EB87C8054400D9 +:102140000640EBE0EB8D3C0C01834E0600BFC80857 +:102150003C0C01824440C34FE2804EF300B73C0C7C +:1021600001854E0600B3C8083C0C01844440C34FAF +:10217000E2804EF300ABA4284E0200A8A4294E0230 +:1021800000A52E07EF764E0300A1026F800A3C4D9A +:10219000FB59E2C44EF2009A026F800B3C4DFB6586 +:1021A000E2C44EF200938481AF182E3010AD3C4053 +:1021B0000302CB08C40650027FE140018006D5022D +:1021C000800481214411665880E538509101441102 +:1021D000661838109101B63F9C54F1814410006498 +:1021E000F18280C250138010502380283C3C017E35 +:1021F000F822EA453C400303C807C40850127FCFC9 +:1022000040000406D5048400D5028004441165B45E +:10221000385091014411655038109101B63F9C76B9 +:10222000F18144100066F182502380303C3C017FF4 +:102230005013801849FFFEDC0434800B0424800A0C +:102240004E360006CB3E5CF105DDE93B04A4800D73 +:1022500004B4800C4EA600074EA300345CF585DD67 +:10226000E9303C0C030B8E02E605E82B80E9A03D2B +:10227000A13C9441401093F59421EA51A07FA0BE67 +:1022800097C394491273000C941140108BF5806A27 +:10229000804BEA5122F3000296438AEF42F3800317 +:1022A00084015EF780F11003007A1213000D2203FF +:1022B0000003E8078A2042F080035EF780F1E90717 +:1022C00084001003007AD5038400AE18FCE33C0FB1 +:1022D000FC5EDD9E4402B64C3C0FFC5DDD9E3C0F77 +:1022E000FE90DD9E3C0FFE8FDD9E4402B5E43C0F68 +:1022F000FE8E500000343C0FFE8DDD9EFC2051FF11 +:10230000FD1880C0121F800380E24411683CEBDBA3 +:10231000B002DD49441168F4EBDBB030DD49441113 +:1023200069ACEBDB500F8178DD49500F82304411EE +:102330006A64EBDBDD495A6002095A60030A5A6895 +:10234000010BB0F084C0D509503F8178D505503FCE +:102350008230D502B0C284C1C722FA5D4450005A0F +:10236000848084E2EA6C381189119603E001E80365 +:10237000C607D50BEA6C9603E020E816C60698550A +:10238000EABB8082960BD5059862EABB80A2960BC9 +:10239000E005E80BE080E8098040D5E5EA6C9603AB +:1023A00038018111D502800251FF82E8FCA03C1C5B +:1023B000030B5A1802160010003C5A180112842010 +:1023C000EB8C021000181210001A021000191210E3 +:1023D000001B0210000EEBA50210000FD5252210E5 +:1023E000001AFA8322200018EBE5FA642210001B81 +:1023F00040210C561220001A22200019EBE5221071 +:10240000001040210C561220001B2220000EEBE58C +:102410002210000F40210C56122000102220001123 +:1024200042111073EB89121000110010007AC908D4 +:102430000210001AEBA50210001B12100011DD9E05 +:10244000FC01021000100220001A0230001B9A8AC0 +:102450000210001196938A2322300008964B5EF1F9 +:10246000803C90419021E8044E240008D50E5EF196 +:102470008C44E9034E26000A00400078E694E90502 +:10248000848940211056D5028440122F80002220DA +:1024900000095EF1003CE8044E140008D50E5EF120 +:1024A00013C4E9034E16000A00400078E694E905DB +:1024B000848940109036D5028420121F80013C1D73 +:1024C000FB655CF08708E8068420121F8000121F5D +:1024D000800104100011EAFDEAC6FF4E441100001D +:1024E000D1203C1C04313C67FCBFE6263C57FCBEB7 +:1024F000E906126F8000125F8001D513EAB9848764 +:10250000964B421310739023964B121F8000021FAC +:102510008001964B421290739023964B121F8001BC +:10252000EAB9964B4031842196DB123F8002021FAC +:102530008001964B402104219693122F8003021FA5 +:1025400080021210000A021F80031210000BEB0E13 +:102550003C0BFCBFEAEF3C0BFCBEFC81FC41F48170 +:10256000411200114102400A0040005A22608000DE +:102570009724EB6F8641C4073C6BF9363C1BF93559 +:10258000EB06D518B4805A48031A3C7DFC983C4DA4 +:10259000FC9988272E77F26888C48CE197F8E6EFDB +:1025A000EB06EB753E77F268E94640631CD6EB0616 +:1025B000EABBEB753F27F268D53E5A48013B3C7DAC +:1025C000FE8E3D37F936A7383D27F9355A48016563 +:1025D0004049980142F200030293800440490401FB +:1025E00042420003888F40948408E324E855029314 +:1025F000800340748408E1E7E803E0C7E8613CAD8C +:10260000FE8F024500098E818A899521E093E803B7 +:10261000E086E856E1C7E803E027E8520275000AC1 +:102620008EE18AE995F9E0F2E837E0E1E849D5344E +:10263000EB06EB755A58012AB4005A0801273C1DD5 +:10264000FE8EA40DE260E8213C0DFC993C4DFC9807 +:102650004030440142F18003A54E40324001EB4D31 +:10266000886F9569E065E811A4CF9F594202C47351 +:102670004242C073401184098801882440000C162E +:10268000EB893C0FFC99EB753C0DFC99AC103C0DB3 +:10269000FC98AC11FCC13C7DFC983C4DFC99882712 +:1026A0002E77F26888C48CE197F840631CD63E7799 +:1026B000F26840709CF6EB063C7FFC98D5BC3D3F31 +:1026C000FC993D2FFC98D5B7FC2004600011EAFD71 +:1026D000EAC6FF764461000022708000224080013B +:1026E0003C3DFC963C1DFC97D604B4005A08010AF8 +:1026F00084003C7FFC973C4FFC963C0FFC95D53BFF +:10270000978B975B41139801410214013C1DFE8D8C +:10271000420880034238000388600200800E3C3F7C +:10272000FC95E060E8240010801E80E09F09427262 +:102730000C73FE0C80674213C4244040040A4F15FA +:1027400000048824D5028A244010803688263C1F45 +:10275000FC974211C0244F0500048824D5028A2426 +:102760004000801688053C0FFC96D5053C7FFC9701 +:102770003C4FFC963C0DFC97AC103C0DFC96AC110C +:10278000FCA0FC2022608000225080013C7DFE8E57 +:102790002E1010AD3D27F9283D07F9260243800E83 +:1027A000C10E3C3DFB65842A4031847704138009C7 +:1027B00096D9EB890433800AFE5CD51150137FEC67 +:1027C00096495CF08C58E80A5012FFEC96495CF090 +:1027D00093D8E8040013801ED502EA7BB4005A089F +:1027E000010A84003C6FFC943C5FFC933C0FFC921C +:1027F000D532411348014072C00142088003423380 +:10280000800388609521E0643C3FFC92E8209E09AB +:1028100080A442500C73FE6480654202C424404090 +:10282000840A4F1500048804D5028A04EB2188121B +:102830003C0FFC9442019C244E7500048804D50290 +:102840008A04EAFF88303C1FFC93D5053C6FFC945A +:102850003C5FFC933C0DFC94AC103C0DFC93AC1124 +:10286000FCA0FC203C6DFE8EEB9100730010230059 +:102870008001CF0284E12E1010ADC1113C1DFB651B +:10288000848A401090370443000996494012043767 +:102890000443000AFF0C3C4FFC8BD50602130009D1 +:1028A00094493C1FFC8BB4205A18011384003E0746 +:1028B000F21C3E07F21A020300093C3BF914940192 +:1028C0003D0BF9133E17F22A3C0FFC8BD5553D17F3 +:1028D000F9133D37F9144048C00140098C01FF2429 +:1028E000424000733C0DFC8B4522C98CE2802E5780 +:1028F000F22A8400E9028401380914089E39D808B4 +:1029000084003E07F22A84013E07F21AD5048CA106 +:102910003E57F22A2E17F21AC90C2E47F22A8001CE +:10292000E204E83138590000CD028C218C01D5F940 +:1029300084808004E207E80738590000CD028C81CA +:102940008C01D5F95A180109E087E8060203000A4C +:1029500094013C0FFC8B9A7CFECC42324C734210AB +:10296000C0244212447340319C763C3BF914400031 +:102970009C163C0BF9133C03F914AC103C03F913FF +:10298000AC11FCA09B7C8A8188A1FEE44232CC730E +:10299000420240244202C47340319C763C3BF9140D +:1029A00040001C16D5E7FC20225080002240800108 +:1029B0002E1010AD3C3DFE8EC10500618022FA2430 +:1029C000D5165012FFCE96495CF08C1CE8075012C9 +:1029D0007FCE96495CF0939CE906021180108C230F +:1029E0009648D5030011802000618022B4005A0867 +:1029F00001073C5BF90C3C4BF90BD52D3C37F90B2F +:102A00003C07F90C8A648A05FEDC423000739409A5 +:102A1000FE042E77F215E2605A78010DE91E84005B +:102A20003E07F2153C5BF90C3C4BF90B3E07F214E8 +:102A3000D514E8082E07F214E206E8048C013E07DC +:102A4000F2142E07F2143C5BF90CE2063C4BF90B36 +:102A5000E90484013E07F2153C03F90CAC103C0379 +:102A6000F90BAC11FCA0FC00B480EB91EB6F5A4069 +:102A70000503CC0AFA0E3C0FFC84841F3C0BF907BB +:102A80003C0BF906D5375A48011600000045C80628 +:102A90003C0DFC84C80A8405D502FA0E3C0FFC8468 +:102AA0003C3BF9073C1BF9063C37F9073C17F90694 +:102AB000D5213C4DFC84C4048E813C4FFC843C4DAC +:102AC000FC84C418000000455A0801063C3BF90785 +:102AD0003C1BF9063C57F9063C47F9079A299BA38A +:102AE000FE04420318735EF003E84012BC1B403240 +:102AF0003C1BACD0AC51FC80FC403C9DFE8D224088 +:102B00008000005480162230000822700009EB6F0C +:102B10008621C506E6A98628E803411280130054E1 +:102B200080178601C506E6A98608E80341028013DE +:102B3000B5405AA0010A04000011EAFDEAC6FF46AA +:102B400044010000D81784003C0FFC823C0FFC813C +:102B500084013D1FFC803D1FFC7F3C3BF8EE3C7B2D +:102B6000F8EF3C4BF8DE3C1BF8DF3C0FFC6E4800F6 +:102B700000B15AA80304480000AB3C0DFC6E51287C +:102B80007FFF8C01420040013C0FFC6E3C0DFC813C +:102B9000E012E8038C01D50284003C0FFC813C0D5F +:102BA000FC823C5DFC81C8064C59400584013C0F09 +:102BB000FC824462C94C942A41330000127980019E +:102BC0004532C92C3849960988133C4DFC8038336E +:102BD0001609AC413C4FFC7F4E5700099E693803F3 +:102BE0000611406304409AC3D50638034A11406376 +:102BF00048409AC322130001420180038A274210F1 +:102C000080030264800D8801E2C08026E906021478 +:102C1000800CE20140103C1A3C0DFC82C8043D1FB0 +:102C2000FC80D5105AA0040F0204800C40384401E7 +:102C30008A20FE5C9A3040008017400800013C0F5B +:102C4000FC803C0DFC8084238064423080738424AB +:102C500080038C02EB21E080E9043C0FFC80D5046A +:102C60008C813C4FFC803C0DFC80E011E8043D1F52 +:102C7000FC80D505E180E8033D0FFC803C0DFC6E37 +:102C80003C1DFC80E001E8033C0FFC8084203C0DEF +:102C9000FC8080C180814C100010383996118883E7 +:102CA000403994402231800188C3C5038EA1D502EA +:102CB00080B28C21D5F1846240008C168880880611 +:102CC00040420496EAFF9723964BD50384208081E7 +:102CD000AD10AC51FCC0FC6B80C0EAFD04000011DB +:102CE000EAC6FF4644010000D804841F3C0FFA7A6C +:102CF0003C1DFE8D3C0DFA7AA44DE201E8048C01E6 +:102D00003C0FFA7AB4064E02014F5A0805044800F7 +:102D1000014B2E000154C00C2E000156C0092E009C +:102D200001555A001F062E0001575A08310A0003A8 +:102D30000045C8060003005A96044E02013B0213E8 +:102D400000180203000E449000648A019603EB749D +:102D5000021300190203000F85418A019603EBD587 +:102D6000EB0E96039001EB74EAEF96039001EBD51E +:102D7000EAB9960BEAB9023F8001964B022F800117 +:102D8000FE44421188738403964B8441F82F80E0FF +:102D9000420024244410005AEAFF97F9FFFC964BA6 +:102DA00084418400F82352139FA410030078964BAB +:102DB00084418403F81BEAB942B02800964B4210C4 +:102DC00080034210A424804A4010AC368402964B03 +:102DD000F80D023F800180E096DBEB4D4231A424E8 +:102DE00084024011AC36804A964B49FFFA89EAB911 +:102DF000964B4E160005FE7A974BD50280A7021F10 +:102E0000800112530012964B4E160004FE029603E8 +:102E100044416B1C8044B0C23B01480480233B000A +:102E2000C824120300130291000044216B2C12905D +:102E300080008262B0463B09C80480E13B03C8249D +:102E40000339800013338000B1CA3B0248048087F5 +:102E50003B02482412920000509F80383B014804F6 +:102E600080493B01482413310000513F80484421F0 +:102E70006B3C3B01480480933B024824A490ACA0E7 +:102E8000002300785CF10028E9595CF10032E80485 +:102E900044400064D5034440006D4302800342A0D7 +:102EA000000340282801969342210003969386212F +:102EB0003929C511E1C2E8058DA141188013D5F962 +:102EC000864D431944015128FFFFE1504129001369 +:102ED000E9038209D50380E182033899C9113818C2 +:102EE00049118A4996D13829C51141312401382820 +:102EF00045113903C9118A41FE9C969340214C56D5 +:102F000088413813C51196938A30FECCFEA4965B97 +:102F10004030CC76887096DBFF1C44700064402102 +:102F20001C5640421C9642128824FE24EABB4000F4 +:102F30001C161213001212030013EB0E96035EF020 +:102F40000051E903EA60EB74EB0E96035EF07FB08C +:102F5000E804440FFFB0EB74EAEF96035EF0005113 +:102F6000E903EA60EBD5EAEF96035EF07FB0E80490 +:102F7000440FFFB0EBD502030012B041EAD80203C0 +:102F800000138041EA5C800649FFFDB8B04180062D +:102F9000804149FFFB9B020F800212030014EA6C80 +:102FA00012030015B4065A08050584003C0FFA7A8E +:102FB000FCEBFC403D2DFE8EEB9100690016EB6FA3 +:102FC000C605E6C9E80597B1D50484C1D50284C811 +:102FD00000490017C405E689E8059721D5048481D6 +:102FE000D5028488B5E084A05B3801123C5FFC6D9B +:102FF0003C5FFC6C3C6FFC6B3C6FFC6A3C3BF8C478 +:103000003C1BF8C53D3FFC61480000AE5B38030443 +:10301000480000A83C0DFC6151027FFF8C0142007A +:1030200010013C0FFC613C0DFC6CE010E8058C01CC +:103030003C0FFC6CD5033C5FFC6C3C0DFC6D3C5DB7 +:10304000FC6CC8064C58400584013C0FFC6D447272 +:10305000C8F8400394403D1DFC6B38339609AC41E1 +:103060003D1FFC6A4E57000C5092FFFF3803A6111B +:103070004093A4409AC322048001D5083803C211AA +:103080009AC34003C040220000019A41EB4D421018 +:10309000800388230239000D94D9E2618003E90797 +:1030A0000209000C9401E2204000BC1A3C1DFC6D9A +:1030B000C9043C6FFC6BD5105B30040F0219000C87 +:1030C000412084088A129A66FE0C8A7240000C170E +:1030D0009A203C0FFC6B3C0DFC6B842380714230CA +:1030E0008073842480038C02EB21E1A0E9043C0F6F +:1030F000FC6BD5048DA13D1FFC6B3C0DFC6BE00609 +:10310000E8043C6FFC6BD505E080E8033C4FFC6BAA +:103110003C0DFC613C1DFC6BE001E8033C0FFC6BCB +:1031200084203C0DFC6B80C180814C100010383332 +:1031300096118883403394402231800188C3C503AF +:103140008EA1D50280B08C21D5F1846240008C160E +:1031500098E0880640318476EAFF96DB964BD503EB +:1031600080258065ACD0AC51FCC0FC40B480EB91B4 +:10317000227080013C1DFE8E5A480113ACD0ADD1A7 +:10318000A60D3C3BF8C03C7BF8C15A000104480046 +:1031900000CD84003C0BF8BE3C0BF8BFFCC0A78DF3 +:1031A0000100005A5A68013554080002C0313C47FA +:1031B000F8BE3C07F8BFCC05C02B3C37F8C0D5287B +:1031C0003C17F8C1C80380E1D523FF62FF0C3C1710 +:1031D000F8C08243424004754232942442100024D5 +:1031E0004330142441108C004231C82442399C756C +:1031F00042301075FE02FE2CFE7C421048734212D3 +:1032000090754031C4764010C43696DB97CB540895 +:103210000002C06E5EF18C80E9093C57F8C05EF296 +:103220008C80E80F44500C7FD50C4E3400083C577E +:10323000F8C04E55000784A0D50480A38400D502B1 +:1032400084015EF39400E9073C47F8C15EF2140084 +:10325000E962D50C4E7400083C07F8C184804240F6 +:103260001001D5045A08014580873D17F8C03D0775 +:10327000F8C140F1C401802380074123C001E80B5D +:1032800084024092C401400780164204C873400083 +:103290003C1688104F22000C8422409240014019B5 +:1032A00004364214BC734010C83688314C48003A8A +:1032B0005EF08C80E9045100F381D5054E14003294 +:1032C000530080004C58800E5EF01400E904511049 +:1032D0006C01D5054E04002353100000E1B0E80452 +:1032E00096EB97C3D505E191E80396CB97E35A682F +:1032F000010C3C03F8C09A183C0BF8BE3C03F8C123 +:103300009A383C0BF8BF3C3BF8C03C7BF8C1ACD0D2 +:10331000ADD1FCC0444013FFD5A94F02FFEAD5E16F +:1033200086004C58FFD3D5E4FCC0FC2180C0EAFDE8 +:1033300004000011EAC6FF4644010000D8098400D9 +:103340003C0BFCC03C0BFCC1841F3C0FFA793C7D5C +:10335000FE8E3C0DFA79A47DE201E8048C013C0F5D +:10336000FA79B406C06D5A00056C0203000AB04138 +:10337000EAD80203000B8041EA5C800649FFFB7536 +:10338000B041800680413C3DFA793C4DFE60A77912 +:1033900049FFF8E6A63AC006B0418006804149FFE1 +:1033A000FA62A63BC006B0418006804149FFFE0399 +:1033B000A63CC006B0418006804149FFF9E4EB4ECF +:1033C0005A00010A2E07EC3E5A0001062E07EBFFB9 +:1033D0005A080107B0418006804149FFFAE6000320 +:1033E000005A960EC0070203000AEAD80203000B37 +:1033F000EA5CB0418006804149FFFEB9220F80029D +:103400004E0400048400EAD822FF80025EF78C801C +:10341000E90444000C7FEAD8220F80034E04000424 +:103420008400EA5C22FF80035EF79400E904440014 +:1034300013FFEA5C020F8002AC36EA6CAC37B406CC +:103440005A08050BA4363C0BFCC0A4373C0BFCC14E +:1034500084003C0FFA79FCA13C0FFECBDD9E3C0FB3 +:10346000FECADD9E4402D24884213C0FFE9F8400A8 +:103470003E07FA803E07FA813E07FA823E07FA834A +:103480003E07FA843E07FA853E07FA863E07FA4968 +:103490003E07FA483E07FA4A3C1FFA7C3E07EDB366 +:1034A0004412D1F88400845FEACF8C015A084FFEA1 +:1034B000DD9EFC00EA88FC80FC0080C049FF9FB7CD +:1034C000C0048400AE34AE35FC802E07FA50DD9E79 +:1034D0002E07FA44DD9E4432D1B8AE18AE59AE9AEA +:1034E000DD9E3C0FFA7CDD9E3C0DFA7CDD9E3C0DA2 +:1034F000FB6C465FF00FEAC6FF4646001000D80698 +:1035000084003E07EDB38401DD9E8400DD9E2E170E +:10351000FA822E57FA83EB344C12C0102E27FA8011 +:103520005A28010CA6059D49400280B697683E576F +:10353000FA823E57FA83DD9EA6058CA1400280B632 +:1035400097683E57FA83D90484013E07FA80DD9ECE +:103550002E57FA822E17FA83D9042E07FA80C00F4D +:10356000EB348CA1A605400280B697683E57FA82DC +:103570004C12C00584003E07FA808401DD9E2E5760 +:10358000FA822E07FA83D8082E07FA8084208E014B +:1035900040008006DD9E8401DD9E2E57FA822E07B4 +:1035A000FA83D8072E17FA80840040000406DD9EB7 +:1035B0008401DD9EFC0084A08C81E2A4E8073860D1 +:1035C000080438608C0C8CA1D5F9FC80FC613CAD02 +:1035D000FA7C84BF81608121B4C1105F80075AA04A +:1035E00001044800009B84E03C3DFECA2F17FA44CA +:1035F0003D2C041A3D3DFECB802A44C0004C81A7DF +:1036000081C7850686029E89000180099690E24066 +:10361000E81243413024B40B41505000B4159E8150 +:10362000E642E9035A08047604058003B4009E814B +:10363000E642E808841F1003003E1003003F4800E4 +:1036400000865A0004F9DD535A0802052E0010DFE7 +:10365000C8F25B1801045B2005EF00098003222AF1 +:103660008004224A80050371800203618003C01731 +:1036700002018009518BFFFF8E0140F041F642F1BB +:103680006073518B7FFF402780560201800A8E01B4 +:1036900040F041F642F2607340478096E057E903FC +:1036A000502BFFFFE09642013400E903504B7FFFAF +:1036B00081E642F3A0738442402104644242380010 +:1036C000102780004020100A102780014022100A95 +:1036D00010278002971F40420084020A800A104788 +:1036E0008003C006B44B885400010014D502840145 +:1036F00010078004020A800BC0039600D5028401E3 +:103700008CE11007800597F81053003C1053003DE2 +:103710008C21964848FFFF792E77FA48C7172E0765 +:10372000FA495A001913E61EA670E805965740009C +:103730008064D503440000F0AE302E07FA4AAE3262 +:103740008401AFF13E07FA5084E02E07FA505A0088 +:10375000FF0DC00BCF0A841F3E07FA503C0DFE93AD +:103760008C013C0FFE93D5033E77FA505AA8011501 +:103770003C0DFECA00400009E2E4E80E84268406FF +:10378000FE7C8A87B449FF0496488822EB54844023 +:10379000806A8E81F946B409842080A050200040C0 +:1037A0000832800188239648DAFCFE4A1010004057 +:1037B0005AA00104480000CC04058003B4209E896F +:1037C000E642E9055A100404480000B92230000618 +:1037D000221000075EF18C80E805844042318800A9 +:1037E000D50344300C7F5EF09400E805844042101D +:1037F0008800D503441013FF000000725A00010432 +:103800008401D503440000F0EAD7042580035A0858 +:10381000F02E840010010072041580034420FF0084 +:103820000400801404308015401008029228101300 +:103830000042401060091013004446100FF01003BE +:103840000043FE0E9210FE9EFE5E1003004592485D +:103850004001E00992301023004610330047100366 +:103860000048101300498489D55F4001A00A100365 +:1038700000424000A00A103300431003004410131C +:10388000004500010043C80702010025C8090201E4 +:103890000026D5045A080105840012010025020102 +:1038A00000253C3DFECB40102009101300461003BC +:1038B0000047A618C00602010014FE029603D503B5 +:1038C00022010014A659C10602110015FE4A964BAA +:1038D000D50322110015A6DACB06100300481013F9 +:1038E0000049D50510130048100300498400100357 +:1038F000004A000100431003004B84001003004CF9 +:10390000000100415A0001085A0002085A08030940 +:10391000EA4ED507FA10D50544000040D502FA005A +:103920001003004D848DB449501200418822EB549D +:10393000844084615242000DD518B429EB545010D4 +:10394000804184408461848DF86CD5125AA803119B +:103950002E07FA495A0819F3EAD7B429EB54501044 +:10396000804284408461848CF85C8401D5028400A8 +:10397000B4498420505100415031004E084280012A +:1039800088249648DBFCFE4A1011004E2E17FA449C +:103990005A10FF0AC108C807841F3E07FA44CF0720 +:1039A0008401D5063E07FA44CF02C0FB84003E07DF +:1039B000FA86FCE1FC00844180624440004EF8310C +:1039C000FC80A60092038C1596275C000014DD9EF7 +:1039D000FC4080E084003E07FA85A63880C1C80418 +:1039E00000038008C0322E07FA815A08010D2E17F5 +:1039F000FA843E17FA823E17FA8384203E17FA8033 +:103A00003E07FA8549FFFD85EB342E97FA83A7041C +:103A10003C1DFE9F8441A0394214907380628E81C8 +:103A200049FFFDCA2E07FA865A0801063E07FA81A9 +:103A30003E97FA842E07FA455A00FF058C013E078F +:103A4000FA458401EB18D5033E07FA452E17FA858F +:103A5000B4065A18012BA605C814F836C80DEB3465 +:103A60002E37FA84A684B4263C0DFE9F420188734B +:103A7000B421F83AD50849FF9CABF826C8FFD5F029 +:103A8000F823C802F846B42684003E07FA853E07AC +:103A9000FA818401AE0DB426AE0CB4C6B406F83477 +:103AA0005A08013DAE37D53AA644C904F868C03675 +:103AB000D50BA6055A080106F807C830F82AD52EF6 +:103AC00049FFFD5FC8FA49FF9CB680E0C82749FF5F +:103AD000FD41EB342E97FA82A684B4263C0DFE9F5E +:103AE000B4214204887349FFFF672E17FA815A18E0 +:103AF00001112E57FA844C54C00DB4063E77FA815A +:103B0000AE45B4E6B40749FFFF5E5A080103AE3F75 +:103B100049FF9CA1B4068421AE44FCC0FC20804037 +:103B200080E14402D1D8A051B6202E17FA50EBCE36 +:103B3000A052A841A053A8432E17FA444462D1F8DA +:103B4000101000104412D1D43C6FFE9949FFFD4083 +:103B50004402D1C82E17FA50AE402E17FA44EBCECD +:103B6000B4273C1FFE954412D1C4A98149FFFF32FE +:103B700084204402D1B8AE40AE41AE4249FFFD0FB1 +:103B8000FCA03C0FFF86DD9E3C0FFF85DD9E840080 +:103B90003E07FE10DD9E4402B5B03C0FFF83DD9E64 +:103BA000FC67006080092300000223100003C61098 +:103BB0003C5DFF85A6EA8E614C61800B0030800879 +:103BC000C307A7AB8EC1FF9D5C630001D50284C112 +:103BD00084603E37FB5AEAFD04300011EAC6FF5EFE +:103BE000447100004432D2A0DF0D84A53C5FFED5B5 +:103BF00084A03C5BFDA43C5BFDA53C5BFDA23C5B63 +:103C0000FDA33C5DFED5C231C50485605A58050947 +:103C10003C7DFF8385610073801C3E77FB583C77B9 +:103C2000FDA441281C013C77FDA540789C01FFFCC8 +:103C3000427948735A500307C5055A500504480095 +:103C400000873C4DFF8302520011A508E2A42E47D5 +:103C5000FB58E807A449E2A1E804C4038E81972039 +:103C600084A3CC7684A1D5749E69E622E8053C1D28 +:103C7000FF83A649D5095A5803043E27FB582E173F +:103C8000FB58C1048E213E17FB582E47FB585A485B +:103C9000010684243E17FB5AD5038425C4028424DC +:103CA0003C1FFED580C3803F3B036404EA863B0390 +:103CB0004C003B00CC203C7DFECC3CADFECD3C9D81 +:103CC000FECE3C87FDA280B93CC7FDA33D07FDA405 +:103CD0003D17FDA52EB7FB5A2E67FB658420B62045 +:103CE0005A50051EB6FFEBD1149F8002128F800A36 +:103CF00012CF800B130F800C131F800DF589104F0E +:103D0000802810BF802A106F8035803F3B00E4047C +:103D10003B01E4243B00CC003B01CC203E27FE08C5 +:103D2000B6A010B0005A1280000412C00005147032 +:103D3000001714A00018149000191420001A5A58E3 +:103D4000010B1280001C12C0001DD50584A28191B8 +:103D50008110D5C5FCE73C0FFFCEDD9E3C0FFFCDAB +:103D6000DD9E4402B5D83C0FFFCCDD9EFC40B44044 +:103D70004E2200FA0070005A96FCC30E84213E17B2 +:103D8000FE4002100008020000093C1BFF1E3C0B15 +:103D9000FF1F480000E95A200404480000AD2E2708 +:103DA000EF764E2300E12E37FE403C2FFF8E3C2F56 +:103DB000FF8DCB412E27FE312E57FE304462D59425 +:103DC0005A20010580438083D5218083804355029A +:103DD00000FF4D02C0048602D5028601391312117C +:103DE0004238447341131040231880018C814228CB +:103DF00044735A4803EE8484403190764021105633 +:103E00003C3FFF8E3C2FFF8DD51639031211887071 +:103E1000410310408C81230800019720E2A48850C0 +:103E2000E8F58CA140319476405114B63C3FFF8EAA +:103E30003C5FFF8D3C5DFFCC3C4DFF8E3D2DFF8DEB +:103E4000A0E942F2000342290003884F94D9E262BC +:103E50004EF2008A3D33FF1EA6E850F9FF105CF7D2 +:103E60008AA0E90294D93D03FF1FA6A950F87F104C +:103E70005CF79220E90294915463800400928002DE +:103E800001128003C60FFF1C4219082440422496E9 +:103E90004010C436403990003C3BFF1E40280400CF +:103EA000D51B8E2184C2406098D640549800405261 +:103EB00084B688D140130436425194014211040162 +:103EC000FF2C42190424403224764020C4568873C3 +:103ED0003C3BFF1E88503C13FF1E3C2BFF1F121063 +:103EE0000008587380023C13FF1F12100009107065 +:103EF000005AD5395A2005382E17FE405A180109A4 +:103F00003E37FE313E37FE303E37FE40D5152E1788 +:103F1000FE30E622E8058C213E17FE30D5033E3701 +:103F2000FE302E17FE31C9082E17FE305A18020532 +:103F300084213E17FE31223000083C23FF1E2E173D +:103F4000FE304442D5949A9A38220609222000096C +:103F50003C03FF1F401204409A10AC093C3BFF1E7B +:103F60003C2BFF1FFCC0FC0000100043101000445D +:103F700000100045101000433C1C042B46000FFFAE +:103F800050000F00FE0E5A090009841F3E07FE2351 +:103F90003E07FE223E07E9F4EAA45A08015CEA451E +:103FA0005A0801313C04083A50107ED496495CF01E +:103FB0008A28E8083C10083B50F0FED45CF791A832 +:103FC000E96E84403C14083B5EF0012C3E27FE2342 +:103FD0003C0BFF103C1BFF0EE8043E27E9F4D55FC5 +:103FE0005EF00B548401E8055EF0812CE805840244 +:103FF0003E07E9F4D5545EF092D48403E8FA841FB6 +:10400000D5F82E07E9F4C0035A0801093C04083A20 +:104010002E27FE234412D590D50B5A0002045A08CD +:10402000033F3C04083B2E27FE234412D58C38F076 +:1040300089118A0FEB4296015CF00065E9302E078A +:10404000FE235A00FF2D3E07FE2284003E07FE237A +:10405000D51A5A080225EA455A08010E84003E077F +:10406000FE233C00083A3C0BFF103C00083B3C0B95 +:10407000FF0ED5152E07FE225A00FF1284203E1790 +:10408000FE23C00A3C03FF103C08083A3C03FF0E25 +:104090003C08083BD504841F3E07FE22FC803C0FF1 +:1040A000FFD0DD9E3C0FFFCFDD9EFC00C0045A0018 +:1040B0000108FC8049FFD08A3C0FFFD1FC8049FFFA +:1040C000D08E3C0FFFD2FC808020E6093C0DFFD251 +:1040D000E82344F13EDCEBC8EA9EDD0F0A3C1016F3 +:1040E0001C22282E34003C0DFFD1DD9E500000F034 +:1040F000DD9E500001E0DD9E500002D0DD9E5000AC +:1041000003C0DD9E500005A0DD9E50000780DD9EAF +:1041100050000960DD9E8400DD9E9200FC4080C25C +:1041200080E13C2DFFD23C1DFFD18123814449FF1A +:10413000D0243C1DFFCFA60AA64B49FFD03EEA4E35 +:104140004203000149FFD05884C03C1DFFD000004D +:104150008010E2C0E81080063810980049FFD05A5D +:104160003C0DFFD0984600108008800649FFD078AB +:104170008CC1D5EC8400F80BF80C8401F808F80920 +:104180005AA801058402F803F804840349FFD038D3 +:1041900049FFD00549FFD02CEA3484818400001403 +:1041A0008000E201E82BA07938508101D025A07D64 +:1041B0009482956A98CA8825A6DAA78AE266E802F8 +:1041C000AECAA07D98CA8825A6DBA78BE2C3E80209 +:1041D000AECBA07D383088008825A788E266E8024B +:1041E000AEC8A0FD884388A3A651A6A9E241E80273 +:1041F000AE693E47EF5C8C01D5D3FCC0FC62464CF7 +:1042000001208881446308FFE2C4804080A14030DF +:10421000C0094EF30082C8054603FF004C5001213F +:10422000808280A1FD028440463BFF00EA2FFD1002 +:10423000FD30EA30FD60FD10F8EE44216B98FD5032 +:10424000EA5DF8E944216B90F8F544216BA0FD404C +:10425000EA5DFD06EA30F8D444216BB0EA5DFD402A +:10426000F8DA44216BA8F8E644216BB8F8DBFD06C8 +:10427000EA303A4F9400FD10FD02EA2F44216BC84A +:10428000F8C744216BC0F8D644216BD0F8CBFD06AB +:10429000EA30F8D544216BD8FD60EA5DF8CEFD1018 +:1042A000FD06EA2FF8C9F8D0EA2FF8C6F8A9F8C435 +:1042B000F082F183844046341A00F8ADFD50F80BCB +:1042C000FD15EA73FD10FD50EA3044216B88EA5D6C +:1042D000EA30FD40FD10FD03EA2FFD60FD10FD03F7 +:1042E000EA73FD14EA2FFD40FD15FD03EA73FD108E +:1042F00044016B883A000400EA303A0F8420FD1331 +:10430000FD05EA2F3B0FC400FD10FD08EA30F878E8 +:10431000F89B480000A250F1FFF044607FDFE2CF3D +:10432000E8289509404203F540420024CC05840169 +:10433000490000A6F813C8054607FF004C5000943A +:104340004001BC098082C8065451FFF044007FF050 +:10435000D80780A1FD02490000A84800008680A17E +:10436000FD02844046343300EA30465FCC0088A129 +:10437000469C01A089254064B40997B74014D00930 +:1043800044716B504043988040228681043202255C +:1043900040A39880802204220224EA730425022686 +:1043A00004350227EA730425002404350025EA3089 +:1043B000FD304004D00AEB1C44216B50F833EA3046 +:1043C0000425002604350027EA2FFD13FD40EA2FBF +:1043D000FD60FD13F820FD50FD16FD04EA73FD138A +:1043E000EA2F3A4F940044216B58FD40EA5DFD02EC +:1043F000EA30F80644216B60FD40EA5DF81EFD10CE +:10440000FD04EA2FFD40FD15F80644216B70EA5DBE +:10441000F082F183FD03EA3044216B68F80B4421FC +:104420006B80EA5D3A0F842083FF4E00FFF5442144 +:104430006B78EA5DEA2FFD10FD05EA303B0FC40002 +:10444000FD10FD08EA2FF402F503FD10FD0283FFC5 +:10445000EA30FD10FD04EA2FFD16EA2FD505840091 +:104460008020D5028002FD10FD01FCE2FC40FD3001 +:10447000812249000503B720FD03FCC0FC01C805EB +:1044800084004613FF00D5048400461BFF00B61FBE +:104490008440F181B41F8062F1014900031FFA5288 +:1044A00049FFFFE6FC81FC60FD10FD50EA73FD1042 +:1044B00049000314FD30FD054900000AC006FD0354 +:1044C000FA5149FFFFD5FCE0FD03FCE0C10446586A +:1044D0000000D904C8038402DD9E465FFF00464702 +:1044E000FE009F2198CDE283E8064657FF0098CD55 +:1044F000E283E9038404DD9E464001009F21E281BE +:10450000E8064658000098CDE283E9038403DD9E67 +:104510004657FF00D104465FFF00D902C003840064 +:10452000DD9E8401DD9E92003A6F98BC40608C0352 +:1045300090DF4E340006FEDAC203FE929ED94E147E +:104540000006FE4AC003FE029E4984804900003AEC +:10455000C60840408004C405FE4AC003FE029E49CE +:104560003A6F9884DD9E9200414140099741921034 +:104570004040D03796D14010C008FE4742020C247C +:10458000E220E8099F21984AE222E905E220E803B7 +:104590009F21984A9A484010D01740004008FE2FAB +:1045A000FECCE203E80998029E49E202E905E20333 +:1045B000E80398029E499A0340424008FE67DD9E48 +:1045C0003BFFFEBCFD80FD918384CB4DE3B2E81937 +:1045D0004209000782A0C00D4129000C5250002062 +:1045E0004058140D4118800C411894044108000CE7 +:1045F000FD08805249FFFFBA82C1820086E0D523C0 +:10460000C2284209000782A0C8048BB286E1D514F3 +:1046100052F000204129000C805240483C0D405887 +:10462000800C4108000C400290044018BC0D49FF6A +:10463000FF9D82E18220FD08805249FFFF9782C1E1 +:10464000510000004FC2005386204108540DD54B45 +:1046500041194A17842084004FC2004CB79C151E94 +:104660000001D547E3B3E9F74209800782A0C044BF +:10467000524000204059100D4029800CFEAF82624C +:104680004129000C4038100D4108000C4008800CF6 +:104690004018900DFE1F49FFFF6982C18220420031 +:1046A000C869E3A1E9054C18C00CE380E809516B27 +:1046B0007FFF8A3340304801E2038A2F800386E07F +:1046C0004FC200154008000140188401E3808A2F82 +:1046D000524A80204110900C4100540D410844047E +:1046E0004110D40DB79C151E00018016501B800090 +:1046F0003BFFFE84DD9EE3F1E903E392E90986C115 +:10470000404848018BB3E3848BAF8204D50286C056 +:1047100086E04FC3FFE9D5EA4231FC0A95093A6FBA +:10472000A8BC959947E80000E286E9054C4340099A +:10473000E202E806FD40FD01FD1495099599FECDC4 +:104740004031F8024072540940A3540940922808AD +:1047500040832808445007FF4C5380C440F20004B3 +:104760004EF200BC40F308044EF200924063A801F0 +:104770005CF300404EF2008C405054094094940485 +:1047800040002C08405154094084140440212C0856 +:10479000E6E2E9274094F8044EA20004408478043D +:1047A0009F714062A81AC61D525300204E57000C3C +:1047B0004041140C4054140C4084180D4021180D35 +:1047C000FEAFD50CFFAA505280204044140CFF17B6 +:1047D0004043181A4024180D8500C40358210002D4 +:1047E000C3594C7540064C9440044C010078E328B2 +:1047F000E9054C94400AE202E8079FF940447C082E +:1048000093019241FEA780809A02E2808B2F8B2831 +:10481000E6E2E9494E93000BFA904043900680A7E8 +:10482000CC0D812084005073FFE042548007E2A742 +:104830005247800142529C01C50D9BFD9B6C526208 +:1048400080204040180D4094940C4000140C40947B +:104850009004500004005CF00400892FE32F88EFDF +:1048600040502C09976C80C09A05E2C08B2F409471 +:1048700084084054D008932C920BFE2F4053D0084C +:10488000409494044010F8024010A4043A6FA884A5 +:10489000DD9E9802E202892FE32F8928E90AE328A6 +:1048A000E908CFD8920B4044D408932BFE27D5EBD0 +:1048B000525387FEC50E54F00001585000024002CA +:1048C000BC1B4044FC0893219201FE279DF9D5C2F0 +:1048D00084004697FF00D5D7C3DA84008420D5D75B +:1048E000409480044C9F40054C557FD2C3D0840037 +:1048F00044180000D5CC9200FC4295099295407076 +:10490000AC0840605409FFF740602C0847C800001D +:10491000955992B54091AC08408154094094A00447 +:1049200040812C08FECD40A1F002443007FFC4585E +:104930004C3200754073F0044E5200874C3280793F +:104940004094F00414AF80035002FC0299204223EB +:10495000A4694203246940910400E32140A1BC0002 +:104960004223A06999D0E2E0892FE32F894F892360 +:10497000E323894F4203206999F9E2E1892FE32F6C +:1049800040153C00FFC75804800140049C1AE420F5 +:10499000E90781E09800E20F9849882F9F2104AF32 +:1049A00080034E470071525207FF4E570046500099 +:1049B00004005CF00400E804882FE22F888F402078 +:1049C0002C0996949A02920B4020D408FE17944921 +:1049D000922C40525008FE6F4010A804FCC240F3D5 +:1049E0009804E81940F37C0999FF88EF99B6CF0540 +:1049F00080E684C050427FE042038007C09E9B2037 +:104A0000522000204023080D4063000C4073800CAE +:104A1000FFD7D593D315802AFCC2FFF74C7E4011F7 +:104A2000CD064024840840212004C20ADB054094BE +:104A3000A0044C9E400684004617FF00D5CE84009B +:104A400044180000FCC24004A004C0E640F47C0905 +:104A50008929892F89084E930006812885005052A4 +:104A6000FFE0420480074E02FF6F9B685220002047 +:104A70004024080D4084000C4094800C409488042D +:104A800048FFFF6284C0523200015CF18020E90AD5 +:104A900080C0800184205031FFE0C0045CF18020A0 +:104AA000E81AC310522180204070880C4050080C36 +:104AB00040000C0D40108C0DFE3FFFAFC6035800A8 +:104AC0000001500004005CF00400882F4040FC0905 +:104AD00048FFFF778400D5A0FC429509929540706D +:104AE000AC0840605409FFF740602C0847C800003C +:104AF000955992B54091AC08408154094094A00466 +:104B000040812C08FECD40A1F002443007FF4E4208 +:104B100000C54C3200EF4073F0044E5200FB4C32A3 +:104B200080F34094F0049B25504203FF92C1401350 +:104B3000FC08FF8F92E14024C009403388F74014FD +:104B4000801342508C244073C00840034009FFC7C3 +:104B500080079BFDE207E8059ED988E9E2E9E8FDC8 +:104B6000402388F7425088244073C0089631FFC71D +:104B700080079BFDE207E8059E9188E9E2E9E8FDF0 +:104B80004031C00898DA4201A069FF8280079BF992 +:104B9000E207C60580079FF9E903E207E80C9ED902 +:104BA00088C84003200688E9E2E9C0049DF9E903CA +:104BB000E6E1E8F64C74C007802880E68440840073 +:104BC000D52B4014C009402384F74004801342F0E1 +:104BD00008244073C00840534009FFEF80A78AEFC4 +:104BE000E2A7E8059E9188E9E2E9E8FD401384F731 +:104BF000425004244073C0089631FFC780079BFDD4 +:104C0000E207E8059E4988E9E2E9E8FD402140081D +:104C1000989142012069FF8280079BF9E207C6054F +:104C200080079FF9E903E207E80C9E9188C84003DA +:104C3000200688E9E2E9C0049DF9E903E6E1E8F627 +:104C4000E460E90781E29892E24F98DB886F9F2148 +:104C5000FFF75801000140011C1A80234E470079DC +:104C6000525207FF4E57004A500004005CF0040007 +:104C7000E804882FE22F888F40202C0996949A020E +:104C8000920B4020D408FE179449922C40525008B1 +:104C9000FE6F4010A804FCC240F39804E81B40F3E8 +:104CA0007C0999FF88EF99B6CF0580E684C0504211 +:104CB0007FE0420380074E02FF329B2052200020FB +:104CC0004023080D4063000C4073800CFFD748FF61 +:104CD000FF26D307CD0440F4A004E807802AFCC2D5 +:104CE0004094A0044C9E3FFC840044180000FCC289 +:104CF000FFF74C7E7FFBD3F984004617FF0040107E +:104D0000A804FCC24094A0044C9E7FF08400D5E728 +:104D100040F4A004E8F240F47C098929892F89082D +:104D20004E930006812885005052FFE04204800720 +:104D30004E02FEFB9B68522000204024080D408458 +:104D4000000C4094800C4094880448FFFEEE84C020 +:104D5000523200015CF18020E90A80C08001842089 +:104D60005031FFE0C0045CF18020E81AC3105221EA +:104D700080204070880C4050080C40000C0D401002 +:104D80008C0DFE3FFFAFC603580000015000040029 +:104D90005CF00400882F4040FC0948FFFF6F84004E +:104DA000D59E92003A6F983C954992B54040AC0828 +:104DB00040605409FF3740302C0846680000FF3738 +:104DC0005CF2843EE8215222843EFAD0E246E906B3 +:104DD0008064848050217FE0CBF9C20B8004403195 +:104DE000880D4042080D522100204000080CFEC7EB +:104DF000E420E805FF22C303FEDA8E8180038024CD +:104E00003A6F9804DD9EE420E90752F287FFE90833 +:104E100095A1FF9FC605464800008460D5F046472F +:104E2000FFFF58420FFF847FD5EA92003A6F983C0B +:104E3000842080A180618040C210E440E807465889 +:104E40000000FE92C103FE4A8E414430041E4241DE +:104E500000079ADC4021100C4040AC094061540826 +:104E6000FF37959192CCFF774061D008FF7780049F +:104E700080253A6F9804DD9E4402D6BCDD9E9200E8 +:104E80008060E644E9285441800354508003C50BF8 +:104E9000525280049A959969084080011841800116 +:104EA0004C12FFFC40511409C50A956D996996A7EB +:104EB0003B00DC043B01DC244C12FFFC40510809A0 +:104EC000C50A956A9969968F3A4090043A419024B0 +:104ED0004C12FFFCC208994A084080011841800129 +:104EE0004C12FFFCDD9E92008060E644E930545194 +:104EF0008003C509525280049A959968181180015F +:104F00004C32FFFE96484040A008FE674040C00873 +:104F1000FE67405114094E520011956D996B96A78A +:104F20008201822182418261828182A182C182E1E9 +:104F30003B01DC244C32FFFE40510809C508956A4C +:104F4000996B968F3A1184244C32FFFEC206995A0F +:104F5000181180014C32FFFEDD9E92003C0DFB409B +:104F60004900103E4900389B490041D54900114590 +:104F700049006C674403F04A44100055490041D58C +:104F80004900A640490039373C0DFB5444038D408D +:104F90004900389B480001553C0DFC2849001FCCB6 +:104FA000490039374900103E3C0DFB3F3C1DFB6674 +:104FB000490038EB3C1DFB4049003C443C1DFB5480 +:104FC0003C0DFB662E07F01F2E07EC583C0DFB64D2 +:104FD00049006C674420019048008D2C49003AAC90 +:104FE000442000552E07EC6D490014E84430019030 +:104FF0004412FEF04402DE5C3A6F98844413F04A97 +:1050000040000009100F80072E07EC732E17EFAA3F +:10501000490058EC3E07EC774900A28E4900A37C7A +:1050200049007587442001803C1DFC281004800045 +:105030003C0FFB3F50037F48443000554423F04A67 +:105040003C0FFB6349001F163C0FFBE349006B60FC +:1050500040F03C0040310C4049006A764900781C21 +:105060004900A6743E07EC28440FFFAA3C0DFB5BE9 +:105070002E0010AD2E1FEF0F2E000C143C0FFB6402 +:10508000660000E02E000C3444338D412E07292C9D +:10509000100F800F440000FF4400005554007FFFB4 +:1050A0004900A194490010423C0E030C5800000135 +:1050B0004200080B490011450000005149003C44E2 +:1050C0001010001C3C0DFFD710938000120F8003BE +:1050D0003A210C004402C4D04200100B440000509E +:1050E000490014A93C0E030B40008040490012AF58 +:1050F0003C1DFB583C0BF64E3C0DFB8E1004800112 +:105100004402FF545410FFFF64030403020F8003A2 +:105110004900781C54637FFF3E07EF104402FEF005 +:1051200042006C0B4402E7D84900A28C00048001C5 +:1051300049006EEE490070B34473F04A4402C369FB +:105140003E07E9B8490058EC441000323C0DFBAD75 +:10515000490041E2440300005800000466000002D8 +:105160002E07EC1E449000555800001044131C20DC +:10517000440200003B00E424490077CF4900391184 +:105180003E07EC6D101000514402FE5038078000BD +:105190004413F4034403651049001B3E1003005000 +:1051A00049007A2C2E0011723E07EC134430008027 +:1051B0003E07EF6E3C0DFB653E07EC224900757023 +:1051C0003C08086C580000024463F04A3E07EF0FA9 +:1051D0002E07EC3140F0BC00490038EB49006D343B +:1051E000490081573B0064043C0BF6643C0C041AF4 +:1051F0002E07292B540000FE2E0FEF10490034CC4F +:105200003C0FFB774462FEF03E07EC42440000692D +:1052100049001B913C0BF8A62E07EF065800002012 +:10522000000500004412FE502E07EC084400003236 +:10523000502F800766000004490034CC2E07EC286C +:10524000021F80004412623840109C36549000FFC8 +:1052500000048000503F80073C03F64F4800017176 +:1052600044700055480001283E07EF123E17EF0F2B +:105270003E000C3450528F003E07EC6F4400007823 +:10528000440373E84200040B3E07EC3A3C0DFFEE8A +:105290006413040266000010382080084413F248AA +:1052A0003C0DFFD844000041440000433E07EC5849 +:1052B0005C0000014422C51410030041120F80025B +:1052C00049006F2042000C0B490063C9541080FE56 +:1052D00040310C062E07EC19440397DE58000008F5 +:1052E00049006EEE2E07EF825800008064132403FD +:1052F0002E07F0D8441300003C0BF8A73E07EC57EC +:1053000049009F8E4412C3973E17EC3A49007E3BFA +:1053100040320D0018128001020F80012E07F09814 +:105320002E07F13438308A0A2E07EBFB501F800F0E +:10533000502F800649006FB5490064B449002054DD +:105340003E07EC313C0E030450000FFF2E07EC66C5 +:1053500046500FFF500F800E401004363E07EC877A +:105360003C0BF7B63C0BF7AC4462FF542E17F01F12 +:10537000443000323C6FFC992E07EF7244026238D1 +:10538000490013A02E07EC431005000004628016AC +:105390004422E8B0020F80004472C7A85CF003E822 +:1053A0003C0FFBE44412168044134C10400018409C +:1053B0002E17EC583C5DFB4F3C1FFB633E0010DE9C +:1053C0003C1DFBB6490046514402FEF14900A616B9 +:1053D0003C0FFB9B49003AA51005800044130FA029 +:1053E000400004164413F1C04403F41C4402E318C3 +:1053F000000F8006500F800638078101440397DCB8 +:10540000540000FD000F800F5CF000333C03F656A3 +:105410003E07F0B73E07F0B13C0BF65666000008B9 +:105420002E07EF5B4900817F3C0C03043C0DFECB53 +:105430003E17EC0A3C0DFB4F3C6FFB9B2E07EC39F3 +:105440002E0729BE3E07F1342E07289B2E07EF07B3 +:105450004422DD684400004244138D40440000446F +:10546000490046514200000349007CF83E07EC66C3 +:105470003C1FFB644000810044136510401004068B +:105480003E07EF9F3C03F660502F800F3C23946251 +:10549000423180030003007D4422E7D849007C8428 +:1054A0004412E7D8490087A1000F8007500F8007FA +:1054B0004900406E44038D424900104E3E07F0E81B +:1054C000440000524412D9703C0DFC582E07EC6B7E +:1054D0004900623B49006C0900148001490063E007 +:1054E0003E07EC013C0BF64D490040424412A50A30 +:1054F00049006B60640308034412C40A380486023E +:105500003C0FFB7A400320093C0DFFDD49003A3592 +:105510000001004244400055221080013E07EC0C7F +:105520003C0FFB4449001D463C0FFB83120F8000DB +:105530003C1FFC98490070FC44037A283E07F0D8D1 +:10554000120480004403F7CE030200004402C4901A +:105550003C0FFB984472C7C03C6FFB3F3C1DFBF502 +:1055600049007A313E07EC694010044049008D50F3 +:1055700040213C0804118014000100463E07EC2441 +:1055800040108C365EF0003349001FC41010003C00 +:10559000120F800B002F80072E07EC4E3E07F0E124 +:1055A000223080002E07F0B1490064471203000941 +:1055B00049009971490080AE448000553C3DFB4C48 +:1055C000109000004410004144100043101000529D +:1055D0003C03F8A6405293F53E07EFA7540000F0B5 +:1055E0003E07EF0644134DA03C0E03071003007D59 +:1055F000121000104403F00E4412E380490019AB6E +:105600003C0DFFE6490075823E0729BE44038D41EB +:105610003C0FFB6A49007A2C3B014C00441000A56A +:105620003E07F0E94413331049003F653C0DFFEF9E +:105630004410004C2E07EF803C5DFB584403F7C834 +:10564000120300253C1DFB452E07EC764412D8C002 +:105650004402FE604900710F4413F2493E07EF7E99 +:105660002E07EC355EF100332E07EF794412D9385E +:10567000490088273E07EF7A4412C3DA38178400BE +:105680004900395D2E07EC3A520000010030000E4F +:1056900049003F70101000083E67EF9C1003004067 +:1056A00014AF80015000024049000D3949007115C6 +:1056B000120F80013E07F123440200003E07EC6216 +:1056C0002E07EF7E2E5010AD442000B64400004659 +:1056D0004403F0805CF287083C13F653120F800AF3 +:1056E00049003B112E07EC0C2E07EC592E07EC0E4F +:1056F00042209073460000F4490022B812030008CB +:1057000049003AFB3B0FCC20490089D43C0BF660A2 +:105710003C1C01C03E07EF073C0E03083C0DFB5943 +:10572000490071334412C3736600000150108FFFAB +:1057300049001B912E372892441FFFAA42028C7306 +:105740003C0C01BF10A48000490070DB44238D4154 +:10575000100F80333C0DFB9B4900393800000000DE +:105760008492030014940300FAAF02008AB102008D +:10577000648F0300F4900300DAAC02006AAE02000A +:1057800010330300903F0300104C030090580300B7 +:1057900000A2010080AE010000BB010080C7010033 +:1057A00010D8010050DE010090E40100D0EA0100B1 +:1057B000E8730300F8740200A00F03006880030080 +:1057C0006464696A6C6E71718A827C6F68647690B9 +:1057D000646467696B6D70718E837A6D6664758FB2 +:1057E0006464696A6C6E71718A827C6F6864769099 +:1057F000646467696B6D70718E837A6D6664758F92 +:105800006464696A6C6E71718A827C6F6864769078 +:10581000646467696B6D70718E837A6D6664758F71 +:105820006464696A6C6E71718A827C6F6864769058 +:10583000646467696B6D70718E837A6D6664758F51 +:105840006464696A6C6E71718A827C6F6864769038 +:10585000646467696B6D70718E837A6D6664758F31 +:105860006464696A6C6E71718A827C6F6864769018 +:10587000646467696B6D70718E837A6D6664758F11 +:105880006464696A6C6E71718A827C6F68647690F8 +:10589000646467696B6D70718E837A6D6664758FF1 +:1058A0006464696A6C6E71718A827C6F68647690D8 +:1058B000646467696B6D70718E837A6D6664758FD1 +:1058C000646468666C6C71709086806F6B647891AC +:1058D000646467686B6C707092857D6E68647590A7 +:1058E000646468666C6C71709086806F6B6478918C +:1058F000646467686B6C707092857D6E6864759087 +:10590000646468666C6C71709086806F6B6478916B +:10591000646467686B6C707092857D6E6864759066 +:10592000646468666C6C71709086806F6B6478914B +:10593000646467686B6C707092857D6E6864759046 +:10594000646468666C6C71709086806F6B6478912B +:10595000646467686B6C707092857D6E6864759026 +:10596000646468666C6C71709086806F6B6478910B +:10597000646467686B6C707092857D6E6864759006 +:10598000646468666C6C71709086806F6B647891EB +:10599000646467686B6C707092857D6E68647590E6 +:1059A000646468666C6C71709086806F6B647891CB +:1059B000646467686B6C707092857D6E68647590C6 +:1059C00064656B6B6F707678A1958A7A6C647B9B4B +:1059D00066646E6B71737678A5988A7C6E647D9B25 +:1059E00064656B6B6F707678A1958A7A6C647B9B2B +:1059F00066646E6B71737678A5988A7C6E647D9B05 +:105A000064656B6B6F707678A1958A7A6C647B9B0A +:105A100066646E6B71737678A5988A7C6E647D9BE4 +:105A200064656B6B6F707678A1958A7A6C647B9BEA +:105A300066646E6B71737678A5988A7C6E647D9BC4 +:105A400064656B6B6F707678A1958A7A6C647B9BCA +:105A500066646E6B71737678A5988A7C6E647D9BA4 +:105A600064656B6B6F707678A1958A7A6C647B9BAA +:105A700066646E6B71737678A5988A7C6E647D9B84 +:105A800064656B6B6F707678A1958A7A6C647B9B8A +:105A900066646E6B71737678A5988A7C6E647D9B64 +:105AA00064656B6B6F707678A1958A7A6C647B9B6A +:105AB00066646E6B71737678A5988A7C6E647D9B44 +:105AC00064656B6B6F707678A1958A7A6C647B9B4A +:105AD00066646E6B71737678A5988A7C6E647D9B24 +:105AE00064656A6A6E707377A6958D7C70647E9E1D +:105AF00064666A6C6E707476A7998B7E72647E9E03 +:105B000064656A6A6E707377A6958D7C70647E9EFC +:105B100064666A6C6E707476A7998B7E72647E9EE2 +:105B200064656A6A6E707377A6958D7C70647E9EDC +:105B300064666A6C6E707476A7998B7E72647E9EC2 +:105B400064656A6A6E707377A6958D7C70647E9EBC +:105B500064666A6C6E707476A7998B7E72647E9EA2 +:105B600064656A6A6E707377A6958D7C70647E9E9C +:105B700064666A6C6E707476A7998B7E72647E9E82 +:105B800064656A6A6E707377A6958D7C70647E9E7C +:105B900064666A6C6E707476A7998B7E72647E9E62 +:105BA00064656A6A6E707377A6958D7C70647E9E5C +:105BB00064666A6C6E707476A7998B7E72647E9E42 +:105BC00064656A6A6E707377A6958D7C70647E9E3C +:105BD00064666A6C6E707476A7998B7E72647E9E22 +:105BE000646468706C71757AA99B8C806E647DA109 +:105BF000676469706F72747BAF9E918571647DA1DB +:105C0000646468706C71757AA99B8C806E647DA1E8 +:105C1000676469706F72747BAF9E918571647DA1BA +:105C2000646468706C71757AA99B8C806E647DA1C8 +:105C3000676469706F72747BAF9E918571647DA19A +:105C4000646468706C71757AA99B8C806E647DA1A8 +:105C5000676469706F72747BAF9E918571647DA17A +:105C6000646468706C71757AA99B8C806E647DA188 +:105C7000676469706F72747BAF9E918571647DA15A +:105C8000646468706C71757AA99B8C806E647DA168 +:105C9000676469706F72747BAF9E918571647DA13A +:105CA000646468706C71757AA99B8C806E647DA148 +:105CB000676469706F72747BAF9E918571647DA11A +:105CC000646468706C71757AA99B8C806E647DA128 +:105CD000676469706F72747BAF9E918571647DA1FA +:105CE00064656A736E747A80CCB9A493786485B263 +:105CF00064646A7270757881D5C1AA987C6487B72C +:105D000064656A736E747A80CCB9A493786485B242 +:105D100064646A7270757881D5C1AA987C6487B70B +:105D200064656A736E747A80CCB9A493786485B222 +:105D300064646A7270757881D5C1AA987C6487B7EB +:105D400064656A736E747A80CCB9A493786485B202 +:105D500064646A7270757881D5C1AA987C6487B7CB +:105D600064656A736E747A80CCB9A493786485B2E2 +:105D700064646A7270757881D5C1AA987C6487B7AB +:105D800064656A736E747A80CCB9A493786485B2C2 +:105D900064646A7270757881D5C1AA987C6487B78B +:105DA00064656A736E747A80CCB9A493786485B2A2 +:105DB00064646A7270757881D5C1AA987C6487B76B +:105DC00064656A736E747A80CCB9A493786485B282 +:105DD00064646A7270757881D5C1AA987C6487B74B +:105DE00064656A736E747A80CCB9A493786485B262 +:105DF00064646A7270757881D5C1AA987C6487B72B +:105E000066666666666666666C6C6C6C6C6C6C6C02 +:105E1000676767676767676768686868686868680A +:105E20006565656565656565676767676767676712 +:105E300068686868686868686666666666666666F2 +:105E400065656565656565656868686868686868EA +:105E500067676767676767676868686868686868CA +:105E600066666666666666666767676767676767CA +:105E700066666666666666666464646464646464D2 +:105E800065656565656565656868686868686868AA +:105E9000666666666666666667676767676767679A +:105EA0006464646464646464686868686868686892 +:105EB000686868686868686867676767676767676A +:105EC000646464646464646467676767676767677A +:105ED0006464646464646464646464646464646482 +:105EE0006464646464646464646464646464646472 +:105EF000656565656565656564646464646464645A +:105F00006C6C6C6C6C6C6C6C6E6E6E6E6E6E6E6EC1 +:105F10006A6A6A6A6A6A6A6A6D6D6D6D6D6D6D6DC9 +:105F200069696969696969696B6B6B6B6B6B6B6BD1 +:105F300069696969696969696B6B6B6B6B6B6B6BC1 +:105F400068686868686868686B6B6B6B6B6B6B6BB9 +:105F500069696969696969696B6B6B6B6B6B6B6BA1 +:105F600069696969696969696D6D6D6D6D6D6D6D81 +:105F700068686868686868686B6B6B6B6B6B6B6B89 +:105F80006767676767676767696969696969696991 +:105F900066666666666666666666666666666666A1 +:105FA0006666666666666666686868686868686881 +:105FB0006565656565656565696969696969696971 +:105FC0006666666666666666676767676767676769 +:105FD0006565656565656565676767676767676761 +:105FE0006464646464646464676767676767676759 +:105FF0006464646464646464646464646464646461 +:106000006E6E6E6E6E6E6E6E6A6A6A6A6A6A6A6AD0 +:106010006C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6CC0 +:106020006D6D6D6D6D6D6D6D6C6C6C6C6C6C6C6CA8 +:106030006C6C6C6C6C6C6C6C6B6B6B6B6B6B6B6BA8 +:106040006C6C6C6C6C6C6C6C6868686868686868B0 +:106050006A6A6A6A6A6A6A6A6B6B6B6B6B6B6B6B98 +:106060006B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B80 +:1060700067676767676767676A6A6A6A6A6A6A6A98 +:106080006B6B6B6B6B6B6B6B6A6A6A6A6A6A6A6A68 +:106090006767676767676767686868686868686888 +:1060A0006969696969696969676767676767676770 +:1060B00069696969696969696B6B6B6B6B6B6B6B40 +:1060C0006A6A6A6A6A6A6A6A686868686868686840 +:1060D00069696969696969696A6A6A6A6A6A6A6A28 +:1060E0006767676767676767656565656565656550 +:1060F0006666666666666666686868686868686830 +:10610000646464646464646464646464646464644F +:106110006464646464646464656565656565656537 +:106120006D6D6D6D6D6D6D6D6F6F6F6F6F6F6F6F8F +:1061300072727272727272726D6D6D6D6D6D6D6D67 +:106140006A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6AAF +:106150006D6D6D6D6D6D6D6D69696969696969698F +:1061600068686868686868686B6B6B6B6B6B6B6B97 +:1061700069696969696969696A6A6A6A6A6A6A6A87 +:106180006666666666666666696969696969696997 +:106190006969696969696969686868686868686877 +:1061A0006969696969696969666666666666666677 +:1061B000696969696969696969696969696969694F +:1061C000686868686868686868686868686868684F +:1061D000696969696969696969696969696969692F +:1061E000686868686868686868686868686868682F +:1061F0006767676767676767686868686868686827 +:10620000666666666666666668686868686868681E +:106210006464646464646464656565656565656536 +:106220006C6C6C6C6C6C6C6C6F6F6F6F6F6F6F6F96 +:106230006D6D6D6D6D6D6D6D707070707070707076 +:106240006C6C6C6C6C6C6C6C6E6E6E6E6E6E6E6E7E +:106250006B6B6B6B6B6B6B6B6E6E6E6E6E6E6E6E76 +:1062600068686868686868686B6B6B6B6B6B6B6B96 +:106270006B6B6B6B6B6B6B6B6F6F6F6F6F6F6F6F4E +:1062800069696969696969696B6B6B6B6B6B6B6B6E +:1062900068686868686868686C6C6C6C6C6C6C6C5E +:1062A0006868686868686868696969696969696966 +:1062B000676767676767676769696969696969695E +:1062C000676767676767676767676767676767675E +:1062D0006565656565656565686868686868686856 +:1062E000676767676767676767676767676767673E +:1062F00065656565656565656B6B6B6B6B6B6B6B1E +:106300006464646464646464656565656565656545 +:10631000656565656565656567676767676767671D +:106320006D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D9D +:106330006D6D6D6D6D6D6D6D6B6B6B6B6B6B6B6B9D +:106340006B6B6B6B6B6B6B6B6A6A6A6A6A6A6A6AA5 +:1063500068686868686868686A6A6A6A6A6A6A6AAD +:1063600068686868686868686B6B6B6B6B6B6B6B95 +:106370006B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6D +:106380006A6A6A6A6A6A6A6A68686868686868687D +:1063900068686868686868686A6A6A6A6A6A6A6A6D +:1063A000686868686868686868686868686868686D +:1063B0006A6A6A6A6A6A6A6A68686868686868684D +:1063C0006565656565656565686868686868686865 +:1063D0006868686868686868676767676767676745 +:1063E0006767676767676767646464646464646455 +:1063F0006767676767676767646464646464646445 +:10640000646464646464646464646464646464644C +:106410006767676767676767646464646464646424 +:10642000656565656565656565656565656565651C +:106430006464646464646464676767676767676704 +:106440006A006F0066006D0069006A0067006B00FB +:1064500069006B0066006D006A006A0065006900F3 +:1064600069006B0065006C0068006B0067006C00E1 +:1064700068006A00630069006800670064006900E2 +:1064800065006500630067006400650063006700E5 +:1064900065006600620067006300630060006200E0 +:1064A000620062005F006500620061005F006300DF +:1064B000600061005E00600061005E005E006000E0 +:1064C000600060005E005F005F005D005C005F00D8 +:1064D0005E005F005A005E005E005E005A005D00D4 +:1064E0005C005C005B005F005D005D005B005E00C7 +:1064F0005B005A0059005D005800590057005A00CF +:1065000059005A005B0059005700560057005600CA +:1065100055005700540057005400550054005500D2 +:1065200056005300540056005500540054005600C5 +:1065300055005400520055005400540050005300C0 +:1065400052005100520052005200500050005000C2 +:106550004F004E005000510050004E004E004F00C2 +:106560004F004D004D004D004E004B004C004C00C4 +:106570004E004B004C004E004C004A004C004B00BB +:106580004C0049004B0049004B00470048004800C0 +:10659000490048004A0049004A00460048004800B7 +:1065A00049004600490047004700460048004600B1 +:1065B00048004300470044004600430047004400B1 +:1065C00047004400450046004700440045004500A0 +:1065D0006A006A006F007000720075007800780031 +:1065E00092008A00830076006E006A007D009900A8 +:1065F000690069006C006E00700072007600770020 +:1066000099008D00840076006E006C007E009A0078 +:1066100064006400680066006C006C00710070002B +:106620008C0082007C006C006800610074008D00AA +:10663000620062006500660069006A006E006E001C +:10664000910084007C006D006700630074008F007F +:106650005E005F0065006500680069006F00710002 +:106660008E00830079006B005F0058006C0088008A +:106670005E005C006500620068006A006D006E00EC +:106680009100860079006D00610058006E0088005E +:1066900054005500590059005C005E006100640020 +:1066A0007E0071006B005E0055004C0060007800B9 +:1066B0005300550058005A005B005D006000620006 +:1066C0007F0074006A00600057004C006000780092 +:1066D0004C004C004F0055005200560059005D0020 +:1066E000710068005E0056004A00430054006C00D0 +:1066F0004C004A004E0053005200540056005B000C +:1067000075006A00610059004C00430054006C00A1 +:106710004300440047004D004A004E00520056001E +:10672000700066005A0051004200370049006200C4 +:106730004200420046004B004A004D004F00550009 +:10674000730068005C00520043003600490063009B +:1067500019004B007D00AF00E100130145017701F6 +:10676000A901DB010D023F027102A302D50207035A +:1067700039036B039D03CF03020436046A049E04AD +:10678000D20406053A056E05A205D6050A063E06A0 +:106790007206A606DA060E0742077607AA07DE0784 +:1067A000120846087A08AE08E20816094A097E0966 +:1067B000B209E60932003200320032003200320003 +:1067C0003200320032003200320032003200320039 +:1067D0003200320032003200320032003400340025 +:1067E0003400340034003400340034003400340009 +:1067F00034003400340034003400340034003400F9 +:1068000034003400340034003400340034003400E8 +:10681000340034003400340019004B007D00AF0018 +:10682000E100130145017701A901DB010D023F02DF +:106830007102A302D502070339036B039D03CF0343 +:106840000104330465049704C904FB042D055F05A6 +:106850009105C305F50527063200320032003200EB +:106860003200320032003200320032003200320098 +:106870003200320032003200320032003200320088 +:106880003200320032003200320032003200320078 +:1068900032003200320032000808090808090100FD +:1068A0000001000201030203E8730300F874020010 +:1068B000A00F03006880030010D8010050DE010023 +:1068C00090E40100D0EA0100208E020060940200F2 +:1068D000A09A0200E0A0020010330300903F0300E2 +:1068E000104C03009058030000090B020F06040D22 +:1068F000070E0C050801030A010203040506000740 +:106900000800000006060606060606060600000049 +:1069100004050607F20A0B00BCC20C002B4C0E004B +:10692000AF3009004C5E090030790D000A930F006A +:10693000C2E40D000DF50400433D0300D4B3010093 +:1069400050CF0600B3A10600CF860200F56C000010 +:106950003D1B02000DF50400F56C00004C5E0900C3 +:106960002B4C0E00000000000000000000000000A2 +:1069700000000000BCC20C00AF30090030790D00EF +:10698000C2E40D0000000000000000000000000054 +:1069900000000000D4B30100433D0300B3A1060092 +:1069A0003D1B02000A930F0030790D00F20A0B0024 +:1069B000AF3009000DF5040050CF0600F56C000063 +:1069C000CF8602004C5E0900C2E40D002B4C0E0085 +:1069D000BCC20C003D1B0200B3A10600433D0300F6 +:1069E000D4B30100AF300900F20A0B0030790D007A +:1069F0000A930F00CF860200F56C000050CF06000E +:106A00000DF50400BCC20C002B4C0E00C2E40D00BE +:106A10004C5E0900F20A0B00BCC20C002B4C0E00AD +:106A2000AF3009004C5E090030790D000A930F0069 +:106A3000C2E40D000202020303030404000002008A +:106A400003000500070009000A000C000E001000FA +:106A5000110013001500160018001A001C001D007C +:106A60001F002100220024002500270029002A0001 +:106A70002C002D002F00300032003400350036008D +:106A8000380039003B003C003E003F00400042001F +:106A90004300440045004700480049004A004B00BD +:106AA0004D004E004F005000510052005300540062 +:106AB0005500560057005700580059005A005B0017 +:106AC0005B005C005D005D005E005F005F006000D9 +:106AD00060006100610061006200620062006300AA +:106AE0006300630063006400640064006400640089 +:106AF00064000000640064006400640064006400DA +:106B00006300630063006300620062006200610072 +:106B100061006100600060005F005F005E005D007A +:106B20005D005C005B005B005A0059005800570094 +:106B300057005600550054005300520051005000B9 +:106B40004F004E004D004B004A00490048004700EE +:106B5000450044004300420040003F003E003C002E +:106B60003B00390038003600350034003200300078 +:106B70002F002D002C002A002900270025002400CA +:106B8000220021001F001D001C001A001800160022 +:106B900015001300110010000E000C000A0009007F +:106BA00007000500030002000000000000000200D2 +:106BB00003000500070009000B000C000E00100088 +:106BC000120013001500170019001B001D001F0004 +:106BD000200022002400260028002A002D002F007B +:106BE00031003300350037003A003C003E004100E0 +:106BF0004300460049004B004E005100540057002E +:106C00005A005D006100640068006B006F00730053 +:106C100077007B00800085008A008F0094009A0036 +:106C2000A000A600AD00B400BC00C400CD00D6009A +:106C3000E100EC00F80005011301220134014701D5 +:106C40005D0175019101B101D6010202370277029F +:106C5000C8022E03B703770496057407300B61163C +:106C600010270000000001000400090010001900B6 +:106C70002400310040005100640079009000A90018 +:106C8000C400E10000012101440169019001B90142 +:106C9000E401110240027102A402D9021003490367 +:106CA0008403C103000441048404C9041005590588 +:106CB000A405F10540069106E40639079007E907A7 +:106CC0004408A10800096109C409290A900AF90ABF +:106CD000640BD10B400CB10C240D990D100E890ED4 +:106CE000040F810F001081100411891110129912E4 +:106CF0002413B1134014D1146415F91590162917F3 +:106D0000C41761180019A119441AE91A901B391CFB +:106D1000E41C911D401EF11EA41F00006D006D00BB +:106D20006E00700071007100710000006D006D0058 +:106D30006B00690068006800670000000000050043 +:106D40000A001300190028003C00000000000000A9 +:106D50000038FAFE422EE63F3067C79357F32E3DC8 +:106D6000010000000000E0BF5B3051555555D53F94 +:106D70009045EBFFFFFFCFBF1101F124B399C93F4D +:106D80009FC806E57555C5BF000000000000E0BFC4 +:106D9000775555555555D53FCBFDFFFFFFFFCFBF6D +:106DA0000CDD95999999C93FA74567555555C5BFBC +:106DB00030DE44A32449C23F653D42A4FFFFBFBF6C +:106DC000CAD62A288471BC3FFF68B043EB99B9BF8B +:106DD00085D0AFF78281B73FCD45D1751352B5BF8E +:106DE0009FDEE0C3F034F73F0090E6797FCCD7BF59 +:106DF0001FE92C6A7813F73F00000DC2EE6FD7BF72 +:106E0000A0B5FA0860F2F63F00E05113E313D7BFD4 +:106E10007D8C131FA6D1F63F007828385BB8D6BF0B +:106E2000D1B4C50B49B1F63F00788090555DD6BF0F +:106E3000BA0C2F334791F63F00001876D002D6BF28 +:106E4000234222189F71F63F00909086CAA8D5BFB2 +:106E5000D91EA5994F52F63F00500356434FD5BF58 +:106E6000C4248FAA5633F63F00406BC337F6D4BF15 +:106E700014DC9D6BB314F63F0050A8FDA79DD4BF52 +:106E80004C5CC65264F6F53F00A889399245D4BFE0 +:106E90004F2C91B567D8F53F00B8B039F4EDD3BFAA +:106EA000DE905BCBBCBAF53F00708F44CE96D3BF6B +:106EB000781AD9F2619DF53F00A0BD171E40D3BFDF +:106EC000875646125680F53F008046EFE2E9D2BF72 +:106ED000D36BE7CE9763F53F00E030381B94D2BF09 +:106EE000937FA7E22547F53F0088DA8CC53ED2BFE5 +:106EF00083450642FF2AF53F00902729E1E9D1BFEB +:106F0000DFBDB2DB220FF53F00F8482B6D95D1BFF6 +:106F1000D7DE34478FF3F43F00F8B99A6741D1BF09 +:106F20004028DECF43D8F43F0098EF94D0EDD0BF97 +:106F3000C8A378C03EBDF43F0010DB18A59AD0BFAF +:106F40008A25E0C37FA2F43F00B86352E647D0BF72 +:106F50003484D4240588F43F00F0864522EBCFBF6B +:106F60000B2D191BCE6DF43F00B017754A47CFBFEC +:106F7000541839D3D953F43F0030103D44A4CEBF48 +:106F80005A84B444273AF43F00B0E9440D02CEBF1E +:106F9000FBF81541B520F43F00F07729A260CDBF82 +:106FA000B1F43EDA8207F43F0090950401C0CCBFF3 +:106FB0008FFE575D8FEEF33F001089562920CCBF1E +:106FC000E94C0BA0D9D5F33F0010818D1781CBBFC1 +:106FD0002BC110C060BDF33F00D0D3CCC9E2CABF03 +:106FE000B8DA752B24A5F33F0090122E4045CABF96 +:106FF00002D09FCD228DF33F00F01D6877A8C9BF56 +:107000001C7A84C55B75F33F003048696D0CC9BFBD +:10701000E236AD49CE5DF33F00C045A62071C8BF42 +:1070200040D44D987946F33F003014B48FD6C7BF93 +:1070300024CBFFCE5C2FF33F0070623CB83CC7BF4F +:10704000490DA1757718F33F0060379B9AA3C6BF1F +:1070500090393E37C801F33F00A0B754310BC6BF8B +:1070600041F895BB4EEBF23F003024767D73C5BFEF +:10707000D1A919020AD5F23F0030C28F7BDCC4BF10 +:107080002AFDB7A8F9BEF23F0000D2512C46C4BF7A +:10709000AB1B0C7A1CA9F23F000083BC8AB0C3BFB3 +:1070A00030B514607293F23F0000496B991BC3BF67 +:1070B000F5A15757FA7DF23F0040A4905487C2BF14 +:1070C000BF3B1D9BB368F23F00A079F8B9F3C1BF85 +:1070D000BDF58F839D53F23F00A02C25C860C1BF32 +:1070E0003B08C9AAB73EF23F0020F7577FCEC0BF8A +:1070F000B640A92B012AF23F00A0FE49DC3CC0BFEC +:107100003241CC967915F23F00804BBCBD57BFBFD2 +:107110009BFCD21D2001F23F004040960837BEBFC5 +:107120000B484D49F4ECF13F0040F93E9817BDBFC4 +:1071300069658F52F5D8F13F00A0D84E67F9BBBF03 +:107140007C7E571123C5F13F00602F2079DCBABF48 +:10715000E926CB747CB1F13F008028E7C3C0B9BFFA +:10716000B61A2C0C019EF13F00C072B346A6B8BF00 +:10717000BD70B67BB08AF13F0000ACB3018DB7BFE4 +:10718000B6BCEF258A77F13F00003845F174B6BFF1 +:10719000DA314C358D64F13F0080876D0E5EB5BFEE +:1071A000DD5F2790B951F13F00E0A1DE5C48B4BF3C +:1071B0004CD232A40E3FF13F00A06A4DD933B3BF89 +:1071C000DAF910728B2CF13F0060C5F87920B2BF5C +:1071D00031B5EC28301AF13F00206298460EB1BF5D +:1071E000AF3484DAFB07F13F0000D26A6CFAAFBF1C +:1071F000B36B4E0FEEF5F03F0040774A8DDAADBF2E +:10720000CE9F2A5D06E4F03F000085E4ECBCABBFF6 +:1072100021A52C6344D2F03F00C0124089A1A9BF30 +:107220001A98E27CA7C0F03F00C002335888A7BF7D +:10723000D136C6832FAFF03F0080D6675E71A5BF01 +:107240003913A098DB9DF03F008065498A5CA3BF9D +:10725000DFE752AFAB8CF03F00401564E349A1BFBC +:10726000FB284E2F9F7BF03F0080EB82C0729EBFB9 +:10727000198F358CB56AF03F00805252F1559ABF94 +:107280002CF9ECA5EE59F03F008081CF623D96BF0E +:10729000902CD1CD4949F03F0000AA8CFB2892BF29 +:1072A000A9ADF0C6C638F03F0000F9207B318CBF95 +:1072B000A93279136528F03F0000AA5D351984BF13 +:1072C0004873EA272418F03F0000ECC2031278BF8D +:1072D00095B114060408F03F00002479090460BF4A +:1072E0001AFA26F71FE0EF3F00009084F3EF6F3F9C +:1072F00074EA61C21CA1EF3F00003D3541DC873FCD +:107300002E9981B01063EF3F0080C2C4A3CE933F9B +:10731000CDADEE3CF625EF3F00008914C19F9B3FA9 +:10732000E7139103C8E9EE3F000011CED8B0A13FAA +:10733000ABB1CB7880AEEE3F00C001D05B8AA53FF9 +:107340009B0C9DA21A74EE3F0080D840835CA93F3D +:10735000B5990A83913AEE3F008057EF6A27AD3F17 +:10736000569A6009E001EE3F00C098E59875B03F7D +:1073700098BB77E501CAED3F00200DE3F553B23F1E +:1073800003917C0BF292ED3F0000388BDD2EB43F71 +:10739000CE5CFB66AC5CED3F00C057875906B63F3C +:1073A0009DDE5EAA2C27ED3F00006A3576DAB73FF6 +:1073B000CD2C6B3E6EF2EC3F00601C4E43ABB93FF0 +:1073C0000279A7A26DBEEC3F00600DBBC778BB3F42 +:1073D0006D08376D268BEC3F0020E7321343BD3F2D +:1073E00004585DBD9458EC3F0060DE71310ABF3F28 +:1073F0008C9FBB33B526EC3F0040912B1567C03FF7 +:107400003FE7ECEE83F5EB3F00B092828547C13F4A +:10741000C196DB75FDC4EB3F0030CACD6E26C23F7E +:10742000284A860C1E95EB3F0050C5A6D703C33FE4 +:107430002C3EEFC5E265EB3F0010333CC3DFC33F9A +:107440008B88C9674837EB3F00807A6B36BAC43FF8 +:107450004A301D214B09EB3F00F0D1283993C53F3D +:107460007EEFF285E8DBEA3F00F01824CD6AC63FE4 +:10747000A23D60311DAFEA3F009066ECF840C73F87 +:10748000A758D33FE682EA3F00F01AF5C015C83F7F +:107490008B7309EF4057EA3F0080F65429E9C83F53 +:1074A000274BAB902A2CEA3F0040F80236BBC93F7D +:1074B000D1F29313A001EA3F00002C1CED8BCA3FD0 +:1074C0001B3CDB249FD7E93F00D0015C515BCB3FE5 +:1074D00090B1C70525AEE93F00C0BCCC6729CC3FC1 +:1074E0002FCE97F22E85E93F006048D535F6CC3F88 +:1074F000754BA4EEBA5CE93F00C04634BDC1CD3F38 +:107500003848E79DC634E93F00E0CFB8018CCE3F54 +:10751000E652672F4F0DE93F009017C00955CF3F46 +:107520009DD7FF8E52E6E83F00B81F126C0ED03F89 +:107530007C00CC9FCEBFE83F00D0930EB871D03F07 +:107540000EC3BEDAC099E83F0070869E6BD4D03F70 +:10755000FB1723AA2774E83F00D04B338736D13F6F +:10756000089AB3AC004FE83F004823670D98D13F1D +:10757000553E65E8492AE83F0080CCE0FFF8D13F5E +:107580006002F4950106E83F006863D75F59D23F77 +:1075900029A3E06325E2E73F00A8140930B9D23FF0 +:1075A000ADB5DC77B3BEE73F006043107218D33F40 +:1075B000C2259767AA9BE73F0018EC6D2677D33F5B +:1075C000570617F20779E73F0030AFFB4FD5D33F9F +:1075D0000C13D6DBCA56E73F00E02FE3EE32D43F70 +:1075E0006BB64F010010E63F3C5B42916C027E3C63 +:1075F00095B44D030030E63F415D0048EABF8D3C45 +:1076000078D4940D0050E63FB7A5D686A77F8E3C70 +:10761000AD6F4E070070E63F4C25546BEAFC613CB1 +:10762000AE0FDFFEFF8FE63FFD0E594C277E7CBC80 +:10763000BCC5630700B0E63F01DADC4868C18ABC1C +:10764000F6C15C1E00D0E63F1193499D1C3F833C70 +:107650003EF605EBFFEFE63F532DE21A04807EBCB9 +:107660008097860E0010E73F5279097166FF7B3CD8 +:1076700012E967FCFF2FE73F2487BD26E2008C3C20 +:107680006A1181DFFF4FE73FD201F16E91026EBCBC +:10769000909C670F0070E73F749C54CD71FC67BCF1 +:1076A00035C87EFAFF8FE73F8304F59EC1BE813C5B +:1076B000E6C220FEFFAFE73F6564CC29177E70BCB1 +:1076C00000C93FEDFFCFE73F1C8B7B08728080BC79 +:1076D000761A26E9FFEFE73FAEF99D6D28C08D3C95 +:1076E000E8A39C040010E83F334CE551D27F893C6D +:1076F0008F2C93170030E83F81F330B6E9FE8ABC47 +:107700009C7333060050E83FBC35656BBFBF893CB6 +:10771000C68942200070E83F757B11F365BF8BBCC2 +:107720000479F5EBFF8FE83F57CB3DA26E0089BC93 +:10773000DF04BC2200B0E83F0A4BE038DF007DBC2C +:107740008A1B0CE5FFCFE83F059FFF46710088BC10 +:10775000438E91FCFFEFE83F38707AD07B81833C09 +:10776000C75FFA1E0010E93F03B4DF76913E893C03 +:10777000B97B46130030E93F7602984B4E807F3C40 +:107780006F07EEE6FF4FE93F2E62FFD9F07E8FBC18 +:10779000D1123CDEFF6FE93FBA382696AA8270BC50 +:1077A0000D8A45F4FF8FE93FEFA864911B8087BCE9 +:1077B0003E2E98DDFFAFE93F37935A8AE04087BC01 +:1077C00066FB49EDFFCFE93F00E09BC108CE3F3C9F +:1077D000519CF12000F0E93F0A5B8827AA3F8ABC50 +:1077E00006B045110010EA3F56DA589948FF743C3C +:1077F000FAF6BB070030EA3F186D2B8AABBE8C3C13 +:10780000791D97100050EA3F307978DDCAFE883C38 +:10781000482EF51D0070EA3FDBABD83D76418FBCAA +:107820005233591C0090EA3F1276C28402BF8EBCCC +:107830004B3E4F2A00B0EA3F5F3FFF3C04FD69BC6E +:10784000D11EAED7FFCFEA3FB4709012E73E82BCA4 +:10785000780451EEFFEFEA3FA3DE0EE03E066A3CFD +:107860005B0D65DBFF0FEB3FB90A1F38C8065A3CBA +:1078700057CAAAFEFF2FEB3F1D3C23741E0179BCA3 +:10788000DCBA95D9FF4FEB3F9F2A866810FF79BC81 +:107890009C659E240070EB3F3E4F86D045FF8A3C9E +:1078A000401687F9FF8FEB3FF9C3C29677FE7C3C09 +:1078B0004FCB04D2FFAFEB3FC42BF2EE27FF63BCEC +:1078C000455C41D2FFCFEB3F21EA3BEEB7FF6CBCFA +:1078D000DF0963F8FFEFEB3F5C0B2E97034181BCA0 +:1078E0005376B5E1FF0FEC3F196AB79464C18B3C46 +:1078F000E357FAF1FF2FEC3FEDC6308DEFFE64BC8D +:1079000024E4BFDCFF4FEC3F7547ECBC683F84BC10 +:10791000F7B954EDFF6FEC3FECE053F0A37E843CED +:10792000D58F99EBFF8FEC3FF192F98D0683733C75 +:107930009A21252100B0EC3F040E18648EFD68BC2E +:107940009C4694DDFFCFEC3F72EAC71CBE7E8E3CA6 +:1079500076C4FDEAFFEFEC3FFE889FAD39BE8E3C5A +:107960002BF89A160010ED3F715AB9A8917D753C1D +:107970001DF70F0D0030ED3FDAC7706990C1893CEB +:10798000C40F79EAFF4FED3F0CFE58C5370E58BCC7 +:10799000E587DC2E0070ED3F440FC14DD6807FBCE3 +:1079A000AA82DC210090ED3F5C5CFD948F7C74BC6E +:1079B00083026BD8FFAFED3F7E6121C51D7F8C3CFC +:1079C00039476C2900D0ED3F53B1FFB29E01883C8E +:1079D000F59044E5FFEFED3F89CC52C6D2006E3CF6 +:1079E00094F6ABCDFF0FEE3FD2692D2040837FBCD4 +:1079F000DDC852DBFF2FEE3F64081BCAC1007B3C91 +:107A0000EF1642F2FF4FEE3F51AB94B0A8FF723C2D +:107A1000115E8AE8FF6FEE3F59BEEFB173F657BCB7 +:107A20000DFF9E110090EE3F01C80B5E8D8084BC5F +:107A30004417A5DFFFAFEE3FB52043D50600783CE5 +:107A4000A17F121A00D0EE3F925C5660F80250BC43 +:107A5000C4BCBA0700F0EE3F11E6355D444085BC7A +:107A6000028D7AF5FF0FEF3F0591EF3931FB4FBCE7 +:107A7000C78AE51E0030EF3F551173F2AC818A3C96 +:107A8000943482F5FF4FEF3F43C7D7D4413F8A3C40 +:107A90006B4CA9FCFF6FEF3F7578981CF40262BC39 +:107AA00041C4F9E1FF8FEF3F4BE777F4D17D773C9D +:107AB0007EE3E0D2FFAFEF3F31A37C9A19016FBCA8 +:107AC0009EE4771C00D0EF3FB1ACCE4BEE81713C11 +:107AD00031C3E0F7FFEFEF3F5A87700137056EBC07 +:107AE0006E6065F4FF0FF03FDA0A1C49AD7E8ABC78 +:107AF000587A86F3FF2FF03FE0B2FCC3697F97BC52 +:107B0000170DFCFDFF4FF03F5B94CB34FEBF973C5D +:107B1000824DCD030070F03FCB56E4C08300823C21 +:107B2000E8CBF2F9FF8FF03F1A7537BEDFFF6DBC6F +:107B300065DA0C0100B0F03FEB26E6AE7F3F91BC6A +:107B400038D3A40100D0F03FF79F4879FA7D803CFC +:107B5000FDFDDAFAFFEFF03FC06BD670050477BC8D +:107B600096FDBA0B0010F13F620B6D84D4808E3C01 +:107B70005DF4E5FAFF2FF13FEF36FD64FABF9D3C5F +:107B8000D99AD50D0050F13FAE50127077009A3C53 +:107B90009A55210F0070F13FEEDEE3E2F9FD8D3CD6 +:107BA000265427FCFF8FF13F73723BDC3000913C81 +:107BB000593C3D1200B0F13F88010380797F993C28 +:107BC000B79E29F8FFCFF13F678C9FAB32F965BCB8 +:107BD00000D48AF4FFEFF13FEB5BA79DBF7F933C9E +:107BE000A4868B0C0010F23F225BFD916B809F3CC2 +:107BF000034385030030F23F33BF9FEBC2FF933C4A +:107C000084F6BCFFFF4FF23F722E2E7EE701763CDA +:107C1000D92129F5FF6FF23F610C7F76BBFC7F3CD9 +:107C20003C3A93140090F23F2B41023CCA0272BCD2 +:107C30001363551400B0F23F021FF233828092BCEE +:107C40003B52FEEBFFCFF23FF2DC4F387EFF88BCA9 +:107C500096ADB80B00F0F23FC541305051FF85BCE6 +:107C6000AFE27AFBFF0FF33F9D285E88710081BC75 +:107C70007F5FACFEFF2FF33F15B7B73F5DFF91BCB1 +:107C80005667A60C0050F33FBD828B22827F953C45 +:107C900021F7FB110070F33FCCD50DC4BA00803C36 +:107CA000B92F59F9FF8FF33F51A7B22D9D3F94BCD7 +:107CB00042D2DD0400B0F33FE13876706B7F853C43 +:107CC00057C9B2F5FFCFF33F3112BF103A027A3CE9 +:107CD00018B4B0EAFFEFF33FB052B1666D7F983C45 +:107CE000F4AF32150010F43F2485195F37F8673C74 +:107CF000298B47170030F43F4351DC72E601833C87 +:107D000063B495E7FF4FF43F5A89B2B869FF893CE5 +:107D1000E07504E8FF6FF43F54F2C29BB1C095BC1C +:107D2000E7C16FEFFF8FF43F722A3AF209409B3CA4 +:107D300004A7BEE5FFAFF43F457D0DBFB7FF94BC80 +:107D4000DE27101700D0F43F3D6ADC7164C099BC97 +:107D5000E23EF00F00F0F43F1C53850B897F973C07 +:107D6000D14BDC120010F53F36A466716504603C0F +:107D70007A2705160030F53F093223CECEBF96BCD8 +:107D80004C70DBECFF4FF53FD7A10505720289BCB3 +:107D9000A9545FEFFF6FF53F1264C90EE6BF9B3C2D +:107DA0001210E6170090F53F90EFAF81C57E883C3A +:107DB000923EC90300B0F53FC00CBF0A08419FBC0A +:107DC000BC19491D00D0F53F294725FB2A8198BCE5 +:107DD000897AB8E7FFEFF53F0469ED80B77E94BC80 +:107DE0000000000000000000000000000000000093 +:107DF0000000000000000000000000000000000083 +:107E00000000000000000000000000000000000072 +:107E10000000000000000000000000000000000062 +:107E20000000000000000000000000000000000052 +:107E30000000000000000000000000000000000042 +:107E40000000000000000000000000000000000032 +:107E50000000000000000000000000000000000022 +:107E60000000000000000000000000000000000012 +:107E70000000000000000000000000000000000002 +:107E800000000000000000000000000000000000F2 +:107E900000000000000000000000000000000000E2 +:107EA00000000000000000000000000000000000D2 +:107EB00000000000000000000000000000000000C2 +:107EC00000000000000000000000000000000000B2 +:107ED00000000000000000000000000000000000A2 +:107EE0000000000000000000000000000000000092 +:107EF0000000000000000000000000000000000082 +:107F00000000000000000000000000000000000071 +:107F10000000000000000000000000000000000061 +:107F20000000000000000000000000000000000051 +:107F30000000000000000000000000000000000041 +:107F40000000000000000000000000000000000031 +:107F50000000000000000000000000000000000021 +:107F60000000000000000000000000000000000011 +:107F70000000000000000000000000000000000001 +:107F800000000000000000000000000000000000F1 +:107F900000000000000000000000000000000000E1 +:107FA00000000000000000000000000000000000D1 +:107FB00000000000000000000000000000000000C1 +:107FC00000000000000000000000000000000000B1 +:107FD00000000000000000000000000000000000A1 +:107FE0000000000000000000000000000000000091 +:107FF0000000000000000000000000000000000081 +:108000000000000000000000000000000000000070 +:108010000000000000000000000000000000000060 +:108020000000000000000000000000000000000050 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:1080800000000000000000000000000000000000F0 +:1080900000000000000000000000000000000000E0 +:1080A00000000000000000000000000000000000D0 +:1080B00000000000000000000000000000000000C0 +:1080C00000000000000000000000000000000000B0 +:1080D00000000000000000000000000000000000A0 +:1080E0000000000000000000000000000000000090 +:1080F0000000000000000000000000000000000080 +:10810000000000000000000000000000000000006F +:10811000000000000000000000000000000000005F +:10812000000000000000000000000000000000004F +:10813000000000000000000000000000000000003F +:10814000000000000000000000000000000000002F +:10815000000000000000000000000000000000001F +:10816000000000000000000000000000000000000F +:1081700000000000000000000000000000000000FF +:1081800000000000000000000000000000000000EF +:1081900000000000000000000000000000000000DF +:1081A00000000000000000000000000000000000CF +:1081B00000000000000000000000000000000000BF +:1081C00000000000000000000000000000000000AF +:1081D000000000000000000000000000000000009F +:1081E000000000000000000000000000000000008F +:1081F000000000000000000000000000000000007F +:10820000000000000000000000000000000000006E +:10821000000000000000000000000000000000005E +:10822000000000000000000000000000000000004E +:10823000000000000000000000000000000000003E +:10824000000000000000000000000000000000002E +:10825000000000000000000000000000000000001E +:10826000000000000000000000000000000000000E +:1082700000000000000000000000000000000000FE +:1082800000000000000000000000000000000000EE +:1082900000000000000000000000000000000000DE +:1082A00000000000000000000000000000000000CE +:1082B00000000000000000000000000000000000BE +:1082C00000000000000000000000000000000000AE +:1082D000000000000000000000000000000000009E +:1082E000000000000000000000000000000000008E +:1082F000000000000000000000000000000000007E +:10830000000000000000000000000000000000006D +:10831000000000000000000000000000000000005D +:10832000000000000000000000000000000000004D +:10833000000000000000000000000000000000003D +:10834000000000000000000000000000000000002D +:10835000000000000000000000000000000000001D +:10836000000000000000000000000000000000000D +:1083700000000000000000000000000000000000FD +:1083800000000000000000000000000000000000ED +:1083900000000000000000000000000000000000DD +:1083A00000000000000000000000000000000000CD +:1083B00000000000000000000000000000000000BD +:1083C00000000000000000000000000000000000AD +:1083D000000000000000000000000000000000009D +:1083E000000000000000000000000000000000008D +:1083F000000000000000000000000000000000007D +:10840000000000000000000000000000000000006C +:10841000000000000000000000000000000000005C +:10842000000000000000000000000000000000004C +:10843000000000000000000000000000000000003C +:10844000000000000000000000000000000000002C +:10845000000000000000000000000000000000001C +:10846000000000000000000000000000000000000C +:1084700000000000000000000000000000000000FC +:1084800000000000000000000000000000000000EC +:1084900000000000000000000000000000000000DC +:1084A00000000000000000000000000000000000CC +:1084B00000000000000000000000000000000000BC +:1084C00000000000000000000000000000000000AC +:1084D000000000000000000000000000000000009C +:1084E000000000000000000000000000000000008C +:1084F000000000000000000000000000000000007C +:10850000000000000000000000000000000000006B +:10851000000000000000000000000000000000005B +:10852000000000000000000000000000000000004B +:10853000000000000000000000000000000000003B +:10854000000000000000000000000000000000002B +:10855000000000000000000000000000000000001B +:10856000000000000000000000000000000000000B +:1085700000000000000000000000000000000000FB +:1085800000000000000000000000000000000000EB +:1085900000000000000000000000000000000000DB +:1085A00000000000000000000000000000000000CB +:1085B00000000000000000000000000000000000BB +:1085C00000000000000000000000000000000000AB +:1085D000000000000000000000000000000000009B +:1085E000000000000000000000000000000000008B +:1085F000000000000000000000000000000000007B +:10860000000000000000000000000000000000006A +:10861000000000000000000000000000000000005A +:10862000000000000000000000000000000000004A +:10863000000000000000000000000000000000003A +:10864000000000000000000000000000000000002A +:10865000000000000000000000000000000000001A +:10866000000000000000000000000000000000000A +:1086700000000000000000000000000000000000FA +:1086800000000000000000000000000000000000EA +:1086900000000000000000000000000000000000DA +:1086A00000000000000000000000000000000000CA +:1086B00000000000000000000000000000000000BA +:1086C00000000000000000000000000000000000AA +:1086D000000000000000000000000000000000009A +:1086E000000000000000000000000000000000008A +:1086F000000000000000000000000000000000007A +:108700000000000000000000000000000000000069 +:108710000000000000000000000000000000000059 +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:108740000000000000000000000000000000000029 +:108750000000000000000000000000000000000019 +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800000000000000000000000000000000000E9 +:1087900000000000000000000000000000000000D9 +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00000000000000000000000000000000000A9 +:1087D0000000000000000000000000000000000099 +:1087E0000000000000000000000000000000000089 +:1087F0000000000000000000000000000000000079 +:108800000000000000000000000000000000000068 +:108810000000000000000000000000000000000058 +:108820000000000000000000000000000000000048 +:108830000000000000000000000000000000000038 +:108840000000000000000000000000000000000028 +:108850000000000000000000000000000000000018 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800000000000000000000000000000000000E8 +:1088900000000000000000000000000000000000D8 +:1088A00000000000000000000000000000000000C8 +:1088B00000000000000000000000000000000000B8 +:1088C00000000000000000000000000000000000A8 +:1088D0000000000000000000000000000000000098 +:1088E0000000000000000000000000000000000088 +:1088F0000000000000000000000000000000000078 +:108900000000000000000000000000000000000067 +:108910000000000000000000000000000000000057 +:108920000000000000000000000000000000000047 +:108930000000000000000000000000000000000037 +:108940000000000000000000000000000000000027 +:108950000000000000000000000000000000000017 +:108960000000000000000000000000000000000007 +:1089700000000000000000000000000000000000F7 +:1089800000000000000000000000000000000000E7 +:1089900000000000000000000000000000000000D7 +:1089A00000000000000000000000000000000000C7 +:1089B00000000000000000000000000000000000B7 +:1089C00000000000000000000000000000000000A7 +:1089D0000000000000000000000000000000000097 +:1089E0000000000000000000000000000000000087 +:1089F0000000000000000000000000000000000077 +:108A00000000000000000000000000000000000066 +:108A10000000000000000000000000000000000056 +:108A20000000000000000000000000000000000046 +:108A30000000000000000000000000000000000036 +:108A40000000000000000000000000000000000026 +:108A50000000000000000000000000000000000016 +:108A60000000000000000000000000000000000006 +:108A700000000000000000000000000000000000F6 +:108A800000000000000000000000000000000000E6 +:108A900000000000000000000000000000000000D6 +:108AA00000000000000000000000000000000000C6 +:108AB00000000000000000000000000000000000B6 +:108AC00000000000000000000000000000000000A6 +:108AD0000000000000000000000000000000000096 +:108AE0000000000000000000000000000000000086 +:108AF0000000000000000000000000000000000076 +:108B00000000000000000000000000000000000065 +:108B10000000000000000000000000000000000055 +:108B20000000000000000000000000000000000045 +:108B30000000000000000000000000000000000035 +:108B40000000000000000000000000000000000025 +:108B50000000000000000000000000000000000015 +:108B60000000000000000000000000000000000005 +:108B700000000000000000000000000000000000F5 +:108B800000000000000000000000000000000000E5 +:108B900000000000000000000000000000000000D5 +:108BA00000000000000000000000000000000000C5 +:108BB00000000000000000000000000000000000B5 +:108BC00000000000000000000000000000000000A5 +:108BD0000000000000000000000000000000000095 +:108BE0000000000000000000000000000000000085 +:108BF0000000000000000000000000000000000075 +:108C00000000000000000000000000000000000064 +:108C10000000000000000000000000000000000054 +:108C20000000000000000000000000000000000044 +:108C30000000000000000000000000000000000034 +:108C40000000000000000000000000000000000024 +:108C50000000000000000000000000000000000014 +:108C60000000000000000000000000000000000004 +:108C700000000000000000000000000000000000F4 +:108C800000000000000000000000000000000000E4 +:108C900000000000000000000000000000000000D4 +:108CA00000000000000000000000000000000000C4 +:108CB00000000000000000000000000000000000B4 +:108CC00000000000000000000000000000000000A4 +:108CD0000000000000000000000000000000000094 +:108CE0000000000000000000000000000000000084 +:108CF0000000000000000000000000000000000074 +:108D00000000000000000000000000000000000063 +:108D10000000000000000000000000000000000053 +:108D20000000000000000000000000000000000043 +:108D30000000000000000000000000000000000033 +:108D40000000000000000000000000000000000023 +:108D50000000000000000000000000000000000013 +:108D60000000000000000000000000000000000003 +:108D700000000000000000000000000000000000F3 +:108D800000000000000000000000000000000000E3 +:108D900000000000000000000000000000000000D3 +:108DA00000000000000000000000000000000000C3 +:108DB00000000000000000000000000000000000B3 +:108DC00000000000000000000000000000000000A3 +:108DD0000000000000000000000000000000000093 +:108DE0000000000000000000000000000000000083 +:108DF0000000000000000000000000000000000073 +:108E00000000000000000000000000000000000062 +:108E10000000000000000000000000000000000052 +:108E20000000000000000000000000000000000042 +:108E30000000000000000000000000000000000032 +:108E40000000000000000000000000000000000022 +:108E50000000000000000000000000000000000012 +:108E60000000000000000000000000000000000002 +:108E700000000000000000000000000000000000F2 +:108E800000000000000000000000000000000000E2 +:108E900000000000000000000000000000000000D2 +:108EA00000000000000000000000000000000000C2 +:108EB00000000000000000000000000000000000B2 +:108EC00000000000000000000000000000000000A2 +:108ED0000000000000000000000000000000000092 +:108EE0000000000000000000000000000000000082 +:108EF0000000000000000000000000000000000072 +:108F00000000000000000000000000000000000061 +:108F10000000000000000000000000000000000051 +:108F20000000000000000000000000000000000041 +:108F30000000000000000000000000000000000031 +:108F40000000000000000000000000000000000021 +:108F50000000000000000000000000000000000011 +:108F60000000000000000000000000000000000001 +:108F700000000000000000000000000000000000F1 +:108F800000000000000000000000000000000000E1 +:108F900000000000000000000000000000000000D1 +:108FA00000000000000000000000000000000000C1 +:108FB00000000000000000000000000000000000B1 +:108FC00000000000000000000000000000000000A1 +:108FD0000000000000000000000000000000000091 +:108FE0000000000000000000000000000000000081 +:108FF0000000000000000000000000000000000071 +:109000000000000000000000000000000000000060 +:109010000000000000000000000000000000000050 +:109020000000000000000000000000000000000040 +:109030000000000000000000000000000000000030 +:109040000000000000000000000000000000000020 +:109050000000000000000000000000000000000010 +:109060000000000000000000000000000000000000 +:1090700000000000000000000000000000000000F0 +:1090800000000000000000000000000000000000E0 +:1090900000000000000000000000000000000000D0 +:1090A00000000000000000000000000000000000C0 +:1090B00000000000000000000000000000000000B0 +:1090C00000000000000000000000000000000000A0 +:1090D0000000000000000000000000000000000090 +:1090E0000000000000000000000000000000000080 +:1090F0000000000000000000000000000000000070 +:10910000000000000000000000000000000000005F +:10911000000000000000000000000000000000004F +:10912000000000000000000000000000000000003F +:10913000000000000000000000000000000000002F +:10914000000000000000000000000000000000001F +:10915000000000000000000000000000000000000F +:1091600000000000000000000000000000000000FF +:1091700000000000000000000000000000000000EF +:1091800000000000000000000000000000000000DF +:1091900000000000000000000000000000000000CF +:1091A00000000000000000000000000000000000BF +:1091B00000000000000000000000000000000000AF +:1091C000000000000000000000000000000000009F +:1091D000000000000000000000000000000000008F +:1091E000000000000000000000000000000000007F +:1091F000000000000000000000000000000000006F +:10920000000000000000000000000000000000005E +:10921000000000000000000000000000000000004E +:10922000000000000000000000000000000000003E +:10923000000000000000000000000000000000002E +:10924000000000000000000000000000000000001E +:10925000000000000000000000000000000000000E +:1092600000000000000000000000000000000000FE +:1092700000000000000000000000000000000000EE +:1092800000000000000000000000000000000000DE +:1092900000000000000000000000000000000000CE +:1092A00000000000000000000000000000000000BE +:1092B00000000000000000000000000000000000AE +:1092C000000000000000000000000000000000009E +:1092D000000000000000000000000000000000008E +:1092E000000000000000000000000000000000007E +:1092F000000000000000000000000000000000006E +:10930000000000000000000000000000000000005D +:10931000000000000000000000000000000000004D +:10932000000000000000000000000000000000003D +:10933000000000000000000000000000000000002D +:10934000000000000000000000000000000000001D +:10935000000000000000000000000000000000000D +:1093600000000000000000000000000000000000FD +:1093700000000000000000000000000000000000ED +:1093800000000000000000000000000000000000DD +:1093900000000000000000000000000000000000CD +:1093A00000000000000000000000000000000000BD +:1093B00000000000000000000000000000000000AD +:1093C000000000000000000000000000000000009D +:1093D000000000000000000000000000000000008D +:1093E000000000000000000000000000000000007D +:1093F000000000000000000000000000000000006D +:10940000000000000000000000000000000000005C +:10941000000000000000000000000000000000004C +:10942000000000000000000000000000000000003C +:10943000000000000000000000000000000000002C +:10944000000000000000000000000000000000001C +:10945000000000000000000000000000000000000C +:1094600000000000000000000000000000000000FC +:1094700000000000000000000000000000000000EC +:1094800000000000000000000000000000000000DC +:1094900000000000000000000000000000000000CC +:1094A00000000000000000000000000000000000BC +:1094B00000000000000000000000000000000000AC +:1094C000000000000000000000000000000000009C +:1094D000000000000000000000000000000000008C +:1094E000000000000000000000000000000000007C +:1094F000000000000000000000000000000000006C +:10950000000000000000000000000000000000005B +:10951000000000000000000000000000000000004B +:10952000000000000000000000000000000000003B +:10953000000000000000000000000000000000002B +:10954000000000000000000000000000000000001B +:10955000000000000000000000000000000000000B +:1095600000000000000000000000000000000000FB +:1095700000000000000000000000000000000000EB +:1095800000000000000000000000000000000000DB +:1095900000000000000000000000000000000000CB +:1095A00000000000000000000000000000000000BB +:1095B00000000000000000000000000000000000AB +:1095C000000000000000000000000000000000009B +:1095D000000000000000000000000000000000008B +:1095E000000000000000000000000000000000007B +:1095F000000000000000000000000000000000006B +:10960000000000000000000000000000000000005A +:10961000000000000000000000000000000000004A +:10962000000000000000000000000000000000003A +:10963000000000000000000000000000000000002A +:10964000000000000000000000000000000000001A +:10965000000000000000000000000000000000000A +:1096600000000000000000000000000000000000FA +:1096700000000000000000000000000000000000EA +:1096800000000000000000000000000000000000DA +:1096900000000000000000000000000000000000CA +:1096A00000000000000000000000000000000000BA +:1096B00000000000000000000000000000000000AA +:1096C000000000000000000000000000000000009A +:1096D000000000000000000000000000000000008A +:1096E000000000000000000000000000000000007A +:1096F000000000000000000000000000000000006A +:109700000000000000000000000000000000000059 +:109710000000000000000000000000000000000049 +:109720000000000000000000000000000000000039 +:109730000000000000000000000000000000000029 +:109740000000000000000000000000000000000019 +:109750000000000000000000000000000000000009 +:1097600000000000000000000000000000000000F9 +:1097700000000000000000000000000000000000E9 +:1097800000000000000000000000000000000000D9 +:1097900000000000000000000000000000000000C9 +:1097A00000000000000000000000000000000000B9 +:1097B00000000000000000000000000000000000A9 +:1097C0000000000000000000000000000000000099 +:1097D0000000000000000000000000000000000089 +:1097E0000000000000000000000000000000000079 +:1097F0000000000000000000000000000000000069 +:109800000000000000000000000000000000000058 +:109810000000000000000000000000000000000048 +:109820000000000000000000000000000000000038 +:109830000000000000000000000000000000000028 +:109840000000000000000000000000000000000018 +:109850000000000000000000000000000000000008 +:1098600000000000000000000000000000000000F8 +:1098700000000000000000000000000000000000E8 +:1098800000000000000000000000000000000000D8 +:1098900000000000000000000000000000000000C8 +:1098A00000000000000000000000000000000000B8 +:1098B00000000000000000000000000000000000A8 +:1098C0000000000000000000000000000000000098 +:1098D0000000000000000000000000000000000088 +:1098E0000000000000000000000000000000000078 +:1098F0000000000000000000000000000000000068 +:109900000000000000000000000000000000000057 +:109910000000000000000000000000000000000047 +:109920000000000000000000000000000000000037 +:109930000000000000000000000000000000000027 +:109940000000000000000000000000000000000017 +:109950000000000000000000000000000000000007 +:1099600000000000000000000000000000000000F7 +:1099700000000000000000000000000000000000E7 +:1099800000000000000000000000000000000000D7 +:1099900000000000000000000000000000000000C7 +:1099A00000000000000000000000000000000000B7 +:1099B00000000000000000000000000000000000A7 +:1099C0000000000000000000000000000000000097 +:1099D0000000000000000000000000000000000087 +:1099E0000000000000000000000000000000000077 +:1099F0000000000000000000000000000000000067 +:109A00000000000000000000000000000000000056 +:109A10000000000000000000000000000000000046 +:109A20000000000000000000000000000000000036 +:109A30000000000000000000000000000000000026 +:109A40000000000000000000000000000000000016 +:109A50000000000000000000000000000000000006 +:109A600000000000000000000000000000000000F6 +:109A700000000000000000000000000000000000E6 +:109A800000000000000000000000000000000000D6 +:109A900000000000000000000000000000000000C6 +:109AA00000000000000000000000000000000000B6 +:109AB00000000000000000000000000000000000A6 +:109AC0000000000000000000000000000000000096 +:109AD0000000000000000000000000000000000086 +:109AE0000000000000000000000000000000000076 +:109AF0000000000000000000000000000000000066 +:109B00000000000000000000000000000000000055 +:109B10000000000000000000000000000000000045 +:109B20000000000000000000000000000000000035 +:109B30000000000000000000000000000000000025 +:109B40000000000000000000000000000000000015 +:109B50000000000000000000000000000000000005 +:109B600000000000000000000000000000000000F5 +:109B700000000000000000000000000000000000E5 +:109B800000000000000000000000000000000000D5 +:109B900000000000000000000000000000000000C5 +:109BA00000000000000000000000000000000000B5 +:109BB00000000000000000000000000000000000A5 +:109BC0000000000000000000000000000000000095 +:109BD0000000000000000000000000000000000085 +:109BE0000000000000000000000000000000000075 +:109BF0000000000000000000000000000000000065 +:109C00000000000000000000000000000000000054 +:109C10000000000000000000000000000000000044 +:109C20000000000000000000000000000000000034 +:109C30000000000000000000000000000000000024 +:109C40000000000000000000000000000000000014 +:109C50000000000000000000000000000000000004 +:109C600000000000000000000000000000000000F4 +:109C700000000000000000000000000000000000E4 +:109C800000000000000000000000000000000000D4 +:109C900000000000000000000000000000000000C4 +:109CA00000000000000000000000000000000000B4 +:109CB00000000000000000000000000000000000A4 +:109CC0000000000000000000000000000000000094 +:109CD0000000000000000000000000000000000084 +:109CE0000000000000000000000000000000000074 +:109CF0000000000000000000000000000000000064 +:109D00000000000000000000000000000000000053 +:109D10000000000000000000000000000000000043 +:109D20000000000000000000000000000000000033 +:109D30000000000000000000000000000000000023 +:109D40000000000000000000000000000000000013 +:109D50000000000000000000000000000000000003 +:109D600000000000000000000000000000000000F3 +:109D700000000000000000000000000000000000E3 +:109D800000000000000000000000000000000000D3 +:109D900000000000000000000000000000000000C3 +:109DA00000000000000000000000000000000000B3 +:109DB00000000000000000000000000000000000A3 +:109DC0000000000000000000000000000000000093 +:109DD0000000000000000000000000000000000083 +:109DE0000000000000000000000000000000000073 +:109DF0000000000000000000000000000000000063 +:109E00000000000000000000000000000000000052 +:109E10000000000000000000000000000000000042 +:109E20000000000000000000000000000000000032 +:109E30000000000000000000000000000000000022 +:109E40000000000000000000000000000000000012 +:109E50000000000000000000000000000000000002 +:109E600000000000000000000000000000000000F2 +:109E700000000000000000000000000000000000E2 +:109E800000000000000000000000000000000000D2 +:109E900000000000000000000000000000000000C2 +:109EA00000000000000000000000000000000000B2 +:109EB00000000000000000000000000000000000A2 +:109EC0000000000000000000000000000000000092 +:109ED0000000000000000000000000000000000082 +:109EE0000000000000000000000000000000000072 +:109EF0000000000000000000000000000000000062 +:109F00000000000000000000000000000000000051 +:109F10000000000000000000000000000000000041 +:109F20000000000000000000000000000000000031 +:109F30000000000000000000000000000000000021 +:109F40000000000000000000000000000000000011 +:109F50000000000000000000000000000000000001 +:109F600000000000000000000000000000000000F1 +:109F700000000000000000000000000000000000E1 +:109F800000000000000000000000000000000000D1 +:109F900000000000000000000000000000000000C1 +:109FA00000000000000000000000000000000000B1 +:109FB00000000000000000000000000000000000A1 +:109FC0000000000000000000000000000000000091 +:109FD0000000000000000000000000000000000081 +:109FE0000000000000000000000000000000000071 +:109FF0000000000000000000000000000000000061 +:10A000000000000000000000000000000000000050 +:10A010000000000000000000000000000000000040 +:10A020000000000000000000000000000000000030 +:10A030000000000000000000000000000000000020 +:10A040000000000000000000000000000000000010 +:10A050000000000000000000000000000000000000 +:10A0600000000000000000000000000000000000F0 +:10A0700000000000000000000000000000000000E0 +:10A0800000000000000000000000000000000000D0 +:10A0900000000000000000000000000000000000C0 +:10A0A00000000000000000000000000000000000B0 +:10A0B00000000000000000000000000000000000A0 +:10A0C0000000000000000000000000000000000090 +:10A0D0000000000000000000000000000000000080 +:10A0E0000000000000000000000000000000000070 +:10A0F0000000000000000000000000000000000060 +:10A10000000000000000000000000000000000004F +:10A11000000000000000000000000000000000003F +:10A12000000000000000000000000000000000002F +:10A13000000000000000000000000000000000001F +:10A14000000000000000000000000000000000000F +:10A1500000000000000000000000000000000000FF +:10A1600000000000000000000000000000000000EF +:10A1700000000000000000000000000000000000DF +:10A1800000000000000000000000000000000000CF +:10A1900000000000000000000000000000000000BF +:10A1A00000000000000000000000000000000000AF +:10A1B000000000000000000000000000000000009F +:10A1C000000000000000000000000000000000008F +:10A1D000000000000000000000000000000000007F +:10A1E000000000000000000000000000000000006F +:10A1F000000000000000000000000000000000005F +:10A20000000000000000000000000000000000004E +:10A21000000000000000000000000000000000003E +:10A22000000000000000000000000000000000002E +:10A23000000000000000000000000000000000001E +:10A24000000000000000000000000000000000000E +:10A2500000000000000000000000000000000000FE +:10A2600000000000000000000000000000000000EE +:10A2700000000000000000000000000000000000DE +:10A2800000000000000000000000000000000000CE +:10A2900000000000000000000000000000000000BE +:10A2A00000000000000000000000000000000000AE +:10A2B000000000000000000000000000000000009E +:10A2C000000000000000000000000000000000008E +:10A2D000000000000000000000000000000000007E +:10A2E000000000000000000000000000000000006E +:10A2F000000000000000000000000000000000005E +:10A30000000000000000000000000000000000004D +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000000000000000000076 +:10AAE0000000000000000000000000000000000066 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB20000000000000000000000000000000000025 +:10AB30000000000000000000000000000000000015 +:10AB40000000000000000000000000000000000005 +:10AB500000000000000000000000000000000000F5 +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00000000000000000000000000000000000A5 +:10ABB0000000000000000000000000000000000095 +:10ABC0000000000000000000000000000000000085 +:10ABD0000000000000000000000000000000000075 +:10ABE0000000000000000000000000000000000065 +:10ABF0000000000000000000000000000000000055 +:10AC00000000000000000000000000000000000044 +:10AC10000000000000000000000000000000000034 +:10AC20000000000000000000000000000000000024 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF0000000000000000000000000000000000051 +:10B000000000000000000000000000000000000040 +:10B010000000000000000000000000000000000030 +:10B020000000000000000000000000000000000020 +:10B030000000000000000000000000000000000010 +:10B040000000000000000000000000000000000000 +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B0900000000000000000000000000000000000B0 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F000000000000000000000000000000000000000 +:10F0100000000000000000000000000000000000F0 +:10F0200000000000000000000000000000000000E0 +:10F0300000000000000000000000000000000000D0 +:10F0400000000000000000000000000000000000C0 +:10F0500000000000000000000000000000000000B0 +:10F0600000000000000000000000000000000000A0 +:10F070000000000000000000000000000000000090 +:10F080000000000000000000000000000000000080 +:10F090000000000000000000000000000000000070 +:10F0A0000000000000000000000000000000000060 +:10F0B0000000000000000000000000000000000050 +:10F0C0000000000000000000000000000000000040 +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000000000000000000020 +:10F0F0000000000000000000000000000000000010 +:10F1000000000000000000000000000000000000FF +:10F1100000000000000000000000000000000000EF +:10F1200000000000000000000000000000000000DF +:10F1300000000000000000000000000000000000CF +:10F1400000000000000000000000000000000000BF +:10F1500000000000000000000000000000000000AF +:10F16000000000000000000000000000000000009F +:10F17000000000000000000000000000000000008F +:10F18000000000000000000000000000000000007F +:10F19000000000000000000000000000000000006F +:10F1A000000000000000000000000000000000005F +:10F1B000000000000000000000000000000000004F +:10F1C000000000000000000000000000000000003F +:10F1D000000000000000000000000000000000002F +:10F1E000000000000000000000000000000000001F +:10F1F000000000000000000000000000000000000F +:10F2000000000000000000000000000000000000FE +:10F2100000000000000000000000000000000000EE +:10F2200000000000000000000000000000000000DE +:10F2300000000000000000000000000000000000CE +:10F2400000000000000000000000000000000000BE +:10F2500000000000000000000000000000000000AE +:10F26000000000000000000000000000000000009E +:10F27000000000000000000000000000000000008E +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F000000000000000000000000000000000000E +:10F3000000000000000000000000000000000000FD +:10F3100000000000000000000000000000000000ED +:10F3200000000000000000000000000000000000DD +:10F3300000000000000000000000000000000000CD +:10F3400000000000000000000000000000000000BD +:10F3500000000000000000000000000000000000AD +:10F36000000000000000000000000000000000009D +:10F37000000000000000000000000000000000008D +:10F38000000000000000000000000000000000007D +:10F39000000000000000000000000000000000006D +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D000000000000000000000000000000000002D +:10F3E000000000000000000000000000000000001D +:10F3F000000000000000000000000000000000000D +:10F4000000000000000000000000000000000000FC +:10F4100000000000000000000000000000000000EC +:10F4200000000000000000000000000000000000DC +:10F4300000000000000000000000000000000000CC +:10F4400000000000000000000000000000000000BC +:10F4500000000000000000000000000000000000AC +:10F46000000000000000000000000000000000009C +:10F47000000000000000000000000000000000008C +:10F48000000000000000000000000000000000007C +:10F49000000000000000000000000000000000006C +:10F4A000000000000000000000000000000000005C +:10F4B000000000000000000000000000000000004C +:10F4C000000000000000000000000000000000003C +:10F4D000000000000000000000000000000000002C +:10F4E000000000000000000000000000000000001C +:10F4F000000000000000000000000000000000000C +:10F5000000000000000000000000000000000000FB +:10F5100000000000000000000000000000000000EB +:10F5200000000000000000000000000000000000DB +:10F5300000000000000000000000000000000000CB +:10F5400000000000000000000000000000000000BB +:10F5500000000000000000000000000000000000AB +:10F56000000000000000000000000000000000009B +:10F57000000000000000000000000000000000008B +:10F58000000000000000000000000000000000007B +:10F59000000000000000000000000000000000006B +:10F5A000000000000000000000000000000000005B +:10F5B000000000000000000000000000000000004B +:10F5C000000000000000000000000000000000003B +:10F5D000000000000000000000000000000000002B +:10F5E000000000000000000000000000000000001B +:10F5F000000000000000000000000000000000000B +:10F6000000000000000000000000000000000000FA +:10F6100000000000000000000000000000000000EA +:10F6200000000000000000000000000000000000DA +:10F6300000000000000000000000000000000000CA +:10F6400000000000000000000000000000000000BA +:10F6500000000000000000000000000000000000AA +:10F66000000000000000000000000000000000009A +:10F67000000000000000000000000000000000008A +:10F68000000000000000000000000000000000007A +:10F69000000000000000000000000000000000006A +:10F6A000000000000000000000000000000000005A +:10F6B000000000000000000000000000000000004A +:10F6C000000000000000000000000000000000003A +:10F6D000000000000000000000000000000000002A +:10F6E000000000000000000000000000000000001A +:10F6F000000000000000000000000000000000000A +:10F7000000000000000000000000000000000000F9 +:10F7100000000000000000000000000000000000E9 +:10F7200000000000000000000000000000000000D9 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000000000099 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F860000000000000000000000000000000000098 +:10F870000000000000000000000000000000000088 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF0000000000000000000000000000000000001 +:020000022000DC +:1000000000000000000000000000000000000000F0 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:102000008B7420324006000A0E0A000103010810FA +:1020100032004006F6090000000C0100000000003C +:1020200000135759040600000000000000080109D1 +:10203000000132334006000028191900000E00008C +:10204000000E0000000E0000000E0000000E000058 +:10205000000E0000000E0000000E0000000D030046 +:10206000000E0000000E0000000E0000000D030036 +:10207000000E0000000E0000000E00000000000036 +:10208000000101000000000000000000000000004E +:10209000000000000000000000000101010101003B +:1020A0000001010000000101010100010000000029 +:1020B0000100000102000000070000000107010309 +:1020C000020314000A0A4000000078003C000000EF +:1020D0000000000000000000000000000000000000 +:1020E0000000000000000000C800C8009600C80002 +:1020F00007078000800005050000000000000000C8 +:1021000006010000000017003900910010001400C3 +:10211000F9FFC4FFFF7FFF7FFF7FFF7FFA002C01E5 +:102120003200C8000A04B4B43232230500000000B3 +:1021300000070D0000320D00000000203232323264 +:1021400032323232323232323232323232320000D3 +:10215000000000000000000000000000000000007F +:102160000A05000A00000000140F001210120000FF +:10217000000000000000000000000000000000005F +:10218000000000000F233246500000006A645046F1 +:102190003C3C3C3C08000000000000000F2332469D +:1021A000500000006A6450463C3C3C3C0F141E2822 +:1021B000000000000A0A0A0A0A0A0A0A0C192D413C +:1021C0005000000046554B4646464646000000007B +:1021D0000A0314005F00F1FF14000F000A00BC02A4 +:1021E00000000000F8FF00007800320064002800C2 +:1021F0000F000F001C023D011C02740400003F068A +:102200000000FF09F40100003F060000FF0932143E +:10221000021E1E32020096003C003C007700C805FA +:10222000770088090000000040063000200001000F +:10223000220000003A00520070008F00AF00CF0073 +:10224000EF000F012E014F016E018E01AD01CE0195 +:10225000EC010F022D024D026D028D02AC02CC0288 +:10226000EB020B032B034A036A038903AA03C90386 +:10227000E703FF0337040000000000000000000037 +:10228000000000000000000000000000000000004E +:10229000000000000000000000000000000000003E +:1022A000000000000000000000000000000000002E +:1022B000000000000000000000000000000000001E +:1022C000000000000000000000000000000000000E +:1022D00000000000000000000000000000000000FE +:1022E00000000000000000000000000000000000EE +:1022F00000000000000000000000F6093000460069 +:102300000100480000003C00430066008500A90071 +:10231000C800E90009012A0149016B018901AB01EB +:10232000C901EB0109022B024A026C028A02AC02CB +:10233000CA02EC020B032D034B036D038B03AE03A8 +:10234000CB03EE030C042F044C046F048B04AF0486 +:10235000CC04EF040D0530054D0570058D05B00565 +:10236000CD05F1050D0630064E0672068E06B10645 +:10237000CE06F2060F073207500773079007B30720 +:10238000D107F40711083408520875089108B108FC +:10239000C608E70800000000000000000000000080 +:1023A000000000000000000000000000000000002D +:1023B000000000000000000000000000000000001D +:1023C000000000000000000000000000000000000D +:1023D0000201200019450000F16C000084D90600BC +:1023E00029B1010010270000C4090000000101010B +:1023F000010102020202014B0F00A00000000000D8 +:102400000100010101010102020202001945000060 +:1024100002000000A46B00000000000014140A0A6F +:102420001400000000000000141414140101010144 +:10243000010040003200E8030F0008000500900092 +:1024400000001E502800B4005000040000000000EE +:10245000B4005000FA00A000000000014F0100008D +:102460000000000068010D0D0A094B004B006400DC +:102470000A003200C800640064000F02E8E8F800B7 +:10248000F8000200190000006A00750081008E004B +:102490009D00AC00BD00CF00E200F7000D01260159 +:1024A00040015C0179019901BC01E00106023002A2 +:1024B0005B028902BA02EE0224035D039A03D90388 +:1024C0001B046004A904F40443059505E9054106CD +:1024D0009C06FA065B07BE0724088D08F808650904 +:1024E000D409450AB80A2D0BA20B190C900C080D43 +:1024F000800DF80D6F0EE60E5C0FD00F4210B3107A +:1025000021118C11F4115912BA1217137013C4133C +:1025100013145D14A114E01418154B1577159C15B0 +:10252000BB15D415E515EF15F31536003D00440035 +:102530004C00560060006B00770085009300A400FB +:10254000B500C900DE00F5000E0129014601650154 +:102550008701AC01D401FE012B025B028F02C6028F +:1025600001033F038003C6030F045D04AE040305AB +:102570005D05BA051B068106EA065707C9073D082F +:10258000B6083109B009320AB70A3E0BC70B520C24 +:10259000DF0C6D0DFC0D8B0E1A0FA80F3610C3103B +:1025A0004D11D6115B12DE125C13D7134D14BD14FE +:1025B00028158D15EC1544169516DE161F1758179D +:1025C0008917B117D117E717F517FA174E005600FC +:1025D00060006B00760083009100A000B100C20093 +:1025E000D600EB0002011A01350152017001910180 +:1025F000B501DB0103022E025C028D02C102F8026A +:1026000032036F03B003F4033B048604D4042605AD +:102610007C05D50532069206F5065C07C607330829 +:10262000A30816098C09040A7E0AFA0A790BF80B2A +:10263000790CFB0C7E0D010E830E060F870F071021 +:10264000861003117D11F5116912DA124713AF13C9 +:1026500013147214CB141E156B15B215F2152C162B +:102660005E168916AC16C716DB16E716EB166A005F +:10267000750081008E009D00AC00BD00CF00E2001F +:10268000F7000D01260140015C0179019901BC01AF +:10269000E001060230025B028902BA02EE02240364 +:1026A0005D039A03D9031B046004A904F4044305E1 +:1026B0009505E90541069C06FA065B07BE07240856 +:1026C0008D08F8086509D409450AB80A2D0BA20B34 +:1026D000190C900C080D800DF80D6F0EE60E5C0FB6 +:1026E000D00F4210B31021118C11F4115912BA12EB +:1026F00017137013C41313145D14A114E0141815E8 +:102700004B1577159C15BB15D415E515EF15F3156D +:102710005500550045004200000000000000000088 +:1027200000000000000000000000000000000000A9 +:102730000000000000000000000000000000000099 +:102740000000000000000000000000000000000089 +:102750000000000000000000000000000000000079 +:102760000000000000000000000000000000000069 +:102770000000000000000000000000000000000059 +:102780000000000000000000000000000000000049 +:102790000000000000000000000000000000000039 +:1027A0000000000000000000000000000000000029 +:1027B0000000000000000000000000000000000019 +:1027C0000000000000000000000000000000000009 +:1027D00000000000000000000000000000000000F9 +:1027E00000000000000000000000000000000000E9 +:1027F00000000000000000000000000000000000D9 +:1028000000000000000000000000000000000000C8 +:1028100000000000000000000000000000000000B8 +:1028200000000000000000000000000000000000A8 +:102830000000000000000000000000000000000098 +:102840000000000000000000000000000000000088 +:102850000000000000000000000000000000000078 +:10286000000000000000000000000000A000D200F6 +:1028700004013C0005000000000000000000000012 +:102880000000000000000000000000000000000048 +:102890000000000000000000000000000000000038 +:1028A0000000000000000000000000000000000028 +:1028B0000000000000000000000000000000000018 +:1028C0000000000000000000000000000000000008 +:1028D00000000000000000000000000000000000F8 +:1028E00000000000000000000000000000000000E8 +:1028F00000000000000000000000000000000000D8 +:1029000000000000000000000000000000000000C7 +:1029100000000000000000000000000000000000B7 +:1029200000000000000000000000000000000000A7 +:102930000000000000000000000000000000000097 +:102940000000000000000000000000000000000087 +:102950000000000000000000000000000000000077 +:102960000000000000000000000000000000000067 +:102970000000000000000000000000000000000057 +:102980000000000000000000000000000000000047 +:102990000000000000000000000000000000000037 +:1029A0000000000000000000000000000000000027 +:1029B0000000000000000000000000000000000017 +:1029C0000000000000000000000000000000000007 +:1029D00000000000000000000000000000000000F7 +:1029E00000000000000000000000000000000000E7 +:1029F00000000000000000000000000000000000D7 +:102A00001901010000000000000000003202300047 +:102A10000000575900000000000000000000000006 +:102A200099020000BC020000DF0200000203000067 +:102A300025030000480300006B0300008E03000024 +:102A4000B1030000D4030000F70300001A040000E3 +:102A50003D0400006004000083040000A6040000A0 +:102A6000C904000020030000D4B804020351180078 +:102A700007B28C2363200C0485011C0800000000B1 +:102A800000000000190000005B555555555555557F +:102A90005555555505000000080A000010000A00B1 +:102AA000000000010000000002E00000EC045406F9 +:102AB00084067E07410AA2076A099109B1097E17B7 +:102AC00007B8C30700800000208300000080328028 +:102AD000648096802DB4040F110C0F0F10000F139B +:102AE000A5BA830A18C80F0015101510104310431B +:102AF00020030000D4A8040C42330E0EC4338E23EE +:102B000063011911E32101132302000000000000FA +:102B10001B0000005B555555555555555555555598 +:102B20005505000098090B0BB0B00000B0B0001BB9 +:102B30000B00000082F01002EC04540684067E07AD +:102B4000410AA2076A099109B1097E1707B8C307AC +:102B50000080000020830000008032806480968026 +:102B60002DB4040F110C0F0F10000F13A5BA830A18 +:102B700018C80F0015101510104310432003000053 +:102B8000090000000000000000000000000000003C +:102B90000000000000000000000000000100000034 +:102BA0000300000000000000000000000000000022 +:102BB0000200000000000000000000000000000013 +:102BC00000000000EC04540684067E07410AA207B8 +:102BD0006A099109B1097E1707B8C3070080000090 +:102BE0002083000000803280648096802DB4040F22 +:102BF000110C0F0F10000F13A5BA830A18C80F008D +:102C0000151015101043104320030000D4B804021F +:102C10000351180007B28C2363200C0485011C08A3 +:102C20000000000000000000190000005B55555531 +:102C3000555555555555555555000000086A666659 +:102C400036666A66666666636600000002E000003B +:102C5000EC04540684067E07410AA2076A0991091A +:102C6000B1097E1707B8C307008000002083000069 +:102C700000803280648096802DB4040F110C0F0FF9 +:102C800010000F13A5BA830A18C80F0015101510ED +:102C90001043104320030000D4A8040C42330E0E4E +:102CA000C4338E2363011911E321011323020000B1 +:102CB000000000001B0000005B555555555555554B +:102CC000555555555505000098696B6BB6B6666647 +:102CD000B6B6663B6B06000082F01002EC045406A8 +:102CE00084067E07410AA2076A099109B1097E1785 +:102CF00007B8C307008000002083000000803280F6 +:102D0000648096802DB4040F110C0F0F10000F1368 +:102D1000A5BA830A18C80F001510151010431043E8 +:102D200020030000D4B854161796010000000000DC +:102D30000000000000000000000000000000000093 +:102D4000080000005B555555000000000000000021 +:102D500000000000081A111100000000000000002F +:102D60000000000002000000EC04540684067E0708 +:102D7000410AA2076A099109B1097E1707B8C3077A +:102D800000800000208300000080328064809680F4 +:102D90002DB4040F110C0F0F10000F13A5BA830AE6 +:102DA00018C80F0015101510104310432003000021 +:102DB000D4B854161796010000000000000000006F +:102DC00000000000000000000000000008000000FB +:102DD0005B55555500000000000000000000000099 +:102DE000083A33330000000000000000000000003B +:102DF00002000000EC04540684067E07410AA20784 +:102E00006A099109B1097E1707B8C307008000005D +:102E10002083000000803280648096802DB4040FEF +:102E2000110C0F0F10000F13A5BA830A18C80F005A +:102E3000151015101043104320030000D4A8540CA3 +:102E4000567339184F068D11A3344E000000000050 +:102E50000000000000000000130000005B55555505 +:102E600055555555550500000000000008191B1B5D +:102E70001B1B0B0B0B0B00000000000002A002004C +:102E8000EC04540684067E07410AA2076A099109E8 +:102E9000B1097E1707B8C307008000002083000037 +:102EA00000803280648096802DB4040F110C0F0FC7 +:102EB00010000F13A5BA830A18C80F0015101510BB +:102EC0001043104320030000D4A8540C5673391843 +:102ED0004F068D11A3344E000000000000000000DA +:102EE00000000000130000005B5555555555555521 +:102EF000550500000000000008393B3B3B3B0B0B35 +:102F00000B0B00000000000002A00200EC045406BD +:102F100084067E07410AA2076A099109B1097E1752 +:102F200007B8C307008000002083000000803280C3 +:102F3000648096802DB4040F110C0F0F10000F1336 +:102F4000A5BA830A18C80F001510151010431043B6 +:102F500020030000D4A8051B023774045E311A2335 +:102F6000C7088C08000000000000000000000000FE +:102F7000140000005B5555555555555555550000E5 +:102F800000000000080909090909000010000000FC +:102F90000000000002500500EC04540684067E0781 +:102FA000410AA2076A099109B1097E1707B8C30748 +:102FB00000800000208300000080328064809680C2 +:102FC0002DB4040F110C0F0F10000F13A5BA830AB4 +:102FD00018C80F00151015101043104320030000EF +:102FE000D4A8051B023774045E311A23C7088C0865 +:102FF00000000000000000000000000014000000BD +:103000005B55555555555555555500000000000068 +:10301000086969696969606030600000000000004B +:1030200002500500EC04540684067E07410AA207FC +:103030006A099109B1097E1707B8C307008000002B +:103040002083000000803280648096802DB4040FBD +:10305000110C0F0F10000F13A5BA830A18C80F0028 +:10306000151015101043104320030000D4A8551B61 +:10307000167775185E0600000000000000000000D2 +:1030800000000000000000000C0000005B555555DA +:103090005555000000000000000000000819191933 +:1030A00019190000000000000000000002000000EC +:1030B000EC04540684067E07410AA2076A099109B6 +:1030C000B1097E1707B8C307008000002083000005 +:1030D00000803280648096802DB4040F110C0F0F95 +:1030E00010000F13A5BA830A18C80F001510151089 +:1030F0001043104320030000D4A8551B1677751801 +:103100005E0600000000000000000000000000005B +:10311000000000000C0000005B555555555500009F +:10312000000000000000000008393939393900007A +:10313000000000000000000002000000EC04540643 +:1031400084067E07410AA2076A099109B1097E1720 +:1031500007B8C30700800000208300000080328091 +:10316000648096802DB4040F110C0F0F10000F1304 +:10317000A5BA830A18C80F00151015101043104384 +:1031800020030000E3180803446100070800000062 +:10319000000000000000000000000000000000002F +:1031A0000B00000055555555550500000000000066 +:1031B000000000000000000001000000000000000E +:1031C0000000000003000000EC04540684067E07A3 +:1031D000410AA2076A099109B1097E1707B8C30716 +:1031E0000080000020830000008032806480968090 +:1031F0002DB4040F110C0F0F10000F13A5BA830A82 +:1032000018C80F00151015101043104320030000BC +:10321000D4B8000000000000000000000000000022 +:10322000000000000000000000000000030000009B +:103230005B0500000000000000000000000000002E +:10324000080A00000000000000000000000000006C +:1032500002000000EC04540684067E07410AA2071F +:103260006A099109B1097E1707B8C30700800000F9 +:103270002083000000803280648096802DB4040F8B +:10328000110C0F0F10000F13A5BA830A18C80F00F6 +:10329000151015101043104320030000090500000D +:1032A00000000000C002000000000000000000005C +:1032B0000000000000000000020000006466666676 +:1032C00066660000000000000000000082000000B0 +:1032D00000A000000000000000000000FC0700004B +:1032E000EC04540684067E07410AA2076A09910984 +:1032F000B1097E1707B8C3070080000020830000D3 +:1033000000803280648096802DB4040F110C0F0F62 +:1033100010000F13A5BA830A18C80F001510151056 +:103320001043104320030000813010050670200078 +:10333000000000000000000000000000000000008D +:10334000000000000900000055555555050000001B +:10335000000000000000000000000001000000006C +:10336000000000000000000000000000EC04540613 +:1033700084067E07410AA2076A099109B1097E17EE +:1033800007B8C3070080000020830000008032805F +:10339000648096802DB4040F110C0F0F10000F13D2 +:1033A000A5BA830A18C80F00151015101043104352 +:1033B0000000000000000001000003000000FC000D +:1033C000000000000D000D0040065906000000003E +:1033D0000155B400020000000000000001010302DA +:1033E000000001000000FC00000000000D000D00C6 +:1033F00000000F000000000004B0B3000000001047 +:103400000000000002020302000001000000FC00B6 +:10341000000000000D000D0001000E000000000083 +:1034200004C4B30000000010000000000303030206 +:10343000000001000000FC00000000000D000D0075 +:1034400002000D000000000004D8B30000000010CE +:103450000000000004040302000001000000FC0062 +:10346000000000000D000D0003000C000000000033 +:1034700004ECB3000000001000000000050503028A +:10348000000001000000FC00000000000D000D0025 +:1034900004000B00000000000400B4000000001055 +:1034A0000000000006060302000001000000FC000E +:1034B000000000000D000D0005000A0000000000E3 +:1034C0000414B4000000001000000000070703020D +:1034D000000001000000FC00000000000D000D00D5 +:1034E00006000900000000000428B40000000010DD +:1034F0000000000008080302000005000000FC00B6 +:10350000000000000D000D00070008000000000092 +:10351000043CB4000000001000000000090000019D +:10352000000007000000FC00000000000D000D007E +:10353000A00FB90F000000000150B400000000000F +:103540000000000000000001000003000000FC007B +:10355000000000000D000D00C116A81600000000BC +:1035600001A0B400060000000000000000001717D2 +:10357000000003000000FC00000000000D000D0032 +:103580003818391800000000019BB4000400000046 +:103590000000000000001616010003000000FD00FE +:1035A000000000000D000D00681070100000FA25EA +:1035B0000473B400040000000000000000001717AE +:1035C000020003000000FC00000000000D000D00E0 +:1035D000F811F9110000FA250487B4000400000076 +:1035E0000000000000001616030003000000FD00AC +:1035F000000000000D000D00681070100000FA259A +:103600000473B4000400000000000000000017175D +:10361000040003000000FC00000000000D000D008D +:10362000F811F9110000FA250487B4000400000025 +:103630000000000000001616050003000000FD0059 +:10364000000000000D000D00681070100000FA2549 +:103650000473B4000400000000000000000017170D +:10366000060003000000FC00000000000D000D003B +:10367000F811F9110000FA250487B40004000000D5 +:103680000000000000001616070003000000FD0007 +:10369000000000000D000D00681070100000FA25F9 +:1036A0000473B400040000000000000000001717BD +:1036B000080003000000FC00000000000D000D00E9 +:1036C000F811F9110000FA250487B4000400000085 +:1036D00000000000000A1414092802000000FC0089 +:1036E00000000000050005000000000000000000D0 +:1036F000010097030000000000000000000000012E +:10370000000003000000FC00000000000D000D00A0 +:103710000000190000000000015AB400020000007F +:103720000000000000000001000003000000FC0099 +:10373000000000000D000D009001A9010000000034 +:10374000015FB40002000000000000000000000162 +:10375000000003000000FC00000000000D000D0050 +:1037600020033903000000000164B40002000000DF +:103770000000000000000001000003000000FC0049 +:10378000000000000D000D00B004C904000000009E +:103790000169B40002000000000000000000000108 +:1037A000000003000000FC00000000000D000D0000 +:1037B0004006590600000000016EB400020000003F +:1037C0000000000000000100000003000000FC00F9 +:1037D000000000000D000D006810811000000000C6 +:1037E00001A5B40006000000000000000000010078 +:1037F000000003000000FC00000000000D000D00B0 +:10380000F81111120000000001AAB4000600000027 +:103810000000000000000100000003000000FC00A8 +:10382000000000000D000D008813A113000000002F +:1038300001AFB4000600000000000000000001001D +:10384000000003000000FC00000000000D000D005F +:10385000181531150000000001B4B4000600000086 +:103860000000000000000100000003000000FC0058 +:10387000000000000D000D00A816C1160000000099 +:1038800001B9B400060000000000000000000100C3 +:10389000002802000000FC000000000009000900F0 +:1038A0000000000000000000010097030600000077 +:1038B00000000000000B1414002802000000FC00AF +:1038C000000000000C000C000000000000000000E0 +:1038D000010097030000000000000000000B14141A +:1038E000002802000000FC003F0000000C000C005B +:1038F000000000000000000001009703000000002D +:1039000000000000000B1515002802000000CC008C +:10391000000000000C000C0000000000000000008F +:1039200001009703000000000000000000000100FB +:10393000002802000000FC00000000000D000D0047 +:1039400000000000000000000100970306000000D6 +:103950004F00000001F4040068931B0060000000A9 +:103960000C000000010004001428000060000000AA +:10397000300000002D008400142800001C0000000E +:10398000730000002DF4840068931B001C000000ED +:10399000700000002DF4840068931B001C000000E0 +:1039A0007300000023F4840068931B001C000000D7 +:1039B0006000000050F4840094EB1B001C00000029 +:1039C0004F00000001F4040068931B00E0000100B8 +:1039D0000C0000000100040014280000E0000100B9 +:1039E000300000002D008400142800001C0000009E +:1039F000700000002DF4840068931B001C00000080 +:103A0000730000002DF4840051651B001C000000B1 +:103A1000010128010101010101010101010101016F +:103A20000101010101010101010101010101010186 +:103A30000101010101010101010101010101010176 +:103A40000101010101010101010101010101010166 +:103A50000101010101010101010101010101010156 +:103A60000101010101010101010101010101010146 +:103A7000010101012B2B2C2E2D2C2E2E2B2E2E2C2A +:103A80002C2D2E2C2D2C2D2D2C2D2D2E2D2C2E2E67 +:103A90002D2C2D2E2E2D2D2D2C2D2E2E2D2E2E2D52 +:103AA0002D2E2D2E2F2D2D2F2E2D2E2F2D2E2F2E38 +:103AB0002D2E2E2E2E2D2F2F2D2E2E2F2E2D2E2E27 +:103AC0002E2E2D2E2F2D2E2E2D2F2F2F2E2E2E2E15 +:103AD0002E2F2E303D2A2B2B2B2B2B2D2B2C2D2D0F +:103AE0002B2E2E2C2B2C2E2C2C2C2D2D2C2D2C2E0D +:103AF0002D2C2E2E2D2C2D2E2E2D2D2D2C2D2E2EF3 +:103B00002D2D2E2D2D2E2D2E2E2D2D2E2D2D2E2FDD +:103B10002D2E2F2E2D2E2E2E2E2D2F2F2D2E2E2FC5 +:103B20002E2D2E2E2E2D2E2E2F2D2F2E2D2F2F2FB4 +:103B30002D2E2E2E2E2E2E2F2B292B2B2B2B2B2DBD +:103B40002B2B2D2D2B2E2E2C2B2C2E2C2C2C2D2DAF +:103B50002C2D2C2E2D2C2D2E2D2C2D2E2E2C2D2D96 +:103B60002C2D2E2E2D2D2E2D2D2E2D2E2E2D2D2E7F +:103B70002D2D2E2F2D2E2F2E2C2E2E2E2E2D2F2E68 +:103B80002D2E2E2F2E2D2E2E2E2D2E2E2F2C2E2E58 +:103B90002D2F2F2F2D2E2E2E2E2E2E2F2A292B2B52 +:103BA0002B2B2B2D2B2B2D2D2B2E2E2C2B2C2E2C53 +:103BB0002C2C2D2D2C2D2C2E2D2C2D2E2D2C2D2E38 +:103BC0002E2C2D2D2C2D2E2E2D2D2E2D2D2E2D2E21 +:103BD0002E2D2D2E2D2D2E2F2D2E2F2E2D2E2E2E09 +:103BE0002E2D2F2E2D2E2E2F2E2D2E2E2E2D2E2EF7 +:103BF0002F2C2E2E2D2F2F2F2D2E2E2E2E2E2E2FE4 +:103C00002B292B2B2B2B2B2D2B2B2C2D2B2E2E2CFA +:103C10002B2C2E2C2C2C2D2D2C2D2C2E2D2C2D2EDA +:103C20002D2C2D2E2E2C2D2D2C2D2E2E2D2D2E2DC2 +:103C30002D2E2D2E2E2D2D2E2D2D2E2F2D2E2F2EA9 +:103C40002D2E2E2E2E2D2F2E2D2E2E2F2E2D2E2E96 +:103C50002E2D2E2E2F2D2E2E2D2F2F2F2D2E2E2E84 +:103C60002E2E2E2F2B292B2B2B2B2B2D2B2B2C2D94 +:103C70002B2E2E2C2B2C2E2C2C2C2D2D2C2D2C2E7B +:103C80002D2C2D2E2D2C2D2E2E2C2D2D2C2D2E2E63 +:103C90002D2D2E2D2D2E2D2E2E2D2D2E2D2D2E2F4C +:103CA0002D2E2F2E2D2E2E2E2E2D2F2E2D2E2E2F35 +:103CB0002E2D2E2E2E2D2E2E2F2D2E2E2D2F2F2F24 +:103CC0002D2E2E2E2E2E2E2F2B292B2B2B2B2B2D2C +:103CD0002B2B2C2D2B2E2E2C2B2C2E2C2C2C2D2D1F +:103CE0002C2D2C2E2D2C2D2E2D2C2D2E2E2C2D2D05 +:103CF0002C2D2E2E2D2D2E2D2D2E2D2E2E2D2D2EEE +:103D00002D2D2E2F2D2E2F2E2D2E2E2E2E2D2F2ED5 +:103D10002D2E2E2F2E2D2E2E2F2D2E2E2F2D2E2EC4 +:103D20002D2F2F2F2D2E2E2E2E2E2E2F2B292B2BBF +:103D30002B2B2B2D2B2C2C2D2B2E2E2C2B2C2E2CC1 +:103D40002D2C2D2D2C2D2C2E2D2C2D2E2D2C2D2EA5 +:103D50002E2D2D2D2C2D2E2E2D2E2E2D2D2E2D2E8D +:103D60002E2D2D2E2D2D2E2F2D2E2F2E2D2E2F2E76 +:103D70002E2D2F2F2D2E2E302E2D2E2F2F2E2E2F5F +:103D80002F2D2F2E2D2F2F2F2D2E2E2E2E2E2E2F50 +:103D90002B292B2C4D4D4D4D4D4D4D4D4D4D4D4DDC +:103DA0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D43 +:103DB0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D33 +:103DC0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D23 +:103DD0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D13 +:103DE0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D03 +:103DF0004D4D4D4D4D4D4D4D9224922492009200CB +:103E000000000000B66DB66DB600B6000000000000 +:103E1000B66DB66D9601960100000000B66DB66DE8 +:103E2000B201B20100000000B62DB62DB601B601F8 +:103E300000000000B665B665B601B60100000000DE +:103E4000B66CB66CB601B60100000000966D966DBA +:103E5000B601B60100000000B26DB26DB601B60148 +:103E600000000000FF7FFF7FFF01FF010000000056 +:103E7000B66DB66DB601B601000000009224922422 +:103E800092009200000000000110000000000000FD +:103E900000000000FFFF3DDB38D4FC020200AA0056 +:103EA0006C768A940001060000000000DB0600002A +:103EB000040C000060056E40415639030100009A71 +:103EC000EC045661000000000000000010C40C501B +:103ED0000390BBBB80442278641164118A3989390C +:103EE00085E00FE06612641201100000000000007F +:103EF00000000000FFFF3DDB38D4FC020200AA00F6 +:103F00006C768A940001060000000000DB060000C9 +:103F1000040C000060056E40415639030100009A10 +:103F2000EC045661000000000000000010C40C10FA +:103F3000E39EBBBB80552278641164118A398939AC +:103F400085E00FE06612641201040000000000002A +:103F50000000000000000000000000020200AA00B3 +:103F60006C768A940001060000000000DB06000069 +:103F7000040C000020066E40418639030100009ABF +:103F8000AC058661000000000000000010C40C5069 +:103F90000390BBBB80442278641164118A3989394B +:103FA00085E00FE066126412C904020001020304F6 +:103FB000EAF7FAFD3001A880CF0304021E000003D7 +:103FC0006C768A940001060000000000DB06000009 +:103FD000014600002B1A0040006B39034100029A91 +:103FE00000006B616478792BCF8A00801C54119893 +:103FF0000080BBBB00572278641164118A3989396B +:1040000085F00FF066126412C9040200010101017B +:10401000EAF7FAFD3001A880CF0304020200000095 +:104020006C768A940001060000000000DB060000A8 +:10403000014600002B1A0040006B39034100029A30 +:1040400000006B61BB7DFC17FFFF00801C541198C2 +:104050000380BBBB80462278641164118A39893998 +:1040600085F00FF066126412C90402000202020217 +:10407000EAF7FAFD3001A880CF0304020200000035 +:104080006C768A940001060000000000DB06000048 +:10409000014600002B1A0040006B39034100029AD0 +:1040A00000006B610F7E3416FFFF00801C541198D6 +:1040B0000380BBBB80462278641164118A39893938 +:1040C00085F00FF066126412C904020003030303B3 +:1040D000EAF7FAFD3001A880CF03040202000000D5 +:1040E0006C768A940001060000000000DB060000E8 +:1040F000014600002B1A0040006B39034100029A70 +:1041000000006B61B17E3C12FFFF00801C541198CF +:104110000380BBBB80462278641164118A398939D7 +:1041200085F00FF066126412C9040200040404044E +:10413000EAF7FAFD3001A880CF0304020200000074 +:104140006C768A940001060000000000DB06000087 +:10415000014600002B1A0040006B39034100029A0F +:1041600000006B611C7F0B0FFFFF00801C54119837 +:104170000380BBBB80462278641164118A39893977 +:1041800085F00FF0661264120104000400000000C4 +:10419000CCF57AFDED20BF8FCF03040202060000AC +:1041A0006C768A940001060000000000DB06000027 +:1041B00001060000093C0040006B39034100029AEF +:1041C00000006B616478792BCF8A00801CC41018C2 +:1041D0000380AAAA00C6227864116411803980394C +:1041E0000F000F00550D550DC904020006070A0BFC +:1041F000EAF7FAFD3001A880CF0304021E0600038F +:104200006C768A940001060000000000DB060000C6 +:10421000014600002B1A0040006B39034100029A4E +:1042200000006B616478792BCF8A00801C54119850 +:104230000080BBBB00572218641164118A39893988 +:1042400085F00FF066126412C90402000606060625 +:10425000EAF7FAFD3001A880CF030402020600004D +:104260006C768A940001060000000000DB06000066 +:10427000014600002B1A0040006B39034100029AEE +:1042800000006B616478792BCF8A00801C541198F0 +:104290000080BBBB00572218641164118A39893928 +:1042A00085F00FF066126412C904020006060A0ABD +:1042B000EAF7FAFD3001A880CF0304020A060100E4 +:1042C0006C768A940043060100000000DB060000C3 +:1042D000014600002B1A0040006B39034100029A8E +:1042E00000006B619367CBB40000008012541198FA +:1042F0000080BBBB00562218641164118A398939C9 +:1043000085F00FF066126412C904020007070B0B58 +:10431000EAF7FAFD3001A880CF0304020A06010083 +:104320006C768A940043060100000000DB06000062 +:10433000014600002B1A0040006B39034100029A2D +:1043400000006B6155737BC8000000801254119807 +:104350000080BBBB00562218641164118A39893968 +:1043600085F00FF066126412C904020009090C0CF2 +:10437000EAF7FAFD3001A880CF0304020A06010023 +:104380006C768A940043060100000000DB06000002 +:10439000014600002B1A0040006B39034100029ACD +:1043A00000006B61D9770ED3000000801254119881 +:1043B0000080BBBB00562218641164118A39893908 +:1043C00085F00FF066126412C90402000A0A06069C +:1043D000EAF7FAFD3001A880CF0304020A060100C3 +:1043E0006C768A940043060100000000DB060000A2 +:1043F000014600002B1A0040006B39034100029A6D +:1044000000006B61BD7977D80000008012541198CC +:104410000080BBBB00562218641164118A398939A7 +:1044200085F00FF066126412C90402000B0B070737 +:10443000EAF7FAFD3001A880CF0304020A06010062 +:104440006C768A940043060100000000DB06000041 +:10445000014600002B1A0040006B39034100029A0C +:1044600000006B61757B34DE0000008012541198EF +:104470000080BBBB00562218641164118A39893947 +:1044800085F00FF066126412C90402000A0A0606DB +:10449000EAF7FAFD3001A880CF0304020A06010002 +:1044A0006C768A940043060100000000DB060000E1 +:1044B000014600002B1A0040006B39034100029AAC +:1044C00000006B61CB7C87E30000008012541198E0 +:1044D0000080BBBB00562218641164118A398939E7 +:1044E00085F00FF066126412C90402000B0B070777 +:1044F000EAF7FAFD3001A880CF0304020A060100A2 +:104500006C768A940043060100000000DB06000080 +:10451000014600002B1A0040006B39034100029A4B +:1045200000006B61F27D29E90000008012541198AF +:104530000080BBBB00562218641164118A39893986 +:1045400085F00FF066126412C90402000C0C090910 +:10455000EAF7FAFD3001A880CF0304020A06010041 +:104560006C768A940043060100000000DB06000020 +:10457000014600002B1A0040006B39034100029AEB +:1045800000006B61D57EC2EE0000008012541198CD +:104590000080BBBB00562218641164118A39893926 +:1045A00085F00FF0661264120000000000000000A9 +:1045B00000101000FFFF56CE000099103F0E30068D +:1045C000FFFFFDF900006FA13F0E3005FFFF464FD2 +:1045D000000029A63F0F3004FFFFAD8700007DD902 +:1045E0003F0F30030000C15A00009C9A00041030B5 +:1045F0000000BCA00000903800091033000083D0F8 +:104600000000D635000B10350000C9C200001A5951 +:10461000000C103600008CA100002C9F000D1037FC +:1046200000009851000044DC000E10380000BEEA83 +:104630000000A536000E103A000026620000DD9949 +:10464000000F103B0000000064000000700000003C +:104650008900000098000000C9000000D700000099 +:10466000F100000000010000400000000000000018 +:10467000000000000000000000000000000000003A +:10468000000000000000000000000000000000002A +:10469000000000000000000000000000000000001A +:1046A000000000000000000000000000000000000A +:1046B00000000000000000000000000000000000FA +:1046C00000000000870700008579385793F930A172 +:1046D000B3D4CC2BCB0AF200000000000000000095 +:1046E00000000000000000000000000000000000CA +:1046F00000000000000000000000000000000000BA +:1047000080220022870700008579385793E4C2B9D8 +:1047100030AFCC2BC5A1B3000000000000000000AA +:104720000000000000000000000000000000000089 +:104730000000000000000000000000000000000079 +:1047400080220022870700008579385793E4C2BC95 +:10475000C2BCD7930D7930000000000000000000BB +:104760000000000000000000000000000000000049 +:104770000000000000000000000000000000000039 +:1047800080220022870700008579385793E4C2BF52 +:10479000930ACC2BC4F50D000000000000000000BF +:1047A0000000000000000000000000000000000009 +:1047B00000000000000000000000000000000000F9 +:1047C00080220022870700008579385793E4C2BF12 +:1047D000930AE4C2B286CF0000000000000000008F +:1047E00000000000000000000000000000000000C9 +:1047F00000000000000000000000000000000000B9 +:1048000080220022870700008579385793E4C2BFD1 +:10481000930AB0AF26CF5000000000000000000057 +:104820000000000000000000000000000000000088 +:104830000000000000000000000000000000000078 +:1048400080220022870700008579385793E4C2BB95 +:104850000AF2E4C2BE4C2B00000000000000000081 +:104860000000000000000000000000000000000048 +:104870000000000000000000000000000000000038 +:1048800080220022870700008579385793E4C2BB55 +:104890000AF2B0AF295E4C000000000000000000EA +:1048A0000000000000000000000000000000000008 +:1048B00000000000000000000000000000000000F8 +:1048C00080220022C8060000450EA63D450EA63DEA +:1048D000BAF15942450EA63D450EA63D450EA63DF0 +:1048E000450EA63D00000000000000000000000092 +:1048F00000000000000000000000000000000000B8 +:1049000080220022000102030405060708090A0BA1 +:104910000C0D0E0F101112131415161718191A1B5F +:104920001C1D1E1F202122232425262728292A2B4F +:104930002C2D2E2F30310000000000000000000060 +:10494000000000000000000000000000191A1B1CFD +:104950001D1E1F202122232425262728292A2B2C0F +:104960002D2E2F303132333435363738393A3B3CFF +:104970003D3E3F404142434445464748494A000086 +:104980000000000000000000000000000000000027 +:10499000000000000020406080A0C0E000204060D7 +:1049A00080A0C0E00020406080A0C0E00020406007 +:1049B00080A0C0E00020406080A0C0E000204060F7 +:1049C00080A0C0E0002000000000000949924812C9 +:1049D00092B46D1B1B4992246DDBB63600204060FB +:1049E00080A0C0E00020406080A0C0E000204060C7 +:1049F00080A0C0E00020406080A0C0E000204060B7 +:104A000080A0C0E00020406080A0C0E00020000046 +:104A1000000000094992481292B46D1B1B49922470 +:104A20006DDBB6362021E0E1A0A160612021E0E14C +:104A3000A0A160612021E0E1A0A160612021E0E16E +:104A4000A0A160612021E0E1A0A160612021E0E15E +:104A5000A0A160612021000076DBB62D2449921BC5 +:104A6000DBB6491292942409090000000100C1C07C +:104A7000818041400100C1C0818041400100C1C02E +:104A8000818041400100C1C0818041400100C1C01E +:104A9000818041400100C1C081804140010000008F +:104AA00076DBB62D2449921BDBB649129294240979 +:104AB000090000002120E1E0A1A061602120E1E0E7 +:104AC000A1A061602120E1E0A1A061602120E1E0DE +:104AD000A1A061602120E1E0A1A061602120E1E0CE +:104AE000A1A061602120000076DBB62D2449921B35 +:104AF000DBB64912929424090900000063432303A2 +:104B0000E2C2A28262422202E2C2A2826242220285 +:104B1000E2C2A28262422202E2C2A2826242220275 +:104B2000E2C2A28262422202E2C2A2826242000089 +:104B300000D0B62D2D499224DBB66D1292242509A2 +:104B4000490200002C0CECCCAC8C6C4C2C0CECCC4A +:104B5000AC8C6C4C2C0CECCCAC8C6C4C2C0CECCC95 +:104B6000AC8C6C4C2C0CECCCAC8C6C4C2C0CEBCB87 +:104B7000AB8B6B4B2B0B00002D499224DBB66D12D7 +:104B8000922425094902000040DBB62DA484644428 +:104B90002404E3C3A38363432303E3C3A3836343E3 +:104BA0002303E3C3A38363432303E3C3A3836343D5 +:104BB0002303E3C3A38363432303E3C3A38300006B +:104BC0000000B42D6D4B9224E4B66D1B922449096C +:104BD00049920000EBCBAB8B6B4B2B0BEBCBAB8B36 +:104BE0006B4B2B0BEBCBAB8B6B4B2B0BEBCBAB8B15 +:104BF0006B4B2B0BEBCBAB8B6B4B2B0BEACAAA8A09 +:104C00006A4A2A0AEACA00002449921BDBB6491202 +:104C100092942409090000006DDBB624E5C5A58542 +:104C200065452505E4C4A48464442404E4C4A48440 +:104C300064442404E4C4A48464442404E4C4A48434 +:104C400064442404E4C4A48464442404E4C400004C +:104C50000000002D6DDB922424B96D1B9B244912AA +:104C600049922400AA8A6A4A2A0AEACAAA8A6A4A8D +:104C70002A0AEACAAA8A6A4A2A0AEACAAA8A6A4A94 +:104C80002A0AEACAAA8A6A4A2A0AE9C9A98969498A +:104C90002909E9C9A989000024496E1BDB264912AC +:104CA000529224090000002D6DDB92242606E6C6F0 +:104CB000A68666462606E5C5A58565452505E5C59E +:104CC000A58565452505E5C5A58565452505E5C594 +:104CD000A58565452505E5C5A5856545250500002E +:104CE000090000006DDBB62424496E1BDB26491247 +:104CF0005292240969492909E9C9A98969492909F7 +:104D0000E9C9A98969492909E9C9A9896949290913 +:104D1000E9C9A98969492909E8C8A888684828080B +:104D2000E8C8A8886848000024B96D1B9B24491274 +:104D3000499224000000B42D6D4B92246747270749 +:104D4000E7C7A78767472707E6C6A68666462606FB +:104D5000E6C6A68666462606E6C6A68666462606F3 +:104D6000E6C6A68666462606E6C6A686664600000F +:104D70004902000040DBB62D2449921BDBB64912E4 +:104D8000929424092808E8C8A88868482808E8C830 +:104D9000A88868482808E8C8A88868482808E8C893 +:104DA000A88868482808FFFFFFFFFFFFFFFFFFFFFD +:104DB000FFFFFFFFFFFF0000E4B66D1B92244909CF +:104DC0004992000000F0FF3FFFFFFF3FFFFFFFFFA2 +:104DD000FFFFFFFFFFFFFFFFFFFFE7C7A787674753 +:104DE0002707E7C7A78767472707E7C7A787674753 +:104DF0002707E7C7A78767472707E7C7A7870000F1 +:104E0000FFFFFF3FFFDFB62D2D499224DBB66D1269 +:104E100092242509636261605F5E5D5C5B5A59584C +:104E200057565554535251504F4E4D4C4B4A49488A +:104E300047464544434241403F3E3D3C3B3A39387A +:104E40003736353433320000000000000000000027 +:104E500000000000000000000000000031302F2E94 +:104E60002D2C2B2A292827262524232221201F1EEA +:104E70001D1C1B1A191817161514131211100F0EDA +:104E80000D0C0B0A090807060504030201000000C7 +:104E90000000000000000000000000000000000012 +:104EA00000000000FFFFFFFFFFFFFFFFFFFFFFFF0E +:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:104ED000FFFFFFFFFFFF0000FFFFFF3FFFFFFF3F60 +:104EE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFFFF12 +:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:104F0000FFFFFFFFFFFFFFFFFFFF000000000000AB +:104F10000000000000000000000000000000000091 +:104F2000FFFFFF3FFFFFFF3FFFFFFF3F00000000CD +:104F30000000000007172737475706162636465643 +:104F400005152535455504142434445403132333DF +:104F500043530212223242520111213141510010B9 +:104F600020304050FFFF0000000000000000000063 +:104F700000000000000000000000003F00020406E6 +:104F8000080A0C0E10121416181A1C1E20222426B1 +:104F9000282A2C2E30323436383A3C3E40424446A1 +:104FA000484A4C4E50525456585A5C5E606200005B +:104FB00000000000000000000000000000000000F1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE00000000000000000000000000000000000C1 +:104FF00000000000000000000000000000000000B1 +:1050000000000000000000000000000000000000A0 +:105010000000000000000000000000000000000090 +:105020000000000000000000000000000000000080 +:105030000000000000000000000000000000000070 +:105040000000000000000000000000000000000060 +:105050000000000000000000000000000000000050 +:105060000000000000000000000000000000000040 +:105070000000000000000000000000000000000030 +:105080000000000000000000000000000000000020 +:105090000000000000000000000000000000000010 +:1050A0000000000000000000000000000000000000 +:1050B00000000000000000000000000000000000F0 +:1050C00000000000000000000000000000000000E0 +:1050D00000000000000000000000000000000000D0 +:1050E00000000000000000000000000000000000C0 +:1050F00000000000000000000000000000000000B0 +:10510000000000000000000000000000000000009F +:10511000000000000000000000000000000000008F +:10512000000000000000000000000000000000007F +:10513000000000000000000000000000000000006F +:10514000000000000000000000000000000000005F +:10515000000000000000000000000000000000004F +:10516000000000000000000000000000000000003F +:10517000000000000000000000000000000000002F +:10518000000000000000000000000000000000001F +:10519000000000000000000000000000000000000F +:1051A00000000000000000000000000000000000FF +:1051B00000000000000000000000000000000000EF +:1051C00000000000000000000000000000000000DF +:1051D00000000000000000000000000000000000CF +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:105200001501010000000000000000003202100043 +:105210001B00000000000000000000000000000073 +:105220008C0C0000AF0C0000D20C0000F50C00004C +:10523000200300004110080344611C080000000026 +:10524000000000000000000000000000000000005E +:105250000A00000066666666560000000000000056 +:10526000000000000000000000000000000000003E +:105270000000000003080000180DD60D060E1F0EDA +:10528000530F580E300F420F430F7E1707B8C30756 +:1052900000800000208300000080328064809680BF +:1052A0002DB4040F110C0F0F10000F1325BD830A2E +:1052B00018C80F00130E130E0E410E4120030000FC +:1052C000CBB2300DCE0345120000000000000000FC +:1052D0000000000000000000000000000A000000C4 +:1052E00066666666560000000000000000000000D0 +:1052F0001111111111111111111100000000000004 +:1053000003080000180DD60D060E1F0E530F580E81 +:10531000300F420F430FAE0B07B80F330080000071 +:105320002083000000803280648096802DB4040FBA +:10533000110C0F0F90000F13A5BA830A18C80F00A5 +:10534000130E130E0E410E4145097E1707B8C30711 +:105350000080008020F3000C00803280648096FE84 +:105360002DB4FFFF11FDFFFFD0FF0F13A5BA830A75 +:1053700018C80F00130F130F0F410F411F03000038 +:105380000900000000000000000000000000000014 +:10539000188DD68D068E1F8E538F588E308F428F6C +:1053A000438F0000000000C000000000000000006B +:1053B00002000000000000000000000000000000EB +:1053C00000E60000EC0454E7E4077EE75509A20775 +:1053D0000A09250945097E1707B8C30700800000A0 +:1053E0002083000000803280648096802DB4048F7A +:1053F00011FDFFFFD0FF0F93A5BA830A18E80FE055 +:10540000130F13FF0F410F411F030000D4B8040214 +:105410000351188748F00C0C85011C08188DD68D97 +:10542000068E1F8E538F588E308F428F438F555567 +:10543000555555D55555000000000018086A666698 +:1054400066666666366600270000000002E6008099 +:10545000EC0C54EFE4877EE75509A2070AE925E939 +:105460000000000000000100002802000000FC0015 +:10547000000000000D000D0059064006000000006D +:105480000155970102000000000000000001020227 +:10549000002800008002FC00FFFFFF010D000D004E +:1054A00007000F000000000004B0B300000000106F +:1054B0000000000000020202002800008002FC0040 +:1054C000FFFFFF010D000D0006000E0000000000B0 +:1054D00004C4B3000000001000000000000302023A +:1054E000002800008002FC00FFFFFF010D000D00FE +:1054F00005000D000000000004D8B30000000010FB +:105500000000000000040202002800008002FC00ED +:10551000FFFFFF010D000D0004000C000000000063 +:1055200004ECB300000000100000000000050202BF +:10553000002800008002FC00FFFFFF010D000D00AD +:1055400003000B00000000000400B4000000001085 +:105550000000000000060202002800008002FC009B +:10556000FFFFFF010D000D0002000A000000000017 +:105570000414B40000000010000000000007020244 +:10558000002800008002FC00FFFFFF010D000D005D +:1055900001000900000000000428B4000000001011 +:1055A0000000000000080202002804008002FC0045 +:1055B000FFFFFF010D000D000000080000000000CB +:1055C00020B0B30000000010000000000000000048 +:1055D000002806000000FC00000000000D000D0087 +:1055E000D20FA00F00000000015097010000000042 +:1055F0000000000000000000002802000000FC0085 +:10560000000000000D000D00C116A81600000000EB +:10561000018C97010600000000000000000B020250 +:10562000002800008000FC00000000000D000D00BC +:1056300007000F000000000004B0B30000000010DD +:1056400000000000000C0202002800008000FC00A6 +:10565000000000000D000D0006000E00000000001C +:1056600004C4B3000000001000000000000D02029E +:10567000002800008000FC00000000000D000D006C +:1056800005000D000000000004D8B3000000001069 +:1056900000000000000E0202002800008000FC0054 +:1056A000000000000D000D0004000C0000000000D0 +:1056B00004ECB3000000001000000000000F020224 +:1056C000002800008000FC00000000000D000D001C +:1056D00003000B00000000000400B40000000010F4 +:1056E0000000000000100202002800008000FC0002 +:1056F000000000000D000D0002000A000000000084 +:105700000414B400000000100000000000110202A8 +:10571000002800008000FC00000000000D000D00CB +:1057200001000900000000000428B400000000107F +:105730000000000000120202002804008000FC00AB +:10574000000000000D000D00000008000000000037 +:1057500020B0B300000000104F00000001F404006E +:1057600068931B00600000000C00000001000400B2 +:105770001428000060000000300000002D008400AC +:10578000142800001C000000730000002DF48400A9 +:1057900068931B001C000000700000002DF48400C2 +:1057A00068931B001C000000630000002DF48400BF +:1057B00068931B001C000000630000002DF48400AF +:1057C00068931B001C0000004F00000001F404005F +:1057D00068931B00E00001000C00000001000400C1 +:1057E00014280000E0000100300000002D008400BB +:1057F000142800001C000000700000002DF484003C +:1058000068931B001C000000000000000000000066 +:105810000000000000000000000000000000000088 +:105820000000000000000000000000000000000078 +:105830000000000000000000000000000000000068 +:105840000000000000000000000000000000000058 +:105850000000000000000000000000000000000048 +:105860000000000000000000000000000000000038 +:1058700000000000000000000000000092249224BC +:105880009200920000000000224924492401A40053 +:105890000000000014492449240114010000000004 +:1058A000A4482449240122010000000024452429A1 +:1058B000240124010000000024292445240124019E +:1058C000000000002449A448220124010000000037 +:1058D00024491449140124010000000024492249EC +:1058E000A400240100000000FF7FFF7FFF01FF01F3 +:1058F00000000000B66DB66DB601B60100000000F4 +:10590000B26DB66DB601B60000000000966DB66DC2 +:10591000B601960100000000B66CB66DB601B2018A +:1059200000000000B665B62DB601B601000000000B +:10593000B62DB665B601B60100000000B66DB66CB6 +:10594000B201B60100000000B66D966D9601B60179 +:1059500000000000B66DB26DB600B6010000000098 +:10596000012800000000000000000000000000000E +:10597000000000020206AA006C768A94000106006C +:1059800000000000DB0600000106000091016E200F +:10599000418C3903010000C61D018C61000000002C +:1059A0000000000010100D100390BBBB8E5A22188F +:1059B000641164118A39893985E00FE06612641236 +:1059C00001280000000000000000000000000000AE +:1059D000000000020206AA006C768A94000106000C +:1059E00000000000DB0600000106000091016E20AF +:1059F000418C3903010000C61D018C6100000000CC +:105A00000000000010000C100380ABAA8044227834 +:105A1000641164118A39893985E005E066126412DF +:105A20000104000000000000000000000000000071 +:105A3000000000020200AA006C768A9400010600B1 +:105A400000000000DB060000040C000038066E2099 +:105A5000418C390301000084C4058C610000000002 +:105A60000000000010C40C500390BBBB804422789F +:105A7000641164118A39893985E00FE06612641275 +:105A8000D004020001020304CCF57AFDED20BF8FA3 +:105A9000CF0304021E0600036C768A940001060000 +:105AA00000000000DB06000001460000121B002081 +:105AB000006B39034100028400006B616478792B2C +:105AC000CF8A00801C5411980080BBBB00572278FD +:105AD000641164118A39893985E00FE06612641215 +:105AE0000100000001010101CCF57AFDED20BF8F1E +:105AF000CF030402020600006C768A9400010600BF +:105B000000000000DB060000000C0000401A00202E +:105B10004100380341000284000000606478792B62 +:105B2000CF8A00801C5410180380BBBB80462278AB +:105B3000641164118A39893985E00FE066126412B4 +:105B4000D004020002020202CCF57AFDED20BF8FE4 +:105B5000CF030402020600006C768A94000106005E +:105B600000000000DB06000001460000121B0020C0 +:105B7000006B39034100028400006B616478792B6B +:105B8000CF8A00801C5411980380BBBB80462278CA +:105B9000641164118A39893985E00FE06612641254 +:105BA0000100000003030303CCF57AFDED20BF8F55 +:105BB000CF030402020600006C768A9400010600FE +:105BC00000000000DB060000000C0000401A00206E +:105BD0004100380341000284000000606478792BA2 +:105BE000CF8A00801C5410180380BBBB80462278EB +:105BF000641164118A39893985E00FE066126412F4 +:105C0000D004020004040404CCF57AFDED20BF8F1B +:105C1000CF030402020600006C768A94000106009D +:105C200000000000DB06000001460000121B0020FF +:105C3000006B39034100028400006B616478792BAA +:105C4000CF8A00801C5411980380BBBB8046227809 +:105C5000641164118A39893985E00FE06612641293 +:105C60000100000000000000CCF57AFDED20BF8FA0 +:105C7000CF030402020600006C768A94000106003D +:105C800000000000DB060000000C0000FF3B0020CD +:105C90004100380341000284000000606478792BE1 +:105CA000CF8A00801CC410180300000000C62278B0 +:105CB000641164118039803905000F0055105510AA +:105CC000000000000000000000101000000092CD55 +:105CD0000000C180100F0002000087370000BBF1F8 +:105CE000100F00040000904100008B43100E0007CD +:105CF0000000BBF100009167100C000900001DFBC3 +:105D00000000709E100E000500000000C806000094 +:105D1000BAF15942BAF15942450EA63D1122334417 +:105D20005566778899AABBCCDDEEFF6900000000BC +:105D30000000000000000000000000000000000063 +:105D40000000000000000000C022C0224A4948476D +:105D5000464544434241403F3E3D3C3B3A3938375B +:105D6000363534333231302F2E2D2C2B2A2928274B +:105D7000262524232221201F1E1D1C1B1A1900006A +:105D80000000000000000000000000000000000013 +:105D90000000000031302F2E2D2C2B2A29282726F9 +:105DA0002524232221201F1E1D1C1B1A191817161B +:105DB0001514131211100F0E0D0C0B0A090807060B +:105DC00005040302010000000000000000000000C4 +:105DD0000000000000000000000000000020406003 +:105DE00080A0C0E00020406080A0C0E000204060B3 +:105DF00080A0C0E00020406080A0C0E000204060A3 +:105E000080A0C0E00020406080A0C0E00020000032 +:105E1000000000094992481292B46D1B1B4992245C +:105E20006DDBB6362000E0C0A08060402000E0C0FE +:105E3000A08060402000E0C0A08060402000E0C062 +:105E4000A08060402000E0C0A08060402000E0C052 +:105E5000A08060402000000076DBB62D2449921B14 +:105E6000DBB649129294240909000000533517F952 +:105E7000DBBD9F8163452709EBCDAF917355371982 +:105E8000FBDDBFA1836547290BEDCFB19375573972 +:105E90001BFDDFC1A38567492B0D8E7052340000B6 +:105EA0006D499224E4B66D1B9224490A499204007C +:105EB0000000B42D2002836547290BEDCFB1937507 +:105EC00057391BFDDFC1A38567492B0DEFD1B39572 +:105ED00077593B1DFFE1C3A587694B2D0FF1D3B562 +:105EE00097795B3D1F01000040DB962424C96D1BA0 +:105EF000DB264912529224090100000016F8DABC90 +:105F00009E8062442608EACCAE9072543618FADCC1 +:105F1000BEA0826446280AECCEB0927456381AFCB1 +:105F2000DEC0A28466482A0C8D6F513315F700003D +:105F300025499224DBB66D129224290949120000EA +:105F400000D0B6255D3F21038466482A0CEED0B20E +:105F50009476583A1CFEE0C2A486684A2C0EF0D211 +:105F6000B496785A3C1E00E2C4A6886A4C2E10F201 +:105F7000D4B6987A5C3E000000D0B6252449721B46 +:105F8000DBB6491292A4240949000000D9BB9D7FC9 +:105F900061432507E9CBAD8F71533517F9DBBD9F01 +:105FA0008163452709EBCDAF9173553719FBDDBFF1 +:105FB000A1836547290B8C6E503214F6D8BA0000C5 +:105FC0002449921BDBB6491292A42409490000001F +:105FD00040DB96249A7C5E4022048567492B0DEFB6 +:105FE000D1B39577593B1DFFE1C3A587694B2D0FB1 +:105FF000F1D3B597795B3D1F01E3C5A7896B4D2FA1 +:1060000011F3D5B7997B00000000B42D2549921CEF +:10601000DBB66D1292242909491200009C7E604271 +:106020002406E8CAAC8E70523416F8DABC9E806240 +:10603000442608EACCAE9072543618FADCBEA08230 +:106040006446280A8B6D4F3113F5D7B99B7D00004C +:1060500024496E1BDB26491292922409010000009C +:106060006D5B9224D7B99B7D5F41230586684A2CDE +:106070000EF0D2B496785A3C1E00E2C4A6886A4C50 +:106080002E10F2D4B6987A5C3E2002E4C6A88A6C40 +:106090004E3012F4D6B800000000002D6D49922455 +:1060A000E4B66D1B9224490A499204005F4123051E +:1060B000E7C9AB8D6F513315F7D9BB9D7F61432580 +:1060C00007E9CBAD8F71533517F9DBBD9F81634570 +:1060D00027098A6C4E3012F4D6B89A7C5E400000D4 +:1060E00024B96D1B9B2449124A9224010000002D03 +:1060F0006D49922414F6D8BA9C7E604224068769C2 +:106100004B2D0FF1D3B597795B3D1F01E3C5A789EF +:106110006B4D2F11F3D5B7997B5D3F2103E5C7A9DF +:106120008B6D4F3113F50000010000006D5B922470 +:1061300024B96D1B9B2449124A9224012204E6C80B +:10614000AA8C6E503214F6D8BA9C7E60422406E8BF +:10615000CAAC8E70523416F8DABC9E8062442608AF +:10616000FFFFFFFFFFFFFFFFFFFFFFFF2103000017 +:10617000E4B66D1B9224490A499204000000FC3FDA +:10618000FFFFFF24513315F7D9BB9D7F61432507DE +:10619000886A4C2E10F2D4B6987A5C3E2002E4C68F +:1061A000A88A6C4E3012F4D6B89A7C5E402204E67F +:1061B000C8AA8C6E503200004900000040DB9624D3 +:1061C00024496E1BDB26491292922409E5C7A98B4C +:1061D0006D4F3113F5D7B99B7D5F412305E7C9ABFF +:1061E0008D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:1061F000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000AD +:10620000DBB66D1292242909C9FFFF3FFFFFFF3F54 +:10621000FFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFF4E +:10622000FFFF896B4D2F11F3D5B7997B5D3FFFFFC2 +:10623000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:10624000FFFFFFFFFFFF0000FFFFFF3FFFDFB6255F +:106250002449FE3FFFFFFF3FFFFFFF3F5F5E5D5CA6 +:106260005B5A595857565554535251504F4E4D4CF6 +:106270004B4A494847464544434241403F3E3D3CE6 +:106280003B3A39383736353433323130FFFF00008E +:1062900000000000000000000000000000000000FE +:1062A0000000003F2F2E2D2C2B2A292827262524BD +:1062B000232221201F1E1D1C1B1A19181716151426 +:1062C000131211100F0E0D0C0B0A09080706050416 +:1062D00003020100FFFF00000000000000000000BA +:1062E00000000000000000000000003F000000006F +:1062F000000000000000000000000000000000009E +:10630000000000000000000000000000000000008D +:10631000000000000000000000000000000000007D +:10632000000000000000000000000000000000006D +:10633000000000000000000000000000000000005D +:10634000000000000000000000000000000000004D +:10635000000000000000000000000000000000003D +:10636000000000000000000000000000000000002D +:10637000000000000000000000000000000000001D +:10638000000000000000000000000000000000000D +:1063900000000000000000000000000000000000FD +:1063A00000000000000000000000000000000000ED +:1063B00000000000000000000000000000000000DD +:1063C00000000000000000000000000000000000CD +:1063D00000000000000000000000000000000000BD +:1063E00000000000000000000000000000000000AD +:1063F000000000000000000000000000000000009D +:10640000000000000000000000000000000000008C +:10641000000000000000000000000000000000007C +:10642000000000000000000000000000000000006C +:10643000000000000000000000000000000000005C +:10644000000000000000000000000000000000004C +:10645000000000000000000000000000000000003C +:10646000000000000000000000000000000000002C +:10647000000000000000000000000000000000001C +:10648000000000000000000000000000000000000C +:1064900000000000000000000000000000000000FC +:1064A00000000000000000000000000000000000EC +:1064B00000000000000000000000000000000000DC +:1064C00000000000000000000000000000000000CC +:1064D00000000000000000000000000000000000BC +:1064E00000000000000000000000000000000000AC +:1064F000000000000000000000000000000000009C +:10650000000000000000000000000000000000008B +:10651000000000000000000000000000000000007B +:10652000000000000000000000000000000000006B +:10653000000000000000000000000000000000005B +:10654000000000000000000000000000000000004B +:10655000000000000000000000000000000000003B +:10656000000000000000000000000000000000002B +:10657000000000000000000000000000000000001B +:10658000000000000000000000000000000000000B +:1065900000000000000000000000000000000000FB +:1065A00000000000000000000000000000000000EB +:1065B00000000000000000000000000000000000DB +:1065C00000000000000000000000000000000000CB +:1065D00000000000000000000000000000000000BB +:1065E00000000000000000000000000000000000AB +:1065F000000000000000000000000000000000009B +:10660000000000000000000000000000000000008A +:10661000000000000000000000000000000000007A +:10662000000000000000000000000000000000006A +:10663000000000000000000000000000000000005A +:10664000000000000000000000000000000000004A +:10665000000000000000000000000000000000003A +:10666000000000000000000000000000000000002A +:10667000000000000000000000000000000000001A +:10668000000000000000000000000000000000000A +:1066900000000000000000000000000000000000FA +:1066A00000000000000000000000000000000000EA +:1066B00000000000000000000000000000000000DA +:1066C00000000000000000000000000000000000CA +:1066D00000000000000000000000000000000000BA +:1066E00000000000000000000000000000000000AA +:1066F000000000000000000000000000000000009A +:106700000000000000000000000000000000000089 +:106710000000000000000000000000000000000079 +:106720000000000000000000000000000000000069 +:106730000000000000000000000000000000000059 +:106740000000000000000000000000000000000049 +:106750000000000000000000000000000000000039 +:106760000000000000000000000000000000000029 +:106770000000000000000000000000000000000019 +:106780000000000000000000000000000000000009 +:1067900000000000000000000000000000000000F9 +:1067A00000000000000000000000000000000000E9 +:1067B00000000000000000000000000000000000D9 +:1067C00000000000000000000000000000000000C9 +:1067D00000000000000000000000000000000000B9 +:1067E00000000000000000000000000000000000A9 +:1067F0000000000000000000000000000000000099 +:106800000000000000000000000000000000000088 +:106810000000000000000000000000000000000078 +:106820000000000000000000000000000000000068 +:106830000000000000000000000000000000000058 +:106840000000000000000000000000000000000048 +:106850000000000000000000000000000000000038 +:106860000000000000000000000000000000000028 +:106870000000000000000000000000000000000018 +:106880000000000000000000000000000000000008 +:1068900000000000000000000000000000000000F8 +:1068A00000000000000000000000000000000000E8 +:1068B00000000000000000000000000000000000D8 +:1068C00000000000000000000000000000000000C8 +:1068D00000000000000000000000000000000000B8 +:1068E00000000000000000000000000000000000A8 +:1068F0000000000000000000000000000000000098 +:106900000000000000000000000000000000000087 +:106910000000000000000000000000000000000077 +:106920000000000000000000000000000000000067 +:106930000000000000000000000000000000000057 +:106940000000000000000000000000000000000047 +:106950000000000000000000000000000000000037 +:106960000000000000000000000000000000000027 +:106970000000000000000000000000000000000017 +:106980000000000000000000000000000000000007 +:1069900000000000000000000000000000000000F7 +:1069A00000000000000000000000000000000000E7 +:1069B00000000000000000000000000000000000D7 +:1069C00000000000000000000000000000000000C7 +:1069D00000000000000000000000000000000000B7 +:1069E00000000000000000000000000000000000A7 +:1069F0000000000000000000000000000000000097 +:106A0000150101000000000000000000320210002B +:106A10001000000000000000000000000000000066 +:106A200099120000BC120000DF12000002130000E7 +:106A300025130000481300006B1300008E130000A4 +:106A4000B1130000D4130000F71300001A14000063 +:106A50003D1400006014000083140000A614000020 +:106A6000C914000020030000D4B804020351180028 +:106A700007B28C2363200C0485011C080000000071 +:106A800000000000190000005B555555555555553F +:106A90005555555505000000080A000010000A0071 +:106AA000000000010000000002E00000EC14541699 +:106AB00084167E17411AA2176A199119B1197E1707 +:106AC00007B8C307008000002083000000803280E8 +:106AD000648096802DB4040F110C0F0F10000F135B +:106AE000A5BA830A18C80F001510151010431043DB +:106AF00020030000D4A8040C42330E0EC4338E23AE +:106B000063011911E32101132302000000000000BA +:106B10001B0000005B555555555555555555555558 +:106B20005505000098090B0BB0B00000B0B0001B79 +:106B30000B00000082F01002EC14541684167E172D +:106B4000411AA2176A199119B1197E1707B8C3071C +:106B500000800000208300000080328064809680E6 +:106B60002DB4040F110C0F0F10000F13A5BA830AD8 +:106B700018C80F0015101510104310432003000013 +:106B800009000000000000000000000000000000FC +:106B900000000000000000000000000001000000F4 +:106BA00003000000000000000000000000000000E2 +:106BB00002000000000000000000000000000000D3 +:106BC00000000000EC14541684167E17411AA21718 +:106BD0006A199119B1197E1707B8C3070080000020 +:106BE0002083000000803280648096802DB4040FE2 +:106BF000110C0F0F10000F13A5BA830A18C80F004D +:106C0000151015101043104320030000D4B80402DF +:106C10000351180007B28C2363200C0485011C0863 +:106C20000000000000000000190000005B555555F1 +:106C3000555555555555555555000000086A666619 +:106C400036666A66666666636600000002E00000FB +:106C5000EC14541684167E17411AA2176A1991195A +:106C6000B1197E1707B8C307008000002083000019 +:106C700000803280648096802DB4040F110C0F0FB9 +:106C800010000F13A5BA830A18C80F0015101510AD +:106C90001043104320030000D4A8040C42330E0E0E +:106CA000C4338E2363011911E32101132302000071 +:106CB000000000001B0000005B555555555555550B +:106CC000555555555505000098696B6BB6B6666607 +:106CD000B6B6663B6B06000082F01002EC14541648 +:106CE00084167E17411AA2176A199119B1197E17D5 +:106CF00007B8C307008000002083000000803280B6 +:106D0000648096802DB4040F110C0F0F10000F1328 +:106D1000A5BA830A18C80F001510151010431043A8 +:106D200020030000D4B8541617960100000000009C +:106D30000000000000000000000000000000000053 +:106D4000080000005B5555550000000000000000E1 +:106D500000000000081A11110000000000000000EF +:106D60000000000002000000EC14541684167E1788 +:106D7000411AA2176A199119B1197E1707B8C307EA +:106D800000800000208300000080328064809680B4 +:106D90002DB4040F110C0F0F10000F13A5BA830AA6 +:106DA00018C80F00151015101043104320030000E1 +:106DB000D4B854161796010000000000000000002F +:106DC00000000000000000000000000008000000BB +:106DD0005B55555500000000000000000000000059 +:106DE000083A3333000000000000000000000000FB +:106DF00002000000EC14541684167E17411AA217E4 +:106E00006A199119B1197E1707B8C30700800000ED +:106E10002083000000803280648096802DB4040FAF +:106E2000110C0F0F10000F13A5BA830A18C80F001A +:106E3000151015101043104320030000D4A8540C63 +:106E4000567339184F068D11A3344E000000000010 +:106E50000000000000000000130000005B555555C5 +:106E600055555555550500000000000008191B1B1D +:106E70001B1B0B0B0B0B00000000000002A002000C +:106E8000EC14541684167E17411AA2176A19911928 +:106E9000B1197E1707B8C3070080000020830000E7 +:106EA00000803280648096802DB4040F110C0F0F87 +:106EB00010000F13A5BA830A18C80F00151015107B +:106EC0001043104320030000D4A8540C5673391803 +:106ED0004F068D11A3344E0000000000000000009A +:106EE00000000000130000005B55555555555555E1 +:106EF000550500000000000008393B3B3B3B0B0BF5 +:106F00000B0B00000000000002A00200EC1454165D +:106F100084167E17411AA2176A199119B1197E17A2 +:106F200007B8C30700800000208300000080328083 +:106F3000648096802DB4040F110C0F0F10000F13F6 +:106F4000A5BA830A18C80F00151015101043104376 +:106F500020030000D4A8051B023774045E311A23F5 +:106F6000C7088C08000000000000000000000000BE +:106F7000140000005B5555555555555555550000A5 +:106F800000000000080909090909000010000000BC +:106F90000000000002500500EC14541684167E1701 +:106FA000411AA2176A199119B1197E1707B8C307B8 +:106FB0000080000020830000008032806480968082 +:106FC0002DB4040F110C0F0F10000F13A5BA830A74 +:106FD00018C80F00151015101043104320030000AF +:106FE000D4A8051B023774045E311A23C7088C0825 +:106FF000000000000000000000000000140000007D +:107000005B55555555555555555500000000000028 +:10701000086969696969606030600000000000000B +:1070200002500500EC14541684167E17411AA2175C +:107030006A199119B1197E1707B8C30700800000BB +:107040002083000000803280648096802DB4040F7D +:10705000110C0F0F10000F13A5BA830A18C80F00E8 +:10706000151015101043104320030000D4A8551B21 +:10707000167775185E060000000000000000000092 +:1070800000000000000000000C0000005B5555559A +:1070900055550000000000000000000008191919F3 +:1070A00019190000000000000000000002000000AC +:1070B000EC14541684167E17411AA2176A199119F6 +:1070C000B1197E1707B8C3070080000020830000B5 +:1070D00000803280648096802DB4040F110C0F0F55 +:1070E00010000F13A5BA830A18C80F001510151049 +:1070F0001043104320030000D4A8551B16777518C1 +:107100005E0600000000000000000000000000001B +:10711000000000000C0000005B555555555500005F +:10712000000000000000000008393939393900003A +:10713000000000000000000002000000EC145416E3 +:1071400084167E17411AA2176A199119B1197E1770 +:1071500007B8C30700800000208300000080328051 +:10716000648096802DB4040F110C0F0F10000F13C4 +:10717000A5BA830A18C80F00151015101043104344 +:1071800020030000E3180803446100070800000022 +:1071900000000000000000000000000000000000EF +:1071A0000B00000055555555550500000000000026 +:1071B00000000000000000000100000000000000CE +:1071C0000000000003000000EC14541684167E1723 +:1071D000411AA2176A199119B1197E1707B8C30786 +:1071E0000080000020830000008032806480968050 +:1071F0002DB4040F110C0F0F10000F13A5BA830A42 +:1072000018C80F001510151010431043200300007C +:10721000D4B80000000000000000000000000000E2 +:10722000000000000000000000000000030000005B +:107230005B050000000000000000000000000000EE +:10724000080A00000000000000000000000000002C +:1072500002000000EC14541684167E17411AA2177F +:107260006A199119B1197E1707B8C3070080000089 +:107270002083000000803280648096802DB4040F4B +:10728000110C0F0F10000F13A5BA830A18C80F00B6 +:1072900015101510104310432003000009050000CD +:1072A00000000000C002000000000000000000001C +:1072B0000000000000000000020000006466666636 +:1072C0006666000000000000000000008200000070 +:1072D00000A000000000000000000000FC0700000B +:1072E000EC14541684167E17411AA2176A199119C4 +:1072F000B1197E1707B8C307008000002083000083 +:1073000000803280648096802DB4040F110C0F0F22 +:1073100010000F13A5BA830A18C80F001510151016 +:107320001043104320030000813010050670200038 +:10733000000000000000000000000000000000004D +:1073400000000000090000005555555505000000DB +:10735000000000000000000000000001000000002C +:10736000000000000000000000000000EC145416B3 +:1073700084167E17411AA2176A199119B1197E173E +:1073800007B8C3070080000020830000008032801F +:10739000648096802DB4040F110C0F0F10000F1392 +:1073A000A5BA830A18C80F00151015101043104312 +:1073B0000000000000000001000003000000FC00CD +:1073C000000000000D000D0008072107000000006C +:1073D0000155B4000200000000000000010103029A +:1073E000000001000000FC00000000000D000D0086 +:1073F00010001F000000000004B0B30000000010E7 +:107400000000000002020302000001000000FC0076 +:10741000000000000D000D0011001E000000000023 +:1074200004C4B300000000100000000003030302C6 +:10743000000001000000FC00000000000D000D0035 +:1074400012001D000000000004D8B300000000106E +:107450000000000004040302000001000000FC0022 +:10746000000000000D000D0013001C0000000000D3 +:1074700004ECB3000000001000000000050503024A +:10748000000001000000FC00000000000D000D00E5 +:1074900014001B00000000000400B40000000010F5 +:1074A0000000000006060302000001000000FC00CE +:1074B000000000000D000D0015001A000000000083 +:1074C0000414B400000000100000000007070302CD +:1074D000000001000000FC00000000000D000D0095 +:1074E00016001900000000000428B400000000107D +:1074F0000000000008080302000005000000FC0076 +:10750000000000000D000D00170018000000000032 +:10751000043CB4000000001000000000090000015D +:10752000000007000000FC00000000000D000D003E +:1075300004101D10000000000150B4000000000005 +:107540000000000000000001000003000000FC003B +:10755000000000000D000D008917701700000000EA +:1075600001A0B40006000000000000000000171792 +:10757000000003000000FC00000000000D000D00F2 +:107580009C189D1800000000019BB400040000003E +:107590000000000000001616010003000000FD00BE +:1075A000000000000D000D00301138110000FE2514 +:1075B0000473B4000400000000000000000017176E +:1075C000020003000000FC00000000000D000D00A0 +:1075D000C012C1120000FE250487B40004000000A0 +:1075E0000000000000001616030003000000FD006C +:1075F000000000000D000D00301138110000FE25C4 +:107600000473B4000400000000000000000017171D +:10761000040003000000FC00000000000D000D004D +:10762000C012C1120000FE250487B400040000004F +:107630000000000000001616050003000000FD0019 +:10764000000000000D000D00301138110000FE2573 +:107650000473B400040000000000000000001717CD +:10766000060003000000FC00000000000D000D00FB +:10767000C012C1120000FE250487B40004000000FF +:107680000000000000001616070003000000FD00C7 +:10769000000000000D000D00301138110000FE2523 +:1076A0000473B4000400000000000000000017177D +:1076B000080003000000FC00000000000D000D00A9 +:1076C000C012C1120000FE250487B40004000000AF +:1076D00000000000000A1414092802000000FC0049 +:1076E0000000000005000500000000000000000090 +:1076F00001009703000000000000000000000001EE +:10770000000003000000FC00000000000D000D0060 +:10771000C800E10000000000015AB40002000000AF +:107720000000000000000001000003000000FC0059 +:10773000000000000D000D00580271020000000062 +:10774000015FB40002000000000000000000000122 +:10775000000003000000FC00000000000D000D0010 +:10776000E8030104000000000164B400020000000E +:107770000000000000000001000003000000FC0009 +:10778000000000000D000D007805910500000000CC +:107790000169B400020000000000000000000001C8 +:1077A000000003000000FC00000000000D000D00C0 +:1077B0000807210700000000016EB400020000006D +:1077C0000000000000000100000003000000FC00B9 +:1077D000000000000D000D003011491100000000F4 +:1077E00001A5B40006000000000000000000010038 +:1077F000000003000000FC00000000000D000D0070 +:10780000C012D9120000000001AAB4000600000056 +:107810000000000000000100000003000000FC0068 +:10782000000000000D000D0050146914000000005D +:1078300001AFB400060000000000000000000100DD +:10784000000003000000FC00000000000D000D001F +:10785000E015F9150000000001B4B40006000000B6 +:107860000000000000000100000003000000FC0018 +:10787000000000000D000D007017891700000000C7 +:1078800001B9B40006000000000000000000010083 +:10789000002802000000FC000000000009000900B0 +:1078A0000000000000000000010097030600000037 +:1078B00000000000000B1414002802000000FC006F +:1078C000000000000C000C000000000000000000A0 +:1078D000010097030000000000000000000B1414DA +:1078E000002802000000FC003F0000000C000C001B +:1078F00000000000000000000100970300000000ED +:1079000000000000000B1515002802000000CC004C +:10791000000000000C000C0000000000000000004F +:1079200001009703000000000000000000000100BB +:10793000002802000000FC00000000000D000D0007 +:107940000000000000000000010097030600000096 +:107950004F00000001F4040068931B006000000069 +:107960000C0000000100040014280000600000006A +:10797000300000002D008400142800001C000000CE +:10798000730000002DF4840068931B001C000000AD +:10799000700000002DF4840068931B001C000000A0 +:1079A0007300000023F4840068931B001C00000097 +:1079B0006000000050F4840094EB1B001C000000E9 +:1079C0004F00000001F4040068931B00E000010078 +:1079D0000C0000000100040014280000E000010079 +:1079E000300000002D008400142800001C0000005E +:1079F000700000002DF4840068931B001C00000040 +:107A0000730000002DF4840051651B001C00000071 +:107A10000101010101010101010101010101010156 +:107A20000101010101010101010101010101010146 +:107A30000101010101010101010101010101010136 +:107A40000101010101010101010101010101010126 +:107A50000101010101010101010101010101010116 +:107A60000101010101010101010101010101010106 +:107A7000010101012B2B2B2D2C2B2C2D2B2C2D2DF3 +:107A80002C2D2D2D2B2B2D2D2B2D2C2F2C2D2D2D2D +:107A90002C2B2D2E2D2C2D2D2C2C2E2D2D2C2F2D19 +:107AA0002C2D2D2E2D2C2D2E2D2C2D2E2D2D2E2E04 +:107AB0002C2D2E2E2C2C2F2E2C2D2E2F2D2C2E2EF1 +:107AC0002D2C2E2E2E2D2D2F2C2D2F2E2D2D2F2FDC +:107AD0002D2F2D312B2A2B2B2B2B2B2C2B2B2B2CE7 +:107AE0002B2C2D2C2C2D2D2C2B2B2D2D2B2D2C2ED2 +:107AF0002C2D2D2D2C2B2D2D2D2C2D2D2C2C2E2DBC +:107B00002D2C2F2D2C2D2D2E2C2C2D2D2D2C2D2EA6 +:107B10002D2D2E2E2D2D2E2E2C2C2E2D2C2D2E2F90 +:107B20002D2C2D2E2D2C2E2E2E2D2D2F2C2D2F2E7F +:107B30002D2D2E2F2D2E2D302A2A2A2B2B2B2B2C80 +:107B40002B2B2B2C2A2B2D2C2B2D2D2C2B2B2D2D79 +:107B50002B2D2C2E2C2C2D2D2C2B2D2D2D2C2D2D5D +:107B60002C2C2E2D2D2C2F2D2C2D2D2E2C2C2C2D48 +:107B70002D2B2D2E2D2D2E2D2C2D2D2E2C2C2E2D36 +:107B80002C2D2E2F2D2C2D2E2D2C2D2E2D2D2D2F21 +:107B90002C2D2F2E2D2D2E2F2D2E2D2F2A2A2A2B18 +:107BA0002B2B2B2C2B2B2B2C2A2B2D2C2B2D2C2C1D +:107BB0002B2B2D2D2B2D2C2E2C2C2D2C2C2B2D2D01 +:107BC0002D2C2D2D2C2C2E2D2D2C2F2D2C2D2D2EE6 +:107BD0002C2C2D2D2D2C2D2E2D2D2E2E2C2D2E2ED4 +:107BE0002C2C2E2D2C2D2E2F2D2C2D2E2D2C2E2EC3 +:107BF0002E2D2D2E2C2D2F2E2D2D2E2F2D2E2D2FAB +:107C00002A2A2A2B2B2B2B2C2B2B2B2C2A2B2C2CC4 +:107C10002B2D2C2C2B2B2D2D2B2D2C2E2C2C2D2CA1 +:107C20002C2B2D2D2D2C2D2D2C2C2E2D2D2C2F2C89 +:107C30002B2D2D2E2C2C2C2D2D2B2D2E2D2D2E2D78 +:107C40002C2D2D2E2C2C2E2D2C2D2E2E2D2C2D2E64 +:107C50002D2C2E2E2D2D2D2E2C2D2F2E2D2D2E2F4D +:107C60002D2E2D2F2A2A2A2B2B2B2B2C2B2B2B2C5A +:107C70002A2B2D2C2B2D2C2C2B2B2D2D2B2D2C2E44 +:107C80002C2C2D2C2C2B2D2D2D2C2D2D2C2C2E2D2C +:107C90002D2C2F2D2C2D2D2E2C2C2C2D2D2C2D2E16 +:107CA0002D2D2E2D2C2D2E2E2C2C2E2D2C2D2E2E02 +:107CB0002D2C2D2E2D2C2E2E2D2D2D2F2C2D2F2EEF +:107CC0002D2D2E2F2D2E2D2F2A2A2A2B2B2B2B2CF0 +:107CD0002B2B2B2C2A2B2D2C2B2D2C2C2B2B2D2DE9 +:107CE0002B2D2C2E2C2C2D2C2C2B2D2D2D2C2D2DCD +:107CF0002C2C2E2D2D2C2F2C2C2D2D2E2C2C2C2DB8 +:107D00002D2B2D2E2D2D2E2E2C2D2D2E2C2C2E2DA3 +:107D10002C2D2E2E2D2C2D2E2D2C2D2E2D2D2D2E91 +:107D20002C2D2F2E2D2D2E2F2D2E2D2F2A2A2A2B86 +:107D30002B2B2B2C2B2B2B2C2B2C2D2C2C2D2C2C88 +:107D40002B2B2D2D2B2D2C2E2C2D2D2C2C2B2D2D6E +:107D50002D2C2D2D2C2C2E2D2D2C2F2C2C2D2D2E55 +:107D60002C2C2C2D2D2C2D2E2D2D2E2E2C2D2E2E43 +:107D70002C2C2E2E2C2D2E2F2D2C2D2E2D2C2E2E30 +:107D80002E2D2D2F2C2D2F2E2D2D2E2F2D2E2D3017 +:107D90002A2A2B2B4D4D4D4D4D4D4D4D4D4D4D4D9D +:107DA0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D03 +:107DB0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4DF3 +:107DC0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4DE3 +:107DD0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4DD3 +:107DE0004D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4DC3 +:107DF0004D4D4D4D4D4D4D4D92249224920092008B +:107E000000000000B66DB66DB600B60000000000C0 +:107E1000B66DB66D9601960100000000B66DB66DA8 +:107E2000B201B20100000000B62DB62DB601B601B8 +:107E300000000000B665B665B601B601000000009E +:107E4000B66CB66CB601B60100000000966D966D7A +:107E5000B601B60100000000B26DB26DB601B60108 +:107E600000000000FF7FFF7FFF01FF010000000016 +:107E7000B66DB66DB601B6010000000092249224E2 +:107E800092009200000000000110000000000000BD +:107E900000000000FFFF3DDB38D4FC020200AA0016 +:107EA0006C768A940001060000000000DB060000EA +:107EB000040C000060056E40415639030100009A31 +:107EC000EC045661000000000000000010C40C50DB +:107ED0000390BBBB804422786411641189398939CD +:107EE0000FE00FE0641264120110000000000000B7 +:107EF00000000000FFFF3DDB38D4FC020200AA00B6 +:107F00006C768A940001060000000000DB06000089 +:107F1000040C000060056E40415639030100009AD0 +:107F2000EC045661000000000000000010C40C10BA +:107F3000E39EBBBB8055227864116411893989396D +:107F40000FE00FE064126412010400000000000062 +:107F50000000000000000000000000020200AA0073 +:107F60006C768A940001060000000000DB06000029 +:107F7000040C000020066E40418639030100009A7F +:107F8000AC058661000000000000000010C40C5029 +:107F90000390BBBB8044227864116411893989390C +:107FA0000FE00FE064126412C9040200010203042E +:107FB000EAF7FAFD3001A880CF0304021E00000397 +:107FC0006C768A940001060000000000DB060000C9 +:107FD000014600002B1A0040006B39034100029A51 +:107FE00000006B616478792BCF8A00801C54119853 +:107FF0000080BBBB0057227864116411893989392C +:108000000FF00FF064126412C904020001010101B3 +:10801000EAF7FAFD3001A880CF0304020200000055 +:108020006C768A940001060000000000DB06000068 +:10803000014600002B1A0040006B39034100029AF0 +:1080400000006B61BB7DFC17FFFF00801C54119882 +:108050000380BBBB80462278641164118939893959 +:108060000FF00FF064126412C9040200020202024F +:10807000EAF7FAFD3001A880CF03040202000000F5 +:108080006C768A940001060000000000DB06000008 +:10809000014600002B1A0040006B39034100029A90 +:1080A00000006B610F7E3416FFFF00801C54119896 +:1080B0000380BBBB804622786411641189398939F9 +:1080C0000FF00FF064126412C904020003030303EB +:1080D000EAF7FAFD3001A880CF0304020200000095 +:1080E0006C768A940001060000000000DB060000A8 +:1080F000014600002B1A0040006B39034100029A30 +:1081000000006B61B17E3C12FFFF00801C5411988F +:108110000380BBBB80462278641164118939893998 +:108120000FF00FF064126412C90402000404040486 +:10813000EAF7FAFD3001A880CF0304020200000034 +:108140006C768A940001060000000000DB06000047 +:10815000014600002B1A0040006B39034100029ACF +:1081600000006B611C7F0B0FFFFF00801C541198F7 +:108170000380BBBB80462278641164118939893938 +:108180000FF00FF0641264120104000400000000FC +:10819000CCF57AFDED20BF8FCF030402020600006C +:1081A0006C768A940001060000000000DB060000E7 +:1081B00001060000093C0040006B39034100029AAF +:1081C00000006B616478792BCF8A00801CC4101882 +:1081D0000380AAAA00C6227864116411803980390C +:1081E0000F000F00550D550DC904020006070A0BBC +:1081F000EAF7FAFD3001A880CF0304021E0600034F +:108200006C768A940001060000000000DB06000086 +:10821000014600002B1A0040006B39034100029A0E +:1082200000006B616478792BCF8A00801C54119810 +:108230000080BBBB00572218641164118939893949 +:108240000FF00FF064126412C9040200060606065D +:10825000EAF7FAFD3001A880CF030402020600000D +:108260006C768A940001060000000000DB06000026 +:10827000014600002B1A0040006B39034100029AAE +:1082800000006B616478792BCF8A00801C541198B0 +:108290000080BBBB005722186411641189398939E9 +:1082A0000FF00FF064126412C904020006060A0AF5 +:1082B000EAF7FAFD3001A880CF0304020A060100A4 +:1082C0006C768A940043060100000000DB06000083 +:1082D000014600002B1A0040006B39034100029A4E +:1082E00000006B619367CBB40000008012541198BA +:1082F0000080BBBB0056221864116411893989398A +:108300000FF00FF064126412C904020007070B0B90 +:10831000EAF7FAFD3001A880CF0304020A06010043 +:108320006C768A940043060100000000DB06000022 +:10833000014600002B1A0040006B39034100029AED +:1083400000006B6155737BC80000008012541198C7 +:108350000080BBBB00562218641164118939893929 +:108360000FF00FF064126412C904020009090C0C2A +:10837000EAF7FAFD3001A880CF0304020A060100E3 +:108380006C768A940043060100000000DB060000C2 +:10839000014600002B1A0040006B39034100029A8D +:1083A00000006B61D9770ED3000000801254119841 +:1083B0000080BBBB005622186411641189398939C9 +:1083C0000FF00FF064126412C90402000A0A0606D4 +:1083D000EAF7FAFD3001A880CF0304020A06010083 +:1083E0006C768A940043060100000000DB06000062 +:1083F000014600002B1A0040006B39034100029A2D +:1084000000006B61BD7977D800000080125411988C +:108410000080BBBB00562218641164118939893968 +:108420000FF00FF064126412C90402000B0B07076F +:10843000EAF7FAFD3001A880CF0304020A06010022 +:108440006C768A940043060100000000DB06000001 +:10845000014600002B1A0040006B39034100029ACC +:1084600000006B61757B34DE0000008012541198AF +:108470000080BBBB00562218641164118939893908 +:108480000FF00FF064126412C90402000A0A060613 +:10849000EAF7FAFD3001A880CF0304020A060100C2 +:1084A0006C768A940043060100000000DB060000A1 +:1084B000014600002B1A0040006B39034100029A6C +:1084C00000006B61CB7C87E30000008012541198A0 +:1084D0000080BBBB005622186411641189398939A8 +:1084E0000FF00FF064126412C90402000B0B0707AF +:1084F000EAF7FAFD3001A880CF0304020A06010062 +:108500006C768A940043060100000000DB06000040 +:10851000014600002B1A0040006B39034100029A0B +:1085200000006B61F27D29E900000080125411986F +:108530000080BBBB00562218641164118939893947 +:108540000FF00FF064126412C90402000C0C090948 +:10855000EAF7FAFD3001A880CF0304020A06010001 +:108560006C768A940043060100000000DB060000E0 +:10857000014600002B1A0040006B39034100029AAB +:1085800000006B61D57EC2EE00000080125411988D +:108590000080BBBB005622186411641189398939E7 +:1085A0000FF00FF0641264120000000000000000E1 +:1085B00000101000FFFF56CE000099103F0E30064D +:1085C000FFFFFDF900006FA13F0E3005FFFF464F92 +:1085D000000029A63F0F3004FFFFAD8700007DD9C2 +:1085E0003F0F30030000C15A00009C9A0004103075 +:1085F0000000BCA00000903800091033000083D0B8 +:108600000000D635000B10350000C9C200001A5911 +:10861000000C103600008CA100002C9F000D1037BC +:1086200000009851000044DC000E10380000BEEA43 +:108630000000A536000E103A000026620000DD9909 +:10864000000F103B000000006400000070000000FC +:108650008900000098000000C9000000D700000059 +:10866000F1000000000100004000000000000000D8 +:1086700000000000000000000000000000000000FA +:1086800000000000000000000000000000000000EA +:1086900000000000000000000000000000000000DA +:1086A00000000000000000000000000000000000CA +:1086B00000000000000000000000000000000000BA +:1086C00000000000870700008579385793F930A132 +:1086D000B3D4CC2BCB0AF200000000000000000055 +:1086E000000000000000000000000000000000008A +:1086F000000000000000000000000000000000007A +:1087000080220022870700008579385793E4C2B998 +:1087100030AFCC2BC5A1B30000000000000000006A +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:1087400080220022870700008579385793E4C2BC55 +:10875000C2BCD7930D79300000000000000000007B +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800080220022870700008579385793E4C2BF12 +:10879000930ACC2BC4F50D0000000000000000007F +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00080220022870700008579385793E4C2BFD2 +:1087D000930AE4C2B286CF0000000000000000004F +:1087E0000000000000000000000000000000000089 +:1087F0000000000000000000000000000000000079 +:1088000080220022870700008579385793E4C2BF91 +:10881000930AB0AF26CF5000000000000000000017 +:108820000000000000000000000000000000000048 +:108830000000000000000000000000000000000038 +:1088400080220022870700008579385793E4C2BB55 +:108850000AF2E4C2BE4C2B00000000000000000041 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800080220022870700008579385793E4C2BB15 +:108890000AF2B0AF295E4C000000000000000000AA +:1088A00000000000000000000000000000000000C8 +:1088B00000000000000000000000000000000000B8 +:1088C00080220022C8060000450EA63D450EA63DAA +:1088D000BAF15942450EA63D450EA63D450EA63DB0 +:1088E000450EA63D00000000000000000000000052 +:1088F0000000000000000000000000000000000078 +:1089000080220022000102030405060708090A0B61 +:108910000C0D0E0F101112131415161718191A1B1F +:108920001C1D1E1F202122232425262728292A2B0F +:108930002C2D2E2F30310000000000000000000020 +:10894000000000000000000000000000191A1B1CBD +:108950001D1E1F202122232425262728292A2B2CCF +:108960002D2E2F303132333435363738393A3B3CBF +:108970003D3E3F404142434445464748494A000046 +:1089800000000000000000000000000000000000E7 +:10899000000000000020406080A0C0E00020406097 +:1089A00080A0C0E00020406080A0C0E000204060C7 +:1089B00080A0C0E00020406080A0C0E000204060B7 +:1089C00080A0C0E000200000000000094992481289 +:1089D00092B46D1B1B4992246DDBB63600204060BB +:1089E00080A0C0E00020406080A0C0E00020406087 +:1089F00080A0C0E00020406080A0C0E00020406077 +:108A000080A0C0E00020406080A0C0E00020000006 +:108A1000000000094992481292B46D1B1B49922430 +:108A20006DDBB6362021E0E1A0A160612021E0E10C +:108A3000A0A160612021E0E1A0A160612021E0E12E +:108A4000A0A160612021E0E1A0A160612021E0E11E +:108A5000A0A160612021000076DBB62D2449921B85 +:108A6000DBB6491292942409090000000100C1C03C +:108A7000818041400100C1C0818041400100C1C0EE +:108A8000818041400100C1C0818041400100C1C0DE +:108A9000818041400100C1C081804140010000004F +:108AA00076DBB62D2449921BDBB649129294240939 +:108AB000090000002120E1E0A1A061602120E1E0A7 +:108AC000A1A061602120E1E0A1A061602120E1E09E +:108AD000A1A061602120E1E0A1A061602120E1E08E +:108AE000A1A061602120000076DBB62D2449921BF5 +:108AF000DBB6491292942409090000007353331322 +:108B0000F2D2B29272523212F2D2B2927252321245 +:108B1000F2D2B29272523212F2D2B2927252321235 +:108B2000F2D2B29272523212F2D2B2927252000069 +:108B300000D0B62D2D499224DBB66D129224250962 +:108B4000490200003C1CFCDCBC9C7C5C3C1CFCDC4A +:108B5000BC9C7C5C3C1CFCDCBC9C7C5C3C1CFCDC55 +:108B6000BC9C7C5C3C1CFCDCBC9C7C5C3C1CFBDB47 +:108B7000BB9B7B5B3B1B00002D499224DBB66D1237 +:108B8000922425094902000040DBB62DB4947454A8 +:108B90003414F3D3B39373533313F3D3B3937353A3 +:108BA0003313F3D3B39373533313F3D3B393735395 +:108BB0003313F3D3B39373533313F3D3B39300004B +:108BC0000000B42D6D4B9224E4B66D1B922449092C +:108BD00049920000FBDBBB9B7B5B3B1BFBDBBB9B36 +:108BE0007B5B3B1BFBDBBB9B7B5B3B1BFBDBBB9BD5 +:108BF0007B5B3B1BFBDBBB9B7B5B3B1BFADABA9AC9 +:108C00007A5A3A1AFADA00002449921BDBB6491262 +:108C100092942409090000006DDBB624F5D5B595C2 +:108C200075553515F4D4B49474543414F4D4B49400 +:108C300074543414F4D4B49474543414F4D4B494F4 +:108C400074543414F4D4B49474543414F4D400002C +:108C50000000002D6DDB922424B96D1B9B2449126A +:108C600049922400BA9A7A5A3A1AFADABA9A7A5A8D +:108C70003A1AFADABA9A7A5A3A1AFADABA9A7A5A54 +:108C80003A1AFADABA9A7A5A3A1AF9D9B99979594A +:108C90003919F9D9B999000024496E1BDB2649120C +:108CA000529224090000002D6DDB92243616F6D670 +:108CB000B69676563616F5D5B59575553515F5D55E +:108CC000B59575553515F5D5B59575553515F5D554 +:108CD000B59575553515F5D5B5957555351500000E +:108CE000090000006DDBB62424496E1BDB26491207 +:108CF0005292240979593919F9D9B99979593919F7 +:108D0000F9D9B99979593919F9D9B99979593919D3 +:108D1000F9D9B99979593919F8D8B89878583818CB +:108D2000F8D8B8987858000024B96D1B9B244912D4 +:108D3000499224000000B42D6D4B922477573717C9 +:108D4000F7D7B79777573717F6D6B69676563616BB +:108D5000F6D6B69676563616F6D6B69676563616B3 +:108D6000F6D6B69676563616F6D6B69676560000EF +:108D70004902000040DBB62D2449921BDBB64912A4 +:108D8000929424093818F8D8B89878583818F8D830 +:108D9000B89878583818F8D8B89878583818F8D853 +:108DA000B89878583818FFFFFFFFFFFFFFFFFFFF5D +:108DB000FFFFFFFFFFFF0000E4B66D1B922449098F +:108DC0004992000000F0FF3FFFFFFF3FFFFFFFFF62 +:108DD000FFFFFFFFFFFFFFFFFFFFF7D7B7977757B3 +:108DE0003717F7D7B79777573717F7D7B797775713 +:108DF0003717F7D7B79777573717F7D7B7970000D1 +:108E0000FFFFFF3FFFDFB62D2D499224DBB66D1229 +:108E100092242509636261605F5E5D5C5B5A59580C +:108E200057565554535251504F4E4D4C4B4A49484A +:108E300047464544434241403F3E3D3C3B3A39383A +:108E400037363534333200000000000000000000E7 +:108E500000000000000000000000000031302F2E54 +:108E60002D2C2B2A292827262524232221201F1EAA +:108E70001D1C1B1A191817161514131211100F0E9A +:108E80000D0C0B0A09080706050403020100000087 +:108E900000000000000000000000000000000000D2 +:108EA00000000000FFFFFFFFFFFFFFFFFFFFFFFFCE +:108EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:108EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:108ED000FFFFFFFFFFFF0000FFFFFF3FFFFFFF3F20 +:108EE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFFFFD2 +:108EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:108F0000FFFFFFFFFFFFFFFFFFFF0000000000006B +:108F10000000000000000000000000000000000051 +:108F2000FFFFFF3FFFFFFF3FFFFFFF3F000000008D +:108F30000000000007172737475706162636465603 +:108F4000051525354555041424344454031323339F +:108F50004353021222324252011121314151001079 +:108F600020304050FFFF0000000000000000000023 +:108F700000000000000000000000003F00020406A6 +:108F8000080A0C0E10121416181A1C1E2022242671 +:108F9000282A2C2E30323436383A3C3E4042444661 +:108FA000484A4C4E50525456585A5C5E606200001B +:108FB00000000000000000000000000000000000B1 +:108FC00000000000000000000000000000000000A1 +:108FD0000000000000000000000000000000000091 +:108FE0000000000000000000000000000000000081 +:108FF0000000000000000000000000000000000071 +:109000000000000000000000000000000000000060 +:109010000000000000000000000000000000000050 +:109020000000000000000000000000000000000040 +:109030000000000000000000000000000000000030 +:109040000000000000000000000000000000000020 +:109050000000000000000000000000000000000010 +:109060000000000000000000000000000000000000 +:1090700000000000000000000000000000000000F0 +:1090800000000000000000000000000000000000E0 +:1090900000000000000000000000000000000000D0 +:1090A00000000000000000000000000000000000C0 +:1090B00000000000000000000000000000000000B0 +:1090C00000000000000000000000000000000000A0 +:1090D0000000000000000000000000000000000090 +:1090E0000000000000000000000000000000000080 +:1090F0000000000000000000000000000000000070 +:10910000000000000000000000000000000000005F +:10911000000000000000000000000000000000004F +:10912000000000000000000000000000000000003F +:10913000000000000000000000000000000000002F +:10914000000000000000000000000000000000001F +:10915000000000000000000000000000000000000F +:1091600000000000000000000000000000000000FF +:1091700000000000000000000000000000000000EF +:1091800000000000000000000000000000000000DF +:1091900000000000000000000000000000000000CF +:1091A00000000000000000000000000000000000BF +:1091B00000000000000000000000000000000000AF +:1091C000000000000000000000000000000000009F +:1091D000000000000000000000000000000000008F +:1091E000000000000000000000000000000000007F +:1091F000000000000000000000000000000000006F +:109200001501010000000000000000003202100003 +:109210001B00000000000000000000000000000033 +:109220008C1C0000AF1C0000D21C0000F51C0000CC +:10923000200300004110080344611C0800000000E6 +:10924000000000000000000000000000000000001E +:109250000A00000066666666560000000000000016 +:1092600000000000000000000000000000000000FE +:109270000000000003080000181DD61D061E1F1E5A +:10928000531F581E301F421F431F7E1707B8C307C6 +:10929000008000002083000000803280648096807F +:1092A0002DB4040F110C0F0F10000F1325BD830AEE +:1092B00018C80F00130E130E0E410E4120030000BC +:1092C000CBB2300DCE0345120000000000000000BC +:1092D0000000000000000000000000000A00000084 +:1092E0006666666656000000000000000000000090 +:1092F00011111111111111111111000000000000C4 +:1093000003080000181DD61D061E1F1E531F581EE1 +:10931000301F421F431FAE0B07B80F330080000001 +:109320002083000000803280648096802DB4040F7A +:10933000110C0F0F90000F13A5BA830A18C80F0065 +:10934000130E130E0E410E4145097E1707B8C307D1 +:109350000080008020F3000C00803280648096FE44 +:109360002DB4FFFF11FDFFFFD0FF0F13A5BA830A35 +:1093700018C80F00130F130F0F410F411F030000F8 +:1093800009000000000000000000000000000000D4 +:10939000189DD69D069E1F9E539F589E309F429FAC +:1093A000439F0000000000C000000000000000001B +:1093B00002000000000000000000000000000000AB +:1093C00000E60000EC0454E7E4077EE75509A20735 +:1093D0000A09250945097E1707B8C3070080000060 +:1093E0002083000000803280648096802DB4048F3A +:1093F00011FDFFFFD0FF0F93A5BA830A18E80FE015 +:10940000130F13FF0F410F411F030000D4B80402D4 +:109410000351188748F00C0C85011C08189DD69D37 +:10942000069E1F9E539F589E309F429F439F5555B7 +:10943000555555D55555000000000018086A666658 +:1094400066666666366600270000000002E6008059 +:10945000EC0C54EFE4877EE75509A2070AE925E9F9 +:109460000000000000000100002802000000FC00D5 +:10947000000000000D000D0059064006000000002D +:1094800001559701020000000000000000010202E7 +:10949000002800008002FC00FFFFFF010D000D000E +:1094A00017001F000000000004B0B300000000100F +:1094B0000000000000020202002800008002FC0000 +:1094C000FFFFFF010D000D0016001E000000000050 +:1094D00004C4B300000000100000000000030202FA +:1094E000002800008002FC00FFFFFF010D000D00BE +:1094F00015001D000000000004D8B300000000109B +:109500000000000000040202002800008002FC00AD +:10951000FFFFFF010D000D0014001C000000000003 +:1095200004ECB3000000001000000000000502027F +:10953000002800008002FC00FFFFFF010D000D006D +:1095400013001B00000000000400B4000000001025 +:109550000000000000060202002800008002FC005B +:10956000FFFFFF010D000D0012001A0000000000B7 +:109570000414B40000000010000000000007020204 +:10958000002800008002FC00FFFFFF010D000D001D +:1095900011001900000000000428B40000000010B1 +:1095A0000000000000080202002804008002FC0005 +:1095B000FFFFFF010D000D0010001800000000006B +:1095C00020B0B30000000010000000000000000008 +:1095D000002806000000FC00000000000D000D0047 +:1095E000D20FA00F00000000015097010000000002 +:1095F0000000000000000000002802000000FC0045 +:10960000000000000D000D00C116A81600000000AB +:10961000018C97010600000000000000000B020210 +:10962000002800008000FC00000000000D000D007C +:1096300017001F000000000004B0B300000000107D +:1096400000000000000C0202002800008000FC0066 +:10965000000000000D000D0016001E0000000000BC +:1096600004C4B3000000001000000000000D02025E +:10967000002800008000FC00000000000D000D002C +:1096800015001D000000000004D8B3000000001009 +:1096900000000000000E0202002800008000FC0014 +:1096A000000000000D000D0014001C000000000070 +:1096B00004ECB3000000001000000000000F0202E4 +:1096C000002800008000FC00000000000D000D00DC +:1096D00013001B00000000000400B4000000001094 +:1096E0000000000000100202002800008000FC00C2 +:1096F000000000000D000D0012001A000000000024 +:109700000414B40000000010000000000011020268 +:10971000002800008000FC00000000000D000D008B +:1097200011001900000000000428B400000000101F +:109730000000000000120202002804008000FC006B +:10974000000000000D000D001000180000000000D7 +:1097500020B0B300000000104F00000001F404002E +:1097600068931B00600000000C0000000100040072 +:109770001428000060000000300000002D0084006C +:10978000142800001C000000730000002DF4840069 +:1097900068931B001C000000700000002DF4840082 +:1097A00068931B001C000000730000002DF484006F +:1097B00068931B001C000000630000002DF484006F +:1097C00068931B001C0000004F00000001F404001F +:1097D00068931B00E00001000C0000000100040081 +:1097E00014280000E0000100300000002D0084007B +:1097F000142800001C000000700000002DF48400FC +:1098000068931B001C000000000000000000000026 +:109810000000000000000000000000000000000048 +:109820000000000000000000000000000000000038 +:109830000000000000000000000000000000000028 +:109840000000000000000000000000000000000018 +:109850000000000000000000000000000000000008 +:1098600000000000000000000000000000000000F8 +:10987000000000000000000000000000922492247C +:109880009200920000000000224924492401A40013 +:1098900000000000144924492401140100000000C4 +:1098A000A448244924012201000000002445242961 +:1098B000240124010000000024292445240124015E +:1098C000000000002449A4482201240100000000F7 +:1098D00024491449140124010000000024492249AC +:1098E000A400240100000000FF7FFF7FFF01FF01B3 +:1098F00000000000B66DB66DB601B60100000000B4 +:10990000B26DB66DB601B60000000000966DB66D82 +:10991000B601960100000000B66CB66DB601B2014A +:1099200000000000B665B62DB601B60100000000CB +:10993000B62DB665B601B60100000000B66DB66C76 +:10994000B201B60100000000B66D966D9601B60139 +:1099500000000000B66DB26DB600B6010000000058 +:1099600001280000000000000000000000000000CE +:10997000000000020206AA006C768A94000106002C +:1099800000000000DB0600000106000091016E20CF +:10999000418C3903010000C61D018C6100000000EC +:1099A0000000000010100D100390BBBB8E5A22184F +:1099B00064116411893989390AE00FE06412641274 +:1099C000012800000000000000000000000000006E +:1099D000000000020206AA006C768A9400010600CC +:1099E00000000000DB0600000106000091016E206F +:1099F000418C3903010000C61D018C61000000008C +:109A00000000000010000C100380ABAA80442278F4 +:109A1000641164118939893905E005E06412641222 +:109A20000104000000000000000000000000000031 +:109A3000000000020200AA006C768A940001060071 +:109A400000000000DB060000040C000038066E2059 +:109A5000418C390301000084C4058C6100000000C2 +:109A60000000000010C40C500390BBBB804422785F +:109A7000641164118A39893905E00FE064126412B7 +:109A8000D004020001020304CCF57AFDED20BF8F63 +:109A9000CF0304021E0600036C768A9400010600C0 +:109AA00000000000DB06000001460000121B002041 +:109AB000006B39034100028400006B616478792BEC +:109AC000CF8A00801C5411980080BBBB00572278BD +:109AD000641164118A39893905E00FE06412641257 +:109AE0000100000001010101CCF57AFDED20BF8FDE +:109AF000CF030402020600006C768A94000106007F +:109B000000000000DB060000000C0000401A0020EE +:109B10004100380341000284000000606478792B22 +:109B2000CF8A00801C5410180380BBBB804622786B +:109B3000641164118A39893905E00FE064126412F6 +:109B4000D004020002020202CCF57AFDED20BF8FA4 +:109B5000CF030402020600006C768A94000106001E +:109B600000000000DB06000001460000121B002080 +:109B7000006B39034100028400006B616478792B2B +:109B8000CF8A00801C5411980380BBBB804622788A +:109B9000641164118A39893905E00FE06412641296 +:109BA0000100000003030303CCF57AFDED20BF8F15 +:109BB000CF030402020600006C768A9400010600BE +:109BC00000000000DB060000000C0000401A00202E +:109BD0004100380341000284000000606478792B62 +:109BE000CF8A00801C5410180380BBBB80462278AB +:109BF000641164118A39893905E00FE06412641236 +:109C0000D004020004040404CCF57AFDED20BF8FDB +:109C1000CF030402020600006C768A94000106005D +:109C200000000000DB06000001460000121B0020BF +:109C3000006B39034100028400006B616478792B6A +:109C4000CF8A00801C5411980380BBBB80462278C9 +:109C5000641164118A39893905E00FE064126412D5 +:109C60000100000000000000CCF57AFDED20BF8F60 +:109C7000CF030402020600006C768A9400010600FD +:109C800000000000DB060000000C0000FF3B00208D +:109C90004100380341000284000000606478792BA1 +:109CA000CF8A00801CC410180300000000C6227870 +:109CB000641164118039803905000F00551055106A +:109CC000000000000000000000101000000092CD15 +:109CD0000000C180100F0002000087370000BBF1B8 +:109CE000100F00040000904100008B43100E00078D +:109CF0000000BBF100009167100C000900001DFB83 +:109D00000000709E100E000500000000C806000054 +:109D1000BAF15942BAF15942450EA63D11223344D7 +:109D20005566778899AABBCCDDEEFF69000000007C +:109D30000000000000000000000000000000000023 +:109D40000000000000000000C022C0224A4948472D +:109D5000464544434241403F3E3D3C3B3A3938371B +:109D6000363534333231302F2E2D2C2B2A2928270B +:109D7000262524232221201F1E1D1C1B1A1900002A +:109D800000000000000000000000000000000000D3 +:109D90000000000031302F2E2D2C2B2A29282726B9 +:109DA0002524232221201F1E1D1C1B1A19181716DB +:109DB0001514131211100F0E0D0C0B0A09080706CB +:109DC0000504030201000000000000000000000084 +:109DD00000000000000000000000000000204060C3 +:109DE00080A0C0E00020406080A0C0E00020406073 +:109DF00080A0C0E00020406080A0C0E00020406063 +:109E000080A0C0E00020406080A0C0E000200000F2 +:109E1000000000094992481292B46D1B1B4992241C +:109E20006DDBB6362000E0C0A08060402000E0C0BE +:109E3000A08060402000E0C0A08060402000E0C022 +:109E4000A08060402000E0C0A08060402000E0C012 +:109E5000A08060402000000076DBB62D2449921BD4 +:109E6000DBB64912929424090900000062442608D6 +:109E7000EACCAE9072543618FADCBEA08264462852 +:109E80000AECCEB0927456381AFCDEC0A284664842 +:109E90002A0CEED0B29476583A1C9D7F61430000A4 +:109EA0006D4B9224E4B66D1B9324490A4992240019 +:109EB0000000B42D2F11927456381AFCDEC0A28413 +:109EC00066482A0CEED0B29476583A1CFEE0C2A442 +:109ED00086684A2C0EF0D2B496785A3C1E00E2C432 +:109EE000A6886A4C2E10000040DB962424496E1B85 +:109EF000DB26491292922409090000002507E9CBCC +:109F0000AD8F71533517F9DBBD9F8163452709EB91 +:109F1000CDAF9173553719FBDDBFA1836547290B81 +:109F2000EDCFB1937557391B9C7E6042240600002B +:109F30002D499224DBB66D13922429094992000021 +:109F400000D0B62D6C4E3012937557391BFDDFC112 +:109F5000A38567492B0DEFD1B39577593B1DFFE1E1 +:109F6000C3A587694B2D0FF1D3B597795B3D1F01D1 +:109F7000E3C5A7896B4D000000D0B6252449921B8C +:109F8000DBB6491292A4240949020000E8CAAC8E4B +:109F900070523416F8DABC9E8062442608EACCAED1 +:109FA0009072543618FADCBEA0826446280AECCEC1 +:109FB000B0927456381A9B7D5F412305E7C90000B3 +:109FC0002449921BDBB64D1292A4240949020000D9 +:109FD00040DBB624A98B6D4F31139476583A1CFEA2 +:109FE000E0C2A486684A2C0EF0D2B496785A3C1E81 +:109FF00000E2C4A6886A4C2E10F2D4B6987A5C3E71 +:10A000002002E4C6A88A00000000B42D254992244D +:10A01000DBB66D139224290949920000AB8D6F5174 +:10A020003315F7D9BB9D7F61432507E9CBAD8F7110 +:10A03000533517F9DBBD9F8163452709EBCDAF9100 +:10A04000735537199A7C5E402204E6C8AA8C00003A +:10A0500024496E1BDB364912929224090900000044 +:10A060006DDB9224E6C8AA8C6E5032149577593B6A +:10A070001DFFE1C3A587694B2D0FF1D3B597795B20 +:10A080003D1F01E3C5A7896B4D2F11F3D5B7997B10 +:10A090005D3F2103E5C700000000002D6D499224BB +:10A0A000E4B66D1B9324490A499224006E50321481 +:10A0B000F6D8BA9C7E60422406E8CAAC8E70523450 +:10A0C00016F8DABC9E8062442608EACCAE90725440 +:10A0D0003618997B5D3F2103E5C7A98B6D4F0000C2 +:10A0E00024B96D1BDB2449124A9224090000002D7B +:10A0F0006D4B92242305E7C9AB8D6F5133159678CC +:10A100005A3C1E00E2C4A6886A4C2E10F2D4B698BF +:10A110007A5C3E2002E4C6A88A6C4E3012F4D6B8AF +:10A120009A7C5E4022040000090000006DDB92244E +:10A1300024B96D1BDB2449124A9224093113F5D747 +:10A14000B99B7D5F412305E7C9AB8D6F513315F78F +:10A15000D9BB9D7F61432507E9CBAD8F715335177F +:10A16000FFFFFFFFFFFFFFFFFFFFFFFF30120000B9 +:10A17000E4B66D1B9324490A499224000000FC3F79 +:10A18000FFFFFF2460422406E8CAAC8E70523416EA +:10A1900097795B3D1F01E3C5A7896B4D2F11F3D55F +:10A1A000B7997B5D3F2103E5C7A98B6D4F3113F54F +:10A1B000D7B99B7D5F4100004902000040DBB62417 +:10A1C00024496E1BDB36491292922409F4D6B89AC0 +:10A1D0007C5E402204E6C8AA8C6E503214F6D8BACF +:10A1E0009C7EFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:10A1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00006D +:10A20000DBB66D1392242909C9FFFF3FFFFFFF3F13 +:10A21000FFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFF0E +:10A22000FFFF987A5C3E2002E4C6A88A6C4EFFFFCE +:10A23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:10A24000FFFFFFFFFFFF0000FFFFFF3FFFDFB62D17 +:10A250002449FE3FFFFFFF3FFFFFFF3F2000E0C01C +:10A26000A08060402000E0C0A08060402000E0C0EE +:10A27000A08060402000E0C0A08060402000E0C0DE +:10A28000A08060402000E0C0A0806040200000006E +:10A2900076DBB62D2449921BDBB649129294240931 +:10A2A000090000002000E0C0A08060402000E0C065 +:10A2B000A08060402000E0C0A08060402000E0C09E +:10A2C000A08060402000E0C0A08060402000E0C08E +:10A2D000A08060402000000076DBB62D2449921B50 +:10A2E000DBB6491292942409090000000000000026 +:10A2F000000000000000000000000000000000005E +:10A30000000000000000000000000000000000004D +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000C822050CE8220F0C56 +:10AAE0000000001002000000000000000000000054 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB2000C00BBC0DEE0B0000400BBC0FEC0B040087 +:10AB3000C02ABC0FEA0B0C00404ABC0FE80B140003 +:10AB4000C069BC0FE60B1C004089BC0FE40B24005D +:10AB5000C0A8BC0FE2082C004C48BE00000000005A +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00029292A2A2A2A29292A2A2A2A29292A2A0B +:10ABB0002A2A29292A2A2A2A2A2A2A2A29292A2AF9 +:10ABC0002A2A29292A2A2A2A29292A2A2A2A2929EB +:10ABD0000000000029292A2A2A2A29292A2A2A2A81 +:10ABE0000000000000000000000000000000000065 +:10ABF00000000000000000002A2A2A2A29292A2A07 +:10AC00002A2A29290000000000000000000000009E +:10AC10000000000029292A2A2A2A29292A2A2A2A40 +:10AC20002A2A2A2A29292A2A2A2A29290000000030 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE100006F0F15506F0F15506F0F15506F0F15542 +:10AE20001D1D1B181B1A1A1A1D1C1D1D1D1D1F235D +:10AE30001F201E1C1B1C1B1B1D1D1E1D1D1D1E1F40 +:10AE40001D1D1C1A1C1C1A1A1D1D1D1D1E1C212433 +:10AE5000201F1E1D1D1C1C1B1D1B1D1C1D1C1F1F20 +:10AE60001C1B1B1A1B1A1A1A1C1B1C1D1D1E21231E +:10AE7000201E1D1C1C1A1B1B1C1B1D1D1D1C1E1F08 +:10AE80001C1C1A1A1A1A1A191A1B1A1C1C1D1F220A +:10AE90001F1E1C1B1C1B1B1B1B1C1C1C1E1C1D1EED +:10AEA0001C1B1A191A1918191B1B1C1C1C1E2022EA +:10AEB0001F1D1C1B1B1A19181A1B1C1B1E1C1E1ED7 +:10AEC0001D1C191A1A1918191A1A1A1B1B1B1D20D6 +:10AED0001D1C1B1A1A19191819191A1A1C1B1C1EC9 +:10AEE0001B1B1A1A1A1818191C1B1C1C1C1D1C20B1 +:10AEF0001D1C1B1A1B191918191A1A1B1C1B1C1EA6 +:10AF00001B1B191919181918191A1B1B1A1C1B1F9E +:10AF10001D1D1A191B19191819191A1A1C1B1C1D89 +:10AF20001B1A1919191818191A1A1B1B1B1B1C207C +:10AF30001D1B1A1A1A191918191A1A1A1B1B1C1D6B +:10AF40001B1A1819191817171819191A1A1B1B2068 +:10AF50001D1B1B191919181818191A191B1A1B1D52 +:10AF60001B1A19191A17161717181819191A1A1F50 +:10AF70001D1B1A191818181819191B1A1A1A1B1C34 +:10AF80001A1A18191918181818171818181A1B202F +:10AF90001C1A1A1A18191817181819191A1A1A1B1C +:10AFA0001B1A18191918171819191919181A1B1F0B +:10AFB0001C1B1A1A18191919191A1A1B1A1A1B1CF0 +:10AFC0001A1918191918171819181919181A1A1EF0 +:10AFD0001B1B1A191819191819191A1A191A1A1CD7 +:10AFE0001A1817181817161719191919191B1A1CD6 +:10AFF0001C1B1A191819191819191A191A1A1B1BB6 +:10B000001A191718191817171919191A181A191CB3 +:10B010001D1B1A19171819181818191819191A1B9D +:10B020001A181718181716171818181A18191A1C9A +:10B030001C1A1919181818181919191A1A1A1A1C79 +:10B04000191817181717161617181819181A1B1B7E +:10B050001C1A1919181818171818191819191A1B61 +:10B060001918161817161616171718181819191A66 +:10B070001B19181818161717181819181A19191B48 +:10B080001918161817161616161717181718191A4A +:10B090001B191818171718161717191819191A1B2A +:10B0A0001918161717161516171718191818191A28 +:10B0B0001C19191918181817171718181A19191A06 +:10B0C000181816171716151517171719181A191A09 +:10B0D0001B19181818181817171819171A19191AE8 +:10B0E00018171617161514151616161717181718F9 +:10B0F0001A19181717161716171818171A19191AD0 +:10B1000018171616161515141616161716181818D9 +:10B110001A181817171717161717181719181819B4 +:10B1200018171616161514141616161716171818BB +:10B130001A18171717171616161718171918181997 +:10B1400017161516151414141516161616161717A5 +:10B15000191717161716161516161717191818197E +:10B160001716151515141414151516161616171886 +:10B170001917161616161615161617161817171865 +:10B18000171715151414141415151516151517176A +:10B190001817171616161715161616161817171845 +:10B1A000171615151413131315151616161617174B +:10B1B0001918171616161616151617151817171824 +:10B1C0001616151515141314151515171516171829 +:10B1D0001818161716171716151617161716171804 +:10B1E0001716151414141315151516161616171709 +:10B1F00018171616161615151515161517161616F0 +:10B2000016161515141413141415151615151616EF +:10B2100018171616151615161515161516161617CF +:10B2200016151414141412131414141514141616D9 +:10B2300017161516151515151415161517151616B6 +:10B2400016151414141313131414141514151617B7 +:10B250001716161515171514141515141615161698 +:10B26000161513141413121313141415141515169C +:10B27000171615151514151414151515161616167A +:10B28000161413141413131313141414141415167E +:10B290001615151514141514131414141515151565 +:10B2A0001514131413131313131313141414151662 +:10B2B0001615151514141514141415141614161641 +:10B2C0001514131313131213131213141314151547 +:10B2D0001615141414141514141414141614151526 +:10B2E0001514131313131212131313141314141528 +:10B2F0001616151515141514141414141515141503 +:10B30000141313141212121212121213131314150F +:10B3100015151514141315141313141315131414ED +:10B3200014131313121312121212121313131416EE +:10B3300015141414141414131314141415141414CD +:10B3400014131213121212121212121313131416D0 +:10B3500014141414141314131314141314131314B3 +:10B3600013131213121212121212121313131415B2 +:10B370001414131414131313131414131513131494 +:10B380001313121212121210121212121212131599 +:10B390001414131314131413131314131514131474 +:10B3A000131212121212111012121213121213157A +:10B3B000141413131313131312131413141313135A +:10B3C000131312121211121012121213121213145A +:10B3D000141313131312141313141313141313133A +:10B3E000131212121111111111121212121213143E +:10B3F0001414141313121413131313131413141417 +:10B400001212121211101111121212121212121320 +:10B4100012131313131313131313121313131414FC +:10B4200013131212121111121213121313121313F7 +:10B4300013131313141413131414131313141415D4 +:10B4400014141212131311121313131313131313CF +:10B4500014131313141414141314141414151414AF +:10B4600019191916181717161A1A1A191A1A1B1E4B +:10B470001B1B1A181817171718191A191B1C1C1D33 +:10B480001A191918191918171B1B1A1A1B1B1E2118 +:10B490001C1B1A191819181819181A1A1C1B1D1D0B +:10B4A0001A19191819181818191A1A1B1B1C1E20FA +:10B4B0001C1B1B191918181819191A1A1B1B1C1DEB +:10B4C0001A1A1918191818171819191A1A1A1C1FE4 +:10B4D0001D1C1A191A191818191A1A191B1B1C1DC8 +:10B4E0001A1A191819181717191919191A1B1C1EC5 +:10B4F0001C1C1A191A18181719191A1A1B1B1D1DAA +:10B500001A1918181917171718191919191A1B1EAB +:10B510001C1A19191A171818181819191A1A1B1C95 +:10B520001B1A181819171618181A191919191B1E89 +:10B530001B1B19191A1718181818191A1A1A1B1C74 +:10B540001A1A1818191817181718181818181A1C72 +:10B550001B1B19191A171818181819191A1A1B1B56 +:10B560001A191818181616171819191818191A1E52 +:10B570001C1A1919191718171818191919191B1B3A +:10B580001A19171818161517171717181718191E3C +:10B590001C1B1919181718171817181819181A1B1F +:10B5A0001A19171718161517161717171719181D20 +:10B5B0001B1A181817171817171719191918191B04 +:10B5C0001919171817161517161717171618181C04 +:10B5D0001A19181817171717171718181817191AEC +:10B5E0001A18171717161516171717171618181CE5 +:10B5F0001A19181817171717181718181918191AC9 +:10B600001918171717161517161616171618181BC8 +:10B610001A19171716171716171718181918191AAD +:10B6200019171617171514161617171817191819AA +:10B630001A1A171716161716161717181917181A91 +:10B64000181716171716151616171717161818188D +:10B650001A19171716161716161617161917191A74 +:10B66000181716171615151616171718161818186E +:10B670001A18171617161716161617161917181A56 +:10B680001717171716151516151616171618181852 +:10B690001A18171617161716161616151817181A39 +:10B6A0001716161716151416151616171618181835 +:10B6B0001A1816161715161516161716181718191C +:10B6C0001716161617151415151616171518181817 +:10B6D00019181616171516151615161718171819FE +:10B6E00017161616161514151616161715181717F9 +:10B6F0001A191716171617161616171618171818D8 +:10B7000016151616151514141616161716191817D9 +:10B7100019181616171516161615171618171719BD +:10B7200016151616151414141516151615171716C2 +:10B7300019181616161516151615171518171719A0 +:10B7400016151616151514141516151615171716A1 +:10B750001817161516151615161516161716171886 +:10B760001615161515141414151515161516171685 +:10B770001817161516151615151516161716171768 +:10B78000151415151514141414151415141616166D +:10B79000171616151615161515141616171617184A +:10B7A000151415151413131414151515141616164F +:10B7B0001717151516151514151416151715161730 +:10B7C0001514151514141314141514151415161630 +:10B7D0001717161516151515151415141715161710 +:10B7E0001514151514131213141514151415161514 +:10B7F00017171615161415141515151517151616F1 +:10B8000015141415141313131414141514151616F3 +:10B8100016171615161515141414151417151616D3 +:10B8200015141315141312141415141514151615D4 +:10B8300016161514151414131414141416151516BD +:10B8400014141313131312141314141414141615BC +:10B85000161615141514141414131413161515169E +:10B86000151413131312121413141414131415159E +:10B870001615151414141414131314141614151582 +:10B88000141413141312121314141414141515157C +:10B890001514151414141513131314131514151566 +:10B8A0001413121312121212131313141314151467 +:10B8B0001514141414131413141314131514141549 +:10B8C0001413121312121213131313131314141448 +:10B8D000151415141413141313131313141414142C +:10B8E0001413121412121213121313131313141429 +:10B8F000141414131313141313131313151415150D +:10B90000141312131212121312121213121314140C +:10B9100014141313131314131313131215131414F1 +:10B9200013131213121212121212121313141414EC +:10B9300014141313131213131313141315131414D1 +:10B9400014121213121212121212121212131314D0 +:10B9500014141313131214131213131314131414B3 +:10B9600014131213121212121213121313131314AC +:10B970001413131312131312121313131413141397 +:10B980001312111311121212121212121213131493 +:10B990001313131313121312121213131413141478 +:10B9A0001212111212121111121212121213131476 +:10B9B0001313131313121212121313131413131459 +:10B9C0001212111312111211121212121212131456 +:10B9D0001313131313121313121313131413131338 +:10B9E0001212121311111111121212121212131437 +:10B9F000131313131312131212121312141313131B +:10BA00001312121311111211121212121212131414 +:10BA100013131212121213121213131214121313FD +:10BA200012121112111111101212121212121313FA +:10BA300013131313121113121313131314121313DA +:10BA400012121112111111101212121212131314D8 +:10BA500013131313131313121313131313131313B7 +:10BA600013131111111011101112121212121313BB +:10BA7000131312121313131212131312131313139B +:10BA8000131211111211101112121212121213129A +:10BA9000131312121312121212131313131212137E +:10BAA00018191917191819181A1A1A1B1A1A1C1EFC +:10BAB0001B1C1B1A181918191A1A1B1A1A1B1B1CE3 +:10BAC000181819181A1A19191B1B1B1C1C1B1E21CC +:10BAD0001C1B1B1A191A1A1A1A191B1B1C1B1C1CBB +:10BAE00019191919191919191A1A1B1C1C1B1E1FAF +:10BAF0001C1B1B1A1A191A191A1A1B1A1C1B1B1B9E +:10BB00001A1A1919191919181919191A1C1B1C1E96 +:10BB10001C1B1A191A191A191A1A1B1A1D1B1B1B7E +:10BB20001919181A1A1918191A1A1B1B1C1C1C1E71 +:10BB30001C1B1A1A1B1A1A191A1A1A1B1D1B1C1C59 +:10BB4000191918191A191819191A1A1A1B1A1B1E59 +:10BB50001C1A1A191B1919191A191A1A1C1A1A1B44 +:10BB6000191918191A1918191A1B1B1B1A1B1B1E35 +:10BB70001B1A1A191A19191919191A1A1B1A1A1A29 +:10BB80001A19181819191919191A19191A191A1D1F +:10BB90001B1A1A191A1919191A191A1B1C191A1B06 +:10BBA00019181819191818181A1A1B1A1A191A1FFD +:10BBB0001B1A1A1B1B191A191A191A1A1B191A1AE5 +:10BBC00019181818191718181818191919191A1EE8 +:10BBD0001B1A1A1A19191919191919191B19191ACD +:10BBE00019191718181817171818181818191A1ECD +:10BBF0001B1A1919181819181A1919191A181919B4 +:10BC00001918171818171817181818181819191DAF +:10BC10001919191918191918191919191A18191996 +:10BC2000191A181818171717181818181719191C8F +:10BC30001A1A1919181919181A1919191A19191972 +:10BC40001919191917181718181818191719181C6D +:10BC50001919181917181818191819191A1918195B +:10BC60001818171817171717191818191719181A55 +:10BC70001A19181818181817181819181A1818193E +:10BC80001919171818171717191717181618181938 +:10BC90001919181817181918191818181A1818191E +:10BCA0001818171818171717181819191719191914 +:10BCB0001A19181718171817191819181A191919FD +:10BCC00017171718181817171818181918191919F5 +:10BCD0001A181818181818171818181719181819E2 +:10BCE00017181718181716171818181817191819D9 +:10BCF0001A181717181717171818191819181818C5 +:10BD000019191718181716171717181817191819B7 +:10BD10001A181818181718171817181819181819A2 +:10BD2000181717181716161718171819171918189B +:10BD30001B19181819181818181719171A1818187D +:10BD4000171717181716161617171818171918187F +:10BD50001A18181819171818181718171918171863 +:10BD60001818161816161516171717181718171863 +:10BD70001A18181718171717181818171A18181844 +:10BD80001817161816161616171717171718181843 +:10BD90001A18181818171717181718171917181727 +:10BDA0001716161717161616171717181718171825 +:10BDB000191817171817171718171817191817170A +:10BDC0001717161716161516171716171717171809 +:10BDD00019171717181718171717181719171717EC +:10BDE00018161517161615161716161817171717EB +:10BDF00019181717171718161717181718171617CF +:10BE000017161617161616161616161716161617CE +:10BE100019171817171717161717171619171617B0 +:10BE200016161517161514161717171716171717AE +:10BE30001917171717161717171717161917161791 +:10BE40001616161716151515161617171616171790 +:10BE50001917171717171717161617161816161675 +:10BE60001616151616151516161616171616171772 +:10BE70001818161617171716161617161816161658 +:10BE80001615151616151516161616171616161754 +:10BE90001818161617161617161617161816161639 +:10BEA0001615151615151517161616161616171635 +:10BEB000181716161616161616161716181616161C +:10BEC0001615151715151516161615171616161715 +:10BED00017171617161616161616161518161616FE +:10BEE00017151416151515151516151615161716FA +:10BEF00017171616161617161616161517161516E0 +:10BF000015151416151515141516161615161616DC +:10BF100016161616161617161515161517151515C5 +:10BF200015141416151515141515151515161616C0 +:10BF300016161616151617151516161517151616A4 +:10BF400015151416151515141515151515151616A0 +:10BF50001616151516151715151516151715151688 +:10BF60001514141614151514151514161515161682 +:10BF70001616151616151615151516161716151567 +:10BF80001414141615141514151515151514151665 +:10BF90001616161615141716151516151715161547 +:10BFA0001514141614151514151515151515151643 +:10BFB000161516151515161515151614161515142E +:10BFC0001413131514141514151414151515151729 +:10BFD000161515151614151515151615161515150E +:10BFE0001414131514141513151414151515151709 +:10BFF00016151515151516151515161517151514ED +:10C0000014141415141414131414141515151516EA +:10C0100016151515161516151515161517151515CA +:10C0200014141315141415131514141515151517C8 +:10C0300015151515151415141515151416151514B3 +:10C0400014141315141414131515141515151516A9 +:10C050001515141415141514151615141615151494 +:10C06000141413151314141314141415151515158D +:10C07000161516151514151515161615161615156B +:10C08000141413151313131314141415161615156D +:10C09000151515151615151616161616151515154A +:10C0A000151414141313131314141514151415154F +:10C0B000151515151515151515151515161515152F +:10C0C0001515131414131313141414141415141431 +:10C0D0001615141515151515141515151615151510 +:10C0E0001B1B1B191C1B1A1B1D1C1D1C1C1C1D1F94 +:10C0F0001C1E1D1B1B1C1B1B1C1D1D1B1C1D1D1D7D +:10C100001B1B1B1A1D1D1B1C1E1D1E1E1E1D202160 +:10C110001D1E1D1C1B1C1C1C1D1C1D1D1D1C1D1C57 +:10C120001A1B1B1B1B1B1C1B1C1D1D1D1D1D1E1F4D +:10C130001D1D1C1C1B1B1C1B1C1C1E1C1D1C1C1D3C +:10C140001B1B1A1B1C1C1B1B1B1C1B1D1D1D1D1F31 +:10C150001E1D1B1B1C1C1C1C1C1C1D1C1E1D1D1D18 +:10C160001A1B1A1B1C1B1A1B1C1D1C1C1D1D1E1F11 +:10C170001D1C1B1B1C1B1B1B1C1C1C1B1E1D1D1DFF +:10C180001B1A1A1B1C1B1B1B1C1C1C1C1C1C1C1FF5 +:10C190001D1C1B1B1C1A1B1B1C1C1D1C1E1C1C1CE1 +:10C1A0001B1B1B1D1C1B1B1C1C1D1D1C1C1C1C1FCE +:10C1B0001D1B1B1B1C1B1B1B1B1C1C1C1E1C1C1DC2 +:10C1C0001B1B1A1C1C1B1A1B1B1C1B1B1B1B1C1EBA +:10C1D0001D1C1B1A1C1A1B1B1B1C1C1B1D1C1C1BA7 +:10C1E0001A1A1A1B1B1B1A1B1C1D1D1C1A1B1C1F99 +:10C1F0001D1B1C1B1C1B1B1B1C1B1C1B1E1C1C1C83 +:10C200001B1B191B1B1A1A1B1B1B1B1C1B1B1B1F7D +:10C210001C1B1B1B1A1B1B1A1B1B1C1B1D1C1C1D68 +:10C220001A1A1A1B1C1A1A1B1A191A1A191B1B1F65 +:10C230001C1C1B1B191A1B1A1B1B1C1B1D1B1C1D4A +:10C240001A1A1A1B1B1A1A1C1A1A1A1A191A1B1F45 +:10C250001B1B1B1B191B1B1B1B1B1B1B1D1B1A1B2F +:10C260001A1A1A1B1C1B1B1C1A1A1A1A181A1B1E24 +:10C270001C1B1B1B191B1B1A1B1B1C1B1D1C1C1C0A +:10C280001A1A1A1B1B1A1A1B1A1A1A1A191B1A1D08 +:10C290001B1B1A1A191B1B1A1A1B1B1B1D1B1A1BF3 +:10C2A0001A19191B1A1A1A1B1A1B1A1A191B1B1BEB +:10C2B0001C1B1B1A191B1B1A1B1B1B1A1D1B1B1BD0 +:10C2C0001A1A191B1B1A191A1B1A191B191B1B1ACC +:10C2D0001B1B1A1A191A1B1A1B1B1C1A1D1C1B1CB0 +:10C2E0001A191A1A1A1A1A1B1B1B1A1B191B1A1BAA +:10C2F0001B1B1A1A191A1B1A1B1B1B1A1D1C1C1C90 +:10C30000191A1A1B1A1A1A1A1A1A191A191B1A1A8E +:10C310001B1A1A1A191A1A1A1A1A1B1A1D1B1B1C75 +:10C320001919191B1A1A191B1A1A1B1B1A1B1A1B6B +:10C330001C1A1A1919191A1A1A1B1B1A1E1B1A1B56 +:10C340001919191B1A1A191A1A1A1A1B191B1A1B4E +:10C350001C1A191919191A1A1A1A1C1A1D1C1B1C35 +:10C360001A19191A1A1919191A1A1B1A191B1A1932 +:10C370001C1B1A1A1A1A1A1A1A1A1B1A1C1B1B1B14 +:10C380001A1A181A191A19191A1A1A1B1A1B1A1A10 +:10C390001C1A1A1A1A191A191A1A1B1A1C1B1B1BF7 +:10C3A0001A1A191A191818181A19191A191B191AF8 +:10C3B0001B1A191919181A191A1B1A191C1B1A1BDE +:10C3C0001919191A19191818191A191A191A1A19DA +:10C3D0001B1A1A19191919181A1A1A1A1C1B1B1BBD +:10C3E000191A191A19191819191A191A191A1A19B8 +:10C3F0001B191A1919191A191A1A1B1A1C1B1B1B9B +:10C40000191A1919191818181A1A1A1A19191A1999 +:10C410001A1A191919191A191A191B1A1C1B1B1B7C +:10C4200019191919191818191A19191A1A1919197B +:10C430001A19191919191A191A191A191B1A1A1B62 +:10C440001A1918191818181919191A1A191819195E +:10C450001A1A1919191A1A1919191A191B1B1B1B3F +:10C4600019191819181818181A1A1A1A191919193D +:10C470001B1919191A19191919191A181C1A1B1B21 +:10C4800018181819181818181918181A1918191925 +:10C490001A1A1A19191A191918191A191B1A1A1A03 +:10C4A00019181719191817191919191A19181A1901 +:10C4B0001A1A19181919191919191A181A191A1AE8 +:10C4C00018171718181818191919191A19181918E6 +:10C4D0001A1A19191918191919191A181B1A191AC7 +:10C4E00018171819171717191819191918181919C9 +:10C4F0001918181918191918181819191A19191AB0 +:10C5000018191818181717181919191A18181918A6 +:10C510001919181818191918181919181919191991 +:10C5200018171717171717171918181A181819198D +:10C530001919181918181918191919181A1919196F +:10C54000181818181718171818181819171819186C +:10C550001918191818181918181818171918181957 +:10C560001818181817171717171818181718191850 +:10C570001818181818181918181819181919191935 +:10C58000171717181817181818181718181719192F +:10C590001818171818181918181818171919191918 +:10C5A0001717171817171717181717181717181816 +:10C5B00018181718181718181818191819191919F8 +:10C5C00017171718171717171817171818171819F4 +:10C5D00018181818181618181718181819181818DD +:10C5E00017181718171717181818171817171819D2 +:10C5F00018171818171819181818191819191818B9 +:10C6000017171617161717171817171818171819B6 +:10C61000181717171816181718181818191818189F +:10C62000161616171717171617161717171717199D +:10C63000171717171817171717181918191918187F +:10C640001717161717171716181717181717171978 +:10C650001717171818171817181818181A1918195B +:10C660001616161817161615171717171616181A5E +:10C67000181817171717181718181817191818183F +:10C68000161616171616171517171717171717193F +:10C69000181717171717181718181818191818181F +:10C6A000161616181616161517171819171717181D +:10C6B0001817181717161818191A191819181818FA +:10C6C0001716161715151615171717171717171802 +:10C6D00017171818181819181818181818181818DB +:10C6E00017171717161516161718171717181718DC +:10C6F00017171717181818171818181718181818C0 +:10C7000018171617181716161817181718171717B7 +:10C710001818171818181818181919191918181896 +:10C7200006F0F15506F0F15506F0F15506F0F15519 +:10C73000402C2B2B2A2F2F2C2C34333131313134F8 +:10C740003040322F2E2C2B2A2B2C2C3131302F31F4 +:10C750003231322F322C2C2C2B2B2B2C2C313331F1 +:10C7600030333131312E312B2C2C2B2B2A2B2B2FEC +:10C77000312F2F302F2F2F2F2F2C2B2A2A2A2A2BE5 +:10C780002A2E2F302F302F2F2F2C2F2A2A282A2ADB +:10C7900029282A2D3030302F2F30312D2C2C2B2AC8 +:10C7A0002B2B2B2B282F2C2E2F2D2F2E2C2E2C2BC2 +:10C7B0002A292A2B2A2B2A2F302F2F2E2E2C2D2DB3 +:10C7C0002B2B2B292A2B2A2C2B333130312F2F2F97 +:10C7D0002D2B2B2A2A2A29292A282B2D2F2E2D2DA5 +:10C7E0002E2D2C2C2D2B2C2C2D2B2B2C2C2D30307E +:10C7F0002F2E2F2D2B2B2A2B2B2B2A2B2C2D2A3077 +:10C800002F30302F2D2D2C2A2C2A2A292A2A2A2C67 +:10C810002D2F2F2D2E2E2C2D2B2C2C29282A282A5B +:10C820002B2B2C2E2D2B2D2D2C2D2C2A2C29292851 +:10C83000282B2D2C2B2E2E2E2D2D2C2B2C2B292640 +:10C840002928292A2928292B2B2B2C2A2B2A2C2D45 +:10C850002C2A29292828282927292B292B2B2B2B3F +:10C860002A2C2B28272728282A29292C2C2C2C2A2B +:10C870002C2B2C2E2A2A292828292929292B2A2918 +:10C88000282929292B2F2A2A2A2928282A2A29290E +:10C890002928282828282B2C292929282728292B0A +:10C8A0002B2C2A2929292A2A292B292929292929EE +:10C8B0002929292A2929292828292A2C2A292828E6 +:10C8C00029292A2B2A2C292829282A29282C2A2ACE +:10C8D000292928292929292A292928292929292AC8 +:10C8E0002A292728292929292B2A2B2B2A292A2AB0 +:10C8F0002B2C292A29282829282929292A2A282AA3 +:10C90000292A2A2B292A272829282928292827279C +:10C91000292929292A2C2529282726272828272894 +:10C92000272827272827282A28282729272827298A +:10C930002926282A29282728272B2728272626277B +:10C9400026262627272626242727272B262928267A +:10C95000262728272725292628262627282A272963 +:10C960002827272727272827262527262627272A57 +:10C970002727272627272827282628262726262749 +:10C980002829262726262524262627272626252544 +:10C990002627272A25272626262626262625252534 +:10C9A0002525252526274025262524252526272615 +:10C9B0002523242525252640402A2D2D2E2E2F2CBB +:10C9C0002C313230303231343240302F30312E2F52 +:10C9D0002E2E2D323131323232343332312E2F2E4F +:10C9E000302E2B2D2C3230312F333334342F332F44 +:10C9F0002F2C2C2C2B2C2B3231303132343435313E +:10CA0000302E2F2E2E2D2D2C2C313331323432322C +:10CA1000312F312D2C2D2E2D2C2C2D2F333030302D +:10CA2000323233302D2F2F2F2D2F2E2D2D34313309 +:10CA3000353333322F2E2E2D2F2E2E2E2E2C2F31FE +:10CA4000313032323230302E2D2D2E2E2D2F2C2DF6 +:10CA50002F323230323231302F2D2F2E2E2F2F2EDB +:10CA60002E2E2F32313231313030302F2E2F2D2ECD +:10CA70002F2F2D2F2E2F3233323131302E2F2E2DBE +:10CA80002E2E2C2D2F2F3031333231302F2F2D2CB5 +:10CA9000312D2E2C2D2F302F30333031323231309A +:10CAA000302E2F2D2E2F2E2E2E2F2E313330313093 +:10CAB0002F31312D302D2F2F303032333034343070 +:10CAC00030302F2E2E2E2B2B2E2D2E2F2D2D2D2D8B +:10CAD0002F2C302E302D2F31312E2E2D2F2D302F6B +:10CAE000303331323030313231302F2D2D2E2D2E4A +:10CAF0002F2F30343132312F302F2E322F2D2D2D3C +:10CB00002C2E2D2D2D302F2D2F2F2E2E30312D2E42 +:10CB10002E2E2D2E2F2F2F2F2F2E2F2E2F2E2D2F2F +:10CB20002E2D2D2B2C2C303030312F2F2F2F2E2E21 +:10CB30002F312D2E2E2D2E2E2F2E2E2D2E2E2F2D13 +:10CB40002F2D2E302E2D2E2F302F3031312F2D2EF8 +:10CB50002F2D2E2D2C2E2E2E2D2D2E2F2F2E3030F4 +:10CB60002F302D2E2D2E2F2F2E2D2D2E2D2E2E2EE5 +:10CB70002F2D2E2E2E2C2E2D2D302D2D2D2C2D2EDD +:10CB80002E2E2E2E2E2E2F2E2F2F2F2E2D2E2E2DC3 +:10CB90002F302D2F302F2E2C2E2D2E2E2E30282DB7 +:10CBA0002E2B2C2C2D2C2D2C2E2E2D2C2E2D2C2EB8 +:10CBB0002D2C2B2D2C2B2C2D2E2D2D2E2D2C2D2EAA +:10CBC0002D2F2B2E2C2B2B2C2C2D2E2D2C2C2C2AA0 +:10CBD0002E2C2E2D2E2E2E2E2E2F2E2F2E2C2D2C7B +:10CBE0002B2B2E2E2C2D2C2E2D2D2D2D2D2D2F2C77 +:10CBF0002A2B2C2B2B2E2E302B2D2C2C2C2B2C2B74 +:10CC00002E2C2C2C2C2C2D2C2D2E2B2D2D2D2C2C5C +:10CC10002E2C2D2B2B2D2B2C2C2E2C2E2A2D2C2C50 +:10CC20002D2E2D2C2E2D2C2D2D2D2D2C2D2E402D21 +:10CC30002D2D2E2C2C2F32302D2C2F2D2F2C2D4006 +:10CC4000402D3231323334313234343335343538A7 +:10CC500034403032333333313231303133323536A0 +:10CC60003635363533323432323131312F32343396 +:10CC700031363536363534323232313130322F3783 +:10CC80003535353638363735343332323433313260 +:10CC90003034343436353634353434313030323063 +:10CCA000312E313335333435343435343235343450 +:10CCB000353437333335333636363635343532332B +:10CCC0003332323332313435363336353534343429 +:10CCD000303132333233323333363636363635331B +:10CCE00034333134343434353633383534343637FC +:10CCF00037353333323334343534343334363837EC +:10CD000035353636343530323434343534363735DB +:10CD1000353536353534322F3534333334323334D8 +:10CD200035373634353935353734383434343436AC +:10CD30003839373737373537373835313333353496 +:10CD40003435373536373936353735353333302F97 +:10CD50003232333333333135333635343634353498 +:10CD60003432343132343537343535373637373578 +:10CD7000363534313232343335353436363834366C +:10CD80003535353532343436363736363334373355 +:10CD9000323635343436323235353534333735354D +:10CDA000353533383533333434343432343438363B +:10CDB0003636353536353634333334343434353429 +:10CDC000363436353734333634323434333434341D +:10CDD0003536363836363635343636353334333400 +:10CDE0003333353433343435363436363333333500 +:10CDF00035353335333934393635383435363634DC +:10CE000034333434363635353535363333353535D8 +:10CE100035353432343434333635343735373734C6 +:10CE200036393636343430333333333333333333C4 +:10CE300034333435363333353333333537333538AC +:10CE4000363335333335343434342F3535333636A1 +:10CE50003435353533313232333333353335343499 +:10CE60003436353433343532343334353334333681 +:10CE7000353436353537343432323434343534356C +:10CE80003335333333353434343435333433343366 +:10CE90003435333437343435353333343332343452 +:10CEA0003335363637343434343637353434363433 +:10CEB000363434343534403D373937393C463935EA +:10CEC0003638333339333340403A353638363736EF +:10CED00034393A373A3A3A3D3D403E3F3F3E3738A3 +:10CEE000373636383837383D3D3A3A3937383A36BA +:10CEF0003635333535383837373C3A3B3B393937B7 +:10CF0000383637363637353A3B38383B3B3A38389F +:10CF100039393938393B363936393D3B3C3B3C3A77 +:10CF20003C38393538383737383536363B38393884 +:10CF3000383A3938353A393A393B3837353E393F5E +:10CF40003A3C3D3B383A373739393A38383A373A4C +:10CF50003A393C3B3C3C3A3834373837393B38383F +:10CF6000373A3C3D3C3E3E3C3A353739393B39391E +:10CF700037383B393B393B3E3B3B393A3739393B14 +:10CF8000393A3A3B3D3A3F3D3D3B3C3B393A3539F6 +:10CF9000393A3A3A3938393A3C3C3B3C3C3A3736F4 +:10CFA0003A39393A38393A3A3F3A3C3B3C3C3B3CD7 +:10CFB00039383B3A393C3A3D3A3B3D3C3C3D3B3DC0 +:10CFC0003E3B3C363A393C3A393C3C3B3D3A3C3AB4 +:10CFD0003D3B3D3D3C3A34373B393B3B39393839B1 +:10CFE0003B3B3B3C3E3B3A383A393A3A3B383738A0 +:10CFF000383B3B38393B3E3B38393A383A393A3896 +:10D00000373A3C3C3B3D3D393D3C383A393B3B3A75 +:10D010003C3D373A3A3A3A3A3B3D3C3C3C3A393A65 +:10D020003B3C3B3A393C3C3B3A3B3D3B3E3A3B3A4E +:10D03000393A3A3A383C3B3E3D3C3B3C3C3C3D3C3B +:10D040003B3A393C3D3B3B3E3A3C3A3C3A393C3B2F +:10D050003B3A3B3A3C3A3B3C3A3A3B3D403C3D3E16 +:10D060003B3B3D3A3A3A393A3B3B3A3A393A393A1C +:10D07000393A3B3E3C3C3B3B3C3C3A393B3B3A3CFF +:10D080003D3E393C3C3B3D3C39393B3B3D3D3B3BE8 +:10D090003A3B3D3A3A3A3B3B3B3A3B373B3A3B3BE8 +:10D0A0003E3B3A3D3A3B393B3C3B3E3C3A3B353DCF +:10D0B0003C3839383A39363C3C3A3C3C3D3B3B3CC9 +:10D0C0003A3B3A3B3A393B393D393A3E3C3B3A3CB4 +:10D0D0003B39373D3B3B38393A383B3A38383C3AB4 +:10D0E0003E3A3A3A373E3D3C3C3C3C3F3B3B3C3B86 +:10D0F0003A3A3D3B3B3C3A3E3C3D3C3B3D3C3B3D74 +:10D1000039393B3B3B3B3C3D393B3C393E393C3C70 +:10D110003D3B3A3C3C3A3C3D3B3A3A3D3A3D3B385C +:10D120003E393D3C3B3D3C3C3C3D3B3A393D3F403C +:10D130003F3E3D3C3E3B3B3C3E3F3F3D3D3B404117 +:10D14000404444474041403F3E3D3D3D413F3D40DE +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000004806108000488610800048061F800044 +:10D3C00048861F800048061180004886118000486A +:10D3D000061E800048861E8000480612800048868F +:10D3E00012800048061D800048861D8000480613F4 +:10D3F0008000488613800048061C800048861C80F8 +:10D40000004806148000488614800048061B8000EF +:10D4100048861B8000480615800048861580004815 +:10D42000061A800048861A80004806168000488642 +:10D4300016800048061980004886198000480617A3 +:10D4400080004886178000480618800048861880AB +:10D4500020001904902000320887200032C8802064 +:10D4600000325882200032E8832000327885200084 +:10D470003208872000196890200019889320000244 +:10D48000F44B200002044C200019F89120001918D8 +:10D4900095200002F44B200002044C20001938981B +:10D4A000200032A8962000326890200032F89120A7 +:10D4B000003288932000321895200032A896000090 +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D54000010090010201060A640028324600000032 +:10D5500000000000000000003C0000004006000049 +:10D5600034080000A0A0010101011900010014000D +:10D5700001001600E4000A00001478000032780070 +:10D580000000002032323232323232323232323223 +:10D59000323232323232000000000000000000005F +:10D5A000000000000000000034083408F40100000E +:10D5B0000209200019450000F16C000084D9060022 +:10D5C00029B1010010270000C409000000014B0F21 +:10D5D00000000000000000003C3C0A0A02000000BD +:10D5E0000000000001010101010040003200E803D9 +:10D5F0000F0008000A0010001000020202000300E1 +:10D6000003000A0006006400E803000004000000B4 +:10D6100000000000000000000101010101004000C5 +:10D620003200E80314000F000A00E10000000808BF +:10D630000A0028001E001E0006006400E803000027 +:10D640000400000000000000000000004006300060 +:10D6500020000100220000003A00520070008F00FC +:10D66000AF00CF00EF000F012E014F016E018E01C0 +:10D67000AD01CE01EC010F022D024D026D028D02B3 +:10D68000AC02CC02EB020B032B034A036A038903AF +:10D69000AA03C903E703FF033704000000000000EA +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000F6090A +:10D72000300046000100480000003C004300660055 +:10D730008500A900C800E90009012A0149016B011F +:10D740008901AB01C901EB0109022B024A026C02FB +:10D750008A02AC02CA02EC020B032D034B036D03D9 +:10D760008B03AE03CB03EE030C042F044C046F04B5 +:10D770008B04AF04CC04EF040D0530054D05700596 +:10D780008D05B005CD05F1050D0630064E06720675 +:10D790008E06B106CE06F2060F0732075007730752 +:10D7A0009007B307D107F407110834085208750829 +:10D7B0009108B108C608E70800000000000000005A +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F00000000000080009000B000D000F001200DF +:10D80000150018001D00210027002D0034003C00E9 +:10D81000450050005C006900780089009C00B10060 +:10D82000C900E3000001210145016C019701C70116 +:10D83000FB0134027102B402FD024B03A003FA03A0 +:10D840005C04C3043205A7052406A8063207C407F2 +:10D850005C08FC08A2094E0A000BB80B750C360DCB +:10D86000FC0DC50E910F5F102E11FD11CC129A13F5 +:10D8700065142C15EF15AD1664171418BB1859193B +:10D88000ED19761AF21A621BC41B191C5E1C951C3A +:10D89000BC1CD41CDC1C080009000B000D000F0090 +:10D8A0001200150018001D00210027002D00340073 +:10D8B0003C00450050005C006900780089009C0035 +:10D8C000B100C900E3000001210145016C0197018D +:10D8D000C701FB0134027102B402FD024B03A00335 +:10D8E000FA035C04C3043205A7052406A806320720 +:10D8F000C4075C08FC08A2094E0A000BB80B750CA3 +:10D90000360DFC0DC50E910F5F102E11FD11CC12BE +:10D910009A1365142C15EF15AD1664171418BB185F +:10D920005919ED19761AF21A621BC41B191C5E1CD8 +:10D93000951CBC1CD41CDC1C080009000B000D004D +:10D940000F001200150018001D00210027002D00F7 +:10D9500034003C00450050005C00690078008900FC +:10D960009C00B100C900E3000001210145016C01E8 +:10D970009701C701FB0134027102B402FD024B039F +:10D98000A003FA035C04C3043205A7052406A80615 +:10D990003207C4075C08FC08A2094E0A000BB80B4A +:10D9A000750C360DFC0DC50E910F5F102E11FD117B +:10D9B000CC129A1365142C15EF15AD1664171418B4 +:10D9C000BB185919ED19761AF21A621BC41B191CDF +:10D9D0005E1C951CBC1CD41CDC1C080009000B0040 +:10D9E0000D000F001200150018001D002100270077 +:10D9F0002D0034003C00450050005C0069007800B8 +:10DA000089009C00B100C900E3000001210145012B +:10DA10006C019701C701FB0134027102B402FD02DF +:10DA20004B03A003FA035C04C3043205A7052406D4 +:10DA3000A8063207C4075C08FC08A2094E0A000BBE +:10DA4000B80B750C360DFC0DC50E910F5F102E1125 +:10DA5000FD11CC129A1365142C15EF15AD16641731 +:10DA60001418BB185919ED19761AF21A621BC41B47 +:10DA7000191C5E1C951CBC1CD41CDC1C0A000B0071 +:10DA80000E0010001300160019001D0022002800CF +:10DA90002E0035003D00460051005C006900780012 +:10DAA00089009B00B000C700E100FD001C013F01A0 +:10DAB00065018E01BC01EE0124025F029F02E402B7 +:10DAC0002F037F03D60332049504FE046D05E3059E +:10DAD0006006E3066D07FE0795083309D609800A3C +:10DAE0002F0BE30B9B0C580D180EDB0EA10F6810CB +:10DAF0002F11F711BE12841346140515C0157516A3 +:10DB00002417CC176B1801198E190F1A851AEF1AE2 +:10DB10004D1B9D1BDF1B121C381C4E1C551C0A0084 +:10DB20000B000E0010001300160019001D0022004B +:10DB300028002E0035003D00460051005C006900C1 +:10DB4000780089009B00B000C700E100FD001C01C7 +:10DB50003F0165018E01BC01EE0124025F029F02BC +:10DB6000E4022F037F03D60332049504FE046D05FF +:10DB7000E3056006E3066D07FE0795083309D6093D +:10DB8000800A2F0BE30B9B0C580D180EDB0EA10F18 +:10DB900068102F11F711BE12841346140515C01515 +:10DBA00075162417CC176B1801198E190F1A851AC0 +:10DBB000EF1A4D1B9D1BDF1B121C381C4E1C551CE5 +:10DBC0000A000B000E0010001300160019001D00C3 +:10DBD000220028002E0035003D00460051005C0068 +:10DBE0006900780089009B00B000C700E100FD00DB +:10DBF0001C013F0165018E01BC01EE0124025F02A0 +:10DC00009F02E4022F037F03D60332049504FE042F +:10DC10006D05E3056006E3066D07FE079508330909 +:10DC2000D609800A2F0BE30B9B0C580D180EDB0E48 +:10DC3000A10F68102F11F711BE1284134614051599 +:10DC4000C01575162417CC176B1801198E190F1AE9 +:10DC5000851AEF1A4D1B9D1BDF1B121C381C4E1C16 +:10DC6000551C0A000B000E001000130016001900CE +:10DC70001D00220028002E0035003D004600510006 +:10DC80005C006900780089009B00B000C700E100DB +:10DC9000FD001C013F0165018E01BC01EE01240263 +:10DCA0005F029F02E4022F037F03D6033204950430 +:10DCB000FE046D05E3056006E3066D07FE079508A3 +:10DCC0003309D609800A2F0BE30B9B0C580D180E55 +:10DCD000DB0EA10F68102F11F711BE12841346142A +:10DCE0000515C01575162417CC176B1801198E1958 +:10DCF0000F1A851AEF1A4D1B9D1BDF1B121C381CB7 +:10DD00004E1C551C29002F0035003B0043004C00E1 +:10DD100055005F006B00780086009500A600B900F2 +:10DD2000CD00E300FC00160133015201740199019A +:10DD3000C001EA01180249027D02B602F102310374 +:10DD40007503BC0308045804AD0406056305C50546 +:10DD50002B06960605077807EF076B08EB086E0998 +:10DD6000F4097F0A0C0B9B0B2E0CC20C580DEF0D07 +:10DD7000870E1F0FB80F4F10E6107B110E129E1268 +:10DD80002B13B4133814B8143315A71516167D16B3 +:10DD9000DD1635178517CD170B1841186D1890181B +:10DDA000A918B718BC1829002F0035003B00430004 +:10DDB0004C0055005F006B00780086009500A600BF +:10DDC000B900CD00E300FC001601330152017401DB +:10DDD0009901C001EA01180249027D02B602F1026E +:10DDE00031037503BC0308045804AD04060563053C +:10DDF000C5052B06960605077807EF076B08EB08A5 +:10DE00006E09F4097F0A0C0B9B0B2E0CC20C580DEB +:10DE1000EF0D870E1F0FB80F4F10E6107B110E127B +:10DE20009E122B13B4133814B8143315A7151616F5 +:10DE30007D16DD1635178517CD170B1841186D188F +:10DE40009018A918B718BC1829002F0035003B00FE +:10DE500043004C0055005F006B0078008600950081 +:10DE6000A600B900CD00E300FC0016013301520109 +:10DE700074019901C001EA01180249027D02B6024B +:10DE8000F10231037503BC0308045804AD04060510 +:10DE90006305C5052B06960605077807EF076B088F +:10DEA000EB086E09F4097F0A0C0B9B0B2E0CC20CBD +:10DEB000580DEF0D870E1F0FB80F4F10E6107B1196 +:10DEC0000E129E122B13B4133814B8143315A71561 +:10DED00016167D16DD1635178517CD170B18411848 +:10DEE0006D189018A918B718BC1829002F00350014 +:10DEF0003B0043004C0055005F006B00780086003B +:10DF00009500A600B900CD00E300FC001601330126 +:10DF1000520174019901C001EA01180249027D020F +:10DF2000B602F10231037503BC0308045804AD04C2 +:10DF300006056305C5052B06960605077807EF0756 +:10DF40006B08EB086E09F4097F0A0C0B9B0B2E0C77 +:10DF5000C20C580DEF0D870E1F0FB80F4F10E610B3 +:10DF60007B110E129E122B13B4133814B8143315F0 +:10DF7000A71516167D16DD1635178517CD170B1844 +:10DF800041186D189018A918B718BC1855005500FD +:10DF900045004200000000001C02370254027202D9 +:10DFA0009002B002D102F30216033A035F03850325 +:10DFB000AC03D503FF03290455048204B004DF0435 +:10DFC0000F0540057205A505D9050E0644067A061B +:10DFD000B206EA0622075C079607D0070B08470837 +:10DFE0008308BF08FB0837097409B009ED09290A3D +:10DFF000650AA10ADC0A170B510B8B0BC30BFB0B39 +:10E00000330C690C9E0CD20C040D360D650D940D6D +:10E01000C10DEC0D150E3D0E630E870EA80EC80E39 +:10E02000E60E010F1B0F320F460F590F690F760FC7 +:10E03000820F8A0F900F940F950FBA04C904D80469 +:10E04000E704F604050514052305320541055005CE +:10E050005F056E057D058B059A05A805B705C50505 +:10E06000D405E205F005FE050C0619062706340660 +:10E0700042064F065C066906760682068F069B06F8 +:10E08000A706B306BE06CA06D506E006EB06F606E8 +:10E0900000070B0715071E07280731073A07430734 +:10E0A0004C0754075C0764076C0773077A078107FE +:10E0B00087078D07930799079E07A307A807AC0753 +:10E0C000B107B407B807BB07BE07C107C307C50739 +:10E0D000C707C807C907CA07CB07CB07FA006C00F8 +:10E0E000FA006B006400D007000028000000000068 +:10E0F0000000000000000000000000000000000020 +:10E100000200190050001E001E000C001900000043 +:10E110000100000001000000948D0300508D0300F9 +:10E12000948D0300548D03000100000078563412D2 +:10E1300078563412014040000100000070AD02002A +:10E14000FFFFFFFFAA0000001033030007000000DC +:10E1500001000000FFFFFFFFFFFFFFFFFFFFFFFFCA +:10E1600001000000FF0000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F000008B7420324006000A0E0A0001030108102A +:10F0100032004006F6090000000C0100000000006C +:10F020000013575904060000000000000008010901 +:10F03000000132334006000028191900000E0000BC +:10F04000000E0000000E0000000E0000000E000088 +:10F05000000E0000000E0000000E0000000D030076 +:10F06000000E0000000E0000000E0000000D030066 +:10F07000000E0000000E0000000E00000000000066 +:10F08000000101000000000000000000000000007E +:10F09000000000000000000000000101010101006B +:10F0A0000001010000000101010100010000000059 +:10F0B0000100000102000000070000000107010339 +:10F0C000020314000A0A4000000078003C0000001F +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000C800C8009600C80032 +:10F0F00007078000800005050000000000000000F8 +:10F1000006010000000017003900910010001400F3 +:10F11000F9FFC4FFFF7FFF7FFF7FFF7FFA002C0115 +:10F120003200C8000A04B4B43232230500000000E3 +:10F1300000070D0000320D00000000203232323294 +:10F140003232323232323232323232323232000003 +:10F1500000000000000000000000000000000000AF +:10F160000A05000A00000000140F0012101200002F +:10F17000000000000000000000000000000000008F +:10F18000000000000F233246500000006A64504621 +:10F190003C3C3C3C08000000000000000F233246CD +:10F1A000500000006A6450463C3C3C3C0F141E2852 +:10F1B000000000000A0A0A0A0A0A0A0A0C192D416C +:10F1C0005000000046554B464646464600000000AB +:10F1D0000A0314005F00F1FF14000F000A00BC02D4 +:10F1E00000000000F8FF00007800320064002800F2 +:10F1F0000F000F001C023D011C02740400003F06BA +:10F200000000FF09F40100003F060000FF0932146E +:10F21000021E1E32020096003C003C007700C8052A +:10F22000770088090000000040063000200001003F +:10F23000220000003A00520070008F00AF00CF00A3 +:10F24000EF000F012E014F016E018E01AD01CE01C5 +:10F25000EC010F022D024D026D028D02AC02CC02B8 +:10F26000EB020B032B034A036A038903AA03C903B6 +:10F27000E703FF0337040000000000000000000067 +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F00000000000000000000000F6093000460099 +:10F300000100480000003C00430066008500A900A1 +:10F31000C800E90009012A0149016B018901AB011B +:10F32000C901EB0109022B024A026C028A02AC02FB +:10F33000CA02EC020B032D034B036D038B03AE03D8 +:10F34000CB03EE030C042F044C046F048B04AF04B6 +:10F35000CC04EF040D0530054D0570058D05B00595 +:10F36000CD05F1050D0630064E0672068E06B10675 +:10F37000CE06F2060F073207500773079007B30750 +:10F38000D107F40711083408520875089108B1082C +:10F39000C608E708000000000000000000000000B0 +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D0000201200019450000F16C000084D90600EC +:10F3E00029B1010010270000C4090000000101013B +:10F3F000010102020202014B0F00A0000000000008 +:10F400000100010101010102020202001945000090 +:10F4100002000000A46B00000000000014140A0A9F +:10F420001400000000000000141414140101010174 +:10F43000010040003200E8030F00080005009000C2 +:10F4400000001E502800B40050000400000000001E +:10F45000B4005000FA00A000000000014F010000BD +:10F460000000000068010D0D0A094B004B0064000C +:10F470000A003200C800640064000F02E8E8F800E7 +:10F48000F8000200190000006A00750081008E007B +:10F490009D00AC00BD00CF00E200F7000D01260189 +:10F4A00040015C0179019901BC01E00106023002D2 +:10F4B0005B028902BA02EE0224035D039A03D903B8 +:10F4C0001B046004A904F40443059505E9054106FD +:10F4D0009C06FA065B07BE0724088D08F808650934 +:10F4E000D409450AB80A2D0BA20B190C900C080D73 +:10F4F000800DF80D6F0EE60E5C0FD00F4210B310AA +:10F5000021118C11F4115912BA1217137013C4136C +:10F5100013145D14A114E01418154B1577159C15E0 +:10F52000BB15D415E515EF15F31536003D00440065 +:10F530004C00560060006B00770085009300A4002B +:10F54000B500C900DE00F5000E0129014601650184 +:10F550008701AC01D401FE012B025B028F02C602BF +:10F5600001033F038003C6030F045D04AE040305DB +:10F570005D05BA051B068106EA065707C9073D085F +:10F58000B6083109B009320AB70A3E0BC70B520C54 +:10F59000DF0C6D0DFC0D8B0E1A0FA80F3610C3106B +:10F5A0004D11D6115B12DE125C13D7134D14BD142E +:10F5B00028158D15EC1544169516DE161F175817CD +:10F5C0008917B117D117E717F517FA174E0056002C +:10F5D00060006B00760083009100A000B100C200C3 +:10F5E000D600EB0002011A013501520170019101B0 +:10F5F000B501DB0103022E025C028D02C102F8029A +:10F6000032036F03B003F4033B048604D4042605DD +:10F610007C05D50532069206F5065C07C607330859 +:10F62000A30816098C09040A7E0AFA0A790BF80B5A +:10F63000790CFB0C7E0D010E830E060F870F071051 +:10F64000861003117D11F5116912DA124713AF13F9 +:10F6500013147214CB141E156B15B215F2152C165B +:10F660005E168916AC16C716DB16E716EB166A008F +:10F67000750081008E009D00AC00BD00CF00E2004F +:10F68000F7000D01260140015C0179019901BC01DF +:10F69000E001060230025B028902BA02EE02240394 +:10F6A0005D039A03D9031B046004A904F404430511 +:10F6B0009505E90541069C06FA065B07BE07240886 +:10F6C0008D08F8086509D409450AB80A2D0BA20B64 +:10F6D000190C900C080D800DF80D6F0EE60E5C0FE6 +:10F6E000D00F4210B31021118C11F4115912BA121B +:10F6F00017137013C41313145D14A114E014181518 +:10F700004B1577159C15BB15D415E515EF15F3159D +:10F7100055005500450042000000000000000000B8 +:10F7200000000000000000000000000000000000D9 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000000000099 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F86000000000000000000000000000A000D20026 +:10F8700004013C0005000000000000000000000042 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF000000000000000000000000000004E565409 +:00000001FF diff --git a/firmware/novatek_nt36672_f10.fw.ihex b/firmware/novatek_nt36672_f10.fw.ihex new file mode 100755 index 000000000000..3f2efae02537 --- /dev/null +++ b/firmware/novatek_nt36672_f10.fw.ihex @@ -0,0 +1,7426 @@ +:100000000001000000000000E3DE0000C034010039 +:10001000007702005F010000801F6B0148C54E544D +:1000200000000000C003561305000000000000009F +:1000300000B80200FF07000000A00100A382B08802 +:10004000004E0200FF13000000480100FE13A10F44 +:1000500000620200FF130000005C01002280F1FB3F +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F000704C0200FF000000000000006206702843 +:10010000480001EA400000094000000940000009E1 +:100110003AFFBFFC3A0FA83C4400000148000190A0 +:100120003AFFBFFC3A0FA83C440000024800018897 +:100130003AFFBFFC3A0FA83C44000003480001808E +:100140003AFFBFFC3A0FA83C440000044800017885 +:100150003AFFBFFC3A0FA83C44000005480001707C +:100160003AFFBFFC3A0FA83C440000064800016873 +:100170003AFFBFFC3A0FA83C44000007480001606A +:10018000480000004000000940000009400000094C +:100190003AFFBCBC3A0F943C440000004800017197 +:1001A0003AFFBCBC3A0F943C440000014800017483 +:1001B0003AFFBCBC3A0F943C440000024800016C7A +:1001C0003AFFBCBC3A0F943C44000003480001597C +:1001D0003AFFBCBC3A0F943C440000044800015C68 +:1001E0003AFFBCBC3A0F943C44000005480001496A +:1001F0003AFFBCBC3A0F943C440000064800014161 +:100200003AFFBCBC3A0F943C440000074800013957 +:100210003AFFBCBC3A0F943C44000008480001314E +:100220003AFFBCBC3A0F943C440000094800012945 +:100230003AFFBCBC3A0F943C4400000A480001213C +:100240003AFFBCBC3A0F943C4400000B4800011933 +:100250003AFFBCBC3A0F943C4400000C480001112A +:100260003AFFBCBC3A0F943C4400000D4800010921 +:100270003AFFBCBC3A0F943C4400000E4800010118 +:100280003AFFBCBC3A0F943C4400000F4800010404 +:100290003AFFBCBC3A0F943C44000010480000FCFC +:1002A0003AFFBCBC3A0F943C44000011480000E9FE +:1002B0003AFFBCBC3A0F943C44000012480000E1F5 +:1002C0003AFFBCBC3A0F943C44000013480000D9EC +:1002D0003AFFBCBC3A0F943C44000014480000DCD8 +:1002E0003AFFBCBC3A0F943C44000015480000D4CF +:1002F0003AFFBCBC3A0F943C44000016480000C1D1 +:100300003AFFBCBC3A0F943C44000017480000B9C7 +:100310003AFFBCBC3A0F943C44000018480000B1BE +:100320003AFFBCBC3A0F943C44000019480000A9B5 +:100330003AFFBCBC3A0F943C4400001A480000A1AC +:100340003AFFBCBC3A0F943C4400001B48000099A3 +:100350003AFFBCBC3A0F943C4400001C480000919A +:100360003AFFBCBC3A0F943C4400001D4800008991 +:100370003AFFBCBC3A0F943C4400001E4800008188 +:100380003AFFBCBC3A0F943C4400001F480000797F +:10039000FEBE0000FEBE000006C00000DCC600007D +:1003A000DCC60000DCC60000DCC60000DCC60000C5 +:1003B000DCC60000DCC600000000000044C20000F3 +:1003C0004CC2000058C20000CAC2000004C30000B2 +:1003D0004AC300009CC30000C0C30000C8C30000A3 +:1003E000D0C30000D8C30000E0C30000E8C3000091 +:1003F000F0C30000F2C30000FAC30000CEC4000046 +:10040000DAC4000028C5000030C50000AAC50000FD +:10041000B2C50000BAC50000DEC5000044C6000039 +:1004200060C6000068C600009AC60000A2C60000B0 +:10043000A4C60000CCC60000D4C600006412A4020A +:10044000642204023A1F883C803F442002983821ED +:100450000202643200029ED964320003DD2264028B +:100460000043640000083A1F88046412A403642255 +:1004700004033A0FA8043AFFBFC4640000044420F8 +:1004800002BC38210202DD223A0F94043AFFBC84F8 +:10049000640000046412A402642204023A1F883C2F +:1004A000442002BC38210202643200029ED9643228 +:1004B0000003DD2264020043640000083A1F880440 +:1004C0006412A403642204033A0F94043AFFBC8428 +:1004D000640000044FF2001D3A0FA83C3AFFBFFC35 +:1004E00045D28DA0801F64126402965F9E49C105AB +:1004F0003CFD5D3C480000043CFD5D3DE809DD2F0E +:10050000C8073AFFBFC43A0FA8046400000464029D +:100510002402441F3FFFFE0E5800400064022403E3 +:100520006400000845D28DA045F2B80044F0BEC07A +:100530004EF20003DD2F3CFD5D3EDD2F640FFFEA30 +:10054000FC41F28180E13C2DFB973C1DFB9680C372 +:10055000490033CB3C1DFB948520A60AA64B4900DD +:1005600033E2F001490033EC3C1DFB9500008010A4 +:10057000E320E81180093810A400490033EF3C0D56 +:10058000FB95401024008009001080084900340EBB +:100590008D21D5EB8400490033D7490033B3840162 +:1005A000490033D2490033AE8403490033CD4900BA +:1005B00033A9490033C1AE308400A670E201E83BA4 +:1005C000A079950138508101D034A0FD94429899CA +:1005D0000091000294AA886200F18002E32FE803F0 +:1005E00010918002A0FD40918400886200948003F5 +:1005F00000A18003E349E80310918003A0FD389136 +:100600008400886200F18000E32FE80310918000ED +:10061000A0FD88238843A649A6D1E261E802AE5135 +:10062000A0BA956988A238111001A4E88823AC68A3 +:100630008C01D5C4FCC1FC40224080008520AD1057 +:1006400022408001AD112E4002D8CC053C4DFBE08C +:1006500004920001444000FC42019073B4804E4279 +:1006600000D70060002054530001CD035A48011206 +:1006700044027D10848138400C08A40844427CE088 +:10068000A44938020E09941A8804AC4148000108B4 +:100690005A400404480000BC44127D103C5FFBCF6C +:1006A00038108C003C5FFBCEC94944427CCC44826C +:1006B0007C3038520C0044427CC038A20C005A50A6 +:1006C000010680E1808187CCD521951A890480A11B +:1006D000808184E14C55400384E222F400008CA127 +:1006E0004213BC7322F4000197684243BC735084E8 +:1006F00000305A5803F084A44010943640421496B7 +:100700003C1FFBCF3C4FFBCED51980A342527873E0 +:1007100038F41611956A88A88C812252800197209E +:10072000882FE34488E5E8F28D414010A8364073F5 +:10073000A8F63C1FFBCF3C7FFBCE001000DC5A101C +:1007400003633C1DFBCF3CADFBCE80A14E140003E8 +:10075000FF4A808A4EA40004524500008885E324A5 +:100760004EF2009E5443000444527CE0959A44901B +:100770000064C40F4440008238728E01FE64401051 +:10078000A436882738128E0942751024986ED50F2A +:100790004470007342409C2438128E0140422496DB +:1007A000888138428E09986E42751C24A5094073D1 +:1007B000A4F688E4ADC938128E0144427C00AC50E6 +:1007C000986E38720E11A44988C4AC5100100020F4 +:1007D00022F0000758108002101000202251000063 +:1007E00022100006224300018AE18AA122110001A1 +:1007F0008A8F8A2FFF24FE4C42439C7342129473CB +:10080000E081E84D842110100050D5498E81E682A8 +:10081000E84644627D1044527CCC38430C004402CC +:100820007CC05A48010A848038428C0838400C0841 +:1008300038430C08D51638400C00E682E8038C815A +:10084000D502848038400C0838428C00CC0A3840ED +:100850000C005A48020744427CCC84A138520C0850 +:1008600038400C0080A3840C4252007344427CE068 +:1008700022608000227080018005945A38520E0157 +:1008800044927C3088249B7538548209A54994028F +:1008900088099B7DAD4138620E09ADC944027C00D8 +:1008A000A45038100E0994DA8860A411AC19FCC069 +:1008B000FC40A10DA04C94D2949188413C6DFBE288 +:1008C0008864A65100918002A772A71B8041422430 +:1008D00094739EE18A6984FE949196D8FFEC8840D7 +:1008E000852038F124114EF4000452F780005EF7A1 +:1008F0008033E9078C6196D8E6648927E9F3D51D32 +:10090000804442128873A733944995A98E81880147 +:1009100084A0E282E910381014114E140003FE4A3C +:100920005EF08033E9088C6196D8E66488A6E80515 +:100930008C41D5F08401D5028400FCC0FC42A10D9D +:1009400094D2886480C000918000A7D90081800281 +:10095000A6DB8381F3829CF98A6996D8F283F381BE +:100960004E830005C703E722E906F001E603E90725 +:10097000480000A649FFFF9E4E0300A28440800865 +:100980003C3DFBE280A28082802204AF8002E340F3 +:10099000E9334E92001700F18002814942A03C7376 +:1009A00038F3291141E504084EF7000488AF976B2E +:1009B00041E3780022FF7FFF4EF70004884F9693B3 +:1009C00001E1800250FF7FFFE0EFE81481E742F091 +:1009D000787341E7840838F33D114EF70004882FFF +:1009E000964B41E3780022FF00014EF70004888F08 +:1009F00097238C01D5CB8405FE84E045E80AFE24CC +:100A0000E001E8074E920006A61A8E01E0E0E959DF +:100A1000F0015A080114F0028C018A089600E606DB +:100A2000E90DE045E9034E93000A8405FF04E081E7 +:100A3000E948A61A8E014C700045F003B9049401F0 +:100A400088018420A60100A1800380E181218441E6 +:100A5000E24AE824A75A8100428114734044040802 +:100A6000388321114E840004528400008928C00A72 +:100A70004083100022847FFF4E84000452840000D3 +:100A800088E88EA14C0280098886224200014E44EB +:100A90000003FF2288248C41D5DC5CF487D1E90F68 +:100AA0005CF38064E902C80B5CF08064E90AA75A31 +:100AB00084208EA1FE2D40008006D5048401D5023D +:100AC0008400FCC2FC4FF185F286441268788440B1 +:100AD000F48CF594F382F181848180A2F305E243E2 +:100AE000F389E83322600000F7021260800A2230A6 +:100AF0000001A1FB1260800CA1851230800B123026 +:100B0000800D3873990194F1127080171460800E73 +:100B1000A58212608020F602A1B48866A7991060B1 +:100B20008033A6D810308032C606C3055A6011043F +:100B30005A3823051040802CD5031050802C8C414E +:100B4000501080488C18D5CB2E07EF84448268481B +:100B5000F087F0848400802044A26818449267E8FB +:100B6000447267B84460004844526878443264581C +:100B700042201824991588433814020A3815020AAD +:100B80003814820A3813820A8C011012002B1011BB +:100B9000002B5A080CEF3C0C01E2F207F0932E00F8 +:100BA00002D844100048F0972E07EB643CADFBE3FD +:100BB000F0983C0DFB5F45E26878F0992E07EB1941 +:100BC000F09AF0059402F09B4402645842010473C9 +:100BD000F09C8400F088F508F11B4C508196F108D8 +:100BE0004402684884413820040A4402621888019B +:100BF000F08344526458F01C4C500180F107F0051A +:100C0000E201221F000CE80A2202800E9A08F08DF1 +:100C1000221F000D2202800FD5092202800C9A08A3 +:100C2000F08D221F000D2202800D9A08F08B220FFA +:100C3000000C44100050F0902202800CF095220F1E +:100C4000000DF0912202800DF096B405F08A220288 +:100C50008018F092FE0C4410006440000416F09DD1 +:100C600000028035C0069F01E6119720E806D502F4 +:100C700080809C419648D502FA2100228034F18E72 +:100C8000C2079E515CF100239648E806D5028022F7 +:100C90009DD196F8D502FA73FAC2F38FFF8C8520A6 +:100CA000F30FE061E92B98F480E494D9048F800E6F +:100CB000E107E921048F8002B50838840C005A80CE +:100CC000FF1804FF800204F7800138F7A100048FA9 +:100CD000000E4CF4400E048F801304FF801D890326 +:100CE0000284000040840011E10FE90285218CE1BB +:100CF0008C62D5DD8C218CD2D5D4F302041F000E7A +:100D0000A0DD944A9999A6F2A673A731A7B0E2068E +:100D1000E920E280E91EE243E91CE222E91AFA2214 +:100D200042010473F11394018801F112A40085E2D9 +:100D300096034010BC36E020E9035A98010B0002EC +:100D40008044E602E806040280098E01E603D5022B +:100D500085E0049280095A980408000280285A0805 +:100D600001084800057E5A9807044800057AF00BF0 +:100D7000F10DFE04F21542008473F1109B8AF1110B +:100D8000F2169BCA0422800F42139C24421318734C +:100D9000CA735AF801044800055704250001E222ED +:100DA0004EF3055202350001F40AFEE4E223E83076 +:100DB00004350002E223E809A0ECA12BFEFC42333B +:100DC00010734E360541D52404350003E223E82094 +:100DD000A0ECA12BFEFC42331073F60A44400064E1 +:100DE000FF1C40421897FF24FF340065002744F0A1 +:100DF000271040F23DF7FF8C44400064406310D759 +:100E0000E2CFE8064E370005F30A4E33051D0032E7 +:100E1000802A00450000E283E80604350004E2234E +:100E20004EF30512F3175A380110F3185A38010D12 +:100E3000F3195CF18065E908F31AC3068465FE9C2A +:100E4000E2224EF30501002500264E22050A442623 +:100E5000D983E2414EF305055A9804044800050180 +:100E60000012802C4E1304FD001F002C4E1304F9B9 +:100E700046190000D5375A200204480004F25A9857 +:100E80000404480004EE04F500012242800EE22F23 +:100E9000048280032222800FA0EC4EF304D50015BB +:100EA000002885EA42940424FE5C4094BD3640F05C +:100EB000BDF6F11188438A228041F11088888A2486 +:100EC000FE94422084734217BC244214A473E04170 +:100ED0004EF204C7FEFC423320734E3704C246185C +:100EE00000008801F10350528048B601F003500021 +:100EF0000030F08348FFFE81F00851EF00488C0479 +:100F0000F08848FFFE6A8400441268188441F307A1 +:100F1000E203E8053820820A8C01D5FAF005E60BD9 +:100F2000E810E66BE80E8023F0054422684844325E +:100F300068184442621844526200490004DED50D2C +:100F4000F005F107442268484432681844426218A8 +:100F50004452620049000488F0888400F0838100D4 +:100F60004608FFFF50000FFF44226458443268785F +:100F7000F08D44A290D4F008E3004EF2017C40448E +:100F8000040844026200880444100048A60180A2BC +:100F9000425004730412800F5A1802164412620061 +:100FA00084AC3810A10042101473445262183812F5 +:100FB00086024E1500094412681884813840820A5E +:100FC0004800015644126200445000483810900016 +:100FD0008083424094732262000C50920018F68A7B +:100FE00080C24260147322548001F687F58BF507A6 +:100FF0002273000CF60A81E49BF72262800DF50B48 +:101000009BAE43E3182443E39C731DE78002F50A7B +:101010001477800188E5F50BA9A488C512748002B5 +:101020001264800380E184CC4270187344626218B9 +:10103000F50D38631E0251E20010E2A6504200385E +:10104000E80CF50784C28CB0A9A1A52A124F0002B2 +:10105000A52B124F0003D50384A0A961445000487A +:10106000808380E2424094734270147380A7509250 +:1010700000108CF02264800222F38002227380032D +:101080008ACFA9A122648003049280098AC7A9A2F9 +:101090000062802050720020106200205A98036E77 +:1010A000384518005A48020D444290C8384218008A +:1010B0005A48010784EA38751808104280284442CB +:1010C00090D4384218005A48010F4440004880A28A +:1010D00042501073004280288C98104280288482ED +:1010E00038451808384518005A48030E444000484F +:1010F00080A242501073808584A1105200288484FD +:10110000384518084440004880A24250107380C3FC +:1011100042609073004280288E81104300282E4741 +:10112000EB6DC41B049F80020473000E04948005C1 +:10113000957A88A900928001A7688B254E97000EAA +:10114000F502A16C38529D00E6A4E9078E813E4766 +:10115000EB6D8480104300284440004880A3425037 +:10116000907380850052802850420020CD0384A1D6 +:10117000D50284A3A961D51484A2A9792E57EB6D59 +:10118000C50FF6020442000EA1B595228886A7A1DC +:10119000A7208AC44E6700058EA13E57EB6D4450D0 +:1011A000004880824240147380C34260947350535D +:1011B00000280042002A3C9DFBE3AF2AB4C6047419 +:1011C0008005E2E6E805E68AE80A8C81D507047422 +:1011D0008006E2C7E804C4038E81AF2A4440004879 +:1011E000445264584250107300528044FF0C5CF229 +:1011F00080C88883E8028CA1105200444450004803 +:1012000042409424FE2C999C4091000022730017C8 +:1012100022548018E0A7445268A8E8068885127313 +:101220000018A421D50A8885445264880274801766 +:10123000880512730018A401AC2244000048808382 +:101240004240807300520020444267B88401380253 +:10125000160A444267E83802060AF0098E01F0894E +:10126000F0048E01F084F0038C01F0838D0148FFBF +:10127000FE84447264584482681880C784A044A2E3 +:1012800067E82E07EF84E2A0E803F004C80E3C0DE7 +:10129000FBE33C10172D446268781210001585009E +:1012A00044A267B84800010E3C3DFBE2F103000197 +:1012B0008009E220E8ED0C0400015A000104480016 +:1012C00000E7F00CC80D040300095A08030AF00CEB +:1012D00014047FFFF0048E01F084480000D9040359 +:1012E00000095A00030B5A0007099E41E622E80B49 +:1012F0000413000F5A1802048420D5193C1DFBE387 +:10130000A649D51500230020441000FCF4064241F4 +:101310000473002200EC5A2801081023002884409E +:10132000102200ECD506001300288E21101300288F +:10133000001300285A1801080023002B582100042C +:101340001023002B00218019852044326848E322B5 +:10135000E80938452602CC043841A602C4068D218E +:10136000D5F7852048000092C1038404D5615A084E +:101370000354001300339E09E610E83A2E0002FBE6 +:10138000C00800030020442290D438010000C0307F +:1013900000230020440000FCF30642310073800368 +:1013A0002231801922400018844394DAFEA4E062BE +:1013B000E81FF214A692CA1C2E27EB39CA19002086 +:1013C00000DBC216000000F9C80E442000484402A9 +:1013D00064584204887300000020442290D43801ED +:1013E0000000C0068407140300098403D51B840889 +:1013F00014030009C1035A18111E000300204412EF +:1014000090D438008000C0168404140300098402BC +:1014100010030028D50F5A08070B00030029C00548 +:101420008E0110030029D5068408D5028406140312 +:101430000009000300445CF000C8E8048C011003BC +:10144000004444200048440268784204887380269F +:10145000F587490063F900230020441267B884012E +:1014600038008A0A3805260A840014047FFFF00435 +:10147000F5078E01F084F0038C01F083D508383530 +:1014800026024E32FF738D214C917FFB8CA150635D +:10149000004848FFFEF8F0094E0200C7004100096D +:1014A000F003E2044EF200C140040808F084440254 +:1014B0006848380022025A00010C8D015063004830 +:1014C000F0053C2DFBE2E300E9E7480000AE4402F2 +:1014D00067E838302202CBF2F1020423000E3C0D03 +:1014E000FBE3A04B3810890102200015E241E8E639 +:1014F0008123381526024E1300920223000CB626D3 +:10150000A871A872A873A874F187F1031223000EC2 +:101510000223000D88011223000F10930020000009 +:10152000001C1003002849002854F1075A0802162D +:101530002E0002D8C0092E07EB56C0060003002873 +:101540008C02100300282E000227C0090003002887 +:101550008C0110030028D50310130028000300207D +:10156000441290D4844038208008F406441000FCD3 +:1015700042400473840B100200F9F1020423000EB0 +:10158000F026F48749FFF9DCF4072E17EB6D100203 +:1015900000DBC902C807840510030028840F10026D +:1015A00000F984001002008284011402002200135A +:1015B0000028C10284031403000984001003002AD8 +:1015C0000003002B84A1FE2F1003002B0203001741 +:1015D00084801443000F104300441203001850137A +:1015E0000032500300348442F588F4874900632CAC +:1015F000F104F508440267E8F4073850040A44028D +:1016000068483855260A3840040AF0098E01F089E6 +:10161000F0038C01F08348FFFF528D21E3244EF349 +:10162000FF6A48FFFF4C8400F1068060004100091A +:10163000E204E808B6611030804E8C01501080FC46 +:10164000D5F684003E07EF848520446267E83C0DB0 +:10165000FBE200000019E3204EF20093380326025B +:101660005A00010448000086F001048000095A80F5 +:1016700006125A8008102EA7EF8444200048440226 +:10168000645842050873F1018D41490062DD3EA7AF +:10169000EF84F00104AF800600100020440000FC3D +:1016A00042A080738400100500EC5A88070684006D +:1016B000B60A8401D5075A8808058400B60AD502FF +:1016C000B70A1005004E0005004E5A08010A02052F +:1016D0000006120500080205000712050009F001C6 +:1016E000501500240000002B10050020F0012200FE +:1016F000000A12050002F0012200000B120500038F +:10170000F0010480000E14850009B400A80DF0015A +:10171000A001A80EF001A002A80FF0010400000F24 +:1017200014050011B40A5A08030D000500DBC80BAC +:10173000F026F102804849FFF903100500DBD503CC +:101740005A000412F00240140408A00338002101DA +:1017500012050018F002A084500500E98822844296 +:1017600049006272000500F9C0048E01100500F9FD +:10177000F0018D2150000048F08148FFFF6A2E07DC +:10178000EF84F2053E07EB6EF1063C0C01E24900E6 +:101790004BD784003E07EB3984002E97EF848040BE +:1017A000444000FC84A344A290D484C1E249E848A8 +:1017B000048380095A88032500338020F1064211F2 +:1017C000907300808050E702E807001380288C2186 +:1017D00010138028D5315A880430B5015A80012D64 +:1017E00038350C00CB29008080F9E70AE825103055 +:1017F00080F91033802814638009B6C1D51D5A883A +:10180000021C00138020F3064230907300118050B8 +:101810005A18010B1083802814538009B6A31013A3 +:10182000802B10118020B4675CF1A711E9055A18CC +:1018300004048C0196008C4150738048D5B83E0753 +:10184000EB39FCCF5A90030448FFFB4EF10C5A18B9 +:10185000010448FFFB494611000048FFFB44841F78 +:1018600048FFFB42FC43F08181008400F484F18254 +:10187000F58580E18380812084814E82003DC73BD5 +:101880005A48013A84A08085855EF101D1223861F1 +:1018900016025A68011DF10495AA88C1F68384C016 +:1018A000F1024C60801539E19A025BE8010F4410A7 +:1018B000003042F30424F1033810BC02E22AE805A8 +:1018C00083868125809E81418CC1D5EB8CA1D5DE9C +:1018D000C4D5F105954188A18C0184201092800027 +:1018E00011C2800196003811260A8F013811F20AC0 +:1018F0008EE1D5C4FCC3C06EC16FFC4051FFFD2812 +:10190000E220E82F80E144A00030851F812442932B +:10191000A87384C038849A0A8CC14C607FFD8CE126 +:101920004C707FF680C083818001802681248105F0 +:10193000F28181434900266CB02649002670800957 +:1019400049002677B0024900267E840C490026858E +:1019500049002688844080A245E000308082D5146A +:10196000E201E8E184E044A00030851F8124429335 +:10197000A87380C038849A0A8CC14C60FFFD8CE14A +:101980004C70FFF6D5D0840C81E94212802442F2DB +:10199000F87384E098F9B00238300C005A3801111D +:1019A00038379E025A37FF0D94D188688C41AFD8E2 +:1019B000AF59F301969038419E0A3845160A8CE1DA +:1019C0004C737FEA8CA14C5E7FE0800251FF82D88D +:1019D000FCC08040D50280418002DD9EFC0080C0BA +:1019E00049003375C00784013E07EABA8400AE346B +:1019F000AE35FC802E07EFA8DD9E44327D40AE1848 +:101A0000AE59AE9ADD9E3C0FFA6EDD9E3C0DFA6E2D +:101A1000DD9E3C0DFB5E465FF00F50528F00FF468F +:101A200046001000D80684003E07ED7B8401DD9E51 +:101A30008400DD9E2E17EFCE2E57EFCF3C0DFC28F5 +:101A40004C12C0102E27EFCC5A28010CA6059D4938 +:101A5000400280B697683E57EFCE3E57EFCFDD9EEF +:101A6000A6058CA1400280B697683E57EFCFD904F7 +:101A700084013E07EFCCDD9E2E57EFCE2E17EFCF21 +:101A8000D9042E07EFCCC0103C0DFC288CA1A60574 +:101A9000400280B697683E57EFCE4C12C0058400D6 +:101AA0003E07EFCC8401DD9E2E57EFCE2E07EFCF01 +:101AB000D8082E07EFCC84208E0140008006DD9EE2 +:101AC0008401DD9E2E57EFCE2E07EFCFD8072E17BD +:101AD000EFCC840040000406DD9E8401DD9EFC0006 +:101AE00084A08C81E2A4E8073860080438608C0C7C +:101AF0008CA1D5F9FC8080603C0DFA6E9E41E622F7 +:101B0000E8253C2DFC2784200041000AE224E80956 +:101B1000A159385287025A58010384028C21D5F703 +:101B2000FC00842000410009445000FCE224E80D40 +:101B3000B44342209473B4429F91E6C2E9055A200F +:101B400004048C21D5F48401FC80DD9EFC438121BA +:101B5000B4E1843F101F80172E102AF88140C1087D +:101B60002E17EFA8C90549FFFFC83C0FFA6E3C2DA0 +:101B7000FA6E5A200104480001073C0DFC283C1D68 +:101B8000FC27F081F28284C087C2F0020040800905 +:101B90009E819690E244847F4EF200F1440000FC66 +:101BA000B48AFE148880F083B4A49EE9E662E90951 +:101BB0005A5004080032004E5A300104480000D444 +:101BC00044327D30383188005CF180C8E806440238 +:101BD0007D308C613830080800320085CB09003236 +:101BE00000505A3801065A580404480000C2003216 +:101BF000004E5A380119440290D438200800CA0710 +:101C000002220008ACA402220009ACA52222000492 +:101C10004E2400048440ACA4222200054E2400047B +:101C20008440ACA5F00122220004A6C0C305023006 +:101C300080098E619A9AF00122320005A741C505FC +:101C40000250800A8EA19AEBF001A743C52E0250E4 +:101C5000800900F000028EA1E9110280800250F498 +:101C60007FFF4082F91642813C7340241457025092 +:101C7000800A028080038EA1D5100280800350F478 +:101C80007FFF4082F91642813C7340241457025072 +:101C9000800A028080028EA150F47FFF4082F916F4 +:101CA0004281BC7340341477A54AE245E9029EA9FB +:101CB000A54BE265E9029EE9840680A742530073C2 +:101CC000F00240F1900940800C08F00158840002B5 +:101CD00010828000A60240811009C80C94948410E0 +:101CE00096DFFE86FE9F1082800110F28002AEAB6E +:101CF000D50B94DC8410969FFEC6FED710F28001AF +:101D000010828002AEEB0222000EC2039690D50232 +:101D100084418067840642330073AE9C0222000F28 +:101D2000C2039690D5028441841FAE9D1003803C6F +:101D30001003803D0020800CE642E912B44AF00313 +:101D4000884000210049CA02844198FEF003102116 +:101D50008046B44A88402021004A1021806E8CC100 +:101D600097B0D50644027D30846038300808F2020E +:101D70008C419610F08248FFFF0A1033803E1033EA +:101D8000803FD53F5A28022784181003803C84C026 +:101D900084001003803D3C3DFC2780060011800A32 +:101DA000E201E81304150001381083025A18010BF0 +:101DB0000023803D4010800CFE578CC11013803DE5 +:101DC00097B08C019600D5EB0003803D3E07EFA352 +:101DD000D5182E67EFA0C6152E17EFA1A638E63E40 +:101DE000E804944B9617D50396178430FE0FAE384F +:101DF0002E07EFA2AFB9AE3A84013E07EFA884C028 +:101E00002E07EFA85A00FF0DC00BCE0A841F3E0715 +:101E1000EFA83C0DFBE98C013C0FFBE9D5033E67C5 +:101E2000EFA83C3DFA6E5A3801163C0DFC270040E5 +:101E30000009E2C4E80F8426B4498406FE748A8649 +:101E4000FF0496488822500F801784408E8149FFF6 +:101E5000FE48B429840080A15020804008328001CF +:101E600088039600DAFCFE02100080408401C6025E +:101E700084003E07EFD2FCC3FC20844180624440D2 +:101E8000004080E080C149FFFE2C3C0DFC27000093 +:101E9000000CE602E9105053804650130046507380 +:101EA0008050080280011800800120028027100065 +:101EB0008027DFF8FCA0FC408120A60080C18420A0 +:101EC0003E17EFD1C0292E07EFCD5A08010C2E275F +:101ED000EFD03E17EFCC3E27EFCE3E27EFCF3E07A9 +:101EE000EFD149FFFDA93C0DFC282E77EFCF3C1D1B +:101EF000FBF2A704844104048001421390738062C2 +:101F00008E8149FFFDEE2E07EFD25A0801063E07EB +:101F1000EFCD3E77EFD02E17EFD1B4065A1801302F +:101F2000A605C818490030D7C80F3C0DFC28B426B8 +:101F30002E37EFD0A6843C0DFBF242018873B4210A +:101F400049FFFF9CD50A490030C6C0F049003088DF +:101F5000D5FB490030C0C803490030C5B426840011 +:101F60003E07EFD13E07EFCD8401AE0DB426AE0C97 +:101F70002E17EFA0C13FB426AE0FD53CA644C9052D +:101F800049FFFDA2C037D50DA6055A080108490032 +:101F900030A2C830490030A7D52D49FFFD87C8F8C9 +:101FA0004900309980E0C82649FFFD683C0DFC28B7 +:101FB000B4262E97EFCEA6843C0DFBF2B42142044A +:101FC000887349FFFF5B2E17EFCD5A18010F2E576C +:101FD000EFD04C54C00BB4063E77EFCDAE452E0784 +:101FE000EFA0C003B406AE474900307DB40684219B +:101FF000AE44FCC0FC20804080E144027D5CA051E6 +:1020000044627D74B6202E17EFA83C6FFBEE1010D3 +:102010000008A052A84144127D5849FFFD9944028E +:102020007D502E17EFA8A981AE40B4273C1FFBEBD3 +:1020300044127D4C49FFFF4144027D408420AE4064 +:10204000AE41AE4249FFFD40FCA0FC41F58140821B +:10205000801141C2C00A445000FC420194730050F8 +:1020600000202260800054A280012210800185217E +:102070004EA200154452888084E038728C08854C4A +:10208000445287F04251A873ADA8AC694452888C81 +:10209000107000E738928C08D56605E000005BE818 +:1020A00003204472888C38538C0081E542F1F87328 +:1020B00040F7880845E287F040F7F8008CA1976860 +:1020C0001267800012178001E6A338538C08E94B91 +:1020D0004452888038A38C0838928C08D5445BE839 +:1020E000016D4492888C84E338548C0081E542F180 +:1020F0009C7340F78808447287F040F79C008CA1DD +:1021000097681267800012178001E6A338548C0884 +:1021100044528880E90539E28C0838A48C0838528A +:102120008C00CD0538548C00C51ED50284A3842CA8 +:10213000427184738460802380C3549180FFE325BF +:10214000E80E40918808892738A38E010294800107 +:1021500088CA882997B3964B8C61D5F0406314D612 +:1021600040109436003F80285A380128B4005A089D +:1021700001253C5DFEC1A42DE280E81F4033200113 +:102180004E340003FEDA4000F0014E040003FE026C +:102190008803A4EEE003E811A4EF9F19400184092D +:1021A000421270734262207388C0880140630CD66B +:1021B00040100C3697B3964BAD90AC51FCC1FC016E +:1021C00096CB9683903090108A018A43FE04420198 +:1021D0000873FC81FC44228080018122222080003F +:1021E000441000FC4201847380E0B400843DFE464C +:1021F00080C3F5833C2BFA803C8BFA81F0814452FA +:1022000082704432815C5A100104480000E63C0DA3 +:10221000FD404442824038029A0A38021A0A444277 +:10222000823484003802180844428204445009C4AD +:1022300038521A0A444281F884AF3852180844428E +:1022400081EC5EF10032100380DC38021808445241 +:1022500081E0E805381298088022D50F5EF1040667 +:10226000E8063802980844100032D507840252115B +:10227000043738029808964B5EF40032444290D4FA +:10228000E8093802980058000004380298088008CD +:10229000D51F5EF408F24EF3046A380298005EF42B +:1022A00008F35800000838029808520409239603DE +:1022B000E90F38521800CD0C84A138521808445246 +:1022C00090B438829909445290EC3822990944A27A +:1022D00090C884A038551808385218005A5802255A +:1022E000445290EC385299118AA24E540003FF6A6E +:1022F0005EF28051E90484A138551808445290B424 +:10230000385299115EF28492E8048CB4E0A8D508A2 +:1023100044A004924C55000950F2FFC4E10FE804B8 +:1023200084A338521808E001444281D4E8058E1E87 +:1023300038021808D5048E3E3812180838021810D2 +:10234000E40FE806440281D4842F381018080213E1 +:10235000800F440281745EF1003338101B0944126F +:102360008150840038009808441290E0380199099F +:10237000380098084412814438009808E9133C1D3D +:10238000FEC00200800950F07FCDE04FE80B5EF404 +:102390000033E9080200800A50F07FCDE10F84018C +:1023A000E902840044128138100380DA8400380086 +:1023B00098084412824038209A024412810838203A +:1023C0009A0A441280FC38009808441280F03800C1 +:1023D0009808480002BC38029A023C1DFD40F38672 +:1023E000F485F284F58249FFFEECF3068140F502A4 +:1023F00038019901F204F405C8090203800F5CF06A +:1024000012C1E904840138019909E683E9072E071E +:10241000EB52C807E688E909D504846F8405D5071F +:102420004430003CFA00D503846F8408001380DC3C +:10243000C142E682E940FE04E340F082E82C441207 +:102440008144380098005CF0003DE92B440280C0D4 +:102450003C1DFD4038001A02F587F486F285F384AE +:1024600049FFFEAFF102F304E201F205F406F507BD +:10247000E81244028204FEDC38301A0A8402100397 +:1024800080DC4402824038101A024402810838106D +:102490001A0AD51144028144842038101808D50B3B +:1024A000C8073C3DFD4044F280C038379A0A8C0191 +:1024B00038009808000380DA5A08021684001003D6 +:1024C00080DA440282044410190038101A0A840386 +:1024D000100380DC4402824038101A024402810852 +:1024E00038101A0A4402820438101A02440281F891 +:1024F00038001800C02D440281E038001810C028B0 +:10250000F303A6D8CB25960054300001C30538F25A +:102510009A11E04FE91954300002C30538329A117C +:10252000E062E91254200004C20794B2884522F107 +:102530000001E10FE909961EC00B943288052200C4 +:102540000001E008E805440281D4381018100003A7 +:102550008020960EC80C4422817494338802A4C251 +:10256000ACC3A4C1ACC238211B01AC81440281744C +:102570000223800F4432815038201B093801980013 +:10258000E603E8048C01380198085CF52710440242 +:1025900090E0E80638301800C3068E61D502846FDB +:1025A000383018084402815C380019015A08013596 +:1025B000000380F8C00D443001F4FEC450F189C41A +:1025C000E34FE8068C01100380F84410FE01F0018F +:1025D0005A0002065A0804218409D5028406846A36 +:1025E000FE9C443281504083080838319800886846 +:1025F0004482817438340D01FE1CE040E80D440231 +:1026000090E038001800E606E905842F4010803677 +:10261000D5034410FE01442280F0380118005A000E +:10262000FF058C0138011808F584F482F181490016 +:102630001FD0F101F402F5045A000203944A440247 +:1026400081F883C038201800C20DF003A680CA06A6 +:102650004422815C38211901C2052E27EB52CA029F +:10266000944CE22AE85E001380DC84413E27EB4074 +:102670005A1001514432823438219808C90F44124B +:1026800080A8FA58382099095A480118442280FC39 +:1026900038411808442000C8D5065A180208FA44E0 +:1026A000441280A838209909D5085A1803054420F7 +:1026B0000032D5F75A1004F544228030441280903D +:1026C000846038411A024402824038309909441229 +:1026D000806038801A0138409A0A38111A01444241 +:1026E00080008A2838121A099472888188418820CB +:1026F000A491A449383F18089A51AC618421101361 +:1027000080DC4412813838309808441281EC38302B +:10271000980844128204844038209A0A8481D502A1 +:102720008480380F1800104380EB3C1DFD40C0181A +:102730008E01442281F8960038011808C81144021D +:10274000815C38129A0A3820190144028204C204BA +:1027500044200384D503442000E138201A0A44327F +:10276000824094B24E4200DD4482823438129A0A8A +:1027700038041800148F8001C80538119A0A4800DF +:1027800000DE5A08035F440280003C83FA80385020 +:102790001A113C03FA8138419A0140F28013F0810A +:1027A00040143C01440280008A249902886222423B +:1027B0000001F00141E20013A4D98A1E96499AC390 +:1027C00096D93C1BF92EFE4A964B3C3BF92FFEDA7C +:1027D0003C1BF92C96DB44028000FE6C3C3BF92D3F +:1027E000F0824E15000AC5068422405284B6405736 +:1027F000940138501A09FEE44E35000A9842C40686 +:10280000846240420C96404F1001AD0938301A11D5 +:10281000CB0B44128000882222108001C90544128B +:102820008234383098084412824088028B03388002 +:102830009A09A4018822F2018A40AC894800007FED +:102840005A0001044800007B444280FC81043802A5 +:102850001800C01B445280303C0DFD4038129A02D3 +:10286000F284F383F58249FFFCACE609F502F30339 +:10287000F204E80838129A024402806038101A0AFA +:10288000D504840038041808385418004482809015 +:10289000CD1B441280603C0DFD4038109A02F2843A +:1028A000F383F58249FFFC8DF5028025490032BC97 +:1028B000381419019601E2203C0BF92AF303F204C3 +:1028C000E80338041909440280A8381019013804B3 +:1028D0001901E201E90944028090F4013810190954 +:1028E0008400380218084452800038041901384224 +:1028F0009A119A08FF043C83FA80404204964044AF +:10290000100138419A098862884522210001FE148D +:10291000400004163C13FA819A08AC19D50F440202 +:1029200090D438001800E604E9093C03FA80884393 +:1029300038019A093C03FA81AC11E74BE9072E07ED +:10294000EB405A0801043CAFFB5F00138082443225 +:1029500090D444028138C90538119800E624E90C66 +:10296000382198008420E64438101808E9054422EC +:102970008234381118083810180044428108440283 +:102980008240C1309EC94412813896D838309808A8 +:10299000441281EC38201A1138A0980038521A11CC +:1029A00040150C0140830808FE8C880842228C7375 +:1029B000405220002200000122F28001FE0C42075A +:1029C0008C734021285640002816960396931204D3 +:1029D0008001AC291224800038221A0984014800A1 +:1029E00000BDB42794B28E21E622E8403811980049 +:1029F000445290D4E62AE93A44A290B438F5191129 +:102A00005EF78493E93322F3804638801A1150A090 +:102A1000FFF65210800E4217842442142873854416 +:102A20004010A8361214800038129800880222F351 +:102A30008047228000015000FFF65210800E42179E +:102A40008424421400734010A83612148001380206 +:102A5000980010A380508C019600380298085A08FC +:102A60000F74840038019808D56F38519800E6A497 +:102A7000E963441290B450A2FFFC38F0991152520D +:102A800080095EF7849222138046E82722F380476C +:102A90005EF78033E9054480003212838047388036 +:102AA0001A11FE6C4214287385454050A8B6125482 +:102AB000800038119800880222F3804722800001AC +:102AC000520080099F4C4217802442141473401016 +:102AD000A83612148001D52344800923128380472D +:102AE00038801A11FE6C4214287384A54010943665 +:102AF00012148000441290D488023810980022806A +:102B0000000150A0FFFC5200800944100923FE0C74 +:102B10004204287340001416120480018404100338 +:102B2000805038019800E609E89D441290D48C0149 +:102B300038009808D50938101A018802121480004C +:102B4000A4011204800102048000884438021A099A +:102B500002048001AC118400100380DD3C1DFD40A7 +:102B60004402803038101A0AFCC44400003248FF86 +:102B7000FBB0FC482270800022608001441000FC01 +:102B800042018473B52044427FC4945A3C5DFEC127 +:102B90005A980116ADD0AD9138720E09A62D8881D4 +:102BA000ADA15A0001044800015C44027F948820D2 +:102BB000844038200E09AC8948000153F28C000093 +:102BC0000020A6AD8143F286F08B5A200104480014 +:102BD00000ABF00B960E4E0200A744027F94382003 +:102BE0000E11CA0A8820220080014E02009D387210 +:102BF0000E11480000998801229000014E930007B1 +:102C00008824226080014800008F8007901FF08791 +:102C100040037C0A528100008824F0884004FC0AAA +:102C2000F08140047C0AF0822200800138120E11EB +:102C3000FE1442048475F102F083901FF0898048ED +:102C400080618008F784490057B78381F18DF101D5 +:102C500080E0804980098061490057AE8080880704 +:102C6000E204F18E883CF08540078400F204F10D07 +:102C7000F307F08A8007F48F4900579E80E0F30243 +:102C8000F18D8009F1018048490057968046F3088C +:102C90004900579241C38001F00DE2FC8A01407067 +:102CA0003C01F203F3098009F10149005785400E08 +:102CB0000001402E00069A79F30A8A22F2054900A3 +:102CC0005679F10197C384405204800040210006E8 +:102CD000FE4AF3028A2280484900576EF204F30745 +:102CE0004900576AF40F8380812180048046F308ED +:102CF000F10E49005761406E0000E2DC88294097E0 +:102D000084008008F102F203F309490057559A3014 +:102D100040630006401484018A26F205F30A490044 +:102D200056499783F50B44927FC4974EC5783C0D66 +:102D3000FEC0802702300009E0E3E9073854AA11F9 +:102D4000E0A3E80E9F59D50C4E7400083854AA1120 +:102D50004E55000784A0D50480A78480D5028481C5 +:102D60000200000A40850808F081F2018006E0C2F6 +:102D7000E9094044A00022420001E082E80F9F11CF +:102D8000D50D4E6400094044A000224200014E448B +:102D90000062D5045A4801448086890939C4AA11C1 +:102DA000228400014023F00140F32001C20B840281 +:102DB00041E2F00140010016420F3C73400008164A +:102DC0008808E80B842241E2200140178436421F24 +:102DD00008734010BC36883C4C44003FE023E905B2 +:102DE000523180018861D5044E140037FECA4C5E12 +:102DF000000DF201E002E905522100018840D506EC +:102E00004E040004FE82D5028440E043E80497EBC0 +:102E10009783D505E062E80397CB97A3F1064005B9 +:102E200008085A18010F3824AA0144127F949ABA4C +:102E30003820AA09402480008820A4919AB2AC8945 +:102E40003874AA098920F00C12648001ADC0AD81EC +:102E5000D5078480D5A384604C5E7FCDD5E0FCC8C7 +:102E6000FC43F1833C1DFEC1812084003C0FFB5FCD +:102E7000A44D3C0DFA6FE201E8048C013C0FFA6F9F +:102E8000814980C984E03C0DFEC000300009E2E3C6 +:102E90004EF200C6B4064E0200945A0806044800DA +:102EA000009022130004442298A4943A38111E0979 +:102EB0002213000588023C8DFEC1AC41A436B0450A +:102EC000120F800AA4378041120F800B000400010A +:102ED0008067B61F3C4DFA6F80093C5DFEBF49FF1D +:102EE000F8B600040004C00B49001B735A0802081E +:102EF000B045800980418067490059963C0DFEC16C +:102F0000A602C00AB045800980418067F40344529C +:102F1000889849FFF9613C0DFEC1A603C00C490029 +:102F20001B585A080209B045800980418067F403A4 +:102F30004900585AB04580414402990896F82E40FD +:102F40002E3149FFEB7AB04580098041806749FF07 +:102F5000FE12220F800A4E0400058400120F800A20 +:102F60003C0DFEC0222F800A02100009E041E90456 +:102F70009E89122F800A222F800B4E240005844048 +:102F8000122F800B0200000A222F800BE040E90480 +:102F90009E81122F800B222F800A225F800B00332C +:102FA00000DAACB4AD755A38010CC2078E214C2042 +:102FB0008005C5038E01D8048402100300DAB4260C +:102FC0005A1006045A180823000300DCC0035A18DC +:102FD0000819440000783E07FAFA2E07FAF9E602CB +:102FE000E80E042300225A280105002300E8C2034A +:102FF0005A18080D8C013E07FAF9D5088401D5044A +:1030000084003E07FAF93E07FAF82E07FAF88CE139 +:103010003E000309506300FC48FFFF372E07FAF813 +:10302000C8072E07FAFAC0108E013E07FAFA44408C +:1030300000FC429190733C27FD7E3C17FD7F3C0DC8 +:10304000FA6F8089D50E3E07FAF9D5F2B46A5A387C +:1030500006072225000422150005840050A500FC67 +:103060004CA27FF63C2BFD7E3C1BFD7F3C0FFA6F94 +:10307000FCC3FC2084808E4184C2E044E91198E2C4 +:103080004031987638700D019559E027E90788A0FE +:10309000A529E024E9079D19D5F19E99D5EF841F54 +:1030A000D5028003FCA0FC423C7DFEC2F18250139D +:1030B000800AF181508380DC51C000028540853E4A +:1030C000F002E3404EF200DB226E7FFFA43DE006FB +:1030D000E85CA53C9C23940188079EA1A401E0C064 +:1030E000E904A5B88EC1D552F0018026F48349FFCA +:1030F000FFC25A07FF4CA57BA4B9E2059441F40333 +:10310000E8108827FE14A4CDA44E8AC3FF94404340 +:1031100014969B8B406218D6405014B788C5D5369C +:103120008A858E81E204E9188827A4FAA50D8865AE +:1031300052F18001880F8AC4FF94FE1440001417D6 +:10314000A4F8405314B6A58E8A628AC488034062EC +:1031500098D688C0D51B8827A4F84231247381E310 +:10316000A4CDA53A8A058AC38E814267982442007D +:103170003C244000101740431096A58E88408AC317 +:10318000406218D688C2D50284C0126E7FFF020347 +:10319000806E226E0000E006E86B0243806D5002F4 +:1031A000006B940188079EA1A402E0C0E9050263B8 +:1031B00080698EC1D55E80088026F48349FFFF5B5D +:1031C0005A07FF580253806C0223806AE20594413B +:1031D000F403E8128827FE140230806E0210806F1C +:1031E0008AC3FF94404314969B8B406218D640508C +:1031F00014B788C5D53E8A858E81E204E91C8827EC +:103200000233806B0240806E886552F18001880F26 +:103210008AC4FF94FE14400014170233806940539F +:1032200014B60260806F8A628AC48803406298D6AE +:1032300088C0D51F8827023380694231247381E317 +:103240000230806E0243806B8A058AC38E8142679A +:10325000982442003C24400010174043109602601E +:10326000806F88408AC3406218D688C2D50284C065 +:103270001A6E000C8D4148FFFF25FCC2FC43F08113 +:10328000F601FA0242608073B40495B199C6838155 +:10329000A678F0838400F482B602A8115A18FF05BC +:1032A000B623A859D50CF002A678A0013800050174 +:1032B000962FB603440000FFA8198401F4014617B5 +:1032C000FFFF50108FFF8824F18480248C21507ED2 +:1032D0007FFFF185501E0001E0274EF300805CF374 +:1032E0008024E878F101F4045090FFFFFA22424371 +:1032F000847394618825F405E089E96CE732E86716 +:10330000F4014C9240054C7E4005D5614C7E4060F6 +:10331000F40340A0940138A228005AA0FF59F402F7 +:103320000482000138A4290154A5003FC80F22805F +:10333000800039E2981140FF2007E849B743B40202 +:103340008B1E8900B7028401D5425A080115B503C6 +:103350004CA400172280800039E2981140FF20071A +:10336000E83614A18001A0118B1E89001481000190 +:103370008402D52D5A080233B5034CA4401022A074 +:1033800080003882981105E10000E10AE8038B48CB +:10339000D5028540895EB742D51A048180014CA4CC +:1033A000401122A080003882981105E10001E10A55 +:1033B000E8038B48D5028540895E14A10001D5073A +:1033C00022F0800038829811E10FE9078D218C22CC +:1033D000D5938CE148FFFF808403FCC3FC4680C08A +:1033E0003C0DFEC3B63FF287A602F0842E07EB4ADF +:1033F0005A08050884003C3DFEC38020480000A216 +:103400002E1002DAC9F8F0049401F0852E07EB358E +:10341000E020E8F14403F04A44200055AE8004A3C4 +:10342000000138550501F5834C50C089A035948AB8 +:10343000884087C0A6D0A751E662A612A693E904E9 +:103440008E6255E180FF3C3DFEC3A71A9FE2E0A7D4 +:10345000E8048CA29728D5038E819720E602F48198 +:10346000E9048E029600D5028400A6DB9F1AE04490 +:10347000E8048C429690D5038E619698F304F2820C +:10348000805E42200C7394918480F2868064804038 +:103490008124F502E0A2E929F506811E88A4F7013E +:1034A000E0E8E91FB4E640F394000077800197D686 +:1034B000CF090077800004FF800338751D014C7729 +:1034C000C00EF70738739411CF09B4FF8C6196D9F9 +:1034D0003873940188E9409380118D018CA2D5E066 +:1034E000F5058C418885D5D640418409892440342E +:1034F0008C76F206B49F8844F402E080E91F80FED7 +:1035000080A2F401E087E917B49FB5269B2C888937 +:103510000092000154F48004E908A720049F80036E +:10352000384511014C44C005A5288A83AD288CE19B +:103530008CA2D5E88C01F405D5DF8C2148FFFF680B +:1035400000218038E002E80DA0B63811020AA0B7C9 +:103550003811020A042300083811020A8C01D5F13F +:1035600085002E07EB35E3004EF200E4A031385021 +:1035700021014C5440DCA075400408088801A7C212 +:10358000E6E2E9048EE197F8D50284E0A6435CF018 +:103590008022E8048C219648D502FA33F183A640B4 +:1035A000E622E9048E219648D5028420A601F18105 +:1035B000E610E8048C019600D502FA01F084FA02C4 +:1035C000FE3CF082F003E0074EF300B104AF80014F +:1035D000F002B43F880A940140908000F004E00AB1 +:1035E0004EF300A0B41F40048001F085F105B4063D +:1035F0008801200000014E050091220480004E0742 +:10360000008D800A8027B088B0CA8086B4BF49FF89 +:10361000FE375A08011DF00AA07694028801221490 +:103620008000B44042250473B640F00AA0B794026B +:103630008802B44042238473B640F00A0423000891 +:1036400094028802B4408822B620D55F5A08025EF0 +:10365000F10AA0F622048000F508F409944A8823B0 +:1036600042201424888540411096B44142251073AD +:10367000B641F20AA17704FF8008F40994928845C4 +:1036800042103C24888F40409096B422421390739D +:10369000B622F40A0423000805EF8008F1099522F8 +:1036A000888242F07824883E4017843604F2000075 +:1036B000882FB624F10B04FF8009F408944A88612E +:1036C000888F42103C2440409096B42342151073DA +:1036D000B623F10BF408944A8825F50942301424E6 +:1036E000888540419096B46142339073B661F10B86 +:1036F000F309944A884142100C24F00888034000E2 +:103700008016B4228801B602B406F1058801441F70 +:10371000FF80A681FE57AE418D418D2248FFFF609C +:10372000F0028CE18C1248FFFF4E8D0148FFFF1B19 +:10373000FCC6FC403C7DFEC380C19B31E282E81F99 +:10374000A10704900008048000060853000100A3AC +:1037500080323894960238421602385416028C7819 +:10376000425514244052A4B71251FFF40053803341 +:10377000FF2C404224971241FFF5D5E0FCC0FC41EC +:1037800080E08400F2818143AE28B63F812480C569 +:103790003C2DFEC38400443288B0E20AE810A079D0 +:1037A00038508101D819A67038018408A6708C2180 +:1037B0009648AE7000410019E224E90E8007F2013C +:1037C000B43F49FFFE0D8400AE3084A03C0DFEC323 +:1037D000442288B0D5098C01D5E1A0793810950133 +:1037E0004C1280068CA14C557FFAD50CA67038512E +:1037F0000408A6708C219648AE7000300019E223B0 +:10380000E9F28007A6B08069441288B049FFFF93AF +:103810008400FA48443288B0A670E201E8098029A1 +:1038200042100873384180008C01A90DD5F6FCC107 +:10383000FC2080E480C5C83FCA17CB112E07EADC04 +:103840005A0801053C0C0179D5555A1004392E004F +:103850002AFC5A00014C3C0C0173D54C5A38014CDF +:103860005A18043ED52C5A280152CB095A1804057F +:103870003C0C0175D5163C0C017FD50A5A38011352 +:103880005A1804053C0C0178D50C3C0C0176B606A0 +:103890002E002AFC5A0801072E07EB52490007E0C8 +:1038A000B606B40684203C0FFB044403F40BAE4080 +:1038B0008421D5295A08012BC90ACB043C0C017577 +:1038C000D5195A3801193C0C0178D5145A1801142D +:1038D000CB043C0C0173D5055A38010E3C0C017623 +:1038E000B6062E002AFC5A0801072E07EB524900A3 +:1038F00007B7B606B40684233C0FFB044403F40B5D +:10390000AE4084204403F40DAE40A47044024E2027 +:1039100097F8AC404403F40044104E20AC404403FC +:10392000F402AFC0FCA084003C0FFB8A4403F40304 +:103930008421AE40DD9E4403F403A6005C00000138 +:10394000DD9E4413F40384003C0FFB8AAE08DD9E29 +:10395000FC0084C03C6FFB8A5A08010949FFFFE55F +:103960003C6FFB8A3C6BF5DCD50349FFFFECFC8028 +:10397000FC204463F01D4473F421A670A631A6B068 +:1039800040002008FE0F580004009640AE709208D8 +:10399000A671AE3144000055AE38442000004430DA +:1039A000000A502100014C21FFFE49FFFFCC84009A +:1039B000AE38442000004430000A502100014C2160 +:1039C000FFFEA6309600AE30FCA0FC402E07EADCDD +:1039D000B4E184C04490003C44A200005A08014C69 +:1039E0002E07EAEBE2C04EF2008580064900253A38 +:1039F00002138012421024733C0DFB174010A804E0 +:103A00003C1FFB01C81602208014440FCFFFFE8626 +:103A10001220801402208015FE86122080150220BC +:103A20008016FE861220801602208017FE16D517FB +:103A3000020080145800300012008014020080152B +:103A40005800300012008015020080165800300027 +:103A50001200801602008017580030008CC112003E +:103A6000801797B0D5BE8006490024FC5A080C097F +:103A70008CC197B02E002A8FE2C0E9F6D53A021326 +:103A80008012421024733C0DFB174010A8043C1F09 +:103A9000FB01C81602208014440FCFFFFE861220BF +:103AA000801402208015FE861220801502208016C8 +:103AB000FE861220801602208017FE16D5170200FF +:103AC0008014580030001200801402008015580045 +:103AD00030001200801502008016580030001200DD +:103AE0008016020080175800300012008017D5C1E0 +:103AF000FCC0FC0049FFFF6BFC80FC214413F0601C +:103B00004463F061A6084473F04A9600100F8007E2 +:103B1000000F8007540000FC100F8007000F800783 +:103B200058000003100F8007AE088400100F8007B4 +:103B300084003C0FFB4E000F80075A000311A63093 +:103B40009600100F8007000F8007960F100F800758 +:103B500044000055AE38490041B8D5EEFCA19403AD +:103B60008420442296C0380105098C215A1808FD8A +:103B70003C2DFB0444010000444296C00411000C9B +:103B80008060FE471411000C4450005C8420972193 +:103B9000A016920A962FE220E80A0201001288037A +:103BA000420094738C211240001AD5F3DD9EFC2153 +:103BB0004413F0604463F061A6084473F04A960031 +:103BC000100F8007000F8007540000FC100F8007C3 +:103BD000000F80079600AE08841F100F8007840036 +:103BE0003C0FFB4E000F8007C010A6309600100F50 +:103BF0008007000F8007960F100F800744000055C4 +:103C0000AE3849004162D5EFFCA13C0DFB04020037 +:103C10000016DD9E44220000FE174430003C0200E6 +:103C2000001242008C738840A616DD9E44220000DC +:103C3000FE174430003C0200001242008C738840A2 +:103C4000A615DD9E3C1002E644024E20AC40DD9EEF +:103C50003C0C017346100370501080370250001561 +:103C600044020000FF47460AFFFA502280785000C5 +:103C70000FFFB605A829A86A8CACDAFCDD9EFC20F3 +:103C8000B48084608C8484E6B4045A380506920AB1 +:103C900040002808D504921E4000780842219C2448 +:103CA000969084A05A20200C386088008C41406394 +:103CB000140C8CA5880696905A581EF68C6196D8DE +:103CC000AA215A3806E3FCA0FC00A6495A180607A8 +:103CD0004412940849FFFFD5D50E5A10030850200E +:103CE000FFF6E642E9035A180D072E17EB528E2114 +:103CF000E622E8EFFC80FC0084003E07EB508403E2 +:103D00003E07EB462E07EB52E6023E07EB3F8400F0 +:103D1000E8028403848144527ADC3E07EB522E078A +:103D2000EB502E17EB462E27EB0B2E37EB2C49FFD3 +:103D3000FD8144027ADC4412940849FFFFA22E0759 +:103D4000EB3F84813E07EB5244527ADC2E07EB5066 +:103D50002E17EB462E27EB0B2E37EB2C49FFFD6A77 +:103D600044027ADC4412940849FFFF8B2E07EB3F94 +:103D7000E6028403E80284003E07EB52FC80B48034 +:103D8000840080403830800095414031940C8C0193 +:103D900088435A0810F98400A8A7804050300010CA +:103DA00096D8954138308C008C014031940C884372 +:103DB0005A0810F614220008DD9EFC00B440806012 +:103DC0003C2FFB04A6495A1003045A180D06800321 +:103DD000441293A0D51A5A18040B2E000AE4E605E3 +:103DE000E91A2E07EB0B5A080105D5155A180508D4 +:103DF000A057841CFE0E58000001D5105030FFF66D +:103E0000E662E8064412A30049FFFFBBD5088E28EE +:103E1000E622E805A057841CFE0EA817FC80FC00D3 +:103E2000A68180C05A20031F5A20061D9E14E60258 +:103E3000E80684003E07EB508404D51C50017FF84F +:103E4000E602E80684013E07EB508400D5135001DA +:103E50007FF6E602E90C5A280D27490013BA5A08E2 +:103E6000020784003E07EB508403D50484013E071B +:103E7000EB503E07EB462E07EB5084812E17EB46A6 +:103E800044527ADC2E27EB0B2E37EB2C49FFFCD269 +:103E900044027ADC802649FFFF9244027ADC8026C5 +:103EA00049FFFF14FC80FC212E17EB3EF081C91561 +:103EB00084213E17EB3E44200048441248944900B8 +:103EC00011DBF0014412492444200048490011D478 +:103ED000F001441249B4D5122E17EAC684034010EB +:103EE00080179600441248944420009042100873B2 +:103EF0002E000AE65A000214F0014420004849004E +:103F000011BB2E07EAC684238C019600402004379B +:103F100096484010041B3E17EAC6FCA1F2018460DB +:103F200044728A080251004838638C0180029B2E3B +:103F30008C424E440003FF22A4008A064E04000374 +:103F4000FE02E004E80312517FFF8C625A3890ECC5 +:103F5000D5D4FC40840084203C0BFECC3C0BFECB33 +:103F60002E57EB528061800144624A5C44724A5E83 +:103F700044924A6044A24A62C5035A580303C91BCB +:103F8000948B9916028200003C43FECC88883C4BFF +:103F9000FECC9917028200003C43FECB88883C4B44 +:103FA000FECB40412400884AA520A4908804886262 +:103FB000960196D98C215A180AE13C13FECC3C2379 +:103FC000FECB8801985A964996013C0BFECC88019D +:103FD0003C1BFECB3C0BFECAFCC0FC4000AF802467 +:103FE000844001CF80204085040880A24C5E001AE6 +:103FF00080C484604090080099CA54F180FF40F763 +:10400000A806E80B02F3000038F48D090AF300015A +:1040100038F38D098C61D5F28CA197688848D5E773 +:10402000FCC0FC00001F801084A0944988224C2012 +:104030008018A500A590E2C4E803A500AD10A580F6 +:10404000A518E2C4E803A500AD180A4100010A6101 +:1040500080018A86E0A4E80297618C02D5E9800598 +:10406000FC80FC42443000909541810044020BF0FA +:10407000880580C142340C24444223A044927A1C17 +:1040800044727A0444A00048442221F0F083B043F3 +:104090008843B75F8864440205204044940088C880 +:1040A00088A749FFFFC097B04412910038009909D2 +:1040B0002E07EB525A080111B75F44020520B043A6 +:1040C00044222310443224C0504480049D7C49FF84 +:1040D000FFAA3C0BF5BAFCC2FC002E07EB56C02031 +:1040E0002E1002FB3C0C0B925A1801049201D502CF +:1040F00092023C1C008D9601E2202E0002CEE805C3 +:10410000E61EE80E8C01D50AC00B5CF08E10E905A6 +:10411000E60FE9038E05D5028E013E0002CE3C0378 +:10412000FEC9E61FE90F2E0002CE5A081E048405C0 +:10413000D505E6148406E80284073C0FFB1B8401C6 +:10414000D50F3C03FD9D5CF00033E8052E0002CE48 +:10415000E60BE808490017DF3C0FFB1B84003E001C +:1041600002FBFC80FC52842080C080E2801F44203F +:1041700000902EA02A6349004D713C03FD9D2E90B6 +:104180002A8E5CF00033E92C400504088440960038 +:1041900080A285439668E229E823842096C8E260DD +:1041A000E81C98CA94D98866384F8501A4D8403154 +:1041B000A47688642E402A8E96D98E81383F850950 +:1041C000DC0A384385019262424228249082886446 +:1041D000383385098C21D5E38CA18840D5DCFCD20D +:1041E000FC0084003E07EACF2E07EAC9E602E90494 +:1041F00084013E07EACF2E07EB543C13FEC9E201CF +:10420000E8053C13FEC8E201E9193C0C05605A00C0 +:1042100001062E0002FE5A0801063C03FD9B8C019C +:10422000D50284003C0BFD9B2E07EB3DC00C3C03EC +:10423000FD9D8C013C0BFD9DD50684003C0BFD9D36 +:104240003C0BFD9BFC8084003E07EAC984003C0BCC +:10425000FD9DDD9EFC003C03FD9D5CF00033E90606 +:1042600049FFFFF384003C0BF5BD3C03FD9B5CF074 +:104270000033E90484003C0BFD9BFC80FC0049FFFB +:10428000FE6A2E27EAC13C13F5BA3C0001B040108B +:104290008836400008163C1BF5BA3C0801B04900BE +:1042A00011985A0802093C0DFF670010002B4400CA +:1042B0000032D5054410FFFF440000963C23F5BAB8 +:1042C000E240E9053C2001B0E240E80A3C03FECAB6 +:1042D000E220E90684003C0BFD9B8401D5028400AA +:1042E000FC802E37EB528E62E662E81D40302C0ACD +:1042F00096C6C304443FF000FE1F3CF7F5D6E00F1E +:10430000E8042E000B02D50A3CF7F5D4E00FE804D0 +:104310002E000AFED5032E07EAC4AE102E07EAC807 +:10432000AE08D5072E07EAC0AE082E07EAC1AE10C8 +:104330002E07FD9A5A08010D2E07EB528E02E60257 +:10434000E8072E07EAC8AE082E07EAC4AE10DD9EC5 +:10435000FC405A0803053C5C0174D5033C5C0173C6 +:104360000232801844620000FEF7A418A1D9B46399 +:1043700002428012927040900013547387FF5431B0 +:104380008FFF9721C908504200B4FF37A0A45421E1 +:104390000FFF969354010800C004440FF000FE87FD +:1043A0000012804946000096500002585A18010732 +:1043B0005014800288238841D50388478C42949109 +:1043C000400008169601FCC05A0803083C04057515 +:1043D000AC083C040574D5063C040577AC083C04E5 +:1043E0000576AC10DD9EFC403C4DFB044460003C77 +:1043F00096F7025200124250187344020000FE2F3A +:1044000054608FFFA14492AC4052B008FF77A9449A +:104410002E77EB529F79E6A2E824B4A05852808010 +:10442000B6A084A35A78010380A704900004974F94 +:104430004062B008445FCFFF40549402FF77A94424 +:10444000A144466F00FF50630FFF40215008FF76E4 +:10445000FF57A944B44092479497FED7B660D5174A +:1044600084A1C70284A304900004446FCFFF40528C +:10447000B00840649802FF77A94410220049B4A410 +:10448000442FFC0794DBFEAEFED7B6648EE2E6E274 +:10449000E82A838444210000BB0CFE9FBA8C8380F1 +:1044A00046380000BA0C94929242FE9FBA8C2E3786 +:1044B000FD9A44201B241220001A5A3001123CF7A6 +:1044C000F5D6E02FE80444101B9CD5073CF7F5D443 +:1044D000E02FE80644101B601210001AD50F1220BE +:1044E000001AD50C8384441EFFFFBA0CFE56B98C0B +:1044F0008380B90C944A9222B98CFCC0FC422E777E +:10450000EACD3C0326E48EE1120F800484C02E061F +:104510004DCA448288BC100F800A3C0326E6120F65 +:1045200080062E064DCE100F800E2E07EAD0FFC457 +:1045300097F82E07EAD0E2C0E8212E07EB525A087E +:1045400001063C97F5BBB003D505983E38940111A0 +:10455000B0028140501F80068009502F800749FF1C +:10456000FEC2380518008029002F8006003F800712 +:104570008CC149FFFF3A97B0D5DDFCC2FC418120D8 +:104580002E07EB52C8043C77FD9AD505440288BC3F +:10459000387025113C0DFF670000002EC0033C74ED +:1045A00015B22E07EAC2501F80063E07EACB2E073F +:1045B000EACA502F80073E07EAC3800749FFFE93EF +:1045C000000F800684C03E07EAC2000F80073E0746 +:1045D000EACA80068CC149001F4597B080272E2764 +:1045E000EAC22E37EACA49FFFF005A680AF43E972A +:1045F000EAC5FCC1FC0049000FEC5A08022644132E +:10460000F0602E27EB45A608540000FC5A28011143 +:1046100058000001AE084423F04A4413F0614430CE +:104620000055A608960F5A000110AED0D5FBAE0873 +:104630004423F04A4413F06144300055A608960F15 +:10464000C003AED0D5FCFC80FC402E47EAC02E272C +:10465000EAC180E0FF14972084004092040944607E +:10466000FFFF80A0D111A4B840A11076E123884FAC +:104670009691E2464002BC1B8CA11A238001406146 +:104680003C1B9768D5F0FCC0949180A088408400C2 +:10469000D2080A328001E223E8FC9CC19618D5F9C1 +:1046A000DD9EFC002E17EACD2E67EAD08E21FE7427 +:1046B000840096483E07EACE94494402910088015E +:1046C0008046FA2E49FFFFE2FE355C0000013E07FE +:1046D000EACEFC80FC0049FFFDBF84202E07EB5290 +:1046E000804149FFFE373C0BF5E02E07FB385A08A6 +:1046F000011B84C03E07EACD3E67EB3E3E67EAC63B +:104700003E67FB3849FFFDA13C0DFF670000002E0E +:10471000C00A3C0015B23E67EB3D3C0BF5BC840083 +:104720003C0E00BBFC80FC003E07EB523C0DFB59ED +:1047300049FFFB772E07EAC549FFFF2284013E07A8 +:10474000FB38FC80FC0080C02E07EB56E606E9042F +:104750002E17EB01D50E2E07EB42E602E9083C14BA +:10476000038B8402401080369649D5033C10159582 +:104770002E0002FB5A0801042E102B822E07EB3D5F +:10478000C8052E002B8488209649AC702E002B8201 +:10479000AC3449000F1E5A0002113C14038B8403F1 +:1047A00094494010803696495CF08055E903AC701E +:1047B000D50444000055AC30FC80DD9E2E3002FB59 +:1047C0005A3001062E37EACC5A38011784603E373A +:1047D000EACC003000103E302E31A00794023C0E8F +:1047E0000B8DA60A3E002E84A60B3E002E85A41239 +:1047F0003C081757D51AA6C03E302E31A0033C0EF8 +:104800000B8DA6083E002E84A6093E002E85A4101E +:104810003C0817572E0002CEE605E90D2E000C606D +:10482000C8042E000D5CC007440000A03C081758C7 +:10483000FA04D505FA043C08175884043E002EB249 +:104840002E07EB56E605E90A2E000308C0074400D0 +:1048500000643E002BEC3E002BEDDD9EC8043C0CBA +:104860000173DD9E5A0801053C0C017BDD9E5A0850 +:1048700003053C0C0174DD9E3C0C017CDD9EFC00BC +:104880002E07EB3BC00484003C0E00BB2E07EB3D23 +:10489000C8303C1C00BBE634E92C3C0804C244226E +:1048A000163480603C10154AE201E80698428C01FB +:1048B000AEC89601D5F83C0C01DD3C1C01DF490077 +:1048C0000D06440000333C0BFD9D3C0DFB17C0045E +:1048D00044023520D5034402052044128A9C442218 +:1048E0008A084432897449FFFC3F84013E07EB3D4E +:1048F000FC802E17EB522E07EB48C1062E17EB4516 +:104900005A1801038C013E002B28DD9EFC202E3717 +:10491000EB5284409F1A5C420002E66244528A08CD +:10492000446003E8C4093872890138300901FEFC8B +:1049300040319877D509E80A383289013870090181 +:10494000FEF440319C77383089098C415A2848EC74 +:10495000FCA02E47EB522E17EAC02E07EAC12E37D5 +:10496000EAC82E27EAC4CC04808180A0D5058083C4 +:1049700080A2806180402E0002FD5A0802322E176C +:10498000FD9AC92EFC403C6C01DF44722A603C0059 +:10499000154AE220E81E940940801C004093000064 +:1049A00002A40000020480000284000042A50C243E +:1049B00042040875FE2442050873FE2C40000C16C4 +:1049C0004000081696018C21120480009649D5E01B +:1049D00084003E07EB3D84003C0E00BBFCC0DD9E26 +:1049E000949188404C0100051A100001D5FCDD9E11 +:1049F000FC4084C04490009044A221F02E07EAD0ED +:104A0000E2C0E8282E07EB1A427324245A08011347 +:104A10004003A80084204420004849FFFFE34402EB +:104A200023A088074410FFFF4420004849FFFFDA15 +:104A3000D50E440288E04013A80049FFFF694412E4 +:104A400023A0440288E0882749FFFF628CC197B009 +:104A5000D5D6FCC0FC402E77EACD81202E07EAD0C7 +:104A60008EE1FFC43C0DFB4D842184C0AE40840127 +:104A70003C6FFB7897F84900108C44A3F04A49FF3B +:104A8000FFB93E67FB3849FFFBE04C648036840089 +:104A90003E07EB5949001DF0441000552E07EB5915 +:104AA000E60AE823101500003C8DFB785A8801F8CF +:104AB00084003C0FFB782E07EB598027960649FFB0 +:104AC000FAD22E17EB595004FFFF8C2196483E175F +:104AD000EB594C603FE32E07EB595A080ADF3C0DB7 +:104AE000FB4D10800000D5D9440FFFAA8CC13E07B2 +:104AF000EB2597B0D5CB84004900104BFCC0FC429D +:104B0000F082840044600048F1833C0BFEC93C0BFA +:104B1000FEC849FFFA20840144327A0444428A08DC +:104B200044528974B61F441223A0440221F0442247 +:104B30007A1CF68149FFFA534402231084208046F0 +:104B400049FFFF50440224C04410FFFF804649FF44 +:104B5000FF49F00249FFF9A984E044824894F00338 +:104B6000814840901C0042A398738029442221F080 +:104B7000443223A044427A1C44527A04B6DF800AAD +:104B800049FFFA513C0BFEC9B6DF800A8029442256 +:104B90002310443224C044427A2044527A0849FF08 +:104BA000FA428CE23C0BFEC85A7806DB2E07EB5229 +:104BB0003C1DFF67C8150260800E0070802A490006 +:104BC0000D085A08020496F9D5243C0DFF674430BD +:104BD000FFFF0260000E8403FF8497B1D51A3C33B7 +:104BE000F5BDC3153C03FD9D0210800F42218024BA +:104BF000FE44446FFFCE44000032406118D64000AE +:104C000080168806999897B18460D5030260800F5A +:104C10002E47EB522E27EAC13C13FEC93C03FEC8C7 +:104C2000C4152E57EAC0FEAC401088364000081666 +:104C3000969040510409407089F6E0AF882F3C1BE4 +:104C4000FEC9401009F6E0AFD5104010883640513B +:104C50000409407089F6E0AF882F400008163C1B1D +:104C6000FEC940100856E0A23C13FEC9880FE2C1FD +:104C70003C0BFEC82E07EAC9E907CC143C23FECA48 +:104C8000E262E903D50FCC083C1BF5E13C13FECAF8 +:104C90003C1BF5D9D5055A4803043C1BF5DE8C01B5 +:104CA000D503C0048E013E07EAC9FCC2FC412EA018 +:104CB0002A8E2E302A634210A82494D984C0F08111 +:104CC000964896D82FE7EB522E07FD9A80A644828D +:104CD0008A0845C289784C550023F40194B1884470 +:104CE000848097E0E2E3E81702F1000095E140F7E5 +:104CF00085F65BE80309C807389E1C01892F389E9A +:104D00001C09D50638941C01892F38941C098C8104 +:104D10008C42D5E88CA1976888C3D5DEFCC1FC0025 +:104D20002E1002FC5A10010944128AA044200048A7 +:104D300049000AA2D51680C0844044428AA0840A51 +:104D400084A638120901FE444030900A3813090144 +:104D5000FE6C90248823381209098C415A2848F3A4 +:104D6000FC804413F4034423F04A44300055A60861 +:104D7000C003AED0D5FDDD9EFC0080C049FFFFF32F +:104D80003C0DFB593E67EB5249FFF84B840049FF4D +:104D9000FBF784203C1FFB8A3C1DFB4D84013E0039 +:104DA00002FDAE0849001C684413F04A4420005537 +:104DB0003C0DFB4DA6005A080104AE88D5FA4413F9 +:104DC000F4034423F04A44300055A608C003AED093 +:104DD000D5FD3C0C01DD3C1C01DF49000A78440292 +:104DE00088E044128A0849FFFD9384013E07FB389E +:104DF0003E07EB3DFC80FC0084003C0FFB8A3C0D31 +:104E0000FB4D8421AE4049001C374413F04A442036 +:104E100000553C0DFB4DA6005A080104AE88D5FA9A +:104E2000441278EA4402951449001A5A49FFFD9346 +:104E30004413F4034423F04A44300055A608C00349 +:104E4000AED0D5FD3C0DFB4D8421AE404402052083 +:104E500049FFFF674402052044128A0844200048A5 +:104E600049000A0AFC80FC0080C049FFFF7C3C0D21 +:104E7000FB593E67EB5249FFF7D484013E07FB38EC +:104E8000FC80FC2084C0840184E13C6FFB173E77EA +:104E9000EACD49FFFFEA49FFFB3344022310802695 +:104EA0004420004849FFFD9E440224C04410FFFFF7 +:104EB0004420004849FFFD96440291008026844C1E +:104EC00049FFFD90840149FFFDC749FFF9D95A0008 +:104ED000011184033E07EB523C0DFB5949FFF7A13A +:104EE000840349FFFC223E7002FD3E77FB38D51853 +:104EF00084023E0002FD800649FFFC1749FFFF7D4A +:104F00002E07EB45C0053E67EB4549FFFB75840066 +:104F10003C0E00BB3E07EB3D84013E07FB38FCA086 +:104F2000FC40840184203E07EACD8446440291007F +:104F30003C1FFB1749FFFD56840249FFFF963C0DBD +:104F4000FF670060002EC6182E07EAD02E17EACDA4 +:104F500044629100FE449648800649FFFB773C2D51 +:104F6000FF6784203C1BF5BD0231000F381301019F +:104F7000E261E92BD5314493F04A447000555A6000 +:104F800001E51074800049FFFABB3C0DFF67A601E4 +:104F900049FFFD6249FFFB872E07EB1AC8052E0764 +:104FA000EACE5A0801D32E07EACD2E27EAD08C018B +:104FB0008426960040108836E0203E07EACDE8E0DF +:104FC0003E17EACD84C1D5DA5CF0812DE9034410A7 +:104FD000012C3C1BF5BD0011002D5A180103840063 +:104FE0002E17EAC53E07EAC584033E17EAC749FF04 +:104FF000FB9C2E07EB525A08030D2E07EB3FC80906 +:10500000440288E044128A0849FFFC828402D502E7 +:1050100084013E0002FD2E07EB1AC80349FFFEED96 +:10502000840084213C0E00BB3E1002FB3E07EB3D9A +:10503000FCC0FC0084013E0002FC49FFFB4D3C0C1F +:1050400001E144128A9C844049FFFD5B2E07EB522C +:10505000C8063E0002FB44000032D502FA0E3E07AD +:10506000EB5449FFF8BF3C0DFF670010002C5A10AD +:1050700001052E17EB41C9092E07EB52C00484002D +:1050800049FFFE7C8400D51B0010002D5A18010832 +:105090002E07EB525A0003F88403D5F30000002ECC +:1050A000C0245A0802103C0415B23C57F5BCD80481 +:1050B0002E17EB52C9E83C0BF5BC84013E07EACF42 +:1050C000D5145A0801133C57F5BC3C0415B2D0DB8B +:1050D000840049FFFE533C0015B23C0BF5BC2E0783 +:1050E000EAC549FFFA4DD5CF3C0C01E144128A9C38 +:1050F00044228A084432897449FFF8362E67EACF81 +:105100005A68010F84023E0002FD84003E0002FC4A +:105110002E07EB523E07EB3F49FFFF04D51E2E073B +:10512000FD9AC81D2E17EB52C11A3C0DFF670000F7 +:10513000002EC8153C23FD9B5CF10032E91084C1B0 +:105140003E17EB3F3E67FB383C0BFD9B3E0002FCED +:105150003E67EACC49FFFE973E6002FC3C0DFF67CC +:105160000000002EC0153C13FEC944021C53968853 +:10517000A6C09228AE80A681AE413C13F5E0440261 +:105180001C559688A6C09228AE80A681AE41FC80B0 +:10519000FC412E10030A3C3004C6B63F2E27EB56C6 +:1051A0002E17EB1D4462B8005DC1812C5CF181F5C6 +:1051B0008A412EA02BF42E47EB522E87EB428420FF +:1051C00080A64470007845E0005A14FF8001549096 +:1051D00080FFE32AE831C4064090040000F48020F8 +:1051E000D50338F0040040930400B47F10F48184A8 +:1051F000CB1F40900400C40400948028D503009481 +:10520000800840F284001097818C4FC300065A88B2 +:1052100001095A2801074092840011E4818CD50AC3 +:10522000F301CB085A280207CC0540928400107481 +:10523000818C8C21D5CDFCC12E17EAC02E27EAC166 +:105240005A08011F4201042496002E27EAC4400098 +:1052500020084020085644521B2444321B60ACA84E +:105260002E100AFE8CA2401004361212801D2E1041 +:105270000B02401004361212803BDBF2DD9E4452DA +:105280001B244400040044121B60AC281202801E40 +:105290001202803C8CA2D9FA3C4DFB04844044327B +:1052A0000000020200128802FE1F5021003C041080 +:1052B000000C944A92221410000C5A2AD0F4DD9E5D +:1052C0003C0DFB044412000002000012500002D00A +:1052D000FE0F44101B5E1210001A44021B5E4410A5 +:1052E0000400AC40DD9EDD9EFC2084003C0FFB4EA4 +:1052F0004463F4034473F04AA6305A08010844009A +:105300000055AE38490035E1D5F8FCA0FC2380C03B +:10531000A601F283F384F48580E55A080412A630CE +:105320005A08010F3C1DFB5C5A100A045A180B0660 +:105330004402951449001769840049001AC22E07D7 +:10534000EB605A08010A44027900F103F204F30504 +:105350008087490028E9440FFFAA3E07EB5D3C1D0A +:10536000FB59442278C4F303F404F505B6FF440264 +:105370007B0C49002A7396003E07EB4A49002647FA +:105380002E07EB4A5A00010584013C0FFB84A6312D +:105390005A080810A6305A0802433C0DFB5C5A001C +:1053A000063D5A080933490009145A08022FD53519 +:1053B0005A08090BA6305A0802333C0DFB5C8E06D6 +:1053C000E602E823D52A5A080A07A6308E02E6022A +:1053D000E826D5235A080308A6305A0801214900B7 +:1053E0000BF8D51B5A080406A6305A080119D51522 +:1053F0005A080616A7B05A680113800649000BE93F +:10540000800649000BC6D509844084618402FA25D0 +:10541000808380A24900162A8408D5028401FCA357 +:10542000FC00840149000BB52E07EAF55A08050D6A +:105430003C0DFB59A60149001A713C0BF5CC8401C7 +:105440003E07EAF5D50484003C0BF5CC84003C0B08 +:10545000F5CB3E07EB3084003C0FFB172E102EECF3 +:10546000840A442294084432947449001A15440F63 +:10547000FFAA3E07EB253C0DFB4D8421AE40FC808E +:10548000FC003C0DFB598423AE4149FFF4CA49009E +:105490001720840049000B7D3C1DFB678401AE088A +:1054A0003C1DFB4DAE082E07EAF55A0004058405A5 +:1054B0003E07EAF549001A46E6028400E90449007D +:1054C0001A418E023C0E00BA84023E07EB5E840055 +:1054D0003E07EAF8FC80FC4084003C0FFB873C0F51 +:1054E000FB4E4473F04A449000553C6DFB87CE0E52 +:1054F00010938000490034E9840180208046806652 +:10550000808080A6490015B2D5F1FCC0FC2084C083 +:105510003C6FFB8849FFFFE13C0DFB1744127ADC2E +:1055200049FFF2E9840149FFF215447000553C6FD0 +:10553000FB4E4463F04A2E002A8F3C1DFB888E01EF +:10554000E220E80DAFF0490034C08401844080209F +:105550008062808080A249001589D5EE84003C0FCE +:10556000FB4E4463F04A4470005549FFF1E6C8051C +:10557000AFF0490034AAD5FAFCA0FC20490016A9D6 +:105580003C0DFB1744127ADC49FFF2B5840149FF58 +:10559000F1E184003C0FFB4E4463F4034473F04A92 +:1055A000A6305A08010844000055AE384900348D31 +:1055B000D5F84900168EFCA0FC003C0DFB59A60155 +:1055C000540000FD5A0809112E07EAF55A00040597 +:1055D00084053E07EAF549000F71E602E905490036 +:1055E0000F6D8E02D50284003C0E00BA84203C0D63 +:1055F000FB594900177D3C0DFB59842AAE4149FFF8 +:10560000F41049FFFFBC84013E0002F984003E070C +:10561000EAF849000F29840E49001544FC80FC403B +:10562000C006441003E8FE0C49000F4C84214400DE +:105630004F00804180614900077144600E5D4473F2 +:10564000F04A44900055490007C4C0068EC1C60404 +:1056500010938000D5F9490007BCC00D84004900B3 +:1056600007814463F04A44700055490007B2C00303 +:10567000AFF0D5FCFCC00000FC40812080C2490096 +:10568000152280E049FFFE325004FFFFE60A4EF289 +:10569000018044F055A03807810140F03C00DD0F47 +:1056A0001400560012010602880028023802840203 +:1056B0006C02BA02840EAE318405AE308400100351 +:1056C0008050449000554473F04A490007825A08BC +:1056D000020510938000D5FA4900077BC008842199 +:1056E00044005AF08041806149000718440000914D +:1056F00049FFFF97D50F840EAE318406AE3084008B +:105700001003805080A750038041843F181280010D +:10571000D8FE80068421490016EB84208402804153 +:105720008461808148000132852184E03E90022C12 +:1057300049FFF2E33E77EB50109300002E07EB5049 +:1057400084812E17EB4644527ADC2E27EB0B2E3742 +:10575000EB2C49FFF06F441293A044027ADC49FF1E +:10576000F31084003E7002F93C0E00BA4900244553 +:105770002E1002FC5A00A103C90484013E07EB1B52 +:105780005A10010884013E07FB38840049000A01D1 +:105790003C1DFB678402AE083C1DFB4DAE08A631E4 +:1057A0008E08E6044EF200F580064900156D4800AB +:1057B00000F0440218CCFA23AE40441218CD440F36 +:1057C000FFAAAE08441218CEAE08441218CFAE0895 +:1057D0003C1DFB4D84013E00022D8402AE08AE301C +:1057E0008400490009E7A6319E43E624E90A5A00ED +:1057F0000D095A080E09490017718400490016293D +:105800008408D5028409AE318400100380503E071D +:10581000EB3049FFF2723C0DFB5949FFF302840360 +:105820003E07EAD14463F04A4900120D4470005526 +:10583000490006CF5A080204AFF0D5FB490006C95B +:10584000C008842144005AF0804180614900066606 +:1058500084003E0002F984003C0E00BA490023CDCA +:105860002E1002FC5A00A103C90484013E07EB1B61 +:105870005A10010884013E07FB3884004900098959 +:105880003C0DFB5C5A0004045A080708844084025B +:1058900084218062848FD57984408402FA258062D5 +:1058A000848F84A1D57384203C0DFB5949001620B8 +:1058B000840AAE318403AE303C0DFB5949FFF2B18E +:1058C000840149FFE0A2D56484003E07EB503E0707 +:1058D000EB2C49FFF16ED53484003E07EB50840178 +:1058E0003E07EB2C49FFF10B2E07EB5084812E175E +:1058F000EB4644527ADC2E27EB0B2E37EB2C49FF7C +:10590000EF994400004049FFF12CD542440000A02B +:10591000441000A1844184604900060084003E07D1 +:10592000EB50D50C440000A08020844184604900E5 +:1059300005F584003E07EB5084013E07EB0B2E0774 +:10594000EB5084812E17EB4644527ADC2E27EB0B6A +:105950002E37EB2C49FFEF6ED51B840EAE3184063B +:10596000AE3080A750038041843F18128001D8FEDA +:1059700080068421490015BC8400842084611003C2 +:10598000805080418402808380A14900136FFCC055 +:10599000FC41A6818E43E6494EF202F780E380C0C7 +:1059A00044F058B03827890140F13C004A003C00DF +:1059B00012004A01D605B802D6058403D4039C041C +:1059C00060053C0DFB5C5A08091E490006025A0896 +:1059D000021A440278A7441279504900152B440258 +:1059E00078C4441278CB49001513840CAE313C0DB9 +:1059F000FB5984204900157C8403AE31FA003C0F2A +:105A0000FB5C000380205A000104480002BE2E0007 +:105A10002AFAC80984003C0FFB4E4493F04A44A084 +:105A20000055D52A5A0001092E002AFA5A0001040D +:105A3000480002ABD5260493800449001783E2098D +:105A4000E8EAD5F33C0DFB4DA6005A0801EF10A47F +:105A500080004900323A2E07EB245A08010644021E +:105A600079584900146684408401842A80628080C9 +:105A700080A2490012FB3C0DFB67A600C0E4D5D50F +:105A8000049380044900175EE209E90EA63A5A0021 +:105A900001092E07EAE95A00010448000276D50BF5 +:105AA0002E000224C8F749FFDFA7C8F42E07EABA80 +:105AB0005A0801F12E07EB465A00041D84003C0FE2 +:105AC000FB4E4473F04A449000553C0DFB67A60022 +:105AD000C80610938000490031F8D5F83C0DFB59F9 +:105AE0008420490015058404AE313C0DFB5949FF63 +:105AF000F19849FFFC97480000AA2E07EAF5C00379 +:105B00005A08032D80068420490014F2840149FFBD +:105B1000EF214473F04A4490005549FFEF0EC8044A +:105B200010938000D5FB4900166A2E07EAF55A004B +:105B3000041B84213C0DFB59490014DA84014900FF +:105B400016C0490016D5F08184408402F1018461B9 +:105B5000808280A24900128AD5065A080405840171 +:105B60003E07EAF5800684E02E17EB4A3E77EAF816 +:105B7000490018452E07EAE95A08010D440FFFAA0B +:105B80003E07EB253C0DFB4D3E77EB2EAFC04800AA +:105B900001FC2E07EB2E5A080104480000C92E070D +:105BA000EAF55A080404480000C33C73F5CCA6315A +:105BB000490016B4E2E0E903490015D43C73F5CB83 +:105BC000A631490016B5E2E0E9042E0002DAC0066B +:105BD0003C03F5CB5CF00168E939440FFFAA3E07AE +:105BE000EB258406AE313C0DFB5949FFF11A8401C7 +:105BF0003E07EAF884003C0BF5CB3C0DFB5C5A08F1 +:105C00000A0644029514842BD5065A080B07440251 +:105C10009514842A490012F92E67EB0B97B05A604D +:105C20000104480001B280263C0DFB594900146074 +:105C30004900165EF081F101840284408066808212 +:105C400080A249001213480001A084213C0DFB5999 +:105C50004900144E84014900163449001649F08168 +:105C6000F10184028440D55C2E97EAF85A98012A03 +:105C700049FFFC4E2E0002DA5A080117490004A918 +:105C80005A0802134900307A80E03E07EB2E5A088A +:105C9000010C840049000DA584003E0002273E70DF +:105CA00002243E0002DA3C0DFB59842149001420F5 +:105CB0008406AE313C0DFB5949FFF0B34800013476 +:105CC0005A900204480001613C0DFB6710900000EF +:105CD0003C0DFB4D10900000A608C8242E07EB2EAB +:105CE000C82100018026C81E2E77EB3BCF1B840401 +:105CF000AE313C0DFB5949FFF0943C1DFB6784011C +:105D00003C7FFB17AE083C1DFB4DAE0884014900EB +:105D100015D8490015EDF081F101800980478461B3 +:105D2000D58F3C0DFB598420490013E249FFFBAAA3 +:105D30004800012B3C0DFB5C5A08061384003E070B +:105D4000EAF53E07EAF849000444C04E490012E172 +:105D50003C0DFB270200001149FFFC63D5455A00AA +:105D6000090448000112490004345A0002044800A2 +:105D7000010C3C0DFB598420490013BA8403AE3159 +:105D8000480001032E97EAF54E93001D8029490033 +:105D900013AF490014C1490015323C0DFB4D84215D +:105DA000AE402E07EAF55A000413490015B2F081FF +:105DB00084618402F1018049808380A949001156E1 +:105DC000D5065A98040584013E07EAF580062E1789 +:105DD000EB4A490017142E07EB2E5A0001062E0736 +:105DE000EAF55A08040C49FFFBE93C1DFB4D840110 +:105DF0003E07EAF4AE08480000C83C93F5CCA63153 +:105E00004900158CE320E903490014AC3C93F5CB21 +:105E1000A6314900158DE320E91285203C0DFB5980 +:105E200014938004802949001363840BAE318401EC +:105E30003E07EAF83C9BF5CB480000A749001569EE +:105E4000F081F1018402844048000099A6005A08BC +:105E5000024CA608C8042E07EB2EC0042E07EAF455 +:105E6000C83B0493800449000B29E320E8052E0772 +:105E7000EAF44E03008A84003C0FFB4E4493F04A40 +:105E800044A000553C0DFB67A600C80610A4800086 +:105E90004900301BD5F82E07EAF55A08050BA63144 +:105EA0004900153C3C0BF5CC84013E07EAF5D504CE +:105EB00084003C0BF5CC852084093C9BF5CBAE31AE +:105EC0003C0DFB5984C049FFEFAC10938021A9BC65 +:105ED0003E97EAF8D54D8400A83C84011003802148 +:105EE00049000AC2D5513C0DFB5C5A08070F8409D2 +:105EF000AE3149FFFB633C1DFB4D84013E07EAF4D4 +:105F0000AE08FA003C0FFB5C840010038021D53CF6 +:105F10002E07EAF85A0801103C0DFB5949FFEF81A2 +:105F200049FFFB2D84023E07EAF83C0DFB4D84201F +:105F3000AE40D52A5A08022984003E07EAF8A6088E +:105F4000C8042E07EB2EC0042E07EAF4C81B8409F0 +:105F5000AE313C0DFB5949FFEF643C0DFB598421E8 +:105F6000490012C684C0840010038021A9BC4900E6 +:105F700014D0F081F101840280468461808348FF5F +:105F8000FE6149FFFB1BFCC14423F242AE104403F7 +:105F9000F243AE40DD9E0000E605E85B4423F24894 +:105FA0004413F24944F05EB43807800040F03C00EE +:105FB0004A003C0006364C506A008401AE10844210 +:105FC000AE884413F24A8464AE084413F24BAE88A0 +:105FD0004413F24CAEC84413F24DAE884413F24E53 +:105FE000AE084413F24FAE88D531841FAE10AE0810 +:105FF0004413F24A8448AE084413F24BAE08D51A53 +:106000008401D5028402AE10AE084413F24AAE08F1 +:106010004413F24BAE084413F24CAE08D50E840084 +:10602000AE10AE084413F24A8441AE084413F24B5A +:10603000AE084413F24CAE884413F24DAE0844133C +:10604000F24EAE084413F24FAE084413F250AE08BD +:10605000DD9E92004433F2514443F241A698AE6073 +:10606000541100E0FE0FAE18DD9E4433F25296014B +:10607000AC184403F2549649AC404403F25696914E +:10608000AC80DD9E4403F2408421AE404413F04ACC +:1060900044200055AE88A6405A1001FFDD9E4413EF +:1060A000F258A448AC404413F25AA448AC414413FB +:1060B000F25CA448AC424413F25EA448AC434413DF +:1060C000F260A64810100008DD9EFC2180E08002EE +:1060D00080C1F38149FFFF624403F24497F9ADC0E8 +:1060E0004403F24697B1AD8049FFFFCEF00149FF6E +:1060F000FFD8FCA14403F1408421AE404413F04A90 +:1061000044200055AE88A6405A1001FFDD9E44028F +:106110001BD83C0FFB1C4403F142441FFFD8AE4088 +:106120004403F143FA2BAE40DD9E3C1DFB1DA682CD +:106130001020800CA6831020800DA680A6011020C0 +:10614000800E1000800FDD9E3C1DFB1DA6821020DE +:106150008010A68310208011A680A6011020801236 +:1061600010008013DD9E3C1DFB1DA68210208014B4 +:10617000A68310208015A680A6011020801610008E +:106180008017DD9EFC01B63FF28149FFFFD0B41FAE +:1061900049FFFFDCF00149FFFFE8FC813C1DFF687F +:1061A0005410802FFE0F3C1DFB1D3C0FFF6810009C +:1061B000800ADD9E3C1DFF68541080F0FE0F3C1DE0 +:1061C000FB1D3C0FFF681000800ADD9E3C1DFF6830 +:1061D000541080F05A1810053C1DFB1DAC0CDD9EC0 +:1061E000FC02F1813C1DFB1C84C0F383AD8BF28269 +:1061F0003C1FFB1D49FFFFD4F102F001F20349FFF0 +:10620000FFC3800649FFFFE43C0DFB1D44107FFFE8 +:106210001210000C441F80001210000DFC82FC4084 +:1062200081408401812180E280C349FFFFC53C4D4C +:10623000FB1D4403F140842112A2000012920001D0 +:10624000ADE21062000BAE40FCC0FC408120840235 +:1062500080E180C249FFFFB03C3DFB1D84008421EA +:10626000AC194403F14012918000ADDA1061800B4B +:10627000AE40FCC0FC029690B61F102F800884012F +:10628000102F800B102F800C102F800FB083806296 +:10629000F181100F800A100F8009100F800E100F6F +:1062A000800DB042FA0049FFFF9DB41FF101844008 +:1062B00049FFFFCD4403F04A44100055AE4044135B +:1062C000F140A6085A0001FFFC82FC02B61F8401BF +:1062D000100F800E2E002A6FF181100F800C100F0E +:1062E000800F2E002A70B04380418061100F800D16 +:1062F000FA0049FFFF77B41FF101844049FFFFA76F +:106300004403F04A44100055AE404413F140A6083F +:106310005A0001FFFC82FC03B61F8401100F801697 +:10632000FA02F181100F8014B045100F8017FA1493 +:10633000F282F38380418061100F8015840049FF51 +:10634000FF51B41FF101F202F30349FFFF6A440356 +:10635000F04A44100055AE404413F140A6085A00DC +:1063600001FFFC83FC2084003C0FFB4E4463F403DC +:106370004473F04AA6305A08010844000055AE386C +:1063800049002DA3D5F84403F3808421AE40441383 +:10639000F04A44200055AE88A6405A1001FFFCA0E8 +:1063A0004453F381944AA7289407544200F0FEA76F +:1063B000FE579648FE0F9600AE284403F38496D805 +:1063C000AEC0DD9EC8044403F386D5034403F387BF +:1063D000A6009600DD9E4413F3868400AE084413A5 +:1063E000F387AE08DD9E4403F3C98421AE40DD9EF1 +:1063F0004413F280A60858000001AE08DD9E442335 +:10640000F2809405A650FE479648AE50DD9E4402A9 +:10641000192744121926A600A64840002008FE0F9E +:10642000DD9E4402192944121928A600A6484000FE +:106430002008FE0F50F066D45CF7805AE903440050 +:10644000192CDD9E44021924A60092019606DD9EB9 +:1064500044021924A60092029606DD9E44021925E4 +:10646000A600DD9E4412192AA6089600C00EA608B2 +:1064700096005A00010BA60896005A000207A608CB +:1064800096005A0003038400DD9E4412192B9600E7 +:10649000AE08DD9EFC20002000094443F280968671 +:1064A00094D1A6A00010000A542100FDFE9F3C4F8D +:1064B000FAFD9646AEA0948AA66080E0541080FB58 +:1064C000FE57AE60A4404403F28480C4AC40A47A7A +:1064D0004403F286AC40001380084403F283AE40CC +:1064E0000003800B49FFFF8D49FFFF844413F04AEE +:1064F00044200055A6309606C003AE88D5FC441350 +:10650000F2813C1FFB0BA60892029606C0EAA60881 +:1065100092039606C0E6FCA0FC0044621924AE700B +:106520004412984CB6018401100080081000800BC2 +:106530008001A989102080091030800A49FFFFAC32 +:10654000A630FC80FC008441842080624400B100BD +:1065500049FFFFE484003C0FFB763E00022AFC80EA +:10656000C808441218C1A6088C019600AE08D50FC1 +:10657000442218C2A6508C219648AE505A080108F1 +:106580004413F060A60858000004D5064413F060D8 +:10659000A608540000FBAE08DD9E4403F061A6008F +:1065A00092029606DD9E4403F061A6009207DD9EEE +:1065B0004413F0679600AE08DD9E4413F068960021 +:1065C000AE08DD9E4413F06A9600AE08DD9EFC0026 +:1065D00049FFFFEBC80749FFFFE25A0001068401AB +:1065E000D5048400D5028402FC809404FE479608FA +:1065F0004423F06D4413F077443FFFC0AED0AE08A3 +:10660000DD9E4403F06D8420AE40DD9E9404FE4781 +:1066100096084413F481AE08DD9E4413F4839680FB +:10662000AE8892084413F4849600AE08DD9E4413AD +:10663000F4859680AE8892084413F4869600AE08DE +:10664000DD9E4413F4879680AE8892084413F48844 +:106650009600AE08DD9E4413F4899600AE08DD9ED8 +:106660004403F48244200055A640541080FE581084 +:106670008001AE404413F04AAE88A6409646C9FE5B +:10668000DD9EFC004463F00EA43054000100C009FC +:10669000441218C0A6088C019600AE088408D57E66 +:1066A000A430960EC86AA430961EC009441218BFC2 +:1066B000A6088C019600AE088403D570A430961607 +:1066C000C009441218BEA6088C019600AE088402C8 +:1066D000D565A4309626C009441218BDA6088C01C1 +:1066E0009600AE088404D55AA4309606C803FA0072 +:1066F000D55549002BFFA4309636C841A430962EBC +:10670000C840A430963EC83FA43054000200C00BDD +:106710004403F063A6409646C138A640541080FE5C +:10672000AE40D5334403F00EA44054108400C92F6A +:10673000A44054108800C92DA44054109000C92BC7 +:10674000A4405410A000922DC928A48054214000D8 +:10675000C20C2E00022BC80584013E00022BD5037B +:106760003E10022B840ED51AA400920FC0C18401E2 +:106770003E00022A840FD5128401D5108406D50E5E +:106780008405D50C8407D50A8409D508840AD50662 +:10679000840BD504840CD502840D4413F00E844080 +:1067A000AC88FC804403F3228421AE40DD9E441378 +:1067B000F323AE08DD9E4403F323A600DD9EFC0018 +:1067C0004463F540B6064403F544B6204403F54857 +:1067D000B6404403F54CB6604403F550B68044031C +:1067E000F554B6A0F1044403F558B620F10544036E +:1067F000F55CB620FC80FC004413F5024403F5046C +:106800003C0FFB153C1FFB16A48858210040AC88A8 +:10681000A44058108040AC408400802080408060BC +:1068200049000C79FC80FC004413F5023C1FFB1668 +:106830004413F5043C1FFB154413F5103C1FFB18D3 +:106840004413F5113C1FFB114413F5123C1FFB12BE +:106850004413F51380C03C1FFB135A08027C440309 +:10686000F5228420AE404403F523842FAE40441328 +:10687000F3448403AE084413F5008441AE88441306 +:10688000F501AE08840080208040806049000C4300 +:106890003C2DFB16441FFFBFA41058000022FE0E23 +:1068A000AC103C0DFB15A480FE56AC40840080204B +:1068B0008040806049000C2F44000D024900060210 +:1068C0003C1DFB15A40858000022AC088400802061 +:1068D0008040806049000C1F44001F38490005F2C9 +:1068E0003C0DFB12A64058108001AE408400802071 +:1068F0008040806049000C0F440007CE490005E24B +:106900003C0DFB18A64058108001AE40840080204A +:106910008040806049000BFF3C1DFB16A408580016 +:106920000004AC083C0DFB15A48058210004AC8089 +:10693000A48858210008AC88A44058108008AC40B6 +:10694000840080208040806049000BE544001A04E8 +:10695000D567C8694413F522844FAE084413F52364 +:106960008461AE884423F3448423AE504423F5006D +:10697000AED04423F5018060AE50802080404900B5 +:106980000BCA3C5DFB16440FFEFF8046A468806680 +:10699000FE46AC683C4DFB15A460FE0EAC20A4681E +:1069A000440FFFEFFE46AC68A460FE0EAC20A428A6 +:1069B000802658000002AC28A42058000002AC2019 +:1069C000A42858000020AC28A42058000020AC20A7 +:1069D000A42858000004AC28A42058000004AC20CF +:1069E000A42858000008AC28A42058000008AC20B7 +:1069F000800649000B903C1DFB183C0DFB12A6883D +:106A000058210001AE88A64058108001AE40840095 +:106A100080208040806049000B7E4400027F490056 +:106A20000551D57E5A08017D4403F5228420AE40ED +:106A30004403F523842AAE404403F3448422AE4049 +:106A40003C2DFB18841EA650FE46AE503C1DFB128A +:106A5000A688FE16AE088400802080408060490031 +:106A60000B5A3C1DFB16A40858000100AC083C0D55 +:106A7000FB15A48058210100AC80A4885821001087 +:106A8000AC88A48058210010AC80A4C8845DFED6D8 +:106A9000ACC8A4C0FE9EAC80A4C8442FFFDFFED6C5 +:106AA000ACC8A4C0FE9EAC80A4C8845BFED6ACC8B3 +:106AB000A4C0FE9EAC80A4C88457FED6ACC8A44037 +:106AC000FE8EAC80840080208040806049000B23D3 +:106AD0003C0DFB59A6415A180E17A6005A0805147A +:106AE0003C1DFB18A60858000003AE083C1DFB1215 +:106AF000A60858000003AE08840080208040806013 +:106B000049000B094413F5008400AE084413F50155 +:106B1000AE08840080208040806049000AFCFC8030 +:106B2000FC004433F5104423F51280203C3FFB1851 +:106B30003C2FFB12C80CA71858420001AF18A6D072 +:106B400058318001AED080408060D50E5A08010FC8 +:106B5000A658841EFE46AE58A650FE0EAE10840007 +:106B600080208040806049000AD6FC80461080006A +:106B70006413240364230402461F7FFF50108FFF19 +:106B8000FE5640006C08FE0F64030403DD9E4610B1 +:106B900008006413240364230402461FF7FF501007 +:106BA0008FFFFE5640005C08FE0F64030403DD9E69 +:106BB000441100006413240364230402441EFFFFF5 +:106BC000FE5640004008FE0F64030403DD9E44109F +:106BD00080006413240364230402441F7FFFFE56D5 +:106BE00040003C08FE0F64030403DD9EFC003C1DD6 +:106BF000FB16A40858000040AC083C1DFB15A40877 +:106C000058000040AC08840080208040806049002B +:106C10000A82FC80FC003C2DFB16440FFFBFA450F1 +:106C2000FE46AC503C1DFB15A488FE16AC08840043 +:106C300080208040806049000A6EFC80FC2080C17A +:106C40004413F04080E2A6C84423F00E5431801C67 +:106C5000FEC7848096D8AD10AEC85A0802058424B9 +:106C6000641304034413F04A44200055AE885A08C4 +:106C7000020749000101C8FE640304034413F0DA6B +:106C800097B0A608540000F0402380044403F0EDC0 +:106C90009690AE88AF804403F04144100055AE405A +:106CA00040000009400000094000000940000009C0 +:106CB00040000009FCA0944D4423F042FE0F9600D2 +:106CC000A6D0AE10DD9E96069404965FFE47440360 +:106CD000F043AE40DD9E4413F044AC08DD9E441307 +:106CE000F046AE08DD9E4433F2009601AC18440332 +:106CF000F2029649AC404403F2049691AC80DD9ECA +:106D00004403F20A44200055A640541080FE581057 +:106D10008001AE404413F04AAE88A6409646C9FEB4 +:106D2000DD9E4423F2069600AE104403F207964817 +:106D3000AE40DD9E4403F20BA600DD9E4413F20834 +:106D4000AC08DD9E4423F20A9401A6509646FE4705 +:106D50009648AE50DD9E0000E608E82544F06C6CD5 +:106D60003807800040F03C004A003C00080E141A2E +:106D700020262C324403F20CD5154403F20ED51212 +:106D80004403F210D50F4403F212D50C4403F2145D +:106D9000D5094403F216D5064403F218D50344037B +:106DA000F21AAE40DD9E9200E608E82544F06CBC85 +:106DB0003807800040F03C004A003C00080E141ADE +:106DC00020262C324403F20DD5154403F20FD512C0 +:106DD0004403F211D50F4403F213D50C4403F2150A +:106DE000D5094403F217D5064403F219D503440329 +:106DF000F21BAE40DD9E92003C0DFAF7B400920308 +:106E00009617DD9E4403F0C4A600DD9E4413F0C433 +:106E10009600AE08DD9E4403F0C3A600DD9E441339 +:106E2000F0C39600AE08DD9E4433F0D44423F0D680 +:106E3000A458A61040F0A00840F7800444021BFFAD +:106E4000E00FE80BA418A65040002008FE0F44F203 +:106E50001C4240003C07DD9E8400DD9E44021C0075 +:106E6000DD9E4413F4038440AE884413F0C69600BC +:106E7000AE08DD9E4403F0F4A600DD9E4403F0F767 +:106E8000A600DD9E4413F0F79600AE08DD9E440395 +:106E9000F0F6A600DD9E4413F0F69600AE08DD9EE7 +:106EA0004423F0509617A650541080F8FE47AE5079 +:106EB000DD9E4423F0509617A65094045410808F02 +:106EC000FE47AE50DD9E4413F050A60858000080E7 +:106ED000AE08DD9E4413F050A6089637AE08DD9E3E +:106EE0004413F051A60858000001AE08DD9EFC00D6 +:106EF000840749FFFFD74403F04C8420AE40840749 +:106F000049FFFFD94403F04E8421AE40FC80C80401 +:106F100044120000D503441230003C1FFB03C80498 +:106F200044120510D503441235103C1FFB02C8045F +:106F3000441206DCD503441236DC3C1FFAFBC804BD +:106F400044020BF0D50344023BF03C0FFAFADD9EFD +:106F500084003C0FFB774403F1808421AE4044134E +:106F6000F04A44200055AE88A6405A1001FFDD9E2D +:106F7000C8283C53F6064443F1863C3DFAFB3C2DC1 +:106F8000FB083C1DFB003C0DFB0AAD604443F18E49 +:106F900096D9ACE04433F1889691AC984423F18AB9 +:106FA0009649AC504413F18C9601AC082E202A6F00 +:106FB0004403F1842E102A70AE804403F185AE4064 +:106FC000DD9EFC404433F1824473F1813C3FFB0978 +:106FD0003C7FFAFEA740848140629002A758855EFC +:106FE0004052A802FF77AF58A741853DFF66406237 +:106FF000900CA7584052A402FF77AF58A742FF66F3 +:1070000095AAA758545280FBFF77AF58A743FF6655 +:1070100095ABA758545280F7FF77AF58A744FF6647 +:1070200095ACA758545280EFFF77AF58A745FF663D +:1070300095ADA758545280DFFF77AF58A606954606 +:10704000A618962FFE2FAE18A610A6F8FE264031E1 +:10705000A80240A1800410A38000A611FF0694217D +:10706000544500FF40422402FF07AF380020800E45 +:107070004403F183AE80A4894403F190AC80A48AD8 +:107080004403F192AC80A68E4403F194AE800220BA +:1070900080084403F196AC80A48E4403F198AC8040 +:1070A000002080084403F19EAE800020800B440342 +:1070B000F195AE800020800A4403F19FAE8000204D +:1070C00080124403F1A0AE800210800A4403F1A2B2 +:1070D000AC40FCC04413F19AA448AC404413F19C6A +:1070E000A448AC414413F1A4A448AC424413F1A613 +:1070F000A448AC434413F1A8A448AC444413F1AAF7 +:10710000A448AC454413F00AA64896571010000C4A +:10711000DD9E3C0DFF69A600DD9EFC00A6488E2486 +:10712000E622E813C80444120000D50344123000DC +:107130003C1FFAF4C80444123000D5034412000086 +:107140003C1FFAF2C016D512C80444123000D50311 +:10715000441200003C1FFAF4C80444120000D50396 +:10716000441230003C1FFAF2C80444020000D50368 +:10717000440230003C0FFAF8FC8084003C0FFB6BAB +:107180004403F1C08421AE40DD9EFC005A0002059C +:107190005A000318C82E2E202A6F4403F1C22E1065 +:1071A0002A70AE804403F1C34423F1C4AE403C1DB9 +:1071B000FAF23C33F5E83C0DFAF89649ACD0D5121A +:1071C0002E202A6F4403F1C22E102A70AE80440391 +:1071D000F1C34423F1C4AE403C13F5E43C0DFAF88E +:1071E000AC504423F1C69601AC504413F1C8AC082E +:1071F000FC80FC202E1002FD80E03C6DFA71C10283 +:10720000840349FFFFC43C1DFA715A100F16C703CF +:107210005A78020380C14403F1C197B0AF8049FF9F +:10722000FFAE4403F04A44100055AE404413F1C091 +:10723000A6085A0001FFFCA0C0045A000209DD9E06 +:107240003C0DFF69A6003C0FFA71DD9E3C1FFA71F0 +:10725000DD9EFC4380E0840080C181222E102BF44F +:107260004422B8008060E201E80699028C011032E5 +:10727000018CD5FAA03D8029FA4E503F801749FF76 +:10728000C961000F80178420F0813C4DFB29841FC9 +:1072900080A1F201E2A2E8260434800194A93831E9 +:1072A0009501DB1E04A4800404348002884A008116 +:1072B000000138319501E702E91300A200028F4274 +:1072C000E10AE80E00A10000E742E90AA6A38E4207 +:1072D000E142E806E2234011BC1B4002BC1B8CA12A +:1072E000D5D95A07FF1B50348018B443944238A1B3 +:1072F0000202A09938510202A09A38310202C375E5 +:10730000002200320002003342250824FE2C41E115 +:107310000FD740300C77D56A846083C380438143A4 +:10732000D50F4E220090000200324205002440A0FA +:107330000957000200334204002440200857A630B9 +:107340005A00010B2E07EB40C004F0015A00010562 +:107350004410003CD502FA38400F28019A9AFE04E6 +:1073600042010873FE4CE22081403C0FFB60001399 +:107370000030E819F001E603E810C90F2E000310F1 +:10738000C80C2E07EB3D5A080109442000783E172F +:10739000EB373E27FDA8AE30A6305A080113440053 +:1073A0000078D50B2E07EB40C00C2E07EB37C00939 +:1073B0002E07FDA8C0058E013E07FDA8D502AE3000 +:1073C000C1038400AE30A6305A0801405CF500C904 +:1073D0002E07EB19E905E605E8388C01D503C03521 +:1073E0008E013E07EB19D53183C304048005844028 +:1073F00088208102A60BA74AF0828142F002E205B2 +:10740000E99100908001A608149F8003049F8003E7 +:10741000E320E9160092000281E042F2A473409753 +:10742000840804F38005892F029480004094801121 +:10743000E53EE904894089058C418C01D5E88CA1A1 +:10744000D5DE814248FFFF7DFCC33C1DFF6DA004DB +:10745000A44CE201E90684003E0002F98402DD9EAC +:107460008400DD9EFC0044027AF48420442FFFAAAD +:10747000AE81AE40AE423E27E9CC840084413E1747 +:10748000FDE33C0FFF763C0FFF753E07FDE23C0B32 +:10749000FEEE3C2FFA723E17FDE13C0BFEEF3E077D +:1074A000FDE43E07FDBF3E07FDBE3E07FDBD3E07B6 +:1074B000FDE03E07FDBCFC803C0DFF6DA404DD9E9D +:1074C000EFF8F081F0018E01F081F001C002D5FBF0 +:1074D000EC08DD9E5A180239FC004617FFFF806059 +:1074E00050F08FFF84A0B4435A280221808084C0CA +:1074F000D618B4445A28021622118004222200040D +:107500009A8A4E240003FE922211800522F2000581 +:107510008A2F4E140003FE4AFE4C4211087381E18B +:107520008CC1504200FC5A680AE58CA1503180FCA5 +:107530005A580ADB44031703E00F8401E802840071 +:107540003E00030AFC8084003E00030ADD9EFC022C +:10755000F382F483B63FF28149FFFD0CB41FF101C1 +:10756000F20249FFFD3049FFFCF5F00349FFFDB48D +:10757000FC82FC40F609227F8016C87E0093000C36 +:107580001092800E02930001129280010293000279 +:10759000129280020093000110928006A4D82E97C8 +:1075A000EB5612328008A4F5ACEEA4F3ACEC003339 +:1075B00000091032800B003300081032800A4E930D +:1075C000000D2E37EB44C3068E613E37EB44A4F525 +:1075D000D502FA78ACEED506A4F5ACEE846A3E3757 +:1075E000EB44A6D15A380113F30A02A18001846545 +:1075F000E54AE90450357FFB96D9ACE9ACEAFA7864 +:10760000ACEE846112A28008AEEE84603E37EAFFE1 +:10761000E7264430003C3E37EB01E90AFA7D3E376D +:10762000EB0184613E37EAFFFA7D123280082E308A +:107630000308C3038460AEEEF30822918004FEFACF +:10764000E123E802ADE92E37EB3B5A380105A4F7F8 +:10765000123280082E3002F95A380106F30CA4DAEF +:10766000123280082E30022FCB052E37EB4F5A38BE +:1076700001048460AEEEA6C85A3802088461AEE404 +:10768000C8068403AE08D5038400AE24001100228E +:1076900084005A18010710010022AE62AE63D503C0 +:1076A000AE22AE23FCC02E000308C8192E0002CF64 +:1076B000C8163C1004C2C1133C0804C23C08056A49 +:1076C00044521634441218BC18028001D9FE2E0010 +:1076D00002FF8C013E0002FF8402DD9E8401DD9EDC +:1076E000FC0084404430FFFFA8C9B641B460444068 +:1076F0000510800284A098A88843B4C1A4909693F2 +:10770000E2C2E802B641A189E246E802A8895052E5 +:107710008024DCF28C025A0824EFFC80441000FC28 +:10772000420184733C1C01B404200009444291408E +:1077300038208A02441001F4FE540220002C40102C +:107740008836002000209686C20438120E0AD50C16 +:1077500038220E0284A5FEAC84A3422094734021FB +:10776000140D38220E0A1210000FDD9EE625E827C0 +:10777000FC013C24038B4412945090419691503F5D +:107780008007A00549FFC6DE84A0002F80073C3C8F +:1077900001AD3C4C01AE8025E2A2E80C3801950118 +:1077A000D80738021501E2014000BC1B80208CA1E3 +:1077B000D5F44400005A40000406FC818400DD9E9C +:1077C0002E17FE0584003E07FE04C10884213E17E3 +:1077D000EB2E3E1002243E07FE058400DD9E3E0790 +:1077E000FE0584003E07FE048400DD9E84003E000A +:1077F0000227DD9E841F3C0FFAAC84003E07FE0585 +:107800003E07FE04DD9EFC438100840081413C0F65 +:10781000FB4E84C0F6813C0DFB2AA603E0C0E87154 +:10782000E4C48400E9029E33F0829C3384E0F08358 +:107830003C0DFB2AA602E0E0E8624403F04A441053 +:107840000055AE40490023413C3DFB2AB448802707 +:10785000A61A42130073381105005A10FF4F044452 +:107860000001381205114E150049E4E487C0E90310 +:1078700051E3FFFDA65BF5038E21E0254012BC1A03 +:107880008E01F1849C7BE0014000BC1AF085F1027E +:10789000F004E001E932801EF505E0A0E92C00913A +:1078A000800281E042F0A4734057840838F13D0023 +:1078B0005AF0FF2038F23D114EF4001C04F500058B +:1078C00088AF3CF003A4A568976BE0AFE91280A7EE +:1078D000425324733851150044FF8000956988A4F1 +:1078E000029280004094BC041292800084A1F58131 +:1078F0008C01D5D38C21D5CD8CE1D59B8CC1D58C79 +:10790000F001C888FCC3FC40A612C0038E01AE1271 +:107910003C9DFB2AA753000480038E01D0038CA159 +:10792000AF53A610C0038E01AE1000048002A75111 +:107930008E01D0038CA1AF512E07EB42E602E90D78 +:107940003C3004C6926196DBE479E9075EF18097EA +:10795000E90544300096D502FA698400A79000A199 +:10796000000180A0E346E926A7D200810003E307D7 +:10797000E91F0044800281E642F39073808F04F097 +:1079800080069521888F02F2000040F78011E06F99 +:10799000E80D02F2000040F78011880F02F20000AB +:1079A00040F78011E0AFE802A5608CE1D5E18CC121 +:1079B000D5DAC506441001F4FE0C40001417FCC0D3 +:1079C000FC42847F3C3FFAAC3C3DFB2BA71B5CF2A6 +:1079D0000042E90444400041AF1BA7185CF200429A +:1079E000E90444400041AF182E5002DA444003E855 +:1079F0005A5001062E5002275A580107A75CA7DDEE +:107A000042929024D505A75BA7D8429290242E37A6 +:107A1000EB0DFFE4C328E665E8212E37EABCE665F6 +:107A2000E8048C613E37EABC2E3002D8C3042E40F5 +:107A30000308CC0484813E47EABB5A3001062E304D +:107A400003085A38010584623E37EABB2E47EABB79 +:107A50002E37EABC88643E37EABB2E37EABB429435 +:107A60008C24FFDCA710CC0484C0480000B68460DE +:107A70003CADFAAC80A3E0A4E80FA1813863150106 +:107A8000DE09A18238631501E26640A2BC1B4033C7 +:107A90003C1B8CA1D5F18102A085F181401508081D +:107AA000882280C08444B0033CAFFAAC490030CC9B +:107AB0008006F101B08349FFFF28E2E0E81F2E07AE +:107AC000EB0D84C0E60BE80784013E07FE043E0090 +:107AD000022784C149FFF57D5A08020A4400007854 +:107AE0003C0801143C0DFB2BA601D505FA083C0807 +:107AF0000114840C3E07FE05D56FE320E8B6442F41 +:107B0000800084204025080400040000E020E80AEA +:107B1000A0F194098803A5404C554003AC808C210A +:107B2000D5F48006F10149FFFE703C9DFAAC04A338 +:107B3000000540148808882AB00384444900308432 +:107B400000340000500500038420E023E82EA0B19B +:107B50003851050196AB4E2400265452FFFF4C5479 +:107B60008022D92000207FFD004F800CE282E903B3 +:107B7000102F800C00207FFE004F800DE282E90371 +:107B8000102F800D00207FFF004F800EE282E9035E +:107B9000102F800EA680004F800FE282E903102F85 +:107BA000800F8C218C04D5D28006F101B08349FF6F +:107BB000FEACE2E04EF2FF5A3C1DFB2B84013E0777 +:107BC000FE04A6493E000227440000783E17FE0549 +:107BD0003C08011484C12E000226C00A84013E071D +:107BE000FE043C0DFB2B84C1A6013E07FE053C00B4 +:107BF00003875CF00065E90984003E0002273E0728 +:107C0000FE043E07FE0584C02E07FE05C00D5A681F +:107C100001053E67FE04D5088E0196003E07FE056D +:107C2000C8033E07FE043C000114C009CE088E01C3 +:107C300096013C080114C8033E6002272E07FE048B +:107C4000FCC22E57EAD22E07EAD13BFFFCBC8C01C6 +:107C5000EFFCD0294403F04A44100055AE402E07F3 +:107C6000EAD12E17EAD12E27EAD1443277009404C4 +:107C7000949488038843944CA00238118402A492FF +:107C8000490021C0440002EE49FFFC1C2E07EAD146 +:107C90008C0196003E07EAD22E07EAD38C019600AB +:107CA0003E07EAD349FFF8B9C00784013C0FFB84C3 +:107CB000840049FFF8B649FFF8A7C00AEC04840124 +:107CC0003C0FFB6F3BFFFC84840048FFF8A1EC04F1 +:107CD0003BFFFC84DD9E84003E07EAD148FFFFB3F2 +:107CE0003BFFFCBCEFFC49FFF4745A00020684031E +:107CF0003E07EAD1D50484043E07EAD1EC043BFFF9 +:107D0000FC8448FFFFA03A6FAABCEFFC81208001F1 +:107D1000490003A88380840340048037549000FF07 +:107D20004402918C548080FF381070005074800C95 +:107D300097F85A10FF1E442291683C03F5C0381191 +:107D4000040049FFDF693C13F5BF44200060421086 +:107D50000873800144120000FE0F84CA3800260216 +:107D6000426418244060180D546303FFD503446037 +:107D700003FF44029174381070005A10FF1E442211 +:107D800091803C03F5C03811040049FFDF453C13E6 +:107D9000F5BF4420006042100873800144120000C7 +:107DA000FE0F842A38001E024214042440A0040D51 +:107DB00054A503FFD50344A003FF803C3C0DFB0406 +:107DC00049FFDF2A838049FFDF2244100060420E12 +:107DD000047344120000FE0F4613FFFF50200060A2 +:107DE00080A050108FFFAA69DAFF846A42340C2405 +:107DF000442003FF40210C0CFE5340A50C0C4063B3 +:107E00000C0CEC04FF8F401504043860260A38106F +:107E10001E0A3A6FAA84DD9E3A6FA8BC3C6DFB0433 +:107E2000449200004063240484E00403000C44A056 +:107E3000003C940792071403000C0413000C460F37 +:107E4000E03F50000FFFFE0E1403000C963849006F +:107E50000309021300128CE1882942102873A08BB9 +:107E60008001441FF03FFE56A8435A7809F13A6F4B +:107E7000A884DD9E84003E07EAD7DD9E3A6F9ABC57 +:107E8000EFFC2E17EAEAE623E9633C3DFB044412CB +:107E9000000002218012FE573C1FFB01B4419247B3 +:107EA00096865A280105B4219677D504B4239223E7 +:107EB0009677442FFE00FE54964984A04440051056 +:107EC000B46088658CA2A49888419691AC98DCF93E +:107ED00049000F6A84003E07EAE63E07EADC3E07F7 +:107EE000EAD43E07EADF3E07EAE3840049FFF640B2 +:107EF0004413F04A442000553C0DFB67A600C8031C +:107F0000AE88D5FB8421804180614400FBA049FFFD +:107F1000F30584418062441000AF44001CA049FF77 +:107F2000F2FD84418062FA284400D9B049FFF2F69C +:107F3000490012942E07EB5084812E17EB464452D1 +:107F40007ADC2E27EB0B2E37EB2C49FFDC738401F8 +:107F5000EC043A6F9A84DD9E5A08040F3BFFFCBC88 +:107F6000EFFC49000F213C0DFB4D8421EC04AE4099 +:107F70003BFFFC84DD9E3C0DFB4D8421AE40DD9E2D +:107F80003C1DFB04463FFC7F464003000220801559 +:107F900044120000FE574650FFF0844C3A6F9C3C60 +:107FA0004210087350318FC7844050420030505205 +:107FB0008FFF466A000AB4015A200206FE2EFE37E1 +:107FC000AA09D504FE1EFE27B6018C4196905A28B8 +:107FD00003F43A6F9C04DD9E3A6F98BC80C12E1763 +:107FE000EAD4C91C5A00FF063E07EAD149FFFE2B1E +:107FF0005A6801154900008CC80944023000441237 +:1080000000003A6F988448FFF16244020000441275 +:1080100030003A6F988448FFF15A3A6F9884DD9E99 +:108020004423F5104413F5125A0801068405AE10D6 +:10803000AE08DD9E3A6F98BC840084C0AF9080602B +:10804000AF8880408020490000663E67EADD3A6FD5 +:108050009884DD9EFC0049FFF316FC804403F04A3F +:1080600044100055AE40DD9EFC03F0818005F38492 +:10807000F485F283F18249FFF2A7F002F10349FF90 +:10808000F61C4403F04A44100055AE40F001F104E0 +:10809000F20549FFF5D5440001F449FFFA13FC83CA +:1080A000FC2084C080E0E2C7E80C8401844080208A +:1080B0008062808080A28CC149FFFFD897B0D5F440 +:1080C000FCA0FC0049FFF6CCFC80FC0049FFF6AEAA +:1080D000FC80FC0049FFF692FC80FC0049FFF26A3C +:1080E000FC80FC004462B8000003000B49FFF26210 +:1080F0004400003249FFF9E60003000B5200000182 +:1081000049FFF25884003E07EABAFC803C0DFB1799 +:10811000DD9EFC0049FFF14649FFF1264403F04A89 +:1081200044100055AE404413F380A6085A0001FFE6 +:1081300084003C0FFB4E4463F380840049FFF1440C +:108140005A08011149FFF14949FFF10E4403F04A71 +:1081500044100055AE4049001EB8A6305A0001FF39 +:10816000D5ED840149FFF1305A0001EEFC80FC009E +:1081700049FFF864FC8044026200DD9EC80444228A +:108180000000D50344223000B641C8044422051043 +:10819000D50344223510A889C804442206DCD5033F +:1081A000442236DCA88DC804442236DCD5034422A0 +:1081B00006DCA88EC80444220BF0D50344223BF011 +:1081C000A88FC80444223BF0D50344220BF01420AE +:1081D000800844220BFCA88A44223BFCA88B2E205A +:1081E0002AFC5A280109C80444020520D503440288 +:1081F0003520A80C4402255014008011440262006E +:1082000014008012DD9E5A180A0544123D44D5051B +:108210005A180B0644124BE01410000ADD9EFC01B4 +:108220005A0801153C0C0AB53C1C0AB0B61F3C0CA0 +:108230000AB63C2C0AB1F0813C3C0AB23C0C0AAFB5 +:108240003C4C0AB33C5C0AB4D5133C0C0AAD3C1C54 +:108250000AA8B61F3C0C0AAE3C2C0AA9F0813C3C93 +:108260000AAA3C0C0AA73C4C0AAB3C5C0AAC49FF8E +:10827000F2A8840080208040806049FFF09349FF8D +:10828000F073FC81FC20842CAE4184C084013C6FDF +:10829000FB7B4470005549FFF1653C6FFB4E446326 +:1082A000F04A3C0DFB7BC00C842084618402804139 +:1082B000808380A33C1FFB7B49FFFED8FCA049FFC5 +:1082C000F27C5A0801F3AFF049001DFFD5EB3C0DDD +:1082D000FB17520000013C0FFB17DD9EFC01B61F8F +:1082E0003C0DFB59F181A6015A00060449FFFFF13C +:1082F000B43F3C0DFB1749FFFF433C0DFB1749FF03 +:10830000F6083C0DFB17F10149FFF709FC81FC0061 +:1083100049FFF24A840149FFF24CFC804423F07586 +:108320009606A650541080FEFE0FAE10DD9EA440AF +:108330008C2196495CF08190AC40E90AFC008400F5 +:1083400049FFDB084400006949FFF58DFC80DD9E94 +:10835000FC00A740D90C8CA19768E6A5E90284A08F +:10836000AF40440FFFAA3E07EB25D512441218BCBC +:10837000A6088C019600AE08840049FFDAEB44039E +:10838000F4038420AE404400005549FFF56C4402DC +:1083900018BCA600C00484013E000301FC80A6882E +:1083A0005A28AA0AFC00A680AE888420AE4049FF65 +:1083B000F593FC80DD9EFC003C0DFB5C5A08042715 +:1083C00049FFF54E3C0FFF8349FFF1035A000216A7 +:1083D0002E002AFB5A08011284003E00022E3E079E +:1083E000EB0784003C0BF5D8441278CB440278C4E8 +:1083F00049FFFFD78403D505FA003C0FFB5C8405D9 +:1084000084203C2DFB5949FFE939FC80A6885A207D +:10841000AA10FC00AE80442FFFAAAE88A6005A081E +:10842000010549FFF552D50349FFF556FC80DD9E55 +:108430008440AE808400AC08DD9EFC008420840172 +:1084400049FFF44344000CD549FFF447FC80FC008D +:108450005A08010549FFF3CCD50349FFF3DDFC8041 +:10846000E60DE8323C1DFB0444F0837838078000B9 +:1084700040F03C004A003C000E12161A1E22262A2A +:1084800030363C424800A009D51DA009D50CA009F2 +:10849000D50DA009D50EA009D50FA009D510A00AA9 +:1084A000D511A00A9205D50EA00A920AD50BA00AF2 +:1084B000920FD508A00A9214D505A00A9219D502E8 +:1084C000A00B9627DD9E8400DD9E9200FC004403F5 +:1084D000F5608420AE404403F5618423AE408400FF +:1084E00080208040806049FFFE16FC80FC00442311 +:1084F000F04A44300055AED04433F380A6985A2059 +:1085000001FFC977A6018E01E60E4EF200B344F0DA +:10851000841C3807810140F03C00DD0F1C00540131 +:1085200020007200200072007200360036008C00BD +:108530008C0072002000BC008402D52B2E000AF4AF +:10854000C8074413F516AE084413F517AE088400A7 +:10855000D5682E000AF4C8084413F5168401AE0845 +:108560004413F517AE08840149FFF029840049FF40 +:10857000FE582E07EB125A08011044000E6449FF02 +:10858000F7A1840149FFF3AD840149FFFEC98400CE +:1085900049FFF14BD56E844084018424806280823F +:1085A00080A049FFFD63D5EE840149FFFEB9840038 +:1085B00049FFFE372E07EB125A08010744000E64EC +:1085C00049FFF780D5C5844084018424806280827D +:1085D00080A049FFFD4BD5BC8440840180A084224B +:1085E0008062808249FFFD42840149FFF37AD5D041 +:1085F0005A180138A6018E03E60CE83B44F0850CBE +:108600003807800040F03C004A003C00121A121A61 +:108610001A1E1E0C0C64122C840149FFFE028401F8 +:1086200049FFF280D5268401D5B4840149FFFDF9C4 +:10863000840149FFF0FAD50B840149FFFDF249FF9F +:10864000FF47840149FFF0F149FFF2D2840049FF5E +:10865000FE67840049FFF345840049FFEFB0D50968 +:108660005A180208840149FFF0E0840049FFF339F9 +:10867000FC809200FC002E07EB505A08012E49FFA7 +:10868000EFA8C82A3C0DFB67A6405A1801FFA600B8 +:108690005A0801233C0DFB4DA78097B05A68011D75 +:1086A0003C0DFB598429AE41842049FFFF213C0D3C +:1086B000FB59842AAE413C0DFB1744127ADC49FF7A +:1086C000DA1A3C1DFB678400AE083C1DFB4DAE086A +:1086D000800649FFD93FFC80FC004403F5608423F9 +:1086E000AE404403F5618420AE4084008020804089 +:1086F000806049FFFD10FC80440293DC8420AE4082 +:1087000084213E17ED228420AC4312100008121081 +:108710000011DD9EFC20840149FFD91C84003C0F20 +:10872000FB4E4463F04A4470005549FFD906C8180F +:108730003C0DFB8AC815AFF049001BC72E07EB2480 +:108740005A0801064402795849FFFDF38440840128 +:1087500080208062808280A249FFFC88D5E7FCA04F +:10876000FC403C0DFB59A6015A08042E3C0DFB5C55 +:108770005A080A0A2E07EB365A00014084013E07C8 +:10878000EB36D50A5A080B092E07EB265A0001369C +:1087900084013E07EB262E07EB365A08010D2E0703 +:1087A000EB265A08010984003C0BF5CC3E07EB365A +:1087B0003E07EB263C4DFB373C5C01E73C6C01E897 +:1087C0008440D50584003C0BF5CCD5F5A623940157 +:1087D000E040E813945199E98826A4F8A438A44805 +:1087E0004090080940018409880992228801960175 +:1087F0008C41AC389690D5EBFCC0FC4084003C0B1F +:10880000F5CB3C0BF5CC3E07EB2E3C0DFB59A601FE +:108810005A0804092E07EAF5C8038403D5045A0848 +:10882000030584043E07EAF52E07EAF55A08020517 +:1088300084003E07EAF184003C2DFB373C3C01E814 +:108840003C4C01E63C5C01E7446001F444729568ED +:108850008120A6539449E001E81D944140A2040000 +:108860004081840002A50000882540A5001312A4C1 +:1088700000002EF002DAE90802A4000040A500136F +:1088800012A08000D502AD88389380088C01960034 +:10889000D5E1FCC08400848C9640E628E80498501A +:1088A000A649D5085A18080510418008D505381181 +:1088B0000000381180088C015A0820F0DD9EFC0071 +:1088C0005A0801132E07EB0BC8112E000AE4E60527 +:1088D000E9075A0005058E029600D502840480201F +:1088E00049FFEE85D50349FFEE8EFC802E17EB0B7A +:1088F0003C0DFB27C903A602D502A6032E17EAF8F2 +:108900005A180206E604E9038E039600DD9E3C0D2C +:10891000FB2700000016DD9E5A0804053C03FF09F2 +:10892000DD9E3C0DFB2702000009DD9E5A08040570 +:108930003C03FF08DD9E3C0DFB270200000ADD9E84 +:108940003C0DFB27A400DD9EA400920196065A0070 +:108950000107A608920196065A080109440000641E +:108960003C0BFF0944000168D5083C0DFB27A447D8 +:10897000020000083C1BFF093C0BFF08DD9EFC4089 +:108980002E17EAF65A18020B2E17EAF4C9072E170B +:10899000EAF58E225C108001D50284203C2DFB3745 +:1089A0003C9C01E884A0A6D384C195198E819FD9EF +:1089B00044A2919852800000E0A4E81BD71740F22F +:1089C00084084024BC0050F7800240F4BC00A4900E +:1089D00002F780008A4F9693E00238251509E903D3 +:1089E000E048E8045A18010384C28CA19768D5E5D1 +:1089F0005A18012D92014422919884208122FF026D +:108A0000E027E81638510511E005E80740A08C0082 +:108A100038F12911E00FE908E0A4E807994B385430 +:108A20009511E0A4E80284C28C219648D5EA5A68E0 +:108A3000010E84E084003E67EAF43E7002DA3E678D +:108A4000EB2E49FFF6CE3E7002278006FCC0FC42AA +:108A5000B61F4400FFFFA80B3C0DFB2785001480C8 +:108A60008002A604E610E80552200010548100FFA1 +:108A7000E6118060E902FA6084C096D880068126FB +:108A800044423D4444A295683C5DFB37A76B956921 +:108A9000E1253C5DFB594EF200AAA6A9407484086A +:108AA000540100FD3C5C01E85A0804203C0DFB5CCD +:108AB0005A080A0944024BE099BC38001C01A5B0D1 +:108AC000D5095A080B0A983C44624BE0A40038636D +:108AD0001C019B8697B35A280604FFB297B398AF40 +:108AE000A4108A069601AC103C2C01E688A78847A2 +:108AF000A428A4904200202442010C739204960101 +:108B0000AC283C0C01E83C5C01E9880788A7A480FC +:108B10003C0C01E78807A4009A109603AC283C0D92 +:108B2000FB27A568A405976BFE02E0A0E8312E079D +:108B3000EAF45A0001062E07EAF55A08022A2E0026 +:108B400002DAC81C380524003C5DFB278C01960026 +:108B500038052408A56EE2A0E8213C5C01E83C0C45 +:108B600001E788A78807A5689769AD4084003805A4 +:108B7000240884013E07EAF1D511F483F182F381E0 +:108B800049FFED27F301F102F4035A0802DD38052D +:108B90002400C0048E01380524083C0C01E8A14AD9 +:108BA0008807A480E2A2E803A540A94AA480A14BBB +:108BB000E245E803A400A80BB41FA7413C0DFB2726 +:108BC0005A580904A403D502A4043C5C01E988E5D1 +:108BD000A578976BE005E80484A13E57EB2E50542E +:108BE0008001549280FF48FFFF51A6695A18090678 +:108BF00049FFFEC73E07EAF6FCC2FC408121A641C0 +:108C000080C05074FFFC5A180433840149FFEFD22E +:108C1000840149FFEFDE840149FFEFBBE6E4E93060 +:108C20005A900C2F2E07EAF55A00042B2E07EAE97A +:108C30005A0001272E07EB0B5A08010449FFE44DA7 +:108C40008006842049FFFC54840149FFD6838400B8 +:108C50003C0FFB4E4493F04A44A0005549FFD66DAB +:108C6000C80F10A4800049001930D5F92E17EAF575 +:108C70005A100407842049FFFC3B49FFFD4D3C038B +:108C8000F5CC441298588C013C0BF5CC3C03F5CB49 +:108C90008C013C0BF5CB800649FFFEDB2E0002DA8F +:108CA0005A08012249FFEC955A08021E490018662D +:108CB00084C081203E07EB2E3C6BF5CC5A08010B9B +:108CC000840049FFF58E3E6002273E9002243E60FC +:108CD00002DA2E07EB065A0801073C03F5CB8C1489 +:108CE0003C0BF5CB2E07EB2E5A08010684003E07FD +:108CF000EB30D5132E67EAF45A68011044029858F5 +:108D00003C1015A8442278D04900054F5A080206A5 +:108D10003E67EB2E3E67EB63440FFFAAE6E23E0799 +:108D2000EB25E80B4900084084003E07EB2E840049 +:108D30003C0BF5CB3C0BF5CC2E07EB125A0801048B +:108D40003E07EB2EFCC0FC2084003C0FFB4E44632E +:108D5000F04A447000553C0DFB8AC815AFF049003D +:108D600018B42E07EB245A0801064402795849FF2B +:108D7000FAE08401844080208062808080A249FFE4 +:108D8000F975D5EA3C0DFB598429AE41842149FF90 +:108D9000FBAF3C0DFB59842AAE412E27ED78CA0962 +:108DA000840284298461848380A249FFF95FD50409 +:108DB000840E49FFF977FCA0FC00840084203E0764 +:108DC000FE243E07FE213E07FE203C1BFF0F3C1BFE +:108DD000FF0E3E17FE233E07FE2244100040840093 +:108DE0003E17EAB53E17EAB43C0FFF8CFC80A601A3 +:108DF000C819E622E9043C0003A4D512E664E90E92 +:108E00008E638405FEC4E470E90444000055D5086F +:108E1000503180463C38172DDD9E440000463C080A +:108E2000172DDD9EFC418501B61F80818120838145 +:108E300085404004A001E320405E28014C57802378 +:108E40004074A000E2E9400E280040678000400323 +:108E50007C0892E1FFC792C1800780268047806628 +:108E6000F481490026A9F401E281E9094C12400588 +:108E7000B43FE220E90481078146D5DC812783865F +:108E8000D5D9E602E8DE8008802AFCC1A6409226F9 +:108E900096465A180109A68092459686CA043C1E39 +:108EA0000058DD9EA640922696465A180109A60053 +:108EB000920596065A0801048402D50284003C0EED +:108EC0000058DD9EFC4DB61F8400F084F08680E1E2 +:108ED000FA01FA338142F185F0873C1C01ACB008FD +:108EE0003C2C01AD80C349FFEF008401802A49FF7B +:108EF000EF1A44028E804C60000D44028E004C60DC +:108F0000000E44028D804C600011508F8014D50FEC +:108F1000B003810051CF8018D505B003810051CF37 +:108F2000801C44900055D507508F8010B00383807B +:108F300044900032FA1D49FFEF03549480FF84806F +:108F400080048420F48149FFEF09F4018029800422 +:108F500049FFEF2CF4018C815A4808F48400F08317 +:108F6000FA82F003E20AE80EB4A8B43CB45F4212FD +:108F7000907338110501B088381101098C01F08314 +:108F8000D5F1840049FFEEE049FFEEBC840149FFC2 +:108F9000EEDB49FFEEB7840349FFEED649FFEEB2A0 +:108FA00049FFEECAAE308400A670E201E819A0794C +:108FB00038508101D013A07D9482956A98CA882583 +:108FC000A6DAA70AE264E802AECAA0FD884388A335 +:108FD000A653A6ABE241E802AE6B8C01D5E6503554 +:108FE000000184A09261502300258085D32FA630F4 +:108FF000E2A0E828A039380015014C02C02450F343 +:109000008014B50F942A8900987500940003008499 +:1090100000028D218B2810908025B52F8920009487 +:10902000800210908037B52F8809A6031000804970 +:10903000A03B381015015002802C94018806AC42E8 +:10904000D502AF108CA18C41D5D28CC184A0843FB5 +:109050004C550010B407380015005A08FF04AE70D4 +:10906000D505A0B938010101AE308CA18CC1D5F174 +:10907000FCCDFC01FA5444328E80B61FF18149FFC9 +:10908000FF23B41FF101FA5444328E0049FFFF1C44 +:10909000B41FF101FA4244328D8049FFFF15B41F1D +:1090A000F101FA4244328D0049FFFF0EFC81FC467B +:1090B00083C0F384F485C907406088068401C2092F +:1090C00084FFD508C20484C3841FD5FB84C2841FD7 +:1090D00084E1FA62FED4F383886194D9887EF386B2 +:1090E000223180005EF1802E4EF300E996D0F387A6 +:1090F00096C8F388F407F3048864A6D9F389F409C1 +:10910000F3048864F40820318025F381F305886432 +:10911000A6D9F38AF40AF305886420318025F38206 +:1091200038329800C304846438329808F3014293BB +:1091300088245EF18024E903F3018E614243882490 +:1091400089238C81FA7442A21C2443C38C2481019C +:10915000FA6242850C73806894D9850040AF0C0098 +:109160008068E124E90938F520114EF70003886F83 +:109170008C81891CD5F7CB028461F40242A00424BF +:10918000E492E903F4028E8189444290042495011B +:109190008D21F48BF4034244807395218780408FA6 +:1091A0001000809CE149E90C38F470114EF700037F +:1091B000888F04FF800B8D2141CE3C00D5F4CC027A +:1091C00084818847FB4242A12824408080004025BA +:1091D00020003CFC005839CF0911844AE91DF109EF +:1091E000FED45010802CF20494498841403190768E +:1091F000A512F2034410005088484490005AFF0C16 +:10920000429E24244410006440420496382F0911E1 +:1092100040948536D51BFF14F20A40320C7650413B +:10922000002CF20595218844882AA512442000507C +:10923000FF14382F05114410005A44900064421E58 +:109240000424404224964090A536F10622F0800086 +:10925000E08FE840F101E423E804F102E423E93A75 +:10926000E122E838E47538329800E8035A380433CC +:10927000F102F2088E21422004739652F201F407A3 +:109280008E4142438873852496A238929808992E7D +:10929000CB03AEA4D5102032000442F38824FFDCB7 +:1092A000E0EFE802AEA42022000842F00424FE14FD +:1092B000E00FE81010120008D50D5EF1802438028E +:1092C0009800E804C0078E01D503C0048404380266 +:1092D0009808FCC6FC44F185F486F587843FC802F3 +:1092E000842143E08024424F0424B69F8A80952144 +:1092F00095C1F48484C0F406384218005A48014FDE +:10930000F4058886A7215A40FF36B52338449C00CF +:109310005A40FF3105C1800104A18005385E11016A +:10932000976FC805952A888AA721D5033845160066 +:10933000FF0CF481F404815E88878889F48385209A +:109340008080048F8001E10AE916B51F8909148F16 +:109350008002048F80033884250038FE210154F7F1 +:10936000803F4CF2C0055A80FF03F4028D418921F1 +:10937000D5E980802051002442909024FF4CE125C3 +:10938000E809A750E6A3E9038EA1AF50A750E6A3D2 +:10939000E811104100248484D50CF4071001002446 +:1093A00038F21C115EF78024E805A710C4038E81F3 +:1093B000AF108CC18C41507380245A68249EFCC429 +:1093C000FC42F281C505B1C1B183FAA2D504B1C393 +:1093D000B181FAB4C00450A07FFFD50281409EAA9B +:1093E000E241E8038EA1D5029D4944200032FF14DA +:1093F00044200064F08340420897852045C0001255 +:10940000F203E222E91204F38000B5064287F0730A +:1094100038F1A111E28FE9054C2000054C208003B2 +:109420008D2A8C41F283D5EDF08304F38000B4469D +:10943000FB024227A073382189114E270004E282E3 +:10944000E80284404C008011F18305C38000B5061A +:1094500044F00012428E3C733881A1114E87000502 +:10946000E288E902884814AF80034CA0000DB507DC +:10947000B406FB424204287338018111E408E90371 +:109480008E078840F583D10CB4A7B406FA224202B5 +:10949000847338018111E408E9038E078840842A27 +:1094A000FE8C400110178809FCC2442000FC4200D9 +:1094B0008873842110100086A042A845DD9EFC021E +:1094C0009703F182964B9A61F28190104E1400033B +:1094D000FE4A023F80059741222F80039AEB9A8231 +:1094E00096DB84028843402100565EF20200964BD0 +:1094F0009613E805FE2440000416D50652420438AF +:10950000FF044002041696039A2897435EF28925C9 +:109510008005E9034400092496434E1400038400A7 +:109520009603FC82FC403C5DFB044460003C02422C +:1095300080124241987344320000FF1F3C4FFB01F0 +:10954000C96DA724025280149720FEEF44500058A2 +:1095500042321473CA3780A28122854195694080C6 +:109560001400892384A09728401204095472000132 +:10957000944A88273864150140720C0938648408BD +:1095800097C640121009546301005073804C944AEE +:1095900088E192C8971788E95A6801074043100C80 +:1095A000A7B8FF37D5064045100CA678FF23FF0E5D +:1095B0008CA1AF385A5825D985225A20014A8441B6 +:1095C000D5CE804180C1949199C288C38440975080 +:1095D0004092900940428C09409488088926970659 +:1095E0008889549280070042004C4042240E4092E9 +:1095F000840940948808974688A997063853140030 +:10960000404220088885384389098C415A2825E141 +:1096100084C25A10011E8421D5D7A6A602528016F4 +:1096200044100060FF5F425104738C0298E9A26904 +:10963000542083FF12207FFF4020A8099234542138 +:1096400003FF541083FFAC80AC418C06DBF1FCC0FF +:10965000FC40EE88B0028420442000B0B1EE490006 +:1096600022FD8420442000C08007490022F73C0DE1 +:10967000FB174412951449FFF5832E002A8D449060 +:10968000003C8C019600F08184C144A20000F001EE +:10969000E2C0E853B00284208441806649FFFF4461 +:1096A000842180078066804149FFFF3E3C0DFB041A +:1096B0003C5C01E302300012840088694031A80458 +:1096C0003C3FFB0180808C8197215A40253202214A +:1096D0008014021180154083800039E3800196498F +:1096E0009691B63F02F400245BE3FF1054210FFF74 +:1096F0009041885EB042969141E080009491884507 +:1097000023EF002613E10000022400245A23FF0F58 +:10971000B43FB08254108FFF9021882F9649884023 +:109720009449882522210001AC888C02D5CD8CC1BA +:1097300097B05094803CD5ACED78FCC03C1DFB014B +:10974000C80402008014D503020080159601DD9E36 +:109750003C5DFB043C1C0175D109021280124420BF +:10976000003C421008738001DD9E0202801250000E +:1097700002D0DD9E3C2DFB044430003C021100125F +:1097800042100C73800144120000FE0F3C0FFB01DD +:10979000B420922796465A180104B400D503B402A7 +:1097A00092039637DD9E2E302B105A380179FC40FB +:1097B00081403C0DFB598122A6015A0009045A0838 +:1097C0000416507081F45CF081F497F984C0E804C9 +:1097D000526081F497B1840C49FFFFCE806AA09A51 +:1097E000A05B402100579691D5362E07EB52C0055D +:1097F0002E27FD9A5A28010B5070812C5CF0812C89 +:1098000097F9E80E5260812CD509507081F45CF014 +:1098100081F497F9E805526081F497B1D50284C0CC +:109820002E17EB3DC90FC00A2E07FD9A5A000107FB +:109830004460019044700258D505446000C84470EB +:109840000190840149FFFF98B44A041500014021AA +:1098500000579691400080175CF3840196018027A1 +:10986000E903441004009649E222E8050004800060 +:109870008C01D504E206E9FB84001004800000049A +:109880008000E6068401E90A8400100480002E00AE +:1098900003008C013E0003008402FCC08401DD9EB5 +:1098A0003C1C01753C5DFB04D1048E019600DD9EDD +:1098B000840CDD9EFC45814080C18400AC08120010 +:1098C000800912008008AC0FAC0EAC0BAC0AAC09DE +:1098D000441003E8AC7484E04410FFFFAC35B6E2FA +:1098E000A8511273000AA8553C1DFAFAA9D4141500 +:1098F00000073C1DFB023C3DFB38141500013C1DDC +:10990000FB0550850084141500033E07EB3C3E0721 +:10991000EB6CB40AB221B2450031800CF48549FFEA +:10992000E4FCB2058027F083F782F7818127B6FF38 +:10993000F203940988028101A4808400969345E093 +:109940007FFF808080A05034001296D904FF8003EE +:1099500094D9886FA4D896DBF3845A80011BE05E0B +:1099600041E13C1B5A50231F9AD34E340003FEDAC8 +:10997000E45F96D9E906E670E8158C819721D51247 +:109980005EF17FE2E80FE670E80D8C019601D50AE2 +:109990008C5496915CF10029E905B45F8C41969056 +:1099A000B65F8CA197688D12F2045A5824CEE69EB9 +:1099B000E90A5024800140910013F2018C419691F4 +:1099C000F281D50A5EFF0010E907E68FE905502411 +:1099D000800140910013E61EE908F0028CE18C0141 +:1099E000960197F9F082D5085EFF7FF1E805E60F52 +:1099F000E9038CE197F98C215A18129CFA1D8020FA +:109A0000844149FFE3348400802049FFE3250405B5 +:109A10000006B0C78020844449FFE359020F800E3E +:109A20008441AC30020F800FAC31F0052200000001 +:109A3000802049FFE31C8400802049FFE30D0405DA +:109A4000000684448020B0C749FFE341020F800E26 +:109A5000AC32020F800FAC33020F8010AC35220FF6 +:109A60008011AC344E930003C70584213E17EB3BB5 +:109A7000D5033E77EB3BF102E630E805F101E63035 +:109A80008420E90284215EF000653E17EB17E904AB +:109A900084013E07EB3BB41F5A08081684033E07B7 +:109AA000EB6F2E07EB6984218C019600E6053E17CB +:109AB000EB6C3E07EB69E90A000F80003E100305DE +:109AC0003E07EB6F84003E07EB692E07EB105A0848 +:109AD000010C2213000544021924AC402213000A91 +:109AE00044021926AC40FCC5FC42812022008008BB +:109AF00080C280E18441802049FFE2B98400802057 +:109B000049FFE2AA0404800584448020403F880085 +:109B100049FFE2DD020F8002021F8005AC32AC7506 +:109B2000020F800402138008AC3440008006FCC29F +:109B3000FC4A84803C87F5CE3DC7F5CD3CAC00594E +:109B400080C0806480A4509F800451E0FFFFD13C1E +:109B5000CD0C22200000227000018A474E24000311 +:109B6000FE9212248000D51D222300004C5F400984 +:109B700022737FFF8A474E240013FE92D510227372 +:109B800000019BD74E740003FFFA22F37FFF8A4F38 +:109B90004E240003FE92E0474023BC1B3824950965 +:109BA0002A230001E102E90EE05CE90C387495110A +:109BB00000F5000240F79C07E90588628C8196DB7E +:109BC00097238CA1D5C500050004E0048400E804B7 +:109BD00040319076961BFCCAFC4A84C0812080E20A +:109BE000FB0250AF8004842080064200A0739401E1 +:109BF0008809A400380505098C215A1824F7800A21 +:109C000049FFFF98947188278440AC08985696497C +:109C1000944988298C52A4C896918A6096DBACC876 +:109C20005A2A88F68CC15A6812E0FCCAFC002E073A +:109C3000EB3B84C85A00010F2E07EB3DC8062E00EF +:109C40002AFC84C25A00010384C149FFE4C2C8024D +:109C500084C33C2C0059A616AE12A6919E51FE4418 +:109C60008402400080168E01FE3496033C0BF5CE34 +:109C70003E27EAFAFE038C413C0BF5CD3E27EAFB7A +:109C8000FC80FC02F081F282F38349FFFFD1F002F5 +:109C9000F101F20349FFFFA2FC823811851188010E +:109CA000E004E9155CF28024E807E6A34402A3A0DF +:109CB000E80A8CB2D5085CF28264E90C5052FD9C33 +:109CC0004402A35838001511E004E8044400800061 +:109CD000DD9E8400DD9E001000A284413E10018ABA +:109CE000001000A1102000B63E100189001000AC49 +:109CF0003E1001880010009C3E1001870010009A61 +:109D00003E1001868420101000A2101000A1101037 +:109D100000AC1010009C1010009A3C0C0063101056 +:109D20000051DD9E2E1001815020040110100438D6 +:109D30002E10018044428F08101004362E10017F2F +:109D4000101004372E10017E101004352E10017DE6 +:109D5000101004602E10017C101004612E10017B85 +:109D6000101004622E10017A101004632E10017975 +:109D7000101000A52E100178101000AB2E100177E6 +:109D80001010009A8420383204008C211831000110 +:109D90005A180AFB8420101000B73C0C0063101006 +:109DA0000051DD9EFC2084003C0FFB4E4463F04AD2 +:109DB000447000553C0DFB67A600C805AFF0490094 +:109DC0001084D5F949FFF1A43C1C0063C804440F7A +:109DD000FFA0D503440FFFA1100080513C0DFB599B +:109DE000A6015A08040584013E07EB4D84003C0F90 +:109DF000FB4E4423F04A443000553C0C00630010F5 +:109E000000515A10BB04AED0D5F984201010005177 +:109E1000FCA05A0801093C0C00638420101000517A +:109E2000840ADD9E8401DD9E8E01E604E81244F082 +:109E30009D3C3807800040F03C00DD0F04080C100A +:109E40008400D5068401D5048402D5028403B601BA +:109E5000DD9E9200FC419EC1E66E4EF200C680017E +:109E600044F09D7038378D0140F1BC004A003C0041 +:109E70001C0022002800A800C800CE007601D400F3 +:109E8000E40004010801760176010C018406480013 +:109E900000AD8407480000AA84003C0FFB4E4473C9 +:109EA000F04A4490005549FFE2DF80C05A000207A3 +:109EB0001093800049001009D5F7840149FFE2E7BB +:109EC00049FFE2A73C0E020449FFE2AD3C0E020549 +:109ED00049FFE2BA3E00081949FFE2C23E000818F5 +:109EE00049FFE2B83E00081A440295B049FFE2D4A7 +:109EF000800649FFE2CC84003C0FFB4E4463F04AED +:109F00004470005549FFE2B0C005AFF049000FDDD5 +:109F1000D5FA49FFE2BCD568842EAE418426AE4016 +:109F2000842149FFF2E5842084028041846180819C +:109F300080A149FFF09BD5588401AE10D51A840149 +:109F4000AE10D50784C1AF9049FFCE843E67FD9A1D +:109F5000840ED54B8401AE1044124E0044014800DB +:109F60004420140049001075440002EE49FFEAAA9B +:109F7000840DD53BFA00D539FA01D53744021C517E +:109F8000A640A7C1A640A68192E440212008FE8FEA +:109F900097CF842154210FFF800749FFD1DB80C078 +:109FA000B0418007502F800649FFD21044021C5553 +:109FB000967092C8A68097B1AE40A641AF81021FAD +:109FC000800244021C579688A6C09228AE80A681C3 +:109FD000AE41021F800344021C599688A6C09228F5 +:109FE000AE80A681AE418401FCC192003C1C00639E +:109FF00010008060DD9E3C0C006300000060DD9E70 +:10A000003C1C006310008061DD9EFC005A080604C1 +:10A010008401D5045A08070684003E07EB12D51CBC +:10A020005A080D0784003E07EB128421D5075A0811 +:10A030000E0B84013E07EB1284203E17EB413E07D6 +:10A04000EB38D50A5A0810048401D5045A081105C2 +:10A0500084003E07EB10FC80FC003C0C0063441FB6 +:10A06000FFAA101000513C0C0063000000515A0878 +:10A07000AA07440000FA49FFEA25D5F65A00DD0494 +:10A080008401D5028403FC805A080307FC00800188 +:10A0900049FFFE23FC805A08041E2E00018A10008E +:10A0A00080A22E000189100080A12E0001881000DE +:10A0B00080AC2E0001871000809C2E0001861000CD +:10A0C000809A8400100080B63C1C00631000805110 +:10A0D000DD9EDD9E5A08051D0000812C84423E0055 +:10A0E00001850000812D3E0001840000809A3E0021 +:10A0F00001830000809E3E00018284001000809A4F +:10A100001000809E1000812C1000812DD5335A083C +:10A1100006162E0001831000809A2E000185100083 +:10A12000812C2E0001841000812D2E000182100050 +:10A13000809E84001000812ED51F5A08072200003F +:10A14000812C84413E0001850000812D3E00018468 +:10A150000000809A3E0001830000809E3E00018244 +:10A1600084001000809A1000809E1000812C100046 +:10A17000812D1020812E3C1C006310008051DD9E3B +:10A180005A08016100008438505084013E0001816A +:10A190000000843680453E00018000008437443250 +:10A1A0008F083E00017F000084353E00017E0000E4 +:10A1B00084603E00017D000084613E00017C00005F +:10A1C00084623E00017B000084633E00017A00004F +:10A1D00080A53E000179000080AB3E0001780000C0 +:10A1E000809A3E00017784000841000138418008D0 +:10A1F0008C015A080AFB84408461102084351020A9 +:10A2000084601020846110208462102080A51020BA +:10A2100080AB1020809A1030843810308436103093 +:10A220008437103084635020840B18028001DAFEDA +:10A230008401100080B73C0C006384201010005192 +:10A24000DD9E5A0802FFFC00800149FFFD6DFC8085 +:10A250009EC1E664E823FC01F281800144F0A16C18 +:10A2600038378C0040F1BC004A003C00040C1C2430 +:10A27000A44858108002D504A488843DFE56AC4002 +:10A28000F10149FFF363D509A44858108001D504B2 +:10A29000A488843EFE56AC40FC81DD9EFC009EC13D +:10A2A000E66CE85F80818004802244F0A1B83837F2 +:10A2B0008C0040F1BC00DD0F0C14222A3242A8A809 +:10A2C000A84C6688A69058210002D504A690542177 +:10A2D00000FDAE8849FFF33AD544A61058000001AE +:10A2E000D510A610540000FED50CA610580000048E +:10A2F000AE1084013E07ED22D534A610540000FBB9 +:10A30000AE08D52FA6D0442FFFBFFED6AEC8A6C834 +:10A3100058318020AEC8A460FE8EACA0D51EA69099 +:10A3200058210040AE88A6C8442FFFDFFED6AEC835 +:10A33000A46058108040AC60A460FE8EACA0D51123 +:10A34000A69058210040AE88A68858210020AE88EB +:10A35000A46058108040AC60A44058108020AC40ED +:10A36000FC8092005A08071C8E21E624E87444F011 +:10A37000A27C3817840040F0BC00DD0F040C121AD8 +:10A38000A41058000002D566A450841DD552A41014 +:10A3900058000001D55FA450841ED54B5A080828E8 +:10A3A0008E21E626E85844F0A2B43817840040F025 +:10A3B000BC00DD0F060E161E262EA6185800000241 +:10A3C000D514A618540000FDD510A6185800000199 +:10A3D000D50CA618540000FED508A6185800000495 +:10A3E000D504A618540000FBAE18DD9E5A080B34A5 +:10A3F0005A100B125A100C205A180A2EA658440F45 +:10A40000FFBFFE46AE58A65858108020AE58A45044 +:10A41000FE0ED51CA61858000040AE18A658440FD2 +:10A42000FFDFFE46AE58A45058108040AC50A450F8 +:10A43000FE0ED510A61858000040AE18A6185800F9 +:10A440000020AE18A41058000040AC10A410580012 +:10A450000020AC10DD9E92003C1C00630000805088 +:10A4600050007FDFE602E904840010008050DD9E8A +:10A470003C4C00638400443298109441382181019F +:10A480008824102080A8382181118C019048102048 +:10A4900080A95A081EF4DD9EFC42F28244221C5020 +:10A4A000F081F383812144121C51A610A790A7C804 +:10A4B0009204979F97F85A0801249E71E622E90FAB +:10A4C0005A6003045A68051D3C1C0063001080603C +:10A4D0005A10A1062E1002FC5A100113440278A74C +:10A4E0004412795049FFEFA6440278C4441278CB55 +:10A4F00049FFEF57FD03F20149FFD8C0D5139E472E +:10A50000E622E9035A080B0F8026F202F30349FF03 +:10A51000FF2B8401100480003C0C00638420101089 +:10A520000050FCC2FC4080C18420AE40A4108122B7 +:10A530009201960680E381445A08010AA4308023E0 +:10A5400058000002AC30800649FFF200020480008F +:10A5500092019606C809A470841DFE0EAC308027B7 +:10A56000800649FFF1F30204800096065A080106AE +:10A57000A43058000001AC30020480009606C805E3 +:10A58000A470841EFE0EAC30020480009207960672 +:10A590005A080108A47058108080AC703E07ED2264 +:10A5A0000204800092079606C806A470440FFF7F3D +:10A5B000FE0EAC3000050000920196065A08010A12 +:10A5C000A638802758000002AE38800649FFF1BE49 +:10A5D0000005000092019606C809A638802754009D +:10A5E00000FDAE38800649FFF1B100050000960677 +:10A5F0005A080106A63858000001AE3800050000D0 +:10A600009606C805A638540000FEAE3800050000C6 +:10A61000920296065A080108A67858108004AE786F +:10A620003E07ED220005000092029606C805A638F6 +:10A63000540000FBAE380005000092059606C805E0 +:10A64000A638540000DFAE380005000092059606DB +:10A650005A080106A63858000020AE380005000050 +:10A6600092069606C805A638540000BFAE3800050D +:10A670000000920696065A080106A63858000040C7 +:10A68000AE380204800092059606C806A470440FF6 +:10A69000FFDFFE0EAC3002048000920596065A08D9 +:10A6A0000106A43058000020AC300204800092065D +:10A6B0009606C806A470440FFFBFFE0EAC3002041D +:10A6C0008000920696065A080106A4305800004001 +:10A6D000AC30FCC0FC0080C049FFFC995A680919E5 +:10A6E0002E07EAE15A08014B49FFF7B449FFFB5C2A +:10A6F00084003E07EAE13E07EAD449FFDF6A802092 +:10A700008403C1038404842049FFEC68D5375A6868 +:10A71000030649FFCA998006D5325A680E0C2E07E7 +:10A72000FD9A5A08012C3C0DFB59A6015A08030A50 +:10A73000D5065A600DFA5A6002F8D5208402D51F5A +:10A74000840049FFE2373C0DFB59A7815A680A0B88 +:10A750008429AE41842049FFEECB3C0DFB59AF81EB +:10A76000D504842049FFEEC449FFDF335A0802E8CC +:10A770003C1DFB598443AE89D5028401FC80000056 +:10A78000FC00800180C149FFFB4696005A680259CF +:10A790003C6C0063001300528E21E627E85144F020 +:10A7A000A6AC3817840040F0BC00DD0F08141E284A +:10A7B0003A4E7A0084014412B80049FFFCE3D510F8 +:10A7C0004402B80049FFFAB0D50B4402B80049FF73 +:10A7D000FA84D50684044412B80049FFFC5784006B +:10A7E00010030052D52F84054412B80049FFFC74B1 +:10A7F0008400100300528402D5202E0001833E0005 +:10A800002AFA2E0001853E002B8C2E0001843E008A +:10A810002B8D2E0001823E002AFE84001003005181 +:10A8200010030052D50A84074412B80049FFFC54B3 +:10A8300084001003005284013E002B8ED5035A0879 +:10A840000A0C49FFFC0B3C2DFB6784219600AE509F +:10A850003C2DFB4DAE50FC80FC43008080013CFC55 +:10A8600000635A88041484C03E67EB4D2E67EAF5F6 +:10A870005A60010D00678050546300F05A60100761 +:10A88000440000553E07EB5DD515006780508125DB +:10A89000F4848143B65F80E1F083CE0F80024412DE +:10A8A00078CB49FFEDB5440000553E07EB5D3E67B0 +:10A8B000EB4984014800017A5A80010949FFDE8989 +:10A8C0005A080205840149FFE184B41F441278CB81 +:10A8D00049FFED673C1C006384003E07EB5F0060AE +:10A8E000805040031009F08200008051979FF08152 +:10A8F00084003C0FFB7FA6795A180421840149FF8C +:10A90000E1482E07EB0B5A08010449FFD5E6800702 +:10A91000842049FFEDED840149FFC81C84003C0FF1 +:10A92000FB4E4483F04A49FFC808C83C4400005528 +:10A930001004000049000AC9D5F7A6785A10010A88 +:10A9400084003C0FFB4E4483F04A44200055D5154B +:10A950003C0FFB873C0FFB4E4483F04A3C0DFB87CA +:10A96000C8F049FFDE365A0802ED440000551004D5 +:10A97000000049000AAAD5F33C0DFB67A640C908B0 +:10A9800010240000F28549000AA0F205D5F6A600C1 +:10A990005A0002093C0DFB4DA6405A1802048420BF +:10A9A000AE40F0028E01E60B4EF200FC44F0A8BC73 +:10A9B0003807810140F03C004A003C0016004E0080 +:10A9C0009E00B8004C0156016401A601E4017A0121 +:10A9D000A601440278A74412795049FFED2BB41F19 +:10A9E000441278CB49FFED148006F101804749FFFE +:10A9F000D6453C0C00638420101000505A600F04B0 +:10AA0000480000D084CC480000B884013E07EB5FCA +:10AA10005A6801092E07EB12C813843F3C1E00BA86 +:10AA2000D5105A6802092E07EB12C80D843F3C1E50 +:10AA300000BAD50A84015A68030A84C2D508840082 +:10AA400084C4D505840084C5D50280C084213E1706 +:10AA5000EB494E0200974800009084053E07EAD17A +:10AA60008026840149FFFE8E80C084043E07EAD11F +:10AA7000480000832E07EAD484E13E77EB5F5A0852 +:10AA800001044800009184023E77EAD43E07EAD1EF +:10AA900049FFE8D95A6801063E67EAE148000084A8 +:10AAA0005A680B053E77EAE9D5215A68031A3C2C0F +:10AAB00000630001005500310054400020080011DF +:10AAC0000052880344310000FEC700010051804657 +:10AAD0003E17EADA3C3FFB3249001C50D5055A606C +:10AAE00005E85A600AE65A680705490024ACD55BB8 +:10AAF0005A68095A3C0C0063000000523E07EAE025 +:10AB000084013E07EAE5D5388006F10349FFF98E56 +:10AB1000D548FD03442278FF49FFF99E9780D52C44 +:10AB20008006802A804949FFFB95F1040205000058 +:10AB300084CBAC08D5213C0C00638420101000505D +:10AB4000440278A74412795049FFEC74B41F4412B0 +:10AB500078CB49FFEC5D8006F101804749FFD3C502 +:10AB6000D5208006802A804949FFFB9AF10E000417 +:10AB7000800084CFAE083C0C00638420101000508D +:10AB80002E07EB5FC80C440278A74412795049FFA6 +:10AB9000EC51B41F441278CB49FFEC3A8006D5053E +:10ABA00084C1D5EA84C9D5EDFCC39200C1245A18EA +:10ABB00004074442922884A13852000844428F344A +:10ABC0004C110015C30485E35A10040385E13832A3 +:10ABD000000044528F34E26FE8058C6138328008FF +:10ABE000D508842038128008D50684403822000811 +:10ABF0008001DD9E8002DD9E2240000C5050000A44 +:10AC00005010002884008441383289118C419AE325 +:10AC100088035A2804FB8CAAD9F7DD9EFC423C4CE1 +:10AC2000006480E084C000A2000F0042001080A6F3 +:10AC3000F48140450408F4824647FFFF50420FFF6D +:10AC400088814272287395F98E218086F1838EE285 +:10AC500087868E01F1038825964A4E150021049FB0 +:10AC60008001E029E81C987E83C34081040043E210 +:10AC7000F073842040900400409480104E95000DA5 +:10AC8000E12AE80A38F40511389F05014297A42407 +:10AC90004E97000388898C215A1803EEF1028CA18B +:10ACA00088C15A5803D94400008440020016960314 +:10ACB000FCC28060804084019A50E622E90B9850E3 +:10ACC000922142F08424E26F4000BC1A4020BC1B59 +:10ACD000D5F4DD9EFC20848080A4806484E1406300 +:10ACE000900CFF96C605386011118CA188668C8186 +:10ACF0005A4819F75A10021AC91A403194773C3F42 +:10AD0000FB3C80C184E14043840CFF16C4063840FC +:10AD100005118A83426210738C215A1819F6400378 +:10AD2000141749FFFFC8D5048003D502841FFCA077 +:10AD3000FC42814246201F8D84205021063F8380A3 +:10AD400080C349FFFFC981008420442739C0801C8B +:10AD500049FFFFC24432990880E3F081440000FCBF +:10AD6000427300733C0C01AE04238009F383229EDE +:10AD7000000C38200900801CF28249FFFF3F00438D +:10AD80008020F3039706501380F8F202CC04A70A40 +:10AD9000E282E802AE8A2E17EB1D2E47EB6E9D492C +:10ADA000E0A42FC7EB62E902C9043C13F5CFD50339 +:10ADB0004410004B50F27FFE5CF78003E80D2EF745 +:10ADC000EB3CE90AE0A4E806843BFE6450108055A1 +:10ADD000D5034410004B4EA2000A3C43F5CF521558 +:10ADE0000004FE64848540109036444000FC80A33B +:10ADF00042531073808584A0105200F80242000F65 +:10AE000045E0008C5CF21451405278B7E90F504293 +:10AE10006BB040F279F640F794064EF2008D44FF95 +:10AE2000FF7440423C9688A4D5045CF20C81E92D65 +:10AE3000444000FC80E34273107300F3805041CE25 +:10AE4000001044400064424E10245AF8010550425C +:10AE50000384D50350420640E289E8058489FF64F3 +:10AE600092A1D50940F4880842F79424404790976E +:10AE700092A188A44440003240401097E285E80344 +:10AE80009B2CD50284808824F00195C1E2E8E90575 +:10AE90005CF10029E804D50AE655E907FA044021E7 +:10AEA00000574010880DD50292215AA00408440290 +:10AEB00090D438001800E604E902FA245CF487D143 +:10AEC000E816440000FC8043422300738002002106 +:10AED00000505A28040A000000FAE608E805944BDE +:10AEE000840A40108037E3018401E9284402922853 +:10AEF00038001800C80B44129288400480133800B0 +:10AF00009909441292E438009909440000FC423344 +:10AF10000073000180505A08040D441292884422A4 +:10AF200092E4383099013890990938311909D506D9 +:10AF30008404D50484A048FFFF7DFCC2FC52F08845 +:10AF40003C0C0064F189F28C0010003200000033E8 +:10AF5000F181F0823C0004C45CF0002EE903FA0E9B +:10AF6000D5035200004B3C0BF5CF2E07EB3C2E17C0 +:10AF7000EB625A080109E622E9063C03F5CF8E0A86 +:10AF80003C0BF5CFE625E90484003C0BF5CFF0013E +:10AF900084E09201F08AF0029201F08BF009506097 +:10AFA00000503C0C0064F08300000009E2E04EF227 +:10AFB000012904037FECB61F8E01E6034EF200F474 +:10AFC000F00122137FDA22937FDB401080B6960BCC +:10AFD000F087F002976840248016F286F20A960005 +:10AFE00088A2F20B85408802FE02F08514AF80042F +:10AFF000F005FEAA42400024B0128500403028002F +:10B00000800442010873F391F190F58FF48EF28D74 +:10B0100049FFFE5196015CF00084F20DF40EF50F2D +:10B02000F110F311E805520000849601D502840066 +:10B03000049F80043801A109892080099601F084C9 +:10B04000F0018D0188405A8803DDF205F0028D463B +:10B050008840F2855AA812CE44229304840040808E +:10B06000801338011D0950047FFEF08EF006852004 +:10B070008E0295798149F08F840AB057421500738A +:10B08000F00FF185880A96038480F08DF00EF10DA3 +:10B0900088049603F208B0D2F591F49049FFFDC000 +:10B0A0008020F410F5114E0400038420F205960B65 +:10B0B0005EF0006538111109E90B44029304441253 +:10B0C0009304380014018C0138009409D5028920BA +:10B0D0008C815A4805DD8D415AA805D04400006492 +:10B0E00040948137440293043800140189204402BB +:10B0F000930438901409F0078521E402E909F0036C +:10B10000A60250907FFEF007E00956978001F003F9 +:10B11000F106A6038E02E020E90550048001549058 +:10B1200000FFF006E402E80650047FF9E604E802B6 +:10B130008524221F803A44000084FE0CF104400064 +:10B140000416A4759601E220AC34E8063C1C02E823 +:10B150005CF080C8E904B43F5A180303AC3596F894 +:10B16000F00944129450F208B67F49FFE2D9F10C7D +:10B170008049B47FB01749FFFDDD804010037FFF99 +:10B18000A6708007806949FFFD13AE305A08010898 +:10B190004402922838001C005A0001038400100366 +:10B1A0000089D52AB43F8417FE0EC0035A1806251D +:10B1B00044129228840010037FFFAE3038009C08B0 +:10B1C0004412925838009C08441291408400380080 +:10B1D0009E0A4412926838009D09441292883800F1 +:10B1E0009D09441292E438009D0944128F341203E1 +:10B1F0007FE738009C088CE1506300FC48FFFED3D9 +:10B20000FCD284A1C20284BFC909FA22FE0CFA2131 +:10B2100042010473B6038805D50E4410027681E01E +:10B2200042F10473FA3342510473FA2214F180009C +:10B2300042028473B604DD9EFC4044302710FE5C5D +:10B24000FA984657FFFF40208856FB2450528FFF44 +:10B2500080C44470005080233830191138601D11AB +:10B26000FECC403198768A624E340003FEDAE06507 +:10B270004051BC1B9CE140923C1B5A30790D5CF163 +:10B280008051E9045262009FD50280C35272007758 +:10B290008083D5E38009FCC05CF00051E9055230A1 +:10B2A00000A0B661D502B60150107FD85CF0805185 +:10B2B000E905520000C8B602DD9EB622DD9EFC44C0 +:10B2C00084C0810583808141F282F38180E480A380 +:10B2D0008126E2E5E9148005F110F202B0C4B1055F +:10B2E000F58349FFFF90F004F503380E01118CA19E +:10B2F0008920F005380E011188C0D5ECF001804698 +:10B300008AE0FFFB8405422380734E2600038441BC +:10B310008029800A49FFFF92B4285A10FF058C212A +:10B3200088019201B608B046B08749FFFFB7F00622 +:10B3300038150111F00738250111840240008016EC +:10B340004204887340000416FCC4FC4580E13C1CA8 +:10B350000078F28350600028002080328400F2855B +:10B360000020803344A28F44F286202080392010B0 +:10B37000803AF287F188F084448000FF3C0C00782A +:10B38000F10400000009E2204EF200D104137FF620 +:10B39000841BFE0E4E0200B85A180604480000B482 +:10B3A000A0375A080204480000AF04937FFF40040E +:10B3B0008808F089F109A03D8801A6C0CB19A642F2 +:10B3C000E622E9029EC9A7035CF20022E8038C8111 +:10B3D000D502FA9384403C1C0079B65FF00380A646 +:10B3E00049FFFF6FA07E3810A6028A20D522A64111 +:10B3F0005A18112CA6C2E662E9038E61D502846058 +:10B40000A7035CF20022E8038C81D502FA933C1C6E +:10B4100000798400B61F501080A28441F00380A6FA +:10B4200049FFFF4FA07EFA423810A602421008736F +:10B43000F205FE54042380083821260288024000C9 +:10B440008016F1078801D504B70602037FEE1203C8 +:10B450007FF2F109A03D8801A6C2CB1BA640E622DF +:10B46000E9029EC9A701E690E8038C81D502FA8122 +:10B470003C1C00798401B61F50108144F0038440C5 +:10B480009D7449FFFF1EA07F3810A6028A20D52098 +:10B49000A6435A18232AA6C0E662E9038E61D502A4 +:10B4A0008460A701E690E8038C81D502FA813C1CF8 +:10B4B00000798441B65F501081E6F0039D7449FF26 +:10B4C000FF00A07FFA543810A60242100873F2065B +:10B4D000FE5404238008382126028802400080168A +:10B4E000F1088801D5051483000102037FEF1203E0 +:10B4F0007FF322037FF21205000022037FF312057F +:10B500000001D50C2205000012037FF22205000184 +:10B51000B70612037FF314830001F0048D448C01FD +:10B52000F084506300FC48FFFF2BFCC5FC2051FF5A +:10B53000FD68B61FF18180C2B0044410DBA844202E +:10B54000028880E349001380440000A2B044421303 +:10B550008073F2018001B43F49FFFE70B042B083B6 +:10B5600049FFFE9C4400005142338024F002B04465 +:10B57000880338208111F103B004886138100D115F +:10B58000840240010016420304734000081696032B +:10B5900051FF8298FCA099015EF207D1E911E00108 +:10B5A00044400064E807AF10FF0440120436AE5870 +:10B5B000DD9EFE6440008016AE10AF18DD9E440094 +:10B5C0000064AE10AE18DD9EC10B402084094430EB +:10B5D000006442200C7340110436960BDD9E8001FE +:10B5E000DD9EFC5E83803C0C0078B046509F80CC92 +:10B5F00000800002A7834400DE3050AF80B83A20BC +:10B6000014043A209424A400AC084400DE44B04B57 +:10B610003A2014043A209424A400AC084400DE58D4 +:10B62000B0503A2014043A209424A400AC084400FA +:10B63000DE6CB0553A2014043A209424A400AC08DF +:10B640004400DE80B05A3A2014043A209424A40026 +:10B65000FA54AC0884208009490013004400DE94A9 +:10B66000B05F3A2014043A209424A400AC084400AB +:10B67000DEA8B0643A2014043A209424A400AC0854 +:10B68000B0694400DEBC80E13A2014043A239424DB +:10B69000A400AC384400DED080EA3A2014043A23F7 +:10B6A0009424A4009EF1AC388400100F8016100F73 +:10B6B00080179E324200202494014261A024881CFD +:10B6C00095B140740408F081400E180088FCB61F44 +:10B6D00084C0F1829630E208E835B05F380E191167 +:10B6E00038109800F38349FFFF71B064380E1909D0 +:10B6F000380399113810980049FFFF6838039909F9 +:10B70000F102F001381098003800191149FFFF5E6E +:10B71000F10138009909B41F3815180038001911C3 +:10B7200049FFFF54B43F38009909B04B38039911D1 +:10B730003810980049FFFF4A38039909F3038CC178 +:10B74000D5CA84009640E228E80FB05A381080002D +:10B750005A180C0938148101382E01018822381436 +:10B7600081098C01D5F0220E000044100041FE44F6 +:10B770004440007B022F8066401090368822121FC2 +:10B7800080664410003AFE0CA47840001016880130 +:10B79000AC3884009640E228E80738148101381E4E +:10B7A00001098C01D5F84261A024407320019C312D +:10B7B0009C7995019489380E0101381E05018C0190 +:10B7C0008C21F2819603964B502F8016503F8017A4 +:10B7D000F48349FFFEE29439881CB61F943140AED1 +:10B7E0000000001F8017000F801622350000445013 +:10B7F00000418526FE6C420024249888FE1CB47FFC +:10B8000040000816A4D8F4038803B47F889CF5820E +:10B81000AC1822050000503F8017FE4440108836C7 +:10B8200012150000F1010202000F883C8C01021089 +:10B83000800F96038C21964B502F801649FFFEAD4A +:10B8400050047FFF88C095B188DC88E0001F801716 +:10B85000000F8016F5022223000095F988FC4200B3 +:10B860002424FF4C9868FE1440900536A438B08616 +:10B87000892012938000220300008520FF4440525B +:10B8800084B6AD70B1D5B190540480FFE208E81FD2 +:10B8900038112400380E2511F28149FFFE97380E29 +:10B8A0002509B41F381324003800251149FFFE8EE6 +:10B8B000B43F3800A509380525113813A40049FF05 +:10B8C000FE8538052509F2018D21D5DF4064040885 +:10B8D00084639C7142340C24382E0511407408088E +:10B8E00040908408381E0D118C6195598CE488FCB9 +:10B8F00088BC8CC2E45F380E221122438000383E9F +:10B900000D112252800188DCE9098802882388040D +:10B910008825846049FFFE0CAC3022230001893C5D +:10B92000E45F224E000222038000221E0003223325 +:10B93000000222548002E90988828823880488252D +:10B94000846249FFFDF5D5028400A4708801AC3003 +:10B95000FCDEA0CD94128803A6C3A6029A18E41FA9 +:10B96000E90484853E47EB6DA10A384209015A4833 +:10B9700001092E47EB005CF20047E813E662E9118B +:10B980002E37EB6A5A380108A04C38108900E6229D +:10B99000E804D5075A300206E41FE8038400DD9E60 +:10B9A00044008000DD9EFC45B61F8401120F800A12 +:10B9B0004400004B120F800B44000046120F800C15 +:10B9C000840080E1120F800DFA34FA0280C249FF30 +:10B9D000D2DD8400842149FFD33F8441B0C7800772 +:10B9E000802649FFD3748400802049FFD335800727 +:10B9F00084418027B0C749FFD36A50538024500345 +:10BA00000024502384ECA46850528024964BAC4010 +:10BA10000212FFFF50000024964B12107FFFDAF451 +:10BA20008403842149FFD31880068026B0C784424E +:10BA300049FFD34D802780068442B0C749FFD347D2 +:10BA40003C3DFB1D500F8016FB02AC19440000402A +:10BA5000854140930013FA9184C01001800BFA14C1 +:10BA60001041800A1291800012918002AD9B12A1B8 +:10BA7000800410A1800C1081800D1081800E1001B7 +:10BA8000800F1061801010618011108180121001F0 +:10BA9000801310A180141081801510818016100170 +:10BAA00080171261800C1261800DF48349FFD3244A +:10BAB0003C0DFB1D97F9B086AC81ADC0ADC249FF0E +:10BAC000D31B3C0DFB1DFA70F38212900001103065 +:10BAD000000A10A000101080001149FFD30D3C0D8A +:10BAE000FB1DF302B08596911030000AAC81106006 +:10BAF000001010600011F28149FFD2FE3C0DFB1DC9 +:10BB0000F403F2011040000AAC80ADC112900002B3 +:10BB10001060000C1060000D10A0001010800011CB +:10BB200049FFD2EA3C0DFB1D023F8000FA38ACC051 +:10BB30001010000A12900001AD8410A0000C1080BB +:10BB4000000DF381B63F49FFD2D73C0DFB1D502FAE +:10BB5000801A9691AC81AC82442000301020000AFB +:10BB600044207FFF1220000C129000001060001093 +:10BB700010600011106000141060001512A0000D7C +:10BB800049FFD2BA3C0DFB1DB43FF301ADC1ACC0BF +:10BB9000ADC21010000A10A000101080001110A0FB +:10BBA00000141080001549FFD2A7020F800D441029 +:10BBB00013EB40008006FCC5FC433C4C01B02E97C3 +:10BBC000EB35954198655024FFFEE644A6C9A6488A +:10BBD0004EF2009444227A98382100005A28010439 +:10BBE0004800008C3DCC01AFE6624022F000F282BA +:10BBF000A4902E702A62924140A100113C8C01E277 +:10BC0000E910804342209C7394918E4288489F9A09 +:10BC1000A490E67096934021280797B0E815D504C4 +:10BC2000446000FF844081E342F09C7380EF8CE12C +:10BC300095F988E8A5F897FBE0EAE80358210002A7 +:10BC40008C6296D8D503443000FFE622F381E908E0 +:10BC50009ECA5CF0802255E180FFE805D50283C1D1 +:10BC60008C229648C24A3C3C01AD97C1F383F785CC +:10BC700084609758D8078C6197D8E2E98C82E9FAFA +:10BC8000D53CF70338738D01F784F50497D9DFF4B9 +:10BC9000A761DE035A20020804AF80014C557FEDF6 +:10BCA0005A2801EBA7E0E2FEE9E7E227E9E5F50221 +:10BCB000387E0D0102A28000E347E8DE44527A9804 +:10BCC00084E138728C0804AF800384E0048F80051F +:10BCD0000AF500014CF4400B028F800844527A9818 +:10BCE00012857FFF850138829C088CE154F380FF28 +:10BCF00040F7A406E9ECD5C0FCC33C0C01E20210FD +:10BD00000013964BE435E9030210001302100025DE +:10BD10002E17EB6A5A18011E50500022504000188E +:10BD200094018460500000229A45A448968BA46830 +:10BD3000964B9A514E140003FE4AE434E8038C619A +:10BD400096D88EA2DCF25A38050584023E07EB6ACB +:10BD50002E07EB675A08010584023E07EB6A2E079F +:10BD6000EB6C5A0801048405D5052E07EB6DC00461 +:10BD70008E013E07EB6DDD9EFC00842084003E07B3 +:10BD8000EB063C6C01E98061804180019971A52836 +:10BD900097235EF200C8E9038C018C41A528972304 +:10BDA0005EF27F39E8038C618C018C225A1890F086 +:10BDB0005A3048045A28480584213E17EB0684204F +:10BDC0003C3C01E880419919A5205CF20064E8063A +:10BDD0008C419690E644E90284008C225A1890F532 +:10BDE0005C000003FC803C1C01B094018801A6406B +:10BDF000A6018E02E60FE8088E215CF08022E8049E +:10BE000084003E07EB67DD9EFC403C3C01AF409068 +:10BE10000408948938418101383185013C7C01B1A5 +:10BE2000E264954A3C4C01AD3C3C01AE9582E8276A +:10BE300038020101380205094001A40038118501CA +:10BE4000A4808822AC40987E983DA6CAA682E24390 +:10BE50004021BC1AAE8AA6CBA683E2624021BC1A5E +:10BE6000AE8BA6C8A680A601E2434021BC1AAE88CC +:10BE7000A689E24040013C1AAE09D52538120501D9 +:10BE800088433812010938118101A4108801AC10CF +:10BE9000987E983DA6CAA682E2434021BC1AAE8293 +:10BEA000A6CBA683E2624021BC1AAE83A6C8A680B8 +:10BEB000A649E2434021BC1AAE80A681E22240207E +:10BEC000BC1AAE81FCC03C0DFB4E461010008C012C +:10BED000E2203C0FFB4EE802D500DD9EFC00440250 +:10BEE00078604422A3E884208A4049000EB7FC8091 +:10BEF000FC0084003C0FFB7E3C0FFB7F3C0FFB8B68 +:10BF00003C0FFB6C3C0FFB8A3C0FFB833C0FFB8917 +:10BF10003C0FFB7C3C0FFB773C0FFB6B3C0FFB8E1D +:10BF20003C0FFB753C0FFB863C0FFB803C0FFB8CF2 +:10BF30003C0FFB6E3C0FFB733C0FFB723C0FFB7026 +:10BF40003C0FFB813C0FFB883C0FFB6D3C0FFB7AE9 +:10BF50003C0FFB8D3C0FFB793C0FFB853C0FFB7DC1 +:10BF60003C0FFB713C0FFB7B3C0FFB783C0FFB76DF +:10BF70003C0FFB8264030003640304036412240285 +:10BF80009646C10364030003440040006402240396 +:10BF9000641200028419FE0E6402000364000008AB +:10BFA00064030402461617805010807CFE0F640361 +:10BFB0000403640200025800000164020003FC80D4 +:10BFC0004403F04A44100055AE404413F0EDA60877 +:10BFD0005A08010A4423F0DAA610540000F0AE100B +:10BFE0008400AE088404640304034403F0498425F8 +:10BFF000AE404403F04A44100053AE40DD9EDD9E47 +:10C00000FC204443F1104473F04AB4649278403108 +:10C01000E008FE1F4433F114B604B4039218400044 +:10C020006008FE474403F10EB623AC804403F10CD4 +:10C030008421AE4084203C1FFB4E80C0A630C00748 +:10C0400044000055AE3849FFFF40D5F9FCA0FC2064 +:10C050004443F1108E41B464969192784031E008E7 +:10C06000FE1F4433F114B604B4034473F04A92182B +:10C0700040006008FE474403F10EB623AC80440341 +:10C08000F10C8421AE4084203C1FFB4E80C0A630C2 +:10C09000C00744000055AE3849FFFF17D5F9FCA092 +:10C0A000FC204443F1144463F134B4644473F04A13 +:10C0B00092784031E008FE1FB6044403F10EAC4014 +:10C0C0004403F1048421B6404403F132AE408400BD +:10C0D0003C0FFB4EA630960EC80744000055AE3804 +:10C0E00049FFFEF3D5F84413F134A6089606C8FEBE +:10C0F000FCA0924284A0D207383016023830960A4B +:10C100008CA1D5FADD9E3A6F9EBC8400802049FF49 +:10C11000D5D484006405E4034403F00EA4009626FD +:10C12000C00949FFD2565A0802064400006949FF77 +:10C13000D69A4403F00EA440964EC90FA4409656DA +:10C14000C90CA440965EC909A4409666C906A4001D +:10C15000540001004E0200D14403F00EA400960EDC +:10C16000C80949FFFEBD4403F00EA440965EC92CE9 +:10C17000D52244021C5084C0AD803E67EB2A49FFA3 +:10C18000D33C440218BCAF80440218BDAF804402C7 +:10C1900018BEAF80440218BFAF80440218C0AF8001 +:10C1A000440218C1AF80440218C2AF80440218C3D1 +:10C1B000AF80D5D8A4409656C907A440964EC9046E +:10C1C000A4009626C019446221EC46013135B4A67C +:10C1D00050000A5AFF46D01049FFD1FB5A08020D01 +:10C1E000460A5A5A500005A54413F063B606A6083D +:10C1F000540000FEAE0844121C6044621C788400A7 +:10C20000AC0844200100AC3044124C7084003C0F58 +:10C21000FB843C0FFB6F3C0FFB8749FFFF1A440078 +:10C2200002EE49FFD94F44224C70503100F0A01962 +:10C230003C2FFB539E44A09BB403964949FFFF3219 +:10C2400044027C0044124E00442014003C0FFB6169 +:10C250004401480049FFFEFD440002EE49FFD93287 +:10C260003C2DFB5304010010021100220421001395 +:10C2700049FFFF184412B800442008004401A00000 +:10C2800049FFFEE7440002EE49FFD91C3C2DFB5359 +:10C290000401000C0211001A0421000F49FFFF02E3 +:10C2A0004402B8008026FA5449FFFF253C0DFB5399 +:10C2B00044321C7C44221C7D0400000940102009EB +:10C2C0003E002A7D3E102A7E4010400992183E1002 +:10C2D0002A7F3E002A80A618A6509602964AAE589B +:10C2E000AE1044321C7E44221C7FA618A650960233 +:10C2F000964AAE58AE10640000094403F06144123F +:10C3000018CDA6009600AE084403F00E441218CED5 +:10C31000A6009600AE084403F00F441218CFA60002 +:10C320009600AE0849FFDE983C0FFB5C5A080107F7 +:10C33000440218CC441FFFAAAE404900025C3A6F89 +:10C340009E84DD9E84013C0FFB7EDD9E3C0DFB7FC9 +:10C350008C013C0FFB7FDD9E3A6F9ABCEFFC3C0DDD +:10C36000FB8B8C013C0FFB8B3C0DFB59A6005A0844 +:10C3700001272E07EB2F5A0055062E07EB255A08EA +:10C3800055153C03F5D88C019601E60A3C0BF5D80F +:10C39000E90F84013E000301840049FFBADB440039 +:10C3A000006949FFD560D50484003C0BF5D84400F2 +:10C3B00000553E07EB2F3E07EB25D50484003C0BD0 +:10C3C000F5D8EC043A6F9A84DD9E3BFFFCBCEFFC91 +:10C3D00084013C0FFB6C49FFD0C549FFBAB43C0D4A +:10C3E000FB59842249FFE08449FFBAC484208402B7 +:10C3F00084468061808180A149FFDE38EC043BFFE8 +:10C40000FC84DD9E3A6F9ABCEFFC49FFD506C01153 +:10C4100084013C0FFB84840049FFD5033C0DFB598C +:10C42000441279003C2DFB683C3DFB4749FFF03648 +:10C4300049FFD4EAC00784013C0FFB6F840049FF29 +:10C44000D4E7EC043A6F9A84DD9E3A6F9ABCEFFC15 +:10C450003C0DFB6784213C1FFB8AAE40440FFFAAC2 +:10C460003E07EB2F2E07EB0CC80A3C0DFB59A681AB +:10C47000542100FD5A20040449FFE03A84003E079D +:10C48000EB0C2E07EAE65A0801072E07EAEA8C01B0 +:10C490003E07EAEAEC043A6F9A84DD9E84013C0F81 +:10C4A000FB834403F081A600C00B3BFFFCBCEFFC08 +:10C4B0004400006949FFD4D7EC043BFFFC84DD9EB7 +:10C4C00084013C0FFB89DD9E84013C0FFB7CDD9EDB +:10C4D00084013C0FFB77DD9E84013C0FFB6BDD9EEE +:10C4E00084013C0FFB8EDD9E84013C0FFB75DD9EBD +:10C4F000DD9E84013C0FFB80DD9E3A6F9ABCEFFC11 +:10C500003C0DFB855A08010684203C1FFB85D502A3 +:10C5100084023E07EAD53C1DFB5984013C0FFB8792 +:10C5200084003C0FFB8CA6095A000D079E82E64250 +:10C53000E9035A08074AA6085A0801472E07EB5094 +:10C540009600C8423C1DFB67A6485A18013E3C1D98 +:10C55000FB4DA6485A1801393C0FFB882E07EAD834 +:10C560005A08010449FFDC882E07EAE65A08010848 +:10C570002E07EADD5A08010449FFDD542E07EADFE1 +:10C580005A08010449FFDC4A2E07EAE65A08010866 +:10C590002E07EAE35A08010449000F883C0DFB59B5 +:10C5A000842049FFDFA544127ADC3C0DFB1749FFCC +:10C5B000BAA2840149FFB9CE3C1DFB678400AE08D6 +:10C5C0003C1DFB4DAE08EC043A6F9A84DD9E3C0D99 +:10C5D000FB8C8C013C0FFB8CDD9E84013C0FFB76B9 +:10C5E0003E00022A4403F07E3BFFFCBCA640EFFC69 +:10C5F0005A10010FA6405A10020CA6405A10030907 +:10C60000A6405A100406A6405A101003A600844102 +:10C61000842080624400B10149FFCF8049FFCF945C +:10C62000EC043BFFFC84DD9E84013C0FFB6EDD9E31 +:10C6300084014413F0633C0FFB73A6089606C819E7 +:10C64000442221EC4615A5A550108A5AB6222E1078 +:10C65000022D5A1801094611313550108A5AB62256 +:10C660003E00022D4413F063A60858000001D51CBB +:10C67000A6089606C01A441221EC460A5A5A5000DF +:10C6800005A5B6012E00022C5A08010A4601515593 +:10C6900050000A5AB60184003E00022C4413F06395 +:10C6A000A608540000FEAE08DD9E84013C0FFB721C +:10C6B000DD9E84013C0FFB70DD9E3BFFFCBCEFFC6C +:10C6C00084013C0FFB8149FFEC985A08A106440005 +:10C6D000005549FFD3C8EC043BFFFC84DD9E3A6F54 +:10C6E0009ABCEFFC84013C0FFB783C0DFB888C016D +:10C6F0003C0FFB882E07EAD85A0801222E07EAE4ED +:10C70000C8052E07EAD749FFDC3D2E07EAE42E17BD +:10C71000EAD749FFDAFA2E07EAD72E57EAEB8C015F +:10C7200096003E07EAD7D80B2E07EAEA8C013E07AF +:10C73000EAEA2E07EAE48C013E07EAE4EC043A6FE9 +:10C740009A84DD9E3BFFFCBC8401EFFC3C0FFB6D3B +:10C750004400005549FFD387EC043BFFFC84DD9E79 +:10C7600084013C0FFB7ADD9E3BFFFCBCEFFC49FFE4 +:10C77000D390C00784013C0FFB79840049FFD38D1F +:10C7800049FFD37EC007840049FFD37E84013C0F5C +:10C79000FB8DEC043BFFFC84DD9E84013C0FFB859C +:10C7A000DD9EDD9E3BFFFCBCEFFC84013C0FFB717A +:10C7B00049FFCE1349FFB8C1C80449FFB8C4D50327 +:10C7C00049FFCDD2EC043BFFFC84DD9E84013C0F8D +:10C7D000FB7BDD9E84013C0FFB82DD9E3BFFFCBCAE +:10C7E000EFFC4400006949FFD33EEC043BFFFC84AE +:10C7F000DD9EFC452E002AF95A0001062E002AFB78 +:10C800005A08011A3C0DFB5C9E46E622E9048E099B +:10C81000E603E8113C0DFB59441290783C2DFB696E +:10C820003C3DFB683C4DFB583C5DFB4749FFC570F8 +:10C830005A00085049FFDA51490012884900118D09 +:10C840003C0DFB598421AE4149001502440000A073 +:10C8500049FFEBCE44027B0C3C1DFB59490011976C +:10C8600049000F1549000C4384013E07EAD149FFF6 +:10C87000D9EA440000A149FFEBBB3C0DFB5944122F +:10C8800079003C2DFB683C3DFB4749FFEE072E0736 +:10C89000EB245A08010A440278A74412795049FF50 +:10C8A000DDC949FFD3193C1DFB678402AE083C1D5E +:10C8B000FB4DAE0849000DE62E07EB245A08010691 +:10C8C00049FFD30349FFD30E490011E449FFDA0AB7 +:10C8D00044A2B8BC449299185085011451C4807880 +:10C8E0004473F04A44600055840E49FFEB8BAFB8A7 +:10C8F00049FFDD632E1002DA2E27EB52840AFE0C6C +:10C9000044100064420104732E1002D82E20030844 +:10C910008801441003E8420104733C08053849FFCC +:10C92000EDA92E002AF95A0001172E002AFB5A0001 +:10C9300001132E07EB605A080125440279003C1DC3 +:10C94000FB693C2DFB683C3DFB583C4DFB4749FFD8 +:10C95000EDEBD5173C0DFB59A6415A100D0D2E10CD +:10C9600002F9C909441279022E202B03443290782F +:10C9700049FFC8102E07EB1B5A0801DD48FFFF7660 +:10C980003C0DFB845A08013C84003C0FFB842E07BD +:10C99000EB5D5A0855163C0DFB473C1DFB59B61F75 +:10C9A000442278C444027B0C3C3DFB693C4DFB684F +:10C9B0003C5DFB5849FFEF523E07EB4AD5033E670B +:10C9C000EB5D2E07EB4A49FFEE8796003E07EB141E +:10C9D0005A08030448FFFF305A08021284003C0F33 +:10C9E000FB4E4463F04A447000553C0DFB67A600C3 +:10C9F0004E03FF3CAFF049FFFA68D5F83C1DFB67DA +:10CA0000A6085A08020C3C0DFB4DA6005A08020766 +:10CA10008401AE083C1DFB4DAE083C0DFB59A60140 +:10CA20005A000B0449FFDE283C0DFB4DA680969072 +:10CA30004E23FF5C2E07EAD85A0801213C2FFB4EFB +:10CA40004463F04A447000553C0DFB67A600C805DE +:10CA5000AFF049FFFA3AD5F94402951449000B8327 +:10CA60002E07EB4A49FFDA7A49FFCDB3C8038403A6 +:10CA7000D502840484214800019C44029514441288 +:10CA800078EAF28749FFDC2C2E07EB5EF2075A08A2 +:10CA9000020A3C1DFB4D84013E07EB5EAE0848FFD9 +:10CAA000FF212E0002245A08010E2E07EB4A49FFEF +:10CAB000DA5584023E00022484053E00022548FF28 +:10CAC000FF115A0802043E2002242E07EB245A08C4 +:10CAD0000107440278A7842049FFDC3C2E07EAE6E0 +:10CAE0005A0801074402951449FFD9CAD5BA2E073E +:10CAF000EB525A08030C2E002AFC5A08010849FF81 +:10CB0000BAED84023C1DFB1BD50649FFD304F08718 +:10CB1000F107840049FFDB2D3C0DFB59A6415A1853 +:10CB20000D098423AE41440000A349FFEA61D51EEC +:10CB3000440000A349FFEA5C2E002AFD5A080111B7 +:10CB40003C0DFB59A6405A18010CA6015A000609D3 +:10CB50002E07EB5EC8052E07EB2749FFD34C2E00AE +:10CB600002FDC00484003E0002FD2E602AFC5A68CB +:10CB7000010984003E0002FC49FFBEBD3E6002FC8C +:10CB800044029514441294AC442298584432B8009C +:10CB9000444294E849FFE6902E07EB4A5A080406FF +:10CBA00049FFE902480006C32E07EB4EE60EE808EF +:10CBB0002E07EB3DC80B3C0C00BBE613E9073C0C11 +:10CBC00001DD44126E7049FFCB823C2C01E38400EE +:10CBD0003C0FFB9080224442A3A00A31000138326E +:10CBE00001098C015A0824F9501084C88400442299 +:10CBF000A3580A308001383101098C015A0824FBFE +:10CC00002E17EB243C0FFB905A180106440278A71C +:10CC100049FFDBA0440294ACB61F3C04159E4412AD +:10CC200078A9F0834402B9E4F08444229078840027 +:10CC3000443294E844427ACC4452970C14AF8001B9 +:10CC4000148F800249FFD497840044127ACC442286 +:10CC5000970C44327AF04442972449FFD47A2E004C +:10CC60002AFE5A08010C3C0C01DD3C1C01DF3C2C67 +:10CC700001E2443295BC49FFE8062E0009904412B7 +:10CC8000970C3E0002CF442297244402951449FF9A +:10CC9000E72D3C0E05603C0004C65CF00104E8048E +:10CCA00084013E07EB3C3C0C01E3A440964BE43589 +:10CCB000E90702100012964B5EF0FFF6E90BA44262 +:10CCC000964BE435E90902100014964B5EF0FFF62E +:10CCD000E8038421D50284203E17EB6AA440964BDA +:10CCE000E435E80EA440964BE435E80AA442964B9E +:10CCF000E435E806020000119603E415E9073C005C +:10CD000003875CF000658401E80284003E07EB675E +:10CD10002E07EADE5A08012E4402951449000978CC +:10CD200049FFCC5780208403C1038404842049FF39 +:10CD3000D9553C0DFB4D8421AE402E67EAE95A607F +:10CD4000010448FFFDCF80263C0DFB5949FFDBD095 +:10CD5000800649FFDDB649FFDDCBF08784408402C1 +:10CD6000F1078066808280A249FFD98048FFFDBA22 +:10CD70002E67EAE55A68012184003E07EAE53E078E +:10CD8000EAD42E07EAE049FFD9AA49FFE80D2E00B0 +:10CD90002A6B5200000149FFD9A23C0DFB4DAF8028 +:10CDA00049FFCC1780208403C1038404842049FFF9 +:10CDB000D91548FFFD972E07EB245A0801074402B6 +:10CDC00078A7842249FFDAC62E002AFC5A080108F7 +:10CDD000440294E84412949449FFBCB649FFCBF94D +:10CDE0005A08020B4402951444129078442294503D +:10CDF00049FFD231D50484003E0002D884203C1F74 +:10CE0000FB903C3C01E2440299C0FA825A100A1E8F +:10CE100004207FD25A20030B04207FF48E42E64286 +:10CE2000E905B4408E42E642E80C00500031002093 +:10CE300000324222907394918843A49012207FBDC7 +:10CE40008C21500000FCD5E33C0C01E23C1FFB9020 +:10CE500049FFF3C984003C0FFB903C1C01E33C6C90 +:10CE600001E28040FAE2444295BC98F240F088002A +:10CE700003E1800040301CB7383215018C01887EF8 +:10CE800096DB12378000503104C840F08C00886671 +:10CE900038521501A4D88C42886596DB1237800081 +:10CEA0005A0824E58401A4893C0FFB9002008013FA +:10CEB00096939603E040E805020080139603AC09C0 +:10CEC00084023C0FFB903C1C01E33C2C01EE3C0C2B +:10CED00001E249FFF56A3E0003083C1C01EE3C0CF0 +:10CEE00001E249FFC9F449FFCB74C0073C0C01E2E1 +:10CEF0004412945049FFE0BF3C1C056084005A1066 +:10CF00000104480000F63E07EB4B2E17EB0D4402E0 +:10CF1000951449FFD42D3E0002262E002AFC5A000B +:10CF200001062E002B025A0801064402B99C49FF53 +:10CF3000C1312E000308C0073C0C01E34412945099 +:10CF40008441D5073C0C01E3441294503C2003A4D7 +:10CF5000443278D549FF9AF6840044127A9880408A +:10CF6000382080088C015A0806FD84003C0FFB9095 +:10CF7000FAC23C0DFB902E17EB35E201E8453C2C44 +:10CF800001AD944138510101D8393C2C01B03C3CF1 +:10CF900001AF8841FA84A651A69080A13801811181 +:10CFA00042511873443295BC49FFE6793C2DFB9001 +:10CFB0003C3C01AD94518823A4C8FE1FAC083C0C36 +:10CFC00001AF3C1004B738000901E220E80C5CF026 +:10CFD000003CE8092E17EB585CF080FAE8048C213D +:10CFE0003E17EB58961049FFF5E92E07EB675A08F4 +:10CFF00001062E07EE4049FFF6F83C0DFB908C0130 +:10D000003C0FFB90D5B75A1002072E002B015A088F +:10D010000161D54584003E07EB6B3E07EB6684005B +:10D020003C0FFB9084C13C0DFB902E17EB35E201C9 +:10D03000E8ED3C1C01AD950138508101D82A2E073E +:10D04000EB6B5A0801182E17EB663C0C01B094C923 +:10D0500088608880A698A6209A828C41E643E80AD8 +:10D06000A6A1A6198A408C42E645E804962849FF05 +:10D07000F6CD3C1DFB903C2C01B094098802A680A3 +:10D08000CA08A601E603E8053E67EB6B3E17EB66B0 +:10D090003C0DFB908C013C0FFB90D5C63C0DFB6911 +:10D0A000A40096065A0001083C0DFB58A6009606FF +:10D0B0005A0801102E07EAC9C80C440294504412C1 +:10D0C0009514442278D549FFD47D3E0002DAD50676 +:10D0D00084003E0002DA49FFD38F2E0002DA5A089C +:10D0E000010584003E00022449FFF609D51D3E00DB +:10D0F000030B3E00030A3E0003102E0002DA5A081A +:10D10000010649FFD35F3E0002DA49FFD371840074 +:10D110003E07EB353E07EB582E07EB4BE60AE804DB +:10D120008C013E07EB4B2E07EB245A080107440203 +:10D1300078A7842349FFD90E84003C0FFB903C0D57 +:10D14000FB902E37EB35E203E81C3C1C01AD385058 +:10D150008101D8134412945096A83C0C01E3443248 +:10D16000907849FFF3F83C1DFB903C2C01AD9449AD +:10D170008822A488FE17AC083C0DFB908C01D5DEFC +:10D18000CB043E37EB62D50D440294503C1C01E2C7 +:10D190003C2C01E344426BD84452790249FFB2F17E +:10D1A0002E0002DA2E1002255A000103C1078E213B +:10D1B0003E10022584203E17EB622E17EB62C1451C +:10D1C0002E302A922E402A939261928144026BD88B +:10D1D0008440E241E80BA5408C4188A3AD40A541C5 +:10D1E0008C1888A412507FF5D5F52E002B053C2F06 +:10D1F000FB905A0801092E00063CC80544026BD872 +:10D2000049FFAF533C0C00B98C013C0E00B98400BF +:10D210003C0E00BA3C0E00BB3E07EB5C3E07EB4EFB +:10D220003C0DFB59A6015A0803048400D5085A088E +:10D230000A5D2E07EAF55A08050684013E07EAF55D +:10D24000D5545A080453D5F2C85084213E00030A2D +:10D250003E07EB403E17EB373E07EB353E07EB62F0 +:10D260003C0E00BD3C0E00B93C1C00BA460005B89F +:10D2700050000D80E201E9048C213C1E00BA3C1CE8 +:10D2800000BBE201E9142E07EB543C23FEC9E20285 +:10D29000E8083C23FEC8E202E8042E07FD9AC00518 +:10D2A0008C213C1E00BBD5033C0E00BB2E07EB17A8 +:10D2B0005A08010C2E07EB4EE60FE80A2E17EB4B2F +:10D2C0005A180A078C01D50284003E07EB4E2E0740 +:10D2D000EB125A0801083E07EB2E84003C0E00BA00 +:10D2E000D50484003E07EB2E2E07EB384E03007B5F +:10D2F0002E0002DAC8282E07EB62C8252E07EB6342 +:10D30000C822440295144412985849FFD1EB2E07C5 +:10D31000FD9A5A08010B3C0C00BB5CF000C8E90503 +:10D3200084013E07EB63D50F49FFD1BF5A0002FAD3 +:10D33000440298584410012C442278FC49FFE235FD +:10D340005A0002F03C0DFB59A6412E07EB635A1020 +:10D3500006045A180B115A0001092E0003055A0041 +:10D3600001052E07EB5CC03E84013E07EB2E3E0715 +:10D37000EAF4D5385A00010A2E0003055A000106C6 +:10D380002E07EB6A5A08022084003E07EB6A8400ED +:10D390003C0FFB4E4463F04A447000553C0DFB6764 +:10D3A000A600C805AFF049FFF590D5F984008421A7 +:10D3B0003E07EB633E0003053E1003063E07EAF519 +:10D3C00048FFFA542E07EB4E5A080F0D84003E0713 +:10D3D000EB3B3E07EB4E3C1C01DF44026E7049FF05 +:10D3E000C7762E0002DA5A08010784003C0E00BA04 +:10D3F0003C0E00BB2E002AFC5A08010A4402BC0065 +:10D40000501000305020005849FFB9DA440290789B +:10D410002E17EB622E27EB3C2E37EB5849FFDCE949 +:10D420003C0C01EE2E27EB6DB61F2E17EB6244026B +:10D430006BD8C20744229908443294508480D506A0 +:10D44000442299084432945084814452907849FF90 +:10D450009B3B2E07EB245A080107440278A784243B +:10D4600049FFD7782E002B0B446299085A08010A0D +:10D470008006441294503C2C01E249FFEF68D5131A +:10D480002E202A6980068420E222E80BB460C305BE +:10D49000A4C2ACC6A4C3ACC78C21500000FCD5F517 +:10D4A0003C1FFB902E07EB622E17EB1D9A4196480E +:10D4B0004402990849FFACD649FFC88BC80D2E0716 +:10D4C000EB283E07EB1D2E002AFB5A000104480002 +:10D4D00001634800014E3C0DFB5849FFDCD9441262 +:10D4E0009450440299084900071B3E07EB6444121C +:10D4F0009450440299084900079244029908441242 +:10D5000094503C2C01E249000BE244029908441279 +:10D5100094503C2C01E24900081484003E07EB289B +:10D5200084003C0FFB903C0DFB90E60AE8C94410D8 +:10D5300000FCFE4498F1B4034E0201165021808095 +:10D54000A6124E0200F5A7164E4200BB002180E64F +:10D55000440299105A280309502000103800040290 +:10D5600038110402D5064024840038000402A0517A +:10D5700049FFA627842049FFDC5796C15CF18097BC +:10D580003C1DFB90E90D440000FC80464220807366 +:10D59000500100808440AE82AE8644300096440044 +:10D5A00000FC804642208073005100E680025271E8 +:10D5B00080968C48C56CE6A2E94722F0000484807E +:10D5C0005EF7821CE903444004375A58022C442079 +:10D5D00000FCFE8C983284A3105000E650500010DE +:10D5E00002F2800245E298A412F0000C02F28003DD +:10D5F000F489F388F58712F0000D38FF0601944A8C +:10D60000883E40048800A449885C41E0C008A0012D +:10D61000A051402F3C0449FFDF54F507F409F308FB +:10D62000AC2B3C1DFB90440000FC804642208073E4 +:10D6300022110004FF3C42408C734410009640428B +:10D640000496AD14D50D2210000A22200004FE7CA1 +:10D6500042110C734420009640108836AC443C1DA7 +:10D66000FB90440000FC80464220807380025011F1 +:10D6700000082200000B22208001FFC442710C73BD +:10D6800044000096407380F6ADC9D53950500088EB +:10D690002212800222400004FE7C42120C7344409D +:10D6A000009640109036AC44221280032201000103 +:10D6B000FFCC42700C73407390F6ADD1D520501161 +:10D6C000808822F08002225180045270000A42F0C9 +:10D6D0003C245041800842F3947384AA40F795F6A5 +:10D6E0002210800312F1800422320001FE44421312 +:10D6F0008C73401094368E01AC61AE123C1DFB90D1 +:10D70000440000FC804642208073223100044E34E5 +:10D7100000048460ACD480464220807380028C0870 +:10D72000221000014E1400048420AC413C1DFB90EB +:10D73000440000FC804642208073800204210022C5 +:10D740005A2801060400002E5A00010E2E07EB286D +:10D7500080468C013E07EB28440000FC4220807389 +:10D760008420B6223C0DFB908C0148FFFEDC2E008D +:10D7700002F95A0801114402907849FFCE68C80B9B +:10D7800044029450441299082E27EB6244327AF4F2 +:10D790004900045584003C0FFB913E07EB423C0FCF +:10D7A000FB902E402A693C6C01AE802044229924D3 +:10D7B0008060447000FFE264E81B04517FF9CD03F0 +:10D7C00080A1D511A152385315015CF28100E80700 +:10D7D000E6B5AD50E9058C019600D502ADD0A15754 +:10D7E000E2A1E9EF8C61502100FC8025D5E53E07E0 +:10D7F000EB422E07EB623C3FFB903C1FFB91C023AA +:10D800002E07EB525A0803202E0002FB5A00010596 +:10D8100044000090D503440000413C1DFB913E07AD +:10D82000EB71E2202E0002CEE805E61EE80C8C012A +:10D83000D508C0095CF09900E9038400D5028E0187 +:10D840003E0002CE49FFC6C55A08020C44029908A0 +:10D850002E17EB62442294503C3DFB9149FFCE3C95 +:10D860003C0DFB59A6015A00030749FFA0D1E6036E +:10D870004EF300983C0DFB6F5A08010984003C0FE1 +:10D88000FB6F44027B1449FFA0AB2E07EB4A5A0002 +:10D89000050A4402965C44127B3049FFA3AD3E0763 +:10D8A000ED7A49FFA0B880C05A08015649FFA0B0E0 +:10D8B0005A080305800649FFA0A849FFA0A95A08F5 +:10D8C0000405840149FFA0A13C0C05603C0E0561E4 +:10D8D0003C00038B3C0BF5D22E07EB623E07EB5668 +:10D8E00049FFA08AE602E94249FFA0865A00FF3FAD +:10D8F000FA0E3E00031049FFA07FC03D2E07EB0D3E +:10D90000E619E8048C013E07EB0D2E002AFC5A00B4 +:10D9100001392E07EB5EC0048E013E07EB5E2E0739 +:10D92000EB4A5A08050448FFF93D3C0DFB4D8421A4 +:10D93000AE402E002AFB5A00010448FFF7D33C0DED +:10D94000FB59A6015A000A0448FFF7CC49FFD9FD4C +:10D9500048FFF7C849FFA05C5A0803B884003C0E92 +:10D9600000BA84013E07EAF4D5B02E000310C0C40B +:10D970008E01D5C03E07EB0D84013E07EABBD5C63C +:10D980003C0DFB59A6015A0006C65A000BC42E07CF +:10D99000EB5EE602E8BF49FFB77449FFBB4CD5BA5E +:10D9A00084003E07ED783E07ED793E07ED7AD58D90 +:10D9B0003A6F98BC40608C0390DF4E340006FEDA6C +:10D9C000C203FE929ED94E140006FE4AC003FE0218 +:10D9D0009E4984804900003AC60840408004C4053E +:10D9E000FE4AC003FE029E493A6F9884DD9E920073 +:10D9F00040A14009974192104040A83796D140106D +:10DA0000C008FE4742020C24E220E8099F21984A00 +:10DA1000E222E905E220E8039F21984A9A48401053 +:10DA2000A81740004008FE2FFECCE203E809980248 +:10DA30009E49E202E905E203E80398029E499A033F +:10DA400040424008FE67DD9EEFD83A6FAAA0FD3045 +:10DA5000FD418384CB51E2E8E81A8008490000CCFC +:10DA6000F087C00C4084000C525000204053140D2D +:10DA70004073800CFFEF4063000CFD03804849FFBA +:10DA8000FFB9F18880C084A0F589D525C22C800813 +:10DA9000490000B2F087C8058AE884A1F589D51449 +:10DAA00052F000204084000C804840433C0D40531D +:10DAB000800C4063000C400290044013BC0D49FFF1 +:10DAC000FF99F18980E0FD03804849FFFF93F188C9 +:10DAD000506000004FC20055F307447000004063DF +:10DAE0000C0DD54C407420D7842084004FC2004CCC +:10DAF000B6DCBF81D548E2E9E9F880094900007C3D +:10DB0000F087C045524000204054100D4024800C46 +:10DB1000FEAF81224084000C4033100D4063000CA6 +:10DB20004003800C4013900DFE1F49FFFF63F188F6 +:10DB300080E0800849000070E2E1E9054C13C00D67 +:10DB4000E2C0E80AF3088A299ED9F3884030200110 +:10DB5000E2038A2F80038460F3894FC200129A3057 +:10DB60009A79E2C08A2FF307524180204070900CCE +:10DB700040600C0DFFBF40708C0DB6DCBF81F0081B +:10DB8000041F80093A6FAA80EC28DD9E8460E32799 +:10DB9000E903E2C8E90A84A1F588404320018AE943 +:10DBA000E2C48AEF80C4D502F388F3894FC3FFE74C +:10DBB000D5E79200425088244010400942500C732F +:10DBC000960140314009969142F00C2442400824CD +:10DBD000FE8C40078800E20240F7C0084020400861 +:10DBE00042F08C7340104009882F9822E204882F5D +:10DBF000984DDD9EC00EFA20FA6F9B194020040D4F +:10DC00004032081B4001081B9221C9F88003DD9EA9 +:10DC1000FA10DD9E968140304009960992304251BB +:10DC20000424FE84FE1C9968E2A040F7C00842F17B +:10DC300084734012C009882F4002C0089802E20293 +:10DC4000882FDD9E8060C207994A084080011841F4 +:10DC50008001D9FCDD9E92008060995AD30418118E +:10DC60008001D5FDDD9E92000F10FF000D0EFF001C +:10DC70000002080000040404040608060108210547 +:10DC8000060604070104040601042206040405062E +:10DC90000601010806060506070104220404012204 +:10DCA00006040501050701044E00560060006B00E4 +:10DCB000760083009100A000B100C200D600EB0006 +:10DCC00002011A013501520170019101B501DB0118 +:10DCD00003022E025C028D02C102F80232036F03BE +:10DCE000B003F4033B048604D40426057C05D50563 +:10DCF00032069206F5065C07C6073308A308160924 +:10DD00008C09040A7E0AFA0A790BF80B790CFB0CD1 +:10DD10007E0D010E830E060F870F0710861003116C +:10DD20007D11F5116912DA124713AF13131472142F +:10DD3000CB141E156B15B215F2152C165E1689162E +:10DD4000AC16C716DB16E716EB164E005600600041 +:10DD50006B00760083009100A000B100C200D600E5 +:10DD6000EB0002011A013501520170019101B50168 +:10DD7000DB0103022E025C028D02C102F8023203B3 +:10DD80006F03B003F4033B048604D40426057C052A +:10DD9000D50532069206F5065C07C6073308A308C8 +:10DDA00016098C09040A7E0AFA0A790BF80B790C19 +:10DDB000FB0C7E0D010E830E060F870F07108610D9 +:10DDC00003117D11F5116912DA124713AF13131401 +:10DDD0007214CB141E156B15B215F2152C165E16A7 +:10DDE0008916AC16C716DB16E716EB164E00560062 +:10DDF00060006B00760083009100A000B100C200BB +:10DE0000D600EB0002011A013501520170019101A7 +:10DE1000B501DB0103022E025C028D02C102F80291 +:10DE200032036F03B003F4033B048604D4042605D5 +:10DE30007C05D50532069206F5065C07C607330851 +:10DE4000A30816098C09040A7E0AFA0A790BF80B52 +:10DE5000790CFB0C7E0D010E830E060F870F071049 +:10DE6000861003117D11F5116912DA124713AF13F1 +:10DE700013147214CB141E156B15B215F2152C1653 +:10DE80005E168916AC16C716DB16E716EB16800071 +:10DE90008D009A00A900B900CA00DC00F00005015D +:10DEA0001C0135014F016B018901A901CB01EF0173 +:10DEB00015023E0269029602C602F8022D036503AE +:10DEC0009F03DC031C045F04A504EE0439058705E9 +:10DED000D8052C068306DC0638079607F7075A088C +:10DEE000C00827099109FC09680AD60A460BB60B37 +:10DEF000270C980C090D7B0DEC0D5C0ECC0E3A0F27 +:10DF0000A70F13107C10E2104611A71105125F1223 +:10DF1000B512081355139E13E31322145B149014C7 +:10DF2000BE14E714091526153C154C155615591540 +:10DF3000BD64646464646464646464646464646448 +:10DF4000646D000000006464646464646464646418 +:10DF500064646464645B00006D6464646464646449 +:10DF60006464646464646464646D00005B64646439 +:10DF7000646464646464646464646464645B000032 +:10DF80000B0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CD2 +:10DF90000C0C00003B436364646464646464646404 +:10DFA000646464645F370000000052646464646405 +:10DFB00064646464646464646459000062646464F6 +:10DFC00064646464646464646464646464620000DB +:10DFD000335F646464646464646464646464646437 +:10DFE0005F3300003C0FFB95DD9E3C0FFB94DD9EF4 +:10DFF000FC00C0085A08010B490004A73C0FFB971E +:10E00000D5054900049F3C0FFB96FC808020E62943 +:10E010003C0DFB97E82544F0DF243817840040F0DE +:10E02000BC00DD0F0A3C10161C22282E34003C0DCB +:10E03000FB96DD9E50000050DD9E500000A0DD9E4E +:10E04000500000F0DD9E50000140DD9E500001E0D8 +:10E05000DD9E50000280DD9E50000320DD9E840086 +:10E06000DD9E92003C0FFBE0DD9E3C0FFBDFDD9E62 +:10E070003C0FFBE3DD9E3C0FFBE2DD9E3C0FFC28EA +:10E08000DD9E3C0FFC27DD9E3C1DFC2844027DB834 +:10E090003C0FFBF2A64D84008E2196483E17EFCE32 +:10E0A0003E17EFCF84213E07EFCC3E07EFCD3E0772 +:10E0B000EFD03E07EFD13E07EFD23E07EFA13E077C +:10E0C000EFA03E07EFA23C1FFA6E3E07ED7B441225 +:10E0D0007D748400845F382080088C015A0841FDDB +:10E0E000DD9EFC0049FFCFEFFC80FC21841F100F58 +:10E0F000800749FFCFF0C810500F8007844044408C +:10E10000003F44127D74846149FF9CEB848080044D +:10E1100044227D74D50A4463F04A4470005549FF97 +:10E12000CFDAC0EBAFF0D5FC381110008C8188013C +:10E1300096005A4840FB8441FE0244121C00806253 +:10E140003E07F01444027D7449FF9CCB84013E07D6 +:10E15000ED7849FFCFC8FCA13C0FFEC1DD9E3C0F0E +:10E16000FEC0DD9E3C0FFEC2DD9E3C0FFEC3DD9E69 +:10E170004433F405AE984423F406AE504413F4043B +:10E18000AE08DD9EA640A6853E100AE4A6414021C9 +:10E1900020083E100AE5A642A6C63E100AE6A6439F +:10E1A000004000083E100AE7A6448841A64796931F +:10E1B0004010A008882300300009964B4031A00889 +:10E1C00088643C3805760030000B0040000A40317E +:10E1D000A00888643C3805770030000C3C280574A2 +:10E1E0003E300AF00030000D3C1805753E300AF153 +:10E1F0000030000E96C63E300AF20030000E9261EA +:10E2000096C63E300AF30030000E926296C63E304B +:10E210000AF40030000E926396C63E300AF50030D4 +:10E22000000F3E300AF6003000110040001040316F +:10E23000A00888643C38057C0030001300400012C0 +:10E240004031A00888643C38057D0030001500404E +:10E25000001496CF4031A00888643C38057E003019 +:10E26000001592623E300AFE003000170040001692 +:10E2700096CF4031A00888643C3805800000001724 +:10E2800092023E000B0240012C0A9606C006440F83 +:10E29000F000FE873C2805744000AC0A9606C006D4 +:10E2A000440FF000FE473C180575DD9EA4C04422D3 +:10E2B000936C44120000FECFB662A4C2504100200D +:10E2C000FECFA8D2A4C4FECFA8D1A4C6FECFB66408 +:10E2D00002300008FECFA8E10230000AFECFA8E21B +:10E2E0000230000CFECFA8E30200000EFE47A86437 +:10E2F000DD9E4413F40BAE08DD9E4413F407AE0814 +:10E300004413F408AE08DD9EFC004403F537842472 +:10E31000AE40840080208040806049FFCEFCFC80BD +:10E320005A0804053C0C0175D5033C0C017302002E +:10E330000013844C4200887344120000FE0F00005A +:10E340000008DD9E5A0804053C0C0175D5033C0C01 +:10E35000017302000013844C4200887344120000D1 +:10E36000FE0FA001540003FFDD9EFC002E000AE713 +:10E3700084C05A08010384C38026840349FFFFD266 +:10E380003E07EB318026840349FFFFDE3C0BF5DAC4 +:10E390008420840449FFFFC63E07EB2D84208404BB +:10E3A00049FFFFD23C0BF5DDFC80B44084A08C44D7 +:10E3B0009C2EA2D196005A58200680A05A0824FA12 +:10E3C000DD9E5441801F384094088CA19768926567 +:10E3D000D8F3D5F4B460505080108001A09F544110 +:10E3E00000031840000192424C02FFFB0401800828 +:10E3F0005010802054200003182280019202D9FB83 +:10E40000DD9EFC404462936C8423B40684E13C0F9F +:10E41000FB044403F40B8520AE404403F40544138D +:10E42000F407AFC04403F406AFC04403F4041090F3 +:10E4300000008402AE084413F408AE0849FFFF66EA +:10E440004403F01E109000004403F420AFC049FFC5 +:10E45000B1B64900008A80064412940849FFFFA71C +:10E46000441293A0800649FFFFB7490000BC840115 +:10E4700049FFB6E449FFB726FCC0FC0084263E17DE +:10E48000EAC72E102B2884003E17EB48441000FFEB +:10E490003C1BF5BC3C1015B23E07EB523C1BFD8EFD +:10E4A0003C1015B33E07EB3F3C1BFD8F3C1015B4F1 +:10E4B0003E07EAC53C1BFD903C1015B53E07EB1A24 +:10E4C0003C1BFD913C1015B63E0002FD3C1BFD922D +:10E4D0003C1015B73C1BFD933C1015B83C1BFD943C +:10E4E0003C1015B93C1BFD953C1015BA3C1BFD9624 +:10E4F0003C1015BB3C1BFD973C1015BC3C1BFD980C +:10E500003C1015BD3C1BFD9984213E07EB453E1791 +:10E51000FB3884203C1BF5BD3E17EB1F842F3E07C4 +:10E52000EB183C1FFB1B3E0002CE441000323C04A3 +:10E5300005803E17EB5484223E17EAD04010240A8F +:10E540009646C104441FFC00FE0F3C0BF5D63C046C +:10E55000057E4010240A9646C104441FFC00FE0FAD +:10E560003C0BF5D4FC802E002AFC5A080118FC0054 +:10E570002E002B86490000712E002B874900007267 +:10E580002E002B88490000782E002B894900006F4F +:10E5900044004A5C49000075FC80DD9E3C0FFF672B +:10E5A000DD9E3C3DFB0402218012003180499691A2 +:10E5B000AEC03C0DFB04B40092039637AE082E07A4 +:10E5C000EB52C80F4412000040010404A0045400A0 +:10E5D0000FFF96033C0BF5BB3C0BFD9A3C0815B1B5 +:10E5E000DD9EFC0084033E07EB5284812E07EB5036 +:10E5F00044527ADC2E17EB462E27EB0B2E37EB2CF2 +:10E6000049FFA9182E07EB1FC80A44027868441274 +:10E61000786449FFFFC884013E07EB1F84003E0772 +:10E62000EB5284812E07EB5044527ADC2E17EB46D6 +:10E630002E27EB0B2E37EB2C49FFA8FC2E07EB18EF +:10E64000C80A440278604412786149FFFFAC840133 +:10E650003E07EB18FC804413F3C59600AE08DD9E20 +:10E660004413F3C69600AE08DD9E4413F3C796002C +:10E67000AE08DD9E4413F3C89600AE08DD9E441339 +:10E68000F3DE9681AC888002DD9EFC204472B800E7 +:10E6900084C02E0031988CE4E2C0E80F0203839C12 +:10E6A0000013873A2E203199846149FFBF378CC10E +:10E6B0001003873B97B0D5EEFCA04423F054AC1078 +:10E6C0004403F056AC40DD9EFC004403F5878423F0 +:10E6D0004423F583AE408402AE104423F59FFA70C4 +:10E6E000AE504423F59B4443F58CAE104423F5AD66 +:10E6F00084A5AE504413F5A9845FAE084403F581A8 +:10E700004413F580AE804403F585AEC08401AE08A5 +:10E710004413F588AE084413F589AE084413F58A0E +:10E72000AE084413F58BAE088420AE604443F58DEB +:10E73000AE604443F58EAE204443F58FAE20444393 +:10E74000F590AE204443F591AE204443F592AE20BF +:10E750004443F593AE204443F594AE204443F595ED +:10E76000AE204443F596AE204443F597AE20444393 +:10E77000F53FAF604443F08CAE204443F599AEA022 +:10E780004443F59DAEE04443F598AE204443F5A0E4 +:10E79000AE204443F5A1AE604443F5A2AE2044430D +:10E7A000F5A3AE204443F5A4AE604443F5A5AE60A6 +:10E7B0004443F5A7AEA04443F5ABAEE04433F5A621 +:10E7C0004443F584AE184433F5AEAE184433F5AF88 +:10E7D000AE184433F5B0AE184433F5B1AE18443337 +:10E7E000F5B2AE584433F5B3AE584433F582AE9823 +:10E7F000FA71AEE04443F586AE204443F59AAEA0EC +:10E800004443F59CAEE04443F59EAE204443F5A856 +:10E81000AEA04423F5AA4443F51AAED04423F5AC88 +:10E82000846AAE104423F56BAED02E200AF4443334 +:10E83000F51BAE605A28011D4403F51CAE58AE808E +:10E840004403F51DAE404403F51EAE404403F51FDE +:10E85000AE404403F514AE404403F515AE404413F6 +:10E86000F518FA14AE084413F519AE08D51DAE1804 +:10E870004433F51CAE184433F51DAE184403F51EA1 +:10E88000846CAE404403F51FAEC04403F514AE40A3 +:10E890004403F515AE404403F518FA34AE40440382 +:10E8A000F519FA2BAE404403F56A8421AE404413B7 +:10E8B000F5B4840FAE084413F5B54433F516AE082D +:10E8C0004413F5B68403AE084413F5B7AE084413F9 +:10E8D000F5B8AE084413F5B9AE084413F517840033 +:10E8E000AE18AE084403F5BA5A280104AE80D50329 +:10E8F0008422AE404403F566842E4423F567AE407F +:10E900008402AE104423F568AE504413F5694423E5 +:10E91000F340AE088438AE504423F524AE5044236F +:10E92000F525AE504413F523844AAE884413F344CE +:10E93000AE08840080208040806049FFCBECFC80E2 +:10E9400044023E6CDD9E44021E00DD9EFC2044031A +:10E95000F0C03C0FFAF74403F0D44410021CAC4062 +:10E9600084003C0FFB4E4463F0F44473F04AA6303D +:10E970009600C00744000055AE3849FFEAA6D5F816 +:10E980004413F0C28441AE884413F0CC44200036D6 +:10E99000AE884413F0E8AE084413F069AE08FCA05A +:10E9A00092084413F0D49601AC08DD9EFC0084006C +:10E9B00049FFC2AF44020BFC3C0FFB08440211109C +:10E9C00044227ACC3C0FFB004402163484213C0FD5 +:10E9D000FB0A8400AE50AE51AE12AE13AE14AE556B +:10E9E000AE164422970CFA7DACD1ACD24430003242 +:10E9F00012310008443000641031000AFA644450B7 +:10EA00000078848A10310012FA64AE561011000E9C +:10EA1000AD56AD141001000B1231000A44227AF0F9 +:10EA20004460005FAE50AE1144223BFC3C2FFB051E +:10EA300044223C083C2FFAF944223C143C2FFB0DA5 +:10EA400044227B34AE50AE51AE12AE13AE14AE556E +:10EA5000AE16442294941001000EAD91AD92ACD448 +:10EA600010310012446000648463AE5612610008E5 +:10EA7000AD561001000B1041000A1231000A442269 +:10EA80007AFCAE50AE11FC803C0FFF69DD9E3C0F5E +:10EA9000FB29DD9E3C0FFF6DDD9E3C0FFF6CDD9E74 +:10EAA0003C0FFF6BDD9E3C0FFF7ADD9E4402911808 +:10EAB0008420AE40AE41AE42AE43AE44AE45AE461B +:10EAC000AE47DD9E3C0FFF80DD9E3C0FFB2BDD9EA5 +:10EAD0003C0FFB2ADD9E3A6F9ABCEFFC3C0FFF8295 +:10EAE00049FFCB4B3C0FFB2C49FFCB475000028822 +:10EAF0003C0FFB2DEC043A6F9A84DD9E50200024DD +:10EB000044123D44A85144123C1CB62244123CB06D +:10EB1000A85244123DD4A85544123D40A856441270 +:10EB20003CACA85444123DD8A85344123E68A857A0 +:10EB3000DD9E4413F302A6089600E41EE808A6082A +:10EB40004413F01F8C029600AE08DD9E4403F01FB4 +:10EB5000FA2FAE40DD9EFC008400802049FFFDAF0F +:10EB600049FFFEF649FFFC4F49FFCC6949FFFFE32F +:10EB700049FFFF1E49FFFDAA49FFBACB49FFC1B9B2 +:10EB800049FFBC3349FFE9B6FC80FC403C0DFB5C0F +:10EB900080C15A0804102E002AFBC00C840249FFD1 +:10EBA000DA31840349FFDA2E3C0DFB5C5A08042A53 +:10EBB000D5174473F04A4490005549FFBD0A5A00E6 +:10EBC00002EF840149FFDA1E8420846110938000E3 +:10EBD00084028041808180A349FFCA48D5EF49FF64 +:10EBE000BCF85A00020F2E702AFB5A78010B8007DE +:10EBF00049FFBDDF840049FFA6AD800749FFBCB2D5 +:10EC000084003C0FFB4E4473F04A449000553C0D89 +:10EC1000FB7BC00C840549FFD9F5840649FFD9F276 +:10EC20002E00022E5A080128D50D49FFBDC65A08EC +:10EC300001F3840449FFD9E61093800049FFE945B8 +:10EC4000D5E73C0DFB5C5A08041749FFBCC25A00CB +:10EC500002132E002AFB5A08010F49FFCB5A8400E9 +:10EC600049FFB4DF3C0DFB59842049FFCC418402AD +:10EC7000AE31D51380468405842049FFB4FF3C0D96 +:10EC8000FB59842049FFCC348402AE31840149FF12 +:10EC9000BFA0840749FFD9B6FCC03C0FFB37DD9EFF +:10ECA0003C0FFB27DD9E502000202E100AE75A1053 +:10ECB00001048420D5028423181000014C017FF741 +:10ECC000DD9E3C0FFF8BDD9E3C0FFF8ADD9E3C0DE1 +:10ECD000FF8BA4413C1BFF0DA444A6003C1BFF0C72 +:10ECE0003E07FE16DD9E3C0FFB39DD9E3C0FFB38D8 +:10ECF000DD9E3C0FFB3ADD9E3C0FFB3BDD9E3C0E58 +:10ED00000059DD9EFC0049FFC9DE84203C0E0063F3 +:10ED1000101000501010005110100052101000532D +:10ED20001010006010100061FC803C0E0064DD9E3D +:10ED30003C0FFB3DDD9E3C0E0079DD9E3C0E0078D5 +:10ED4000DD9E3C0E0087DD9EFC402E302A622E1098 +:10ED50002A922E202A6342008C243C0815392E006A +:10ED60002A9392214240082492013E002A9A2E00C2 +:10ED70002A6A3E202A703C48153A3E102A993E30B5 +:10ED80002A6F4422B800C00284013E002AF844528F +:10ED9000B800444F64784412B82498EC080280010B +:10EDA0009602AE18D9FB44521C9C443DEAD844025A +:10EDB0001CA4986B3811041018128001D8FB44323F +:10EDC0001C7C44221C7DA618A6509602964AAE587A +:10EDD000AE1044321C7E44221C7FA618A650960218 +:10EDE000964AAE58AE102E102A632E002A6284C0B6 +:10EDF000FE0C3C08154A44024E203C6FFB5B49FF69 +:10EE0000FA573C0C0173442218CA44321C5E3C0F72 +:10EE1000FB4F44121C5C440218C8444218C4AD980D +:10EE2000AD88AD80AD903C4FFB67444218C53C4F68 +:10EE3000FB4D444218C63C2FFB583C3FFB683E67E5 +:10EE4000EB383C1FFB693C0FFB473C4FFB59A508C7 +:10EE500084E158420002AD08A5088541FF3FAD0896 +:10EE6000A548444FFF7FFF2EAD08A50885225842D4 +:10EE70000020AD08A548444FFFBFFF2EAD08A448B1 +:10EE8000AC58A65058108002AE50A650FE7FAE502F +:10EE9000A650541080FBAE50A650AE402E002B085A +:10EEA0003E67EB603E07EB24440FFFAA3E07EB2BC7 +:10EEB000440000553E07EB2F3E07EB253E07EB5D78 +:10EEC0003E67EB4F3C7E00B83E67EB633E67EB5C12 +:10EED0003E67EB303E6003063E67EB073C6BF5D8C0 +:10EEE0003C6BF5DC3EA7EB4A3EA7EB1449FFFF0C59 +:10EEF0003C0DFB593E67EAD23E67EB123E67EAD310 +:10EF0000AF813E67EB273EA7EB413E67EB10AF803A +:10EF10002E002AF93E67EB503E0002F83C0DFB67DD +:10EF20003E67EB463C6E05603E67EB2C3C7E05641D +:10EF30003E6002F93E6002FA3E67EB0B1090000063 +:10EF40003C0DFB4D10900000440295143E67EB1BF6 +:10EF50003E97EB0949FFFDD444026E703C0E02322D +:10EF600044026E203C0E023344026D8C3C0E02348F +:10EF700044026CF83C0E0235440000323C0803A405 +:10EF80003C0803A8440298E03C0E01D3440293607D +:10EF90003C0FFB63840A3E07ED202E002A633C6B86 +:10EFA000F5E23E002B954402B8003C6BF5DF3E676E +:10EFB000EB0F3E67ED883E67ED213E67ED2249FF8E +:10EFC000FEC2800649FFF816800749FFF813800645 +:10EFD00049FFF81E3C0E01AC800749FFF8193C0EB2 +:10EFE00001AD840249FFF8143C0E01AE840349FFD1 +:10EFF000F80F3C0E01AF840449FFF80A3C0E01B043 +:10F00000840549FFF8053C0E01B1840649FFF8006C +:10F010003C0E01B2840749FFF7FB3C0E01B38408A4 +:10F0200049FFF7F63C0E01B44402B80049FFFE8BDD +:10F030004402A2E03C0FFB513C0015393C1016463F +:10F040003C0816443C00153A3C6E00BD3C0816AD29 +:10F050003C0016473E67EB2E40001C0C88013C0824 +:10F0600016483C0016B03C1016AF40001C0C88013E +:10F070003C0816B14402BC603E6002F049FFF80053 +:10F080004402B80049FFF7FF49FFF82D3C0FFB5D34 +:10F0900049FFF7FC440299083C0E0230440294F404 +:10F0A0003C0E023144027B143E67ED793E67ED78F9 +:10F0B0003E67ED7A3E6008BC3C0FFB64845F3C0D0C +:10F0C000FB5D843F382018088CC65A683CFA3C0D1A +:10F0D000FB5D84C084E11010003C1010003D2E0048 +:10F0E0002A6B3C6E00BA3E07EAE03C6E00BB3E6015 +:10F0F00003003E6002FF3E6003013E6003023E6784 +:10F10000ED543E67ED563E67ED553E77EB323E6778 +:10F11000EB4D3E67EB0C3E67EB5E3E67EB363E67C2 +:10F12000EB263E67EADB3E67EADC3E67EAE13E67E4 +:10F13000EAD43E67EAE63E67EADE3E67EAE23E6719 +:10F14000EAD83E67EAE53E67EAE93E60030549FF23 +:10F15000FCAF4400005AFA493C0804363C28043A03 +:10F16000440000963C2DFB583C0804373C08043C06 +:10F17000FA183E6003033E6008653E6008663C087E +:10F18000043D84053C08043FA6104410006454006C +:10F1900000F73C1804343C6804353C6804383C688B +:10F1A00004393C68043B3C68043E3C680440AE10B3 +:10F1B000FA043C080328440003843C080329840F14 +:10F1C0003E00065684063C18032A3E0006583E6060 +:10F1D00003043E60063C3E60063D3E60063E3C68E1 +:10F1E00003213C6803273E6006573E6006593E7087 +:10F1F000065A49FFCA83FA083E00065C44024E00E4 +:10F200003E67EB583E67EB3C3E67EB4449FFF7BC7B +:10F210002E002AFC5A08010449FFF9314402A300D8 +:10F220003E7002FC3E77EB3D49FFFD3F84003C0F02 +:10F23000FB4E3E07EB393C0FFB5F3E07EB4E2E10BB +:10F240002A702E002A6F49FFB6A1FCC0FC0144625F +:10F25000B8B8800649FFFC1A50037F48F08149FF87 +:10F26000FD449C3449FFFD445003007849FFFD49AB +:10F27000500300A849FFFD3F500300C049FFFD3E79 +:10F28000500300CC49FFF6B050037F48F08149FF9E +:10F29000F6AE50037F48F08149FFFD4C500300B0AB +:10F2A00049FFFC1550037F48F08149FFFC135003D0 +:10F2B0007F48F08149FFFBED5003011849FFFD0332 +:10F2C00050037F48F08149FFFD0149FFFD025003D3 +:10F2D000012C49FFFBE150037F48F08149FFFBDF30 +:10F2E000500303A849FFFBDE50037F48F08149FF2C +:10F2F000F73E5003017049FFF7375003031849FFE9 +:10F30000F6B950037F48F08149FFF6B75003036C0C +:10F3100049FFF6AA50037F48F08149FFF6A8500341 +:10F32000037C49FFF71B50037F48F08149FFF71921 +:10F33000500303B449FFFCB650037F48F08149FFF6 +:10F34000FCAE3C1DFB583C0DFB6949FFCAFF500356 +:10F3500003D849FFFCF250037F48F08149FFFCF0DD +:10F360005003004849FFF91C50037F48F08149FFD2 +:10F37000FBB450037F48F08149FFFCD950037F481C +:10F38000F08149FFFBA150037F48F08149FFFB8DCD +:10F39000FC81FC402E07EB52E602E8062E77EAC01D +:10F3A0002E97EAC1D5052E77EAC82E97EAC484C005 +:10F3B0002E002A8FE2C0E8122E07EB52E6028006EA +:10F3C000E8043C17F5BBD5033C17F5D480478069AA +:10F3D0008CC149FFB1E197B0D5ECFCC0FC4480E0A2 +:10F3E000F1843C0DFB1744127ADCF28549FFAD5ADB +:10F3F0003C1DFB67840184C0AE083C1DFB4D81278A +:10F40000AE0884013C6FFB7849FFC59AE6E9E90242 +:10F41000852885403C6FFB4E80CA4C6480D4448371 +:10F42000F04A4410005510140000F18749FFEF2402 +:10F4300040031C3784003E07EB593C0DFB59F18615 +:10F44000F107A6018E0AE602E81310140000440337 +:10F45000F403A6005A0001FD3C0DFB59842049FF2E +:10F46000D21E84003C0FFB88840149FFAC4A54043F +:10F4700080FF5084FFFFF0872E17EB592E002A8F54 +:10F48000E2204EF2009D3C0DFB785A0001045AA880 +:10F4900001F584203C1FFB782E07EB598C01960068 +:10F4A0003E07EB592E27EB592E002A8EE202E82D5B +:10F4B0002E37EB59F2068A60B6FFCA0AF004F281D1 +:10F4C000F2828020F20596D8FA9484A1D51BF0042C +:10F4D000F181F182442206DC802096D8FA9484A13E +:10F4E000490000752E07EB592E302A8EF10584A1B4 +:10F4F0009AC3B6BFF581F582440206DC804196D8F6 +:10F50000FA9449000064D50D2E57EB59D80A2E0005 +:10F510002AFC5A08010744020520F10749FFB59F5C +:10F520002E002AFC5A0801112E17EB592E502A8E54 +:10F53000D9193C1DFB4DAE084C6440152E07EB520B +:10F540005A080311D50B3C0DFB4D8421AE404C6491 +:10F55000400A2E07EB555A0806063C0DFB4D842049 +:10F56000AE402E002AFC5A0801162E002A8F2E5774 +:10F57000EB598E01D80F4C64400E2E07EB52C80A8F +:10F5800084033E07EB523C0DFB5949FFAE2149FF76 +:10F59000FF023C5DFB882E07EB598540D0073C0DF0 +:10F5A000FB882E202A8E40A100062E07EB592E50F4 +:10F5B0002A8F4C507F63854048FFFF608CC148FF15 +:10F5C000FF2E840049FFC4BCFCC4FC593C6DFB0405 +:10F5D0004490003C048F803A0273001602630012CC +:10F5E0004261A47344320000FF9FFEFF00930006B7 +:10F5F00044700060F48104FF803C3C6FFB014234A6 +:10F600009C734E8300038501E90285E150AF8008B9 +:10F6100051E18060812AA3D955C383FF13C48000C0 +:10F6200041C3A80992F455CE03FF547383FF13C45A +:10F630008001127480028D264C3F7FEF8780F3019A +:10F640004DC1803802330014029300150A75000181 +:10F650004044801396D9B69F03E500235A73FF13E5 +:10F660009261886796D9F43B38708D11FFE440931E +:10F67000BD3738700D11FFEC4073A0F788E9387181 +:10F680000D095BE3FF14B47FF43B9261887E96D949 +:10F6900038708D11FFE44093BD3738700D11FFECC9 +:10F6A0004073A0F788E938710D0951CE0001D5C823 +:10F6B000FCD9FC412E002B1C4412000044223000D7 +:10F6C000444235104432051049FFFE8A2E102A624A +:10F6D0002E47EAC8B63F2E102A632E57EAC0F181A2 +:10F6E0002E17EAC1840081218AA43C0FFB5A3C0FEB +:10F6F000FB493C0FFB4A2E77EAC4972180208040CB +:10F7000044A2300044820BFC3C30154AE243E82F0F +:10F7100041E1040844322A60406F0C00403F280059 +:10F7200041EF200002F1800003EF000040F79DF65A +:10F73000A4D841EF27D641E7F80141EF17D6403171 +:10F740009C764232787396D9ACF02E302A6240F122 +:10F750000FD6926140FF0C07A4F05031FE3EE90342 +:10F760008803D50288238C419691D5CFB47FF201CE +:10F7700044428978FE9C4031080A882390418803DE +:10F7800040108837400008172E202A63500001C21D +:10F79000501081C23C0FFB493C1FFB5A94918400DE +:10F7A000443288E0445003E844628A08E002E80DED +:10F7B0003812010138730101FE6C40109C3638117B +:10F7C00081098C019601D5F32E07EB3FC8143E0743 +:10F7D000EB523C0DFB5949FFACFB49FFFDDC4402F9 +:10F7E0000BFC4412000049FFBF4944020BFC4412C9 +:10F7F0003000D51684033E07EB522E07EAC84412A8 +:10F800008A083E07EAC22E07EAC43E07EACA440253 +:10F8100088E049FFB2544402300044120BFC49FF17 +:10F82000BF2D4403F04A44100055AE40FCC1FC41DA +:10F8300084013E07EB1A2E002AFC5A08011E2E07EF +:10F84000EB41C0032E07EB523E07EB3F84003E071F +:10F85000EB1C3E07FD9A3E0002FD3E07EB523E07C1 +:10F86000EB3E3E07EAC62E07EAC03E07EAC22E0775 +:10F87000EAC13E07EACA3C0DFB5984203C1FFB1736 +:10F88000A601F1813E07EB5549FFC07A3C2DFB599B +:10F89000F1015A0802098404AE11800249FFCFFF2A +:10F8A000842DD5078409AE11800249FFCFF8842A40 +:10F8B0003C0DFB59AE413C0DFB5949FFAC892E0074 +:10F8C0002AFC5A08010449FFFD66840849FFDD71DE +:10F8D0002E002B065A0801044900031C840C49FF22 +:10F8E000DD682E002AFC5A0801392E202A634402C2 +:10F8F0008A088420949149FFB24C2E202A63440246 +:10F9000089788420949149FFB2442E07FD9AC82239 +:10F910003C0DFB5949FFAC5C2E002B1C441200002F +:10F9200044220BFC4432051044423BFC49FFFD5885 +:10F9300049FFC0265A00020644000E6449FFC799D9 +:10F9400084013E07EB3D840D49FFDD3349FFFEB3E3 +:10F95000D5102E002B85D5032E002B1C4412000041 +:10F9600044220BFC4432051044423BFC49FFFD3865 +:10F9700049FFC0063C1DFB592E27EB555A080206CD +:10F980009E12E602E804D5055A200204AE89D5038A +:10F99000840DAE092E002AFC5A0001133C0DFB59C0 +:10F9A00049FFAC16840084233E07EB3B3E07EB4E39 +:10F9B0003E07EB1B3E17EB093E07EB1AFCC184C068 +:10F9C0004490009044728AA02E002A8EE2C0E8E79C +:10F9D000441205204213247344028A08442000483C +:10F9E00049FFBE21442000484213082494494402A0 +:10F9F0008A0888278CC149FFBE1697B0D5E6FC411E +:10FA0000B421006F802802108014B6DF9649CA0422 +:10FA1000ACC0AD02FCC14061200954A300014462A6 +:10FA20000000FE77F1818781B43FE2A1E8F2441043 +:10FA30000058048F800185E042828473812F8928D9 +:10FA400084204070840995FA5460800188C7407012 +:10FA50008C093824980897C6406090095073804CF0 +:10FA600095B288C788C9547080075AA8010901E374 +:10FA7000000040751C0C407F1C04D508407E1C0C07 +:10FA800001E30000FFFB407F1C028C219648AFF091 +:10FA90005A1825D985225AF0010485E1D5D18CA1C7 +:10FAA0009768D5C3FC413C0DFB0480C14410003C69 +:10FAB0000200001242030473449200004000240438 +:10FAC0003C0FFB01800280E28143810449FFD80F93 +:10FAD00040902404CF10800A80278441806649FF2B +:10FAE000D6FA842180418008806649FFD6F4804799 +:10FAF000FA35D503FA5484208006F281B63F49FFD7 +:10FB0000D812B43FF2018C21944994913C5DFB04DE +:10FB10003C4C0175882A8902846045E001FF382445 +:10FB20000D015A23FF25D40444F0012CD50344F0E1 +:10FB300001F438248901402100568A4F96933CF302 +:10FB4000F5D54E250005A488884FD503A4888A4F93 +:10FB5000AC88222080004E2400048440AC8822F02F +:10FB600080005EF78200E90313E080008C618C2244 +:10FB70005A3824D75A7801088420800A8041806648 +:10FB800049FFD6A9FCC1FC40EE78B63F81408420F5 +:10FB90008102B006442000B049FFFA378420442097 +:10FBA00000C0B03249FFFA31840149FFC1C9840164 +:10FBB0003E07EB153C5DFB043C0C0175D00784004F +:10FBC000B43F3C0FFB1749FFA96D3C1DFB67840147 +:10FBD000467EFFFFAE083C1DFB4D84C050738FFF77 +:10FBE000AE0884003E07EB473C0DFB048380B90C54 +:10FBF00092309646F181BA0C441EFFFFFE56B98C36 +:10FC000096304C64001549FFD77C44120000FE0F6B +:10FC10008380B083B90C3C0FFB01923C96463813AD +:10FC20000808B90C8CC1FE7EB98CD5EB840A4690CD +:10FC300010003E07EB0A8D2184C045C3F4032E0754 +:10FC4000EB155A000104480001304403F04A441007 +:10FC500000558F21AE404E930003D50084003E072F +:10FC6000EB5984003C0FFB7849FFBE8A5A00021111 +:10FC70002E07EB47C80D3C0DFB5C5A0804058409B0 +:10FC8000100500013C0DFB59842049FFCE0884017A +:10FC90002E17EB473E07EB0C440000804000040E9B +:10FCA0009601C80284013C0BF5D53C5DFB043C0C7D +:10FCB0000175D80A84003C0FFB884403F04A4410C5 +:10FCC0000055AE40D50649FFBE5B5A0802F5D51C6B +:10FCD000000E00005A0001FE000500015A08090745 +:10FCE0003C0DFB59842049FFCDDA840149FFA80966 +:10FCF0002E07EB0A2E57EB478E01D8038400D5025E +:10FD000084013E07EB0C3C0DFB04A1C692EA97EF81 +:10FD10002E07EB59E2074EF200AB3C0DFB785A0080 +:10FD200001045A6801F72E07EB0A2E17EB478E01E4 +:10FD3000E020E80E2E07EB5996005A08010A3C1CF9 +:10FD400001753C5DFB04D1043C1DFB4DAE088400F5 +:10FD50003C0FFB782E07EB592E500AF68C019600CB +:10FD60003E07EB592E07EB594C5000CA2E07EB59B2 +:10FD700049FFD76FB61F2E07EB0A2E57EB478E01B0 +:10FD8000D81549FFBDFD5A0802123C0C01753C5DB7 +:10FD9000FB04D80C3C0DFB4D8421AE40840D1005B6 +:10FDA00000013C0DFB5949FFAA13440293C0B43F24 +:10FDB0008440B0C6B13249FFFE77440293C0B43FDD +:10FDC0008441B0C6B13249FFFE6F3C0C01733C5D0B +:10FDD000FB04D83B2E07EB415A0801382E07EB599C +:10FDE0005A0801342E27EB52CA302E002AFC5A083A +:10FDF000012D2E002B0E5A08012944020520441221 +:10FE00008A9C49FFB05549FFBDBB5A0802133C0309 +:10FE1000FEC83C1015C0E220E80684013E07FD9AAA +:10FE200084C0D5253C03FECA2E102B8BE220E9F6B8 +:10FE300049FFBDA65A00020A3C2015C03C13FEC86B +:10FE40008403FE14E001E9EA3C5DFB882E07EB59D0 +:10FE500084C0D0062E07EB5984C1406300062E579C +:10FE6000EB594C53FF5784C048FFFF542E07EB4714 +:10FE70003C1C01753C5DFB048C013E07EB472E07E3 +:10FE8000EB0AD1092E17EB52C9062E17FD9AC103B2 +:10FE90003E07EB472E57EB474C507ED384023E077C +:10FEA000EB1548FFFECE840049FFC04A3C2DFB0401 +:10FEB000F001838240104008BB0C440EFFFFFE1E81 +:10FEC000FE0F467EFFFFB88C84C050738FFF9630C4 +:10FED0004C64001E49FFD61544120000FE0FB043CB +:10FEE0008380381304003C0FFB0196464020F00845 +:10FEF000B90C8CC1FE7EFE57B98CD5EA3C0C01755D +:10FF00003C5DFB044C507F6348FFFF32ED88FCC032 +:10FF1000FC4185294430012C444001F484A0440272 +:10FF200093C044127ADC44200100B73F49FFFD69C9 +:10FF30003C0DFB5944127ADC844A49FFFE268009B5 +:10FF400049FFDA372E002AFC5A0801322E702B0E98 +:10FF50005A78012E2E07FD9AC02A2E67EB52CE2723 +:10FF60003E6002FC3E7002FD49FFB1B3840A3E7060 +:10FF700002FC3E7002FB3E67EB3D3C6E00BB49FF5E +:10FF8000DA18440293C044127ADC44200100B73FDF +:10FF90004430012C444001F480A649FFFD323C0D61 +:10FFA000FB5944127ADC844A49FFFDEF49FFBCE863 +:10FFB0003C1DFB595A0802098405AE0980018420C2 +:10FFC00049FFCC6DD5038409AE093C0DFB5949FFAF +:10FFD000A8FF840B49FFD9ED840BB61F44127ADCCD +:10FFE000440293C0442001004430012C444001F4F9 +:10FFF00084AA49FFFD063C0DFB5944127ADC84417A +:020000021000EC +:1000000049FFFDC384003E00030649FFBCB95A08FE +:100010000206842D3C0DFB59D50D3C0DFB59842067 +:1000200049FFCC3D2E17EB553C0DFB595A180203E6 +:10003000842AAE413C0DFB5949FFA8CAFCC1FC0013 +:100040003C1DFB678402AE083C1DFB4DAE088401DD +:100050003C0FFB17440000A249FFD9A13C0DFB59FE +:10006000A6015A080D128400847F3C2DFB5D843F5D +:10007000383100088C065A083CFA3C0DFB5D101024 +:10008000003C1010003D49FFD0703E0002D92E0008 +:100090002A6B84C0520000013E67EB0749FFC9F696 +:1000A0003E6002DA49FFC57FFC803C0C0173020010 +:1000B0000016DD9E3C0DFB0402000015DD9E3C0C8D +:1000C0000173DD9EA44044020000FE0F3C0E017946 +:1000D000DD9E3A6FA6BC3C1DFF82A1450220801A1E +:1000E0002E17EAE95A1801082E202A630430000C62 +:1000F0009491D50280653C13F5C23C43F5C1E224DE +:10010000E9073C6DFB2C3C7DFB2D8420D5568C21D2 +:1001100096493C1BF5C25A10010580038420D53353 +:100120008400443FFF804440007F9641E222E87A09 +:100130003C1DFB2C383080083C1DFB2D38408008CE +:100140008C01D5F43C6DFB2C3C3DFB2D2E57EAE990 +:1001500038430410383184105A580106A540976B73 +:1001600090A2AD40A540976BE085E911A540976B43 +:10017000E0A3E918384304083C4DFB2D8C023832CB +:1001800004088C2196C9E262E9DED54CA5009723CC +:100190005EF20080E804A5009723D5E94440007F83 +:1001A000D5E6A4C096DB5EF1FF81E904A4C096DB2E +:1001B000D5E2443FFF81D5DF96C9E262E8133843B8 +:1001C00004103833840040422008FF1F94C9409235 +:1001D0008C008C2112448000049000068869AD18C0 +:1001E000D5EC84C03E67EADE3E67EAD449FFDE3FD5 +:1001F0002E07EAE95A0801143E07EB1284203C0D51 +:10020000FB593E67EB4D49FFD1D63C0DFB5984238A +:10021000AE4149FFAE69840049FFC52F84003E0707 +:10022000EAE93A6FA684DD9E2E17EAEA5A182546B7 +:100230003C2DFB0484203E17EAEA023100123E17EF +:10024000EAE444120000FE5FB4623A6F98BC926325 +:100250003C1FFB0196F73C5DFF828440FAC8021206 +:10026000801AE241E80DB480945188818C41A460E9 +:100270009691FE7440108C379649AC60D5F149FFD9 +:10028000DDF684003E07EAD43E07EAD83E07EADC02 +:1002900049FFE147840049FFC4DF2E07EB5084810A +:1002A0002E17EB4644527ADC2E27EB0B3A6F9884DC +:1002B0002E37EB2C48FFAB21DD9E3A6FAABCEFF442 +:1002C000840044529168843F444291804432918C2E +:1002D00044229174381280083812000838118008BE +:1002E000381100088C0144A29168448291804462D4 +:1002F000918C447291745A0809EF85202E07EAEB1D +:10030000E320E8453C13F5C54402000041C08004E9 +:1003100050048001549000FF80293C03F5C049FF40 +:10032000ACEA842C43C00473803C8440B4015A205E +:10033000022294D240540C00848054F000079203AF +:100340005AF80204389290088C815A4804F8A5099A +:10035000886A84005452000792835A5802043891E4 +:1003600080088C015A0804F88C418C245A2803E038 +:10037000D5C6541000075A1802043E9003E89210A4 +:1003800096175A0802BD3E9003D0D5B9852085083E +:100390002E07EAEBE320E850800949FFD0C68140F0 +:1003A0003C0DFB0445C20000802A023000154000CD +:1003B000700496D9F38149FFAC9EF301842C40313F +:1003C000F004423004738400B4435A0002219502C1 +:1003D000972084205451000792435A580205994CA3 +:1003E0003853A8088C2196485A1804F6A4998420FA +:1003F0005451000792435A580205994C3853280823 +:100400008C2196485A1804F68C64D50D54110007B7 +:100410005A1802043883A808925096975A28020462 +:10042000388328088C0196005A0803D050048001B4 +:10043000549000FFD5AEEC0C3A6FAA84DD9E3A6F63 +:10044000AABCEFFC850084C1812180E283838140C6 +:100450003E67EADC3E87EAEA3E87EAE349FFFE2799 +:100460003C0BF5BF49FFFE2D3C0BF5C049FFFE24B8 +:100470003C0BF5C53E87EAE43E87EADD5A7803087F +:1004800084013E67EAD849FFC3E7D5228421804131 +:1004900080614400FBA03E67EAE649FFC0A28441B8 +:1004A0008062441000FA44001CA049FFC09A8441B5 +:1004B0004400D9B0FA20806249FFC0935AA8AD0524 +:1004C0003E67EADDD5055AA8AE043E67EAE350056B +:1004D00000559600E602E8068404490007FA3EA7A4 +:1004E000EAD654048002C01C5A90030445C15C0043 +:1004F000801C441262004420140049FFEE0D4400A9 +:1005000002EE49FFC8425A7803074402622049FFBD +:10051000FDDBD50F4402622449FFFDD6D50A490010 +:1005200007B84E92FFF25A980105801C49FFFDCC96 +:100530002E07EB5084812E17EB4644527ADC2E278F +:10054000EB0B2E37EB2C49FFA9D83C0DFB04A00682 +:10055000920A962F3E07EAEB5A780307EC043A6FAB +:10056000AA8448FFFEACEC043A6FAA84DD9E3C3DB1 +:10057000FB0444120000FECF3A6FAABC0421800C99 +:10058000460FE03F50000FFFFE1646200AC0FE1740 +:100590001401800C0401800C462800009407920787 +:1005A000FE17EFEC1401800C84408081446FF8FF4B +:1005B000445FC7FF02018012448200008802880461 +:1005C0005021003CA045FE7658108100A845A0456A +:1005D000FE6EA8455A2A58F00201801285EC880860 +:1005E000446FFFC7A645020180154200BC7388080E +:1005F0008438B440444FFE3FFE8E58210004B6407C +:10060000B440467FFC7FFEB658210020B640B4407F +:1006100046900200FEA658210100B640B440444F67 +:10062000F1FFFEA658210800B640B4A04428FFFF01 +:10063000FF564052A004B6A0B4A050438FFFFF66FF +:100640004052A404F481B6A0B4A0467FE3FF504317 +:100650008FFFFF6646701000FF7FF482B6A0B4A043 +:1006600046AF1FFF50450FFF47C08000FF66405256 +:10067000F004F483B6A0A141444FFE3FFF4E585210 +:100680008004A941A14147E04000FF7658528020F4 +:10069000A941A141FF6658528100A941A141444F9F +:1006A000F1FFFF6658528800A941A14140A288028B +:1006B0004454000040A5140414A0000104A000014B +:1006C000F40140A5100240A5240414A0000104A0D8 +:1006D0000001F40240A5100240A51C0414A0000172 +:1006E00004A00001F40340A5100240A5700414A06A +:1006F000000104A00002444FFE3F40A5040258A59B +:10070000000214A0000204A0000240A5080240A5B7 +:10071000140414A0000202A180124402004138A077 +:1007200028000201801542053C738808B54040A5A9 +:10073000040258A50004B740B54040A5180258A5CA +:100740000020B740B54040A5100258A50100B740B1 +:10075000B540444FF1FF40A5100258A50800B7402E +:10076000B54040A5080240A51404B740B540F401C7 +:1007700040A510024640010040A51004B740B54016 +:10078000F40240A5100240A51C04B740F403B54094 +:1007900040A5100240A57004B74004A00001444FDA +:1007A000FE3F40A5040258A5000414A0000104A0C7 +:1007B000000140A5180258A5002014A0000104A0C3 +:1007C000000140A5100258A5010014A0000104A0DA +:1007D0000001444FF1FF40A5100258A5040014A0E9 +:1007E000000104A0000140A5080240A5140414A0C3 +:1007F000000104A00001F40140A5100240A524045A +:1008000014A0000104A00001F40240A5100240A5BC +:100810001C0414A0000104A00001F40340A5100270 +:1008200040A5700414A0000104A00002444FFE3F44 +:1008300040A5080240A5140414A0000204A0000270 +:1008400040A5040258A5000414A0000202A18012D1 +:100850004402007D38A028000201801542053C7347 +:100860008808B54040A5040258A50004B740B5402B +:1008700040A5180258A50020B740B54040A5100279 +:1008800058A50100B740B540444FF1FF40A5100204 +:1008900058A50800B740B54040A5080240A514047B +:1008A000B740B540F40140A5100240A52404B7406C +:1008B000B540F40240A510024640080040A51004CF +:1008C000B740B540F40340A5100240A57004B740FE +:1008D00004A00001444FFE3F40A5040258A50004B7 +:1008E00014A0000104A0000140A5180258A5002092 +:1008F00014A0000104A0000140A5100258A500802A +:1009000014A0000104A00001444FF1FF40A5100213 +:1009100058A5080014A0000104A0000140A5080289 +:1009200040A5140414A0000104A00001F40140A596 +:10093000100240A5240414A0000104A00001F40248 +:1009400040A5100240A51C0414A0000104A0000151 +:10095000F40340A5100240A5700414A0000104A0F7 +:100960000002444FFE3F40A5080240A5140414A015 +:10097000000204A0000240A5040258A5000414A02F +:10098000000202A18012440200B938A0280002012E +:10099000801542053C738808B54040A5040258A55F +:1009A0000004B740B54040A5180258A50020B74044 +:1009B000B54040A5100258A50100B740B540444FCE +:1009C000F1FF40A5100258A50800B740B54040A56A +:1009D000080240A51404B740B540F40140A5100238 +:1009E00040A52404B740B540F40240A5100240A53C +:1009F0001C04B740B540F40340A5100240A578049C +:100A0000B74004A00001444FFE3F40A5040258A592 +:100A1000000414A0000104A0000140A5180258A57C +:100A2000001014A0000104A0000140A5100258A568 +:100A3000010014A0000104A00001444FF1FF40A5F3 +:100A4000100258A5080014A0000104A0000140A550 +:100A5000080240A5140414A0000104A00001F40140 +:100A600040A5100240A5240414A0000104A0000128 +:100A7000F40240A5100240A51C0414A0000104A02B +:100A80000001F40340A5100240A5700414A0000169 +:100A900004A00002444FFE3F40A5080240A51404F4 +:100AA00014A0000204A0000240A5040258A50004FE +:100AB00014A0000202A18012440200F538A0280010 +:100AC0000201801542053C738808B54040A5040228 +:100AD00058A50004B740B54040A5180258A500200D +:100AE000B740B54040A5100258A50100B740B54039 +:100AF000444FF1FF40A5100258A50800B740B5408B +:100B000040A5080240A51404B740B540F40140A533 +:100B1000100240A52404B740B540F40240A51002DD +:100B200040A51C04B740F403B54040A5100240A501 +:100B30007004B74004A00001444FFE3F40A50402EA +:100B400058A5000214A0000104A0000140A518024D +:100B500058A5002014A0000104A0000140A5100227 +:100B600058A5010014A0000104A00001444FF1FFAA +:100B700040A5100258A5080014A0000104A000011F +:100B800040A5080240A5200414A0000104A0000113 +:100B9000F40140A5100240A5240414A0000104A003 +:100BA0000001F40240A5100240A51C0414A000019D +:100BB00004A00001F40340A5100240A5700414A095 +:100BC000000104A00002444FFE3F40A5080240A5DA +:100BD000140414A0000204A0000240A5040258A5B9 +:100BE000000414A0000202A180124402013138A0C6 +:100BF00028000201801542053C738808B54040A5D5 +:100C0000040258A50004B740B54040A5180258A5F5 +:100C10000020B740B54040A5100258A50100B740DC +:100C2000B540444FF1FF40A5100258A50400B7405D +:100C3000B54040A5080240A51404B740B540F401F2 +:100C400040A5100240A52404B740B540F40240A5D9 +:100C5000100240A51C04B740B540F40340A51002A3 +:100C600040A57004B74004A00001444FFE3F40A5DA +:100C7000040258A5000414A0000104A0000140A52E +:100C8000180258A5002014A0000104A0000140A5EE +:100C9000100258A5010014A0000104A00001444F57 +:100CA000F1FF40A5100258A5080014A0000104A0FF +:100CB000000140A5080240A5140414A0000104A0EE +:100CC0000001F40140A510024640010040A51004B7 +:100CD00014A0000104A00001F40240A5100240A5E8 +:100CE0001C0414A0000104A00001F40340A510029C +:100CF00040A5700414A0000104A00002444FFE3F70 +:100D000040A5080240A5140414A0000204A000029B +:100D100040A5040258A5000414A0000202A18012FC +:100D20004402016D38A028000201801542053C7381 +:100D30008808B54040A5040258A50004B740B54056 +:100D400040A5180258A50020B740B54040A51002A4 +:100D500058A50080B740B540444FF1FF40A51002B0 +:100D600058A50800B740B54040A5080240A51404A6 +:100D7000B740B540F40140A5100240A52404B74097 +:100D8000B540F40240A5100240A51C04B740B54090 +:100D9000F40340A5100240A57004B74004A0000170 +:100DA000444FFE3F40A5040258A5000414A00001D2 +:100DB00004A0000140A5180258A5002014A00001BD +:100DC00004A0000140A5100258A5010014A00001D4 +:100DD00004A00001444FF1FF40A5100258A50800EF +:100DE00014A0000104A0000140A5080240A51404BD +:100DF00014A0000104A00001F40140A5100240A5C8 +:100E0000240414A0000104A00001F40240A5100273 +:100E10004640080040A5100414A0000104A00001F1 +:100E2000F40340A5100240A5700414A0000104A022 +:100E30000002444FFE3F40A5080240A5140414A040 +:100E4000000204A0000240A5040258A5000414A05A +:100E5000000202A18012440201A938A02800020168 +:100E6000801542053C738808B54040A5040258A58A +:100E70000004B740B54040A5180258A50010B7407F +:100E8000B54040A5100258A50100B740B540444FF9 +:100E9000F1FF40A5100258A50800B740B54040A595 +:100EA000080240A51404B740B540F40140A5100263 +:100EB00040A52404B740B540F40240A5100240A567 +:100EC0001C04B740F403B54040A5100240A57004CF +:100ED000B74004A00001444FFE3F40A5040258A5BE +:100EE000000414A0000104A0000140A5180258A5A8 +:100EF000002014A0000104A0000140A5100258A584 +:100F0000010014A0000104A00001444FF1FF40A51E +:100F1000100258A5080014A0000104A0000140A57B +:100F2000080240A5140414A0000104A00001F4016B +:100F300040A5100240A5240414A0000104A0000153 +:100F4000F40240A5100240A51C0414A0000104A056 +:100F50000001F40340A5100240A5780414A000018C +:100F600004A00002444FFE3F40A5080240A514041F +:100F700014A0000204A0000240A5040258A5000429 +:100F800014A0000202A18012440201E538A028004A +:100F90000201801542053C7388088148B50046FF70 +:100FA000FE3F4084040258840002B700B50050F7A9 +:100FB0008FFF4084180258840020B700B500408499 +:100FC000100258840100B700B500444FF1FF40847F +:100FD000100258840800B700B5004084080240841D +:100FE0001404B700B500F4014084100240842404C6 +:100FF000B700B500F4024084100240841C04B7001E +:10100000B500F4034084100240847004B7000480EB +:101010000001444FFE3F40840402588400041480C1 +:1010200000010480000140841802588400201480CC +:1010300000010480000140841002588401001480E3 +:10104000000104800001444FF1FF408410025884E5 +:10105000080014800001048000014084080240540C +:101060001404A941A141F401FF664092A404149024 +:101070000001A141F402449F8FFFFF66FFEFA9C169 +:10108000A141F403FF664052F004A941A142444F3C +:10109000F1FFFF4E58528004A942A142FF56405230 +:1010A000A804A9420201801240002804A6070201F8 +:1010B000801844026CACA14192AB4052AC0858522B +:1010C000805FA941A14492AF4052BC085852805F52 +:1010D000A944A1C4465C000750528FFFFF7E4670B2 +:1010E00002F8FF7FA9444450005F105000190470BB +:1010F0000010FFF6147000101050001B0470001058 +:10110000FFE6147000104470005E1070001C048034 +:101110000010444C7FFF40842402148000101070A3 +:10112000001D048000104084100214800010107014 +:10113000001E04800010444FFE3F40843C02148097 +:1011400000101070001F05E00010468FF1FF508462 +:101150000FFF41EF200215E000101050002405E0C1 +:10116000001141EF100215E000111050002505E0BC +:101170000011444FF1FF41EF100215E00011105033 +:10118000002605E00011444C7FFF41EF240215E0EA +:1011900000111050002705E0001141EF100215E08A +:1011A00000111050002805E00011444FFE3F40FFA1 +:1011B0003C0214F000111050002904F0001147E027 +:1011C00005F04087A002148000111050002A04F09E +:1011D0000011468F8FFF50840FFF4087A0021480BC +:1011E00000111050002B04F00011468C7FFF50843A +:1011F0000FFF4087A002148000111050002C0480C3 +:10120000001246F8000F40840402148000121050AF +:10121000002D0480001250F78FFF408418021480C4 +:1012200000121050002E048000124084100214801E +:1012300000121050002F04800012444FF1FF408430 +:101240001002148000121050003004800012444C30 +:101250007FFF40842402148000121050003104806B +:101260000012408410021480001204800014930FB6 +:1012700040843C085884005F1480001404800014EB +:1012800040843C02408478041480001404800015DB +:10129000930F40843C085884005F1480001504803C +:1012A000001540F43C024087F804148000151050EB +:1012B000005904800020408418021480002010503F +:1012C000005B04800020F4014084100214800020A0 +:1012D0001050005D04800020444FF1FF4084100254 +:1012E000148000201050005F04800020F40340842C +:1012F0001002148000201070006004800020444F11 +:10130000FE3F40842402148000201070006104809D +:10131000002140840402148000211070006204F057 +:1013200000204688FFFF50840FFF40F7A00214F012 +:1013300000201070006304F0002140F7880214F0D0 +:1013400000211070006404F00021406798021460CE +:1013500000211070006504600021FFA614600021C8 +:101360001070006604600021F401FFA614600021E3 +:101370001070006704600021F402FFA614600021D1 +:101380001050007004600022444FFE3FFFA614601E +:1013900000221050007104600022444FF1FFFF361C +:1013A000144000221050007204400022F602FF3662 +:1013B000144000221050007304400022F503EC1486 +:1013C000FF2E144000221070007404400023FE66BB +:1013D0001410002310700075041000224010A402A5 +:1013E000141000221070007604100023FE8E1420CA +:1013F000002310700077041000224010A002141087 +:10140000002202018018880AA042922F4010BC08D6 +:101410005810811CA842A043922F4010BC085810BD +:10142000811CA84384201210000A1210000B020134 +:1014300080124410003C40002804002000080201F3 +:101440008017420104738940460FF3FF041500051D +:1014500050000FFFFE0E46100800FE0F1405000599 +:1014600004150005460F3FFF50000FFFFE0E400021 +:1014700070041405000504050005461800009402D8 +:101480009202FE0F140500053A6FAA84DD9EFC202F +:101490003C0C0063441FFFCC4463F04A1010005121 +:1014A00084003C0FFB4E447000553C0C0063000070 +:1014B00000515A00BB06AFF049FFE56AD5F744007A +:1014C000003249FFC06284003C0FFB84FCA08421F1 +:1014D0003E17EAD93C1C00638801002000523C2BD7 +:1014E000F5C7001000534010A00888223C1BF5C728 +:1014F000001000543C1BF5C60000005540002008B9 +:1015000088013C0BF5C6DD9EFC003C1C0063840199 +:101510003E07EADE0020805284003C0BF5C2840ABC +:10152000FE143C0BF5C1000080515A08AB05840243 +:1015300049FFFFCFFC80FC4184C081209FD13C6FDC +:10154000FB4E44A3F04A44800055E0E6E918F181DF +:101550001085000049FFEF6298F79061F1014C633C +:10156000C00538548E02D11138548E02941AE225E7 +:10157000E9088809A001E220E806D107841FD50602 +:101580009FD9D5E49D99D5E28003FCC1FC4085201C +:1015900080C33C4DFF6D804180E98069855B850596 +:1015A000B4A240F2A802E80F5A50060E04F1000956 +:1015B000A1423852BD0100F2000640F79406E8034C +:1015C00010830002B4A250F2FFFF5CF78002E9032F +:1015D0005A58041B2251000502F2001EE0AFE91424 +:1015E00002F2001F40F79407E90F2251000402F2B3 +:1015F000001CE0AFE90902F2001D40F79407E9047E +:101600008CE197F881238C6196D8502100FC5A38E0 +:101610000AC92E87FDE3CF038400D51AA6325A00EB +:10162000051984035A78011550047FFFE602E80586 +:101630002E57FDE04C54FFF2440000FC421480732E +:1016400084012220800422108005AE32D504AE32FF +:1016500084208041A6325A0801593C5DFF6BA6E800 +:101660005A3801093C3DFF6C023180098E619A9A1B +:101670009693A6E95A3801093C3DFF6C0231800A75 +:101680008E619A59964BA6EB01E280025A380139D5 +:101690003C5DFF6C0232800950F1FFFF4FE3001AFE +:1016A000A4EA51E1FFFF846240A78D5642A17873FE +:1016B00040253C5702A2800AA56B8F418EA1403580 +:1016C0000C76423094734011A8379693964BD51DF3 +:1016D000A4EB85428E6140A7A95642A10C73402518 +:1016E0003C5702A2800AA56A8F4184628EA14035D0 +:1016F0000C76423094734011A8379693964B5BE872 +:101700000105806280418023E705E81844F0E0C8C5 +:101710003887A00040F43C00DD0F060C0C161C00BE +:101720005A08010BD5105A00010CC80C8403D50BC4 +:10173000E602E808D503C806D5068400D50484026D +:10174000D50284043E07FDE38E01E60484604EF278 +:1017500002A944F0E1103807810140F03C004A0042 +:101760003C0008006600CC01380584603C3FFF76F1 +:101770003C3FFF75846184003C3FFA72443FFFAAFE +:101780003C0BFEEE3E07FDE23E07FDE13E37E9CCB5 +:101790003C2BFEE83C1BFEE93C2BFEE63C1BFEE737 +:1017A0003C2BFEE43C1BFEE53C2BFEE23C1BFEE337 +:1017B0003C2BFEE03C1BFEE13E07FDBE3E97FDE0FC +:1017C0003E07FDBC480002702E07FDBE0232001A23 +:1017D000E203E8048C013E07FDBE3CF7FEE23C2B31 +:1017E000FEE0E04F3C1BFEE1E8043C2BFEE2D507A7 +:1017F0003C07FEE4E002E8033C2BFEE43CF7FEE39A +:10180000E02FE8043C1BFEE3D5073C07FEE5E001C2 +:10181000E8033C1BFEE53C07FEE69B424E540003FA +:10182000FF6A3C37FEE79A194E040003FE02880562 +:101830005EF000B0E90484013E07FDBC3C97FEE881 +:10184000400488014E040003FE023DE7FEE9403FEC +:1018500004014E340003FEDA02A200059958E34564 +:101860004EF20222A5662E87FDE1E205E90CE12297 +:10187000E805585400028540D508545400018540BD +:101880008521D50480A885428520A527E264E90E3C +:10189000E03EE80458528001D509974E504480013B +:1018A0009768549200FF58A500013C4DFF7588646D +:1018B0003C3FFF753C3DFF7688033C0FFF765A980E +:1018C000020E2E07FDE2C81D84013E07FDE23C0D1D +:1018D000FA7294023C0FFA72D5255AA803132E0708 +:1018E000FDE2C80F3C0DFA729402580000023C0F52 +:1018F000FA7284013E07FDE284023E07FDE1D51243 +:101900004C5400112E37FDE2E667E80C3C0DFA72EC +:101910008C619402FE2F3C0FFA723E37FDE23E5777 +:10192000FDE13C2BFEE83C1BFEE9480001BD2E0713 +:10193000FDE23C3DFF75E6033C0DFF76E8453C5774 +:10194000FEE60212000CE0A1E93D0212000DE025C6 +:10195000E9393C17FEE70222000EE022E9330222B9 +:10196000000FE041E92F3C27FEE18A410212000B03 +:1019700052F08000E04FE8070212000AE2018429D9 +:10198000E916D508E022E8060212000AE201842ADC +:10199000E90E3C17FEE0022200088A25FF52E025EE +:1019A000E80902120009E261E80F842B3E17E9CC36 +:1019B000D50BE041E80902120009E261842CE9F745 +:1019C000D5038422AE72021200108803E2204EF288 +:1019D00000EE2E07E9CC5A00AA04480000E83C07B4 +:1019E000FEE602120011E0014EF300DF02120012C7 +:1019F000E0204EF300DA3C07FEE702120013E0019C +:101A00004EF300D302120014E0204EF300CE440245 +:101A100077703C1DFA724420003849FFFD8E5A0F42 +:101A2000FF04480000BD4410DB70380080003C1DFE +:101A3000FF6D3E07E9CC5A0821203C27FEE13C0718 +:101A4000FEE7E040E8038406D57B8A024E040003EB +:101A5000FE024430006442200C243CF7FEE33C07C5 +:101A6000FEE58A0F400100160020802B9603E0401F +:101A70008400E966D5E95A0822363C27FEE03C0797 +:101A8000FEE6E040E9E18A024E040003FE02443033 +:101A9000006442200C243CF7FEE23C07FEE48A0F7F +:101AA000400100160020802D9603E040E9193C0714 +:101AB000FEE73C27FEE18A024E040003FE024430AA +:101AC000006442200C243CF7FEE33C07FEE58A0F4D +:101AD000400100160020802E9603E040E8B5840700 +:101AE000D52F5A0802303C07FEE33C47FEE53CF7A1 +:101AF000FEE28A803C07FEE48A0F4E040003FE02E9 +:101B000044200064FE14003080304000101696031C +:101B1000FE9CE040E9133C07FEE73C27FEE19A8289 +:101B20004E240003FE9244300064FE9C40011016D7 +:101B30000020802F9603E040E805440FFFAA3E07EF +:101B4000E9CC2E07E9CCC8323C07FEE23C47FEE474 +:101B50003CF7FEE38A803C07FEE58A0F4E04000353 +:101B6000FE0244200064FE140030802C4000101659 +:101B70009603FE9CE040E9133C07FEE63C27FEE0AE +:101B80009A824E240003FE9244300064FE9C400181 +:101B900010160010802A9603E020E808440FFFAAE0 +:101BA0003E07E9CCD5038402AE322E47E9CC3C0D8A +:101BB000FF6D5CF20020E811A440A4C14010C008F1 +:101BC00040208C045212001F4011040E9646C90595 +:101BD000441FFFAA3E17E9CCA440922C9646C1634D +:101BE0002E17FDBF5A18012A2E27FDBE0210001A1B +:101BF000E241E8232E27FDBD0210001BE241E81D53 +:101C00002E17FDBCC91A3C17FEE03CF7FEDC022093 +:101C100000198A2F4E140003FE4AE022E80E3C17FA +:101C2000FEE13CF7FEDD8A2F4E140003FE4AE0225F +:101C3000E80484233E17E9CC2E27E9CC84203E1704 +:101C4000FDBD5A2003313E17FDBF2E17FDBCC92B29 +:101C50003C17FEE10220001EE022E91D0220001FC9 +:101C6000E041E9193C27FEE00230001CE043E913A3 +:101C70000230001DE062E90F2E37FDBE0200001A9F +:101C8000E260E81184013E07FDBF3C2BFEDC3C1BFB +:101C9000FEDDD5098402AE32D5063E37FDBFD50341 +:101CA0003E37FDE384003E07FDE43C2DFF6D3C0321 +:101CB000FEEEC70EA454E201E8038C01D521840195 +:101CC0003E07FDE48404AE323E07FDE3D51B2E172C +:101CD000FDBF5A18010E2E17FDBD0231001BE22375 +:101CE000E8058C213E17FDBDD5033E77FDBFA4540A +:101CF000E201E905440FFFAA3E07E9CC84003C0B52 +:101D0000FEEE2E27E9CC5CF10020E8198C4C969071 +:101D10008401E65FAE30AEB18401E903FA2ED5024C +:101D2000802249FF9915840349FF991884003E07D2 +:101D3000FDE3440FFFAA3E07E9CCD5038400AE3093 +:101D4000FCC0FC41446000FC42019873B4003C8D2F +:101D5000FEC1F081F6012240800022508001841DE6 +:101D600000140017FE3600940016B63F45C287C027 +:101D7000447287904462837044A283345A08011CE1 +:101D8000842038138E0A4472876038430E093893D2 +:101D90008E0A44728730381E0E0A38938E0A95DAFE +:101DA00088C738050E0AAD714462836438130C0885 +:101DB000480000E638050E028C01E415E902FA0439 +:101DC00038050E0A38038E0244A28790E413E80314 +:101DD0008C01D502840038050E0A380E0E02C80A9E +:101DE00038038E025A081307440287C0854138A081 +:101DF0000E0A38038E02854C80E342702873384304 +:101E00001E0995FA88C745E28730AD714462876044 +:101E100044F2837038730E02387F0E0A4E070009B1 +:101E200051E07FFF8023421F28738141D50350A1D9 +:101E300080E439E7AA1140A50808894F404F1001F6 +:101E400022A50001405514014E440003FF224E54C8 +:101E50000003FF6A02A4000D88A4E345808AE90616 +:101E60000244000CE2A44042BC1AB43FE0E1E804A2 +:101E7000221F8000D5069C79964BE434E902FA24AF +:101E8000385E0E02CD0438930E0AD514F5018EA4E7 +:101E9000E6A2E91002F4000C4080A40140523C018B +:101EA0008088FF6440453C01404290979B0C38433A +:101EB0000E0A38430E0285438107428510738088DD +:101EC00085E48C8240423C96E0E44452876038438B +:101ED0000E0A44A28364E81138450C005083800147 +:101EE0008C819720E10438450C08E80438828E0A7A +:101EF000D50438728E0AD504848038450C083853CE +:101F00000E0244428760E0A9E80438920E0AD50523 +:101F1000E025E80338120E0A4412833438430E02D7 +:101F200038108E02E024E8054442876038120E0A19 +:101F300084A038930E02808580C544728370854CDE +:101F40004C54801380234210287338838611944A9E +:101F5000882788882210800188C1C0038E01D5029D +:101F6000FA038CA1D5EE842240028416888088066C +:101F700040421496405014B69723976BAD10AD5164 +:101F8000FCC1FC41446000FC42019873444283045C +:101F9000445282D4B4C022A0800022808001F28109 +:101FA00038720E0238128E025A68010C440282A462 +:101FB000842038A20E0A38828E0A38100E0AD554B0 +:101FC0005A68030738A20E0A38828E0AD54D963B0E +:101FD0004065000183C5964B4E640003FFB2405438 +:101FE00004014E540003FF6A3C7DFEC188C5445283 +:101FF00082A438628E0A0253800EE0C5E831009355 +:10200000801E83855074FFFF43C398734272A424DB +:102010004023F001FE54421E207340109C36381FAE +:102020000E0A441290D438108C008E24E626E80E56 +:10203000401488085090FFFF956A4254987395FCAD +:102040009A7DFE0C4202A873D5068022FE448001D0 +:10205000420E287340701CF638720E0AD50538A25D +:102060000E0A388F0E0AF10138020E02AC08440243 +:1020700082D438000E02AC09FCC1FC405050006014 +:1020800050900A388400804084C2848384E1003206 +:10209000FFC054F180010432FFE8E816C315043292 +:1020A000FFF104A0800594DA886A00F18000A6D9C7 +:1020B000E9065A3011191472FFFFD5195A38111454 +:1020C0001462FFFFD5148E61E663E8520432FFF11B +:1020D00004A0800594DA886A00F18000E808A6D997 +:1020E000E671E8058C011422FFFF96000432FFFF21 +:1020F000CB04B685A8E9D53C5A38011522A2FFD6F3 +:102100005EF57FFDE803B645D521E54BE9065EF5B2 +:102110000029806640323C1A5EF500C9B665E827A2 +:10212000D5155A38022622A2FFD65EF5043BE903F4 +:10213000B645D5165EF5042DE903B6E5D50E5EF578 +:10214000040F40323C1BB665D50822F2FFD75EF77C +:102150008793E90DA9E9D50C5EF5036FE90822F232 +:10216000FFD75EF78793E903A9A9D502A8A9505222 +:1021700080FC4C54FF8EFCC0FC408481505000B465 +:1021800084E550000A8C85248460854384C2002243 +:10219000FF6C54F100010422FFD3E816C21504229B +:1021A000FFDC048080059492884800F10002A69329 +:1021B000E9065A20231A1442FFFED5185A2823157F +:1021C0001462FFFED5138E41E643E8470422FFDC8C +:1021D000048080059492884800F10002E807A693E5 +:1021E0005CF10023E8031432FFFE0422FFFECA0B59 +:1021F00022F2FFAD1462FFFF5EF7849340223C1A87 +:10220000B645D52B5A2801102282FFAD5EF47FFC23 +:10221000E8041432FFFFD518E51F40233C1A1422AE +:10222000FFFFD5125A28021A2282FFAD5EF4092858 +:10223000E9041432FFFFD5155EF4090540223C1A6B +:102240001422FFFFD50E2222FFAC5EF101C3E81D70 +:102250005EF400FBE822B6C5505280FCD899FCC061 +:102260002222FFAC5EF101C3E8065EF40829E90B07 +:10227000B725D5F35EF10275E9065EF40829E90396 +:10228000B6E5D5EBB685D5E95EF10275E9065EF4F3 +:1022900000FBE803B745D5E1B665D5DFFC47F1891A +:1022A0002E17EAB883825CF080C8E8048C213E17C0 +:1022B000EAB82E17EAB75CF080C8E8048C213E1714 +:1022C000EAB73C9C005884E05014FFFFF18380C0C3 +:1022D0005014FFFE840AE2E1F087840114FF800DB0 +:1022E000F085F784F782F7818107B4064E020396E2 +:1022F0005A080604480003925A0804044800031BC5 +:10230000F2090003002404A3002BA0949441882226 +:102310009402A689A648F286F18AF109A04D8801A7 +:10232000A643A602F18BF08C4EA2005C5AA0010AD3 +:10233000841FF085FA12F088FB1344128D00D50833 +:1023400014AF800514AF8008850044128D80F0061C +:102350008801A60198885000002C940100310037B4 +:10236000880100210049A502F381F2828003C303A2 +:102370008E01D502F001F084F002E611E8039DC160 +:10238000D502FAE1F1028048807C84A1F00149FF86 +:10239000D6C8F208FA3483DC43E1047380BC84407D +:1023A000425404738062F104E0E1E90D3842851182 +:1023B0004E4700038864384F05114E470003884498 +:1023C0008C21D5F3F10484879A79FE4B42209073D7 +:1023D0004E2600038441842AFE5C40208856D503A3 +:1023E000804A800A001300209646C15B842F003F7C +:1023F0008018101300CA842012030061101300E635 +:10240000103300C44EA2001B8461101300BDF10103 +:10241000103300BC84631433002EC104F1025A1837 +:102420001105FA2E101300CAFA22F306423404737F +:10243000381E0D1112130063D50C441FFFC8101372 +:1024400000BC84211413002E101300BD12A30063DE +:10245000221300072E37EAB814130033E6718420E4 +:102460001213005F101300C0101300D0101300D11E +:10247000101300D2101300D3101300D4101300D582 +:10248000101300D6101300D7101300D8E8028421CF +:10249000101300C82E17EAB7E6318420E83AD53881 +:1024A00002130061E220E803120300614EA200174C +:1024B000F101C104F1025A181105FA2E101300CAD5 +:1024C000FA62001300C442140C7322330063381EF6 +:1024D0000511E061E80312130063001300BC5CF017 +:1024E00080C8E80B8C2104330033101300BC221386 +:1024F00000078823141300332E17EAB8E631E804E6 +:102500008421101300C82E17EAB7E631E8048421AD +:10251000101300C9F103E622E913441FFFC810138A +:1025200000BC0433002E8421101300BD843DFE5EE8 +:102530005A1801071413002E84201413002B842032 +:1025400010130068F103E622E8360413002BC133B0 +:102550005A1801075A98010C843F8482D50C5A18E6 +:1025600002095A980107843F8483D505F40DD503E9 +:102570008421808144328BD438319000C31C445272 +:102580008BD48885F30620520008FECCFE6CE02335 +:10259000E912F305F10AFE5C20320004F405FEE4C2 +:1025A000E061E909021300615CF08029E9048421FB +:1025B00010130068003300684E33008B0413002BA7 +:1025C000C130041300115A10022D0413002E5A18A2 +:1025D00003070413002DE622E824D5035A1802222B +:1025E000F10BF40C8C218A249648E622E91AE4487F +:1025F000E81842F100245CF7815FE81300130083C0 +:102600005A180108001300BDC904842A101300825F +:1026100084211413002E101300BD84201413002BEA +:102620000443002BC455041300115A100252041322 +:10263000002E5A1005058E22E622E84A5A48010566 +:10264000001300C8D5055A480244001300C9C94008 +:1026500022430046221300069A614E140003FE4AEC +:102660000253006144400BB844F003E8FF2C4042A1 +:102670003C97E281E82D5CF08033E92A004300C4F6 +:10268000FAA2814442A414732253006338FE291134 +:1026900085424052A8B6E0AFE809F504E085E903B9 +:1026A000E0E4E8165CF0812DE913001300835A186A +:1026B0000108001300BDC904842A1013008284217C +:1026C0001413002E101300BD84201413002B0413C8 +:1026D000002B4E1201000443002E5A400304480010 +:1026E0000114004300BC005300CAE2A44EF300A949 +:1026F0000453002CCD0B004300C08C81104300C05C +:10270000004300D68C81104300D65EF101C3E80778 +:1027100042F1002444A057E4E34FE80B004300C01B +:102720008C81104300C0004300D88C81104300D836 +:10273000E6A2E8285A1801165A98010822F3000662 +:102740005EF7821DE909D5145A98021D22F300068E +:102750005EF7821CE90D22130007E42BE813D5086D +:102760005A18021122F300075EF78919E90B0213C8 +:10277000005F8C211213005F001300D08C21101316 +:1027800000D05A38010C0213005F8C211213005F35 +:10279000001300D18C21101300D15EF10029E8054F +:1027A000FE145CF007D1E90B0203005F8C011203F9 +:1027B000005F000300D28C01100300D2020300610D +:1027C0005CF0003DE90EF003E602E80B0203005F57 +:1027D0008C011203005F000300D48C01100300D4AD +:1027E0000403002A5CF00065E90FF003E6024EF2F4 +:1027F000008C0203005F8C011203005F000300D510 +:102800008C01100300D50403002D5A9802095A00C8 +:1028100002125A08047A2E07EAB7D50E5A980175A3 +:102820005A0805072E17EAB7E631E86ED53D5A0873 +:10283000036C2E07EAB8E6118405E936D565040372 +:102840000033400010165A18020D5EF00919E827EF +:102850000203005F001300D08A011203005FD51F3E +:102860005A18011E5A98010A22F300060213005F4B +:102870005EF7821DE90DD50A5A98021222F300066E +:102880000213005F5EF7821CE803E41FD502E40B2D +:10289000E906000300D08A201213005F0203005FE4 +:1028A000E60BE90584021403002ED52E00030083F5 +:1028B0005A080108000300BDC804840A10030082FE +:1028C00084011403002E100300BD84001403002BA8 +:1028D000D51B040300115A0002180403002E9E4267 +:1028E000E622E9035A080511000300835A0801088B +:1028F000000300BDC804840A10030082840114038D +:10290000002E100300BD0403002DC8080413002E80 +:102910005A18010E3E07EAB8D50A5A0801090403FD +:10292000002E5A08010584003E07EAB74400003231 +:10293000D562000300209616C0700423002E840088 +:10294000100300CB84015A2805068401100300CB34 +:10295000840000430090FA620013009142120C734D +:1029600038FE05110213003E8463944940108C36F2 +:10297000E02FE8058402100300CB840002130061FD +:102980005CF0803DE908F103E622E80584031003CA +:1029900000CB8400003300BC0413003340108C369D +:1029A0008C245CF0892CE808001300C0004300D69A +:1029B0008A24101300C0004300C0E68BE8059C5930 +:1029C0009021E024E8058404100300CB8400001368 +:1029D00000CAE223E903E662E8058405100300CBA0 +:1029E00084000413002A5CF08065E908F103E62204 +:1029F000E8058406100300CBD5105A2001075A08B9 +:102A0000010D1403002ED5035A0801080403002207 +:102A10005A08010410030085F007506300FC8E0182 +:102A2000F0874E03FC64FCC7FC5AF08AF1848102F3 +:102A30008420FA54B01049FFF7C08420FA54B0192A +:102A400049FFF7BB8420FA54B02249FFF7B6B02BF8 +:102A50008420FA5449FFF7B12E07EAB65CF000C8AB +:102A6000E8048C013E07EAB62E07EAB95CF000C81C +:102A7000E8048C013E07EAB980088420FA53443206 +:102A80008E8044428D0044528BD449FFD1C18008CE +:102A9000FA21FA5344328E0044428D0044528BD4C2 +:102AA00049FFD1B644028CB88520F083B010149F42 +:102AB0008002149F8001F08544628E80B73F80E6DB +:102AC000854008038025F0865063005CF006E340F3 +:102AD000E82608038001C02000038011B45FF08164 +:102AE000000380238068F082F102F001A53084A009 +:102AF00049FFD3175CF0005B4EF204BEF003F10116 +:102B00008801F103F2029A41E241E906081000014E +:102B1000C1F9480004B18D418CC2D5D95A90010D3C +:102B200044028C70F083B019F085FA01852144626B +:102B30008E00B61FD5C5840044128E8044228CB806 +:102B4000F304B11080A849FFD276FA0144128E0036 +:102B500044228C70F304B11980A849FFD26CF00AAA +:102B6000149F8008F08780C044028C28F08B84007A +:102B7000F085F086F089B406F08C4E02042D5A08D8 +:102B80000604480004295A080404480003AEF1046E +:102B90000003002404730017A04CF08D94018801F9 +:102BA000A64100A00000F183000F800CF104100387 +:102BB000009110A30090F00DA04D94028801A64151 +:102BC000A600F18EF08FC76C5A70010D44028BE0A5 +:102BD000F08B841FF088FA01FB20B61F44128E0090 +:102BE000D50A44028C28F08B8400F7888127B61F11 +:102BF00044128E804000A800A60198885000002C46 +:102C0000940100310037880100210049A502F381B9 +:102C1000F2828003C3038E01D502F001F086F00238 +:102C20005CF00023E8038C01D502FA13F085F10271 +:102C3000B45F806884A0F00149FFD273F106804040 +:102C4000FA02FE0CB43FF50699018809940195211A +:102C500041E400008400888881208060F105E0253F +:102C6000E90F38F200114EF70003886F38FF0011AA +:102C70004EF70003892F8CA150000024D5F080016D +:102C8000F1068A01FE0384274290047380094E9660 +:102C900000038401842AFE5C40908136D50480477D +:102CA00081278067000300209606C060840F100310 +:102CB000009210A300A5C71B8401100300698403C0 +:102CC00014030022840010030083F001C004F0020A +:102CD0005A082305FA0E10030092FA02B43F421577 +:102CE00000733804051112030053D50E440FFFC8BA +:102CF000100300698401140300221003008312737F +:102D000000533E77EAB622130006840012130046F1 +:102D100014130026A477848012130047F1041003D3 +:102D200000821043006FA04B12430036F40D1223B3 +:102D3000003814930025381091011003008510030A +:102D4000009C1003009D1003009E1003009F1003C1 +:102D500000A0100300A1100300A2100300A31003A1 +:102D600000A41213003E8400D559C717F001C00417 +:102D7000F0025A082305FA0E10030092001300A572 +:102D8000FA02B49F42408073221300533804111199 +:102D9000E020E80312030053000300695CF000C860 +:102DA000E80E504300948C0110030069B404A06144 +:102DB0008809B604220300068801A821F00C5A08ED +:102DC0000108A43412030046A4351203004702038D +:102DD0000038E202E80312230038F004F10DA003EA +:102DE000380005010213003EE220E8031203003E12 +:102DF00022030046224300069B044E440003FF22A8 +:102E000022130047220300079A084E040003FE0223 +:102E10000413002A8804E220E8031403002A3C7CFF +:102E20000058840010030068CF2504030017C02257 +:102E30005A000103840344128BD438408000C41A22 +:102E40008801F408F5032010000842F21424FE64FF +:102E5000E02FE9102000000452150000FE02E001FE +:102E6000E909020300385CF00029E9048401100339 +:102E7000006800030068C85B04030017C05804031F +:102E800000115A000255F00EF10F8C01044300228C +:102E90008A0196005A48030604130019C104D50894 +:102EA0005A480207E602E943E5284EF302F88E820B +:102EB000E682E83DE602E93BE52CE83942F4882465 +:102EC0005CF78227E83400030069E603E83000037A +:102ED0000083C823001300BD5A180120840A100380 +:102EE00000820203004750F07FB95CF787F2E815D3 +:102EF000020300468E1E5CF003FCE9058402100309 +:102F000000E6D503101300E6F00AF109F28DF38C08 +:102F100049FFD17CF20DF30C84011403002210034D +:102F200000838400140300173E07EAB6000300681C +:102F30002E57EB62C00604130017C96B480001420C +:102F400004030017C0F9040300115A0002F6040339 +:102F500000225A0005058E02E602E8EE2213004721 +:102F6000220300079A084E040003FE0202430038C1 +:102F700044100CB244F003E8FE644010BC37E22079 +:102F8000E8DB5CF00033E9D8001300A5FA8204FF07 +:102F9000800042F090732243005339E43D1185E2F2 +:102FA00040423C96E09EE80AF406E024E904F40579 +:102FB000E081E8C25CF0012DE9BF44F00190405788 +:102FC00094B6E0A3E8B900030083C80E000300BD77 +:102FD0005A08010B840A10030082F109F00AF28CEE +:102FE00049FFD114F20C8401F10BF3061403002203 +:102FF000100300838400140300178823F30BF405E7 +:103000009ACBE283E9991800800110008023D5F75C +:10301000040300225A000304480000EC0033006956 +:1030200000030092E203E97904130018C90B0003BE +:10303000006F8C011003006F000300A28C011003CD +:1030400000A25EF481C3E80742F48824443057E4C8 +:10305000E26FE80B0003006F8C011003006F0003A8 +:1030600000A48C01100300A4E622E80B0203003642 +:103070008C01120300360003009C8C011003009C9D +:10308000000300685A08010C020300368C01120389 +:1030900000360003009D8C011003009D5EF4802922 +:1030A000E806422488245CF107D1E90B02030036CC +:1030B0008C01120300360003009E8C011003009E59 +:1030C000020300385CF00047E90CCF0B0203003626 +:1030D0008C0112030036000300A08C01100300A035 +:1030E0000403002A5CF00065E90CCF0B02030036F4 +:1030F0008C0112030036000300A18C01100300A113 +:10310000040300198E01E602E874CF732E07EAB9B2 +:10311000E6118405E940D56D0403002540000C1735 +:103120005CF00038E816FE845CF10ABFE8124090BB +:1031300024018D2AE735E80D020300385CF00033E6 +:10314000E808020300360023009E8A0212030036BC +:103150000403002640300C768E6B5CF18422E80874 +:10316000020300360023009C8A0212030036020389 +:103170000036E60BE80F5A18010722030004E41E8C +:10318000E909D50C5A18020B22F300045EF7841AE1 +:10319000E905840214030022D52C00030083C8082B +:1031A000000300BD5A080105840A1003008284014F +:1031B0001403002210030083840014030017D519A0 +:1031C000040300115A000216040300228E02E604D2 +:1031D000E81000030083C808000300BD5A08010579 +:1031E000840A100300828401140300221003008368 +:1031F00004030017C01C44028CB838002800C00A21 +:1032000044028CB8880AF10320000024E0014EF249 +:10321000013E44028C7038102800C121880A20F039 +:103220000024F003E00F4EF20132D51944028CB8AD +:1032300038002800C003F003C00944028C70380035 +:103240002800C00DF0035A08110B84041403002257 +:10325000F0034E030121840114030017CF39040346 +:1032600000228E04E602E934F003C80444028C28EC +:10327000D506F0035A08112D44028BE038002800CF +:10328000C02704130017840214030022C921F1038C +:10329000C9028401140300170403001710A300A53A +:1032A0005A000104FA01D5028400B61FB43FFA02A5 +:1032B000421500733804051112030053A43612039B +:1032C0000046A437120300478400120300380403A9 +:1032D00000225A08010584003E07EAB94400003282 +:1032E0001003006ED578000300209616C074840089 +:1032F000002300901003006EFA22000300914201A7 +:103300000473381401118403FE0C0213003E944927 +:10331000E0208421E80584021003006E842000036D +:10332000006A0423001D50000037E202E8102E0757 +:10333000EAB98E015CF0003BE80A0403003C5EF051 +:1033400000C9E90584031003006E8420002300698E +:1033500004030026400008168C035CF0043EE808D5 +:103360000003006F003300A28A031003006F0033D4 +:10337000006FE66BE8059C119001E003E80584040A +:103380001003006E842000030092E202E903E6428B +:10339000E80584051003006E84200403002A5CF015 +:1033A0000065E9083C0C0058C80584291013006E1C +:1033B0008020040300225A0001075A18010D14133B +:1033C0000022D5035A1801080403002E5A080104EC +:1033D00010030085F009506300FC8C01F0895A004D +:1033E0000A0448FFFBCAF00AB0EB502009D88481D8 +:1033F000B162F007B4008E01E603E91CF00750004B +:1034000000FCF0874C017FF7F304B12280A8840010 +:1034100044128E8044228C2849FFCE0DFA014412BA +:103420008E0044228BE0F304B12B80A849FFCE0329 +:10343000FCDAF007040000225A0002058E04E602BE +:10344000E8DEF007F10400000024A04D940288019A +:10345000A642A783E2C1E9D3F007040000175A0887 +:10346000010538009408D5055A08020438408C0834 +:103470008C21D5F1F001F102E0204EF3FB4EF10575 +:103480008441382080088C01D5F78404140300227D +:1034900048FFFF1F840248FFFEE142F488245CF7E6 +:1034A000815F4EF3FD1648FFFD04000000000000A0 +:1034B000000000000000000000000000000000000C +:1034C000E4DE0000AD130000E4DF0000FEE5C435DB +:1034D000E4DE0000170D000092F3000084ABFFF063 +:1034E000E4DE00008B140000AA00010013361B86E6 +:1034F000E4DE00000B080000361501002104B25084 +:10350000E4DE000067170000421D010068454E1709 +:10351000050000000000000001000000FFFFFFFFA9 +:10352000030000000700000001000000AA000000E6 +:10353000120000001B000000480000004B000000CB +:1035400052000000620000006300000072000000F2 +:10355000730000001E010000210100002D01000089 +:103560003B010000480100004B0100006C0100001D +:1035700078010000870100008B010000920100002B +:103580009B010000B2010000B3010000B401000083 +:10359000BB010000CB010000D2010000E1010000EE +:1035A000E2010000E3010000EE01000078040000E9 +:1035B000B4040000BB040000ED040000210500007D +:1035C0002D050000E1050000EE0500001E060000CC +:1035D0004B0600006D060000CB060000D20600007E +:1035E000E2060000E3060000ED0600004B070000C5 +:1035F000870700008B070000B8070000ED120000ED +:10360000B81700004B1B00006D1B00008B1B000057 +:10361000FFFFFFFF4040C8C8C8C80101010000000B +:10362000000000000000000000000000000000009A +:10363000000000000000000000000000000000008A +:10364000000000000000000000000000000000007A +:10365000000000000000000000000000000000006A +:10366000000000000000000000000000000000005A +:10367000000000000000000000000000000000004A +:10368000000000000000000000000000000000003A +:10369000000000000000000000000000000000002A +:1036A000000000000000000000000000000000001A +:1036B000000000000000000000000000000000000A +:1036C00000000000000000000000000000000000FA +:1036D00000000000000000000000000000000000EA +:1036E00000000000000000000000000000000000DA +:1036F00000000000000000000000000000000000CA +:1037000000000000000000000000000000000000B9 +:1037100000000000000000000000000000000000A9 +:103720000000000000000000000000000000000099 +:103730000000000000000000000000000000000089 +:103740000000000000000000000000000000000079 +:103750000000000000000000000000000000000069 +:103760000000000000000000000000000000000059 +:103770000000000000000000000000000000000049 +:103780000000000000000000000000000000000039 +:103790000000000000000000000000000000000029 +:1037A0000000000000000000000000000000000019 +:1037B0000000000000000000000000000000000009 +:1037C00000000000000000000000000000000000F9 +:1037D00000000000000000000000000000000000E9 +:1037E00000000000000000000000000000000000D9 +:1037F00000000000000000000000000000000000C9 +:1038000000000000000000000000000000000000B8 +:1038100000000000000000000000000000000000A8 +:103820000000000000000000000000000000000098 +:103830000000000000000000000000000000000088 +:103840000000000000000000000000000000000078 +:103850000000000000000000000000000000000068 +:103860000000000000000000000000000000000058 +:103870000000000000000000000000000000000048 +:103880000000000000000000000000000000000038 +:103890000000000000000000000000000000000028 +:1038A0000000000000000000000000000000000018 +:1038B0000000000000000000000000000000000008 +:1038C00000000000000000000000000000000000F8 +:1038D00000000000000000000000000000000000E8 +:1038E00000000000000000000000000000000000D8 +:1038F00000000000000000000000000000000000C8 +:1039000000000000000000000000000000000000B7 +:1039100000000000000000000000000000000000A7 +:103920000000000000000000000000000000000097 +:103930000000000000000000000000000000000087 +:103940000000000000000000000000000000000077 +:103950000000000000000000000000000000000067 +:103960000000000000000000000000000000000057 +:103970000000000000000000000000000000000047 +:103980000000000000000000000000000000000037 +:103990000000000000000000000000000000000027 +:1039A0000000000000000000000000000000000017 +:1039B0000000000000000000000000000000000007 +:1039C00000000000000000000000000000000000F7 +:1039D00000000000000000000000000000000000E7 +:1039E00000000000000000000000000000000000D7 +:1039F00000000000000000000000000000000000C7 +:103A000000000000000000000000000000000000B6 +:103A100000000000000000000000000000000000A6 +:103A20000000000000000000000000000000000096 +:103A30000000000000000000000000000000000086 +:103A40000000000000000000000000000000000076 +:103A50000000000000000000000000000000000066 +:103A60000000000000000000000000000000000056 +:103A70000000000000000000000000000000000046 +:103A80000000000000000000000000000000000036 +:103A90000000000000000000000000000000000026 +:103AA0000000000000000000000000000000000016 +:103AB0000000000000000000000000000000000006 +:103AC00000000000000000000000000000000000F6 +:103AD00000000000000000000000000000000000E6 +:103AE00000000000000000000000000000000000D6 +:103AF00000000000000000000000000000000000C6 +:103B000000000000000000000000000000000000B5 +:103B100000000000000000000000000000000000A5 +:103B20000000000000000000000000000000000095 +:103B30000000000000000000000000000000000085 +:103B40000000000000000000000000000000000075 +:103B50000000000000000000000000000000000065 +:103B60000000000000000000000000000000000055 +:103B70000000000000000000000000000000000045 +:103B80000000000000000000000000000000000035 +:103B90000000000000000000000000000000000025 +:103BA0000000000000000000000000000000000015 +:103BB0000000000000000000000000000000000005 +:103BC00000000000000000000000000000000000F5 +:103BD00000000000000000000000000000000000E5 +:103BE00000000000000000000000000000000000D5 +:103BF00000000000000000000000000000000000C5 +:103C000000000000000000000000000000000000B4 +:103C100000000000000000000000000000000000A4 +:103C20000000000000000000000000000000000094 +:103C30000000000000000000000000000000000084 +:103C40000000000000000000000000000000000074 +:103C50000000000000000000000000000000000064 +:103C60000000000000000000000000000000000054 +:103C70000000000000000000000000000000000044 +:103C80000000000000000000000000000000000034 +:103C90000000000000000000000000000000000024 +:103CA0000000000000000000000000000000000014 +:103CB0000000000000000000000000000000000004 +:103CC00000000000000000000000000000000000F4 +:103CD00000000000000000000000000000000000E4 +:103CE00000000000000000000000000000000000D4 +:103CF00000000000000000000000000000000000C4 +:103D000000000000000000000000000000000000B3 +:103D100000000000000000000000000000000000A3 +:103D20000000000000000000000000000000000093 +:103D30000000000000000000000000000000000083 +:103D40000000000000000000000000000000000073 +:103D50000000000000000000000000000000000063 +:103D60000000000000000000000000000000000053 +:103D70000000000000000000000000000000000043 +:103D80000000000000000000000000000000000033 +:103D90000000000000000000000000000000000023 +:103DA0000000000000000000000000000000000013 +:103DB0000000000000000000000000000000000003 +:103DC00000000000000000000000000000000000F3 +:103DD00000000000000000000000000000000000E3 +:103DE00000000000000000000000000000000000D3 +:103DF00000000000000000000000000000000000C3 +:103E000000000000000000000000000000000000B2 +:103E100000000000000000000000000000000000A2 +:103E20000000000000000000000000000000000092 +:103E30000000000000000000000000000000000082 +:103E40000000000000000000000000000000000072 +:103E50000000000000000000000000000000000062 +:103E60000000000000000000000000000000000052 +:103E70000000000000000000000000000000000042 +:103E80000000000000000000000000000000000032 +:103E90000000000000000000000000000000000022 +:103EA0000000000000000000000000000000000012 +:103EB0000000000000000000000000000000000002 +:103EC00000000000000000000000000000000000F2 +:103ED00000000000000000000000000000000000E2 +:103EE00000000000000000000000000000000000D2 +:103EF00000000000000000000000000000000000C2 +:103F000000000000000000000000000000000000B1 +:103F100000000000000000000000000000000000A1 +:103F20000000000000000000000000000000000091 +:103F30000000000000000000000000000000000081 +:103F40000000000000000000000000000000000071 +:103F50000000000000000000000000000000000061 +:103F60000000000000000000000000000000000051 +:103F70000000000000000000000000000000000041 +:103F80000000000000000000000000000000000031 +:103F90000000000000000000000000000000000021 +:103FA0000000000000000000000000000000000011 +:103FB0000000000000000000000000000000000001 +:103FC00000000000000000000000000000000000F1 +:103FD00000000000000000000000000000000000E1 +:103FE00000000000000000000000000000000000D1 +:103FF00000000000000000000000000000000000C1 +:1040000000000000000000000000000000000000B0 +:1040100000000000000000000000000000000000A0 +:104020000000000000000000000000000000000090 +:104030000000000000000000000000000000000080 +:104040000000000000000000000000000000000070 +:104050000000000000000000000000000000000060 +:104060000000000000000000000000000000000050 +:104070000000000000000000000000000000000040 +:104080000000000000000000000000000000000030 +:104090000000000000000000000000000000000020 +:1040A0000000000000000000000000000000000010 +:1040B0000000000000000000000000000000000000 +:1040C00000000000000000000000000000000000F0 +:1040D00000000000000000000000000000000000E0 +:1040E00000000000000000000000000000000000D0 +:1040F00000000000000000000000000000000000C0 +:1041000000000000000000000000000000000000AF +:10411000000000000000000000000000000000009F +:10412000000000000000000000000000000000008F +:10413000000000000000000000000000000000007F +:10414000000000000000000000000000000000006F +:10415000000000000000000000000000000000005F +:10416000000000000000000000000000000000004F +:10417000000000000000000000000000000000003F +:10418000000000000000000000000000000000002F +:10419000000000000000000000000000000000001F +:1041A000000000000000000000000000000000000F +:1041B00000000000000000000000000000000000FF +:1041C00000000000000000000000000000000000EF +:1041D00000000000000000000000000000000000DF +:1041E00000000000000000000000000000000000CF +:1041F00000000000000000000000000000000000BF +:1042000000000000000000000000000000000000AE +:10421000000000000000000000000000000000009E +:10422000000000000000000000000000000000008E +:10423000000000000000000000000000000000007E +:10424000000000000000000000000000000000006E +:10425000000000000000000000000000000000005E +:10426000000000000000000000000000000000004E +:10427000000000000000000000000000000000003E +:10428000000000000000000000000000000000002E +:10429000000000000000000000000000000000001E +:1042A000000000000000000000000000000000000E +:1042B00000000000000000000000000000000000FE +:1042C00000000000000000000000000000000000EE +:1042D00000000000000000000000000000000000DE +:1042E00000000000000000000000000000000000CE +:1042F00000000000000000000000000000000000BE +:1043000000000000000000000000000000000000AD +:10431000000000000000000000000000000000009D +:10432000000000000000000000000000000000008D +:10433000000000000000000000000000000000007D +:10434000000000000000000000000000000000006D +:10435000000000000000000000000000000000005D +:10436000000000000000000000000000000000004D +:10437000000000000000000000000000000000003D +:10438000000000000000000000000000000000002D +:10439000000000000000000000000000000000001D +:1043A000000000000000000000000000000000000D +:1043B00000000000000000000000000000000000FD +:1043C00000000000000000000000000000000000ED +:1043D00000000000000000000000000000000000DD +:1043E00000000000000000000000000000000000CD +:1043F00000000000000000000000000000000000BD +:1044000000000000000000000000000000000000AC +:10441000000000000000000000000000000000009C +:10442000000000000000000000000000000000008C +:10443000000000000000000000000000000000007C +:10444000000000000000000000000000000000006C +:10445000000000000000000000000000000000005C +:10446000000000000000000000000000000000004C +:10447000000000000000000000000000000000003C +:10448000000000000000000000000000000000002C +:10449000000000000000000000000000000000001C +:1044A000000000000000000000000000000000000C +:1044B00000000000000000000000000000000000FC +:1044C00000000000000000000000000000000000EC +:1044D00000000000000000000000000000000000DC +:1044E00000000000000000000000000000000000CC +:1044F00000000000000000000000000000000000BC +:1045000000000000000000000000000000000000AB +:10451000000000000000000000000000000000009B +:10452000000000000000000000000000000000008B +:10453000000000000000000000000000000000007B +:10454000000000000000000000000000000000006B +:10455000000000000000000000000000000000005B +:10456000000000000000000000000000000000004B +:10457000000000000000000000000000000000003B +:10458000000000000000000000000000000000002B +:10459000000000000000000000000000000000001B +:1045A000000000000000000000000000000000000B +:1045B00000000000000000000000000000000000FB +:1045C00000000000000000000000000000000000EB +:1045D00000000000000000000000000000000000DB +:1045E00000000000000000000000000000000000CB +:1045F00000000000000000000000000000000000BB +:1046000000000000000000000000000000000000AA +:10461000000000000000000000000000000000009A +:10462000000000000000000000000000000000008A +:10463000000000000000000000000000000000007A +:10464000000000000000000000000000000000006A +:10465000000000000000000000000000000000005A +:10466000000000000000000000000000000000004A +:10467000000000000000000000000000000000003A +:10468000000000000000000000000000000000002A +:10469000000000000000000000000000000000001A +:1046A000000000000000000000000000000000000A +:1046B00000000000000000000000000000000000FA +:1046C00000000000000000000000000000000000EA +:1046D00000000000000000000000000000000000DA +:1046E00000000000000000000000000000000000CA +:1046F00000000000000000000000000000000000BA +:1047000000000000000000000000000000000000A9 +:104710000000000000000000000000000000000099 +:104720000000000000000000000000000000000089 +:104730000000000000000000000000000000000079 +:104740000000000000000000000000000000000069 +:104750000000000000000000000000000000000059 +:104760000000000000000000000000000000000049 +:104770000000000000000000000000000000000039 +:104780000000000000000000000000000000000029 +:104790000000000000000000000000000000000019 +:1047A0000000000000000000000000000000000009 +:1047B00000000000000000000000000000000000F9 +:1047C00000000000000000000000000000000000E9 +:1047D00000000000000000000000000000000000D9 +:1047E00000000000000000000000000000000000C9 +:1047F00000000000000000000000000000000000B9 +:10480000050201014400BA0F000000002401050167 +:1048100000031459F553BD630000000000000000C0 +:104820003C4E0000904E0000E44E0000384F000067 +:104830008C4F0000E04F000034500000200C0000BE +:104840002088410AE6A004000000000000000000EB +:104850000000000000280000888888888800000088 +:1048600088508454C054A05B405EC85DA85C4880FA +:104870000000105C2F04090000C186002DB4180050 +:10488000137DDC0227060C0000090009000000006F +:10489000080C00000C0000000000000000000000F8 +:1048A0000000000000000000000400000100000003 +:1048B000000000008850A854C054A05B405EC85D52 +:1048C000185C48800000105C2F04090000C106003D +:1048D0002DB41800137DDC0227060C000009000926 +:1048E00000000000800000002088410AE6A00400CB +:1048F0000000000000000000000000000028000090 +:10490000888808000000000088508454C054A05BD0 +:10491000405EC85D185C48800000105C2F040900F0 +:1049200000C186012DB41800137DDC0227010600AA +:104930000009000900000000100C0000CD35D71C54 +:10494000CD3507000000000000000000000000005E +:104950000028000088880800000000008850845467 +:10496000C054A05B405EC85DA85C48800000105C3D +:104970002F04090000C186002DB41800137DDC024D +:1049800027060C0000C900C900000000400000001C +:104990000F3EF8200F3E080000000000000000005D +:1049A00000000000002800008888080000000000C7 +:1049B00088508454C054A05B405EC85D185C488039 +:1049C0000000105C2F04090000C186012DB41800FE +:1049D000137DDC022701060000C900C900000000A9 +:1049E000200C00002088410AE620000000000000A2 +:1049F00000000000000000000024000055550100E8 +:104A000000000000885084548858A05B405EC85D58 +:104A1000185C48800000105C2F04090000C186006B +:104A20002DB41800137DDC0227060C0000C900C954 +:104A300000000000200C00002088410AE6A00400CD +:104A4000000000000000000000000000002800003E +:104A500000000000000000008850A854C054A05B73 +:104A6000405EC85DA85C48800000105C2F0409000F +:104A700000C186002DB41800137DDC0227060C004F +:104A800000C900C900000000000000000909000082 +:104A90000010000020080000E30F0000B4DC21003B +:104AA000030003000000000094489648504A0000AC +:104AB00020052005D00600000000000000000000D6 +:104AC00002000000000000000000010001100000D2 +:104AD00020080000E30F0000B4DC01000300020026 +:104AE00000000000DC06FE06F00B000000002200C3 +:104AF000100500000000000000000000020000009F +:104B00000000000001010200011000002008000068 +:104B1000E30F0000B4DC010003000200000000000D +:104B2000DE06FC06F20B0000020020001205000069 +:104B30000000000000000000020000000000000073 +:104B4000020202000110000020080000E30F000034 +:104B5000B4DC01000300020000000000E006FA06D9 +:104B6000F40B000004001E0014050000000000000B +:104B7000000000000200000000000000030302002B +:104B80000110000020080000E30F0000B4DC010069 +:104B90000300020000000000E206F806F60B000029 +:104BA00006001C00160500000000000000000000C8 +:104BB00002000000000000000404020001100000D8 +:104BC00020080000E30F0000B4DC01000300020035 +:104BD00000000000E406F6060000000008001A00CD +:104BE00000000000000000000000000000000000C5 +:104BF0000000000005050200011000002008000070 +:104C0000E30F0000B4DC010003000200000000001C +:104C1000E606F406000000000A001800000000008C +:104C20000000000000000000000000000000000084 +:104C3000060602000110000020080000E30F00003B +:104C4000B4DC01000300020000000000E806F206E8 +:104C5000000000000C001600000000000000000032 +:104C60000000000000000000000000000707020034 +:104C70000110000020080000E30F0000B4DC010078 +:104C80000300020000000000EA06F0060000000039 +:104C90000E001400000000000000000000000000F2 +:104CA00000000000000000000808020001100000E1 +:104CB00020080000E30F0000B4DC01000300020044 +:104CC00000000000EC06EE060000000010001200DC +:104CD00000000000000000000000000000000000D4 +:104CE0000000000009090000001001002008000079 +:104CF000C00F0000B4DC210003000300000000002E +:104D000094489648504A0000B005B005D00600000F +:104D10000000000000000000020000000000000091 +:104D2000090900000010000020080000C00F00006A +:104D3000B4DC210003000300000000009448964802 +:104D4000504A000040064006D00600000000000067 +:104D50000000000002000000810000000A090001BC +:104D60000110000020080000F70F6000B4DC01060D +:104D7000030002000000000000000000000000002E +:104D80001C3C1C3CAC3C000000000000000000008B +:104D900002000000000000000909000000100000EF +:104DA00020080000D30F0000B4DC2106030003003C +:104DB0000000000094489648504A00002005200555 +:104DC000D00600000000000000000000020000000B +:104DD0000000000009090000001000002008000089 +:104DE000D30F0000B4DC2106030003000000000024 +:104DF0000000000000000000200520050000000069 +:104E000000000000000000000000000000000000A2 +:104E1000090900000010000020080000D30F000066 +:104E2000B4DC2103030003000000000000000000C8 +:104E30000000000020052005000000000000000028 +:104E40000000000000000000000000000909000050 +:104E50000010000020080000D30F0000B4DC210384 +:104E6000030003000000000000000000000000003C +:104E700020052005000000000000000000000000E8 +:104E8000000000000F00000010B43844693E00002C +:104E9000030000002DB4B4C469020000000000004B +:104EA0002D38B48410030000000000002DB4B4C4F9 +:104EB00069030000030000002DB4B4C469030000BE +:104EC0005858585858585858585858585858585862 +:104ED0005858585858585858585858585858585852 +:104EE0005858585858585858585858585858585842 +:104EF0005858585858585858585858585858585832 +:104F00005858585858585858580058000000000031 +:104F100000000000000000005858585858585858D1 +:104F20005858585858585858585858585858585801 +:104F300058585858585858585858585858585858F1 +:104F400058585858585858585858585858585858E1 +:104F500058585858585858585858585858585858D1 +:104F60005800580000000000000000000000000091 +:104F700058585858585858585858585858585858B1 +:104F800058585858585858585858585858585858A1 +:104F90005858585858585858585858585858585891 +:104FA0005858585858585858585858585858585881 +:104FB0005858585858585858580058000000000081 +:104FC0000000000000000000585858585858585821 +:104FD0005858585858585858585858585858585851 +:104FE0005858585858585858585858585858585841 +:104FF0005858585858585858585858585858585831 +:105000005858585858585858585858585858585820 +:1050100058005800000000000000000000000000E0 +:105020005858585858585858585858585858585800 +:1050300058585858585858585858585858585858F0 +:1050400058585858585858585858585858585858E0 +:1050500058585858585858585858585858585858D0 +:1050600058585858585858585800580000000000D0 +:105070000000000000000000585858585858585870 +:1050800058585858585858585858585858585858A0 +:105090005858585858585858585858585858585890 +:1050A0005858585858585858585858585858585880 +:1050B0005858585858585858585858585858585870 +:1050C0005800580000000000000000000000000030 +:1050D0005858585858585858585858585858585850 +:1050E0005858585858585858585858585858585840 +:1050F0005858585858585858585858585858585830 +:10510000585858585858585858585858585858581F +:10511000585858585858585858005800000000001F +:1051200000000000000000005858585858585858BF +:1051300058585858585858585858585858585858EF +:1051400058585858585858585858585858585858DF +:1051500058585858585858585858585858585858CF +:1051600058585858585858585858585858585858BF +:10517000580058000000000000000000000000007F +:10518000585858585858585858585858585858589F +:10519000585858585858585858585858585858588F +:1051A000585858585858585858585858585858587F +:1051B000585858585858585858585858585858586F +:1051C000585858585858585858005800000000006F +:1051D00000000000000000000000000000000000CF +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:10520000000000000000000000000000000000009E +:10521000000000000000000000000000000000008E +:10522000000000000000000000000000000000007E +:10523000000000000000000000000000000000006E +:10524000000000000000000000000000000000005E +:10525000000000000000000000000000000000004E +:10526000000000000000000000000000000000003E +:10527000000000000000000000000000000000002E +:10528000000000000000000000000000000000001E +:10529000000000000000000000000000000000000E +:1052A00000000000000000000000000000000000FE +:1052B00000000000000000000000000000000000EE +:1052C00000000000000000000000000000000000DE +:1052D00000000000000000000000000000000000CE +:1052E00000000000000000000000000000000000BE +:1052F00000000000000000000000000000000000AE +:10530000000000000000000000000000000000009D +:10531000000000000000000000000000000000008D +:10532000000000000000000000000000000000007D +:10533000000000000000000000000000000000006D +:10534000000000000000000000000000000000005D +:10535000000000000000000000000000000000004D +:10536000000000000000000000000000000000003D +:10537000000000000000000000000000000000002D +:10538000000000000000000000000000000000001D +:10539000000000000000000000000000000000000D +:1053A00000000000000000000000000000000000FD +:1053B00000000000000000000000000000000000ED +:1053C00000000000000000000000000000000000DD +:1053D00000000000000000000000000000000000CD +:1053E00000000000000000000000000000000000BD +:1053F00000000000000000000000000000000000AD +:10540000000000000000000000000000000000009C +:10541000000000000000000000000000000000008C +:10542000000000000000000000000000000000007C +:10543000000000000000000000000000000000006C +:10544000000000000000000000000000000000005C +:10545000000000000000000000000000000000004C +:10546000000000000000000000000000000000003C +:10547000000000000000000000000000000000002C +:10548000000000000000000000000000000000001C +:10549000000000000000000000000000000000000C +:1054A00000000000000000000000000000000000FC +:1054B00000000000000000000000000000000000EC +:1054C00000000000000000000000000000000000DC +:1054D00000000000000000000000000000000000CC +:1054E00000000000000000000000000000000000BC +:1054F00000000000000000000000000000000000AC +:10550000000000000000000000000000000000009B +:10551000000000000000000000000000000000008B +:10552000000000000000000000000000000000007B +:10553000000000000000000000000000000000006B +:10554000000000000000000000000000000000005B +:10555000000000000000000000000000000000004B +:10556000000000000000000000000000000000003B +:10557000000000000000000000000000000000002B +:10558000000000000000000000000000000000001B +:10559000000000000000000000000000000000000B +:1055A000B6ADB69DB6ADB6AD02000200B6ADB66DF5 +:1055B000B6A5B6A506000600B6ADB6ADB6ACB69CAF +:1055C00006000600B6ADB6AD96AD966D06000600B7 +:1055D000B6ADB6ADB2ADB2AD06000600B6A5B6A585 +:1055E000B6ADB6AD06000600B6ACB6ACB6ADB6AD5F +:1055F0000600060096AD96ADB6ADB6AD0600060047 +:10560000B2ADB2ADB6ADB6AD0600060092A49254EE +:1056100092A4925402000200E4007000DE18000020 +:10562000BE807000BE807000DE006F00FFFFFFFFD5 +:1056300033DE33DEDDDDDDDD33323332DEDEDEDE92 +:10564000DEDEDEDEDEDEDEDEDEDE000001010101AA +:105650000101010101010101000000000000000042 +:105660000000000000000000DE80DE80DE00DE00C2 +:1056700033DE33DE33DE33DEDDDDDDDDDDDDDDDDFE +:105680003332333233323332DEDEDEDEDDDDDDDD9A +:105690000101010100000000000000000000000006 +:1056A0000000000000000000B30646001C190000C6 +:1056B0008D0658038D0658031C018E005305E40027 +:1056C0005A1C5A1C1B1B1B1B5A595A591C1C1C1CAC +:1056D0001C1C1C1C1C1C1C1C1C1C000001010101AE +:1056E00001010101010101010892240040922409F5 +:1056F00049920000000000001C011C011C011C015B +:105700005A1C5A1C5A1C5A1C1B1B1B1B1B1B1B1BE9 +:105710005A595A595A595A591C1C1C1C1B1B1B1BE1 +:1057200001010101000000000812081249004900AF +:105730004012401201000100B30646001C1900008F +:105740008D0658038D0658031C018E005305E40096 +:105750005A1C5A1C1B1B1B1B5A595A591C1C1C1C1B +:105760001C1C1C1C1C1C1C1C1C1C0000010101011D +:105770000101010101010101089224004092240964 +:1057800049920000000000001C011C011C011C01CA +:105790005A1C5A1C5A1C5A1C1B1B1B1B1B1B1B1B59 +:1057A0005A595A595A595A591C1C1C1C1B1B1B1B51 +:1057B000010101010000000008120812490049001F +:1057C0004012401201000100030300000303030321 +:1057D000030303030303030303030101E8EBAAAA82 +:1057E000C0000000000000000303030303030303E1 +:1057F00001010101EB0BE80B00FC00FC00000000C4 +:10580000000000000303000003030303030303037A +:10581000030303030303010108000000C0000000AC +:10582000000000000303030303030303010101015C +:10583000EB0B080000FC00FC000000000000000072 +:105840000004200003105000061C80000928B0004E +:105850000C34E0000F401001124C4001155870014B +:105860001864A0011B70D0011E7C00022188300248 +:105870002494600227A090022AACC0022DB8F00246 +:1058800030C4200333D0500336DC800339E8B00342 +:105890003CF4E0033F001104420C4104451871043C +:1058A000129060034868C1067E40220AB418830D36 +:1058B000EAF0E31020C9441456A1A5178C79061B01 +:1058C000C251671EF829C8212E02292564DA090071 +:1058D0007602200124D880045AB0E1079088420B58 +:1058E000C660A30EFC3804123211651568E9C518AC +:1058F0009EC1261CD499871F0A72E822404A492675 +:10590000004840023620A1056CF80109A2D0620CC3 +:10591000D8A8C30F0E812413445985167A31E6198D +:10592000B009471DE6E1A7201CBA08245292692756 +:10593000004840023620A1056CF80109A2D0620C93 +:10594000D8A8C30F0E812413445985167A31E6195D +:10595000B009471DE6E1A7201CBA08245292692726 +:1059600000D849265202E9221C2A881FE651271C2A +:10597000B079C6187AA1651544C904120EF1A30EB8 +:10598000D818430BA240E2076C68810436902001CE +:105990007692292540BAC8210AE2671ED409071B5E +:1059A0009E31A617685945143281E410FCA8830D76 +:1059B000C6D0220A90F8C1065A206103244800008C +:1059C00000000000000000000000000000000000D7 +:1059D00000000000000000000000000000000000C7 +:1059E00000000000000000000000000000000000B7 +:1059F00000000000000000000000000000000000A7 +:105A00000000000000000000000000000000000096 +:105A10000000000000000000000000000000000086 +:105A20000000000000000000000000000000000076 +:105A30000000000000000000000000000000000066 +:105A40000000000000000000000000000000000056 +:105A50000000000000000000000000000000000046 +:105A60000000000000000000000000000000000036 +:105A70000000000000000000000000000000000026 +:105A80000000000000000000000000000000000016 +:105A90000000000000000000000000000000000006 +:105AA00000000000000000000000000000000000F6 +:105AB00000000000000000000000000000000000E6 +:105AC00000000000000000000000000000000000D6 +:105AD00000000000000000000000000000000000C6 +:105AE00000000000000000000000000000000000B6 +:105AF00000000000000000000000000000000000A6 +:105B00000000000000000000000000000000000095 +:105B10000000000000000000000000000000000085 +:105B20000000000000000000000000000000000075 +:105B30000000000000000000000000000000000065 +:105B40000000000000000000000000000000000055 +:105B50000000000000000000000000000000000045 +:105B60000000000000000000000000000000000035 +:105B70000000000000000000000000000000000025 +:105B80000000000000000000000000000000000015 +:105B90000000000000000000000000000000000005 +:105BA00000000000000000000000000000000000F5 +:105BB00000000000000000000000000000000000E5 +:105BC00000000000000000000000000000000000D5 +:105BD00000000000000000000000000000000000C5 +:105BE00000000000000000000000000000000000B5 +:105BF00000000000000000000000000000000000A5 +:105C00000502010100000000000000000001040185 +:105C1000000435110000000000000000000000003A +:105C2000286200007C620000500C00002088414A7D +:105C3000E6200040000000400000000000000000DE +:105C400000240000EEEE010000000000D06280673A +:105C5000BC672C6BB46D3C6D1C6C104F0000105772 +:105C60002F04095400C186012DB41C00137DDC22D1 +:105C70002701060000C900C900000000500C000008 +:105C80002088414AE620004000000040000000005B +:105C90000000000000240000EEEE01000000000003 +:105CA00028658067BC67A46BB46D3C6D1C6C9C1D43 +:105CB000000010572F04095400C186012DB41C00A8 +:105CC000137DDC022701060000C900C900000000A6 +:105CD000000000000000000000100000200800008C +:105CE000DF0F0000FF8E2300000000000000000016 +:105CF000DC06FE06F00B000000001200100500009C +:105D00000000000000000000020000000000000091 +:105D1000000104000010000020080000DF0F000058 +:105D2000FF8E23000000000000000000DE06FC06DD +:105D3000F20B000002001400120500000000000039 +:105D4000000000000200000000000000000205004A +:105D50000010000020080000DF0F0000FF8E23006D +:105D60000000000000000000E006FA06F40B00004E +:105D700004001600140500000000000000000000F0 +:105D800002000000000000000003060000100000F8 +:105D900020080000DF0F0000FF8E2300000000003D +:105DA00000000000E206F806F60B000006001800EE +:105DB00016050000000000000000000002000000C6 +:105DC0000000000000040700001000002008000090 +:105DD000DF0F0000FF8E2300000000000000000025 +:105DE000E406F6060000000008001A0000000000AB +:105DF00000000000000000000000000000000000A3 +:105E0000000508000010000020080000DF0F00005F +:105E1000FF8E23000000000000000000E606F406EC +:105E2000000000000A001C0000000000000000004C +:105E30000000000000000000000000000006090053 +:105E40000010000020080000DF0F0000FF8E23007C +:105E50000000000000000000E806F206000000005C +:105E60000C001E0000000000000000000000000008 +:105E7000000000000000000000070A000010000001 +:105E800020080000DF0F0000FF8E2300000000004C +:105E900000000000EA06F006000000000E002000EE +:105EA00000000000000000000000000000000000F2 +:105EB0000000000000080B00001000002008000097 +:105EC000DF0F0000FF8E2300000000000000000034 +:105ED000EC06EE06000000001000220000000000AA +:105EE00000000000000000000000000000000000B2 +:105EF000080801000110000020080000DF0F00006A +:105F0000F44120000300030000000000EC06EE0650 +:105F1000000000000000240048004A0000000000CB +:105F2000000000000300000000000000000001016C +:105F30000110000020080000DF0F0000B44800003E +:105F40000000000000000000DC06FE06F00B000070 +:105F5000000012001005000000000000000000001A +:105F6000020000000000000000010201011000001A +:105F700020080000DF0F0000B4480000000000000F +:105F800000000000DE06FC06F20B00000200140018 +:105F900012050000000000000000000002000000E8 +:105FA00000000000000202010110000020080000B3 +:105FB000DF0F0000B44800000000000000000000F7 +:105FC000E006FA06F40B00000400160014050000B9 +:105FD00000000000000000000200000000000000BF +:105FE000000302010110000020080000DF0F000084 +:105FF000B44800000000000000000000E206F806BF +:10600000F60B000006001800160500000000000056 +:106010000000000002000000000000000004020177 +:106020000110000020080000DF0F0000B44800004D +:106030000000000000000000E406F606000000007A +:1060400008001A000000000000000000000000002E +:106050000000000000000000000502010110000027 +:1060600020080000DF0F0000B4480000000000001E +:1060700000000000E606F406000000000A001C0014 +:106080000000000000000000000000000000000010 +:1060900000000000000602010110000020080000BE +:1060A000DF0F0000B4480000000000000000000006 +:1060B000E806F206000000000C001E0000000000D0 +:1060C00000000000000000000000000000000000D0 +:1060D000000702010110000020080000DF0F00008F +:1060E000B44800000000000000000000EA06F006CE +:1060F000000000000E002000000000000000000072 +:106100000000000000000000000000000008030183 +:106110000110000020080000DF0F0000B44800005C +:106120000000000000000000EC06EE060000000089 +:10613000100022000000000000000000000000002D +:10614000000000000000000008080200011000002C +:1061500020080000DF0F0000F448200003000300C7 +:1061600000000000EC06EE06000000000000240025 +:1061700048004A000000000000000000030000008A +:10618000000000002DB4B4C4690300000300000047 +:106190002DB4B4C4690300000F00000010B43844EB +:1061A000693E0000000000002D38B4841003000098 +:1061B00000000000000000000000000000000000DF +:1061C00000000000000000000000000000000000CF +:1061D00000000000000000000000000000000000BF +:1061E00000000000000000000000000000000000AF +:1061F000000000000000000000000000000000009F +:10620000000000000000000000000000000000008E +:10621000000000000000000000000000000000007E +:10622000000000000000000000000000000000006E +:10623000000000000000000000000000000000005E +:10624000000000000000000000000000000000004E +:10625000000000000000000000000000000000003E +:10626000000000000000000000000000000000002E +:10627000000000000000000000000000000000001E +:10628000000000000000000000000000000000000E +:1062900000000000000000000000000000000000FE +:1062A00000000000000000000000000000000000EE +:1062B00000000000000000000000000000000000DE +:1062C00000000000000000000000000000000000CE +:1062D000000000002499249924A924A902000200A6 +:1062E0002469246924A524A50400040024A924A960 +:1062F000A498A4980400040024A924A9146914698A +:106300000400040024A924A922A922A9040004004D +:1063100024A524A524A924A904000400A4A8A4A8B1 +:1063200024A924A90400040014A514A924A924A9BB +:106330000400040022A922A924A924A9040004001D +:10634000000000000000000000000000FFFFFF3F11 +:10635000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F4D +:10636000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F3D +:10637000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F2D +:10638000FFFFFF3FFFFFFF7FFFFFFF3FFFFFFF3FDD +:10639000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F0D +:1063A000FFFFFF3FFFFFFF3FFFFFFF3F00484002AF +:1063B0003620A1056CF80189A2D0620CD8A8C30FC1 +:1063C0000E812413445985167A31E619B009471D08 +:1063D000E6E1A7601CBA08245292692700484002EF +:1063E0003620A1056CF801C9A2D0620CD8A8C30F51 +:1063F0000E812413445985967A31E619B009471D58 +:10640000E6E1A7201CBA08245292692769076000B8 +:106410003A1900004707B3034707B3033A019D0049 +:106420000D06EE005A3A5A3A393939395A595A59F9 +:106430003A3A3A3A3A3A3A3A3A3A3A3A3A3A000030 +:106440000101010101010101010101010892240082 +:106450004092240949920000000000003A013A01EC +:106460003A013A015A3A5A3A5A3A5A3A3939393982 +:10647000393939395A595A595A595A593A3A3A3A84 +:1064800039393939010101010000000008120812F0 +:10649000490049004012401201000100445985168C +:1064A0007A31E619B009471DE6E1A7201CBA082495 +:1064B0005292692700000000000000000000000068 +:1064C00000000000000000000000000000000000CC +:1064D00000000000000000000000000000000000BC +:1064E00000000000000000000000000000000000AC +:1064F000000000000000000000000000000000009C +:10650000000000000000000000000000000000008B +:10651000000000000000000000000000000000007B +:1065200000000000000000000000000022992499F3 +:1065300024A924A9040002001469246924A924A51B +:1065400004000400A4A824A92499A4980400040029 +:1065500024A524A9246914690400040024A924A9F9 +:1065600022A922A90400040024A924A514A924A96D +:106570000400040024A9A4A8A4A824A904000400D9 +:1065800024A914A924A524A90400040024A922A94B +:1065900024A924A9020004002499249924A924A947 +:1065A00002000200B29DB69DB6ADB6AD0600020077 +:1065B000966DB66DB6ADB6A506000600B6ACB6AD26 +:1065C000B69DB69C06000600B6A5B6ADB66D966D36 +:1065D00006000600B6ADB6ADB2ADB2AD060006001F +:1065E000B6ADB6A596ADB6AD06000600B6ADB6AC76 +:1065F000B6ACB6AD06000600B6AD96ADB6A5B6AD66 +:1066000006000600B6ADB2ADB6ADB6AD02000600EE +:1066100000000000000000000000000040016000D9 +:106620003A1900001A819E001A819E003A019D00CD +:10663000FFFFFFFF5A3A5A3A393939395A595A59EC +:106640003A3A3A3A3A3A3A3A3A3A3A3A3A3A00001E +:106650000101010101010101010101010892240070 +:106660004092240949920000000000003A813A81DA +:106670003A013A015A3A5A3A5A3A5A3A3939393970 +:10668000393939395A595A595A595A593A3A3A3A72 +:1066900039393939010101010000000008120812DE +:1066A000490049004012401201000100420160000F +:1066B0003A19000020819F0020819F003A019D002F +:1066C000FFFFFFFF5A3A5A3A393939395A595A595C +:1066D0003A3A3A3A3A3A3A3A3A3A3A3A3A3A00008E +:1066E00001010101010101010101010108922400E0 +:1066F0004092240949920000000000003A813A814A +:106700003A013A015A3A5A3A5A3A5A3A39393939DF +:10671000393939395A595A595A595A593A3A3A3AE1 +:10672000393939390101010100000000081208124D +:10673000490049004012401201000100030300001B +:10674000030303030303030303030303030301011D +:10675000EBEBEEEECE0000000000000003030303AD +:106760000303030301010101EB0B0800000000001B +:106770000000000000000000030300000303030307 +:106780000303030303030303030301010800E0EE13 +:10679000C00000000000000003030303000000002D +:1067A00000000000000000000000000000000000E9 +:1067B00000000000FFFFFF3FFFFFFF3FFFFFFF3F25 +:1067C000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FD9 +:1067D000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FC9 +:1067E000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FB9 +:1067F000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FA9 +:10680000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F98 +:10681000FFFFFF3F129060034868C1067E40220AD6 +:10682000B418830DEAF0E31020C9441456A1A5174B +:106830008C79061BC251671EF829C8212E02292512 +:1068400064DA0900004840023620A1056CF801090D +:10685000A2D0620CD8A8C30F0E8124134459851608 +:106860007A31E619B009471DE6E1A7201CBA0824D1 +:1068700052926927004840023620A1056CF80109B0 +:10688000A2D0620CD8A8C30F0E81241344598516D8 +:106890007A31E619B009471DE6E1A7201CBA0824A1 +:1068A00052926927004840023620A1056CF8010980 +:1068B000A2D0620CD8A8C30F0E81241344598516A8 +:1068C0007A31E619B009471DE6E1A7201CBA082471 +:1068D00052926927004840023620A1056CF8010950 +:1068E000A2D0620CD8A8C30F0E8124134459851678 +:1068F0007A31E619B009471DE6E1A7201CBA082441 +:10690000529269277602200124D880045AB0E10708 +:106910009088420BC660A30EFC3804123211651534 +:1069200068E9C5189EC1261CD499871F0A72E822FF +:10693000404A4926FFFFFF3FFFFFFF3FFFFFFF3FAA +:10694000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F57 +:10695000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F47 +:10696000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F37 +:10697000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F27 +:10698000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F17 +:10699000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F07 +:1069A000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FF7 +:1069B000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FE7 +:1069C000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FD7 +:1069D000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FC7 +:1069E000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FB7 +:1069F000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FA7 +:106A0000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F96 +:106A1000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F86 +:106A2000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F76 +:106A3000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F66 +:106A4000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F56 +:106A5000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F46 +:106A6000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F36 +:106A7000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F26 +:106A8000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F16 +:106A9000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F06 +:106AA000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FF6 +:106AB000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FE6 +:106AC000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FD6 +:106AD000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FC6 +:106AE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FB6 +:106AF000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FA6 +:106B0000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F95 +:106B1000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F85 +:106B2000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F75 +:106B3000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F65 +:106B4000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F55 +:106B5000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F45 +:106B6000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F35 +:106B7000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F25 +:106B8000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F15 +:106B9000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F05 +:106BA000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FF5 +:106BB000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FE5 +:106BC000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FD5 +:106BD000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FC5 +:106BE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FB5 +:106BF000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3FA5 +:106C0000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F94 +:106C1000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F84 +:106C2000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFF3F74 +:106C3000FFFFFF3F644A09242E72A820F899471DE0 +:106C4000C2C1E6198CE98516561125132039C40FE7 +:106C5000EA60630CB48802097EB0A10548D84002FE +:106C6000120060277692292540BAC8210AE2671EE1 +:106C7000D409071B9E31A617685945143281E410C8 +:106C8000FCA8830DC6D0220A90F8C1065A206103E1 +:106C90002448000000000000000000000000000088 +:106CA00000000000000000000000000000000000E4 +:106CB00000000000000000000000000000000000D4 +:106CC00000000000000000000000000000000000C4 +:106CD00000000000000000000000000000000000B4 +:106CE00000000000000000000000000000000000A4 +:106CF0000000000000000000000000000000000094 +:106D00000000000000000000000000000000000083 +:106D10000000000000000000000000000000000073 +:106D20000000000000000000000000000000000063 +:106D30000000000000000000000000000000000053 +:106D40000000000000000000000000000000000043 +:106D50000000000000000000000000000000000033 +:106D60000000000000000000000000000000000023 +:106D70000000000000000000000000000000000013 +:106D80000000000000000000000000000000000003 +:106D900000000000000000000000000000000000F3 +:106DA00000000000000000000000000000000000E3 +:106DB00000000000000000000000000000000000D3 +:106DC00000000000000000000000000000000000C3 +:106DD00000000000000000000000000000000000B3 +:106DE00000000000000000000000000000000000A3 +:106DF0000000000000000000000000000000000093 +:106E00000000000000000000000000000000000082 +:106E10000000000000000000000000000000000072 +:106E20000000000000000000000000000000000062 +:106E30000000000000000000000000000000000052 +:106E40000000000000000000000000000000000042 +:106E50000000000000000000000000000000000032 +:106E60000000000000000000000000000000000022 +:106E70000000000000000000000000000000000012 +:106E80000000000000000000000000000000000002 +:106E900000000000000000000000000000000000F2 +:106EA00000000000000000000000000000000000E2 +:106EB00000000000000000000000000000000000D2 +:106EC00000000000000000000000000000000000C2 +:106ED00000000000000000000000000000000000B2 +:106EE00000000000000000000000000000000000A2 +:106EF0000000000000000000000000000000000092 +:106F00000000000000000000000000000000000081 +:106F10000000000000000000000000000000000071 +:106F20000000000000000000000000000000000061 +:106F30000000000000000000000000000000000051 +:106F40000000000000000000000000000000000041 +:106F50000000000000000000000000000000000031 +:106F60000000000000000000000000000000000021 +:106F70000000000000000000000000000000000011 +:106F80000000000000000000000000000000000001 +:106F900000000000000000000000000000000000F1 +:106FA00000000000000000000000000000000000E1 +:106FB00000000000000000000000000000000000D1 +:106FC00000000000000000000000000000000000C1 +:106FD00000000000000000000000000000000000B1 +:106FE00000000000000000000000000000000000A1 +:106FF0000000000000000000000000000000000091 +:107000000000000000000000000000000000000080 +:107010000000000000000000000000000000000070 +:107020000000000000000000000000000000000060 +:107030000000000000000000000000000000000050 +:107040000000000000000000000000000000000040 +:107050000000000000000000000000000000000030 +:107060000000000000000000000000000000000020 +:107070000000000000000000000000000000000010 +:107080000000000000000000000000000000000000 +:1070900000000000000000000000000000000000F0 +:1070A00000000000000000000000000000000000E0 +:1070B00000000000000000000000000000000000D0 +:1070C00000000000000000000000000000000000C0 +:1070D00000000000000000000000000000000000B0 +:1070E00000000000000000000000000000000000A0 +:1070F0000000000000000000000000000000000090 +:10710000000000000000000000000000000000007F +:10711000000000000000000000000000000000006F +:10712000000000000000000000000000000000005F +:10713000000000000000000000000000000000004F +:10714000000000000000000000000000000000003F +:10715000000000000000000000000000000000002F +:10716000000000000000000000000000000000001F +:10717000000000000000000000000000000000000F +:1071800000000000000000000000000000000000FF +:1071900000000000000000000000000000000000EF +:1071A00000000000000000000000000000000000DF +:1071B00000000000000000000000000000000000CF +:1071C00000000000000000000000000000000000BF +:1071D00000000000000000000000000000000000AF +:1071E000000000000000000000000000000000009F +:1071F000000000000000000000000000000000008F +:10720000000000000000000000000000000000007E +:10721000000000000000000000000000000000006E +:10722000000000000000000000000000000000005E +:10723000000000000000000000000000000000004E +:10724000000000000000000000000000000000003E +:10725000000000000000000000000000000000002E +:10726000000000000000000000000000000000001E +:10727000000000000000000000000000000000000E +:1072800000000000000000000000000000000000FE +:1072900000000000000000000000000000000000EE +:1072A00000000000000000000000000000000000DE +:1072B00000000000000000000000000000000000CE +:1072C00000000000000000000000000000000000BE +:1072D00000000000000000000000000000000000AE +:1072E000000000000000000000000000000000009E +:1072F000000000000000000000000000000000008E +:10730000000000000000000000000000000000007D +:10731000000000000000000000000000000000006D +:10732000000000000000000000000000000000005D +:10733000000000000000000000000000000000004D +:10734000000000000000000000000000000000003D +:10735000000000000000000000000000000000002D +:10736000000000000000000000000000000000001D +:10737000000000000000000000000000000000000D +:1073800000000000000000000000000000000000FD +:1073900000000000000000000000000000000000ED +:1073A00000000000000000000000000000000000DD +:1073B00000000000000000000000000000000000CD +:1073C00000000000000000000000000000000000BD +:1073D00000000000000000000000000000000000AD +:1073E000000000000000000000000000000000009D +:1073F000000000000000000000000000000000008D +:10740000000000000000000000000000000000007C +:10741000000000000000000000000000000000006C +:10742000000000000000000000000000000000005C +:10743000000000000000000000000000000000004C +:10744000000000000000000000000000000000003C +:10745000000000000000000000000000000000002C +:10746000000000000000000000000000000000001C +:10747000000000000000000000000000000000000C +:1074800000000000000000000000000000000000FC +:1074900000000000000000000000000000000000EC +:1074A00000000000000000000000000000000000DC +:1074B00000000000000000000000000000000000CC +:1074C00000000000000000000000000000000000BC +:1074D00000000000000000000000000000000000AC +:1074E000000000000000000000000000000000009C +:1074F000000000000000000000000000000000008C +:10750000000000000000000000000000000000007B +:10751000000000000000000000000000000000006B +:10752000000000000000000000000000000000005B +:10753000000000000000000000000000000000004B +:10754000000000000000000000000000000000003B +:10755000000000000000000000000000000000002B +:10756000000000000000000000000000000000001B +:10757000000000000000000000000000000000000B +:1075800000000000000000000000000000000000FB +:1075900000000000000000000000000000000000EB +:1075A00000000000000000000000000000000000DB +:1075B00000000000000000000000000000000000CB +:1075C00000000000000000000000000000000000BB +:1075D00000000000000000000000000000000000AB +:1075E000000000000000000000000000000000009B +:1075F000000000000000000000000000000000008B +:10760000000000000000000000000000000000007A +:10761000000000000000000000000000000000006A +:10762000000000000000000000000000000000005A +:10763000000000000000000000000000000000004A +:10764000000000000000000000000000000000003A +:10765000000000000000000000000000000000002A +:10766000000000000000000000000000000000001A +:10767000000000000000000000000000000000000A +:1076800000000000000000000000000000000000FA +:1076900000000000000000000000000000000000EA +:1076A00000000000000000000000000000000000DA +:1076B00000000000000000000000000000000000CA +:1076C00000000000000000000000000000000000BA +:1076D00000000000000000000000000000000000AA +:1076E000000000000000000000000000000000009A +:1076F000000000000000000000000000000000008A +:107700000000000000000000000000000000000079 +:107710000000000000000000000000000000000069 +:107720000000000000000000000000000000000059 +:107730000000000000000000000000000000000049 +:107740000000000000000000000000000000000039 +:107750000000000000000000000000000000000029 +:107760000000000000000000000000000000000019 +:107770000000000000000000000000000000000009 +:1077800000000000000000000000000000000000F9 +:1077900000000000000000000000000000000000E9 +:1077A00000000000000000000000000000000000D9 +:1077B00000000000000000000000000000000000C9 +:1077C00000000000000000000000000000000000B9 +:1077D00000000000000000000000000000000000A9 +:1077E0000000000000000000000000000000000099 +:1077F0000000000000000000000000000000000089 +:107800000000000000000000000000000000000078 +:107810000000000000000000000000000000000068 +:107820000000000000000000000000000000000058 +:107830000000000000000000000000000000000048 +:107840000000000000000000000000000000000038 +:107850000000000000000000000000000000000028 +:107860000000000000000000000000000000000018 +:107870000000000000000000000000000000000008 +:1078800000000000000000000000000000000000F8 +:1078900000000000000000000000000000000000E8 +:1078A00000000000000000000000000000000000D8 +:1078B00000000000000000000000000000000000C8 +:1078C00000000000000000000000000000000000B8 +:1078D00000000000000000000000000000000000A8 +:1078E0000000000000000000000000000000000098 +:1078F0000000000000000000000000000000000088 +:107900000000000000000000000000000000000077 +:107910000000000000000000000000000000000067 +:107920000000000000000000000000000000000057 +:107930000000000000000000000000000000000047 +:107940000000000000000000000000000000000037 +:107950000000000000000000000000000000000027 +:107960000000000000000000000000000000000017 +:107970000000000000000000000000000000000007 +:1079800000000000000000000000000000000000F7 +:1079900000000000000000000000000000000000E7 +:1079A00000000000000000000000000000000000D7 +:1079B00000000000000000000000000000000000C7 +:1079C00000000000000000000000000000000000B7 +:1079D00000000000000000000000000000000000A7 +:1079E0000000000000000000000000000000000097 +:1079F0000000000000000000000000000000000087 +:107A00000000000000000000000000000000000076 +:107A10000000000000000000000000000000000066 +:107A20000000000000000000000000000000000056 +:107A30000000000000000000000000000000000046 +:107A40000000000000000000000000000000000036 +:107A50000000000000000000000000000000000026 +:107A60000000000000000000000000000000000016 +:107A70000000000000000000000000000000000006 +:107A800000000000000000000000000000000000F6 +:107A900000000000000000000000000000000000E6 +:107AA00000000000000000000000000000000000D6 +:107AB00000000000000000000000000000000000C6 +:107AC00000000000000000000000000000000000B6 +:107AD00000000000000000000000000000000000A6 +:107AE0000000000000000000000000000000000096 +:107AF0000000000000000000000000000000000086 +:107B00000000000000000000000000000000000075 +:107B10000000000000000000000000000000000065 +:107B20000000000000000000000000000000000055 +:107B30000000000000000000000000000000000045 +:107B40000000000000000000000000000000000035 +:107B50000000000000000000000000000000000025 +:107B60000000000000000000000000000000000015 +:107B70000000000000000000000000000000000005 +:107B800000000000000000000000000000000000F5 +:107B900000000000000000000000000000000000E5 +:107BA00000000000000000000000000000000000D5 +:107BB00000000000000000000000000000000000C5 +:107BC00000000000000000000000000000000000B5 +:107BD00000000000000000000000000000000000A5 +:107BE0000000000000000000000000000000000095 +:107BF0000000000000000000000000000000000085 +:107C00000000000000000000000000000000000074 +:107C10000000000000000000000000000000000064 +:107C20000000000000000000000000000000000054 +:107C30000000000000000000000000000000000044 +:107C40000000000000000000000000000000000034 +:107C50000000000000000000000000000000000024 +:107C60000000000000000000000000000000000014 +:107C70000000000000000000000000000000000004 +:107C800000000000000000000000000000000000F4 +:107C900000000000000000000000000000000000E4 +:107CA00000000000000000000000000000000000D4 +:107CB00000000000000000000000000000000000C4 +:107CC00000000000000000000000000000000000B4 +:107CD00000000000000000000000000000000000A4 +:107CE0000000000000000000000000000000000094 +:107CF0000000000000000000000000000000000084 +:107D00000000000000000000000000000000000073 +:107D10000000000000000000000000000000000063 +:107D20000000000000000000000000000000000053 +:107D30000000000000000000000000000000000043 +:107D40000000000000000000000000000000000033 +:107D50000000000000000000000000000000000023 +:107D60000000000000000000000000000000000013 +:107D70000000000000000000000000000000000003 +:107D800000000000000000000000000000000000F3 +:107D900000000000000000000000000000000000E3 +:107DA00000000000000000000000000000000000D3 +:107DB00000000000000000000000000000000000C3 +:107DC00000000000000000000000000000000000B3 +:107DD00000000000000000000000000000000000A3 +:107DE0000000000000000000000000000000000093 +:107DF0000000000000000000000000000000000083 +:107E00000000000000000000000000000000000072 +:107E10000000000000000000000000000000000062 +:107E20000000000000000000000000000000000052 +:107E30000000000000000000000000000000000042 +:107E40000000000000000000000000000000000032 +:107E50000000000000000000000000000000000022 +:107E60000000000000000000000000000000000012 +:107E70000000000000000000000000000000000002 +:107E800000000000000000000000000000000000F2 +:107E900000000000000000000000000000000000E2 +:107EA00000000000000000000000000000000000D2 +:107EB00000000000000000000000000000000000C2 +:107EC00000000000000000000000000000000000B2 +:107ED00000000000000000000000000000000000A2 +:107EE0000000000000000000000000000000000092 +:107EF0000000000000000000000000000000000082 +:107F00000000000000000000000000000000000071 +:107F10000000000000000000000000000000000061 +:107F20000000000000000000000000000000000051 +:107F30000000000000000000000000000000000041 +:107F40000000000000000000000000000000000031 +:107F50000000000000000000000000000000000021 +:107F60000000000000000000000000000000000011 +:107F70000000000000000000000000000000000001 +:107F800000000000000000000000000000000000F1 +:107F900000000000000000000000000000000000E1 +:107FA00000000000000000000000000000000000D1 +:107FB00000000000000000000000000000000000C1 +:107FC00000000000000000000000000000000000B1 +:107FD00000000000000000000000000000000000A1 +:107FE0000000000000000000000000000000000091 +:107FF0000000000000000000000000000000000081 +:108000000000000000000000000000000000000070 +:108010000000000000000000000000000000000060 +:108020000000000000000000000000000000000050 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:1080800000000000000000000000000000000000F0 +:1080900000000000000000000000000000000000E0 +:1080A00000000000000000000000000000000000D0 +:1080B00000000000000000000000000000000000C0 +:1080C00000000000000000000000000000000000B0 +:1080D00000000000000000000000000000000000A0 +:1080E0000000000000000000000000000000000090 +:1080F0000000000000000000000000000000000080 +:10810000000000000000000000000000000000006F +:10811000000000000000000000000000000000005F +:10812000000000000000000000000000000000004F +:10813000000000000000000000000000000000003F +:10814000000000000000000000000000000000002F +:10815000000000000000000000000000000000001F +:10816000000000000000000000000000000000000F +:1081700000000000000000000000000000000000FF +:1081800000000000000000000000000000000000EF +:1081900000000000000000000000000000000000DF +:1081A00000000000000000000000000000000000CF +:1081B00000000000000000000000000000000000BF +:1081C00000000000000000000000000000000000AF +:1081D000000000000000000000000000000000009F +:1081E000000000000000000000000000000000008F +:1081F000000000000000000000000000000000007F +:10820000000000000000000000000000000000006E +:10821000000000000000000000000000000000005E +:10822000000000000000000000000000000000004E +:10823000000000000000000000000000000000003E +:10824000000000000000000000000000000000002E +:10825000000000000000000000000000000000001E +:10826000000000000000000000000000000000000E +:1082700000000000000000000000000000000000FE +:1082800000000000000000000000000000000000EE +:1082900000000000000000000000000000000000DE +:1082A00000000000000000000000000000000000CE +:1082B00000000000000000000000000000000000BE +:1082C00000000000000000000000000000000000AE +:1082D000000000000000000000000000000000009E +:1082E000000000000000000000000000000000008E +:1082F000000000000000000000000000000000007E +:10830000000000000000000000000000000000006D +:10831000000000000000000000000000000000005D +:10832000000000000000000000000000000000004D +:10833000000000000000000000000000000000003D +:10834000000000000000000000000000000000002D +:10835000000000000000000000000000000000001D +:10836000000000000000000000000000000000000D +:1083700000000000000000000000000000000000FD +:1083800000000000000000000000000000000000ED +:1083900000000000000000000000000000000000DD +:1083A00000000000000000000000000000000000CD +:1083B00000000000000000000000000000000000BD +:1083C00000000000000000000000000000000000AD +:1083D000000000000000000000000000000000009D +:1083E000000000000000000000000000000000008D +:1083F000000000000000000000000000000000007D +:10840000000000000000000000000000000000006C +:10841000000000000000000000000000000000005C +:10842000000000000000000000000000000000004C +:10843000000000000000000000000000000000003C +:10844000000000000000000000000000000000002C +:10845000000000000000000000000000000000001C +:10846000000000000000000000000000000000000C +:1084700000000000000000000000000000000000FC +:1084800000000000000000000000000000000000EC +:1084900000000000000000000000000000000000DC +:1084A00000000000000000000000000000000000CC +:1084B00000000000000000000000000000000000BC +:1084C00000000000000000000000000000000000AC +:1084D000000000000000000000000000000000009C +:1084E000000000000000000000000000000000008C +:1084F000000000000000000000000000000000007C +:10850000000000000000000000000000000000006B +:10851000000000000000000000000000000000005B +:10852000000000000000000000000000000000004B +:10853000000000000000000000000000000000003B +:10854000000000000000000000000000000000002B +:10855000000000000000000000000000000000001B +:10856000000000000000000000000000000000000B +:1085700000000000000000000000000000000000FB +:1085800000000000000000000000000000000000EB +:1085900000000000000000000000000000000000DB +:1085A00000000000000000000000000000000000CB +:1085B00000000000000000000000000000000000BB +:1085C00000000000000000000000000000000000AB +:1085D000000000000000000000000000000000009B +:1085E000000000000000000000000000000000008B +:1085F000000000000000000000000000000000007B +:10860000000000000000000000000000000000006A +:10861000000000000000000000000000000000005A +:10862000000000000000000000000000000000004A +:10863000000000000000000000000000000000003A +:10864000000000000000000000000000000000002A +:10865000000000000000000000000000000000001A +:10866000000000000000000000000000000000000A +:1086700000000000000000000000000000000000FA +:1086800000000000000000000000000000000000EA +:1086900000000000000000000000000000000000DA +:1086A00000000000000000000000000000000000CA +:1086B00000000000000000000000000000000000BA +:1086C00000000000000000000000000000000000AA +:1086D000000000000000000000000000000000009A +:1086E000000000000000000000000000000000008A +:1086F000000000000000000000000000000000007A +:108700000000000000000000000000000000000069 +:108710000000000000000000000000000000000059 +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:108740000000000000000000000000000000000029 +:108750000000000000000000000000000000000019 +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800000000000000000000000000000000000E9 +:1087900000000000000000000000000000000000D9 +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00000000000000000000000000000000000A9 +:1087D0000000000000000000000000000000000099 +:1087E0000000000000000000000000000000000089 +:1087F0000000000000000000000000000000000079 +:108800000000000000000000000000000000000068 +:108810000000000000000000000000000000000058 +:108820000000000000000000000000000000000048 +:108830000000000000000000000000000000000038 +:108840000000000000000000000000000000000028 +:108850000000000000000000000000000000000018 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800000000000000000000000000000000000E8 +:1088900000000000000000000000000000000000D8 +:1088A00000000000000000000000000000000000C8 +:1088B00000000000000000000000000000000000B8 +:1088C00000000000000000000000000000000000A8 +:1088D0000000000000000000000000000000000098 +:1088E0000000000000000000000000000000000088 +:1088F0000000000000000000000000000000000078 +:108900000000000000000000000000000000000067 +:108910000000000000000000000000000000000057 +:108920000000000000000000000000000000000047 +:108930000000000000000000000000000000000037 +:108940000000000000000000000000000000000027 +:108950000000000000000000000000000000000017 +:108960000000000000000000000000000000000007 +:1089700000000000000000000000000000000000F7 +:1089800000000000000000000000000000000000E7 +:1089900000000000000000000000000000000000D7 +:1089A00000000000000000000000000000000000C7 +:1089B00000000000000000000000000000000000B7 +:1089C00000000000000000000000000000000000A7 +:1089D0000000000000000000000000000000000097 +:1089E0000000000000000000000000000000000087 +:1089F0000000000000000000000000000000000077 +:108A00000000000000000000000000000000000066 +:108A10000000000000000000000000000000000056 +:108A20000000000000000000000000000000000046 +:108A30000000000000000000000000000000000036 +:108A40000000000000000000000000000000000026 +:108A50000000000000000000000000000000000016 +:108A60000000000000000000000000000000000006 +:108A700000000000000000000000000000000000F6 +:108A800000000000000000000000000000000000E6 +:108A900000000000000000000000000000000000D6 +:108AA00000000000000000000000000000000000C6 +:108AB00000000000000000000000000000000000B6 +:108AC00000000000000000000000000000000000A6 +:108AD0000000000000000000000000000000000096 +:108AE0000000000000000000000000000000000086 +:108AF0000000000000000000000000000000000076 +:108B00000000000000000000000000000000000065 +:108B10000000000000000000000000000000000055 +:108B20000000000000000000000000000000000045 +:108B30000000000000000000000000000000000035 +:108B40000000000000000000000000000000000025 +:108B50000000000000000000000000000000000015 +:108B60000000000000000000000000000000000005 +:108B700000000000000000000000000000000000F5 +:108B800000000000000000000000000000000000E5 +:108B900000000000000000000000000000000000D5 +:108BA00000000000000000000000000000000000C5 +:108BB00000000000000000000000000000000000B5 +:108BC00000000000000000000000000000000000A5 +:108BD0000000000000000000000000000000000095 +:108BE0000000000000000000000000000000000085 +:108BF0000000000000000000000000000000000075 +:108C00000000000000000000000000000000000064 +:108C10000000000000000000000000000000000054 +:108C20000000000000000000000000000000000044 +:108C30000000000000000000000000000000000034 +:108C40000000000000000000000000000000000024 +:108C50000000000000000000000000000000000014 +:108C60000000000000000000000000000000000004 +:108C700000000000000000000000000000000000F4 +:108C800000000000000000000000000000000000E4 +:108C900000000000000000000000000000000000D4 +:108CA00000000000000000000000000000000000C4 +:108CB00000000000000000000000000000000000B4 +:108CC00000000000000000000000000000000000A4 +:108CD0000000000000000000000000000000000094 +:108CE0000000000000000000000000000000000084 +:108CF0000000000000000000000000000000000074 +:108D00000000000000000000000000000000000063 +:108D10000000000000000000000000000000000053 +:108D20000000000000000000000000000000000043 +:108D30000000000000000000000000000000000033 +:108D40000000000000000000000000000000000023 +:108D50000000000000000000000000000000000013 +:108D60000000000000000000000000000000000003 +:108D700000000000000000000000000000000000F3 +:108D800000000000000000000000000000000000E3 +:108D900000000000000000000000000000000000D3 +:108DA00000000000000000000000000000000000C3 +:108DB00000000000000000000000000000000000B3 +:108DC00000000000000000000000000000000000A3 +:108DD0000000000000000000000000000000000093 +:108DE0000000000000000000000000000000000083 +:108DF0000000000000000000000000000000000073 +:108E00000000000000000000000000000000000062 +:108E10000000000000000000000000000000000052 +:108E20000000000000000000000000000000000042 +:108E30000000000000000000000000000000000032 +:108E40000000000000000000000000000000000022 +:108E50000000000000000000000000000000000012 +:108E60000000000000000000000000000000000002 +:108E700000000000000000000000000000000000F2 +:108E800000000000000000000000000000000000E2 +:108E900000000000000000000000000000000000D2 +:108EA00000000000000000000000000000000000C2 +:108EB00000000000000000000000000000000000B2 +:108EC00000000000000000000000000000000000A2 +:108ED0000000000000000000000000000000000092 +:108EE0000000000000000000000000000000000082 +:108EF0000000000000000000000000000000000072 +:108F00000000000000000000000000000000000061 +:108F10000000000000000000000000000000000051 +:108F20000000000000000000000000000000000041 +:108F30000000000000000000000000000000000031 +:108F40000000000000000000000000000000000021 +:108F50000000000000000000000000000000000011 +:108F60000000000000000000000000000000000001 +:108F700000000000000000000000000000000000F1 +:108F800000000000000000000000000000000000E1 +:108F900000000000000000000000000000000000D1 +:108FA00000000000000000000000000000000000C1 +:108FB00000000000000000000000000000000000B1 +:108FC00000000000000000000000000000000000A1 +:108FD0000000000000000000000000000000000091 +:108FE0000000000000000000000000000000000081 +:108FF0000000000000000000000000000000000071 +:109000000000000000000000000000000000000060 +:109010000000000000000000000000000000000050 +:109020000000000000000000000000000000000040 +:109030000000000000000000000000000000000030 +:109040000000000000000000000000000000000020 +:109050000000000000000000000000000000000010 +:109060000000000000000000000000000000000000 +:1090700000000000000000000000000000000000F0 +:1090800000000000000000000000000000000000E0 +:1090900000000000000000000000000000000000D0 +:1090A00000000000000000000000000000000000C0 +:1090B00000000000000000000000000000000000B0 +:1090C00000000000000000000000000000000000A0 +:1090D0000000000000000000000000000000000090 +:1090E0000000000000000000000000000000000080 +:1090F0000000000000000000000000000000000070 +:10910000000000000000000000000000000000005F +:10911000000000000000000000000000000000004F +:10912000000000000000000000000000000000003F +:10913000000000000000000000000000000000002F +:10914000000000000000000000000000000000001F +:10915000000000000000000000000000000000000F +:1091600000000000000000000000000000000000FF +:1091700000000000000000000000000000000000EF +:1091800000000000000000000000000000000000DF +:1091900000000000000000000000000000000000CF +:1091A00000000000000000000000000000000000BF +:1091B00000000000000000000000000000000000AF +:1091C000000000000000000000000000000000009F +:1091D000000000000000000000000000000000008F +:1091E000000000000000000000000000000000007F +:1091F000000000000000000000000000000000006F +:10920000000000000000000000000000000000005E +:10921000000000000000000000000000000000004E +:10922000000000000000000000000000000000003E +:10923000000000000000000000000000000000002E +:10924000000000000000000000000000000000001E +:10925000000000000000000000000000000000000E +:1092600000000000000000000000000000000000FE +:1092700000000000000000000000000000000000EE +:1092800000000000000000000000000000000000DE +:1092900000000000000000000000000000000000CE +:1092A00000000000000000000000000000000000BE +:1092B00000000000000000000000000000000000AE +:1092C000000000000000000000000000000000009E +:1092D000000000000000000000000000000000008E +:1092E000000000000000000000000000000000007E +:1092F000000000000000000000000000000000006E +:10930000000000000000000000000000000000005D +:10931000000000000000000000000000000000004D +:10932000000000000000000000000000000000003D +:10933000000000000000000000000000000000002D +:10934000000000000000000000000000000000001D +:10935000000000000000000000000000000000000D +:1093600000000000000000000000000000000000FD +:1093700000000000000000000000000000000000ED +:1093800000000000000000000000000000000000DD +:1093900000000000000000000000000000000000CD +:1093A00000000000000000000000000000000000BD +:1093B00000000000000000000000000000000000AD +:1093C000000000000000000000000000000000009D +:1093D000000000000000000000000000000000008D +:1093E000000000000000000000000000000000007D +:1093F000000000000000000000000000000000006D +:10940000000000000000000000000000000000005C +:10941000000000000000000000000000000000004C +:10942000000000000000000000000000000000003C +:10943000000000000000000000000000000000002C +:10944000000000000000000000000000000000001C +:10945000000000000000000000000000000000000C +:1094600000000000000000000000000000000000FC +:1094700000000000000000000000000000000000EC +:1094800000000000000000000000000000000000DC +:1094900000000000000000000000000000000000CC +:1094A00000000000000000000000000000000000BC +:1094B00000000000000000000000000000000000AC +:1094C000000000000000000000000000000000009C +:1094D000000000000000000000000000000000008C +:1094E000000000000000000000000000000000007C +:1094F000000000000000000000000000000000006C +:10950000000000000000000000000000000000005B +:10951000000000000000000000000000000000004B +:10952000000000000000000000000000000000003B +:10953000000000000000000000000000000000002B +:10954000000000000000000000000000000000001B +:10955000000000000000000000000000000000000B +:1095600000000000000000000000000000000000FB +:1095700000000000000000000000000000000000EB +:1095800000000000000000000000000000000000DB +:1095900000000000000000000000000000000000CB +:1095A00000000000000000000000000000000000BB +:1095B00000000000000000000000000000000000AB +:1095C000000000000000000000000000000000009B +:1095D000000000000000000000000000000000008B +:1095E000000000000000000000000000000000007B +:1095F000000000000000000000000000000000006B +:10960000000000000000000000000000000000005A +:10961000000000000000000000000000000000004A +:10962000000000000000000000000000000000003A +:10963000000000000000000000000000000000002A +:10964000000000000000000000000000000000001A +:10965000000000000000000000000000000000000A +:1096600000000000000000000000000000000000FA +:1096700000000000000000000000000000000000EA +:1096800000000000000000000000000000000000DA +:1096900000000000000000000000000000000000CA +:1096A00000000000000000000000000000000000BA +:1096B00000000000000000000000000000000000AA +:1096C000000000000000000000000000000000009A +:1096D000000000000000000000000000000000008A +:1096E000000000000000000000000000000000007A +:1096F000000000000000000000000000000000006A +:109700000000000000000000000000000000000059 +:109710000000000000000000000000000000000049 +:109720000000000000000000000000000000000039 +:109730000000000000000000000000000000000029 +:109740000000000000000000000000000000000019 +:109750000000000000000000000000000000000009 +:1097600000000000000000000000000000000000F9 +:1097700000000000000000000000000000000000E9 +:1097800000000000000000000000000000000000D9 +:1097900000000000000000000000000000000000C9 +:1097A00000000000000000000000000000000000B9 +:1097B00000000000000000000000000000000000A9 +:1097C0000000000000000000000000000000000099 +:1097D0000000000000000000000000000000000089 +:1097E0000000000000000000000000000000000079 +:1097F0000000000000000000000000000000000069 +:109800000000000000000000000000000000000058 +:109810000000000000000000000000000000000048 +:109820000000000000000000000000000000000038 +:109830000000000000000000000000000000000028 +:109840000000000000000000000000000000000018 +:109850000000000000000000000000000000000008 +:1098600000000000000000000000000000000000F8 +:1098700000000000000000000000000000000000E8 +:1098800000000000000000000000000000000000D8 +:1098900000000000000000000000000000000000C8 +:1098A00000000000000000000000000000000000B8 +:1098B00000000000000000000000000000000000A8 +:1098C0000000000000000000000000000000000098 +:1098D0000000000000000000000000000000000088 +:1098E0000000000000000000000000000000000078 +:1098F0000000000000000000000000000000000068 +:109900000000000000000000000000000000000057 +:109910000000000000000000000000000000000047 +:109920000000000000000000000000000000000037 +:109930000000000000000000000000000000000027 +:109940000000000000000000000000000000000017 +:109950000000000000000000000000000000000007 +:1099600000000000000000000000000000000000F7 +:1099700000000000000000000000000000000000E7 +:1099800000000000000000000000000000000000D7 +:1099900000000000000000000000000000000000C7 +:1099A00000000000000000000000000000000000B7 +:1099B00000000000000000000000000000000000A7 +:1099C0000000000000000000000000000000000097 +:1099D0000000000000000000000000000000000087 +:1099E0000000000000000000000000000000000077 +:1099F0000000000000000000000000000000000067 +:109A00000000000000000000000000000000000056 +:109A10000000000000000000000000000000000046 +:109A20000000000000000000000000000000000036 +:109A30000000000000000000000000000000000026 +:109A40000000000000000000000000000000000016 +:109A50000000000000000000000000000000000006 +:109A600000000000000000000000000000000000F6 +:109A700000000000000000000000000000000000E6 +:109A800000000000000000000000000000000000D6 +:109A900000000000000000000000000000000000C6 +:109AA00000000000000000000000000000000000B6 +:109AB00000000000000000000000000000000000A6 +:109AC0000000000000000000000000000000000096 +:109AD0000000000000000000000000000000000086 +:109AE0000000000000000000000000000000000076 +:109AF0000000000000000000000000000000000066 +:109B00000000000000000000000000000000000055 +:109B10000000000000000000000000000000000045 +:109B20000000000000000000000000000000000035 +:109B30000000000000000000000000000000000025 +:109B40000000000000000000000000000000000015 +:109B50000000000000000000000000000000000005 +:109B600000000000000000000000000000000000F5 +:109B700000000000000000000000000000000000E5 +:109B800000000000000000000000000000000000D5 +:109B900000000000000000000000000000000000C5 +:109BA00000000000000000000000000000000000B5 +:109BB00000000000000000000000000000000000A5 +:109BC0000000000000000000000000000000000095 +:109BD0000000000000000000000000000000000085 +:109BE0000000000000000000000000000000000075 +:109BF0000000000000000000000000000000000065 +:109C00000000000000000000000000000000000054 +:109C10000000000000000000000000000000000044 +:109C20000000000000000000000000000000000034 +:109C30000000000000000000000000000000000024 +:109C40000000000000000000000000000000000014 +:109C50000000000000000000000000000000000004 +:109C600000000000000000000000000000000000F4 +:109C700000000000000000000000000000000000E4 +:109C800000000000000000000000000000000000D4 +:109C900000000000000000000000000000000000C4 +:109CA00000000000000000000000000000000000B4 +:109CB00000000000000000000000000000000000A4 +:109CC0000000000000000000000000000000000094 +:109CD0000000000000000000000000000000000084 +:109CE0000000000000000000000000000000000074 +:109CF0000000000000000000000000000000000064 +:109D00000000000000000000000000000000000053 +:109D10000000000000000000000000000000000043 +:109D20000000000000000000000000000000000033 +:109D30000000000000000000000000000000000023 +:109D40000000000000000000000000000000000013 +:109D50000000000000000000000000000000000003 +:109D600000000000000000000000000000000000F3 +:109D700000000000000000000000000000000000E3 +:109D800000000000000000000000000000000000D3 +:109D900000000000000000000000000000000000C3 +:109DA00000000000000000000000000000000000B3 +:109DB00000000000000000000000000000000000A3 +:109DC0000000000000000000000000000000000093 +:109DD0000000000000000000000000000000000083 +:109DE0000000000000000000000000000000000073 +:109DF0000000000000000000000000000000000063 +:109E00000000000000000000000000000000000052 +:109E10000000000000000000000000000000000042 +:109E20000000000000000000000000000000000032 +:109E30000000000000000000000000000000000022 +:109E40000000000000000000000000000000000012 +:109E50000000000000000000000000000000000002 +:109E600000000000000000000000000000000000F2 +:109E700000000000000000000000000000000000E2 +:109E800000000000000000000000000000000000D2 +:109E900000000000000000000000000000000000C2 +:109EA00000000000000000000000000000000000B2 +:109EB00000000000000000000000000000000000A2 +:109EC0000000000000000000000000000000000092 +:109ED0000000000000000000000000000000000082 +:109EE0000000000000000000000000000000000072 +:109EF0000000000000000000000000000000000062 +:109F00000000000000000000000000000000000051 +:109F10000000000000000000000000000000000041 +:109F20000000000000000000000000000000000031 +:109F30000000000000000000000000000000000021 +:109F40000000000000000000000000000000000011 +:109F50000000000000000000000000000000000001 +:109F600000000000000000000000000000000000F1 +:109F700000000000000000000000000000000000E1 +:109F800000000000000000000000000000000000D1 +:109F900000000000000000000000000000000000C1 +:109FA00000000000000000000000000000000000B1 +:109FB00000000000000000000000000000000000A1 +:109FC0000000000000000000000000000000000091 +:109FD0000000000000000000000000000000000081 +:109FE0000000000000000000000000000000000071 +:109FF0000000000000000000000000000000000061 +:10A0000005FA1224380424090E0A0001010108127D +:10A010002400380424090000000C010001000000A5 +:10A020000000145900000000000000000009010AAF +:10A0300000013C4188020000281E200000C00100F1 +:10A0400000C0010000C0010000C0010000C001000C +:10A0500000C0010000C0010000C0010000DE40009F +:10A0600000C0010000C0010000C0010000DE40008F +:10A0700000C0010000C0010000C00100000000009D +:10A0800000010100000000000000000000000000CE +:10A0900000000000000000000001010101010100BA +:10A0A00000010100000001010101010100000100A7 +:10A0B00001000000000000000F0F000001012D0052 +:10A0C0002D000A00640078000100320001015F00E9 +:10A0D0005F0014000A007800000064002D000000FA +:10A0E00000000000000000002C01F4012C012C01F4 +:10A0F0002C010A0A000120000001F40105050000FE +:10A1000005010000CEFFD3FF3700F6FF1200E4FF89 +:10A11000FF7FFF7FFF7FFF7FFF7FFF7F960096001F +:10A120003C003C320A08CECE323228050000000046 +:10A1300001070D1200240D00000000122424242425 +:10A140002424242424242424242424242424000017 +:10A1500000000000000000000000000000000000FF +:10A160000A05000A000000001428010F0C0F00006F +:10A170000000000000000000010200030400FA0FCC +:10A18000000000000F1E3246500000007369645A40 +:10A190005555555508000000000000000F1E3246BE +:10A1A000500000007369645A555555550F141E2808 +:10A1B000000000000A0A0A0A0A0A0A0A0F1E3246AA +:10A1C00000000000645F553C3C3C3C3C000000004B +:10A1D00003081C004200ECFF1700B0008200BC0224 +:10A1E000000000000010000055002D00C8002800ED +:10A1F0000F000F00C800C800C800C80000003704E6 +:10A2000000002309F4010000370400002309321480 +:10A21000021E1E320200AF00280028006400D40392 +:10A220006400C0080000000038042800200001007D +:10A23000220000003A00520070008F00AF00CF00F3 +:10A24000EF000F012E014F016E018E01AD01CE0115 +:10A25000EC010F022D024D026D028D02AC02CC0208 +:10A26000EB020B032B034A036A038903AA03C90306 +:10A27000E703FF03370400000000000000000000B7 +:10A2800000000000000000000000000000000000CE +:10A2900000000000000000000000000000000000BE +:10A2A00000000000000000000000000000000000AE +:10A2B000000000000000000000000000000000009E +:10A2C000000000000000000000000000000000008E +:10A2D000000000000000000000000000000000007E +:10A2E000000000000000000000000000000000006E +:10A2F00000000000000000000000240928004700C2 +:10A300000100490000003C00430066008500A900F0 +:10A31000C800E90009012A0149016B018901AB016B +:10A32000C901EB0109022B024A026C028A02AC024B +:10A33000CA02EC020B032D034B036D038B03AE0328 +:10A34000CB03EE030C042F044C046F048B04AF0406 +:10A35000CC04EF040D0530054D0570058D05B005E5 +:10A36000CD05F1050D0630064E0672068E06B106C5 +:10A37000CE06F2060F073207500773079007B307A0 +:10A38000D107F40711083408520875089108B1087C +:10A39000C608E70800000000000000000000000000 +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D00002012000F16C0000409C000084D90600BE +:10A3E00029B1010010270000C40900000202020286 +:10A3F000020202020202014B0F00460000000000B0 +:10A40000010202020202020202020200F16C0000DA +:10A4100001020202020202020202020084DE0100C4 +:10A42000000000000F0F0A0A0500000000000000F5 +:10A430000F0F141400010101010140003200E80374 +:10A440000F0008000500E100000003030A001400EB +:10A4500014000400000000001400140064009001C7 +:10A460000000000141020000000000006801000D32 +:10A470000F006400640064000A0064002C016400A2 +:10A480002C010A02E8E8F800F800010201001900B6 +:10A490009800A600B500C500D700EA00FE00130131 +:10A4A0002B0143015E017A019801B701D901FD0139 +:10A4B00022024A027502A102D002010335036B0396 +:10A4C000A403DF031D045D04A004E6042E05790542 +:10A4D000C70517066A06BF0616077007CC072B08C4 +:10A4E0008B08ED085109B6091D0A850AEF0A590BB8 +:10A4F000C40B2F0C9A0C060D710DDC0D460EAF0E21 +:10A50000170F7D0FE10F4310A31001115B11B21162 +:10A5100006125612A212EB122E136D13A813DD139E +:10A520000D1438145E147E149814AD14BB14C414A6 +:10A53000C71417012B014101580170018901A401C1 +:10A54000C001DE01FD011E02410265028A02B20263 +:10A55000DB020603330361039203C403F8032F04F1 +:10A560006604A004DC04190559059A05DD052206D8 +:10A570006806B006F90645079107DF072E087E0832 +:10A58000D00822097509C9091E0A730AC90A1E0BD7 +:10A59000740BCA0B1F0C740CC80C1C0D6F0DC10D75 +:10A5A000110E600EAD0EF90E430F8A0FD00F121070 +:10A5B00053109010CB100211371168119611C01171 +:10A5C000E61109122712421259126C127A128512E0 +:10A5D0008B128D124E00560060006B0076008300D7 +:10A5E0009100A000B100C200D600EB0002011A01E8 +:10A5F0003501520170019101B501DB0103022E0208 +:10A600005C028D02C102F80232036F03B003F4034F +:10A610003B048604D40426057C05D5053206920643 +:10A62000F5065C07C6073308A30816098C09040A57 +:10A630007E0AFA0A790BF80B790CFB0C7E0D010EE1 +:10A64000830E060F870F0710861003117D11F51179 +:10A650006912DA124713AF1313147214CB141E15B8 +:10A660006B15B215F2152C165E168916AC16C716A8 +:10A67000DB16E716EB166A00750081008E009D0060 +:10A68000AC00BD00CF00E200F7000D012601400143 +:10A690005C0179019901BC01E001060230025B0214 +:10A6A0008902BA02EE0224035D039A03D9031B0454 +:10A6B0006004A904F40443059505E90541069C06D8 +:10A6C000FA065B07BE0724088D08F8086509D40957 +:10A6D000450AB80A2D0BA20B190C900C080D800D21 +:10A6E000F80D6F0EE60E5C0FD00F4210B310211163 +:10A6F0008C11F4115912BA1217137013C4131314D6 +:10A700005D14A114E01418154B1577159C15BB1595 +:10A71000D415E515EF15F315550055004500420019 +:10A720000000000001036400640264005A008C0011 +:10A73000BE00140005000000000000000000000042 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000050000000000000000000000D4 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000000000000000000076 +:10AAE0000000000000000000000000000000000066 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB20000000000000000000000000000000000025 +:10AB30000000000000000000000000000000000015 +:10AB40000000000000000000000000000000000005 +:10AB500000000000000000000000000000000000F5 +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00000000000000000000000000000000000A5 +:10ABB0000000000000000000000000000000000095 +:10ABC0000000000000000000000000000000000085 +:10ABD0000000000000000000000000000000000075 +:10ABE0000000000000000000000000000000000065 +:10ABF0000000000000000000000000000000000055 +:10AC00000000000000000000000000000000000044 +:10AC10000000000000000000000000000000000034 +:10AC20000000000000000000000000000000000024 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF000000000000000000000000000004E565459 +:10B0000000007642000074431900CE400C00174146 +:10B010000000000000000000000000000000000030 +:10B02000002492000000000020204801204E02076A +:10B0300041B428122342B428122243B428122344D4 +:10B04000B428122345B4281223469428122348B466 +:10B050002812220000000000000000000000000094 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B090000000000000000000000000000000E20DC1 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:00000001FF diff --git a/firmware/novatek_ts_fw.bin.ihex b/firmware/novatek_ts_fw.bin.ihex new file mode 100644 index 000000000000..9e747fe57368 --- /dev/null +++ b/firmware/novatek_ts_fw.bin.ihex @@ -0,0 +1,12291 @@ +:100000000002000000000000F77B01000020020059 +:1000100000000200EFBE00009812AE701B67A543FF +:1000200003000000000000000000000000000000CD +:100030000000020000000000002002006D994B4308 +:10004000000A020000000000002A0200CB94D02029 +:100050000032020000000000005202000C52006852 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F000F0BE0200FF000000000000006D32499FCA +:100100000002000000000000F77B01000020020058 +:1001100000000200EFBE00009812AE701B67A543FE +:1001200001000000000000000000000000000000CE +:100130000000020000000000002002006D994B4307 +:10014000004A020000000000006A0200AF0FDC1548 +:100150000072020000000000009202000C520068D1 +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F000F0BF0200FF00000000010000DC7AD24BDB +:10020000480001A2EAB10000EAB10000EAB1000032 +:10021000EAB10000EAB10000EAB10000EAB1000072 +:1002200048000000DD4B0000EAAD0000EAAD000030 +:10023000DD4B0000EAAD0000DD4B0000DD4B0000AF +:10024000DD4B0000DD4B0000DD4B0000DD4B00000E +:10025000DD4B0000DD4B0000DD4B0000DD4B0000FE +:10026000EAAD0000EAAD0000DD4B0000DD4B000010 +:10027000DD4B0000EAAD0000EAAD0000DD4B000000 +:10028000DD4B0000DD4B0000DD4B0000DD4B0000CE +:10029000DD4B0000DD4B0000DD4B0000DD4B0000BE +:1002A000DD4B0000DD4B0000DD4B0000DD4B0000AE +:1002B000DD4B0000DD4B0000DD4B0000480000007E +:1002C00048000000DD4B0000DD4B0000DD4B00006E +:1002D000DD4B00004800000048000000480000001E +:1002E00048000000480000004800000048000000EE +:1002F00048000000480000004800000048000000DE +:1003000048000000480000004800000048000000CD +:1003100048000000480000004800000048000000BD +:1003200048000000E8040000E8040000580700004E +:10033000EE110000EE110000EE110000EE110000C1 +:10034000EE110000EE110000EE11000000000000B0 +:10035000120900001A09000056090000D009000027 +:10036000180A00009A0A0000FA0A0000180B0000A0 +:10037000200B0000280B0000300B0000380B0000A1 +:100380004A0B0000520B00005E0B0000A80F00009B +:10039000700B0000040C00004C0C0000540C00001A +:1003A000900C0000A20C0000B40C0000DA0C00005D +:1003B0005E0D0000DA0D0000E20D0000F40D0000FB +:1003C0003C1000003E100000621000006A100000A7 +:1003D00072100000821000008410000090100000D5 +:1003E0009E100000BA100000000000000000000095 +:1003F000221100003E1100008A110000D0110000FF +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:100450003A0FEFFC421E80203A1F883C6412A4022F +:10046000642204023A1F883C803F640264029205C1 +:1004700096374420012C38210202643200029ED9B2 +:1004800064320003DD2264020043640000083A1F66 +:1004900088046412A403642204033A1F8804421EE1 +:1004A00080213A0FEFC4640000043AFFECBC3A0F1D +:1004B000943C421E80203A1F883C640264029205EC +:1004C00096374420012C382102028E09DD223A1F82 +:1004D0008804421E80213A0F94043AFFEC846400A1 +:1004E00000043AFFECBC3A0F943C421E80203A1FB5 +:1004F000883C6412A402642204023A1F883C64020D +:100500006402920596374420012C382102028E099C +:10051000643200029ED964320003DD22640200438B +:10052000640000083A1F88046412A40364220403D0 +:100530003A1F8804421E80213A0F94043AFFEC844B +:10054000640000044FF200223A0FEFFC421E8020AC +:100550003A1F883C45D2D4D0801F64126402965F53 +:100560009E49C1053CFD4B15480000043CFD4B165F +:10057000E80CDD2F4E03000A3A1F8804421E80213A +:100580003A0FEFC464000004640224024410C00067 +:10059000FE0FFE0D640224036400000845D2D4D08F +:1005A00045F2FE006400800292189604C0054401E2 +:1005B0004D94420E002144F004BAE802DD2F3CFDC8 +:1005C0004B17DD2F640FFFEAFC004462EB2C440262 +:1005D000C0F084209AB0EA42EA38AE31FC80FC00D8 +:1005E00084003C0FFB7FEB523C0FFB8E3C0FFB92D9 +:1005F000EB6A3C0FFBA33C0FFB883C0FFB933C0FCB +:10060000FB8F3C0FFB9B3C0FFB903C0FFB8C3C0F8C +:10061000FB893C0FFB823C0FFBA13C0FFBA63C0F70 +:10062000FB993C0FFB9A3C0FFB973C0FFB7DEB7754 +:100630003C0FFB913C0FFB87EAF6EABB3C0FFB84C7 +:100640003C0FFB863C0FFBA53C0FFB983C0FFBA02F +:100650003C0FFB8D3C0FFB833C0FFB953C0FFB8558 +:100660003C0FFB943C0FFB9C3E07EC9E6403000395 +:10067000EA70EB3A64122402964C8040C103640392 +:100680000003642224036402000266000006640280 +:100690000003640000086403040246029C1050003A +:1006A000007CEA706403080244000633EB3A6402FB +:1006B0000002EA4564020003FC804403F0EDA6401A +:1006C0005A1801048420AE404413F0DAA608EB0A5D +:1006D000AE088404EA7084254403F049AE40441017 +:1006E0000053DD43AE40DD9EDD9E4443F114B4640F +:1006F000927840000F04B6044403F138AC408420E3 +:100700004403F13AAE404403F104B640842144036B +:10071000F136AE40F808A640964CC103AED0D5FCE9 +:100720004413F134EA36EA3383FFA608960EC80371 +:10073000AED0D5FC4403F134A6009604DD9E84A01F +:10074000D20738301400383094088CA1D5FADD9ED9 +:10075000FC00DD41C00C8407DD4A8400DD4A441200 +:10076000BFF08402804144300100DD46FC80FC0083 +:1007700080C0DD41C012441FFF9FEB8FAE4096301A +:100780004412FE61AE08EB3D4412FE62AE08DD434A +:10079000DD44C603AE40D5FEFC80FC403C7DFB56EC +:1007A0008140DD41C05B852384C03C2DFB56402148 +:1007B0002480A051C108F85C5A0801064010240C9E +:1007C000FF8F97B18D215A980FF2F85F5A080104F4 +:1007D00042633C088387B97DB87C8E249649BA7FF2 +:1007E000F85C5A08010558630001D502C6055AA8ED +:1007F000AE048006F8118420EB05AE404402FE638F +:10080000A6408420AE40A681AE4149000F185A0888 +:1008100001065803000249FFFFACEA5DEA3DEA2801 +:10082000A78097B05A600204AE88D5FB4472FEF1EF +:10083000A6385A008608440000C1DD42F87FAE4069 +:10084000D5FF4900395E84003E07EE91802780067F +:100850004422C3618461DD46FCC05AA8AE4B84E3E8 +:1008600080C03C2DFB5640211C80A051C10BB4021E +:100870009649A093F8125A08010640001C0CFF8705 +:1008800097B18CE15A780FEF3C2DFB568382B93D2E +:10089000B83C8E249649BA3F49FFFF295A08010502 +:1008A000EA5A42633C0884204402FE78AC40441279 +:1008B000FEF1EA5DC619442FFFEEAE888422AE40F9 +:1008C0004412FE60440FFF8FAE084422FE61963052 +:1008D000AE10EB3D96004422FE62AE108463804170 +:1008E0008402DD46D520442FFF86AE888422D507BA +:1008F000441FFF86EB05AE408422EA5DAE40440310 +:10090000F007A6004412FE639600AE084403F0040C +:10091000A6004422FE649600AE10840280418060EE +:10092000DD4684C04412FEF1804184618402DD46CC +:10093000EA22804184028461DD46DD43DD4483FF99 +:10094000C603AE40D5FE4412FEF1EA36EA33A608ED +:10095000C003AED0D5FDFCC03A6FA0BC840080209F +:100960004900628A84006405E403EB78A44096663B +:100970009649C102D5004422FEF6AE50A440964EE0 +:10098000C910A4409656C90DA440965EC90AA44059 +:100990009666C907A4405410810096494E120084FF +:1009A000EBFFA408960EC806A5885463010097B112 +:1009B000C6208400EA9AA788AC0844138D203E071D +:1009C000EC4CAE0844138D21AE0844138D22AE08C2 +:1009D00044138D23AE0844138D24AE0844138D2593 +:1009E000AE0844138D26AE0844138D2797B0AE0889 +:1009F00049FFFDEC49000CBEEB78A440964EC908B7 +:100A0000A4409666C905A40054000100C003490033 +:100A100036AEEB8F8420AC404472BEF08400EABB5B +:100A20003C7FFB56EAF63C0FFB9DDD41C805507349 +:100A300081003C7FFB5649FFFE8D800649FFFEAFDB +:100A40008423EA5DAE4084014413F7D3AE08441317 +:100A5000F7D9AE08FA56EAAF4412FE7849FFFE71A4 +:100A60003C0DFB564432FE7C040000093E072B4D32 +:100A7000401020093E172B4E4010400992183E1797 +:100A80002B4F3E072B504422FE7DF8054432FE7E5C +:100A90004422FE7FA618A6509602964AAE58AE1083 +:100AA00083FFD508A40054000200C004840249005A +:100AB0000E614413F029A608EAA8AE088400EA5E95 +:100AC0003C0DFA71EBFFA648EB624413F00FA64809 +:100AD0001010003D490036B53C0FFB64FA04F802E3 +:100AE000FA0449004E4A2E07ED90DD4AEA3F9E8106 +:100AF000E648E80B84214010880C5410808FC10513 +:100B000050007FE09600DD424900049B3A6FA084CC +:100B1000DD9E84013C0FFB7FDD9E3BFFFEBC3C0D58 +:100B2000FB8A8C01EB522E07EF765A0801133C1D0D +:100B3000FB8A2E07EF75E220E8044900630AD50915 +:100B40004900630D84004900612184003E07EF766F +:100B50003BFFFE84DD9E3BFFFEBC3C0DFB8E8C010B +:100B60003C0FFB8EDD40A6008E01E602E82D2E072D +:100B7000EC515A08550A3C03F65D8C019601E60AD1 +:100B8000EB7AE91DD508DD41C0182E07EC475A085D +:100B90005515D5F28404DD4284013E07EFC284007E +:100BA000EA23DD40A6005A080105EA96EA5BD5076C +:100BB0008E02E602E900D5038400EB7AEA3A3E07AA +:100BC000EC51EA87D5038400EB7A3BFFFE84DD9E7F +:100BD0003A6F98BC4403F06BA6003E07EC9CDD47DF +:100BE000C8062E07EC9C961F5A000F16FA10DD421D +:100BF00084013C0FFB92EBB7490066B0DD408422D4 +:100C0000DD55490066C3842084028446806180816A +:100C100080A1DD53EA21DD9E3A6F9EBC490061E56B +:100C2000C0178400490061E5F82280C05A0801110C +:100C3000DD475A0802043C6FFB8B44000080DD4214 +:100C4000DD40EB44EABDEBB5848149001DBA4900A3 +:100C500061C3C00784013C0FFB9E8400490061C052 +:100C6000490061F3C0108400490061F3490062400B +:100C700080805A080109EABBEB44DD40EABDEBB5D0 +:100C800049001D9F490061D8C0068400490061D811 +:100C90008401EAF63A6F9E84DD9E3BFFFEBCDD5880 +:100CA00084213C1FFB9FAE40EA3844238D433E071E +:100CB000EC51A6108801AE10DD40A681542100FD44 +:100CC0005A200403DD554900663CC00A8409DD4210 +:100CD000FA18EA3B8403EA6D84013E07EC742E07A0 +:100CE000EF3F8C0196003E07EF3FDD41C8048401D1 +:100CF0003E07EF2E3BFFFE84DD9E3A6F98BC8401D9 +:100D00003C0FFBA3FA11DD424403F082A600C003AE +:100D1000EA96EA5BEA21DD9E84013C0FFB88DD9EBA +:100D200084013C0FFB93DD9E84013C0FFB8FDD9E15 +:100D300084013C0FFB9BDD9E3A6F98BCFA12DD42AA +:100D400084013C0FFB90EA21DD9E84013C0FFB8C6B +:100D5000DD9E3A6F98BCFA13DD42EA21DD9E3A6FC0 +:100D600098BCFA14DD4284013C0FFB82EA21DD9E2F +:100D70003A6F9ABCEFF4490016BA3C0DFBA1EA5C4D +:100D80008C013C0FFBA1EAA4EBAB8C013C0FFB9563 +:100D9000EAA4EB16960049001295000F8006EA5C63 +:100DA000490013D23E07EC4FDD41C005EBAFC8034D +:100DB0008401D508DD41C805EBAF96005A00010358 +:100DC0008400EBB8EB8D5A08010A8400EBE944017A +:100DD00024F83C0E03904900163F3C6DFBA15A6875 +:100DE000020F3C0DFB865A08010BDD41C808800646 +:100DF0004413970044238D54EAFAEACAEC0C3A6F84 +:100E00009A84DD9E3A6F98BC84013C0FFB8D3E07AF +:100E1000EF6C4403F07EA6405A10010FA6405A1012 +:100E2000020CA6405A100309A6405A100406A64018 +:100E30005A101003A60084418420806280824400FE +:100E4000B101EAA749003096EA21DD9E84013C0FFA +:100E5000FBA6DD9E84013C0FFB994403F064A64091 +:100E6000964CC90FA640EBF4AE40DD40A6008E02C2 +:100E7000E602E90E3A6F98BCEA3AEA5BEA21D50845 +:100E8000A640964CC105A640EAC6AE40DD9EDD9E5A +:100E90003A6F98BCFA15DD4284013C0FFB9AEA21B7 +:100EA000DD9E3A6F98BCFA16DD4284013C0FFB9739 +:100EB000EA21DD9E3A6F98BCFA17DD42FA04DD4A5A +:100EC00084013C0FFB7D490019515A08A104EA3AFC +:100ED000EA5B8403EA6DEA21DD9E3BFFFEBC8401F0 +:100EE0003C0FFBA0EB3044138D468C01EB77A6083A +:100EF0008C01AE0849000DB1EB8DC813DD41C00572 +:100F0000EBAF96005A000107DD41C805EBAFC803FF +:100F10008401EBB88400EBE9440061A83C0E039027 +:100F20004900104DDD41C015DD575A0820132E072A +:100F3000EF24E602E90EEB305A0801084402988CCF +:100F4000EB0044201900DD488401842049001CD7AF +:100F5000DD41C803490015D23BFFFE84DD9E3A6F98 +:100F600098BCFA18DD424403F00AA600DD424403AF +:100F7000F00DA600DD42EB78A600DD424403F00F41 +:100F8000A600DD424403F01AA600DD424403F01B34 +:100F9000A600DD424403F082A600DD424403F35381 +:100FA000A600DD424403F369A600DD424403F38654 +:100FB000A600DD424403F387A600DD424403F3CFDD +:100FC000A600DD424403F40CA600DD4284013C0F80 +:100FD000FB91EA3AEA5BEA21DD9E84013C0FFB8744 +:100FE000DD9E4403F403A60096005A0801043C0F5A +:100FF000FB84DD9E84013C0FFB86DD9EFC2084018A +:101000003C0FFB8684003C0FFB953C0FFB85DD40CD +:10101000A6419E8BE642E9055A1006045A180D3384 +:10102000DD56A6485A18012FEA342E07EC8FC80D5A +:101030002E07EC33C80A3C5DFB613C0C006AD0050E +:101040004402C2304900630ADD40A6015A0003048D +:101050005A080D19EAE9C8162E07EC8FC8132E0797 +:10106000EC33C810DD4FA600C805802044238D4115 +:10107000D5079E43E622E80644238D41A650490049 +:10108000680ADD41C00349000FF0DD54A6095A008B +:101090000D079E82E642E9035A080726A6885A28C9 +:1010A00001232E67EC2197B0CE3ADD58A6005A08EE +:1010B0000137DD4CA7C097F85A78013280018026AD +:1010C000EAC8DD558007EA23DD58AF80DD4CAF80EC +:1010D0008409EA508404DD4A2E07E9BCDD4A800712 +:1010E000EA73D51D5A08041C2E67EF34CE18DD595B +:1010F000A6485A100215DD4AEACB04000008962FD4 +:10110000DD4ADD408026EAC8DD558401EA23DD584A +:10111000AF80DD4CAF8084013E07EF34EB0F5A08FF +:101120000104490016A8FCA0FC20EACB3C5C00644A +:10113000D0043C5C0065D80CEB27C80ADD58A6003B +:101140009600C806DD59A6885A280103AE082E0766 +:10115000EC40C023EB84EAF5D8202E67EC21840014 +:1011600097B03E07EC40CE19DD58A6005A0801168C +:10117000DD4CA7C097F85A7801118026DD40EAC8F7 +:10118000DD558405DD4A8007EA23DD58AF802E0750 +:10119000EC74C803DD59AE082E07EF24E602E8041C +:1011A0008C013E07EF24FCA03A6F9EBC4900083733 +:1011B000DD41C8082E07EC9E5A00013F84013E071E +:1011C000EC9E44138D45A6088C01AE08F818C01794 +:1011D0008401DD4ADD4180C0C00749000956840012 +:1011E000490014ECD50C4412C1F08041846484029F +:1011F000DD468006490014E2490007F649003989B6 +:10120000C00984013C0FFB963E07EC2349FFFEF822 +:10121000D50984023E07EC2349FFFF88DD58A6006C +:10122000F85484013C0FFB9D84003C0FFBA13E075A +:10123000EC9E4900081C3A6F9E84DD9EDD9E3A6F4D +:1012400098BCFA19DD4284013C0FFBA5490059A660 +:10125000EA78C80449006382D5034900596AEA2143 +:10126000DD9E84013C0FFB98DD9E84013C0FFB83D7 +:10127000DD9E3A6F98BC8403DD4A8401EA73EA215B +:10128000DD9EDD9E3A6F98BC8401F806EA21DD9E62 +:101290003A6F98BC840049000F28EA21DD9E3A6F1E +:1012A00098BCFA1BDD428400842A490032C9DD4122 +:1012B000C003EA96EA5BEA21DD9E3BFFFEBC4403E5 +:1012C000F41CA600E602E81549000ED8DD41C01165 +:1012D000DD40A6015A08030E2E07EC3AC00A84002E +:1012E0004412DE7C3E07EC3A80418402EAB6EACA48 +:1012F000DD41C80DEAE15CF000A0E9098402441375 +:1013000058904423806844300C80EACA2E07EC7160 +:10131000C0068401EB8084003E07EC713BFFFE8435 +:10132000DD9E3A6F98BC4413F7EEA60896009684AB +:10133000C203EA8FAE088400F857EA21DD9E3BFF26 +:10134000FEBC84013C0FFB9C4413F7EFA6089600FB +:101350009684C203EA8FAE088401F846F829EB8D23 +:101360005A08010C3C0DFB78C00684024900094C68 +:101370003C0FFB78490013702E07EF2EC0048E013E +:101380003E07EF2E3BFFFE84DD9E3BFFFEBCDD47AC +:101390005A08020584013C0FFB944413F7C9A608C0 +:1013A00096009684C203EA8FAE088400F81D4900B7 +:1013B0000C66DD41C80BEAB5A600C008DD40EB4471 +:1013C000EABDEBB58481490019FC3BFFFE84DD9E3C +:1013D0003A6F98BC4413F7CAA60896009684C203D5 +:1013E000EA8FAE0884014900089AEA21DD9E3BFF9E +:1013F000FEBC2E07EC9FC81DB401A6003C0FFBF4F9 +:10140000640264024412FFF03C0FFBF3B6013C1D82 +:10141000FBF44402FFF4B6204601122350000344BB +:101420004412FFF8B6012E07EC9F8C013E07EC9F9B +:10143000FA1ADD42EA96EA5B3BFFFE84DD9EFC631E +:101440008400EBD8490039E65A00081749003A658C +:101450002E07EFD4441000A08C013E07EFD4840384 +:10146000DD45840DDD4A49003A91840EDD4A84034E +:10147000441000A1DD45B1834492E5E644A0012C6F +:10148000DD414E020078EB82442397EC40110420AA +:10149000A448440397D8964BAC403C0C03954413A6 +:1014A00097DA40010020A4009603AC08F8634900D5 +:1014B0003AA65A0003CD5A0802078404441000607B +:1014C000DD45D5C75A0013DEF868F86CDD4CA7C0BF +:1014D00097F8CFD72EB7EC9A5AB801D48403EB7E95 +:1014E000DD45DD5A3E77EFCA5A080206490040172B +:1014F0003EB7EC3A49003BAFDD575A081209EA6C97 +:101500008420EA7F5A0801048400F82FDD575A0826 +:101510000408490041DEEB81F8ACF826D5285A08CA +:101520001406EB81F8B0F820D5225A081906840079 +:101530008020490019E449003BD5490042DA5A08A5 +:10154000020448FFFF87DD575A080508490041C0DB +:10155000EB81F8EBF809D50B5A08150AEB818403E7 +:10156000441000A9DD45EACFEA4EEA714900418DF9 +:10157000F9358403EBCADD45490044EA80E0840183 +:10158000EB4E5A08010448FFFF9A5A78030448FFBB +:10159000FF5F5A781303F9228403441000A3DD454A +:1015A000EAEF8403EBC5DD45DD4CA600C807DD404E +:1015B000A6415A180D048423AE41440000A3EB3920 +:1015C0002E07EC5E4E0300F02E17EC39440297E82C +:1015D0004900202EF081EB7E8403DD453C7DFB6DD0 +:1015E000800749003E145A7805112E07EF955A08D6 +:1015F000010D2E07EF94C8092EB00E684EB30006F9 +:101600004900696B3EB7EF952E07EF96C82CEACEDE +:10161000C02AE6E2E828EBDC5A000705EA465A0849 +:1016200009238404EAF9800749003BC1EACE4E73DE +:1016300000D8EA86EB58EACE5CF00030E9142E10B0 +:101640000E4C8401EBA0C90684273C1E0398F805C4 +:10165000D50A8407EA548400EAECEB5FEB5883FF79 +:101660008405EAF9800749003F98DD575A081409B4 +:101670008403441000A6DD45F85C48000092EA2A85 +:101680005A08040A8403441000A7DD4549003B7F43 +:10169000EAF9D5542EB00E684EB30051E6E2E842A6 +:1016A000800749003FE05A78013E8007490040A08A +:1016B000EB3B3EB7EC2C8E04E602DD57E90F5A00F7 +:1016C000150E3C1C04285A100503C90584203C1E35 +:1016D0000392D50484223C1E03928E14E602E90C88 +:1016E0002E07EC5AC8073C000888C0068E01EAB7EE +:1016F000D5033CA808888400EBA12E07EC86960051 +:101700005A00010AEA67C80EEB838041EAFA8402B4 +:10171000DD46D5083E07EC452E07EC455A0001FE94 +:10172000D5F2DD575A08150B8403441000A8DD4597 +:101730003C0DFB5BEB2849003CBFF001EB834422EE +:10174000E3344900210ADD578E14E602E929EB0F44 +:10175000C8272E17EC2DC924EB3B9E82E643E80AEE +:1017600084223C1FFB485A08031C8401EBA184011E +:10177000D50C5A0805043C1808883C100888C91084 +:101780008401EA7A3E101116AC30149300021493CF +:1017900000014402E2B03A130C00490010CB84016E +:1017A0003E07EC5E2E07EC825A080512DD58A600B3 +:1017B0005A08010EEA675A08090B2E17ED6C2E27FE +:1017C000EC7C2E07EC8249000CEAF8082E07EC822C +:1017D0005A000603F8038400EABC48FFFE53EA7986 +:1017E000EB5848FFFF2A3C0FFC09DD9E3C0FFC082C +:1017F000DD9E4402B7F43C0FFBF8DD9EFC20A5C83B +:10180000B4C097FBE0E63D27F052E80BA448EA9EFF +:101810009A71964BFE544010C8368AC1B6C0FCA0DF +:10182000A410B5839603E00605118001E812A448D0 +:10183000EA9E8A26964BFE544000C8169603FF4443 +:101840004022FC0A40581401E38540188801D51352 +:10185000A5C8A490EAF19ABA9693420104244000E4 +:1018600048169603FF444012FC0A40581401E385D1 +:10187000401884018A2FB6A3A859B444A06140300F +:101880007C0A9A10E2408A238A2FB604A861FCA041 +:10189000FC4180E18123CC09B400C2090260001F31 +:1018A0000220001E97B3D50CA001CA05A580A48113 +:1018B00097B3D506026000310220003097B380262E +:1018C00096938007490046D0001480005A10FF0507 +:1018D0008C2188019201EA52803FB0814900472B58 +:1018E000B41F38138111F001382381118402EAAE4C +:1018F00042030873EAA6FCC1FC61C30A2E47EC62EE +:101900002E57EC245C4200015CC28001D503818328 +:101910008083B4A04E5202388EA4E6A24EF3023465 +:1019200080E0A60C8143816280C1C863CC62EBADCC +:10193000C30E3C0DFB62EADD4EF20232EA2F5A0082 +:101940000103F803501082884800022A501085BE17 +:101950005033806E8440800B8082F9873C9348C06E +:10196000F0813C8348E04EA20019B42BB0019C8A60 +:101970005043002880A950330010F98CA035A0B442 +:10198000944140508BF5F40194514024A00140044F +:101990008806EBBEFE02D56C3C17F4C23C47F4C689 +:1019A000FE0CA0B5412012564044801394514022B1 +:1019B0002001E28252478000A034952140920BF52D +:1019C00041197C0A9491405083F59441EB204204E4 +:1019D000C873422148698860980AEBC9E201986B94 +:1019E0000433000B88524041480688714800008843 +:1019F000A6355A001F04480000874E430085EBAD12 +:101A00004EA200103C0DFB62EADDE807EA2F5A08FF +:101A100001055010832AF803501080A2480001C429 +:101A20005010851C5033806E800B84418480F91DDA +:101A30003C9348DFF0813C8348FF4EA20037B44B13 +:101A4000B0015011003E504300285021003C80A9B5 +:101A500050330010F91FA035A0B49441F401405058 +:101A60008BF594514024A000EBBE40012406940164 +:101A700040900BF59491EB20420490734221106941 +:101A80008860980AEBC9E201986B0433000B884424 +:101A9000404110068871882F8864EA40960312033B +:101AA000800812038018D53D3C17F4C33C47F4C6A8 +:101AB000FE0CA0B5411012364044801394514022D0 +:101AC0002000E244A0344047840840920BF54128AE +:101AD000FC0A9491405083F5944142090824420441 +:101AE000C473422144698860980AEBC9E201986B8B +:101AF0000433000B8851404144068872882F886463 +:101B0000EA40D50D841F4EA200071003806C22030B +:101B10008004D5C61003806E0203800C1203800E71 +:101B2000A6364E0300854EC30083EBAD4EA2000FD8 +:101B3000EA55EADDE807EA2F5A080105501083CC80 +:101B4000F8035010814448000133501085BE5033D3 +:101B5000806F800B84408481F8883C93485CF081DE +:101B60003C83488E4EA200350415800180A99C8AD2 +:101B7000B0015033001850430030F88CA037A13624 +:101B80009441402093F594614044A00140049006A4 +:101B9000050F8001FE029401409013F541187C0A64 +:101BA0009521420890244204C0734242406988A0B3 +:101BB000980C403004069855EAE60453000D88500E +:101BC0004041400688B1882398E54800008A3C17C8 +:101BD000F4C43C57F4C6FE0CA0B6405014B6A0376F +:101BE0004112FC0A944141008BF59451402480132A +:101BF00040412001E244522780009491409113F526 +:101C000094A1EB2042049473422114698860980ADD +:101C1000EAE6E20140180C000433000D884540510B +:101C200014068871882F886548000095A6375A00E9 +:101C30003104480000924EC30090EBAD4EA2000F5D +:101C4000EA55EADDE807EA2F5A0801055010846ECC +:101C5000F803501081E6480000AF5010851C503347 +:101C6000806F8441800B808249FFFE143C83488D45 +:101C7000F0813C9348BF4EA2004304258001B0018F +:101C80005011006250330018502100605043003062 +:101C900080A849FFFDB5A037A0B6944141008BF55F +:101CA000945140242400F401405120069569EBBE74 +:101CB00040528BF59491EB204202907342211069BF +:101CC0008860980AEAE64050040640180C00043385 +:101CD000000D884440411006887188258864EA40D8 +:101CE00096031203800912038019020380083C0B3B +:101CF000F7EE020380093C0BF7EFD5613C17F4C502 +:101D00003C47F4C6FE0CA0B640401096A0374054A5 +:101D10000013944141008BF594514022A400E24508 +:101D200040578408EBBE40528BF59491EB20420261 +:101D30009073422110698860980AEAE6E20140182F +:101D40000C000433000D8844404110068871882F30 +:101D50008864EA40D50D841F4EA200071003806DF1 +:101D600022038005D5BF1003806F0203800D12038C +:101D7000800F0203800C3C0BF7EC0203800D3C0B40 +:101D8000F7EDD51D843FC3061010006C1010006DD8 +:101D9000D5161010006E1010006FD5115033806CE6 +:101DA00048FFFDDA5033806C48FFFE405033806DB1 +:101DB00048FFFED15033806D48FFFF55FCE1FC2009 +:101DC0003C6DFC0884E1A772A7B3C20284FFC90876 +:101DD0009E69FF4442510473B6A388A7D50B9E7138 +:101DE000FE8C802042111473884742011473B6237D +:101DF00080A0B6A4FCA0FC6384C081A08141F281D4 +:101E0000818380E4816581038126E2E8E91280080C +:101E1000F112F201B0C2B10349FFFFD3F0028D010C +:101E2000380681118920F0033806811188C0D5EE6B +:101E30008AEC8405FFFB42638073844142230800DF +:101E4000800A802949004410002580005A20FF069E +:101E50008C41884040010409EB69B044B0854900D9 +:101E6000446AF00438150111F00538250111840287 +:101E7000EAAE42048873EAA6FCE3FC6581213C1DBE +:101E8000FC08F28200208032F28400208033F28548 +:101E900020D08039A68A20E0803AA64B50800020CE +:101EA0009E09F083960AF0889E12F0869612F089B9 +:101EB0009E0A4472C4B4854050C17FFFF0873C0D38 +:101EC000FC0800000009E3404EF200EAB2184E029E +:101ED00000D48E04E6024EF300D0040400045A0835 +:101EE0000204480000CAB37F0404800540658808E6 +:101EF0008806A6C0CB24A642E622E9029EC9A70313 +:101F0000F007E080E8038C81D502F4038440B65FDB +:101F1000EB31F00280A8F88B04148006F204EB8BFE +:101F20008A20FE540424800838212E028802EAAE5A +:101F300022147FF2880D9603E001D52CA7414C5660 +:101F4000402CA6C2E662E9038E61D5028460A70335 +:101F5000F007E080E8038C81D502F403EB318400C4 +:101F6000B61F501080A28441F00280A8F8600414CB +:101F70008006F209EB8BEBD5F204FE5404248008B2 +:101F800038212E028802EAAE22147FF2880D9603D1 +:101F9000E020EB3ED506841F1004000002047FF20F +:101FA00012047FF60404800588C0A6F2CB28A63070 +:101FB000E602E9029EC1A731F006E080E8038C81C9 +:101FC000D502808CEB318401B61F501081448440CF +:101FD000F00250540001F82B04148007F205EB8B3B +:101FE0008A20FE540424800838212E028802EAAE9A +:101FF00022147FF3880E9603E001D52EA773F00319 +:10200000D82DA6F0E662E9038E61D5028460A7317F +:10201000F006E080E8038C81D502808CEB318441AE +:10202000B65F501081E640540800F00249FFFEE51B +:10203000041480073820AE02F108EBD2F105FE8CC3 +:1020400004148008EB8B88014001001622147FF3F2 +:10205000880E9603E020EB3ED506841F1004000195 +:1020600002047FF312047FF722047FF6AC382204C7 +:102070007FF7AC39D50E2203800012047FF62203CD +:10208000800112047FF7841F100400001004000177 +:102090008D418CE45084004448FFFF13FCE55A0056 +:1020A00001054403F7DED5034403F7DD441000695E +:1020B000AE40EA3E8420AE40DD9E8401DD9EFC20E1 +:1020C0004473F080A7B897B05433001F583180A0F4 +:1020D000AEF8DD48AFB8FCA0DD5D8E01EAF2DD9E12 +:1020E00044100055DD43AE404413F7F1A6089604B2 +:1020F000C003EA3ED5FCDD9E44100055DD43AE40F2 +:102100004413F7F0A6089604C003EA3ED5FCDD9E12 +:102110004443F7FDA72097205A08010558020008FC +:10212000D503540200F75A180104EA57D5035400A6 +:1021300000FB5A280104EA81D502EB0D5A3801044C +:10214000EA45D502EA8F4413F7FDAE08DD9EFC2177 +:1021500080E08400EA268400802084418060506F03 +:102160008007F835C703EA38EA2684214403F7C01C +:10217000AE40442FFFE7EBF6AE8096B04403F7C6BF +:10218000AE8084404403F7C1AE8084774403F7C433 +:10219000AEC0EB3D96004433F7C7AE184403F7C218 +:1021A000AE8092D08443EBF3AE8097B0EB85AF80E6 +:1021B0004403F7CCAE40EA368020EA33A608960006 +:1021C000C003AED0D5FC80208040806049FFFFA2D4 +:1021D000FCA184004412C1D0845FEAB98C015A0882 +:1021E00007FEDD9E84004432C1D044438D404453F9 +:1021F0008D413811800096805A10FF0D5A20010A37 +:10220000C2055A280208AE68D505EBE1AE50D502EA +:10221000AE608C015A0807EFDD9E4403F7C0A6406C +:102220004402E974AE404413F7C3A648AE434413D6 +:10223000F7C6A648AE464413F7C1A648AE414413BC +:10224000F7C4A648AE444413F7C7A648AE474413A4 +:10225000F7C2A648AE424413F7C5A648AE4544139C +:10226000F7C8A64810100008DD9EFC00EA5344029F +:10227000E974A6804413F7C0AE88A6834413F7C35D +:10228000AE88A6864413F7C6AE88A6814413F7C16C +:10229000AE88A6844413F7C4AE88A6874413F7C754 +:1022A000AE88A6824413F7C2AE88A6854413F7C54C +:1022B000AE8800100008EB85AE40FC80FC408140F9 +:1022C0005400807F80C180E281235A087F0544004A +:1022D00000C8DD42EA535AA8010A8400F9A5EB5070 +:1022E0008420AE404403F7CBD5034403F7CC5424F9 +:1022F00080FF4413F7C0AE8896B04413F7C3AE888E +:1023000096B84413F7C6AE884014A00996484423F3 +:10231000F7C1AE504013200996484423F7C4AE508D +:102320004013A00996484423F7C7AE504014C00993 +:1023300096484423F7C292D0AE5097B04413F7C5E5 +:1023400092F0AF8897F84413F7C8AFC88421AE4025 +:10235000EA36EA33A640C103AED0D5FD5AA801083B +:10236000800AF962441FFFAAEB50AE408401FCC012 +:10237000FC004403F02CA7804413F3EC8401AE0866 +:1023800084474413F3EDAE884413F3EEAE084413D0 +:10239000F3EFAE084423F3F08420AE50846444236A +:1023A000F3F1AED04423F3F28462AED04423F3F3CE +:1023B000AE5097B04413F3F4AE089674C945541365 +:1023C000000296484423F439C1063E07F02B8403EB +:1023D000AE10D5043E37F02BAE50EA5397968401E9 +:1023E000F8C997B08400F8C6C60584013E07E9E045 +:1023F000D5033E67E9E0DD5D5A0802074413F02D7E +:10240000A608EA45AE084401D80044128E104420C4 +:1024100025A049FFFE56441FFF86EB05AE408420F1 +:10242000EA5DAE40441000404403F6CAAE40FA21D3 +:102430004403F697AE40FA2F4403F384AE40842160 +:102440004403F380AE40DD5D5A00011E4605555A37 +:102450004412BEA850000AAA3C0FFA7680418402BA +:102460008464DD46DD43DD44AE404605A5AA500048 +:1024700005A53C5DFA77D8FE460123455000067855 +:102480003C0FFA77FC80FC0049FFFEA5DD4C4412AE +:10249000C1D0A600AE08DD4FA600AE0944038D41B1 +:1024A000A600AE0A804184678402DD46FC80FC20E1 +:1024B000440000C6DD424403F7C0A600DD424403E9 +:1024C000F7C1A600DD424403F7C2A600DD42EBF6E9 +:1024D000A600DD424403F7C4A600DD42EBF3A600EC +:1024E000DD424403F7C6A600DD424403F7C7A60059 +:1024F000DD42EB85A600DD424462FE504472FE568A +:1025000008030001DD424C63FFFD4403F41CA600F8 +:10251000DD42440000C7DD42FCA0FC004423F7F08C +:10252000C80380A2D5034453F7F1A6689648DA178A +:10253000540080029780C609440000C3DD42F817AA +:102540008400F8188400FC809656C118440000C42A +:10255000DD42F80D8006F80E8006FC80546080FE97 +:10256000C60D440000C5DD428006DD4249FFFFA1E3 +:10257000840149FFFD968400FC808401FC80FC40BE +:10258000814080E180C28123EA535405007F5A08CC +:10259000010A8400F8498420EB50AE404413F7CB85 +:1025A000D5034413F7CC542480FF4403F7C0AE8016 +:1025B00096B8EBF6AE8096B04403F7C6AE80400402 +:1025C000A00996004423F7C1AE104003A00996006D +:1025D0004423F7C4AE10EB3D96004423F7C74034C4 +:1025E000C009AE1096D84403F7C292F0AEC097F877 +:1025F000EBF392D0AFC097B0EB85AF808401AE080B +:102600008401FCC05A0001054413F7CCD5034413E0 +:10261000F7CB4433F04AEB43A688C203AF18D5FD8D +:102620005A08010BFC0049FFFD94441FFFAAEB5020 +:10263000AE408402FC808402DD9EFC41DD5D84C1ED +:102640005A0001044800008B4413F7F1EA36EA33DC +:10265000A6089604C003AED0D5FC3C6DFB564413CF +:10266000F1289CB484638402DD464413F11850239E +:10267000000884638402DD464413F10050230018EF +:1026800084648402DD464413F12C502300108463DB +:102690008402DD464413F130502300148463840225 +:1026A000DD464413F1045023001C84648402DD469B +:1026B00084014413F30EEAA08060DD46001F80070A +:1026C000440FFF80FE0FEA264413F30EEAA0846154 +:1026D0008402DD46440FFFAEEA26EA9AEAA084614E +:1026E0008402DD468401EA264413F10D8402EAA047 +:1026F0008461DD46DD43DD44AE404605555A500059 +:102700000AAA3C5DFA76D8FE4601234550000678B9 +:102710003C0FFA76EA7CEA85840AEA3B8401EA58AF +:102720004413F133EAA08060DD46006F8007540354 +:102730000004C0F3978FC606440000C2DD4284C186 +:10274000D50D4605A5AA500005A54412BEAC3C0F08 +:10275000FA77804184028464DD468006FCC1DD5D39 +:102760005A00010544024A00DD9E44020A00DD9E33 +:10277000FC405A000203F819840880C1DD4A440372 +:10278000F31CA600C0074413F33FA60858000080BE +:10279000AE084403F369A6009604C009FA22EA5D74 +:1027A000AE408420EB05AE40480000EB4413F36CD0 +:1027B000A608EB0A5800000AAE082E97F02B2E77D9 +:1027C000F02A5A90010448000080CF1E8009DD4A9B +:1027D0004413F374A60858000003AE08C61284051B +:1027E0003E97F02ADD4A2E07F02980478C013E07EC +:1027F000F029840280208069808780A7DD53D5047A +:1028000044000898EA3B84003E07F02ACE1D44634A +:10281000F36A8402DD4AA630EB0DEA57AE3044007D +:1028200001C2EA3BEA22FA00AE08804184618402D8 +:10283000DD468403DD4AA6304413F369EA45AE3031 +:10284000EA36EA33D51E8400F809844080A280620B +:10285000848384228401DD538401490052A0EA94D8 +:10286000FA0380268046AE3084618402DD4684010E +:10287000EAD1EA3DEA28A6305A0014CBAE88D5FC4E +:10288000A6089604C803AED0D5FC8404DD4A4422D1 +:10289000FEF04433F04AEB43A610EA225A0011043A +:1028A000AF18D5FBFA02AE088440EB05AE80840277 +:1028B00080418060DD468405DD4A2E07F0288C01CA +:1028C0003E07F028D55DCF0EC60D84013E07F02AE5 +:1028D0008405DD4A8402802780478067848380A73F +:1028E000DD5384003E07F02AC61D4472FEF0449377 +:1028F000F04A44A00055A638EA945A00130B8440CD +:102900008401EBC080208062848380A2DD53D5F4F3 +:102910008401EAD1FA04AE308026840280468461C4 +:10292000DD46EA22EA36EA33A6085A001004AED0A1 +:10293000D5FC8403DD4A4413F36AA608EA36EA4567 +:10294000AE08EA334413F369A6089604C803AED070 +:10295000D5FC8404DD4AEA94FA01AE308026804634 +:1029600084028461DD46EA3DEA28A6305A0012045A +:10297000AE88D5FC2E07F0288C013E07F028FCC05D +:102980004423F02BA6502E37F02B96485A380109D5 +:10299000C00458008008D50A540080F7D507C00449 +:1029A00058008010D503540080EFAE10DD9E440324 +:1029B000F02AA600EB9F96005A180104EAE4DD9E77 +:1029C000EA9CDD9EC807FC008401EA5E8405DD4ABE +:1029D000FC80DD9EFC00EA785A0801094403F7F008 +:1029E000A600560000019604FC808400FC80DD589F +:1029F000A6009600C004EA9B5E000001DD9EFC403C +:102A000097808402DD4A8006DD4A4412FEF284018A +:102A1000AE084402FEF3AF80840280418060DD4650 +:102A2000EA6AEA8C4492FEF649FFFFC35A00010BA2 +:102A30008404441000F2DD45EAEFAFF0EAD55A080D +:102A4000ECF58403DD4A84004412FEF2AE08441221 +:102A5000FEF3AE08FCC0FC00EBD6DD475A000207CF +:102A6000DD40A6015A000903F893EACB3C1C006440 +:102A700097704C0080063C1C00654C00C01D2E0762 +:102A8000F07C4C0280E42E07F07FE2A04EF300F6CB +:102A9000EB9F5A100103F87C8428EB062E101128B6 +:102AA0003E17EF314C5000E82E07F0804C02C0E694 +:102AB000480000E23C1C006C4C0080063C1C006D91 +:102AC0004C00C00C2E07F06FE2A0E8472E07F0681C +:102AD0004C02C0D4480000BB3C1C00754C00800672 +:102AE0003C1C00764C00C0462E07F0554C02805D21 +:102AF0002E07F0604C02808B2E07F0624C0280871C +:102B00002E07F0644C0280832E07F0664C02807F13 +:102B10002E07F0614C02807B2E07F0634C02807719 +:102B20002E07F0654C0280732E07F0674C02806F11 +:102B30002E07F05B4C0280122E07F05C4C02800ED8 +:102B40002E07F05D4C02800A2E07F05E4C028006D4 +:102B50002E07F05F4C02C092DD5D5A000103F818A9 +:102B60008408EA6B8409EA502E001135EA63F810F4 +:102B70003C1C00734C0080063C1C00744C00C0518F +:102B80002E07F0464C02C00DDD5D5A0001044800DE +:102B900000758408EA6B2E001128EA63D56E2E07B3 +:102BA000F0414C02C00CDD5D5A0001688407EA6BFD +:102BB0002E00112A3E07EF30D5602E07F0434C025D +:102BC000C006DD5D5A08015AD5562E07F04C4C025E +:102BD000801E2E07F04E4C02801A2E07F0504C0239 +:102BE00080162E07F0524C0280122E07F04D4C0238 +:102BF000800E2E07F04F4C02800A2E07F0514C0237 +:102C000080062E07F0534C02C039DD5D5A000136B4 +:102C10008407EA6B2E00112C3E07EF30D52E3C1CAA +:102C200000664C10400C2E27F02B84282E00112912 +:102C3000EB065A280113EA63D5203C1C007C4C109B +:102C400040102E07F02C4C02C019DD5D5A00011611 +:102C50008407EA6B2E00112B3E07EF30D50E3C5C4B +:102C6000007BD80BDD5D5A0801098408EA6B2E0051 +:102C70001128EA638409EA50FC80FC00EBD63C0D85 +:102C8000FB6C5A0008083C0DFB6C5A000704480016 +:102C90000195DD475A000208DD40A6015A000904EB +:102CA000480001673C1DFB583C2C00649770DD5DBB +:102CB0004C1100063C2C00654C11400F2E17F08182 +:102CC0004C1280A42E17F0824C1280A02E17F07C9C +:102CD0004C12C144D5123C2C006C4C1100063C2C0B +:102CE000006D4C11401A2E17F06FE2A14EF2008ECB +:102CF0002E17F0684C12C1325A080103F8B2EA27C5 +:102D00004E1700048E21EA84EA274E1301278444DB +:102D1000EB87EAABF8B63C2C00754C1100063C2C56 +:102D200000764C1140672E17F0554C12C0115A080E +:102D30000103F897EA274E1700048E21EA84EA2758 +:102D40004E13010C8445EB87EAABF89B2E27F0600D +:102D5000D20D2E17F0624C12800A2E17F0644C121E +:102D600080062E17F0664C12C0205A080103F8792D +:102D7000EA274E1700048E21EA84EA274E1300EE5C +:102D80003C1FFB6DEAAB4C51007B2E17F0624C12DE +:102D9000807F2E17F0644C1280822E17F0664C1242 +:102DA000C0DD480000832E17F0614C1280922E1770 +:102DB000F0634C12808E2E17F0654C12808A2E170D +:102DC000F0674C1280862E17F05B4C12801F2E1776 +:102DD000F05C4C12801B2E17F05D4C1280172E17E2 +:102DE000F05E4C1280132E17F05F4C12C0B7D50D59 +:102DF0003C2C00734C1100063C2C00744C114076A6 +:102E00002E17F0464C12C0075A000103F83A48004A +:102E1000009B2E17F0414C12C0145A080103F821F0 +:102E2000EA274E1700048E21EA84EA274E13009603 +:102E30008445EB8784413E27EF95EAABF8222E27A5 +:102E4000F04CD20D2E17F04E4C12800A2E17F05077 +:102E50004C1280062E17F0524C12C02B5A08010457 +:102E60004800007EEA274E1700048E21EA84EA27F4 +:102E70004E1300743C1FFB6DEAABDA05842BEB2B81 +:102E80004800006C2E17F04E4C12C005842CEB2B22 +:102E9000D5642E17F0504C12C005842DEB2BD55D58 +:102EA0002E17F0524C12C05A842EEB2BD5562E17EB +:102EB000F04D4C12800E2E17F04F4C12800A2E1738 +:102EC000F0514C1280062E17F0534C12C0475A0096 +:102ED0000147EA274E1700048E21EA84EA27C93DFC +:102EE0008441EB87EAABD5393C2C00664C1140108D +:102EF0005A080108EA9B4E0700338E01EA63D52F7A +:102F0000EA274E17002B8E21EA84D5273C2C007C23 +:102F10004C20C0112E17F02C4C12C0205A0001205A +:102F2000EA274E1700048E21EA84EA27C916EAAB85 +:102F3000D5143C5C007BD9115A0801104403F403FA +:102F4000A600C80DEA9B4E0700048E01EA63EA9BC7 +:102F5000C8068406EA50D5035A080105EA9BC82D25 +:102F6000D5042E0FEF30C829840AEA6BD526DD4739 +:102F70005A000224EB84EAF5D820DD5D5A08010EE0 +:102F8000EA9B4E0700048E01EA63EA9BC81684069A +:102F9000EA508404DD4AD5118402DD4A2E0FEF2F5A +:102FA0004E0700058E013E07EF2F2E0FEF2FC805AD +:102FB0008406EA508403DD4AFC80FC00EB30960076 +:102FC0005A080114DD5D5A08014FDD5A5A08020BF8 +:102FD0004900352B49007CCBC0468400EA2CEB1A13 +:102FE000D5428400EBA1D53F2E57F04CD804840085 +:102FF000EA8ED5392E57F04DD8048401EA8ED533A8 +:103000002E57F04ED8078402EA8EDD5D5A08012C57 +:10301000D5DD2E57F04FD8048403EA8ED5242E57E1 +:10302000F050D8078404EA8EDD5D5A08011DD5CE24 +:103030002E57F051D8048405EA8ED5152E57F0523C +:10304000D80D8406EA8EDD5D5A0001C14412E318F2 +:103050008041FA748402DD46D5062E57F053D8031A +:103060008407EA8EFC8044039680A600961F8E019A +:10307000E6013EF7EC96DD9EFC202E07EC9697804D +:103080005A6801314413968144039680A600A688AD +:1030900044139682A648407010094010A0084010C2 +:1030A0008A0444239683A690FE5744239684A6D090 +:1030B00096D85A7001075A78020BF8038006D50893 +:1030C000800744239690DD468007D5028403842040 +:1030D00044239680AE504423968FAE103E17EC9654 +:1030E000FCA08401FCA02E07ECA0C005FC0084031A +:1030F000DD4AFC80DD9EFC00C80284263E17EC827F +:1031000049004E30FC80FC03B61FF181F282F3834C +:10311000B45FEBE0EA6F8402F484F585DD46F201EA +:103120004412A69AF837F2024412A82AF833F2039E +:10313000EBCEF830F20444129ECAF82CF205441289 +:10314000A05AF828F20A4412A1EAF824F20B441219 +:10315000A37AF820F20C4412988AF81CF20D44125B +:103160009A1AF818F20E44129BAAF814F20F44129D +:103170009D3AF810F2104412AB4AF80CF2114412C6 +:10318000ABAEF808F2124412AC12F8044412AC765A +:10319000F213EA6F8402DD46FC832E27F02B5A28B7 +:1031A00001044800008DFC4580E0812184048027D3 +:1031B000EBD6DD455A7005075A78060448000066CC +:1031C000F804EA675A000904480000784403F41C34 +:1031D000A6008E02E6064EF20071E724E916E730FB +:1031E000E83D44437A28F82FEAB444137578F4860E +:1031F000F487F488F489B65FF381F082F183F28476 +:10320000F385FD20F829D52A44038388B61FEBCB2C +:10321000F081EB4DF08244037BB8F083EBC2F08485 +:1032200044037ED8F085440386A8F086440388389A +:10323000F087440389C8F08844038B58F08944130D +:103240007578EAB4442377084433789883FF44437D +:103250008068445381F849FFFF58EB83F8244412F7 +:10326000E3188041FA74F821441397DC80418464A8 +:10327000F81C8404441000CEDD45490005E68404B2 +:10328000441000CFDD45D5199630661000088E2613 +:10329000E622E90850107FF6E622E9048E12E602E3 +:1032A000E80CEB838041EAFA8402DD464412E3181D +:1032B00084028041FA74DD468401FCC58401DD9EF0 +:1032C0008E015CF000204EF2013A44F030D4EB0C59 +:1032D000EA31DD0F40004E005E006E007E008E0081 +:1032E0009E00B000C200D400E600F60008011A01FA +:1032F0002C013E014E016001720184019601A6017C +:10330000B801CA01DC01EE01FE0110022202340202 +:1033100046025602A009962FAE10DD519604AE1853 +:10332000DD9EA0099206962FAE10DD51EA92AE18EE +:10333000DD9EA009920C962FAE10DD51EA64AE1806 +:10334000DD9EA0099212962FAE10DD51EA9CAE18B8 +:10335000DD9EA0099218962FAE10DD51EAE4AE185A +:10336000DD9EA00A962FAE10DD514200140BAE1860 +:10337000DD9EA00A9206962FAE10DD514200180B7A +:10338000AE18DD9EA00A920C962FAE10DD514200C1 +:103390001C0BAE18DD9EA00A9212962FAE10DD51C6 +:1033A0004200200BAE18DD9EA00A9218962FAE1098 +:1033B000DD514200240BAE18DD9EA00B962FAE10FF +:1033C000DD514200280BAE18DD9EA00B9206962F11 +:1033D000AE10DD5142002C0BAE18DD9EA00B920CFE +:1033E000962FAE10DD514200300BAE18DD9EA00BC3 +:1033F0009212962FAE10DD514200340BAE18DD9EB6 +:10340000A00B9218962FAE10DD514200380BAE186B +:10341000DD9EA00C962FAE10DD5142003C0BAE1885 +:10342000DD9EA00C9206962FAE10DD514200400B9F +:10343000AE18DD9EA00C920C962FAE10DD5142000E +:10344000440BAE18DD9EA00C9212962FAE10DD51EB +:103450004200480BAE18DD9EA00C9218962FAE10BD +:10346000DD5142004C0BAE18DD9EA00D962FAE1024 +:10347000DD514200500BAE18DD9EA00D9206962F36 +:10348000AE10DD514200540BAE18DD9EA00D920C23 +:10349000962FAE10DD514200580BAE18DD9EA00DE8 +:1034A0009212962FAE10DD5142005C0BAE18DD9EDD +:1034B000A00D9218962FAE10DD514200600BAE1891 +:1034C000DD9EA00E962FAE10DD514200640BAE18AB +:1034D000DD9EA00E9206962FAE10DD514200680BC5 +:1034E000AE18DD9EA00E920C962FAE10DD5142005C +:1034F0006C0BAE18DD9EA00E9212962FAE10DD5111 +:103500004200700BAE18DD9EA00E9218962FAE10E2 +:10351000DD514200740BAE18DD9EA00F962FAE1049 +:10352000DD514200780BAE18DD9EA00F9206962F5B +:10353000AE10DD51921FAE18DD9E8400AE10AE18A5 +:10354000DD9E920004108012FA58FE14EA8A4010A0 +:103550000440EAAF882004008009EA64DD9E04107C +:103560008012FA58FE14EA8A40100440EAAF88201C +:10357000040080089600DD9EFC6081400400000885 +:10358000858181215480003F81AC80CC84E050B59E +:103590000004E3064EF300A79E319600802B4900FD +:1035A00055378E015CF000234EF2009944F033BC95 +:1035B0003827810140F13C004A003C0058001E01C0 +:1035C0001E011E011E011E011E0184001801520071 +:1035D0004C00D800E000E800F000F800000108010D +:1035E00010014600B000B800C000C800D0001E01A5 +:1035F0001E011E011E011E01460046004600460037 +:1036000046008CE197F8D56A9A37EA52D5679A371F +:10361000EA4AD564EA664CA0400D9AB75AD801062A +:103620001024800385A0D55A1024800485A0D55687 +:103630003C0C00734CA040539A3710048003D54EC5 +:10364000EA664CA0400D9AB75AC8010610248005BE +:103650008580D544102480068580D5403C0C0073BD +:103660004CA0403D9A3710048006D5389A37100494 +:103670008007D5349A3710048008D5309A37100463 +:103680008009D52C9A371004800AD5289A3710045F +:10369000800BD5249A371004800CD5209A3710045B +:1036A000800DD51C9A371004800ED5189A37100457 +:1036B000800FD5149A3710048010D5109A37100453 +:1036C0008011D50C9A3710048012D5089A3710044F +:1036D0008013D5049A37100480028CC197B048FF3C +:1036E000FF5AFCE0FC61F081F1018400F8323E00F9 +:1036F000112084003E07EF2B84C04492E5F09DF139 +:10370000F1019638F8262E17EF2B88C9AE318801C3 +:103710003E07EF2B80C75A7808F4F1018409F819A5 +:103720003E001129F101840AF8143E00112AF1012A +:10373000840BF80F3E00112BF101840CF80A3E00B7 +:10374000112CF101840DF8053E00112DF101FA054F +:1037500049FFFF073C7C00733E00113584C0449351 +:10376000978050A3800404038008962FE0C0E80BE4 +:103770008006802A40B324004900544A8CC1EB697A +:1037800097B0D5F2FCE1FC004462D660B406441266 +:10379000C54CF8118386B8084412C538F80CB81126 +:1037A0004412C524F808B80F4412C510F804B8181C +:1037B0004412C4FC49FFFEE2FC804423F7DAA65021 +:1037C0009648C00458108020D503541080DFAE50B6 +:1037D000DD9EFC40840149004AC58401F8272E176C +:1037E000EF2B46008B3B88014413F7F8B6018401A8 +:1037F0004413F7FCAE084413F7CDAE0884283E0707 +:10380000EF2F8404EB06446000C8DD4AEA7CEA85B9 +:103810002E0FEF2F4E0700088EC1EA58840A97B189 +:10382000EA3BCEF78405DD4A840049FFFFC8FCC0AF +:10383000FC20DD475A0802174473F41CA7B8DD4486 +:10384000DD43AE40840A4410009997B0DD45DD5851 +:10385000A600C806A7B897B0EA3EEAEFD5F95A68BD +:1038600002FBFCA0FC21F081DD5D5A08011FF83548 +:103870004412FEF0A608EA945A0850FEF8164400D6 +:103880000051F825F82AA6304472FEF05A0852FD7D +:10389000F001490066A244000053AE3880278047FB +:1038A00084618402DD46FCA14900208EEA94EA93FB +:1038B000F80E4403F04ADD44AE408006A640EA9488 +:1038C0005A1851FEF00149006688EB2EAE30802672 +:1038D000840280468461DD46DD44DD43AE4083FFE3 +:1038E000A6305A0853FFFCA1FC20DD5DEA6AEA8C91 +:1038F0005A080113AFF0EA22A6085A0852FF8401C1 +:10390000EBB7DD44DD43AE40DD47C0FF441000535C +:10391000EA5DAE40FCA08401EBB7AFF0DD47C0FF2D +:10392000EA22EB2EAE08804184618402DD46FCA0D1 +:10393000FC4280C0B0013A100C2022AF8002F70296 +:10394000049F8003DD475A00020980278049806A6E +:103950008402DD468401FCC200030065001300649C +:103960008A015A00082D0003006500130065E6086F +:10397000840CE80EF80812A10000F803149100026C +:10398000001300658046EBD283FFA9D1D5108E28A5 +:103990004E00FFFA12A10000F80314910002001378 +:1039A000006580468E28EBD283FFA9D10003006515 +:1039B0008C019600100300658401FCC28400FCC2E7 +:1039C000FC0000608064002080654C6100270030AE +:1039D0008064844C8081EBC40030806422520000FB +:1039E0008081EBC480C1A0E2004080644262087321 +:1039F00000208064A1318C419690102080640020CA +:103A000080645A28080B8440102080640020806560 +:103A10008E48969010208065AD40A901A8C2FC8018 +:103A20003C1DFB7C3C1DFB7C00300064844C42014F +:103A30008873501087A3222000004400004BEBD570 +:103A400080013C1C0390E201E804EBE98401DD9E67 +:103A50008400DD9EFC023C6DFB95EB8DC0469630EC +:103A60009E43E631E806DD56A648C9035A080B0511 +:103A70008400EBB8D53A2E500E452E000E44D823C4 +:103A8000EB9F97B03C0DFB785A0003083C03F6709F +:103A90008C0196013C0BF6705A68020E5A10010C0C +:103AA0003C03F6705A0001F084003C0BF670840071 +:103AB0003C0FFB78840084203C0BF6703C1FFB78A5 +:103AC000EBB8D5134402E2B049FFFFACC0DAB00155 +:103AD0004412E2B049FFFF768402F102F203223F72 +:103AE0008002EACA3C0FFB78FC824403F7C9A64077 +:103AF000C1038420AE40DD9EFC01DD5D5A0001491A +:103B0000EB843C0C0073D0043C0C0074D841EAA454 +:103B1000EA5C8C019600B081503F800549FFFBD2E2 +:103B2000EA5C000F80040460800849FFFD0D001F5F +:103B3000800597AFC11CEAA4EA5C8C029600EBAB4F +:103B4000EB1649FFFBBF000F8006EA5C49FFFCFC57 +:103B5000C80AEAA4E206E807EB25C80584013E0787 +:103B6000EC71D51A84003E07EC71D516C80AEAA498 +:103B7000E206E8072E07EC86C8048401EB80D50C2A +:103B8000840AEA3B8400EB803E07EC45D5058400BF +:103B9000EB803E07EC45FC81EB9F5A18010644126E +:103BA000C24CF804DD9E4412C1DC38008101500093 +:103BB0007F5BEAF283FFDD9EFC40DD4480C0DD4395 +:103BC000AE40EA76A608C8FF2E37F02B44A2C1DC2F +:103BD000440000A5947150737FA04492C24C5A389F +:103BE0000115882A8041380519098402DD46EA5307 +:103BF000F814380499015A08A5FEF81B4412C24C67 +:103C000038051909EB75FCC08829804138049909E9 +:103C100084618402DD46EA53DD43DD44AE4097F81B +:103C200044038D44AFC083FF380519015A08A5FE2F +:103C300050037FB0960044138D44AE08840083FF88 +:103C40004412C1DCEB7538049909FCC0FC002E2736 +:103C5000F0AD102004302E27F0AC1020042E2E27BB +:103C6000F0AB1020042F2E27F0AA1020042D2E27B1 +:103C7000F0A9102004582E27F0A8102004592E2750 +:103C8000F0A71020045A2E27F0A61020045B2E2740 +:103C9000F0A5102000A52E27F0A4102000AB2E27A1 +:103CA000F0A31020009A0040000950300401844025 +:103CB0004452C564E244E807386288001861800114 +:103CC0008C41D5F92E27F092102000A42E27F091D8 +:103CD000AE888420101000B7DD52EA74FC80FC200E +:103CE0008400441000C1DD45EA67C8038407EABCCC +:103CF000DD52007000510060005280278401DD45D4 +:103D00005A780213EBD7EAB7DD523C7FFB4800003C +:103D10000053C8038400D53C5A00013B5A000239C5 +:103D20005A0803FAD5355A7803378402EA7AEBD772 +:103D3000EAB7DD520010005300000054968C421088 +:103D4000840BC914CA0AC8038404D5225A08010482 +:103D50008406D51E8408D51CC8038405D5195A08C5 +:103D600001048407D5158409D513CA0AC803840A37 +:103D7000D50F5A080104840CD50B840ED509C8034D +:103D8000840BD5065A080104840DD502840F3C0F1C +:103D9000FB5BD5175A78041684003E07EC673E0794 +:103DA000EF942E000E4DEAEC3C0C0396EAC13C0C5D +:103DB0000397EB1BDD41C82E8401EA7A8426D528BF +:103DC0005A60FF1D84013E07EF94EA2D3E000E4D20 +:103DD0003C0C03943C0E03963C0C03953C0E03975D +:103DE000400310095A000F03EAC1979F5A600F045D +:103DF0003C6E0395841FEAECD50484003E07EF94E3 +:103E000084013E07EC67DD41C8058401842549FF34 +:103E1000F974FCA0FC0180C08400EA26DD41C813CF +:103E20003E67EC564412C126804184618402DD461F +:103E300084014412C126EAA08060DD46EA67005F83 +:103E40008007D8F1FC81FC00DD41C010EA675A0010 +:103E50000305EA675A080AFF84004412C126EABC37 +:103E6000804184618402DD46FC80840A49FFFFD4DE +:103E7000FC80FC00DD41C80AEA675A08080484098E +:103E8000D504EA67C8038407EABCFC80FC00EB6346 +:103E900084203C0FFC2E10100050EA74EB701010C0 +:103EA00000531010006010100061FC80FC00DD4128 +:103EB000C825EA56001080F25A180121EA28EA3D86 +:103EC000AE883C2DFC2E001100F2C902D500441230 +:103ED000FEF3A64896485A10040C5A10030A5A10CA +:103EE00006085A100A065A1009045A180B083E17F9 +:103EF000EF33100100F2100100F38401FC802E0763 +:103F0000EF3DC80DEA563E07EF3F00208051EBEC35 +:103F1000EB7184013E27EF3C3E07EF3DDD9EFC0048 +:103F20005A0806048401D5045A08070684003E078F +:103F3000EC2DD51C5A080D0784003E07EC2D84217A +:103F4000D5075A080E0B84013E07EC2D84203E173E +:103F5000EC723E07EC5FD50A5A0810048401D504C0 +:103F60005A08110584003E07EC2AFC80FC002E074D +:103F7000EF3EC82F2E07EF3C5A0810053C0C024FAD +:103F8000D50A5A0811053C0C0249D5055A081207F2 +:103F90003C0C024B441320D0EA4FEA4EDD52C903D9 +:103FA000EBD0D503441FFFA1EA74EB94A6485A183E +:103FB0000305441FFFB1D503441FFFB0EB70DD4084 +:103FC000A6015A08040584013E07EC7E8401EBEC4F +:103FD000DD52EAA15A08BB192E07EF3FE614E806A6 +:103FE0002E07EF3FE60AE910D50DDD475A0802FA21 +:103FF000EA568400EB71100080523E07EF3FEBEC75 +:10400000D503DD47C0F6FC80FC408120DD402E2733 +:10401000EF2CA601E64180E13EF7EF2CEA6A5A0850 +:1040200003498408441000B1DD45EA3AAE3044A3A8 +:104030008D4084C9DD56A608C8123C2DFB485A287D +:1040400001FCEA2A5A0806F93C6FFB6D2E07EF2C9B +:10405000C0F33E27EC9AEBF1EBF7D5ED8408441062 +:1040600000B2DD45DD41C80A2E07EF2CC8128401DD +:10407000EA37DD4FA600EBF7D50CDD44DD43AE405B +:104080002E17EC25EA2A5A0006F15A1801FDD5ED43 +:104090008408441000B3DD45DD5A5A080206EB0FD0 +:1040A000C00349FFFED28408441000B4DD45D508A2 +:1040B000EA3AAE30DD56A608C803EA3ED5FD8408CC +:1040C000441000B5DD452E07EF3C3C2DFC2E8E1034 +:1040D000E60310910053E80449FFFF4AD541CF049D +:1040E000440FFFA0D503440FFFA110010051DD4F85 +:1040F000A6005A080305440FFFB1D503440FFFB0D3 +:1041000010010052DD40A6015A08040584013E0753 +:10411000EC7E441000B68408DD45EA3DEA28DD5215 +:10412000EAA15A00BB04AE88D5FB8408441000B74E +:10413000DD45DD41C0068402EA9A80418060DD46AB +:104140008400EA5E8408441000B8DD45EB81DD524E +:104150008420EA74EB708408441000B9DD45FCC08B +:10416000EA5610008060DD9EDD5200000060DD9E9A +:10417000EA56100080613C1DFA711000803EDD9E01 +:10418000FC0080C049FFFECD84015A680305490048 +:104190004D2D800650137FF3E622E9035A68021B77 +:1041A0008401EAD2DD40A7815A6803048402D51253 +:1041B0005A680A098429AE418420DD55DD40AF816B +:1041C000D5038420DD55DD475A0802F2DD548443CF +:1041D000AE89FC804000040E9604DD9EFC02DD41A9 +:1041E000C020DD52441FFFAAEA74DD5200100051C6 +:1041F0005A18AA0AEBBAEA3B840744100031DD459D +:10420000EAEFD5F4B041500000518441F083EBF95E +:10421000A8093A108C004402E2B049FFFB8BD50C90 +:10422000DD52EAA1C809EBBAEA3B84074410003129 +:10423000DD45EAEFD5F68407EA9DDD45DD52EAA1CA +:104240005A00DD048401D5028403FC825A08031F4E +:10425000000080A23E07F0B5000080A13E07F0B448 +:104260000000809C3E07F0B30000809A3E07F0B249 +:1042700084418400100080A2100080A11000809C66 +:104280001000809A102080B6D5165A0804172E0701 +:10429000F0B5100080A22E07F0B4100080A12E0708 +:1042A000F0B31000809C2E07F0B21000809A8400BA +:1042B000100080B6EA56EB71DD9EFC2080615A0842 +:1042C000016F000084303E07F0AD0000842E3E07F1 +:1042D000F0AC0000842F3E07F0AB0000842D3E07B9 +:1042E000F0AA000084583E07F0A9000084593E0758 +:1042F000F0A80000845A3E07F0A70000845B3E0748 +:10430000F0A6000080A53E07F0A5000080AB3E07A8 +:10431000F0A4504084010000809A3E07F0A30050B2 +:104320008009840080244462C564E205E8070870BF +:104330008001387300088C01D5F9000180A43E0784 +:10434000F092A61084213E07F09184001011843071 +:104350001011842E1011842F1001842D1001845807 +:10436000100184591001845A1011845B100180A53A +:10437000100180AB1001809A842A8400E205E805D0 +:10438000181200018C01D5FB8421101180B7EA5668 +:104390008400100180A4AE10EB71FCA05A08020644 +:1043A0008022800349FFFC54FCA09200FC01840A97 +:1043B000EA265A1001065A1002094800007CDD5214 +:1043C0008420EA744800007B3C6DFC2E0003005200 +:1043D0008E01E6094EF2006F44F041E4EB0C40F030 +:1043E0003C00DD0F120020002E006800CE0074009B +:1043F0007E009600BE008401EB3F4422B54049FF99 +:10440000FF5ED529440200004412B54049FFFC205C +:10441000D5222E072BD23E07F0B52E072BD13E0713 +:10442000F0B4EA2B3E07F0B3EBDD3E07F0B2842197 +:1044300084003E072BD23E072BD13E072BCC3E07F4 +:104440002BCA3E172BE610030051D5098404EB3F1D +:1044500049FFFEFE8400D5038400EB571003005291 +:10446000D52D8401EB5784008040DD54EA43EA8D6A +:104470003C079619490056ADD50A8403EB578401D1 +:10448000EA7AEB3F00030053490055EDDD4FA600EB +:10449000EB3F4422C12FEB163C4DFC2E49005657F2 +:1044A000D50D440201028026490052528401EA26B9 +:1044B000D5058401EA268402AE10EB255A080A0AC3 +:1044C00049FFFE8EDD56EA268401AE08DD59AE08AE +:1044D000EB25FC815A0001075A080309B401EA5789 +:1044E000D503B401EA82B601DD9E8402AE10DD9EE2 +:1044F000FC00DD52EAA15A08040CDD47C809DD4181 +:10450000C00484013E07F090DD528420EA74FC80F0 +:10451000FC409F01E68F4EF2008880C2800144F08B +:10452000432C3847910140F23C00DD0F24002E005F +:1045300038009600BC00C200FA00D400E000000180 +:104540001E00EE00FA00FA00F400FA0148000071C3 +:1045500084003E07EF3D8406D56B84003E07EF3DA7 +:104560008407D566EA7CEA85F82580C05A000204F3 +:10457000EA58D5FB8401F823490014A53C0E0450E9 +:10458000490014AA3C0E0451490014B73E001149D9 +:10459000490014BD3E001148490014B43E00114AC0 +:1045A00084214402E610490040508006F808EA6A77 +:1045B000EA8C490014B0C003AFF0D5FC490014BE2A +:1045C000D512842EAE418426AE40EA568440102097 +:1045D00080508421DD558420840280418461808163 +:1045E00080A1DD538401D5248401AE10D51584004B +:1045F00044100066DD458401AE30DD47840ED518D9 +:104600008401AE108401F8068402D5128401AE1034 +:10461000840049004AF5840DD50B8400EB34D5E3C2 +:1046200049FFFF68D5E08402AE18D5DDFA00FCC072 +:10463000920092005A0007044800007CE62A4EF2DD +:1046400000BCFC0080C344F04450EB18EA8BDD0F43 +:104650000A2E4CD8D8D8D8BA7094A660440FFF80E0 +:10466000FE0FAE20B40396976600070040200904B1 +:10467000B643440000B0DD42B4069208D545A621F9 +:104680009697EA45AE21B403EBDF40200964B643B8 +:10469000440000B1DD42B406920BD536A621968FB8 +:1046A000EA81AE21B423440F3FFFFE0E402009C42F +:1046B000B643440000B2DD42B406920E960FD533E5 +:1046C000A621968FEA57AE21B423460FFC7FEAB3AA +:1046D000FE0E40200A64B643440000B8DD42B40632 +:1046E0009213D512A621968FEAA8AE21B423460FC5 +:1046F000E3FFEAB3FE0E40200AC4B643440000B90B +:10470000DD42B40692169617D50EB4039694420075 +:10471000480940200A44B643440000B7DD42B406CD +:104720004200480BDD42FC80843BEAB5AE40FC8091 +:104730005A080B368E21E62CE83F44F04548EB182A +:1047400040F0BC004A003C000C12181E242A3036EF +:104750006E3C444CB403EA81D52DB403EA46D52A15 +:10476000B403EA45D527B403EB26D524B403EAA85D +:10477000D521B403EB11D51EB403EA86D51BB403CF +:10478000EAEBD518B403EA9FEA79D514B403EA9F9B +:10479000EBDED510B40358000060D50C5A080510A4 +:1047A0005A1001075A180309B403EA57D503B40392 +:1047B000EA82B603DD9E843BEAB5AE40DD9EFC4254 +:1047C000F282F081F3834422FE50A610814144120C +:1047D000FE51A790A7C89204979F97F85A0001042A +:1047E0004800006C9E31E603E90E5A600503F80E9E +:1047F000DD52000000605A00A1072E07EFBF5A08E3 +:104800000103F804EAFD5A08AA044800006D4E426C +:10481000006BDD41C00ADD40A601EB0D5A0804061D +:1048200044000088DD42FCC24402C0F0EB32EBEAF7 +:10483000EB89EA7E490019025A6005048400EBE521 +:10484000EA76EA36EA33A6085A080104AED0D5FC67 +:10485000DD41C024F81A44000082DD422E1FEF31F2 +:104860002E0FEF304423F41C4E170006A6D05A3802 +:1048700002FDD5034E06FFFCEA9A8041846684025D +:10488000DD4644000083DD42DD44DD43AE4083FF6E +:10489000EA22A6085A08E1FFD50C44000084DD4254 +:1048A000EA22440FFFE1AE08804184028461DD46C4 +:1048B000FD03F201EB73FCC25A000B065410000D0D +:1048C0005A1805124492FE5084201014800080472C +:1048D0008026F302F40349FFFEAFEAD55A00FB0439 +:1048E0008401EB48FCC24413F04AEA28DD52EAA1F5 +:1048F0005A00BB04AE88D5FBDD9EFC0080C0DD52B3 +:10490000EAA15A08BB224900438ADD520010005038 +:10491000C1035A18FB102E17EF29C9042E17EF28D0 +:10492000C1108400EB97EB428400EB348401EAD29F +:10493000D517CE08EB6E5A08A00A44030FA0D50B7A +:10494000C609EBD0D50CC6F7D50B5A08A104EBD499 +:10495000D502EAB4EAAAEA4FEBD0DD52EA74FC8051 +:10496000FC00E60AE86244F04770EA75EA31DD0FC0 +:104970000A40B8B8B8B8B8B864A2C903FA18D504E0 +:104980005A18010CFA133C0BF4DCEB0E3C0BF4DA76 +:10499000840F3C0BF4DBD5495A180204FA0ED5F407 +:1049A0005A180304FA09D5F05A180440FA04D5EC51 +:1049B0008401C1045A18010684023E07EF20D53550 +:1049C00084005A1002FC5A1003045A18042F3E1790 +:1049D000EF20D52BC903FA0ED5045A180107EB0EA8 +:1049E0003C0BF4D9FA13D5135A180207EA933C0B7F +:1049F000F4D9FA09D50C5A180304EAC9D5055A188E +:104A00000415440000823C0BF4D9FA043C0BF4D8A2 +:104A1000D50CE6238400E90784015A1003055A18CF +:104A2000040584023C0BF791FC809200FC4080C19D +:104A30008420AE40B40280E24200640B81245A0814 +:104A40000106B40642006408B606B4074200640BCF +:104A5000C805B40642006409B606B407EA925A08CB +:104A60000107B406EA81B6068006EBBFB407EA92F6 +:104A7000C80AB406EA46B606490015D03E07EFA1BB +:104A80008006EBBFB40796045A080105B406EA4550 +:104A9000B606B4079604C804B406EB26B606B407F7 +:104AA000EA645A080105B406EA57B606B407EA6490 +:104AB000C804B406EA82B606B407EA9C5A0801059F +:104AC000B406EAA8B606B407EA9CC804B406EB111B +:104AD000B606B407EAE45A080105B406EA86B60643 +:104AE000B407EAE4C804B406EAEBB606B4079205D4 +:104AF000960F5A080106B406EA9FEA79B606B4078B +:104B00009205960F5A080206B406EA9FEBDEB60637 +:104B1000B4079205960F5A080306B40658000060C1 +:104B2000B606EAD592075A080111EAD59637EA5235 +:104B3000B427840092289657F8BCB4075410070095 +:104B4000B40666000700F83EEA7796045A08011199 +:104B5000EBCF6610800110148001B427922B96577A +:104B6000F8A8B40754103800B406EBDFF82BEA7746 +:104B7000EA645A080112EA77EA82EA4AB42784080A +:104B800092339657F896B42746000380FE46B44603 +:104B9000460FFC7FF81500048001EA9C5A080116B4 +:104BA000EA77EB11EA4AB427840992369657F881DE +:104BB000B42746001C00FE46B446460FE3FFEAB3A6 +:104BC000FE16FE0FB60683FFEA77EA925A08010F37 +:104BD000EA77EA46EA4AB407B4274400C000B4467C +:104BE000FE46440F3FFF4E00FFEDFCC0E60A4EF2CA +:104BF000007CFC0080C244F04A00EA75EA31DD0F17 +:104C00000A2E50E0E0E0E0C27096B40296576600CB +:104C1000070040100504B622B4228400922896575B +:104C2000F84844000070DD42B4069208D549B40249 +:104C30009657EBDF40100564B622B4228401922B14 +:104C40009657F83744000071DD42B406920BD53810 +:104C5000B442440F3FFFFE16964F401005C4B626DF +:104C6000B40644000072DD42B406920E960FD537AA +:104C7000B442460FFC7FEAB3FE16964F401006641E +:104C8000B626B426840892339657F813EBBADD4261 +:104C9000B4069213D515B442460FE3FFEAB3FE16ED +:104CA000964F401006C4B626B4268409923696570D +:104CB00049FFFE5844000079DD42B406921696176B +:104CC000D50EB402964C4200480940100644B62264 +:104CD00044000077DD42B4064200480BDD42FC8010 +:104CE0008402AE18FC808402AE18DD9EFC00FA0E31 +:104CF0003C0BF4DCEB0E3C0BF4DA44100050840F58 +:104D00003C0BF4DB3C1BF4D98400FA293C0BF791F3 +:104D10003C1BF4D83E07EF20FC8092008E01E60C8D +:104D2000E841FC0080C144F04B30EA75EA31DD0F08 +:104D30000C14282E343A40466C4C5A62B401EA8175 +:104D4000B601D508B401EA46B601490014673E072A +:104D5000EFA18006EBBFFC80B401EA45D51EB4018B +:104D6000EB26D51BB401EAA8D518B401EB11D51573 +:104D7000B401EA86D512B401EAEBD50FB401EA9F7B +:104D8000EA79B60149FFFFB4FC80B401EA9FEBDE8B +:104D9000D504B40158000060B606FC808402AE1051 +:104DA000FC808402AE10DD9E92009200FC62A60997 +:104DB0008121F281814381845A08040584003E07E1 +:104DC000EC7EDD41C007EAFD5A08AA052E07EDE496 +:104DD000D504DD52000000504E0201E45A08FB04E5 +:104DE000480001E0F001EA7E490016288400EB96B5 +:104DF000DD41C00CEAFD5A08AA0A2E67EDE42EB781 +:104E0000EDE540731009979FD509DD520060005011 +:104E100000B0005140731009979F8401EA47840055 +:104E2000EB52EBCF5A1804182E17EF32C1043E078D +:104E3000EF32D5262E07EC365A080103EB518420B9 +:104E40008009DD558401EA23DD44DD43AE40EA7884 +:104E5000C0FFD516DD41C009EAFD5A085507EA9A98 +:104E6000840280418466DD46DD58A6005A000209AE +:104E70003C0DFB5DA6405A1802048420AE402E076C +:104E8000ECA28C013E07ECA240031C848EE1E6EC10 +:104E90003E07ECA14EF2015B44F04CA838779D012F +:104EA00040F3BC004A003C0018005000BC01D40193 +:104EB0003A0248026402A202A202A2027402900212 +:104EC0004402C0F0EB32EBEAF001EA7E490015B68D +:104ED0008006802B8049EB738400EA475A600F04F8 +:104EE000480000FFDD5284CC000000505A00FB0453 +:104EF00048000140480000F58EC18401E6C63E0727 +:104F0000EC8D4EF200AA44F04D143867990140F33D +:104F10003C00DD0F0C0034005E002001260164001F +:104F20008400EA478401EAB8FA318404DD45EB0FD6 +:104F3000C8078404FA3ADD4584C4F814D5578404BC +:104F4000FA3BDD45FAC4D5528400EA478401EAB849 +:104F5000FA318404DD45EB0FC8088404FA3ADD45D4 +:104F600084C549FFF7CED5428404FA3BDD45FAC536 +:104F7000D53DEAB884C2F88CDD41EA56C03D8401D3 +:104F8000EAB80000805284C0106F800F5A08AA2728 +:104F9000490040458401EB34DD52001000530020ED +:104FA0000054440FFFA0FE0F5A28010FEB424400AB +:104FB000988C3E67EF29F80DDD52441FFFBB3E671A +:104FC000EF24EA74D508EB97440062383E67EF2877 +:104FD0004900409ADD528420EB70EB6EC806EAE18E +:104FE00084C1C004FAD0D502FAC9EAAC4E0300C2AB +:104FF000841FEA2CF84D2E27EF28C202EA47000052 +:1050000080525A08AA150020805484005A28010BA7 +:1050100000308053442FFFA0FE9FEA473E27EF2831 +:10502000D502EB42EB97840010008052EAE14E0378 +:1050300000A0D556EA96EA5BD5538400EA56EA47C3 +:105040008401EAB80000805500108054EBAE3C0BA0 +:10505000F65FFAC2F81D8404FA3FDD458400EB9642 +:10506000480000728402EAFF80268401502F800FDE +:1050700049FFF99E80C08405EAFFF80A84002E17D4 +:10508000EC25EA478401EB965A18010584C94800CB +:1050900000713E07EC25EAFF5A68010D84004410B8 +:1050A0000041DD45DD5A3C0FFB733E67EC7AEB9126 +:1050B000D5038402EA47000F800F5A0802E9DD5247 +:1050C00084C0106000513E67EC8D3E67EC25DD47E3 +:1050D0005A0002053E67ECAAD5038405EAFF84C1A5 +:1050E000D5488006802A502F800F49FFF9F5D51D3D +:1050F000840044100060DD45800680294422C15DA3 +:10510000503F800F49FFFA069780D5338006802BE9 +:10511000804A503F800F49FFFD6BD5078006802AEB +:10512000502F800F49FFFDFC000F800F5A0002D95D +:10513000B40AB60C84CBD51D5A68010649FFF5D1D7 +:10514000FAC3D5178402EA47D5CB840284C1EA4763 +:105150003E67EC6FDD41C0073E67EC6F840F441083 +:1051600000FBD504840F441000EBDD45D5B9FAD01F +:10517000000F800F84205A0001055A080206843B64 +:10518000DD52101000502E07EC8DC8094402C0F00B +:10519000EB32EBEAF001EA7E490014758006D51384 +:1051A000EB6EC803EAE1C0068400EB97EB42840093 +:1051B000EB34F001EA7E49001466EA3AEAF384002F +:1051C000EAB88401FCE23C0FFC30DD9EFC67F08D08 +:1051D00081A18182C407C30CFA10846684A180C0B7 +:1051E000D510C30BEAEE840180A384C4D50AFA70FB +:1051F000840180A384C6D505EB01846484A180C0AA +:1052000040E300139781F8274082801397D9F08AF2 +:105210004492E9E42E07E0AA44B2E98044A2EA48B5 +:10522000F08B442255B88400F30DF81F842BF8331B +:105230008400806C8040381481114E170007EBED1C +:10524000EB67976BAD58D502AC988C019641E22E76 +:105250008C62E9F23C07F679F0893C07F67883FF27 +:10526000F08A2E07E0AAF08B14CF8000149F8001F3 +:1052700014BF800214AF800314DF800414EF800594 +:10528000148F8006F787F68883FF8400842D4422DC +:1052900055B8F30D808C44527200F8F9FCE7FC011C +:1052A000F081440004733C0BF679440FFB8C3C0BFB +:1052B000F6782E07E0A93E07ECA48C0180C13E07DA +:1052C000ECA5C92944029ECAF817F20180668481C0 +:1052D000F80744029ECAF81084618083F2014402F8 +:1052E0009ECAEBE0F840F806F20180668481F80A75 +:1052F000F83A4402A1EA844180208062490014A463 +:1053000084614402A1EA4412A82A83FFF201808347 +:10531000F82AFC815A18012A4402A05AF81884601D +:105320008083F806F8204402A05AF81184804402D1 +:10533000A05A4412A69AF20183FF8066F814F80579 +:1053400084608083F809F80F4402A37A80208046A5 +:105350008066490014794402A37AEBCEF20183FF00 +:105360008066848049FFFF34FC8138110511880173 +:10537000E003E9038400DD9E44008000DD9E3C1DC7 +:10538000FC302E07EC66A68EC80CEA2B5A08010AE0 +:105390009411AE0AA6098E01F8079401F80BD511F5 +:1053A000A609AE8A8E01FE148442400008168E01C2 +:1053B00083FF96033C0BF679FE033C0BF67883FFE4 +:1053C000A6093E07ECA48C013E07ECA5DD9EFC6718 +:1053D0002E672B33F08D81C181022E072B32CB0536 +:1053E000802080408401D5048026844180C097C1FC +:1053F000F82D40B080134091001344D2E98044C29C +:10540000EA483C0DFC3097B144A2E9E4B71FEB9B9E +:1054100014DF800214CF8003F827F833842BF83789 +:1054200084008068820D808C80409641E22BE80EDB +:10543000381501114E170007EBEDEB67976BAD5870 +:10544000D502AC988C018C62D5F13C07F679F089D5 +:105450003C07F678F08A83FF3C0DFC30F483B71FDD +:10546000EB9B150F800214EF800414BF8005F786B4 +:10547000F687149F8008A602F08B840083FF842D9A +:10548000442255B8F30D808880A083FF490036A0E0 +:10549000FCE7FC0180C0F18149FFFF73A036A075D5 +:1054A000F201846049FFFF95FC813C0FFBA9DD9E62 +:1054B0003C0FFBA7DD9E3C0FFBA8DD9EFC418463F7 +:1054C00080C080E2501F8006FA50B400EBA8EA5971 +:1054D000B607F80FA47044920000F8101013801063 +:1054E000B406501F8006FA508464EBA8EA59A83924 +:1054F00049003816A4703C3DFBA78A0100148002C5 +:1055000092014000043783FF10138011B406A0728B +:10551000A0B60031800C8481490013E9FCC1FC6510 +:1055200080E1842080C4121F800D5A480405049035 +:105530000006D5030490000502310439A613854006 +:1055400050BF801CA7528083B61F802980098445E4 +:10555000EB9B14AF800214AF800314BF800449009A +:10556000360F020F800EAC3802058001AC39501F97 +:10557000801A8009804A8463EBA8020F800D5A6864 +:1055800004053C0BF674D5055A6805043C0BF66F10 +:10559000AC3B501F801A800984408464EBA8020F42 +:1055A000800D5A6804053C0BF660D5055A68050461 +:1055B0003C0BF65CAC3A5A60040E84003E07EC618A +:1055C000221380033C0399D0E020E80484013E07C5 +:1055D000EC61FCE5FC0180C1F3818460B61F3E37BD +:1055E000EC6149FFFF6DB41F8026F2018460848462 +:1055F00049FFFF972E07EC2A5A08010722130003E0 +:10560000440395B4AC40FC81B460B42080A0927097 +:1056100096098440986AB4819290E264E804B421C7 +:10562000806496098C445A2820F7DD9EFC2080E196 +:1056300080C049FFFFEBE6E8E84E44F05448387775 +:105640009C0040F3BC00DD0F081224364C566678EF +:10565000961F3C0BF8688400D53F3C13F86894040F +:105660009600FE0F3C0BF8688400D5363C13F868B2 +:10567000961F400081043C0BF8688400D52D3C1334 +:10568000F868400081849643EACD3C1BF868AC4042 +:105690008401D5225410000FEB748400D51D94446E +:1056A0003C03F8679648FE47EB748400D515541008 +:1056B000000F3C03F86740100504EB748400D50C20 +:1056C0003C13F86740108184964BEACCEB74AC40F5 +:1056D0008402D5028400842FB626FCA0C910402085 +:1056E000380954003FFFC00696C4882396489201AB +:1056F000D5FB964FFE555C008001DD9E8401DD9E4A +:105700005450000C848090A2E28510F08000541068 +:105710000030540000C090249006E2814002000650 +:1057200010F10000AE18DD9EFC0180C1B42380A002 +:10573000C94F847F3E37F0CA3E17F0C9C41AC2155C +:10574000402020095401000C9002E2205401000383 +:10575000EBB22E27F0C840003C244C2000503E17EE +:10576000F0C73E07F0C8D561122300254800009C11 +:10577000541000032E07F0C84C00C013EB7BE60268 +:10578000E8038C01EAEDEB7BE602E903101300402D +:10579000EA55EAC0E8098400EAEDEB9AD5053E47F0 +:1057A000F0C73E17F0C85452BFFF44000FFF92A24B +:1057B000D00A0213002684034250807390A2125331 +:1057C0000025D50312530025EBEEEBD9F8445A100F +:1057D0000403F8414E42007E920896015410000CDA +:1057E0009022C23B8440960F40110406E2404007DD +:1057F00084242E17F0C84C1040152E17F0C7E6244D +:10580000E8048C213E17F0C72E17F0C7E624E90202 +:10581000EB9AEA55EAC0E8098400EAEDEB9AD5056F +:105820003E27F0C73E07F0C8EBEEEBD98400EB88CB +:10583000501F80058005EBABEB16F839000F800692 +:10584000001F8007940140000440001F800588016C +:105850003E07F0C648000080960F40110406E24063 +:10586000400784242E17F0CA4C1040172E17F0C999 +:10587000E622E8048C213E17F0C92E17F0C9E62273 +:10588000E802841FEB46EA55EAC0E80A8400EBE22E +:10589000841FEB46D5053E27F0C93E07F0CA8400B9 +:1058A000EB888005501F8005EBABEB1649FFFF2A04 +:1058B000EB25001F8006940540000480001F800532 +:1058C000400004602E17F0C6FE0F10030059D543A8 +:1058D000541000032E07F0C84C00C013EB7BE60207 +:1058E000E8038C01EAEDEB7BE602E90310130040CC +:1058F000EA55EAC0E8098400EAEDEB9AD5053E478F +:10590000F0C73E17F0C8540280FC92021003005901 +:10591000CA2292A82E07F0CA974F4C02C0192E0730 +:10592000F0C9E602E8038C01EBE22E07F0C9E602BB +:10593000E90410530041D503841FEB46EA55EAC041 +:10594000E80A8400EBE2841FEB46D5053E27F0C948 +:105950003E57F0CAFC81FC6080C181425A000105BB +:105960005A000245F80AEACDA440EBBD964BC003AD +:105970005A0805068400EBA5480000A9B402EA8293 +:105980004E0300A540B08013540580039FC35C7391 +:1059900080013E77F0CC3E7010E2CF0F2E27F0CD85 +:1059A000E444E80D2E57F0CBD808EA55EAC0E905E3 +:1059B0008C413E27F0CDD5038400EBA554908003A5 +:1059C000800B80273E97F0CBF841CF692E17F0CDA2 +:1059D0004E93000AE422E8633C1DFB6E5CF088FDF8 +:1059E000E85ED542E424E9F9D55AEACCA440EBBDFF +:1059F000964BC0C15A0005C0EB30E60AE967B40215 +:105A0000EA82C86440B08013540580039FC35C736E +:105A100080013E77F0CC3E7010E2CF102E27F0CD03 +:105A2000E444E80E2E57F0CBD809EA555CF003E9C0 +:105A3000E9058C413E27F0CDD5038400EBA55490B9 +:105A40008003800B80273E97F0CB49FFFE49CF3281 +:105A50002E17F0CD4E930021E422E82C3C1DFB6E66 +:105A60005CF088FDE82784013E07F0CC8400EB88D9 +:105A7000EBBD5A00042C00030045100300462E071E +:105A8000F0CCEBFBC823EBEEC8048401EB88EBD928 +:105A90008404EBA5D51BE424E9E2D50CC0EA84001C +:105AA0001203001F8026800B8441806A8087F80BD8 +:105AB000D5E0C0DF84001203001F8026800B8440E5 +:105AC000806A808749FFFE32D5D4FCE0DD9EDD9EF2 +:105AD0004422AB4AB6404432AC764422ABAEA881F5 +:105AE000A8C94422AC128460B641ACC4ACC5ACCCED +:105AF000ACCD8420B4A080619929ACE0990A8C22B5 +:105B0000ACE05A1840FBA101840080204432AC76FE +:105B100098A0AC5098838C02AC505A0864FBDD9E70 +:105B2000FC21A4C0842096DB121F8003848084AFF4 +:105B3000446001EA96615CF08064E80940208409D1 +:105B4000A5C0A44052210031964BD509A5C05022D2 +:105B50007F9CA4409041964B52210031FEAC96911F +:105B6000FE54401098368827964BAC40A440964B84 +:105B7000E061E803A4C096DB8C818C025A48C8DC43 +:105B8000123F8003EA59441007D096034000800773 +:105B9000FCA1C80E3E07EC62A40EC80684013E07B5 +:105BA000EC628400DD9E5A001FFB8401DD9E8400B0 +:105BB0003E07EC24A40FC80684013E07EC248400B1 +:105BC000DD9E5A0831F4D5F9FC442E40111880208E +:105BD00080022E27E09AE282E8043C57F046D50383 +:105BE0003C57F048E282125F8000E8052E47E094BF +:105BF0009723D5042E47E09597238440124F8001C8 +:105C0000EBF9C8065090800CB4E1FB90D50650909B +:105C1000800EA1C945000032225480004E93000737 +:105C20009CA940238820A490F80C4647FFFF5042CF +:105C30000FFF50287FFF8885DA0740439020A4A0FB +:105C40009693EBF9D5179521411390008C848887A2 +:105C500002688000A4A097B39693E046E807024844 +:105C600080009723124F8002D505A5209723124F5D +:105C70008002952998BCA590022F80028AC297B312 +:105C8000126F80035A30010448000065EA59EAA9FE +:105C90009603964BE02050287FFFE81CE0A2E8071F +:105CA0008C828887A420F805F808AC20F8318EE2B1 +:105CB0009643EADB960383FFFE0CEAF1EAA6403046 +:105CC0007C0AF082F383F002F103960383FFAC3881 +:105CD000D53DEADBE0A296C3EA599643EAFB9783F7 +:105CE0005001FF9CFE0C400018165000006441104B +:105CF0007C0AF084151F8005E80B8C8299BCA430C7 +:105D0000F810F086F187F006F1079603AC30220414 +:105D100080004E07001C407380200203FFFF83FFBA +:105D2000F404F50596034222802440107C0AEBB16E +:105D30004200106984608822EA9EEA40F086F1877A +:105D4000F0068EE29603F107AC3884013E07EC6260 +:105D5000FCC449FFFF20C0212E1011183C07F0524F +:105D6000E635E9088E35E637842AE9054410004611 +:105D7000D5028420022F800388019693221480008C +:105D800044300064FE9C407384209603A478400154 +:105D900000169A089603AC38FCC4FC208480C83AEC +:105DA000A4D610308009847FA90CA90D8381BC8AF8 +:105DB000BC8BAECCAE0D80C045116650B482F83BB2 +:105DC0004E37001CF83F05008004A0CDF845A8CD53 +:105DD000A6CC8CC1A90C97B35A38FF03AE0CA6CD44 +:105DE000E003E902AE0DB4628381BC0B88E3A4F842 +:105DF000BF0AF849BB8ABC8B8C015A0820E1840099 +:105E00004E670007A416B44240010020A400AC086D +:105E1000FCA0A41710008008841FAE0E8400AE0FF3 +:105E20008400A90EA90F8381BC8CBC8D80C0451154 +:105E30006588A11195C18887A4E096DB83FF4E3762 +:105E4000002DA5203838810197234241906883FFB7 +:105E500005008006A0CF8890E2908865886F83FF58 +:105E6000A8CFA6CE8CC1A90E97B35A38FF03AE0EA9 +:105E7000A6CFE003E902AE0FA0D18381BC0D88E379 +:105E8000A4F8BF0C96DB4051FC0A8867E26788855E +:105E9000888F83FFBB8CBC8D8C015A0832CC840068 +:105EA0004E670007A417A09140010020A4005CF0F9 +:105EB00002EFAC09E90584013E001117FCA0840043 +:105EC0003E001117FCA02E4692064E42009FFC6039 +:105ED000814394C940900C000204800080E1960345 +:105EE000422008682EB72B32F8842E672B54EA9E86 +:105EF00084604EA2004BEA40F8494E0200864013EF +:105F0000AC578460969196498003444166D0E20183 +:105F1000E808385200008C01886596D99601D5F8BA +:105F200084008080445166D0E224E9083862900001 +:105F30008C81880696019721D5F82E1004068E01D3 +:105F4000E2614030BC1B2E100407960184804200A1 +:105F500080013C7C020D80A4E203E90D40638C20AB +:105F6000A470964BE081E804A53080A397238C6150 +:105F700096D9D5F302048000405114A044115C3836 +:105F8000960338209400D533EA409603EABF2E07E3 +:105F9000EC5A83FFC039406398572E100404949341 +:105FA0009691E2419C174020BC1B2E1004059601DF +:105FB00097B1420080013C5C020C806A80EAE202F8 +:105FC000E90D40128820A5089723E064E804A4C8DE +:105FD00080E296DB8C419691D5F3022480004063E9 +:105FE00098A0441155F8961338209800422008686C +:105FF00050010032E2028023882F83FF8460EA9EF2 +:10600000EA409603EABFFCE0DD9EFC6380E1221FCC +:106010008028B63F2E172B3380C081C2F382048FB5 +:106020008012229F802600AF80542ED72B322EC79D +:106030002B54F18340B104084E42006B4011379657 +:10604000541E00FFF1814EA2000A80224421640800 +:10605000806438213901F83EF40389660205800026 +:1060600054CE00FF4023B020A450F8ADF8B5AC509A +:10607000B42842103073B628878144B16408F00216 +:10608000E21CE945405670014E550014413770013D +:106090004EA20004F816F820F824F894E020E8094D +:1060A000F828F89A12190000F1014020F001F89C3C +:1060B00040567000E0ADE826413770004EA2001255 +:1060C000401980133825CD0180648006F585153F81 +:1060D0008004F483F86DF505053F8004F40383FF25 +:1060E00041334C200209800083FFF86CE020E80A6D +:1060F000412394200219000083FFF86E121900005A +:10610000F870500E000155C000FFD5BAFCE340D135 +:1061100031B6541680FFF1814EA20009802244213D +:106120006278382139018064F8438966020580006D +:1061300054D680FF4023B420A450F845F84DAC500D +:10614000B42842103473B628878144B16278F002D3 +:10615000E21CE9544046F0014E450019425E3024ED +:106160004EA2000740271401F81CF405F50440076F +:10617000140141230020F824E020E808F82912192E +:106180008000F1014020F001F82FF0034046F000BC +:10619000E080E82F425E30244EA2000F402714001A +:1061A00096518006382589018460F485F58449FF7D +:1061B000FE8CF405F5044127140041234820020910 +:1061C0000000B43F96038A0983FFE020E8124133C0 +:1061D0009020021980008820964B83FF12198000BE +:1061E000F101402E0400B42842100873B62883FF42 +:1061F000504E000155C200FFD5ABFCE3FC68812086 +:10620000EA2F8101F387838585405A0001042EA778 +:10621000E07C3C13F03CF1868420F18EF18FC412B7 +:106220005A0801053C17F041D5033C17F040121FF6 +:10623000801A5A0801053C07F042D5143C07F03F8C +:10624000D5112E07EC625A0001092E07EC245A00E2 +:1062500001053C07F044D5028004120F801A3C0768 +:10626000F043120F801B4E83001F84001281000434 +:10627000A814A8152E772B322E072B555111000884 +:106280005131000C04C10000F0852ED7E09650611A +:10629000001081C7FAB0455000C050BF803844316B +:1062A0006408D51C8400AC158400A816A8172E77A6 +:1062B0002B545111000A5131000E04C100012ED798 +:1062C000E09750610018F78544500032455000C8EF +:1062D00085C150BF803C4431627884001208800040 +:1062E000840080203A030420842082C982018041F6 +:1062F00002F88000020B000040F4BC2002F780008E +:10630000960341278011E1C0E803122880000A0BA0 +:1063100000018C41960340F07C0A8801417004061C +:10632000898F9691802089974C2AFFE4B6068400D5 +:1063300015030001802C80408C0196011A208001F9 +:106340004C02FFFC2E069206026880005A08011BD0 +:1063500040049820A40038119901960342008068F7 +:10636000EA9E8460F48BF58A153F8009151F80082A +:10637000EA409603051F8008053F8009F50AF40BE3 +:10638000D50540049820A4009603F106E001E80535 +:10639000F1078400AC08FCE84E83000C40631C1637 +:1063A000120980000208800040701CF697F8D50A98 +:1063B00040631CD6126980000208800040001CF671 +:1063C00097F8C41402098000C0099E694C00800738 +:1063D0005A0001058EA24C02C0062E07E075EBC1E3 +:1063E000D5082E07E074EBC1D5042E07E076EBC18B +:1063F000EA2F5A080107000F80338C019600EBC189 +:10640000F83B52640001964B960397B00228800037 +:106410008086F84F80AD151F8006F856051F800650 +:1064200002388000CF0440270C00D507F0058E010C +:106430004C70400D4021B801969140048820A40082 +:106440009603E140F82DF83EFCE84051B8014021A8 +:10645000B8004044942040348820A420A4589603D7 +:10646000964BE02040050013E816A460A4988A2209 +:106470009649E201E82B003F8033021F801A020F89 +:10648000801B83FF964B9603F181F08296A9F81347 +:10649000F819FCE8A458A4E08A239649E201E8161A +:1064A000003F8033021F801A020F801B964B960319 +:1064B000F181F082B77F15CF80038009802C83FFA4 +:1064C0009691808680AD49FFFDA2FCE8FC4080E00B +:1064D0008400AE388400AC088121AC108024A01D5B +:1064E000814280C44420003280678480EBE684A02F +:1064F000A638E2A0E819A031946938001501D81235 +:10650000A0320224800038001501E240E802EABF10 +:10651000A0333800040102150000E220E803120550 +:1065200000008CA1D5E6FCC03C23F7C0964150008A +:106530008064EBF89601E8242E27EF7B5A280106A9 +:106540005010805A9609DD9E5A2002062E37EF829F +:106550005A380206501080509609DD9E5A200304D6 +:106560005A380306501080469609DD9E8E44E6494F +:10657000E9048E64E669E804501080329609DD9ED5 +:106580003C1395FDAC40AC442E172BCC5A18010C93 +:10659000EB94A6485A1803082E172C52AC402E171D +:1065A0002C52AC442E172BE35A1801183C1DFB51FA +:1065B000C9142E272BCC5A280111FC0080C0DD4FB6 +:1065C000A6005A080306840AF804AC30FC80800157 +:1065D00049FFFFACAC30FC80DD9E4412C5FC3800A6 +:1065E0008202E603E8073C0DFA795A080104FA0E24 +:1065F000DD9E44000640DD9EE602E8093C03F4F41B +:10660000E020E807E686E80B8401DD9E5A080206D2 +:10661000E686E8058402DD9EE607E8028407DD9E43 +:10662000E001E90DE002E80A8A838A01FF048A4159 +:1066300040220856886296DBD50280648003DD9E86 +:10664000E60280808401E905E69E8402E802840077 +:10665000E622E803EA57D5055CF08030E902EAA8B3 +:106660003C53F86BE045E90E3C2DFA795A28010BB2 +:10667000E63FE808E682E803EA86D504E69EE902FA +:10668000EA793C23F86AE062E9193C2DFA795A2844 +:10669000020AE69CE913E624E9105CF0802EE90E7C +:1066A000D5075A28030CE684E809E624E803EA86BD +:1066B000DD9E5CF0802EE902EA79DD9EFC6381A517 +:1066C000005F8058F185F38281648423846FFA89A6 +:1066D00080E080C28005844600AF8054F584F8E6EF +:1066E0004120001384238446FA69FA93800A3D2BE3 +:1066F000F86B152F8003F8DA9601F08122CF802401 +:10670000228F8026EB4F3C0BF86A8068F002802BCA +:10671000804CF917F10522EF80284432C5D4052FAB +:106720008003F504C90338019E0A3C9DFA7938219B +:106730009E025A98011354210030C22B3C03F4F4FA +:10674000E00DE805E6C3E825E6A6E9035A6802225B +:106750003C0DFC3DC01DD51A54010030C01A3C034D +:10676000F4F4E00DE805E6C3E814E6A6E9035A6888 +:1067700002113C4DFC3D54020002C00454010010C3 +:10678000C8059716C40596AEC20384C8D50284C254 +:1067900038719E0254038003C04840F64807E9035D +:1067A0005A1801444EA20007EA9EFEAC41012A1687 +:1067B000D502820A8006802D804C806E8085150F60 +:1067C0008002F84580C0050F80025A08022F5A98AF +:1067D0000114E77EE8055CF8015FE85BD5045CF531 +:1067E0008028E8773C0DFC3DC0565CF80097E90234 +:1067F00084C7E77ED54C3C13F4F48443FE8C800DB3 +:10680000964B96938465848AF8512E17F1919600E1 +:10681000E201E803967CC9552E17F190E201E807E2 +:1068200054038002C004D54D5A9001545403800C87 +:10683000C050F001E100E9062E07F0D8C04AE74653 +:10684000E9488006802D8048806E808A49FFFED608 +:1068500080C03C0DFC3D54100002C10E5A98020548 +:1068600054138008D5055A98030854138004C104B2 +:10687000E6C7E80284C79616C02C5A98020497D639 +:10688000D5045A98032797DEC724E6C7E918D5210F +:1068900084C7D5A9E77EE81D3C13F4F48443FE8C3D +:1068A000800D964B96938465848A49FFFEBB2E1714 +:1068B000F1919600E201E807967CC10584C7D509ED +:1068C00084C7D5B52E17F190E201E80397CECFF734 +:1068D0008006FCE3FC6184C03C6FFC3D3E67F0F049 +:1068E0002E472B393CCC01363CDC01353C8DFA7906 +:1068F0003CEC013450A0001C44B2C4149630E204B5 +:10690000E84604057FF9C03F5A00053E38059A0263 +:106910005A00013AB52A40162420A609A7C89E832A +:10692000E65A3816A501E82F9EBB5CF1002CE82B37 +:106930005CF08033E920442000FF80278062F481EE +:1069400049FFFE80F401C8173C2DFC3D58010001B1 +:106950003C0FFC3D5A880205E6FAE909D5055A883C +:10696000030BE6F9E80458210003D503582100057C +:106970003C2FFC3D380725012E17F0F0E220E803FC +:106980003E07F0F08CC150A50044D5B92E07F0F0B9 +:10699000E615840AE8052E07F0D8C0048E013E07EC +:1069A000F0D8FCE1EBDB8423B400400080BE3C0F58 +:1069B000FA79DD9E3C0DFA795A080104840FD5025C +:1069C0008400441000FF3C5C024EFD10404288C031 +:1069D000A5209723E48BE9095A38FF0580228062BD +:1069E000D504E22240113C1B8C4196905A2832F08B +:1069F0008A23442000FF96488062404280C0504273 +:106A0000003EA5209723E48BE9095A30FF06E240B7 +:106A100040203C1BD503804080608C0196005A08C2 +:106A200032EE8A43E6243E27F1903E17F191E804C6 +:106A30009610E604E9082E07EF405CF0003CE806FB +:106A40008C01D50284003E07EF40DD9EFC204422ED +:106A5000C5D43831060296DF9E5DE622E9058E69CF +:106A60005C318002D50284613C1C0137EAC7848016 +:106A7000A642A7C33D0C024E80A4E2E1E923A68012 +:106A80000110000141209408E3A2E91940690800BF +:106A900040681820A5B097B3C305C2075A281F0B3A +:106AA000D504C2065A201F05C1035A1831044253A7 +:106AB00014008C41424310009690D5E78C219648F3 +:106AC000D5DDEAC9FE2C8C81400010169603FCA08F +:106AD000FA2EFECC3C1DFC3DC10394D996D944123C +:106AE000C5AC38208101E243E80338308109380021 +:106AF0008101DD9EFC66F2882280800122208000D8 +:106B00003C10048C80C35010803C3C1BF4F4EB23FD +:106B1000EB56F2878160B400C05E5A00055F043511 +:106B200080073C0C013640000C200090000100A0C2 +:106B300000003C0C01353C1C013738500D113C0C59 +:106B4000013A40108C4039C00E023C0C0139E7225A +:106B500038700E02A60951300001A60840098001D4 +:106B6000553000FFA60BA64A8C018A0154D000FFC5 +:106B70003C0C0138EA9D38200E02FE8C40217056F4 +:106B80009691E909E73EE9055201060E9681D50383 +:106B90004420FFFF44100033FFCCE7424073F0F67F +:106BA00097F9E90A5CF50030E905527389C397F952 +:106BB000D5034470FFFF96188026F28B153F800A9C +:106BC000F58949FFFF4554E000FFF509053F800ABC +:106BD000F20BD50E81C0D50285C04470FFFF44A0E2 +:106BE00000FF804781AE826E812A80AE838E444250 +:106BF000C41438121A028184C92E4402C624EAC47D +:106C0000023F800EACC0128000014402C64CEBACC7 +:106C10004402C5D4EB604402C5ACEBACB40B44E217 +:106C2000C5FC38171A0A5A080110F81EF082F781BD +:106C3000153F800314DF8004800680418069808ACC +:106C4000F82A38071A0A38071A024E0200F7840198 +:106C5000EAD4D5475A100104480000B75A90FF24DF +:106C6000B40B5A0802219613B61F97FB400E001171 +:106C700083FF4502C5FCF082153F8003F78114DFD6 +:106C8000800438281A0280068069808A153F800AAD +:106C9000150F800949FFFD14050F8009053F800A83 +:106CA00038081A0A4402C64C38101911E43EE803A9 +:106CB0008C21EBACB42B4E1200965A1805044800F8 +:106CC00000925A1804134412C5FC38109A025A1044 +:106CD00002045A18080738001911E41E4EF3008305 +:106CE0008400B60B480000AA8E21E6224EF200A6D0 +:106CF0004412C5FC38309A029472F18945C2C62408 +:106D00004412C5D45A38021338209A025421003054 +:106D1000C20D38001911E40AE90984204402C5C8EB +:106D20003810180838361A0AD5473C0DFA795A082F +:106D3000010738009A02960FC813D50638009A0248 +:106D40005400000CC00D80068029804A8073F8151D +:106D50005CF7003380E0E9148006F806D5125CF792 +:106D60000033E906800649FFFC3A80E0D502FAEEDE +:106D700080068029804A806D49FFFEACD502FA0E5C +:106D8000382E1A11F307F1098A4342210003969124 +:106D9000883CE2E2EA7BE9068A28EB339649E20185 +:106DA000E8094402C5C88420381018088402EAD4CF +:106DB000D5038400B60BF009881C22100000F1876F +:106DC00022800001D53A5A1802394422C5C8380138 +:106DD00018009CC1965838111808B44BC2035A28A1 +:106DE00005058400EAD4D529E628E82452000007E6 +:106DF00096005A280306002580189696CA1E44322B +:106E0000C624F50738219A11FF4C425100739901AD +:106E100040229056406198409693F28722230001C9 +:106E200042140424EBD58125401090364080801117 +:106E3000D504840038021A0AF008021F800EAC4004 +:106E400012800001FCE6FC61814084C049FFFDAC7A +:106E500049FFFDB2800A49FFFD3F5095000880E6DA +:106E600044B2C4143A048000B0413A00802080410A +:106E7000800A96F849FFFE40B0013A0000003A044B +:106E8000802038059E02C0038CC197B08CE15094DD +:106E900080445A780AE93E67EF41FCE13C1DFB4E15 +:106EA000B4219225964FC10DFC0080C0DD475A08E1 +:106EB00002082E072BE7C804800649FFFFC6FC80A6 +:106EC000DD9E440395B7A640440395B6A600400056 +:106ED0000504DD9E440395B9A600441395B8A64861 +:106EE00040008104441F6A4488205CF0805AE90312 +:106EF000440095BCDD9E440395B4A600EA92DD9E55 +:106F0000440395B4A600EA64DD9E440395B5A6004B +:106F1000DD9E441395BAA6089600C00EA6089600FA +:106F20005A00010BA60896005A000207A608960010 +:106F30005A0003038400DD9E9600441395BBAE08FF +:106F4000DD9EFC00446395B4AE704412E610B601B9 +:106F50008401A98910208009100080081030800A5F +:106F60001000800B8001802449002B6FA630FC802C +:106F7000FC0084414400B100842080628082EAA742 +:106F800084003C0FFB8D3E07EF6CFC80FC402E071D +:106F90002B322E272B622E372B33421008243C1B1A +:106FA00095A12E172B63924142418424FE1C92210D +:106FB0003E272B693C4B95A23C0B95B23E172B6AA2 +:106FC0004402FE85A640842184C0AE40A641AF8124 +:106FD0003C6FFB51EAE850000020490035BDEA66ED +:106FE0003C0FFB6149FFE38049FFE3CF44038D364B +:106FF0004412FE5C44238D34B6C1AD90AD803C0F8D +:10700000FB5744038D303C0FFB6F44038D313C0F25 +:10701000FB5D44038D323C0FFB492E072BD33C1FF5 +:10702000FB4E3C2FFB553E67EC5F5A080106B4014E +:10703000EA81B601D504B401EA46B601B40185215E +:1070400040002404B601B40184C0EA82B601B40150 +:107050008540EB11B601B40184E0EA86B601B401C3 +:10706000EA9FEA79B601B4013C0FFB7244038D3606 +:10707000A44066108002AC40A44066108001AC4081 +:10708000A44066108008AC40A44044038D34AC405A +:107090002E072BD83E07EC43EA383E07EC4DEA3A80 +:1070A0003E07EC513E67EC8E3E67EC7F3C9FFBEA6F +:1070B0003CABF6653EA7EC983E67EC893E67EC5327 +:1070C0003E67EFC73E67EC20EA87EAF33CABF65D2C +:1070D0003CABF6673E97EC7C3E97EC3049FFE6D838 +:1070E000DD403E67ECAB3CABF65F3E67ECACAF819E +:1070F0003E67EC2D3E97EC723E67EC2AAF80DD5682 +:1071000084023E67EC213C9E00F43E67EC573E67EC +:10711000EFBC3E67EC363E67EFBDAE08DD59AE080A +:107120003E07EC5E440000C83C08048C3C08049018 +:107130004402E4043C0E02474402E2843C0FFB6834 +:1071400084083E07ED783E67EC373C7FFB583E678E +:10715000EC6C3E97EC653C7BF6753CABF66D3E67A0 +:10716000EC2B3E67ED9C3E67ED792E072B333E07F7 +:107170002C6580073E67ED7A3E67EF7C3C7FFB76AF +:107180003C7FFB703C7FFB663C7FFB533C7FFB6A94 +:107190003C7FFB523C7FFB7B3C7FFB6B3C7FFB429D +:1071A0003C7FFB4AF80280094900679F8007F8206E +:1071B0003C0E01328009F81C3C0E01338402F818A1 +:1071C0003C0E01348403F8143C0E01358404F8109D +:1071D0003C0E01368405F80C3C0E01378406F80895 +:1071E0003C0E01388407F8043C0E0139840849003C +:1071F000678B3C0E013A3C0395A13C0B96AC3C03DB +:1072000095A23C0B97153C0396AF3C1396AE4000FD +:1072100080203C0B96B03C0397183C139717400016 +:1072200080203C7FFBEE3C0B97193E67EFB4490092 +:107230005B8F3C0FFB7449005B65EAA53C0E034184 +:10724000EA603C0E03434402C2A03E67EDD53E67B0 +:10725000EDD43E67EDD63E600D003C7E03423E60BD +:107260000D103C0FFB77845F3C0DFB74843F38208E +:107270001C088CE65A783CFA3C0DFB7484C0EB6227 +:107280001010003D3C6FFBEB3C6FFBEC3E67EFC129 +:107290003E67EFC03E67EFC23E67EFC33E67ED1C3F +:1072A0003E67ED1E3E67ED1D3E67EC7E3E67EC914E +:1072B0003E67EC4E3E67EC753E67EC633E67EC7AEA +:1072C0003E67EC253E67EC543E67EFC649001A491D +:1072D0003E67EFC43E67EC3C3E67EC613E67EC3EC8 +:1072E0003E67EC88EAE8490033A9DD4FAF80EA2B1E +:1072F0005A080104490037C68401EB29EAB0EA7D47 +:107300004900030084C1490002F98400EBF0AE0893 +:10731000EB91EB373C1FFB73842AEB0684293C1F5F +:10732000FB6DEB5F3E07EC968420440061A83C1F98 +:10733000FB7C3C1FFB783C1BF6703E17EC313E1784 +:10734000EC4F3E100E443E100E453C0E039084025E +:107350003C0E011F84053C0E01208407EB2B3C6E84 +:10736000011E3E17EC563C0E0121DD41C030441099 +:107370000190440397ECAC404410011D440397EE88 +:10738000AC40441000E4440397F0AC40441000C704 +:10739000440397F2AC40441000AA440397F4AC4075 +:1073A0004410008E440397F6AC404410007244032E +:1073B00097F8AC40DD44440397FAAC40EACF44135D +:1073C00097FCAC08441397FEAC08D50580068426CC +:1073D00049FFDE938401EA54EB58840584C04412CB +:1073E000E648EA444402DD003E67EC5C3E67EC6739 +:1073F0003E67EC863E600E4C3E67EC453E67EC71A6 +:1074000049FFF368EBD7EAB74402FEFC3E6010F98F +:107410003E67EC42AF804402FEFDAF80490009E2C6 +:10742000EB2C3E67EC353E67EC6F3E67EC49842001 +:10743000AF8084464402C1DCEA4284208446440290 +:10744000C24CEA4244038D45AF8044038D46AF8071 +:10745000FCC0FC21446200B8800649002EA8EA3036 +:10746000F08149FFF0249C3449FFF0245003007858 +:1074700049FFEEAB500300A849FFF01F500300CCBA +:107480004900662DEA30F0814900662C500300B0B7 +:1074900049001612EA30F08149001611EA30F081F5 +:1074A00049001B7650030118490000B2EA30F08110 +:1074B000490000B1490000CD5003012C4900199B3F +:1074C000507303A0EA30F081490019988007490001 +:1074D0001998EA30F08149004A30500301704900A0 +:1074E0004BFF5003031849005DF5EA30F081490075 +:1074F0005DF45003036449006383EA30F08149007E +:1075000063825003037449004BF3EA30F081490071 +:107510004BF28007490059F0EA30F081490059EFF9 +:10752000500303AC49001F97EA30F08149001F90D7 +:10753000EBDBEBBF500303D049FFD157EA30F081BA +:1075400049FFD1565003004849003AF5EA30F0812E +:107550004900190449FFF2BC49FFF2BB49004BC383 +:10756000490061B349FFD1474900644949004CAD26 +:10757000FCA1FC00DD56840284C03C6FFBEBAE082E +:10758000DD59AE08440000A2EB39DD40A6015A08DF +:107590000D118006847F3C2DFB74843F3831000838 +:1075A0008C065A083CFA3C0DFB74EB621010003D4F +:1075B000490000343E07EFA12E072B3B84C0520048 +:1075C00000013E67EC204900017F8401EA693E0723 +:1075D000EC693E07EF9DEA2B3E67EC763E67EC4494 +:1075E0003E67EC8B5A080103EA73FC80FC018401BE +:1075F000EAB0EB6BEBD4EA4F8400EA4B3C1C025D33 +:10760000EB0BFA50EAEEEB408401FC813C0FFC6A84 +:10761000DD9E3C0FFC69DD9EFC00840084203E075B +:10762000F1A23E07F19F3E07F19E3C1BF8CE3C1BAA +:10763000F8CD3E17F1A13E07F1A0441000408400B0 +:107640003E17E9ED3E17E9EC3C0FFC6BFC803C0D6E +:10765000FC6AA4413C1BF8CCA444A6003C1BF8CB1C +:107660003E07F194DD9EFC20A7403C439795446281 +:1076700000002F072B395A50010584A08225D525FB +:107680005073040184A04C580009091380018CA197 +:107690001113FFEA9768D5F82E7FEF414E76000868 +:1076A000A6003C5399CE5A08015ED5178EA1976863 +:1076B000E0A7E9F741029C018986011803EC410328 +:1076C0001400111803ECD5F397E8E2F0E8EA99F515 +:1076D000111383EC8CA1D5F92E07EC889A10E402E3 +:1076E000E9095A3801082E07F1B0C8083E37F1B051 +:1076F000D50484003E07F1B0846084003E07EC8826 +:10770000A609C8332E072BE35A0801105A30010886 +:107710005A28010C3C03F69EE614E9073C00048C51 +:107720008C0A3C0B9795D5033C5B97952E27EF2051 +:107730003C139795C21A9B0C96215A2801054000CC +:10774000803DD5115A2802054000805DD50C5A288D +:1077500003054000805CD5075A2804084000803C9F +:10776000D50284003C0B9795FCA0FC003C1DFA72EE +:10777000A6088C01AE083C1DFA72A6089604C8063D +:107780003C0DFA743C0FFA71D5053C0DFA733C0FB1 +:10779000FA713C0DFA71A6481010003F80A08420B9 +:1077A000EADA5000003CEADAD8FFFC803C2DFA719E +:1077B000A65098D1AE199C0996005CF0003BE902F6 +:1077C0008400AE10A6108840841FAE11DD9EFC0020 +:1077D000EAE52E57EF38D00BC804EB2EDD42D50476 +:1077E00044000051DD42EAE53E07EF382E07EFA0E6 +:1077F0002E57EF39D00DC80544000054DD42D504A2 +:1078000044000053DD422E07EFA03E07EF392E075C +:10781000EFA12E57EF3AD00CC80544000056DD42C8 +:10782000D503EA3ADD422E07EFA13E07EF3A2E00DC +:10783000165D5A00AA048407DD42FC80DD9EFC0030 +:1078400049002800FC8044100055DD43AE40DD9E19 +:10785000FC03F0818005F283F182F384F485490012 +:107860002768F002F10349002B07DD44DD43AE40F9 +:10787000F001F104F20549002AA0FC83FC2084C039 +:1078800080E0E2C7E80B8401844080208062808031 +:1078900080A28CC1DD5397B0D5F5FCA0FC00490057 +:1078A0002BBBFC80FC0049002BA9FC80EB6EC808B8 +:1078B0002E17EF28C907FC0049002BB9FC80840073 +:1078C000DD9EDD9EFC0049002726FC80EAE9C80F0A +:1078D000FC002E072B3B4900271EFA09EA3B2E0726 +:1078E0002B3B5200000149002716FC80DD9EDD9EE7 +:1078F000FC0049002C6DFC80FC0049002C5FFC80E2 +:1079000044130FA0B62044138068A845441373E8BD +:10791000A846EB1FA84244130C80A84444133F9090 +:1079200050200044B62244123200A851441274F888 +:10793000A853DD9EFC4480C0440155983B004C0098 +:10794000440155A8EBB6B1C43B004C003B03CC202E +:10795000EB9EEBF2813F420004019640C1038E2171 +:107960009648EAF08386B88A38038602B88B4420AA +:1079700000C84402D9DC42008873B89344031F4016 +:10798000B88944038DD4B88CFCC4FC20842CAE414F +:1079900084003C0FFB98EA6A49FFDFA8EA8C3C0DA3 +:1079A000FB98C00B8420846184028041808380A383 +:1079B0003C1FFB98DD53FCA0490027DB5A0801F46B +:1079C000AFF0D5EEFC00490027CB8401490027CD5C +:1079D000FC80A4408C2196495CF08190AC40E90980 +:1079E000FC008405DD428400EA23EA96EA5BFC8021 +:1079F000DD9EFC20FD30DD41C01FA770DF0A8CA199 +:107A00009768E6A5E90284A0EA38AF70EA87D50D49 +:107A10008406DD4244138D20A6088C019600AE0832 +:107A20008400EA23EA3AEA5B44038D20A600C004FE +:107A300084013E07EFC2FCA0A6885A28AA0AFC00CF +:107A4000A680AE888420AE4049002B6AFC80DD9E73 +:107A5000FC00EA3F5A080416DD475A000213EA8880 +:107A60005A08011084003E07EC208400EB7AEA7E7D +:107A7000EB8949FFFFE3840384203C2DFB49EB7332 +:107A8000FC80A6885A20AA10FC00AE80442FFFAAD2 +:107A9000AE88A6005A08010549002B3BFC8049002E +:107AA0002B3FFC80DD9E8440AE808400AC08DD9ED0 +:107AB000FC005A0801054900297EFC804900297C08 +:107AC000FC80FC0084204403F560AE408423440322 +:107AD000F561AE408400802080408060EA2EFC800A +:107AE000FC0084234403F560AE4084204403F56128 +:107AF000AE408400802080408060EA2EFC80FC0044 +:107B00004402FE63A7404403F007A600D8084402DD +:107B1000FE64A7404403F004A600D006441FFF8E75 +:107B2000EB8FAE40F80A4403F007A6005A00231179 +:107B3000441FFF9EEB8FAE40843F4402FE61AE4087 +:107B40008420840280418461808180A1DD53FC8097 +:107B5000FC24440155C83B004C00442155D8EBB6E9 +:107B6000B004EB7D3B004C2044238D41A690441192 +:107B7000D80040108840A6C838500A028400384F08 +:107B80008A0296D84462623880E03C1395B2E201E2 +:107B9000E81840230020030100003812800042183A +:107BA00004243902010140108C0E8A309649AC50F1 +:107BB000A450964B4E140003ADD08C019601D5E62F +:107BC000FCA4FC01F08194918001F101DD48FC816D +:107BD000FC0644220000FAD0A6D2A71384A1844058 +:107BE000F68584C2F283F284F286F288F289B67F47 +:107BF000F581F382F687F58A8041EA35FC86FC0040 +:107C0000C805EAA2EAAAEA4FFC8049FFD25880A040 +:107C1000C8F9EAA244130002442262382E372B32FC +:107C20002E472B334900243BFC80FC00DD5480C0F0 +:107C3000A64949FFFFE65A680306EAE9C80349FF77 +:107C4000FF89FC80FC2697D0FA5084C084A1F2857D +:107C500084429718F287B6FFF581F782F683F6849F +:107C6000F686F688F689F58A80418067EA35FCA6B3 +:107C7000FC0644420000A7A284A0A723F581F58258 +:107C8000F583F584F586F588F58984A1F285F38777 +:107C9000B6DFF58A80418066EA35FC86FC07F38D05 +:107CA000FA7084A08082F38584418462F281F48238 +:107CB000F387F28A8064B6BFF583F584F586F5888C +:107CC000F5898041F40DEA35FC87FC01EB45EB1F9B +:107CD000EA4FEBD4EB6BEA4F8400EA4B3C1C025DAD +:107CE000EB0BFA50EAEEEB40FC81FC08F18EF08DD4 +:107CF0008023F28F2E372B32C4052E472B3380037F +:107D0000D5038004848184A1B61FF0828400F083AF +:107D1000F184F085F086F088F089F08AF581F587A6 +:107D2000F00DF10EF20FEA35FC88FC01DD475A0830 +:107D3000021B8400EA4B8481EB45EB1F442373E86C +:107D4000846049FFFFD4501F8006EAB484408463F6 +:107D5000EBA8220F8003441000E64200000340001D +:107D60008007FC818400FC81FC00840184204900A0 +:107D7000288B44000CD54900288FFC804403F01F59 +:107D80004423F302A600A650540000E096678C221C +:107D90005EF08020E807A650966788018C02960066 +:107DA000D5038C1F96004413F01FAE08DD9EFC0027 +:107DB00084008020490024C94900297E49002F9F62 +:107DC00049FFFFD449FFFFDC490027F4490022A8FE +:107DD000490029D249002414490023BE49FFC401A7 +:107DE000FC803C03F4F83C1DFA7D4423F540B4428A +:107DF0003820820A4423F544B4629C819691EADEDD +:107E00004423F548B4629C829691EADE4423F54C03 +:107E1000B4629C839691EADE4423F550B4629C845C +:107E20009691EADE4423F554B4629C859691EADE8D +:107E30004423F558B4629C869691EADE50200008EF +:107E40003C2BF4F88C074423F55CB44296013820AF +:107E5000820ADD9EFC015A0801163C0DCAE9B61FD4 +:107E60003C0DCAEAF0813C1DCAE43C0DCAE33C2D3E +:107E7000CAE53C3DCAE63C4DCAE73C5DCAE8F81598 +:107E8000D516C8153C0DCAE1B61F3C0DCAE2F081FB +:107E90003C1DCADC3C0DCADB3C2DCADD3C3DCADEC4 +:107EA0003C4DCADF3C5DCAE049002567EAC25A087A +:107EB00001093C03F4F85CF00080E80349FFFF93FC +:107EC000840080208040806049002356490023318F +:107ED000FC814423F077A6509604EAC6FE0FAE104C +:107EE000DD9E9200FC2080E080C1DD47A6B9C80677 +:107EF00050017FF6E6028409E9028002EA28EA3DA1 +:107F0000AE884423F380A6505A1001FF4E630067E9 +:107F10008E01E60E4EF200CA44F07D24EB0C40F0D8 +:107F20003C00DD0F1C00840122005A0022005A0090 +:107F30005A0028002800600060005A002200AA00B1 +:107F40008403EA6DF8498400F895F84684014900F5 +:107F500023E78400F895EAAC5A0801064400088E2D +:107F6000EA3BD5088440840184248062808280A01A +:107F7000DD538401EAD18401F88A49FFFDB384000E +:107F8000EA6DF82AEAE0C005EAC2C0038400EBC348 +:107F90008401F87D8400F874EAAC5A0801064400B4 +:107FA000088EEA3BD5088440840184248062808264 +:107FB00080A0DD5349FFFD968400F85CEAE04E02A4 +:107FC0000075EAC24E0300728401EBC3F805840118 +:107FD000EAD18400EA6D480000695A6801618E03A5 +:107FE000E60CE86344F07DF0EA7540F03C00DD0FFC +:107FF0000C120C121218187070B80C8C8401F83A1C +:10800000D5548401EA6DD551EAE0C011EAC2C00F2F +:108010008400EBC33E07F0903C03F4F83C1DFA7D6E +:108020008E019402B60184013C0BF4F8EAE0C80D1D +:108030008401F8268401EA6D44000037EA3B84009D +:10804000F8268400F829D531EAC2C8F33C5DFA7DF0 +:1080500084213E17F1B150128200AA29D9FFD5E937 +:10806000EAC2C005EAE0C0038400EBC38401F8085B +:1080700084014900264EEAE0C8A5D517840149FFCE +:10808000FEEB49FFFD208401EA6D840049FFFF23D8 +:108090008400EAD1840049002343D5075A680206C8 +:1080A0008401EA6D8400EAD1FCA0FC40EA3F80C173 +:1080B0005A08040BEA88C008DD475A0802138420D6 +:1080C00049FFD358D50EDD475A0002F88401DD5030 +:1080D0008420846184028041808180A3DD53D5F4B3 +:1080E0008402DD508441440001A0441000308062CD +:1080F0008082EAA784208461440001A080418083BB +:10810000EAA75A00300E8441441000308062808219 +:10811000440001A0EAA7440000D7DD42D5ECEA3FC5 +:108120005A080410DD475A00020D2E772BCB5A78DF +:1081300001098007490024198400EA238007EBB76E +:10814000EA7CEA853C0DFB98C0078404DD50EA3FD9 +:108150005A08041FD5094900240C5A0801F8840361 +:10816000DD50EA58D5F0DD475A000213EA885A0874 +:108170000110840049FFDB78441FFFC34403F42946 +:10818000AE40DD408420DD558402AE31D50E804600 +:1081900084058420EB73DD408420DD558402AE31FC +:1081A0008401EBE58405DD50FCC0FC20EB275A0878 +:1081B0000152DD47C84FDD58A6405A1801FFA600FE +:1081C0005A080149DD4CA78097B05A680144DD4048 +:1081D0008429AE418420DD55DD40842AAE41DD4155 +:1081E00080E0DD58C70D8420AE40DD4CAE408006F7 +:1081F000EA238408EA6B2E07EF2BEA63D52BAFC086 +:10820000DD4CAFC08006EA234402FEF2AFC0DD447D +:10821000DD43AE40EA78C0FF49FFDADDEA22EB0138 +:10822000AE08804184618402DD46DD40EB5BDD4CBD +:108230008421AE408401EB4E5A00010DEA885A08B1 +:108240000108DD40A6015A080A0449001A81840089 +:10825000EA5EFCA0FC43441155E88140A600B182CF +:108260003B00CC003B034C2085205A080105490007 +:1082700039EC81208400EA4B84E0EB1C38031E02B9 +:10828000842094918CE1EA425A7804F9EBF15A087F +:10829000011C8403DD548049EA43EA8D2E17EC3B30 +:1082A000440000C8FE0CEA4BEB1FF80344130FA078 +:1082B000EB0B2E272B322E372B33EB4049FFFF776A +:1082C000DD56A608C8FFDD44DD43AE408400FCC394 +:1082D000FC2184C0FA003E67EC2244738D40DD42ED +:1082E00049002B7984013E67EC683E07EC343E0779 +:1082F000EF7A3E67EF923E67EC523E67EC55AFB8BF +:10830000DD47DD545A08020B8404AE098001842045 +:10831000DD55DD40842DAE41D50A8409AE098001CA +:108320008420DD55DD40842AAE41AFB8DD5884217C +:10833000AE40EA2B5A08010FDD4FA6003E07EC6A5B +:1083400044038D41A6003E07EC2EEB8EC8033E078A +:10835000EF92DD40A6013E07EC838406DD50EB245E +:10836000C814DD40EA342E072BD65A080104490010 +:108370001705840ADD5049001776EA2BC04ADD470D +:108380005A080248840BDD50EA2B5A080110DD41DF +:10839000C00DEB245A0001052E07EC52C807440219 +:1083A000C462501F800749FFFF57EA2B5A08012B70 +:1083B000EB24C80B44000066DD50490017C75A087B +:1083C000010C3E07EC22D50844000067DD50DD5665 +:1083D000A6085A0801FF44000068DD50DD41C008CE +:1083E000EA2A5A0806FFEAA2EAAAEA4FD505DD56AC +:1083F000A6085A0801FFDD568402AE08DD59AE0812 +:10840000D508DD41C006EA96DD50DD4FA600EBF74A +:1084100084003E07EF7ADD47DD542E27EC835A08AF +:1084200002089E12E602E806840DAE09D5075A201E +:108430000204AE89D503840BAE09DD40EA34840022 +:10844000EA41EB413E07EC373E07EC3484C144007F +:10845000006ADD503E67EC52DD41C00349FFF8C8B9 +:108460003E67EC4ADD47C80484013E07EF744400D0 +:10847000006FDD50FCA1FC00EB275A08011FDD470F +:10848000C81CDD58A6405A1801FFA6005A0801165C +:10849000DD4CA78097B05A680111DD408429AE41B8 +:1084A0008420DD55DD40842AAE41DD568400AE08CF +:1084B000DD59AE088006EA23FC80FC00DD40A641C1 +:1084C0005A10061C2E17EC33C9182E67EC8FCE15E8 +:1084D000DD56A6485A180112DD59A6485A18010E51 +:1084E0008026EAC8DD55DD58AF802E07EC74C8033E +:1084F000DD59AE088401EA23FC802E07EC46842176 +:10850000EBB2DD9E4403F07FA600EAE4DD9EFC00B2 +:1085100049FFFFFAFC80FC4080C2812080E14900D5 +:10852000261E4900264044201900FE14E206E813E6 +:108530008AC0442186A04023085710248000440E9E +:10854000796096904261007344001388406300D7BD +:10855000AFB8FCC0842010148000AE78FCC0FC00D2 +:10856000490025FD490025F5FC80FC0180C0800103 +:10857000F281490025DBF001F82E84013E07EF76F9 +:10858000A6303E07EF758400EB528401490023FEBC +:10859000F8F42E07EF765A080109844080208062A3 +:1085A000808080A2DD53D5F6FC81FC0080C0800174 +:1085B000A648C1058421442000CDF807A630C00795 +:1085C000800684244420008249FFFFD184074900AB +:1085D00025AD8400490025E28400490023D7FC80B2 +:1085E000FC20A78080E0E6CBE9068ECA840A97B01B +:1085F000AE38D50284C0A638C0038C01AE38A63888 +:10860000E603E9038C01AE38A638C8038401AE380E +:10861000A608C004EA9DFE0CEA3BC6059431EA8F29 +:1086200049FFF92EA678C1078440840284618483BF +:1086300080A2DD53FCA0FC02F08180C1F80CF201A5 +:10864000F8725A68020984013E07EF70EADFEAE334 +:10865000F862D505EAE3EADF83FFF869F88EFC8269 +:10866000FC21FD30F281DD47C82C5A700907461005 +:1086700000F450008240D505461000C3500085002C +:108680005A60011DC6045A600205FCA1F876FCA1DF +:108690002E27EF6F2E37EF6ECA02C310441186A04B +:1086A000FE5C846AEB61443FE70042010C738A017F +:1086B00084203E17EF6E3E17EF6FF10149FFFFBDBB +:1086C000FCA1FC2080E080C1DD475A08020ACF1AD5 +:1086D000DD40A6415A10041349FFFEF1D513DD40D9 +:1086E000A6415A100B105A6004068006844349FFC5 +:1086F000FFB9DD40A6415A180904EB2FD50349FF05 +:10870000FEBCFCA0FC02F081EADFEAE3F201F80B18 +:10871000EAE3EADF49FFFF66FC82FC02F081EADF60 +:10872000EAE3F20149FFFEF9EAE3EADF49FFFF3F2E +:10873000FC82FC00460000A650000040F80DFC80C2 +:10874000FC00F81BFC80FC00F818FC80FC004600D4 +:1087500000A65000004049FFFFD7FC80FC00EBB4AE +:10876000EB9CEB10FC80FC00F808FC80FC00EBB4F8 +:10877000EB9CEB10FC80FC0049FFFEF3FC80FC004E +:10878000EBB4EB9CEB10FC80FC2080E180C2C00DC0 +:108790005A00041184003C0BF66849002E2D444316 +:1087A00095AC443395AAD50A444395A6443395A481 +:1087B000D505444395AC443395B084009680E24699 +:1087C000E80738138101381201098C01D5F83C0300 +:1087D000F668AC18FCA04422FF5038100808DD9E53 +:1087E0004452FF5084204402FF70EADAD8FFDD9E35 +:1087F0003C03F8DA8C0196015CF000FFE90284008A +:108800003C0BF8DA3C13F8DA4402FF52AE40DD9E2E +:10881000FC4049FFD96CEA3F9E46E622E90A501027 +:108820007FF7E625E9065A00110584014800007427 +:10883000DD40A6015A0804148404441000BDDD453F +:10884000440000D0DD50DD41C01F840049FFD0BC92 +:108850008401DD4AEA94EA7CEA85D50B8E08E604B9 +:10886000E9ECDD475A0802EAFA31EA5DAE40D5216B +:10887000A6305A002105EAEFEA58D5FB8402DD4A0A +:108880008400EA5ED5162E07F02AC8088402441335 +:10889000970044238D54EAFAEACA8406DD4AEA22A4 +:1088A000FA11AE08804184028461DD468400EA95B5 +:1088B0008403DD4ADD4084C0A601DD4A49001F5E15 +:1088C000440000D1DD50DD479E424013040684027F +:1088D00049FFCF50DD475A08010A80064900221A95 +:1088E0008006EBE5800649002229440000D2DD50D5 +:1088F000DD404412C4703C2DFB4E4432C298490006 +:108900003A3D80C05A00080448FFFF91440000D35C +:10891000DD508006FCC0FC20EB8149FFF33949FFA4 +:10892000FA48DD408421AE4149FFF595440000A09E +:10893000EB39EB79DD5449FFFBBA44000051DD50BF +:10894000EA6AEA8C49FFFDE0C803AFF0D5FCEB2EE4 +:10895000DD50FCA0FC00840FDD4284044410006262 +:10896000DD45DD44DD43AE40EA76A608C8FF44009D +:108970000082DD5044000083DD50840149FFD91E90 +:1089800044000084DD50FC80FC008404441000613D +:10899000DD45441000678404DD458404EAFF44009B +:1089A00000A1EB39DD40EB44EABDEBB5848049FF23 +:1089B000DF08EA655A0801084402C0F0EB32EBEA2E +:1089C000490023AEDD568402AE08DD59AE0849FFEA +:1089D000FFC3840444100068DD4549FFFC7BEA6561 +:1089E0005A0801044900239549FFF5C58402DD4278 +:1089F000840444100069DD45FC80FC00EB6380C00A +:108A0000840CDD5044038D47A6408C219648AE402F +:108A1000DD44DD43AE408409441000A1DD4549FF3B +:108A2000F8198409EBCADD458409441000A3DD452B +:108A3000DD40A6415A100D0B2E17EFBCC90744129A +:108A4000C1654422C47049003AD18409EBC5DD45B3 +:108A50002E07EC375A080106FA05DD4284C2F88376 +:108A60008409EB7EDD452E07EF2CC00AEAB5A6404F +:108A70005A102105A6005A0822048401EA37DD575E +:108A80005A08190449FFDF3184003E07EC592E07CC +:108A9000EC9AC810EA2A5A08060E8409EA50DD54F6 +:108AA0008401EA373E07EC59DD4FA600A64949FF8D +:108AB000F8A82E07EC8E5A08010D4402C15E3C1D39 +:108AC000FB4EEABD3C3DFB573C4DFB5549FFDFB03B +:108AD000DD41C013840C00130050DD45840D0013EC +:108AE0000051DD45840E00130052DD452E07EC25B4 +:108AF0005A0801048400EABB3C0DFB7E5A0801447D +:108B0000DD58A60096005A08013F84203C1FFB7EDA +:108B10002E17EC8A5A18551B2E17EF2DC104EABBED +:108B2000EAD2D516EAB5A6005A0813054400008615 +:108B3000DD42EB79DD544422C1133C3DFB4E4442FF +:108B4000C29849FFE135EAD2D503EA3AEAF3DD57A4 +:108B500049FFDB1896003E07EC30DD4A2E67EC300B +:108B60005A680304480000755A68020EFA04DD4290 +:108B70002E07ECA1DD42DD44DD43AE40DD56A60804 +:108B8000C0FFD566DD56A6085A080206DD4CA600D1 +:108B90005A0002062E07EF9D5A08012D8401AE08E7 +:108BA000DD59AE082E07EF9D5A080121EA2A5A081E +:108BB000061E8409EA5084003E07EF9DEA2B5A08FE +:108BC0000114DD4FA60049FFF8B25A080107EB8EE9 +:108BD0005A0801043E07EC222E07EC22C005FA06D3 +:108BE000DD4284C2D5358401EAB0DD47C80349FFC0 +:108BF000FDC8DD40A6015A080A08DD47C80349FF41 +:108C0000FDA149FFFAD42E07EC595A08010DDD4F9A +:108C1000A6005A080309EAE9C80684023E07EC598F +:108C200049FFF798DD575A08040449002F112E0711 +:108C3000EC8B84C15A08010D84003E07EC8BDD5992 +:108C4000A6089600C8FE8441AE88FAC3EA378006BB +:108C5000FC80FC01EA655A0801064402C0F0842049 +:108C6000EAF4EA2B5A08010449003116DD4FA60048 +:108C70005A08030CEA2B5A08010949002D81840285 +:108C80003C1DFB4DF807D50849002294F081F10105 +:108C9000840049FFF62FDD40A6415A180D048423B5 +:108CA000AE41440000A3EB392E072BCD5A08010B2F +:108CB000DD40A6005A080107DD4FA600490023A4A5 +:108CC000D504EB45EB6BEA4FEA7D4412C1E4442244 +:108CD000E19C443200004442DDE849FFE47DFC8130 +:108CE000FC002E072BCE5A080108EA7D4412D6CC90 +:108CF00049FFE3D1D5063C0C024F3C1C024EEA4F23 +:108D00002E072BE35A08010E4402C4524412C450E9 +:108D10004422C44E4432DDF44442D99849FFEBD892 +:108D20002E07EF7BE6053C03F7BFE8055CF0012C5E +:108D3000E905D50A5CF0010EE807EAD0E9058400F0 +:108D40003C0FFB51D50484013C0FFB5184013E07CD +:108D5000EFCADD575A081208EA6C8421EA7F5A08E4 +:108D60000103F8112E17EC435A1801054402C0F014 +:108D7000EAF4DD575A08120AEA6C8422EA7F5A089C +:108D800001058402EA4EEA71FC80EACEC80BFC00C1 +:108D90004403307049FFE6C6C007FA18EAB78403F7 +:108DA000FC808404DD9E8401FC80FC6680C0EA2D8A +:108DB0002EA72B322E872B552E972B542EB72B33C5 +:108DC000C00944C3343C44D333D844233374EB7FC9 +:108DD000D50844C21B3044D219A044221810EAFC22 +:108DE000CE2F84E1FB708522806A808880A7804135 +:108DF000F80B44034C10EA35EB00EA294403589081 +:108E0000DD48802D804DB75FF78114AF8002F68377 +:108E1000F68414BF8005F686149F8007F688F689CD +:108E2000F78A83FF44034F30806A808880A7EA3541 +:108E300044134F30EA2944035BB0DD48FCE65A682E +:108E4000013084E0FB10854280228069808B80A6FF +:108E500044034DA0F80CEA3544134DA0DD5E4403F5 +:108E60005A20DD48440350C0802C804CB73FF68127 +:108E7000149F8002F783F784148F8005F78614AF60 +:108E80008007F788F789F68A83FF8069808B80A640 +:108E9000EA3544035D40441350C0DD5EDD48FCE626 +:108EA000FC004E02005AEAB4EA295A181420EB00DA +:108EB000DD4844134F30F81F44129ECAF821440382 +:108EC00083884412A1EAF82BEA2DC003EB7FD50278 +:108ED000EAFCF824EA2DC004441333D8D503441225 +:108EE00019A0EA29EBC2DD48FC8044135890DD4804 +:108EF00044135BB0EA2944037708DD48EBE0EA2934 +:108F000044038068DD48440383884412A82AF80794 +:108F1000EA2DC003EB7FD502EAFCEB4DEA29DD48E0 +:108F2000EA2DC004441333D8D503441219A0EBC270 +:108F30004E00FFF6441386A84402AB4AF86BF806CD +:108F40004402AC12441389C8F8653B0054003B004E +:108F5000D42083FFFC8044037578DD5E5A18142109 +:108F600044134DA0DD48441350C0F81F4412A05ACA +:108F7000F822440385184412A37AF823EA2DC0048A +:108F800044133374D50344121810F824EA2DC00496 +:108F90004413343CD50344121B30F827FC8044139F +:108FA0005A20DD4844135D40DD5E44037898DD4877 +:108FB0004412A69ADD5E440381F8DD48EBCBEBCE8C +:108FC000DD5EDD48EA2DC00444133374D50344123A +:108FD000181044037BB8DD5EDD48EA2DC00444135D +:108FE000343CD50344121B30DD5E44037ED8DD489B +:108FF0004423883880224402ABAE3B0064044423FF +:109000008B583B00E424F806F80A4402AC76802230 +:10901000F8013B0064043B00E42483FF3B00500064 +:109020003B00D02083FFFC80FC40C8053C5DFB6D0D +:10903000C508D53F5A08013E3C5DFB6D5A58013AC0 +:109040002E57EC2F84C38EABE2C584C0E9052E6792 +:10905000EC2F8ECB97B1C0085A08010B4470003238 +:1090600080A78604D508FAF084A68207D50484E098 +:1090700080A782078124EAB4444001904258142416 +:10908000420310735A181406802294A9DD48D504AF +:10909000802394A9DD48EAF1EB4D4203047394B9AF +:1090A0008029DD482E07EC2F5A080E048408EABCFC +:1090B000FCC09200FC012E27EC565A200704480001 +:1090C00000A4E6104EF200A1F18144F08ED83817CA +:1090D000810140F0BC00DD0F2000200020002000B6 +:1090E0004C006000740086009800AC00C000D40002 +:1090F000E600F80008011C012E57EC2F8C0B4C5099 +:109100004084EA2AC8048401F101F807EA2A5A00D7 +:109110000103F8078400F10149FFFEC48408EABC9A +:10912000480000738400F10144234C1044335890EC +:109130004442AB4AF867D5688401F10144234DA04D +:1091400044335A204442ABAEF85DD55E44221680CB +:109150008400F10180624442AB4AF854D555442260 +:1091600018108401F10180624442ABAEF84BD54C3B +:109170008400F10144229ECA4432A50A4442AB4A0B +:10918000F841D5428401F1014422A05A4432A69A02 +:109190004442ABAEF837D5388400F10144234F3058 +:1091A00044335BB04442AC12F82DD52E8401F1015A +:1091B000442350C044335D40EBFCF824D5254422C1 +:1091C00019A08400F10180624442AC12F81BD51C46 +:1091D00044221B308401F1018062EBFCF813D514AA +:1091E0008400F1014422A1EA4432A82A4442AC128C +:1091F000F809D50A8401F1014422A37A4432A9BABC +:10920000EBFC49FFFF13FC819200FC602E472B32E0 +:109210002E272B552E372B542E172B334E0300F3AE +:10922000423208244052040990618020449320D0A7 +:1092300044A3226044B3271044C328A045234C1004 +:1092400045334F30E023E82C4020949797209489B1 +:10925000CC02961040412400A5208C21411200111F +:1092600040412800A52096484102001140412C00B1 +:10927000A5E0884C9501A5904022480013110000FC +:10928000988594914111480097FB97B38893885330 +:109290008C01130880009600ADE0AD90D5D4EAE1D2 +:1092A0005CF000A04EF3013A5A00A0095A00A10B4D +:1092B0004462A1EA44129ECAD50844634F30EB00D1 +:1092C000D504446219A0EAFC2E07EC39E602E82B2B +:1092D0003C0DFB715CF01388E9048400EBD8D503E6 +:1092E0008C01EBD8EA29EAB4DD488026EA29440358 +:1092F0007578DD48441000C144037572AC40EACD76 +:10930000A400441375749603AC08EACCA40044137B +:1093100075769603AC08442373E8EB00EAB6840242 +:10932000EACAF8729E82E642E822EA29EB4DDD485D +:109330008026EA2944037BB8DD48441000C2440378 +:109340007BB2AC40EACDA40044137BB49603AC08D6 +:10935000EACCA40044137BB69603AC0844237708F8 +:1093600044134F30EAB68402EACAF84E9E84E642BD +:10937000E823EA2944038068DD488026EA2944037B +:1093800081F8DD48441000C3440381F2AC40EACDCB +:10939000A400441381F49603AC08EACCA40044135F +:1093A00081F69603AC0844237A2844135250EAB657 +:1093B0008402EACAF8298E06E6024EF200AFEA29D4 +:1093C000440386A8DD488026EA2944038838DD481E +:1093D000441000C444038832AC40EACDA4004413D6 +:1093E00088349603AC08EACCA4004413883696036C +:1093F000AC0844237D4844135570EAB68402EACA97 +:10940000F8035A0001044800008940518409FECC49 +:10941000842090618001449323F044A3258044B3C9 +:109420002A3044C32BC045234DA0453350C0E00330 +:10943000E82C4020149797209481CC02965040410C +:109440002400A5208C014112001140412800A520D4 +:1094500096004102001140412C00A5E0884C95097E +:10946000A5904022480013110000988D949141115D +:10947000480097FB97B3889388538C21130880008A +:109480009648ADE0AD90D5D4EAE15CF000A0E945A6 +:109490005A00A0095A00A10C4462A37A4412A05AAF +:1094A000D50A446350C044134DA0D50544621B3017 +:1094B000441218102E07EC39E602E80BDD5E440377 +:1094C0007708DD488026DD5E44037898DD48D525A1 +:1094D0009E82E642E80ADD5EEBC2DD488026DD5E64 +:1094E00044037ED8DD48D5199E84E642E80ADD5E55 +:1094F00044038388DD488026DD5EEBCBDD48D50D57 +:109500008E06E602E80ADD5E440389C8DD484403AE +:109510008B588026DD5EDD48FCE084004412DE7C52 +:109520008040382081098C014432DE7C5A08C0FB1F +:109530008400804098588C02122080C85A0990FC00 +:10954000FC203C4C024F84A084C344700640A420FD +:109550005412801F4022A009402088A096033901A0 +:1095600089014000181688103801890940029409C1 +:109570000A22000194024000047C9693500000C827 +:1095800040111836382181018CA188229769381141 +:109590008109DFDEFCA0FC662EA72B3280C02E875F +:1095A0002B552E972B542EB72B33C0035A0801048A +:1095B00049001E47EA2DC00944C3343C44D333D884 +:1095C00044233374EB7FD50844C21B3044D219A026 +:1095D00044221810EAFCCE2284E1806A808880A7A9 +:1095E000F8064403589044229ECAEA35B75FF781D3 +:1095F00014AF8002F683F684F685F686F787F68840 +:10960000F689F68A83FF44035BB0802D4422A1EAE9 +:10961000806A808880A7EA35FCE65A68012384E0E6 +:10962000802244035A204422A05A8069808B80A65D +:10963000F802EA35B73FF681149F8002F783F7847A +:10964000F785F786F687F788F789F78A83FF44035B +:109650005D40802C4422A37A8069808B80A6EA3505 +:10966000FCE6FC0080C080204402D6CC49FFDE1915 +:10967000CE5D4452A50A443D5AF64442DE7C84C382 +:109680004422A68A982B38120011A4289603E020C1 +:10969000E909EA2FC80340109836A4288A019603E6 +:1096A000AC288CA2DAF0848180A44402A50A44325A +:1096B000D8D08420EB04F89384003C0FFB623C4C30 +:1096C000020C806080A02E2010E59860C20FA48854 +:1096D00096934E27000CA48850217FCE9693AC8899 +:1096E000A48896934E240003AD48A4488C02964B60 +:1096F00088615A0840EA84403C3FFB624402DD0036 +:1097000080628421F85E8400EB47EB04F86D8420CE +:1097100080814402A82AEB2A4432D85884A1F85FF9 +:109720008400EBB0EB2AF860D5615A6801604452BE +:10973000A69A443D5AF64442DE7C84C34422A82AB9 +:10974000982B38120011A4289603E020E909EA2F8B +:10975000C80340109836A4288A019603AC288CA22E +:10976000DAF084214402A69A4432D8D0808180A1C4 +:10977000EB04F83584003C0FFB6E3C4C020D80601E +:1097800080A02E2010E59860C20FA48896934E27E3 +:10979000000CA48850217FCE9693AC88A488969321 +:1097A0004E240003AD48A4488C02964B88615A08A9 +:1097B00064EA842180413C3FFB6E4402DD0084600A +:1097C00049FFE2048401EB47EB04F80E84214402D4 +:1097D000A9BAEB2A80A14432D858848049FFE51009 +:1097E0008401EBB0EB2A49FFE2DAFC80FC00443252 +:1097F000C12A4402D8D0EBB04422E570490038F5C4 +:10980000EA60EB472E27EC5A49005064EA60EB47C8 +:10981000EB048461F805EB2A8460EBB0EA6049FF51 +:10982000C06DEA6049003BB32E17E0E1EA604900F1 +:1098300052EBEA60490044BBEA6049003BEEEA6053 +:10984000490047D4EBBDC0035A08050D84013E0012 +:1098500010E63E0010E584003C080875841F3E00B9 +:1098600010E12E0010E15A00FF0684003E00111C9A +:10987000D50484013E00111CEA602E17E0E1490086 +:1098800053BE8401FC80FC002E07EC44C803EA3779 +:10989000D5068401EA3784003E07EC44DD575A08B8 +:1098A000120AEA6C842FEA7F5A080105840FEA4EF7 +:1098B000EA71DD4C8421AE40EA885A080108DD4097 +:1098C000A6015A080A0449000F43FC80DD9EDD9E74 +:1098D000FC002E07EC5FC830EAE5C81B2E07EC95AC +:1098E000C8182E07EC98C8154900066E5A080208D9 +:1098F000FA02DD4284013E07EC98D50B4402E19C5C +:109900003C13960E4422C159490009455A0002F2FF +:10991000DD40A6412E07EC985A1006045A180B0F8A +:109920005A0001082E07EFC65A000104EBDAC00402 +:109930008401EA3CEA698401D5245A00010A2E0711 +:10994000EFC65A0001062E07EC765A0801F6DD44F0 +:10995000DD43AE40DD56A608C0FF84003E07EC980C +:109960003E07EFC68401EB41DD575A08120AEA6C44 +:109970008425EA7F5A0801058405EA4EEA718402CB +:10998000FC80FC00EA2B5A08010A44020400501033 +:10999000002850200050490028D1DD404412C470F6 +:1099A0002E27EC952E37EC612E47EC3C49FFEE5DFF +:1099B000EA885A080107EBBB5A080104490008D19C +:1099C000FC80FC2084C02E07EC5DE2C0E82C3C0C3F +:1099D000013395F138501901DE243C0C0136442244 +:1099E000D6CC98473C0C0135A649380019113C30BB +:1099F000048C49FFDCBC3C1C013388E1A478FE0FD9 +:109A0000AC383C0C0135381019013C0399CEE220EA +:109A1000E8082E07EC3C5A00FF058C013E07EC3CA1 +:109A20008CC1D5D2FCA0FC00DD40A6015A00030584 +:109A3000F856E603E906DD575A0005045A08120AEB +:109A400084003E07EDD43E07EDD53E07EDD6D54F59 +:109A50003C0DFB815A0801078400EAF64402C2A0CB +:109A6000F8214402E1D04412C2AC49004AF73E0753 +:109A7000EDD6F8355A080321EB89EA7E49FFEFDE7F +:109A80004460005F8401844080608080842C80A2D8 +:109A9000DD533C0DFB815A0801098400EAF64402BB +:109AA000C2A049004758D5048EC197B0CEECEB89CF +:109AB000EA7E49FFEFE84900476880C05A08011074 +:109AC000F80E5A0803078006EB5444000061DD429B +:109AD000F8065A08040D8401EB54D5094900475291 +:109AE0005A0803068400EA2C8401EA69FC80FC2001 +:109AF000EA655A0801064402C0F08422EAF44402EE +:109B0000DDE849FFE53FEA885A080109EBBB5A083E +:109B100001064402DDE849000837EA7D4412C20C20 +:109B2000442200008460848549FFDCFBDD575A082D +:109B3000120AEA6C8423EA7F5A0801058403EA4E7C +:109B4000EA718400441201D03E07EC7D502080145D +:109B50004402C470490004D52E07EC7DC8074402B6 +:109B6000C4704412DDF4490004DF2E07EC7DC048C8 +:109B700084003E07EC64DD575A08120AEA6C84241C +:109B8000EA7F5A0801058404EA4EEA71EA2B5A007A +:109B900001062E072BD25A0801064402019C4900F7 +:109BA00029E13C0C024E4412D9983C20048C4432EA +:109BB000C12D8481EBE62E072BD15A08011AEBDB6D +:109BC000B40096045A0001083C0DFB57A600960409 +:109BD0005A08010FEB68C80C4402D9984412DDF40E +:109BE0004422C12D490003B43E07EFA2D5068400EC +:109BF0003E07EFA24900027049FFFEE5D50DEAE5F8 +:109C00005A0801064900025E3E07EFA284003E07A3 +:109C1000EC5D3E07EC3CEA655A0801064402C0F0E0 +:109C20008423EAF42E17EC5D2E07EC953E07EF7BBC +:109C3000C9043E17EC95D5094402D9984422E22480 +:109C40004432C165490037C52E57EC95C53D2E27D6 +:109C50002B622E372B63924192614402E2248420CE +:109C6000E225E80BA5008C218882AD00A5018C08B7 +:109C7000888312407FFDD5F58400EA2CEB1A3E075D +:109C8000EC89EBB3DD40A6015A080317DD5F5A08E3 +:109C90000411EAACC805DD578E04E602E9052E077B +:109CA000EC755A0801078404EA41D5655A08046432 +:109CB0008400EA41D5605A080A5FDD5F5A0805F85A +:109CC0008401EA41D558EAE5C8562E17EF923E07BF +:109CD000EC5D3E07EC95EB663C0FFBEE5A1001097C +:109CE0003C0DFBEB4420EA60E240E9038C01EA2CE6 +:109CF0003C0DFBEC4420EA60E240E90D3C23F7C652 +:109D00003C33F677E262E802C1048C01EB1AD5031A +:109D10003C1FFBECEAAC5A08010F84203C1FFBEB14 +:109D20002E17EF83EA3C5CF08032E80A8C213E1764 +:109D3000EF83D50684203E17EC4E3E17EF832E1797 +:109D40002BCC5A180119DD54A6495A1003045A188D +:109D50000A132E17EF845A1801093C1DFBECE6226A +:109D6000E804C8033E07EF848400EB29490027CCB0 +:109D70008401EB29DD5A5A080207490045F8C0035F +:109D80008400EA2C49FFFDA65A080204480000DBC3 +:109D9000EAE55A0801058400EA2CEB1A49FFFDF3B5 +:109DA0004402E2242E17EC954422E6884432D998E6 +:109DB00049004996DD575A08120AEA6C8426EA7F60 +:109DC0005A0801058406EA4EEA71EA655A08010656 +:109DD0004402C0F08424EAF42E072BDB5A0001076A +:109DE0002E272B39EAA58420D512EAA54412D9984A +:109DF0003C2C024E49FFC043D50CB460C305A4C23D +:109E0000ACC6A4C3ACC78C2150000044E222E9F6E2 +:109E1000EAA52E172F0149004EF9EAA549003DB9E0 +:109E2000DD575A08120AEA6C8427EA7F5A080105AE +:109E30008407EA4EEA71EAA549FFE832EA885A083F +:109E40000117EBBB5A0801144402D9984412E68862 +:109E50002E27EC954432C1EC490004D64900067E19 +:109E60005A0801064402C47049000C6684203C1F55 +:109E7000FBE22E672B393C7C01343D0C0135EAA511 +:109E8000808186214520FFFF453000FFE286E83BC8 +:109E9000B440C22BA147383395011310000B5CF17D +:109EA00081004039BC1A1230000A04300009E22354 +:109EB0004011BC1B5A2003245A2005220220001EF8 +:109EC0000230001FE262E8031220001F1220001D72 +:109ED00038281501025000201220001E4C59001095 +:109EE0008CA112500020D50B1220000A1220001D58 +:109EF0001220001E1220001F122000208C81500012 +:109F00000044D5C53C1FFBE249FFEC63DD5A5A0013 +:109F1000020549FFFD8AD504DD475A0802FC2E6779 +:109F20002BCC5A680112EAE9C810DD5A5A08010E12 +:109F3000DD40A6015A00060A5A000B0849002CFA17 +:109F4000D50480C0D50284C18006FCA0FC00EB6370 +:109F500080C0840CDD50DD44DD43AE4084094410F4 +:109F600000A1DD4549FFED768409EBCADD45DD4002 +:109F7000A6415A100D0B2E17EFBCC9074412C1653C +:109F80004422C470490030328409441000A3DD45E6 +:109F90002E07EC375A08010BDD44DD43AE40840147 +:109FA000EB4EC0FE8402480000868409EBC5DD4507 +:109FB0004402FEF2A600C007DD40A6415A18030481 +:109FC00049FFCF768409EB7EDD452E07EC8E5A08DB +:109FD000010D4402C15E3C1DFB4EEABD3C3DFB57FA +:109FE0003C4DFB5549FFD524840C00130050DD4542 +:109FF000840D00130051DD45840E00130052DD4531 +:10A000003C0DFB94C035840B44100087DD45840073 +:10A01000EABB3C0FFB94EAFD5A08550EEB79DD5480 +:10A020004422C1133C3DFB4E4442C29849FFD6C076 +:10A03000EAD2D503EA3AEAF3DD5749FFD0A3960006 +:10A040003E07EC305A0003375A080213DD44DD4363 +:10A05000AE40DD56A608C0FFDD475A0002A5DD442C +:10A06000DD43AE408401EB4EC0FE48FFFF9D8409F6 +:10A07000441000A6DD45DD56A6085A080206DD4C50 +:10A08000A6005A0002062E07EF9D5A080109840116 +:10A09000AE08DD59AE0884003E07EF9DDD40A60105 +:10A0A0005A000B0449FFF0838409441000A7DD45E2 +:10A0B0008401FC803C0FFBAFDD9E3C0FFBAEDD9EC0 +:10A0C0002E07F1BD8E019600EB8AC802EB352E07F4 +:10A0D000F1BCDD9E841F3C0FFA7E8400EB8AEB35D9 +:10A0E000DD9EFC63A1054022084001310000009183 +:10A0F000000100A1000200B100038620E1A34EF29E +:10A1000000E0A081385145014C58C0D8A105415804 +:10A1100088088895A7A0E4C3E9038EC3D50284C04C +:10A12000A7612E272B328CA3E0A2E9029F51A6A2A1 +:10A13000E443E9038E43D5028440A7232E772B33D3 +:10A140008C83E087E9029F39E1264EF300B7E0B344 +:10A150004EF300B4E1624EF300B1E08A4EF300AE7C +:10A1600042634C004252A40142422C01F681F58226 +:10A1700042212800F483F403E0824EF3009FE4447C +:10A1800085A0E90350D17FFD9D13F701F485F4020A +:10A19000E0874EF30090EB434453F04AAF283C4D28 +:10A1A000FBAE80A7008200020560000042512073D0 +:10A1B000385B15005A50FF7C05700001385B951123 +:10A1C0004E540076E4E484C0E9029FBB058000059C +:10A1D000A763410C540000E8000140F71807E96745 +:10A1E0009D3B51247FFF83C4424248010128000067 +:10A1F000E092E95D00C8000340F63407E95804FF27 +:10A2000080058EA10108000242579401E0B0E94F99 +:10A2100043E238013C40048C4306C000838442483A +:10A220002024432348004252B001F4848680E0B0E9 +:10A23000E93EF40481D288948892952140FF380742 +:10A24000E932386B10005A60FF2B419B982002CCFA +:10A25000800040F600114EF5002304F0800540F721 +:10A26000900002F7800040F7801140F7F007E917EF +:10A27000442F800040260804122C8000406C1840B7 +:10A28000A6B043398801A6B142948800A6B242A57F +:10A290000801A6B342B5880048FFFF3150E700012E +:10A2A0008C82D5CD8D81414A2000D5C28CE148FFFA +:10A2B000FF708C4148FFFF618DA148FFFF21FCE347 +:10A2C000FC20A612C0038E01AE123C7DFBAEA7534C +:10A2D000A63B8E01D0038CA1AF53A610C0038E0104 +:10A2E000AE10A63AA7518E01D0038CA1AF518400C5 +:10A2F000A750011100018060E3A5E922A792012186 +:10A300000003E3C6E91BA73A81E542F31073050099 +:10A31000800540483C20EB5341080011E59AE90CC8 +:10A32000EB5302F200004108001140F78011E06F8A +:10A330008810E802A4E08CC1D5E58CA1D5DEC30667 +:10A34000441001F4FE0C40000C17FCA0FC4280C03D +:10A35000841F3C0FFA7E3C0DFBAFF181A64380E2E7 +:10A360005CF08042E90444100041AE43A6405CF03A +:10A370008042E90444100041AE40A64000A0000322 +:10A38000440003E8FE0C40900013A638C027844028 +:10A390003C1DFA7E80A2E0A0E80FA0F138319501C3 +:10A3A000DB09A0F238319501E2434012BC1B402189 +:10A3B000BC1B8CA1D5F1A0353C1FFA7E3C2BF6626C +:10A3C000401004403A008000B0433A008020F10180 +:10A3D0008006B083F868E320E96A2E17F1BC5A18AA +:10A3E0000104A678C964441003E842150424964980 +:10A3F000E220E9038420D5703CADFA7E442F800032 +:10A40000840040250804A6F8E003E80AA071401083 +:10A410008020A5484C554003AC888C01D5F58006BA +:10A42000F101542500FF49FFFE5EA0354010284091 +:10A430003A108400B0833A110420A6F88C038420DB +:10A44000E023E82EA0B13851050196AB4E2400263A +:10A450005452FFFF4C550022D92000207FFD004FB1 +:10A46000800CE282E903102F800C00207FFE004F59 +:10A47000800DE244E903102F800D00207FFF004F84 +:10A48000800EE282E903102F800EA680004F800F1D +:10A49000E244E903102F800F8C218C04D5D2800672 +:10A4A000F101B08349FFFF0EE320E8098401EB3599 +:10A4B0003C0DFBAF8421A601EB8AD50E8400A67863 +:10A4C000E001E899A07140108020A4888C015421FB +:10A4D0007FFFAC88D5F52E07F1BDC00B5A180105DA +:10A4E0003E17F1BCD5068E019600EB8AC802EB350B +:10A4F0002E07F1BC5A0801048420AE78FCC2FC008F +:10A500002E17EFBC3C0399D15A1001049680D50256 +:10A51000A6943C0C024E4412D9984432C14D84801A +:10A52000EBE6FC80DD402E472BEEA6015A00060428 +:10A530009721D5032E472BF02E07EC802E272BF5E5 +:10A54000E202E8068C013C4395FB3E07EC802E2797 +:10A55000EC642E072BF42E372BEDE240E92F2E076B +:10A56000EC655A080130FC2040000C0C8A0496016E +:10A5700084E0EB1CE2E2E821A18AB44194F988C3AB +:10A5800088430303000004508014A49088A3FEA411 +:10A59000A4E8422040738CE188432E372BED4031F4 +:10A5A0000C0D96D9ACF0A4F02E672BED4031980C31 +:10A5B0008A439691ACA8D5DEFCA08C413E27EC6482 +:10A5C000DD9EDD9E2E172BD75A1001048401DD9EDF +:10A5D0002E07EC7DC84344326EB880803C1395B2A0 +:10A5E000E201E8213C1C024E40108020A4883C136C +:10A5F00095FE9693FE4AE041E8119883A6508C217F +:10A600009648AE50A6903C1395F9E241E9093C13F7 +:10A61000F6658C213C1BF665D5039843AF088C0189 +:10A620009601D5DD3C03F6653C1395FFE220E8CFAB +:10A6300084203C1BF665840044326EB8EB1CE202B9 +:10A64000E80698838C01AE509601D5F92E07EFC02D +:10A650008C013E07EFC08402DD9E84003C0BF66552 +:10A660008001DD9EFC204440271080C0FE64220053 +:10A67000002840208856FE24221300502233000078 +:10A68000EAE7E022E85140F00DF6E04FE84F445091 +:10A690000078FA788024991D4002040A5CF0005189 +:10A6A000E904524000A0D50480805A002805527069 +:10A6B0000078D503447000503843111138731D11D0 +:10A6C000FF0C40421C96E044E8039F41D504E08221 +:10A6D000E8309CC1E0A3E8E04C01800380A35CF279 +:10A6E0008051E904521280A0D50280255072802842 +:10A6F0005CF38051E90352728078381305114430BD +:10A700002710FECC38131D118A82EB389A9A4242E8 +:10A71000000342210003E082E90CE044E909E2057C +:10A720004002BC1AFCA0FA18FCA0EBBAFCA0800501 +:10A73000FCA05CF00051E905523000A0B661D502E2 +:10A74000B60150107FD85CF08051E905520000C876 +:10A75000B602DD9EB622DD9E3C0FFC70DD9E4402FB +:10A76000EAAC8420AE40AE41AE42AE43AE44AE450C +:10A77000AE46AE47DD9EFC01F081F80740000009BF +:10A78000F0019E41F181C8FBDD43DD44AE4083FF13 +:10A79000FC81FC02F081F001441003E8FE0C501033 +:10A7A0007C5E4603A19650000B1F4200806940006A +:10A7B0009409F083F001C802D509EA3EF0039E41F6 +:10A7C000F183C8FCDD43DD44AE40FC82FC02F08135 +:10A7D0008400F083D50ADD43DD44AE40440003E845 +:10A7E000EA3BF0038C01F083F103F001E220E9F48D +:10A7F000FC823C0FFC79DD9E3C0FFC78DD9E3C0F1B +:10A80000FC77DD9EFC4084E03C2DFC7980C1808794 +:10A8100080A7862504F30000E81250F7FFFC5CF7E0 +:10A820008002E90D052300070500000238F8490100 +:10A8300001210006E3CFE80311118002B5865128FB +:10A840007FFFE7C2E9035B0804058C81972080E560 +:10A850008CA19768506300445A580ADE2F17F1FB09 +:10A86000CC0684008420AE1A80A1D51FA61A5A00F7 +:10A87000051B5A4801145008FFFFE602E8042E5752 +:10A88000F1FADFF044000044421380738401225047 +:10A89000800422108005AE1AD50884038420AE1AE5 +:10A8A00080A1D503842080A1A61A5A0801263C6DF8 +:10A8B000FC77A7B35A6801213D2DFC780269000995 +:10A8C00051337FFF0269000250937FFF84C2410928 +:10A8D0009A164302A47340584CB70309000A03298F +:10A8E00000038F818FC1406818D64260C873976B90 +:10A8F00040134037964BE7A5E81844F0A7083917EE +:10A90000C40040F8BC00DD0F060C0C161C005A08F1 +:10A91000010BD5105A00010CC80C8403D50BE602BC +:10A92000E808D503C806D5068400D5048402D502FC +:10A930008404EB3C8E01E60484C04EF2008E44F0A9 +:10A94000A74CEB0C40F03C004A003C0008003200F1 +:10A950004E0004018400446FFFAAEBEF3E67E9FC60 +:10A960003C5BF8FA3C1BF8FB3C5BF8F83C1BF8F945 +:10A970003E07F1EE3E77F1FA3E07F1ECD56F2E0778 +:10A98000F1EE0261001AE206E8048C013E07F1EEE6 +:10A990003C5BF8F83C1BF8F9D5612E07F1EF5A083B +:10A9A00001282E17F1EE0201001AE220E8212E17ED +:10A9B000F1ED0201001BE220E81B2E07F1ECC818A4 +:10A9C0003CF7F8F43C07F8F8021100198A0F42002E +:10A9D0000003E001E80D3CF7F8F53C07F8F98A0FB1 +:10A9E00042000003E001E80484033E07E9FC2E175F +:10A9F000E9FC84003E07F1ED5A1003313E07F1EF08 +:10AA00002E07F1ECC82B3C07F8F90211001EE001FB +:10AA1000E91D0211001FE020E9193C17F8F8025166 +:10AA2000001CE025E9130251001DE0A1E90F2E678B +:10AA3000F1EE0251001AE2C5E81184A13E57F1EF90 +:10AA40003C1BF8F43C0BF8F5D5098402AE1AD50688 +:10AA50003E67F1EFD5033E67F1FB84003E07F1FC52 +:10AA60003C03F8FCCC052E17EFA25A18010FA45492 +:10AA7000E201E8048C01EBEFD52084013E07F1FCF4 +:10AA80008404AE1AEB3CD5192E17F1EF5A18010EBB +:10AA90002E17F1ED0251001BE225E8058C213E172F +:10AAA000F1EDD5033E47F1EFA454E201E904EA38A1 +:10AAB0003E07E9FC8400EBEF2E27E9FC5CF1002067 +:10AAC000E81F8C4C96908401E65EAE18AE99840126 +:10AAD000E904FA2EF803D504802249003F4A840392 +:10AAE000EB548400EB3CEA383E07E9FC440000608C +:10AAF000DD422E07F1D88C013E07F1D8D503840042 +:10AB0000AE183C0DFC793C1DFBEBA404E220E904EB +:10AB100084003E07EFBCFCC0FC0084004412C1EC82 +:10AB2000442FFFAAAE08AE0AAE8984203E27E9FC76 +:10AB3000EB3C3C1BF8FC3E17F1FC3E07F1EF3E07F7 +:10AB4000F1EE3E07F1ED3E07F1FA3E07F1ECFC8035 +:10AB50003C0DFC79A404DD9E2E07F1FCDD9E2E1732 +:10AB60002B3984004432000084819680E241E8065B +:10AB70009883104103EC8C01D5F9440000DC3C0BB8 +:10AB80009795DD9E3C13968CAC40DD9E3C0FFBB14F +:10AB9000DD9EFC002E572BE05A5001048401FC80FE +:10ABA0003C3DFB49A6D95A3009045A3804193C33B4 +:10ABB000960D994BE2239769E8049A599649D50274 +:10ABC00084202E47EC58A0C2A0034031907740006B +:10ABD000101796D996012E472C27D51B44338D404C +:10ABE000A718CCDD3C33960C994BE2239769E80417 +:10ABF0009A599649D50280242E67EC3BB460A00197 +:10AC000040319877400018172E472C2696D9960188 +:10AC100044F002004252BC01E2A3E805A6108C01F8 +:10AC2000AE10D505E201E9FB8400AE10DD40A601BF +:10AC30005A0804048400AE10A610E280E8B0840034 +:10AC4000AE102E07EFC18C013E07EFC18402FC80DD +:10AC5000FC2005008013006F8018011F801C550820 +:10AC60007FFFCA0F8381BE1244220168B913EA5ADA +:10AC7000406118405420FFFFA6749648CB16D52497 +:10AC8000447200004103C04045200064E2D1E8EB7B +:10AC900080F04273487351338064182380014C79EB +:10ACA000FFFE8CC197B0D5F344600064FE74401081 +:10ACB000884044620064442200008841882618319C +:10ACC00000014C20FFFEAD00AD41FCA0FC20F608C9 +:10ACD0005A60010B4462DE5C387304004462D90898 +:10ACE00039130400D503862284E98380B912450212 +:10ACF00000005460FFFFFA38FE7CBF1440109840FB +:10AD00004063C00954737FFF44600060883042682C +:10AD1000982440631C40A7CFAFD8A6CEAEE0A6CC07 +:10AD2000AEE8024000300230800D02000030021018 +:10AD3000800C88648801F406F1074008002088D060 +:10AD400040380C20B664B601B406920A9637AE10AD +:10AD5000FCA0FC408380BD14B814446000485452E9 +:10AD6000FFFFEA48FEF4FF34404200404031944087 +:10AD70004452000088A484008A64386194003860DA +:10AD8000810908628001386101098C015A0832F793 +:10AD900044020034888084A0852339319002411018 +:10ADA00094000D2200014101140084E04203A42418 +:10ADB00002A880004069800D9797406519001A68C5 +:10ADC00080014009000D0268000096174003010051 +:10ADD0008CE11A0800015A780AEB8CB45A5864DFE7 +:10ADE000FCC004000013EB59FEE4EA484001804037 +:10ADF00044320000886084009908A76138408000D0 +:10AE000040424008404217009950A769404215004F +:10AE1000385100008C028885AB195A0832EFDD9E4C +:10AE200004000013EB59EA48FEE440318040EAAFE9 +:10AE300088608400A51938408008A75B9908AF6135 +:10AE4000B48338410008A319995092888C02AF2925 +:10AE50005A0832F2DD9E4412DE5C380080008E011A +:10AE60005C000009DD9EE201E80AA610E260E80449 +:10AE70009AC3AED0DD9E8400AE10DD9EE220E80BCA +:10AE8000A61052F180FFE00FE8048860AED0DD9E8E +:10AE9000841FAE10DD9EFC60EEA8F0858141F28437 +:10AEA00080E35A3801053C800B03D506F9164E02A3 +:10AEB00000A43C800B022E07ECAE84C1E602E9053B +:10AEC0008E014063000C97B04063280E97B0CE020D +:10AED00084C1B00A50BF8024505F8021F081F10509 +:10AEE000F004B088503F8022504F8023B77FF78214 +:10AEF00049FFFEEEF004B064B0BD003F8022004F79 +:10AF0000802349FFFF28F86F49FFFF8CB024812080 +:10AF1000B00B8380858044D000323855B2024400A3 +:10AF200065109928440073E840E28000420634240A +:10AF3000F08584E039049D015CF807FFE8492E178D +:10AF4000ECAF3932C101003F80208E214028040837 +:10AF500040098C164CA0C0158844A4508A08403083 +:10AF60008C768A68EB2242F00003E06FE90413312B +:10AF70000000D52E38074101380E1C08D5294EA3F4 +:10AF8000000639324109F810D5168844A4504030E3 +:10AF90008C76401020018A68EB2242F08003E06F3B +:10AFA000E90A1331000038149D01382E1C0038279F +:10AFB000050983FFF105B0CB98B988439601802835 +:10AFC0008066F487F58649FFFF50F407F5068CE1AB +:10AFD0005A7832B25094806451CE00325AC0010483 +:10AFE0008581D59CF004B04B502F805E003F8021BE +:10AFF00083FF49FFFEF8ED58FCE0FC61F08184011D +:10B00000B63F814280C3EA73DD475A0002048400E0 +:10B01000EA5EDD568401AE08DD59AE0884003C0FBF +:10B02000FBA02E07EFC75A08010684073E07ECAEC7 +:10B03000D50C5A6801072E072C213E07ECAED5052A +:10B040002E072C203E07ECAE2E07ECAE8C013E07FF +:10B05000ECAF44000060DD50DD475A08024D5A68ED +:10B0600001074413F423EA36EA33D50C44000061A7 +:10B070008520DD50816944C3F04A4480005585A194 +:10B08000D511A6085A0002F4AED0D5FC3C0DFBA0A9 +:10B09000C81CE9FD50048001549000FFDD4C10D025 +:10B0A00000002E07ECAFE320E8643CBFFBA2EBD32B +:10B0B0005A60010744000062DD5084E0D518800624 +:10B0C000EA23EA78C0FFD5F73CBFFBA0CE12EAA482 +:10B0D0008E0154E000FF800E49FFFEBFC008800EC5 +:10B0E0008029B45F80668CE1F82D97F8E2EAD5D22A +:10B0F0008007D5F746B000F484E044C3F04A4480AA +:10B10000005585A150B582402E07ECAFE2E0E83152 +:10B11000EBD3F8C244000061DD505A680105F0012C +:10B12000EB2FD506DD408420DD554900273444004F +:10B130000062DD5085204C95000D80098027B45FAA +:10B14000806649FFFEAA50548001549280FFD5F4D6 +:10B15000DD4C8CE1549380FF10D000005A6801064A +:10B160002E77ECAF4C93BFD2800BEB1080E9D5CD9E +:10B170008400EA738400FCE1FC212E07EFC7C806B7 +:10B180003C2396113C339612D503EAFA80432E07EE +:10B190002B5F84C0EA5C3C43960C3C53960DF081D7 +:10B1A00096904402EAD496D8B6DF49FFFD53DD47B6 +:10B1B00080E0EA5CDD405A78021B84488066F8250E +:10B1C0005A0801053E07EF92D54CDD408425AE417B +:10B1D00084213E17EF343E77EF7AEA348441DD4034 +:10B1E000EA5C8062F8123E67EF34D51B2E272B5F96 +:10B1F0008066F80BDD408429AE413E67EFBCEA343F +:10B200008441EA5C8062DD4049FFFEF9DD40802632 +:10B21000DD55DD40842AAE4184213E17EFBCEA347F +:10B2200084013E07EC4084033E07EF7A8407DD503B +:10B230008400EB41DD475A080206DD40842DAE4113 +:10B24000D50BDD408420DD552E17EC83DD405A18E8 +:10B250000203842AAE41DD40EA344400006FDD5031 +:10B26000FCA1FC00DD475A0802158400EB7784013D +:10B27000EA73DD43DD44AE40DD58A640C9FFA64079 +:10B280005A1801FFDD4C8422AE408400EA73D50BCE +:10B29000EBB4EB9CEB1049FFEA70DD408420DD55F8 +:10B2A0004900267944000065DD50DD41C00DDD44D4 +:10B2B000DD43AE4049FFBB9DC0FEEAA2EB1FFA5042 +:10B2C000EAEE49FFE4C1FC80FC24442166D8EB7D12 +:10B2D000444166E8B084EBB63B024C003B014C2095 +:10B2E000390102024421D80040210040A79080E1AA +:10B2F00097B0381F8202848045136510452262385A +:10B30000EB1CE282E81894E14021C4000331000004 +:10B310004021C800994BA490383810008C81FE9CC5 +:10B32000A4E84021180E8A539693EBC88843ACA832 +:10B330009721D5E744200C804431A20042300873A5 +:10B34000800349FFB6BEFCA4FC6184C08401EAC846 +:10B350003E67EC4E8126EA7380E6850485A644E3C9 +:10B360008D405A78040B8400DD548040EA433ED778 +:10B37000EF7A8581EA8DD50B80073E87EF7AF81941 +:10B380008180DD5484038047EA43EA8DDD4C8421CB +:10B39000AE409E39854054B000FF4CA60031DD58C8 +:10B3A000A640C9FFDD41C00EE2C9E80CC70B800B07 +:10B3B00049002056F0818CC1800BF10197B049FF04 +:10B3C000FF8500170000DD585A180312A6405A18CE +:10B3D00001FFDD41C007EA2A5A0806FFEAA2EAAAED +:10B3E000EA4F50048001549000FFD504A6405A183B +:10B3F00001FF5005000154A000FFD5D08CE197F863 +:10B400005A7805B18400EA738400FCE1FC454421CC +:10B4100066F844720000EB7DB042442167083B00AF +:10B42000CC20EB7DA6BA81208400B186EA4B38108F +:10B43000A602EB0BA6FB92413B034C20EB40EB0B2F +:10B4400038132602A6BAA6FBEB40FCC53C0FFBB2A4 +:10B45000DD9E3C0FFBB4DD9EFC008420DD55DD56F7 +:10B460008400AE08DD59AE088401EA2384018440DB +:10B47000842A8080806280A2DD53DD44DD43AE40BB +:10B48000EA78C8043C0DFB9FC0FCDD41C016840176 +:10B49000DD4ADD44DD43AE4049FFBAABC0FE840265 +:10B4A000DD4ADD475A000214EA22EB01AE08804172 +:10B4B00084618402DD46D50BDD475A000209DD4474 +:10B4C000DD43AE40EA22A6085A0832FFDD475A089B +:10B4D00002072E07EC468C013E07EC46FC8080A05C +:10B4E0003C0DFBB23C3C0255A6839222E2A2E82727 +:10B4F000CD09A4199649F829F8194EF2009448008C +:10B500000090F85D9F118805DC08F8469603E0205E +:10B51000F80A4EF30086DD9EF8684EF300828C0434 +:10B520008803F8724EF3007D884540218820A410DE +:10B530009603E02083FF4EF30074DD9E8483FF14A6 +:10B54000E2A4E926DC0DF8279603E0204EF300691B +:10B5500083FF9AAA4E00FFEB4EF30063DD9E951227 +:10B56000F82E8E818805DC05F817F80DF808DD9EA9 +:10B57000F83CE9568C048803A400F8059AAA4021F7 +:10B580008820A4109603E020E94B83FFDD9ED203C0 +:10B590009411D8139C2940018020A400964983FF70 +:10B5A0004E00FFF29A2A40018020A4004E00FFECDA +:10B5B00088454E00FFE6DD9EFC009F814607FFFFA9 +:10B5C000EAB383FF8805D6038E81DC0F4E00FFE5CA +:10B5D0009603E020E8048401EA3CFC80F812E9FCD0 +:10B5E0004E00FFA4E9F9FC8094019918A520964922 +:10B5F0009723E02483FFE9F08C048803F805E9EC45 +:10B600009A2A40018020A4009603E02083FFE9E409 +:10B61000982A402180204E00FF8CE9DEFC808401C6 +:10B62000EA3CDD9E2E17EC28C1092E272FB2E241FD +:10B63000E9048E219648D50284204422E9643831F9 +:10B640000501E260E92BFC20840038010509EAC508 +:10B65000842084A33C3C02533C0C02543C4C025CCE +:10B660009489886288028881A598A5C0A620880749 +:10B6700042031473404008099721AD183C4C025313 +:10B680003C3C025C8844A4908861400008419600DC +:10B690008C21AE185A18C8E0FCA0DD9EFC005A08A8 +:10B6A00001122E1011992E0011985A1801048E03C0 +:10B6B000D5028E0296008440802080624900084CAA +:10B6C000FC804900085BFC80A641EA805A180411FE +:10B6D0002E17EC36C903A602D502A6032E17EC934B +:10B6E0005A180208E604E9058E039600DD9EA604BA +:10B6F000DD9E540000FD5A0804053C03F901DD9E5F +:10B70000EA8002000009DD9E5A0804053C03F900A6 +:10B71000DD9EEA800200000ADD9EEA80A400DD9E34 +:10B72000B400EA80A447020000083C1BF9013C0B6E +:10B73000F900DD9E2E17EC2DC90984423E17E9D48D +:10B740003E27EC693E17EC4EEA49DD9EFC00DD44E5 +:10B75000DD43AE403C0DFB9FC810EA655A08010668 +:10B760004402C19E49FFE137840184408020806209 +:10B77000808080A2DD53D5EF8406DD4ADD41C01C08 +:10B78000EA22EA36EA33A6085A003204AED0D5FCE3 +:10B79000EA3DEA28EA2A5A000604AE88D5FC44129B +:10B7A000C2A4840280418461DD46EBBBC003840AED +:10B7B000D5028409EA39EA5D44100033AE402E0711 +:10B7C000EDD4C81149FFC4D25A00A10EDD4180203A +:10B7D000C807840280418061848380A1DD5349FFD2 +:10B7E000E7AAFC80840E49FFE04BFC80FC00DD47AB +:10B7F0005A0802074403F422A600961FFC80840026 +:10B80000FC80FC2084003C0BF67BDD4084233C7DE7 +:10B81000FB4884C1AE41EB91EA34DD4FA60084239E +:10B8200097F84900135A3C7FFB48EB86C80A2E075D +:10B83000EC70C8078409DD4A3E67EC813E67EC4046 +:10B84000DD40EA34DD5684003E07EC708401AE082A +:10B85000DD59AE08DD5F5A0004048405EA41EBDAE5 +:10B860008420C8093C1DFBB4A448E622E9038E22CB +:10B87000D50280203C1FFBEBEB375A18020FC8099A +:10B880003C1DFBB4A448E62AE9055000FFF6D502AA +:10B890008400EA2CFA18EAB784013E07EC8B840096 +:10B8A000EA98FCA0FC0084C03C6FFB84EAC8EB5122 +:10B8B000EB9E3E07EC288401EA23DD58AF80EB5174 +:10B8C000FC80FC00DD40A601EB0D5A080910DD5F8D +:10B8D0005A0004048405EA41EBDAC808F803E602DA +:10B8E000E90549FFF9378E02D5028400EA2CF818E1 +:10B8F00049FFE728DD408429AE418420DD55DD4045 +:10B90000842AAE41EA344900234684008421EA3780 +:10B910003E17EFBCEA9849FFF90149003FD249FFC1 +:10B92000E71FFC80EA803C3C0255A503842084018B +:10B930009899A4909693E082E80284008C225A1988 +:10B9400090F9DD9EFC202E17EC695A18020B2E1779 +:10B95000E9D4C9072E17EC918E225C108001D50224 +:10B9600084203C6DFBB23C4DFA803C7C025484A0A8 +:10B970008461864353300000A6B351138002510105 +:10B980007FFF4C58001D410104088F814C5800185E +:10B99000430148248F814C58001394928E41D20F5A +:10B9A000A4B8027880008A479693E00238221509ED +:10B9B000E903E053E8045A18010384628CA180F182 +:10B9C0005A58C7DC5A18011C401004098440FF4A29 +:10B9D00038720911E027E807A633880238F201110E +:10B9E000E02FE909E0E5E808A633880238020111F2 +:10B9F000E005E80284628C415A2895EC8003FCA0A3 +:10BA000084204422E964380105098C215A1808FD74 +:10BA1000DD9EFC4080E0A60080C25A08051E84011D +:10BA2000AE38DD4085203C9BF7BCA601EABEF81588 +:10BA30003C13F67AE62AE8058C213C1BF67AD513EE +:10BA40003C9BF67AA430E619E804EA588400F8052D +:10BA50008400AC30D508840049FFFFD48400AC30AA +:10BA60003C0BF67AFCC0FC01DD40A601EABEF08189 +:10BA7000F1014402C1614422C1B449FFFFCC2E1739 +:10BA8000EC918400EA913E07EC53C9033E07EC5564 +:10BA900084003E07EC28EA38EA87FC81FC20FD3070 +:10BAA000EB9E80A0A630AF70C508EBF284C0E22503 +:10BAB000E9059FA997B0D50280C5D01DDD475A087A +:10BAC000021B3C3DFBB28400A65B9449E001E80DFB +:10BAD0008387BA09BC0B944188418824A4488C010F +:10BAE0009649AC509600D5F13C03F65EC00E8E012F +:10BAF000EA91D50B4402E964385019014410FFFF64 +:10BB0000D1048CA1385019092E17EC554000980E1D +:10BB10009604C81B0513800A050380090453800B93 +:10BB200040380000A498404880009691ACA0A498AA +:10BB3000992896918C02ACA05A0990F48401406037 +:10BB4000180CFE773E17EC55FCA0FC002E272FB2F8 +:10BB5000441000FF4020880C4413F422A648FE93B2 +:10BB6000965F9690C1038E219648A78084A140429B +:10BB7000840CFF37972296E0AEC04C61800D4C31AB +:10BB8000000B88254052840CFF679768FF5D5C02BC +:10BB90008001FC808005FC80FC008400EA91EAC5FD +:10BBA000EA3CDD40A6015A080423DD5FC8094402CF +:10BBB000C12549FFFFCC5A0801048403EA41DD5F37 +:10BBC0005A08031E4402D9DC842044200320EA42A0 +:10BBD0002E07EC97C807EAB5A600962EC803840482 +:10BBE000D5098401EA418400EB17D509EBC7C804E5 +:10BBF0008402EA41D5042E07EC97D5F1DD5F5A089F +:10BC0000020584003E07ECB0840080804452E33C8F +:10BC10003C3C025294418861A4D83C2C025496D9F1 +:10BC20008841ACD03C2C02533C3C025488418823D0 +:10BC3000A4489649AC503C1C025C8820AF083842AE +:10BC400080088C015A08C8E6FC80FC208407DD4A85 +:10BC500084C0DD403E67EF34EA34DD4C84213E672A +:10BC6000EC46AE4084003C0FFB96EA6AEA8C3C2D21 +:10BC7000FB96CA098401AFF080208062808080A298 +:10BC8000DD53D5F6DD44DD43AE40EA78C80B3C2DEC +:10BC9000FB9FCA08840184278062808080A2DD53D4 +:10BCA000D5F58421DD40DD55DD41EA3DEA28C00EB1 +:10BCB0008400EA7AAE883C2DFB48CA2684018020A5 +:10BCC0008062808080A2DD53D5F7AE882E07EC5EBF +:10BCD000C0098401844080208062808080A2DD537E +:10BCE000D5F649FFE854EAF95A0803048402D5025C +:10BCF0008401EA7A4412C1F084013E07EC5E80417F +:10BD000084028461DD468408DD4ADD40EA34FCA01B +:10BD1000FC4080E184203E17EC4E4090080884C02F +:10BD2000E0C9E8143C2C025540211820A4909693B9 +:10BD3000E0E2E809FD0349FFFBD4EAA3C0043E6743 +:10BD4000EECCFCC08CC197B0D5ECFCC0FC6080E1AF +:10BD500080C04412DDF44402C0F849FFFEA1440053 +:10BD6000FFFF84A03C1DFBB4A97AA83B000080160D +:10BD7000E610E8045250001097688520FB804300CD +:10BD800040013D3DFBB23CAC02543CBC02523C8CF9 +:10BD900002553CCC02532ED7E9D42EE7EC912F2745 +:10BDA000ECB080494512E33C82890009800394C2CB +:10BDB000E043E85B4091040840452400A4E04005CE +:10BDC000A400A400FEEC42304073926496D9ACE02B +:10BDD00040342400892CA42002F480008A0F9603AA +:10BDE000AC18A4D8A40D96DBFE02E060E81A5AD085 +:10BDF00001045AE80217380888008C0196003808B8 +:10BE00008808A4CEE260E813A42086419601EABF28 +:10BE10002E07EECD394888088C013E07EECDD507B8 +:10BE200038088800C0048E0138088808A4E0A03AC9 +:10BE3000E203E803A420A83AA4E0A03BE260E80300 +:10BE4000A420A83BA03A3C37F67BE260E8033C0B19 +:10BE5000F67BA6315A08090502908003D5030290AB +:10BE600080048C419690D5A280293F27ECB049FFF1 +:10BE7000FF51DD40A6015A080907800949FFFD640A +:10BE80003E07EC69FCE0FC4080E0A60180C15A0856 +:10BE9000041F9E0CE604E90C5A100C0BDD5F5A00DF +:10BEA00004082E07EC365A08010BEB51D508DD418A +:10BEB000C80B3C03F7BC5A080108D5F48007EB2FE8 +:10BEC000EA7DEB93EB928400EB17D508DD5F5A0017 +:10BED000040649FFE43A8007EB2FDD414E0200796A +:10BEE0003C03F6724412E19C8C01EAC53C03F65E09 +:10BEF0008C01EA91800749FFFF2BEB2CA600C005BF +:10BF00008401EA3C8400EA2CEAA35A080114840064 +:10BF10003E07EC538400EBF24432E9648080968063 +:10BF2000E241E805384181098C01D5FAEA93DD4206 +:10BF3000D5242E97E9D45A9801159E34E602E911CA +:10BF40004402E19C3C13960F4422C12349FFF6238F +:10BF50005A080208FA01DD423E97EC4E3E97EC98F3 +:10BF60004412FEFCA6085A08A5098401EB41EA3CEC +:10BF70003E07EC988400AE08EBC7C82AA6385A08DA +:10BF80000228DD5F5A00010A2E07ECB05A0801189A +:10BF90002E07EC695A08011449FFFCC6C804EA3CA4 +:10BFA000EAC5D50D840184E0EA693E77EFA249FF36 +:10BFB000F093DD5F5A0802043E77EC91DD5F5A088A +:10BFC00002082E07EC695A0802048400EA3CEA38A9 +:10BFD000EA879E34E602E80CDD41C004EACFEA4E6F +:10BFE000EA718400EA3C8400EA91EAC5D5055A6802 +:10BFF00002048401EA3CEAAC5A080104EA3CEA691A +:10C00000FCC09200E60F4EF2007444F0BE14EA75D4 +:10C01000EA31DD0F102E46DA6298DADADADADADAA5 +:10C02000DADAA4008401EABAAE084423F249842291 +:10C03000AE504423F24AAE104423F24BAE50846417 +:10C04000D529841FEABAAE08EB90AE084413F24A31 +:10C05000AE08EBE8AE088448D53C8401EABAAE08E5 +:10C06000EB90AE084413F24AAE08EBE8AE08441376 +:10C07000F24CAE08D5318401EABAAE084423F24945 +:10C080008424AE504423F24AAE104423F24BAE5007 +:10C09000846C4423F24CAED04423F24DAE50442382 +:10C0A000F24EAE104423F24FAE50D51F8400EABAD0 +:10C0B000AE08EB90AE08D507EABA8400AE08845FFC +:10C0C000EB90AE884413F24AAE08EBE8AE08844128 +:10C0D0004413F24CAE884413F24DAE084413F24EB2 +:10C0E000AE084413F24FAE084413F250AE08DD9E82 +:10C0F0009200C102EA8696004413F251AE08DD9E1A +:10C1000040003C0892104423F244EBCDAC10923036 +:10C110004403F246AC40DD9E84214403F240AE402D +:10C12000EA28EA3DAE88A6405A1001FFDD9E44137E +:10C13000F258A448AC404413F25AA448AC4144130A +:10C14000F25CA448AC424413F25EA448AC434413EE +:10C15000F260A64810100008DD9EFC02F08180020B +:10C16000F383F18249FFFF50F001F10249FFFFCA5A +:10C1700049FFFFD4F00349FFFFDCFC82FC02F081A1 +:10C180004403F242F182F283AF40001F8020440357 +:10C19000F243AE404403F252ACC04403F254AD004B +:10C1A00084214403F256AC40001F80244403F24132 +:10C1B000AE40000F8028001F802C49FFFF9CF0013B +:10C1C000F102F203F30C49FFFFCAFC82FC203C6D34 +:10C1D000FBB597C4050300025510800F43085C09A6 +:10C1E00040781EE44273D809470FFF0F4273D40909 +:10C1F00051080FFF4073C0028E2A86404073C60468 +:10C20000E625A9F2132300031123000B4EF2007C54 +:10C21000012F8038011F8030010F8034007F802C77 +:10C2200044F0C02CEB18EA8B4A003C000606067668 +:10C230007600C003EB5CD5034021BC08F0079250A8 +:10C240009201AC32F00692A192011203000BF008A9 +:10C25000926192011203000EF009ACB09201120338 +:10C26000000F220F801E1203000C220F80201203E9 +:10C27000000D020F8022AD718C01ACF41123000C73 +:10C280001113000D1103000E1073000F1123001085 +:10C290001113001111030012107300131203000A8E +:10C2A000D532C003EB5CD5034021BC08F00A9250A4 +:10C2B0009201AC32840010030010840192819261DB +:10C2C000100300118400ACB0AD31ACF41123000CAC +:10C2D0001113000D1103000E1073000F1103001253 +:10C2E000107300131123001411130015110300160D +:10C2F000107300171203000C1203000D1203000E3E +:10C300001203000F4403F1408421AE40EA36EA33C1 +:10C31000A6405A180104AED0D5FCFCA044038CF012 +:10C320003C0FFBB5441FC6784403F142AC40840087 +:10C3300044138D08B6013C1DFBB5A80F3C1DFBB591 +:10C3400014008008DD9E84203C0FFB59AC43DD9E29 +:10C350003C3DFB59920192219241AC18AC59AC9AE8 +:10C36000DD9E3C1DFB59A6821020800CA683102068 +:10C37000800DA680A6011020800E1000800FDD9E8B +:10C380003C1DFB59A68210208010A683102080112E +:10C39000A680A6011020801210008013DD9E3C1D97 +:10C3A000FB59A68210208014A68310208015A68039 +:10C3B000A6011020801610008017DD9EFC01B63FFC +:10C3C000F28149FFFFD0B41F49FFFFDCF00149FFB4 +:10C3D000FFE8FC81FC24007F8060F081F182F28321 +:10C3E000001F803C002F8038000F8040006F804C81 +:10C3F000105F8016103F8014102F8017104F80158B +:10C40000101F801A103F8018100F801B104F8019CA +:10C41000CF08105F801E103F801C102F801FD50793 +:10C42000101F801E103F801C100F801F3C0DFBB59D +:10C43000104F801DF855B005B046B087F856F00192 +:10C44000F102F203F8573C0DFB59021F8028AC445F +:10C45000001F8054002F8044FE775263002040600C +:10C460009824001F80481060000A58108040FE5732 +:10C470001010000B221F802C1210000C221F802E87 +:10C480001210000DDD44DD43AE404403F140842131 +:10C49000AE40A6405A1001FFFCA4FC04F0819419A0 +:10C4A0009600F182100F80178422100F801B84C128 +:10C4B0003C0DFBB5103F8014104F8015103F8018C5 +:10C4C000104F8019103F801C103F801F104F801D9F +:10C4D000F283101F8016101F801A106F801E49FFF4 +:10C4E000FF34B005B046B08749FFFF6AF001F102A2 +:10C4F000F20349FFFF2F3C0DFB5984208449AC44D3 +:10C500001010000B1020000ADD44DD43AE40440350 +:10C51000F140AF80A6405A1001FFFC844403F1486B +:10C52000A6404403F149A600EBAE9601DD9E4410FF +:10C530000055DD43AE40EA76A6085A0001FF84218B +:10C540004403F380AE40EA28EA3DAE88A6405A1084 +:10C5500001FFDD9EFC004413F381A608EB0AAE0840 +:10C5600084004413F384AE084413F56BAE0849FF0E +:10C57000FFE0FC804453F381A72896D8544200F092 +:10C58000FEA7401104449688400100E496804403CD +:10C59000F384AEA8AEC0DD9E84004413F386AE08DB +:10C5A0004413F387AE08DD9EFC604403F38496D801 +:10C5B000AEC049FFFFBEDD44DD43AE404413F3800F +:10C5C000A6085A0001FF4473F3864463F38744933B +:10C5D000F04A44A0005544B3F380A6385A08010C31 +:10C5E00049FFFFDC49FFFFA5EBC0000580005A00B2 +:10C5F00001FED5F4A6305A0001F5FCE0DD9E441E94 +:10C6000000008801920296014413F3CAAC08DD9E33 +:10C610004413F280A608EA45AE08DD9E4423F2806A +:10C62000A650400080A49600AE10DD9E441E00007F +:10C63000880196814413F286AC884200400B441373 +:10C64000F288AE08DD9EFC60002000094473F28091 +:10C6500096D4A6B880C0662100020000000A4021DE +:10C660000C243C7FFBB7AEB89684A6388121EA82C1 +:10C6700040000844AE38A4704403F284AC40A031BA +:10C6800049FFFFD6001300084403F283AE4044A3E1 +:10C69000F04A44B000550003000B49FFFFC149FFB9 +:10C6A000FFB9A6389604C00410B50000D5FB4403BA +:10C6B000F2813C0FFBB65A980307A6404210880B44 +:10C6C000C1EBD5085A980105A600EA64D5055A9829 +:10C6D0000205A600EA9CC0E0FCE0C80844138D25D2 +:10C6E000A6088C019600AE08D50E44238D26A650D0 +:10C6F0008C219648AE505A0801074413F060A608F2 +:10C70000EA57D5064413F060A608540000FBAE08B3 +:10C71000DD9E96004413F068AE08DD9E4423F0537E +:10C72000A6509604EAC688019600AE10DD9E44131A +:10C73000F06AA6889604542100FEAE88A688880276 +:10C740009600AE08DD9E4423F054AC104403F0562E +:10C75000AC40DD9E4031C8084021898088024010ED +:10C7600004C084A54443F06D4403F06EAF603C1FE9 +:10C77000FBB83A100420DD9E84204403F06DAE40E7 +:10C78000DD9E4403F061A600EA64DD9E4403F0618F +:10C79000A6009207DD9EFC0049FFFFFAC80749FF8B +:10C7A000FFF25A0001068401FC808400FC808402B0 +:10C7B000FC804000808496004413F481AE08DD9E26 +:10C7C00096814413F48396D0A7089248AEC8A6C9B0 +:10C7D000AE89EB028801921096004413F485AE08EE +:10C7E000DD9E96814413F486AC88EB02880192109A +:10C7F00096004413F488AE08DD9E96814413F489B4 +:10C8000096D0A7089248AEC8A6C9AE89EB028801A7 +:10C81000921096004413F48BAE08DD9E96004413EC +:10C82000F48CAE08DD9E4403F482A640EA28EAC6F2 +:10C83000EBF4AE40EA3DAE88A640964CC9FEDD9EC4 +:10C84000FC004463F00EA4304200200BC0074413E8 +:10C850008D24F81C84084800007BA430EA92C85953 +:10C86000A430EA9CC00644138D23F8108403D56FCE +:10C87000A430EA64C00644138D22F8088402D56708 +:10C88000A430EAE4C00A44138D21A6088C01960066 +:10C89000AE0883FF8404D55BA4309604C04E49FFE4 +:10C8A0009EA0A4304200180BC836A4304200140BDE +:10C8B000C834A43042001C0BC832A4304200240B00 +:10C8C000C00B4403F064A640964CC12BA640EAC6B8 +:10C8D000AE408409D53CEB78A4404210A80BC92394 +:10C8E000A4404210AC0BC921A4404210B00BC91F98 +:10C8F000A4404210B40BC91DA4404210B80BC91B80 +:10C90000A400920FC01A84013E07EF6C840FD51F5C +:10C910008401D51D8406D51B8405D5198407D51738 +:10C920008409D515840AD513840BD511840CD50F31 +:10C93000840DD50D840ED50B4403F01AA400EA92A1 +:10C94000C00549FF9E4EFA01D502FA08842044230F +:10C95000F00EAC504423F01AAC50FC808421440308 +:10C96000F322AE40DD9E4413F323AE08DD9E440364 +:10C97000F323A600DD9EFC004463F540B6064403A5 +:10C98000F544B6204403F548B6404403F54CB66080 +:10C990004403F550B6804403F554B6A0F1044403B3 +:10C9A000F558B620F1054403F55CB620FC80FC6127 +:10C9B0004433F5044423F5024413F5033C3FFBBA2A +:10C9C0004433F50580C03C2FFBBD3C1FFBBC3C3F06 +:10C9D000FBB95A00030448000146DD414413F51A2F +:10C9E000C0048401AE08D502AE084403F578842063 +:10C9F000AE40843FAE40442FFFAA4403F579AE8099 +:10CA000084C1AE404403F500AF80840080208040A4 +:10CA10008060EA2E84234403F501AE408400802028 +:10CA200080408060EA2EEAFEA608EA81AE08840013 +:10CA3000802080408060EA2E44000802EA3B3C1DD2 +:10CA4000FBBCA608EA81AE0884008020804080609C +:10CA5000EA2E4400041AEA3BDD444403F509AE40E3 +:10CA60008400802080408060EA2EEAFEA608EA4525 +:10CA7000AE083C0DFBBCA68058210001AE80A68804 +:10CA800058210004AE88A68058210004AE80A688F4 +:10CA900058210008AE88A68058210008AE80A688DC +:10CAA00058210010AE88A64058108010AE40840077 +:10CAB000802080408060EA2E440005AAEA3BEAFE1E +:10CAC000A608EAEBAE083C1DFBBCA608EAEBAE08E4 +:10CAD0008400802080408060EA2E2E07EC6C4E039C +:10CAE0000117DD403E67EC6CA601B61FDD47DD5443 +:10CAF0005A0802058404AE09D5038409AE098501EC +:10CB0000DD403E87EF34EA343C2DFB61440201688E +:10CB1000046100128420EA5A4060184004A3000314 +:10CB2000049300034005100954A000034004980931 +:10CB3000960F3E17EF34F081A1F3A03344B3F68093 +:10CB400066000030EA79A833A033FA6F660000C0AF +:10CB500058000080A833A03392E866000300580014 +:10CB60000200A83304410013844C929054027FFFCA +:10CB7000A73597CFFF1440420040EAAF40E20000E3 +:10CB800004D700004608000804C7000140068002E0 +:10CB9000B60E460F000F40060002140700014423A2 +:10CBA000F683841F10858000AE104423F684AE10F7 +:10CBB0004423F685AE104423F686AE104403F68770 +:10CBC000AE404403F688AE404403F689AE404403C9 +:10CBD000F68AAE40840080208040EA2E4403F40BA5 +:10CBE000A64044200039548080FF4413F415AE88D9 +:10CBF0008424AE408401EA23440005AAEA3BDD44D4 +:10CC0000DD43AE40EA78C0FF840085208020109587 +:10CC100080008040FA6FEA2E4403F415EB6F440362 +:10CC2000F40B10800000A0336600003040A0288480 +:10CC300014A30003A033F101660000C0409004C4B7 +:10CC400014930003A0336600030040701D04A9F391 +:10CC5000DD40001F800014D7000014C70001AE4162 +:10CC6000D556C83184414413F500AE88844344133B +:10CC7000F501AE883C2DFBBD8060A65058108002A7 +:10CC8000AE503C2DFBBCA65058108002AE50802008 +:10CC90008040EA2EEAFE8066A608EA57AE083C0D00 +:10CCA000FBBCA68058210004AE80A688582100084D +:10CCB000AE88A640804658108008AE408006802688 +:10CCC000EA2ED5255A080124A6D0A608543180F3AF +:10CCD000540000F3AED0AE08840080208040806015 +:10CCE000EA2E84004413F500AE084413F501AE08A3 +:10CCF000EAFEA608EA46AE083C1DFBBCA608EA46CA +:10CD0000AE088400802080408060EA2EFCE1DD9E39 +:10CD100046108000EB14EAEA4210EC0940008364FC +:10CD2000EA70DD9E46100800EB14EAEA4210DC09C6 +:10CD3000400082E4EA70DD9E44110000EB14EAEA50 +:10CD40004210C00940008204EA70DD9E4410800059 +:10CD5000EB14EAEA4210BC09400081E4EA70DD9E6F +:10CD60004410020064132803641308026610820052 +:10CD700040008124EB3A4413F7EFA608960096840E +:10CD8000C203EA8FAE08DD9E8422EB14EAEA661045 +:10CD9000800240008024EA70DD9E64120002C0041C +:10CDA00058008001D5036600800164020003DD9E07 +:10CDB000DD9EDD9EDD9EFC4080E04403F040A780C8 +:10CDC000812181425463001C5A780225DD41C01440 +:10CDD0004422FEF64433F04AEB43A6104412FEF61A +:10CDE0005A00EC04AF18D5FA8400AE088041846183 +:10CDF0008402DD46D50A4412FEF6440FFFECAE086D +:10CE0000804180078461DD46EA5DFA30AE408400EF +:10CE1000EA5E8400EBFFAC08FFBF4413F01AAC08D5 +:10CE200097B04403F040AF80DD44DD43AE405A7814 +:10CE3000020A4410005AAE40490000F9C8FEEA70E8 +:10CE4000EB3A4413F0DAA608EB0A4025000496906A +:10CE5000AE88540480FF4413F0EDAE08DD44440373 +:10CE6000F041AE40EA3EEA3EEA3EEA3EEA3EEA3EB3 +:10CE7000EA3EFCC0400004A44423F0429600A6D041 +:10CE8000AE10DD9E965F9604400080844413F0430C +:10CE9000AE08DD9E4413F044AC08DD9E540000FD56 +:10CEA0004413F046AE08DD9E40003C089210443327 +:10CEB000F200EBCDAC1892304403F202EB5CAC40D4 +:10CEC00092504403F204AC80DD9E4403F20AA64073 +:10CED000EA28EAC6EBF4AE40EA3DAE88A640964C9E +:10CEE000C9FEDD9E96004423F206AE109648440328 +:10CEF000F207AE40DD9EFC00DD41C004440255B89F +:10CF0000FC80440215B8FC80FC00DD41C0044402F2 +:10CF10004A00FC8044020A00FC804403F20BA60095 +:10CF2000DD9E4413F208AC08DD9E4423F20AA650AD +:10CF3000964C400080249600AE10DD9EE608E82363 +:10CF400044F0CD4CEA75EA314A003C00080E141A50 +:10CF500020262C324403F20CD5154403F20ED512D0 +:10CF60004403F210D50F4403F212D50C4403F2141B +:10CF7000D5094403F216D5064403F218D503440339 +:10CF8000F21AAE40DD9E9200E608E82344F0CD9808 +:10CF9000EA75EA314A003C00080E141A20262C32A9 +:10CFA0004403F20DD5154403F20FD5124403F211D8 +:10CFB000D50F4403F213D50C4403F215D5094403ED +:10CFC000F217D5064403F219D5034403F21BAE4011 +:10CFD000DD9E92004403F0C4A600DD9E960044133B +:10CFE000F0C4AE08DD9E4403F0C3A600DD9E9600AB +:10CFF0004413F0C3AE08DD9E4403F0CEA4004413F6 +:10D00000F0D0A648400080E4441D020088015C0086 +:10D010000080DD9E4402FE00DD9E84214403F0F585 +:10D02000AE40DD44DD43AE40DD9E4403F0F4A60097 +:10D030009204DD9E4403F0F7A600DD9E96004413A3 +:10D04000F0F7AE08DD9E4403F0F6A600DD9E9600E4 +:10D050004413F0F6AE08DD9E4452FE004412FE3E3C +:10D0600018028001D9FEDD9EFC40440000FD49FF0E +:10D07000FFF54463F068EA7CEA85F803FA09EA3BC5 +:10D08000A6305200000149FFFB4644000492EA3BEF +:10D09000EA58D5F4FC0049FFFFE992004423F0C7A9 +:10D0A000A65096485A080105581080C0D502966FC0 +:10D0B000AE50DD9EFC00441005FC4403F0CEAC40B5 +:10D0C00084204403F0D0AE40840149FFFFE9FC8096 +:10D0D0004423F0ECA6509604541080FB400080449A +:10D0E000AE10DD9EFC0049FFFFF5FC804403F0CE4E +:10D0F000A4004413F0D0A648400080E4EA9AFE0D54 +:10D10000EAF2DD9E92024413F0E6AC08DD9E441381 +:10D11000F050A60858000080AE08DD9E4413F05081 +:10D12000A6089637AE08DD9E4423F050A650961709 +:10D13000541080F8FE47AE50DD9E4423F050A650B8 +:10D1400096175410808F40008084AE10DD9E4413EB +:10D15000F050A608EAA8AE08DD9E4413F050A608D9 +:10D16000540000F7AE08DD9E4413F051A608EA45CE +:10D17000AE08DD9EFC00840749FFFFD884204403ED +:10D18000F04CAE40840749FFFFDA84214403F04E9F +:10D19000AE4049FFFFEBFC8096004413F04CAE0814 +:10D1A000DD9E4403F04DA600DD9E3C0FFC82DD9E1B +:10D1B0003C0DFC82A600DD9E44030FA0EAAA3C0FB2 +:10D1C000FB6B3C1FFB423C0FFB4ADD9EC0045A0038 +:10D1D0000209DD9E3C0DFC82A6003C0FFA81DD9E1B +:10D1E0003C1FFA81DD9E40003C0892104433F1C49C +:10D1F000EBCDAC1892304403F1C6EB5CAC409250DE +:10D200004403F1C8AC80DD9EFC0044020000A6820D +:10D21000A6434403F1C2AE80EBFAAE403C0DFB6B7B +:10D220003C1DFB423C2DFB4A49FFFFDFFC80840094 +:10D230003C0FFB9B84214403F1C0AE40DD9EFC60AB +:10D240002EB72B322EA72B552E972B542E772B3300 +:10D250004E03007A2E0010E2C8113C00085650F030 +:10D260007FB05CF78BE0E8083C00085750F07FB0D7 +:10D270005CF79360E9038401D50284003E07F20461 +:10D280003C0DFB62EADDE807EA2FC01AEAD784CC3E +:10D29000C018D5165CF008FCE807EA2FC011EAD7E1 +:10D2A00084C4C00FD50D5CF00A8CE807EA2FC008D3 +:10D2B000EAD784C5C006D50484003E07F20484CFB3 +:10D2C0004413F1C210B080004413F1C310A08000D9 +:10D2D0004423F1C4441FAC48AC50443FA608442347 +:10D2E000F1C6ACD04423F1C8AC5096304413F1C120 +:10D2F000AE08F894DD44DD43AE40EB09A6085A00C1 +:10D3000001FF4403F1C210B00000EBFA10A00000CE +:10D310004413F1C4440FADD8AC08442FA79844136C +:10D32000F1C6AC884413F1C8AC0897B04403F1C10E +:10D33000AF80F874DD44DD43AE40EB09A6085A0027 +:10D3400001FFD5605A08015FEA55EADDE807EA2FD8 +:10D35000C01AEAD784CCC018D5165CF008FCE807E0 +:10D36000EA2FC011EAD784C4C00FD50D5CF00A8C37 +:10D37000E807EA2FC008EAD784C5C006D5048400B0 +:10D380003E07F20484CF4413F1C21090800044138E +:10D39000F1C3AFC84423F1C4441FAD10AC50443FA7 +:10D3A000A6D04423F1C6ACD04423F1C8AC5096308B +:10D3B0004413F1C1AE08F832DD44DD43AE40EB0961 +:10D3C000A6085A0001FF4403F1C2EB6FEBFAAFC0AD +:10D3D0004413F1C4440FAEA0AC08442FA86044131A +:10D3E000F1C6AC884413F1C8AC0897B04403F1C14E +:10D3F000AF80F814DD44DD43AE40EB09A6085A00C7 +:10D4000001FFFCE0FC0649FFFF013C0DFA815A00D8 +:10D410000F1096004413F1C1AE0849FFFF0ADD4426 +:10D42000DD43AE40EB09A6085A0001FFFC86FA3046 +:10D430002E372B32F1858422840084A1F187EB6B97 +:10D44000F083F084F086F088F089B67FF581F3826E +:10D45000F58AEB4580418083EA35FC86FC212E0766 +:10D46000EC6380E480C55A08010A8406441000E198 +:10D47000DD453C0C006AB606D55A9E0CE60250000B +:10D48000FFF8E9049680E642E81E9600E602E92EDF +:10D490002E07EF34C00B8405DD458406441000E2FE +:10D4A000DD453C0C0066B606D542F181DD47F10151 +:10D4B0005A0802F38406441000E3DD453C0C007C6E +:10D4C000B606D5355A180D258406441000E4DD450E +:10D4D0002E07EF7A8E01E606E81044F0D2E4EA75F2 +:10D4E000EA31DD0F1A060E24141A3C0C0066B6064B +:10D4F000D51EEAF5B606D51BDD4FA600C804EA66C0 +:10D50000B606D5155A080314EB1DB606D5108E2A9B +:10D51000E622E808EAF5B605441000E58406DD4594 +:10D52000D506DD4FA60049000BAAB606B406441284 +:10D53000FF80402008093C0FFB58B641041000084A +:10D540004422FF84966FB622A0014412FF88962FD2 +:10D55000AE08EACB4412FF89A0014452FF90920624 +:10D56000962FAE08EACB4412FF8AA001443D00701A +:10D57000920C962FAE08EACB4412FF8BA0014422F6 +:10D58000C3D09212962FAE084402FF98986B3811C0 +:10D590000400EADAD8FCEAE8B446EB0288229222D8 +:10D5A0009649EB76EAE8441E002088019202960133 +:10D5B0004413F400AC0897F84403F402AFC0FCA194 +:10D5C0009200FC204471672C38138602463000FF1D +:10D5D00040608C0292CC106000094060900910609D +:10D5E000000A38638A02462000F04073080292F075 +:10D5F00040138484FEE6926C1010000B4410FF0070 +:10D60000407304021030000EFEAE40321009FE6E70 +:10D61000952492E8979F40220A1592281070000CDA +:10D620001060000D1030000F1020001010100011BD +:10D6300010500012FCA0FC02444167183B024C0051 +:10D64000EBB6380F8000FE45380F8400FE85380F9A +:10D6500088005600000FFC82FC41B4A0EA66D04569 +:10D66000EB1DD0433C0C007CD040EBDCE608E83DF1 +:10D6700044F0D47CEA7540F03C00DD0F12622032A9 +:10D6800044265A08EACEC8338400EA54D530EB3B2E +:10D690008E02E602E82C8402EA54D5298405EA5475 +:10D6A000D5262E00111CC8238406EA54D5203C0C34 +:10D6B00003995A08030F3C10086FE622E8F6D516C6 +:10D6C0003C0C03995A0803F23C00086FE602E8EDAF +:10D6D0008404EA54D50CEB3BE602E809D5D6EACE41 +:10D6E000C0D48407EA54D5038401EA5404028014A8 +:10D6F000441203009210EA48EAC73C1C0398E62D46 +:10D700004EF2011144F0D51038178501EA8BDD0F78 +:10D710001A008A00E80028016401A401AE01B801E2 +:10D72000CA010202D40108020E022E17EF965A18FF +:10D73000010584203E17EF968420EA49841F3E00AD +:10D7400010F9EA2DC8083C0C011EEAC13C0C011F6F +:10D75000EB1BD5095A0801083C0C0120EAC13C0C1E +:10D760000121EB1BEB824491672C97C89648EAF0A5 +:10D77000EAF8842AB61F84468007F88838048202B3 +:10D78000F081EA5AEAAFB49FEAC4F5018426844ADC +:10D790008067F88C8400EA44F84E8421EA49EA2D37 +:10D7A000C8083C0C011EEAC13C0C011FEB1BD5094B +:10D7B0005A0801083C0C0120EAC13C0C0121EB1B7A +:10D7C000EB824491672C97C89648EAF0EAF88423E4 +:10D7D000B61F84428007F85A38048202F081EA5A60 +:10D7E00044020040B49FEAC4F50184228443806768 +:10D7F000F85D8405EA44F81F8422EA493C1C03953D +:10D800004491672C97C89648EAF0EAF88421B61F3D +:10D8100084428007F83B38048202F081EA5A4402CD +:10D820000080B49FEAC4F501842284418067F83EF9 +:10D830008400EA44480000778423EA49460000CC8B +:10D84000500002BCEAF88426B61F84428401F81E08 +:10D850004411672C38008202F081EA5A440200C069 +:10D86000B49FEAC4F501842284468461F81F8401D0 +:10D87000EA44D5588423EA4946000093500000AF9B +:10D88000EAF88426B61F8442840349FFFED6441179 +:10D89000672C38008202F081EA5A440200C0B49F2B +:10D8A000EAC4F50184228446846349FFFE8C840225 +:10D8B000EA44D5388424EA498404EA44D5338425EB +:10D8C000EA498400EA44D52E8426EA492E07EF96D9 +:10D8D0005A0801218400EBA0D51D8427EA4984055C +:10D8E000EA44D5208428EA49040280164412020042 +:10D8F000EA48EAC74624259F4613DA6050108E4551 +:10D90000502101BAA841A842A883A844A845A84626 +:10D91000A8478405EA44D5068407EA44D50384066B +:10D92000EA44FCC192008400EB6A84214403F403BE +:10D93000AE40DD9E4403F403A600EAF2DD9E4403FC +:10D94000F40CA6009600C8074413F3CFA648400085 +:10D950000406DD9E8401DD9E8400EA76EB6AAE0853 +:10D96000DD9EFC005A08010F49FFFFDF842A840076 +:10D97000EB0644138D463C0BF6673E07EC74AE088D +:10D98000FC8049FFFFEBFC804403F01DA680A6410C +:10D99000A6C040110504581084009688AE809228D5 +:10D9A000A681AE41EA284413F421F8065021000173 +:10D9B0004C21FFFE8440AE88442000004430000A21 +:10D9C00083FF502100014C21FFFEA6409648AE4047 +:10D9D000DD9EFC20DD474432DE5CEB2D4422E20478 +:10D9E0005A08021484004472D9BC4462E290445242 +:10D9F000E628F81238408008384280003841000894 +:10DA00008C015A0820F8FCA084004472E1E44462CE +:10DA1000E9444452D92838438000384180083843CB +:10DA2000000083FF384100083842800038408008F9 +:10DA30008C015A0820F2FCA0A6403E101198A64185 +:10DA40003E101199A6423E10119AA6433E10119B1A +:10DA5000A645A68440210500A647A6C6401185001C +:10DA60000030000900400008EAD93C3808D00030F6 +:10DA7000000B0040000AEAD93C3808D10030000C05 +:10DA80003E3011A40030000D3E3011A5EB99969365 +:10DA900096DC3E3011A6EB99964B4231840B3E301A +:10DAA00011A7EB993C2808CE4231880B3E3011A8D3 +:10DAB000EB993C1808CF42318C0B3E3011A9003055 +:10DAC000000F96DF3E3011AA0030000F92643E3006 +:10DAD00011AB0030001100400010EAD93C3808D6E4 +:10DAE0000030001300400012EAD93C3808D700305B +:10DAF00000150040001496CFEAD93C3808D8003011 +:10DB0000001592623E3011B200300017004000163E +:10DB100096CFEAD93C3808DA0030001792623E30DE +:10DB200011B60000001E962F3E0011B742012C0BCB +:10DB3000C006440FF000FE873C2808CE4200AC0B24 +:10DB4000C006440FF000FE473C1808CFFA003E0024 +:10DB500011AADD9EA4C0442200004412D660EA321D +:10DB6000B661A4C2EA321430800FA4C4EA32A8CA53 +:10DB7000A4C6EA32A8C902300008EA321430801084 +:10DB80000230000AEA32143080080230000CEA3217 +:10DB9000143080090230000EEA3214308011023055 +:10DBA0000010EA321430801202300012EA321430CF +:10DBB000801302300014EA32143080140230001650 +:10DBC000EA321430801502300018EA321430801620 +:10DBD0000230001AEA32143080170200001C402183 +:10DBE000004014208018DD9EFC00EAE83C2C006414 +:10DBF000EB02882292229649EB76FC80FC004423BB +:10DC0000F6AC4413F6AD5A080106AE108407AE0810 +:10DC1000D5048400AE10AE08840080208040FA6FE6 +:10DC2000EA2EFC80B44084A08C449C2DA2D19600A6 +:10DC30005A58200680A05A0823FADD9E5441803F9E +:10DC4000384094088CA197689266D8F3D5F4FC20EC +:10DC5000B48084608C8484E5B4045A380605660078 +:10DC60000FFFD504921E4000780842219C2484A016 +:10DC700096905A20200C386088008C414063140C28 +:10DC80008CA6880696905A581EF68C6196D8AA21C2 +:10DC90005A3807E4FCA0FC20B46084005031802492 +:10DCA0009583A31997B0844099568C415472000F04 +:10DCB000976896903870940892845A2808F78C01D7 +:10DCC00096005A0804EFFCA0FC20B4608400503198 +:10DCD00080349583A31997B0844099568C4154722F +:10DCE000000F976896903870940892845A2808F725 +:10DCF0008C0196005A0804EFFCA0FC00EA663C0F79 +:10DD0000FB5884234403F40BAE4084264403F404FC +:10DD1000AE4084014413F407AE084413F408AE087F +:10DD200084404413F01EAE884413F420AE08EA2B5E +:10DD30005A080105EA66490006CB4402D66044123F +:10DD4000D9BCF81A4402D6604412E628F81B4402F3 +:10DD5000D6644412E1B0F8164412E2904402D66050 +:10DD6000F817490008AF44020000490009204402A6 +:10DD7000D6BC4412E1E449FFFF574402D6BC44122A +:10DD8000E94449FFFF8A4402D6BC4412D92849FF1E +:10DD9000FF9DFC80FC00B48084405042002484003D +:10DDA00080A098D096D838308C00958296DF40318C +:10DDB000980C8C0188A35A0808F68C489690AB61A1 +:10DDC0005A2820EFFC80FC04A649B4405A100304F2 +:10DDD0005A180D0FEB94A648C9054412E628EA68C4 +:10DDE000FC845A1803254412E1B0EA68FC845A18EE +:10DDF0000407F81658000003B889FC845030FFF679 +:10DE0000E662E80B842084463820FC088C215A18EE +:10DE100020FD803FEA68FC848E28E622E8088382A1 +:10DE2000B8096600000F83FFEA57B889FC84FC003C +:10DE3000A68180C05A2003145A2006129E14E602BE +:10DE4000E90E50017FF8E602E90E50017FF6E60286 +:10DE5000E90A5A280D1EDD475A08020684003E07CB +:10DE6000EC21D50484013E07EC21EB27A6712E2777 +:10DE7000EC3684812E37EC574452C25449FFFAF0F5 +:10DE8000DD475A000206EA4D802649FFFF9EFC80CE +:10DE9000FC00B480844050420034840080A098D0BC +:10DEA00096D838308C00958296DF4031980C8C01E2 +:10DEB00088A35A0808F68C489690AB615A2820EF40 +:10DEC000FC80FC014412DE5CF08149FFFEC2F001DF +:10DED000EB2DF989FC81FC2480E180C049FFFD7BAA +:10DEE0002E2011AA4442DE5C4402D9082E3011993A +:10DEF0005A780635842938120808E66284223810D8 +:10DF00000808E924DD475A08022284005A680312EF +:10DF10002E1011994432E1B0F83C5A0820FFEA6112 +:10DF2000C00D8E228440881FE24110F07FFFD5068D +:10DF30004422E628F83F5A0820FFEA618429381F66 +:10DF40008008EA4D803FEA68D54CEA614412E20459 +:10DF50008443EAB9EA4DEA68D544842038120808B7 +:10DF60005A68030538600808D50484213810080869 +:10DF7000E662E930DD475A08022E5A6803192E007E +:10DF8000119984285A080203842784004432E1B09E +:10DF900038218000382F80088C0183FF5A0820FA2E +:10DFA000EA61C010881F10107FFFD50C8400442246 +:10DFB000E62838110000381F80088C0183FF5A08BA +:10DFC00020FAEA618422381F8008EA4D803FEA681F +:10DFD000D508EA614412E2048445EAB9EA4DEA68E8 +:10DFE000EA4D49FFFF70FCA43C5DFB613C1C0073E3 +:10DFF000D10C3C1C0074D1093C1C0075D1063C0CB2 +:10E000000076FE2DEAF2DD9E8401DD9E84454030DF +:10E010000817848696D8FE2438108E024000800DA2 +:10E02000962FDD9EEB373C3C00715A1802043C3CB5 +:10E030000073EB5D442201209230EA8A40110440D3 +:10E040000440800A462C003F50210FFF54000FFF70 +:10E0500040004808FF16FF071440800AEB5D443279 +:10E0600001809230EA8A401184400430800AFE9E8A +:10E07000FE171400800ADD9EFC0044620104406328 +:10E0800000202203000049FFFFCFA4303C0BF671B3 +:10E09000FC80FC4180C03C0DA496F081EB84EAF545 +:10E0A00080E181224C5000A2CE04AF9084E1D50FD4 +:10E0B0005A680409800149FFFFE11074800084E37D +:10E0C000D506B00138600400AE5084E38400EB2D27 +:10E0D000386080088C014492D9085A0820FB49FF17 +:10E0E000FF85C0663C3C0073441204205081805080 +:10E0F000B4083C2C03959210EA48EAC7EB828C45A1 +:10E100008C2596489690AE44AE86B40844220360AF +:10E110009210EA48400100403C2C011E84888C4546 +:10E120009690AE843C2C012084A28C459690AE85BE +:10E130003C2C011F84CB8C459690AE863C2C012153 +:10E1400086098C459690AE87B408442203C092108D +:10E15000EA4840010040AE443C2DFB58AE454433F4 +:10E160009780AE46AE47840004110008966FE00128 +:10E17000E8389843A6489648E634E809E62CE810C3 +:10E18000C1125A180A1339048008D50F5A10140600 +:10E1900050F0FFE0E2AFE90938448008D506386462 +:10E1A0008008D503387480088C019600D5DE3C5D6C +:10E1B000FB61EA66D003EB1DD81484083E000438E6 +:10E1C000840A3E00043AEA614422DE5C3821000001 +:10E1D000EB2D5A2809058442EAB9D5033870800826 +:10E1E000EA4DEB2D49FFFE56FCC144138D40AE08AD +:10E1F000AE98DD9EFC0180C0DD4FB65FF381AF803D +:10E200008001EA348006B43FF20149FFFF44FC81FB +:10E21000FC6084003E07EC21DD40842300A0000167 +:10E2200044738D41AE410093800049FFFBD48400CC +:10E2300080408067DD5444638D4000B30000EB559F +:10E24000EA4D4412D9BC49FFFD048403DD548049E2 +:10E250008067EB55E7628403E8028400AE30441225 +:10E26000D9BCEA4D49FFFCF5A630DD548049EA43AC +:10E27000EB55A6303E07EC6ADD4010A00001FCE043 +:10E280008400EB94AE08EA9D3C1BF67F4412C6F076 +:10E290003E07EC6AAE08AE09AE0AAE0BDD9EFC602E +:10E2A000847FAED084DF846084A182468083820331 +:10E2B0004532C6E48125814302B0000097D8E3616E +:10E2C0008220E80A38A98C08A540E2B2E809824514 +:10E2D000820784A0D50638998C08AFD0D50284A0D7 +:10E2E000031880008C61E3A68C024068BC1B40438D +:10E2F000BC1B5A3804E35A50010380908004FCE0B0 +:10E30000FC42FA40812080E1801F8420EA422E27CF +:10E31000F2104432C3D8EAD53801880880834462B9 +:10E32000EB1CC70438730909D504840138030909B3 +:10E3300084209C114501684C45100BB899419757B2 +:10E34000387214005A70FF0D383804003853150124 +:10E35000EBFDEBA9385F9E028865383F9E0A8C2151 +:10E360005A1808EE842080618081385F8602978881 +:10E37000E2858C2140333C1B4042BC1B5A1804F7F9 +:10E38000E647E90284003E07F21010348000FCC228 +:10E39000FC002E27F22684C340111857EAB6969047 +:10E3A000EBD142110C73DD5EEB6C2E07F2268C0173 +:10E3B00096004060183796484010041B3E17F2261E +:10E3C000FC80FC002E27F22584C340111857EAB6C2 +:10E3D0009690EBD142110C73DD5EEB6C2E07F225AB +:10E3E0008C0196004060183796484010041B3E1779 +:10E3F000F225FC8084003C0BF66A3C0BF65BDD4F9B +:10E40000A600C0049E43E622E81244037320A6003F +:10E410003C0BF65B441373224403732144237323A0 +:10E42000A600A648A6903C2BF66AD5269E41E62279 +:10E43000E9035A08052084004453732080204433A4 +:10E440007334A7283C23F65B8CA488443C2BF65BF2 +:10E450000022FFFD88020022FFFE0042FFFF88220B +:10E460003C23F66A9601884496493C2BF66ADBEA1F +:10E47000D503840080203C23F66A88223C23F65B87 +:10E480009649880296013C1BF66A88203C0BF65B95 +:10E490003C1BF668DD9EFC00846080A384DF971837 +:10E4A000E282E80738500D0938608D098C61D5F893 +:10E4B000FC80FC0084A040308C204C118018A5000A +:10E4C000A588E2C4E803A500AD08A580A510E2C4B4 +:10E4D000E803A500AD100A4080010A6100018A86A8 +:10E4E000E0A4E80297618C02D5E98005FC80FC205D +:10E4F00084A08260412140098082800597E9E2E39F +:10E50000E83C5CF38064E90650F3FF385CF7806414 +:10E51000E8304069942002F3000003108000E3AF6C +:10E52000E80503030000130080000313000002F25B +:10E530000000E3AFE805030300001302000003102E +:10E540008000EB534108C001E010E8133D180B1E9A +:10E5500040080013EB533D080B1FA5B03C680B208F +:10E560003C780B213C080B223C280B233D280B2434 +:10E570008CA18C228C82D5C3FCA0FC0044400320DB +:10E5800080C1441300004210107380018022804338 +:10E590004430012CEBA2AC30FC804010042044300D +:10E5A000FFFF84404C00800EA500E244E803A480F5 +:10E5B0009691A500E283E803A4C096D98C02D5F316 +:10E5C00044000096420180019A109601DD9EFC7B7A +:10E5D000B18281808420449000C880068448EA4249 +:10E5E0004014B03685604090840844732D508540B7 +:10E5F0004CA60014B004B05D4420003249FFFF4D2A +:10E60000EA9D8007EB0338132901E220E803380371 +:10E6100029098D4188E9D5ED44732EE05AB00104F3 +:10E620008561D5E64422C11844100190800649FF57 +:10E63000FE38EA2638130101EBBC49FFFE632E07C2 +:10E64000EC26EB643813010138230901E241E805A7 +:10E650009A8AEBF8E804D5028440EA2694514430C3 +:10E6600001F440108C37E623E807C907441000C7BF +:10E6700040108806D5028423EB642E57F227DA0770 +:10E680002E37F21188613E37F211D5033E17F21191 +:10E690002E37F211E663E8035A18030684003E079A +:10E6A000F21180023E27F227FCFBFC2080C180E0B3 +:10E6B000AE08840449FFFF8D4412C6E438109C0064 +:10E6C0002E27EF985A180108E642E8098C413E27A8 +:10E6D000EF98D505C2048E413E27EF9884203E175F +:10E6E000EF972E17EF98C10584213E17EF97AE30B4 +:10E6F000FCA0FC6044600320FE344483019044632A +:10E70000000050B1819050A2019080E181228900E7 +:10E7100088C0EA9D8006EB030214800081A9E220F4 +:10E72000E802EABF50C30190EA9D800CEB03021699 +:10E7300080008D22E220E8031204FFFF5015FE70D6 +:10E74000800650257E70F809A47881A7E220E802AF +:10E75000AC38802B800C804AEAEEEB120216800067 +:10E760008CE2E220E8031203FFFF5063006450B51F +:10E77000806450A500644C647FCEFCE0FC002E0752 +:10E78000EF7B2E17EFBEC0203C0DCBC65A180105FB +:10E7900092019601D503920296013C2DFBE2E240E4 +:10E7A0002E07EF9AE806E61EE80F8C01EB66D50C03 +:10E7B000C00B5CF10E10E906E60FE9048E05EB666E +:10E7C000D5038E01EB665A1801112E07EF9A5A08ED +:10E7D0001E058405EB5ED50CE614E9048406EB5EA9 +:10E7E000D5078407EB5ED50449FFF4E4EB5EFC80BB +:10E7F0003C33F90D5CF18033E913FC00848084C361 +:10E80000E282E80D40301020A558A4C88C81FEF4A7 +:10E8100090624031945C1A308001D5F3FC80DD9E1B +:10E8200084003E07EF998400EAD8DD9EFC003C039B +:10E83000F90DEAD0E905EAD684003C0BF67EEBA39D +:10E84000EAD0E9038400EA99FC8084003E07EF984F +:10E8500084003C0BF907DD9E3C03F907EAD0E9058B +:10E86000FC0049FFFFF4FC80DD9E9200FC0149FFA3 +:10E87000FFF52E07EC26501F800749FFFF182E07D3 +:10E88000EC485A00FF292E07EF938C013E07EF93C7 +:10E890004400004ADD422E17EC48E624E81CEA2D2D +:10E8A00044F0E6ACEB18EA8B4A003C000416041670 +:10E8B000C81284018427EBA03C1E0398EAECEB5FAE +:10E8C000D50A5A0801098401EBA08407EA548400A0 +:10E8D000EAECEB5FFC81DD40A6015A080309DD5A32 +:10E8E0005A080206FC0049FFFFC3FC80DD9EFC00C5 +:10E8F00080C084003C0BF66849FFFD7E2E07EC3B90 +:10E90000406300D6DD473C2396285A000208842342 +:10E91000FE549649E2C1E90BD50EEB7CE2C2001031 +:10E92000002BE8093C03F668E220E9058400EA9937 +:10E930008400D5028401FC80B461AE185A28020418 +:10E940009208AE19B4018840B641DD9EFC44814076 +:10E95000B61F81218400B1C13815000038101C0891 +:10E960008C015A081AFB44001900F844EB1DB43F0F +:10E97000A680AE880400001EB43F92109C89962F9A +:10E98000B65FAE09F82B844244000280F835EA668F +:10E99000803F04600014EAAF92D0EA5A4060184009 +:10E9A0008386B80E8442F821F823B80BF829F8239F +:10E9B000B41F00130028AE40B41F84429C41B63FF0 +:10E9C0003C1C0071046080144412018092D0EA5A09 +:10E9D0004060984000130028AE41B41F803F8C0176 +:10E9E000B61F83FF0403000E92109605F80502037C +:10E9F0000016803F844249FFFFA10403000B803FC3 +:10EA0000921054000FFF83FF4E00FFF6440FFFAA41 +:10EA100010048051EA3DEA28000480515A00CC04D9 +:10EA2000AE88D5FBDD41C0074412FE51840280410F +:10EA30008461DD46840038138000381500088C019D +:10EA40005A081AFB840010048051FCC4FC004403E3 +:10EA50000C803C1C024D442000C8EB6CFC80FC0088 +:10EA60002E07EC4A8E01E602E808DD5E44030C80C6 +:10EA7000EA6E3C2FFBC4EB6C2E07EC4AEB0D5A08F8 +:10EA8000011644530C80442F74F844300960444309 +:10EA90000FA08400986AA5A8386080095000032060 +:10EAA0004C01FFFB8CA2DCF6FC80FC80FC0049FFE3 +:10EAB000FEBF49FFFFCD2E07EC4AC008EAD6DD4F66 +:10EAC000A60049FFFFCE8400EB95FC80FC0004000B +:10EAD0000014441200609210EA48EAC72E172C581E +:10EAE000101000182E172C59101000192E172C5624 +:10EAF0001010001B2E172C571010001AA0454210A2 +:10EB0000F008A845A0454210F408A845A0454210C9 +:10EB1000FC08A845A0454210F808A845DD41C005FD +:10EB200044037320F804FC804403738449FFED69B7 +:10EB3000FC803C0FFC8ADD9E2E37EFBE5A3001066A +:10EB40002E37ECB15A38011E84603E37ECB10030EC +:10EB500000103E372F01A0C5840AFE1C3C0FCBC11C +:10EB6000A60A3E072F4CA60B3E072F4DA4123C0BC6 +:10EB700097BBA4133C0B97BCFA043E072F7ADD9E8B +:10EB8000A6C03E372F01A0033C0FCBC1A6083E070D +:10EB90002F4CA6093E072F4DA4103C0B97BBA41188 +:10EBA0003C0B97BC84043E072F7ADD9E5A0001047B +:10EBB000EBD1D502EA6E5040832080A184001A0276 +:10EBC0008001DCFEFC204453000044630C80800183 +:10EBD00080650A218001A5C04023885C1A200001BD +:10EBE0004C027FF950528320DEF384004432817856 +:10EBF0004440096084A0988338608001386114091A +:10EC000050528320DCFA8C025A0B20F6FCA0FC60E8 +:10EC1000848084FF84C1826780A482244492C6F0E9 +:10EC20008166810403000000552200FFE3828140D9 +:10EC3000E80E03008000E383E80A38849008A5808A +:10EC4000E2D3E8088266823284C0D50538B49008E1 +:10EC5000D50284C00B00800102A500008C81898A46 +:10EC6000E3878C0240783C1B40593C1B5A4804DC2B +:10EC70005A60010380B18005FCE0FC002E17EC8196 +:10EC80003C6C0064C10B84003E07EC81441000E63C +:10EC900084063C6C007BDD45D534C80ADD5A5A0039 +:10ECA0000131DD5A5A08022E3C6C0073D52A5A08ED +:10ECB000030EDD5A5A0801053C6C0065D522DD5A69 +:10ECC0005A0802203C6C0074D51C5A08010EDD5A0B +:10ECD0005A0801053C6C006CD514DD5A5A08021222 +:10ECE0003C6C0075D50E5A08020DDD5A5A08010514 +:10ECF0003C6C006DD506DD5A5A0802043C6C007667 +:10ED00008006FC80FC002E07EC66C82B3C0DFBEC5B +:10ED10005CF00032E9042E07EF84C0062E07EF8373 +:10ED20005CF00032E91E84203C1BF665840044320E +:10ED30006EB8EB1CE202E80698838C01AE50960197 +:10ED4000D5F93C0C02493C1C024BEA4F440000330D +:10ED5000EAD8EA6EEB36DD5E49FFFD4C8401EAB08D +:10ED6000FC8040300C204C0180051A200001D5FCAD +:10ED7000DD9EFC4051FFF9B8F0818400EB19EA6E8A +:10ED8000B0028440EA6FEB6D500F8328EA6E442096 +:10ED9000FFFFEA6FEB6D84C044A0032044928178AA +:10EDA0004472EAF4800942032873B042502F83284A +:10EDB000EA6FEBA2380399098CC1EB195A6803F486 +:10EDC000B042502F8328EA6FF001EBA2EB193C0808 +:10EDD0000B16EA6EF00149FFFADDDD4FA6008E0347 +:10EDE000E602E8113C03F67F44600032EAD0E9080D +:10EDF0009E4150007FCE406018D69B8E97B13C6BF1 +:10EE0000F67FD504EB7C0260000EDD475A00020558 +:10EE10008403FF8497B13C03F7C63C100B183C08F1 +:10EE20000B17E220E8033C080B18E2C03C680B1902 +:10EE30003C080A343C680A35E80584023E07EF992D +:10EE4000D5162E17EF99C1048E213E17EF993C136A +:10EE5000F677E220E90A3C03F90D4410EA5FE2206C +:10EE6000E9068C01EAD8D5038400EAD8EB68E6020B +:10EE7000E9078401EA9084003E07F20CD50984007A +:10EE8000EA902E07F20CC0048E013E07F20C51FFEF +:10EE90008648FCC044038D40A6402E07EC79C1068D +:10EEA0002E17EC785A1801038C013E072BF8DD9ED3 +:10EEB00044100055DD43AE40EA76A608C8FFDD9E4B +:10EEC0003C1C0064442200C0040080149210EA48F4 +:10EED00040010040B400920A96373E07EC58040007 +:10EEE0008014441200009210EA48EAC7B4200000DF +:10EEF0000028922A96773E17EC3B3E07EC60DD9E99 +:10EF0000FC008400EB6ADD4C8421AE40840180204B +:10EF1000EB4BDD43DD44AE40EBE1A6505A1001FF60 +:10EF2000DD44AE408409EA50DD4C8421AE408400CB +:10EF3000EB1AEBB3FC80FC008403EB95EA898400B8 +:10EF40008040DD54EA43EA8D8400EAB0EBB38401EB +:10EF50003E07EF84EB15DD4FA600EBF7EAD6FC8009 +:10EF6000FC20444200002E672CC4842044338D4092 +:10EF700080E49688E246E819A7589881C5040051B4 +:10EF80000020D503385004004102040010580184C9 +:10EF9000A758C50400210028D5030021000899794D +:10EFA0001022818C8C21D5E6FCA04422D660B4626C +:10EFB00044420000EB5DA0919230EA8A4012044086 +:10EFC0000410800A923254108FFF964B1210008169 +:10EFD0003C1BF676EB5D0421001592304432018033 +:10EFE000EA8A4011844054217FFF4432000C4021C2 +:10EFF00088400230801F103001040230801F926868 +:10F00000103001050230801E103001060230801ED3 +:10F01000926810300107A4D310300108A4D392687D +:10F0200010300109A4D11030010AA4D19268103027 +:10F03000010BA112846192985452003F0440801148 +:10F040004041903E404290E41040010CA0920410D8 +:10F050008011924896AFFECE40310CE41030010D85 +:10F06000DD9EFC2080E080C1DD41C00C5013010416 +:10F070008041846A8402DD46EA53840249FFA59EEA +:10F08000D504840249FFA59AEB1D442201808380A8 +:10F09000B914BB1592304402000C5431FFFF4030CC +:10F0A0000C40EA8A000301054011044000230104DA +:10F0B0004001010096011200801F00030107002398 +:10F0C00001064001010096011200801E0003010CA0 +:10F0D00040201C0950408044B404EA464000082403 +:10F0E000B604B4040023010DEB26400008F5B60475 +:10F0F0000003010900130108EBAE9601AC1B0003ED +:10F10000010B0013010AEBAE9601AC190003010CD0 +:10F11000A09A5410003F460C0FFFEAB3FE164000C1 +:10F120000704A81A0003010D5410003FA01A66003E +:10F130003F0040000504A81AC7038EE197F8840336 +:10F14000DD548047EA43EB55FCA0FC6081218162DD +:10F15000814380C4DD56A60896005A0801FEDD5999 +:10F16000AE088020EB4BDD58A640C9FFA6405A18D8 +:10F1700001FF84003E07EC68DD41C020EA2A5A08FE +:10F1800006FFEAA2EAAAEA4FDD4C8421AE400074F1 +:10F19000812ECF05F8083E77EC68D510007300513A +:10F1A00097FCCF0649FFC5931074809ED505840057 +:10F1B000EB5749FFC4CF8401EB69840AEB48840014 +:10F1C000100300511003005210030053FCE03C1CDC +:10F1D00000644422000004108014463C003F92303A +:10F1E000EA8A401104400420800A50318FFF540005 +:10F1F0000FFFFE9E402102441420800ADD9EFC4247 +:10F2000080C2812080E1FA408420801FEA42987EFB +:10F210002E27F21C4432C3E4EAD596493801880807 +:10F2200080834462EAE4C10438130909D5048401E7 +:10F230003803090984209C114501684C45100BB81E +:10F2400099419757387214005A70FF0D38380400EE +:10F2500038531501EBFDEBA9385F9E028865383FF6 +:10F260009E0A8C215A1808EE842080618081385FC4 +:10F2700086029788E2858C2140333C1B4042BC1BB0 +:10F280005A1804F7E647E90284003E07F21C1034DE +:10F290008000FCC2FC60EE38509F8028F082F18331 +:10F2A000844884208009B1CCEA42800784208448C5 +:10F2B000EA428400EB19F003446000C8406300D6C2 +:10F2C00054D300FF400684089600F0848580943172 +:10F2D000F081048F80028169814C97B1F0034CA0CA +:10F2E000005FB00E501F8100F20449FFF8D644526F +:10F2F000817844428AD840E61400888C14BF800587 +:10F30000B04E502F81008066800EF487EB12F0869D +:10F31000B06750070190502F81648066EB12F506AC +:10F3200002158000E20540503C1A9629E220F407BD +:10F33000E8031255800050E703204CE27FE3B04E13 +:10F34000502F810080668008EB1250E40190F08617 +:10F35000B067800E502F81648066EB12F406F105D1 +:10F36000E20440403C1AA4489621E2208D62E80362 +:10F370001245FFFF802D8008EB033803A909802D7B +:10F38000800EEB033813A901E220E8033803A90932 +:10F39000F0018D41890040C60000D5A1F00249FF6F +:10F3A000F812DD473C1DFC8A0220800F5A0002053E +:10F3B0008403FE849691806280298007F976381351 +:10F3C0008101100F802738248101500F802749FFC9 +:10F3D000FF18EBF0A608004F802738038101EB19D6 +:10F3E000A6C83853910138238D0138048D01880255 +:10F3F000382491018845E040E8059A82EBF8E80559 +:10F40000D5028440103F8027A608443001F494516F +:10F4100040108C37E623E807C907441000C74010A6 +:10F420008806D5028423002F80272E57F224DA077E +:10F430002E37F21D88613E37F21DD5033E17F21DAF +:10F440002E37F21DE663E8035A18030684003E07D0 +:10F45000F21D80023E27F224EDC8FCE08401DD9E0F +:10F4600084004412C3E4845FEAB98C015A0808FEA0 +:10F4700084003E07F21CDD9E5A0801078401AE0895 +:10F480008400AC10DD9EEB7C0200000F42420001C4 +:10F49000E283E9F5A410E61EE8048C01AC10DD9EC1 +:10F4A0008400AE08DD9EFC40812184203C1BF7C611 +:10F4B00010910000842480C2814349FFFEED80E06A +:10F4C0004402C6F03810240081205A18010FEB685E +:10F4D000E602E8048C013E07EF9984013E07EFBE87 +:10F4E00084003C0BF67DD52E4412C48E8400442249 +:10F4F000C1CA3C33F7C63C43F677F9112E17EF9992 +:10F50000C1048E213E17EF995AA80112846080230E +:10F5100038048C00C8038C2196498C615A3804FA4F +:10F520005A180406EBA38C01EA99D5038400EA99E2 +:10F530003C13F90D4400EA5FE201E9048C213C1B15 +:10F54000F90D8400EA90EB68C0048401EA90AFF002 +:10F55000FCC0FC0097844060982044100640FE0CDC +:10F56000441300004000803C80228043EA6FEBA2FD +:10F57000AC30FC80FC6051FFF9B8B67F8160EA6F67 +:10F58000B002818180E2EA6E8440F481EB6D442018 +:10F59000FFFFEA6F500F8328EA6EEB6DDD4C84218C +:10F5A000AE4084C084013C6FFBA04493F04AEA73F0 +:10F5B00044A00055EAD644D3F4234C65804284002D +:10F5C0003E07EC878400EB7784018020EB4B8409B5 +:10F5D000EBC0EA50000680005A000404EBC0D5FBE3 +:10F5E000850985C0EBEBE20CE823EA2A5A0806FFFE +:10F5F0003C8FFB6D3CEFFBA0EBEBB43F5A7802096C +:10F60000F201B0C2504F832849FFF875D50BB08284 +:10F61000503F83285A78010549FFF7B1D50349FFC8 +:10F62000FF9AEBEB8C0196003E07EC87D5DCDD4CB6 +:10F630008421AE408CC1EA38EA8797B0D5BFEA8909 +:10F6400051FF8648FCE0FC4384208448B002EA4233 +:10F6500084208448B004EA42EA898422DD4FAE4027 +:10F66000844284018425F80C44638D42EA7CEA8557 +:10F67000A6305A088F0AEA58840184258442B0C211 +:10F68000B104F829D5F6B04284448402F859DD4724 +:10F690003C1DFC8A0220800F5A0002058403FE8470 +:10F6A0009691B0428062B00449FFFAB3F08149FFFD +:10F6B000FED98402F815EA89F001FCC3FC0180C080 +:10F6C000EA898421DD4FAE40840184258040B0C1A9 +:10F6D000504F800649FFFF505A680105800649FFD8 +:10F6E000FA67EA89EB4F49FFF904FC81FC41840089 +:10F6F000EA2649FFF9DDDD4FA600C0145A000404D4 +:10F7000048000061EA933C0BF6774412C48E8400F3 +:10F710004422C1CA3C33F7C64440005049FFFEAE04 +:10F72000D5063E07EFBEEA933C0BF677EB36842016 +:10F7300049FFFB21DD4FA6004412C45C844149FF10 +:10F74000C825EB2CA60096424E14000F5A088809D3 +:10F750008400EA903C03F90D8C01EAD8D5058401B8 +:10F76000EA908400EAD8EB36EA6EDD5E49FFF842A3 +:10F77000EB8E5A000103F8612E07EF8E5A00010349 +:10F78000F85C8400EB2944000043DD4249FFFF5D43 +:10F79000EA26EB2CA60096424E140004960FEA26A9 +:10F7A000DD54EB64EA438403EA8D84C184003C0B9E +:10F7B000F67DEAB03E67EFBEEB15EAD63E67EFBFD7 +:10F7C000F83C440000963C0BF677EB245A080109FC +:10F7D0003C3DFBEC4400003140300C06D507846012 +:10F7E000C8052E37EC5D40300C06EBF0EB36A64832 +:10F7F000EAA049FFFE5A44138D42200080004E04C7 +:10F80000001A8400EA90A6089636C00F8400EA9990 +:10F81000A60854200020C20E66200020960FAE8855 +:10F82000EA268401EA90D506EBA3E61EE803FA0E69 +:10F83000EA99EB8E5A0001044800006D2E07EF8E06 +:10F840005A08011D2E77EC525A78011944938D41C4 +:10F8500000548000EB25D05E84C03E67EFBFEA898C +:10F860008403DD54EB648069EA8D3E67EC663E6795 +:10F87000EF833E77EFBFEB15D54DEBA3E61EE94ACC +:10F8800044000042DD428400EA99EA89DD41C00774 +:10F89000EA2A5A0806FFDD4FA600EBF7840149FF6C +:10F8A000FF0F44238D42A6508062970A4E44000801 +:10F8B0009666C106440FFFC0AE10D521C82084E073 +:10F8C000AFD82E67EF92EA43CE0E8006DD54804615 +:10F8D000EA8D3E67EC663C6FFBEC3E77EF83EB1501 +:10F8E000EAD6D5188403DD54A698EA8D3C0DFBECCE +:10F8F000EAD0E91084013E07EC76D50CEA43840394 +:10F90000DD54A698EA8D8400EAB0EBB38401EB29BC +:10F91000EB15EB7C0000002EC00B3C13F7C6440235 +:10F92000FE54AC403C13F66E4402FE56AC40FCC1A3 +:10F93000FC00DD475A08022BEBE7EA61E220E8030E +:10F94000EA78C00C84003C0BF66749FFEFFAC81E4A +:10F9500049FFF55249FFFECCD519EA655A08010660 +:10F960004402C19E49FFC037840184408080842ABC +:10F97000806280A2DD53DD5A5A08020549FFD05546 +:10F98000D5DC2E07EC235A0801D9FC80FC20DD4F82 +:10F99000A6802E17EC3B2E07EC602E37EC292E505C +:10F9A00011B7CA05804082018003D50482058043D7 +:10F9B00080A1427140243D1C024B422014248480CB +:10F9C000452333103C0395B2E280E81595A140032E +:10F9D0004800A4C0A44088D1A430FE6C4231C024A9 +:10F9E0009A08FE3C8C81400008169A189601AC30AB +:10F9F0009721D5E93C0C024B3C1C0249EA4FFCA084 +:10FA000044531C20442003E844331DB05A08050B1E +:10FA1000A528021291B8FE64401088379649AC6858 +:10FA2000D50B5A08010AA468024291B8FE5440104E +:10FA300090379649AC688CA2DBEADD9EFC6080E0E2 +:10FA4000DD4F80C1818281638144009000005A783B +:10FA50000115C1038EC197B044038D41A740D6075D +:10FA6000EB245A080105800649FFDCD28403DD54EB +:10FA70008046EA43EA8DD50D5A78020C5A9804055F +:10FA8000840149FFFFBF8400DD548046EA43EA8DCC +:10FA90008401EBE5DD56A60896005A0801FEDD5903 +:10FAA000AE088020EB4BDD58A640C9FFA6405A188F +:10FAB00001FFDD41C016EA2A5A0806FFEAA2EAAAB7 +:10FAC000EA4FDD4FA600C8045A980409D5055A0824 +:10FAD00004064E93000449FFFF5BDD4C8421AE40D9 +:10FAE0005A78010984001076000010758000EB48F8 +:10FAF000D5095A780208840010060000EB698401D9 +:10FB0000EB48FCE0FC202E67EC753C73F65EA6012A +:10FB100049FFDDFC8EC1E2E05C630001E904EB8695 +:10FB2000C00284C18006FCA0FC00DD40A6415A1042 +:10FB300004058424AE41EA34840A441000B5DD454E +:10FB4000EB86C803F80AE80349FFE081840A441001 +:10FB500000B6DD45DD41C024DD578E04E60283FF9B +:10FB6000E8172E07EA085A08010A4410003F8408E3 +:10FB70008041806149FFE5F0D5155A080214440020 +:10FB8000003F84268040806049FFE5E6D50B442095 +:10FB9000003F84088426806249FFE5DED50349FFE3 +:10FBA000E5ED441000B7840ADD458405DD4AEA53DB +:10FBB00049FF92A48406DD4A840A441000B8DD455A +:10FBC000DD4C8421AE4084208402804184618081A8 +:10FBD00080A1DD53FC80FC418120EA38EA8784065D +:10FBE0003C7DFB48EA4A84C1DD40EB91EA34DD4FBD +:10FBF000A600842649FFF1718400EA91DD5897F848 +:10FC00003C7FFB483E67EC93AF80DD4CAF802E67B6 +:10FC1000EC3697B05A6801108026DD40DD5580092A +:10FC200049FFDD54F08184408402F10180668082C6 +:10FC300080A2DD53FCC1FC2080C0DD44DD43AE402A +:10FC40004472FEF22E07EF33C8198404441000F307 +:10FC5000DD45EAEF8401EB4E5A080103F821A6B80E +:10FC60009690C205DD4049FFA123D5ED8401802097 +:10FC70008062808080A2DD53D5E68401EA5E840A3A +:10FC8000DD4A2E07EF33DD4A2E27EF335A28030BC8 +:10FC90008401EA37EBE38400EA5E8400EA954800D9 +:10FCA000006C5A280409DD408421DD55EB138400E3 +:10FCB000EA95D5625A28060D800649FFFF8E840119 +:10FCC0003E07EF2D8400EA5E8400EA95D5555A2858 +:10FCD0000A13A63184C15A080A0784003E67EFBCA4 +:10FCE000EA95D54AEAC3DD4C3E67E9D4AF8084008B +:10FCF000EA95D5425A28092DA63184E05A080A0906 +:10FD000084023E77EFBC3E77EF33AE30D5355A08EC +:10FD10000B14AEB1DD403E77EF33EA34DD40842191 +:10FD2000DD558400EA2C3E77EFBC49FFC5218401F4 +:10FD30003E07EF6DD5218405DD4AEA5349FF91DE88 +:10FD40008406DD4A3E77EF3384028420D5105A289A +:10FD50000B1484203C1FFBEBAEB1EBE18401EA986D +:10FD60003C1BF65E3E17EF33AE1084028041846187 +:10FD7000808180A1DD53FCA0FC6180C0A601B65F3C +:10FD8000F3815A080408A6305A080105840049FF87 +:10FD9000DC872E07EC8E5A08010C4402C15EB43F8A +:10FDA000F2013C3DFB573C4DFB5549FFA641EA386B +:10FDB000EAF3DD41C805EA22EA36EA33D567852051 +:10FDC00044A2FE5044C2C2B444DD01B044B2FE5667 +:10FDD000DD5F5A000122A6315A08041FEBF144727C +:10FDE000FE50EB0A5A0010198401EB17A638854023 +:10FDF000549000FF80278047846610A3800084020F +:10FE0000DD4684024412C44880418060DD46EA58E1 +:10FE10003EA7EDE4D52C3B0540003B0640204402C4 +:10FE2000FE54A6403E17EDE8A6013E07EDE9EA9A2A +:10FE300084024422C2B48466DD464452FE50441219 +:10FE4000C2B4800538203404380080004C01000D15 +:10FE500050748001E72597F8E80644000089DD42E8 +:10FE60008127D5B781278CA14C55FFEDEA22FA12E4 +:10FE7000AE08804184028461DD462E07EDE45A0815 +:10FE8000130F44000085DD42D50AA6085A0022045B +:10FE9000AED0D5FCEAB5A6005A0013F5DD544422D5 +:10FEA000C113B47FF401EB7949FFA7829600EAD22F +:10FEB00049FFA037DD575A00010984E13C7FFB7EF2 +:10FEC000DD41C8033C7FFB94A6315A080812A630D6 +:10FED0005A08024DEA3F5A00063C5A000906EA3F1A +:10FEE0005A08113CD514DD475A0802FBD53154108D +:10FEF00000FD5A180910A6705A18020D8401EA7301 +:10FF0000EA3F9E46E622E9245A081128DD41C02036 +:10FF1000D5245A080A07A6308E02E602E827D5182B +:10FF20005A08030BA7B05A6801228006EBE5800649 +:10FF3000EA738408D51C5A08040EA7B05A68011742 +:10FF40008006EBE58006EA73EB9E3E07EC2884080A +:10FF5000D50E5A0006E9D50A844084618402FA2548 +:10FF6000808380A2DD538408D5028401FCE1FC007B +:10FF700084003C0FFB9DDD44DD43AE403C2DFB9DEA +:10FF8000CA08840180208062808080A2DD53D5F77A +:10FF9000FC80FC00DD568400AE08DD59AE0884010B +:10FFA000EA238408EA6B2E07EF2BEA63DD44DD4386 +:10FFB000AE40EA76A6085A0001FFDD41C00AEA22F7 +:10FFC000A6085A0832FF8406EA508401DD4AD50C9F +:10FFD00049FF9C01EA22EB01AE0880418402846162 +:10FFE000DD468402DD4AFC80FC6180C081618406BC +:10FFF000A67180E28520DD45854944C3F04A4480EE +:020000021000EC +:100000000055A6313E97EF6D8E03E6094EF202E3EE +:1000100044F0FE1CEB0C40F03C00DD0F12004A01E6 +:10002000B6053002B605380396037004D604DD41E8 +:10003000EBDDC809DD44DD43AE4084094410009186 +:10004000DD45D5275A08013D04938003F845E32098 +:10005000E9F2D536DD58A600C822DD4CA6005A08C4 +:10006000011FDD5A5A080219EA655A0801064402BE +:10007000C19E49FFBCB02E072B5FEBE79401E22045 +:10008000E80884408401842A8062808080A2DD5355 +:10009000DD41C005D5E0DD5A5A0001E8DD41C80C5C +:1000A000DD58A600C8092E07EC255A0001062E07C8 +:1000B000EC5E5A0001DB840944100092DD45EBDD63 +:1000C0005A000103EA20DD41C01BEB2CA600C0034F +:1000D0008400EA2CA1FB49FFDB22E207E904EAAC39 +:1000E000C006D50949001440C8FBD510DD578E0461 +:1000F000E602E90C2E07EC755A000109EA202E17DA +:10010000EF335A100403EA20EA95DD44DD43AE40A4 +:10011000DD56A608C0FFDD41C808DD4FA6005A081D +:10012000030949FFF70AD50549FF9463C0FED5F6D8 +:100130008404AE3184003E07EF34DD40EA3449FFE9 +:10014000DC94DD41C0088406441000D5DD458404FC +:10015000EA39D5038401EA5E840EDD4A84023E0753 +:10016000EC46EB13EA20840B441000BADD45DD4178 +:10017000C812840B441000BBDD458006EB28F9460D +:100180008405DD4A8404441000F1DD45EAEF800671 +:10019000EB5BEA20840B441000BCDD45DD5FC83812 +:1001A0008401DD4ADD579E44E624E90E5A000C0D19 +:1001B000DD5F5A00040A3C03F7BC5A0801048006BC +:1001C000EB2F8400EB17EB9E2E57EC28D805EA7D29 +:1001D000EB93EB92F903EA38EA87DD578E04E602E7 +:1001E000E809EACFEA4EEA718400EA3C8400EA9129 +:1001F000EAC5DD5F5A000413441000D28406DD45D1 +:100200008404EA39DD408421DD55EB13D5075A0813 +:1002100004068401EA418400EB178400EA98EB2885 +:100220008006F8F48401EA37EAA35A080103F804C7 +:10023000DD5F5A080404480001A7DD5A5A00020392 +:10024000F804EB864E0301A0480001A42ED7EC93DE +:100250005AD8011349FFDB288402EA98DD4CEB6F82 +:1002600084053E97EC9ADD4ADD414E02FECCEA2A37 +:100270005A0806FFEA205AD00203EA208400EA7AEC +:10028000DD41C027EA618C02EBE78C22E220E80521 +:100290003C1DFB845A1801FAEA7DEB93EB92DD409A +:1002A0004412E19C49FFDD54EAA3C805DD40A601E4 +:1002B000EABEF9738406DD4ADD43DD44AE4080C00A +:1002C00049FF938AC0FEEA3AAE30DD5AC0FFD5221C +:1002D00049FFC55DEAF95A0803053CDFFB48D50331 +:1002E0008401EA7ADD44DD43AE404493F7F1EA78D5 +:1002F00080605A0801FE0074800097FCCFF9441218 +:10030000C1F080418402DD468006EB5B3E77EF2D35 +:10031000EA202E67EC7584003E07EF2D5A6801082D +:10032000DD408420DD553E67EC93EA200005800027 +:100330004E03012CEAA34E030129DD5A5A000104A1 +:1003400048000124441000D48406DD458404EA39C1 +:10035000EB13EA20EA3F5A0806108400EA41EA98C3 +:10036000EB93EA7DEB92DD47C00CEA8002000010BF +:1003700049FF9A7AD5065A081110DD41C0EFD50C15 +:100380008403DD42EAC3DD598401EA37EA69AE0835 +:10039000840FDD4AEA20EA3F5A000903EA20DD47DC +:1003A0005A000203EA20DD408420DD558403AE318B +:1003B000EA208401DD4ADD41C8098006EB28F826E1 +:1003C0008405DD4A8006EB5BEA20DD5FC817840206 +:1003D000DD4A49FFC1BA8006EB2F49FFDBDFDD4C68 +:1003E0008421AE40DD5F5A00040E8409EA3984039B +:1003F000DD4ADD41C007F835D5055A0804048401FB +:10040000EA418404DD4A8006EB2849FFDD3EEAA389 +:1004100085213E97EC9A5A000105DD5F5A08040ACF +:10042000840AEA39EAC3DD598401EA69AE08EA20A0 +:10043000A631EABEF8B23CA3F65EA63149FFD96602 +:10044000E340E912840BEA398400842BA83BAE71A7 +:10045000EA91DD4C3E97EC93EB6FDD414E0200BB21 +:1004600049FFC176EA208409EA398405DD4AEA5366 +:1004700049FF8E448406DD4ADD418020C8F28402B3 +:1004800080418461808180A1DD53EA20DD41C80282 +:10049000EA69A6305A08021EEBD3DD56A608C0FF53 +:1004A000A631EABEF08185A04402C161F101442277 +:1004B000C1B449FFDAB03CDBF65E10A30001DD40B9 +:1004C000EA34840010D3801CA83B3ED7EC93F8524A +:1004D000EA3F5A08070C8409AE31EAC3DD598401AA +:1004E000EA69AE08FA083C0FFB6484001003801C24 +:1004F000EA202E07EC935A080119DD40EA3449FF3F +:10050000C134DD408429AE418420DD55DD40842B9B +:10051000AE4149FFFD408402DD59EA988400AE08EF +:10052000EA378403DD4AD5565A0802558404DD4A69 +:100530003E97EC93DD41C8088006EB5B2E07EF6D1C +:100540004E03FD61D54700058000C803EAA3C00340 +:10055000EBC7C8128409EA3910A30001DD40EA3470 +:10056000DD408421DD5584001093801CA83B49FFA9 +:10057000C0FF48FFFD48840AEA39EAC3DD4C842104 +:10058000AE40D5288402DD4A8403EA39EBE3D52264 +:100590008403DD4AA631EABE49FFD846DD4049FF63 +:1005A000FAB3C00E8404DD4A84013E07EF2D8406B1 +:1005B000EA39800649FFFB118405DD4AD50B44105A +:1005C00000D38406DD458404EA39DD408421DD550D +:1005D000EB13FCE19200FC40C002F92B4460006583 +:1005E000EA7CEA85DD47C00E8EC1C60C84218041BD +:1005F0008061848044004F00EAA7EAC9EA3BEA58D8 +:10060000D5F28400EBB7FCC044100055DD43AE408A +:10061000EA76A6085A0001FFDD9E9200FC4080E0C9 +:100620008122EB6380C049FFFFF19E79E62F4EF2F5 +:10063000018144F1044038178501EA8B4A003C00EF +:100640001E00720020012A029200F002F002F00265 +:10065000F0024C028002D202F002F002F4028404A2 +:10066000FA21DD4544000030DD42840EEA4A84056B +:10067000EA528400EA97EA8CEA6ADD475A080204E3 +:10068000AFF0D5FCDD47C00B842144005AF0804117 +:1006900080618081EAA7EAC949FFFF9F8009842120 +:1006A000DD558420840280418461808180A1DD53F6 +:1006B000F8DB8404FA22DD45840EEA4A8406EA5215 +:1006C0008400EA9780A650030041843FEADAD8FF0D +:1006D000D5E6FA258404DD4544000031DD4284E09E +:1006E0004403F429AFC0F85D84013E77EC21EA525F +:1006F00010730050EB27EBCF2E27EC3684812E377A +:10070000EC574452C25449FFE6ABDD4FA600C80681 +:10071000EA4D4412E628EA68D5075A080306EA4D6E +:100720004412E1B0EA6884003E07EFBC2E17EFBF29 +:100730008400EA2C84013E07EC375A100103EB9544 +:100740008400EA73DD568402AE08DD59AE08EA770C +:100750008E08E6044EF200F0800949FFB918F884CB +:10076000FA238404DD45EB01DD42DD598402AE0845 +:10077000EA52EA779E43E624E90A5A000D095A082C +:100780000E0A49FFB9AF840049FFB9948408EA4AC8 +:10079000D5038409EA4A84E0107300503E77EC5395 +:1007A00049FFED38DD40EA3484043E77ECAAEA6A7A +:1007B000DD4AEA8CDD475A080205EAEFAFF0D5FBC7 +:1007C0004413F3D1A608EA8FAE08441FFFC34403C5 +:1007D000F429AE40DD47C008842144005AF080412E +:1007E00080618081EAA784003E07EFBC2E17EFBF2F +:1007F0008400EA2C84013E07EC375A100103EB9584 +:100800008400EA73840049FFE28584208009DD5575 +:100810008405DD4A44000033DD42EA3F5A00040407 +:100820005A080706440001F4EA3BD5054400004B92 +:1008300049FFCFCEDD47C006EA800200001049FF25 +:10084000981344000034DD42DD418020848F84020F +:10085000C10784408020806280A2DD53F80580417A +:10086000806180A1DD53480000678404FA24DD45DF +:100870008420DD40DD55840AEA4A8403EA5284007C +:10088000EA97DD40EA348401EB54D5558404FA2A12 +:10089000DD45840EEA4A8406EA5280A650030041F0 +:1008A000843FEADAD8FF80098421DD558420840062 +:1008B0008461EA9780418402808380A1DD53D53B27 +:1008C000FA2B8404DD45DD47DD545A08020CA609E5 +:1008D0005A00031280018420DD55EBE38401EA37DE +:1008E000D50AA6095A000A0880018420DD55EAC30A +:1008F0008401EA3700030051001300524422C12F43 +:100900004432C0FD4442C14249FFF89A8400EA974C +:10091000D5128404FA2CDD45000300515A0001056C +:100920005A08020584003E07EC758400EA97D50357 +:10093000841BEA97FCC03C0FFC8BDD9EFC6004EF3F +:10094000800DC80AB461A0499419944940108FF5EC +:10095000EA4CEA40D5469521981C9E628C82A40000 +:1009600088238864A5C8A5989603814597FB97B30B +:100970004E070006EB1EF812FD60D503858081ACA2 +:100980004E7700078007EB1EF809FD40D503850070 +:1009900081284E6700088006EB1E49001C4CFD3084 +:1009A000D50384C080E640050408EB1EFD50FD130E +:1009B000FD04EA5FFD10FD05EA24FD50FD13FD0472 +:1009C000EA25FD16EA5FFD16EA5FFD10FD05490008 +:1009D00020A149002205021F801892014000042036 +:1009E00012070000FCE0FC433C43F06E124F800A0B +:1009F000124F800B00400009C4085A401F070040F6 +:100A00000008C4035A48311100410042C407B482AF +:100A10005A48050B00410046CC07444007D0124F0E +:100A2000800A124F800B3C4C02114E4600AACC08A3 +:100A30003C4C02104450C34FE2A44EF300A23C4C85 +:100A400002134E46009ECC083C4C02124450C34F49 +:100A5000E2A44EF30096A5004E420093A5014E423B +:100A600000902E57EF964E53008C026F800A3C4D3B +:100A7000FB62E2C44EF20085026F800B3C4DFB6EC0 +:100A8000E2C44EF2007E8481AF182E6010E53C4037 +:100A9000041ECE06C40750327FE1E2C3D50481E5CF +:100AA000D50281E48120440166903850110144014F +:100AB000665038001101B61F9C14F081EAC9F0821B +:100AC00080C2800F80E150248028501480103C3C6C +:100AD000020CF8212E1010E53C40041F8400C907C9 +:100AE000C40550027FCFEBB2D5028004441165ECFF +:100AF000385091014411658838109101B63F9C76B9 +:100B0000F18144100066F182502480303C3C020D9B +:100B10005014801849FFFF140433800B0423800A0B +:100B20004E360006CB295CF105DDE9260493800DE5 +:100B300004A3800C4E9600074E93001F5CF505DD64 +:100B4000E91BEBDC8E02E605E817A03DA13C9441D1 +:100B5000401093F59421EA40A07FA0BE944912036F +:100B6000000C40108BF594118069804AEA40120312 +:100B7000000D8401D50284001003007AD50384009F +:100B8000AE18FCC3FC203D0DFC8B80C19B31E28282 +:100B9000E81E0873000104500008012800323912D1 +:100BA0009E02A146A10738529E0238421E024259B7 +:100BB00014248C684052C4B71251FFFC0058003313 +:100BC000FF2C404244971241FFFDD5E1FCA0FC60A0 +:100BD00081A1EB3781208400818280C3AE185A182E +:100BE000025084E044E2C700E2EDE86B04048001B7 +:100BF00038501D01DF4350548018A02A3C2DFC8B37 +:100C000038101E02B4050031003238001E023C4488 +:100C10000852FE1C0021003340A00557A0299081F6 +:100C200038001E0240451001FE1442F200033C440D +:100C3000085340B00577908140459001424200033F +:100C4000888F5EF20032E917A6303C1DFC8B38A677 +:100C50000309A6304006006012B00001A6303877C4 +:100C60000008A6308C019600AE3000108019E20119 +:100C7000E905D52749000E7BC0E88CE1D5B63C1DBF +:100C8000FC8B84004422C700E20DE811043480018B +:100C900038518101D814A6F038010C08A7308C8196 +:100CA0009720AF3000308019E283E90980094412AF +:100CB000C700A6B0806C49FFFF67D5038C01D5E55E +:100CC00084004422C700A670E201E80840160060D4 +:100CD00038310000A8C98C01D5F7FCE03C0FFC912D +:100CE000DD9E4402B64C3C0FFC90DD9E3C0FFEE8BE +:100CF000DD9E3C0FFEE7DD9E22200000EB6522001A +:100D00000001EA7B8A438A01FE0442010873DD9EEA +:100D10008060804084019A50E622E90A985092212E +:100D200042F08424E26FEB3E4020BC1BD5F5DD9EF3 +:100D3000FC4080C180E2812349FFFFECE206E80825 +:100D40004E9300049A30FCC08AE68807FCC0E4CBCE +:100D5000E90580074004A41AFCC04E930005500327 +:100D60007FF6FCC09A3E8C0AFCC0FC612261000048 +:100D700081628440806280E0F18180018026F81ADF +:100D80003C9DFEE781400224800984619A56964B7F +:100D9000F001F81022658001844080628026810085 +:100DA000F001F8080224800A81609A56F001964BFF +:100DB000846149FFFFBF22238000E04AE90AE10283 +:100DC000E90822238001E04BE90440000807FCE128 +:100DD0008401FCE13C3DFEE7222000000211800975 +:100DE00040408409E082E8038A22968B22100001A9 +:100DF0000201800A40300409E061E8038A01964359 +:100E000042108801840A42008000DD9EFC6081411E +:100E1000EB234201047380C2B42044C2D05444B2D4 +:100E2000D04495D24492D008C10D00000018960419 +:100E3000C00984033806080884003805880884003F +:100E4000D53A38059800E604E8068C014412D044EF +:100E500038009808380618004412D054E603E90315 +:100E60008400D5028C0138009808802A40049C0038 +:100E700049FFFF44EAF1FE0C49FFFF4C442100000A +:100E800038161800E24040013C1B88274442CF90AE +:100E9000846038020509804338059800E260E8075D +:100EA000985F381205018C618841D5F94021003CDA +:100EB000400100162215000038149A0988E922150D +:100EC0000001AC79FCE04402B5E43C0FFEE65000C2 +:100ED00000343C0FFEE5DD9EFC2051FFFD1880C074 +:100EE000121F800380E244116854EBA7B002DD4872 +:100EF0004411690CEBA7B030DD48441169C4EBA77D +:100F0000500F8178DD48500F823044116A7CEBA786 +:100F1000DD485A6002095A60030A5A68010BB0F0B2 +:100F200084C0D509503F8178D505503F8230D50225 +:100F3000B0C284C1C722FA5D4450005A848084E262 +:100F4000EA59381189119603E001E803C607D50B69 +:100F5000EA599603E020E816C6069855EB8C808285 +:100F6000960BD5059862EB8C80A2960BE005E80BFA +:100F7000E080E8098040D5E5EA59960338018111FF +:100F8000D502800251FF82E8FCA03C1C03985A184D +:100F900002160010003C5A1801128420EB62021065 +:100FA00000181210001A021000191210001B021073 +:100FB000000EEB760210000FD5222210001AFA83E1 +:100FC00022200018EBB1FA642210001BEBF512206E +:100FD000001A22200019EBB122100010EBF51220AC +:100FE000001B2220000EEBB12210000FEBF51220A7 +:100FF00000102220001142111073EB611210001139 +:101000000010007AC9080210001AEB760210001BCB +:1010100012100011DD9EFC010220001A02100010C7 +:101020000230001B8A2202200011224000088A435D +:10103000964B96935EF2003C90219041E8094E1445 +:10104000001A00300045CB168465FEE4D50D5EF233 +:101050000C44E9104E17000F00300045CB0B5252E4 +:101060000C7F8465FEEC44500078EBA98C6196DB24 +:10107000D50600300078E674E9048469EB61D50296 +:10108000842022300009121F80005EF1803CE808B5 +:101090004E24001DEB5AC91A8425FE5CD50C5EF166 +:1010A00093C4E9144E270013EB5AC910525193FF11 +:1010B0008425FE6C44500078401094368C21964B69 +:1010C00040210456122F8001D50900100078E63423 +:1010D0008429E8F78420121F80013C1DFB6E5CF020 +:1010E0008708E8068420121F8000121F8001041068 +:1010F0000011EAE2EAB2FF4E44110000D11F3C1C8D +:10110000043F3C67FD5AE6263C57FD59E906126F3D +:101110008000125F8001D512EAA98447964B4213E2 +:1011200008739023964B121F8000EBCC964B421213 +:1011300088739023964B121F8001EAA9964B404278 +:1011400004219723124F8002EBCC964B403184212F +:1011500096DB123F8003021F80021210000A021F5A +:1011600080031210000BEAFB3C0BFD5AEADB3C0B40 +:10117000FD59FC81FC61F581413280114122C00A98 +:101180002270800122508000EB23EB56009F8038B4 +:1011900000100018854154F080014462CEF84412DA +:1011A000CEBCE8114502CF6438580D09EB07450263 +:1011B000CF444452CF3438780D0938708E0A38A2A3 +:1011C0008C08D55EB5805B08031F39030E024512FB +:1011D000CF3488B039008E02EB07898738788C00CD +:1011E00039008E0A8CE197F8E6EF38788C08E948E8 +:1011F00040529CB640781CF6EB0738708E0A38A82F +:101200008C08D53E5B08013A4502CF643D1DFEE8DF +:1012100038B80D114502CF4438A80D1101088000DF +:101220005B08016A40F5940141051C0142F7800307 +:101230004308000302888004898FE310E85C0318E8 +:101240008003E171E803E0B1E86A3C8DFEE7030446 +:1012500000098F818B91E18BE803E185E860E15122 +:10126000E803E0F1E85C0304000A8F818B91E18AD6 +:10127000E842E187E854D53FEB0738708E0A5A9868 +:101280000134B4005A0801313D0DFEE802080005A2 +:10129000E280E82A38030E0238708E0240504C017A +:1012A00042F280034053C8014252800302480006C4 +:1012B00088AFE0A4E819025800074512CEF85102A1 +:1012C000FFFF42084C734042840942784873880407 +:1012D00040001416888738088E0A4042149644024B +:1012E000CEBC38400E0A38030E02AC1038008E0215 +:1012F000AC11FCE139030E024512CF3488B039003D +:101300008E02898738788C008CE197F840529CB621 +:1013100038788C08EB0740781CF6D5B038B30E0A45 +:1013200038A08E0AD5ADFC60446000444201987339 +:101330003CADFEE8B40022508000EA46EA7B01059D +:1013400000163C93F4D94512CEAC4522CE9C95DCD8 +:101350004462CADC4532CACC5A0801108480385332 +:101360001E0940630CC038488C0838090C08AC7161 +:1013700039098C084800009138090C00E610E8048F +:101380008C0138090C0838088C0044B2CEACE60F4A +:10139000E9038400D5028C0138058C0839188C00CB +:1013A00040089C003853020940030040AC4102153C +:1013B000000DE081E8100255000CE0A4E80B4008A5 +:1013C00024018A85FE244100940141004216898946 +:1013D000D502820938498C008403802442180073A6 +:1013E00084048C22EAAEE0804452CACCE8058C81A9 +:1013F000E08040023C1B38028C0838190C00384948 +:101400008C00846AFE5CE024E905E28380244011BC +:10141000BC1B84A0860A4100C216800580654C581A +:10142000001340489C0039231211404310402242CF +:101430000001887288044F1200048FA1D502862F04 +:101440008CA1D5EE848AFEE4FE24404090B6C50C03 +:1014500088F138431E1140731C404232907322437E +:101460008001420290734E3500064050840A88A3E2 +:10147000D50584A2405094B69B5DEB67976B4E05F3 +:1014800000064030840A8803D505846240308C769B +:101490008A03EAE7964BAD50AC51FCE0FC20446077 +:1014A00000444201987322508000B400EA7BEA466F +:1014B0004462CA9095DA4502CA805A08010A9837F0 +:1014C000AC41EAC938530E0938080C08D54B5EF216 +:1014D0000029E8043C43F4D8D5135EF2012CE80F50 +:1014E0003C03F4D850427FD8531000644248902403 +:1014F00045100104404244968880D502EB593808D3 +:101500000C0086234202447384848C02400010162F +:1015100038080C089937960039230E112312000160 +:10152000530000644240142442484873445000640D +:101530004E45000550420032D50350427FCEFE0C8E +:10154000420844734042149638430E09EAF14E05AE +:10155000000550000032D50350007FCEEAA69877F0 +:10156000AC0938030E0188C7AC10A431AC11FCA043 +:10157000FC6222D0800022808001EB23EB56816246 +:10158000B42080C36610800212DF8006128F8007AD +:1015900045C2CA3444A2C9F844E2C9BC44C2C980A5 +:1015A0004492C94495DA5A1801184402CA7084203A +:1015B00038100C08F003380E0E0A38050E0A8400A5 +:1015C00038070E0A38060E0A3C03F4DCFE04380421 +:1015D0008E0A480000D1402E1C00F081B0438002EA +:1015E000B65F49FFFB8B38471A02B45FF501CC1E8A +:1015F0004432CA7038119800E634E8188C219648B5 +:10160000381198083C33F4DCFEDC38349A0A5A1856 +:10161000140E3C13F4DB840138071A0AFE4CF00365 +:10162000380E1A0A38149A0A8004A0EF3C1C013ABA +:1016300038108E025EF09771E90C3C13F4DA3834FE +:101640009A02FE4CE261E8054432C94438119A0A14 +:1016500038149A02E220E905B00349FFFB88C01A5A +:10166000F003380E1A0A3C03F79138271A02FE04D9 +:1016700038049A0A4402C9BCC2085A28010E8422BE +:10168000EB6038261A0AD5088422EB608401EAD47C +:10169000D5038521D502852038061A025A08012A69 +:1016A00084204402C92444E2C8E8EBAC40071C0093 +:1016B00049FFFB925EF0003C806E4412C8C8E9020C +:1016C000EB0EEB7538251A0138119A014402C88CCB +:1016D0008A2238101A0940251C009847981FA40137 +:1016E000A4918A02AC098402EAD44E92000ED5433A +:1016F0004E9300425A08030940051C0038D51A09C8 +:1017000012800001D5384412C8E88827B00349FF89 +:10171000FAF549FFFAFF4412C924382099019601CD +:10172000E240E802EB754402C8C8382019013800CD +:101730009901E202E9074402C92438201909840307 +:10174000EAD4381099014432C88C9A1138119A1190 +:10175000886722318001FE44FE1C4010883640001C +:1017600008164016840138151A0940040001401576 +:101770001C00AC0938051A0188EA12058000A4395A +:101780001205800138061A028E01E603E905F1030D +:101790004402C8E8EB60FCE2FC60EBFE22508001F2 +:1017A000EB23EB564472C850B4C0411188083C1D6D +:1017B000FEE85A680112AD10AD51A60DF8DC5A00D2 +:1017C0000104480000E54472C814840038038E09FF +:1017D00088F1AC39FCE001208005013000185B285D +:1017E000013E54098002C03A4402C81438600E1108 +:1017F000881122000001CE05C03138438E11D52E4C +:10180000C8064003C40022500001D5284013C4007C +:10181000EA7B53030000FF8C38138E118144426031 +:101820000475424840244210002442B040244090B5 +:101830009000424228244245947542401875FE02A9 +:1018400042004024FE6C4210287342181875404232 +:1018500024964010A4369723974B54098002C07CED +:101860003C0DFEE7802402600009E086E908393378 +:101870008E11E1E6E80F51337FFFD50C4E4400088E +:1018800039338E114F3500078660D5048264852078 +:10189000D50285210300000A8005E0B0E90A4093E3 +:1018A000C40022948001E130E81150987FFFD50EEA +:1018B0004E54000A4093C40022A480018520429522 +:1018C0002401D5045A980149812538A38E1140B3CB +:1018D000C40022B5800140D2280140C2AC014ED2E2 +:1018E000000C840240E9A8014006801642073073CC +:1018F00040003416880B4EC2000C842240E4AC0138 +:1019000040160436421734734010B036882A4C957E +:10191000803BE026E9055263000188C1D5044E14DE +:101920000033FF8A4D35000DE010E9055308000132 +:101930008980D5074E04000553000000D5028600BB +:10194000E186E805404980119743D506E0D0E804D8 +:10195000970B405480115B28010F38138E0144020D +:10196000C8149A6138100E094013C400A4498811A4 +:101970009A69AC4138438E0988F1AD7983FFAD1087 +:10198000AD51FCE04D353FE984C0D5CFFCE0FC63B0 +:101990003CADFEE880C0021500053C0DFA85E20171 +:1019A000E8048C013C0FFA8584E0509300088167BD +:1019B0003C8DFEE700340009E2E3E86D0404FFFE1D +:1019C000C0665A00056502048002120F800A0204F4 +:1019D0008003120F800BB0458047800649FFFA183C +:1019E000F083B04500050001B61F80418006806786 +:1019F0003C4DFA853C5DFEAF49FFFBBE0005000291 +:101A0000C007B04580068041806749FFFDB30005EF +:101A10000003C008B045800680418067F40349FF99 +:101A2000FC8400050004C008B04580068041806742 +:101A3000F40349FFFD35B04580068041806749FFCA +:101A4000FEAD220F800A4E04000412BF800A020479 +:101A50000009221F800AE020E9048E01120F800A8B +:101A6000220F800B4E04000412BF800B0204000AF8 +:101A7000221F800BE020E9048E01120F800B020F61 +:101A8000800AEABF020F800B120480018CE150949F +:101A90008044D58F4440004480A6426190733C2727 +:101AA000FD5E3C17FD5F3C0DFA858066D30CB48566 +:101AB0005A480507222280042212800584005052D1 +:101AC0008044D5F53C2BFD5E3C1BFD5F3C0FFA8549 +:101AD000FCE3FC41F481411200114102400A004044 +:101AE000005A226080009724EA7B8641C4073C6B41 +:101AF000F9983C1BF997EB08D518B4805A48031A9B +:101B00003C7DFCC93C4DFCCA88272E77F32C88C449 +:101B10008CE197F8E6EFEB08EBB93E77F32CE9465A +:101B200040631CD6EB08EB8CEBB93F27F32CD53E7A +:101B30005A48013B3C7DFEE63D37F998A7383D27E2 +:101B4000F9975A4801654049980142F2000302930F +:101B500080044049040142420003888F4094840875 +:101B6000E324E8550293800340748408E1E7E80326 +:101B7000E0C7E8613CADFEE7024500098E818A8935 +:101B80009521E093E803E086E856E1C7E803E02703 +:101B9000E8520275000A8EE18AE995F9E0F2E83729 +:101BA000E0E1E849D534EB08EBB95A58012AB40012 +:101BB0005A0801273C1DFEE6A40DE260E8213C0D19 +:101BC000FCCA3C4DFCC94030440142F18003A54EA3 +:101BD00040324001EB22886F9569E065E811A4CF9F +:101BE0009F594202C4734242C07340118409880164 +:101BF000882440000C16EB613C0FFCCAEBB93C0D8D +:101C0000FCCAAC103C0DFCC9AC11FCC13C7DFCC94C +:101C10003C4DFCCA88272E77F32C88C48CE197F8BA +:101C200040631CD63E77F32C40709CF6EB083C7F5B +:101C3000FCC9D5BC3D3FFCCA3D2FFCC9D5B7FC2033 +:101C400004600011EAE2EAB2FF764461000022700B +:101C50008000224080013C3DFCC73C1DFCC8D604EE +:101C6000B4005A08010A84003C7FFCC83C4FFCC702 +:101C70003C0FFCC6D53A978B975B41139801410204 +:101C800014013C1DFEE542088003423800038860D1 +:101C90000200800E3C3FFCC6E060E8230010801E7E +:101CA00080E09F0942720C73FE0C80674213C424CB +:101CB0004040040A4F1500048824D5028A244010AD +:101CC000803688263C1FFCC84211C0244F05000402 +:101CD0008824D5028A24EAAE88053C0FFCC7D505C6 +:101CE0003C7FFCC83C4FFCC73C0DFCC8AC103C0D15 +:101CF000FCC7AC11FCA0FC20227080002260800197 +:101D00002E1010E53D37F98A3D07F9883C5DFEE667 +:101D1000C10F3C3DFB6E848A4031907704428009BC +:101D200096D940420C960432800AFF1CD50300422B +:101D3000801EB4005A08010A84003C7FFCC53C6F39 +:101D4000FCC43C0FFCC3D54C4123CC0141134001E2 +:101D50000212800E420900034238800388609449D1 +:101D6000E0613C3FFCC3E8382E000404C00C2E00A8 +:101D700004055A001F092E000406C0052E000407A2 +:101D80005A08310AFA03808142418073FA04806460 +:101D9000FE0CD5089E2180A142500C734200902475 +:101DA00080654211C8244040040A4F25000488245D +:101DB000D5028A244010803688333C1FFCC5EBFDD9 +:101DC0004F1500048864D5028A644001801688108B +:101DD0003C0FFCC4D5053C7FFCC53C6FFCC43C0DEE +:101DE000FCC5AC103C0DFCC4AC11FCA0FC203C6D4F +:101DF000FEE6EB652270800100130010C902842109 +:101E00002E4010E5C40F3C4DFB6E84AA404214974F +:101E1000045300099721404290970453000AFF643D +:101E2000D5115041FFC497215CF20C080253000900 +:101E3000E8075043FFC497215CF21388E9028CA5A0 +:101E40009569B4803C5FFCBC5A48011384003E078E +:101E5000F2E03E07F2DE020300093C3BF976940112 +:101E60003C7BF9753E47F2EE3C0FFCBCD5533D0779 +:101E7000F9753D27F97640581C0140090C01FF6CAB +:101E8000425000733C0DFCBC4512C7B0E2A02E5777 +:101E9000F2EE8400E9028401380894089E09D8080B +:101EA00084003E07F2EE84013E07F2DED5048CA1E9 +:101EB0003E57F2EE2E47F2DECC0C2E57F2EE8004A7 +:101EC000E205E82F38688000CE028C818C01D5F9BC +:101ED00084A08005E201E80738F88000E9028CA1BF +:101EE0008C01D5F95A480109E0A1E8060203000A6D +:101EF00094013C0FFCBC9B0DFEE44232C8734202CD +:101F00001C24EB383C3BF9764202C073EAA63C0B3A +:101F1000F9753C03F976AC103C03F975AC11FCA0E3 +:101F20009B8D8AA488C4FEEC4233487342029C24F1 +:101F3000EB383C3BF97642034073D5E9FC00EBFEFD +:101F4000223080012E1010E53C5DFEE6C1050062E6 +:101F50008022FA24D5050012802000628022B4007D +:101F60005A0801063C4BF96EEBC6D52A3C07F96DC1 +:101F70003C57F96E8A038AA4FE04420294732E57DA +:101F8000F2D99449E2015A58010CE91C84003E0739 +:101F9000F2D93C4BF96EEBC63E07F2D8D513E808F0 +:101FA0002E07F2D8E206E8048C013E07F2D82E078D +:101FB000F2D83C4BF96EE206EBC6E90484013E0719 +:101FC000F2D93C03F96EAC103C03F96DAC11FC8006 +:101FD000FC403C9DFEE5EBFE0054801622300008DC +:101FE00022700009EA7B8621C506E6A98628E80357 +:101FF00041128013005480178601C506E6A98608A1 +:10200000E80341028013B5405AA0010A0400001100 +:10201000EAE2EAB2FF4644010000D81784003C0F10 +:10202000FCB53C0FFCB484013D1FFCB33D1FFCB26A +:102030003C3BF9543C7BF9553C4BF9443C1BF9457E +:102040003C0FFCA1480000B05AA80304480000AAB5 +:102050003C0DFCA151287FFF8C01420040013C0F48 +:10206000FCA13C0DFCB4E012E8038C01D502840015 +:102070003C0FFCB43C0DFCB53C5DFCB4C8064C59AF +:10208000400584013C0FFCB54462C778942A413373 +:102090000000127980014532C758384996098813E3 +:1020A0003C4DFCB338331609AC413C4FFCB24E57A3 +:1020B00000099E6938030611406304409AC3D5069F +:1020C00038034A11406348409AC322130001420179 +:1020D00080038A27EB330264800D8801E2C08026EA +:1020E000E9060214800CE20140103C1A3C0DFCB5DC +:1020F000C8043D1FFCB3D5105AA0040F0204800C85 +:10210000403844018A20FE5C9A3040008017400825 +:1021100000013C0FFCB33C0DFCB3842380644230CF +:102120008073842480038C02EAA6E080E9043C0FDB +:10213000FCB3D5048C813C4FFCB33C0DFCB3E011E7 +:10214000E8043D1FFCB3D505E180E8033D0FFCB377 +:102150003C0DFCA13C1DFCB3E001E8033C0FFCB3CB +:1021600084203C0DFCB380C180814C1000103839B4 +:1021700096118883403994402231800188C3C50379 +:102180008EA1D50280B28C21D5F1846240008C16DC +:102190008880880640420496EAE79723964BD50349 +:1021A00084208081AD10AC51FCC0FC6B80C0EAE2A1 +:1021B00004000011EAB2FF4644010000D804841F65 +:1021C0003C0FFA843C1DFEE53C0DFA84A44DE2016F +:1021D000E8048C013C0FFA84B4064E02014A5A0806 +:1021E0000504480001462E00038CC00C2E00038E0F +:1021F000C0092E00038D5A001F062E00038F5A08B7 +:10220000310A00030045C8060003005A96044E0236 +:102210000136021300180203000E449000648A0184 +:102220009603EB49021300190203000F85418A014E +:102230009603EB9DEAFB96039001EB49EADB9603DC +:102240009001EB9DEAA9960BEAA9023F8001964B0B +:10225000022F8001FE44421188738403964B84410F +:10226000F82E80E0420024244410005AEAE797F94F +:10227000FFFC964B84418400F82252139FA4100364 +:102280000078964B84418403F81AEAA942B02800EA +:10229000964BEB334210A424804A4010AC368402A3 +:1022A000964BF80D023F800180E096DBEB22423135 +:1022B000A42484024011AC36804A964B49FFF60EA6 +:1022C000EAA9964B4E160005FE7A974BD50280A7D9 +:1022D000EBCC12530012964B4E160004FE029603EE +:1022E00044416B348044B0C23B01480480233B002E +:1022F000C824120300130291000044216B44129081 +:1023000080008262B0463B09C80480E13B03C824D8 +:102310000339800013338000B1CA3B024804808730 +:102320003B02482412920000509F80383B01480431 +:1023300080493B01482413310000513F804844212B +:102340006B543B01480480933B024824A490ACA00A +:10235000002300785CF10028E9575CF10032E803C3 +:10236000EB59D5034440006A4302800342A00003B6 +:10237000402828019693422100039693862139290B +:10238000C511E1C2E8058DA141188013D5F9864D2C +:10239000431944015128FFFFE15041290013E9038B +:1023A0008209D50380E182033899C911381849118F +:1023B0008A4996D13829C51141312401382845115F +:1023C0003903C9118A41FE9C969340214C5688419D +:1023D0003813C51196938A30FECCFEA4965B40302C +:1023E000CC76887096DBFF1C44700064EBC84042DA +:1023F0001C9642128824FE24EB8C40001C161213FB +:10240000001212030013EAFB96035EF00051E90389 +:10241000EA93EB49EAFB96035EF07FB0E804440FD1 +:10242000FFB0EB49EADB96035EF00051E903EA9363 +:10243000EB9DEADB96035EF07FB0E804440FFFB04B +:10244000EB9D02030012B041EAF702030013804142 +:10245000EA4B800649FFFDBEB0418006804149FF3E +:10246000FBF0EB4F12030014EA5912030015B406F7 +:102470005A08050584003C0FFA84FCEBFC403D2D16 +:10248000FEE6EB6500690016EA7BC605E6C9E805CD +:1024900097B1D50484C1D50284C800490017C4058A +:1024A000E689E8059721D5048481D5028488B5E0C2 +:1024B00084A05B3801123C5FFCA03C5FFC9F3C6F3A +:1024C000FC9E3C6FFC9D3C3BF92A3C1BF92B3D3F9D +:1024D000FC94480000A85B380304480000A23C0DAF +:1024E000FC9451027FFF8C01420010013C0FFC94D0 +:1024F0003C0DFC9FE010E8058C013C0FFC9FD503D0 +:102500003C5FFC9F3C0DFCA03C5DFC9FC8064C580A +:10251000400584013C0FFCA04472C7244003944052 +:102520003D1DFC9E38339609AC413D1FFC9D4E5726 +:10253000000C5092FFFF3803A6114093A4409AC3A9 +:1025400022048001D5083803C2119AC34003C04059 +:10255000220000019A41EB22EB3388230239000D5F +:1025600094D9E2618003E9060209000C9401E2209B +:10257000EB3E3C1DFCA0C9043C6FFC9ED5105B30BB +:10258000040F0219000C412084088A129A66FE0C7E +:102590008A7240000C179A203C0FFC9EEBE48423C7 +:1025A000807142308073842480038C02EAA6E1A00B +:1025B000E9043C0FFC9ED5048DA13D1FFC9EEBE47D +:1025C000E006E8043C6FFC9ED505E080E8033C4F44 +:1025D000FC9E3C0DFC943C1DFC9EE001E8033C0F7E +:1025E000FC9E8420EBE480C180814C1000103833C5 +:1025F00096118883403394402231800188C3C503FB +:102600008EA1D50280B08C21D5F1846240008C1659 +:1026100098E08806EB38EAE796DB964BD5038025F1 +:102620008065ACD0AC51FCC0FC40B480EB6522703E +:1026300080013C1DFEE65A480113ACD0ADD1A60D79 +:102640003C3BF9263C7BF9275A000104480000CDA9 +:1026500084003C0BF9243C0BF925FCC0A78D01003C +:10266000005A5A68013554080002C0313C47F92429 +:102670003C07F925CC05C02B3C37F926D5283C175B +:10268000F927C80380E1D523FF62FF0C3C17F92628 +:102690008243424004754232942442100024433065 +:1026A000142441108C004231C82442399C754230B8 +:1026B0001075FE02FE2CFE7C42104873421290758B +:1026C0004031C4764010C43696DB97CB54080002E4 +:1026D000C06E5EF18C80E9093C57F9265EF28C8071 +:1026E000E80F44500C7FD50C4E3400083C57F926B7 +:1026F0004E55000784A0D50480A38400D502840130 +:102700005EF39400E9073C47F9275EF21400E962A2 +:10271000D50C4E7400083C07F92784804240100114 +:10272000D5045A08014580873D17F9263D07F9274A +:1027300040F1C401802380074123C001E80B8402DB +:102740004092C401400780164204C87340003C1602 +:1027500088104F22000C8422409240014019043618 +:102760004214BC734010C83688314C48003A5EF0C1 +:102770008C80E9045100F381D5054E1400325300DA +:1027800080004C58800E5EF01400E90451106C017A +:10279000D5054E04002353100000E1B0E80496EB89 +:1027A00097C3D505E191E80396CB97E35A68010CEE +:1027B0003C03F9269A183C0BF9243C03F9279A3874 +:1027C0003C0BF9253C3BF9263C7BF927ACD0ADD13D +:1027D000FCC0444013FFD5A94F02FFEAD5E18600B3 +:1027E0004C58FFD3D5E4FCC0FC2180C0EAE20400D1 +:1027F0000011EAB2FF4644010000D80984003C0BF6 +:10280000FD5C3C0BFD5D841F3C0FFA833C7DFEE6C6 +:102810003C0DFA83A47DE201E8048C013C0FFA83AD +:10282000B406C05C5A00055B0203000AEAF7020323 +:10283000000BEA4BB041800680413C3DFA833C4DA1 +:10284000FEAEA77949FFF947A63AC006B041800617 +:10285000804149FFFACDA63BC006B04180068041C9 +:1028600049FFFE0EA63CC006B0418006804149FFEC +:10287000FA44B0418006804149FFFB620003005AE0 +:10288000960EC0070203000AEAF70203000BEA4BA8 +:10289000B0418006804149FFFEC9220F80024E04EC +:1028A00000048400EAF722FF80025EF78C80E904CE +:1028B00044000C7FEAF7220F80034E0400048400DA +:1028C000EA4B22FF80035EF79400E904440013FF03 +:1028D000EA4BEB4FAC36EA59AC37B4065A08050B55 +:1028E000A4363C0BFD5CA4373C0BFD5D84003C0F23 +:1028F000FA83FCA13C0FFF23DD9E3C0FFF22DD9EEF +:102900004402D10884213C0FFEF784003E07FBE01F +:102910003E07FBE13E07FBE23E07FBE33E07FBE42D +:10292000EBA63E07FBE63E07FBA93E07FBA83E07DA +:10293000FBAA3C1FFA863E07EDD74412D0B88400AC +:10294000845FEAB98C015A084FFEDD9EFC00EB6300 +:10295000FC80FC0080C049FFA7A7C0048400AE34FF +:10296000AE35FC802E07FBB0DD9EEBA4DD9E44322D +:10297000D078AE18AE59AE9ADD9E3C0FFA86DD9E39 +:102980003C0DFA86DD9E3C0DFB75465FF00FEAB20A +:10299000FF4646001000D80684003E07EDD78401AC +:1029A000DD9E8400DD9E2E17FBE22E57FBE3EB211C +:1029B0004C12C0102E27FBE05A28010CA6059D4999 +:1029C000400280B697683E57FBE23E57FBE3DD9E30 +:1029D000A6058CA1400280B697683E57FBE3D90458 +:1029E00084013E07FBE0DD9E2E57FBE22E17FBE342 +:1029F000D9042E07FBE0C00FEB218CA1A6054002F5 +:102A000080B697683E57FBE24C12C00584003E0733 +:102A1000FBE08401DD9E2E57FBE22E07FBE3D80787 +:102A20002E07FBE084208E01EBB2DD9E8401DD9E4B +:102A30002E57FBE22E07FBE3D8072E17FBE084009E +:102A400040000406DD9E8401DD9EFC0084A08C8194 +:102A5000E2A4E8073860080438608C0C8CA1D5F932 +:102A6000FC8080603C0DFA869E41E622E8263C2DE3 +:102A7000FF2284200041000AE224E809A1593852CB +:102A800087025A58010384028C21D5F7FC00842068 +:102A90000041000944500044E224E80CB4434220C1 +:102AA0009473B4429F91E6C2E9065A2004058C2132 +:102AB000D5F4FC808401FC80DD9EFC618141B4C1C1 +:102AC000843F101F80072E172BC88120C1082E17A6 +:102AD000FBB0C90549FFFFC73C0FFA863C3DFA86AB +:102AE0005A3001044800009C84E03C5DFF222F27FF +:102AF000FBA43D3C04283CBDFF23802344C000448C +:102B000081A781C78506861F86229E8900028009CB +:102B10009690E240E81243413024B40941505000FD +:102B2000B4159E81E642E9035A0804760404800342 +:102B3000B4009E81E642E808841F1003003E1003A3 +:102B4000003F480000AB5A0004F9DD5A5A0802055C +:102B50002E001117C8F25B2801045B3005EF000559 +:102B60008003222A8004224A8005037280020362C5 +:102B70008003C01702028009518BFFFF8E0140F0D5 +:102B800045F642F16073518B7FFF40278056020269 +:102B9000800A8E0140F045F642F26073404780960D +:102BA000E057E903502BFFFFE09642013400E903B0 +:102BB000504B7FFF81E642F3A073844240210464BE +:102BC00042423800102780004020100A1027800160 +:102BD0004022100A10278002971F40420084020AF8 +:102BE000800A10478003C006B449885400010014CD +:102BF000D502840110078004020A800BC0039600EE +:102C0000D50284018CE11007800597F81103003C80 +:102C10001103003D8C21964848FFFF795A3802275E +:102C200084181003003C84E084001003003D3C4DF8 +:102C3000FF2280070012000AE201E8130414800159 +:102C4000381083025A18010B0023003D4010800CFD +:102C5000FE578CE11013003D97F88C019600D5EBE0 +:102C60000003003D3E07FBABD5182E77FBA8C71528 +:102C70002E07FBA9A670E61EE80596574000806463 +:102C8000D503440000F0AE302E07FBAAAE3284011B +:102C9000AFF13E07FBB084E02E07FBB05A00FF0DFA +:102CA000C00BCF0A841F3E07FBB03C0DFEEB8C012E +:102CB0003C0FFEEBD5033E77FBB05A3801143C0DB8 +:102CC000FF2200400009E2E4E80D84268406FE7C31 +:102CD0008A87B44AFF0496488822EBBC84408E81E0 +:102CE000F93EB42A840080A150208040083280013F +:102CF00088039600DAFCFE02100080400424800362 +:102D0000B4029E41E622E9055A000404480000C8C6 +:102D100022110006220100075EF08C80E805846025 +:102D200042108C00D50344100C7F5EF01400E805BF +:102D3000846042000C00D503440013FF00210072A0 +:102D400084615A280104443000F010330041042407 +:102D500080035A38F02D840010010072041480039F +:102D60004420FF0004008014043080154010080245 +:102D700092281013004240106009101300444610BE +:102D80000FF010030043FE0E9210FE9EFE5EEBFB62 +:102D900092484001E009923010230046103300476A +:102DA00010030048101300498489D56D4030A00AF3 +:102DB000101300434010200A103300421013004447 +:102DC000EBFB00010043C80602010025C80884018E +:102DD000D5045A08010584001201002502010025CE +:102DE0001003004740102009101300463C1DFF232C +:102DF000A608C00602010014FE029603D5032201B4 +:102E00000014A6C9C30602310015FEDA96DBD5030D +:102E100022310015A64AC9061003004810330049A4 +:102E2000D505103300481003004984001003004A00 +:102E3000000100431003004B0001004096440003D2 +:102E4000004CEB26FE0F1003004C00010040541014 +:102E500000020003004C9604FE0F1003004C00011A +:102E600000415A0001085A0002085A080309EACF33 +:102E7000D507FA10D50544000040D502FA0010032A +:102E8000004D848DB44A501200418822EBBC84402E +:102E900084615242000DF8638421D50AB42AEBBC48 +:102EA0005010804184408461848DF8598420B44A54 +:102EB0008400505100415031004E08428001880486 +:102EC0009600DBFCFE021001004EEBA45A00FF0A44 +:102ED000C008C907841F3E07FBA4CF078401D5069D +:102EE0003E17FBA4CF02C1FB84003E07FBE6FCE1DA +:102EF000FC00844180624440004EF831FC80A60012 +:102F000092038C1596275C000014DD9EFC4080E047 +:102F10008400EBA6A63880C1C80400038008C03333 +:102F20002E101116C9302E07FBE15A08010B2E276F +:102F3000FBE43E27FBE23E27FBE33E17FBE0EBA66C +:102F400049FFFD33EB212E97FBE3A7043C1DFEF761 +:102F50008441A0394214907380628E8149FFFD77CD +:102F60002E07FBE65A0801063E07FBE13E97FBE40D +:102F70002E07FBA55A00FF058C013E07FBA5840127 +:102F8000EBA1D50484003E07FBA52E17FBE5B40694 +:102F90005A18012AA605C814F835C80DEB212E379A +:102FA000FBE4A684B4263C0DFEF742018873B421ED +:102FB000F839D50849FFA449F825C8FFD5F0F8220B +:102FC000C802F845B4268400EBA63E07FBE1840165 +:102FD000AE0DB426AE0CB4C6B406F8345A08013DA2 +:102FE000AE37D53AA644C904F871C036D50BA6054C +:102FF0005A080106F807C830F82AD52E49FFFD0DFA +:10300000C8FA49FFA45580E0C82749FFFCEFEB212F +:103010002E97FBE2A684B4263C0DFEF7B4214204B1 +:10302000887349FFFF672E17FBE15A1801112E57CD +:10303000FBE44C54C00DB4063E77FBE1AE45B4E66C +:10304000B40749FFFF5E5A080103AE3F49FFA440A1 +:10305000B4068421AE44FCC0FC2080E1A0413C1FAA +:10306000FEF22E17FBB03E17FBD0A042A0033C0F90 +:10307000FEF5EBA43E07FBD82E0011164422D0B873 +:103080003C1FFEF33C2FFEF180C2C8074402D098DB +:103090004412D09449FFFD132E07FBB03E07FBB846 +:1030A000EBA43E07FBC0B4074412D0843C0FFEEDF6 +:1030B0004402D0883C6FFEEF49FFFF2A84003E07A0 +:1030C000FBA83E07FBA93E07FBAA49FFFCB3FCA0F7 +:1030D0003C0E0008DD9E3C0E0007DD9EFC6051FFAB +:1030E000F800F385506F81348460F182F2863C5C95 +:1030F0000007802686018223F202F284E262E82A37 +:1031000022400000222000011240800A1240800C60 +:10311000F4051220800B1220800DA081A124142020 +:10312000800B40220820A7D1C70BA72A8E814C72A2 +:103130000008A710C405A6AB8E414C414005110004 +:103140008035D503111080358C61501080388C0883 +:10315000D5D42E1000188400F18150EF80448040B7 +:10316000512F8080511F80BC510F80F8447000386F +:10317000EB9842301C243827020A99733829020A36 +:103180003828820A3828020A88648C011022802A92 +:103190001021802A5A080FEFEB0EFE0CF083F0028C +:1031A0003C3C0008E201511F847C8206856014FFCC +:1031B000800786DF47E1000086AA4798000047891C +:1031C000000044D00064F002E3604EF200D98401B4 +:1031D00038072E0A84E04402D198F2034C7100CAE9 +:1031E000F2072248000CC2092220000E2250000FD4 +:1031F0008A822228000DD5082220000C2250000DC2 +:103200008A822228000D8A45FE9442221073237878 +:10321000000C2240000C2348000D413B900122404D +:10322000000D04800009409A10014254A424425920 +:10323000CC73B5405A880407004000285A4801035F +:10324000F8610440000CCC59A119E2A44EF3032804 +:10325000A51942451024E2A4E830A11AE2A4E80B23 +:10326000A10404A00003424490244249A8734E469E +:103270000317D523A11BE2A4E820A1040520000325 +:10328000424490244249C8730121802743323424A8 +:103290004322C8244139AA774339CC2444902710CB +:1032A0004339A8244129365740F9A5F7E3CFE8056B +:1032B0004E4700044EA302F4004000290121800083 +:1032C000E3C4E805A11CE2A44EF302EA0041802613 +:1032D0004E4202F0A11BFF24E2A44EF202EB5A88F8 +:1032E0000403F810004800354E4302E40040003566 +:1032F0004E4302E08858D5355A400203F8035A88F5 +:103300000404480002D704F1800122A0000EE2AFBD +:1033100004C000032240000F052000044EF302C049 +:1033200000518028889242861424425914244084F3 +:1033300055164052D4B6404A1001894C40ABA80102 +:10334000FF24FF6C4245287342542073E0854EF2FF +:1033500002B14244C8244249B0734E4702AB885977 +:1033600038289C0A5073803C5000003848FFFF37D3 +:103370008D618DA45108003848FFFF2784008441E7 +:10338000E201E806B0E03821820A8C01D5FAF002A9 +:10339000E60BE80AE62BE808804EB0E0EB4CB149BA +:1033A000490003BCD508F002804EB0E0EB4CB149B7 +:1033B000490003713C1C0008F1834420003884203C +:1033C0004798FFFF820144C2D19885AF519C8FFF7F +:1033D00083C2518F80F88521517F80BC850286C3CE +:1033E000E38044B2D1984EF200F4B0C94031C0201D +:1033F000A6D980AC425188730452800C5A580211ED +:10340000B109385241004251B473EB4C38521602A4 +:103410004E550007B12038920E0A480000D744727A +:10342000D198B10942718873385241000123803626 +:1034300080E6EB4AF405511380305073802804A3D2 +:10344000800105320003F40338F9A90102A2001536 +:1034500011288006E34FE80C4F23000B0123800264 +:10346000848159290001112380021048800680E6DA +:10347000EB4AEB98EBC450F3801822A7800123227B +:10348000000D22B3800C412548012332000C435922 +:1034900048241523800489CA1327800382454135B7 +:1034A000CC014321B47382874359CC738224EB4C03 +:1034B0001D5A000239224A02153A000189EB1337DE +:1034C000800240FCC80651438010E80D8DB0148383 +:1034D000800C02788002127A000202788003127A4D +:1034E0000003D50484801443800C80E6EB98EB4AFB +:1034F000EBC450A380105132001022B98002232562 +:103500000002233980038BCB152380012325000380 +:103510008BD301320020113380200532000915239E +:103520008002512380205B3803160123803601126C +:1035300000285B2801038FA11113802880E6EB4A45 +:1035400080890113802850738020404B441BA93987 +:10355000D5031489000180EC4271887300738034B4 +:103560005CF380C8E8038CE197F88246EB9843222D +:10357000F8734241F873F3031079003451190028AD +:10358000A0DDB5D200720029E27210788001E80552 +:10359000E6EAE80B8CE1D507F303A0DEE3C3E80518 +:1035A000C7048EE110788001806642328873389BB0 +:1035B000960A003180208C21389C0E0AF3048E611B +:1035C000F384F3018E61F3818D8148FFFF0B84A0AA +:1035D000B0A0800B8145B1EF44C00038852185A59E +:1035E00085042E300018E2A33C3C0007E803F401F8 +:1035F000CC0A844086018006814282228110858324 +:103600004800009300F18009E22FE8F40D01000169 +:103610005B080179050000095B080308F30114A1A8 +:103620007FFF8E61F381D56E8F81E782E80D050003 +:10363000000C5B080206848010400028D50AF403C1 +:1036400001020001D504010000288F81110000282B +:10365000010000285B0801080110002A59188004A5 +:103660001110002A0031801987C040FF0C06E823A2 +:1036700038F3FA02E91D38F77A02E91A8068403611 +:10368000C01A1430000981E080663B07E404423F21 +:1036900030733B01E4243B07CC003B01CC200030DD +:1036A0000020B13E38920E0A3893FA0AD52551EF20 +:1036B0000001D5DC85E0D50350F780014CF1802373 +:1036C0003843BE02CCFA80684036C01A1430000974 +:1036D00083C080663B0F64044237B0733B01E4242F +:1036E0003B0F4C003B01CC2000300020B13E389213 +:1036F0000E0A3893BE0AF30114A17FFF8E61F38195 +:103700008C218CA15000003848FFFF6DF404C47078 +:1037100001218009E232E86C38570A025A50010947 +:103720008C4150000038F402E244E9F1D561B12F38 +:1037300038520A02CDF6B13E38721602CF55F40364 +:10374000B6E0A9C1A9C2A9C3A9C40270000C127035 +:10375000000E0270000D1270000F99E1F405007365 +:10376000801C05320003F403105000201070002864 +:103770000490000B03220015CF0D3879A501E3C793 +:10378000E80415000009D50F14C0000910800028B6 +:10379000D50A38F9A50114C00009E3CFE9048CE18A +:1037A000107000283879A501B13EE3C780E8407861 +:1037B000BC1A3902160AB12F1070003639020A0AF3 +:1037C0000070002AF404587380018E8111100034B7 +:1037D000111000291070002A14A0000C38A70A0A42 +:1037E000F4848C21D59E8CA1E2B2E9A6D59A8400FE +:1037F00044200044808000118009E201E808421062 +:103800000824F5068C013842840AD5F684003E006F +:1038100000188420509F80BC44A0004444C000385D +:1038200000018019E220E849EAF05A0801350473E2 +:1038300000095A7005132E200018800B80A63B0249 +:10384000E404420130738C413B0064243B02CC0011 +:103850003B004C203E20001800030020F2064220CE +:1038600028738002B6E20023002A102000180223E9 +:10387000000AAC820223000BAC830423000BA88750 +:10388000B44650400024B644A0B1A8A1A0B2A8A25A +:10389000EAE6A8A38C2150630038D5C35A800303FD +:1038A000F806004000344E43FD5D885E48FFFD5A37 +:1038B00039689C0A48FFFD5851FF8800FCE08400ED +:1038C0003E000018DD9E4402B5B03C0E0005DD9EB2 +:1038D000FC67006080092300000223100003C6106B +:1038E0003C5C0007A6EA8E614C61800B00308008CA +:1038F000C307A7AB8EC1FF9D5C630001D50284C1E5 +:1039000084603E37FCBAEAE204300011EAB2FF5E9E +:10391000447100004432D160DF0D84A53C5FFF2D6F +:1039200084A03C5BFE543C5BFE553C5BFE523C5B22 +:10393000FE533C5DFF2DC26AC50485605A580509D7 +:103940003C7C000585610073801C3E77FCB83C77A9 +:10395000FE5441281C013C77FE5540789C01FFFC39 +:10396000427948735A500305C5035A5805153C4C13 +:10397000000502520011A508E2A42E47FCB8E80792 +:10398000A449E2A1E804C4038E81972084A3CC0457 +:1039900084A1D50284A2819181108420B6205A503E +:1039A000051EB6FFEB9B149F8002128F800A12CF78 +:1039B000800B130F800C131F800DF589104F80288A +:1039C00010BF802A106F8035803F3B00E4043B012C +:1039D000E4243B00CC003B01CC203E200010B6A0EC +:1039E00010B0005A1280000412C0000514700017B5 +:1039F00014A00018149000191420001A5A58014AF3 +:103A00001280001C12C0001DD5449E69E622E80CFD +:103A10003C1C00052E47EF96A6495A48010EE625A4 +:103A2000E80B8425D5095A5803043E27FCB82E1705 +:103A3000FCB8C1048E213E17FCB82E47FCB85A488A +:103A4000010684243E17FCBAD5038425C4028424CD +:103A50003C1FFF2D80C3803F3B0364043B00E424F4 +:103A60003B034C003B00CC203C7DFF243CADFF25BC +:103A70003C9DFF263C87FE5280B93CC7FE533D0764 +:103A8000FE543D17FE552EB7FCBA2E67FCC5D586F1 +:103A9000FCE7FC608160822084008241812082609A +:103AA00084E1810044E0003C4F1200374F22003592 +:103AB0005A78013384C080E6855E4C65801E3901EA +:103AC0001A025B0801184142184086004D0080131D +:103AD00038D1C2025AD8010D42C8382438CA30023F +:103AE00040F62806E8058130826680ED814C8D81A4 +:103AF000D5EE8CC1D5E3C7D94062802011330000D8 +:103B0000109300019D8138814E0A96303881A60AB3 +:103B10008FA18FC1D5CAFCE0FC6051FFFB9880C02B +:103B2000C06AC168E220E83080E14510003C865F51 +:103B300082044303C47384003928020A8C014C03B5 +:103B40007FFD8CE14C737FF6800181C1802681A5C9 +:103B500081448183816249FFC62EB03949FFC63254 +:103B6000800A49FFC640801F49FFC6498126840F4D +:103B700084C049FFC65549FFC65880A6862F4430E9 +:103B8000003C8046D520E201E8E084E04510003C9E +:103B9000865F82044303C47380063928020A8C01BD +:103BA0004C00FFFD8CE14C70FFF6D5CF40081000B3 +:103BB000380F80005A00010F8D814D04FFF98CA150 +:103BC0004C57001A802A4242C42442128C73860049 +:103BD000D5EE3800C2025A07FFF1400698209DF149 +:103BE00011000000AF4197B83825C20A3826160ADE +:103BF000D5E480C1800651FF8468FCE03C0E005E85 +:103C0000DD9E3C0E005DDD9EFC6050B0FFFF8542F6 +:103C10003CCC005D3C4C00483C2C00473D0C005E19 +:103C200040A5A9564532D6308C0C4432D5F44462B6 +:103C3000D5CC4522D5DC862085014492D51885AFA8 +:103C400085C400160009E3A14EF200D404707FFD84 +:103C50004E7200C70010000C974CC50B10898000F5 +:103C600022100000AC5822100001AC59480000B9E5 +:103C70005A7004044800008400298000CA3A0049B0 +:103C800000005A400106A7F0808280A2D51E015391 +:103C900000004074C440808280A285E14C5AC00379 +:103CA00085E2234380008CA14247D07323438001E7 +:103CB00097684227D0735073803C5A5803F04042B3 +:103CC000389640213856D51781F142F2B4738CA151 +:103CD0003944BE1140F4BC4022F780019768884FF8 +:103CE000E2E58894E8F28CE140421C96EBC8D503EB +:103CF00080458085425100034272000388E50458E4 +:103D00000001E2A7E86D54708004005800000168CB +:103D10000002C70FFF64A5D84052D8B688A7AD5897 +:103D20000058000100780003FF5440529CB6D51A99 +:103D3000407B28004073ACF60148000342539401D5 +:103D4000FF6440FA2800015800014052D8B6A5D8B7 +:103D500040F7ADF688E54257D401FF54ADD8405244 +:103D6000D0B6A5D95810800288A7AD59EBEDAD406B +:103D700022518001AD411010000CD5325A7005312E +:103D8000001980005A18010810590000AF7010592E +:103D90008000D510A670E622E8048C21AE70D50212 +:103DA000AF7000190000C906A6705A1802041089E5 +:103DB0000000A67080B14250B47322F0000080254C +:103DC000A558405794013854860922700001A5591E +:103DD000401484409B7DAD4912F18000ADD98DA186 +:103DE0008DE1500000448C648CC18DC148FFFF2BD5 +:103DF0003C4E00483C2E0047FCE04402B5D83C0E47 +:103E0000005CDD9EFC40B4404E2200F80070005A79 +:103E100096FCC30E84213E100044021000080200EC +:103E200000093C1800203C080021480000E75A2007 +:103E30000404480000AB2E27EF964E2300DF2E30FF +:103E400000443C2E000F3C2E000ECB402E200035AF +:103E50002E5000344462D4F85A20010580438083F8 +:103E6000D52180838043550200FF4D02C0048602A5 +:103E7000D5028601391312114238447341131040A0 +:103E8000231880018C81422844735A4803EE8484AD +:103E900040319076402110563C3E000F3C2E000EE3 +:103EA000D515390312118870410310408C81230805 +:103EB00000019720E2A48850E8F58CA1EBA94051BD +:103EC00014B63C3E000F3C5E000E3C5C005C3C4C7B +:103ED000000F3D2C000EA0E942F20003422900032E +:103EE000884F94D9E2624EF200893D300020A6E866 +:103EF00050F9FF105CF78AA0E90294D93D00002137 +:103F0000A6A950F87F105CF79220E90294915463BF +:103F100080040092800201128003C60FFF1C421928 +:103F20000824404224964010C436403990003C3862 +:103F3000002040280400D51A8E2184C2406098D603 +:103F400040549800EB6788D14013043642519401E5 +:103F500042110401FF2C42190424403224764020EF +:103F6000C45688733C38002088503C1000203C2800 +:103F7000002112100008587380023C10002112101A +:103F800000091070005AD5395A2005382E10004407 +:103F90005A1801093E3000353E3000343E300044AE +:103FA000D5152E100034E622E8058C213E10003491 +:103FB000D5033E3000342E100035C9082E100034D1 +:103FC0005A18020584213E100035223000083C209A +:103FD00000202E1000344442D4F89A9A3822060960 +:103FE000222000093C000021401204409A10AC0934 +:103FF0003C3800203C280021FCC0FC00001000439D +:10400000101000440420001146100FFF50108F00C4 +:10401000FE565A19002B84203E17EC6D0410001731 +:104020005CF08064E8038421D5105CF083E8E80349 +:104030008422D50B5CF0A710E8038423D506442026 +:104040004E1FE241E90484243E1000262E1004098C +:10405000C1085A101F072E100408C1035A18311244 +:1040600084203E100026D50DEB5A5A1801082E1751 +:10407000EC6D5A10FF078C21D502843F3E17EC6D82 +:104080002E47EC6D2E300026E264E91FB4205A1052 +:1040900004045A18021B842002500026101000430A +:1040A0009A5C42209424945D40110436CC033C5821 +:1040B00000123C30001296498443421188739022CA +:1040C00096493C180012D507EB5A101000435A18B5 +:1040D0000105842012100025FC803C0E0060DD9E4E +:1040E0003C0E005FDD9EFC00C0045A000108FC800D +:1040F00049FFC7033C0E0061FC8049FFC7073C0E27 +:104100000062FC808020E6093C0C0062E82344F158 +:104110003F18EB18EA8BDD0F0A3C10161C22282EE4 +:1041200034003C0C0061DD9E500000F0DD9E50002C +:1041300001E0DD9E500002D0DD9E500003C0DD9EF8 +:10414000500005A0DD9E50000780DD9E50000960F4 +:10415000DD9E8400DD9E9200FC4080C280E13C2C0C +:1041600000623C1C00618123814449FFC69F3C1CC6 +:10417000005FA60AA64B49FFC6B7EACF420300017B +:1041800049FFC6D184C03C1C006000008010E2C022 +:10419000E81080063810980049FFC6D23C0C006039 +:1041A000984600108008800649FFC6F08CC1D5EC07 +:1041B0008400F80BF80C8401F808F8095AA80105E6 +:1041C0008402F803F804840349FFC6B149FFC67F9F +:1041D00049FFC6A5EA52840000148000E201E829E4 +:1041E000A07938508101D023A07D9482956A98CA25 +:1041F0008825A6DAA70AE264E802AECAA07D98CABA +:104200008825A6DBA70BE283E802AECBA07D383081 +:1042100088008825A708E264E802AEC8A0FD8843AC +:1042200088A3A651A6A9E241E802AE698C01D5D5C2 +:10423000FCC0FC62464C01208881446308FFE2C454 +:10424000804080A14030C0094EF30082C80546037B +:10425000FF004C500121808280A1FD028440463B3A +:10426000FF00EA25FD10FD30EA24FD60FD10F8EEA8 +:1042700044216BB0FD50EA4CF8E944216BA8F8F5F5 +:1042800044216BB8FD40EA4CFD06EA24F8D44421F1 +:104290006BC8EA4CFD40F8DA44216BC0F8E64421D3 +:1042A0006BD0F8DBFD06EA243A4F9400FD10FD02C6 +:1042B000EA2544216BE0F8C744216BD8F8D64421A5 +:1042C0006BE8F8CBFD06EA24F8D544216BF0FD60DD +:1042D000EA4CF8CEFD10FD06EA25F8C9F8D0EA252B +:1042E000F8C6F8A9F8C4F082F183844046341A0075 +:1042F000F8ADFD50F80BFD15EA5FFD10FD50EA2406 +:1043000044216BA0EA4CEA24FD40FD10FD03EA25A0 +:10431000FD60FD10FD03EA5FFD14EA25FD40FD157B +:10432000FD03EA5FFD1044016BA03A000400EA249B +:104330003A0F8420FD13FD05EA253B0FC400FD1054 +:10434000FD08EA24F878F89B480000A250F1FFF03D +:1043500044607FDFE2CFE8289509404203F5404200 +:104360000024CC058401490000A6F813C8054607BF +:10437000FF004C5000944001BC098082C806545193 +:10438000FFF044007FF0D80780A1FD02490000A89B +:104390004800008680A1FD02844046343300EA24B0 +:1043A000465FCC0088A1469C01A089254064B409E1 +:1043B00097B74014D00944716B68404398804022FD +:1043C00086810432022540A39880802204220224A0 +:1043D000EA5F0425022604350227EA5F042500244B +:1043E00004350025EA24FD304004D00AEB1E4421A8 +:1043F0006B68F833EA240425002604350027EA25F3 +:10440000FD13FD40EA25FD60FD13F820FD50FD166B +:10441000FD04EA5FFD13EA253A4F940044216B70D6 +:10442000FD40EA4CFD02EA24F80644216B78FD4089 +:10443000EA4CF81EFD10FD04EA25FD40FD15F806C6 +:1044400044216B88EA4CF082F183FD03EA24442185 +:104450006B80F80B44216B98EA4C3A0F842083FF61 +:104460004E00FFF544216B90EA4CEA25FD10FD0556 +:10447000EA243B0FC400FD10FD08EA25F402F50311 +:10448000FD10FD0283FFEA24FD10FD04EA25FD1660 +:10449000EA25D50584008020D5028002FD10FD01AB +:1044A000FCE2FC40FD30812249000504B720FD03F9 +:1044B000FCC0FC01C80584004613FF00D50484003D +:1044C000461BFF00B61F8440F181B41F8062F101DA +:1044D00049000320FA5249FFFFE6FC81FC60FD1011 +:1044E000FD50EA5FFD1049000315FD30FD05490050 +:1044F000000BC006FD03FA5149FFFFD5FCE0FD03A8 +:10450000FCE09200C10446580000D904C8038402AC +:10451000DD9E465FFF004647FE009F2198CDE28367 +:10452000E8064657FF0098CDE283E9038404DD9E48 +:10453000464001009F21E281E8064658000098CDE0 +:10454000E283E9038403DD9E4657FF00D104465F02 +:10455000FF00D902C0038400DD9E8401DD9E92002D +:104560003A6F98BC40608C0390DF4E340006FEDA50 +:10457000C203FE929ED94E140006FE4AC003FE02FC +:104580009E4984804900003AC60840408004C40522 +:10459000FE4AC003FE029E493A6F9884DD9E920057 +:1045A00041414009974192104040D03796D1401088 +:1045B000C008FE4742020C24E220E8099F21984AE5 +:1045C000E222E905E220E8039F21984A9A48401038 +:1045D000D01740004008FE2FFECCE203E809980205 +:1045E0009E49E202E905E203E80398029E499A0324 +:1045F00040424008FE67DD9E3BFFFEBCFD80FD9112 +:104600008384CB4DE3B2E8194209000782A0C00DB4 +:104610004129000C525000204058140D4118800CC4 +:10462000411894044108000CFD08805249FFFFBA6C +:1046300082C1820086E0D523C2284209000782A0F9 +:10464000C8048BB286E1D51452F000204129000C39 +:10465000805240483C0D4058800C4108000C4002FC +:1046600090044018BC0D49FFFF9D82E18220FD08A7 +:10467000805249FFFF9782C1510000004FC2005392 +:1046800086204108540DD54B41194A1784208400D7 +:104690004FC2004CB79C151E0001D547E3B3E9F7A4 +:1046A0004209800782A0C044524000204059100DAA +:1046B0004029800CFEAF82624129000C4038100D69 +:1046C0004108000C4008800C4018900DFE1F49FF67 +:1046D000FF6982C182204200C869E3A1E9054C1844 +:1046E000C00CE380E809516B7FFF8A3340304801FA +:1046F000E2038A2F800386E04FC2001540080001C4 +:1047000040188401E3808A2F524A80204110900C87 +:104710004100540D410844044110D40DB79C151EAE +:1047200000018016501B80003BFFFE84DD9EE3F1FC +:10473000E903E392E90986C1404848018BB3E38469 +:104740008BAF8204D50286C086E04FC3FFE9D5EA6D +:104750004231FC0A95093A6FA8BC959947E80000D8 +:10476000E286E9054C434009E202E806FD40FD010E +:10477000FD1495099599FECD4031F8024072540917 +:1047800040A354094092280840832808445007FF5A +:104790004C5380C440F200044EF200BC40F30804C5 +:1047A0004EF200924063A8015CF300404EF2008C90 +:1047B000405054094094940440002C08405154093E +:1047C0004084140440212C08E6E2E9274094F804D0 +:1047D0004EA20004408478049F714062A81AC61D4E +:1047E000525300204E57000C4041140C4054140CFE +:1047F0004084180D4021180DFEAFD50CFFAA505271 +:1048000080204044140CFF174043181A4024180D10 +:104810008500C40358210002C3594C7540064C94CE +:1048200040044C010078E328E9054C94400AE20278 +:10483000E8079FF940447C0893019241FEA78080DD +:104840009A02E2808B2F8B28E6E2E9494E93000B17 +:10485000FA904043900680A7CC0D812084005073CD +:10486000FFE042548007E2A75247800142529C0178 +:10487000C50D9BFD9B6C526280204040180D4094FA +:10488000940C4000140C40949004500004005CF020 +:104890000400892FE32F88EF40502C09976C80C0CB +:1048A0009A05E2C08B2F409484084054D008932C82 +:1048B000920BFE2F4053D008409494044010F8020D +:1048C0004010A4043A6FA884DD9E9802E202892F6A +:1048D000E32F8928E90AE328E908CFD8920B40445E +:1048E000D408932BFE27D5EB525387FEC50E54F008 +:1048F0000001585000024002BC1B4044FC089321B8 +:104900009201FE279DF9D5C284004697FF00D5D7B6 +:10491000C3DA84008420D5D7409480044C9F40059E +:104920004C557FD2C3D0840044180000D5CC9200EF +:10493000FC42950992954070AC0840605409FFF71D +:1049400040602C0847C80000955992B54091AC08CA +:10495000408154094094A00440812C08FECD40A120 +:10496000F002443007FFC4584C3200754073F00425 +:104970004E5200874C3280794094F00414AF80038B +:104980005002FC0299204223A46942032469409109 +:104990000400E32140A1BC004223A06999D0E2E0D9 +:1049A000892FE32F894F8923E323894F420320690D +:1049B00099F9E2E1892FE32F40153C00FFC7580425 +:1049C000800140049C1AE420E90781E09800E20F8E +:1049D0009849882F9F2104AF80034E47007152529F +:1049E00007FF4E570046500004005CF00400E80446 +:1049F000882FE22F888F40202C0996949A02920BE0 +:104A00004020D408FE179449922C40525008FE6F63 +:104A10004010A804FCC240F39804E81940F37C0954 +:104A200099FF88EF99B6CF0580E684C050427FE0B9 +:104A300042038007C09E9B20522000204023080D87 +:104A40004063000C4073800CFFD7D593D315802AA8 +:104A5000FCC2FFF74C7E4011CD0640248408402163 +:104A60002004C20ADB054094A0044C9E400684004A +:104A70004617FF00D5CE840044180000FCC2400455 +:104A8000A004C0E640F47C098929892F89084E9347 +:104A90000006812885005052FFE0420480074E0244 +:104AA000FF6F9B68522000204024080D4084000CBA +:104AB0004094800C4094880448FFFF6284C05232C6 +:104AC00000015CF18020E90A80C08001842050311F +:104AD000FFE0C0045CF18020E81AC310522180205E +:104AE0004070880C4050080C40000C0D40108C0D9C +:104AF000FE3FFFAFC60358000001500004005CF009 +:104B00000400882F4040FC0948FFFF778400D5A0AF +:104B1000FC42950992954070AC0840605409FFF73B +:104B200040602C0847C80000955992B54091AC08E8 +:104B3000408154094094A00440812C08FECD40A13E +:104B4000F002443007FF4E4200C54C3200EF407384 +:104B5000F0044E5200FB4C3280F34094F0049B254D +:104B6000504203FF92C14013FC08FF8F92E14024A2 +:104B7000C009403388F74014801342508C2440739E +:104B8000C00840034009FFC780079BFDE207E80516 +:104B90009ED988E9E2E9E8FD402388F7425088245D +:104BA0004073C0089631FFC780079BFDE207E80508 +:104BB0009E9188E9E2E9E8FD4031C00898DA4201B7 +:104BC000A069FF8280079BF9E207C60580079FF96D +:104BD000E903E207E80C9ED988C84003200688E96B +:104BE000E2E9C0049DF9E903E6E1E8F64C74C00788 +:104BF000802880E684408400D52B4014C0094023DF +:104C000084F74004801342F008244073C0084053E6 +:104C10004009FFEF80A78AEFE2A7E8059E9188E9A7 +:104C2000E2E9E8FD401384F7425004244073C008D1 +:104C30009631FFC780079BFDE207E8059E4988E99A +:104C4000E2E9E8FD40214008989142012069FF8295 +:104C500080079BF9E207C60580079FF9E903E20791 +:104C6000E80C9E9188C84003200688E9E2E9C00468 +:104C70009DF9E903E6E1E8F6E460E90781E298924C +:104C8000E24F98DB886F9F21FFF758010001400138 +:104C90001C1A80234E470079525207FF4E57004A94 +:104CA000500004005CF00400E804882FE22F888F95 +:104CB00040202C0996949A02920B4020D408FE17AB +:104CC0009449922C40525008FE6F4010A804FCC238 +:104CD00040F39804E81B40F37C0999FF88EF99B6EC +:104CE000CF0580E684C050427FE0420380074E0239 +:104CF000FF329B20522000204023080D4063000C0F +:104D00004073800CFFD748FFFF26D307CD0440F443 +:104D1000A004E807802AFCC24094A0044C9E3FFCFB +:104D2000840044180000FCC2FFF74C7E7FFBD3F9DF +:104D300084004617FF004010A804FCC24094A00461 +:104D40004C9E7FF08400D5E740F4A004E8F240F4E4 +:104D50007C098929892F89084E93000681288500BE +:104D60005052FFE0420480074E02FEFB9B68522037 +:104D700000204024080D4084000C4094800C409496 +:104D8000880448FFFEEE84C0523200015CF18020AE +:104D9000E90A80C0800184205031FFE0C0045CF14A +:104DA0008020E81AC310522180204070880C4050A7 +:104DB000080C40000C0D40108C0DFE3FFFAFC603E9 +:104DC00058000001500004005CF00400882F4040AF +:104DD000FC0948FFFF6F8400D59E92003A6F983C13 +:104DE000954992B54040AC0840605409FF374030C7 +:104DF0002C0846680000FF375CF2843EE82152220E +:104E0000843EFAD0E246E9068064848050217FE047 +:104E1000CBF9C20B80044031880D4042080D52216D +:104E200000204000080CFEC7E420E805FF22C30371 +:104E3000FEDA8E81800380243A6F9804DD9EE420A0 +:104E4000E90752F287FFE90895A1FF9FC60546488A +:104E500000008460D5F04647FFFF58420FFF847F73 +:104E6000D5EA92003A6F983C842080A1806180400E +:104E7000C210E440E80746580000FE92C103FE4A13 +:104E80008E414430041E424100079ADC4021100C40 +:104E90004040AC0940615408FF37959192CCFF77B0 +:104EA0004061D008FF77800480253A6F9804DD9E2A +:104EB0004402D65CDD9E92008060E644E9285441BD +:104EC000800354508003C50B525280049A9599690F +:104ED00008408001184180014C12FFFC4051140928 +:104EE000C50A956D996996A73B00DC043B01DC245B +:104EF0004C12FFFC40510809C50A956A9969968FC2 +:104F00003A4090043A4190244C12FFFCC208994A5E +:104F100008408001184180014C12FFFCDD9E920088 +:104F20008060E644E93054518003C5095252800440 +:104F30009A959968181180014C32FFFE96484040BE +:104F4000A008FE674040C008FE67405114094E5259 +:104F50000011956D996B96A7820182218241826131 +:104F6000828182A182C182E13B01DC244C32FFFEBE +:104F700040510809C508956A996B968F3A118424A7 +:104F80004C32FFFEC206995A181180014C32FFFEC6 +:104F9000DD9E92003C0DFB4949000F6C49003AD65A +:104FA0004403F04A44100055490042EB4900105EAA +:104FB000490062CB4900A65C490042EB49003B77BF +:104FC000480001553C0DFB5D49003AD649003B774E +:104FD00044038D4049001FB8040080113C0DFC2E95 +:104FE00049003B283C1DFB4949003E723C1DFB6FBC +:104FF0002E07EC7C3C0DFB6F3C1DFB5D3C0DFB4824 +:10500000490062CB49000F6C2E07F02B4420019021 +:105010002E07EC91480081E93A6F98844412FEF023 +:1050200049006BB14900A3984900A2AA100F80075C +:105030002E1FEF3044200055442001803C0DFB6DB5 +:105040002E072BCC3C0FFBEB2E000E4C490061D4FD +:105050002E0010E550037F4840F03C0040310C40EA +:105060004430005549006E17490060EA4423F04A75 +:105070003E07EC9A440FFFAA490013FF4400005575 +:10508000490052C93E07EC4E4413F04A4000000963 +:105090003C0DFB644900A1B03E07EC914900A6908D +:1050A00044338D413C0E0399580000016600000214 +:1050B000100F800F54007FFF1010001C100480019F +:1050C000120F80033A210C004402C2542E17EFCA7B +:1050D00049003CE83C0FFB6D49006E17100480004E +:1050E00049000F703C0E03983C0DFB6E3C1DFC2EDE +:1050F0005800000410938000020F800354637FFF68 +:105100004900674A3C1DFB614402FEF0490013C0A0 +:105110004900A2A84402E5702E0011AA490052C914 +:105120003E07EF314200080B2E07EC433C0C0064B5 +:105130002E07EC5649006DCA3E07E9D44463F04A95 +:105140003C0FFB6C3C03F65F490063D744131C2003 +:10515000443001906403040349001F0449003E7277 +:105160004900659210100051380780004413F40381 +:105170000004800149006B9A580000203C0FFB4856 +:10518000221080014473F04A4402DDF44412C11D30 +:1051900049001FEA3C0DFBB4580000026600000401 +:1051A0004900105E3E17EF30449000555800001043 +:1051B0003E07EC472E072BCB490076585410FFFFD3 +:1051C00040F0BC004470005549006FF53E07EC39D3 +:1051D000540000FE3E07EF8E3C0BF65E4200040BCF +:1051E000440000504462FEF03E07EF334400006983 +:1051F000100300503E07EC933C0BF90C4412FE5098 +:105200002E0FEF3142000C0B44100032442000649A +:1052100066000060502F800700000051440300002A +:105220002E07EC4E3C0DFB954402E6884000041628 +:10523000490036A158000008021F8000441262385D +:105240003E17EC5E2E07EC2D4800017140008016E1 +:10525000440200003E07EC664800012850528F00CF +:1052600050000FFF440373E84402FE504430032013 +:105270003C0808883E07EC7B382080084413F2483D +:105280003C0FFB7E3E07EC564422C29849005A79F7 +:10529000120480005CF003E83C0E03942E07F1B189 +:1052A00049005B61400018403C0BF672541080FED0 +:1052B000400080403C6FFBA244000064490011BFE5 +:1052C0003C0DFB58440397DE440397DC2E000E6828 +:1052D000440000FF5CF000334900664E3E07EC7C62 +:1052E00049003B2838061A0A000480004900731060 +:1052F0002E07F2043C0BF90D40320D00181280010C +:10530000020F8001490065925CF0070838308A0A74 +:10531000501F800F2E07F0902E07EF2846500FFFEA +:10532000500F800E4200100B2E07EFA20423000C3A +:1053300040100436490012AF2E072C5E641304029D +:10534000660000103E000E4C3E07F0C744300032AD +:10535000490042F838048602441000645C000001F1 +:105360003E07EC8A49003BF93C0C007B3C0FFB817B +:10537000120F8002046280163C0E039244300080BB +:10538000020F8000441216802E07EC8A3C1DFBBDE4 +:105390003E07ECAA44134C1044000032441E0000A7 +:1053A000490071CD4422DD004402FEF13C1FFB6C3C +:1053B00038530E0A3C6FFCCA4413F1C0540000F08D +:1053C000500F800638078101540000FD4400003C66 +:1053D0002E07EC674900428D6600000849007159AC +:1053E00049007C946413240349007680503F800771 +:1053F0003C0BF7BC381784003C0BF7C63C0FFBECAA +:105400003C0E03953C2395B23C0C00654900A63246 +:1054100044136510420888243C0DFF234231800369 +:10542000441000442E07EF92000F80076600000131 +:105430002E07EC212E17EC7C3E07EFBF4422E648F6 +:105440003E17EC2F44038D424412D9084400005209 +:105450004900592C3C0DFBA23C1DFC094412C18A99 +:1054600042108003490067723E07F1BC3C0C024DBC +:105470003C1DFB484031847649001FB0640308039B +:105480003C0C03923E07F1FB400320094000BC1A8C +:105490004412000049003D4E3E07EFC73E07EF288B +:1054A000444000554412C15E44026238100300417A +:1054B0004412D8D010050000120F80004272887389 +:1054C00049004261504F847C44037A2849001CCC37 +:1054D000020F80024403F7CE49007EB73C0FFB8ADF +:1054E00003020000490093BD49006FFA4201847332 +:1054F0003E072C5E3E000E684440006400100045EC +:1055000049007D1B40213C08041180143C0FFB4DD9 +:105510003E07EC2638101A0A40108C361010003C5A +:1055200049003B4E002F8007223080003E07EF9A53 +:10553000405284B62E07EF99100580003C0FFB9F68 +:1055400044130FA049003CE1490075B12E07EF2933 +:1055500010900000101000521000805149006FF5AB +:105560004900820E3C1BF8673800990912100010A0 +:105570003C0FFBA24403F00E4402C2143C0BF65D48 +:105580002E07F0C73C0DFC8A3B014C00441000A5DF +:10559000441333103E07EC8649001B183C1C03944F +:1055A0004412E5703C5DFB584403F7C84900417D57 +:1055B0003C2FFB6D120300254402C1133E07F1BDD1 +:1055C0003810AE0240109C362E07EC312E07EC72DC +:1055D0004402FE604413F2493C6FFB4849003B9A89 +:1055E0004412C0F844138D403E07EC4A3E07EC8D50 +:1055F0003E07EF294442D1980030000E10030040CE +:1056000014AF800150000240120F800149005AF689 +:105610002E17F02B3E07EF963E00111649007177CA +:105620003C03F90C2E07FBA43E07F0CD3E07FBE53B +:10563000442000B649003D3840319476490042F894 +:10564000502F8006381019093C1DFBF840008100DE +:105650002E07EC4F4412D858422090734000800629 +:105660003E07EF83460000F43C3DFB553B0FCC204A +:105670004900626D3E07EC313C1FFCC944000078D4 +:105680002E07EFBC500F80073C0C042841127C0A07 +:1056900049005A9010A48000100F803344037D48C5 +:1056A0003E07F1B142418873441000A43C3BF96DC0 +:1056B0002E07E9D440211C560423000A441000A2FE +:1056C00044038518021F80014010BC084412A9BA87 +:1056D00000148001441FFFA044128178422080738F +:1056E0001086000044036510421100733C6DFBA25C +:1056F0004400012C3C0FFB71120300262E07EC899D +:105700003C0DFB4E3C0C03982E072BCA5800004062 +:10571000660038004412A50A3C2DFB5D3E07F0C927 +:1057200049005B013C0DFC9E490065A649009FAC09 +:105730003C1DFBA24413F24B3C0FFB7C49003C5345 +:105740002E07EC873E07EF3E225180000203002522 +:105750003C0BF8FC44138D41000500002E172FB2BE +:105760004403F7C55810800140210C564403F7C389 +:1057700049003D155CF100C8122F80024403F1C3BB +:10578000100300454442AC764231C42422408000DC +:105790004413F00E000000008492030014940300F0 +:1057A000FAAF02008AB10200648F0300F490030094 +:1057B000DAAC02006AAE020010330300903F03002F +:1057C000104C03009058030000A2010080AE0100BD +:1057D00000BB010080C7010010D8010050DE0100AD +:1057E00090E40100D0EA0100E8730300F8740200BD +:1057F000A00F03006880030064676B6F7072767D92 +:10580000B3A5968974647D9D64666A716F70757DB9 +:10581000ADA1928773647D9E64676B6F7072767DB5 +:10582000B3A5968974647D9D64666A716F70757D99 +:10583000ADA1928773647D9E64676B6F7072767D95 +:10584000B3A5968974647D9D64666A716F70757D79 +:10585000ADA1928773647D9E64676B6F7072767D75 +:10586000B3A5968974647D9D64666A716F70757D59 +:10587000ADA1928773647D9E64676B6F7072767D55 +:10588000B3A5968974647D9D64666A716F70757D39 +:10589000ADA1928773647D9E64676B6F7072767D35 +:1058A000B3A5968974647D9D64666A716F70757D19 +:1058B000ADA1928773647D9E64676B6F7072767D15 +:1058C000B3A5968974647D9D64666A716F70757DF9 +:1058D000ADA1928773647D9E64676B6F7072767DF5 +:1058E000B3A5968974647D9D64666A716F70757DD9 +:1058F000ADA1928773647D9E6464686C6A6B7075F9 +:10590000A89C8E8370647D9A6564686F6C6E7277F4 +:10591000A1948A816E647B9B6464686C6A6B707509 +:10592000A89C8E8370647D9A6564686F6C6E7277D4 +:10593000A1948A816E647B9B6464686C6A6B7075E9 +:10594000A89C8E8370647D9A6564686F6C6E7277B4 +:10595000A1948A816E647B9B6464686C6A6B7075C9 +:10596000A89C8E8370647D9A6564686F6C6E727794 +:10597000A1948A816E647B9B6464686C6A6B7075A9 +:10598000A89C8E8370647D9A6564686F6C6E727774 +:10599000A1948A816E647B9B6464686C6A6B707589 +:1059A000A89C8E8370647D9A6564686F6C6E727754 +:1059B000A1948A816E647B9B6464686C6A6B707569 +:1059C000A89C8E8370647D9A6564686F6C6E727734 +:1059D000A1948A816E647B9B6464686C6A6B707549 +:1059E000A89C8E8370647D9A6564686F6C6E727714 +:1059F000A1948A816E647B9B646568686F6E737620 +:105A0000A6958A7C6E647F9B6465676A6E6E73740C +:105A1000A3968A7A6E647C9C646568686F6E737600 +:105A2000A6958A7C6E647F9B6465676A6E6E7374EC +:105A3000A3968A7A6E647C9C646568686F6E7376E0 +:105A4000A6958A7C6E647F9B6465676A6E6E7374CC +:105A5000A3968A7A6E647C9C646568686F6E7376C0 +:105A6000A6958A7C6E647F9B6465676A6E6E7374AC +:105A7000A3968A7A6E647C9C646568686F6E7376A0 +:105A8000A6958A7C6E647F9B6465676A6E6E73748C +:105A9000A3968A7A6E647C9C646568686F6E737680 +:105AA000A6958A7C6E647F9B6465676A6E6E73746C +:105AB000A3968A7A6E647C9C646568686F6E737660 +:105AC000A6958A7C6E647F9B6465676A6E6E73744C +:105AD000A3968A7A6E647C9C646568686F6E737640 +:105AE000A6958A7C6E647F9B6465676A6E6E73742C +:105AF000A3968A7A6E647C9C646568686F6E737620 +:105B0000A6958A7C6E647F9B6465676A6E6E73740B +:105B1000A3968A7A6E647C9C64686C6F77767D7ECF +:105B2000AEA08F7D6D647EA06465696C71737879B9 +:105B3000AB9C8E7B6C647EA264686C6F77767D7E96 +:105B4000AEA08F7D6D647EA06465696C7173787999 +:105B5000AB9C8E7B6C647EA264686C6F77767D7E76 +:105B6000AEA08F7D6D647EA06465696C7173787979 +:105B7000AB9C8E7B6C647EA264686C6F77767D7E56 +:105B8000AEA08F7D6D647EA06465696C7173787959 +:105B9000AB9C8E7B6C647EA264686C6F77767D7E36 +:105BA000AEA08F7D6D647EA06465696C7173787939 +:105BB000AB9C8E7B6C647EA264686C6F77767D7E16 +:105BC000AEA08F7D6D647EA06465696C7173787919 +:105BD000AB9C8E7B6C647EA264686C6F77767D7EF6 +:105BE000AEA08F7D6D647EA06465696C71737879F9 +:105BF000AB9C8E7B6C647EA264686C6F77767D7ED6 +:105C0000AEA08F7D6D647EA06465696C71737879D8 +:105C1000AB9C8E7B6C647EA265646B6970707878D7 +:105C2000A5948C756A647E9F65646A676F6F7575ED +:105C3000A59489746B6480A065646B6970707878D2 +:105C4000A5948C756A647E9F65646A676F6F7575CD +:105C5000A59489746B6480A065646B6970707878B2 +:105C6000A5948C756A647E9F65646A676F6F7575AD +:105C7000A59489746B6480A065646B697070787892 +:105C8000A5948C756A647E9F65646A676F6F75758D +:105C9000A59489746B6480A065646B697070787872 +:105CA000A5948C756A647E9F65646A676F6F75756D +:105CB000A59489746B6480A065646B697070787852 +:105CC000A5948C756A647E9F65646A676F6F75754D +:105CD000A59489746B6480A065646B697070787832 +:105CE000A5948C756A647E9F65646A676F6F75752D +:105CF000A59489746B6480A065646B697070787812 +:105D0000A5948C756A647E9F65646A676F6F75750C +:105D1000A59489746B6480A065646D6A6F727979EB +:105D2000A8958A78686480A168646D6D73727979CA +:105D3000A6958A75696482A365646D6A6F727979C4 +:105D4000A8958A78686480A168646D6D73727979AA +:105D5000A6958A75696482A365646D6A6F727979A4 +:105D6000A8958A78686480A168646D6D737279798A +:105D7000A6958A75696482A365646D6A6F72797984 +:105D8000A8958A78686480A168646D6D737279796A +:105D9000A6958A75696482A365646D6A6F72797964 +:105DA000A8958A78686480A168646D6D737279794A +:105DB000A6958A75696482A365646D6A6F72797944 +:105DC000A8958A78686480A168646D6D737279792A +:105DD000A6958A75696482A365646D6A6F72797924 +:105DE000A8958A78686480A168646D6D737279790A +:105DF000A6958A75696482A365646D6A6F72797904 +:105E0000A8958A78686480A168646D6D73727979E9 +:105E1000A6958A75696482A365646D6A6F727979E3 +:105E2000A8958A78686480A168646D6D73727979C9 +:105E3000A6958A75696482A36F6F6F6F6F6F6F6FBE +:105E40007070707070707070707070707070707052 +:105E50006F6F6F6F6F6F6F6F6C6C6C6C6C6C6C6C6A +:105E60006F6F6F6F6F6F6F6F6C6C6C6C6C6C6C6C5A +:105E70006F6F6F6F6F6F6F6F6A6A6A6A6A6A6A6A5A +:105E80006B6B6B6B6B6B6B6B6A6A6A6A6A6A6A6A6A +:105E90006A6A6A6A6A6A6A6A67676767676767677A +:105EA000696969696969696968686868686868686A +:105EB0006868686868686868686868686868686862 +:105EC0006969696969696969676767676767676752 +:105ED0006868686868686868666666666666666652 +:105EE000686868686868686867676767676767673A +:105EF000676767676767676764646464646464644A +:105F00006464646464646464646464646464646451 +:105F10006464646464646464666666666666666631 +:105F20006666666666666666666666666666666611 +:105F300065656565656565657070707070707070B9 +:105F40007070707070707070727272727272727241 +:105F50006F6F6F6F6F6F6F6F6D6D6D6D6D6D6D6D61 +:105F60006D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D61 +:105F70006C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C61 +:105F80006D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D41 +:105F90006D6D6D6D6D6D6D6D6B6B6B6B6B6B6B6B41 +:105FA00069696969696969696B6B6B6B6B6B6B6B51 +:105FB00069696969696969696A6A6A6A6A6A6A6A49 +:105FC0006A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A31 +:105FD0006A6A6A6A6A6A6A6A686868686868686831 +:105FE0006767676767676767696969696969696931 +:105FF0006868686868686868646464646464646441 +:106000006464646464646464646464646464646450 +:106010006464646464646464666666666666666630 +:106020006565656565656565686868686868686808 +:106030006666666666666666747474747474747490 +:106040006F6F6F6F6F6F6F6F717171717171717150 +:106050007272727272727272717171717171717128 +:106060006A6A6A6A6A6A6A6A6C6C6C6C6C6C6C6C80 +:106070006C6C6C6C6C6C6C6C6F6F6F6F6F6F6F6F48 +:106080006B6B6B6B6B6B6B6B6D6D6D6D6D6D6D6D50 +:106090006D6D6D6D6D6D6D6D707070707070707018 +:1060A00069696969696969696C6C6C6C6C6C6C6C48 +:1060B0006A6A6A6A6A6A6A6A707070707070707010 +:1060C00069696969696969696D6D6D6D6D6D6D6D20 +:1060D0006C6C6C6C6C6C6C6C6D6D6D6D6D6D6D6DF8 +:1060E00068686868686868686C6C6C6C6C6C6C6C10 +:1060F0006C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6CE0 +:1061000069696969696969696B6B6B6B6B6B6B6BEF +:106110006969696969696969666666666666666607 +:10612000656565656565656567676767676767670F +:106130006565656565656565646464646464646417 +:106140006464646464646464656565656565656507 +:1061500065656565656565656D6D6D6D6D6D6D6DAF +:106160006D6D6D6D6D6D6D6D6B6B6B6B6B6B6B6B6F +:106170006B6B6B6B6B6B6B6B6D6D6D6D6D6D6D6D5F +:106180006F6F6F6F6F6F6F6F6D6D6D6D6D6D6D6D2F +:106190006E6E6E6E6E6E6E6E6C6C6C6C6C6C6C6C2F +:1061A0006B6B6B6B6B6B6B6B6A6A6A6A6A6A6A6A47 +:1061B0006B6B6B6B6B6B6B6B6A6A6A6A6A6A6A6A37 +:1061C0006A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A2F +:1061D0006A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A1F +:1061E000686868686868686868686868686868682F +:1061F0006A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6AFF +:106200006868686868686868676767676767676716 +:10621000676767676767676767676767676767670E +:106220006666666666666666676767676767676706 +:10623000666666666666666664646464646464640E +:10624000646464646464646464646464646464640E +:1062500065656565656565656B6B6B6B6B6B6B6BBE +:106260006A6A6A6A6A6A6A6A6D6D6D6D6D6D6D6D76 +:10627000696969696969696969696969696969698E +:1062800068686868686868686A6A6A6A6A6A6A6A7E +:106290006969696969696969686868686868686876 +:1062A0006868686868686868696969696969696966 +:1062B000686868686868686866666666666666666E +:1062C0006A6A6A6A6A6A6A6A68686868686868683E +:1062D000686868686868686866666666666666664E +:1062E000666666666666666666666666666666664E +:1062F000666666666666666664646464646464644E +:10630000646464646464646464646464646464644D +:106310006565656565656565646464646464646435 +:106320006565656565656565646464646464646425 +:10633000646464646464646464646464646464641D +:1063400065656565656565656565656565656565FD +:106350006565656565656565747474747474747475 +:1063600074747474747474747777777777777777D5 +:1063700074747474747474747171717171717171F5 +:1063800072727272727272727272727272727272ED +:1063900070707070707070707171717171717171F5 +:1063A00070707070707070707272727272727272DD +:1063B00070707070707070706E6E6E6E6E6E6E6EED +:1063C00070707070707070707171717171717171C5 +:1063D00070707070707070706F6F6F6F6F6F6F6FC5 +:1063E000727272727272727272727272727272728D +:1063F00072727272727272726D6D6D6D6D6D6D6DA5 +:106400006F6F6F6F6F6F6F6F707070707070707094 +:106410006F6F6F6F6F6F6F6F6A6A6A6A6A6A6A6AB4 +:106420006B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6BBC +:1064300068686868686868686767676767676767E4 +:1064400068686868686868686868686868686868CC +:1064500067676767676767676565656565656565DC +:1064600067676767676767676767676767676767BC +:1064700065656565656565658300800084007E00EF +:106480007F007F007F007F007D007A007D00790023 +:106490007A0078007B0077007B0078007900770035 +:1064A000780077007A00750076007200760072003E +:1064B000780074007800730075007100720070003D +:1064C000740071007200710073006D0070006D0047 +:1064D00071006E006F006E006F006B006E006C004C +:1064E0006B006800690068006D0069006D006A005B +:1064F0006C006C006B006C0069006700670067004F +:106500006700680068006800680066006700650052 +:106510006800660068006700650065006700670046 +:1065200064006600660064005F0062006200600054 +:106530005D006100600060005F0061005F005F005F +:106540005F006300610062005E005F005E005F004C +:106550005C005E005E005E005C005D005D005E0051 +:106560005C005D005C005C005A005B005C005B004E +:106570005700590059005A0057005A005900590055 +:106580005500580057005900540058005600580054 +:1065900053005A005500580053005700540057004C +:1065A000510055005200560051005600520055004F +:1065B000510056005300560051005500520056003D +:1065C0004F0053004F0053004F0052004F00530044 +:1065D0004D0052004E0053004E0053004F00540037 +:1065E0004C0051004D0052004A004E004A004D0040 +:1065F00048004C0048004C0047004B0047004B004F +:106600004600490045004A00720075007A007F008C +:106610008000820087008E00B500A70097008A00E6 +:10662000750065007E009F00720074007900810093 +:106630007E00800085008E00AF00A30093008800DC +:10664000740065007E00A0006E006E00720077008E +:10665000750076007B008100A30097008A007F0010 +:106660006D006100790095006C006B006F00770091 +:10667000740076007A007F009E00910087007E0003 +:106680006C00620079009800640065006800680092 +:106690006F006E00730076009C008C008200750015 +:1066A00067005E00770092006500660068006B007E +:1066B0006F006F007400750099008D0082007300F8 +:1066C00067005E00750093005B005F00620065007C +:1066D0006C006B00720073009E00920082007200DA +:1066E00063005B00730092005F006000640067005D +:1066F0006B006D00720073009C008E0081007000C2 +:1067000062005B0073009300570056005C005A0063 +:1067100060006000670067008E007F007800650001 +:106720005B0056006C008900590058005D005B005A +:1067300062006200670067008E007F0076006400E0 +:106740005C0056006E008A00510050005700550052 +:1067500059005B00610061008A007A0071006200EC +:106760005500520069008400530050005700570044 +:106770005C005B006100610088007A0071006000CD +:10678000560052006B0086001A004D008000B300D6 +:10679000E6001A014D018001B301E6011A024D0223 +:1067A0008002B302E6021A034D038003B303E6033B +:1067B0001A044D048004B304E6041A054D0580054F +:1067C000B305E6051A064D068006B306E6061A0767 +:1067D0004D078007B307E6071A084D088008B3087D +:1067E000E6081A094D098009B309E60934003200A8 +:1067F00034003200340034003200340032003400FF +:1068000034003200340032003400340032003400EE +:1068100032003400340032003400320034003400DE +:1068200032003400320034003400320034003200D0 +:1068300034003400320034003200340034003200BE +:1068400034003200340034003200340032003400AE +:1068500019004B007D00AF00E100130145017701F5 +:10686000A901DB010D023F027102A302D502070359 +:1068700039036B039D03CF030104330465049704BC +:10688000C904FB042D055F059105C305F505270621 +:106890003200320032003200320032003200320068 +:1068A0003200320032003200320032003200320058 +:1068B0003200320032003200320032003200320048 +:1068C0003200320032003200320032003200320038 +:1068D0000808090808090100E8730300F8740200B9 +:1068E000A00F03006880030010D8010050DE0100F3 +:1068F00090E40100D0EA0100208E020060940200C2 +:10690000A09A0200E0A0020010330300903F0300B1 +:10691000104C03009058030000090B020F06040DF1 +:10692000070E0C050801030A04050607F20A0B000E +:10693000BCC20C002B4C0E00AF3009004C5E0900AD +:1069400030790D000A930F00C2E40D000DF504002C +:10695000433D0300D4B3010050CF0600B3A10600AD +:10696000CF860200F56C00003D1B02000DF504000F +:10697000F56C00004C5E09002B4C0E00000000007E +:10698000000000000000000000000000BCC20C007D +:10699000AF30090030790D00C2E40D0000000000A6 +:1069A000000000000000000000000000D4B301005F +:1069B000433D0300B3A106003D1B02000A930F00F4 +:1069C00030790D00F20A0B00AF3009000DF504001C +:1069D00050CF0600F56C0000CF8602004C5E090027 +:1069E000C2E40D002B4C0E00BCC20C003D1B02008B +:1069F000B3A10600433D0300D4B30100AF3009004A +:106A0000F20A0B0030790D000A930F00CF860200C6 +:106A1000F56C000050CF06000DF50400BCC20C0060 +:106A20002B4C0E00C2E40D004C5E0900F20A0B0074 +:106A3000BCC20C002B4C0E00AF3009004C5E0900AC +:106A400030790D000A930F00C2E40D000202020328 +:106A5000030304040000020003000500070009000E +:106A60000A000C000E0010001100130015001600A3 +:106A700018001A001C001D001F0021002200240025 +:106A80002500270029002A002C002D002F003000AF +:106A90003200340035003600380039003B003C003D +:106AA0003E003F00400042004300440045004700D4 +:106AB000480049004A004B004D004E004F00500076 +:106AC0005100520053005400550056005700570023 +:106AD000580059005A005B005B005C005D005D00DF +:106AE0005E005F005F0060006000610061006100A7 +:106AF0006200620062006300630063006300640080 +:106B000064006400640064006400000064006400C9 +:106B10006400640064006400630063006300630059 +:106B2000620062006200610061006100600060005C +:106B30005F005F005E005D005D005C005B005B006D +:106B40005A0059005800570057005600550054008D +:106B500053005200510050004F004E004D004B00BA +:106B60004A004900480047004500440043004200F5 +:106B700040003F003E003C003B003900380036003A +:106B800035003400320030002F002D002C002A0088 +:106B90002900270025002400220021001F001D00DD +:106BA0001C001A0018001600150013001100100038 +:106BB0000E000C000A000900070005000300020097 +:106BC00000000000000002000300050007000900AB +:106BD0000B000C000E00100012001300150017002F +:106BE00019001B001D001F002000220024002600A9 +:106BF00028002A002D002F00310033003500370017 +:106C00003A003C003E0041004300460049004B0072 +:106C10004E005100540057005A005D0061006400AE +:106C200068006B006F00730077007B0080008500B8 +:106C30008A008F0094009A00A000A600AD00B40066 +:106C4000BC00C400CD00D600E100EC00F800050156 +:106C500013012201340147015D0175019101B10168 +:106C6000D601020237027702C8022E03B703770467 +:106C700096057407300B6116102700000000010014 +:106C800004000900100019002400310040005100E8 +:106C9000640079009000A900C400E1000001210116 +:106CA000440169019001B901E4011102400271023D +:106CB000A402D902100349038403C1030004410460 +:106CC0008404C90410055905A405F1054006910680 +:106CD000E40639079007E9074408A108000961099B +:106CE000C409290A900AF90A640BD10B400CB10CB3 +:106CF000240D990D100E890E040F810F00108110C4 +:106D000004118911101299122413B1134014D114D3 +:106D10006415F91590162917C41761180019A119DF +:106D2000441AE91A901B391CE41C911D401EF11EE7 +:106D3000A41F00006B006B006D00700071007100FB +:106D4000710000006B006B006A0069006800680059 +:106D500067000000000005000A0013001900280069 +:106D60003C000000000000000038FAFE422EE63F22 +:106D70003067C79357F32E3D010000000000E0BFCD +:106D80005B3051555555D53F9045EBFFFFFFCFBFC9 +:106D90001101F124B399C93F9FC806E57555C5BFD8 +:106DA000000000000000E0BF775555555555D53F10 +:106DB000CBFDFFFFFFFFCFBF0CDD95999999C93F30 +:106DC000A74567555555C5BF30DE44A32449C23F8A +:106DD000653D42A4FFFFBFBFCAD62A288471BC3FCD +:106DE000FF68B043EB99B9BF85D0AFF78281B73F59 +:106DF000CD45D1751352B5BF9FDEE0C3F034F73FE8 +:106E00000090E6797FCCD7BF1FE92C6A7813F73F53 +:106E100000000DC2EE6FD7BFA0B5FA0860F2F63FD2 +:106E200000E05113E313D7BF7D8C131FA6D1F63FAB +:106E3000007828385BB8D6BFD1B4C50B49B1F63F4E +:106E400000788090555DD6BFBA0C2F334791F63F3E +:106E500000001876D002D6BF234222189F71F63F59 +:106E600000909086CAA8D5BFD91EA5994F52F63F6B +:106E700000500356434FD5BFC4248FAA5633F63F64 +:106E800000406BC337F6D4BF14DC9D6BB314F63FE0 +:106E90000050A8FDA79DD4BF4C5CC65264F6F53FD8 +:106EA00000A889399245D4BF4F2C91B567D8F53FDA +:106EB00000B8B039F4EDD3BFDE905BCBBCBAF53F80 +:106EC00000708F44CE96D3BF781AD9F2619DF53FFA +:106ED00000A0BD171E40D3BF875646125680F53F0F +:106EE000008046EFE2E9D2BFD36BE7CE9763F53F70 +:106EF00000E030381B94D2BF937FA7E22547F53FCF +:106F00000088DA8CC53ED2BF83450642FF2AF53F92 +:106F100000902729E1E9D1BFDFBDB2DB220FF53FA9 +:106F200000F8482B6D95D1BFD7DE34478FF3F43F7F +:106F300000F8B99A6741D1BF4028DECF43D8F43F6B +:106F40000098EF94D0EDD0BFC8A378C03EBDF43F09 +:106F50000010DB18A59AD0BF8A25E0C37FA2F43FBA +:106F600000B86352E647D0BF3484D4240588F43F88 +:106F700000F0864522EBCFBF0B2D191BCE6DF43FE1 +:106F800000B017754A47CFBF541839D3D953F43FCF +:106F90000030103D44A4CEBF5A84B444273AF43F95 +:106FA00000B0E9440D02CEBFFBF81541B520F43F17 +:106FB00000F07729A260CDBFB1F43EDA8207F43F3A +:106FC0000090950401C0CCBF8FFE575D8FEEF33F5C +:106FD000001089562920CCBFE94C0BA0D9D5F33F2E +:106FE0000010818D1781CBBF2BC110C060BDF33F56 +:106FF00000D0D3CCC9E2CABFB8DA752B24A5F33FC1 +:107000000090122E4045CABF02D09FCD228DF33F83 +:1070100000F01D6877A8C9BF1C7A84C55B75F33F73 +:10702000003048696D0CC9BFE236AD49CE5DF33F13 +:1070300000C045A62071C8BF40D44D987946F33FA3 +:10704000003014B48FD6C7BF24CBFFCE5C2FF33FE4 +:107050000070623CB83CC7BF490DA1757718F33F7B +:107060000060379B9AA3C6BF90393E37C801F33FF3 +:1070700000A0B754310BC6BF41F895BB4EEBF23FB1 +:10708000003024767D73C5BFD1A919020AD5F23F1D +:107090000030C28F7BDCC4BF2AFDB7A8F9BEF23F27 +:1070A0000000D2512C46C4BFAB1B0C7A1CA9F23F86 +:1070B000000083BC8AB0C3BF30B514607293F23F46 +:1070C0000000496B991BC3BFF5A15757FA7DF23FEA +:1070D0000040A4905487C2BFBF3B1D9BB368F23FE2 +:1070E00000A079F8B9F3C1BFBDF58F839D53F23F7E +:1070F00000A02C25C860C1BF3B08C9AAB73EF23F1B +:107100000020F7577FCEC0BFB640A92B012AF23F1F +:1071100000A0FE49DC3CC0BF3241CC967915F23F5D +:1071200000804BBCBD57BFBF9BFCD21D2001F23F6E +:10713000004040960837BEBF0B484D49F4ECF13F84 +:107140000040F93E9817BDBF69658F52F5D8F13FF1 +:1071500000A0D84E67F9BBBF7C7E571123C5F13F15 +:1071600000602F2079DCBABFE926CB747CB1F13FF7 +:10717000008028E7C3C0B9BFB61A2C0C019EF13FAE +:1071800000C072B346A6B8BFBD70B67BB08AF13FEF +:107190000000ACB3018DB7BFB6BCEF258A77F13FD5 +:1071A00000003845F174B6BFDA314C358D64F13FDB +:1071B0000080876D0E5EB5BFDD5F2790B951F13F4E +:1071C00000E0A1DE5C48B4BF4CD232A40E3FF13FD8 +:1071D00000A06A4DD933B3BFDAF910728B2CF13F9E +:1071E0000060C5F87920B2BF31B5EC28301AF13F04 +:1071F00000206298460EB1BFAF3484DAFB07F13F3E +:107200000000D26A6CFAAFBFB36B4E0FEEF5F03FE1 +:107210000040774A8DDAADBFCE9F2A5D06E4F03F8D +:10722000000085E4ECBCABBF21A52C6344D2F03F49 +:1072300000C0124089A1A9BF1A98E27CA7C0F03F04 +:1072400000C002335888A7BFD136C6832FAFF03FA6 +:107250000080D6675E71A5BF3913A098DB9DF03F13 +:10726000008065498A5CA3BFDFE752AFAB8CF03F7B +:1072700000401564E349A1BFFB284E2F9F7BF03FE0 +:107280000080EB82C0729EBF198F358CB56AF03FCB +:1072900000805252F1559ABF2CF9ECA5EE59F03FFF +:1072A000008081CF623D96BF902CD1CD4949F03FFF +:1072B0000000AA8CFB2892BFA9ADF0C6C638F03FEB +:1072C0000000F9207B318CBFA93279136528F03F8B +:1072D0000000AA5D351984BF4873EA272418F03FDF +:1072E0000000ECC2031278BF95B114060408F03F09 +:1072F00000002479090460BF1AFA26F71FE0EF3F67 +:1073000000009084F3EF6F3F74EA61C21CA1EF3F6D +:1073100000003D3541DC873F2E9981B01063EF3F7F +:107320000080C2C4A3CE933FCDADEE3CF625EF3F27 +:1073300000008914C19F9B3FE7139103C8E9EE3F0A +:10734000000011CED8B0A13FABB1CB7880AEEE3FFC +:1073500000C001D05B8AA53F9B0C9DA21A74EE3F32 +:107360000080D840835CA93FB5990A83913AEE3FEB +:10737000008057EF6A27AD3F569A6009E001EE3F63 +:1073800000C098E59875B03F98BB77E501CAED3F1E +:1073900000200DE3F553B23F03917C0BF292ED3FD9 +:1073A0000000388BDD2EB43FCE5CFB66AC5CED3F5D +:1073B00000C057875906B63F9DDE5EAA2C27ED3FD9 +:1073C00000006A3576DAB73FCD2C6B3E6EF2EC3FAB +:1073D00000601C4E43ABB93F0279A7A26DBEEC3FE3 +:1073E00000600DBBC778BB3F6D08376D268BEC3F47 +:1073F0000020E7321343BD3F04585DBD9458EC3F75 +:107400000060DE71310ABF3F8C9FBB33B526EC3F75 +:107410000040912B1567C03F3FE7ECEE83F5EB3F53 +:1074200000B092828547C13FC196DB75FDC4EB3F3A +:107430000030CACD6E26C23F284A860C1E95EB3F0F +:107440000050C5A6D703C33F2C3EEFC5E265EB3F16 +:107450000010333CC3DFC33F8B88C9674837EB3F1D +:1074600000807A6B36BAC43F4A301D214B09EB3F8E +:1074700000F0D1283993C53F7EEFF285E8DBEA3F83 +:1074800000F01824CD6AC63FA23D60311DAFEA3F2F +:10749000009066ECF840C73FA758D33FE682EA3F2A +:1074A00000F01AF5C015C83F8B7309EF4057EA3F4B +:1074B0000080F65429E9C83F274BAB902A2CEA3FBD +:1074C0000040F80236BBC93FD1F29313A001EA3F56 +:1074D00000002C1CED8BCA3F1B3CDB249FD7E93FEF +:1074E00000D0015C515BCB3F90B1C70525AEE93FB1 +:1074F00000C0BCCC6729CC3F2FCE97F22E85E93F48 +:10750000006048D535F6CC3F754BA4EEBA5CE93F38 +:1075100000C04634BDC1CD3F3848E79DC634E93F81 +:1075200000E0CFB8018CCE3FE652672F4F0DE93F08 +:10753000009017C00955CF3F9DD7FF8E52E6E83F18 +:1075400000B81F126C0ED03F7C00CC9FCEBFE83F2E +:1075500000D0930EB871D03F0EC3BEDAC099E83F99 +:107560000070869E6BD4D03FFB1723AA2774E83F98 +:1075700000D04B338736D13F089AB3AC004FE83F79 +:10758000004823670D98D13F553E65E8492AE83FFA +:107590000080CCE0FFF8D13F6002F4950106E83F9F +:1075A000006863D75F59D23F29A3E06325E2E73F34 +:1075B00000A8140930B9D23FADB5DC77B3BEE73FC0 +:1075C000006043107218D33FC2259767AA9BE73F1C +:1075D0000018EC6D2677D33F570617F20779E73F7F +:1075E0000030AFFB4FD5D33F0C13D6DBCA56E73F75 +:1075F00000E02FE3EE32D43F6BB64F010010E63FC0 +:107600003C5B42916C027E3C95B44D030030E63FFA +:10761000415D0048EABF8D3C78D4940D0050E63FB0 +:10762000B7A5D686A77F8E3CAD6F4E070070E63FAC +:107630004C25546BEAFC613CAE0FDFFEFF8FE63F4A +:10764000FD0E594C277E7CBCBCC5630700B0E63FED +:1076500001DADC4868C18ABCF6C15C1E00D0E63F96 +:107660001193499D1C3F833C3EF605EBFFEFE63F3F +:10767000532DE21A04807EBC8097860E0010E73FEF +:107680005279097166FF7B3C12E967FCFF2FE73FE7 +:107690002487BD26E2008C3C6A1181DFFF4FE73F63 +:1076A000D201F16E91026EBC909C670F0070E73FB3 +:1076B000749C54CD71FC67BC35C87EFAFF8FE73FE0 +:1076C0008304F59EC1BE813CE6C220FEFFAFE73FCA +:1076D0006564CC29177E70BC00C93FEDFFCFE73F42 +:1076E0001C8B7B08728080BC761A26E9FFEFE73F8F +:1076F000AEF99D6D28C08D3CE8A39C040010E83FC6 +:10770000334CE551D27F893C8F2C93170030E83FF2 +:1077100081F330B6E9FE8ABC9C7333060050E83F23 +:10772000BC35656BBFBF893CC68942200070E83F0D +:10773000757B11F365BF8BBC0479F5EBFF8FE83FD8 +:1077400057CB3DA26E0089BCDF04BC2200B0E83FED +:107750000A4BE038DF007DBC8A1B0CE5FFCFE83F19 +:10776000059FFF46710088BC438E91FCFFEFE83F08 +:1077700038707AD07B81833CC75FFA1E0010E93FE6 +:1077800003B4DF76913E893CB97B46130030E93F74 +:107790007602984B4E807F3C6F07EEE6FF4FE93F45 +:1077A0002E62FFD9F07E8FBCD1123CDEFF6FE93F25 +:1077B000BA382696AA8270BC0D8A45F4FF8FE93F3D +:1077C000EFA864911B8087BC3E2E98DDFFAFE93F98 +:1077D00037935A8AE04087BC66FB49EDFFCFE93F0B +:1077E00000E09BC108CE3F3C519CF12000F0E93FF6 +:1077F0000A5B8827AA3F8ABC06B045110010EA3F01 +:1078000056DA589948FF743CFAF6BB070030EA3F55 +:10781000186D2B8AABBE8C3C791D97100050EA3F47 +:10782000307978DDCAFE883C482EF51D0070EA3FAD +:10783000DBABD83D76418FBC5233591C0090EA3FF8 +:107840001276C28402BF8EBC4B3E4F2A00B0EA3F84 +:107850005F3FFF3C04FD69BCD11EAED7FFCFEA3FBE +:10786000B4709012E73E82BC780451EEFFEFEA3F1D +:10787000A3DE0EE03E066A3C5B0D65DBFF0FEB3FCF +:10788000B90A1F38C8065A3C57CAAAFEFF2FEB3F59 +:107890001D3C23741E0179BCDCBA95D9FF4FEB3F28 +:1078A0009F2A866810FF79BC9C659E240070EB3F80 +:1078B0003E4F86D045FF8A3C401687F9FF8FEB3F4D +:1078C000F9C3C29677FE7C3C4FCB04D2FFAFEB3FAF +:1078D000C42BF2EE27FF63BC455C41D2FFCFEB3FE8 +:1078E00021EA3BEEB7FF6CBCDF0963F8FFEFEB3F2B +:1078F0005C0B2E97034181BC5376B5E1FF0FEC3F43 +:10790000196AB79464C18B3CE357FAF1FF2FEC3F3F +:10791000EDC6308DEFFE64BC24E4BFDCFF4FEC3FCE +:107920007547ECBC683F84BCF7B954EDFF6FEC3F82 +:10793000ECE053F0A37E843CD58F99EBFF8FEC3FB6 +:10794000F192F98D0683733C9A21252100B0EC3F1A +:10795000040E18648EFD68BC9C4694DDFFCFEC3F9E +:1079600072EAC71CBE7E8E3C76C4FDEAFFEFEC3F98 +:10797000FE889FAD39BE8E3C2BF89A160010ED3F65 +:10798000715AB9A8917D753C1DF70F0D0030ED3F80 +:10799000DAC7706990C1893CC40F79EAFF4FED3FA7 +:1079A0000CFE58C5370E58BCE587DC2E0070ED3F45 +:1079B000440FC14DD6807FBCAA82DC210090ED3FF0 +:1079C0005C5CFD948F7C74BC83026BD8FFAFED3F91 +:1079D0007E6121C51D7F8C3C39476C2900D0ED3F6D +:1079E00053B1FFB29E01883CF59044E5FFEFED3FB7 +:1079F00089CC52C6D2006E3C94F6ABCDFF0FEE3F61 +:107A0000D2692D2040837FBCDDC852DBFF2FEE3FC3 +:107A100064081BCAC1007B3CEF1642F2FF4FEE3FE9 +:107A200051AB94B0A8FF723C115E8AE8FF6FEE3F45 +:107A300059BEEFB173F657BC0DFF9E110090EE3F9B +:107A400001C80B5E8D8084BC4417A5DFFFAFEE3FFD +:107A5000B52043D50600783CA17F121A00D0EE3F36 +:107A6000925C5660F80250BCC4BCBA0700F0EE3F0E +:107A700011E6355D444085BC028D7AF5FF0FEF3F7E +:107A80000591EF3931FB4FBCC78AE51E0030EF3F4F +:107A9000551173F2AC818A3C943482F5FF4FEF3F6D +:107AA00043C7D7D4413F8A3C6B4CA9FCFF6FEF3FE3 +:107AB0007578981CF40262BC41C4F9E1FF8FEF3F76 +:107AC0004BE777F4D17D773C7EE3E0D2FFAFEF3F29 +:107AD00031A37C9A19016FBC9EE4771C00D0EF3F64 +:107AE000B1ACCE4BEE81713C31C3E0F7FFEFEF3F1D +:107AF0005A87700137056EBC6E6065F4FF0FF03F6A +:107B0000DA0A1C49AD7E8ABC587A86F3FF2FF03F13 +:107B1000E0B2FCC3697F97BC170DFCFDFF4FF03F3F +:107B20005B94CB34FEBF973C824DCD030070F03F99 +:107B3000CB56E4C08300823CE8CBF2F9FF8FF03FE4 +:107B40001A7537BEDFFF6DBC65DA0C0100B0F03F7F +:107B5000EB26E6AE7F3F91BC38D3A40100D0F03FC6 +:107B6000F79F4879FA7D803CFDFDDAFAFFEFF03FA0 +:107B7000C06BD670050477BC96FDBA0B0010F13FC0 +:107B8000620B6D84D4808E3C5DF4E5FAFF2FF13FEB +:107B9000EF36FD64FABF9D3CD99AD50D0050F13FF8 +:107BA000AE50127077009A3C9A55210F0070F13F49 +:107BB000EEDEE3E2F9FD8D3C265427FCFF8FF13F1A +:107BC00073723BDC3000913C593C3D1200B0F13FF8 +:107BD00088010380797F993CB79E29F8FFCFF13F58 +:107BE000678C9FAB32F965BC00D48AF4FFEFF13F9C +:107BF000EB5BA79DBF7F933CA4868B0C0010F23FEC +:107C0000225BFD916B809F3C034385030030F23F74 +:107C100033BF9FEBC2FF933C84F6BCFFFF4FF23FA4 +:107C2000722E2E7EE701763CD92129F5FF6FF23FB7 +:107C3000610C7F76BBFC7F3C3C3A93140090F23F92 +:107C40002B41023CCA0272BC1363551400B0F23FD0 +:107C5000021FF233828092BC3B52FEEBFFCFF23F19 +:107C6000F2DC4F387EFF88BC96ADB80B00F0F23FD7 +:107C7000C541305051FF85BCAFE27AFBFF0FF33FA7 +:107C80009D285E88710081BC7F5FACFEFF2FF33FB3 +:107C900015B7B73F5DFF91BC5667A60C0050F33F88 +:107CA000BD828B22827F953C21F7FB110070F33F50 +:107CB000CCD50DC4BA00803CB92F59F9FF8FF33FE2 +:107CC00051A7B22D9D3F94BC42D2DD0400B0F33FDA +:107CD000E13876706B7F853C57C9B2F5FFCFF33F33 +:107CE0003112BF103A027A3C18B4B0EAFFEFF33F0A +:107CF000B052B1666D7F983CF4AF32150010F43F7E +:107D00002485195F37F8673C298B47170030F43F0B +:107D10004351DC72E601833C63B495E7FF4FF43FC7 +:107D20005A89B2B869FF893CE07504E8FF6FF43FF7 +:107D300054F2C29BB1C095BCE7C16FEFFF8FF43F17 +:107D4000722A3AF209409B3C04A7BEE5FFAFF43F1C +:107D5000457D0DBFB7FF94BCDE27101700D0F43F60 +:107D60003D6ADC7164C099BCE23EF00F00F0F43F64 +:107D70001C53850B897F973CD14BDC120010F53FDB +:107D800036A466716504603C7A2705160030F53F1D +:107D9000093223CECEBF96BC4C70DBECFF4FF53FD3 +:107DA000D7A10505720289BCA9545FEFFF6FF53FAB +:107DB0001264C90EE6BF9B3C1210E6170090F53F17 +:107DC00090EFAF81C57E883C923EC90300B0F53F7D +:107DD000C00CBF0A08419FBCBC19491D00D0F53F2B +:107DE000294725FB2A8198BC897AB8E7FFEFF53F40 +:107DF0000469ED80B77E94BC000000000000000024 +:107E00000000000000000000000000000000000072 +:107E10000000000000000000000000000000000062 +:107E20000000000000000000000000000000000052 +:107E30000000000000000000000000000000000042 +:107E40000000000000000000000000000000000032 +:107E50000000000000000000000000000000000022 +:107E60000000000000000000000000000000000012 +:107E70000000000000000000000000000000000002 +:107E800000000000000000000000000000000000F2 +:107E900000000000000000000000000000000000E2 +:107EA00000000000000000000000000000000000D2 +:107EB00000000000000000000000000000000000C2 +:107EC00000000000000000000000000000000000B2 +:107ED00000000000000000000000000000000000A2 +:107EE0000000000000000000000000000000000092 +:107EF0000000000000000000000000000000000082 +:107F00000000000000000000000000000000000071 +:107F10000000000000000000000000000000000061 +:107F20000000000000000000000000000000000051 +:107F30000000000000000000000000000000000041 +:107F40000000000000000000000000000000000031 +:107F50000000000000000000000000000000000021 +:107F60000000000000000000000000000000000011 +:107F70000000000000000000000000000000000001 +:107F800000000000000000000000000000000000F1 +:107F900000000000000000000000000000000000E1 +:107FA00000000000000000000000000000000000D1 +:107FB00000000000000000000000000000000000C1 +:107FC00000000000000000000000000000000000B1 +:107FD00000000000000000000000000000000000A1 +:107FE0000000000000000000000000000000000091 +:107FF0000000000000000000000000000000000081 +:108000000000000000000000000000000000000070 +:108010000000000000000000000000000000000060 +:108020000000000000000000000000000000000050 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:1080800000000000000000000000000000000000F0 +:1080900000000000000000000000000000000000E0 +:1080A00000000000000000000000000000000000D0 +:1080B00000000000000000000000000000000000C0 +:1080C00000000000000000000000000000000000B0 +:1080D00000000000000000000000000000000000A0 +:1080E0000000000000000000000000000000000090 +:1080F0000000000000000000000000000000000080 +:10810000000000000000000000000000000000006F +:10811000000000000000000000000000000000005F +:10812000000000000000000000000000000000004F +:10813000000000000000000000000000000000003F +:10814000000000000000000000000000000000002F +:10815000000000000000000000000000000000001F +:10816000000000000000000000000000000000000F +:1081700000000000000000000000000000000000FF +:1081800000000000000000000000000000000000EF +:1081900000000000000000000000000000000000DF +:1081A00000000000000000000000000000000000CF +:1081B00000000000000000000000000000000000BF +:1081C00000000000000000000000000000000000AF +:1081D000000000000000000000000000000000009F +:1081E000000000000000000000000000000000008F +:1081F000000000000000000000000000000000007F +:10820000000000000000000000000000000000006E +:10821000000000000000000000000000000000005E +:10822000000000000000000000000000000000004E +:10823000000000000000000000000000000000003E +:10824000000000000000000000000000000000002E +:10825000000000000000000000000000000000001E +:10826000000000000000000000000000000000000E +:1082700000000000000000000000000000000000FE +:1082800000000000000000000000000000000000EE +:1082900000000000000000000000000000000000DE +:1082A00000000000000000000000000000000000CE +:1082B00000000000000000000000000000000000BE +:1082C00000000000000000000000000000000000AE +:1082D000000000000000000000000000000000009E +:1082E000000000000000000000000000000000008E +:1082F000000000000000000000000000000000007E +:10830000000000000000000000000000000000006D +:10831000000000000000000000000000000000005D +:10832000000000000000000000000000000000004D +:10833000000000000000000000000000000000003D +:10834000000000000000000000000000000000002D +:10835000000000000000000000000000000000001D +:10836000000000000000000000000000000000000D +:1083700000000000000000000000000000000000FD +:1083800000000000000000000000000000000000ED +:1083900000000000000000000000000000000000DD +:1083A00000000000000000000000000000000000CD +:1083B00000000000000000000000000000000000BD +:1083C00000000000000000000000000000000000AD +:1083D000000000000000000000000000000000009D +:1083E000000000000000000000000000000000008D +:1083F000000000000000000000000000000000007D +:10840000000000000000000000000000000000006C +:10841000000000000000000000000000000000005C +:10842000000000000000000000000000000000004C +:10843000000000000000000000000000000000003C +:10844000000000000000000000000000000000002C +:10845000000000000000000000000000000000001C +:10846000000000000000000000000000000000000C +:1084700000000000000000000000000000000000FC +:1084800000000000000000000000000000000000EC +:1084900000000000000000000000000000000000DC +:1084A00000000000000000000000000000000000CC +:1084B00000000000000000000000000000000000BC +:1084C00000000000000000000000000000000000AC +:1084D000000000000000000000000000000000009C +:1084E000000000000000000000000000000000008C +:1084F000000000000000000000000000000000007C +:10850000000000000000000000000000000000006B +:10851000000000000000000000000000000000005B +:10852000000000000000000000000000000000004B +:10853000000000000000000000000000000000003B +:10854000000000000000000000000000000000002B +:10855000000000000000000000000000000000001B +:10856000000000000000000000000000000000000B +:1085700000000000000000000000000000000000FB +:1085800000000000000000000000000000000000EB +:1085900000000000000000000000000000000000DB +:1085A00000000000000000000000000000000000CB +:1085B00000000000000000000000000000000000BB +:1085C00000000000000000000000000000000000AB +:1085D000000000000000000000000000000000009B +:1085E000000000000000000000000000000000008B +:1085F000000000000000000000000000000000007B +:10860000000000000000000000000000000000006A +:10861000000000000000000000000000000000005A +:10862000000000000000000000000000000000004A +:10863000000000000000000000000000000000003A +:10864000000000000000000000000000000000002A +:10865000000000000000000000000000000000001A +:10866000000000000000000000000000000000000A +:1086700000000000000000000000000000000000FA +:1086800000000000000000000000000000000000EA +:1086900000000000000000000000000000000000DA +:1086A00000000000000000000000000000000000CA +:1086B00000000000000000000000000000000000BA +:1086C00000000000000000000000000000000000AA +:1086D000000000000000000000000000000000009A +:1086E000000000000000000000000000000000008A +:1086F000000000000000000000000000000000007A +:108700000000000000000000000000000000000069 +:108710000000000000000000000000000000000059 +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:108740000000000000000000000000000000000029 +:108750000000000000000000000000000000000019 +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800000000000000000000000000000000000E9 +:1087900000000000000000000000000000000000D9 +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00000000000000000000000000000000000A9 +:1087D0000000000000000000000000000000000099 +:1087E0000000000000000000000000000000000089 +:1087F0000000000000000000000000000000000079 +:108800000000000000000000000000000000000068 +:108810000000000000000000000000000000000058 +:108820000000000000000000000000000000000048 +:108830000000000000000000000000000000000038 +:108840000000000000000000000000000000000028 +:108850000000000000000000000000000000000018 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800000000000000000000000000000000000E8 +:1088900000000000000000000000000000000000D8 +:1088A00000000000000000000000000000000000C8 +:1088B00000000000000000000000000000000000B8 +:1088C00000000000000000000000000000000000A8 +:1088D0000000000000000000000000000000000098 +:1088E0000000000000000000000000000000000088 +:1088F0000000000000000000000000000000000078 +:108900000000000000000000000000000000000067 +:108910000000000000000000000000000000000057 +:108920000000000000000000000000000000000047 +:108930000000000000000000000000000000000037 +:108940000000000000000000000000000000000027 +:108950000000000000000000000000000000000017 +:108960000000000000000000000000000000000007 +:1089700000000000000000000000000000000000F7 +:1089800000000000000000000000000000000000E7 +:1089900000000000000000000000000000000000D7 +:1089A00000000000000000000000000000000000C7 +:1089B00000000000000000000000000000000000B7 +:1089C00000000000000000000000000000000000A7 +:1089D0000000000000000000000000000000000097 +:1089E0000000000000000000000000000000000087 +:1089F0000000000000000000000000000000000077 +:108A00000000000000000000000000000000000066 +:108A10000000000000000000000000000000000056 +:108A20000000000000000000000000000000000046 +:108A30000000000000000000000000000000000036 +:108A40000000000000000000000000000000000026 +:108A50000000000000000000000000000000000016 +:108A60000000000000000000000000000000000006 +:108A700000000000000000000000000000000000F6 +:108A800000000000000000000000000000000000E6 +:108A900000000000000000000000000000000000D6 +:108AA00000000000000000000000000000000000C6 +:108AB00000000000000000000000000000000000B6 +:108AC00000000000000000000000000000000000A6 +:108AD0000000000000000000000000000000000096 +:108AE0000000000000000000000000000000000086 +:108AF0000000000000000000000000000000000076 +:108B00000000000000000000000000000000000065 +:108B10000000000000000000000000000000000055 +:108B20000000000000000000000000000000000045 +:108B30000000000000000000000000000000000035 +:108B40000000000000000000000000000000000025 +:108B50000000000000000000000000000000000015 +:108B60000000000000000000000000000000000005 +:108B700000000000000000000000000000000000F5 +:108B800000000000000000000000000000000000E5 +:108B900000000000000000000000000000000000D5 +:108BA00000000000000000000000000000000000C5 +:108BB00000000000000000000000000000000000B5 +:108BC00000000000000000000000000000000000A5 +:108BD0000000000000000000000000000000000095 +:108BE0000000000000000000000000000000000085 +:108BF0000000000000000000000000000000000075 +:108C00000000000000000000000000000000000064 +:108C10000000000000000000000000000000000054 +:108C20000000000000000000000000000000000044 +:108C30000000000000000000000000000000000034 +:108C40000000000000000000000000000000000024 +:108C50000000000000000000000000000000000014 +:108C60000000000000000000000000000000000004 +:108C700000000000000000000000000000000000F4 +:108C800000000000000000000000000000000000E4 +:108C900000000000000000000000000000000000D4 +:108CA00000000000000000000000000000000000C4 +:108CB00000000000000000000000000000000000B4 +:108CC00000000000000000000000000000000000A4 +:108CD0000000000000000000000000000000000094 +:108CE0000000000000000000000000000000000084 +:108CF0000000000000000000000000000000000074 +:108D00000000000000000000000000000000000063 +:108D10000000000000000000000000000000000053 +:108D20000000000000000000000000000000000043 +:108D30000000000000000000000000000000000033 +:108D40000000000000000000000000000000000023 +:108D50000000000000000000000000000000000013 +:108D60000000000000000000000000000000000003 +:108D700000000000000000000000000000000000F3 +:108D800000000000000000000000000000000000E3 +:108D900000000000000000000000000000000000D3 +:108DA00000000000000000000000000000000000C3 +:108DB00000000000000000000000000000000000B3 +:108DC00000000000000000000000000000000000A3 +:108DD0000000000000000000000000000000000093 +:108DE0000000000000000000000000000000000083 +:108DF0000000000000000000000000000000000073 +:108E00000000000000000000000000000000000062 +:108E10000000000000000000000000000000000052 +:108E20000000000000000000000000000000000042 +:108E30000000000000000000000000000000000032 +:108E40000000000000000000000000000000000022 +:108E50000000000000000000000000000000000012 +:108E60000000000000000000000000000000000002 +:108E700000000000000000000000000000000000F2 +:108E800000000000000000000000000000000000E2 +:108E900000000000000000000000000000000000D2 +:108EA00000000000000000000000000000000000C2 +:108EB00000000000000000000000000000000000B2 +:108EC00000000000000000000000000000000000A2 +:108ED0000000000000000000000000000000000092 +:108EE0000000000000000000000000000000000082 +:108EF0000000000000000000000000000000000072 +:108F00000000000000000000000000000000000061 +:108F10000000000000000000000000000000000051 +:108F20000000000000000000000000000000000041 +:108F30000000000000000000000000000000000031 +:108F40000000000000000000000000000000000021 +:108F50000000000000000000000000000000000011 +:108F60000000000000000000000000000000000001 +:108F700000000000000000000000000000000000F1 +:108F800000000000000000000000000000000000E1 +:108F900000000000000000000000000000000000D1 +:108FA00000000000000000000000000000000000C1 +:108FB00000000000000000000000000000000000B1 +:108FC00000000000000000000000000000000000A1 +:108FD0000000000000000000000000000000000091 +:108FE0000000000000000000000000000000000081 +:108FF0000000000000000000000000000000000071 +:109000000000000000000000000000000000000060 +:109010000000000000000000000000000000000050 +:109020000000000000000000000000000000000040 +:109030000000000000000000000000000000000030 +:109040000000000000000000000000000000000020 +:109050000000000000000000000000000000000010 +:109060000000000000000000000000000000000000 +:1090700000000000000000000000000000000000F0 +:1090800000000000000000000000000000000000E0 +:1090900000000000000000000000000000000000D0 +:1090A00000000000000000000000000000000000C0 +:1090B00000000000000000000000000000000000B0 +:1090C00000000000000000000000000000000000A0 +:1090D0000000000000000000000000000000000090 +:1090E0000000000000000000000000000000000080 +:1090F0000000000000000000000000000000000070 +:10910000000000000000000000000000000000005F +:10911000000000000000000000000000000000004F +:10912000000000000000000000000000000000003F +:10913000000000000000000000000000000000002F +:10914000000000000000000000000000000000001F +:10915000000000000000000000000000000000000F +:1091600000000000000000000000000000000000FF +:1091700000000000000000000000000000000000EF +:1091800000000000000000000000000000000000DF +:1091900000000000000000000000000000000000CF +:1091A00000000000000000000000000000000000BF +:1091B00000000000000000000000000000000000AF +:1091C000000000000000000000000000000000009F +:1091D000000000000000000000000000000000008F +:1091E000000000000000000000000000000000007F +:1091F000000000000000000000000000000000006F +:10920000000000000000000000000000000000005E +:10921000000000000000000000000000000000004E +:10922000000000000000000000000000000000003E +:10923000000000000000000000000000000000002E +:10924000000000000000000000000000000000001E +:10925000000000000000000000000000000000000E +:1092600000000000000000000000000000000000FE +:1092700000000000000000000000000000000000EE +:1092800000000000000000000000000000000000DE +:1092900000000000000000000000000000000000CE +:1092A00000000000000000000000000000000000BE +:1092B00000000000000000000000000000000000AE +:1092C000000000000000000000000000000000009E +:1092D000000000000000000000000000000000008E +:1092E000000000000000000000000000000000007E +:1092F000000000000000000000000000000000006E +:10930000000000000000000000000000000000005D +:10931000000000000000000000000000000000004D +:10932000000000000000000000000000000000003D +:10933000000000000000000000000000000000002D +:10934000000000000000000000000000000000001D +:10935000000000000000000000000000000000000D +:1093600000000000000000000000000000000000FD +:1093700000000000000000000000000000000000ED +:1093800000000000000000000000000000000000DD +:1093900000000000000000000000000000000000CD +:1093A00000000000000000000000000000000000BD +:1093B00000000000000000000000000000000000AD +:1093C000000000000000000000000000000000009D +:1093D000000000000000000000000000000000008D +:1093E000000000000000000000000000000000007D +:1093F000000000000000000000000000000000006D +:10940000000000000000000000000000000000005C +:10941000000000000000000000000000000000004C +:10942000000000000000000000000000000000003C +:10943000000000000000000000000000000000002C +:10944000000000000000000000000000000000001C +:10945000000000000000000000000000000000000C +:1094600000000000000000000000000000000000FC +:1094700000000000000000000000000000000000EC +:1094800000000000000000000000000000000000DC +:1094900000000000000000000000000000000000CC +:1094A00000000000000000000000000000000000BC +:1094B00000000000000000000000000000000000AC +:1094C000000000000000000000000000000000009C +:1094D000000000000000000000000000000000008C +:1094E000000000000000000000000000000000007C +:1094F000000000000000000000000000000000006C +:10950000000000000000000000000000000000005B +:10951000000000000000000000000000000000004B +:10952000000000000000000000000000000000003B +:10953000000000000000000000000000000000002B +:10954000000000000000000000000000000000001B +:10955000000000000000000000000000000000000B +:1095600000000000000000000000000000000000FB +:1095700000000000000000000000000000000000EB +:1095800000000000000000000000000000000000DB +:1095900000000000000000000000000000000000CB +:1095A00000000000000000000000000000000000BB +:1095B00000000000000000000000000000000000AB +:1095C000000000000000000000000000000000009B +:1095D000000000000000000000000000000000008B +:1095E000000000000000000000000000000000007B +:1095F000000000000000000000000000000000006B +:10960000000000000000000000000000000000005A +:10961000000000000000000000000000000000004A +:10962000000000000000000000000000000000003A +:10963000000000000000000000000000000000002A +:10964000000000000000000000000000000000001A +:10965000000000000000000000000000000000000A +:1096600000000000000000000000000000000000FA +:1096700000000000000000000000000000000000EA +:1096800000000000000000000000000000000000DA +:1096900000000000000000000000000000000000CA +:1096A00000000000000000000000000000000000BA +:1096B00000000000000000000000000000000000AA +:1096C000000000000000000000000000000000009A +:1096D000000000000000000000000000000000008A +:1096E000000000000000000000000000000000007A +:1096F000000000000000000000000000000000006A +:109700000000000000000000000000000000000059 +:109710000000000000000000000000000000000049 +:109720000000000000000000000000000000000039 +:109730000000000000000000000000000000000029 +:109740000000000000000000000000000000000019 +:109750000000000000000000000000000000000009 +:1097600000000000000000000000000000000000F9 +:1097700000000000000000000000000000000000E9 +:1097800000000000000000000000000000000000D9 +:1097900000000000000000000000000000000000C9 +:1097A00000000000000000000000000000000000B9 +:1097B00000000000000000000000000000000000A9 +:1097C0000000000000000000000000000000000099 +:1097D0000000000000000000000000000000000089 +:1097E0000000000000000000000000000000000079 +:1097F0000000000000000000000000000000000069 +:109800000000000000000000000000000000000058 +:109810000000000000000000000000000000000048 +:109820000000000000000000000000000000000038 +:109830000000000000000000000000000000000028 +:109840000000000000000000000000000000000018 +:109850000000000000000000000000000000000008 +:1098600000000000000000000000000000000000F8 +:1098700000000000000000000000000000000000E8 +:1098800000000000000000000000000000000000D8 +:1098900000000000000000000000000000000000C8 +:1098A00000000000000000000000000000000000B8 +:1098B00000000000000000000000000000000000A8 +:1098C0000000000000000000000000000000000098 +:1098D0000000000000000000000000000000000088 +:1098E0000000000000000000000000000000000078 +:1098F0000000000000000000000000000000000068 +:109900000000000000000000000000000000000057 +:109910000000000000000000000000000000000047 +:109920000000000000000000000000000000000037 +:109930000000000000000000000000000000000027 +:109940000000000000000000000000000000000017 +:109950000000000000000000000000000000000007 +:1099600000000000000000000000000000000000F7 +:1099700000000000000000000000000000000000E7 +:1099800000000000000000000000000000000000D7 +:1099900000000000000000000000000000000000C7 +:1099A00000000000000000000000000000000000B7 +:1099B00000000000000000000000000000000000A7 +:1099C0000000000000000000000000000000000097 +:1099D0000000000000000000000000000000000087 +:1099E0000000000000000000000000000000000077 +:1099F0000000000000000000000000000000000067 +:109A00000000000000000000000000000000000056 +:109A10000000000000000000000000000000000046 +:109A20000000000000000000000000000000000036 +:109A30000000000000000000000000000000000026 +:109A40000000000000000000000000000000000016 +:109A50000000000000000000000000000000000006 +:109A600000000000000000000000000000000000F6 +:109A700000000000000000000000000000000000E6 +:109A800000000000000000000000000000000000D6 +:109A900000000000000000000000000000000000C6 +:109AA00000000000000000000000000000000000B6 +:109AB00000000000000000000000000000000000A6 +:109AC0000000000000000000000000000000000096 +:109AD0000000000000000000000000000000000086 +:109AE0000000000000000000000000000000000076 +:109AF0000000000000000000000000000000000066 +:109B00000000000000000000000000000000000055 +:109B10000000000000000000000000000000000045 +:109B20000000000000000000000000000000000035 +:109B30000000000000000000000000000000000025 +:109B40000000000000000000000000000000000015 +:109B50000000000000000000000000000000000005 +:109B600000000000000000000000000000000000F5 +:109B700000000000000000000000000000000000E5 +:109B800000000000000000000000000000000000D5 +:109B900000000000000000000000000000000000C5 +:109BA00000000000000000000000000000000000B5 +:109BB00000000000000000000000000000000000A5 +:109BC0000000000000000000000000000000000095 +:109BD0000000000000000000000000000000000085 +:109BE0000000000000000000000000000000000075 +:109BF0000000000000000000000000000000000065 +:109C00000000000000000000000000000000000054 +:109C10000000000000000000000000000000000044 +:109C20000000000000000000000000000000000034 +:109C30000000000000000000000000000000000024 +:109C40000000000000000000000000000000000014 +:109C50000000000000000000000000000000000004 +:109C600000000000000000000000000000000000F4 +:109C700000000000000000000000000000000000E4 +:109C800000000000000000000000000000000000D4 +:109C900000000000000000000000000000000000C4 +:109CA00000000000000000000000000000000000B4 +:109CB00000000000000000000000000000000000A4 +:109CC0000000000000000000000000000000000094 +:109CD0000000000000000000000000000000000084 +:109CE0000000000000000000000000000000000074 +:109CF0000000000000000000000000000000000064 +:109D00000000000000000000000000000000000053 +:109D10000000000000000000000000000000000043 +:109D20000000000000000000000000000000000033 +:109D30000000000000000000000000000000000023 +:109D40000000000000000000000000000000000013 +:109D50000000000000000000000000000000000003 +:109D600000000000000000000000000000000000F3 +:109D700000000000000000000000000000000000E3 +:109D800000000000000000000000000000000000D3 +:109D900000000000000000000000000000000000C3 +:109DA00000000000000000000000000000000000B3 +:109DB00000000000000000000000000000000000A3 +:109DC0000000000000000000000000000000000093 +:109DD0000000000000000000000000000000000083 +:109DE0000000000000000000000000000000000073 +:109DF0000000000000000000000000000000000063 +:109E00000000000000000000000000000000000052 +:109E10000000000000000000000000000000000042 +:109E20000000000000000000000000000000000032 +:109E30000000000000000000000000000000000022 +:109E40000000000000000000000000000000000012 +:109E50000000000000000000000000000000000002 +:109E600000000000000000000000000000000000F2 +:109E700000000000000000000000000000000000E2 +:109E800000000000000000000000000000000000D2 +:109E900000000000000000000000000000000000C2 +:109EA00000000000000000000000000000000000B2 +:109EB00000000000000000000000000000000000A2 +:109EC0000000000000000000000000000000000092 +:109ED0000000000000000000000000000000000082 +:109EE0000000000000000000000000000000000072 +:109EF0000000000000000000000000000000000062 +:109F00000000000000000000000000000000000051 +:109F10000000000000000000000000000000000041 +:109F20000000000000000000000000000000000031 +:109F30000000000000000000000000000000000021 +:109F40000000000000000000000000000000000011 +:109F50000000000000000000000000000000000001 +:109F600000000000000000000000000000000000F1 +:109F700000000000000000000000000000000000E1 +:109F800000000000000000000000000000000000D1 +:109F900000000000000000000000000000000000C1 +:109FA00000000000000000000000000000000000B1 +:109FB00000000000000000000000000000000000A1 +:109FC0000000000000000000000000000000000091 +:109FD0000000000000000000000000000000000081 +:109FE0000000000000000000000000000000000071 +:109FF0000000000000000000000000000000000061 +:10A000000000000000000000000000000000000050 +:10A010000000000000000000000000000000000040 +:10A020000000000000000000000000000000000030 +:10A030000000000000000000000000000000000020 +:10A040000000000000000000000000000000000010 +:10A050000000000000000000000000000000000000 +:10A0600000000000000000000000000000000000F0 +:10A0700000000000000000000000000000000000E0 +:10A0800000000000000000000000000000000000D0 +:10A0900000000000000000000000000000000000C0 +:10A0A00000000000000000000000000000000000B0 +:10A0B00000000000000000000000000000000000A0 +:10A0C0000000000000000000000000000000000090 +:10A0D0000000000000000000000000000000000080 +:10A0E0000000000000000000000000000000000070 +:10A0F0000000000000000000000000000000000060 +:10A10000000000000000000000000000000000004F +:10A11000000000000000000000000000000000003F +:10A12000000000000000000000000000000000002F +:10A13000000000000000000000000000000000001F +:10A14000000000000000000000000000000000000F +:10A1500000000000000000000000000000000000FF +:10A1600000000000000000000000000000000000EF +:10A1700000000000000000000000000000000000DF +:10A1800000000000000000000000000000000000CF +:10A1900000000000000000000000000000000000BF +:10A1A00000000000000000000000000000000000AF +:10A1B000000000000000000000000000000000009F +:10A1C000000000000000000000000000000000008F +:10A1D000000000000000000000000000000000007F +:10A1E000000000000000000000000000000000006F +:10A1F000000000000000000000000000000000005F +:10A20000000000000000000000000000000000004E +:10A21000000000000000000000000000000000003E +:10A22000000000000000000000000000000000002E +:10A23000000000000000000000000000000000001E +:10A24000000000000000000000000000000000000E +:10A2500000000000000000000000000000000000FE +:10A2600000000000000000000000000000000000EE +:10A2700000000000000000000000000000000000DE +:10A2800000000000000000000000000000000000CE +:10A2900000000000000000000000000000000000BE +:10A2A00000000000000000000000000000000000AE +:10A2B000000000000000000000000000000000009E +:10A2C000000000000000000000000000000000008E +:10A2D000000000000000000000000000000000007E +:10A2E000000000000000000000000000000000006E +:10A2F000000000000000000000000000000000005E +:10A30000000000000000000000000000000000004D +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000000000000000000076 +:10AAE0000000000000000000000000000000000066 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB20000000000000000000000000000000000025 +:10AB30000000000000000000000000000000000015 +:10AB40000000000000000000000000000000000005 +:10AB500000000000000000000000000000000000F5 +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00000000000000000000000000000000000A5 +:10ABB0000000000000000000000000000000000095 +:10ABC0000000000000000000000000000000000085 +:10ABD0000000000000000000000000000000000075 +:10ABE0000000000000000000000000000000000065 +:10ABF0000000000000000000000000000000000055 +:10AC00000000000000000000000000000000000044 +:10AC10000000000000000000000000000000000034 +:10AC20000000000000000000000000000000000024 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF0000000000000000000000000000000000051 +:10B000000000000000000000000000000000000040 +:10B010000000000000000000000000000000000030 +:10B020000000000000000000000000000000000020 +:10B030000000000000000000000000000000000010 +:10B040000000000000000000000000000000000000 +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B0900000000000000000000000000000000000B0 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F000000000000000000000000000000000000000 +:10F0100000000000000000000000000000000000F0 +:10F0200000000000000000000000000000000000E0 +:10F0300000000000000000000000000000000000D0 +:10F0400000000000000000000000000000000000C0 +:10F0500000000000000000000000000000000000B0 +:10F0600000000000000000000000000000000000A0 +:10F070000000000000000000000000000000000090 +:10F080000000000000000000000000000000000080 +:10F090000000000000000000000000000000000070 +:10F0A0000000000000000000000000000000000060 +:10F0B0000000000000000000000000000000000050 +:10F0C0000000000000000000000000000000000040 +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000000000000000000020 +:10F0F0000000000000000000000000000000000010 +:10F1000000000000000000000000000000000000FF +:10F1100000000000000000000000000000000000EF +:10F1200000000000000000000000000000000000DF +:10F1300000000000000000000000000000000000CF +:10F1400000000000000000000000000000000000BF +:10F1500000000000000000000000000000000000AF +:10F16000000000000000000000000000000000009F +:10F17000000000000000000000000000000000008F +:10F18000000000000000000000000000000000007F +:10F19000000000000000000000000000000000006F +:10F1A000000000000000000000000000000000005F +:10F1B000000000000000000000000000000000004F +:10F1C000000000000000000000000000000000003F +:10F1D000000000000000000000000000000000002F +:10F1E000000000000000000000000000000000001F +:10F1F000000000000000000000000000000000000F +:10F2000000000000000000000000000000000000FE +:10F2100000000000000000000000000000000000EE +:10F2200000000000000000000000000000000000DE +:10F2300000000000000000000000000000000000CE +:10F2400000000000000000000000000000000000BE +:10F2500000000000000000000000000000000000AE +:10F26000000000000000000000000000000000009E +:10F27000000000000000000000000000000000008E +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F000000000000000000000000000000000000E +:10F3000000000000000000000000000000000000FD +:10F3100000000000000000000000000000000000ED +:10F3200000000000000000000000000000000000DD +:10F3300000000000000000000000000000000000CD +:10F3400000000000000000000000000000000000BD +:10F3500000000000000000000000000000000000AD +:10F36000000000000000000000000000000000009D +:10F37000000000000000000000000000000000008D +:10F38000000000000000000000000000000000007D +:10F39000000000000000000000000000000000006D +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D000000000000000000000000000000000002D +:10F3E000000000000000000000000000000000001D +:10F3F000000000000000000000000000000000000D +:10F4000000000000000000000000000000000000FC +:10F4100000000000000000000000000000000000EC +:10F4200000000000000000000000000000000000DC +:10F4300000000000000000000000000000000000CC +:10F4400000000000000000000000000000000000BC +:10F4500000000000000000000000000000000000AC +:10F46000000000000000000000000000000000009C +:10F47000000000000000000000000000000000008C +:10F48000000000000000000000000000000000007C +:10F49000000000000000000000000000000000006C +:10F4A000000000000000000000000000000000005C +:10F4B000000000000000000000000000000000004C +:10F4C000000000000000000000000000000000003C +:10F4D000000000000000000000000000000000002C +:10F4E000000000000000000000000000000000001C +:10F4F000000000000000000000000000000000000C +:10F5000000000000000000000000000000000000FB +:10F5100000000000000000000000000000000000EB +:10F5200000000000000000000000000000000000DB +:10F5300000000000000000000000000000000000CB +:10F5400000000000000000000000000000000000BB +:10F5500000000000000000000000000000000000AB +:10F56000000000000000000000000000000000009B +:10F57000000000000000000000000000000000008B +:10F58000000000000000000000000000000000007B +:10F59000000000000000000000000000000000006B +:10F5A000000000000000000000000000000000005B +:10F5B000000000000000000000000000000000004B +:10F5C000000000000000000000000000000000003B +:10F5D000000000000000000000000000000000002B +:10F5E000000000000000000000000000000000001B +:10F5F000000000000000000000000000000000000B +:10F6000000000000000000000000000000000000FA +:10F6100000000000000000000000000000000000EA +:10F6200000000000000000000000000000000000DA +:10F6300000000000000000000000000000000000CA +:10F6400000000000000000000000000000000000BA +:10F6500000000000000000000000000000000000AA +:10F66000000000000000000000000000000000009A +:10F67000000000000000000000000000000000008A +:10F68000000000000000000000000000000000007A +:10F69000000000000000000000000000000000006A +:10F6A000000000000000000000000000000000005A +:10F6B000000000000000000000000000000000004A +:10F6C000000000000000000000000000000000003A +:10F6D000000000000000000000000000000000002A +:10F6E000000000000000000000000000000000001A +:10F6F000000000000000000000000000000000000A +:10F7000000000000000000000000000000000000F9 +:10F7100000000000000000000000000000000000E9 +:10F7200000000000000000000000000000000000D9 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000000000099 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F860000000000000000000000000000000000098 +:10F870000000000000000000000000000000000088 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF0000000000000000000000000000000000001 +:020000022000DC +:1000000000000000000000000000000000000000F0 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:1020000003FC20324006000A0E0A000103010810FA +:1020100032004006F6090000000C0100000000003C +:1020200000135359040600000000000000080109D5 +:102030000001323340060000281919000000080092 +:102040000000080000000800000008000000080070 +:10205000000008000000080000000800F0EF000089 +:10206000000008000000080000000800F0EF000079 +:102070000000080000000800000008000000000048 +:10208000000101000000000000000000000000004E +:10209000000000000000000000000101010101003B +:1020A000000100000000010101010001000000002A +:1020B000010000010000000007000000010701030B +:1020C000020314000A0A40000000C8003C0000009F +:1020D0000000000000000000000000000000000000 +:1020E0000000000000000000C800C8009600C80002 +:1020F00007078000800005050000000000000000C8 +:1021000006010000000017003900910010001400C3 +:10211000F9FFC4FFFF7FFF7FFF7FFF7F50002C018F +:102120003200FA000A04B4B4323223050000000081 +:1021300000070D0000320D00000000203232323264 +:1021400032323232323232323232323232320000D3 +:10215000000000000000000000000000000000007F +:102160000A05000A00000000170F001210120000FC +:10217000000000000000000000000000000000005F +:10218000000000000F2332465000000078643C3C01 +:102190003C3C3C3C08000000000000000F2332469D +:1021A0005000000078643C3C3C3C3C3C0F141E2832 +:1021B000000000000A0A0A0A0A0A0A0A1946000070 +:1021C00000000000374646464646464600000000EE +:1021D0000A0314005F00F1FF14000F000A00BC02A4 +:1021E00000000000F8FF0000DC003200640028005E +:1021F0000F000F001C023D011C02740400003F068A +:102200000000FF09F40100003F060000FF0932143E +:10221000021E1E3202006400460046007700C80518 +:10222000770088090000000040063000200001000F +:10223000220000003A00520070008F00AF00CF0073 +:10224000EF000F012E014F016E018E01AD01CE0195 +:10225000EC010F022D024D026D028D02AC02CC0288 +:10226000EB020B032B034A036A038903AA03C90386 +:10227000E703FF0337040000000000000000000037 +:10228000000000000000000000000000000000004E +:10229000000000000000000000000000000000003E +:1022A000000000000000000000000000000000002E +:1022B000000000000000000000000000000000001E +:1022C000000000000000000000000000000000000E +:1022D00000000000000000000000000000000000FE +:1022E00000000000000000000000000000000000EE +:1022F00000000000000000000000F6093000460069 +:102300000100480000003C00430066008500A90071 +:10231000C800E90009012A0149016B018901AB01EB +:10232000C901EB0109022B024A026C028A02AC02CB +:10233000CA02EC020B032D034B036D038B03AE03A8 +:10234000CB03EE030C042F044C046F048B04AF0486 +:10235000CC04EF040D0530054D0570058D05B00565 +:10236000CD05F1050D0630064E0672068E06B10645 +:10237000CE06F2060F073207500773079007B30720 +:10238000D107F40711083408520875089108B108FC +:10239000C608E70800000000000000000000000080 +:1023A000000000000000000000000000000000002D +:1023B000000000000000000000000000000000001D +:1023C000000000000000000000000000000000000D +:1023D0000201200019450000F16C000084D90600BC +:1023E00029B1010010270000C40900000000030308 +:1023F000030505050505014B0F00F0000000000076 +:10240000010000030303050505050500194500004B +:102410000200000084DE01000000000014140A0A1B +:102420001400000000000000141414140101010144 +:10243000010040003200E8030F0008000500E10041 +:1024400000001E502800B4005000040000000000EE +:10245000B40050006400A000000000014F01000023 +:102460000000000078000D0D0A09320064006400CD +:102470000A003200C800640064000F02E8E8F800B7 +:10248000F8000200190000006A00750081008E004B +:102490009D00AC00BD00CF00E200F7000D01260159 +:1024A00040015C0179019901BC01E00106023002A2 +:1024B0005B028902BA02EE0224035D039A03D90388 +:1024C0001B046004A904F40443059505E9054106CD +:1024D0009C06FA065B07BE0724088D08F808650904 +:1024E000D409450AB80A2D0BA20B190C900C080D43 +:1024F000800DF80D6F0EE60E5C0FD00F4210B3107A +:1025000021118C11F4115912BA1217137013C4133C +:1025100013145D14A114E01418154B1577159C15B0 +:10252000BB15D415E515EF15F31536003D00440035 +:102530004C00560060006B00770085009300A400FB +:10254000B500C900DE00F5000E0129014601650154 +:102550008701AC01D401FE012B025B028F02C6028F +:1025600001033F038003C6030F045D04AE040305AB +:102570005D05BA051B068106EA065707C9073D082F +:10258000B6083109B009320AB70A3E0BC70B520C24 +:10259000DF0C6D0DFC0D8B0E1A0FA80F3610C3103B +:1025A0004D11D6115B12DE125C13D7134D14BD14FE +:1025B00028158D15EC1544169516DE161F1758179D +:1025C0008917B117D117E717F517FA174E005600FC +:1025D00060006B00760083009100A000B100C20093 +:1025E000D600EB0002011A01350152017001910180 +:1025F000B501DB0103022E025C028D02C102F8026A +:1026000032036F03B003F4033B048604D4042605AD +:102610007C05D50532069206F5065C07C607330829 +:10262000A30816098C09040A7E0AFA0A790BF80B2A +:10263000790CFB0C7E0D010E830E060F870F071021 +:10264000861003117D11F5116912DA124713AF13C9 +:1026500013147214CB141E156B15B215F2152C162B +:102660005E168916AC16C716DB16E716EB164E007B +:10267000560060006B00760083009100A000B1005E +:10268000C200D600EB0002011A01350152017001AF +:102690009101B501DB0103022E025C028D02C10231 +:1026A000F80232036F03B003F4033B048604D4043E +:1026B00026057C05D50532069206F5065C07C60799 +:1026C0003308A30816098C09040A7E0AFA0A790B52 +:1026D000F80B790CFB0C7E0D010E830E060F870F95 +:1026E0000710861003117D11F5116912DA124713D4 +:1026F000AF1313147214CB141E156B15B215F2150B +:102700002C165E168916AC16C716DB16E716EB16E6 +:102710005500550045004200000000000000000088 +:1027200000000000000000000000000000000000A9 +:102730000000000000000000000000000000000099 +:102740000000000000000000000000000000000089 +:102750000000000000000000000000000000000079 +:102760000000000000000000000000000000000069 +:102770000000000000000000000000000000000059 +:102780000000000000000000000000000000000049 +:102790000000000000000000000000000000000039 +:1027A0000000000000000000000000000000000029 +:1027B0000000000000000000000000000000000019 +:1027C0000000000000000000000000000000000009 +:1027D00000000000000000000000000000000000F9 +:1027E00000000000000000000000000000000000E9 +:1027F00000000000000000000000000000000000D9 +:1028000000000000000000000000000000000000C8 +:1028100000000000000000000000000000000000B8 +:1028200000000000000000000000000000000000A8 +:102830000000000000000000000000000000000098 +:102840000000000000000000000000000000000088 +:102850000000000000000000000000000000000078 +:10286000000000000000000000000000F000220155 +:1028700054013C00050000000000000000000000C2 +:102880000000000000000000000000000000000048 +:102890000000000000000000000000000000000038 +:1028A0000000000000000000000000000000000028 +:1028B0000000000000000000000000000000000018 +:1028C0000000000000000000000000000000000008 +:1028D00000000000000000000000000000000000F8 +:1028E00000000000000000000000000000000000E8 +:1028F00000000000000000000000000000000000D8 +:1029000000000000000000000000000000000000C7 +:1029100000000000000000000000000000000000B7 +:1029200000000000000000000000000000000000A7 +:102930000000000000000000000000000000000097 +:102940000000000000000000000000000000000087 +:102950000000000000000000000000000000000077 +:102960000000000000000000000000000000000067 +:102970000000000000000000000000000000000057 +:102980000000000000000000000000000000000047 +:102990000000000000000000000000000000000037 +:1029A0000000000000000000000000000000000027 +:1029B0000000000000000000000000000000000017 +:1029C0000000000000000000000000000000000007 +:1029D00000000000000000000000000000000000F7 +:1029E00000000000000000000000000000000000E7 +:1029F00000000000000000000000000000000000D7 +:102A00001901010000000000000000003202100067 +:102A100001034F590000000000000000000000000A +:102A200099020000BC020000DF0200000203000067 +:102A300025030000480300006B0300008E03000024 +:102A4000B1030000D4030000F70300001A040000E3 +:102A50003D0400006004000083040000A6040000A0 +:102A6000C904000020030000D4B804020351180771 +:102A7000C8388E232310080344611C08000000009E +:102A800000000000190000005B555555555555557F +:102A90005555555505000000080A000000000000CB +:102AA000010000000000000002F80000EC045406E1 +:102AB00084067E07410AA2076A099109B1097E17B7 +:102AC00007B8C30700800000208300000080328028 +:102AD000648096802DB4040F110C0F0F10000F139B +:102AE000A5BA830A18C80F0015101510104310431B +:102AF00020030000D4A8040C42330E0EC4338E23EE +:102B000063011911E32101132302000000000000FA +:102B10001B0000005B555555555555555555555598 +:102B20005505000098090B0BB0B00000B0B0001BB9 +:102B30000B00000082F01002EC04540684067E07AD +:102B4000410AA2076A099109B1097E1707B8C307AC +:102B50000080000020830000008032806480968026 +:102B60002DB4040F110C0F0F10000F13A5BA830A18 +:102B700018C80F0015101510104310432003000053 +:102B8000090000000000000000000000000000003C +:102B90000000000000000000000000000100000034 +:102BA0000300000000000000000000000000000022 +:102BB0000200000000000000000000000000000013 +:102BC00000000000EC04540684067E07410AA207B8 +:102BD0006A099109B1097E1707B8C3070080000090 +:102BE0002083000000803280648096802DB4040F22 +:102BF000110C0F0F10000F13A5BA830A18C80F008D +:102C0000151015101043104320030000D4B804021F +:102C100003511807C8388E232310080344611C0889 +:102C20000000000000000000190000005B55555531 +:102C3000555555555555555555000000086A666659 +:102C400066666666636666666600000002F80000F7 +:102C5000EC04540684067E07410AA2076A0991091A +:102C6000B1097E1707B8C307008000002083000069 +:102C700000803280648096802DB4040F110C0F0FF9 +:102C800010000F13A5BA830A18C80F0015101510ED +:102C90001043104320030000D4A8040C42330E0E4E +:102CA000C4338E2363011911E321011323020000B1 +:102CB000000000001B0000005B555555555555554B +:102CC000555555555505000098696B6BB6B6666647 +:102CD000B6B6663B6B06000082F01002EC045406A8 +:102CE00084067E07410AA2076A099109B1097E1785 +:102CF00007B8C307008000002083000000803280F6 +:102D0000648096802DB4040F110C0F0F10000F1368 +:102D1000A5BA830A18C80F001510151010431043E8 +:102D200020030000D4B854161796010000000000DC +:102D30000000000000000000000000000000000093 +:102D4000080000005B555555000000000000000021 +:102D500000000000081A111100000000000000002F +:102D60000000000002000000EC04540684067E0708 +:102D7000410AA2076A099109B1097E1707B8C3077A +:102D800000800000208300000080328064809680F4 +:102D90002DB4040F110C0F0F10000F13A5BA830AE6 +:102DA00018C80F0015101510104310432003000021 +:102DB000D4B854161796010000000000000000006F +:102DC00000000000000000000000000008000000FB +:102DD0005B55555500000000000000000000000099 +:102DE000083A33330000000000000000000000003B +:102DF00002000000EC04540684067E07410AA20784 +:102E00006A099109B1097E1707B8C307008000005D +:102E10002083000000803280648096802DB4040FEF +:102E2000110C0F0F10000F13A5BA830A18C80F005A +:102E3000151015101043104320030000D4A8540CA3 +:102E4000567339184F068D11A3344E000000000050 +:102E50000000000000000000130000005B55555505 +:102E600055555555550500000000000008191B1B5D +:102E70001B1B0B0B0B0B00000000000002A002004C +:102E8000EC04540684067E07410AA2076A099109E8 +:102E9000B1097E1707B8C307008000002083000037 +:102EA00000803280648096802DB4040F110C0F0FC7 +:102EB00010000F13A5BA830A18C80F0015101510BB +:102EC0001043104320030000D4A8540C5673391843 +:102ED0004F068D11A3344E000000000000000000DA +:102EE00000000000130000005B5555555555555521 +:102EF000550500000000000008393B3B3B3B0B0B35 +:102F00000B0B00000000000002A00200EC045406BD +:102F100084067E07410AA2076A099109B1097E1752 +:102F200007B8C307008000002083000000803280C3 +:102F3000648096802DB4040F110C0F0F10000F1336 +:102F4000A5BA830A18C80F001510151010431043B6 +:102F500020030000D4A8051B023774045E311A2335 +:102F6000C7088C08000000000000000000000000FE +:102F7000140000005B5555555555555555550000E5 +:102F800000000000080909090909000010000000FC +:102F90000000000002500500EC04540684067E0781 +:102FA000410AA2076A099109B1097E1707B8C30748 +:102FB00000800000208300000080328064809680C2 +:102FC0002DB4040F110C0F0F10000F13A5BA830AB4 +:102FD00018C80F00151015101043104320030000EF +:102FE000D4A8051B023774045E311A23C7088C0865 +:102FF00000000000000000000000000014000000BD +:103000005B55555555555555555500000000000068 +:10301000086969696969606030600000000000004B +:1030200002500500EC04540684067E07410AA207FC +:103030006A099109B1097E1707B8C307008000002B +:103040002083000000803280648096802DB4040FBD +:10305000110C0F0F10000F13A5BA830A18C80F0028 +:10306000151015101043104320030000D4A8551B61 +:10307000167775185E0600000000000000000000D2 +:1030800000000000000000000C0000005B555555DA +:103090005555000000000000000000000819191933 +:1030A00019190000000000000000000002000000EC +:1030B000EC04540684067E07410AA2076A099109B6 +:1030C000B1097E1707B8C307008000002083000005 +:1030D00000803280648096802DB4040F110C0F0F95 +:1030E00010000F13A5BA830A18C80F001510151089 +:1030F0001043104320030000D4A8551B1677751801 +:103100005E0600000000000000000000000000005B +:10311000000000000C0000005B555555555500009F +:10312000000000000000000008393939393900007A +:10313000000000000000000002000000EC04540643 +:1031400084067E07410AA2076A099109B1097E1720 +:1031500007B8C30700800000208300000080328091 +:10316000648096802DB4040F110C0F0F10000F1304 +:10317000A5BA830A18C80F00151015101043104384 +:1031800020030000813010050670200000000000C0 +:10319000000000000000000000000000000000002F +:1031A00009000000555555550500000000000000BD +:1031B000000000000000000100000000000000000E +:1031C0000000000000000000EC04540684067E07A6 +:1031D000410AA2076A099109B1097E1707B8C30716 +:1031E0000080000020830000008032806480968090 +:1031F0002DB4040F110C0F0F10000F13A5BA830A82 +:1032000018C80F00151015101043104320030000BC +:10321000D4B8000000000000000000000000000022 +:10322000000000000000000000000000030000009B +:103230005B0500000000000000000000000000002E +:10324000080A00000000000000000000000000006C +:1032500002000000EC04540684067E07410AA2071F +:103260006A099109B1097E1707B8C30700800000F9 +:103270002083000000803280648096802DB4040F8B +:10328000110C0F0F10000F13A5BA830A18C80F00F6 +:1032900015101510104310432003000054726119DB +:1032A0001A00000000000000000000000000000004 +:1032B000000000000000000002000000465555001C +:1032C00000000000000000000000000028999900A4 +:1032D00000000000000000000000000000000000EE +:1032E000EC04540684067E07410AA2076A09910984 +:1032F000B1097E1707B8C3070080000020830000D3 +:1033000000803280648096802DB4040F110C0F0F62 +:1033100010000F13A5BA830A18C80F001510151056 +:1033200010431043200300008C7561191A0000003F +:10333000000000000000000000000000000000008D +:10334000000000000100000054555500000000007E +:1033500000000000000000009B99990000000000A0 +:10336000000000000000000000000000EC04540613 +:1033700084067E07410AA2076A099109B1097E17EE +:1033800007B8C3070080000020830000008032805F +:10339000648096802DB4040F110C0F0F10000F13D2 +:1033A000A5BA830A18C80F00151015101043104352 +:1033B0000000000000000001000003000000FC000D +:1033C000000000000D000D0040065906000000003E +:1033D0000155B400020000000000000001010302DA +:1033E000000001000000FC00000000000D000D00C6 +:1033F00000000F000000000004B0B3000000001047 +:103400000000000002020302000001000000FC00B6 +:10341000000000000D000D0001000E000000000083 +:1034200004C4B30000000010000000000303030206 +:10343000000001000000FC00000000000D000D0075 +:1034400002000D000000000004D8B30000000010CE +:103450000000000004040302000001000000FC0062 +:10346000000000000D000D0003000C000000000033 +:1034700004ECB3000000001000000000050503028A +:10348000000001000000FC00000000000D000D0025 +:1034900004000B00000000000400B4000000001055 +:1034A0000000000006060302000001000000FC000E +:1034B000000000000D000D0005000A0000000000E3 +:1034C0000414B4000000001000000000070703020D +:1034D000000001000000FC00000000000D000D00D5 +:1034E00006000900000000000428B40000000010DD +:1034F0000000000008080302000005000000FC00B6 +:10350000000000000D000D00070008000000000092 +:10351000043CB4000000001000000000090000019D +:10352000000007000000FC00000000000D000D007E +:10353000A00FB90F000000000150B400000000000F +:103540000000000000000001000003000000FC007B +:10355000000000000D000D00C116A81600000000BC +:1035600001A0B400060000000000000000001717D2 +:10357000000003000000FC00000000000D000D0032 +:103580003818391800000000019BB4000400000046 +:103590000000000000001616000003000000FD00FF +:1035A000000000000D000D00681070100000FA25EA +:1035B0000473B400040000000000000000001717AE +:1035C000000003000000FC00000000000D000D00E2 +:1035D000F811F9110000FA250487B4000400000076 +:1035E0000000000000001616000003000000FD00AF +:1035F000000000000D000D00681070100000FA259A +:103600000473B4000400000000000000000017175D +:10361000000003000000FC00000000000D000D0091 +:10362000F811F9110000FA250487B4000400000025 +:103630000000000000001616000003000000FD005E +:10364000000000000D000D00681070100000FA2549 +:103650000473B4000400000000000000000017170D +:10366000000003000000FC00000000000D000D0041 +:10367000F811F9110000FA250487B40004000000D5 +:103680000000000000001616000003000000FD000E +:10369000000000000D000D00681070100000FA25F9 +:1036A0000473B400040000000000000000001717BD +:1036B000000003000000FC00000000000D000D00F1 +:1036C000F811F9110000FA250487B4000400000085 +:1036D00000000000000A1414002802000000FC0092 +:1036E00000000000050005000000000000000000D0 +:1036F000010097030000000000000000000001002E +:10370000002802000000FC00000000000D000D0079 +:103710000000190000000000015AB400020000007F +:103720000000000000000100002802000000FC0072 +:10373000000000000D000D009001A9010000000034 +:10374000015FB40002000000000000000000010062 +:10375000002802000000FC00000000000D000D0029 +:1037600020033903000000000164B40002000000DF +:103770000000000000000100002802000000FC0022 +:10378000000000000D000D00B004C904000000009E +:103790000169B40002000000000000000000010008 +:1037A000002802000000FC00000000000D000D00D9 +:1037B0004006590600000000016EB400020000003F +:1037C0000000000000000100002802000000FC00D2 +:1037D000000000000D000D006810811000000000C6 +:1037E00001A5B40006000000000000000000010078 +:1037F000002802000000FC00000000000D000D0089 +:10380000F81111120000000001AAB4000600000027 +:103810000000000000000100002802000000FC0081 +:10382000000000000D000D008813A113000000002F +:1038300001AFB4000600000000000000000001001D +:10384000002802000000FC00000000000D000D0038 +:10385000181531150000000001B4B4000600000086 +:103860000000000000000100002802000000FC0031 +:10387000000000000D000D00A816C1160000000099 +:1038800001B9B400060000000000000000000100C3 +:10389000002802000000FC000000000009000900F0 +:1038A0000000000000000000010097030600000077 +:1038B00000000000000B1414002802000000FC00AF +:1038C000000000000C000C000000000000000000E0 +:1038D000010097030000000000000000000B14141A +:1038E000002802000000FC003F0000000C000C005B +:1038F000000000000000000001009703000000002D +:1039000000000000000B1515002802000000CC008C +:10391000000000000C000C0000000000000000008F +:1039200001009703000000000000000000000100FB +:10393000002802000000FC00000000000D000D0047 +:1039400000000000000000000100970306000000D6 +:103950004F00000001F4040068931B0060000000A9 +:103960000C000000010004001428000060000000AA +:10397000300000002D008400142800001C0000000E +:10398000730000002DF4840068931B001C000000ED +:10399000700000002DF4840068931B001C000000E0 +:1039A0007300000023F4840068931B001C000000D7 +:1039B000600000002DF4840068931B001C000000D0 +:1039C0004F00000001F4040068931B00E0000100B8 +:1039D0000C0000000100040014280000E0000100B9 +:1039E000300000002D008400142800001C0000009E +:1039F000700000002DF4840068931B001C00000080 +:103A0000730000002DF4840051651B001C000000B1 +:103A1000010128010101010101010101010101016F +:103A20000101010101010101010101010101010186 +:103A30000101010101010101010101010101010176 +:103A40000101010101010101010101010101010166 +:103A50000101010101010101010101010101010156 +:103A60000101010101010101010101010101010146 +:103A70000101010133323C333533353534333534CC +:103A800033333335353434343434323433343433FB +:103A900033333433353333343334333334343434ED +:103AA00033343335353234343233323232333233E5 +:103AB00032323232323132323233323232323232E6 +:103AC00033323132313133323232333233313332D5 +:103AD000323332342F2F303033323C3335333535B7 +:103AE0003433353433333335353434343434333498 +:103AF000333434333333343335333334333433338F +:103B0000343434343334333535323434323333327D +:103B10003233323332323232323232323233323282 +:103B20003232323233323132313133323232333275 +:103B300033313332323332342F2E302F333233336A +:103B40003333333434333534333333353534343439 +:103B5000343433343334343333333433353333342C +:103B6000333433333334343433343335353234331C +:103B70003233323232333233323232323231323223 +:103B80003133323232323232323231323131333217 +:103B90003232333232313232323232332F2E302F10 +:103BA00033323333333333343433353433333335DF +:103BB00035343434343433343334343333333433CA +:103BC00035333334333433333334343433343335BB +:103BD00035323433323333323233323332323232BB +:103BE00032323232323332323232323232323132B5 +:103BF00031323332323233323331333232323233A2 +:103C00002F2E302F32323333333333343433353491 +:103C10003333333535343434343433343333343369 +:103C2000333334333533333433343333333434345C +:103C30003334333534323433323332323233323355 +:103C40003232313232313232313232323232323257 +:103C50003232313131313332323232323331323247 +:103C6000323232332F2E302F323233333333333438 +:103C70003433353433333335353434343434333406 +:103C800033333433333334333533333433343333FE +:103C900033343434333433353532343332333232EF +:103CA00032333233323231323231323232333232F3 +:103CB00032323232323231323131333232323232E6 +:103CC00033313232323232332F2E302F32323333DD +:103CD00033333334343335343333333535343434A8 +:103CE000343433343334343333333433343333349C +:103CF000333433333334343433343335343234338C +:103D00003233323232323233323231323231323293 +:103D10003132323232323232323231323131333286 +:103D20003132323232313232313232332F2E302F81 +:103D3000333233333333333434333534333333354D +:103D40003534343434343334333434333333343338 +:103D5000343333343334333333343434333433352A +:103D6000343234333233323232323233323231322D +:103D70003231323231323232323232323232313226 +:103D80003131333231323232323132323232323315 +:103D90002F2E302F4B4D5351514F4F514F4F534FAB +:103DA000534F4F51534F4E4D53514D4F4F4F534F14 +:103DB0004F4F4F4F514D4F51514F4F4F534F4F4F0B +:103DC00051534F53554F51514F4F4F4D4F514D4FF1 +:103DD0004F4D4D4D4D4D4F4D4F4F4F4F4F4F4D4F01 +:103DE000514D4D4D4D4F4D4D4F4B4F4D51494D4FF9 +:103DF0004F4F4B4F4B494B4B9224922492009200D1 +:103E000000000000B66DB66DB600B6000000000000 +:103E1000B66DB66D9601960100000000B66DB66DE8 +:103E2000B201B20100000000B62DB62DB601B601F8 +:103E300000000000B665B665B601B60100000000DE +:103E4000B66CB66CB601B60100000000966D966DBA +:103E5000B601B60100000000B26DB26DB601B60148 +:103E600000000000FF7FFF7FFF01FF010000000056 +:103E7000B66DB66DB601B601000000009224922422 +:103E800092009200000000000110000000000000FD +:103E900000000000FFFF3DDB38D4FC020200AA0056 +:103EA0006C768A940001060000000000DB0600002A +:103EB000040C000060056E40415639030100009A71 +:103EC000EC045661000000000000000010C40C501B +:103ED0000390BBBB80442278641164118A3989390C +:103EE00085E00FE06612641201100000000000007F +:103EF00000000000FFFF3DDB38D4FC020200AA00F6 +:103F00006C768A940001060000000000DB060000C9 +:103F1000040C000060056E40415639030100009A10 +:103F2000EC045661000000000000000010C40C10FA +:103F3000E39EBBBB80552278641164118A398939AC +:103F400085E00FE06612641201040000000000002A +:103F50000000000000000000000000020200AA00B3 +:103F60006C768A940001060000000000DB06000069 +:103F7000040C000020066E40418639030100009ABF +:103F8000AC058661000000000000000010C40C5069 +:103F90000390BBBB80442278641164118A3989394B +:103FA00085E00FE066126412C904020001020304F6 +:103FB000EAF7FAFD3001A880CF0304021E000003D7 +:103FC0006C768A940001060000000000DB06000009 +:103FD000014600002B1A0040006B39034100029A91 +:103FE00000006B616478792BCF8A00801C54119893 +:103FF0000080BBBB00572278641164118A3989396B +:1040000085F00FF066126412C9040200010101017B +:10401000EAF7FAFD3001A880CF0304020200000095 +:104020006C768A940001060000000000DB060000A8 +:10403000014600002B1A0040006B39034100029A30 +:1040400000006B619A7F0A0AFFFF00801C541198E0 +:104050000380BBBB80462278641164118A39893998 +:1040600085F00FF066126412C90402000202020217 +:10407000EAF7FAFD3001A880CF0304020200000035 +:104080006C768A940001060000000000DB06000048 +:10409000014600002B1A0040006B39034100029AD0 +:1040A00000006B616C7E0614FFFF00801C541198A9 +:1040B0000380BBBB80462278641164118A39893938 +:1040C00085F00FF066126412C904020003030303B3 +:1040D000EAF7FAFD3001A880CF03040202000000D5 +:1040E0006C768A940001060000000000DB060000E8 +:1040F000014600002B1A0040006B39034100029A70 +:1041000000006B61767CE11DFFFF00801C5411985C +:104110000380BBBB80462278641164118A398939D7 +:1041200085F00FF066126412C9040200040404044E +:10413000EAF7FAFD3001A880CF0304020200000074 +:104140006C768A940001060000000000DB06000087 +:10415000014600002B1A0040006B39034100029A0F +:1041600000006B61BC798D27FFFF00801C54119803 +:104170000380BBBB80462278641164118A39893977 +:1041800085F00FF0661264120104000400000000C4 +:10419000CCF57AFDED20BF8FCF03040202060000AC +:1041A0006C768A940001060000000000DB06000027 +:1041B00001060000093C0040006B39034100029AEF +:1041C00000006B616478792BCF8A00801CC41018C2 +:1041D0000380ABAA00C6227864116411803980394B +:1041E0000F000F00550D550DC904020006070A0BFC +:1041F000EAF7FAFD3001A880CF0304021E0600038F +:104200006C768A940001060000000000DB060000C6 +:10421000014600002B1A0040006B39034100029A4E +:1042200000006B616478792BCF8A00801C54119850 +:104230000080BBBB00572218641164118A39893988 +:1042400085F00FF066126412C90402000606060625 +:10425000EAF7FAFD3001A880CF030402020600004D +:104260006C768A940001060000000000DB06000066 +:10427000014600002B1A0040006B39034100029AEE +:1042800000006B616478792BCF8A00801C541198F0 +:104290000080BBBB00572218641164118A39893928 +:1042A00085F00FF066126412C904020006060A0ABD +:1042B00073EDFAFD5985A880CF0304020A060100B8 +:1042C0006C768A940043060100000000DB060000C3 +:1042D000014600002B1A0040006B39034100029A8E +:1042E00000006B619367CBB40000008012541198FA +:1042F0000080BBBB00562218641164118A398939C9 +:1043000085F00FF066126412C904020007070B0B58 +:1043100073EDFAFD5985A880CF0304020A06010057 +:104320006C768A940043060100000000DB06000062 +:10433000014600002B1A0040006B39034100029A2D +:1043400000006B6155737BC8000000801254119807 +:104350000080BBBB00562218641164118A39893968 +:1043600085F00FF066126412C904020009090C0CF2 +:1043700073EDFAFD5985A880CF0304020A060100F7 +:104380006C768A940043060100000000DB06000002 +:10439000014600002B1A0040006B39034100029ACD +:1043A00000006B61D9770ED3000000801254119881 +:1043B0000080BBBB00562218641164118A39893908 +:1043C00085F00FF066126412C90402000A0A06069C +:1043D00073EDFAFD5985A880CF0304020A06010097 +:1043E0006C768A940043060100000000DB060000A2 +:1043F000014600002B1A0040006B39034100029A6D +:1044000000006B61BD7977D80000008012541198CC +:104410000080BBBB00562218641164118A398939A7 +:1044200085F00FF066126412C90402000B0B070737 +:1044300073EDFAFD5985A880CF0304020A06010036 +:104440006C768A940043060100000000DB06000041 +:10445000014600002B1A0040006B39034100029A0C +:1044600000006B61757B34DE0000008012541198EF +:104470000080BBBB00562218641164118A39893947 +:1044800085F00FF066126412C90402000A0A0606DB +:1044900073EDFAFD5985A880CF0304020A060100D6 +:1044A0006C768A940043060100000000DB060000E1 +:1044B000014600002B1A0040006B39034100029AAC +:1044C00000006B61CB7C87E30000008012541198E0 +:1044D0000080BBBB00562218641164118A398939E7 +:1044E00085F00FF066126412C90402000B0B070777 +:1044F00073EDFAFD5985A880CF0304020A06010076 +:104500006C768A940043060100000000DB06000080 +:10451000014600002B1A0040006B39034100029A4B +:1045200000006B61F27D29E90000008012541198AF +:104530000080BBBB00562218641164118A39893986 +:1045400085F00FF066126412C90402000C0C090910 +:1045500073EDFAFD5985A880CF0304020A06010015 +:104560006C768A940043060100000000DB06000020 +:10457000014600002B1A0040006B39034100029AEB +:1045800000006B61D57EC2EE0000008012541198CD +:104590000080BBBB00562218641164118A39893926 +:1045A00085F00FF0661264120000000000000000A9 +:1045B00000101000000060CA00009B94100F000261 +:1045C0000000E92A0000EA17100F00050000C825C6 +:1045D00000001579100E00070000D3C100002AA8C2 +:1045E000100C00090000C15A00009C9A0004103011 +:1045F0000000BCA00000903800091033000083D0F8 +:104600000000D635000B10350000C9C200001A5951 +:10461000000C103600008CA100002C9F000D1037FC +:1046200000009851000044DC000E10380000BEEA83 +:104630000000A536000E103A000026620000DD9949 +:10464000000F103B000000008C0000007300000011 +:1046500073000000660000003F0000003F00000003 +:1046600033000000260000000000000000000000F1 +:10467000000000000000000000000000000000003A +:10468000000000000000000000000000000000002A +:10469000000000000000000000000000000000001A +:1046A000000000000000000000000000000000000A +:1046B00000000000000000000000000000000000FA +:1046C00000000000870700008579385793F930A172 +:1046D000B3D4CC2BCB0AF200000000000000000095 +:1046E00000000000000000000000000000000000CA +:1046F00000000000000000000000000000000000BA +:1047000080220022870700008579385793E4C2B9D8 +:1047100030AFCC2BC5A1B3000000000000000000AA +:104720000000000000000000000000000000000089 +:104730000000000000000000000000000000000079 +:1047400080220022870700008579385793E4C2BC95 +:10475000C2BCD7930D7930000000000000000000BB +:104760000000000000000000000000000000000049 +:104770000000000000000000000000000000000039 +:1047800080220022870700008579385793E4C2BF52 +:10479000930ACC2BC4F50D000000000000000000BF +:1047A0000000000000000000000000000000000009 +:1047B00000000000000000000000000000000000F9 +:1047C00080220022870700008579385793E4C2BF12 +:1047D000930AE4C2B286CF0000000000000000008F +:1047E00000000000000000000000000000000000C9 +:1047F00000000000000000000000000000000000B9 +:1048000080220022870700008579385793E4C2BFD1 +:10481000930AB0AF26CF5000000000000000000057 +:104820000000000000000000000000000000000088 +:104830000000000000000000000000000000000078 +:1048400080220022870700008579385793E4C2BB95 +:104850000AF2E4C2BE4C2B00000000000000000081 +:104860000000000000000000000000000000000048 +:104870000000000000000000000000000000000038 +:1048800080220022870700008579385793E4C2BB55 +:104890000AF2B0AF295E4C000000000000000000EA +:1048A0000000000000000000000000000000000008 +:1048B00000000000000000000000000000000000F8 +:1048C00080220022C8060000450EA63D450EA63DEA +:1048D000BAF15942450EA63D450EA63D450EA63DF0 +:1048E000450EA63D00000000000000000000000092 +:1048F00000000000000000000000000000000000B8 +:104900008022002231302F2E2D2C2B2A29282726D9 +:104910002524232221201F1E1D1C1B1A19181716BF +:104920001514131211100F0E0D0C0B0A09080706AF +:104930000504030201000000000000000000000068 +:104940000000000000000000000000004A49484745 +:10495000464544434241403F3E3D3C3B3A3938376F +:10496000363534333231302F2E2D2C2B2A2928275F +:10497000262524232221201F1E1D1C1B1A1900007E +:104980000000000000000000000000000000000027 +:10499000000000002000E0C0A08060402000E0C0D7 +:1049A000A08060402000E0C0A08060402000E0C007 +:1049B000A08060402000E0C0A08060402000E0C0F7 +:1049C000A08060402000000076DBB62D2449921BB9 +:1049D000DBB6491292942409090000002000E0C0CF +:1049E000A08060402000E0C0A08060402000E0C0C7 +:1049F000A08060402000E0C0A08060402000E0C0B7 +:104A0000A08060402000E0C0A08060402000000046 +:104A100076DBB62D2449921BDBB649129294240909 +:104A2000090000002021E0E1A0A160612021E0E177 +:104A3000A0A160612021E0E1A0A160612021E0E16E +:104A4000A0A160612021E0E1A0A160612021E0E15E +:104A5000A0A160612021000076DBB62D2449921BC5 +:104A6000DBB6491292942409090000000100C1C07C +:104A7000818041400100C1C0818041400100C1C02E +:104A8000818041400100C1C0818041400100C1C01E +:104A9000818041400100C1C081804140010000008F +:104AA00076DBB62D2449921BDBB649129294240979 +:104AB000090000002120E1E0A1A061602120E1E0E7 +:104AC000A1A061602120E1E0A1A061602120E1E0DE +:104AD000A1A061602120E1E0A1A061602120E1E0CE +:104AE000A1A061602120000076DBB62D2449921B35 +:104AF000DBB64912929424090900000063432303A2 +:104B0000E2C2A28262422202E2C2A2826242220285 +:104B1000E2C2A28262422202E2C2A2826242220275 +:104B2000E2C2A28262422202E2C2A2826242000089 +:104B300000D0B62D2D499224DBB66D1292242509A2 +:104B4000490200002C0CECCCAC8C6C4C2C0CECCC4A +:104B5000AC8C6C4C2C0CECCCAC8C6C4C2C0CECCC95 +:104B6000AC8C6C4C2C0CECCCAC8C6C4C2C0CEBCB87 +:104B7000AB8B6B4B2B0B00002D499224DBB66D12D7 +:104B8000922425094902000040DBB62DA484644428 +:104B90002404E3C3A38363432303E3C3A3836343E3 +:104BA0002303E3C3A38363432303E3C3A3836343D5 +:104BB0002303E3C3A38363432303E3C3A38300006B +:104BC0000000B42D6D4B9224E4B66D1B922449096C +:104BD00049920000EBCBAB8B6B4B2B0BEBCBAB8B36 +:104BE0006B4B2B0BEBCBAB8B6B4B2B0BEBCBAB8B15 +:104BF0006B4B2B0BEBCBAB8B6B4B2B0BEACAAA8A09 +:104C00006A4A2A0AEACA00002449921BDBB6491202 +:104C100092942409090000006DDBB624E5C5A58542 +:104C200065452505E4C4A48464442404E4C4A48440 +:104C300064442404E4C4A48464442404E4C4A48434 +:104C400064442404E4C4A48464442404E4C400004C +:104C50000000002D6DDB922424B96D1B9B244912AA +:104C600049922400AA8A6A4A2A0AEACAAA8A6A4A8D +:104C70002A0AEACAAA8A6A4A2A0AEACAAA8A6A4A94 +:104C80002A0AEACAAA8A6A4A2A0AE9C9A98969498A +:104C90002909E9C9A989000024496E1BDB264912AC +:104CA000529224090000002D6DDB92242606E6C6F0 +:104CB000A68666462606E5C5A58565452505E5C59E +:104CC000A58565452505E5C5A58565452505E5C594 +:104CD000A58565452505E5C5A5856545250500002E +:104CE000090000006DDBB62424496E1BDB26491247 +:104CF0005292240969492909E9C9A98969492909F7 +:104D0000E9C9A98969492909E9C9A9896949290913 +:104D1000E9C9A98969492909E8C8A888684828080B +:104D2000E8C8A8886848000024B96D1B9B24491274 +:104D3000499224000000B42D6D4B92246747270749 +:104D4000E7C7A78767472707E6C6A68666462606FB +:104D5000E6C6A68666462606E6C6A68666462606F3 +:104D6000E6C6A68666462606E6C6A686664600000F +:104D70004902000040DBB62D2449921BDBB64912E4 +:104D8000929424092808E8C8A88868482808E8C830 +:104D9000A88868482808E8C8A88868482808E8C893 +:104DA000A88868482808FFFFFFFFFFFFFFFFFFFFFD +:104DB000FFFFFFFFFFFF0000E4B66D1B92244909CF +:104DC0004992000000F0FF3FFFFFFF3FFFFFFFFFA2 +:104DD000FFFFFFFFFFFFFFFFFFFFE7C7A787674753 +:104DE0002707E7C7A78767472707E7C7A787674753 +:104DF0002707E7C7A78767472707E7C7A7870000F1 +:104E0000FFFFFF3FFFDFB62D2D499224DBB66D1269 +:104E100092242509636261605F5E5D5C5B5A59584C +:104E200057565554535251504F4E4D4C4B4A49488A +:104E300047464544434241403F3E3D3C3B3A39387A +:104E40003736353433320000000000000000000027 +:104E500000000000000000000000000031302F2E94 +:104E60002D2C2B2A292827262524232221201F1EEA +:104E70001D1C1B1A191817161514131211100F0EDA +:104E80000D0C0B0A090807060504030201000000C7 +:104E90000000000000000000000000000000000012 +:104EA00000000000FFFFFFFFFFFFFFFFFFFFFFFF0E +:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:104ED000FFFFFFFFFFFF0000FFFFFF3FFFFFFF3F60 +:104EE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFFFF12 +:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:104F0000FFFFFFFFFFFFFFFFFFFF000000000000AB +:104F10000000000000000000000000000000000091 +:104F2000FFFFFF3FFFFFFF3FFFFFFF3F00000000CD +:104F30000000000057473727170756463626160643 +:104F4000554535251505544434241404534333235F +:104F500013035242322212025141312111015040B9 +:104F600030201000FFFF00000000000000000000E3 +:104F700000000000000000000000003F62605E5C76 +:104F80005A58565452504E4C4A48464442403E3C71 +:104F90003A38363432302E2C2A28262422201E1C61 +:104FA0001A18161412100E0C0A080604020000004B +:104FB00000000000000000000000000000000000F1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE00000000000000000000000000000000000C1 +:104FF00000000000000000000000000000000000B1 +:1050000000000000000000000000000000000000A0 +:105010000000000000000000000000000000000090 +:105020000000000000000000000000000000000080 +:105030000000000000000000000000000000000070 +:105040000000000000000000000000000000000060 +:105050000000000000000000000000000000000050 +:105060000000000000000000000000000000000040 +:105070000000000000000000000000000000000030 +:105080000000000000000000000000000000000020 +:105090000000000000000000000000000000000010 +:1050A0000000000000000000000000000000000000 +:1050B00000000000000000000000000000000000F0 +:1050C00000000000000000000000000000000000E0 +:1050D00000000000000000000000000000000000D0 +:1050E00000000000000000000000000000000000C0 +:1050F00000000000000000000000000000000000B0 +:10510000000000000000000000000000000000009F +:10511000000000000000000000000000000000008F +:10512000000000000000000000000000000000007F +:10513000000000000000000000000000000000006F +:10514000000000000000000000000000000000005F +:10515000000000000000000000000000000000004F +:10516000000000000000000000000000000000003F +:10517000000000000000000000000000000000002F +:10518000000000000000000000000000000000001F +:10519000000000000000000000000000000000000F +:1051A00000000000000000000000000000000000FF +:1051B00000000000000000000000000000000000EF +:1051C00000000000000000000000000000000000DF +:1051D00000000000000000000000000000000000CF +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:105200000801010000000000000000003202100050 +:105210001B00000000000000000000000000000073 +:105220008C0C0000AF0C0000D20C0000F50C00004C +:10523000200300004110080344611C080000000026 +:10524000000000000000000000000000000000005E +:105250000A00000066666666560000000000000056 +:10526000000000000000000000000000000000003E +:105270000000000003000000180DD60D060E1F0EE2 +:10528000530F580E300F420F430F7E1707B8C30756 +:1052900000800000208300000080328064809680BF +:1052A0002DB4040F110C0F0F10000F13A5BA030A31 +:1052B00018C80F00151015101043104320030000EC +:1052C000CBB2300DCE0345120000000000000000FC +:1052D0000000000000000000000000000A000000C4 +:1052E00066666666560000000000000000000000D0 +:1052F00011111111111111111111000000000010F4 +:1053000003000000180DD60D060E1F0E530F580E89 +:10531000300F420F430F7E1707B80733008000009D +:105320002083000000803280648096802DB4040FBA +:10533000110C0F0F90000F13A5BA830A18C80F00A5 +:10534000151015101043104345097E1707B8C30701 +:105350000080008020F3000C00803280648096FE84 +:105360002DB4FFFF11FDFFFFD0FF0F13A5BA830A75 +:1053700018C80F00130F130F0F410F411F03000038 +:105380000900000000000000000000000000000014 +:10539000188DD68D068E1F8E538F588E308F428F6C +:1053A000438F0000000000C000000000000000006B +:1053B00002000000000000000000000000000000EB +:1053C00000E60000EC0454E7E4077EE75509A20775 +:1053D0000A09250945097E1707B8C30700800000A0 +:1053E0002083000000803280648096802DB4048F7A +:1053F00011FDFFFFD0FF0F93A5BA830A18E80FE055 +:10540000130F13FF0F410F411F030000D4B8040214 +:105410000351188748F00C0C85011C08188DD68D97 +:10542000068E1F8E538F588E308F428F438F555567 +:10543000555555D55555000000000018086A666698 +:1054400066666666366600270000000002E6008099 +:10545000EC0C54EFE4877EE75509A2070AE925E939 +:105460000000000000000100002802000000FC0015 +:10547000000000000D000D0059064006000000006D +:105480000155970102000000000000000001020227 +:10549000002800008002FC00FFFFFF010D000D004E +:1054A00007000F000000000004B0B300000000106F +:1054B0000000000000020202002800008002FC0040 +:1054C000FFFFFF010D000D0006000E0000000000B0 +:1054D00004C4B3000000001000000000000302023A +:1054E000002800008002FC00FFFFFF010D000D00FE +:1054F00005000D000000000004D8B30000000010FB +:105500000000000000040202002800008002FC00ED +:10551000FFFFFF010D000D0004000C000000000063 +:1055200004ECB300000000100000000000050202BF +:10553000002800008002FC00FFFFFF010D000D00AD +:1055400003000B00000000000400B4000000001085 +:105550000000000000060202002800008002FC009B +:10556000FFFFFF010D000D0002000A000000000017 +:105570000414B40000000010000000000007020244 +:10558000002800008002FC00FFFFFF010D000D005D +:1055900001000900000000000428B4000000001011 +:1055A0000000000000080202002804008002FC0045 +:1055B000FFFFFF010D000D000000080000000000CB +:1055C00020B0B30000000010000000000000000048 +:1055D000002806000000FC00000000000D000D0087 +:1055E000D20FA00F00000000015097010000000042 +:1055F0000000000000000000002802000000FC0085 +:10560000000000000D000D00C116A81600000000EB +:10561000018C97010600000000000000000B020250 +:10562000002800008000FC00000000000D000D00BC +:1056300007000F000000000004B0B30000000010DD +:1056400000000000000C0202002800008000FC00A6 +:10565000000000000D000D0006000E00000000001C +:1056600004C4B3000000001000000000000D02029E +:10567000002800008000FC00000000000D000D006C +:1056800005000D000000000004D8B3000000001069 +:1056900000000000000E0202002800008000FC0054 +:1056A000000000000D000D0004000C0000000000D0 +:1056B00004ECB3000000001000000000000F020224 +:1056C000002800008000FC00000000000D000D001C +:1056D00003000B00000000000400B40000000010F4 +:1056E0000000000000100202002800008000FC0002 +:1056F000000000000D000D0002000A000000000084 +:105700000414B400000000100000000000110202A8 +:10571000002800008000FC00000000000D000D00CB +:1057200001000900000000000428B400000000107F +:105730000000000000120202002804008000FC00AB +:10574000000000000D000D00000008000000000037 +:1057500020B0B300000000104F00000001F404006E +:1057600068931B00600000000C00000001000400B2 +:105770001428000060000000300000002D008400AC +:10578000142800001C000000730000002DF48400A9 +:1057900068931B001C000000700000002DF48400C2 +:1057A00068931B001C000000730000002DF48400AF +:1057B00068931B001C000000630000002DF48400AF +:1057C00068931B001C0000004F00000001F404005F +:1057D00068931B00E00001000C00000001000400C1 +:1057E00014280000E0000100300000002D008400BB +:1057F000142800001C000000700000002DF484003C +:1058000068931B001C000000000000000000000066 +:105810000000000000000000000000000000000088 +:105820000000000000000000000000000000000078 +:105830000000000000000000000000000000000068 +:105840000000000000000000000000000000000058 +:105850000000000000000000000000000000000048 +:105860000000000000000000000000000000000038 +:1058700000000000000000000000000092249224BC +:105880009200920000000000224924492401A40053 +:105890000000000014492449240114010000000004 +:1058A000A4482449240122010000000024452429A1 +:1058B000240124010000000024292445240124019E +:1058C000000000002449A448220124010000000037 +:1058D00024491449140124010000000024492249EC +:1058E000A400240100000000FF7FFF7FFF01FF01F3 +:1058F00000000000B66DB66DB601B60100000000F4 +:10590000B26DB66DB601B60000000000966DB66DC2 +:10591000B601960100000000B66CB66DB601B2018A +:1059200000000000B665B62DB601B601000000000B +:10593000B62DB665B601B60100000000B66DB66CB6 +:10594000B201B60100000000B66D966D9601B60179 +:1059500000000000B66DB26DB600B6010000000098 +:10596000012800000000000000000000000000000E +:10597000000000020206AA006C768A94000106006C +:1059800000000000DB0600000106000091016E40EF +:10599000418C39030100009A1D018C610000000058 +:1059A0000000000010100D100390BBBB8E5A22188F +:1059B000641164118A39893985E00FE06612641236 +:1059C00001200000000000000000000000000000B6 +:1059D000000000020206AA006C768A94000106000C +:1059E00000000000DB0600000106000091016E408F +:1059F000418C39030100009A1D018C6100000000F8 +:105A00000000000010000C100380ABAA8044227834 +:105A1000641164118A39893985E005E066126412DF +:105A20000104000000000000000000000000000071 +:105A3000000000020200AA006C768A9400010600B1 +:105A400000000000DB060000040C000038066E2099 +:105A5000418C390301000084C4058C610000000002 +:105A60000000000010C40C500390BBBB804422789F +:105A7000641164118A39893985E00FE06612641275 +:105A8000D004020001020304CCF57AFDED20BF8FA3 +:105A9000CF0304021E0600036C768A940001060000 +:105AA00000000000DB06000001460000121B002081 +:105AB000006B39034100028400006B616478792B2C +:105AC000CF8A00801C5411980080BBBB00572278FD +:105AD000641164118A39893985E00FE06612641215 +:105AE0000100000001010101CCF57AFDED20BF8F1E +:105AF000CF030402020600006C768A9400010600BF +:105B000000000000DB060000000C0000401A00202E +:105B10004100380341000284000000606478792B62 +:105B2000CF8A00801C5410180380BBBB80462278AB +:105B3000641164118A39893985E00FE066126412B4 +:105B4000D004020002020202CCF57AFDED20BF8FE4 +:105B5000CF030402020600006C768A94000106005E +:105B600000000000DB06000001460000121B0020C0 +:105B7000006B39034100028400006B616478792B6B +:105B8000CF8A00801C5411980380BBBB80462278CA +:105B9000641164118A39893985E00FE06612641254 +:105BA0000100000003030303CCF57AFDED20BF8F55 +:105BB000CF030402020600006C768A9400010600FE +:105BC00000000000DB060000000C0000401A00206E +:105BD0004100380341000284000000606478792BA2 +:105BE000CF8A00801C5410180380BBBB80462278EB +:105BF000641164118A39893985E00FE066126412F4 +:105C0000D004020004040404CCF57AFDED20BF8F1B +:105C1000CF030402020600006C768A94000106009D +:105C200000000000DB06000001460000121B0020FF +:105C3000006B39034100028400006B616478792BAA +:105C4000CF8A00801C5411980380BBBB8046227809 +:105C5000641164118A39893985E00FE06612641293 +:105C60000100000000000000CCF57AFDED20BF8FA0 +:105C7000CF030402020600006C768A94000106003D +:105C800000000000DB060000000C0000FF3B0020CD +:105C90004100380341000284000000606478792BE1 +:105CA000CF8A00801CC410180300000000C62278B0 +:105CB000641164118039803905000F0055105510AA +:105CC000000000000000000000101000000092CD55 +:105CD0000000C180100F0002000087370000BBF1F8 +:105CE000100F00040000904100008B43100E0007CD +:105CF0000000BBF100009167100C000900001DFBC3 +:105D00000000709E100E000500000000C806000094 +:105D1000BAF15942BAF15942450EA63D1122334417 +:105D20005566778899AABBCCDDEEFF6900000000BC +:105D30000000000000000000000000000000000063 +:105D40000000000000000000C022C0224A4948476D +:105D5000464544434241403F3E3D3C3B3A3938375B +:105D6000363534333231302F2E2D2C2B2A2928274B +:105D7000262524232221201F1E1D1C1B1A1900006A +:105D80000000000000000000000000000000000013 +:105D90000000000031302F2E2D2C2B2A29282726F9 +:105DA0002524232221201F1E1D1C1B1A191817161B +:105DB0001514131211100F0E0D0C0B0A090807060B +:105DC00005040302010000000000000000000000C4 +:105DD0000000000000000000000000002000E0C003 +:105DE000A08060402000E0C0A08060402000E0C0B3 +:105DF000A08060402000E0C0A08060402000E0C0A3 +:105E0000A08060402000E0C0A08060402000000032 +:105E100076DBB62D2449921BDBB6491292942409F5 +:105E200009000000826446280AECCEB0927456380D +:105E30001AFCDEC0A28466482A0CEED0B2947658D2 +:105E40003A1CFEE0C2A486684A2C0EF0D2B49678C2 +:105E50005A3C1E00FFFF00006D5B922424B76D1BAF +:105E60009B244912499224010000003F533517F941 +:105E7000DBBD9F8163452709EBCDAF917355371982 +:105E8000FBDDBFA1836547290BEDCFB19375573972 +:105E90001BFDDFC1A38567492B0D8E7052340000B6 +:105EA0006D499224E4B66D1B9224490A499204007C +:105EB0000000B42D2002836547290BEDCFB1937507 +:105EC00057391BFDDFC1A38567492B0DEFD1B39572 +:105ED00077593B1DFFE1C3A587694B2D0FF1D3B562 +:105EE00097795B3D1F01000040DB962424C96D1BA0 +:105EF000DB264912529224090100000016F8DABC90 +:105F00009E8062442608EACCAE9072543618FADCC1 +:105F1000BEA0826446280AECCEB0927456381AFCB1 +:105F2000DEC0A28466482A0C8D6F513315F700003D +:105F300025499224DBB66D129224290949120000EA +:105F400000D0B6255D3F21038466482A0CEED0B20E +:105F50009476583A1CFEE0C2A486684A2C0EF0D211 +:105F6000B496785A3C1E00E2C4A6886A4C2E10F201 +:105F7000D4B6987A5C3E000000D0B6252449721B46 +:105F8000DBB6491292A4240949000000D9BB9D7FC9 +:105F900061432507E9CBAD8F71533517F9DBBD9F01 +:105FA0008163452709EBCDAF9173553719FBDDBFF1 +:105FB000A1836547290B8C6E503214F6D8BA0000C5 +:105FC0002449921BDBB6491292A42409490000001F +:105FD00040DB96249A7C5E4022048567492B0DEFB6 +:105FE000D1B39577593B1DFFE1C3A587694B2D0FB1 +:105FF000F1D3B597795B3D1F01E3C5A7896B4D2FA1 +:1060000011F3D5B7997B00000000B42D2549921CEF +:10601000DBB66D1292242909491200009C7E604271 +:106020002406E8CAAC8E70523416F8DABC9E806240 +:10603000442608EACCAE9072543618FADCBEA08230 +:106040006446280A8B6D4F3113F5D7B99B7D00004C +:1060500024496E1BDB26491292922409010000009C +:106060006D5B9224D7B99B7D5F41230586684A2CDE +:106070000EF0D2B496785A3C1E00E2C4A6886A4C50 +:106080002E10F2D4B6987A5C3E2002E4C6A88A6C40 +:106090004E3012F4D6B800000000002D6D49922455 +:1060A000E4B66D1B9224490A499204005F4123051E +:1060B000E7C9AB8D6F513315F7D9BB9D7F61432580 +:1060C00007E9CBAD8F71533517F9DBBD9F81634570 +:1060D00027098A6C4E3012F4D6B89A7C5E400000D4 +:1060E00024B96D1B9B2449124A9224010000002D03 +:1060F0006D49922414F6D8BA9C7E604224068769C2 +:106100004B2D0FF1D3B597795B3D1F01E3C5A789EF +:106110006B4D2F11F3D5B7997B5D3F2103E5C7A9DF +:106120008B6D4F3113F50000010000006D5B922470 +:1061300024B96D1B9B2449124A9224012204E6C80B +:10614000AA8C6E503214F6D8BA9C7E60422406E8BF +:10615000CAAC8E70523416F8DABC9E8062442608AF +:10616000FFFFFFFFFFFFFFFFFFFFFFFF2103000017 +:10617000E4B66D1B9224490A499204000000FC3FDA +:10618000FFFFFF24513315F7D9BB9D7F61432507DE +:10619000886A4C2E10F2D4B6987A5C3E2002E4C68F +:1061A000A88A6C4E3012F4D6B89A7C5E402204E67F +:1061B000C8AA8C6E503200004900000040DB9624D3 +:1061C00024496E1BDB26491292922409E5C7A98B4C +:1061D0006D4F3113F5D7B99B7D5F412305E7C9ABFF +:1061E0008D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:1061F000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000AD +:10620000DBB66D1292242909C9FFFF3FFFFFFF3F54 +:10621000FFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFF4E +:10622000FFFF896B4D2F11F3D5B7997B5D3FFFFFC2 +:10623000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:10624000FFFFFFFFFFFF0000FFFFFF3FFFDFB6255F +:106250002449FE3FFFFFFF3FFFFFFF3F5F5E5D5CA6 +:106260005B5A595857565554535251504F4E4D4CF6 +:106270004B4A494847464544434241403F3E3D3CE6 +:106280003B3A39383736353433323130FFFF00008E +:1062900000000000000000000000000000000000FE +:1062A0000000003F2F2E2D2C2B2A292827262524BD +:1062B000232221201F1E1D1C1B1A19181716151426 +:1062C000131211100F0E0D0C0B0A09080706050416 +:1062D00003020100FFFF00000000000000000000BA +:1062E00000000000000000000000003F000000006F +:1062F000000000000000000000000000000000009E +:10630000000000000000000000000000000000008D +:10631000000000000000000000000000000000007D +:10632000000000000000000000000000000000006D +:10633000000000000000000000000000000000005D +:10634000000000000000000000000000000000004D +:10635000000000000000000000000000000000003D +:10636000000000000000000000000000000000002D +:10637000000000000000000000000000000000001D +:10638000000000000000000000000000000000000D +:1063900000000000000000000000000000000000FD +:1063A00000000000000000000000000000000000ED +:1063B00000000000000000000000000000000000DD +:1063C00000000000000000000000000000000000CD +:1063D00000000000000000000000000000000000BD +:1063E00000000000000000000000000000000000AD +:1063F000000000000000000000000000000000009D +:10640000000000000000000000000000000000008C +:10641000000000000000000000000000000000007C +:10642000000000000000000000000000000000006C +:10643000000000000000000000000000000000005C +:10644000000000000000000000000000000000004C +:10645000000000000000000000000000000000003C +:10646000000000000000000000000000000000002C +:10647000000000000000000000000000000000001C +:10648000000000000000000000000000000000000C +:1064900000000000000000000000000000000000FC +:1064A00000000000000000000000000000000000EC +:1064B00000000000000000000000000000000000DC +:1064C00000000000000000000000000000000000CC +:1064D00000000000000000000000000000000000BC +:1064E00000000000000000000000000000000000AC +:1064F000000000000000000000000000000000009C +:10650000000000000000000000000000000000008B +:10651000000000000000000000000000000000007B +:10652000000000000000000000000000000000006B +:10653000000000000000000000000000000000005B +:10654000000000000000000000000000000000004B +:10655000000000000000000000000000000000003B +:10656000000000000000000000000000000000002B +:10657000000000000000000000000000000000001B +:10658000000000000000000000000000000000000B +:1065900000000000000000000000000000000000FB +:1065A00000000000000000000000000000000000EB +:1065B00000000000000000000000000000000000DB +:1065C00000000000000000000000000000000000CB +:1065D00000000000000000000000000000000000BB +:1065E00000000000000000000000000000000000AB +:1065F000000000000000000000000000000000009B +:10660000000000000000000000000000000000008A +:10661000000000000000000000000000000000007A +:10662000000000000000000000000000000000006A +:10663000000000000000000000000000000000005A +:10664000000000000000000000000000000000004A +:10665000000000000000000000000000000000003A +:10666000000000000000000000000000000000002A +:10667000000000000000000000000000000000001A +:10668000000000000000000000000000000000000A +:1066900000000000000000000000000000000000FA +:1066A00000000000000000000000000000000000EA +:1066B00000000000000000000000000000000000DA +:1066C00000000000000000000000000000000000CA +:1066D00000000000000000000000000000000000BA +:1066E00000000000000000000000000000000000AA +:1066F000000000000000000000000000000000009A +:106700000000000000000000000000000000000089 +:106710000000000000000000000000000000000079 +:106720000000000000000000000000000000000069 +:106730000000000000000000000000000000000059 +:106740000000000000000000000000000000000049 +:106750000000000000000000000000000000000039 +:106760000000000000000000000000000000000029 +:106770000000000000000000000000000000000019 +:106780000000000000000000000000000000000009 +:1067900000000000000000000000000000000000F9 +:1067A00000000000000000000000000000000000E9 +:1067B00000000000000000000000000000000000D9 +:1067C00000000000000000000000000000000000C9 +:1067D00000000000000000000000000000000000B9 +:1067E00000000000000000000000000000000000A9 +:1067F0000000000000000000000000000000000099 +:106800000000000000000000000000000000000088 +:106810000000000000000000000000000000000078 +:106820000000000000000000000000000000000068 +:106830000000000000000000000000000000000058 +:106840000000000000000000000000000000000048 +:106850000000000000000000000000000000000038 +:106860000000000000000000000000000000000028 +:106870000000000000000000000000000000000018 +:106880000000000000000000000000000000000008 +:1068900000000000000000000000000000000000F8 +:1068A00000000000000000000000000000000000E8 +:1068B00000000000000000000000000000000000D8 +:1068C00000000000000000000000000000000000C8 +:1068D00000000000000000000000000000000000B8 +:1068E00000000000000000000000000000000000A8 +:1068F0000000000000000000000000000000000098 +:106900000000000000000000000000000000000087 +:106910000000000000000000000000000000000077 +:106920000000000000000000000000000000000067 +:106930000000000000000000000000000000000057 +:106940000000000000000000000000000000000047 +:106950000000000000000000000000000000000037 +:106960000000000000000000000000000000000027 +:106970000000000000000000000000000000000017 +:106980000000000000000000000000000000000007 +:1069900000000000000000000000000000000000F7 +:1069A00000000000000000000000000000000000E7 +:1069B00000000000000000000000000000000000D7 +:1069C00000000000000000000000000000000000C7 +:1069D00000000000000000000000000000000000B7 +:1069E00000000000000000000000000000000000A7 +:1069F0000000000000000000000000000000000097 +:106A0000150101000000000000000000320210002B +:106A10001000000000000000000000000000000066 +:106A200099120000BC120000DF12000002130000E7 +:106A300025130000481300006B1300008E130000A4 +:106A4000B1130000D4130000F71300001A14000063 +:106A50003D1400006014000083140000A614000020 +:106A6000C914000020030000D4B804020351180721 +:106A7000C8388E232310080344611C08000000005E +:106A800000000000190000005B555555555555553F +:106A90005555555505000000080A0000000000008B +:106AA000010000000000000002F80000EC14541681 +:106AB00084167E17411AA2176A199119B1197E1707 +:106AC00007B8C307008000002083000000803280E8 +:106AD000648096802DB4040F110C0F0F10000F135B +:106AE000A5BA830A18C80F001510151010431043DB +:106AF00020030000D4A8040C42330E0EC4338E23AE +:106B000063011911E32101132302000000000000BA +:106B10001B0000005B555555555555555555555558 +:106B20005505000098090B0BB0B00000B0B0001B79 +:106B30000B00000082F01002EC14541684167E172D +:106B4000411AA2176A199119B1197E1707B8C3071C +:106B500000800000208300000080328064809680E6 +:106B60002DB4040F110C0F0F10000F13A5BA830AD8 +:106B700018C80F0015101510104310432003000013 +:106B800009000000000000000000000000000000FC +:106B900000000000000000000000000001000000F4 +:106BA00003000000000000000000000000000000E2 +:106BB00002000000000000000000000000000000D3 +:106BC00000000000EC14541684167E17411AA21718 +:106BD0006A199119B1197E1707B8C3070080000020 +:106BE0002083000000803280648096802DB4040FE2 +:106BF000110C0F0F10000F13A5BA830A18C80F004D +:106C0000151015101043104320030000D4B80402DF +:106C100003511807C8388E232310080344611C0849 +:106C20000000000000000000190000005B555555F1 +:106C3000555555555555555555000000086A666619 +:106C400066666666636666666600000002F80000B7 +:106C5000EC14541684167E17411AA2176A1991195A +:106C6000B1197E1707B8C307008000002083000019 +:106C700000803280648096802DB4040F110C0F0FB9 +:106C800010000F13A5BA830A18C80F0015101510AD +:106C90001043104320030000D4A8040C42330E0E0E +:106CA000C4338E2363011911E32101132302000071 +:106CB000000000001B0000005B555555555555550B +:106CC000555555555505000098696B6BB6B6666607 +:106CD000B6B6663B6B06000082F01002EC14541648 +:106CE00084167E17411AA2176A199119B1197E17D5 +:106CF00007B8C307008000002083000000803280B6 +:106D0000648096802DB4040F110C0F0F10000F1328 +:106D1000A5BA830A18C80F001510151010431043A8 +:106D200020030000D4B8541617960100000000009C +:106D30000000000000000000000000000000000053 +:106D4000080000005B5555550000000000000000E1 +:106D500000000000081A11110000000000000000EF +:106D60000000000002000000EC14541684167E1788 +:106D7000411AA2176A199119B1197E1707B8C307EA +:106D800000800000208300000080328064809680B4 +:106D90002DB4040F110C0F0F10000F13A5BA830AA6 +:106DA00018C80F00151015101043104320030000E1 +:106DB000D4B854161796010000000000000000002F +:106DC00000000000000000000000000008000000BB +:106DD0005B55555500000000000000000000000059 +:106DE000083A3333000000000000000000000000FB +:106DF00002000000EC14541684167E17411AA217E4 +:106E00006A199119B1197E1707B8C30700800000ED +:106E10002083000000803280648096802DB4040FAF +:106E2000110C0F0F10000F13A5BA830A18C80F001A +:106E3000151015101043104320030000D4A8540C63 +:106E4000567339184F068D11A3344E000000000010 +:106E50000000000000000000130000005B555555C5 +:106E600055555555550500000000000008191B1B1D +:106E70001B1B0B0B0B0B00000000000002A002000C +:106E8000EC14541684167E17411AA2176A19911928 +:106E9000B1197E1707B8C3070080000020830000E7 +:106EA00000803280648096802DB4040F110C0F0F87 +:106EB00010000F13A5BA830A18C80F00151015107B +:106EC0001043104320030000D4A8540C5673391803 +:106ED0004F068D11A3344E0000000000000000009A +:106EE00000000000130000005B55555555555555E1 +:106EF000550500000000000008393B3B3B3B0B0BF5 +:106F00000B0B00000000000002A00200EC1454165D +:106F100084167E17411AA2176A199119B1197E17A2 +:106F200007B8C30700800000208300000080328083 +:106F3000648096802DB4040F110C0F0F10000F13F6 +:106F4000A5BA830A18C80F00151015101043104376 +:106F500020030000D4A8051B023774045E311A23F5 +:106F6000C7088C08000000000000000000000000BE +:106F7000140000005B5555555555555555550000A5 +:106F800000000000080909090909000010000000BC +:106F90000000000002500500EC14541684167E1701 +:106FA000411AA2176A199119B1197E1707B8C307B8 +:106FB0000080000020830000008032806480968082 +:106FC0002DB4040F110C0F0F10000F13A5BA830A74 +:106FD00018C80F00151015101043104320030000AF +:106FE000D4A8051B023774045E311A23C7088C0825 +:106FF000000000000000000000000000140000007D +:107000005B55555555555555555500000000000028 +:10701000086969696969606030600000000000000B +:1070200002500500EC14541684167E17411AA2175C +:107030006A199119B1197E1707B8C30700800000BB +:107040002083000000803280648096802DB4040F7D +:10705000110C0F0F10000F13A5BA830A18C80F00E8 +:10706000151015101043104320030000D4A8551B21 +:10707000167775185E060000000000000000000092 +:1070800000000000000000000C0000005B5555559A +:1070900055550000000000000000000008191919F3 +:1070A00019190000000000000000000002000000AC +:1070B000EC14541684167E17411AA2176A199119F6 +:1070C000B1197E1707B8C3070080000020830000B5 +:1070D00000803280648096802DB4040F110C0F0F55 +:1070E00010000F13A5BA830A18C80F001510151049 +:1070F0001043104320030000D4A8551B16777518C1 +:107100005E0600000000000000000000000000001B +:10711000000000000C0000005B555555555500005F +:10712000000000000000000008393939393900003A +:10713000000000000000000002000000EC145416E3 +:1071400084167E17411AA2176A199119B1197E1770 +:1071500007B8C30700800000208300000080328051 +:10716000648096802DB4040F110C0F0F10000F13C4 +:10717000A5BA830A18C80F00151015101043104344 +:107180002003000081301005067020000000000080 +:1071900000000000000000000000000000000000EF +:1071A000090000005555555505000000000000007D +:1071B00000000000000000010000000000000000CE +:1071C0000000000000000000EC14541684167E1726 +:1071D000411AA2176A199119B1197E1707B8C30786 +:1071E0000080000020830000008032806480968050 +:1071F0002DB4040F110C0F0F10000F13A5BA830A42 +:1072000018C80F001510151010431043200300007C +:10721000D4B80000000000000000000000000000E2 +:10722000000000000000000000000000030000005B +:107230005B050000000000000000000000000000EE +:10724000080A00000000000000000000000000002C +:1072500002000000EC14541684167E17411AA2177F +:107260006A199119B1197E1707B8C3070080000089 +:107270002083000000803280648096802DB4040F4B +:10728000110C0F0F10000F13A5BA830A18C80F00B6 +:10729000151015101043104320030000547261199B +:1072A0001A000000000000000000000000000000C4 +:1072B00000000000000000000200000046555500DC +:1072C0000000000000000000000000002899990064 +:1072D00000000000000000000000000000000000AE +:1072E000EC14541684167E17411AA2176A199119C4 +:1072F000B1197E1707B8C307008000002083000083 +:1073000000803280648096802DB4040F110C0F0F22 +:1073100010000F13A5BA830A18C80F001510151016 +:1073200010431043200300008C7561191A000000FF +:10733000000000000000000000000000000000004D +:10734000000000000100000054555500000000003E +:1073500000000000000000009B9999000000000060 +:10736000000000000000000000000000EC145416B3 +:1073700084167E17411AA2176A199119B1197E173E +:1073800007B8C3070080000020830000008032801F +:10739000648096802DB4040F110C0F0F10000F1392 +:1073A000A5BA830A18C80F00151015101043104312 +:1073B0000000000000000001000003000000FC00CD +:1073C000000000000D000D0008072107000000006C +:1073D0000155B4000200000000000000010103029A +:1073E000000001000000FC00000000000D000D0086 +:1073F00010001F000000000004B0B30000000010E7 +:107400000000000002020302000001000000FC0076 +:10741000000000000D000D0011001E000000000023 +:1074200004C4B300000000100000000003030302C6 +:10743000000001000000FC00000000000D000D0035 +:1074400012001D000000000004D8B300000000106E +:107450000000000004040302000001000000FC0022 +:10746000000000000D000D0013001C0000000000D3 +:1074700004ECB3000000001000000000050503024A +:10748000000001000000FC00000000000D000D00E5 +:1074900014001B00000000000400B40000000010F5 +:1074A0000000000006060302000001000000FC00CE +:1074B000000000000D000D0015001A000000000083 +:1074C0000414B400000000100000000007070302CD +:1074D000000001000000FC00000000000D000D0095 +:1074E00016001900000000000428B400000000107D +:1074F0000000000008080302000005000000FC0076 +:10750000000000000D000D00170018000000000032 +:10751000043CB4000000001000000000090000015D +:10752000000007000000FC00000000000D000D003E +:1075300004101D10000000000150B4000000000005 +:107540000000000000000001000003000000FC003B +:10755000000000000D000D008917701700000000EA +:1075600001A0B40006000000000000000000171792 +:10757000000003000000FC00000000000D000D00F2 +:107580009C189D1800000000019BB400040000003E +:107590000000000000001616000003000000FD00BF +:1075A000000000000D000D00301138110000FE2514 +:1075B0000473B4000400000000000000000017176E +:1075C000000003000000FC00000000000D000D00A2 +:1075D000C012C1120000FE250487B40004000000A0 +:1075E0000000000000001616000003000000FD006F +:1075F000000000000D000D00301138110000FE25C4 +:107600000473B4000400000000000000000017171D +:10761000000003000000FC00000000000D000D0051 +:10762000C012C1120000FE250487B400040000004F +:107630000000000000001616000003000000FD001E +:10764000000000000D000D00301138110000FE2573 +:107650000473B400040000000000000000001717CD +:10766000000003000000FC00000000000D000D0001 +:10767000C012C1120000FE250487B40004000000FF +:107680000000000000001616000003000000FD00CE +:10769000000000000D000D00301138110000FE2523 +:1076A0000473B4000400000000000000000017177D +:1076B000000003000000FC00000000000D000D00B1 +:1076C000C012C1120000FE250487B40004000000AF +:1076D00000000000000A1414002802000000FC0052 +:1076E0000000000005000500000000000000000090 +:1076F00001009703000000000000000000000100EE +:10770000002802000000FC00000000000D000D0039 +:10771000C800E10000000000015AB40002000000AF +:107720000000000000000100002802000000FC0032 +:10773000000000000D000D00580271020000000062 +:10774000015FB40002000000000000000000010022 +:10775000002802000000FC00000000000D000D00E9 +:10776000E8030104000000000164B400020000000E +:107770000000000000000100002802000000FC00E2 +:10778000000000000D000D007805910500000000CC +:107790000169B400020000000000000000000100C8 +:1077A000002802000000FC00000000000D000D0099 +:1077B0000807210700000000016EB400020000006D +:1077C0000000000000000100002802000000FC0092 +:1077D000000000000D000D003011491100000000F4 +:1077E00001A5B40006000000000000000000010038 +:1077F000002802000000FC00000000000D000D0049 +:10780000C012D9120000000001AAB4000600000056 +:107810000000000000000100002802000000FC0041 +:10782000000000000D000D0050146914000000005D +:1078300001AFB400060000000000000000000100DD +:10784000002802000000FC00000000000D000D00F8 +:10785000E015F9150000000001B4B40006000000B6 +:107860000000000000000100002802000000FC00F1 +:10787000000000000D000D007017891700000000C7 +:1078800001B9B40006000000000000000000010083 +:10789000002802000000FC000000000009000900B0 +:1078A0000000000000000000010097030600000037 +:1078B00000000000000B1414002802000000FC006F +:1078C000000000000C000C000000000000000000A0 +:1078D000010097030000000000000000000B1414DA +:1078E000002802000000FC003F0000000C000C001B +:1078F00000000000000000000100970300000000ED +:1079000000000000000B1515002802000000CC004C +:10791000000000000C000C0000000000000000004F +:1079200001009703000000000000000000000100BB +:10793000002802000000FC00000000000D000D0007 +:107940000000000000000000010097030600000096 +:107950004F00000001F4040068931B006000000069 +:107960000C0000000100040014280000600000006A +:10797000300000002D008400142800001C000000CE +:10798000730000002DF4840068931B001C000000AD +:10799000700000002DF4840068931B001C000000A0 +:1079A0007300000023F4840068931B001C00000097 +:1079B000600000002DF4840068931B001C00000090 +:1079C0004F00000001F4040068931B00E000010078 +:1079D0000C0000000100040014280000E000010079 +:1079E000300000002D008400142800001C0000005E +:1079F000700000002DF4840068931B001C00000040 +:107A0000730000002DF4840051651B001C00000071 +:107A10000101010101010101010101010101010156 +:107A20000101010101010101010101010101010146 +:107A30000101010101010101010101010101010136 +:107A40000101010101010101010101010101010126 +:107A50000101010101010101010101010101010116 +:107A60000101010101010101010101010101010106 +:107A70000101010133343A3335333534333433358E +:107A800033343233343334333334333334333333C2 +:107A900034343233343433333334323334333433B1 +:107AA00033343334353233333332323233333233A7 +:107AB00032333231333232323033323331323232A6 +:107AC0003231323232323232323231323332313298 +:107AD000313432342F2F2F3033343A333533353479 +:107AE0003334333533343233343334333334333360 +:107AF0003433333334333233343433333334323353 +:107B00003333333333353334353233333332323244 +:107B10003333323332333231333232323033323341 +:107B20003132323232313232323232323232313238 +:107B300033323132313432342F2F2F303334333328 +:107B400034333434333333353334333334333433FD +:107B500033343333343333333434333334343333EF +:107B600033343233343333333335333434323332E2 +:107B700033333232333332323233323133323232E0 +:107B800030333232313232313231323132323132DB +:107B90003232313232323132313332332F2F2E30D2 +:107BA000333433333433343433333335333433339E +:107BB000343334333334333334333333343433338F +:107BC0003434333333343233333333333335333480 +:107BD000343233323333323233333233323332317D +:107BE0003332323231333233313232323231323176 +:107BF0003232313232323132333231323133323366 +:107C00002F2F2E3033343233343334333333333550 +:107C10003334333334333433333433333333333330 +:107C20003433333234343333333432333333333322 +:107C30003335333434323332333232323333323217 +:107C40003233323133323232303332323132323116 +:107C50003231323132323132323231323332313208 +:107C6000313332332F2F2E2F3334323334333434F5 +:107C700033333335333433333433343333343333CE +:107C800034333333343333333434333333343233C0 +:107C900033333333333533343432333233323232B5 +:107CA00033333233323332313332323231333233AF +:107CB00031323231323132323232313232323132A9 +:107CC00033323132313332332F2F2E2F333532329C +:107CD000343333333334333433343333343334336E +:107CE000333433333433333334343332343433335F +:107CF0003334323333333333333533343432333252 +:107D00003332323233333232323232313332323250 +:107D1000303332333132313132313131323231324A +:107D20003232313232323132313332332F2F2E3040 +:107D3000333532323433333333343334333433330F +:107D400034333433333433333333333334343332FF +:107D500034343333333432333333333333353334EE +:107D600034323332333232323333323232333231ED +:107D700033323232303332333132323232313232E4 +:107D800032323132323231323232313231333233D5 +:107D90002F2F2E2F4F51534F4F4D514D4F4F4D5170 +:107DA0004D4F4F514F4F534F4B515151534D534DD9 +:107DB0004F4D4F515151514F4F4F4F4F514D514FCB +:107DC0004F515153534F5151514F514F4F4E4F4FB0 +:107DD0004B4F4F4F4F4D4F514B4F4F514F4D4F51B9 +:107DE0004D4F4F4D4F4B4D51514F4F4F4F4D4D4FAD +:107DF0004B4D4F514D494B4D92249224920092008D +:107E000000000000B66DB66DB600B60000000000C0 +:107E1000B66DB66D9601960100000000B66DB66DA8 +:107E2000B201B20100000000B62DB62DB601B601B8 +:107E300000000000B665B665B601B601000000009E +:107E4000B66CB66CB601B60100000000966D966D7A +:107E5000B601B60100000000B26DB26DB601B60108 +:107E600000000000FF7FFF7FFF01FF010000000016 +:107E7000B66DB66DB601B6010000000092249224E2 +:107E800092009200000000000110000000000000BD +:107E900000000000FFFF3DDB38D4FC020200AA0016 +:107EA0006C768A940001060000000000DB060000EA +:107EB000040C000060056E40415639030100009A31 +:107EC000EC045661000000000000000010C40C50DB +:107ED0000390BBBB804422786411641189398939CD +:107EE0000FE00FE0641264120110000000000000B7 +:107EF00000000000FFFF3DDB38D4FC020200AA00B6 +:107F00006C768A940001060000000000DB06000089 +:107F1000040C000060056E40415639030100009AD0 +:107F2000EC045661000000000000000010C40C10BA +:107F3000E39EBBBB8055227864116411893989396D +:107F40000FE00FE064126412010400000000000062 +:107F50000000000000000000000000020200AA0073 +:107F60006C768A940001060000000000DB06000029 +:107F7000040C000020066E40418639030100009A7F +:107F8000AC058661000000000000000010C40C5029 +:107F90000390BBBB8044227864116411893989390C +:107FA0000FE00FE064126412C9040200010203042E +:107FB000EAF7FAFD3001A880CF0304021E00000397 +:107FC0006C768A940001060000000000DB060000C9 +:107FD000014600002B1A0040006B39034100029A51 +:107FE00000006B616478792BCF8A00801C54119853 +:107FF0000080BBBB0057227864116411893989392C +:108000000FF00FF064126412C904020001010101B3 +:10801000EAF7FAFD3001A880CF0304020200000055 +:108020006C768A940001060000000000DB06000068 +:10803000014600002B1A0040006B39034100029AF0 +:1080400000006B619A7F0A0AFFFF00801C541198A0 +:108050000380BBBB80462278641164118939893959 +:108060000FF00FF064126412C9040200020202024F +:10807000EAF7FAFD3001A880CF03040202000000F5 +:108080006C768A940001060000000000DB06000008 +:10809000014600002B1A0040006B39034100029A90 +:1080A00000006B616C7E0614FFFF00801C54119869 +:1080B0000380BBBB804622786411641189398939F9 +:1080C0000FF00FF064126412C904020003030303EB +:1080D000EAF7FAFD3001A880CF0304020200000095 +:1080E0006C768A940001060000000000DB060000A8 +:1080F000014600002B1A0040006B39034100029A30 +:1081000000006B61767CE11DFFFF00801C5411981C +:108110000380BBBB80462278641164118939893998 +:108120000FF00FF064126412C90402000404040486 +:10813000EAF7FAFD3001A880CF0304020200000034 +:108140006C768A940001060000000000DB06000047 +:10815000014600002B1A0040006B39034100029ACF +:1081600000006B61BC798D27FFFF00801C541198C3 +:108170000380BBBB80462278641164118939893938 +:108180000FF00FF0641264120104000400000000FC +:10819000CCF57AFDED20BF8FCF030402020600006C +:1081A0006C768A940001060000000000DB060000E7 +:1081B00001060000093C0040006B39034100029AAF +:1081C00000006B616478792BCF8A00801CC4101882 +:1081D0000380ABAA00C6227864116411803980390B +:1081E0000F000F00550D550DC904020006070A0BBC +:1081F000EAF7FAFD3001A880CF0304021E0600034F +:108200006C768A940001060000000000DB06000086 +:10821000014600002B1A0040006B39034100029A0E +:1082200000006B616478792BCF8A00801C54119810 +:108230000080BBBB00572218641164118939893949 +:108240000FF00FF064126412C9040200060606065D +:10825000EAF7FAFD3001A880CF030402020600000D +:108260006C768A940001060000000000DB06000026 +:10827000014600002B1A0040006B39034100029AAE +:1082800000006B616478792BCF8A00801C541198B0 +:108290000080BBBB005722186411641189398939E9 +:1082A0000FF00FF064126412C904020006060A0AF5 +:1082B00073EDFAFD5985A880CF0304020A06010078 +:1082C0006C768A940043060100000000DB06000083 +:1082D000014600002B1A0040006B39034100029A4E +:1082E00000006B619367CBB40000008012541198BA +:1082F0000080BBBB0056221864116411893989398A +:108300000FF00FF064126412C904020007070B0B90 +:1083100073EDFAFD5985A880CF0304020A06010017 +:108320006C768A940043060100000000DB06000022 +:10833000014600002B1A0040006B39034100029AED +:1083400000006B6155737BC80000008012541198C7 +:108350000080BBBB00562218641164118939893929 +:108360000FF00FF064126412C904020009090C0C2A +:1083700073EDFAFD5985A880CF0304020A060100B7 +:108380006C768A940043060100000000DB060000C2 +:10839000014600002B1A0040006B39034100029A8D +:1083A00000006B61D9770ED3000000801254119841 +:1083B0000080BBBB005622186411641189398939C9 +:1083C0000FF00FF064126412C90402000A0A0606D4 +:1083D00073EDFAFD5985A880CF0304020A06010057 +:1083E0006C768A940043060100000000DB06000062 +:1083F000014600002B1A0040006B39034100029A2D +:1084000000006B61BD7977D800000080125411988C +:108410000080BBBB00562218641164118939893968 +:108420000FF00FF064126412C90402000B0B07076F +:1084300073EDFAFD5985A880CF0304020A060100F6 +:108440006C768A940043060100000000DB06000001 +:10845000014600002B1A0040006B39034100029ACC +:1084600000006B61757B34DE0000008012541198AF +:108470000080BBBB00562218641164118939893908 +:108480000FF00FF064126412C90402000A0A060613 +:1084900073EDFAFD5985A880CF0304020A06010096 +:1084A0006C768A940043060100000000DB060000A1 +:1084B000014600002B1A0040006B39034100029A6C +:1084C00000006B61CB7C87E30000008012541198A0 +:1084D0000080BBBB005622186411641189398939A8 +:1084E0000FF00FF064126412C90402000B0B0707AF +:1084F00073EDFAFD5985A880CF0304020A06010036 +:108500006C768A940043060100000000DB06000040 +:10851000014600002B1A0040006B39034100029A0B +:1085200000006B61F27D29E900000080125411986F +:108530000080BBBB00562218641164118939893947 +:108540000FF00FF064126412C90402000C0C090948 +:1085500073EDFAFD5985A880CF0304020A060100D5 +:108560006C768A940043060100000000DB060000E0 +:10857000014600002B1A0040006B39034100029AAB +:1085800000006B61D57EC2EE00000080125411988D +:108590000080BBBB005622186411641189398939E7 +:1085A0000FF00FF0641264120000000000000000E1 +:1085B00000101000000060CA00009B94100F000221 +:1085C0000000E92A0000EA17100F00050000C82586 +:1085D00000001579100E00070000D3C100002AA882 +:1085E000100C00090000C15A00009C9A00041030D1 +:1085F0000000BCA00000903800091033000083D0B8 +:108600000000D635000B10350000C9C200001A5911 +:10861000000C103600008CA100002C9F000D1037BC +:1086200000009851000044DC000E10380000BEEA43 +:108630000000A536000E103A000026620000DD9909 +:10864000000F103B000000008C00000073000000D1 +:1086500073000000660000003F0000003F000000C3 +:1086600033000000260000000000000000000000B1 +:1086700000000000000000000000000000000000FA +:1086800000000000000000000000000000000000EA +:1086900000000000000000000000000000000000DA +:1086A00000000000000000000000000000000000CA +:1086B00000000000000000000000000000000000BA +:1086C00000000000870700008579385793F930A132 +:1086D000B3D4CC2BCB0AF200000000000000000055 +:1086E000000000000000000000000000000000008A +:1086F000000000000000000000000000000000007A +:1087000080220022870700008579385793E4C2B998 +:1087100030AFCC2BC5A1B30000000000000000006A +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:1087400080220022870700008579385793E4C2BC55 +:10875000C2BCD7930D79300000000000000000007B +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800080220022870700008579385793E4C2BF12 +:10879000930ACC2BC4F50D0000000000000000007F +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00080220022870700008579385793E4C2BFD2 +:1087D000930AE4C2B286CF0000000000000000004F +:1087E0000000000000000000000000000000000089 +:1087F0000000000000000000000000000000000079 +:1088000080220022870700008579385793E4C2BF91 +:10881000930AB0AF26CF5000000000000000000017 +:108820000000000000000000000000000000000048 +:108830000000000000000000000000000000000038 +:1088400080220022870700008579385793E4C2BB55 +:108850000AF2E4C2BE4C2B00000000000000000041 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800080220022870700008579385793E4C2BB15 +:108890000AF2B0AF295E4C000000000000000000AA +:1088A00000000000000000000000000000000000C8 +:1088B00000000000000000000000000000000000B8 +:1088C00080220022C8060000450EA63D450EA63DAA +:1088D000BAF15942450EA63D450EA63D450EA63DB0 +:1088E000450EA63D00000000000000000000000052 +:1088F0000000000000000000000000000000000078 +:108900008022002231302F2E2D2C2B2A2928272699 +:108910002524232221201F1E1D1C1B1A191817167F +:108920001514131211100F0E0D0C0B0A090807066F +:108930000504030201000000000000000000000028 +:108940000000000000000000000000004A49484705 +:10895000464544434241403F3E3D3C3B3A3938372F +:10896000363534333231302F2E2D2C2B2A2928271F +:10897000262524232221201F1E1D1C1B1A1900003E +:1089800000000000000000000000000000000000E7 +:10899000000000002000E0C0A08060402000E0C097 +:1089A000A08060402000E0C0A08060402000E0C0C7 +:1089B000A08060402000E0C0A08060402000E0C0B7 +:1089C000A08060402000000076DBB62D2449921B79 +:1089D000DBB6491292942409090000002000E0C08F +:1089E000A08060402000E0C0A08060402000E0C087 +:1089F000A08060402000E0C0A08060402000E0C077 +:108A0000A08060402000E0C0A08060402000000006 +:108A100076DBB62D2449921BDBB6491292942409C9 +:108A2000090000002021E0E1A0A160612021E0E137 +:108A3000A0A160612021E0E1A0A160612021E0E12E +:108A4000A0A160612021E0E1A0A160612021E0E11E +:108A5000A0A160612021000076DBB62D2449921B85 +:108A6000DBB6491292942409090000000100C1C03C +:108A7000818041400100C1C0818041400100C1C0EE +:108A8000818041400100C1C0818041400100C1C0DE +:108A9000818041400100C1C081804140010000004F +:108AA00076DBB62D2449921BDBB649129294240939 +:108AB000090000002120E1E0A1A061602120E1E0A7 +:108AC000A1A061602120E1E0A1A061602120E1E09E +:108AD000A1A061602120E1E0A1A061602120E1E08E +:108AE000A1A061602120000076DBB62D2449921BF5 +:108AF000DBB6491292942409090000007353331322 +:108B0000F2D2B29272523212F2D2B2927252321245 +:108B1000F2D2B29272523212F2D2B2927252321235 +:108B2000F2D2B29272523212F2D2B2927252000069 +:108B300000D0B62D2D499224DBB66D129224250962 +:108B4000490200003C1CFCDCBC9C7C5C3C1CFCDC4A +:108B5000BC9C7C5C3C1CFCDCBC9C7C5C3C1CFCDC55 +:108B6000BC9C7C5C3C1CFCDCBC9C7C5C3C1CFBDB47 +:108B7000BB9B7B5B3B1B00002D499224DBB66D1237 +:108B8000922425094902000040DBB62DB4947454A8 +:108B90003414F3D3B39373533313F3D3B3937353A3 +:108BA0003313F3D3B39373533313F3D3B393735395 +:108BB0003313F3D3B39373533313F3D3B39300004B +:108BC0000000B42D6D4B9224E4B66D1B922449092C +:108BD00049920000FBDBBB9B7B5B3B1BFBDBBB9B36 +:108BE0007B5B3B1BFBDBBB9B7B5B3B1BFBDBBB9BD5 +:108BF0007B5B3B1BFBDBBB9B7B5B3B1BFADABA9AC9 +:108C00007A5A3A1AFADA00002449921BDBB6491262 +:108C100092942409090000006DDBB624F5D5B595C2 +:108C200075553515F4D4B49474543414F4D4B49400 +:108C300074543414F4D4B49474543414F4D4B494F4 +:108C400074543414F4D4B49474543414F4D400002C +:108C50000000002D6DDB922424B96D1B9B2449126A +:108C600049922400BA9A7A5A3A1AFADABA9A7A5A8D +:108C70003A1AFADABA9A7A5A3A1AFADABA9A7A5A54 +:108C80003A1AFADABA9A7A5A3A1AF9D9B99979594A +:108C90003919F9D9B999000024496E1BDB2649120C +:108CA000529224090000002D6DDB92243616F6D670 +:108CB000B69676563616F5D5B59575553515F5D55E +:108CC000B59575553515F5D5B59575553515F5D554 +:108CD000B59575553515F5D5B5957555351500000E +:108CE000090000006DDBB62424496E1BDB26491207 +:108CF0005292240979593919F9D9B99979593919F7 +:108D0000F9D9B99979593919F9D9B99979593919D3 +:108D1000F9D9B99979593919F8D8B89878583818CB +:108D2000F8D8B8987858000024B96D1B9B244912D4 +:108D3000499224000000B42D6D4B922477573717C9 +:108D4000F7D7B79777573717F6D6B69676563616BB +:108D5000F6D6B69676563616F6D6B69676563616B3 +:108D6000F6D6B69676563616F6D6B69676560000EF +:108D70004902000040DBB62D2449921BDBB64912A4 +:108D8000929424093818F8D8B89878583818F8D830 +:108D9000B89878583818F8D8B89878583818F8D853 +:108DA000B89878583818FFFFFFFFFFFFFFFFFFFF5D +:108DB000FFFFFFFFFFFF0000E4B66D1B922449098F +:108DC0004992000000F0FF3FFFFFFF3FFFFFFFFF62 +:108DD000FFFFFFFFFFFFFFFFFFFFF7D7B7977757B3 +:108DE0003717F7D7B79777573717F7D7B797775713 +:108DF0003717F7D7B79777573717F7D7B7970000D1 +:108E0000FFFFFF3FFFDFB62D2D499224DBB66D1229 +:108E100092242509636261605F5E5D5C5B5A59580C +:108E200057565554535251504F4E4D4C4B4A49484A +:108E300047464544434241403F3E3D3C3B3A39383A +:108E400037363534333200000000000000000000E7 +:108E500000000000000000000000000031302F2E54 +:108E60002D2C2B2A292827262524232221201F1EAA +:108E70001D1C1B1A191817161514131211100F0E9A +:108E80000D0C0B0A09080706050403020100000087 +:108E900000000000000000000000000000000000D2 +:108EA00000000000FFFFFFFFFFFFFFFFFFFFFFFFCE +:108EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:108EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:108ED000FFFFFFFFFFFF0000FFFFFF3FFFFFFF3F20 +:108EE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFFFFD2 +:108EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:108F0000FFFFFFFFFFFFFFFFFFFF0000000000006B +:108F10000000000000000000000000000000000051 +:108F2000FFFFFF3FFFFFFF3FFFFFFF3F000000008D +:108F30000000000057473727170756463626160603 +:108F4000554535251505544434241404534333231F +:108F50001303524232221202514131211101504079 +:108F600030201000FFFF00000000000000000000A3 +:108F700000000000000000000000003F62605E5C36 +:108F80005A58565452504E4C4A48464442403E3C31 +:108F90003A38363432302E2C2A28262422201E1C21 +:108FA0001A18161412100E0C0A080604020000000B +:108FB00000000000000000000000000000000000B1 +:108FC00000000000000000000000000000000000A1 +:108FD0000000000000000000000000000000000091 +:108FE0000000000000000000000000000000000081 +:108FF0000000000000000000000000000000000071 +:109000000000000000000000000000000000000060 +:109010000000000000000000000000000000000050 +:109020000000000000000000000000000000000040 +:109030000000000000000000000000000000000030 +:109040000000000000000000000000000000000020 +:109050000000000000000000000000000000000010 +:109060000000000000000000000000000000000000 +:1090700000000000000000000000000000000000F0 +:1090800000000000000000000000000000000000E0 +:1090900000000000000000000000000000000000D0 +:1090A00000000000000000000000000000000000C0 +:1090B00000000000000000000000000000000000B0 +:1090C00000000000000000000000000000000000A0 +:1090D0000000000000000000000000000000000090 +:1090E0000000000000000000000000000000000080 +:1090F0000000000000000000000000000000000070 +:10910000000000000000000000000000000000005F +:10911000000000000000000000000000000000004F +:10912000000000000000000000000000000000003F +:10913000000000000000000000000000000000002F +:10914000000000000000000000000000000000001F +:10915000000000000000000000000000000000000F +:1091600000000000000000000000000000000000FF +:1091700000000000000000000000000000000000EF +:1091800000000000000000000000000000000000DF +:1091900000000000000000000000000000000000CF +:1091A00000000000000000000000000000000000BF +:1091B00000000000000000000000000000000000AF +:1091C000000000000000000000000000000000009F +:1091D000000000000000000000000000000000008F +:1091E000000000000000000000000000000000007F +:1091F000000000000000000000000000000000006F +:109200000801010000000000000000003202100010 +:109210001B00000000000000000000000000000033 +:109220008C1C0000AF1C0000D21C0000F51C0000CC +:10923000200300004110080344611C0800000000E6 +:10924000000000000000000000000000000000001E +:109250000A00000066666666560000000000000016 +:1092600000000000000000000000000000000000FE +:109270000000000003000000181DD61D061E1F1E62 +:10928000531F581E301F421F431F7E1707B8C307C6 +:10929000008000002083000000803280648096807F +:1092A0002DB4040F110C0F0F10000F13A5BA030AF1 +:1092B00018C80F00151015101043104320030000AC +:1092C000CBB2300DCE0345120000000000000000BC +:1092D0000000000000000000000000000A00000084 +:1092E0006666666656000000000000000000000090 +:1092F00011111111111111111111000000000010B4 +:1093000003000000181DD61D061E1F1E531F581EE9 +:10931000301F421F431F7E1707B80733008000002D +:109320002083000000803280648096802DB4040F7A +:10933000110C0F0F90000F13A5BA830A18C80F0065 +:10934000151015101043104345097E1707B8C307C1 +:109350000080008020F3000C00803280648096FE44 +:109360002DB4FFFF11FDFFFFD0FF0F13A5BA830A35 +:1093700018C80F00130F130F0F410F411F030000F8 +:1093800009000000000000000000000000000000D4 +:10939000189DD69D069E1F9E539F589E309F429FAC +:1093A000439F0000000000C000000000000000001B +:1093B00002000000000000000000000000000000AB +:1093C00000E60000EC0454E7E4077EE75509A20735 +:1093D0000A09250945097E1707B8C3070080000060 +:1093E0002083000000803280648096802DB4048F3A +:1093F00011FDFFFFD0FF0F93A5BA830A18E80FE015 +:10940000130F13FF0F410F411F030000D4B80402D4 +:109410000351188748F00C0C85011C08189DD69D37 +:10942000069E1F9E539F589E309F429F439F5555B7 +:10943000555555D55555000000000018086A666658 +:1094400066666666366600270000000002E6008059 +:10945000EC0C54EFE4877EE75509A2070AE925E9F9 +:109460000000000000000100002802000000FC00D5 +:10947000000000000D000D0059064006000000002D +:1094800001559701020000000000000000010202E7 +:10949000002800008002FC00FFFFFF010D000D000E +:1094A00017001F000000000004B0B300000000100F +:1094B0000000000000020202002800008002FC0000 +:1094C000FFFFFF010D000D0016001E000000000050 +:1094D00004C4B300000000100000000000030202FA +:1094E000002800008002FC00FFFFFF010D000D00BE +:1094F00015001D000000000004D8B300000000109B +:109500000000000000040202002800008002FC00AD +:10951000FFFFFF010D000D0014001C000000000003 +:1095200004ECB3000000001000000000000502027F +:10953000002800008002FC00FFFFFF010D000D006D +:1095400013001B00000000000400B4000000001025 +:109550000000000000060202002800008002FC005B +:10956000FFFFFF010D000D0012001A0000000000B7 +:109570000414B40000000010000000000007020204 +:10958000002800008002FC00FFFFFF010D000D001D +:1095900011001900000000000428B40000000010B1 +:1095A0000000000000080202002804008002FC0005 +:1095B000FFFFFF010D000D0010001800000000006B +:1095C00020B0B30000000010000000000000000008 +:1095D000002806000000FC00000000000D000D0047 +:1095E000D20FA00F00000000015097010000000002 +:1095F0000000000000000000002802000000FC0045 +:10960000000000000D000D00C116A81600000000AB +:10961000018C97010600000000000000000B020210 +:10962000002800008000FC00000000000D000D007C +:1096300017001F000000000004B0B300000000107D +:1096400000000000000C0202002800008000FC0066 +:10965000000000000D000D0016001E0000000000BC +:1096600004C4B3000000001000000000000D02025E +:10967000002800008000FC00000000000D000D002C +:1096800015001D000000000004D8B3000000001009 +:1096900000000000000E0202002800008000FC0014 +:1096A000000000000D000D0014001C000000000070 +:1096B00004ECB3000000001000000000000F0202E4 +:1096C000002800008000FC00000000000D000D00DC +:1096D00013001B00000000000400B4000000001094 +:1096E0000000000000100202002800008000FC00C2 +:1096F000000000000D000D0012001A000000000024 +:109700000414B40000000010000000000011020268 +:10971000002800008000FC00000000000D000D008B +:1097200011001900000000000428B400000000101F +:109730000000000000120202002804008000FC006B +:10974000000000000D000D001000180000000000D7 +:1097500020B0B300000000104F00000001F404002E +:1097600068931B00600000000C0000000100040072 +:109770001428000060000000300000002D0084006C +:10978000142800001C000000730000002DF4840069 +:1097900068931B001C000000700000002DF4840082 +:1097A00068931B001C000000730000002DF484006F +:1097B00068931B001C000000630000002DF484006F +:1097C00068931B001C0000004F00000001F404001F +:1097D00068931B00E00001000C0000000100040081 +:1097E00014280000E0000100300000002D0084007B +:1097F000142800001C000000700000002DF48400FC +:1098000068931B001C000000000000000000000026 +:109810000000000000000000000000000000000048 +:109820000000000000000000000000000000000038 +:109830000000000000000000000000000000000028 +:109840000000000000000000000000000000000018 +:109850000000000000000000000000000000000008 +:1098600000000000000000000000000000000000F8 +:10987000000000000000000000000000922492247C +:109880009200920000000000224924492401A40013 +:1098900000000000144924492401140100000000C4 +:1098A000A448244924012201000000002445242961 +:1098B000240124010000000024292445240124015E +:1098C000000000002449A4482201240100000000F7 +:1098D00024491449140124010000000024492249AC +:1098E000A400240100000000FF7FFF7FFF01FF01B3 +:1098F00000000000B66DB66DB601B60100000000B4 +:10990000B26DB66DB601B60000000000966DB66D82 +:10991000B601960100000000B66CB66DB601B2014A +:1099200000000000B665B62DB601B60100000000CB +:10993000B62DB665B601B60100000000B66DB66C76 +:10994000B201B60100000000B66D966D9601B60139 +:1099500000000000B66DB26DB600B6010000000058 +:1099600001280000000000000000000000000000CE +:10997000000000020206AA006C768A94000106002C +:1099800000000000DB0600000106000091016E40AF +:10999000418C39030100009A1D018C610000000018 +:1099A0000000000010100D100390BBBB8E5A22184F +:1099B00064116411893989390AE00FE06412641274 +:1099C0000120000000000000000000000000000076 +:1099D000000000020206AA006C768A9400010600CC +:1099E00000000000DB0600000106000091016E404F +:1099F000418C39030100009A1D018C6100000000B8 +:109A00000000000010000C100380ABAA80442278F4 +:109A1000641164118939893905E005E06412641222 +:109A20000104000000000000000000000000000031 +:109A3000000000020200AA006C768A940001060071 +:109A400000000000DB060000040C000038066E2059 +:109A5000418C390301000084C4058C6100000000C2 +:109A60000000000010C40C500390BBBB804422785F +:109A7000641164118A39893905E00FE064126412B7 +:109A8000D004020001020304CCF57AFDED20BF8F63 +:109A9000CF0304021E0600036C768A9400010600C0 +:109AA00000000000DB06000001460000121B002041 +:109AB000006B39034100028400006B616478792BEC +:109AC000CF8A00801C5411980080BBBB00572278BD +:109AD000641164118A39893905E00FE06412641257 +:109AE0000100000001010101CCF57AFDED20BF8FDE +:109AF000CF030402020600006C768A94000106007F +:109B000000000000DB060000000C0000401A0020EE +:109B10004100380341000284000000606478792B22 +:109B2000CF8A00801C5410180380BBBB804622786B +:109B3000641164118A39893905E00FE064126412F6 +:109B4000D004020002020202CCF57AFDED20BF8FA4 +:109B5000CF030402020600006C768A94000106001E +:109B600000000000DB06000001460000121B002080 +:109B7000006B39034100028400006B616478792B2B +:109B8000CF8A00801C5411980380BBBB804622788A +:109B9000641164118A39893905E00FE06412641296 +:109BA0000100000003030303CCF57AFDED20BF8F15 +:109BB000CF030402020600006C768A9400010600BE +:109BC00000000000DB060000000C0000401A00202E +:109BD0004100380341000284000000606478792B62 +:109BE000CF8A00801C5410180380BBBB80462278AB +:109BF000641164118A39893905E00FE06412641236 +:109C0000D004020004040404CCF57AFDED20BF8FDB +:109C1000CF030402020600006C768A94000106005D +:109C200000000000DB06000001460000121B0020BF +:109C3000006B39034100028400006B616478792B6A +:109C4000CF8A00801C5411980380BBBB80462278C9 +:109C5000641164118A39893905E00FE064126412D5 +:109C60000100000000000000CCF57AFDED20BF8F60 +:109C7000CF030402020600006C768A9400010600FD +:109C800000000000DB060000000C0000FF3B00208D +:109C90004100380341000284000000606478792BA1 +:109CA000CF8A00801CC410180300000000C6227870 +:109CB000641164118039803905000F00551055106A +:109CC000000000000000000000101000000092CD15 +:109CD0000000C180100F0002000087370000BBF1B8 +:109CE000100F00040000904100008B43100E00078D +:109CF0000000BBF100009167100C000900001DFB83 +:109D00000000709E100E000500000000C806000054 +:109D1000BAF15942BAF15942450EA63D11223344D7 +:109D20005566778899AABBCCDDEEFF69000000007C +:109D30000000000000000000000000000000000023 +:109D40000000000000000000C022C0224A4948472D +:109D5000464544434241403F3E3D3C3B3A3938371B +:109D6000363534333231302F2E2D2C2B2A2928270B +:109D7000262524232221201F1E1D1C1B1A1900002A +:109D800000000000000000000000000000000000D3 +:109D90000000000031302F2E2D2C2B2A29282726B9 +:109DA0002524232221201F1E1D1C1B1A19181716DB +:109DB0001514131211100F0E0D0C0B0A09080706CB +:109DC0000504030201000000000000000000000084 +:109DD0000000000000000000000000002000E0C0C3 +:109DE000A08060402000E0C0A08060402000E0C073 +:109DF000A08060402000E0C0A08060402000E0C063 +:109E0000A08060402000E0C0A080604020000000F2 +:109E100076DBB62D2449921BDBB6491292942409B5 +:109E2000090000009173553719FBDDBFA183654719 +:109E3000290BEDCFB1937557391BFDDFC1A38567A2 +:109E4000492B0DEFD1B39577593B1DFFE1C3A58792 +:109E5000694B2D0FFFFF00006D5B922424B96D1B31 +:109E60009B2449124A9224010000003F62442608C4 +:109E7000EACCAE9072543618FADCBEA08264462852 +:109E80000AECCEB0927456381AFCDEC0A284664842 +:109E90002A0CEED0B29476583A1C9D7F61430000A4 +:109EA0006D4B9224E4B66D1B9324490A4992240019 +:109EB0000000B42D2F11927456381AFCDEC0A28413 +:109EC00066482A0CEED0B29476583A1CFEE0C2A442 +:109ED00086684A2C0EF0D2B496785A3C1E00E2C432 +:109EE000A6886A4C2E10000040DB962424496E1B85 +:109EF000DB26491292922409090000002507E9CBCC +:109F0000AD8F71533517F9DBBD9F8163452709EB91 +:109F1000CDAF9173553719FBDDBFA1836547290B81 +:109F2000EDCFB1937557391B9C7E6042240600002B +:109F30002D499224DBB66D13922429094992000021 +:109F400000D0B62D6C4E3012937557391BFDDFC112 +:109F5000A38567492B0DEFD1B39577593B1DFFE1E1 +:109F6000C3A587694B2D0FF1D3B597795B3D1F01D1 +:109F7000E3C5A7896B4D000000D0B6252449921B8C +:109F8000DBB6491292A4240949020000E8CAAC8E4B +:109F900070523416F8DABC9E8062442608EACCAED1 +:109FA0009072543618FADCBEA0826446280AECCEC1 +:109FB000B0927456381A9B7D5F412305E7C90000B3 +:109FC0002449921BDBB64D1292A4240949020000D9 +:109FD00040DBB624A98B6D4F31139476583A1CFEA2 +:109FE000E0C2A486684A2C0EF0D2B496785A3C1E81 +:109FF00000E2C4A6886A4C2E10F2D4B6987A5C3E71 +:10A000002002E4C6A88A00000000B42D254992244D +:10A01000DBB66D139224290949920000AB8D6F5174 +:10A020003315F7D9BB9D7F61432507E9CBAD8F7110 +:10A03000533517F9DBBD9F8163452709EBCDAF9100 +:10A04000735537199A7C5E402204E6C8AA8C00003A +:10A0500024496E1BDB364912929224090900000044 +:10A060006DDB9224E6C8AA8C6E5032149577593B6A +:10A070001DFFE1C3A587694B2D0FF1D3B597795B20 +:10A080003D1F01E3C5A7896B4D2F11F3D5B7997B10 +:10A090005D3F2103E5C700000000002D6D499224BB +:10A0A000E4B66D1B9324490A499224006E50321481 +:10A0B000F6D8BA9C7E60422406E8CAAC8E70523450 +:10A0C00016F8DABC9E8062442608EACCAE90725440 +:10A0D0003618997B5D3F2103E5C7A98B6D4F0000C2 +:10A0E00024B96D1BDB2449124A9224090000002D7B +:10A0F0006D4B92242305E7C9AB8D6F5133159678CC +:10A100005A3C1E00E2C4A6886A4C2E10F2D4B698BF +:10A110007A5C3E2002E4C6A88A6C4E3012F4D6B8AF +:10A120009A7C5E4022040000090000006DDB92244E +:10A1300024B96D1BDB2449124A9224093113F5D747 +:10A14000B99B7D5F412305E7C9AB8D6F513315F78F +:10A15000D9BB9D7F61432507E9CBAD8F715335177F +:10A16000FFFFFFFFFFFFFFFFFFFFFFFF30120000B9 +:10A17000E4B66D1B9324490A499224000000FC3F79 +:10A18000FFFFFF2460422406E8CAAC8E70523416EA +:10A1900097795B3D1F01E3C5A7896B4D2F11F3D55F +:10A1A000B7997B5D3F2103E5C7A98B6D4F3113F54F +:10A1B000D7B99B7D5F4100004902000040DBB62417 +:10A1C00024496E1BDB36491292922409F4D6B89AC0 +:10A1D0007C5E402204E6C8AA8C6E503214F6D8BACF +:10A1E0009C7EFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:10A1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00006D +:10A20000DBB66D1392242909C9FFFF3FFFFFFF3F13 +:10A21000FFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFF0E +:10A22000FFFF987A5C3E2002E4C6A88A6C4EFFFFCE +:10A23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:10A24000FFFFFFFFFFFF0000FFFFFF3FFFDFB62D17 +:10A250002449FE3FFFFFFF3FFFFFFF3F2000E0C01C +:10A26000A08060402000E0C0A08060402000E0C0EE +:10A27000A08060402000E0C0A08060402000E0C0DE +:10A28000A08060402000E0C0A0806040200000006E +:10A2900076DBB62D2449921BDBB649129294240931 +:10A2A000090000002000E0C0A08060402000E0C065 +:10A2B000A08060402000E0C0A08060402000E0C09E +:10A2C000A08060402000E0C0A08060402000E0C08E +:10A2D000A08060402000000076DBB62D2449921B50 +:10A2E000DBB6491292942409090000000000000026 +:10A2F000000000000000000000000000000000005E +:10A30000000000000000000000000000000000004D +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000C822050CE8220F0C56 +:10AAE0000000001002000000000000000000000054 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB2000C00BBC0DEE0B0000400BBC0FEC0B040087 +:10AB3000C02ABC0FEA0B0C00404ABC0FE80B140003 +:10AB4000C069BC0FE60B1C004089BC0FE40B24005D +:10AB5000C0A8BC0FE2082C004C48BE00000000005A +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00029292A2A2A2A29292A2A2A2A29292A2A0B +:10ABB0002A2A29292A2A2A2A2A2A2A2A29292A2AF9 +:10ABC0002A2A29292A2A2A2A29292A2A2A2A2929EB +:10ABD0000000000029292A2A2A2A29292A2A2A2A81 +:10ABE0000000000000000000000000000000000065 +:10ABF00000000000000000002A2A2A2A29292A2A07 +:10AC00002A2A29290000000000000000000000009E +:10AC10000000000029292A2A2A2A29292A2A2A2A40 +:10AC20002A2A2A2A29292A2A2A2A29290000000030 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE100006F0F15506F0F15506F0F15506F0F15542 +:10AE200020212224232323242325232424242424EF +:10AE300028272628272628262627252627252420B2 +:10AE40002121221F242425232623222625242524CC +:10AE5000262827272527282828282828272428287F +:10AE600024212220232524242523202623212525AF +:10AE7000262A272A2326262C26262B292B27292655 +:10AE80002424232222242223232225232423272689 +:10AE9000242927272827272C29262A272626252341 +:10AEA0002925242224242325242423232326252260 +:10AEB0002626282726262B26272C282828292B2813 +:10AEC0002322252225222324252423262524252543 +:10AED000282728282A29282B292B2C2C2A252424EA +:10AEE0002524242324222425222325242424242425 +:10AEF00025272727282625272826272927272425E9 +:10AF00002123222323212323232425242324242211 +:10AF100029282826272927262726242726252325CA +:10AF200022222322242323232323232424222421F3 +:10AF300027272629262727252827262729272727A1 +:10AF400023232421232424242423242422242523CA +:10AF50002727272626262726262425272A2826248B +:10AF600022222322242324242322232524242223AF +:10AF70002725252627272525252726262627252672 +:10AF8000252625232222242323232423232323238A +:10AF9000262627262526252626272627282727274B +:10AFA000232422222322232422232423232424246F +:10AFB0002625262727262627252727282629272529 +:10AFC0002323232324232325232524252524232544 +:10AFD0002727252626262626282626272729262807 +:10AFE000232423232324242224232423232324222D +:10AFF00026272526262626262627282829282727E5 +:10B000002122232225232323242322232323242410 +:10B0100026272626262626262727272629262828C5 +:10B0200022222023232224222324222425242523F0 +:10B0300027242527262725292528272728292825A5 +:10B0400025252323242424242525232424242424BF +:10B050002726272725262726272726272928262784 +:10B0600021222321252623242423232323242423AC +:10B070002727272626272628262629292A2927255D +:10B080002324222324232424242624242524242482 +:10B090002724272627252525272826272828272748 +:10B0A0002424232126242323272423232524242561 +:10B0B000282727282726282827272828272827271A +:10B0C0002324232224242523242326252525252340 +:10B0D0002727272727272827262828272328282700 +:10B0E0002424222325232323232423242524232526 +:10B0F000272928262828272727272828262A2727D8 +:10B1000023222325242424252425262523242625FB +:10B1100027272727272726292627282626292928BB +:10B1200022222325232424242524252525282525DA +:10B130002626282528272725292A272A26282A2A95 +:10B1400024242524242424252323252524252425BB +:10B150002628272627272727282627262727262782 +:10B160002423262124252522252426242427252599 +:10B17000292827272829282929272829282829294B +:10B180002423222322232325232524242524242485 +:10B19000272728272727272827272926262627283D +:10B1A000222222232426242324242425262526255E +:10B1B0002828292826272826282827272826292717 +:10B1C0002322242325242424252626252526242736 +:10B1D00026262729272729282628282827262928F8 +:10B1E000252524232524252526262625252627250D +:10B1F00027282A282727292926282B2729292627CF +:10B2000023232324242522252426262524262625F7 +:10B2100026282727272927262727282829292728B6 +:10B2200024232322242423262624272525252526D6 +:10B230002628292927262828272627292728272995 +:10B2400023232322252423232523252525242425C0 +:10B25000272728272628272627272829282A292973 +:10B2600025242321242123232423252524242425A4 +:10B270002626282728282828282628292829282754 +:10B280002220222425232423242625252324242583 +:10B290002727262828262628272727292828292738 +:10B2A000252322242424232426252325242424255D +:10B2B0002726262727272627282927282B2B282615 +:10B2C000252422242423232422252425252525253D +:10B2D000272728272727282728282628292C2A27F0 +:10B2E0002424252323232524242425242625252519 +:10B2F0002927282928282827282828282A272928CC +:10B3000025262422242424242424242525252324FA +:10B31000262726262727272527282728292A2928B8 +:10B3200026272523242523242525262624242525D0 +:10B330002727262727272827282828282929282695 +:10B3400025262524252324242525242525252526B1 +:10B35000262727282727282728292B2A2B292B2867 +:10B36000252626232624242524252526252525268D +:10B37000282627262727272727272828282A282757 +:10B38000272724222326232626232525262527256D +:10B390002927262726282628282828282728292735 +:10B3A0002323232423272425252427252625252751 +:10B3B0002927262728272727282627272A2A2A2811 +:10B3C000242226222523262624272726262726262A +:10B3D000282828282828272829282A292A292A28E5 +:10B3E0002424242326252525272727282727262602 +:10B3F00027262526252A292A2B2B2A28282A2A28C7 +:10B4000026262424232725272529262729292927D5 +:10B410002C2B29292B292A2A292A2A2A2928262796 +:10B4200026242423272325272627262828282729BA +:10B4300028292D292A2C2A2B2D292B2A2B29292A68 +:10B44000252427252724262626272627272A272896 +:10B4500029272A28292B282B2C2A28292A29292957 +:10B460001B1A181A19191819191919191A1C1A1A44 +:10B470001B1D1B1C1B1A1A191918181A1B1B1B1928 +:10B480001A1818181A1919181917181A181A1B1A2D +:10B490001C1B1B1B1A171A1A191A19191E1A1C1D04 +:10B4A000171A1A1A1C1B1A191917171A19191A1B05 +:10B4B0001D1D1C1C1D1C1A1B18191B191E1A1D1BD7 +:10B4C0001C191A1A1A1A17181817181719191B1AEB +:10B4D0001C1D1C1C1B1C1A1A1A191C181C1B1A1ABE +:10B4E0001E1C1C191A19191917181918191A191AC2 +:10B4F0001D1B1B1B1B1B1A191C1B1A1B1C1D1E1C96 +:10B500001A181A191A1719191818191A191A1B1BA7 +:10B510001D1E1C1D1C1B1B1B1A1B1B1B1C1C1C1D6E +:10B5200018191919181818181719191818191A1B91 +:10B530001C1C1E1B1A18191B1A1A1A1C1D1C1B1B5B +:10B540001B1B1A1A191819181818181919191A1A68 +:10B550001C1A1C1B1B1C1A191A191A1B1B1C1A1E3D +:10B560001A1919191918181917171A181919191950 +:10B570001C1C1A1C1B1C1B19191A1A1B1D1A1B1C1C +:10B580001C1A19181919181818181818181A1B1A2B +:10B590001D1C1B1C1B1C1B1B1A191A1C1B1C1C1DF5 +:10B5A0001A1A1919191819191918181919191A1A0A +:10B5B0001C1B1A1B1C1B1A1B191C1A1C1B1C1C1CD9 +:10B5C0001C1B1A1A181819171817181918181919EE +:10B5D0001C1A1C1B1A1A1A191A1A1A191C1D1D1CBE +:10B5E0001D19191818181719171818191919191BCE +:10B5F0001C1C1C1B1B1C1B1A1A1B1C1B1D1E1C1C91 +:10B600001A191819181818181819191919181A1AAE +:10B610001D1E1C1B1C1B1A1A1A1B1A1C1C1E1B1E6F +:10B620001B1A181B181818181819181718191A1A8D +:10B630001C1B1B1C1A1C1B191A1B1A1C1E201D1E4E +:10B6400019171918171918171718181919181A1A75 +:10B650001A1C1C1C1B1A1B1B1B1A1A191D1E1E1F31 +:10B660001918161A1718171817181819181A1A1A55 +:10B670001B191C1B1B1A1A191A1A1B1C1B1F1C1B1B +:10B680001B1917181918171818191718191A1A1B2F +:10B690001B191D1B1A1C1B1A1A1A1A1C1D1C1D1BF8 +:10B6A0001817171719191717171718181818191A1C +:10B6B0001B1B1B1B191A1B1917191B1B1C1E1D1AE0 +:10B6C0001A19171817171818181819181B1A191AF1 +:10B6D0001A1B1B1A1C1A191919181A1B1C1E1C1BC1 +:10B6E00018191818181817181716171719191A19DA +:10B6F0001C1C1B1B1C1A1A1A1B1A191D1C1D1C1C96 +:10B7000018161717171717161818181818191A1BBC +:10B710001B1A1C1B1B1B1C19191A191B1A1E1C1B7C +:10B7200018161617171817161717171618191919A4 +:10B730001C1C1C1B1A1C1C1A1919191B1A1F1C1C57 +:10B740001817161818171718171819171819191A7B +:10B750001B1C1B1A191A1B1A19191B1A1C1F1C1C3B +:10B7600018161619171816171718181818191A1C5A +:10B770001C1A1B1B1C191A1A1C1A191B1A1E1D1C19 +:10B780001819181819181717171718171919191C35 +:10B790001B1C1B1A191A191B1B18191A1D1B1B1C01 +:10B7A000191719161817161717171817181819191F +:10B7B0001B1C1C1C1A191B1A1B1B1B1B1B1C1D1CD6 +:10B7C0001B181616161716161818191818181A19FD +:10B7D0001A1A1B191B1B191A181A18191A1C1B1CC8 +:10B7E00018161518171717171617181818181819E4 +:10B7F0001B1A1B1B1B191B1819191A1B1B1B1D1CA1 +:10B800001917171717171617171718181819181CBC +:10B810001B1A1A1B1A1919191A19191A1B1B1C1B86 +:10B820001A19171717181718171817181818191B97 +:10B830001C1B1B1919191919191A1A191B1E1B1B64 +:10B840001818171716171515161818181818191B81 +:10B850001A1C1A191A1A19181B1A1A1B1C1D1D1C3E +:10B860001816171616171717171718191918181961 +:10B870001A1C1B1A1A1A1B19181A1A1A1B1B1A1A25 +:10B880001817161717181515181617191718191A43 +:10B890001A1C1B19191B181717171A1A1B1C1B1B0C +:10B8A0001A18171616151516161717171817181A27 +:10B8B0001B191B1A191919181918171C1B1D1C1AEA +:10B8C0001815151716151515171716181618181A0E +:10B8D0001B1A191C1A18181A1919181B1A1C1C1AC9 +:10B8E00019171616161715171716171817181919E6 +:10B8F0001A191919181918191918181A1B1C1A19B4 +:10B900001818161616171618161718181818191AC0 +:10B910001B1A1A191918191719181A1C1A1D1C1A8A +:10B9200017161716161617171718181918171819A3 +:10B930001B191A1A191A18181A1B19191B1C1D1B66 +:10B940001918161516161515161717181818181A87 +:10B950001A1B181B1A1919181A1918191B1C1A1A4C +:10B960001817171516181616161717171918171867 +:10B97000191A1919191A19181A191B191A1A1A1A2F +:10B980001818161717161615171617181718191945 +:10B99000191B19191819191719181B1B1B1A1A1911 +:10B9A0001817171515171717161717191718181A24 +:10B9B0001A181717191819191818181A181A1919FE +:10B9C000181915151616161517161617161718180E +:10B9D00018181818171819171819181A181B1A19DF +:10B9E0001716161616161817151717171717191AE8 +:10B9F0001A181919181918181A1919181C1B1B1AB2 +:10BA000016151815161515161617181817181819CB +:10BA10001918181917171719191818191A1A1A199D +:10BA20001716161518171516181918171719191AA1 +:10BA30001B1917171A1919171B1A1818191B1A1A74 +:10BA40001616151516171615141518161716171895 +:10BA50001C1B1B1A191A1918191819181B1A1A1B4A +:10BA6000141414141616141415161416171717197F +:10BA70001818191918171B18191A17191819191A3B +:10BA80001515151416161516151716171718181953 +:10BA900019171818181719191A1916171817191B22 +:10BAA0001A19181918181818171818191A1C1D1C03 +:10BAB0001C1C1B1B1D1D1C1D191A1B1C1A1D1D1BCC +:10BAC0001A1918171917171618171819181A1B19F1 +:10BAD0001D1C1B1A1B1A1B191819191A1C1C1E20B5 +:10BAE0001D1B1A191A1A1A181917171A1A191C1ABB +:10BAF0001E1E1C1C191C1C1C191A1A191F1C202183 +:10BB00001C1D1A19181916171615171619191A1AAD +:10BB10001D1E1D1B1A1A1B1C1A181C1A1C1E1B1A70 +:10BB20001E1D1B191A1818171516171818191A1A86 +:10BB30001C1C1B181C1B1B1A1919191B1C1D201F50 +:10BB40001A1919191917181617151819181A1B1D6B +:10BB5000211D1D1E1D1C1B1B181A1A1A1C1C1C1D26 +:10BB60001A1A18181917171615171718181A1B1A52 +:10BB70001D1E1B1C1B1A181B1819191C1D1E1F200B +:10BB80001B1A191919181717161617181C1A1C1C26 +:10BB90001F1E1F1C1B1A1A19181C1C1C1D1E1B1EE5 +:10BBA00019181817191617171516171719181A1B19 +:10BBB0001F1E1D1C1B1A1A1918191B1B1E1C1D1FCA +:10BBC0001C1919181818171717171718181A1B1BEC +:10BBD000201D1D1D1B1A19191A181C1C1D1C1E1FA7 +:10BBE0001A1919181817171716151718191A1A1CD1 +:10BBF0001E1D1C1C1B1A19191919191A1D1C1B1E94 +:10BC00001A1A1918171617161516161818181A1AB8 +:10BC10001E1C1B1C1A1919181818191A1A1A1C1E7E +:10BC20001C191918181617171516181818191B1C8F +:10BC30001E1D1C1B1B1B191817191B18191C1C1D5A +:10BC40001916171916161616151617181819191C7D +:10BC50001E1C1A1A1A19191818181618191B1B1D48 +:10BC60001A18171918171716151616171818191B5A +:10BC70001E1B1B1A1A181918181916191C1B1C1D23 +:10BC800019181716171616151516151718181A1B42 +:10BC90001E1C1B1B1A191919181817181C1A1C1D01 +:10BCA00018161616161616151516161718191A1927 +:10BCB0001C1B1A1A19181818171718171A1B1A1BF1 +:10BCC0001A191617171616161617161718191A1BFB +:10BCD0001D1B1B1A191818171718191A1C1B1A1CC8 +:10BCE00017161515171616151514151616181819F2 +:10BCF0001C1B1B1918171717161718191A1B191BB5 +:10BD00001918151616151515161616171818191BC5 +:10BD10001C1A1918191717171617191B19191B1C94 +:10BD20001718171516161515161516171718191AA8 +:10BD30001C1B1A1A191819181718191B191A1A1C6A +:10BD40001715161516151414141416161818191993 +:10BD50001B1A191919181817141516161619191B64 +:10BD60001816151516151514141515161718181A72 +:10BD70001C1B19191818171515161616181A1A1B40 +:10BD80001716141516141314141415151618191A59 +:10BD90001B1A19181718151515161516171A1A1B28 +:10BDA0001715141715141414151515151718181A36 +:10BDB0001C1A1918191816151617171618191B1CFE +:10BDC0001715171616151414141316161617191A14 +:10BDD0001A1A171817181514151515161718191CEF +:10BDE0001816151415141412141415151617181AFC +:10BDF0001B1A191817161616151517181919191CC4 +:10BE00001918151415141414141415161716181AD5 +:10BE10001A19191818171617151617161717191DA6 +:10BE20001715141414141413131414151616171AC2 +:10BE30001B191918171616161616161717161A1C88 +:10BE40001816151415141213141415161617181A9B +:10BE50001A181817171616161616171718171A1D68 +:10BE60001918161515141414141414151616171879 +:10BE70001B19181716161615161618171819191B48 +:10BE80001716141513141213131415151617171962 +:10BE90001918171617161514161616181718181A33 +:10BEA0001816151414131313131414151516181942 +:10BEB0001919181716161614141414161718181B17 +:10BEC000171514141413121213131415151516182C +:10BED0001A18171616151412131514141618191B00 +:10BEE000181714131312121213131315151517180C +:10BEF00016181817161613131415141516171819E3 +:10BF000016141313131212121314141414161719EF +:10BF10001718161716151314141515151618191ABF +:10BF200017141313131212121313131515151618D1 +:10BF300016171615151514121414141717171819A7 +:10BF400017151313131212131214141414161618AF +:10BF5000171817151515151415151516171718197F +:10BF60001716141313121212131313141415161791 +:10BF70001617161615151414141515161716181964 +:10BF80001816141213121212121313141415161772 +:10BF90001817161515141412141515161617171848 +:10BFA0001615141212131212131213141414161657 +:10BFB000181616151314141313151616151617182C +:10BFC0001616141313121212121313131414151736 +:10BFD000171615151313131213151616161618180F +:10BFE0001615141112121212121313141415161816 +:10BFF00018161515131414141315151614171718ED +:10C0000015161211131211121211121313141617FE +:10C0100017161514141312121314141514161718D6 +:10C0200015131312121212121212131314141617DC +:10C0300018171514151414131414141415171817AD +:10C0400014131312121112121112141414141517BE +:10C050001616151413141314141415141616171792 +:10C06000141313121313111212121313141515169D +:10C07000161514141314131314141313141515187C +:10C080001413121111111110111112131314151789 +:10C09000171616161613131313141615151516184E +:10C0A0001312121011100F10101011121314161673 +:10C0B000171516161313131314121212131517193A +:10C0C0001312131011101010101011121113151655 +:10C0D0001514151513131313111211121214171826 +:10C0E0001F1E1C1C1B1A1A1B1B1A1C1C1D21212184 +:10C0F00025252322211F1E1D1B1C1B1C1F201F1E4C +:10C100001D1D1C1B1B1C1B181B1A1C1D1C1E1F1F6E +:10C110002522201F201E1C1D1A191B1B1B1B20253E +:10C1200020201E1D1D201E1B1A191B1E1B1E202138 +:10C1300025242323201F1E1F181B1D1C201E222503 +:10C14000201F1D1D1C1C191A191919191A1D202030 +:10C15000242521211F1E1C1E191A1D1D1F1D1E1FF7 +:10C1600025211F1E1F1C1B1B18191B1A1B1B1D1E04 +:10C1700025222120201F1E1C1A1C1D1E1F212021CC +:10C18000201F1F1E1D191B1B19191B1C1C1E1F20E5 +:10C1900027252322211F1E1D1B1A1C1C1F1F201FA9 +:10C1A0001F1E1C1C1D1A1A18171A1A1B1B1D1D1ED8 +:10C1B00021211F1E1E1C1A1A1A1B1C1E1C1D1F21AA +:10C1C0001F1F201D1E1B1C1A1717191B1C1D1E1EAE +:10C1D000252422201F1E1D1C1B1B1C1D1E1E1E2471 +:10C1E0001F1C1B1B1C1A1A18181819191B1C1D1DA3 +:10C1F0002321211F1E1D1B1B1A1B1C1C1F1B1D2264 +:10C20000211F1E1B1B1B1A1919191A1C191B1D1D76 +:10C210002422211F1E1D1C1A1B1A1C1D1E2020213A +:10C22000201C1C1C1B1A191917191A1A1B1D1D1F5B +:10C230001E201F1F1D1B1A1A191B1B1A1D1F1E2132 +:10C24000211F1D1C1A191818171719181A1A1C1B48 +:10C250001B201E1E1B1B1A1918191B181B1C1E1E27 +:10C260001F1D1D1B1B1A191917181A1A191B1D1E21 +:10C270001E20201E1D1D1A1817191A1B1A1E1E1FFC +:10C280001D1B1B1C1A1818181717191A19191A1D13 +:10C2900022201E1E1D1B1717181818181B1B1B20E9 +:10C2A0001F1E1C1C1B191918171819191A1B1B1DE6 +:10C2B000221F1D1C1B1B1716171919181B1B1C21CD +:10C2C0001E1B1B191A1817161717181A1A1A1C1ED4 +:10C2D00022201F1E1C1B1917171718181C1D1D21A3 +:10C2E0001C19181A19181817161718191A1B1B1CBD +:10C2F000201D1D1C1B1A1917151617181B1C1D1D98 +:10C300001D1B1A1A19181617171818191A1B1B1E95 +:10C31000211D1E1C1A1A1918181A1A181B1B1C1F6B +:10C320001B1A18171918171616161717171A191B8C +:10C330001C1B1A1C1A19181816171919191B1B1C63 +:10C340001B1A181918171716161719191A1B1B1D5F +:10C350001C1A19191A1918171819191A19191B1E44 +:10C360001C1A18181817161617161718191A1A1B48 +:10C370001D1C1A1A1B191A18181918191A1C1C1E18 +:10C380001B1917181716151415161718191A1B1B31 +:10C390001C1919191918181717181718181B1C1E0B +:10C3A0001B191817171616151516161719191A1B13 +:10C3B0001D1B191A1A19171716181718171C1C1EE7 +:10C3C0001A181718171615141515161817191A1CF8 +:10C3D0001E1C1B1A1918171716171616171B1C1DCB +:10C3E0001A1817181715141415161716181A191BDA +:10C3F0001C191B19191817161718171618191C1FAE +:10C400001C1A191816161415141416161618191CB9 +:10C410001A1A1818181715151717161518181A1E9E +:10C420001B18181615151513141416151616181BA7 +:10C430001C1A1819191716161717171817181A1E75 +:10C440001E18161615151414131415161717181B85 +:10C450001B191819191717161516171617181B1F59 +:10C460001917161615151413131415161616181A6F +:10C470001A181919181617151515171819171B1C3E +:10C480001B191716151413131514151616171A1C45 +:10C490001D1A191817161615161717171A171C1F15 +:10C4A0001B19171715151414151416161616181B24 +:10C4B0001D1B19181717161515171718191C1B1EF1 +:10C4C0001918161614141212131415161717191C0E +:10C4D0001B1918171615151415151618191B1D1DDF +:10C4E0001917161615141313141415161617191BED +:10C4F0001C1B181917161614151516171918191CC0 +:10C500001A18151515141212131314151516181BD5 +:10C510001C1A1917161615141415161618181A1EA3 +:10C520001B17151414121312131415151617181BB4 +:10C530001B19191716161514151517171818191D84 +:10C540001816141414131212131415151517171B9B +:10C550001C1A1818161514141515161716171B1C67 +:10C560001816141414131212141313151515171981 +:10C570001A18161615151313141515161817181B57 +:10C580001A17151413131212121314141517171A5D +:10C590001B1A1716151514131515151617181B1B2E +:10C5A0001716161414121212121313141415171A44 +:10C5B0001A171716151414131415151517171A1E14 +:10C5C0001917151313121211121313141516171924 +:10C5D0001A1816151515141313141415171A1A1CF6 +:10C5E000181614131313121212131413141416180A +:10C5F0001A171615151515131415171518171A1DD2 +:10C6000018171513131211121212121314141619EB +:10C6100019171615141313131414141518171C1DB9 +:10C6200018171512121211111213131314161719C9 +:10C630001A17151514141313131415151519191B9E +:10C6400017161313121211121212121313141618B2 +:10C6500019171614131414121313141416171B1C81 +:10C66000171614131312121112131313141416198C +:10C670001B17161515141412131414141617191C5D +:10C680001715141312121111111213131314151874 +:10C6900017151514141312131315161416191B1C41 +:10C6A0001614131212111011121313131514151856 +:10C6B0001A16151414141312111212131414171C31 +:10C6C0001614131211111010101011111313141746 +:10C6D0001816151414131212121313141615181A0F +:10C6E0001413131011100F1010111111111314162F +:10C6F00016151514131312111313131314151619F9 +:10C70000141312111210100F10101110111314160F +:10C7100015141313121211111213121213151619E4 +:10C7200006F0F15506F0F15506F0F15506F0F15519 +:10C73000402C2B2B2A2F2F2C2C34333131313134F8 +:10C740003040322F2E2C2B2A2B2C2C3131302F31F4 +:10C750003231322F322C2C2C2B2B2B2C2C313331F1 +:10C7600030333131312E312B2C2C2B2B2A2B2B2FEC +:10C77000312F2F302F2F2F2F2F2C2B2A2A2A2A2BE5 +:10C780002A2E2F302F302F2F2F2C2F2A2A282A2ADB +:10C7900029282A2D3030302F2F30312D2C2C2B2AC8 +:10C7A0002B2B2B2B282F2C2E2F2D2F2E2C2E2C2BC2 +:10C7B0002A292A2B2A2B2A2F302F2F2E2E2C2D2DB3 +:10C7C0002B2B2B292A2B2A2C2B333130312F2F2F97 +:10C7D0002D2B2B2A2A2A29292A282B2D2F2E2D2DA5 +:10C7E0002E2D2C2C2D2B2C2C2D2B2B2C2C2D30307E +:10C7F0002F2E2F2D2B2B2A2B2B2B2A2B2C2D2A3077 +:10C800002F30302F2D2D2C2A2C2A2A292A2A2A2C67 +:10C810002D2F2F2D2E2E2C2D2B2C2C29282A282A5B +:10C820002B2B2C2E2D2B2D2D2C2D2C2A2C29292851 +:10C83000282B2D2C2B2E2E2E2D2D2C2B2C2B292640 +:10C840002928292A2928292B2B2B2C2A2B2A2C2D45 +:10C850002C2A29292828282927292B292B2B2B2B3F +:10C860002A2C2B28272728282A29292C2C2C2C2A2B +:10C870002C2B2C2E2A2A292828292929292B2A2918 +:10C88000282929292B2F2A2A2A2928282A2A29290E +:10C890002928282828282B2C292929282728292B0A +:10C8A0002B2C2A2929292A2A292B292929292929EE +:10C8B0002929292A2929292828292A2C2A292828E6 +:10C8C00029292A2B2A2C292829282A29282C2A2ACE +:10C8D000292928292929292A292928292929292AC8 +:10C8E0002A292728292929292B2A2B2B2A292A2AB0 +:10C8F0002B2C292A29282829282929292A2A282AA3 +:10C90000292A2A2B292A272829282928292827279C +:10C91000292929292A2C2529282726272828272894 +:10C92000272827272827282A28282729272827298A +:10C930002926282A29282728272B2728272626277B +:10C9400026262627272626242727272B262928267A +:10C95000262728272725292628262627282A272963 +:10C960002827272727272827262527262627272A57 +:10C970002727272627272827282628262726262749 +:10C980002829262726262524262627272626252544 +:10C990002627272A25272626262626262625252534 +:10C9A0002525252526274025262524252526272615 +:10C9B0002523242525252640402A2D2D2E2E2F2CBB +:10C9C0002C313230303231343240302F30312E2F52 +:10C9D0002E2E2D323131323232343332312E2F2E4F +:10C9E000302E2B2D2C3230312F333334342F332F44 +:10C9F0002F2C2C2C2B2C2B3231303132343435313E +:10CA0000302E2F2E2E2D2D2C2C313331323432322C +:10CA1000312F312D2C2D2E2D2C2C2D2F333030302D +:10CA2000323233302D2F2F2F2D2F2E2D2D34313309 +:10CA3000353333322F2E2E2D2F2E2E2E2E2C2F31FE +:10CA4000313032323230302E2D2D2E2E2D2F2C2DF6 +:10CA50002F323230323231302F2D2F2E2E2F2F2EDB +:10CA60002E2E2F32313231313030302F2E2F2D2ECD +:10CA70002F2F2D2F2E2F3233323131302E2F2E2DBE +:10CA80002E2E2C2D2F2F3031333231302F2F2D2CB5 +:10CA9000312D2E2C2D2F302F30333031323231309A +:10CAA000302E2F2D2E2F2E2E2E2F2E313330313093 +:10CAB0002F31312D302D2F2F303032333034343070 +:10CAC00030302F2E2E2E2B2B2E2D2E2F2D2D2D2D8B +:10CAD0002F2C302E302D2F31312E2E2D2F2D302F6B +:10CAE000303331323030313231302F2D2D2E2D2E4A +:10CAF0002F2F30343132312F302F2E322F2D2D2D3C +:10CB00002C2E2D2D2D302F2D2F2F2E2E30312D2E42 +:10CB10002E2E2D2E2F2F2F2F2F2E2F2E2F2E2D2F2F +:10CB20002E2D2D2B2C2C303030312F2F2F2F2E2E21 +:10CB30002F312D2E2E2D2E2E2F2E2E2D2E2E2F2D13 +:10CB40002F2D2E302E2D2E2F302F3031312F2D2EF8 +:10CB50002F2D2E2D2C2E2E2E2D2D2E2F2F2E3030F4 +:10CB60002F302D2E2D2E2F2F2E2D2D2E2D2E2E2EE5 +:10CB70002F2D2E2E2E2C2E2D2D302D2D2D2C2D2EDD +:10CB80002E2E2E2E2E2E2F2E2F2F2F2E2D2E2E2DC3 +:10CB90002F302D2F302F2E2C2E2D2E2E2E30282DB7 +:10CBA0002E2B2C2C2D2C2D2C2E2E2D2C2E2D2C2EB8 +:10CBB0002D2C2B2D2C2B2C2D2E2D2D2E2D2C2D2EAA +:10CBC0002D2F2B2E2C2B2B2C2C2D2E2D2C2C2C2AA0 +:10CBD0002E2C2E2D2E2E2E2E2E2F2E2F2E2C2D2C7B +:10CBE0002B2B2E2E2C2D2C2E2D2D2D2D2D2D2F2C77 +:10CBF0002A2B2C2B2B2E2E302B2D2C2C2C2B2C2B74 +:10CC00002E2C2C2C2C2C2D2C2D2E2B2D2D2D2C2C5C +:10CC10002E2C2D2B2B2D2B2C2C2E2C2E2A2D2C2C50 +:10CC20002D2E2D2C2E2D2C2D2D2D2D2C2D2E402D21 +:10CC30002D2D2E2C2C2F32302D2C2F2D2F2C2D4006 +:10CC4000402D3231323334313234343335343538A7 +:10CC500034403032333333313231303133323536A0 +:10CC60003635363533323432323131312F32343396 +:10CC700031363536363534323232313130322F3783 +:10CC80003535353638363735343332323433313260 +:10CC90003034343436353634353434313030323063 +:10CCA000312E313335333435343435343235343450 +:10CCB000353437333335333636363635343532332B +:10CCC0003332323332313435363336353534343429 +:10CCD000303132333233323333363636363635331B +:10CCE00034333134343434353633383534343637FC +:10CCF00037353333323334343534343334363837EC +:10CD000035353636343530323434343534363735DB +:10CD1000353536353534322F3534333334323334D8 +:10CD200035373634353935353734383434343436AC +:10CD30003839373737373537373835313333353496 +:10CD40003435373536373936353735353333302F97 +:10CD50003232333333333135333635343634353498 +:10CD60003432343132343537343535373637373578 +:10CD7000363534313232343335353436363834366C +:10CD80003535353532343436363736363334373355 +:10CD9000323635343436323235353534333735354D +:10CDA000353533383533333434343432343438363B +:10CDB0003636353536353634333334343434353429 +:10CDC000363436353734333634323434333434341D +:10CDD0003536363836363635343636353334333400 +:10CDE0003333353433343435363436363333333500 +:10CDF00035353335333934393635383435363634DC +:10CE000034333434363635353535363333353535D8 +:10CE100035353432343434333635343735373734C6 +:10CE200036393636343430333333333333333333C4 +:10CE300034333435363333353333333537333538AC +:10CE4000363335333335343434342F3535333636A1 +:10CE50003435353533313232333333353335343499 +:10CE60003436353433343532343334353334333681 +:10CE7000353436353537343432323434343534356C +:10CE80003335333333353434343435333433343366 +:10CE90003435333437343435353333343332343452 +:10CEA0003335363637343434343637353434363433 +:10CEB000363434343534403D373937393C463935EA +:10CEC0003638333339333340403A353638363736EF +:10CED00034393A373A3A3A3D3D403E3F3F3E3738A3 +:10CEE000373636383837383D3D3A3A3937383A36BA +:10CEF0003635333535383837373C3A3B3B393937B7 +:10CF0000383637363637353A3B38383B3B3A38389F +:10CF100039393938393B363936393D3B3C3B3C3A77 +:10CF20003C38393538383737383536363B38393884 +:10CF3000383A3938353A393A393B3837353E393F5E +:10CF40003A3C3D3B383A373739393A38383A373A4C +:10CF50003A393C3B3C3C3A3834373837393B38383F +:10CF6000373A3C3D3C3E3E3C3A353739393B39391E +:10CF700037383B393B393B3E3B3B393A3739393B14 +:10CF8000393A3A3B3D3A3F3D3D3B3C3B393A3539F6 +:10CF9000393A3A3A3938393A3C3C3B3C3C3A3736F4 +:10CFA0003A39393A38393A3A3F3A3C3B3C3C3B3CD7 +:10CFB00039383B3A393C3A3D3A3B3D3C3C3D3B3DC0 +:10CFC0003E3B3C363A393C3A393C3C3B3D3A3C3AB4 +:10CFD0003D3B3D3D3C3A34373B393B3B39393839B1 +:10CFE0003B3B3B3C3E3B3A383A393A3A3B383738A0 +:10CFF000383B3B38393B3E3B38393A383A393A3896 +:10D00000373A3C3C3B3D3D393D3C383A393B3B3A75 +:10D010003C3D373A3A3A3A3A3B3D3C3C3C3A393A65 +:10D020003B3C3B3A393C3C3B3A3B3D3B3E3A3B3A4E +:10D03000393A3A3A383C3B3E3D3C3B3C3C3C3D3C3B +:10D040003B3A393C3D3B3B3E3A3C3A3C3A393C3B2F +:10D050003B3A3B3A3C3A3B3C3A3A3B3D403C3D3E16 +:10D060003B3B3D3A3A3A393A3B3B3A3A393A393A1C +:10D07000393A3B3E3C3C3B3B3C3C3A393B3B3A3CFF +:10D080003D3E393C3C3B3D3C39393B3B3D3D3B3BE8 +:10D090003A3B3D3A3A3A3B3B3B3A3B373B3A3B3BE8 +:10D0A0003E3B3A3D3A3B393B3C3B3E3C3A3B353DCF +:10D0B0003C3839383A39363C3C3A3C3C3D3B3B3CC9 +:10D0C0003A3B3A3B3A393B393D393A3E3C3B3A3CB4 +:10D0D0003B39373D3B3B38393A383B3A38383C3AB4 +:10D0E0003E3A3A3A373E3D3C3C3C3C3F3B3B3C3B86 +:10D0F0003A3A3D3B3B3C3A3E3C3D3C3B3D3C3B3D74 +:10D1000039393B3B3B3B3C3D393B3C393E393C3C70 +:10D110003D3B3A3C3C3A3C3D3B3A3A3D3A3D3B385C +:10D120003E393D3C3B3D3C3C3C3D3B3A393D3F403C +:10D130003F3E3D3C3E3B3B3C3E3F3F3D3D3B404117 +:10D14000404444474041403F3E3D3D3D413F3D40DE +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000004806108000488610800048061F800044 +:10D3C00048861F800048061180004886118000486A +:10D3D000061E800048861E8000480612800048868F +:10D3E00012800048061D800048861D8000480613F4 +:10D3F0008000488613800048061C800048861C80F8 +:10D40000004806148000488614800048061B8000EF +:10D4100048861B8000480615800048861580004815 +:10D42000061A800048861A80004806168000488642 +:10D4300016800048061980004886198000480617A3 +:10D4400080004886178000480618800048861880AB +:10D4500020001904902000320887200032C8802064 +:10D4600000325882200032E8832000327885200084 +:10D470003208872000196890200019889320000244 +:10D48000F44B200002044C200019F89120001918D8 +:10D4900095200002F44B200002044C20001938981B +:10D4A000200032A8962000326890200032F89120A7 +:10D4B000003288932000321895200032A896000090 +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D540000100EE020201060A6400283246000000D3 +:10D5500000000000000000003C0000004006000049 +:10D5600034080000A0A0010101011900010014000D +:10D5700001001600A5000A000014780000327800AF +:10D580000000002032323232323232323232323223 +:10D59000323232323232000000000000000000005F +:10D5A0000000000000000000D007D0072C010000A0 +:10D5B0000203200019450000F16C000084D9060028 +:10D5C00029B1010010270000C409000000014B0F21 +:10D5D00000000000000000003C3C0A0A02000000BD +:10D5E0000000000001010101010040003200E803D9 +:10D5F0000F0008000A0009000000030402000300F5 +:10D6000003000A0008006400E803000004000000B2 +:10D6100000000000000000000101010101004000C5 +:10D620003200E80314000F000A00E10000000808BF +:10D630000A0028001E001E0008006400E803000025 +:10D640000400000000000000000000004006300060 +:10D6500020000100220000003A00520070008F00FC +:10D66000AF00CF00EF000F012E014F016E018E01C0 +:10D67000AD01CE01EC010F022D024D026D028D02B3 +:10D68000AC02CC02EB020B032B034A036A038903AF +:10D69000AA03C903E703FF033704000000000000EA +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000F6090A +:10D72000300046000100480000003C004300660055 +:10D730008500A900C800E90009012A0149016B011F +:10D740008901AB01C901EB0109022B024A026C02FB +:10D750008A02AC02CA02EC020B032D034B036D03D9 +:10D760008B03AE03CB03EE030C042F044C046F04B5 +:10D770008B04AF04CC04EF040D0530054D05700596 +:10D780008D05B005CD05F1050D0630064E06720675 +:10D790008E06B106CE06F2060F0732075007730752 +:10D7A0009007B307D107F407110834085208750829 +:10D7B0009108B108C608E70800000000000000005A +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F000000000000600070009000A000C000E00EF +:10D800001100140018001C00200026002C0033001A +:10D810003B0044004F005B006900780089009D00D8 +:10D82000B200CB00E600040126014B017401A10106 +:10D83000D201090244028502CB0217036903C20325 +:10D8400022048804F5046A05E6056906F4068707DC +:10D850002008C1086909180ACE0A890B4B0C110D62 +:10D86000DC0DAB0E7E0F531029110112D812AE132E +:10D87000811452151E16E416A5175D180D19B3195B +:10D880004F1ADF1A621BD81B401C991CE21C1C1D7E +:10D89000461D5F1D671D0600070009000A000C00F9 +:10D8A0000E001100140018001C00200026002C009F +:10D8B00033003B0044004F005B00690078008900A2 +:10D8C0009D00B200CB00E600040126014B0174016B +:10D8D000A101D201090244028502CB0217036903A8 +:10D8E000C20322048804F5046A05E6056906F40605 +:10D8F00087072008C1086909180ACE0A890B4B0C52 +:10D90000110DDC0DAB0E7E0F531029110112D81230 +:10D91000AE13811452151E16E416A5175D180D19C5 +:10D92000B3194F1ADF1A621BD81B401C991CE21C4A +:10D930001C1D461D5F1D671D0600070009000A002B +:10D940000C000E001100140018001C00200026001E +:10D950002C0033003B0044004F005B00690078005E +:10D9600089009D00B200CB00E600040126014B01B6 +:10D970007401A101D201090244028502CB021703FE +:10D980006903C20322048804F5046A05E6056906F2 +:10D99000F40687072008C1086909180ACE0A890B0E +:10D9A0004B0C110DDC0DAB0E7E0F53102911011223 +:10D9B000D812AE13811452151E16E416A5175D1861 +:10D9C0000D19B3194F1ADF1A621BD81B401C991C82 +:10D9D000E21C1C1D461D5F1D671D06000700090097 +:10D9E0000A000C000E001100140018001C0020009A +:10D9F00026002C0033003B0044004F005B00690010 +:10DA0000780089009D00B200CB00E60004012601E9 +:10DA10004B017401A101D201090244028502CB022B +:10DA200017036903C20322048804F5046A05E605A6 +:10DA30006906F40687072008C1086909180ACE0A92 +:10DA4000890B4B0C110DDC0DAB0E7E0F5310291101 +:10DA50000112D812AE13811452151E16E416A51722 +:10DA60005D180D19B3194F1ADF1A621BD81B401C21 +:10DA7000991CE21C1C1D461D5F1D671D29002F00FF +:10DA800035003B0043004C0055005F006B00780000 +:10DA900086009500A600B900CD00E300FC00160149 +:10DAA0003301520174019901C001EA0118024902CF +:10DAB0007D02B602F10231037503BC030804580469 +:10DAC000AD0406056305C5052B0696060507780710 +:10DAD000EF076B08EB086E09F4097F0A0C0B9B0B30 +:10DAE0002E0CC20C580DEF0D870E1F0FB80F4F10E4 +:10DAF000E6107B110E129E122B13B4133814B814B7 +:10DB00003315A71516167D16DD1635178517CD1793 +:10DB10000B1841186D189018A918B718BC182900CF +:10DB20002F0035003B0043004C0055005F006B00A8 +:10DB3000780086009500A600B900CD00E300FC0047 +:10DB400016013301520174019901C001EA01180262 +:10DB500049027D02B602F10231037503BC030804D9 +:10DB60005804AD0406056305C5052B069606050792 +:10DB70007807EF076B08EB086E09F4097F0A0C0BB6 +:10DB80009B0B2E0CC20C580DEF0D870E1F0FB80FFC +:10DB90004F10E6107B110E129E122B13B413381483 +:10DBA000B8143315A71516167D16DD16351785170B +:10DBB000CD170B1841186D189018A918B718BC1874 +:10DBC00029002F0035003B0043004C0055005F004A +:10DBD0006B00780086009500A600B900CD00E30038 +:10DBE000FC0016013301520174019901C001EA01E0 +:10DBF000180249027D02B602F10231037503BC032B +:10DC000008045804AD0406056305C5052B069606F1 +:10DC100005077807EF076B08EB086E09F4097F0A20 +:10DC20000C0B9B0B2E0CC20C580DEF0D870E1F0F0B +:10DC3000B80F4F10E6107B110E129E122B13B41367 +:10DC40003814B8143315A71516167D16DD163517BA +:10DC50008517CD170B1841186D189018A918B7180B +:10DC6000BC1829002F0035003B0043004C00550034 +:10DC70005F006B00780086009500A600B900CD001B +:10DC8000E300FC0016013301520174019901C00147 +:10DC9000EA01180249027D02B602F102310375035E +:10DCA000BC0308045804AD0406056305C5052B062E +:10DCB000960605077807EF076B08EB086E09F4096D +:10DCC0007F0A0C0B9B0B2E0CC20C580DEF0D870E10 +:10DCD0001F0FB80F4F10E6107B110E129E122B1360 +:10DCE000B4133814B8143315A71516167D16DD169F +:10DCF00035178517CD170B1841186D189018A918EE +:10DD0000B718BC185500550045004200000000003F +:10DD10001C023702540272029002B002D102F302D6 +:10DD200016033A035F038503AC03D503FF032904FD +:10DD300055048204B004DF040F0540057205A505F3 +:10DD4000D9050E0644067A06B206EA0622075C07E3 +:10DD50009607D0070B0847088308BF08FB08370958 +:10DD60007409B009ED09290A650AA10ADC0A170B32 +:10DD7000510B8B0BC30BFB0B330C690C9E0CD20CA1 +:10DD8000040D360D650D940DC10DEC0D150E3D0EF7 +:10DD9000630E870EA80EC80EE60E010F1B0F320F82 +:10DDA000460F590F690F760F820F8A0F900F940F4D +:10DDB000950FBA04C904D804E704F6040505140550 +:10DDC00023053205410550055F056E057D058B0570 +:10DDD0009A05A805B705C505D405E205F005FE05B9 +:10DDE0000C0619062706340642064F065C0669062D +:10DDF000760682068F069B06A706B306BE06CA06EF +:10DE0000D506E006EB06F60600070B0715071E070A +:10DE1000280731073A0743074C0754075C07640794 +:10DE20006C0773077A07810787078D0793079907A0 +:10DE30009E07A307A807AC07B107B407B807BB073D +:10DE4000BE07C107C307C507C707C807C907CA0771 +:10DE5000CB07CB07FA006C00FA006B006400D00718 +:10DE6000000028000000000000000000000000008A +:10DE700000000000000000000000000000000000A2 +:10DE8000190050003C000F001E00000001000000BF +:10DE900001000000948D0300508D0300948D030059 +:10DEA000548D030001000000785634127856341265 +:10DEB0000100000001000000DC0000004040000004 +:10DEC0000100000070AD0200FFFFFFFFAA0000008C +:10DED000103303000700000001000000FFFFFFFFF8 +:10DEE000FFFFFFFFFFFFFFFF010000000000000039 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F0000003FC20324006000A0E0A0001030108102A +:10F0100032004006F6090000000C0100000000006C +:10F020000013535904060000000000000008010905 +:10F0300000013233400600002819190000000800C2 +:10F0400000000800000008000000080000000800A0 +:10F05000000008000000080000000800F0EF0000B9 +:10F06000000008000000080000000800F0EF0000A9 +:10F070000000080000000800000008000000000078 +:10F08000000101000000000000000000000000007E +:10F09000000000000000000000000101010101006B +:10F0A000000100000000010101010001000000005A +:10F0B000010000010000000007000000010701033B +:10F0C000020314000A0A40000000C8003C000000CF +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000C800C8009600C80032 +:10F0F00007078000800005050000000000000000F8 +:10F1000006010000000017003900910010001400F3 +:10F11000F9FFC4FFFF7FFF7FFF7FFF7F50002C01BF +:10F120003200FA000A04B4B43232230500000000B1 +:10F1300000070D0000320D00000000203232323294 +:10F140003232323232323232323232323232000003 +:10F1500000000000000000000000000000000000AF +:10F160000A05000A00000000170F0012101200002C +:10F17000000000000000000000000000000000008F +:10F18000000000000F2332465000000078643C3C31 +:10F190003C3C3C3C08000000000000000F233246CD +:10F1A0005000000078643C3C3C3C3C3C0F141E2862 +:10F1B000000000000A0A0A0A0A0A0A0A19460000A0 +:10F1C000000000003746464646464646000000001E +:10F1D0000A0314005F00F1FF14000F000A00BC02D4 +:10F1E00000000000F8FF0000DC003200640028008E +:10F1F0000F000F001C023D011C02740400003F06BA +:10F200000000FF09F40100003F060000FF0932146E +:10F21000021E1E3202006400460046007700C80548 +:10F22000770088090000000040063000200001003F +:10F23000220000003A00520070008F00AF00CF00A3 +:10F24000EF000F012E014F016E018E01AD01CE01C5 +:10F25000EC010F022D024D026D028D02AC02CC02B8 +:10F26000EB020B032B034A036A038903AA03C903B6 +:10F27000E703FF0337040000000000000000000067 +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F00000000000000000000000F6093000460099 +:10F300000100480000003C00430066008500A900A1 +:10F31000C800E90009012A0149016B018901AB011B +:10F32000C901EB0109022B024A026C028A02AC02FB +:10F33000CA02EC020B032D034B036D038B03AE03D8 +:10F34000CB03EE030C042F044C046F048B04AF04B6 +:10F35000CC04EF040D0530054D0570058D05B00595 +:10F36000CD05F1050D0630064E0672068E06B10675 +:10F37000CE06F2060F073207500773079007B30750 +:10F38000D107F40711083408520875089108B1082C +:10F39000C608E708000000000000000000000000B0 +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D0000201200019450000F16C000084D90600EC +:10F3E00029B1010010270000C40900000000030338 +:10F3F000030505050505014B0F00F00000000000A6 +:10F40000010000030303050505050500194500007B +:10F410000200000084DE01000000000014140A0A4B +:10F420001400000000000000141414140101010174 +:10F43000010040003200E8030F0008000500E10071 +:10F4400000001E502800B40050000400000000001E +:10F45000B40050006400A000000000014F01000053 +:10F460000000000078000D0D0A09320064006400FD +:10F470000A003200C800640064000F02E8E8F800E7 +:10F48000F8000200190000006A00750081008E007B +:10F490009D00AC00BD00CF00E200F7000D01260189 +:10F4A00040015C0179019901BC01E00106023002D2 +:10F4B0005B028902BA02EE0224035D039A03D903B8 +:10F4C0001B046004A904F40443059505E9054106FD +:10F4D0009C06FA065B07BE0724088D08F808650934 +:10F4E000D409450AB80A2D0BA20B190C900C080D73 +:10F4F000800DF80D6F0EE60E5C0FD00F4210B310AA +:10F5000021118C11F4115912BA1217137013C4136C +:10F5100013145D14A114E01418154B1577159C15E0 +:10F52000BB15D415E515EF15F31536003D00440065 +:10F530004C00560060006B00770085009300A4002B +:10F54000B500C900DE00F5000E0129014601650184 +:10F550008701AC01D401FE012B025B028F02C602BF +:10F5600001033F038003C6030F045D04AE040305DB +:10F570005D05BA051B068106EA065707C9073D085F +:10F58000B6083109B009320AB70A3E0BC70B520C54 +:10F59000DF0C6D0DFC0D8B0E1A0FA80F3610C3106B +:10F5A0004D11D6115B12DE125C13D7134D14BD142E +:10F5B00028158D15EC1544169516DE161F175817CD +:10F5C0008917B117D117E717F517FA174E0056002C +:10F5D00060006B00760083009100A000B100C200C3 +:10F5E000D600EB0002011A013501520170019101B0 +:10F5F000B501DB0103022E025C028D02C102F8029A +:10F6000032036F03B003F4033B048604D4042605DD +:10F610007C05D50532069206F5065C07C607330859 +:10F62000A30816098C09040A7E0AFA0A790BF80B5A +:10F63000790CFB0C7E0D010E830E060F870F071051 +:10F64000861003117D11F5116912DA124713AF13F9 +:10F6500013147214CB141E156B15B215F2152C165B +:10F660005E168916AC16C716DB16E716EB164E00AB +:10F67000560060006B00760083009100A000B1008E +:10F68000C200D600EB0002011A01350152017001DF +:10F690009101B501DB0103022E025C028D02C10261 +:10F6A000F80232036F03B003F4033B048604D4046E +:10F6B00026057C05D50532069206F5065C07C607C9 +:10F6C0003308A30816098C09040A7E0AFA0A790B82 +:10F6D000F80B790CFB0C7E0D010E830E060F870FC5 +:10F6E0000710861003117D11F5116912DA12471304 +:10F6F000AF1313147214CB141E156B15B215F2153B +:10F700002C165E168916AC16C716DB16E716EB1616 +:10F7100055005500450042000000000000000000B8 +:10F7200000000000000000000000000000000000D9 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000000000099 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F86000000000000000000000000000F000220185 +:10F8700054013C00050000000000000000000000F2 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF000000000000000000000000000004E565409 +:00000001FF diff --git a/firmware/novatek_ts_mp.bin.ihex b/firmware/novatek_ts_mp.bin.ihex new file mode 100644 index 000000000000..db1751c4a538 --- /dev/null +++ b/firmware/novatek_ts_mp.bin.ihex @@ -0,0 +1,12291 @@ +:100000000002000000000000EF6601000020020076 +:1000100000000200DFBE0000A1F36FFED09D2DF3B3 +:1000200003000000000000000000000000000000CD +:100030000000020000000000002002008379472A2F +:10004000000A020000000000002A0200CB94D02029 +:100050000032020000000000005202000C52006852 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F000E0BE0200FF00000000000000FB2C483DB5 +:100100000002000000000000EF6601000020020075 +:1001100000000200DFBE0000A1F36FFED09D2DF3B2 +:1001200001000000000000000000000000000000CE +:100130000000020000000000002002008379472A2E +:10014000004A020000000000006A0200AF0FDC1548 +:100150000072020000000000009202000C520068D1 +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F000E0BF0200FF000000000100004A64D3E9F4 +:10020000480001A2EAB30000EAB30000EAB300002C +:10021000EAB30000EAB30000EAB30000EAB300006A +:1002200048000000DD4D0000EAB20000EAB2000024 +:10023000DD4D0000EAB20000DD4D0000DD4D0000A4 +:10024000DD4D0000DD4D0000DD4D0000DD4D000006 +:10025000DD4D0000DD4D0000DD4D0000DD4D0000F6 +:10026000EAB20000EAB20000DD4D0000DD4D000002 +:10027000DD4D0000EAB20000EAB20000DD4D0000F2 +:10028000DD4D0000DD4D0000DD4D0000DD4D0000C6 +:10029000DD4D0000DD4D0000DD4D0000DD4D0000B6 +:1002A000DD4D0000DD4D0000DD4D0000DD4D0000A6 +:1002B000DD4D0000DD4D0000DD4D00004800000078 +:1002C00048000000DD4D0000DD4D0000DD4D000068 +:1002D000DD4D00004800000048000000480000001C +:1002E00048000000480000004800000048000000EE +:1002F00048000000480000004800000048000000DE +:1003000048000000480000004800000048000000CD +:1003100048000000480000004800000048000000BD +:1003200048000000E4040000E4040000540700005A +:1003300028120000281200002812000028120000D5 +:1003400028120000281200002812000000000000FF +:10035000120900001A09000054090000CE0900002B +:10036000160A0000940A0000F40A0000120B0000B4 +:100370001A0B0000220B00002A0B0000320B0000B9 +:10038000440B00004C0B0000580B0000AA0F0000AB +:100390006A0B0000FC0B0000440C00004C0C000039 +:1003A0008A0C00009C0C0000AE0C0000D40C000075 +:1003B000580D0000D40D0000DC0D0000EE0D000013 +:1003C0007C1000007E100000A2100000AA100000A7 +:1003D000B2100000C2100000C4100000D0100000D5 +:1003E000DE100000FA100000000000000000000015 +:1003F000601100007C110000C81100000A1200000A +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:100450003A0FEFFC421E80203A1F883C6412A4022F +:10046000642204023A1F883C803F640264029205C1 +:1004700096374420012C38210202643200029ED9B2 +:1004800064320003DD2264020043640000083A1F66 +:1004900088046412A403642204033A1F8804421EE1 +:1004A00080213A0FEFC4640000043AFFECBC3A0F1D +:1004B000943C421E80203A1F883C640264029205EC +:1004C00096374420012C382102028E09DD223A1F82 +:1004D0008804421E80213A0F94043AFFEC846400A1 +:1004E00000043AFFECBC3A0F943C421E80203A1FB5 +:1004F000883C6412A402642204023A1F883C64020D +:100500006402920596374420012C382102028E099C +:10051000643200029ED964320003DD22640200438B +:10052000640000083A1F88046412A40364220403D0 +:100530003A1F8804421E80213A0F94043AFFEC844B +:10054000640000044FF200223A0FEFFC421E8020AC +:100550003A1F883C45D2D468801F64126402965FBB +:100560009E49C1053CFD4B2F480000043CFD4B302B +:10057000E80CDD2F4E03000A3A1F8804421E80213A +:100580003A0FEFC464000004640224024410C00067 +:10059000FE0FFE0D640224036400000845D2D468F7 +:1005A00045F2FE006400800292189604C0054401E2 +:1005B0003890420E002144F004B6E802DD2F3CFDE5 +:1005C0004B31DD2F640FFFEAFC004462EA5C440219 +:1005D000C0E084209AB0EA4CEA42AE31FC80FC00D4 +:1005E00084003C0FFB96EBC03C0FFBA53C0FFBA926 +:1005F000EBB93C0FFBBA3C0FFB9F3C0FFBAA3C0F37 +:10060000FBA63C0FFBB23C0FFBA73C0FFBA33C0F30 +:10061000FBA03C0FFB993C0FFBB83C0FFBBD3C0F14 +:10062000FBB03C0FFBB13C0FFBAE3C0FFB94EAEF81 +:100630003C0FFBA83C0FFB9EEB08EA9A3C0FFB9B90 +:100640003C0FFB9D3C0FFBBC3C0FFBAFEBE33C0FB7 +:10065000FBA43C0FFB9A3C0FFBAC3C0FFB9CEBA6B6 +:100660003C0FFBB33E07ECFA64030003EA7AEB515C +:1006700064122402964C8040C10364030003642288 +:1006800024036402000266000006640200036400A2 +:1006900000086403040246029C105000007CEA7AC1 +:1006A0006403080244000633EB5164020002EA4D81 +:1006B00064020003FC804403F0EDA6405A180104D4 +:1006C0008420AE404413F0DAA608EB17AE08840489 +:1006D000EA7A84254403F049AE4044100053DD45D6 +:1006E000AE40DD9EDD9E4443F114B4649278400038 +:1006F0000F04B6044403F138AC4084204403F13ABB +:10070000AE404403F104B64084214403F136AE40C8 +:10071000F808A640964CC103AED0D5FC4413F13482 +:10072000EA39EA3883FFA608960EC803AED0D5FC96 +:100730004403F134A6009604DD9E84A0D20738302D +:100740001400383094088CA1D5FADD9EFC00DD4100 +:10075000C00C8407DD498400DD494412BFE08402F7 +:10076000804144300100DD44FC80FC0080C0DD415C +:10077000C012441FFF9FEB94AE4096304412FE61BE +:10078000AE08EB544412FE62AE08DD45DD46C603FA +:10079000AE40D5FEFC80FC403C7DFB6D8140DD41E0 +:1007A000C05B852384C03C2DFB6D40212480A0517B +:1007B000C108F85C5A0801064010240CFF8F97B15D +:1007C0008D215A980FF2F85F5A08010442633C08E1 +:1007D0008387B97DB87C8E249649BA7FF85C5A0825 +:1007E000010558630001D502C6055AA8AE0480066B +:1007F000F8118420EB10AE404402FE63A640842032 +:10080000AE40A681AE4149000DF15A0801065803D9 +:10081000000249FFFFACEA67EA28EA22A78097B006 +:100820005A600204AE88D5FB4472FEF1A6385A0025 +:100830008608440000C1DD43F87FAE40D5FF490083 +:10084000350A84003E07EEED802780064422C3551A +:100850008461DD44FCC05AA8AE4B84E380C03C2DCB +:10086000FB6D40211C80A051C10BB4029649A0939E +:10087000F8125A08010640001C0CFF8797B18CE162 +:100880005A780FEF3C2DFB6D8382B93DB83C8E2426 +:100890009649BA3F49FFFF295A080105EA644263B5 +:1008A0003C0884204402FE78AC404412FEF1EA6722 +:1008B000C619442FFFEEAE888422AE404412FE607B +:1008C000440FFF8FAE084422FE619630AE10EB5409 +:1008D00096004422FE62AE10846380418402DD44AF +:1008E000D520442FFF86AE888422D507441FFF867B +:1008F000EB10AE408422EA67AE404403F007A60046 +:100900004412FE639600AE084403F004A60044229D +:10091000FE649600AE10840280418060DD4484C095 +:100920004412FEF1804184618402DD44EA27804163 +:1009300084028461DD44DD45DD4683FFC603AE40AD +:10094000D5FE4412FEF1EA39EA38A608C003AED05B +:10095000D5FDFCC03A6FA0BC84008020490063D064 +:1009600084006405E403EB82A44096669649C102C4 +:10097000D5004422FEF6AE50A440964EC910A440C5 +:100980009656C90DA440965EC90AA4409666C9074A +:10099000A4405410810096494E1200854413F00E75 +:1009A000A408960EC806A5885463010097B1C62016 +:1009B0008400EAA5A788AC0844138D203E07ECA666 +:1009C000AE0844138D21AE0844138D22AE084413A3 +:1009D0008D23AE0844138D24AE0844138D25AE0834 +:1009E00044138D26AE0844138D2797B0AE0849FFF7 +:1009F000FDED49000B94EB82A440964EC908A4403B +:100A00009666C905A40054000100C003490032598C +:100A1000EB948420AC404472BEE08400EA9A3C7FB0 +:100A2000FB6DEB083C0FFBB4DD41C8055073810042 +:100A30003C7FFB6D49FFFE8C800649FFFEAE8423A0 +:100A4000EA67AE4084014413F7D3AE084413F7D9E4 +:100A5000AE08FA56EA994412FE7849FFFE703C0D42 +:100A6000FB6D4432FE7C040000093E072BB54010AC +:100A700020093E172BB64010400992183E172BB79D +:100A80003E072BB84422FE7DF8054432FE7E442208 +:100A9000FE7FA618A6509602964AAE58AE1083FF67 +:100AA000D508A40054000200C004840249000D3996 +:100AB0004413F029A608EAD3AE088400EA663C0D88 +:100AC000FA8B4413F00EA648EB714413F00FA648BE +:100AD0001010003D4900325F3C0FFB7BFA04F80226 +:100AE000FA0449004EF62E07EDECDD49EA479E81F7 +:100AF000E648E80B84214010880C5410808FC10513 +:100B000050007FE09600DD43490004B83A6FA084AE +:100B1000DD9E84013C0FFB96DD9E3BFFFEBC3C0D41 +:100B2000FBA18C01EBC02E07EFCE5A0801123C1D31 +:100B3000FBA12E07EFCDE220E8044900644FD50861 +:100B4000EBDE84004900626584003E07EFCE3BFF88 +:100B5000FE84DD9E3BFFFEBC3C0DFBA58C013C0FE3 +:100B6000FBA5DD40A6008E01E602E82D2E07ECABCA +:100B70005A08550A3C03F68B8C019601E60AEB975E +:100B8000E91DD508DD41C0182E07ECA15A085515FE +:100B9000D5F28404DD4384013E07F01A8400EA2E76 +:100BA000DD40A6005A080105EAA0EA69D5078E02D1 +:100BB000E602E900D5038400EB97EA453E07ECAB7B +:100BC000EA88D5038400EB973BFFFE84DD9E3A6FF5 +:100BD00098BC4403F06BA6003E07ECF8DD47C8065E +:100BE0002E07ECF8961F5A000F16FA10DD43840109 +:100BF0003C0FFBA9EBBD490067F8DD408422DD56C0 +:100C00004900680B8420840284468061808180A131 +:100C1000DD53EA25DD9E3A6F9EBC4900632CC01669 +:100C200084004900632CF82180C05A080110DD4778 +:100C30005A0802043C6FFBA244000080DD43DD4003 +:100C4000EB53EAC0EB998481EBD24900630BC007F8 +:100C500084013C0FFBB58400490063084900633BF5 +:100C6000C00F84004900633B4900638780805A08B5 +:100C70000108EA9AEB53DD40EAC0EB99EBD2490058 +:100C80006321C0068400490063218401EB083A6FA8 +:100C90009E84DD9E3BFFFEBCDD5984213C1FFBB6DC +:100CA000AE40EA4244238D433E07ECABA6108801D8 +:100CB000AE10DD40A681542100FD5A200403DD560C +:100CC00049006786C00A8409DD43FA18EA2A8403CA +:100CD000EA7E84013E07ECCF2E07EF978C01960049 +:100CE0003E07EF97DD41C80484013E07EF863BFFD6 +:100CF000FE84DD9E3A6F98BC84013C0FFBBAFA116A +:100D0000DD434403F082A600C003EAA0EA69EA25B5 +:100D1000DD9E84013C0FFB9FDD9E84013C0FFBAAFE +:100D2000DD9E84013C0FFBA6DD9E84013C0FFBB2DF +:100D3000DD9E3A6F98BCFA12DD4384013C0FFBA79D +:100D4000EA25DD9E84013C0FFBA3DD9E3A6F98BC33 +:100D5000FA13DD43EA25DD9E3A6F98BCFA14DD43B1 +:100D600084013C0FFB99EA25DD9E3A6F9ABCEFF4B3 +:100D7000490015EB3C0DFBB8EA658C013C0FFBB854 +:100D8000EAB5EAE38C013C0FFBACEAB5EAB19600A8 +:100D9000EB55EB19EA65490012AF3E07ECA9DD41BE +:100DA000C005EBB5C8038401D508DD41C805EBB526 +:100DB00096005A0001038400EB59EB655A08010BB9 +:100DC00084003C0FFB93440124F83C0E0376490059 +:100DD00015723C6DFBB85A68020F3C0DFB9D5A081A +:100DE000010BDD41C80880064413970044238D544D +:100DF000EAFCEACDEC0C3A6F9A84DD9E3A6F98BC1F +:100E000084013C0FFBA43E07EFC44403F07EA640E0 +:100E10005A10010FA6405A10020CA6405A1003099E +:100E2000A6405A100406A6405A101003A60084419A +:100E30008420806280824400B101EAAB49002CB575 +:100E4000EA25DD9E84013C0FFBBDDD9E84013C0F45 +:100E5000FBB04403F064A640964CC910A64058105D +:100E60008001AE40DD40A6008E02E602E90E3A6F38 +:100E700098BCEA45EA69EA25D508A640964CC10522 +:100E8000A640EB0BAE40DD9EDD9E3A6F98BCFA1596 +:100E9000DD4384013C0FFBB1EA25DD9E3A6F98BC2F +:100EA000FA16DD4384013C0FFBAEEA25DD9E3A6F66 +:100EB00098BCFA17DD43FA04DD4984013C0FFB942A +:100EC000490018835A08A104EA45EA698403EA7EC6 +:100ED000EA25DD9E3BFFFEBC8401EBE3EB68441397 +:100EE0008D468C01EAEFA6088C01AE0849000C8CF7 +:100EF000EB65C814DD41C005EBB596005A0001074B +:100F0000DD41C805EBB5C8038401EB5984003C0FF3 +:100F1000FB93440061A83C0E037649000F27DD4196 +:100F2000C015DD5A5A0820132E07EF7CE602E90EA1 +:100F3000EB685A0801084402988CEB05442019001C +:100F4000DD4A8401842049001C9BDD41C80349001F +:100F500015033BFFFE84DD9E3A6F98BCFA18DD4313 +:100F60004403F00AA600DD434403F00DA600DD4370 +:100F7000EB82A600DD434403F00FA600DD434403EB +:100F8000F01AA600DD434403F01BA600DD43440332 +:100F9000F082A600DD434403F353A600DD4344037F +:100FA000F369A600DD434403F386A600DD43440352 +:100FB000F387A600DD434403F3CFA600DD434403DB +:100FC000F40CA600DD4384013C0FFBA8EA45EA6966 +:100FD000EA25DD9E84013C0FFB9EDD9E4403F40365 +:100FE000A60096005A0801043C0FFB9BDD9E84017D +:100FF0003C0FFB9DDD9EFC0084013C0FFB9D8400AB +:101000003C0FFBAC3C0FFB9CDD40A6419E8BE642B7 +:10101000E9055A1006045A180D2EDD54A6485A1830 +:10102000012AEA43EB81C80BEB66C8093C5DFB78FB +:10103000EB9AD0054402C22449006458DD40A60161 +:101040005A0003045A080D17EAF3C814EB81C812BA +:10105000EB66C810DD4FA600C805802044238D41F3 +:10106000D5079E43E622E80644238D41A650490059 +:101070006960DD41C00349000ECFDD57A6095A0063 +:101080000D079E82E642E9035A08072CA6485A1823 +:101090000129EAC19600C841DD54A6485A18013E0C +:1010A000DD58A6485A18013AEAEFEB665A080106DD +:1010B0004402C1484900374C8420DD40DD5684019C +:1010C000EA2EDD548400AE08DD58AE088409EA56E5 +:1010D0008404DD492E07EA24DD498401EA6BD51D2D +:1010E0005A08041C2E67EF8CCE18DD58A6485A10FB +:1010F0000215DD49EAE404000008962FDD49DD40D1 +:101100008026EB0DDD568401EA2EDD59AF80DD4BE4 +:10111000AF8084013E07EF8CEB985A080104490028 +:1011200015D5FC80FC20EAE43C5C004AD0073C5C1E +:10113000004BD004EB815A08010DEAC1C80ADD5901 +:10114000A6009600C806DD58A6885A280103AE08F6 +:101150002E07EC9AC023EB40EB2FD8202E67EC7AB9 +:10116000840097B03E07EC9ACE19DD59A6005A08C4 +:101170000116DD4BA7C097F85A7801118026DD4093 +:10118000EB0DDD568405DD498007EA2EDD59AF8081 +:101190002E07ECCFC803DD58AE082E07EF7CE60221 +:1011A000E8048C013E07EF7CFCA03A6FA6BC490026 +:1011B000070CDD41C8082E07ECFA5A00015E8401D5 +:1011C0003E07ECFA4900379D80C0EA5D8120440368 +:1011D0008D45A6808C41AE80F818C0178401DD498A +:1011E000DD4180E0C0074900082584004900140F54 +:1011F000D50C4412C1E4804184648402DD4480073C +:1012000049001405490006C549003542C00984015A +:101210003C0FFBAD3E07EC7C49FFFEEFD509840295 +:101220003E07EC7C49FFFF80DD59A600F86E840084 +:1012300084E13C7FFBB43C0FFBB82E07ECCAC01323 +:10124000DD41C0060003000F10048051D508840260 +:10125000501480515023000F8067DD448400EBFE62 +:101260001003000FDD41C80349003B2784003E07FF +:10127000ECFA490006D23A6FA684DD9EDD9E3A6FF5 +:1012800098BCFA19DD4384013C0FFBBC49005B109C +:10129000EA8EC804490064A9D50349005AD4EA2556 +:1012A000DD9E84013C0FFBAFDD9E84013C0FFB9A69 +:1012B000DD9E3A6F98BC8403DD498401EA6BEA2520 +:1012C000DD9EDD9E3A6F98BC8401F806EA25DD9E1E +:1012D0003A6F98BC840049000DDFEA25DD9E3A6F25 +:1012E00098BCFA1BDD438400842A49002E53DD415B +:1012F000C003EAA0EA69EA25DD9E3BFFFEBC440389 +:10130000F41CA600E602E81549000D8FDD41C0116E +:10131000DD40A6015A08030E2E07EC93C00A840094 +:101320004412DDAC3E07EC9380418402EABBEACD77 +:10133000DD41C80DEAD55CF000A0E9098402441340 +:1013400058904423806844300C80EACD2E07ECCCC2 +:10135000C0058401EBAD8400EBFB3BFFFE84DD9E0A +:101360003A6F98BC4413F7EEA60896009684C20321 +:10137000EA9CAE088400F855EA25DD9E3BFFFEBCE2 +:1013800084013C0FFBB34413F7EFA6089600968444 +:10139000C203EA9CAE088401F844F828EB655A08B9 +:1013A000010C3C0DFB8FC0068402490008053C0F70 +:1013B000FB8F490012802E07EF86C0048E013E0786 +:1013C000EF863BFFFE84DD9E3BFFFEBCDD475A08F7 +:1013D00002048401EBA64413F7C9A608960096847C +:1013E000C203EA9CAE088400F81C49000B20DD41D2 +:1013F000C80AEABAA600C007DD40EB53EAC0EB9981 +:101400008481EBD23BFFFE84DD9E3A6F98BC44138F +:10141000F7CAA60896009684C203EA9CAE08840127 +:1014200049000753EA25DD9E3BFFFEBC2E07ECFB7F +:10143000C81DB401A6003C0FFC0A640264024412F9 +:10144000FFF03C0FFC09B6013C1DFC0A4402FFF40E +:10145000B62046011223500003444412FFF8B6019F +:101460002E07ECFB8C013E07ECFBFA1ADD43EAA0E9 +:10147000EA693BFFFE84DD9EFC6384003C0FFB8831 +:1014800049003A1D5A00081749003A9D2E07F02CD2 +:10149000441000A08C013E07F02C8403DD42840D33 +:1014A000DD4949003AC8840EDD498403441000A197 +:1014B000DD42B1834492E51644A2C0E1DD414E0213 +:1014C000007DEB74442397EC40110420A4484403AE +:1014D00097D8964BAC403C0C037B441397DA400101 +:1014E0000020A4009603AC08F86849003ADD5A00D1 +:1014F00003CD5A080207840444100060DD42D5C7BA +:101500005A0013DEF86DF8715A0002C25A0013D85F +:10151000F871DD4BA7C097F8CFD22EB7ECF65AB8CA +:1015200001CF8403EB86DD42DD553E77F0225A0879 +:1015300002064900404F3EB7EC9349003BE3DD5AB9 +:101540005A081209EAA38420EADD5A08010484003B +:10155000F82FDD5A5A08040849004216EAADF8C1CE +:10156000F826D5285A081406EAADF8C5F820D52281 +:101570005A081906840080204900198249003C0A53 +:10158000490042F25A08020448FFFF82DD5A5A0815 +:101590000508490041F8EAADF901F809D50B5A08E8 +:1015A000150AEAAD8403441000A9DD42EA4BEA3390 +:1015B000EA46490041C5F9548403EBD5DD424900B0 +:1015C000457780E08401EB7E5A08010448FFFF95CF +:1015D0005A78030448FFFF5A5A781303F9418403E9 +:1015E000441000A3DD42EAEB490044AD5A0813035E +:1015F000F9378403EBCEDD42DD4BA600C807DD40A2 +:10160000A6415A180D048423AE41440000A3EB7D8B +:10161000EB834E03010B2E17EC92440297E849002E +:101620002091F081EB868403DD423C7DFB848007C2 +:1016300049003E465A7805112E07EFED5A08010D74 +:101640002E07EFECC8092EB00E004EB3000649007D +:101650006A903EB7EFED2E07EFEEC83DEA5BC03B68 +:10166000E6E2E8393C0C037E5A000705EA735A08A3 +:1016700009338404EB3E800749003BF0EA5B4E737C +:1016800000F2EA76EA82EA5B5CF00030E9242E1090 +:101690000DE48401EBB8C90684273C1E037EF805DF +:1016A000D50A8407EA538400EB0CEB45EA8283FFFA +:1016B0008405EB3E2E07ECF55A08010EAC3014A35E +:1016C000000214A300013E07EC793A130C00EACBA8 +:1016D00049001059800749003FBBDD5A5A081409D8 +:1016E0008403441000A6DD42F85D4800009DDD5BE8 +:1016F0005A08040A8403441000A7DD4249003B9EB7 +:10170000EB3ED5552EB00E004EB30052E6E2E84354 +:101710008007490040035A78013F8007490040C3D1 +:101720003C0C03783EB7EC858E04E602DD5AE90FE7 +:101730005A00150E3C1C040E5A100503C9058420DE +:101740003C1E0378D50484223C1E03788E14E602E6 +:10175000E90C2E07ECB4C8073C000854C0068E0103 +:10176000EA87D503EB4DEA878400EBAF2E07ECE167 +:1017700096005A00010AEA80C80EEBCB8041EAFCD1 +:101780008402DD44D5083E07EC9F2E07EC9F5A00EB +:1017900001FED5F2DD5A5A08150B8403441000A847 +:1017A000DD423C0DFB72EB2049003CDCF001EBCB51 +:1017B0004422E2644900215DDD5A8E14E602EAB05B +:1017C000E91A2E17ECC2C917C8163C1C03789E8A6A +:1017D000E643E8098402EA375A1803268401EBAF8E +:1017E0008401D5175A180503EA873C100854840170 +:1017F000C91AD50C5A080118EB8A5A1802152E1767 +:10180000EC79C1113C100854C90EEA373E1010AEF5 +:10181000AC301493000214930001EACB3A130C008D +:1018200049000FB18401EAE62E07ECDD5A080512E3 +:10183000DD59A6005A08010EEA805A08090B2E1736 +:10184000EDC82E27ECD72E07ECDD49000B7FF808FA +:101850002E07ECDD5A000603F8038400EAC948FFAE +:10186000FE2FEAA4EA8248FFFF103C0FFC1FDD9E1A +:101870003C0FFC1EDD9E4402B7F43C0FFC0EDD9EC7 +:10188000FC20A5C8B4C097FBE0E63D27F086E80B36 +:10189000A448EAC89A71964BFE544010C8368AC1D3 +:1018A000B6C0FCA0A410B5839603E0060511800124 +:1018B000E812A448EAC88A26964BFE544000C8168F +:1018C0009603FF444022FC0A40581401E385401867 +:1018D0008801D513A5C8A490EBF69ABA9693420155 +:1018E0000424400048169603FF444012FC0A405866 +:1018F0001401E385401884018A2FB6A3A859B44483 +:10190000A06140307C0A9A10E2408A238A2FB604F4 +:10191000A861FCA0FC4180E18123CC09B400C2098C +:101920000260001F0220001E97B3D50CA001CA055B +:10193000A580A48197B3D506026000310220003053 +:1019400097B38026969380074900473A0014800099 +:101950005A10FF058C2188019201EA4F803FB08127 +:1019600049004795B41F38138111F00138238111C4 +:1019700084024000801642030873EB15FCC1FC6131 +:10198000C30A2E47ECBD2E57EC7D5C4200015CC2C1 +:101990008001D50381838083B4A04E5202388EA487 +:1019A000E6A24EF3023480E0A60C8143816280C13E +:1019B000C863CC62EB57C30E3C0DFB79EAE04EF2F4 +:1019C0000232EA3A5A000103F803501082884800B4 +:1019D000022A501085BE5033806E8440800B808276 +:1019E000F9873C933E70F0813C833E904EA20019F3 +:1019F000B42BB0019C8A5043002880A950330010BA +:101A0000F98CA035A0B4944140508BF5F401945169 +:101A10004024A00140048806EBC5FE02D56C3C17AB +:101A2000F4F63C47F4FAFE0CA0B5412012564044AF +:101A30008013945140222001E28252478000A0345A +:101A4000952140920BF541197C0A9491405083F501 +:101A50009441EB344204C873422148698860980A73 +:101A6000EBD4E201986B0433000B885240414806E6 +:101A7000887148000088A6355A001F044800008776 +:101A80004E430085EB574EA200103C0DFB79EAE077 +:101A9000E807EA3A5A0801055010832AF803501063 +:101AA00080A2480001C45010851C5033806E800B0A +:101AB00084418480F91D3C933E8FF0813C833EAF8E +:101AC0004EA20037B44BB0015011003E50430028E5 +:101AD0005021003C80A950330010F91FA035A0B45C +:101AE0009441F40140508BF594514024A000EBC583 +:101AF00040012406940140900BF59491EB3442048C +:101B00009073422110698860980AEBD4E201986BC7 +:101B10000433000B8844404110068871882F886484 +:101B2000EA4E96031203800812038018D53D3C1735 +:101B3000F4F73C47F4FAFE0CA0B5411012364044CD +:101B40008013945140222000E244A034404784088E +:101B500040920BF54128FC0A9491405083F5944142 +:101B6000420908244204C473422144698860980AE7 +:101B7000EBD4E201986B0433000B885140414406DA +:101B80008872882F8864EA4ED50D841F4EA2000704 +:101B90001003806C22038004D5C61003806E0203FC +:101BA000800C1203800EA6364E0300854EC30083C0 +:101BB000EB574EA2000FEA5EEAE0E807EA3A5A085D +:101BC0000105501083CCF8035010814448000133C4 +:101BD000501085BE5033806F800B84408481F8881C +:101BE0003C933E0CF0813C833E3E4EA200350415F2 +:101BF000800180A99C8AB001503300185043003006 +:101C0000F88CA037A1369441402093F5946140446C +:101C1000A00140049006050F8001FE02940140904F +:101C200013F541187C0A9521420890244204C073A0 +:101C30004242406988A0980C403004069855EB4613 +:101C40000453000D88504041400688B1882398E530 +:101C50004800008A3C17F4F83C57F4FAFE0CA0B692 +:101C6000405014B6A0374112FC0A944141008BF554 +:101C700094514024801340412001E24452278000C7 +:101C80009491409113F594A1EB3442049473422152 +:101C900014698860980AEB46E20140180C0004338E +:101CA000000D8845405114068871882F88654800CA +:101CB0000095A6375A003104480000924EC30090A8 +:101CC000EB574EA2000FEA5EEAE0E807EA3A5A084C +:101CD00001055010846EF803501081E6480000AFF3 +:101CE0005010851C5033806F8441800B808249FFE7 +:101CF000FE133C833E3DF0813C933E6F4EA2004379 +:101D000004258001B00150110062503300185021A9 +:101D100000605043003080A849FFFDB4A037A0B652 +:101D2000944141008BF5945140242400F40140512A +:101D300020069569EBC540528BF59491EB34420235 +:101D40009073422110698860980AEB46405004065F +:101D500040180C000433000D88444041100688717F +:101D600088258864EA4E96031203800912038019BD +:101D7000020380083C0BF81A020380093C0BF81B95 +:101D8000D5613C17F4F93C47F4FAFE0CA0B640408C +:101D90001096A03740540013944141008BF59451A4 +:101DA0004022A400E24540578408EBC540528BF521 +:101DB0009491EB3442029073422110698860980A32 +:101DC000EB46E20140180C000433000D884440410A +:101DD00010068871882F8864EA4ED50D841F4EA2A4 +:101DE00000071003806D22038005D5BF1003806FAC +:101DF0000203800D1203800F0203800C3C0BF818C5 +:101E00000203800D3C0BF819D51D843FC30610104A +:101E1000006C1010006DD5161010006E1010006FC1 +:101E2000D5115033806C48FFFDDA5033806C48FF89 +:101E3000FE405033806D48FFFED15033806D48FF27 +:101E4000FF55FCE15A0001054403F7DED5034403C6 +:101E5000F7DD44100069AE40EA298420AE40DD9EE3 +:101E60008401DD9EFC204473F080A7B897B0543302 +:101E7000001F583180A0AEF8DD4AAFB8FCA0DD5E8F +:101E80008E01EAF5DD9E44100055DD45AE40441359 +:101E9000F7F1A6089604C003EA29D5FCDD9E44109C +:101EA0000055DD45AE404413F7F0A6089604C00384 +:101EB000EA29D5FCDD9E4443F7FDA72097205A0868 +:101EC000010558020008D503540200F75A1801040E +:101ED000EA71D503540000FB5A280104EA8CD502AC +:101EE000EB1C5A380104EA4DD502EA9C4413F7FD75 +:101EF000AE08DD9EFC2180E08400EA2F8400802073 +:101F000084418060506F8007F837C703EA42EA2FA8 +:101F100084214403F7C0AE40442FFFE74403F7C3D6 +:101F2000AE8096B04403F7C6AE8084404403F7C148 +:101F3000AE8084774403F7C4AEC0EB5496004433BC +:101F4000F7C7AE184403F7C2AE8092D0844344036F +:101F5000F7C5AE8097B0EB8DAF804403F7CCAE40B1 +:101F6000EA398020EA38A6089600C003AED0D5FC36 +:101F700080208040806049FFFFA0FCA184004412C3 +:101F8000C1C4845FEAA28C015A0807FEDD9E84006A +:101F90004432C1C444438D4044538D4138118000C4 +:101FA00096805A10FF0E5A20010BC2055A280209CA +:101FB000AE68D5063C2DFB74AE50D502AE608C01E8 +:101FC0005A0807EEDD9E4403F7C0A6404402E8A489 +:101FD000AE404413F7C3A648AE434413F7C6A64821 +:101FE000AE464413F7C1A648AE414413F7C4A64811 +:101FF000AE444413F7C7A648AE474413F7C2A648F9 +:10200000AE424413F7C5A648AE454413F7C8A648E8 +:1020100010100008DD9EFC00EA494402E8A4A680F6 +:102020004413F7C0AE88A6834413F7C3AE88A686D0 +:102030004413F7C6AE88A6814413F7C1AE88A684C0 +:102040004413F7C4AE88A6874413F7C7AE88A682A8 +:102050004413F7C2AE88A6854413F7C5AE880010B6 +:102060000008EB8DAE40FC80FC4081405400807F36 +:1020700080C180E281235A087F05440000C8DD4307 +:10208000EA495AA8010A8400F9A7EB638420AE400C +:102090004403F7CBD5034403F7CC542480FF441307 +:1020A000F7C0AE8896B04413F7C3AE8896B8441311 +:1020B000F7C6AE884014A00996484423F7C1AE5035 +:1020C0004013200996484423F7C4AE504013A0099A +:1020D00096484423F7C7AE504014C009964844239D +:1020E000F7C292D0AE5097B04413F7C592F0AF88C4 +:1020F00097F84413F7C8AFC88421AE40EA39EA38EC +:10210000A640C103AED0D5FD5AA80107800AF964E4 +:10211000EBC4EB63AE408401FCC0FC004403F02C34 +:10212000A7804413F3EC8401AE0884474413F3ED15 +:10213000AE884413F3EEAE084413F3EFAE08442325 +:10214000F3F08420AE5084644423F3F1AED04423F2 +:10215000F3F28462AED04423F3F3AE5097B044134D +:10216000F3F4AE089674C94554130002964844230C +:10217000F439C1063E07F0838403AE10D5043E3720 +:10218000F083AE50EA4997968401F8CA97B084006C +:10219000F8C7C60584013E07EA48D5033E67EA480A +:1021A000DD5E5A0802074413F02DA608EA4DAE087A +:1021B0004401D80044128E10442025A049FFFE544B +:1021C000441FFF86EB10AE408420EA67AE40441007 +:1021D00000404403F6CAAE40FA214403F697AE40ED +:1021E000FA2F4403F384AE4084214403F380AE40CD +:1021F000DD5E5A00011E4605555A4412BEA8500025 +:102200000AAA3C0FFA90804184028464DD44DD45D3 +:10221000DD46AE404605A5AA500005A53C5DFA91F5 +:10222000D8FE46012345500006783C0FFA91FC8009 +:10223000FC0049FFFEA5DD4B4412C1C4A600AE0858 +:10224000DD4FA600AE0944038D41A600AE0A8041D1 +:1022500084678402DD44FC80FC20440000C6DD432A +:102260004403F7C0A600DD434403F7C1A600DD43E5 +:102270004403F7C2A600DD434403F7C3A600DD43D1 +:102280004403F7C4A600DD434403F7C5A600DD43BD +:102290004403F7C6A600DD434403F7C7A600DD43A9 +:1022A000EB8DA600DD434462FE504472FE560803E7 +:1022B0000001DD434C63FFFDEB18A600DD43440045 +:1022C00000C7DD43FCA0FC004423F7F0C80380A254 +:1022D000D5034453F7F1A6689648DA1754008002F4 +:1022E0009780C609440000C3DD43F8178400F8183E +:1022F0008400FC809656C118440000C4DD43F80DEC +:102300008006F80E8006FC80546080FEC60D4400F6 +:1023100000C5DD438006DD4349FFFFA0840149FF7E +:10232000FD938400FC808401FC80FC40814080E1BE +:1023300080C28123EA495405007F5A08010A8400BB +:10234000F84B8420EB63AE404413F7CBD503441322 +:10235000F7CC542480FF4403F7C0AE8096B8440302 +:10236000F7C3AE8096B04403F7C6AE804004A00920 +:1023700096004423F7C1AE104003A0099600442301 +:10238000F7C4AE10EB5496004423F7C74034C0099D +:10239000AE1096D84403F7C292F0AEC097F844034B +:1023A000F7C592D0AFC097B0EB8DAF808401AE0877 +:1023B0008401FCC05A0001054413F7CCD503441333 +:1023C000F7CB4433F04AEB5AA688C203AF18D5FDC9 +:1023D0005A08010AFC0049FFFD8FEBC4EB63AE40D5 +:1023E0008402FC808402DD9EFC41DD5E84C15A00D3 +:1023F00001044800008B4413F7F1EA39EA38A608D3 +:102400009604C003AED0D5FC3C6DFB6D4413F1289F +:102410009CB484638402DD444413F1185023000803 +:1024200084638402DD444413F10050230018846463 +:102430008402DD444413F12C502300108463840291 +:10244000DD444413F1305023001484638402DD44DE +:102450004413F1045023001C84648402DD4484018D +:102460004413F30EEAA98060DD44001F8007440F87 +:10247000FF80FE0FEA2F4413F30EEAA98461840261 +:10248000DD44440FFFAEEA2FEAA5EAA98461840285 +:10249000DD448401EA2F4413F10D8402EAA984612A +:1024A000DD44DD45DD46AE404605555A50000AAADA +:1024B0003C5DFA90D8FE46012345500006783C0F5B +:1024C000FA90EA89EA8F840AEA2A8401EA5F4413CF +:1024D000F133EAA98060DD44006F800754030004F3 +:1024E000C0F3978FC606440000C2DD4384C1D50DFA +:1024F0004605A5AA500005A54412BEAC3C0FFA91B2 +:10250000804184028464DD448006FCC1DD5E5A00A3 +:10251000010544024A00DD9E44020A00DD9EFC40A3 +:102520005A000203F819840880C1DD494403F31CF2 +:10253000A600C0074413F33FA60858000080AE0869 +:102540004403F369A6009604C009FA22EA67AE4084 +:102550008420EB10AE40480000EB4413F36CA60857 +:10256000EB175800000AAE082E97F0832E77F08202 +:102570005A90010448000080CF1E8009DD494413B1 +:10258000F374A60858000003AE08C61284053E97EF +:10259000F082DD492E07F08180478C013E07F081F3 +:1025A000840280208069808780A7DD53D5044400A1 +:1025B0000898EA2A84003E07F082CE1D4463F36A3D +:1025C0008402DD49A630EB1CEA71AE30440001C242 +:1025D000EA2AEA27FA00AE08804184618402DD44D9 +:1025E0008403DD49A6304413F369EA4DAE30EA397D +:1025F000EA38D51E8400F809844080A28062848372 +:1026000084228401DD5384014900550CEA9FFA03BA +:1026100080268046AE3084618402DD448401EAE78E +:10262000EA28EA22A6305A0014CBAE88D5FCA608C8 +:102630009604C803AED0D5FC8404DD494422FEF0E4 +:102640004433F04AEB5AA610EA275A001104AF1897 +:10265000D5FBFA02AE088440EB10AE8084028041C4 +:102660008060DD448405DD492E07F0808C013E0743 +:10267000F080D55DCF0EC60D84013E07F082840543 +:10268000DD498402802780478067848380A7DD53EB +:1026900084003E07F082C61D4472FEF04493F04A67 +:1026A00044A00055A638EA9F5A00130B84408401C9 +:1026B000EBC680208062848380A2DD53D5F4840140 +:1026C000EAE7FA04AE308026840280468461DD4465 +:1026D000EA27EA39EA38A6085A001004AED0D5FC39 +:1026E0008403DD494413F36AA608EA39EA4DAE08CB +:1026F000EA384413F369A6089604C803AED0D5FCA3 +:102700008404DD49EA9FFA01AE30802680468402C7 +:102710008461DD44EA28EA22A6305A001204AE8819 +:10272000D5FC2E07F0808C013E07F080FCC04423CE +:10273000F02BA6502E37F08396485A380109C00472 +:1027400058008008D50A540080F7D507C004580007 +:102750008010D503540080EFAE10DD9E4403F02AB4 +:10276000A600EB1A96005A180104EAEADD9EEAA6D2 +:10277000DD9EC807FC008401EA668405DD49FC8013 +:10278000DD9EFC00EA8E5A0801094403F7F0A6001A +:10279000560000019604FC808400FC80DD59A600F0 +:1027A0009600C004EA8B5E000001DD9EFC4097802D +:1027B0008402DD498006DD494412FEF28401AE0840 +:1027C0004402FEF3AF80840280418060DD44EA75FC +:1027D000EA964492FEF649FFFFC35A00010B8404B7 +:1027E000441000F2DD42EAEBAFF0EAD95A08ECF50A +:1027F0008403DD4984004412FEF2AE084412FEF365 +:10280000AE08FCC0FC003C6DFBB9DD475A00020776 +:10281000DD40A6015A000903F893EAE43C1C004A93 +:1028200097704C0080063C1C004B4C00C01D2E07CE +:10283000F0D44C0280E42E07F0D7E2A04EF300F66D +:10284000EB1A5A100103F87C8428EB1F2E1010C0DD +:102850003E17EF894C5000E82E07F0D84C02C0E636 +:10286000480000E23C1C00524C0080063C1C005317 +:102870004C00C00C2E07F0C7E2A0E8472E07F0C0BE +:102880004C02C0D4480000BB3C1C005B4C008006DE +:102890003C1C005C4C00C0462E07F0AD4C02805D35 +:1028A0002E07F0B84C02808B2E07F0BA4C028087BE +:1028B0002E07F0BC4C0280832E07F0BE4C02807FB6 +:1028C0002E07F0B94C02807B2E07F0BB4C028077BC +:1028D0002E07F0BD4C0280732E07F0BF4C02806FB4 +:1028E0002E07F0B34C0280122E07F0B44C02800E7B +:1028F0002E07F0B54C02800A2E07F0B64C02800677 +:102900002E07F0B74C02C092DD5E5A000103F818A2 +:102910008408EA6E8409EA562E0010CDEA7BF8108E +:102920003C1C00594C0080063C1C005A4C00C05115 +:102930002E07F09E4C02C00DDD5E5A0001044800D7 +:1029400000758408EA6E2E0010C0EA7BD56E2E0753 +:10295000F0994C02C00CDD5E5A0001688407EA6EF3 +:102960002E0010C23E07EF88D5602E07F09B4C0268 +:10297000C006DD5E5A08015AD5562E07F0A44C0257 +:10298000801E2E07F0A64C02801A2E07F0A84C02DB +:1029900080162E07F0AA4C0280122E07F0A54C02DA +:1029A000800E2E07F0A74C02800A2E07F0A94C02D9 +:1029B00080062E07F0AB4C02C039DD5E5A000136AE +:1029C0008407EA6E2E0010C43E07EF88D52E3C1C0B +:1029D000004C4C10400C2E27F08384282E0010C190 +:1029E000EB1F5A280113EA7BD5203C1C00624C10D7 +:1029F00040102E07F0844C02C019DD5E5A0001160B +:102A00008407EA6E2E0010C33E07EF88D50E3C5CAB +:102A10000061D80BDD5E5A0801098408EA6E2E00B9 +:102A200010C0EA7B8409EA56FC80FC003C6DFBB9CF +:102A30003C0DFB835A0008083C0DFB835A00070439 +:102A400048000193DD475A000208DD40A6015A0004 +:102A50000904480001653C1DFB6F3C2C004A97703F +:102A6000DD5E4C1100063C2C004B4C11400F2E1724 +:102A7000F0D94C1280A32E17F0DA4C12809F2E173B +:102A8000F0D44C12C142D5123C2C00524C1100061D +:102A90003C2C00534C11401A2E17F0C7E2A14EF205 +:102AA000008D2E17F0C04C12C1305A080103F8B146 +:102AB000EA344E1700048E21EA98EA344E130125B9 +:102AC0008444EB69EAB4F8B43C2C005B4C1100067A +:102AD0003C2C005C4C1140662E17F0AD4C12C0111E +:102AE0005A080103F896EA344E1700048E21EA983A +:102AF000EA344E13010A8445EB69EAB4F8992E27AB +:102B0000F0B8D20D2E17F0BA4C12800A2E17F0BC76 +:102B10004C1280062E17F0BE4C12C01F5A0801033B +:102B2000F878EA344E1700048E21EA98EA344E13FE +:102B300000ECEBDBEAB44C51007A2E17F0BA4C12E1 +:102B4000807E2E17F0BC4C1280812E17F0BE4C12E6 +:102B5000C0DC480000822E17F0B94C1280912E176D +:102B6000F0BB4C12808D2E17F0BD4C1280892E17B1 +:102B7000F0BF4C1280852E17F0B34C12801F2E1719 +:102B8000F0B44C12801B2E17F0B54C1280172E1784 +:102B9000F0B64C1280132E17F0B74C12C0B6D50DFC +:102BA0003C2C00594C1100063C2C005A4C1140752D +:102BB0002E17F09E4C12C0075A000103F839480046 +:102BC000009A2E17F0994C12C0145A080103F821EC +:102BD000EA344E1700048E21EA98EA344E13009529 +:102BE0008445EB6984413E27EFEDEAB4F8212E27B6 +:102BF000F0A4D20D2E17F0A64C12800A2E17F0A8C2 +:102C00004C1280062E17F0AA4C12C02A5A08010452 +:102C10004800007DEA344E1700048E21EA98EA3419 +:102C20004E130073EBDBEAB4DA05842BEB28480083 +:102C3000006C2E17F0A64C12C005842CEB28D5642E +:102C40002E17F0A84C12C005842DEB28D55D2E1749 +:102C5000F0AA4C12C05A842EEB28D5562E17F0A598 +:102C60004C12800E2E17F0A74C12800A2E17F0A9D6 +:102C70004C1280062E17F0AB4C12C0475A00014789 +:102C8000EA344E1700048E21EA98EA34C93D8441A3 +:102C9000EB69EAB4D5393C2C004C4C1140105A0871 +:102CA0000108EA8B4E0700338E01EA7BD52FEA3408 +:102CB0004E17002B8E21EA98D5273C2C00624C2021 +:102CC000C0112E17F0844C12C0205A000120EA34A3 +:102CD0004E1700048E21EA98EA34C916EAB4D514D6 +:102CE0003C5C0061D9115A0801104403F403A600AA +:102CF000C80DEA8B4E0700048E01EA7BEA8BC806FA +:102D00008406EA56D5035A080105EA8BC82DD50476 +:102D10002E0FEF88C829840AEA6ED526DD475A00AF +:102D20000224EB40EB2FD820DD5E5A08010EEA8B1F +:102D30004E0700048E01EA7BEA8BC8168406EA5629 +:102D40008404DD49D5118402DD492E0FEF874E073B +:102D500000058E013E07EF872E0FEF87C80584061A +:102D6000EA568403DD49FC80FC00EB6896005A08B3 +:102D70000114DD5E5A08014FDD555A08020B490067 +:102D8000369049007912C0468400EA3FEBA1D54253 +:102D90008400EBAFD53F2E57F0A4D8048400EA940A +:102DA000D5392E57F0A5D8048401EA94D5332E578F +:102DB000F0A6D8078402EA94DD5E5A08012CD5DD1E +:102DC0002E57F0A7D8048403EA94D5242E57F0A8F0 +:102DD000D8078404EA94DD5E5A08011DD5CE2E572B +:102DE000F0A9D8048405EA94D5152E57F0AAD80D79 +:102DF0008406EA94DD5E5A0001C14412E248804133 +:102E0000FA748402DD44D5062E57F0ABD80384074C +:102E1000EA94FC8044039680A600961F8E01E6018A +:102E20003EF7ECF1DD9EFC202E07ECF197805A680E +:102E300001314413968144039680A600A68844136A +:102E40009682A648407010094010A00840108A04DD +:102E500044239683A690FE5744239684A6D096D802 +:102E60005A7001075A78020BF8038006D5088007CC +:102E700044239690DD448007D502840384204423B4 +:102E80009680AE504423968FAE103E17ECF1FCA016 +:102E90008401FCA02E07ECFCC005FC008403DD4986 +:102EA000FC80DD9EFC00C80284263E17ECDD490054 +:102EB000509CFC80FC03B61FF181F282F383B45F67 +:102EC000EB4FEA608402F484F585DD44F20144129C +:102ED000A69AF837F2024412A82AF833F203EBDD7F +:102EE000F830F20444129ECAF82CF2054412A05A9B +:102EF000F828F20A4412A1EAF824F20B4412A37A49 +:102F0000F820F20C4412988AF81CF20D44129A1A16 +:102F1000F818F20E44129BAAF814F20F44129D3ACC +:102F2000F810F2104412AB4AF80CF2114412ABAE96 +:102F3000F808F2124412AC12F8044412AC76F21300 +:102F4000EA608402DD44FC832E27F0835A280104C2 +:102F50004800008DFC4580E08121840480273C6D81 +:102F6000FBB9DD425A7005075A780604480000652F +:102F7000F804EA805A00090448000077EB18A6001C +:102F80008E02E6064EF20071E724E916E730E83DCE +:102F900044437A28F82FEAB944137578F486F48705 +:102FA000F488F489B65FF381F082F183F284F385CB +:102FB000FD20F829D52A44038388B61FEBD6F0817B +:102FC000EB61F08244037BB8F083EBCAF0844403E6 +:102FD0007ED8F085440386A8F08644038838F087BD +:102FE000440389C8F08844038B58F08944137578EA +:102FF000EAB9442377084433789883FF44438068D0 +:10300000445381F849FFFF58EBCBF8244412E248BF +:103010008041FA74F821441397DC80418464F81CE1 +:103020008404441000CEDD424900063A8404441072 +:1030300000CFDD42D5199630661000088E26E622B4 +:10304000E90850107FF6E622E9048E12E602E80C49 +:10305000EBCB8041EAFC8402DD444412E248840266 +:103060008041FA74DD448401FCC58401DD9E920038 +:103070008E015CF000204EF2013A44F02E84EAD03A +:10308000EA36DD0F40004E005E006E007E008E00CE +:103090009E00B000C200D400E600F60008011A014C +:1030A0002C013E014E016001720184019601A601CE +:1030B000B801CA01DC01EE01FE0110022202340255 +:1030C00046025602A009962FAE10DD529604AE18A5 +:1030D000DD9EA0099206962FAE10DD52EA9DAE1835 +:1030E000DD9EA009920C962FAE10DD52EA6CAE1850 +:1030F000DD9EA0099212962FAE10DD52EAA6AE1800 +:10310000DD9EA0099218962FAE10DD52EAEAAE18A5 +:10311000DD9EA00A962FAE10DD524200140BAE18B1 +:10312000DD9EA00A9206962FAE10DD524200180BCB +:10313000AE18DD9EA00A920C962FAE10DD52420012 +:103140001C0BAE18DD9EA00A9212962FAE10DD5217 +:103150004200200BAE18DD9EA00A9218962FAE10EA +:10316000DD524200240BAE18DD9EA00B962FAE1050 +:10317000DD524200280BAE18DD9EA00B9206962F62 +:10318000AE10DD5242002C0BAE18DD9EA00B920C4F +:10319000962FAE10DD524200300BAE18DD9EA00B14 +:1031A0009212962FAE10DD524200340BAE18DD9E07 +:1031B000A00B9218962FAE10DD524200380BAE18BD +:1031C000DD9EA00C962FAE10DD5242003C0BAE18D7 +:1031D000DD9EA00C9206962FAE10DD524200400BF1 +:1031E000AE18DD9EA00C920C962FAE10DD52420060 +:1031F000440BAE18DD9EA00C9212962FAE10DD523D +:103200004200480BAE18DD9EA00C9218962FAE100F +:10321000DD5242004C0BAE18DD9EA00D962FAE1075 +:10322000DD524200500BAE18DD9EA00D9206962F87 +:10323000AE10DD524200540BAE18DD9EA00D920C74 +:10324000962FAE10DD524200580BAE18DD9EA00D39 +:103250009212962FAE10DD5242005C0BAE18DD9E2E +:10326000A00D9218962FAE10DD524200600BAE18E2 +:10327000DD9EA00E962FAE10DD524200640BAE18FC +:10328000DD9EA00E9206962FAE10DD524200680B16 +:10329000AE18DD9EA00E920C962FAE10DD524200AD +:1032A0006C0BAE18DD9EA00E9212962FAE10DD5262 +:1032B0004200700BAE18DD9EA00E9218962FAE1035 +:1032C000DD524200740BAE18DD9EA00F962FAE109B +:1032D000DD524200780BAE18DD9EA00F9206962FAD +:1032E000AE10DD52921FAE18DD9E8400AE10AE18F7 +:1032F000DD9E920004108012FA58FE14EA61EB0E73 +:10330000EA99882004008009EA6CDD9E041080128E +:10331000FA58FE14EA61EB0EEA998820040080084E +:103320009600DD9EFC6081400400000885818121BB +:103330005480003F81AC80CC84E050B50004E306AB +:103340004EF300A79E319600802B490057AF8E01A7 +:103350005CF000234EF2009944F031683827810177 +:1033600040F13C004A003C0058001E011E011E01B5 +:103370001E011E011E018400180152004C00D800DD +:10338000E000E800F000F80000010801100146002C +:10339000B000B800C000C800D0001E011E011E0110 +:1033A0001E011E01460046004600460046008CE114 +:1033B00097F8D56A9A37EA4FD5679A37EA55D564B0 +:1033C000EA624CA0400D9AB75AD801061024800337 +:1033D00085A0D55A1024800485A0D5563C0C0059F0 +:1033E0004CA040539A3710048003D54EEA624CA09B +:1033F000400D9AB75AC80106102480058580D5442F +:10340000102480068580D5403C0C00594CA0403DDE +:103410009A3710048006D5389A3710048007D534BF +:103420009A3710048008D5309A3710048009D52CBB +:103430009A371004800AD5289A371004800BD524B7 +:103440009A371004800CD5209A371004800DD51CB3 +:103450009A371004800ED5189A371004800FD514AF +:103460009A3710048010D5109A3710048011D50CAB +:103470009A3710048012D5089A3710048013D504A7 +:103480009A37100480028CC197B048FFFF5AFCE0C5 +:10349000FC61F081F1018400F8323E0010B8840034 +:1034A0003E07EF8384C04492E5209DF1F1019638F8 +:1034B000F8262E17EF8388C9AE3188013E07EF83C7 +:1034C00080C75A7808F4F1018409F8193E0010C148 +:1034D000F101840AF8143E0010C2F101840BF80FC8 +:1034E0003E0010C3F101840CF80A3E0010C4F10143 +:1034F000840DF8053E0010C5F101FA0549FFFF08EB +:103500003C7C00593E0010CD84C04493978050A36A +:10351000800404038008962FE0C0E80C8006802A0F +:1035200040B32400490056C28CC11005800097B0FA +:10353000D5F1FCE1FC004462D590B4064412C53CD0 +:10354000F8118386B8084412C528F80CB811441243 +:10355000C514F808B80F4412C500F804B81844128E +:10356000C4EC49FFFEE1FC804423F7DAA6509648FC +:10357000C00458108020D503541080DFAE50DD9E6B +:10358000FC40840149004D318401F8272E17EF8358 +:1035900046008B3B88014413F7F8B60184014413BD +:1035A000F7FCAE084413F7CDAE0884283E07EF873A +:1035B0008404EB1F446000C8DD49EA89EA8F2E0FBE +:1035C000EF874E0700088EC1EA5F840A97B1EA2AA6 +:1035D000CEF78405DD49840049FFFFC8FCC0FC40EC +:1035E00080E0DD4780605A08024DEB1A5A18012826 +:1035F000F83044A2FEFC4492FEFD00550000441247 +:10360000FEFCD70F0015000000648000840A97B00C +:10361000DD428026840BDD42840AEA2AEA29D5EEBF +:10362000EAD95A08AAF144000046AE088440EBCF1C +:10363000AE80840280418060DD44FCC04462FEFCB8 +:10364000AFF0EBC44472FEFDAE7880468026DD44C8 +:10365000DD46DD45AE4083FFA63096005A00460C9D +:10366000A670A638EB93840ADD42840B8029DD42E4 +:10367000EA29D5F34412FEFCAE08EBCF8420AE401D +:10368000FCC0FC20DD475A0802174473F41CA7B89D +:10369000DD46DD45AE40840A4410009997B0DD4216 +:1036A000DD59A600C806A7B897B0EA29EAEBD5F914 +:1036B0005A6802FBFCA0FC21F081DD5E5A08011F64 +:1036C000F8354412FEF0A608EA9F5A0850FEF81694 +:1036D00044000051F825F82AA6304472FEF05A083A +:1036E00052FDF001490068C644000053AE388027FF +:1036F000804784618402DD44FCA149001D10EA9FDB +:10370000EA9EF80E4403F04ADD46AE408006A6402D +:10371000EA9F5A1851FEF001490068ACEB44AE3004 +:103720008026840280468461DD44DD46DD45AE406E +:1037300083FFA6305A0853FFFCA1FC20DD5EEA752A +:10374000EA965A080113AFF0EA27A6085A0852FF72 +:103750008401EBBDDD46DD45AE40DD47C0FF4410D2 +:103760000053EA67AE40FCA08401EBBDAFF0DD473B +:10377000C0FFEA27EB44AE08804184618402DD4447 +:10378000FCA0FC4280C0B0013A100C2022AF8002A5 +:10379000F702049F8003DD475A0002098027804911 +:1037A000806A8402DD448401FCC2000300650013CA +:1037B00000648A015A00082F0003006500130065A9 +:1037C000E608840CE80FF80812A10000F803149131 +:1037D00000020013006580464220807383FFA9D158 +:1037E000D5118E284E00FFF912A10000F8031491A4 +:1037F00000020013006580468E284220807383FFFC +:10380000A9D1000300658C019600100300658401B6 +:10381000FCC28400FCC2FC00006080640020806563 +:103820004C61002900308064844C8081424188735F +:10383000003080642252000080814241887380C140 +:10384000A0E2004080644262087300208064A131DD +:103850008C41969010208064002080645A28080BC8 +:10386000844010208064002080658E48969010204F +:103870008065AD40A901A8C2FC803C1DFB933C1DA6 +:10388000FB9300300064844C42018873501087A37E +:10389000222000004400004B4211007380013C1CB8 +:1038A0000376E201E8053C0FFB938401DD9E840072 +:1038B000DD9EFC023C6DFBACEB65C04596309E4343 +:1038C000E631E806DD54A648C9035A080B05840012 +:1038D000EB59D5392E500DDD2E000DDCD823EB1A17 +:1038E00097B03C0DFB8F5A0003083C03F69E8C01F9 +:1038F00096013C0BF69E5A68020E5A10010C3C03CE +:10390000F69E5A0001F084003C0BF69E84003C0FAA +:10391000FB8F840084203C0BF69E3C1FFB8FEB59F1 +:10392000D512EACB49FFFFABC0DBB0014412E1E0A6 +:1039300049FFFF738402F102F203223F8002EACDC5 +:103940003C0FFB8FFC824403F7C9A640C1038420CF +:10395000AE40DD9EFC01DD5E5A000144EB403C0CB4 +:103960000059D0043C0C005AD83CEAB5EA658C01F9 +:103970009600B081503F8005EB55EA65000F80044A +:103980000460800849FFFCB8001F800597AFC1188C +:10399000EAB5EA658C029600EAE3EAB1EB55EB1969 +:1039A000EA6549FFFCA9C809EAB5E206E806EB3A70 +:1039B000C8048401EBFBD5198400EBFBD516C80ABB +:1039C000EAB5E206E8072E07ECE1C8048401EBAD96 +:1039D000D50C840AEA2A8400EBAD3E07EC9FD5059E +:1039E0008400EBAD3E07EC9FFC81EB1A5A180106F0 +:1039F0004412C240F804DD9E4412C1D03800810157 +:103A000050007F5BEAF583FFDD9EFC40DD4680C011 +:103A1000DD45AE40EA83A608C8FF2E37F08344A2F6 +:103A2000C1D0440000A5947150737FA04492C2405D +:103A30005A380116882A8041380519098402DD4464 +:103A4000EA49F815380499015A08A5FEF81C4412F1 +:103A5000C2403805190938009909FCC088298041FD +:103A60003804990984618402DD44EA49DD45DD4674 +:103A7000AE4097F844038D44AFC083FF3805190169 +:103A80005A08A5FE50037FB0960044138D44AE083B +:103A9000840083FF4412C1D0380099093804990981 +:103AA000FCC0FC002E27F105102004302E27F10465 +:103AB0001020042E2E27F1031020042F2E27F102B0 +:103AC0001020042D2E27F101102004582E27F1007C +:103AD000102004592E27F0FF1020045A2E27F0FE44 +:103AE0001020045B2E27F0FD102000A52E27F0FCEF +:103AF000102000AB2E27F0FB1020009A0040000998 +:103B00005030040184404452C554E244E80738620E +:103B10008800186180018C41D5F92E27F0EA102029 +:103B200000A42E27F0E9AE888420101000B7DD4CE9 +:103B3000EA6AFC80FC208400441000C1DD42EA8077 +:103B4000C8038407EAC9DD4C0070005100600052D0 +:103B500080278401DD425A780213EB4DEA87DD4C61 +:103B60003C7FFB5F00000053C8038400D53C5A0033 +:103B7000013B5A0002395A0803FAD5355A780337FF +:103B80008402EA37EB4DEA87DD4C00100053000059 +:103B90000054968C4210840BC914CA0AC8038404CA +:103BA000D5225A0801048406D51E8408D51CC803F2 +:103BB0008405D5195A0801048407D5158409D5133D +:103BC000CA0AC803840AD50F5A080104840CD50B0D +:103BD000840ED509C803840BD5065A080104840D48 +:103BE000D502840F3C0FFB72D5175A780416840057 +:103BF0003E07ECC23E07EFEC2E000DE5EB0C3C0C53 +:103C0000037CEAD73C0C037DEAF1DD41C82E840138 +:103C1000EA378426D5285A60FF1D84013E07EFEC61 +:103C2000EA3E3E000DE53C0C037A3C0E037C3C0C66 +:103C3000037B3C0E037D400310095A000F03EAD7B3 +:103C4000979F5A600F043C6E037B841FEB0CD504D6 +:103C500084003E07EFEC84013E07ECC2DD41C8055D +:103C60008401842549FFF920FCA0FC0180C0840068 +:103C7000EA2FDD41C8133E67ECB04412C118804101 +:103C800084618402DD4484014412C118EAA9806081 +:103C9000DD44EA80005F8007D8F1FC81FC00DD4153 +:103CA000C010EA805A000305EA805A080AFF84001F +:103CB0004412C118EAC9804184618402DD44FC8059 +:103CC000840A49FFFFD4FC80FC00DD41C80AEA8079 +:103CD0005A0808048409D504EA80C8038407EAC99D +:103CE000FC80FC00EA5D84203C0FFC441010005076 +:103CF000EA6AEB7A10100053101000601010006197 +:103D0000FC80FC00DD41C825EA26001080F25A182C +:103D10000121EA22EA28AE883C2DFC44001100F281 +:103D2000C902D5004412FEF3A64896485A10040C66 +:103D30005A10030A5A1006085A100A065A100904A3 +:103D40005A180B083E17EF8B100100F2100100F318 +:103D50008401FC802E07EF95C80EEA263E07EF97F8 +:103D6000002080513E07EF96EB7B84013E27EF94C5 +:103D70003E07EF95DD9EFC005A0806048401D50439 +:103D80005A08070684003E07EC86D51C5A080D0722 +:103D900084003E07EC868421D5075A080E0B840167 +:103DA0003E07EC8684203E17ECCD3E07ECBAD50AE0 +:103DB0005A0810048401D5045A08110584003E07EE +:103DC000EC83FC80FC002E07EF96C8302E07EF94A2 +:103DD0005A0810053C0C0235D50A5A0811053C0C4E +:103DE000022FD5055A0812073C0C0231441320D08B +:103DF000DD5FEA33DD4CC903EBDFD503441FFFA1D0 +:103E0000EA6AEB9CA6485A180305441FFFB1D50384 +:103E1000441FFFB0EB7ADD40A6015A080405840177 +:103E20003E07ECD984013E07EF96DD4CEA505A0874 +:103E3000BB1A2E07EF97E614E8062E07EF97E60A5F +:103E4000E911D50EDD475A0802FAEA268400EB7B19 +:103E5000100080523E07EF973E07EF96D503DD47EF +:103E6000C0F5FC80FC408120DD402E27EF84A601B8 +:103E7000E64180E13EF7EF84EA755A08034A840878 +:103E8000441000B1DD42EA45AE3044A38D4084C900 +:103E9000DD54A608C8133C2DFB5F5A2801FCDD5BEE +:103EA0005A0806F93C6FFB842E07EF84C0F33E27C7 +:103EB000ECF600050000EBD0D5EC8408441000B20D +:103EC000DD42DD41C80A2E07EF84C8128401EA2CC6 +:103ED000DD4FA600EBD0D50CDD46DD45AE402E17FC +:103EE000EC7EDD5B5A0006F15A1801FDD5ED840821 +:103EF000441000B3DD42DD555A080206EB98C003BA +:103F000049FFFECE8408441000B4DD42D508EA45DE +:103F1000AE30DD54A608C803EA29D5FD8408441054 +:103F200000B5DD422E07EF943C2DFC448E10E603D5 +:103F300010910053E80449FFFF47D541CF04440FD7 +:103F4000FFA0D503440FFFA110010051DD4FA600D3 +:103F50005A080305440FFFB1D503440FFFB0100109 +:103F60000052DD40A6015A08040584013E07ECD941 +:103F7000441000B68408DD42EA28EA22DD4CEA500B +:103F80005A00BB04AE88D5FB8408441000B7DD425C +:103F9000DD41C0068402EAA580418060DD448400E2 +:103FA000EA668408441000B8DD42EAADDD4C8420A6 +:103FB000EA6AEB7A8408441000B9DD42FCC0EA26C4 +:103FC00010008060DD9EDD4C00000060DD9EEA2672 +:103FD000100080613C1DFA8B1000803EDD9EEA26B9 +:103FE0000000805050007FDFE602E90484001000EA +:103FF0008050DD9EFC00DD4C441FFFCCEA6AEA22C3 +:10400000EA28DD4CEA505A00BB04AE88D5FBEB39F8 +:10401000EA2A8400EA9AFC8084213E17EC96EA267C +:104020008801002000523C2BF69A001000534011EA +:1040300005003C1BF69A001000543C1BF69700004C +:104040000055EB323C0BF697DD9EFC008400EB58EC +:10405000EAF93C0BF691DD555A080106DD4C0010DB +:104060000052D506DD41EA2600108052C003840AC2 +:10407000D502FA18FE0C3C0BF68FDD4CEA505A08BC +:10408000AB05840249FFFFCAFC80FC0080C049FFE9 +:10409000FE7484015A68030549004EEF80065013F0 +:1040A0007FF3E622E9035A68021B8401EACCDD4073 +:1040B000A7815A6803048402D5125A680A09842920 +:1040C000AE418420DD56DD40AF81D5038420DD562E +:1040D000DD475A0802F2DD578443AE89FC80400078 +:1040E000040E9604DD9EFC02DD41C01FDD4CEBC4D6 +:1040F000EA6ADD4C001000515A18AA0AEB39EA2A84 +:10410000840744100031DD42EAEBD5F4B0415000A1 +:1041100000518441F083122F8002A8093A108C00CC +:10412000EACB49FFFB30D50CDD4CEA50C809EB392E +:10413000EA2A840744100031DD42EAEBD5F6840711 +:10414000EAC6DD42DD4CEA505A00DD048401D502A6 +:104150008403FC825A08031F000080A23E07F10D71 +:10416000000080A13E07F10C0000809C3E07F10B8F +:104170000000809A3E07F10A84418400100080A26A +:10418000100080A11000809C1000809A102080B642 +:10419000D5165A0804172E07F10D100080A22E071D +:1041A000F10C100080A12E07F10B1000809C2E074F +:1041B000F10A1000809A8400100080B6EA26EB7B9A +:1041C000DD9EFC2080615A08016F000084303E07AC +:1041D000F1050000842E3E07F1040000842F3E0705 +:1041E000F1030000842D3E07F102000084583E07D1 +:1041F000F101000084593E07F1000000845A3E0797 +:10420000F0FF0000845B3E07F0FE000080A53E0743 +:10421000F0FD000080AB3E07F0FC50408401000040 +:10422000809A3E07F0FB005080098400802444629D +:10423000C554E205E80708708001387300088C0156 +:10424000D5F9000180A43E07F0EAA61084213E07BC +:10425000F0E98400101184301011842E1011842F85 +:104260001001842D10018458100184591001845AC2 +:104270001011845B100180A5100180AB1001809AA1 +:10428000842A8400E205E805181200018C01D5FBA0 +:104290008421101180B7EA268400100180A4AE109A +:1042A000EB7BFCA05A0802068022800349FFFBFB3F +:1042B000FCA09200FC01840AEA2F5A1001065A1051 +:1042C00002094800007CDD4C8420EA6A4800007B3B +:1042D0003C6DFC44000300528E01E6094EF2006F73 +:1042E00044F040ECEAD040F03C00DD0F120020002A +:1042F0002C006800CE0074007E009600BE00840191 +:10430000EB564422B54049FFFF5ED529EB2D441200 +:10431000B54049FFFBC8D5232E072C3A3E07F10DC7 +:104320002E072C393E07F10CEA413E07F10B2E0710 +:104330002C323E07F10A842184003E072C3A3E07C6 +:104340002C393E072C343E072C323E172C4E1003DE +:104350000051D5098404EB5649FFFEFE8400D503C5 +:104360008400EB9610030052D52D8401EB96840057 +:104370008040DD57EA4AEA903C07964D4900583D97 +:10438000D50A8403EB968401EA37EB560003005309 +:104390004900577CDD4FA600EB564422C122EAB10A +:1043A0003C4DFC44490057E6D50D440201028026ED +:1043B0004900541A8401EA2FD5058401EA2F8402AA +:1043C000AE10EB3A5A080A0A49FFFE8FDD54EA2F75 +:1043D0008401AE08DD58AE08EB3AFC815A000107B3 +:1043E0005A080309B401EA71D503B401EA8DB60194 +:1043F000DD9E8402AE10DD9EFC00DD4CEA505A08C2 +:10440000040CDD47C809DD41C00484013E07F0E823 +:10441000DD4C8420EA6AFC80FC409F01E68F4EF26E +:10442000009A812380C2800144F0423838479101CC +:1044300040F23C004A003C0022002C00380096006C +:10444000BC00C2001A01F400000120011E000E0190 +:104450001A011A011401FA01F80A84003E07EF95C7 +:104460008406F80584003E07EF958407480000792C +:10447000EA89EA8FF82580C05A000204EA5FD5FB7A +:104480008401F8234900113A3C0E04364900113FDB +:104490003C0E04374900114C3E0010E14900115216 +:1044A0003E0010E0490011493E0010E28421440220 +:1044B000E540490042548006F808EA75EA9649004A +:1044C0001145C003AFF0D5FC49001153D512842E1D +:1044D000AE418426AE40EA268440102080508421DC +:1044E000DD568420840280418461808180A1DD5377 +:1044F0008401D5368401AE10D525840044100066B1 +:1045000084E1DD42AFF0DD475A08022ADD41C005F3 +:104510008400EA4F3E77EF8584013E07ECF5842066 +:10452000EA8284013E17EC79EA53D5198401AE1072 +:104530008401F8068402D5148401AE108400490079 +:104540004CAE840DD50D8400EB8BD5D349FFFF56BF +:10455000D5D08402AE18D5CDFA00D502840EFCC0A9 +:10456000920092005A0007044800007CE62A4EF2AE +:1045700000BCFC0080C344F04380EB27EA93DD0FCE +:104580000A2E4CD8D8D8D8BA7094A660440FFF80B1 +:10459000FE0FAE20B4039697660007004020090482 +:1045A000B643440000B0DD43B4069208D545A621C9 +:1045B0009697EA4DAE21B403EBEC40200964B64374 +:1045C000440000B1DD43B406920BD536A621968F88 +:1045D000EA8CAE21B423440F3FFFFE0E402009C4F5 +:1045E000B643440000B2DD43B406920E960FD533B5 +:1045F000A621968FEA71AE21B423460FFC7FEAB85C +:10460000FE0E40200A64B643440000B8DD43B40601 +:104610009213D512A621968FEAD3AE21B423460F6A +:10462000E3FFEAB8FE0E40200AC4B643440000B9D6 +:10463000DD43B40692169617D50EB4039694420045 +:10464000480940200A44B643440000B7DD43B4069D +:104650004200480BDD43FC80843BEABAAE40FC805C +:104660005A080B368E21E62CE83F44F04478EB27BD +:1046700040F0BC004A003C000C12181E242A3036C0 +:104680006E3C444CB403EA8CD52DB403EA73D52AAE +:10469000B403EA4DD527B403EB3CD524B403EAD3E5 +:1046A000D521B403EB1ED51EB403EA76D51BB403A3 +:1046B000EAF0D518B403EAA8EAA4D514B403EAA82A +:1046C000EBEAD510B40358000060D50C5A08051069 +:1046D0005A1001075A180309B403EA71D503B40349 +:1046E000EA8DB603DD9E843BEABAAE40DD9EFC62F5 +:1046F000F282F081F3834422FE50A61081414412DD +:10470000FE51A790A6489204979F549080FF5A00AC +:104710000104480000959E31E603E90E5A60050346 +:10472000F81BDD4C000000605A00A1072E07F017AF +:104730005A080103F811EB115A08AA03F80D4E426A +:104740000094DD41C00BDD40A601EB1C5A080407B4 +:1047500044000088DD43480000884402C0E0EB7953 +:104760004900154DEB5BEA95EBE65A6005058400C0 +:1047700049004431EA83EA39EA38A6085A080104B4 +:10478000AED0D5FCDD41C04B44A3F04A44B0005547 +:10479000EBF110B50000DD43DD475A08021F2E1F64 +:1047A000EF892E0FEF884423F41C4E170014A6D077 +:1047B0005A3802FDEAA5804184668402DD44440043 +:1047C0000083DD43DD46DD45AE40DD475A08021873 +:1047D000D5214E06FFEED5EF44700064EA8B4E07FC +:1047E000000A8EE110B50000840A97F9EA2ACFF793 +:1047F000D5E22E0FEF884E06FFF6D5DD4402FEF619 +:10480000A6005A08EC08DD40A6015A080A0449002F +:104810001B4FEA27A6085A08E1FFD50C4400008484 +:10482000DD43EA27440FFFE1AE0880418402846142 +:10483000DD4480068029F201EB88D5165A000B066C +:104840005410000D5A1805114472FE508420AE78A1 +:1048500080498026F302F40349FFFE86A6385A00F9 +:10486000FB048401EB5DFCE24413F04AEA22DD4CD8 +:10487000EA505A00BB04AE88D5FBDD9EFC0080C028 +:10488000DD4CEA505A08BB224900450FDD4C0010B0 +:104890000050C1035A18FB102E17EF81C9042E17C0 +:1048A000EF80C1108400EBBBEB768400EB8B8401BE +:1048B000EACCD517CE08EB495A08A00A44030FA04A +:1048C000D50BC609EBDFD50CC6F7D50B5A08A104EA +:1048D000EA84D502EAB9EAAFDD5FEBDFDD4CEA6AD4 +:1048E000FC809200FC00E60AE86344F046F4EA81AA +:1048F000EA36DD0F0A42BABABABABABA66A4C9032E +:10490000FA18D5045A18010DFA133C0BF51044009F +:10491000003C3C0BF50E840F3C0BF50FD5495A18A3 +:104920000204FA0ED5F35A180304FA09D5EF5A18FF +:104930000440FA04D5EB8401C1045A18010684022C +:104940003E07EF78D53584005A1002FC5A10030454 +:104950005A18042F3E17EF78D52BC903FA0ED50548 +:104960005A1801084400003C3C0BF50DFA13D5120F +:104970005A180207EA9E3C0BF50DFA09D50B5A1896 +:104980000304EB7CD5045A180414EBF13C0BF50D31 +:10499000FA043C0BF50CD50CE6238400E9078401EE +:1049A0005A1003055A18040584023C0BF7BDFC801D +:1049B0009200FC4080C18420AE40B40280E24200FC +:1049C000640B81245A080106B40642006408B60646 +:1049D000B4074200640BC805B40642006409B60679 +:1049E000B407EA9D5A080107B406EA8CB6068006A9 +:1049F000EB42B407EA9DC80AB406EA73B60649005A +:104A000012393E07EFF98006EB42B40796045A08C4 +:104A10000105B406EA4DB606B4079604C804B40608 +:104A2000EB3CB606B407EA6C5A080105B406EA7115 +:104A3000B606B407EA6CC804B406EA8DB606B40735 +:104A4000EAA65A080105B406EAD3B606B407EAA6F0 +:104A5000C804B406EB1EB606B407EAEA5A08010514 +:104A6000B406EA76B606B407EAEAC804B406EAF081 +:104A7000B606B4079205960F5A080106B406EAA8CE +:104A8000EAA4B606B4079205960F5A080206B406C1 +:104A9000EAA8EBEAB606B4079205960F5A08030691 +:104AA000B40658000060B606EAD992075A08011108 +:104AB000EAD99637EA4FB427840092289657F8BD72 +:104AC000B40754100700B40666000700F83FEA86F2 +:104AD00096045A0801120014800166108001101417 +:104AE0008001B427922B9657F8A8B40754103800C9 +:104AF000B406EBECF82BEA86EA6C5A080112EA8657 +:104B0000EA8DEA55B427840892339657F896B4276D +:104B100046000380FE46B446460FFC7FF8150004AD +:104B20008001EAA65A080116EA86EB1EEA55B42768 +:104B3000840992369657F881B42746001C00FE4639 +:104B4000B446460FE3FFEAB8FE16FE0FB60683FF33 +:104B5000EA86EA9D5A08010FEA86EA73EA55B40725 +:104B6000B4274400C000B446FE46440F3FFF4E0049 +:104B7000FFEDFCC0E60A4EF2007CFC0080C244F06F +:104B80004988EA81EA36DD0F0A2E50E0E0E0E0C213 +:104B90007096B40296576600070040100504B622CE +:104BA000B422840092289657F84844000070DD43F0 +:104BB000B4069208D549B4029657EBEC4010056450 +:104BC000B622B4228401922B9657F8374400007124 +:104BD000DD43B406920BD538B442440F3FFFFE16B6 +:104BE000964F401005C4B626B40644000072DD435B +:104BF000B406920E960FD537B442460FFC7FEAB842 +:104C0000FE16964F40100664B626B42684089233EA +:104C10009657F813EB39DD43B4069213D515B44219 +:104C2000460FE3FFEAB8FE16964F401006C4B626BC +:104C3000B42684099236965749FFFE5644000079FF +:104C4000DD43B40692169617D50EB402964C420078 +:104C5000480940100644B62244000077DD43B406FC +:104C60004200480BDD43FC808402AE18FC808402C5 +:104C7000AE18DD9EFC00FA0E3C0BF5104400003C23 +:104C80003C0BF50E44100050840F3C0BF50F3C1B01 +:104C9000F50D8400FA293C0BF7BD3C1BF50C3E07D3 +:104CA000EF78FC808E01E60CE841FC0080C144F006 +:104CB0004AB8EA81EA36DD0F0C14282E343A404611 +:104CC0006C4C5A62B401EA8CB601D508B401EA739F +:104CD000B601490010CF3E07EFF98006EB42FC8099 +:104CE000B401EA4DD51EB401EB3CD51BB401EAD3A7 +:104CF000D518B401EB1ED515B401EA76D512B4016E +:104D0000EAF0D50FB401EAA8EAA4B60149FFFFB45E +:104D1000FC80B401EAA8EBEAD504B40158000060B5 +:104D2000B606FC808402AE10FC808402AE10DD9ECC +:104D300092009200FC62F281EB18A600A609814164 +:104D4000816381845A08040584003E07ECD9DD4163 +:104D5000C007EB115A08AA052E07EE40D504DD4C1A +:104D6000000000504E0202A35A08FB044800029FB4 +:104D7000F001EA95EBE68400EBCCDD41C00CEB11D1 +:104D80005A08AA0A2E77EE402E87EE4140939009EA +:104D900097DFD509DD4C0070005000800051409332 +:104DA000900997DF8401EA448400EBC000150001FC +:104DB0005A1804182E17EF8AC1043E07EF8AD54807 +:104DC0002E07EC8F5A080103EBBE8420800ADD56C3 +:104DD0008401EA2EDD46DD45AE40EA8EC0FFD538BF +:104DE000EB18A780DD46DD45AE4097B0DD41C01031 +:104DF000DD475A000204DD54D5078EC2E6D3E9FC34 +:104E00008401EA9AD50DA608C80EEA29D5FDDD472A +:104E10005A08020A8EC2E6D3E9068401EBA6DD5ADF +:104E200048000257DD41C009EB115A085507EAA5B1 +:104E3000840280418466DD44DD59A6005A000209DF +:104E40003C0DFB74A6405A1802048420AE402E0785 +:104E5000ECFE8C013E07ECFE4003A4848F21E72C7E +:104E60003E07ECFD4EF201F844F04C783897A5016E +:104E700040F4BC004A003C0018004C00C001D601C0 +:104E80006C037803A203DC03DC03DC03B203CA0374 +:104E90004402C0E0EB79490011B2F001EA95EBE67B +:104EA00080078028804AEB888400EA445A700F0308 +:104EB000F8ADDD4C84CC000000505A00FB044800E3 +:104EC00001DEF8A48EE18401E6E63E07ECE84EF24E +:104ED00000AE44F04CE038779D0140F3BC00DD0F9C +:104EE0000C003600600026012E0166008400EA44B2 +:104EF0008401EABFFA318404DD42EB98C8088404D7 +:104F0000FA3ADD4284C449FFF727D5588404FA3BB6 +:104F1000DD42FAC4D5538400EA448401EABFFA3181 +:104F20008404DD42EB98C8088404FA3ADD4284C563 +:104F300049FFF712D5438404FA3BDD42FAC5D53E5A +:104F4000EABF84C2F88EDD41EA26C03E8401EABF92 +:104F50000000805284C0106F800F5A08AA284900B0 +:104F600041A48401EB8BDD4C001000530020005461 +:104F7000440FFFA0FE0F5A280110EB764400988CD6 +:104F80003E67EF8149004205DD4C441FFFBB3E6791 +:104F9000EF7CEA6AD508EBBB440062383E67EF80DD +:104FA000490041F7DD4C8420EB7AEB49C806EAD58D +:104FB00084C1C004FAD0D502FAC9EAB04E03015F39 +:104FC000841FEA3FF84E2E27EF80C202EA44000019 +:104FD00080525A08AA150020805484005A28010BD8 +:104FE00000308053442FFFA0FE9FEA443E27EF800D +:104FF000D502EB76EBBB840010008052EAD54E035D +:10500000013D480000EFEAA0EA69480000EB840097 +:10501000EA26EA448401EABF00008055001080546B +:10502000EB323C0BF68DFAC2F81C8404FA3FDD42E9 +:105030008400EBCC4800010D8402EB128027840130 +:10504000EB3649FFF93980C08405EB12F80A840079 +:105050002E17EC7EEA448401EBCC5A18010584C972 +:105060004800010D3E07EC7EEB129E39E60C4EF235 +:1050700000A244F04E80EAD040F03C004A003C00E0 +:10508000180032018600320186003201D20032015E +:105090001E01860044003000840044100041DD42BF +:1050A00084013E07ECD5DD55EB018401EA37F809B0 +:1050B0008400EB89DD4284013E07ECD5DD55EB0130 +:1050C0004800007B84004410004BDD42EA26840146 +:1050D00000108051DD4284C084013E07ECF23E673F +:1050E000EC86F85B3C1DFB65EBA9B401EA76B601E2 +:1050F0003C0DFB893E67ECA8EA763C0FFB898400F7 +:10510000EA59EA85D559EA26DD55EB0100108051B0 +:105110008401EA37DD42DD4C8027EA50EB36F8386F +:10512000EB1D5A00024A3C2DFC44000100550031A1 +:10513000005440318100001100524231C00800018A +:10514000005180473E17ECAA3C3FFB734900175AB9 +:10515000D533840044100047DD42EA268401001064 +:105160008051DD42DD55EB01000500015A080308BE +:10517000DD4FA6005A0003048402D5028401EA37F9 +:1051800084013E07ECC9DD4C8427EA50EB36490028 +:105190001719EB1D5A00021149FFF759D50DEA26E0 +:1051A000840100108052EA443E17ECD23E07ECE73F +:1051B000D5038402EA44EB1D5A00020448FFFF5164 +:1051C000DD4C84C0106000513E67ECE83E67EC7E29 +:1051D000DD475A0002053E67ED06D5038405EB1254 +:1051E00084C1D54C8007802BEB3649FFF8F9D523D5 +:1051F000840044100060DD422E67ECF55A6801051A +:105200008400EA44D53B8007802A4422C150503FA5 +:10521000800F49FFF9039780D53180078028804BA4 +:10522000503F800F49FFFCA8D5068007802BEB3646 +:1052300049FFFD3AEB1D5A0002D5B40BB60C84CBE6 +:10524000D51D5A78010649FFF477FAC3D5178402B1 +:10525000EA44D5C7840284C1EA443E67ECCADD4112 +:10526000C0073E67ECCA840F441000FBD504840FCE +:10527000441000EBDD42D5B5FAD0EB1D84205A0076 +:1052800001055A080206843BDD4C101000502E0721 +:10529000ECE8C80A4402C0E0EB7949000FB0F00125 +:1052A000EA9549000F9A8006D513EB49C803EAD561 +:1052B000C0068400EBBBEB768400EB8BF001EA9533 +:1052C00049000F8BEA45EB2E8400EABF8401FCE223 +:1052D0003C0FFC46DD9EFC67F08D81A18182C407F6 +:1052E000C30CFA10846684A180C0D510C30BEAF207 +:1052F000840180A384C4D50AFA70840180A384C683 +:10530000D505EB09846484A180C040E30013978134 +:10531000F8294082801397D9F08A4492E9142E0725 +:10532000E11244B2E8B044A2E978F08B442255B8C7 +:105330008400F30DF821842BF8358400806C8040C4 +:10534000381481114E17000922518000405284B652 +:10535000976BAD58D502AC988C019641E22E8C62C9 +:10536000E9F03C07F6A7F0893C07F6A683FFF08A30 +:105370002E07E112F08B14CF8000149F800114BF20 +:10538000800214AF800314DF800414EF8005148FB3 +:105390008006F787F68883FF8400842D442255B861 +:1053A000F30D808C44527200F8FBFCE7FC01F081A5 +:1053B000440004733C0BF6A7440FFB8C3C0BF6A691 +:1053C0002E07E1113E07ED008C0180C13E07ED0183 +:1053D000C92944029ECAF817F20180668481F80741 +:1053E00044029ECAF81084618083F20144029ECA7E +:1053F000EB4FF840F806F20180668481F80AF83A2B +:105400004402A1EA84418020806249000FC7846180 +:105410004402A1EA4412A82A83FFF2018083F82AF9 +:10542000FC815A18012A4402A05AF818846080832B +:10543000F806F8204402A05AF81184804402A05AC9 +:105440004412A69AF20183FF8066F814F80584607E +:105450008083F809F80F4402A37A80208046806692 +:1054600049000F9C4402A37AEBDDF20183FF8066C2 +:10547000848049FFFF32FC81381105118801E00367 +:10548000E9038400DD9E44008000DD9E3C1DFC4657 +:105490002E07ECC1A68EC80CEA415A08010A9411E5 +:1054A000AE0AA6098E01F8079401F80BD511A609DA +:1054B000AE8A8E01FE148442400008168E0183FFDE +:1054C00096033C0BF6A7FE033C0BF6A683FFA6094A +:1054D0003E07ED008C013E07ED01DD9EFC672E6767 +:1054E0002B9BF08D81C181022E072B9ACB0580204A +:1054F00080408401D5048026844180C097C1F82F64 +:1055000040B080134091001344D2E8B044C2E9781F +:105510003C0DFC4697B144A2E914B71FEBA414DF7D +:10552000800214CF8003F829F835842BF8398400E1 +:105530008068820D808C80409641E22BE8103815FF +:1055400001114E17000922518000405284B6976B1A +:10555000AD58D502AC988C018C62D5EF3C07F6A70C +:10556000F0893C07F6A6F08A83FF3C0DFC46F483E5 +:10557000B71FEBA4150F800214EF800414BF800541 +:10558000F786F687149F8008A602F08B840083FFBD +:10559000842D442255B8F30D808880A083FF4900F4 +:1055A00037A1FCE7FC0180C0F18149FFFF71A03603 +:1055B000A075F201846049FFFF93FC813C0FFBC0A2 +:1055C000DD9E3C0FFBBEDD9E3C0FFBBFDD9EFC4124 +:1055D000846380C080E2501F8006FA50B400EBC79D +:1055E000EA63B607F80FA47044920000F810101395 +:1055F0008010B406501F8006FA508464EBC7EA633B +:10560000A83949003917A4703C3DFBBE8A0100143B +:10561000800292014000043783FF10138011B4060A +:10562000A072A0B60031800C848149000F0AFCC131 +:10563000FC6580E1842080C4121F800D5A48040557 +:1056400004900006D5030490000502310439A61326 +:10565000854050BF801CA7528083B61F80298009D7 +:105660008445EBA414AF800214AF800314BF800400 +:1056700049003710020F800EAC3802058001AC39AA +:10568000501F801A8009804A8463EBC7020F800D87 +:105690005A6804053C0BF6A2D5055A6805043C0B74 +:1056A000F69DAC3B501F801A800984408464EBC790 +:1056B000020F800D5A6804053C0BF68ED5055A681A +:1056C00005043C0BF68AAC3A5A60040E84003E078F +:1056D000ECBC221380033C039A04E020E80484011C +:1056E0003E07ECBCFCE5FC0180C1F3818460B61F81 +:1056F0003E37ECBC49FFFF6DB41F8026F201846089 +:10570000848449FFFF972E07EC835A080107221370 +:105710000003440395B4AC40FC81B460B42080A085 +:10572000927096098440986AB4819290E264E80489 +:10573000B421806496098C445A2820F7DD9E92009B +:10574000FC2080E180C049FFFFEAE6E8E84E44F033 +:10575000555C38779C0040F3BC00DD0F08122436FE +:105760004C566678961F3C0BF8948400D53F3C134A +:10577000F89494049600FE0F3C0BF8948400D53600 +:105780003C13F894961F400081043C0BF89484006D +:10579000D52D3C13F894400081849643EAD23C1BFB +:1057A000F894AC408401D5225410000FEB678400BC +:1057B000D51D94443C03F8939648FE47EB6784005C +:1057C000D5155410000F3C03F89340100504EB6707 +:1057D0008400D50C3C13F89340108184964BEAD199 +:1057E000EB67AC408402D5028400842FB626FCA06F +:1057F000C9104020380954003FFFC00696C48823D2 +:1058000096489201D5FB964FFE555C008001DD9EC7 +:105810008401DD9E5450000C848090A2E28510F03B +:10582000800054100030540000C090249006E281A3 +:105830004002000610F10000AE18DD9EFC0180C1A0 +:10584000B42380A0C94F847F3E37F1223E17F12157 +:10585000C41AC215402020095401000C9002E22015 +:1058600054010003EBB72E27F12040003C244C20CC +:1058700000503E17F11F3E07F120D561122300258D +:105880004800009C541000032E07F1204C00C01368 +:10589000EB5FE602E8038C01EB04EB5FE602E90351 +:1058A00010130040EA5EEAC5E8098400EB04EBA3AC +:1058B000D5053E47F11F3E17F1205452BFFF44006B +:1058C0000FFF92A2D00A0213002684034250807375 +:1058D00090A212530025D50312530025EBF5EBE7F8 +:1058E000F8435A100403F8404E42007E9208960195 +:1058F0005410000C9022C23A8440960F40110406C6 +:10590000E240400784242E17F1204C1040152E173A +:10591000F11FE624E8048C213E17F11F2E17F11F1A +:10592000E624E902EBA3EA5EEAC5E8098400EB0499 +:10593000EBA3D5053E27F11F3E07F120EBF5EBE782 +:105940008400EB90501F80058005EAE3EAB1F83946 +:10595000EB19001F8007940140000440001F8005E0 +:1059600088013E07F11E48000083960F401104068F +:10597000E240400784242E17F1224C1040182E17C5 +:10598000F121E622E8048C213E17F1212E17F121A6 +:10599000E622E802841FEB5CEA5EEAC5E80B8400BD +:1059A0003E07F121841FEB5CD5053E27F1213E0720 +:1059B000F1228400EB908005501F8005EAE3EAB1F4 +:1059C00049FFFF2AEB3A001F80069405400004803F +:1059D000001F8005400004602E17F11EFE0F10030B +:1059E0000059D545541000032E07F1204C00C01378 +:1059F000EB5FE602E8038C01EB04EB5FE602E903F0 +:105A000010130040EA5EEAC5E8098400EB04EBA34A +:105A1000D5053E47F11F3E17F120540280FC92024B +:105A200010030059CA2492A82E07F122974F4C0266 +:105A3000C01B2E07F121E602E8048C013E07F1218C +:105A40002E07F121E602E90410530041D503841F1B +:105A5000EB5CEA5EEAC5E80B84003E07F121841F97 +:105A6000EB5CD5053E27F1213E57F122FC81FC601D +:105A700080C181425A0001055A000244F80AEAD264 +:105A8000A440EB8C964BC0035A0805068400EBAC8F +:105A9000480000A8B402EA8D4E0300A440B0801371 +:105AA000540580039FC35C7380013E77F1243E70F0 +:105AB000107ACF0F2E27F125E444E80D2E57F1235D +:105AC000D808EA5EEAC5E9058C413E27F125D503F1 +:105AD0008400EBAC54908003800B80273E97F12329 +:105AE000F840CF682E17F1254E930009E422E862B2 +:105AF000EBF45CF088FDE85ED541E424E9FAD55A80 +:105B0000EAD1A440EB8C964BC0C25A0005C1EB68A9 +:105B1000E60AE967B402EA8DC86440B08013540510 +:105B200080039FC35C7380013E77F1243E70107A3E +:105B3000CF102E27F125E444E80E2E57F123D80983 +:105B4000EA5E5CF003E9E9058C413E27F125D503C7 +:105B50008400EBAC54908003800B80273E97F123A8 +:105B600049FFFE48CF322E17F1254E930021E42243 +:105B7000E82CEBF45CF088FDE82884013E07F12472 +:105B80008400EB90EB8C5A00042D000300451003B9 +:105B900000462E07F12410030045C823EBF5C80486 +:105BA0008401EB90EBE78404EBACD51BE424E9E241 +:105BB000D50CC0E984001203001F8026800B8441AD +:105BC000806A8087F80BD5DFC0DE84001203001FD7 +:105BD0008026800B8440806A808749FFFE31D5D3C0 +:105BE000FCE0DD9EDD9E4422AB4AB6404432AC76FA +:105BF0004422ABAEA881A8C94422AC128460B6414D +:105C0000ACC4ACC5ACCCACCD8420B4A08061992927 +:105C1000ACE0990A8C22ACE05A1840FBA101840048 +:105C200080204432AC7698A0AC5098838C02AC5063 +:105C30005A0864FBDD9EFC21A4C0842096DB121F61 +:105C40008003848084AF446001EA96615CF08064E4 +:105C5000E80940208409A5C0A44052210031964B98 +:105C6000D509A5C050227F9CA4409041964B52215B +:105C70000031FEAC9691FE54401098368827964B22 +:105C8000AC40A440964BE061E803A4C096DB8C8155 +:105C90008C025A48C8DC123F8003EA63441007D0E4 +:105CA000960340008007FCA1C80E3E07ECBDA40E81 +:105CB000C80684013E07ECBD8400DD9E5A001FFB30 +:105CC0008401DD9E84003E07EC7DA40FC80684019C +:105CD0003E07EC7D8400DD9E5A0831F4D5F9FC4482 +:105CE0002E4010B0802080022E27E102E282E804DC +:105CF0003C57F07AD5033C57F07CE282125F80007B +:105D0000E8052E47E0FC9723D5042E47E0FD9723B6 +:105D10008440124F8001122F8002C8065090800CE0 +:105D2000B4E1FB90D5065090800EA1C94500003229 +:105D3000225480004E9300079CA940238820A49001 +:105D4000F80C4647FFFF50420FFF50287FFF888521 +:105D5000DA0840439020A4A09693122F8002D51712 +:105D60009521411390008C84888702688000A4A04C +:105D700097B39693E046E807024880009723124FB6 +:105D80008002D505A5209723124F8002952998BC43 +:105D9000A590022F80028AC297B3126F80035A30F7 +:105DA000010448000065EA63EAAE9603964BE020E2 +:105DB00050287FFFE81CE0A2E8078C828887A42097 +:105DC000F805F808AC20F8318EE29643EADC960339 +:105DD00083FFFE0CEBF6EB1540307C0AF082F38378 +:105DE000F002F103960383FFAC38D53DEADCE0A274 +:105DF00096C3EA639643EAFF97835001FF9CFE0C2B +:105E0000400018165000006441107C0AF084151FF1 +:105E10008005E80B8C8299BCA430F810F086F187DD +:105E2000F006F1079603AC30220480004E07001CF8 +:105E3000407380200203FFFF83FFF404F5059603FF +:105E40004222802440107C0AEBB642001069846034 +:105E50008822EAC8EA4EF086F187F0068EE29603C1 +:105E6000F107AC3884013E07ECBDFCC449FFFF1EBE +:105E7000C0212E1010B03C07F086E635E9088E35BB +:105E8000E637842AE90544100046D5028420022F13 +:105E90008003880196932214800044300064FE9CA5 +:105EA000407384209603A478400100169A08960354 +:105EB000AC38FCC4FC208480C83AA4D610308009D9 +:105EC000847FA90CA90D8381BC8ABC8BAECCAE0D9E +:105ED00080C045115148B482F83B4E37001CF83F52 +:105EE00005008004A0CDF845A8CDA6CC8CC1A90C96 +:105EF00097B35A38FF03AE0CA6CDE003E902AE0D0E +:105F0000B4628381BC0B88E3A4F8BF0AF849BB8A5A +:105F1000BC8B8C015A0820E184004E670007A41650 +:105F2000B44240010020A400AC08FCA0A41710005B +:105F30008008841FAE0E8400AE0F8400A90EA90F46 +:105F40008381BC8CBC8D80C045115080A11195C14E +:105F50008887A4E096DB83FF4E37002DA5203838D4 +:105F6000810197234241906883FF05008006A0CFFE +:105F70008890E2908865886F83FFA8CFA6CE8CC1F9 +:105F8000A90E97B35A38FF03AE0EA6CFE003E9027D +:105F9000AE0FA0D18381BC0D88E3A4F8BF0C96DBC3 +:105FA0004051FC0A8867E2678885888F83FFBB8C35 +:105FB000BC8D8C015A0832CC84004E670007A417B0 +:105FC000A09140010020A4005CF002EFAC09E905BB +:105FD00084013E0010AFFCA084003E0010AFFCA086 +:105FE0002E467D664E42009FFC60814394C94090DE +:105FF0000C000204800080E19603422008682EB75E +:106000002B9AF8842E672BBCEAC884604EA2004B02 +:10601000EA4EF8494E0200864013AC5784609691D0 +:1060200096498003444151C8E201E8083852000013 +:106030008C01886596D99601D5F8840080804451FA +:1060400051C8E224E908386290008C8188069601E4 +:106050009721D5F82E10039E8E01E2614030BC1BC3 +:106060002E10039F96018480420080013C7C01F346 +:1060700080A4E203E90D40638C20A470964BE0817C +:10608000E804A53080A397238C6196D9D5F3020448 +:106090008000405114A044114730960338209400EA +:1060A000D533EA4E9603EAFE2E07ECB483FFC039DF +:1060B000406398572E10039C94939691E2419C174D +:1060C0004020BC1B2E10039D960197B14200800119 +:1060D0003C5C01F2806A80EAE202E90D401288200D +:1060E000A5089723E064E804A4C880E296DB8C410D +:1060F0009691D5F302248000406398A0441140F0AB +:106100009613382098004220086850010032E202BD +:106110008023882F83FF8460EAC8EA4E9603EAFE54 +:10612000FCE0DD9EFC6380E1221F8028B63F2E1735 +:106130002B9B80C081C2F382048F8012229F802615 +:1061400000AF80542ED72B9A2EC72BBCF18340B1C1 +:1061500004084E42006B40113796541E00FFF18137 +:106160004EA2000A802244214F0080643821390168 +:10617000F83EF40389660205800054CE00FF4023F8 +:10618000B020A450F8ADF8B5AC50B428421030732C +:10619000B628878144B14F00F002E21CE945405621 +:1061A00070014E550014413770014EA20004F816DC +:1061B000F820F824F894E020E809F828F89A121951 +:1061C0000000F1014020F001F89C40567000E0AD65 +:1061D000E826413770004EA200124019801338257E +:1061E000CD0180648006F585153F8004F483F86D49 +:1061F000F505053F8004F40383FF41334C20020979 +:10620000800083FFF86CE020E80A41239420021903 +:10621000000083FFF86E12190000F870500E0001A4 +:1062200055C000FFD5BAFCE340D131B6541680FF0B +:10623000F1814EA20009802244214D70382139019C +:106240008064F84389660205800054D680FF4023AD +:10625000B420A450F845F84DAC50B4284210347323 +:10626000B628878144B14D70F002E21CE9544046E3 +:10627000F0014E450019425E30244EA2000740272F +:106280001401F81CF405F504400714014123002013 +:10629000F824E020E808F82912198000F1014020D4 +:1062A000F001F82FF0034046F000E080E82F425E56 +:1062B00030244EA2000F4027140096518006382546 +:1062C00089018460F485F58449FFFE8CF405F504AA +:1062D000412714004123482002090000B43F9603DF +:1062E0008A0983FFE020E8124133902002198000E0 +:1062F0008820964B83FF12198000F101402E040084 +:10630000B42842100873B62883FF504E000155C2CE +:1063100000FFD5ABFCE3FC688120EA3A8101F387FA +:10632000838585405A0001042EA7E0E43C13F070F9 +:10633000F1868420F18EF18FC4125A0801053C17B2 +:10634000F075D5033C17F074121F801A5A08010526 +:106350003C07F076D5143C07F073D5112E07ECBD41 +:106360005A0001092E07EC7D5A0001053C07F07820 +:10637000D5028004120F801A3C07F077120F801BA1 +:106380004E83001F840012810004A814A8152E77E4 +:106390002B9A2E072BBD511100085131000C04C15E +:1063A0000000F0852ED7E0FE5061001081C7FAB0E2 +:1063B000455000C050BF803844314F00D51C840088 +:1063C000AC158400A816A8172E772BBC5111000A13 +:1063D0005131000E04C100012ED7E0FF50610018BA +:1063E000F78544500032455000C885C150BF803CFD +:1063F00044314D70840012088000840080203A03EC +:106400000420842082C98201804102F88000020BAE +:10641000000040F4BC2002F7800096034127801161 +:10642000E1C0E803122880000A0B00018C419603AA +:1064300040F07C0A880141700406898F9691802083 +:1064400089974C2AFFE4B606840015030001802CCE +:1064500080408C0196011A2080014C02FFFC2E0620 +:106460007D66026880005A08011B40049820A40041 +:1064700038119901960342008068EAC88460F48B61 +:10648000F58A153F8009151F8008EA4E9603051FFF +:106490008008053F8009F50AF40BD50540049820D3 +:1064A000A4009603F106E001E805F1078400AC08BA +:1064B000FCE84E83000C40631C16120980000208A1 +:1064C000800040701CF697F8D50A40631CD612690C +:1064D00080000208800040001CF697F8C4140209EE +:1064E0008000C0099E694C0080075A0001058EA2F9 +:1064F0004C02C0062E07E0DDEBC8D5082E07E0DC15 +:10650000EBC8D5042E07E0DEEBC8EA3A5A080107CB +:10651000000F80338C019600EBC8F83B52640001F9 +:10652000964B960397B0022880008086F84F80AD86 +:10653000151F8006F856051F800602388000CF041C +:1065400040270C00D507F0058E014C70400D40210E +:10655000B801969140048820A4009603E140F82DEC +:10656000F83EFCE84051B8014021B8004044942076 +:1065700040348820A420A4589603964BE020400580 +:106580000013E816A460A4988A229649E201E82B39 +:10659000003F8033021F801A020F801B83FF964B3F +:1065A0009603F181F08296A9F813F819FCE8A45833 +:1065B000A4E08A239649E201E816003F8033021FD7 +:1065C000801A020F801B964B9603F181F082B77FF1 +:1065D00015CF80038009802C83FF9691808680AD43 +:1065E00049FFFDA2FCE8FC4080E08400AE38840056 +:1065F000AC088121AC108024A01D814280C44420BD +:106600000032806784804900632784A0A638E2A016 +:10661000E819A031946938001501D812A03202247B +:10662000800038001501E240E802EAFEA03338009D +:10663000040102150000E220E803120500008CA10D +:10664000D5E6FCC03C23F7EC9641500080645CF139 +:1066500000C89601E8242E27EFD35A2801065010CF +:10666000805A9609DD9E5A2002062E37EFDA5A38F4 +:106670000206501080509609DD9E5A2003045A38B5 +:106680000306501080469609DD9E8E44E649E904D3 +:106690008E64E669E804501080329609DD9E3C1352 +:1066A0009631AC40AC442E172C345A18010CEB9C9C +:1066B000A6485A1803082E172CBAAC402E172CBA2D +:1066C000AC442E172C4B5A1801183C1DFB68C914FA +:1066D0002E272C345A280111FC0080C0DD4FA60063 +:1066E0005A080306840AF804AC30FC80800149FF94 +:1066F000FFABAC30FC80DD9E440395B7A64044035D +:1067000095B6A60040000504DD9E440395B9A60099 +:10671000441395B8A64840008104441F6A44882069 +:106720005CF0805AE903440095BCDD9E440395B4B7 +:10673000A600EA9DDD9E440395B4A600EA6CDD9EAA +:10674000440395B5A600DD9E441395BAA6089600AD +:10675000C00EA60896005A00010BA60896005A0023 +:106760000207A60896005A0003038400DD9E9600E7 +:10677000441395BBAE08DD9EFC00446395B4AE7037 +:106780004412E540B6018401A98910208009100057 +:1067900080081030800A1000800B8001802449009E +:1067A00030DEA630FC80FC0084414400B10084202F +:1067B00080628082EAAB84003C0FFBA43E07EFC4FA +:1067C000FC80FC402E072B9A2E272BCA2E372B9BA2 +:1067D000421008243C1B95D52E172BCB92414241E9 +:1067E0008424FE1C92213E272BD13C4B95D63C0B9A +:1067F00095E63E172BD24402FE85A640842184C034 +:10680000AE40A641AF813C6FFB68EB3050000020EA +:1068100049003AE9EA623C0FFB7849FFE63B49FF51 +:10682000E68B44038D364412FE5C44238D34B6C19E +:10683000AD90AD803C0FFB6E44038D303C0FFB866A +:1068400044038D313C0FFB7444038D323C0FFB60DD +:106850002E072C3B3C1FFB653C2FFB6C3E67ECBAC4 +:106860005A080106B401EA8CB601D504B401EA73F2 +:10687000B601B401852140002404B601B40184C0EE +:10688000EA8DB601B4018540EB1EB601B40184E087 +:10689000EA76B601B401EAA8EAA4B601B4013C0F55 +:1068A000FB8944038D36A44066108002AC40A440AE +:1068B00066108001AC40A44066108008AC40A44043 +:1068C00044038D34AC402E072C403E07EC9DEA4239 +:1068D0003E07ECA7EA453E07ECAB3E67ECE93E67B6 +:1068E000ECDA3C9FFC003CABF6933EA7ECF33E6732 +:1068F000ECE43E67ECAD3E67F01F3E67EC78EA885B +:10690000EB2E3CABF68B3CABF6953E97ECD73E9727 +:10691000EC8949FFE9E8DD403E67ED073CABF68DC9 +:106920003E67ED08AF813E67EC863E97ECCD3E6753 +:10693000EC83AF80DD5484023E67EC7A3C9E00DA43 +:106940003E67ECB1EBA93E67EC8F3E67F015AE08F1 +:10695000DD58AE08EAE6440000C83C0804583C088C +:10696000045C4402E3343C0E022D4402E1B43C0FCB +:10697000FB7F84083E07EDD43E67EC903C7FFB6FC5 +:106980003E67ECC73E97ECC03C7BF6A33CABF69B66 +:106990003E67EC843E67EDF83E67EDD52E072B9BF6 +:1069A0003E072CCD80073E67EDD63E67EFD43C7F97 +:1069B000FB8D3C7FFB873C7FFB7D3C7FFB6A3C7F04 +:1069C000FB813C7FFB693C7FFB923C7FFB823C7FF1 +:1069D000FB593C7FFB61F802800949006103800795 +:1069E000F8203C0E01188009F81C3C0E01198402A5 +:1069F000F8183C0E011A8403F8143C0E011B8404A1 +:106A0000F8103C0E011C8405F80C3C0E011D840698 +:106A1000F8083C0E011E8407F8043C0E011F840890 +:106A2000490060F03C0E01203C0395D53C0B96E0FC +:106A30003C0395D63C0B97493C0396E33C1396E206 +:106A4000400080203C0B96E43C03974C3C13974B52 +:106A5000400080203C7FFC043C0B974D3E67F00CCF +:106A600049005A953C0FFB8B49005A6B4402E5B82C +:106A70003C0E0327EA5A3C0E03294402C2943E67A7 +:106A8000EE313E67EE303E67EE323E600C983C7E63 +:106A900003283E600CA83C0FFB8E845FEBE9843F2B +:106AA00038201C088CE65A783CFBEBE984C0EB717B +:106AB0001010003DEB063E07ECD23C6FFC013C6F32 +:106AC000FC023E67F0193E67F0183E67F01A3E6719 +:106AD000F01B3E67ED783E67ED7A3E67ED793E67E5 +:106AE000ECD93E67ECEC3E67ECA83E67ECD03E6725 +:106AF000ECBE3E67ECD53E67EC7E3E67ECB83E6789 +:106B0000ECEA3E67ECC93E67EC8C3E67ECE73E671B +:106B1000ECF23E67EC983E67ECAE3E67F01E490033 +:106B20001ECC3E67F01C3E67EC953E67ECBC3E67B2 +:106B3000EC973E67ECE3EB30490038C7DD4FAF80A0 +:106B4000EA415A08010449003CEA8401EB23EABC0B +:106B5000EA324900028184C1490002778400EBFCDB +:106B6000AE08EBE1EB8A3C1FFB8A842AEB1F8429E9 +:106B7000EBDBEB453E07ECF18420440061A83C1FB1 +:106B8000FB933C1FFB8F3C1BF69E3E17EC8A3E1787 +:106B9000ECA93E100DDC3E100DDD3C0E03768402A8 +:106BA0003C0E010584053C0E01068407EB283C6E73 +:106BB00001043E17ECB03C0E0107DD41C03044102B +:106BC0000190440397ECAC404410011D440397EE40 +:106BD000AC40441000E4440397F0AC40441000C7BC +:106BE000440397F2AC40441000AA440397F4AC402D +:106BF0004410008E440397F6AC40441000724403E6 +:106C000097F8AC40DD46440397FAAC40EA4B441396 +:106C100097FCAC08441397FEAC08D5058006842683 +:106C200049FFE1428401EA53EA82840584C04412A8 +:106C3000E578EA484402DC303E67ECB63E67ECC2D9 +:106C40003E67ECE13E600DE43E67EC9F3E67ECCCB6 +:106C500049FFF7CBEB4DEA874402FEFC3E60109102 +:106C60003E67EC9CAF80EBCFAF8049000E25EB3F39 +:106C70003E67EC8E3E67ECCA3E67ECA33E67ECF5E0 +:106C80003E67EC798420AF8084464402C1D0EA4C50 +:106C9000842084464402C240EA4C44038D45AF80C0 +:106CA00044038D46AF80FCC0FC21446200B88006DE +:106CB000490033C2EA35F08149FFF4829C3449FF30 +:106CC000F4825003007849FFF305500300A849FF00 +:106CD000F47D500300CC49005F7FEA35F081490024 +:106CE0005F7E500300B049001A98EA35F0814900F0 +:106CF0001A97EA35F08149001FE650030118490050 +:106D000000B3EA35F081490000B2490000CE5003DB +:106D1000012C49001E1C507303A0EA35F081490084 +:106D20001E19800749001E19EA35F08149004F51AC +:106D300050030170490050755003031849005CE589 +:106D4000EA35F08149005CE45003036449005DCDFD +:106D5000EA35F08149005DCC500303744900506965 +:106D6000EA35F081490050688007490058E4EA3567 +:106D7000F081490058E3500303AC490024E2EA35AE +:106D8000F081490024DB3C0DFB65EB42500303D04E +:106D900049FFD56DEA35F08149FFD56C50030048B5 +:106DA00049004015EA35F081490008BBEA35F08119 +:106DB00049001D8049FFF71749FFF7164900503475 +:106DC00049005CAD49FFD55949005D9549005037F0 +:106DD000FCA1FC00DD54840284C03C6FFC01AE08C1 +:106DE000DD58AE08440000A2EB7DDD40A6015A0844 +:106DF0000D108006847F3C2DFB8B843F38310008CA +:106E00008C065A083CFAEBE9EB711010003D490082 +:106E100000313E07EFF9EB0684C0EB9E3E67EC784D +:106E2000490000FC8401EA7D3E07ECC4EBF9EA412D +:106E30003E67ECD13E67EC9E3E67ECE65A080103E4 +:106E4000EA6BFC80FC018401EABCEB14EA84DD5FA0 +:106E50008400EA573C1C0243EB1BFA50EAF2EB4871 +:106E60008401FC813C0FFC50DD9E3C0FFC4FDD9EFD +:106E7000FC00840084203E07F13A3E07F1373E07CC +:106E8000F1363C1BF89A3C1BF8993E17F1393E0746 +:106E9000F1384410004084003E17EA4A3E17EA49A0 +:106EA0003C0FFC51FC803C0DFC50A4413C1BF8986D +:106EB000A444A6003C1BF8973E07F12CDD9EFC0085 +:106EC0003C1DFA8CA6088C01AE083C1DFA8CA60865 +:106ED0009604C8063C0DFA8E3C0FFA8BD5053C0D86 +:106EE000FA8D3C0FFA8B3C0DFA8BA6481010003F30 +:106EF00080A08420EB2B5000003CEB2BD8FFFC80C3 +:106F00003C2DFA8BA65098D1AE199C0996005CF0E6 +:106F1000003BE9028400AE10A6108840841FAE1129 +:106F2000DD9EFC00EACF2E57EF90D00BC804EB4457 +:106F3000DD43D50444000051DD43EACF3E07EF9026 +:106F40002E07EFF82E57EF91D00DC80544000054DE +:106F5000DD43D50444000053DD432E07EFF83E0720 +:106F6000EF912E07EFF92E57EF92D00CC805440091 +:106F70000056DD43D503EA45DD432E07EFF93E0712 +:106F8000EF922E0015F55A00AA048407DD43FC8019 +:106F9000DD9EFC0049002D99FC8044100055DD4524 +:106FA000AE40DD9EFC03F0818005F283F182F38424 +:106FB000F48549002D48F002F103490030A1DD4677 +:106FC000DD45AE40F001F104F20549003039FC83A3 +:106FD000FC2084C080E0E2C7E80B8401844080206C +:106FE0008062808080A28CC1DD5397B0D5F5FCA073 +:106FF000FC0049003157FC80FC0049003145FC8011 +:10700000EB49C8082E17EF80C907FC00490031552D +:10701000FC808400DD9EDD9EFC0049002D06FC8086 +:10702000EAF3C80CFC00EB0649002CFFFA09EA2A37 +:10703000EB06EB9E49002CF9FC80DD9EDD9EFC00FA +:107040004900320BFC80FC00490031FDFC8044010A +:10705000F120DD9E44130FA0B62044138068A8459C +:10706000441373E8A846EB33A84244130C80A844A9 +:1070700044133F9050200044B62244123200A851DD +:10708000441274F8A853DD9EFC4480C04401409033 +:107090003B004C00440140A0EBBFB1C43B004C009E +:1070A0003B03CC20EB502E17301A813F42000401E5 +:1070B0009640C1038E219648EB528386B88A3803E6 +:1070C0008602B88B442000C84402D90C4200887361 +:1070D000B89344031F40B88944038DD4B88CFCC4D2 +:1070E000FC20842CAE4184003C0FFBAFEA7549FFC5 +:1070F000E326EA963C0DFBAFC00B8420846184023A +:107100008041808380A33C1FFBAFDD53FCA049007E +:107110002D735A0801F4AFF0D5EEFC0049002D6341 +:10712000840149002D65FC80A4408C2196495CF0C7 +:107130008190AC40E909FC008405DD438400EA2E1F +:10714000EAA0EA69FC80DD9EFC20FD30DD41C01F25 +:10715000A770DF0A8CA19768E6A5E90284A0EA423D +:10716000AF70EA88D50D8406DD4344138D20A60850 +:107170008C019600AE088400EA2EEA45EA694403D1 +:107180008D20A600C00484013E07F01AFCA0A6884A +:107190005A28AA0AFC00A680AE888420AE40490086 +:1071A0003104FC80DD9EFC00EA475A080415DD47E7 +:1071B0005A000212EA975A08010F84003E07EC7841 +:1071C0008400EB97EA95EB5BEBE6840384203C2D8F +:1071D000FB60EB88FC80A6885A20AA10FC00AE80D9 +:1071E000442FFFAAAE88A6005A080105490030D6F0 +:1071F000FC80490030DAFC80DD9E8440AE80840053 +:10720000AC08DD9EFC005A08010549002F17FC80E0 +:1072100049002F15FC80FC0084204403F560AE403B +:1072200084234403F561AE40840080208040806068 +:10723000EA3BFC80FC0084234403F560AE408420DC +:107240004403F561AE408400802080408060EA3BCA +:10725000FC80FC004402FE63A7404403F007A60044 +:10726000D8084402FE64A7404403F004A600D006F8 +:10727000441FFF8EEB94AE40F80A4403F007A600CB +:107280005A002311441FFF9EEB94AE40843F4402FA +:10729000FE61AE408420840280418461808180A1AF +:1072A000DD53FC80FC24440140C03B004C004421E1 +:1072B00040D0EBBFB004EB853B004C2044238D4114 +:1072C000A6904411D80040108840A6C838500A0241 +:1072D0008400384F8A0296D84462623880E03C13BA +:1072E00095E6E201E818402300200301000038126F +:1072F0008000421804243902010140108C0E8A30AB +:107300009649AC50A450964B4E140003ADD08C015E +:107310009601D5E6FCA4FC01F08194918001F10175 +:10732000DD4AFC81FC0644220000FAD0A6D2A71355 +:1073300084A18440F68584C2F283F284F286F288C6 +:10734000F289B67FF581F382F687F58A8041EA40BB +:10735000FC86FC00C805EA6FEAAFDD5FFC8049FFF0 +:10736000D58180A0C8F9EA6F441300024422623834 +:107370002E372B9A2E472B9B49002A1BFC80FC00A2 +:10738000DD5780C0A64949FFFFE65A680306EAF3C5 +:10739000C80349FFFF89FC80FC2697D0FA5084C0BF +:1073A00084A1F28584429718F287B6FFF581F782AF +:1073B000F683F684F686F688F689F58A804180673A +:1073C000EA40FCA6FC0644420000A7A284A0A72332 +:1073D000F581F582F583F584F586F588F58984A134 +:1073E000F285F387B6DFF58A80418066EA40FC8645 +:1073F000FC07F38DFA7084A08082F3858441846257 +:10740000F281F482F387F28A8064B6BFF583F58453 +:10741000F586F588F5898041F40DEA40FC87FC018A +:10742000EAFAEB33DD5FEA84EB14DD5F8400EA57B0 +:107430003C1C0243EB1BFA50EAF2EB48FC81FC08CF +:10744000F18EF08D8023F28F2E372B9AC4052E47B4 +:107450002B9B8003D5038004848184A1B61FF08216 +:107460008400F083F184F085F086F088F089F08A5A +:10747000F581F587F00DF10EF20FEA40FC88FC0172 +:10748000DD475A08021B8400EA578481EAFAEB338D +:10749000442373E8846049FFFFD4501F8006EAB993 +:1074A00084408463EBC7220F8003441000E642004F +:1074B000000340008007FC818400FC81FC00840103 +:1074C000842049002E2544000CD549002E29FC803B +:1074D0004403F01F4423F302A600A650540000E02A +:1074E00096678C225EF08020E807A6509667880198 +:1074F0008C029600D5038C1F96004413F01FAE0833 +:10750000DD9EFC008400802049002AA949002F1933 +:107510004900354449FFFFD449FFFFDC49002D8D68 +:107520004900288849002F6D490029F44900299E07 +:1075300049FFC857FC803C03F5263C1DFA944423C0 +:10754000F540B4423820820A4423F544B4629C8159 +:107550009691EAE14423F548B4629C829691EAE16F +:107560004423F54CB4629C839691EAE14423F550A0 +:10757000B4629C849691EAE14423F554B4629C85FC +:107580009691EAE14423F558B4629C869691EAE12B +:10759000502000083C2BF5268C074423F55CB442B0 +:1075A00096013820820ADD9EFC015A0801163C0D26 +:1075B000CB03B61F3C0DCB04F0813C1DCAFE3C0D35 +:1075C000CAFD3C2DCAFF3C3DCB003C4DCB013C5D90 +:1075D000CB02F815D516C8153C0DCAFBB61F3C0DDD +:1075E000CAFCF0813C1DCAF63C0DCAF53C2DCAF719 +:1075F0003C3DCAF83C4DCAF93C5DCAFA49002B0033 +:10760000EAC75A0801093C03F5265CF00080E8034C +:1076100049FFFF9384008020804080604900293624 +:1076200049002911FC814423F077A6509604EB0B06 +:10763000FE0FAE10DD9E9200FC2080E080C1DD4791 +:10764000A6B9C80650017FF6E6028409E902800265 +:10765000EA22EA28AE884423F380A6505A1001FF9C +:107660004E6300678E01E60E4EF200CA44F0747855 +:10767000EAD040F03C00DD0F1C00840122005A00DB +:1076800022005A005A0028002800600060005A00BA +:107690002200AA008403EA7EF8498400F895F8469F +:1076A0008401490029C78400F895EAB05A08010608 +:1076B0004400088EEA2AD50884408401842480622C +:1076C000808280A0DD538401EAE78401F88A49FFC3 +:1076D000FDB38400EA7EF82AEADEC005EAC7C003EB +:1076E0008400EBCD8401F87D8400F874EAB05A0878 +:1076F00001064400088EEA2AD508844084018424C7 +:107700008062808280A0DD5349FFFD968400F85C92 +:10771000EADE4E020075EAC74E0300728401EBCD2B +:10772000F8058401EAE78400EA7E480000695A68A7 +:1077300001618E03E60CE86344F07544EA8140F091 +:107740003C00DD0F0C120C121218187070B80C8C63 +:107750008401F83AD5548401EA7ED551EADEC0119D +:10776000EAC7C00F8400EBCD3E07F0E83C03F526E6 +:107770003C1DFA948E019402B60184013C0BF5265F +:10778000EADEC80D8401F8268401EA7E4400003751 +:10779000EA2A8400F8268400F829D531EAC7C8F31C +:1077A0003C5DFA9484213E17F14850128200AA29C8 +:1077B000D9FFD5E9EAC7C005EADEC0038400EBCDF6 +:1077C0008401F808840149002BE7EADEC8A5D51733 +:1077D000840149FFFEEB49FFFD208401EA7E84001D +:1077E00049FFFF238400EAE7840049002923D507E5 +:1077F0005A6802068401EA7E8400EAE7FCA0FC40A5 +:10780000EA4780C15A08040BEA97C008DD475A08C6 +:107810000213842049FFD685D50EDD475A0002F8B1 +:107820008401DD508420846184028041808180A3B2 +:10783000DD53D5F48402DD508441440001A044109E +:10784000003080628082EAAB84208461440001A021 +:1078500080418083EAAB5A00300E844144100030EE +:1078600080628082440001A0EAAB440000D7DD437F +:10787000D5ECEA475A080410DD475A00020D2E776E +:107880002C335A7801098007490029B28400EA2E76 +:107890008007EBBDEA89EA8F3C0DFBAFC00784048B +:1078A000DD50EA475A08041FD509490029A55A089E +:1078B00001F88403DD50EA5FD5F0DD475A0002137A +:1078C000EA975A080110840049FFDEF7441FFFC3FE +:1078D0004403F429AE40DD408420DD568402AE31FD +:1078E000D50F804684058420EB88DD408420DD565A +:1078F0008402AE31840149002B6E8405DD50FCC04A +:10790000FC20EAC15A00010448000064DD474E0330 +:107910000061DD59A6405A1801FFA6005A08015A15 +:10792000DD4BA78097B05A680155DD408429AE41F0 +:107930008420DD56DD40842AAE41DD4180E0DD5902 +:10794000C70D8420AE40DD4BAE408006EA2E840891 +:10795000EA6E2E07EF83EA7BD53CAFC0DD4BAFC0AC +:107960008006EA2E4402FEF2AFC0DD46DD45AE40A1 +:10797000EA8EC0FF49FFDE06EA27EB09AE08804128 +:1079800084618402DD44DD40EB4AEBFF5A080110BC +:107990002E07ECC95A08010CEB03C009EA305A085B +:1079A00001068403EA23490020A5EA74DD4B842103 +:1079B000AE408401EB7E5A00010DEA975A08010897 +:1079C000DD40A6015A080A04490020388400EA660E +:1079D000FCA0FC43441140E08140A600B1823B0082 +:1079E000CC003B034C2085205A08010549003F4448 +:1079F00081208400EA5784E0EB3B38031E02842098 +:107A000094918CE1EA4C5A7804F9000500005A0878 +:107A1000011C8403DD578049EA4AEA902E17EC9452 +:107A2000440000C8FE0CEA57EB33F80344130FA0E0 +:107A3000EB1B2E272B9A2E372B9BEB4849FFFF621F +:107A4000DD54A608C8FFDD46DD45AE408400FCC31A +:107A5000FC2184C0FA003E67EC7B44738D40DD431B +:107A60004900310084013E67ECC33E07EC8D3E07C0 +:107A7000EFD23E67EFEA3E67ECAC3E67ECAFAFB8E3 +:107A8000DD47DD575A08020B8404AE0980018420CB +:107A9000DD56DD40842DAE41D50A8409AE09800152 +:107AA0008420DD56DD40842AAE41AFB8DD59842103 +:107AB000AE40EA415A08010EDD4FA600EBD1440367 +:107AC0008D41A6003E07EC87EBA2C8033E07EFEA14 +:107AD000DD40A6013E07ECDE8406DD50EAEEC81468 +:107AE000DD40EA432E072C3E5A08010449001BE101 +:107AF000840ADD5049001D2DEA41C04ADD475A087D +:107B00000248840BDD50EA415A080110DD41C00DE6 +:107B1000EAEE5A0001052E07ECACC8074402C45235 +:107B2000501F800749FFFF57EA415A08012BEAEE30 +:107B3000C80B44000066DD5049001D7F5A08010C47 +:107B40003E07EC7BD50844000067DD50DD54A608F5 +:107B50005A0801FF44000068DD50DD41C008DD5BCC +:107B60005A0806FFEA6FEAAFDD5FD505DD54A608C7 +:107B70005A0801FFDD548402AE08DD58AE08D5086E +:107B8000DD41C006EAA0DD50DD4FA600EBD0840049 +:107B90003E07EFD2DD47DD572E27ECDE5A080208FC +:107BA0009E12E602E806840DAE09D5075A200204AB +:107BB000AE89D503840BAE09DD40EA438400EA7C3C +:107BC000EB603E07EC903E07EC8D84C14400006AF8 +:107BD000DD503E67ECACDD41C00349FFF9353E673F +:107BE000ECA4DD47C80484013E07EFCC4400006FDD +:107BF000DD50FCA1FC00EAC15A08011FDD47C81C8A +:107C0000DD59A6405A1801FFA6005A080116DD4B9F +:107C1000A78097B05A680111DD408429AE418420C5 +:107C2000DD56DD40842AAE41DD548400AE08DD58C7 +:107C3000AE088006EA2EFC80FC00DD40A6415A100A +:107C4000061C2E17EC8CC9182E67ECEACE15DD54F5 +:107C5000A6485A180112DD58A6485A18010E802667 +:107C6000EB0DDD56DD59AF802E07ECCFC803DD5894 +:107C7000AE088401EA2EFC802E07ECA08421EBB72D +:107C8000DD9E4403F07FA600EAEADD9EFC0049FF8A +:107C9000FFFAFC80FC4080C2812080E1EBDE4900DD +:107CA0002BC744201900FE14E206E8138AC04421C1 +:107CB00086A04023085710248000440E79609690D7 +:107CC0004261007344001388406300D7AFB8FCC022 +:107CD000842010148000AE78FCC0FC00EBDE49006C +:107CE0002B7DFC80FC0180C08001F28149002B6368 +:107CF000F001F82E84013E07EFCEA6303E07EFCD0F +:107D00008400EBC0840149002984F8F42E07EFCEEB +:107D10005A080109844080208062808080A2DD535F +:107D2000D5F6FC81FC0080C08001A648C1058421F5 +:107D3000442000CDF807A630C007800684244420E4 +:107D4000008249FFFFD1840749002B358400490098 +:107D50002B6A84004900295DFC80FC20A78080E01C +:107D6000E6CBE9068ECA840A97B0AE38D50284C045 +:107D7000A638C0038C01AE38A638E603E9038C01AF +:107D8000AE38A638C8038401AE38A608C004EAC6D7 +:107D9000FE0CEA2AC6059431EA9C49FFF91BA67835 +:107DA000C107844084028461848380A2DD53FCA0E7 +:107DB000FC02F08180C1F80CF201F8725A680209E5 +:107DC00084013E07EFC8EAE2EAE9F862D505EAE98C +:107DD000EAE283FFF869F88EFC82FC21FD30F28133 +:107DE000DD47C82C5A700907461000F45000824045 +:107DF000D505461000C3500085005A60011DC60419 +:107E00005A600205FCA1F876FCA12E27EFC72E3799 +:107E1000EFC6CA02C310441186A0FE5C846AEB6FF1 +:107E2000443FE70042010C738A0184203E17EFC6ED +:107E30003E17EFC7F10149FFFFBDFCA1FC2080E028 +:107E400080C1DD475A08020ACF1ADD40A6415A1008 +:107E5000041349FFFEF3D513DD40A6415A100B1061 +:107E60005A6004068006844349FFFFB9DD40A641FD +:107E70005A180904EB84D50349FFFEBEFCA0FC029E +:107E8000F081EAE2EAE9F201F80BEAE9EAE249FF05 +:107E9000FF66FC82FC02F081EAE2EAE9F20149FFB6 +:107EA000FEFBEAE9EAE249FFFF3FFC82FC004600F4 +:107EB00000A650000040F80DFC80FC00F81BFC8080 +:107EC000FC00F818FC80FC00460000A650000040B2 +:107ED00049FFFFD7FC80FC00EBBAEBA5EB29FC8047 +:107EE000FC00F808FC80FC00EBBAEBA5EB29FC8059 +:107EF000FC0049FFFEF4FC80FC00EBBAEBA5EB298B +:107F0000FC805A080408FC00EA4BEA33EA46F8020F +:107F1000FC80DD588401AE08EAE683FFDD9EFC00AC +:107F20003C0FFC54DD41C805F8073C0FFBC3D50EE0 +:107F3000F8033C0FFBC449FFF88C3C1DFC54A68A97 +:107F4000A64B420104733C0FFBC2FC80FC004413AF +:107F5000F69280C08403AE08FA4F4413F6AEAE88A2 +:107F60004413F6AFAE084423F6A084204403F6A1E0 +:107F7000AE50AE404403F6A2AE404403F6A3AE407A +:107F80004403F6A4AE404403F6A5AE404403F6A66F +:107F9000AE40A6F040110C7CA608542180078461F5 +:107FA0004021880CFE878400AE88FA6F80208040D4 +:107FB000EA3BA6705CF08032E8038C21AE70FC8056 +:107FC000FC008E239648E628E81B84614011840C4F +:107FD000543080B1CB049656C90EFC805000005638 +:107FE0009600E602E90D840180C2EBFEDD418402C9 +:107FF000AE30FC80500000569600E605D5F4FC80BB +:10800000FC418120F3818400846180C180E23E379D +:10801000ECBE3E07ECF43E07ECE03E07ECC63E3714 +:10802000ECF65A2803053E37EC8CD5073E37ECEAD0 +:108030005A98AD043E37ECC6500480559600E602CF +:10804000E806840449FFDFEA3E97ED03540300028B +:10805000C0175A78030ADD41C00444023220D523F8 +:1080600044027220D520DD41C00444023224D503ED +:1080700044027224F81884003E07ED04D5168401EA +:10808000EBFEDD4149FFDFB8CE0B5A7003E6DD4160 +:10809000C00444023224D50744027224D5045A682D +:1080A0000105F00149002EF4DD4B8421AE40FCC1F6 +:1080B000FC2080E180C2C00D5A00041184003C0BFA +:1080C000F696490032E6444395AC443395AAD50A66 +:1080D000444395A6443395A4D505444395AC443315 +:1080E00095B084009680E246E80738138101381283 +:1080F00001098C01D5F83C03F696AC18FCA04402AB +:10810000FF50DD9EFC00EA5D2E17ECF25A180107C5 +:1081100084403E27ECD93E17EC8684203E17EC7E47 +:108120003E17ECD53E17ECEF3E17EC8C3E17ECF209 +:108130003E17ECC63E17ECEA3E17ECCE3E17ECC9F4 +:108140003E17ECE73E17ECB83E17EC9810100050C5 +:10815000FC80FC2080C0EA5D80E02E07ECF45CF03F +:108160000032E95FEAAD84003E07ECF43E07ECE044 +:10817000DD41C80944000041EA92DD41C826EA28F1 +:10818000EA22D527EB9A3C4DFC5404100014EA99DE +:108190009230EA61EB0EB4418400924A96B74453A0 +:1081A0000000FB880212001AE201E8E594C1985D24 +:1081B000A448B5A64210C0248871401088378C01AD +:1081C0009649AC589601D5EFEA4BEA33EA46D50713 +:1081D000000380515A00BB04AE88D5FBDD4B8421DF +:1081E000AE4084004413F692AE084413F6AEAE08D7 +:1081F0004413F6AFAE08840080208040FA6FEA3B5B +:10820000EA74DD41C007EA84EAD8DD5FEA84B42677 +:10821000DD5F84003E07ECBE8401EA37EA2CF87982 +:10822000FCA0FC2080C0EA5D80E02E07ECF45A0838 +:108230000215DD414E020070EB18A640EA38EA391B +:108240009648AED05A100C06A6409648EA29D5FBAF +:10825000EA6FB426DD5FD55FE603E95DEAADDD4197 +:10826000C804DD41C81BD512EBD384A00200001A5C +:108270004433000092019401D0F598ABB426A49049 +:1082800088259691AC888CA2D5F844000042EA92E9 +:10829000DD41C823EA28EA22D524EB9A442FFE01C7 +:1082A00004100014440200609230EA61EB0EB42125 +:1082B000EBD3922A9677FE540240001A96498440E6 +:1082C0009611E204E8E3B46640318820A4188C419A +:1082D00088019601AC18D5F5EA4BEA33EA46D50792 +:1082E000000380515A00BB04AE88D5FBDD4B8421CE +:1082F000AE40EA74DD41C007EA84EAD8DD5FEA8473 +:10830000B426DD5F84003E07ECBE8401EA37EA2C28 +:1083100049FFDE678401FCA0FC00EB665A080106F9 +:10832000EA3249FFFF18D507EB815A08010EEA32FD +:1083300049FFFF79DD5AF9622E07ECF48C013E0704 +:10834000ECF4FA03FC808401FC80FC4381202E17AE +:10835000ECF2EBD3046480050270001A5A1801068F +:10836000EBD70464800C95FA3C03F6913C23F68F1E +:10837000E202E8728C013C0BF6918400EB4BDD418C +:108380004E0200B83C03F691E603E904802684001F +:10839000D549EBB2A64096483E17F14E9667581065 +:1083A00080A0AE40EB2D49FFFDBC8400442FFF8030 +:1083B0004430007F9641E227E80A3C1DFBC4EAA254 +:1083C0003C1DFBC2383080088C01D5F5EA305A08D4 +:1083D0000103F8063C0C022F3C1C0231DD5F480013 +:1083E00000893C5DFBC43C2DFBC22E47ECF288A00B +:1083F00020328000382100105A480106A508972332 +:108400009082AD08A5089723E064E910A50897239A +:10841000E082E917AEE83C3DFBC28C22382180089F +:108420008C019681E247E9DED564A4C896DB5EF153 +:108430008080E804A4C896DBD5EA4430007FD5E705 +:10844000A48896935EF17F81E904A4889693D5E38E +:10845000442FFF81D5E0DD555A0001045A18012848 +:10846000DD41C00BEA305A000106DD40A6015A0882 +:108470000A1F8401EAF9D51BEB355A00010B840170 +:10848000EAF98401120F8006B0434402C10BD51AE9 +:108490002E07F14F8C019600E602EB4BE805DD5903 +:1084A000A6005A0801278401EB58D521EB035A0096 +:1084B00001128401EB588401120F8006B04344027C +:1084C000C0F6F085A8093A108C00EACB49FFD95BC9 +:1084D000D5102E07F14F8C019600E602EB4BE80514 +:1084E000DD59A6005A0801068401EAF98400EB4B25 +:1084F000EB03C052EB35C050EAADDD41C01D3C4D31 +:10850000FBC43C5DFBC284209609E207E8113802F7 +:1085100004103822840080C9A0F540210104940988 +:108520008860AC98A0F68C218803AC80D5EE2E171D +:10853000F14EEBB2AE40EA305A000104EBFAEA9297 +:10854000EA4BEA33EA46EA305A080125DD475A0881 +:1085500002078403EA2349001ACDD51C2E672C3369 +:108560005A680119DD40A6015A080915EA23840555 +:10857000DD49EA49EB2C8406DD49EA74DD40490017 +:108580001A1BF08184408402F1018066808680A2FB +:10859000DD53EA74D5292E67ECF25A680126DD47CF +:1085A0005A0802098404EA23DD408026DD56EB13D5 +:1085B000D51B2E672C335A680118DD40A6015A08D6 +:1085C0000914EA238405DD49EA49EB2C8406DD49D8 +:1085D000DD40490019F1F08184408402F101806698 +:1085E000808680A2DD53FCC3FC002E07ECD55A0820 +:1085F0000109EAAD49001714DD5A49FFFC84D50F83 +:10860000EA305A08010F2E17EC985A18010C840012 +:10861000EA3C8400EA59EA85EA32F920FA03D502F5 +:108620008401FC80FC22EA5D80C03C13F68F3C0391 +:10863000F691E2014EF200B08C01960184203C0BD1 +:10864000F6913E17F14D5A08013BEBB2A640964811 +:108650003E17F14C9667581080A0AE40EB2D49FFB5 +:10866000FC603C1DFBC384408001806180E2445F6C +:10867000800044407FFF5CF100C0E809AD58124122 +:10868000832012518190124184B0D508ADC0127080 +:10869000032012700190127004B08C419691125018 +:1086A00080C8124083E812508258124085788C624C +:1086B0008C228C025A28C8E1480000913C1DFBC363 +:1086C0008400804145029ECA447F80004512A1EA91 +:1086D00040504000A56822310320976B22410000E2 +:1086E000E0A342429000E806DF04443F8001D50247 +:1086F0008065AD101231032040504400A56822313E +:1087000004B0976B22410190E0A342429000E8063A +:10871000DF04443F8001D50280658C021241019044 +:10872000123104B08C425A0980D584004472A05A98 +:10873000444F80004502A37A9947A568222083E828 +:10874000976B223080C8E0A242328C00E806DC043D +:10875000442F8001D5028045123080C8122083E862 +:1087600040504000A56822208578976B22308258BF +:10877000E0A242328C00E806DC04442F8001D502DE +:1087800080458C0212308258122085788C225A093A +:1087900090D5D524EB355A0001118401EAF9840102 +:1087A000B041EAC44402C10BF083A8093A108C001E +:1087B000EACB49FFD7E8D5122E07F14D8C01960080 +:1087C000E6053E07F14DE805DD59A6005A08010708 +:1087D0008401EB5884003E07F14DEB03C024EB35D8 +:1087E000C022EAAD44129ECA3C2DFBC34430064071 +:1087F0008402DD443C2DFBC3EB4F50210640443046 +:1088000006408402DD44EBFAEA92EA28EA220003F9 +:1088100000515A00BB04AE88D5FB2E17F14CEBB2C9 +:10882000AE40EA74FCA22E07ECC95A08010BDD5BCE +:108830005A08010AFC00EA3249FFFEF6F804FC80FF +:108840008401DD9E8401EAE6FA0383FFDD9EFC00DD +:108850002E67ECC95A680116EA3249FFFD78840098 +:10886000EA2CDD4BAF80DD475A000221EA975A0817 +:10887000011EDD40A6015A080A1A490018DFD51664 +:108880002E07ECE75A080115EA742E07ECD249FFCF +:10889000F3C5DD41C004EA4BEA33EA46EB06EB9E42 +:1088A00049FFF3BCDD4B8421AE40FA03D5028401BD +:1088B000FC80DD9EDD9EDD9EDD9EFC4049FFD845AF +:1088C000EA479E46E622E90A50107FF7E625E906C8 +:1088D0005A001105840148000075DD40A6015A08C0 +:1088E00004148404441000BDDD42440000D0DD5077 +:1088F000DD41C01F840049FFCF3E8401DD49EA9F6E +:10890000EA89EA8FD50B8E08E604E9ECDD475A08C0 +:1089100002EAFA31EA67AE40D521A6305A002105B5 +:10892000EAEBEA5FD5FB8402DD498400EA66D516EE +:108930002E07F082C80884024413970044238D5404 +:10894000EAFCEACD8406DD49EA27FA11AE08804147 +:1089500084028461DD448400EAAC8403DD49DD40A7 +:1089600084C0A601DD4949002093440000D1DD50B8 +:10897000DD479E4240130406840249FFCDD2DD4705 +:108980005A08010B8006490023088006490023236A +:10899000800649002316440000D2DD50DD40441219 +:1089A000C4603C2DFB654432C28C49003B1180C041 +:1089B0005A00080448FFFF90440000D3DD508006B1 +:1089C000FCC0FC20EAAD49FFEEFE49FFF59CDD400E +:1089D0008421AE4149FFF16A440000A0EB7DEBA881 +:1089E000DD5749FFF70E44000051DD50EA75EA9665 +:1089F00049FFF949C803AFF0D5FCEB44DD50FCA0BA +:108A0000FC00840FDD43840444100062DD42DD4637 +:108A1000DD45AE40EA83A608C8FFEBF1DD50440017 +:108A20000083DD50840149FFD7F244000084DD500B +:108A3000FC80FC00840444100061DD4244100067A7 +:108A40008404DD428404EB12440000A1EB7DDD4090 +:108A5000EB53EAC0EB998480EBD2EA705A08010923 +:108A60004402C0E0EB7949FFF3CA4900249EDD547B +:108A70008402AE08DD58AE0849FFFFC484044410E8 +:108A80000068DD4249FFF7E6EA705A080104490030 +:108A9000248549FFF1A08402DD4384044410006969 +:108AA000DD42FC80FC00EA5D80C0840CDD504403A4 +:108AB0008D47A6408C219648AE40DD46DD45AE4050 +:108AC0008409441000A1DD4249FFF36F8409EBD50E +:108AD000DD428409441000A3DD42DD40A6415A185E +:108AE0000D0D8409EBCEDD422E07EC905A080113E0 +:108AF000FA05DD4384C2F88EEBE4C9F44412C15890 +:108B00004422C46049003B9CEAC35A0801EC84C17A +:108B1000F8818409EB86DD422E07EF84C00AEABAA9 +:108B2000A6405A102105A6005A0822048401EA2C06 +:108B3000DD5A5A08190449FFDE9984003E07ECB358 +:108B40002E07ECF6C810DD5B5A08060E8409EA56BB +:108B5000DD578401EA2C3E07ECB3DD4FA600A649A1 +:108B600049FFF3F92E07ECE95A08010C4402C15100 +:108B70003C1DFB65EAC03C3DFB6E3C4DFB6CEBEFE6 +:108B8000DD41C012840C00130050DD42840D00133F +:108B90000051DD42840E00130052DD42EBFF5A0803 +:108BA00001048400EA9A3C0DFB955A080144DD5902 +:108BB000A60096005A08013F84203C1FFB952E1703 +:108BC000ECE55A18551B2E17EF85C104EA9AEACC3A +:108BD000D516EABAA6005A08130544000086DD43FC +:108BE000EBA8DD574422C1053C3DFB654442C28CE5 +:108BF00049FFE0A2EACCD503EA45EB2EDD5A49FF56 +:108C0000DA4696003E07EC89DD492E67EC895A6802 +:108C10000304480000755A68020EFA04DD432E076B +:108C2000ECFDDD43DD46DD45AE40DD54A608C0FF6A +:108C3000D566DD54A6085A080206DD4BA6005A0088 +:108C400002062E07EFF55A08012C8401AE08DD5804 +:108C5000AE082E07EFF55A080120DD5B5A08061D05 +:108C60008409EA568400EBF9EA415A080114DD4F01 +:108C7000A60049FFF4065A080107EBA25A080104AE +:108C80003E07EC7B2E07EC7BC005FA06DD4384C271 +:108C9000D5368401EABCDD47C80349FFF92FDD4022 +:108CA000A6015A080A08DD47C80349FFF90849FF29 +:108CB000F6292E07ECB35A08010DDD4FA6005A081D +:108CC0000309EAF3C80684023E07ECB349FFF2EC5D +:108CD000DD5A5A080404490030072E07ECE65A0012 +:108CE000010448FFFF1684003E07ECE6DD58A608A5 +:108CF0009600C8FE8441AE88FAC3EA2C8006FC8048 +:108D0000FC01EA705A0801064402C0E08420EB31FD +:108D1000EA415A080104490031CFDD4FA6005A0844 +:108D2000030DEA415A08010A49002E7784023C1DCE +:108D3000FB6449FFF186D50849002381F081F101E8 +:108D4000840049FFF17EDD40A6415A180D048423BA +:108D5000AE41440000A3EB7D2E072C355A08010BD1 +:108D6000DD40A6005A080107DD4FA6004900249205 +:108D7000D504EAFAEB14DD5FEA324412C1D844228A +:108D8000E0CC443200004442DD1849FFE4AEFC81EF +:108D9000FC002E072C365A080108EA324412D5FC92 +:108DA00049FFE402D5053C0C0235EBF2DD5F2E07EE +:108DB0002C4B5A08010E4402C4424412C4404422BF +:108DC000C43E4432DD244442D8C849FFEC0E2E078D +:108DD000EFD3E6053C03F7EBE8055CF0012CE90571 +:108DE000D50A5CF0010EE807EAD4E90584003C0FDF +:108DF000FB68D50484013C0FFB6884013E07F02228 +:108E0000DD5A5A081208EAA38421EADD5A08010350 +:108E1000F8112E17EC9D5A1801054402C0E0EB3101 +:108E2000DD5A5A08120AEAA38422EADD5A0801052B +:108E30008402EA33EA46FC80EA5BC80BFC00440388 +:108E4000307049FFE6FAC007FA18EA878403FC800D +:108E50008404DD9E8401FC80FC6680C0EA3E2EA76F +:108E60002B9A2E872BBD2E972BBC2EB72B9BC00980 +:108E700044C3343C44D333D844233374EB87D508FC +:108E800044C21B3044D219A044221810EB00CE2F4C +:108E900084E1FB708522806A808880A78041F80B7E +:108EA00044034C10EA40EB05EA3144035890DD4A94 +:108EB000802D804DB75FF78114AF8002F683F68472 +:108EC00014BF8005F686149F8007F688F689F78A16 +:108ED00083FF44034F30806A808880A7EA404413B0 +:108EE0004F30EA3144035BB0DD4AFCE65A6801309A +:108EF00084E0FB10854280228069808B80A6440339 +:108F00004DA0F80CEA4044134DA0EA2144035A2036 +:108F1000DD4A440350C0802C804CB73FF681149F3B +:108F20008002F783F784148F8005F78614AF8007DB +:108F3000F788F789F68A83FF8069808B80A6EA40EC +:108F400044035D40441350C0EA21DD4AFCE6FC00C6 +:108F50004E02005AEAB9EA315A181420EB05DD4AEC +:108F600044134F30F81F44129ECAF82144038388EB +:108F70004412A1EAF82BEA3EC003EB87D502EB00CE +:108F8000F824EA3EC004441333D8D503441219A090 +:108F9000EA31EBCADD4AFC8044135890DD4A4413A1 +:108FA0005BB0EA3144037708DD4AEB4FEA31440312 +:108FB0008068DD4A440383884412A82AF807EA3E01 +:108FC000C003EB87D502EB00EB61EA31DD4AEA3EF4 +:108FD000C004441333D8D503441219A0EBCA4E0081 +:108FE000FFF6441386A84402AB4AF86BF806440225 +:108FF000AC12441389C8F8653B0054003B00D420F0 +:1090000083FFFC8044037578EA215A181421441325 +:109010004DA0DD4A441350C0F81F4412A05AF82254 +:10902000440385184412A37AF823EA3EC00444138B +:109030003374D50344121810F824EA3EC0044413D4 +:10904000343CD50344121B30F827FC8044135A20CB +:10905000DD4A44135D40EA2144037898DD4A441216 +:10906000A69AEA21440381F8DD4AEBD6EBDDEA213A +:10907000DD4AEA3EC00444133374D5034412181089 +:1090800044037BB8EA21DD4AEA3EC0044413343C81 +:10909000D50344121B30EA2144037ED8DD4A442321 +:1090A000883880224402ABAE3B00640444238B58D2 +:1090B0003B00E424F806F80A4402AC768022F8016A +:1090C0003B0064043B00E42483FF3B0050003B0072 +:1090D000D02083FFFC80FC40C8053C5DFB84C508B4 +:1090E000D53F5A08013E3C5DFB845A58013A2E5741 +:1090F000EC8884C38EABE2C584C0E9052E67EC889A +:109100008ECB97B1C0085A08010B4470003280A77B +:109110008604D508FAF084A68207D50484E080A7E7 +:1091200082078124EAB94440019042581424420342 +:1091300010735A181406802294A9DD4AD50480239E +:1091400094A9DD4AEBF6EB614203047394B98029DC +:10915000DD4A2E07EC885A080E048408EAC9FCC0D0 +:10916000FC012E27ECB05A200704480000A7E610A7 +:109170004EF200A4F18144F08F843817810140F051 +:10918000BC00DD0F20002000200020004C0060000B +:10919000740086009800AC00C000D400E800FA001B +:1091A0000C0120012E57EC888C0B4C504087DD5B66 +:1091B000C8048401F101F807DD5B5A000103F807D8 +:1091C0008400F10149FFFEC58408EAC94800007621 +:1091D0008400F10144234C10443358904442AB4A7C +:1091E000F86AD56B8401F10144234DA044335A2021 +:1091F0004442ABAEF860D561442216808400F10190 +:1092000080624442AB4AF857D55844221810840172 +:10921000F10180624442ABAEF84ED54F8400F101BB +:1092200044229ECA4432A50A4442AB4AF844D5457A +:109230008401F1014422A05A4432A69A4442ABAEC2 +:10924000F83AD53B8400F10144234F3044335BB0FE +:109250004442AC12F830D5318401F101442350C0AE +:1092600044335D404442AC76F826D527442219A009 +:109270008400F10180624442AC12F81DD51E4422E4 +:109280001B308401F10180624442AC76F814D5159C +:109290008400F1014422A1EA4432A82A4442AC12DB +:1092A000F80AD50B8401F1014422A37A4432A9BA09 +:1092B0004442AC7649FFFF11FC819200FC602E47CE +:1092C0002B9A2E272BBD2E372BBC2E172B9B4E03F4 +:1092D00000F54232082440520409906180204493F2 +:1092E00020D044A3226044B3271044C328A04523C0 +:1092F0004C1045334F30E023E82C402094979720C2 +:109300009489CC02961040412400A5208C21411262 +:10931000001140412800A52096484102001140411B +:109320002C00A5E0884C9501A5904022480013111F +:109330000000988594914111480097FB97B388935A +:1093400088538C01130880009600ADE0AD90D5D411 +:10935000EAD55CF000A04EF3013C5A00A0095A0087 +:10936000A10B4462A1EA44129ECAD50844634F305F +:10937000EB05D504446219A0EB002E07EC92E6023F +:10938000E82D3C0DFB885CF01388E90584003C0F58 +:10939000FB88D5048C013C0FFB88EA31EAB9DD4A31 +:1093A0008026EA3144037578DD4A441000C1440345 +:1093B0007572AC40EAD2A400441375749603AC08ED +:1093C000EAD1A400441375769603AC08442373E8ED +:1093D000EB05EABB8402EACDF8729E82E642E822FF +:1093E000EA31EB61DD4A8026EA3144037BB8DD4A8D +:1093F000441000C244037BB2AC40EAD2A400441340 +:109400007BB49603AC08EAD1A40044137BB6960360 +:10941000AC084423770844134F30EABB8402EACDFA +:10942000F84E9E84E642E823EA3144038068DD4A30 +:109430008026EA31440381F8DD4A441000C3440326 +:1094400081F2AC40EAD2A400441381F49603AC0844 +:10945000EAD1A400441381F69603AC0844237A2889 +:1094600044135250EABB8402EACDF8298E06E60284 +:109470004EF200AFEA31440386A8DD4A8026EA3185 +:1094800044038838DD4A441000C444038832AC40A9 +:10949000EAD2A400441388349603AC08EAD1A400AD +:1094A000441388369603AC0844237D484413557012 +:1094B000EABB8402EACDF8035A000104480000899F +:1094C00040518409FECC842090618001449323F0B4 +:1094D00044A3258044B32A3044C32BC045234DA068 +:1094E000453350C0E003E82C402014979720948126 +:1094F000CC02965040412400A5208C01411200115D +:1095000040412800A52096004102001140412C0056 +:10951000A5E0884C9509A590402248001311000051 +:10952000988D94914111480097FB97B38893885385 +:109530008C21130880009648ADE0AD90D5D4EAD5D3 +:109540005CF000A0E9455A00A0095A00A10C446251 +:10955000A37A4412A05AD50A446350C044134DA0C4 +:10956000D50544621B30441218102E07EC92E60217 +:10957000E80BEA2144037708DD4A8026EA21440308 +:109580007898DD4AD5259E82E642E80AEA21EBCAB0 +:10959000DD4A8026EA2144037ED8DD4AD5199E841F +:1095A000E642E80AEA2144038388DD4A8026EA216C +:1095B000EBD6DD4AD50D8E06E602E80AEA21440321 +:1095C00089C8DD4A44038B588026EA21DD4AFCE045 +:1095D00084004412DDAC8040382081098C01443283 +:1095E000DDAC5A08C0FB8400804098588C021220E1 +:1095F00080C85A0990FCFC203C4C023584A084C3EE +:1096000044700640A4205412801F4022A00940202C +:1096100088A0960339018901400018168810380186 +:109620008909400294090A22000194024000047C46 +:109630009693500000C840111836382181018CA142 +:109640008822976938118109DFDEFCA0FC662EA70D +:109650002B9A80C02E872BBD2E972BBC2EB72B9B11 +:10966000C0035A08010449001F31EA3EC00944C33F +:10967000343C44D333D844233374EB87D50844C2F5 +:109680001B3044D219A044221810EB00CE2284E1F2 +:10969000806A808880A7F8064403589044229ECAB6 +:1096A000EA40B75FF78114AF8002F683F684F6854F +:1096B000F686F787F688F689F68A83FF44035BB05F +:1096C000802D4422A1EA806A808880A7EA40FCE6D7 +:1096D0005A68012384E0802244035A204422A05A7D +:1096E0008069808B80A6F802EA40B73FF681149F1C +:1096F0008002F783F784F785F786F687F788F7897E +:10970000F78A83FF44035D40802C4422A37A80695A +:10971000808B80A6EA40FCE6FC0080C080204402EA +:10972000D5FC49FFDE45CE5D4452A50A443D5AF6BC +:109730004442DDAC84C34422A68A982B381200111F +:10974000A4289603E020E909EA3AC80340109836B5 +:10975000A4288A019603AC288CA2DAF0848180A424 +:109760004402A50A4432D8008420EAF8F893840021 +:109770003C0FFB793C4C01F2806080A02E20107DD4 +:109780009860C20FA48896934E27000CA48850219D +:109790007FCE9693AC88A48896934E240003AD4860 +:1097A000A4488C02964B88615A0840EA84403C3FAA +:1097B000FB794402DC3080628421F85E8400EBABEC +:1097C000EAF8F86D842080814402A82AEB0A44322A +:1097D000D78884A1F85F8400EBC2EB0AF860D561FA +:1097E0005A6801604452A69A443D5AF64442DDACA0 +:1097F00084C34422A82A982B38120011A428960367 +:10980000E020E909EA3AC80340109836A4288A0102 +:109810009603AC288CA2DAF084214402A69A443242 +:10982000D800808180A1EAF8F83584003C0FFB85E0 +:109830003C4C01F3806080A02E20107D9860C20F08 +:10984000A48896934E27000CA48850217FCE96932F +:10985000AC88A48896934E240003AD48A4488C029B +:10986000964B88615A0864EA842180413C3FFB851D +:109870004402DC30846049FFE2348401EBABEAF857 +:10988000F80E84214402A9BAEB0A80A14432D78899 +:10989000848049FFE5428401EBC2EB0A49FFE30CF7 +:1098A000FC80FC004432C11C4402D800EBC24422BC +:1098B000E4A0490039E6EA5AEBAB2E27ECB44900A4 +:1098C0004733EA5AEBABEAF88461F805EB0A8460A7 +:1098D000EBC2EA5A49FFC055EA5A49003B122E171B +:1098E000E149EA5A4900480CEA5A49003F74EA5AE9 +:1098F00049003B50EA5A49004297EB8CC0035A0892 +:10990000050D84013E00107E3E00107D84003C0861 +:109910000841841F3E0010792E0010795A00FF067E +:1099200084003E0010B4D50484013E0010B4EA5A0D +:109930002E17E149490048E08401FC80FC002E0715 +:10994000EC9EC803EA2CD5068401EA2C84003E076D +:10995000EC9EDD5A5A08120AEAA3842FEADD5A085F +:109960000105840FEA33EA46DD4B8421AE40EA97D5 +:109970005A080108DD40A6015A080A044900105E91 +:10998000FC80DD9EDD9EFC002E07ECBAC831EACFDC +:10999000C81B2E07ECF0C8182E07ECF3C8154900B9 +:1099A00006C25A080208FA02DD4384013E07ECF3BE +:1099B000D50B4402E0CC3C1396424422C14C4900F2 +:1099C00009855A0002F2DD40A6412E07ECF35A1039 +:1099D00006045A180B105A0001092E07F01E5A00EF +:1099E00001052E07ECE4C0048401EA3CEA7D840111 +:1099F000D5245A00010A2E07F01E5A0001062E0730 +:109A0000ECD15A0801F6DD46DD45AE40DD54A6082E +:109A1000C0FF84003E07ECF33E07F01E8401EB60BC +:109A2000DD5A5A08120AEAA38425EADD5A0801051C +:109A30008405EA33EA468402FC80FC2084C02E07B9 +:109A4000ECB7E2C0E82C3C0C011995F13850190133 +:109A5000DE243C0C011C4422D5FC98473C0C011B25 +:109A6000A649380019113C30045849FFDD073C1C59 +:109A7000011988E1A478FE0FAC383C0C011B3810AA +:109A800019013C039A02E220E8082E07EC955A00DF +:109A9000FF058C013E07EC958CC1D5D2FCA0FC00E3 +:109AA000DD40A6015A000305F855E603E906DD5A34 +:109AB0005A0005045A08120A84003E07EE303E0799 +:109AC000EE313E07EE32D54E3C0DFB985A080107A9 +:109AD0008400EB084402C294F8204402E1004412DE +:109AE000C2A0490045D73E07EE32F8345A08032099 +:109AF000EB5BEA95EBE64460005F840184408060A4 +:109B00008080842C80A2DD533C0DFB985A0801090B +:109B10008400EB084402C2944900423CD5048EC143 +:109B200097B0CEECEB5BEA9549FFEB574900424B0F +:109B300080C05A080110F80E5A0803078006EB6A25 +:109B400044000061DD43F8065A08040D8401EB6A05 +:109B5000D509490042355A0803068400EA3F8401CA +:109B6000EA7DFC80FC20EA705A0801064402C0E04D +:109B70008422EB314402DD1849FFE593EA975A0845 +:109B8000010A2E07F0145A0801064402DD184900A4 +:109B90000896EA324412C2004422000084608485A0 +:109BA00049FFDD48DD5A5A08120AEAA38423EADD98 +:109BB0005A0801058403EA33EA468400441201D0BE +:109BC0003E07ECD8502080144402C4604900054888 +:109BD0002E07ECD8C8074402C4604412DD244900B3 +:109BE00005522E07ECD8C04A84003E07ECBFDD5A70 +:109BF0005A08120AEAA38424EADD5A0801058404FB +:109C0000EA33EA46EA415A0001062E072C3A5A087E +:109C100001064402019C49002AB83C0C023444125B +:109C2000D8C83C2004584432C11F848149004814DC +:109C30002E072C395A08011B3C0DFB65B400960415 +:109C40005A0001083C0DFB6EA60096045A08010F4D +:109C5000EB70C80C4402D8C84412DD244422C11F52 +:109C6000490004263E07EFFAD50684003E07EFFAC6 +:109C7000490002E349FFFEE3D50DEACF5A08010689 +:109C8000490002D13E07EFFA84003E07ECB73E07D9 +:109C9000EC95EA705A0801064402C0E08423EB31D7 +:109CA0002E07ECF03E07EFD384003E07ECB73E07EB +:109CB000ECF0EACFC8522E17EFEAEB9D3C0FFC0404 +:109CC0005A1001093C0DFC014420EA60E240E9031E +:109CD0008C01EA3F3C0DFC024420EA60E240E90DC1 +:109CE0003C23F7F23C33F6A5E262E802C1048C01A2 +:109CF000EBA1D5033C1FFC02EAB05A08010F8420F7 +:109D00003C1FFC012E17EFDBEA3C5CF08032E80AD6 +:109D10008C213E17EFDBD50684203E17ECA83E17BA +:109D2000EFDB2E172C345A180119DD57A6495A10AB +:109D300003045A180A132E17EFDC5A1801093C1DA8 +:109D4000FC02E622E804C8033E07EFDC8400EB23B4 +:109D5000490028EC8401EB23DD555A08020749002D +:109D60004124C0038400EA3F49FFFE0F5A08020461 +:109D700048000094EACF5A0801058400EA3FEBA1AD +:109D8000EA705A0801064402C0E08424EB31EA97E5 +:109D90005A0801182E07F0145A0801144402D8C8B2 +:109DA0004412E5B82E27ECF04432C1E0490005D852 +:109DB000490007825A0801064402C46049000E3275 +:109DC00084203C1FFBF82E672BA13C7C011A3D0C24 +:109DD000011B4402E5B8808186214520FFFF453004 +:109DE00000FFE286E83BB440C22BA147383395011F +:109DF0001310000B5CF181004039BC1A1230000ACC +:109E000004300009E2234011BC1B5A2003245A20CD +:109E100005220220001E0230001FE262E803122029 +:109E2000001F1220001D38281501025000201220AA +:109E3000001E4C5900108CA112500020D50B12208E +:109E4000000A1220001D1220001E1220001F1220E6 +:109E500000208C8150000044D5C53C1FFBF849FF11 +:109E6000E862DD555A00020549FFFE1BD504DD47B7 +:109E70005A0802FC2E672C345A680112EAF3C81003 +:109E8000DD555A08010EDD40A6015A00060A5A00A7 +:109E90000B0849002E67D50480C0D50284C1800616 +:109EA000FCA0FC0149001ACBF081F101840049FFBC +:109EB000E8C8EAFAEB14DD5FEA324412C1D8442262 +:109EC000E0CC443200004442DD1849FFDC0E2E078E +:109ED0002C365A080108EA324412D5FC49FFDB64EB +:109EE000FC813C0C0235EBF2DD5FFC81FC00DD5BAC +:109EF00049FFF9E6EA5BC01ADD5BC004DD5B5A0886 +:109F00000116DD5B49FFF7AADD5BC804EA5BEA7670 +:109F1000EA82DD5B5A080105EA5BEAA4EA82EA5BB1 +:109F20005CF00030E9038400EA82DD5B49FFFB90CE +:109F3000DD5BC004DD5B5A080105DD5B49FFFBEE1C +:109F4000FC80FC40EA5D2E67ECF581205A68013404 +:109F5000DD55EB01DD4180E04410006AC016840449 +:109F6000DD422E07EC795A000103F82D84E08404C9 +:109F70004410006BDD42107480503E77ECF549FFD1 +:109F8000F49B3E77EF85F81F8402EA378404DD42B4 +:109F90002E07EC795A000103F81684044410006B74 +:109FA000DD42107480503E77ECF549FFF4853C7833 +:109FB0000854F8092E67EC7E5A60010884003E07B9 +:109FC000ECAE84C148000072840444100040DD42BD +:109FD0002E07ECAEC8058408DD433E67ECAE840472 +:109FE0004410004ADD42EAEB49FFF3005A00025DEB +:109FF0005A00132C84044410004BDD42DD555A08EE +:10A0000001278404441000AADD42DD4BA78097B0ED +:10A01000CE1C8404EB89DD423E67F02249FFF17ECD +:10A020005A00131484044410004DDD42DD41C00683 +:10A030002E07ECF65A08010AF81DF81E5A001306FE +:10A0400084044410004EDD42FAC3D52F840444102A +:10A0500000BBDD4284003E07F022DD41C017DD4B2E +:10A06000A600C8F32E07ECF65A0801F08404EB8929 +:10A07000DD4249FFFF1849FFF3EC5A0013E784045F +:10A080004410004DDD42FAC3D510EB83C003EB351D +:10A09000C0DC8404EB89DD4249FFFF2A49FFF3C598 +:10A0A0005A0813EFD5D280C08006FCC0FC00EA5DE0 +:10A0B00080C0840CDD50DD46DD45AE40840944108F +:10A0C00000A1DD4249FFE8718409EBD5DD42DD40A6 +:10A0D000A6415A180D0E8409441000A3DD422E0734 +:10A0E000EC905A080118DD46DD45AE40D50DEBE495 +:10A0F000C9F34412C1584422C460490030A1EAC3E4 +:10A100005A0801EBF8058401EB7EC0FE840248008A +:10A1100000838409EBCEDD424402FEF2A600C007B4 +:10A12000DD40A6415A18030449FFCDED8409EB86B2 +:10A13000DD422E07ECE95A08010C4402C1513C1DD6 +:10A14000FB65EAC03C3DFB6E3C4DFB6CEBEF840CC9 +:10A1500000130050DD42840D00130051DD42840ED7 +:10A1600000130052DD423C0DFBABC034840B4410A5 +:10A170000087DD428400EA9AEBA6EB115A08550EDF +:10A18000EBA8DD574422C1053C3DFB654442C28C2F +:10A1900049FFD5D2EACCD503EA45EB2EDD5A49FF7B +:10A1A000CF7696003E07EC895A0003365A08021310 +:10A1B000DD46DD45AE40DD54A608C0FFDD475A0050 +:10A1C00002A7DD46DD45AE408401EB7EC0FE48FFC0 +:10A1D000FF9F8409441000A6DD42DD54A6085A08FA +:10A1E0000206DD4BA6005A0002062E07EFF55A08BC +:10A1F00001088401AE08DD58AE088400EBF9DD40AB +:10A20000A6015A000B0449FFEB7D8409441000A706 +:10A21000DD428401FC803C0FFBC6DD9E3C0FFBC58C +:10A22000DD9E2E07F1558E019600EBBCC802EB7740 +:10A230002E07F154DD9E841F3C0FFA958400EBBC81 +:10A24000EB77DD9EFC63A105402208400131000050 +:10A250000091000100A1000200B100038620E1A3EB +:10A260004EF200DFA081385145014C58C0D7A105FE +:10A27000415888088895A7A0E4C3E9038EC3D50296 +:10A2800084C0A7612E272B9A8CA3E0A2E9029F51DC +:10A29000A6A2E443E9038E43D5028440A723EBD76B +:10A2A0008C83E087E9029F39E1264EF300B7E0B3E3 +:10A2B0004EF300B4E1624EF300B1E08A4EF300AE1B +:10A2C00042634C004252A40142422C01F681F582C5 +:10A2D00042212800F483F403E0824EF3009FE4441B +:10A2E00085A0E90350D17FFD9D13F701F485F402A9 +:10A2F000E0874EF30090EB5A4453F04AAF283C4DB0 +:10A30000FBC580A700820002056000004251207357 +:10A31000385B15005A50FF7C05700001385B9511C1 +:10A320004E540076E4E484C0E9029FBB058000053A +:10A33000A763410C540000E8000140F71807E967E3 +:10A340009D3B51247FFF83C4424248010128000005 +:10A35000E092E95D00C8000340F63407E95804FFC5 +:10A3600080058EA10108000242579401E0B0E94F38 +:10A3700043E238013C4004584306C000838442480D +:10A380002024432348004252B001F4848680E0B088 +:10A39000E93EF40481D288948892952140FF3807E1 +:10A3A000E932386B10005A60FF2B419B982002CC99 +:10A3B000800040F600114EF5002304F0800540F7C0 +:10A3C000900002F7800040F7801140F7F007E9178E +:10A3D000442F800040260804122C8000406C184056 +:10A3E000A6B043398801A6B142948800A6B242A51E +:10A3F0000801A6B342B5880048FFFF3250E70001CC +:10A400008C82D5CD8D81414A2000D5C28CE148FF98 +:10A41000FF708C4148FFFF618DA148FFFF22FCE3E4 +:10A42000FC20A612C0038E01AE123C7DFBC5A753D3 +:10A43000A63B8E01D0038CA1AF53A610C0038E01A2 +:10A44000AE10A63AA7518E01D0038CA1AF51840063 +:10A45000A750011100018060E3A5E922A792012124 +:10A460000003E3C6E91BA73A81E542F31073050038 +:10A47000800540483C20EB6441080011E59AE90C56 +:10A48000EB6402F200004108001140F78011E06F18 +:10A490008810E802A4E08CC1D5E58CA1D5DEC30606 +:10A4A000441001F4FE0C40000C17FCA0FC4280C0DC +:10A4B000841F3C0FFA953C0DFBC6F181A64380E258 +:10A4C0005CF08042E90444100041AE43A6405CF0D9 +:10A4D0008042E90444100041AE40A64000A00003C1 +:10A4E000440003E8FE0C40900013A638C0268440C8 +:10A4F0003C1DFA9580A2E0A0E80FA0F1383195014B +:10A50000DB09A0F238319501E2434012BC1B402127 +:10A51000BC1B8CA1D5F1A0353C1FFA953C2BF690C5 +:10A52000EB0E3A008000B0433A008020F101800633 +:10A53000B083F868E320E96A2E17F1545A18010431 +:10A54000A678C964441003E8421504249649E22021 +:10A55000E9038420D5703CADFA95442F8000840037 +:10A5600040250804A6F8E003E80AA0714010802006 +:10A57000A5484C554003AC888C01D5F58006F10107 +:10A58000542500FF49FFFE60A035401028403A10D6 +:10A590008400B0833A110420A6F88C038420E023C1 +:10A5A000E82EA0B13851050196AB4E240026545236 +:10A5B000FFFF4C550022D92000207FFD004F800C6A +:10A5C000E282E903102F800C00207FFE004F800DF7 +:10A5D000E244E903102F800D00207FFF004F800E22 +:10A5E000E282E903102F800EA680004F800FE24424 +:10A5F000E903102F800F8C218C04D5D28006F10145 +:10A60000B08349FFFF0FE320E8098401EB773C0D9D +:10A61000FBC68421A601EBBCD50E8400A678E00120 +:10A62000E899A07140108020A4888C0154217FFFFC +:10A63000AC88D5F52E07F155C00B5A1801053E1709 +:10A64000F154D5068E019600EBBCC802EB772E07BD +:10A65000F1545A0801048420AE78FCC2FC00EBE4FB +:10A660003C039A055A1001049680D502A6943C0C2E +:10A6700002344412D8C84432C1408480490042ECBC +:10A68000FC80DD402E472C56A6015A000604972177 +:10A69000D5032E472C582E07ECDB2E272C5DE2022B +:10A6A000E8068C013C43962F3E07ECDB2E27ECBFDF +:10A6B0002E072C5C2E372C55E240E92F2E07ECC0DC +:10A6C0005A080130FC2040000C0C8A04960184E0FA +:10A6D000EB3BE2E2E821A18AB44194F988C38843C4 +:10A6E0000303000004508014A49088A3FEA4A4E8EF +:10A6F000422040738CE188432E372C5540310C0D9D +:10A7000096D9ACF0A4F02E672C554031980C8A43B2 +:10A710009691ACA8D5DEFCA08C413E27ECBFDD9E17 +:10A72000DD9E2E172C3F5A1001048401DD9E2E075A +:10A73000ECD8C84044326EB880803C1395E6E20104 +:10A74000E81FEBF240108020A4883C1396329693C9 +:10A75000FE4AE041E8109883A6508C219648AE50FE +:10A76000A6903C13962DE241E9083C13F6938C2108 +:10A77000EBF0D5039843AF088C019601D5DF3C037D +:10A78000F6933C139633E220E8D18420EBF084006A +:10A7900044326EB8EB3BE202E80698838C01AE507F +:10A7A0009601D5F92E07F0188C013E07F0188402A7 +:10A7B000DD9E84003C0BF6938001DD9EFC2044402E +:10A7C000271080C0FE642200002840208856FE2406 +:10A7D0002213005022330000EB47E022E85140F002 +:10A7E0000DF6E04FE84F44500078FA788024991D28 +:10A7F0004002040A5CF00051E904524000A0D50474 +:10A8000080805A00280552700078D50344700050AB +:10A810003843111138731D11FF0C40421C96E0445F +:10A82000E8039F41D504E082E8309CC1E0A3E8E062 +:10A830004C01800380A35CF28051E904521280A095 +:10A84000D5028025507280285CF38051E903527252 +:10A8500080783813051144302710FECC38131D11B1 +:10A860008A82EB4E9A9A4242000342210003E08220 +:10A87000E90CE044E909E2054002BC1AFCA0FA1820 +:10A88000FCA0EB39FCA08005FCA05CF00051E905C0 +:10A89000523000A0B661D502B60150107FD85CF0EE +:10A8A0008051E905520000C8B602DD9EB622DD9E49 +:10A8B0003C0FFC56DD9E4402E9DC8420AE40AE41F4 +:10A8C000AE42AE43AE44AE45AE46AE47DD9EFC0161 +:10A8D000F081F80740000009F0019E41F181C8FBBA +:10A8E000DD45DD46AE4083FFFC81FC02F081F001D6 +:10A8F000441003E8FE0C50107C5E4603A196500005 +:10A900000B1F4200806940009409F083F001C802E7 +:10A91000D509EA29F0039E41F183C8FCDD45DD46F7 +:10A92000AE40FC82FC02F0818400F083D50ADD4554 +:10A93000DD46AE40440003E8EA2AF0038C01F083D0 +:10A94000F103F001E220E9F4FC823C0FFC5FDD9EA4 +:10A950003C0FFC5EDD9E3C0FFC5DDD9EFC4084E018 +:10A960003C2DFC5F80C1808780A7862504F3000012 +:10A97000E81250F7FFFC5CF78002E90D05230007A1 +:10A980000500000238F8490101210006E3CFE80381 +:10A9900011118002B58651287FFFE7C2E9035B08E9 +:10A9A00004058C81972080E58CA197685063004452 +:10A9B0005A580ADE2F17F193CC0684008420AE1A71 +:10A9C00080A1D51FA61A5A00051B5A480114500829 +:10A9D000FFFFE602E8042E57F192DFF04400004446 +:10A9E0004213807384012250800422108005AE1A25 +:10A9F000D50884038420AE1A80A1D503842080A1C9 +:10AA0000A61A5A0801263C6DFC5DA7B35A680121BD +:10AA10003D2DFC5E0269000951337FFF026900028F +:10AA200050937FFF84C241099A164302A473405891 +:10AA30004CB70309000A032900038F818FC14068C6 +:10AA400018D64260C873976B40134037964BE7A502 +:10AA5000E81844F0A8603917C40040F8BC00DD0FC6 +:10AA6000060C0C161C005A08010BD5105A00010CDC +:10AA7000C80C8403D50BE602E808D503C806D50642 +:10AA80008400D5048402D5028404EB628E01E604BE +:10AA900084C04EF2008F44F0A8A4EAD040F03C00FD +:10AAA0004A003C0008003400500006018400446F56 +:10AAB000FFAA3C0BF8C83E67EA583C5BF8C63C1B53 +:10AAC000F8C73C5BF8C43C1BF8C53E07F1863E77EF +:10AAD000F1923E07F184D56F2E07F1860261001ACC +:10AAE000E206E8048C013E07F1863C5BF8C43C1B9F +:10AAF000F8C5D5612E07F1875A0801282E17F1866F +:10AB00000201001AE220E8212E17F1850201001B44 +:10AB1000E220E81B2E07F184C8183CF7F8C03C0778 +:10AB2000F8C4021100198A0F42000003E001E80D89 +:10AB30003CF7F8C13C07F8C58A0F42000003E0016A +:10AB4000E80484033E07EA582E17EA5884003E07BB +:10AB5000F1855A1003313E07F1872E07F184C82B87 +:10AB60003C07F8C50211001EE001E91D0211001F9B +:10AB7000E020E9193C17F8C40251001CE025E91354 +:10AB80000251001DE0A1E90F2E67F1860251001A63 +:10AB9000E2C5E81184A13E57F1873C1BF8C03C0B8D +:10ABA000F8C1D5098402AE1AD5063E67F187D503F0 +:10ABB0003E67F19384003E07F1943C03F8C8CC054E +:10ABC0002E17EFFA5A180110A454E201E8058C017F +:10ABD0003C0BF8C8D52184013E07F1948404AE1AD9 +:10ABE000EB62D51A2E17F1875A18010E2E17F18530 +:10ABF0000251001BE225E8058C213E17F185D503A3 +:10AC00003E47F187A454E201E904EA423E07EA58CC +:10AC100084003C0BF8C82E27EA585CF10020E81F9E +:10AC20008C4C96908401E65EAE18AE998401E904DE +:10AC3000FA2EF803D5048022490039B98403EB6A5F +:10AC40008400EB62EA423E07EA5844000060DD43BC +:10AC50002E07F1708C013E07F170D5038400AE1809 +:10AC60003C0DFC5F3C1DFC01A404E220E9038400D0 +:10AC7000EBEDFCC0FC0084004412C1E0442FFFAAAD +:10AC8000AE08AE0AAE8984203E27EA58EB623C1B30 +:10AC9000F8C83E17F1943E07F1873E07F1863E075C +:10ACA000F1853E07F1923E07F184FC803C0DFC5F8C +:10ACB000A404DD9E2E07F194DD9E3C1396C0AC40AB +:10ACC000DD9E3C0FFBC8DD9EFC002E572C485A50E1 +:10ACD00001048401FC803C3DFB60A6D95A30090484 +:10ACE0005A3804193C339641994BE2239769E8049A +:10ACF0009A599649D50284202E47ECB2A0C2A003EF +:10AD0000403190774000101796D996012E472C8F2E +:10AD1000D51B44338D40A718CCDD3C339640994B6E +:10AD2000E2239769E8049A599649D50280242E6750 +:10AD3000EC94B460A00140319877400018172E477A +:10AD40002C8E96D9960144F002004252BC01E2A337 +:10AD5000E805A6108C01AE10D505E201E9FB8400E0 +:10AD6000AE10DD40A6015A0804048400AE10A610FF +:10AD7000E280E8B08400AE102E07F0198C013E0787 +:10AD8000F0198402FC80FC2005008013006F8018FD +:10AD9000011F801C55087FFFCA0F8381BE12442209 +:10ADA0000168B913EA64406118405420FFFFA6749B +:10ADB0009648CB16D524447200004103C04045207C +:10ADC0000064E2D1E8EB80F0427348735133806451 +:10ADD000182380014C79FFFE8CC197B0D5F34460F5 +:10ADE0000064FE7440108840446200644422000005 +:10ADF00088418826183100014C20FFFEAD00AD418E +:10AE0000FCA0FC20F6085A60010B4462DD8C38730C +:10AE100004004462D83839130400D503862284E93B +:10AE20008380B912450200005460FFFFFA38FE7CAF +:10AE3000BF14401098404063C00954737FFF4460C2 +:10AE4000006088304268982440631C40A7CFAFD888 +:10AE5000A6CEAEE0A6CCAEE8024000300230800DB7 +:10AE6000020000300210800C88648801F406F107AB +:10AE70004008002088D040380C20B664B601B406E3 +:10AE8000920A9637AE10FCA0FC408380BD14B81423 +:10AE9000446000485452FFFFEA52FEF4FF3440423F +:10AEA0000040403194404452000088A484008A64E9 +:10AEB00038619400386081090862800138610109B5 +:10AEC0008C015A0832F744020034888084A085231C +:10AED00039319002411094000D220001410114000B +:10AEE00084E04203A42402A880004069800D979763 +:10AEF000406519001A6880014009000D02680000D1 +:10AF00009617400301008CE11A0800015A780AEBF9 +:10AF10008CB45A5864DFFCC0040000134440006441 +:10AF2000FEE4EA5240018040443200008860840020 +:10AF30009908A7613840800040424008404217000D +:10AF40009950A76940421500385100008C0288854D +:10AF5000AB195A0832EFDD9E040000134440006430 +:10AF6000EA52FEE440318040EA9988608400A519E5 +:10AF700038408008A75B9908AF61B4833841000866 +:10AF8000A319995092888C02AF295A0832F2DD9E9B +:10AF90004412DD8C380080008E015C000009DD9ECB +:10AFA000E201E80AA610E260E8049AC3AED0DD9E92 +:10AFB0008400AE10DD9EE220E80BA61052F180FF67 +:10AFC000E00FE8048860AED0DD9E841FAE10DD9EE9 +:10AFD000FC60EEA8F0858141F28480E35A380105D7 +:10AFE0003C800ACFD506F9144E0200A43C800ACE5C +:10AFF0002E07ED0A84C1E602E9058E014063000CCC +:10B0000097B04063280E97B0CE0284C1B00A50BFFB +:10B010008024505F8021F081F105F004B088503F1A +:10B020008022504F8023B77FF78249FFFEECF00467 +:10B03000B064B0BD003F8022004F802349FFFF264F +:10B04000F86F49FFFF8BB0248120B00B838085808F +:10B0500044D000323855B2024400651099284400AB +:10B0600073E840E2800042063424F08584E039042D +:10B070009D015CF807FFE8492E17ED0B3932C1013D +:10B08000003F80208E214028040840098C164CA0E7 +:10B09000C0158844A4508A0840308C768A68EB3703 +:10B0A00042F00003E06FE90413310000D52E3807A9 +:10B0B0004101380E1C08D5294EA30006393241093A +:10B0C000F810D5168844A45040308C7640102001EA +:10B0D0008A68EB3742F08003E06FE90A1331000021 +:10B0E00038149D01382E1C003827050983FFF1050F +:10B0F000B0CB98B98843960180288066F487F5869E +:10B1000049FFFF50F407F5068CE15A7832B25094AB +:10B11000806451CE00325AC001048581D59CF00470 +:10B12000B04B502F805E003F802183FF49FFFEF629 +:10B13000ED58FCE0FC61F0818401B63F814280C3A0 +:10B14000EA6BDD475A0002048400EA66DD5484019C +:10B15000AE08DD58AE088400EBE32E07F01F5A0856 +:10B16000010684073E07ED0AD50C5A6801072E0731 +:10B170002C893E07ED0AD5052E072C883E07ED0ADF +:10B180002E07ED0A8C013E07ED0B44000060DD50F8 +:10B19000DD475A08024C5A6801074413F423EA3980 +:10B1A000EA38D50C440000618520DD50816944C334 +:10B1B000F04A4480005585A1D510A6085A0002F433 +:10B1C000AED0D5FC3C0DFBB7C81BE9FD5004800197 +:10B1D000EB93DD4B10D000002E07ED0BE320E8646D +:10B1E0003CBFFBB9EBE25A60010744000062DD504E +:10B1F00084E0D5188006EA2EEA8EC0FFD5F73CBF62 +:10B20000FBB7CE12EAB58E0154E000FF800E49FF75 +:10B21000FEC1C008800E8029B45F80668CE1F82DE5 +:10B2200097F8E2EAD5D38007D5F746B000F484E07A +:10B2300044C3F04A4480005585A150B582402E0792 +:10B24000ED0BE2E0E831EBE2F99D44000061DD50F6 +:10B250005A680105F001EB84D506DD408420DD56F7 +:10B26000490027C344000062DD5085204C95000D45 +:10B2700080098027B45F806649FFFEAC505480018E +:10B28000549280FFD5F4DD4B8CE1549380FF10D0B5 +:10B2900000005A6801062E77ED0B4C93BFD2800B4D +:10B2A000EB2980E9D5CD8400EA6B8400FCE1FC2128 +:10B2B0002E07F01FC8063C2396453C339646D5031F +:10B2C000EAFC80432E072BC784C0EA653C439640C6 +:10B2D0003C539641F08196904402EA0496D8B6DF3A +:10B2E00049FFFD53DD4780E0EA65DD405A78021BE7 +:10B2F00084488066F8245A0801053E07EFEAD54BDA +:10B30000DD408425AE4184213E17EF8C3E77EFD29D +:10B31000EA438441DD40EA658062F8113E67EF8CC4 +:10B32000D51A2E272BC78066F80ADD408429AE4146 +:10B33000EBA9EA438441EA658062DD4049FFFEFCF7 +:10B34000DD408026DD56DD40842AAE4184213E1753 +:10B35000F014EA4384013E07EC9A84033E07EFD2DF +:10B360008407DD508400EB60DD475A080206DD40AB +:10B37000842DAE41D50BDD408420DD562E17ECDE4A +:10B38000DD405A180203842AAE41DD40EA434400FE +:10B39000006FDD50FCA1FC20EEB0B0C8B187505F5B +:10B3A0008019F381F282503F801AB086504F801B83 +:10B3B000B6DFF08549FFFD27004F801BF005B06226 +:10B3C000B0BB003F801A49FFFD61F005003F8019C6 +:10B3D000B049502F805649FFFDC1840044300064BD +:10B3E00044400032B04942101073B1E28201385338 +:10B3F000020242700C738420382385015CF107FF40 +:10B40000E80539180400391289098C215A1832F6D6 +:10B410005A0001048401D5E7ED50FCA0FC61EA5D0F +:10B420008120FA218404DD428404FA22DD42EA62AA +:10B430003CADFB783C0FFB78DD41C004440000408C +:10B44000EA928404FA23DD4284C03CBC004A9DF1A8 +:10B4500097F8EAE38007802BEAB1EB55002F8006CE +:10B460008E41E648E90580C75A7820F3D508800B5D +:10B4700080268440F814EB195A0808F73CBC004CAD +:10B4800084C09DF197F88007802BEAE3EAB1EB5581 +:10B49000EB195A080908800B8026844149FFFF7D7B +:10B4A000D50480C75A7820EF8404FA24DD42DD41B8 +:10B4B000C81BEAD8804144300C808402DD44441328 +:10B4C0001F408041EA608402DD4444000040EA926B +:10B4D00084024412988A4422168044300640DD4497 +:10B4E00044000044EA928404FA25DD42DD41C00FA5 +:10B4F000EA6F441373E8DD5F44031F4044138DD4A7 +:10B50000442000C8EB2A44000044EA928404FA264E +:10B51000DD423CAFFB78DD41C804EA28EA22D505CC +:10B52000EA4BEA33EA46D507000480515A00BB04CF +:10B53000AE88D5FBEA74DD41C004EA84EAD8DD5F59 +:10B54000DD41C805100480508401EAE6FCE1FC00FE +:10B55000DD475A0802158400EAEF8401EA6BDD45F5 +:10B56000DD46AE40DD59A640C9FFA6405A1801FF8E +:10B57000DD4B8422AE408400EA6BD50BEBBAEBA521 +:10B58000EB2949FFE4B7DD408420DD564900262D34 +:10B5900044000065DD50DD41C00DDD46DD45AE40B7 +:10B5A00049FFB8FEC0FEEA6FEB33FA50EAF249FFFA +:10B5B000DEF5FC80FC24442151D0EB85444151E070 +:10B5C000B084EBBF3B024C003B014C20390102022E +:10B5D0004421D80040210040A79080E197B0381F57 +:10B5E000820284804513651045226238EB3BE2827B +:10B5F000E81994E14021C400033100004021C80053 +:10B60000994BA490383810008C81FE9CA4E840210E +:10B61000180E8A53969340211C568843ACA8972154 +:10B62000D5E644200C804431A200423008738003E8 +:10B6300049FFB41AFCA4FC6184C08401EB0D3E6791 +:10B64000ECA88126EA6B80E6850485A644E38D405C +:10B650005A78040B8400DD578040EA4A3ED7EFD287 +:10B660008581EA90D50B80073E87EFD2F81981805B +:10B67000DD5784038047EA4AEA90DD4B8421AE40DF +:10B680009E39854054B000FF4CA60030DD59A640DD +:10B69000C9FFDD41C00EE2C9E80CC70B800B4900B1 +:10B6A0001FF5F0818CC1800BF10197B049FFFF8439 +:10B6B00000170000DD595A180311A6405A1801FF5F +:10B6C000DD41C007DD5B5A0806FFEA6FEAAFDD5FC8 +:10B6D00050048001EB93D504A6405A1801FF500591 +:10B6E000000154A000FFD5D18CE197F85A7805B23B +:10B6F0008400EA6B8400FCE1FC45442151F0447273 +:10B700000000EB85B042442152003B00CC20EB8589 +:10B71000A6BA81208400B186EA573810A602EB1B36 +:10B72000A6FB92413B034C20EB48EB1B381326024F +:10B73000A6BAA6FBEB48FCC53C0FFBC9DD9E3C0F3F +:10B74000FBCBDD9EFC008420DD56DD548400AE087A +:10B75000DD58AE088401EA2E84018440842A80806A +:10B76000806280A2DD53DD46DD45AE40EA8EC8042E +:10B770003C0DFBB6C0FCDD41C0168401DD49DD4651 +:10B78000DD45AE4049FFB80CC0FE8402DD49DD470F +:10B790005A000214EA27EB09AE0880418461840252 +:10B7A000DD44D50BDD475A000209DD46DD45AE40DC +:10B7B000EA27A6085A0832FFDD475A0802072E0773 +:10B7C000ECA08C013E07ECA0FC8080A03C0DFBC9E6 +:10B7D0003C3C023BA6839222E2A2E827CD09A419B1 +:10B7E0009649F829F8194EF2009448000090F85D47 +:10B7F0009F118805DC08F8469603E020F80A4EF30E +:10B800000086DD9EF8684EF300828C048803F8728F +:10B810004EF3007D884540218820A4109603E02047 +:10B8200083FF4EF30074DD9E8483FF14E2A4E926B7 +:10B83000DC0DF8279603E0204EF3006983FF9AAAF7 +:10B840004E00FFEB4EF30063DD9E9512F82E8E81C5 +:10B850008805DC05F817F80DF808DD9EF83CE95678 +:10B860008C048803A400F8059AAA40218820A4101B +:10B870009603E020E94B83FFDD9ED2039411D81399 +:10B880009C2940018020A400964983FF4E00FFF2CE +:10B890009A2A40018020A4004E00FFEC88454E000B +:10B8A000FFE6DD9EFC009F814607FFFFEAB883FFAD +:10B8B0008805D6038E81DC0F4E00FFE59603E0205D +:10B8C000E8048401EA3CFC80F812E9FC4E00FFA485 +:10B8D000E9F9FC8094019918A52096499723E02462 +:10B8E00083FFE9F08C048803F805E9EC9A2A40010B +:10B8F0008020A4009603E02083FFE9E4982A4021F9 +:10B9000080204E00FF8CE9DEFC808401EA3CDD9E55 +:10B910002E17EC81C1092E27301AE241E9048E214D +:10B920009648D50284204422E89438310501E2602B +:10B93000E92BFC20840038010509EA85842084A3D2 +:10B940003C3C02393C0C023A3C4C024294898862ED +:10B9500088028881A598A5C0A62088074203147391 +:10B96000404008099721AD183C4C02393C3C02424A +:10B970008844A49088614000084196008C21AE184C +:10B980005A18C8E0FCA0DD9EFC005A0801122E10D7 +:10B9900011312E0011305A1801048E03D5028E0287 +:10B9A000960084408020806249000860FC80490045 +:10B9B000086FFC80A641EA915A1804112E17EC8FEB +:10B9C000C903A602D502A6032E17ECEE5A180208E8 +:10B9D000E604E9058E039600DD9EA604DD9E540074 +:10B9E00000FD5A0804053C03F8CDDD9EEA910200F3 +:10B9F0000009DD9E5A0804053C03F8CCDD9EEA915F +:10BA00000200000ADD9EEA91A400DD9EB400EA91E6 +:10BA1000A447020000083C1BF8CD3C0BF8CCDD9E8F +:10BA20002E17EC86C90984423E17EA3C3E27ECC437 +:10BA30003E17ECA8EA54DD9EFC00DD46DD45AE4035 +:10BA40003C0DFBB6C810EA705A0801064402C192C8 +:10BA500049FFDB6C8401844080208062808080A26A +:10BA6000DD53D5EF8406DD49DD41C01DEA27EA3903 +:10BA7000EA38A6085A003204AED0D5FCEA28EA22F9 +:10BA8000DD5B5A000604AE88D5FC4412C2988402DD +:10BA900080418461DD442E07F014C003840AD5027E +:10BAA0008409EA23EA6744100033AE402E07EE30E3 +:10BAB000C81149FFC28A5A00A10EDD418020C80783 +:10BAC000840280418061848380A1DD5349FFE1F0DD +:10BAD000FC80840E49FFDA7EFC80FC00DD475A08BA +:10BAE00002074403F422A600961FFC808400FC8019 +:10BAF000FC2084003C0BF6A9DD4084233C7DFB5FE9 +:10BB000084C1AE41EBE1EA43DD4FA600842397F800 +:10BB1000490013313C7FFB5FEB8EC80A2E07ECCB4C +:10BB2000C8078409DD493E67ECDC3E67EC9ADD40DE +:10BB3000EA43DD5484003E07ECCB8401AE08DD58B7 +:10BB4000AE08EA245A0004048405EA7C2E07ECE4DB +:10BB50008420C8093C1DFBCBA448E622E9038E22C1 +:10BB6000D50280203C1FFC01EB8A5A18020FC8093D +:10BB70003C1DFBCBA448E62AE9055000FFF6D502A0 +:10BB80008400EA3FFA18EA8784013E07ECE6840065 +:10BB9000EAB7FCA0FC0084C03C6FFB9BEB0DEBBE46 +:10BBA000EB50EBDA8401EA2EDD59AF80EBBEFC806E +:10BBB000FC00DD40A601EB1C5A080911EA245A00DA +:10BBC00004048405EA7C2E07ECE4C808F803E602C6 +:10BBD000E90549FFF86D8E02D5028400EA3FF818A6 +:10BBE00049FFE16DDD408429AE418420DD56DD4012 +:10BBF000842AAE41EA43490022F884008421EA2CD9 +:10BC00003E17F014EAB749FFF8374900358449FF79 +:10BC1000E164FC80EA913C3C023BA5038420840162 +:10BC20009899A4909693E082E80284008C225A1995 +:10BC300090F9DD9EFC202E17ECC45A18020B2E172B +:10BC4000EA3CC9072E17ECEC8E225C108001D5026D +:10BC500084203C6DFBC93C4DFA973C7C023A84A0A1 +:10BC60008461864353300000A6B351138002510112 +:10BC70007FFF4C58001D410104088F814C5800186B +:10BC8000430148248F814C58001394928E41D20F67 +:10BC9000A4B8027880008A479693E00238221509FA +:10BCA000E903E053E8045A18010384628CA180F18F +:10BCB0005A58C7DC5A18011C401004098440FF4A36 +:10BCC00038720911E027E807A633880238F201111B +:10BCD000E02FE909E0E5E808A633880238020111FF +:10BCE000E005E80284628C415A2895EC8003FCA0B0 +:10BCF00084204422E894380105098C215A1808FD53 +:10BD0000DD9EFC4080E0A60080C25A08051E84012A +:10BD1000AE38DD4085203C9BF7E8A601EAC2F81565 +:10BD20003C13F6A8E62AE8058C213C1BF6A8D5139F +:10BD30003C9BF6A8A430E619E804EA5F8400F80505 +:10BD40008400AC30D508840049FFFFD48400AC30B7 +:10BD50003C0BF6A8FCC0FC01DD40A601EAC2F08164 +:10BD6000F1014402C1544422C1A849FFFFCC2E175F +:10BD7000ECEC8400EA593E07ECADC9033E07ECAF9A +:10BD80008400EBDAEA42EA88FC81FC20FD30EB50CB +:10BD900080A0A630AF70C5092E17301A84C0E225E6 +:10BDA000E9059FA997B0D50280C5D01DDD475A0887 +:10BDB000021B3C3DFBC98400A65B9449E001E80DF1 +:10BDC0008387BA09BC0B944188418824A4488C011C +:10BDD0009649AC509600D5F13C03F68CC00E8E010E +:10BDE000EA59D50B4402E894385019014410FFFF7A +:10BDF000D1048CA1385019092E17ECAF4000980ED1 +:10BE00009604C81B0513800A050380090453800BA0 +:10BE100040380000A498404880009691ACA0A498B7 +:10BE2000992896918C02ACA05A0990F48401406044 +:10BE3000180CFE773E17ECAFFCA0FC002E27301A42 +:10BE4000441000FF4020880C4413F422A648FE93BF +:10BE5000965F9690C1038E219648A78084A14042A8 +:10BE6000840CFF37972296E0AEC04C61800D4C31B8 +:10BE7000000B88254052840CFF679768FF5D5C02C9 +:10BE80008001FC808005FC80FC008400EA59EA8582 +:10BE9000EA3CDD40A6015A080422EA24C80944020B +:10BEA000C11749FFFFCC5A0801048403EA7CEA2445 +:10BEB0005A08031D4402D90C842044200320EA4C74 +:10BEC000EA30C807EABAA600962EC8038404D50A49 +:10BED0008401EA7C8400EB38D5092E07EA3CC804CB +:10BEE0008402EA7CD503EA30D5F1EA245A08020537 +:10BEF00084003E07ED0C840080804452E26C3C3CA0 +:10BF0000023894418861A4D83C2C023A96D98841E1 +:10BF1000ACD03C2C02393C3C023A88418823A448EE +:10BF20009649AC503C1C02428820AF083842800839 +:10BF30008C015A08C8E6FC80FC208407DD4984C0D7 +:10BF4000DD403E67EF8CEA43DD4B84213E67ECA089 +:10BF5000AE4084003C0FFBADEA75EA963C2DFBAD8C +:10BF6000CA098401AFF080208062808080A2DD5306 +:10BF7000D5F6DD46DD45AE40EA8EC80B3C2DFBB65E +:10BF8000CA08840184278062808080A2DD53D5F5B1 +:10BF90008421DD40DD56DD41EA28EA22C00E84001E +:10BFA000EA37AE883C2DFB5FCA2484018020806282 +:10BFB000808080A2DD53D5F7AE88EB83C009840171 +:10BFC000844080208062808080A2DD53D5F749FFC5 +:10BFD000E735EB3E5A0803048402D5028401EA37B0 +:10BFE0004412C1E48401EAE6804184028461DD44B4 +:10BFF0008408DD49DD40EA43FCA0FC4080E1842068 +:10C000003E17ECA84090080884C0E0C9E8143C2C16 +:10C01000023B40211820A4909693E0E2E809FD033A +:10C0200049FFFBD5EAAAC0043E67EF28FCC08CC1DB +:10C0300097B0D5ECFCC0FC6080E180C04412DD24E8 +:10C040004402C0E949FFFEA34400FFFF84A03C1D59 +:10C05000FBCBA97AA83B00008016E610E8045250FA +:10C06000001097688520FB80430040013D3DFBC9DF +:10C070003CAC023A3CBC02383C8C023B3CCC023922 +:10C080002ED7EA3C2EE7ECEC2F27ED0C8049451229 +:10C09000E26C82890009800394C2E043E85B40912E +:10C0A000040840452400A4E04005A400A400FEECE0 +:10C0B00042304073926496D9ACE040342400892C1D +:10C0C000A42002F480008A0F9603AC18A4D8A40D13 +:10C0D00096DBFE02E060E81A5AD001045AE8021723 +:10C0E000380888008C01960038088808A4CEE260E1 +:10C0F000E813A42086419601EAFE2E07EF2939486D +:10C1000088088C013E07EF29D50738088800C0044D +:10C110008E0138088808A4E0A03AE203E803A420CE +:10C12000A83AA4E0A03BE260E803A420A83BA03A20 +:10C130003C37F6A9E260E8033C0BF6A9A6315A08A1 +:10C14000090502908003D503029080048C419690EB +:10C15000D5A280293F27ED0C49FFFF51DD40A60104 +:10C160005A080907800949FFFD673E07ECC4FCE057 +:10C17000FC4080E0A60180C15A0804299E0CE60418 +:10C18000E90A5A100C09EA245A000406EA305A084F +:10C190000109D50ADD41C817EBEB5A080115D5F79F +:10C1A000EB3D5A080107DD41C80BEBEB5A080109CA +:10C1B0002E07EC8F5A080103EBBE8007EB84EA32AE +:10C1C000EBAEEBAA8400EB38D508EA245A0004064B +:10C1D00049FFDE788007EB84DD414E02007B3C03A3 +:10C1E000F6A04412E0CC8C01EA853C03F68C8C016D +:10C1F000EA59800749FFFF21EB3FA600C0058401F3 +:10C20000EA3C8400EA3FEAAA5A08011584003E0786 +:10C21000ECAD84002E17301A4432E894808096806A +:10C22000E241E805384181098C01D5FAEA9EDD43F7 +:10C23000D5242E97EA3C5A9801159E34E602E9115E +:10C240004402E0CC3C1396434422C11549FFF53E1D +:10C250005A080208FA01DD433E97ECA83E97ECF33A +:10C260004412FEFCA6085A08A5098401EB60EA3CCA +:10C270003E07ECF38400AE082E07EA3CC82AA63835 +:10C280005A080228EA245A00010A2E07ED0C5A081F +:10C2900001182E07ECC45A08011449FFFCBDC8045C +:10C2A000EA3CEA85D50D840184E0EA7D3E77EFFA29 +:10C2B00049FFEFC3EA245A0802043E77ECECEA2473 +:10C2C0005A0802082E07ECC45A0802048400EA3C0B +:10C2D000EA42EA889E34E602E80CDD41C004EA4BFB +:10C2E000EA33EA468400EA3C8400EA59EA85D50547 +:10C2F0005A6802048401EA3CEB3D5A000105EA3029 +:10C300005A08010584013E07EC98EAB05A08010476 +:10C31000EA3CEA7DFCC09200E60F4EF2007444F065 +:10C32000C128EA81EA36DD0F102E46DA6298DADAA1 +:10C33000DADADADADADAA4008401EABEAE084423F3 +:10C34000F2498422AE504423F24AAE104423F24B09 +:10C35000AE508464D529841FEABEAE08EB95AE08C2 +:10C360004413F24AAE08EBF3AE088448D53C84018E +:10C37000EABEAE08EB95AE084413F24AAE08EBF302 +:10C38000AE084413F24CAE08D5318401EABEAE08C3 +:10C390004423F2498424AE504423F24AAE1044238D +:10C3A000F24BAE50846C4423F24CAED04423F24D99 +:10C3B000AE504423F24EAE104423F24FAE50D51F80 +:10C3C0008400EABEAE08EB95AE08D507EABE84004D +:10C3D000AE08845FEB95AE884413F24AAE08EBF3E7 +:10C3E000AE0884414413F24CAE884413F24DAE08BB +:10C3F0004413F24EAE084413F24FAE084413F25009 +:10C40000AE08DD9E9200C102EA7696004413F25116 +:10C41000AE08DD9E40003C0892104423F244EBDC61 +:10C42000AC1092304403F246AC40DD9E84214403BC +:10C43000F240AE40EA22EA28AE88A6405A1001FF38 +:10C44000DD9E4413F258A448AC404413F25AA44869 +:10C45000AC414413F25CA448AC424413F25EA448DD +:10C46000AC434413F260A64810100008DD9EFC02A5 +:10C47000F0818002F383F18249FFFF50F001F10265 +:10C4800049FFFFCA49FFFFD4F00349FFFFDCFC82EC +:10C49000FC02F0814403F242F182F283AF40001FBC +:10C4A00080204403F243AE404403F252ACC0440344 +:10C4B000F254AD0084214403F256AC40001F8024A6 +:10C4C0004403F241AE40000F8028001F802C49FF3A +:10C4D000FF9CF001F102F203F30C49FFFFCAFC825A +:10C4E000FC203C6DFBCC97C4050300025510800F67 +:10C4F00043085C0940781EE44273D809470FFF0FD8 +:10C500004273D40951080FFF4073C0028E2A86403F +:10C510004073C604E625A9F2132300031123000B80 +:10C520004EF2007C012F8038011F8030010F8034D3 +:10C53000007F802C44F0C340EB27EA934A003C0084 +:10C54000060606767600C003EB6CD5034021BC08D6 +:10C55000F00792509201AC32F00692A192011203C0 +:10C56000000BF008926192011203000EF009ACB0CA +:10C5700092011203000F220F801E1203000C220FE3 +:10C5800080201203000D020F8022AD718C01ACF4EB +:10C590001123000C1113000D1103000E1073000F76 +:10C5A0001123001011130011110300121073001356 +:10C5B0001203000AD532C003EB6CD5034021BC083E +:10C5C000F00A92509201AC328400100300108401F2 +:10C5D00092819261100300118400ACB0AD31ACF4D3 +:10C5E0001123000C1113000D1103000E1073000F26 +:10C5F00011030012107300131123001411130015FE +:10C6000011030016107300171203000C1203000D23 +:10C610001203000E1203000F4403F1408421AE40C8 +:10C62000EA39EA38A6405A180104AED0D5FCFCA07D +:10C6300044038CF03C0FFBCC441FC6784403F1420A +:10C64000AC40840044138D08B6013C1DFBCCA80F00 +:10C650003C1DFBCC14008008DD9E84203C0FFB7049 +:10C66000AC43DD9E3C3DFB70920192219241AC189F +:10C67000AC59AC9ADD9E3C1DFB70A6821020800C4C +:10C68000A6831020800DA680A6011020800E100029 +:10C69000800FDD9E3C1DFB70A68210208010A683BB +:10C6A00010208011A680A601102080121000801397 +:10C6B000DD9E3C1DFB70A68210208014A6831020F6 +:10C6C0008015A680A6011020801610008017DD9E20 +:10C6D000FC01B63FF28149FFFFD0B41F49FFFFDCE8 +:10C6E000F00149FFFFE8FC81FC24007F8060F081BD +:10C6F000F182F283001F803C002F8038000F8040C1 +:10C70000006F804C105F8016103F8014102F801730 +:10C71000104F8015101F801A103F8018100F801BBB +:10C72000104F8019CF08105F801E103F801C102F03 +:10C73000801FD507101F801E103F801C100F801F08 +:10C740003C0DFBCC104F801DF855B005B046B087AE +:10C75000F856F001F102F203F8573C0DFB70021F8E +:10C760008028AC44001F8054002F8044FE77526321 +:10C77000002040609824001F80481060000A581074 +:10C780008040FE571010000B221F802C1210000C4E +:10C79000221F802E1210000DDD46DD45AE40440301 +:10C7A000F1408421AE40A6405A1001FFFCA4FC04D5 +:10C7B000F08194199600F182100F80178422100FD7 +:10C7C000801B84C13C0DFBCC103F8014104F8015A2 +:10C7D000103F8018104F8019103F801C103F801FA1 +:10C7E000104F801DF283101F8016101F801A106FCB +:10C7F000801E49FFFF34B005B046B08749FFFF6A8D +:10C80000F001F102F20349FFFF2F3C0DFB70842081 +:10C810008449AC441010000B1020000ADD46DD45B1 +:10C82000AE404403F140AF80A6405A1001FFFC84A3 +:10C830004403F148A6404403F149A600EB329601B7 +:10C84000DD9E44100055DD45AE40EA83A6085A003F +:10C8500001FF84214403F380AE40EA22EA28AE8837 +:10C86000A6405A1001FFDD9EFC004413F381A60888 +:10C87000EB17AE0884004413F384AE084413F56B41 +:10C88000AE0849FFFFE0FC804453F381A72896D807 +:10C89000544200F0FEA7401104449688400100E491 +:10C8A00096804403F384AEA8AEC0DD9E840044139A +:10C8B000F386AE084413F387AE08DD9EFC604403A4 +:10C8C000F38496D8AEC049FFFFBEDD46DD45AE40DD +:10C8D0004413F380A6085A0001FF4473F3864463AF +:10C8E000F3874493F04A44A0005544B3F380A6383C +:10C8F0005A08010C49FFFFDC49FFFFA5EBC6000504 +:10C9000080005A0001FED5F4A6305A0001F5FCE083 +:10C91000DD9E441E00008801920296014413F3CA72 +:10C92000AC08DD9E4413F280A608EA4DAE08DD9EF9 +:10C930004423F280A650400080A49600AE10DD9EF5 +:10C94000441E0000880196814413F286AC884200A0 +:10C95000400B4413F288AE08DD9EFC600020000905 +:10C960004473F28096D4A6B880C06621000200000D +:10C97000000A40210C243C7FFBCEAEB89684A6383A +:10C980008121EA8D40000844AE38A4704403F2844B +:10C99000AC40A03149FFFFD6001300084403F283E6 +:10C9A000AE4044A3F04A44B000550003000B49FFD9 +:10C9B000FFC149FFFFB9A6389604C00410B50000B6 +:10C9C000D5FB4403F2813C0FFBCD5A980307A640E8 +:10C9D0004210880BC1EBD5085A980105A600EA6CF5 +:10C9E000D5055A980205A600EAA6C0E0FCE0C808F2 +:10C9F00044138D25A6088C019600AE08D50E44235D +:10CA00008D26A6508C219648AE505A080107441333 +:10CA1000F060A608EA71D5064413F060A608540039 +:10CA200000FBAE08DD9E96004413F068AE08DD9E64 +:10CA30004423F053A6509604EB0B88019600AE10E9 +:10CA4000DD9E4413F06AA6889604542100FEAE8849 +:10CA5000A68888029600AE08DD9E4423F054AC10F0 +:10CA60004403F056AC40DD9E4031C8084021898027 +:10CA70008802401004C084A54443F06D4403F06E66 +:10CA8000AF603C1FFBCF3A100420DD9E842044039E +:10CA9000F06DAE40DD9E4403F061A600EA6CDD9EC1 +:10CAA0004403F061A6009207DD9EFC0049FFFFFAF7 +:10CAB000C80749FFFFF25A0001068401FC80840088 +:10CAC000FC808402FC80FC004463F00EA430420031 +:10CAD000200BC00744138D24F81C84084800007BF9 +:10CAE000A430EA9DC859A430EAA6C00644138D2399 +:10CAF000F8108403D56FA430EA6CC00644138D226D +:10CB0000F8088402D567A430EAEAC00A44138D21EC +:10CB1000A6088C019600AE0883FF8404D55BA43080 +:10CB20009604C04E49FF9D5DA4304200180BC836E4 +:10CB3000A4304200140BC834A43042001C0BC8328D +:10CB4000A4304200240BC00B4403F064A640964C72 +:10CB5000C12BA640EB0BAE408409D53CEB82A44030 +:10CB60004210A80BC923A4404210AC0BC921A44019 +:10CB70004210B00BC91FA4404210B40BC91DA44001 +:10CB80004210B80BC91BA400920FC01A84013E07C3 +:10CB9000EFC4840FD51F8401D51D8406D51B8405E1 +:10CBA000D5198407D5178409D515840AD513840BA4 +:10CBB000D511840CD50F840DD50D840ED50B4403EF +:10CBC000F01AA400EA9DC00549FF9D0BFA01D502A9 +:10CBD000FA0884204423F00EAC504423F01AAC50E1 +:10CBE000FC8084214403F322AE40DD9E4413F323F2 +:10CBF000AE08DD9E4403F323A600DD9EFC004463E3 +:10CC0000F540B6064403F544B6204403F548B64063 +:10CC10004403F54CB6604403F550B6804403F55424 +:10CC2000B6A0F1044403F558B620F1054403F55CC1 +:10CC3000B620FC80FC614433F5044423F502441320 +:10CC4000F5033C3FFBD14433F50580C03C2FFBD4BA +:10CC50003C1FFBD33C3FFBD05A0003044800014675 +:10CC6000DD414413F51AC0048401AE08D502AE08B4 +:10CC70004403F5788420AE40843FAE40442FFFAAA1 +:10CC80004403F579AE8084C1AE404403F500AF8023 +:10CC90008400802080408060EA3B84234403F501C7 +:10CCA000AE408400802080408060EA3BEB02A60812 +:10CCB000EA8CAE088400802080408060EA3B44001B +:10CCC0000802EA2A3C1DFBD3A608EA8CAE088400C1 +:10CCD000802080408060EA3B4400041AEA2ADD4656 +:10CCE0004403F509AE408400802080408060EA3B28 +:10CCF000EB02A608EA4DAE083C0DFBD3A6805821F6 +:10CD00000001AE80A68858210004AE88A680582174 +:10CD10000004AE80A68858210008AE88A68058215D +:10CD20000008AE80A68858210010AE88A640581092 +:10CD30008010AE408400802080408060EA3B440048 +:10CD400005AAEA2AEB02A608EAF0AE083C1DFBD3CE +:10CD5000A608EAF0AE088400802080408060EA3BAC +:10CD60002E07ECC74E030117DD403E67ECC7A60156 +:10CD7000B61FDD47DD575A0802058404AE09D50306 +:10CD80008409AE098501DD403E87EF8CEA433C2DE6 +:10CD9000FB7844020168046100128420EA64406068 +:10CDA000184004A30003049300034005100954A095 +:10CDB000000340049809960F3E17EF8CF081A1F311 +:10CDC000A03344B3F68066000030EAA4A833A03351 +:10CDD000FA6F660000C058000080A833A03392E8C4 +:10CDE0006600030058000200A83304410013844C7D +:10CDF000929054027FFFA73597CFFF144042004026 +:10CE0000EA9940E2000004D700004608000804C781 +:10CE1000000140068002B60E460F000F40060002D9 +:10CE2000140700014423F683841F10858000AE1090 +:10CE30004423F684AE104423F685AE104423F686D0 +:10CE4000AE104403F687AE404403F688AE40440378 +:10CE5000F689AE404403F68AAE40840080208040CC +:10CE6000EA3B4403F40BA64044200039548080FF81 +:10CE70004413F415AE888424AE408401EA2E4400A5 +:10CE800005AAEA2ADD46DD45AE40EA8EC0FF8400F1 +:10CE900085208020109580008040FA6FEA3B440393 +:10CEA000F415EB784403F40B10800000A033660007 +:10CEB000003040A0288414A30003A033F1016600D1 +:10CEC00000C0409004C414930003A0336600030024 +:10CED00040701D04A9F3DD40001F800014D700003E +:10CEE00014C70001AE41D556C83184414413F50042 +:10CEF000AE8884434413F501AE883C2DFBD480609A +:10CF0000A65058108002AE503C2DFBD3A6505810AE +:10CF10008002AE5080208040EA3BEB028066A6088B +:10CF2000EA71AE083C0DFBD3A68058210004AE8008 +:10CF3000A68858210008AE88A64080465810800870 +:10CF4000AE4080068026EA3BD5255A080124A6D0AB +:10CF5000A608543180F3540000F3AED0AE0884002C +:10CF6000802080408060EA3B84004413F500AE08D6 +:10CF70004413F501AE08EB02A608EA73AE083C1DA7 +:10CF8000FBD3A608EA73AE0884008020804080604E +:10CF9000EA3BFCE1DD9E46108000EB21EAED421009 +:10CFA000EC0940008364EA7ADD9E46100800EB211C +:10CFB000EAED4210DC09400082E4EA7ADD9E441189 +:10CFC0000000EB21EAED4210C00940008204EA7A39 +:10CFD000DD9E44108000EB21EAED4210BC094000C8 +:10CFE00081E4EA7ADD9E441002006413280364138E +:10CFF00008026610820040008124EB514413F7EFD1 +:10D00000A60896009684C203EA9CAE08DD9E8422A0 +:10D01000EB21EAED6610800240008024EA7ADD9E72 +:10D0200064120002C00458008001D503660080012C +:10D0300064020003DD9EDD9EDD9EDD9EFC4080E0FF +:10D040004403F040A780812181425463001C5A7838 +:10D050000225DD41C0144422FEF64433F04AEB5A67 +:10D06000A6104412FEF65A00EC04AF18D5FA84005C +:10D07000AE08804184618402DD44D50A4412FEF684 +:10D08000440FFFECAE08804180078461DD44EA670D +:10D09000FA30AE408400EA6684004413F00EAC0817 +:10D0A000FFBF4413F01AAC0897B04403F040AF80C0 +:10D0B000DD46DD45AE405A78020A4410005AAE40C3 +:10D0C000490000FBC8FEEA7AEB514413F0DAA608E7 +:10D0D000EB17402500049690AE88540480FF44135B +:10D0E000F0EDAE08DD464403F041AE40EA29EA29FE +:10D0F000EA29EA29EA29EA29EA29FCC0400004A42D +:10D100004423F0429600A6D0AE10DD9E965F9604B2 +:10D11000400080844413F043AE08DD9E4413F04485 +:10D12000AC08DD9E540000FD4413F046AE08DD9EC1 +:10D1300040003C0892104433F200EBDCAC18923013 +:10D140004403F202EB6CAC4092504403F204AC8016 +:10D15000DD9E4403F20AA640EA22EB0B5810800140 +:10D16000AE40EA28AE88A640964CC9FEDD9E9600E9 +:10D170004423F206AE1096484403F207AE40DD9E0B +:10D18000FC00DD41C004440255B8FC80440215B8DF +:10D19000FC80FC00DD41C00444024A00FC804402E3 +:10D1A0000A00FC804403F20BA600DD9E4413F20843 +:10D1B000AC08DD9E4423F20AA650964C4000802421 +:10D1C0009600AE10DD9E9200E608E82344F0CFD82A +:10D1D000EA81EA364A003C00080E141A20262C3256 +:10D1E0004403F20CD5154403F20ED5124403F21099 +:10D1F000D50F4403F212D50C4403F214D5094403AD +:10D20000F216D5064403F218D5034403F21AAE40D1 +:10D21000DD9E9200E608E82344F0D024EA81EA3655 +:10D220004A003C00080E141A20262C324403F20D4A +:10D23000D5154403F20FD5124403F211D50F440360 +:10D24000F213D50C4403F215D5094403F217D506A1 +:10D250004403F219D5034403F21BAE40DD9E920055 +:10D260004403F0C4A600DD9E96004413F0C4AE084B +:10D27000DD9E4403F0C3A600DD9E96004413F0C378 +:10D28000AE08DD9E4403F0CEA4004413F0D0A648BF +:10D29000400080E4441D020088015C000080DD9EA7 +:10D2A0004402FE00DD9E84214403F0F5AE40DD46DD +:10D2B000DD45AE40DD9E4403F0F4A6009204DD9E01 +:10D2C0004403F0F7A600DD9E96004413F0F7AE0885 +:10D2D000DD9E4403F0F6A600DD9E96004413F0F6B2 +:10D2E000AE08DD9E4452FE004412FE3E180280014C +:10D2F000D9FEDD9EFC40440000FD49FFFFF544637C +:10D30000F068EA89EA8FF803FA09EA2AA630EB9E68 +:10D3100049FFFB8B44000492EA2AEA5FD5F5FC0042 +:10D3200049FFFFEA92004423F0C7A65096485A08E6 +:10D330000105581080C0D502966FAE50DD9EFC00EE +:10D34000441005FC4403F0CEAC4084204403F0D0EC +:10D35000AE40840149FFFFE9FC804423F0ECA65075 +:10D360009604541080FB40008044AE10DD9EFC000B +:10D3700049FFFFF5FC804403F0CEA4004413F0D035 +:10D38000A648400080E4EAA5FE0DEAF5DD9E920283 +:10D390004413F0E6AC08DD9E4413F050A608580094 +:10D3A0000080AE08DD9E4413F050A6089637AE0804 +:10D3B000DD9E4423F050A6509617541080F8FE4787 +:10D3C000AE50DD9E4423F050A65096175410808F27 +:10D3D00040008084AE10DD9E4413F050A608EAD3CE +:10D3E000AE08DD9E4413F050A608540000F7AE08C6 +:10D3F000DD9E4413F051A608EA4DAE08DD9EFC0008 +:10D40000840749FFFFD884204403F04CAE408407D2 +:10D4100049FFFFDA84214403F04EAE4049FFFFEBA1 +:10D42000FC8096004413F04CAE08DD9E4403F04DA2 +:10D43000A600DD9E3C0FFC68DD9E3C0DFC68A6004E +:10D44000DD9E44030FA0EAAF3C0FFB823C1FFB595B +:10D450003C0FFB61DD9EC0045A000209DD9E3C0DBD +:10D46000FC68A6003C0FFA98DD9E3C1FFA98DD9EF2 +:10D4700040003C0892104433F1C4EBDCAC1892300D +:10D480004403F1C6EB6CAC4092504403F1C8AC804D +:10D49000DD9EFC00EB2DA682A6434403F1C2AE80C4 +:10D4A0004403F1C3AE403C0DFB823C1DFB593C2DB7 +:10D4B000FB6149FFFFDFFC8084003C0FFBB284214D +:10D4C0004403F1C0AE40DD9EFC602EB72B9A2EA720 +:10D4D0002BBD2E972BBCEBD74E03007B2E00107A72 +:10D4E000C8113C00082250F07FB05CF78BE0E808E0 +:10D4F0003C00082350F07FB05CF79360E90384019F +:10D50000D50284003E07F19C3C0DFB79EAE0E80778 +:10D51000EA3AC01AEADA84CCC018D5165CF008FCE6 +:10D52000E807EA3AC011EADA84C4C00FD50D5CF00E +:10D530000A8CE807EA3AC008EADA84C5C006D504CE +:10D5400084003E07F19C84CF4413F1C210B08000E8 +:10D550004413F1C310A080004423F1C4441FAC481D +:10D56000AC50443FA6084423F1C6ACD04423F1C8D4 +:10D57000AC5096304413F1C1AE08F896DD46DD4557 +:10D58000AE40EB16A6085A0001FF4403F1C210B0EA +:10D5900000004403F1C310A000004413F1C4440F81 +:10D5A000ADD8AC08442FA7984413F1C6AC884413F7 +:10D5B000F1C8AC0897B04403F1C1AF80F875DD46FF +:10D5C000DD45AE40EB16A6085A0001FFD5615A08AA +:10D5D0000160EA5EEAE0E807EA3AC01AEADA84CCD7 +:10D5E000C018D5165CF008FCE807EA3AC011EADA80 +:10D5F00084C4C00FD50D5CF00A8CE807EA3AC00875 +:10D60000EADA84C5C006D50484003E07F19C84CFC5 +:10D610004413F1C2109080004413F1C3AFC84423F7 +:10D62000F1C4441FAD10AC50443FA6D04423F1C612 +:10D63000ACD04423F1C8AC5096304413F1C1AE08CD +:10D64000F833DD46DD45AE40EB16A6085A0001FF73 +:10D650004403F1C2EB784403F1C3AFC04413F1C4F7 +:10D66000440FAEA0AC08442FA8604413F1C6AC88A8 +:10D670004413F1C8AC0897B04403F1C1AF80F8146B +:10D68000DD46DD45AE40EB16A6085A0001FFFCE082 +:10D69000FC0649FFFF003C0DFA985A000F10960057 +:10D6A0004413F1C1AE0849FFFF09DD46DD45AE4038 +:10D6B000EB16A6085A0001FFFC86FA302E372B9A8B +:10D6C000F1858422840084A1F187EB14F083F08437 +:10D6D000F086F088F089B67FF581F382F58AEAFA60 +:10D6E00080418083EA40FC86FC212E07ECBE80E46A +:10D6F00080C55A0801098406441000E1DD42EB9A16 +:10D70000B606D55B9E0CE6025000FFF8E904968051 +:10D71000E642E81E9600E602E92F2E07EF8CC00BCA +:10D720008405DD428406441000E2DD423C0C004CDE +:10D73000B606D543F181DD47F1015A0802F38406AC +:10D74000441000E3DD423C0C0062B606D5365A18A0 +:10D750000D268406441000E4DD422E07EFD28E0130 +:10D76000E606E81144F0D570EA8140F03C00DD0F98 +:10D770001A060E24141A3C0C004CB606D51EEB2FCC +:10D78000B606D51BDD4FA600C804EA62B606D5155D +:10D790005A080314EAF4B606D5108E2AE622E808E1 +:10D7A000EB2FB605441000E58406DD42D506DD4FBB +:10D7B000A60049000B76B606B4064412FF8040204E +:10D7C00008093C0FFB6FB641041000084422FF8497 +:10D7D000966FB622A0014412FF88962FAE08EAE4A5 +:10D7E0004412FF89A0014452FF909206962FAE0882 +:10D7F000EAE44412FF8AA001443D0070920C962F87 +:10D80000AE08EAE44412FF8BA0014422C3C4921282 +:10D81000962FAE084402FF98986B38110400EB2B4A +:10D82000D8FCEB30B446441E000088229222964970 +:10D83000EB80EB30441E00208801920296014413D5 +:10D84000F400AC0897F84403F402AFC0FCA19200C6 +:10D85000FC204471522438138602463000FF406099 +:10D860008C0292CC10600009406090091060000AA0 +:10D8700038638A02462000F04073080292F0401399 +:10D880008484FEE6926C1010000B4410FF0040737D +:10D8900004021030000EFEAE40321009FE6E9524D8 +:10D8A00092E8979F40220A1592281070000C106091 +:10D8B000000D1030000F102000101010001110503B +:10D8C0000012FCA0FC02444152103B024C00EBBF92 +:10D8D000380F8000FE45380F8400FE85380F880021 +:10D8E0005600000FFC829200FC41B4A0EA62D047CF +:10D8F000EAF4D0453C0C0062D0423C0C037EE608C2 +:10D90000E83E44F0D70CEA81EA36DD0F1266223495 +:10D9100046285C08EA5BC8358400EA53D5323C0CE3 +:10D9200003788E02E602E82D8402EA53D52A8405A4 +:10D93000EA53D5272E0010B4C8248406EA53D52113 +:10D940003C0C037F5A08030F3C10083BE622E8F624 +:10D95000D5173C0C037F5A0803F23C00083BE60253 +:10D96000E8ED8404EA53D50D3C0C0378E602E8099F +:10D97000D5D4EA5BC0D28407EA53D5038401EA53C5 +:10D9800004028014441203009210EA52EACA3C1CBA +:10D99000037EE62D4EF2010E44F0D7A43817850120 +:10D9A000EA93DD0F1A008800E40022015E019E0167 +:10D9B000A801B201C401FC01CE01020208022E1727 +:10D9C000EFEE5A18010584203E17EFEE8420EA544A +:10D9D000841F3E001091EA3EC8083C0C0104EAD7BF +:10D9E0003C0C0105EAF1D5095A0801083C0C010676 +:10D9F000EAD73C0C0107EAF1EB74EBF797C89648BD +:10DA0000EB52EAFB842AB61F84468007F886380466 +:10DA10008202F081EA64EA99B49FEB07F50184265B +:10DA2000844A8067F88A8400EA48F84C8421EA54E2 +:10DA3000EA3EC8083C0C0104EAD73C0C0105EAF1B7 +:10DA4000D5095A0801083C0C0106EAD73C0C01072D +:10DA5000EAF1EB74EBF797C89648EB52EAFB8423A4 +:10DA6000B61F84428007F85938048202F081EA64C4 +:10DA700044020040B49FEB07F50184228443806791 +:10DA8000F85C8405EA48F81E8422EA543C1C037BB7 +:10DA9000EBF797C89648EB52EAFB8421B61F844205 +:10DAA0008007F83B38048202F081EA644402008077 +:10DAB000B49FEB07F501842284418067F83E84001F +:10DAC000EA48480000778423EA54460000CC50001E +:10DAD00002BCEAFB8426B61F84428401F81E44116E +:10DAE000522438008202F081EA64440200C0B49FEC +:10DAF000EB07F501842284468461F81F8401EA481B +:10DB0000D5588423EA5446000093500000AFEAFB46 +:10DB10008426B61F8442840349FFFED64411522452 +:10DB200038008202F081EA64440200C0B49FEB072F +:10DB3000F50184228446846349FFFE8C8402EA480E +:10DB4000D5388424EA548404EA48D5338425EA5439 +:10DB50008400EA48D52E8426EA542E07EFEE5A08B0 +:10DB600001218400EBB8D51D8427EA548405EA48D6 +:10DB7000D5208428EA540402801644120200EA5296 +:10DB8000EACA4624259F4613DA6050108E4550217C +:10DB900001BAA841A842A883A844A845A846A84716 +:10DBA0008405EA48D5068407EA48D5038406EA488E +:10DBB000FCC192008400EBB984214403F403AE401D +:10DBC000DD9E4403F403A600EAF5DD9E4403F40C55 +:10DBD000A6009600C8074413F3CFA64840000406E9 +:10DBE000DD9E8401DD9E8400EA83EBB9AE08DD9EF4 +:10DBF000FC005A08010F49FFFFDF842A8400EB1F55 +:10DC000044138D463C0BF6953E07ECCFAE08FC80E6 +:10DC100049FFFFEBFC804403F01DA680A641A6C08F +:10DC200040110504581084009688AE809228A68181 +:10DC3000AE41EA224413F421F806502100014C21A0 +:10DC4000FFFE8440AE88442000004430000A83FF79 +:10DC5000502100014C21FFFEA6409648AE40DD9EBB +:10DC6000FC20DD474432DD8CEB244422E1345A08A9 +:10DC7000021484004472D8EC4462E1C04452E55876 +:10DC8000F8123840800838428000384100088C0182 +:10DC90005A0820F8FCA084004472E1144462E8743D +:10DCA0004452D85838438000384180083843000037 +:10DCB00083FF3841000838428000384080088C01DA +:10DCC0005A0820F2FCA0A6403E101130A6413E109A +:10DCD0001131A6423E101132A6433E101133A64523 +:10DCE000A68440210500A647A6C640118500003045 +:10DCF000000900400008EADB3C38089C0030000BBB +:10DD00000040000AEADB3C38089D0030000C3E3041 +:10DD1000113C0030000D3E30113DEB9F969396DC98 +:10DD20003E30113EEB9F964B4231840B3E30113F0B +:10DD3000EB9F3C28089A4231880B3E301140EB9F04 +:10DD40003C18089B42318C0B3E3011410030000FD3 +:10DD500096DF3E3011420030000F92643E30114396 +:10DD60000030001100400010EADB3C3808A200300F +:10DD7000001300400012EADB3C3808A30030001515 +:10DD80000040001496CFEADB3C3808A400300015B0 +:10DD900092623E30114A003000170040001696CFC4 +:10DDA000EADB3C3808A60030001792623E30114E84 +:10DDB0000000001E962F3E00114F42012C0BC006A2 +:10DDC000440FF000FE873C28089A4200AC0BC006C6 +:10DDD000440FF000FE473C18089BFA003E00114239 +:10DDE000DD9EA4C0442200004412D590EA3DB661F5 +:10DDF000A4C2EA3D1430800FA4C4EA3DA8CAA4C658 +:10DE0000EA3DA8C902300008EA3D14308010023013 +:10DE1000000AEA3D143080080230000CEA3D14305C +:10DE200080090230000EEA3D1430801102300010EB +:10DE3000EA3D1430801202300012EA3D14308013A3 +:10DE400002300014EA3D1430801402300016EA3D1E +:10DE50001430801502300018EA3D1430801602306C +:10DE6000001AEA3D143080170200001C40210040D7 +:10DE700014208018DD9EFC00EB303C2C004A441E30 +:10DE80000000882292229649EB80FC80A400441274 +:10DE90000000EACA3C0E0050DD9EFC004423F6ACB4 +:10DEA0004413F6AD5A080106AE108407AE08D50437 +:10DEB0008400AE10AE08840080208040FA6FEA3BF8 +:10DEC000FC80B44084A08C449C2DA2D196005A586A +:10DED000200680A05A0823FADD9E5441803F384036 +:10DEE00094088CA197689266D8F3D5F4FC20B4808E +:10DEF00084608C8484E5B4045A38060566000FFFFC +:10DF0000D504921E4000780842219C2484A096905B +:10DF10005A20200C386088008C414063140C8CA679 +:10DF2000880696905A581EF68C6196D8AA215A38BF +:10DF300007E4FCA0FC20B460840050318024958369 +:10DF4000A31997B0844099568C415472000F97687A +:10DF500096903870940892845A2808F78C0196009D +:10DF60005A0804EFFCA0FC20B460840050318034D7 +:10DF70009583A31997B0844099568C415472000F31 +:10DF8000976896903870940892845A2808F78C0104 +:10DF900096005A0804EFFCA0FC00EA623C0FFB6FFD +:10DFA00084234403F40BAE4084264403F404AE40BF +:10DFB00084014413F407AE084413F408AE08844007 +:10DFC0004413F01EAE884413F420AE08EA415A0808 +:10DFD0000105EA62490006C84402D5904412D8EC13 +:10DFE000F8194402D5904412E558F81A4402D59421 +:10DFF0004412E0E0F8154412E1C04402D590F8164E +:10E0000049000870EB2D490008E54402D5EC4412A4 +:10E01000E11449FFFF584402D5EC4412E87449FF6B +:10E02000FF8B4402D5EC4412D85849FFFF9EFC8078 +:10E03000FC00B480844050420024840080A098D02A +:10E0400096D838308C00958296DF4031980C8C0140 +:10E0500088A35A0808F68C489690AB615A2820EF9E +:10E06000FC80FC04A649B4405A1003045A180D0F52 +:10E07000EB9CA648C9054412E558EA72FC845A187C +:10E0800003254412E0E0EA72FC845A180407F816EB +:10E0900058000003B889FC845030FFF6E662E80BB4 +:10E0A000842084463820FC088C215A1820FD803FAB +:10E0B000EA72FC848E28E622E8088382B8096600AA +:10E0C000000F83FFEA71B889FC84FC00A68180C040 +:10E0D0005A2003145A2006129E14E602E90E50013B +:10E0E0007FF8E602E90E50017FF6E602E90A5A28B7 +:10E0F0000D1EDD475A08020684003E07EC7AD5045F +:10E1000084013E07EC7AEAC1A6712E27EC8F848148 +:10E110002E37ECB14452C24849FFFAE8DD475A00B5 +:10E120000206EA51802649FFFF9EFC80FC00B48075 +:10E13000844050420034840080A098D096D8383073 +:10E140008C00958296DF4031980C8C0188A35A0888 +:10E1500008F68C489690AB615A2820EFFC80FC01B1 +:10E160004412DD8CF08149FFFEC3F001EB24F989F4 +:10E17000FC81FC2480E180C049FFFD742E20114207 +:10E180004442DD8C4402D8382E3011315A7806359D +:10E19000842938120808E662842238100808E92425 +:10E1A000DD475A08022284005A6803122E101131EA +:10E1B0004432E0E0F83C5A0820FFEA78C00D8E2295 +:10E1C0008440881FE24110F07FFFD5064422E558C5 +:10E1D000F83F5A0820FFEA788429381F8008EA515E +:10E1E000803FEA72D54CEA784412E1348443EAA2D3 +:10E1F000EA51EA72D5448420381208085A680305A7 +:10E2000038600808D504842138100808E662E9302F +:10E21000DD475A08022E5A6803192E00113184284E +:10E220005A080203842784004432E0E03821800049 +:10E23000382F80088C0183FF5A0820FAEA78C01032 +:10E24000881F10107FFFD50C84004422E558381138 +:10E250000000381F80088C0183FF5A0820FAEA78F2 +:10E260008422381F8008EA51803FEA72D508EA7894 +:10E270004412E1348445EAA2EA51EA72EA5149FFC4 +:10E28000FF70FCA43C5DFB783C1C0059D10C3C1C8D +:10E29000005AD1093C1C005BD1063C0C005CFE2DF1 +:10E2A000EAF5DD9E8401DD9E8445403008178486B2 +:10E2B00096D8FE2438108E024000800D962FDD9EE9 +:10E2C000EB8A3C3C00575A1802043C3C0059EB6D69 +:10E2D000442201209230EA61401104400440800A47 +:10E2E000462C003F50210FFF54000FFF400048080C +:10E2F000FF16FF071440800AEB6D44320180923014 +:10E30000EA61401184400430800AFE9EFE1714002A +:10E31000800ADD9EFC004462010440630020220369 +:10E32000000049FFFFCFA4303C0BF69FFC80FC416E +:10E3300080C03C0D9F6EF081EB40EB2F80E181228D +:10E340004C5000A2CE04AF9084E1D50F5A68040966 +:10E35000800149FFFFE11074800084E3D506B0011D +:10E3600038600400AE5084E38400EB2438608008F9 +:10E370008C014492D8385A0820FB49FFFF85C066BB +:10E380003C3C00594412042050818050B4083C2C7D +:10E39000037B9210EA52EACAEB748C458C259648AE +:10E3A0009690AE44AE86B408442203609210EA52BE +:10E3B000400100403C2C010484888C459690AE843A +:10E3C0003C2C010684A28C459690AE853C2C010520 +:10E3D00084CB8C459690AE863C2C010786098C45F3 +:10E3E0009690AE87B408442203C09210EA524001CE +:10E3F0000040AE443C2DFB6FAE4544339780AE46A3 +:10E40000AE47840004110008966FE001E838984395 +:10E41000A6489648E634E809E62CE810C1125A18D6 +:10E420000A1339048008D50F5A10140650F0FFE083 +:10E43000E2AFE90938448008D50638648008D5037E +:10E44000387480088C019600D5DE3C5DFB78EA626A +:10E45000D003EAF4D81484083E0003D0840A3E00B6 +:10E4600003D2EA784422DD8C38210000EB245A28BC +:10E4700009058442EAA2D50338708008EA51EB24EA +:10E4800049FFFE56FCC144138D40AE08AE98DD9E98 +:10E49000FC0180C0DD4FB65FF381AF808001EA43AD +:10E4A0008006B43FF20149FFFF44FC81FC60840018 +:10E4B0003E07EC7ADD40842300A0000144738D41C7 +:10E4C000AE410093800049FFFBCD8400804080670F +:10E4D000DD5744638D4000B30000EB6EEA514412F7 +:10E4E000D8EC49FFFD058403DD5780498067EB6E5A +:10E4F000E7628403E8028400AE304412D8ECEA51AB +:10E5000049FFFCF6A630DD578049EA4AEB6EA6309B +:10E51000EBD1DD4010A00001FCE08400EB9CAE08D4 +:10E52000EAC63C1BF6AD4412C620EBD1AE08AE09DC +:10E53000AE0AAE0BDD9EFC60847FAED084DF8460CB +:10E5400084A18246808382034532C614812581439B +:10E5500002B0000097D8E3618220E80A38A98C084D +:10E56000A540E2B2E8098245820784A0D506389921 +:10E570008C08AFD0D50284A0031880008C61E3A67C +:10E580008C024068BC1B4043BC1B5A3804E35A5001 +:10E59000010380908004FCE0FC42FA40812080E18D +:10E5A000801F8420EA4C2E27F1A84432C3CCEAD93C +:10E5B0003801880880834462EA4CC704387309092B +:10E5C000D50484013803090984209C114501534472 +:10E5D00045100BB899419757387214005A70FF0EC6 +:10E5E00038380400385315014231C424EBB1385F88 +:10E5F0009E028865383F9E0A8C215A1808ED8420B7 +:10E6000080618081385F86029788E2858C21403363 +:10E610003C1B4042BC1B5A1804F7E647E902840041 +:10E620003E07F1A810348000FCC2FC002E27F1BE8A +:10E6300084C340111857EABB9690EBE042110C736B +:10E64000EA21EB2A2E07F1BE8C01960040601837B4 +:10E6500096484010041B3E17F1BEFC80FC002E279C +:10E66000F1BD84C340111857EABB9690EBE042110C +:10E670000C73EA21EB2A2E07F1BD8C019600406055 +:10E68000183796484010041B3E17F1BDFC808400EB +:10E690003C0BF6983C0BF689DD4FA600C0049E4368 +:10E6A000E622E81244037320A6003C0BF6894413CB +:10E6B00073224403732144237323A600A648A69023 +:10E6C0003C2BF698D5269E41E622E9035A08052000 +:10E6D000840044537320802044337334A7283C23A0 +:10E6E000F6898CA488443C2BF6890022FFFD880221 +:10E6F0000022FFFE0042FFFF88223C23F69896018D +:10E70000884496493C2BF698DBEAD50384008020A8 +:10E710003C23F69888223C23F68996498802960184 +:10E720003C1BF69888203C0BF6893C1BF696DD9E38 +:10E73000FC00846080A384DF9718E282E8073850E9 +:10E740000D0938608D098C61D5F8FC80FC0084A02F +:10E7500040308C204C118018A500A588E2C4E80345 +:10E76000A500AD08A580A510E2C4E803A500AD1082 +:10E770000A4080010A6100018A86E0A4E8029761EC +:10E780008C02D5E98005FC80FC2084A082604121B8 +:10E7900040098082800597E9E2E3E83C5CF380640D +:10E7A000E90650F3FF385CF78064E8304069942054 +:10E7B00002F3000003108000E3AFE805030300004C +:10E7C000130080000313000002F20000E3AFE8052D +:10E7D000030300001302000003108000EB644108F3 +:10E7E000C001E010E8133D180AEA40080013EB648A +:10E7F0003D080AEBA5B03C680AEC3C780AED3C0801 +:10E800000AEE3C280AEF3D280AF08CA18C228C826B +:10E81000D5C3FCA0FC004440032080C1EAD84210CC +:10E8200010738001802280434430012CEB75AC30A2 +:10E83000FC80401004204430FFFF84404C00800ED8 +:10E84000A500E244E803A4809691A500E283E803D2 +:10E85000A4C096D98C02D5F34400009642018001F1 +:10E860009A109601DD9EFC7BB182818084204490C9 +:10E8700000C880068448EA4C4014B0368560409059 +:10E88000840844732D5085404CA60014B004B05D3C +:10E890004420003249FFFF4EEAC68007EAF63813EB +:10E8A0002901E220E803380329098D4188E9D5EDE3 +:10E8B00044732EE05AB001048561D5E64422C10AB2 +:10E8C00044100190800649FFFE38EA2F38130101F9 +:10E8D000EBC349FFFE632E07EC7FEB723813010197 +:10E8E00038230901E241E8069A8A5CF100C8E8048D +:10E8F000D5028440EA2F9451443001F440108C3703 +:10E90000E623E807C907441000C740108806D5026F +:10E910008423EB722E57F1BFDA072E37F1A98861F5 +:10E920003E37F1A9D5033E17F1A92E37F1A9E663C9 +:10E93000E8035A18030684003E07F1A980023E2727 +:10E94000F1BFFCFBFC2080C180E0AE08840449FFDD +:10E95000FF8C4412C61438109C002E27EFF05A1872 +:10E960000108E642E8098C413E27EFF0D505C204D4 +:10E970008E413E27EFF084203E17EFEF2E17EFF089 +:10E98000C10584213E17EFEFAE30FCA0FC6044606F +:10E990000320FE34448301904463000050B1819011 +:10E9A00050A2019080E18122890088C0EAC68006D9 +:10E9B000EAF60214800081A9E220E802EAFE50C3D0 +:10E9C0000190EAC6800CEAF6021680008D22E22051 +:10E9D000E8031204FFFF5015FE70800650257E707C +:10E9E000F809A47881A7E220E802AC38802B800CDB +:10E9F000804AEAF2EB26021680008CE2E220E8036D +:10EA00001203FFFF5063006450B5806450A500649A +:10EA10004C647FCEFCE0FC002E07EFD32E17F016DF +:10EA2000C0203C0DCBE05A18010592019601D50398 +:10EA3000920296013C2DFBF8E2402E07EFF2E80629 +:10EA4000E61EE80F8C01EB9DD50CC00B5CF10E109F +:10EA5000E906E60FE9048E05EB9DD5038E01EB9DDB +:10EA60005A1801112E07EFF25A081E058405EBC152 +:10EA7000D50CE614E9048406EBC1D5078407EBC185 +:10EA8000D50449FFF4DCEBC1FC803C33F8D95CF1E0 +:10EA90008033E913FC00848084C3E282E80D4030B7 +:10EAA0001020A558A4C88C81FEF490624031945C7B +:10EAB0001A308001D5F3FC80DD9E8400EBFD8400DC +:10EAC000EADFDD9EFC003C03F8D9EAD4E905EACE92 +:10EAD00084003C0BF6ACEB7FEAD4E9038400EAA7A0 +:10EAE000FC8084003E07EFF084003C0BF8D3DD9EF1 +:10EAF0003C03F8D3EAD4E905FC0049FFFFF4FC80AD +:10EB0000DD9E9200FC0149FFFFF52E07EC7F501FB0 +:10EB1000800749FFFF192E07ECA25A00FF292E0794 +:10EB2000EFEB8C013E07EFEB4400004ADD432E176C +:10EB3000ECA2E624E81CEA3E44F0E944EB27EA9321 +:10EB40004A003C0004160416C81284018427EBB85E +:10EB50003C1E037EEB0CEB45D50A5A0801098401E3 +:10EB6000EBB88407EA538400EB0CEB45FC81DD40F5 +:10EB7000A6015A080309DD555A080206FC0049FFA0 +:10EB8000FFC3FC80DD9EFC0080C084003C0BF69639 +:10EB900049FFFD7F2E07EC94406300D6DD473C2300 +:10EBA000965C5A0002088423FE549649E2C1E90BA0 +:10EBB000D50EEBB3E2C20010002BE8093C03F69639 +:10EBC000E220E9058400EAA78400D5028401FC80E4 +:10EBD000B461AE185A2802049208AE19B4018840F4 +:10EBE000B641DD9EFC448140B61F81218400B1C145 +:10EBF0003815000038101C088C015A081AFB440014 +:10EC00001900F844EAF4B43FA680AE880400001E60 +:10EC1000B43F92109C89962FB65FAE09F82B8442C0 +:10EC200044000280F835EA62803F04600014EA99EB +:10EC300092D0EA64406018408386B80E8442F8217E +:10EC4000F823B80BF829F823B41F00130028AE40AE +:10EC5000B41F84429C41B63F3C1C005704608014A2 +:10EC60004412018092D0EA6440609840001300286A +:10EC7000AE41B41F803F8C01B61F83FF0403000E1A +:10EC800092109605F80502030016803F844249FF62 +:10EC9000FFA10403000B803F921054000FFF83FF7D +:10ECA0004E00FFF6440FFFAA10048051EA28EA2222 +:10ECB000000480515A00CC04AE88D5FBDD41C0076A +:10ECC0004412FE51840280418461DD448400381383 +:10ECD0008000381500088C015A081AFB84001004C3 +:10ECE0008051FCC4FC0044030C803C1C02334420D3 +:10ECF00000C8EB2AFC80FC002E07ECA48E01E60283 +:10ED0000E808EA2144030C80EA773C2FFBDBEB2A7E +:10ED10002E07ECA4EB1C5A08011644530C80442F18 +:10ED200074F84430096044430FA08400986AA5A891 +:10ED300038608009500003204C01FFFB8CA2DCF6F8 +:10ED4000FC80FC80FC0049FFFEBF49FFFFCD2E0781 +:10ED5000ECA4C008EACEDD4FA60049FFFFCE840038 +:10ED6000EBA0FC80FC000400001444120060921030 +:10ED7000EA52EACA2E172CC0101000182E172CC108 +:10ED8000101000192E172CBE1010001B2E172CBFB0 +:10ED90001010001AA0454210F008A845A0454210E6 +:10EDA000F408A845A0454210FC08A845A04542101B +:10EDB000F808A845DD41C00544037320F804FC8031 +:10EDC0004403738449FFEDA7FC803C0FFC70DD9E7B +:10EDD0005A000104EBE0D502EA775040832080A17D +:10EDE00084001A028001DCFEFC20445300004463CE +:10EDF0000C80800180650A218001A5C04023885CC9 +:10EE00001A2000014C027FF950528320DEF3840067 +:10EE1000443281784440096084A09883386080013E +:10EE20003861140950528320DCFA8C025A0B20F608 +:10EE3000FCA0FC60848084FF84C1826780A482245B +:10EE40004492C6208166810403000000552200FF21 +:10EE5000E3828140E80E03008000E383E80A3884FF +:10EE60009008A580E2D3E8088266823284C0D50586 +:10EE700038B49008D50284C00B00800102A50000C0 +:10EE80008C81898AE3878C0240783C1B40593C1B6B +:10EE90005A4804DC5A60010380B18005FCE0FC00A4 +:10EEA0002E17ECDC3C6C004AC10B84003E07ECDC06 +:10EEB000441000E684063C6C0061DD42D534C80A8B +:10EEC000DD555A000131DD555A08022E3C6C0059BF +:10EED000D52A5A08030EDD555A0801053C6C004B33 +:10EEE000D522DD555A0802203C6C005AD51C5A0820 +:10EEF000010EDD555A0801053C6C0052D514DD5554 +:10EF00005A0802123C6C005BD50E5A08020DDD5502 +:10EF10005A0801053C6C0053D506DD555A08020419 +:10EF20003C6C005C8006FC80FC002E07ECC1C82A0B +:10EF30003C0DFC025CF00032E9042E07EFDCC00659 +:10EF40002E07EFDB5CF00032E91D8420EBF084003B +:10EF500044326EB8EB3BE202E80698838C01AE5077 +:10EF60009601D5F93C0C022F3C1C0231DD5F4400B8 +:10EF70000033EADFEA77EBB4EA2149FFFD88840138 +:10EF8000EABCFC8040300C204C0180051A200001B6 +:10EF9000D5FCDD9EFC4051FFF9B8F0818400EB22E6 +:10EFA000EA77B0028440EA60EB8F500F8328EA775B +:10EFB0004420FFFFEA60EB8F84C044A0032044920A +:10EFC00081784472EA24800942032873B042502FAA +:10EFD0008328EA60EB75380399098CC1EB225A68E3 +:10EFE00003F4B042502F8328EA60F001EB75EB2266 +:10EFF0003C080AE2EA77F00149FFFB19DD4FA60061 +:10F000008E03E602E8113C03F6AD44600032EAD418 +:10F01000E9089E4150007FCE406018D69B8E97B184 +:10F020003C6BF6ADD504EBB30260000EDD475A0031 +:10F0300002058403FF8497B13C03F7F23C100AE415 +:10F040003C080AE3E220E8033C080AE4E2C03C682A +:10F050000AE53C080A003C680A01E8048402EBFD6A +:10F06000D5162E17EFF1C1048E213E17EFF13C1398 +:10F07000F6A5E220E90A3C03F8D94410EA5FE22051 +:10F08000E9068C01EADFD5038400EADFEB70E602D3 +:10F09000E9078401EA8A84003E07F1A4D5098400C7 +:10F0A000EA8A2E07F1A4C0048E013E07F1A451FFA5 +:10F0B0008648FCC044038D40A6402E07ECD4C10610 +:10F0C0002E17ECD35A1801038C013E072C60DD9EED +:10F0D00044100055DD45AE40EA83A608C8FFDD9E1A +:10F0E0003C1C004A442200C0040080149210EA52E2 +:10F0F00040010040B400920A96373E07ECB204008B +:10F100008014441200009210EA52EACAB4200000AF +:10F110000028922A96773E17EC943E07ECBBDD9EC2 +:10F12000FC008400EBB9DD4B8421AE4084018020DB +:10F13000EB4CDD45DD46AE403C2DFB74A6505A102D +:10F1400001FFDD46AE408409EA56DD4B8421AE4026 +:10F150008400EBA13E07EFDBFC80FC008403EBA006 +:10F16000EA9B84008040DD57EA4AEA908400EABCCA +:10F170003E07EFDB84013E07EFDCEAF7DD4FA60038 +:10F18000EBD0EACEFC80FC20444200002E672D2C00 +:10F19000842044338D4080E49688E246E819A758DD +:10F1A0009881C50400510020D50338500400410265 +:10F1B000040010580184A758C50400210028D50375 +:10F1C0000021000899791022818C8C21D5E6FCA0C1 +:10F1D0004422D590B46244420000EB6DA09192307D +:10F1E000EA61401204400410800A923254108FFFEA +:10F1F000964B121000813C1BF6A4EB6D0421001508 +:10F20000923044320180EA614011844054217FFFF2 +:10F210004432000C402188400230801F103001042D +:10F220000230801F9268103001050230801E1030BD +:10F2300001060230801E926810300107A4D31030FE +:10F240000108A4D3926810300109A4D11030010A3A +:10F25000A4D192681030010BA1128461929854528B +:10F26000003F044080114041903E404290E41040F5 +:10F27000010CA09204108011924896AFFECE40314E +:10F280000CE41030010DDD9EFC2080E080C1DD41EA +:10F29000C00C501301048041846A8402DD44EA49B1 +:10F2A000840249FFA3B4D504840249FFA3B0EAF461 +:10F2B000442201808380B914BB1592304402000CB3 +:10F2C0005431FFFF40300C40EA610003010540115A +:10F2D0000440002301044001010096011200801F38 +:10F2E00000030107002301064001010096011200FE +:10F2F000801E0003010C40201C0950408044B404CF +:10F30000EA7340000824B604B4040023010DEB3C6A +:10F31000400008F5B6040003010900130108EB32B0 +:10F320009601AC1B0003010B0013010AEB3296019E +:10F33000AC190003010CA09A5410003F460C0FFFBB +:10F34000EAB8FE1640000704A81A0003010D541085 +:10F35000003FA01A66003F0040000504A81AC7033A +:10F360008EE197F88403DD578047EA4AEB6EFCA0F4 +:10F37000FC6081218162814380C4DD54A60896002F +:10F380005A0801FEDD58AE088020EB4CDD59A6403E +:10F39000C9FFA6405A1801FF84003E07ECC3DD41B7 +:10F3A000C021DD5B5A0806FFEA6FEAAFDD5FDD4B87 +:10F3B0008421AE400074812ECF05F8083E77ECC35F +:10F3C000D5110073005197FCCF0649FFC02A107475 +:10F3D000809ED5058400EB9649FFBF668401100529 +:10F3E0008000840AEB5D840010030051100300527A +:10F3F00010030053FCE03C1C004A442200000410AF +:10F400008014463C003F9230EA61401104400420E1 +:10F41000800A50318FFF54000FFFFE9E40210244AE +:10F420001420800ADD9EFC4280C2812080E1FA40E7 +:10F430008420801FEA4C987E2E27F1B44432C3D832 +:10F44000EAD996493801880880834462EA14C104E5 +:10F4500038130909D50484013803090984209C1153 +:10F460004501534445100BB8994197573872140021 +:10F470005A70FF0E38380400385315014231C42445 +:10F48000EBB1385F9E028865383F9E0A8C215A187E +:10F4900008ED842080618081385F86029788E2854C +:10F4A0008C2140333C1B4042BC1B5A1804F7E647F2 +:10F4B000E90284003E07F1B410348000FCC2FC6015 +:10F4C000EE38509F8028F082F183844884208009A0 +:10F4D000B1CCEA4C800784208448EA4C8400EB22BB +:10F4E000F003446000C8406300D654D300FF4006D8 +:10F4F00084089600F08485809431F081048F800226 +:10F500008169814C97B1F0034CA0005FB00E501F91 +:10F510008100F20449FFF90E4452817844428AD8AE +:10F5200040E61400888C14BF8005B04E502F810037 +:10F530008066800EF487EB26F086B0675007019056 +:10F54000502F81648066EB26F50602158000E205E7 +:10F5500040503C1A9629E220F407E8031255800037 +:10F5600050E703204CE27FE3B04E502F81008066CD +:10F570008008EB2650E40190F086B067800E502F93 +:10F5800081648066EB26F406F105E20440403C1AF3 +:10F59000A4489621E2208D62E8031245FFFF802DEA +:10F5A0008008EAF63803A909802D800EEAF63813A0 +:10F5B000A901E220E8033803A909F0018D4189007F +:10F5C00040C60000D5A1F00249FFF84ADD473C1DC6 +:10F5D000FC700220800F5A0002058403FE8496917D +:10F5E000806280298007F97838138101100F802705 +:10F5F00038248101500F802749FFFF17EBFCA60834 +:10F60000004F802738038101EB22A6C838539101AF +:10F6100038238D0138048D018802382491018845F2 +:10F62000E040E8069A825CF100C8E805D502844013 +:10F63000103F8027A608443001F4945140108C37C5 +:10F64000E623E807C907441000C740108806D50222 +:10F650008423002F80272E57F1BCDA072E37F1B50F +:10F6600088613E37F1B5D5033E17F1B52E37F1B5B8 +:10F67000E663E8035A18030684003E07F1B58002EA +:10F680003E27F1BCEDC8FCE08401DD9E84004412FD +:10F69000C3D8845FEAA28C015A0808FE84003E07A2 +:10F6A000F1B4DD9E5A0801078401AE088400AC1055 +:10F6B000DD9EEBB30200000F42420001E283E9F558 +:10F6C000A410E61EE8048C01AC10DD9E8400AE0898 +:10F6D000DD9EFC40812184203C1BF7F2109100004C +:10F6E000842480C2814349FFFEEC80E04402C620AE +:10F6F0003810240081205A18010EEB70E602E8034E +:10F700008C01EBFD84013E07F01684003C0BF6AB48 +:10F71000D52E4412C47E84004422C1BE3C33F7F28D +:10F720003C43F6A5F9142E17EFF1C1048E213E17C4 +:10F73000EFF15AA801128460802338048C00C803BA +:10F740008C2196498C615A3804FA5A180406EB7FCA +:10F750008C01EAA7D5038400EAA73C13F8D944003A +:10F76000EA5FE201E9048C213C1BF8D98400EA8AB3 +:10F77000EB70C0048401EA8AAFF0FCC0FC009784FF +:10F780004060982044100640FE0CEAD84000803CBF +:10F7900080228043EA60EB75AC30FC80FC6051FF56 +:10F7A000F9B8B67F8160EA60B002818180E2EA77D1 +:10F7B0008440F481EB8F4420FFFFEA60500F8328E0 +:10F7C000EA77EB8FDD4B8421AE4084C084013C6F2F +:10F7D000FBB74493F04AEA6B44A00055EACE44D309 +:10F7E000F4234C65804584003E07ECE28400EAEF98 +:10F7F00084018020EB4C8409EBC6EA5600068000A9 +:10F800005A000404EBC6D5FB850985C02E07ECE23F +:10F81000E20CE825DD5B5A0806FF3C8FFB843CEFD9 +:10F82000FBB72E07ECE2B43F5A780209F201B0C2EE +:10F83000504F832849FFF8ACD50BB082503F832846 +:10F840005A78010549FFF7E8D50349FFFF992E07CC +:10F85000ECE28C0196003E07ECE2D5D9DD4B842129 +:10F86000AE408CC1EA42EA8897B0D5BCEA9B51FF12 +:10F870008648FCE0FC4384208448B002EA4C8420A3 +:10F880008448B004EA4CEA9B8422DD4FAE408442B7 +:10F8900084018425F80C44638D42EA89EA8FA630FE +:10F8A0005A088F0AEA5F840184258442B0C2B104F9 +:10F8B000F829D5F6B04284448402F85ADD473C1D4D +:10F8C000FC700220800F5A0002058403FE8496918A +:10F8D000B0428062B00449FFFAAEF08149FFFED821 +:10F8E0008402F815EA9BF001FCC3FC0180C0EA9B8E +:10F8F0008421DD4FAE40840184258040B0C1504F4B +:10F90000800649FFFF4D5A680105800649FFFA62EB +:10F91000EA9B020F800249FFF938FC81FC41840018 +:10F92000EA2F49FFFA11DD4FA600C0145A00040463 +:10F9300048000060EA9E3C0BF6A54412C47E840099 +:10F940004422C1BE3C33F7F24440005049FFFEACB4 +:10F95000D5063E07F016EA9E3C0BF6A5EBB48420D4 +:10F9600049FFFB1ADD4FA6004412C44C844149FFF5 +:10F97000C3A1EB3FA60096424E14000F5A08880917 +:10F980008400EA8A3C03F8D98C01EADFD5058401BA +:10F99000EA8A8400EADFEBB4EA77EA2149FFF877E4 +:10F9A000EBA25A000103F8602E07EFE65A000103AC +:10F9B000F85B8400EB23EBFADD4349FFFF5DEA2FA0 +:10F9C000EB3FA60096424E140004960FEA2FDD5737 +:10F9D000EB72EA4A8403EA9084C184003C0BF6ABE4 +:10F9E000EABC3E67F016EAF7EACE3E67F017F83C4D +:10F9F000440000963C0BF6A5EAEE5A0801093C3D8E +:10FA0000FC024400003140300C06D5078460C80574 +:10FA10002E37ECB740300C06EBFCEBB4A648EAA955 +:10FA200049FFFE5944138D42200080004E04001A05 +:10FA30008400EA8AA6089636C00F8400EAA7A608C2 +:10FA400054200020C20E66200020960FAE88EA2FB8 +:10FA50008401EA8AD506EB7FE61EE803FA0EEAA7E0 +:10FA6000EBA25A0001044800006E2E07EFE65A0888 +:10FA7000011D2E77ECAC5A78011944938D41005446 +:10FA80008000EB3AD05F84C03E67F017EA9B8403A6 +:10FA9000DD57EB728069EA903E67ECC13E67EFDBB1 +:10FAA0003E77F017EAF7D54EEB7FE61EE94B4400B0 +:10FAB0000042DD438400EAA7EA9BDD41C007DD5B2D +:10FAC0005A0806FFDD4FA600EBD0840149FFFF0F67 +:10FAD00044238D42A6508062970A4E4400089666E1 +:10FAE000C106440FFFC0AE10D521C82084E0AFD8B6 +:10FAF0002E67EFEAEA4ACE0E8006DD578046EA908E +:10FB00003E67ECC13C6FFC023E77EFDBEAF7EACEE2 +:10FB1000D5198403DD57A698EA903C0DFC02EAD47F +:10FB2000E91184013E07ECD1D50DEA4A8403DD5783 +:10FB3000A698EA908400EABC3E07EFDB8401EB2341 +:10FB4000EAF7EBB30000002EC00B3C13F7F24402BF +:10FB5000FE54AC403C13F69C4402FE56AC40FCC143 +:10FB6000FC00DD475A08022C3C1DFBB9EA78E22074 +:10FB7000E803EA8EC00C84003C0BF69549FFF028A0 +:10FB8000C81E49FFF58649FFFECBD519EA705A0811 +:10FB900001064402C19249FFBAC9840184408080B1 +:10FBA000842A806280A2DD53DD555A08020549FF90 +:10FBB000CF78D5DB2E07EC7C5A0801D8FC80FC20DE +:10FBC000DD4FA6802E17EC942E07ECBB2E37EC826F +:10FBD0002E50114FCA05804082018003D504820552 +:10FBE000804380A1427140243D1C023142201424F4 +:10FBF0008480452333103C0395E6E280E81595A107 +:10FC000040034800A4C0A44088D1A430FE6C423117 +:10FC1000C0249A08FE3C8C81400008169A18960170 +:10FC2000AC309721D5E93C0C02313C1C022FDD5F42 +:10FC3000FCA044531C20442003E844331DB05A0860 +:10FC4000050BA528021291B8FE644010883796492A +:10FC5000AC68D50B5A08010AA468024291B8FE5458 +:10FC6000401090379649AC688CA2DBEADD9EFC60C0 +:10FC700080E0DD4F80C1818281638144009000007B +:10FC80005A780115C1038EC197B044038D41A74036 +:10FC9000D607EAEE5A080105800649FFDD2F8403E6 +:10FCA000DD578046EA4AEA90D50D5A78020C5A98F8 +:10FCB0000405840149FFFFBF8400DD578046EA4AFE +:10FCC000EA90840149FFE987DD54A60896005A08A6 +:10FCD00001FEDD58AE088020EB4CDD59A640C9FF7F +:10FCE000A6405A1801FFDD41C016DD5B5A0806FF29 +:10FCF000EA6FEAAFDD5FDD4FA600C8045A98040939 +:10FD0000D5055A0804064E93000449FFFF5ADD4BFF +:10FD10008421AE405A7801098400107600001075E5 +:10FD20008000EB5DD50A5A780209840010060000B5 +:10FD3000100580008401EB5DFCE0FC202E67ECD018 +:10FD40003C73F68CA60149FFDE578EC1E2E05C638E +:10FD50000001E904EB8EC00284C18006FCA0FC0017 +:10FD6000DD40A6415A1004058424AE41EA43840ACA +:10FD7000441000B5DD42EB8EC803F80AE80349FFE2 +:10FD8000E0DD840A441000B6DD42DD41C024DD5AC6 +:10FD90008E04E60283FFE8172E07EA645A08010A78 +:10FDA0004410003F84088041806149FFE65FD5151B +:10FDB0005A0802144400003F84268040806049FFB6 +:10FDC000E655D50B4420003F84088426806249FF15 +:10FDD000E64DD50349FFE65C441000B7840ADD42D6 +:10FDE0008405DD49EA49EB2C8406DD49840A441088 +:10FDF00000B8DD42DD4B8421AE4084208402804186 +:10FE00008461808180A1DD53FC80FC418120EA4235 +:10FE1000EA8884063C7DFB5FEA5584C1DD40EBE166 +:10FE2000EA43DD4FA600842649FFF1A58400EA5984 +:10FE3000DD5997F83C7FFB5F3E67ECEEAF80DD4B12 +:10FE4000AF802E67EC8F97B05A6801108026DD4096 +:10FE5000DD56800949FFDDB0F08184408402F10164 +:10FE60008066808280A2DD53FCC1FC2080C0DD461C +:10FE7000DD45AE404472FEF22E07EF8BC8198404B4 +:10FE8000441000F3DD42EAEB8401EB7E5A080103E3 +:10FE9000F832A6B89690C205DD4049FF9F34D5EDF3 +:10FEA000840180208062808080A2DD53D5E68401B9 +:10FEB000EA66840ADD492E07EF8BDD49EA305A08ED +:10FEC0000108EAC35A080105EB03C002EA742E27B1 +:10FED000EF8B5A280313EA305A080106EAC35A087E +:10FEE0000103EA748401EA2C49FFDE048400EA6617 +:10FEF0008400EAAC4800006B5A280409DD408421E4 +:10FF0000DD56EB138400EAACD5615A28060D800655 +:10FF100049FFFF7D84013E07EF858400EA66840087 +:10FF2000EAACD5545A280A12A63184C15A080A06E6 +:10FF30008400EBA9EAACD54AEAE5DD4B3E67EA3C32 +:10FF4000AF808400EAACD5425A28092CA63184E05F +:10FF50005A080A0984023E77F0143E77EF8BAE30E0 +:10FF6000D5355A080B14AEB1DD403E77EF8BEA432E +:10FF7000DD408421DD568400EA3F3E77F01449FFDE +:10FF8000BFB484013E07EFC5D5218405DD49EA49A8 +:10FF9000EB2C8406DD493E77EF8B84028420D5115B +:10FFA0005A280B1584203C1FFC01AEB13C2DFB747C +:10FFB0008401EAB73C1BF68C3E17EF8BAE1084022F +:10FFC00080418461808180A1DD53FCA0FC6180C000 +:10FFD000A601B65FF3815A080408A6305A08010545 +:10FFE000840049FFDCD32E07ECE95A08010B4402D8 +:10FFF000C151B43FF2013C3DFB6E3C4DFB6CEBEF5D +:020000021000EC +:10000000EA42EB2EDD41C805EA27EA39EA38D5672E +:10001000852044A2FE5044C2C2A844DD01B044B2CF +:10002000FE56EA245A000122A6315A08041F000590 +:1000300000004472FE50EB175A0010188401EB3890 +:10004000A6388540EB9380278047846610A3800004 +:100050008402DD4484024412C43880418060DD445F +:10006000EA5F3EA7EE40D52C3B0540003B06402012 +:100070004402FE54A6403E17EE44A6013E07EE455C +:10008000EAA584024422C2A88466DD444452FE509C +:100090004412C2A8800538203404380080004C0186 +:1000A000000D50748001E72597F8E80644000089A8 +:1000B000DD438127D5B781278CA14C55FFEDEA2779 +:1000C000FA12AE08804184028461DD442E07EE40BE +:1000D0005A08130F44000085DD43D50AA6085A00CC +:1000E0002204AED0D5FCEABAA6005A0013F5DD57BB +:1000F0004422C105B47FF401EBA849FFA61D960078 +:10010000EACC49FF9E3ADD5A5A00010984E13C7F5E +:10011000FB95DD41C8033C7FFBABA6315A080812B2 +:10012000A6305A08024EEA475A00063D5A00090610 +:10013000EA475A08113DD514DD475A0802FBD5326B +:10014000541000FD5A180910A6705A18020D8401A7 +:10015000EA6BEA479E46E622E9255A081129DD4165 +:10016000C021D5255A080A07A6308E02E602E828E3 +:10017000D5195A08030CA7B05A680123800649FF15 +:10018000E72A8006EA6B8408D51C5A08040EA7B03B +:100190005A680117800649FFE71E8006EA6BEB509C +:1001A000EBDA8408D50E5A0006E8D50A844084614B +:1001B0008402FA25808380A2DD538408D50284015D +:1001C000FCE1FC0084003C0FFBB4DD46DD45AE40A5 +:1001D0003C2DFBB4CA08840180208062808080A20C +:1001E000DD53D5F7FC80FC00DD548400AE08DD58FB +:1001F000AE088401EA2E8408EA6E2E07EF83EA7BBC +:10020000DD46DD45AE40EA83A6085A0001FFDD4128 +:10021000C00AEA27A6085A0832FF8406EA56840173 +:10022000DD49D50C49FF99AEEA27EB09AE088041BC +:1002300084028461DD448402DD49FC80FC6180C06D +:1002400081618406A67180E28520DD42854944C330 +:10025000F04A44800055A6313E97EFC58E03E6096B +:100260004EF2030644F10070EAD040F03C00DD0F8E +:1002700012005801FC056A02FC057403D203B204A3 +:100280001805DD412E072C32C809DD46DD45AE409C +:10029000840944100091DD42D5285A08013C04939A +:1002A0008003F845E320E9F2D535DD59A600C823DF +:1002B000DD4BA6005A080120DD555A08021AEA70E3 +:1002C0005A0801064402C19249FFB7302E072BC7D6 +:1002D0003C1DFBB99401E220E80884408401842A93 +:1002E0008062808080A2DD53DD41C005D5DFDD5511 +:1002F0005A0001E7DD41C80ADD59A600C807EBFF37 +:100300005A000105EB835A0001DC84094410009275 +:10031000DD422E072C325A000103EA20DD41C021C4 +:10032000EB3FA600C0038400EA3FA1FB49FFDB6D61 +:10033000E2E0E805EA305A080107D51949000E3312 +:10034000C8FAD515EB3D5A000113EAB0C805DD5ACD +:100350008E04E602E90C2E07ECD05A000109EA20CF +:100360002E17EF8B5A100403EA20EAACDD46DD4578 +:10037000AE40DD54A608C0FFDD41C808DD4FA60031 +:100380005A08030949FFF6EBD50549FF9209C0FE5B +:10039000D5F68404AE3184003E07EF8CDD40EA439D +:1003A00049FFDCDBDD41C0088406441000D5DD4296 +:1003B0008404EA23D5038401EA66840EDD498402BD +:1003C0003E07ECA0EB13EA20840B441000BADD4298 +:1003D000DD41C81F840B441000BBDD428006EB20CA +:1003E000F95D8405DD49EB3D5A000105EA305A0804 +:1003F00001098408441000D2DD4284013E07EC98D4 +:100400008404441000F1DD42EAEB8006EB4AEA2066 +:10041000840B441000BCDD42EA24C83D8401DD4960 +:10042000DD5A9E44E624E9135A000C12EA245A00CD +:10043000040FEA305A000105EB3D5A080105EBEBC9 +:100440005A0801048006EB848400EB38EB502E57E9 +:10045000EC81D805EA32EBAEEBAAF908EA42EA8869 +:10046000DD5A8E04E602E809EA4BEA33EA468400E4 +:10047000EA3C8400EA59EA85EA245A00041344104D +:1004800000D28406DD428404EA23DD408421DD5667 +:10049000EB13D5075A0804068401EA7C8400EB3884 +:1004A0008400EAB7EB208006F8F9EAC35A08010392 +:1004B000EA208401EA2CEAAA5A080103F804EA2493 +:1004C0005A080404480001ACDD555A000203F80440 +:1004D000EB8E4E0301A5480001AA2ED7ECEE5AD8A8 +:1004E000011349FFDB598402EAB7DD4BEB78840541 +:1004F0003E97ECF6DD49DD414E02FEAFDD5B5A086A +:1005000006FFEA205AD00203EA208400EA37DD41E0 +:10051000C028EA788C023C1DFBB98C22E220E80559 +:100520003C1DFB9B5A1801F9EA32EBAEEBAADD4009 +:100530004412E0CC49FFDD81EAAAC805DD40A601EE +:10054000EAC2F9788406DD49DD45DD46AE4080C06B +:1005500049FF9119C0FEEA45AE30DD55C0FFD522F6 +:1005600049FFC46CEB3E5A0803053CDFFB5FD50333 +:100570008401EA37DD46DD45AE404493F7F1EA8E6B +:1005800080605A0801FE0074800097FCCFF9441285 +:10059000C1E480418402DD448006EB4A3E77EF856A +:1005A000EA202E67ECD084003E07EF855A680108E8 +:1005B000DD408420DD563E67ECEEEA200005800039 +:1005C0004E030130EAAA4E03012DDD555A00010405 +:1005D00048000128441000D48406DD428404EA2344 +:1005E000EB13EA20EA475A0806108400EA7CEAB7CF +:1005F000EBAEEA32EBAADD47C00CEA910200001034 +:1006000049FF985BD5065A081110DD41C0EFD50CA3 +:100610008403DD43EAE5DD588401EA2CEA7DAE0877 +:10062000840FDD49EA20EA475A000903EA20DD4742 +:100630005A000203EA20DD408420DD568403AE31F7 +:10064000EA208401DD49DD41C8098006EB20F82657 +:100650008405DD498006EB4AEA20EA24C8178402B3 +:10066000DD4949FFBC2F8006EB8449FFDC0FDD4BE1 +:100670008421AE40EA245A00040E8409EA2384034C +:10068000DD49DD41C007F839D5055A080404840165 +:10069000EA7C8404DD498006EB2049FFDD6BEAC378 +:1006A0005A080103EA20EAAA85213E97ECF65A008F +:1006B0000105EA245A08040A840AEA23EAE5DD5817 +:1006C0008401EA7DAE08EA20A631EAC2F8B33CA371 +:1006D000F68CA63149FFD990E340E912840BEA2356 +:1006E0008400842BA83BAE71EA59DD4B3E97ECEEBB +:1006F000EB78DD414E0200BC49FFBBE7EA208409EC +:10070000EA238405DD49EA49EB2C8406DD49DD4115 +:100710008020C8F3840280418461808180A1DD5300 +:10072000EA20DD41C802EA7DA6305A08021EEBE24B +:10073000DD54A608C0FFA631EAC2F08185A04402BC +:10074000C154F1014422C1A849FFDADD3CDBF68C3B +:1007500010A30001DD40EA43840010D3801CA83BB5 +:100760003ED7ECEEF853EA475A08070C8409AE313D +:10077000EAE5DD588401EA7DAE08FA083C0FFB7B10 +:1007800084001003801CEA202E07ECEE5A080119A1 +:10079000DD40EA4349FFBBA6DD408429AE41842009 +:1007A000DD56DD40842BAE4149FFFD1F8402DD583C +:1007B000EAB78400AE08EA2C8403DD49D5585A080C +:1007C00002578404DD493E97ECEEDD41C8088006FF +:1007D000EB4A2E07EFC54E03FD40D54900058000CA +:1007E000C803EAAAC0042E07EA3CC8128409EA2317 +:1007F00010A30001DD40EA43DD408421DD56840082 +:100800001093801CA83B49FFBB7048FFFD26840A5B +:10081000EA23EAE5DD4B8421AE40D5298402DD4997 +:100820008403EA2349FFD966D5228403DD49A63132 +:10083000EAC249FFD86FDD4049FFFA81C00E840447 +:10084000DD4984013E07EF858406EA23800649FFDF +:10085000FADE8405DD49D50B441000D38406DD4261 +:100860008404EA23DD408421DD56EB13FCE1920091 +:10087000FC40C002F92944600065EA89EA8FDD473F +:10088000C00E8EC1C60C84218041806184804400EA +:100890004F00EAABEB7CEA2AEA5FD5F28400EBBDBD +:1008A000FCC044100055DD45AE40EA83A6085A005E +:1008B00001FFDD9EFC4080E08122EA5D80C049FFAF +:1008C000FFF29E79E62F4EF2018144F106D83817E7 +:1008D0008501EA934A003C001E00720020012802B4 +:1008E0009200F002F002F002F0024A027E02D2020E +:1008F000F002F002F4028404FA21DD4244000030E8 +:10090000DD43840EEA558405EA4F8400EAA1EA96A5 +:10091000EA75DD475A080204AFF0D5FCDD47C00B8D +:10092000842144005AF0804180618081EAABEB7CF5 +:1009300049FFFFA080098421DD5684208402804184 +:100940008461808180A1DD53F8DA8404FA22DD42DB +:10095000840EEA558406EA4F8400EAA180A650037B +:100960000041843FEB2BD8FFD5E6FA258404DD4215 +:1009700044000031DD4384E04403F429AFC0F85D56 +:1009800084013E77EC7AEA4F10730050EAC10014FC +:1009900080012E27EC8F84812E37ECB14452C2485F +:1009A00049FFE6A4DD4FA600C806EA514412E55807 +:1009B000EA72D5075A080306EA514412E0E0EA72E7 +:1009C0008400EBED2E17F0178400EA3F84013E0708 +:1009D000EC905A100103EBA08400EA6BDD54840212 +:1009E000AE08DD58AE08EA868E08E6044EF200F046 +:1009F000800949FFB377F883FA238404DD42EB09C9 +:100A0000DD43DD588402AE08EA4FEA869E43E624C1 +:100A1000E90A5A000D095A080E0A49FFB40D84006C +:100A200049FFB3F28408EA55D5038409EA5584E006 +:100A3000107300503E77ECAD49FFED3ADD40EA43DC +:100A400084043E77ED06EA75DD49EA96DD475A08EB +:100A50000205EAEBAFF0D5FB4413F3D1A608EA9CFC +:100A6000AE08441FFFC34403F429AE40DD47C0086D +:100A7000842144005AF0804180618081EAAB840087 +:100A8000EBED2E17F0178400EA3F84013E07EC904F +:100A90005A100103EBA08400EA6B840049FFE27D59 +:100AA00084208009DD568405DD4944000033DD43A0 +:100AB000EA475A0004045A080706440001F4EA2AE7 +:100AC000D5054400004B49FFCF2FDD47C006EA9112 +:100AD0000200001049FF95F144000034DD43DD4180 +:100AE0008020848F8402C10784408020806280A29D +:100AF000DD53F8058041806180A1DD534800006826 +:100B00008404FA24DD428420DD40DD56840AEA555F +:100B10008403EA4F8400EAA1DD40EA438401EB6AE2 +:100B2000D5568404FA2ADD42840EEA558406EA4F3B +:100B300080A650030041843FEB2BD8FF800984211D +:100B4000DD56842084008461EAA180418402808390 +:100B500080A1DD53D53CFA2B8404DD42DD47DD570F +:100B60005A08020DA6095A00031380018420DD569D +:100B700049FFD7C08401EA2CD50AA6095A000A0801 +:100B800080018420DD56EAE58401EA2C000300514F +:100B9000001300524422C1224432C0EE4442C13507 +:100BA00049FFF8678400EAA1D5128404FA2CDD42DB +:100BB000000300515A0001055A08020584003E074F +:100BC000ECD08400EAA1D503841BEAA1FCC03C0F51 +:100BD000FC71DD9EFC6004EF800DC80AB461A04981 +:100BE0009419944940108FF5EA58EA4ED54695215C +:100BF000981C9E628C82A40088238864A5C8A5984E +:100C00009603814597FB97B34E070006EAECF8126E +:100C1000FD60D503858081AC4E7700078007EAEC44 +:100C2000F809FD40D503850081284E67000880063D +:100C3000EAEC4900107EFD30D50384C080E6400513 +:100C40000408EAECFD50FD13FD04EA68FD10FD0503 +:100C5000EA2BFD50FD13FD04EA2DFD16EA68FD1692 +:100C6000EA68FD10FD05490014D349001637021F3C +:100C7000801892014000042012070000FCE0FC43B1 +:100C80003C43F0A2124F800A124F800B0040000933 +:100C9000C4085A401F0700400008C4035A483111D5 +:100CA00000410042C407B4825A48050B0041004687 +:100CB000CC07444007D0124F800A124F800B3C4CA7 +:100CC00001F74E4600ABCC083C4C01F64450C34FF4 +:100CD000E2A44EF300A33C4C01F94E46009FCC0821 +:100CE0003C4C01F84450C34FE2A44EF30097A500DA +:100CF0004E420094A5014E4200912E57EFEE4E5306 +:100D0000008D026F800A3C4DFB79E2C44EF20086F2 +:100D1000026F800B3C4DFB85E2C44EF2007F848164 +:100D2000AF182E60107D3C4003EACE06C407503257 +:100D30007FE1E2C3D50481E5D50281E4812044014D +:100D40005188385011014401514838001101B61F33 +:100D50009C14F081EB7CF08280C2800F80E15024F3 +:100D60008028501480103C3C01F2F8212E10107D98 +:100D70003C4003EB8400C907C40550027FCFEBB7AA +:100D8000D5028004441150E4385091014411508040 +:100D900038109101B63F9C76F18144100066F182D3 +:100DA000502480303C3C01F35014801849FFFF145C +:100DB0000433800B0423800A4E360006CB2A5CF1F4 +:100DC00005DDE9270493800D04A3800C4E960007EF +:100DD0004E9300205CF505DDE91C3C0C037E8E0281 +:100DE000E605E817A03DA13C9441401093F59421FD +:100DF000EA4EA07FA0BE94491203000C40108BF570 +:100E000094118069804AEA4E1203000D8401D502D4 +:100E100084001003007AD5038400AE18FCC33C0F95 +:100E2000FC77DD9E4402B64C3C0FFC76DD9E3C0F09 +:100E3000FECEDD9E3C0FFECDDD9E4402B5E43C0FB0 +:100E4000FECC500000343C0FFECBDD9EFC2051FF59 +:100E5000FD1880C0121F800380E24411534CEBB098 +:100E6000B002DD4A44115404EBB0B030DD4A441105 +:100E700054BCEBB0500F8178DD4A500F82304411E2 +:100E80005574EBB0DD4A5A6002095A60030A5A6889 +:100E9000010BB0F084C0D509503F8178D505503F93 +:100EA0008230D502B0C284C1C722FA5D4450005AD4 +:100EB000848084E2EA63381189119603E001E80333 +:100EC000C607D50BEA639603E020E816C6069855D8 +:100ED000EB928082960BD5059862EB9280A2960BDE +:100EE000E005E80BE080E8098040D5E5EA63960379 +:100EF00038018111D502800251FF82E8FCA03C1C20 +:100F0000037E5A1802160010003C5A180112842061 +:100F1000EB71021000181210001A021000191210C2 +:100F2000001B0210000EEB800210000FD5252210CE +:100F3000001AFA8322200018EBB6FA642210001B74 +:100F400040210C561220001A22200019EBB6221064 +:100F5000001040210C561220001B2220000EEBB680 +:100F60002210000F40210C561220001022200011E8 +:100F700042111073EB6F121000110010007AC908B3 +:100F80000210001AEB800210001B12100011DD9EEF +:100F9000FC010220001A021000100230001B8A22FD +:100FA00002200011224000088A43964B96935EF27D +:100FB000003C90219041E8094E14001A0030004591 +:100FC000CB168465FEE4D50D5EF20C44E9104E1795 +:100FD000000F00300045CB0B52520C7F8465FEECB5 +:100FE00044500078EBB18C6196DBD5060030007878 +:100FF000E674E9048469EB6FD5028420223000098D +:10100000121F80005EF1803CE8084E24001DEB6B4F +:10101000C91A8425FE5CD50C5EF193C4E9144E27F1 +:101020000013EB6BC910525193FF8425FE6C4450A2 +:101030000078401094368C21964B40210456122F94 +:101040008001D50900100078E6348429E8F784206F +:10105000121F8001EBF45CF08708E8068420121F61 +:101060008000121F800104100011EAE8EAB6FF4E6A +:1010700044110000D11F3C1C04253C67FD26E626D8 +:101080003C57FD25E906126F8000125F8001D512E2 +:10109000EAAE8447964B421308739023964B121F77 +:1010A0008000EBD8964B421288739023964B121F08 +:1010B0008001EAAE964B404204219723124F8002F2 +:1010C000EBD8964B4031842196DB123F8003021F00 +:1010D00080021210000A021F80031210000BEAFFA8 +:1010E0003C0BFD26EADC3C0BFD25FC81FC41F48138 +:1010F000411200114102400A0040005A2260800063 +:101100009724221080018641C4073C6BF9643C1B84 +:10111000F963EAFDD518B4805A48031A3C7DFCAF48 +:101120003C4DFCB088272E77F2C488C48CE197F838 +:10113000E6EFEAFDEB9B3E77F2C4E94640631CD63E +:10114000EAFDEB92EB9B3F27F2C4D53E5A48013BA8 +:101150003C7DFECC3D37F964A7383D27F9635A48FA +:1011600001654049980142F200030293800440491E +:10117000040142420003888F40948408E324E85528 +:101180000293800340748408E1E7E803E0C7E86164 +:101190003CADFECD024500098E818A899521E09300 +:1011A000E803E086E856E1C7E803E027E852027565 +:1011B000000A8EE18AE995F9E0F2E837E0E1E849D2 +:1011C000D534EAFDEB9B5A58012AB4005A0801278E +:1011D0003C1DFECCA40DE260E8213C0DFCB03C4D72 +:1011E000FCAF4030440142F18003A54E4032400143 +:1011F000EB37886F9569E065E811A4CF9F594202EB +:10120000C4734242C073401184098801882440009D +:101210000C16EB6F3C0FFCB0EB9B3C0DFCB0AC1024 +:101220003C0DFCAFAC11FCC13C7DFCAF3C4DFCB0B7 +:1012300088272E77F2C488C48CE197F840631CD6C7 +:101240003E77F2C440709CF6EAFD3C7FFCAFD5BC13 +:101250003D3FFCB03D2FFCAFD5B7FC200460001132 +:10126000EAE8EAB6FF76446100002270800022407E +:1012700080013C3DFCAD3C1DFCAED604B4005A08D8 +:10128000010A84003C7FFCAE3C4FFCAD3C0FFCAC43 +:10129000D53B978B975B41139801410214013C1D8C +:1012A000FECB420880034238000388600200800EB3 +:1012B0003C3FFCACE060E8240010801E80E09F0909 +:1012C00042720C73FE0C80674213C4244040040A2F +:1012D0004F1500048824D5028A24401080368826C1 +:1012E0003C1FFCAE4211C0244F0500048824D502E7 +:1012F0008A244000801688053C0FFCADD5053C7F54 +:10130000FCAE3C4FFCAD3C0DFCAEAC103C0DFCAD5E +:10131000AC11FCA0FC2022708000226080012E1005 +:10132000107D3D37F9563D07F9543C5DFECCC10FA9 +:101330003C3DFB85848A403190770442800996D9F0 +:1013400040420C960432800AFF1CD5030042801EE6 +:10135000B4005A08010A84003C7FFCAB3C6FFCAA35 +:101360003C0FFCA9D54D4123CC0141134001021291 +:10137000800E420900034238800388609449E0618E +:101380003C3FFCA9E8392E00039CC00C2E00039DB5 +:101390005A001F092E00039EC0052E00039F5A0805 +:1013A000310AFA03808142418073FA048064FE0CA2 +:1013B000D5089E2180A142500C7342009024806584 +:1013C0004211C8244040040A4F2500048824D50255 +:1013D0008A244010803688333C1FFCAB4231C42441 +:1013E0004F1500048864D5028A6440018016881075 +:1013F0003C0FFCAAD5053C7FFCAB3C6FFCAA3C0D26 +:10140000FCABAC103C0DFCAAAC11FCA0FC203C6D6C +:10141000FECC223080002270800100130010C9022F +:1014200084212E40107DC40F3C4DFB8584AA404290 +:101430001497045300099721404290970453000ADF +:10144000FF64D5115041FFC497215CF20C08025390 +:101450000009E8075043FFC497215CF21388E902B2 +:101460008CA59569B4803C5FFCA25A4801138400A6 +:101470003E07F2783E07F276020300093C3BF94250 +:1014800094013C7BF9413E47F2863C0FFCA2D553C8 +:101490003D07F9413D27F94240581C0140090C0124 +:1014A000FF6C425000733C0DFCA24512C6E0E2A066 +:1014B0002E57F2868400E9028401380894089E09B8 +:1014C000D80884003E07F28684013E07F276D504F0 +:1014D0008CA13E57F2862E47F276CC0C2E57F28620 +:1014E0008004E205E82F38688000CE028C818C01F0 +:1014F000D5F984A08005E201E80738F88000E90208 +:101500008CA18C01D5F95A480109E0A1E806020333 +:10151000000A94013C0FFCA29B0DFEE44232C8730A +:1015200042021C24EB4E3C3BF9424202C073EB15D5 +:101530003C0BF9413C03F942AC103C03F941AC11BE +:10154000FCA09B8D8AA488C4FEEC423348734202FF +:101550009C24EB4E3C3BF94242034073D5E9FC002E +:1015600022408000223080012E10107D3C5DFECC98 +:10157000C10500628022FA24D50500128020006295 +:101580008022B4005A0801073C4BF93A3C3BF93938 +:10159000D52C3C07F9393C57F93A8A038AA4FE0452 +:1015A000420294732E57F2719449E2015A58010D88 +:1015B000E91E84003E07F2713C4BF93A3C3BF93995 +:1015C0003E07F270D514E8082E07F270E206E80430 +:1015D0008C013E07F2702E07F2703C4BF93AE2069E +:1015E0003C3BF939E90484013E07F2713C03F93AC6 +:1015F000AC103C03F939AC11FC80FC403C9DFECBA7 +:101600002240800000548016223000082270000919 +:10161000221080018621C506E6A98628E80341122A +:101620008013005480178601C506E6A98608E803E2 +:1016300041028013B5405AA0010A04000011EAE8F3 +:10164000EAB6FF4644010000D81784003C0FFC9B1B +:101650003C0FFC9A84013D1FFC993D1FFC983C3BCC +:10166000F9203C7BF9213C4BF9103C1BF9113C0F54 +:10167000FC87480000AD5AA80304480000A73C0DB1 +:10168000FC8751287FFF8C01420040013C0FFC8702 +:101690003C0DFC9AE012E8038C01D50284003C0F5B +:1016A000FC9A3C0DFC9B3C5DFC9AC8064C594005DD +:1016B00084013C0FFC9B4462C6A8942A413300007D +:1016C000127980014532C6883849960988133C4D05 +:1016D000FC9938331609AC413C4FFC984E57000931 +:1016E0009E6938030611406304409AC3D506380347 +:1016F0004A11406348409AC322130001420180030B +:101700008A27EBE50264800D8801E2C08026E906A5 +:101710000214800CE20140103C1A3C0DFC9BC804F2 +:101720003D1FFC99D5105AA0040F0204800C4038CC +:1017300044018A20FE5C9A30400080174008000176 +:101740003C0FFC99EBE8842380644230807384244E +:1017500080038C02EB15E080E9043C0FFC99D50472 +:101760008C813C4FFC99EBE8E011E8043D1FFC99AB +:10177000D505E180E8033D0FFC993C0DFC873C1D3D +:10178000FC99E001E8033C0FFC998420EBE880C160 +:1017900080814C100010383996118883403994406C +:1017A0002231800188C3C5038EA1D50280B28C216D +:1017B000D5F1846240008C168880880640420496E9 +:1017C000EB479723964BD50384208081AD10AC5115 +:1017D000FCC0FC6B80C0EAE804000011EAB6FF46DA +:1017E00044010000D804841F3C0FFA9B3C1DFECB33 +:1017F0003C0DFA9BA44DE201E8048C013C0FFA9BDE +:10180000B4064E02014D5A080504480001492E0055 +:101810000324C00C2E000326C0092E0003255A0005 +:101820001F062E0003275A08310A00030045C80688 +:101830000003005A96044E020139021300180203F5 +:10184000000E449000648A019603EB5E02130019B7 +:101850000203000F85418A019603EBA7EAFF960376 +:101860009001EB5EEADC96039001EBA7EAAE960BE3 +:10187000EAAE023F8001964B022F8001FE444211E6 +:1018800088738403964B8441F82E80E04200242420 +:101890004410005AEB4797F9FFFC964B84418400B3 +:1018A000F82252139FA410030078964B84418403BE +:1018B000F81AEAAE42B02800964BEBE54210A42499 +:1018C000804A4010AC368402964BF80D023F8001EE +:1018D00080E096DBEB374231A42484024011AC3621 +:1018E000804A964B49FFFAB4EAAE964B4E16000575 +:1018F000FE7A974BD50280A7EBD812530012964B75 +:101900004E160004FE0296034441562C8044B0C299 +:101910003B01480480233B00C824120300130291BA +:1019200000004421563C129080008262B0463B0980 +:10193000C80480E13B03C8240339800013338000CE +:10194000B1CA3B02480480873B024824129200003F +:10195000509F80383B01480480493B0148241331A3 +:101960000000513F80484421564C3B01480480937D +:101970003B024824A490ACA0002300785CF100282E +:10198000E9595CF10032E80444400064D503444066 +:10199000006A4302800342A0000340282801969376 +:1019A00042210003969386213929C511E1C2E80539 +:1019B0008DA141188013D5F9864D43194401512852 +:1019C000FFFFE15041290013E9038209D50380E1BB +:1019D00082033899C911381849118A4996D1382992 +:1019E000C51141312401382845113903C9118A41F3 +:1019F000FE9C969340214C5688413813C51196930E +:101A00008A30FECCFEA4965B4030CC76887096DBA4 +:101A1000FF1C4470006440211C5640421C96421238 +:101A20008824FE24EB9240001C16121300121203AD +:101A30000013EAFF96035EF00051E903EA9EEB5EB5 +:101A4000EAFF96035EF07FB0E804440FFFB0EB5E60 +:101A5000EADC96035EF00051E903EA9EEBA7EADCBC +:101A600096035EF07FB0E804440FFFB0EBA70203DB +:101A70000012B041EAC4020300138041EA57800615 +:101A800049FFFDBDB0418006804149FFFBE8020FE0 +:101A9000800212030014EA6312030015B4065A0808 +:101AA000050584003C0FFA9BFCEBFC403D2DFECC71 +:101AB000223080000069001622108001C605E6C9A8 +:101AC000E80597B1D50484C1D50284C80049001740 +:101AD000C405E689E8059721D5048481D502848868 +:101AE000B5E084A05B3801123C5FFC863C5FFC855E +:101AF0003C6FFC843C6FFC833C3BF8F63C1BF8F7E6 +:101B00003D3FFC7A480000AC5B380304480000A667 +:101B10003C0DFC7A51027FFF8C01420010013C0F0A +:101B2000FC7A3C0DFC85E010E8058C013C0FFC853F +:101B3000D5033C5FFC853C0DFC863C5DFC85C806FE +:101B40004C58400584013C0FFC864472C654400347 +:101B500094403D1DFC8438339609AC413D1FFC8305 +:101B60004E57000C5092FFFF3803A6114093A4403B +:101B70009AC322048001D5083803C2119AC34003D6 +:101B8000C040220000019A41EB37EBE5882302397F +:101B9000000D94D9E2618003E9070209000C940169 +:101BA000E2204000BC1A3C1DFC86C9043C6FFC844A +:101BB000D5105B30040F0219000C412084088A12F2 +:101BC0009A66FE0C8A7240000C179A203C0FFC8427 +:101BD0003C0DFC8484238071423080738424800314 +:101BE0008C02EB15E1A0E9043C0FFC84D5048DA127 +:101BF0003D1FFC843C0DFC84E006E8043C6FFC8443 +:101C0000D505E080E8033C4FFC843C0DFC7A3C1D8C +:101C1000FC84E001E8033C0FFC8484203C0DFC8440 +:101C200080C180814C100010383396118883403376 +:101C300094402231800188C3C5038EA1D50280B0B3 +:101C40008C21D5F1846240008C1698E08806EB4E1A +:101C5000EB4796DB964BD50380258065ACD0AC5125 +:101C6000FCC0FC40B48022308000227080013C1D0A +:101C7000FECC5A480113ACD0ADD1A60D3C3BF8F2D6 +:101C80003C7BF8F35A000104480000CD84003C0B73 +:101C9000F8F03C0BF8F1FCC0A78D0100005A5A681F +:101CA000013554080002C0313C47F8F03C07F8F118 +:101CB000CC05C02B3C37F8F2D5283C17F8F3C80305 +:101CC00080E1D523FF62FF0C3C17F8F282434240CB +:101CD00004754232942442100024433014244110ED +:101CE0008C004231C82442399C7542301075FE0286 +:101CF000FE2CFE7C42104873421290754031C4762F +:101D00004010C43696DB97CB54080002C06E5EF1DB +:101D10008C80E9093C57F8F25EF28C80E80F445061 +:101D20000C7FD50C4E3400083C57F8F24E55000796 +:101D300084A0D50480A38400D50284015EF39400BE +:101D4000E9073C47F8F35EF21400E962D50C4E74E3 +:101D500000083C07F8F3848042401001D5045A087B +:101D6000014580873D17F8F23D07F8F340F1C401C3 +:101D7000802380074123C001E80B84024092C40104 +:101D8000400780164204C87340003C1688104F225A +:101D9000000C842240924001401904364214BC7366 +:101DA0004010C83688314C48003A5EF08C80E90417 +:101DB0005100F381D5054E140032530080004C5879 +:101DC000800E5EF01400E90451106C01D5054E043C +:101DD000002353100000E1B0E80496EB97C3D5054B +:101DE000E191E80396CB97E35A68010C3C03F8F2C3 +:101DF0009A183C0BF8F03C03F8F39A383C0BF8F1D6 +:101E00003C3BF8F23C7BF8F3ACD0ADD1FCC0444095 +:101E100013FFD5A94F02FFEAD5E186004C58FFD346 +:101E2000D5E4FCC0FC2180C0EAE804000011EAB659 +:101E3000FF4644010000D80984003C0BFD283C0B00 +:101E4000FD29841F3C0FFA9A3C7DFECC3C0DFA9A8A +:101E5000A47DE201E8048C013C0FFA9AB406C05D4F +:101E60005A00055C0203000AEAC40203000BEA57A9 +:101E7000B041800680413C3DFA9A3C4DFE94A779E2 +:101E800049FFF936A63AC006B0418006804149FFB5 +:101E9000FABFA63BC006B0418006804149FFFE075D +:101EA000A63CC006B0418006804149FFFA35B041EA +:101EB0008006804149FFFB550003005A960EC0077B +:101EC0000203000AEAC40203000BEA57B04180068D +:101ED000804149FFFEC8220F80024E0400048400A6 +:101EE000EAC422FF80025EF78C80E90444000C7F84 +:101EF000EAC4220F80034E0400048400EA5722FF44 +:101F000080035EF79400E904440013FFEA57020FD0 +:101F10008002AC36EA63AC37B4065A08050BA43627 +:101F20003C0BFD28A4373C0BFD2984003C0FFA9A9A +:101F3000FCA13C0FFF09DD9E3C0FFF08DD9E440223 +:101F4000D03884213C0FFEDD84003E07FB783E073D +:101F5000FB793E07FB7A3E07FB7B3E07FB7CEB43AE +:101F60003E07FB7E3E07FB413E07FB403E07FB4230 +:101F70003C1FFA9D3E07EE334412CFE88400845F95 +:101F8000EAA28C015A084FFEDD9EFC00EA5DFC804F +:101F9000FC0080C049FFA832C0048400AE34AE35D6 +:101FA000FC80EBD9DD9EEBC9DD9E4432CFA8AE1894 +:101FB000AE59AE9ADD9E3C0FFA9DDD9E3C0DFA9D1A +:101FC000DD9E3C0DFB8C465FF00FEAB6FF464600F7 +:101FD0001000D80684003E07EE338401DD9E8400A5 +:101FE000DD9E2E17FB7A2E57FB7BEB254C12C01083 +:101FF0002E27FB785A28010CA6059D49400280B681 +:1020000097683E57FB7A3E57FB7BDD9EA6058CA169 +:10201000400280B697683E57FB7BD90484013E0797 +:10202000FB78DD9EEBF82E17FB7BD9042E07FB789F +:10203000C00FEB258CA1A605400280B697683E57DD +:10204000FB7A4C12C00584003E07FB788401DD9EBC +:10205000EBF82E07FB7BD8072E07FB7884208E0138 +:10206000EBB7DD9E8401DD9EEBF82E07FB7BD807E6 +:102070002E17FB78840040000406DD9E8401DD9E5F +:10208000FC0084A08C81E2A4E80738600804386072 +:102090008C0C8CA1D5F9FC8080603C0DFA9D9E4192 +:1020A000E622E8263C2DFF0884200041000AE224B5 +:1020B000E809A159385287025A58010384028C2139 +:1020C000D5F7FC0084200041000944500044E2247C +:1020D000E80CB44342209473B4429F91E6C2E906EF +:1020E0005A2004058C21D5F4FC808401FC80DD9EFF +:1020F000FC618141B4C1843F101F80072E172C3032 +:102100008120C1082E17FB48C90549FFFFC73C0FB6 +:10211000FA9D3C3DFA9D5A3001044800009C84E041 +:102120003C5DFF082F27FB3C3D3C040E3CBDFF09F6 +:10213000802344C0004481A781C78506861F86226C +:102140009E89000280099690E240E81243413024C3 +:10215000B40941505000B4159E81E642E9035A0883 +:10216000047604048003B4009E81E642E808841FDC +:102170001003003E1003003F480000AB5A0004F972 +:10218000DD555A0802052E0010AFC8F25B28010485 +:102190005B3005EF00058003222A8004224A800577 +:1021A0000372800203628003C01702028009518B10 +:1021B000FFFF8E0140F045F642F16073518B7FFFC7 +:1021C000402780560202800A8E0140F045F642F216 +:1021D000607340478096E057E903502BFFFFE0967D +:1021E00042013400E903504B7FFF81E642F3A073C4 +:1021F000844240210464424238001027800040207D +:10220000100A102780014022100A10278002971F11 +:1022100040420084020A800A10478003C006B44985 +:10222000885400010014D502840110078004020ABA +:10223000800BC0039600D50284018CE11007800555 +:1022400097F81103003C1103003D8C21964848FF8C +:10225000FF795A38022784181003003C84E0840078 +:102260001003003D3C4DFF0880070012000AE20108 +:10227000E81304148001381083025A18010B00235C +:10228000003D4010800CFE578CE11013003D97F884 +:102290008C019600D5EB0003003D3E07FB43D518AB +:1022A0002E77FB40C7152E07FB41A670E61EE805FA +:1022B000965740008064D503440000F0AE302E07EE +:1022C000FB42AE328401AFF13E07FB4884E0EBD91C +:1022D0005A00FF0DC00BCF0A841F3E07FB483C0D80 +:1022E000FED18C013C0FFED1D5033E77FB485A3816 +:1022F00001143C0DFF0800400009E2E4E80D8426CB +:102300008406FE7C8A87B44AFF0496488822EBC381 +:1023100084408E81F940B42A840080A150208040FE +:102320000832800188039600DAFCFE02100080402B +:1023300004248003B4029E41E622E9055A00040405 +:10234000480000CA22110006220100075EF08C80BE +:10235000E805846042108C00D50344100C7F5EF0C9 +:102360001400E805846042000C00D503440013FF0C +:102370000021007284615A280104443000F01033B7 +:102380000041042480035A38F02E840010010072AA +:10239000041480034420FF000400801404308015DE +:1023A00040100802922810130042401060091013D8 +:1023B000004446100FF010030043FE0E9210FE9EE4 +:1023C000FE5E1003004592484001E0099230102360 +:1023D0000046103300471003004810130049848959 +:1023E000D56E4030A00A101300434010200A10336D +:1023F0000042101300441003004500010043C806CA +:1024000002010025C8088401D5045A08010584008A +:102410001201002502010025100300474010200989 +:10242000101300463C1DFF09A608C0060201001457 +:10243000FE029603D50322010014A6C9C306023189 +:102440000015FEDA96DBD50322310015A64AC9062F +:102450001003004810330049D5051033004810031D +:10246000004984001003004A000100431003004BA0 +:102470000001004096440003004CEB3CFE0F1003AB +:10248000004C00010040541000020003004C960470 +:10249000FE0F1003004C000100415A0001085A00D1 +:1024A00002085A080309EA4BD507FA10D50544007B +:1024B0000040D502FA001003004D848DB44A50123A +:1024C00000418822EBC3844084615242000DF863CE +:1024D0008421D50AB42AEBC3501080418440846122 +:1024E000848DF8598420B44A840050510041503101 +:1024F000004E0842800188049600DBFCFE021001B9 +:10250000004EEBC95A00FF0AC008C907841F3E07E6 +:10251000FB3CCF078401D5063E17FB3CCF02C1FB35 +:1025200084003E07FB7EFCE1FC0084418062444065 +:10253000004EF831FC80A60092038C1596275C00B3 +:102540000014DD9EFC4080E08400EB43A63880C18F +:10255000C80400038008C0332E1010AEC9302E0707 +:10256000FB795A08010B2E27FB7C3E27FB7A3E277E +:10257000FB7B3E17FB78EB4349FFFD35EB252E97A0 +:10258000FB7BA7043C1DFEDD8441A03942149073FF +:1025900080628E8149FFFD762E07FB7E5A08010678 +:1025A0003E07FB793E97FB7C2E07FB3D5A00FF055B +:1025B0008C013E07FB3D8401EBAFD50484003E0750 +:1025C000FB3D2E17FB7DB4065A18012AA605C81438 +:1025D000F835C80DEB252E37FB7CA684B4263C0DC0 +:1025E000FEDD42018873B421F839D50849FFA4D72C +:1025F000F825C8FFD5F0F822C802F845B4268400B3 +:10260000EB433E07FB798401AE0DB426AE0CB4C695 +:10261000B406F8345A08013DAE37D53AA644C90489 +:10262000F870C036D50BA6055A080106F807C83061 +:10263000F82AD52E49FFFD0EC8FA49FFA4E380E031 +:10264000C82749FFFCF1EB252E97FB7AA684B42618 +:102650003C0DFEDDB4214204887349FFFF672E174D +:10266000FB795A1801112E57FB7C4C54C00DB4064F +:102670003E77FB79AE45B4E6B40749FFFF5E5A08E2 +:102680000103AE3F49FFA4CEB4068421AE44FCC092 +:10269000FC2080E1A0413C1FFED82E17FB483E17CE +:1026A000FB68A042A0033C0FFEDBEBC93E07FB70BA +:1026B0002E0010AE4422CFE83C1FFED93C2FFED79F +:1026C00080C2C8074402CFC84412CFC449FFFD12DC +:1026D000EBD93E07FB50EBC93E07FB58B407441249 +:1026E000CFB43C0FFED34402CFB83C6FFED549FFB8 +:1026F000FF2B84003E07FB403E07FB413E07FB42A9 +:1027000049FFFCB4FCA03C0FFFEEDD9E3C0FFFED4B +:10271000DD9E84003E07FFB0DD9E4402B5B03C0F55 +:10272000FFEBDD9EFC6700608009230000022310A0 +:102730000003C6103C5DFFEDA6EA8E614C61800B84 +:1027400000308008C307A7AB8EC1FF9D5C6300010A +:10275000D50284C184603E37FC52EAE8043000119F +:10276000EAB6FF5E447100004432D090DF0D84A5CC +:102770003C5FFF1384A03C5BFE203C5BFE213C5B86 +:10278000FE1E3C5BFE1F3C5DFF13C26AC5048560F4 +:102790005A5805093C7DFFEB85610073801C3E772C +:1027A000FC503C77FE2041281C013C77FE214078FC +:1027B0009C01FFFC427948735A500305C5035A58DF +:1027C00005153C4DFFEB02520011A508E2A42E476F +:1027D000FC50E807A449E2A1E804C4038E819720D5 +:1027E00084A3CC0484A1D50284A281918110842089 +:1027F000B6205A50051EB6FFEBA4149F8002128F1C +:10280000800A12CF800B130F800C131F800DF589E7 +:10281000104F802810BF802A106F8035803F3B000A +:10282000E4043B01E4243B00CC003B01CC203E27E8 +:10283000FFA8B6A010B0005A1280000412C0000514 +:102840001470001714A00018149000191420001A16 +:102850005A58014A1280001C12C0001DD5449E69BE +:10286000E622E80C3C1DFFEB2E47EFEEA6495A4846 +:10287000010EE625E80B8425D5095A5803043E27A6 +:10288000FC502E17FC50C1048E213E17FC502E47E1 +:10289000FC505A48010684243E17FC52D503842577 +:1028A000C40284243C1FFF1380C3803F3B036404A5 +:1028B0003B00E4243B034C003B00CC203C7DFF0A62 +:1028C0003CADFF0B3C9DFF0C3C87FE1E80B93CC716 +:1028D000FE1F3D07FE203D17FE212EB7FC522E673E +:1028E000FC5DD586FCE73C0E0044DD9E3C0E0043BB +:1028F000DD9E4402B5D83C0E0042DD9EFC40B44053 +:102900004E2200F90070005A96FCC30E84213E1737 +:10291000FFDC02100008020000093C1BFFEC3C0B2E +:10292000FFED480000E85A200404480000AC2E27C0 +:10293000EFEE4E2300E02E37FFDC3C2FFFF53C2F5F +:10294000FFF4CB402E27FFCD2E57FFCC4462D42876 +:102950005A20010580438083D5218083804355021E +:1029600000FF4D02C0048602D50286013913121100 +:102970004238447341131040231880018C8142284F +:1029800044735A4803EE84844031907640211056B7 +:102990003C3FFFF53C2FFFF4D51539031211887029 +:1029A000410310408C81230800019720E2A4885045 +:1029B000E8F58CA1EBB1405114B63C3FFFF53C5F0C +:1029C000FFF43C5C00423C4DFFF53D2DFFF4A0E9D7 +:1029D00042F2000342290003884F94D9E2624EF28A +:1029E000008A3D33FFECA6E850F9FF105CF78AA09F +:1029F000E90294D93D03FFEDA6A950F87F105CF7DA +:102A00009220E902949154638004009280020112A2 +:102A10008003C60FFF1C4219082440422496401030 +:102A2000C436403990003C3BFFEC40280400D51BE5 +:102A30008E2184C2406098D640549800405284B69B +:102A400088D1401304364251940142110401FF2CF5 +:102A500042190424403224764020C45688733C3BFB +:102A6000FFEC88503C13FFEC3C2BFFED12100008EC +:102A7000587380023C13FFED121000091070005AC9 +:102A8000D5395A2005382E17FFDC5A1801093E3770 +:102A9000FFCD3E37FFCC3E37FFDCD5152E17FFCCE0 +:102AA000E622E8058C213E17FFCCD5033E37FFCC4C +:102AB0002E17FFCDC9082E17FFCC5A180205842106 +:102AC0003E17FFCD223000083C23FFEC2E17FFCC31 +:102AD0004442D4289A9A38220609222000093C034D +:102AE000FFED401204409A10AC093C3BFFEC3C2B3C +:102AF000FFEDFCC0FC000010004310100044042057 +:102B0000001146100FFF50108F00FE565A19002B6F +:102B100084203E17ECC8041000175CF08064E803C2 +:102B20008421D5105CF083E8E8038422D50B5CF0A7 +:102B3000A710E8038423D50644204E1FE241E90490 +:102B400084243E17FFBE2E1003A1C1085A101F0790 +:102B50002E1003A0C1035A18311284203E17FFBE65 +:102B6000D50DEB6B5A1801082E17ECC85A10FF0749 +:102B70008C21D502843F3E17ECC82E47ECC82E3777 +:102B8000FFBEE264E91FB4205A1004045A18021B65 +:102B9000842002500026101000439A5C42209424A6 +:102BA000945D40110436CC033C5BFFDE3C33FFDE1A +:102BB0009649844342118873902296493C1BFFDE5C +:102BC000D507EB6B101000435A1801058420121032 +:102BD0000025FC803C0E0046DD9E3C0E0045DD9E3F +:102BE000FC00C0045A000108FC8049FFD2CB3C0E17 +:102BF0000047FC8049FFD2CF3C0E0048FC80920089 +:102C00008020E6093C0C0048E82344F12A14EB2715 +:102C1000EA93DD0F0A3C10161C22282E34003C0CCF +:102C20000047DD9E500000F0DD9E500001E0DD9E7B +:102C3000500002D0DD9E500003C0DD9E500005A074 +:102C4000DD9E50000780DD9E50000960DD9E8400FF +:102C5000DD9E9200FC4080C280E13C2C00483C1C80 +:102C600000478123814449FFD2653C1C0045A60AE8 +:102C7000A64B49FFD27EEA4B4203000149FFD2989E +:102C800084C03C1C004600008010E2C0E8108006B2 +:102C90003810980049FFD29A3C0C00469846001024 +:102CA0008008800649FFD2B88CC1D5EC8400F80BAF +:102CB000F80C8401F808F8095AA801058402F80301 +:102CC000F804840349FFD27849FFD24549FFD26C0A +:102CD000EA4F840000148000E201E829A07938500E +:102CE0008101D023A07D9482956A98CA8825A6DAAE +:102CF000A70AE264E802AECAA07D98CA8825A6DBCE +:102D0000A70BE283E802AECBA07D3830880088258F +:102D1000A708E264E802AEC8A0FD884388A3A651D4 +:102D2000A6A9E241E802AE698C01D5D5FCC0FC62DF +:102D3000464C01208881446308FFE2C4804080A1A2 +:102D40004030C0094EF30082C8054603FF004C50D6 +:102D50000121808280A1FD028440463BFF00EA2DD4 +:102D6000FD10FD30EA2BFD60FD10F8EE442156A861 +:102D7000FD50EA58F8E9442156A0F8F5442156B030 +:102D8000FD40EA58FD06EA2BF8D4442156C0EA5823 +:102D9000FD40F8DA442156B8F8E6442156C8F8DB7D +:102DA000FD06EA2B3A4F9400FD10FD02EA2D442166 +:102DB00056D8F8C7442156D0F8D6442156E0F8CB6F +:102DC000FD06EA2BF8D5442156E8FD60EA58F8CE16 +:102DD000FD10FD06EA2DF8C9F8D0EA2DF8C6F8A9CD +:102DE000F8C4F082F183844046341A00F8ADFD50F7 +:102DF000F80BFD15EA68FD10FD50EA2B44215698AA +:102E0000EA58EA2BFD40FD10FD03EA2DFD60FD10A0 +:102E1000FD03EA68FD14EA2DFD40FD15FD03EA6897 +:102E2000FD10440156983A000400EA2B3A0F842022 +:102E3000FD13FD05EA2D3B0FC400FD10FD08EA2B34 +:102E4000F878F89B480000A250F1FFF044607FDF63 +:102E5000E2CFE8289509404203F540420024CC0522 +:102E60008401490000A6F813C8054607FF004C502E +:102E700000944001BC098082C8065451FFF0440010 +:102E80007FF0D80780A1FD02490000A84800008615 +:102E900080A1FD02844046343300EA2B465FCC001B +:102EA00088A1469C01A089254064B40997B74014C5 +:102EB000D009447156604043988040228681043294 +:102EC000022540A39880802204220224EA68042577 +:102ED000022604350227EA6804250024043500256B +:102EE000EA2BFD304004D00AEAEC44215660F83366 +:102EF000EA2B0425002604350027EA2DFD13FD40AA +:102F0000EA2DFD60FD13F820FD50FD16FD04EA6872 +:102F1000FD13EA2D3A4F940044215668FD40EA58CB +:102F2000FD02EA2BF80644215670FD40EA58F81ECF +:102F3000FD10FD04EA2DFD40FD15F80644215680E4 +:102F4000EA58F082F183FD03EA2B44215678F80B0E +:102F500044215690EA583A0F842083FF4E00FFF533 +:102F600044215688EA58EA2DFD10FD05EA2B3B0F57 +:102F7000C400FD10FD08EA2DF402F503FD10FD026A +:102F800083FFEA2BFD10FD04EA2DFD16EA2DD50581 +:102F900084008020D5028002FD10FD01FCE2FC408F +:102FA000FD30812249000504B720FD03FCC0FC016F +:102FB000C80584004613FF00D5048400461BFF00AB +:102FC000B61F8440F181B41F8062F10149000320E3 +:102FD000FA5249FFFFE6FC81FC60FD10FD50EA68F3 +:102FE000FD1049000315FD30FD054900000BC0062A +:102FF000FD03FA5149FFFFD5FCE0FD03FCE0920020 +:10300000C10446580000D904C8038402DD9E465F0F +:10301000FF004647FE009F2198CDE283E806465711 +:10302000FF0098CDE283E9038404DD9E4640010061 +:103030009F21E281E8064658000098CDE283E9032B +:103040008403DD9E4657FF00D104465FFF00D9028E +:10305000C0038400DD9E8401DD9E92003A6F98BC1F +:1030600040608C0390DF4E340006FEDAC203FE920D +:103070009ED94E140006FE4AC003FE029E4984807B +:103080004900003AC60840408004C405FE4AC00317 +:10309000FE029E493A6F9884DD9E920041414009AC +:1030A000974192104040D03796D14010C008FE475B +:1030B00042020C24E220E8099F21984AE222E90515 +:1030C000E220E8039F21984A9A484010D017400018 +:1030D0004008FE2FFECCE203E80998029E49E20276 +:1030E000E905E203E80398029E499A03404240083A +:1030F000FE67DD9E3BFFFEBCFD80FD918384CB4DD2 +:10310000E3B2E8194209000782A0C00D4129000C72 +:10311000525000204058140D4118800C411894045E +:103120004108000CFD08805249FFFFBA82C18200AD +:1031300086E0D523C2284209000782A0C8048BB2CA +:1031400086E1D51452F000204129000C80524048FD +:103150003C0D4058800C4108000C4002900440187F +:10316000BC0D49FFFF9D82E18220FD08805249FF8E +:10317000FF9782C1510000004FC2005386204108D2 +:10318000540DD54B41194A17842084004FC2004C7E +:10319000B79C151E0001D547E3B3E9F74209800744 +:1031A00082A0C044524000204059100D4029800C9C +:1031B000FEAF82624129000C4038100D4108000C1E +:1031C0004008800C4018900DFE1F49FFFF6982C126 +:1031D00082204200C869E3A1E9054C18C00CE380D5 +:1031E000E809516B7FFF8A3340304801E2038A2FA0 +:1031F000800386E04FC2001540080001401884019A +:10320000E3808A2F524A80204110900C4100540DD7 +:10321000410844044110D40DB79C151E00018016CE +:10322000501B80003BFFFE84DD9EE3F1E903E39247 +:10323000E90986C1404848018BB3E3848BAF82041F +:10324000D50286C086E04FC3FFE9D5EA4231FC0AC9 +:1032500095093A6FA8BC959947E80000E286E90510 +:103260004C434009E202E806FD40FD01FD149509CA +:103270009599FECD4031F8024072540940A354099B +:103280004092280840832808445007FF4C5380C4CC +:1032900040F200044EF200BC40F308044EF20092EB +:1032A0004063A8015CF300404EF2008C405054098A +:1032B0004094940440002C08405154094084140464 +:1032C00040212C08E6E2E9274094F8044EA20004CD +:1032D000408478049F714062A81AC61D5253002092 +:1032E0004E57000C4041140C4054140C4084180DEF +:1032F0004021180DFEAFD50CFFAA5052802040444B +:10330000140CFF174043181A4024180D8500C403FD +:1033100058210002C3594C7540064C9440044C019E +:103320000078E328E9054C94400AE202E8079FF997 +:1033300040447C0893019241FEA780809A02E2807B +:103340008B2F8B28E6E2E9494E93000BFA9040431D +:10335000900680A7CC0D812084005073FFE042547A +:103360008007E2A75247800142529C01C50D9BFD98 +:103370009B6C526280204040180D4094940C400099 +:10338000140C40949004500004005CF00400892F59 +:10339000E32F88EF40502C09976C80C09A05E2C05B +:1033A0008B2F409484084054D008932C920BFE2F0E +:1033B0004053D008409494044010F8024010A404F4 +:1033C0003A6FA884DD9E9802E202892FE32F8928B4 +:1033D000E90AE328E908CFD8920B4044D408932B9C +:1033E000FE27D5EB525387FEC50E54F0000158500E +:1033F00000024002BC1B4044FC0893219201FE27BE +:103400009DF9D5C284004697FF00D5D7C3DA840062 +:103410008420D5D7409480044C9F40054C557FD2E2 +:10342000C3D0840044180000D5CC9200FC4295091A +:1034300092954070AC0840605409FFF740602C083A +:1034400047C80000955992B54091AC084081540995 +:103450004094A00440812C08FECD40A1F0024430ED +:1034600007FFC4584C3200754073F0044E52008779 +:103470004C3280794094F00414AF80035002FC0277 +:1034800099204223A4694203246940910400E32166 +:1034900040A1BC004223A06999D0E2E0892FE32F2C +:1034A000894F8923E323894F4203206999F9E2E197 +:1034B000892FE32F40153C00FFC7580480014004CA +:1034C0009C1AE420E90781E09800E20F9849882FD0 +:1034D0009F2104AF80034E470071525207FF4E57A1 +:1034E0000046500004005CF00400E804882FE22F3E +:1034F000888F40202C0996949A02920B4020D40881 +:10350000FE179449922C40525008FE6F4010A804B8 +:10351000FCC240F39804E81940F37C0999FF88EF56 +:1035200099B6CF0580E684C050427FE04203800711 +:10353000C09E9B20522000204023080D4063000CB9 +:103540004073800CFFD7D593D315802AFCC2FFF7B8 +:103550004C7E4011CD064024840840212004C20A3C +:10356000DB054094A0044C9E400684004617FF00F3 +:10357000D5CE840044180000FCC24004A004C0E67C +:1035800040F47C098929892F89084E9300068128F7 +:1035900085005052FFE0420480074E02FF6F9B6897 +:1035A000522000204024080D4084000C4094800CE0 +:1035B0004094880448FFFF6284C0523200015CF1ED +:1035C0008020E90A80C0800184205031FFE0C004DF +:1035D0005CF18020E81AC310522180204070880CD2 +:1035E0004050080C40000C0D40108C0DFE3FFFAF0A +:1035F000C60358000001500004005CF00400882F4E +:103600004040FC0948FFFF778400D5A0FC429509A3 +:1036100092954070AC0840605409FFF740602C0858 +:1036200047C80000955992B54091AC0840815409B3 +:103630004094A00440812C08FECD40A1F00244300B +:1036400007FF4E4200C54C3200EF4073F0044E526B +:1036500000FB4C3280F34094F0049B25504203FF62 +:1036600092C14013FC08FF8F92E14024C00940330F +:1036700088F74014801342508C244073C0084003E4 +:103680004009FFC780079BFDE207E8059ED988E94E +:10369000E2E9E8FD402388F7425088244073C008DF +:1036A0009631FFC780079BFDE207E8059E9188E9F8 +:1036B000E2E9E8FD4031C00898DA4201A069FF82E2 +:1036C00080079BF9E207C60580079FF9E903E20737 +:1036D000E80C9ED988C84003200688E9E2E9C004C6 +:1036E0009DF9E903E6E1E8F64C74C007802880E61E +:1036F00084408400D52B4014C009402384F7400443 +:10370000801342F008244073C00840534009FFEF83 +:1037100080A78AEFE2A7E8059E9188E9E2E9E8FD43 +:10372000401384F7425004244073C0089631FFC709 +:1037300080079BFDE207E8059E4988E9E2E9E8FD8C +:1037400040214008989142012069FF8280079BF93F +:10375000E207C60580079FF9E903E207E80C9E919E +:1037600088C84003200688E9E2E9C0049DF9E9031E +:10377000E6E1E8F6E460E90781E29892E24F98DB3F +:10378000886F9F21FFF75801000140011C1A802318 +:103790004E470079525207FF4E57004A500004002E +:1037A0005CF00400E804882FE22F888F40202C0969 +:1037B00096949A02920B4020D408FE179449922CBA +:1037C00040525008FE6F4010A804FCC240F3980419 +:1037D000E81B40F37C0999FF88EF99B6CF0580E696 +:1037E00084C050427FE0420380074E02FF329B209C +:1037F000522000204023080D4063000C4073800CD1 +:10380000FFD748FFFF26D307CD0440F4A004E80704 +:10381000802AFCC24094A0044C9E3FFC84004418C3 +:103820000000FCC2FFF74C7E7FFBD3F984004617F3 +:10383000FF004010A804FCC24094A0044C9E7FF0FE +:103840008400D5E740F4A004E8F240F47C0989291B +:10385000892F89084E930006812885005052FFE089 +:10386000420480074E02FEFB9B6852200020402449 +:10387000080D4084000C4094800C4094880448FF5C +:10388000FEEE84C0523200015CF18020E90A80C063 +:10389000800184205031FFE0C0045CF18020E81AF0 +:1038A000C310522180204070880C4050080C40000A +:1038B0000C0D40108C0DFE3FFFAFC60358000001F9 +:1038C000500004005CF00400882F4040FC0948FFD1 +:1038D000FF6F8400D59E92003A6F983C954992B54F +:1038E0004040AC0840605409FF3740302C0846681F +:1038F0000000FF375CF2843EE8215222843EFAD079 +:10390000E246E9068064848050217FE0CBF9C20B57 +:1039100080044031880D4042080D522100204000B3 +:10392000080CFEC7E420E805FF22C303FEDA8E81FF +:10393000800380243A6F9804DD9EE420E90752F268 +:1039400087FFE90895A1FF9FC605464800008460EF +:10395000D5F04647FFFF58420FFF847FD5EA92001B +:103960003A6F983C842080A180618040C210E4407E +:10397000E80746580000FE92C103FE4A8E414430DB +:10398000041E424100079ADC4021100C4040AC0963 +:1039900040615408FF37959192CCFF774061D00881 +:1039A000FF77800480253A6F9804DD9E4402D58C11 +:1039B000DD9E92008060E644E92854418003545023 +:1039C0008003C50B525280049A9599690840800182 +:1039D000184180014C12FFFC40511409C50A956D35 +:1039E000996996A73B00DC043B01DC244C12FFFCE8 +:1039F00040510809C50A956A9969968F3A40900422 +:103A00003A4190244C12FFFCC208994A08408001B8 +:103A1000184180014C12FFFCDD9E92008060E6445C +:103A2000E93054518003C509525280049A9599682F +:103A3000181180014C32FFFE96484040A008FE67F6 +:103A40004040C008FE67405114094E520011956D68 +:103A5000996B96A78201822182418261828182A133 +:103A600082C182E13B01DC244C32FFFE4051080957 +:103A7000C508956A996B968F3A1184244C32FFFEE3 +:103A8000C206995A181180014C32FFFEDD9E920049 +:103A90003C0DFB6049000E3F490043594900368008 +:103AA00049000F344403F04A44100055490064555E +:103AB000490043594900371E49009BDA3C0DFB740D +:103AC0003C0DFC44480001554900368044038D40BC +:103AD00049001EE74900371E04008011490036D214 +:103AE0003C1DFB863C0DFB5F49003A1C3C1DFB6006 +:103AF0003C1DFB743C0DFB862E07ECD73C0DFB8474 +:103B000049000E3F490064552E07F0834900389262 +:103B1000480083364420019044200055490012D6C5 +:103B20002E07ECEC3A6F98843C1DFC444412FEF0E6 +:103B30004413F04A400000094900537549009916A2 +:103B40003E07ECF64900982849006CF8100F8007F2 +:103B50002E07ECF2442001804402DD242E17F022CF +:103B60002E1FEF8850037F4840F03C003C0FFB5F66 +:103B7000443000554423F04A2E00107D4900635E16 +:103B80003E07ECA840310C402E000DE43C0FFC0138 +:103B9000490062742E072C34440FFFAA49006F6558 +:103BA000100F800F4400005549001E323C0DFB7B76 +:103BB0003C0E037F49000E4344338D41440000FF17 +:103BC00049009C0E580000014900972E1004800007 +:103BD000000000514402C24854007FFF3C0E037EA7 +:103BE0001010001C100480013C0FFB84120F800396 +:103BF0003A210C003C0BF68C4402E4A02E000E008F +:103C000049006F65490036F83C0DFB851093800034 +:103C1000443001905410FFFF3C0C004A020F800317 +:103C200054637FFF3C1DFB78490012974402FEF06D +:103C3000490098264900688F10100051490066D548 +:103C40004200080B49000F343C0FFB834403000083 +:103C50002E07EC9D5800000449006F186600000212 +:103C600049003F824463F04A5800001044131C206E +:103C70002E00114249005375640304033E07EF8987 +:103C80003E07ECEC3E07EA3C4900651A49003A1C45 +:103C90002E07ECB0380780003E000E004413F403FA +:103CA000440365103C0BF6A0000480013C08085456 +:103CB0003E07ECA14473F04A3E07EFE62E0FEF8972 +:103CC000580000026600000449006CE14490005571 +:103CD000490071433C0DFBCB490019EF40F0BC009B +:103CE0003E07EC924412C10F447000552E072C334E +:103CF0003E17EF88440200003C0FFB9549007768AF +:103D0000540000FE4200040B440000504462FEF0E8 +:103D10004400006910030050382080083C03F68DF1 +:103D2000580000204412FE5042000C0B3C0BF8D807 +:103D300066000060502F80072E07ECA8490032BCB7 +:103D40003E07EF8B49001A41021F8000441262387F +:103D50002E07EC86503F800748000171480001287B +:103D60003E17ECB93C0DFBAC50528F003E07ECEE19 +:103D700050000FFF440373E84402FE504430032018 +:103D80003E07ECC1490066D54413F2483E07ECD625 +:103D90004422C28C2E07EC7A49005BEF2E07EC9888 +:103DA000120F80025CF003E8441000322E07F14845 +:103DB000442000643E07ECB0400080404402E1E053 +:103DC0003E07ECD7490010954900745D2E07EFFAC5 +:103DD00038078101440397DE440397DC580000084C +:103DE0005CF000332E07EF80490036D23C0E037A98 +:103DF00044130000000480002E07F19C40320D00A7 +:103E0000020F800149001F6F2E07F0E83C0BF8D924 +:103E10005CF0070838308A0A501F800F502F800648 +:103E20003C0DFB6F49005CD83E07ECB94900679236 +:103E300046500FFF500F800E4200100B4900435CAC +:103E400049009BB0641304022E07EFEA3C0FFBB954 +:103E5000660000103C0E037B443000322E072CC657 +:103E60003C0C004B5C00000149007319490077903D +:103E70004422DC303E07ECA3440262380462801620 +:103E8000443000803C6FFCB012048000020F8000C0 +:103E9000441216803C0FFB8A3C1DFBD42E07EC8E8F +:103EA0003E07F11F44134C102E072BA3400018406F +:103EB0003C0FFB98440000324422E578541080FE09 +:103EC0003E000DE43C6FFBB9401004404900435CE8 +:103ED0004402FEF12E07ECE53E07ED0649007DAFFA +:103EE00044130FA0400004164413F1C0540000F026 +:103EF0004403F41C000F80062E17F083500F800639 +:103F0000540000FD000F800F660000083C1FFB837B +:103F10002E17ECD7641324033C0BF7F23E07F0177F +:103F20004412D8383C0DFF09490072A638178400A6 +:103F30003E17EC8849003E4A4900388B1812800130 +:103F400049000E4F440200003E07ECE53C0C0061C6 +:103F500049001186490037A44000810044136510D0 +:103F6000420888242E07ECA3502F800F4231800393 +:103F70003C0BF7E844000078000F80073C2395E6EF +:103F8000660000012E07ECB83C0E037844038D4216 +:103F90003C5DFB6F4900714349005C063E07FB7DB9 +:103FA000440000523E07EC7F0423000C401004360E +:103FB000490038F82E07EF8149007E353E07F14F62 +:103FC00049003E1E4400012C403184764412A50A6B +:103FD00049005C6D64030803380486024412C15131 +:103FE0004003200949001738441200003C1DFC0E14 +:103FF0003E07EC8E3E07EC8A444000554402C10562 +:104000001003004110050000120F80002E07F11F61 +:104010003E07F01F44037A283E07F1934403F7CE8E +:10402000030200002E07EC8A2E07EC8C3C1BF89351 +:104030003C0DFBB93C2FFB8449008EDB0010004592 +:1040400040213C08041180144900714840108C360E +:104050002E07EFF11010003C002F800749001A4195 +:104060003C1C037A490072C43E07EF803E07F154BE +:10407000109000004412C17E1010005210008051B8 +:104080004400006449001EDF49001BF53C03F8D8DA +:10409000121000102E07ECEA4403F00E2E07ECB9C4 +:1040A00049005AA23B014C00441000A544133310B0 +:1040B0004900835A4410004C3C1DFB5F490068B71F +:1040C0003C0C040E4403F7C849003D3C490076C24D +:1040D000120300254900635E40109C36549000FF97 +:1040E0004402FE604413F2493E072CC63C0BF68B9B +:1040F0002E07ECC23C3DFB6C3C0C00503C1FFCAF5F +:1041000044138D403E07EFF2520000010030000ED4 +:104110003E07ECA43C0FFC022E07ECCD1003004040 +:1041200014AF8001500002403C0FFBAB120F800126 +:104130004402C2083E67F014490037444412D800D4 +:104140003E07F1253E07ECE14412C0E93E0010AE07 +:10415000442000B6403194764403F0803C0DFC705E +:104160003C0C02332E07ECA94220907340008006DD +:104170003E07EFEE3C0FFBB6460000F43E07EF8132 +:104180003E07F155490063F749007FE13B0FCC2022 +:104190003C0FFBA13C0FFB644412D788500F8007F3 +:1041A000441FFFAA41127C0A10A48000490038E293 +:1041B000100F80332E07FB3C44037D484412E4A0DB +:1041C0003E07ECE83E07F148441000A44402FEFD1F +:1041D000490038BF3E07ECC5490022773C0DFC542E +:1041E0000423000A441000A2440385182E772B9B59 +:1041F000021F80012E07FB483E07EC813C1FFB8419 +:104200004010BC084412A9BA490068F2441FFFA03C +:10421000441281783C6FFB5F108600003C0FFBB7B7 +:104220002E17F01442108003490037C712030026EE +:104230003C0DFC993C0DFB8B580000403C03F7E81B +:10424000660038003E07F01449001095490023D954 +:104250003C1BF693440000823C1C02344413F24B96 +:104260003C1DFB8502030025441000644491522448 +:104270002E57FB7A3E07EFF5440000433E07ECCC97 +:1042800044138D413E07EFF13E07ECCA2E07EC7E4A +:104290008492030014940300FAAF02008AB1020072 +:1042A000648F0300F4900300DAAC02006AAE0200EF +:1042B00010330300903F0300104C0300905803009C +:1042C00000A2010080AE010000BB010080C7010018 +:1042D00010D8010050DE010090E40100D0EA010096 +:1042E000E8730300F8740200A00F03006880030065 +:1042F00064676B6F7072767DB3A5968974647D9DDB +:1043000064666A716F70757DADA1928773647D9EDE +:1043100064676B6F7072767DB3A5968974647D9DBA +:1043200064666A716F70757DADA1928773647D9EBE +:1043300064676B6F7072767DB3A5968974647D9D9A +:1043400064666A716F70757DADA1928773647D9E9E +:1043500064676B6F7072767DB3A5968974647D9D7A +:1043600064666A716F70757DADA1928773647D9E7E +:1043700064676B6F7072767DB3A5968974647D9D5A +:1043800064666A716F70757DADA1928773647D9E5E +:1043900064676B6F7072767DB3A5968974647D9D3A +:1043A00064666A716F70757DADA1928773647D9E3E +:1043B00064676B6F7072767DB3A5968974647D9D1A +:1043C00064666A716F70757DADA1928773647D9E1E +:1043D00064676B6F7072767DB3A5968974647D9DFA +:1043E00064666A716F70757DADA1928773647D9EFE +:1043F0006464686C6A6B7075A89C8E8370647D9A27 +:104400006564686F6C6E7277A1948A816E647B9B21 +:104410006464686C6A6B7075A89C8E8370647D9A06 +:104420006564686F6C6E7277A1948A816E647B9B01 +:104430006464686C6A6B7075A89C8E8370647D9AE6 +:104440006564686F6C6E7277A1948A816E647B9BE1 +:104450006464686C6A6B7075A89C8E8370647D9AC6 +:104460006564686F6C6E7277A1948A816E647B9BC1 +:104470006464686C6A6B7075A89C8E8370647D9AA6 +:104480006564686F6C6E7277A1948A816E647B9BA1 +:104490006464686C6A6B7075A89C8E8370647D9A86 +:1044A0006564686F6C6E7277A1948A816E647B9B81 +:1044B0006464686C6A6B7075A89C8E8370647D9A66 +:1044C0006564686F6C6E7277A1948A816E647B9B61 +:1044D0006464686C6A6B7075A89C8E8370647D9A46 +:1044E0006564686F6C6E7277A1948A816E647B9B41 +:1044F000646568686F6E7376A6958A7C6E647F9B30 +:104500006465676A6E6E7374A3968A7A6E647C9C27 +:10451000646568686F6E7376A6958A7C6E647F9B0F +:104520006465676A6E6E7374A3968A7A6E647C9C07 +:10453000646568686F6E7376A6958A7C6E647F9BEF +:104540006465676A6E6E7374A3968A7A6E647C9CE7 +:10455000646568686F6E7376A6958A7C6E647F9BCF +:104560006465676A6E6E7374A3968A7A6E647C9CC7 +:10457000646568686F6E7376A6958A7C6E647F9BAF +:104580006465676A6E6E7374A3968A7A6E647C9CA7 +:10459000646568686F6E7376A6958A7C6E647F9B8F +:1045A0006465676A6E6E7374A3968A7A6E647C9C87 +:1045B000646568686F6E7376A6958A7C6E647F9B6F +:1045C0006465676A6E6E7374A3968A7A6E647C9C67 +:1045D000646568686F6E7376A6958A7C6E647F9B4F +:1045E0006465676A6E6E7374A3968A7A6E647C9C47 +:1045F000646568686F6E7376A6958A7C6E647F9B2F +:104600006465676A6E6E7374A3968A7A6E647C9C26 +:1046100064686C6F77767D7EAEA08F7D6D647EA0C2 +:104620006465696C71737879AB9C8E7B6C647EA2D7 +:1046300064686C6F77767D7EAEA08F7D6D647EA0A2 +:104640006465696C71737879AB9C8E7B6C647EA2B7 +:1046500064686C6F77767D7EAEA08F7D6D647EA082 +:104660006465696C71737879AB9C8E7B6C647EA297 +:1046700064686C6F77767D7EAEA08F7D6D647EA062 +:104680006465696C71737879AB9C8E7B6C647EA277 +:1046900064686C6F77767D7EAEA08F7D6D647EA042 +:1046A0006465696C71737879AB9C8E7B6C647EA257 +:1046B00064686C6F77767D7EAEA08F7D6D647EA022 +:1046C0006465696C71737879AB9C8E7B6C647EA237 +:1046D00064686C6F77767D7EAEA08F7D6D647EA002 +:1046E0006465696C71737879AB9C8E7B6C647EA217 +:1046F00064686C6F77767D7EAEA08F7D6D647EA0E2 +:104700006465696C71737879AB9C8E7B6C647EA2F6 +:1047100065646B6970707878A5948C756A647E9F07 +:1047200065646A676F6F7575A59489746B6480A002 +:1047300065646B6970707878A5948C756A647E9FE7 +:1047400065646A676F6F7575A59489746B6480A0E2 +:1047500065646B6970707878A5948C756A647E9FC7 +:1047600065646A676F6F7575A59489746B6480A0C2 +:1047700065646B6970707878A5948C756A647E9FA7 +:1047800065646A676F6F7575A59489746B6480A0A2 +:1047900065646B6970707878A5948C756A647E9F87 +:1047A00065646A676F6F7575A59489746B6480A082 +:1047B00065646B6970707878A5948C756A647E9F67 +:1047C00065646A676F6F7575A59489746B6480A062 +:1047D00065646B6970707878A5948C756A647E9F47 +:1047E00065646A676F6F7575A59489746B6480A042 +:1047F00065646B6970707878A5948C756A647E9F27 +:1048000065646A676F6F7575A59489746B6480A021 +:1048100065646D6A6F727979A8958A78686480A1F9 +:1048200068646D6D73727979A6958A75696482A3DF +:1048300065646D6A6F727979A8958A78686480A1D9 +:1048400068646D6D73727979A6958A75696482A3BF +:1048500065646D6A6F727979A8958A78686480A1B9 +:1048600068646D6D73727979A6958A75696482A39F +:1048700065646D6A6F727979A8958A78686480A199 +:1048800068646D6D73727979A6958A75696482A37F +:1048900065646D6A6F727979A8958A78686480A179 +:1048A00068646D6D73727979A6958A75696482A35F +:1048B00065646D6A6F727979A8958A78686480A159 +:1048C00068646D6D73727979A6958A75696482A33F +:1048D00065646D6A6F727979A8958A78686480A139 +:1048E00068646D6D73727979A6958A75696482A31F +:1048F00065646D6A6F727979A8958A78686480A119 +:1049000068646D6D73727979A6958A75696482A3FE +:1049100065646D6A6F727979A8958A78686480A1F8 +:1049200068646D6D73727979A6958A75696482A3DE +:104930006F6F6F6F6F6F6F6F70707070707070707F +:1049400070707070707070706F6F6F6F6F6F6F6F6F +:104950006C6C6C6C6C6C6C6C6F6F6F6F6F6F6F6F7F +:104960006C6C6C6C6C6C6C6C6F6F6F6F6F6F6F6F6F +:104970006A6A6A6A6A6A6A6A6B6B6B6B6B6B6B6B8F +:104980006A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A87 +:104990006767676767676767696969696969696997 +:1049A0006868686868686868686868686868686887 +:1049B000686868686868686869696969696969696F +:1049C000676767676767676768686868686868686F +:1049D0006666666666666666686868686868686867 +:1049E0006767676767676767676767676767676757 +:1049F0006464646464646464646464646464646477 +:104A00006464646464646464646464646464646466 +:104A10006666666666666666666666666666666636 +:104A2000666666666666666665656565656565652E +:104A30007070707070707070707070707070707076 +:104A400072727272727272726F6F6F6F6F6F6F6F5E +:104A50006D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D86 +:104A60006D6D6D6D6D6D6D6D6C6C6C6C6C6C6C6C7E +:104A70006C6C6C6C6C6C6C6C6D6D6D6D6D6D6D6D6E +:104A80006D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D56 +:104A90006B6B6B6B6B6B6B6B696969696969696976 +:104AA0006B6B6B6B6B6B6B6B696969696969696966 +:104AB0006A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A56 +:104AC0006A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A46 +:104AD000686868686868686867676767676767675E +:104AE000696969696969696968686868686868683E +:104AF0006464646464646464646464646464646476 +:104B00006464646464646464646464646464646465 +:104B1000666666666666666665656565656565653D +:104B20006868686868686868666666666666666615 +:104B300074747474747474746F6F6F6F6F6F6F6F5D +:104B4000717171717171717172727272727272724D +:104B500071717171717171716A6A6A6A6A6A6A6A7D +:104B60006C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C85 +:104B70006F6F6F6F6F6F6F6F6B6B6B6B6B6B6B6B65 +:104B80006D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D55 +:104B9000707070707070707069696969696969694D +:104BA0006C6C6C6C6C6C6C6C6A6A6A6A6A6A6A6A55 +:104BB000707070707070707069696969696969692D +:104BC0006D6D6D6D6D6D6D6D6C6C6C6C6C6C6C6C1D +:104BD0006D6D6D6D6D6D6D6D68686868686868682D +:104BE0006C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C05 +:104BF0006C6C6C6C6C6C6C6C69696969696969690D +:104C00006B6B6B6B6B6B6B6B696969696969696904 +:104C1000666666666666666665656565656565653C +:104C20006767676767676767656565656565656524 +:104C30006464646464646464646464646464646434 +:104C40006565656565656565656565656565656514 +:104C50006D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D84 +:104C60006B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B94 +:104C70006D6D6D6D6D6D6D6D6F6F6F6F6F6F6F6F54 +:104C80006D6D6D6D6D6D6D6D6E6E6E6E6E6E6E6E4C +:104C90006C6C6C6C6C6C6C6C6B6B6B6B6B6B6B6B5C +:104CA0006A6A6A6A6A6A6A6A6B6B6B6B6B6B6B6B5C +:104CB0006A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A54 +:104CC0006A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A44 +:104CD0006A6A6A6A6A6A6A6A686868686868686844 +:104CE00068686868686868686A6A6A6A6A6A6A6A34 +:104CF0006A6A6A6A6A6A6A6A686868686868686824 +:104D00006767676767676767676767676767676733 +:104D1000676767676767676766666666666666662B +:104D2000676767676767676766666666666666661B +:104D30006464646464646464646464646464646433 +:104D4000646464646464646465656565656565651B +:104D50006B6B6B6B6B6B6B6B6A6A6A6A6A6A6A6AAB +:104D60006D6D6D6D6D6D6D6D696969696969696993 +:104D700069696969696969696868686868686868AB +:104D80006A6A6A6A6A6A6A6A69696969696969698B +:104D90006868686868686868686868686868686893 +:104DA000696969696969696968686868686868687B +:104DB00066666666666666666A6A6A6A6A6A6A6A73 +:104DC0006868686868686868686868686868686863 +:104DD0006666666666666666666666666666666673 +:104DE0006666666666666666666666666666666663 +:104DF0006464646464646464646464646464646473 +:104E0000646464646464646465656565656565655A +:104E1000646464646464646465656565656565654A +:104E20006464646464646464646464646464646442 +:104E3000646464646464646465656565656565652A +:104E40006565656565656565656565656565656512 +:104E50007474747474747474747474747474747412 +:104E600077777777777777777474747474747474EA +:104E7000717171717171717172727272727272721A +:104E80007272727272727272707070707070707012 +:104E9000717171717171717170707070707070700A +:104EA00072727272727272727070707070707070F2 +:104EB0006E6E6E6E6E6E6E6E707070707070707002 +:104EC00071717171717171717070707070707070DA +:104ED0006F6F6F6F6F6F6F6F7272727272727272CA +:104EE00072727272727272727272727272727272A2 +:104EF0006D6D6D6D6D6D6D6D6F6F6F6F6F6F6F6FD2 +:104F000070707070707070706F6F6F6F6F6F6F6FA9 +:104F10006A6A6A6A6A6A6A6A6B6B6B6B6B6B6B6BE9 +:104F20006B6B6B6B6B6B6B6B6868686868686868E9 +:104F300067676767676767676868686868686868F9 +:104F400068686868686868686767676767676767E9 +:104F500065656565656565656767676767676767F1 +:104F600067676767676767676565656565656565E1 +:104F70008300800084007E007F007F007F007F0030 +:104F80007D007A007D0079007A0078007B00770050 +:104F90007B00780079007700780077007A00750050 +:104FA000760072007600720078007400780073005A +:104FB0007500710072007000740071007200710061 +:104FC00073006D0070006D0071006E006F006E0068 +:104FD0006F006B006E006C006B0068006900680079 +:104FE0006D0069006D006A006C006C006B006C0065 +:104FF0006900670067006700670068006800680074 +:105000006800660067006500680066006800670069 +:105010006500650067006700640066006600640064 +:105020005F006200620060005D006100600060007F +:105030005F0061005F005F005F006300610062006D +:105040005E005F005E005F005C005E005E005E0070 +:105050005C005D005D005E005C005D005C005C006B +:105060005A005B005C005B005700590059005A0071 +:1050700057005A0059005900550058005700590070 +:10508000540058005600580053005A00550058006C +:10509000530057005400570051005500520056006D +:1050A0005100560052005500510056005300560062 +:1050B00051005500520056004F0053004F0053005E +:1050C0004F0052004F0053004D0052004E0053005D +:1050D0004E0053004F0054004C0051004D00520050 +:1050E0004A004E004A004D0048004C0048004C0069 +:1050F00047004B0047004B004600490045004A006E +:10510000720075007A007F008000820087008E00A8 +:10511000B500A70097008A00750065007E009F001B +:1051200072007400790081007E00800085008E008E +:10513000AF00A30093008800740065007E00A0000B +:105140006E006E0072007700750076007B008100B3 +:10515000A30097008A007F006D0061007900950030 +:105160006C006B006F007700740076007A007F009F +:105170009E00910087007E006C006200790098001C +:1051800064006500680068006F006E0073007600C0 +:105190009C008C008200750067005E007700920022 +:1051A0006500660068006B006F006F00740075009A +:1051B00099008D008200730067005E007500930007 +:1051C0005B005F00620065006C006B0072007300A2 +:1051D0009E0092008200720063005B0073009200E8 +:1051E0005F006000640067006B006D007200730078 +:1051F0009C008E008100700062005B0073009300D1 +:10520000570056005C005A006000600067006700AD +:105210008E007F00780065005B0056006C008900FE +:10522000590058005D005B00620062006700670083 +:105230008E007F00760064005C0056006E008A00DD +:10524000510050005700550059005B00610061009B +:105250008A007A00710062005500520069008400E3 +:1052600053005000570057005C005B006100610074 +:1052700088007A0071006000560052006B008600C2 +:105280001A004D008000B300E6001A014D018001B4 +:10529000B301E6011A024D028002B302E6021A03CC +:1052A0004D038003B303E6031A044D048004B304E2 +:1052B000E6041A054D058005B305E6051A064D06F8 +:1052C0008006B306E6061A074D078007B307E60710 +:1052D0001A084D088008B308E6081A094D09800924 +:1052E000B309E609340032003400320034003400DF +:1052F0003200340032003400340032003400320016 +:105300003400340032003400320034003400320003 +:1053100034003200340034003200340032003400F3 +:1053200034003200340032003400340032003400E3 +:1053300032003400340032003400320034003400D3 +:10534000320034003200340019004B007D00AF0001 +:10535000E100130145017701A901DB010D023F02C4 +:105360007102A302D502070339036B039D03CF0328 +:105370000104330465049704C904FB042D055F058B +:105380009105C305F50527063200320032003200D0 +:10539000320032003200320032003200320032007D +:1053A000320032003200320032003200320032006D +:1053B000320032003200320032003200320032005D +:1053C00032003200320032000808090808090100E2 +:1053D000E8730300F8740200A00F03006880030064 +:1053E00010D8010050DE010090E40100D0EA010075 +:1053F000208E020060940200A09A0200E0A0020049 +:1054000010330300903F0300104C0300905803003A +:1054100000090B020F06040D070E0C050801030A14 +:1054200004050607F20A0B00BCC20C002B4C0E0050 +:10543000AF3009004C5E090030790D000A930F006F +:10544000C2E40D000DF50400433D0300D4B3010098 +:1054500050CF0600B3A10600CF860200F56C000015 +:105460003D1B02000DF50400F56C00004C5E0900C8 +:105470002B4C0E00000000000000000000000000A7 +:1054800000000000BCC20C00AF30090030790D00F4 +:10549000C2E40D0000000000000000000000000059 +:1054A00000000000D4B30100433D0300B3A1060097 +:1054B0003D1B02000A930F0030790D00F20A0B0029 +:1054C000AF3009000DF5040050CF0600F56C000068 +:1054D000CF8602004C5E0900C2E40D002B4C0E008A +:1054E000BCC20C003D1B0200B3A10600433D0300FB +:1054F000D4B30100AF300900F20A0B0030790D007F +:105500000A930F00CF860200F56C000050CF060012 +:105510000DF50400BCC20C002B4C0E00C2E40D00C3 +:105520004C5E0900F20A0B00BCC20C002B4C0E00B2 +:10553000AF3009004C5E090030790D000A930F006E +:10554000C2E40D000202020303030404000002008F +:1055500003000500070009000A000C000E001000FF +:10556000110013001500160018001A001C001D0081 +:105570001F002100220024002500270029002A0006 +:105580002C002D002F003000320034003500360092 +:10559000380039003B003C003E003F004000420024 +:1055A0004300440045004700480049004A004B00C2 +:1055B0004D004E004F005000510052005300540067 +:1055C0005500560057005700580059005A005B001C +:1055D0005B005C005D005D005E005F005F006000DE +:1055E00060006100610061006200620062006300AF +:1055F000630063006300640064006400640064008E +:1056000064000000640064006400640064006400DE +:105610006300630063006300620062006200610077 +:1056200061006100600060005F005F005E005D007F +:105630005D005C005B005B005A0059005800570099 +:1056400057005600550054005300520051005000BE +:105650004F004E004D004B004A00490048004700F3 +:10566000450044004300420040003F003E003C0033 +:105670003B0039003800360035003400320030007D +:105680002F002D002C002A002900270025002400CF +:10569000220021001F001D001C001A001800160027 +:1056A00015001300110010000E000C000A00090084 +:1056B00007000500030002000000000000000200D7 +:1056C00003000500070009000B000C000E0010008D +:1056D000120013001500170019001B001D001F0009 +:1056E000200022002400260028002A002D002F0080 +:1056F00031003300350037003A003C003E004100E5 +:105700004300460049004B004E0051005400570032 +:105710005A005D006100640068006B006F00730058 +:1057200077007B00800085008A008F0094009A003B +:10573000A000A600AD00B400BC00C400CD00D6009F +:10574000E100EC00F80005011301220134014701DA +:105750005D0175019101B101D601020237027702A4 +:10576000C8022E03B703770496057407300B611641 +:1057700010270000000001000400090010001900BB +:105780002400310040005100640079009000A9001D +:10579000C400E10000012101440169019001B90147 +:1057A000E401110240027102A402D902100349036C +:1057B0008403C103000441048404C904100559058D +:1057C000A405F10540069106E40639079007E907AC +:1057D0004408A10800096109C409290A900AF90AC4 +:1057E000640BD10B400CB10C240D990D100E890ED9 +:1057F000040F810F001081100411891110129912E9 +:105800002413B1134014D1146415F91590162917F7 +:10581000C41761180019A119441AE91A901B391C00 +:10582000E41C911D401EF11EA41F00006B006B00C4 +:105830006D00700071007100710000006B006B0062 +:105840006A00690068006800670000000000050049 +:105850000A001300190028003C00000000000000AE +:105860000038FAFE422EE63F3067C79357F32E3DCD +:10587000010000000000E0BF5B3051555555D53F99 +:105880009045EBFFFFFFCFBF1101F124B399C93F52 +:105890009FC806E57555C5BF000000000000E0BFC9 +:1058A000775555555555D53FCBFDFFFFFFFFCFBF72 +:1058B0000CDD95999999C93FA74567555555C5BFC1 +:1058C00030DE44A32449C23F653D42A4FFFFBFBF71 +:1058D000CAD62A288471BC3FFF68B043EB99B9BF90 +:1058E00085D0AFF78281B73FCD45D1751352B5BF93 +:1058F0009FDEE0C3F034F73F0090E6797FCCD7BF5E +:105900001FE92C6A7813F73F00000DC2EE6FD7BF76 +:10591000A0B5FA0860F2F63F00E05113E313D7BFD9 +:105920007D8C131FA6D1F63F007828385BB8D6BF10 +:10593000D1B4C50B49B1F63F00788090555DD6BF14 +:10594000BA0C2F334791F63F00001876D002D6BF2D +:10595000234222189F71F63F00909086CAA8D5BFB7 +:10596000D91EA5994F52F63F00500356434FD5BF5D +:10597000C4248FAA5633F63F00406BC337F6D4BF1A +:1059800014DC9D6BB314F63F0050A8FDA79DD4BF57 +:105990004C5CC65264F6F53F00A889399245D4BFE5 +:1059A0004F2C91B567D8F53F00B8B039F4EDD3BFAF +:1059B000DE905BCBBCBAF53F00708F44CE96D3BF70 +:1059C000781AD9F2619DF53F00A0BD171E40D3BFE4 +:1059D000875646125680F53F008046EFE2E9D2BF77 +:1059E000D36BE7CE9763F53F00E030381B94D2BF0E +:1059F000937FA7E22547F53F0088DA8CC53ED2BFEA +:105A000083450642FF2AF53F00902729E1E9D1BFEF +:105A1000DFBDB2DB220FF53F00F8482B6D95D1BFFB +:105A2000D7DE34478FF3F43F00F8B99A6741D1BF0E +:105A30004028DECF43D8F43F0098EF94D0EDD0BF9C +:105A4000C8A378C03EBDF43F0010DB18A59AD0BFB4 +:105A50008A25E0C37FA2F43F00B86352E647D0BF77 +:105A60003484D4240588F43F00F0864522EBCFBF70 +:105A70000B2D191BCE6DF43F00B017754A47CFBFF1 +:105A8000541839D3D953F43F0030103D44A4CEBF4D +:105A90005A84B444273AF43F00B0E9440D02CEBF23 +:105AA000FBF81541B520F43F00F07729A260CDBF87 +:105AB000B1F43EDA8207F43F0090950401C0CCBFF8 +:105AC0008FFE575D8FEEF33F001089562920CCBF23 +:105AD000E94C0BA0D9D5F33F0010818D1781CBBFC6 +:105AE0002BC110C060BDF33F00D0D3CCC9E2CABF08 +:105AF000B8DA752B24A5F33F0090122E4045CABF9B +:105B000002D09FCD228DF33F00F01D6877A8C9BF5A +:105B10001C7A84C55B75F33F003048696D0CC9BFC2 +:105B2000E236AD49CE5DF33F00C045A62071C8BF47 +:105B300040D44D987946F33F003014B48FD6C7BF98 +:105B400024CBFFCE5C2FF33F0070623CB83CC7BF54 +:105B5000490DA1757718F33F0060379B9AA3C6BF24 +:105B600090393E37C801F33F00A0B754310BC6BF90 +:105B700041F895BB4EEBF23F003024767D73C5BFF4 +:105B8000D1A919020AD5F23F0030C28F7BDCC4BF15 +:105B90002AFDB7A8F9BEF23F0000D2512C46C4BF7F +:105BA000AB1B0C7A1CA9F23F000083BC8AB0C3BFB8 +:105BB00030B514607293F23F0000496B991BC3BF6C +:105BC000F5A15757FA7DF23F0040A4905487C2BF19 +:105BD000BF3B1D9BB368F23F00A079F8B9F3C1BF8A +:105BE000BDF58F839D53F23F00A02C25C860C1BF37 +:105BF0003B08C9AAB73EF23F0020F7577FCEC0BF8F +:105C0000B640A92B012AF23F00A0FE49DC3CC0BFF0 +:105C10003241CC967915F23F00804BBCBD57BFBFD7 +:105C20009BFCD21D2001F23F004040960837BEBFCA +:105C30000B484D49F4ECF13F0040F93E9817BDBFC9 +:105C400069658F52F5D8F13F00A0D84E67F9BBBF08 +:105C50007C7E571123C5F13F00602F2079DCBABF4D +:105C6000E926CB747CB1F13F008028E7C3C0B9BFFF +:105C7000B61A2C0C019EF13F00C072B346A6B8BF05 +:105C8000BD70B67BB08AF13F0000ACB3018DB7BFE9 +:105C9000B6BCEF258A77F13F00003845F174B6BFF6 +:105CA000DA314C358D64F13F0080876D0E5EB5BFF3 +:105CB000DD5F2790B951F13F00E0A1DE5C48B4BF41 +:105CC0004CD232A40E3FF13F00A06A4DD933B3BF8E +:105CD000DAF910728B2CF13F0060C5F87920B2BF61 +:105CE00031B5EC28301AF13F00206298460EB1BF62 +:105CF000AF3484DAFB07F13F0000D26A6CFAAFBF21 +:105D0000B36B4E0FEEF5F03F0040774A8DDAADBF32 +:105D1000CE9F2A5D06E4F03F000085E4ECBCABBFFB +:105D200021A52C6344D2F03F00C0124089A1A9BF35 +:105D30001A98E27CA7C0F03F00C002335888A7BF82 +:105D4000D136C6832FAFF03F0080D6675E71A5BF06 +:105D50003913A098DB9DF03F008065498A5CA3BFA2 +:105D6000DFE752AFAB8CF03F00401564E349A1BFC1 +:105D7000FB284E2F9F7BF03F0080EB82C0729EBFBE +:105D8000198F358CB56AF03F00805252F1559ABF99 +:105D90002CF9ECA5EE59F03F008081CF623D96BF13 +:105DA000902CD1CD4949F03F0000AA8CFB2892BF2E +:105DB000A9ADF0C6C638F03F0000F9207B318CBF9A +:105DC000A93279136528F03F0000AA5D351984BF18 +:105DD0004873EA272418F03F0000ECC2031278BF92 +:105DE00095B114060408F03F00002479090460BF4F +:105DF0001AFA26F71FE0EF3F00009084F3EF6F3FA1 +:105E000074EA61C21CA1EF3F00003D3541DC873FD1 +:105E10002E9981B01063EF3F0080C2C4A3CE933FA0 +:105E2000CDADEE3CF625EF3F00008914C19F9B3FAE +:105E3000E7139103C8E9EE3F000011CED8B0A13FAF +:105E4000ABB1CB7880AEEE3F00C001D05B8AA53FFE +:105E50009B0C9DA21A74EE3F0080D840835CA93F42 +:105E6000B5990A83913AEE3F008057EF6A27AD3F1C +:105E7000569A6009E001EE3F00C098E59875B03F82 +:105E800098BB77E501CAED3F00200DE3F553B23F23 +:105E900003917C0BF292ED3F0000388BDD2EB43F76 +:105EA000CE5CFB66AC5CED3F00C057875906B63F41 +:105EB0009DDE5EAA2C27ED3F00006A3576DAB73FFB +:105EC000CD2C6B3E6EF2EC3F00601C4E43ABB93FF5 +:105ED0000279A7A26DBEEC3F00600DBBC778BB3F47 +:105EE0006D08376D268BEC3F0020E7321343BD3F32 +:105EF00004585DBD9458EC3F0060DE71310ABF3F2D +:105F00008C9FBB33B526EC3F0040912B1567C03FFB +:105F10003FE7ECEE83F5EB3F00B092828547C13F4F +:105F2000C196DB75FDC4EB3F0030CACD6E26C23F83 +:105F3000284A860C1E95EB3F0050C5A6D703C33FE9 +:105F40002C3EEFC5E265EB3F0010333CC3DFC33F9F +:105F50008B88C9674837EB3F00807A6B36BAC43FFD +:105F60004A301D214B09EB3F00F0D1283993C53F42 +:105F70007EEFF285E8DBEA3F00F01824CD6AC63FE9 +:105F8000A23D60311DAFEA3F009066ECF840C73F8C +:105F9000A758D33FE682EA3F00F01AF5C015C83F84 +:105FA0008B7309EF4057EA3F0080F65429E9C83F58 +:105FB000274BAB902A2CEA3F0040F80236BBC93F82 +:105FC000D1F29313A001EA3F00002C1CED8BCA3FD5 +:105FD0001B3CDB249FD7E93F00D0015C515BCB3FEA +:105FE00090B1C70525AEE93F00C0BCCC6729CC3FC6 +:105FF0002FCE97F22E85E93F006048D535F6CC3F8D +:10600000754BA4EEBA5CE93F00C04634BDC1CD3F3C +:106010003848E79DC634E93F00E0CFB8018CCE3F59 +:10602000E652672F4F0DE93F009017C00955CF3F4B +:106030009DD7FF8E52E6E83F00B81F126C0ED03F8E +:106040007C00CC9FCEBFE83F00D0930EB871D03F0C +:106050000EC3BEDAC099E83F0070869E6BD4D03F75 +:10606000FB1723AA2774E83F00D04B338736D13F74 +:10607000089AB3AC004FE83F004823670D98D13F22 +:10608000553E65E8492AE83F0080CCE0FFF8D13F63 +:106090006002F4950106E83F006863D75F59D23F7C +:1060A00029A3E06325E2E73F00A8140930B9D23FF5 +:1060B000ADB5DC77B3BEE73F006043107218D33F45 +:1060C000C2259767AA9BE73F0018EC6D2677D33F60 +:1060D000570617F20779E73F0030AFFB4FD5D33FA4 +:1060E0000C13D6DBCA56E73F00E02FE3EE32D43F75 +:1060F0006BB64F010010E63F3C5B42916C027E3C68 +:1061000095B44D030030E63F415D0048EABF8D3C49 +:1061100078D4940D0050E63FB7A5D686A77F8E3C75 +:10612000AD6F4E070070E63F4C25546BEAFC613CB6 +:10613000AE0FDFFEFF8FE63FFD0E594C277E7CBC85 +:10614000BCC5630700B0E63F01DADC4868C18ABC21 +:10615000F6C15C1E00D0E63F1193499D1C3F833C75 +:106160003EF605EBFFEFE63F532DE21A04807EBCBE +:106170008097860E0010E73F5279097166FF7B3CDD +:1061800012E967FCFF2FE73F2487BD26E2008C3C25 +:106190006A1181DFFF4FE73FD201F16E91026EBCC1 +:1061A000909C670F0070E73F749C54CD71FC67BCF6 +:1061B00035C87EFAFF8FE73F8304F59EC1BE813C60 +:1061C000E6C220FEFFAFE73F6564CC29177E70BCB6 +:1061D00000C93FEDFFCFE73F1C8B7B08728080BC7E +:1061E000761A26E9FFEFE73FAEF99D6D28C08D3C9A +:1061F000E8A39C040010E83F334CE551D27F893C72 +:106200008F2C93170030E83F81F330B6E9FE8ABC4B +:106210009C7333060050E83FBC35656BBFBF893CBB +:10622000C68942200070E83F757B11F365BF8BBCC7 +:106230000479F5EBFF8FE83F57CB3DA26E0089BC98 +:10624000DF04BC2200B0E83F0A4BE038DF007DBC31 +:106250008A1B0CE5FFCFE83F059FFF46710088BC15 +:10626000438E91FCFFEFE83F38707AD07B81833C0E +:10627000C75FFA1E0010E93F03B4DF76913E893C08 +:10628000B97B46130030E93F7602984B4E807F3C45 +:106290006F07EEE6FF4FE93F2E62FFD9F07E8FBC1D +:1062A000D1123CDEFF6FE93FBA382696AA8270BC55 +:1062B0000D8A45F4FF8FE93FEFA864911B8087BCEE +:1062C0003E2E98DDFFAFE93F37935A8AE04087BC06 +:1062D00066FB49EDFFCFE93F00E09BC108CE3F3CA4 +:1062E000519CF12000F0E93F0A5B8827AA3F8ABC55 +:1062F00006B045110010EA3F56DA589948FF743C41 +:10630000FAF6BB070030EA3F186D2B8AABBE8C3C17 +:10631000791D97100050EA3F307978DDCAFE883C3D +:10632000482EF51D0070EA3FDBABD83D76418FBCAF +:106330005233591C0090EA3F1276C28402BF8EBCD1 +:106340004B3E4F2A00B0EA3F5F3FFF3C04FD69BC73 +:10635000D11EAED7FFCFEA3FB4709012E73E82BCA9 +:10636000780451EEFFEFEA3FA3DE0EE03E066A3C02 +:106370005B0D65DBFF0FEB3FB90A1F38C8065A3CBF +:1063800057CAAAFEFF2FEB3F1D3C23741E0179BCA8 +:10639000DCBA95D9FF4FEB3F9F2A866810FF79BC86 +:1063A0009C659E240070EB3F3E4F86D045FF8A3CA3 +:1063B000401687F9FF8FEB3FF9C3C29677FE7C3C0E +:1063C0004FCB04D2FFAFEB3FC42BF2EE27FF63BCF1 +:1063D000455C41D2FFCFEB3F21EA3BEEB7FF6CBCFF +:1063E000DF0963F8FFEFEB3F5C0B2E97034181BCA5 +:1063F0005376B5E1FF0FEC3F196AB79464C18B3C4B +:10640000E357FAF1FF2FEC3FEDC6308DEFFE64BC91 +:1064100024E4BFDCFF4FEC3F7547ECBC683F84BC15 +:10642000F7B954EDFF6FEC3FECE053F0A37E843CF2 +:10643000D58F99EBFF8FEC3FF192F98D0683733C7A +:106440009A21252100B0EC3F040E18648EFD68BC33 +:106450009C4694DDFFCFEC3F72EAC71CBE7E8E3CAB +:1064600076C4FDEAFFEFEC3FFE889FAD39BE8E3C5F +:106470002BF89A160010ED3F715AB9A8917D753C22 +:106480001DF70F0D0030ED3FDAC7706990C1893CF0 +:10649000C40F79EAFF4FED3F0CFE58C5370E58BCCC +:1064A000E587DC2E0070ED3F440FC14DD6807FBCE8 +:1064B000AA82DC210090ED3F5C5CFD948F7C74BC73 +:1064C00083026BD8FFAFED3F7E6121C51D7F8C3C01 +:1064D00039476C2900D0ED3F53B1FFB29E01883C93 +:1064E000F59044E5FFEFED3F89CC52C6D2006E3CFB +:1064F00094F6ABCDFF0FEE3FD2692D2040837FBCD9 +:10650000DDC852DBFF2FEE3F64081BCAC1007B3C95 +:10651000EF1642F2FF4FEE3F51AB94B0A8FF723C32 +:10652000115E8AE8FF6FEE3F59BEEFB173F657BCBC +:106530000DFF9E110090EE3F01C80B5E8D8084BC64 +:106540004417A5DFFFAFEE3FB52043D50600783CEA +:10655000A17F121A00D0EE3F925C5660F80250BC48 +:10656000C4BCBA0700F0EE3F11E6355D444085BC7F +:10657000028D7AF5FF0FEF3F0591EF3931FB4FBCEC +:10658000C78AE51E0030EF3F551173F2AC818A3C9B +:10659000943482F5FF4FEF3F43C7D7D4413F8A3C45 +:1065A0006B4CA9FCFF6FEF3F7578981CF40262BC3E +:1065B00041C4F9E1FF8FEF3F4BE777F4D17D773CA2 +:1065C0007EE3E0D2FFAFEF3F31A37C9A19016FBCAD +:1065D0009EE4771C00D0EF3FB1ACCE4BEE81713C16 +:1065E00031C3E0F7FFEFEF3F5A87700137056EBC0C +:1065F0006E6065F4FF0FF03FDA0A1C49AD7E8ABC7D +:10660000587A86F3FF2FF03FE0B2FCC3697F97BC56 +:10661000170DFCFDFF4FF03F5B94CB34FEBF973C62 +:10662000824DCD030070F03FCB56E4C08300823C26 +:10663000E8CBF2F9FF8FF03F1A7537BEDFFF6DBC74 +:1066400065DA0C0100B0F03FEB26E6AE7F3F91BC6F +:1066500038D3A40100D0F03FF79F4879FA7D803C01 +:10666000FDFDDAFAFFEFF03FC06BD670050477BC92 +:1066700096FDBA0B0010F13F620B6D84D4808E3C06 +:106680005DF4E5FAFF2FF13FEF36FD64FABF9D3C64 +:10669000D99AD50D0050F13FAE50127077009A3C58 +:1066A0009A55210F0070F13FEEDEE3E2F9FD8D3CDB +:1066B000265427FCFF8FF13F73723BDC3000913C86 +:1066C000593C3D1200B0F13F88010380797F993C2D +:1066D000B79E29F8FFCFF13F678C9FAB32F965BCBD +:1066E00000D48AF4FFEFF13FEB5BA79DBF7F933CA3 +:1066F000A4868B0C0010F23F225BFD916B809F3CC7 +:10670000034385030030F23F33BF9FEBC2FF933C4E +:1067100084F6BCFFFF4FF23F722E2E7EE701763CDF +:10672000D92129F5FF6FF23F610C7F76BBFC7F3CDE +:106730003C3A93140090F23F2B41023CCA0272BCD7 +:106740001363551400B0F23F021FF233828092BCF3 +:106750003B52FEEBFFCFF23FF2DC4F387EFF88BCAE +:1067600096ADB80B00F0F23FC541305051FF85BCEB +:10677000AFE27AFBFF0FF33F9D285E88710081BC7A +:106780007F5FACFEFF2FF33F15B7B73F5DFF91BCB6 +:106790005667A60C0050F33FBD828B22827F953C4A +:1067A00021F7FB110070F33FCCD50DC4BA00803C3B +:1067B000B92F59F9FF8FF33F51A7B22D9D3F94BCDC +:1067C00042D2DD0400B0F33FE13876706B7F853C48 +:1067D00057C9B2F5FFCFF33F3112BF103A027A3CEE +:1067E00018B4B0EAFFEFF33FB052B1666D7F983C4A +:1067F000F4AF32150010F43F2485195F37F8673C79 +:10680000298B47170030F43F4351DC72E601833C8B +:1068100063B495E7FF4FF43F5A89B2B869FF893CEA +:10682000E07504E8FF6FF43F54F2C29BB1C095BC21 +:10683000E7C16FEFFF8FF43F722A3AF209409B3CA9 +:1068400004A7BEE5FFAFF43F457D0DBFB7FF94BC85 +:10685000DE27101700D0F43F3D6ADC7164C099BC9C +:10686000E23EF00F00F0F43F1C53850B897F973C0C +:10687000D14BDC120010F53F36A466716504603C14 +:106880007A2705160030F53F093223CECEBF96BCDD +:106890004C70DBECFF4FF53FD7A10505720289BCB8 +:1068A000A9545FEFFF6FF53F1264C90EE6BF9B3C32 +:1068B0001210E6170090F53F90EFAF81C57E883C3F +:1068C000923EC90300B0F53FC00CBF0A08419FBC0F +:1068D000BC19491D00D0F53F294725FB2A8198BCEA +:1068E000897AB8E7FFEFF53F0469ED80B77E94BC85 +:1068F0000000000000000000000000000000000098 +:106900000000000000000000000000000000000087 +:106910000000000000000000000000000000000077 +:106920000000000000000000000000000000000067 +:106930000000000000000000000000000000000057 +:106940000000000000000000000000000000000047 +:106950000000000000000000000000000000000037 +:106960000000000000000000000000000000000027 +:106970000000000000000000000000000000000017 +:106980000000000000000000000000000000000007 +:1069900000000000000000000000000000000000F7 +:1069A00000000000000000000000000000000000E7 +:1069B00000000000000000000000000000000000D7 +:1069C00000000000000000000000000000000000C7 +:1069D00000000000000000000000000000000000B7 +:1069E00000000000000000000000000000000000A7 +:1069F0000000000000000000000000000000000097 +:106A00000000000000000000000000000000000086 +:106A10000000000000000000000000000000000076 +:106A20000000000000000000000000000000000066 +:106A30000000000000000000000000000000000056 +:106A40000000000000000000000000000000000046 +:106A50000000000000000000000000000000000036 +:106A60000000000000000000000000000000000026 +:106A70000000000000000000000000000000000016 +:106A80000000000000000000000000000000000006 +:106A900000000000000000000000000000000000F6 +:106AA00000000000000000000000000000000000E6 +:106AB00000000000000000000000000000000000D6 +:106AC00000000000000000000000000000000000C6 +:106AD00000000000000000000000000000000000B6 +:106AE00000000000000000000000000000000000A6 +:106AF0000000000000000000000000000000000096 +:106B00000000000000000000000000000000000085 +:106B10000000000000000000000000000000000075 +:106B20000000000000000000000000000000000065 +:106B30000000000000000000000000000000000055 +:106B40000000000000000000000000000000000045 +:106B50000000000000000000000000000000000035 +:106B60000000000000000000000000000000000025 +:106B70000000000000000000000000000000000015 +:106B80000000000000000000000000000000000005 +:106B900000000000000000000000000000000000F5 +:106BA00000000000000000000000000000000000E5 +:106BB00000000000000000000000000000000000D5 +:106BC00000000000000000000000000000000000C5 +:106BD00000000000000000000000000000000000B5 +:106BE00000000000000000000000000000000000A5 +:106BF0000000000000000000000000000000000095 +:106C00000000000000000000000000000000000084 +:106C10000000000000000000000000000000000074 +:106C20000000000000000000000000000000000064 +:106C30000000000000000000000000000000000054 +:106C40000000000000000000000000000000000044 +:106C50000000000000000000000000000000000034 +:106C60000000000000000000000000000000000024 +:106C70000000000000000000000000000000000014 +:106C80000000000000000000000000000000000004 +:106C900000000000000000000000000000000000F4 +:106CA00000000000000000000000000000000000E4 +:106CB00000000000000000000000000000000000D4 +:106CC00000000000000000000000000000000000C4 +:106CD00000000000000000000000000000000000B4 +:106CE00000000000000000000000000000000000A4 +:106CF0000000000000000000000000000000000094 +:106D00000000000000000000000000000000000083 +:106D10000000000000000000000000000000000073 +:106D20000000000000000000000000000000000063 +:106D30000000000000000000000000000000000053 +:106D40000000000000000000000000000000000043 +:106D50000000000000000000000000000000000033 +:106D60000000000000000000000000000000000023 +:106D70000000000000000000000000000000000013 +:106D80000000000000000000000000000000000003 +:106D900000000000000000000000000000000000F3 +:106DA00000000000000000000000000000000000E3 +:106DB00000000000000000000000000000000000D3 +:106DC00000000000000000000000000000000000C3 +:106DD00000000000000000000000000000000000B3 +:106DE00000000000000000000000000000000000A3 +:106DF0000000000000000000000000000000000093 +:106E00000000000000000000000000000000000082 +:106E10000000000000000000000000000000000072 +:106E20000000000000000000000000000000000062 +:106E30000000000000000000000000000000000052 +:106E40000000000000000000000000000000000042 +:106E50000000000000000000000000000000000032 +:106E60000000000000000000000000000000000022 +:106E70000000000000000000000000000000000012 +:106E80000000000000000000000000000000000002 +:106E900000000000000000000000000000000000F2 +:106EA00000000000000000000000000000000000E2 +:106EB00000000000000000000000000000000000D2 +:106EC00000000000000000000000000000000000C2 +:106ED00000000000000000000000000000000000B2 +:106EE00000000000000000000000000000000000A2 +:106EF0000000000000000000000000000000000092 +:106F00000000000000000000000000000000000081 +:106F10000000000000000000000000000000000071 +:106F20000000000000000000000000000000000061 +:106F30000000000000000000000000000000000051 +:106F40000000000000000000000000000000000041 +:106F50000000000000000000000000000000000031 +:106F60000000000000000000000000000000000021 +:106F70000000000000000000000000000000000011 +:106F80000000000000000000000000000000000001 +:106F900000000000000000000000000000000000F1 +:106FA00000000000000000000000000000000000E1 +:106FB00000000000000000000000000000000000D1 +:106FC00000000000000000000000000000000000C1 +:106FD00000000000000000000000000000000000B1 +:106FE00000000000000000000000000000000000A1 +:106FF0000000000000000000000000000000000091 +:107000000000000000000000000000000000000080 +:107010000000000000000000000000000000000070 +:107020000000000000000000000000000000000060 +:107030000000000000000000000000000000000050 +:107040000000000000000000000000000000000040 +:107050000000000000000000000000000000000030 +:107060000000000000000000000000000000000020 +:107070000000000000000000000000000000000010 +:107080000000000000000000000000000000000000 +:1070900000000000000000000000000000000000F0 +:1070A00000000000000000000000000000000000E0 +:1070B00000000000000000000000000000000000D0 +:1070C00000000000000000000000000000000000C0 +:1070D00000000000000000000000000000000000B0 +:1070E00000000000000000000000000000000000A0 +:1070F0000000000000000000000000000000000090 +:10710000000000000000000000000000000000007F +:10711000000000000000000000000000000000006F +:10712000000000000000000000000000000000005F +:10713000000000000000000000000000000000004F +:10714000000000000000000000000000000000003F +:10715000000000000000000000000000000000002F +:10716000000000000000000000000000000000001F +:10717000000000000000000000000000000000000F +:1071800000000000000000000000000000000000FF +:1071900000000000000000000000000000000000EF +:1071A00000000000000000000000000000000000DF +:1071B00000000000000000000000000000000000CF +:1071C00000000000000000000000000000000000BF +:1071D00000000000000000000000000000000000AF +:1071E000000000000000000000000000000000009F +:1071F000000000000000000000000000000000008F +:10720000000000000000000000000000000000007E +:10721000000000000000000000000000000000006E +:10722000000000000000000000000000000000005E +:10723000000000000000000000000000000000004E +:10724000000000000000000000000000000000003E +:10725000000000000000000000000000000000002E +:10726000000000000000000000000000000000001E +:10727000000000000000000000000000000000000E +:1072800000000000000000000000000000000000FE +:1072900000000000000000000000000000000000EE +:1072A00000000000000000000000000000000000DE +:1072B00000000000000000000000000000000000CE +:1072C00000000000000000000000000000000000BE +:1072D00000000000000000000000000000000000AE +:1072E000000000000000000000000000000000009E +:1072F000000000000000000000000000000000008E +:10730000000000000000000000000000000000007D +:10731000000000000000000000000000000000006D +:10732000000000000000000000000000000000005D +:10733000000000000000000000000000000000004D +:10734000000000000000000000000000000000003D +:10735000000000000000000000000000000000002D +:10736000000000000000000000000000000000001D +:10737000000000000000000000000000000000000D +:1073800000000000000000000000000000000000FD +:1073900000000000000000000000000000000000ED +:1073A00000000000000000000000000000000000DD +:1073B00000000000000000000000000000000000CD +:1073C00000000000000000000000000000000000BD +:1073D00000000000000000000000000000000000AD +:1073E000000000000000000000000000000000009D +:1073F000000000000000000000000000000000008D +:10740000000000000000000000000000000000007C +:10741000000000000000000000000000000000006C +:10742000000000000000000000000000000000005C +:10743000000000000000000000000000000000004C +:10744000000000000000000000000000000000003C +:10745000000000000000000000000000000000002C +:10746000000000000000000000000000000000001C +:10747000000000000000000000000000000000000C +:1074800000000000000000000000000000000000FC +:1074900000000000000000000000000000000000EC +:1074A00000000000000000000000000000000000DC +:1074B00000000000000000000000000000000000CC +:1074C00000000000000000000000000000000000BC +:1074D00000000000000000000000000000000000AC +:1074E000000000000000000000000000000000009C +:1074F000000000000000000000000000000000008C +:10750000000000000000000000000000000000007B +:10751000000000000000000000000000000000006B +:10752000000000000000000000000000000000005B +:10753000000000000000000000000000000000004B +:10754000000000000000000000000000000000003B +:10755000000000000000000000000000000000002B +:10756000000000000000000000000000000000001B +:10757000000000000000000000000000000000000B +:1075800000000000000000000000000000000000FB +:1075900000000000000000000000000000000000EB +:1075A00000000000000000000000000000000000DB +:1075B00000000000000000000000000000000000CB +:1075C00000000000000000000000000000000000BB +:1075D00000000000000000000000000000000000AB +:1075E000000000000000000000000000000000009B +:1075F000000000000000000000000000000000008B +:10760000000000000000000000000000000000007A +:10761000000000000000000000000000000000006A +:10762000000000000000000000000000000000005A +:10763000000000000000000000000000000000004A +:10764000000000000000000000000000000000003A +:10765000000000000000000000000000000000002A +:10766000000000000000000000000000000000001A +:10767000000000000000000000000000000000000A +:1076800000000000000000000000000000000000FA +:1076900000000000000000000000000000000000EA +:1076A00000000000000000000000000000000000DA +:1076B00000000000000000000000000000000000CA +:1076C00000000000000000000000000000000000BA +:1076D00000000000000000000000000000000000AA +:1076E000000000000000000000000000000000009A +:1076F000000000000000000000000000000000008A +:107700000000000000000000000000000000000079 +:107710000000000000000000000000000000000069 +:107720000000000000000000000000000000000059 +:107730000000000000000000000000000000000049 +:107740000000000000000000000000000000000039 +:107750000000000000000000000000000000000029 +:107760000000000000000000000000000000000019 +:107770000000000000000000000000000000000009 +:1077800000000000000000000000000000000000F9 +:1077900000000000000000000000000000000000E9 +:1077A00000000000000000000000000000000000D9 +:1077B00000000000000000000000000000000000C9 +:1077C00000000000000000000000000000000000B9 +:1077D00000000000000000000000000000000000A9 +:1077E0000000000000000000000000000000000099 +:1077F0000000000000000000000000000000000089 +:107800000000000000000000000000000000000078 +:107810000000000000000000000000000000000068 +:107820000000000000000000000000000000000058 +:107830000000000000000000000000000000000048 +:107840000000000000000000000000000000000038 +:107850000000000000000000000000000000000028 +:107860000000000000000000000000000000000018 +:107870000000000000000000000000000000000008 +:1078800000000000000000000000000000000000F8 +:1078900000000000000000000000000000000000E8 +:1078A00000000000000000000000000000000000D8 +:1078B00000000000000000000000000000000000C8 +:1078C00000000000000000000000000000000000B8 +:1078D00000000000000000000000000000000000A8 +:1078E0000000000000000000000000000000000098 +:1078F0000000000000000000000000000000000088 +:107900000000000000000000000000000000000077 +:107910000000000000000000000000000000000067 +:107920000000000000000000000000000000000057 +:107930000000000000000000000000000000000047 +:107940000000000000000000000000000000000037 +:107950000000000000000000000000000000000027 +:107960000000000000000000000000000000000017 +:107970000000000000000000000000000000000007 +:1079800000000000000000000000000000000000F7 +:1079900000000000000000000000000000000000E7 +:1079A00000000000000000000000000000000000D7 +:1079B00000000000000000000000000000000000C7 +:1079C00000000000000000000000000000000000B7 +:1079D00000000000000000000000000000000000A7 +:1079E0000000000000000000000000000000000097 +:1079F0000000000000000000000000000000000087 +:107A00000000000000000000000000000000000076 +:107A10000000000000000000000000000000000066 +:107A20000000000000000000000000000000000056 +:107A30000000000000000000000000000000000046 +:107A40000000000000000000000000000000000036 +:107A50000000000000000000000000000000000026 +:107A60000000000000000000000000000000000016 +:107A70000000000000000000000000000000000006 +:107A800000000000000000000000000000000000F6 +:107A900000000000000000000000000000000000E6 +:107AA00000000000000000000000000000000000D6 +:107AB00000000000000000000000000000000000C6 +:107AC00000000000000000000000000000000000B6 +:107AD00000000000000000000000000000000000A6 +:107AE0000000000000000000000000000000000096 +:107AF0000000000000000000000000000000000086 +:107B00000000000000000000000000000000000075 +:107B10000000000000000000000000000000000065 +:107B20000000000000000000000000000000000055 +:107B30000000000000000000000000000000000045 +:107B40000000000000000000000000000000000035 +:107B50000000000000000000000000000000000025 +:107B60000000000000000000000000000000000015 +:107B70000000000000000000000000000000000005 +:107B800000000000000000000000000000000000F5 +:107B900000000000000000000000000000000000E5 +:107BA00000000000000000000000000000000000D5 +:107BB00000000000000000000000000000000000C5 +:107BC00000000000000000000000000000000000B5 +:107BD00000000000000000000000000000000000A5 +:107BE0000000000000000000000000000000000095 +:107BF0000000000000000000000000000000000085 +:107C00000000000000000000000000000000000074 +:107C10000000000000000000000000000000000064 +:107C20000000000000000000000000000000000054 +:107C30000000000000000000000000000000000044 +:107C40000000000000000000000000000000000034 +:107C50000000000000000000000000000000000024 +:107C60000000000000000000000000000000000014 +:107C70000000000000000000000000000000000004 +:107C800000000000000000000000000000000000F4 +:107C900000000000000000000000000000000000E4 +:107CA00000000000000000000000000000000000D4 +:107CB00000000000000000000000000000000000C4 +:107CC00000000000000000000000000000000000B4 +:107CD00000000000000000000000000000000000A4 +:107CE0000000000000000000000000000000000094 +:107CF0000000000000000000000000000000000084 +:107D00000000000000000000000000000000000073 +:107D10000000000000000000000000000000000063 +:107D20000000000000000000000000000000000053 +:107D30000000000000000000000000000000000043 +:107D40000000000000000000000000000000000033 +:107D50000000000000000000000000000000000023 +:107D60000000000000000000000000000000000013 +:107D70000000000000000000000000000000000003 +:107D800000000000000000000000000000000000F3 +:107D900000000000000000000000000000000000E3 +:107DA00000000000000000000000000000000000D3 +:107DB00000000000000000000000000000000000C3 +:107DC00000000000000000000000000000000000B3 +:107DD00000000000000000000000000000000000A3 +:107DE0000000000000000000000000000000000093 +:107DF0000000000000000000000000000000000083 +:107E00000000000000000000000000000000000072 +:107E10000000000000000000000000000000000062 +:107E20000000000000000000000000000000000052 +:107E30000000000000000000000000000000000042 +:107E40000000000000000000000000000000000032 +:107E50000000000000000000000000000000000022 +:107E60000000000000000000000000000000000012 +:107E70000000000000000000000000000000000002 +:107E800000000000000000000000000000000000F2 +:107E900000000000000000000000000000000000E2 +:107EA00000000000000000000000000000000000D2 +:107EB00000000000000000000000000000000000C2 +:107EC00000000000000000000000000000000000B2 +:107ED00000000000000000000000000000000000A2 +:107EE0000000000000000000000000000000000092 +:107EF0000000000000000000000000000000000082 +:107F00000000000000000000000000000000000071 +:107F10000000000000000000000000000000000061 +:107F20000000000000000000000000000000000051 +:107F30000000000000000000000000000000000041 +:107F40000000000000000000000000000000000031 +:107F50000000000000000000000000000000000021 +:107F60000000000000000000000000000000000011 +:107F70000000000000000000000000000000000001 +:107F800000000000000000000000000000000000F1 +:107F900000000000000000000000000000000000E1 +:107FA00000000000000000000000000000000000D1 +:107FB00000000000000000000000000000000000C1 +:107FC00000000000000000000000000000000000B1 +:107FD00000000000000000000000000000000000A1 +:107FE0000000000000000000000000000000000091 +:107FF0000000000000000000000000000000000081 +:108000000000000000000000000000000000000070 +:108010000000000000000000000000000000000060 +:108020000000000000000000000000000000000050 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:1080800000000000000000000000000000000000F0 +:1080900000000000000000000000000000000000E0 +:1080A00000000000000000000000000000000000D0 +:1080B00000000000000000000000000000000000C0 +:1080C00000000000000000000000000000000000B0 +:1080D00000000000000000000000000000000000A0 +:1080E0000000000000000000000000000000000090 +:1080F0000000000000000000000000000000000080 +:10810000000000000000000000000000000000006F +:10811000000000000000000000000000000000005F +:10812000000000000000000000000000000000004F +:10813000000000000000000000000000000000003F +:10814000000000000000000000000000000000002F +:10815000000000000000000000000000000000001F +:10816000000000000000000000000000000000000F +:1081700000000000000000000000000000000000FF +:1081800000000000000000000000000000000000EF +:1081900000000000000000000000000000000000DF +:1081A00000000000000000000000000000000000CF +:1081B00000000000000000000000000000000000BF +:1081C00000000000000000000000000000000000AF +:1081D000000000000000000000000000000000009F +:1081E000000000000000000000000000000000008F +:1081F000000000000000000000000000000000007F +:10820000000000000000000000000000000000006E +:10821000000000000000000000000000000000005E +:10822000000000000000000000000000000000004E +:10823000000000000000000000000000000000003E +:10824000000000000000000000000000000000002E +:10825000000000000000000000000000000000001E +:10826000000000000000000000000000000000000E +:1082700000000000000000000000000000000000FE +:1082800000000000000000000000000000000000EE +:1082900000000000000000000000000000000000DE +:1082A00000000000000000000000000000000000CE +:1082B00000000000000000000000000000000000BE +:1082C00000000000000000000000000000000000AE +:1082D000000000000000000000000000000000009E +:1082E000000000000000000000000000000000008E +:1082F000000000000000000000000000000000007E +:10830000000000000000000000000000000000006D +:10831000000000000000000000000000000000005D +:10832000000000000000000000000000000000004D +:10833000000000000000000000000000000000003D +:10834000000000000000000000000000000000002D +:10835000000000000000000000000000000000001D +:10836000000000000000000000000000000000000D +:1083700000000000000000000000000000000000FD +:1083800000000000000000000000000000000000ED +:1083900000000000000000000000000000000000DD +:1083A00000000000000000000000000000000000CD +:1083B00000000000000000000000000000000000BD +:1083C00000000000000000000000000000000000AD +:1083D000000000000000000000000000000000009D +:1083E000000000000000000000000000000000008D +:1083F000000000000000000000000000000000007D +:10840000000000000000000000000000000000006C +:10841000000000000000000000000000000000005C +:10842000000000000000000000000000000000004C +:10843000000000000000000000000000000000003C +:10844000000000000000000000000000000000002C +:10845000000000000000000000000000000000001C +:10846000000000000000000000000000000000000C +:1084700000000000000000000000000000000000FC +:1084800000000000000000000000000000000000EC +:1084900000000000000000000000000000000000DC +:1084A00000000000000000000000000000000000CC +:1084B00000000000000000000000000000000000BC +:1084C00000000000000000000000000000000000AC +:1084D000000000000000000000000000000000009C +:1084E000000000000000000000000000000000008C +:1084F000000000000000000000000000000000007C +:10850000000000000000000000000000000000006B +:10851000000000000000000000000000000000005B +:10852000000000000000000000000000000000004B +:10853000000000000000000000000000000000003B +:10854000000000000000000000000000000000002B +:10855000000000000000000000000000000000001B +:10856000000000000000000000000000000000000B +:1085700000000000000000000000000000000000FB +:1085800000000000000000000000000000000000EB +:1085900000000000000000000000000000000000DB +:1085A00000000000000000000000000000000000CB +:1085B00000000000000000000000000000000000BB +:1085C00000000000000000000000000000000000AB +:1085D000000000000000000000000000000000009B +:1085E000000000000000000000000000000000008B +:1085F000000000000000000000000000000000007B +:10860000000000000000000000000000000000006A +:10861000000000000000000000000000000000005A +:10862000000000000000000000000000000000004A +:10863000000000000000000000000000000000003A +:10864000000000000000000000000000000000002A +:10865000000000000000000000000000000000001A +:10866000000000000000000000000000000000000A +:1086700000000000000000000000000000000000FA +:1086800000000000000000000000000000000000EA +:1086900000000000000000000000000000000000DA +:1086A00000000000000000000000000000000000CA +:1086B00000000000000000000000000000000000BA +:1086C00000000000000000000000000000000000AA +:1086D000000000000000000000000000000000009A +:1086E000000000000000000000000000000000008A +:1086F000000000000000000000000000000000007A +:108700000000000000000000000000000000000069 +:108710000000000000000000000000000000000059 +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:108740000000000000000000000000000000000029 +:108750000000000000000000000000000000000019 +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800000000000000000000000000000000000E9 +:1087900000000000000000000000000000000000D9 +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00000000000000000000000000000000000A9 +:1087D0000000000000000000000000000000000099 +:1087E0000000000000000000000000000000000089 +:1087F0000000000000000000000000000000000079 +:108800000000000000000000000000000000000068 +:108810000000000000000000000000000000000058 +:108820000000000000000000000000000000000048 +:108830000000000000000000000000000000000038 +:108840000000000000000000000000000000000028 +:108850000000000000000000000000000000000018 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800000000000000000000000000000000000E8 +:1088900000000000000000000000000000000000D8 +:1088A00000000000000000000000000000000000C8 +:1088B00000000000000000000000000000000000B8 +:1088C00000000000000000000000000000000000A8 +:1088D0000000000000000000000000000000000098 +:1088E0000000000000000000000000000000000088 +:1088F0000000000000000000000000000000000078 +:108900000000000000000000000000000000000067 +:108910000000000000000000000000000000000057 +:108920000000000000000000000000000000000047 +:108930000000000000000000000000000000000037 +:108940000000000000000000000000000000000027 +:108950000000000000000000000000000000000017 +:108960000000000000000000000000000000000007 +:1089700000000000000000000000000000000000F7 +:1089800000000000000000000000000000000000E7 +:1089900000000000000000000000000000000000D7 +:1089A00000000000000000000000000000000000C7 +:1089B00000000000000000000000000000000000B7 +:1089C00000000000000000000000000000000000A7 +:1089D0000000000000000000000000000000000097 +:1089E0000000000000000000000000000000000087 +:1089F0000000000000000000000000000000000077 +:108A00000000000000000000000000000000000066 +:108A10000000000000000000000000000000000056 +:108A20000000000000000000000000000000000046 +:108A30000000000000000000000000000000000036 +:108A40000000000000000000000000000000000026 +:108A50000000000000000000000000000000000016 +:108A60000000000000000000000000000000000006 +:108A700000000000000000000000000000000000F6 +:108A800000000000000000000000000000000000E6 +:108A900000000000000000000000000000000000D6 +:108AA00000000000000000000000000000000000C6 +:108AB00000000000000000000000000000000000B6 +:108AC00000000000000000000000000000000000A6 +:108AD0000000000000000000000000000000000096 +:108AE0000000000000000000000000000000000086 +:108AF0000000000000000000000000000000000076 +:108B00000000000000000000000000000000000065 +:108B10000000000000000000000000000000000055 +:108B20000000000000000000000000000000000045 +:108B30000000000000000000000000000000000035 +:108B40000000000000000000000000000000000025 +:108B50000000000000000000000000000000000015 +:108B60000000000000000000000000000000000005 +:108B700000000000000000000000000000000000F5 +:108B800000000000000000000000000000000000E5 +:108B900000000000000000000000000000000000D5 +:108BA00000000000000000000000000000000000C5 +:108BB00000000000000000000000000000000000B5 +:108BC00000000000000000000000000000000000A5 +:108BD0000000000000000000000000000000000095 +:108BE0000000000000000000000000000000000085 +:108BF0000000000000000000000000000000000075 +:108C00000000000000000000000000000000000064 +:108C10000000000000000000000000000000000054 +:108C20000000000000000000000000000000000044 +:108C30000000000000000000000000000000000034 +:108C40000000000000000000000000000000000024 +:108C50000000000000000000000000000000000014 +:108C60000000000000000000000000000000000004 +:108C700000000000000000000000000000000000F4 +:108C800000000000000000000000000000000000E4 +:108C900000000000000000000000000000000000D4 +:108CA00000000000000000000000000000000000C4 +:108CB00000000000000000000000000000000000B4 +:108CC00000000000000000000000000000000000A4 +:108CD0000000000000000000000000000000000094 +:108CE0000000000000000000000000000000000084 +:108CF0000000000000000000000000000000000074 +:108D00000000000000000000000000000000000063 +:108D10000000000000000000000000000000000053 +:108D20000000000000000000000000000000000043 +:108D30000000000000000000000000000000000033 +:108D40000000000000000000000000000000000023 +:108D50000000000000000000000000000000000013 +:108D60000000000000000000000000000000000003 +:108D700000000000000000000000000000000000F3 +:108D800000000000000000000000000000000000E3 +:108D900000000000000000000000000000000000D3 +:108DA00000000000000000000000000000000000C3 +:108DB00000000000000000000000000000000000B3 +:108DC00000000000000000000000000000000000A3 +:108DD0000000000000000000000000000000000093 +:108DE0000000000000000000000000000000000083 +:108DF0000000000000000000000000000000000073 +:108E00000000000000000000000000000000000062 +:108E10000000000000000000000000000000000052 +:108E20000000000000000000000000000000000042 +:108E30000000000000000000000000000000000032 +:108E40000000000000000000000000000000000022 +:108E50000000000000000000000000000000000012 +:108E60000000000000000000000000000000000002 +:108E700000000000000000000000000000000000F2 +:108E800000000000000000000000000000000000E2 +:108E900000000000000000000000000000000000D2 +:108EA00000000000000000000000000000000000C2 +:108EB00000000000000000000000000000000000B2 +:108EC00000000000000000000000000000000000A2 +:108ED0000000000000000000000000000000000092 +:108EE0000000000000000000000000000000000082 +:108EF0000000000000000000000000000000000072 +:108F00000000000000000000000000000000000061 +:108F10000000000000000000000000000000000051 +:108F20000000000000000000000000000000000041 +:108F30000000000000000000000000000000000031 +:108F40000000000000000000000000000000000021 +:108F50000000000000000000000000000000000011 +:108F60000000000000000000000000000000000001 +:108F700000000000000000000000000000000000F1 +:108F800000000000000000000000000000000000E1 +:108F900000000000000000000000000000000000D1 +:108FA00000000000000000000000000000000000C1 +:108FB00000000000000000000000000000000000B1 +:108FC00000000000000000000000000000000000A1 +:108FD0000000000000000000000000000000000091 +:108FE0000000000000000000000000000000000081 +:108FF0000000000000000000000000000000000071 +:109000000000000000000000000000000000000060 +:109010000000000000000000000000000000000050 +:109020000000000000000000000000000000000040 +:109030000000000000000000000000000000000030 +:109040000000000000000000000000000000000020 +:109050000000000000000000000000000000000010 +:109060000000000000000000000000000000000000 +:1090700000000000000000000000000000000000F0 +:1090800000000000000000000000000000000000E0 +:1090900000000000000000000000000000000000D0 +:1090A00000000000000000000000000000000000C0 +:1090B00000000000000000000000000000000000B0 +:1090C00000000000000000000000000000000000A0 +:1090D0000000000000000000000000000000000090 +:1090E0000000000000000000000000000000000080 +:1090F0000000000000000000000000000000000070 +:10910000000000000000000000000000000000005F +:10911000000000000000000000000000000000004F +:10912000000000000000000000000000000000003F +:10913000000000000000000000000000000000002F +:10914000000000000000000000000000000000001F +:10915000000000000000000000000000000000000F +:1091600000000000000000000000000000000000FF +:1091700000000000000000000000000000000000EF +:1091800000000000000000000000000000000000DF +:1091900000000000000000000000000000000000CF +:1091A00000000000000000000000000000000000BF +:1091B00000000000000000000000000000000000AF +:1091C000000000000000000000000000000000009F +:1091D000000000000000000000000000000000008F +:1091E000000000000000000000000000000000007F +:1091F000000000000000000000000000000000006F +:10920000000000000000000000000000000000005E +:10921000000000000000000000000000000000004E +:10922000000000000000000000000000000000003E +:10923000000000000000000000000000000000002E +:10924000000000000000000000000000000000001E +:10925000000000000000000000000000000000000E +:1092600000000000000000000000000000000000FE +:1092700000000000000000000000000000000000EE +:1092800000000000000000000000000000000000DE +:1092900000000000000000000000000000000000CE +:1092A00000000000000000000000000000000000BE +:1092B00000000000000000000000000000000000AE +:1092C000000000000000000000000000000000009E +:1092D000000000000000000000000000000000008E +:1092E000000000000000000000000000000000007E +:1092F000000000000000000000000000000000006E +:10930000000000000000000000000000000000005D +:10931000000000000000000000000000000000004D +:10932000000000000000000000000000000000003D +:10933000000000000000000000000000000000002D +:10934000000000000000000000000000000000001D +:10935000000000000000000000000000000000000D +:1093600000000000000000000000000000000000FD +:1093700000000000000000000000000000000000ED +:1093800000000000000000000000000000000000DD +:1093900000000000000000000000000000000000CD +:1093A00000000000000000000000000000000000BD +:1093B00000000000000000000000000000000000AD +:1093C000000000000000000000000000000000009D +:1093D000000000000000000000000000000000008D +:1093E000000000000000000000000000000000007D +:1093F000000000000000000000000000000000006D +:10940000000000000000000000000000000000005C +:10941000000000000000000000000000000000004C +:10942000000000000000000000000000000000003C +:10943000000000000000000000000000000000002C +:10944000000000000000000000000000000000001C +:10945000000000000000000000000000000000000C +:1094600000000000000000000000000000000000FC +:1094700000000000000000000000000000000000EC +:1094800000000000000000000000000000000000DC +:1094900000000000000000000000000000000000CC +:1094A00000000000000000000000000000000000BC +:1094B00000000000000000000000000000000000AC +:1094C000000000000000000000000000000000009C +:1094D000000000000000000000000000000000008C +:1094E000000000000000000000000000000000007C +:1094F000000000000000000000000000000000006C +:10950000000000000000000000000000000000005B +:10951000000000000000000000000000000000004B +:10952000000000000000000000000000000000003B +:10953000000000000000000000000000000000002B +:10954000000000000000000000000000000000001B +:10955000000000000000000000000000000000000B +:1095600000000000000000000000000000000000FB +:1095700000000000000000000000000000000000EB +:1095800000000000000000000000000000000000DB +:1095900000000000000000000000000000000000CB +:1095A00000000000000000000000000000000000BB +:1095B00000000000000000000000000000000000AB +:1095C000000000000000000000000000000000009B +:1095D000000000000000000000000000000000008B +:1095E000000000000000000000000000000000007B +:1095F000000000000000000000000000000000006B +:10960000000000000000000000000000000000005A +:10961000000000000000000000000000000000004A +:10962000000000000000000000000000000000003A +:10963000000000000000000000000000000000002A +:10964000000000000000000000000000000000001A +:10965000000000000000000000000000000000000A +:1096600000000000000000000000000000000000FA +:1096700000000000000000000000000000000000EA +:1096800000000000000000000000000000000000DA +:1096900000000000000000000000000000000000CA +:1096A00000000000000000000000000000000000BA +:1096B00000000000000000000000000000000000AA +:1096C000000000000000000000000000000000009A +:1096D000000000000000000000000000000000008A +:1096E000000000000000000000000000000000007A +:1096F000000000000000000000000000000000006A +:109700000000000000000000000000000000000059 +:109710000000000000000000000000000000000049 +:109720000000000000000000000000000000000039 +:109730000000000000000000000000000000000029 +:109740000000000000000000000000000000000019 +:109750000000000000000000000000000000000009 +:1097600000000000000000000000000000000000F9 +:1097700000000000000000000000000000000000E9 +:1097800000000000000000000000000000000000D9 +:1097900000000000000000000000000000000000C9 +:1097A00000000000000000000000000000000000B9 +:1097B00000000000000000000000000000000000A9 +:1097C0000000000000000000000000000000000099 +:1097D0000000000000000000000000000000000089 +:1097E0000000000000000000000000000000000079 +:1097F0000000000000000000000000000000000069 +:109800000000000000000000000000000000000058 +:109810000000000000000000000000000000000048 +:109820000000000000000000000000000000000038 +:109830000000000000000000000000000000000028 +:109840000000000000000000000000000000000018 +:109850000000000000000000000000000000000008 +:1098600000000000000000000000000000000000F8 +:1098700000000000000000000000000000000000E8 +:1098800000000000000000000000000000000000D8 +:1098900000000000000000000000000000000000C8 +:1098A00000000000000000000000000000000000B8 +:1098B00000000000000000000000000000000000A8 +:1098C0000000000000000000000000000000000098 +:1098D0000000000000000000000000000000000088 +:1098E0000000000000000000000000000000000078 +:1098F0000000000000000000000000000000000068 +:109900000000000000000000000000000000000057 +:109910000000000000000000000000000000000047 +:109920000000000000000000000000000000000037 +:109930000000000000000000000000000000000027 +:109940000000000000000000000000000000000017 +:109950000000000000000000000000000000000007 +:1099600000000000000000000000000000000000F7 +:1099700000000000000000000000000000000000E7 +:1099800000000000000000000000000000000000D7 +:1099900000000000000000000000000000000000C7 +:1099A00000000000000000000000000000000000B7 +:1099B00000000000000000000000000000000000A7 +:1099C0000000000000000000000000000000000097 +:1099D0000000000000000000000000000000000087 +:1099E0000000000000000000000000000000000077 +:1099F0000000000000000000000000000000000067 +:109A00000000000000000000000000000000000056 +:109A10000000000000000000000000000000000046 +:109A20000000000000000000000000000000000036 +:109A30000000000000000000000000000000000026 +:109A40000000000000000000000000000000000016 +:109A50000000000000000000000000000000000006 +:109A600000000000000000000000000000000000F6 +:109A700000000000000000000000000000000000E6 +:109A800000000000000000000000000000000000D6 +:109A900000000000000000000000000000000000C6 +:109AA00000000000000000000000000000000000B6 +:109AB00000000000000000000000000000000000A6 +:109AC0000000000000000000000000000000000096 +:109AD0000000000000000000000000000000000086 +:109AE0000000000000000000000000000000000076 +:109AF0000000000000000000000000000000000066 +:109B00000000000000000000000000000000000055 +:109B10000000000000000000000000000000000045 +:109B20000000000000000000000000000000000035 +:109B30000000000000000000000000000000000025 +:109B40000000000000000000000000000000000015 +:109B50000000000000000000000000000000000005 +:109B600000000000000000000000000000000000F5 +:109B700000000000000000000000000000000000E5 +:109B800000000000000000000000000000000000D5 +:109B900000000000000000000000000000000000C5 +:109BA00000000000000000000000000000000000B5 +:109BB00000000000000000000000000000000000A5 +:109BC0000000000000000000000000000000000095 +:109BD0000000000000000000000000000000000085 +:109BE0000000000000000000000000000000000075 +:109BF0000000000000000000000000000000000065 +:109C00000000000000000000000000000000000054 +:109C10000000000000000000000000000000000044 +:109C20000000000000000000000000000000000034 +:109C30000000000000000000000000000000000024 +:109C40000000000000000000000000000000000014 +:109C50000000000000000000000000000000000004 +:109C600000000000000000000000000000000000F4 +:109C700000000000000000000000000000000000E4 +:109C800000000000000000000000000000000000D4 +:109C900000000000000000000000000000000000C4 +:109CA00000000000000000000000000000000000B4 +:109CB00000000000000000000000000000000000A4 +:109CC0000000000000000000000000000000000094 +:109CD0000000000000000000000000000000000084 +:109CE0000000000000000000000000000000000074 +:109CF0000000000000000000000000000000000064 +:109D00000000000000000000000000000000000053 +:109D10000000000000000000000000000000000043 +:109D20000000000000000000000000000000000033 +:109D30000000000000000000000000000000000023 +:109D40000000000000000000000000000000000013 +:109D50000000000000000000000000000000000003 +:109D600000000000000000000000000000000000F3 +:109D700000000000000000000000000000000000E3 +:109D800000000000000000000000000000000000D3 +:109D900000000000000000000000000000000000C3 +:109DA00000000000000000000000000000000000B3 +:109DB00000000000000000000000000000000000A3 +:109DC0000000000000000000000000000000000093 +:109DD0000000000000000000000000000000000083 +:109DE0000000000000000000000000000000000073 +:109DF0000000000000000000000000000000000063 +:109E00000000000000000000000000000000000052 +:109E10000000000000000000000000000000000042 +:109E20000000000000000000000000000000000032 +:109E30000000000000000000000000000000000022 +:109E40000000000000000000000000000000000012 +:109E50000000000000000000000000000000000002 +:109E600000000000000000000000000000000000F2 +:109E700000000000000000000000000000000000E2 +:109E800000000000000000000000000000000000D2 +:109E900000000000000000000000000000000000C2 +:109EA00000000000000000000000000000000000B2 +:109EB00000000000000000000000000000000000A2 +:109EC0000000000000000000000000000000000092 +:109ED0000000000000000000000000000000000082 +:109EE0000000000000000000000000000000000072 +:109EF0000000000000000000000000000000000062 +:109F00000000000000000000000000000000000051 +:109F10000000000000000000000000000000000041 +:109F20000000000000000000000000000000000031 +:109F30000000000000000000000000000000000021 +:109F40000000000000000000000000000000000011 +:109F50000000000000000000000000000000000001 +:109F600000000000000000000000000000000000F1 +:109F700000000000000000000000000000000000E1 +:109F800000000000000000000000000000000000D1 +:109F900000000000000000000000000000000000C1 +:109FA00000000000000000000000000000000000B1 +:109FB00000000000000000000000000000000000A1 +:109FC0000000000000000000000000000000000091 +:109FD0000000000000000000000000000000000081 +:109FE0000000000000000000000000000000000071 +:109FF0000000000000000000000000000000000061 +:10A000000000000000000000000000000000000050 +:10A010000000000000000000000000000000000040 +:10A020000000000000000000000000000000000030 +:10A030000000000000000000000000000000000020 +:10A040000000000000000000000000000000000010 +:10A050000000000000000000000000000000000000 +:10A0600000000000000000000000000000000000F0 +:10A0700000000000000000000000000000000000E0 +:10A0800000000000000000000000000000000000D0 +:10A0900000000000000000000000000000000000C0 +:10A0A00000000000000000000000000000000000B0 +:10A0B00000000000000000000000000000000000A0 +:10A0C0000000000000000000000000000000000090 +:10A0D0000000000000000000000000000000000080 +:10A0E0000000000000000000000000000000000070 +:10A0F0000000000000000000000000000000000060 +:10A10000000000000000000000000000000000004F +:10A11000000000000000000000000000000000003F +:10A12000000000000000000000000000000000002F +:10A13000000000000000000000000000000000001F +:10A14000000000000000000000000000000000000F +:10A1500000000000000000000000000000000000FF +:10A1600000000000000000000000000000000000EF +:10A1700000000000000000000000000000000000DF +:10A1800000000000000000000000000000000000CF +:10A1900000000000000000000000000000000000BF +:10A1A00000000000000000000000000000000000AF +:10A1B000000000000000000000000000000000009F +:10A1C000000000000000000000000000000000008F +:10A1D000000000000000000000000000000000007F +:10A1E000000000000000000000000000000000006F +:10A1F000000000000000000000000000000000005F +:10A20000000000000000000000000000000000004E +:10A21000000000000000000000000000000000003E +:10A22000000000000000000000000000000000002E +:10A23000000000000000000000000000000000001E +:10A24000000000000000000000000000000000000E +:10A2500000000000000000000000000000000000FE +:10A2600000000000000000000000000000000000EE +:10A2700000000000000000000000000000000000DE +:10A2800000000000000000000000000000000000CE +:10A2900000000000000000000000000000000000BE +:10A2A00000000000000000000000000000000000AE +:10A2B000000000000000000000000000000000009E +:10A2C000000000000000000000000000000000008E +:10A2D000000000000000000000000000000000007E +:10A2E000000000000000000000000000000000006E +:10A2F000000000000000000000000000000000005E +:10A30000000000000000000000000000000000004D +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000000000000000000076 +:10AAE0000000000000000000000000000000000066 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB20000000000000000000000000000000000025 +:10AB30000000000000000000000000000000000015 +:10AB40000000000000000000000000000000000005 +:10AB500000000000000000000000000000000000F5 +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00000000000000000000000000000000000A5 +:10ABB0000000000000000000000000000000000095 +:10ABC0000000000000000000000000000000000085 +:10ABD0000000000000000000000000000000000075 +:10ABE0000000000000000000000000000000000065 +:10ABF0000000000000000000000000000000000055 +:10AC00000000000000000000000000000000000044 +:10AC10000000000000000000000000000000000034 +:10AC20000000000000000000000000000000000024 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF0000000000000000000000000000000000051 +:10B000000000000000000000000000000000000040 +:10B010000000000000000000000000000000000030 +:10B020000000000000000000000000000000000020 +:10B030000000000000000000000000000000000010 +:10B040000000000000000000000000000000000000 +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B0900000000000000000000000000000000000B0 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F000000000000000000000000000000000000000 +:10F0100000000000000000000000000000000000F0 +:10F0200000000000000000000000000000000000E0 +:10F0300000000000000000000000000000000000D0 +:10F0400000000000000000000000000000000000C0 +:10F0500000000000000000000000000000000000B0 +:10F0600000000000000000000000000000000000A0 +:10F070000000000000000000000000000000000090 +:10F080000000000000000000000000000000000080 +:10F090000000000000000000000000000000000070 +:10F0A0000000000000000000000000000000000060 +:10F0B0000000000000000000000000000000000050 +:10F0C0000000000000000000000000000000000040 +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000000000000000000020 +:10F0F0000000000000000000000000000000000010 +:10F1000000000000000000000000000000000000FF +:10F1100000000000000000000000000000000000EF +:10F1200000000000000000000000000000000000DF +:10F1300000000000000000000000000000000000CF +:10F1400000000000000000000000000000000000BF +:10F1500000000000000000000000000000000000AF +:10F16000000000000000000000000000000000009F +:10F17000000000000000000000000000000000008F +:10F18000000000000000000000000000000000007F +:10F19000000000000000000000000000000000006F +:10F1A000000000000000000000000000000000005F +:10F1B000000000000000000000000000000000004F +:10F1C000000000000000000000000000000000003F +:10F1D000000000000000000000000000000000002F +:10F1E000000000000000000000000000000000001F +:10F1F000000000000000000000000000000000000F +:10F2000000000000000000000000000000000000FE +:10F2100000000000000000000000000000000000EE +:10F2200000000000000000000000000000000000DE +:10F2300000000000000000000000000000000000CE +:10F2400000000000000000000000000000000000BE +:10F2500000000000000000000000000000000000AE +:10F26000000000000000000000000000000000009E +:10F27000000000000000000000000000000000008E +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F000000000000000000000000000000000000E +:10F3000000000000000000000000000000000000FD +:10F3100000000000000000000000000000000000ED +:10F3200000000000000000000000000000000000DD +:10F3300000000000000000000000000000000000CD +:10F3400000000000000000000000000000000000BD +:10F3500000000000000000000000000000000000AD +:10F36000000000000000000000000000000000009D +:10F37000000000000000000000000000000000008D +:10F38000000000000000000000000000000000007D +:10F39000000000000000000000000000000000006D +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D000000000000000000000000000000000002D +:10F3E000000000000000000000000000000000001D +:10F3F000000000000000000000000000000000000D +:10F4000000000000000000000000000000000000FC +:10F4100000000000000000000000000000000000EC +:10F4200000000000000000000000000000000000DC +:10F4300000000000000000000000000000000000CC +:10F4400000000000000000000000000000000000BC +:10F4500000000000000000000000000000000000AC +:10F46000000000000000000000000000000000009C +:10F47000000000000000000000000000000000008C +:10F48000000000000000000000000000000000007C +:10F49000000000000000000000000000000000006C +:10F4A000000000000000000000000000000000005C +:10F4B000000000000000000000000000000000004C +:10F4C000000000000000000000000000000000003C +:10F4D000000000000000000000000000000000002C +:10F4E000000000000000000000000000000000001C +:10F4F000000000000000000000000000000000000C +:10F5000000000000000000000000000000000000FB +:10F5100000000000000000000000000000000000EB +:10F5200000000000000000000000000000000000DB +:10F5300000000000000000000000000000000000CB +:10F5400000000000000000000000000000000000BB +:10F5500000000000000000000000000000000000AB +:10F56000000000000000000000000000000000009B +:10F57000000000000000000000000000000000008B +:10F58000000000000000000000000000000000007B +:10F59000000000000000000000000000000000006B +:10F5A000000000000000000000000000000000005B +:10F5B000000000000000000000000000000000004B +:10F5C000000000000000000000000000000000003B +:10F5D000000000000000000000000000000000002B +:10F5E000000000000000000000000000000000001B +:10F5F000000000000000000000000000000000000B +:10F6000000000000000000000000000000000000FA +:10F6100000000000000000000000000000000000EA +:10F6200000000000000000000000000000000000DA +:10F6300000000000000000000000000000000000CA +:10F6400000000000000000000000000000000000BA +:10F6500000000000000000000000000000000000AA +:10F66000000000000000000000000000000000009A +:10F67000000000000000000000000000000000008A +:10F68000000000000000000000000000000000007A +:10F69000000000000000000000000000000000006A +:10F6A000000000000000000000000000000000005A +:10F6B000000000000000000000000000000000004A +:10F6C000000000000000000000000000000000003A +:10F6D000000000000000000000000000000000002A +:10F6E000000000000000000000000000000000001A +:10F6F000000000000000000000000000000000000A +:10F7000000000000000000000000000000000000F9 +:10F7100000000000000000000000000000000000E9 +:10F7200000000000000000000000000000000000D9 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000000000099 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F860000000000000000000000000000000000098 +:10F870000000000000000000000000000000000088 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF0000000000000000000000000000000000001 +:020000022000DC +:1000000000000000000000000000000000000000F0 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:10200000837C20324006000A0E0A000103010810FA +:1020100032004006F6090000000C0100000000003C +:1020200000135359040600000000000000080109D5 +:102030000001323340060000281919000000080092 +:102040000000080000000800000008000000080070 +:10205000000008000000080000000800F0EF000089 +:10206000000008000000080000000800F0EF000079 +:102070000000080000000800000008000000000048 +:10208000000101000000000000000000000000004E +:10209000000000000000000000000101010101003B +:1020A000000100000000010101010001000000002A +:1020B000010000010000000007000000010701030B +:1020C000020314000A0A40000000C8003C0000009F +:1020D0000000000000000000000000000000000000 +:1020E0000000000000000000C800C8009600C80002 +:1020F00007078000800005050000000000000000C8 +:1021000006010000000017003900910010001400C3 +:10211000F9FFC4FFFF7FFF7FFF7FFF7F50002C018F +:102120003200FA000A04B4B4323223050000000081 +:1021300000070D0000320D00000000203232323264 +:1021400032323232323232323232323232320000D3 +:10215000000000000000000000000000000000007F +:102160000A05000A00000000170F001210120000FC +:10217000000000000000000000000000000000005F +:10218000000000000F2332465000000078643C3C01 +:102190003C3C3C3C08000000000000000F2332469D +:1021A0005000000078643C3C3C3C3C3C0F141E2832 +:1021B000000000000A0A0A0A0A0A0A0A1946000070 +:1021C00000000000374646464646464600000000EE +:1021D0000A0314005F00F1FF14000F000A00BC02A4 +:1021E00000000000F8FF0000DC003200640028005E +:1021F0000F000F001C023D011C02740400003F068A +:102200000000FF09F40100003F060000FF0932143E +:10221000021E1E3202006400460046007700C80518 +:10222000770088090000000040063000200001000F +:10223000220000003A00520070008F00AF00CF0073 +:10224000EF000F012E014F016E018E01AD01CE0195 +:10225000EC010F022D024D026D028D02AC02CC0288 +:10226000EB020B032B034A036A038903AA03C90386 +:10227000E703FF0337040000000000000000000037 +:10228000000000000000000000000000000000004E +:10229000000000000000000000000000000000003E +:1022A000000000000000000000000000000000002E +:1022B000000000000000000000000000000000001E +:1022C000000000000000000000000000000000000E +:1022D00000000000000000000000000000000000FE +:1022E00000000000000000000000000000000000EE +:1022F00000000000000000000000F6093000460069 +:102300000100480000003C00430066008500A90071 +:10231000C800E90009012A0149016B018901AB01EB +:10232000C901EB0109022B024A026C028A02AC02CB +:10233000CA02EC020B032D034B036D038B03AE03A8 +:10234000CB03EE030C042F044C046F048B04AF0486 +:10235000CC04EF040D0530054D0570058D05B00565 +:10236000CD05F1050D0630064E0672068E06B10645 +:10237000CE06F2060F073207500773079007B30720 +:10238000D107F40711083408520875089108B108FC +:10239000C608E70800000000000000000000000080 +:1023A000000000000000000000000000000000002D +:1023B000000000000000000000000000000000001D +:1023C000000000000000000000000000000000000D +:1023D0000201200019450000F16C000084D90600BC +:1023E00029B1010010270000C40900000000030308 +:1023F000030505050505014B0F00F0000000000076 +:10240000010000030303050505050500194500004B +:102410000200000084DE01000000000014140A0A1B +:102420001400000000000000141414140101010144 +:10243000010040003200E8030F0008000500E10041 +:1024400000001E502800B4005000040000000000EE +:10245000B40050006400A000000000014F01000023 +:102460000000000078000D0D0A09320064006400CD +:102470000A003200C800640064000F02E8E8F800B7 +:10248000F8000200190000006A00750081008E004B +:102490009D00AC00BD00CF00E200F7000D01260159 +:1024A00040015C0179019901BC01E00106023002A2 +:1024B0005B028902BA02EE0224035D039A03D90388 +:1024C0001B046004A904F40443059505E9054106CD +:1024D0009C06FA065B07BE0724088D08F808650904 +:1024E000D409450AB80A2D0BA20B190C900C080D43 +:1024F000800DF80D6F0EE60E5C0FD00F4210B3107A +:1025000021118C11F4115912BA1217137013C4133C +:1025100013145D14A114E01418154B1577159C15B0 +:10252000BB15D415E515EF15F31536003D00440035 +:102530004C00560060006B00770085009300A400FB +:10254000B500C900DE00F5000E0129014601650154 +:102550008701AC01D401FE012B025B028F02C6028F +:1025600001033F038003C6030F045D04AE040305AB +:102570005D05BA051B068106EA065707C9073D082F +:10258000B6083109B009320AB70A3E0BC70B520C24 +:10259000DF0C6D0DFC0D8B0E1A0FA80F3610C3103B +:1025A0004D11D6115B12DE125C13D7134D14BD14FE +:1025B00028158D15EC1544169516DE161F1758179D +:1025C0008917B117D117E717F517FA174E005600FC +:1025D00060006B00760083009100A000B100C20093 +:1025E000D600EB0002011A01350152017001910180 +:1025F000B501DB0103022E025C028D02C102F8026A +:1026000032036F03B003F4033B048604D4042605AD +:102610007C05D50532069206F5065C07C607330829 +:10262000A30816098C09040A7E0AFA0A790BF80B2A +:10263000790CFB0C7E0D010E830E060F870F071021 +:10264000861003117D11F5116912DA124713AF13C9 +:1026500013147214CB141E156B15B215F2152C162B +:102660005E168916AC16C716DB16E716EB164E007B +:10267000560060006B00760083009100A000B1005E +:10268000C200D600EB0002011A01350152017001AF +:102690009101B501DB0103022E025C028D02C10231 +:1026A000F80232036F03B003F4033B048604D4043E +:1026B00026057C05D50532069206F5065C07C60799 +:1026C0003308A30816098C09040A7E0AFA0A790B52 +:1026D000F80B790CFB0C7E0D010E830E060F870F95 +:1026E0000710861003117D11F5116912DA124713D4 +:1026F000AF1313147214CB141E156B15B215F2150B +:102700002C165E168916AC16C716DB16E716EB16E6 +:102710005500550045004200000000000000000088 +:1027200000000000000000000000000000000000A9 +:102730000000000000000000000000000000000099 +:102740000000000000000000000000000000000089 +:102750000000000000000000000000000000000079 +:102760000000000000000000000000000000000069 +:102770000000000000000000000000000000000059 +:102780000000000000000000000000000000000049 +:102790000000000000000000000000000000000039 +:1027A0000000000000000000000000000000000029 +:1027B0000000000000000000000000000000000019 +:1027C0000000000000000000000000000000000009 +:1027D00000000000000000000000000000000000F9 +:1027E00000000000000000000000000000000000E9 +:1027F00000000000000000000000000000000000D9 +:1028000000000000000000000000000000000000C8 +:1028100000000000000000000000000000000000B8 +:1028200000000000000000000000000000000000A8 +:102830000000000000000000000000000000000098 +:102840000000000000000000000000000000000088 +:102850000000000000000000000000000000000078 +:10286000000000000000000000000000F000220155 +:1028700054013C00050000000000000000000000C2 +:102880000000000000000000000000000000000048 +:102890000000000000000000000000000000000038 +:1028A0000000000000000000000000000000000028 +:1028B0000000000000000000000000000000000018 +:1028C0000000000000000000000000000000000008 +:1028D00000000000000000000000000000000000F8 +:1028E00000000000000000000000000000000000E8 +:1028F00000000000000000000000000000000000D8 +:1029000000000000000000000000000000000000C7 +:1029100000000000000000000000000000000000B7 +:1029200000000000000000000000000000000000A7 +:102930000000000000000000000000000000000097 +:102940000000000000000000000000000000000087 +:102950000000000000000000000000000000000077 +:102960000000000000000000000000000000000067 +:102970000000000000000000000000000000000057 +:102980000000000000000000000000000000000047 +:102990000000000000000000000000000000000037 +:1029A0000000000000000000000000000000000027 +:1029B0000000000000000000000000000000000017 +:1029C0000000000000000000000000000000000007 +:1029D00000000000000000000000000000000000F7 +:1029E00000000000000000000000000000000000E7 +:1029F00000000000000000000000000000000000D7 +:102A00001901010000000000000000003202100067 +:102A100001034F590000000000000000000000000A +:102A200099020000BC020000DF0200000203000067 +:102A300025030000480300006B0300008E03000024 +:102A4000B1030000D4030000F70300001A040000E3 +:102A50003D0400006004000083040000A6040000A0 +:102A6000C904000020030000D4B804020351180771 +:102A7000C8388E232310080344611C08000000009E +:102A800000000000190000005B555555555555557F +:102A90005555555505000000080A000000000000CB +:102AA000010000000000000002F80000EC045406E1 +:102AB00084067E07410AA2076A099109B1097E17B7 +:102AC00007B8C30700800000208300000080328028 +:102AD000648096802DB4040F110C0F0F10000F139B +:102AE000A5BA830A18C80F0015101510104310431B +:102AF00020030000D4A8040C42330E0EC4338E23EE +:102B000063011911E32101132302000000000000FA +:102B10001B0000005B555555555555555555555598 +:102B20005505000098090B0BB0B00000B0B0001BB9 +:102B30000B00000082F01002EC04540684067E07AD +:102B4000410AA2076A099109B1097E1707B8C307AC +:102B50000080000020830000008032806480968026 +:102B60002DB4040F110C0F0F10000F13A5BA830A18 +:102B700018C80F0015101510104310432003000053 +:102B8000090000000000000000000000000000003C +:102B90000000000000000000000000000100000034 +:102BA0000300000000000000000000000000000022 +:102BB0000200000000000000000000000000000013 +:102BC00000000000EC04540684067E07410AA207B8 +:102BD0006A099109B1097E1707B8C3070080000090 +:102BE0002083000000803280648096802DB4040F22 +:102BF000110C0F0F10000F13A5BA830A18C80F008D +:102C0000151015101043104320030000D4B804021F +:102C100003511807C8388E232310080344611C0889 +:102C20000000000000000000190000005B55555531 +:102C3000555555555555555555000000086A666659 +:102C400066666666636666666600000002F80000F7 +:102C5000EC04540684067E07410AA2076A0991091A +:102C6000B1097E1707B8C307008000002083000069 +:102C700000803280648096802DB4040F110C0F0FF9 +:102C800010000F13A5BA830A18C80F0015101510ED +:102C90001043104320030000D4A8040C42330E0E4E +:102CA000C4338E2363011911E321011323020000B1 +:102CB000000000001B0000005B555555555555554B +:102CC000555555555505000098696B6BB6B6666647 +:102CD000B6B6663B6B06000082F01002EC045406A8 +:102CE00084067E07410AA2076A099109B1097E1785 +:102CF00007B8C307008000002083000000803280F6 +:102D0000648096802DB4040F110C0F0F10000F1368 +:102D1000A5BA830A18C80F001510151010431043E8 +:102D200020030000D4B854161796010000000000DC +:102D30000000000000000000000000000000000093 +:102D4000080000005B555555000000000000000021 +:102D500000000000081A111100000000000000002F +:102D60000000000002000000EC04540684067E0708 +:102D7000410AA2076A099109B1097E1707B8C3077A +:102D800000800000208300000080328064809680F4 +:102D90002DB4040F110C0F0F10000F13A5BA830AE6 +:102DA00018C80F0015101510104310432003000021 +:102DB000D4B854161796010000000000000000006F +:102DC00000000000000000000000000008000000FB +:102DD0005B55555500000000000000000000000099 +:102DE000083A33330000000000000000000000003B +:102DF00002000000EC04540684067E07410AA20784 +:102E00006A099109B1097E1707B8C307008000005D +:102E10002083000000803280648096802DB4040FEF +:102E2000110C0F0F10000F13A5BA830A18C80F005A +:102E3000151015101043104320030000D4A8540CA3 +:102E4000567339184F068D11A3344E000000000050 +:102E50000000000000000000130000005B55555505 +:102E600055555555550500000000000008191B1B5D +:102E70001B1B0B0B0B0B00000000000002A002004C +:102E8000EC04540684067E07410AA2076A099109E8 +:102E9000B1097E1707B8C307008000002083000037 +:102EA00000803280648096802DB4040F110C0F0FC7 +:102EB00010000F13A5BA830A18C80F0015101510BB +:102EC0001043104320030000D4A8540C5673391843 +:102ED0004F068D11A3344E000000000000000000DA +:102EE00000000000130000005B5555555555555521 +:102EF000550500000000000008393B3B3B3B0B0B35 +:102F00000B0B00000000000002A00200EC045406BD +:102F100084067E07410AA2076A099109B1097E1752 +:102F200007B8C307008000002083000000803280C3 +:102F3000648096802DB4040F110C0F0F10000F1336 +:102F4000A5BA830A18C80F001510151010431043B6 +:102F500020030000D4A8051B023774045E311A2335 +:102F6000C7088C08000000000000000000000000FE +:102F7000140000005B5555555555555555550000E5 +:102F800000000000080909090909000010000000FC +:102F90000000000002500500EC04540684067E0781 +:102FA000410AA2076A099109B1097E1707B8C30748 +:102FB00000800000208300000080328064809680C2 +:102FC0002DB4040F110C0F0F10000F13A5BA830AB4 +:102FD00018C80F00151015101043104320030000EF +:102FE000D4A8051B023774045E311A23C7088C0865 +:102FF00000000000000000000000000014000000BD +:103000005B55555555555555555500000000000068 +:10301000086969696969606030600000000000004B +:1030200002500500EC04540684067E07410AA207FC +:103030006A099109B1097E1707B8C307008000002B +:103040002083000000803280648096802DB4040FBD +:10305000110C0F0F10000F13A5BA830A18C80F0028 +:10306000151015101043104320030000D4A8551B61 +:10307000167775185E0600000000000000000000D2 +:1030800000000000000000000C0000005B555555DA +:103090005555000000000000000000000819191933 +:1030A00019190000000000000000000002000000EC +:1030B000EC04540684067E07410AA2076A099109B6 +:1030C000B1097E1707B8C307008000002083000005 +:1030D00000803280648096802DB4040F110C0F0F95 +:1030E00010000F13A5BA830A18C80F001510151089 +:1030F0001043104320030000D4A8551B1677751801 +:103100005E0600000000000000000000000000005B +:10311000000000000C0000005B555555555500009F +:10312000000000000000000008393939393900007A +:10313000000000000000000002000000EC04540643 +:1031400084067E07410AA2076A099109B1097E1720 +:1031500007B8C30700800000208300000080328091 +:10316000648096802DB4040F110C0F0F10000F1304 +:10317000A5BA830A18C80F00151015101043104384 +:1031800020030000813010050670200000000000C0 +:10319000000000000000000000000000000000002F +:1031A00009000000555555550500000000000000BD +:1031B000000000000000000100000000000000000E +:1031C0000000000000000000EC04540684067E07A6 +:1031D000410AA2076A099109B1097E1707B8C30716 +:1031E0000080000020830000008032806480968090 +:1031F0002DB4040F110C0F0F10000F13A5BA830A82 +:1032000018C80F00151015101043104320030000BC +:10321000D4B8000000000000000000000000000022 +:10322000000000000000000000000000030000009B +:103230005B0500000000000000000000000000002E +:10324000080A00000000000000000000000000006C +:1032500002000000EC04540684067E07410AA2071F +:103260006A099109B1097E1707B8C30700800000F9 +:103270002083000000803280648096802DB4040F8B +:10328000110C0F0F10000F13A5BA830A18C80F00F6 +:1032900015101510104310432003000054726119DB +:1032A0001A00000000000000000000000000000004 +:1032B000000000000000000002000000465555001C +:1032C00000000000000000000000000028999900A4 +:1032D00000000000000000000000000000000000EE +:1032E000EC04540684067E07410AA2076A09910984 +:1032F000B1097E1707B8C3070080000020830000D3 +:1033000000803280648096802DB4040F110C0F0F62 +:1033100010000F13A5BA830A18C80F001510151056 +:1033200010431043200300008C7561191A0000003F +:10333000000000000000000000000000000000008D +:10334000000000000100000054555500000000007E +:1033500000000000000000009B99990000000000A0 +:10336000000000000000000000000000EC04540613 +:1033700084067E07410AA2076A099109B1097E17EE +:1033800007B8C3070080000020830000008032805F +:10339000648096802DB4040F110C0F0F10000F13D2 +:1033A000A5BA830A18C80F00151015101043104352 +:1033B0000000000000000001000003000000FC000D +:1033C000000000000D000D0040065906000000003E +:1033D0000155B400020000000000000001010302DA +:1033E000000001000000FC00000000000D000D00C6 +:1033F00000000F000000000004B0B3000000001047 +:103400000000000002020302000001000000FC00B6 +:10341000000000000D000D0001000E000000000083 +:1034200004C4B30000000010000000000303030206 +:10343000000001000000FC00000000000D000D0075 +:1034400002000D000000000004D8B30000000010CE +:103450000000000004040302000001000000FC0062 +:10346000000000000D000D0003000C000000000033 +:1034700004ECB3000000001000000000050503028A +:10348000000001000000FC00000000000D000D0025 +:1034900004000B00000000000400B4000000001055 +:1034A0000000000006060302000001000000FC000E +:1034B000000000000D000D0005000A0000000000E3 +:1034C0000414B4000000001000000000070703020D +:1034D000000001000000FC00000000000D000D00D5 +:1034E00006000900000000000428B40000000010DD +:1034F0000000000008080302000005000000FC00B6 +:10350000000000000D000D00070008000000000092 +:10351000043CB4000000001000000000090000019D +:10352000000007000000FC00000000000D000D007E +:10353000A00FB90F000000000150B400000000000F +:103540000000000000000001000003000000FC007B +:10355000000000000D000D00C116A81600000000BC +:1035600001A0B400060000000000000000001717D2 +:10357000000003000000FC00000000000D000D0032 +:103580003818391800000000019BB4000400000046 +:103590000000000000001616000003000000FD00FF +:1035A000000000000D000D00681070100000FA25EA +:1035B0000473B400040000000000000000001717AE +:1035C000000003000000FC00000000000D000D00E2 +:1035D000F811F9110000FA250487B4000400000076 +:1035E0000000000000001616000003000000FD00AF +:1035F000000000000D000D00681070100000FA259A +:103600000473B4000400000000000000000017175D +:10361000000003000000FC00000000000D000D0091 +:10362000F811F9110000FA250487B4000400000025 +:103630000000000000001616000003000000FD005E +:10364000000000000D000D00681070100000FA2549 +:103650000473B4000400000000000000000017170D +:10366000000003000000FC00000000000D000D0041 +:10367000F811F9110000FA250487B40004000000D5 +:103680000000000000001616000003000000FD000E +:10369000000000000D000D00681070100000FA25F9 +:1036A0000473B400040000000000000000001717BD +:1036B000000003000000FC00000000000D000D00F1 +:1036C000F811F9110000FA250487B4000400000085 +:1036D00000000000000A1414002802000000FC0092 +:1036E00000000000050005000000000000000000D0 +:1036F000010097030000000000000000000001002E +:10370000002802000000FC00000000000D000D0079 +:103710000000190000000000015AB400020000007F +:103720000000000000000100002802000000FC0072 +:10373000000000000D000D009001A9010000000034 +:10374000015FB40002000000000000000000010062 +:10375000002802000000FC00000000000D000D0029 +:1037600020033903000000000164B40002000000DF +:103770000000000000000100002802000000FC0022 +:10378000000000000D000D00B004C904000000009E +:103790000169B40002000000000000000000010008 +:1037A000002802000000FC00000000000D000D00D9 +:1037B0004006590600000000016EB400020000003F +:1037C0000000000000000100002802000000FC00D2 +:1037D000000000000D000D006810811000000000C6 +:1037E00001A5B40006000000000000000000010078 +:1037F000002802000000FC00000000000D000D0089 +:10380000F81111120000000001AAB4000600000027 +:103810000000000000000100002802000000FC0081 +:10382000000000000D000D008813A113000000002F +:1038300001AFB4000600000000000000000001001D +:10384000002802000000FC00000000000D000D0038 +:10385000181531150000000001B4B4000600000086 +:103860000000000000000100002802000000FC0031 +:10387000000000000D000D00A816C1160000000099 +:1038800001B9B400060000000000000000000100C3 +:10389000002802000000FC000000000009000900F0 +:1038A0000000000000000000010097030600000077 +:1038B00000000000000B1414002802000000FC00AF +:1038C000000000000C000C000000000000000000E0 +:1038D000010097030000000000000000000B14141A +:1038E000002802000000FC003F0000000C000C005B +:1038F000000000000000000001009703000000002D +:1039000000000000000B1515002802000000CC008C +:10391000000000000C000C0000000000000000008F +:1039200001009703000000000000000000000100FB +:10393000002802000000FC00000000000D000D0047 +:1039400000000000000000000100970306000000D6 +:103950004F00000001F4040068931B0060000000A9 +:103960000C000000010004001428000060000000AA +:10397000300000002D008400142800001C0000000E +:10398000730000002DF4840068931B001C000000ED +:10399000700000002DF4840068931B001C000000E0 +:1039A0007300000023F4840068931B001C000000D7 +:1039B000600000002DF4840068931B001C000000D0 +:1039C0004F00000001F4040068931B00E0000100B8 +:1039D0000C0000000100040014280000E0000100B9 +:1039E000300000002D008400142800001C0000009E +:1039F000700000002DF4840068931B001C00000080 +:103A0000730000002DF4840051651B001C000000B1 +:103A1000010128010101010101010101010101016F +:103A20000101010101010101010101010101010186 +:103A30000101010101010101010101010101010176 +:103A40000101010101010101010101010101010166 +:103A50000101010101010101010101010101010156 +:103A60000101010101010101010101010101010146 +:103A70000101010133323C333533353534333534CC +:103A800033333335353434343434323433343433FB +:103A900033333433353333343334333334343434ED +:103AA00033343335353234343233323232333233E5 +:103AB00032323232323132323233323232323232E6 +:103AC00033323132313133323232333233313332D5 +:103AD000323332342F2F303033323C3335333535B7 +:103AE0003433353433333335353434343434333498 +:103AF000333434333333343335333334333433338F +:103B0000343434343334333535323434323333327D +:103B10003233323332323232323232323233323282 +:103B20003232323233323132313133323232333275 +:103B300033313332323332342F2E302F333233336A +:103B40003333333434333534333333353534343439 +:103B5000343433343334343333333433353333342C +:103B6000333433333334343433343335353234331C +:103B70003233323232333233323232323231323223 +:103B80003133323232323232323231323131333217 +:103B90003232333232313232323232332F2E302F10 +:103BA00033323333333333343433353433333335DF +:103BB00035343434343433343334343333333433CA +:103BC00035333334333433333334343433343335BB +:103BD00035323433323333323233323332323232BB +:103BE00032323232323332323232323232323132B5 +:103BF00031323332323233323331333232323233A2 +:103C00002F2E302F32323333333333343433353491 +:103C10003333333535343434343433343333343369 +:103C2000333334333533333433343333333434345C +:103C30003334333534323433323332323233323355 +:103C40003232313232313232313232323232323257 +:103C50003232313131313332323232323331323247 +:103C6000323232332F2E302F323233333333333438 +:103C70003433353433333335353434343434333406 +:103C800033333433333334333533333433343333FE +:103C900033343434333433353532343332333232EF +:103CA00032333233323231323231323232333232F3 +:103CB00032323232323231323131333232323232E6 +:103CC00033313232323232332F2E302F32323333DD +:103CD00033333334343335343333333535343434A8 +:103CE000343433343334343333333433343333349C +:103CF000333433333334343433343335343234338C +:103D00003233323232323233323231323231323293 +:103D10003132323232323232323231323131333286 +:103D20003132323232313232313232332F2E302F81 +:103D3000333233333333333434333534333333354D +:103D40003534343434343334333434333333343338 +:103D5000343333343334333333343434333433352A +:103D6000343234333233323232323233323231322D +:103D70003231323231323232323232323232313226 +:103D80003131333231323232323132323232323315 +:103D90002F2E302F4B4D5351514F4F514F4F534FAB +:103DA000534F4F51534F4E4D53514D4F4F4F534F14 +:103DB0004F4F4F4F514D4F51514F4F4F534F4F4F0B +:103DC00051534F53554F51514F4F4F4D4F514D4FF1 +:103DD0004F4D4D4D4D4D4F4D4F4F4F4F4F4F4D4F01 +:103DE000514D4D4D4D4F4D4D4F4B4F4D51494D4FF9 +:103DF0004F4F4B4F4B494B4B9224922492009200D1 +:103E000000000000B66DB66DB600B6000000000000 +:103E1000B66DB66D9601960100000000B66DB66DE8 +:103E2000B201B20100000000B62DB62DB601B601F8 +:103E300000000000B665B665B601B60100000000DE +:103E4000B66CB66CB601B60100000000966D966DBA +:103E5000B601B60100000000B26DB26DB601B60148 +:103E600000000000FF7FFF7FFF01FF010000000056 +:103E7000B66DB66DB601B601000000009224922422 +:103E800092009200000000000110000000000000FD +:103E900000000000FFFF3DDB38D4FC020200AA0056 +:103EA0006C768A940001060000000000DB0600002A +:103EB000040C000060056E40415639030100009A71 +:103EC000EC045661000000000000000010C40C501B +:103ED0000390BBBB80442278641164118A3989390C +:103EE00085E00FE06612641201100000000000007F +:103EF00000000000FFFF3DDB38D4FC020200AA00F6 +:103F00006C768A940001060000000000DB060000C9 +:103F1000040C000060056E40415639030100009A10 +:103F2000EC045661000000000000000010C40C10FA +:103F3000E39EBBBB80552278641164118A398939AC +:103F400085E00FE06612641201040000000000002A +:103F50000000000000000000000000020200AA00B3 +:103F60006C768A940001060000000000DB06000069 +:103F7000040C000020066E40418639030100009ABF +:103F8000AC058661000000000000000010C40C5069 +:103F90000390BBBB80442278641164118A3989394B +:103FA00085E00FE066126412C904020001020304F6 +:103FB000EAF7FAFD3001A880CF0304021E000003D7 +:103FC0006C768A940001060000000000DB06000009 +:103FD000014600002B1A0040006B39034100029A91 +:103FE00000006B616478792BCF8A00801C54119893 +:103FF0000080BBBB00572278641164118A3989396B +:1040000085F00FF066126412C9040200010101017B +:10401000EAF7FAFD3001A880CF0304020200000095 +:104020006C768A940001060000000000DB060000A8 +:10403000014600002B1A0040006B39034100029A30 +:1040400000006B619A7F0A0AFFFF00801C541198E0 +:104050000380BBBB80462278641164118A39893998 +:1040600085F00FF066126412C90402000202020217 +:10407000EAF7FAFD3001A880CF0304020200000035 +:104080006C768A940001060000000000DB06000048 +:10409000014600002B1A0040006B39034100029AD0 +:1040A00000006B616C7E0614FFFF00801C541198A9 +:1040B0000380BBBB80462278641164118A39893938 +:1040C00085F00FF066126412C904020003030303B3 +:1040D000EAF7FAFD3001A880CF03040202000000D5 +:1040E0006C768A940001060000000000DB060000E8 +:1040F000014600002B1A0040006B39034100029A70 +:1041000000006B61767CE11DFFFF00801C5411985C +:104110000380BBBB80462278641164118A398939D7 +:1041200085F00FF066126412C9040200040404044E +:10413000EAF7FAFD3001A880CF0304020200000074 +:104140006C768A940001060000000000DB06000087 +:10415000014600002B1A0040006B39034100029A0F +:1041600000006B61BC798D27FFFF00801C54119803 +:104170000380BBBB80462278641164118A39893977 +:1041800085F00FF0661264120104000400000000C4 +:10419000CCF57AFDED20BF8FCF03040202060000AC +:1041A0006C768A940001060000000000DB06000027 +:1041B00001060000093C0040006B39034100029AEF +:1041C00000006B616478792BCF8A00801CC41018C2 +:1041D0000380ABAA00C6227864116411803980394B +:1041E0000F000F00550D550DC904020006070A0BFC +:1041F000EAF7FAFD3001A880CF0304021E0600038F +:104200006C768A940001060000000000DB060000C6 +:10421000014600002B1A0040006B39034100029A4E +:1042200000006B616478792BCF8A00801C54119850 +:104230000080BBBB00572218641164118A39893988 +:1042400085F00FF066126412C90402000606060625 +:10425000EAF7FAFD3001A880CF030402020600004D +:104260006C768A940001060000000000DB06000066 +:10427000014600002B1A0040006B39034100029AEE +:1042800000006B616478792BCF8A00801C541198F0 +:104290000080BBBB00572218641164118A39893928 +:1042A00085F00FF066126412C904020006060A0ABD +:1042B00073EDFAFD5985A880CF0304020A060100B8 +:1042C0006C768A940043060100000000DB060000C3 +:1042D000014600002B1A0040006B39034100029A8E +:1042E00000006B619367CBB40000008012541198FA +:1042F0000080BBBB00562218641164118A398939C9 +:1043000085F00FF066126412C904020007070B0B58 +:1043100073EDFAFD5985A880CF0304020A06010057 +:104320006C768A940043060100000000DB06000062 +:10433000014600002B1A0040006B39034100029A2D +:1043400000006B6155737BC8000000801254119807 +:104350000080BBBB00562218641164118A39893968 +:1043600085F00FF066126412C904020009090C0CF2 +:1043700073EDFAFD5985A880CF0304020A060100F7 +:104380006C768A940043060100000000DB06000002 +:10439000014600002B1A0040006B39034100029ACD +:1043A00000006B61D9770ED3000000801254119881 +:1043B0000080BBBB00562218641164118A39893908 +:1043C00085F00FF066126412C90402000A0A06069C +:1043D00073EDFAFD5985A880CF0304020A06010097 +:1043E0006C768A940043060100000000DB060000A2 +:1043F000014600002B1A0040006B39034100029A6D +:1044000000006B61BD7977D80000008012541198CC +:104410000080BBBB00562218641164118A398939A7 +:1044200085F00FF066126412C90402000B0B070737 +:1044300073EDFAFD5985A880CF0304020A06010036 +:104440006C768A940043060100000000DB06000041 +:10445000014600002B1A0040006B39034100029A0C +:1044600000006B61757B34DE0000008012541198EF +:104470000080BBBB00562218641164118A39893947 +:1044800085F00FF066126412C90402000A0A0606DB +:1044900073EDFAFD5985A880CF0304020A060100D6 +:1044A0006C768A940043060100000000DB060000E1 +:1044B000014600002B1A0040006B39034100029AAC +:1044C00000006B61CB7C87E30000008012541198E0 +:1044D0000080BBBB00562218641164118A398939E7 +:1044E00085F00FF066126412C90402000B0B070777 +:1044F00073EDFAFD5985A880CF0304020A06010076 +:104500006C768A940043060100000000DB06000080 +:10451000014600002B1A0040006B39034100029A4B +:1045200000006B61F27D29E90000008012541198AF +:104530000080BBBB00562218641164118A39893986 +:1045400085F00FF066126412C90402000C0C090910 +:1045500073EDFAFD5985A880CF0304020A06010015 +:104560006C768A940043060100000000DB06000020 +:10457000014600002B1A0040006B39034100029AEB +:1045800000006B61D57EC2EE0000008012541198CD +:104590000080BBBB00562218641164118A39893926 +:1045A00085F00FF0661264120000000000000000A9 +:1045B00000101000000060CA00009B94100F000261 +:1045C0000000E92A0000EA17100F00050000C825C6 +:1045D00000001579100E00070000D3C100002AA8C2 +:1045E000100C00090000C15A00009C9A0004103011 +:1045F0000000BCA00000903800091033000083D0F8 +:104600000000D635000B10350000C9C200001A5951 +:10461000000C103600008CA100002C9F000D1037FC +:1046200000009851000044DC000E10380000BEEA83 +:104630000000A536000E103A000026620000DD9949 +:10464000000F103B000000008C0000007300000011 +:1046500073000000660000003F0000003F00000003 +:1046600033000000260000000000000000000000F1 +:10467000000000000000000000000000000000003A +:10468000000000000000000000000000000000002A +:10469000000000000000000000000000000000001A +:1046A000000000000000000000000000000000000A +:1046B00000000000000000000000000000000000FA +:1046C00000000000870700008579385793F930A172 +:1046D000B3D4CC2BCB0AF200000000000000000095 +:1046E00000000000000000000000000000000000CA +:1046F00000000000000000000000000000000000BA +:1047000080220022870700008579385793E4C2B9D8 +:1047100030AFCC2BC5A1B3000000000000000000AA +:104720000000000000000000000000000000000089 +:104730000000000000000000000000000000000079 +:1047400080220022870700008579385793E4C2BC95 +:10475000C2BCD7930D7930000000000000000000BB +:104760000000000000000000000000000000000049 +:104770000000000000000000000000000000000039 +:1047800080220022870700008579385793E4C2BF52 +:10479000930ACC2BC4F50D000000000000000000BF +:1047A0000000000000000000000000000000000009 +:1047B00000000000000000000000000000000000F9 +:1047C00080220022870700008579385793E4C2BF12 +:1047D000930AE4C2B286CF0000000000000000008F +:1047E00000000000000000000000000000000000C9 +:1047F00000000000000000000000000000000000B9 +:1048000080220022870700008579385793E4C2BFD1 +:10481000930AB0AF26CF5000000000000000000057 +:104820000000000000000000000000000000000088 +:104830000000000000000000000000000000000078 +:1048400080220022870700008579385793E4C2BB95 +:104850000AF2E4C2BE4C2B00000000000000000081 +:104860000000000000000000000000000000000048 +:104870000000000000000000000000000000000038 +:1048800080220022870700008579385793E4C2BB55 +:104890000AF2B0AF295E4C000000000000000000EA +:1048A0000000000000000000000000000000000008 +:1048B00000000000000000000000000000000000F8 +:1048C00080220022C8060000450EA63D450EA63DEA +:1048D000BAF15942450EA63D450EA63D450EA63DF0 +:1048E000450EA63D00000000000000000000000092 +:1048F00000000000000000000000000000000000B8 +:104900008022002231302F2E2D2C2B2A29282726D9 +:104910002524232221201F1E1D1C1B1A19181716BF +:104920001514131211100F0E0D0C0B0A09080706AF +:104930000504030201000000000000000000000068 +:104940000000000000000000000000004A49484745 +:10495000464544434241403F3E3D3C3B3A3938376F +:10496000363534333231302F2E2D2C2B2A2928275F +:10497000262524232221201F1E1D1C1B1A1900007E +:104980000000000000000000000000000000000027 +:10499000000000002000E0C0A08060402000E0C0D7 +:1049A000A08060402000E0C0A08060402000E0C007 +:1049B000A08060402000E0C0A08060402000E0C0F7 +:1049C000A08060402000000076DBB62D2449921BB9 +:1049D000DBB6491292942409090000002000E0C0CF +:1049E000A08060402000E0C0A08060402000E0C0C7 +:1049F000A08060402000E0C0A08060402000E0C0B7 +:104A0000A08060402000E0C0A08060402000000046 +:104A100076DBB62D2449921BDBB649129294240909 +:104A2000090000002021E0E1A0A160612021E0E177 +:104A3000A0A160612021E0E1A0A160612021E0E16E +:104A4000A0A160612021E0E1A0A160612021E0E15E +:104A5000A0A160612021000076DBB62D2449921BC5 +:104A6000DBB6491292942409090000000100C1C07C +:104A7000818041400100C1C0818041400100C1C02E +:104A8000818041400100C1C0818041400100C1C01E +:104A9000818041400100C1C081804140010000008F +:104AA00076DBB62D2449921BDBB649129294240979 +:104AB000090000002120E1E0A1A061602120E1E0E7 +:104AC000A1A061602120E1E0A1A061602120E1E0DE +:104AD000A1A061602120E1E0A1A061602120E1E0CE +:104AE000A1A061602120000076DBB62D2449921B35 +:104AF000DBB64912929424090900000063432303A2 +:104B0000E2C2A28262422202E2C2A2826242220285 +:104B1000E2C2A28262422202E2C2A2826242220275 +:104B2000E2C2A28262422202E2C2A2826242000089 +:104B300000D0B62D2D499224DBB66D1292242509A2 +:104B4000490200002C0CECCCAC8C6C4C2C0CECCC4A +:104B5000AC8C6C4C2C0CECCCAC8C6C4C2C0CECCC95 +:104B6000AC8C6C4C2C0CECCCAC8C6C4C2C0CEBCB87 +:104B7000AB8B6B4B2B0B00002D499224DBB66D12D7 +:104B8000922425094902000040DBB62DA484644428 +:104B90002404E3C3A38363432303E3C3A3836343E3 +:104BA0002303E3C3A38363432303E3C3A3836343D5 +:104BB0002303E3C3A38363432303E3C3A38300006B +:104BC0000000B42D6D4B9224E4B66D1B922449096C +:104BD00049920000EBCBAB8B6B4B2B0BEBCBAB8B36 +:104BE0006B4B2B0BEBCBAB8B6B4B2B0BEBCBAB8B15 +:104BF0006B4B2B0BEBCBAB8B6B4B2B0BEACAAA8A09 +:104C00006A4A2A0AEACA00002449921BDBB6491202 +:104C100092942409090000006DDBB624E5C5A58542 +:104C200065452505E4C4A48464442404E4C4A48440 +:104C300064442404E4C4A48464442404E4C4A48434 +:104C400064442404E4C4A48464442404E4C400004C +:104C50000000002D6DDB922424B96D1B9B244912AA +:104C600049922400AA8A6A4A2A0AEACAAA8A6A4A8D +:104C70002A0AEACAAA8A6A4A2A0AEACAAA8A6A4A94 +:104C80002A0AEACAAA8A6A4A2A0AE9C9A98969498A +:104C90002909E9C9A989000024496E1BDB264912AC +:104CA000529224090000002D6DDB92242606E6C6F0 +:104CB000A68666462606E5C5A58565452505E5C59E +:104CC000A58565452505E5C5A58565452505E5C594 +:104CD000A58565452505E5C5A5856545250500002E +:104CE000090000006DDBB62424496E1BDB26491247 +:104CF0005292240969492909E9C9A98969492909F7 +:104D0000E9C9A98969492909E9C9A9896949290913 +:104D1000E9C9A98969492909E8C8A888684828080B +:104D2000E8C8A8886848000024B96D1B9B24491274 +:104D3000499224000000B42D6D4B92246747270749 +:104D4000E7C7A78767472707E6C6A68666462606FB +:104D5000E6C6A68666462606E6C6A68666462606F3 +:104D6000E6C6A68666462606E6C6A686664600000F +:104D70004902000040DBB62D2449921BDBB64912E4 +:104D8000929424092808E8C8A88868482808E8C830 +:104D9000A88868482808E8C8A88868482808E8C893 +:104DA000A88868482808FFFFFFFFFFFFFFFFFFFFFD +:104DB000FFFFFFFFFFFF0000E4B66D1B92244909CF +:104DC0004992000000F0FF3FFFFFFF3FFFFFFFFFA2 +:104DD000FFFFFFFFFFFFFFFFFFFFE7C7A787674753 +:104DE0002707E7C7A78767472707E7C7A787674753 +:104DF0002707E7C7A78767472707E7C7A7870000F1 +:104E0000FFFFFF3FFFDFB62D2D499224DBB66D1269 +:104E100092242509636261605F5E5D5C5B5A59584C +:104E200057565554535251504F4E4D4C4B4A49488A +:104E300047464544434241403F3E3D3C3B3A39387A +:104E40003736353433320000000000000000000027 +:104E500000000000000000000000000031302F2E94 +:104E60002D2C2B2A292827262524232221201F1EEA +:104E70001D1C1B1A191817161514131211100F0EDA +:104E80000D0C0B0A090807060504030201000000C7 +:104E90000000000000000000000000000000000012 +:104EA00000000000FFFFFFFFFFFFFFFFFFFFFFFF0E +:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:104ED000FFFFFFFFFFFF0000FFFFFF3FFFFFFF3F60 +:104EE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFFFF12 +:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:104F0000FFFFFFFFFFFFFFFFFFFF000000000000AB +:104F10000000000000000000000000000000000091 +:104F2000FFFFFF3FFFFFFF3FFFFFFF3F00000000CD +:104F30000000000057473727170756463626160643 +:104F4000554535251505544434241404534333235F +:104F500013035242322212025141312111015040B9 +:104F600030201000FFFF00000000000000000000E3 +:104F700000000000000000000000003F62605E5C76 +:104F80005A58565452504E4C4A48464442403E3C71 +:104F90003A38363432302E2C2A28262422201E1C61 +:104FA0001A18161412100E0C0A080604020000004B +:104FB00000000000000000000000000000000000F1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE00000000000000000000000000000000000C1 +:104FF00000000000000000000000000000000000B1 +:1050000000000000000000000000000000000000A0 +:105010000000000000000000000000000000000090 +:105020000000000000000000000000000000000080 +:105030000000000000000000000000000000000070 +:105040000000000000000000000000000000000060 +:105050000000000000000000000000000000000050 +:105060000000000000000000000000000000000040 +:105070000000000000000000000000000000000030 +:105080000000000000000000000000000000000020 +:105090000000000000000000000000000000000010 +:1050A0000000000000000000000000000000000000 +:1050B00000000000000000000000000000000000F0 +:1050C00000000000000000000000000000000000E0 +:1050D00000000000000000000000000000000000D0 +:1050E00000000000000000000000000000000000C0 +:1050F00000000000000000000000000000000000B0 +:10510000000000000000000000000000000000009F +:10511000000000000000000000000000000000008F +:10512000000000000000000000000000000000007F +:10513000000000000000000000000000000000006F +:10514000000000000000000000000000000000005F +:10515000000000000000000000000000000000004F +:10516000000000000000000000000000000000003F +:10517000000000000000000000000000000000002F +:10518000000000000000000000000000000000001F +:10519000000000000000000000000000000000000F +:1051A00000000000000000000000000000000000FF +:1051B00000000000000000000000000000000000EF +:1051C00000000000000000000000000000000000DF +:1051D00000000000000000000000000000000000CF +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:105200000801010000000000000000003202100050 +:105210001B00000000000000000000000000000073 +:105220008C0C0000AF0C0000D20C0000F50C00004C +:10523000200300004110080344611C080000000026 +:10524000000000000000000000000000000000005E +:105250000A00000066666666560000000000000056 +:10526000000000000000000000000000000000003E +:105270000000000003000000180DD60D060E1F0EE2 +:10528000530F580E300F420F430F7E1707B8C30756 +:1052900000800000208300000080328064809680BF +:1052A0002DB4040F110C0F0F10000F13A5BA030A31 +:1052B00018C80F00151015101043104320030000EC +:1052C000CBB2300DCE0345120000000000000000FC +:1052D0000000000000000000000000000A000000C4 +:1052E00066666666560000000000000000000000D0 +:1052F00011111111111111111111000000000010F4 +:1053000003000000180DD60D060E1F0E530F580E89 +:10531000300F420F430F7E1707B80733008000009D +:105320002083000000803280648096802DB4040FBA +:10533000110C0F0F90000F13A5BA830A18C80F00A5 +:10534000151015101043104345097E1707B8C30701 +:105350000080008020F3000C00803280648096FE84 +:105360002DB4FFFF11FDFFFFD0FF0F13A5BA830A75 +:1053700018C80F00130F130F0F410F411F03000038 +:105380000900000000000000000000000000000014 +:10539000188DD68D068E1F8E538F588E308F428F6C +:1053A000438F0000000000C000000000000000006B +:1053B00002000000000000000000000000000000EB +:1053C00000E60000EC0454E7E4077EE75509A20775 +:1053D0000A09250945097E1707B8C30700800000A0 +:1053E0002083000000803280648096802DB4048F7A +:1053F00011FDFFFFD0FF0F93A5BA830A18E80FE055 +:10540000130F13FF0F410F411F030000D4B8040214 +:105410000351188748F00C0C85011C08188DD68D97 +:10542000068E1F8E538F588E308F428F438F555567 +:10543000555555D55555000000000018086A666698 +:1054400066666666366600270000000002E6008099 +:10545000EC0C54EFE4877EE75509A2070AE925E939 +:105460000000000000000100002802000000FC0015 +:10547000000000000D000D0059064006000000006D +:105480000155970102000000000000000001020227 +:10549000002800008002FC00FFFFFF010D000D004E +:1054A00007000F000000000004B0B300000000106F +:1054B0000000000000020202002800008002FC0040 +:1054C000FFFFFF010D000D0006000E0000000000B0 +:1054D00004C4B3000000001000000000000302023A +:1054E000002800008002FC00FFFFFF010D000D00FE +:1054F00005000D000000000004D8B30000000010FB +:105500000000000000040202002800008002FC00ED +:10551000FFFFFF010D000D0004000C000000000063 +:1055200004ECB300000000100000000000050202BF +:10553000002800008002FC00FFFFFF010D000D00AD +:1055400003000B00000000000400B4000000001085 +:105550000000000000060202002800008002FC009B +:10556000FFFFFF010D000D0002000A000000000017 +:105570000414B40000000010000000000007020244 +:10558000002800008002FC00FFFFFF010D000D005D +:1055900001000900000000000428B4000000001011 +:1055A0000000000000080202002804008002FC0045 +:1055B000FFFFFF010D000D000000080000000000CB +:1055C00020B0B30000000010000000000000000048 +:1055D000002806000000FC00000000000D000D0087 +:1055E000D20FA00F00000000015097010000000042 +:1055F0000000000000000000002802000000FC0085 +:10560000000000000D000D00C116A81600000000EB +:10561000018C97010600000000000000000B020250 +:10562000002800008000FC00000000000D000D00BC +:1056300007000F000000000004B0B30000000010DD +:1056400000000000000C0202002800008000FC00A6 +:10565000000000000D000D0006000E00000000001C +:1056600004C4B3000000001000000000000D02029E +:10567000002800008000FC00000000000D000D006C +:1056800005000D000000000004D8B3000000001069 +:1056900000000000000E0202002800008000FC0054 +:1056A000000000000D000D0004000C0000000000D0 +:1056B00004ECB3000000001000000000000F020224 +:1056C000002800008000FC00000000000D000D001C +:1056D00003000B00000000000400B40000000010F4 +:1056E0000000000000100202002800008000FC0002 +:1056F000000000000D000D0002000A000000000084 +:105700000414B400000000100000000000110202A8 +:10571000002800008000FC00000000000D000D00CB +:1057200001000900000000000428B400000000107F +:105730000000000000120202002804008000FC00AB +:10574000000000000D000D00000008000000000037 +:1057500020B0B300000000104F00000001F404006E +:1057600068931B00600000000C00000001000400B2 +:105770001428000060000000300000002D008400AC +:10578000142800001C000000730000002DF48400A9 +:1057900068931B001C000000700000002DF48400C2 +:1057A00068931B001C000000730000002DF48400AF +:1057B00068931B001C000000630000002DF48400AF +:1057C00068931B001C0000004F00000001F404005F +:1057D00068931B00E00001000C00000001000400C1 +:1057E00014280000E0000100300000002D008400BB +:1057F000142800001C000000700000002DF484003C +:1058000068931B001C000000000000000000000066 +:105810000000000000000000000000000000000088 +:105820000000000000000000000000000000000078 +:105830000000000000000000000000000000000068 +:105840000000000000000000000000000000000058 +:105850000000000000000000000000000000000048 +:105860000000000000000000000000000000000038 +:1058700000000000000000000000000092249224BC +:105880009200920000000000224924492401A40053 +:105890000000000014492449240114010000000004 +:1058A000A4482449240122010000000024452429A1 +:1058B000240124010000000024292445240124019E +:1058C000000000002449A448220124010000000037 +:1058D00024491449140124010000000024492249EC +:1058E000A400240100000000FF7FFF7FFF01FF01F3 +:1058F00000000000B66DB66DB601B60100000000F4 +:10590000B26DB66DB601B60000000000966DB66DC2 +:10591000B601960100000000B66CB66DB601B2018A +:1059200000000000B665B62DB601B601000000000B +:10593000B62DB665B601B60100000000B66DB66CB6 +:10594000B201B60100000000B66D966D9601B60179 +:1059500000000000B66DB26DB600B6010000000098 +:10596000012800000000000000000000000000000E +:10597000000000020206AA006C768A94000106006C +:1059800000000000DB0600000106000091016E40EF +:10599000418C39030100009A1D018C610000000058 +:1059A0000000000010100D100390BBBB8E5A22188F +:1059B000641164118A39893985E00FE06612641236 +:1059C00001200000000000000000000000000000B6 +:1059D000000000020206AA006C768A94000106000C +:1059E00000000000DB0600000106000091016E408F +:1059F000418C39030100009A1D018C6100000000F8 +:105A00000000000010000C100380ABAA8044227834 +:105A1000641164118A39893985E005E066126412DF +:105A20000104000000000000000000000000000071 +:105A3000000000020200AA006C768A9400010600B1 +:105A400000000000DB060000040C000038066E2099 +:105A5000418C390301000084C4058C610000000002 +:105A60000000000010C40C500390BBBB804422789F +:105A7000641164118A39893985E00FE06612641275 +:105A8000D004020001020304CCF57AFDED20BF8FA3 +:105A9000CF0304021E0600036C768A940001060000 +:105AA00000000000DB06000001460000121B002081 +:105AB000006B39034100028400006B616478792B2C +:105AC000CF8A00801C5411980080BBBB00572278FD +:105AD000641164118A39893985E00FE06612641215 +:105AE0000100000001010101CCF57AFDED20BF8F1E +:105AF000CF030402020600006C768A9400010600BF +:105B000000000000DB060000000C0000401A00202E +:105B10004100380341000284000000606478792B62 +:105B2000CF8A00801C5410180380BBBB80462278AB +:105B3000641164118A39893985E00FE066126412B4 +:105B4000D004020002020202CCF57AFDED20BF8FE4 +:105B5000CF030402020600006C768A94000106005E +:105B600000000000DB06000001460000121B0020C0 +:105B7000006B39034100028400006B616478792B6B +:105B8000CF8A00801C5411980380BBBB80462278CA +:105B9000641164118A39893985E00FE06612641254 +:105BA0000100000003030303CCF57AFDED20BF8F55 +:105BB000CF030402020600006C768A9400010600FE +:105BC00000000000DB060000000C0000401A00206E +:105BD0004100380341000284000000606478792BA2 +:105BE000CF8A00801C5410180380BBBB80462278EB +:105BF000641164118A39893985E00FE066126412F4 +:105C0000D004020004040404CCF57AFDED20BF8F1B +:105C1000CF030402020600006C768A94000106009D +:105C200000000000DB06000001460000121B0020FF +:105C3000006B39034100028400006B616478792BAA +:105C4000CF8A00801C5411980380BBBB8046227809 +:105C5000641164118A39893985E00FE06612641293 +:105C60000100000000000000CCF57AFDED20BF8FA0 +:105C7000CF030402020600006C768A94000106003D +:105C800000000000DB060000000C0000FF3B0020CD +:105C90004100380341000284000000606478792BE1 +:105CA000CF8A00801CC410180300000000C62278B0 +:105CB000641164118039803905000F0055105510AA +:105CC000000000000000000000101000000092CD55 +:105CD0000000C180100F0002000087370000BBF1F8 +:105CE000100F00040000904100008B43100E0007CD +:105CF0000000BBF100009167100C000900001DFBC3 +:105D00000000709E100E000500000000C806000094 +:105D1000BAF15942BAF15942450EA63D1122334417 +:105D20005566778899AABBCCDDEEFF6900000000BC +:105D30000000000000000000000000000000000063 +:105D40000000000000000000C022C0224A4948476D +:105D5000464544434241403F3E3D3C3B3A3938375B +:105D6000363534333231302F2E2D2C2B2A2928274B +:105D7000262524232221201F1E1D1C1B1A1900006A +:105D80000000000000000000000000000000000013 +:105D90000000000031302F2E2D2C2B2A29282726F9 +:105DA0002524232221201F1E1D1C1B1A191817161B +:105DB0001514131211100F0E0D0C0B0A090807060B +:105DC00005040302010000000000000000000000C4 +:105DD0000000000000000000000000002000E0C003 +:105DE000A08060402000E0C0A08060402000E0C0B3 +:105DF000A08060402000E0C0A08060402000E0C0A3 +:105E0000A08060402000E0C0A08060402000000032 +:105E100076DBB62D2449921BDBB6491292942409F5 +:105E200009000000826446280AECCEB0927456380D +:105E30001AFCDEC0A28466482A0CEED0B2947658D2 +:105E40003A1CFEE0C2A486684A2C0EF0D2B49678C2 +:105E50005A3C1E00FFFF00006D5B922424B76D1BAF +:105E60009B244912499224010000003F533517F941 +:105E7000DBBD9F8163452709EBCDAF917355371982 +:105E8000FBDDBFA1836547290BEDCFB19375573972 +:105E90001BFDDFC1A38567492B0D8E7052340000B6 +:105EA0006D499224E4B66D1B9224490A499204007C +:105EB0000000B42D2002836547290BEDCFB1937507 +:105EC00057391BFDDFC1A38567492B0DEFD1B39572 +:105ED00077593B1DFFE1C3A587694B2D0FF1D3B562 +:105EE00097795B3D1F01000040DB962424C96D1BA0 +:105EF000DB264912529224090100000016F8DABC90 +:105F00009E8062442608EACCAE9072543618FADCC1 +:105F1000BEA0826446280AECCEB0927456381AFCB1 +:105F2000DEC0A28466482A0C8D6F513315F700003D +:105F300025499224DBB66D129224290949120000EA +:105F400000D0B6255D3F21038466482A0CEED0B20E +:105F50009476583A1CFEE0C2A486684A2C0EF0D211 +:105F6000B496785A3C1E00E2C4A6886A4C2E10F201 +:105F7000D4B6987A5C3E000000D0B6252449721B46 +:105F8000DBB6491292A4240949000000D9BB9D7FC9 +:105F900061432507E9CBAD8F71533517F9DBBD9F01 +:105FA0008163452709EBCDAF9173553719FBDDBFF1 +:105FB000A1836547290B8C6E503214F6D8BA0000C5 +:105FC0002449921BDBB6491292A42409490000001F +:105FD00040DB96249A7C5E4022048567492B0DEFB6 +:105FE000D1B39577593B1DFFE1C3A587694B2D0FB1 +:105FF000F1D3B597795B3D1F01E3C5A7896B4D2FA1 +:1060000011F3D5B7997B00000000B42D2549921CEF +:10601000DBB66D1292242909491200009C7E604271 +:106020002406E8CAAC8E70523416F8DABC9E806240 +:10603000442608EACCAE9072543618FADCBEA08230 +:106040006446280A8B6D4F3113F5D7B99B7D00004C +:1060500024496E1BDB26491292922409010000009C +:106060006D5B9224D7B99B7D5F41230586684A2CDE +:106070000EF0D2B496785A3C1E00E2C4A6886A4C50 +:106080002E10F2D4B6987A5C3E2002E4C6A88A6C40 +:106090004E3012F4D6B800000000002D6D49922455 +:1060A000E4B66D1B9224490A499204005F4123051E +:1060B000E7C9AB8D6F513315F7D9BB9D7F61432580 +:1060C00007E9CBAD8F71533517F9DBBD9F81634570 +:1060D00027098A6C4E3012F4D6B89A7C5E400000D4 +:1060E00024B96D1B9B2449124A9224010000002D03 +:1060F0006D49922414F6D8BA9C7E604224068769C2 +:106100004B2D0FF1D3B597795B3D1F01E3C5A789EF +:106110006B4D2F11F3D5B7997B5D3F2103E5C7A9DF +:106120008B6D4F3113F50000010000006D5B922470 +:1061300024B96D1B9B2449124A9224012204E6C80B +:10614000AA8C6E503214F6D8BA9C7E60422406E8BF +:10615000CAAC8E70523416F8DABC9E8062442608AF +:10616000FFFFFFFFFFFFFFFFFFFFFFFF2103000017 +:10617000E4B66D1B9224490A499204000000FC3FDA +:10618000FFFFFF24513315F7D9BB9D7F61432507DE +:10619000886A4C2E10F2D4B6987A5C3E2002E4C68F +:1061A000A88A6C4E3012F4D6B89A7C5E402204E67F +:1061B000C8AA8C6E503200004900000040DB9624D3 +:1061C00024496E1BDB26491292922409E5C7A98B4C +:1061D0006D4F3113F5D7B99B7D5F412305E7C9ABFF +:1061E0008D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:1061F000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000AD +:10620000DBB66D1292242909C9FFFF3FFFFFFF3F54 +:10621000FFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFF4E +:10622000FFFF896B4D2F11F3D5B7997B5D3FFFFFC2 +:10623000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:10624000FFFFFFFFFFFF0000FFFFFF3FFFDFB6255F +:106250002449FE3FFFFFFF3FFFFFFF3F5F5E5D5CA6 +:106260005B5A595857565554535251504F4E4D4CF6 +:106270004B4A494847464544434241403F3E3D3CE6 +:106280003B3A39383736353433323130FFFF00008E +:1062900000000000000000000000000000000000FE +:1062A0000000003F2F2E2D2C2B2A292827262524BD +:1062B000232221201F1E1D1C1B1A19181716151426 +:1062C000131211100F0E0D0C0B0A09080706050416 +:1062D00003020100FFFF00000000000000000000BA +:1062E00000000000000000000000003F000000006F +:1062F000000000000000000000000000000000009E +:10630000000000000000000000000000000000008D +:10631000000000000000000000000000000000007D +:10632000000000000000000000000000000000006D +:10633000000000000000000000000000000000005D +:10634000000000000000000000000000000000004D +:10635000000000000000000000000000000000003D +:10636000000000000000000000000000000000002D +:10637000000000000000000000000000000000001D +:10638000000000000000000000000000000000000D +:1063900000000000000000000000000000000000FD +:1063A00000000000000000000000000000000000ED +:1063B00000000000000000000000000000000000DD +:1063C00000000000000000000000000000000000CD +:1063D00000000000000000000000000000000000BD +:1063E00000000000000000000000000000000000AD +:1063F000000000000000000000000000000000009D +:10640000000000000000000000000000000000008C +:10641000000000000000000000000000000000007C +:10642000000000000000000000000000000000006C +:10643000000000000000000000000000000000005C +:10644000000000000000000000000000000000004C +:10645000000000000000000000000000000000003C +:10646000000000000000000000000000000000002C +:10647000000000000000000000000000000000001C +:10648000000000000000000000000000000000000C +:1064900000000000000000000000000000000000FC +:1064A00000000000000000000000000000000000EC +:1064B00000000000000000000000000000000000DC +:1064C00000000000000000000000000000000000CC +:1064D00000000000000000000000000000000000BC +:1064E00000000000000000000000000000000000AC +:1064F000000000000000000000000000000000009C +:10650000000000000000000000000000000000008B +:10651000000000000000000000000000000000007B +:10652000000000000000000000000000000000006B +:10653000000000000000000000000000000000005B +:10654000000000000000000000000000000000004B +:10655000000000000000000000000000000000003B +:10656000000000000000000000000000000000002B +:10657000000000000000000000000000000000001B +:10658000000000000000000000000000000000000B +:1065900000000000000000000000000000000000FB +:1065A00000000000000000000000000000000000EB +:1065B00000000000000000000000000000000000DB +:1065C00000000000000000000000000000000000CB +:1065D00000000000000000000000000000000000BB +:1065E00000000000000000000000000000000000AB +:1065F000000000000000000000000000000000009B +:10660000000000000000000000000000000000008A +:10661000000000000000000000000000000000007A +:10662000000000000000000000000000000000006A +:10663000000000000000000000000000000000005A +:10664000000000000000000000000000000000004A +:10665000000000000000000000000000000000003A +:10666000000000000000000000000000000000002A +:10667000000000000000000000000000000000001A +:10668000000000000000000000000000000000000A +:1066900000000000000000000000000000000000FA +:1066A00000000000000000000000000000000000EA +:1066B00000000000000000000000000000000000DA +:1066C00000000000000000000000000000000000CA +:1066D00000000000000000000000000000000000BA +:1066E00000000000000000000000000000000000AA +:1066F000000000000000000000000000000000009A +:106700000000000000000000000000000000000089 +:106710000000000000000000000000000000000079 +:106720000000000000000000000000000000000069 +:106730000000000000000000000000000000000059 +:106740000000000000000000000000000000000049 +:106750000000000000000000000000000000000039 +:106760000000000000000000000000000000000029 +:106770000000000000000000000000000000000019 +:106780000000000000000000000000000000000009 +:1067900000000000000000000000000000000000F9 +:1067A00000000000000000000000000000000000E9 +:1067B00000000000000000000000000000000000D9 +:1067C00000000000000000000000000000000000C9 +:1067D00000000000000000000000000000000000B9 +:1067E00000000000000000000000000000000000A9 +:1067F0000000000000000000000000000000000099 +:106800000000000000000000000000000000000088 +:106810000000000000000000000000000000000078 +:106820000000000000000000000000000000000068 +:106830000000000000000000000000000000000058 +:106840000000000000000000000000000000000048 +:106850000000000000000000000000000000000038 +:106860000000000000000000000000000000000028 +:106870000000000000000000000000000000000018 +:106880000000000000000000000000000000000008 +:1068900000000000000000000000000000000000F8 +:1068A00000000000000000000000000000000000E8 +:1068B00000000000000000000000000000000000D8 +:1068C00000000000000000000000000000000000C8 +:1068D00000000000000000000000000000000000B8 +:1068E00000000000000000000000000000000000A8 +:1068F0000000000000000000000000000000000098 +:106900000000000000000000000000000000000087 +:106910000000000000000000000000000000000077 +:106920000000000000000000000000000000000067 +:106930000000000000000000000000000000000057 +:106940000000000000000000000000000000000047 +:106950000000000000000000000000000000000037 +:106960000000000000000000000000000000000027 +:106970000000000000000000000000000000000017 +:106980000000000000000000000000000000000007 +:1069900000000000000000000000000000000000F7 +:1069A00000000000000000000000000000000000E7 +:1069B00000000000000000000000000000000000D7 +:1069C00000000000000000000000000000000000C7 +:1069D00000000000000000000000000000000000B7 +:1069E00000000000000000000000000000000000A7 +:1069F0000000000000000000000000000000000097 +:106A0000150101000000000000000000320210002B +:106A10001000000000000000000000000000000066 +:106A200099120000BC120000DF12000002130000E7 +:106A300025130000481300006B1300008E130000A4 +:106A4000B1130000D4130000F71300001A14000063 +:106A50003D1400006014000083140000A614000020 +:106A6000C914000020030000D4B804020351180721 +:106A7000C8388E232310080344611C08000000005E +:106A800000000000190000005B555555555555553F +:106A90005555555505000000080A0000000000008B +:106AA000010000000000000002F80000EC14541681 +:106AB00084167E17411AA2176A199119B1197E1707 +:106AC00007B8C307008000002083000000803280E8 +:106AD000648096802DB4040F110C0F0F10000F135B +:106AE000A5BA830A18C80F001510151010431043DB +:106AF00020030000D4A8040C42330E0EC4338E23AE +:106B000063011911E32101132302000000000000BA +:106B10001B0000005B555555555555555555555558 +:106B20005505000098090B0BB0B00000B0B0001B79 +:106B30000B00000082F01002EC14541684167E172D +:106B4000411AA2176A199119B1197E1707B8C3071C +:106B500000800000208300000080328064809680E6 +:106B60002DB4040F110C0F0F10000F13A5BA830AD8 +:106B700018C80F0015101510104310432003000013 +:106B800009000000000000000000000000000000FC +:106B900000000000000000000000000001000000F4 +:106BA00003000000000000000000000000000000E2 +:106BB00002000000000000000000000000000000D3 +:106BC00000000000EC14541684167E17411AA21718 +:106BD0006A199119B1197E1707B8C3070080000020 +:106BE0002083000000803280648096802DB4040FE2 +:106BF000110C0F0F10000F13A5BA830A18C80F004D +:106C0000151015101043104320030000D4B80402DF +:106C100003511807C8388E232310080344611C0849 +:106C20000000000000000000190000005B555555F1 +:106C3000555555555555555555000000086A666619 +:106C400066666666636666666600000002F80000B7 +:106C5000EC14541684167E17411AA2176A1991195A +:106C6000B1197E1707B8C307008000002083000019 +:106C700000803280648096802DB4040F110C0F0FB9 +:106C800010000F13A5BA830A18C80F0015101510AD +:106C90001043104320030000D4A8040C42330E0E0E +:106CA000C4338E2363011911E32101132302000071 +:106CB000000000001B0000005B555555555555550B +:106CC000555555555505000098696B6BB6B6666607 +:106CD000B6B6663B6B06000082F01002EC14541648 +:106CE00084167E17411AA2176A199119B1197E17D5 +:106CF00007B8C307008000002083000000803280B6 +:106D0000648096802DB4040F110C0F0F10000F1328 +:106D1000A5BA830A18C80F001510151010431043A8 +:106D200020030000D4B8541617960100000000009C +:106D30000000000000000000000000000000000053 +:106D4000080000005B5555550000000000000000E1 +:106D500000000000081A11110000000000000000EF +:106D60000000000002000000EC14541684167E1788 +:106D7000411AA2176A199119B1197E1707B8C307EA +:106D800000800000208300000080328064809680B4 +:106D90002DB4040F110C0F0F10000F13A5BA830AA6 +:106DA00018C80F00151015101043104320030000E1 +:106DB000D4B854161796010000000000000000002F +:106DC00000000000000000000000000008000000BB +:106DD0005B55555500000000000000000000000059 +:106DE000083A3333000000000000000000000000FB +:106DF00002000000EC14541684167E17411AA217E4 +:106E00006A199119B1197E1707B8C30700800000ED +:106E10002083000000803280648096802DB4040FAF +:106E2000110C0F0F10000F13A5BA830A18C80F001A +:106E3000151015101043104320030000D4A8540C63 +:106E4000567339184F068D11A3344E000000000010 +:106E50000000000000000000130000005B555555C5 +:106E600055555555550500000000000008191B1B1D +:106E70001B1B0B0B0B0B00000000000002A002000C +:106E8000EC14541684167E17411AA2176A19911928 +:106E9000B1197E1707B8C3070080000020830000E7 +:106EA00000803280648096802DB4040F110C0F0F87 +:106EB00010000F13A5BA830A18C80F00151015107B +:106EC0001043104320030000D4A8540C5673391803 +:106ED0004F068D11A3344E0000000000000000009A +:106EE00000000000130000005B55555555555555E1 +:106EF000550500000000000008393B3B3B3B0B0BF5 +:106F00000B0B00000000000002A00200EC1454165D +:106F100084167E17411AA2176A199119B1197E17A2 +:106F200007B8C30700800000208300000080328083 +:106F3000648096802DB4040F110C0F0F10000F13F6 +:106F4000A5BA830A18C80F00151015101043104376 +:106F500020030000D4A8051B023774045E311A23F5 +:106F6000C7088C08000000000000000000000000BE +:106F7000140000005B5555555555555555550000A5 +:106F800000000000080909090909000010000000BC +:106F90000000000002500500EC14541684167E1701 +:106FA000411AA2176A199119B1197E1707B8C307B8 +:106FB0000080000020830000008032806480968082 +:106FC0002DB4040F110C0F0F10000F13A5BA830A74 +:106FD00018C80F00151015101043104320030000AF +:106FE000D4A8051B023774045E311A23C7088C0825 +:106FF000000000000000000000000000140000007D +:107000005B55555555555555555500000000000028 +:10701000086969696969606030600000000000000B +:1070200002500500EC14541684167E17411AA2175C +:107030006A199119B1197E1707B8C30700800000BB +:107040002083000000803280648096802DB4040F7D +:10705000110C0F0F10000F13A5BA830A18C80F00E8 +:10706000151015101043104320030000D4A8551B21 +:10707000167775185E060000000000000000000092 +:1070800000000000000000000C0000005B5555559A +:1070900055550000000000000000000008191919F3 +:1070A00019190000000000000000000002000000AC +:1070B000EC14541684167E17411AA2176A199119F6 +:1070C000B1197E1707B8C3070080000020830000B5 +:1070D00000803280648096802DB4040F110C0F0F55 +:1070E00010000F13A5BA830A18C80F001510151049 +:1070F0001043104320030000D4A8551B16777518C1 +:107100005E0600000000000000000000000000001B +:10711000000000000C0000005B555555555500005F +:10712000000000000000000008393939393900003A +:10713000000000000000000002000000EC145416E3 +:1071400084167E17411AA2176A199119B1197E1770 +:1071500007B8C30700800000208300000080328051 +:10716000648096802DB4040F110C0F0F10000F13C4 +:10717000A5BA830A18C80F00151015101043104344 +:107180002003000081301005067020000000000080 +:1071900000000000000000000000000000000000EF +:1071A000090000005555555505000000000000007D +:1071B00000000000000000010000000000000000CE +:1071C0000000000000000000EC14541684167E1726 +:1071D000411AA2176A199119B1197E1707B8C30786 +:1071E0000080000020830000008032806480968050 +:1071F0002DB4040F110C0F0F10000F13A5BA830A42 +:1072000018C80F001510151010431043200300007C +:10721000D4B80000000000000000000000000000E2 +:10722000000000000000000000000000030000005B +:107230005B050000000000000000000000000000EE +:10724000080A00000000000000000000000000002C +:1072500002000000EC14541684167E17411AA2177F +:107260006A199119B1197E1707B8C3070080000089 +:107270002083000000803280648096802DB4040F4B +:10728000110C0F0F10000F13A5BA830A18C80F00B6 +:10729000151015101043104320030000547261199B +:1072A0001A000000000000000000000000000000C4 +:1072B00000000000000000000200000046555500DC +:1072C0000000000000000000000000002899990064 +:1072D00000000000000000000000000000000000AE +:1072E000EC14541684167E17411AA2176A199119C4 +:1072F000B1197E1707B8C307008000002083000083 +:1073000000803280648096802DB4040F110C0F0F22 +:1073100010000F13A5BA830A18C80F001510151016 +:1073200010431043200300008C7561191A000000FF +:10733000000000000000000000000000000000004D +:10734000000000000100000054555500000000003E +:1073500000000000000000009B9999000000000060 +:10736000000000000000000000000000EC145416B3 +:1073700084167E17411AA2176A199119B1197E173E +:1073800007B8C3070080000020830000008032801F +:10739000648096802DB4040F110C0F0F10000F1392 +:1073A000A5BA830A18C80F00151015101043104312 +:1073B0000000000000000001000003000000FC00CD +:1073C000000000000D000D0008072107000000006C +:1073D0000155B4000200000000000000010103029A +:1073E000000001000000FC00000000000D000D0086 +:1073F00010001F000000000004B0B30000000010E7 +:107400000000000002020302000001000000FC0076 +:10741000000000000D000D0011001E000000000023 +:1074200004C4B300000000100000000003030302C6 +:10743000000001000000FC00000000000D000D0035 +:1074400012001D000000000004D8B300000000106E +:107450000000000004040302000001000000FC0022 +:10746000000000000D000D0013001C0000000000D3 +:1074700004ECB3000000001000000000050503024A +:10748000000001000000FC00000000000D000D00E5 +:1074900014001B00000000000400B40000000010F5 +:1074A0000000000006060302000001000000FC00CE +:1074B000000000000D000D0015001A000000000083 +:1074C0000414B400000000100000000007070302CD +:1074D000000001000000FC00000000000D000D0095 +:1074E00016001900000000000428B400000000107D +:1074F0000000000008080302000005000000FC0076 +:10750000000000000D000D00170018000000000032 +:10751000043CB4000000001000000000090000015D +:10752000000007000000FC00000000000D000D003E +:1075300004101D10000000000150B4000000000005 +:107540000000000000000001000003000000FC003B +:10755000000000000D000D008917701700000000EA +:1075600001A0B40006000000000000000000171792 +:10757000000003000000FC00000000000D000D00F2 +:107580009C189D1800000000019BB400040000003E +:107590000000000000001616000003000000FD00BF +:1075A000000000000D000D00301138110000FE2514 +:1075B0000473B4000400000000000000000017176E +:1075C000000003000000FC00000000000D000D00A2 +:1075D000C012C1120000FE250487B40004000000A0 +:1075E0000000000000001616000003000000FD006F +:1075F000000000000D000D00301138110000FE25C4 +:107600000473B4000400000000000000000017171D +:10761000000003000000FC00000000000D000D0051 +:10762000C012C1120000FE250487B400040000004F +:107630000000000000001616000003000000FD001E +:10764000000000000D000D00301138110000FE2573 +:107650000473B400040000000000000000001717CD +:10766000000003000000FC00000000000D000D0001 +:10767000C012C1120000FE250487B40004000000FF +:107680000000000000001616000003000000FD00CE +:10769000000000000D000D00301138110000FE2523 +:1076A0000473B4000400000000000000000017177D +:1076B000000003000000FC00000000000D000D00B1 +:1076C000C012C1120000FE250487B40004000000AF +:1076D00000000000000A1414002802000000FC0052 +:1076E0000000000005000500000000000000000090 +:1076F00001009703000000000000000000000100EE +:10770000002802000000FC00000000000D000D0039 +:10771000C800E10000000000015AB40002000000AF +:107720000000000000000100002802000000FC0032 +:10773000000000000D000D00580271020000000062 +:10774000015FB40002000000000000000000010022 +:10775000002802000000FC00000000000D000D00E9 +:10776000E8030104000000000164B400020000000E +:107770000000000000000100002802000000FC00E2 +:10778000000000000D000D007805910500000000CC +:107790000169B400020000000000000000000100C8 +:1077A000002802000000FC00000000000D000D0099 +:1077B0000807210700000000016EB400020000006D +:1077C0000000000000000100002802000000FC0092 +:1077D000000000000D000D003011491100000000F4 +:1077E00001A5B40006000000000000000000010038 +:1077F000002802000000FC00000000000D000D0049 +:10780000C012D9120000000001AAB4000600000056 +:107810000000000000000100002802000000FC0041 +:10782000000000000D000D0050146914000000005D +:1078300001AFB400060000000000000000000100DD +:10784000002802000000FC00000000000D000D00F8 +:10785000E015F9150000000001B4B40006000000B6 +:107860000000000000000100002802000000FC00F1 +:10787000000000000D000D007017891700000000C7 +:1078800001B9B40006000000000000000000010083 +:10789000002802000000FC000000000009000900B0 +:1078A0000000000000000000010097030600000037 +:1078B00000000000000B1414002802000000FC006F +:1078C000000000000C000C000000000000000000A0 +:1078D000010097030000000000000000000B1414DA +:1078E000002802000000FC003F0000000C000C001B +:1078F00000000000000000000100970300000000ED +:1079000000000000000B1515002802000000CC004C +:10791000000000000C000C0000000000000000004F +:1079200001009703000000000000000000000100BB +:10793000002802000000FC00000000000D000D0007 +:107940000000000000000000010097030600000096 +:107950004F00000001F4040068931B006000000069 +:107960000C0000000100040014280000600000006A +:10797000300000002D008400142800001C000000CE +:10798000730000002DF4840068931B001C000000AD +:10799000700000002DF4840068931B001C000000A0 +:1079A0007300000023F4840068931B001C00000097 +:1079B000600000002DF4840068931B001C00000090 +:1079C0004F00000001F4040068931B00E000010078 +:1079D0000C0000000100040014280000E000010079 +:1079E000300000002D008400142800001C0000005E +:1079F000700000002DF4840068931B001C00000040 +:107A0000730000002DF4840051651B001C00000071 +:107A10000101010101010101010101010101010156 +:107A20000101010101010101010101010101010146 +:107A30000101010101010101010101010101010136 +:107A40000101010101010101010101010101010126 +:107A50000101010101010101010101010101010116 +:107A60000101010101010101010101010101010106 +:107A70000101010133343A3335333534333433358E +:107A800033343233343334333334333334333333C2 +:107A900034343233343433333334323334333433B1 +:107AA00033343334353233333332323233333233A7 +:107AB00032333231333232323033323331323232A6 +:107AC0003231323232323232323231323332313298 +:107AD000313432342F2F2F3033343A333533353479 +:107AE0003334333533343233343334333334333360 +:107AF0003433333334333233343433333334323353 +:107B00003333333333353334353233333332323244 +:107B10003333323332333231333232323033323341 +:107B20003132323232313232323232323232313238 +:107B300033323132313432342F2F2F303334333328 +:107B400034333434333333353334333334333433FD +:107B500033343333343333333434333334343333EF +:107B600033343233343333333335333434323332E2 +:107B700033333232333332323233323133323232E0 +:107B800030333232313232313231323132323132DB +:107B90003232313232323132313332332F2F2E30D2 +:107BA000333433333433343433333335333433339E +:107BB000343334333334333334333333343433338F +:107BC0003434333333343233333333333335333480 +:107BD000343233323333323233333233323332317D +:107BE0003332323231333233313232323231323176 +:107BF0003232313232323132333231323133323366 +:107C00002F2F2E3033343233343334333333333550 +:107C10003334333334333433333433333333333330 +:107C20003433333234343333333432333333333322 +:107C30003335333434323332333232323333323217 +:107C40003233323133323232303332323132323116 +:107C50003231323132323132323231323332313208 +:107C6000313332332F2F2E2F3334323334333434F5 +:107C700033333335333433333433343333343333CE +:107C800034333333343333333434333333343233C0 +:107C900033333333333533343432333233323232B5 +:107CA00033333233323332313332323231333233AF +:107CB00031323231323132323232313232323132A9 +:107CC00033323132313332332F2F2E2F333532329C +:107CD000343333333334333433343333343334336E +:107CE000333433333433333334343332343433335F +:107CF0003334323333333333333533343432333252 +:107D00003332323233333232323232313332323250 +:107D1000303332333132313132313131323231324A +:107D20003232313232323132313332332F2F2E3040 +:107D3000333532323433333333343334333433330F +:107D400034333433333433333333333334343332FF +:107D500034343333333432333333333333353334EE +:107D600034323332333232323333323232333231ED +:107D700033323232303332333132323232313232E4 +:107D800032323132323231323232313231333233D5 +:107D90002F2F2E2F4F51534F4F4D514D4F4F4D5170 +:107DA0004D4F4F514F4F534F4B515151534D534DD9 +:107DB0004F4D4F515151514F4F4F4F4F514D514FCB +:107DC0004F515153534F5151514F514F4F4E4F4FB0 +:107DD0004B4F4F4F4F4D4F514B4F4F514F4D4F51B9 +:107DE0004D4F4F4D4F4B4D51514F4F4F4F4D4D4FAD +:107DF0004B4D4F514D494B4D92249224920092008D +:107E000000000000B66DB66DB600B60000000000C0 +:107E1000B66DB66D9601960100000000B66DB66DA8 +:107E2000B201B20100000000B62DB62DB601B601B8 +:107E300000000000B665B665B601B601000000009E +:107E4000B66CB66CB601B60100000000966D966D7A +:107E5000B601B60100000000B26DB26DB601B60108 +:107E600000000000FF7FFF7FFF01FF010000000016 +:107E7000B66DB66DB601B6010000000092249224E2 +:107E800092009200000000000110000000000000BD +:107E900000000000FFFF3DDB38D4FC020200AA0016 +:107EA0006C768A940001060000000000DB060000EA +:107EB000040C000060056E40415639030100009A31 +:107EC000EC045661000000000000000010C40C50DB +:107ED0000390BBBB804422786411641189398939CD +:107EE0000FE00FE0641264120110000000000000B7 +:107EF00000000000FFFF3DDB38D4FC020200AA00B6 +:107F00006C768A940001060000000000DB06000089 +:107F1000040C000060056E40415639030100009AD0 +:107F2000EC045661000000000000000010C40C10BA +:107F3000E39EBBBB8055227864116411893989396D +:107F40000FE00FE064126412010400000000000062 +:107F50000000000000000000000000020200AA0073 +:107F60006C768A940001060000000000DB06000029 +:107F7000040C000020066E40418639030100009A7F +:107F8000AC058661000000000000000010C40C5029 +:107F90000390BBBB8044227864116411893989390C +:107FA0000FE00FE064126412C9040200010203042E +:107FB000EAF7FAFD3001A880CF0304021E00000397 +:107FC0006C768A940001060000000000DB060000C9 +:107FD000014600002B1A0040006B39034100029A51 +:107FE00000006B616478792BCF8A00801C54119853 +:107FF0000080BBBB0057227864116411893989392C +:108000000FF00FF064126412C904020001010101B3 +:10801000EAF7FAFD3001A880CF0304020200000055 +:108020006C768A940001060000000000DB06000068 +:10803000014600002B1A0040006B39034100029AF0 +:1080400000006B619A7F0A0AFFFF00801C541198A0 +:108050000380BBBB80462278641164118939893959 +:108060000FF00FF064126412C9040200020202024F +:10807000EAF7FAFD3001A880CF03040202000000F5 +:108080006C768A940001060000000000DB06000008 +:10809000014600002B1A0040006B39034100029A90 +:1080A00000006B616C7E0614FFFF00801C54119869 +:1080B0000380BBBB804622786411641189398939F9 +:1080C0000FF00FF064126412C904020003030303EB +:1080D000EAF7FAFD3001A880CF0304020200000095 +:1080E0006C768A940001060000000000DB060000A8 +:1080F000014600002B1A0040006B39034100029A30 +:1081000000006B61767CE11DFFFF00801C5411981C +:108110000380BBBB80462278641164118939893998 +:108120000FF00FF064126412C90402000404040486 +:10813000EAF7FAFD3001A880CF0304020200000034 +:108140006C768A940001060000000000DB06000047 +:10815000014600002B1A0040006B39034100029ACF +:1081600000006B61BC798D27FFFF00801C541198C3 +:108170000380BBBB80462278641164118939893938 +:108180000FF00FF0641264120104000400000000FC +:10819000CCF57AFDED20BF8FCF030402020600006C +:1081A0006C768A940001060000000000DB060000E7 +:1081B00001060000093C0040006B39034100029AAF +:1081C00000006B616478792BCF8A00801CC4101882 +:1081D0000380ABAA00C6227864116411803980390B +:1081E0000F000F00550D550DC904020006070A0BBC +:1081F000EAF7FAFD3001A880CF0304021E0600034F +:108200006C768A940001060000000000DB06000086 +:10821000014600002B1A0040006B39034100029A0E +:1082200000006B616478792BCF8A00801C54119810 +:108230000080BBBB00572218641164118939893949 +:108240000FF00FF064126412C9040200060606065D +:10825000EAF7FAFD3001A880CF030402020600000D +:108260006C768A940001060000000000DB06000026 +:10827000014600002B1A0040006B39034100029AAE +:1082800000006B616478792BCF8A00801C541198B0 +:108290000080BBBB005722186411641189398939E9 +:1082A0000FF00FF064126412C904020006060A0AF5 +:1082B00073EDFAFD5985A880CF0304020A06010078 +:1082C0006C768A940043060100000000DB06000083 +:1082D000014600002B1A0040006B39034100029A4E +:1082E00000006B619367CBB40000008012541198BA +:1082F0000080BBBB0056221864116411893989398A +:108300000FF00FF064126412C904020007070B0B90 +:1083100073EDFAFD5985A880CF0304020A06010017 +:108320006C768A940043060100000000DB06000022 +:10833000014600002B1A0040006B39034100029AED +:1083400000006B6155737BC80000008012541198C7 +:108350000080BBBB00562218641164118939893929 +:108360000FF00FF064126412C904020009090C0C2A +:1083700073EDFAFD5985A880CF0304020A060100B7 +:108380006C768A940043060100000000DB060000C2 +:10839000014600002B1A0040006B39034100029A8D +:1083A00000006B61D9770ED3000000801254119841 +:1083B0000080BBBB005622186411641189398939C9 +:1083C0000FF00FF064126412C90402000A0A0606D4 +:1083D00073EDFAFD5985A880CF0304020A06010057 +:1083E0006C768A940043060100000000DB06000062 +:1083F000014600002B1A0040006B39034100029A2D +:1084000000006B61BD7977D800000080125411988C +:108410000080BBBB00562218641164118939893968 +:108420000FF00FF064126412C90402000B0B07076F +:1084300073EDFAFD5985A880CF0304020A060100F6 +:108440006C768A940043060100000000DB06000001 +:10845000014600002B1A0040006B39034100029ACC +:1084600000006B61757B34DE0000008012541198AF +:108470000080BBBB00562218641164118939893908 +:108480000FF00FF064126412C90402000A0A060613 +:1084900073EDFAFD5985A880CF0304020A06010096 +:1084A0006C768A940043060100000000DB060000A1 +:1084B000014600002B1A0040006B39034100029A6C +:1084C00000006B61CB7C87E30000008012541198A0 +:1084D0000080BBBB005622186411641189398939A8 +:1084E0000FF00FF064126412C90402000B0B0707AF +:1084F00073EDFAFD5985A880CF0304020A06010036 +:108500006C768A940043060100000000DB06000040 +:10851000014600002B1A0040006B39034100029A0B +:1085200000006B61F27D29E900000080125411986F +:108530000080BBBB00562218641164118939893947 +:108540000FF00FF064126412C90402000C0C090948 +:1085500073EDFAFD5985A880CF0304020A060100D5 +:108560006C768A940043060100000000DB060000E0 +:10857000014600002B1A0040006B39034100029AAB +:1085800000006B61D57EC2EE00000080125411988D +:108590000080BBBB005622186411641189398939E7 +:1085A0000FF00FF0641264120000000000000000E1 +:1085B00000101000000060CA00009B94100F000221 +:1085C0000000E92A0000EA17100F00050000C82586 +:1085D00000001579100E00070000D3C100002AA882 +:1085E000100C00090000C15A00009C9A00041030D1 +:1085F0000000BCA00000903800091033000083D0B8 +:108600000000D635000B10350000C9C200001A5911 +:10861000000C103600008CA100002C9F000D1037BC +:1086200000009851000044DC000E10380000BEEA43 +:108630000000A536000E103A000026620000DD9909 +:10864000000F103B000000008C00000073000000D1 +:1086500073000000660000003F0000003F000000C3 +:1086600033000000260000000000000000000000B1 +:1086700000000000000000000000000000000000FA +:1086800000000000000000000000000000000000EA +:1086900000000000000000000000000000000000DA +:1086A00000000000000000000000000000000000CA +:1086B00000000000000000000000000000000000BA +:1086C00000000000870700008579385793F930A132 +:1086D000B3D4CC2BCB0AF200000000000000000055 +:1086E000000000000000000000000000000000008A +:1086F000000000000000000000000000000000007A +:1087000080220022870700008579385793E4C2B998 +:1087100030AFCC2BC5A1B30000000000000000006A +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:1087400080220022870700008579385793E4C2BC55 +:10875000C2BCD7930D79300000000000000000007B +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800080220022870700008579385793E4C2BF12 +:10879000930ACC2BC4F50D0000000000000000007F +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00080220022870700008579385793E4C2BFD2 +:1087D000930AE4C2B286CF0000000000000000004F +:1087E0000000000000000000000000000000000089 +:1087F0000000000000000000000000000000000079 +:1088000080220022870700008579385793E4C2BF91 +:10881000930AB0AF26CF5000000000000000000017 +:108820000000000000000000000000000000000048 +:108830000000000000000000000000000000000038 +:1088400080220022870700008579385793E4C2BB55 +:108850000AF2E4C2BE4C2B00000000000000000041 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800080220022870700008579385793E4C2BB15 +:108890000AF2B0AF295E4C000000000000000000AA +:1088A00000000000000000000000000000000000C8 +:1088B00000000000000000000000000000000000B8 +:1088C00080220022C8060000450EA63D450EA63DAA +:1088D000BAF15942450EA63D450EA63D450EA63DB0 +:1088E000450EA63D00000000000000000000000052 +:1088F0000000000000000000000000000000000078 +:108900008022002231302F2E2D2C2B2A2928272699 +:108910002524232221201F1E1D1C1B1A191817167F +:108920001514131211100F0E0D0C0B0A090807066F +:108930000504030201000000000000000000000028 +:108940000000000000000000000000004A49484705 +:10895000464544434241403F3E3D3C3B3A3938372F +:10896000363534333231302F2E2D2C2B2A2928271F +:10897000262524232221201F1E1D1C1B1A1900003E +:1089800000000000000000000000000000000000E7 +:10899000000000002000E0C0A08060402000E0C097 +:1089A000A08060402000E0C0A08060402000E0C0C7 +:1089B000A08060402000E0C0A08060402000E0C0B7 +:1089C000A08060402000000076DBB62D2449921B79 +:1089D000DBB6491292942409090000002000E0C08F +:1089E000A08060402000E0C0A08060402000E0C087 +:1089F000A08060402000E0C0A08060402000E0C077 +:108A0000A08060402000E0C0A08060402000000006 +:108A100076DBB62D2449921BDBB6491292942409C9 +:108A2000090000002021E0E1A0A160612021E0E137 +:108A3000A0A160612021E0E1A0A160612021E0E12E +:108A4000A0A160612021E0E1A0A160612021E0E11E +:108A5000A0A160612021000076DBB62D2449921B85 +:108A6000DBB6491292942409090000000100C1C03C +:108A7000818041400100C1C0818041400100C1C0EE +:108A8000818041400100C1C0818041400100C1C0DE +:108A9000818041400100C1C081804140010000004F +:108AA00076DBB62D2449921BDBB649129294240939 +:108AB000090000002120E1E0A1A061602120E1E0A7 +:108AC000A1A061602120E1E0A1A061602120E1E09E +:108AD000A1A061602120E1E0A1A061602120E1E08E +:108AE000A1A061602120000076DBB62D2449921BF5 +:108AF000DBB6491292942409090000007353331322 +:108B0000F2D2B29272523212F2D2B2927252321245 +:108B1000F2D2B29272523212F2D2B2927252321235 +:108B2000F2D2B29272523212F2D2B2927252000069 +:108B300000D0B62D2D499224DBB66D129224250962 +:108B4000490200003C1CFCDCBC9C7C5C3C1CFCDC4A +:108B5000BC9C7C5C3C1CFCDCBC9C7C5C3C1CFCDC55 +:108B6000BC9C7C5C3C1CFCDCBC9C7C5C3C1CFBDB47 +:108B7000BB9B7B5B3B1B00002D499224DBB66D1237 +:108B8000922425094902000040DBB62DB4947454A8 +:108B90003414F3D3B39373533313F3D3B3937353A3 +:108BA0003313F3D3B39373533313F3D3B393735395 +:108BB0003313F3D3B39373533313F3D3B39300004B +:108BC0000000B42D6D4B9224E4B66D1B922449092C +:108BD00049920000FBDBBB9B7B5B3B1BFBDBBB9B36 +:108BE0007B5B3B1BFBDBBB9B7B5B3B1BFBDBBB9BD5 +:108BF0007B5B3B1BFBDBBB9B7B5B3B1BFADABA9AC9 +:108C00007A5A3A1AFADA00002449921BDBB6491262 +:108C100092942409090000006DDBB624F5D5B595C2 +:108C200075553515F4D4B49474543414F4D4B49400 +:108C300074543414F4D4B49474543414F4D4B494F4 +:108C400074543414F4D4B49474543414F4D400002C +:108C50000000002D6DDB922424B96D1B9B2449126A +:108C600049922400BA9A7A5A3A1AFADABA9A7A5A8D +:108C70003A1AFADABA9A7A5A3A1AFADABA9A7A5A54 +:108C80003A1AFADABA9A7A5A3A1AF9D9B99979594A +:108C90003919F9D9B999000024496E1BDB2649120C +:108CA000529224090000002D6DDB92243616F6D670 +:108CB000B69676563616F5D5B59575553515F5D55E +:108CC000B59575553515F5D5B59575553515F5D554 +:108CD000B59575553515F5D5B5957555351500000E +:108CE000090000006DDBB62424496E1BDB26491207 +:108CF0005292240979593919F9D9B99979593919F7 +:108D0000F9D9B99979593919F9D9B99979593919D3 +:108D1000F9D9B99979593919F8D8B89878583818CB +:108D2000F8D8B8987858000024B96D1B9B244912D4 +:108D3000499224000000B42D6D4B922477573717C9 +:108D4000F7D7B79777573717F6D6B69676563616BB +:108D5000F6D6B69676563616F6D6B69676563616B3 +:108D6000F6D6B69676563616F6D6B69676560000EF +:108D70004902000040DBB62D2449921BDBB64912A4 +:108D8000929424093818F8D8B89878583818F8D830 +:108D9000B89878583818F8D8B89878583818F8D853 +:108DA000B89878583818FFFFFFFFFFFFFFFFFFFF5D +:108DB000FFFFFFFFFFFF0000E4B66D1B922449098F +:108DC0004992000000F0FF3FFFFFFF3FFFFFFFFF62 +:108DD000FFFFFFFFFFFFFFFFFFFFF7D7B7977757B3 +:108DE0003717F7D7B79777573717F7D7B797775713 +:108DF0003717F7D7B79777573717F7D7B7970000D1 +:108E0000FFFFFF3FFFDFB62D2D499224DBB66D1229 +:108E100092242509636261605F5E5D5C5B5A59580C +:108E200057565554535251504F4E4D4C4B4A49484A +:108E300047464544434241403F3E3D3C3B3A39383A +:108E400037363534333200000000000000000000E7 +:108E500000000000000000000000000031302F2E54 +:108E60002D2C2B2A292827262524232221201F1EAA +:108E70001D1C1B1A191817161514131211100F0E9A +:108E80000D0C0B0A09080706050403020100000087 +:108E900000000000000000000000000000000000D2 +:108EA00000000000FFFFFFFFFFFFFFFFFFFFFFFFCE +:108EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:108EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:108ED000FFFFFFFFFFFF0000FFFFFF3FFFFFFF3F20 +:108EE000FFFFFF3FFFFFFF3FFFFFFF3FFFFFFFFFD2 +:108EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:108F0000FFFFFFFFFFFFFFFFFFFF0000000000006B +:108F10000000000000000000000000000000000051 +:108F2000FFFFFF3FFFFFFF3FFFFFFF3F000000008D +:108F30000000000057473727170756463626160603 +:108F4000554535251505544434241404534333231F +:108F50001303524232221202514131211101504079 +:108F600030201000FFFF00000000000000000000A3 +:108F700000000000000000000000003F62605E5C36 +:108F80005A58565452504E4C4A48464442403E3C31 +:108F90003A38363432302E2C2A28262422201E1C21 +:108FA0001A18161412100E0C0A080604020000000B +:108FB00000000000000000000000000000000000B1 +:108FC00000000000000000000000000000000000A1 +:108FD0000000000000000000000000000000000091 +:108FE0000000000000000000000000000000000081 +:108FF0000000000000000000000000000000000071 +:109000000000000000000000000000000000000060 +:109010000000000000000000000000000000000050 +:109020000000000000000000000000000000000040 +:109030000000000000000000000000000000000030 +:109040000000000000000000000000000000000020 +:109050000000000000000000000000000000000010 +:109060000000000000000000000000000000000000 +:1090700000000000000000000000000000000000F0 +:1090800000000000000000000000000000000000E0 +:1090900000000000000000000000000000000000D0 +:1090A00000000000000000000000000000000000C0 +:1090B00000000000000000000000000000000000B0 +:1090C00000000000000000000000000000000000A0 +:1090D0000000000000000000000000000000000090 +:1090E0000000000000000000000000000000000080 +:1090F0000000000000000000000000000000000070 +:10910000000000000000000000000000000000005F +:10911000000000000000000000000000000000004F +:10912000000000000000000000000000000000003F +:10913000000000000000000000000000000000002F +:10914000000000000000000000000000000000001F +:10915000000000000000000000000000000000000F +:1091600000000000000000000000000000000000FF +:1091700000000000000000000000000000000000EF +:1091800000000000000000000000000000000000DF +:1091900000000000000000000000000000000000CF +:1091A00000000000000000000000000000000000BF +:1091B00000000000000000000000000000000000AF +:1091C000000000000000000000000000000000009F +:1091D000000000000000000000000000000000008F +:1091E000000000000000000000000000000000007F +:1091F000000000000000000000000000000000006F +:109200000801010000000000000000003202100010 +:109210001B00000000000000000000000000000033 +:109220008C1C0000AF1C0000D21C0000F51C0000CC +:10923000200300004110080344611C0800000000E6 +:10924000000000000000000000000000000000001E +:109250000A00000066666666560000000000000016 +:1092600000000000000000000000000000000000FE +:109270000000000003000000181DD61D061E1F1E62 +:10928000531F581E301F421F431F7E1707B8C307C6 +:10929000008000002083000000803280648096807F +:1092A0002DB4040F110C0F0F10000F13A5BA030AF1 +:1092B00018C80F00151015101043104320030000AC +:1092C000CBB2300DCE0345120000000000000000BC +:1092D0000000000000000000000000000A00000084 +:1092E0006666666656000000000000000000000090 +:1092F00011111111111111111111000000000010B4 +:1093000003000000181DD61D061E1F1E531F581EE9 +:10931000301F421F431F7E1707B80733008000002D +:109320002083000000803280648096802DB4040F7A +:10933000110C0F0F90000F13A5BA830A18C80F0065 +:10934000151015101043104345097E1707B8C307C1 +:109350000080008020F3000C00803280648096FE44 +:109360002DB4FFFF11FDFFFFD0FF0F13A5BA830A35 +:1093700018C80F00130F130F0F410F411F030000F8 +:1093800009000000000000000000000000000000D4 +:10939000189DD69D069E1F9E539F589E309F429FAC +:1093A000439F0000000000C000000000000000001B +:1093B00002000000000000000000000000000000AB +:1093C00000E60000EC0454E7E4077EE75509A20735 +:1093D0000A09250945097E1707B8C3070080000060 +:1093E0002083000000803280648096802DB4048F3A +:1093F00011FDFFFFD0FF0F93A5BA830A18E80FE015 +:10940000130F13FF0F410F411F030000D4B80402D4 +:109410000351188748F00C0C85011C08189DD69D37 +:10942000069E1F9E539F589E309F429F439F5555B7 +:10943000555555D55555000000000018086A666658 +:1094400066666666366600270000000002E6008059 +:10945000EC0C54EFE4877EE75509A2070AE925E9F9 +:109460000000000000000100002802000000FC00D5 +:10947000000000000D000D0059064006000000002D +:1094800001559701020000000000000000010202E7 +:10949000002800008002FC00FFFFFF010D000D000E +:1094A00017001F000000000004B0B300000000100F +:1094B0000000000000020202002800008002FC0000 +:1094C000FFFFFF010D000D0016001E000000000050 +:1094D00004C4B300000000100000000000030202FA +:1094E000002800008002FC00FFFFFF010D000D00BE +:1094F00015001D000000000004D8B300000000109B +:109500000000000000040202002800008002FC00AD +:10951000FFFFFF010D000D0014001C000000000003 +:1095200004ECB3000000001000000000000502027F +:10953000002800008002FC00FFFFFF010D000D006D +:1095400013001B00000000000400B4000000001025 +:109550000000000000060202002800008002FC005B +:10956000FFFFFF010D000D0012001A0000000000B7 +:109570000414B40000000010000000000007020204 +:10958000002800008002FC00FFFFFF010D000D001D +:1095900011001900000000000428B40000000010B1 +:1095A0000000000000080202002804008002FC0005 +:1095B000FFFFFF010D000D0010001800000000006B +:1095C00020B0B30000000010000000000000000008 +:1095D000002806000000FC00000000000D000D0047 +:1095E000D20FA00F00000000015097010000000002 +:1095F0000000000000000000002802000000FC0045 +:10960000000000000D000D00C116A81600000000AB +:10961000018C97010600000000000000000B020210 +:10962000002800008000FC00000000000D000D007C +:1096300017001F000000000004B0B300000000107D +:1096400000000000000C0202002800008000FC0066 +:10965000000000000D000D0016001E0000000000BC +:1096600004C4B3000000001000000000000D02025E +:10967000002800008000FC00000000000D000D002C +:1096800015001D000000000004D8B3000000001009 +:1096900000000000000E0202002800008000FC0014 +:1096A000000000000D000D0014001C000000000070 +:1096B00004ECB3000000001000000000000F0202E4 +:1096C000002800008000FC00000000000D000D00DC +:1096D00013001B00000000000400B4000000001094 +:1096E0000000000000100202002800008000FC00C2 +:1096F000000000000D000D0012001A000000000024 +:109700000414B40000000010000000000011020268 +:10971000002800008000FC00000000000D000D008B +:1097200011001900000000000428B400000000101F +:109730000000000000120202002804008000FC006B +:10974000000000000D000D001000180000000000D7 +:1097500020B0B300000000104F00000001F404002E +:1097600068931B00600000000C0000000100040072 +:109770001428000060000000300000002D0084006C +:10978000142800001C000000730000002DF4840069 +:1097900068931B001C000000700000002DF4840082 +:1097A00068931B001C000000730000002DF484006F +:1097B00068931B001C000000630000002DF484006F +:1097C00068931B001C0000004F00000001F404001F +:1097D00068931B00E00001000C0000000100040081 +:1097E00014280000E0000100300000002D0084007B +:1097F000142800001C000000700000002DF48400FC +:1098000068931B001C000000000000000000000026 +:109810000000000000000000000000000000000048 +:109820000000000000000000000000000000000038 +:109830000000000000000000000000000000000028 +:109840000000000000000000000000000000000018 +:109850000000000000000000000000000000000008 +:1098600000000000000000000000000000000000F8 +:10987000000000000000000000000000922492247C +:109880009200920000000000224924492401A40013 +:1098900000000000144924492401140100000000C4 +:1098A000A448244924012201000000002445242961 +:1098B000240124010000000024292445240124015E +:1098C000000000002449A4482201240100000000F7 +:1098D00024491449140124010000000024492249AC +:1098E000A400240100000000FF7FFF7FFF01FF01B3 +:1098F00000000000B66DB66DB601B60100000000B4 +:10990000B26DB66DB601B60000000000966DB66D82 +:10991000B601960100000000B66CB66DB601B2014A +:1099200000000000B665B62DB601B60100000000CB +:10993000B62DB665B601B60100000000B66DB66C76 +:10994000B201B60100000000B66D966D9601B60139 +:1099500000000000B66DB26DB600B6010000000058 +:1099600001280000000000000000000000000000CE +:10997000000000020206AA006C768A94000106002C +:1099800000000000DB0600000106000091016E40AF +:10999000418C39030100009A1D018C610000000018 +:1099A0000000000010100D100390BBBB8E5A22184F +:1099B00064116411893989390AE00FE06412641274 +:1099C0000120000000000000000000000000000076 +:1099D000000000020206AA006C768A9400010600CC +:1099E00000000000DB0600000106000091016E404F +:1099F000418C39030100009A1D018C6100000000B8 +:109A00000000000010000C100380ABAA80442278F4 +:109A1000641164118939893905E005E06412641222 +:109A20000104000000000000000000000000000031 +:109A3000000000020200AA006C768A940001060071 +:109A400000000000DB060000040C000038066E2059 +:109A5000418C390301000084C4058C6100000000C2 +:109A60000000000010C40C500390BBBB804422785F +:109A7000641164118A39893905E00FE064126412B7 +:109A8000D004020001020304CCF57AFDED20BF8F63 +:109A9000CF0304021E0600036C768A9400010600C0 +:109AA00000000000DB06000001460000121B002041 +:109AB000006B39034100028400006B616478792BEC +:109AC000CF8A00801C5411980080BBBB00572278BD +:109AD000641164118A39893905E00FE06412641257 +:109AE0000100000001010101CCF57AFDED20BF8FDE +:109AF000CF030402020600006C768A94000106007F +:109B000000000000DB060000000C0000401A0020EE +:109B10004100380341000284000000606478792B22 +:109B2000CF8A00801C5410180380BBBB804622786B +:109B3000641164118A39893905E00FE064126412F6 +:109B4000D004020002020202CCF57AFDED20BF8FA4 +:109B5000CF030402020600006C768A94000106001E +:109B600000000000DB06000001460000121B002080 +:109B7000006B39034100028400006B616478792B2B +:109B8000CF8A00801C5411980380BBBB804622788A +:109B9000641164118A39893905E00FE06412641296 +:109BA0000100000003030303CCF57AFDED20BF8F15 +:109BB000CF030402020600006C768A9400010600BE +:109BC00000000000DB060000000C0000401A00202E +:109BD0004100380341000284000000606478792B62 +:109BE000CF8A00801C5410180380BBBB80462278AB +:109BF000641164118A39893905E00FE06412641236 +:109C0000D004020004040404CCF57AFDED20BF8FDB +:109C1000CF030402020600006C768A94000106005D +:109C200000000000DB06000001460000121B0020BF +:109C3000006B39034100028400006B616478792B6A +:109C4000CF8A00801C5411980380BBBB80462278C9 +:109C5000641164118A39893905E00FE064126412D5 +:109C60000100000000000000CCF57AFDED20BF8F60 +:109C7000CF030402020600006C768A9400010600FD +:109C800000000000DB060000000C0000FF3B00208D +:109C90004100380341000284000000606478792BA1 +:109CA000CF8A00801CC410180300000000C6227870 +:109CB000641164118039803905000F00551055106A +:109CC000000000000000000000101000000092CD15 +:109CD0000000C180100F0002000087370000BBF1B8 +:109CE000100F00040000904100008B43100E00078D +:109CF0000000BBF100009167100C000900001DFB83 +:109D00000000709E100E000500000000C806000054 +:109D1000BAF15942BAF15942450EA63D11223344D7 +:109D20005566778899AABBCCDDEEFF69000000007C +:109D30000000000000000000000000000000000023 +:109D40000000000000000000C022C0224A4948472D +:109D5000464544434241403F3E3D3C3B3A3938371B +:109D6000363534333231302F2E2D2C2B2A2928270B +:109D7000262524232221201F1E1D1C1B1A1900002A +:109D800000000000000000000000000000000000D3 +:109D90000000000031302F2E2D2C2B2A29282726B9 +:109DA0002524232221201F1E1D1C1B1A19181716DB +:109DB0001514131211100F0E0D0C0B0A09080706CB +:109DC0000504030201000000000000000000000084 +:109DD0000000000000000000000000002000E0C0C3 +:109DE000A08060402000E0C0A08060402000E0C073 +:109DF000A08060402000E0C0A08060402000E0C063 +:109E0000A08060402000E0C0A080604020000000F2 +:109E100076DBB62D2449921BDBB6491292942409B5 +:109E2000090000009173553719FBDDBFA183654719 +:109E3000290BEDCFB1937557391BFDDFC1A38567A2 +:109E4000492B0DEFD1B39577593B1DFFE1C3A58792 +:109E5000694B2D0FFFFF00006D5B922424B96D1B31 +:109E60009B2449124A9224010000003F62442608C4 +:109E7000EACCAE9072543618FADCBEA08264462852 +:109E80000AECCEB0927456381AFCDEC0A284664842 +:109E90002A0CEED0B29476583A1C9D7F61430000A4 +:109EA0006D4B9224E4B66D1B9324490A4992240019 +:109EB0000000B42D2F11927456381AFCDEC0A28413 +:109EC00066482A0CEED0B29476583A1CFEE0C2A442 +:109ED00086684A2C0EF0D2B496785A3C1E00E2C432 +:109EE000A6886A4C2E10000040DB962424496E1B85 +:109EF000DB26491292922409090000002507E9CBCC +:109F0000AD8F71533517F9DBBD9F8163452709EB91 +:109F1000CDAF9173553719FBDDBFA1836547290B81 +:109F2000EDCFB1937557391B9C7E6042240600002B +:109F30002D499224DBB66D13922429094992000021 +:109F400000D0B62D6C4E3012937557391BFDDFC112 +:109F5000A38567492B0DEFD1B39577593B1DFFE1E1 +:109F6000C3A587694B2D0FF1D3B597795B3D1F01D1 +:109F7000E3C5A7896B4D000000D0B6252449921B8C +:109F8000DBB6491292A4240949020000E8CAAC8E4B +:109F900070523416F8DABC9E8062442608EACCAED1 +:109FA0009072543618FADCBEA0826446280AECCEC1 +:109FB000B0927456381A9B7D5F412305E7C90000B3 +:109FC0002449921BDBB64D1292A4240949020000D9 +:109FD00040DBB624A98B6D4F31139476583A1CFEA2 +:109FE000E0C2A486684A2C0EF0D2B496785A3C1E81 +:109FF00000E2C4A6886A4C2E10F2D4B6987A5C3E71 +:10A000002002E4C6A88A00000000B42D254992244D +:10A01000DBB66D139224290949920000AB8D6F5174 +:10A020003315F7D9BB9D7F61432507E9CBAD8F7110 +:10A03000533517F9DBBD9F8163452709EBCDAF9100 +:10A04000735537199A7C5E402204E6C8AA8C00003A +:10A0500024496E1BDB364912929224090900000044 +:10A060006DDB9224E6C8AA8C6E5032149577593B6A +:10A070001DFFE1C3A587694B2D0FF1D3B597795B20 +:10A080003D1F01E3C5A7896B4D2F11F3D5B7997B10 +:10A090005D3F2103E5C700000000002D6D499224BB +:10A0A000E4B66D1B9324490A499224006E50321481 +:10A0B000F6D8BA9C7E60422406E8CAAC8E70523450 +:10A0C00016F8DABC9E8062442608EACCAE90725440 +:10A0D0003618997B5D3F2103E5C7A98B6D4F0000C2 +:10A0E00024B96D1BDB2449124A9224090000002D7B +:10A0F0006D4B92242305E7C9AB8D6F5133159678CC +:10A100005A3C1E00E2C4A6886A4C2E10F2D4B698BF +:10A110007A5C3E2002E4C6A88A6C4E3012F4D6B8AF +:10A120009A7C5E4022040000090000006DDB92244E +:10A1300024B96D1BDB2449124A9224093113F5D747 +:10A14000B99B7D5F412305E7C9AB8D6F513315F78F +:10A15000D9BB9D7F61432507E9CBAD8F715335177F +:10A16000FFFFFFFFFFFFFFFFFFFFFFFF30120000B9 +:10A17000E4B66D1B9324490A499224000000FC3F79 +:10A18000FFFFFF2460422406E8CAAC8E70523416EA +:10A1900097795B3D1F01E3C5A7896B4D2F11F3D55F +:10A1A000B7997B5D3F2103E5C7A98B6D4F3113F54F +:10A1B000D7B99B7D5F4100004902000040DBB62417 +:10A1C00024496E1BDB36491292922409F4D6B89AC0 +:10A1D0007C5E402204E6C8AA8C6E503214F6D8BACF +:10A1E0009C7EFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:10A1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00006D +:10A20000DBB66D1392242909C9FFFF3FFFFFFF3F13 +:10A21000FFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFF0E +:10A22000FFFF987A5C3E2002E4C6A88A6C4EFFFFCE +:10A23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:10A24000FFFFFFFFFFFF0000FFFFFF3FFFDFB62D17 +:10A250002449FE3FFFFFFF3FFFFFFF3F2000E0C01C +:10A26000A08060402000E0C0A08060402000E0C0EE +:10A27000A08060402000E0C0A08060402000E0C0DE +:10A28000A08060402000E0C0A0806040200000006E +:10A2900076DBB62D2449921BDBB649129294240931 +:10A2A000090000002000E0C0A08060402000E0C065 +:10A2B000A08060402000E0C0A08060402000E0C09E +:10A2C000A08060402000E0C0A08060402000E0C08E +:10A2D000A08060402000000076DBB62D2449921B50 +:10A2E000DBB6491292942409090000000000000026 +:10A2F000000000000000000000000000000000005E +:10A30000000000000000000000000000000000004D +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000C822050CE8220F0C56 +:10AAE0000000001002000000000000000000000054 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB2000C00BBC0DEE0B0000400BBC0FEC0B040087 +:10AB3000C02ABC0FEA0B0C00404ABC0FE80B140003 +:10AB4000C069BC0FE60B1C004089BC0FE40B24005D +:10AB5000C0A8BC0FE2082C004C48BE00000000005A +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00029292A2A2A2A29292A2A2A2A29292A2A0B +:10ABB0002A2A29292A2A2A2A2A2A2A2A29292A2AF9 +:10ABC0002A2A29292A2A2A2A29292A2A2A2A2929EB +:10ABD0000000000029292A2A2A2A29292A2A2A2A81 +:10ABE0000000000000000000000000000000000065 +:10ABF00000000000000000002A2A2A2A29292A2A07 +:10AC00002A2A29290000000000000000000000009E +:10AC10000000000029292A2A2A2A29292A2A2A2A40 +:10AC20002A2A2A2A29292A2A2A2A29290000000030 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE100006F0F15506F0F15506F0F15506F0F15542 +:10AE200020212224232323242325232424242424EF +:10AE300028272628272628262627252627252420B2 +:10AE40002121221F242425232623222625242524CC +:10AE5000262827272527282828282828272428287F +:10AE600024212220232524242523202623212525AF +:10AE7000262A272A2326262C26262B292B27292655 +:10AE80002424232222242223232225232423272689 +:10AE9000242927272827272C29262A272626252341 +:10AEA0002925242224242325242423232326252260 +:10AEB0002626282726262B26272C282828292B2813 +:10AEC0002322252225222324252423262524252543 +:10AED000282728282A29282B292B2C2C2A252424EA +:10AEE0002524242324222425222325242424242425 +:10AEF00025272727282625272826272927272425E9 +:10AF00002123222323212323232425242324242211 +:10AF100029282826272927262726242726252325CA +:10AF200022222322242323232323232424222421F3 +:10AF300027272629262727252827262729272727A1 +:10AF400023232421232424242423242422242523CA +:10AF50002727272626262726262425272A2826248B +:10AF600022222322242324242322232524242223AF +:10AF70002725252627272525252726262627252672 +:10AF8000252625232222242323232423232323238A +:10AF9000262627262526252626272627282727274B +:10AFA000232422222322232422232423232424246F +:10AFB0002625262727262627252727282629272529 +:10AFC0002323232324232325232524252524232544 +:10AFD0002727252626262626282626272729262807 +:10AFE000232423232324242224232423232324222D +:10AFF00026272526262626262627282829282727E5 +:10B000002122232225232323242322232323242410 +:10B0100026272626262626262727272629262828C5 +:10B0200022222023232224222324222425242523F0 +:10B0300027242527262725292528272728292825A5 +:10B0400025252323242424242525232424242424BF +:10B050002726272725262726272726272928262784 +:10B0600021222321252623242423232323242423AC +:10B070002727272626272628262629292A2927255D +:10B080002324222324232424242624242524242482 +:10B090002724272627252525272826272828272748 +:10B0A0002424232126242323272423232524242561 +:10B0B000282727282726282827272828272827271A +:10B0C0002324232224242523242326252525252340 +:10B0D0002727272727272827262828272328282700 +:10B0E0002424222325232323232423242524232526 +:10B0F000272928262828272727272828262A2727D8 +:10B1000023222325242424252425262523242625FB +:10B1100027272727272726292627282626292928BB +:10B1200022222325232424242524252525282525DA +:10B130002626282528272725292A272A26282A2A95 +:10B1400024242524242424252323252524252425BB +:10B150002628272627272727282627262727262782 +:10B160002423262124252522252426242427252599 +:10B17000292827272829282929272829282829294B +:10B180002423222322232325232524242524242485 +:10B19000272728272727272827272926262627283D +:10B1A000222222232426242324242425262526255E +:10B1B0002828292826272826282827272826292717 +:10B1C0002322242325242424252626252526242736 +:10B1D00026262729272729282628282827262928F8 +:10B1E000252524232524252526262625252627250D +:10B1F00027282A282727292926282B2729292627CF +:10B2000023232324242522252426262524262625F7 +:10B2100026282727272927262727282829292728B6 +:10B2200024232322242423262624272525252526D6 +:10B230002628292927262828272627292728272995 +:10B2400023232322252423232523252525242425C0 +:10B25000272728272628272627272829282A292973 +:10B2600025242321242123232423252524242425A4 +:10B270002626282728282828282628292829282754 +:10B280002220222425232423242625252324242583 +:10B290002727262828262628272727292828292738 +:10B2A000252322242424232426252325242424255D +:10B2B0002726262727272627282927282B2B282615 +:10B2C000252422242423232422252425252525253D +:10B2D000272728272727282728282628292C2A27F0 +:10B2E0002424252323232524242425242625252519 +:10B2F0002927282928282827282828282A272928CC +:10B3000025262422242424242424242525252324FA +:10B31000262726262727272527282728292A2928B8 +:10B3200026272523242523242525262624242525D0 +:10B330002727262727272827282828282929282695 +:10B3400025262524252324242525242525252526B1 +:10B35000262727282727282728292B2A2B292B2867 +:10B36000252626232624242524252526252525268D +:10B37000282627262727272727272828282A282757 +:10B38000272724222326232626232525262527256D +:10B390002927262726282628282828282728292735 +:10B3A0002323232423272425252427252625252751 +:10B3B0002927262728272727282627272A2A2A2811 +:10B3C000242226222523262624272726262726262A +:10B3D000282828282828272829282A292A292A28E5 +:10B3E0002424242326252525272727282727262602 +:10B3F00027262526252A292A2B2B2A28282A2A28C7 +:10B4000026262424232725272529262729292927D5 +:10B410002C2B29292B292A2A292A2A2A2928262796 +:10B4200026242423272325272627262828282729BA +:10B4300028292D292A2C2A2B2D292B2A2B29292A68 +:10B44000252427252724262626272627272A272896 +:10B4500029272A28292B282B2C2A28292A29292957 +:10B460001B1A181A19191819191919191A1C1A1A44 +:10B470001B1D1B1C1B1A1A191918181A1B1B1B1928 +:10B480001A1818181A1919181917181A181A1B1A2D +:10B490001C1B1B1B1A171A1A191A19191E1A1C1D04 +:10B4A000171A1A1A1C1B1A191917171A19191A1B05 +:10B4B0001D1D1C1C1D1C1A1B18191B191E1A1D1BD7 +:10B4C0001C191A1A1A1A17181817181719191B1AEB +:10B4D0001C1D1C1C1B1C1A1A1A191C181C1B1A1ABE +:10B4E0001E1C1C191A19191917181918191A191AC2 +:10B4F0001D1B1B1B1B1B1A191C1B1A1B1C1D1E1C96 +:10B500001A181A191A1719191818191A191A1B1BA7 +:10B510001D1E1C1D1C1B1B1B1A1B1B1B1C1C1C1D6E +:10B5200018191919181818181719191818191A1B91 +:10B530001C1C1E1B1A18191B1A1A1A1C1D1C1B1B5B +:10B540001B1B1A1A191819181818181919191A1A68 +:10B550001C1A1C1B1B1C1A191A191A1B1B1C1A1E3D +:10B560001A1919191918181917171A181919191950 +:10B570001C1C1A1C1B1C1B19191A1A1B1D1A1B1C1C +:10B580001C1A19181919181818181818181A1B1A2B +:10B590001D1C1B1C1B1C1B1B1A191A1C1B1C1C1DF5 +:10B5A0001A1A1919191819191918181919191A1A0A +:10B5B0001C1B1A1B1C1B1A1B191C1A1C1B1C1C1CD9 +:10B5C0001C1B1A1A181819171817181918181919EE +:10B5D0001C1A1C1B1A1A1A191A1A1A191C1D1D1CBE +:10B5E0001D19191818181719171818191919191BCE +:10B5F0001C1C1C1B1B1C1B1A1A1B1C1B1D1E1C1C91 +:10B600001A191819181818181819191919181A1AAE +:10B610001D1E1C1B1C1B1A1A1A1B1A1C1C1E1B1E6F +:10B620001B1A181B181818181819181718191A1A8D +:10B630001C1B1B1C1A1C1B191A1B1A1C1E201D1E4E +:10B6400019171918171918171718181919181A1A75 +:10B650001A1C1C1C1B1A1B1B1B1A1A191D1E1E1F31 +:10B660001918161A1718171817181819181A1A1A55 +:10B670001B191C1B1B1A1A191A1A1B1C1B1F1C1B1B +:10B680001B1917181918171818191718191A1A1B2F +:10B690001B191D1B1A1C1B1A1A1A1A1C1D1C1D1BF8 +:10B6A0001817171719191717171718181818191A1C +:10B6B0001B1B1B1B191A1B1917191B1B1C1E1D1AE0 +:10B6C0001A19171817171818181819181B1A191AF1 +:10B6D0001A1B1B1A1C1A191919181A1B1C1E1C1BC1 +:10B6E00018191818181817181716171719191A19DA +:10B6F0001C1C1B1B1C1A1A1A1B1A191D1C1D1C1C96 +:10B7000018161717171717161818181818191A1BBC +:10B710001B1A1C1B1B1B1C19191A191B1A1E1C1B7C +:10B7200018161617171817161717171618191919A4 +:10B730001C1C1C1B1A1C1C1A1919191B1A1F1C1C57 +:10B740001817161818171718171819171819191A7B +:10B750001B1C1B1A191A1B1A19191B1A1C1F1C1C3B +:10B7600018161619171816171718181818191A1C5A +:10B770001C1A1B1B1C191A1A1C1A191B1A1E1D1C19 +:10B780001819181819181717171718171919191C35 +:10B790001B1C1B1A191A191B1B18191A1D1B1B1C01 +:10B7A000191719161817161717171817181819191F +:10B7B0001B1C1C1C1A191B1A1B1B1B1B1B1C1D1CD6 +:10B7C0001B181616161716161818191818181A19FD +:10B7D0001A1A1B191B1B191A181A18191A1C1B1CC8 +:10B7E00018161518171717171617181818181819E4 +:10B7F0001B1A1B1B1B191B1819191A1B1B1B1D1CA1 +:10B800001917171717171617171718181819181CBC +:10B810001B1A1A1B1A1919191A19191A1B1B1C1B86 +:10B820001A19171717181718171817181818191B97 +:10B830001C1B1B1919191919191A1A191B1E1B1B64 +:10B840001818171716171515161818181818191B81 +:10B850001A1C1A191A1A19181B1A1A1B1C1D1D1C3E +:10B860001816171616171717171718191918181961 +:10B870001A1C1B1A1A1A1B19181A1A1A1B1B1A1A25 +:10B880001817161717181515181617191718191A43 +:10B890001A1C1B19191B181717171A1A1B1C1B1B0C +:10B8A0001A18171616151516161717171817181A27 +:10B8B0001B191B1A191919181918171C1B1D1C1AEA +:10B8C0001815151716151515171716181618181A0E +:10B8D0001B1A191C1A18181A1919181B1A1C1C1AC9 +:10B8E00019171616161715171716171817181919E6 +:10B8F0001A191919181918191918181A1B1C1A19B4 +:10B900001818161616171618161718181818191AC0 +:10B910001B1A1A191918191719181A1C1A1D1C1A8A +:10B9200017161716161617171718181918171819A3 +:10B930001B191A1A191A18181A1B19191B1C1D1B66 +:10B940001918161516161515161717181818181A87 +:10B950001A1B181B1A1919181A1918191B1C1A1A4C +:10B960001817171516181616161717171918171867 +:10B97000191A1919191A19181A191B191A1A1A1A2F +:10B980001818161717161615171617181718191945 +:10B99000191B19191819191719181B1B1B1A1A1911 +:10B9A0001817171515171717161717191718181A24 +:10B9B0001A181717191819191818181A181A1919FE +:10B9C000181915151616161517161617161718180E +:10B9D00018181818171819171819181A181B1A19DF +:10B9E0001716161616161817151717171717191AE8 +:10B9F0001A181919181918181A1919181C1B1B1AB2 +:10BA000016151815161515161617181817181819CB +:10BA10001918181917171719191818191A1A1A199D +:10BA20001716161518171516181918171719191AA1 +:10BA30001B1917171A1919171B1A1818191B1A1A74 +:10BA40001616151516171615141518161716171895 +:10BA50001C1B1B1A191A1918191819181B1A1A1B4A +:10BA6000141414141616141415161416171717197F +:10BA70001818191918171B18191A17191819191A3B +:10BA80001515151416161516151716171718181953 +:10BA900019171818181719191A1916171817191B22 +:10BAA0001A19181918181818171818191A1C1D1C03 +:10BAB0001C1C1B1B1D1D1C1D191A1B1C1A1D1D1BCC +:10BAC0001A1918171917171618171819181A1B19F1 +:10BAD0001D1C1B1A1B1A1B191819191A1C1C1E20B5 +:10BAE0001D1B1A191A1A1A181917171A1A191C1ABB +:10BAF0001E1E1C1C191C1C1C191A1A191F1C202183 +:10BB00001C1D1A19181916171615171619191A1AAD +:10BB10001D1E1D1B1A1A1B1C1A181C1A1C1E1B1A70 +:10BB20001E1D1B191A1818171516171818191A1A86 +:10BB30001C1C1B181C1B1B1A1919191B1C1D201F50 +:10BB40001A1919191917181617151819181A1B1D6B +:10BB5000211D1D1E1D1C1B1B181A1A1A1C1C1C1D26 +:10BB60001A1A18181917171615171718181A1B1A52 +:10BB70001D1E1B1C1B1A181B1819191C1D1E1F200B +:10BB80001B1A191919181717161617181C1A1C1C26 +:10BB90001F1E1F1C1B1A1A19181C1C1C1D1E1B1EE5 +:10BBA00019181817191617171516171719181A1B19 +:10BBB0001F1E1D1C1B1A1A1918191B1B1E1C1D1FCA +:10BBC0001C1919181818171717171718181A1B1BEC +:10BBD000201D1D1D1B1A19191A181C1C1D1C1E1FA7 +:10BBE0001A1919181817171716151718191A1A1CD1 +:10BBF0001E1D1C1C1B1A19191919191A1D1C1B1E94 +:10BC00001A1A1918171617161516161818181A1AB8 +:10BC10001E1C1B1C1A1919181818191A1A1A1C1E7E +:10BC20001C191918181617171516181818191B1C8F +:10BC30001E1D1C1B1B1B191817191B18191C1C1D5A +:10BC40001916171916161616151617181819191C7D +:10BC50001E1C1A1A1A19191818181618191B1B1D48 +:10BC60001A18171918171716151616171818191B5A +:10BC70001E1B1B1A1A181918181916191C1B1C1D23 +:10BC800019181716171616151516151718181A1B42 +:10BC90001E1C1B1B1A191919181817181C1A1C1D01 +:10BCA00018161616161616151516161718191A1927 +:10BCB0001C1B1A1A19181818171718171A1B1A1BF1 +:10BCC0001A191617171616161617161718191A1BFB +:10BCD0001D1B1B1A191818171718191A1C1B1A1CC8 +:10BCE00017161515171616151514151616181819F2 +:10BCF0001C1B1B1918171717161718191A1B191BB5 +:10BD00001918151616151515161616171818191BC5 +:10BD10001C1A1918191717171617191B19191B1C94 +:10BD20001718171516161515161516171718191AA8 +:10BD30001C1B1A1A191819181718191B191A1A1C6A +:10BD40001715161516151414141416161818191993 +:10BD50001B1A191919181817141516161619191B64 +:10BD60001816151516151514141515161718181A72 +:10BD70001C1B19191818171515161616181A1A1B40 +:10BD80001716141516141314141415151618191A59 +:10BD90001B1A19181718151515161516171A1A1B28 +:10BDA0001715141715141414151515151718181A36 +:10BDB0001C1A1918191816151617171618191B1CFE +:10BDC0001715171616151414141316161617191A14 +:10BDD0001A1A171817181514151515161718191CEF +:10BDE0001816151415141412141415151617181AFC +:10BDF0001B1A191817161616151517181919191CC4 +:10BE00001918151415141414141415161716181AD5 +:10BE10001A19191818171617151617161717191DA6 +:10BE20001715141414141413131414151616171AC2 +:10BE30001B191918171616161616161717161A1C88 +:10BE40001816151415141213141415161617181A9B +:10BE50001A181817171616161616171718171A1D68 +:10BE60001918161515141414141414151616171879 +:10BE70001B19181716161615161618171819191B48 +:10BE80001716141513141213131415151617171962 +:10BE90001918171617161514161616181718181A33 +:10BEA0001816151414131313131414151516181942 +:10BEB0001919181716161614141414161718181B17 +:10BEC000171514141413121213131415151516182C +:10BED0001A18171616151412131514141618191B00 +:10BEE000181714131312121213131315151517180C +:10BEF00016181817161613131415141516171819E3 +:10BF000016141313131212121314141414161719EF +:10BF10001718161716151314141515151618191ABF +:10BF200017141313131212121313131515151618D1 +:10BF300016171615151514121414141717171819A7 +:10BF400017151313131212131214141414161618AF +:10BF5000171817151515151415151516171718197F +:10BF60001716141313121212131313141415161791 +:10BF70001617161615151414141515161716181964 +:10BF80001816141213121212121313141415161772 +:10BF90001817161515141412141515161617171848 +:10BFA0001615141212131212131213141414161657 +:10BFB000181616151314141313151616151617182C +:10BFC0001616141313121212121313131414151736 +:10BFD000171615151313131213151616161618180F +:10BFE0001615141112121212121313141415161816 +:10BFF00018161515131414141315151614171718ED +:10C0000015161211131211121211121313141617FE +:10C0100017161514141312121314141514161718D6 +:10C0200015131312121212121212131314141617DC +:10C0300018171514151414131414141415171817AD +:10C0400014131312121112121112141414141517BE +:10C050001616151413141314141415141616171792 +:10C06000141313121313111212121313141515169D +:10C07000161514141314131314141313141515187C +:10C080001413121111111110111112131314151789 +:10C09000171616161613131313141615151516184E +:10C0A0001312121011100F10101011121314161673 +:10C0B000171516161313131314121212131517193A +:10C0C0001312131011101010101011121113151655 +:10C0D0001514151513131313111211121214171826 +:10C0E0001F1E1C1C1B1A1A1B1B1A1C1C1D21212184 +:10C0F00025252322211F1E1D1B1C1B1C1F201F1E4C +:10C100001D1D1C1B1B1C1B181B1A1C1D1C1E1F1F6E +:10C110002522201F201E1C1D1A191B1B1B1B20253E +:10C1200020201E1D1D201E1B1A191B1E1B1E202138 +:10C1300025242323201F1E1F181B1D1C201E222503 +:10C14000201F1D1D1C1C191A191919191A1D202030 +:10C15000242521211F1E1C1E191A1D1D1F1D1E1FF7 +:10C1600025211F1E1F1C1B1B18191B1A1B1B1D1E04 +:10C1700025222120201F1E1C1A1C1D1E1F212021CC +:10C18000201F1F1E1D191B1B19191B1C1C1E1F20E5 +:10C1900027252322211F1E1D1B1A1C1C1F1F201FA9 +:10C1A0001F1E1C1C1D1A1A18171A1A1B1B1D1D1ED8 +:10C1B00021211F1E1E1C1A1A1A1B1C1E1C1D1F21AA +:10C1C0001F1F201D1E1B1C1A1717191B1C1D1E1EAE +:10C1D000252422201F1E1D1C1B1B1C1D1E1E1E2471 +:10C1E0001F1C1B1B1C1A1A18181819191B1C1D1DA3 +:10C1F0002321211F1E1D1B1B1A1B1C1C1F1B1D2264 +:10C20000211F1E1B1B1B1A1919191A1C191B1D1D76 +:10C210002422211F1E1D1C1A1B1A1C1D1E2020213A +:10C22000201C1C1C1B1A191917191A1A1B1D1D1F5B +:10C230001E201F1F1D1B1A1A191B1B1A1D1F1E2132 +:10C24000211F1D1C1A191818171719181A1A1C1B48 +:10C250001B201E1E1B1B1A1918191B181B1C1E1E27 +:10C260001F1D1D1B1B1A191917181A1A191B1D1E21 +:10C270001E20201E1D1D1A1817191A1B1A1E1E1FFC +:10C280001D1B1B1C1A1818181717191A19191A1D13 +:10C2900022201E1E1D1B1717181818181B1B1B20E9 +:10C2A0001F1E1C1C1B191918171819191A1B1B1DE6 +:10C2B000221F1D1C1B1B1716171919181B1B1C21CD +:10C2C0001E1B1B191A1817161717181A1A1A1C1ED4 +:10C2D00022201F1E1C1B1917171718181C1D1D21A3 +:10C2E0001C19181A19181817161718191A1B1B1CBD +:10C2F000201D1D1C1B1A1917151617181B1C1D1D98 +:10C300001D1B1A1A19181617171818191A1B1B1E95 +:10C31000211D1E1C1A1A1918181A1A181B1B1C1F6B +:10C320001B1A18171918171616161717171A191B8C +:10C330001C1B1A1C1A19181816171919191B1B1C63 +:10C340001B1A181918171716161719191A1B1B1D5F +:10C350001C1A19191A1918171819191A19191B1E44 +:10C360001C1A18181817161617161718191A1A1B48 +:10C370001D1C1A1A1B191A18181918191A1C1C1E18 +:10C380001B1917181716151415161718191A1B1B31 +:10C390001C1919191918181717181718181B1C1E0B +:10C3A0001B191817171616151516161719191A1B13 +:10C3B0001D1B191A1A19171716181718171C1C1EE7 +:10C3C0001A181718171615141515161817191A1CF8 +:10C3D0001E1C1B1A1918171716171616171B1C1DCB +:10C3E0001A1817181715141415161716181A191BDA +:10C3F0001C191B19191817161718171618191C1FAE +:10C400001C1A191816161415141416161618191CB9 +:10C410001A1A1818181715151717161518181A1E9E +:10C420001B18181615151513141416151616181BA7 +:10C430001C1A1819191716161717171817181A1E75 +:10C440001E18161615151414131415161717181B85 +:10C450001B191819191717161516171617181B1F59 +:10C460001917161615151413131415161616181A6F +:10C470001A181919181617151515171819171B1C3E +:10C480001B191716151413131514151616171A1C45 +:10C490001D1A191817161615161717171A171C1F15 +:10C4A0001B19171715151414151416161616181B24 +:10C4B0001D1B19181717161515171718191C1B1EF1 +:10C4C0001918161614141212131415161717191C0E +:10C4D0001B1918171615151415151618191B1D1DDF +:10C4E0001917161615141313141415161617191BED +:10C4F0001C1B181917161614151516171918191CC0 +:10C500001A18151515141212131314151516181BD5 +:10C510001C1A1917161615141415161618181A1EA3 +:10C520001B17151414121312131415151617181BB4 +:10C530001B19191716161514151517171818191D84 +:10C540001816141414131212131415151517171B9B +:10C550001C1A1818161514141515161716171B1C67 +:10C560001816141414131212141313151515171981 +:10C570001A18161615151313141515161817181B57 +:10C580001A17151413131212121314141517171A5D +:10C590001B1A1716151514131515151617181B1B2E +:10C5A0001716161414121212121313141415171A44 +:10C5B0001A171716151414131415151517171A1E14 +:10C5C0001917151313121211121313141516171924 +:10C5D0001A1816151515141313141415171A1A1CF6 +:10C5E000181614131313121212131413141416180A +:10C5F0001A171615151515131415171518171A1DD2 +:10C6000018171513131211121212121314141619EB +:10C6100019171615141313131414141518171C1DB9 +:10C6200018171512121211111213131314161719C9 +:10C630001A17151514141313131415151519191B9E +:10C6400017161313121211121212121313141618B2 +:10C6500019171614131414121313141416171B1C81 +:10C66000171614131312121112131313141416198C +:10C670001B17161515141412131414141617191C5D +:10C680001715141312121111111213131314151874 +:10C6900017151514141312131315161416191B1C41 +:10C6A0001614131212111011121313131514151856 +:10C6B0001A16151414141312111212131414171C31 +:10C6C0001614131211111010101011111313141746 +:10C6D0001816151414131212121313141615181A0F +:10C6E0001413131011100F1010111111111314162F +:10C6F00016151514131312111313131314151619F9 +:10C70000141312111210100F10101110111314160F +:10C7100015141313121211111213121213151619E4 +:10C7200006F0F15506F0F15506F0F15506F0F15519 +:10C73000402C2B2B2A2F2F2C2C34333131313134F8 +:10C740003040322F2E2C2B2A2B2C2C3131302F31F4 +:10C750003231322F322C2C2C2B2B2B2C2C313331F1 +:10C7600030333131312E312B2C2C2B2B2A2B2B2FEC +:10C77000312F2F302F2F2F2F2F2C2B2A2A2A2A2BE5 +:10C780002A2E2F302F302F2F2F2C2F2A2A282A2ADB +:10C7900029282A2D3030302F2F30312D2C2C2B2AC8 +:10C7A0002B2B2B2B282F2C2E2F2D2F2E2C2E2C2BC2 +:10C7B0002A292A2B2A2B2A2F302F2F2E2E2C2D2DB3 +:10C7C0002B2B2B292A2B2A2C2B333130312F2F2F97 +:10C7D0002D2B2B2A2A2A29292A282B2D2F2E2D2DA5 +:10C7E0002E2D2C2C2D2B2C2C2D2B2B2C2C2D30307E +:10C7F0002F2E2F2D2B2B2A2B2B2B2A2B2C2D2A3077 +:10C800002F30302F2D2D2C2A2C2A2A292A2A2A2C67 +:10C810002D2F2F2D2E2E2C2D2B2C2C29282A282A5B +:10C820002B2B2C2E2D2B2D2D2C2D2C2A2C29292851 +:10C83000282B2D2C2B2E2E2E2D2D2C2B2C2B292640 +:10C840002928292A2928292B2B2B2C2A2B2A2C2D45 +:10C850002C2A29292828282927292B292B2B2B2B3F +:10C860002A2C2B28272728282A29292C2C2C2C2A2B +:10C870002C2B2C2E2A2A292828292929292B2A2918 +:10C88000282929292B2F2A2A2A2928282A2A29290E +:10C890002928282828282B2C292929282728292B0A +:10C8A0002B2C2A2929292A2A292B292929292929EE +:10C8B0002929292A2929292828292A2C2A292828E6 +:10C8C00029292A2B2A2C292829282A29282C2A2ACE +:10C8D000292928292929292A292928292929292AC8 +:10C8E0002A292728292929292B2A2B2B2A292A2AB0 +:10C8F0002B2C292A29282829282929292A2A282AA3 +:10C90000292A2A2B292A272829282928292827279C +:10C91000292929292A2C2529282726272828272894 +:10C92000272827272827282A28282729272827298A +:10C930002926282A29282728272B2728272626277B +:10C9400026262627272626242727272B262928267A +:10C95000262728272725292628262627282A272963 +:10C960002827272727272827262527262627272A57 +:10C970002727272627272827282628262726262749 +:10C980002829262726262524262627272626252544 +:10C990002627272A25272626262626262625252534 +:10C9A0002525252526274025262524252526272615 +:10C9B0002523242525252640402A2D2D2E2E2F2CBB +:10C9C0002C313230303231343240302F30312E2F52 +:10C9D0002E2E2D323131323232343332312E2F2E4F +:10C9E000302E2B2D2C3230312F333334342F332F44 +:10C9F0002F2C2C2C2B2C2B3231303132343435313E +:10CA0000302E2F2E2E2D2D2C2C313331323432322C +:10CA1000312F312D2C2D2E2D2C2C2D2F333030302D +:10CA2000323233302D2F2F2F2D2F2E2D2D34313309 +:10CA3000353333322F2E2E2D2F2E2E2E2E2C2F31FE +:10CA4000313032323230302E2D2D2E2E2D2F2C2DF6 +:10CA50002F323230323231302F2D2F2E2E2F2F2EDB +:10CA60002E2E2F32313231313030302F2E2F2D2ECD +:10CA70002F2F2D2F2E2F3233323131302E2F2E2DBE +:10CA80002E2E2C2D2F2F3031333231302F2F2D2CB5 +:10CA9000312D2E2C2D2F302F30333031323231309A +:10CAA000302E2F2D2E2F2E2E2E2F2E313330313093 +:10CAB0002F31312D302D2F2F303032333034343070 +:10CAC00030302F2E2E2E2B2B2E2D2E2F2D2D2D2D8B +:10CAD0002F2C302E302D2F31312E2E2D2F2D302F6B +:10CAE000303331323030313231302F2D2D2E2D2E4A +:10CAF0002F2F30343132312F302F2E322F2D2D2D3C +:10CB00002C2E2D2D2D302F2D2F2F2E2E30312D2E42 +:10CB10002E2E2D2E2F2F2F2F2F2E2F2E2F2E2D2F2F +:10CB20002E2D2D2B2C2C303030312F2F2F2F2E2E21 +:10CB30002F312D2E2E2D2E2E2F2E2E2D2E2E2F2D13 +:10CB40002F2D2E302E2D2E2F302F3031312F2D2EF8 +:10CB50002F2D2E2D2C2E2E2E2D2D2E2F2F2E3030F4 +:10CB60002F302D2E2D2E2F2F2E2D2D2E2D2E2E2EE5 +:10CB70002F2D2E2E2E2C2E2D2D302D2D2D2C2D2EDD +:10CB80002E2E2E2E2E2E2F2E2F2F2F2E2D2E2E2DC3 +:10CB90002F302D2F302F2E2C2E2D2E2E2E30282DB7 +:10CBA0002E2B2C2C2D2C2D2C2E2E2D2C2E2D2C2EB8 +:10CBB0002D2C2B2D2C2B2C2D2E2D2D2E2D2C2D2EAA +:10CBC0002D2F2B2E2C2B2B2C2C2D2E2D2C2C2C2AA0 +:10CBD0002E2C2E2D2E2E2E2E2E2F2E2F2E2C2D2C7B +:10CBE0002B2B2E2E2C2D2C2E2D2D2D2D2D2D2F2C77 +:10CBF0002A2B2C2B2B2E2E302B2D2C2C2C2B2C2B74 +:10CC00002E2C2C2C2C2C2D2C2D2E2B2D2D2D2C2C5C +:10CC10002E2C2D2B2B2D2B2C2C2E2C2E2A2D2C2C50 +:10CC20002D2E2D2C2E2D2C2D2D2D2D2C2D2E402D21 +:10CC30002D2D2E2C2C2F32302D2C2F2D2F2C2D4006 +:10CC4000402D3231323334313234343335343538A7 +:10CC500034403032333333313231303133323536A0 +:10CC60003635363533323432323131312F32343396 +:10CC700031363536363534323232313130322F3783 +:10CC80003535353638363735343332323433313260 +:10CC90003034343436353634353434313030323063 +:10CCA000312E313335333435343435343235343450 +:10CCB000353437333335333636363635343532332B +:10CCC0003332323332313435363336353534343429 +:10CCD000303132333233323333363636363635331B +:10CCE00034333134343434353633383534343637FC +:10CCF00037353333323334343534343334363837EC +:10CD000035353636343530323434343534363735DB +:10CD1000353536353534322F3534333334323334D8 +:10CD200035373634353935353734383434343436AC +:10CD30003839373737373537373835313333353496 +:10CD40003435373536373936353735353333302F97 +:10CD50003232333333333135333635343634353498 +:10CD60003432343132343537343535373637373578 +:10CD7000363534313232343335353436363834366C +:10CD80003535353532343436363736363334373355 +:10CD9000323635343436323235353534333735354D +:10CDA000353533383533333434343432343438363B +:10CDB0003636353536353634333334343434353429 +:10CDC000363436353734333634323434333434341D +:10CDD0003536363836363635343636353334333400 +:10CDE0003333353433343435363436363333333500 +:10CDF00035353335333934393635383435363634DC +:10CE000034333434363635353535363333353535D8 +:10CE100035353432343434333635343735373734C6 +:10CE200036393636343430333333333333333333C4 +:10CE300034333435363333353333333537333538AC +:10CE4000363335333335343434342F3535333636A1 +:10CE50003435353533313232333333353335343499 +:10CE60003436353433343532343334353334333681 +:10CE7000353436353537343432323434343534356C +:10CE80003335333333353434343435333433343366 +:10CE90003435333437343435353333343332343452 +:10CEA0003335363637343434343637353434363433 +:10CEB000363434343534403D373937393C463935EA +:10CEC0003638333339333340403A353638363736EF +:10CED00034393A373A3A3A3D3D403E3F3F3E3738A3 +:10CEE000373636383837383D3D3A3A3937383A36BA +:10CEF0003635333535383837373C3A3B3B393937B7 +:10CF0000383637363637353A3B38383B3B3A38389F +:10CF100039393938393B363936393D3B3C3B3C3A77 +:10CF20003C38393538383737383536363B38393884 +:10CF3000383A3938353A393A393B3837353E393F5E +:10CF40003A3C3D3B383A373739393A38383A373A4C +:10CF50003A393C3B3C3C3A3834373837393B38383F +:10CF6000373A3C3D3C3E3E3C3A353739393B39391E +:10CF700037383B393B393B3E3B3B393A3739393B14 +:10CF8000393A3A3B3D3A3F3D3D3B3C3B393A3539F6 +:10CF9000393A3A3A3938393A3C3C3B3C3C3A3736F4 +:10CFA0003A39393A38393A3A3F3A3C3B3C3C3B3CD7 +:10CFB00039383B3A393C3A3D3A3B3D3C3C3D3B3DC0 +:10CFC0003E3B3C363A393C3A393C3C3B3D3A3C3AB4 +:10CFD0003D3B3D3D3C3A34373B393B3B39393839B1 +:10CFE0003B3B3B3C3E3B3A383A393A3A3B383738A0 +:10CFF000383B3B38393B3E3B38393A383A393A3896 +:10D00000373A3C3C3B3D3D393D3C383A393B3B3A75 +:10D010003C3D373A3A3A3A3A3B3D3C3C3C3A393A65 +:10D020003B3C3B3A393C3C3B3A3B3D3B3E3A3B3A4E +:10D03000393A3A3A383C3B3E3D3C3B3C3C3C3D3C3B +:10D040003B3A393C3D3B3B3E3A3C3A3C3A393C3B2F +:10D050003B3A3B3A3C3A3B3C3A3A3B3D403C3D3E16 +:10D060003B3B3D3A3A3A393A3B3B3A3A393A393A1C +:10D07000393A3B3E3C3C3B3B3C3C3A393B3B3A3CFF +:10D080003D3E393C3C3B3D3C39393B3B3D3D3B3BE8 +:10D090003A3B3D3A3A3A3B3B3B3A3B373B3A3B3BE8 +:10D0A0003E3B3A3D3A3B393B3C3B3E3C3A3B353DCF +:10D0B0003C3839383A39363C3C3A3C3C3D3B3B3CC9 +:10D0C0003A3B3A3B3A393B393D393A3E3C3B3A3CB4 +:10D0D0003B39373D3B3B38393A383B3A38383C3AB4 +:10D0E0003E3A3A3A373E3D3C3C3C3C3F3B3B3C3B86 +:10D0F0003A3A3D3B3B3C3A3E3C3D3C3B3D3C3B3D74 +:10D1000039393B3B3B3B3C3D393B3C393E393C3C70 +:10D110003D3B3A3C3C3A3C3D3B3A3A3D3A3D3B385C +:10D120003E393D3C3B3D3C3C3C3D3B3A393D3F403C +:10D130003F3E3D3C3E3B3B3C3E3F3F3D3D3B404117 +:10D14000404444474041403F3E3D3D3D413F3D40DE +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000004806108000488610800048061F800044 +:10D3C00048861F800048061180004886118000486A +:10D3D000061E800048861E8000480612800048868F +:10D3E00012800048061D800048861D8000480613F4 +:10D3F0008000488613800048061C800048861C80F8 +:10D40000004806148000488614800048061B8000EF +:10D4100048861B8000480615800048861580004815 +:10D42000061A800048861A80004806168000488642 +:10D4300016800048061980004886198000480617A3 +:10D4400080004886178000480618800048861880AB +:10D4500020001904902000320887200032C8802064 +:10D4600000325882200032E8832000327885200084 +:10D470003208872000196890200019889320000244 +:10D48000F44B200002044C200019F89120001918D8 +:10D4900095200002F44B200002044C20001938981B +:10D4A000200032A8962000326890200032F89120A7 +:10D4B000003288932000321895200032A896000090 +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D540000100EE020201060A6400283246000000D3 +:10D5500000000000000000003C0000004006000049 +:10D5600034080000A0A0010101011900010014000D +:10D5700001001600A5000A000014780000327800AF +:10D580000000002032323232323232323232323223 +:10D59000323232323232000000000000000000005F +:10D5A0000000000000000000D007D0072C010000A0 +:10D5B0000203200019450000F16C000084D9060028 +:10D5C00029B1010010270000C409000000014B0F21 +:10D5D00000000000000000003C3C0A0A02000000BD +:10D5E0000000000001010101010040003200E803D9 +:10D5F0000F0008000A0009000000030402000300F5 +:10D6000003000A0008006400E803000004000000B2 +:10D6100000000000000000000101010101004000C5 +:10D620003200E80314000F000A00E10000000808BF +:10D630000A0028001E001E0008006400E803000025 +:10D640000400000000000000000000004006300060 +:10D6500020000100220000003A00520070008F00FC +:10D66000AF00CF00EF000F012E014F016E018E01C0 +:10D67000AD01CE01EC010F022D024D026D028D02B3 +:10D68000AC02CC02EB020B032B034A036A038903AF +:10D69000AA03C903E703FF033704000000000000EA +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000F6090A +:10D72000300046000100480000003C004300660055 +:10D730008500A900C800E90009012A0149016B011F +:10D740008901AB01C901EB0109022B024A026C02FB +:10D750008A02AC02CA02EC020B032D034B036D03D9 +:10D760008B03AE03CB03EE030C042F044C046F04B5 +:10D770008B04AF04CC04EF040D0530054D05700596 +:10D780008D05B005CD05F1050D0630064E06720675 +:10D790008E06B106CE06F2060F0732075007730752 +:10D7A0009007B307D107F407110834085208750829 +:10D7B0009108B108C608E70800000000000000005A +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F000000000000600070009000A000C000E00EF +:10D800001100140018001C00200026002C0033001A +:10D810003B0044004F005B006900780089009D00D8 +:10D82000B200CB00E600040126014B017401A10106 +:10D83000D201090244028502CB0217036903C20325 +:10D8400022048804F5046A05E6056906F4068707DC +:10D850002008C1086909180ACE0A890B4B0C110D62 +:10D86000DC0DAB0E7E0F531029110112D812AE132E +:10D87000811452151E16E416A5175D180D19B3195B +:10D880004F1ADF1A621BD81B401C991CE21C1C1D7E +:10D89000461D5F1D671D0600070009000A000C00F9 +:10D8A0000E001100140018001C00200026002C009F +:10D8B00033003B0044004F005B00690078008900A2 +:10D8C0009D00B200CB00E600040126014B0174016B +:10D8D000A101D201090244028502CB0217036903A8 +:10D8E000C20322048804F5046A05E6056906F40605 +:10D8F00087072008C1086909180ACE0A890B4B0C52 +:10D90000110DDC0DAB0E7E0F531029110112D81230 +:10D91000AE13811452151E16E416A5175D180D19C5 +:10D92000B3194F1ADF1A621BD81B401C991CE21C4A +:10D930001C1D461D5F1D671D0600070009000A002B +:10D940000C000E001100140018001C00200026001E +:10D950002C0033003B0044004F005B00690078005E +:10D9600089009D00B200CB00E600040126014B01B6 +:10D970007401A101D201090244028502CB021703FE +:10D980006903C20322048804F5046A05E6056906F2 +:10D99000F40687072008C1086909180ACE0A890B0E +:10D9A0004B0C110DDC0DAB0E7E0F53102911011223 +:10D9B000D812AE13811452151E16E416A5175D1861 +:10D9C0000D19B3194F1ADF1A621BD81B401C991C82 +:10D9D000E21C1C1D461D5F1D671D06000700090097 +:10D9E0000A000C000E001100140018001C0020009A +:10D9F00026002C0033003B0044004F005B00690010 +:10DA0000780089009D00B200CB00E60004012601E9 +:10DA10004B017401A101D201090244028502CB022B +:10DA200017036903C20322048804F5046A05E605A6 +:10DA30006906F40687072008C1086909180ACE0A92 +:10DA4000890B4B0C110DDC0DAB0E7E0F5310291101 +:10DA50000112D812AE13811452151E16E416A51722 +:10DA60005D180D19B3194F1ADF1A621BD81B401C21 +:10DA7000991CE21C1C1D461D5F1D671D29002F00FF +:10DA800035003B0043004C0055005F006B00780000 +:10DA900086009500A600B900CD00E300FC00160149 +:10DAA0003301520174019901C001EA0118024902CF +:10DAB0007D02B602F10231037503BC030804580469 +:10DAC000AD0406056305C5052B0696060507780710 +:10DAD000EF076B08EB086E09F4097F0A0C0B9B0B30 +:10DAE0002E0CC20C580DEF0D870E1F0FB80F4F10E4 +:10DAF000E6107B110E129E122B13B4133814B814B7 +:10DB00003315A71516167D16DD1635178517CD1793 +:10DB10000B1841186D189018A918B718BC182900CF +:10DB20002F0035003B0043004C0055005F006B00A8 +:10DB3000780086009500A600B900CD00E300FC0047 +:10DB400016013301520174019901C001EA01180262 +:10DB500049027D02B602F10231037503BC030804D9 +:10DB60005804AD0406056305C5052B069606050792 +:10DB70007807EF076B08EB086E09F4097F0A0C0BB6 +:10DB80009B0B2E0CC20C580DEF0D870E1F0FB80FFC +:10DB90004F10E6107B110E129E122B13B413381483 +:10DBA000B8143315A71516167D16DD16351785170B +:10DBB000CD170B1841186D189018A918B718BC1874 +:10DBC00029002F0035003B0043004C0055005F004A +:10DBD0006B00780086009500A600B900CD00E30038 +:10DBE000FC0016013301520174019901C001EA01E0 +:10DBF000180249027D02B602F10231037503BC032B +:10DC000008045804AD0406056305C5052B069606F1 +:10DC100005077807EF076B08EB086E09F4097F0A20 +:10DC20000C0B9B0B2E0CC20C580DEF0D870E1F0F0B +:10DC3000B80F4F10E6107B110E129E122B13B41367 +:10DC40003814B8143315A71516167D16DD163517BA +:10DC50008517CD170B1841186D189018A918B7180B +:10DC6000BC1829002F0035003B0043004C00550034 +:10DC70005F006B00780086009500A600B900CD001B +:10DC8000E300FC0016013301520174019901C00147 +:10DC9000EA01180249027D02B602F102310375035E +:10DCA000BC0308045804AD0406056305C5052B062E +:10DCB000960605077807EF076B08EB086E09F4096D +:10DCC0007F0A0C0B9B0B2E0CC20C580DEF0D870E10 +:10DCD0001F0FB80F4F10E6107B110E129E122B1360 +:10DCE000B4133814B8143315A71516167D16DD169F +:10DCF00035178517CD170B1841186D189018A918EE +:10DD0000B718BC185500550045004200000000003F +:10DD10001C023702540272029002B002D102F302D6 +:10DD200016033A035F038503AC03D503FF032904FD +:10DD300055048204B004DF040F0540057205A505F3 +:10DD4000D9050E0644067A06B206EA0622075C07E3 +:10DD50009607D0070B0847088308BF08FB08370958 +:10DD60007409B009ED09290A650AA10ADC0A170B32 +:10DD7000510B8B0BC30BFB0B330C690C9E0CD20CA1 +:10DD8000040D360D650D940DC10DEC0D150E3D0EF7 +:10DD9000630E870EA80EC80EE60E010F1B0F320F82 +:10DDA000460F590F690F760F820F8A0F900F940F4D +:10DDB000950FBA04C904D804E704F6040505140550 +:10DDC00023053205410550055F056E057D058B0570 +:10DDD0009A05A805B705C505D405E205F005FE05B9 +:10DDE0000C0619062706340642064F065C0669062D +:10DDF000760682068F069B06A706B306BE06CA06EF +:10DE0000D506E006EB06F60600070B0715071E070A +:10DE1000280731073A0743074C0754075C07640794 +:10DE20006C0773077A07810787078D0793079907A0 +:10DE30009E07A307A807AC07B107B407B807BB073D +:10DE4000BE07C107C307C507C707C807C907CA0771 +:10DE5000CB07CB07FA006C00FA006B006400D00718 +:10DE6000000028000000000000000000000000008A +:10DE700000000000000000000000000000000000A2 +:10DE8000190050003C000F001E00000001000000BF +:10DE900001000000948D0300508D0300948D030059 +:10DEA000548D030001000000785634127856341265 +:10DEB000014040000100000070AD0200FFFFFFFFC5 +:10DEC000AA0000001033030007000000010000005A +:10DED000FFFFFFFFFFFFFFFFFFFFFFFF010000004D +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E2500000000000000000000000000000000000BE +:10E2600000000000000000000000000000000000AE +:10E27000000000000000000000000000000000009E +:10E28000000000000000000000000000000000008E +:10E29000000000000000000000000000000000007E +:10E2A000000000000000000000000000000000006E +:10E2B000000000000000000000000000000000005E +:10E2C000000000000000000000000000000000004E +:10E2D000000000000000000000000000000000003E +:10E2E000000000000000000000000000000000002E +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:10E3200000000000000000000000000000000000ED +:10E3300000000000000000000000000000000000DD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000000000000000009D +:10E38000000000000000000000000000000000008D +:10E39000000000000000000000000000000000007D +:10E3A000000000000000000000000000000000006D +:10E3B000000000000000000000000000000000005D +:10E3C000000000000000000000000000000000004D +:10E3D000000000000000000000000000000000003D +:10E3E000000000000000000000000000000000002D +:10E3F000000000000000000000000000000000001D +:10E40000000000000000000000000000000000000C +:10E4100000000000000000000000000000000000FC +:10E4200000000000000000000000000000000000EC +:10E4300000000000000000000000000000000000DC +:10E4400000000000000000000000000000000000CC +:10E4500000000000000000000000000000000000BC +:10E4600000000000000000000000000000000000AC +:10E47000000000000000000000000000000000009C +:10E48000000000000000000000000000000000008C +:10E49000000000000000000000000000000000007C +:10E4A000000000000000000000000000000000006C +:10E4B000000000000000000000000000000000005C +:10E4C000000000000000000000000000000000004C +:10E4D000000000000000000000000000000000003C +:10E4E000000000000000000000000000000000002C +:10E4F000000000000000000000000000000000001C +:10E50000000000000000000000000000000000000B +:10E5100000000000000000000000000000000000FB +:10E5200000000000000000000000000000000000EB +:10E5300000000000000000000000000000000000DB +:10E5400000000000000000000000000000000000CB +:10E5500000000000000000000000000000000000BB +:10E5600000000000000000000000000000000000AB +:10E57000000000000000000000000000000000009B +:10E58000000000000000000000000000000000008B +:10E59000000000000000000000000000000000007B +:10E5A000000000000000000000000000000000006B +:10E5B000000000000000000000000000000000005B +:10E5C000000000000000000000000000000000004B +:10E5D000000000000000000000000000000000003B +:10E5E000000000000000000000000000000000002B +:10E5F000000000000000000000000000000000001B +:10E60000000000000000000000000000000000000A +:10E6100000000000000000000000000000000000FA +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA +:10E67000000000000000000000000000000000009A +:10E68000000000000000000000000000000000008A +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E7100000000000000000000000000000000000F9 +:10E7200000000000000000000000000000000000E9 +:10E7300000000000000000000000000000000000D9 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000000000000000000000B9 +:10E7600000000000000000000000000000000000A9 +:10E770000000000000000000000000000000000099 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000000000000000079 +:10E7A0000000000000000000000000000000000069 +:10E7B0000000000000000000000000000000000059 +:10E7C0000000000000000000000000000000000049 +:10E7D0000000000000000000000000000000000039 +:10E7E0000000000000000000000000000000000029 +:10E7F0000000000000000000000000000000000019 +:10E800000000000000000000000000000000000008 +:10E8100000000000000000000000000000000000F8 +:10E8200000000000000000000000000000000000E8 +:10E8300000000000000000000000000000000000D8 +:10E8400000000000000000000000000000000000C8 +:10E8500000000000000000000000000000000000B8 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 +:10E880000000000000000000000000000000000088 +:10E890000000000000000000000000000000000078 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 +:10E8C0000000000000000000000000000000000048 +:10E8D0000000000000000000000000000000000038 +:10E8E0000000000000000000000000000000000028 +:10E8F0000000000000000000000000000000000018 +:10E900000000000000000000000000000000000007 +:10E9100000000000000000000000000000000000F7 +:10E9200000000000000000000000000000000000E7 +:10E9300000000000000000000000000000000000D7 +:10E9400000000000000000000000000000000000C7 +:10E9500000000000000000000000000000000000B7 +:10E9600000000000000000000000000000000000A7 +:10E970000000000000000000000000000000000097 +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000000000077 +:10E9A0000000000000000000000000000000000067 +:10E9B0000000000000000000000000000000000057 +:10E9C0000000000000000000000000000000000047 +:10E9D0000000000000000000000000000000000037 +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000000000000000000000000000F6 +:10EA200000000000000000000000000000000000E6 +:10EA300000000000000000000000000000000000D6 +:10EA400000000000000000000000000000000000C6 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000000000086 +:10EA90000000000000000000000000000000000076 +:10EAA0000000000000000000000000000000000066 +:10EAB0000000000000000000000000000000000056 +:10EAC0000000000000000000000000000000000046 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB00000000000000000000000000000000000005 +:10EB100000000000000000000000000000000000F5 +:10EB200000000000000000000000000000000000E5 +:10EB300000000000000000000000000000000000D5 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000000000000095 +:10EB80000000000000000000000000000000000085 +:10EB90000000000000000000000000000000000075 +:10EBA0000000000000000000000000000000000065 +:10EBB0000000000000000000000000000000000055 +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF0000000000000000000000000000000000015 +:10EC00000000000000000000000000000000000004 +:10EC100000000000000000000000000000000000F4 +:10EC200000000000000000000000000000000000E4 +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 +:10EC500000000000000000000000000000000000B4 +:10EC600000000000000000000000000000000000A4 +:10EC70000000000000000000000000000000000094 +:10EC80000000000000000000000000000000000084 +:10EC90000000000000000000000000000000000074 +:10ECA0000000000000000000000000000000000064 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE0000000000000000000000000000000000024 +:10ECF0000000000000000000000000000000000014 +:10ED00000000000000000000000000000000000003 +:10ED100000000000000000000000000000000000F3 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 +:10ED400000000000000000000000000000000000C3 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE400000000000000000000000000000000000C2 +:10EE500000000000000000000000000000000000B2 +:10EE600000000000000000000000000000000000A2 +:10EE70000000000000000000000000000000000092 +:10EE80000000000000000000000000000000000082 +:10EE90000000000000000000000000000000000072 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED0000000000000000000000000000000000032 +:10EEE0000000000000000000000000000000000022 +:10EEF0000000000000000000000000000000000012 +:10EF00000000000000000000000000000000000001 +:10EF100000000000000000000000000000000000F1 +:10EF200000000000000000000000000000000000E1 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF600000000000000000000000000000000000A1 +:10EF70000000000000000000000000000000000091 +:10EF80000000000000000000000000000000000081 +:10EF90000000000000000000000000000000000071 +:10EFA0000000000000000000000000000000000061 +:10EFB0000000000000000000000000000000000051 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000000000011 +:10F00000837C20324006000A0E0A0001030108102A +:10F0100032004006F6090000000C0100000000006C +:10F020000013535904060000000000000008010905 +:10F0300000013233400600002819190000000800C2 +:10F0400000000800000008000000080000000800A0 +:10F05000000008000000080000000800F0EF0000B9 +:10F06000000008000000080000000800F0EF0000A9 +:10F070000000080000000800000008000000000078 +:10F08000000101000000000000000000000000007E +:10F09000000000000000000000000101010101006B +:10F0A000000100000000010101010001000000005A +:10F0B000010000010000000007000000010701033B +:10F0C000020314000A0A40000000C8003C000000CF +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000C800C8009600C80032 +:10F0F00007078000800005050000000000000000F8 +:10F1000006010000000017003900910010001400F3 +:10F11000F9FFC4FFFF7FFF7FFF7FFF7F50002C01BF +:10F120003200FA000A04B4B43232230500000000B1 +:10F1300000070D0000320D00000000203232323294 +:10F140003232323232323232323232323232000003 +:10F1500000000000000000000000000000000000AF +:10F160000A05000A00000000170F0012101200002C +:10F17000000000000000000000000000000000008F +:10F18000000000000F2332465000000078643C3C31 +:10F190003C3C3C3C08000000000000000F233246CD +:10F1A0005000000078643C3C3C3C3C3C0F141E2862 +:10F1B000000000000A0A0A0A0A0A0A0A19460000A0 +:10F1C000000000003746464646464646000000001E +:10F1D0000A0314005F00F1FF14000F000A00BC02D4 +:10F1E00000000000F8FF0000DC003200640028008E +:10F1F0000F000F001C023D011C02740400003F06BA +:10F200000000FF09F40100003F060000FF0932146E +:10F21000021E1E3202006400460046007700C80548 +:10F22000770088090000000040063000200001003F +:10F23000220000003A00520070008F00AF00CF00A3 +:10F24000EF000F012E014F016E018E01AD01CE01C5 +:10F25000EC010F022D024D026D028D02AC02CC02B8 +:10F26000EB020B032B034A036A038903AA03C903B6 +:10F27000E703FF0337040000000000000000000067 +:10F28000000000000000000000000000000000007E +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D000000000000000000000000000000000002E +:10F2E000000000000000000000000000000000001E +:10F2F00000000000000000000000F6093000460099 +:10F300000100480000003C00430066008500A900A1 +:10F31000C800E90009012A0149016B018901AB011B +:10F32000C901EB0109022B024A026C028A02AC02FB +:10F33000CA02EC020B032D034B036D038B03AE03D8 +:10F34000CB03EE030C042F044C046F048B04AF04B6 +:10F35000CC04EF040D0530054D0570058D05B00595 +:10F36000CD05F1050D0630064E0672068E06B10675 +:10F37000CE06F2060F073207500773079007B30750 +:10F38000D107F40711083408520875089108B1082C +:10F39000C608E708000000000000000000000000B0 +:10F3A000000000000000000000000000000000005D +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D0000201200019450000F16C000084D90600EC +:10F3E00029B1010010270000C40900000000030338 +:10F3F000030505050505014B0F00F00000000000A6 +:10F40000010000030303050505050500194500007B +:10F410000200000084DE01000000000014140A0A4B +:10F420001400000000000000141414140101010174 +:10F43000010040003200E8030F0008000500E10071 +:10F4400000001E502800B40050000400000000001E +:10F45000B40050006400A000000000014F01000053 +:10F460000000000078000D0D0A09320064006400FD +:10F470000A003200C800640064000F02E8E8F800E7 +:10F48000F8000200190000006A00750081008E007B +:10F490009D00AC00BD00CF00E200F7000D01260189 +:10F4A00040015C0179019901BC01E00106023002D2 +:10F4B0005B028902BA02EE0224035D039A03D903B8 +:10F4C0001B046004A904F40443059505E9054106FD +:10F4D0009C06FA065B07BE0724088D08F808650934 +:10F4E000D409450AB80A2D0BA20B190C900C080D73 +:10F4F000800DF80D6F0EE60E5C0FD00F4210B310AA +:10F5000021118C11F4115912BA1217137013C4136C +:10F5100013145D14A114E01418154B1577159C15E0 +:10F52000BB15D415E515EF15F31536003D00440065 +:10F530004C00560060006B00770085009300A4002B +:10F54000B500C900DE00F5000E0129014601650184 +:10F550008701AC01D401FE012B025B028F02C602BF +:10F5600001033F038003C6030F045D04AE040305DB +:10F570005D05BA051B068106EA065707C9073D085F +:10F58000B6083109B009320AB70A3E0BC70B520C54 +:10F59000DF0C6D0DFC0D8B0E1A0FA80F3610C3106B +:10F5A0004D11D6115B12DE125C13D7134D14BD142E +:10F5B00028158D15EC1544169516DE161F175817CD +:10F5C0008917B117D117E717F517FA174E0056002C +:10F5D00060006B00760083009100A000B100C200C3 +:10F5E000D600EB0002011A013501520170019101B0 +:10F5F000B501DB0103022E025C028D02C102F8029A +:10F6000032036F03B003F4033B048604D4042605DD +:10F610007C05D50532069206F5065C07C607330859 +:10F62000A30816098C09040A7E0AFA0A790BF80B5A +:10F63000790CFB0C7E0D010E830E060F870F071051 +:10F64000861003117D11F5116912DA124713AF13F9 +:10F6500013147214CB141E156B15B215F2152C165B +:10F660005E168916AC16C716DB16E716EB164E00AB +:10F67000560060006B00760083009100A000B1008E +:10F68000C200D600EB0002011A01350152017001DF +:10F690009101B501DB0103022E025C028D02C10261 +:10F6A000F80232036F03B003F4033B048604D4046E +:10F6B00026057C05D50532069206F5065C07C607C9 +:10F6C0003308A30816098C09040A7E0AFA0A790B82 +:10F6D000F80B790CFB0C7E0D010E830E060F870FC5 +:10F6E0000710861003117D11F5116912DA12471304 +:10F6F000AF1313147214CB141E156B15B215F2153B +:10F700002C165E168916AC16C716DB16E716EB1616 +:10F7100055005500450042000000000000000000B8 +:10F7200000000000000000000000000000000000D9 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000000000000000000000000000000A9 +:10F760000000000000000000000000000000000099 +:10F770000000000000000000000000000000000089 +:10F780000000000000000000000000000000000079 +:10F790000000000000000000000000000000000069 +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000000000000000000000000000000000019 +:10F7F0000000000000000000000000000000000009 +:10F8000000000000000000000000000000000000F8 +:10F8100000000000000000000000000000000000E8 +:10F8200000000000000000000000000000000000D8 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F86000000000000000000000000000F000220185 +:10F8700054013C00050000000000000000000000F2 +:10F880000000000000000000000000000000000078 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F9000000000000000000000000000000000000F7 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F9500000000000000000000000000000000000A7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B0000000000000000000000000000000000047 +:10F9C0000000000000000000000000000000000037 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA100000000000000000000000000000000000E6 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB90000000000000000000000000000000000065 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF0000000000000000000000000000000000005 +:10FC000000000000000000000000000000000000F4 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000000000000000A4 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD100000000000000000000000000000000000E3 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000000000000000000083 +:10FD80000000000000000000000000000000000073 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE300000000000000000000000000000000000C2 +:10FE400000000000000000000000000000000000B2 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF0000000000000000000000000000000000002 +:10FF000000000000000000000000000000000000F1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF500000000000000000000000000000000000A1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF000000000000000000000000000004E565409 +:00000001FF diff --git a/firmware/st_fts.ftb.ihex b/firmware/st_fts.ftb.ihex new file mode 100644 index 000000000000..9d390964077a --- /dev/null +++ b/firmware/st_fts.ftb.ihex @@ -0,0 +1,6813 @@ +:1000000055AA55AA0100000036390000450000003D +:100010004500000019000000190000000000000069 +:100020000000000019E1000000000000049F010032 +:10003000600A0000000000000000000014C51C342D +:10004000A9247135C067000056DB8ECA3F98FFFFB8 +:1000500000041000E101000039020000530200001A +:100060006D02000087020000A102000000000000F5 +:10007000000000000000000000000000DF6601003A +:10008000E766010000000000BB020000EF6601000F +:10009000F7660100036701000F6701001B6701009D +:1000A00027670100336701003F6701004B670100CC +:1000B00057670100C9020000636701006F67010014 +:1000C0007B670100836701008B6701009367010074 +:1000D0009F670100A7670100AF67010000000000F3 +:1000E000000000000000000000000000B7670100F1 +:1000F000BF67010000000000C767010000000000AA +:1001000000000000000000000000000000000000EF +:10011000450098100000FFFF0000000000000000F4 +:1001200000000000000000000000000000000000CF +:1001300000F002F800F068F80AA090E8000C824491 +:100140008344AAF10107DA4501D100F05DF8AFF26E +:10015000090EBAE80F0013F0010F18BFFB1A43F0A5 +:1001600001031847BC9C0100EC9C01000A444FF0BD +:10017000000C10F8013B13F0070408BF10F8014B06 +:100180001D1108BF10F8015B641E05D010F8016B4B +:10019000641E01F8016BF9D113F0080F1EBF10F8AF +:1001A000014BAD1C0C1B09D16D1E58BF01F801CBD2 +:1001B000FAD505E014F8016B01F8016B6D1EF9D555 +:1001C0009142D6D370470000103A24BF78C878C156 +:1001D000FAD8520724BF30C830C144BF04680C604D +:1001E000704700000023002400250026103A28BF95 +:1001F00078C1FBD8520728BF30C148BF0B60704799 +:100200001FB51FBD10B510BDDFF80CD0FFF7F8FF0C +:1002100016F004FB18F035FD0004100003B4FFF7DE +:10022000F1FF03BC18F036FD40BA7047C0BA704702 +:1002300012481349A1EB00014FF0200391FBF3F2A8 +:1002400002FB13114FF0CC334FF0CC344FF0CC35D0 +:100250004FF0CC364FF0CC374FF0CC384FF0CC3994 +:100260004FF0CC3AA0E8F807013AFBD119B140F8B9 +:1002700004AB0439FBD10348004700000000100024 +:1002800000041000E10000001EF0040F0CBFEFF3AB +:100290000880EFF309804FF001014FF0000212F0E7 +:1002A0005DBB1EF0040F0CBFEFF30880EFF3098075 +:1002B0004FF002014FF0000212F050BB1EF0040F8D +:1002C0000CBFEFF30880EFF309804FF003014FF00C +:1002D000000212F043BB1EF0040F0CBFEFF30880C6 +:1002E000EFF309804FF004014FF0000212F036BB2B +:1002F0001EF0040F0CBFEFF30880EFF309804FF0FE +:1003000005014FF0000212F029BB00B516F008FA03 +:100310005DF804EB00F032B81EF0040F0CBFEFF3F1 +:100320000880EFF309804FF006014FF0000212F051 +:1003300015BB00000A484FF0FF0101704FF00000AC +:1003400080F311884FF0000080F3098805484FF0D2 +:100350000201017062B604484FF08051016070479D +:1003600022ED00E0D408100004ED00E002484FF058 +:10037000805101607047000004ED00E04FF0200064 +:1003800080F31188EFF3098098B112480068124990 +:100390000968884217D0EFF309800E49096820E9FF +:1003A000F00F886000B50B48006816F0CDFA5DF8D4 +:1003B00004EB084808490A68026000688168B1E8EF +:1003C000F00F81F309884EF0040E4FF0000080F327 +:1003D00011887047D8081000DC081000EFF3118076 +:1003E0004FF0200181F31188704700004FF00000AA +:1003F00080F311887047000062B6704772B670478C +:10040000401EFDD17047000010B501463422FA4865 +:1004100018F0B4FB0121BDE81040002016F0CDBA61 +:1004200038B50446F548F44D2060204615F051FFDC +:1004300000226B460121104616F008FB0121002026 +:1004400016F0E7FA2878002802D012F0DEFAECE77E +:1004500038BD2DE9F047DFF8A88382460127D8F898 +:100460000000E84D90F8314010F8301F90F831004E +:100470004C4300F003008740A100284618F0DAFB47 +:100480000026DFF8749312E0DB483430FFF7C8FF32 +:100490000020D9F8081007E055F8202031F9103075 +:1004A0001A4445F82020401CA042F5DB761CBE42D1 +:1004B000EADB40460AE000BF026855F8241092F8D3 +:1004C000612002F0030211412AF81410641EF3D2D5 +:1004D000BDE8F0872DE9F04FDFF824B34FF00109B4 +:1004E000C84EDBF80000A7B090F8611090F83140DA +:1004F000C1F3810890F8305009FA08FA60198100B8 +:1005000006EB8407304618F095FBBB48343015F0F5 +:10051000BBFEB949343181F80690DBF8000090F851 +:100520006000820701D581F80490C00703D0B2486B +:100530003430FFF775FF00202BE0AF483430FFF771 +:100540006FFFDFF8B4B2620006A8DBF8181018F0ED +:10055000D0FA6A0011A8DBF81C1018F0CAFA20467D +:1005600006A906E056F8202031F910301A4446F862 +:100570002020401EF6D2284611A906E057F8202078 +:1005800031F910301A4447F82020401EF6D209F104 +:10059000010081465045D0DB9B4905E056F8240018 +:1005A00040FA08F021F81400641EF7D2974905E0DC +:1005B00057F8250040FA08F021F815006D1EF7D213 +:1005C00027B0BDE8F08F2DE9FF5FDFF834828D4F53 +:1005D000D8F8000090F8314090F8305007EB840ACA +:1005E0006019810004FB05FB0AEB8506384618F00C +:1005F00021FB4FEA8B01304618F01CFB7E4834305B +:1006000015F042FE7C494FF00109343181F8069023 +:1006100081F80490D8F8000090F86000C00702D07C +:100620000846FFF7FDFED8F8000090F86100C0F31F +:100630008101029100F0030103910299484609FAF1 +:1006400001F9039988400190002030E06A48343075 +:10065000FFF7E6FE6848D0E906328168204606E0EA +:1006600057F820C033F91080C44447F820C0401E1A +:10067000F6D2284607E000BF5AF8203032F910C001 +:100680009C444AF820C0401EF6D2DDE900029042A8 +:100690000BDA584607E000BF56F8202031F9103039 +:1006A0001A4446F82020401EF6D20098401C0090C4 +:1006B0004845CBDB019848451DDD4F4800213430CB +:1006C000884681710198A0EB090912E04A4834304C +:1006D000FFF7A6FE48488168584606E056F82020F5 +:1006E00031F910301A4446F82020401EF6D208F1A5 +:1006F0000108C145EADC444906E000BF57F8240080 +:10070000029A104121F81400641EF7D23F4905E017 +:100710005AF82500029A104121F815006D1EF7D2F3 +:1007200058463B4A06E000BF56F82010039B19418B +:1007300022F81010401EF7D2BDE8FF9F2DE9F041CE +:100740000546002016F0D9F9022016F0D6F903204C +:1007500016F0D3F92F4E002030702748343015F0B2 +:1007600093FD27482C4FDFF8B48000684FF0010458 +:1007700090F8600080074FEA05700AD500280FDA6C +:10078000A80708D53470FFF71EFF3C7088F80040BA +:1007900001E0002804DA307810B9FFF79BFE3C70C6 +:1007A000154FA80707F1340710D53078C8B9384677 +:1007B00015F06AFD3C711648FFF74BFE144800F037 +:1007C00031F81749087088F800400AE0680708D532 +:1007D0000948343015F058FD042038710C48FFF7F3 +:1007E00038FE032016F0A4F9022016F0A1F9BDE8A6 +:1007F000F041002016F09CB9F8081000B903000081 +:10080000B8071000E06710004C6D0120766D0120E4 +:100810001067012000041000ED071000EC07100025 +:10082000EE0710002DE9F04327494FF00009CC46B0 +:100830000F684B4697F8312097F8306097F8604082 +:1008400002FB06F109B2640736D5204C2468258ED8 +:100850008D4231D1323427E035461FE034F815108F +:1008600030F81580A1EB080109B2002901DB8846A8 +:1008700001E0C1F10008E04507DD002901DB8C46FD +:1008800001E0C1F1000C0FFA8CFC002900DA4942AA +:10089000B7F86280414501DD5B1C9BB26D1EDDD166 +:1008A00004EB460400EB4600521ED5D297F86400D4 +:1008B000984201D24FF001090548A0F800C0054850 +:1008C00003804846BDE8F083B8071000BC0710005D +:1008D000F0071000F207100010B501463422F84866 +:1008E00018F04CF90121BDE81040002016F065B861 +:1008F00038B50446F348F24D2060204615F0E9FC77 +:1009000000226B460121104616F0A0F801210020BC +:1009100016F07FF82878002802D012F076F8ECE77D +:1009200038BD2DE9FF410024DDE90A76082168463B +:1009300016F032FE0546082102A816F02DFE0246EA +:1009400000206FF07E0E14E0002100FB02F30DE0AA +:1009500007EB010C13F90CC0B444F44501DA01248F +:1009600003E0BCF17F0F00DD0224491C9142EFDB64 +:10097000401CA842E8DB204604B0BDE8F0812DE928 +:10098000FF410AAC082194E8C0010024684616F033 +:1009900003FE0546082102A816F0FEFD01460020D0 +:1009A00008E03256D21901D5012402E0FF2A00DD09 +:1009B0000224401CA842F4DB00200AE02A18B256A8 +:1009C00012EB080201D5012402E0FF2A00DD022417 +:1009D000401C8842F2DB2046CEE72DE9F04F87B07D +:1009E0004FF0010B15F0E4FC04460D4615F0E2FC57 +:1009F000DFF8D48206460F46D8F8000090F8E700EA +:100A000010F0600F05D02046294613F053F9044634 +:100A10000D46AD48016891F8310091F8301000FBA7 +:100A200001F8012104A810F08DFCDFF8A09200204D +:100A3000DFF89CA2D9F80010049B324691F91B10F4 +:100A40000390CDF800A0CDE901313B462046294670 +:100A500013F0AFF9012003900021049BCDF800A012 +:100A6000CDE9013132463B462046294613F0A1F933 +:100A70009348343015F008FC914905203431087151 +:100A80000846FFF735FF8E480221D0F808A005A8D8 +:100A900010F058FC8C4842460168B1F9C20101903F +:100AA000B1F9C411009108444010029050460599D4 +:100AB00013F0A1FE8246022105A810F0A6FC0198C1 +:100AC0004FF00008824502DC00998A450ADA7E4828 +:100AD00002990068AAEB0101B0F8C60191FBF0F0A1 +:100AE0004FFA80F80499CDE9001832463B4620467B +:100AF0002946FFF716FF01281DD0022824D0D9F877 +:100B000000100120724A81F81B800390049B8DE83D +:100B10000C0132463B462046294613F04AF9D9F8E3 +:100B20000000A5218176012104A810F06EFC07B019 +:100B30005846BDE8F08FD9F800104FF0000B81F84F +:100B40001BB00121B02007E0D9F800104FF0000BD6 +:100B5000B12081F81BB0012111F048FFDFE72DE93A +:100B6000F04FDFF8648189B04FF0010BD8F8000036 +:100B700090F831A090F83000079015F019FC044669 +:100B80000D4615F017FC0646D8F800000F4690F801 +:100B9000E70010F0600F05D02046294613F08AF8D0 +:100BA00004460D46012104A810F0CCFBDFF81C918F +:100BB0004FF00008049BD9F80000294690F91D2049 +:100BC000444805900090CDF80C80CDE901323246C2 +:100BD0003B46204613F0EDF8DDE904030121CDE9A1 +:100BE0000030CDE9028132463B462046294613F0CB +:100BF000E0F83348343015F047FB314906203431F2 +:100C000008710846FFF774FE2D480221D0F80880CD +:100C100006A810F097FB2C480068B0F9C811B0F98D +:100C2000CA01084440100090079806990AFB00F298 +:100C3000404613F0E0FD8246022106A810F0E5FBD5 +:100C400021484FF000080068B0F9C821524503DB85 +:100C5000B0F9CA21524508DD009AB0F8CC01AAEBE0 +:100C6000020191FBF0F04FFA80F80499CDE90018E9 +:100C700032463B4620462946FFF753FE4FF480712B +:100C8000012829D002282FD0D9F80010012081F89E +:100C90001D80DDE90423CDE90032CDE90280324632 +:100CA0003B462046294613F084F8D9F80000A521D8 +:100CB0000177012104A810F0A8FB584609B038E7D5 +:100CC0003C09100089080000B8071000BC0710009C +:100CD000E06F012008750120D9F800204FF0000BCB +:100CE000B02082F81DB006E0D9F800204FF0000BCC +:100CF000B12082F81DB011F079FED6E72DE9F04F52 +:100D000091B0DFF8BCA301200F90DAF8000090F852 +:100D100031100E9190F830000D9015F049FB80468F +:100D2000894615F047FB04460D46012106A810F040 +:100D300009FBDAF8000002AB002690F8340100F05D +:100D40000101E048006890F9202090F91F0005910A +:100D500083E84500DC4806990C90CDE90001224665 +:100D60002B464046494613F075F8DAF80000012199 +:100D7000224690F83401029600F00100CDE90410FB +:100D800006990C98CDE9000103962B46404649464A +:100D900013F060F8CD4815F077FACC49032088713C +:100DA0000846FFF7A5FDC94802213438D0E9067688 +:100DB000DAF80000B0F9CEA1B0F9D0B107A810F070 +:100DC000C1FA0AEB0B004010059038460E9A0799BD +:100DD00013F011FD0027504501DC584508DA05994C +:100DE000091AB7480068B0F8D20191FBF0F047B299 +:100DF00030460D9A079913F0FEFC0026504501DCA1 +:100E0000584508DA0599091AAD480068B0F8D401C8 +:100E100091FBF0F046B2022107A810F0F6FA06980E +:100E2000CDE9000722462B46029640464946FFF789 +:100E3000A6FD012826D002282ED0A2480121224654 +:100E400000682B46C77780F820609D48006890F8BE +:100E50003401CDE9027600F00100CDE904100699D5 +:100E60000C98CDE900014046494612F0F3FF954841 +:100E7000A52100688177012106A810F0C6FA0F9815 +:100E800011B056E68F4900200F900968C87781F8A5 +:100E900020001021B22008E08A4900200F90096844 +:100EA000C87781F820001021B32011F09FFDDEE704 +:100EB0002DE9F04F8DB04FF0010915F079FA064693 +:100EC0000F4615F077FADFF8F8810121D8F8000015 +:100ED00090F831000A9006A810F034FAD8F8000013 +:100EE000784C4FF0000A90F8840902AB00F0010141 +:100EF00020685546DFF8D0B190F9232090F9220000 +:100F0000059183E8250006990BF1980BCDE900B116 +:100F1000524653463046394612F09CFFD8F800003E +:100F20000121002290F88409029500F00100CDE92A +:100F3000041006990395CDE900B1134630463946B1 +:100F400012F088FF614815F09FF96049032008728C +:100F50000846FFF7CDFC5D4802213438856A09A8B0 +:100F600010F0F0F9D8F80000B0F9D611B0F9D801B6 +:100F7000084400EBD07040100190DDE909122846CA +:100F800013F039FCD8F800100025AB46B1F9D62192 +:100F9000824203DBB1F9D821824206DD019AB1F821 +:100FA000DA11101A90FBF1F045B2022109A810F0F5 +:100FB0002CFA069900228DE822081346304639465D +:100FC000FFF7DDFC012826D002282ED0216801225F +:100FD0003D4801F8225F81F801A0D8F8001091F88F +:100FE0003411029501F001010591CDE903A20699A2 +:100FF0000022CDE9000113463046394612F02AFF9F +:101000002168A52081F82100012106A810F0FDF932 +:1010100048460DB08DE521684FF0000901F822AF78 +:1010200081F801A04021B22008E021684FF00009BA +:10103000B32001F822AF81F801A0402111F0D6FCC5 +:10104000DEE770B505460124002015F056FD0220AC +:1010500015F053FD1A4E306890F8C0012840C007C3 +:1010600003D0FFF7BAFC00F00104306890F8C0012B +:10107000800704D5A80702D5FFF771FD044030684A +:1010800090F8C001400704D5680702D5FFF736FE87 +:101090000440306890F8C001000704D5280702D545 +:1010A000FFF706FF0440022015F042FD002015F076 +:1010B0003FFDE80702D0012001F0B3F9204670BDE2 +:1010C000B8071000BC071000D07A0120700910008A +:1010D00070B56F4C4FF6FF714FF426752068418252 +:1010E000294616F093FA00211F200EF1B1FD2A4681 +:1010F0002168BDE870401F23664816F0AEBA644808 +:1011000010B50068644C417D206841744FF48C61D7 +:1011100016F07CFA00211A200EF19AFD00211B2006 +:101120000EF196FD1A234FF480625C48216816F098 +:1011300094FA21681B23BDE810406022584801F54D +:10114000805116F08ABA2DE9F041564D041D0E4625 +:101150002146284616F05AFA3068534900EB8403BA +:101160008B4201D21C2312E0504A934212D2884291 +:101170000CD28846091A8F081C233A46294616F0D5 +:101180006CFAE21B05EB87011D2311E01D232246AB +:1011900029460EE0904214D2111A8F0890461D2362 +:1011A0003A46294616F059FAE21B05EB87011E2341 +:1011B000404616F052FA306800EB84003060BDE81B +:1011C000F0811E23E3E7F8B5364C3948009010341F +:1011D000022015F092FC00211C200EF139FD0021A7 +:1011E0001D200EF135FD00211E200EF131FD1021D4 +:1011F000204617F0FDFC00202080A0700120244D27 +:10120000E0704FF6FF71A1802868028AE280437D7A +:1012100028482372E688A0F8F86EA0F8FA1E042287 +:1012200080F8FC3E69461046FFF78DFF012300223F +:101230002146102013F042F86946FFF784FF01238E +:1012400000222146112013F039F86946FFF77BFF91 +:10125000286890F85012C90703D190F88002C0079F +:1012600008D0012300222146122013F027F86946F6 +:10127000FFF769FF012300222146132013F01EF817 +:101280006946FFF760FF022015F052FCF8BD000030 +:10129000B8071000F0EF0100BC071000F09F01003C +:1012A000F0AF0100E0671000F0CF0100F0DF0100B7 +:1012B000F0BF0100E06F01200B4801785A2911D1DD +:1012C0008188B1F57C7F0DD8418800290AD1064973 +:1012D00040781031022805D0A0F17002072A01D809 +:1012E00011F066BD704700000000012010B50146F6 +:1012F0003422FE4817F042FC0121BDE810400020D6 +:1013000015F05BBB2DE9F041F94CA0F16006092E08 +:10131000D4E91205D4E9142316D2DFE806F0051645 +:10132000263746586778870002462B46084600F065 +:101330009DF902460120002117F091FBD4E9022318 +:1013400010431943C4E9020175E0084600F08EF924 +:10135000012302460021184617F081FBD4E90A2335 +:1013600010431943C4E90A0165E002462B460846CA +:1013700000F07CF902460120002117F070FBD4E94F +:10138000062310431943C4E9060154E0084600F05F +:101390006DF902460120002117F061FBD4E90E230C +:1013A00010431943C4E90E0145E002462B460846A6 +:1013B00000F05CF9012302460021184617F04FFBAC +:1013C000D4E9042310431943C4E9040133E0084677 +:1013D00000F04CF902460120002117F040FBD4E94F +:1013E0000C2310431943C4E90C0124E002462B46A8 +:1013F000084600F03BF902460120002117F02FFBC0 +:10140000D4E9082310431943C4E9080113E008464E +:1014100000F02CF902460120002117F020FBD4E94E +:10142000102310431943C4E9100104E0012088404F +:101430006168084360602068401C2060BDE8F0815E +:101440002DE9F041174604460D46002609E0E00765 +:1014500003D03146384611F0C9FA761C6D084FEAC0 +:10146000340454EA0500F2D1E8E72DE9F041A04C3C +:10147000D4E90223D4E90656104619462A433343D9 +:10148000D4E90A56D4E90EC745EA0C053E43D4E92F +:10149000087C97432CEA030CC4E9087CD4E91023A8 +:1014A000AA43B343C4E910232268002AC6D06022AD +:1014B000FFF7C6FFD4E90A016122FFF7C1FFD4E9B3 +:1014C00006016222FFF7BCFFD4E90E016322FFF799 +:1014D000B7FFD4E904016422FFF7B2FFD4E90C019D +:1014E0006522FFF7ADFFD4E908016622FFF7A8FFE8 +:1014F000D4E910016722FFF7A3FF6068BDE8F0415F +:10150000682200219CE799E72DE9F14F4FF000098F +:1015100014F04EFF0646884614F04CFF744A044609 +:101520000D46C2E91401C2E912684FF01D0A4FF0DE +:10153000260B15F03EFD00273A460120002117F04A +:101540008EFA304001EA0801084322D0F8B20021A7 +:1015500015F037FD410705D50099C90602D5494662 +:10156000622010E0C10705D00099490702D549461D +:10157000602008E0009911F0C00F06D010F00A0FAB +:1015800003D049466420FFF7BDFE09F1010000F0D9 +:10159000FF097F1C5745CFDB15F00BFD00273E46AA +:1015A00032460120002117F05AFA20402940084312 +:1015B00020D0F0B2012115F004FD410705D50099B6 +:1015C000890602D53946632010E0C10705D000998D +:1015D000090702D53946612008E0009911F4C07F5F +:1015E00006D010F00A0F03D039466520FFF78AFEB7 +:1015F0007F1CFFB2761C5E45D2DDBDE8F84F15F0CA +:10160000D8BC10B50446002015F077FA3849002000 +:1016100014F00C0FC1E90800C1E90200C1E904009F +:10162000C1E90600C1E91000C1E90A00C1E90C00E6 +:10163000C1E90E004860086009D1E00607D4A006A1 +:1016400005D4600603D4E00501D4200602D5204667 +:10165000FFF75AFFA00702D0204600F022F8FFF75C +:1016600004FFBDE81040002015F062BA2DE9F041FA +:1016700016461F4680464FF0FF35002422460120C3 +:10168000002117F0ECF930403940084304D06D1CBC +:10169000454501D12046D1E6641C402CEED3002004 +:1016A000CCE62DE9FF410446012000F038F88046E1 +:1016B00014F07EFECDE9000114F07CFECDE90201BC +:1016C0000821684615F068FF0746082102A815F0B2 +:1016D00063FF0546074EE00707D0306842462946BB +:1016E000B0F8DE30384600F04AF805E08009100016 +:1016F00008041000B8071000A00707D5306842465C +:101700002946B0F8DE30384600F089F86A480168AA +:1017100041F00201016010F05BFABDE8FF8130B5D5 +:1017200085B00446684614F0AFFD64480090022C72 +:1017300015D007208DF80400614C684614F0C9FDEF +:10174000002204AB0121104615F080F90121002090 +:1017500015F05FF9207830B111F057F9EDE703206B +:101760008DF80900E8E714F023FE564DC5E9120193 +:1017700014F020FEC5E91401A06805B030BD2DE9C4 +:10178000FF5F9B4692460F46002544E000984FF0CD +:1017900000094C46A0F101083AE000BF04FB0750E5 +:1017A00081B2601C00FB075080B23AF811203AF871 +:1017B0001000101A00B2584502DDB9F1000F0AD02E +:1017C000CBF10001884213DAB9F1000F06D04FF0D7 +:1017D0000009214618E04FF0010914E0002604E05A +:1017E00031466620FFF78EFD761CA642F8D90EE042 +:1017F000B9F1000F0BD021466620FFF783FD00985A +:10180000801E844203D1611C6620FFF77BFD641CAF +:101810004445C3D36D1CBD42B8D3BDE8FF9F2DE93D +:10182000FF5F9B4692460D46002641E04FF00009BF +:101830004C46A5F1010838E006FB0540611C06FB9B +:10184000051180B289B23AF810203AF81100101A46 +:1018500000B2584502DDB9F1000F0AD0CBF100010A +:10186000884213DAB9F1000F06D04FF00009214683 +:1018700017E04FF0010913E0002704E03946672024 +:10188000FFF740FD7F1CA742F8D90DE0B9F1000F2A +:101890000AD021466720FFF735FDA81E844203D1F8 +:1018A000611C6720FFF72EFD641C4445C4D3761CE1 +:1018B00000988642BAD3B0E7D80710009D12000006 +:1018C0008009100008041000144908604FF400510A +:1018D000002015F072B838B5002015F00EF9AFF2FF +:1018E000170016F051FF00224FF400546B462146BA +:1018F000104615F0ABF82146002015F08AF80020BC +:1019000015F016F90648A522016804480A74006813 +:1019100020F07F424A6116F05BFF38BD6004100082 +:10192000BC071000020004D0012A04D0022805D010 +:1019300002E0012000E0042014F05CBC00207047AD +:1019400010B501463422FE4817F018F90121BDE810 +:101950001040002015F031B830B585B00446684617 +:1019600014F092FCF74800900CB3012C21D0022C0B +:1019700021D0032C19D108208DF80400F04D032448 +:10198000684614F0A6FC002204AB0121104615F0B5 +:101990005DF80121002015F03CF82878002804D0DB +:1019A00011F033F8641E002CEADC05B030BD0520D0 +:1019B000E2E70620E0E702208DF80900DEE72DE9E6 +:1019C000F14F88B014F0F4FC8346029114F0F2FC5D +:1019D0008146DD4C08988A460028206807D0B0F878 +:1019E0007A110898FFF79EFF0490D84812E090F80B +:1019F000E70010F0600F05D05846029912F05AF92E +:101A0000834602912068B0F872110898FFF78AFFA8 +:101A10000490CF480390402007900690C848B82112 +:101A2000B83817F007F9002000900898FFF794FFE6 +:101A3000C34800273E468068059001203D4601903E +:101A40002A460120002117F00AF8029A00EA0B004A +:101A50001140084341D0002422460120002116F005 +:101A6000FEFF02460B4600EA090001EA0A010843AC +:101A700020D0B348B83800EBC6018E4603C900EA4F +:101A8000020C01EA03085CEA080C12D1DDF814C06C +:101A90003CF91780DDF810C0E04504DC1043194321 +:101AA000CEE9000105E022463146009B039815F07F +:101AB000D8F97F1C0698641C8442CDDBA048B83856 +:101AC00000EBC601D1E9000280EA090082EA0A02BD +:101AD000104301D000200190761C07986D1C8542B0 +:101AE000AEDB0198012804D00098401C00907F28AC +:101AF0009BDD019809B0BDE8F08F2DE9F14F98B05A +:101B000014F056FCCDE90C0114F054FCCDE91001A1 +:101B100018988D4C00285CD02068B0F87A1118987D +:101B2000FFF700FF0F9089480690402082460E90F4 +:101B300008210CA815F030FD0446082110A815F066 +:101B40002BFD44438348019000F5E6602146029056 +:101B500017F04EF86100019817F04AF87848B8215C +:101B6000B83817F067F84FF000091898FFF7F4FE3F +:101B7000734800273C4680680A90C9F100004FF086 +:101B8000010B3E46139032460120002116F067FFFC +:101B9000DDE90C231040194008436ED000252A4689 +:101BA0000120002116F05BFFDDE9108C02460B4698 +:101BB00000EA080001EA0C01084373D06048B83815 +:101BC00000EBC70CDCE900011040194008430FD0BE +:101BD00093E0DDE90C0112F06DF8CDE90C0120680D +:101BE000B0F872111898FFF79DFE0F9058489BE7C8 +:101BF000B9F1000F0ADA0A9830F914100F988142EF +:101C000001DB002100E00121029801550A980F999B +:101C100030F91400884231DD0299095D11B10129C2 +:101C200009D06AE0B9F17F0F67DA019909F1010380 +:101C300021F8140051E0DCE9001011431843CCE90D +:101C40000010019830F914100F98091A0A9830F909 +:101C500014200F98A2EB000000D54942002800DABA +:101C60004042814205DC139B2A4639465B1C06989C +:101C700036E0019820F814203FE052E037DA02996C +:101C8000095D012901D071B137E0139911F17F0F7E +:101C900033DD01992A4621F81400139B39465B1E57 +:101CA00006981DE02AE0DCE9001011431843CCE956 +:101CB000001001980F9A30F914100F98081A0A9919 +:101CC00031F91410A1EB020200D54042002A00DADB +:101CD0005242904207DCA9F101032A463946069890 +:101CE00015F0BFF809E0019820F8141005E0DCE9D0 +:101CF000001011431843CCE90010641C6D1C5545BD +:101D0000FFF64DAF0E48B83800EBC701D1E900012E +:101D1000DDE9102350405940084301D04FF0000B3B +:101D20007F1C0E98761C8642FFF62DAFBBF1010F8B +:101D300005D009F10109B9F17F0F7FF716AF0BE06C +:101D4000700A1000F1180000B80710000875012093 +:101D5000E06F0120E0671000584619B0CBE62DE98E +:101D6000F04F044685B0002014F0C7FE022014F0A6 +:101D7000C4FE14F01FFBCDE90201FE480490402789 +:101D8000082102A815F008FC8046012C70D1DDE97D +:101D90000201CDE9000101220023049815F070F83A +:101DA000DFF8D49300206FF07E0509EB480B690C37 +:101DB00005E000BF29F810100BF80050401C40450A +:101DC000F8DB0320FFF7C8FDEC4800242646D0F8D6 +:101DD00008A032460120002116F041FEDDE9022371 +:101DE0001040194008431DD03AF9141039F9140075 +:101DF000002900DA4942002800DA404281420ADA2A +:101E000032460021049815F021F80BF804003AF846 +:101E1000141029F814102B4632460021049815F0AE +:101E200020F8641C761CBE42D3DB6D1C7F2DC8DD00 +:101E300000252C4622460120002116F010FEDDE987 +:101E4000022310401940084307D01BF905302246F1 +:101E50000021049815F005F86D1C641CBC42E9DBF8 +:101E6000C74826220499006800F5865016F041FE06 +:101E70000026C44D344622460120002116F0EFFD15 +:101E8000DDE9022310401940084307D02246002113 +:101E9000049814F0DBFF25F81600761C641CBC4285 +:101EA000E9DB0320FFF758FDB4488168002006E015 +:101EB00031F8103008EB0002401C25F81230404584 +:101EC000F6DB022014F034FE002014F031FE05B0E1 +:101ED00011E62DE9F04F87B0002014F00EFE02202D +:101EE00014F00BFE4FF0000B14F064FACDE904017E +:101EF000A0480390082104A815F04EFB06460020D8 +:101F0000DFF87482CDE9000008EB460505EB060911 +:101F10000320FFF721FDDFF864A200242746DAF84A +:101F2000080002901AE03A460120002116F097FDC1 +:101F3000DDE904231040194008430ED03A46002141 +:101F4000039814F083FF2855029830F8141028F8ED +:101F50001410002009F80400641C7F1CB442E2DB6A +:101F600000273C4615E022460120002116F077FDAF +:101F7000DDE9042310401940084309D0EB577F2BBB +:101F800005DA224600215B1C039814F06AFF7F1CCF +:101F9000641CB742E7DB0320FFF7DEFC00200124CE +:101FA000DAF8083014E000BF33F9102038F91010C7 +:101FB000002A00DA5242002900DA49428A4206DA4F +:101FC00029567F2903DA491C295409F80040401C8E +:101FD000B042E9DB00273C4616E022460120002102 +:101FE00016F03DFDDDE904231040194008430AD0F6 +:101FF000EB5713F17F0F05DD224600215B1E03988E +:1020000014F02FFF7F1C641CB742E6DB0320FFF7B0 +:10201000A3FC5A488368002019E000BF19F800109B +:10202000A1B933F9101038F91020002900DA49421B +:10203000002A00DA5242914208DA295611F17F0F44 +:1020400004DD491E2954022209F80020401CB04238 +:10205000E4DB0024274627E03A460120002116F061 +:10206000FEFCDDE90423824602911040194008433A +:1020700019D02B573A460021039814F0F2FE19F8B4 +:10208000040078B9DDE9002302994AEA0200194305 +:10209000CDE9000138F91400FE30B0F5FE7F01D91A +:1020A0004FF0010B641C7F1CB442D5DB082168464D +:1020B00015F072FAB04208DBBBF1000F03D000212B +:1020C000B42010F093FC07B015E5002036E00320A3 +:1020D000FFF742FC2948002427468068029023E04D +:1020E0003A460120002116F0BAFCDDE9043C024624 +:1020F0008E46184001EA0C01084314D0DDE90003C4 +:1021000002EA000C0EEA03015CEA010C0AD119F99B +:102110000410012943D0022972D002434EEA030180 +:10212000CDE90021641C7F1CB442D9DB082168463C +:1021300015F032FAB04208DA0AF10100824612487C +:10214000006890F8E2115145C1DC0D482622039940 +:10215000006800F5865016F0CCFC0821684615F0A2 +:102160001BFAB04202DBBBF1000F11D00021B420FA +:102170000CE00000E07E0120E0671000700A100013 +:10218000BC071000C26D0120B807100010F02EFC33 +:10219000022014F0CDFC002014F0CAFC93E7029852 +:1021A00038F9141030F91400002801DB034600E070 +:1021B0004342002900DA49428B4205DC295D7F2930 +:1021C00002D028F8140047E0002109F80410DDE9E6 +:1021D0000001024302984EEA0103CDE9002330F9E1 +:1021E000141038F91400002900DA4942002800DAF6 +:1021F0004042814233DD285D401E28552FE0FFE735 +:10220000029830F9141038F91400002901DB0B464C +:1022100000E04B42002800DA4042834205DC2857A8 +:102220007F3002D028F81410E5E7002009F80400F8 +:10223000DDE900130A434EEA0300CDE900200298CD +:1022400030F9141038F91400002900DA4942002846 +:1022500000DA4042814202DD285D401CCDE72B5769 +:102260003A460021039814F0FCFD5BE72DE9F041AC +:1022700005460124002014F040FC022014F03DFC2F +:102280004C4EE8074FF000074FF0A50808D000F0CB +:1022900020F810F0010403D03068C77680F81A8067 +:1022A000A80708D500F05BF82040040003D0306890 +:1022B000477780F81C80002014F03AFC022014F0CC +:1022C00037FCE80702D0012000F0ABF82046BDE85B +:1022D000F0812DE9FC47012614F06AF804460D460A +:1022E00014F068F8DFF8D09007468846D9F8000067 +:1022F00090F8E70010F0600F05D02046294611F055 +:10230000D9FC04460D46D9F8000090F87001C007CA +:102310001FD0CDE9007822462B46284814F0B0FDA6 +:10232000D9F8000090F87011C90712D090F8E700B2 +:10233000C0F3411002284FF0000002D3FFF7DDFB8D +:1023400001E0FFF73CFB060003D10121742010F0EF +:102350004DFB0020FFF700FB3046BDE8FC872DE970 +:10236000FC41012614F024F804460D4614F022F82E +:10237000114F3A6892F87821D20715D0CDE90001C3 +:1023800022462B460E4814F07BFD386890F8780101 +:10239000C00709D00120FFF712FB060004D14FF45B +:1023A0008071742010F022FB0120FFF7D5FA30462F +:1023B000BDE8FC81BC071000B8071000E06F0120E9 +:1023C0000875012010B5FFF786FA0120FFF7C7FC5A +:1023D000012000F094F95320FFF748FF00F00104BA +:1023E0004FF4D67001F0E5F8204205D0FEF7EBFE81 +:1023F000BDE81040FEF783BE10BD10B5FFF76BFAC5 +:102400000120FFF7ACFC012000F079F940F2FF1049 +:10241000FEF717FE002803D0BDE81040FEF76FBEA0 +:1024200010BD2DE9F0411349096891F8C121D20787 +:102430001DD001281BD1114F91F8312091F8301097 +:102440003D684A4302200C4E14B23235FEF776F94D +:10245000032014F052FB3868620031460486284697 +:1024600016F047FBBDE8F041032014F061BBBDE866 +:10247000F0810000B807100010670120BC071000B1 +:1024800010B501463422FA4816F078FB0121BDE868 +:102490001040002014F091BA30B585B0684613F0B2 +:1024A000F3FEF44802220078E0B1032101280DD0A8 +:1024B00003280ED0022818D0042205280CD00428A6 +:1024C0000DD006280ED007280FD010E08DF806108A +:1024D0000DE08DF808100AE08DF80A2007E08DF86D +:1024E0000A1004E08DF8062001E08DF80820E2488B +:1024F000DF4D03240090684613F0EBFE002204AB8E +:102500000121104614F0A2FA0121002014F081FAF2 +:102510002878002804D010F078FA641E002CEADC39 +:1025200005B030BD2DE9F34FD24D87B006200E46E1 +:10253000287013F03DFFCDE9040136200290CF4C06 +:1025400007984FF0400AC0B1012821D002287DD160 +:1025500007202870CA48DFF818830090206808F127 +:10256000280841F2421108440190082104A815F0FE +:1025700013F80446012E1ED089E0C148DFF8F0822E +:102580004838009008F1180841F2E6012068EAE7AF +:1025900013F010FFCDE90401B94841F21C112838AD +:1025A00000902068DFF8C88208440190262008F1D6 +:1025B0001C080290D9E7024604A9009814F0A0FC78 +:1025C000DFF8C0926FF07E0609EB44000390002014 +:1025D000710C04E029F81010039A1654401CA04214 +:1025E000F8DB00BFFFF758FF0025D8F800B02F46F2 +:1025F0003A460120002116F032FADDE904231040AA +:10260000194008431BD03BF9151039F91500002972 +:1026100000DA4942002800DA4042814209DA3946AC +:10262000009814F05BFC039948553BF8151029F805 +:10263000151032463946009814F057FC6D1CA5421F +:1026400002D07F1C5745D3DB761C00E054E07F2E80 +:10265000C8DD002635462A460120002116F0FFF984 +:10266000DDE9042310401940084306D003982946A9 +:102670008257009814F039FC761CA64202D06D1CDB +:102680005545E8DBDDE90010029A16F032FA0798AA +:1026900030B1012806D0022806D0032805D103E076 +:1026A000794E02E0794E00E0794E00273D462A46F9 +:1026B0000120002116F0D3F9DDE904231040194070 +:1026C000084306D02946009814F008FC26F81700A5 +:1026D0007F1CA74202D06D1C5545E8DBFFF7DCFEEE +:1026E0000020D8F8001005E031F810202318401C15 +:1026F00026F81320A042F7DB09B0BDE8F08F10B533 +:102700000446002014F0F9F9022014F0F6F92146ED +:102710000020FFF707FF21460120FFF703FF2146B6 +:102720000220FFF7FFFE022014F002FABDE810407D +:10273000002014F0FDB92DE9F04F4E4E04468DB047 +:102740000620307013F034FECDE90A0136200690E1 +:1027500050481021494D006890F8E3B107914CB3FF +:10276000012C32D0022C7DD10721317044490391D4 +:10277000296841F242123E4F11440891283790F8DF +:10278000E4B1402007900020029008210AA814F02C +:1027900003FFDFF8F0A006460AEB4605A8190190F2 +:1027A0000020CDE90400FFF777FE00242046D7F88B +:1027B000009035E032482E4F48380390296841F2A6 +:1027C000E600084418370890DDE713F0F3FDCDE983 +:1027D0000A012B48264F28380390286841F21C1123 +:1027E00008441C37089026200690CCE702460120BA +:1027F000002116F034F9DDE90A231040194008439E +:102800000CD04146039814F069FB285539F8141090 +:102810002AF81410019900200855641C08F10100E1 +:102820008046B442E2DB0024204615E00246012047 +:10283000002116F014F9DDE90A231040194008437D +:1028400008D02A577F2A04DA4146521C039814F014 +:102850004CFB641C08F101008046B442E6DBFFF744 +:102860001BFE00E0EDE0002001243B6828E00000B2 +:10287000A40A10006804100031240000BC071000F6 +:10288000507F0120E06710005A6E0120AE6E0120DB +:10289000466F0120B807100033F910103AF91020E4 +:1028A000002900DA4942002A00DA5242914206DA4F +:1028B00029567F2903DA491C295401990C54401CDC +:1028C000B042E9DB0024A0466FF07E0915E04246E5 +:1028D0000120002116F0C3F8DDE90A231040194059 +:1028E000084308D02A574A4504DD4146521E039842 +:1028F00014F0FBFA641C08F10108B442E7DBFFF7AF +:10290000CBFD00203B6817E00199095C99B933F9C8 +:1029100010103AF91020002900DA4942002A00DAA2 +:102920005242914207DA2956494504DD491E29548D +:10293000019902220A54401CB042E5DB00242046E3 +:1029400027E002460120002116F089F80091DDE918 +:102950000A23814610401940084318D02A5741469F +:10296000039814F0C2FA0198005D78B9DDE90423F8 +:10297000009849EA02011843CDE904103AF914001D +:10298000FE30B0F5FE7F01D901200290641C08F1F1 +:1029900001008046B442D4DB082104A814F0FCFDF9 +:1029A000B04247DA002037E0FFF776FD38680024B0 +:1029B0000090204625E002460120002116F04FF845 +:1029C000DDE90A8C02460B4600EA080001EA0C0128 +:1029D000084314D0DDE9040C02EA000103EA0C0804 +:1029E00051EA08010AD10199095701292BD002297E +:1029F00059D0024343EA0C03CDE90423641C09F1D6 +:102A000001008146B442D6DB082104A814F0C4FDBD +:102A1000B04204DA0998401C09905845C4DB069A74 +:102A20000399089816F065F8082104A814F0B4FD7D +:102A3000B04202DB0298002803D0B52007990FF0BE +:102A4000D5FF0DB059E600983AF9141030F914008A +:102A5000002801DB844601E0C0F1000C002900DA07 +:102A600049428C4505DC295D7F2902D02AF81400F3 +:102A700045E0019900200855DDE9040102430B43BC +:102A8000CDE90423009830F914103AF91400002914 +:102A900000DA4942002800DA4042814232DD285DF6 +:102AA000401E28552EE000983AF9141030F9140011 +:102AB000002801DB844601E0C0F1000C002900DAA7 +:102AC00049428C4505DC29577F3102D02AF8140091 +:102AD000E5E7019800210155DDE9040102430B43BC +:102AE000CDE90423009830F914103AF914000029B4 +:102AF00000DA4942002800DA4042814202DD285DC6 +:102B0000401CCEE72A574946039814F0EEF975E7C2 +:102B100010B5002013F0F1FF022013F0EEFF0020AB +:102B2000FFF709FE0120FFF706FE0220FFF703FE74 +:102B3000022013F0FDFFBDE81040002013F0F8BFA5 +:102B40002DE9F047FF4800252C46D0E91478D0F84D +:102B500034902E46824632460120002115F07FFF38 +:102B6000384001EA0801084304D019F80600A842D9 +:102B700000D90546761C402EEDD3DAE91678DAF84E +:102B80003890002632460120002115F068FF3840B9 +:102B900001EA0801084304D019F80600A04200D950 +:102BA0000446761C402EEDD3DAF8442050461570CA +:102BB000DAF848100C70DAF82C30DAF82470DAF809 +:102BC00030601B783F782B443B44DAF82870367825 +:102BD0003F7826443E44D0E9147C57EA0C070DD0D8 +:102BE000D0E9167C57EA0C070AD0FF27B34213D26C +:102BF000F31A2B44FF2B07D813700BE0147009E075 +:102C000015700D70BDE8F0871770826942F400728C +:102C1000CAF818200C70F5E79E420DD29B1B234486 +:102C2000FF2B01D80B7005E00F70816941F4007132 +:102C3000CAF818101570E5E71570EBE72DE9F041BB +:102C40001F460D46002A1FDDBE4C77B1B4F90A605D +:102C5000114611F01EFEB042287812DAFF2807D282 +:102C6000401C28700020BDE8F081B4F90860EFE74F +:102C7000A0691FB140F00200A06105E040F40060CF +:102C8000FAE708B1401E28700120ECE72DE9F04179 +:102C90001E460D46002A1ADDAA4C66B1B4F90A7028 +:102CA000114611F0F6FDB84211DD287850B1102818 +:102CB00004D3103803E0B4F90870F1E7002028705D +:102CC0000020D0E7A06926B140F00100A0610120FA +:102CD000C9E740F48060F9E72DE9F14F82B00025A3 +:102CE0009848029A2C46FF2102B3D0F82C90022675 +:102CF0004FF0180B89F80010D0F8308088F80010D9 +:102D0000B0F90A70310200910169002900DC012547 +:102D10008C484069002800DC0124FFF711FFFFF711 +:102D2000BBFB00980FF0FDFD85B121E0D0F82490A9 +:102D30004FF400664FF0180B89F80010D0F8288087 +:102D400088F80010B0F90870F110DCE7DFF8F4A1A2 +:102D50003A46DAF81C00DAF81010006800F063FC5C +:102D6000012805D1DAF8181031430125CAF81810E6 +:102D70008CB9DFF8D0A13A46DAF82000DAF814105E +:102D8000006800F050FC012805D1DAF81810314332 +:102D90000124CAF818100DB1002C4ED12F4626463A +:102DA0004FF0170A4FB96748029BC16902690F6863 +:102DB00049463846FFF76AFF07464EB96148029B0D +:102DC000016A42690E6841463046FFF75FFF0646DA +:102DD000FFF7B6FEFFF760FB00980FF0A2FD07B10A +:102DE00016B9BAF1010ADDD22F46564DABF10106F4 +:102DF0003FB9E869029B494600682A69FFF71EFF50 +:102E000007463CB9286A029B414600686A69FFF799 +:102E100015FF0446FFF794FEFFF73EFB00980FF006 +:102E200080FD07B10CB9761EE2D2012F05D1012C2D +:102E300003D1A86920F40070A861BDE8FE8F2DE9D8 +:102E4000F04F9A46914600223E4B83461446B3F912 +:102E50000C7010460123904615E000BF09EBE40515 +:102E600004F0070C2E7803FA0CF535420AD03BF932 +:102E70001250BD4203DC0AF80230012001E00AF8DA +:102E80000280521C641C8A42E8DB36E42DE9FF5FB5 +:102E900000244FF001089A4617462546DFF8A49013 +:102EA0004646DDF83CB051E00AEBE50005F00701CD +:102EB000007806FA01F2024247D01BF8040001280C +:102EC0003FD00098B9F90C1030F914208A421DDA6D +:102ED0002946019814F02FF8FF280EDA401CC2B2E0 +:102EE0004FF000082946019814F027F8009830F8B0 +:102EF00014100E9820F8141023E00BF80460D9F891 +:102F0000181041F00801C9F818101AE00E9830F9AD +:102F10001400002813DD401AA2EB010100D5404245 +:102F2000002900DA4942884209DC2946019814F058 +:102F300002F8401EC2B22946019813F0FEFF0BF8BA +:102F4000046001E068041000641C6D1CBC42ABDB33 +:102F5000404604B0BDE8F09F2DE9FF5F00244FF02C +:102F600001089A46174625464646DFF86C94DDF878 +:102F700038B030E00AEBE50005F00702017806FA08 +:102F800002F0084226D01BF80400012821D0009846 +:102F900030F91410B9F90C0081421ADD2946019864 +:102FA00013F0C9FF00280CDD4FF00008042801DBF6 +:102FB000001F00E00020C2B22946019813F0BDFFB7 +:102FC00007E00BF80460D9F8181041F00401C9F8C3 +:102FD0001810641C6D1CBC42CCDB4046B9E72DE9DF +:102FE000F04F95B00024254620210CA815F022FEB4 +:102FF000282102A815F01EFEF7480169002900DC0F +:1030000001244269002A00DC0125F34A8146064674 +:10301000FF235032406B00F010FBEF4AFF23583281 +:103020007169B06B00F009FBFFF78AFDFFF734FA16 +:103030004FF4806A50460FF074FC8CB1D9F81C0034 +:10304000E54A4E4600680CAB5032D9F81010FFF735 +:10305000F6FE012804D1B069012440F00800B061F7 +:103060008DB1D9F82000DC4A4E46006802AB5832D8 +:10307000D9F81410FFF7E3FE012804D1B069012547 +:1030800040F00800B0610CB1002D78D12646A8466A +:1030900000276EB90CA80090D9F81C00CE4BD9F8C7 +:1030A000102000685033D9F83410FFF755FF06465A +:1030B000B8F1000F0DD102A80090D9F82010C64B2E +:1030C000D9F8142008685833D9F83810FFF744FFAE +:1030D0008046FFF735FDFFF7DFF950460FF021FC82 +:1030E00016B1B8F1000F02D17F1C602FD1DBDFF8E1 +:1030F000ECB2D9F81000264641000BF5E6684C46C4 +:10310000584615F075FD60694100404615F070FDA8 +:103110000027D146FFF7C0F948460FF002FC5EB920 +:103120000CA8CDE900B0E069AB4B226900685033D0 +:10313000616BFFF7ABFE06465DB902A9CDE90081E0 +:10314000206AA54B626900685833A16BFFF79EFEA9 +:103150000546FFF7F5FCFFF79FF948460FF0E1FB46 +:1031600006B115B97F1C602FD4DB012E07D1012DCC +:1031700005D1A069810502D520F40070A06115B0C9 +:1031800083E62DE9FF5F4FF0010800259A461746B8 +:103190002C46DFF844924646DDF83CB03AE000BFEA +:1031A0000AEBE40004F00702017806FA02F0084294 +:1031B0002FD01BF8040058BB2146019813F08EFE57 +:1031C0000099B9F90E2031F915304946934212DDC4 +:1031D0000E9A7F3A904208DD0E99421A21460198D4 +:1031E00013F083FE4FF0000812E0886940F04000C1 +:1031F000C9F818000CE00BF804600E99C1F17F01CA +:10320000814205DD0E9942182146019813F06DFEAA +:103210006D1C641CBD42C3DB40469AE62DE9F04FAD +:103220006D4C9FB02169B9B3002083466069A0B39B +:1032300000208246BBF1000F02D0BAF1000F5AD134 +:10324000674B04AD0DCB85E80D00634A7F235032F8 +:10325000E06B00F0F2F9604A7F2358326169206C1C +:1032600000F0EBF90026A14604A85C4650F8268041 +:103270005546202111A815F0DDFC282107A815F0DE +:10328000D9FCD9F81810002721F04001C9F818100E +:10329000FFF702F934B114E000E001E00120C4E7D7 +:1032A0000120C6E711A9CDE90081D9F81C104A4BCD +:1032B000D9F8102008685033D9F83C10FFF761FFA7 +:1032C000044675B907A9CDE90081D9F82010424B11 +:1032D000D9F8142008685833D9F84010FFF751FF87 +:1032E0000546FFF72DFC04B115B97F1C182FCFDB65 +:1032F000761C032EB8D31FB0C7E570B5364C002638 +:103300000546A66101285DD0022D5DD00120207008 +:10331000607968B1304A002350322169606B00F057 +:103320008CF92D4A002358326169A06B00F085F9B1 +:10333000A07958B1284922695031E06B13F0E0FDC3 +:10334000254962695831206C13F0DAFDE07810B13C +:103350000020FFF7C1FC207960B1E07838B16178D6 +:10336000606A00F058F96178A06A00F054F9012011 +:10337000FFF7B2FC607908B1FFF731FE012D25D0CF +:10338000022D25D084F80060FFF786F8A07958B1A7 +:10339000207938B1A178E06A00F03DF9A178206B7E +:1033A00000F039F9FFF73AFFFFF776F8012D19D051 +:1033B000022D19D01021A06900F054F9A069B0B114 +:1033C000002070BD0320A2E70520A0E7022000E056 +:1033D00004202070D8E7000068041000E0671000A7 +:1033E000248E01004021E6E74FF40071E3E701205D +:1033F00070BD70B5B64D0C46022828D012F0D8FF2B +:10340000C5E9140112F0D6FFC5E91601B04808213C +:10341000503014F0C1F82861AD480821583014F03C +:10342000BBF8686104F190006862401CA862401C0F +:10343000E862401C28634B3868632030C5E90E04FD +:103440004838286474309534C5E9110470BD12F011 +:10345000B3FFC5E9140112F0B1FFD5E710B59D49DE +:103460000020FFF7C6FF9A489B49C161091D016210 +:103470009A490B6893F8882112F00104C4704FF048 +:10348000000204D0436A1A70836A1A7008E0446A22 +:1034900093F8923123700B68846A93F89331237008 +:1034A0000B6893F88841C4F34004047114B1C36AF3 +:1034B0001A7006E093F89421C36A1A700A6892F8A9 +:1034C0009521036B1A70096891F88821C2F3800373 +:1034D0004371C2F3C0028271B1F88A210281B1F84E +:1034E0008C214281B1F88E218281B1F89021C28174 +:1034F00091F89621427091F897118170BDE81040C3 +:103500000020FAE6734910B598310120FFF771FFEA +:1035100071496F481031C1610021C0E916110A4696 +:1035200041616E490B6893F8A04114F00104C47026 +:1035300004D0436A1A70836A1A7008E0446A93F8E8 +:10354000AA3123700B68846A93F8AB3123700C683E +:1035500094F8A031C3F34003037113B1C36A1A7026 +:1035600006E0C36A94F8AC211A700A6892F8AD219B +:10357000036B1A70096891F8A021C2F380034371AC +:10358000C2F3C0028271B1F8A2210281B1F8A42174 +:103590004281B1F8A6218281B1F8A821C28191F8B7 +:1035A000AE21427091F8AF118170BDE8104001204A +:1035B000A3E62DE9F04107460124002013F09DFA0F +:1035C000022013F09AFA464E78074FF000054FF0AC +:1035D000A5080AD5FFF742FF10F0010405D03068B6 +:1035E000C57780F8205080F81E8038070AD5FFF78D +:1035F00089FF2040040005D0306800F8225F457044 +:1036000000F8018C022013F093FA002013F090FAD6 +:103610002046BDE8F08102788A4201D9511A00E0C3 +:1036200000210170704710B5144611F032F9A04224 +:1036300001DC012010BD002010BDF0B500252C4696 +:1036400001260CE002EBE40704F0070C3F7806FAD1 +:103650000CFE1EEA070F01D003556D1C641C8D4241 +:10366000F0DBF0BD70B504460D46C00702D08320E4 +:103670000FF0BCF9A00703D5294684200FF0B6F956 +:10368000600703D5294685200FF0B0F9200703D540 +:10369000294686200FF0AAF9600603D529468B201B +:1036A0000FF0A4F9200603D529468C200FF09EF9CF +:1036B000E00503D5294687200FF098F9A00505D528 +:1036C0002946BDE8704088200FF090B970BD000019 +:1036D00068041000D07A0120BC0A1000B80710005E +:1036E000BC071000DFF8949108B5654D0024DFF8A1 +:1036F00094A1C9F80040644E2C60DFF89081CAF8AC +:103700000040DFF88CB13460C8F80040CBF80040CE +:1037100000226B465F49104613F098F90098810724 +:1037200013D5FCF76BFE2F682C60FCF765FE17F0D5 +:10373000530F02D03846FEF799FD17F4D67F02D01A +:103740003846FFF736FF022194E0810504D5FEF7E5 +:10375000C2F84FF400718DE0410514D5FCF74EFE20 +:1037600037683460FCF748FEF80701D0FDF7B0FC7D +:10377000B80701D5FDF727FD780701D5FDF7BFFC98 +:103780004FF4806176E001060CD5FCF737FED8F8DF +:103790000070C8F80040FCF72FFE3846FDF731FFF7 +:1037A000802167E081020DD5FCF728FEDAF8007071 +:1037B000CAF80040FCF720FE3846FDF742FC4FF403 +:1037C000001157E0C10404D5FEF7FCFD4FF4805111 +:1037D00050E0010204D5FDF76FFD4FF4000149E010 +:1037E000010504D5FEF709FE4FF4006142E04102F5 +:1037F00030D5FCF703FEDBF80070CBF80040FCF797 +:10380000FBFDF80701D0FEF766F8B80705D50120E3 +:10381000FEF7A5FA0120FEF772FF38070FD51E4804 +:10382000006890F8C101000601D5FEF752FB1A4866 +:10383000006890F8C101400601D5FFF769F97807E3 +:1038400005D50020FEF78BFA0020FEF758FF4FF455 +:1038500080010FE0C0057FF55BAFFCF7CFFDD9F825 +:103860000070C9F80040FCF7C7FD3846FCF766FF5A +:103870004FF48071002013F0CCF849E7C007100026 +:10388000C4071000C8071000CC071000D0071000B4 +:10389000D4071000839FF000B8071000204810B52F +:1038A000016820480268134692EA010F28D01E4A98 +:1038B000CC07126825D092F82143E40702D043F0E8 +:1038C000010303608B071FD592F84033DB0703D059 +:1038D000036843F0020303600B0719D592F86033C5 +:1038E000DB0703D0036843F008030360490613D5E0 +:1038F00092F86013C90703D0016841F040010160EC +:1039000010BD23F00103DCE7036823F00203E2E7C4 +:10391000036823F00803E8E7016821F04001EEE7BF +:10392000E0071000F0041000B80710002DE9F04780 +:10393000DFF82092884C0025D9F8001091F831006A +:1039400084F8300091F83020844984F831205043C5 +:10395000097884F8331082492160343906B28B7BB0 +:1039600084F82D30884677000FE02A463146D8F893 +:1039700008000FF04CFF0146226806FB05F002EB41 +:1039800040003A4615F0B5F86D1C94F82D00A84299 +:10399000EBDC74487449007809780843400711D576 +:1039A00072486060D9F8001091F8F11189074A0F48 +:1039B00094F83110921C4A43D8F81010BDE8F04733 +:1039C00015F097B8BDE8F0872DE9F041654E664FD8 +:1039D0000025346838680443012013F08EF838213C +:1039E0005D4815F027F9E00706D0FFF79FFFE006D6 +:1039F00001D500F07EF801255D480078400603D52A +:103A0000E00601D50EF0E4F85A48534C0068E06136 +:103A100030682062396861625149574E34394968CB +:103A2000A162317884F82C10C1071BD0C10619D5CA +:103A3000484F386890F85002C00706D000F08BFD60 +:103A400018B9E06940F01000E061386890F8800231 +:103A5000C0070BD000F07FFD40B9E06940F02000C6 +:103A6000E06103E0400601D50EF0B2F8012013F04A +:103A70005FF8002D0CD03078052807D0062805D037 +:103A80000121BDE8F041022012F097BF0221F8E7C2 +:103A9000BDE8F081394810B50078002828D1304CB5 +:103AA000343CD4E9060100F059FD94F83110A06AC5 +:103AB00000F075FCFFF788FF2648006890F8600367 +:103AC000C10715D0810713D50024400915F038F936 +:103AD00000B101242A4801788C4209D004700CB14D +:103AE000082100E01021BDE81040032012F065BF5E +:103AF00010BD2DE9F0411748194E174C0068343EAF +:103B000090F8315090F83070B16939B1174884F8A5 +:103B10003050C2386A00206114F0EBFFF16939B10E +:103B2000124884F8317098387A00606114F0E1FF2F +:103B30000C480D490078097808438006A8D50B4841 +:103B40004C38E0606A00716ABDE8F04114F0D1BF02 +:103B50009EE70000B8071000D8791000FC041000A0 +:103B60000C0B1000F4041000F8041000FE070120F4 +:103B7000E4071000F0041000E8041000E90410004D +:103B8000C8041000144810B51449047800200860D7 +:103B900000F071F800F004FB052C14D0062C12D0B4 +:103BA0000F49012008700F48016821F0020141F01F +:103BB00004010160012105200FF0FCF94FF4807130 +:103BC000002012F0FAFE00F08EFD0221BDE8104048 +:103BD000012012F0F2BE0000E8041000EC04100016 +:103BE000F9071000C00710004E4910B509780129E7 +:103BF00009D0C0070AD04C480324006890F850123E +:103C0000C90708D103E049490120087010BD90F8A8 +:103C10008002C00700D00B24FCF7F0FB4448016889 +:103C200021430160FCF7E8FB012105200FF0C2F9F8 +:103C3000BDE810404FF48071002012F0BEBE10B5F8 +:103C4000C00717D03848006890F8C101010601D4B8 +:103C500040060FD5FCF7D2FB3648016841F0080159 +:103C60000160FCF7C9FBBDE810404FF48001002063 +:103C700012F0A3BE10BD10B500F035FD02210120E9 +:103C800012F0C7FE012012F038FF38212A4814F044 +:103C9000D1FF2949012081F82C0012F049FF0121B0 +:103CA000022012F08AFEBDE8104000F072BA70B532 +:103CB0002248234E0568306890EA050426D055B1A5 +:103CC00060B104EA05000446FFF7B9FF2046FFF79C +:103CD0008BFF356070BDFFF7CEFFFAE700F003FD04 +:103CE0000221012012F095FE00F083F800F049FA5D +:103CF0002C402046FFF7A3FF2046FFF775FF00F09A +:103D00002FFA0221012012F058FEE2E7002DE1D146 +:103D10000C480078052801D00628DBD13560BDE8C5 +:103D20007040A8E7F8071000B8071000FA07100065 +:103D3000C0071000D4071000D8791000DC0710006D +:103D4000EC041000E804100070B5ED4900200346B3 +:103D5000096891F84020D20733D0EA4A1578022D3D +:103D600016D0042D03D0052D0FD0062D0DD091F8BF +:103D70004120E5490C68641C0C60944221DDE34A53 +:103D80000020147864B108600CE091F84320F0E75B +:103D900091F8422091F89010C906EAD50123E8E78E +:103DA00013B10120107000E00860052D0AD000F06A +:103DB00059F8044600F05CF840EA040500F066F8A3 +:103DC000284370BD012070BD10B501463422D04893 +:103DD00014F0D4FE0121BDE81040084612F0EDBDFC +:103DE00010B500F080FC0221BDE81040012012F067 +:103DF000E4BDC549002008607047C3490020086041 +:103E0000704738B5002012F078FEC248006810B143 +:103E100000F027FA01E000F0D0F9BA48007800F08D +:103E200086F80446AFF2470100F055FC204600F04A +:103E30003BF801280ED101216B460022084612F002 +:103E400005FE0121084612F0E4FDB148007830B1CA +:103E50000EF0DBFDBDE83840002012F069BEFFF730 +:103E600019FEF7E7AC480078C00700D00120704782 +:103E7000A9480078C00707D0A148006890F8500210 +:103E8000C00701D01020704700207047A24800787A +:103E9000C00707D09A48006890F88002C00701D098 +:103EA00010207047002070472DE9FF4195480078A9 +:103EB00002281CD0032816D00424984D984E0127C0 +:103EC000052818D00628684628D000F0B5F895488F +:103ED0000090684612F0FDF99349944AC978117030 +:103EE00004B0BDE8F081684600F077F8EFE7684677 +:103EF00000F04CF8EBE7684612F0C6F9FFF724FF34 +:103F00004021C20701D08DF80440C20601D58DF8CA +:103F100006708DF8087028603160D8E7002712F02D +:103F2000B3F98DF8044001202F603060CFE738B539 +:103F30007349801E0528096813D2DFE800F00306E4 +:103F4000090C0F0091F873400CE091F8724009E001 +:103F500091F8714006E091F8744003E091F87540E3 +:103F600000E0012400250EF02DFB00B1012569467B +:103F7000032012F05CFD009800B91DB1142C01D291 +:103F8000142401E004B90124204638BD70B506466A +:103F9000002512F079F9FFF7D7FE04465E48007855 +:103FA000C00700D0402544EA0500C00702D000F059 +:103FB00099F8307169074FF0010000D57071E10682 +:103FC00000D5B071690600D53072A90600D5F07130 +:103FD000524804605248056070BD2DE9F041064624 +:103FE00012F052F9FFF7B0FE0746FFF73BFF044619 +:103FF000FFF73EFF0443FFF749FF044300F056F884 +:10400000044300F061F840EA040547EA0504E007CC +:1040100002D000F067F8307169074FF0010000D559 +:104020007071E10600D5B071A90600D5F0713B486A +:1040300007603B48056054E72DE9F041074612F060 +:1040400023F9FFF781FE0446FFF70CFF0646FFF752 +:104050000FFF40EA0605FFF719FF054300F026F8B9 +:10406000054300F031F805432A480068810602D56F +:104070000024012503E0400601D50024102544EA70 +:104080000506F00702D000F02DF8387171074FF0E7 +:10409000010000D57871F10600D5B871A90600D5E8 +:1040A000F8711E4804601E4805601AE71A48007837 +:1040B000C00707D01248006890F8F001C00701D08F +:1040C000042070470020704713480078C00707D0CD +:1040D0000B48006890F81002C00701D020207047FC +:1040E0000020704706490120096891F8E710090689 +:1040F00003D50D48407808B103207047022070476F +:10410000B8071000E8041000CC041000E904100007 +:10411000D80A1000E4071000EC041000F8041000A6 +:10412000F4041000793D0000E8071000FC041000C2 +:1041300010B500F093F900F008FA6E4900204860CD +:104140006D490220087010BD10B500F087F900F02D +:10415000FCF968490020486067490320087010BDD9 +:1041600010B500F07BF900F0F0F9624900204860DA +:104170006149042008706149012008706049087095 +:1041800010BD5C490020486070475A4900204860D3 +:10419000704758490020486057490120087070470F +:1041A00010B500F058F95349087000F057F900F0C5 +:1041B000CCF951490520087010BD70B54E4D002650 +:1041C0004C4C2878801E042810D2DFE800F0312003 +:1041D000023F00F05FF8012807D06068401C606073 +:1041E00000F060F8012802D00CE0666070BD454820 +:1041F0006168006890F878000A30884202D2BDE811 +:104200007040A1E700F060F801280ED070BD00F00A +:1042100041F8012817D06068401C606000F054F835 +:10422000012802D000F03EF80BE0BDE870407FE7C7 +:1042300000F030F8012806D06068401C606000F093 +:104240003BF80128E2D0BDE8704089E700F003F9AF +:1042500008B1217809B1207070BD20700620287047 +:1042600070BD00F0600151EAC072234901D0042002 +:1042700002E0820702D5032008707047420701D58B +:104280000220F9E7020701D50520F5E7C006F4D5BD +:104290000620F1E710B500F0DEF804460DF0ABFCA7 +:1042A000204310BD1748006890F87000800701D5C2 +:1042B00001207047002070471248006890F8700095 +:1042C000C00700D00120704710B5FFF7F5FF0128A7 +:1042D0000ED100F040F958B90B48064900884968EA +:1042E000401C00EB8000B1EB400F01D9012010BD54 +:1042F000002010BDD0041000E8041000EC071000EE +:10430000ED071000B8071000F60710002DE9F04186 +:104310007E4C07460E462068002590F898207C4881 +:1043200010F0DDF902007B48294634D002780125DF +:10433000521CD2B20270236893F8993093422BD268 +:1043400001707348760032463946543814F0D1FB78 +:104350006F48324639462A3814F0CBFB20680326D2 +:1043600090F85012C90703D190F88002C00700D01E +:104370000B26FCF743F86848016831430160FCF7FD +:104380003BF8202105200EF015FE4FF4807100202F +:1043900012F013FB00E001702846BDE8F0812DE922 +:1043A000F04705004CD05B4C0020DFF870A1E070B6 +:1043B00007469AF800108146022903D0032901D04C +:1043C00005293CD1B4F904602846A278314600F0B2 +:1043D00058F8DFF83881A070D8F8000090F8900005 +:1043E000800704D528463146FFF790FF0746002195 +:1043F000474B0846D8F8002017E000BF33F91050AB +:10440000B2F892C065450EDD92F89150491C8D427C +:1044100009DC9AF80010012002290AD0032908D0EB +:10442000052909D00BE0401CC0B2B042E6DB48468B +:1044300005E06070E07006E0617801B917B1607066 +:10444000BDE8F087607000F04EF9BDE8F04702214A +:10445000012012F0B2BA2F48407870472D48002151 +:10446000012201708270294A126892F831208280FC +:104470002A4A1278052A02D0062A00D041707047D5 +:10448000ECE72DE9FC418046224814460D46407871 +:10449000164640B91E480A467F23414654380094C8 +:1044A00010F072F90026194F386890F89010C9077B +:1044B00000D0ECB116486A0041462A3814F019FBC6 +:1044C000134A2B46543A02F12A01114810F025F9FB +:1044D000386890F89010490707D590F89A3023B1C2 +:1044E0000B492A46084610F068F93046BDE8FC81C1 +:1044F000B0F99610CDE90015054AB0F99430543A58 +:10450000414602F12A0010F08FF8D9E7B8071000F1 +:1045100082090120D8041000C0071000E804100030 +:1045200070B50028049E0DD0002406E030F911502B +:104530009D4201DD954200DB641C491EF6D2B44267 +:1045400001DD012070BD002070BD3F4800210170D9 +:1045500041607047F9E73C48007870472DE9F34F18 +:10456000DFF8E8A084464FF00008DAF80000DFF832 +:10457000D8B081B090F880104746C907C1462BD00B +:104580003349097803292DD004292BD0052936D1A8 +:10459000B0F88860B0F88A5090F88740BCF1000FFE +:1045A00008D0009490F831102BB232B26046FFF779 +:1045B000B7FF8046029850B10094DAF800002BB2A1 +:1045C00032B290F830100298FFF7AAFF0746B8F110 +:1045D000010F0ED0012F0CD09BF800105846012976 +:1045E0001DD00AE0B0F88260B0F8845090F88640A0 +:1045F000D4E79BF80010584619B1CBF80490BDE8F9 +:10460000FE8F4168491C4160DAF8002092F8812051 +:104610008A42F4DA01210170CBF804900DE0416880 +:10462000491C4160DAF8002092F881208A42E6DADB +:1046300080F800900021CBF8049003B00720BDE87B +:10464000F04F0EF0B7BC0000E0041000B8071000F7 +:10465000E8041000254908B5002048600122886060 +:104660000A7048702249087022490870224908706F +:1046700022490870FFF704FFFFF76CFFFFF7BDFB4F +:10468000FFF783FD6B4600225E21012012F0DEF968 +:104690000098410703D5FFF70AFB04210EE001074C +:1046A00003D5FFF7FBF8082108E0C10603D5FFF7A3 +:1046B00069FA102102E0410604D54021012012F0E0 +:1046C000A8F9DFE78007DDD50221012012F0A1F96A +:1046D000FFF797FBD6E700EB80004FF6FF7202EA88 +:1046E000400013F0F3BE13F013BF0000E804100005 +:1046F000EE071000F8071000F9071000FA07100085 +:1047000000F0C3BD5E48407800280BD05D485E498C +:10471000007E097EC84205D101235C4A5A495948A6 +:1047200000F04ABA70473CB50023009301936B46F2 +:1047300007E04418647814B11D5D6D1C1D55491CBB +:10474000C9B29142F5D9002001211C5C5A5CA242F9 +:1047500000D90846491CC9B20629F6D33CBD70B53C +:104760000446002008700E4610704648464915461B +:10477000007E097EC8420BD0E278A1784448FFF75A +:10478000D2FF3070627821784248FFF7CCFF287062 +:1047900070BD70B500240123057E08E0C61896F9A7 +:1047A00012608E4202DB964200DC641C5B1C9D4260 +:1047B000F4D2012C01DC012070BD002070BD2DE978 +:1047C000F043994600231F4647F6FF764FF0FF3C23 +:1047D0000125047E0DE000BF00EB050898F912806A +:1047E000884505DB904503DC431993F9123002E05C +:1047F0006D1CAC42F0D2641C0AE0051995F9125008 +:104800008D4205DB954203DC204490F9127001E0F3 +:10481000641EF2D1BB4209D10AE000BF39F913008E +:10482000B04202DA06464FFA83FC5B1CBB42F5DD60 +:104830006046BDE8F0832DE9F04117460E46044678 +:10484000C27881780F48FFF7A4FF050006D1E2780F +:10485000A178114B0B48FFF7B2FF307062782178D6 +:104860000948FFF796FF060006D1627821780B4BC6 +:104870000548FFF7A4FF387005EA0600BDE8F0819F +:10488000800710000024100040241000B024100005 +:10489000AA210120C1210120F81A0120221B012098 +:1048A00010B54021FA4814F0C5F9F94840214030CC +:1048B00014F0C0F9F64800218030C0E90011C0E9C9 +:1048C00002111030C0E90011C0E902111030C0E936 +:1048D0000011C0E902110846EE49086010BD2DE93B +:1048E000FF5F06468946EC48EC499846007809681F +:1048F0001446012850D0B1F986A291F88852B1F936 +:104900008272114648460FF0AAFF83462146484668 +:104910000FF0B0FF0090394658460EF0E3FE0FFA54 +:1049200080FB394600980EF0DDFE00B2ABEB0000D4 +:104930006843642190FBF1F0384405B2A8F80850B0 +:10494000701C00210390C8F80010C8F80410B9F9D1 +:104950000000A84202DD03990120087009EB440021 +:10496000761C30F9022C3119AA4202DD012201F82D +:10497000012CB9F9023003EB0A0212B2AB4218DD86 +:10498000B9F90030934203DDB9F9043093420ADCEF +:10499000039B01225A700CE0B1F96AA291F86552AA +:1049A000B1F96672ADE7D8F8006046F00206C8F8C3 +:1049B000006030F9043CA4F1020B03EB0A0212B2CE +:1049C000AB4216DD30F9063C934203DD30F9020CB0 +:1049D000904203DC012001F8020C0AE0D8E90064EF +:1049E0005A460120002114F03AF806430C43C8E966 +:1049F0000064022458E000BF39F91400A84252DDD7 +:104A000009EB44010291504431F9021C00B2814289 +:104A100004DD029AB2F90220824210DC029A32F9D5 +:104A2000042C824204DD029AB2F90220824206DCA2 +:104A3000814235DD0299B1F90410814230DDD8E9B7 +:104A4000006722460120002114F009F8CDE9000199 +:104A500006430F43621E01200021C8E9006713F0DE +:104A6000FEFF02460B4606EA020007EA030108437E +:104A700019D0029839F9141030F9020C814209DA80 +:104A800096439F43C8E9006703990120214401F838 +:104A9000010C08E0DDE900108E438743C8E9006798 +:104AA000039901200855641C5C45A5D3BDE8FF9F10 +:104AB0002DE9FF4F81B0824600211D461976062060 +:104AC0009046C31F764C07E0002229180A738B74A6 +:104AD00005EB400122880A80401EF5D26E4801781D +:104AE0006E480129006806D0B0F984224FF0000B0F +:104AF0005946584616E0B0F96822F7E70AEB00037A +:104B00005C7874B11AF800400CB9491CC9B25970EC +:104B1000029B33F91030934203DD01238B4043EABB +:104B20000B0B401C4045E9D35E4800900E984FF0B7 +:104B300000094C46C0E9009937E000BF0AEB0400C9 +:104B400042788AB30121914011EA0B0F02D1002172 +:104B5000417029E01AF8041039B909F1010101F096 +:104B6000FF095049009105F8194080F801900E980E +:104B700022460021D0E90067012013F070FF0643B0 +:104B80000E980F43C0E9006705EB0900017B491C43 +:104B9000017305EB49014C700299009A31F9141028 +:104BA000914201DD00918474641C4445C6D385F8AC +:104BB000189005B0BDE8F08F2DE9F84F0C4605467A +:104BC0001E4691461721384814F012F8282137481C +:104BD00014F00EF8DFF8D8A0364F09F108089AF85B +:104BE000001076B10A4605F1200333492E48FFF73D +:104BF00076FE04F120033A7830492C48FFF76FFE27 +:104C000011E04A46284800F0E6F84246397827483D +:104C100000F0E1F80020C5E90800C4E908002848D0 +:104C2000008828852085274E288D2B4626F8110FD1 +:104C3000208D7080CDF800909AF800201E491A4807 +:104C4000FFF736FFCDF8008023463A781B49174816 +:104C5000FFF72EFF297E307961F303003071217E4A +:104C600061F307103071BDE8F88F70B50B4C206808 +:104C700090F83012090742D513490A780AB94978E1 +:104C8000E9B305490978012920D0B0F842121FE0A4 +:104C9000002410000005100012051000B8071000D5 +:104CA000308E01000080FFFFAA210120C1210120D8 +:104CB0005107100052071000F81A0120221B012092 +:104CC00014051000A066012080071000B0F84812FB +:104CD00001220DB2B0F944124B4800F04AFA2068A4 +:104CE0000122B0F946124848103000F042FA294635 +:104CF000BDE8704044480122103800F03ABA4248FA +:104D00004FF0FF31C0E90011C0E902111038C0E9CD +:104D10000011C0E902112030C0E90011C0E9021100 +:104D200070BD2DE9FF4F83B01546069991F84210EA +:104D300002290CD001290CD0334910398A464FF092 +:104D4000000BA97814F088F88146A87832E02E4943 +:104D5000F4E72D491031F1E702462C7801200021BB +:104D600013F07DFECDE900011DE000BF19F804102D +:104D70000498814216D1DDE90023DAE900011040F0 +:104D80001940084323D0DAE90267224601200021B6 +:104D900013F065FE06400F403E4318D00BF10100B2 +:104DA0001FFA80FB641C6878A042DFDA09F1280949 +:104DB00008F10100E97880464145CDDA06995FEABD +:104DC0000B00A1F826B000D0012007B0F2E60020C9 +:104DD00009F80400E6E72DE9F0479146451C0C462A +:104DE0004FF001080CE0D9E90067224601200021BC +:104DF00013F035FE06400F403E4301D005F8048015 +:104E0000641EF0D2BDE8F087902410009D4A10B5D2 +:104E100013680021B3F81422824205DA93F81022B5 +:104E2000520701D5022108E0B3F81222824204DAC7 +:104E300093F81002800700D501219348934C4278E3 +:104E4000914214D1A17891420DD0914B1B781A4315 +:104E5000904B1B781A4307D04168491E41600029D6 +:104E600001DC4078A07010BD41704168F7E759B18E +:104E7000022901D1012A07D093F81822426041701B +:104E8000002AF0DCA17010BD93F81922F6E770B586 +:104E9000814A824B7D4D16787A4A9C7900211268AE +:104EA000AB78012E02D17E4E36784EB1B2F8146244 +:104EB000864217DA92F81062760713D5022125E0B0 +:104EC000B2F81C62864203DA92F810627607F5D4D3 +:104ED000B2F81A6208E000BF92F81002800705D508 +:104EE000012113E0B2F812628642F5DB73B1684823 +:104EF0000078012803D067480078012803D192F890 +:104F00001002000701D5012C00D119465E4834B1CA +:104F100019B100BF92F819224260A97070BD002932 +:104F2000F8D1002BF6D04468002CF6DD92F8101270 +:104F30000A0755494968A1F1010102D5594A127879 +:104F400002B141601946E8E74E484F49006890F8C1 +:104F50001002C2064FF0000003D44C4A9070487013 +:104F600048600870704710B504464648006890F8DD +:104F70001002C006204602D5FFF789FF01E0FFF7C7 +:104F800045FF424882784848417B62F307114173EC +:104F9000A0F82F4010BD2DE9FC5F83464348002553 +:104FA0000A46067800782F4641002C46012A17D081 +:104FB000DFF8D0A0DFF8F880DFF8F890DAF800002A +:104FC00090F81022920610D5B0F92012CDE9001603 +:104FD000B0F91E324246594648460FF025FB09E01B +:104FE00033484C3813F004FE42E00A465946314833 +:104FF00013F07FFD2E484C3835E000BF38F91420FF +:1050000039F91410511A00D54942DAF8003009B2C2 +:1050100093F8102252060BD5204A9279012A07D123 +:10502000254A127822B9B3F822228A4200DA0127EF +:1050300030F914208A4202DA93F8163201E093F82C +:1050400017325A43C3F5807301FB0321CA1701EBE2 +:105050001261091220F8141030F91410A94200DD71 +:105060000D46641C24B2B442C8DB2846FFF77BFF20 +:10507000720059460E4813F03CFD03480770BDE826 +:10508000FC9F0000B807100008051000E80710009A +:105090005707100010051000580710008007100077 +:1050A000590710005C071000A0660120510710008E +:1050B000081A0120541A0120200510002DE9F04F94 +:1050C0008146DDE909B5012047F6FF779A46844617 +:1050D000FE432C4615E000BF32F8143031F814803E +:1050E000A3EB08031BB2BB4200DA1F46B34200DD4C +:1050F0001E46002B02DD4FF0000C02E001DA4FF0FB +:105100000000641EE8D220B1BCF1000F01D00023E2 +:1051100009E050EA0C0306D020B9BCF1000F01D021 +:10512000334600E03B4600273C462846CBF1000CC6 +:105130000EE000BF32F8106031F81080A6EB0806D0 +:10514000F61A36B2564503DA664501DD3744641C6B +:10515000401EEFD204B9012497FBF4F0184404E098 +:1051600031F81520024429F815206D1EF8D2BDE84B +:10517000F08F2DE9F04104460346FD4815460E46E2 +:105180000A460178FB4800F0E8F9FB4804F10803FF +:105190001F460178F74832462A3000F0DEF9002D2C +:1051A00007D0204613F03AFE3846BDE8F04113F030 +:1051B00035BEBDE8F0812DE9FC410746144688461E +:1051C000032011F09AFCED4DE94E0094E948327845 +:1051D000394676382B680FF0BDFA0094E64CE54866 +:1051E000414622784C382B680FF0B4FAE44D286819 +:1051F00090F83012C9071AD03278B0F93412CDE9DC +:105200000012DC49B0F932327639DE4A0846FFF73F +:1052100055FF28682278B0F93812CDE90012D54937 +:10522000B0F936324C39D84A0846FFF747FFD14922 +:105230003378D44A7639CF480FF06FFACD492378C6 +:105240004C39D14A01F176000FF067FA286890F8DE +:1052500030128A0704D4CD4A12788AB149070FD593 +:10526000C44990F84132327808460FF0A6FA28680F +:10527000C049227890F841322A3108460FF09DFA51 +:10528000BDE8FC41032011F053BC70B5C04CC149CE +:105290000025A57001200870B94825706570006868 +:1052A000B0F83A02A08000F0DAF9A560E56070BDC0 +:1052B0002DE9F0410E46B7490746B54C0D78002060 +:1052C0000870607000F0CBF92A4631463846FFF787 +:1052D00072FFB1484178AA480029A17814D0012969 +:1052E00018D00068B0F93C12AC4DA18001222846CC +:1052F000FFF73FFFD5E9000108430FD0D5E90201D0 +:1053000008430BD001200AE0012903D00068B0F95E +:105310003A12E9E70068B0F97812E5E7002020705A +:1053200047E72DE9F04F04469D48A7B04FF001092B +:10533000017893480129006815D094490978A9B1EA +:10534000B0F954628A4801214FF0000A0078954D67 +:10535000801E00F0FF088848834603789A1E02F0FA +:10536000FF0C224613E0B0F95962EBE7B0F9526244 +:10537000E8E7504606E000BF32F91070AF4200DDAA +:105380003D46401C6045F7DD02EB4302491C4145A8 +:10539000EFDD5F465A0004EB4301684613F0A9FBBA +:1053A000814A38786B461288414202EB410109B2CA +:1053B000420004EB410103EB400013F09AFB387804 +:1053C0006946420008460FF016FA281A774900B2DB +:1053D000B042A1F8480001DD4FF00009484627B06F +:1053E000C5E62DE9F041624C207802283BD970488F +:1053F000007818B96A480078012834D0604E3068C7 +:1054000090F8500241076B48006802D500F033F96C +:1054100001E0FFF786FF0546306890F8500200076C +:1054200020D554492278574BA439022A1ADB5D4C07 +:10543000501E04E033F91070A74200DD3C46401EC8 +:10544000F8D1981C921E0FF0D6F93168201A574AED +:1054500000B2B1F95712A2F84A00884202DD35B114 +:105460000220A6E60DB10020A3E60120A1E603205C +:105470009FE62DE9F04107464F4816460024007884 +:10548000D0B34748414D007808B34C4840490831F3 +:10549000006800F0B1F83A483D49006808310A68F0 +:1054A000B0F85F329A4218DDB1F9061090F8610247 +:1054B000814212DD4248394AB0F90010384600F006 +:1054C00041F904464CB100BF00F010F90CE02C7813 +:1054D000012912D00029F5D1002486B139490020D4 +:1054E0000870287800B10124374E28783178884236 +:1054F0000CD038B1012106E00DE00124E4E700F012 +:105500000BF9EEE7002106200DF054FD28783070ED +:105510000CB101204DE600204BE670B5032011F0E0 +:10552000ECFAFFF75EFF0446032011F001FB1F4970 +:10553000C87B64F30510C8731D48017821B10021B0 +:105540000170204600F076F9114D1C4821462A785A +:105550000068FFF78EFFA87070BD2DE9F0471D466B +:105560004FF00008C5E90088914682460C463EE0AF +:1055700051071000F81A0120520710001007100000 +:10558000B80710004C6D0120766D01202005100039 +:1055900010051000ED071000E8071000B0241000FF +:1055A000250510000080FFFF60071000A0660120A5 +:1055B000240510007C0710008007100074071000FD +:1055C0000C07100023051000210510003AF91410F3 +:1055D00049450CDDD5E900674FF0010822464046F9 +:1055E000002113F03CFA06430F43C5E90067641E2F +:1055F000ECD24046BDE8F08730B5344A1268B2F8C4 +:105600005D22524213B20022CA808A800A60304A68 +:10561000B2F9002013E000BF30F91240002C0EDA7E +:105620008C88641C8C8030F912500C682C440C60FF +:1056300030F912409C4202DACC88641CCC80521EA5 +:10564000EAD2244A887982F84E000868002800DAF5 +:105650004042A2F84F0008684042086030BD1E4832 +:105660000021C0E90011C0E9021108461B49087673 +:105670001B49087670472DE9F0411A4A144B002760 +:105680001268B3F900400121158E3E46A54216D19D +:10569000054602F1320840F23C61134813F0A8FAC3 +:1056A000114806E035F8142038F81410511A20F883 +:1056B0001410641EF6D20C48FFF733FE014605486D +:1056C00020F8337F8670084673E50000B8071000A5 +:1056D00060071000A0660120B02410000024100014 +:1056E00040241000BC0710006E1B0120554800210B +:1056F000C1700278002A0ED18278534B521CD2B26C +:1057000082701B6893F8623203F00F03934202D257 +:1057100001220270817070474A480021817002782E +:10572000002A0ED0C278484B521CD2B2C2701B68FD +:1057300093F86232B2EB131F03D9444A117001701F +:10574000C17070472DE9F74F86B08B46D2E9000152 +:10575000CDE90201D2E90201CDE9040102A813F06A +:105760005DFB04A813F05AFB394800252F46067844 +:105770002FE0F1B2069813F067FB824635483246B7 +:1057800000210478012013F06AF9029A00EA020865 +:10579000039801EA0009DDE90401CDE9000116E002 +:1057A0003AF91410594512DD58EA09000DD0224685 +:1057B0000120002113F053F9DDE9002310401940C6 +:1057C000084302D07F1CBFB201E06D1CADB2641E65 +:1057D000E6D2761ECDD2204800F84C5F47701A48BA +:1057E000006890F85B12A94207D890F85C02B842B2 +:1057F00003D3012009B0BDE8F08F0020FAE711487B +:1058000010B54178017000218170C170FFF73DFD36 +:10581000BDE81040FFF744B80A4800210A4A017069 +:105820004170126892F85022920700D5012141710F +:105830000171704703494A79012A02D1002800D139 +:105840004871704720051000B807100006051000C9 +:105850005107100052071000A06601202DE9F84FF3 +:105860001E4615468846834600244FF0AA090A9F23 +:105870004FE0305D08B9285DF0B306F8049038F9C0 +:10588000140000F0EBF828F81400285DA0B305EB35 +:10589000040A1AF8011C81421CD0AA281AD00AF85E +:1058A000019C0BEB4401009131F9020C00F0D6F899 +:1058B000009921F8020C311901F8019C08EB440110 +:1058C000009131F9020C00F0C9F8009921F8020C9E +:1058D000285D88B19AF80110285D814218D0AA2865 +:1058E00016D08AF801900BEB440ABAF9020000F0D6 +:1058F000B5F8AAF8020000E00AE0311908EB440A02 +:1059000081F80190BAF9020000F0A8F8AAF80200A4 +:10591000641CBC42ADD3BDE8F88F8E4900200860FE +:1059200070478C49086070472DE9F74F8AB01746D9 +:105930000C4606F039FF8849002811F8510F0FD0A6 +:1059400040F001000870854804908548DFF804A203 +:10595000012590F800804FF0000BDAF8009027E066 +:1059600020F0010008700DB0BDE8F08F0120A840C4 +:1059700010EA090F1BD17B4800EB85060498B1782B +:1059800013F06AFAB2785B460EE0317806E000BFA9 +:1059900010F801C0AC4500D14354491C96F801C031 +:1059A0008C45F5DA2830521CF1789142EDDA6D1C05 +:1059B0004545DBD900210A9813F054FA08900121DB +:1059C0000A9813F04FFA01900021644813F044FA4A +:1059D00007900121614813F03FFA8046651EE9B245 +:1059E0000A9813F03FFA8146A61EF1B20A9813F006 +:1059F00039FA0490E9B2594813F02EFA0546F1B28B +:105A0000564813F029FA06460097DDE90720434679 +:105A10000199FFF723FF33462A4600974846049929 +:105A2000FFF71CFF0A98002100EB4700851EA0F13C +:105A300004084A48C619701E13F00EFA8146B01EBB +:105A4000002113F009FACDE9004703464A464146D2 +:105A5000284600F013F8CAF800B084E74249096804 +:105A600091F890244243642092FBF0F0B1F88E2428 +:105A700000B2824201DAB1F98E0470472DE9FF4F7E +:105A800083B09A461746894600254FF0AA0BDDF8E9 +:105A900040805BE0119805FB00F605EB8500C40033 +:105AA0001AF8040008B9385DE8B30AF804B039F907 +:105AB0001600FFF7D3FF29F81600385D98B339199F +:105AC000019111F8281C81421ED0AA281CD00198EF +:105AD00000F828BC1198311A0398009130F9110090 +:105AE000FFF7BCFF039A009922F811000AEB0401AA +:105AF00001F828BC009939F91100FFF7AFFF0099B0 +:105B000029F81100385D70B1019890F82810385DBF +:105B100081421AD0AA2818D0019880F828B011988C +:105B20000644039800E010E030F91600FFF796FFF6 +:105B3000039921F816000AEB040181F828B039F91D +:105B40001600FFF78BFF29F816006D1C4545A1D301 +:105B500007B009E728051000A0660120DE3B012000 +:105B6000AD061000763F0120B80710002DE9F04F78 +:105B7000FE4C8025FE4E236893F8311093F83000D8 +:105B800001FB00F202E000BF26F81250521EFBD2C9 +:105B900093F8AA22A64612074FF0640831D54A1E90 +:105BA00002FB00FADFF8C8B303F59469024626E069 +:105BB00019F802300AEB0204DB01B3FBF8F30BEB3C +:105BC00044050C4619E0802B05DDC3F180066643D1 +:105BD00096FBF1F606E0A3F1800606FB04F797FBBF +:105BE000F1F7F61BB5F9007080367743FE1707EB27 +:105BF0005666F6112E80A5EB4005641EE3D2521EB8 +:105C0000D6D2DEF80020F24692F8AA32DB062FD573 +:105C100002F59869D64B4A1E424303EB42050A46F9 +:105C200024E000BF19F80230DB01B3FBF8F60346AD +:105C300018E0802E05DDC6F180045C4394FBF0F48F +:105C400006E0A6F1800404FB03F797FBF0F7E41BE2 +:105C500035F9137080346743FC1707EB5464E41183 +:105C600025F813405B1EE4D2A5EB4005521ED9D2A5 +:105C7000DAF8004094F8AB22D20720D0BC4E0023C3 +:105C800004F59C6419E000BF03FB00F206EB420739 +:105C900000220FE0A55CED01B5FBF8FC37F91250CE +:105CA00005FB0CF54FEAE57C05EB5C65ED1127F88B +:105CB0001250521C8242EDD35B1C8B42E4D3BDE8F0 +:105CC000F08F08B5009380230EF034FD08BD08B5B1 +:105CD00000931346A74AB2F900200EF03BFD08BD21 +:105CE0002DE9F05FDFF890A2A44900209AF8014066 +:105CF00091F800C0A24B022C02D2BCF1000F06D0DA +:105D00009870022C02D2BCF1000F00D0D8709D799F +:105D100055EA0C0100D01871DFF8509293F8038017 +:105D2000D9F80000B8F1000FB0F90013B0F9222340 +:105D3000B0F9427307D0934E3678012E03D1B0F9F3 +:105D40004E23B0F95013012C52D0022C04D3B0F8DA +:105D500004430CB1B0F904139E469DB190F8693329 +:105D6000642403FB01F595FBF4F5294403FB02F5DC +:105D70007B4395FBF4F593FBF4F32A443B4409B2CF +:105D800012B21FB2804CDFF804B2DFF804A2218007 +:105D9000ABF80020AAF8007090F802337D4DC91AC4 +:105DA0004E46298090F82413F146521A7A490A8007 +:105DB00090F84423BB1A794A13809EF800304BB107 +:105DC000774B1B7833B1B0F86C32238090F86E7249 +:105DD000DB1B2B80BCF1000F06D0B0F86C322380A7 +:105DE00090F86E02181A288099F802306BB111E011 +:105DF00090F80343214490F8254309B2224490F8D7 +:105E0000454312B23C4427B2A6E72788ABF800709E +:105E10002B880B80B8F1000F04D12388AAF800303A +:105E200028881080B2F90020B1F90010B5F90000FF +:105E30000DF046FC5B4F00B25B49388022880A8037 +:105E40005A4A2B8813805A4B1B789BB14A4B5B787C +:105E500013B1336893F88D34D6F800C0BCF88A8447 +:105E600043440B809CF88C14591A09B211800DF030 +:105E700035FC388020884F4C4F49504A208008809C +:105E80002888108099F804004D46F8B13068B0F8C1 +:105E9000443423B1AB7913B1B0F8443404E0B0F822 +:105EA000423413B1B0F842342380B0F8463433B1F1 +:105EB000B0F846340B8090F84804181A1080B2F9F4 +:105EC0000010B7F900000DF009FC388034483C4F51 +:105ED000007818B13068B0F8BE020EE027480078AC +:105EE0000028F7D13068B0F9BC0238802979002940 +:105EF00004D0B4F900100DF0F1FB3880BDE8F09F3C +:105F00002DE9FF4F8A4681462E490D9893464A0C4B +:105F1000044607E03AF91430934200DA1A468B42FD +:105F200000DD1946641EF5D20025002901DA0D4670 +:105F300002E0002A00DD154600231C461E461946D5 +:105F40001F46024641E000BF3AF912C0ACEB050C17 +:105F5000DC453ADA0CEB0B08B8F1000F35DD02FB3B +:105F6000024402FB0C11134466442DE0B8071000F4 +:105F7000EA21012060071000E80710002C0510003E +:105F8000800710005B0710000007100002071000D8 +:105F90000407100006071000080710000A07100089 +:105FA000200510000C071000140710001607100041 +:105FB000F40710001C0710001E0710002007100037 +:105FC0000E0710000080FFFF7F1C521EBCD204FB96 +:105FD00007F203FB132E01FB07F203FB16277443A2 +:105FE00001FB134600242146024625E00023BEF1B2 +:105FF000000F0FD007FB026C9CFBFEF3DC465B45F9 +:1060000001DD634606E0DDF80CC013EB0C0F01D593 +:10601000039B5B423AF812C02B44ACEB0303DDF860 +:106020000CC01BB2634505DA9C44BCF1000F01DDD6 +:106030001C44491C29F81230521ED7D201B9012143 +:1060400094FBF1F105E000BF39F81020521A29F84D +:106050001020401EF8D2BDE8FF8F2DE9F8431F46FF +:10606000FE4B0E4605461B681446B3F9DA92B3F9A7 +:10607000DC820AE043464A46314628460097FFF74D +:106080003FFF06EB470605EB4705641EF2D2BDE86D +:10609000F8832DE9FF5FF24C8846002607469246BA +:1060A00035464FF466714046266012F0A1FD00218E +:1060B000404612F0D1FE81460021384612F0C4FE5F +:1060C0000022E84BE84F29E000214FF0010EDFF8F5 +:1060D0008CB318E030F91180D04505DD09F801E0F6 +:1060E00030F911C0761C6544DBF800C030F911802E +:1060F000BCF855C3E04505DDD4F800C00CF1010C37 +:10610000C4F800C0491C93F800C06145E2DB0CF004 +:10611000FF0109F1280900EB4100521C39788A423D +:10612000D2DB03980560304604B0E7E606E000BF26 +:1061300030F912308B4201DD01207047521EF7D238 +:10614000002070472DE9FC470446C848C84D134657 +:1061500002682868FFF7BBFD032010F0CEFCDFF8D3 +:10616000FC92DFF81083BF4ED9F80000BE4F90F8C4 +:10617000AA02800715D5C048B0F90020BF48B0F981 +:106180000010BF48B0F900000DF09AFA03B2317860 +:106190003878CDE900012968D8F80020084600F0D9 +:1061A0005AFAB848D8F800202968B0F900302046DB +:1061B0000EF0B3FA032010F0BBFCD9F800004D46F6 +:1061C00090F8AA02000605D5214633783A780846A9 +:1061D000FFF743FF286890F8AA02400721D53378DB +:1061E0003F781A461BE000213D4609E005FB0326E7 +:1061F00034F91600002812DD09B1884200DA0146A0 +:106200006D1EF3D200290ADD384606E000FB0325A7 +:1062100034F81560761A24F81560401EF6D2521E26 +:10622000E1D2BDE8FC872DE9F04391461C4636E0FB +:10623000954D4FF0010C6A0CE0464F4612E000BF4E +:1062400007FB034631F91660964200DA3246AE4249 +:1062500000DD3546002E02DD4FF0000802E001DAD5 +:106260004FF0000C7F1EEBD2BCF1000F02D0B8F152 +:10627000000F14D15CEA080611D0BCF1000F03D165 +:10628000B8F1000F00D02A464E4606E006FB034553 +:1062900031F81570BF1A20F81570761EF6D2641EFC +:1062A000C6D2BDE8F0832DE9F74F834677484FF01B +:1062B000000890F800A080F80080FFF711FD02218F +:1062C00073480BF03FF87348DFF89C91654D0078F8 +:1062D000012821D1BAF1010F1ED199F8004019E02F +:1062E0006448E1B2006812F0BDFD0746E1B25846CD +:1062F00012F0B8FD0646E1B2674812F0ADFD014666 +:10630000287805E00A5C1AB936F8102027F8102022 +:10631000401EF7D2641EE3D25D4C5246241F5946FC +:106320006068FFF70FFF4D4E306890F8AB028007B2 +:1063300006D561682B7899F800200846FFF773FFAF +:106340003168504F91F8AA02020705D4C00603D461 +:1063500091F8AB02C00706D06168B7F900304F4A28 +:106360000846FFF7AEFCB7F90000616842004C48F0 +:10637000006812F0BEFB2A7899F800106068FFF7F9 +:10638000D3FADFF8209199F8000010B999F80100CC +:1063900028B1DDE901016268FEF78AFF02E04249A7 +:1063A00081F800804148424D40780228306890F8DA +:1063B000AA124FEA816116D3002907DA6168B0F9A1 +:1063C000BA22B7F90030084600F0B4F9306890F806 +:1063D000AA12490612D5B0F9B832364A616828685F +:1063E00009F0C6FC11E0002908DAB0F9BA22B7F9C1 +:1063F00000306168286800F09DF906E0B7F90000F8 +:1064000061684200286812F074FB022120480AF0FB +:10641000FCFF99F80000DFF8A0A04FF0010B90B14D +:106420009AF8000001280ED1306890F8AB024007BE +:106430004ED5207860B984F800B0FFF751FC0121F7 +:1064400008200CF0B7FD306890F8AB0240073FD54C +:10645000306890F8AB1209073AD52FE0B807100062 +:10646000F40610005207100051071000100710002A +:10647000780710007C0710000407100002071000C6 +:1064800000071000600710000080FFFFEC071000FD +:1064900030051000FA071000DE3B0120EA21012040 +:1064A000740710008007100010051000E8071000A6 +:1064B00070071000B296010012051000217839B162 +:1064C000B0F9C532A548A44A0168286809F050FC13 +:1064D000A348007830B199F8010018B19AF800008B +:1064E00002281CD09F48B7F90020B0F90010286896 +:1064F000FFF71CFE9C499D4EA0B181F800B002241C +:1065000001219B480AF01EFF9B489A4BB0F90020DE +:10651000974801682868FFF7BCFD30600DE0042053 +:10652000BDE8FE8F954AC6F800800124C2F80080BD +:10653000904AC2F8008081F800802046F0E770B5EC +:1065400005468F48002604780670FFF7C9FB022134 +:106550008C480AF0F7FE22468A4C2946241F6068C0 +:10656000FFF7F0FD884D286890F8AB02800707D54B +:10657000864861680378864802780846FFF753FE2C +:106580002968844D91F8AA02020705D4C00603D4F5 +:1065900091F8AB02C00706D06168B5F900307E4AB9 +:1065A0000846FFF78EFB6168B5F900007B4C42009E +:1065B000206812F09EFA022172480AF026FF69480C +:1065C000B5F90020B0F900102068FFF7AFFD66496B +:1065D00090B1012008700146022565480AF0B2FE1C +:1065E0006548644BB0F90020614801682068FFF7F6 +:1065F00050FD5E49086001E00E700125284670BD1F +:10660000604910B5091F584A002048601070087092 +:106610004870FFF782F9BDE8104000F002B8FFF7BC +:10662000A5BA594810B500685D495E4BB0F8002323 +:106630000A80B0F822135C4C1980B0F842332380F2 +:106640005A4C22805A4A11805A490B804A49B0F864 +:10665000BC02088010BD2DE9FF4F9B46DDE90D19F6 +:10666000864664E0019A01FB09F002EB4004029ABD +:10667000514F02EB40064FF0010C0EEB40057B0C36 +:10668000E2464A4615E000BF36F8120034F81280A0 +:10669000A0EB080000B2984200DA0346B84200DDE1 +:1066A0000746002802DD4FF0000A02E001DA4FF051 +:1066B000000C521EE8D2BCF1000F04D0BAF1000F5A +:1066C00001D000200BE05CEA0A0008D0BCF1000F0A +:1066D00004D1BAF1000F01D0384600E01846002777 +:1066E0003B464A46CBF1000A10E000BF36F812C024 +:1066F00034F81280ACEB080CACEB000C0FFA8CFCFD +:10670000DC4503DAD44501DD67445B1C521EEDD243 +:1067100003B9012397FBF3F20244484605E000BFAA +:1067200034F81030134425F81030401EF8D2491EBA +:1067300098D290E470B50024264609E031F914504F +:10674000954202DA20F8146001E020F81450641C2D +:106750009C42F3DB70BD0000B2960100740710008C +:10676000100510000C07100057071000F00610006D +:10677000C4061000F80610000E071000F406100002 +:10678000EC07100030051000B80710005207100089 +:106790005107100060071000EA2101207007100067 +:1067A0000007100002071000040710000607100081 +:1067B000080710000A0710000080FFFF8948002129 +:1067C00001704180704730B58749024601200C684E +:1067D00094F8C6394BB1834DB2F844106D68491B2B +:1067E00000D549428B4200DA002094F8C7190029ED +:1067F00012D07C4CB2F91A500834B2F91820B4F90E +:106800000230B4F900405B1BA21A5B4302FB023268 +:1068100049438A4200DD002030BD2DE9F047724F28 +:10682000DFF8C08106004FF005044FF0060510D0D8 +:1068300096F8C40100F09AF90446386890F8C50942 +:1068400018B1B6F8441081422DD8B06900F09FF815 +:1068500048B398F8000001214FF0000907280ED234 +:10686000DFE800F00404243C68040400052C04D094 +:10687000042C06D0012C07D015E088F80090BDE864 +:10688000F08788F80010FAE7FFF798FF022088F8F1 +:106890000000A8F80290B6F84400C8F80400B069F7 +:1068A000C8F80800EBE788F80050E8E7B8F80200FD +:1068B000401C80B2A8F80200032C03D0396891F87C +:1068C000C01942E0032088F80000A8F80290D6E73B +:1068D000052CD4D03046FFF776FF28E0B8F8022028 +:1068E000521C92B2A8F80220012C18D0386890F8F7 +:1068F000C1399342C3D83D4888F80050394A4170A5 +:106900001921083281705188C170090A01711188FA +:106910004171090A8171BDE8F0470CF04FBB304668 +:10692000FFF751FF042288F80020A8F80290002801 +:10693000B9D0A4E7B8F80200401C80B2A8F8020061 +:10694000032C05D0396891F8C2198142C0D8AAE752 +:10695000052088F8000092E738B5002100916946CB +:1069600000F0E1F81F4C012802D90620207005E054 +:106970000098FFF752FF2078052801D0002038BD8D +:106980001A480121417005218170012038BDF0B500 +:10699000154906460120096891F8C329950091F828 +:1069A000C4292B46940091F83620D7074A8E898E49 +:1069B000A2EB0502A1EB040112B209B20ED02346EC +:1069C0000F462C463114994206DBB94204DC31B241 +:1069D000A14201DB914200DD0020F0BD17460A46CE +:1069E000F0E7000034051000B8071000E82410009C +:1069F00000F049BA934810B590F82C00062801D051 +:106A0000052807D190489149006890F8B40200F039 +:106A10000F0008608E490020087000F0DBFBBDE825 +:106A2000104000F04DBA2DE9F041DFF82482044611 +:106A300098F8000010B90A2188F80010002704F522 +:106A400080560125D6F8200C05FA07F108420AD035 +:106A5000C7EB071104EB411191F8C401032802D1DF +:106A6000204606F0DFF87F1CFFB20F2FEAD3002686 +:106A700004F5805705FA06F1D7F8200C084208D033 +:106A8000C6EB061104EB411000F118010C300CF0BC +:106A900070FF761CF6B20F2EECD36E4800214646EE +:106AA0000160416098F80800800603D52046FFF792 +:106AB00053FF70B9B068C00103D5204600F070FAEA +:106AC00038B96549B06808420AD0204601F0BFF9DC +:106AD00030B160480CF072FAFFF770FE00F07AFBFC +:106AE0000027A84604F5805608FA07F0D6F8201CBF +:106AF00001420FD0C7EB071104EB411595F8C40113 +:106B0000082807D12946204606F0A7F8294620463E +:106B100006F06AF87F1CFFB20F2FE5D32046BDE8D0 +:106B2000F04100F055B830B5054600204FEA0003AB +:106B3000C3EB031205EB421494F8C421012A0DD0D3 +:106B4000022A0BD0032A09D0042A07D0052A05D02F +:106B5000062A03D0072A01D0082A02D1401CC0B25D +:106B60000C605B1CDBB20F2BE2D330BD09280ED2C8 +:106B7000DFE800F00D0505070909090B0B000420EB +:106B8000704701207047022070470320704705209E +:106B9000704770B500242E4D402808D201230246CC +:106BA0000021184611F05BFFD5E9022309E0802897 +:106BB0000CD2A0F140020120002111F050FFD5E9D4 +:106BC000042310401940084300D00124204670BD22 +:106BD00070B5224901220978062903D011B105298F +:106BE00000D000221E490B781E49012B4C7E18490B +:106BF00024D0022B22D0082C20D0FAB10A7822B15E +:106C0000521E12F0FF020A701AD105465FF000040E +:106C1000C4EB041005EB40163146284605F0E4FFAE +:106C20003146284606F019F8641CE4B20F2CEFD365 +:106C3000BDE87040102101200FF0BFBE0A2008708F +:106C400070BD0000D8791000B807100010071000C0 +:106C500040051000E8241000DEFFFF00340510009E +:106C60002A251000283801202DE9FC4FFA48DFF8CA +:106C7000ECA30668BAF90670B14696F836C0B48E31 +:106C80005FEACC78BAF90A50BAF90430BAF90800C8 +:106C9000768E4FEA4C7809D0B8F1000F21DAF31A5A +:106CA000301A63F31F4160F31F421EE0B8F1000F7A +:106CB00006DAF71B751B67F31F4165F31F4203E0FC +:106CC00065F31F4167F31F425FEA8C7504D5E31A31 +:106CD00063F30F01201A0FE060F30F0163F30F025B +:106CE00011E060F31F4163F31F425FEA8C7006D529 +:106CF000E01B60F30F01601B60F30F0203E065F31C +:106D00000F0167F30F0299F8307099F83190B6FBD4 +:106D1000F7F005B2601CB0FBF9F003B2002E76D09C +:106D2000002C74D0002D72D0002B70D05FEA224C62 +:106D30004FF0000E13D09CFBF5F8584668F307009F +:106D40009CFBF5F805FB18CC1FFA8CFC4FEA214898 +:106D500046450ADC7F1E67F30F20AEB20EE05846B0 +:106D60006EF307004FF0000CF0E798FBF5F666F3C2 +:106D70000F2098FBF5F605FB1686B6B212B28AB163 +:106D800092FBF3F767F3174092FBF3F703FB17222D +:106D900092B209B28C4209DCA9F1010161F31F60D2 +:106DA00099B20CE06EF317400022F2E791FBF3F486 +:106DB00064F31F6091FBF3F403FB141189B20CEB35 +:106DC0008C04640094FBF5F4C4F10A041FFA84FBFC +:106DD00001EB810106EB860402EB820249005200BE +:106DE000640091FBF3F194FBF5F492FBF3F21FFACC +:106DF00084FE1FFA81FCC2F10A020024C1B297B2DC +:106E00008946C0F30743050EC0F3072625E038E0A6 +:106E1000894502D10FFA8BF806E08E4202D10FFAB3 +:106E20008EF801E04FF00A083AB201920FFA8CF2A4 +:106E3000184600920DE0834201D1019A04E0854298 +:106E400001D1009A00E00A2208FB0242401C14B261 +:106E500000B28542EFDA491C09B28E42D8DAAAF8AC +:106E600010408AF80C908AF80D60AAF812B0AAF8BF +:106E700014E08AF80E308AF80F50AAF81670AAF8B3 +:106E800018C0BDE8FC8F7548002140F81A1F41600A +:106E9000018171480168714891F8E829A0F8012042 +:106EA00091F8E9290270B1F8EA29C280B1F8EE2917 +:106EB0008280B1F8EC294281B1F8F0190181D3E662 +:106EC0006649002041F81A0F4860088163491A3169 +:106ED000087070472DE9F84F07466048DFF87CB12D +:106EE0000BF1120B008AABF1060608B947F6FF70EA +:106EF0004FF000088246C14697F85C5025E0B07814 +:106F0000A84221D8F078A8421ED3E9B2544811F023 +:106F1000A3FF009097F85A4012E03078A0420ED8B4 +:106F20007078A0420BD30098005D40B1E9B2E0B2A6 +:106F30005B46324600F016F948441FFA80F9641C9B +:106F400097F85B00A042E8D26D1C97F85D00A8425C +:106F5000D5D2642009FB00F2B2FBFAF0B7F8441076 +:106F600080B229B164235943B2FBF1F11FFA81F8D1 +:106F70003C49A1F853A0A1F8559081F8570081F839 +:106F800058803549096891F8F229824206D891F86B +:106F9000F319414502D80120BDE8F88F0020FBE736 +:106FA0002DE9F05FDFF8B490804609F11A09002658 +:106FB00099F8007048460125C7B104462748274B79 +:106FC0001A30DFF8A4A080791A78C0EB001008EB23 +:106FD00040104FF003094FF0180B00F11801012F7A +:106FE00052D0022F7ED0032F7DD060E00024DFF846 +:106FF0006CB008F580572AE0D7F8200C05FA04F1A8 +:10700000084222D0C4EB041108EB4110DBF8041055 +:1070100090F8C431DBF808208246032B01D0042B02 +:1070200013D1B0F91AC00B149C450EDBB0F918301F +:1070300009B28B4209DB11148C4506DC11B28B427C +:1070400003DCFFF747FF012810D0641C64B297F9F6 +:10705000280CA042D0DA2CE0B80710001025100050 +:10706000DE3B0120A0660120E824100089F80050D2 +:10707000DAF81820CBF81C2089F80640B9F8081077 +:10708000491CA9F8081014E0074690F8C401042828 +:1070900001D006280BD198461346A01C0CF0DEFB4D +:1070A000012804D13846FFF715FF012804D084F8E1 +:1070B00000903046BDE8F09F2089B8F80110884262 +:1070C00018D3022020708AF801508AF802B0B97EE5 +:1070D0008AF80310798B090A8AF80410397E8AF835 +:1070E000051001E009E036E0398B090A8AF806103C +:1070F0000126DEE7401C2081DBE7074690F8C4014B +:10710000042801D006281DD11346A01C0CF0A6FBB4 +:10711000012817D13846FFF7DDFE012812D18AF881 +:1071200001508AF802B0B97E8AF80310798B090AF7 +:107130008AF80410397E8AF80510398B090A8AF812 +:107140000610012697F8C4010828B2D13846B9695B +:107150000BF040FF03E090F8C4010828A9D1FFF725 +:10716000AFFEA6E730B51478844204D25578854244 +:1071700001D90A2011E0844204D15578854201D01A +:10718000187809E0844204D05478844201D1987878 +:1071900002E018789C786043C0B294788C4204D2A4 +:1071A000D5788D4201D90A2111E08C4204D1D578DD +:1071B0008D4201D0197909E08C4204D0D2788A42FC +:1071C00001D1997902E019799A795143C9B24843BA +:1071D00030BD0000FE4800214161017641767047D4 +:1071E0002DE9FE4F9B46DDF834A091460D4606463C +:1071F000BAF1010F7DD900273C46A9F1010814E03E +:1072000006EB440036F91410B0F9020035F91420E9 +:10721000401A05EB44014043B1F90210891A01FB01 +:1072200001000CF063FA0744641C4445E8DBAAF152 +:10723000010097FBF0F00090B6F90010ABF80010D9 +:107240000C9AB5F900001080002201241746029222 +:107250005CE000BF36F91420511A35F91420494377 +:10726000101A00FB00100CF041FA0299864601EB5F +:107270000E0000990190884242DB90FBF1F0C2B20F +:1072800000202DE00099401C029B4143C91A642351 +:10729000594391FBFEF106EB440336F914C033F970 +:1072A000023C09B2ACEB030808FB01F84FF0640C98 +:1072B00098FBFCF87F1C3FB243442BF8173005EBDA +:1072C000440335F9148033F9023CC0B2A8EB03083B +:1072D00008FB01F898FBFCF10B440C9921F81730DE +:1072E0009042CFD336F9141035F91400DDE90023AC +:1072F00000E020E093FBF2FC02FB1C32029204E06F +:10730000029036F9141035F91400641C4C4501DA6A +:1073100057459FDB06EB490030F8022C0BEB4A0087 +:1073200020F8022C05EB490030F8022C0C9800EBF9 +:107330004A0020F8022CBDE8FE8F2DE9FC470446E8 +:10734000A448D0F8009099F8E219C9077ED099F8BE +:10735000E479002F7AD08046642F77D84FF4C87133 +:107360009D4811F045FC9D4D0220DFF874A2687025 +:107370009948A5F8030004EB840000EB84210AEB94 +:10738000410499F8E309B4F80228DFF84C9204F5B7 +:10739000806682420DD209EB4001CDE900104B46D8 +:1073A00031462046FFF71CFFD8F8000090F8E309AB +:1073B0001EE0BA420FD888485200214611F099FBCE +:1073C000B4F8021809EB41004A00314611F091FB74 +:1073D000B4F802080CE009EB4700CDE900077E4B4A +:1073E00031462046FFF7FCFED8F8000090F8E4098B +:1073F000A5F80500A878172805D0162803D0152869 +:1074000001D014282CD1B5F805004FF6FF730022E7 +:10741000494603EA400307E09C1A521C31F8146005 +:1074200001EB440492B2A6809042F5D8684ABAF8BB +:107430000A4801EB4006938921F810400AEB430308 +:10744000B3F808487480BAF80A2C00E008E009EBA9 +:107450008001801C8A80B3F8082CCA80A5F805003A +:10746000BDE8FC875F4A10B50020118000290AD0D2 +:107470005A480122427081700020FFF75EFF544895 +:107480000C214176012010BDF0B58AB300EB420318 +:10749000B0F9004033F9023CB1F900501B1B01EB7D +:1074A000420434F9024CA4EB050400D1012304B9D1 +:1074B0000124002B01DB1D4600E05D42261E00DAA0 +:1074C0006642B54203DDA40294FBF3F605E09B029D +:1074D00093FBF4F6034608461946B0F90030B1F9BB +:1074E000004073430027A4EBA32C3D463C4613E029 +:1074F00025E000BF30F914E031F914300EFB06FE30 +:107500000CEBAE2EB3EB0E0300D55B421F449D4245 +:1075100000D21D46641CA4B29442EBD3B7FBF2F038 +:107520003049C8802B49096891F8CF29824206D991 +:1075300091F8D00908B1A84201D90120F0BD00207E +:10754000F0BD2DE9F74F00EB800101EB80212448CD +:1075500000EB410000F58061B0F80228FFF794FFCE +:10756000DFF88080012855D047F6FF71A8F8081091 +:10757000DDE901764FF6FF74192500BF37F81500D5 +:1075800039883288401A36F8151000B2891A09B2C3 +:10759000404301FB01000CF0A9F880B2844200D9FD +:1075A00004466D1CEDB21E2DE8D3A8F80A40DFF8A2 +:1075B0003880DFF83890002458F8240090F83C60B8 +:1075C0003046FFF7E6FA68B30025094F12E00000E5 +:1075D00028380120B807100034390120E8241000B1 +:1075E00028280120B43B012074051000688E01009A +:1075F0006C051000DFF880B641F6FF7A785DB04286 +:107600000CD159F825304BB1DDE9010122469847EC +:1076100010B103E00021A9E72BF814A06D1CEDB216 +:10762000052DEBD3641CE4B21E2CC5D383E62DE9F3 +:10763000FF4F8BB0824691461C216846189C11F082 +:10764000F9FA00210846062C12D1002423462246CE +:107650003AF91250A54201DD2C46114619F90250A3 +:107660009D4201DD2B461046521CD2B21E2AEFD39A +:107670004A1CD5B2421CD4B200260DF1280E00BF20 +:1076800006F0030207AF0023BB5408AF1E29BB540A +:1076900009AFBB540EF8023000D300211E2D00D3D9 +:1076A00000251E2800D300201E2C00D300243AF908 +:1076B00011303AF9157003F1020C674503DD07AB91 +:1076C00001279F5406E0BF1C9F4203DA07AF4FF02B +:1076D000FF33BB540C9F0C9B37F9117033F91530F5 +:1076E00007F1020C634501DD012304E09B1CBB4252 +:1076F00003DA4FF0FF3308AFBB5419F9003019F922 +:10770000047003F1020C674501DD012304E0BF1C96 +:107710009F4203DA4FF0FF3309AFBB540E9B1F5754 +:107720001B5603F1020C674501DD012304E0BF1C79 +:107730009F4203DA4FF0FF330EF8023000239E42DF +:1077400054D3D71A3F1D4FEAE77C07EB9C7C2CF003 +:10775000030CA7EB0C070DF11C0C7FB21CF9028087 +:107760000DF1240C1CF907C0A8EB0C080DF1200C3E +:107770005FEA080B1CF902801EF907C0A8EB0C0C8D +:10778000D84601D5CBF10008BCF1000F01DACCF1ED +:10779000000CE044EC460CEB830BDBF80CC0E0443F +:1077A0000DF1240CCBF80C801CF902800DF11C0C9F +:1077B0001CF907C0A8EB0C0C5FEA0C0B0DF1200CB8 +:1077C0001EF902801CF90770DC46A8EB070701D5FB +:1077D000CBF1000C002F00DA7F420CEB0708C3F15D +:1077E00003075DF827C0C4444DF827C05B1CDBB21B +:1077F000032BA4D9491C401C6D1C641C761CF6B2DA +:10780000C9B2C0B2EDB2E4B21D2EFFF439AF6FF0D1 +:10781000004100204FEA0D024FF4E85552F8204095 +:10782000D0F1030304FB05F400D55B42C3F11D0353 +:10783000B4FBF3F342F820308B4200D21946401CCF +:10784000C0B20728E8D30FB0C1F30F20BDE8F08F16 +:10785000F0B50024DDE9056530F9147031F914C084 +:107860006F430CFB0677BF1222F8147031F91470C5 +:1078700030F914C06F430CFB1677BF1223F8147055 +:10788000641CE4B21E2CE7D3F0BD2DE9F34FFA4F90 +:107890000024DFF8E8933C3783B047F6FF7807F120 +:1078A000480B00BF59F8246096F83C5027F8148024 +:1078B000402D13D22A460120002111F0D0F8F049C2 +:1078C00008420BD0EF49EC48096830F9142091F8D0 +:1078D000DD198A4202DD20F8148029E01BF904003A +:1078E0000B2825D2E849E84AE84B163231F9101046 +:1078F00032F91000E34A126892F8DEA9CDE90010CF +:10790000DDE90301A3F13C02FFF7A2FFDF4906F125 +:107910001E033246A1F13C000095FFF788FE27F8D0 +:107920001400504504D9D44843F6FF7120F81410D0 +:10793000641CE4B21E2CB5D305B087E72DE9FF41E6 +:1079400000EB8001CF4C01EB8021D148226800EB95 +:107950004100B0F8001892F8D92991423AD3CD49A4 +:107960000D1F2E1F371FCDE90251CDE90076B0F86B +:10797000022800F580613B1F00F0ECFBB6F9020025 +:10798000B5F90210411A00D54942C248B7F90020A2 +:107990001038B0F90000801A00D54042226892F8F1 +:1079A000DA39B1EB430F15DB92F8DB39B0EB430F5B +:1079B00010DB92F8DC29130904D013094343B3EB1D +:1079C000410F07DB130709D002F00F024A43B2EB65 +:1079D000400F03DA002004B0BDE8F0810120FAE78F +:1079E0002DE9F04100EB800101EB8024A549A84B73 +:1079F000096803EB4400B0F8002891F8CA59AA427C +:107A000051D3B1F83B2091F8CB7902EB8202C2F35B +:107A1000D71291F8CC6991F8CD5991F8CE19574306 +:107A2000564355435143B0F8022833F9143000EB64 +:107A3000420C3CF902ECBCF9FE43B0F900C4BEEBC9 +:107A40000303A4EB0C0400D1012304B90124002B8F +:107A500001DB9C4601E0C3F1000CBC450CD3002CBB +:107A600001DB274600E06742B74205D8002B01DD65 +:107A7000012412E0022410E0002B00DA5B42AB424A +:107A800011D8002C01DB234600E063428B420AD36D +:107A9000002C01DD032400E0042400F58061FFF7E1 +:107AA000F3FC012801D0002096E7204694E72DE959 +:107AB000F84F0020764EDFF8CC918046012704462F +:107AC000EA4606F58055009004EB840000EB842024 +:107AD00006EB400090F80818032926D1D9F80010C9 +:107AE00091F8D2299AB1B0F80028B0F804381A44B5 +:107AF00092B2A0F8062854B130F8040C801A00D5D0 +:107B0000404291F8D219884201DD05201FE020464D +:107B1000FFF766FF0AF8040098B1B8F1000F0BD028 +:107B2000404502D00B2068760027641CE4B2022C8A +:107B3000CAD3012F02D004E08046F6E7287E02284F +:107B400009D0687E052803D00B2801D00A2068766A +:107B50000020BDE8F88F4046FBE710B504004FF069 +:107B6000050003D094F8C401FFF700F894F9D3118D +:107B700001EB810202EB8122454901EB4201052222 +:107B800091F80838062B17D2DFE803F00303120F31 +:107B90000303052804D0042804D0012806D00BE0F4 +:107BA000002000E0012081F8080810BD0220FAE75B +:107BB0000228FAD00328F6D081F8082810BD38B57D +:107BC0000C46002100912246694600F08AFB00988D +:107BD00078B390F8C40103280AD0042833D00528CC +:107BE00031D006282FD007282DD008282BD02CE004 +:107BF00004EB840000EB8421254800EB410131F8BF +:107C00000A2CB1F80018511A1E4A126892F8D129AC +:107C100091421ADA012C01D064B114E01C4901F63A +:107C20000A00B1F80018B0F80028891AA0F8041862 +:107C300009E00AE030F80A1DB0F80A28891A82889B +:107C40001144A0F80E18012038BD10480421D03886 +:107C50004176002038BDF8B5054600200E4600905C +:107C6000012469462846FEF75EFF084AD03A08B16B +:107C7000022811D903202EE03C3B0120740510009E +:107C8000DEFFFF00B80710003C8E0100F83801202D +:107C900028280120680510004FF4E15041590120C7 +:107CA00000FA06F3194202D150760020F8BDC6EB67 +:107CB000061005EB401191F8C40170B1F84800912D +:107CC000006890F8C90940B1B1F84430834204D942 +:107CD000F44902208B80507600242046F8BDF0B590 +:107CE00090F9D311072401EB810202EB8122EE49C6 +:107CF00001EB420501F58053B5F80228B2F5007F8B +:107D00003DD2468B25F8126090F9D361058B06EBC6 +:107D1000860707EB862601EB460606EB4202A2F831 +:107D2000005490F9D32102EB820505EB822201EB8E +:107D30004202B2F802586D1CA2F8025890F9D32101 +:107D400002EB820505EB822201EB4205B5F8002823 +:107D5000521C92B2A5F8002890F8D35135B9B1F869 +:107D60000058D0494D80B0F844008880CC48006865 +:107D700090F8C809002803D0B2EB400F00D95C7618 +:107D8000F0BD2DE9F843804600200090694640464A +:107D9000FEF7C9FE28B1C54C607E28B1082803D083 +:107DA00051E0FFF717FA50E0207E0126022829D87B +:107DB00000252A466946404600F093FA009890F85C +:107DC000C401032817D108206076616906FA05F717 +:107DD000394210D105EB8500B34900EB852001EB5A +:107DE000400040F60A0110F003FF6069384360610B +:107DF000207E401C20766D1CEDB2022DD9D3207E52 +:107E0000022820D810F0FF0F1DD00025606906FA67 +:107E100005F7384210D02A466946404600F061FA1C +:107E2000009848B1FFF75BFF009890F8C40108285C +:107E300002D16069B84360616D1CEDB2022DE5D3DB +:107E40000120BDE8F883062060760020F9E770B5D0 +:107E500005460024FFF795FF012804D1284600F0CD +:107E600085FA012801D0002070BD284600F04DFAA7 +:107E700001280FD18D48007E012803D9284600F043 +:107E800008FA02E0002000F0C5F901462846FFF795 +:107E9000E9FA0446204670BD824847F6FF72B0F901 +:107EA0000810914207DB7E49B0F90A00096891F891 +:107EB000E619884201DD0020704701207047F0B5C7 +:107EC0004FF0000C82F800C001230B7067460024BD +:107ED00025462646BB1900EB430E30F81330BEF89A +:107EE00002E0AEEB03031BB2002B03DC05DBBCF1AD +:107EF000000F02DB641CE4B201E06D1CEDB2761CE5 +:107F0000F6B2052EE6D3AC4201D9012301E04FF0D1 +:107F1000FF339C4505D0147804B90B701478641CA9 +:107F200014707F1CFFB29C46192FD0D3F0BD7FB5D3 +:107F30005C4B47F6FF750C339A560C3BB3F908407F +:107F4000AC422BDB564CB3F90A30246894F8E6496E +:107F5000A34223DB0B2A24D2554B554C163433F95C +:107F6000123034F912200024CDE900324D4B8DF847 +:107F70000840B43B8DF80C40A3F13C02FFF768FCCD +:107F8000484802AA03A9F038FFF799FF9DF90C00B1 +:107F9000002803DA9DF80800022802D0002004B06F +:107FA00070BD0120FBE72DE9FF4107463D48012454 +:107FB0000C3080560B2839D23D4A3D4B163332F9EE +:107FC000102033F9100000238DF808308DF80C30A4 +:107FD0001D46344BCDE90020B43B1E46A3F13C02C4 +:107FE0003846FFF735FC2F48F038B0F93A10B0F9B1 +:107FF0000000081A322800DD012502AA03A9304634 +:10800000FFF75DFF9DF90C00002806DA9DF90800D6 +:1080100004280ADB072807DD07E006DD9DF90800D4 +:10802000052802DB062800DC05B900242046D2E43E +:108030002DE9FF4107461B4801240C3080560B28D0 +:108040003FD21B4A1A4B163332F9102033F9100075 +:1080500000238DF808308DF80C301D46114BCDE90A +:108060000020B43B1E46A3F13C023846FFF7F0FB6C +:108070000C48F038B0F93A10B0F90000081A32286C +:1080800000DD012502AA03A93046FFF718FF9DF97C +:108090000C0000280EDA9DF8080005280FD00FE02C +:1080A000B8071000B43B01202828012028380120FF +:1080B0003C8E010004DD9DF80800042800D105B9BC +:1080C0000024204687E4F0B50746FF48012487B026 +:1080D00080560B283BD2FD4BFC4A163332F9102058 +:1080E00033F9103000208DF81400CDE90023F64B51 +:1080F0008DF80800C03B8DF80C008DF81000054687 +:108100001E46A3F13C023846FFF7A2FBEE4802AA46 +:1081100003A9FC38FFF7D3FE04AA05A93046FFF7F0 +:10812000CEFE9DF90C0000280BDD9DF80800032809 +:1081300007D1E548FC38B0F900003230642800D897 +:1081400001259DF91000022800DB05B9002407B0C5 +:108150002046F0BD2DE9F04308AC079F94E860028B +:1081600004885C800C881C8004887C800C883C809F +:1081700004886C800C882C80048874800C8834807F +:10818000012433E031F914C0B3F90080C44508DAA2 +:1081900030F814C0A3F802C031F814C0A3F800C02E +:1081A0000BE0B7F90080C44507DD30F814C0A7F82C +:1081B00002C031F814C0A7F800C030F914C0B5F9F6 +:1081C0000280C44506DAA5F802C031F814C0A5F84B +:1081D00000C009E0B6F90280C44505DDA6F802C07A +:1081E00031F814C0A6F800C0641CA4B29442C9D3EC +:1081F000B5F90200B6F9021008444110A9F80210BE +:10820000B3F90000B7F9001008444110A9F80010B4 +:10821000BDE8F08370B50546AB4A002047F6FF7114 +:10822000B2F1840222F81010401CC0B21E28F9D30B +:10823000A74C207810F01E0F20D02846FFF7D0FB67 +:10824000E0B1012806D0022809D003280CD0042868 +:108250000FD013E02078C00610D5042070BD207820 +:1082600000070BD5032070BD2078400706D50220FB +:1082700070BD2078800701D5012070BD9549206828 +:10828000084204D0284600F0A3F80028F5D10020C9 +:1082900070BD10B58E4C216811F4700F1FD0FFF720 +:1082A00006FCE0B1012806D0022809D003280CD032 +:1082B00004280FD013E02068000210D5172010BD4D +:1082C000206840020BD5162010BD2068800206D51C +:1082D000152010BD2068C00201D5142010BD00205B +:1082E00010BD10B500230B604FF4E15301241B585F +:1082F0009440234208D0C2EB021300EB431090F9E4 +:10830000D331934200D1086010BD38B50546002036 +:1083100002460090012469462846FFF7E2FF0098D4 +:1083200008B1FFF71AFC012269462846FFF7D9FF7A +:10833000009808B1FFF711FC67480021A0F58053B1 +:10834000027E0DE001EB810505EB812503EB450580 +:1083500095F80858032D01D0002405E0491CC9B246 +:108360008A42EFD809214176204638BDF8B5064645 +:108370000020044605460246009069463046FFF755 +:10838000B0FF009828B100213046FFF764FC00B927 +:108390000124012269463046FFF7A3FF009888B107 +:1083A00001213046FFF757FC08B944F002044B485E +:1083B000006890F8D10928B101213046FFF7FFFB92 +:1083C00000B902252C4301D00020F8BD0120F8BDE2 +:1083D00038B50446FFF7B2FA002825D03E483E4B98 +:1083E0005830009004EB840000EB84213C481C339F +:1083F00000EB410000F58061B0F8022800F051F870 +:10840000324B2046083B34491C6800941C315D689F +:1084100001F13C026B4600F00AF8BDF90200291494 +:10842000884202DC9DF8000038BDE8B238BD2DE975 +:10843000F0410746002018700D4647F6FF7058803F +:108440001C4616461146284600F078F83146284664 +:10845000FFF71BFA324629463846FFF772F81A4AE8 +:10846000843A0021B2F900304FEA010032F910508D +:108470009D4201DA2B460146401C40B21E28F5DB26 +:108480001E290CD232F91100FF2808DA154850F8DD +:10849000210090F83C00207032F811006080BDE8A7 +:1084A000F0812DE9FC47084C9846C03C1E25DDF8BC +:1084B0002890A4F13C03CDE90045FEF791FEA4F11C +:1084C0003C02134600260FE0C03B01203C8E010019 +:1084D00048051000DEFFFF0028380120B807100013 +:1084E00028280120740510003146304632F91070FA +:1084F0003E4434F91070401CC0B239441E28F5D3F4 +:1085000096FBF5F691FBF5F15FF00000274632F897 +:108510001050AD1B23F8105034F810506D1A24F889 +:108520001050401CC0B21E28F0D302B04B46424649 +:108530003946BDE8F0476C4800F04AB82DE9F34FE2 +:10854000694883B04FF0FF321E21FC3010F048FB29 +:10855000DFF89891DFF890B1DFF894810025A9F158 +:10856000160A0BF1780B00BF39F915103AF915000E +:10857000CDE900015F4BDDE90301A3F13C02FFF708 +:1085800067F9002458F8246096F83C000746FEF787 +:1085900000FB90B1574906F11E033246A1F13C00A1 +:1085A000009700F05AF83BF9142000B2824204DD33 +:1085B0002BF814004C48FC300555641CE4B21E2C0A +:1085C000E0D36D1CEDB20B2DCED305B0BDE8F08F1E +:1085D0002DE9F043994647F6FF73DD431C462E46CE +:1085E0005FF0000730F91780A04500DA444631F902 +:1085F00017C09C4500DA6346A84500DD4546B445F2 +:1086000000DD66467F1CFFB21E2FEBD3AC4201D1CA +:10861000012400E02C1B24B2B34201D1012300E06D +:10862000F31A4FF448551BB295FBF4F495FBF3F3A2 +:108630001DB224B25FF0000330F913606643F611F7 +:1086400022F8136031F913606E43F71129F81370A3 +:108650005B1CDBB21E2BEFD3DAE52DE9F05F814620 +:1086600000260A989A4690468B463546062813D12E +:10867000002108464FEA010439F914208A4201DD3D +:108680001146264618F90420824201DD104625468F +:10869000641CE4B21E2CEFD300273C4618F90510E9 +:1086A00039F816001AF90520081A01B23BF816002D +:1086B0004943101A00B200FB00100BF017F86D1CB4 +:1086C000761CEDB20744F6B21E2D00D300251E2EF7 +:1086D00000D30026641CE4B21E2CDFD31E20B7FB9F +:1086E000F0F080B2BDE8F09FC43A0120528E010044 +:1086F00074051000F83801207047A54A30B412689C +:1087000092F8A423120980F828200A6802624A68B5 +:108710004262B1F90220D3171B0443EA1243120448 +:108720008260C360B1F90010CA17120442EA114214 +:108730000904016042601022014630BC103010F084 +:10874000D8B92DE9F04F924F81468A4638688FB0EC +:108750001646B0F8A61390F8AA5301FB01FBB0F837 +:10876000A81301FB01F810F029FB0028386802D09B +:1087700090F8AC4301E090F8AB43AC4200D2254600 +:10878000002E02DB89F8286019E009F1240199F82C +:108790002860081F0BF0B1F8584501DB264602E0BF +:1087A000404500DC2E46386899F8281090F8A4035C +:1087B00000F00F0230460BF0C3F889F8280099F852 +:1087C0002810744800EB81000168CA17CDE9061231 +:1087D000416CCA17CDE90412D0F8CC20D0F88840FB +:1087E000D51701959346DDE90612D9F80830D9F876 +:1087F0000C50A3FB010705FB017103FB0211E617F7 +:108800004FF48032002310F050F9BAF90230B9F970 +:108810002620019D9F18A7FB0B384FEAE77C0CFB35 +:108820000B8207FB0525B9F92220A2FB04C8D71744 +:1088300007FB048713EB0C0302FB067255411F1A5A +:1088400065EB0105DDE90412D9F81830D9F81CC030 +:10885000A3FB01080CFB018103FB02114FF48032E2 +:10886000002310F022F9381A65EB0105CDE90A055D +:10887000DDE90612D9F80030D9F80450A3FB01074E +:1088800005FB017103FB02114FF48032002310F04D +:108890000CF9BAF90030B9F92420019D1344A3FB67 +:1088A0000B784FEAE37C0CFB0B8203FB0525B9F93F +:1088B0002020A2FB04C8D31703FB048302FB06326B +:1088C00017EB0C0355411C1A65EB0105DDE9041299 +:1088D000D9F81030D9F81460A3FB010706FB017129 +:1088E00003FB02114FF48032002310F0DEF8201A4F +:1088F00065EB0105CDE90805D9F82010C9F8241069 +:10890000DAF80010C9F820101022494609F11000C9 +:1089100010F0EFF8102208A9484610F0EAF8DDE957 +:108920000A014FF40042801841F100015200002377 +:1089300010F0BBF8AAF80200DDE908014FF400428C +:10894000801841F100015200002310F0AEF8AAF89F +:1089500000000FB0BDE8F08F70B50D46044601462B +:108960001022103010F0C5F8B5F90200C117090443 +:1089700041EA10410004A060E160B5F90000C117B0 +:10898000090441EA104100042060616070BD0000EC +:10899000B8071000A295010030B52A490B6893F87A +:1089A0000914890715D54FF4E1520E2112580124FC +:1089B00004FA01F52A420DD0C1EB011500EB451573 +:1089C00095F8C5516D0705D51F4893F80A14017035 +:1089D000447030BD491EEBD230BD1A49096891F888 +:1089E0000914890709D5184910B10020487003E01F +:1089F0000878002801D0401E0870704711490968A6 +:108A000091F809148A0706D50F494A78012A08D037 +:108A1000097831B97047C907FCD090F8C51104290D +:108A2000F8D10A4AAA21117090F8C411032905D07F +:108A3000042901D00629EDD1082100E0022180F8A7 +:108A4000C4117047B8071000EC0510005C07100057 +:108A500090F85B1090F85A208A1AB0F84210521C15 +:108A6000022A0FD990F85D2090F85C309A4209D123 +:108A700048F20402114205D141F00101A0F8421070 +:108A80000120704721F00101A0F84210002070473A +:108A900070B50446002084F8C801FD48FD4D0E461F +:108AA0000178286811B9FC49097831B194F9D211DB +:108AB00090F86302B1421ED028E094F8C511012954 +:108AC0000BD010F07BF9002894F9D20127D0B042E6 +:108AD000286890F89B0319D10DE0F049097869B135 +:108AE00010F06CF9002894F9D2010AD0B04228683D +:108AF00090F84D030AD100F00F0008E090F84B0306 +:108B0000F9E7B042286890F84C03F4D0000984F8E3 +:108B1000C8012046FFF79CFF012806D00FE0B042B5 +:108B2000286890F89A03F1D1E5E7296894F8C8011C +:108B300091F89C1301F00F01084484F8C801D8484B +:108B4000D84900780978084307D0296894F8C80103 +:108B500091F89D13084484F8C80170BDCF4910B541 +:108B60000C78CC4990F8C821096891F89A3303F041 +:108B70000F035CB191F84C1301F00F01C91A511A9F +:108B8000002900DC002180F8C81110BD91F84B13BA +:108B9000F2E7C54900200870C4490870BF49087051 +:108BA00070472DE9F04F8BB04FF0000900F580556C +:108BB00004468DF810908DF81490B5F8200CBA4E3C +:108BC0000004000C0DD02046FFF7E6FE4FF0FF3703 +:108BD000307839464FF00048B3464FF0010A10BBD9 +:108BE0000AE0B24986F80090012081F80090FFF772 +:108BF000F4FE0BB0BDE8F08F04F58052002092F92E +:108C0000286C1FE0D2F820CC0AFA00F31CEA030F0C +:108C100016D0C0EB001304EB431393F8C4C1BCF1AE +:108C2000010F01D039460FE0B3F844C0BCF1000F8A +:108C300006D05B6B93FBFCF3984501DA984601463E +:108C4000401C40B28642DDDA0027DFF848820191FD +:108C5000A9E000BFD5F8201C0AFA07F001427BD03A +:108C6000C7EB071004EB401696F8C401012802D0A8 +:108C7000052808D010E030460199FFF709FF0220CF +:108C800086F8C40111E0304600F0A3F8062086F80B +:108C9000C401304600F03EF996F8C401022804D021 +:108CA00006283BD0072844D049E096F84200C00788 +:108CB00013D03046FFF7CCFE78B9D8F8001096F8FC +:108CC000C80191F89C1301F00F01884203D9401AA2 +:108CD00086F8C80101E086F8C8917148007840B173 +:108CE00096F8C80128B9D8F8000090F89D0386F8D6 +:108CF000C801B6F84200400402D496F8C80120B179 +:108D000096F8C401032803D019E0032086F8C401B3 +:108D10009BF80010491C8BF8001010E096F8C90170 +:108D200068B996F84200800703D5072086F8C40189 +:108D300005E0082086F8C401304600F08FF8304680 +:108D4000FFF75CFE96F8C401022806D006280FD073 +:108D5000032814D0042812D023E0B6F842004004BF +:108D60001FD496F8C801E0B1401E86F8C80118E08B +:108D700096F8C901A8B1401E86F8C90111E096F81D +:108D8000C501012802D0032806D00AE09DF814008E +:108D9000401C8DF8140004E09DF81000401C8DF874 +:108DA00010007F1C7FB295F9280CB842BFF652AF75 +:108DB00005AA04A9204600F058F80020FFF70DFE90 +:108DC0003B499DF8100008703A489DF81410017056 +:108DD0000FE770B50026044680F8C9612C482D4D78 +:108DE0000178286819B100BF90F8640216E02A499A +:108DF00009780029F8D10FF0E1FF60B12868012659 +:108E000090F89E035FEA101084F8C90194F8C50138 +:108E1000012806D00EE0286890F89E0300F00F00AD +:108E2000F2E7296894F8C90191F84B1300EB11108F +:108E300084F8C9011EB994F8420080070DD428684F +:108E4000E16A90F89F0300F00F02914205D994F86F +:108E5000C91101EB101084F8C90170BD12490878DE +:108E6000002801D0401E087070472DE9F05F92463F +:108E700080460E460A789AF80000084F0121DAB1C0 +:108E8000F0B3002408F5805589464FF0020B34E01A +:108E900020051000B80710002C0510005B0710001B +:108EA000EA061000EE0710005C07100087071000AC +:108EB0005D0710005E071000002829D0397022E0FD +:108EC000D5F8201C09FA04F0014214D0C4EB0411B7 +:108ED00008EB411090F8C41103290CD190F8C5118A +:108EE000012908D180F8C4B1FFF7B8FF9AF8000053 +:108EF000401E8AF80000641C64B295F9280C00E05A +:108F000004E0A042DCDA3078002801D0002038707C +:108F1000BDE8F09F2DE9FC41254D0446286890F8F6 +:108F20008103C00741D02146201D0AF0E6FC074618 +:108F3000214604F120000AF0E0FC80460FF03EFFDD +:108F40000028286805D0B0F89353B0F88F636D43BC +:108F500004E0B0F89153B0F88D636D437643AF42AF +:108F60001ADA94F8C401062801D0052814D1B4F8FF +:108F7000BC00ADF80200B4F8B800ADF80000B4F8D9 +:108F8000C400ADF80600B4F8C000ADF8040001A9B3 +:108F900068460AF0B2FC0746B04506DDAF4204DD84 +:108FA00034F8420F40F002002080BDE8FC81000050 +:108FB000B8071000F8B50746FB480E46FC4C017890 +:108FC000FA481546007801B988B1206890F8BE13B8 +:108FD000B0F8C92301F00F030C09B0F8C7134943D7 +:108FE0005243304600940AF096FC2C60F8BD0FF016 +:108FF000E5FE58B1206890F8B413B0F8B72301F03B +:109000000F030C09B0F8B5134943E9E797F8C50118 +:1090100002280ED0012820680FD090F8B91300BFA5 +:1090200001F00F030C09B0F8BF13B0F8C123494396 +:10903000D6E7206890F8BA13F2E790F8BB13B0F8BF +:10904000C52301F00F030C09B0F8C3134943C7E768 +:109050002DE9F843044690F8C401884604F18807D6 +:1090600003280BD0D24D04280DD0072836D008286D +:1090700032D13846BDE8F84300F0F1BC3846BDE8CF +:10908000F84300F0B8BC04F10C01081D0AF035FCEF +:1090900001466A462046FFF78DFF296891F8BC1308 +:1090A0000A09D4F890100AF04BFC0646286890F89C +:1090B0005002810609D5400607D5BE48007820B188 +:1090C000BD480078012800D1002632464146384686 +:1090D00000F095FCC4F89060BDE8F883286800248F +:1090E00090F8811389070AD590F8BD0300F00F04AA +:1090F0000FF064FE18B1286890F8BD0304092246F9 +:1091000041463846BDE8F84300F091BC2DE9F043F4 +:10911000DFF89C924FF0000CB0F90230D9F8004013 +:10912000674666466546002B02DA4FF0010C04E004 +:10913000B4F83280984500DA0127B0F90030002BEE +:1091400001DA012604E0B4F83480984500DA0125FC +:109150000023BCF1000F02D00EB1438003E04FB1F9 +:1091600026B1618E37E00380BDE8F08315B1628ED1 +:10917000428004E0BCF1000F2FD02DB14380D9F81C +:109180000010898E0180EFE7B2F802C0BCF1000F39 +:1091900023D04380B1F9024067422BE00CFB07FC6F +:1091A000002C00DA64429CFBF4F40F883C440480F9 +:1091B00046B3B2F900402CB3B1F90050B2F9022025 +:1091C0006D4200D56D426A43002C00DA644292FB86 +:1091D000F4F2498811444180C5E7002FE8D0578850 +:1091E000002FE5D0648E4480D9F80040B1F90270B8 +:1091F000648EE71BB2F90240B2F900C0002FCDDA4D +:109200007F42CBE7002DAFD0B2F90030002BABD0BE +:10921000D9F80040B1F90060B2F90220A48EA41B75 +:1092200000D564426243002B00DA5B4292FBF3F20A +:10923000498811444180A2E72DE9F041054600F13B +:109240009804B0F842000F4600054FF0050603D51C +:1092500095F8B80101281ED0702120460FF0EAFCD5 +:1092600004EBC60178684860386844F83600761E1A +:10927000F6D200BFD7E90001C4E90D010120206347 +:1092800004F1580304F1400204F134012046BDE822 +:10929000F0410AF0E1BB182104F140000FF0CAFCD4 +:1092A000182104F158000FF0C5FC95F8BA01012807 +:1092B00015D195F8C201012802D0032808D00EE08C +:1092C000E889A5F8C0016884B5F8BE01288406E0E5 +:1092D000A889A5F8BE012884B5F8C0016884B5F94D +:1092E000C0117868E162401A90FBF6F0B5F9C01140 +:1092F00000EB400201446162B5F9C01101EB40018D +:10930000E161B5F9C01111446161B5F9C01101EB1A +:109310008000E06078686060B5F9BE113868A162CD +:10932000401A90FBF6F0B5F9BE1100EB4002014483 +:109330002162B5F9BE1101EB4001A161B5F9BE1181 +:1093400011442161B5F9BE1101EB8000A0603868BD +:1093500020608FE710B50446D1E90002C4E90D0290 +:10936000062220460AF0AFFA206B04F15803401C95 +:10937000206304F1400204F134012046BDE81040AE +:109380000AF06ABBD1E90021C0E93321D0F8C81046 +:109390000023491CC0F8C81000F1F00200F1D80108 +:1093A000CC300AF039BC0000200510002C0510005C +:1093B000B807100080071000120510002DE9FC5FAF +:1093C000044617460D464FF0010B0020FD49A1F160 +:1093D0001009488008802868C9F800004E462946D0 +:1093E000204601F021F8DFF8E08328687060D8F8A3 +:1093F000000090F88103400625D5B5F902100191CF +:10940000B5F90010009194F8C411204604F19806B3 +:10941000032908D004290AD0062908D007290BD02F +:10942000082909D00BE06946FFF706FF07E0694607 +:109430003046FFF78FFF02E06946FFF7A3FF308F4A +:109440006880B08E2880D8F8000004F10C0A90F8EB +:109450008003410722D594F8C40104F584760228DC +:109460000AD0032808D004280BD0062812D00728D9 +:1094700010D008280ED011E051463046FFF73DF9D4 +:109480000CE0204600F015FA024629463046FFF768 +:1094900058F903E029463046FFF75EFA2968C9F813 +:1094A0000810D8F80000464690F88003000714D54D +:1094B00094F8420010F0C80F05D0C448007810B9E5 +:1094C000C348007820B12946204600F01DFA04E088 +:1094D000514604F59A7000F030FE2968C9F80C1066 +:1094E000306890F8800301071FD5C10604F5BC78E9 +:1094F0000DD594F8C401072817D1B24A4146284631 +:10950000FFF704FE306890F8800300070DD594F84B +:10951000C401072809D1306890F88003C00604D43C +:10952000A84A41462846FFF7F1FD3068B0F93210ED +:10953000B5F902000AF0A9F968803068B0F9341072 +:10954000B5F900000AF0A1F9288094F8C4010328B5 +:1095500006D0042808D0072817D0082815D017E00F +:109560003988A4F8501013E03068B4F8502090F80F +:10957000BC0300F00F00C0F110014243388800FB2B +:1095800001200009A4F8500001E0B4F85000388030 +:10959000904A294604F1240000F082F95846BDE8BB +:1095A000FC9F2DE9F34F8C4983B04FF00009C1F8BF +:1095B00000908849894D4E46C1F8009085F800908A +:1095C000039FDFF804B24FF0010A07F58057A2E0CD +:1095D000D7F8201C0AFA06F001427CD00398C6EBAB +:1095E000061100EB411494F8C401032805D00428A7 +:1095F00003D0072801D008286DD1E0680090B4F8A6 +:109600004E00ADF8040004F10C01734A081D00F08F +:1096100047F901AA69462046FFF7D0FE8046DBF8ED +:10962000000090F88003400604D56946204602F009 +:1096300011FB8046DBF8000090F88003800603D51C +:1096400069462046FFF704FDDBF8000090F881032F +:1096500040070CD5B8F1000F09D094F8C4010328D5 +:1096600005D1608CADF80200208CADF8000094F8B4 +:10967000C501012808D15A48007828B994F8C401D6 +:10968000082801D04FF0000856480078D0B156485D +:109690000078012807D094F8420040070AD500BF9F +:1096A0004FF000080EE004F120000FF0A5FB0028A9 +:1096B000F6D107E094F8B801012803D1206A0090A0 +:1096C00084F8B89194F8C50103280BD12878401C80 +:1096D000C0B2287000E01DE094F84210490701D59F +:1096E000401E287000986062BDF80400A4F8500085 +:1096F000B8F1010F0ED10098A061BDF80400A4F8E4 +:109700005200049894F8D22101680AFA02F0014349 +:1097100004980160761C97F9280CB042BFF658AF48 +:10972000DBF8000090F8880400070ED529782F4850 +:1097300029B12F490978012901D180F800A0D7F873 +:10974000241C002901D180F8009005B0BDE8F08FFD +:109750002DE9F0478946064600274FF0010800F53D +:10976000805552E0D5F8202C08FA07F002424BD081 +:10977000C7EB071006EB401494F8C401032805D08A +:10978000042803D0072801D008283DD194F8D2310D +:10979000D9F8002008FA03F10A4235D0032803D192 +:1097A0002146304603F03EFA94F9D30100282BDB22 +:1097B00094F8C501002101281CD002281CD00428DF +:1097C0001CD01CE0FE051000B80710002C0510008E +:1097D000200510008C071000880710008707100074 +:1097E0005B071000F4071000FA07100019071000BB +:1097F00018071000032102E0042100E0052184F88D +:10980000C611204609F0CBFB7F1C95F9280CB84205 +:10981000A8DA0024474622E0D5F8200C07FA04F124 +:1098200008421BD0C4EB041006EB401898F8C401A2 +:10983000082813D198F8D221D9F8001007FA02F0BD +:10984000014207D098F9D301002803DB4146304696 +:1098500003F003FA4146304603F0C6F9641C95F95B +:10986000280CA042D8DABDE8F0875A4910B500208C +:10987000086059490860FEF73FFF00F03FFCBDE873 +:10988000104000F0B7B838B5044600200090694693 +:109890002046FFF786FE69462046FFF759FF38BD90 +:1098A00010B514460AF029F82168814200DA2060D8 +:1098B00010BD4A4910B50B78494902464FF0FF30B8 +:1098C000096813B191F9AA0310BD464B1B78002B10 +:1098D000F8D1B2F842305C0603D591F8A50300092F +:1098E00010BD1B0702D591F851040AE092F8C5217A +:1098F000012A04D03C4A1278032AE3D810BD91F81B +:10990000A50300F00F0010BD30B40C4690F8C41150 +:1099100000F59A73032923D0042903D0062901D026 +:1099200007294CD12E4A126892F88023D2062DD5F1 +:1099300090F85B2090F85A50521BC0F8A82190F87C +:109940005D2090F85C50521BC0F8AC21826BC0F8CF +:10995000A421264A07291288C0F8B02106D00FE0BA +:1099600000F10C0130BC184600F0E7BB90F8B511CF +:10997000032905D9214630BC1D4A184600F0C0BC59 +:1099800090F8B511491C80F8B51108E090F8B521A0 +:10999000032A0FD9072907D0521C80F8B521214688 +:1099A00030BC184600F032BC214630BC104A184684 +:1099B00000F05ABC042904D0002180F8B51130BC55 +:1099C0007047521C80F8B521214630BC184600F083 +:1099D00006BC0000880710008C071000200510004E +:1099E000B80710002C0510005C071000EC061000F2 +:1099F000FE05100070470022826000F035B87CB58B +:109A0000044615460E46684600F02EF801992A468F +:109A1000606800F03BF8606000992A46206800F01A +:109A200035F820602146304600F027F87CBD7CB533 +:109A3000044615460E46684600F016F801992A4677 +:109A4000606800F023F8606000992A46206800F002 +:109A50001DF820602146304600F00FF87CBD0A4614 +:109A60000146104600F009B8B1F902201202426026 +:109A7000B1F900100902016070474A688032121281 +:109A8000428009688031091201807047C2F11003D9 +:109A9000504301FB03000011704700002DE9F04125 +:109AA000FE4A146871B3618E94F83030826F056F8E +:109AB000C06F6427400000FB02504843A0FB002613 +:109AC000002101FB006600FB0161A2FB070C0026E0 +:109AD00001FB07C102FB06115D432A4633460EF027 +:109AE00047FF2A4600230EF043FFED4B00221B1ACE +:109AF0008A4101D2EA48002194F8D723BDE8F04119 +:109B00000EF0C0BFA18E94F83130426FCFE77CB524 +:109B10000446E448B4F902100078012830D0B4F9C2 +:109B20000600B4F90A20091A801A081A0190B4F93B +:109B30000010B4F90400B4F90820091A801A081AB0 +:109B4000D6490090206C0968019B91F8B3235043DB +:109B5000C2F180025343C21700EB526003EBE010E6 +:109B6000206491F8B313E06B009A4843C1F180017F +:109B70004A43C11700EB516002EBE010E0637CBD8B +:109B8000B4F94600B4F94A20091A801A081A01905B +:109B9000B4F90010B4F94400B4F94820091A801A45 +:109BA000081A009004F1500003226946054609F0A6 +:109BB0008AFE94F88000032802D2401C84F88000BA +:109BC000C2B2294604F1680000F0DEFB7CBD2DE93D +:109BD000F04F89B0002605960696079601240DF1F0 +:109BE000140808960225CDE901480746CDE903543B +:109BF00000F10C03AB489B462A46294620300095CD +:109C000009F0C2FDDFF89C924FF4807A99F80000C9 +:109C1000012848D0386C00900123022207A909F1DD +:109C2000080009F088FD07A9012302220846CDF8A3 +:109C300000A009F072FD02235A4607A905A8009466 +:109C400009F086FD0596069607960896CDE9014827 +:109C5000CDE90354934807F11403009502221D46F1 +:109C60001146203009F090FD99F8000001281FD01E +:109C7000F86B00908B480123022207A9083009F0F5 +:109C80005AFD07A9012302220846CDF800A009F0D9 +:109C900044FD02232A4607A905A8009409F058FDAF +:109CA00009B0BDE8F08FDDE90501C7E90301C9E7A7 +:109CB000DDE90501C7E90501F2E72DE9F04F8DB0B7 +:109CC00000260224059606960796089609960A9697 +:109CD0000B9605AF0C96CDE901470546714805F195 +:109CE0001C03039404949B46224621462030009492 +:109CF00009F04AFD0DF1240ACDE9014A694B02221F +:109D0000039404943033114605A8009409F03CFDF7 +:109D1000DFF890814FF0040998F80000012812D173 +:109D2000E86E022308F1600100901A46A1F11000CC +:109D300009F001FD022308F160011A460846CDF83A +:109D4000009009F0EAFC574902235A46603109A8FD +:109D5000009409F0FDFC059606960796089609966C +:109D60000A960B960C96CDE901474E4805F12C0357 +:109D70000222039404941E4611462030009409F0F8 +:109D800003FDCDE9014A474B02220394049430338A +:109D9000114605A8009409F0F7FC98F80000012886 +:109DA00012D14049A86E0223603100901A46A1F1F9 +:109DB000100009F0C0FC3B49022360311A460846F6 +:109DC000CDF8009009F0A9FC3649022332466031F3 +:109DD00009A8009409F0BCFC0DB062E72DE9F04F32 +:109DE00089B000260124059606960DF1140A0796FF +:109DF000CDE9014A054600F10C034FF0020929485C +:109E000093460F46039498464A4621461030CDF8B3 +:109E10000090049409F0B8FCB5F9020005990123FB +:109E2000401A05900090022206A9384609F083FCEA +:109E300064274146012302220846009709F07BFC73 +:109E40004246022306A91046009409F081FC4146CF +:109E5000012302220846009709F05FFC059606964A +:109E60000796CDE9014A0F4805F1140303941E46F5 +:109E7000022201211030CDF80090049409F084FCF6 +:109E8000B5F9000005990123401A059000900222BF +:109E900006A9584609F04FFC012305E0B807100059 +:109EA00040420F0004061000314602220846009787 +:109EB00009F041FC3246022306A91046009409F03D +:109EC00047FC3146012302220846009709F025FC91 +:109ED000E6E62DE9F74F8AB0002605960696079626 +:109EE000089601244FF002090DF1140A0996CDE9F4 +:109EF000014ACDE90394074607F11C004D46FD4B8E +:109F00004A4649468046CDF8009009F03DFC07A836 +:109F1000CDE90150F748CDE903454346022201212E +:109F20000838009509F030FC0DF1240BCDE9014B08 +:109F30000394F04B0222012107A80095049409F034 +:109F400023FCEC4D183D2878012804D10121384626 +:109F5000FFF7A4FD6860099869684FF06408084439 +:109F600005A9099001230222CDF80080084609F0D6 +:109F7000E2FB099800900123022205A80B9909F041 +:109F8000CCFB07960896059606960996CDE9014AF8 +:109F9000CDE903944E46022207F12C00CDF8009043 +:109FA000D44B1146814609F0EFFB07A8CDE90160CB +:109FB000CDE90346CF484B460222012108380096DE +:109FC00009F0E2FBCDE9014B0394CA4B02220121C7 +:109FD00007A80096049409F0D7FB2878012804D13B +:109FE00000213846FFF75AFD686009986968012327 +:109FF000084405A909900222CDF80080084609F01E +:10A000009AFB099800900123022205A80C9909F0F7 +:10A0100084FBE1E62DE9F74F8EB000250595069506 +:10A0200007950224089509950A950B9505AF0C959F +:10A03000CDE901478C464FF0010AAE4B064603942A +:10A04000083B524621466046CDF800A0049409F032 +:10A050009BFBA84805AA022311462830009409F06A +:10A0600085FB0DF12408CDE9014806F11C0302220D +:10A07000039404949B46114605A8009409F084FBC0 +:10A080004FF0640902231A46594609A8CDF80090FA +:10A0900009F043FB059506950795089509950A95DE +:10A0A0000B950C95CDE90147924B0394083B012297 +:10A0B0000221CDF800A00494109809F065FB8D48AA +:10A0C00005AA022311462830009409F04FFBCDE980 +:10A0D00001480394049406F12C03009402221C46C8 +:10A0E000114605A809F050FB02231A46214609A88B +:10A0F000CDF8009009F011FB11B0D2E538B57E48DB +:10A100007C4C0168183C91F88003C0F30012227067 +:10A11000B1F8B1031AB1642148430D4601E0D1F80A +:10A12000AD53744980080223483100901A46A1F1CA +:10A13000100009F000FB656038BDF8B50B680360DE +:10A140004A68044642608868A06000252564E5638B +:10A15000B1F90260C4E90365B1F900106364C4E9B0 +:10A1600012206448C4E905151838017801290AD07D +:10A1700060301C340FC80FC484E80F00B4F12C0405 +:10A1800084F88150F8BD50301C340FC80FC45A4EAB +:10A190000FC4306864210223B0F8B1031A46484363 +:10A1A0008008A4F12001009008463C3C09F0C3FA65 +:10A1B000306864210223B0F8B1031A46484380088E +:10A1C00004F12C010090084609F0B5FA94E8070064 +:10A1D00004F1440383E8070084F88050D0E710B509 +:10A1E0000446032209F059FB2046FFF790FCB4F91E +:10A1F0000200E060B4F90610401A2061B4F90000D2 +:10A200006061B4F90410401AA06110BD7FB50D461D +:10A210000446032209F041FB2046FFF778FC204664 +:10A22000FFF7D5FC2046FFF748FD00200090019085 +:10A230000290039002AA69462046FFF74AFE02AA4E +:10A2400069462046FFF7CAFD02AA69462046FFF785 +:10A25000E1FEA0896880A08A28800322294604F1B3 +:10A26000440009F01AFB7FBD2DE9F04704468946FA +:10A27000488861889246401A01B2B9F800002288E5 +:10A28000B4F84A30801AB4F8462000B2D21A15B297 +:10A29000B4F84420B4F84830D21A16B20DB9002EE2 +:10A2A00027D0494300FB00106421484305FB05F11A +:10A2B00006FB0611B0FBF1F009F018FA45430A223B +:10A2C000464329B230B291FBF2F190FBF2F0B4F8C0 +:10A2D000462061F31F48114461F31F47B4F844104E +:10A2E00060F30F08084460F30F07C9F80070CAF85C +:10A2F000008003E01C061000B8071000BDE8F087DE +:10A300002DE9F04706464888B6F84A308946C01A13 +:10A31000B6F84640924601B2B9F80000B6F84820B7 +:10A32000E31A1CB2801AB6F8443000B29A1A15B279 +:10A330000CB9002DDDD0494300FB001064214843D7 +:10A3400004FB04F105FB0511B0FBF1F009F0CEF9B7 +:10A3500044430A22454321B228B291FBF2F190FB1B +:10A36000F2F0B6F8462061F31F48114461F31F472D +:10A37000B6F8441060F30F08084460F30F07C9F8FB +:10A380000070CAF80080B4E7F0B54FF0000C6346E7 +:10A390006546144607E000BF01EBC4067668354405 +:10A3A00051F834603344641EF6D295FBF2F693FB09 +:10A3B000F2F7C0F804C0154642F21074C0F800C0AD +:10A3C00017E000BF01EBC5035B689B1B5B43A34227 +:10A3D00000DD2346D0F804C06344436051F83530B3 +:10A3E000DB1B5B43A34200DD2346D0F800C063447F +:10A3F00003606D1EE6D241686423594391FBF2F17C +:10A4000041600168594391FBF2F10160F0BD000029 +:10A4100010B5142152480EF00DFC0EF08AF964219B +:10A4200048434F49086010BD2DE9F041DFF8348101 +:10A4300004460D46D8F8000090F8A00300F00F067F +:10A44000C6F11007204600F05CF8F0B1E089618A9F +:10A45000228A401AA18900B2891AB4F92A207843C5 +:10A4600002FB06000011608509B2B4F928007943A7 +:10A4700000FB0610001120850EF045F8384A91893E +:10A48000081A117C01290ED00FE0206B022807D199 +:10A49000E089618A401A6085A089218A401A208556 +:10A4A0000020BDE8F08151680844002800DA00204F +:10A4B00000EB800116684900B1FBF6F7D8F80010F0 +:10A4C000B1F8A1339F4203D973430A20B3FBF0F0E4 +:10A4D000B4F92A6091F8A33392685E43642146433D +:10A4E0004A43B4F9284096FBF2F15C43444394FBA1 +:10A4F000F2F06A8811446980298808442880012084 +:10A50000CFE770B5044617480125006890F880032E +:10A51000800710D594F8420000070CD40EF04EFCD2 +:10A5200048B91148007830B91048007818B9104877 +:10A530000078012802D9002020630EE0206B022859 +:10A540000CD8401C2063022807D994F8C4010428C1 +:10A5500004D0062802D0072800D00025284670BD68 +:10A5600034251000B8071000200510002C0510003D +:10A5700087071000B0F84420B1F844301A44A0F81E +:10A580004420B0F84620B1F846301A44A0F84620DE +:10A59000426B4B6B1A444263826B8B6B1A4482632F +:10A5A000B1F95420B0F954309A4201DDA0F854209A +:10A5B000B1F95620B0F956309A4201DDA0F8562084 +:10A5C00090F8CC2191F8CC319A420AD030F8482F3B +:10A5D000B1F848301A4420F80C29C96B02681144BC +:10A5E000016070472DE9F04F97B0804600F580502C +:10A5F00000261190BFE00020089005901090129066 +:10A60000814682468346054607460A900B900C9089 +:10A610000D9008EB860000F580501490D0F89C0C4B +:10A620000AAA044617E000BF90F8CC1108EB010C11 +:10A63000535C0CF5805C5B1CDBB253549CF88ACCF9 +:10A64000634506D1012B04D901238B4012990B439A +:10A650001293D0F8D8010028E6D140E094F8CC114C +:10A66000012000FA01FC12991CEA010F12D1A06B23 +:10A67000B4F90E30059A4946C0FB0312059289468B +:10A68000B4F90C3051465A46C0FB03128A46934631 +:10A69000054419E008991CEA010F15D1E06BB4F9E3 +:10A6A0001E30059A4946C0FB031205928946B4F94B +:10A6B0001C3051465A46C0FB03128A46089905448D +:10A6C0004CEA010093460890204600F06CFF0128F8 +:10A6D00002D11098401C1090D4F8D8417F1C002C57 +:10A6E000BCD1002F45DDE817044603462A464846FC +:10A6F00005990EF0DAF9ADF81E002A4623465046B9 +:10A7000059460EF0D2F9ADF81C0014984FF0FF37FF +:10A710000025D0F89C4C23E0204600F044FF01289F +:10A7200001D0109890B904F1100107A809F0E5F8DC +:10A73000B8420BD207463DB129462046FFF71AFF23 +:10A740002946404600F046FF254607E021462846B8 +:10A75000FFF710FF2146404600F03CFFD4F8D841F7 +:10A76000002CD9D1079845F80C0FE88E40F0400036 +:10A77000E8861198761C90F8140DB0423FF73BAF75 +:10A7800017B0BDE8F08F2DE9F74F05460E46C1EB37 +:10A79000061082B005EB401A00244FF00108DFF8E4 +:10A7A0008CB505F580577DE0D7F8202C08FA04F920 +:10A7B00012EA090F75D0B44273D0DBF80C1031F8EF +:10A7C000161011EA090F6CD1C4EB041005EB401010 +:10A7D000009000F0E2FE012804D0009800F0E3FEB3 +:10A7E00001285ED1009800F0D0FEE8BB00990AF184 +:10A7F0000C000C3109F081F80190DBF80C0008FA2C +:10A8000006F230F8163043EA090320F8163030F823 +:10A810001430134320F814305046DBF8049000F055 +:10A82000CEFE012804D1009800F0B7FE01281DD00B +:10A83000504600F0B2FE012804D1009800F0BFFE9F +:10A84000012813D0504600F0A8FE01281ED1009820 +:10A8500000F0A3FE012819D100999AF8420091F85E +:10A8600042100843800600E01BE00FD5BAF8420012 +:10A87000DBF8089040F02001AAF842100098B0F8E8 +:10A88000420040F020010098A0F84210019848458D +:10A8900007D241F69C4051462844049B009A00F0A0 +:10A8A000A8FE641C97F9280CA042BFF67DAF05B046 +:10A8B00067E72DE9F84F88460646C1EB081006EB1E +:10A8C0004014DFF868A494F842004FF0040B4006EF +:10A8D0004FF0010906F580552CD5002704F10C0B2B +:10A8E00022E000BFD5F8201C09FA07F001421AD077 +:10A8F000474518D0C7EB071006EB4010009000F05A +:10A900004CFE01280FD1009800F03FFE58B9009985 +:10A910005846103108F0F1FFDAF80810884202D2E8 +:10A92000042084F8C4017F1C95F9280CB842D9DAB8 +:10A93000BDE8F88FFE49E06A096891F895138842EE +:10A94000F6D900272FE000BFD5F8201C09FA07F040 +:10A95000014227D0474525D0C7EB071006EB401032 +:10A96000009000F01AFE01281CD1009894F8CC1138 +:10A9700090F8CD01814215D1009800F006FE88B90B +:10A98000009904F10C00103108F0B7FFDAF8081054 +:10A99000884207D284F8C4B1B4F8420040F04000C5 +:10A9A000A4F842007F1C95F9280CB842CCDA0027A5 +:10A9B00026E000BFD5F8201C09FA07F001421ED09E +:10A9C00047451CD0C7EB071006EB4010834600F04C +:10A9D000EAFD012813D1584600F0D7FD78B90BF1F4 +:10A9E000100104F10C0008F088FFDAF80810884222 +:10A9F00005D2BBF8420040F04001ABF842107F1C8A +:10AA000095F9280CB842D5DA92E72DE9F8430646C5 +:10AA1000FF2000258DF80000012706F5805417E07F +:10AA2000C5EB051006EB4018D4F8200C07FA05F129 +:10AA300008420CD0404600F0A8FD012807D098F845 +:10AA4000C401052803D129463046FFF732FF6D1CAB +:10AA500094F9280CA842E3DA002519E0C5EB0510AB +:10AA600006EB4018D4F8200C07FA05F108420ED086 +:10AA7000404600F08AFD012809D0404600F093FDD1 +:10AA8000012804D16A4629463046FFF77CFE6D1C3A +:10AA900094F9280CA842E1DA0025B8461FE000BF6F +:10AAA000C5EB051006EB4017D4F8201C08FA05F09A +:10AAB000014213D0384600F068FD01280ED0384618 +:10AAC00000F06BFD012804D16A4629463046FFF7A5 +:10AAD0005AFE37F8420F20F0200038806D1C94F9A0 +:10AAE000280CA842DCDA9DF80000401C84F8140D04 +:10AAF000BDE8F88310B504468C4803210C3006F0FD +:10AB0000D7FB8A481E21C0680EF072F841F69C40BF +:10AB10007C2120440EF08EF8854802688548B2F802 +:10AB200096138079494310B1B2F86A134943B2F8D9 +:10AB3000982302FB02107D4A121D1160111D08604E +:10AB40002046FFF762FF2046FFF74CFD77480321C0 +:10AB5000BDE810400C3006F0C3BBF0B4846BC26893 +:10AB60008B6BCE68171467434FEA264C03FB0C77B8 +:10AB7000E51897FBF5F767F31F4217B2674334B246 +:10AB800003FB047393FBF5F363F30F02C260F0BCA5 +:10AB9000F0E4674A126892F84024920611D590F8C2 +:10ABA000CF3123B191F8CF210AB1934207D190F868 +:10ABB000D00130B191F8D01119B1884201D00020F4 +:10ABC0007047012070472DE9FE4F00F5805405467F +:10ABD000D4F82C1CD4F8200C01400028C4F82C1CFC +:10ABE0004FF000000CD081460F2153480EF000F8C2 +:10ABF0000026DFF844A14FF0010841F6304B59E040 +:10AC0000C4F82C0CBDE8FE8FD4F8202C08FA06F10D +:10AC100040460A424DD0C6EB061205EB421797F8A4 +:10AC200040201206D4F82C2C11D50A4305EB8601DE +:10AC3000C4F82C2C01F5E051D7F85A200A6397F894 +:10AC4000CC11884040EA09090AF8016031E00A4263 +:10AC50002FD097F8C421062A15D0052A13D097F8CB +:10AC6000CC1108FA01F040EA09090AF8016000BFB6 +:10AC700005EB860101EB0B005A373946009004F0D2 +:10AC80002BFB98B115E0B7F8420020F00800A7F8B8 +:10AC90004200D4F82C0C8843C4F82C0C274905EB4F +:10ACA000860000F5E05009680163E1E70098396823 +:10ACB0000160761C94F9280CB042A5DA00276CE0FC +:10ACC000D4F8202C08FA07F140460A4264D0D4F8A0 +:10ACD0002C2C0A4260D1C7EB071105EB4111009102 +:10ACE00091F8C411022901D0012955D1009991F898 +:10ACF000CC1100FA01F212EA090F21D01AF8010072 +:10AD0000B84249D0C0EB001005EB40163046009920 +:10AD1000FFF73FFF01283FD130460099FFF71DFFA5 +:10AD20002846009901F060FF36E00000740610002C +:10AD3000B807100080071000322A1000DA960100D0 +:10AD400000995A310026029122E000BFD4F82C1C51 +:10AD500008FA06F001421AD0C6EB061005EB4010C7 +:10AD600005EB860101905944029804F0B5FA0128D8 +:10AD70000DD1DDE90010FFF70CFF012807D1DDE957 +:10AD80000010FFF7EAFE2846009901F02DFF761C1F +:10AD900094F9280CB042D9DA7F1C94F9280CB842F7 +:10ADA0008EDA2FE72DE9F0470446914256D007D9B5 +:10ADB00001EB0200A0EB0201CAB2A0EB0200C1B29B +:10ADC00001EBC10004EBC00102EBC20004EBC000C8 +:10ADD000B1F93250B0F9323081469D4200DA4B86EB +:10ADE000CB8CC58C2B44CB840B8D058D2B440B85D4 +:10ADF0008B6985692B448B61C769CE69CB68D9F8AB +:10AE00000C004FEA234C4FEA20480CFB06FCF519D6 +:10AE100007FB08CC9CFBF5FC6CF31F430FFA83FC8B +:10AE20000CFB06FC00B207FB00C090FBF5F060F3E2 +:10AE30000F03CD61CB6094F83804411E914208D0D5 +:10AE400000EBC00004EBC0014846482248390DF031 +:10AE500095FE94F83804401E84F83804BDE8F08765 +:10AE60002DE9FE4F16460F468346012B2BD10120BC +:10AE7000F94B0FE017F8101011B1491E07F8101028 +:10AE800007EB40021C785178641EA14201DA491C8C +:10AE90005170401C397E8142ECD20120EF4B0FE013 +:10AEA00016F8101011B1491E06F8101006EB4002FA +:10AEB0001C785178641EA14201DA491C5170401C73 +:10AEC000317E8142ECD2E6484FF00109CA46006863 +:10AED000B0F88E0240430290002001906FE0012004 +:10AEE00067E0002000909BF8381429E001EBC102D4 +:10AEF0000BEBC20202F1400016F818400378A3429F +:10AF00001ED306EB48046478A34219D8407817F89A +:10AF10001930984214D307EB49035B7898420FD855 +:10AF2000D048007838B1D048007820B192F8240099 +:10AF300010F0060F04D1009A0AFA01F010430090B5 +:10AF4000491ED3D2042168460CF026FB01282EDDD1 +:10AF500000245246009901E0641CE4B202FA04F0B5 +:10AF600092460842F8D09BF838541DE000990AFA3E +:10AF700005F0084218D004EBC4010BEBC10005EB4F +:10AF8000C5020BEBC2010C300C3108F0B6FC029983 +:10AF9000884209D2EAB221465846FFF703FFB34977 +:10AFA0000120019081F800A06D1EA542DED808F1B5 +:10AFB0000100317E8046414593D209F10109397E75 +:10AFC00049458CD201981DE6A94810B540780C4639 +:10AFD000002851D0A748007800284DD1A648007815 +:10AFE000002849D19E4894F83824006890F88912C6 +:10AFF0008A4241D8002308E002EBC20104EBC10100 +:10B00000B1F93210994200DD0B46521EF4D29B4931 +:10B010000B80B0F88A1299422EDBB0F98C12002214 +:10B020009748FAF7A6F8964AD2E90010014323D0D0 +:10B03000D2E9020108431FD0A2F140010123A1F18E +:10B040004000F9F7B9FD8E488038007E002813D003 +:10B050008B494039097E00290ED0484394F83814B2 +:10B060000023884200D20123854A2046403ABDE8A9 +:10B070001040A2F14001F3E610BD80490020C860F5 +:10B080000F2180480DF0B4BD70B50C460546097817 +:10B09000007808F023FB20706178687808F022FBC4 +:10B0A0006070A178A87808F019FBA070E178E878C2 +:10B0B00008F018FBE07070BD2DE9FC5F8146684820 +:10B0C0001546012B0068B0F98622009290F888722C +:10B0D000B0F9822206D091F800804C786A49434644 +:10B0E000480C0CE091F80280CC78F7E739F913604E +:10B0F0008E4200DD3146864200DA30465B1CA342B8 +:10B10000F4D9914200DA1146904200DA1046081A4A +:10B110007843642190FBF1F0104439F918100FFACC +:10B1200080FB59450ADDD5E9006742460120002130 +:10B130000DF095FC06430F43C5E9006739F914008B +:10B1400058450ADDD5E900672246012000210DF0AF +:10B1500086FC06430F43C5E90067A4EB080000F036 +:10B16000FF0ABAF1010F3AD908F10100C2B2009802 +:10B1700039F91210084400B2594513DD09EB4201B8 +:10B1800031F9023C834203DDB1F90210814209DC4E +:10B19000D5E90067012000210DF061FC06430F4353 +:10B1A000C5E90067601EC2B2009839F91210084460 +:10B1B00000B2594513DD09EB420131F9023C8342EB +:10B1C00003DDB1F90210814209DCD5E900670120F5 +:10B1D00000210DF044FC06430F43C5E90067BAF1B6 +:10B1E000020F34D9A01E08F1020A01902DE000BF21 +:10B1F00039F91A00584525DD0099084409EB4A0140 +:10B2000000B231F9022C824203DDB1F902308342EF +:10B2100018DC31F9043C834203DDB1F9023083428A +:10B2200010DC824203DDB1F9041081420ADCD5E969 +:10B2300000675246012000210DF011FC06430F4328 +:10B24000C5E9006701980AF1010A8245D0D94FF09B +:10B250000009CA46404633E051071000520710006B +:10B26000B8071000180710001A0710008C0610000D +:10B2700080071000200510002C0510007406100037 +:10B28000C8251000322A10000080FFFFD5E90067B2 +:10B290000246012000210DF0E2FB06400F403E4334 +:10B2A00009D0B9F1000F08D10AF101004FF00109EE +:10B2B00000F0FF0A01E04FF0000908F101008046AC +:10B2C000A045E3D95046BDE8FC9F2DE9F05F856BB2 +:10B2D000FF4C0646C76800200246C5F30741DFF869 +:10B2E000ECA324684FEA156C0AE000BF3AF911306C +:10B2F000B4F83A82434502DD03FB01001A44491CBD +:10B300008C45F3D2F3490978491E82FB01A3A18E33 +:10B310009B46A1FB00C80022C31702FB008001FB73 +:10B320000301604652465B460DF0BFFB60F30F0918 +:10B330000020E9B20246DFF8A0C3C5F3072509E003 +:10B340003CF91130B4F83A82434502DD03FB0100B9 +:10B350001A44491C8D42F3D2E04900254FEAE07CB3 +:10B360000978491E82FB0123618EA1FB004805FB81 +:10B37000008001FB0C0120460DF097FB01B248460E +:10B3800061F31F4001EB410189003A1401EB820196 +:10B3900000B200EB4000091180003AB200EB8200DD +:10B3A0000011F181B081BDE8F09F2DE9F04F044616 +:10B3B000CB4887B04FF00008407800287ED0C948BD +:10B3C000007800287AD140F23C41C7480DF032FCA9 +:10B3D0001E21C6480DF00CFCBD480026354600680D +:10B3E0004FF0010AB0F88E0200FB00FB5CE00AFAA5 +:10B3F00005F05146304256D18A46BC4921F8150025 +:10B40000B349304386B205EBC500096804EBC000C0 +:10B41000B0F93220B1F88A128A4244DCC168019145 +:10B42000806B6F1C00903AE007EBC70004EBC0098B +:10B43000A748B9F932100068B0F88A0281422DDCC1 +:10B44000D9F80C00069006A901A808F056FA58454C +:10B4500024D20020CDE90200CDE9040009F1380032 +:10B460006946FFF711FE012302AA69469748FFF7D4 +:10B4700023FE8146002304AA69469748FFF71CFE75 +:10B4800009FB00F1012909D198490AFA07F031F8BE +:10B4900015200243304321F8152086B27F1C94F812 +:10B4A0003804B842C0D86D1C94F83804A8429ED81D +:10B4B0008D4F0020054687F8380442E062E0DFF84F +:10B4C0002C9239F81500D8B397F8386405EBC5000D +:10B4D00004EBC00106EBC60007EBC0008346482220 +:10B4E0000DF04CFB761C8BF843606E1C19E000BF1E +:10B4F00039F815100AFA06F0014211D006EBC60021 +:10B5000004EBC0000BF138013830FFF7BDFD97F8B0 +:10B510003834F1B2744A204600F097F84FF0010831 +:10B52000761C94F83804B042E2D8B8F1010F02D189 +:10B530005846FFF7CAFE97F83804401C87F83804CD +:10B540006D1C94F83804A842B9D8B8F1010F19D18C +:10B5500040F23C4120460DF06DFB97F8380484F82A +:10B56000380400250AE000BF05EBC50007EBC00169 +:10B5700004EBC00048220DF001FB6D1C97F8380465 +:10B58000A842F1D807B0BDE8F08F90F8420040071C +:10B5900001D5012070470020704790F8C4010128B0 +:10B5A00000D00020704790F8C401022805D003287D +:10B5B00003D0042801D0002070470120704710B547 +:10B5C00090F84210490603D5FFF7EDFF012800D09F +:10B5D000002010BD91F8C421012A08D0022A06D00B +:10B5E000062081F8C401002081F8C901704701F0EC +:10B5F000FBBAF0B591F9D16193F9004092F9D151BC +:10B60000771C02D06D1C15D00BE06E1C0BD000EB2C +:10B61000850200EB8400D26BC2F8D811C16381F8B7 +:10B62000D1411C70F0BD641C64B240F8241081F854 +:10B63000D14102E000EB8601C96B00EB8400C1F848 +:10B64000D821C26382F8D141EBE72DE9F04103EB49 +:10B65000C30302EBC30401EBC10100EBC105E368C6 +:10B66000E0694FEA234CEA68E9690CFB00FC4718E3 +:10B670001BB24FEA224E434301FB0ECC10B201FB3A +:10B6800000309CFBF7FC90FBF7F06CF31F4660F377 +:10B690000F06E660B5F93210B4F9320008F022F86E +:10B6A0006086A069A9690844C4E90607E08CE98CB2 +:10B6B0000844E084208D298D084420854020A08402 +:10B6C000032084F84200BDE8F0810000F81A012050 +:10B6D000B807100051071000221B0120520710006C +:10B6E0008007100020051000D8251000142A100033 +:10B6F0002DE9F041044690F88400FF4E00270D46E6 +:10B700007F2852D104F10C01081D08F0F6F801461B +:10B71000204600F01DFB40B284F884000F2802DDB3 +:10B720000F2084F88400B4F8420080053DD5688875 +:10B73000B4F96CC0B4F96A30A0EB0C0001B22888EF +:10B74000D4F86A20C4F85E20D6F800E0C01A64225B +:10B750009EF867E900290EFB01FE9EFBF2F100B2A4 +:10B7600001DD614401E0ACEB0101A4F86410316833 +:10B77000002891F8671901FB00F191FBF2F001DD5F +:10B78000184400E0181AA4F862006888B4F864103D +:10B79000401AA4F868002888B4F86210401AA4F887 +:10B7A0006600306890F86709F0B394F98400B5F941 +:10B7B0000220C0F110015143B4F96C2000FB0210CB +:10B7C00040F30F106880B4F84210890510D5B4F921 +:10B7D0006010884203DDB4F96420904205DC8842A1 +:10B7E00006DAB4F96410884202DAB4F864006880BA +:10B7F00094F98400B5F90020C0F110015143B4F967 +:10B800006A2000FB021040F30F102880B4F84210A9 +:10B81000890524D5B4F95E10884203DDB4F96220AD +:10B82000904207DC884200E02DE00ADAB4F96210A9 +:10B83000884206DAB4F862002880B4F84200800535 +:10B840000DD5B5F90000B4F96210884207D1B5F9F9 +:10B850000200B4F96410884201D184F88470316820 +:10B8600094F8840091F8691901F00F01401A40B270 +:10B8700084F88400002801DA84F884702868C4F809 +:10B880006A00BDE8F08184F88470012084F88200A9 +:10B89000F7E72DE9F04188460446012790F8841027 +:10B8A000384671B194F8821001290AD0032241462A +:10B8B00004F16E0007F0F1FF94F88300012803D033 +:10B8C00048E084F88200DCE70DF078FA8A4E002820 +:10B8D000306832D090F86C1990F86D0961F31F450B +:10B8E00060F30F052B145B432AB202FB023504F10F +:10B8F0006A00414608F001F80023A84224DC3168C0 +:10B90000B4F8422091F8650900EB80004000120570 +:10B9100004D591F8640900EB8000400010B1E26AA0 +:10B92000824211D891F88003000600D40027D4F891 +:10B930006A00C8F800003846A3E790F86A1990F842 +:10B940006B0961F31F45CBE784F8833094F98400D9 +:10B950000028F0DD41462046FFF7CAFEEBE72DE95F +:10B96000F84F044601200D464FF0000B00900DF0FB +:10B9700025FADFF884A10028DAF8000012D090F848 +:10B98000766990F877790322294604F16E0007F072 +:10B9900084FFB4F8420000051DD594F8BA010128CF +:10B9A00005D018E090F8746990F87579EBE7DAF84B +:10B9B0000000E16A90F87C0981420CD26888B4F8F2 +:10B9C0006C10401AB4F87E100844A4F87E00288851 +:10B9D000B4F86A100BE06888B4F87410401AB4F830 +:10B9E0007E100844A4F87E002888B4F87210401A2B +:10B9F000B4F880100844A4F88000B4F97E00002850 +:10BA000001DB014600E04142B1425EDD4FF0010B37 +:10BA1000002801DD811B00E081190FFA81F9A0EBFC +:10BA20000900A4F87E0034F86C1F01EB090000B295 +:10BA30002080DAF80010B1F9321007F026FF24F860 +:10BA40006C09B5F902108646081A02B2002A01DB19 +:10BA5000104600E05042B04252DDB4F97400081ABA +:10BA600000D54042DAF800800FFA80FC98F87A3965 +:10BA700098F87B6998F8780998F879199C450FDB54 +:10BA80009E420DD0B44501DD084609E0ACEB030C45 +:10BA9000091A0CFB01FCF11A9CFBF1F1084400B2FD +:10BAA000B4F97E105143002906DDB9F1000F00DC26 +:10BAB00040427044A4F86C00B8F93210B4F96C003C +:10BAC00007F0E3FEA4F86C001AE0DAF80010B4F90D +:10BAD0007000498E884203D1B4F974208A4203D0A1 +:10BAE00070B9B4F8741059B9B4F96C10814207D028 +:10BAF000A4F86C0002E00000B80710004FF0010B42 +:10BB0000B4F98000002801DB014600E04142B9425F +:10BB100056DD002801DDC11B00E0C1190EB2801BFB +:10BB2000A4F8800034F86A0F304400B22080DAF8BC +:10BB30000010B1F9341007F0A8FE24F86A09B5F92D +:10BB400000108146081A02B2002A01DB104600E00C +:10BB50005042B84253DDB4F97200081A00D5404291 +:10BB6000DAF800800FFA80FC98F87A3998F87B7937 +:10BB700098F8780998F879199C450FDB9F420DD009 +:10BB8000BC4501DD084609E0ACEB030C091A0CFBCF +:10BB900001FCF91A9CFBF1F1084400B2B4F98010E1 +:10BBA0005143002905DD002E00DC40424844A4F842 +:10BBB0006A00B8F93410B4F96A0007F066FE12E0C2 +:10BBC000DAF80020B4F96E00918E884203D1B4F9FE +:10BBD00072308B4203D048B9B4F8721031B9B4F95D +:10BBE0006A10814202D0A4F86A0008E0BBF1000F9D +:10BBF00005D192F88003000601D400200090D4F80B +:10BC00006A0028600098BDE8F88F10B5044690F8E7 +:10BC1000C40104281DD1B4F84200400519D404F130 +:10BC20000C01081D07F069FE01466048006890F8A5 +:10BC30006629B4F84200524343050AD4914202DA1D +:10BC400040F4007003E020F4007040F48060A4F839 +:10BC5000420010BD2DE9F0410E4604460125FFF7D4 +:10BC6000D4FF94F8C401032804D0042807D008287E +:10BC700025D027E03146204600F029F822E04B4F3E +:10BC8000386890F88103C00609D531462046FFF791 +:10BC900000FE054694F88200012803D00CE0012044 +:10BCA00084F88200386890F88103000704D5314693 +:10BCB0002046FFF754FE0546012D03D005E0D4F8D9 +:10BCC0007A0030603068C4F87A002846D9E570B54B +:10BCD00004460868C4F86A000D46032204F16E00A9 +:10BCE00007F0E8FD3148016891F88103C2064FF082 +:10BCF000000025D52E4A167801227F23D6B1B4F84C +:10BD00004260360516D584F8820084F8832084F8D2 +:10BD10008430D4F8BE21C4F86A206A88B4F86C3044 +:10BD2000D21AA4F868202A88B4F86A30D21AA4F883 +:10BD3000662005E084F8820084F8832084F884304B +:10BD400091F88113090702D524F87E0F608070BD39 +:10BD500010B50C460DF032F814490A6880B192F81B +:10BD6000730992F8703900F00F01000992F87129F7 +:10BD70005B4352439C4202DD94420CDB084610BDFB +:10BD800092F8720992F86E3900F00F0100095B43D6 +:10BD900092F86F29EDE79A4200D1521CE41A411A39 +:10BDA0004C43D11A94FBF1F1401A10BDB8071000B2 +:10BDB000F407100030B50124039D9C4035B10914EF +:10BDC00091420EDA81682143816030BD09B291420F +:10BDD00003DA01682143016030BD416821434160BD +:10BDE00030BDC1682143C16030BD2DE9F8439146A3 +:10BDF0000646DDE9087208790025DDF828C00C4602 +:10BE0000032832D2FE48DFF8FC83016891F89214CF +:10BE1000E170D8F80480B8F1000F06DDD0F800809A +:10BE200098F89384A1EB0801E1700068716BB0F899 +:10BE30009404814217DDDBB249463846CDF800C094 +:10BE4000FFF7B8FF2079401CC0B22071032806D04C +:10BE5000ED49B6F95600B1F90010884205DD03201E +:10BE60002071012501E0002020712846BDE8F883FB +:10BE70002DE9F0470446E548007800285BD0E0480B +:10BE8000006890F88804C00655D594F9D3010028BD +:10BE900051DAB4F8420080044DD4B4F840000026D2 +:10BEA000400500D5012604F10C000CF0A5FF054665 +:10BEB000B4F842004FF0010941044FF002074FF07F +:10BEC00003081ED535430CD084F8C47140F004003B +:10BED000A4F8420094F8C801032822D284F8C8814B +:10BEE0001FE04BF6FB71084040F42050A4F84200DC +:10BEF000002204F5DF71204600F0FFFC84F8BA91BF +:10BF00000FE004F120000CF077FF012801D1012D92 +:10BF100013D0B4F8420020F4804040F40050A4F85C +:10BF20004200B4F84200400405D5B94810F8511F4A +:10BF300041F004010170BDE8F087002EF1D0B4F8A3 +:10BF4000420044F204010843A4F8420084F8C4719A +:10BF500094F8C801032801D284F8C8810021C4F8EC +:10BF6000B811C4F8BC11C4F8C011E168C4F8BE111E +:10BF700084F8C291D5E72DE9FF5F4FF0000B0C4626 +:10BF800081465E464FF0020A4FF0010800F58057E7 +:10BF9000E9E000BF08FA06F0D7F8201C0090014243 +:10BFA00064D0C6EB061109EB411505F5DC70039072 +:10BFB0002846FFF75DFFB5F84210480456D4EA68FA +:10BFC00095F8C4019446012813D0022811D04807DF +:10BFD0007ED50398B0F906108E48B0F91020914232 +:10BFE00003DBB0F91230994273DD0020F3B2009008 +:10BFF0009DE08949B5F95430B1F900108B4235DB29 +:10C00000012804D103980021016041608160814BC7 +:10C0100010B2B3F90010884208DBB3F9021088426D +:10C0200004DC1114B3F90A2091422FDDB5F8421057 +:10C0300041F00401A5F842100399EA68C1F806200E +:10C04000B3F90010884203DBB3F9022090420EDD01 +:10C0500000200094CDE9011033466246284603993A +:10C06000FFF7C3FE0399834681F80AA07AE0B3F98B +:10C0700008103346CDE900416246CDF808802846D5 +:10C080000399FFF7B2FE8346042140E0B3F9102084 +:10C09000904207DBB3F91220904203DCB3F91A2077 +:10C0A000914237DDB5F8421041F00401A5F8421085 +:10C0B0000399EA68C1F80620039A82F80A80B3F966 +:10C0C0001010884203DBB3F91220904211DD01E029 +:10C0D00032E027E000200094CDE9011033466246AB +:10C0E00028460399FFF781FE0399834681F80A8069 +:10C0F00038E0B3F918103346CDE900416246CDF877 +:10C10000088028460399FFF770FE834603210398B1 +:10C11000817227E003990020887220690099084302 +:10C1200020611FE0CDF80080B0F91820F3B261461D +:10C130002046FFF73FFE15E0364811B2B0F9103047 +:10C1400099420FDDB0F9123099420BDAB0F91A00BA +:10C150001114814206DA2169009A114321612F49A5 +:10C1600081F80080761C97F9280CB042BFF612AF18 +:10C1700020686568A168E36840EA050241EA0306B1 +:10C180003243204E226901D022B105E022B186F867 +:10C1900000A001E086F800801E4A58321668B043BD +:10C1A000206050688543656090688143A160D068D5 +:10C1B0001B498343E36020690978084305D1154989 +:10C1C0002C222C3113480CF0D9FC04B05846BDE8A1 +:10C1D000F09F30B50B4B0021049A1B78012B01D145 +:10C1E00002B1012190F8C421042A41D1044A136804 +:10C1F00093F8882452073BD5B0F84A2012E000009B +:10C20000B80710008406100000071000F4071000A3 +:10C21000A0660120442A1000140710001A0710001D +:10C2200087071000B0F84C40121BFE4C248DA24230 +:10C230001EDD4FF4E172125C012A01D0022A0AD1FC +:10C2400090F85B4090F85A50641B93F89154AC42BC +:10C2500001DD01210CE0032A01D0042A08D190F865 +:10C260005D2090F85C00101A93F891249042F0DC65 +:10C27000084630BD30B5EC4A0021136893F8882495 +:10C2800052072BD590F8C421042A27D1B0F84A20B0 +:10C29000B0F84C40121BE34C248DA2421EDD4FF43B +:10C2A000E172125C012A01D0022A0AD190F85B40A7 +:10C2B00090F85A50641B93F89154AC4201DD01216F +:10C2C0000CE0032A01D0042A08D190F85D2090F8F0 +:10C2D0005C00101A93F891249042F0DC084630BDBF +:10C2E0002DE9F34F97B0D148002415940078DFF87A +:10C2F00034B301280BD11898006940B1DBF80CA0C9 +:10C30000DBF81490DBF80470DBF81C0007E0DBF8C6 +:10C3100008A0DBF81090DBF80070DBF81800179E1F +:10C320008046002506F58056A8E10120A840D6F8F1 +:10C33000201C059001420ED01798C5EB051100EBAB +:10C3400041100290B0F84200410404D4400703D4E5 +:10C35000B7490120087090E1029800F5DC70039065 +:10C360000298C0680B900790029890F8C4010128C9 +:10C3700006D0022804D004282ED005287ED07CE1E7 +:10C3800018981422C1680091006901900BA81899AF +:10C390000CF0AFFB0DF12C0C02989CE80E00FFF79F +:10C3A00018FF012801D10399487018981422C16818 +:10C3B0000091006901900BA818990CF09AFB0DF1FF +:10C3C0002C0C02989CE80E00FFF754FF0128C2D104 +:10C3D00003980021C17050E118981422C16800919F +:10C3E000006901900CA818990CF083FB0DF1300C3A +:10C3F00002989CE80E00FFF73DFF012809D0039842 +:10C40000C07848B10399401E10F0FF00C87003D0F7 +:10C4100008E003990020C870029890F8CE1101201E +:10C420008840044318981422C16800910069019063 +:10C430000CA818990CF05DFB0DF1300C02989CE8EB +:10C440000E00FFF7C6FE012801D10399487003983A +:10C450000079032820D20399C978E9B102994A6B7F +:10C4600071490968B1F894148A4212DD401C03999D +:10C47000C0B20328087109D0029800E0DFE06D49DE +:10C48000B0F95600B1F90010884205DD0120159081 +:10C4900002E00399002008710B983AB200B2904272 +:10C4A00008DB3914884205DC0B994FEA2A4309144A +:10C4B00099421BDDDDE902319042DB68C1F80630AC +:10C4C00002DB3914884206DD03980221EBB2817247 +:10C4D0000020009007E003980421EBB28172012054 +:10C4E0000FFA8AF200900799189867E00FFA89F21C +:10C4F0000692904207DB4FEA2942904203DC4FEA62 +:10C50000284081425DDD0398807A022802D0042809 +:10C5100004D00BE003990120887202E00398032104 +:10C520008172DDE90210C968C0F8061003984078EE +:10C5300068BB0398801D00900298DBF824100591D9 +:10C54000019090F8C2110C300129009929D007F010 +:10C55000D4F9059988420FDDDDE90010002200F0D2 +:10C56000CCF901984FF6FB31B0F84200084040F496 +:10C5700000610198A0F842100298B0F8420000054E +:10C5800005D5029890F8CE11012088408443039885 +:10C59000807A01280CD00120EBB20FFA88F20090CB +:10C5A000A1E7B1F90210B0F90200081A4043D0E740 +:10C5B0000020DDE906210090EBB21898FFF7FAFBA6 +:10C5C0005BE01898059900220069084318990861F2 +:10C5D000DDE90201891D00F090F902984FF6FB3168 +:10C5E000B0F84200084040F400610298A0F8421000 +:10C5F0000399012088700298B0F844100A48006836 +:10C6000090F89E24914208D9029990F89F0491F8DD +:10C61000C8110844029981F8C801029890F8CE1117 +:10C62000012009E0442A1000B80710008406100019 +:10C630001A07100000071000884084431DE003988B +:10C64000807A012801D0032817D10398C078A0B1BF +:10C65000DDE902010122891D00F04FF90298B0F8CE +:10C66000420020F0040040F400410298A0F842107B +:10C670000298B0F85610A0F854106D1C96F9280CCA +:10C68000A842BFF652AEA648006890F8880480071A +:10C6900002D52046F9F745F9A2480CB1012100E086 +:10C6A00000210170159819B0BDE8F08F30B59C4994 +:10C6B0000A689D49938E08801B1A4B8092F8974414 +:10C6C00005198D801B1BCB80528E0881101A488162 +:10C6D0008D81001BC88130BD914909688A8E9249BD +:10C6E0000884101A488470478D498F4A0B68598E08 +:10C6F00048B11083091A518393F89A3418449083EF +:10C70000C81AD08370470020108351839083D1834F +:10C710007047834A10B4136883499A8E60B10882C7 +:10C72000121A4A8293F89A4420448882101BC882C5 +:10C7300093F89D0410BCCFE7002008824A828882CB +:10C74000CA8208844A8410BC704770B5744C206853 +:10C7500090F89604FFF7AAFF206890F89B04FFF773 +:10C76000D8FF206890F88704FFF7BEFF22686E4963 +:10C7700092F898044043486292F8990408852C2264 +:10C78000A1F12C000CF0FAF966480024684D047001 +:10C7900066481421047064486C602C300CF04AFA2E +:10C7A000644804702C7070BD5E48007850B15C48DD +:10C7B000006890F88804800704D55C48007808B1C8 +:10C7C000012070470020704770B586B006461421DE +:10C7D00068460CF02FFA554800246946047030462C +:10C7E000FFF7C9FB054669463046FFF779FD284348 +:10C7F0004F49012801D0486805E04948006890F891 +:10C800009204401F4860002804DD401E48604548EF +:10C81000007800B94C604448142269462C300CF072 +:10C82000ADF906B070BD2DE9F04700F138060546B8 +:10C83000B078414F0B460024B8B1404AF1781078E7 +:10C84000401E814257D1C1B2904618460CF004FBFD +:10C85000814698F80000401EC1B238680CF002FB17 +:10C86000034630787278014610E0002118460CF03B +:10C87000F3FA81460021F0E719F8006095F843705B +:10C88000BE4201D1641CE4B2401CC0B28242F3D269 +:10C89000234E61B13068B0F88A04491EC9B233F939 +:10C8A0001170874203DD641CE4B20029F5D12448ED +:10C8B0000078401E82420DDA316882420ADA521C48 +:10C8C000D2B2B1F88AC433F91270674502DD641C34 +:10C8D000E4B2F2E71B4880F85240316891F89C14AA +:10C8E000A14208D2A98C41F48061A98410F8511F9B +:10C8F00041F008010170BDE8F087022380F8C431DF +:10C90000002380F8C8310123C362012A04D00968DA +:10C91000016280F8B831704703220C3006F0CABFBC +:10C92000B807100018071000702A10001A0710002E +:10C93000840610001907100074071000510710003A +:10C9400052071000A0660120FAF752B810B541F660 +:10C950001851CD480CF06EF940F23C41CB480CF038 +:10C9600069F9CB48FF2180F8281C00F069FCFEF72C +:10C9700084FBFFF7EAFE00F09BF9FCF70AF9FCF7ED +:10C9800074FFFDF745FDBDE81040FAF733B870B508 +:10C99000C04C0025BC48A57100F058FCBE4800689A +:10C9A00090F84004C00605D5BC48007910B1B648DF +:10C9B000FEF709F9BA48007828B1B348FFF704FF39 +:10C9C000B14800F076F9B048FCF7EBF8AE48FCF758 +:10C9D0005AFFAE4880F83854AD48B0F82C0CA4F893 +:10C9E0001F0070BD2DE9F047A849AA4D91F8380401 +:10C9F00088B1A94CA87189462368A84E93F85002C3 +:10CA0000810623D5400621D53078F8B1A5480078B5 +:10CA1000012803D01AE0FFF7BAFF4FE0DFF86C827D +:10CA2000A149002047F6FF72A8F1180801EB800722 +:10CA3000B7F902C0944506D031F920C0944502D020 +:10CA40003F68C8F82470401C0A28EFD39748002795 +:10CA5000077093F88002810709D5000603D58B483B +:10CA6000FEF7A3FC03E089498748FEF7ADFA874942 +:10CA7000854800F01BFC206890F84004C00604D5EF +:10CA8000307910B18048FEF79EF88548007810B1E3 +:10CA90007D48FFF799FE206890F88003C00702D018 +:10CAA0007948FEF727F8784800F003F97648FCF754 +:10CAB00078F87548FCF7E7FE89F838747448B0F8E0 +:10CAC0002C0CA5F81F00BDE8F0872DE9F0416E4E53 +:10CAD000002401274FF0080806F5805521E000BF2B +:10CAE000D5F8200C07FA04F1084219D0C4EB041061 +:10CAF00006EB401090F8C411032909D0042907D08F +:10CB0000052905D0062903D0072901D0082907D116 +:10CB100080F8C48190F9D311002901DB06F03FFAB7 +:10CB2000641C95F9280CA042DADABDE8F08110B552 +:10CB3000584800248471544800F088FB5248FCF7A0 +:10CB400030F85148F9F76FFF504880F8384410BD6D +:10CB500010B54E4C94F8380490B14E498871214676 +:10CB6000494800F0A3FB484800F0A3F84648FCF70A +:10CB700018F84548F9F757FF002084F8380410BD2D +:10CB8000BDE81040D3E710B5404C014694F8380496 +:10CB90000F280BD200EBC00004EBC00048220BF0C2 +:10CBA000EDFF94F83804401C84F8380410BD10B52B +:10CBB00000F580500021D0F8203C012202FA01F457 +:10CBC00023420BD18A401343C0F8203C90F9282C13 +:10CBD0008A4201DA80F8281C48B210BD491C0F298E +:10CBE000ECDB4FF0FF3010BD10B500F5805091F830 +:10CBF000D2410123D0F8202CA3409A43C0F8202C26 +:10CC0000002281F8C42190F9282C91F9D2118A428E +:10CC100007D1D0F8201CB1FA81F1C1F11F0180F8D1 +:10CC2000281C10BD30B500F580500022D0F8244CEF +:10CC3000012300BF03FA02F52C4206D193401C43A6 +:10CC4000C0F8244C81F8D32130BD521C52B20A2ABC +:10CC5000F0DBFF2081F8D30130BD10B500F5805026 +:10CC600091F8D3410123D0F8242CA3409A43C0F873 +:10CC7000242CFF2081F8D30110BD044870470348DD +:10CC800090F8380470470000B02A1000C847100020 +:10CC9000B03A1000A0660120B8071000800710000D +:10CCA000F407100012051000C02410008C061000BC +:10CCB00070472DE9F05F0546042100F5E1500AF0C8 +:10CCC0006BFC002400F0FF080127DFF81891DFF863 +:10CCD00018A14FF0050B05F580567CE0D6F8201C16 +:10CCE00007FA04F0014274D0C4EB041005EB4011C4 +:10CCF00091F8C401012804D0022802D0042844D0AD +:10CD000067E091F8C501032804D0042802D0012867 +:10CD100034D05EE0364A35481278B0F90000042A73 +:10CD20000DD1B8F1010F0AD1324A12783AB9B1F8EF +:10CD30004220120403D430480068B0F9FE02B1F872 +:10CD4000422048F204031A4202D02C48B0F90000F5 +:10CD5000130702D52A48B0F90000B1F954308342D4 +:10CD600037DAD00506D5B9F90000834202DD81F833 +:10CD7000C5712EE02846FFF737FF2AE0B1F95420AD +:10CD8000B9F900008242F5DB23E091F8400010F091 +:10CD9000060F1ED091F8420040071AD41A4A1948CB +:10CDA0001278B0F90000012A01D1BAF9000091F817 +:10CDB000C521032A02D0022A05D00AE0B1F9542085 +:10CDC000BAF9000001E0B1F95420824201DA81F899 +:10CDD000C4B1641C64B296F9280CA042BFF67EAFC1 +:10CDE000BDE8F09F040710000607100000071000C0 +:10CDF000E80410008C061000B8071000140710009B +:10CE00001E071000080710001907100090F84010C6 +:10CE1000090604D530F8421F41F00801018070472F +:10CE20002DE9F04715460C46824601F10C074FF0FC +:10CE300000084FF0FF3902F10C0643B3012084F8DB +:10CE4000C40195F8420084F8C50184F8D39184F8B0 +:10CE5000C88184F8C981A4F84280C4F82C8084F881 +:10CE6000C78184F8CA8195F8440084F8CD01688EA2 +:10CE7000A4F85600E868206203223146204606F0F6 +:10CE800019FD03223146384606F014FD14E0114620 +:10CE9000204600F0CDFAE06A0322401CE0623146F1 +:10CEA000204606F0FAFC03223146384606F0F5FC2F +:10CEB00094F8CC0184F8CD0194F8C50104284CD035 +:10CEC00095F8420084F8C50195F8440084F8CC0137 +:10CED00095F8430084F8CE01E88CA4F84400288D2E +:10CEE000A4F84600688DA4F84800E88DA4F84A002C +:10CEF000288EA4F84C00288BA4F84E00B5F9320017 +:10CF0000A4F85400A9696163E969A163296AE1632E +:10CF1000A98EA4F85810A98CA4F84010A96BC4F8E5 +:10CF20005A106969E16195F8451084F8CF1195F8B8 +:10CF3000461084F8D011B4F95610814201DAA4F8F1 +:10CF40005600C4F8D88184F8D191A88C8005B4F833 +:10CF5000420016D540F4807015E095F8421004297F +:10CF600008D094F9D401002801DD401E06E084F8C1 +:10CF7000C511A9E7FB48006890F80A0484F8D401B9 +:10CF8000A2E720F48070A4F842002146504600F049 +:10CF900025FA2046BDE8F04738E7F0B5B1F9026060 +:10CFA000B2F90250782406FB05F7002F2ADDB1F90B +:10CFB0000070B2F900C007FB0CF7002F22DD7643AA +:10CFC0005D4396FBF5F52DB24580B1F90010B2F93D +:10CFD000002049435A4391FBF2F10AB20280782DB6 +:10CFE00000DD4480B0F902306FF077018B4200DA47 +:10CFF0004180782A00DD0480B0F900208A4200DAFE +:10D000000180F0BD00214180FAE72DE9FF4FDFF8F4 +:10D01000588383460F46D8F8040087B0002101608A +:10D0200000F095FA00250BF580564FF001090590A8 +:10D0300083E000BFD6F8201C09FA05F001427AD03F +:10D04000C5EB05110BEB411494F8C401072872D00D +:10D05000C448059901910068214690F88CA3201DD1 +:10D0600006F04BFC00FB0AF0019900FB0AF0884235 +:10D0700000DA0846BB49096891F88123920611D568 +:10D08000E26A012A0ED802D191F8D61302E04AB919 +:10D0900091F8D513019A01FB01F101FB02F18842DD +:10D0A00000DA084682462246211D684606F01BFC2F +:10D0B000221D111D03A806F016FCBDF90000643006 +:10D0C000C82804D8BDF902006430C82801D901235A +:10D0D00000E0032303AA694602A8FFF75EFF608809 +:10D0E000BDF80A100844ADF812002088BDF80810F9 +:10D0F00000240844ADF8100019E000BF04EBC400A0 +:10D1000007EBC00104A80C3106F0F7FB50450CDA20 +:10D11000D8F804100A6802EB420201EB42025060A8 +:10D12000547215720868401C0860641CE4B297F8D9 +:10D130003804A042E2D86D1C6DB296F9280CA842C2 +:10D14000BFF678AFD8F8040045460168002974D0CE +:10D1500000F0D9F900244FF0040A6AE004EB44011E +:10D1600000EB410090F9082090F90910099809FA9C +:10D1700002FC0368484613EA0C0F59D10A9E00FAD4 +:10D1800001F8366816EA080F52D1099843EA0C03F1 +:10D19000C2EB021203600A980A9B0BEB421600686E +:10D1A00040EA0800186001EBC10007EBC002002351 +:10D1B00031465846FFF734FE96F8C401032804D0E0 +:10D1C000042805D0062809D032E086F8C79102E08D +:10D1D000002086F8C70186F8C4A129E086F8C4A11A +:10D1E00096F8400010F0060F22D096F84200400753 +:10D1F0001ED45F495D480978B0F90000012902D1C9 +:10D200005C48B0F9000096F8C511032902D0022944 +:10D210000AD00DE05748B6F95410B0F9000005E007 +:10D22000062086F8C40103E0B6F954108142F7DB0A +:10D23000641C68680168A14290DC0BB0BDE8F08F07 +:10D240004948002101704160816070472DE9F0413B +:10D25000054641F66C402E2128440BF0EBFC0024DF +:10D2600005F5805601274FF0050819E0D6F8200C87 +:10D2700007FA04F1084212D0C4EB041005EB401188 +:10D2800091F8C401032804D0042802D0022803D056 +:10D2900005E081F8C48102E02846FFF7A5FC641C84 +:10D2A00096F9280CA042E1DABDE8F0812DE9FC47AF +:10D2B000044600252C480F4600950121001D0195CC +:10D2C00003F0F6FF28480521083003F0F1FF41F68E +:10D2D0006C402E2120440BF0ADFC234EFF222D216B +:10D2E000B0680BF07DFC357004F580564FF00108F6 +:10D2F000D6F8200C48B36B4601AA39462046FFF702 +:10D3000084FE4FF005091CE0D6F8201C08FA05F051 +:10D31000014215D00199084212D1C5EB051004EB6A +:10D32000401191F8C401032804D0042802D0022837 +:10D3300003D005E081F8C49102E02046FFF754FCD9 +:10D340006D1C96F9280CA842DEDA002537E000BFF4 +:10D35000009908FA05F0084230D1D6F8200C58B1EF +:10D3600000200AE0B807100090061000080710001F +:10D370001907100006071000012082462046FFF71B +:10D3800016FC00281ADBC0EB001104EB411905EB79 +:10D39000C50107EBC10289F8D201494601232046A5 +:10D3A000FFF73EFDB9F84200BAF1000F02D040F499 +:10D3B000805101E020F48051A9F842106D1C97F8CB +:10D3C0003804A842C4D80121764803F089FF754883 +:10D3D0000521001D03F084FFBDE8FC8730B5714ACC +:10D3E00091F8CC51121F9468635DFF2B05D113781F +:10D3F00063550F2B01D25B1C137091F8CC21A25CFA +:10D4000081F8CC2100EB420202F5805291F8D25112 +:10D41000B2F86C3C0124AC402343A2F86C3C91F878 +:10D42000CC1141F68A4210440A5C521C0A5430BDA9 +:10D430002DE9F041044691F8420000260D460128EE +:10D4400001D184F8CA6194F8C501574FDFF85C81B7 +:10D4500001281FD195F8420003284DD194F8C4014A +:10D46000022804D0032806D0042804D01EE0204659 +:10D47000FBF774FB0EE0D8F8001094F8CA0191F89D +:10D480004B1301F00F01884202D83978012906D0E8 +:10D4900084F8CA6195F84200032807D008E0401CD0 +:10D4A00084F8CA01012085F8420001E084F8CB61CC +:10D4B00094F8C50103281FD195F8420001281BD11B +:10D4C00094F8C401042817D13878B0B9D8F800000E +:10D4D000B4F956200321B0F852339A4210DA94F886 +:10D4E000CB2190F85403824207D285F8421094F879 +:10D4F000CB01401C84F8CB01D6E684F8CB61D3E69F +:10D5000085F84210F9E77CB500211CE001EB4103EE +:10D510004A1C00EB430312E002EB420400EB44041C +:10D520005E686568AE4209DD00961E89ADF804604C +:10D530005D6025891D81009D65602681521C0468FF +:10D540009442E9DC491C02688A42DFDC7CBD70B58C +:10D55000164D2868B0F882430BF030FC80B1286883 +:10D560001349B0F88643B0F88A030968884207DA9D +:10D570000BF02EFC012803D12868B0F8880304447E +:10D580000C48007810B12868B0F876420BF020FC07 +:10D59000012804D12868B0F8840300B1044604FBD4 +:10D5A00004F070BD940610005B071000B80710006F +:10D5B00088071000200510002DE9F84F0022914641 +:10D5C000154614460092F74AF74B1268B3F900C0AB +:10D5D000F64B178E1E68674560D18646F44802F107 +:10D5E000320A8B4690F800C0F24807784DE03A4680 +:10D5F00043E000BF3AF812103EF812003BF8123038 +:10D60000081AC91A00B20BB2002801DB014600E07B +:10D610004142494506DD002801DB014600E0414268 +:10D620000FFA81F9191A01D4884601E0C1F1000806 +:10D63000A84505DD002901DB0D4600E04D422DB275 +:10D64000002900DA4942B6F8E283414515DD002B96 +:10D6500000DA5B42011E00DA41428B4202DD641CAB +:10D66000A4B20AE0002800DA4042B6F8E413884287 +:10D6700003DD4FF0000C644601E0521EBAD10AEB04 +:10D68000470A0EEB470E0BEB470BBCF1010CAED279 +:10D6900096F8E603A04201D20120009096F8E71325 +:10D6A000C548009A06F0A3F8C44921F8255F21F87F +:10D6B000029C8C70BDE8F88F10B50C46BC49097807 +:10D6C0004A000146BE480BF014FABA4821460078D9 +:10D6D0004200BC480BF00DFABB490120087010BD98 +:10D6E000B14910B5B1F900104A000146B7480068C9 +:10D6F0000BF0FFF9B6490120087010BD2DE9FF5F5E +:10D70000AD4800240838994644600470A74827466D +:10D7100026460168254691F8AB22520701D5AD4A4D +:10D720001570824691F8E003DFF88C82C0070ED0B6 +:10D73000032009F0E2F9A54801680098FFF73CFFD3 +:10D7400004461126032009F0F3F914B164E088F8C7 +:10D750000050A148017809B94078E8B3F7F7DDFE39 +:10D76000DFF878B29BF8000078B9DAF8000090F89A +:10D77000E103C00709D09C48994A9A49006800F023 +:10D7800086F830260446012701E088F801509BF80E +:10D79000000020430FD1DAF8000090F8E103800781 +:10D7A00009D591488E4A8F49006800F0B5F80443C6 +:10D7B0003126012701E088F802509BF80000204341 +:10D7C00028D1DAF8001091F8E023520722D5854BD2 +:10D7D000834FB1F9FD2300E01EE07548017818463B +:10D7E00006F07DFF0646DAF80000B0F9FD23714827 +:10D7F0000178384606F073FF40EA0602DAF80000C6 +:10D8000090F8FF1308F1030005F0F1FF044321260F +:10D81000012701E088F803500BF0E0FA0146734855 +:10D8200001704CB36FB189F800503146052005F006 +:10D83000C1FB0098FFF754FFDDE90101FFF73CFF52 +:10D8400016E0012089F800005B480838067041683E +:10D8500041F002014160DAF8002092F85032DB0713 +:10D8600003D192F88022D20702D041F00801416032 +:10D87000012004B0BDE8F09F89F800500078F8E777 +:10D880004D480021083841600170816070472DE9E2 +:10D89000F74FDFF818910B468246D9F8001044483C +:10D8A0000026B1F9E87391F8EC83B1F9EA530278F4 +:10D8B00034463946184600F06EF883463D483946EE +:10D8C0000278029800F067F80146BBF1000F00D023 +:10D8D000A1B9354852460024B0F9000009E000BF64 +:10D8E00032F91010002900DA4942A94201DD641C16 +:10D8F000E4B2401EF4D2444500D90126D9F8000014 +:10D90000324690F8ED132C48401C05F070FF2B496F +:10D9100081F83140BDE8FE8F2DE9F047DFF88C80BB +:10D9200084460B46D8F800001F49002590F8F27392 +:10D93000B0F9F06391462C46B0F9EE03B1F900104E +:10D9400007E000BF3CF91120002A00DA524282426F +:10D9500013DC491EF6D2164831460278184600F00C +:10D960004BF80446134831460278484600F044F824 +:10D970002044C4B2BC4200D90125D8F800002A4690 +:10D9800090F8F3130C48801C05F031FF0B4981F827 +:10D990003240BDE8F0872BE030F912308B4227DDB2 +:10D9A00001207047BC07100060071000B807100086 +:10D9B0005107100052071000A4061000A0660120B5 +:10D9C0004C6D0120766D0120ED0710007C071000E2 +:10D9D000EC0710002C051000800710005C071000F9 +:10D9E000221B0120F81A012070071000EA0610001F +:10D9F000521ED1D20020D4E710B50346002005E026 +:10DA000033F912408C4201DD401CC0B2521EF7D2E5 +:10DA100010BD00002DE9FF4F8FB04FF0000A9A486B +:10DA2000CDF814A0CDF810A000680C469346B0F8CD +:10DA3000BA020690D046897850680BF005FA079034 +:10DA4000A07809908146E0780A9033E00F99257814 +:10DA500001EBC9000D906078089020E00D982A46EF +:10DA60000021D0E9006701200AF0F9FF06400F40CD +:10DA70003E4312D00798069930F9150088420CDD14 +:10DA80000599804405FB00110591049909FB0010DC +:10DA900004900AF101001FFA80FA08986D1CA84250 +:10DAA000DCDA7A49079809F10109097800EB4100AD +:10DAB00007900A984845C9DABAF1000F45D1724873 +:10DAC00009990068B0F8CB020690DBF804000BF06F +:10DAD000BBF9089094F80290E078099033E00F9831 +:10DAE000257800EBC9000B906078079020E00B9838 +:10DAF0002A460021D0E9006701200AF0B0FF064065 +:10DB00000F403E4312D00898069930F9150088421C +:10DB10000CDD0599049A05FB0011804409FB0020E7 +:10DB200004900AF1010005911FFA80FA07986D1C14 +:10DB3000A842DCDA5549089809F10109097800EB97 +:10DB40004100089009984845C9DA4F480024056803 +:10DB50000498A98EC217A1FB003604FB006001FBEC +:10DB600002064FF6FF71A3FB010706FB017103FBE1 +:10DB7000041195F8313030355B1E88FB03230AF021 +:10DB800094FF47F6FF7280184FF6FF7941F10001CC +:10DB90004A4600230AF089FF074605986988C3179B +:10DBA000A1FB002604FB006001FB03014C46A2FB25 +:10DBB000040601FB0461002302FB03112A78521EB4 +:10DBC00088FB02230AF071FF6210801841F1000106 +:10DBD0004A4600230AF069FFCBF81C80ABF828A066 +:10DBE0001299486012990F6013B0BDE8F08F10B51C +:10DBF0002549436800220968002B01DA426003E0EE +:10DC00004C8EA34200DD44600368002B01DA026001 +:10DC100010BD898E8B42FBDD016010BD7CB51446C2 +:10DC200000256B46FFF7F6FE19480178164829B122 +:10DC3000016891F80715090700D5042594F84210EA +:10DC4000032902D0012907D00FE0006890F80705EA +:10DC5000C0070AD0294605E0006890F8070540078C +:10DC600003D50221684601F029FE6846FFF7BFFF91 +:10DC70000198E0810098A08194F82400C00601D4A6 +:10DC8000E06860617CBD0000B8071000520710001A +:10DC9000180710002DE9F047054690F802800F465E +:10DCA00088681446012641460BF0CEF88146A8F15B +:10DCB0000100C1B2B8680BF0C7F8297809EB41023E +:10DCC00032F9022CA24203DB30F91110A14200DA32 +:10DCD0000026697809EB4102B2F90220A24203DB77 +:10DCE00030F91100A04200DA002695F80380B868E8 +:10DCF00041460BF0A9F8814608F10100C1B2B868AD +:10DD00000BF0A2F8297809EB410232F9022CA24269 +:10DD100003DB30F91110A14200DA0026697809EB23 +:10DD20004102B2F90220A24203DB30F91100A04205 +:10DD300000DA00263046BDE8F0872DE9FF4FFB48AA +:10DD4000DFF8EC839246046897B099460122514669 +:10DD5000D8F8000001F0D4FAF6480068B0F94D1484 +:10DD6000119190F84C040A90F3489AF802709AF8CE +:10DD7000036000789AF800B09AF80150401E87427C +:10DD800001DA7F1CFFB20EB1761EF6B2EB490978BC +:10DD9000491E8B4503DA0BF1010000F0FF0B0DB1BA +:10DDA0006D1EEDB2B81EC1B2D9F808000BF04CF8E8 +:10DDB0000B90781EC1B2D9F808000BF045F804901A +:10DDC0003946D9F808000BF03FF80190781CC1B231 +:10DDD000D9F808000BF038F80290B81CC1B2D9F895 +:10DDE00008000BF031F80390394617980BF026F82D +:10DDF0000890CF48394600680BF02EF88646002080 +:10DE00007AB2CF4F0C90B7E04FFA8BF094E000213C +:10DE10000EF800100899189B095C994275D1DFF83B +:10DE200014C3019BDCF800C033F91030BCF84FC4B8 +:10DE300063456ADA00211491139111991944049BE6 +:10DE400009B233F9103010938B4206DD029B33F98F +:10DE500010308B4201DD01231393019B03EB400340 +:10DE600033F9028C884507DDB3F902C08C4503DD28 +:10DE70004FF0010CCDF850C0012A0FDDDDF82CC0A9 +:10DE80003CF910C08C4509DDDDF808C03CF910C034 +:10DE90008C4503DD4FF0010CCDF84CC0DFF898C283 +:10DEA0009CF800C0ACF1020C62450DDADDF840C010 +:10DEB0008C4509DDDDF80CC03CF910C08C4503DD54 +:10DEC0004FF0010CCDF84CC001280BDD33F904CC28 +:10DED0008C4507DDB3F902C08C4503DD4FF0010C22 +:10DEE000CDF850C0DFF854C29CF800C0ACF1020C71 +:10DEF000604505DA884503DDB3F904308B4212DC56 +:10DF0000149981B913990DE0FFE799B90199B7F90F +:10DF1000003031F9101099420CDA8649096891F8FD +:10DF20004114C90731B101210EF800100C99491CA8 +:10DF300089B20C91401C40B2A8427FF768AF7F487D +:10DF40000B990EF1280E007801EB40010B9104991A +:10DF500001EB40010491019901EB4001019102990B +:10DF600001EB40010291039901EB400003900898F6 +:10DF70002830521C52B20890B2427FF745AF0A993E +:10DF80000C9888422AD9002084F80E01DAF80000A3 +:10DF90002060674800231A462146006801F0F8FA1D +:10DFA000012517E004EB85000646514600F03FF9D5 +:10DFB00070B104EB4500B0F8B4100A98814207D95B +:10DFC0003046B7F900204946FFF764FE012806D025 +:10DFD0006D1CEDB294F80E01A842E3D200201BB0F4 +:10DFE000BDE8F08F2DE9F84F04465048DFF8408136 +:10DFF00091468B46056801222146D8F8000001F0C1 +:10E000007FF90027A6784FF0010A1DE03146D8F8C5 +:10E0100000000AF021FF00903146DBF808000AF00A +:10E0200013FF01462078524609E000BF31F910C0C5 +:10E03000CC4502DA009B01271A54401CC0B2637819 +:10E040008342F3D2761CF6B2E078B042DED2012FE2 +:10E050002ED1002085F80E012068286000231A4682 +:10E060002946D8F8000001F093FA0126DFF8C480B1 +:10E070001AE000BF05EB86072146384600F0D7F8C6 +:10E0800080B105EB4600B0F8B410D8F8000090F865 +:10E090004C04814206D938464A465946FFF7FAFDF4 +:10E0A000012806D0761CF6B295F80E01B042E1D2F6 +:10E0B0000020BDE8F88F2DE9F0411E4E0F46804646 +:10E0C000316814461F481D469A69B1F849340078F2 +:10E0D0009A4210DCEA8C042A0DD96278237891F8F0 +:10E0E0004B14D21A521C8A4205DCE278A378D21A69 +:10E0F000521C8A4202DD0020BDE8F0810028FBD1DD +:10E100000F482946B0F900202046FFF76BFF002892 +:10E11000F2D1316891F840148907EDD52B4622469B +:10E1200039464046BDE8F04107E60000E006100031 +:10E13000C8061000B8071000510710005207100061 +:10E140001C071000A80610002DE9FF4F81B0DFF872 +:10E1500008B1DDF838905FEA030815461DD42C7825 +:10E160000BEBC80A16E000BF08F0FF0101980AF0A7 +:10E1700073FE0090DAE900672246012000210AF0D0 +:10E180006EFC06400F403E4302D10098002101552D +:10E19000641CE4B26878A042E6D2B9F100001EDB4C +:10E1A0000246AC78012000210AF059FC06460F46D1 +:10E1B0004FF0000810E0214601980AF04DFE0BEBED +:10E1C000C4010246D1E9000130403940084301D181 +:10E1D00002F80980641CE4B2E878A042EBD205B0F2 +:10E1E000FEE670B51E4B1D4A8C691B681278B3F8A9 +:10E1F0004954AC4210DCCC8C042C0DD94478057801 +:10E2000093F84B34641B641C9C4205DCC47885780D +:10E21000641B641C9C4201DD002206E02AB9114AFD +:10E22000B2F90020FFF7DEFE0246104670BD02780C +:10E230000B789A420BD942784B789A4207D282786F +:10E240008B789A4203D9C078C978884201D30020DC +:10E250007047012070470000B04C1000A806100065 +:10E26000B80710000607100070B5FB4C00EB430523 +:10E27000049E00EB830386B18E69A660CE8C668017 +:10E2800009686161B5F8B410A1801968E16090F87F +:10E290000E0120701068206170BDA6688E616688CE +:10E2A000CE8466690E60A188A5F8B410E168196093 +:10E2B000217880F80E112069106070BD2DE9FF4FA4 +:10E2C00081B00C461E469978DDF840800E9D0AF01C +:10E2D000C3FD0090B17820460AF0B0FD8346B178C6 +:10E2E000D8F804000AF0B0FD8146DC484FF0000A7F +:10E2F000C8F818A000682860B77841E0347831E0A9 +:10E300001BF80410039881422AD139F914100F9890 +:10E31000814222DD0099039808552978204605F0AE +:10E32000DDF928706978204605F0DCF96870A97875 +:10E33000384605F0D3F9A870E978384605F0D2F9E7 +:10E34000E8700AF101001FFA80FA39F91400D8F8D0 +:10E3500018100144C8F8181002E000990020085570 +:10E36000641CE4B27078A042CAD20098BC4928303C +:10E37000009009787F1C0BF1280B09EB4109FFB2D3 +:10E38000F078B842BAD2A8F826A005B0BDE8F08F60 +:10E390002DE9FF47814693F84200B24E1C4688465D +:10E3A0001546032819D13068B4F9321090F8B70235 +:10E3B0004843642190FBF1F0B4F9361000B2814279 +:10E3C0000BDA03A9CDE900101346494642460294F0 +:10E3D0000846FFF773FF03982860A34F387808B901 +:10E3E000787878B1306890F8300200070AD59F48F5 +:10E3F000007838B923462A4641464846F6F791FC4C +:10E40000002841D09A480178042029B1397819B1FF +:10E4100098490978012904D094F84210032905D0BD +:10E420000CE03268E18C92F87A2203E03268E18CE9 +:10E4300092F80723914201D984F842008E4B2A4674 +:10E440004146484600F013FF00281DD02868A0630D +:10E4500004F14602511E2846F6F781F92246294664 +:10E46000854800F0ABFD85492046FEF7DCF92946DA +:10E47000814800F095FE224629467F48FFF7CEFBF3 +:10E480002046FEF780FB012004B0BDE8F0872DE9AF +:10E49000F0410D461F461646044648210AF0CAFBC5 +:10E4A000002084F84200764800686060A06006EBB7 +:10E4B000450084F8445030F8B41F61850088E0843A +:10E4C00006EB85000068E0636E480088E0866248DD +:10E4D000816921600121A940394201D0406A206050 +:10E4E000BDE8F0812DE9F04789461C461646664D89 +:10E4F00003F1400891780AF0A1FC0746B178606802 +:10E500000AF0A2FC02460020A061B17820E0307839 +:10E5100014E000BF17F800C0CC450DD132F910301F +:10E52000D4F818C0AB429C44C4F818C004DD88F885 +:10E5300000001D4688F80110401CC0B27378834269 +:10E54000E8D24748491CC9B20078283702EB40029C +:10E55000F0788842DBD2658697E72DE9FF411746C0 +:10E560000AAA804692E83100464A1E46B2F90020C7 +:10E57000824202DB002004B0B2E703AACDE900200A +:10E5800002943A464046FFF799FE01212868B940B7 +:10E5900008432860C4F80080E08C10B10398306014 +:10E5A000E8E70120E7E72DE9FF4F81B090460E9C98 +:10E5B0008B4604EB880094F80E71DDF840A00068EB +:10E5C0001E46206001232146584600F0E1FF0198D5 +:10E5D00058451ED0B57819E0294601980AF03CFC50 +:10E5E0008146294658460AF037FC0146307808E053 +:10E5F00019F80030434502D10B5C09F80030401C8B +:10E60000C0B272788242F3D26D1CEDB2F078A842AB +:10E61000E2D294F80E0100250121B84212D01198DF +:10E6200078B17F1CF8B208E0DAF8002001FA00F3B4 +:10E630001A43401CC0B2CAF8002094F80E2182424E +:10E64000F2D2012500914346524620460F99FFF72A +:10E650000BFE284699E60000AC061000DA96010091 +:10E6600052071000B8071000800710005B07100069 +:10E670001005100012051000084C1000DE3B0120B0 +:10E68000700710000E0710000080FFFF10B5FE4A53 +:10E69000FE4C1368647893F8062354B191F8241063 +:10E6A00011F0090F02D093F8091301E093F8081351 +:10E6B0000A44904201D9012010BD002010BD2DE96F +:10E6C000F0471C4617468846814601F087F9EE4E12 +:10E6D000E18C306890F80E23914254D8032184F8DD +:10E6E000421090F8E01200258A0701D4490700D5AE +:10E6F0000125E64AB0F80A135378E54A1BB193792D +:10E700000BB9B0F80C13A38D8B4202D2E149097802 +:10E7100021B1618D032906D2002517E0618D002506 +:10E720000329F9D312E08DB1117979B190F8400441 +:10E7300040070BD521463846FFF753FDD6490870F0 +:10E7400020B1A08C40F08000A08415E0A08C10F4D3 +:10E75000C07F11D185B1306890F8E002C00703D0C6 +:10E760002146384601F00DFB23463A4641464846CD +:10E77000BDE8F04702F050BA23463A4641464846C3 +:10E78000BDE8F04704E6042084F84200F4E7C048FE +:10E79000C07858B1BC48C14A0068126890F8571355 +:10E7A000914205D290F84003800701D500207047C0 +:10E7B0000120704791F82410B34ACB07B84912687A +:10E7C000097806D011B192F8481305E092F8491380 +:10E7D00002E059B192F84613AC4B5B7813B192F852 +:10E7E0004A231144884204D90120704792F8471304 +:10E7F000F2E7002070472DE9FF4F834687B0A44819 +:10E8000000270C46DDF850A001790126154606FACE +:10E810000AF6B946C9B3A348A349B0F90000B1F953 +:10E820000010884231DA296831422ED1E18C042966 +:10E830002BD98DE83100DFF8748252460A9BD8F854 +:10E840001810D8F82400FFF788FE07001DD12346D2 +:10E85000206851460A9AFFF72EFC8F490870A0B134 +:10E86000781E8DF810008DF814008748006890F825 +:10E870004104800705D505AA04A90A98F5F7DBFF2E +:10E8800040B1A08C40F08000A084A08C10F4C07F28 +:10E8900020D02AE086499DF9103001F8363F9DF9D5 +:10E8A000140048700090206859460A9AFFF74CFC03 +:10E8B00001A8CDF800B080E830025246216804F18A +:10E8C0003C03D8F81800FFF76EFE0028DDD00120C9 +:10E8D0000BB05BE52868304207D053462A462146F4 +:10E8E0005846CDF80090FFF7BFFC3846F0E72DE919 +:10E8F000F04F7049DFF8B091E5B0B1F90010B9F907 +:10E900000000CDE9600100276848BA463E46012173 +:10E910001C3002F017FD65480121243002F012FD81 +:10E9200062480221203002F00DFD0221624802F00F +:10E93000BFFC0421614802F0BBFCDFF870B14FF46A +:10E94000667529465C46DBF81C000AF051F9294639 +:10E95000606A0AF04DF95A48B0F900004100206A97 +:10E960000AF046F9294657480AF042F9A8215648C4 +:10E970000AF060F94FF00008454684F80180F6F788 +:10E9800074F9F5F7BFFE51488DF872510123006804 +:10E990001990002219A9A06900F0FAFD4C485D9574 +:10E9A0000025B0F90010B9F9000004F097FE0FFA45 +:10E9B00080F99DF87201012802D9374880F800805B +:10E9C00016A801245E9060E10020019019A800EBD8 +:10E9D0008400059019AA214607A85D9BFFF757FD03 +:10E9E00007AB2146059A0798FFF77CFD01200090B0 +:10E9F00023465DAA07A919A8FFF736FC17A800F05F +:10EA0000A9FB78B1BDF8400040F00100ADF840002E +:10EA100007A800F04CFD28B12E4826490088088040 +:10EA2000214908801B48007838B1BDF8400010F03B +:10EA3000060F02D1284800680890059800F09CFB5A +:10EA400028B1BDF8400040F00800ADF84000BDF925 +:10EA50004E1049457EDD00945DAA07A919A8059BC3 +:10EA6000FFF7C9FE002876D10120A04003905D99F0 +:10EA7000084273D1BDF8400010F4C07F6ED15DAA8A +:10EA800007A909482AE00000B8071000E8071000AD +:10EA90008007100018071000A8061000F4061000E8 +:10EAA0005B0710001C07100006071000AC061000E2 +:10EAB000A066012008071000D4061000E006100030 +:10EAC00060071000DE3B0120084C1000FC0610001F +:10EAD000200710001607100074071000B0F900009E +:10EAE0008DE807002246059BDBF81810DBF82400B0 +:10EAF000FFF733FD0190FE485D9A0088ADF85200A3 +:10EB00000398104224D0FB48BDF84220006890F8DA +:10EB10000E339A4205D890F8E002820718D44007D5 +:10EB200016D401235DAA07A919A88DE80F00224673 +:10EB30005E9BDBF82410DBF81800FFF734FD019032 +:10EB40000120009023465DAA07A919A8FFF78CFBB6 +:10EB5000019802E023E096E000E0C0B9BDF8420071 +:10EB600007A9FFF793FD90B107A80090E24821465E +:10EB70005E9AB0F90030DBF8180000F059FA07ABE4 +:10EB80002146059A0798FFF79AFD012766E023467C +:10EB90005DAA07A919A8CDF80080FFF765FBD64844 +:10EBA000BDF94E10B0F90000814257DDFFF7EFFDCF +:10EBB000E8B30120A04003905D99084234D1CE48CB +:10EBC0005DAA07A9B0F900008DE807002246059B61 +:10EBD000DBF81810DBF82400FFF7BFFC0190C648F3 +:10EBE0000088ADF85200C348006890F84003C006A2 +:10EBF0001AD45D990398084216D001235DAA07A98B +:10EC000019A88DE80F0022465E9BDBF82410DBF884 +:10EC10001800FFF7C8FC01900120009023465DAA70 +:10EC200007A919A8FFF720FB019878B900E015E0C3 +:10EC3000BDF8420007A9FFF7BDFD38B107AB21467B +:10EC4000059A079800F03DFA012607E023465DAAE1 +:10EC500007A919A8CDF80080FFF706FB01205D99F0 +:10EC6000A0400143A54A5D9161991180A04A609935 +:10EC70001180A3490A7832B105439DF87201012839 +:10EC800001D981F80080641CE4B29DF87201A042B1 +:10EC9000BFF49AAE9C4A9B4B9BF80110A2F566709C +:10ECA00001F046FF99489DF872114171A0F81D507E +:10ECB0009749984881F800A007709748022106708C +:10ECC000964802F00DFB0421954802F009FB012152 +:10ECD000944802F09AFB93480121001D02F095FB35 +:10ECE000904801210C3002F090FB8E480221083040 +:10ECF00002F08BFB65B0BDE8F08F2DE9F04F7C484A +:10ED00000025E3B0B0F900608648A946A846012175 +:10ED1000001D02F017FB834801210C3002F012FBAA +:10ED200080480221083002F00DFB02217B4802F0EE +:10ED3000BFFA04217A4802F0BBFADFF8E8A14FF4E9 +:10ED40006677AAF1180A39465446DAF81C0009F029 +:10ED50004FFF3946606A09F04BFF7348B0F9000075 +:10ED60004100206A09F044FF3946704809F040FF2D +:10ED7000AB466F4884F801B08DF872B10068199005 +:10ED80005F4601235A4619A9A06900F001FC01243D +:10ED900005978AE019A800EB84005D9019AA214626 +:10EDA00007A8059BFFF773FB07AB21465D9A079801 +:10EDB000FFF798FB0127234605AA07A919A8009782 +:10EDC000FFF752FA17A800F0C5F928B1BDF84000C6 +:10EDD00040F00100ADF840005D9800F0CDF928B199 +:10EDE000BDF8400040F00800ADF84000BDF94E000D +:10EDF000B04254DD07FA04F005990390084238D177 +:10EE0000BDF8400010F4C07F33D1394805AA07A9E6 +:10EE1000B0F900008DE8070022465D9BDAF8181073 +:10EE2000DAF82400FFF799FB5F90059903980842F0 +:10EE30001DD03048BDF84210006890F80E23914272 +:10EE400005D890F8E002810711D440070FD407A934 +:10EE500019AA05A8CDE90021CDE9020716AB224683 +:10EE6000DAF82410DAF81800FFF79DFBD8B95F989C +:10EE700068B9BDF8420007A9FFF708FC38B107AB35 +:10EE800021465D9A0798FFF71AFC012507E0234603 +:10EE900005AA07A919A8CDF800B0FFF7E5F905986C +:10EEA000A74007430597641CE4B29DF87201A04295 +:10EEB000BFF470AF134B144A9AF801101B4801F0CD +:10EEC00037FE12499DF8720148711149114881F8C5 +:10EED000009011490570114881F80080022102F06C +:10EEE000FFF904210E4802F0FBF901210D4821E051 +:10EEF00006071000B80710000A07100008071000E6 +:10EF0000A8061000B04C1000763F0120A06601203A +:10EF100058071000590710005A071000D4061000B7 +:10EF2000E0061000C406100060071000DE3B012060 +:10EF3000FC06100002F069FA0121794802F065FA36 +:10EF400077480121083002F060FA75480221001D5F +:10EF500002F05BFA63B0CEE6724900200870724995 +:10EF600008707249087072490870A821714809F048 +:10EF700061BEF1E76A4900201C396F4A0862886166 +:10EF8000C86110606D4A1060664A1070664A107061 +:10EF9000664A1070664A107048707047604910B534 +:10EFA0001C39002048706348A821A83809F042FEA7 +:10EFB000BDE81040A8215F4809F03CBE2DE9F74F9D +:10EFC00057480D461C3841780F2901D2491C417021 +:10EFD00001F0FF095A4982F8439001EB8900296842 +:10EFE0000160A978574809F037FF8246A87819E0F0 +:10EFF00000982C7800EBC80B0DE0DBE90067224697 +:10F000000120002109F02BFD06400F403E4301D0B6 +:10F010000AF80490641C6878A042EEDA0AF1280A23 +:10F0200008F10100E97880464145E1DABDE8FE8F4C +:10F030002DE9FF5F8B46144691780E9D09F0FEFE88 +:10F040000646A178686809F0FFFE07464FF0000900 +:10F05000FFF79DFB002832D03B49B5F93200B1F9EA +:10F06000001088422BDC3948A178E37890F800A0A2 +:10F0700019E0207862780FE016F80080D84509D1B1 +:10F0800037F91080DDF80CC0E04503DD09F1010C13 +:10F090001FFA8CF9401CC0B28242EDD2491C07EB2A +:10F0A0004A07C9B228368B42E3D229464846FFF7C1 +:10F0B00081FB002803D0A88C40F40070A884BDE830 +:10F0C000FF9F2DE9F0418046012083F842001C4655 +:10F0D00016460F46404600F081FC1D4D286890F80A +:10F0E0004003410704D52146304600F05BFE05E0B1 +:10F0F000000703D52146304600F043FE286823462A +:10F10000324690F840033946C006404603D5BDE874 +:10F11000F04101F081BDBDE8F041FFF739B90000D1 +:10F12000C806100058071000590710005A071000B1 +:10F13000A8061000B04C1000D4061000E006100025 +:10F14000763F0120DE3B012000071000520710002F +:10F15000B8071000017859B1954A1278521E9142B1 +:10F1600006D0407820B193490978491E884201D1E0 +:10F170000120704700207047017829B18C494278FE +:10F180000978491E8A4209D1817829B1C178894814 +:10F190000078401E814201D1012070470020704755 +:10F1A000F0B5854D002205EBC2060023C6E9003309 +:10F1B000521CD2B2172AF6D38A782CE000EBC20395 +:10F1C000D3E9007657EA060323D074084FEA3703E1 +:10F1D00017EB070E46EB060C44EA0C04344343EAF3 +:10F1E0000E0305EBC2063B43D6E9007C1F434CEA05 +:10F1F000040CC6E9007CD6E9027C1F434CEA040CEF +:10F20000C6E9027CD6E9047C1F434CEA040CC6E93B +:10F21000047C521CD2B2CB789342CFD20022654BF1 +:10F220000AE000BF05EBC20400EBC207D4E90264A8 +:10F23000C7E90064521CD2B21C78A242F2D308780B +:10F2400008B1401E08705A4A48781278521E9042FF +:10F2500001DA401C4870887808B1401E88701A781E +:10F26000C878521E904201DA401CC870F0BD2DE9EA +:10F27000FF5F9478164604EB84028B4600EBC200D5 +:10F28000002100F1290820E00020814682463578DF +:10F2900077780FE018F805205A4509D12A46012051 +:10F2A000002109F0DCFB41EA0A0A40EA09090121D0 +:10F2B0006D1CEDB2AF42EDD2039B08F1280803EBC1 +:10F2C000C403641CC3E9009AE4B2F078A042DBD224 +:10F2D00004B00846BDE8F09F0A7843789A420BD8FC +:10F2E0004A7803789A4207D38A78C3789A4203D837 +:10F2F000C9788078814201D2002070470120704790 +:10F3000070B50C788B784D78C9789AB10CB1641EC1 +:10F31000E4B2274A1278521E954201DA6D1CEDB212 +:10F320000BB15B1EDBB2234A1278521E914201DA06 +:10F33000491CC9B203EB830200EBC202002629324A +:10F3400009E0204602E01654401CC0B2A842FAD997 +:10F350005B1CDBB228328B42F3D970BD2DE9F04340 +:10F360009C7893F803C004EB840500EBC5051048B6 +:10F3700090F8009004FB09F001EB400600202935CD +:10F3800012E019785F7808E015F80180904502D105 +:10F3900036F911804044491CC9B28F42F4D2641C32 +:10F3A00006EB4906E4B22835A445EAD2BDE8F0836D +:10F3B0005207100051071000584D10002DE9F0477A +:10F3C00080464A488C780D460078801E012C05D96D +:10F3D000E978814202DA0020BDE8F087022C01D2F0 +:10F3E000022701E0EF78C4B24FF000092146D8F8B7 +:10F3F000080009F029FD06462146D8F8040009F066 +:10F4000023FD01463A48027815E028786B780AE037 +:10F4100036F910C031F91080C44502D04FF001090F +:10F4200003E0401CC0B28342F2D2641C06EB4206E9 +:10F4300001EB4201E4B2BC42E7D94846CCE72DE9F2 +:10F44000F04780462A480C464E780178891E8E4245 +:10F4500001DA0020C0E78146CFB24FF0000AA17860 +:10F46000D8F8080009F0F0FC0546A178D8F80400A7 +:10F4700009F0EAFCA178E37899F8002013E03C4613 +:10F480000AE000BF35F914C030F91480C44502D039 +:10F490004FF0010A02E0641CB442F3D905EB4205C7 +:10F4A00000EB4200491C8B42E9D2504694E70F4AD8 +:10F4B00000211278521ED3B290F841200AB19A422C +:10F4C00004D1818C41F0020181840121084A90F825 +:10F4D00040301278521ED2B2934204D1818C41F056 +:10F4E0000401818401210846704700005107100083 +:10F4F0005207100030B5B0B1884214D002D20A468B +:10F5000001461046CB4A536803EB40031C788C42FB +:10F5100009D05C788C4206D095682A5C022A02D217 +:10F52000541C2C549954084630BDF0B503EB8204AA +:10F53000A57805EB850600EBC606E0782836A842DC +:10F540000FD3207807E0371897F801C0944500D111 +:10F550007970401CC0B267788742F4D26D1CEDB25E +:10F56000EBE703EB81002568056003EB420003EB4A +:10F57000410130F8B42FA1F8B420AF4909682160E7 +:10F580000021018093F80E01401E83F80E01F0BDAA +:10F590002DE9FF4F8846084609788FB0FF2913D020 +:10F5A0008A46A649427809788A4200D2511CCEB2D6 +:10F5B000A34990F80290C0780978884201D2401C93 +:10F5C00000E00846C7B204E04FF0000A5646D146B4 +:10F5D000574611984FF0000B08B198F80EB1954CB2 +:10F5E000206800F15A01C4E901015A2109F000FB29 +:10F5F000D4E901122C2000BF01F81000002313549D +:10F60000401EC0B2F8D20BF101000D90C0B20690BE +:10F610000F9809EB890100EBC10509F101000A957A +:10F6200039E000BF0AF101000995C4B228352EE087 +:10F6300029190868E0B1285D38B311F8011C0020D1 +:10F6400001B108460999095D09B1FFF753FF129905 +:10F6500061B1099921440E9111F8011C09B1FFF71C +:10F6600049FF0E99497809B1FFF744FF18B10BE043 +:10F67000E41CE4B209E006982D2803D2411CC9B26B +:10F68000069101E0401EC0B22855641CE4B2B442A9 +:10F69000CED90798401CC0B20790B842C2D906988C +:10F6A00000F06FF806900D980022C0B2624B09E09E +:10F6B00008EB80011C680C6008EB4001401CA1F8BD +:10F6C000B420C0B206998842F2D30A984D46283039 +:10F6D000009039E0544630E0204401210958E9B354 +:10F6E000417841B3534A526812F81110417008EB47 +:10F6F000410008EB810930F8B42F521C028099F8C0 +:10F700000010204603F0EAFF89F8000099F8011084 +:10F71000204603F0E7FF89F8010099F80210284617 +:10F7200003F0DCFF89F8020099F80310284603F083 +:10F73000D9FF89F80300641CE4B20098B442CBD32B +:10F7400028306D1CEDB20090BD42C3D30698401E18 +:10F75000C2B288F80E211198002800E00BE00DD00D +:10F76000A2EB0B00012809D111990F9813B0434661 +:10F77000BDE8F04FD9E6E41CE4B2DCE713B0BDE825 +:10F78000F08F2DE9F05F07460025DFF8A8B02CE0E8 +:10F79000DBF808104E5DDBF8041001EB450A1AE0B7 +:10F7A0000AEB0600804610F8011C10F8029C08467F +:10F7B00000F035F80446484600F031F8844202D2A1 +:10F7C000014620460C46DBF80410761EF6B201F81E +:10F7D000104008F8024C012EE2D804D1284600F06F +:10F7E0001EF88AF800006D1CEDB2BD42D0D3002196 +:10F7F0000846DBF804400DE004EB40021378834236 +:10F8000003D11170491CC9B202E014F8133013700F +:10F81000401CC0B2B842EFD30846BDE8F09F054A8D +:10F82000D2E9011202E000BF11F81000135C002BB6 +:10F83000FAD17047D4061000DA9601005207100082 +:10F8400051071000F0B5B2F900400668B44202DD7D +:10F85000B3F9001030E002EB410434F9025CB54228 +:10F8600004DA03EB410131F9021C25E000252C46A6 +:10F870004F1E0CE032F914C0B44507DC02EB440C17 +:10F88000BCF902C0B44501DB25460C46641CBC42F1 +:10F89000F0DB32F9154003EB450133F91530B1F9CE +:10F8A000021002EB4502361BC91AB2F9022071435D +:10F8B000121B91FBF2F119440160F0BD2DE9F041FA +:10F8C00005463748036893F80705C40603F20F504E +:10F8D00021D5B3F8AA696C68B4421CDBB3F8AC69F3 +:10F8E000B44218DCB3F8AE692C68B44213DBB3F849 +:10F8F000B069B4420FDC074693F8B40993F8B21923 +:10F9000093F8B52907EB400093F8B34900EB4106A3 +:10F9100007EB420E10E039B302292CD0032935D071 +:10F9200004293AD193F8081593F8094593F80E3550 +:10F9300000EB410600EB430E0A4422440EEB410764 +:10F94000A02A2ADC012906DD05F1040C03467246D3 +:10F950006046FFF777FF012C1FDD284633463A4605 +:10F960002146BDE8F0416DE793F8081593F8094585 +:10F9700093F80A2505E093F8081593F8094593F8DC +:10F980000C2500EB410600EB420ED5E793F8081575 +:10F9900093F8094593F80D25F3E7BDE8F0810000E1 +:10F9A000B807100030B542780378CD8CD21AC378EE +:10F9B0008078521C1B1A5B1C05FB02F0D4185D43B7 +:10F9C00040006A00B0FBF4F0B2FBF4F2904202D9BE +:10F9D000C8850A8630BDCA85088630BD2DE9FF4F2F +:10F9E000002783B01546019700973E463C46BB462C +:10F9F000917809F023FA8246AB7895F8039028E0D5 +:10FA0000297895F801C08E461DE000BF1AF8012044 +:10FA10000498824215D1A1EB0E02521CDDF8008041 +:10FA2000A9EB030002FB0288401CCDF80080DDF842 +:10FA30000480164402FB008200FB00BB04447F1CD0 +:10FA40000192491CC9B28C45E0D25B1C0AF1280A1C +:10FA5000DBB29945D4D24FF47A70704390FBF7F142 +:10FA60004FF47A70604390FBF7F34FF47A7201FB26 +:10FA700004F0714390FBF2F791FBF2F6634393FBC2 +:10FA8000F2F301980099C01B891BABEB0302069CA3 +:10FA90008B1A00D55B42002800DA404203EB40009D +:10FAA00011440A18081A521040104FF47A71484352 +:10FAB00090FBF2F0C0F57A70A085069907B0284651 +:10FAC000BDE8F04F6EE700002DE9FF5F0025DDF88F +:10FAD00038808B46994614462E462F46414600985C +:10FAE00009F0B2F930F91900A04232DDA8F10100A5 +:10FAF00044B208F1010828E0002C22DBB24800786B +:10FB000084421EDAE1B2009809F09EF9AF498246BC +:10FB1000A9F101000A7840B209F101010EE00028C4 +:10FB200008DB904206DA3BF915303AF910C01F4461 +:10FB30000CFB03666D1C401CEDB240B28842EEDD4A +:10FB400001E0ED1CEDB2641C64B24445D4DD0FB19C +:10FB500001E00646012796FBF7F004B000B2BDE8CD +:10FB6000F09F2DE9FF4F83B091461099087800B1BE +:10FB7000401EC4B2887800B1401EDFF850A2C5B262 +:10FB80004A789AF80000431E9A4201DA501C00E0BD +:10FB9000401EDFF834B2C6B2C9789BF80000421E9E +:10FBA000914201DA481C00E0401EC7B2CCB9A84619 +:10FBB00012E00146039809F055F9CDE9008023468B +:10FBC0004946069A0498FFF77FFF019921F814002F +:10FBD00008F1010000F0FF084046B845E9D9641C6F +:10FBE000E4B27A480078401E864219D1A84612E055 +:10FBF0000146039809F036F982463346CDF8008075 +:10FC00004946069A0498FFF75FFF2AF8160008F1A4 +:10FC1000010000F0FF084046B845E9D9761EF6B26B +:10FC2000C5B92946039809F01DF98246A0460CE0A3 +:10FC3000034600954946069A0498FFF745FF2AF8BF +:10FC4000180008F1010000F0FF084046B045EFD968 +:10FC50006D1CEDB29BF80000401E874218D139465A +:10FC6000039809F0FFF88246A0460CE0034600978F +:10FC70004946069A0498FFF727FF2AF8180008F16A +:10FC8000010000F0FF084046B045EFD97F1EFFB2EB +:10FC9000B9F912005FEA000A65D14FF0010A62E08B +:10FCA0002946039809F0DEF80190681EC1B2049855 +:10FCB00009F0CAF800902946049809F0C5F82146D1 +:10FCC0004DE000BF30F91120069B9A4242DD009AB8 +:10FCD000B9F9008002EB4102002332F902CD0CFB9E +:10FCE0000833B2F902C0B9F902800CFB0833B2F94B +:10FCF00004C0B9F904800CFB083B344BB9F9068009 +:10FD000093F800E002EB4E02B2F900C00CFB08B31E +:10FD1000B2F902C0B9F908800CFB0833B2F904C08B +:10FD2000B9F90A8002EB4E020CFB083BB2F900C0A5 +:10FD3000B9F90C800CFB08B3B2F902C0B9F90E8016 +:10FD40000CFB0833B2F904C0B9F910200CFB0232E5 +:10FD500092FBFAF2019B23F81120491CC9B2B1426F +:10FD6000B0D96D1CEDB2BD429AD907B0BDE8F08F95 +:10FD70001CB5174C2468019401AC0094FFF7F1FE08 +:10FD80001CBD38B5164D009012480C46124A00684A +:10FD9000B0F9E232114801682868FFF7E2FE2868EE +:10FDA000A06038BD38B50E4D00900A480C460A4A8E +:10FDB0000068143AB0F9E232084801682868FFF791 +:10FDC000D0FE2868606038BD51071000520710004F +:10FDD000FC061000B8071000C6960100700710005E +:10FDE000CC0610002DE9FF5F8946144691780F9DDF +:10FDF00009F024F88246A178A86809F025F847F6AA +:10FE0000FF76A778F543FE4994F8038091F800B097 +:10FE100018E0227894F801C00DE000BF1AF8021033 +:10FE2000494507D130F91230B34200DA1E46AB42E1 +:10FE300000DD1D46521C9445F0D20AF1280A00EB61 +:10FE40004B007F1CB845E4D2039806800E980580CD +:10FE5000BDE8FF9F2DE9FF4FEA4885B09A46046848 +:10FE600003A9CDE9001ADDE90501154604F58879F5 +:10FE700002ABFFF7B7FFE448BDF90C20DFF88CB305 +:10FE800000685F4690F8E412BDF90800121A4A4370 +:10FE9000642192FBF1F10E1801222946DBF80000E3 +:10FEA000FFF72EFAD7F80080DDE9050731B201919E +:10FEB000A97808F0C3FF0646A978404608F0CCFFB1 +:10FEC0000090A978DAF8080008F0BEFF0146AA7889 +:10FED0000123DFF82CE31DE028780EE016F800C0BF +:10FEE000BC4509D131F91080DDF804C0E04503DDDF +:10FEF000DDF800C00CF80030401C95F801C08445C6 +:10FF0000ECD20098521C283000909EF80000283651 +:10FF100001EB4001E8789042DED2002084F80E0127 +:10FF2000286820600123002221465E46DBF800009D +:10FF3000FFF72EFB94F80E01012826D901251DE0BC +:10FF400048225146484608F019FE04EB450004EBF0 +:10FF50008507B0F8B410A9F8261049463846FFF7CF +:10FF600021FD3A46E9B24B463068FEF7BBFA3A4605 +:10FF7000E9B24B463068FEF70BFA6D1C94F80E019F +:10FF8000A842DDD209B0BDE8F08FDDE90501534696 +:10FF90002A46FEF7FDF9F5E72DE9FE4F06469A4899 +:10FFA0001D460B4600689A490E9CB0F9E692897985 +:10FFB000934609B1B0F962939649097809B1B0F94D +:10FFC000F49218460C9908F039FF824630460C9995 +:10FFD00008F042FF0190A0680C9908F035FF2C78DA +:10FFE0006D78804664B99AF80010594507D1B8F980 +:10FFF00000100D98814202DD019901200870012452 +:020000021000EC +:100000007F480078401E854255D11AF805105945A1 +:1000100007D138F915100D98814202DD01990120B0 +:1000200048556D1EEDB246E01AF80410594541D10D +:1000300038F914100D98029181423BDD00200090A8 +:1000400075490C98224601EBC0000021D0E90067F9 +:10005000012008F004FD06400F403E4327D10298DE +:1000600008EB4402484432F9021C00B2814205DD2B +:10007000B2F90230834201DD01230093012C09D93A +:1000800032F9043C834205DDB2F90230834201DDDE +:10009000012300935A4B1B789B1E9C4205D2814240 +:1000A00003DDB2F90410814204DC009810B9019913 +:1000B00001200855641CAC42B6D9BDE8FE8F2DE97D +:1000C000FF4F54489BB0DFF8489101784E48289E76 +:1000D0001D46006839B190F8F342B0F9F41211915D +:1000E000B0F9F60211E099F8061039B190F86843BA +:1000F000B0F962131191B0F9640306E090F8E5429B +:10010000B0F9E6121191B0F9E802444F0C90ACB18D +:1001100004A8CDE90006DDE91C0102AB2A46FFF781 +:1001200061FEBDF91000BDF90810401A604364215A +:1001300090FBF1F03988084400B201E0B7F9000003 +:10014000AC7895F8038082464CB9CDE9004A1BAFE4 +:10015000029697E807002B46FFF71EFF012430495F +:100160000978491E88450DD1CDF80080CDE901A65A +:100170001BAF2B4697E80700FFF70EFFA8F1010021 +:1001800000F0FF08601EC1B2B06808F05DFE834653 +:10019000012C06D9A01EC1B2B06808F055FE0D9022 +:1001A00001E0CDF834B02146B06808F04DFE05906E +:1001B000601CC1B2B06808F047FE0190A01CC1B23B +:1001C000B06808F041FE069021461C9808F036FE03 +:1001D0000A9021461B9808F03FFE0B9000201490D7 +:1001E000012013900020129099F8040058B306489B +:1001F000006890F84014090725D569782A7811E03D +:1002000052071000E0061000B8071000C8061000E2 +:10021000800710002C051000B04C100006071000DD +:10022000510710008A1A90F84B14521C8A420ADCBB +:10023000EB78AA789A1A521C8A4204DCB0F8490476 +:10024000B169814201DD00201390A146DBE02C78EA +:10025000BBE00A98015D1D98814266D10020109094 +:10026000FB491690159001EBC9002246D0E90067C2 +:100270000120002108F0F3FB06400F403E437CD1F3 +:1002800005980C9A30F814101198084411443BF961 +:10029000142000B209B2824207DD019B33F9143009 +:1002A000834202DD012310931593ECB3E94B93F8DD +:1002B00000E0AEF101039C4265D0059B03EB440CCA +:1002C0003CF9026C864206DDBCF90230834202DD55 +:1002D0000123109316930BEB440333F9027C8F42F6 +:1002E00008DD019F07EB4407B7F902708F4201DD7B +:1002F00001271097B3F902308B4206DD019B03EB17 +:10030000440333F9023C8B4248DC1099B1BBB9F18C +:10031000010F0FD90D9931F9141081420ADD0199AD +:1003200031F91410814201E02DE04DE002DD0121A0 +:1003300010911591C84B1B789B1E994509D282429A +:1003400007DD069931F91410814202DD0121109177 +:100350001591012C0AD93CF9041C814206DDBCF937 +:100360000210814202DD012110911691AEF10201CD +:100370008C4208D2864206DD01E006E00EE0BCF9C0 +:10038000041081420CDC109840B9059830F9141023 +:10039000514503DD0B990120085515E0169898B1D9 +:1003A000159888B1139878B10B99012008551298C7 +:1003B000401C80B21290A948006890F84C14129822 +:1003C000814201D201201490641C6878A042BFF4DD +:1003D00040AFA048CDF834B00599007809F1010983 +:1003E00001EB4001059101990BEB400B01EB400142 +:1003F0000191069901EB400006900A9828300A9076 +:100400000B9828300B90C1457FF621AF14981FB090 +:10041000B9E52DE9F047044691425AD007D901EBDE +:100420000200A0EB0201CAB2A0EB0200C1B201EBD4 +:10043000C10004EBC00102EBC20004EBC000B1F943 +:100440003250B0F9323081469D4200DA4B86CB8C77 +:10045000C58C2B44CB840B8D058D2B440B854B8D8C +:10046000458D2B444B858B6985692B448B61C7690E +:10047000CE69CB68D9F80C004FEA234C4FEA2048EC +:100480000CFB06FCF51907FB08CC9CFBF5FC6CF398 +:100490001F430FFA83FC0CFB06FC00B207FB00C0F5 +:1004A00090FBF5F060F30F03CD61CB6094F8380456 +:1004B000411E914208D000EBC00004EBC001484649 +:1004C0004822483908F05AFB94F83804401E84F852 +:1004D0003804BDE8F0872DE9FE4F07465F488A469D +:1004E00000250068B0F8EA1201FB01F95C4989793E +:1004F00019B1B0F8660300FB00F954464FF0010B48 +:100500009FE000BF0BFA04F02646009068E0009AD6 +:100510000BFA06F05946104261D006EBC60007EB15 +:10052000C000C26820464DE0B0424AD000EBC00394 +:1005300007EBC303DB684FEA2348A8EB224C9B1A66 +:100540000FFA8CFC1BB26CF31F4563F30F059E463C +:10055000424BCDF804C01B6893F8E0C2CDF808C048 +:100560005FEA8C6C0BD593F8ED820EFB08FC4FF024 +:1005700064089CFBF8F808EB0E0C6CF30F05DDF833 +:1005800008C05FEACC6C0CD593F8ED32DDF804C0FE +:100590000CFB03FC64239CFBF3FC019B634463F3AF +:1005A0001F454FEA254C0CFB0CFC2BB203FB03C38D +:1005B0004B4506D2DDF800C001FA00F343EA0C0314 +:1005C0000093401C97F838348342ADD80421684624 +:1005D00006F0E2FF012802D1009840000090761C4E +:1005E00097F83804B04292D80421684606F0D4FF48 +:1005F00001280BD00421684606F0CEFF97F8386436 +:10060000A6EB0A01884205D187F838A455E5641C99 +:10061000E4B201E0009A584600FA04F11142F6D023 +:10062000D84609E0009908FA06F0084204D0F2B270 +:1006300021463846FFF7EDFE761EA642F2D8641C2E +:10064000E4B297F83804A0423FF65CAF35E500000D +:10065000B04C10005207100051071000B8071000EE +:10066000800710002DE9F04FFE4C012B246894F810 +:10067000F97294F8F86205D00B784C78FA4D9C46E4 +:10068000690C0DE08B78CC78F8E700BF30F91C805E +:10069000A84500DD4546884500DA41460CF1010CCD +:1006A000A445F3D9B54200DA3546B14200DA314605 +:1006B000691A7943642591FBF5F131440EB230F9A2 +:1006C00013500121B54205DD156801FA03FC45EA26 +:1006D0000C05156030F91450B54205DD156801FAB6 +:1006E00004FC45EA0C051560E51A05F0FF09B9F1AF +:1006F000010F37D95D1CEDB230F9158008EB070CFE +:100700000FFA8CFCB04511DD00EB450A3AF9028C7A +:10071000E04503DDBAF90280E04507DCD2F800C00D +:1007200001FA05F54CEA050CC2F800C0651EEDB2F1 +:1007300030F9158008EB070C0FFA8CFCB04511DD81 +:1007400000EB450A3AF9028CE04503DDBAF9028074 +:10075000E04507DCD2F800C001FA05F54CEA050CCB +:10076000C2F800C0B9F1020F2ED99D1CA4F10209F4 +:1007700028E000BF30F915C0B44522DD00EB450B81 +:10078000BC443BF902EC0FFA8CFAD64503DDBBF909 +:100790000280D04515DC3BF9048CD04503DDBBF964 +:1007A0000280D0450DDCD64503DDBBF90480D04581 +:1007B00007DCD2F800C001FA05F84CEA080CC2F8D0 +:1007C00000C06D1C4D45D5D9002528460CE000BF62 +:1007D000166801FA03F73E4204D025B90125401CF2 +:1007E000C0B200E000255B1CA342F1D9BDE8F08F48 +:1007F0002DE9FF4F9D488FB0DFF8749204681746CB +:1008000004F5887002904FF0FF300C9000200A90A1 +:100810000B901D46012239464E46D9F80000FEF7DE +:100820006FFD0095DDE90F123B463068FFF747FC8E +:10083000060006D08F4901200870A88C40F0800087 +:10084000A8848D48007880B17EB995F8240010F016 +:10085000060F0AD139462846FEF7B0FD060004D13E +:1008600039462846FEF7EBFD06468448007800B17D +:1008700001267C48006890F8E10240073CD501233E +:100880000AAA39467E48FFF7EDFE804600230BAAF0 +:1008900039467C48FFF7E6FE08FB00F001282BD123 +:1008A0007048B5F932100068B0F8DE02814223DAF0 +:1008B000B8781DE008F0FF010F9808F0CDFA8346E4 +:1008C00008F0FF01D9F8000008F0C6FA01463878B0 +:1008D000012308E01BF800C0109A944502D10A5C7D +:1008E00002B90B54401C7A788242F3DA08F1010015 +:1008F0008046F8784045DDDA002084F80E0138683B +:1009000020605B483346002221460068FEF740FE27 +:1009100094F80E014FF0000801287DD9FCF7AFF9DB +:100920008346FCF7AAF982463A68DDE90F0107928F +:10093000554B07AAFEF79BFC60B107A95248FEF78A +:100940002FFC2A4607A95048FDF768F9E968696154 +:10095000E969296249480078E8B34248006890F89C +:10096000E102800744D594F80E01012840D94FF0E8 +:10097000000901260FE000BF3D4804EB8603F2B2F8 +:10098000A9680068FEF7EAFC4049484541F826009E +:1009900000DD8146761C94F80E11B142ECD2B9F11B +:1009A000000F1EDD2F4A0120384B8646126816E0E4 +:1009B00053F820604FF0640C06FB0CF696FBF9F63A +:1009C00092F8F2C2B44509DDDDF830C00EFA00F647 +:1009D0002CEA060C00E00BE0CDF830C0401C814250 +:1009E000E6D294F80E01012802D9002084F80E0105 +:1009F0000126DFF8709052E048222946029808F05C +:100A0000BDF8D9F8001004EB4600B0F8B42091F816 +:100A1000EC128A4242D900E077E001210C9AB14001 +:100A200011423BD00299898C41F0100202998A84CC +:100A3000B0F8B410029804EB8602C1841046089204 +:100A40000299FEF7AFFF0A48F1B2029B089A0068CC +:100A5000FDF748FD0648F1B2029B089A0068FDF7D1 +:100A600097FC15E0B80710000080FFFFE0061000BB +:100A7000C8061000A8061000180710002C0510006A +:100A8000F81A0120221B0120084C1000104E100003 +:100A9000012803D108F1010000F0FF08761C94F84A +:100AA0000E01B042A8D2D9F800004C4690F8E002FE +:100AB00000070CD5B8F1010F09D959465046FFF788 +:100AC0000AFDFCF7DCF8A0EB0B0000F0FF08216842 +:100AD00091F8E002000612D540460EE00BEB000252 +:100AE000D2B202EBC2030AEBC30291F80733D28CF5 +:100AF0009A4202D98AF838B407E0401EEED2B8F123 +:100B0000010F0AD0B8F1000F05D1DDE90F012B4626 +:100B10003A46FDF73DFC13B068E6524800780028DD +:100B2000F9D19AF8380400B1401E8AF83804ECE78D +:100B30002DE9FF4F4C4881B0006890F8E102C007F2 +:100B400068D0A821049808F075F8012545E00398BD +:100B500000EB85008246847890F803904348007843 +:100B6000401E844201DA641CE4B2B9F1000F03D0E4 +:100B7000A9F1010000F0FF092146019808F05EF993 +:100B80008346A04625E00398049910F8254001EB20 +:100B9000C800009013E000BF1BF80400A8420CD16D +:100BA000009822460021D0E90067012007F057FF96 +:100BB000064300980F43C0E90067641CE4B29AF84A +:100BC0000100A042E8D208F101000BF1280B00F06F +:100BD000FF08C845D7D96D1CEDB202988542B6D939 +:100BE0000021224E13E0049800EBC10501F1010140 +:100BF000D5E90032DC1842EB020052084FEA330319 +:100C000004EA030400EA0200C5E90040C9B23078F2 +:100C10008142E8D305B0E9E5F0B41468DC63124C16 +:100C2000256895F8E042A60713D493F84260012E98 +:100C30000FD0660713D5640609D50D4C64785CB1F6 +:100C4000B5F8F0420B4D64432D68A54207DCF0BCBB +:100C5000CEE5F0BCFFF7FEB8B5F8EE42F2E7F0BC27 +:100C6000FDF796BB2C051000B807100051071000C7 +:100C7000E8071000880710007047F0B51446059F7C +:100C80000BE000BF31F9145030F9146005EB030C90 +:100C9000B44519DBED1BB54216DC641EF2D1494B9D +:100CA0001B6893F845301B09C3F110040AE000BF2C +:100CB00031F9125030F912605D4306FB04552D11D5 +:100CC00021F81250521EF3D2F0BDF8B50E4605467B +:100CD00000F091FF002839D13B4CF00703D0286881 +:100CE000216800F034F8F00630D5364E3068B0F99F +:100CF000501000913549B0F94E3028690A783449CE +:100D0000FFF7BBFF3068B0F9541000913149B0F9DA +:100D1000523068690A783049FFF7AFFF2F48304AF0 +:100D2000007808B1012010E0118859B92D482E4DE6 +:100D30002368B0F9000003E033F8104025F81040B4 +:100D4000401EF9D2491CC1F308001080F8BD2DE9FE +:100D5000F0438146254803781A48052B006890F82F +:100D600044200CD030F9465F02F00F03B0F9026066 +:100D70001C48C3F11004B0F90000024611E030F93C +:100D80004A5F1309B0F90260F2E700BF31F912704F +:100D900039F912C007EB0508E04511DBBF1B6745B9 +:100DA0000EDC521EF2D209E031F9102039F9105050 +:100DB0005A4305FB0422121121F81020401EF3D2E1 +:100DC000BDE8F083B80710007C0710005107100041 +:100DD0004C6D012052071000766D01202005100097 +:100DE0000405100060071000440D0120500710009A +:100DF0002DE9FC4781469A489A4E8846017830682A +:100E0000012511B99849097811B1B0F9A1420DE055 +:100E10009649B0F99B424978012902D0022903D0B2 +:100E200004E0B0F99D4201E0B0F99F42022101A81F +:100E300000F088FA8E4F42464946B7F900300198D3 +:100E400003F06BFC316891F8AA02020705D4C006D2 +:100E500003D491F8AB02C00708D0B7F9000001999C +:100E600000908023834A084603F064FCB7F9001021 +:100E7000019A0CE032F91100002801DB034600E082 +:100E80004342A34203DD7C490025088001E0491E5E +:100E9000F0D2022101A800F0B8FA2846BDE8FC878C +:100EA0007048006890F89002400707D56F48734972 +:100EB000C0780978884201D001207047002070472F +:100EC000684810B5006890F89012890727D56C49DA +:100ED0000A78521CD2B20A7090F8923293421ED213 +:100EE00000220A7090F850120324C90703D190F829 +:100EF0008002C00700D00B24EFF780FA6148016838 +:100F000021430160EFF778FA1021052002F052F832 +:100F1000BDE810404FF48071002005F04EBD10BDBB +:100F20004F49514A514809781278437811430B438D +:100F300053494FF0000208D14B785B1CDBB24B7079 +:100F4000052B03D90123437083704A7070472DE944 +:100F5000F34F4D480027DFF818A190F80080414872 +:100F600081B03C460068B94690F89002C0071AD09C +:100F700000264FF0010B019D12E028460299FFF771 +:100F800037FF10F0010F05D00BFA06F03843641C50 +:100F9000C7B2E4B2BAF90000761C05EB400536B2E0 +:100FA0004645EADB01E04446FF27384807704CB16C +:100FB0000094BAF800003B4682B24146019800F026 +:100FC00012F807E02C48B0F90010032001F0F2FFFE +:100FD0004FF001094846BDE8FE8F704728480021C0 +:100FE0000170417070472DE9F003069F002F19D062 +:100FF0000125012F02D01446A9462EE000240FE05F +:1010000005FA04F61E420AD0002C0BD053006243AE +:10101000BDE8F00300EB42011A4607F06ABD641C0C +:101020008C42EDDBBDE8F003704700BF002600EB0B +:10103000440C35460BE000BF09FA05F818EA030F27 +:1010400002D0BCF9008046440CEB420C6D1C8D4272 +:10105000F2DB96FBF7F520F81450641EE6D2E1E7C8 +:1010600020051000B80710002C051000E80710003C +:1010700060071000EA210120EE061000530710005F +:10108000E4061000C007100054071000E906100025 +:1010900010B5F3F759FFF4F7B2FBBDE81040F3F7D2 +:1010A0002FBB2DE9F04781461F4690460E46032090 +:1010B000089D05F022FD734801684846FFF747FF89 +:1010C0000446032005F034FD64B1FFF729FFFFF764 +:1010D000F7FE31464846FFF780FF6B480470204614 +:1010E000BDE8F087FFF77AFF16B1304600F0D2FB7B +:1010F0005DB1664801782846F3F74DFF6448807873 +:1011000018B1644900200870487007F041FE054698 +:10111000FFF7C6FE50EA0504DBD13A464146484691 +:1011200000F03EF80446D4E710B5044600F089F814 +:1011300000212046FFF751FF002010BD10B5F5F744 +:101140005FFAFDF717FFFBF701FCFFF7A1FFFFF7C1 +:1011500045FFFCF795FB4C490020087048708880DB +:10116000C88088708860C860086114310870887011 +:101170004948006810F8302F4A704078C87010BD98 +:1011800010B5F5F74CFAFDF709FFFBF7DDFB00F0B2 +:10119000F6FBF4F741FB3E4800214170817010BD21 +:1011A0002DE9F8430024804616460F4625468DF863 +:1011B0000040022005F0A1FC324639464046F5F7D2 +:1011C00072F836490128CA7860F30302CA7029D040 +:1011D000022831D0042800D001246B46324639461B +:1011E0004046FCF78BFA40EA0405022005F0A0FC1B +:1011F0009DF8000098B1EFF701F92948294A0168E4 +:10120000126811430160EFF7F7F8274801780520CD +:1012100001F0D0FE4FF48071002005F0CEFB28468F +:10122000BDE8F88321480178012900D10570FDF758 +:1012300093FEFBF7ACFBD0E7FDF759FBFBF7D2FBC6 +:10124000CBE770B505460024022005F056FC284681 +:10125000F5F775F911490128CA7860F30302CA70DD +:1012600002D0022805D008E0FDF783FEFBF75FFC03 +:1012700003E0FDF742FDFBF76BFC022005F058FC94 +:10128000204670BD7C071000E8061000EC07100037 +:10129000E807100080071000B8071000A0660120C2 +:1012A000C0071000A00610009C061000FA071000EE +:1012B000062904D28B4A515C8B4A535C2BB1002126 +:1012C00001600146482001F044BB864B083353F8C7 +:1012D00021300360854B43F82100012050547047B2 +:1012E0000A4630B40021062A11D27E4B9A5C72B1B4 +:1012F0007C4C0368083454F82240A34207D17A4B4F +:1013000099547A4B43F82210016030BC7047016059 +:10131000014630BC492001F01CBB2DE9F0410124FD +:10132000714D724F0026285D38B12E5557F82410A4 +:101330004A2001F00EFB47F82460641C032CF2DB0A +:10134000BDE8F0812DE9F041684D674B00270A4662 +:101350000C350760596805F1140603F10804012AE9 +:1013600038D0022A1CD0032A3FD1002204EB020C01 +:10137000DCF800E0BEF1000F07D0521C022AF5DBBA +:10138000042930D301464C2031E055F82240046056 +:1013900046F822004FF00330091FCCF8000032E07D +:1013A0005FF0000204EB020CBCF800E0BEF1000F9D +:1013B00005D0521C042AF5DB0229E3D213E055F8CC +:1013C0002240046046F8220040F20220ACF80000FF +:1013D000891E18E05FF0040214F802C0BCF1000F8F +:1013E00009D0521EF8D2002FAAD101464B20BDE8E9 +:1013F000F04101F0AEBA55F82250056046F82200DF +:101400000120A054491E59609AE7F0B4374E364C7B +:10141000002504220C36D0F80030083456F822702B +:101420009F4212D1A75C8F420FD1531C11D02F4D78 +:1014300000232035036045F82230A354012911D040 +:10144000022911D0032904D108E0521EE6D2002D52 +:1014500008D1F0BC01464D2001F07BBAA0184370C2 +:101460008370C370F0BC7047A0184370FAE770B582 +:101470001D4E1E4D0524083620350BE0305D48B169 +:1014800055F824104E2001F064FA315D55F824001F +:10149000FFF7BBFF641EF1D270BD70B50120134B86 +:1014A000114A002143F820101154401C0328F9DB95 +:1014B000012010700C4A05200C4B50600C330A4C74 +:1014C00004200B4A083403F114057326464302EB4B +:1014D000C60643F82060215445F82010401EF4D27F +:1014E00070BD0000E096010024071000F0541000C9 +:1014F000E0671000F0B5A7B00D460646002498211D +:10150000684607F097FBFF4A00216846137810E011 +:1015100001FB03F7224609E007EB020E50F822C058 +:1015200036F91EE0F44440F822C0521C9A42F3DB24 +:10153000491CA942ECDB214607E000BF50F82120FE +:1015400092FBF5F240F82120491C9942F6DB00217C +:1015500017E000273A460CE002FB034C50F824E069 +:1015600036F91CC0BCEB0E0C01D5CCF1000C674465 +:10157000521CAA42F0DB97FBF5F28A4200DD1146CD +:10158000641C9C42E5DBB1F5803F03DB4FF6FF7046 +:1015900027B0F0BD88B2FBE7F0B5DB49DB4B09684B +:1015A00091F8AA22D20734D0D94A57784FB191F88E +:1015B000B542B1F8B25204F00F022609B1F8B042B8 +:1015C00008E091F8B442B1F8AE5204F00F022609D7 +:1015D000B1F8AC42DFF83CC39CF800C0BCF1030F8B +:1015E00006D191F8B6120FB10A0901E001F00F021D +:1015F000A04201DC1A60F0BDA84201DB1E60F0BD14 +:10160000001BB11A4843291B90FBF1F010441860ED +:10161000F0BD0020FBE7BC48BD4900680A7800F532 +:10162000F970805CC87070472DE9F00F8346B648AA +:10163000DFF8DC92DFF8E0A2016899F80070002082 +:1016400091F80A6291F809123AF817406FF00042D7 +:101650004FEA11180B071CD001F00F05AA4B00210F +:101660008C461B68B44293F8083205DBA61B06FBC8 +:1016700008F696FBF5F52B44A34D99F801602D680B +:10168000012E95F8F15106D0022E07D005F0030681 +:1016900013E00125E2E7C5F381060EE0C5F301166C +:1016A0000BE000BF3AF81C50AA4201DD2A46604612 +:1016B000A94200DA29460CF1010CB445F2DDABF881 +:1016C0000010A11A994201DCB74204DD89F800003C +:1016D000BDE8F00F9FE7BDE8F00F70478F4910B5E8 +:1016E0000B7889490022012B096802D18C4B1B78A9 +:1016F0004BB1B1F8FC31834218D291F8F0311B079D +:1017000014D5032225E0B1F80232834203D291F8C6 +:10171000F0311B07F5D4B1F80032834203D291F8BF +:10172000F0315B070AD4B1F8FE310BE0B1F8FA31C1 +:10173000834205D291F8F0315B0701D5022208E01F +:10174000B1F8F831834204D291F8F001800700D556 +:10175000012271486E4C143803789A4211D1617895 +:1017600099421AD06F4A1278134307D08168491EF4 +:101770008160002911DC007860700EE001708168E2 +:10178000F7E78AB1022A01D1012B0DD091F8F611A9 +:1017900081600270002900DC627063486278417BDE +:1017A00062F30301417310BD91F8F711F0E7564A57 +:1017B000126892F8F021D20607D5421A002A04DCFA +:1017C000C1EBC1110844C0F3CF107047504900204D +:1017D0004D4A487050491439486088600870126852 +:1017E00092F8AA32DB0703D092F8B522120900E082 +:1017F0000022464B1A60C8600861486188617047E2 +:101800002DE9F84F0021ADF800103E49DFF80891AE +:10181000DFF804810E784FF0100B370105460024E5 +:10182000A9F10809A8F1140A10E0324659462846E1 +:10183000FFF760FE29F81400434638F81410FFF74C +:10184000B6FF23F8140005EB4705641C9AF8010065 +:101850008442EADD6846FFF7E7FE2B482C4D00681E +:1018600090F8F001400602D5BDF8004002E029786A +:1018700038F811402D4804802046FFF72FFF2046FE +:10188000FFF78AFE297839F811002749A1F81B00D3 +:10189000BDE8F88F2DE9FE4F00210291DFF878B006 +:1018A0001026ABF1140B1749DBF80420044692FB19 +:1018B000F6F30D7806FB13221D486A439BF801706E +:1018C0004FEA051900EB420882467F1C3DE00E48B6 +:1018D000016891F8F00180062ED5DBF8040000289D +:1018E0000FDD0298B1F90622281ACDE90020B1F9DE +:1018F000043202990AEB410204EB4101084602F06E +:1019000093FE17E052071000B807100010071000F0 +:10191000E807100050071000480710005807100093 +:101920005907100057071000A0660120EC061000B0 +:10193000B63F01200AEB490A6A002146404607F0FB +:10194000D8F804EB450408EB49087F1EBFD2DBF84A +:1019500004104FF0FF32491C02EB46025846CBF808 +:1019600004108A4200DA4660DBF80400B04203DB70 +:10197000BDE8FE4F0F4843E7BDE8FE8F26E710B5F0 +:101980000D4C206890F8F101C0F30112C0F3810101 +:1019900000F0030001F09BFE0849487020680849E8 +:1019A00090F8EB0000F003000870FFF734FEBDE88C +:1019B00010400BE7B63F0120B807100034071000B5 +:1019C000E807100070B5E64DE64800242A6892F852 +:1019D0003110417092F83020827051430182E24907 +:1019E000C978C17001210171417181710170448216 +:1019F00044738473FFF7A2FBDC484FF466710470F4 +:101A0000DB480480DB4807F0F3F840F23C642146F1 +:101A1000D94807F0EDF82146D84807F0E9F82868DA +:101A2000D74A90F8881401F001011170D549B0F837 +:101A300076000880BDE87040FFF71EB910B5C948B0 +:101A4000002444610463848680F83640C461846164 +:101A5000FFF796FBFFF721FDCB480480BDE810405F +:101A6000B0E7CA4810B590F82C10C748BD4A81703D +:101A7000D379017963F30001537A63F3C301137AD5 +:101A800063F38201937A63F34101B74BDB7803720E +:101A9000137BC371D37A547B63F30411837B927BF2 +:101AA00064F3030362F30713B94A8373127880F86F +:101AB0002820B84A1288A0F82920B74A137890F84D +:101AC000512063F3410280F85120B44A127862F346 +:101AD000C7110171B2490988A0F82B10B1490988D2 +:101AE000A0F82D10B0490A78C17B62F30301C173DD +:101AF000AE490A78017C62F30001AD4A127862F3C4 +:101B00004101AC4A127862F3C30121F0040101746F +:101B1000A9490A8802874A8842878A888287C988B1 +:101B2000C18710BD70B50C4680EA0406F00601D5E9 +:101B3000F3F765FE8B4DC4F3001030352870B00606 +:101B400001D5F2F7DDFDC4F34010687014F04800D1 +:101B500000D00120A8718248006890F8400400F08D +:101B600001002871C4F34000E87070BD70B57D4E6F +:101B7000864CD6E906010143D4E9080240EA020096 +:101B800081EA000503D110B1FFF758FF12E0E90721 +:101B90000CD08A490A78012A04D100220A7008B9B7 +:101BA000FAF793FFFFF7CAFAFFF7E8FEE80601D558 +:101BB000FFF76EFAE1697069FFF7B4FFE0697061E1 +:101BC000206AF061606AB061BDE8704000F045B81D +:101BD00070B57B4D2C68002C0CD00022A0B21146B1 +:101BE00001F01CF82868A043286003D1BDE87040CC +:101BF00001F086B870BD5B48017A012908D0417AAE +:101C0000012905D0817A012902D0007B002800D06B +:101C10000120704708B5FFF711FF6B4600220B212A +:101C2000022004F013FF0098C00705D00121022014 +:101C300004F0EFFE00F032F80098800705D502218D +:101C4000084604F0E6FE00F05BF800980007E4D5D3 +:101C50000821022004F0DDFEDFE74C49414891F8FD +:101C60003020427091F8313083705A43028291F8EB +:101C70003320C27011F82C2F02704A7802718A78D2 +:101C80004271C97881714F49016201F23C61416240 +:101C9000A1F6784181624C49C162704738B5002491 +:101CA00000F030FE012004F028FFFFF75FFF2D4D0C +:101CB000287F297E0843C00708D03448C1680091B6 +:101CC000D0E9042303C8FFF7ECF90446A86950B132 +:101CD0004CB9032004F011FF2C48A969FEF7F5FF69 +:101CE000032004F025FFFFF7BCFEFFF771FFFFF7AD +:101CF000BEFBFFF712FBBDE83840012004F018BF1F +:101D000070B5002400F0FEFD012004F0F6FEFFF7A0 +:101D10002DFF144D1D4E287FC00703D03068FFF7FC +:101D200003FA0446A86970B16CB900213068FFF766 +:101D300054F9032004F0E1FE1448A969FEF7C5FF39 +:101D4000032004F0F5FEFFF78CFEFFF741FFFFF7DD +:101D50008EFBFFF7E2FABDE87040012004F0E8BE18 +:101D6000B807100050071000E80710000605100023 +:101D700004051000AC090120440D0120801301204E +:101D8000F4071000F6071000A0660120D8791000B3 +:101D9000E9061000EE06100018071000EE0710000C +:101DA000F0071000F20710001205100010051000D7 +:101DB000200510002505100048071000F907100045 +:101DC000D8071000F2580120106701200D4D0020A7 +:101DD0000D4C28602868401C2860EEF70FFB06F0C9 +:101DE0002AFD0128206809D040F00400206005F099 +:101DF0009CFB00BFEEF700FB30BFEBE720F00400D8 +:101E00002060F7E79007100010ED00E070B5134C6C +:101E100025462021114806F0EBFE104800F0B8FBE3 +:101E20002B78421E691C184600F04AF818B10120B0 +:101E3000216801F0BFF800F0C5FB0028E9D170BDB2 +:101E400038B50C46054604F0B8FD6946284604F04E +:101E5000EEFD00992142F8D138BD00002455100054 +:101E600070B5002300290EDD0278491E022A0AD22D +:101E7000114D401C55F8324005EBC20252689142A8 +:101E800001D1A0470346184670BD017811B90B492E +:101E9000407808800120704710B5017811B1012900 +:101EA00007D103E04078FAF734FC02E04078FAF713 +:101EB0001BFC012010BD0000F4960100F607100085 +:101EC00010B50C460023A0F1A001092903D8F7485A +:101ED00050F8213008E0C0280AD1F449A0F1C00030 +:101EE000A1F1040151F820301146204698470346DD +:101EF000184610BD0020704770B5ED4C0023002936 +:101F0000236011DD0278491E042A0DD2E74D401CE2 +:101F1000283555F8324005EBC2025268002A03DB2F +:101F2000914201D1A0470346184670BD70B500210B +:101F30000078E04C82060D4602D50121217003E0B5 +:101F4000C00701D001212570DB4801600421012078 +:101F5000FFF776FF2570012070BD10B5102101201C +:101F6000FFF76EFFD44900200860012010BD10B5B6 +:101F70000146002409782046032918D005DC59B110 +:101F800001290CD002291AD10EE0042911D0102900 +:101F900012D0112913D111E00124002001E0022404 +:101FA000012000F081FA0AE004240220F9E720244D +:101FB00000E04024012002E0082400E01024BC4995 +:101FC00014F0180F0C60BC4C06D010210120FFF754 +:101FD00037FF0020206007E02168814204D02060A4 +:101FE00004210120FFF72CFF012010BD70B5002354 +:101FF00000290FDD0278491E052A0BD2AB4D401C8B +:10200000483555F8324005EBC2025268914201D181 +:10201000A0470346184670BD10B50078C207A74810 +:10202000016802D041F0020101E021F002010160EB +:1020300008210120FFF704FF012010BD10B5007832 +:10204000C2079E48016802D041F0040101E021F07E +:102050000401016008210120FFF7F2FE012010BDFC +:1020600010B50178CB0795490A6802D042F0080202 +:1020700001E022F008020A600078800702D542F0F1 +:10208000400001E022F04000086008210120FFF735 +:10209000D7FE012010BD10B5002103780A469C062A +:1020A00001D5202100229C0701D541F002015C07E7 +:1020B00001D541F004011C0701D541F00801DC06FF +:1020C00001D541F010015C0601D541F040011B062D +:1020D00001D541F080014378DC0701D041F48071E3 +:1020E0009C0701D541F400715C0701D541F4806182 +:1020F0001C0701D541F40061DC0601D541F4805193 +:102100009C0601D541F400515C0601D541F48041A3 +:102110001B0601D541F400418378DC0701D041F46E +:1021200080319C0701D541F400315C0701D541F4B1 +:1021300080211C0701D541F40021DC0601D541F4C2 +:1021400080119C0601D541F400115C0601D541F4D3 +:1021500080011B0601D541F40001C078C00701D001 +:1021600041F080715648C0E90012012010BD00788E +:1021700000B10120534908700120704770B5002359 +:1021800000290FDD0278491E0B2A0BD2474D401C57 +:10219000703555F8324005EBC2025268914201D1C8 +:1021A000A0470346184670BD01460020097805295E +:1021B00006D23E48C83050F821200021084610477A +:1021C000704710B505F06DF9012010BD10B500F095 +:1021D00091FA012010BD10B54FF400610020FFF707 +:1021E0002FFE012010BD10B54FF480510020FFF7E5 +:1021F00027FE012010BD10B54FF400010020FFF7AD +:102200001FFE012010BD10B50078C00702D000F0FD +:1022100000FA01E000F0F4F9012010BD10B50088CB +:102220000024C10700D00224810701D544F0040432 +:10223000400701D544F0080494B1EEF7DFF82248D6 +:10224000016821430160EEF7D7F80221052000F074 +:10225000B1FE4FF480710020FFF7F2FD012010BDA8 +:10226000002010BD10B500880024C10700D0012453 +:10227000810701D544F00204410701D544F004046C +:10228000000701D544F008046CB1EEF7B7F80F4829 +:10229000016821430160EEF7AFF802210020FFF74B +:1022A000CFFD012010BD002010BD000008970100E7 +:1022B000E4071000F8071000DC071000E00710002A +:1022C00048051000F4071000C0071000C4071000F4 +:1022D00010B500880024C10700D00124810701D572 +:1022E00044F00204410701D544F00404000701D57D +:1022F00044F0080474B1EEF781F870480168214396 +:102300000160EEF779F84FF400110020FFF798FD17 +:102310000120C9E70020C7E710B500880024C107E5 +:1023200000D00124810701D544F00204410701D502 +:1023300044F00404010701D544F00804C10601D5A6 +:1023400044F01004810601D544F02004410601D573 +:1023500044F04004010601D544F08004C10501D5D4 +:1023600044F48074810501D544F40074400501D51E +:1023700044F480646CB1EEF741F8514801682143A0 +:102380000160EEF739F880210020FFF759FD0120A8 +:102390008AE7002088E710B500880024C10700D034 +:1023A0000124810701D544F00204400701D544F01F +:1023B000040474B1EEF722F8424801682143016039 +:1023C000EEF71AF84FF480010020FFF739FD0120E5 +:1023D0006AE7002068E710B500780024C10700D044 +:1023E0000124810701D544F00204400701D544F0DF +:1023F000040474B1EEF702F8334801682143016028 +:10240000EDF7FAFF4FF480610020FFF719FD01207E +:102410004AE7002048E710B50078002451283DD055 +:1024200018DC302836D00CDC11282FD004DC012831 +:1024300029D0102830D129E0122827D013282BD1F9 +:1024400024E0312826D0322824D0332822D0502826 +:1024500022D123E0732824D00CDC702821D004DCA6 +:1024600052281BD0532817D118E0712819D0722890 +:1024700012D116E0742814D0752812D0762810D006 +:10248000772809D10DE000F0E4FA01E000F07AFBD2 +:10249000012401E000F096FB204605E700F080FBF8 +:1024A000F6E700F06EFCF3E7002118B1012801D037 +:1024B000022800D10121084670470000C80710001B +:1024C000D0071000D4071000CC0710001C4908B535 +:1024D00000201C4C08601C492060086000F0B9FA1C +:1024E00000F05BFD6B4600221921032004F0AEFAD8 +:1024F0000098C00705D00121032004F08AFAFFF7F5 +:1025000085FC009800070BD50821032004F081FA10 +:102510002068082140F0080020600120FFF790FCAF +:102520000098C006DED51021032004F072FA20685E +:10253000082120F0080020600120FFF781FCD1E78E +:10254000DC071000E0071000E40710001F4800211E +:10255000017041708170704710B51C4C0346A07823 +:10256000102814D20F2900D90F211948227800EB26 +:1025700002100A4600F8011B194606F0BAFA207844 +:10258000401C00F00F002070A078401CA07010BD0F +:1025900070B50E4C0025A17891B10D49627801EB20 +:1025A000021111F8015B2A4606F0A3FA6078401C7C +:1025B00000F00F00607072B6A078401EA07062B686 +:1025C000284670BD014880787047000094071000CD +:1025D0004455100010B54FF486714F4806F02AFBA1 +:1025E0004D490120C1F804014C48002141600170AF +:1025F00006F058FB0021BDE81040012005F0DFBACD +:1026000010B572B600204549087006F04BFB62B663 +:1026100010BD10B572B60120404908703E48D0F890 +:10262000080108B106F09AFB62B610BD10B572B68B +:1026300039493A4B0A46D1F80841D2F80021521CD8 +:10264000202C07D2641C22F02002C1F80841C1F8F6 +:1026500000210FE0D1F8044122F02002641CC1F8EF +:10266000002124F02002C1F804215A68521C5A604B +:10267000D1F80021046801EBC20214604068506088 +:102680001878012805D1D1F80801012801D106F0F8 +:1026900065FB62B610BD204AD2F8080100280ED0B2 +:1026A000D2F8040102EBC000C37923F03F03C371E9 +:1026B00092F80821521E02F03F021343C371704783 +:1026C00010B572B61448D0F8081159B1491EC0F8B7 +:1026D0000811D0F8042102F1010222F02002C0F812 +:1026E000042105D10D480078012801D106F0DAFA5D +:1026F00062B610BD10B572B6002007490122C1F8BC +:102700000801C1E94002054948600878012801D163 +:1027100006F0C8FA62B610BD6C650120980710007B +:10272000064900224FF470430A804B80044BC0E9F5 +:10273000003102210172427270470000A0071000B0 +:10274000E99701002DE9F05FDFF8AC91DFF8A4B163 +:102750000F4606464FF0010AA9F10805A846287859 +:102760000446072809D2DFE800F004272B476E89CA +:102770009A00012E02D0022E13D07CE0002F7AD0D6 +:102780005C4810300078862809D05A48F9B21030D9 +:10279000FFF7E2FE0121032004F00FF96BE00324B0 +:1027A00069E06878012803D01021524806F020FA29 +:1027B000544689F800A05EE0022E5AD0002445E07D +:1027C000022E1BD14D4C4B48D8F80410227806F04D +:1027D00090F9032189F800102178A9F8041098F8DD +:1027E0000000042488F8010088F8004033E0002449 +:1027F00088F801002C70B1E7022E02D0012EF6D02D +:1028000039E0FFF748FF082170B13A4AD0E90030BB +:10281000C2E90030022289F80020364AA9F80220D5 +:10282000A9F80410052426E06878062804D00022C0 +:10283000CBF80020CBF80420032289F80020A9F867 +:102840000410062417E0022E08D002245FFA80F05C +:1028500088F801002C702848BDE8F09F68780428AB +:1028600007D00BEB0700394610F8012C214806F081 +:10287000B7F989F800A0A8462878E9E7022E04D025 +:10288000082F8CD1FFF71CFF89E7FFF719FF98F895 +:102890000000032488F8010088F800405EE7022E5B +:1028A0004FF00304A4D0D1E71349002208390A707D +:1028B0004A70124A521C4A60114901600D498180D8 +:1028C0001031C18010210181704710B5044606F017 +:1028D000E9F9084AD4E90001C2E9000107480C38C7 +:1028E00006F046FA05480C3805F080FABDE81040BD +:1028F00006F034BA78660120AC071000505610007C +:10290000F526010070B50F4D702128462C8806F081 +:1029100091F9641C2C8070BD0A48083800210160C0 +:102920007047084908390A88024204D0C87818B1AB +:10293000C878401EC8707047A52088708878A52880 +:10294000FCD07047A066012037480021016041603B +:102950007047C0B2012200F02FFBFEE7344C002587 +:10296000324FC4E90225C4E90071064600682061BF +:1029700070686061B068A061F068E06130692062F1 +:1029800070696062B069A062F069E06229489046AF +:10299000894600682063274810380068606325482E +:1029A0000C380068A063234808380068E0632148B9 +:1029B000001D006820641F483438006860641D48AA +:1029C00014380068C4E9120504F047F92065C4E929 +:1029D0001565E56525666566A566E566256765672F +:1029E000C4E91E5741464846FFF7B3FF10B50446F9 +:1029F000C0B2002200F0E0FA0F490868082803DAA4 +:102A0000094A1454401C086010BD012806D0022851 +:102A100008D100221146132000F0CEBA0022114640 +:102A20001220F9E77047000070EF0120AF0550FA5F +:102A300080EF012038ED00E0B4071000FD48FE4AA9 +:102A40000168914204D1FD4902794A700021016078 +:102A50007047F0B585B040F23C71F64806F0EAF8F0 +:102A6000684605F040F8F34C012500266570A68005 +:102A7000A6710220E07104F0FCFC208104F0F5FC5A +:102A8000070204F0F2FC47EA102060814520208212 +:102A900041F298006082EA480068418AA182018A76 +:102AA000E182E849B1F8FA2E2283B1F8F82E628368 +:102AB000427D227791F8FC1E6177E3490968497CE1 +:102AC000A177E67701992162009961620299A1627A +:102AD000DDE9031241EA0221E16281692163C169F2 +:102AE0006163DA490968A1630168E163418EA4F872 +:102AF0005010818EA4F8521090F8311084F85410C0 +:102B000090F8300084F85500D148A4F88000D148EE +:102B1000A4F88800D048A4F88A00D048A4F88C0013 +:102B2000CF48A4F88E00CF48A4F89000CE48A4F86F +:102B30009200CE48A4F89400CD48A4F89600CD4861 +:102B4000A4F89800CC48A4F89A00CC48A4F89C00BB +:102B5000CB48A4F89E00CB48A4F8D000CA48A4F8FB +:102B6000D200CA48A4F8D400B449C948A4F8D60091 +:102B70008888401C8880A5222270657060800D7056 +:102B800005B0F0BD70B5AD4C05460023A088A9493D +:102B9000401C82B2A280284601F090FB257070BDD7 +:102BA00070B5054640F23C71A24806F043F8A34CCC +:102BB000A049A088401C82B2A280284601F0ABFB4D +:102BC000257070BD70B59D4C05462078A84204D094 +:102BD00040F23C71974806F02DF8AE48A5700F21E1 +:102BE00001609448934A1030A0607020107194489E +:102BF00002F18005E560006890F8311090F83030FF +:102C0000517101FB03F005EB400693712661084406 +:102C1000D17105EB40006061137270BD70B505465F +:102C2000864CC00704D070228949A06805F061FF76 +:102C3000834EA80712D5316891F8310091F8301011 +:102C40004843A178302935D0312935D0322935D0C3 +:102C50008249E3684200184605F04BFF680716D525 +:102C60003068A17890F831208B48302928D031295C +:102C700031D00078322930D0022838D0052836D01B +:102C8000062834D079495200206905F032FF280720 +:102C900035D5306890F83020A078302829D03128F8 +:102CA00029D0322829D075496069BDE870405200AA +:102CB00005F01FBF6749CCE76749CAE76849C8E71D +:102CC0000078022805D0052803D0062801D06549E0 +:102CD000D9E76D49D7E76449D5E7022805D005282B +:102CE00003D0062801D06249CDE76949CBE767499F +:102CF000C9E76049D8E76049D6E76149D4E770BDC4 +:102D00004C4AA52010704D4881785170017081881F +:102D1000491C81805180704730B587B00C46002136 +:102D20008DF80C104FF4832504AB03AA694600F01C +:102D3000DAF89DF8100010B1112816D01AE09DF8AD +:102D40000C20BAB10098627105EB800104F110000B +:102D50000A78930703D002F0FC02083200E0121D4B +:102D6000D2B205F0C6FE07B030BD3220002220717D +:102D7000114603E0302000222071114600F01CF9BA +:102D8000F1E770B505464FF4C8712A4805F052FFC7 +:102D90002A4C2849A088401CA0802846FFF7BCFF89 +:102DA00024482570A52101704570A188418070BD1F +:102DB0002DE9F84F884606460C460D1D00239B2240 +:102DC0000421404600F032FD90BBA078B0422FD1E4 +:102DD000217800239B22284600F028FD6178884254 +:102DE0007BD1207881070AD0022202EB90060021D5 +:102DF00001E02954401CB0EB860FFAD302E0012118 +:102E000001EB90060024DFF82CB04FF48325A14697 +:102E10004FF0330A55F8240005EB8407401C3DD0E1 +:102E200000239B220421384600F000FD08B14BE04E +:102E300053E035E0000001204B435546FC071000ED +:102E4000B8071000E06F0120BC071000F0FF010080 +:102E5000A066012034850120B6520120F2580120DD +:102E60001067012050820120821A0120F81A0120E7 +:102E70004C6D01207A820120AC1A0120221B012016 +:102E8000766D0120808001205809012082090120EF +:102E90002E090120D8071000E804100000940CE06F +:102EA0003878810704EB900401D0A41C00E0641C76 +:102EB000602CAFD3B9F1000F06D031464046009ADE +:102EC00004F003FC00280CD000228BF804A011466B +:102ED0003320BDE8F84F00F06FB8002211463120D2 +:102EE000F7E7BDE8F88F2DE9FF5F00260E601D466D +:102EF00088464FF48327B1463446B34683F80060D2 +:102F000057F8240007EB840A401C23D000239B229F +:102F10000421504600F08AFC18B1122028700126C6 +:102F20001CE09AF8022000999AF800008A4208D121 +:102F30000299029A4FF001090978491C1170C8F8EA +:102F40000040810704EB900401D0A41C00E0641C45 +:102F5000602CD5D316B9B9F1010F0BD056EA09068A +:102F600006D111202870029981F800B0C8F800B08D +:102F7000BDE8FF9FD8F80000002307EB8004201D68 +:102F800021789B2200F052FC6178884202D185F8BA +:102F900000B0EDE712202870EAE700F011B838B56C +:102FA00004466946183000F0E4FC2046009900F021 +:102FB00011F838BD00F061B800F07DB800F09BB8A2 +:102FC0001CB55849D1E90001CDE900016846FFF779 +:102FD0002DFB1CBD1CB5534BD3E90223CDE90023C7 +:102FE00090F8C421032A19D0082A9DF8002022F065 +:102FF000F00219D012F120028DF8002090F8C521BE +:1030000002F00F02012A11D0022A15D0042A9DF8DD +:10301000012022F00F022ED0521C12E09DF8002059 +:1030200022F0F0021032E7E73032E5E79DF80120A8 +:1030300022F00F02921C04E09DF8012022F00F0202 +:10304000D21C8DF8012090F8D301D2B260F30712A0 +:103050008DF80120BDF802000A0C62F30B00ADF8F8 +:103060000200BDF8030061F30F10ADF803006846DD +:10307000FFF7DCFA1CBD121DE3E71CB52A4A1268F3 +:1030800092F8A020930715D5082813D2DFE800F0A6 +:10309000120406060606060612060BD5214BD3E9D6 +:1030A0000623CDE900238DF80100CDF80210684613 +:1030B000FFF7BCFA1CBD1CB51A4CD4E90834CDE9A5 +:1030C00000348DF80100CDF80210684612B1FFF708 +:1030D000FCFB1CBDFFF7AAFA1CBD1CB5114BD3E9C4 +:1030E0000A23CDE900238DF80100CDF802106846CF +:1030F000FFF79CFA1CBD1CB54178002910D00529AA +:103100000ED2084AD2E90C12CDE90012D0F8021012 +:10311000CDF80210C088ADF806006846FFF786FAC1 +:103120001CBD0000F4970100B80710002DE9FF4115 +:1031300003F08EFB234D0024C4EBC40105EB81009A +:1031400000F10C03027EC8CBCDE90272CDE9003656 +:10315000D0E9012355F82100002103F023FD18B127 +:1031600021464320FFF7F5FB641C052CE4DB154DDD +:1031700000248C3505EBC4000021426855F834006A +:1031800003F097FC18B121464420FFF7E2FB641CD2 +:10319000062CEFDB0B4D002415F1BC05002155F882 +:1031A000240003F0ECFB18B121464520FFF7D1FBCA +:1031B000641C042CF2DBBDE8FF8101464620FFF7CA +:1031C000C8BB00002C98010000F01F0301229A40A8 +:1031D00043099B0003F1E023C3F880224907090E4D +:1031E000002806DA00F00F0000F1E02080F8141D3E +:1031F00003E000F1E02080F80014C3F800217047DC +:103200002DE9F041642707260025F94CF94804F020 +:103210000DFCF8480368D91C40D04268D11C3DD051 +:10322000816811F1030F39D0006910F1030F35D017 +:10323000B3F1FF3F35D013F1020F32D0B2F1FF3FAF +:103240002FD012F1020F2CD0B1F1FF3F29D011F194 +:10325000020F26D0B0F1FF3F23D010F1020F20D093 +:10326000DFB2D6B2CDB204462A463146384604F023 +:1032700025F9204604F02FF9DF4804F0ADFB0328C0 +:1032800014D0012815D0022813D0DB480168012989 +:1032900015D1BDE8F041001D03F025BD002124201B +:1032A00001E000212520FFF7A1FBDDE70021292017 +:1032B00001E000212A20BDE8F041FFF797BBBDE8FF +:1032C000F0812DE9FC41CD4F012501AA6946384620 +:1032D00004F074F9CA4C4FF48C56012803D10098BD +:1032E000B0F58C6F04D000212220FFF77FFB30E087 +:1032F00032463946206805F0FCFB206804F071F97D +:10330000012804D000212320FFF770FB002521684D +:1033100026220F46BB4801F5865105F0EAFB41F233 +:10332000E6003918B7483622283005F0E2FB41F2B2 +:103330001C103918B3482622483005F0DAFB41F258 +:1033400042103918AF483622703005F0D2FB002DFC +:1033500003D13146206805F04BFCBDE8FC81F8B58F +:103360000D46064600246A4604F028F9012801D0DB +:1033700001240BE0286831468200A34805F0FEFBDB +:10338000A14804F02EF9012800D002242046F8BDFF +:10339000F8B59D4D9D4F10354FF470619C4805F078 +:1033A00049FC69463846FFF7DAFF012805D00228B4 +:1033B00006D0E87801280AD105E00021A02029E004 +:1033C0000021A12026E0A87808B9288810B10021A2 +:1033D000A2201FE08E48E9880024A0F8F81EA988E2 +:1033E000A0F8FA1E297A80F8FC1E0098694607EBBF +:1033F00080073846FFF7B3FF78B1012804D00021D9 +:103400005FF0A600FFF7F2FAE00723D0A00723D46D +:103410001121A720FFF7EAFAF8BD6E782946304659 +:1034200000F02BFF50B1102E0BD0112E0CD0122E0D +:103430000DD0132ED9D144F01004D6E73146A82080 +:10344000E0E744F00104D0E744F00204CDE744F0A3 +:103450000804CAE71021DCE720070BD46D48006898 +:1034600090F85012C90703D190F88002C00701D02C +:103470001221CEE7E006CFD41321CAE730B58DB0D4 +:10348000ECF7BCFF0020012241B201F01F0302FA59 +:1034900003F34909890001F1E021C1F88031401CA2 +:1034A0001F28F1DBECF7A8FF03F0B6FFFFF7C6FA21 +:1034B00004F06EFB07210A20FFF786FE07210B2090 +:1034C000FFF782FEFFF786F8FFF740F804A8FFF742 +:1034D000EBF907A8FFF724F904A8009007A80290C9 +:1034E0000AA80390684604F01DFD02210020FFF7A2 +:1034F0006BFE05F039FC0078C00701D1FFF789F8B1 +:10350000FFF722FAFFF77CFE03F0D0FF424D01AA3D +:103510006946284604F052F83E4C012802D00021AA +:10352000202010E00098B0F5267FF8D14FF42662F5 +:103530002946206805F0DDFA206804F052F80128D9 +:1035400003D000212120FFF704FAFFF7BAFE04F0B0 +:10355000EAFA050046D00121012D02D02E20FFF706 +:10356000F8F92068017DA94202D02F20FFF7F1F978 +:10357000FFF70EFF00F052F802F054FE03F088FB54 +:10358000002301221946052005F038F900231A46C8 +:103590000121062005F032F903210120FFF714FE76 +:1035A00004210720FFF710FE04210820FFF70CFE7E +:1035B000206890F86003C1070FD081070DD5002166 +:1035C000012340091A46009104F006FB20680021FF +:1035D00090F86003400904F027FB0DB0BDE83040CF +:1035E000FFF79AB900212D20FFF700FAC0E700008D +:1035F0000090D003908C100064911000F09F0100A7 +:10360000BC071000E07E0120E0671000F0BF010061 +:10361000E06F0120B8071000F0EF010010B504F0D2 +:1036200041FD002301221946184605F0E7F8002362 +:1036300001221946104605F0E1F800231A4601213F +:10364000022005F0DBF800231A460121032005F0D3 +:10365000D5F800231A460121042005F0CFF81748B9 +:103660000068017CA52908D04FF4FA4005F0B0F8B5 +:1036700000212820FFF7BAF902E0406905F0A8F818 +:1036800004210220FFF7A0FD04210320FFF79CFD89 +:1036900004210846FFF798FD04210520FFF794FD5B +:1036A00004210620FFF790FD01210920FFF78CFD82 +:1036B0000421BDE810400F2086E50000BC07100083 +:1036C000884200D30846904200D310467047884293 +:1036D00000D80846904200D810467047884200D370 +:1036E00008467047884200D80846704702460020C6 +:1036F0004FF0804100E089089142FCD807E0431870 +:10370000934202D8D21A00EB4100400889080029F0 +:10371000F5D1824200D9401C704710B55A43029C33 +:1037200006E000BF50F8223093FBF4F341F822305A +:10373000521EF7D210BD10B55A43029C05E000BFDF +:1037400050F82230634341F82230521EF8D210BDA7 +:1037500030B5039C634306E050F8234051F82350F2 +:103760002C4442F823405B1EF6D230BD30B5039C9A +:10377000634306E050F8234051F82350641B42F89D +:1037800023405B1EF6D230BD2DE9F04F8346DDE9C4 +:103790000906DDF834E08A46824226D1002022E084 +:1037A00000FB02F10BEB81090B9D00FB0EF10024E5 +:1037B00005EB810514E000210FE000BF01FB06F8D6 +:1037C00003EB880859F821C055F8247058F8248074 +:1037D000491C0CFB087745F824709142EEDB641C11 +:1037E000B442E8DB401C5045DADBBDE8F08F10B591 +:1037F00000231C4642B10278521CD2B202708A42A7 +:1038000003D90470012300E00470184610BD30B5E0 +:103810000024012305E00C44E41C04F00305641BB0 +:103820005B1C9342F7DD00EB440030BD70B50546EC +:10383000184600240EE02B5D58400823060602D5EA +:1038400082EA400000E040005B1EC0B213F0FF03BC +:10385000F4D1641C8C42EED370BD000030B5B0F9D9 +:103860000240B1F90250641B00D56442B0F9000077 +:10387000B1F90010401A00D54042944203DA984250 +:1038800001DA012030BD002030BD884201DD08464C +:1038900070470028FCDA0020704710B505E000BF33 +:1038A00000EB820353F8044C1C60521EF8D10968E7 +:1038B000016010BD10B503E000EB82030C681C60D2 +:1038C000521EF9D210BD30B506E000BF00EBC203B6 +:1038D00073E90245C3E90245521EF7D1D1E900213F +:1038E000C0E9002130BD10B553884C881B1B4380B4 +:1038F00012880988511A018010BD08B50A46014690 +:103900006846FFF7F0FFBDF90010BDF9020049431A +:1039100000FB001008BD10B58842029C01DC204667 +:1039200010BD904201DB184610BD8A4200D1521CE6 +:10393000401AE31A5843511A90FBF1F0201A10BDB7 +:1039400010B5002A03D0431A934201DD881810BD38 +:103950005442A342FBDA881A10BD914201D100B251 +:1039600070475043B0FBF1F000B29042F7D91046D7 +:10397000F5E770B50B0002463DD0CC4C2068468E72 +:10398000858EB2F9020031B2FFF77FFF5880B2F99D +:10399000000029B2FFF779FF1880216891F83610EE +:1039A000490702D55988711A5980216891F8361053 +:1039B000890701D5281A1880206890F83610090761 +:1039C00010D5B0F83720B3F902003146FFF7C5FF34 +:1039D000588020682946B0F83920B3F90000FFF775 +:1039E000BCFF1880206890F83600C00703D05888C4 +:1039F00019885980188070BD2DE9F047D0F810C0A3 +:103A00000568046A85FB0C12A1FB04124269436835 +:103A1000914683FB02628269E246A6FB0267761842 +:103A2000D0E9021781FB07C8C069ACFB00C81CEBDA +:103A3000060682FB0A2CA2FB011280FB0902A0FBF6 +:103A40000502401884FB0712A1FB03120818301A64 +:103A50004FEAE071BDE8F0872DE9FF4F0025804671 +:103A600091B02E462F46284608EBC00149680D4408 +:103A7000414301FB0077401C0E440628F4DB8C4CCC +:103A8000049560680590A068CDE906062069089055 +:103A90006069CDE90907E0690B90206A0C9004A8E1 +:103AA000FFF7AAFF81462068CDE90405A0680690CB +:103AB000E068CDE9070660690990A069CDE90A07C9 +:103AC000206A0C908B4604A8FFF796FF82460D9162 +:103AD000206804906068CDE90505E06807902069DA +:103AE000CDE90806A0690A90E069CDE90B0704A8B2 +:103AF000FFF782FF0E460D991AEB0A03494113EBBB +:103B0000090341EB0B01B200054642EA90728000C6 +:103B1000181851414FF47562002304F0C6FFC8F82D +:103B20002400129948601399C1E9009B139A0D99DA +:103B3000C2E902A11398C0E9045600252E462F467B +:103B40004FEA050058F830100D44414301FB00775F +:103B5000401C0E440628F5DB049560680590A068BB +:103B6000CDE90606206908906069CDE90907E0699A +:103B70000B90206A0C9004A8FFF73EFF8246206855 +:103B8000CDE90405A0680690E068CDE90706606904 +:103B90000990A069CDE90A07206A0C908B4604A819 +:103BA000FFF72AFF0090206804906068CDE90505C2 +:103BB000E06807902069CDE90806A0690A90E069ED +:103BC000CDE90B07894604A8FFF716FF04460098C5 +:103BD0000D46031849EB090113EB0A0041EB0B01F9 +:103BE000AA00A300C01842EA947251414FF47562D2 +:103BF000002304F05AFFC8F82000129908601499B5 +:103C0000C1E900AB149A0098C2E902091498C0E90E +:103C1000044515B0BDE8F08F2DE9F05FD1E90165ED +:103C20001C46A5FB0438D1F80CC017460CFB048CCD +:103C30000A6882464FF0000B05FB0BC0D318D1E990 +:103C4000042104FB04F5A2FB05C801FB05814641E4 +:103C50004FEAE57902FB091213EB0C0046EB020177 +:103C60004FF475625B4604F020FFCAF8040097E841 +:103C70000B00FA68A3FB04C802FB048203FB0B23BE +:103C800010EB0C025941D7E90434A3FB056704FB90 +:103C9000057403FB0943901959414FF475620023E1 +:103CA00004F003FFCAF80000BDE8F09FB807100059 +:103CB0001408100073B51D24DDE9005622460120CA +:103CC000002104F0CCFE28403140084301D1641E9D +:103CD000F4D50821684603F05FFCFF49C0B20968CB +:103CE00091F8E710C1F3411102290ED310F003003F +:103CF00005D0012805D0022805D01F200AE00F209A +:103D000008E07F2006E03F2004E0C00701D0072044 +:103D100000E003200021621C04F0A1FEDDE9002385 +:103D200010431943CDE900017CBD10B5EB4C502880 +:103D300014D008DC102811D0112825D0122823D047 +:103D4000132806D120E051281ED052281CD0532819 +:103D50001AD00020C4E9020001461BE002F028FB53 +:103D6000C4E9020102F026FBC4E90401DA48006854 +:103D700090F8E70010F0600F0ED0D4E90201FFF7D1 +:103D800099FFC4E9020107E002F012FBC4E9020155 +:103D900002F010FBC4E90401D0480821083003F008 +:103DA000FBFB2060CD480821103003F0F5FB60607C +:103DB00010BD2DE9FF5F0821DDE90FBA684603F069 +:103DC000EBFB8146082102A803F0E6FB074600242E +:103DD00020463AE042460120002104F040FEDDE9A1 +:103DE00000231040194008432DD000252E4627E01F +:103DF00032460120002104F032FEDDE902231040AA +:103E0000194008431BD0119860B104FB07F00BEB7D +:103E100005014156324601EB0A0321460E9803F094 +:103E200020F80BE0324621460E9803F00FF804FB11 +:103E300007F10BEB0502A0EB0A0088546D1C761C01 +:103E4000BD42D5DB641C08F1010080464C45C1DB56 +:103E5000BDE8FF9F2DE9FF5F84B00821DDE912ABCB +:103E600004A803F099FB8146082106A803F094FBFF +:103E7000804600250AF14800029020300190483821 +:103E80002C462F462E46009034E03A460120002171 +:103E900004F0E5FDDDE9042310401940084327D074 +:103EA000169890B11BF8051014980844C2B2394610 +:103EB000029803F042F805EB090141441BF9012087 +:103EC0003946504603F011F810E03946029803F0E5 +:103ED00032F81499401A0BF805003946504602F0A2 +:103EE000FDFF05EB090242440BF802006D1CEDB228 +:103EF0007F1CFFB24D45C8DB38E03246012000216F +:103F000004F0ADFDDDE906231040194008432BD035 +:103F10001698A0B104EB090115981BF8011008448C +:103F2000C2B23146019803F008F804EB490141445C +:103F30001BF901203146009802F0D7FF12E031460C +:103F4000019802F0F8FF159904EB0902401A0BF8EA +:103F500002003146009802F0C1FF04EB49024244DE +:103F60000BF80200641CE4B2761CF6B24445C4DBD4 +:103F700008B0BDE8F09F2DE9FF5F0821DDE90EBA2A +:103F8000684603F009FB8146082102A803F004FB00 +:103F900007460024204629E042460120002104F083 +:103FA0005EFDDDE900231040194008431CD00025C8 +:103FB0002E4616E032460120002104F050FDDDE9D6 +:103FC00002231040194008430AD032462146584681 +:103FD00002F03CFF04FB075280002AF812006D1C1F +:103FE000761CBD42E6DB641C08F1010080464C45AE +:103FF000D2DB2DE72DE9FF5F0821DDE90E9B684646 +:1040000003F0CAFA8246082102A803F0C5FA002587 +:1040100080462C462F462E463DE03A4601200021A0 +:1040200004F01DFDDDE9002310401940084330D0A5 +:10403000394609F1480002F07EFF274999F892C0FD +:104040000A6892F8413192F8402103F00F01491CAF +:104050000CFB01FC012101EB131300FB03C399F8D6 +:10406000900001EB121100FB0130109919B94FF6C5 +:10407000FF7101EA80002BF815003946484602F02E +:104080002DFF05EB0A02800042446D1C2BF8120044 +:10409000EDB27F1CFFB25545BFDB44E03246012044 +:1040A000002104F0DCFCDDE9022310401940084344 +:1040B00037D0314609F1680002F03DFF064999F812 +:1040C00093500B6893F8431101F00F02521C5543B3 +:1040D000012202EB111103E0B807100038081000AC +:1040E00000FB015193F8423199F8910002EB131251 +:1040F00000FB0210109919B94FF6FF7101EA800018 +:1041000004EB0A0231462BF8120009F1200002F0FC +:10411000E5FE04EB4A0280004244641C2BF81200C6 +:10412000E4B2761CF6B24445B8DB91E62DE9F043E3 +:104130008946002787B0904604463E46FC2104F09D +:1041400057FDFD4DB8F1010F287820712879607175 +:10415000FA4890F8821BA17190F8831BE17190F8E6 +:10416000841BA17290F8851BE17290F8801B21736B +:1041700090F8810B607308D1F1480068817FA52910 +:1041800003D190F91F7090F92060EE48002100687B +:1041900090F83401CDE9027600F00100CDE9041079 +:1041A00004F11000E849CDE9001005F108000FC83E +:1041B000FFF750FEA520207012206070A4F8029036 +:1041C000D5E900010844132101EB4000800807B045 +:1041D000BDE8F0832DE9F0438946002787B090467B +:1041E00004463E46FC2104F003FDD34DB8F1010F17 +:1041F0002878207128796071D04890F81A1CA17134 +:1042000090F81B1CE17190F81C1CA17290F81D1C09 +:10421000E17290F8181C217390F8190C607309D1A1 +:10422000C748006890F82110A52903D110F9227F12 +:1042300090F90160C3480021006890F88409CDE935 +:10424000027600F00100CDE90410BF4904F110002E +:104250009831CDE9001005F108000FC8FFF7FAFD0D +:10426000A520207013206070A4F80290D5E90012F8 +:10427000114400EB41008008A9E770B50E460446E2 +:104280000025FFF752FD102C06D0112C08D0122C5F +:104290000CD0132C08D10DE0304600F085F802E078 +:1042A000304600F0A4F80546284670BD304600F0C0 +:1042B000C0F8F8E7304600F0FDF8F4E72DE9F041EA +:1042C0001E461746884605460024FFF72EFD102D92 +:1042D00006D0112D0AD0122D11D0132D0CD114E0BF +:1042E00032463946404600F033F904E0324639465A +:1042F000404600F05FF904462046BDE8F0813246B2 +:1043000039464046FFF712FFF5E732463946404648 +:10431000FFF760FFEFE72DE9FF4117460C46064621 +:10432000FFF703FD844D502E2878207128796071A5 +:1043300004F1100007D0512E07D08249522E0DD023 +:10434000532E2BD115E07D4900E08049CDE90010C6 +:10435000083595E80F00FFF70EFE1FE009687A4B5D +:1043600091F8342191F8401102F0010201F00101AD +:104370000AE00968744B91F8842991F8901902F0C9 +:10438000010201F0010198330DF10408009388E85F +:104390000700083595E80F00FFF72CFEA5202070D8 +:1043A00066706780BDE8FF811FB5634902790B68BD +:1043B0009A4203D142794B689A4202D0002004B05D +:1043C00010BD5F4B00221B689C7EA52C01D193F988 +:1043D0001B205A4C0DF1040C0123103000948CE882 +:1043E0000D0008310FC9FFF7E4FC0120E7E71FB516 +:1043F000514902790B689A4203D142794B689A423B +:1044000001D00020DBE74E4B00221B681C7FA52C4F +:1044100001D193F91D204D4B0DF1040C01241030F6 +:1044200000938CE8150008310FC9FFF7C2FC01208A +:10443000C5E730B54049027987B00B689A4203D18D +:1044400042794B689A4202D0002007B030BD3B4A07 +:104450008579002482F8825BC57982F8835B857A4E +:1044600082F8845BC57A82F8855B057B82F8805B85 +:10447000457B82F8815B324A23461268957FA52DE1 +:1044800003D192F91F4092F920302E4A01251030B5 +:104490001268083192F83421CDE9024302F001029A +:1044A000CDE90452284ACDE900200FC9FFF7D2FC1C +:1044B0000120CAE730B52049027987B00B689A42DB +:1044C00003D142794B689A4201D00020BDE71B4AD4 +:1044D0008579002482F81A5CC57982F81B5C857A9C +:1044E00082F81C5CC57A82F81D5C057B82F8185C3A +:1044F000457B82F8195C124A2346126892F82150D3 +:10450000A52D03D112F9224F92F901300D4A012550 +:1045100010301268083192F88429CDE9024302F084 +:104520000102CDE90452084A9832CDE900200FC9B2 +:10453000FFF790FC012088E738081000E06F0120A9 +:10454000BC071000B8071000D07A012008750120C0 +:104550002DE9FF410F4615460446002640F27A3108 +:1045600004F046FB2C48012D01782171017961711D +:1045700006D12A4909688A7EA52A01D191F91B60D2 +:1045800004F11001264BCDE900310022CDE9026291 +:1045900000F1080105460FC9FFF70BFCA5202070AC +:1045A000102060706780D5E900014843133080080F +:1045B00004B0A2E62DE9FF410F4615460446002649 +:1045C00040F27A3104F014FB1348012D0178217177 +:1045D0000179617106D1114909680A7FA52A01D1C3 +:1045E00091F91D6004F110010E4ACDE9002100236C +:1045F000CDE9026300F1080105460FC9FFF7D9FBB9 +:10460000A5202070112060706780D5E90001484323 +:1046100013308008CCE7000038081000BC071000F9 +:10462000E06F0120087501202DE9F04F47F6FF7774 +:10463000DDE909B58146FE4301209A4684462C46B1 +:1046400015E000BF32F8143031F81480A3EB0803F2 +:104650001BB2BB4200DA1F46B34200DD1E46002BF0 +:1046600002DD4FF0000C02E001DA4FF00000641EA2 +:10467000E8D220B1BCF1000F01D0002309E050EADC +:104680000C0306D020B9BCF1000F01D0334600E086 +:104690003B4600273C462846CBF1000C0EE000BF0D +:1046A00032F8106031F81080A6EB0806F61A36B220 +:1046B000564503DA664501DD3744641C401EEFD2DF +:1046C00004B9012497FBF4F0184404E031F81520F4 +:1046D000024429F815206D1EF8D2BDE8F08FF0B520 +:1046E000002306461D4618460EE000BF36F911406D +:1046F000002C01DB274600E06742974204DD002CD6 +:1047000001DD254400E02344491EEFD2002B00DAEE +:104710005B42AB4200DD0120F0BD30B507E000BFD9 +:1047200032F8134031F81350641B20F813405B1E1D +:10473000F6D230BD70B5049C09E000BF31F91450C9 +:1047400032F91460754395FBF3F520F81450641E9C +:10475000F4D270BDF0B4049C1CB913B1C3F11004C1 +:104760000EE0F0BC520004F0C4B900BF30F91250A2 +:1047700031F912605D4306FB04552D1120F81250EB +:10478000521EF3D2F0BC7047F0B4049C1CB913B1B4 +:10479000C3F180040EE0F0BC520004F0AAB900BFDF +:1047A00030F9125031F912605D4306FB0455ED11EA +:1047B00020F81250521EF3D2E4E7F0B5002B19D0C6 +:1047C000144615E000273E46E51A04EB030C08E00A +:1047D000002D05DB954203DA31F915E0761C7744AC +:1047E0006D1CAC45F4DA1EB197FBF6F520F81450B9 +:1047F000641EE7D2F0BD70B50C461546A04204D049 +:1048000001466A00204604F074F9002017E00146D2 +:10481000421C07E034F9126034F911309E4200DA8C +:104820001146521CAA42F5D3884207D034F8102012 +:1048300034F8113024F8103024F81120401CB0EB6B +:10484000550FE4D9E90725F0010001D0205E70BDC5 +:10485000215E204430F9020C0844401070BD03462C +:10486000002004E033F91120824200DD1046491E89 +:10487000F8D27047034647F6FF7004E033F9112081 +:10488000824200DA1046491EF8D2002800DA0020E1 +:1048900070470246B0F9000005E000BF32F9113060 +:1048A000834200DD1846491EF8D2704770B50500F6 +:1048B00003D0BDE8704001F061BDFE4C2146607838 +:1048C000097930B10A46FC4901F1980001F0A4FDD4 +:1048D0000BE0207801F06EFE21794A00F64901EBE9 +:1048E0004001F548983004F004F9A078F34E28B15F +:1048F000F1482179983001F05BFE01E0EE489830F4 +:10490000B062E07886F831002846D2E72DE9F05F02 +:10491000DFF8ACA383460127DAF80000B84600F2BE +:104920005E6490F8981990F8945901F01F0690F879 +:10493000951901F00F0990F88219890609D590F8A8 +:10494000581690F859060A2204EB400001F0A0FD29 +:104950000746DAF8000090F88219490609D590F860 +:10496000681890F869080A2204EB400001F090FDF5 +:1049700080464FF48070854200D905461F2E00D92D +:104980001F26761C754309F101004543C5EB452000 +:104990007843DAF8002000FB08F0C01392F8501AB0 +:1049A000B0FA80F0C0F12000890611D50021BBF1DA +:1049B000010F06D192F8561A0A0701F0070100D537 +:1049C0004942401801D5002002E01F2800DD1F20C9 +:1049D000C0B2BDE8F09FF8B5044602F072F9B648DF +:1049E00002F074F9A4F8760001F03CFDB14A0B46E0 +:1049F000127800920246204602F033FC01F037FDA7 +:104A000002460B46204602F062FC204601F0DEFD25 +:104A1000AB4DB4F856102868B0F8C02062F3090115 +:104A2000A4F8561090F8BF0094F8551060F30301F5 +:104A300084F855100521204602F073F9286890F893 +:104A40009409A0702868218EB0F89A2962F30801B1 +:104A5000218690F8950900F00F01204602F0D8F960 +:104A6000286834F81A1FB0F88C2962F30B0124F877 +:104A70001419B0F88A29618962F30B016181B0F8D9 +:104A80008819E08861F30B00E08014F8050C20F031 +:104A90000C0004F8050C2868217B90F8962962F335 +:104AA0000101217390F89629920862F3871121730E +:104AB00090F88219627861F30002627090F88509BB +:104AC000E070804890F8181C217690F8191CA177A6 +:104AD00090F81A1C617690F81B1CE17790F81C1C6A +:104AE000A17690F81D0C84F82000774802F0EEF8CB +:104AF000A4F87A007448203002F0E8F8A4F87E00A8 +:104B0000286814F8166F90F89019090961F30716D0 +:104B100004F8066B90F892192278090961F30712DC +:104B2000227090F8913914F8051C63F3030104F81E +:104B3000051C90F89379637867F30303637090F82A +:104B400091793F0967F3071104F8051C90F8931950 +:104B5000090961F30713637090F8901961F3000677 +:104B600004F8066C90F8921961F3000204F8222907 +:104B700090F886090109204602F056F95248483853 +:104B800002F0A4F8A4F87E004F482734283802F039 +:104B90009DF8A4F85B00296891F8840982082078C0 +:104BA00062F38300207091F8842962F30000207082 +:104BB00091F88429520862F3410004F8010B20782F +:104BC00020F01000207091F88229D308E27A63F374 +:104BD0004512E27291F8831961F3451004F828092F +:104BE000204601F0D7FC286890F88309C0F3410102 +:104BF000204602F0E7F8296891F88209820914F842 +:104C0000330F62F3000004F81D0991F8822952095C +:104C100062F34100607791F89709E27D60F3040246 +:104C2000E27591F89819A07D61F30400A0752248FF +:104C300094F849100838407860F30401224884F859 +:104C40004910E83002F042F8A4F86400286834F80B +:104C5000181FB0F88E2962F30B0124F8041910F81C +:104C6000E31F227861F3030204F8012B01780A099B +:104C7000217862F3030104F8091B90F89F18CA0910 +:104C8000217862F3000104F82B1B14F8571941F046 +:104C9000200184F8571090F8B4184A09217862F37B +:104CA0000611217090F8A0184A09217C62F3C30113 +:104CB00021740BE050081000E87F012030911000B3 +:104CC000B8071000E06F0120B07B012090F89F082A +:104CD000400860F304112174F8BD2DE9F041044649 +:104CE000524D01200129A87008D00026504F0229FA +:104CF00008D0032914D004292CD13AE0204600F032 +:104D000091F827E04B48FFF766FE204600F08AF84E +:104D1000B87894F85F1060F3040184F85F1014E031 +:104D20004448FFF758FE204600F07CF8F87894F8E5 +:104D30005F1060F3040184F85F1094F8270020F0FE +:104D4000020040F0010084F827000021204602F014 +:104D50005FF8AE7094F8270040F30000401CE87044 +:104D60003548006890F88309C0F380106870BDE88A +:104D7000F081204600F056F8204601F068FCE8E794 +:104D80007CB501F06FFBCDE900010821684602F017 +:104D900003FC2649264D0871002028602871012453 +:104DA000E0B2FFF7B3FD2855641C052CF8DB214861 +:104DB000FFF711FE7CBD30B5017AA9B079B3684622 +:104DC000FFF78BFF9DF8120000F0030001F0B2FB2B +:104DD000194C206800F25E6300F66E0590F85816D4 +:104DE00090F8590603EB400001F075FB206890F83D +:104DF000681890F8690805EB400001F083FB0B4848 +:104E0000417801B102210170C9B2684602F079FA15 +:104E10000A49684602F0AAFA002029B030BDFFE72F +:104E20000120FAE7A422034903F063BE50081000F2 +:104E3000E07F0120A48C1000B80710005D4801003D +:104E400010B5040003D0BDE8104001F097BA254822 +:104E500025490078420001EB40012348983003F0D7 +:104E600048FE21482149983048622046EBE71CB5AE +:104E700001F0F8FACDE900010821684602F08CFB48 +:104E800018491B4C0870204600F0E5FA164801F05E +:104E90001DFFA4F8760017480168A07C91F8462110 +:104EA00062F30100A07491F84611890861F387103C +:104EB000A0741CBD10B50E4CC07980B1A07C00F070 +:104EC000030001F037FB00F027FB0421204602F02D +:104ED00018FA0949204602F049FA002010BD0120C5 +:104EE00010BD000055081000CC800120309110004A +:104EF000488D1000B8071000F14D0100FE49C86848 +:104F0000401CC860022803D2FC4951F82000004729 +:104F1000002001F033BA002801D102F018BA70471E +:104F2000F54910B50A790120521CD2B20A710B7AE8 +:104F30009A420AD8487A48B102F05AF90320EBF7AE +:104F40005FFAEF4802F048F9002010BD02F0FFF9C7 +:104F5000FAE770B518B1BDE8704001F00FBAE64C41 +:104F6000207A08B1E74D01E0E64D763DA078E649AC +:104F7000820001F5AE7003F001FE607928B1A278DD +:104F8000E149284601F048FA0CE0A178607801F088 +:104F900011FBA178C0B24A00DB4901EB4001284671 +:104FA00003F0A7FDD7482379A2782946763801F087 +:104FB00044FAFFF7B5FF002815D0A079D34D01289A +:104FC0000BD0D0487638A861E07985F83000207998 +:104FD00085F82000BDE8704090E7CA48A17876388F +:104FE00001F0E6FAEFE770BD70B518B1BDE87040AA +:104FF00001F0C4B9C04C207A08B1C24D01E0C14DE6 +:105000004C3DE078C049820001F5D87003F0B6FD50 +:10501000607928B1E278BC49284601F0FDF90CE03E +:10502000E178607801F0CCFAE178C0B24A00B64984 +:1050300001EB4001284603F05CFDB2482379E27899 +:1050400029464C3801F0F9F9FFF76AFF002815D01E +:10505000A079AE4D01280BD0AA484C38E861E07920 +:1050600085F83000207985F82100BDE8704045E7DB +:10507000A448E1784C3801F09CFAEFE770BD2DE9C7 +:10508000F14FDFF88CB20127B846DBF8000000F2E0 +:105090005E6490F8491190F8445101F0030A90F8C9 +:1050A000481101F01F0690F8451101F00F0990F822 +:1050B0003211890609D590F8561690F857060A223B +:1050C00004EB400001F0E4F90746DBF8000090F83B +:1050D0003211490609D590F8661890F867080A2237 +:1050E00004EB400001F0D4F980464FF48070854213 +:1050F00000D905461F2E00D91F26761C754309F1DD +:1051000001004543C5EB4520784300FB08F00AF158 +:1051100001014843DBF80020C013B0FA80F092F898 +:10512000501AC0F12000C90611D5009B0021012BA7 +:1051300006D192F8551A0A0701F0070100D5494235 +:10514000401801D5002002E01F2800DD1F20C0B25A +:10515000BDE8F88FF8B5044601F0B3FD6A4801F0E8 +:10516000B5FDA4F8760001F07DF9634E0B46727828 +:1051700000920246204602F074F801F078F90246E7 +:105180000B46204602F0A3F8204601F01FFA604DBE +:10519000B4F856102868B0F8C02062F30901A4F8EA +:1051A000561090F8BF0094F8551060F3030184F88E +:1051B00055100521204601F0B4FD286890F84401FF +:1051C000A0702868218EB0F84A2162F30801218678 +:1051D00090F8450100F00F01204601F019FE286803 +:1051E00034F81A1FB0F83C2162F30B0124F81219AD +:1051F000B0F83A21218962F30B012181B0F83821FE +:10520000A18862F30B01A18090F84621A17A62F394 +:105210000101A17290F84621920862F38711A172F0 +:1052200090F8321114F8012C61F3000204F8012CFB +:1052300090F835016070374890F8801BA17590F8A0 +:10524000811B217790F8821BE17590F8831B6177B1 +:1052500090F8841B217690F8850BA0772E4801F0FA +:1052600035FDA4F878002C48203001F02FFDA4F87B +:105270007C00286814F8147F90F84011090961F344 +:10528000071704F8067B90F842110A09217862F3A7 +:105290000711217090F8413114F8052C63F30302D3 +:1052A00004F8052C90F843C163786CF30303637032 +:1052B00090F841C14FEA1C1C6CF3071204F8052C4E +:1052C00090F84321120962F30713637090F84021AC +:1052D00062F3000704F8067C90F8422162F30001B3 +:1052E00004F8221990F836010109204601F09CFDCE +:1052F0000948483812E0000058081000F8980100EA +:10530000C74E0100C6820120B881012030911000F3 +:10531000B8071000E06F0120187B012001F0D6FCD7 +:10532000A4F87E00CD48273401F0D0FCA4F85B003F +:10533000296891F834018208207862F38300207094 +:1053400091F8342162F30000207091F83421520862 +:1053500062F3410004F8010B207820F01000207067 +:1053600091F83221D308E27A63F34512E27291F8A0 +:10537000331161F3451004F82809204601F0F8F8CC +:10538000286890F83301C0F34101204601F01AFD6E +:10539000286890F832118A0914F8331F62F300016B +:1053A00004F8071990F83221520962F34101E171C2 +:1053B00090F84711627861F30402627090F8480136 +:1053C000217860F30401A648217094F833104078E6 +:1053D00060F3040184F83310A24801F077FCA4F8CC +:1053E0004E00286834F8021FB0F83E2162F30B012A +:1053F00024F8181910F8E31F227D61F303022275C7 +:1054000010F8451B0A09617D62F303016175817A19 +:10541000CA09A17F62F30001A17794F8491041F015 +:10542000200184F84910C17F4A0914F80E1C62F368 +:10543000061104F80E1CC17A4A09A17862F3C3016F +:10544000A170827A520862F30411A170C07AC0F38D +:1054500080107071F8BDA422834903F04ABB2DE986 +:10546000F041824D002601272E71AF712E720C463D +:105470006E72012807D07A4F02282CD0032814D04E +:1054800004283AD141E00846FFF7E5FF7848016873 +:1054900091F83701420630D591F84911000601F024 +:1054A0000301297229D56F7227E06F48FFF752FE7A +:1054B0002046FFF7D0FFF87894F85F1060F30401FE +:1054C00084F85F1094F8270020F0020040F00100FB +:1054D00084F827000CE06448FFF73CFE2046FFF705 +:1054E000BAFFB87894F85F1060F3040184F85F1095 +:1054F0000021204601F08CFCAE7194F8270040F3A7 +:105500000000401CE871BDE8F0810846FFF7A3FFEA +:10551000204601F09CF8EFE770B5554D286800F281 +:105520005E6200F66E0490F8561690F8570602EB8D +:10553000400000F0D0FF286890F8661890F86708DF +:1055400004EB4000BDE8704000F0DCBF70B5474D93 +:10555000454C6879A43400B102206870214628784F +:10556000FFF77DFF42480168A07C91F8462162F375 +:105570000100A07491F84611890861F38710A074A6 +:105580006978204601F0BDFEA07C00F0030000F029 +:10559000D1FFFFF7C1FF2046BDE87040354901F05B +:1055A000E5BE70B5314D304C6879A43408B10320A4 +:1055B00000E00120687021462878FFF750FF2C4852 +:1055C000016891F846010209A07C62F30100A07411 +:1055D00091F84611890961F38710A0746978204613 +:1055E00001F08FFEA07C00F0030000F0A3FFFFF7A6 +:1055F00093FF2046BDE870401F4901F0B7BE7FB55C +:1056000000F030FFCDE9000100F031FFCDE90201EB +:105610000821684601F0C0FF144C0821A07002A8C0 +:1056200001F0BAFFE0700E4D0124E0B2FFF727FD54 +:105630002855641C052CF8DB0B48FFF78BFD7FBD5C +:1056400010B5807940B1094908704FF0FF30C8604B +:10565000FFF754FC002010BD012010BDF07A01209E +:10566000B0810120987C0120EC8D100058081000BA +:10567000B8071000034F0100994F010010B9714A9B +:105680006F49116100F07ABE70B56F4D044628680D +:1056900090F8F101C0F30112C0F3810100F00300A2 +:1056A000FEF715F8401CC6B2204600F031FC6448F5 +:1056B00001F00CFBA4F8760000223146204601F0F0 +:1056C0000BFDA07940F00200A07194F86F0066F322 +:1056D000020084F86F0094F86E0020F00F0084F848 +:1056E0006E002968A07C91F8082162F30100A07483 +:1056F00091F80821920862F38710A074A0896FF3D3 +:105700000B00A08191F80701A07094F85E000021C1 +:1057100020F0010084F85E00204601F079FB286843 +:1057200090F8F21184F8661090F8F31184F868107C +:1057300090F8F41184F86A1090F8F50184F86C0080 +:105740003F4894F85F10001F407860F3040184F82C +:105750005F102046BDE8704000F0FEBE10B5384C2A +:105760000020241F2080012000F02FF86070BDE889 +:105770001040364888E72DE9F041344E407910B3A7 +:10578000B07C00F0030000F0D5FE2F4F3C6804F21F +:105790005E6094F8512604F66E0594F8501600EBFE +:1057A000420000F098FE386890F8601890F86108A0 +:1057B00005EB400000F0A6FE2549304601F0CCFC88 +:1057C0000020BDE8F0810120FBE730B51E494FF411 +:1057D00080750A6892F8071192F8F43092F8F14057 +:1057E00003F01F0304F00F04A94200D929461F2B20 +:1057F00000D91F235B1C59434900641C6143C1EB62 +:105800004121C91392F8503AB1FA81F1C1F1200156 +:105810009B0713D50023012809D192F8540A0207E7 +:1058200003D500F00700434201E000F00703C91868 +:1058300001D5002102E01F2900DD1F21C8B230BDC3 +:105840000484012030911000B8071000348F10003C +:105850002D5601002DE9F05FDFF8A08583464FF05B +:105860000109D8F800000027ABF1020100F25E64E4 +:10587000CA46062950D2DFE801F04F092C4F2C030D +:1058800010F8D46F007900F01F056DE090F8F41067 +:1058900090F8026101F01F0590F8F11001F00F0778 +:1058A00090F8E610890609D590F8521690F853063C +:1058B0000A2204EB400000F0EBFD8146D8F800001E +:1058C00090F8E61049064FD590F8621890F86308F2 +:1058D00044E090F8FC1090F8F86001F01F0590F893 +:1058E000F91001F00F0790F8E610890609D590F835 +:1058F000541690F855060A2204EB400000F0C8FD4B +:105900008146D8F8000090F8E61049062CD590F8AA +:10591000641890F8650821E090F8F41090F8F060B1 +:1059200001F01F0590F8F11001F00F0790F8E61054 +:10593000890609D590F8501690F851060A2204EB12 +:10594000400000F0A5FD8146D8F8000090F8E61070 +:10595000490609D590F8601890F861080A2204EB0E +:10596000400000F095FD82464FF48070864200D9D9 +:1059700006461F2D00D91F256D1C6E4370007F1C2D +:105980007843C0EB402000FB09F000FB0AF0C01395 +:10599000D8F80020B0FA80F0C0F1200192F8500A47 +:1059A000C00723D00020BBF1050F11D2DFE80BF0B8 +:1059B00010030609140092F8510A04E092F8510A03 +:1059C0000CE092F8520A020700F0070000D54042AE +:1059D000091808D5002109E092F8520A0206C0F31E +:1059E0000210F4D4F4E71F2900DD1F21C8B2BDE87E +:1059F000F09F70B5060003D0BDE8704000F0BEBC5B +:105A000000F018F8012814D1FD4DFE4C287801282B +:105A100009D0FD48A0606878E073E878A073E88852 +:105A2000A0813046E8E76A792979F74800F0BFFDA0 +:105A3000F0E770BDF24B10B5D978F44C491CCAB2EE +:105A4000DA70997801208A420ED819795879414341 +:105A5000ED48FDF7DCFE01F039F9A4F87600EC49D9 +:105A6000204601F079FB002010BD38B5044601F056 +:105A700028F9E54801F02AF9A4F8760000F0F2FCD4 +:105A8000DE4D0B462A6892F8E720C2F341120092DD +:105A90000246204601F0FFFA00F0E9FC02460B4600 +:105AA000204601F024FBA07920F00200A07194F8B8 +:105AB0006F0020F0070084F86F0094F86E0020F06B +:105AC0000F0084F86E00286890F8E700C0F34111D9 +:105AD000204601F026FB286890F8E70010F0600FE0 +:105AE00094F85E007ED040F0010000BF84F85E00B4 +:105AF000204600F06BFD0521204601F012F92868D0 +:105B000090F8F000A0702868218EB0F8F62062F3BB +:105B10000801218690F8F10000F00F01204601F005 +:105B200077F92868627D90F8EA1061F303026275E4 +:105B3000B0F8EC20218A62F30B01218290F8F21078 +:105B4000A27D61F30302A27510F8F11F0A09A17C7E +:105B500062F30101A17410F80B29920962F3871115 +:105B6000A1740178E27961F30002E271C178617297 +:105B700000790109204601F057F9A64801F0A6F87E +:105B8000A4F87C00296811F8E80F820814F8270FA0 +:105B900062F38300207011F8012962F30000207085 +:105BA0004A78520862F34100207008780109607851 +:105BB00061F304106070984801F088F8A4F85F0061 +:105BC000286810F8E61FCA0814F80C1F62F3451184 +:105BD00004F80B194078217860F3451104F828196E +:105BE000204600E05CE000F0B7FC286890F8E70091 +:105BF000C0F34101204601F0E5F8286810F8E61FDF +:105C00008A0914F8331F62F3000104F80B190278B3 +:105C1000520962F34101E172417B627961F304024E +:105C20006271807B217960F304017C48217194F8D2 +:105C30003710407860F3040184F83710784801F099 +:105C400045F8A4F85200286834F8061FB0F8EE2092 +:105C500062F30B0124F8061B10F8E21F14F80A2C5B +:105C600061F3030204F80A2C01780A0914F8091CEC +:105C700062F3030104F8091C01798A0814F80C1C6A +:105C800062F3000104F80C1C0079C109207861F36B +:105C9000000004F82B0B207840F02000207038BD65 +:105CA00020F0010022E738B5044601F00AF8564812 +:105CB00001F00CF8A4F8760000F0D4FB4F4D0B4631 +:105CC0002A6892F8C920C2F3411200920246204687 +:105CD00001F0E1F900F0CBFB02460B46204601F053 +:105CE00006FAA07920F00200A07194F86F0020F06D +:105CF000070084F86F0094F86E0020F00F0084F81D +:105D00006E00286890F8C900C0F34111204601F0E8 +:105D100008FA286890F8C90010F0600F94F85E0047 +:105D20006BD040F0010000BF84F85E00204600F018 +:105D30004DFC286890F8D400A0702868218EB0F837 +:105D4000DA2062F30801218690F8D50000F00F01F7 +:105D5000204601F05DF82868627D90F8CC1061F370 +:105D600003026275B0F8CE20218A62F30B01218212 +:105D700090F8D610A27D61F30302A275B0F8D0208E +:105D8000A18962F30B01A18110F8D51F0A09A17C3A +:105D900062F30101A17410F80D29920962F38711D1 +:105DA000A1740178E27961F30002E271C178617255 +:105DB00000790109204601F037F8164800F086FF07 +:105DC000A4F87C00296811F8CA0F820814F8270F7C +:105DD00062F38300207011F8012962F30000207043 +:105DE0004A78520862F3410020700878010960780F +:105DF00061F304106070084814E086E0B8071000F2 +:105E00006808100030911000348501207C9010004B +:105E1000A3590100E06F0120707F0120369E012010 +:105E2000987C012000F052FFA4F85F00286810F869 +:105E3000C81FCA0814F80C1F62F3451104F80B19A7 +:105E40004078217860F3451104F82819204600F0C5 +:105E500083FB286890F8C900C0F34101204600F098 +:105E6000B1FF296811F8C80F820914F8330F62F3E3 +:105E7000000004F80B090A78520962F34100E0724D +:105E8000C87B627960F304026271087C217960F357 +:105E90000401DC48217194F83710C07960F30401E3 +:105EA00084F83710D84800F011FFA4F85200286891 +:105EB00034F8061FB0F8D22062F30B0124F8061B59 +:105EC00010F8E21F14F80A2C61F3030204F80A2CFC +:105ED00010F81A190A0914F8091C62F3030104F8EE +:105EE000091C01788A0814F80C1C62F3000104F8FC +:105EF0000C1C0078C109207861F3000004F82B0B1A +:105F0000207840F02000207038BD20F001000BE721 +:105F100010B50446A422BD4902F0EBFDBC48C1788F +:105F2000A08961F30B00A08110BD38B50446FFF7CE +:105F3000EFFF00F097FA0022009202460B4620463F +:105F400001F0A9F8B34800F0C1FEB34DA4F87C00FD +:105F5000286890F8F800A070286890F8F90000F020 +:105F60000F01204600F054FF286810F8F91F0A09B5 +:105F7000A17C62F30101A1740278920962F3871196 +:105F8000A174817894F82D2061F3040284F82D2007 +:105F9000C17894F82C2061F3040284F82C20407816 +:105FA000A17D60F30301A1750021204601F0B9F83D +:105FB00014F85E0F20F0010004F8010B91480179FC +:105FC000207861F3040004F82F092868B0F8FE1067 +:105FD000208861F30800208038BD70B58E4E0328FC +:105FE000346804F25E6204F66E0515D0042821D0F0 +:105FF00094F8510694F8501602EB400000F06BFA4A +:10600000306890F8601890F8610800BF05EB400018 +:10601000BDE8704000F076BA94F8530694F8521632 +:1060200002EB400000F057FA306890F8621890F8E0 +:106030006308EBE794F8550694F8541602EB400019 +:1060400000F049FA306890F8641890F86508DDE7C8 +:106050002DE9F843714D4FF00109002685F80090B5 +:10606000AE70684FDFF8B0810446EE70092972D235 +:10607000DFE801F071050918442F485E62002046F0 +:10608000FFF746FF67E02046FFF742FFB87894F835 +:106090005F1060F3040184F85F10D8F8000090F8F6 +:1060A000000112E02046FFF733FFD8F8001091F806 +:1060B0000211A170F97894F85F2061F3040284F86A +:1060C0005F20D8F8000090F8010100F00300A870EC +:1060D00041E02046FFF71CFF0021204600F098FE1B +:1060E00094F85E0020F0010084F85E00787994F85E +:1060F0005F1060F3040184F85F1017E02046FFF79B +:1061000014FF28E02046FFF710FF0021204600F092 +:106110007FFEB87994F85F1060F3040184F85F1093 +:1061200094F85E0020F0010084F85E002E7012E00A +:106130002046FFF7B8FDF9E72046FFF7E9FE012208 +:1061400000232046009600F0A6FF204600F07FFACC +:10615000204600F001FA94F82700C00701D06E70C5 +:1061600001E085F80190A089C0F30B00E880BDE84C +:10617000F8837FB500F076F9CDE9000100F077F9FA +:10618000CDE902010821684601F006FA234C0821F6 +:10619000207102A801F000FA60711A480021801EE7 +:1061A000184D40F8021F012441600172E0B2FFF770 +:1061B00051FB2855641C092CF8DB1448FFF755FCEB +:1061C0007FBD70B5114D0479A4358CB121462846A8 +:1061D000FFF73EFFA87C00F0030000F0ABF920467B +:1061E000FFF7FBFE0E49284600F0B6FF002070BD09 +:1061F000012070BD40F2FF10C1EB412191FBF0F096 +:1062000000207047369E0120987C0120D88F100016 +:10621000E807100008750120B80710006808100092 +:10622000A359010010B500F05FFAFFF7A2FFFFF7D6 +:1062300095FAFFF7E4F9FEF7A3FDFEF718FE7149A2 +:10624000002048607021704802F0D2FC6F4801685D +:1062500091F8E700C00607D5BDE8104028226A483B +:1062600001F50F6102F045BC10BD38B1012807D01F +:10627000022807D017200021FCF76BBB1420FAE797 +:106280001520F8E71620F6E70021016041608160E3 +:10629000C160704770B55B4C5D4D206809E000BF80 +:1062A00055F820105B488847002811D02068401C12 +:1062B00020600728F4D360685649401C1031002242 +:1062C00060600A70486053480168103088470120B8 +:1062D00070BD70B504460079002540B9E07930B949 +:1062E000A07920B9207A10B9607900280ED04948E9 +:1062F0003421103002F09EFC1ECC464880E81E007F +:10630000404805604348FFF7C5FF012070BD10B548 +:10631000012000F060F8072000F05DF8082000F090 +:106320005AF8052000F057F80D2000F054F80C2022 +:1063300000F051F8012000F059F8072000F056F85D +:10634000082000F053F8052000F050F80D2000F070 +:106350004DF80C2000F04AF802F05BF800F0A9FCC0 +:10636000012000F02DF8072000F02AF8082000F0A6 +:1063700027F8BDE81040052000F022B870B5214C88 +:1063800005000ED0FFF7C3FF60682249401C1031A2 +:1063900060600D7048601F480168BDE870401030B3 +:1063A00008472068401C2060BDE87040194871E72C +:1063B00000F058B800F05BB800F05EB800F062B8CA +:1063C00000F01F02012191404009800000F1E0200F +:1063D000C0F80011704700F01F02012191404009F0 +:1063E000800000F1E020C0F88011704700F01F022B +:1063F000012191404009800000F1E020C0F88012A6 +:106400007047000070081000707F0120B80710006E +:10641000009901002091100070B50023144609E096 +:1064200031F9135031F9146035446D1020F81350D0 +:106430005B1C641C9342F3DB70BD30B400244BB989 +:106440000CE000BF30F8143031F814502B4420F821 +:106450001430641C9442F5DB30BC704730BC5200F1 +:1064600002F047BB99480068C16A806A7047974844 +:106470000068416A006A70479448006800F6382056 +:1064800003C870479148006800F5236003C870474F +:10649000F0B5002425468E4E4FF4006714E000BF8F +:1064A00030F81530C3F30B035FEAD32C00D033432D +:1064B000002B00DA5B429C4200DA9CB2BC4202D361 +:1064C00040F2FF7402E06D1C8D42E9DBD4400120F4 +:1064D000A04080B2F0BD30B57F4B7E4C5A688242FE +:1064E00002D1DA688A420AD0002206E030F812505F +:1064F000C5F30B0524F81250521C8A42F6DBD96012 +:10650000586030BD30B5744B744C9A68824202D1E9 +:106510001A698A420DD0002207E000BF30F81250FD +:10652000C5F30B0524F81250521C8A42F6DB1961A0 +:10653000986030BD70B504466948016802290AD1E7 +:10654000654D29788C4206D000EB8400D0F89C0081 +:1065500000F0CFFB2C7070BD10B5044690F82800F9 +:10656000800604D55F4800F0B1FBA4F88C0010BD94 +:1065700010B5044690F8280080060AD559482830FE +:1065800000F0A4FB24F88E0F5648483000F09EFB24 +:10659000608010BD10B5044690F82800800605D52F +:1065A0005048703000F092FBA4F88E0010BD704788 +:1065B0007047704702004FF0000000D10846704756 +:1065C00002460020012A00D1084670473F490A6868 +:1065D00092F8B020930910F83E2B63F3820200F882 +:1065E0003E2C0B6893F8B0305B0963F3451200F85A +:1065F0003E2C0968B1F8B720028291F8B620837F5B +:1066000062F30713837791F8B3201309027D63F3D4 +:106610000612027531F8B13F028B63F3090202835F +:1066200011F8012C9308827D63F3861282758A78B3 +:10663000C37D62F30303C375B1F80330B0F81B20C8 +:1066400063F30802A0F81B2009894182704710F803 +:10665000371F41F0100100F81F1930F80C2CC17ED3 +:106660006FF30B02103220F80C2C30F8082C21F0BC +:1066700023016FF30B02403220F8082C082200F8A7 +:10668000162C90F8472041F00C0122F01F0280F8F0 +:106690004720028B6FF308020283C176C18A6FF331 +:1066A0000B013F31C182417D21F01F014175017D08 +:1066B00021F01F01017590F8461021F0010180F8CA +:1066C0004610017C41F0200101747047B8071000AA +:1066D00000F0FFFF987C012078081000987E0120D0 +:1066E00064911000E07E0120704710B500F08BFD32 +:1066F00008B1012010BD084800F06EFD002010BD5B +:10670000064810B5006890F87000400701D500F009 +:106710006FFD012010BD00002D630100B8071000BF +:106720003D48016821F00401016000F0FDBE10B594 +:10673000FFF7F6FF10BD10B5FFF7F2FF10BD10B563 +:10674000FFF7EEFF10BD10B5FFF7EAFF01F02FFCD9 +:1067500010BD10B5FFF7E4FF00F0D8FA10BD10B57A +:10676000FFF7DEFF01F039FD10BD10B5FFF7D8FFD0 +:1067700001F09EFD10BD10B5FFF7D2FF01F003FE42 +:1067800010BD10B5FFF7CCFF01F06AFE10BD10B5CB +:10679000FFF7C6FF01F0E3FE10BD10B5FFF7C0FF25 +:1067A00001F04AFF10BD10B5FFF7BAFF01F0B1FFCD +:1067B00010BD10B5FFF7B4FF02F09EFA10BD10B582 +:1067C000FFF7AEFF02F074FA10BD10B5FFF7A8FF97 +:1067D00010BD10B5FFF7A4FF10BD10B5FFF7A0FF67 +:1067E00010BD10B5FFF79CFF01F0DAFF10BD10B52A +:1067F000FFF796FF10BD10B5FFF792FF10BD10B563 +:10680000FFF78EFF10BD10B5FFF78AFF10BD10B562 +:10681000FFF786FF10BD704710ED00E00EB50020B9 +:10682000009001900290094800F027FE684600F0B1 +:1068300028FEFCF723FEFCF779FC00F031F800217C +:106840004720FCF786F801200EBD00004500981097 +:106850001A4910B50120087019490020086019492B +:106860000860194908601949086000F07FF900F0D4 +:1068700019F900F07DF8002010BD10B5124802F0A3 +:1068800021F8104908600E490968884207D00B4872 +:106890000078022803D1BDE81040E9F767BD10BDBC +:1068A00010B5FFF7EAFF054902200870E9F742FD3D +:1068B0004FF0FF3010BD012070470000D4081000D9 +:1068C000D8081000DC081000E0081000E4081000F0 +:1068D00070B50D460446C1698068CC2202F080F98B +:1068E000E169A068002208444FF0807140F8041C60 +:1068F000216A40E9032140F8102C40F8142C40F89C +:10690000182C40F81C2C4FF00B3140E909154FF0C2 +:106910000A3140F8281C4FF0093140F82C1C4FF088 +:10692000083140F8301C4FF0073140F8341C4FF06C +:10693000063140F8381C4FF0053140F83C1C4FF050 +:10694000043140F8401D70BD81694FF0CC330A68B6 +:106950009A4208D14A689A4205D18A689A4202D17D +:10696000C968994202D04068FCF727BC7047000014 +:1069700010B5A021494802F05DF9002010BD70B5A6 +:106980000646464800EB0614E9F728FD0546207840 +:1069900028B12846E9F72AFD6FF0010070BD0320F9 +:1069A000207000206660E06004F1080001F064FFE0 +:1069B0002846E9F71BFD002070BD2DE9F0410F4688 +:1069C0003649002501EB00142E46E9F707FD804605 +:1069D000E0683843E06004F10800074601F072FF08 +:1069E0000CE0E168C26A114203D000F00FF9012601 +:1069F00000E06D1C2946384601F05AFF0028F0D10E +:106A00000EB1FFF73AFF4046E9F7F0FC0020BDE881 +:106A1000F08170B50D46214901EB0014E9F7DEFC69 +:106A2000E168A943E160E9F7E1FC002070BD70B5C1 +:106A30000C461A4901EB001500202060E9F7CEFC56 +:106A4000E9682160E9F7D2FC002070BD2DE9F04132 +:106A50000D4612491E46904601EB0014E9F7BEFCB4 +:106A600007460F480068C562E168294203D104F176 +:106A7000080100F0DDF83846E9F7B8FCE9F7AEFCAC +:106A8000E16829403160B8F1010F02D1E168A94302 +:106A9000E160E9F7ABFC0020B9E7000010921000BC +:106AA000D808100010B5C8212E4802F0C3F8002005 +:106AB00010BD2DE9F04106462A4900EB8600174635 +:106AC00001EB8004E9F78AFC0546207830B12846BE +:106AD000E9F78CFC6FF00100BDE8F0810220207026 +:106AE00000206660C4E9027004F1100001F0C4FEE9 +:106AF0002846E9F77BFC0020EEE770B5194900EB6A +:106B0000800001EB8004E9F769FC0546D4E9020145 +:106B1000814205DB144804F11001006800F088F898 +:106B2000E068401CE0602846E9F760FC002070BD8A +:106B300070B50C4900EB800001EB8004E9F74EFCD6 +:106B40000546E06808B1401EE06004F1100001F065 +:106B5000B9FE10B1206900F011F82846E9F746FCAB +:106B6000002070BDB0921000D808100010B54FF48E +:106B7000F0713C4802F05EF8002010BD10B50446EC +:106B800090F8240002280BD0204601F09DFE022040 +:106B900084F824003449204601F072FEFFF76DFEB0 +:106BA000002010BD2DE9F05F06460AA806EB46015D +:106BB00090E8000E2B481D4600EB0114904620780B +:106BC00018B16FF00100BDE8F09FE9F707FC074638 +:106BD00001202070C4F81480C4E9016504F1180193 +:106BE000002081E8200684F82400E0602061C4E9E8 +:106BF0000A8059462046FFF76BFEA0602046FFF74B +:106C0000BDFF3846E9F7F2FB0020DCE710B504468B +:106C100090F82400022809D0204601F055FE0220F9 +:106C200084F824001049204601F02AFE002010BDFF +:106C300070B5044690F824000D4602280BD120467A +:106C400001F042FE032084F824002946204601F08A +:106C500017FEFFF712FE002070BD04480068406870 +:106C60007047000078931000E0081000D80810006A +:106C7000724810B500210160012202600160704C71 +:106C80006920A0710420E9F7BBFB0820A07110BDAA +:106C900010B5FFF7EDFF6B4800210170416000F077 +:106CA000F6F9BDE8104000F0D8BA01F09EBC01F042 +:106CB00009BD10B501F006FD01F097FCBDE81040DC +:106CC000E6E7A422604901F014BF704710B50446FE +:106CD000800702D00220FFF7C8FA4FF4803020442A +:106CE000C0F34F0010BD014655489822A43001F072 +:106CF00000BF534AA432002142F82100491C262932 +:106D0000FADB704701F0BBBC01F039BC4D4810B54F +:106D1000406810B1BDE8104000470020FFF7A5FA19 +:106D200010BD062937D2DFE801F0112437243603DD +:106D3000017821F0120100F84D1B017821F00301C8 +:106D400000F8071B017821F080010CE0017821F0A8 +:106D5000020141F0100100F84D1B017821F0030100 +:106D600000F8071B12E000F8441B017821F0010134 +:106D700010E00278012942F01202027000D00321D3 +:106D800010F84D2F61F3010200F8072B017841F054 +:106D90008001E8E701707047017821F0020141F0BD +:106DA000100100F84D1B017821F00301891C00F847 +:106DB000071B017841F0800100F8441B017841F085 +:106DC0000101E7E790F82920022904D0032922F0E5 +:106DD000400102D104E042F0400121F0800101E0D5 +:106DE00041F0800180F82910704790F8292001298E +:106DF00004D0022907D022F0100101E042F0100176 +:106E000021F0200101E042F0300180F829107047A4 +:106E1000C278002961F30302C27004D010F85E1F2B +:106E200041F0040101707047C27A012961F3030245 +:106E3000C27202D942F01001C17270479004002260 +:106E4000000003208C0810001C99010001EB810157 +:106E500002EBC101405C010602D500F07F00404218 +:106E60007047002B04DA5B42DBB243F0800301E0A1 +:106E700003F07F0301EB810102EBC1014354704732 +:106E80002DE9F05F0025DDE90A7891469A468346B0 +:106E90002E462A460120002101F0E1FD00EA09000A +:106EA00001EA0A01084314D00024224601200021EF +:106EB00001F0D5FD384001EA0801084305D0002360 +:106EC000224631465846FFF7CCFF641C282CECDBE9 +:106ED000761C6D1C382DDCDBBDE8F09F405C0106A4 +:106EE00002D500F07F0040427047002A04DA524287 +:106EF000D2B242F0800201E002F07F0242547047B9 +:106F0000F0B5002415460E468446234601270FE0BF +:106F100006EBE30003F00701007807FA01F20242F2 +:106F200005D0002219466046FFF7DFFF641C5B1C9A +:106F3000AC42EDDBF0BD405C704742547047F0B5A9 +:106F40000024234601260DE001EBE30503F00707CB +:106F50002D7806FA07FC1CEA050F02D00025C5545F +:106F6000641C5B1C9442EFDBF0BD405C70474254F4 +:106F70007047405C70474254704700002DE9F0476D +:106F8000334C54F83C8F6768E668257CDFF8C49082 +:106F90000121C9F800104FF42070E9F731FA0021FF +:106FA000C9F80010C4F800806760E6602574BDE889 +:106FB000F08727480021C1630164816480F84C1088 +:106FC000704770B500240D4602460120214601F0AD +:106FD00046FD35B31E4A483210601171FFF7CEFFEF +:106FE000002000F023F800B10124FFF7C7FF0120C3 +:106FF00000F01CF808B144F00204FFF7BFFF0220C4 +:1070000000F014F808B144F00404FFF7B7FF0320C0 +:1070100000F00CF808B144F00804FFF7AFFF204679 +:1070200070BD0B4A3C32C2E90001D7E740F02001B5 +:10703000074810B580F8A310E52181714FF4207046 +:10704000E9F7DEF90448D0F8C002C0B210BD000074 +:107050000000032068146022001060224E4801687E +:10706000002901D001200847704710B5FFF71FFE27 +:107070004A49022008704A490020086046480168D1 +:10708000002903D0BDE810400020084710BD424948 +:107090000020086070477FB504460399089DC1F33E +:1070A00014010391082102A800F076FA012D02D004 +:1070B000022D04D006E0C01C20F0010002E0C01D3B +:1070C00020F00300DDE9021244F83C1F6260217ADF +:1070D00060F3060121727FBD012340F83C3F00238D +:1070E00043605143027A61F30602027270471FB592 +:1070F0000446039902A801F03F010391082100F022 +:107100004BFADDE90212A16484F84C2014F8701FD8 +:1071100060F3050104F81E19E17F60F30501E177D2 +:107120001FBD08B51FA2126800921DF8012010F8BB +:107130005D1F62F30101017008BD1849032008704A +:1071400017491948086019490120C1F8C0001849B9 +:107150004FF4FA70FFF7D6BD10B50A46817921F0D9 +:107160000D0141F0E00181710B490A600B4A0321D6 +:1071700011700B4A0C4911600146A4220D4801F020 +:10718000B8FC0A490120C1F8C000BDE81040084918 +:107190004FF4FA70FFF7B6BD940810008C08100089 +:1071A00090081000000102001B7001000000602226 +:1071B0000D7001000000032016480178012908D154 +:1071C000022101701448016819B1002202601046C2 +:1071D00008470120FFF749B80E4A012111700E49F6 +:1071E00008600E49E82088710D490C20FFF78CBD1E +:1071F0000A49082088710B49002008620549087077 +:1072000005490860704703480078002800D0012035 +:10721000704700008C081000980810000000032040 +:10722000697101000000602268480168002901D0EE +:1072300001200847704710B5FFF739FD6449022067 +:10724000087064490020086060480168002903D084 +:10725000BDE810400020084710BD5C4900200860D0 +:1072600070477FB504460399089DC1F3140103914B +:10727000082102A800F090F9DDE90212E16322641E +:1072800094F84420C1B261F3060284F844200A2D28 +:107290000FD00B2D0DD014F8720F61F30500207084 +:1072A000607861F305006070A07820F00800A0709D +:1072B0007FBD14F8721F401C60F3050121706178D6 +:1072C00060F305016170A07840F00800EFE71FB59A +:1072D0000446039902A801F03F010391082100F040 +:1072E0005BF9DDE90212A16484F84C2014F8701FE8 +:1072F00060F3050104F81E19E17F60F30501E177F1 +:107300001FBD30B534A28CB03CCA8DE83C0036A21B +:107310000DF1100C3CCA8CE83C0037A20DF1200C9A +:107320003CCA8CE83C0004AA535C427E63F305022D +:1073300042761DF80130027E63F34202027608AA0B +:10734000525C817962F3830181710CB030BD2049B8 +:10735000042008701F492C4808602C490120C1F8FE +:10736000C0002B494FF4FA70FFF7CCBC10B50A46A9 +:10737000B0F8561041F00101A0F85610017F21F03D +:107380000101017790F8221021F0010180F822100C +:10739000817921F0010141F0E00181710B490A601E +:1073A0000B4A042111700B4A174911600146A422AF +:1073B000184801F09EFB15490120C1F8C000BDE846 +:1073C000104013494FF4FA70FFF79CBC9C08100062 +:1073D0008C08100090081000000002020101030355 +:1073E0000303000200000000020202020202020285 +:1073F0000101020201010000020302030203020371 +:107400000203020202030000E77101000000602293 +:10741000D9710100000003204949012008601722AA +:10742000410701F8272F0B2281F8412044491839E0 +:1074300008604FF00851C1F8C403414B0022B0333B +:107440001A60404A1060121D10603D4A943A106064 +:10745000C1F8740370473A490120943908607047B5 +:10746000374900209439086070474FF00050008879 +:1074700070474FF00050807870474FF000514860DF +:107480007047314902680A6042684A6080688860D3 +:1074900070472D490A6802604A68426089688160C5 +:1074A0007047274901203039086070474FF000507D +:1074B00010F8221F21F00301017070474FF00053B4 +:1074C00003F81F0F5970987862F3030098707047A3 +:1074D0001E48006870471D490860704710B54FF09E +:1074E0000054E27E202322F0AF0203EA401313434C +:1074F000042202EA8000034301F003000343E37621 +:1075000010BD4FF0005090F8220010F0030005D09D +:10751000012805D0022805D00D4870470D48704756 +:107520000D4870470D487047704770470C4901205F +:10753000C1F8DC0070470A490020C1F8DC00704740 +:10754000CC040022801E002208000020A0081000A9 +:1075500000127A000090D0030048E8010024F400F3 +:1075600000006022F0B50746002003462F4E10E0D1 +:1075700057F8235003224FEAC20C45FA0CF484EA70 +:107580002064E4B2521E56F8244084EA0020F2D56A +:107590005B1C8B42ECDBF0BD30B50446234B002076 +:1075A000103B08E0625C02F00F0503EB12125D5D18 +:1075B000127828441044491EF4D230BD10B58468B6 +:1075C0000368E443A3420AD1C4684368E443A34286 +:1075D00005D15B1C0B6000681060012010BD00200D +:1075E00010BD3CB50446002501AA6946FFF7E6FF39 +:1075F000012809D1009904F11000091FFFF7B2FF1B +:107600000199884200D1012528463CBD30B50D4680 +:107610000446091F1030FFF7A5FF6D1E6560E943A2 +:10762000E1602060C043A06030BD0000D09901003F +:1076300001468000B1F5803F02D21038C0F310003F +:107640007047C0F387207047B0F5802F02D210300A +:10765000C0F31000C0F38F00704730B5FE4C012519 +:107660002560E50603F01F0385F86B30002304E076 +:1076700051F8235040F823505B1C9342F8DB002064 +:10768000206030BDF0B5F44F01233B605C0784F807 +:107690006B309B1E0360002312E051F8234040F83A +:1076A0002340002450F8235051F82360B54206D0FF +:1076B0006D1C04D1641C40F82360032CF2D35B1CC6 +:1076C0009342EADB00203860F0BDF0B513460A466D +:1076D0000546002498184FF48326602801D9012418 +:1076E00011E0002107E05F1856F82700401C01D088 +:1076F00011460224491C9142F5D324B906EB8300BC +:107700002946FFF7BFFF2046F0BD10B503460846E7 +:10771000FFF78EFF0146BDE810409200184601F0C9 +:107720002DBA2DE9F0414FF000580C46D8F81470EE +:107730000125C0F38F066FF48041C8F814100E20A5 +:1077400000F012FA204600F01AFA0200C3484FF087 +:10775000010119D00160A4F580344046A8F8726098 +:10776000A8F87440602288F87120BD4A1160BB4AB5 +:10777000C432116030BF98F87810890700D0002516 +:1077800047612846BDE8F08100220260E5E72DE967 +:10779000F05F1546DFF8C0B2002601270A4604460E +:1077A0004FF0005CB1F5882F15D3A30AFFF740FF17 +:1077B0005946CBF8007003F01F038CF86B300023A0 +:1077C00004E052F8234040F823405B1CAB42F8DB56 +:1077D0000E60BDE8F09FDCF81490C1F38F08E2461C +:1077E0006FF48041CCF814100E2000F0BDF9CBF8F6 +:1077F0000070204600F0C3F90100984817D00760D8 +:10780000A4F58034AAF87280AAF874406D1EAAF814 +:10781000765040218AF8711091490E608F49C43129 +:107820000F6030BFCBF80060CAF81490D1E7066053 +:10783000E8E72DE9F0414FF000540F4654F8146F7B +:1078400085086FF4804020600E2000F08DF9002044 +:10785000A066A4F85E507F1EA4F8627084F85D00F4 +:107860007F4908607D490120C431086030BFE06E67 +:10787000266087E770B506460C4601F11000111F1F +:10788000154689B2FFF7D5FF2060681E606020684A +:107890002A46C043A06060682146C043E06030468D +:1078A000BDE8704073E7F0B50746002004466D4E12 +:1078B00015E057F8245003234FEAC30C45FA0CF2A5 +:1078C00080EA02600822002802DA86EA400000E02E +:1078D0004000521E002AF6DC5B1EEDD5641C8C4273 +:1078E000E7DBF0BD30B550F8084B50F8085B30F8D6 +:1078F0000C1C491C89B2FFF7D6FF844204D1E04337 +:10790000854201D1012030BD002030BD2DE9F0417C +:107910000126750704466F696FF4804068610E2088 +:1079200000F022F94FF00008C5F87C80204600F0F6 +:1079300026F9020049494FF0010015D00860A4F56E +:107940008034A5F87440202185F8711044490860FE +:107950004249C431086030BF95F87800800700D0F4 +:1079600000266F6130460DE7C1F80080E9E700B5F9 +:107970000B46FFF75DFE82680168D243914208D151 +:107980004268C068C043824203D1521C1A80012061 +:1079900000BD002000BDF8B5044610300D46064677 +:1079A000FFF7BFFE012801D00020F8BD6946284638 +:1079B000FFF7DDFFBDF80000001F81B23046FFF782 +:1079C00038FF2060BDF80010C043491E6160A06010 +:1079D000C843E0600120F8BDF0B5B1B007466D4680 +:1079E000214E0124C021284601F024F9002056F838 +:1079F000201045F82010401C3028F8D31B4900986F +:107A0000884210D1029881B205A80446FFF74BFFC7 +:107A10000199814206D1AC222146384601F0AEF8E8 +:107A2000002400E0032431B02046F0BD70B594B0CE +:107A300004466D460E4E5021284601F0FBF800200A +:107A400056F8201045F82010401C1428F8D3094897 +:107A50006FF0020500990FE0C41B0022780D002290 +:107A60001C0F00221B000080481D0400B2570E703E +:107A7000AC1E04005C000D6081422ED1A810206075 +:107A80006060A060E0602061029881B205A8FFF705 +:107A90000AFF0199814220D1BDF8381045F2AA5061 +:107AA00081420CD19DF81D1021609DF81C1001F041 +:107AB0000F0161609DF81E1001F00F01A160BDF87B +:107AC0003C10814201D10899E160BDF8401081422B +:107AD00001D10998206114B070BD25606560A56072 +:107AE000E5602561F7E770B586B004466D46274E20 +:107AF0001421284601F09EF8002156F8210045F88F +:107B00002100491C0529F8D3009820600198606085 +:107B10000298C0B2A0600398C0B2E0600498C0B2FE +:107B2000206106B070BD1CB50020184A0090843A50 +:107B30006B460146019052F8214043F82140491C10 +:107B40000229F8D3BDF80010A1F5AA42AA3A0AD139 +:107B5000BDF80420114206D19DF802109DF80620C0 +:107B6000114200D108461CBD00F01F0201219140C6 +:107B70004009800000F1E020C0F880127047B0F5A5 +:107B8000803F01D20020704701207047601F040031 +:107B90004FF00050002180F83D1080F83E1080F832 +:107BA0003F103F2280F8322000F8301F02714171EF +:107BB0004270017241728172C172C1717047894A0B +:107BC0001160884A002134321160121D08B1116021 +:107BD000704701201060704730B501248440E0B246 +:107BE0004FF000540029039D94F8321001D0014356 +:107BF00000E0814384F8321094F830100AB1014358 +:107C000000E0814384F8301094F834100BB1014344 +:107C100000E0814384F8341014F8351F0DB101439E +:107C200000E08143217030BD4FF00052062817D28A +:107C3000DFE800F00306090F171A12F83D0F04E001 +:107C400012F83D0F07E012F83E0F20F00F00084336 +:107C500005E012F83E0F20F0F00040EA011010702D +:107C6000704712F83F0FF0E712F83F0FF3E70123D8 +:107C70008340D8B24FF00053002993F8381001D058 +:107C8000014300E0814383F8381013F8391F0AB12B +:107C9000014300E081431970704701238340D8B24B +:107CA0004FF00053002993F83A1001D0014300E04F +:107CB000814383F83A1013F83A1F0AB1014300E0F8 +:107CC0008143197070472DE9F04705460120A8400F +:107CD000C4B21F46914688460A20DDF820A000F075 +:107CE0006BF80B2000F068F80A2000F070F80B2009 +:107CF00000F06DF84FF0005696F83800A04386F873 +:107D0000380096F83A00A04386F83A0096F82E001C +:107D1000A04386F82E00344A0020B8F1000F42F844 +:107D200025000BD096F83810214386F8381096F8C5 +:107D30003A10214386F83A1042F8257096F8391027 +:107D4000A14386F8391096F83B10A14386F83B1002 +:107D500096F82F10A14386F82F1023492031B9F14E +:107D6000000F41F825000BD096F83900204386F823 +:107D7000390096F83B00204386F83B0041F825A0E7 +:107D800096F8380010B10A2000F00BF896F8390088 +:107D9000002804D0BDE8F0470B2000F002B8BDE891 +:107DA000F08700F01F02012191404009800000F19E +:107DB000E020C0F80011704700F01F02012191403F +:107DC0004009800000F1E020C0F88011704700F009 +:107DD0001F02012191404009800000F1E020C0F81D +:107DE0008012704704050022589510002DE9F047D5 +:107DF000417ACA074FF0000101D0554A516001276E +:107E00007D0785F8E57085F8E470C5F8C010C5F801 +:107E1000E81085F8E11085F8E310DFF838A1067A5C +:107E200004680AF10709072E00D9072600216DE032 +:107E30004A1CD3B201EB810214F802800AF80180D7 +:107E4000D0F804C022443CF8118029F8118092F83F +:107E500003C0BCF1010F02D0BCF1030F07D195F8AC +:107E6000E5C007FA03F84CEA080C85F8E5C090F87D +:107E700009C05FEACC7C0FD192F803C0BCF1020FBD +:107E800002D0BCF1030F07D195F8E4C007FA03F85C +:107E90004CEA080C85F8E4C001EB410C21F0010824 +:107EA000E04492F801C00CF0070C0CFA08FCD5F87D +:107EB000C0804CEA080CC5F8C0C092F802C04FEA76 +:107EC00081080CF00F0C0CFA08FCD5F8E8804CEA9D +:107ED000080CC5F8E8C090F809C05FEACC7C14D162 +:107EE0001279D20707D095F8E12007FA03FC42EA9D +:107EF0000C0285F8E1202279D20606D595F8E32018 +:107F000007FA03F31A4385F8E320491CB1428FD3E3 +:107F1000D5F8E8006864BDE8F0870E4AD21D22F863 +:107F20001010704710B504460B48006838B1A068BF +:107F3000FFF75CFF2068BDE8104000F00FB8E06874 +:107F4000FFF754FF6068BDE8104000F0D3BC0000AC +:107F500000200022AB000020BC05002210B54F4BD2 +:107F60000168002499608188598002899A801C7078 +:107F70004FF00053A3F81A21A3F81E11C088A3F8EC +:107F8000200147480122C0F8D821C0F8DC21C0F800 +:107F9000C421C0F8CC21C0F8D421C0F8802172B629 +:107FA000D0F808120029FBD1426062B610BD2DE95D +:107FB000F0413B4DD5F85C01384F2E040124BA68DE +:107FC00050B3B6F81C815FEA08000FD0D5F8540111 +:107FD00010B9D5F8000148B1414601209047C5F8D5 +:107FE000D842D5F8540108B1C5F8D442BA68414620 +:107FF000022090470178022902D0032902D008E02C +:10800000418800E07988A6F81E118088A6F81A0138 +:108010003C70C5F8DC4238E0D5F8440180B1B6F8D0 +:108020001C1103209047387838B17888A6F81E01D3 +:10803000B888A6F81A0100203870C5F8C44224E0B8 +:10804000D5F8580130B1B6F81C1101209047C5F899 +:10805000D8421AE0D5F84C0128B9D5F8540110B926 +:10806000D5F8000188B1B6F81C1119B1012090476C +:10807000C5F8D842D5F84C0110B1C5F8CC4204E09F +:10808000D5F8540108B1C5F8D442D5F8000100284C +:1080900001D0C5F88042BDE8F0810000A4081000BE +:1080A00000200022F64900200860091D0860091D13 +:1080B0000860091D0860091D0860091D0860091D88 +:1080C0000860091D0860EF4901220A60ED4914317A +:1080D0000860510701F8500FFF234B7001F8050CA1 +:1080E00010234B808A80E849086048608860C86037 +:1080F000086148618861C861086270477047E24A58 +:108100001160DF4900220A6000EB80004FF6FF7229 +:1081100002EA40004FF00052A2F858000120086027 +:108120007047D94B10B5D64A1960002111604FF045 +:10813000005191F85140E40707D01B6A5843800969 +:10814000A1F858000120106010BD00EBC00303EB44 +:1081500000104FF6FF7303EA8000F1E74FF0005084 +:10816000B0F8580070474FF0005090F82200C0F36C +:10817000810028B1012805D0022805D0C3487047E6 +:10818000C3487047C3487047C348704770B54FF045 +:10819000005494F85100BA49C2074FF0000001D0D2 +:1081A000086070BD656972B6626942F0040262617E +:1081B0000860B4F8581009B1A4F85800FFF7A1F905 +:1081C0000146FFF7D0FFB1FBF0F0E8F719F9656160 +:1081D000022000F03BFB62B670BDAB4810B5002139 +:1081E00004680160FFF7D2FF1CB1A446BDE810404F +:1081F00060470020FFF782FF10BDA34A5160A049ED +:108200000022091D0A6000EB80004FF6FF7202EAAF +:108210004000CA06A2F85A000120086070479A4B35 +:1082200010B55960964A0021121D1160D10691F8CF +:108230005140A40708D400EBC00303EB00104FF635 +:10824000FF7303EA800002E01B6A58438009A1F82B +:108250005A000120106010BD4FF00050B0F85A00D5 +:10826000704770B54FF0005494F851008B49820765 +:108270004FF000001AD4656972B6626942F00802D4 +:1082800062610860B4F85A1009B1A4F85A00FFF707 +:1082900038F90146FFF767FFB1FBF0F0E8F7B0F8F7 +:1082A0006561032000F0D2FA62B670BD086070BD4F +:1082B000754810B5002144684160FFF7D2FF1CB13A +:1082C000A446BDE8104060470120FFF717FF10BD2E +:1082D0006D4A916071490022091D0A6000EB80001F +:1082E0004FF6FF7202EA40008A06A2F85C00012005 +:1082F00008607047644B10B59960684A0021121DF0 +:108300001160910691F85140640708D400EBC00356 +:1083100003EB00104FF6FF7303EA800002E01B6AD4 +:1083200058438009A1F85C000120106010BD4FF097 +:108330000050B0F85C00704770B54FF0005494F8EE +:108340005100574942074FF000001AD4656972B6D0 +:10835000626942F0100262610860B4F85C1009B111 +:10836000A4F85C00FFF7CDF80146FFF7FCFEB1FB77 +:10837000F0F0E8F745F86561042000F067FA62B6AE +:1083800070BD086070BD404810B5002184688160F0 +:10839000FFF7D2FF1CB1A446BDE8104060470220A1 +:1083A000FFF7ACFE10BD384AD1603D490022091DDF +:1083B0000A6000EB80004FF6FF7202EA40004FF0C7 +:1083C0000052A2F85E000120086070472E4B10B5E5 +:1083D000D960334A0021121D11604FF0005191F80D +:1083E0005140240708D400EBC00303EB00104FF604 +:1083F000FF7303EA800002E01B6A58438009A1F87A +:108400005E000120106010BD4FF00050B0F85E001B +:10841000704770B54FF0005494F85100214902079D +:108420004FF000001AD4656972B6626942F020020A +:1084300062610860B4F85E1009B1A4F85E00FFF74D +:1084400060F80146FFF78FFEB1FBF0F0E7F7D8FFC9 +:108450006561052000F0FAF962B670BD086070BD74 +:10846000094810B50021C468C160FFF7D2FF1CB1F4 +:10847000A446BDE8104060470320FFF73FFE10BD53 +:1084800040090022C0040022B008100000093D008D +:108490000048E8010024F40000127A004409002298 +:1084A000480900224C090022EE4A1161EE490022DF +:1084B0000A6000EB80004FF6FF7202EA40004FF0C6 +:1084C0000052A2F86000012008607047E54B10B52B +:1084D000E54A1961002111604FF0005191F85140B7 +:1084E000E40608D400EBC00303EB00104FF6FF7363 +:1084F00003EA800002E01B6A58438009A1F860008B +:108500000120106010BD4FF00050B0F860007047BF +:1085100070B54FF0005494F85100D349C2064FF0A3 +:1085200000001AD4656972B6626942F04002626165 +:108530000860B4F8601009B1A4F86000FEF7E1FF2C +:108540000146FFF710FEB1FBF0F0E7F759FF656158 +:10855000062000F07BF962B670BD086070BDC148AE +:1085600010B5002104690161FFF7D2FF1CB1A446D8 +:10857000BDE8104060470420FFF7C0FD10BDB94AB8 +:108580005161B9490022091D0A6000EB80004FF6D5 +:10859000FF7202EA40004FF00052A2F86200012090 +:1085A00008607047AF4B10B55961AF4A0021121DEA +:1085B00011604FF0005191F85140A40608D400EB2F +:1085C000C00303EB00104FF6FF7303EA800002E0E4 +:1085D0001B6A58438009A1F862000120106010BD99 +:1085E0004FF00050B0F86200704770B54FF0005483 +:1085F00094F851009D4982064FF000001AD4656935 +:1086000072B6626942F0800262610860B4F862107A +:1086100009B1A4F86200FEF774FF0146FFF7A3FD5D +:10862000B1FBF0F0E7F7ECFE6561072000F00EF912 +:1086300062B670BD086070BD8A4810B500214469FB +:108640004161FFF7D2FF1CB1A446BDE8104060476E +:108650000520FFF753FD10BD824A91618349002236 +:10866000091D0A6000EB80004FF6FF7202EA40002D +:108670004FF00052A2F86400012008607047794B67 +:1086800010B59961794A0021121D11604FF0005117 +:1086900091F85140640608D400EBC00303EB0010CE +:1086A0004FF6FF7303EA800002E01B6A584380091B +:1086B000A1F864000120106010BD4FF00050B0F828 +:1086C0006400704770B54FF0005494F85100684949 +:1086D00042064FF000001AD4656972B6626942F42E +:1086E000807262610860B4F8641009B1A4F8640093 +:1086F000FEF707FF0146FFF736FDB1FBF0F0E7F7A5 +:108700007FFE6561082000F0A1F862B670BD0860C8 +:1087100070BD544810B5002184698161FFF7D2FF14 +:108720001CB1A446BDE8104060470620FFF7E6FCF8 +:1087300010BD10B5FEF7CCFE4FF0005191F822208D +:1087400042F21073B0FBF3F0C2F38102521CD0402E +:10875000B1F85420C96C51438909B0FBF1F010BD48 +:1087600043490022091D0A603E4A126A50434FF0F5 +:1087700000528009A2F866000120086070473C4959 +:108780000020091D086070473649C8613949012039 +:10879000C1F8DC003649A0310860091D0860704747 +:1087A000304A10B50020D169D061324AC2F8DC00ED +:1087B00051B12F4AA03210604FF00050C06CBDE89C +:1087C000104020F07F400847FF20FFF797FC10BDC6 +:1087D00010B50446FEF77CFE4FF0005191F82210D0 +:1087E00042F21072B0FBF2F0C1F38101491CC840A3 +:1087F0000003B0FBF4F01B49086210BD30B54FF028 +:1088000000550124844095F8510009B1204300E04F +:10881000A04385F8510095F84B000AB1204300E0D1 +:10882000A04385F84B0015F8500F0BB1204300E032 +:10883000A043287030BD4FF0005010F84A1FC07997 +:10884000814301D0012070470020704700F01F02D3 +:10885000012191404009800000F1E020C0F8801221 +:1088600070470000B008100050090022540900228F +:10887000580900220000602200210160084670476C +:1088800030B50A6812B10B46846A08E0002208601D +:10889000C0E903210AE002F10C03D26812B1956A23 +:1088A000A542F8DC1A68C0E903211860002030BD39 +:1088B0000068002201E0C068521C8A4201D00028F2 +:1088C000F9D170470068704702690AB1116831B97F +:1088D0006FF00400704701F10C02C96839B18142A0 +:1088E000F9D1C968116000210161084670476FF035 +:1088F00003007047017C31B14FF0005111F82D2F6A +:1089000042F002020A70194902680A6042684A602D +:1089100082688A60C068C860704730B44FF0005108 +:1089200011F8E00F0A8AC968104BC40704D09B688D +:10893000002B07D030BC1847DB68002B02D0521C3C +:1089400092B2F7E730BC70474FF0005090F8E20069 +:108950000649C20704D08A68002A06D0096803E0E5 +:10896000CA68002A01D0496808477047E808100023 +:1089700053EA020C00F069802DE9F04B4FF000063D +:10898000002B1FBFB3FA83F503FA05F424FA05F6AA +:108990005E4012BF1643B2FA82F502FA05F4C5F141 +:1089A00020051EBF22FA05FC44EA0C04203556EAD5 +:1089B000044C4FEA144418BF641C4FF000084FF0F9 +:1089C0000009904271EB030C39D3002919BFB1FAA9 +:1089D00081F701FA07F6B0FA80F700FA07F6C7F157 +:1089E00020071EBF20FA07FC46EA0C062037B6FB1C +:1089F000F4FCA7EB0507103F07F01F0BCBF1200697 +:108A00000CFA0BFB2CFA06F644BFB3460026202FC7 +:108A1000A4BF5E464FF0000B5BEA060C08BF4FF0A8 +:108A2000010B19EB0B09ABFB027C48EB0608C01BE2 +:108A300006FB02CC0BFB03CC71EB0C01C1E70B4630 +:108A4000024641464846BDE8F08B13B54FF00000A2 +:108A50004FF00001AFF30080BDE81C407047B2F159 +:108A600020030AD5C2F1200301FA02F120FA03F330 +:108A700000FA02F041EA0301704700FA03F14FF0F7 +:108A800000007047B2F120030AD5C2F1200320FA9A +:108A900002F001FA03F321FA02F140EA0300704701 +:108AA00021FA03F04FF00001704710B54C1084EA32 +:108AB000530404D54042C1F1000138BF491E1B4296 +:108AC00004D55242C3F1000338BF5B1EFFF750FFCD +:108AD00014F0804F04D04042C1F1000138BF491E5C +:108AE00014F0004F04D05242C3F1000338BF5B1EA4 +:108AF00010BD032A40F2308010F0030C00F0158006 +:108B000011F8013BBCF1020F624498BF11F801CB90 +:108B100000F8013B38BF11F8013BA2F1040298BFF5 +:108B200000F801CB38BF00F8013B11F0030300F05F +:108B30002580083AC0F0088051F8043B083A51F803 +:108B400004CBA0E80810F5E7121D5CBF51F8043B08 +:108B500040F8043BAFF30080D20724BF11F8013B7B +:108B600011F801CB48BF11F8012B24BF00F8013BDD +:108B700000F801CB48BF00F8012B704710B5203A30 +:108B8000C0F00B80B1E81850203AA0E81850B1E8C6 +:108B90001850A0E81850BFF4F5AF5FEA027C24BF7C +:108BA000B1E81850A0E8185044BF18C918C0BDE873 +:108BB00010405FEA827C24BF51F8043B40F8043B3C +:108BC00008BF7047D20728BF31F8023B48BF11F8F1 +:108BD000012B28BF20F8023B48BF00F8012B70474B +:108BE00002F0FF0343EA032242EA024200F002B825 +:108BF0004FF000020429C0F0128010F0030C00F0C6 +:108C00001B80CCF1040CBCF1020F18BF00F8012B43 +:108C1000A8BF20F8022BA1EB0C0100F00DB85FEA11 +:108C2000C17C24BF00F8012B00F8012B48BF00F8DD +:108C3000012B70474FF0000200B51346944696464C +:108C4000203922BFA0E80C50A0E80C50B1F120015F +:108C5000BFF4F7AF090728BFA0E80C5048BF0CC00D +:108C60005DF804EB890028BF40F8042B08BF70476B +:108C700048BF20F8022B11F0804F18BF00F8012BDD +:108C8000704710B50446AFF300802046BDE81040A1 +:108C9000E7F7C4BA01491820ABBEFEE72600020080 +:108CA0007047000001490020086070473805002225 +:108CB0002DE9F0410F4F00244FF001084FF000560E +:108CC00008FA04F0C5B296F82F0028420CD096F8A6 +:108CD0003900284208D057F8240000B1804796F8A0 +:108CE0002F00A84386F82F00641C062CE8DBBDE8A3 +:108CF000F0810000789510002DE9F0410F4F00241D +:108D00004FF001084FF0005608FA04F0C5B296F88B +:108D10002E0028420CD096F83800284208D057F888 +:108D2000240000B1804796F82E00A84386F82E0054 +:108D3000641C062CE8DBBDE8F081000058951000AB +:108D400001218140C8B24FF0005191F83310014227 +:108D500001D0012070470020704700000149012028 +:108D6000086070473805002200487047FD07100072 +:108D70000549044A0A80054AC0E90021012101721F +:108D80004172704778660120A0071000E497010047 +:108D90000748417849B1807838B106488079012880 +:108DA00003D105480078012800D00020704700005A +:108DB000E8071000800710000805100003484178FC +:108DC00011B98078002800D001207047E807100012 +:108DD0000148007870470000E80610000548417817 +:108DE000827811440278C0781044081800D001201D +:108DF00070470000A40610000749B0F90000B1F95F +:108E00002020824203DCB1F92210814201DA0120E4 +:108E10007047002070470000442A100070B5D0E968 +:108E200000214C084FEA3203961841EB0105334309 +:108E30002C4313430C43C0E9003470BD01EB8101A6 +:108E400000EBC10029307047024A1278514300EB11 +:108E5000410070475207100001EB810100EBC10097 +:108E600029307047024A1278514300EB41007047A5 +:108E70005207100010000000040000000100000074 +:108E8000FF0000000000FF7F0000FF7FF7FE2BFFC8 +:108E900060FF95FFCAFF000036006B00A000D50000 +:108EA0000901DD03EA03F303FA03FF030004FF03F0 +:108EB000FA03F303EA03DD03497E0000DF7E0000CE +:108EC000577F0000E17F00007780000032312E28BC +:108ED00021190F05FBF1E7DFD8D2CFCECFD2D8DFF3 +:108EE000E7F1FB050F1921282E31000A141D252B4F +:108EF000303232302B251D140A00F6ECE3DBD5D0DE +:108F0000CECED0D5DBE3ECF606312E2821190F05A5 +:108F1000FBF1E7DFD8D2CFCECFD2D8DFE7F1FB0528 +:108F20000F1921282E3132F6ECE3DBD5D0CECED08E +:108F3000D5DBE3ECF6000A141D252B303232302B42 +:108F4000251D140A0006CFD1D4D7D9DCDFE4E8EC24 +:108F5000EFF3F6FAFF04070A0C10151A2022242654 +:108F600027292D30DCE8F4000C1A273023170BFEDC +:108F7000F2E6DADCE7F3010F1B2727190CFFF2E614 +:108F8000D9CE09D7D3D0CFCFCFD2D7DEE9F2F8FCF4 +:108F9000FDFE0003080D141E28303333302C26212B +:108FA0001AD3DBE7F3FE091520282922180CFFF35A +:108FB000F1FC07111B1F1A1106FBF0E5DAD0C709F7 +:108FC000CCCED0D1D1D2D4D6D9DDE2EAF0F6FB03B3 +:108FD0000A11181F2226292C2E3031313131C4CCF0 +:108FE000D5DEE8F2FD060F1821231A10090D151C15 +:108FF000242921181007FFF4EBE1D8CE09D1D4D6EB +:10900000D9DBDFE3E8ECEFF4F7FBFE010405080A27 +:109010000C0F1214171D22272C3033E9F5020D18FE +:1090200022261B1004F8EBE0D3C8CED9E6F2FF0BE2 +:1090300015212C251A0F05FBEF09CED0D1D3D5D69B +:10904000D7DBE2E8EDF2F7F9FBFF04080D12192077 +:10905000272B2C2E2F2F30303125180CFEF1E5DB7D +:10906000E7F4FF0B1621261A0F04F8EEE2D8CFDA48 +:10907000E6F3FF0B172208DDD6D2D0CECDCED3DD5E +:10908000EBF4F9FCFDFDFDFE01060D16232C2F2F40 +:109090003031313130352A1F1306FBEDE1DADFEADA +:1090A000F603111D1305FAEDE1D8D4DDE9F704103C +:1090B0001C283408D7DBDCDDDEDEDEDEDEDEE0E4CD +:1090C000E9EFF90106080A0C11171C252F37393A68 +:1090D0003A3AD1DFEBF80717253226190BFDF0E6F7 +:1090E000E4EEFA0715190DFFF4E8E1E9F5041320A1 +:1090F00008CDCBCCD0D4DAE3EAEEF1F4F5F5F6F80E +:10910000FAFE030A121C25282B2D2E2E2E2E2E2879 +:109110001E1308FDF5F2FB050F1C261B0E03F7EAD4 +:10912000DDD3CBCAD3DDE9F706141E262D08D4DD26 +:10913000E7EBE8E4E0DEE3E8EDF3FA0000FFFCFD36 +:1091400002070D121C20201F1F222C38DACFD6E771 +:10915000FC0F222D1B09F7E4D7E6FA0F232210FD9E +:10916000ECDBD0E2F60B1F333322082C23190E065A +:10917000FDF6EFE9E4E1DEDEDEDFE0E2E5E8EDF278 +:10918000F9020A0F1720282D32CDCCCCCDCFD3D663 +:10919000DBE0E6EBF1F6FC01070C12171C2025289A +:1091A0002A2C2C2C2C2A2907332D261D150D04FAC8 +:1091B000F0E7E0DAD6D3D2D2D4D8DEE6EFF9040F66 +:1091C00019222B303437DDD8D3D0CECECFD1D5DB5A +:1091D000E2EAF3FA030C151D24292D2F2F2E2C293A +:1091E000251F1A1507DFEBF6030E1821282A251A6A +:1091F0000CFFF2E7DFD8D4D2D2D7DFE9F4010E1C9E +:109200002934340C0C0A04FFF7EEE4D8CFCBCACED5 +:10921000D3DBE3EDF7040F1B252C2F302E29231D64 +:109220001D0ACAD4DEE8F2FD07121D262E2C2218D4 +:109230000D03F9F0EAE4E2E1E4ECF5000B17212A72 +:1092400006060300FDFAF6F3EFEAE1D5D0D0D2D559 +:10925000DBE4EEFA0817242E33353532302A0ADFE4 +:10926000E6F2FF0C17232E383830271D1005FAEED2 +:10927000E5DDD5D2D3D6DDE6EFFB06111E000102F7 +:1092800002020100FFFAEFE5DED8D5D4D5D9DEE839 +:10929000F3FE091520272D323537370AEFECECECB9 +:1092A000ECEDEDEDEDEDEDEDEDEDEDEDEDEFF1F8DE +:1092B00000081018202A323B434CC0C4C9CED3D872 +:1092C000DFE5EAF0F5FB0004090F14191E21212146 +:1092D000201E1E1C1B1A1A1A0B0E0C0C0C0C0D0E49 +:1092E0000F1011111211100D04F7EBE1D9D3CFCFEC +:1092F000D8E5F40211202FC7CDD4DAE1E7EEF4FB74 +:1093000001070E141B212726221E18120C0500FE31 +:10931000FDFCFCFCFD0C39352A1D0E01FBFAFAFCA4 +:10932000FF00030507080805FEF0E6DED9D7DAE4FA +:10933000F0FF0D1BDED7D2CFCFD2D9E0E8EFF6FE9B +:10934000040C131A22292F2F29231C150D0804029F +:1093500002010CD0D3D6DADDE1E4E7EAEBEEF0F37C +:10936000FAFE02070A0D1114171B1E2124282C2FA8 +:1093700032DBE1E8F0F6FE060C141A21282E2E2826 +:10938000221A140F0903FEF8F2ECE7DFD8D2CB0D56 +:109390001B0DFCEEE5E1EFFD060E110F111F2A2F4C +:1093A0002C210FFDECDED3CDCFDBECFE0E1BF4E960 +:1093B000EDFA0A1D251808F7ECFF121606F4E0D1A5 +:1093C000CBCED7E3F30417262D2D25180E20160B30 +:1093D000FFF2E8E1DFE0E6EEF903101D2730322E60 +:1093E000281F160CFFF2E7DFD8D4D0D4D0CECDCFD3 +:1093F000D4DAE2E8EEF3F7FAFD01050B11171D23AD +:10940000272A2C2C29241F19130FF7F0E8E0DAD5AE +:10941000D2D1D1D4D9E0E8F1FA030D1720282E32A9 +:1094200032302C2720191007CFD1D4D8DBDFE3E767 +:10943000ECF0F4F7FAFD00020407090C1014181CF4 +:109440002124282B2E310FD3DEE9F3FE0A16202C1F +:10945000362D261E150D04FDF4EDE4DBD4D4DEE933 +:10946000F5000C161ED7D6D4D4D3D3D3D4D4D7DE9C +:10947000E4EBF3F900060E141C232A3032333434A3 +:1094800035363510000B162028251F18110A01FA51 +:10949000F3ECE5DFD9D3CCD0DAE4EFF9040E1823EE +:1094A0002323CACACACBCED5DAE0E5EBF3F9FF0431 +:1094B0000A10151B212423211F1E1D1C1C1C1C1CF3 +:1094C00010EDF4FC040E1720211B130C04FEF6EE25 +:1094D000E7E0D9D2D6DFE9F2FB040D16202933CE1E +:1094E000CECDCCCBCCCED8E0E7EDF4FA00050C1312 +:1094F0001A222A2B2A292828282929282810DEE0A0 +:10950000E6EDF3FB01080F161D242A31332C241C31 +:10951000150D05FDF6EEE5DDD6CEC7C9CDCCD0D50F +:10952000D8DCE0E4E7EBEEF2F6FB0206090D0F13E0 +:1095300015181B1E202326292D28122E29211A1426 +:109540000C05FEF6F0E9E2DAD2D0D6DDE3EAF0F679 +:10955000FB01070C12181E2427CFD2D6D9DBDFE27D +:10956000E4E7EAEDEFF2F6FCFF0205080C1014192F +:109570001D22282C30332F112C292723201D1A17A8 +:109580001413110F0C0602FEFAF7F4F0EEEBE7E409 +:10959000E2DFDBD7D5D2221D160F0902FAF5EEE87D +:1095A000E2DBD6D6DBE1E8EEF2F502070D12171E7C +:1095B000252A310013D2D5D7DBDFE2E4E7EBEEF06A +:1095C000F4F7FAFE02060C0F111314171A1D2023CC +:1095D00027292C312A251E17120D0702FDF8F2EE5D +:1095E000E8E1DBD6D6DBE2E8EEF5FA02090F161D5C +:1095F0002213BE94FEFF27C4FEFF59F2FEFF6B1F2D +:10960000FFFF814BFFFFC576FFFF67A1FFFF97CBF1 +:10961000FFFF88F5FFFF6C1F000076490000D9733B +:109620000000C69E00006DCA0000FCF600009A24EF +:10963000010066530100A38D0000717400000260F8 +:109640000000A24F0000C84200000C390000213287 +:109650000000D22D0000002C00009B2C0000A92F40 +:109660000000403500008B3D0000CB4800005957FA +:109670000000AD69000065800000301100004C1C46 +:1096800000002D2900008637000024470000E8571D +:109690000000C4690000B57C0000C490000003A66F +:1096A00000008FBC00008CD4000029EE00009C0953 +:1096B00001002B27010024470100E66901009808FA +:1096C0000000260E000097140000C31B0000922328 +:1096D0000000F42B0000E23400005A3E0000624813 +:1096E000000002530000485E0000466A0000147744 +:1096F0000000CE8400009593000092A30000F3B414 +:10970000000001000200010002000400020001004C +:10971000020001001000FFFFFFFFFFFFFFFF14002A +:10972000FFFFFFFFFFFFFFFF0C00FF00FF00000037 +:109730000001010102020000000000004C4E100078 +:10974000985310003B1E010002000000491E01005A +:1097500002000000111E0100A91E0100A51E01004B +:109760009D1F0100A51E01002D210100A51E010065 +:10977000A51E0100A51E0100A51E0100A51E0100D9 +:10978000DD1E0100010000000B1F010000000000B1 +:10979000A51E0100000000001F1F010001000000C5 +:1097A000C91F010001000000ED1F010001000000C1 +:1097B000112001000100000047200100040000000A +:1097C0001F210100010000005921010001000000DB +:1097D000B721010001000000CD21010002000000BE +:1097E0001522010002000000C92201000200000051 +:1097F0008723010001000000C723010001000000D1 +:109800008122010002000000472301000200000045 +:10981000A51E010000000000A51E010000000000C0 +:10982000732101007D2101008721010097210100A2 +:10983000A72101008600020100A6020F0300A80272 +:109840000B03000003000000000000000300000004 +:109850000000000053000000000000004300000072 +:1098600000000000F300000000000000E300000022 +:109870000000000053020000000000000000000093 +:1098800005000000107A100000040000953600006A +:1098900000000000020000000100000004000000C1 +:1098A000107E1000000400000546000000000000CB +:1098B00002000000020000000300000010821000FF +:1098C00000080000C51B01000000000002000000AD +:1098D0000300000002000000108A100000020000D7 +:1098E0007D240100000000000200000004000000D0 +:1098F00001000000108C1000800000007D1D0100A0 +:109900000000000002000000000000000100000054 +:109910000100000001000000020000000100000042 +:10992000030000000100000004000000010000002E +:109930000500000001000000000000000100000020 +:10994000020000000300000053550100FD54010017 +:109950009B660100674D01002757010073610100FC +:10996000654E0100F1550100B166010000044000A0 +:1099700010210000001F010006000000300001005F +:10998000000406000802500060020C0C0000600297 +:109990000C300C1A31100F0F00002F000100AA2C00 +:1099A0000100000003000000FFFF030000000000B2 +:1099B00018000000FFFFFFFF3F0000000000000054 +:1099C00000010000000000006002018000010000B2 +:1099D00000000C000C000C000C00070126261212DF +:1099E000110000000038003C203DD041EC4108420D +:1099F0001C4230424442604274428842A442000009 +:109A00000000000000000000000000000000002036 +:109A10000001010201020203010202030203030426 +:109A2000000000001B0000802D00008036000000B8 +:109A3000410000805A0000006C00000077000080A8 +:109A40009900008082000000B4000000AF00008098 +:109A5000D8000000C3000080F5000080EE00000088 +:109A60002901008032010000040100001F01008074 +:109A70006801000073010080450100805E01000064 +:109A8000B0010000AB0100809D0100808601000054 +:109A9000F1010080EA010000DC010000C701008044 +:109AA0004902008052020000640200007F02008030 +:109AB0000802000013020080250200803E02000020 +:109AC000D0020000CB020080FD020080E602000010 +:109AD000910200808A020000BC020000A702008000 +:109AE000600300007B0300804D03008056030000EC +:109AF000210300803A0300000C03000017030080DC +:109B0000F9030080E2030000D4030000CF030080CB +:109B1000B8030000A3030080950300808E030000BB +:109B20008904008092040000A4040000BF040080A7 +:109B3000C8040000D3040080E5040080FE04000097 +:109B4000100400000B0400803D0400802604000087 +:109B5000510400804A0400007C0400006704008077 +:109B6000A0050000BB0500808D0500809605000063 +:109B7000E1050080FA050000CC050000D705008053 +:109B80003905008022050000140500000F05008043 +:109B90007805000063050080550500804E05000033 +:109BA000C0060000DB060080ED060080F60600001F +:109BB000810600809A060000AC060000B70600800F +:109BC0005906008042060000740600006F060080FF +:109BD0001806000003060080350600802E060000EF +:109BE000E9070080F2070000C4070000DF070080DB +:109BF000A8070000B3070080850700809E070000CB +:109C0000700700006B0700805D07008046070000BA +:109C1000310700802A0700001C07000007070080AA +:109C20000909008012090000240900003F09008092 +:109C30004809000053090080650900807E09000082 +:109C4000900900008B090080BD090080A609000072 +:109C5000D1090080CA090000FC090000E709008062 +:109C6000200800003B0800800D0800801608000056 +:109C7000610800807A0800004C0800005708008046 +:109C8000B9080080A2080000940800008F08008036 +:109C9000F8080000E3080080D5080080CE08000026 +:109CA000400B00005B0B00806D0B0080760B00000A +:109CB000010B00801A0B00002C0B0000370B0080FA +:109CC000D90B0080C20B0000F40B0000EF0B0080EA +:109CD000980B0000830B0080B50B0080AE0B0000DA +:109CE000690A0080720A0000440A00005F0A0080CE +:109CF000280A0000330A0080050A00801E0A0000BE +:109D0000F00A0000EB0A0080DD0A0080C60A0000AD +:109D1000B10A0080AA0A00009C0A0000870A00809D +:109D2000800D00009B0D0080AD0D0080B60D000081 +:109D3000C10D0080DA0D0000EC0D0000F70D008071 +:109D4000190D0080020D0000340D00002F0D008061 +:109D5000580D0000430D0080750D00806E0D000051 +:109D6000A90C0080B20C0000840C00009F0C008045 +:109D7000E80C0000F30C0080C50C0080DE0C000035 +:109D8000300C00002B0C00801D0C0080060C000025 +:109D9000710C00806A0C00005C0C0000470C008015 +:109DA000C90F0080D20F0000E40F0000FF0F0080F9 +:109DB000880F0000930F0080A50F0080BE0F0000E9 +:109DC000500F00004B0F00807D0F0080660F0000D9 +:109DD000110F00800A0F00003C0F0000270F0080C9 +:109DE000E00E0000FB0E0080CD0E0080D60E0000BD +:109DF000A10E0080BA0E00008C0E0000970E0080AD +:109E0000790E0080620E0000540E00004F0E00809C +:109E1000380E0000230E0080150E00800E0E00008C +:109E2000009E010000041000F80400001C01000066 +:109E3000B49E010000FC100040000000780100000A +:109E4000B49E0100F8081000A08C000094010000EE +:109E500001FF016D36060708090A147C8E011AB944 +:109E6000041AF60414338F011A70041AAD041AEAA6 +:109E700004142790011A64041AA1041ADE04141BA6 +:109E800091011A58041A95041AD204140F92011A57 +:109E90004C041A89041AC604140393011A40041AC4 +:109EA0007D041ABA041AF704143494011A71041ABE +:109EB000AE041AEB04142895011A6504011C1490D1 +:109EC0005F0129223202692AA908091A0CB2642901 +:109ED0000C694829040A11041001FF01460755F0D6 +:109EE00001206056103206320F9A37089AE10803B3 +:109EF00042D303AAFF0C590101150B4190D06E010A +:109F00001200000030B572B601230C4D2B600C4AD4 +:109F1000002481B113604FF0005100F01F0081F860 +:109F20006A0007481C38036001680029FCD11460EE +:109F30002C6062B630BD1460EDE70000C01B00224B +:109F4000780D00221AC4187997020000E53BE786D5 +:109F500068FDFFFF000019000102000019E1000088 +:109F600000000000FFFFFFFF00000000FFFF0000F7 +:109F7000000000002010C70837040FC7083704B8D6 +:109F80000100000001202050AAAA000500050005DC +:109F9000000500010001000100017000700008B020 +:109FA00000B0000003AAC800040000000000000088 +:109FB0000000000005080F0A1F0FF9000200000052 +:109FC0000000000000000000000000000000000091 +:109FD000000000000B01500064008001D00F000061 +:109FE0000000000082000064000000FF000000008C +:109FF000000000001608000208000600000000A093 +:10A00000504C260108001300000000008D01094F8C +:10A01000040032000200310023500600000000005E +:10A02000BBBB401FC80088880000EDA50D1F2400A1 +:10A030003C003B00235006000000000023400600C7 +:10A0400000000000000123000000002305000000C4 +:10A050000000000000008D11084F040030000600D1 +:10A060002F0040100600000001000000000000006A +:10A07000000000000000E8650D1F100034003000F3 +:10A08000600017001001100020009923000100005B +:10A0900000000000000000000000000000000000C0 +:10A0A00000000000000000000000000000000000B0 +:10A0B0000000000011002C01000000000100000061 +:10A0C000000000000000B80B000000000E000000BF +:10A0D00060F000000000000000000200000000002E +:10A0E000000000000E000000000000000000000062 +:10A0F000000002000000000000000000000000005E +:10A1000000000200000164006400D000800CF00A2E +:10A11000D00000150012500150010015001250012E +:10A12000800CF00AD00000000000000000000000D9 +:10A1300000000000332A020A1100011E1E00000068 +:10A140000000300000000000FF0FFF0F10140A0095 +:10A15000000000000B004001000000D00240900110 +:10A160009001FF7FFF7FF40100000000000000006D +:10A1700000000000890000018001000180016400EE +:10A180006400200002003C0064006400C80000007D +:10A19000000064000702F4014001002C012C0108BA +:10A1A00019C800000B030521010164006400600070 +:10A1B000900132030000000000230001C800FF2CC2 +:10A1C000012000000300640032002000140A200374 +:10A1D00050000004000020000600050005000000FB +:10A1E0000600050005000000000000000000910CC2 +:10A1F000080030003000000162844032200010006E +:10A200003200C8008813401F056400640064001019 +:10A21000000000000200000000000000000000013B +:10A22000000184030C062000100F5000960064000B +:10A23000000A000F000F00016000600000404000B5 +:10A2400000009001000132007C01003C0100000090 +:10A2500000005600000000000000000000000000A8 +:10A2600000000000000000000000000000000000EE +:10A2700000000000000000000000000000000000DE +:10A2800000000000010096003200010A010A0013DC +:10A29000115500000002C8000A0000140000000070 +:10A2A0000000000040005000700032004000C80074 +:10A2B0000000000000640000000000000000000A30 +:10A2C000001405006179AA00000210010002640078 +:10A2D00006000000001E001E001050003200002189 +:10A2E0000F02100F000A0014821114001000041055 +:10A2F0000400400000200030B810006400A49494D2 +:10A3000028886210003000100030000A0018000594 +:10A310003C053C033CD80532F80301030000000073 +:10A32000000000000401C800C8000A0A6400FA0026 +:10A330000103800080000103000000000000000015 +:10A3400000C8000A0000000000000000000110002A +:10A35000000500640A1E0000C3081E00006F08000C +:10A360000000370400000037040A3280FF0520197E +:10A370000000000000000000403203200000000048 +:10A3800000000000030250005000FA0032FF7F0B73 +:10A390000132002003000A201405F800000000002C +:10A3A00000000000000000000000000000000000AD +:10A3B0000000000000000102030400010203840306 +:10A3C00050015001500100000000001E11003C002F +:10A3D0000000000000051E04FA000000500A051EDF +:10A3E00007640A0264646464646464646464646446 +:10A3F000646464646464646464646464646464641D +:10A40000646464645A5A5A5A5A5A5A5A5A5A5A5A84 +:10A410005A5A5A5A000000000000000000000000D4 +:10A4200000000000967D6E67656464646464646423 +:10A430006465676E7D96000000000000000000006B +:10A440000000000000000000000000110D0C22229E +:10A450002200000000000028005000B4001801ABEA +:10A46000070F0869089B08AF08C708C70800001451 +:10A470000028003C0050006400D403E803FC0310F3 +:10A480000424043704000000000000000000000065 +:10A4900000000000000000000006001600320091DD +:10A4A00000FD00BA0720087808A708B108C008C74F +:10A4B0000807000C00140023002D004500F2030AD9 +:10A4C00004140423042B04300400000000000000E6 +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000006E08C708178F +:10A57000013F018F011102A702F7021F0300006EC5 +:10A5800008C708FF00300180010902A80203031F69 +:10A5900003000000460046004600404610860000CA +:10A5A0000000360038003C0042004B0056006400BA +:10A5B000740086009A00B000C700E000F9001401A2 +:10A5C00030014C0169018501A101BD01D901F301EF +:10A5D0000C0224023B0250026302740282028F02C8 +:10A5E0009902A102A602A902A902A602A102990249 +:10A5F0008F0282027402630250023B0224020C02A8 +:10A60000F301D901BD01A101850169014C013001AE +:10A610001401F900E000C700B0009A008600740041 +:10A62000640056004B0042003C00380036005D00DC +:10A630005F006700740087009E00B900D900FE002B +:10A64000250151017F01AF01E10115024A027F029C +:10A65000B402E8021C034D037C03A903D303F903EE +:10A660001B043904520467047604810486048604BA +:10A67000810476046704520439041B04F903D303EC +:10A68000A9037C034D031C03E802B4027F024A02C3 +:10A690001502E101AF017F0151012501FE00D90042 +:10A6A000B9009E008700740067005F005D00A40091 +:10A6B000F500DB012E03B40428064B07EA07EA077E +:10A6C0004B072806B4042E03DB01F500A4000000AC +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A0000000000001000100010004010405000098 +:10A7B0000000FF030807080708070807FF03FF0357 +:10A7C000FF03FF0300000000000000000000000085 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000030507080C0D0F0F0F0E0E9F +:10A840000E0D0D0D0A0800000000000000000000C1 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A000000000000000000002013C000102232320 +:10A8B0002323083C083C40F8050505050105050F64 +:10A8C000140000000000E8650D1F10003400300087 +:10A8D000600017001001100008009923000000001C +:10A8E00000000000000000000000000000006E08F2 +:10A8F000C70817011F0302078C9600000000000024 +:10A9000000000000501E501214B020FFD0000614AA +:10A91000142A3A40003232000000000000146E6E2B +:10A92000471A38000000010F1E0020000164A80132 +:10A930009C0258064E07280000000000000000009E +:10A94000000000000000E920041F10002500250081 +:10A95000500024007001800010005500000000002D +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000888800000000000000000000B7 +:10A990000000000077000000000900000000000037 +:08A9A00000000000EB145CAEA6 +:00000001FF diff --git a/firmware/st_fts_e5.ftb.ihex b/firmware/st_fts_e5.ftb.ihex new file mode 100644 index 000000000000..8776bbf72bdf --- /dev/null +++ b/firmware/st_fts_e5.ftb.ihex @@ -0,0 +1,6799 @@ +:1000000055AA55AA0100000036390000162000004C +:10001000540000003E0000002A0000000000000024 +:10002000000000002AE5000000000000489D0100DB +:10003000400B000000000000000000009104B83AEE +:100040005E43B8A751670000A1BC4758AE98FFFFB8 +:1000500000041000E101000039020000530200001A +:100060006D02000087020000A102000000000000F5 +:10007000000000000000000000000000176E0100FA +:100080001F6E010000000000BB020000276E01008F +:100090002F6E01003B6E0100476E0100536E0100A0 +:1000A0005F6E01006B6E0100776E0100836E0100D0 +:1000B0008F6E0100C90200009B6E0100A76E010057 +:1000C000B36E0100BB6E0100C36E0100CB6E010078 +:1000D000D76E0100DF6E0100E76E01000000000036 +:1000E000000000000000000000000000EF6E0100B2 +:1000F000F76E010000000000FF6E0100000000002C +:1001000000000000000000000000000000000000EF +:10011000540016200400FFFF000000000000000053 +:1001200000000000000000000000000000000000CF +:1001300000F002F800F068F80AA090E8000C824491 +:100140008344AAF10107DA4501D100F05DF8AFF26E +:10015000090EBAE80F0013F0010F18BFFB1A43F0A5 +:10016000010318478C9B0100BC9B01000A444FF01F +:10017000000C10F8013B13F0070408BF10F8014B06 +:100180001D1108BF10F8015B641E05D010F8016B4B +:10019000641E01F8016BF9D113F0080F1EBF10F8AF +:1001A000014BAD1C0C1B09D16D1E58BF01F801CBD2 +:1001B000FAD505E014F8016B01F8016B6D1EF9D555 +:1001C0009142D6D370470000103A24BF78C878C156 +:1001D000FAD8520724BF30C830C144BF04680C604D +:1001E000704700000023002400250026103A28BF95 +:1001F00078C1FBD8520728BF30C148BF0B60704799 +:100200001FB51FBD10B510BDDFF80CD0FFF7F8FF0C +:1002100016F0A0FE19F0C4F80004100003B4FFF7B4 +:10022000F1FF03BC19F0C6F840BA7047C0BA704776 +:1002300012481349A1EB00014FF0200391FBF3F2A8 +:1002400002FB13114FF0CC334FF0CC344FF0CC35D0 +:100250004FF0CC364FF0CC374FF0CC384FF0CC3994 +:100260004FF0CC3AA0E8F807013AFBD119B140F8B9 +:1002700004AB0439FBD10348004700000000100024 +:1002800000041000E10000001EF0040F0CBFEFF3AB +:100290000880EFF309804FF001014FF0000212F0E7 +:1002A0009BB91EF0040F0CBFEFF30880EFF3098039 +:1002B0004FF002014FF0000212F08EB91EF0040F51 +:1002C0000CBFEFF30880EFF309804FF003014FF00C +:1002D000000212F081B91EF0040F0CBFEFF308808A +:1002E000EFF309804FF004014FF0000212F074B9EF +:1002F0001EF0040F0CBFEFF30880EFF309804FF0FE +:1003000005014FF0000212F067B900B516F0A4FD28 +:100310005DF804EB00F032B81EF0040F0CBFEFF3F1 +:100320000880EFF309804FF006014FF0000212F051 +:1003300053B900000A484FF0FF0101704FF0000070 +:1003400080F311884FF0000080F3098805484FF0D2 +:100350000201017062B604484FF08051016070479D +:1003600022ED00E02C08100004ED00E002484FF000 +:10037000805101607047000004ED00E04FF0200064 +:1003800080F31188EFF3098098B112480068124990 +:100390000968884217D0EFF309800E49096820E9FF +:1003A000F00F886000B50B48006816F06FFE5DF82E +:1003B00004EB084808490A68026000688168B1E8EF +:1003C000F00F81F309884EF0040E4FF0000080F327 +:1003D000118870473008100034081000EFF31180C6 +:1003E0004FF0200181F31188704700004FF00000AA +:1003F00080F311887047000062B6704772B670478C +:10040000401EFDD17047000010B501464022FE4855 +:1004100018F0CCFE0121BDE81040002016F06FBEA0 +:1004200038B50446F948F84D2060204616F0D3FA56 +:1004300000226B460121104616F0AAFE0121002081 +:1004400016F089FE2878002802D012F01CF9ECE79B +:1004500038BD2DE9F047DFF8B88382460127D8F888 +:100460000000EC4D90F8314010F8301F90F8450333 +:100470004C4300F003008740A100284618F0F2FE2C +:100480000026DFF8849312E0DF484030FFF7C8FF12 +:100490000020D9F8081007E055F8202031F9103075 +:1004A0001A4445F82020401CA042F5DB761CBE42D1 +:1004B000EADB40460AE000BF026855F8241092F8D3 +:1004C000752302F0030211412AF81410641EF3D2BE +:1004D000BDE8F0872DE9F043CD494FF00009CC4647 +:1004E0000F684B4697F8312097F8306097F87443BF +:1004F00002FB06F109B2640736D5C74C2468258E85 +:100500008D4231D1323427E035461FE034F81510E2 +:1005100030F81580A1EB080109B2002901DB8846FB +:1005200001E0C1F10008E04507DD002901DB8C4650 +:1005300001E0C1F1000C0FFA8CFC002900DA4942FD +:10054000B7F87783414501DD5B1C9BB26D1EDDD1A1 +:1005500004EB460400EB4600521ED5D297F879030F +:10056000984201D24FF00109AC48A0F800C0AC4855 +:1005700003804846BDE8F0832DE9F04FDFF890B2E4 +:100580004FF00109A34EDBF80000A7B090F87513F7 +:1005900090F83140C1F3810890F8305009FA08FA18 +:1005A0006019810006EB8407304618F05BFE964820 +:1005B000403016F0EBF99449403181F80690DBF8B1 +:1005C000000090F87403820701D581F80490C007F9 +:1005D00003D08D484030FFF723FF00202BE08A48EE +:1005E0004030FFF71DFFDFF820B2620006A8DBF8FD +:1005F000181018F096FD6A0011A8DBF81C1018F00E +:1006000090FD204606A906E056F8202031F910306A +:100610001A4446F82020401EF6D2284611A906E0CA +:1006200057F8202031F910301A4447F82020401E96 +:10063000F6D209F1010081465045D0DB794905E049 +:1006400056F8240040FA08F021F81400641EF7D28E +:10065000754905E057F8250040FA08F021F8150023 +:100660006D1EF7D227B0BDE8F08F2DE9F04FDFF80F +:10067000A0B14FF00109674EDBF80000A7B090F879 +:10068000761390F8314001F0030890F8305009FAE1 +:1006900008FA6019810006EB8407304618F0E2FD85 +:1006A0005948403016F072F95749403181F80B90A3 +:1006B000DBF8000090F87403020701D581F804907C +:1006C000C00603D550484030FFF7AAFE00202CE0BA +:1006D0004D484030FFF7A4FEDFF82CB1620006A8B9 +:1006E000DBF8341018F01DFD6A0011A8DBF8381093 +:1006F00018F017FD204606A907E000BF56F8202095 +:1007000031F910301A4446F82020401EF6D228460F +:1007100011A906E057F8202031F910301A4447F8A3 +:100720002020401EF6D209F1010081465045CFDB62 +:100730003E4905E056F8240040FA08F021F814007C +:10074000641EF7D23A4905E057F8250040FA08F050 +:1007500021F815006D1EF7D284E72DE9F84F2C4ED5 +:100760000546306890F8314090F830004443264800 +:10077000403016F00BF9244801214030012D017161 +:1007800006D1326892F8A020120701D40422027127 +:10079000C1713068002500F5F97990F8752302F0F1 +:1007A000030201FA02F823498B4691F803A029E0DD +:1007B00019F805108BF803101F4905FB04F001EB35 +:1007C000400700266000009019E00F484030FFF716 +:1007D00027FE0D4881680EB120460DE03846009A8C +:1007E00018F09FFC0AE000BF37F9102031F91030F3 +:1007F0001A44521027F81020401EF5D2761C4645A8 +:10080000E3DB6D1C024819E050081000B90300003A +:10081000F4061000D4611000F80610003007100034 +:10082000320710000C720120367201208272012002 +:10083000AC720120280710001C590120006890F8B4 +:10084000F10100F00300401CA842B1D88BF803A0CE +:100850009BF80000FB49604301EB4000FFF73AFEC4 +:10086000F9490870BDE8F88F2DE9F04FF74D85B0D4 +:10087000296891F8319091F83010009109FB01F04E +:100880000290F34816F082F8F14801248471047153 +:10089000C471286890F87403C00702D0EC48FFF7D1 +:1008A000BFFD28684FF0000B90F8752300F5F97034 +:1008B00002F0030104FA01FAC2F38102E54904FAE5 +:1008C00002F20192C9785C46CDE9030158E0039831 +:1008D000015DE048C1700298DA49604301EB4006CF +:1008E00000254AE0DA48FFF79BFDD9484038D0E9B7 +:1008F0000631876888462DB101998B4530DA484624 +:10090000D5491BE04FEA49021946D34818F009FCC3 +:10091000009841464200D14818F003FC029839463D +:100920004200304618F0FDFB26E000BF31F91020F0 +:1009300033F910C06244521021F81020401EF5D245 +:10094000C649009808E000BF31F9103038F910208E +:100950001A44521021F81020401EF5D20BF1010B61 +:10096000029807E036F9102037F9101011444910A9 +:1009700026F81010401EF5D26D1C5545B2DB641CE4 +:10098000B248006890F8F10100F00300401CA0425A +:100990009DD801998B452CDAAD4800210C46017198 +:1009A0000199A1EB0B0522E0A948FFF739FDA84802 +:1009B000A9494038D0E90623484607E031F91060DC +:1009C00032F910703E44761021F81060401EF5D2C6 +:1009D000A249009808E000BF31F9102033F91060F7 +:1009E0003244521021F81020401EF5D2641CA5425A +:1009F000DADC98490498C87005B034E62DE9FF5F49 +:100A0000DFF84882964FD8F8000090F8314090F80F +:100A1000305007EB840A6019810004FB05FB0AEBE8 +:100A20008506384618F01EFC4FEA8B01304618F058 +:100A300019FC874815F0AAFF85494FF0010981F894 +:100A4000069081F80490D8F8000090F87403C0076D +:100A500002D00846FFF7E4FCD8F8000090F87503D0 +:100A6000C0F38101029100F003010391029948460D +:100A700009FA01F9039988400190002031E0744897 +:100A8000FFF7CEFC72484038D0E906328168204634 +:100A900007E000BF57F820C033F91080C44447F87E +:100AA00020C0401EF6D2284607E000BF5AF820308A +:100AB00032F910C09C444AF820C0401EF6D2DDE94D +:100AC000000290420BDA584607E000BF56F820209B +:100AD00031F910301A4446F82020401EF6D2009812 +:100AE000401C00904845CADB019848451DDD584828 +:100AF0000021884681710198A0EB090913E0544850 +:100B0000FFF78EFC524840388168584607E000BF26 +:100B100056F8202031F910301A4446F82020401EA3 +:100B2000F6D208F10108C145E9DC4B4906E000BFF7 +:100B300057F82400029A104121F81400641EF7D2DD +:100B4000464905E05AF82500029A104121F815009F +:100B50006D1EF7D258463B4A06E000BF56F82010FB +:100B6000039B194122F81010401EF7D2BDE8FF9FE9 +:100B70002DE9F0470546002016F061FB022016F033 +:100B80005EFB032016F05BFB364F002038703048C8 +:100B900015F0FCFEE8054FF0010403D5FFF765FDF5 +:100BA00031480470294EDFF8C480DFF8C490306803 +:100BB00090F87413890712D5290718D5A90710D5FD +:100BC0003C7090F8F001000602D5FFF74DFE01E001 +:100BD000FFF714FF88F8004089F8004001E028077B +:100BE00005D5387818B9FFF7C7FC88F80040DFF85A +:100BF0006080A8071AD5387810BB306890F8F001EB +:100C0000000603D50020FFF7A8FD0CE0104815F002 +:100C1000BDFE88F804400B48FFF71BFC0948FFF7AE +:100C200059FC0949087089F8004034E0680732D55A +:100C3000306890F8F00100061CD50120FFF78DFD0B +:100C400029E000001C5901202F071000F4061000B5 +:100C500090081000280710000C7201203672012045 +:100C6000D4611000000410002E0710002D071000A2 +:100C70002C0710000D4815F089FE306890F8A00090 +:100C8000000702D588F8044002E0042188F8041027 +:100C90000748FFF7DEFB032016F0ECFA022016F0FF +:100CA000E9FABDE8F047002016F0E4BA9008100019 +:100CB0001C59012010B501464022F84818F076FA78 +:100CC0000121BDE81040002016F019BA38B50446DD +:100CD000F348F24D2060204615F07DFE00226B4661 +:100CE0000121104616F054FA0121002016F033FAC3 +:100CF0002878002802D011F0C6FCECE738BD2DE9B9 +:100D0000FF410024DDE90A760821684616F0E6FF77 +:100D10000546082102A816F0E1FF024600206FF008 +:100D20007E0E14E0002100FB02F30DE007EB010C46 +:100D300013F90CC0B444F44501DA012403E0BCF11A +:100D40007F0F00DD0224491C9142EFDB401CA842CA +:100D5000E8DB204604B0BDE8F0812DE9FF410AAC94 +:100D6000082194E8C0010024684616F0B7FF054644 +:100D7000082102A816F0B2FF0146002008E0325612 +:100D8000D21901D5012402E0FF2A00DD0224401C13 +:100D9000A842F4DB00200AE02A18B25612EB08023F +:100DA00001D5012402E0FF2A00DD0224401C884214 +:100DB000F2DB2046CEE72DE9F04F87B04FF0010B74 +:100DC00015F07AFE04460D4615F078FEDFF8D48261 +:100DD00006460F46D8F8000090F8E70010F0600FC4 +:100DE00005D02046294612F007FE04460D46AD48C0 +:100DF000016891F8310091F8301000FB01F80121F1 +:100E000004A80FF0F3FEDFF8A0920020DFF89CA208 +:100E1000D9F80010049B324691F91B100390CDF8CD +:100E200000A0CDE901313B462046294612F06EFE76 +:100E3000012003900021049BCDF800A0CDE90131F1 +:100E400032463B462046294612F060FE9348403029 +:100E500015F09CFD91490520403108710846FFF7C7 +:100E600035FF8E480221D0F808A005A80FF0BEFE7D +:100E70008C4842460168B1F9C2010190B1F9C41130 +:100E800000910844401002905046059913F06FFB02 +:100E90008246022105A80FF00CFF01984FF00008D0 +:100EA000824502DC00998A450ADA7E480299006888 +:100EB000AAEB0101B0F8C60191FBF0F04FFA80F8FF +:100EC0000499CDE9001832463B4620462946FFF7F3 +:100ED00016FF01281DD0022824D0D9F800100120C7 +:100EE000724A81F81B800390049B8DE80C01324606 +:100EF0003B462046294612F009FED9F80000A521FC +:100F00008176012104A80FF0D4FE07B05846BDE851 +:100F1000F08FD9F800104FF0000B81F81BB00121C1 +:100F2000B02007E0D9F800104FF0000BB12081F895 +:100F30001BB0012111F098FBDFE72DE9F04FDFF83E +:100F4000648189B04FF0010BD8F8000090F831A00F +:100F500090F83000079015F0AFFD04460D4615F0EF +:100F6000ADFD0646D8F800000F4690F8E70010F0F7 +:100F7000600F05D02046294612F03EFD04460D467E +:100F8000012104A80FF032FEDFF81C914FF0000899 +:100F9000049BD9F80000294690F91D20444805908B +:100FA0000090CDF80C80CDE9013232463B46204618 +:100FB00012F0ACFDDDE904030121CDE90030CDE9FB +:100FC000028132463B462046294612F09FFD3348B7 +:100FD000403015F0DBFC31490620403108710846ED +:100FE000FFF774FE2D480221D0F8088006A80FF004 +:100FF000FDFD2C480068B0F9C811B0F9CA010844D9 +:1010000040100090079806990AFB00F2404613F042 +:10101000AEFA8246022106A80FF04BFE21484FF09F +:1010200000080068B0F9C821524503DBB0F9CA21B5 +:10103000524508DD009AB0F8CC01AAEB020191FB01 +:10104000F0F04FFA80F80499CDE9001832463B469B +:1010500020462946FFF753FE4FF48071012829D01E +:1010600002282FD0D9F80010012081F81D80DDE979 +:101070000423CDE90032CDE9028032463B462046CA +:10108000294612F043FDD9F80000A521017701217E +:1010900004A80FF00EFE584609B038E7A00810006B +:1010A000650C0000F4061000F8061000147501200D +:1010B0003C7A0120D9F800204FF0000BB02082F8D4 +:1010C0001DB006E0D9F800204FF0000BB12082F8E7 +:1010D0001DB011F0C9FAD6E72DE9F04F91B0DFF855 +:1010E000C0A301200F90DAF8000090F831100E91A3 +:1010F00090F830000D9015F0DFFC8046894615F021 +:10110000DDFC04460D46012106A80FF06FFDDAF85C +:10111000000002AB002690F8340100F00101E14824 +:10112000006890F9202090F91F00059183E84500A0 +:10113000DD4806990C90CDE9000122462B46404639 +:10114000494612F034FDDAF800000121224690F8F9 +:101150003401029600F00100CDE9041006990C98C4 +:10116000CDE9000103962B464046494612F01FFD8B +:10117000CE4815F00BFCCD49032088710846FFF7D7 +:10118000A5FDCA4802214038D0E90676DAF8000009 +:10119000B0F9CEA1B0F9D0B107A80FF027FD0AEB46 +:1011A0000B004010059038460E9A079913F0DFF9AE +:1011B0000027504501DC584508DA0599091AB84856 +:1011C0000068B0F8D20191FBF0F047B230460D9ABA +:1011D000079913F0CCF90026504501DC584508DA90 +:1011E0000599091AAE480068B0F8D40191FBF0F0F7 +:1011F00046B2022107A80FF05CFD0698CDE9000772 +:1012000022462B46029640464946FFF7A6FD012896 +:1012100026D002282ED0A3480121224600682B4662 +:10122000C77780F820609E48006890F83401CDE9C7 +:10123000027600F00100CDE9041006990C98CDE982 +:1012400000014046494612F0B2FC9648A5210068CC +:101250008177012106A80FF02CFD0F9811B056E6FA +:10126000904900200F900968C87781F8200010216C +:10127000B22008E08B4900200F900968C87781F8F8 +:1012800020001021B32011F0EFF9DEE72DE9F04F37 +:101290008DB04FF0010915F00FFC06460F4615F012 +:1012A0000DFCDFF8FC810121D8F8000090F8310036 +:1012B0000A9006A80FF09AFCD8F80000794C4FF07D +:1012C000000A90F8620902AB00F00101206855465F +:1012D000DFF8D4B190F9232090F92200059183E83A +:1012E000250006990BF1980BCDE900B15246534603 +:1012F0003046394612F05BFCD8F80000012100228C +:1013000090F86209029500F00100CDE904100699F9 +:101310000395CDE900B113463046394612F047FC3B +:10132000624815F033FB6149032008720846FFF755 +:10133000CDFC5E4802214038856A09A80FF056FCB2 +:10134000D8F80000B0F9D611B0F9D801084400EB84 +:10135000D07040100190DDE90912284613F007F91A +:10136000D8F800100025AB46B1F9D621824203DB44 +:10137000B1F9D821824206DD019AB1F8DA11101ACA +:1013800090FBF1F045B2022109A80FF092FC0699FA +:1013900000228DE82208134630463946FFF7DDFC6F +:1013A000012826D002282ED0216801223E4801F8CB +:1013B000225F81F801A0D8F8001091F8341102954D +:1013C00001F001010591CDE903A206990022CDE9C2 +:1013D000000113463046394612F0E9FB2168A5208A +:1013E00081F82100012106A80FF063FC48460DB0EA +:1013F0008DE521684FF0000901F822AF81F801A0C6 +:101400004021B22008E021684FF00009B32001F824 +:1014100022AF81F801A0402111F026F9DEE770B576 +:1014200005460124002015F00AFF022015F007FFF1 +:101430001B4E306890F8C0012840C00703D0FFF76A +:10144000BAFC00F00104306890F8C001800704D5B0 +:10145000A80702D5FFF771FD0440306890F8C0017D +:10146000400704D5680702D5FFF736FE0440306810 +:1014700090F8C001000704D5280702D5FFF706FF42 +:101480000440022015F0F6FE002015F0F3FE0CB922 +:10149000E80702D0012001F0B4F9204670BD000039 +:1014A000F4061000F806100004800120E008100087 +:1014B00070B56F4C4FF6FF714FF434752068418260 +:1014C000294616F045FC00211F200EF1C1FB2A46DB +:1014D0002168BDE870401F23664816F060BC644870 +:1014E00010B50068644C417D206841744FF48C61F4 +:1014F00016F02EFC00211A200EF1AAFB00211B2061 +:101500000EF1A6FB1A234FF480625C48216816F0A6 +:1015100046FC21681B23BDE810406022584801F5B5 +:10152000805116F03CBC2DE9F041564D041D0E468D +:101530002146284616F00CFC3068534900EB840322 +:101540008B4201D21C2312E0504A934212D28842AD +:101550000CD28846091A8F081C233A46294616F0F1 +:101560001EFCE21B05EB87011D2311E01D23224613 +:1015700029460EE0904214D2111A8F0890461D237E +:101580003A46294616F00BFCE21B05EB87011E23A9 +:10159000404616F004FC306800EB84003060BDE883 +:1015A000F0811E23E3E7F8B5364C3948009010343B +:1015B000022015F044FE00211C200EF149FB002101 +:1015C0001D200EF145FB00211E200EF141FB1021D4 +:1015D000204617F025FE00202080A0700120244D19 +:1015E000E0704FF6FF71A1802868028AE280437D97 +:1015F00028482372E688A0F8F86EA0F8FA1E0422A4 +:1016000080F8FC3E69461046FFF78DFF012300225B +:101610002146102012F041FD6946FFF784FF0123A7 +:1016200000222146112012F038FD6946FFF77BFFAA +:10163000286890F85012C90703D190F81E0AC00715 +:1016400008D0012300222146122012F026FD69460F +:10165000FFF769FF012300222146132012F01DFD30 +:101660006946FFF760FF022015F004FEF8BD000098 +:10167000F4061000F0EF0100F8061000F09F0100E2 +:10168000F0AF0100D4611000F0CF0100F0DF0100E5 +:10169000F0BF0100147501200B4801785A2911D1BF +:1016A0008188B1F57C7F0DD8418800290AD106498F +:1016B00040781031022805D0A0F17002072A01D825 +:1016C00011F0B8B9704700000000012010B50146C4 +:1016D0004022FE4817F06AFD0121BDE810400020BD +:1016E00015F00DBD2DE9F041F94CA0F16006092E71 +:1016F000D4E91205D4E9142316D2DFE806F0051662 +:10170000263746586778870002462B46084600F081 +:101710009DF902460120002117F0CCFCD4E90223F8 +:1017200010431943C4E9020175E0084600F08EF940 +:10173000012302460021184617F0BCFCD4E90A2315 +:1017400010431943C4E90A0165E002462B460846E6 +:1017500000F07CF902460120002117F0ABFCD4E92F +:10176000062310431943C4E9060154E0084600F07B +:101770006DF902460120002117F09CFCD4E90E23EC +:1017800010431943C4E90E0145E002462B460846C2 +:1017900000F05CF9012302460021184617F08AFC8C +:1017A000D4E9042310431943C4E9040133E0084693 +:1017B00000F04CF902460120002117F07BFCD4E92F +:1017C0000C2310431943C4E90C0124E002462B46C4 +:1017D000084600F03BF902460120002117F06AFCA0 +:1017E000D4E9082310431943C4E9080113E008466B +:1017F00000F02CF902460120002117F05BFCD4E92F +:10180000102310431943C4E9100104E0012088406B +:101810006168084360602068401C2060BDE8F0817A +:101820002DE9F041174604460D46002609E0E00781 +:1018300003D03146384610F017FF761C6D084FEA8A +:10184000340454EA0500F2D1E8E72DE9F041A04C58 +:10185000D4E90223D4E90656104619462A433343F5 +:10186000D4E90A56D4E90EC745EA0C053E43D4E94B +:10187000087C97432CEA030CC4E9087CD4E91023C4 +:10188000AA43B343C4E910232268002AC6D06022C9 +:10189000FFF7C6FFD4E90A016122FFF7C1FFD4E9CF +:1018A00006016222FFF7BCFFD4E90E016322FFF7B5 +:1018B000B7FFD4E904016422FFF7B2FFD4E90C01B9 +:1018C0006522FFF7ADFFD4E908016622FFF7A8FF04 +:1018D000D4E910016722FFF7A3FF6068BDE8F0417B +:1018E000682200219CE799E72DE9F14F4FF00009AC +:1018F00015F0E2F80646884615F0E0F8744A04460A +:101900000D46C2E91401C2E912684FF01D0A4FF0FA +:10191000260B15F0F0FE00273A460120002117F0B3 +:10192000C9FB304001EA0801084322D0F8B2002187 +:1019300015F0E9FE410705D50099C90602D54946CB +:10194000622010E0C10705D00099490702D5494639 +:10195000602008E0009911F0C00F06D010F00A0FC7 +:1019600003D049466420FFF7BDFE09F1010000F0F5 +:10197000FF097F1C5745CFDB15F0BDFE00273E4613 +:1019800032460120002117F095FB204029400843F2 +:1019900020D0F0B2012115F0B6FE410705D500991F +:1019A000890602D53946632010E0C10705D00099A9 +:1019B000090702D53946612008E0009911F4C07F7B +:1019C00006D010F00A0F03D039466520FFF78AFED3 +:1019D0007F1CFFB2761C5E45D2DDBDE8F84F15F0E6 +:1019E0008ABE10B50446002015F029FC38490020B5 +:1019F00014F00C0FC1E90800C1E90200C1E90400BC +:101A0000C1E90600C1E91000C1E90A00C1E90C0002 +:101A1000C1E90E004860086009D1E00607D4A006BD +:101A200005D4600603D4E00501D4200602D5204683 +:101A3000FFF75AFFA00702D0204600F022F8FFF778 +:101A400004FFBDE81040002015F014BC2DE9F04162 +:101A500016461F4680464FF0FF35002422460120DF +:101A6000002117F027FB30403940084304D06D1C9B +:101A7000454501D12046D1E6641C402CEED3002020 +:101A8000CCE62DE9FF410446012000F038F88046FD +:101A900015F012F8CDE9000115F010F8CDE90201BA +:101AA0000821684616F01AF90746082102A816F020 +:101AB00015F90546074EE00707D03068424629462B +:101AC000B0F8DE30384600F04AF805E0F0081000C3 +:101AD00008041000F4061000A00707D5306842463D +:101AE0002946B0F8DE30384600F089F86A480168C7 +:101AF00041F0020101600FF020FDBDE8FF8130B52B +:101B000085B00446684614F041FF64480090022CFA +:101B100015D007208DF80400614C684614F05BFF77 +:101B2000002204AB0121104615F032FB01210020F8 +:101B300015F011FB207830B110F0A5FDEDE7032082 +:101B40008DF80900E8E714F0B7FF564DC5E912011A +:101B500014F0B4FFC5E91401A06805B030BD2DE94B +:101B6000FF5F9B4692460F46002544E000984FF0E9 +:101B700000094C46A0F101083AE000BF04FB075001 +:101B800081B2601C00FB075080B23AF811203AF88D +:101B90001000101A00B2584502DDB9F1000F0AD04A +:101BA000CBF10001884213DAB9F1000F06D04FF0F3 +:101BB0000009214618E04FF0010914E0002604E076 +:101BC00031466620FFF78EFD761CA642F8D90EE05E +:101BD000B9F1000F0BD021466620FFF783FD009876 +:101BE000801E844203D1611C6620FFF77BFD641CCC +:101BF0004445C3D36D1CBD42B8D3BDE8FF9F2DE95A +:101C0000FF5F9B4692460D46002641E04FF00009DB +:101C10004C46A5F1010838E006FB0540611C06FBB7 +:101C2000051180B289B23AF810203AF81100101A62 +:101C300000B2584502DDB9F1000F0AD0CBF1000126 +:101C4000884213DAB9F1000F06D04FF0000921469F +:101C500017E04FF0010913E0002704E03946672040 +:101C6000FFF740FD7F1CA742F8D90DE0B9F1000F46 +:101C70000AD021466720FFF735FDA81E844203D114 +:101C8000611C6720FFF72EFD641C4445C4D3761CFD +:101C900000988642BAD3B0E7180710007D160000FE +:101CA000F008100008041000144908604FF40051B7 +:101CB000002015F024BA38B5002015F0C0FAAFF2B4 +:101CC000170017F003F900224FF400546B46214629 +:101CD000104615F05DFA2146002015F03CFA002070 +:101CE00015F0C8FA0648A522016804480A7400687D +:101CF00020F07F424A6117F00DF938BD60041000F2 +:101D0000F8061000020004D0012A04D0022805D0F1 +:101D100002E0012000E0042014F0C1BD0020704763 +:101D200010B501464022FE4817F040FA0121BDE8F7 +:101D30001040002015F0E3B930B585B00446684680 +:101D400014F024FEF74800900CB3012C21D0022C93 +:101D500021D0032C19D108208DF80400F04D032464 +:101D6000684614F038FE002204AB0121104615F03D +:101D70000FFA0121002015F0EEF92878002804D090 +:101D800010F081FC641E002CEADC05B030BD05209B +:101D9000E2E70620E0E702208DF80900DEE72DE902 +:101DA000F14F88B014F088FE8346029114F086FE4D +:101DB0008146DD4C08988A460028206807D0B0F894 +:101DC0007A110898FFF79EFF0490D84812E090F827 +:101DD000E70010F0600F05D05846029911F00CFE94 +:101DE000834602912068B0F872110898FFF78AFFC5 +:101DF0000490CF480390402007900690C848B8212F +:101E0000B83817F02FFA002000900898FFF794FFD9 +:101E1000C34800273E468068059001203D4601905A +:101E20002A460120002117F045F9029A00EA0B002A +:101E30001140084341D0002422460120002117F020 +:101E400039F902460B4600EA090001EA0A01084393 +:101E500020D0B348B83800EBC6018E4603C900EA6B +:101E6000020C01EA03085CEA080C12D1DDF814C088 +:101E70003CF91780DDF810C0E04504DC104319433D +:101E8000CEE9000105E022463146009B039815F09B +:101E90008AFB7F1C0698641C8442CDDBA048B838BE +:101EA00000EBC601D1E9000280EA090082EA0A02D9 +:101EB000104301D000200190761C07986D1C8542CC +:101EC000AEDB0198012804D00098401C00907F28C8 +:101ED0009BDD019809B0BDE8F08F2DE9F14F98B076 +:101EE00014F0EAFDCDE90C0114F0E8FDCDE9100194 +:101EF00018988D4C00285CD02068B0F87A1118989A +:101F0000FFF700FF0F9089480690402082460E9010 +:101F100008210CA815F0E2FE0446082110A815F0CF +:101F2000DDFE44438348019000F5E66021460290BF +:101F300017F076F96100019817F072F97848B82126 +:101F4000B83817F08FF94FF000091898FFF7F4FE32 +:101F5000734800273C4680680A90C9F100004FF0A2 +:101F6000010B3E46139032460120002117F0A2F8E3 +:101F7000DDE90C231040194008436ED000252A46A5 +:101F80000120002117F096F8DDE9108C02460B467F +:101F900000EA080001EA0C01084373D06048B83831 +:101FA00000EBC70CDCE900011040194008430FD0DA +:101FB00093E0DDE90C0111F01FFDCDE90C01206873 +:101FC000B0F872111898FFF79DFE0F9058489BE7E4 +:101FD000B9F1000F0ADA0A9830F914100F9881420B +:101FE00001DB002100E00121029801550A980F99B8 +:101FF00030F91400884231DD0299095D11B10129DF +:1020000009D06AE0B9F17F0F67DA019909F101039C +:1020100021F8140051E0DCE9001011431843CCE929 +:102020000010019830F914100F98091A0A9830F925 +:1020300014200F98A2EB000000D54942002800DAD6 +:102040004042814205DC139B2A4639465B1C0698B8 +:1020500036E0019820F814203FE052E037DA029988 +:10206000095D012901D071B137E0139911F17F0F9A +:1020700033DD01992A4621F81400139B39465B1E73 +:1020800006981DE02AE0DCE9001011431843CCE972 +:10209000001001980F9A30F914100F98081A0A9935 +:1020A00031F91410A1EB020200D54042002A00DAF7 +:1020B0005242904207DCA9F101032A4639460698AC +:1020C00015F071FA09E0019820F8141005E0DCE938 +:1020D000001011431843CCE90010641C6D1C5545D9 +:1020E000FFF64DAF0E48B83800EBC701D1E900014B +:1020F000DDE9102350405940084301D04FF0000B58 +:102100007F1C0E98761C8642FFF62DAFBBF1010FA7 +:1021100005D009F10109B9F17F0F7FF716AF0BE088 +:10212000E8091000D11C0000F40610003C7A0120E0 +:1021300014750120D4611000584619B0CBE62DE982 +:10214000F04F044685B0002015F079F8022015F014 +:1021500076F814F0B3FCCDE90201FE480490402764 +:10216000082102A815F0BAFD8046012C70D1DDE9E6 +:102170000201CDE9000101220023049815F022FAA2 +:10218000DFF8D49300206FF07E0509EB480B690C53 +:1021900005E000BF29F810100BF80050401C404526 +:1021A000F8DB0320FFF7C8FDEC4800242646D0F8F2 +:1021B00008A032460120002116F07CFFDDE9022351 +:1021C0001040194008431DD03AF9141039F9140091 +:1021D000002900DA4942002800DA404281420ADA46 +:1021E00032460021049815F0D3F90BF804003AF8B0 +:1021F000141029F814102B4632460021049815F0CB +:10220000D2F9641C761CBE42D3DB6D1C7F2DC8DD69 +:1022100000252C4622460120002116F04BFFDDE967 +:10222000022310401940084307D01BF9053022460D +:102230000021049815F0B7F96D1C641CBC42E9DB61 +:10224000C74826220499006800F5865016F069FFF9 +:102250000026C44D344622460120002116F02AFFF4 +:10226000DDE9022310401940084307D0224600212F +:10227000049815F08DF925F81600761C641CBC42F4 +:10228000E9DB0320FFF758FDB4488168002006E031 +:1022900031F8103008EB0002401C25F812304045A0 +:1022A000F6DB022014F0E6FF002014F0E3FF05B097 +:1022B00011E62DE9F04F87B0002014F0C0FF022096 +:1022C00014F0BDFF4FF0000B14F0F8FBCDE9040152 +:1022D000A0480390082104A815F000FD0646002040 +:1022E000DFF87482CDE9000008EB460505EB06092E +:1022F0000320FFF721FDDFF864A200242746DAF867 +:10230000080002901AE03A460120002116F0D2FEA1 +:10231000DDE904231040194008430ED03A4600215D +:10232000039815F035F92855029830F8141028F85C +:102330001410002009F80400641C7F1CB442E2DB86 +:1023400000273C4615E022460120002116F0B2FE8F +:10235000DDE9042310401940084309D0EB577F2BD7 +:1023600005DA224600215B1C039815F01CF97F1C3E +:10237000641CB742E7DB0320FFF7DEFC00200124EA +:10238000DAF8083014E000BF33F9102038F91010E3 +:10239000002A00DA5242002900DA49428A4206DA6B +:1023A00029567F2903DA491C295409F80040401CAA +:1023B000B042E9DB00273C4616E02246012000211E +:1023C00016F078FEDDE904231040194008430AD0D6 +:1023D000EB5713F17F0F05DD224600215B1E0398AA +:1023E00015F0E1F87F1C641CB742E6DB0320FFF721 +:1023F000A3FC5A488368002019E000BF19F80010B8 +:10240000A1B933F9101038F91020002900DA494237 +:10241000002A00DA5242914208DA295611F17F0F60 +:1024200004DD491E2954022209F80020401CB04254 +:10243000E4DB0024274627E03A460120002116F07D +:1024400039FEDDE904238246029110401940084319 +:1024500019D02B573A460021039815F0A4F819F823 +:10246000040078B9DDE9002302994AEA0200194321 +:10247000CDE9000138F91400FE30B0F5FE7F01D936 +:102480004FF0010B641C7F1CB442D5DB0821684669 +:1024900015F024FCB04208DBBBF1000F03D0002193 +:1024A000B42010F0E1F807B015E5002036E0032075 +:1024B000FFF742FC2948002427468068029023E069 +:1024C0003A460120002116F0F5FDDDE9043C024604 +:1024D0008E46184001EA0C01084314D0DDE90003E0 +:1024E00002EA000C0EEA03015CEA010C0AD119F9B8 +:1024F0000410012943D0022972D002434EEA03019D +:10250000CDE90021641C7F1CB442D9DB0821684658 +:1025100015F0E4FBB04208DA0AF1010082461248E5 +:10252000006890F8E2115145C1DC0D48262203995C +:10253000006800F5865016F0F4FD0821684615F095 +:10254000CDFBB04202DBBBF1000F11D00021B42063 +:102550000CE0000014840120D4611000E809100090 +:10256000F8061000F8720120F406100010F07CF854 +:10257000022014F07FFE002014F07CFE93E7029806 +:1025800038F9141030F91400002801DB034600E08C +:102590004342002900DA49428B4205DC295D7F294C +:1025A00002D028F8140047E0002109F80410DDE902 +:1025B0000001024302984EEA0103CDE9002330F9FD +:1025C000141038F91400002900DA4942002800DA12 +:1025D0004042814233DD285D401E28552FE0FFE751 +:1025E000029830F9141038F91400002901DB0B4669 +:1025F00000E04B42002800DA4042834205DC2857C5 +:102600007F3002D028F81410E5E7002009F8040014 +:10261000DDE900130A434EEA0300CDE900200298E9 +:1026200030F9141038F91400002900DA4942002862 +:1026300000DA4042814202DD285D401CCDE72B5785 +:102640003A460021039814F0AEFF5BE72DE9F04114 +:1026500005460124002014F0F2FD022014F0EFFDE5 +:102660004C4EE8074FF000074FF0A50808D000F0E7 +:1026700020F810F0010403D03068C77680F81A8083 +:10268000A80708D500F05BF82040040003D03068AC +:10269000477780F81C80002014F0ECFD022014F035 +:1026A000E9FDE80702D0012000F0ABF82046BDE8C4 +:1026B000F0812DE9FC47012614F0FEF904460D4691 +:1026C00014F0FCF9DFF8D09007468846D9F80000EE +:1026D00090F8E70010F0600F05D02046294611F071 +:1026E0008BF904460D46D9F8000090F87001C00738 +:1026F0001FD0CDE9007822462B46284814F062FF0F +:10270000D9F8000090F87011C90712D090F8E700CE +:10271000C0F3411002284FF0000002D3FFF7DDFBA9 +:1027200001E0FFF73CFB060003D1012174200FF00C +:102730009BFF0020FFF700FB3046BDE8FC872DE93A +:10274000FC41012614F0B8F904460D4614F0B6F920 +:10275000114F3A6892F87821D20715D0CDE90001DF +:1027600022462B460E4814F02DFF386890F8780169 +:10277000C00709D00120FFF712FB060004D14FF477 +:10278000807174200FF070FF0120FFF7D5FA3046FA +:10279000BDE8FC81F8061000F40610001475012055 +:1027A0003C7A012010B5FFF786FA0120FFF7C7FC3D +:1027B000012000F094F95320FFF748FF00F00104D6 +:1027C0004FF4D67001F0E5F8204205D0FEF7EBFE9D +:1027D000BDE81040FEF783BE10BD10B5FFF76BFAE1 +:1027E0000120FFF7ACFC012000F079F940F2FF1066 +:1027F000FEF715FE002803D0BDE81040FEF76FBEBF +:1028000010BD2DE9F0411349096891F8C121D207A3 +:102810001DD001281BD1114F91F8312091F83010B3 +:102820003D684A4302200C4E14B23235FEF7A0F93F +:10283000032014F004FD38686200314604862846FF +:1028400016F06FFCBDE8F041032014F013BDBDE8A5 +:10285000F0810000F40610001C590120F806100059 +:1028600010B501464022FA4816F0A0FC0121BDE84F +:102870001040002014F043BC30B585B0684614F019 +:1028800085F8F44802220078E0B1032101280DD038 +:1028900003280ED0022818D0042205280CD00428C2 +:1028A0000DD006280ED007280FD010E08DF80610A6 +:1028B0000DE08DF808100AE08DF80A2007E08DF889 +:1028C0000A1004E08DF8062001E08DF80820E248A7 +:1028D000DF4D03240090684614F07DF8002204AB1D +:1028E0000121104614F054FC0121002014F033FCA7 +:1028F0002878002804D00FF0C6FE641E002CEADC05 +:1029000005B030BD2DE9F34FD24D87B006200E46FD +:10291000287014F0D1F8CDE9040136200290CF4C94 +:1029200007984FF0400AC0B1012821D002287DD17C +:1029300007202870CA48DFF818830090206808F143 +:10294000280841F2421108440190082104A815F01A +:10295000C5F90446012E1ED089E0C148DFF8F08297 +:102960004838009008F1180841F2E6012068EAE7CB +:1029700014F0A4F8CDE90401B94841F21C1128383B +:1029800000902068DFF8C88208440190262008F1F2 +:102990001C080290D9E7024604A9009814F052FEE0 +:1029A000DFF8C0926FF07E0609EB44000390002030 +:1029B000710C04E029F81010039A1654401CA04230 +:1029C000F8DB00BFFFF758FF0025D8F800B02F460E +:1029D0003A460120002116F06DFBDDE9042310408A +:1029E000194008431BD03BF9151039F9150000298F +:1029F00000DA4942002800DA4042814209DA3946C9 +:102A0000009814F00DFE039948553BF8151029F86D +:102A1000151032463946009814F009FE6D1CA54287 +:102A200002D07F1C5745D3DB761C00E054E07F2E9C +:102A3000C8DD002635462A460120002116F03AFB63 +:102A4000DDE9042310401940084306D003982946C5 +:102A50008257009814F0EBFD761CA64202D06D1C44 +:102A60005545E8DBDDE90010029A16F05AFB07989D +:102A700030B1012806D0022806D0032805D103E092 +:102A8000794E02E0794E00E0794E00273D462A4615 +:102A90000120002116F00EFBDDE90423104019404F +:102AA000084306D02946009814F0BAFD26F817000E +:102AB0007F1CA74202D06D1C5545E8DBFFF7DCFE0A +:102AC0000020D8F8001005E031F810202318401C31 +:102AD00026F81320A042F7DB09B0BDE8F08F10B54F +:102AE0000446002014F0ABFB022014F0A8FB2146A2 +:102AF0000020FFF707FF21460120FFF703FF2146D3 +:102B00000220FFF7FFFE022014F0B4FBBDE81040E6 +:102B1000002014F0AFBB2DE9F04F4E4E04468DB0AF +:102B20000620307013F0C8FFCDE90A013620069068 +:102B300050481021494D006890F8E3B107914CB31B +:102B4000012C32D0022C7DD10721317044490391F0 +:102B5000296841F242123E4F11440891283790F8FB +:102B6000E4B1402007900020029008210AA815F047 +:102B7000B5F8DFF8F0A006460AEB4605A819019063 +:102B80000020CDE90400FFF777FE00242046D7F8A7 +:102B9000009035E032482E4F48380390296841F2C2 +:102BA000E600084418370890DDE713F087FFCDE909 +:102BB0000A012B48264F28380390286841F21C113F +:102BC00008441C37089026200690CCE702460120D6 +:102BD000002116F06FFADDE90A231040194008437E +:102BE0000CD04146039814F01BFD285539F81410F9 +:102BF0002AF81410019900200855641C08F10100FE +:102C00008046B442E2DB0024204615E00246012063 +:102C1000002116F04FFADDE90A231040194008435D +:102C200008D02A577F2A04DA4146521C039814F030 +:102C3000FEFC641C08F101008046B442E6DBFFF7AD +:102C40001BFE00E0EDE0002001243B6828E00000CE +:102C5000280A10006804100011280000F80610006F +:102C600084840120D461100090730120E47301205A +:102C70007C740120F406100033F910103AF910208A +:102C8000002900DA4942002A00DA5242914206DA6B +:102C900029567F2903DA491C295401990C54401CF8 +:102CA000B042E9DB0024A0466FF07E0915E0424601 +:102CB0000120002116F0FEF9DDE90A231040194039 +:102CC000084308D02A574A4504DD4146521E03985E +:102CD00014F0ADFC641C08F10108B442E7DBFFF717 +:102CE000CBFD00203B6817E00199095C99B933F9E5 +:102CF00010103AF91020002900DA4942002A00DABF +:102D00005242914207DA2956494504DD491E2954A9 +:102D1000019902220A54401CB042E5DB00242046FF +:102D200027E002460120002116F0C4F90091DDE9F8 +:102D30000A23814610401940084318D02A574146BB +:102D4000039814F074FC0198005D78B9DDE9042360 +:102D5000009849EA02011843CDE904103AF9140039 +:102D6000FE30B0F5FE7F01D901200290641C08F10D +:102D700001008046B442D4DB082104A814F0AEFF61 +:102D8000B04247DA002037E0FFF776FD38680024CC +:102D90000090204625E002460120002116F08AF925 +:102DA000DDE90A8C02460B4600EA080001EA0C0144 +:102DB000084314D0DDE9040C02EA000103EA0C0820 +:102DC00051EA08010AD10199095701292BD002299A +:102DD00059D0024343EA0C03CDE90423641C09F1F2 +:102DE00001008146B442D6DB082104A814F076FF26 +:102DF000B04204DA0998401C09905845C4DB069A91 +:102E00000399089816F08DF9082104A814F066FFBC +:102E1000B04202DB0298002803D0B52007990FF0DA +:102E200023FC0DB059E600983AF9141030F914005B +:102E3000002801DB844601E0C0F1000C002900DA23 +:102E400049428C4505DC295D7F2902D02AF814000F +:102E500045E0019900200855DDE9040102430B43D8 +:102E6000CDE90423009830F914103AF91400002930 +:102E700000DA4942002800DA4042814232DD285D12 +:102E8000401E28552EE000983AF9141030F914002D +:102E9000002801DB844601E0C0F1000C002900DAC3 +:102EA00049428C4505DC29577F3102D02AF81400AD +:102EB000E5E7019800210155DDE9040102430B43D8 +:102EC000CDE90423009830F914103AF914000029D0 +:102ED00000DA4942002800DA4042814202DD285DE2 +:102EE000401CCEE72A574946039814F0A0FB75E72B +:102EF00010B5002014F0A3F9022014F0A0F900206E +:102F0000FFF709FE0120FFF706FE0220FFF703FE90 +:102F1000022014F0AFF9BDE81040002014F0AAB967 +:102F20002DE9F047FF4800252C46D0E91478D0F869 +:102F300034902E46824632460120002116F0BAF81F +:102F4000384001EA0801084304D019F80600A842F5 +:102F500000D90546761C402EEDD3DAE91678DAF86A +:102F60003890002632460120002116F0A3F83840A0 +:102F700001EA0801084304D019F80600A04200D96C +:102F80000446761C402EEDD3DAF8442050461570E6 +:102F9000DAF848100C70DAF82C30DAF82470DAF825 +:102FA00030601B783F782B443B44DAF82870367841 +:102FB0003F7826443E44D0E9147C57EA0C070DD0F4 +:102FC000D0E9167C57EA0C070AD0FF27B34213D288 +:102FD000F31A2B44FF2B07D813700BE0147009E091 +:102FE00015700D70BDE8F0871770826942F40072A9 +:102FF000CAF818200C70F5E79E420DD29B1B2344A3 +:10300000FF2B01D80B7005E00F70816941F400714E +:10301000CAF818101570E5E71570EBE72DE9F041D7 +:103020001F460D46002A1FDDBE4C77B1B4F90A6079 +:10303000114611F0FEFAB042287812DAFF2807D2C2 +:10304000401C28700020BDE8F081B4F90860EFE76B +:10305000A0691FB140F00200A06105E040F40060EB +:10306000FAE708B1401E28700120ECE72DE9F04195 +:103070001E460D46002A1ADDAA4C66B1B4F90A7044 +:10308000114611F0D6FAB84211DD287850B1102857 +:1030900004D3103803E0B4F90870F1E70020287079 +:1030A0000020D0E7A06926B140F00100A061012016 +:1030B000C9E740F48060F9E72DE9F14F82B00025BF +:1030C0009848029A2C46FF2102B3D0F82C90022691 +:1030D0004FF0180B89F80010D0F8308088F80010F5 +:1030E000B0F90A70310200910169002900DC012564 +:1030F0008C484069002800DC0124FFF711FFFFF72E +:10310000BBFB00980FF04BFA85B121E0D0F824907A +:103110004FF400664FF0180B89F80010D0F82880A3 +:1031200088F80010B0F90870F110DCE7DFF8F4A1BE +:103130003A46DAF81C00DAF81010006800F063FC78 +:10314000012805D1DAF8181031430125CAF8181002 +:103150008CB9DFF8D0A13A46DAF82000DAF814107A +:10316000006800F050FC012805D1DAF8181031434E +:103170000124CAF818100DB1002C4ED12F46264656 +:103180004FF0170A4FB96748029BC16902690F687F +:1031900049463846FFF76AFF07464EB96148029B29 +:1031A000016A42690E6841463046FFF75FFF0646F6 +:1031B000FFF7B6FEFFF760FB00980FF0F0F907B1DC +:1031C00016B9BAF1010ADDD22F46564DABF1010610 +:1031D0003FB9E869029B494600682A69FFF71EFF6C +:1031E00007463CB9286A029B414600686A69FFF7B6 +:1031F00015FF0446FFF794FEFFF73EFB00980FF023 +:10320000CEF907B10CB9761EE2D2012F05D1012CFF +:1032100003D1A86920F40070A861BDE8FE8F2DE9F4 +:10322000F04F9A46914600223E4B83461446B3F92E +:103230000C7010460123904615E000BF09EBE40531 +:1032400004F0070C2E7803FA0CF535420AD03BF94E +:103250001250BD4203DC0AF80230012001E00AF8F6 +:103260000280521C641C8A42E8DB36E42DE9FF5FD1 +:1032700000244FF001089A4617462546DFF8A4902F +:103280004646DDF83CB051E00AEBE50005F00701E9 +:10329000007806FA01F2024247D01BF80400012828 +:1032A0003FD00098B9F90C1030F914208A421DDA89 +:1032B0002946019814F0E1F9FF280EDA401CC2B249 +:1032C0004FF000082946019814F0D9F9009830F819 +:1032D00014100E9820F8141023E00BF80460D9F8AD +:1032E000181041F00801C9F818101AE00E9830F9CA +:1032F0001400002813DD401AA2EB010100D5404262 +:10330000002900DA4942884209DC2946019814F074 +:10331000B4F9401EC2B22946019814F0B0F90BF876 +:10332000046001E068041000641C6D1CBC42ABDB4F +:10333000404604B0BDE8F09F2DE9FF5F00244FF048 +:1033400001089A46174625464646DFF86C94DDF894 +:1033500038B030E00AEBE50005F00702017806FA24 +:1033600002F0084226D01BF80400012821D0009862 +:1033700030F91410B9F90C0081421ADD2946019880 +:1033800014F07BF900280CDD4FF00008042801DB65 +:10339000001F00E00020C2B22946019814F06FF926 +:1033A00007E00BF80460D9F8181041F00401C9F8DF +:1033B0001810641C6D1CBC42CCDB4046B9E72DE9FB +:1033C000F04F95B00024254620210CA815F04AFFA7 +:1033D000282102A815F046FFF7480169002900DC02 +:1033E00001244269002A00DC0125F34A8146064691 +:1033F000FF235032406B00F010FBEF4AFF2358329E +:103400007169B06B00F009FBFFF78AFDFFF734FA32 +:103410004FF4806A50460FF0C2F88CB1D9F81C0006 +:10342000E54A4E4600680CAB5032D9F81010FFF751 +:10343000F6FE012804D1B069012440F00800B06113 +:103440008DB1D9F82000DC4A4E46006802AB5832F4 +:10345000D9F81410FFF7E3FE012804D1B069012563 +:1034600040F00800B0610CB1002D78D12646A84686 +:1034700000276EB90CA80090D9F81C00CE4BD9F8E3 +:10348000102000685033D9F83410FFF755FF064676 +:10349000B8F1000F0DD102A80090D9F82010C64B4A +:1034A000D9F8142008685833D9F83810FFF744FFCA +:1034B0008046FFF735FDFFF7DFF950460FF06FF854 +:1034C00016B1B8F1000F02D17F1C602FD1DBDFF8FD +:1034D000ECB2D9F81000264641000BF5E6684C46E0 +:1034E000584615F09DFE60694100404615F098FE73 +:1034F0000027D146FFF7C0F948460FF050F85EB9F3 +:103500000CA8CDE900B0E069AB4B226900685033EC +:10351000616BFFF7ABFE06465DB902A9CDE90081FC +:10352000206AA54B626900685833A16BFFF79EFEC5 +:103530000546FFF7F5FCFFF79FF948460FF02FF817 +:1035400006B115B97F1C602FD4DB012E07D1012DE8 +:1035500005D1A069810502D520F40070A06115B0E5 +:1035600083E62DE9FF5F4FF0010800259A461746D4 +:103570002C46DFF844924646DDF83CB03AE000BF06 +:103580000AEBE40004F00702017806FA02F00842B0 +:103590002FD01BF8040058BB2146019814F040F8C6 +:1035A0000099B9F90E2031F915304946934212DDE0 +:1035B0000E9A7F3A904208DD0E99421A21460198F0 +:1035C00014F035F84FF0000812E0886940F0400030 +:1035D000C9F818000CE00BF804600E99C1F17F01E6 +:1035E000814205DD0E9942182146019814F01FF81A +:1035F0006D1C641CBD42C3DB40469AE62DE9F04FCA +:103600006D4C9FB02169B9B3002083466069A0B3B7 +:1036100000208246BBF1000F02D0BAF1000F5AD150 +:10362000674B04AD0DCB85E80D00634A7F23503214 +:10363000E06B00F0F2F9604A7F2358326169206C38 +:1036400000F0EBF90026A14604A85C4650F826805D +:103650005546202111A815F005FE282107A815F0D0 +:1036600001FED9F81810002721F04001C9F8181000 +:10367000FFF702F934B114E000E001E00120C4E7F3 +:103680000120C6E711A9CDE90081D9F81C104A4BE9 +:10369000D9F8102008685033D9F83C10FFF761FFC3 +:1036A000044675B907A9CDE90081D9F82010424B2D +:1036B000D9F8142008685833D9F84010FFF751FFA3 +:1036C0000546FFF72DFC04B115B97F1C182FCFDB81 +:1036D000761C032EB8D31FB0C7E570B5364C002654 +:1036E0000546A66101285DD0022D5DD00120207025 +:1036F000607968B1304A002350322169606B00F074 +:103700008CF92D4A002358326169A06B00F085F9CD +:10371000A07958B1284922695031E06B13F092FF2B +:10372000254962695831206C13F08CFFE07810B1A4 +:103730000020FFF7C1FC207960B1E07838B16178F2 +:10374000606A00F058F96178A06A00F054F901202D +:10375000FFF7B2FC607908B1FFF731FE012D25D0EB +:10376000022D25D084F80060FFF786F8A07958B1C3 +:10377000207938B1A178E06A00F03DF9A178206B9A +:1037800000F039F9FFF73AFFFFF776F8012D19D06D +:10379000022D19D01021A06900F054F9A069B0B130 +:1037A000002070BD0320A2E70520A0E7022000E072 +:1037B00004202070D8E7000068041000D4611000D5 +:1037C000209501004021E6E74FF40071E3E7012076 +:1037D00070BD70B5B64D0C46022828D013F06CF9B8 +:1037E000C5E9140113F06AF9C5E91601B0480821CA +:1037F000503014F073FA2861AD480821583014F0A5 +:103800006DFA686104F190006862401CA862401C77 +:10381000E862401C28634B3868632030C5E90E0419 +:103820004838286474309534C5E9110470BD13F02C +:1038300047F9C5E9140113F045F9D5E710B59D49DD +:103840000020FFF7C6FF9A489B49C161091D01622C +:103850009A490B6893F8882112F00104C4704FF064 +:10386000000204D0436A1A70836A1A7008E0446A3E +:1038700093F8923123700B68846A93F89331237024 +:103880000B6893F88841C4F34004047114B1C36A0F +:103890001A7006E093F89421C36A1A700A6892F8C5 +:1038A0009521036B1A70096891F88821C2F380038F +:1038B0004371C2F3C0028271B1F88A210281B1F86A +:1038C0008C214281B1F88E218281B1F89021C28190 +:1038D00091F89621427091F897118170BDE81040DF +:1038E0000020FAE6734910B598310120FFF771FF07 +:1038F00071496F481031C1610021C0E916110A46B3 +:1039000041616E490B6893F8A04114F00104C47042 +:1039100004D0436A1A70836A1A7008E0446A93F804 +:10392000AA3123700B68846A93F8AB3123700C685A +:1039300094F8A031C3F34003037113B1C36A1A7042 +:1039400006E0C36A94F8AC211A700A6892F8AD21B7 +:10395000036B1A70096891F8A021C2F380034371C8 +:10396000C2F3C0028271B1F8A2210281B1F8A42190 +:103970004281B1F8A6218281B1F8A821C28191F8D3 +:10398000AE21427091F8AF118170BDE81040012066 +:10399000A3E62DE9F04107460124002013F04FFC77 +:1039A000022013F04CFC464E78074FF000054FF014 +:1039B000A5080AD5FFF742FF10F0010405D03068D2 +:1039C000C57780F8205080F81E8038070AD5FFF7A9 +:1039D00089FF2040040005D0306800F8225F457060 +:1039E00000F8018C022013F045FC002013F042FC8B +:1039F0002046BDE8F08102788A4201D9511A00E0E0 +:103A000000210170704710B5144610F012FEA0425C +:103A100001DC012010BD002010BDF0B500252C46B2 +:103A200001260CE002EBE40704F0070C3F7806FAED +:103A30000CFE1EEA070F01D003556D1C641C8D425D +:103A4000F0DBF0BD70B504460D46C00702D0832000 +:103A50000EF00AFEA00703D5294684200EF004FECE +:103A6000600703D5294685200EF0FEFD200703D50B +:103A7000294686200EF0F8FD600603D529468B20E6 +:103A80000EF0F2FD200603D529468C200EF0ECFD49 +:103A9000E00503D5294687200EF0E6FDA00505D5F3 +:103AA0002946BDE8704088200EF0DEBD70BD0000E4 +:103AB0006804100004800120400A1000F406100081 +:103AC000F8061000DFF8949108B5654D0024DFF882 +:103AD00094A1C9F80040644E2C60DFF89081CAF8C8 +:103AE0000040DFF88CB13460C8F80040CBF80040EB +:103AF00000226B465F49104613F04AFB009881078D +:103B000013D5FCF77BFC2F682C60FCF775FC17F0D5 +:103B1000530F02D03846FEF799FD17F4D67F02D036 +:103B20003846FFF736FF022194E0810504D5FEF701 +:103B3000C2F84FF400718DE0410514D5FCF75EFC2E +:103B400037683460FCF758FCF80701D0FDF7B0FC8B +:103B5000B80701D5FDF727FD780701D5FDF7BFFCB4 +:103B60004FF4806176E001060CD5FCF747FCD8F8ED +:103B70000070C8F80040FCF73FFC3846FDF731FF05 +:103B8000802167E081020DD5FCF738FCDAF800707F +:103B9000CAF80040FCF730FC3846FDF740FC4FF413 +:103BA000001157E0C10404D5FEF7FCFD4FF480512D +:103BB00050E0010204D5FDF76FFD4FF4000149E02C +:103BC000010504D5FEF709FE4FF4006142E0410211 +:103BD00030D5FCF713FCDBF80070CBF80040FCF7A5 +:103BE0000BFCF80701D0FEF766F8B80705D50120F1 +:103BF000FEF7A5FA0120FEF772FF38070FD51E4821 +:103C0000006890F8C101000601D5FEF752FB1A4882 +:103C1000006890F8C101400601D5FFF769F97807FF +:103C200005D50020FEF78BFA0020FEF758FF4FF471 +:103C300080010FE0C0057FF55BAFFCF7DFFBD9F833 +:103C40000070C9F80040FCF7D7FB3846FCF790FF3E +:103C50004FF48071002013F07EFA49E7000710004E +:103C600004071000080710000C07100010071000D0 +:103C700014071000839FF000F4061000274810B5C9 +:103C8000016827480268134692EA010F32D0254A9C +:103C9000CC0712682FD092F82143E40702D043F0FA +:103CA000010303608B0729D592F84033DB0703D06B +:103CB000036843F0020303600B0723D592F86033D7 +:103CC000DB0703D0036843F0080303604B061DD5F0 +:103CD00092F86033DB0703D0036843F040030360CE +:103CE000C90517D592F89610490703D5016841F424 +:103CF0008071016010BD23F00103D2E7036823F057 +:103D00000203D8E7036823F00803DEE7036823F023 +:103D10004003E4E7016821F48071EAE7200710001E +:103D2000F0041000F40610002DE9F047DFF8689267 +:103D30009A4C0025D9F8000090F8311084F8301022 +:103D400090F83020964884F831205143037B84F862 +:103D5000333000F140032360837B0EB284F82D30B2 +:103D6000804677000FE02A463146D8F808000FF069 +:103D7000B4FB0146226806FB05F002EB40003A4620 +:103D800015F0CFF96D1C94F82D00A842EBDC8548A6 +:103D90008549007809780843400711D58348606059 +:103DA000D9F8001091F8F11189074A0F94F83110F1 +:103DB000921C4A43D8F81010BDE8F04715F0B1B98D +:103DC000BDE8F0872DE9F041764F774C00263D683D +:103DD00020680543012013F032FA40216F4815F0A6 +:103DE00041FAE80706D0FFF79FFFE80601D500F08B +:103DF000A3F801266E480078400603D5E80601D5F1 +:103E00000DF09BFB280702D500F076F801266948E3 +:103E100001686248C161056222684262604A2946BF +:103E2000654D526882622A7880F82C20CA071CD01F +:103E30000446C80619D5584F386890F85002C00794 +:103E400006D000F072FE18B9E06940F01000E061A1 +:103E5000386890F81E0AC0070CD000F066FE48B91A +:103E6000E06940F02000E06104E03878400601D5C8 +:103E70000DF063FB012013F0FDF9002E0CD0287823 +:103E8000052807D0062805D00121BDE8F041022011 +:103E900013F035B90221F8E7BDE8F081474810B5C5 +:103EA0000078002827D13E4CD4E9060100F040FEFE +:103EB00094F83110A06A00F04EFDFFF783FF3648FA +:103EC000006890F86003C10715D0810713D500245E +:103ED000400915F0C3FA00B10124394801788C4239 +:103EE00009D004700CB1082100E01021BDE8104099 +:103EF000032013F004B910BD70B52748284E274C95 +:103F00000068716B90F8312090F8305031B184F82E +:103F100030202C485200A06315F003F9B16B002942 +:103F200009D0284884F831502A306A00E063BDE89F +:103F3000704015F0F6B870BD2DE9F0411648184EE6 +:103F4000164C0068B16990F8315090F8307039B172 +:103F5000164884F83050C2386A00206115F0E1F844 +:103F6000F16939B1114884F8317098387A0060618C +:103F700015F0D7F80B480C490078097808438006FB +:103F80008AD50A484C38E0606A00716ABDE8F041A1 +:103F900015F0C7B880E70000F4061000CC731000DD +:103FA000680A1000F4041000F80410002E08012024 +:103FB00024071000F0041000E8041000E9041000C9 +:103FC000C80410005E090120174810B5174904788D +:103FD0000020086000F07FF800F0C2FB052C1AD02A +:103FE000062C18D01249012008701248006890F879 +:103FF000A000000706D41048016821F0020141F03A +:1040000004010160012105200EF026FE4FF48071AD +:10401000002013F074F800F047FE0221BDE81040C4 +:10402000012013F06CB80000E8041000EC0410004C +:1040300039071000F406100000071000514910B5B0 +:1040400009780024012929D0C1070BD04E49032447 +:10405000096891F85022D20703D191F81E1AC907B6 +:1040600000D00B24400704D54849012044F4807453 +:104070000870002C12D0FCF7C1F9454801682143B3 +:104080000160FCF7B9F9012105200EF0E5FDBDE85E +:1040900010404FF48071002013F031B810BD10B5FE +:1040A000C00717D03848006890F8C101010601D454 +:1040B00040060FD5FCF7A2F93648016841F0080127 +:1040C0000160FCF799F9BDE810404FF48001002031 +:1040D00013F015B810BD10B500F0E6FD0221012067 +:1040E00013F039F8012013F0AAF840212A4815F0FE +:1040F000B9F82949012081F82C0013F0BBF80121FF +:10410000022012F0FCFFBDE8104000F022BB70B5A9 +:104110002248234E0568306890EA050426D055B140 +:1041200060B104EA05000446FFF7B9FF2046FFF737 +:1041300085FF356070BDFFF7CEFFFAE700F0B4FDF4 +:104140000221012013F007F800F01DF900F0F9FA40 +:104150002C402046FFF7A3FF2046FFF76FFF00F03B +:10416000DDFA0221012012F0CAFFE2E7002DE1D1C1 +:104170000C480078052801D00628DBD13560BDE861 +:104180007040A8E738071000F40610002E07100052 +:104190000007100014071000CC7310001C0710005B +:1041A000EC041000E80410002DE9F041FF48002461 +:1041B0002646006890F84010C90739D0FC4F39787E +:1041C000022912D0042903D005290BD0062909D0D1 +:1041D00090F841500DF05EFA02460021F548012AA0 +:1041E0000BD028E090F84350F4E790F8425090F854 +:1041F000AE00C006EED50126ECE73A78052A1AD0C3 +:104200000A460160AA4213DDEB4A1378BBB1016094 +:1042100011703878052818D000F0EEF8044600F048 +:10422000F1F8044300F0FCF8044300F007F90443FC +:104230002046BDE8F0810268521C0260E2E716B138 +:1042400001201070E5E70160E3E70124F0E710B515 +:1042500001464022D94814F0A9FF0121BDE81040D1 +:10426000084612F04CBF2DE9FF47D14800780228DC +:104270001CD0032816D0CD4EDFF84493DFF844A3BA +:1042800001274FF00408052814D0062868462DD0D1 +:1042900000F075F9CC480090684612F09CFB04B021 +:1042A000BDE8F087684600F02BF9F3E7684600F0B8 +:1042B000E1F8EFE7684612F069FBFFF775FF044687 +:1042C0004025C0070BD0306890F8A000000704D547 +:1042D00000F0C2F88DF8040001E08DF80480E006DB +:1042E00001D58DF806708DF808700FE0002412F0EB +:1042F0004DFB3068012590F8A000000704D500F0C0 +:10430000ABF88DF8040001E08DF80480C9F8004096 +:10431000CAF80050BEE738B5A449801E05280968D0 +:1043200013D2DFE800F00306090C0F0091F8A34058 +:104330000CE091F8A24009E091F8A14006E091F864 +:10434000A44003E091F8A54000E0012400250DF011 +:1043500029FF00B101256946032012F00AFF0098E9 +:1043600000B91DB1142C01D2142401E004B90124B8 +:10437000204638BD10B500F097FC0221BDE8104082 +:10438000012012F0BCBE8B490020086070478949AB +:1043900000200860704738B5002012F050FF8B48AD +:1043A000006810B100F026FA01E000F0E6F980485C +:1043B0000078FFF7B0FF0446AFF2470100F06CFC55 +:1043C0002046FFF750FF01280ED101216B46002245 +:1043D000084612F0DDFE0121084612F0BCFE7748C7 +:1043E000007830B10EF04FF9BDE83840002012F0EF +:1043F00041BFFFF753FDF7E775480078C00700D0CD +:104400000120704772480078C00707D067480068ED +:1044100090F85002C00701D010207047002070476C +:104420006B480078C00707D06048006890F81E0A03 +:10443000C00701D010207047002070476448007802 +:10444000400707D55948006890F88A09C00701D08D +:10445000082070470020704754490120096891F8EE +:10446000E710090603D55B48407808B10320704780 +:10447000022070472DE9F0410546002712F086FA28 +:10448000FFF792FE04465248DFF820810078C0070B +:1044900008D1D8F8000090F8F00114EAD01F02D03B +:1044A000E00600D44027FFF7C9FF40EA070644EAC8 +:1044B0000607F8070CD0D8F8000090F8F00114EACD +:1044C000D01F02D03C480078C0B1FFF7C5FF28716B +:1044D00071074FF0010000D56871E10600D5A871A1 +:1044E000710600D52872B10600D5E871390700D5EC +:1044F000E87233480460334806609AE60920E6E72C +:104500002DE9F041044612F041FAFFF74DFE064650 +:10451000FFF772FF0546FFF775FF0543FFF780FFC2 +:10452000054300F08BF80543FFF788FF40EA0507D5 +:1045300000F092F840EA070546EA0507F8070BD0B5 +:104540001A48006890F8F00116EAD01F01D009203F +:1045500001E0FFF781FF207169074FF0010000D5EE +:104560006071F90600D5A071A90600D5E071390780 +:1045700000D5E072124806601248056059E62DE940 +:10458000F041064612F002FAFFF70EFE0446FFF76E +:1045900033FF0546FFF736FF0543FFF741FF0543AD +:1045A00000F04CF8054300F057F815E0F406100051 +:1045B000E8041000CC041000E9041000680A1000A0 +:1045C000F8041000F4041000FF410000240710005C +:1045D000EC041000280710000543FFF72FFF0543E8 +:1045E00024480068810602D50024012503E0400626 +:1045F00001D50024102544EA0507F8070BD01E4812 +:10460000006890F8F00114EAD01F01D0092001E001 +:10461000FFF722FF307179074FF0010000D570716C +:10462000F90600D5B071A90600D5F071390700D59B +:10463000F0721248046012480560FAE511480078EB +:10464000C00707D00C48006890F8F001C00701D0FF +:1046500004207047002070470A480078C00707D040 +:104660000548006890F81002C00701D0202070476C +:104670000020704724071000F4061000F804100012 +:10468000F4041000EC041000834810B5006890F8A2 +:10469000A000C0070BD014F02FFF012804D07F48E2 +:1046A000017829B1407818B17D490020486010BDDB +:1046B000012010BD10B5FFF7E7FF012814D100F06D +:1046C00034FA88B97748764C00886168401C00EB62 +:1046D0008000B1EB400F07D914F00EFF012801D084 +:1046E000012010BD00206060002010BD10B500F05A +:1046F0009EF900F014FA6A49002048606A490220D5 +:10470000087010BD10B500F092F900F008FA644985 +:104710000020486064490320087010BD10B500F007 +:1047200086F900F0FCF95E49002048605E490420EB +:1047300008705E49012008705D4908705D49087085 +:1047400010BD574900204860704755490020486017 +:104750007047534900204860534901200870704752 +:1047600010B500F061F94E49087000F060F900F0F2 +:10477000D6F94D490520087010BD70B54A4D484C1A +:104780002878801E042830D2DFE800F017060229BE +:10479000BDE8704000F059B800F045F801281BD082 +:1047A0006068401C6060FFF785FF012802D000F0C0 +:1047B00042F80FE0BDE8704098E700F034F80128B7 +:1047C0000AD03D480078012806D06068401C60602F +:1047D000FFF75AFF012808D0BDE870409EE700F0BF +:1047E00023F908B1217809B1207070BD207006202E +:1047F000287070BD00F0600151EAC0722A4901D0F2 +:10480000042002E0820702D50320087070474207A7 +:1048100001D50220F9E7020701D50520F5E7C0061A +:10482000F4D50620F1E710B500F0FEF804460CF0D0 +:1048300031FF204310BD1848006890F8A0008007A1 +:1048400001D5012070470020704710B5FFF7EBFF3E +:10485000134C01280BD018480078012807D0606855 +:10486000401C6060FFF7E7FF012803D00DE0002047 +:10487000606010BD08486168006890F8A8000A30C0 +:10488000884202D2BDE810403CE7FFF713FF012841 +:10489000EFD1BDE8104029E7F4061000C70610006C +:1048A000D004100036071000E80410002C07100098 +:1048B0002D0710002E071000340710002DE9F041DD +:1048C000874C07460E462068002590F8B62085489C +:1048D0000FF0C1FD02008448294638D00278012536 +:1048E000521CD2B20270236893F8B73093422FD291 +:1048F00001707C48760032463946543814F011FC79 +:104900007848324639462A3814F00BFC774800784C +:1049100005281DD02068032690F85012C90703D13E +:1049200090F81E0AC00700D00B26FBF767FD704801 +:10493000016831430160FBF75FFD202105200EF087 +:104940008BF94FF48071002012F0D9FB00E0017068 +:104950002846BDE8F0812DE9F05F060059D0624C91 +:104960000025DFF88891E5702F4699F80000AA46E7 +:10497000022803D0032801D0052849D1B4F90450F6 +:104980003046A278294600F065F8DFF85481A0701F +:10499000D8F8000090F8AE00800704D530462946CC +:1049A000FFF78CFF074600214E4B08464FF0010BE6 +:1049B000D8F800200FE000BF33F91060B2F8B0C0A3 +:1049C000664506DD92F8AF60491C8E4201DC5D460B +:1049D00004E0401CC0B2A842EEDB554699F8000046 +:1049E0004E46022801D0032802D114F085FD05436C +:1049F00075B13078022804D0032802D0052804D0ED +:104A000006E0657084F803B006E0607800B917B17D +:104A10006570BDE8F09F657000F046F9BDE8F05F95 +:104A20000221012012F06BBB2F48407870472E48BE +:104A30000021012201708270294A126892F8312007 +:104A400082802A4A1278052A02D0062A00D04170B4 +:104A50007047ECE72DE9FC418046234814460D469B +:104A60004078164640B91F480A467F2341465438CD +:104A700000940FF045FD0026194F386890F8AE10ED +:104A8000C90700D0ECB117486A0041462A3814F033 +:104A900048FB144A2B46543A02F12A0111480FF000 +:104AA000F8FC386890F8AE10490707D590F8B83090 +:104AB00023B10C492A4608460FF03BFD3046BDE8BD +:104AC000FC81B0F9B410CDE90015064AB0F9B23056 +:104AD000543A414602F12A000FF062FCD9E7000087 +:104AE000F4061000280A0120D8041000E804100081 +:104AF0000007100070B50028049E0DD0002406E0C9 +:104B000030F911509D4201DD954200DB641C491EC5 +:104B1000F6D2B44201DD012070BD002070BD3F48D7 +:104B20000021017041607047F9E73C480078704708 +:104B30002DE9F34FDFF8E8A084464FF00008DAF8DB +:104B40000000DFF8D8B081B090F816144746C907C6 +:104B5000C1462BD03349097803292DD004292BD005 +:104B6000052936D1B0F81E64B0F8205490F81D44E1 +:104B7000BCF1000F08D0009490F831102BB232B283 +:104B80006046FFF7B7FF8046029850B10094DAF80C +:104B900000002BB232B290F830100298FFF7AAFF53 +:104BA0000746B8F1010F0ED0012F0CD09BF8001072 +:104BB000584601291DD00AE0B0F81864B0F81A541C +:104BC00090F81C44D4E79BF80010584619B1CBF874 +:104BD0000490BDE8FE8F4168491C4160DAF800206E +:104BE00092F817248A42F4DA01210170CBF804907C +:104BF0000DE04168491C4160DAF8002092F8172462 +:104C00008A42E6DA80F800900021CBF8049003B0E5 +:104C10000720BDE8F04F0EF01FB80000E0041000C0 +:104C2000F4061000E804100008B500F03FF8314C1D +:104C30006B4600227E21012012F0AAFA009841075B +:104C400003D5FFF764FA042119E0010703D5FFF744 +:104C500015F8082113E0C10603D5FFF7B5F91021B7 +:104C60000DE0810608D52078052801D0062801D15D +:104C7000FFF7AAF9202102E0410604D540210120D6 +:104C800012F069FAD4E78007D2D50221012012F090 +:104C900062FAFFF780FBCBE700EB80004FF6FF7274 +:104CA00002EA400013F0B4BF13F0D4BF10B5114CAA +:104CB000002001216060A06021700F4960700870C1 +:104CC0000E4908700E4908700E490870FFF7C1FEC2 +:104CD000FFF72AFFFFF75BFBFFF737FD0A48006885 +:104CE00090F84003C00703D0A06840F00200A06025 +:104CF00010BD0000E80410002F0710003807100056 +:104D0000390710003A071000F406100001F070B9DE +:104D10004548407801280DD14448454990F82C0079 +:104D200091F82C10C84205D10123424A40493F481E +:104D300000F0D5BC704770B50024012390F82C50CA +:104D400008E0C61896F921608E4202DB964200DC2C +:104D5000641C5B1C9D42F4D2012C01DC012070BD5F +:104D6000002070BD2DE9F043994600231F4647F609 +:104D7000FF764FF0FF3C012590F82C400DE000BF7E +:104D800000EB050898F92180884505DB904503DC98 +:104D9000431993F9213002E06D1CAC42F0D2641C3F +:104DA0000AE0051995F921508D4205DB954203DC97 +:104DB000204490F9217001E0641EF2D1BB4209D178 +:104DC0000AE000BF39F91300B04202DA06464FFA92 +:104DD00083FC5B1CBB42F5DD6046BDE8F0832DE93A +:104DE000F04117460E460446C27881780F48FFF717 +:104DF000A2FF050006D1E278A1780F4B0B48FFF720 +:104E0000B1FF3070627821780948FFF794FF0600FF +:104E100006D162782178094B0548FFF7A3FF387067 +:104E200005EA0600BDE8F081A806100098231000EE +:104E3000F023100050261000F00C01201A0D012064 +:104E4000FE480021FE4B01700122C1601A704170C2 +:104E50008170018170472DE9F04F8246DDE90A0932 +:104E6000012547F6FF779B46AC46FE430446DDF836 +:104E700024E014E032F8143031F81480A3EB080376 +:104E80001BB2BB4200DA1F46B34200DD1E46002BB8 +:104E900002DD4FF0000C02E001DA4FF00005641E65 +:104EA000E8D225B1BCF1000F01D0002309E055EA9A +:104EB0000C0306D025B9BCF1000F01D0334600E049 +:104EC0003B4600273D465FEA090402D00124861EC6 +:104ED00001E00024461ECEF1000910E032F814C0B3 +:104EE00031F81480ACEB080CACEB030C0FFA8CFC23 +:104EF000DC4503DACC4501DD67446D1C641CB4421B +:104F0000ECD905B9012597FBF5F21A4405E000BF7D +:104F100031F8103013442AF81030401EF8D2BDE8A2 +:104F2000F08F2DE9F0470025894629462F462E4669 +:104F3000A8462B460DE000BF30F913C039F91340E5 +:104F40000CFB0C660CFB047704FB048865442144CD +:104F50005B1C9342F0DB87FB020485FB013CC71A14 +:104F600086FB020385FB056564EB0C04B0EB060CC5 +:104F700063EB050688FB020381FB0121851A63EBC5 +:104F800001086421A7FB010304FB0131002207FB98 +:104F900002113346624614F0A0F80246A2FB070352 +:104FA00001FB073102FB04112A46434614F095F831 +:104FB000002C00DA4042BDE8F08770B503460020BF +:104FC000024601EBD17408E003EB420633F91250BC +:104FD000B6F90260AD1B2844521CB2EB640FF3DB40 +:104FE000621008E003EB420533F9124035F9025C28 +:104FF000641B2044521C8A42F4DB70BD2DE9F04151 +:105000008E4C00208F4DA070607028684FF0010713 +:1050100090F88B09C00736D08B4E8C486169327886 +:1050200000F045F9286832788849A84600F6BC1097 +:10503000FFF777FF054631788448FFF7BEFFD8F8C1 +:10504000001091F8A429AA4204DAB1F8A2298242F8 +:1050500000DAA770322D14DD7C4AB2F90000002876 +:1050600000DA4042B1F88C1988420ADD307802EB50 +:10507000400030F9020C002800DA4042884200DD8E +:105080006770BDE8F081724E7048216932782A3825 +:1050900000F00DF96D49286832782A39A84600F6E3 +:1050A000BC10FFF73EFF0546684831782A38FFF705 +:1050B00084FFD8F8001091F8A429AA4204DAB1F8C4 +:1050C000A229824200DAA770322DDADD5F4A2A3A3D +:1050D000B2F90000002800DA4042B1F88E19C3E7A7 +:1050E0002DE9FE4F574D8946DFF8508129689346D8 +:1050F00098F8002091F8A7190C9E0C099A46012AED +:1051000001D101F00F04524F0096014623463A7830 +:1051100050480FF0DBF923464B4C4E48009622785E +:1051200049462A300FF0D2F9286890F88A194907C1 +:105130001BD5B0F9941901233A788DE80E00454942 +:10514000B0F992395A460846FFF785FE28680023D1 +:105150002278B0F998198DE80E003E49B0F99639D9 +:105160002A3152460846FFF776FE344802211030B5 +:105170000BF03CFD3148022114300BF037FD3B7839 +:105180005A4634494646D8F810000FF082F93149A2 +:10519000237852462A3170690FF07BF9286890F81D +:1051A0008A09000701D5FFF729FF244802211030A2 +:1051B0000BF07FFD2148022114300BF07AFD2549C8 +:1051C0003B785A4601F176000FF063F9237803B07B +:1051D0005246BDE8F04F1F492A3101F176000FF029 +:1051E00058B92DE9F84380461548144C0026057837 +:1051F0000F462670032012F022F8174B174A394643 +:1052000040460095FFF76CFF032012F033F80D487D +:10521000134D4FF48077016891F88B09420602D54F +:10522000A278012A24D0268180061CD50749763928 +:10523000A1F12A0000F053F8012813E0FC0410004B +:105240002E071000F406100076061000680B0120EF +:1052500075061000520A0120AC72012082720120F2 +:105260000007100015D000F064F82070BDE8F88346 +:105270002289521C12B2228191F8A51901F00F0166 +:105280009142D1DA26812868432140F48070286059 +:1052900004E02868412140F48070286005200DF06A +:1052A000DBFC3946BDE8F843002011F028BF30B5DB +:1052B00047F6FF73002405E031F91450AB4200DDDE +:1052C0002B46641C9442F7DB002405E031F81450AF +:1052D000ED1A20F81450641C9442F7DB30BD2DE920 +:1052E000F041324C0F4600252168B1F9B729304909 +:1052F00009780FF0B0F806462068B0F9B7292D48B4 +:10530000017838460FF0A7F8014600222A48012EFE +:1053100001D1012902D0C2602846B2E6C168491C09 +:10532000C160236893F8B9398B42F5DA0125C26070 +:10533000F2E72DE9F0411D4F1F4C00253868B0F908 +:105340008E29A280B0F88C19E18090F89E39184817 +:1053500001781A4800F017F806463868B4F90620B4 +:1053600090F89E391348017814482A3000F00BF861 +:10537000012E06D1012804D1607810B9A07800B9B7 +:10538000012528467DE670B500252C4606E000BFC5 +:1053900030F91460964200DD6D1C641C8C42F7DB12 +:1053A0009D4201D9012070BD002070BDF40610009F +:1053B0007506100076061000FC041000C80A0120D3 +:1053C00010B55821FD4813F04DFFFC4858215830C6 +:1053D00013F048FFF9480021B030C0E90011C0E9DE +:1053E00002111030C0E90011C0E902111030C0E90B +:1053F0000011C0E902110846F149086010BD2DE90D +:10540000FF5F06468946EF48EF49984600780968ED +:105410001446012850D0B1F924AA91F8265AB1F9BE +:10542000207A114648460FF0D6F883462146484672 +:105430000FF0EFF80090394658460EF03AF80FFAA0 +:1054400080FB394600980EF034F800B2ABEB000058 +:105450006843642190FBF1F0384405B2A8F8085085 +:10546000701C00210390C8F80010C8F80410B9F9A6 +:105470000000A84202DD03990120087009EB4400F6 +:10548000761C30F9022C3119AA4202DD012201F802 +:10549000012CB9F9023003EB0A0212B2AB4218DD5B +:1054A000B9F90030934203DDB9F9043093420ADCC4 +:1054B000039B01225A700CE0B1F96AA291F865527F +:1054C000B1F96672ADE7D8F8006046F00206C8F898 +:1054D000006030F9043CA4F1020B03EB0A0212B2A3 +:1054E000AB4216DD30F9063C934203DD30F9020C85 +:1054F000904203DC012001F8020C0AE0D8E90064C4 +:105500005A460120002113F0D5FD06430C43C8E99B +:105510000064022458E000BF39F91400A84252DDAB +:1055200009EB44010291504431F9021C00B281425E +:1055300004DD029AB2F90220824210DC029A32F9AA +:10554000042C824204DD029AB2F90220824206DC77 +:10555000814235DD0299B1F90410814230DDD8E98C +:10556000006722460120002113F0A4FDCDE90001CF +:1055700006430F43621E01200021C8E9006713F0B3 +:1055800099FD02460B4606EA020007EA03010843BA +:1055900019D0029839F9141030F9020C814209DA55 +:1055A00096439F43C8E9006703990120214401F80D +:1055B000010C08E0DDE900108E438743C8E900676D +:1055C000039901200855641C5C45A5D3BDE8FF9FE5 +:1055D0002DE9FF4F81B0824600211D4683F82C1033 +:1055E0000B2090464B1E794C08E0002229188A7542 +:1055F00081F8213005EB400122880A80401EF4D258 +:105600007048017870480129006806D0B0F9222A54 +:105610004FF0000B5946584616E0B0F96822F7E7FC +:105620000AEB00035C7874B11AF800400CB9491C0D +:10563000C9B25970029B33F91030934203DD012344 +:105640008B4043EA0B0B401C4045E9D36048009077 +:105650000E984FF000094C46C0E9009938E000BFB1 +:105660000AEB0400427892B30121914011EA0B0F3A +:1056700002D1002141702AE01AF8041039B909F169 +:10568000010101F0FF095249009105F8194080F825 +:1056900001900E9822460021D0E90067012013F006 +:1056A00009FD06430E980F43C0E9006705EB0900AA +:1056B000817D491C817505EB49014C700299009A66 +:1056C00031F91410914202DD009180F82140641CF0 +:1056D0004445C5D385F82C9005B0BDE8F08F2DE981 +:1056E000F84F0C4605461E4691461721394813F0DF +:1056F00097FD2821384813F093FDDFF8E0A0384FDC +:1057000009F108089AF8001076B10A4605F130034D +:1057100034493048FFF773FE04F130033A783249D8 +:105720002D48FFF76CFE11E04A462A4800F0E9F8E0 +:1057300042463978284800F0E4F80020C5E90C001A +:10574000C4E90C002948008828872087284E288F24 +:105750002B4626F8110F208F7080CDF800909AF814 +:10576000002020491B48FFF733FFCDF80080234677 +:105770003A781D491848FFF72BFF95F82C1030791F +:1057800061F30300307194F82C1061F3071030714D +:10579000BDE8F88F70B50C4C206890F82612090708 +:1057A00043D514490A780AB9497831B105490978CD +:1057B000012921D0B0F8381220E036E098231000FB +:1057C0001405100022051000F40610002C950100AD +:1057D0000080FFFFA2130120B913012075061000FD +:1057E00076061000F00C01201A0D0120280510008B +:1057F0007C580120A8061000B0F8401201220DB21A +:10580000B0F93C124B4800F085FA20680022B0F94C +:105810003E124848103000F07DFA2946BDE870403D +:1058200044480122103800F075BA42484FF0FF3169 +:10583000C0E90011C0E902111038C0E90011C0E947 +:1058400002112030C0E90011C0E9021170BD2DE93C +:10585000FF4F83B01546069991F84A1002290CD0E3 +:1058600001290CD0334910398A464FF0000BA97832 +:1058700013F070FE8146A87832E02E49F4E72D49F6 +:105880001031F1E702462C780120002113F012FCC0 +:10589000CDE900011DE000BF19F804100498814211 +:1058A00016D1DDE90023DAE9000110401940084370 +:1058B00023D0DAE9026722460120002113F0FAFB27 +:1058C00006400F403E4318D00BF101001FFA80FB49 +:1058D000641C6878A042DFDA09F1280908F10100A8 +:1058E000E97880464145CDDA06995FEA0B00A1F8D8 +:1058F00026B000D0012007B0EFE6002009F8040030 +:10590000E6E72DE9F0479146451C0C464FF00108AB +:105910000CE0D9E9006722460120002113F0CAFB00 +:1059200006400F403E4301D005F80480641EF0D2CB +:10593000BDE8F087582410009D4A10B51368002177 +:10594000B3F81422824205DA93F81022520701D5E7 +:10595000022108E0B3F81222824204DA93F810021E +:10596000800700D501219348934C4278914214D18D +:10597000A17891420DD0914B1B781A43904B1B7824 +:105980001A4307D04168491E4160002901DC407874 +:10599000A07010BD41704168F7E759B1022901D1EB +:1059A000012A07D093F8182242604170002AF0DCE7 +:1059B000A17010BD93F81922F6E770B5814A824BA9 +:1059C0007D4D16787A4A9C7900211268AB78012EB9 +:1059D00002D17E4E36784EB1B2F81462864217DAA2 +:1059E00092F81062760713D5022125E0B2F81C6206 +:1059F000864203DA92F810627607F5D4B2F81A629A +:105A000008E000BF92F81002800705D5012113E0DD +:105A1000B2F812628642F5DB73B16848007801285B +:105A200003D067480078012803D192F810020007DC +:105A300001D5012C00D119465E4834B119B100BF1F +:105A400092F819224260A97070BD0029F8D1002B8C +:105A5000F6D04468002CF6DD92F810120A0755497A +:105A60004968A1F1010102D5594A127802B1416099 +:105A70001946E8E74E484F49006890F81002C20600 +:105A80004FF0000003D44C4A907048704860087092 +:105A9000704710B504464648006890F81002C006EA +:105AA000204602D5FFF789FF01E0FFF745FF424896 +:105AB00082784848417B62F307114173A0F82F4078 +:105AC00010BD2DE9FC5F8346434800250A46067851 +:105AD00000782F4641002C46012A17D0DFF8D0A0CD +:105AE000DFF8F880DFF8F890DAF8000090F810227C +:105AF000920610D5B0F92012CDE90016B0F91E3289 +:105B00004246594648460EF04BFC09E033484C38B3 +:105B100013F086FB42E00A465946314813F001FB78 +:105B20002E484C3835E000BF38F9142039F91410EC +:105B3000511A00D54942DAF8003009B293F8102220 +:105B400052060BD5204A9279012A07D1254A1278AC +:105B500022B9B3F822228A4200DA012730F9142050 +:105B60008A4202DA93F8163201E093F817325A4368 +:105B7000C3F5807301FB0321CA1701EB12610912FF +:105B800020F8141030F91410A94200DD0D46641CF1 +:105B900024B2B442C8DB2846FFF77BFF72005946A7 +:105BA0000E4813F0BEFA03480770BDE8FC9F0000E2 +:105BB000F406100018051000280710007C061000DD +:105BC000200510007D061000A80610007E061000BB +:105BD000820610007C58012075061000000C012080 +:105BE0004C0C0120340510002DE9F04F8146DDE911 +:105BF00009B5012047F6FF779A468446FE432C46B6 +:105C000015E000BF32F8143031F81480A3EB08031C +:105C10001BB2BB4200DA1F46B34200DD1E46002B1A +:105C200002DD4FF0000C02E001DA4FF00000641ECC +:105C3000E8D220B1BCF1000F01D0002309E050EA06 +:105C40000C0306D020B9BCF1000F01D0334600E0B0 +:105C50003B4600273C462846CBF1000C0EE000BF37 +:105C600032F8106031F81080A6EB0806F61A36B24A +:105C7000564503DA664501DD3744641C401EEFD209 +:105C800004B9012497FBF4F0184404E031F815201E +:105C9000024429F815206D1EF8D2BDE8F08F2DE9D9 +:105CA000FF4F1D4681B04FF0000BC5E900BBF8481F +:105CB000D84691460378F7489942D0F800A005D11C +:105CC000BAF83802484501D14FF001080C46491E88 +:105CD00000911AE0B8F1000F05D00098844200D07E +:105CE0000CB9BAF93A92019830F9141049450CDD13 +:105CF000D5E900674FF0010B22465846002113F00A +:105D0000D9F906430F43C5E90067641EE2D258463D +:105D100005B0C2E72DE9F04106460346DC481546CA +:105D20000C460A460178DC48FFF7B9FF15B130464A +:105D300013F0F2FBD94806F108031F460178D64854 +:105D400022462A30FFF7ABFF002D07D0304613F074 +:105D5000E3FB3846BDE8F04113F0DEBBBDE8F0815F +:105D60002DE9F00FCB498246DDE909400968089E1C +:105D7000914691F871134FF0000B01F0030C0128CC +:105D800001D0002237E000200CE000BF04FB00F14E +:105D900003EB4102DAF800501560BAF80410401C19 +:105DA000918000B26045F1DBA6F800B0BDE8F00FCD +:105DB000704700BF3AF91200B6F9005001460027BB +:105DC00012E000BF04FB052833F91880884500DA8B +:105DD0004146804500DD4046002D02DD6D1E2DB29E +:105DE00000E002257F1C3FB26745EBDB401A29F833 +:105DF0001200521C12B2A242DCDB47F6FF710020F7 +:105E000007E000BF39F910208A4200DA1146401C31 +:105E100000B2A042F6DB002007E000BF39F81020F6 +:105E2000521A29F81020401C00B2A042F6DBB6F945 +:105E30000000022802DA401C308001E0A6F800B021 +:105E4000B6F90000620060435146BDE8F00F03EB75 +:105E5000400013F066B930B5002B0DD18D4B1C6896 +:105E600094F86E33B4F86F439D078D4B04FB04F434 +:105E70001B6802D59C4208DC30BD9C42FCDD894B8E +:105E80009C7814B95B78002BF6D000230AE000BFA1 +:105E900030F9135031F91340A54201DA20F81340CC +:105EA0005B1C1BB29342F3DB30BD2DE9FE43804601 +:105EB00017468946032011F0C2F97B4C744D0097B8 +:105EC00075482A784146763823680EF0FFFA734EFB +:105ED00000977148327849464C3823680EF0F6FA3C +:105EE0006C4C206890F82612C9071AD02A78B0F9AD +:105EF0002A12CDE900126849B0F9283276396B4A86 +:105F00000846FFF771FE20683278B0F92E12CDE90D +:105F100000126149B0F92C324C39654A0846FFF746 +:105F200063FE5D492B78614A76395B480EF0B1FA21 +:105F3000594933784C395E4A01F176000EF0A9FADE +:105F4000206890F826128A0704D45A4A12788AB137 +:105F500049070FD5504990F837322A7808460EF095 +:105F6000E8FA20684C49327890F837322A310846EE +:105F70000EF0DFFA206890F86E03C10733D04007B7 +:105F800001D5454800E0404629784B4ACDE900213B +:105F90004A4B029703F5B1724449FFF7E1FE3B46D5 +:105FA0002A7847493C48FFF756FF206890F86E036F +:105FB000400702D538482A3000E0484631783E4A4A +:105FC0003E4B921CCDE900217E33029703F5877288 +:105FD0003749FFF7C5FE3A492F483B4632782A3108 +:105FE0002A30FFF738FFBDE8FE43032011F042B925 +:105FF00070B5314C3349241F0025A570012008706D +:106000002448257065700068B0F83002208100F0E7 +:10601000DEF9E560256170BD2DE9F0410E462949A4 +:10602000254C07460D780020241F0870607000F092 +:10603000CEF92A4631463846FFF737FF19484178EE +:1060400014480029A17815D0012919D00068B0F9A9 +:1060500032121B4D2181763501222846FFF75AFE68 +:10606000D5E9000108430FD0D5E9020108430BD060 +:1060700001200AE0012903D00068B0F93012E8E7F6 +:106080000068B0F97812E4E70020207066E60000AE +:1060900075061000F4061000F00C012076061000C2 +:1060A000B406100028071000380610000C720120FA +:1060B00036720120340510002405100078241000E9 +:1060C000DA2510002D0710002DE9F34F0446C748CC +:1060D000A7B04FF0010A0178C5480129006815D022 +:1060E000C4490978A9B1B0F95462C34801214FF0FD +:1060F00000090078C24D801E00F0FF08BF488346AB +:1061000003789A1E02F0FF0C224612E0B0F95962A1 +:10611000EBE7B0F95262E8E7484605E032F9107063 +:10612000AF4200DD3D46401C6045F7DD02EB430217 +:10613000491C4145F0DD5F465A0004EB43016846C7 +:1061400012F0EFFFAF4A38786B461288414202EBFB +:10615000410109B2420004EB410103EB400012F09F +:10616000E0FF38786946420008460EF000FA281A27 +:10617000289AA54900B2022A08D0A1F85200B042DC +:1061800001DD4FF0000A504629B086E5A1F8500025 +:10619000F5E72DE9F047DFF86092044699F8000032 +:1061A000022867D99948007818B9904800780128E2 +:1061B00060D08F4F0125386890F85002410794480D +:1061C000006824D5934906460120D1F800808D4906 +:1061D000B8F83020B1F90040A24216D140F23C613B +:1061E0008D4808F1320813F01BF88B4807E000BF18 +:1061F00036F8141038F81420891A20F81410641E88 +:10620000F6D201218448FFF75FFF05460AE002212C +:10621000FFF75AFF064603212046FFF755FF0643C6 +:1062200000D10025386890F85002000721D599F870 +:1062300000207A487A49022A1BDB714C531E04E085 +:1062400030F91360A64200DD34465B1EF8D1801C95 +:10625000921E0EF08CF93968201A6B4A00B2B1F91F +:106260005712A2F85400884203DD3DB10220BDE878 +:10627000F0870DB10020FAE70120F8E70320F6E7E8 +:106280002DE9F04107466748164600240078B8B368 +:106290005648584D0078F0B164486349006800F0F2 +:1062A00063F85348604900680A68B0F85F329A4260 +:1062B00017DDB1F9061090F86102814211DD5D48E9 +:1062C0005B4AB0F90010384600F0E8F8044644B1E3 +:1062D00000F0BAF80CE02C78012912D00029F6D190 +:1062E000002486B1544900200870287800B10124A8 +:1062F000524E2878317888420CD038B1012106E01E +:106300000DE00124E4E700F0B5F8EEE700210620F7 +:106310000CF0A2FC287830700CB101201EE50020A2 +:106320001CE570B50446032010F089FF2046FFF7F6 +:1063300030FF0446032010F09DFF3349C87B64F30F +:106340000510C8733148017821B100210170204641 +:1063500000F01CF9344D35480C3D21462A78006880 +:10636000FFF78EFFA87070BD30B5214A1268B2F8F1 +:106370005D22524213B20022CA808A800A60214AFA +:10638000B2F9002013E000BF30F91240002C0EDA01 +:106390008C88641C8C8030F912500C682C440C6082 +:1063A00030F912409C4202DACC88641CCC80521E28 +:1063B000EAD2154A887982F858000868002800DA7D +:1063C0004042A2F8590008684042086030BD1848B1 +:1063D0000021C0E90011C0E902110846184981F8FE +:1063E0002C00184981F82C00704700003905100076 +:1063F000F406100034051000750610007606100033 +:106400000080FFFF860610007C5801203805100030 +:10641000A4061000F8061000660D01200C72012081 +:106420004C0C0120A80610002C0510009C06100042 +:1064300050261000340610003705100035051000F6 +:1064400098231000F023100057480021C1700278F3 +:10645000002A0ED18278554B521CD2B282701B6832 +:1064600093F8623203F00F03934202D201220270CA +:10647000817070474C48002181700278002A0CD04E +:10648000C2784A4B521CD2B2C2701B6893F8623277 +:10649000B2EB131F01D90170C17070472DE9F74F9E +:1064A00086B08B46D2E90001CDE90201D2E90201B2 +:1064B000CDE9040102A813F02FF804A813F02CF87A +:1064C0003B4800252F4606782FE0F1B2069813F0DE +:1064D00039F882463748324600210478012012F00C +:1064E000E9FD029A00EA0208039801EA0009DDE9E1 +:1064F0000401CDE9000116E03AF91410594512DD06 +:1065000058EA09000DD022460120002112F0D2FDE8 +:10651000DDE9002310401940084302D07F1CBFB2C0 +:1065200001E06D1CADB2641EE6D2761ECDD22248CB +:1065300000F8565F47701D48006890F85B12A9424A +:1065400007D890F85C02B84203D3012009B0BDE837 +:10655000F08F0020FAE7144810B54178017000214F +:106560008170C170FFF744FDBDE81040FEF728BF01 +:106570000D4800210D4A01704170126892F85022B6 +:10658000920700D501214171017170470B490A78CA +:106590000549012A04D04A79012A03D1002801D1F2 +:1065A000002048717047000034051000F406100008 +:1065B00075061000760610007C5801203A0710007E +:1065C0002DE9F84F1E4615468846834600244FF0B5 +:1065D000AA090A9F4FE0305D08B9285DF0B306F8BC +:1065E000049038F9140000F0E7F828F81400285D4A +:1065F000A0B305EB040A1AF8011C81421CD0AA289A +:106600001AD00AF8019C0BEB4401009131F9020CFD +:1066100000F0D2F8009921F8020C311901F8019C20 +:1066200008EB4401009131F9020C00F0C5F8009923 +:1066300021F8020C285D88B19AF80110285D81428A +:1066400018D0AA2816D08AF801900BEB440ABAF9A0 +:10665000020000F0B1F8AAF8020000E00AE03119E7 +:1066600008EB440A81F80190BAF9020000F0A4F89E +:10667000AAF80200641CBC42ADD3BDE8F88F8C4977 +:106680000020086070472DE9F74F8AB017460C4686 +:1066900004F0D4FF8749002811F85B0F0FD040F0B9 +:1066A00001000870844804908448DFF804A20125A2 +:1066B00090F800804FF0000BDAF8009026E020F010 +:1066C000010008700DB0BDE8F08F0120A84010EA6D +:1066D000090F1AD17A4800EB85060498B17812F0B8 +:1066E00039FFB2785B460DE0317805E010F801C063 +:1066F000AC4500D14354491C96F801C08C45F5DAED +:106700002830521CF1789142EEDA6D1C4545DCD9F7 +:1067100000210A9812F024FF089001210A9812F033 +:106720001FFF01900021644812F014FF079001211F +:10673000614812F00FFF8046651EE9B20A9812F018 +:106740000FFF8146A61EF1B20A9812F009FF0490CD +:10675000E9B2594812F0FEFE0546F1B2564812F071 +:10676000F9FE06460097DDE9072043460199FFF749 +:1067700027FF33462A46009748460499FFF720FF33 +:106780000A98002100EB4700851EA0F104084A4842 +:10679000C619701E12F0DEFE8146B01E002112F0F6 +:1067A000D9FECDE9004703464A464146284600F057 +:1067B00013F8CAF800B085E74249096891F86124E6 +:1067C0004243642092FBF0F0B1F85F2400B28242B1 +:1067D00001DAB1F95F0470472DE9FF4F83B09A46A3 +:1067E0001746894600254FF0AA0BDDF840805BE094 +:1067F000119805FB00F605EB8500C4001AF80400AB +:1068000008B9385DE8B30AF804B039F91600FFF7A3 +:10681000D3FF29F81600385D98B33919019111F8A2 +:10682000281C81421ED0AA281CD0019800F828BC40 +:106830001198311A0398009130F91100FFF7BCFF4D +:10684000039A009922F811000AEB040101F828BC10 +:10685000009939F91100FFF7AFFF009929F81100ED +:10686000385D70B1019890F82810385D81421AD0D7 +:10687000AA2818D0019880F828B0119806440398E7 +:1068800000E010E030F91600FFF796FF039921F8B9 +:1068900016000AEB040181F828B039F91600FFF759 +:1068A0008BFF29F816006D1C4545A1D307B00AE7F8 +:1068B0003C0510007C580120B01A0120CA051000C8 +:1068C000481E0120F40610002DE9FC5FFF4F8046B2 +:1068D00099463868164690F89F12B0F9A6424906C4 +:1068E00007D590F83100FF22C100F948103112F0AD +:1068F0008FFCF848417809B9807818B13868B0F948 +:10690000A8422CE0396891F89F02000627D5F24A88 +:10691000F24D0023B2F90040F14A2D781846127862 +:106920006A4305E036F91050A54200DD2B44401CB7 +:106930008242F7DC0A20B3FBF0F0EA4D002325F891 +:106940008A0FB1F8A622CDE90023B1F8A832B1F838 +:10695000A222B1F8A4120CF0E6FD04B26C8000256E +:10696000DFF86CA3BB461FE00C980C9A684306EB5B +:106970004007394608460CF021FD224611463846AC +:106980000C9B0CF03DFDDBF8002092F8A02212B128 +:106990000C9B0CF055FD0AEBC502C2E9020108EBA5 +:1069A000C5026D1CC2E900014D45DDDBDBF80000CE +:1069B00090F89F02400617D500205546C84E10E0BB +:1069C00005EBC00393E80610DF6801EA0C013A40CA +:1069D000D3E904731A4008EBC0033940C3E900123D +:1069E000401C31788842EBDB2046BDE8FC9F2DE956 +:1069F000F04FB64C8025BC4E236893F8311093F8C5 +:106A0000300001FB00F201E026F81250521EFBD2CA +:106A100093F89E22A64612074FF0640831D54A1E0D +:106A200002FB00FADFF8C0B203F59469024626E0E3 +:106A300019F802300AEB0204DB01B3FBF8F30BEBAD +:106A400044050C4619E0802B05DDC3F18006664342 +:106A500096FBF1F606E0A3F1800606FB04F797FB30 +:106A6000F1F7F61BB5F9007080367743FE1707EB98 +:106A70005666F6112E80A5EB4005641EE3D2521E29 +:106A8000D6D2DEF80020F24692F89E32DB062FD5F1 +:106A900002F59869944B4A1E424303EB42050A46AD +:106AA00024E000BF19F80230DB01B3FBF8F603461F +:106AB00018E0802E05DDC6F180045C4394FBF0F401 +:106AC00006E0A6F1800404FB03F797FBF0F7E41B54 +:106AD00035F9137080346743FC1707EB5464E411F5 +:106AE00025F813405B1EE4D2A5EB4005521ED9D217 +:106AF000DAF8004094F89F22D20720D07A4E002383 +:106B000004F59C6419E000BF03FB00F206EB4207AA +:106B100000220FE0A55CED01B5FBF8FC37F912503F +:106B200005FB0CF54FEAE57C05EB5C65ED1127F8FC +:106B30001250521C8242EDD35B1C8B42E4D3BDE861 +:106B4000F08F08B5009380230DF0B0FC08BD08B5A8 +:106B500000931346654AB2F900200DF0B7FC08BD5A +:106B60002DE9F05FDFF86C91614C002299F801305B +:106B700020786049022B00D220B18A70022B00D20B +:106B800000B1CA708B79A246034300D00A714F4C02 +:106B9000594A20681278B0F90853B0F92263B0F965 +:106BA0004273062A01D1B0F904538846C97839B135 +:106BB00052490978012903D1B0F94E63B0F9505315 +:106BC00090F87C10090604D54D49097809B1B0F94F +:106BD0007E5012F081FC68B1206890F80B132944B4 +:106BE0000DB290F8251390F84503314438440EB2A5 +:106BF00007B209E099F80100022805D32068B0F82F +:106C00000C1309B1B0F90C5398F80600A0B1206834 +:106C1000642190F8690300FB05F292FBF1F22A442B +:106C200015B200FB06F2784392FBF1F290FBF1F013 +:106C30003244384416B207B2DFF8C8903249DFF860 +:106C4000CCB0A9F800500E80ABF800702068304B33 +:106C500090F80A23AA1A1A8090F82423B21A2D4E0B +:106C6000328090F84423BF1A2B4A17802B4F97F895 +:106C700000C0BCF1000F02D0BF78ED1B1D8098F85A +:106C8000005055B1264D2D783DB1B0F86C52A9F8A1 +:106C9000005090F86E72ED1B1D809AF800503DB1C7 +:106CA000B0F86C52A9F8005090F86E02281A1880BB +:106CB00098F8020020B9B9F80000088018883080E0 +:106CC00098F8030070BBB9F800102CE0F40610002F +:106CD000182710002807100036061000760610004E +:106CE000750610007C580120E21301208606100072 +:106CF00040051000A8061000E804100081061000EE +:106D000034071000280610002A0610002C06100078 +:106D10002E0610003006100032061000C7061000C4 +:106D20003405100003E0ABF8001018881080B2F9A9 +:106D30000020B6F900101F46B3F900000CF0A7FBC5 +:106D4000FD4D4E46DFF8F8B32880B9F80010DFF8A3 +:106D5000EC93FC48A9F800103988ABF800100078D3 +:106D6000B0B112F0B9FB10B1206890F85E04216850 +:106D7000B1F85B241044A9F8000091F85D14401AA2 +:106D800001B2ABF80010B5F900000CF08EFB2880C2 +:106D90003088ED4EED4AEE4930801080388808800A +:106DA00098F8040000B32068B0F844342BB198F888 +:106DB000063013B1B0F8443404E0B0F8423413B1F3 +:106DC000B0F842343380B0F8463433B1B0F84634CA +:106DD000138090F84804181A0880B1F90010B5F92A +:106DE00000000CF062FB2880DA48DB4D007818B117 +:106DF0002068B0F8BE020FE09AF800000028F7D132 +:106E00002068B0F9BC02288098F80410002904D04A +:106E1000B6F900100CF049FB2880BDE8F09F2DE981 +:106E2000FF4F85B00746082112A8149D10F056FFA9 +:106E3000049000286BDD4FF0000ADDE91201564690 +:106E4000D046D346D146CDF804A05446CDF800A094 +:106E5000CDE9020115E022460120002112F02AF9B5 +:106E6000DDE9022310401940084309D037F9140026 +:106E700004FB048804FB00990AF1010A26448344B8 +:106E8000641CAC42E7DB08FB0AF006FB16025AB3AF +:106E900009FB0AF006FB1B0308FB0BF009FB1604B9 +:106EA00000201FE003FB004191FBF2F1069EB1427E +:106EB00001DD314603E0F14201D50699494237F838 +:106EC0001060711A09B227F81010079EB14208DA53 +:106ED0000E44002E05DD019E314401910099491CAC +:106EE0000091401CA842DDDB9C48006890F8A1128C +:106EF000049881420BDDDDE9001090FBF1F004E025 +:106F000037F81510091A27F815106D1EF8D209B0B8 +:106F100015E62DE9FF5F924C88460026074692460B +:106F200035464FF466714046266012F079F900212B +:106F3000404612F00FFB81460021384612F002FB5A +:106F40000022884B884F29E000214FF0010EDFF826 +:106F50000CB218E030F91180D04505DD09F801E0E8 +:106F600030F911C0761C6544DBF800C030F911809F +:106F7000BCF855C3E04505DDD4F800C00CF1010CA8 +:106F8000C4F800C0491C93F800C06145E2DB0CF076 +:106F9000FF0109F1280900EB4100521C39788A42AF +:106FA000D2DB03980560304604B036E706E000BF48 +:106FB00030F912308B4201DD01207047521EF7D2AA +:106FC000002070472DE9FE4F644C8146674D2068D4 +:106FD0004FF0000690F89F32DB0607D5644BB0F8FF +:106FE000CD021B684043834200DD2E60614F134693 +:106FF0002A683868FFF7ABFD032010F020F92068FD +:10700000594D90F84003C00711D029785A480DF027 +:10701000EDFA21685A4AB1F858335849984204DCCD +:10702000584883780BB94078F0B3CE70167020685A +:10703000DFF854814B4E90F89E02800715D55348D7 +:10704000B0F900205248B0F900105248B0F90000E1 +:107050000CF01DFA03B231782878CDE900013968C7 +:10706000D8F80020084600F075FA4B48D8F8002000 +:107070003968B0F9003048460DF00BFA05F0F2FA25 +:10708000032010F0F7F8206890F89E12090627D523 +:10709000B0F9AAB2307800904A462B7811463F48A2 +:1070A000FFF712FC824600E003E00027DFF8EC80E7 +:1070B00013E00120C870BAE7327808EBC70102FB81 +:1070C00007F009EB4003D1E900018DE807005A46BB +:1070D00051461846FFF7A3FE7F1C28788742EBDB5A +:1070E000206890F89E02400708D533782A784946F0 +:1070F00003B00846BDE8F04F00F0DABABDE8FE8FF5 +:107100002DE9F04391461C466DE0254D4FF0010CF2 +:107110006A0CE0464F4648E007FB034631F916602B +:10712000964200DA3246AE4200DD3546002E39DDA9 +:107130004FF0000839E0000034061000400610004F +:107140004206100035071000480610004A061000DD +:107150004C0610003405100036061000F40610002E +:107160001C06100076061000750610003806100088 +:10717000B4061000A00610000C720120A806100032 +:107180007F06100028071000A40610002C0610002F +:107190002A0610002806100086061000602610003F +:1071A0000080FFFF01DA4FF0000C7F1EB4D2BCF16B +:1071B000000F02D0B8F1000F15D15CEA080612D01A +:1071C000BCF1000F03D1B8F1000F00D02A464E46A3 +:1071D00007E000BF06FB034531F81570BF1A20F821 +:1071E0001570761EF6D2641E8FD2BDE8F0832DE9AD +:1071F000F05F0546F9484FF00008924604788B4648 +:1072000080F80080FFF7ACFC0221F54809F0EEFCA5 +:107210002246F34C2946241F6068FFF7D3FEF14D48 +:10722000DFF8C493F14F286890F89F02800706D5D5 +:10723000616899F800303A780846FFF761FF2968DD +:10724000EB4E91F89E02020705D4C00603D491F8D4 +:107250009F02C00706D06168B6F90030E54A0846CB +:10726000FFF76FFCB6F9000061684200E248006871 +:1072700011F057FF99F8002039786068FFF703FA9A +:10728000DFF8789399F8000010B999F8010028B157 +:10729000514658466268FEF7BFFE02E0D84981F8C1 +:1072A0000080D848D84F40780228286890F89E126D +:1072B0004FEA816116D3002907DA6168B0F9BA2272 +:1072C000B6F90030084600F04EFA286890F89E1291 +:1072D000490612D5B0F9B832CC4A6168386807F06F +:1072E000D5FF11E0002908DAB0F9BA22B6F900306A +:1072F0006168386800F037FA06E0B6F900006168A6 +:107300004200386811F00DFF0221B54809F0D1FCA8 +:1073100099F80000DFF8F8A24FF0010B90B19AF84D +:10732000000001280ED1286890F89F0240071DD563 +:10733000207860B984F800B0FFF712FC0121082022 +:107340000BF08AFC286890F89F0240070ED5286849 +:1073500090F89F12090709D5217839B1B0F9C532E3 +:10736000A548AA4A0168386807F090FFA448007849 +:1073700030B199F8010018B19AF8000002281CD029 +:10738000A448B6F90020B0F900103868FFF70EFEE7 +:10739000A149A24D98B181F800B002240121A04872 +:1073A00009F024FCA0489F4BB0F900209C480168DC +:1073B0003868FFF7AEFD28600CE004202DE59B4AFD +:1073C000C5F800800124C2F80080964AC2F8008007 +:1073D00081F80080204620E52DE9F04705467F48EA +:1073E0004FF00009047880F80090FFF7B9FB022104 +:1073F0007B4809F0FBFB2246794C2946241F606834 +:10740000FFF7E0FDDFF8DC81D8F8000090F8E51325 +:10741000C9061FD58649DFF81CC28F680E68BA1BE3 +:10742000ACF86320CD684B68E91AACF86510B74238 +:1074300003DDD0F80D64B24205D89D420ADDB0F8F4 +:107440001124914206DD0221654809F032FC00203A +:10745000BDE8F08790F89F02800707D56248616811 +:107460000378624802780846FFF74AFED8F8001011 +:107470005F4D91F89E02020705D4C00603D491F82F +:107480009F02C00706D06168B5F90030594A084626 +:10749000FFF757FBB5F900005B4E420061683068AA +:1074A00011F03FFEB5F900006168420052480068E3 +:1074B00011F037FE02214A4809F0FBFB5548B5F9A7 +:1074C0000020B0F900103068FFF770FD524990B10C +:1074D0000120087001460224514809F087FB5248F8 +:1074E000504BB0F900204E4801683068FFF711FD9D +:1074F0004A49086002E081F8009001242046A7E78D +:10750000374910B5091F444A0020486010700870C0 +:10751000FFF7B5F8BDE8104000F002B8FFF767BA12 +:10752000304810B500684449444BB0F808230A803D +:10753000B0F82213424C1980B0F842332380414CFA +:107540002280414A118041490B803749B0F8BC0282 +:10755000088010BD2DE9FF4F9B46DDE90D198646D9 +:10756000A1E000BF019A01FB09F002EB4004029A7E +:10757000374F02EB40064FF0010C0EEB40057B0C41 +:10758000E2464A4615E000BF36F8120034F8128091 +:10759000A0EB080000B2984200DA0346B84200DDD2 +:1075A0000746002802DD4FF0000A02E001DA4FF042 +:1075B000000C521EE8D2BCF1000F04D0BAF1000F4B +:1075C00001D0002047E05CEA0A0044D0BCF1000F83 +:1075D00040D1BAF1000F3DD038463CE02C071000F6 +:1075E00044051000F4061000760610007506100021 +:1075F00086061000E21301209C061000A806100069 +:107600002005100028071000980610002E95010094 +:1076100022051000340610007C0610001806100029 +:10762000E005100020061000360610001C061000B1 +:10763000A01A01207C580120280610002A061000FC +:107640002C0610002E061000300610003206100026 +:107650000080FFFF184600273B464A46CBF1000A50 +:1076600010E000BF36F812C034F81280ACEB080C02 +:10767000ACEB000C0FFA8CFCDC4503DAD44501DDE1 +:1076800067445B1C521EEDD203B9012397FBF3F252 +:107690000244484605E000BF34F81030134425F892 +:1076A0001030401EF8D2491EBFF45CAFBDE8FF8F1A +:1076B0002DE9FF4F83B01E460F461C464EE000BF2B +:1076C000012047F6FF7900906FEA09080190059DB7 +:1076D00024E02E48224600EBC5000021D0E900A39B +:1076E0009B46012011F0E6FC00EA0A0001EA0B01CA +:1076F000084313D005FB064037F91000814500DD33 +:107700008146804500DA8046002803DA4FF0000009 +:10771000019003E002DD4FF0000000906D1ED8D212 +:10772000DDE9001008430AD0019810B130B119B159 +:1077300004E019B1404602E0484600E00020410064 +:107740000CD0059908E000BF01FB0642039D37F805 +:1077500012301B1A25F81230491EF5D2641EAFD222 +:1077600007B0BDE8F08F70B5002426460AE000BFE0 +:1077700031F91450954202DA20F8146001E020F843 +:107780001450641C9C42F3DB70BD000060261000A6 +:10779000A448002101704180704730B5A249012200 +:1077A0000C6894F8AA3A53B19E4DB0F840106D6839 +:1077B000491B00D549428B4201DA072030BD94F8BD +:1077C000AB1A99B1974CB0F92A500834B0F9280097 +:1077D000B4F90230B4F900405B1B201A5B4300FB94 +:1077E00000304943884201DD082030BD104630BDDD +:1077F0002DE9F0478C4FDFF82C8206004FF005048E +:107800004FF0060512D096F8260100F0BFF90446A5 +:10781000386890F8A90A28B1B6F84010814201D919 +:10782000032112E0B06A00F0D3F868B198F80000C4 +:107830004FF000094FF0010A072811D2DFE800F0ED +:107840000808274985080800042188F8005095E0B9 +:10785000052C07D0042C08D0012C09D088F8005042 +:10786000BDE8F08788F80090FAE788F800A0F7E70D +:10787000FFF78EFF022088F80000A8F80290B6F803 +:107880004000C8F80400B06AC8F80800E8E7B8F893 +:107890000200401C80B2A8F80200032C08D039680E +:1078A00091F8A41A814209D888F80050052165E0B2 +:1078B000032088F80000A8F80290D1E7052CCFD06B +:1078C0003046FFF76AFF0128CAD088F80050014609 +:1078D00054E0B8F80210491C89B2A8F80210012C33 +:1078E00021D03868464690F8A50A8842B8D804F1F5 +:1078F000F001E5200BF056FA357070780028AFD112 +:107900004A48484A192180F801A0083281705188FC +:10791000C170090A017111884171090A8171BDE8BC +:10792000F0470BF09DB93046FFF737FF042288F887 +:107930000020A8F80290012892D088F8005007286B +:1079400001D00A211AE0092118E0B8F80200401C11 +:1079500080B2A8F80200032C15D0396891F8A61A55 +:107960008142A1D9052C91D03046FFF716FF01289E +:107970008CD088F80050072809D00C21BDE8F047CA +:10798000E5200BF00FBA052088F8000068E70B210E +:10799000F4E738B500210091694600F0D2F8214C97 +:1079A000012806D9062020700221E5200BF0FAF903 +:1079B00002E00098FFF71CFF2078052801D0002086 +:1079C00038BD1A480121417005218170012038BD60 +:1079D000F0B5154906460120096891F8A72A9500D7 +:1079E00091F8A82A2B46940091F83620D7074A8EA2 +:1079F000898EA2EB0502A1EB040112B209B20ED0EE +:107A000023460F462C463114994206DBB94204DC6A +:107A100031B2A14201DB914200DD0020F0BD1746EA +:107A20000A46F0E748051000F4061000D0271000C1 +:107A30007047764890F82C00062801D0052807D119 +:107A400073487449006890F8B40200F00F000860B1 +:107A500071490020087070472DE9F041DFF8B881C6 +:107A6000044698F8000010B90A2188F80010002791 +:107A700004F580565FF00105D6F8380305FA07F1E2 +:107A800008420CD007EBC70000EB471104EBC10123 +:107A900091F82601032802D1204604F02BF87F1C20 +:107AA000FFB20F2FE8D3002604F5805705FA06F140 +:107AB000D7F8380308420AD006EBC60000EB46119F +:107AC00004EBC10000F128010C300BF0C0FD761C66 +:107AD000F6B20F2EEAD3514800210160416098F8B8 +:107AE0000800800608D52046FFF753FF20B14B4819 +:107AF0000BF0B6F8FFF74CFE0027A84604F58056B9 +:107B000008FA07F0D6F83813014211D007EBC70086 +:107B100000EB471104EBC10595F82601082807D1B1 +:107B20002946204604F001F82946204603F0C4FF08 +:107B30007F1CFFB20F2FE3D32046BDE8F04100F0D9 +:107B400038B830B5054600204FEA000303EBC30206 +:107B500002EB431205EBC20494F82621012A0DD052 +:107B6000022A0BD0032A09D0042A07D0052A05D0FF +:107B7000062A03D0072A01D0082A02D1401CC0B22D +:107B80000C605B1CDBB20F2BE0D330BD09280ED29A +:107B9000DFE800F00D0505070909090B0B000420BB +:107BA000704701207047022070470320704705206E +:107BB000704770B51A490A781749062A05D022B1CC +:107BC000052A02D00A20087070BD0A7822B1521E20 +:107BD00012F0FF020A70F7D10546002404EBC4003E +:107BE00000EB441005EBC0063146284603F064FF65 +:107BF0003146284603F099FF641CE4B20F2CEDD304 +:107C0000BDE87040202101200FF079BACC7310003C +:107C1000F40610003806100058051000D027100098 +:107C200048051000F0B5FE4900F580544FF00103FF +:107C30000D684FF00E0195F89620960719D5D4F8E7 +:107C4000382300BF03FA01F422420FD001EBC10434 +:107C500004EB411400EBC40494F82741640705D5F4 +:107C6000F04895F8971001704370F0BD491EE9D2B5 +:107C7000F0BD5207FCD5EC4AD279002AF8D0E94D84 +:107C800000222D1FEA80D4F8386300BF03FA01F404 +:107C900026420ED001EBC10404EB411400EBC404F6 +:107CA00094F827717F0704D0B4F84240944200D979 +:107CB0002246491EEAD2EA80F0BDD949096891F806 +:107CC0009610890709D5D74910B10020487003E004 +:107CD0000878002801D0401E0870704770B506462D +:107CE000CF4800252C46036893F8960041071CD521 +:107CF000CD49C979C9B1CB4893F89810001FC27813 +:107D0000012A03D193F89930C91AC9B2C3888B42AA +:107D100003D9042186F8271101242146C4708A4220 +:107D200013D009200AF098FF0FE0810706D5BD485F +:107D30004178012908D0007830B906E0C00704D0A6 +:107D400096F82701042800D1012525430FD0B74913 +:107D5000AA20087096F82601032805D0042801D02F +:107D6000062804D1082000E0022086F8260170BD14 +:107D70002DE9F04FAA49814600200B6809F580568D +:107D8000A84CB3F88CA00246241F96F9407346E035 +:107D90000125D6F83813954029423FD002EBC201A5 +:107DA00001EB4215DFF888C209EBC50191F85F507D +:107DB0009CF800C0AB46ACF1020C654507DBB3F89C +:107DC0003280B1F922C0A8EB0A05AC4531DA91F84E +:107DD0003E506D0722D491F85EC091F8618091F811 +:107DE0006010ABEB0C05A8EB01016D1C491CEDB25A +:107DF00001F0FF0B05EB85014FEA4108B8FBFBF1F1 +:107E000093F88E80C44509D393F885C0AC4505D25C +:107E10005D4503D993F886508D420AD3521C974290 +:107E2000B6DA93F88210A17011F0FF0F05D0BDE80B +:107E3000F08FA17809B1491EF5E70120F7E72DE998 +:107E4000F04F77487B4B002502681B782946B2F932 +:107E500091002E460F4684461C46DFF8DC9106E072 +:107E600039F91380E04502DD491C474409B25B1E25 +:107E7000F6D24FF0640B002909DD97FBF1F192F87F +:107E8000943009B24B4393FBFBF109B200E0614629 +:107E90004B4604E033F914708F4200DD6D1C641E04 +:107EA000F8D292F88E30002184460C469946DFF8CD +:107EB0008CA192F88F7007E03AF91380E04502DD5B +:107EC000491C444409B25B1C9F42F5DC002908DDD3 +:107ED00094FBF1F092F8941000B2414391FBFBF057 +:107EE00000B24946534607E033F91140844202DDAF +:107EF000761C36B26D1C491C8F42F5DA494892F85F +:107F00009510001FB14207DC92F89010A94203DCE3 +:107F10004B490978012902D092F8931002E0417888 +:107F200031B1491E417011F0FF0F01D000207EE7F2 +:107F300001207CE7F0B53A4A00F580534FF0010C80 +:107F40001468002293F94063B4F8835019E000BF2D +:107F5000D3F838730CFA02FE17EA0E0F10D002EBBA +:107F6000C20707EB421700EBC70749B1B4F832E08C +:107F7000B7F90270AEEB050E774501DA491EC9B2BA +:107F8000521C9642E4DA94F88100884201D2012022 +:107F9000F0BD0020F0BD2DE9F041214D07462868D5 +:107FA00090F87C00010639D526490978002935D09A +:107FB0001C4C00074FF0010604F1040403D5FFF741 +:107FC0003EFF012810D041F23830042138440FF030 +:107FD00085FEC1B2286890F87C00C0070AD049B17C +:107FE0003846FFF7A7FF28B1286890F87D00207079 +:107FF000A67009E0286890F87C00800704D5384610 +:10800000FFF7B6FE0028EFD16078002806D1A078EF +:10801000012803D1AA200AF025FE6670BDE8F08190 +:10802000F406100074051000A80610008206100067 +:108030007606100075061000C80A0120F20A012019 +:10804000FC041000340710002DE9F047494E0446A7 +:108050000025306890F87C1009063AD54649097821 +:1080600081B346498978012933D1B0F8887041F24B +:108070003830042120440FF031FE04F58051C2B2A3 +:1080800000204FF00109366891F940331FE0D2B16A +:10809000D1F8388309FA00FC18EA0C0F16D000EB6F +:1080A000C00505EB401504EBC505B6F83280B5F9FF +:1080B00002C0A8EB0708C44507DB95F83E506D07E2 +:1080C00003D4002505E0012503E00125401C83427F +:1080D000DDDA2846BDE8F08770B5264E316891F8A4 +:1080E0007C10090624D524490978002920D0234C86 +:1080F000002510B1A570257006E0207820B1401E43 +:1081000010F0FF00207000D1A570607801280FD119 +:10811000A07800280CD1BB200AF0A4FD657031685E +:108120001648083891F89320427091F882108170B7 +:1081300070BD1049096891F87C10090614D50F49E3 +:108140000839097800290FD00D4ABB21117090F829 +:108150002611032905D0042901D0062904D10821BC +:1081600000E0022180F826117047044908390870A0 +:1081700070470000F4061000340710007805100066 +:108180008206100090F85F1090F85E208A1AC18F66 +:10819000521C022A0ED990F8612090F860309A4261 +:1081A00008D148F20402114204D141F00101C18713 +:1081B0000120704721F00101C1870020704770B590 +:1081C0000446002084F82A01FA48FB4D0E46017847 +:1081D000286811B9F949097831B194F9341190F846 +:1081E0006302B1421ED028E094F8271101290BD078 +:1081F00011F072F9002894F9340127D0B0422868B0 +:1082000090F8990319D10DE0ED49097869B111F0A1 +:1082100063F9002894F934010AD0B042286890F834 +:108220004D030AD100F00F0008E090F84B03F9E786 +:10823000B042286890F84C03F4D0000984F82A0171 +:108240002046FFF79FFF012811D01EE0B04203D166 +:10825000286890F89803E5E794F83C00C006286881 +:1082600002D590F89A03E8E790F89803E5E7D54837 +:108270000078012809D9296894F82A0191F89A13FD +:1082800001F00F01084484F82A01CF48CF49007853 +:108290000978084307D0296894F82A0191F89B13BC +:1082A000084484F82A0170BDC54910B50C78C2494C +:1082B00090F82A21096891F8983303F00F035CB114 +:1082C00091F84C1301F00F01C91A511A002900DC72 +:1082D000002180F82A1110BD91F84B13F2E72DE927 +:1082E000FC47B54D0446286890F87D03C00749D087 +:1082F0002146201D0BF06FF98046214604F1200035 +:108300000BF069F9814611F0E7F80028286805D0DC +:10831000B0F89163B0F88D73764304E0B0F88F63E2 +:10832000B0F88B7376432968E06A7F4391F8D913DC +:10833000884216D3B04514DCB4F8CC00ADF8020086 +:10834000B4F8C800ADF80000B4F8D400ADF80600E9 +:10835000B4F8D000ADF8040001A968460BF03BF971 +:1083600080462A68E06A92F8D91388420CD2B9454F +:108370000ADD92F8DA034043814509DC204600F02B +:10838000F3F928B9BDE8FC878842FBD3B045F9DD95 +:10839000E08F40F00200E087F4E78D49002008708C +:1083A000884908708649087070472DE9F04F8BB0F6 +:1083B0004FF0000900F5805504468DF810908DF8B7 +:1083C0001490B5F83803824E0004000C10D02046FB +:1083D000FFF728FC2046FFF7DEFD4FF0FF3730782F +:1083E00039464FF00048B3464FF0010A68BB13E02E +:1083F000744986F80090204681F80090704981F811 +:108400000090FFF7C8FD0020FFF766FE0120FFF790 +:1084100054FC0BB0BDE8F08F04F58052002092F9B7 +:10842000406321E0D2F838C30AFA00F31CEA030FD4 +:1084300018D000EBC00303EB401304EBC30393F825 +:1084400026C1BCF1010F01D039460FE0B3F840C09E +:10845000BCF1000F06D01B6B93FBFCF3984501DACF +:1084600098460146401C40B28642DBDA0027DFF81E +:1084700048810191CEE000BFD5F838130AFA07F021 +:1084800001427DD007EBC70000EB471004EBC006AC +:1084900096F82601012802D0052808D010E03046C1 +:1084A0000199FFF78CFE022086F8260111E0304684 +:1084B00000F0CDF8062086F826013046FFF70FFFC2 +:1084C00096F82601022804D006283AD0072843D07F +:1084D00052E096F83E00C00713D03046FFF752FE38 +:1084E00078B9D8F8001096F82A0191F89A1301F09B +:1084F0000F01884203D9401A86F82A0101E086F864 +:108500002A913148007840B196F82A0128B9D8F864 +:10851000000090F89B0386F82A01F08F400402D4F3 +:1085200096F82A0120B196F82601032803D023E00B +:10853000032086F826019BF80010491C8BF80010D8 +:108540001AE096F82B01B8B996F83E0080070DD5D1 +:10855000072086F826010FE0D8F8000090F87C0389 +:10856000800603D596F8A000012805D0082086F8DB +:108570002601304600F0B0F83046FFF7AFFB00E0D0 +:1085800046E03046FFF7D5FD96F82601022806D0D2 +:1085900006281FD0032824D0042822D033E0F08FEF +:1085A000400430D496F82A0108B3401E86F82A0108 +:1085B00029E0000034051000F4061000400510000A +:1085C00081061000B1061000120610002F071000DF +:1085D0008206100096F82B0148B1401E86F82B0148 +:1085E00011E096F82701012802D0032806D00AE0FE +:1085F0009DF81400401C8DF8140004E09DF8100054 +:10860000401C8DF81000734996F8260181F89300FC +:108610007F1C7FB295F94003B842BFF62DAF05AA83 +:1086200004A9204600F05FF80020FFF746FB204633 +:10863000FFF70AFD10B10020FFF74EFD66499DF8D7 +:108640001000087065499DF814000870E1E670B5E7 +:108650000026044680F82B616148624D0178286845 +:1086600019B100BF90F8640216E05F49097800294B +:10867000F8D110F031FF60B12868012690F89D0311 +:108680005FEA101084F82B0194F82701012806D026 +:108690000EE0286890F89D0300F00F00F2E72968CB +:1086A00094F82B0191F84B1300EB111084F82B0177 +:1086B0001EB994F83E0080070DD42868E16A90F84E +:1086C0009E0300F00F02914205D994F82B1101EBA3 +:1086D000101084F82B0170BD44490878002801D09F +:1086E000401E087070472DE9F05F924680460E46A6 +:1086F0000A789AF800003E4F01213AB180B3002475 +:1087000008F5805589464FF0020B22E0002829D059 +:10871000397022E0D5F8381309FA04F0014216D076 +:1087200004EBC40000EB441108EBC10090F82611E3 +:1087300003290CD190F82711012908D180F826B11E +:10874000FFF7CAFF9AF80000401E8AF80000641C78 +:1087500064B295F94003A042DCDA3078002801D0F9 +:1087600000203870BDE8F09F30B5C18F01230905A6 +:1087700001D5012030BD1B4CB0F95820B0F956107E +:10878000246802FB01F5002D0CDA002A00DA5242BF +:1087900094F8DB53AA4205DD002900DA4942A942D8 +:1087A00000DD0023B0F95C10B0F95A0001FB00F2C3 +:1087B000002A0CDA002900DA494294F8DB239142BE +:1087C00005DD002800DA4042904200DD0023184613 +:1087D00030BD00007C580120830610008406100084 +:1087E00034051000F4061000400510008206100049 +:1087F000810610002DE9F8430746FF4889461646D2 +:108800000178FE480078FE4C01B990B1206890F8DC +:10881000BF13B0F8CA2301F00F030D09B0F8C81355 +:1088200049435243484600950AF0E3FE3560BDE8EF +:10883000F88310F051FE58B1206890F8B513B0F8E5 +:10884000B82301F00F030D09B0F8B6134943E8E768 +:1088500097F82701022818D0012822D0246894F81C +:10886000350394F834C300F00F030509E548017897 +:1088700031B194F83B2394F83AC302F00F03150981 +:1088800097F82521012A18D02EE0206890F8BB1314 +:10889000B0F8C22301F00F030D09B0F8C01349432B +:1088A000BFE7206890F8BC13B0F8C62301F00F03AF +:1088B0000D09B0F8C4134943B3E794F87C84FA6A0D +:1088C000424511D294F87D1494F8BA03B2FBF1F149 +:1088D00094F87B2400F00F0302F00F02551AB5EB59 +:1088E000101F1CDA05091AE0B7F84020624505D9C7 +:1088F000B4F83613B4F83823494392E794F8BA230E +:1089000002F00F03150909B10379457997F83C0086 +:10891000C00604D594F8DC0300F00F03E2E7B4F8D6 +:10892000C013B4F8C22349437BE72DE9F8438846D6 +:1089300090F82611044600F1940703290DD0B04D9C +:10894000042928680FD0072942D008293FD1414681 +:108950003846BDE8F84300F095BB41463846BDE8CF +:10896000F84300F052BB90F8BD0304F10C01060976 +:10897000081D0AF030FE01466A462046FFF73AFF1E +:10898000034694F82501012810D12868E16A90F87F +:108990007C2491420AD290F87D2490F8BD03B1FB6B +:1089A000F2F6B6EB101F05DD060903E095480178E5 +:1089B00001B1867954F89C1F324618460AF02EFE03 +:1089C000054602464146384600F024FB25602EE766 +:1089D00090F87D1300268A07314602D594F8A0202E +:1089E00042B184F8A010324641463846BDE8F8430B +:1089F00000F028BB90F8BE0300F00F0610F06CFDED +:108A000018B1286890F8BE030609012084F8A00078 +:108A1000E9E72DE9F041044600F1A805C08F0F46B3 +:108A200000054FF0050603D594F8180101281ED063 +:108A30007021284610F016FC05EBC60178684860E6 +:108A4000386845F83600761EF6D200BFD7E9000137 +:108A5000C5E90D010120286305F1580305F1400225 +:108A600005F134012846BDE8F0410AF063BE182143 +:108A700005F1400010F0F6FB182105F1580010F048 +:108A8000F1FB94F81A0101281FD194F82401012860 +:108A900002D003280DD018E094F8250110B9E08920 +:108AA000A4F82201B4F822016084B4F820012084E3 +:108AB0000BE094F8250110B9A089A4F82001B4F8BE +:108AC00020012084B4F82201608494F82501012853 +:108AD0003AD0B4F922117868E962401A90FBF6F0B6 +:108AE000B4F9221100EB400201446962B4F9221189 +:108AF00001EB4001E961B4F9221111446961B4F953 +:108B0000221101EB8000E86078686860B4F92011F8 +:108B10003868A962401A90FBF6F0B4F9201100EB16 +:108B2000400201442962B4F9201101EB4001A9611E +:108B3000B4F9201111442961B4F9201101EB80002E +:108B4000A8603868286081E75FF0000005EBC0028C +:108B5000B4F922115160B4F9201145F83010401CCD +:108B6000C0B20628F2D371E710B50446D1E900027D +:108B7000C4E90D02062220460AF013FD206B04F121 +:108B80005803401C206304F1400204F134012046E4 +:108B9000BDE810400AF0CEBDD1E90021C0E937217F +:108BA000D0F8D8100023491CC0F8D81000F5807206 +:108BB00000F1E801DC300AF0D0BE2DE9FC47DFF817 +:108BC00048800C460968C8F80010DFF83490216826 +:108BD0000546C8F80410D9F8000017464FF0010AFE +:108BE00090F87D03400631D5B4F90200019005F1FB +:108BF000A806B4F9000009E0340510004005100093 +:108C0000F4061000C70610007C051000009095F8CF +:108C10002601032808D004280BD0062809D00728ED +:108C20000CD008280AD00DE069462846FFF7F1FE6F +:108C300008E069463046FFF797FF03E0694628469B +:108C4000FFF7AAFF308F6080B08E20802168C8F8BF +:108C500008102168C8F80C10D9F800004E46B0F989 +:108C60003210B4F902000AF07FFC60803068B0F97D +:108C70003410B4F900000AF077FC208095F8260142 +:108C8000032806D0042808D0072817D0082815D0B4 +:108C900017E03988A5F84C1013E03068B5F84C207F +:108CA00090F8BD0300F00F00C0F110014243388876 +:108CB00000FB01200009A5F84C0001E0B5F84C00CC +:108CC0003880C84A214605F1240000F082F9504658 +:108CD000BDE8FC872DE9F34FC34983B04FF000098D +:108CE000C1F80090BF49C14D4E46C1F8009085F8CB +:108CF0000090039FDFF8F8B24FF0010A07F58057A4 +:108D0000B5E000BFD7F838130AFA06F0014277D071 +:108D100006EBC60000EB4611039800EBC10494F883 +:108D20002601032805D0042803D0072801D00828ED +:108D300066D1E0680090B4F84A00ADF8040004F190 +:108D40000C01A94A081D00F044F901AA6946204611 +:108D5000FFF733FF8046DBF8000090F87C03400605 +:108D600004D56946204601F0AAFA8046DBF80000E7 +:108D700090F87C03800603D569462046FFF7D5FDB1 +:108D8000DBF8000090F87D0340070CD5B8F1000F28 +:108D900009D094F82601032805D1608CADF80200B3 +:108DA000208CADF8000094F82701012808D19148E3 +:108DB000007828B994F82601082801D04FF000085F +:108DC0008D48007828B38D480078012807D094F8A2 +:108DD0003E00400715D500BF4FF0000819E004F130 +:108DE0002000029001F09FFB18B9029801F0AAFB45 +:108DF00008B14FF0000894F83E004007ECD408E0BA +:108E000034E094F81801012803D1206A009084F816 +:108E1000189194F82701032809D12878401CC0B282 +:108E2000287094F83E10490701D5401E287000981C +:108E30006062BDF80400A4F84C0070480078012876 +:108E400002D1E08FC00411D5B8F1010F0ED1009806 +:108E5000A061BDF80400A4F84E00049894F83421F1 +:108E600001680AFA02F0014304980160761C97F940 +:108E70004003B042BFF646AFDBF8000090F85A045A +:108E800000070ED529785E4829B15E490978012985 +:108E900001D180F800A0D7F83C13002901D180F857 +:108EA000009005B0BDE8F08F2DE9F04789460646F1 +:108EB00000274FF0010800F5805543E0D5F838232E +:108EC00008FA07F10A423CD007EBC70101EB471152 +:108ED00006EBC10494F82611032905D0042903D018 +:108EE000072901D008292CD194F83431D9F8002071 +:108EF00008FA03F0024224D0032903D12146304668 +:108F000002F0F8FD94F93501002813DB94F82701ED +:108F10000021012804D0022804D0042804D004E051 +:108F2000032102E0042100E0052184F828112046F5 +:108F300009F087FE94F82601082802D1002084F861 +:108F400037017F1C95F94003B842B7DA0024474641 +:108F500025E000BFD5F8380307FA04F108421DD018 +:108F600004EBC40000EB441006EBC00898F826019F +:108F7000082813D198F83421D9F8001007FA02F024 +:108F8000014207D098F93501002803DB41463046FD +:108F900002F0CBFD4146304602F08EFD641C95F98F +:108FA0004003A042D6DABDE8F0870F4900200860F0 +:108FB0000C49086000F028B838B50446002000903D +:108FC00069462046FFF786FE69462046FFF76CFF9C +:108FD00038BD10B514460AF0FEFA2168814200DA65 +:108FE000206010BDB8061000B4061000B1061000D5 +:108FF000F406100081061000350710003A07100033 +:10900000450610004406100070470022826002737B +:1090100000F03DB87CB5044615460E46684600F0A3 +:1090200036F801992A46606800F043F860600099BC +:109030002A46206800F03DF820602146304600F0C6 +:109040002FF87CBD7FB504464068019020680090F1 +:1090500015460E4602A800F01AF8039860600298C0 +:1090600020602A460399019800F023F801902A46CF +:109070000299009800F01DF800906946304600F013 +:109080000FF87FBD0A460146104600F009B8B1F955 +:10909000022012024260B1F900100902016070471B +:1090A0004A688032121242800968803109120180B8 +:1090B0007047C2F11003504301FB030000117047D9 +:1090C000B0F84020B1F840301A44A0F84020B0F881 +:1090D0004220B1F842301A44A0F84220026B0B6BD8 +:1090E0001A440263426B4B6B1A444263B1F950203D +:1090F000B0F950309A4201DDA0F85020B1F9522069 +:10910000B0F952309A4201DDA0F8522090F82E2199 +:1091100091F82E319A420AD030F8442FB1F84430F9 +:109120001A4420F80C29896B0268114401607047C9 +:109130002DE9F04F97B0804600F580500026119041 +:10914000BEE0002008900590109012908146824663 +:109150008346054607460A900B900C900D9008EB4D +:10916000860000F580501490D0F8B4030AAA044693 +:1091700017E000BF90F82E1108EB010C535C0CF5C2 +:10918000805C5B1CDBB253549CF8A2C3634506D1E0 +:10919000012B04D901238B4012990B431293D0F871 +:1091A00038010028E6D140E094F82E11012000FAA1 +:1091B00001FC12991CEA010F12D1606BB4F90E3058 +:1091C000059A4946C0FB031205928946B4F90C3052 +:1091D00051465A46C0FB03128A469346054419E09D +:1091E00008991CEA010F15D1A06BB4F91E30059A3D +:1091F0004946C0FB031205928946B4F91C3051461A +:109200005A46C0FB03128A46089905444CEA0100FD +:1092100093460890204600F036FD012802D11098B0 +:10922000401C1090D4F838417F1C002CBCD1002F7A +:1092300044DDE817044603462A46484605990FF0E0 +:109240004CFFADF81E002A462346504659460FF003 +:1092500044FFADF81C0014984FF0FF370025D0F8FC +:10926000B44323E0204600F00EFD012801D0109801 +:1092700090B904F1100107A80AF0ADF9B8420BD279 +:1092800007463DB129462046FFF71AFF29464046CA +:1092900000F010FD254607E021462846FFF710FFA5 +:1092A0002146404600F006FDD4F83841002CD9D1C3 +:1092B0000798E860E88F40F04000E8871198761C36 +:1092C00090F82C04B0423FF73CAF17B0BDE8F08FE8 +:1092D0002DE9F74F05460E4601EBC60000EB4610A0 +:1092E00082B005EBC00A00244FF00108DFF894B506 +:1092F00005F580577FE0D7F8381308FA04F942469D +:1093000011EA090F76D0B44274D0DBF80800904619 +:1093100030F8160010EA090F6CD104EBC40000EB22 +:10932000441005EBC000009000F0A7FC012804D019 +:10933000009800F0A8FC01285CD1009800F095FC92 +:10934000F0BB00990AF10C000C310AF044F90190CD +:10935000DBF8080008FA06F230F8163043EA090391 +:1093600020F8163030F81430134320F814305046EB +:10937000DBF8009000F093FC012804D1009800F085 +:109380007CFC01281BD0504600F077FC012804D15A +:10939000009800F084FC012811D0504600F06DFCCC +:1093A00001281CD1009800F068FC012817D1009911 +:1093B0009AF83E0091F83E10084380060FD500E071 +:1093C00018E0BAF83E00DBF8049040F02001AAF85B +:1093D0003E100098C08F40F020010098C18701988E +:1093E000484507D241F2B43051462844049B009AC4 +:1093F00000F06FFC641C97F94003A042BFF67BAFFE +:1094000005B063E72DE9F84F8846064601EBC10138 +:1094100001EB481006EBC004DFF868A494F83E00A6 +:109420004FF0040B40064FF0010906F580552DD58D +:10943000002704F10C0B23E0D5F8381309FA07F0E4 +:1094400001421CD047451AD007EBC70000EB47107C +:1094500006EBC000009000F010FC01280FD100982E +:1094600000F003FC58B90099584610310AF0B3F8DF +:10947000DAF80410884202D2042084F826017F1C06 +:1094800095F94003B842D7DABDE8F88FFE49E06AA3 +:10949000096891F893138842F6D900272FE000BF9E +:1094A000D5F8381309FA07F0014227D0474525D0EF +:1094B00007EBC70000EB471006EBC000009000F080 +:1094C000DCFB01281AD1009894F82E1190F82F0196 +:1094D000814213D1009800F0C8FB78B9009904F1DB +:1094E0000C0010310AF077F8DAF80410884205D23F +:1094F00084F826B1E08F40F04000E0877F1C95F9AA +:109500004003B842CCDA002728E000BFD5F8381372 +:1095100009FA07F0014220D047451ED007EBC700EB +:1095200000EB471006EBC000834600F0ACFB0128BF +:1095300013D1584600F099FB78B90BF1100104F1F2 +:109540000C000AF048F8DAF80410884205D2BBF89B +:109550003E0040F04001ABF83E107F1C95F94003FF +:10956000B842D3DA90E72DE9F8430646FF200025FC +:109570008DF80000012706F5805419E005EBC500C1 +:1095800000EB451006EBC008D4F8380307FA05F1E4 +:1095900008420CD0404600F068FB012807D098F83C +:1095A0002601052803D129463046FFF72BFF6D1C05 +:1095B00094F94003A842E1DA00251BE005EBC50061 +:1095C00000EB451006EBC008D4F8380307FA05F1A4 +:1095D00008420ED0404600F048FB012809D0404622 +:1095E00000F051FB012804D16A4629463046FFF7B6 +:1095F0006FFE6D1C94F94003A842DFDA0025B846DF +:1096000020E000BF05EBC50000EB451006EBC007EE +:10961000D4F8381308FA05F0014212D0384600F0A9 +:1096200024FB01280DD0384600F027FB012804D187 +:109630006A4629463046FFF74BFEF88F20F020009F +:10964000F8876D1C94F94003A842DBDA9DF800000E +:10965000401C84F82C04BDE8F88310B50446894802 +:109660000321083007F078FA86481E2180680FF041 +:10967000D7FD41F2B4307C2120440FF0F3FD824845 +:1096800002688248B2F894138079494310B1B2F865 +:109690006A134943B2F8962302FB0210794A11601B +:1096A000111D08602046FFF75EFF2046FFF740FDD2 +:1096B00074480321BDE81040083007F065BAF0B4E3 +:1096C000446BC2684B6BCE68171467434FEA264C55 +:1096D00003FB0C77E51897FBF5F767F31F4217B20A +:1096E000674334B203FB047393FBF5F363F30F0298 +:1096F000C260F0BCE4E4644A126892F84024920626 +:1097000011D590F8313123B191F831210AB193424A +:1097100007D190F8320130B191F8321119B1884275 +:1097200001D000207047012070472DE9FE4F00F561 +:1097300080540546D4F84413D4F838030140002877 +:10974000C4F844134FF000000CD081460F2150485C +:109750000FF088FD0026DFF838A14FF0010841F234 +:10976000483B59E0C4F84403BDE8FE8FD4F83823E1 +:1097700008FA06F140460A424DD006EBC60202EB5B +:10978000461205EBC20797F83C201206D4F8442392 +:1097900011D50A4305EB8601C4F8442301F598511D +:1097A000D7F85E208A6497F82E11884040EA0909AC +:1097B0000AF801602FE00A422DD097F82621062AE8 +:1097C00015D0052A13D097F82E1108FA01F040EAB7 +:1097D00009090AF8016000BF05EB860101EB0B00E7 +:1097E0005E373946009004F071FF88B113E0F88FBE +:1097F00020F00800F887D4F844038843C4F84403F1 +:10980000244905EB860000F5985009688164E3E778 +:10981000009839680160761C94F94003B042A5DADB +:10982000002772E0D4F8382308FA07F140460A42CC +:109830006AD0D4F844230A4266D107EBC70101EB92 +:10984000471105EBC101009191F82611022901D0C1 +:10985000012959D1009991F82E1100FA01F212EA6A +:10986000090F23D01AF80100B8424DD000EBC00117 +:1098700001EB401005EBC00630460099FFF73BFFB7 +:10988000012809E08C051000F4061000A80610005D +:10989000B82810005695010036D130460099FFF7E0 +:1098A0000EFF2846009902F007F92DE000995E317D +:1098B0000026029124E000BFD4F8441308FA06F011 +:1098C00001421CD006EBC60000EB461005EBC000C1 +:1098D00005EB860101905944029804F0F7FE012837 +:1098E0000DD1DDE90010FFF706FF012807D1DDE902 +:1098F0000010FFF7E4FE2846009902F0DDF8761C20 +:1099000094F94003B042D7DA7F1C94F94003B8427F +:1099100088DA29E72DE9F047044691425CD007D95F +:1099200001EB0200A0EB0201CAB2A0EB0200C1B23F +:10993000C1EBC10000EB400004EB8001C2EBC200B0 +:1099400000EB400004EB8000B1F93250B0F9323046 +:1099500081469D4200DA4B86CB8CC58C2B44CB8450 +:109960000B8D058D2B440B858B6985692B448B6191 +:10997000C769CE69CB68D9F80C004FEA234C4FEA8F +:1099800020480CFB06FCF51907FB08CC9CFBF5FCFA +:109990006CF31F430FFA83FC0CFB06FC00B207FBC1 +:1099A00000C090FBF5F060F30F03CD61CB6094F83D +:1099B000EC04411E91420AD0C0EBC00000EB400015 +:1099C00004EB80014846542254390FF0EFFB94F821 +:1099D000EC04401E84F8EC04BDE8F0872DE9FE4F4E +:1099E000144689468346012B2ED10120CF4B0FE030 +:1099F00019F8101011B1491E09F8101009EB4002B6 +:109A00001D7851786D1EA94201DA491C5170401C25 +:109A100099F82C108142EBD20120C54B10E000BF19 +:109A200014F8101011B1491E04F8101004EB400294 +:109A30001D7851786D1EA94201DA491C5170401CF5 +:109A400094F82C108142EBD2BA480068B0F82C0A86 +:109A5000404302900020019001209AE0012591E00E +:109A6000002000909BF8EC1452E000BFC1EBC10055 +:109A700000EB40020BEB820000F1440214F815C029 +:109A80001778961C012367450FD304EB450898F817 +:109A90000180474509D8527819F81A70BA4204D3A0 +:109AA00009EB4A077F78BA4200D90023A14A12681D +:109AB00092F81F2A92071AD59F4FB0F94820B7F99C +:109AC0000070BA4213DB9BB93278624520D304EBB5 +:109AD00045035B789A421BD8727819F81A309A427B +:109AE00016D309EB4A035B789A4211D800E07BB1A8 +:109AF000924A12783AB1924A127822B190F8240030 +:109B000010F0060F04D10120009A88401043009005 +:109B1000491EABD2042168460EF0E0F8012830DD82 +:109B200000260120009A01E0761CF6B200FA06F148 +:109B30001142F9D0C6EBC60000EB40000BEB8000F1 +:109B40009BF8EC7400F10C0818E001200099B84073 +:109B5000084213D0C7EBC70101EB41020BEB8201B6 +:109B600040460C3109F037FD0299884206D2FAB21C +:109B700031465846FFF7CEFE012001907F1EB742C6 +:109B8000E3D86D1C94F82C00A842BFF469AF0AF129 +:109B9000010099F82C1082465145BFF45FAF01983F +:109BA000E2E5684810B5407800230C46002853D001 +:109BB0006548007800284FD16448007800284BD1D0 +:109BC0005C4894F8EC24006890F8271A8A4243D83D +:109BD0000BE000BFC2EBC20101EB410104EB8101CC +:109BE000B1F93210994200DD0B46521EF2D2B0F8A4 +:109BF000281A994230DBB0F92A1A00225448FCF79F +:109C000089F85349D1E90002104325D0D1E9020176 +:109C1000084321D04E4A0123A2F15801A1F1580076 +:109C2000FBF75DFD4A48B03890F82C10002913D09E +:109C3000583090F82C0000280ED0414394F8EC04E2 +:109C40000023814200D20123414A2046583ABDE810 +:109C50001040A2F15801C1E610BD3E4900208860C5 +:109C60003B480F2110300FF0FDBA90F83E0040073E +:109C700001D5012070470020704790F82601012887 +:109C800000D00020704790F82601022805D0032854 +:109C900003D0042801D0002070470120704710B580 +:109CA00090F83E10490603D5FFF7EDFF012800D0DC +:109CB000002010BD91F82621012A08D0022A06D0E2 +:109CC000062081F82601002081F82B01704701F061 +:109CD000F3BEF0B591F9336193F9004092F9335135 +:109CE000771C02D06D1C15D00BE06E1C0BD000EB66 +:109CF000850200EB8400D26BC2F83811C16381F891 +:109D000033411C70F0BD641C64B240F8241081F82B +:109D1000334102E000EB8601C96B00EB8400C1F81F +:109D20003821C26382F83341EBE70000750610006A +:109D300076061000F40610002E06100044061000EF +:109D400046061000A806100034051000400510005B +:109D5000A82810008C0510002DE9F041044690F869 +:109D60009000FF4E00270D467F2851D104F10C01D1 +:109D7000081D09F030FC0146204600F028FB40B2E7 +:109D800084F890000F2802DD0F2084F89000E08F07 +:109D900080053DD56888B4F978C0B4F97630A0EB79 +:109DA0000C0001B22888D4F87620C4F86A20D6F8CE +:109DB00000E0C01A64229EF83DE900290EFB01FE76 +:109DC0009EFBF2F100B201DD614401E0ACEB010168 +:109DD000A4F870103168002891F83D1901FB00F1DA +:109DE00091FBF2F001DD184400E0181AA4F86E00AF +:109DF0006888B4F87010401AA4F874002888B4F881 +:109E00006E10401AA4F87200306890F83D09E8B36B +:109E100094F99000B5F90220C0F110015143B4F952 +:109E2000782000FB021040F30F106880E18F890555 +:109E300010D5B4F96C10884203DDB4F9702090425B +:109E400005DC884206DAB4F97010884202DAB4F808 +:109E50007000688094F99000B5F90020C0F11001FD +:109E60005143B4F9762000FB021040F30F10288014 +:109E7000E18F890523D5B4F96A10884203DDB4F96E +:109E80006E20904207DC88420BDA00E02BE0B4F948 +:109E90006E10884205DAB4F86E002880E08F8005E5 +:109EA0000DD5B5F90000B4F96E10884207D1B5F9A7 +:109EB0000200B4F97010884201D184F890703168C2 +:109EC00094F8900091F83F1901F00F01401A40B248 +:109ED00084F89000002801DA84F890702868C4F8AB +:109EE0007600BDE8F08184F89070012084F88E003F +:109EF000F7E72DE9F04188460546012790F89010D4 +:109F0000384671B195F88E1001290AD003224146D6 +:109F100005F17A0009F030FB95F88F00012803D095 +:109F20004FE085F88E00DCE70FF0D6FA8C4E002863 +:109F3000306806D090F8421990F8430961F31F4445 +:109F40000DE090F8401990F8410961F31F4460F367 +:109F50000F048448017821B1C07860F31F4460F396 +:109F60000F0423145B4322B202FB023405F1760096 +:109F7000414609F030FB0023A0421CDC3168EA8F27 +:109F800091F83B0900EB80004000120504D591F8E0 +:109F90003A0900EB8000400010B1EA6A82420AD818 +:109FA00091F87C03000600D40027D5F87600C8F8A5 +:109FB0000000384695E785F88F3095F99000002825 +:109FC000F7DD41462846FFF7C7FEF2E72DE9F84FD7 +:109FD000044601200D464FF0000B00900FF07CFA74 +:109FE000DFF87CA10028DAF8000011D090F84C6965 +:109FF00090F84D790322294604F17A0009F0BCFA61 +:10A00000E08F00051DD594F81A01012805D018E04D +:10A0100090F84A6990F84B79ECE7DAF80000E16AC9 +:10A0200090F8520981420CD26888B4F87810401A2E +:10A03000B4F88A100844A4F88A002888B4F8761086 +:10A040000BE06888B4F88010401AB4F88A1008440D +:10A05000A4F88A002888B4F87E10401AB4F88C104E +:10A060000844A4F88C00B4F98A00002801DB0146FA +:10A0700000E04142B1425EDD4FF0010B002801DDFE +:10A08000811B00E081190FFA81F9A0EB0900A4F807 +:10A090008A0034F8781F01EB090000B22080DAF85A +:10A0A0000010B1F9321009F05FFA24F87809B5F917 +:10A0B00002108646081A02B2002A01DB104600E0B0 +:10A0C0005042B04254DDB4F98000081A00D5404235 +:10A0D000DAF800800FFA80FC98F8503998F8516946 +:10A0E00098F84E0998F84F199C450FDB9E420DD009 +:10A0F000B44501DD084609E0ACEB030C091A0CFB82 +:10A1000001FCF11A9CFBF1F1084400B2B4F98A1089 +:10A110005143002906DDB9F1000F00DC40427044D4 +:10A12000A4F87800B8F93210B4F9780009F01CFAF4 +:10A13000A4F878001CE0DAF80010B4F97C00498E2D +:10A14000884203D1B4F980208A4203D080B9B4F8A0 +:10A15000801069B9B4F97810814209D004E0000098 +:10A16000F4061000C7061000A4F878004FF0010BA9 +:10A17000B4F98C00002801DB014600E04142B942FD +:10A1800056DD002801DDC11B00E0C1190EB2801BA5 +:10A19000A4F88C0034F8760F304400B22080DAF84E +:10A1A0000010B1F9341009F0DFF924F87609B5F997 +:10A1B00000108146081A02B2002A01DB104600E0B6 +:10A1C0005042B84253DDB4F97E00081A00D540422F +:10A1D000DAF800800FFA80FC98F8503998F8517935 +:10A1E00098F84E0998F84F199C450FDB9F420DD007 +:10A1F000BC4501DD084609E0ACEB030C091A0CFB79 +:10A2000001FCF91A9CFBF1F1084400B2B4F98C107E +:10A210005143002905DD002E00DC40424844A4F8EB +:10A220007600B8F93410B4F9760009F09DF912E01F +:10A23000DAF80020B4F97A00918E884203D1B4F99B +:10A240007E308B4203D048B9B4F87E1031B9B4F9EE +:10A250007610814202D0A4F8760008E0BBF1000F2E +:10A2600005D192F87C03000601D400200090D4F8B8 +:10A27000760028600098BDE8F88F10B5044690F885 +:10A28000260104281AD1E08F400517D404F10C01EF +:10A29000081D09F0A0F901466448006890F83C29BF +:10A2A000E08F5243430509D4914202DA40F4007032 +:10A2B00003E020F4007040F48060E08710BD2DE9D9 +:10A2C000F0410E4604460125FFF7D7FF94F826011A +:10A2D000032804D0042807D0082825D027E03146D9 +:10A2E000204600F029F822E0504F386890F87D03AE +:10A2F000C00609D531462046FFF7FBFD054694F818 +:10A300008E00012803D00CE0012084F88E0038680C +:10A3100090F87D03000704D531462046FFF756FE2E +:10A320000546012D03D005E0D4F886003060306882 +:10A33000C4F886002846D4E570B504460868C4F819 +:10A3400076000D46032204F17A0009F021F937481E +:10A35000026892F87D03C1064FF000002FD5344902 +:10A360000E7801217F2326B3E68F360521D594F898 +:10A370002561012E16D084F88E0084F88F1084F8A1 +:10A380009030D4F82011C4F876106988B4F8783089 +:10A39000C91AA4F874102988B4F87630C91AA4F838 +:10A3A00072100CE084F88E1084F88F0084F890000E +:10A3B00005E084F88E0084F88F1084F8903092F8CD +:10A3C0007D13090702D524F88A0F608070BD10B58F +:10A3D0000C460FF081F815490A6880B192F84909D6 +:10A3E00092F8463900F00F01000992F847295B43C3 +:10A3F00052439C4202DD94420CDB084610BD92F8A9 +:10A40000480992F8443900F00F0100095B4392F8C3 +:10A410004529EDE79A4200D1521CE41A411A4C43F7 +:10A42000D11A94FBF1F1401A10BD0000F40610009F +:10A43000350710002DE9F041FF4F0D463A4606461C +:10A44000797892F803C013790020FC4C52795FEAC6 +:10A45000017E06D01946604609F020F80146B87919 +:10A4600016E08F0702D01946604611E0F24F11F056 +:10A470000B0FBF7901D0394603E011F0050F02D070 +:10A480006146104604E011F00A0F10D03946184614 +:10A4900009F00FF858B1216891F88624824206D35A +:10A4A00091F880043070206890F881040EE02168F3 +:10A4B00091F8862482420CD291F88724824208D3F4 +:10A4C00091F882043070206890F883042870BDE809 +:10A4D000F08191F887248242F9D291F8882482424F +:10A4E000F5D391F884043070206890F88504EDE786 +:10A4F00030B50124039D9C4035B1091491420EDA18 +:10A5000081682143816030BD09B2914203DA01685C +:10A510002143016030BD41682143416030BDC168C5 +:10A520002143C16030BDC649B0F90000B1F9202017 +:10A53000824203DCB1F92210814201DA0120704726 +:10A5400000207047BE49B0F90200B1F91A108842E4 +:10A5500001DD01207047002070472DE9F843914646 +:10A560000646DDE9087288790025DDF828C00C462A +:10A5700003282FD2B148DFF8CC82006890F863142A +:10A58000A180D8F81080B8F1000F04DD90F8648441 +:10A59000A1EB0801A180B0F86504316B814217DDA1 +:10A5A000DBB249463846CDF800C0FFF7A1FFA079DD +:10A5B000401CC0B2A071032806D0A349B6F95200CE +:10A5C000B1F90010884205DD0320A071012501E0EA +:10A5D0000020A0712846BDE8F8832DE9F04104462B +:10A5E0009A480078002853D09448006890F85A049C +:10A5F000C0064DD594F93501002849DAE08F800472 +:10A6000046D4A08F0025400500D5012504F10C009B +:10A61000FFF789FF0346E08F4FF0010641044FF03A +:10A6200002074FF0030C1CD52B430BD084F8267186 +:10A6300040F00400E08794F82A0103281FD284F830 +:10A640002AC11CE04BF6FB71084040F42050E08723 +:10A65000002204F59071204601F099F884F81A61FF +:10A660000DE004F12000FFF75EFF012801D1012B6E +:10A670000FD0E08F20F4804040F40050E087E08F5E +:10A68000400405D5724810F85B1F41F004010170C9 +:10A690001DE7002DF3D0E08F44F204010843E0876A +:10A6A00084F8267194F82A01032801D284F82AC17B +:10A6B0000E2104F58C700EF0D5FDE068C4F8200181 +:10A6C00084F82461DBE703B25C480268614892F8D1 +:10A6D0009D148B4203DB928E511A994204DA8189D0 +:10A6E000491C818101207047C189491CC18100201A +:10A6F0007047F0B551490D686A8E95F87834A98E87 +:10A7000095F8365014466E0703D5A2EB204666F343 +:10A710001F40AE0702D50E1A66F30F00ED0706D0F4 +:10A72000021460F31F4062F30F000A46214606142C +:10A73000B6EB520F04B208DAB4EB510F02DA00257F +:10A7400001240AE00125022407E0B4EB510F02DAEC +:10A750000225042401E003250824374F4FF0010EA1 +:10A760000EFA05FE97F801C01CEA0E0F01D07B1906 +:10A77000DB789E4202DBD21A964205DD02B29A4293 +:10A7800003DBC91A8A4200DC0024324960310A889E +:10A79000521C0A804B808E80C8800C812046F0BD00 +:10A7A000264930B40968B0F90E30B1F895249342C7 +:10A7B0001DDBB1F89724934219DCB0F90C20B1F8F5 +:10A7C0009944A24213DBB1F89B44A2420FDC91F8FA +:10A7D0009E14C26A8A420AD81E4940310B80808981 +:10A7E00048801C488A80028230BC00F0EABF30BC3E +:10A7F00070472DE9FC47114D044688462868DFF86C +:10A800005490002790F880148DF8001090F881146F +:10A810008DF8041094F83D2109F1200942B994F80B +:10A820003E1100295CD090F831305B1E99427CD0FB +:10A8300090F83010491E0FE0C0061000F40610001A +:10A84000C8281000980510002806100035071000D1 +:10A850007C5801201E1A01208A4202D194F83E3110 +:10A86000F3B38A4206D190F8311094F83E21491E84 +:10A870008A425AD0FA49097899B301A96846FFF784 +:10A88000D9FD286890F87E14B4F9500000FB01F25D +:10A89000642192FBF1F216B2B8F1640F04D206FB08 +:10A8A00008F696FBF1F10EB2A9F80000A9F80260D3 +:10A8B00094F83D119DF80420EA48C84691421FD201 +:10A8C00094F83EC19DF800309C4519D200210068E3 +:10A8D0000EF046FEB0F90000B04200DD012701E0B5 +:10A8E00023E002E0A8F804004BE090F83B148DF858 +:10A8F000001090F83C148DF8041090F83D14C3E754 +:10A90000914214D22B689DF8008094F83EC193F8D0 +:10A910003130A3EB0808C44509DB5B1ED9B20068DF +:10A920000EF01EFEB0F9000010E0012729E02B68B0 +:10A9300093F830C0ACEB020291420ADB94F83EC1BE +:10A940009DF80080C44504D200210FE0B042ECDC49 +:10A9500017E0914215DB93F831109DF8003094F820 +:10A960003E21CB1A9A420CDB491EC9B200680EF098 +:10A97000F7FD296891F8301000EB410030F9020C26 +:10A98000E4E7A9F80670B9F808103846491CA9F898 +:10A990000810BDE8FC8770B504460025C068FFF7C5 +:10A9A00092FE88B9B0480068B0F89114B0F88F04EE +:10A9B000091AB4F81C01814205DB28B1D4F8200142 +:10A9C00000F003FF00B90125284670BD10B500F066 +:10A9D000F1FE002809D0A5494A8882434A808A8826 +:10A9E00082438A80CA888243CA8010BD2DE9F04F15 +:10A9F00085B08246DFF8748200200D46019098F8F9 +:10AA0000001021B1491E88F8001000F0DAFE00267F +:10AA10004FF0020B4FF001090AF580572DE200BFFD +:10AA200009FA06F0D7F838130290014269D006EB14 +:10AA3000C60000EB46110AEBC10404F58C700490CB +:10AA40002046FFF7CAFDE18F48045AD4E068009021 +:10AA5000039094F82601012806D0022804D0490763 +:10AA60007DD504287CD0E5E1814AB4F95010B2F9D3 +:10AA70000020914245DB012803D10E2104980EF0FD +:10AA8000CFFBE06800F096FED0B377486421006801 +:10AA900090F87F0484F840012046FFF7AAFE0128C1 +:10AAA00066D0049906200873E08F334640F0040016 +:10AAB000E0870498E16881600499204681F80D9050 +:10AAC00069490968B1F98B140095CDE90119DDE9EF +:10AAD0000321FFF742FD019063480068B0F891142C +:10AAE00004988180E06800F065FE20B1B8F8042089 +:10AAF0000243A8F8042094F8241107293FD043E02A +:10AB000000E0B9E1009801B25A48B0F90020914242 +:10AB10000DDBB0F90220914209DC009AB0F90A304D +:10AB200012149A4203DCB0F908309A4244DAE28FF8 +:10AB300042F00402E287049AE3689360B0F90020CF +:10AB4000914203DBB0F90230994224DD00200095E8 +:10AB5000CDE90120DDE903213346204601E041E152 +:10AB60008CE0FFF7FAFC0499019081F80CB083E1C6 +:10AB7000052084F8410104980721017394E7B8F88F +:10AB800006200243A8F8062094F82611A8F8081019 +:10AB9000A8F80A6070E1B0F90800CDF80890CDE996 +:10ABA0000050DDE9032133462046FFF7D6FC019033 +:10ABB0000498042101735FE1B0F9103099420BDB76 +:10ABC000B0F91230994207DCB0F91A309A4203DC2E +:10ABD000B0F918309A4234DAE28F42F00402E28788 +:10ABE000049A127B12B9049AE3689360049B83F879 +:10ABF0000C90B0F91020914203DBB0F91230994269 +:10AC00000EDD00200095CDE90120DDE9032133466A +:10AC10002046FFF7A2FC0499019081F80C902BE1EB +:10AC2000B0F91800CDF80890CDE90050DDE9032116 +:10AC300033462046FFF791FC0499019003200873E6 +:10AC40001AE10498002101732869029908432861D8 +:10AC50002046FFF7A5FD08480189491C01810BE149 +:10AC6000C00610009C061000F406100098051000A5 +:10AC700040061000C82810001E1A01200498007B0E +:10AC8000072826D1FE4800780028FE4800680ED02C +:10AC900090F893142046FFF7ACFD01280AD094F8F1 +:10ACA000410148B1B0F1010084F8410111E090F890 +:10ACB0003E14EFE70520F7E704990620087304988F +:10ACC000806800F077FD20B1B8F806208243A8F82C +:10ACD00006200498017B06290FD007290DD0009883 +:10ACE00002B2E948B0F910309A4203DBB0F91230F1 +:10ACF0009A4264DD03295ED09CE0E06800F05AFDD2 +:10AD000030B1E048006890F87F1484F8401105E005 +:10AD100094F8400170B1401E84F84001D948CDF844 +:10AD20000090F3B200680399B0F979242846FFF740 +:10AD3000DFFB7FE00098D44902B2B1F910008242F3 +:10AD400003DBB1F912309A420EDD00210095CDE906 +:10AD50000101DDE9032133462046FFF7FEFB04999C +:10AD6000019081F80C9021E00098B1F91A200014AC +:10AD7000904203DCB1F91820904210DAB1F91810B2 +:10AD8000CDF80890CDE90051DDE903213346204696 +:10AD9000FFF7E3FB049901900320087306E029699B +:10ADA000029A11432961B94981F80090049880689A +:10ADB000FFF70CFE3EE0049981F80C900EE0009A3B +:10ADC000B0F91A3012149A4203DCB0F9180082422A +:10ADD00030DA01292ED10499032008730498E16820 +:10ADE000816027E0009801B2A748B0F91020914295 +:10ADF00020DDB0F9122091421CDA0099B0F91A2036 +:10AE00000914914216DAB0F91800814212DD29695D +:10AE1000029A2046114329619C4981F80090FFF76E +:10AE2000BFFC9B484189491C41810020A8F80C00C7 +:10AE3000A8F80E0094F8260105281DD19148B4F910 +:10AE40000E100068B0F89524914215DBB0F89724F5 +:10AE5000914211DCB4F90C10B0F8992491420BDB4B +:10AE6000B0F89B24914207DC90F89F14884888F83A +:10AE70000010818A491C8182761C97F94003B042F8 +:10AE8000BFF6CEAD28686968AA68EC6840EA01039D +:10AE900042EA040633432B6901D023B105E023B114 +:10AEA00088F801B001E088F80190774B58331E68AC +:10AEB000B043286058688143696098687549824347 +:10AEC000AA60D8688443EC6028690978084305D1F2 +:10AED0002C22A3F12C016C480EF068F9019805B002 +:10AEE000BDE8F08F30B590F82611002204292DD14D +:10AEF00064490B6893F85A14490727D5B0F84610EF +:10AF0000B0F84840091B604C248DA1421EDD4FF46F +:10AF10009271095C012901D002290AD190F85F40A1 +:10AF200090F85E50641B93F86254AC4201DD01223C +:10AF30000CE0032901D0042908D190F8611090F8A1 +:10AF40006000081A93F862148842F0DC104630BDA5 +:10AF500030B54C4A0021136893F85A2452072BD578 +:10AF600090F82621042A27D1B0F84620B0F84840AE +:10AF7000121B454C248DA2421EDD4FF49272125CCE +:10AF8000012A01D0022A0AD190F85F4090F85E5061 +:10AF9000641B93F86254AC4201DD01210CE0032AEA +:10AFA00001D0042A08D190F8612090F86000101AAE +:10AFB00093F862249042F0DC084630BD2DE9F34F4F +:10AFC00097B03548002415944078DFF8BCB00128CC +:10AFD0000BD11898006940B1DBF80CA0DBF80490A5 +:10AFE000DBF81480DBF81C6007E0DBF808A0DBF876 +:10AFF0000090DBF81080DBF81860179F002507F53C +:10B00000805762E20120A840D7F83813059001422A +:10B010000FD005EBC50000EB4511179800EBC10000 +:10B020000290C08F410404D4400703D41749012083 +:10B03000087049E2029800F58C7003900298C0688D +:10B040000C900790029890F82601012806D002285B +:10B0500004D004283ED005287ED035E2189814226A +:10B06000C1680091006901900CA818990EF059F878 +:10B070000DF1300C02989CE80E00FFF733FF0DE055 +:10B08000C0061000F4061000C82810004606100084 +:10B090001E1A0120B106100098051000012802D1E7 +:10B0A00003980121417018981422C1680091006929 +:10B0B00001900CA818990EF034F80DF1300C02989C +:10B0C0009CE80E00FFF744FF0128B2D1039900204D +:10B0D0008880F9E10398007B012801D0032803D17F +:10B0E000DBF81480DBF81C6018981422C16800910A +:10B0F000006901900DA818990EF013F80DF1340CA9 +:10B1000002989CE80E00FFF723FF012804D0039863 +:10B110008088012804D038E003990020888034E03A +:10B120000298BBF91010B0F90C0088421EDBBBF985 +:10B13000121088421ADC0398007B062816D1029868 +:10B14000FFF729FC50B11898059A016901201143B5 +:10B15000189A1161F84900E054E10870039880687A +:10B16000FFF734FC0398808801280ED10298BBF9C0 +:10B170001020B0F90C00904203DBBBF9121088429A +:10B1800003DDEE48C18A491CC18203988188EB48DF +:10B19000C1800398808828B1401E03990004000CE8 +:10B1A000888005D1029890F830110120884004432E +:10B1B00018981422C1680091006901900DA818998F +:10B1C0000DF0AFFF0DF1340C02989CE80E00FFF774 +:10B1D00089FE012801D103994870039880790328DA +:10B1E0001ED203998988D9B102990A6BD44909689A +:10B1F000B1F865148A4210DD401C0399C0B20328DF +:10B20000887107D00298CF49B0F95200B1F9001007 +:10B21000884205DD0120159002E003990020887125 +:10B220000398037B062B28D0072B26D00C980FFA07 +:10B2300089F200B290420DDB4FEA2941884209DCD5 +:10B240000C994FEA2A4C0914614503DC0FFA8AFC79 +:10B25000614540DADDE902319042DB688B6003DB57 +:10B260004FEA294188422DDD03980221EBB2017398 +:10B27000002000900799189890E01898059A0169A5 +:10B280000120114217D00299002291F83011884014 +:10B290008443DDE90201083100F079FA02984FF6A3 +:10B2A000FB31C08F084040F400610298C1870399C8 +:10B2B0000120887008E10090A148EBB20068B0F965 +:10B2C0007924D7E703980421EBB2017301200FFA28 +:10B2D0008AF20090CEE70FFA88F20692904209DBDC +:10B2E0004FEA2842904205DC3014814202DC30B241 +:10B2F000814256DA022B02D0042B04D00AE00399D3 +:10B300000120087302E0039803210173DDE90210B4 +:10B31000C96881600398407850BB0398083000905A +:10B320000298DBF824100591019090F824110C305C +:10B330000129009925D008F04EF9059988420DDDC4 +:10B34000DDE90010002200F022FA01984FF6FB31EF +:10B35000C08F084040F400610198C1870298C08FF7 +:10B36000000505D5029890F83011012088408443EB +:10B370000398007B01280BD00120EBB232B2009081 +:10B3800078E7B1F90210B0F90200081A4043D4E797 +:10B390000020DDE906210090EBB21898FFF7A8F82D +:10B3A00092E01898059900220069084318990861ED +:10B3B000DDE90201083100F0EAF902984FF6FB31AD +:10B3C000C08F084040F400610298C18703990120B2 +:10B3D00088700298B0F840105948006890F87124BD +:10B3E000914208D9029990F8720491F82A11084400 +:10B3F000029981F82A01029890F8301101208840C2 +:10B40000844361E00398007B012804D003280DD019 +:10B41000062818D01BE003988088E8B30298B0F99A +:10B42000521047480068B0F8670409E00398808824 +:10B4300090B30298B0F9521041480068B0F8730414 +:10B4400081421EDC40E00298FFF7A5FAC8B90398D4 +:10B45000007B07282ED102980090C068FFF733F9CF +:10B4600040BB3748006890F89404C00722D0009889 +:10B47000B0F81C01F0B10098D0F8200100F0A5F957 +:10B48000C0B9DDE902010122083100F080F902981B +:10B49000C08F20F0040000E016E040F40041029864 +:10B4A000C1870298B0F85210A0F850102348818844 +:10B4B000491C81800398007B062801D0072803D10E +:10B4C00003988068FFF782FA6D1C97F94003A84241 +:10B4D000BFF698AD1C480CB1012100E000210170BD +:10B4E0001A48164982880A8042884A80C2888A801F +:10B4F00000784882159819B0F2E430B510490A680E +:10B500001349938E08801B1A4B8092F86A440519E0 +:10B510008D801B1BCB80528E0881101A48818D8133 +:10B52000001BC88130BD064909688A8E0849088415 +:10B53000101A488470470000460610001E1A0120A9 +:10B54000F4061000280610004406100098051000AC +:10B55000F4281000B649B74A0B68598E48B11083D9 +:10B56000091A518393F86D3418449083C81AD08314 +:10B57000E0E70020108351839083D183DAE7AC4A5F +:10B5800010B41368AB499A8E60B10882121A4A82CD +:10B5900093F86D4420448882101BC88293F870048D +:10B5A00010BCC0E7002008824A828882CA820884D0 +:10B5B0004A8410BC704770B59D4C206890F86904AF +:10B5C000FFF79BFF206890F86E04FFF7D8FF206814 +:10B5D00090F87704FFF7BEFF2268964992F86B0453 +:10B5E0004043486292F86C0408852C22A1F12C009B +:10B5F0000DF0DCFD90480024914D04708F4814211B +:10B6000004708C482C612C300DF02CFE8D482021CC +:10B6100004706C708C480DF003FE8B4820212030A4 +:10B620000DF0FEFD8848202140300DF0F9FDBDE809 +:10B6300070408548202160300DF0F2BD7E480078D2 +:10B6400050B17B48006890F85A04800704D57B48C5 +:10B65000007808B101206DE700206BE770B586B077 +:10B660000646142168460DF0FDFD74480024694625 +:10B6700004703046FFF7BAF9054669463046FFF7D1 +:10B680009DFC28436E49012801D0086905E06848FF +:10B69000006890F86304401F0861002804DD401E24 +:10B6A00008616548007800B90C6162481422694657 +:10B6B0002C300DF07BFD06B070BD2DE9F04700F198 +:10B6C00038060546B078614F0B460024B8B1604A91 +:10B6D000F1781078401E814257D1C1B29046184689 +:10B6E0000DF038FF814698F80000401EC1B238685E +:10B6F0000DF036FF034630787278014610E00021E5 +:10B7000018460DF027FF81460021F0E719F8006088 +:10B7100095F84B70BE4201D1641CE4B2401CC0B22B +:10B720008242F3D2424E61B13068B0F85B04491EE8 +:10B73000C9B233F91170874203DD641CE4B20029F9 +:10B74000F5D144480078401E82420DDA31688242C9 +:10B750000ADA521CD2B2B1F85BC433F912706745F1 +:10B7600002DD641CE4B2F2E73B4880F85C403168DB +:10B7700091F86F14A14208D2A98C41F48061A98488 +:10B7800010F85B1F41F008010170BDE8F08702234B +:10B7900080F82631002380F82A310123C362012A70 +:10B7A00004D00968016280F81831C3E603220C3026 +:10B7B00007F0EEBE2949097809B1FEF79ABF00F0FB +:10B7C00010B81F4881884180B4E610B50024FFF707 +:10B7D000F1FF20B11A494988014200D001242046D6 +:10B7E00010BD70B51249024614140968002012B247 +:10B7F000B1F88B349C420ADAB1F88D54AA4201DACE +:10B80000082004E08E8E751B954200DA02204D8ED2 +:10B81000EB1AA34204DAB1F88D349A4201DA04201B +:10B8200070BD898EC91A9142FADA012070BD0000FC +:10B83000F4061000F428100044061000460610001C +:10B8400098051000450610001E1A01209C061000E5 +:10B8500075061000760610007C580120C006100006 +:10B86000FCF7E6B810B541F23041BB480DF0FAFCE8 +:10B870004FF49E61B9480DF0F5FCB948FF2180F8FE +:10B88000401300F093FCFEF7E8F9FFF794FE00F098 +:10B8900071F9FCF782FDFDF788FBBDE81040FCF76D +:10B8A000C8B870B5AF4C0025AB48A57100F084FC5A +:10B8B000AD48006890F84004C00605D5AB48007953 +:10B8C00010B1A548FDF731FFA948007828B1A2487A +:10B8D000FFF7C4FEA04800F04EF99F48FCF765FD55 +:10B8E0009D48FDF769FB9D4880F8EC549C48B0F8F2 +:10B8F0004403A4F81F0070BD70B5984D994E95F89B +:10B90000EC04C8B3984CB071206890F81E0A800708 +:10B9100003D529469048FEF744F990498E4800F037 +:10B920007DFC206890F84004C00605D58F4800795A +:10B9300010B18948FDF7F9FE8D48007810B18648AE +:10B94000FFF78CFE206890F87C03C00702D0824885 +:10B95000FDF783FE804800F00EF97F48FCF725FDD7 +:10B960007D48FDF729FB002085F8EC047C48B0F801 +:10B970004403A6F81F0070BDFFE7FFF792FFF5E74D +:10B980002DE9F041744E002401274FF0080806F518 +:10B99000805522E0D5F8380307FA04F108421BD09D +:10B9A00004EBC40000EB441006EBC00090F8261135 +:10B9B000032909D0042907D0052905D0062903D079 +:10B9C000072901D0082907D180F8268190F935117F +:10B9D000002901DB07F035F9641C95F94003A0420A +:10B9E000D8DABDE8F08110B55E48002484715A4869 +:10B9F00000F0E2FB5848FCF7D8FC5748FCF72CF85D +:10BA0000564880F8EC4410BD10B5544C94F8EC0442 +:10BA1000D8B15449887121464F4800F0FFFB524885 +:10BA2000006890F87C03C00702D04B48FDF715FE74 +:10BA3000494800F0A0F84848FCF7B7FC4648FCF736 +:10BA40000BF8002084F8EC0410BDBDE81040CAE7F4 +:10BA500010B5424C014694F8EC040F280DD2C0EB0F +:10BA6000C00000EB400004EB800054220DF09EFB70 +:10BA700094F8EC04401C84F8EC0410BD10B500F5FB +:10BA800080500021D0F83833012200BF02FA01F4BF +:10BA900023420BD18A401343C0F8383390F9402336 +:10BAA0008A4201DA80F8401348B210BD491C0F29C0 +:10BAB000ECDB4FF0FF3010BD10B500F5805091F871 +:10BAC00034410123D0F83823A3409A43C0F83823E7 +:10BAD000002281F8262190F9402391F934118A42FD +:10BAE00007D1D0F83813B1FA81F1C1F11F0180F804 +:10BAF000401310BD30B500F580500022D0F83C4313 +:10BB0000012300BF03FA02F52C4206D193401C43E7 +:10BB1000C0F83C4381F8352130BD521C52B20A2A8C +:10BB2000F0DBFF2081F8350130BD10B500F5805005 +:10BB300091F835410123D0F83C23A3409A43C0F843 +:10BB40003C23FF2081F8350110BD044870470348AD +:10BB500090F8EC047047000038291000683D100090 +:10BB6000383910007C580120F4061000A806100097 +:10BB70003507100070472DE9F047054641F238308F +:10BB8000042128440CF0AAF800240127DFF81081D2 +:10BB9000DFF810914FF0050A05F580567AE000BFF6 +:10BBA000D6F8381307FA04F0014271D004EBC40050 +:10BBB00000EB441005EBC00191F82601012804D0E8 +:10BBC000022802D004283FD062E091F83F0101280A +:10BBD00008D091F82701032808D0042806D00128AE +:10BBE00028D055E0002081F83F0129E02E4848F296 +:10BBF0000403B0F90020C88F184203D02B4AB2F9D1 +:10BC0000002005E0030503D5294A1268B2F989240A +:10BC1000030702D5274AB2F90020B1F95030934208 +:10BC200036DAC0050CD5B8F90000834208DD81F88A +:10BC300027712DE0B1F95020B8F90000824227DACF +:10BC40002846FFF739FF23E091F83C0010F0060F7B +:10BC50001ED091F83E0040071AD4184A16481278B0 +:10BC6000B0F90000012A01D1B9F9000091F82721AB +:10BC7000032A02D0022A05D00AE0B1F95020B9F90E +:10BC8000000001E0B1F95020824201DA81F826A1DA +:10BC9000641C64B296F94003A04281DABDE8F087E3 +:10BCA0002C0610002E06100028061000400610007A +:10BCB000F40610004A061000300610004506100079 +:10BCC00090F83C10090603D5C18F41F00801C187E7 +:10BCD00070472DE9FF5FDFF8C09615460C4601F16D +:10BCE0000C074FF000084FF0010A4FF0FF3B02F144 +:10BCF0000C0693B384F826A195F84A0084F827012E +:10BD000084F835B184F82A8184F82B81A4F83E8028 +:10BD1000C4F82C8084F8298184F82C8195F84C0093 +:10BD200084F82F01688EA4F85200E868206203228C +:10BD30003146204607F02CFC03223146384607F0F6 +:10BD400027FC4FF40040A4F85C00A4F85800401E03 +:10BD5000A4F85A00A4F856003CE0FFE7114620463C +:10BD600000F024FBE06A0322401CE06231462046DA +:10BD700007F002FC03223146384607F0FDFB94F839 +:10BD80002E0184F82F01D9F80000E16A90F8D90358 +:10BD900081421FD2E189608A081AB4F9581000B2B2 +:10BDA000814201DAA4F85800B4F95610814201DD4D +:10BDB000A4F85600A089218A401AB4F95C1000B298 +:10BDC000814201DAA4F85C00B4F95A10814201DD25 +:10BDD000A4F85A00D9F8000090F8961009070FD57A +:10BDE00095F84A00042804D094F83701012803D0BC +:10BDF0000EE084F837A10BE0042085F84A0007E044 +:10BE000094F8271104294ED095F84A0084F82701A8 +:10BE100095F84A0084F8270195F84C0084F82E0123 +:10BE200095F84B0084F83001E88CA4F84000288D88 +:10BE3000A4F84200688DA4F84400E88DA4F84600F8 +:10BE4000288EA4F84800288BA4F84A00B5F93200DF +:10BE5000A4F85000A9692163E9696163296AA163B3 +:10BE6000A98EA4F85410A98CA187A96BC4F85E1000 +:10BE70006969E16195F84D1084F8311195F84E101B +:10BE800084F83211B4F95210814201DAA4F8520058 +:10BE9000C4F8388184F833B1A88C8005E08F14D5BC +:10BEA00040F4807013E095F84A10042908D094F902 +:10BEB0003601002801DD401E04E084F82711A7E7C1 +:10BEC00090F8970084F83601A2E720F48070E087AC +:10BED00055F83C0FC4F86200287A84F83D01687A6E +:10BEE00084F83E012146009800F02DFA04B0204667 +:10BEF000BDE8F05FE4E6F0B5B1F90260B2F90250D6 +:10BF0000782406FB05F7002F2ADDB1F90070B2F99D +:10BF100000C007FB0CF7002F22DD76435D4396FB44 +:10BF2000F5F52DB24580B1F90010B2F90020494372 +:10BF30005A4391FBF2F10AB20280782D00DD448071 +:10BF4000B0F902306FF077018B4200DA4180782A35 +:10BF500000DD0480B0F900208A4200DA0180F0BDE3 +:10BF600000214180FAE72DE9FF4FDFF83084834656 +:10BF70000F46D8F8040087B00021016000F0A5FA50 +:10BF800000250BF580564FF00109059089E000BFB0 +:10BF9000D6F8380309FA05F108427DD005EBC50053 +:10BFA00000EB45110BEBC10494F82601072876D06D +:10BFB000F948059901910068214690F88AA3201D4F +:10BFC00007F009FB00FB0AF0019900FB0AF0884228 +:10BFD00000DA0846F049096891F87D23920611D5E8 +:10BFE000E26A012A0ED802D191F8D71302E04AB9C9 +:10BFF00091F8D613019A01FB01F101FB02F188428D +:10C0000000DA084682462246211D684607F0D9FA22 +:10C01000221D111D03A807F0D4FABDF900006430F9 +:10C02000C82804D8BDF902006430C82801D901230A +:10C0300000E0032303AA694602A8FFF75CFF6088BB +:10C04000BDF80A100844ADF812002088BDF80810A9 +:10C0500000240844ADF810001BE000BFC4EBC4008E +:10C0600000EB400007EB800104A80C3107F0B3FAA5 +:10C0700050450CDAD8F804100A6802EB420201EBD2 +:10C0800042025060547215720868401C0860641CBB +:10C09000E4B297F8EC0400E001E0A042DED86D1CA9 +:10C0A0006DB296F94003A842BFF672AFD8F804000B +:10C0B00046460168002976D000F0E3F900244FF0ED +:10C0C000040A6CE004EB440001EB400090F90850D6 +:10C0D00090F909C0099809FA05F1026848460A4230 +:10C0E0005CD10A9BD3F8008000FA0CF318EA030F26 +:10C0F00054D109980A43C84602600A980168194356 +:10C10000016005EBC50000EB4511CCEBCC0000EB6A +:10C1100040000BEBC10507EB80020023294658467F +:10C12000FFF7D7FD95F82601032804D0042805D091 +:10C13000062809D032E085F8298102E0002085F840 +:10C14000290185F826A129E085F826A195F83C006B +:10C1500010F0060F22D095F83E0040071ED49149FA +:10C160008F480978B0F90000012902D18E48B0F952 +:10C17000000095F82711032902D002290AD00DE00A +:10C180008948B5F95010B0F9000005E0062085F89F +:10C19000260103E0B5F950108142F7DB641C716899 +:10C1A0000868A0428EDC0BB0BDE8F08F7B48002110 +:10C1B00001704160816070472DE9F041054641F210 +:10C1C00084302E2128440DF04DF8002405F58056CA +:10C1D00001274FF005081BE0D6F8380307FA04F1F1 +:10C1E000084214D004EBC40000EB441005EBC0017E +:10C1F00091F82601032804D0042802D0022803D095 +:10C2000005E081F8268102E02846FFF755FC641C12 +:10C2100096F94003A042DFDABDE8F0812DE9FC4742 +:10C22000044600255D480F4600950121001D01953B +:10C2300004F092FC59480521083004F08DFC41F2CD +:10C2400084302E2120440DF00DF8544EFF222D2174 +:10C25000B0680CF0DDFF357004F580564FF0010832 +:10C26000D6F8380358B36B4601AA39462046FFF783 +:10C270007AFE4FF005091EE0D6F8381308FA05F0EB +:10C28000014217D00199084214D105EBC50000EB1B +:10C29000451004EBC00191F82601032804D00428BE +:10C2A00002D0022803D005E081F8269102E0204662 +:10C2B000FFF702FC6D1C96F94003A842DCDA00256A +:10C2C00031E000BF009908FA05F008422AD1D6F8FB +:10C2D000380308B1002000E0012082462046FFF725 +:10C2E000CDFB00281EDB00EBC00101EB401104EB8D +:10C2F000C109C5EBC50101EB410107EB810289F8DA +:10C300003401494601232046FFF7E3FCB9F83E001B +:10C31000BAF1000F02D040F4805101E020F48051C6 +:10C32000A9F83E106D1C97F8EC04A842CAD81B4827 +:10C330000121001D04F028FC18480521083004F0F4 +:10C3400023FCBDE8FC8730B5144A91F82E5194685F +:10C35000635DFF2B05D1137863550F2B01D25B1C56 +:10C36000137091F82E21A25C81F82E2100EB42027D +:10C3700002F5805291F83451B2F884330124AC4074 +:10C380002343A2F8843391F82E1141F2A2321044D3 +:10C390000A5C521C0A5430BDF4061000AC051000B3 +:10C3A00030061000450610002E0610002DE9F04161 +:10C3B000044691F84A0000260D46012801D184F870 +:10C3C0002C6194F82701564FDFF8588101281FD1BE +:10C3D00095F84A0003284DD194F82601022804D08C +:10C3E000032806D0042804D01EE02046FBF75CFF9B +:10C3F0000EE0D8F8001094F82C0191F84B1301F0DE +:10C400000F01884202D83978012906D084F82C61BE +:10C4100095F84A00032807D008E0401C84F82C0156 +:10C42000012085F84A0001E084F82D6194F8270185 +:10C4300003281FD195F84A0001281BD194F8260142 +:10C44000042817D13878B0B9D8F80000B4F95220D0 +:10C450000321B0F852339A4210DA94F82D2190F863 +:10C460005403824207D285F84A1094F82D01401CEB +:10C4700084F82D01D0E684F82D61CDE685F84A10C8 +:10C48000F9E77CB500211CE001EB41034A1C00EBFD +:10C49000430312E002EB420400EB44045E6865686B +:10C4A000AE4209DD00961E89ADF804605D60258905 +:10C4B0001D81009D65602681521C04689442E9DC60 +:10C4C000491C02688A42DFDC7CBD70B5154D2868C6 +:10C4D000B0F880430DF000F880B128681249B0F838 +:10C4E0008443B0F888030968884207DA0CF0FEFF3D +:10C4F000012803D12868B0F8860304440B4800786B +:10C5000010B12868B0F876420CF0F0FF012804D191 +:10C510002868B0F8820300B1044604FB04F070BD43 +:10C5200081061000F4061000B40610003405100057 +:10C530002DE9F84F00229146154614460092FE4A16 +:10C54000FE4B1268B3F900C0FD4B178E1E6867459D +:10C5500060D18646FB4802F1320A8B4690F800C053 +:10C56000F94807784DE03A4643E000BF3AF8121028 +:10C570003EF812003BF81230081AC91A00B20BB28A +:10C58000002801DB014600E04142494506DD002864 +:10C5900001DB014600E041420FFA81F9191A01D48A +:10C5A000884601E0C1F10008A84505DD002901DB4E +:10C5B0000D4600E04D422DB2002900DA4942B6F89E +:10C5C000E683414515DD002B00DA5B42011E00DAEF +:10C5D00041428B4202DD641CA4B20AE0002800DA6A +:10C5E0004042B6F8E813884203DD4FF0000C644681 +:10C5F00001E0521EBAD10AEB470A0EEB470E0BEBD5 +:10C60000470BBCF1010CAED296F8EA03A04201D26E +:10C610000120009096F8EB13CC48009A06F04DFFED +:10C62000CB4921F8255F21F8029C8C70BDE8F88F7A +:10C63000F0B500240646254620465F4209E000BFCB +:10C6400036F91130934201DD1D4402E0BB4200DAAD +:10C650001C44491EF4D2002C00DA6442AC4200DDD6 +:10C660000120F0BD2DE9F05FB44CBB4EB94DB4F9DB +:10C670000040002047F6FF7A01462A465346A4466A +:10C6800036680AE036F91C70974200DD3A469F4250 +:10C6900000DA3B46381841EBE771BCF1010CF1D2EE +:10C6A000D71ADFF8B8924FEAE47B22465B46C9F816 +:10C6B00004700CF012FDDFF8988203B20020A8F895 +:10C6C00080700146224604E036F91270FF1AC7FB5B +:10C6D0000701521EF8D222465B460CF0FEFC0A21EE +:10C6E000C9F8000090FBF1F0A8F882009C4B0020F4 +:10C6F0004E4601465246A4461F680AE037F91C30F0 +:10C70000AB4200DD1D46934200DA1A46181841EB91 +:10C71000E371BCF1010CF1D2AA1AF26022465B4629 +:10C720000CF0DBFC03B200200146224605E000BF0E +:10C7300037F91250ED1AC5FB0501521EF8D22246F8 +:10C740005B460CF0CAFCB060BDE8F09F30B4144604 +:10C75000824A15689368AB4202DD5B1B834206DCAC +:10C76000D3685068834204DD181A884201DD012233 +:10C7700000E000222146754830BC001D06F09DBE39 +:10C7800010B50C466F4909784A00014675480CF00F +:10C79000C8FC6D4821460078420073480CF0C1FC8B +:10C7A00072490120087010BD644910B5B1F900103C +:10C7B0004A0001466A4800680CF0B3FC6C4901204D +:10C7C000087010BD2DE9FF5FDFF880B10024ABF1E8 +:10C7D000080BDFF86CA1CBF804408BF80040DAF8C6 +:10C7E0000000DFF86881994690F8E5132746264651 +:10C7F0002546090716D559490A890B88D31A544A80 +:10C8000022F8633F8B898988591A518090F80C244B +:10C81000B0F80A14D0F80604FFF798FF1226044671 +:10C82000012701E088F80450DAF8001091F89F22FF +:10C83000520701D54F4A157091F8E403C0070DD097 +:10C8400003200AF0FCFC464801680098FFF770FEE0 +:10C850000443112603200AF00DFD01E088F8005082 +:10C860008CBBDFF814A19AF8000010B99AF8010007 +:10C8700018B10098F9F755FD0AE04048007818B162 +:10C880000021062006F0E8F93C4805703C48057098 +:10C890009AF8001011B99AF80100A0B1DFF8A0A031 +:10C8A000DAF8000090F8E503C0070DD03748354AA4 +:10C8B0003549006800F0EBF804004FF030064FF007 +:10C8C000010703D012E024E088F80150DAF80000F4 +:10C8D00090F8E503800709D52C482A4A2A490068C0 +:10C8E00000F01AF931260446012701E088F80250C9 +:10C8F0006CB9DAF8000090F8E403400707D5214945 +:10C90000214800F047F921260446012701E088F874 +:10C9100003500CF0F1FD01461D480170E4B31D48C1 +:10C9200005800748016891F8F011090600D5A7BBFA +:10C930009FB389F8005031E0F80610008606100019 +:10C94000F40610007506100076061000C0051000F1 +:10C950007C5801200080FFFFA0061000A01A0120D3 +:10C96000A40610000C720120367201202D07100061 +:10C970002C07100040051000A80610003405100018 +:10C98000220510001A0D0120F00C0120980610005D +:10C9900012061000FC06100027E00BE031460520CF +:10C9A00006F05AF90098FFF7FFFEDDE90101FFF7F5 +:10C9B000E7FE17E0012189F800108BF80060DBF832 +:10C9C000042042F00202CBF80420006890F85032B4 +:10C9D000DB0703D190F81E0AC00703D042F008001D +:10C9E000CBF80400012004B0AEE689F800500078CE +:10C9F000F9E72DE9F047DFF81892824600248548D0 +:10CA0000C9F8044089F8004000680E46274690F8AF +:10CA1000E5132546A046C9060BD590F81324B0F8B7 +:10CA20001114D0F80D04FFF791FE122504460127DA +:10CA300003E07749083181F804800CF05DFD014680 +:10CA400075480170BCB14FB186F8008029460520B9 +:10CA500006F002F95046FFF7A7FE09E0012030700A +:10CA600089F80050D9F8041041F00201C9F8041007 +:10CA70000120BDE8F08786F800800078F9E7644976 +:10CA800000204860087008310860087170472DE97F +:10CA9000F74FDFF880910B468246D9F800105F48C7 +:10CAA0000026B1F9EC7391F8F083B1F9EE530278F6 +:10CAB00034463946184600F091F8834658483946BE +:10CAC0000278029800F08AF80146BBF1000F00D00E +:10CAD000A1B9544852460024B0F9000009E000BF53 +:10CAE00032F91010002900DA4942A94201DD641C24 +:10CAF000E4B2401EF4D2444500D90126D9F8000022 +:10CB0000324690F8F1134248093006F0D6FC464907 +:10CB100081F83140BDE8FE8F2DE9F047DFF8F48061 +:10CB200084460B46D8F800003E49002590F8F6737D +:10CB3000B0F9F46391462C46B0F9F203B1F9001054 +:10CB400007E000BF3CF91120002A00DA524282427D +:10CB500013DC491EF6D2314831460278184600F0FF +:10CB600049F804462E4831460278484600F042F81B +:10CB70002044C4B2BC4200D90125D8F800002A469E +:10CB800090F8F71322480A3006F097FC264981F8FE +:10CB900032406EE770B51F4C05460E462068B0F96E +:10CBA0000334B0F901241D4801782846FFF740FD01 +:10CBB00005462068B0F90334B0F90124184801781B +:10CBC0003046FFF735FD40EA0502206890F805146D +:10CBD000BDE870400E480B3006F06FBC06E000BFA9 +:10CBE00030F912308B4201DD01207047521EF7D21E +:10CBF0000020704710B50346002005E033F91240CD +:10CC00008C4201DD401CC0B2521EF7D210BD0000A4 +:10CC1000B8051000F406100012061000750610008A +:10CC200076061000860610007C5801202DE9FF4F83 +:10CC300093B000200E908346049005909C4889464E +:10CC400016460068B0F8BA020D90897850680CF06A +:10CC500079FC0A9099F8021030680CF07BFC09907E +:10CC600099F8020047E000BF99F8004034E01398BB +:10CC7000224600EBC8000021D0E9005701200CF04B +:10CC800019FA05400F403D4325D00A980D9930F917 +:10CC90001400009088421EDD8548006890F8DF028D +:10CCA00000070AD50998005DCF287BD028B196F8F7 +:10CCB0004F10884201D000200090009904988B44C6 +:10CCC00004FB01000490059808FB010005900E98F4 +:10CCD000401C80B20E90641C99F80100A042C6DA94 +:10CCE00074490A98097800EB41000A9009982830A5 +:10CCF000099008F1010099F8031080464145B3DA24 +:10CD00006B48002504680598A18EC217A1FB003767 +:10CD100005FB007001FB02014FF6FF77A3FB070C38 +:10CD200001FB07C103FB051194F8313030345B1E61 +:10CD30008BFB03230CF0D1F97A108018B94641F12E +:10CD400000014A4600230CF0C8F980460498618827 +:10CD5000C217A1FB003705FB007001FB02024D4624 +:10CD6000A3FB050702FB0572002103FB01212378C9 +:10CD70005B1E8BFB03230CF0B0F96A10801841F1A5 +:10CD800000014A4600230CF0A8F9C6F81CB00E9921 +:10CD90003185169948601699C1F8008017B0BDE832 +:10CDA000F08FFFE700200F90451E089008EB050765 +:10CDB000F9B230680CF0CEFB8246F9B270680CF024 +:10CDC000C1FB4FF0FF3163181AF803208AB1CF2A54 +:10CDD0000FD096F84F70974205D130F81370089A2B +:10CDE0003A4492B2089230F813300F9A1A4492B231 +:10CDF0000F92491C49B20129E5DD6D1C6DB2012D70 +:10CE0000D4DD089800283FF458AF009948430F99A3 +:10CE100090FBF1F050E710B52549436800220968FE +:10CE2000002B01DA426003E04C8EA34200DD446037 +:10CE30000368002B01DA026010BD898E8B42FBDD96 +:10CE4000016010BD7CB5144600256B46FFF7EEFE71 +:10CE500019480178164829B1016891F807150907A2 +:10CE600000D5042594F84A10032902D0012907D0DF +:10CE70000FE0006890F80705C0070AD0294605E0D2 +:10CE8000006890F80705400703D50221684601F0C5 +:10CE9000A3FF6846FFF7BFFF0198E0810098A081DB +:10CEA00094F82400C00601D4E06860617CBD0000F5 +:10CEB000F406100076061000440610002DE9F04735 +:10CEC000054690F802800F468868144601264146C0 +:10CED0000CF038FB8146A8F10100C1B2B8680CF033 +:10CEE00031FB297809EB410232F9022CA24203DB23 +:10CEF00030F91110A14200DA0026697809EB4102ED +:10CF0000B2F90220A24203DB30F91100A04200DA9C +:10CF1000002695F80380B86841460CF013FB814663 +:10CF200008F10100C1B2B8680CF00CFB297809EBDC +:10CF3000410232F9022CA24203DB30F91110A14266 +:10CF400000DA0026697809EB4102B2F90220A24218 +:10CF500003DB30F91100A04200DA00263046BDE8BC +:10CF6000F0872DE9FF4FFB48DFF8EC839246046819 +:10CF700097B0994601225146D8F8000001F0BAFB5B +:10CF8000F6480068B0F94D14119190F84C040A90DD +:10CF9000F3489AF802709AF8036000789AF800B0A3 +:10CFA0009AF80150401E874201DA7F1CFFB20EB191 +:10CFB000761EF6B2EB490978491E8B4503DA0BF170 +:10CFC000010000F0FF0B0DB16D1EEDB2B81EC1B235 +:10CFD000D9F808000CF0B6FA0B90781EC1B2D9F857 +:10CFE00008000CF0AFFA04903946D9F808000CF0AC +:10CFF000A9FA0190781CC1B2D9F808000CF0A2FA85 +:10D000000290B81CC1B2D9F808000CF09BFA03904A +:10D01000394617980CF090FA0890CF4839460068C6 +:10D020000CF098FA864600207AB2CF4F0C90B7E009 +:10D030004FFA8BF094E000210EF800100899189B2D +:10D04000095C994275D1DFF814C3019BDCF800C07C +:10D0500033F91030BCF84FC463456ADA00211491EB +:10D06000139111991944049B09B233F910301093AC +:10D070008B4206DD029B33F910308B4201DD012328 +:10D080001393019B03EB400333F9028C884507DDC2 +:10D09000B3F902C08C4503DD4FF0010CCDF850C050 +:10D0A000012A0FDDDDF82CC03CF910C08C4509DDEC +:10D0B000DDF808C03CF910C08C4503DD4FF0010CD1 +:10D0C000CDF84CC0DFF898C29CF800C0ACF1020C5F +:10D0D00062450DDADDF840C08C4509DDDDF80CC095 +:10D0E0003CF910C08C4503DD4FF0010CCDF84CC06D +:10D0F00001280BDD33F904CC8C4507DDB3F902C000 +:10D100008C4503DD4FF0010CCDF850C0DFF854C260 +:10D110009CF800C0ACF1020C604505DA884503DDDF +:10D12000B3F904308B4212DC149981B913990DE0E4 +:10D13000FFE799B90199B7F9003031F91010994218 +:10D140000CDA8649096891F84114C90731B1012107 +:10D150000EF800100C99491C89B20C91401C40B289 +:10D16000A8427FF768AF7F480B990EF1280E007830 +:10D1700001EB40010B91049901EB400104910199ED +:10D1800001EB40010191029901EB400102910399E9 +:10D1900001EB4000039008982830521C52B20890CE +:10D1A000B2427FF745AF0A990C9888422AD90020ED +:10D1B00084F80E01DAF800002060674800231A4660 +:10D1C0002146006801F03DFC012517E004EB8500D5 +:10D1D0000646514600F03FF970B104EB4500B0F847 +:10D1E000B4100A98814207D93046B7F90020494661 +:10D1F000FFF764FE012806D06D1CEDB294F80E0115 +:10D20000A842E3D200201BB0BDE8F08F2DE9F84F13 +:10D2100004465048DFF8408191468B46056801225C +:10D220002146D8F8000001F065FA0027A6784FF0F3 +:10D23000010A1DE03146D8F800000CF08BF900908F +:10D240003146DBF808000CF07DF9014620785246A3 +:10D2500009E000BF31F910C0CC4502DA009B01277C +:10D260001A54401CC0B263788342F3D2761CF6B2E3 +:10D27000E078B042DED2012F2ED1002085F80E01D9 +:10D280002068286000231A462946D8F8000001F0DB +:10D29000D8FB0126DFF8C4801AE000BF05EB860743 +:10D2A0002146384600F0D7F880B105EB4600B0F8CB +:10D2B000B410D8F8000090F84C04814206D93846E2 +:10D2C0004A465946FFF7FAFD012806D0761CF6B209 +:10D2D00095F80E01B042E1D20020BDE8F88F2DE9AB +:10D2E000F0411E4E0F468046316814461F481D46C9 +:10D2F0009A69B1F8493400789A4210DCEA8C042A21 +:10D300000DD96278237891F84B14D21A521C8A42B4 +:10D3100005DCE278A378D21A521C8A4202DD002092 +:10D32000BDE8F0810028FBD10F482946B0F9002064 +:10D330002046FFF76BFF0028F2D1316891F84014C6 +:10D340008907EDD52B46224639464046BDE8F041D7 +:10D3500007E60000FC051000E4051000F4061000CC +:10D36000750610007606100048061000C50510006E +:10D370002DE9FF4F81B0DFF808B1DDF838905FEAA2 +:10D38000030815461DD42C780BEBC80A16E000BF25 +:10D3900008F0FF0101980CF0DDF80090DAE9006771 +:10D3A0002246012000210BF085FE06400F403E433F +:10D3B00002D1009800210155641CE4B26878A042B3 +:10D3C000E6D2B9F100001EDB0246AC780120002154 +:10D3D0000BF070FE06460F464FF0000810E02146A5 +:10D3E00001980CF0B7F80BEBC4010246D1E900013B +:10D3F00030403940084301D102F80980641CE4B28E +:10D40000E878A042EBD205B0FEE670B51E4B1D4A8F +:10D410008C691B681278B3F84954AC4210DCCC8C90 +:10D42000042C0DD94478057893F84B34641B641CA4 +:10D430009C4205DCC4788578641B641C9C4201DD39 +:10D44000002206E02AB9114AB2F90020FFF7DEFEF9 +:10D450000246104670BD02780B789A420BD942788A +:10D460004B789A4207D282788B789A4203D9C07857 +:10D47000C978884201D3002070470120704700001E +:10D4800000431000C5051000F40610002E06100021 +:10D4900070B5FE4C00EB4305049E00EB830386B1A0 +:10D4A0008E69A660CE8CA68009686161B5F8B4105B +:10D4B000E1801968E16090F80E01607010682061E9 +:10D4C00070BDA6688E61A688CE8466690E60E1880C +:10D4D000A5F8B410E1681960617880F80E11206930 +:10D4E000106070BD0146002091F82410099B1F9A1E +:10D4F000C90610D4D9B2D2B2514301290BD1E449A3 +:10D500008A78002A07D14978002904D1E1490978AD +:10D51000002900D1012070472DE9FF4F81B00C4652 +:10D520001E469978DDF840800E9D0CF013F80090AF +:10D53000B17820460CF000F88346B178D8F80400A2 +:10D540000CF000F88146D4484FF0000AC8F818A043 +:10D5500000682860B77841E0347831E01BF80410A7 +:10D56000039881422AD139F914100F98814222DDA3 +:10D570000099039808552978204605F096FF2870F1 +:10D580006978204605F095FF6870A978384605F05F +:10D590008CFFA870E978384605F08BFFE8700AF137 +:10D5A00001001FFA80FA39F91400D8F81810014464 +:10D5B000C8F8181002E0009900200855641CE4B275 +:10D5C0007078A042CAD20098B449283000900978F7 +:10D5D0007F1C0BF1280B09EB4109FFB2F078B84230 +:10D5E000BAD2A8F826A005B0BDE8F08F2DE9F04327 +:10D5F000814693F84A00AA4EABB01C4615468846B1 +:10D60000032822D194F82400C0061ED4E08CA4F88C +:10D6100050002868E0633068B4F9321090F8B7021F +:10D620004843642190FBF1F0B4F9361000B2814216 +:10D630000BDA03A9CDE9001049462B464246029475 +:10D640000846FFF769FF03982860964F387808B9B5 +:10D65000787860B1306890F82602000707D5234635 +:10D660002A4641464846F8F7F2F8002854D08E483A +:10D670000178042029B1397819B18C490978012938 +:10D6800004D094F84A10032905D00CE03268E18CEC +:10D6900092F87A2203E03268E18C92F80F239142EB +:10D6A00001D984F84A00824B2A464146484600F098 +:10D6B000D8FF002830D084F84F802868A063224625 +:10D6C00029467B4800F06CFE7A492046FDF7F5FFBD +:10D6D0005822794914A80BF069FD50227749684611 +:10D6E0000BF064FD75480838D0E900232046FFF7A9 +:10D6F000F9FE012803D129466D4800F04BFF294669 +:10D700006B4800F047FF224629466948FFF79AFB1D +:10D710002046FEF79DF901202BB0BDE8F0832DE9EE +:10D72000F0410D461F461646044654210BF09AFD63 +:10D73000002084F84A00624800686060A06006EB40 +:10D74000450084F84C5030F8B41F61850088E084AF +:10D7500006EB8500006820645A480088E0864B4844 +:10D76000816921600121A940394201D0406A2060CD +:10D77000BDE8F0812DE9F05F534D8B461C461746FE +:10D780002E4603F1440803F1460A91780BF0D4FECB +:10D790008146B97860680BF0D5FE0021A161BA78A6 +:10D7A00034E0397827E000BF19F801C0DC4520D10A +:10D7B00030F91130D4F818C09D429C44C4F818C008 +:10D7C0000FDA2E4698F800508AF8005098F8015069 +:10D7D0008AF8015030F9115088F8001088F80120BB +:10D7E00007E09E4205DA30F911608AF800108AF8E5 +:10D7F0000120491CC9B27B788B42D5D22749521CE3 +:10D8000009F128090978D2B200EB4100F978914278 +:10D81000C7D2A4F848606586BDE8F09F2DE9FF41B6 +:10D8200017460AAA804692E83100264A1E46B2F9F7 +:10D830000020824202DB002004B099E703AACDE970 +:10D84000002002943A464046FFF766FE0121286810 +:10D85000B94008432860C4F80080E08C10B10398F8 +:10D860003060E8E70120E7E72DE9FF4F81B09046FF +:10D870000E9C1E4604EB88008B4694F80E71DDF872 +:10D8800040A000682060012321461FE0C805100069 +:10D890002807100034051000569501007606100088 +:10D8A000F4061000A8061000200510002205100044 +:10D8B00058421000B01A0120F0231000A0231000DD +:10D8C00098061000360610000080FFFF584601F051 +:10D8D000B8F8019858451ED0B57819E02946019846 +:10D8E0000BF038FE8146294658460BF033FE0146C0 +:10D8F000307808E019F80030434502D10B5C09F894 +:10D900000030401CC0B272788242F3D26D1CEDB27E +:10D91000F078A842E2D294F80E0100250121B84225 +:10D9200012D0119878B17F1CF8B208E0DAF8002024 +:10D9300001FA00F31A43401CC0B2CAF8002094F860 +:10D940000E218242F2D201250091434652462046E2 +:10D950000F99FFF79DFD284645E610B5FE4AFF4C9E +:10D960001368647893F80E2354B191F8241011F0E1 +:10D97000090F02D093F8111301E093F810130A4431 +:10D98000904201D9012010BD002010BD2DE9F047C3 +:10D990001C4617468846814601F0AEFAEE4EE08CF2 +:10D9A000316891F81623904267D8032084F84A0022 +:10D9B00091F8DE020025820701D4400700D5012539 +:10D9C000E64BB1F81203B1F8172393F801C0E44B0A +:10D9D000BCF1000F06D093F806C0BCF1000F01D1D6 +:10D9E000B1F81403DFF87CC39CF800C0BCF1010F50 +:10D9F00003D1904201D9801A80B2A28D824202D214 +:10DA0000D948007820B1608D032806D2002517E0A0 +:10DA1000608D00250328F9D312E08DB1187978B113 +:10DA200091F8400440070BD521463846FFF7EDFC3E +:10DA3000CE49087020B1A08C40F08000A08415E091 +:10DA4000A08C10F4C07F11D185B1306890F8DE024F +:10DA5000C00703D02146384601F021FC23463A4650 +:10DA600041464846BDE8F04702F0FABB23463A4635 +:10DA700041464846BDE8F047B8E5042084F84A002E +:10DA8000F4E7B748C07858B1B348B94A006812689B +:10DA900090F85713914207D290F84003800703D5BE +:10DAA000B4490020087070470120704791F8241095 +:10DAB000A94ACB07B0491268097806D011B192F88B +:10DAC000481305E092F8491302E059B192F8461361 +:10DAD000A24B5B7813B192F84A231144884204D9CF +:10DAE0000120704792F84713F2E7002070472DE9B4 +:10DAF000FF4F834687B09A4800270C46DDF850A0B8 +:10DB000001790126154606FA0AF6B946E9B39B489B +:10DB10009B49B0F90000B1F90010884235DA296854 +:10DB2000314232D1E18C04292FD98DE83100DFF860 +:10DB3000548252460A9BD8F81810D8F82400FFF7F0 +:10DB40006DFE070021D12346206851460A9AFFF74F +:10DB5000C6FB86490870C0B1781E8DF810008DF89C +:10DB600014007D48006890F84104800709D5864874 +:10DB70000078042805D105AA04A90A98F7F72FF917 +:10DB800040B1A08C40F08000A084A08C10F4C07F35 +:10DB900020D02AE07D499DF9103001F8363F9DF9EB +:10DBA000140048700090206859460A9AFFF7E0FB7D +:10DBB00001A8CDF800B080E830025246216804F197 +:10DBC0004003D8F81800FFF74FFE0028DDD00120F1 +:10DBD0000BB009E52868304207D053462A46214653 +:10DBE0005846CDF80090FFF753FC3846F0E72DE992 +:10DBF000F04FE9B04FF0000A614D6549CDF894A1AE +:10DC0000B5F90000B1F90010624A61916490118089 +:10DC10006149D346D14608805A4801211C3002F0A0 +:10DC2000E5FF58480121243002F0E0FF5548022169 +:10DC3000203002F0DBFF0221584802F08DFF042162 +:10DC4000574802F089FF4F4C4FF466763146E06941 +:10DC50000BF0E6FA3146606A0BF0E2FA5148B0F98F +:10DC600000004100206A0BF0DBFA31464E480BF011 +:10DC7000D7FAA8214D480BF0F5FA0027A770F7F75F +:10DC800089FDF7F745F84A488DF87E710123006851 +:10DC90001C9000221CA9A06900F0D3FE45486097A3 +:10DCA0000026B0F90010B5F9000005F0FEFB00B247 +:10DCB00006909DF87E01012801D92C480770207834 +:10DCC0004FF0010868B93748B0F900103A480068C9 +:10DCD00006F081FC3949B1F90010884201DD84F871 +:10DCE000008017A80125629068E1002001901CA81F +:10DCF00000EB850005901CAA294607A8609BFFF74A +:10DD00000EFD07AB2946059A0798FFF733FD2B4612 +:10DD100060AA07A91CA8CDF80080FFF7B9FB18A8D6 +:10DD200000F012FC78B1BDF8400040F00100ADF801 +:10DD3000400007A800F0B5FD28B12148144900882B +:10DD400008800F49088008480078D8B3BDF8400023 +:10DD500010F0060F3AD136E0F40610002807100044 +:10DD6000A8061000B006100044061000C5051000FB +:10DD70001C0610007F0610008106100048061000E7 +:10DD80002E061000C8051000E80410007C58012081 +:10DD9000300610003E0610003C061000F005100092 +:10DDA000FC05100086061000B01A01205842100031 +:10DDB000240610004C0610009806100028061000DB +:10DDC0004206100002E0FE4800680890059800F046 +:10DDD000CDFB28B1BDF8400040F00800ADF8400090 +:10DDE000BDF94E100698814272DD009560AA07A920 +:10DDF0001CA8059BFFF77BFE00287DD108FA05F0E3 +:10DE000060990390084240D1BDF8400010F4C07FF3 +:10DE10003BD1EC4860AA07A9B0F900008DE80700E3 +:10DE20002A46059BA169606AFFF7F8FC0190E54866 +:10DE3000609A03990088ADF85200114223D0E2495C +:10DE4000BDF84220096891F816339A4205D891F836 +:10DE5000DE128A0717D4490715D41CAB60A907AA9C +:10DE6000CDF80C800093CDE901212A46629B616ABE +:10DE7000A069FFF7F9FCCDE900802B4660AA07A94D +:10DE80001CA8FFF705FB0198D8B9BDF8420007A907 +:10DE9000FFF763FDA8B1207850B907A80090CB48E0 +:10DEA0002946629AB0F90030A06900F0B3FA8146C1 +:10DEB00007AB2946059A0798FFF768FD4FF0010A5E +:10DEC00066E02B4660AA07A91CA80097FFF7E0FAB6 +:10DED000BE48BDF94E10B0F90000814258DDFFF791 +:10DEE000D0FDE8B32078D8BB08FA05F0609903901C +:10DEF000084233D160AA00E05EE0B44807A9B0F957 +:10DF000000008DE807002A46059BA169606AFFF7BB +:10DF100085FC0190AD480088ADF85200AA48006821 +:10DF200090F84003C00619D4609A0398104215D0A7 +:10DF30001CAB60A907AACDF80C800093CDE90121A4 +:10DF40002A46629B616AA069FFF78EFCCDE90080DA +:10DF50002B4660AA07A91CA8FFF79AFA019800E0CF +:10DF600016E070B9BDF8420007A9FFF79FFD40B168 +:10DF700007AB2946059A079800F099FA4FF0010B74 +:10DF800006E02B4660AA07A91CA80097FFF780FAB5 +:10DF9000609908FA05F001438D4A609161991180FA +:10DFA000884A649911808B490A782AB106439DF802 +:10DFB0007E01012800D90F706D1CEDB29DF87E0125 +:10DFC000A842BFF492AE854A834BA178A2F5667051 +:10DFD00002F0D3F882489DF87E1141718149A0F882 +:10DFE0001D60659808708048804980F800A081F81D +:10DFF00000B07F4981F80090FDF7A9FD9DF87E21D2 +:10E000007C49904202D981F8008000E00F70022123 +:10E01000794802F0B9FD0421784802F0B5FD0121EC +:10E02000774802F046FE76480121001D02F041FECD +:10E03000734801210C3002F03CFE71480221083087 +:10E0400002F037FE69B0BDE8F08F2DE9F04F0026F1 +:10E050006B48E5B0B146B0465A4F0121001D02F0B1 +:10E06000C5FD674801210C3002F0C0FD6448022163 +:10E07000083002F0BBFD02215F4802F06DFD042173 +:10E080005E4802F069FDDFF878B14FF46675ABF1D8 +:10E09000180B29465C46DBF81C000BF0C1F829463A +:10E0A000606A0BF0BDF85748B0F900004100206AE3 +:10E0B0000BF0B6F8294654480BF0B2F84648A821B0 +:10E0C000A8380BF0CFF84FF0000A504884F802A0AF +:10E0D0008DF87EA100681C905546012352461CA96C +:10E0E000A06900F0AEFC4A4860950025B0F9001028 +:10E0F000B7F9000005F0D9F907B29DF87E010128B3 +:10E1000002D9344981F800A00124D8E01CA800EB12 +:10E11000840005901CAA214607A8609BFFF7FFFA20 +:10E1200007AB2146059A0798FFF724FB01200090D2 +:10E13000234660AA07A91CA8FFF7AAF918A800F0AF +:10E1400003FA28B1BDF8400040F00100ADF84000EE +:10E15000059800F00BFA28B1BDF8400040F0080027 +:10E16000ADF84000BDF94E00B8427DDD009460AAD4 +:10E1700007A91CA8059BFFF7BAFC002875D1012050 +:10E18000A04060990390084272D1BDF8400010F49D +:10E19000C07F6DD10B4860AA07A9B0F900008DE8D7 +:10E1A00007002246059BDBF81810DBF82400FFF778 +:10E1B00035FB01900348609A0088ADF8520029E0D1 +:10E1C0009C0610002E061000F40610003206100007 +:10E1D00030061000C505100000431000481E012045 +:10E1E0007C5801207D0610007E0610007F0610007E +:10E1F00080061000B0061000F0051000FC051000AD +:10E20000E005100086061000B01A01202406100058 +:10E210004C0610000399114224D0BC49BDF842209D +:10E22000096891F816339A4205D891F8DE128A07E8 +:10E2300018D4490716D4012360AA07A91CA88DE8A1 +:10E240000F0017AB2246DBF82410DBF81800FFF7AD +:10E250000BFB019001200090234660AA07A91CA88F +:10E26000FFF716F9019802E018E026E000E068B92F +:10E27000BDF8420007A9FFF770FB38B107AB214694 +:10E28000059A0798FFF782FB012607E0234660AA5C +:10E2900007A91CA8CDF800A0FFF7FAF801206099A3 +:10E2A000A040014360919A490A7832B105439DF834 +:10E2B0007E01012801D981F800A0641CE4B29DF818 +:10E2C0007E01A042BFF422AF934A924B9BF802100A +:10E2D000A2F5667001F051FF90489DF87E114171E2 +:10E2E0008F49A0F81D508F4881F800908E49067024 +:10E2F0008E4881F80080022102F046FC04218C48FF +:10E3000002F042FC01218B4802F0D3FC8948012134 +:10E31000001D02F0CEFC874801210C3002F0C9FC40 +:10E3200084480221083002F0C4FC65B08BE610B5C9 +:10E330007B480024A82104707A4804707A4804704D +:10E340007348047073480AF08DFF7B480470794865 +:10E350001838047010BDEAE7764900201839734A6E +:10E3600008628861C8611060714A10606C4A107060 +:10E370006C4A10706C4A1070654A10708870704753 +:10E380006C4910B51839002088706248A821A83857 +:10E390000AF068FFBDE81040A8215E480AF062BF9D +:10E3A0002DE9F74F63480D46183881780F2901D2BF +:10E3B000491C817001F0FF09574982F84B9001EB2D +:10E3C000890029680160A9785C480BF0C3F882468F +:10E3D000A87819E000982C7800EBC80B0DE0DBE979 +:10E3E00000672246012000210AF064FE06400F402B +:10E3F0003E4301D00AF80490641C6878A042EEDA2B +:10E400000AF1280A08F10100E97880464145E1DA7D +:10E41000BDE8FE8F2DE9FF5F8B46144691780E9D77 +:10E420000BF08AF80646A17868680BF08BF807466F +:10E430004FF00009FFF725FB30B14149B5F9320033 +:10E44000B1F90010884203DD002004B0BDE8F09F60 +:10E450003C48A178E37890F800A01AE02078627830 +:10E4600010E000BF16F80080D84509D137F91080B8 +:10E47000DDF80CC0E04503DD09F1010C1FFA8CF951 +:10E48000401CC0B28242EDD2491C07EB4A07C9B218 +:10E4900028368B42E2D229464846FFF707FB002880 +:10E4A000D3D0A88C40F40070A8840120CDE72DE9DA +:10E4B000F0418046012083F84A001C4616460F466C +:10E4C000404600F019FD114D286890F840034107BF +:10E4D00004D52146304600F0F3FE05E0000703D5E1 +:10E4E0002146304600F0DBFE28682346324690F88D +:10E4F00040033946C006404603D5BDE8F04101F06F +:10E50000AFBEBDE8F041FFF771B80000F40610009F +:10E51000C505100000431000481E01207C58012052 +:10E520007D0610007E0610007F061000F00510002A +:10E53000FC051000E0051000B0061000B01A012024 +:10E540002806100076061000017859B1954A127815 +:10E55000521E914206D0407820B193490978491E55 +:10E56000884201D10120704700207047017829B10D +:10E570008C4942780978491E8A4209D1817829B1AB +:10E58000C17889480078401E814201D1012070473E +:10E5900000207047F0B5854D002205EBC206002330 +:10E5A000C6E90033521CD2B2172AF6D38A782CE07F +:10E5B00000EBC203D3E9007657EA060323D07408C0 +:10E5C0004FEA370317EB070E46EB060C44EA0C0440 +:10E5D000344343EA0E0305EBC2063B43D6E9007C15 +:10E5E0001F434CEA040CC6E9007CD6E9027C1F43B9 +:10E5F0004CEA040CC6E9027CD6E9047C1F434CEAD1 +:10E60000040CC6E9047C521CD2B2CB789342CFD220 +:10E610000022654B0AE000BF05EBC20400EBC20715 +:10E62000D4E90264C7E90064521CD2B21C78A24249 +:10E63000F2D3087808B1401E08705A4A4878127818 +:10E64000521E904201DA401C4870887808B1401E82 +:10E6500088701A78C878521E904201DA401CC8703F +:10E66000F0BD2DE9FF5F9478164604EB84028B46DB +:10E6700000EBC200002100F1290820E000208146C3 +:10E680008246357877780FE018F805205A4509D189 +:10E690002A46012000210AF00DFD41EA0A0A40EA5B +:10E6A000090901216D1CEDB2AF42EDD2039B08F1C7 +:10E6B000280803EBC403641CC3E9009AE4B2F078B1 +:10E6C000A042DBD204B00846BDE8F09F0A78437848 +:10E6D0009A420BD84A7803789A4207D38A78C3784B +:10E6E0009A4203D8C9788078814201D200207047CD +:10E6F0000120704770B50C788B784D78C9789AB145 +:10E700000CB1641EE4B2274A1278521E954201DA17 +:10E710006D1CEDB20BB15B1EDBB2234A1278521EA8 +:10E72000914201DA491CC9B203EB830200EBC20239 +:10E730000026293209E0204602E01654401CC0B2EF +:10E74000A842FAD95B1CDBB228328B42F3D970BDE8 +:10E750002DE9F0439C7893F803C004EB840500EBAB +:10E76000C505104890F8009004FB09F001EB400645 +:10E770000020293512E019785F7808E015F801804B +:10E78000904502D136F911804044491CC9B28F42EC +:10E79000F4D2641C06EB4906E4B22835A445EAD25B +:10E7A000BDE8F0837606100075061000A84310003F +:10E7B0002DE9F04780464A488C780D460078801E47 +:10E7C000012C05D9E978814202DA0020BDE8F08702 +:10E7D000022C01D2022701E0EF78C4B24FF0000909 +:10E7E0002146D8F808000AF0ADFE06462146D8F8C2 +:10E7F00004000AF0A7FE01463A48027815E028789E +:10E800006B780AE036F910C031F91080C44502D0A7 +:10E810004FF0010903E0401CC0B28342F2D2641CF5 +:10E8200006EB420601EB4201E4B2BC42E7D948469E +:10E83000CCE72DE9F04780462A480C464E7801780F +:10E84000891E8E4201DA0020C0E78146CFB24FF028 +:10E85000000AA178D8F808000AF074FE0546A178ED +:10E86000D8F804000AF06EFEA178E37899F8002049 +:10E8700013E03C460AE000BF35F914C030F91480BB +:10E88000C44502D04FF0010A02E0641CB442F3D93F +:10E8900005EB420500EB4200491C8B42E9D2504691 +:10E8A00094E70F4A00211278521ED3B290F8452007 +:10E8B0000AB19A4204D1818C41F002018184012184 +:10E8C000084A90F844301278521ED2B2934204D1D2 +:10E8D000818C41F0040181840121084670470000C9 +:10E8E00075061000760610002DE9F05F074600253A +:10E8F000DFF85CB42DE000BFDBF808104E5DDBF8FC +:10E90000041001EB450A1AE00AEB0600804610F8F5 +:10E91000011C10F8029C084600F00FFA0446484615 +:10E9200000F00BFA844202D2014620460C46DBF886 +:10E930000410761EF6B201F8104008F8024C012EC1 +:10E94000E2D804D1284600F0F8F98AF800006D1CDE +:10E95000EDB2BD42D0D300221146DBF804000DE039 +:10E9600000EB41031C788C4203D11A70521CD2B2C6 +:10E9700002E010F814401C70491CC9B2B942EFD330 +:10E9800000221346114608E010F811409C4202D0C4 +:10E99000521CD2B22346491CC9B2B942F4D3521C0C +:10E9A000D0B2BDE8F09F30B5B0B1884214D002D2E9 +:10E9B0000A4601461046E64A536803EB40031C78BA +:10E9C0008C4209D05C788C4206D095682A5C022A79 +:10E9D00002D2541C2C549954084630BDF0B503EBB8 +:10E9E0008204A57805EB850600EBC606E07828369C +:10E9F000A8420FD3207807E0371897F801C0944554 +:10EA000000D17970401CC0B267788742F4D26D1C87 +:10EA1000EDB2EBE703EB81002568056003EB4200F4 +:10EA200003EB410130F8B42FA1F8B420C9490968BB +:10EA300021600021018093F80E01401E83F80E0131 +:10EA4000F0BD2DE9FF4F88460846097887B0FF29B9 +:10EA500015D0C14A8A4641781278914201D2491CA8 +:10EA600000E01146CDB2BD4990F80290C078097817 +:10EA7000884201D2401C00E00846C6B204E04FF0D4 +:10EA8000000A5546D146564609984FF0000B08B18A +:10EA900098F80EB1AE4C206800F15A01C4E90101AA +:10EAA0005A210AF0BDFBD4E901122C20002301F801 +:10EAB00010001354401EC0B2F8D20BF101000390B5 +:10EAC000C0B20090079809EB890100EBC10709F17A +:10EAD0000100029743E000BF0AF101000197C4B2B0 +:10EAE000283738E03919086830B3385D30B3CF289B +:10EAF0002FD011F8011C002011B1CF2900D00846F9 +:10EB00000199095D19B1CF2901D0FFF74CFF0A998E +:10EB100081B101992144059111F8011C19B1CF2946 +:10EB200001D0FFF740FF0599497819B1CF2901D0ED +:10EB3000FFF739FF18B10BE0E41CE4B209E00098DC +:10EB40002D2803D2411CC9B2009101E0401EC0B281 +:10EB50003855641CE4B2AC42C4D90498401CC0B21D +:10EB60000490B042B8D90098FFF7BEFE0090039819 +:10EB70000022C0B2774B09E008EB80011C680C60F2 +:10EB800008EB4001401CA1F8B420C0B200998842B3 +:10EB9000F2D302984F46283001903BE0544632E0D1 +:10EBA000204401210958E9B3417851B3CF2928D035 +:10EBB000674A526812F81110417008EB410008EBE7 +:10EBC000810930F8B42F521C028099F800102046B9 +:10EBD00004F06BFC89F8000099F80110204604F05D +:10EBE00068FC89F8010099F80210384604F05DFCD1 +:10EBF00089F8020099F80310384604F05AFC89F8A5 +:10EC00000300641CE4B20198AC42C9D328307F1CD5 +:10EC1000FFB20190B742C1D30098401EC2B288F83B +:10EC20000E2100E00DE0099800280DD0A2EB0B00AA +:10EC3000012809D1099907980BB04346BDE8F04F68 +:10EC4000CCE6E41CE4B2DCE70BB0BDE8F08F2DE9C4 +:10EC5000FF4FAFB01C46012080463C9890F80E1143 +:10EC6000414544DBB82168460AF0FCFA3C996B4602 +:10EC700001EB880008F0FF0100682E902EAA309862 +:10EC8000FFF7EFFC80B32EA96846FFF783FC9DF8E1 +:10EC9000BA1031980AF05EFC82469DF8BA001EE078 +:10ECA00068469DF8B85000EBC90B10E0DBE900673F +:10ECB0002A46012000210AF0FDF906400F403E439C +:10ECC00004D01AF80500401C0AF805006D1C9DF8D8 +:10ECD000B900A842EADA0AF1280A09F101009DF810 +:10ECE000BB1081464945DBDA08F10100B4E7A178A1 +:10ECF00030980AF02FFC0546A1782F980AF02AFCDC +:10ED00000646A17831980AF025FCA278CF230FE0BF +:10ED1000217806E0475C022F02D36F5C07B9735479 +:10ED2000491C67788F42F5DA2830521C283528367E +:10ED3000E1789142ECDA33B087E7054AD2E9011273 +:10ED400002E000BF11F81000135C002BFAD17047ED +:10ED5000F0051000569501007606100075061000AB +:10ED6000F0B5B2F900400668B44202DDB3F9001014 +:10ED700030E002EB410434F9025CB54204DA03EB03 +:10ED8000410131F9021C25E000252C464F1E0CE004 +:10ED900032F914C0B44507DC02EB440CBCF902C0E4 +:10EDA000B44501DB25460C46641CBC42F0DB32F95D +:10EDB000154003EB450133F91530B1F9021002EBB0 +:10EDC0004502361BC91AB2F902207143121B91FB8E +:10EDD000F2F119440160F0BD2DE9F04105463748D4 +:10EDE000036893F80705C40603F20F5021D5B3F862 +:10EDF0007C696C68B4421CDBB3F87E69B44218DCF1 +:10EE0000B3F880692C68B44213DBB3F88269B4426A +:10EE10000FDC074693F8860993F8841993F887293D +:10EE200007EB400093F8854900EB410607EB420EE3 +:10EE300010E039B302292CD0032935D004293AD166 +:10EE400093F8081593F8094593F80E3500EB410641 +:10EE500000EB430E0A4422440EEB4107A02A2ADCB1 +:10EE6000012906DD05F1040C034672466046FFF7F2 +:10EE700077FF012C1FDD284633463A462146BDE880 +:10EE8000F0416DE793F8081593F8094593F80A25C2 +:10EE900005E093F8081593F8094593F80C2500EB65 +:10EEA000410600EB420ED5E793F8081593F80945A3 +:10EEB00093F80D25F3E7BDE8F0810000F40610009B +:10EEC00030B542780378CD8CD21AC3788078521C42 +:10EED0001B1A5B1C05FB02F0D4185D4340006A005E +:10EEE000B0FBF4F0B2FBF4F2904202D9C8850A8676 +:10EEF00030BDCA85088630BD2DE9FF4F002783B09D +:10EF00001546019700973E463C46BB4691780AF06D +:10EF100013FB8246AB7895F8039028E0297895F8A2 +:10EF200001C08E461DE000BF1AF8012004988242FD +:10EF300015D1A1EB0E02521CDDF80080A9EB0300F5 +:10EF400002FB0288401CCDF80080DDF804801644E6 +:10EF500002FB008200FB00BB04447F1C0192491CA1 +:10EF6000C9B28C45E0D25B1C0AF1280ADBB2994594 +:10EF7000D4D24FF47A70704390FBF7F14FF47A706B +:10EF8000604390FBF7F34FF47A7201FB04F0714396 +:10EF900090FBF2F791FBF2F6634393FBF2F30198D7 +:10EFA0000099C01B891BABEB0302069C8B1A00D592 +:10EFB0005B42002800DA404203EB400011440A188B +:10EFC000081A521040104FF47A71484390FBF2F047 +:10EFD000C0F57A70A085069907B02846BDE8F04FC5 +:10EFE0006EE700002DE9FF5F0025DDF838808B46D5 +:10EFF000994614462E462F46414600980AF0A2FA3A +:10F0000030F91900A04232DDA8F1010044B208F144 +:10F01000010828E0002C22DBB248007884421EDA86 +:10F02000E1B200980AF08EFAAF498246A9F10100D8 +:10F030000A7840B209F101010EE0002808DB904295 +:10F0400006DA3BF915303AF910C01F440CFB036691 +:10F050006D1C401CEDB240B28842EEDD01E0ED1CBB +:10F06000EDB2641C64B24445D4DD0FB101E0064644 +:10F07000012796FBF7F004B000B2BDE8F09F2DE940 +:10F08000FF4F83B091461099087800B1401EC4B27A +:10F09000887800B1401EDFF850A2C5B24A789AF8CD +:10F0A0000000431E9A4201DA501C00E0401EDFF8C7 +:10F0B00034B2C6B2C9789BF80000421E914201DA10 +:10F0C000481C00E0401EC7B2CCB9A84612E0014679 +:10F0D00003980AF045FACDE9008023464946069A8E +:10F0E0000498FFF77FFF019921F8140008F101004F +:10F0F00000F0FF084046B845E9D9641CE4B27A48FC +:10F100000078401E864219D1A84612E001460398B5 +:10F110000AF026FA82463346CDF800804946069A20 +:10F120000498FFF75FFF2AF8160008F1010000F0CD +:10F13000FF084046B845E9D9761EF6B2C5B929465A +:10F1400003980AF00DFA8246A0460CE003460095AB +:10F150004946069A0498FFF745FF2AF8180008F177 +:10F16000010000F0FF084046B045EFD96D1CEDB23C +:10F170009BF80000401E874218D1394603980AF0D8 +:10F18000EFF98246A0460CE0034600974946069AEE +:10F190000498FFF727FF2AF8180008F1010000F093 +:10F1A000FF084046B045EFD97F1EFFB2B9F9120003 +:10F1B0005FEA000A65D14FF0010A62E02946039830 +:10F1C0000AF0CEF90190681EC1B204980AF0BAF9AB +:10F1D0000090294604980AF0B5F921464DE000BF99 +:10F1E00030F91120069B9A4242DD009AB9F900805D +:10F1F00002EB4102002332F902CD0CFB0833B2F9D5 +:10F2000002C0B9F902800CFB0833B2F904C0B9F9A5 +:10F2100004800CFB083B344BB9F9068093F800E0FE +:10F2200002EB4E02B2F900C00CFB08B3B2F902C007 +:10F23000B9F908800CFB0833B2F904C0B9F90A80A7 +:10F2400002EB4E020CFB083BB2F900C0B9F90C808E +:10F250000CFB08B3B2F902C0B9F90E800CFB0833FD +:10F26000B2F904C0B9F910200CFB023292FBFAF299 +:10F27000019B23F81120491CC9B2B142B0D96D1CC1 +:10F28000EDB2BD429AD907B0BDE8F08F1CB5174C5E +:10F290002468019401AC0094FFF7F1FE1CBD38B561 +:10F2A000164D009012480C46124A0068B0F9E2323E +:10F2B000114801682868FFF7E2FE2868A06038BDA1 +:10F2C00038B50E4D00900A480C460A4A0068143AB8 +:10F2D000B0F9E232084801682868FFF7D0FE2868D4 +:10F2E000606038BD75061000760610002406100018 +:10F2F000F40610004295010098061000E805100081 +:10F300002DE9FF5F8946144691780F9D0AF014F9A4 +:10F310008246A178A8680AF015F947F6FF76A77823 +:10F32000F543FE4994F8038091F800B018E0227884 +:10F3300094F801C00DE000BF1AF80210494507D14A +:10F3400030F91230B34200DA1E46AB4200DD1D46F2 +:10F35000521C9445F0D20AF1280A00EB4B007F1CA6 +:10F36000B845E4D2039806800E980580BDE8FF9F5B +:10F370002DE9FF4FEA4885B09A46046803A9CDE914 +:10F38000001ADDE90501154604F5887902ABFFF79F +:10F39000B7FFE448BDF90C20DFF88CB300685F4686 +:10F3A00090F8E412BDF90800121A4A43642192FB56 +:10F3B000F1F10E1801222946DBF80000FFF79AF957 +:10F3C000D7F80080DDE9050731B20191A9780AF08C +:10F3D000B3F80646A97840460AF0BCF80090A97830 +:10F3E000DAF808000AF0AEF80146AA780123DFF83F +:10F3F0002CE31DE028780EE016F800C0BC4509D1CA +:10F4000031F91080DDF804C0E04503DDDDF800C00F +:10F410000CF80030401C95F801C08445ECD20098EF +:10F42000521C283000909EF80000283601EB400165 +:10F43000E8789042DED2002084F80E01286820602F +:10F440000123002221465E46DBF80000FFF7F9FAAF +:10F4500094F80E01012826D901251DE054225146B9 +:10F46000484609F0A3FE04EB450004EB8507B0F81D +:10F47000B410A9F8261049463846FFF721FD3A4650 +:10F48000E9B24B463068FEF775F93A46E9B24B46A9 +:10F490003068FEF7ABF86D1C94F80E01A842DDD27F +:10F4A00009B0BDE8F08FDDE9050153462A46FEF7B5 +:10F4B0009DF8F5E72DE9FE4F06469A481D460B4696 +:10F4C00000689A490E9CB0F9E6928979934609B191 +:10F4D000B0F962939649097809B1B0F9F4921846E7 +:10F4E0000C990AF029F8824630460C990AF032F855 +:10F4F0000190A0680C990AF025F82C786D78804668 +:10F5000064B99AF80010594507D1B8F900100D9860 +:10F51000814202DD01990120087001247F480078B2 +:10F52000401E854255D11AF80510594507D138F9C2 +:10F5300015100D98814202DD0199012048556D1E7C +:10F54000EDB246E01AF80410594541D138F91410CB +:10F550000D98029181423BDD0020009075490C9886 +:10F56000224601EBC0000021D0E90067012009F02C +:10F57000A1FD06400F403E4327D1029808EB44020C +:10F58000484432F9021C00B2814205DDB2F9023072 +:10F59000834201DD01230093012C09D932F9043C97 +:10F5A000834205DDB2F90230834201DD012300937D +:10F5B0005A4B1B789B1E9C4205D2814203DDB2F957 +:10F5C0000410814204DC009810B90199012008550B +:10F5D000641CAC42B6D9BDE8FE8F2DE9FF4F5448FC +:10F5E0009BB0DFF848B101784E48289E1D46006860 +:10F5F00031B190F8F342B0F9F4A2B0F9F60225E087 +:10F600009BF8061031B190F86843B0F962A3B0F9E5 +:10F6100064031BE0484990F8E542B0F9E6A2097896 +:10F62000B0F9E892012912D190F8FB120C4490F83D +:10F63000FC12514503DAAAEB01010FFA81FA90F8A6 +:10F64000FD02484503DAA9EB000000B281463B4FBA +:10F65000ACB104A8CDE90006DDE91C0102AB2A46E5 +:10F66000FFF74EFEBDF91000BDF90810401A6043C7 +:10F67000642190FBF1F03988084400B201E0B7F949 +:10F6800000000390AC7895F8038054B903981BAF41 +:10F69000CDE90040029697E807002B46FFF70AFFE6 +:10F6A000012427480078401E80450ED10399CDF8EB +:10F6B0000080CDE901161BAF2B4697E80700FFF746 +:10F6C000F9FEA8F1010000F0FF08601EC1B2B068A9 +:10F6D00009F038FF0D90012C04D9A01EC1B2B0680A +:10F6E00009F030FF06902146B06809F02BFF0C901E +:10F6F000601CC1B2B06809F025FF0A90A01CC1B21D +:10F70000B06809F01FFF019021461C9809F014FF12 +:10F710000F9021461B9809F01DFF13E0760610009C +:10F72000FC051000F4061000E4051000A806100007 +:10F730004005100000431000B00610002E06100017 +:10F74000750610000E9000201490012013900020E8 +:10F7500012909BF80400C0B1FE48006890F8401475 +:10F76000090712D569782A78891A90F84B24491C20 +:10F7700091420ADCE978AB78C91A491C914204DC51 +:10F78000B0F84904B169814201DD00201390A3461D +:10F79000F0E02C78CFE00F98015D1D98814268D190 +:10F7A00000200B90EC491690159001EBCB002246FF +:10F7B000D0E900760120002109F07CFC07400E40D2 +:10F7C00037437DD10C9830F8142002EB0A0002EB8D +:10F7D00009010D9A00B209B232F91420824207DD04 +:10F7E0000A9B33F91430834202DD01230B931593F6 +:10F7F000F4B3DA4B93F800E0AEF101039C4269D018 +:10F800000C9B03EB440C3CF9026C864206DDBCF910 +:10F810000230834202DD01230B9316930D9B03EB11 +:10F82000440333F9027C8F4208DD0A9F07EB44074B +:10F83000B7F902708F4201DD01270B97B3F902304F +:10F840008B4206DD0A9B03EB440333F9023C8B42F7 +:10F850004CDC0B99A9BBBBF1010F0FD9069931F90B +:10F86000141081420ADD0A9931F91410814201E035 +:10F8700030E05FE002DD01210B911591B84B1B7860 +:10F880009B1E9B4509D2824207DD019931F9141074 +:10F89000814202DD01210B911591012C0AD93CF91D +:10F8A000041C814206DDBCF90210814202DD012107 +:10F8B0000B911691AEF102018C420BD2864201E00F +:10F8C0000AE013E006DDBCF90410814202DD0120EC +:10F8D00016900BE00B9848B90C9830F91410039867 +:10F8E000814203DD0E980121015523E09949086802 +:10F8F00090F8DF02000708D50C9830F9142003981F +:10F90000824202DD0E98CF220255169890B11598CA +:10F9100080B1139870B10E9A012010551298401CB6 +:10F9200080B21290086890F84C141298814201D26B +:10F9300001201490641C6878A042BFF42CAF874863 +:10F940000D99069100780BF1010B01EB40010D912F +:10F950000C9901EB40010C910A9901EB40010A91CD +:10F96000019901EB400001900F9828300F900E98FC +:10F9700028300E90C3457FF60CAF14981FB090E569 +:10F980002DE9F0470446914260D007D901EB02000F +:10F99000A0EB0201CAB2A0EB0200C1B2C1EBC100F0 +:10F9A00000EB400004EB8001C2EBC20000EB400022 +:10F9B00004EB8000B1F93250B0F9323081469D42FB +:10F9C00000DA4B86CB8CC58C2B44CB840B8D058DFC +:10F9D0002B440B854B8D458D2B444B858B6985695D +:10F9E0002B448B61C769CE69CB68D9F80C004FEA0C +:10F9F000234C4FEA20480CFB06FCF51907FB08CC0A +:10FA00009CFBF5FC6CF31F430FFA83FC0CFB06FC1C +:10FA100000B207FB00C090FBF5F060F30F03CD616F +:10FA2000CB6094F8EC04411E91420AD0C0EBC000B8 +:10FA300000EB400004EB800148465422543909F0A1 +:10FA4000B5FB94F8EC04401E84F8EC04BDE8F087A4 +:10FA50002DE9FE4F07463F488A4600250068B0F86A +:10FA6000EA1201FB01F93F49897919B1B0F866033F +:10FA700000FB00F954464FF0010BAEE00BFA04F026 +:10FA80002646009077E0009A0BFA06F0594610429D +:10FA900070D0C6EBC60000EB400007EB8000C268E8 +:10FAA00020464EE0B0424BD0C0EBC00303EB430313 +:10FAB00007EB8303DB684FEA234CACEB224C9B1A29 +:10FAC0000FFA8CFC1BB26CF31F4563F30F059E46C7 +:10FAD000204BCDF804C01B6893F8DEC2CDF808C0F7 +:10FAE0005FEA8C6C0AD593F8ED820EFB08FC4FF0B0 +:10FAF00064089CFBF8FCF4446CF30F05DDF808C0C7 +:10FB00005FEACC6C0CD593F8ED32DDF804C00CFB49 +:10FB100003FC64239CFBF3FC019B634463F31F45DC +:10FB20004FEA254C0CFB0CFC2BB203FB03C34B45EB +:10FB300006D2DDF800C001FA00F343EA0C0300939B +:10FB4000401C97F8EC348342ACD80421684608F096 +:10FB5000C5F80AE0F4061000004310007606100015 +:10FB600075061000A806100004E0012802D10098D4 +:10FB700040000090761C97F8EC04B04283D8042132 +:10FB8000684608F0ABF801280BD00421684608F05D +:10FB9000A5F897F8EC64A6EB0A01884205D187F82E +:10FBA000ECA418E5641CE4B201E0009A584600FA9F +:10FBB00004F11142F6D0D8460AE000BF009908FAD5 +:10FBC00006F0084204D0F2B221463846FFF7D8FECC +:10FBD000761EA642F2D8641CE4B297F8EC04A04268 +:10FBE0003FF64CAFF7E42DE9F04FFE4C012B2468B3 +:10FBF00094F8F97294F8F86205D00B784C78FA4DC5 +:10FC00009C46690C0CE08B78CC78F8E730F91C80C6 +:10FC1000A84500DD4546884500DA41460CF1010C57 +:10FC2000A445F3D9B54200DA3546B14200DA31468F +:10FC3000691A7943642591FBF5F131440EB230F92C +:10FC400013500121B54205DD156801FA03FC45EAB0 +:10FC50000C05156030F91450B54205DD156801FA40 +:10FC600004FC45EA0C051560E51A05F0FF09B9F139 +:10FC7000010F37D95D1CEDB230F9158008EB070C88 +:10FC80000FFA8CFCB04511DD00EB450A3AF9028C05 +:10FC9000E04503DDBAF90280E04507DCD2F800C098 +:10FCA00001FA05F54CEA050CC2F800C0651EEDB27C +:10FCB00030F9158008EB070C0FFA8CFCB04511DD0C +:10FCC00000EB450A3AF9028CE04503DDBAF90280FF +:10FCD000E04507DCD2F800C001FA05F54CEA050C56 +:10FCE000C2F800C0B9F1020F2ED99D1CA4F102097F +:10FCF00028E000BF30F915C0B44522DD00EB450B0C +:10FD0000BC443BF902EC0FFA8CFAD64503DDBBF993 +:10FD10000280D04515DC3BF9048CD04503DDBBF9EE +:10FD20000280D0450DDCD64503DDBBF90480D0450B +:10FD300007DCD2F800C001FA05F84CEA080CC2F85A +:10FD400000C06D1C4D45D5D9002528460CE000BFEC +:10FD5000166801FA03F73E4204D025B90125401C7C +:10FD6000C0B200E000255B1CA342F1D9BDE8F08FD2 +:10FD70002DE9FF4F9D488FB0DFF8749204684FF073 +:10FD8000FF300C90002017460A900B901D4604F59A +:10FD9000887B012239464E46D9F80000FEF7AAFCBE +:10FDA0000095DDE90F123B463068FFF716FC0600B0 +:10FDB00006D0904901200870A88C40F08000A884EB +:10FDC0008D48007880B17EB995F8240010F0060FB8 +:10FDD0000AD139462846FEF7EBFC060004D1394625 +:10FDE0002846FEF726FD06468448007800B1012625 +:10FDF000DFF8F0A1DAF8000090F8DF0240073ED506 +:10FE000001230AAA39467E48FFF7EDFE804600230B +:10FE10000BAA39467B48FFF7E6FE08FB00F00128F5 +:10FE20002DD1DAF80000B5F93210B0F8E0028142C5 +:10FE300025DAB8781FE000BF08F0FF010F9809F03D +:10FE400089FB049008F0FF01D9F8000009F082FB5B +:10FE500001463878012209E0049BDDF840C01B5CB4 +:10FE6000634502D10B5C03B90A54401C7B78834282 +:10FE7000F2DA08F10100F97880464145DCDA002029 +:10FE800084F80E0138682060594833460022214624 +:10FE90000068FEF7D6FD94F80E014FF00008012827 +:10FEA00070D95048006890F8DF0200070CD54FF475 +:10FEB0006671554809F0D6F94D4800943B460168F3 +:10FEC000514A0846FEF7C3FEFBF741FE0090FBF7E0 +:10FED0003CFE82463A68DDE90F0107924B4B07AAC8 +:10FEE000FEF7BFFB60B107A94848FEF753FB2A465F +:10FEF00007A94648FCF7A6FFE9686961E969296234 +:10FF00003E480078E8B33748006890F8DF02800781 +:10FF100047D594F80E01012843D94FF00009012676 +:10FF200010E000BF324804EB8603F2B2A968006813 +:10FF3000FEF70EFC34493C39484541F8260000DD07 +:10FF40008146761C94F80E11B142EBD2B9F1000F44 +:10FF500020DD244A01202C4B86463C3B126817E0EA +:10FF600053F820604FF0640C06FB0CF696FBF9F694 +:10FF700092F8F2C2B4450ADD0EFA00F6DDF830C0A0 +:10FF800001E00EE0E6E02CEA060CCDF830C0401CA3 +:10FF90008142E5D294F80E01012802D9002084F8AC +:10FFA0000E011B481C4A0126B0F9001019480591A2 +:10FFB000DFF83090B0F900000890118017490880F0 +:10FFC0008FE054222946584609F0F0F8D9F800107D +:10FFD00004EB4600B0F8B43091F8EC2293427FD99C +:10FFE00001221DE0F40610000080FFFFFC05100058 +:10FFF000E4051000C505100044061000400510007F +:020000021000EC +:10000000F00C01201A0D01209C44100058421000F1 +:100010003E0610003C061000300610002E061000B0 +:100020000C9BB2401A425BD0BBF8242042F0100374 +:10003000ABF82430B0F8B420ABF8262091F8DF02FA +:10004000000703D599480168CBF8001004EB86003F +:10005000099059460790FEF733FF9448F1B25B468A +:10006000079A0068FDF786FB9BF8440060B1904951 +:100070000978491E884207D09BF8450020B18D4978 +:100080000978491E88420FD1BBF8240040F00101D5 +:100090005846ABF82410FEF704FC28B1864887497F +:1000A00000880880864908808548BBF93210B0F97D +:1000B000000081420CDD7D48F1B25B46099A006880 +:1000C000FDF794FA012803D108F1010000F0FF08C0 +:1000D0007A49059808807A49089800E000E008808D +:1000E000761C94F80E01B042BFF46BAFD9F8000053 +:1000F0004C4690F8DE0200070DD5B8F1010F0AD981 +:1001000050460099FFF7A4FCFBF721FD014600983B +:10011000081A00F0FF08216891F8DE02000613D5E6 +:1001200040460FE0009A0244D2B2C2EBC20202EB98 +:1001300042030AEB830291F80F33D28C9A4201D921 +:10014000009817E0401EEDD2B8F1010F0AD0B8F1C7 +:10015000000F05D1DDE90F012B463A46FDF746FABF +:1001600013B003E6574800780028F9D19AF8EC0458 +:1001700000B1401E8AF8EC04ECE72DE9FF4F52482D +:1001800081B0006890F8DF02C00767D0A82104980A +:1001900009F068F8012544E0039800EB85008246E9 +:1001A000847890F8039043480078401E844201DA36 +:1001B000641CE4B2B9F1000F03D0A9F1010000F012 +:1001C000FF092146019809F0B7F98346A04624E0CB +:1001D0000398049910F8254001EBC800009012E044 +:1001E0001BF80400A8420CD1009822460021D0E957 +:1001F0000067012008F05EFF064300980F43C0E946 +:100200000067641CE4B29AF80100A042E8D208F149 +:1002100001000BF1280B00F0FF08C845D8D96D1C70 +:10022000EDB202988542B7D90021224E13E004981E +:1002300000EBC10501F10101D5E90032DC1842EB08 +:10024000020052084FEA330304EA030400EA020002 +:10025000C5E90040C9B230788142E8D305B085E5F0 +:10026000F0B414681C64184C256895F8DE42A607A3 +:1002700013D493F84A60012E0FD0660713D5640695 +:1002800009D5124C64785CB1B5F8F042104D644366 +:100290002D68A54207DCF0BC6AE5F0BCFFF768B842 +:1002A000B5F8EE42F2E7F0BCFDF7A0B9E4051000A6 +:1002B0007606100075061000420610003006100089 +:1002C0002E06100040051000F4061000280710004C +:1002D000B40610007047F0B51446059F0BE000BF50 +:1002E00031F9145030F9146005EB030CB44519DBF7 +:1002F000ED1BB54216DC641EF2D1BD4B1B6893F8B2 +:1003000045301B09C3F110040AE000BF31F9125057 +:1003100030F912605D4306FB04552D1121F812508F +:10032000521EF3D2F0BDF0B51446059F0BE000BF9E +:1003300031F9145030F9146005EB030CB44519DBA6 +:10034000ED1BB54216DC641EF2D1A94B1B6893F875 +:10035000683003F00F03C3F1100409E031F91250C3 +:1003600030F912605D4306FB04552D1121F812503F +:10037000521EF3D2F0BD2DE9F8430E46054601F0BA +:1003800089F9002844D1F00704D09A4928680968FF +:1003900000F0F2F8984FDFF86482954CF00616D51D +:1003A0002068B0F950100091B0F94E303A78944975 +:1003B0002869FFF790FF2068B0F954100091B0F958 +:1003C000523098F800208F496869FFF784FF206851 +:1003D00090F8401089071BD4310719D58A4909784C +:1003E000002915D1B0F962100091B0F960303A7867 +:1003F0008649A86BFFF797FF2068B0F96610009157 +:10040000B0F9643098F800208149E86BFFF78BFF62 +:10041000BDE8F8837F4A10B512780024022A05D07F +:10042000080706D501F036F910B102E0000700D543 +:100430000124204610BD2DE9FF4F7749DDE90D94D9 +:10044000D1E90156864693460020694FDDF83CC04D +:1004500028E000BF39F8101034F91030C91A0AB278 +:100460000021002A0EDAC2F100083A689246B2F87A +:100470007620904502DDBAF8781001E076B901994E +:10048000494207E055B90FFA8EF15A4506DD039946 +:100490008A4201DD09B201E00FFA8BF1194424F818 +:1004A0001010401C6045D5DBBDE8FF8F2DE9FE43F1 +:1004B00002465A488846002103785748012B00D14C +:1004C0000180544B1C784A4B022C1B682ED0446888 +:1004D000641C446093F86A50B4EB151F00DD416062 +:1004E000846805F00F05641C8460A54200DA816011 +:1004F00093F87040210710D093F8715001888D4215 +:100500000BD9491C018093F86B1004F00F000D0902 +:10051000454301F00F04444304E093F86B000509E0 +:1005200000F00F0433F8726F5F880AE04160816069 +:1005300093F86900B3F86C60B3F86E70050900F0C9 +:100540000F042D4831493B460078CDE90021029047 +:10055000324621462846FFF76EFF28482C4A3B4684 +:100560000178CDF80080CDE90121324621462846A8 +:10057000FFF761FFBDE8FE832DE9F043814628487F +:1005800003781B48052B006890F844200DD030F903 +:10059000465F02F00F03B0F9026000BF2148C3F1CB +:1005A0001004B0F90000024611E030F94A5F130967 +:1005B000B0F90260F2E700BF31F9127039F912C0E8 +:1005C00007EB0508E04511DBBF1B67450EDC521E3B +:1005D000F2D209E031F9102039F910505A4305FBE5 +:1005E0000422121121F81020401EF3D2BDE8F0833E +:1005F000F4061000A4061000750610007606100020 +:100600000C72012036720120FC041000827201205D +:10061000AC720120E8041000000610002E07100044 +:1006200074061000860610002DE9FC4781469A48A2 +:100630009A4E884601783068012511B998490978A1 +:1006400011B1B0F991420DE09649B0F98B42497869 +:10065000012902D0022903D004E0B0F98D4201E063 +:10066000B0F98F42022101A800F0C0FA8E4F424635 +:100670004946B7F90030019803F00BFF316891F853 +:100680009E02020705D4C00603D491F89F02C0075A +:1006900008D0B7F90000019900908023834A0846EA +:1006A00003F004FFB7F90010019A0CE032F91100D1 +:1006B000002801DB034600E04342A34203DD7C49FE +:1006C0000025088001E0491EF0D2022101A800F0B7 +:1006D000F0FA2846BDE8FC877048006890F8800270 +:1006E000400707D56F487349C0780978884201D020 +:1006F0000120704700207047684810B5006890F8E6 +:100700008012890727D56C490A78521CD2B20A7028 +:1007100090F8823293421ED200220A7090F8501252 +:100720000324C90703D190F81E0AC00700D00B2488 +:10073000EFF764FE6148016821430160EFF75CFE5A +:100740001021052002F088FABDE810404FF48071B6 +:10075000002006F0D4BC10BD4F49514A51480978D9 +:100760001278437811430B4353494FF0000208D1EC +:100770004B785B1CDBB24B70052B03D90123437014 +:1007800083704A7070472DE9F34F4D480027DFF81A +:1007900018A190F80080414881B03C460068B946F5 +:1007A00090F88002C0071AD000264FF0010B019D7F +:1007B00012E028460299FFF737FF10F0010F05D02D +:1007C0000BFA06F03843641CC7B2E4B2BAF9000071 +:1007D000761C05EB400536B24645EADB01E04446AF +:1007E000FF27384807704CB10094BAF800003B4628 +:1007F00082B24146019800F012F807E02C48B0F9A7 +:100800000010032002F028FA4FF001094846BDE825 +:10081000FE8F7047284800210170417070472DE914 +:10082000F003069F002F19D00125012F02D0144696 +:10083000A9462EE000240FE005FA04F61E420AD075 +:10084000002C0BD053006243BDE8F00300EB4201E3 +:100850001A4608F066BC641C8C42EDDBBDE8F00370 +:10086000704700BF002600EB440C35460BE000BF8C +:1008700009FA05F818EA030F02D0BCF900804644D3 +:100880000CEB420C6D1C8D42F2DB96FBF7F520F869 +:100890001450641EE6D2E1E734051000F40610009F +:1008A000400510002807100086061000E213012002 +:1008B00016061000770610000C0610000007100046 +:1008C000780610001106100010B5F5F7D3F8F5F70B +:1008D00042FEBDE81040F4F719BA2DE9FF5F9B46D0 +:1008E0008A460320DDF8388006F0A9FC8E480168AE +:1008F0000098FFF748FF0446032006F0BBFC6CB1EC +:10090000FFF72AFFFFF7F8FE51460098FFF781FF37 +:100910008648047004B02046BDE8F09FFFF77AFFD8 +:10092000BAF1000001D000F02BFCDFF804920025A2 +:10093000804F814EB8F1000F0ED0804801784046BC +:10094000F5F7BFF8B87838B1D9F8000090F86E0321 +:10095000C00701D13570757008F0A8FD8046FFF71B +:10096000BBFE40EA0804D9F8000090F84003C00735 +:1009700008D00120F070B87808B9787810B17048C4 +:10098000F5700570002CBFD15A460299009800F00E +:100990003EF80446B8E710B5044600F086F800219A +:1009A0002046FFF736FF002010BD10B5F6F7A8FD72 +:1009B000FDF7D2FCFAF756FFFFF786FFFFF72AFF95 +:1009C000FCF75DF859490020087048708880C8809D +:1009D00088708860C8600861143108708870544855 +:1009E000006810F8302F4A704078C87010BD10B5FC +:1009F000F6F794FDFDF7C4FCFAF732FF00F057FC60 +:100A0000F5F7B6FD4B4800214170817010BD2DE90E +:100A1000F8430024804616460F4625468DF80040D0 +:100A2000022006F00CFC324639464046F6F7DFFB62 +:100A300044490128CA7860F30302CA7029D0022809 +:100A40002ED0042800D001246B4632463946404659 +:100A5000FBF7B8FE40EA0405022006F00BFC9DF807 +:100A6000000098B1EFF7CAFC3748384A01681268AD +:100A700011430160EFF7C0FC35480178052002F012 +:100A8000EBF84FF48071002006F039FB2846BDE8F2 +:100A9000F88330480570FDF74AFCFAF702FFD3E708 +:100AA000FDF7A5F8FAF728FFCEE738B50446002091 +:100AB0008DF80000022006F0C2FB2046F6F78CFC01 +:100AC00020490128CA7860F30302CA7002D00228C4 +:100AD00005D008E0FDF73FFCFAF785FF03E0FDF7DE +:100AE000B4FAFAF791FF69462046FBF782FF044605 +:100AF000022006F0BFFB9DF8000098B1EFF77EFCE6 +:100B00001148124A0168126811430160EFF774FC42 +:100B10000F480178052002F09FF84FF48071002003 +:100B200006F0EDFA204638BDA406100010061000AD +:100B3000F406100028071000A80610002C0710006B +:100B40007F0610007C58012000071000BC05100033 +:100B5000B80510003A071000062904D28B4A515CF0 +:100B60008B4A535C2BB1002101600146482001F003 +:100B70002EBD864B083353F821300360854B43F874 +:100B800021000120505470470A4630B40021062A43 +:100B900011D27E4B9A5C72B17C4C0368083454F8D5 +:100BA0002240A34207D17A4B99547A4B43F8221042 +:100BB000016030BC70470160014630BC492001F043 +:100BC00006BD2DE9F0410124714D724F0026285DCC +:100BD00038B12E5557F824104A2001F0F8FC47F898 +:100BE0002460641C032CF2DBBDE8F0812DE9F041A8 +:100BF000684D674B00270A460C350760596805F1B8 +:100C0000140603F10804012A38D0022A1CD0032A52 +:100C10003FD1002204EB020CDCF800E0BEF1000F33 +:100C200007D0521C022AF5DB042930D301464C20A0 +:100C300031E055F82240046046F822004FF00330BE +:100C4000091FCCF8000032E05FF0000204EB020C58 +:100C5000BCF800E0BEF1000F05D0521C042AF5DB01 +:100C60000229E3D213E055F82240046046F822003E +:100C700040F20220ACF80000891E18E05FF0040288 +:100C800014F802C0BCF1000F09D0521EF8D2002F98 +:100C9000AAD101464B20BDE8F04101F098BC55F8BF +:100CA0002250056046F822000120A054491E5960D8 +:100CB0009AE7F0B4374E364C002504220C36D0F8B3 +:100CC0000030083456F822709F4212D1A75C8F4240 +:100CD0000FD1531C11D02F4D00232035036045F850 +:100CE0002230A354012911D0022911D0032904D1A3 +:100CF00008E0521EE6D2002D08D1F0BC01464D207E +:100D000001F065BCA01843708370C370F0BC7047DD +:100D1000A0184370FAE770B51D4E1E4D0524083625 +:100D200020350BE0305D48B155F824104E2001F01D +:100D30004EFC315D55F82400FFF7BBFF641EF1D275 +:100D400070BD70B50120134B114A002143F82010EB +:100D50001154401C0328F9DB012010700C4A0520B7 +:100D60000C4B50600C330A4C04200B4A083403F13E +:100D700014057326464302EBC60643F8206021544F +:100D800045F82010401EF4D270BD00005C950100B3 +:100D900050061000E44E1000D4611000F0B5A7B06A +:100DA0000D46064600249821684608F05BFAFF4A83 +:100DB00000216846137810E001FB03F7224609E0A2 +:100DC00007EB020E50F822C036F91EE0F44440F85A +:100DD00022C0521C9A42F3DB491CA942ECDB21469B +:100DE00007E000BF50F8212092FBF5F240F82120E7 +:100DF000491C9942F6DB002117E000273A460CE037 +:100E000002FB034C50F824E036F91CC0BCEB0E0C7E +:100E100001D5CCF1000C6744521CAA42F0DB97FBD1 +:100E2000F5F28A4200DD1146641C9C42E5DBB1F517 +:100E3000803F03DB4FF6FF7027B0F0BD88B2FBE7C1 +:100E4000F0B5DB49DB4B096891F89E22D20734D01C +:100E5000D94A57784FB191F8B542B1F8B25204F07F +:100E60000F022609B1F8B04208E091F8B442B1F897 +:100E7000AE5204F00F022609B1F8AC42DFF83CC3D1 +:100E80009CF800C0BCF1030F06D191F8B6120FB167 +:100E90000A0901E001F00F02A04201DC1A60F0BD76 +:100EA000A84201DB1E60F0BD001BB11A4843291B9C +:100EB00090FBF1F010441860F0BD0020FBE7BC4847 +:100EC000BD4900680A7800F5F970805CC870704709 +:100ED0002DE9F00FDFF8E0A28346B5489AF80070DC +:100EE00089466FF0004231F817500168002091F8F0 +:100EF0000A6291F809124FEA11180B071FD001F08E +:100F00000F0CAB4C00210B462468B54294F8084204 +:100F100005DBAE1B06FB08F696FBFCF63444A44E3C +:100F20009AF801C0D0463668BCF1010F96F8F1611D +:100F300008D0BCF1020F08D006F0030C12E04FF00D +:100F4000010CDEE7C6F3810C0CE0C6F3011C09E0DE +:100F500039F81360B24201DD32461846B14200DA78 +:100F600031465B1C6345F3DDABF80010A91AA142C2 +:100F700001DC674504DD88F80000BDE8F00F9EE75E +:100F8000BDE8F00F70478E4910B50B7888490022F4 +:100F9000012B096802D18B4B1B784BB1B1F8FC31A6 +:100FA000834218D291F8F0311B0714D5032225E0B3 +:100FB000B1F80232834203D291F8F0311B07F5D425 +:100FC000B1F80032834203D291F8F0315B070AD4C2 +:100FD000B1F8FE310BE0B1F8FA31834205D291F855 +:100FE000F0315B0701D5022208E0B1F8F831834205 +:100FF00004D291F8F001800700D5012272486E4CAE +:1010000003789A4211D1617899421AD06F4A1278C6 +:10101000134307D08168491E8160002911DC0078E4 +:1010200060700EE001708168F7E78AB1022A01D191 +:10103000012B0DD091F8F61181600270002900DCBF +:10104000627063486278417B62F30301417310BDB3 +:1010500091F8F711F0E7564A126892F8F021D2069B +:1010600007D5421A002A04DCC1EBC1110844C0F3C1 +:10107000CF107047504900204D4A4870524948608F +:1010800088600870126892F89E32DB0703D092F8ED +:10109000B522120900E00022464B1A60C8600861C0 +:1010A0004C49086048608860C86070472DE9F05F6F +:1010B0008B463E49DFF810914FF0100A0E78054636 +:1010C0003701002409F10C09DFF8FC8013E03246F7 +:1010D00051462846FFF762FE29F81400BBF1010FC4 +:1010E0000FD03C4B33F81410FFF7B5FF23F8140072 +:1010F00005EB4705641C98F801008442E7DDBDE874 +:10110000F09F344B0833EDE738B5294C0020ADF89B +:10111000000020684FF0000190F8F00180062D4893 +:1011200000F1100008D5FFF7C1FF01212A48FFF7A1 +:10113000BDFF2849083102E0FFF7B8FF254968469E +:10114000FFF7C6FE20681C4D90F8F001400602D55E +:10115000BDF8004003E028781E4931F810401F48D0 +:1011600004802046FFF70FFF2046FFF769FE16496F +:1011700028780C3131F810001549A1F81B0038BD52 +:101180002DE9F14F84B00020029008481026057820 +:101190000D484FEA0518406890FBF6F106FB110078 +:1011A0000C496843103101EB400A19E07606100043 +:1011B000F40610003806100028071000740610000E +:1011C0007D0610007E061000600610007C061000F0 +:1011D0007C580120881E012098310120140610003F +:1011E0008B464049049C096891F8F011890615D591 +:1011F0000BF5985101EB40093B48477868007F1C8C +:10120000009008E021464846009A07F08AFF04EB68 +:10121000450409EB48097F1EF4D2049CDFF8C8900E +:1012200099F801707F1C24E02E48006890F8F011B6 +:10123000890615D5D9F8041000290FDD02996A1A1C +:10124000B0F90612CDE90012B0F9043202980BEBA6 +:10125000400204EB4001084603F0A2F80BEB480BF8 +:101260006A002146504607F05CFF04EB45040AEB98 +:10127000480A7F1ED8D2D9F804104FF0FF32491C1B +:1012800002EB46024846C9F804108A4200DA46607A +:10129000D9F80400B04206DB05B01449BDE8F04FB0 +:1012A000A1F5985030E705B0BDE8F08FE2E610B543 +:1012B0000C4C206890F8F101C0F30112C0F38101D9 +:1012C00000F0030002F0EAF8074948702068084976 +:1012D00090F8EB0000F003000870FFF7F0FDBDE8A8 +:1012E0001040C7E6F4061000600610009831012097 +:1012F0002807100010B5FF4800248461446384630C +:101300000462C461FFF773FBFFF71BFDFA4804801A +:10131000BDE8104000F023BAF0B5F849F548FA4F9F +:1013200091F83020427091F8313083705A4316B2F0 +:10133000468291F83340C47011F82C2F02704A781D +:1013400002718A784271C9788171ED49416201F276 +:101350003C618162A1F67841C162EA490B6893F869 +:10136000F01109061AD503F5F97593F8F131002249 +:1013700003F0030311465B1C08E000BF15F801C031 +:10138000A44501D10A4603E0491CC9B28B42F5D8F5 +:10139000C271724307EB42010163F0BD0763F0BD08 +:1013A000D64810B590F82C10D348D24A8170137AE1 +:1013B000017963F30001937A63F3C301537A63F312 +:1013C0008201D37A63F34101137B63F30411CF4BA2 +:1013D000DB780372937BC371537BD47B63F345113A +:1013E000837B127C64F3030362F30713C84A83739D +:1013F000127880F82820C74A1288A0F82920C64A07 +:10140000137890F85B2063F3410280F85B20C34AB5 +:10141000127862F3C7110171C1490988A0F82B1035 +:10142000C0490988A0F82D10BF490A78C17B62F332 +:101430000301C173BD490A78017C62F30001BC4A13 +:10144000127862F34101BB4A127862F3C30121F0C2 +:1014500004010174B8490A88A0F84020B74A1388EB +:1014600003874B88A0F84230538843878B88A0F8C5 +:10147000443093888387C988A0F84610D188C187F3 +:10148000AF49097880F8941010BD70B50D4680EA18 +:101490000506F00601D5F5F75EF8964CC5F3001089 +:1014A00034342070B00601D5F3F730FCC5F340109A +:1014B000607015F0480000D00120A07191480068CC +:1014C00090F8400400F001002071C5F30020E071A5 +:1014D000C5F34000E07070BD70B5864E874CD6E90C +:1014E00007010143D4E9080240EA020081EA00054D +:1014F00003D110B1FFF7FEFE12E0E9070CD09149CD +:101500000A78012A04D100220A7008B9FAF738FAD9 +:10151000FFF74BFAFFF7CAFEE80601D5FFF7D4F94B +:10152000E169B069FFF7B1FFE069B061206A30623C +:10153000606AF061BDE87040EEE670B5824D2C68DF +:10154000002C0CD00022A0B2114601F0A9F92868A5 +:10155000A043286003D1BDE8704001F013BA70BD0C +:10156000F8B5002601F00CF8012005F068FEFFF741 +:10157000B3FF604C614D94F82000000716D5D5E903 +:101580000E01F3F72EFE5F48006890F840008007D8 +:1015900009D5D4E90701FEF73DFF012803D1D5E9BC +:1015A0000E01FEF783FF69490020087094F82000BF +:1015B000217F0843C00708D0E8680090D5E9000102 +:1015C000D5E90423FFF789F90646E06950B14EB921 +:1015D000032005F034FE4948E169FEF7CCFE032004 +:1015E00005F048FEFFF7DCFEFFF7A7FFFFF793FBD0 +:1015F000FFF7E7FABDE8F840012005F03BBE70B503 +:10160000002500F0BDFF012005F019FEFFF764FF83 +:10161000384C3A4E94F82000C00703D03068FFF7EA +:10162000BAF90546E06940B33DBB49480078052852 +:1016300015D13448006890F8E50380060FD50221E3 +:101640004448FFF7D3FA4348B4F912303168226BAB +:10165000006802F01EFF02213E48FFF72AFB00212E +:101660003068FFF7D6F8032005F0E9FD2348E1696B +:10167000FEF781FE032005F0FDFDFFF791FEFFF769 +:101680005CFFFFF748FBFFF79CFABDE870400120C4 +:1016900005F0F0BD1748417A012908D0817A012967 +:1016A00005D0C17A012902D0807B002800D001201A +:1016B000704708B5FFF71EFE6B4600220B21022083 +:1016C00005F066FD0098C00705D00121022005F055 +:1016D00042FDFFF745FF0098800705D50221084627 +:1016E00005F039FDFFF78BFF00980007E4D50821CE +:1016F000022031E0740610007C580120CC731000E9 +:10170000D44A0120F40610001C59012028071000BB +:101710001106100016061000440610002F071000D6 +:1017200030071000320710002205100020051000BD +:101730003405100039051000881E0120901E01207C +:10174000C706100039071000180710002E071000F8 +:10175000E80410004405100005F0FDFCACE710B5EE +:10176000144C1548226892F83110417092F83020DC +:101770008270514341821149C978C17001210171C0 +:1017800041718171017000218182C1730174FFF781 +:101790000CF9F3F755FB2068094A90F85A1401F048 +:1017A000010111700749B0F8A6000880BDE810409B +:1017B000FEF790BDF4061000740610002807100014 +:1017C00035071000360710000D4D00200D4C286025 +:1017D0002868401C2860EEF711FE07F0CEFB0128B8 +:1017E000206809D040F00400206006F040FA00BFF5 +:1017F000EEF702FE30BFEBE720F004002060F7E7D1 +:10180000BC06100010ED00E070B5134C25462021F9 +:10181000114807F005FD104800F0AAFC2B78421E85 +:10182000691C184600F022F918B10120216801F066 +:1018300013FA00F0B7FC0028E9D170BD38B50C46AA +:10184000054605F05CFC6946284605F092FC0099C7 +:101850002142F8D138BD0000184F10000020704719 +:1018600002787B48017842B17A4A126892F87C206B +:10187000120606D529B9012102E0012901D1002172 +:1018800001700120704710B5007800B10120F6F713 +:101890006CFC012010BD70B5002300290EDD02781C +:1018A000491E0A2A0AD26C4D401C55F8324005EBFD +:1018B000C2025268914201D1A0470346184670BD4A +:1018C000017811B96549407808800120704710B54A +:1018D000017811B1012907D103E04078F9F74FFEF3 +:1018E00002E04078F9F736FE012010BD594903782F +:1018F0005B4A096833B1407881F8A50A012010706D +:1019000001207047002081F8A50AF8E71CB501689E +:1019100000918188ADF8041080798DF806009DF85B +:101920000000504AF0B19DF80100102803D29DF844 +:10193000020010280CD3002046490090019009684D +:101940006B4691F878141C18401CE1700428FADBEF +:1019500000981060BDF8040090809DF8060090711A +:1019600001201CBD107000201CBD1CB50168009139 +:101970008188ADF8041081799DF800008DF806107B +:10198000F0B334489DF802200068642A01D964222B +:1019900002E01AB990F80A238DF802209DF803306E +:1019A00090F84029934200D80BB98DF803209DF898 +:1019B00004309DF80520934202D80AB10F2B08D9B4 +:1019C00090F8BA2302F00F038DF8043012098DF855 +:1019D0000520022900D821B990F8BD0300098DF82F +:1019E00006002048009940F8071FBDF804108180C8 +:1019F0009DF8061081711C490868820708D500E02F +:101A000008E020F00200086008210120FFF716FF1F +:101A100001201CBD1349C91D087000201CBD0D49C3 +:101A200010B5096891F8961049070AD50078C207E1 +:101A30000D48016802D041F4807101E021F4807109 +:101A4000016008210120FFF7F9FE012010BD000010 +:101A500034071000F40610007095010036071000DE +:101A600049051000C00610002007100010B50C46F4 +:101A70000023A0F1A001092903D8FC4850F8213027 +:101A800008E0C0280AD1F949A0F1C000A1F1040181 +:101A900051F820301146204698470346184610BD9D +:101AA0000020704770B5F24C00230029236011DD3F +:101AB0000278491E042A0DD2EC4D401C283555F8F9 +:101AC000324005EBC2025268002A03DB914201D189 +:101AD000A0470346184670BD70B500210278E54C5A +:101AE00093060D4602D50121217003E0D20701D0F3 +:101AF000012125700078400701D541F00401DE483E +:101B0000016004210120FFF799FE2570012070BDBE +:101B100010B510210120FFF791FED7490020086081 +:101B2000012010BD10B50146002409782046032984 +:101B300018D005DC59B101290CD002291AD10EE0C8 +:101B4000042911D0102912D0112913D111E0012438 +:101B5000002001E00224012000F08CFA0AE00424B5 +:101B60000220F9E7202400E04024012002E00824BC +:101B700000E01024BE4914F0180F0C60BE4C06D0D3 +:101B800010210120FFF75AFE0020206007E02168A5 +:101B9000814204D0206004210120FFF74FFE012084 +:101BA00010BD70B5002300290FDD0278491E052AFB +:101BB0000BD2AE4D401C483555F8324005EBC20201 +:101BC0005268914201D1A0470346184670BD10B536 +:101BD0000078C207A948016802D041F0020101E083 +:101BE00021F00201016008210120FFF727FE0120FA +:101BF00010BD10B50078C207A048016802D041F0BE +:101C0000040101E021F00401016008210120FFF737 +:101C100015FE012010BD10B50178CB0797490A6861 +:101C200002D042F0080201E022F008020A600078C7 +:101C3000800702D542F0400001E022F04000086039 +:101C400008210120FFF7FAFD012010BD10B5002189 +:101C500003780A469C0601D5202100229C0701D565 +:101C600041F002015C0701D541F004011C0701D5D8 +:101C700041F00801DC0601D541F010015C0601D5F8 +:101C800041F040011B0601D541F080014378DC079B +:101C900001D041F480719C0701D541F400715C07CB +:101CA00001D541F480611C0701D541F40061DC06D7 +:101CB00001D541F480519C0601D541F400515C06E8 +:101CC00001D541F480411B0601D541F400418378E0 +:101CD000DC0701D041F480319C0701D541F400318B +:101CE0005C0701D541F480211C0701D541F4002196 +:101CF000DC0601D541F480119C0601D541F40011A8 +:101D00005C0601D541F480011B0601D541F40001B8 +:101D1000C078C00701D041F080715948C0E9001275 +:101D2000012010BD007800B1012056490870012043 +:101D3000704770B5002300290FDD0278491E0B2A79 +:101D40000BD24A4D401C703555F8324005EBC202AB +:101D50005268914201D1A0470346184670BD014622 +:101D600000200978052906D24048C83050F82120C3 +:101D7000002108461047704710B505F034FF0120D8 +:101D800010BD10B500F0A6FA012010BD10B54FF43B +:101D900000610020FFF752FD012010BD10B54FF487 +:101DA00080510020FFF74AFD012010BD10B54FF40F +:101DB00000010020FFF742FD012010BD10B50078A2 +:101DC000C00702D000F015FA01E000F009FA012086 +:101DD00010BD10B500880024C10700D0022481077F +:101DE00001D544F00404410701D544F00804C005BE +:101DF00001D544F4807494B1EEF700FB22480168E9 +:101E000021430160EEF7F8FA0221052000F024FFDB +:101E10004FF480710020FFF711FD012010BD00205C +:101E200010BD10B500880024C10700D0012481072F +:101E300001D544F00204410701D544F00404010730 +:101E400001D544F00804C00501D544F48074FCB108 +:101E5000EEF7D4FA0D48016821430160EEF7CCFAA1 +:101E600002210020FFF7EAFC012010BDC49501000B +:101E700024071000380710001C071000200710006E +:101E8000600510003507100000071000040710005F +:101E90000020EAE710B500880024C10700D0012423 +:101EA000810701D544F00204410701D544F0040440 +:101EB000000701D544F0080474B1EEF79FFA7248A8 +:101EC000016821430160EEF797FA4FF400110020FA +:101ED000FFF7B4FC0120C8E70020C6E710B5008872 +:101EE0000024C10700D00124810701D544F0020479 +:101EF000410701D544F00404010701D544F008046A +:101F0000C10601D544F01004810601D544F0200437 +:101F1000410601D544F04004010601D544F0800497 +:101F2000C10501D544F48074810501D544F40074E1 +:101F3000400501D544F480646CB1EEF75FFA534874 +:101F4000016821430160EEF757FA80210020FFF776 +:101F500075FC012089E7002087E710B50088002480 +:101F6000C10700D00124810701D544F002044007D5 +:101F700001D544F0040474B1EEF740FA4448016816 +:101F800021430160EEF738FA4FF480010020FFF79B +:101F900055FC012069E7002067E710B500780024B0 +:101FA000C10700D00124810701D544F00204400795 +:101FB00001D544F0040474B1EEF720FA3548016805 +:101FC00021430160EEF718FA4FF480610020FFF71B +:101FD00035FC012049E7002047E710B500780024D0 +:101FE000522841D01CDC30283AD00CDC112833D0E8 +:101FF00004DC01282DD0102834D12DE012282BD05C +:1020000013282FD128E033282AD004DC312827D008 +:10201000322827D124E0502826D0512822D123E08D +:10202000732824D00CDC702821D004DC53281BD06A +:10203000582817D118E0712819D0722812D116E04B +:10204000742814D0752812D0762810D0772809D19A +:102050000DE000F03CFB01E000F0D6FB012401E0C4 +:1020600000F0F2FB204600E700F0DCFBF6E700F0B2 +:10207000CAFCF3E7002118B1012801D0022800D1E1 +:1020800005210846704700000807100010071000DF +:10209000140710000C071000204908B50020204C40 +:1020A00008602049206008601F48006890F84003DD +:1020B000C00701D00220206000F009FB00F0BFFD46 +:1020C0006B4600221921032005F062F80098C00732 +:1020D00005D00121032005F03EF8FFF795FB00989D +:1020E00000070BD50821032005F035F820680821EA +:1020F00040F0080020600120FFF7A0FB0098C00618 +:10210000DED51021032005F026F82068082120F0F4 +:10211000080020600120FFF791FBD1E71C071000A9 +:102120002007100024071000F40610001F480021AB +:10213000017041708170704710B51C4C0346A07847 +:10214000102814D20F2900D90F211948227800EB4A +:1021500002100A4600F8011B194606F0E2FF20783B +:10216000401C00F00F002070A078401CA07010BD33 +:1021700070B50E4C0025A17891B10D49627801EB44 +:10218000021111F8015B2A4606F0CBFF6078401C73 +:1021900000F00F00607072B6A078401EA07062B6AA +:1021A000284670BD0148807870470000CE061000B8 +:1021B000384F100010B54FF486714F4807F052F8B1 +:1021C0004D490120C1F804014C48002141600170D3 +:1021D00007F0F6F80021BDE81040012006F091B8A4 +:1021E00010B572B600204549087007F0E9F862B6EC +:1021F00010BD10B572B60120404908703E48D0F8B5 +:10220000080108B107F038F962B610BD10B572B612 +:1022100039493A4B0A46D1F80841D2F80021521CFC +:10222000202C07D2641C22F02002C1F80841C1F81A +:1022300000210FE0D1F8044122F02002641CC1F813 +:10224000002124F02002C1F804215A68521C5A606F +:10225000D1F80021046801EBC202146040685060AC +:102260001878012805D1D1F80801012801D107F01B +:1022700003F962B610BD204AD2F8080100280ED03A +:10228000D2F8040102EBC000C37923F03F03C3710D +:1022900092F80821521E02F03F021343C3717047A7 +:1022A00010B572B61448D0F8081159B1491EC0F8DB +:1022B0000811D0F8042102F1010222F02002C0F836 +:1022C000042105D10D480078012801D107F078F8E4 +:1022D00062B610BD10B572B6002007490122C1F8E0 +:1022E0000801C1E94002054948600878012801D188 +:1022F00007F066F862B610BD4C570120D4061000F6 +:10230000064900224FF470430A804B80044BC0E919 +:10231000003102210172427270470000DC06100099 +:10232000A59601002DE9F05FDFF83C92DFF834B2AA +:102330000F4606464FF0010AA9F10805A84628787D +:102340000446072809D2DFE800F004292D49708BE4 +:102350009C00012E02D0022E13D07EE0002F7CD0F4 +:10236000804810300078862809D07E48F9B21030B5 +:10237000FFF7E2FE0121032004F0C1FE6DE003241B +:102380006BE06878012805D01021764806F048FFF8 +:1023900000F0A2F8544689F800A05EE0022E5AD060 +:1023A000002445E0022E1BD1704C6E48D8F8041072 +:1023B000227806F0B6FE032189F800102178A9F8EA +:1023C000041098F80000042488F8010088F8004000 +:1023D00033E0002488F801002C70AFE7022E02D011 +:1023E000012EF6D039E0FFF746FF082170B15D4AB3 +:1023F000D0E90030C2E90030022289F80020594AB1 +:10240000A9F80220A9F80410052426E06878062817 +:1024100004D00022CBF80020CBF80420032289F856 +:102420000020A9F80410062417E0022E08D0022488 +:102430005FFA80F088F801002C704B48BDE8F09FEF +:102440006878042807D00BEB0700394610F8012CF8 +:10245000444806F0DDFE89F800A0A8462878E9E7A0 +:10246000022E04D0082F8AD1FFF71AFF87E7FFF763 +:1024700017FF98F80000032488F8010088F800404E +:102480005CE7022E4FF00304A4D0D1E736490022C6 +:1024900008390A704A70354A521C4A603449016052 +:1024A000304981801031C18010210181704710B501 +:1024B000044606F085FF2B4AD4E90001C2E9000179 +:1024C0002A480C3806F0E2FF28480C3806F030F8AD +:1024D000BDE8104006F0D0BF70B5224C1034207813 +:1024E000C12824D160781F4D052808D100F020F8BC +:1024F0002048016829608188A9808079A871607866 +:10250000082814D11C4C207858B90F216170002183 +:10251000A1701A49E01C096891F87824042106F09A +:1025200077FE20682860A088A880A079A87170BD77 +:1025300010480178002913D141701049096891F8B9 +:102540000A23827091F84029C27091F8BA231309C6 +:10255000437102F00F02027191F8BD1309098171F4 +:102560007047000058580120E80610004450100041 +:10257000D5220100C7061000C0061000F4061000A6 +:1025800070B50F4DA02128462C8806F06BFE641C08 +:102590002C8070BD0A48001F002101607047084967 +:1025A000091F0A88024204D0C87818B1C878401EB2 +:1025B000C8707047A52088708878A528FCD070471F +:1025C0007C58012037480021016041607047C0B24B +:1025D000012200F043FBFEE7344C0025324FC4E9F2 +:1025E0000225C4E9007106460068206170686061D8 +:1025F000B068A061F068E061306920627069606273 +:10260000B069A062F069E062294890468946006896 +:102610002063274810380068606325480C3800683C +:10262000A063234808380068E0632148001D006863 +:1026300020641F483438006860641D4814380068FE +:10264000C4E9120504F0ABFE2065C4E91565E56533 +:1026500025666566A566E56625676567C4E91E5754 +:1026600041464846FFF7B3FF10B50446C0B200220A +:1026700000F0F4FA0F490868082803DA094A1454EC +:10268000401C086010BD012806D0022808D1002295 +:102690001146132000F0E2BA002211461220F9E799 +:1026A0007047000070EF0120AF0550FA80EF012065 +:1026B00038ED00E0F0061000FD48FE4A0168914246 +:1026C00004D1FD4902794A70002101607047F0B5DC +:1026D00085B040F26C71F64806F0C4FD684605F01E +:1026E000A4FDF34C012500266570A680A67102208A +:1026F000E07105F060FA208105F059FA070205F053 +:1027000056FA47EA102060815420208242F21600D7 +:102710006082EA480068418AA182018AE182E84930 +:10272000B1F8FA2E2283B1F8F82E6283427D227727 +:1027300091F8FC1E6177E3490968497CA177E67747 +:1027400001992162009961620299A162DDE9031297 +:1027500041EA0221E16281692163C1696163DA4969 +:102760000968A1630168E163418EA4F85010818E6D +:10277000A4F8521090F8311004F8541F90F830006B +:102780006070D24824F82C0FD1482081D148608154 +:10279000D148A081D148E081D1482082D1486082CF +:1027A000D148A082D148E082D1482083D1486083BB +:1027B000D148A083D148E083D148A4F85000D14843 +:1027C000A4F85200D048A4F85400D048A4F8560009 +:1027D000CF482086CF486086CF48A086CF48E08685 +:1027E000CF482087CF486087CF48A087B249CF48DD +:1027F000E0878888401C8880A52204F8802D6570B9 +:1028000060800D7005B0F0BD70B5AB4C054600237F +:10281000A088A749401C82B2A280284601F03DFC56 +:10282000257070BD70B5054640F26C71A04806F089 +:1028300019FDA14C9E49A088401C82B2A280284666 +:1028400001F059FC257070BD70B59B4C0546207891 +:10285000A84204D040F26C71954806F003FDB448DC +:10286000A5700F2101609248914A1030A060A0200D +:102870001071924802F1B005E560006890F83110DF +:1028800090F83030517101FB03F005EB4006937175 +:1028900026610844D17105EB40006061137270BD80 +:1028A00070B50546844CC00704D0A0228749A068B3 +:1028B00006F037FC814EA80712D5316891F8310037 +:1028C00091F830104843A178302935D0312935D0DE +:1028D000322935D08049E3684200184606F021FCD1 +:1028E000680716D53068A17890F8312091483029D2 +:1028F00028D0312931D00078322930D0022838D080 +:10290000052836D0062834D077495200206906F0D1 +:1029100008FC280735D5306890F83020A07830289A +:1029200029D0312829D0322829D073496069BDE8DF +:102930007040520006F0F5BB6549CCE76549CAE72F +:102940006649C8E70078022805D0052803D0062884 +:1029500001D06349D9E76B49D7E76249D5E7022837 +:1029600005D0052803D0062801D06049CDE7674986 +:10297000CBE76549C9E75E49D8E75E49D6E75F49D5 +:10298000D4E770BD4A4AA52010704B488178517039 +:1029900001708188491C81805180704730B587B0B3 +:1029A0000C4600218DF80C104FF4832504AB03AACC +:1029B000694600F0EBF89DF8100010B1112816D010 +:1029C0001AE09DF80C20BAB10098627105EB800105 +:1029D00004F110000A78930703D002F0FC020832D9 +:1029E00000E0121DD2B206F09CFB07B030BD3220D1 +:1029F00000222071114603E0302000222071114690 +:102A000000F02CF9F1E770B505464FF4C87128487D +:102A100006F028FC284C2649A088401CA0802846A7 +:102A2000FFF7BCFF22482570A52101704570A188E1 +:102A3000418070BD2DE9F84F884606460C460D1DB5 +:102A400000239B220421404600F056FD70BBA07875 +:102A5000B0422BD1217800239B22284600F04CFD68 +:102A60006178884222D1207881070AD0022202EBC5 +:102A70009006002101E02954401CB0EB860FFAD3E8 +:102A800002E0012101EB90060024DFF824B04FF4AE +:102A90008325A1464FF0330A55F8240005EB84073F +:102AA000401C4ED000239B22042145E068E000003A +:102AB000000001204B4355463C071000F40610006F +:102AC00014750120F8061000F0FF01007C58012069 +:102AD000B48C012098440120D44A01201C590120C3 +:102AE000D08901207A0C0120F00C01200C72012009 +:102AF000FA890120A40C01201A0D01203672012050 +:102B0000FC850120FE090120280A0120D4090120AA +:102B1000EC860120520A0120C80A0120827201209D +:102B2000168701207C0A0120F20A0120AC720120E4 +:102B300018071000E8041000384600F0DDFC10B162 +:102B400015E000940CE03878810704EB900401D084 +:102B5000A41C00E0641C602C9ED3B9F1000F06D0C9 +:102B600031464046009A05F052F900280CD0002268 +:102B70008BF804A011463320BDE8F84F00F06EB882 +:102B8000002211463120F7E7BDE8F88F2DE9FF5FFD +:102B900000260E601D4688464FF48327B146344612 +:102BA000B3461E7057F8240007EB840A401C23D05C +:102BB00000239B220421504600F09EFC18B11220F5 +:102BC000287001261CE09AF8022000999AF800006B +:102BD0008A4208D10299029A4FF001090978491CEA +:102BE0001170C8F80040810704EB900401D0A41CC8 +:102BF00000E0641C602CD5D316B9B9F1010F0BD0DD +:102C000056EA090606D111202870029981F800B011 +:102C1000C8F800B0BDE8FF9FD8F80000002307EB1C +:102C20008004201D21789B2200F066FC6178884298 +:102C300002D185F800B0EDE712202870EAE700F035 +:102C400015B838B504466946183000F000FD204636 +:102C5000009900F015F838BD00F073B800F090B896 +:102C600000F0B4B80146032000F05DB81CB562491D +:102C7000D1E90001CDE900016846FFF7C7FA1CBDA4 +:102C80001CB55D4BD3E90223CDE9002390F8262142 +:102C9000032A19D0082A9DF8002022F0F00219D04A +:102CA00012F120028DF8002090F8272102F00F0287 +:102CB000012A11D0022A15D0042A9DF8012022F001 +:102CC0000F022ED0521C12E09DF8002022F0F002DC +:102CD0001032E7E73032E5E79DF8012022F00F02DD +:102CE000921C04E09DF8012022F00F02D21C8DF806 +:102CF000012090F83501D2B260F307128DF801205F +:102D0000BDF802000A0C62F30B00ADF80200BDF83A +:102D1000030061F30F10ADF803006846FFF776FA81 +:102D20001CBD121DE3E71CB5334BD3E90423CDE9E9 +:102D300000238DF80100CDF802106846FFF766FA0F +:102D40001CBD1CB52D4A126892F8BA20930716D5FF +:102D50000A2814D2DFE800F0130507070707070762 +:102D6000130712060BD5244BD3E90623CDE9002324 +:102D70008DF80100CDF802106846FFF747FA1CBD38 +:102D80001CB51D4CD4E90834CDE900348DF80100A0 +:102D9000CDF80210684612B1FFF789FB1CBDFFF7A2 +:102DA00035FA1CBD1CB5154A126892F8BA201207F4 +:102DB0000BD5114BD3E90C23CDE900238DF801008D +:102DC000CDF802106846FFF721FA1CBD1CB541780A +:102DD000002910D005290ED2074AD2E90E12CDE9FA +:102DE0000012D0F80210CDF80210C088ADF806002D +:102DF0006846FFF70BFA1CBDB0960100F406100000 +:102E00002DE9FF4104F0C6F8234D0024C4EBC401B2 +:102E100005EB810000F10C03027EC8CBCDE9027204 +:102E2000CDE90036D0E9012355F82100002104F056 +:102E30005BFA18B121464320FFF7C9FB641C052C3F +:102E4000E4DB154D00248C3505EBC40000214268FD +:102E500055F8340004F0CFF918B121464420FFF7AB +:102E6000B6FB641C062CEFDB0B4D002415F1BC05F2 +:102E7000002155F8240004F024F918B1214645201A +:102E8000FFF7A5FB641C042CF2DBBDE8FF810146C3 +:102E90004620FFF79CBB0000F096010000F01F03E6 +:102EA00001229A4043099B0003F1E023C3F88022EA +:102EB0004907090E002806DA00F00F0000F1E020B3 +:102EC00080F8141D03E000F1E02080F80014C3F83E +:102ED000002170472DE9F041642707260025FE4CAC +:102EE000FE4805F045F9FD480368D91C40D042680A +:102EF000D11C3DD0816811F1030F39D0006910F168 +:102F0000030F35D0B3F1FF3F35D013F1020F32D0AC +:102F1000B2F1FF3F2FD012F1020F2CD0B1F1FF3FE1 +:102F200029D011F1020F26D0B0F1FF3F23D010F1CC +:102F3000020F20D0DFB2D6B2CDB204462A463146C7 +:102F4000384604F05DFE204604F067FEE44805F0D4 +:102F5000E5F8032814D0012815D0022813D0E04842 +:102F60000168012915D1BDE8F041001D04F05DBAEA +:102F70000021242001E000212520FFF775FBDDE77B +:102F80000021292001E000212A20BDE8F041FFF7BF +:102F90006BBBBDE8F0812DE9FC47D24D012401AAAD +:102FA0006946284604F0ACFEDFF83C834FF48C59A8 +:102FB000012803D10098B0F58C6F04D000212220A5 +:102FC000FFF752FB40E029464A464546D8F8000044 +:102FD00006F0A7F8286804F0A6FE012804D0002116 +:102FE0002320FFF741FB0024296828220F46BF4811 +:102FF00001F5865106F095F841F2E6003918BB4814 +:1030000020220E46283006F08CF841F21C103918A8 +:10301000B64828220D46483006F083F841F24210A7 +:103020003918B2482022703006F07BF8AF482022D1 +:103030003146903006F075F8AC4828222946B03069 +:1030400006F06FF8002C04D14946D8F8000006F0CD +:10305000E7F8BDE8FC87F8B50D46064600246A4649 +:1030600004F04EFE012801D001240BE0286831460F +:1030700082009F4806F09AF89D4804F054FE01280B +:1030800000D002242046F8BDF8B5994D994F10356F +:103090004FF47061984806F0E5F869463846FFF746 +:1030A000DAFF012805D0022806D0E87801280AD1E5 +:1030B00005E00021A02029E00021A12026E0A87839 +:1030C00008B9288810B10021A2201FE08A48E988A9 +:1030D0000024A0F8F81EA988A0F8FA1E297A80F822 +:1030E000FC1E0098694607EB80073846FFF7B3FFE0 +:1030F00078B1012804D000215FF0A600FFF7B4FAF0 +:10310000E00725D0A00725D41121A720FFF7ACFAAE +:10311000F8BD6E782946304600F09DFF60B1102E54 +:103120000DD0112E0ED0122E03D0132E0DD0182E2E +:10313000D7D144F00804D4E73146A820DEE744F0B4 +:103140000104CEE744F00204CBE744F01004C8E7E2 +:103150001021DAE720070BD46848006890F8501275 +:10316000C90703D190F81E0AC00701D01221CCE78D +:10317000E006CDD41321C8E730B58DB0EDF73EF9A8 +:103180000020012241B201F01F0302FA03F34909B2 +:10319000890001F1E021C1F88031401C1F28F1DBDA +:1031A000EDF72AF904F0DAFCFFF786FA05F092F859 +:1031B00007210A20FFF772FE07210B20FFF76EFEA2 +:1031C000FEF7F8FFFEF7B2FF04A8FFF75FF907A8C4 +:1031D000FFF796F804A8009007A802900AA80390A9 +:1031E000684605F041FA02210020FFF757FE06F07D +:1031F00049F90078C00701D1FEF7FBFFFFF7E2F9BC +:10320000FFF768FE04F0F4FC3D4D01AA694628462C +:1032100004F076FD394C012802D00021202010E076 +:103220000098B0F5347FF8D14FF434622946206815 +:1032300005F077FF206804F076FD012803D0002117 +:103240002120FFF7C4F9FFF7A6FE05F00EF80500F0 +:103250005DD00121012D02D02E20FFF7B8F92068A2 +:10326000017DA94202D02F20FFF7B1F9FFF70CFF33 +:1032700000F052F803F056FB04F0ACF800230122F2 +:103280001946052005F05CFE00231A4601210620A0 +:1032900005F056FE03210120FFF700FE0421072060 +:1032A000FFF7FCFD04210820FFF7F8FD206890F8E7 +:1032B0006003C1070FD081070DD50021012340090C +:1032C0001A46009105F02AF82068002190F8600362 +:1032D000400905F04BF815E00090D0038C861000F3 +:1032E000B48C1000F09F0100F80610001484012037 +:1032F000D4611000F0BF010014750120F406100025 +:10330000F0EF01000DB0BDE83040FFF743B90021F8 +:103310002D20FFF7A9F9A9E710B505F065FA0023FC +:1033200001221946184605F00BFE0023012219461A +:10333000104605F005FE00231A460121022005F083 +:10334000FFFD00231A460121032005F0F9FD0023AB +:103350001A460121042005F0F3FD17480068017C9E +:10336000A52908D04FF4FA4005F0D4FD002128200B +:10337000FFF77AF902E0406905F0CCFD0421022054 +:10338000FFF78CFD04210320FFF788FD0421084688 +:10339000FFF784FD04210520FFF780FD04210620AE +:1033A000FFF77CFD01210920FFF778FD0421BDE82E +:1033B00010400F2072E50000F806100070B5694B50 +:1033C00016465C0C08E000BF31F91650A54200DA41 +:1033D0002C469D4200DD2B46761EF5D20025002BA3 +:1033E00001DA1D4609E0002C07DD254605E000BF97 +:1033F00031F812305B1B20F81230521EF8D270BD2B +:103400002DE9F047002591460F4680461C462E4682 +:103410005A1E0120294605F04DFE0BE038F9142014 +:10342000BA4204DA4A44002A01DD05430E43490842 +:103430004FEA3000641EF1D228463146BDE8F087DD +:103440002DE9F047994616461EE0021800F00105E6 +:103450002A4341EB010707EA010503464F0802EA48 +:1034600003084FEA3004A9F101024FF001004FF0C8 +:10347000000105F01FFE00EA0800044329400F4345 +:1034800004EA080007EA0501761EDED2D6E7884284 +:1034900000D30846904200D310467047884200D8B7 +:1034A0000846904200D810467047884200D308462C +:1034B0007047884200D80846704710B500231C4664 +:1034C00042B10278521CD2B202708A4203D904700F +:1034D000012300E00470184610BD30B5002401231C +:1034E00005E00C44E41C04F00305641B5B1C9342E0 +:1034F000F7DD00EB440030BD70B5054618460024EA +:103500000EE02B5D58400823060602D582EA4000F3 +:1035100000E040005B1EC0B213F0FF03F4D1641C56 +:103520008C42EED370BDF0B5851ADDE905471E1B50 +:1035300075438E1A012F02D0904206DD0BE09042B7 +:1035400001DC1846F0BD884201DB2046F0BD95FB4A +:10355000F6F0181AF0BD8842F3DA95FBF6F0204435 +:10356000F0BD00000080FFFF884201DD0846704783 +:103570000028FCDA0020704710B504E000EB82035D +:1035800053F8044C1C60521EF8D10968016010BD4C +:1035900010B503E000EB82030C681C60521EF9D2E8 +:1035A00010BD30B506E000BF00EBC20373E9024571 +:1035B000C3E90245521EF7D1D1E90021C0E900213B +:1035C00030BD10B553884C881B1B43801288098876 +:1035D000511A018010BD08B50A4601466846FFF73A +:1035E000F0FFBDF90010BDF90200494300FB0010D7 +:1035F00008BD10B58842029C01DC204610BD9042F7 +:1036000001DB184610BD8A4200D1521C401AE31A51 +:103610005843511A90FBF1F0201A10BD10B5002A42 +:1036200003D0431A934201DD881810BD5442A342CF +:10363000FBDA881A10BD914201D100B270475043A5 +:10364000B0FBF1F000B29042F7D91046F5E770B543 +:103650000B0002463DD0E64C2068468E858EB2F9BE +:10366000020031B2FFF780FF5880B2F9000029B2A2 +:10367000FFF77AFF1880216891F83610490702D5C4 +:103680005988711A5980216891F83610890701D537 +:10369000281A1880206890F83610090710D5B0F85D +:1036A0003720B3F902003146FFF7C5FF5880206884 +:1036B0002946B0F83920B3F90000FFF7BCFF1880A5 +:1036C000206890F83600C00703D0588819885980C0 +:1036D000188070BD2DE9F047D0F810C00568046A65 +:1036E00085FB0C12A1FB041242694368914683FBDF +:1036F00002628269E246A6FB02677618D0E90217E9 +:1037000081FB07C8C069ACFB00C81CEB060682FB46 +:103710000A2CA2FB011280FB0902A0FB0502401843 +:1037200084FB0712A1FB03120818301A4FEAE0715C +:10373000BDE8F0872DE9FF4F8146AD4800268DB0EA +:1037400000683746B04690F87E4390F87F0300F05B +:10375000030A04B90224BAF1000F01D14FF0040AA0 +:103760005FF0000109EBC10040680644484300FBDC +:103770000188491C07440629F4DB9E4D00966868C1 +:103780000190A868CDE90207286904906869CDE92D +:103790000508E8690790286A08906846FFF79AFFCD +:1037A00083460B912868CDE90006A8680290E86876 +:1037B000CDE9030768690590A869CDE90608286A7C +:1037C00008906846FFF786FFCDE909012868009058 +:1037D0006868CDE90106E86803902869CDE9040727 +:1037E000A8690690E869CDE907086846FFF772FF07 +:1037F00006468846DDE90901A0FB0435A6FB047CEA +:1038000001FB0451002200FB021508FB04C106FB6A +:103810000210A7FB04C100FB041007FB020013EB1E +:103820000C0345EB00010B9A13EB0B0051414FF4D5 +:103830007562002305F051FC09EBCA0148600E993E +:1038400048600F990B9AC1E900B2DDE909010F9AAE +:10385000C2E902010F98C0E9046800263746B04665 +:103860004FEA060059F830100E44414301FB00882E +:10387000401C0F440628F5DB5E4D009668680190F9 +:10388000A868CDE90207286904906869CDE90508B0 +:10389000E8690790286A08906846FFF71BFFCDE9A2 +:1038A00009012868CDE90006A8680290E868CDE91A +:1038B000030768690590A869CDE90608286A089099 +:1038C0006846FFF707FFCDE90B012868009068689C +:1038D000CDE90106E86803902869CDE90407A869E5 +:1038E0000690E869CDE907086846FFF7F3FE8046D1 +:1038F0008B46DDE90B01A0FB0453A8FB046701FB29 +:103900000431002200FB02110BFB047308FB0230A0 +:10391000A6FB043700FB047006FB0200EB184141D4 +:10392000DDE90902181851414FF47562002305F0D2 +:10393000D4FB49F83A000E990860DDE909021099B4 +:10394000C1E90002DDE90B01109AC2E902011099F8 +:10395000C1E9048B11B0BDE8F08F2DE9F05FD1E92A +:1039600001651C46A5FB0438D1F80CC017460CFBBA +:10397000048C0A6882464FF0000B05FB0BC0D3187D +:10398000D1E9042104FB04F5A2FB05C801FB058174 +:1039900046414FEAE57902FB091213EB0C0046EBB6 +:1039A00002014FF475625B4605F097FBCAF804000C +:1039B00097E80B00FA68A3FB04C802FB048203FB30 +:1039C0000B2310EB0C025941D7E90434A3FB056724 +:1039D00004FB057403FB0943901959414FF47562C8 +:1039E000002305F07AFBCAF80000BDE8F09F000054 +:1039F000F40610005407100073B51D24DDE90056CD +:103A000022460120002105F055FB284031400843A3 +:103A100001D1641EF4D50821684604F05FF9FF491E +:103A2000C0B2096891F8E710C1F3411102290ED321 +:103A300010F0030005D0012805D0022805D01F2072 +:103A40000AE00F2008E07F2006E03F2004E0C007E6 +:103A500001D0072000E003200021621C05F02AFBB2 +:103A6000DDE9002310431943CDE900017CBD10B509 +:103A7000EB4C502818D00ADCA0F1100009280ED217 +:103A8000DFE800F0122828280D0D0D0D2F00512819 +:103A900020D052281ED053281CD0582821D00020D6 +:103AA000C4E90200014622E003F006F8C4E902017D +:103AB00003F004F8C4E90401D848006890F8E7006E +:103AC00010F0600F15D0D4E90201FFF795FFC4E9AB +:103AD00002010EE002F0F0FFC4E9020102F0EEFF85 +:103AE00005E002F0F1FFC4E9020102F0EFFFC4E9D2 +:103AF0000401CB480821083004F0F0F82060C848E1 +:103B00000821103004F0EAF8606010BD2DE9FF5F75 +:103B10000821DDE90FBA684604F0E0F88146082183 +:103B200002A804F0DBF80746002420463AE04246AB +:103B30000120002105F0BEFADDE900231040194004 +:103B400008432DD000252E4627E0324601200021D3 +:103B500005F0B0FADDE902231040194008431BD0FC +:103B6000119860B104FB07F00BEB0501415632469A +:103B700001EB0A0321460E9803F015FD0BE03246D7 +:103B800021460E9803F004FD04FB07F10BEB050240 +:103B9000A0EB0A0088546D1C761CBD42D5DB641C6A +:103BA00008F1010080464C45C1DBBDE8FF9F2DE9CF +:103BB000FF5F84B00821DDE912AB04A804F08EF8A1 +:103BC0008146082106A804F089F8804600250AF1FC +:103BD000480002902030019048382C462F462E464F +:103BE000009034E03A460120002105F063FADDE957 +:103BF000042310401940084327D0169890B11BF8B1 +:103C0000051014980844C2B23946029803F037FDF3 +:103C100005EB090141441BF901203946504603F0E8 +:103C200006FD10E03946029803F027FD1499401A6A +:103C30000BF805003946504603F0F2FC05EB09028B +:103C400042440BF802006D1CEDB27F1CFFB24D45E3 +:103C5000C8DB38E032460120002105F02BFADDE90F +:103C600006231040194008432BD01698A0B104EB4E +:103C7000090115981BF801100844C2B23146019899 +:103C800003F0FDFC04EB490141441BF901203146DE +:103C9000009803F0CCFC12E03146019803F0EDFCF3 +:103CA000159904EB0902401A0BF8020031460098FE +:103CB00003F0B6FC04EB490242440BF80200641C1A +:103CC000E4B2761CF6B24445C4DB08B0BDE8F09F10 +:103CD0002DE9FF5F0821DDE90EBA684603F0FEFF1B +:103CE0008146082102A803F0F9FF07460024204678 +:103CF00029E042460120002105F0DCF9DDE900233E +:103D00001040194008431CD000252E4616E03246CC +:103D10000120002105F0CEF9DDE902231040194011 +:103D200008430AD032462146584603F031FC04FBD2 +:103D3000075280002AF812006D1C761CBD42E6DB9B +:103D4000641C08F1010080464C45D2DB2DE72DE9CB +:103D5000FF5F0821DDE90E9B684603F0BFFF824646 +:103D6000082102A803F0BAFF002580462C462F4602 +:103D70002E463DE03A460120002105F09BF9DDE9A1 +:103D8000002310401940084330D0394609F148005B +:103D900003F073FC214999F892C00A6892F8413106 +:103DA00092F8402103F00F01491C0CFB01FC01219A +:103DB00001EB131300FB03C399F8900001EB121100 +:103DC00000FB0130109919B94FF6FF7101EA80002C +:103DD0002BF815003946484603F022FC05EB0A0291 +:103DE000800042446D1C2BF81200EDB27F1CFFB224 +:103DF0005545BFDB44E032460120002105F05AF969 +:103E0000DDE9022310401940084337D0314609F15B +:103E1000680003F032FC99F8935003E0F4061000B8 +:103E200078071000FE490B6893F8431193F842316C +:103E300001F00F02521C5543012202EB111100FB4D +:103E4000015199F8910002EB131200FB0210109936 +:103E500019B94FF6FF7101EA800004EB0A023146FE +:103E60002BF8120009F1200003F0DAFB04EB4A0200 +:103E700080004244641C2BF81200E4B2761CF6B2B7 +:103E80004445B8DB91E630B5E649027987B00B6866 +:103E90009A4203D142794B689A4202D0002007B07F +:103EA00030BDE14A8579002482F8825BC57982F8C9 +:103EB000835B857A82F8845BC57A82F8855B057BB3 +:103EC00082F8805B457B82F8815BD84A2346126882 +:103ED000957FA52D03D192F91F4092F92030D04A49 +:103EE000012510301268083192F83421CDE90243DF +:103EF00002F00102CDE90452CD4ACDE900200FC9FC +:103F0000FFF755FE0120CAE72DE9F0438946002757 +:103F100087B0904604463E46FC2105F081F9C14D2C +:103F2000B8F1010F2878207128796071BE4890F8A7 +:103F3000821BA17190F8831BE17190F8841BA17220 +:103F400090F8851BE17290F8801B217390F8810B2B +:103F5000607308D1B5480068817FA52903D190F925 +:103F60001F7090F92060AE480021006890F834017D +:103F7000CDE9027600F00100CDE9041004F1100053 +:103F8000AB49CDE9001005F108000FC8FFF70FFE9F +:103F9000A520207012206070A4F80290D5E90001DD +:103FA0000844132101EB4000800807B0BDE8F0830E +:103FB0002DE9F0438946002787B0904604463E46E7 +:103FC000FC2105F02DF9974DB8F1010F28782071EB +:103FD00028796071944890F81A1CA17190F81B1C04 +:103FE000E17190F81C1CA17290F81D1CE17290F810 +:103FF000181C217390F8190C607309D18B48006864 +:1040000090F82110A52903D110F9227F90F90160C1 +:1040100083480021006890F86209CDE9027600F03B +:104020000100CDE90410824904F110009831CDE976 +:10403000001005F108000FC8FFF7B9FDA52020709A +:1040400013206070A4F80290D5E90012114400EB2F +:1040500041008008A9E770B50E4605460024FFF729 +:1040600006FD103D092D0ED2DFE805F00509130FFE +:104070000D0D0D0D1300304600F08FF802E03046B4 +:1040800000F0AEF80446204670BD304600F0D8F887 +:10409000F8E73046FFF7F7FEF4E72DE9F0411E465A +:1040A0001746884605460024FFF7E1FC103D092D20 +:1040B00012D2DFE805F0050B1A14111111111A00C4 +:1040C00032463946404600F0FCF804E032463946B4 +:1040D000404600F028F904462046BDE8F08132460B +:1040E00039464046FFF764FFF5E732463946404619 +:1040F000FFF70AFFEFE72DE9FF41174606460D4699 +:10410000FFF7B5FC4748A6F15003494A01782971E9 +:1041100001796971424905F11004092B29D2DFE8C0 +:1041200003F005072E12282828282E003E4900E01B +:104130004049CDE9001484680C3090E80E00204618 +:10414000FFF7C6FD15E00968394B91F8622991F82F +:104150006E1902F0010201F001019833CDE902125B +:10416000CDE9003484680C3090E80E002046FFF75B +:10417000EEFDA52028706E706F80BDE8FF81096894 +:1041800091F8343191F8401103F0010301F001017D +:10419000CDE90213CDE90024E4E71FB521490279F6 +:1041A0000B689A4203D142794B689A4202D00020B0 +:1041B00004B010BD1D4B00221B689C7EA52C01D1B4 +:1041C00093F91B20184C0DF1040C012310300094BE +:1041D0008CE80D0008310FC9FFF798FC0120E7E7D4 +:1041E0001FB5104902790B689A4203D142794B6896 +:1041F0009A4201D00020DBE70C4B00221B681C7F99 +:10420000A52C01D193F91D2001241030094B0DF18B +:10421000040C00938CE8150008310FC90CE0000075 +:10422000F40610007807100014750120F80610003D +:10423000048001203C7A0120FFF768FC0120B7E7E9 +:1042400030B55149027987B00B689A4203D142795F +:104250004B689A4201D0002021E64C4A857900241F +:1042600082F81A5CC57982F81B5C857A82F81C5C3E +:10427000C57A82F81D5C057B82F8185C457B82F864 +:10428000195C434A2346126892F82150A52D03D1A8 +:1042900012F9224F92F901303E4A0125103012687E +:1042A000083192F86229CDE9024302F00102CDE91A +:1042B0000452394ACDE900200FC9FFF778FC0120EC +:1042C000EDE52DE9FF410F4615460446002640F274 +:1042D0007A3104F0A5FF2C48012D01782171017974 +:1042E000617106D12A4909688A7EA52A01D191F90E +:1042F0001B6004F11001254BCDE900310022CDE90E +:10430000026200F1080105460FC9FFF7FFFBA52077 +:104310002070102060706780D5E900014843133099 +:10432000800804B0D9E62DE9FF410F461546044642 +:10433000002640F27A3104F073FF1348012D017812 +:1043400021710179617106D1114909680A7FA52A95 +:1043500001D191F91D6004F11001104ACDE900214D +:104360000023CDE9026300F1080105460FC9FFF7FC +:10437000CDFBA5202070112060706780D5E9000179 +:10438000484313308008CCE77807100014750120EB +:10439000F8061000F40610009C8001203C7A0120F1 +:1043A0002DE9F04F47F6FF77DDE909B58146FE4379 +:1043B00001209A4684462C4615E000BF32F814309E +:1043C00031F81480A3EB08031BB2BB4200DA1F468E +:1043D000B34200DD1E46002B02DD4FF0000C02E070 +:1043E00001DA4FF00000641EE8D220B1BCF1000FEA +:1043F00001D0002309E050EA0C0306D020B9BCF13B +:10440000000F01D0334600E03B4600273C462846DB +:10441000CBF1000C0EE000BF32F8106031F81080D4 +:10442000A6EB0806F61A36B2564503DA664501DDF4 +:104430003744641C401EEFD204B9012497FBF4F00A +:10444000184404E031F81520024429F815206D1EA7 +:10445000F8D2BDE8F08FF0B5002306461D46184699 +:104460000EE000BF36F91140002C01DB274600E0CA +:104470006742974204DD002C01DD254400E023441F +:10448000491EEFD2002B00DA5B42AB4200DD012077 +:10449000F0BD30B507E000BF32F8134031F81350DB +:1044A000641B20F813405B1EF6D230BD70B5049C2F +:1044B00009E000BF31F9145032F91460754395FBDF +:1044C000F3F520F81450641EF4D270BDF0B4049CCF +:1044D0001CB913B1C3F110040EE0F0BC520004F09B +:1044E00020BE00BF30F9125031F912605D4306FB67 +:1044F00004552D1120F81250521EF3D2F0BC704713 +:10450000F0B4049C1CB913B1C3F180040EE0F0BCFC +:10451000520004F006BE00BF30F9125031F91260AB +:104520005D4306FB0455ED1120F81250521EF3D2E4 +:10453000E4E7F0B5002B19D0144615E000273E46FD +:10454000E51A04EB030C08E0002D05DB954203DAC5 +:1045500031F915E0761C77446D1CAC45F4DA1EB1D8 +:1045600097FBF6F520F81450641EE7D2F0BD70B545 +:104570000C461546A04204D001466A00204604F0CD +:10458000D0FD002017E00146421C07E034F912601C +:1045900034F911309E4200DA1146521CAA42F5D37A +:1045A000884207D034F8102034F8113024F8103045 +:1045B00024F81120401CB0EB550FE4D9E90725F091 +:1045C000010001D0205E70BD215E204430F9020C54 +:1045D0000844401070BD0346002004E033F9112068 +:1045E000824200DD1046491EF8D2704710B5002403 +:1045F00047F6FF7308E000BF30F91120A24200DD4A +:1046000014469A4200DA1346491EF5D2E01A00B267 +:1046100010BD034647F6FF7005E000BF33F91120D7 +:10462000824200DA1046491EF8D2002800DA002043 +:1046300070470246B0F9000005E000BF32F91130C2 +:10464000834200DD1846491EF8D2704770B5050058 +:1046500003D0BDE8704002F015BAFE4C21466078E8 +:10466000097930B10A46FC4901F1980002F05CFA80 +:104670000BE0207802F038FB21794A00F64901EB83 +:104680004001F548983004F04CFDA078F34E28B175 +:10469000F1482179983002F025FB01E0EE4898308E +:1046A000B062E07886F831002846D2E72DE9F05F65 +:1046B000DFF8ACA383460127DAF80000B84600F221 +:1046C0005E6490F8761990F8725901F01F0690F820 +:1046D000731901F00F0990F86019890609D590F84F +:1046E000541690F855060A2204EB400002F058FADE +:1046F0000746DAF8000090F86019490609D590F8E5 +:10470000C41890F8C5080A2204EB400002F048FAE9 +:1047100080464FF48070854200D905461F2E00D98F +:104720001F26761C754309F101004543C5EB452062 +:104730007843DAF8002000FB08F0C01392F8501A12 +:10474000B0FA80F0C0F12000890611D50021BBF13C +:10475000010F06D192F8561A0A0701F0070100D599 +:104760004942401801D5002002E01F2800DD1F202B +:10477000C0B2BDE8F09FF8B5044602F044FEB6486A +:1047800002F046FEA4F8760002F0F4F9B14A0B46B6 +:10479000127800920246204603F005F902F0EFF984 +:1047A00002460B46204603F034F9204602F0A8FAF0 +:1047B000AB4DB4F856102868B0F8382462F30901FC +:1047C000A4F8561090F8370494F8551060F30301DC +:1047D00084F855100521204602F045FE286890F81F +:1047E0007209A0702868218EB0F8782962F3080158 +:1047F000218690F8730900F00F01204602F0AAFE0E +:10480000286834F81A1FB0F86A2962F30B0124F8FB +:104810001419B0F86829618962F30B016181B0F85D +:104820006619E08861F30B00E08014F8050C20F0B5 +:104830000C0004F8050C2868217B90F8742962F3B9 +:104840000101217390F87429920862F38711217392 +:1048500090F86019627861F30002627090F8630961 +:10486000E070804890F8181C217690F8191CA17708 +:1048700090F81A1C617690F81B1CE17790F81C1CCC +:10488000A17690F81D0C84F82000774802F0C0FD56 +:10489000A4F87A007448203002F0BAFDA4F87E0033 +:1048A000286814F8166F90F86E19090961F3071655 +:1048B00004F8066B90F870192278090961F3071261 +:1048C000227090F86F3914F8051C63F3030104F8A3 +:1048D000051C90F87179637867F30303637090F8AF +:1048E0006F793F0967F3071104F8051C90F87119F7 +:1048F000090961F30713637090F86E1961F30006FC +:1049000004F8066C90F8701961F3000204F822298B +:1049100090F864090109204602F028FE5248483800 +:1049200002F076FDA4F87E004F482734283802F0C4 +:104930006FFDA4F85B00296891F86209820820786D +:1049400062F38300207091F8622962F30000207006 +:1049500091F86229520862F3410004F8010B2078B3 +:1049600020F01000207091F86029D308E27A63F3F8 +:104970004512E27291F8611961F3451004F82809B3 +:10498000204602F08FF9286890F86109C0F34101D0 +:10499000204602F0B9FD296891F86009820914F8EF +:1049A000330F62F3000004F81D0991F860295209E1 +:1049B00062F34100607791F87509E27D60F30402CB +:1049C000E27591F87619A07D61F30400A075224884 +:1049D00094F849100838407860F30401224884F8BC +:1049E0004910E83002F014FDA4F86400286834F897 +:1049F000181FB0F86C2962F30B0124F8041910F8A1 +:104A0000E31F227861F3030204F8012B01780A09FD +:104A1000217862F3030104F8091B90F87D18CA0994 +:104A2000217862F3000104F82B1B14F8571941F0A8 +:104A3000200184F8571090F892184A09217862F3FF +:104A40000611217090F87E184A09217C62F3C30197 +:104A500021740BE09007100064850120748C100015 +:104A6000F406100014750120E480012090F87D0800 +:104A7000400860F304112174F8BD2DE9F0410446AB +:104A8000524D01200129A87008D00026504F02295C +:104A900008D0032914D004292CD13AE0204600F094 +:104AA00091F827E04B48FFF766FE204600F08AF8B1 +:104AB000B87894F85F1060F3040184F85F1014E094 +:104AC0004448FFF758FE204600F07CF8F87894F848 +:104AD0005F1060F3040184F85F1094F8270020F061 +:104AE000020040F0010084F827000021204602F077 +:104AF00031FDAE7094F8270040F30000401CE870D0 +:104B00003548006890F86109C0F380106870BDE80E +:104B1000F081204600F056F8204602F034F9E8E72C +:104B20007CB502F027F8CDE900010821684603F0C2 +:104B3000D5F82649264D08710020286028710124E7 +:104B4000E0B2FFF7B3FD2855641C052CF8DB2148C3 +:104B5000FFF711FE7CBD30B5017AA9B079B3684684 +:104B6000FFF78BFF9DF8120000F0030002F06AF8D7 +:104B7000194C206800F25E6300F6CA0590F85416DE +:104B800090F8550603EB400002F02DF8206890F8ED +:104B9000C41890F8C50805EB400002F03BF80B483C +:104BA000417801B102210170C9B2684602F04BFFA1 +:104BB0000A49684602F07CFF002029B030BDFFE7BB +:104BC0000120FAE7A422034904F0ABBA90071000D1 +:104BD0005C850120A0861000F4061000FD45010050 +:104BE000FE49C868401CC860022803D2FC4951F83D +:104BF00020000047002001F045BF002801D102F04D +:104C000048BF7047F54910B50A790120521CD2B24D +:104C10000A710B7A9A420AD8487A48B102F08AFEA1 +:104C20000320EBF7EDFBEF4802F078FE002010BD0B +:104C300002F02FFFFAE770B514460E46054653B949 +:104C4000A10004F00FFB06E055F8240036F914101B +:104C5000084445F82400641EF6D270BD70B5E24CDD +:104C60006642650C0BE000BF51F82230B34201DB15 +:104C70002B4602E0A34200DA234620F81230521EEF +:104C8000F2D270BD70B518B1BDE8704001F0FABE47 +:104C9000D24C207A08B1D54D01E0D44D763DCF49B4 +:104CA0006079897828B10A46D149284601F03CFF4D +:104CB0000BE0607802F018F8A178C0B24A00CC4945 +:104CC00001EB4001284604F02CFAC8482379A27869 +:104CD00029464E30FFF7AFFFFFF794FF00281CD0A6 +:104CE000C249A2784E31A1F1C400FFF7B7FFA07905 +:104CF000C04D01280BD0BD4876386863E07985F84F +:104D00003E00207985F83C00BDE8704068E7B74870 +:104D1000A178763801F0E6FFEFE770BD70B518B105 +:104D2000BDE8704001F0AEBEAC4C207A08B1AF4D8A +:104D300001E0AE4D4C3DA9496079C97828B10A46D9 +:104D4000AB49284601F0F0FE0BE0607801F0D2FF9D +:104D5000E178C0B24A00A64901EB4001284604F0C0 +:104D6000E0F9A2482379E27829464E30FFF763FF45 +:104D7000FFF748FF00281CD09C49E2784E31A1F192 +:104D80009A00FFF76BFFA0799A4D01280BD0974846 +:104D90004C38A863E07985F83E00207985F83D001D +:104DA000BDE870401CE79148E1784C3801F09BFF6A +:104DB000EFE770BD2DE9FF5FDFF83CB28C460127BD +:104DC000DBF80000109E134690F8491190F844411A +:104DD000C1F3820A90F84811B84601F01F0590F817 +:104DE000451190F8320101F00F09800605D50A221D +:104DF0001946604601F0D4FE0746DBF8000090F843 +:104E00003201400605D50A220E99039801F0C8FE2A +:104E100080464FF48070844200D904461F2D00D98B +:104E20001F256D1C6C4309F101004443C4EB442071 +:104E3000784300FB08F00AF101014843DBF8001059 +:104E4000C013B0FA80F091F8501AC0F12000C906E2 +:104E50000FD5009A0021012A04D10F9909B171429E +:104E600000E03146401801D5002002E01F2800DD97 +:104E70001F2004B0C0B2BDE8F09FF8B5044602F0B0 +:104E8000C2FA5B4802F0C4FAA4F8760001F072FEA0 +:104E9000524E0B46727800920246204602F083FD85 +:104EA00001F06DFE02460B46204602F0B2FD2046A0 +:104EB00001F026FF504DB4F856102868B0F8382499 +:104EC00062F30901A4F8561090F8370494F85510CD +:104ED00060F3030184F855100521204602F0C3FA5F +:104EE000286890F84401A0702868218EB0F84A2103 +:104EF00062F30801218690F8450100F00F01204679 +:104F000002F028FB286834F81A1FB0F83C2162F33D +:104F10000B0124F81219B0F83A21218962F30B0130 +:104F20002181B0F83821A18862F30B01A18090F8AB +:104F30004621A17A62F30101A17290F846219208FC +:104F400062F38711A17290F8321114F8012C61F309 +:104F5000000204F8012C90F835016070274890F8A1 +:104F6000801BA17590F8811B217790F8821BE17559 +:104F700090F8831B617790F8841B217690F8850B5D +:104F8000A0771F4802F044FAA4F878001C482030AB +:104F900002F03EFAA4F87C00286890F840110A0953 +:104FA00014F8141F62F3071104F8061B90F842214D +:104FB0001309227863F30712227090F8417114F8F4 +:104FC000053C67F3030304F8053C90F843C1677898 +:104FD0006CF30307677090F841C113E09807100065 +:104FE000BC970100AB4B01000080FFFF62870120EE +:104FF00054860120748C1000F406100014750120F2 +:105000004C8001204FEA1C1C6CF3071304F8053C8C +:1050100090F843311B0963F30717677090F840312C +:1050200063F3000104F8061C90F8421161F30002DA +:1050300004F8222990F836010109204602F096FA78 +:10504000F94802F0E5F9A4F87E00F748273420304B +:1050500002F0DEF9A4F85B00296891F834018208B7 +:10506000207862F38300207091F8342162F300000D +:10507000207091F83421520862F3410004F8010BCA +:10508000207820F01000207091F83221D308E27AC5 +:1050900063F34512E27291F8331161F3451004F89D +:1050A0002809204601F00BFE286890F83301C0F370 +:1050B0004101204602F028FA286890F832118A0946 +:1050C00014F8331F62F3000104F8071990F8322135 +:1050D000520962F34101E17190F84711627861F37E +:1050E0000402627090F84801217860F30401217095 +:1050F000CE4802F08DF9A4F84E00286834F8021F5B +:10510000B0F83E2162F30B0124F8181910F8E31FE0 +:10511000227D61F30302227510F8451B0A09617DA7 +:1051200062F303016175817ACA09A17F62F300010C +:10513000A17794F8491041F0200184F84910C17F0B +:105140004A0914F80E1C62F3061104F80E1CC17A09 +:105150004A09A17862F3C301A170827A520862F30E +:105160000411A170C07AC0F380107071F8BDA42240 +:10517000AF4903F0D6BF2DE9F041AE4C0026012720 +:105180002671A77126720D466672012806D0022884 +:1051900025D0032814D004282CD133E00846FFF78B +:1051A000E6FFA548016891F83701820622D591F8FB +:1051B00049110006C1F3820121721BD5677219E003 +:1051C0009B48FFF75AFE2846FFF7D1FF95F82700C6 +:1051D00020F0020040F0010085F8270005E0944827 +:1051E000FFF74BFE2846FFF7C2FF0021284602F0DA +:1051F000B1F9A67195F8270040F30000401CE0715A +:10520000BDE8F0810846FFF7B2FF284601F0BBFD7C +:10521000EFE770B5884D286800F25E6200F6CA04B8 +:1052200090F85A1690F85B0602EB400001F0DBFCA8 +:10523000286890F8C01890F8C10804EB4000BDE859 +:10524000704001F0E7BC70B57B4D286800F25E62EB +:1052500000F6CA0490F85C1690F85D0602EB400078 +:1052600001F0C1FC286890F8C21890F8C30804EB5C +:105270004000BDE8704001F0CDBC70B56D4D6C4C88 +:105280006879A43400B10220687021462878FFF7BD +:1052900072FF694928780A68A17C92F8463163F365 +:1052A0000101A17492F84621920862F38711A1745A +:1052B0006249085C94F85F1060F3040184F85F10A1 +:1052C0006978204602F0BFFBA07C00F0030001F0EB +:1052D000B9FCFFF79EFF2046BDE87040584902F038 +:1052E000E7BB70B5534D524C6879A43408B1032024 +:1052F00000E00120687021462878FFF73CFF4E4906 +:1053000028780A6892F846110B09A17C63F3010121 +:10531000A17492F84621920962F38711A17447495A +:10532000491D085C94F85F1060F3040184F85F1075 +:105330006978204602F087FBA07C00F0030001F0B2 +:1053400081FCFFF780FF2046BDE870403D4902F038 +:10535000AFBB2DE9F043384F89B03D6805F25E667A +:1053600005F6CA0501F006FCCDE9040101F007FCD1 +:10537000CDE90601082104A802F0B0FC2D4C08215B +:10538000A07006A802F0AAFCDFF8B080E07001244B +:1053900008F10509386890F8581A90F8C03801F0FB +:1053A0000702C1F3C0010093CDE9011290F8C118C2 +:1053B00090F85A2690F85B0605EB410306EB400196 +:1053C000E0B2FFF7F7FC08F80400386890F8581AC4 +:1053D00090F8C238C1F30212C9090093CDE9011255 +:1053E00090F8C31890F85C2690F85D0605EB410331 +:1053F00006EB4001E0B2FFF7DDFC09F80400641C95 +:10540000052CC7DB0A48FFF738FD09B0BDE8F0837B +:1054100010B5C07AC0B1074908704FF0FF30C860BE +:10542000FFF7DEFB002010BD04800120CC810120AD +:105430004487100098071000F406100048860120E9 +:10544000354C0100CD4C01000120ECE710B5040003 +:1054500003D0BDE8104001F015BB25482549007870 +:10546000420001EB40012348983003F05AFE2148E6 +:105470002149983048622046EBE71CB501F07AFBE1 +:10548000CDE900010821684602F028FC18491B4CB0 +:105490000870204600F0D5FA164801F0B9FFA4F8CC +:1054A000760017480168A07C91F8462162F301005C +:1054B000A07491F84611890861F38710A0741CBD8F +:1054C00010B50E4CC07980B1A07C00F0030001F053 +:1054D000B9FB00F008FB0421204602F0B4FA0949A8 +:1054E000204602F0E5FA002010BD012010BD0000AA +:1054F000A807100048880120748C10008C881000C8 +:10550000F4061000FD530100FE49C868401CC86045 +:10551000022803D2FC4951F820000047002001F086 +:10552000B1BA002801D102F0B4BA7047F54910B5FC +:105530000A790120521CD2B20A710B7A9A420AD817 +:10554000487A48B102F0F6F90320EAF759FFEF482C +:1055500002F0E4F9002010BD02F09BFAFAE770B502 +:1055600018B1BDE8704001F08DBAE64C207A08B160 +:10557000E74D01E0E64D763DA078E649820001F571 +:10558000AE7003F013FE607928B1A278E149284695 +:1055900001F0CAFA0CE0A178607801F0A5FBA178CF +:1055A000C0B24A00DB4901EB4001284603F0B9FDD7 +:1055B000D7482379A2782946763801F0C6FAFFF752 +:1055C000B5FF002815D0A079D34D01280BD0D048C5 +:1055D0007638A861E07985F83000207985F82000D8 +:1055E000BDE8704090E7CA48A178763801F07AFBB0 +:1055F000EFE770BD70B518B1BDE8704001F042BA78 +:10560000C04C207A08B1C24D01E0C14D4C3DE0785C +:10561000C049820001F5D87003F0C8FD607928B157 +:10562000E278BC49284601F07FFA0CE0E178607826 +:1056300001F060FBE178C0B24A00B64901EB4001DD +:10564000284603F06EFDB2482379E27829464C38AB +:1056500001F07BFAFFF76AFF002815D0A079AE4D64 +:1056600001280BD0AA484C38E861E07985F8300071 +:10567000207985F82100BDE8704045E7A448E1782D +:105680004C3801F030FBEFE770BD2DE9FF5FDFF82C +:105690008CB28C460127DBF80000109E134690F870 +:1056A000491190F8444101F0030A90F84811B846B6 +:1056B00001F01F0590F8451190F8320101F00F0933 +:1056C000800605D50A221946604601F069FA0746A8 +:1056D000DBF8000090F83201400605D50A220E9949 +:1056E000039801F05DFA80464FF48070844200D93F +:1056F00004461F2D00D91F256D1C6C4309F10100C4 +:105700004443C4EB4420784300FB08F00AF1010154 +:105710004843DBF80010C013B0FA80F091F8501A3B +:10572000C0F12000C9060FD5009A0021012A04D13A +:105730000F9909B1714200E03146401801D50020AF +:1057400002E01F2800DD1F2004B0C0B2BDE8F09FBA +:10575000F8B5044601F057FE6E4801F059FEA4F872 +:10576000760001F007FA674E0B4672780092024607 +:10577000204602F018F901F002FA02460B462046D4 +:1057800002F047F9204601F0BBFA644DB4F8561018 +:105790002868B0F8382462F30901A4F8561090F88C +:1057A000370494F8551060F3030184F8551005216F +:1057B000204601F058FE286890F84401A07028683F +:1057C000218EB0F84A2162F30801218690F8450144 +:1057D00000F00F01204601F0BDFE286834F81A1FC2 +:1057E000B0F83C2162F30B0124F81219B0F83A2109 +:1057F000218962F30B012181B0F83821A18862F37D +:105800000B01A18090F84621A17A62F30101A172F7 +:1058100090F84621920862F38711A17290F8321134 +:1058200014F8012C61F3000204F8012C90F8350102 +:1058300060703B4890F8801BA17590F8811B217720 +:1058400090F8821BE17590F8831B617790F8841BB8 +:10585000217690F8850BA077324801F0D9FDA4F8A5 +:1058600078003048203001F0D3FDA4F87C0028688F +:1058700090F840110A0914F8141F62F3071104F894 +:10588000061B90F842211309227863F30712227055 +:1058900090F8417114F8053C67F3030304F8053CE4 +:1058A00090F843C167786CF30307677090F841C1C3 +:1058B0004FEA1C1C6CF3071304F8053C90F84331C5 +:1058C0001B0963F30717677090F8403163F3000119 +:1058D00004F8061C90F8421161F3000204F8222932 +:1058E00090F836010109204601F040FE0D48483885 +:1058F00001F08EFDA4F87E000A482734283801F014 +:1059000087FD11E0AC071000C4970100D3540100DB +:10591000468A012038890120748C1000F40610009A +:10592000147501204C800120A4F85B00296891F8CF +:1059300034018208207862F38300207091F83421CA +:1059400062F30000207091F83421520862F34100A4 +:1059500004F8010B207820F01000207091F832211B +:10596000D308E27A63F34512E27291F8331161F3DE +:10597000451004F82809204601F082F9286890F8BB +:105980003301C0F34101204601F0BEFD286890F8C4 +:1059900032118A0914F8331F62F3000104F8071961 +:1059A00090F83221520962F34101E17190F84711F8 +:1059B000627861F30402627090F84801217860F324 +:1059C00004012170CC4801F023FDA4F84E002868A2 +:1059D00034F8021FB0F83E2162F30B0124F81819C5 +:1059E00010F8E31F227D61F30302227510F8451BB6 +:1059F0000A09617D62F303016175817ACA09A17F99 +:105A000062F30001A17794F8491041F0200184F875 +:105A10004910C17F4A0914F80E1C62F3061104F8FC +:105A20000E1CC17A4A09A17862F3C301A170827A7F +:105A3000520862F30411A170C07AC0F38010707133 +:105A4000F8BDA422AD4903F06CBB2DE9F041AC4C8C +:105A5000002601272671A77126720D46667201285D +:105A600006D0022825D0032814D004282CD133E0F6 +:105A70000846FFF7E6FFA348016891F837014206A0 +:105A800022D591F84911000601F0030121721BD5BE +:105A9000677219E09948FFF75BFE2846FFF7D1FFD0 +:105AA00095F8270020F0020040F0010085F827005B +:105AB00005E09248FFF74CFE2846FFF7C2FF0021A1 +:105AC000284601F047FDA67195F8270040F3000035 +:105AD000401CE071BDE8F0810846FFF7B2FF2846A0 +:105AE00001F051F9EFE770B5864D286800F25E626B +:105AF00000F6CA0490F8501690F8510602EB4000E8 +:105B000001F071F8286890F8C01890F8C10804EB0B +:105B10004000BDE8704001F07DB870B5794D28684F +:105B200000F25E6200F6CA0490F8521690F853062E +:105B300002EB400001F057F8286890F8C21890F87E +:105B4000C30804EB4000BDE8704001F063B870B5D5 +:105B50006B4D6A4C6879A43400B10220687021460C +:105B60002878FFF772FF674928780A68A17C92F8C5 +:105B7000463163F30101A17492F84621920862F361 +:105B80008711A1746049085C94F85F1060F3040108 +:105B900084F85F106978204601F055FFA07C00F082 +:105BA000030001F04FF8FFF79EFF2046BDE870406C +:105BB000564901F07DBF70B5514D504C6879A43401 +:105BC00008B1032000E00120687021462878FFF723 +:105BD0003CFF4C4928780A6892F846110B09A17CD1 +:105BE00063F30101A17492F84621920962F38711CF +:105BF000A1744549491D085C94F85F1060F30401E5 +:105C000084F85F106978204601F01DFFA07C00F049 +:105C1000030001F017F8FFF780FF2046BDE8704051 +:105C20003B4901F045BF2DE9F041364E88B035685B +:105C300005F25E6500F09EFFCDE9040100F09FFFD4 +:105C4000CDE90601082104A802F048F82C4C0821EF +:105C5000A07006A802F042F82B4FE070012407F173 +:105C60000508306890F8551A90F8C03801F007021E +:105C7000C1F3C0010093CDE9011290F8C11890F86A +:105C8000502690F8510605EB410305EB4001E0B2C8 +:105C9000FFF7FBFC3855306890F8551A90F8C23879 +:105CA000C1F30212C9090093CDE9011290F8C3189B +:105CB00090F8522690F8530605EB410305EB40019E +:105CC000E0B2FFF7E2FC08F80400641C052CC8DB16 +:105CD0000A48FFF73DFD08B0FCE610B5807940B1F9 +:105CE000074908704FF0FF30C860FFF70DFC002037 +:105CF00010BD012010BD0000CC81012030891000B2 +:105D0000AC071000F40610002C8901200F5501008B +:105D1000A555010010B9714A6F49116100F0B2BE7A +:105D200070B56F4D0446286890F8F101C0F3011278 +:105D3000C0F3810100F00300FDF7B0FB401CC6B2C8 +:105D4000204600F033FC644801F062FBA4F87600C2 +:105D500000223146204601F061FDA07940F00200AA +:105D6000A07194F86F0066F3020084F86F0094F855 +:105D70006E0020F00F0084F86E002968A07C91F876 +:105D8000082162F30100A07491F80821920862F3DF +:105D90008710A074A0896FF30B00A08191F8070110 +:105DA000A07094F85E00002120F0010084F85E00ED +:105DB000204601F0CFFB286890F8F21184F86610B5 +:105DC00090F8F31184F8681090F8F41184F86A10D0 +:105DD00090F8F50184F86C003F4894F85F10001FBC +:105DE000407860F3040184F85F102046BDE87040FD +:105DF00000F03ABF10B5384C0020241F208001204D +:105E000000F02FF86070BDE81040364888E72DE9B3 +:105E1000F041344E407910B3B07C00F0030000F044 +:105E200011FF2F4F3C6804F25E6094F84B2604F695 +:105E3000CA0594F84A1600EB420000F0D4FE386818 +:105E400090F8BA1890F8BB0805EB400000F0E2FEAD +:105E50002549304601F022FD0020BDE8F0810120F7 +:105E6000FBE730B51E494FF480750A6892F80711B8 +:105E700092F8F43092F8F14003F01F0304F00F049D +:105E8000A94200D929461F2B00D91F235B1C594367 +:105E90004900641C6143C1EB4121C91392F8503A97 +:105EA000B1FA81F1C1F120019B0713D5002301282C +:105EB00009D192F8540A020703D500F007004342C3 +:105EC00001E000F00703C91801D5002102E01F29F5 +:105ED00000DD1F21C8B230BD848B0120748C1000FE +:105EE000F4061000788A1000C55C01002DE9F05F0F +:105EF000DFF8A48583464FF00109D8F80000002799 +:105F0000ABF1020100F25E64CA46062950D2DFE816 +:105F100001F04F092C4F2C0310F8D46F007900F0DA +:105F20001F056DE090F8F41090F8026101F01F0574 +:105F300090F8F11001F00F0790F8E610890609D5E6 +:105F400090F84C1690F84D060A2204EB400000F041 +:105F500027FE8146D8F8000090F8E61049064FD594 +:105F600090F8BC1890F8BD0844E090F8FC1090F848 +:105F7000F86001F01F0590F8F91001F00F0790F894 +:105F8000E610890609D590F84E1690F84F060A22B9 +:105F900004EB400000F004FE8146D8F8000090F8C1 +:105FA000E61049062CD590F8BE1890F8BF0821E0FD +:105FB00090F8F41090F8F06001F01F0590F8F110DF +:105FC00001F00F0790F8E610890609D590F84A16F7 +:105FD00090F84B060A2204EB400000F0E1FD8146F8 +:105FE000D8F8000090F8E610490609D590F8BA18DC +:105FF00090F8BB080A2204EB400000F0D1FD824675 +:106000004FF48070864200D906461F2D00D91F2507 +:106010006D1C6E4370007F1C7843C0EB402000FB7A +:1060200009F000FB0AF0C013D8F80020B0FA80F0A5 +:10603000C0F1200192F8500AC00725D00020BBF122 +:106040000A0F13D2DFE80BF01205080B161212121A +:10605000120592F8510A04E092F8510A0CE092F805 +:10606000520A020700F0070000D54042091808D57F +:10607000002109E092F8520A0206C0F30210F4D49B +:10608000F4E71F2900DD1F21C8B2BDE8F09F70B5FD +:10609000060003D0BDE8704000F0F4BC00F018F832 +:1060A000012814D1FD4DFE4C2878012809D0FD4867 +:1060B000A0606878E073E878A0732889A0813046F2 +:1060C000E8E76A792979F74800F00BFEF0E770BD40 +:1060D000F24B10B5D978F44C491CCAB2DA709978F1 +:1060E00001208A420ED8197958794143ED48FDF7CD +:1060F000F4F901F08DF9A4F87600EC49204601F09E +:10610000CDFB002010BD38B5044601F07CF9E54810 +:1061100001F07EF9A4F8760000F02CFDDE4D0B4670 +:106120002A6892F8E720C2F3411200920246204604 +:1061300001F053FB00F023FD02460B46204601F020 +:1061400078FBA07920F00200A07194F86F0020F095 +:10615000070084F86F0094F86E0020F00F0084F8B8 +:106160006E00286890F8E700C0F34111204601F066 +:106170007AFB286890F8E70010F0600F94F85E0052 +:106180007ED040F0010000BF84F85E00204600F0A1 +:10619000B7FD0521204601F066F9286890F8F00067 +:1061A000A0702868218EB0F8F62062F308012186DD +:1061B00090F8F10000F00F01204601F0CBF92868BB +:1061C000627D90F8EA1061F303026275B0F8EC208A +:1061D000218A62F30B01218290F8F210A27D61F313 +:1061E0000302A27510F8F11F0A09A17C62F30101F4 +:1061F000A17410F80B29920962F38711A174017838 +:10620000E27961F30002E271C178617200790109FB +:10621000204601F0ABF9A64801F0FAF8A4F87C009A +:10622000296811F8E80F820814F8270F62F3830039 +:10623000207011F8012962F3000020704A7852089A +:1062400062F34100207008780109607861F304105E +:106250006070984801F0DCF8A4F85F00286810F836 +:10626000E61FCA0814F80C1F62F3451104F80B1955 +:106270004078217860F3451104F82819204600E0A1 +:106280005CE000F0F1FC286890F8E700C0F3410101 +:10629000204601F039F9286810F8E61F8A0914F839 +:1062A000331F62F3000104F80B190278520962F3FC +:1062B0004101E172417B627961F304026271807B8A +:1062C000217960F304017C48217194F837104078FB +:1062D00060F3040184F83710784801F099F8A4F8C5 +:1062E0005200286834F8061FB0F8EE2062F30B0164 +:1062F00024F8061B10F8E21F14F80A2C61F30302BD +:1063000004F80A2C01780A0914F8091C62F3030145 +:1063100004F8091C01798A0814F80C1C62F30001C6 +:1063200004F80C1C0079C109207861F3000004F81E +:106330002B0B207840F02000207038BD20F00100A9 +:1063400022E738B5044601F05EF8564801F060F8DF +:10635000A4F8760000F00EFC4F4D0B462A6892F828 +:10636000C920C2F3411200920246204601F035FADC +:1063700000F005FC02460B46204601F05AFAA079CF +:1063800020F00200A07194F86F0020F0070084F85C +:106390006F0094F86E0020F00F0084F86E002868FB +:1063A00090F8C900C0F34111204601F05CFA28685A +:1063B00090F8C90010F0600F94F85E006BD040F0C8 +:1063C000010000BF84F85E00204600F099FC2868B8 +:1063D00090F8D400A0702868218EB0F8DA2062F31B +:1063E0000801218690F8D50000F00F01204601F049 +:1063F000B1F82868627D90F8CC1061F303026275F1 +:10640000B0F8CE20218A62F30B01218290F8D610D9 +:10641000A27D61F30302A275B0F8D020A18962F3D6 +:106420000B01A18110F8D51F0A09A17C62F30101BB +:10643000A17410F80D29920962F38711A1740178F3 +:10644000E27961F30002E271C178617200790109B9 +:10645000204601F08BF8164800F0DAFFA4F87C0023 +:10646000296811F8CA0F820814F8270F62F3830015 +:10647000207011F8012962F3000020704A78520858 +:1064800062F34100207008780109607861F304101C +:106490006070084814E086E0F4061000BC071000A5 +:1064A000748C1000B48C0120C08B10003F60010080 +:1064B00014750120EC840120B6A50120CC810120B7 +:1064C00000F0A6FFA4F85F00286810F8C81FCA08EB +:1064D00014F80C1F62F3451104F80B194078217869 +:1064E00060F3451104F82819204600F0BDFB286828 +:1064F00090F8C900C0F34101204601F005F8296871 +:1065000011F8C80F820914F8330F62F3000004F881 +:106510000B090A78520962F34100E072C87B627984 +:1065200060F304026271087C217960F30401F5488C +:10653000217194F83710C07960F3040184F83710A2 +:10654000F14800F065FFA4F85200286834F8061FEF +:10655000B0F8D22062F30B0124F8061B10F8E21FFA +:1065600014F80A2C61F3030204F80A2C10F81A1923 +:106570000A0914F8091C62F3030104F8091C0178E4 +:106580008A0814F80C1C62F3000104F80C1C007853 +:10659000C109207861F3000004F82B0B207840F04B +:1065A0002000207038BD20F001000BE710B5044634 +:1065B000A422D64902F0B5FDD548C178A08961F37F +:1065C0000B00A08110BD38B50446FFF7EFFF00F0C7 +:1065D000D1FA0022009202460B46204601F0FDF857 +:1065E000CC4800F015FFCC4DA4F87C00286890F84A +:1065F000F800A070286890F8F90000F00F0120461C +:1066000000F0A8FF286810F8F91F0A09A17C62F3BE +:106610000101A1740278920962F38711A174817853 +:1066200094F82D2061F3040284F82D20C17894F8A9 +:106630002C2061F3040284F82C204078A17D60F3C3 +:106640000301A1750021204601F00DF914F85E0F39 +:1066500020F0010004F8010BAA480179207861F3C9 +:10666000040004F82F092868B0F8FE10208861F3B0 +:106670000800208038BD70B5A74E0328346804F2A6 +:106680005E6204F6CA0515D0042821D094F84B06A2 +:1066900094F84A1602EB400000F0A5FA306890F832 +:1066A000BA1890F8BB0800BF05EB4000BDE8704089 +:1066B00000F0B0BA94F84D0694F84C1602EB400086 +:1066C00000F091FA306890F8BC1890F8BD08EBE73C +:1066D00094F84F0694F84E1602EB400000F083FA4F +:1066E000306890F8BE1890F8BF08DDE72DE9F84350 +:1066F0008A4D4FF00109002685F80090AE70814F59 +:10670000DFF814820446EE700A2976D2DFE801F041 +:106710007505091848334C62662F2046FFF746FF7F +:106720006BE02046FFF742FFB87894F85F1060F303 +:10673000040184F85F10D8F8000090F8000112E01E +:106740002046FFF733FFD8F8001091F80211A1702E +:10675000F97894F85F2061F3040284F85F20D8F898 +:10676000000090F8010100F00300A87045E0204609 +:1067700000F09DF841E02046FFF718FF0021204679 +:1067800000F0E8FE94F85E0020F0010084F85E005E +:10679000787994F85F1060F3040184F85F1017E0D3 +:1067A0002046FFF710FF28E02046FFF70CFF0021EE +:1067B000204600F0CFFEB87994F85F1060F3040132 +:1067C00084F85F1094F85E0020F0010084F85E0009 +:1067D0002E7012E02046FFF7B4FDF9E72046FFF7E0 +:1067E000E5FE012200232046009600F0F6FF204639 +:1067F00000F0C9FA204600F037FA94F82700C007E5 +:1068000001D06E7001E085F80190A089C0F30B0003 +:106810002881BDE8F8832DE9FF4100F0ABF9CDE90F +:10682000000100F0ACF9CDE902010821684601F051 +:1068300055FA3A4D0821287102A801F04FFA687103 +:1068400030480026801E2F4F40F8026F012446601A +:106850000681E0B2FFF74AFB3855641C0A2CF8DBCE +:106860002A48FFF750FCAE71BDE8FF8170B5274D97 +:106870000479A4358CB121462846FFF737FFA87C60 +:1068800000F0030000F0DEF92046FFF7F4FE244993 +:10689000284601F003F8002070BD012070BD40F2D1 +:1068A000FF10C1EB412191FBF0F00020704770B563 +:1068B0000446FFF77BFE1848184A016801F5F97392 +:1068C00091F8F10100F0030592F90600854206DB1C +:1068D0001D5CA389401C65F30B03A381907191F8A3 +:1068E000F10192F9061000F00300884201DA00205D +:1068F0009071044814F85F1F407A60F3040121701E +:1069000070BD0000B6A50120CC8101201C8B1000B9 +:10691000280710003C7A0120F4061000BC07100084 +:106920003F60010010B500F07BFAFFF774FFFFF73E +:1069300061FAFFF778F9FEF70CFDFEF7F1F8FEF7C4 +:106940009CFD7449002048607021734802F068FC87 +:106950007248016891F8E700C00607D5BDE810400D +:1069600028226D4801F52E6102F0DBBB10BD38B165 +:10697000012807D0022807D017200021FBF727BEE7 +:106980001420FAE71520F8E71620F6E70021016049 +:1069900041608160C160704770B55E4C604D206899 +:1069A00009E000BF55F820105E488847002811D044 +:1069B0002068401C20600828F4D360685949401CB6 +:1069C0001031002260600A7048605648016810303B +:1069D0008847012070BD70B504460079002550B984 +:1069E000E07940B9A07930B9E07A20B9207A10B9BD +:1069F000607900280ED04B484021103002F032FC64 +:106A00001ECC484880E81E00424805604548FFF714 +:106A1000C3FF012070BD10B5012000F064F807200D +:106A200000F061F8082000F05EF8052000F05BF847 +:106A30000D2000F058F80C2000F055F8012000F06F +:106A40005DF8072000F05AF8082000F057F80520FC +:106A500000F054F80D2000F051F80C2000F04EF832 +:106A600002F079F800F0C7FC012000F031F80720AF +:106A700000F02EF8082000F02BF8BDE810400520AB +:106A800000F026B870B5234C05000ED0FFF7C3FF09 +:106A900060682449401C103160600D7048602148D6 +:106AA0000168BDE87040103008472068401C206035 +:106AB000BDE870401B486FE700F05CB800F05FB8BD +:106AC00000F062B800F066B800F054B800F057B8B3 +:106AD00000F01F02012191404009800000F1E020F8 +:106AE000C0F80011704700F01F02012191404009D9 +:106AF000800000F1E020C0F88011704700F01F0214 +:106B0000012191404009800000F1E020C0F880128E +:106B100070470000C8071000EC840120F406100044 +:106B2000CC970100648C100070B50023144609E076 +:106B300031F9135031F9146035446D1020F81350B9 +:106B40005B1C641C9342F3DB70BD30B400244BB972 +:106B50000CE000BF30F8143031F814502B4420F80A +:106B60001430641C9442F5DB30BC704730BC5200DA +:106B700002F0D7BAA3480068C16A806A7047A1488A +:106B80000068416A006A70479E48006800F6382035 +:106B900003C870479B48006800F5236003C870472E +:106BA000F0B500242546984E4FF4006714E000BF6E +:106BB00030F81530C3F30B035FEAD32C00D0334316 +:106BC000002B00DA5B429C4200DA9CB2BC4202D34A +:106BD00040F2FF7402E06D1C8D42E9DBD4400120DD +:106BE000A04080B2F0BD30B5894B884C5A688242D3 +:106BF00002D1DA688A420AD0002206E030F8125048 +:106C0000C5F30B0524F81250521C8A42F6DBD960FA +:106C1000586030BD30B57E4B7E4C9A68824202D1BE +:106C20001A698A420DD0002207E000BF30F81250E6 +:106C3000C5F30B0524F81250521C8A42F6DB196189 +:106C4000986030BD70B504467348016802290AD1C6 +:106C50006F4D29788C4206D000EB8400D0F89C0060 +:106C600000F0E9FB2C7070BD10B5044690F82800C8 +:106C7000800604D5694800F0CBFBA4F88C0010BD59 +:106C800010B5044690F8280080060AD563482830DD +:106C900000F0BEFB24F88E0F6048483000F0B8FBCF +:106CA000608010BD10B5044690F82800800605D518 +:106CB0005A48703000F0ACFBA4F88E0010BD10B53F +:106CC000044690F8280080060AD55448903000F019 +:106CD0009FFB24F88E0F5148B03000F099FB608084 +:106CE00010BD70477047704702004FF0000000D1A0 +:106CF0000846704702460020012A00D10846704726 +:106D000040490A6892F82824930910F83E2B63F34F +:106D1000820200F83E2C0B6893F828345B0963F379 +:106D2000451200F83E2C0968B1F82F24028291F830 +:106D30002E24837F62F30713837791F82B241309A2 +:106D4000027D63F306120275B1F82934028B63F3F6 +:106D50000902028391F828249308827D63F3861246 +:106D6000827591F82B24C37D62F30303C375B1F8D8 +:106D70002C34B0F81B2063F30802A0F81B20B1F8F4 +:106D800031144182704710F8371F41F0100100F8AC +:106D90001F1930F80C2CC17E6FF30B02103220F853 +:106DA0000C2C30F8082C21F023016FF30B02403239 +:106DB00020F8082C082200F8162C90F8472041F003 +:106DC0000C0122F01F0280F84720028B6FF30802AB +:106DD0000283C176C18A6FF30B013F31C182417DCD +:106DE00021F01F014175017D21F01F01017590F80F +:106DF000461021F0010180F84610017C41F020018D +:106E000001747047F406100000F0FFFFCC810120F0 +:106E1000D0071000CC830120B48C10001484012012 +:106E2000704710B500F091FD08B1012010BD084871 +:106E300000F074FD002010BD064810B5006890F801 +:106E4000A000400701D500F075FD012010BD000035 +:106E5000356A0100F40610003D48016821F0040184 +:106E6000016000F003BF10B5FFF7F6FF10BD10B5CD +:106E7000FFF7F2FF10BD10B5FFF7EEFF10BD10B524 +:106E8000FFF7EAFF01F035FC10BD10B5FFF7E4FF96 +:106E900000F0DEFA10BD10B5FFF7DEFF01F03FFD98 +:106EA00010BD10B5FFF7D8FF01F0A4FD10BD10B55F +:106EB000FFF7D2FF01F009FE10BD10B5FFF7CCFFC0 +:106EC00001F070FE10BD10B5FFF7C6FF01F0E9FE3E +:106ED00010BD10B5FFF7C0FF01F050FF10BD10B599 +:106EE000FFF7BAFF01F0B7FF10BD10B5FFF7B4FF11 +:106EF00002F090FA10BD10B5FFF7AEFF02F066FA8F +:106F000010BD10B5FFF7A8FF10BD10B5FFF7A4FF27 +:106F100010BD10B5FFF7A0FF10BD10B5FFF79CFF27 +:106F200001F0E0FF10BD10B5FFF796FF10BD10B5E2 +:106F3000FFF792FF10BD10B5FFF78EFF10BD10B523 +:106F4000FFF78AFF10BD10B5FFF786FF10BD704731 +:106F500010ED00E00EB50BA207CA8DE807000C4843 +:106F600000F02DFE684600F02EFEFCF705F9FBF759 +:106F700047FF00F037F800214720FBF728FB0120EE +:106F80000EBD000004000000000000000000000032 +:106F9000540016201A4910B5012008701949002024 +:106FA000086019490860194908601949086000F02B +:106FB0007FF900F019F900F07DF8002010BD10B540 +:106FC000124802F021F8104908600E490968884209 +:106FD00007D00B480078022803D1BDE81040E9F73C +:106FE000C5B910BD10B5FFF7EAFF054902200870CA +:106FF000E9F7A0F94FF0FF3010BD01207047000005 +:107000002C08100030081000340810003808100058 +:107010003C08100070B50D460446C1698068CC225A +:1070200002F0F6F8E169A068002208444FF0807190 +:1070300040F8041C216A40E9032140F8102C40F874 +:10704000142C40F8182C40F81C2C4FF00B3140E960 +:1070500009154FF00A3140F8281C4FF0093140F86B +:107060002C1C4FF0083140F8301C4FF0073140F82D +:10707000341C4FF0063140F8381C4FF0053140F811 +:107080003C1C4FF0043140F8401D70BD81694FF049 +:10709000CC330A689A4208D14A689A4205D18A6874 +:1070A0009A4202D1C968994202D04068FBF7EFBE0C +:1070B0007047000010B5A021494802F0D3F8002025 +:1070C00010BD70B50646464800EB0614E9F786F990 +:1070D0000546207828B12846E9F788F96FF00100C5 +:1070E00070BD0320207000206660E06004F108009D +:1070F00001F064FF2846E9F779F9002070BD2DE919 +:10710000F0410F463649002501EB00142E46E9F701 +:1071100065F98046E0683843E06004F108000746FE +:1071200001F072FF0CE0E168C26A114203D000F086 +:107130000FF9012600E06D1C2946384601F05AFF80 +:107140000028F0D10EB1FFF73AFF4046E9F74EF9BB +:107150000020BDE8F08170B50D46214901EB001417 +:10716000E9F73CF9E168A943E160E9F73FF900205C +:1071700070BD70B50C461A4901EB00150020206067 +:10718000E9F72CF9E9682160E9F730F9002070BDD2 +:107190002DE9F0410D4612491E46904601EB0014C0 +:1071A000E9F71CF907460F480068C562E168294203 +:1071B00003D104F1080100F0DDF83846E9F716F9CB +:1071C000E9F70CF9E16829403160B8F1010F02D10B +:1071D000E168A943E160E9F709F90020B9E7000097 +:1071E000608D10003008100010B5C8212E4802F044 +:1071F00039F8002010BD2DE9F04106462A4900EB80 +:107200008600174601EB8004E9F7E8F80546207888 +:1072100030B12846E9F7EAF86FF00100BDE8F081E7 +:107220000220207000206660C4E9027004F11000A2 +:1072300001F0C4FE2846E9F7D9F80020EEE770B562 +:10724000194900EB800001EB8004E9F7C7F8054617 +:10725000D4E90201814205DB144804F11001006801 +:1072600000F088F8E068401CE0602846E9F7BEF8C6 +:10727000002070BD70B50C4900EB800001EB80046C +:10728000E9F7ACF80546E06808B1401EE06004F19B +:10729000100001F0B9FE10B1206900F011F8284685 +:1072A000E9F7A4F8002070BD008E1000300810002F +:1072B00010B54FF4F0713C4801F0D4FF002010BD30 +:1072C00010B5044690F8240002280BD0204601F0A7 +:1072D0009DFE022084F824003449204601F072FE0D +:1072E000FFF76DFE002010BD2DE9F05F06460AA8ED +:1072F00006EB460190E8000E2B481D4600EB0114FA +:107300009046207818B16FF00100BDE8F09FE9F7D2 +:1073100065F8074601202070C4F81480C4E90165AF +:1073200004F11801002081E8200684F82400E060C0 +:107330002061C4E90A8059462046FFF76BFEA06031 +:107340002046FFF7BDFF3846E9F750F80020DCE79C +:1073500010B5044690F82400022809D0204601F018 +:1073600055FE022084F824001049204601F02AFE30 +:10737000002010BD70B5044690F824000D46022888 +:107380000BD1204601F042FE032084F82400294658 +:10739000204601F017FEFFF712FE002070BD0448E2 +:1073A0000068406870470000C88E10003808100060 +:1073B00030081000724810B50021016001220260FF +:1073C0000160704C6920A0710420E9F719F80820C9 +:1073D000A07110BD10B5FFF7EDFF6B4800210170E3 +:1073E000416000F0F6F9BDE8104000F0D8BA01F0B5 +:1073F0009EBC01F009BD10B501F006FD01F097FC3F +:10740000BDE81040E6E7A422604901F08ABE70475B +:1074100010B50446800702D00220FFF7A8FA4FF407 +:1074200080302044C0F34F0010BD014655489822DB +:10743000A43001F076BE534AA432002142F8210064 +:10744000491C2629FADB704701F0BBBC01F039BCAE +:107450004D4810B5406810B1BDE81040004700200D +:10746000FFF785FA10BD062937D2DFE801F01124B5 +:1074700037243603017821F0120100F84D1B017802 +:1074800021F0030100F8071B017821F080010CE0D6 +:10749000017821F0020141F0100100F84D1B017844 +:1074A00021F0030100F8071B12E000F8441B0178EB +:1074B00021F0010110E00278012942F0120202706D +:1074C00000D0032110F84D2F61F3010200F8072BC3 +:1074D000017841F08001E8E701707047017821F000 +:1074E000020141F0100100F84D1B017821F0030169 +:1074F000891C00F8071B017841F0800100F8441B4B +:10750000017841F00101E7E790F82920022904D031 +:10751000032922F0400102D104E042F0400121F0B1 +:10752000800101E041F0800180F82910704790F857 +:107530002920012904D0022907D022F0100101E0FE +:1075400042F0100121F0200101E042F0300180F80A +:1075500029107047C278002961F30302C27004D079 +:1075600010F85E1F41F0040101707047C27A0129D2 +:1075700061F30302C27202D942F01001C172704776 +:107580009004002200000320E4071000EC970100A3 +:1075900001EB810102EBC101405C010602D500F064 +:1075A0007F0040427047002B04DA5B42DBB243F0BD +:1075B000800301E003F07F0301EB810102EBC101D5 +:1075C000435470472DE9F05F0025DDE90A789146C4 +:1075D0009A4683462E462A460120002101F06AFD84 +:1075E00000EA090001EA0A01084314D000242246F7 +:1075F0000120002101F05EFD384001EA0801084346 +:1076000005D00023224631465846FFF7CCFF641CC4 +:10761000282CECDB761C6D1C382DDCDBBDE8F09FE4 +:10762000405C010602D500F07F0040427047002A0E +:1076300004DA5242D2B242F0800201E002F07F024C +:1076400042547047F0B5002415460E468446234642 +:1076500001270FE006EBE30003F00701007807FACB +:1076600001F2024205D0002219466046FFF7DFFF13 +:10767000641C5B1CAC42EDDBF0BD405C70474254C7 +:107680007047F0B50024234601260DE001EBE30529 +:1076900003F007072D7806FA07FC1CEA050F02D055 +:1076A0000025C554641C5B1C9442EFDBF0BD405CBC +:1076B000704742547047405C704742547047000026 +:1076C0002DE9F047334C54F83C8F6768E668257C19 +:1076D000DFF8C4900121C9F800104FF42070E8F7DA +:1076E0008FFE0021C9F80010C4F800806760E660D2 +:1076F0002574BDE8F08727480021C16301648164D7 +:1077000080F84C10704770B500240D4602460120E9 +:10771000214601F0CFFC35B31E4A4832106011718A +:10772000FFF7CEFF002000F023F800B10124FFF79F +:10773000C7FF012000F01CF808B144F00204FFF775 +:10774000BFFF022000F014F808B144F00404FFF772 +:10775000B7FF032000F00CF808B144F00804FFF76D +:10776000AFFF204670BD0B4A3C32C2E90001D7E7AB +:1077700040F02001074810B580F8A310E521817181 +:107780004FF42070E8F73CFE0448D0F8C002C0B2C5 +:1077900010BD000000000320681460220010602269 +:1077A0004E480168002901D001200847704710B5F4 +:1077B000FFF71FFE4A49022008704A49002008606E +:1077C00046480168002903D0BDE810400020084762 +:1077D00010BD42490020086070477FB504460399F8 +:1077E000089DC1F314010391082102A800F076FA64 +:1077F000012D02D0022D04D006E0C01C20F00100B3 +:1078000002E0C01D20F00300DDE9021244F83C1F35 +:107810006260217A60F3060121727FBD012340F886 +:107820003C3F002343605143027A61F30602027237 +:1078300070471FB50446039902A801F03F01039168 +:10784000082100F04BFADDE90212A16484F84C2013 +:1078500014F8701F60F3050104F81E19E17F60F34E +:107860000501E1771FBD08B51FA2126800921DF83F +:10787000012010F85D1F62F30101017008BD184975 +:107880000320087017491948086019490120C1F8F8 +:10789000C00018494FF4FA70FFF7D6BD10B50A467C +:1078A000817921F00D0141F0E00181710B490A60FD +:1078B0000B4A032111700B4A0C4911600146A422A6 +:1078C0000D4801F02EFC0A490120C1F8C000BDE8B6 +:1078D000104008494FF4FA70FFF7B6BDEC071000EE +:1078E000E4071000E8071000000102005F770100C4 +:1078F0000000602251770100000003201648017843 +:10790000012908D1022101701448016819B100222F +:107910000260104608470120FFF729B80E4A0121EE +:1079200011700E4908600E49E82088710D490C203D +:10793000FFF78CBD0A49082088710B4900200862B6 +:107940000549087005490860704703480078002819 +:1079500000D0012070470000E4071000F00710007D +:1079600000000320AD780100000060226848016833 +:10797000002901D001200847704710B5FFF739FDF5 +:10798000644902200870644900200860604801686A +:10799000002903D0BDE810400020084710BD5C4915 +:1079A0000020086070477FB504460399089DC1F325 +:1079B00014010391082102A800F090F9DDE90212F8 +:1079C000E163226494F84420C1B261F3060284F8B2 +:1079D00044200A2D0FD00B2D0DD014F8720F61F337 +:1079E00005002070607861F305006070A07820F0D9 +:1079F0000800A0707FBD14F8721F401C60F30501E1 +:107A00002170617860F305016170A07840F0080092 +:107A1000EFE71FB50446039902A801F03F01039167 +:107A2000082100F05BF9DDE90212A16484F84C2022 +:107A300014F8701F60F3050104F81E19E17F60F36C +:107A40000501E1771FBD30B534A28CB03CCA8DE88A +:107A50003C0036A20DF1100C3CCA8CE83C0037A269 +:107A60000DF1200C3CCA8CE83C0004AA535C427E19 +:107A700063F3050242761DF80130027E63F3420291 +:107A8000027608AA525C817962F3830181710CB09D +:107A900030BD2049042008701F492C4808602C493B +:107AA0000120C1F8C0002B494FF4FA70FFF7CCBC9D +:107AB00010B50A46B0F8561041F00101A0F8561072 +:107AC000017F21F00101017790F8221021F00101DE +:107AD00080F82210817921F0010141F0E0018171EB +:107AE0000B490A600B4A042111700B4A17491160B7 +:107AF0000146A422184801F014FB15490120C1F8E1 +:107B0000C000BDE8104013494FF4FA70FFF79CBC69 +:107B1000F4071000E4071000E8071000000002025C +:107B2000010103030303000200000000020202023D +:107B3000020202020101020201010000020302032B +:107B40000203020302030202020300002B79010078 +:107B5000000060221D790100000003204949012036 +:107B600008601722410701F8272F0B2281F84120D6 +:107B70004449183908604FF00851C1F8C403414B1B +:107B80000022B0331A60404A1060121D10603D4A56 +:107B9000943A1060C1F8740370473A49012094394F +:107BA00008607047374900209439086070474FF0EB +:107BB0000050008870474FF00050807870474FF0B9 +:107BC000005148607047314902680A6042684A6063 +:107BD0008068886070472D490A6802604A68426080 +:107BE00089688160704727490120303908607047F3 +:107BF0004FF0005010F8221F21F003010170704770 +:107C00004FF0005303F81F0F5970987862F3030088 +:107C1000987070471E48006870471D49086070479B +:107C200010B54FF00054E27E202322F0AF0203EAA9 +:107C300040131343042202EA8000034301F00300CF +:107C40000343E37610BD4FF0005090F8220010F08F +:107C5000030005D0012805D0022805D00D48704743 +:107C60000D4870470D4870470D4870477047704782 +:107C70000C490120C1F8DC0070470A490020C1F816 +:107C8000DC007047CC040022801E00220800002087 +:107C9000F807100000127A000090D0030048E801B5 +:107CA0000024F40000006022F0B5074600200346DF +:107CB0002F4E10E057F8235003224FEAC20C45FA2A +:107CC0000CF484EA2064E4B2521E56F8244084EA9C +:107CD0000020F2D55B1C8B42ECDBF0BD30B50446D6 +:107CE000234B0020103B08E0625C02F00F0503EB21 +:107CF00012125D5D127828441044491EF4D230BD42 +:107D000010B584680368E443A3420AD1C468436899 +:107D1000E443A34205D15B1C0B60006810600120A6 +:107D200010BD002010BD3CB50446002501AA6946DF +:107D3000FFF7E6FF012809D1009904F11000091F9F +:107D4000FFF7B2FF0199884200D1012528463CBDCA +:107D500030B50D460446091F1030FFF7A5FF6D1E14 +:107D60006560E943E1602060C043A06030BD000071 +:107D7000A098010001468000B1F5803F02D2103882 +:107D8000C0F310007047C0F387207047B0F5802F14 +:107D900002D21030C0F31000C0F38F00704730B52E +:107DA000FE4C01252560E50603F01F0385F86B30C6 +:107DB000002304E051F8235040F823505B1C934209 +:107DC000F8DB0020206030BDF0B5F44F01233B60AC +:107DD0005C0784F86B309B1E0360002312E051F8AF +:107DE000234040F82340002450F8235051F82360EA +:107DF000B54206D06D1C04D1641C40F82360032CEE +:107E0000F2D35B1C9342EADB00203860F0BDF0B592 +:107E100013460A460546002498184FF48326602826 +:107E200001D9012411E0002107E05F1856F827006E +:107E3000401C01D011460224491C9142F5D324B9BB +:107E400006EB83002946FFF7BFFF2046F0BD10B5C3 +:107E500003460846FFF78EFF0146BDE8104092003A +:107E6000184601F0A3B92DE9F0414FF000580C4637 +:107E7000D8F814700125C0F38F066FF48041C8F85C +:107E800014100E2000F012FA204600F01AFA020038 +:107E9000C3484FF0010119D00160A4F58034404679 +:107EA000A8F87260A8F87440602288F87120BD4A72 +:107EB0001160BB4AC432116030BF98F8781089074E +:107EC00000D0002547612846BDE8F081002202600D +:107ED000E5E72DE9F05F1546DFF8C0B2002601277F +:107EE0000A4604464FF0005CB1F5882F15D3A30A6B +:107EF000FFF740FF5946CBF8007003F01F038CF8E2 +:107F00006B30002304E052F8234040F823405B1C10 +:107F1000AB42F8DB0E60BDE8F09FDCF81490C1F3D3 +:107F20008F08E2466FF48041CCF814100E2000F068 +:107F3000BDF9CBF80070204600F0C3F90100984865 +:107F400017D00760A4F58034AAF87280AAF87440AC +:107F50006D1EAAF8765040218AF8711091490E6082 +:107F60008F49C4310F6030BFCBF80060CAF814905D +:107F7000D1E70660E8E72DE9F0414FF000540F46E5 +:107F800054F8146F85086FF4804020600E2000F0D4 +:107F90008DF90020A066A4F85E507F1EA4F86270E0 +:107FA00084F85D007F4908607D490120C431086084 +:107FB00030BFE06E266087E770B506460C4601F1DB +:107FC0001000111F154689B2FFF7D5FF2060681E0B +:107FD000606020682A46C043A06060682146C043B4 +:107FE000E0603046BDE8704073E7F0B5074600201A +:107FF00004466D4E15E057F8245003234FEAC30C96 +:1080000045FA0CF280EA02600822002802DA86EAC9 +:10801000400000E04000521E002AF6DC5B1EEDD559 +:10802000641C8C42E7DBF0BD30B550F8084B50F8CB +:10803000085B30F80C1C491C89B2FFF7D6FF84425C +:1080400004D1E043854201D1012030BD002030BD84 +:108050002DE9F0410126750704466F696FF48040F1 +:1080600068610E2000F022F94FF00008C5F87C800E +:10807000204600F026F9020049494FF0010015D0D2 +:108080000860A4F58034A5F87440202185F87110AB +:10809000444908604249C431086030BF95F878000F +:1080A000800700D000266F6130460DE7C1F80080E0 +:1080B000E9E700B50B46FFF75DFE82680168D24331 +:1080C000914208D14268C068C043824203D1521C29 +:1080D0001A80012000BD002000BDF8B50446103014 +:1080E0000D460646FFF7BFFE012801D00020F8BD6F +:1080F00069462846FFF7DDFFBDF80000001F81B28A +:108100003046FFF738FF2060BDF80010C043491E1D +:108110006160A060C843E0600120F8BDF0B5B1B077 +:1081200007466D46214E0124C021284601F09AF8E9 +:10813000002056F8201045F82010401C3028F8D3B5 +:108140001B490098884210D1029881B205A80446C4 +:10815000FFF74BFF0199814206D1AC2221463846F8 +:1081600001F024F8002400E0032431B02046F0BDE3 +:1081700070B594B004466D460E4E5021284601F06D +:1081800071F8002056F8201045F82010401C1428E3 +:10819000F8D309486FF0020500990FE0C41B0022D4 +:1081A000780D00221C0F00221B000080481D0400D7 +:1081B000B2570E70AC1E04005C000D6081422ED1DF +:1081C000A81020606060A060E0602061029881B229 +:1081D00005A8FFF70AFF0199814220D1BDF83810A8 +:1081E00045F2AA5081420CD19DF81D1021609DF8E6 +:1081F0001C1001F00F0161609DF81E1001F00F01CD +:10820000A160BDF83C10814201D10899E160BDF840 +:108210004010814201D10998206114B070BD2560E1 +:108220006560A560E5602561F7E770B586B0044636 +:108230006D46274E1421284601F014F8002156F807 +:10824000210045F82100491C0529F8D30098206039 +:10825000019860600298C0B2A0600398C0B2E0606C +:108260000498C0B2206106B070BD1CB50020184A49 +:108270000090843A6B460146019052F8214043F841 +:108280002140491C0229F8D3BDF80010A1F5AA42EB +:10829000AA3A0AD1BDF80420114206D19DF8021075 +:1082A0009DF80620114200D108461CBD00F01F02B7 +:1082B000012191404009800000F1E020C0F88012C7 +:1082C0007047B0F5803F01D2002070470120704711 +:1082D000601F04004FF00050002180F83D1080F82E +:1082E0003E1080F83F103F2280F8322000F8301F07 +:1082F000027141714270017241728172C172C17129 +:108300007047894A1160884A002134321160121D79 +:1083100008B11160704701201060704730B501242A +:108320008440E0B24FF000540029039D94F83210CD +:1083300001D0014300E0814384F8321094F83010FA +:108340000AB1014300E0814384F8301094F83410FE +:108350000BB1014300E0814384F8341014F8351F59 +:108360000DB1014300E08143217030BD4FF0005258 +:10837000062817D2DFE800F00306090F171A12F8D3 +:108380003D0F04E012F83D0F07E012F83E0F20F019 +:108390000F00084305E012F83E0F20F0F00040EA1D +:1083A00001101070704712F83F0FF0E712F83F0FFE +:1083B000F3E701238340D8B24FF00053002993F82C +:1083C000381001D0014300E0814383F8381013F8DE +:1083D000391F0AB1014300E081431970704701233E +:1083E0008340D8B24FF00053002993F83A1001D0DF +:1083F000014300E0814383F83A1013F83A1F0AB1B1 +:10840000014300E08143197070472DE9F0470546AC +:108410000120A840C4B21F46914688460A20DDF8D4 +:1084200020A000F06BF80B2000F068F80A2000F0A4 +:1084300070F80B2000F06DF84FF0005696F83800F9 +:10844000A04386F8380096F83A00A04386F83A0030 +:1084500096F82E00A04386F82E00344A0020B8F18A +:10846000000F42F825000BD096F83810214386F80B +:10847000381096F83A10214386F83A1042F82570E1 +:1084800096F83910A14386F8391096F83B10A143AD +:1084900086F83B1096F82F10A14386F82F10234939 +:1084A0002031B9F1000F41F825000BD096F83900C2 +:1084B000204386F8390096F83B00204386F83B00BD +:1084C00041F825A096F8380010B10A2000F00BF80A +:1084D00096F83900002804D0BDE8F0470B2000F0E2 +:1084E00002B8BDE8F08700F01F0201219140400969 +:1084F000800000F1E020C0F80011704700F01F027A +:10850000012191404009800000F1E020C0F8801175 +:10851000704700F01F02012191404009800000F1E6 +:10852000E020C0F88012704704050022A8901000D7 +:108530002DE9F047417ACA074FF0000101D0554AB2 +:10854000516001277D0785F8E57085F8E470C5F86E +:10855000C010C5F8E81085F8E11085F8E310DFF8E1 +:1085600038A1067A04680AF10709072E00D9072600 +:1085700000216DE04A1CD3B201EB810214F80280A5 +:108580000AF80180D0F804C022443CF8118029F890 +:10859000118092F803C0BCF1010F02D0BCF1030FAF +:1085A00007D195F8E5C007FA03F84CEA080C85F8FE +:1085B000E5C090F809C05FEACC7C0FD192F803C007 +:1085C000BCF1020F02D0BCF1030F07D195F8E4C053 +:1085D00007FA03F84CEA080C85F8E4C001EB410CFB +:1085E00021F00108E04492F801C00CF0070C0CFAED +:1085F00008FCD5F8C0804CEA080CC5F8C0C092F859 +:1086000002C04FEA81080CF00F0C0CFA08FCD5F8F8 +:10861000E8804CEA080CC5F8E8C090F809C05FEAA9 +:10862000CC7C14D11279D20707D095F8E12007FA53 +:1086300003FC42EA0C0285F8E1202279D20606D535 +:1086400095F8E32007FA03F31A4385F8E320491C61 +:10865000B1428FD3D5F8E8006864BDE8F0870E4AD0 +:10866000D21D22F81010704710B504460B48006860 +:1086700038B1A068FFF75CFF2068BDE8104000F04B +:108680000FB8E068FFF754FF6068BDE8104000F0E5 +:10869000D3BC000000200022AB000020BC0500225B +:1086A00010B54F4B01680024996081885980028978 +:1086B0009A801C704FF00053A3F81A21A3F81E11E2 +:1086C000C088A3F8200147480122C0F8D821C0F88B +:1086D000DC21C0F8C421C0F8CC21C0F8D421C0F8F6 +:1086E000802172B6D0F808120029FBD1426062B630 +:1086F00010BD2DE9F0413B4DD5F85C01384F2E04FB +:108700000124BA6850B3B6F81C815FEA08000FD0A4 +:10871000D5F8540110B9D5F8000148B141460120FF +:108720009047C5F8D842D5F8540108B1C5F8D442ED +:10873000BA684146022090470178022902D00329F5 +:1087400002D008E0418800E07988A6F81E118088F0 +:10875000A6F81A013C70C5F8DC4238E0D5F84401AF +:1087600080B1B6F81C1103209047387838B178886A +:10877000A6F81E01B888A6F81A0100203870C5F8BE +:10878000C44224E0D5F8580130B1B6F81C110120DC +:108790009047C5F8D8421AE0D5F84C0128B9D5F869 +:1087A000540110B9D5F8000188B1B6F81C1119B1FF +:1087B00001209047C5F8D842D5F84C0110B1C5F852 +:1087C000CC4204E0D5F8540108B1C5F8D442D5F83C +:1087D0000001002801D0C5F88042BDE8F08100000A +:1087E000FC07100000200022F64900200860091D47 +:1087F0000860091D0860091D0860091D0860091D41 +:108800000860091D0860091D0860EF4901220A601F +:10881000ED4914310860510701F8500FFF234B70E8 +:1088200001F8050C10234B808A80E84908604860F5 +:108830008860C860086148618861C86108627047E3 +:108840007047E24A1160DF4900220A6000EB8000B5 +:108850004FF6FF7202EA40004FF00052A2F85800B3 +:10886000012008607047D94B10B5D64A1960002125 +:1088700011604FF0005191F85140E40707D01B6A96 +:1088800058438009A1F858000120106010BD00EB8A +:10889000C00303EB00104FF6FF7303EA8000F1E71B +:1088A0004FF00050B0F8580070474FF0005090F86B +:1088B0002200C0F3810028B1012805D0022805D08C +:1088C000C3487047C3487047C3487047C3487047A0 +:1088D00070B54FF0005494F85100BA49C2074FF0F8 +:1088E000000001D0086070BD656972B6626942F02F +:1088F000040262610860B4F8581009B1A4F8580085 +:10890000FFF7A1F90146FFF7D0FFB1FBF0F0E7F761 +:1089100077FD6561022000F03BFB62B670BDAB489D +:1089200010B5002104680160FFF7D2FF1CB1A44616 +:10893000BDE8104060470020FFF782FF10BDA34A4A +:108940005160A0490022091D0A6000EB80004FF62B +:10895000FF7202EA4000CA06A2F85A00012008602D +:1089600070479A4B10B55960964A0021121D11604C +:10897000D10691F85140A40708D400EBC00303EBE3 +:1089800000104FF6FF7303EA800002E01B6A5843B1 +:108990008009A1F85A000120106010BD4FF000506E +:1089A000B0F85A00704770B54FF0005494F8510079 +:1089B0008B4982074FF000001AD4656972B662696C +:1089C00042F0080262610860B4F85A1009B1A4F8D4 +:1089D0005A00FFF738F90146FFF767FFB1FBF0F0E7 +:1089E000E7F70EFD6561032000F0D2FA62B670BDB4 +:1089F000086070BD754810B5002144684160FFF7FC +:108A0000D2FF1CB1A446BDE8104060470120FFF72B +:108A100017FF10BD6D4A916071490022091D0A605F +:108A200000EB80004FF6FF7202EA40008A06A2F8CF +:108A30005C00012008607047644B10B59960684A7B +:108A40000021121D1160910691F85140640708D46D +:108A500000EBC00303EB00104FF6FF7303EA800046 +:108A600002E01B6A58438009A1F85C0001201060F5 +:108A700010BD4FF00050B0F85C00704770B54FF07B +:108A8000005494F85100574942074FF000001AD49F +:108A9000656972B6626942F0100262610860B4F8FA +:108AA0005C1009B1A4F85C00FFF7CDF80146FFF7B0 +:108AB000FCFEB1FBF0F0E7F7A3FC6561042000F0D9 +:108AC00067FA62B670BD086070BD404810B50021FD +:108AD00084688160FFF7D2FF1CB1A446BDE8104056 +:108AE00060470220FFF7ACFE10BD384AD1603D4917 +:108AF0000022091D0A6000EB80004FF6FF7202EAB7 +:108B000040004FF00052A2F85E000120086070475C +:108B10002E4B10B5D960334A0021121D11604FF061 +:108B2000005191F85140240708D400EBC00303EB37 +:108B300000104FF6FF7303EA800002E01B6A5843FF +:108B40008009A1F85E000120106010BD4FF00050B8 +:108B5000B0F85E00704770B54FF0005494F85100C3 +:108B6000214902074FF000001AD4656972B66269A4 +:108B700042F0200262610860B4F85E1009B1A4F806 +:108B80005E00FFF760F80146FFF78FFEB1FBF0F0E3 +:108B9000E7F736FC6561052000F0FAF962B670BDB2 +:108BA000086070BD094810B50021C468C160FFF7B6 +:108BB000D2FF1CB1A446BDE8104060470320FFF778 +:108BC0003FFE10BD40090022C0040022080810002A +:108BD00000093D000048E8010024F40000127A007A +:108BE00044090022480900224C090022EE4A116182 +:108BF000EE4900220A6000EB80004FF6FF7202EAA5 +:108C000040004FF00052A2F8600001200860704759 +:108C1000E54B10B5E54A1961002111604FF0005194 +:108C200091F85140E40608D400EBC00303EB0010B8 +:108C30004FF6FF7303EA800002E01B6A5843800985 +:108C4000A1F860000120106010BD4FF00050B0F896 +:108C50006000704770B54FF0005494F85100D3494C +:108C6000C2064FF000001AD4656972B6626942F01C +:108C7000400262610860B4F8601009B1A4F86000B5 +:108C8000FEF7E1FF0146FFF710FEB1FBF0F0E7F75A +:108C9000B7FB6561062000F07BF962B670BD086025 +:108CA00070BDC14810B5002104690161FFF7D2FF12 +:108CB0001CB1A446BDE8104060470420FFF7C0FD8A +:108CC00010BDB94A5161B9490022091D0A6000EB83 +:108CD00080004FF6FF7202EA40004FF00052A2F807 +:108CE0006200012008607047AF4B10B55961AF4A70 +:108CF0000021121D11604FF0005191F85140A4065F +:108D000008D400EBC00303EB00104FF6FF7303EA37 +:108D1000800002E01B6A58438009A1F8620001202C +:108D2000106010BD4FF00050B0F86200704770B591 +:108D30004FF0005494F851009D4982064FF0000016 +:108D40001AD4656972B6626942F080026261086095 +:108D5000B4F8621009B1A4F86200FEF774FF01468E +:108D6000FFF7A3FDB1FBF0F0E7F74AFB65610720D1 +:108D700000F00EF962B670BD086070BD8A4810B58B +:108D8000002144694161FFF7D2FF1CB1A446BDE850 +:108D9000104060470520FFF753FD10BD824A9161E6 +:108DA00083490022091D0A6000EB80004FF6FF7224 +:108DB00002EA40004FF00052A2F86400012008606F +:108DC0007047794B10B59961794A0021121D1160E5 +:108DD0004FF0005191F85140640608D400EBC003F5 +:108DE00003EB00104FF6FF7303EA800002E01B6AFA +:108DF00058438009A1F864000120106010BD4FF0B5 +:108E00000050B0F86400704770B54FF0005494F80B +:108E10005100684942064FF000001AD4656972B6E5 +:108E2000626942F4807262610860B4F8641009B14A +:108E3000A4F86400FEF707FF0146FFF736FDB1FB1B +:108E4000F0F0E7F7DDFA6561082000F0A1F862B6FE +:108E500070BD086070BD544810B5002184698161FF +:108E6000FFF7D2FF1CB1A446BDE8104060470620C2 +:108E7000FFF7E6FC10BD10B5FEF7CCFE4FF0005139 +:108E800091F8222042F21073B0FBF3F0C2F381029A +:108E9000521CD040B1F85420C96C51438909B0FB31 +:108EA000F1F010BD43490022091D0A603E4A126AD2 +:108EB00050434FF000528009A2F86600012008607C +:108EC00070473C490020091D086070473649C86159 +:108ED00039490120C1F8DC003649A0310860091D7C +:108EE00008607047304A10B50020D169D061324A1D +:108EF000C2F8DC0051B12F4AA03210604FF0005090 +:108F0000C06CBDE8104020F07F400847FF20FFF70D +:108F100097FC10BD10B50446FEF77CFE4FF00051E3 +:108F200091F8221042F21072B0FBF2F0C1F381010D +:108F3000491CC8400003B0FBF4F01B49086210BD97 +:108F400030B54FF000550124844095F8510009B127 +:108F5000204300E0A04385F8510095F84B000AB18A +:108F6000204300E0A04385F84B0015F8500F0BB1EB +:108F7000204300E0A043287030BD4FF0005010F8AF +:108F80004A1FC079814301D00120704700207047FB +:108F900000F01F02012191404009800000F1E02013 +:108FA000C0F8801270470000080810005009002225 +:108FB00054090022580900220000602200210160AB +:108FC0000846704730B50A6812B10B46846A08E05B +:108FD00000220860C0E903210AE002F10C03D26814 +:108FE00012B1956AA542F8DC1A68C0E9032118603D +:108FF000002030BD0068002201E0C068521C8A4297 +:1090000001D00028F9D170470068704702690AB1A1 +:10901000116831B96FF00400704701F10C02C968A2 +:1090200039B18142F9D1C968116000210161084656 +:1090300070476FF003007047017C31B14FF0005171 +:1090400011F82D2F42F002020A70194902680A60D5 +:1090500042684A6082688A60C068C860704730B4FD +:109060004FF0005111F8E00F0A8AC968104BC4078D +:1090700004D09B68002B07D030BC1847DB68002B5E +:1090800002D0521C92B2F7E730BC70474FF000504C +:1090900090F8E2000649C20704D08A68002A06D088 +:1090A000096803E0CA68002A01D049680847704788 +:1090B00040081000B2F120030AD5C2F1200301FAE2 +:1090C00002F120FA03F300FA02F041EA03017047CB +:1090D00000FA03F14FF00000704710B54C1084EA1D +:1090E000530404D54042C1F1000138BF491E1B4260 +:1090F00004D55242C3F1000338BF5B1E00F0D9F81B +:1091000014F0804F04D04042C1F1000138BF491E25 +:1091100014F0004F04D05242C3F1000338BF5B1E6D +:1091200010BD032A40F2308010F0030C00F01580CF +:1091300011F8013BBCF1020F624498BF11F801CB5A +:1091400000F8013B38BF11F8013BA2F1040298BFBF +:1091500000F801CB38BF00F8013B11F0030300F029 +:109160002580083AC0F0088051F8043B083A51F8CD +:1091700004CBA0E80810F5E7121D5CBF51F8043BD2 +:1091800040F8043BAFF30080D20724BF11F8013B45 +:1091900011F801CB48BF11F8012B24BF00F8013BA7 +:1091A00000F801CB48BF00F8012B704710B5203AFA +:1091B000C0F00B80B1E81850203AA0E81850B1E890 +:1091C0001850A0E81850BFF4F5AF5FEA027C24BF46 +:1091D000B1E81850A0E8185044BF18C918C0BDE83D +:1091E00010405FEA827C24BF51F8043B40F8043B06 +:1091F00008BF7047D20728BF31F8023B48BF11F8BB +:10920000012B28BF20F8023B48BF00F8012B704714 +:1092100002F0FF0343EA032242EA024200F002B8EE +:109220004FF000020429C0F0128010F0030C00F08F +:109230001B80CCF1040CBCF1020F18BF00F8012B0D +:10924000A8BF20F8022BA1EB0C0100F00DB85FEADB +:10925000C17C24BF00F8012B00F8012B48BF00F8A7 +:10926000012B70474FF0000200B513469446964616 +:10927000203922BFA0E80C50A0E80C50B1F1200129 +:10928000BFF4F7AF090728BFA0E80C5048BF0CC0D7 +:109290005DF804EB890028BF40F8042B08BF704735 +:1092A00048BF20F8022B11F0804F18BF00F8012BA7 +:1092B000704753EA020C00F069802DE9F04B4FF043 +:1092C0000006002B1FBFB3FA83F503FA05F424FA56 +:1092D00005F65E4012BF1643B2FA82F502FA05F4B3 +:1092E000C5F120051EBF22FA05FC44EA0C04203516 +:1092F00056EA044C4FEA144418BF641C4FF00008AF +:109300004FF00009904271EB030C39D3002919BFCB +:10931000B1FA81F701FA07F6B0FA80F700FA07F61A +:10932000C7F120071EBF20FA07FC46EA0C062037CB +:10933000B6FBF4FCA7EB0507103F07F01F0BCBF1C2 +:1093400020060CFA0BFB2CFA06F644BFB3460026A7 +:10935000202FA4BF5E464FF0000B5BEA060C08BF4F +:109360004FF0010B19EB0B09ABFB027C48EB060835 +:10937000C01B06FB02CC0BFB03CC71EB0C01C1E75D +:109380000B46024641464846BDE8F08B13B54FF008 +:1093900000004FF00001AFF30080BDE81C407047B3 +:1093A00010B50446AFF300802046BDE81040E6F754 +:1093B00035BF704701491820ABBEFEE7260002000A +:1093C0000149002008607047380500222DE9F0416E +:1093D0000F4F00244FF001084FF0005608FA04F038 +:1093E000C5B296F82F0028420CD096F839002842D2 +:1093F00008D057F8240000B1804796F82F00A84302 +:1094000086F82F00641C062CE8DBBDE8F081000024 +:10941000C89010002DE9F0410F4F00244FF00108D3 +:109420004FF0005608FA04F0C5B296F82E00284214 +:109430000CD096F83800284208D057F8240000B124 +:10944000804796F82E00A84386F82E00641C062C50 +:10945000E8DBBDE8F0810000A89010000121814008 +:10946000C8B24FF0005191F83310014201D00120F1 +:1094700070470020704700000149012008607047D4 +:1094800038050022004870473D0710000549044A8E +:109490000A80054AC0E9002101210172417270472A +:1094A00058580120DC061000A096010007484178BA +:1094B00049B1807838B106488079012803D1054840 +:1094C0000078012800D00020704700002807100015 +:1094D000A8061000180510000348417811B98078DB +:1094E000002800D0012070472807100001480078AC +:1094F0007047000010061000064841788278C37853 +:109500001144027800791A441144081800D001204F +:1095100070470000C005100070B5D0E900214C086C +:109520004FEA3203961841EB010533432C431343B2 +:109530000C43C0E9003470BD01EB810100EBC100B8 +:1095400029307047024A1278514300EB41007047BE +:109550007606100001EB810100EBC1002930704755 +:10956000024A1278514300EB410070477606100022 +:10957000100000000400000001000000FF000100D6 +:1095800002000100020004000200010002000100CC +:109590001000FFFFFFFFFFFFFFFF1400FFFFFFFFB3 +:1095A000FFFFFFFF0C00FF00FF00000000010101B2 +:1095B000020200000000000034481000804D10003E +:1095C00071180100020000007F1801000200000075 +:1095D0009D180100020000001118010002000000A7 +:1095E0000D180100020000001B1901000700000017 +:1095F0000D18010002000000CF1901000100000059 +:10960000BD1801000700000037180100020000002B +:1096100047180100551A0100511A0100531B01009F +:10962000511A0100E31C0100511A0100511A0100F6 +:10963000511A0100511A0100511A0100891A010042 +:1096400001000000C11A010000000000511A0100D1 +:1096500000000000D51A0100010000007F1B01007E +:1096600001000000A31B010001000000C71B010056 +:1096700001000000FD1B010004000000D51C0100DA +:10968000010000000F1D0100010000006D1D010020 +:1096900001000000831D010002000000D31D010035 +:1096A000020000008D1E0100020000004B1F01009F +:1096B000010000008B1F010001000000451E010099 +:1096C000020000000B1F010002000000511A0100FF +:1096D00000000000511A010000000000291D0100D7 +:1096E000331D01003D1D01004D1D01005D1D0100E8 +:1096F0008600020100A6020F0300A8020B0300006F +:109700000300000000000000030000000000000053 +:1097100053000000000000004300000000000000B3 +:10972000F300000000000000E30000000000000063 +:10973000E3000000000000005302000000000000F1 +:1097400000000000050000000C7410000004000080 +:10975000753A000000000000020000000100000057 +:10976000040000000C78100000040000D94B000039 +:1097700000000000020000000200000003000000E2 +:109780000C7C1000000800006316010000000000BF +:109790000200000003000000020000000C84100022 +:1097A000000200004920010000000000020000004B +:1097B00004000000010000000C8610008000000082 +:1097C0007917010000000000020000000000000006 +:1097D0000100000001000000010000000200000084 +:1097E0000100000003000000010000000400000070 +:1097F0000100000005000000010000000000000062 +:10980000010000000200000003000000935201006C +:109810002B520100675B0100FF5A0100D36D01006C +:10982000C1530100074B010071540100BF5D0100ED +:109830008B5C01001D680100E96D0100000440001F +:1098400010210000001F0100060000003000010090 +:10985000000406000802500060020C0C00006002C8 +:109860000C300C1A31100F0F00002F000100AA2C31 +:109870000100000003000000FFFF030000000000E3 +:1098800018000000FFFFFFFF3F0000000000000085 +:1098900000010000000000006002018000010000E3 +:1098A00000000C000C000C000C0007012626121210 +:1098B000110000000038003C203DD041EC4108423E +:1098C0001C4230424442604274428842A44200003A +:1098D0000000000000000000000000000000002068 +:1098E0000001010201020203010202030203030458 +:1098F000000000001B0000802D00008036000000EA +:10990000410000805A0000006C00000077000080D9 +:109910009900008082000000B4000000AF000080C9 +:10992000D8000000C3000080F5000080EE000000B9 +:109930002901008032010000040100001F010080A5 +:109940006801000073010080450100805E01000095 +:10995000B0010000AB0100809D0100808601000085 +:10996000F1010080EA010000DC010000C701008075 +:109970004902008052020000640200007F02008061 +:109980000802000013020080250200803E02000051 +:10999000D0020000CB020080FD020080E602000041 +:1099A000910200808A020000BC020000A702008031 +:1099B000600300007B0300804D030080560300001D +:1099C000210300803A0300000C030000170300800D +:1099D000F9030080E2030000D4030000CF030080FD +:1099E000B8030000A3030080950300808E030000ED +:1099F0008904008092040000A4040000BF040080D9 +:109A0000C8040000D3040080E5040080FE040000C8 +:109A1000100400000B0400803D04008026040000B8 +:109A2000510400804A0400007C04000067040080A8 +:109A3000A0050000BB0500808D0500809605000094 +:109A4000E1050080FA050000CC050000D705008084 +:109A50003905008022050000140500000F05008074 +:109A60007805000063050080550500804E05000064 +:109A7000C0060000DB060080ED060080F606000050 +:109A8000810600809A060000AC060000B706008040 +:109A90005906008042060000740600006F06008030 +:109AA0001806000003060080350600802E06000020 +:109AB000E9070080F2070000C4070000DF0700800C +:109AC000A8070000B3070080850700809E070000FC +:109AD000700700006B0700805D07008046070000EC +:109AE000310700802A0700001C07000007070080DC +:109AF0000909008012090000240900003F090080C4 +:109B00004809000053090080650900807E090000B3 +:109B1000900900008B090080BD090080A6090000A3 +:109B2000D1090080CA090000FC090000E709008093 +:109B3000200800003B0800800D0800801608000087 +:109B4000610800807A0800004C0800005708008077 +:109B5000B9080080A2080000940800008F08008067 +:109B6000F8080000E3080080D5080080CE08000057 +:109B7000400B00005B0B00806D0B0080760B00003B +:109B8000010B00801A0B00002C0B0000370B00802B +:109B9000D90B0080C20B0000F40B0000EF0B00801B +:109BA000980B0000830B0080B50B0080AE0B00000B +:109BB000690A0080720A0000440A00005F0A0080FF +:109BC000280A0000330A0080050A00801E0A0000EF +:109BD000F00A0000EB0A0080DD0A0080C60A0000DF +:109BE000B10A0080AA0A00009C0A0000870A0080CF +:109BF000800D00009B0D0080AD0D0080B60D0000B3 +:109C0000C10D0080DA0D0000EC0D0000F70D0080A2 +:109C1000190D0080020D0000340D00002F0D008092 +:109C2000580D0000430D0080750D00806E0D000082 +:109C3000A90C0080B20C0000840C00009F0C008076 +:109C4000E80C0000F30C0080C50C0080DE0C000066 +:109C5000300C00002B0C00801D0C0080060C000056 +:109C6000710C00806A0C00005C0C0000470C008046 +:109C7000C90F0080D20F0000E40F0000FF0F00802A +:109C8000880F0000930F0080A50F0080BE0F00001A +:109C9000500F00004B0F00807D0F0080660F00000A +:109CA000110F00800A0F00003C0F0000270F0080FA +:109CB000E00E0000FB0E0080CD0E0080D60E0000EE +:109CC000A10E0080BA0E00008C0E0000970E0080DE +:109CD000790E0080620E0000540E00004F0E0080CE +:109CE000380E0000230E0080150E00800E0E0000BE +:109CF000D09C010000041000500400001C01000072 +:109D0000F89C010000FC10004000000078010000F9 +:109D1000F89C010050081000988800009401000091 +:109D200001FF01FF01F70759F001205450103206DE +:109D3000320F9A37089AE108035AD303AAFF0C5945 +:109D40000101150B5390D08630B572B601230C4D2E +:109D50002B600C4A002481B113604FF0005100F0D9 +:109D60001F0081F86A0007481C3803600168002959 +:109D7000FCD114602C6062B630BD1460EDE70000C9 +:109D8000C01B0022780D0022F92F56FFCF020000E1 +:109D900006D0A90030FDFFFF3E002A0001020000AE +:109DA0002AE5000000000000FFFFFFFF01000000A7 +:109DB000FF7F000000000000210F230937040F235C +:109DC000093704B80100000003302019CCC0FA00A4 +:109DD000FA00FA00FA0096009600960096007000CD +:109DE000700008B000B00000000100010001000197 +:109DF0000800188100000000041080004000983A1C +:109E0000C80000008B10E60000010A2C01041400B9 +:109E10002C0100005E0113200A96000328010510A2 +:109E20003C0A0000000000000D080F0A1F0FF90097 +:109E30000200000000000B013C0064008001D00122 +:109E4000000082000064000000FF0000000000002D +:109E50008D05094F04002800040027002C6006002F +:109E600000000000BBBB401FC80088880000ADA5F3 +:109E70000D1F24002E002D002C60060000000000A5 +:109E80002C5006000000000000012C000000002CF7 +:109E9000060000000000000000008D11084F0400C3 +:109EA000300006002F0040100600000001000000F6 +:109EB00000000000000000000000E8650D1F1020F9 +:109EC00036003000600017001001100020009923B8 +:109ED0000015000000000000000000000000006409 +:109EE0000000000000000000000A0014050000004F +:109EF000000000000000000011002C010000000024 +:109F000001000000000000000000B80B000000008D +:109F10000E00000000000000000000000000020031 +:109F200000000000000000000E0000000000000023 +:109F3000000000000000020000000000000000001F +:109F40000000000000000200000064006400D00077 +:109F5000800CF00AD00000150012500150010015CD +:109F600000125001800CF00AD00000000000000038 +:109F70000000000000000000B32A040E1600011EBD +:109F8000180000000000300000000000FF0FFF0F6D +:109F900010140A00000000002B00C800000000D0D0 +:109FA0000F1490019001FF7FFF7FF4010000090072 +:109FB00096009600960096003C0064001E00020089 +:109FC0003C003C0064003C00C8000000000064004D +:109FD0000000000000000000010258025E01002C99 +:109FE000012C010819C800000B03052101016400C0 +:109FF00064006000900132030000000000230001B3 +:10A00000C800FF2C01200000000020000600050011 +:10A01000050000000600050005000000000000002B +:10A0200000000000000085DD0200401FE02E9600C9 +:10A0300096009600080018001E00000100644032DF +:10A0400020001E003200C8008813401F0564006411 +:10A050000064001000460000000000000000000046 +:10A060000000000000000C0E84032000100F780098 +:10A0700096006400000A6400000F000160006000A8 +:10A080000040400000000000000000004A015E01A6 +:10A09000A401AA007C01003C010000000000560061 +:10A0A00000000000000000000000000000000000B0 +:10A0B0000000000000000000000000000FE80A009F +:10A0C00030000F51000000000300B4003C280306DC +:10A0D00002020213115500005E01C8000632001E84 +:10A0E000F4010000000000004000780096003200FB +:10A0F0004000C80000000564000300001BAA0AC855 +:10A1000000040000617B0103AA00000210010002AC +:10A1100064000678009600140014001078003200E5 +:10A1200000211A0000100F0001000A00148211140F +:10A1300000100004100400400000200030D810007F +:10A1400064005194941888621000300010003000B0 +:10A150000A001800053C053C033CD80532F8030111 +:10A16000030E960684C80000000000000413C80017 +:10A17000C8000A0A3C007800000A50007800016418 +:10A180000000000000000000003C0096001E2003BC +:10A190000000640008E8030000FA0003000000006B +:10A1A00000000000000000000000000000000000AF +:10A1B0001608000208000600000000A0504C26010E +:10A1C00008001302043C50000302500050004A01F2 +:10A1D00050204E0B0132001405000A201405F8002F +:10A1E00000003182000A28000000051E00FA0090DD +:10A1F000010000500A002806640A02C8001E032855 +:10A20000961E000F64140F0002020302030396C897 +:10A21000FFC000C800640001001E005001C8005BC0 +:10A22000086400D303000A0A0000000000000000D8 +:10A23000000000000000000000000000000000001E +:10A2400000000000000000005A5A5A5A5A5A5A5A3E +:10A250005A5A5A5A5A5A5A00000000000000000088 +:10A26000000000000000000060565658585A595B24 +:10A270005B5D5D5E62616263646465676A686B68AA +:10A28000696A6E6E6D6F716B7D00000000000001E9 +:10A290000C0C2222220000000000000A00140032F0 +:10A2A000006400BF08F1080F0919092309230900F8 +:10A2B0000000000A00140032006400D303050423E8 +:10A2C000042D0437043704000000000000000000E3 +:10A2D000000000000000000000000000000A000D67 +:10A2E00000100019004600E1080A09130917091AAD +:10A2F00009230900000A000E00120022004B00E8AA +:10A30000031004210428042D043704000000000079 +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D00000005800580058004058409810D800001D +:10A3E000000040E840E85200530057005D0065005F +:10A3F00070007D008D009E00B200C700DF00F800F5 +:10A4000013012F014C016B018A01AB01CC01ED015D +:10A410000F023102530275029602B702D702F6020A +:10A42000140331034C0366037E039503AA03BC03A4 +:10A43000CD03DB03E703F103F803FD03FF03FF0391 +:10A44000FD03F803F103E703DB03CD03BC03AA0319 +:10A4500095037E0366034C0331031403F602D7020F +:10A46000B70296027502530231020F02ED01CC01D0 +:10A47000AB018A016B014C012F011301F800DF00D1 +:10A48000C700B2009E008D007D00700065005D0079 +:10A4900057005300520054005B00670077008B00A8 +:10A4A000A400C000E0000301290152017D01A901BF +:10A4B000D7010602340263029102BF02EA021403CA +:10A4C0003C0360038203A003BA03D103E303F10357 +:10A4D000FA03FF03FF03FA03F103E303D103BA0313 +:10A4E000A003820360033C031403EA02BF0291024B +:10A4F000630234020602D701A9017D01520129013C +:10A500000301E000C000A4008B00770067005B003F +:10A5100054005200520054005B00670077008B002B +:10A52000A400C000E0000301290152017D01A9013E +:10A53000D7010602340263029102BF02EA02140349 +:10A540003C0360038203A003BA03D103E303F103D6 +:10A55000FA03FF03FF03FA03F103E303D103BA0392 +:10A56000A003820360033C031403EA02BF029102CA +:10A57000630234020602D701A9017D0152012901BB +:10A580000301E000C000A4008B00770067005B00BF +:10A590005400520052007B00EE0097015A0214034F +:10A5A000A603F503F503A60314035A029701EE0070 +:10A5B0007B0052007B00520054005B006700770074 +:10A5C0008B00A400C000E0000301290152017D01BD +:10A5D000A901D7010602340263029102BF02EA0216 +:10A5E00014033C0360038203A003BA03D103E30313 +:10A5F000F103FA03FF03FF03FA03F103E303D103BB +:10A60000BA03A003820360033C031403EA02BF02FF +:10A610009102630234020602D701A9017D015201B1 +:10A6200029010301E000C000A4008B00770067004F +:10A630005B00540052000000000000000000000019 +:10A6400000000100010001000401040504090000EC +:10A650000000FF03DC05DC05DC05DC05DC05DC05B2 +:10A66000DC05DC05DC05DC05DC05DC0500000000A4 +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000002013C00010223232323083C083C34 +:10A6D00040F805050A0A0105050F140000000000F6 +:10A6E0000000000000000000E8650D1F10003600AB +:10A6F00030006000170010011000080099E300000E +:10A700000000000000000000000000000000000049 +:10A7100000000D60640064001414FA00FA00FA00EE +:10A72000FA0000000000000000002C013203008845 +:10A730000000000000000000000000000000000019 +:10A74000040800003404F400700036000F000A0012 +:10A750000400000004000A000F0036007000F4003E +:10A7600034040000000000000000000000000000B1 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000E920021F10008F +:10A7900025002500500024007001800110005500A4 +:10A7A0000000000000000300640032002000140AD2 +:10A7B00084032800000400000000000000000000E6 +:10A7C0000000000000000000888800000000000079 +:10A7D0000000000000000000770000000099000069 +:10A7E000BB00F401DC050000FF6F0000FF6F0000FC +:10A7F000000018018C00FF7F0000000000FF7FC8F0 +:10A8000000320A00028A0290018813000000000052 +:10A8100000000000000000000000000A80FE32017D +:10A820003200053201B80B00001E0000501E50120D +:10A8300014B020C8D0000614142A3A400032320066 +:10A840000000000000146E6E471A38000000010F6F +:10A850001E0020001E64000001EA014E0260280074 +:10A86000280000000000000000030507080C0D0F81 +:10A870000F0F0E0E0E0D0D0D0A0800000000000057 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000010203040001020350015001F6 +:10A8B00050015001000000000000000000000000F6 +:0CA8C00000000000000000009410262C96 +:00000001FF diff --git a/firmware/st_fts_f1.ftb.ihex b/firmware/st_fts_f1.ftb.ihex new file mode 100644 index 000000000000..c48dd0ce7f32 --- /dev/null +++ b/firmware/st_fts_f1.ftb.ihex @@ -0,0 +1,6816 @@ +:1000000055AA55AA01000000363900006022000000 +:10001000600000003E00000037000000000000000B +:100020000000000037F1000000000000B09D01005A +:10003000E00B0000000000000000000037A8894825 +:100040001FBCB9DE6B670000E04346219498FFFFB8 +:1000500000041000E101000039020000530200001A +:100060006D02000087020000A102000000000000F5 +:10007000000000000000000000000000F76D01001B +:10008000FF6D010000000000BB020000076E0100D0 +:100090000F6E01001B6E0100276E0100336E010020 +:1000A0003F6E01004B6E0100576E0100636E010050 +:1000B0006F6E0100C90200007B6E0100876E0100B7 +:1000C000936E01009B6E0100A36E0100AB6E0100F8 +:1000D000B76E0100BF6E0100C76E01000000000096 +:1000E000000000000000000000000000CF6E0100D2 +:1000F000D76E010000000000DF6E0100000000006C +:1001000000000000000000000000000000000000EF +:10011000600060220000FFFF0000000000000000FF +:1001200000000000000000000000000000000000CF +:1001300000F002F800F068F80AA090E8000C824491 +:100140008344AAF10107DA4501D100F05DF8AFF26E +:10015000090EBAE80F0013F0010F18BFFB1A43F0A5 +:1001600001031847F09B0100209C01000A444FF056 +:10017000000C10F8013B13F0070408BF10F8014B06 +:100180001D1108BF10F8015B641E05D010F8016B4B +:10019000641E01F8016BF9D113F0080F1EBF10F8AF +:1001A000014BAD1C0C1B09D16D1E58BF01F801CBD2 +:1001B000FAD505E014F8016B01F8016B6D1EF9D555 +:1001C0009142D6D370470000103A24BF78C878C156 +:1001D000FAD8520724BF30C830C144BF04680C604D +:1001E000704700000023002400250026103A28BF95 +:1001F00078C1FBD8520728BF30C148BF0B60704799 +:100200001FB51FBD10B510BDDFF80CD0FFF7F8FF0C +:1002100016F090FE19F00CF90004100003B4FFF77B +:10022000F1FF03BC19F00EF940BA7047C0BA70472D +:1002300012481349A1EB00014FF0200391FBF3F2A8 +:1002400002FB13114FF0CC334FF0CC344FF0CC35D0 +:100250004FF0CC364FF0CC374FF0CC384FF0CC3994 +:100260004FF0CC3AA0E8F807013AFBD119B140F8B9 +:1002700004AB0439FBD10348004700000000100024 +:1002800000041000E10000001EF0040F0CBFEFF3AB +:100290000880EFF309804FF001014FF0000212F0E7 +:1002A0004BB81EF0040F0CBFEFF30880EFF309808A +:1002B0004FF002014FF0000212F03EB81EF0040FA2 +:1002C0000CBFEFF30880EFF309804FF003014FF00C +:1002D000000212F031B81EF0040F0CBFEFF30880DB +:1002E000EFF309804FF004014FF0000212F024B840 +:1002F0001EF0040F0CBFEFF30880EFF309804FF0FE +:1003000005014FF0000212F017B800B516F094FD89 +:100310005DF804EB00F032B81EF0040F0CBFEFF3F1 +:100320000880EFF309804FF006014FF0000212F051 +:1003300003B800000A484FF0FF0101704FF00000C1 +:1003400080F311884FF0000080F3098805484FF0D2 +:100350000201017062B604484FF08051016070479D +:1003600022ED00E04408100004ED00E002484FF0E8 +:10037000805101607047000004ED00E04FF0200064 +:1003800080F31188EFF3098098B112480068124990 +:100390000968884217D0EFF309800E49096820E9FF +:1003A000F00F886000B50B48006816F059FE5DF844 +:1003B00004EB084808490A68026000688168B1E8EF +:1003C000F00F81F309884EF0040E4FF0000080F327 +:1003D00011887047480810004C081000EFF3118096 +:1003E0004FF0200181F31188704700004FF00000AA +:1003F00080F311887047000062B6704772B670478C +:10040000401EFDD17047000010B501464022FC4857 +:1004100018F014FF0121BDE81040002016F059BE6D +:1004200038B50446F748F64D2060204616F0C5FA68 +:1004300000226B460121104616F094FE0121002097 +:1004400016F073FE2878002802D011F0CCFFECE7FC +:1004500038BD2DE9F047DFF8B08382460127D8F890 +:100460000000EA4D90F8314010F8301F90F831004C +:100470004C4300F003008740A100284618F03AFFE3 +:100480000026DFF87C9312E0DD484030FFF7C8FF1C +:100490000020D9F8081007E055F8202031F9103075 +:1004A0001A4445F82020401CA042F5DB761CBE42D1 +:1004B000EADB40460AE000BF026855F8241092F8D3 +:1004C000612002F0030211412AF81410641EF3D2D5 +:1004D000BDE8F0872DE9F04FDFF82CB34FF00109AC +:1004E000CA4EDBF80000A7B090F8611090F83140D8 +:1004F000C1F3810890F8305009FA08FA60198100B8 +:1005000006EB8407304618F0F5FEBD48403016F083 +:100510002FFABB49403181F80690DBF8000090F8D3 +:100520006000820701D581F80490C00703D0B44869 +:100530004030FFF775FF00202BE0B1484030FFF757 +:100540006FFFDFF8BCB2620006A8DBF8181018F0E5 +:1005500030FE6A0011A8DBF81C1018F02AFE2046B5 +:1005600006A906E056F8202031F910301A4446F862 +:100570002020401EF6D2284611A906E057F8202078 +:1005800031F910301A4447F82020401EF6D209F104 +:10059000010081465045D0DB9D4905E056F8240016 +:1005A00040FA08F021F81400641EF7D2994905E0DA +:1005B00057F8250040FA08F021F815006D1EF7D213 +:1005C00027B0BDE8F08F2DE9F04FDFF83CB24FF0D7 +:1005D00001098E4EDBF80000A7B090F8621090F889 +:1005E000314001F0030890F8305009FA08FA601918 +:1005F000810006EB8407304618F07CFE80484030CE +:1006000016F0B6F97E49403181F80B90DBF8000016 +:1006100090F86000020701D581F80490C00603D568 +:1006200077484030FFF7FCFE00202CE07448403053 +:10063000FFF7F6FEDFF8C8B1620006A8DBF8341059 +:1006400018F0B7FD6A0011A8DBF8381018F0B1FDFA +:10065000204606A907E000BF56F8202031F91030E7 +:100660001A4446F82020401EF6D2284611A906E07A +:1006700057F8202031F910301A4447F82020401E46 +:10068000F6D209F1010081465045CFDB624905E011 +:1006900056F8240040FA08F021F81400641EF7D23E +:1006A0005E4905E057F8250040FA08F021F81500EA +:1006B0006D1EF7D284E72DE9F84F534D04462868A4 +:1006C00090F8311090F8300001FB00F84C484030B1 +:1006D00016F04EF94A4801264030012C067106D129 +:1006E000296891F87010090701D404210171286864 +:1006F000AB4600F5F97990F8611001F003018E40E6 +:100700004749002491F803A02AE000BF444819F8A3 +:1007100004100025C170434904FB08F001EB4007B9 +:100720004FEA4800009018E035484030FFF778FE67 +:10073000334881680DB140460CE03846009A18F005 +:1007400038FD09E037F9102031F910301A44521001 +:1007500027F81020401EF5D26D1CB542E4DB641C66 +:10076000DBF8000090F8F10100F00300401CA0420B +:10077000CCD82B4981F803A0BDE8F88F2DE9F04FC4 +:10078000214D85B0296891F8319091F83010009191 +:1007900009FB01F002901A48403016F0E9F81848B9 +:1007A0000124403084710471C471286890F860009D +:1007B000C00703D012484030FFF732FE28684FF0E0 +:1007C000000B90F8612000F5F97002F0030104FAC3 +:1007D00001FAC2F38102124904FA02F20192C978C5 +:1007E0005C46CDE903016DE00398015D0C48C170E2 +:1007F00002980C49604301EB400600255FE00000D1 +:1008000068081000B90300000407100070641000AD +:10081000006F01202A6F0120766F0120A06F012058 +:100820004007100010560120E248FFF7F9FDE148AB +:100830004038D0E90631876888462DB101998B454B +:1008400030DA4846DC491BE04FEA49021946DA48EB +:1008500018F0AFFC009841464200D84818F0A9FCB7 +:10086000029839464200304618F0A3FC26E000BF4B +:1008700031F9102033F910C06244521021F81020D1 +:10088000401EF5D2CD49009808E000BF31F9103084 +:1008900038F910201A44521021F81020401EF5D2C9 +:1008A0000BF1010B029807E036F9102037F9101010 +:1008B0001144491026F81010401EF5D26D1C554504 +:1008C000B2DB641CBE48006890F8F10100F0030040 +:1008D000401CA04288D801998B452CDAB5480021EC +:1008E0000C4601710199A1EB0B0522E0B148FFF71D +:1008F00097FDB048B0494038D0E90623484607E0A4 +:1009000031F9106032F910703E44761021F8106011 +:10091000401EF5D2A949009808E000BF31F9102027 +:1009200033F910603244521021F81020401EF5D2E5 +:10093000641CA542DADCA3490498C87005B040E6FF +:100940002DE9FF5FDFF878829F4FD8F8000090F81C +:10095000314090F8305007EB840A6019810004FBA5 +:1009600005FB0AEB8506384618F0C4FC4FEA8B01FC +:10097000304618F0BFFC8F4815F0FAFF8D494FF054 +:10098000010981F8069081F80490D8F8000090F8E9 +:100990006000C00702D00846FFF742FDD8F800000B +:1009A00090F86100C0F38101029100F0030103910E +:1009B0000299484609FA01F90399884001900020FC +:1009C00031E07C48FFF72CFD7A484038D0E9063208 +:1009D0008168204607E000BF57F820C033F9108037 +:1009E000C44447F820C0401EF6D2284607E000BFA6 +:1009F0005AF8203032F910C09C444AF820C0401EFA +:100A0000F6D2DDE9000290420BDA584607E000BF5B +:100A100056F8202031F910301A4446F82020401EA4 +:100A2000F6D20098401C00904845CADB0198484522 +:100A30001DDD60480021884681710198A0EB0909FD +:100A400013E05C48FFF7ECFC5A4840388168584690 +:100A500007E000BF56F8202031F910301A4446F85C +:100A60002020401EF6D208F10108C145E9DC5249B8 +:100A700006E000BF57F82400029A104121F8140044 +:100A8000641EF7D24D4905E05AF82500029A10413C +:100A900021F815006D1EF7D258464C4A06E000BFFB +:100AA00056F82010039B194122F81010401EF7D26F +:100AB000BDE8FF9F2DE9F0470546002016F0A9FB91 +:100AC000022016F0A6FB032016F0A3FB404F0020E7 +:100AD0003870384815F04CFFE8054FF0010403D595 +:100AE000FFF771FD3B480470354EDFF8EC80DFF80E +:100AF000EC90306890F86010890712D5290718D556 +:100B0000A90710D53C7090F8F001000602D5FFF758 +:100B100035FE01E0FFF714FF88F8004089F8004037 +:100B200001E0280705D5387818B9FFF7D3FC88F815 +:100B30000040DFF88080A80715D5387878BB30688A +:100B400090F8F001000603D50020FFF7B4FD07E0A0 +:100B5000184815F00DFF88F804401C48FFF779FC91 +:100B600089F800401BE0680719D5306890F8F0015B +:100B7000000603D50120FFF79EFD10E00D4815F09B +:100B8000F7FE306890F87000000702D588F804403E +:100B900002E0042188F804100C48FFF75AFC0320F7 +:100BA00016F052FB022016F04FFBBDE8F047002084 +:100BB00016F04ABBA8081000006F01202A6F012020 +:100BC0000407100040071000706410001056012048 +:100BD00000041000380710004507100044071000FB +:100BE00010B501464022F84818F028FB0121BDE865 +:100BF0001040002016F06DBA38B50446F348F24DA7 +:100C00002060204615F0D9FE00226B4601211046D7 +:100C100016F0A8FA0121002016F087FA287800289B +:100C200002D011F0E0FBECE738BD2DE9FF410024D4 +:100C3000DDE90A760821684617F04EF805460821D6 +:100C400002A817F049F8024600206FF07E0E14E06B +:100C5000002100FB02F30DE007EB010C13F90CC0BF +:100C6000B444F44501DA012403E0BCF17F0F00DD58 +:100C70000224491C9142EFDB401CA842E8DB2046DD +:100C800004B0BDE8F0812DE9FF410AAC082194E8E9 +:100C9000C0010024684617F01FF80546082102A885 +:100CA00017F01AF80146002008E03256D21901D593 +:100CB000012402E0FF2A00DD0224401CA842F4DBEC +:100CC00000200AE02A18B25612EB080201D50124CE +:100CD00002E0FF2A00DD0224401C8842F2DB2046AD +:100CE000CEE72DE9F04F87B04FF0010B15F0D6FE9F +:100CF00004460D4615F0D4FEDFF8D48206460F46B2 +:100D0000D8F8000090F8E70010F0600F05D02046FA +:100D1000294612F033FD04460D46AD48016891F8AE +:100D2000310091F8301000FB01F8012104A80FF008 +:100D3000DBFDDFF8A0920020DFF89CA2D9F80010BC +:100D4000049B324691F91B100390CDF800A0CDE929 +:100D500001313B462046294612F09AFD01200390BE +:100D60000021049BCDF800A0CDE9013132463B467D +:100D70002046294612F08CFD9348403015F0F8FDCE +:100D800091490520403108710846FFF735FF8E482C +:100D90000221D0F808A005A80FF0A6FD8C48424615 +:100DA0000168B1F9C2010190B1F9C4110091084480 +:100DB000401002905046059913F0EFFB8246022145 +:100DC00005A80FF0F4FD01984FF00008824502DC01 +:100DD00000998A450ADA7E4802990068AAEB010167 +:100DE000B0F8C60191FBF0F04FFA80F80499CDE914 +:100DF000001832463B4620462946FFF716FF0128D9 +:100E00001DD0022824D0D9F800100120724A81F8A0 +:100E10001B800390049B8DE80C0132463B46204624 +:100E2000294612F035FDD9F80000A521817601216F +:100E300004A80FF0BCFD07B05846BDE8F08FD9F804 +:100E400000104FF0000B81F81BB00121B02007E02B +:100E5000D9F800104FF0000BB12081F81BB0012130 +:100E600011F0B2FADFE72DE9F04FDFF8648189B0C5 +:100E70004FF0010BD8F8000090F831A090F8300046 +:100E8000079015F00BFE04460D4615F009FE0646C8 +:100E9000D8F800000F4690F8E70010F0600F05D07A +:100EA0002046294612F06AFC04460D46012104A89A +:100EB0000FF01AFDDFF81C914FF00008049BD9F8E1 +:100EC0000000294690F91D20444805900090CDF877 +:100ED0000C80CDE9013232463B46204612F0D8FC68 +:100EE000DDE904030121CDE90030CDE9028132467C +:100EF0003B462046294612F0CBFC3348403015F0E3 +:100F000037FD31490620403108710846FFF774FE6D +:100F10002D480221D0F8088006A80FF0E5FC2C48E7 +:100F20000068B0F9C811B0F9CA0108444010009037 +:100F3000079806990AFB00F2404613F02EFB824602 +:100F4000022106A80FF033FD21484FF00008006889 +:100F5000B0F9C821524503DBB0F9CA21524508DD7A +:100F6000009AB0F8CC01AAEB020191FBF0F04FFA25 +:100F700080F80499CDE9001832463B4620462946C0 +:100F8000FFF753FE4FF48071012829D002282FD09B +:100F9000D9F80010012081F81D80DDE90423CDE996 +:100FA0000032CDE9028032463B462046294612F007 +:100FB0006FFCD9F80000A5210177012104A80FF0EA +:100FC000F6FC584609B038E7B8081000910B00004D +:100FD0000407100008071000EC6F012014750120B1 +:100FE000D9F800204FF0000BB02082F81DB006E0C9 +:100FF000D9F800204FF0000BB12082F81DB011F09D +:10100000E3F9D6E72DE9F04F91B0DFF8B4A3012062 +:101010000F90DAF8000090F831100E9190F830003F +:101020000D9015F03BFD8046894615F039FD0446CC +:101030000D46012106A80FF057FCDAF8000002ABBC +:10104000002690F8340100F00101DE48006890F9B4 +:10105000202090F91F00059183E84500DA480699A1 +:101060000C90CDE9000122462B464046494612F03D +:1010700060FCDAF800000121224690F83401029663 +:1010800000F00100CDE9041006990C98CDE90001AB +:1010900003962B464046494612F04BFCCB4815F0D0 +:1010A00067FCCA49032088710846FFF7A5FDC748B9 +:1010B00002214038D0E90676DAF80000B0F9CEA176 +:1010C000B0F9D0B107A80FF00FFC0AEB0B004010ED +:1010D000059038460E9A079913F05FFA002750459D +:1010E00001DC584508DA0599091AB5480068B0F8D6 +:1010F000D20191FBF0F047B230460D9A079913F0F8 +:101100004CFA0026504501DC584508DA0599091AC1 +:10111000AB480068B0F8D40191FBF0F046B2022170 +:1011200007A80FF044FC0698CDE9000722462B469D +:10113000029640464946FFF7A6FD012826D0022820 +:101140002ED0A0480121224600682B46C77780F8A0 +:1011500020609B48006890F83401CDE9027600F0E9 +:101160000100CDE9041006990C98CDE90001404634 +:10117000494612F0DEFB9348A521006881770121E2 +:1011800006A80FF014FC0F9811B056E68D49002008 +:101190000F900968C87781F820001021B22008E07C +:1011A000884900200F900968C87781F82000102135 +:1011B000B32011F009F9DEE72DE9F04F8DB04FF0C3 +:1011C000010915F06BFC06460F4615F069FCDFF8C7 +:1011D000F0810121D8F8000090F831000A9006A8AB +:1011E0000FF082FBD8F80000764C4FF0000A90F820 +:1011F000E00902AB00F0010120685546DFF8C8B1F4 +:1012000090F9232090F92200059183E825000699A2 +:101210000BF1980BCDE900B15246534630463946A2 +:1012200012F087FBD8F800000121002290F8E009B5 +:10123000029500F00100CDE9041006990395CDE96F +:1012400000B113463046394612F073FB5F4815F083 +:101250008FFB5E49032008720846FFF7CDFC5B4810 +:1012600002214038856A09A80FF03EFBD8F800003B +:10127000B0F9D611B0F9D801084400EBD070401095 +:101280000190DDE90912284613F087F9D8F800101B +:101290000025AB46B1F9D621824203DBB1F9D82152 +:1012A000824206DD019AB1F8DA11101A90FBF1F0D2 +:1012B00045B2022109A80FF07AFB069900228DE8B9 +:1012C0002208134630463946FFF7DDFC012826D0B8 +:1012D00002282ED0216801223B4801F8225F81F8C4 +:1012E00001A0D8F8001091F83411029501F0010125 +:1012F0000591CDE903A206990022CDE9000113462C +:101300003046394612F015FB2168A52081F82100EE +:10131000012106A80FF04BFB48460DB08DE5216872 +:101320004FF0000901F822AF81F801A04021B2205E +:1013300008E021684FF00009B32001F822AF81F8DE +:1013400001A0402111F040F8DEE770B50546012408 +:10135000002015F05EFF022015F05BFF184E30688C +:1013600090F8C0012840C00703D0FFF7BAFC00F096 +:101370000104306890F8C001800704D5A80702D5A1 +:10138000FFF771FD0440306890F8C001400704D5B4 +:10139000680702D5FFF736FE0440306890F8C001B8 +:1013A000000704D5280702D5FFF706FF04400220F6 +:1013B00015F04AFF002015F047FF204670BD0000E1 +:1013C0000407100008071000DC7A0120F80810005C +:1013D00070B5764C4FF6FF714FF43E752068418230 +:1013E000294616F0B3FC00211F200EF131FC2A46DD +:1013F0002168BDE870401F236D4816F0CEBC6B48D5 +:1014000010B500686B4C417D206841744FF48C61CD +:1014100016F09CFC00211A200EF11AFC00211B2062 +:101420000EF116FC1A234FF480626348216816F00F +:10143000B4FC21681B23BDE8104060225F4801F521 +:10144000805116F0AABC2DE9F0415D4D041D0E46F9 +:101450002146284616F07AFC30685A4900EB84038E +:101460008B4201D21C2312E0574A934212D2884287 +:101470000CD28846091A8F081C233A46294616F0D2 +:101480008CFCE21B05EB87011D2311E01D23224686 +:1014900029460EE0904214D2111A8F0890461D235F +:1014A0003A46294616F079FCE21B05EB87011E231C +:1014B000404616F072FC306800EB84003060BDE8F6 +:1014C000F0811E23E3E7F8B53D4C4048009010340E +:1014D000022015F09EFE00211C200EF1B9FB002118 +:1014E0001D200EF1B5FB00211E200EF1B1FB1021D5 +:1014F000204617F0DDFE00202080A07001202B4D3B +:10150000E0704FF6FF71A1802868028AE280437D77 +:101510002F482372E688A0F8F86EA0F8FA1E04227D +:1015200080F8FC3E69461046FFF78DFF012300223C +:101530002146102012F01FFD6946FFF784FF0123AA +:1015400000222146112012F016FD6946FFF77BFFAD +:10155000286890F85012C90703D190F88002C0079C +:1015600008D0012300222146122012F004FD694612 +:10157000FFF769FF012300222146132012F0FBFC34 +:101580006946FFF760FF286890F85002C00708D04E +:10159000012300222146182012F0EDFC6946FFF7D6 +:1015A00052FF022015F050FEF8BD000004071000A5 +:1015B000F0EF010008071000F09F0100F0AF0100FC +:1015C00070641000F0CF0100F0DF0100F0BF0100F7 +:1015D000EC6F01200B4801785A2911D18188B1F5AF +:1015E0007C7F0DD8418800290AD106494078103106 +:1015F000022805D0A0F17002072A01D811F0CAB85C +:10160000704700000000012010B501464022FE484E +:1016100017F014FE0121BDE81040002015F059BD5F +:101620002DE9F041F94CA0F16006092ED4E912052C +:10163000D4E9142316D2DFE806F0051626374658FB +:101640006778870002462B46084600F09DF902465F +:101650000120002117F076FDD4E90223104319433D +:10166000C4E9020175E0084600F08EF90123024644 +:101670000021184617F066FDD4E90A2310431943E8 +:10168000C4E90A0165E002462B46084600F07CF9F1 +:1016900002460120002117F055FDD4E9062310432E +:1016A0001943C4E9060154E0084600F06DF902460A +:1016B0000120002117F046FDD4E90E231043194301 +:1016C000C4E90E0145E002462B46084600F05CF9ED +:1016D000012302460021184617F034FDD4E9042303 +:1016E00010431943C4E9040133E0084600F04CF903 +:1016F00002460120002117F025FDD4E90C231043F8 +:101700001943C4E90C0124E002462B46084600F0C8 +:101710003BF902460120002117F014FDD4E908230B +:1017200010431943C4E9080113E0084600F02CF9FE +:1017300002460120002117F005FDD4E910231043D3 +:101740001943C4E9100104E001208840616808439E +:1017500060602068401C2060BDE8F0812DE9F04108 +:10176000174604460D46002609E0E00703D031463F +:10177000384610F029FE761C6D084FEA340454EA0E +:101780000500F2D1E8E72DE9F041A04CD4E90223AD +:10179000D4E90656104619462A433343D4E90A567B +:1017A000D4E90EC745EA0C053E43D4E9087C9743CB +:1017B0002CEA030CC4E9087CD4E91023AA43B34300 +:1017C000C4E910232268002AC6D06022FFF7C6FFB2 +:1017D000D4E90A016122FFF7C1FFD4E906016222C0 +:1017E000FFF7BCFFD4E90E016322FFF7B7FFD4E98E +:1017F00004016422FFF7B2FFD4E90C016522FFF770 +:10180000ADFFD4E908016622FFF7A8FFD4E9100173 +:101810006722FFF7A3FF6068BDE8F041682200215E +:101820009CE799E72DE9F14F4FF0000915F036F9E3 +:101830000646884615F034F9744A04460D46C2E956 +:101840001401C2E912684FF01D0A4FF0260B15F083 +:101850003CFF00273A460120002117F073FC30407E +:1018600001EA0801084322D0F8B2002115F035FF43 +:10187000410705D50099C90602D54946622010E006 +:10188000C10705D00099490702D54946602008E004 +:10189000009911F0C00F06D010F00A0F03D049468E +:1018A0006420FFF7BDFE09F1010000F0FF097F1C75 +:1018B0005745CFDB15F009FF00273E463246012091 +:1018C000002117F03FFC20402940084320D0F0B20F +:1018D000012115F002FF410705D50099890602D5BF +:1018E0003946632010E0C10705D00099090702D5E9 +:1018F0003946612008E0009911F4C07F06D010F04D +:101900000A0F03D039466520FFF78AFE7F1CFFB21D +:10191000761C5E45D2DDBDE8F84F15F0D6BE10B599 +:101920000446002015F075FC3849002014F00C0F17 +:10193000C1E90800C1E90200C1E90400C1E90600EB +:10194000C1E91000C1E90A00C1E90C00C1E90E00BB +:101950004860086009D1E00607D4A00605D46006F7 +:1019600003D4E00501D4200602D52046FFF75AFF34 +:10197000A00702D0204600F022F8FFF704FFBDE8E0 +:101980001040002015F060BC2DE9F04116461F46BE +:1019900080464FF0FF35002422460120002117F039 +:1019A000D1FB30403940084304D06D1C454501D17E +:1019B0002046D1E6641C402CEED30020CCE62DE975 +:1019C000FF410446012000F038F8804615F066F823 +:1019D000CDE9000115F064F8CDE90201082168465F +:1019E00016F07AF90746082102A816F075F905469F +:1019F000074EE00707D0306842462946B0F8DE308F +:101A0000384600F04AF805E0080910000804100004 +:101A100004071000A00707D5306842462946B0F8F1 +:101A2000DE30384600F089F86A48016841F002016A +:101A300001600FF002FCBDE8FF8130B585B00446BF +:101A4000684614F095FF64480090022C15D00720DA +:101A50008DF80400614C684614F0AFFF002204AB1F +:101A60000121104615F07EFB0121002015F05DFBE1 +:101A7000207830B110F0B7FCEDE703208DF80900B5 +:101A8000E8E715F00BF8564DC5E9120115F008F816 +:101A9000C5E91401A06805B030BD2DE9FF5F9B4684 +:101AA00092460F46002544E000984FF000094C464E +:101AB000A0F101083AE000BF04FB075081B2601CAE +:101AC00000FB075080B23AF811203AF81000101AC3 +:101AD00000B2584502DDB9F1000F0AD0CBF1000188 +:101AE000884213DAB9F1000F06D04FF00009214601 +:101AF00018E04FF0010914E0002604E031466620AA +:101B0000FFF78EFD761CA642F8D90EE0B9F1000F62 +:101B10000BD021466620FFF783FD0098801E84428B +:101B200003D1611C6620FFF77BFD641C4445C3D3D1 +:101B30006D1CBD42B8D3BDE8FF9F2DE9FF5F9B46FA +:101B400092460D46002641E04FF000094C46A5F1B3 +:101B5000010838E006FB0540611C06FB051180B258 +:101B600089B23AF810203AF81100101A00B258451C +:101B700002DDB9F1000F0AD0CBF10001884213DA7F +:101B8000B9F1000F06D04FF00009214617E04FF0E1 +:101B9000010913E0002704E039466720FFF740FD04 +:101BA0007F1CA742F8D90DE0B9F1000F0AD02146F9 +:101BB0006720FFF735FDA81E844203D1611C672012 +:101BC000FFF72EFD641C4445C4D3761C0098864262 +:101BD000BAD3B0E72C071000B915000008091000AF +:101BE00008041000144908604FF40051002015F05B +:101BF00070BA38B5002015F00CFBAFF2170017F0E3 +:101C0000ADF900224FF400546B462146104615F002 +:101C1000A9FA2146002015F088FA002015F014FBDF +:101C20000648A522016804480A74006820F07F4233 +:101C30004A6117F0B7F938BD6004100008071000BA +:101C4000020004D0012A04D0022805D002E00120BD +:101C500000E0042014F015BE0020704710B50146C6 +:101C60004022FE4817F0EAFA0121BDE810400020AA +:101C700015F02FBA30B585B00446684614F078FEEA +:101C8000F74800900CB3012C21D0022C21D0032C5A +:101C900019D108208DF80400F04D0324684614F093 +:101CA0008CFE002204AB0121104615F05BFA0121E5 +:101CB000002015F03AFA2878002804D010F093FBA1 +:101CC000641E002CEADC05B030BD0520E2E70620EA +:101CD000E0E702208DF80900DEE72DE9F14F88B03A +:101CE00014F0DCFE8346029114F0DAFE8146DD4CEE +:101CF00008988A460028206807D0B0F87A1108981A +:101D0000FFF79EFF0490D84812E090F8E70010F02B +:101D1000600F05D05846029911F030FD83460291BC +:101D20002068B0F872110898FFF78AFF0490CF4836 +:101D30000390402007900690C848B821B83817F0A3 +:101D4000D9FA002000900898FFF794FFC3480027B5 +:101D50003E468068059001203D4601902A460120BC +:101D6000002117F0EFF9029A00EA0B001140084336 +:101D700041D0002422460120002117F0E3F9024659 +:101D80000B4600EA090001EA0A01084320D0B348E3 +:101D9000B83800EBC6018E4603C900EA020C01EA1E +:101DA00003085CEA080C12D1DDF814C03CF9178076 +:101DB000DDF810C0E04504DC10431943CEE9000112 +:101DC00005E022463146009B039815F0D6FB7F1CA8 +:101DD0000698641C8442CDDBA048B83800EBC601ED +:101DE000D1E9000280EA090082EA0A02104301D028 +:101DF00000200190761C07986D1C8542AEDB01988F +:101E0000012804D00098401C00907F289BDD019899 +:101E100009B0BDE8F08F2DE9F14F98B014F03EFE07 +:101E2000CDE90C0114F03CFECDE9100118988D4C61 +:101E300000285CD02068B0F87A111898FFF700FFEE +:101E40000F9089480690402082460E9008210CA8E9 +:101E500015F042FF0446082110A815F03DFF444349 +:101E60008348019000F5E6602146029017F020FAC1 +:101E70006100019817F01CFA7848B821B83817F0BB +:101E800039FA4FF000091898FFF7F4FE734800275D +:101E90003C4680680A90C9F100004FF0010B3E46B5 +:101EA000139032460120002117F04CF9DDE90C2394 +:101EB0001040194008436ED000252A460120002119 +:101EC00017F040F9DDE9108C02460B4600EA0800E5 +:101ED00001EA0C01084373D06048B83800EBC70C26 +:101EE000DCE900011040194008430FD093E0DDE920 +:101EF0000C0111F043FCCDE90C012068B0F872111F +:101F00001898FFF79DFE0F9058489BE7B9F1000F16 +:101F10000ADA0A9830F914100F98814201DB002187 +:101F200000E00121029801550A980F9930F9140038 +:101F3000884231DD0299095D11B1012909D06AE0B9 +:101F4000B9F17F0F67DA019909F1010321F8140053 +:101F500051E0DCE9001011431843CCE9001001986E +:101F600030F914100F98091A0A9830F914200F98B4 +:101F7000A2EB000000D54942002800DA404281422D +:101F800005DC139B2A4639465B1C069836E001980F +:101F900020F814203FE052E037DA0299095D012968 +:101FA00001D071B137E0139911F17F0F33DD019941 +:101FB0002A4621F81400139B39465B1E06981DE043 +:101FC0002AE0DCE9001011431843CCE90010019825 +:101FD0000F9A30F914100F98081A0A9931F9141051 +:101FE000A1EB020200D54042002A00DA52429042A0 +:101FF00007DCA9F101032A463946069815F0BDFA17 +:1020000009E0019820F8141005E0DCE90010114304 +:102010001843CCE90010641C6D1C5545FFF64DAF0C +:102020000E48B83800EBC701D1E90001DDE9102303 +:1020300050405940084301D04FF0000B7F1C0E98D0 +:10204000761C8642FFF62DAFBBF1010F05D009F1DA +:102050000109B9F17F0F7FF716AF0BE0000A1000FE +:102060000D1C00000407100014750120EC6F012006 +:1020700070641000584619B0CBE62DE9F04F0546C4 +:1020800085B0002015F0C5F8022015F0C2F814F054 +:1020900007FDCDE90201F84804904027082102A875 +:1020A00015F01AFE0446012D71D1DDE90201CDE9DA +:1020B000000101220023049815F06EFADFF8BC83BA +:1020C00000216FF07E0508EB440A680C05E000BFB4 +:1020D00028F811000AF80150491CA142F8DBDFF88A +:1020E000A0B30320FFF7C6FD0024DBF808902646C6 +:1020F00032460120002117F025F8DDE902231040C7 +:10210000194008431DD039F9141038F9140000297A +:1021100000DA4942002800DA404281420ADA3246B7 +:102120000021049815F01EFA0AF8040039F814107A +:1021300028F814102B4632460021049815F01DFA99 +:10214000641C761CBE42D3DB6D1C7F2DC9DD0025CF +:102150002C4622460120002116F0F4FFDDE902237F +:1021600010401940084307D01AF9053022460021D3 +:10217000049815F002FA6D1C641CBC42E9DBC148EE +:1021800026220499006800F5865017F012F8022004 +:1021900015F05AF8002015F057F805B039E62DE98A +:1021A000F04F87B0002015F034F8022015F031F818 +:1021B0004FF0000B14F074FCCDE90401AE4803901D +:1021C000082104A815F088FD06460020DFF8AC823F +:1021D000CDE9000008EB460505EB06090320FFF7F3 +:1021E00049FDDFF89CA200242746DAF80800029097 +:1021F0001AE03A460120002116F0A4FFDDE904238D +:102200001040194008430ED03A460021039815F0BB +:10221000A9F92855029830F8141028F81410002055 +:1022200009F80400641C7F1CB442E2DB00273C4632 +:1022300015E022460120002116F084FFDDE9042389 +:1022400010401940084309D0EB577F2B05DA22468E +:1022500000215B1C039815F090F97F1C641CB742A9 +:10226000E7DB0320FFF706FD00200124DAF8083041 +:1022700014E000BF33F9102038F91010002A00DAFA +:102280005242002900DA49428A4206DA29567F2959 +:1022900003DA491C295409F80040401CB042E9DB2C +:1022A00000273C4616E022460120002116F04AFF96 +:1022B000DDE904231040194008430AD0EB5713F11D +:1022C0007F0F05DD224600215B1E039815F055F9AE +:1022D0007F1C641CB742E6DB0320FFF7CBFC684899 +:1022E0008368002019E000BF19F80010A1B933F984 +:1022F000101038F91020002900DA4942002A00DACB +:102300005242914208DA295611F17F0F04DD491E2D +:102310002954022209F80020401CB042E4DB0024CA +:10232000274627E03A460120002116F00BFFDDE9A1 +:1023300004238246029110401940084319D02B57BC +:102340003A460021039815F018F919F8040078B9F5 +:10235000DDE9002302994AEA02001943CDE90001B0 +:1023600038F91400FE30B0F5FE7F01D94FF0010BB3 +:10237000641C7F1CB442D5DB0821684615F0ACFC18 +:10238000B04208DBBBF1000F03D00021B42010F0F5 +:102390001BF807B03DE5002036E00320FFF76AFC9C +:1023A0003748002427468068029023E03A460120FF +:1023B000002116F0C7FEDDE9043C02468E461840B7 +:1023C00001EA0C01084314D0DDE9000302EA000C25 +:1023D0000EEA03015CEA010C0AD119F90410012983 +:1023E00035D002296DD002434EEA0301CDE9002128 +:1023F000641C7F1CB442D9DB0821684615F06CFCD4 +:10240000B04208DA0AF1010082461F48006890F8DD +:10241000E2115145C1DC1B4826220399006800F5F2 +:10242000865016F0C6FE0821684615F055FCB042ED +:1024300002DBBBF1000F03D00021B4200FF0C4FF7A +:10244000022014F001FF002014F0FEFEA1E7029824 +:1024500038F9141030F91400002801DB034600E0BD +:102460004342002900DA49428B420FDC295D7F2973 +:102470000CD028F8140050E0847F01207064100014 +:10248000000A10000807100004071000002109F8D6 +:102490000410DDE90001024302984EEA0103CDE990 +:1024A000002330F9141038F91400002900DA4942E9 +:1024B000002800DA4042814232DD285D401E285566 +:1024C0002EE0029830F9141038F91400002901DBCD +:1024D0000B4600E04B42002800DA4042834205DC14 +:1024E00028577F3002D028F81410E6E7002009F8BA +:1024F0000400DDE900130A434EEA0300CDE90020A1 +:10250000029830F9141038F91400002900DA494211 +:10251000002800DA4042814202DD285D401CCEE7FF +:102520002B573A460021039815F027F860E72DE96C +:10253000F04106460124002014F06BFE022014F046 +:1025400068FE4A4DF0074FF000074FF0A50808D08D +:1025500000F01BF810F0010403D02868C77680F85B +:102560001A80B00708D500F056F82040040003D0C8 +:102570002868477780F81C80002014F065FE022050 +:1025800014F062FE2046BDE8F0812DE9FC470126EB +:1025900014F084FA04460D4614F082FADFF8D09065 +:1025A00007468846D9F8000090F8E70010F0600F61 +:1025B00005D02046294611F0E1F804460D46D9F829 +:1025C000000090F87001C0071FD0CDE900782246C6 +:1025D0002B46284814F0E0FFD9F8000090F870115D +:1025E000C90712D090F8E700C0F3411002284FF05D +:1025F000000002D3FFF70FFC01E0FFF76EFB0600BF +:1026000003D1012174200FF0DFFE0020FFF732FB21 +:102610003046BDE8FC872DE9FC41012614F03EFA66 +:1026200004460D4614F03CFA114F3A6892F87821AE +:10263000D20715D0CDE9000122462B460E4814F0F2 +:10264000ABFF386890F87801C00709D00120FFF788 +:1026500044FB060004D14FF4807174200FF0B4FEE7 +:102660000120FFF707FB3046BDE8FC81080710009A +:1026700004071000EC6F01201475012010B5FFF75E +:10268000B8FA0120FFF7F9FC012000F075F953209A +:10269000FFF74DFF00F001044FF4D67001F058F938 +:1026A000204205D0FEF70FFFBDE81040FEF7A7BEA1 +:1026B00010BD10B5FFF79DFA0120FFF7DEFC0120E9 +:1026C00000F05AF940F2FF10FEF73FFE002803D059 +:1026D000BDE81040FEF793BE10BD000010B50146E6 +:1026E0004022FD4816F0AAFD0121BDE8104000205F +:1026F00014F0EFBC30B585B0684614F039F9F748EE +:1027000002230078B0B10321012816D0032817D086 +:10271000022818D00422052818D0042819D0072828 +:102720001AD006281BD008281CD009281DD00A283A +:102730001ED01FE08DF806301CE08DF8061019E061 +:102740008DF8081016E08DF8083013E08DF80A2097 +:1027500010E08DF80A100DE08DF80B100AE08DF8EE +:102760000B3007E08DF8062004E08DF8082001E02A +:102770008DF80B20DA48D84D03240090684614F0F9 +:102780001CF9002204AB0121104614F0EBFC0121DE +:10279000002014F0CAFC2878002804D00FF023FE93 +:1027A000641E002CEADC05B030BD2DE9F04FCB4EA5 +:1027B000044687B008208846307014F06FF9CDE9E0 +:1027C0000001402005903620C64D03907CB3012CBB +:1027D0003AD0022C4AD00A20042C55D0052C7DD1A9 +:1027E000307014F065F9CDE90001BB4C286841F266 +:1027F0009A01383400EB010BDFF8ECA2262003909D +:102800000821684615F068FA0746B8F1010F65D14E +:102810003A466946504614F0FFFEDFF8D0926FF05A +:102820007E0109EB4700029000204A0C43E0FFE7DD +:10283000DFF8B4A2A84C296841F2E600AAF1880AA0 +:10284000183401EB000BDBE714F02AF9CDE90001A5 +:10285000A14C286841F21C11DFF88CA21C3400EB5B +:10286000010B2620AAF1680A0390C9E709203070FD +:10287000DFF874A2984C286841F24211AAF1400A8C +:10288000283400EB010BBBE7307014F00FF9CDE9F1 +:102890000001DFF854A2904C286841F26401AAF1CB +:1028A000200A343400EB010BAAE700BF29F81020FE +:1028B000029B1954401CB842F8DB8846FFF71AFF08 +:1028C000206800252E46049032460120002116F093 +:1028D00039FCDDE900231040194000E049E00843DD +:1028E0001DD0049830F9151039F91500002900DAC7 +:1028F0004942002800DA404281420ADA3146504615 +:1029000014F078FE02994855049830F8151029F80B +:10291000151042463146504614F073FE6D1CBD4200 +:1029200003D00598761C8642CEDB08F10108B8F189 +:102930007F0FC3DD00252C4622460120002116F022 +:1029400001FCDDE9002310401940084306D002983D +:1029500021464257504614F054FE6D1CBD4203D030 +:102960000598641C8442E7DB51465846039A16F0EA +:1029700020FC07B0BDE8F08F10B50446002014F02D +:1029800048FC022014F045FC21460020FFF70DFF13 +:1029900021460120FFF709FF21460220FFF705FF2E +:1029A00021460420FFF701FF21460520FFF7FDFE29 +:1029B000022014F049FCBDE81040002014F044BC93 +:1029C0002DE9F04F454E04468DB00820307014F0CC +:1029D00065F8CDE90601DFF8188136200590D8F8B2 +:1029E000000010213F4D90F8E3910991ACB3012C08 +:1029F0003FD0022C4ED00A21042C5CD0052C6AD189 +:102A0000317014F055F8CDE9060137480090286878 +:102A100041F29A010844049026200590D8F800005D +:102A20002D4F383790F8E5910820099000200A9042 +:102A3000082106A815F050F9DFF8B0B006460BEBF8 +:102A40004605A81908900020CDE90200FFF752FEC4 +:102A500000242046D7F800A066E0FFE722481E4F7A +:102A600088380090286841F2E6010844183704903D +:102A7000DCE714F015F8CDE906011B48164F68385D +:102A80000090286841F21C1108441C37049026204D +:102A90000590CBE709213170134941F242124039C8 +:102AA000009129680C4F11440491283790F8E49163 +:102AB00040200990BAE731700B4941F26402203995 +:102AC00000912968044F11440491343790F8E5913E +:102AD00008200990AAE722E1400A100068041000CB +:102AE0008D2600000807100034800120706410005B +:102AF0000407100002460120002116F023FBDDE947 +:102B000006231040194008430CD04146009814F0A9 +:102B100071FD28553AF814102BF81410089800216C +:102B20000155641C08F101008046B442E2DB002438 +:102B3000204615E002460120002116F003FBDDE9E6 +:102B4000062310401940084308D02A577F2A04DA88 +:102B50004146521C009814F054FD641C08F1010019 +:102B60008046B442E6DBFFF7C5FD002001243B6848 +:102B700014E000BF33F910203BF91010002A00DAEE +:102B80005242002900DA49428A4206DA29567F2950 +:102B900003DA491C295408990C54401CB042E9DB63 +:102BA0000024A0466FF07E0A15E042460120002175 +:102BB00016F0C8FADDE9062310401940084308D092 +:102BC0002A57524504DD4146521E009814F019FD63 +:102BD000641C08F10108B442E7DBFFF78BFD00201D +:102BE0003B6817E00899095C99B933F910203BF963 +:102BF0001010002A00DA5242002900DA49428A42C3 +:102C000007DA2956514504DD491E29540899022244 +:102C10000A54401CB042E5DB0024204627E002466F +:102C20000120002116F08EFA0191DDE9062382468B +:102C300010401940084318D02A574146009814F014 +:102C4000E0FC0898005D78B9DDE90121039B4AEAC0 +:102C500001001A43CDE902023BF91400FE30B0F541 +:102C6000FE7F01D901200A90641C08F10100804612 +:102C7000B442D4DB082102A815F02EF8B04247DA9E +:102C8000002037E0FFF736FD386800240190204629 +:102C900025E002460120002116F054FADDE9068CF9 +:102CA00002460B4600EA080001EA0C01084314D072 +:102CB000DDE9020C02EA000103EA0C0851EA08010E +:102CC0000AD10899095701292BD0022959D002436A +:102CD00043EA0C03CDE90223641C0AF10100824699 +:102CE000B442D6DB082102A814F0F6FFB04204DAA1 +:102CF0000B98401C0B904845C4DBDDE904020099A9 +:102D000016F057FA082102A814F0E6FFB04202DBE1 +:102D10000A98002803D0B52009990FF055FB0DB093 +:102D200028E601983BF9141030F91400002801DB63 +:102D3000844601E0C0F1000C002900DA49428C45CC +:102D400005DC295D7F2902D02BF8140045E00898A6 +:102D500000210155DDE90201024301980B43CDE951 +:102D6000022330F914003BF91410002800DA404225 +:102D7000002900DA4942884232DD285D401E28558C +:102D80002EE0019830F914103BF91400002901DB02 +:102D90008C4601E0C1F1000C002800DA4042844575 +:102DA00005DC28577F3002D02BF81410E5E708988F +:102DB00000210155DDE90201024301980B43CDE9F1 +:102DC000022330F914003BF91410002800DA4042C5 +:102DD000002900DA4942884202DD285D401CCEE726 +:102DE0002A575146009814F00CFC75E710B50020E6 +:102DF00014F00FFA022014F00CFA0020FFF7E0FDA7 +:102E00000120FFF7DDFD0220FFF7DAFD022014F0BC +:102E10001BFABDE81040002014F016BA2DE9F04767 +:102E2000FF4800252C46D0E91478D0F834902E467F +:102E3000824632460120002116F084F9384001EA2A +:102E40000801084304D019F80600A84200D9054635 +:102E5000761C402EEDD3DAE91678DAF838900026A1 +:102E600032460120002116F06DF9384001EA0801D0 +:102E7000084304D019F80600A04200D90446761C85 +:102E8000402EEDD3DAF8442050461570DAF8481099 +:102E90000C70DAF82C30DAF82470DAF830601B782D +:102EA0003F782B443B44DAF8287036783F78264444 +:102EB0003E44D0E9147C57EA0C070DD0D0E9167CCB +:102EC00057EA0C070AD0FF27B34213D2F31A2B4458 +:102ED000FF2B07D813700BE0147009E015700D700C +:102EE000BDE8F0871770826942F40072CAF81820B2 +:102EF0000C70F5E79E420DD29B1B2344FF2B01D89B +:102F00000B7005E00F70816941F40071CAF8181068 +:102F10001570E5E71570EBE72DE9F0411F460D460A +:102F2000002A1FDDBE4C77B1B4F90A60114611F0DA +:102F300096FBB042287812DAFF2807D2401C28708E +:102F40000020BDE8F081B4F90860EFE7A0691FB187 +:102F500040F00200A06105E040F40060FAE708B12B +:102F6000401E28700120ECE72DE9F0411E460D4679 +:102F7000002A1ADDAA4C66B1B4F90A70114611F0A4 +:102F80006EFBB84211DD287850B1102804D31038F8 +:102F900003E0B4F90870F1E7002028700020D0E7C2 +:102FA000A06926B140F00100A0610120C9E740F40A +:102FB0008060F9E72DE9F14F82B000259848029A28 +:102FC0002C46FF2102B3D0F82C9002264FF0180BAC +:102FD00089F80010D0F8308088F80010B0F90A7035 +:102FE000310200910169002900DC01258C4840690B +:102FF000002800DC0124FFF711FFFFF77BFB00989E +:103000000FF07DF985B121E0D0F824904FF40066EF +:103010004FF0180B89F80010D0F8288088F80010BD +:10302000B0F90870F110DCE7DFF8F4A13A46DAF8FD +:103030001C00DAF81010006800F0D7FC012805D158 +:10304000DAF8181031430125CAF818108CB9DFF8E6 +:10305000D0A13A46DAF82000DAF81410006800F03F +:10306000C4FC012805D1DAF8181031430124CAF84C +:1030700018100DB1002C4ED12F4626464FF0170ADE +:103080004FB96748029BC16902690F6849463846D3 +:10309000FFF76AFF07464EB96148029B016A426921 +:1030A0000E6841463046FFF75FFF0646FFF7B6FE63 +:1030B000FFF720FB00980FF022F907B116B9BAF11B +:1030C000010ADDD22F46564DABF101063FB9E86942 +:1030D000029B494600682A69FFF71EFF07463CB974 +:1030E000286A029B414600686A69FFF715FF04469B +:1030F000FFF794FEFFF7FEFA00980FF000F907B112 +:103100000CB9761EE2D2012F05D1012C03D1A8699A +:1031100020F40070A861BDE8FE8F2DE9F04F9A46BB +:10312000914600223E4B83461446B3F90C7010467C +:103130000123904615E000BF09EBE40504F0070CFD +:103140002E7803FA0CF535420AD03BF91250BD42F5 +:1031500003DC0AF80230012001E00AF80280521C68 +:10316000641C8A42E8DB05E42DE9FF5F00244FF090 +:1031700001089A4617462546DFF8A4904646DDF832 +:103180003CB051E00AEBE50005F00701007806FAD3 +:1031900001F2024247D01BF8040001283FD00098FA +:1031A000B9F90C1030F914208A421DDA2946019829 +:1031B00014F04DFAFF280EDA401CC2B24FF000089E +:1031C0002946019814F045FA009830F814100E982A +:1031D00020F8141023E00BF80460D9F8181041F01F +:1031E0000801C9F818101AE00E9830F914000028E8 +:1031F00013DD401AA2EB010100D54042002900DA9C +:103200004942884209DC2946019814F020FA401E00 +:10321000C2B22946019814F01CFA0BF8046001E0D0 +:1032200068041000641C6D1CBC42ABDB404604B05B +:10323000BDE8F09F2DE9FF5F00244FF001089A469A +:10324000174625464646DFF86C94DDF838B030E086 +:103250000AEBE50005F00702017806FA02F00842E1 +:1032600026D01BF80400012821D0009830F9141052 +:10327000B9F90C0081421ADD2946019814F0E7F9EA +:1032800000280CDD4FF00008042801DB001F00E0DF +:103290000020C2B22946019814F0DBF907E00BF8D0 +:1032A0000460D9F8181041F00401C9F81810641C22 +:1032B0006D1CBC42CCDB4046B9E72DE9F04F95B020 +:1032C0000024254620210CA816F014F8282102A875 +:1032D00016F010F8F7480169002900DC0124426962 +:1032E000002A00DC0125F34A81460646FF235032BE +:1032F000406B00F084FBEF4AFF2358327169B06BDA +:1033000000F07DFBFFF78AFDFFF7F4F94FF4806AC8 +:1033100050460EF0F4FF8CB1D9F81C00E54A4E4639 +:1033200000680CAB5032D9F81010FFF7F6FE0128F8 +:1033300004D1B069012440F00800B0618DB1D9F822 +:103340002000DC4A4E46006802AB5832D9F814100F +:10335000FFF7E3FE012804D1B069012540F0080021 +:10336000B0610CB1002D78D12646A84600276EB971 +:103370000CA80090D9F81C00CE4BD9F8102000689A +:103380005033D9F83410FFF755FF0646B8F1000F57 +:103390000DD102A80090D9F82010C64BD9F81420FE +:1033A00008685833D9F83810FFF744FF8046FFF714 +:1033B00035FDFFF79FF950460EF0A1FF16B1B8F1A9 +:1033C000000F02D17F1C602FD1DBDFF8ECB2D9F8FF +:1033D0001000264641000BF5E6684C46584615F0AD +:1033E00067FF60694100404615F062FF0027D14643 +:1033F000FFF780F948460EF082FF5EB90CA8CDE9D0 +:1034000000B0E069AB4B226900685033616BFFF795 +:10341000ABFE06465DB902A9CDE90081206AA54B45 +:10342000626900685833A16BFFF79EFE0546FFF7FF +:10343000F5FCFFF75FF948460EF061FF06B115B9DC +:103440007F1C602FD4DB012E07D1012D05D1A0698F +:10345000810502D520F40070A06115B083E62DE946 +:10346000FF5F4FF0010800259A4617462C46DFF80B +:1034700044924646DDF83CB03AE000BF0AEBE40077 +:1034800004F00702017806FA02F008422FD01BF878 +:10349000040058BB2146019814F0ACF80099B9F922 +:1034A0000E2031F915304946934212DD0E9A7F3ACB +:1034B000904208DD0E99421A2146019814F0A1F8B5 +:1034C0004FF0000812E0886940F04000C9F8180089 +:1034D0000CE00BF804600E99C1F17F01814205DD1B +:1034E0000E9942182146019814F08BF86D1C641C4B +:1034F000BD42C3DB40469AE62DE9F04F6D4C9FB0CC +:103500002169B9B3002083466069A0B300208246D8 +:10351000BBF1000F02D0BAF1000F5AD1674B04ADD6 +:103520000DCB85E80D00634A7F235032E06B00F03D +:1035300066FA604A7F2358326169206C00F05FFAB6 +:103540000026A14604A85C4650F826805546202156 +:1035500011A815F0CFFE282107A815F0CBFED9F849 +:103560001810002721F04001C9F81810FFF7C2F821 +:1035700034B114E000E001E00120C4E70120C6E717 +:1035800011A9CDE90081D9F81C104A4BD9F81020B7 +:1035900008685033D9F83C10FFF761FF044675B94D +:1035A00007A9CDE90081D9F82010424BD9F81420A1 +:1035B00008685833D9F84010FFF751FF0546FFF768 +:1035C0002DFC04B115B97F1C182FCFDB761C032E00 +:1035D000B8D31FB0C7E570B5364C00260546A661C6 +:1035E000012863D0022D63D0032D6AD00120207002 +:1035F000607968B12F4A002350322169606B00F076 +:10360000FEF92C4A002358326169A06B00F0F7F9EB +:10361000A07958B1274922695031E06B13F0FCFFC3 +:10362000244962695831206C13F0F6FFE07810B13C +:103630000020FFF7BFFC207960B1E07838B16178F5 +:10364000606A00F0CAF96178A06A00F0C6F901204A +:10365000FFF7B0FC607908B1FFF72FFE012D32D0E3 +:10366000022D32D0032D32D084F80060FFF742F8EB +:10367000A07958B1207938B1A178E06A00F0ADF9AD +:10368000A178206B00F0A9F9FFF736FFFFF732F8B9 +:10369000012D1FD0022D1FD0032D20D01021A06995 +:1036A00000F0C2F9A069E0B1002070BD03209EE7E0 +:1036B00005209CE76804100070641000BC950100B0 +:1036C000FFE7072093E7022002E0042000E0062045 +:1036D0002070CBE74021E2E74FF40071DFE70821DB +:1036E000DDE7012070BD70B5EA4D0C46022828D0F8 +:1036F00013F0D4F9C5E9140113F0D2F9C5E91601A4 +:10370000E4480821503014F0E7FA2861E148082124 +:10371000583014F0E1FA686104F190006862401CCE +:10372000A862401CE862401C28634B386863203064 +:10373000C5E90E044838286474309534C5E911048D +:1037400070BD13F0AFF9C5E9140113F0ADF9D5E779 +:1037500010B5D1490020FFF7C6FFCE48CF49C1615F +:10376000091D0162CE490B6893F8882112F001040B +:10377000C4704FF0000204D0436A1A70836A1A7052 +:1037800008E0446A93F8923123700B68846A93F8D6 +:10379000933123700B6893F88841C4F3400404719B +:1037A00014B1C36A1A7006E093F89421C36A1A70C0 +:1037B0000A6892F89521036B1A70096891F88821BC +:1037C000C2F380034371C2F3C0028271B1F88A214F +:1037D0000281B1F88C214281B1F88E218281B1F849 +:1037E0009021C28191F89621427091F897118170D1 +:1037F000BDE810400020EEE610B5AA490320FFF70F +:1038000072FFA649A3481C31C161091D0162A44988 +:103810000B6893F8D92A12F00104C4704FF000022B +:1038200004D0436A1A70836A1A7008E0446A93F8F5 +:10383000DA3A23700B68846A93F8DB3A23700B68DA +:1038400093F8D94AC4F34004047114B1C36A1A70DE +:1038500006E093F8DE2AC36A1A700A6892F8E52A2D +:10386000036B1A70096891F8D92AC2F38003437177 +:10387000C2F3C0028271B1F8DC2A0281B1F8DF2AFA +:103880004281B1F8E12A8281B1F8E32AC28191F83C +:10389000E62A427091F8E71A8170BDE810400320D3 +:1038A00099E67D4910B598310120FFF71CFF7B494F +:1038B00078481031C1610021C0E916110A46416102 +:1038C00077490B6893F8A04114F00104C47004D048 +:1038D000436A1A70836A1A7008E0446A93F8AA313E +:1038E00023700B68846A93F8AB3123700C6894F8EA +:1038F000A031C3F34003037113B1C36A1A7006E029 +:10390000C36A94F8AC211A700A6892F8AD21036B6F +:103910001A70096891F8A021C2F380034371C2F3C1 +:10392000C0028271B1F8A2210281B1F8A4214281C2 +:10393000B1F8A6218281B1F8A821C28191F8AE2107 +:10394000427091F8AF118170BDE81040012042E64D +:103950002DE9F04107460124002013F05AFC022013 +:1039600013F057FC504E78074FF000054FF0A508B4 +:103970000AD5FFF7EDFE10F0010405D03068C577D9 +:1039800080F8205080F81E8038070AD5FFF789FF9D +:103990002040040005D0306800F8225F457000F830 +:1039A000018C3F48006890F80E0BC0070CD0F8055A +:1039B0000AD5FFF721FF2040040005D0306800F849 +:1039C0002A5F457000F8018C022013F03DFC0020B6 +:1039D00013F03AFC2046BDE8F08102788A4201D912 +:1039E000511A00E000210170704710B5144610F024 +:1039F00036FEA04201DC012010BD002010BDF0B554 +:103A000000252C4601260CE002EBE40704F0070C2D +:103A10003F7806FA0CFE1EEA070F01D003556D1C15 +:103A2000641C8D42F0DBF0BD70B504460D46C00746 +:103A300002D083200EF0C8FCA00703D529468420BD +:103A40000EF0C2FC600703D5294685200EF0BCFCB1 +:103A5000200703D5294686200EF0B6FC600603D564 +:103A600029468B200EF0B0FC200603D529468C2079 +:103A70000EF0AAFCE00503D5294687200EF0A4FC31 +:103A8000A00505D52946BDE8704088200EF09CBCF5 +:103A900070BD000068041000DC7A0120580A100094 +:103AA00004071000EC7E012008071000DFF8849165 +:103AB00008B5614D0024DFF884A1C9F80040604ECC +:103AC0002C60DFF88081CAF80040DFF87CB13460F8 +:103AD000C8F80040CBF8004000226B465B49104616 +:103AE00013F040FB0098810713D5FCF787FC2F6883 +:103AF0002C60FCF781FC17F0530F02D03846FEF71C +:103B000016FD17F4D67F02D03846FFF721FF0221B9 +:103B10008BE0810504D5FEF76CF84FF4007184E06A +:103B2000410514D5FCF76AFC37683460FCF764FC87 +:103B3000F80701D0FDF74CFCB80701D5FDF7C3FC31 +:103B4000780701D5FDF75BFC4FF480616DE001065D +:103B50000CD5FCF753FCD8F80070C8F80040FCF70F +:103B60004BFC3846FDF7DBFE80215EE081020DD57F +:103B7000FCF744FCDAF80070CAF80040FCF73CFCA3 +:103B80003846FDF7E2FB4FF400114EE0C10404D5C6 +:103B9000FEF774FD4FF4805147E0010204D5FDF7B4 +:103BA00019FD4FF4000140E0010504D5FEF781FD49 +:103BB0004FF4006139E0410227D5FCF71FFCDBF828 +:103BC0000070CBF80040FCF717FCF80701D0FEF7B7 +:103BD00010F8B80705D50120FEF74FFA0120FEF7CF +:103BE000CBFE38070ED51A4F386890F8C101000691 +:103BF00001D5FEF7D4FA386890F8C101400601D526 +:103C0000FFF7F4F84FF480010FE0C0057FF564AFD3 +:103C1000FCF7F4FBD9F80070C9F80040FCF7ECFBA6 +:103C20003846FCF747FF4FF48071002013F07DFA0F +:103C300052E7000014071000180710001C071000BE +:103C4000200710002407100028071000839FF000B1 +:103C5000040710002C4810B501682C480268134670 +:103C600092EA010F4ED02A4ACC07126834D092F85B +:103C70002B43E40702D043F0010303608B072ED5EA +:103C800092F84033DB0703D0036843F0020303607C +:103C90000B0728D592F86033DB0703D0036843F0A5 +:103CA000080303604B0622D592F86033DB0703D08C +:103CB000036843F040030360CB051CD592F8932AB8 +:103CC000520703D5026842F48072026089050168D8 +:103CD00015D541F4007114E023F00103CDE703682A +:103CE00023F00203D3E7036823F00803D9E703684E +:103CF00023F04003DFE7026822F48072E5E721F455 +:103D00000071016010BD000034071000F0041000C5 +:103D1000040710002DE9F047DFF868929A4C00255F +:103D2000D9F8000090F8311084F8301090F8302065 +:103D3000964884F831205143037B84F8333000F1F6 +:103D400040032360837B0EB284F82D3080467700D9 +:103D50000FE02A463146D8F808000FF086FA0146EF +:103D6000226806FB05F002EB40003A4615F021FA06 +:103D70006D1C94F82D00A842EBDC8548854900783D +:103D800009780843400711D583486060D9F80010CE +:103D900091F8F11189074A0F94F83110921C4A43A7 +:103DA000D8F81010BDE8F04715F003BABDE8F08769 +:103DB0002DE9F041764F774C00263D682068054399 +:103DC000012013F026FA40216F4815F093FAE80716 +:103DD00006D0FFF79FFFE80601D500F083F8012623 +:103DE0006E480078400603D5E80601D50DF025FAA7 +:103DF000280702D500F0A5F8012669480168624845 +:103E0000C161056222684262604A2946654D526876 +:103E100082622A7880F82C20CA071CD00446C80683 +:103E200019D5584F386890F85002C00706D000F0F6 +:103E30006DFE18B9E06940F01000E061386890F854 +:103E40008002C0070CD000F061FE48B9E06940F084 +:103E50002000E06104E03878400601D50DF0EDF96E +:103E6000012013F0F1F9002E0CD02878052807D096 +:103E7000062805D00121BDE8F041022013F029B940 +:103E80000221F8E7BDE8F081474810B50078002826 +:103E900027D13E4CD4E9060100F03BFE94F83110E6 +:103EA000A06A00F05EFDFFF783FF3648006890F8D7 +:103EB0006003C10715D0810713D50024400915F010 +:103EC00015FB00B10124394801788C4209D00470F7 +:103ED0000CB1082100E01021BDE81040032013F0D0 +:103EE000F8B810BD2DE9F0412648284E264C006850 +:103EF000B16990F8315090F8307039B1264884F8A3 +:103F00003050C2386A00206115F053F9F16939B1B7 +:103F1000214884F8317098387A00606115F049F9C9 +:103F20001B481C490078097808438006AAD51A481E +:103F30004C38E0606A00716ABDE8F04115F039B9AB +:103F4000A0E770B50F48114E0F4C0068716B90F8E8 +:103F5000312090F8305031B184F8302014485200AC +:103F6000A06315F026F9B16B002909D0104884F838 +:103F700031502A306A00E063BDE8704015F019B98D +:103F800070BD00000407100068761000800A100061 +:103F9000F4041000F80410000E0801203C07100083 +:103FA000F0041000E8041000E9041000C804100038 +:103FB0003E090120174810B5174904780020086011 +:103FC00000F086F800F0CAFB052C1AD0062C18D099 +:103FD0001249012008701248006890F8700000072C +:103FE00006D41048016821F0020141F0040101608B +:103FF000012105200EF0E4FC4FF48071002013F045 +:1040000068F800F0E1FD0221BDE81040012013F046 +:1040100060B80000E8041000EC0410004B0710002A +:104020000407100014071000554910B50978002442 +:104030000122012909D0C10713D05249032409687C +:1040400091F85032DB070BD106E04F480078012889 +:1040500001D14E48027010BD91F88012C90700D0FE +:104060000B24400703D54A4844F480740270002CA6 +:10407000F1D0FCF7C3F94748016821430160FCF720 +:10408000BBF9012105200EF09BFCBDE810404FF468 +:104090008071002013F01DB810B5C00717D0394843 +:1040A000006890F8C101010601D440060FD5FCF765 +:1040B000A5F93948016841F008010160FCF79CF955 +:1040C000BDE810404FF48001002013F002B810BD8D +:1040D00010B500F079FD0221012013F026F801202F +:1040E00013F097F840212D4815F004F92B490120D1 +:1040F00081F82C0013F0A8F80121022012F0E9FF4A +:10410000BDE8104000F023BB70B52548254E05687A +:10411000306890EA050426D055B160B104EA050084 +:104120000446FFF7B9FF2046FFF77EFF356070BDFC +:10413000FFF7CEFFFAE700F047FD0221012012F061 +:10414000F4FF00F0F3F800F0FAFA2C402046FFF7F5 +:10415000A3FF2046FFF768FF00F0DEFA02210120EE +:1041600012F0B7FFE2E7002DE1D10F4800780528F3 +:1041700001D00628DBD13560BDE87040A8E700001B +:104180004A07100004071000C40610004C07100076 +:104190003807100014071000280710006876100078 +:1041A00030071000EC041000E80410002DE9F04185 +:1041B000FF4800242646006890F84010C90739D00F +:1041C000FC4F3978022912D0042903D005290BD0DD +:1041D000062909D090F841500DF091F802460021CF +:1041E000F548012A0BD028E090F84350F4E790F806 +:1041F000425090F89000C006EED50126ECE73A78E0 +:10420000052A1AD00A460160AA4213DDEB4A137848 +:10421000BBB1016011703878052818D000F0BFF8E4 +:10422000044600F0C2F8044300F0CDF8044300F067 +:10423000D8F804432046BDE8F0810268521C0260B1 +:10424000E2E716B101201070E5E70160E3E7012421 +:10425000F0E710B501464022D94814F0EFFF0121E4 +:10426000BDE81040084612F034BF2DE9FF47D148A1 +:10427000007802281CD0032816D0CD4EDFF84493D6 +:10428000DFF844A301274FF00408052814D00628BE +:1042900068462DD000F046F9CC480090684612F0F0 +:1042A0008CFB04B0BDE8F087684600F0FCF8F3E74B +:1042B000684600F0B2F8EFE7684612F059FBFFF7E6 +:1042C00075FF04464025C0070BD0306890F8700099 +:1042D000000704D500F093F88DF8040001E08DF894 +:1042E0000480E00601D58DF806708DF808700FE0A7 +:1042F000002412F03DFB3068012590F870000007A3 +:1043000004D500F07CF88DF8040001E08DF80480FD +:10431000C9F80040CAF80050BEE710B500F054FCE0 +:104320000221BDE81040012012F0D3BEA2490020B6 +:1043300008607047A04900200860704738B5002029 +:1043400012F067FFA248006810B100F051FA01E0D6 +:1043500000F011FA9748007800F043F90446AFF2F4 +:10436000450100F029FC2046FFF77FFF01280ED110 +:1043700001216B460022084612F0F4FE0121084696 +:1043800012F0D3FE8E48007830B10EF02CF8BDE864 +:104390003840002012F058BFFFF776FDF7E78D4850 +:1043A0000078C00700D0012070478A480078C00715 +:1043B00007D07F48006890F85002C00701D0102055 +:1043C00070470020704783480078C00707D07848BE +:1043D000006890F88002C00701D0102070470020CC +:1043E00070477C480078400707D57148006890F80E +:1043F0000E0BC00701D008207047002070476C49A1 +:104400000120096891F8E710090603D57248407841 +:1044100008B103207047022070472DE9F04105469E +:10442000002712F0A5FAFFF7C1FE04466948DFF83D +:1044300080810078C00708D1D8F8000090F8F0011A +:1044400014EAD01F02D0E00600D44027FFF7C9FFCE +:1044500040EA070644EA0607F8070CD0D8F800003F +:1044600090F8F00114EAD01F02D054480078C0B18F +:10447000FFF7C5FF287171074FF0010000D5687183 +:10448000E10600D5A871710600D52872B10600D5E5 +:10449000E871390700D5E8724A4804604A48066066 +:1044A000C9E60920E6E72DE9F041044612F060FA7A +:1044B000FFF77CFE0646FFF772FF0546FFF775FF24 +:1044C0000543FFF780FF054300F0BAF80543FFF707 +:1044D00088FF40EA050700F0C1F840EA070546EA10 +:1044E0000507F8070BD03248006890F8F00116EA8B +:1044F000D01F01D0092001E0FFF781FF207169077B +:104500004FF0010000D56071F90600D5A071A90631 +:1045100000D5E071390700D5E0722A4806602A48C4 +:10452000056088E62DE9F041064612F021FAFFF712 +:104530003DFE0446FFF733FF0546FFF736FF054310 +:10454000FFF741FF054300F07BF8054300F086F8D4 +:104550000543FFF746FF05431D480068810602D565 +:104560000024012503E0400601D50024102544EA7B +:104570000507F8070BD00E48006890F8F00114EA20 +:10458000D01F01D0092001E0FFF739FF3071790712 +:104590004FF0010000D57071F90600D5B071A90681 +:1045A00000D5F071390700D5F0720648046015E0B7 +:1045B00004071000E8041000CC041000E904100007 +:1045C000800A1000F8041000F404100003420000F8 +:1045D0003C071000EC04100040071000264805605E +:1045E00029E638B52549801E0528096813D2DFE879 +:1045F00000F00306090C0F0091F873400CE091F8ED +:10460000724009E091F8714006E091F8744003E0CF +:1046100091F8754000E0012400250DF055FC00B133 +:1046200001256946032012F08EFD009800B91DB1E6 +:10463000142C01D2142401E004B90124204638BD11 +:104640000F480078C00707D00C48006890F8F001C8 +:10465000C00701D004207047002070470848007848 +:10466000C00707D00548006890F81002C00701D0C5 +:104670002020704700207047F40410000407100049 +:10468000EC041000834810B5006890F87000C00773 +:104690000BD014F07FFF012804D07F48017829B1A6 +:1046A000407818B17D490020486010BD012010BD40 +:1046B00010B5FFF7E7FF012814D100F027FA88B9F9 +:1046C0007748764C00886168401C00EB8000B1EBB5 +:1046D000400F07D914F05EFF012801D0012010BD62 +:1046E00000206060002010BD10B500F0A6F900F0B9 +:1046F00007FA6A49002048606A490220087010BD24 +:1047000010B500F09AF900F0FBF964490020486008 +:1047100064490320087010BD10B500F08EF900F058 +:10472000EFF95E49002048605E49042008705E4948 +:10473000012008705D4908705D49087010BD574937 +:104740000020486070475549002048607047534931 +:1047500000204860534901200870704710B500F0F0 +:1047600069F94E49087000F068F900F0C9F94D493F +:104770000520087010BD70B54A4D484C2878801E41 +:10478000042830D2DFE800F017060229BDE87040A7 +:1047900000F059B800F045F801281BD06068401CB3 +:1047A0006060FFF785FF012802D000F042F80FE0BB +:1047B000BDE8704098E700F034F801280AD03D4881 +:1047C0000078012806D06068401C6060FFF75AFF3F +:1047D000012808D0BDE870409EE700F02BF908B131 +:1047E000217809B1207070BD20700620287070BD3E +:1047F00000F0600151EAC0722A4901D0042002E0B1 +:10480000820702D5032008707047420701D50220B5 +:10481000F9E7020701D50520F5E7C006F4D5062023 +:10482000F1E710B500F006F904460CF068FD2043EE +:1048300010BD1848006890F87000800701D501206D +:1048400070470020704710B5FFF7EBFF134C0128AD +:104850000BD018480078012807D06068401C6060C1 +:10486000FFF7E7FF012803D00DE00020606010BDD6 +:1048700008486168006890F878000A30884202D2DF +:10488000BDE810403CE7FFF713FF0128EFD1BDE87A +:10489000104029E704071000D0061000D0041000D3 +:1048A00048071000E80410004407100045071000F6 +:1048B00038071000460710002DE9F0418B4C0746E1 +:1048C0000E462068002590F8982089480FF0CFFD0B +:1048D00002008848294640D002780125521CD2B2F5 +:1048E0000270236893F89930934237D20170804860 +:1048F000760032463946543814F05BFC7C48324628 +:1049000039462A3814F055FC7B4F3878052825D0D5 +:104910002068032690F85012C90703D190F880024E +:10492000C00700D00B26FBF769FD744801683143CE +:104930000160FBF761FD3878052804D1206890F804 +:10494000EB03C00603D5202105200EF039F84FF403 +:104950008071002012F0BDFB00E001702846BDE828 +:10496000F0812DE9F05F060059D0624C0025DFF898 +:104970008891E5702F4699F80000AA46022803D0D6 +:10498000032801D0052849D1B4F904503046A27853 +:10499000294600F065F8DFF85481A070D8F80000CF +:1049A00090F89000800704D530462946FFF784FF31 +:1049B000074600214E4B08464FF0010BD8F8002067 +:1049C0000FE000BF33F91060B2F892C0664506DD13 +:1049D00092F89160491C8E4201DC5D4604E0401C67 +:1049E000C0B2A842EEDB554699F800004E460228B8 +:1049F00001D0032802D114F0CDFD054375B1307804 +:104A0000022804D0032802D0052804D006E06570EF +:104A100084F803B006E0607800B917B16570BDE8AE +:104A2000F09F657000F0D0F8BDE8F05F0221012032 +:104A300012F04FBB2F48407870472E4800210122CA +:104A400001708270294A126892F8312082802A4AC5 +:104A50001278052A02D0062A00D041707047ECE790 +:104A60002DE9FC418046234814460D464078164601 +:104A700040B91F480A467F234146543800940FF03E +:104A800055FD0026194F386890F89010C90700D0DE +:104A9000ECB117486A0041462A3814F08AFB144AE0 +:104AA0002B46543A02F12A0111480FF0FEFC3868F7 +:104AB00090F89010490707D590F89A3023B10C4927 +:104AC0002A4608460FF04BFD3046BDE8FC81B0F9A0 +:104AD0009610CDE90015064AB0F99430543A414693 +:104AE00002F12A000FF068FCD9E70000040710006B +:104AF000080A0120D8041000E80410001407100070 +:104B00000F480021017041607047F9E70C480078B8 +:104B100070470B4800210278012A01D0416070479C +:104B20004268084B521C42601B6893F881309342E4 +:104B3000F5DA01704160002107200DF041BF00004F +:104B4000E00410000407100008B500F03FF8304CF6 +:104B50006B4600227E21012012F004FB00984107E1 +:104B600003D5FFF7D1FA042119E0010703D5FFF7B8 +:104B700071F8082113E0C10603D5FFF71BFA1021D5 +:104B80000DE0810608D52078052801D0062801D13E +:104B9000FFF710FA202102E0410604D54021012050 +:104BA00012F0C3FAD4E78007D2D50221012012F017 +:104BB000BCFAFFF7C3FBCBE700EB80004FF6FF72B8 +:104BC00002EA400014F06CB814F08CB810B5104C28 +:104BD000002001216060A06021700E4960700870A3 +:104BE0000D4908700D490870FFF739FFFFF78DFF79 +:104BF000FFF7A0FBFFF7A7FD0948006890F8400306 +:104C0000C00703D0A06840F00200A06010BD000003 +:104C1000E80410004A0710004B0710004C07100072 +:104C20000407100001F030B94548407800280DD045 +:104C30004448454990F82C0091F82C10C84205D101 +:104C40000123424A40493F4800F0D5BC704770B547 +:104C50000024012390F82C5008E0C61896F9216032 +:104C60008E4202DB964200DC641C5B1C9D42F4D247 +:104C7000012C01DC012070BD002070BD2DE9F04346 +:104C8000994600231F4647F6FF764FF0FF3C01256B +:104C900090F82C400DE000BF00EB050898F921804A +:104CA000884505DB904503DC431993F9213002E088 +:104CB0006D1CAC42F0D2641C0AE0051995F9215034 +:104CC0008D4205DB954203DC204490F9217001E020 +:104CD000641EF2D1BB4209D10AE000BF39F91300CA +:104CE000B04202DA06464FFA83FC5B1CBB42F5DD9C +:104CF0006046BDE8F0832DE9F04117460E460446B4 +:104D0000C27881780F48FFF7A2FF050006D1E2784C +:104D1000A1780F4B0B48FFF7B1FF30706278217814 +:104D20000948FFF794FF060006D162782178094B05 +:104D30000548FFF7A3FF387005EA0600BDE8F081DB +:104D4000A8511000B023100008241000682610009D +:104D5000D00C0120FA0C0120FE480021FE4B01700E +:104D60000122C1601A7041708170018170472DE984 +:104D7000F04F8246DDE90A09012547F6FF779B4699 +:104D8000AC46FE430446DDF824E014E032F814306B +:104D900031F81480A3EB08031BB2BB4200DA1F46B4 +:104DA000B34200DD1E46002B02DD4FF0000C02E096 +:104DB00001DA4FF00005641EE8D225B1BCF1000F06 +:104DC00001D0002309E055EA0C0306D025B9BCF157 +:104DD000000F01D0334600E03B4600273D465FEA26 +:104DE000090402D00124861E01E00024461ECEF1F3 +:104DF000000910E032F814C031F81480ACEB080C54 +:104E0000ACEB030C0FFA8CFCDC4503DACC4501DD7E +:104E100067446D1C641CB442ECD905B9012597FBAD +:104E2000F5F21A4405E000BF31F8103013442AF8B7 +:104E30001030401EF8D2BDE8F08F2DE9F047002574 +:104E4000894629462F462E46A8462B460DE000BF30 +:104E500030F913C039F913400CFB0C660CFB0477D6 +:104E600004FB0488654421445B1C9342F0DB87FB10 +:104E7000020485FB013CC71A86FB020385FB05651E +:104E800064EB0C04B0EB060C63EB050688FB020335 +:104E900081FB0121851A63EB01086421A7FB010353 +:104EA00004FB0131002207FB02113346624614F075 +:104EB0005CF90246A2FB070301FB073102FB041168 +:104EC0002A46434614F051F9002C00DA4042BDE86E +:104ED000F08770B503460020024601EBD17408E06C +:104EE00003EB420633F91250B6F90260AD1B2844B9 +:104EF000521CB2EB640FF3DB621008E003EB4205D7 +:104F000033F9124035F9025C641B2044521C8A427A +:104F1000F4DB70BD2DE9F0418E4C00208F4DA07068 +:104F2000607028684FF0010790F80F0BC00736D06B +:104F30008B4E8C486169327800F045F928683278E8 +:104F40008849A84600F53460FFF777FF05463178B9 +:104F50008448FFF7BEFFD8F8001091F8282BAA422A +:104F600004DAB1F8262B824200DAA770322D14DD64 +:104F70007C4AB2F90000002800DA4042B1F8101B68 +:104F800088420ADD307802EB400030F9020C00283C +:104F900000DA4042884200DD6770BDE8F081724E61 +:104FA0007048216932782A3800F00DF96D49286877 +:104FB00032782A39A84600F53460FFF73EFF0546EF +:104FC000684831782A38FFF784FFD8F8001091F844 +:104FD000282BAA4204DAB1F8262B824200DAA77005 +:104FE000322DDADD5F4A2A3AB2F90000002800DAF1 +:104FF0004042B1F8121BC3E72DE9FE4F574D8946D9 +:10500000DFF850812968934698F8002091F82B1B0F +:105010000C9E0C099A46012A01D101F00F04524F4F +:105020000096014623463A7850480FF065FA234629 +:105030004B4C4E480096227849462A300FF05CFAD5 +:10504000286890F80E1B49071BD5B0F9181B0123DF +:105050003A788DE80E004549B0F9163B5A460846A5 +:10506000FFF785FE286800232278B0F91C1B8DE825 +:105070000E003E49B0F91A3B2A3152460846FFF766 +:1050800076FE3448022110300BF02EFC314802210C +:1050900014300BF029FC3B785A4634494646D8F880 +:1050A00010000FF002FA3149237852462A31706914 +:1050B0000FF0FBF9286890F80E0B000701D5FFF7F9 +:1050C00029FF2448022110300BF071FC21480221F5 +:1050D00014300BF06CFC25493B785A4601F1760000 +:1050E0000FF0E3F9237803B05246BDE8F04F1F49B3 +:1050F0002A3101F176000FF0D8B92DE9F843804646 +:105100001548144C002605780F462670032012F02F +:1051100080F8174B174A394640460095FFF76CFF59 +:10512000032012F091F80D48134D4FF48077016879 +:1051300091F80F0B420602D5A278012A24D02681CD +:1051400080061CD507497639A1F12A0000F053F8F2 +:10515000012813E0FC0410003807100004071000B9 +:1051600086061000480B012085061000320A012037 +:10517000A06F0120766F01201407100015D000F0F9 +:1051800064F82070BDE8F8832289521C12B2228193 +:1051900091F8291B01F00F019142D1DA268128688C +:1051A000432140F48070286004E02868412140F4E5 +:1051B0008070286005200DF003FC3946BDE8F843F7 +:1051C000002011F086BF30B547F6FF73002405E0DC +:1051D00031F91450AB4200DD2B46641C9442F7DBDE +:1051E000002405E031F81450ED1A20F81450641C26 +:1051F0009442F7DB30BD2DE9F041324C0F460025DB +:105200002168B1F93B2B304909780FF030F9064697 +:105210002068B0F93B2B2D48017838460FF027F96C +:10522000014600222A48012E01D1012902D0C26084 +:105230002846B2E6C168491CC160236893F83D3B2B +:105240008B42F5DA0125C260F2E72DE9F0411D4FEE +:105250001F4C00253868B0F9122BA280B0F8101B43 +:10526000E18090F8223B184801781A4800F017F8BE +:1052700006463868B4F9062090F8223B13480178B6 +:1052800014482A3000F00BF8012E06D1012804D171 +:10529000607810B9A07800B9012528467DE670B580 +:1052A00000252C4606E000BF30F91460964200DD70 +:1052B0006D1C641C8C42F7DB9D4201D9012070BD3E +:1052C000002070BD0407100085061000860610003F +:1052D000FC041000A80A012010B55821FD4814F064 +:1052E00009F8FC485821583014F004F8F948002116 +:1052F000B030C0E90011C0E902111030C0E900115E +:10530000C0E902111030C0E90011C0E902110846DD +:10531000F149086010BD2DE9FF5F06468946EF4858 +:10532000EF499846007809681446012850D0B1F931 +:1053300086A291F88852B1F98272114648460FF060 +:1053400060F98346214648460FF079F900903946C6 +:1053500058460DF076FF0FFA80FB394600980DF0A5 +:1053600070FF00B2ABEB00006843642190FBF1F0EA +:10537000384405B2A8F80850701C00210390C8F802 +:105380000010C8F80410B9F90000A84202DD039922 +:105390000120087009EB4400761C30F9022C311909 +:1053A000AA4202DD012201F8012CB9F9023003EB17 +:1053B0000A0212B2AB4218DDB9F90030934203DDA4 +:1053C000B9F9043093420ADC039B01225A700CE0C5 +:1053D000B1F96AA291F86552B1F96672ADE7D8F8F1 +:1053E000006046F00206C8F8006030F9043CA4F101 +:1053F000020B03EB0A0212B2AB4216DD30F9063C97 +:10540000934203DD30F9020C904203DC012001F8E5 +:10541000020C0AE0D8E900645A460120002113F08A +:1054200091FE06430C43C8E90064022458E000BF23 +:1054300039F91400A84252DD09EB440102915044AD +:1054400031F9021C00B2814204DD029AB2F9022055 +:10545000824210DC029A32F9042C824204DD029A64 +:10546000B2F90220824206DC814235DD0299B1F9AF +:105470000410814230DDD8E9006722460120002176 +:1054800013F060FECDE9000106430F43621E0120C8 +:105490000021C8E9006713F055FE02460B4606EAF4 +:1054A000020007EA0301084319D0029839F91410E1 +:1054B00030F9020C814209DA96439F43C8E900673C +:1054C00003990120214401F8010C08E0DDE90010F6 +:1054D0008E438743C8E90067039901200855641C7F +:1054E0005C45A5D3BDE8FF9F2DE9FF4F81B0824603 +:1054F00000211D4683F82C100B2090464B1E794C42 +:1055000008E0002229188A7581F8213005EB400156 +:1055100022880A80401EF4D2704801787048012920 +:10552000006806D0B0F984224FF0000B5946584667 +:1055300016E0B0F96822F7E70AEB00035C7874B173 +:105540001AF800400CB9491CC9B25970029B33F9D2 +:105550001030934203DD01238B4043EA0B0B401CC8 +:105560004045E9D3604800900E984FF000094C4642 +:10557000C0E9009938E000BF0AEB0400427892B31A +:105580000121914011EA0B0F02D1002141702AE064 +:105590001AF8041039B909F1010101F0FF09524963 +:1055A000009105F8194080F801900E9822460021DC +:1055B000D0E90067012013F0C5FD06430E980F43A4 +:1055C000C0E9006705EB0900817D491C817505EB89 +:1055D00049014C700299009A31F91410914202DD90 +:1055E000009180F82140641C4445C5D385F82C9077 +:1055F00005B0BDE8F08F2DE9F84F0C4605461E4674 +:1056000091461721394813F053FE2821384813F0EA +:105610004FFEDFF8E0A0384F09F108089AF80010B3 +:1056200076B10A4605F1300334493048FFF773FE7E +:1056300004F130033A7832492D48FFF76CFE11E04F +:105640004A462A4800F0E9F842463978284800F0EE +:10565000E4F80020C5E90C00C4E90C0029480088E2 +:1056600028872087284E288F2B4626F8110F208F59 +:105670007080CDF800909AF8002020491B48FFF771 +:1056800033FFCDF8008023463A781D491848FFF7CC +:105690002BFF95F82C10307961F30300307194F8EA +:1056A0002C1061F307103071BDE8F88F70B50C4C09 +:1056B000206890F83012090743D514490A780AB9CE +:1056C000497831B105490978012921D0B0F8421251 +:1056D00020E036E0B023100014051000260510006D +:1056E00004071000C89501000080FFFF860D01200F +:1056F0009D0D01208506100086061000D00C0120AB +:10570000FA0C01202C05100090550120A851100022 +:10571000B0F8481201220DB2B0F944124B4800F023 +:105720004AFA20680022B0F946124848103000F0CA +:1057300042FA2946BDE8704044480122103800F082 +:105740003ABA42484FF0FF31C0E90011C0E90211F6 +:105750001038C0E90011C0E902112030C0E9001181 +:10576000C0E9021170BD2DE9FF4F83B015460699BF +:1057700091F8461002290CD001290CD03349103978 +:105780008A464FF0000BA97813F032FF8146A878C3 +:1057900032E02E49F4E72D491031F1E702462C782A +:1057A0000120002113F0CEFCCDE900011DE000BF77 +:1057B00019F804100498814216D1DDE90023DAE9D2 +:1057C000000110401940084323D0DAE9026722465D +:1057D0000120002113F0B6FC06400F403E4318D0D4 +:1057E0000BF101001FFA80FB641C6878A042DFDA2D +:1057F00009F1280908F10100E97880464145CDDA30 +:1058000006995FEA0B00A1F826B000D0012007B08E +:10581000EFE6002009F80400E6E72DE9F04791469D +:10582000451C0C464FF001080CE0D9E90067224600 +:105830000120002113F086FC06400F403E4301D0BA +:1058400005F80480641EF0D2BDE8F08770241000D3 +:105850009D4A10B513680021B3F81422824205DA7C +:1058600093F81022520701D5022108E0B3F8122262 +:10587000824204DA93F81002800700D50121934890 +:10588000934C4278914214D1A17891420DD0914B22 +:105890001B781A43904B1B781A4307D04168491E66 +:1058A0004160002901DC4078A07010BD4170416862 +:1058B000F7E759B1022901D1012A07D093F818223C +:1058C00042604170002AF0DCA17010BD93F81922EB +:1058D000F6E770B5814A824B7D4D16787A4A9C79FD +:1058E00000211268AB78012E02D17E4E36784EB17F +:1058F000B2F81462864217DA92F81062760713D56E +:10590000022125E0B2F81C62864203DA92F81062A6 +:105910007607F5D4B2F81A6208E000BF92F81002D8 +:10592000800705D5012113E0B2F812628642F5DB4B +:1059300073B168480078012803D0674800780128CF +:1059400003D192F81002000701D5012C00D11946AD +:105950005E4834B119B100BF92F819224260A970B3 +:1059600070BD0029F8D1002BF6D04468002CF6DD7C +:1059700092F810120A0755494968A1F1010102D5B0 +:10598000594A127802B141601946E8E74E484F493A +:10599000006890F81002C2064FF0000003D44C4A91 +:1059A0009070487048600870704710B504464648CB +:1059B000006890F81002C006204602D5FFF789FF64 +:1059C00001E0FFF745FF424882784848417B62F397 +:1059D00007114173A0F82F4010BD2DE9FC5F8346ED +:1059E000434800250A46067800782F4641002C4699 +:1059F000012A17D0DFF8D0A0DFF8F880DFF8F890A0 +:105A0000DAF8000090F81022920610D5B0F92012B2 +:105A1000CDE90016B0F91E324246594648460EF00E +:105A2000CBFC09E033484C3813F042FC42E00A4614 +:105A30005946314813F0BDFB2E484C3835E000BFC5 +:105A400038F9142039F91410511A00D54942DAF8FE +:105A5000003009B293F8102252060BD5204A9279F1 +:105A6000012A07D1254A127822B9B3F822228A42A4 +:105A700000DA012730F914208A4202DA93F816324C +:105A800001E093F817325A43C3F5807301FB0321F9 +:105A9000CA1701EB1261091220F8141030F9141022 +:105AA000A94200DD0D46641C24B2B442C8DB28467E +:105AB000FFF77BFF720059460E4813F07AFB03484C +:105AC0000770BDE8FC9F00000407100018051000D7 +:105AD000400710008C061000240510008D061000F1 +:105AE000A85110008E06100092061000905501205B +:105AF00085061000E00B01202C0C01203805100059 +:105B00002DE9F04F8146DDE909B5012047F6FF7721 +:105B10009A468446FE432C4615E000BF32F8143006 +:105B200031F81480A3EB08031BB2BB4200DA1F4616 +:105B3000B34200DD1E46002B02DD4FF0000C02E0F8 +:105B400001DA4FF00000641EE8D220B1BCF1000F72 +:105B500001D0002309E050EA0C0306D020B9BCF1C3 +:105B6000000F01D0334600E03B4600273C46284664 +:105B7000CBF1000C0EE000BF32F8106031F810805D +:105B8000A6EB0806F61A36B2564503DA664501DD7D +:105B90003744641C401EEFD204B9012497FBF4F093 +:105BA000184404E031F81520024429F815206D1E30 +:105BB000F8D2BDE8F08F2DE9F04115460E460446B7 +:105BC00003460A46FE480178FE4800F099FCFE486C +:105BD00004F108031F460178FA4832462A3000F0E3 +:105BE0008FFC002D07D0204613F0E4FC3846BDE8BA +:105BF000F04113F0DFBCBDE8F0812DE9F00FF3496F +:105C00008246DDE909400968089E914691F82B1209 +:105C10004FF0000B01F0030C012801D0002236E008 +:105C200000200BE004FB00F103EB4102DAF8005026 +:105C30001560BAF80410401C918000B26045F1DB99 +:105C4000A6F800B0BDE8F00F704700BF3AF91200A7 +:105C5000B6F900500146002712E000BF04FB0528FA +:105C600033F91880884500DA4146804500DD40461A +:105C7000002D02DD6D1E2DB200E002257F1C3FB21B +:105C80006745EBDB401A29F81200521C12B2A242FF +:105C9000DCDB47F6FF71002007E000BF39F9102078 +:105CA0008A4200DA1146401C00B2A042F6DB002016 +:105CB00007E000BF39F81020521A29F81020401CC4 +:105CC00000B2A042F6DBB6F90000022802DA401C5E +:105CD000308001E0A6F800B0B6F900006200604331 +:105CE0005146BDE8F00F03EB400013F062BA30B547 +:105CF000002B0DD1B54B1C6894F82832B4F829421A +:105D00009D07B34B04FB04F41B6802D59C4208DCDE +:105D100030BD9C42FCDDAF4B9C7814B95B78002B06 +:105D2000F6D000230AE000BF30F9135031F91340D8 +:105D3000A54201DA20F813405B1C1BB29342F3DB4F +:105D400030BD2DE9FE43804617468946032011F0F9 +:105D500060FAA14C9A4D00979A482A7841467638C5 +:105D600023680EF0C9FB984E009796483278494652 +:105D70004C3823680EF0C0FB944C206890F8301229 +:105D8000C9071AD02A78B0F93412CDE900128D492A +:105D9000B0F932327639914A0846FFF7B1FE2068F1 +:105DA0003278B0F93812CDE900128649B0F93632AE +:105DB0004C398B4A0846FFF7A3FE82492B78874A65 +:105DC000763980480EF071FB7E4933784C39844A2D +:105DD00001F176000EF069FB206890F830128A0716 +:105DE00004D4804A12788AB149070FD5754990F8D2 +:105DF00041322A7808460EF0B2FB206871493278A9 +:105E000090F841322A3108460EF0A9FB206890F83C +:105E10002802C10733D0400701D56A4800E0404658 +:105E20002978714ACDE90021704B029703F5B172D0 +:105E30006A49FFF7E2FE3B462A786D496148FFF761 +:105E400056FF206890F82802400702D55D482A30A6 +:105E500000E048463178644A644B921CCDE9002149 +:105E60007E33029703F587725D49FFF7C6FE6049EE +:105E700054483B4632782A312A30FFF738FFBDE8D4 +:105E8000FE43032011F0E0B970B5574C5949083C66 +:105E90000025A571012008704C48257165710068C6 +:105EA000B0F83A02A08100F07EFB2561656170BD0B +:105EB0002DE9F0410E464F494B4C07460D78002026 +:105EC000083C0870607100F06EFB2A463146384687 +:105ED000FFF737FF3F4841783C480029A17915D0AA +:105EE000012919D00068B0F93C12414DA1817635E5 +:105EF00001222846FFF75FFED5E9000108430FD0D5 +:105F0000D5E9020108430BD001200AE0012903D0A2 +:105F10000068B0F93A12E8E70068B0F97812E4E7EF +:105F20000020207167E62DE9F34F834632480027B1 +:105F300040F6FF7401782548A7B02546006801297E +:105F400009D02849097849B12C490978012908D094 +:105F500002290BD00EE0B0F959420BE0B0F95242E1 +:105F600001E0B0F95442B0F9CE5B03E0B0F954421D +:105F7000B0F9D05B124801214FF0000E0078204E9E +:105F8000801E00F0FF0910480278931E03F0FF08FE +:105F90000BEB42039A460CE0704605E033F910C063 +:105FA000B44500DD6646401C4045F7DD03EB420387 +:105FB000491C4945F0DDDFF810805200514621E0D0 +:105FC00085061000D00C0120860610000407100082 +:105FD000BC0610004007100038061000006F0120BA +:105FE0002A6F0120380510002805100090241000A9 +:105FF000F2251000450710003E051000390510007D +:106000000080FFFF684613F0D4F898F80000414282 +:10601000FE4A6B46128802EB410109B242000BEBCB +:10602000410103EB400013F0C4F898F80000694602 +:10603000420008460EF0B1FA301A289AF44900B22C +:10604000022A05D0A1F85000A84204DD022705E08D +:10605000A1F85200F8E7A04200DD0127ED490A88C7 +:10606000521C0A80EC4A12784A808C80CD800881CC +:10607000384629B09DE52DE9F14FE848E84A4FF050 +:1060800000090068FF261278B0F8D2AB85B0494607 +:10609000354632B1E04A1278012A05D0022A08D0EA +:1060A0000BE090F8D46B01E090F8D56B90F8D65BDC +:1060B00003E090F8D56B90F8D75BDA4801230078BD +:1060C000801E00F0FF0E039003200490D648027853 +:1060D000901E00F0FF0B0290059800EB4204019423 +:1060E00029E0DFF830C39FB204980CF1200C009730 +:1060F0001CE000BF04EB400834F9107038F9048C40 +:10610000B7EB080700D57F423FB257450DDDACF82D +:106110000400DDF80080ACF80680DFF8F882491C46 +:1061200008F13008C9B2A8F80070401C5845E1DDFC +:1061300004EB42045B1C7345D3DDB64803233030C7 +:1061400002EB420481800398C0B2009001200390CA +:10615000029800F0FF0B059800EB440C019C32E024 +:106160004FF0000E039820E03CF9107034F91080D5 +:10617000B7EB080700D57F420FFA87F8D04513DD4B +:10618000A44F2037491CA7F8008038817B813CF858 +:106190001080A7F80C8034F81080A7F80E800EF15C +:1061A000010707F0FF0EC9B2401C5845DCDD9F48CF +:1061B0000CEB420C04EB42040778F046774500D81C +:1061C000474607705B1C00988342C9DDA94201D98C +:1061D000022002E0B14201D9012081468D482030E1 +:1061E0004180484606B0E4E4F0B58A488A4B002274 +:1061F000018A491C01828D494C7844821E7886822E +:10620000CD78C5828F780783A64205D18A70CA707F +:10621000C18B491CC183F0BDDFF800C2B442DCF879 +:1062200000C010D907F10107CA70FDB28D709CF84B +:10623000626206F00F06B542EDD91C708A70418B80 +:10624000491C4183F0BDFDD26D1C8A70EDB2CD704A +:106250009CF86262B5EB161FF4D91C70CA70818B72 +:10626000491C8183F0BD2DE9F047DFF8B891054660 +:1062700099F8000002285DD96D48007818B96D487A +:106280000078012856D06C4E012402213068FFF7B7 +:106290004AFE074603212846FFF745FE05463068BB +:1062A000FFF7E9FE0146AF4201D9284600E0384633 +:1062B000814200D90846614A127802B10020574E47 +:1062C0005A4B326893F8008092F8D8CBC44502D874 +:1062D0000020587002E0587000B100244D48418100 +:1062E0008781C58192F85002000722D599F80020D5 +:1062F00053485449022A1CDB534D531E05E000BF8E +:1063000030F91370AF4200DD3D465B1EF8D1801CB2 +:10631000921E0EF042F93168281A3D4A00B2B1F9D6 +:106320005712A2F85400884203DD3CB10220BDE8B8 +:10633000F0870CB10020FAE70120F8E70320F6E728 +:106340002DE9F04107464148164600240078D8B3AD +:106350003848334D007800B33D4834491031006867 +:1063600000F0EFF82D483149006810310A68B0F8A4 +:106370005F329A4217DDB1F9061090F8610281424E +:1063800011DD3548334AB0F90010384600F05CF9A9 +:10639000044644B100F02EF90CE02C78012914D009 +:1063A0000029F6D1002496B12C49002008702878E5 +:1063B00000B10124FFF718FF294E28783178884270 +:1063C0000CD038B1012106E00DE00124E2E700F035 +:1063D00027F9ECE7002106200CF0F2FA287830705B +:1063E0000CB1012007E4002005E470B50446032049 +:1063F00010F00FFF2046FFF736FF0446032010F091 +:1064000023FF0349C87B64F305102BE096061000B8 +:1064100090550120460D0120390510000407100099 +:1064200038051000850610008606100020051000B3 +:106430003D0510003E051000B4061000D006100007 +:10644000006F01202C0C01200080FFFFA8511000DC +:10645000AC06100068261000340610003C05100041 +:106460003A051000C8735748017821B10021017026 +:10647000204600F062F9544D544821462A790068BC +:10648000FFF75EFFA87170BD70B5514A0024234626 +:1064900012782146521E52B24E4D0DE035F912606F +:1064A000864202DD491CC9B204E08C4200D9214673 +:1064B0000C460021521E52B2002AEFDA8C4200D95B +:1064C0002146454C00222478641E65B2414C2A3492 +:1064D0000EE000BF34F91560864202DD521CD2B2D4 +:1064E00004E0934200D91A46134600226D1E6DB295 +:1064F000002DEFDA934200D91A468818C0B270BD59 +:106500002DE9F0471D464FF00008C5E90088914687 +:1065100082460C4611E000BF3AF9141049450CDDE3 +:10652000D5E900674FF0010822464046002112F0ED +:1065300009FE06430F43C5E90067641EECD24046DE +:10654000F5E630B5254A1268B2F85D22524213B220 +:106550000022CA808A800A60214AB2F9002012E033 +:1065600030F91240002C0EDA8C88641C8C8030F9D3 +:1065700012500C682C440C6030F912409C4202DA34 +:10658000CC88641CCC80521EEAD2164A887982F8E4 +:1065900058000868002800DA4042A2F8590008684C +:1065A0004042086030BD10480021C0E90011C0E938 +:1065B000021108460D4981F82C000D4981F82C0084 +:1065C000704700003D05100020051000AC061000CB +:1065D00085061000D00C012086061000040710006C +:1065E000960610009055012068261000B023100078 +:1065F000082410005748002101710278002A0ED1AA +:10660000C278554B521CD2B2C2701B6893F86232EA +:1066100003F00F03934202D201220270C17070474F +:106620004C480021C1700278002A0CD002794A4BF4 +:10663000521CD2B202711B6893F86232B2EB131F84 +:1066400001D90170017170472DE9F74F86B08B4673 +:10665000D2E90001CDE90201D2E90201CDE904014C +:1066600002A812F0A7FF04A812F0A4FF3B480025DF +:106670002F4606782FE0F1B2069812F0B1FF82465D +:106680003748324600210478012012F05BFD029A5F +:1066900000EA0208039801EA0009DDE90401CDE9F6 +:1066A000000116E03AF91410594512DD58EA0900C4 +:1066B0000DD022460120002112F044FDDDE9002327 +:1066C00010401940084302D07F1CBFB201E06D1C8E +:1066D000ADB2641EE6D2761ECDD2224800F8565FD7 +:1066E00047701D48006890F85B12A94207D890F8DF +:1066F0005C02B84203D3012009B0BDE8F08F00204E +:10670000FAE7144810B5817801700021C170017159 +:10671000FFF7BAFBBDE81040FEF7DEBD0D480021D3 +:106720000D4A017041708170126892F850229207F0 +:1067300000D501218171417170470B490A780549E3 +:10674000012A04D08A79012A03D1002801D100202E +:106750008871704738051000040710008506100086 +:1067600086061000905501204C0710002DE9FF5FB0 +:10677000FF4F0546DDF838B03868984690F8A51206 +:10678000B0F9AC42490607D590F83100FF22C100AC +:10679000F848103112F084FDF748417809B9807843 +:1067A00010B13868B0F9AE420026DFF8C893BA4697 +:1067B00021E000BF02990BFB06F001EB40073946D0 +:1067C0005A4608460CF0C2FC22465B461146384643 +:1067D0000CF0DEFCDAF8002092F8A62212B15B463B +:1067E0000CF0F6FC09EBC602C2E9020105EBC60299 +:1067F000761CC2E900014645DCDBDAF8000090F8BF +:10680000A502400619D500204B46DFF870C310E002 +:1068100003EBC00797E80601FE6801EA0801324071 +:10682000D7E90467314005EBC0063A40C6E90012DB +:10683000401C9CF800108842EADB204604B0BDE80A +:10684000F09F08B5009380230DF046FE08BD70B59B +:10685000B1F90050B2F90060049C75435B1EEE175D +:10686000634305EB5665641EED11A4B2058031F952 +:106870001450B2F902609BB27543EE1705EB5665F2 +:10688000ED1120F8145031F91350B2F9046075433A +:10689000EE1705EB5665ED1120F813502344B2F9BD +:1068A000062031F913105143CA1701EB5261C91187 +:1068B00020F8131070BD08B500931346B04AB2F922 +:1068C00000200DF019FE08BD2DE9F05FAA4DAD4A7C +:1068D00000216B789078DFF8B092022B00D230B1B3 +:1068E00089F80210022B00D208B189F8031099F838 +:1068F00006309246034301D089F804109C4CA3490A +:1069000020680978B0F91873B0F94283062901D1DB +:10691000B0F9167399F8031029B19D490978012936 +:1069200001D1B0F9507390F88B1B090604D5994931 +:10693000097809B1B0F98D7B12F016FE50B12068CC +:1069400090F81B1390F84503394440440FB20FFAF6 +:1069500080F808E06878022805D32068B0F81C1396 +:1069600009B1B0F91C7399F8060080B12068642160 +:1069700090F8690300FB07F200FB08F092FBF1F2CC +:1069800090FBF1F03A44404417B20FFA80F8824E7F +:106990008249834D3780A1F80080206890F81A233F +:1069A000BA1A2A8090F84423A8EB02037D4A138088 +:1069B0007D4B93F800C0BCF1000F02D09B78FB1A0E +:1069C0002B8099F800304BB1784B1B7833B1B0F87D +:1069D0006C32338090F86E72DB1B2B809AF8023099 +:1069E00033B1B0F86C32338090F86E02181A2880F8 +:1069F00099F802306E4823B96E4F33883B802B885C +:106A0000038099F80330CB461BB933880B80298863 +:106A10001180B0F90010B2F90020B5F900000CF0B7 +:106A2000FEFB654FB046DFF8989138803088634EA2 +:106A3000308064482988A9F800100078A8B112F0C5 +:106A400093FD10B1206890F83D042168B1F83A2414 +:106A50001044308091F83C14401A01B2A9F800109B +:106A6000B7F900000CF0E9FB3880574E5749B8F8E9 +:106A700000003080564A0880288810809BF8040067 +:106A80005D46F8B12068B0F8B03923B1AB7913B1E5 +:106A9000B0F8B03904E0B0F8AE3913B1B0F8AE399F +:106AA0003380B0F8B23933B1B0F8B2390B8090F816 +:106AB000B409181A1080B2F90010B7F900000CF0F0 +:106AC000BCFB38803948434F007818B12068B0F8D3 +:106AD000C4020EE09AF802000028F7D12068B0F94D +:106AE000C20238802979002904D0B6F900100CF0D0 +:106AF000A4FB3880A3E62DE9FF4F85B007460821A7 +:106B000012A8149D11F0E8F80490002875DD4FF0EC +:106B1000000ADDE912015646D046D346D146CDF8EB +:106B200004A05446CDF800A0CDE9020115E02246AC +:106B30000120002112F006FBDDE90223104019407C +:106B4000084309D037F9140004FB048804FB0099BA +:106B50000AF1010A26448344641CAC42E7DB08FBCB +:106B60000AF006FB160212B109FB0AF034E05EE0FF +:106B700004071000302710004007100085061000A1 +:106B80009606100040051000A8511000E8041000FF +:106B90009106100046071000280610002C06100071 +:106BA0002E06100032061000D00610003805100026 +:106BB000300610002A0610003406100040061000AF +:106BC0004206100047071000480610004A06100051 +:106BD0004C0610003606100006FB1B0308FB0BF0EA +:106BE00009FB1604002020E003FB004191FBF2F1B9 +:106BF000069EB14202DD314604E02CE0F14201D5AF +:106C00000699494237F81060711A09B227F8101036 +:106C1000079EB14208DA0E44002E05DD019E314484 +:106C200001910099491C0091401CA842DCDBFE4800 +:106C3000006890F8A712049881420CDDDDE900108D +:106C400090FBF1F005E000BF37F81510091A27F89E +:106C500015106D1EF8D209B0BDE8F08F2DE9FF5F69 +:106C6000F24C884600260746924635464FF4667138 +:106C70004046266012F01CFB0021404612F0B8FC92 +:106C800081460021384612F0ABFC0022E84BE94F68 +:106C90002AE000214FF0010EDFF88CB319E000BFAD +:106CA00030F91180D04505DD09F801E030F911C057 +:106CB000761C6544DBF800C030F91180BCF855C380 +:106CC000E04505DDD4F800C00CF1010CC4F800C0AB +:106CD000491C93F800C06145E2DB0CF0FF0109F1AB +:106CE000280900EB4100521C39788A42D1DB039815 +:106CF00005603046A2E505E030F912308B4201DD37 +:106D000001207047521EF7D2002070472DE9FE4F38 +:106D1000C54C8146C84E20684FF0000590F8A5325A +:106D2000DB0607D5C54BB0F8D3021B68404383424E +:106D300000DD356013463268C14E3068FFF7BBFD99 +:106D4000032010F066FA2068BA4F90F84003C0079D +:106D500014D0BC48007888B93978BB480DF05CFC89 +:106D60002168BB4AB1F85833B849984204DCB948A5 +:106D700083780BB9407820B3CD701570B648316870 +:106D8000B0F90030B548026848460DF08EFB05F0BA +:106D900039FE032010F058FA2068A54E90F8A4128E +:106DA000090624D5B0F9B0B2307800904A463B7855 +:106DB0001146AB48FFF7DAFC82460025DFF8A082D7 +:106DC00012E00120C870D9E708EBC5023378D2E998 +:106DD00000128DE80E0003FB05F009EB40005A4657 +:106DE0005146FFF788FE6D1C38788542ECDB206841 +:106DF00090F8A402400708D533783A78494603B0A2 +:106E00000846BDE8F04F00F08FBBBDE8FE8F2DE9CE +:106E1000F0410A4680460026924D3146104612F057 +:106E2000E7FB04460021404612F0E8FB024680489A +:106E3000002103787F4890F800C012E0002009E0AC +:106E4000275C2FB132F91070AF4201DDC6B23D466A +:106E5000401C00B29842F3DB491C02EB430209B22A +:106E600028346145EADB202E01D0212E1FD10721D5 +:106E7000404612F0C3FB6C4C30F9401F6425226879 +:106E800092F8B52A514391FBF5F1428811444180B3 +:106E90000821404612F0B2FB226830F9401F92F8F8 +:106EA000B52A514391FBF5F1428811444180BDE878 +:106EB000F0812DE9F04780465B4899461746056802 +:106EC00069480E460024006805F6A73512F088FBD5 +:106ED000B8EB0702A6EB090100D55242002900DAFF +:106EE00049425018C0B2142800D82C5C2046BDE896 +:106EF000F0872DE9F04704464B485C4A006832F9B8 +:106F0000118000F6C330B8F1000F05DD584D35F99A +:106F100014A0BAF1000F03DC807A4043000AE6E7D0 +:106F200032F8112035F8145002EB82024FEA420980 +:106F3000504A05EB85056F00B2F900C0B2F9026056 +:106F400099FBFCF397FBF6F5C3F10A03C5F10A05BB +:106F5000C35C455D03FB05F0000AC828C7D9518111 +:106F600099FBFCF1A2F80C80C1F10A01D18197FBD9 +:106F7000F6F113825482A2F814A0C1F10A01D18261 +:106F800015835083B3E770B520213A4812F090F989 +:106F9000284A0021354C3748137809E0B0F90050F1 +:106FA00034F91120954200DD2A46491C0280C9B2FD +:106FB0009942F3D31E4A00212D4C13780AE000BFFA +:106FC000B0F9022034F91150AA4200DC2A46491CCB +:106FD0004280C9B29942F3D370BD2DE9F05F8A4671 +:106FE0008346FFF7D0FF0026B146DFF848805AE01D +:106FF0001D483146006812F001FB054600240C4F85 +:107000004CE000BF35F91400002845DD53465A46D0 +:1070100031462046FFF74DFF70B335F91410414358 +:10702000081225F8140028E0040710001C061000C0 +:10703000860610008506100038061000BC061000F9 +:10704000B0061000D0061000006F0120A8511000FB +:107050008F0610004007100096061000B4061000BE +:10706000782610000080FFFFA8061000D00C012039 +:10707000FA0C01200A1401201AE031462046FFF7DD +:1070800038FFA8B135F914104143091225F814103E +:10709000FE498C80CE800881641CE4B2387884423A +:1070A000B0D3761CF6B298F800008642A0D321E552 +:1070B00025F81490F0E72DE9F04700252C46DFF87D +:1070C000D093DFF8D083F44EF44F17E02146D9F87F +:1070D000000012F085FA0021424633780AE000BF32 +:1070E00030F911C0AC4503DD30F811501170547007 +:1070F000491CC9B29942F3D3641CE4B23878844283 +:10710000E4D3F4E62DE9F84F0646E548002592461B +:1071100004788B460570FFF7D7FBDE480221001D7F +:1071200009F0E2FB2246DB4C31466068FFF7EEFDDA +:10713000DC4EDD4F316891F8A402020705D4C00689 +:1071400003D491F8A502C00706D06168B7F90030F2 +:10715000D64A0846FFF775FB3068B14690F8A5029D +:1071600080060AD5CC48D14A00780090CB486168A7 +:10717000083A03780846FFF76AFBB7F90000616830 +:107180004200CB48006812F014F8DFF8288398F822 +:10719000000010B998F8010028B1514658466268BD +:1071A000FEF786FE01E0C4480570B94EB7F900004D +:1071B00061684200306811F0FCFFB6480221001DF2 +:1071C00009F0F5FB98F80000DFF8F0B2C24628B3EA +:1071D0009BF80000012821D1D9F8000090F8A50201 +:1071E00040071BD5A078C8B90120A070FFF76CFB41 +:1071F000012108200BF0E4FBB148007802280DD1F2 +:107200002078009094F80180FFF755FF4046B8F1D0 +:10721000FF0F03D001460098FFF7DFFEA648007875 +:1072200030B19AF8010018B19BF80000022828D06C +:10723000A448B7F90020B0F900103068FFF75BFDF3 +:10724000A149A24FF8B10120087001460224A048CC +:1072500009F04AFBA0489E4D9E4BB0F900202968DA +:107260003068FFF7FBFC3860D9F8000090F8B40AEA +:10727000C00703D029683068FFF7C9FD2046BDE884 +:10728000F88F0420FBE7FF202070607093483D607A +:10729000012405608F4805600D70EFE72DE9F84384 +:1072A00005467F484FF00009047880F80090FFF70A +:1072B0000BFB78480221001D09F016FB2246754C95 +:1072C00029466068FFF722FDDFF8D881D8F8000072 +:1072D00090F8EB13490620D58149DFF808C28F6882 +:1072E0000E68BA1BACF86720CD684B68E91AACF899 +:1072F0006910B74203DDD0F81364B24205D89D424D +:107300000BDDB0F81724914207DD62480221001D11 +:1073100009F04DFB0020BDE8F88390F8A412624DFF +:107320000A0705D4C90603D490F8A502C00706D001 +:107330006168B5F900305D4A0846FFF782FAD8F86F +:10734000000090F8A50280060AD55348574A0078F5 +:10735000009052486168083A03780846FFF777FAC8 +:10736000B5F900004A4E42006168306811F021FF13 +:10737000B5F90000616842004D48006811F019FF3E +:1073800044480221001D09F012FB4E48B5F90020C7 +:10739000B0F900103068FFF7AEFC4B4990B1012006 +:1073A0000870014602244A4809F09EFA4A48494BAF +:1073B000B0F90020464801683068FFF74FFC4349A8 +:1073C000086002E081F8009001242046A3E73149DB +:1073D0003D4A002048601070887000F002B800F04C +:1073E0001AB8304810B500683F49404BB0F8182330 +:1073F0000A80B0F82C133E4C1980B0F84233238039 +:107400003C4C22803C4A11803C490B803249B0F808 +:10741000C202088010BD2DE9F00F224B8024234EBC +:10742000196891F8312091F8305002FB05F001E025 +:1074300026F81040401EFBD291F8A5029A46C007DC +:1074400022D01A4F002301F59C611BE003FB05F0DD +:1074500007EB400C00204FF0640910E00E5C4FEA8F +:10746000C618B8FBF9F83CF9106006FB08F64FEABD +:10747000E67806EB5866F6112CF81060401CA8421E +:10748000ECD35B1C9342E1D33AE000000A140120E4 +:10749000A8061000400510008606100085061000A2 +:1074A000440710000407100096061000CE0D0120BE +:1074B000AC061000A851100024051000260510008D +:1074C00039051000340610008C0610001806100054 +:1074D000E005100020061000360610001C06100003 +:1074E0002C14012090550120280610002A061000B7 +:1074F0002C0610002E061000300610003206100078 +:10750000DAF8000090F8A50280060AD55149032058 +:1075100021F81040401EFBD2BDE8F00F4D4800F0AE +:107520005EB8BDE8F00F70472DE9FF4F83B01E46EF +:107530000F461C464EE000BF012047F6FF79009041 +:107540006FEA09080190059D24E04348224600EBBC +:10755000C5000021D0E900A39B46012011F0F2FDF7 +:1075600000EA0A0001EA0B01084313D005FB0640BC +:1075700037F91000814500DD8146804500DA8046FC +:10758000002803DA4FF00000019003E002DD4FF025 +:10759000000000906D1ED8D2DDE9001008430AD02B +:1075A000019810B130B119B104E019B1404602E0C0 +:1075B000484600E0002041000CD0059908E000BFDB +:1075C00001FB0642039D37F812301B1A25F81230D2 +:1075D000491EF5D2641EAFD207B0BDE8F08F1F4B35 +:1075E00010B5196891F8D512CA016421B2FBF1F403 +:1075F000B0F900206243D41702EB5462D21102802A +:107600001A6892F8D622D201B2FBF1F4B0F9022046 +:107610006243D41702EB5462D21142801B6893F884 +:10762000D722D201B2FBF1F4B0F904206243D4179F +:1076300002EB5462D211828093F8D822D201B2FBBD +:10764000F1F2B0F906105143CA1701EB5261C911AA +:10765000C18010BDC60D012078261000040710005F +:107660008C48002101704180704730B58A4902463C +:1076700001200C6894F81F3A4BB1864DB2F84010C7 +:107680006D68491B00D549428B4200DA002094F80E +:10769000201A002912D07F4CB2F92A500834B2F9CE +:1076A0002820B4F90230B4F900405B1BA21A5B43F6 +:1076B00002FB023249438A4200DD002030BD2DE941 +:1076C000F047754FDFF8CC8106004FF005044FF00E +:1076D000060510D096F8240100F048FA04463868F0 +:1076E00090F81E0A18B1B6F8401081422DD8B06A41 +:1076F00000F0A5F848B398F8000001214FF0000908 +:1077000007280ED2DFE800F00404243C6E040400D5 +:10771000052C04D0042C06D0012C07D015E088F8E5 +:107720000090BDE8F08788F80010FAE7FFF798FFAF +:10773000022088F80000A8F80290B6F84000C8F8C7 +:107740000400B06AC8F80800EBE788F80050E8E7E2 +:10775000B8F80200401C80B2A8F80200032C03D045 +:10776000396891F8191A48E0032088F80000A8F851 +:107770000290D6E7052CD4D03046FFF776FF2EE0F6 +:10778000B8F80220521C92B2A8F80220012C1ED098 +:10779000386890F81A3A40469342C2D8057098F873 +:1077A0000100012801D00328BBD13C48394A41706F +:1077B0001921083281705188C170090A017111883C +:1077C0004171090A8171BDE8F0470BF0FFB83046FE +:1077D000FFF74BFF042288F80020A8F80290002849 +:1077E000B3D09EE7B8F80200401C80B2A8F80200AF +:1077F000032C05D0396891F81B1A8142BAD8A4E746 +:10780000052088F800008CE738B500210091694612 +:1078100000F088F91F4C012802D90620207005E0ED +:107820000098FFF74CFF2078052801D0002038BDD4 +:107830001A480121417005218170012038BDF0B541 +:10784000154906460120096891F81C2A950091F80F +:107850001D2A2B46940091F83620D7074A8E898E30 +:10786000A2EB0502A1EB040112B209B20ED023462D +:107870000F462C463114994206DBB94204DC31B282 +:10788000A14201DB914200DD0020F0BD17460A460F +:10789000F0E700004805100004071000E82710007A +:1078A00000F095BABB4890F82C00062801D00528B6 +:1078B00007D1B948B949006890F8BA0200F00F0042 +:1078C0000860B7490020487000F0B8BA70B5B549F3 +:1078D00000220978062903D011B1052900D0012220 +:1078E000B1490B78AE49012B04D0022B02D0032BF7 +:1078F00000D04AB1A848006890F8790048700A287A +:1079000001D20A20487070BD4A7822B1521E12F08E +:10791000FF024A70F7D105465FF00004C4EB041083 +:1079200000EB441005EBC0063146284604F0CEFAC1 +:107930003146284604F003FB641CE4B20F2CEDD35F +:107940009A4800780528DED0BDE87040102101205B +:107950000FF0BFBB2DE9F0410024054600F580562D +:107960005FF00107D6F8080607FA04F108420AD0CA +:10797000C4EB041000EB441005EBC00000F128013B +:107980000C300BF026FD641CE4B20F2CEAD3BDE8EA +:10799000F0812DE9F0470027814605463C4600F579 +:1079A00080580126D8F8080606FA04F108420CD0DF +:1079B000C4EB041000EB441005EBC00191F8240166 +:1079C000032802D1284604F09FFA641CE4B20F2C6D +:1079D000E8D34846FFF7BEFF754C0020704D20608D +:1079E0006060A060E060A868C00104D5484600F06F +:1079F000D3FD012806D0287A800603D54846FFF734 +:107A000003FF50B9A868C00115D5484600F016FB21 +:107A1000A1781A2907D0182768B165480AF0D6FF5F +:107A2000182F02D005E01A27F6E7614808300AF05F +:107A3000CBFFFFF715FEB0464D46002409F58056F2 +:107A400008FA04F0D6F80816014211D0C4EB04106D +:107A500000EB441005EBC00797F82401082807D174 +:107A60003946284604F06BFA3946284604F02EFAC7 +:107A7000641CE4B20F2CE3D34846BDE8F04725E789 +:107A80002DE9F84F80464448006890F83C0AC0074A +:107A900044D04046FFF75EFF414F4FF00006B86804 +:107AA000C0013DD5404600F010FCDFF8049183464C +:107AB00009F1080000244FF0010A08F580550090F4 +:107AC00028E0D5F808060AFA04F15646084220D004 +:107AD000C4EB041000EB441108EBC10090F87001F6 +:107AE000012803D130488079A04201D0387880B98C +:107AF000BBF1000F0BD02E480AF068FF99F8020086 +:107B00001A2806D03E7000980AF05EFF01E00020BF +:107B10003870641C95F91006A042D2DABDE8F88FDF +:107B20003E70FBE730B5054600200346C3EB031269 +:107B300002EB431205EBC20494F82421012A0DD074 +:107B4000022A0BD0032A09D0042A07D0052A05D01F +:107B5000062A03D0072A01D0082A02D1401CC0B24D +:107B60000C605B1CDBB20F2BE0D330BD09280ED2BA +:107B7000DFE800F00D0505070909090B0B000420DB +:107B8000704701207047022070470320704705208E +:107B900070470000687610000407100038061000D7 +:107BA000580510004805100050281000E804100087 +:107BB000E82710002DE9FC4FFE4AB0F90270B0F939 +:107BC0000660D2F800C0B0F90050B0F904409CF84B +:107BD0003620BCF8323093465FEAC278BCF83420D5 +:107BE0004FEA4B7809D0B8F1000F21DA5D1B1C1B5E +:107BF00065F31F4964F31F411EE0B8F1000F06DA78 +:107C0000DF1B9E1B67F31F4966F31F4103E066F30A +:107C10001F4967F31F415FEA8B7604D5551B65F357 +:107C20000F09141B0FE064F30F0965F30F0111E056 +:107C300064F31F4965F31F415FEA8B7406D5D41BBB +:107C400064F30F09941B64F30F0103E066F30F095B +:107C500067F30F019CF83040551C9CF831C0A046DA +:107C6000B3FBF4F4B5FBFCF524B22DB2002B76D0B7 +:107C7000002A74D0002C72D0002D70D00E144FF05A +:107C8000000B13D096FBF4F767F3070A96FBF4F7A3 +:107C900004FB17661FFA86F64FEA2947BB4209DC48 +:107CA000A8F1010363F30F2AA3B20CE06BF3070AF8 +:107CB0000026F1E797FBF4F363F30F2A97FBF4F345 +:107CC00004FB13739BB209B291B191FBF5F767F313 +:107CD000174A91FBF5F705FB171189B20FFA89F7DF +:107CE000BA4209DCACF1010262F31F6AAAB20CE0ED +:107CF0006BF3174A0021F1E797FBF5F262F31F6A75 +:107D000097FBF5F205FB127292B201EB810106EBD3 +:107D100086064900760003EB830391FBF5F15B00D7 +:107D2000C1F10A011FFA81F902EB820196FBF4F618 +:107D300093FBF4F3490091FBF5F1C6F10A061FFA33 +:107D400086FE9BB20AF0FF028FB200259346CAF36B +:107D500007444FEA1A66CAF3072C009325E034E083 +:107D6000934502D10FFA8EF807E0944503D10099AC +:107D70000FFA81F801E04FF00A083BB221460FFAF2 +:107D800089FA01930DE08C4201D1534604E08E4202 +:107D900001D1019B00E00A2308FB0353491C1DB2DB +:107DA00009B28E42EFDA521C12B29445D8DA8581BC +:107DB00080F808B080F809C0A0F810E0009941826E +:107DC0008472C672A0F81490C782BDE8FC8F7A480E +:107DD00010B5007828B9794800218163C163A0F803 +:107DE0004010744C7548216891F83D2AC28191F881 +:107DF0003E2A8276B1F83F2A4280B1F8432A0280B7 +:107E0000B1F8412AC280B1F8452A828091F8472A08 +:107E1000027691F8481A4176FFF7CCFE67491C229A +:107E200001F11C0011F0C5F9216864481C3091F87B +:107E3000492A027691F84A1A417610BD5E480078C8 +:107E4000002811D15D495D4A8863C863A1F84000EC +:107E5000383108705748006890F8471A117602F1D7 +:107E60001C0190F8490A087670472DE9F041044654 +:107E700090F8337190F8246190F825510B2084F824 +:107E80003301082084F82401052084F825012046C8 +:107E9000A16A0AF0A7FD84F83371474984F8246188 +:107EA00084F8255100200870BDE8F0812DE9FE4FCF +:107EB000064643480C46002180F82F1004F11000BC +:107EC0000290A08904F1080808B947F6FF704FF046 +:107ED000000B0190DA46D94696F8667031E000BF93 +:107EE00098F80200B8422BD898F80300B84227D37C +:107EF000F9B2344811F07CFB009096F864501BE016 +:107F000098F80000A84216D898F80100A84212D3A9 +:107F10000098405D78B1F9B2E8B24246029B00F0A9 +:107F20005BFB58441FFA80FB0098405D18B109F1D3 +:107F300001001FFA80F96D1C96F86500A842DFD297 +:107F40007F1C96F86700B842CAD264200BFB00F190 +:107F50000198B1FBF0F082B2B6F8440028B1642376 +:107F60004343B1FBF3F11FFA81FA96F8701101292E +:107F700003D11349012381F82F3011490872000AF7 +:107F8000487281F80A904FEA1920C8720E48019988 +:107F900020F85D1FA0F802B0B6F84410C180A0F828 +:107FA0000890027180F805A0207E904212D8617E70 +:107FB00051450BE004071000C406100018281000FB +:107FC000E8271000D41701209055012002D8012085 +:107FD000BDE8FE8F0020FBE72DE9F04190F8242159 +:107FE0000024032A01D0042A26D1FF4AB1F9023025 +:107FF000126892F84C5A5B1BB0F92A50AB421BDC5A +:10800000B1F9003092F84E6A9E1BB0F928309E42BA +:1080100012DCB1F9066092F84D7A3E44AE420BDBB9 +:10802000B1F9045092F84F2A2A449A4204DBFFF730 +:108030003DFF012800D10224204635E72DE9F05FFD +:10804000DFF8A8938046002799F800300126A9F1AF +:108050003800DBB1E5494D46DFF894A38979DFF8B4 +:108060009493C1EB011202EB4111024608EBC104EB +:10807000927E4FF0040B04F12801012B3CD0022B1F +:108080007ED0032B7DD0042B7CD049E0002408F562 +:10809000805583461BE000BFD5F8080606FA04F1B8 +:1080A000084212D0C4EB041000EB4411CE4808EB98 +:1080B000C10A006890F8471A8BF81810CB4950464F +:1080C0003839FFF789FF022806D0641C64B295F99D +:1080D0001006A042E0DA25E0C44A89F80060383A88 +:1080E000DAF82810C2F83A1089F80640B9F80810F2 +:1080F000491CA9F8081015E094F82431042B01D08C +:10810000062B0DD180461346A81C0BF0D7F801288A +:1081100006D1B64920463839FFF7C8FE012804D0F9 +:1081200085F800B03846BDE8F09F2889B8F80E20E1 +:10813000904233D30220287014F8602F8AF8002070 +:1081400062788AF80120A2788AF80220AA48E278A8 +:108150008AF80320067089F80160182289F8022045 +:1081600014F8362C89F8032034F8362C120A89F8D2 +:10817000042014F8382C89F8052034F8382C02E053 +:108180000FE05EE09AE09848120A89F8062000683D +:10819000012790F8500A88F81800C3E7401C28818E +:1081A000C0E794F82401042801D0062818D113460A +:1081B000A81C0BF083F8012806D18C4920463839D9 +:1081C000FFF774FE012813D094F82461082084F886 +:1081D00024012046FFF749FE0320287084F824611B +:1081E00094F8240108289DD12046FFF73EFE69E05F +:1081F00094F860108AF8001094F861108AF8011061 +:1082000094F862108AF802107B4894F863108AF898 +:108210000310067089F80160182189F8021094F89B +:108220002A1089F80310618D090A89F8041094F85E +:10823000281089F80510218D090A89F806100127F0 +:10824000CEE794F82401042801D0062836D113463D +:10825000A81C0BF033F8012830D164492046383986 +:10826000FFF724FE012829D194F860108AF8001045 +:1082700094F861108AF8011094F862108AF80210DC +:108280005D4894F863108AF80310067089F801605D +:10829000182189F8021094F82A1089F80310618DCA +:1082A0000127090A89F8041094F8281089F80510A4 +:1082B000218D090A89F806100220287094F82401FB +:1082C000082890D1FFF7BAFD2CE72DE9F05F0546AD +:1082D000494800260178DFF81491DFF80CB1A9F1C4 +:1082E0001C0939B1DBF8001091F8511A89F81810FF +:1082F00000210170DFF8F4A005F5805450469AF88B +:1083000000804FF0010CB8F1000F1FD086463748AF +:108310000127364A8079DFF8DCA08740C0EB0011E6 +:108320001C3A01EB401005EBC000927E00F12801E1 +:10833000B8F1010F3ED0F146B8F1020F7DD0B8F18F +:10834000030F7BD0B8F1040F79D006E10027CB46AC +:10835000E0461AE0D4F8081608FA07F0014212D0F5 +:10836000C7EB071000EB471005EBC0091E4800687B +:1083700090F8491A8BF818101C4948463839FFF70D +:108380002BFE022806D07F1C7FB294F91006B8425B +:10839000E0DAE5E0154A8AF80080383AD9F8281082 +:1083A000C2F83A108AF80670BAF80810491CAAF800 +:1083B0000810D5E0D4F808367546E0463B427DD03B +:1083C000044690F82401042801D0062819D1134648 +:1083D000A81C0AF073FF012811D1044920461C395A +:1083E000FFF764FD012809E0040710005028100081 +:1083F000C5061000E8271000C406100002D00420B3 +:108400002870ADE02889B9F80E10884221D30220E7 +:1084100028708AF8018018218AF8021014F82A1F9F +:108420008AF8031034F80219090A8AF8041021782E +:108430008AF805102188090A02E00DE053E085E082 +:108440008AF80610DBF8000090F8510A89F8180045 +:108450007AE0401C288183E0D4F80836E0463B42AD +:1084600001D128463CE0044690F82401042801D0BC +:10847000062830D1134609F102000AF01FFF012837 +:1084800005D171492046FFF711FD012804D099F864 +:108490000000022819D01EE08AF8018018218AF80D +:1084A000021094F82A108AF80310618D090A8AF8DC +:1084B000041094F828108AF8051000E04DE0218D92 +:1084C000090A8AF80610012605E02046FFF7CDFCD0 +:1084D000032089F8000094F82401082840D12046A0 +:1084E000FFF7C3FC36E0D4F8083665463B4231D08E +:1084F000044690F82401042801D0062830D1134600 +:1085000009F102000AF0DAFE012829D14E4920467D +:10851000FFF7CCFC012823D18AF8015018218AF8F2 +:10852000021014F82A1F8AF8031034F80219090AF5 +:108530008AF8041021788AF805102188090A8AF837 +:108540000610022089F80000012609E0D4F8080688 +:10855000384205D1FFF772FC02E004208EF80000DB +:108560003046E0E53849B0F92A201C39B1F902302B +:108570009A420FDBB0F92800B1F90030984209DBCC +:10858000B1F906309A4205DCB1F90410884201DCE9 +:10859000012070470020704710B52B4990F8243116 +:1085A00000221C395B1E052B14D8B0F92A30B1F912 +:1085B0000240A3420EDBB0F92800B1F90040A0420E +:1085C00008DBB1F90640A34204DCB1F9041088428B +:1085D00000DC0122104610BD30B51478844204D26C +:1085E0005578854201D90A2011E0844204D155789A +:1085F000854201D0187809E0844204D0547884423E +:1086000001D1987802E018789C786043C0B29478E1 +:108610008C4204D2D5788D4201D90A2111E08C42D6 +:1086200004D1D5788D4201D0197909E08C4204D06B +:10863000D2788A4201D1997902E019799A79514325 +:10864000C9B2484330BD000034281000FE48002164 +:1086500001808170FD480268FB480A3892F8A43B0B +:10866000437092F8922B82700170017170472DE96E +:10867000F041F64900F580534FF001050E684FF0C8 +:108680000E0196F893CA5FEA8C721AD5D3F80846A1 +:108690000A4600BF05FA02F73C4210D0C2EB0217AF +:1086A00007EB421700EBC70797F825717F0706D540 +:1086B000E54A96F8944A521F1470557001E0521E14 +:1086C000E8D25FEA4C7225D5E14AD279002A21D05E +:1086D000DD4C00220A3C2281D3F8083605FA01F766 +:1086E0003B420FD0C1EB011707EB411700EBC70767 +:1086F00097F825C15FEA4C7C04D0B7F842709742E6 +:1087000000D93A46491EE9D22281B6F9B90AFDF7E5 +:10871000BBFEE070BDE8F081CC49096891F8931A7E +:1087200089070AD5C849491F10B10020487003E0E5 +:108730000878002801D0401E087070472DE9F041EC +:108740000646C24800252C46006890F8931A4A074E +:1087500026D5BF4AD2791AB3BB4A90F8B73A0A3A3B +:1087600090F8BB1A1779012F08D190F8B8CA90F881 +:10877000BC0AA3EB0C03081ADBB2C1B21089984201 +:1087800002D8D078884203D9042086F82501012434 +:10879000214614718F4214D009200AF011F910E01B +:1087A000880707D5A848401F4178012908D00078DC +:1087B00030B906E0C80704D096F82501042800D196 +:1087C00001252543A6D0A349AA20087096F82401C4 +:1087D000032805D0042801D006289BD1082000E0FA +:1087E000022086F8240195E72DE9F04F974981464C +:1087F00000200C6809F58053934AB4F89DAB0146FC +:108800000A3A93F9106641E00127D3F808568F40E1 +:108810003D423AD0C1EB011505EB4117DFF838C2F4 +:1088200009EBC70797F861509CF800C0AB46ACF164 +:10883000020C654507DBB4F83280B7F922C0A8EB1B +:108840000A05AC452CDA97F83E506D071DD497F811 +:1088500060C094F8958BABEB0C0597F863C097F864 +:1088600062706D1CACEB0707EDB27F1C05EB850C4D +:10887000FFB24FEA4C0CBCFBF7FCA84505D2BD4249 +:1088800003D994F8965B65450AD3491C8E42BBDA3E +:1088900094F8921B917011F0FF0F05D0BDE8F08F96 +:1088A000917809B1491EF5E70120F7E72DE9F04776 +:1088B00066486A490025046809782A46B4F9A20B7B +:1088C000174684460B46664E07E000BF36F9138014 +:1088D000E04502DD521C474412B25B1EF6D24FF057 +:1088E000640A002A09DD97FBF2F294F8A53B12B264 +:1088F000534393FBFAF212B207E0624605E000BF71 +:1089000036F91130934200DD6D1C491EF8D294F8FF +:108910009F2B002184460E461346DFF8489194F8B9 +:10892000A07B07E039F91280E04502DD491C46448E +:1089300009B2521C9742F5DC002908DD96FBF1F0E4 +:1089400094F8A51B00B2414391FBFAF000B24946EE +:1089500006E000BF31F91320824200DD6D1C5B1C74 +:108960009F42F7DA384894F8A11B0A38A94203DA83 +:108970003D490978012902D094F8A41B02E041780E +:1089800039B1491E417011F0FF0F02D00020BDE83F +:10899000F0870120FBE7F0B52C4A00F580534FF03B +:1089A000010C1468002293F91066B4F8935B18E088 +:1089B000D3F808760CFA02FE17EA0E0F10D0C2EBBD +:1089C000021707EB421700EBC70749B1B4F832E0D2 +:1089D000B7F90270AEEB050E774501DA491EC9B250 +:1089E000521C9642E4DA94F8910B884201D201209D +:1089F000F0BD0020F0BD2DE9F041144D0746286878 +:108A000090F88B0B01064CD518490978002948D0FD +:108A10000D4C00074FF0010603D5FFF747FF012873 +:108A200010D041F20860042138440FF055F9C1B26A +:108A3000286890F88B0BC0071FD0F1B13846FFF7BC +:108A4000AAFFD0B1286813E07A05100004071000CF +:108A5000A85110009206100086061000850610002E +:108A6000A80A0120D20A0120FC04100046071000C9 +:108A700090F88C0B2070A67009E0286890F88B0B9A +:108A8000800704D53846FFF7AFFE0028DAD16078BA +:108A9000002806D1A078012803D1AA2009F08CFF74 +:108AA000667037E62DE9F0474F4E044600253068E2 +:108AB00090F88B1B09063AD54C49097881B34C498B +:108AC0008978012933D1B0F8987B41F208600421FC +:108AD00020440FF001F904F58051C2B200204FF09C +:108AE0000109366891F910361FE0D2B1D1F8088635 +:108AF00009FA00FC18EA0C0F16D0C0EB001505EBC4 +:108B0000401504EBC505B6F83280B5F902C0A8EBF4 +:108B10000708C44507DB95F83E506D0703D40025D0 +:108B200005E0012503E00125401C8342DDDA2846EB +:108B30002DE770B52C4E316891F88B1B090625D5B1 +:108B40002A490978002921D0294C002510B1A570A7 +:108B5000257006E0207820B1401E10F0FF00207044 +:108B600000D1A5706078012810D1A07800280DD11F +:108B7000BB2009F021FF657031681D480A3891F863 +:108B8000A42B427091F8921B8170057070BD16493C +:108B9000096891F88B1B09061FD51449097800292B +:108BA0001BD013498A78012A02D00978002914D0F1 +:108BB0000F490A39097800290FD00E4ABB211170DC +:108BC00090F82411032905D0042901D0062904D1E5 +:108BD000082100E0022180F8241170470449012097 +:108BE0000A3908707047000004071000460710009B +:108BF0007A0510009206100090F8611090F860203D +:108C00008A1AC18F521C022A0ED990F8632090F85C +:108C100062309A4208D148F20402114204D141F074 +:108C20000101C1870120704721F00101C1870020A7 +:108C3000704770B50446002084F82801F848F94DC3 +:108C40000E460178286811B9F749097831B194F9CD +:108C5000321190F86302B1421ED028E094F8251139 +:108C600001290BD010F080FC002894F9320135D096 +:108C7000B042286890F89B0319D10DE0EB490978C0 +:108C800069B110F071FC002894F932010AD0B042A9 +:108C9000286890F84D030AD100F00F0008E090F822 +:108CA0004B03F9E7B042286890F84C03F4D0000970 +:108CB00084F828012046FFF79FFF01280DD1DC48EA +:108CC0000078012809D9296894F8280191F89C13A3 +:108CD00001F00F01084484F8280170BDB04203D1AF +:108CE000286890F89A03D7E794F83C00C0062868F3 +:108CF00002D590F89C03DAE790F89A03D7E7CB49BE +:108D000010B50C78C74990F82821096891F89A3372 +:108D100003F00F0364B191F84C1300BF01F00F0191 +:108D2000C91A511A002900DC002180F8281110BD51 +:108D300091F84B13F2E72DE9FC47BA4D0446286839 +:108D400090F87F03C00749D02146201D0AF005FB9B +:108D50008046214604F120000AF0FFFA814610F017 +:108D600003FC0028286805D0B0F89363B0F88F732F +:108D7000764304E0B0F89163B0F88D7376432968C8 +:108D8000E06A7F4391F8DA13884216D3B04514DCC9 +:108D9000B4F8CC00ADF80200B4F8C800ADF800009B +:108DA000B4F8D400ADF80600B4F8D000ADF8040073 +:108DB00001A968460AF0D1FA80462A68E06A92F86A +:108DC000DA1388420CD2B9450ADD92F8DB0340433E +:108DD000814509DC204600F0FFF928B9BDE8FC8791 +:108DE0008842FBD3B045F9DDE08F40F00200E08718 +:108DF000F4E79049002008708D4908708B4908708D +:108E00008D4908808D49087070472DE9F04F8BB06F +:108E1000002500F5805604468DF810508DF814504A +:108E2000B6F80806834F0004000C10D02046FFF768 +:108E30001EFC2046FFF7DFFD4FF0FF39387849462A +:108E40004FF00048BB464FF0010A60BB12E0784883 +:108E50003D7005702046FFF7CEFD0020FFF769FE4C +:108E60000120FFF759FC74480580744805700BB069 +:108E7000BDE8F08F04F58052002092F9107621E0D1 +:108E8000D2F808C60AFA00F31CEA030F18D0C0EBA8 +:108E9000001303EB401304EBC30393F824C1BCF1AC +:108EA000010F01D049460FE0B3F840C0BCF1000FFC +:108EB00006D01B6B93FBFCF3984501DA98460146FC +:108EC000401C40B28742DBDA0091A8468BF8005084 +:108ED0000027DFF85091E2E0D6F808160AFA07F00A +:108EE00001426DD0C7EB071000EB471004EBC00543 +:108EF00095F82401012806D005280CD0092820D097 +:108F00000D282DD010E028460099FFF792FE022090 +:108F100085F8240133E0284600F0E0F8062085F8C3 +:108F200024012846FFF707FF95F82401022826D0E0 +:108F3000062846D007284FD00A280DD00E281AD070 +:108F400058E0D9F8000090F89E0300F00F0085F873 +:108F500028010A2085F8240195F8280178B349E012 +:108F6000D9F8000090F8A10300F00F0085F829015E +:108F70000E2085F8240195F82901F0B13AE095F822 +:108F80003E00C00713D02846FFF736FE78B9D9F85F +:108F9000001095F8280191F89C1301F00F01884208 +:108FA00003D9401A85F8280101E085F82881E88F67 +:108FB00040041FD495F82801DFE7032018E016E0ED +:108FC00065E095F82901A8B995F83E00800701D51C +:108FD00007200DE008200BE0D9F8000090F87E0390 +:108FE0008006F7D595F8A000012803D0F2E70B2002 +:108FF00085F824012846FFF7A1FB2846FFF7C7FDA7 +:1090000095F8240102281BD0062824D00A2829D04C +:109010000E2820D0032829D0042827D03DE00000C6 +:1090200038051000040710004205100091061000DA +:10903000B9061000920610007805100073051000A4 +:10904000E88F400429D400BF95F82801F8B1401EEC +:1090500085F8280121E095F82901C0B1401E85F866 +:1090600029011AE02846FFF766FEEDE79BF80000AD +:10907000401C8BF8000095F82501012802D0032838 +:1090800006D00AE09DF81400401C8DF8140004E09E +:109090009DF81000401C8DF810007F1C7FB296F9DF +:1090A0001006B842BFF618AF05AA04A9204600F082 +:1090B00059F80020FFF730FB62499DF81000087056 +:1090C00061489DF8141001702046FFF7EBFC002862 +:1090D0003FF4CDAE0020FFF72CFDC8E670B50026AA +:1090E000044680F829615948594D0178286811B122 +:1090F00090F8640216E0574909780029F8D110F079 +:1091000033FA60B12868012690F89F035FEA1010D7 +:1091100084F8290194F82501012806D00EE028687A +:1091200090F89F0300F00F00F2E7296894F82901F6 +:1091300091F84B1300EB111084F829011EB994F833 +:109140003E0080070DD42868E16A90F8A00300F083 +:109150000F02914205D994F8291101EB101084F8FF +:10916000290170BDF0B50C7813783B4F012534B15F +:109170007BB3002300F580544FF0020C22E0002B5B +:1091800029D03D7022E000BFD4F8086605FA03FE3E +:1091900016EA0E0F14D0C3EB031606EB431600EBD2 +:1091A000C60696F824E1BEF1030F09D196F825E131 +:1091B000BEF1010F04D186F824C11678761E167010 +:1091C0005B1C5BB294F910669E42DDDA08780028D9 +:1091D00001D000203870F0BD30B5C18F01230905E2 +:1091E00001D5012030BD1A4CB0F95A20B0F9581001 +:1091F000246802FB01F5002D0CDA002A00DA524245 +:1092000094F8DC53AA4205DD002900DA4942A9425C +:1092100000DD0023B0F95E10B0F95C0001FB00F244 +:10922000002A0CDA002900DA494294F8DC23914242 +:1092300005DD002800DA4042904200DD0023184698 +:1092400030BD000093061000940610003805100091 +:109250000407100042051000910610002DE9F843A4 +:109260000746FF48894616460178FE480078FE4CBE +:1092700001B990B1206890F8C013B0F8CB2301F089 +:109280000F030D09B0F8C9134943524348460095EE +:109290000AF071F83560BDE8F88310F065F958B14F +:1092A000206890F8B613B0F8B92301F00F030D0948 +:1092B000B0F8B7134943E8E797F82501022818D01A +:1092C000012822D0246894F8E10394F8E0C300F068 +:1092D0000F030509E548017831B194F8E72394F8C4 +:1092E000E6C302F00F03150997F82321012A18D0CD +:1092F0002EE0206890F8BC13B0F8C32301F00F03F0 +:109300000D09B0F8C1134943BFE7206890F8BD13B9 +:10931000B0F8C72301F00F030D09B0F8C513494396 +:10932000B3E794F8998AFA6A424511D294F89A1AE6 +:1093300094F8BB03B2FBF1F194F8982A00F00F0304 +:1093400002F00F02551AB5EB101F1CDA05091AE0DE +:10935000B7F84020624505D9B4F8E213B4F8E42325 +:10936000494392E794F8BB2302F00F03150909B1B2 +:109370000379457997F83C00C00604D594F8DD03DD +:1093800000F00F03E2E7B4F8C113B4F8C323494374 +:109390007BE72DE9F843884690F82411044600F154 +:1093A000940703290DD0B04D042928680FD0072950 +:1093B00042D008293FD141463846BDE8F84300F085 +:1093C000B3BB41463846BDE8F84300F070BB90F8A7 +:1093D000BE0304F10C010609081D09F0BEFF014699 +:1093E0006A462046FFF73AFF034694F82301012816 +:1093F00010D12868E16A90F8992A91420AD290F82F +:109400009A2A90F8BE03B1FBF2F6B6EB101F05DD09 +:10941000060903E09548017801B1867954F89C1F4C +:109420003246184609F0BCFF05460246414638461A +:1094300000F042FB25602EE790F87F1300268A0794 +:10944000314602D594F8A02042B184F8A0103246EB +:1094500041463846BDE8F84300F046BB90F8BF03EC +:1094600000F00F0610F080F818B1286890F8BF03DC +:109470000609012084F8A000E9E72DE9F04104463F +:1094800000F1A805C08F0F4600054FF0050603D573 +:1094900094F8180101281ED0702128460FF02AFFE9 +:1094A00005EBC60178684860386845F83600761ED6 +:1094B000F6D200BFD7E90001C5E90D0101202863FC +:1094C00005F1580305F1400205F134012846BDE8D5 +:1094D000F04109F0F1BF182105F140000FF00AFF3B +:1094E000182105F158000FF005FF94F81A01012822 +:1094F0001FD194F82201012802D003280DD018E0D2 +:1095000094F8230110B9E089A4F82001B4F82001EF +:109510006084B4F81E0120840BE094F8230110B994 +:10952000A089A4F81E01B4F81E012084B4F820011B +:10953000608494F8230101283AD0B4F920117868A6 +:10954000E962401A90FBF6F0B4F9201100EB4002FA +:1095500001446962B4F9201101EB4001E961B4F9F9 +:10956000201111446961B4F9201101EB8000E86019 +:1095700078686860B4F91E113868A962401A90FBD7 +:10958000F6F0B4F91E1100EB400201442962B4F96F +:109590001E1101EB4001A961B4F91E1111442961AA +:1095A000B4F91E1101EB8000A8603868286081E7DB +:1095B0005FF0000005EBC002B4F920115160B4F96E +:1095C0001E1145F83010401CC0B20628F2D371E7D6 +:1095D00010B50446D1E90002C4E90D020622204676 +:1095E00009F0A1FE206B04F15803401C206304F134 +:1095F000400204F134012046BDE8104009F05CBF90 +:10960000D1E90021C0E93721D0F8D8100023491C46 +:10961000C0F8D81000F5807200F1E801DC300AF0E3 +:109620005EB82DE9FC47DFF848800C460968C8F8A9 +:109630000010DFF8349021680546C8F80410D9F806 +:10964000000017464FF0010A90F87F03400631D51D +:10965000B4F90200019005F1A806B4F9000009E090 +:10966000380510004205100004071000D006100055 +:109670007E051000009095F82401032808D00428E6 +:109680000BD0062809D007280CD008280AD00DE0F6 +:1096900069462846FFF7F1FE08E069463046FFF7C5 +:1096A00097FF03E069462846FFF7AAFF308F6080E6 +:1096B000B08E20802168C8F808102168C8F80C1006 +:1096C000D9F800004E46B0F93210B4F9020009F0A2 +:1096D0000CFE60803068B0F93410B4F9000009F075 +:1096E00004FE208095F82401032806D0042808D021 +:1096F000072817D0082815D017E03988A5F84E108C +:1097000013E03068B5F84E2090F8BE0300F00F006B +:10971000C0F110014243388800FB01200009A5F880 +:109720004E0001E0B5F84E003880D74A214605F1D9 +:10973000240000F0A0F95046BDE8FC872DE9F34F66 +:10974000D24883B000250560CF48DFF844932E4609 +:10975000056089F80050039FDFF838B34FF0010A25 +:1097600007F58057ACE000BFD7F808160AFA06F0F4 +:1097700001426ED0C6EB061000EB4611039800EBD9 +:10978000C10484F8705194F8240103280BD00428F4 +:1097900009D0072807D0082805D0092803D00A28AF +:1097A00001D00B2855D1E0680090B4F84C00ADF81A +:1097B000040004F10C01B54A081D00F05CF901AA8F +:1097C00069462046FFF72DFF8046DBF8000090F841 +:1097D0007E03400604D56946204601F08DF9804697 +:1097E000DBF8000090F87E03800603D5694620462A +:1097F000FFF7CFFDDBF8000090F87F0340070CD5A2 +:10980000B8F1000F09D094F82401032805D1608C29 +:10981000ADF80200208CADF8000094F82501012875 +:1098200008D19D48007828B994F82401082801D06F +:109830004FF000089948007828B39948007801282B +:1098400008D094F83E00400715D500BF4FF000083F +:1098500019E034E004F12000029001F0D5FA18B9C3 +:10986000029801F0E0FA08B14FF0000894F83E00C9 +:109870004007EBD407E094F81801012803D1206ACF +:10988000009084F8185194F8250103280CD199F818 +:109890000000401CC0B289F8000094F83E20520736 +:1098A00002D5401E89F8000000986062BDF80400EF +:1098B000A4F84E00B8F1010F16D084F87051761C50 +:1098C00097F91006B042BFF64FAFDBF8000090F8F2 +:1098D0003804000720D599F800107248B9B17249D0 +:1098E0000978012911D012E00098A061BDF80400A8 +:1098F000A4F85000049894F8322101680AFA02F2A0 +:109900001143016084F870A1D9E780F800A0D7F86E +:109910000C16002900D1057005B0BDE8F08F2DE9C7 +:10992000F0478946064600274FF0010800F58055AC +:1099300043E000BFD5F8080608FA07F210423BD012 +:10994000C7EB071000EB471006EBC00494F82401A6 +:1099500003280BD0042809D0072807D0082805D0F1 +:10996000092803D00A2801D00B2825D194F83231D8 +:10997000D9F8002008FA03F10A421DD0032803D1C8 +:109980002146304602F0C0FA94F93301002813DB77 +:1099900094F825010021012804D0022804D00428CD +:1099A00004D004E0032102E0042100E0052184F852 +:1099B0002611204608F0F5FF7F1C95F91006B842E5 +:1099C000B8DA00273DE000BFD5F8081608FA07F21C +:1099D000114235D0C7EB071101EB471106EBC1046B +:1099E00094F82411082902D00B2915D028E094F806 +:1099F0003221D9F8001008FA02F0014207D094F998 +:109A00003301002803DB2146304602F098FA214654 +:109A1000304602F05BFA13E094F83221D9F80010D6 +:109A200008FA02F001420BD094F93301002807DB59 +:109A3000E08F214620F40060E087304602F07FFA94 +:109A40007F1C95F91006B842BEDABDE8F0870F49D1 +:109A5000002008600C49086000F028B838B50446BA +:109A60000020009069462046FFF768FE69462046C0 +:109A7000FFF755FF38BD10B5144609F06EFC21689C +:109A8000814200DA206010BDC0061000BC06100044 +:109A9000B9061000040710009106100047071000D7 +:109AA0004C071000450610004406100070470022C5 +:109AB0008260027300F03DB87CB5044615460E4640 +:109AC000684600F036F801992A46606800F043F8CD +:109AD000606000992A46206800F03DF82060214629 +:109AE000304600F02FF87CBD7FB5044640680190F9 +:109AF0002068009015460E4602A800F01AF8039858 +:109B00006060029820602A460399019800F023F8CB +:109B100001902A460299009800F01DF800906946CD +:109B2000304600F00FF87FBD0A460146104600F0AF +:109B300009B8B1F9022012024260B1F9001009021D +:109B4000016070474A688032121242800968803191 +:109B5000091201807047C2F11003504301FB03005A +:109B600000117047B0F84020B1F840301A44A0F816 +:109B70004020B0F84220B1F842301A44A0F8422008 +:109B8000026B0B6B1A440263426B4B6B1A444263C9 +:109B9000B1F95220B0F952309A4201DDA0F85220BA +:109BA000B1F95420B0F954309A4201DDA0F85420A4 +:109BB00090F82C2191F82C319A420AD030F8462F97 +:109BC000B1F846301A4420F80E29896B0268114416 +:109BD000016070472DE9F04F97B0804600F5805046 +:109BE00000261190BEE00020089005901090129081 +:109BF000814682468346054607460A900B900C90A4 +:109C00000D9008EB860000F580501490D0F8840683 +:109C10000AAA044617E000BF90F82C1108EB010CCB +:109C2000535C0CF5805C5B1CDBB253549CF872C631 +:109C3000634506D1012B04D901238B4012990B43B4 +:109C40001293D0F86C010028E6D140E094F82C1172 +:109C5000012000FA01FC12991CEA010F12D1606B7D +:109C6000B4F90E30059A4946C0FB031205928946A5 +:109C7000B4F90C3051465A46C0FB03128A4693464B +:109C8000054419E008991CEA010F15D1A06BB4F93D +:109C90001E30059A4946C0FB031205928946B4F965 +:109CA0001C3051465A46C0FB03128A4608990544A7 +:109CB0004CEA010093460890204600F00EFC012873 +:109CC00002D11098401C1090D4F86C417F1C002CDD +:109CD000BCD1002F44DDE817044603462A46484617 +:109CE00005990FF042FAADF81E002A462346504669 +:109CF00059460FF03AFAADF81C0014984FF0FF37B0 +:109D00000025D0F8844623E0204600F0E6FB012839 +:109D100001D0109890B904F1100107A809F01DFBBB +:109D2000B8420BD207463DB129462046FFF71AFF3D +:109D30002946404600F0E8FB254607E02146284634 +:109D4000FFF710FF2146404600F0DEFBD4F86C41DF +:109D5000002CD9D10798E860E88F40F04000E887F0 +:109D60001198761C90F8FC06B0423FF73CAF17B054 +:109D7000BDE8F08F2DE9F74F05460E46C1EB061002 +:109D800000EB461082B005EBC00A00244FF001083A +:109D9000DFF894B505F580577FE0D7F8081608FA84 +:109DA00004F9424611EA090F76D0B44274D0DBF8C8 +:109DB0000C00904630F8160010EA090F6CD1C4EB85 +:109DC000041000EB441005EBC000009000F07FFB96 +:109DD000012804D0009800F080FB01285CD1009895 +:109DE00000F06DFBF0BB00990AF10C000C3109F09A +:109DF000B4FA0190DBF80C0008FA06F230F81630DD +:109E000043EA090320F8163030F81430134320F8E1 +:109E100014305046DBF8049000F06BFB012804D1AD +:109E2000009800F054FB01281BD0504600F04FFB77 +:109E3000012804D1009800F05CFB012811D05046A5 +:109E400000F045FB01281CD1009800F040FB0128E0 +:109E500017D100999AF83E0091F83E100843800609 +:109E60000FD500E018E0BAF83E00DBF8089040F0AB +:109E70002001AAF83E100098C08F40F02001009801 +:109E8000C1870198484507D241F284605146284471 +:109E9000049B009A00F047FB641C97F91006A0424F +:109EA000BFF67BAF05B063E72DE9F84F884606465D +:109EB000C1EB011101EB481006EBC004DFF868A408 +:109EC00094F83E004FF0040B40064FF0010906F5F0 +:109ED00080552DD5002704F10C0B23E0D5F808168A +:109EE00009FA07F001421CD047451AD0C7EB07100A +:109EF00000EB471006EBC000009000F0E8FA0128E4 +:109F00000FD1009800F0DBFA58B90099584610318B +:109F100009F023FADAF80810884202D2042084F803 +:109F200024017F1C95F91006B842D7DABDE8F88FF6 +:109F3000FE49E06A096891F895138842F6D900272E +:109F40002FE000BFD5F8081609FA07F0014227D024 +:109F5000474525D0C7EB071000EB471006EBC000C4 +:109F6000009000F0B4FA01281AD1009894F82C114E +:109F700090F82D01814213D1009800F0A0FA78B931 +:109F8000009904F10C00103109F0E7F9DAF8081033 +:109F9000884205D284F824B1E08F40F04000E08789 +:109FA0007F1C95F91006B842CCDA002728E000BFE4 +:109FB000D5F8081609FA07F0014220D047451ED00F +:109FC000C7EB071000EB471006EBC000834600F01C +:109FD00084FA012813D1584600F071FA78B90BF1D0 +:109FE000100104F10C0009F0B8F9DAF80810884201 +:109FF00005D2BBF83E0040F04001ABF83E107F1C9C +:10A0000095F91006B842D3DA90E72DE9F8430646F1 +:10A01000FF2000258DF80000012706F5805419E087 +:10A02000C5EB051000EB451006EBC008D4F8080698 +:10A0300007FA05F108420CD0404600F040FA01282A +:10A0400007D098F82401052803D129463046FFF7A8 +:10A050002BFF6D1C94F91006A842E1DA00251BE0E5 +:10A06000C5EB051000EB451006EBC008D4F8080658 +:10A0700007FA05F108420ED0404600F020FA012808 +:10A0800009D0404600F029FA012804D16A46294641 +:10A090003046FFF76FFE6D1C94F91006A842DFDA18 +:10A0A0000025B84620E000BFC5EB051000EB4510C9 +:10A0B00006EBC007D4F8081608FA05F0014212D0E2 +:10A0C000384600F0FCF901280DD0384600F0FFF9C1 +:10A0D000012804D16A4629463046FFF74BFEF88F27 +:10A0E00020F02000F8876D1C94F91006A842DBDAF6 +:10A0F0009DF80000401C84F8FC06BDE8F88310B50C +:10A100000446894803210C3006F0A4FB86481E2132 +:10A11000C0680FF0CDF841F284607C2120440FF03C +:10A12000E9F8824802688248B2F896138079494378 +:10A1300010B1B2F86A1349437E480068C00106D5E1 +:10A140007D480078062802D1B2F8DE134943B2F800 +:10A15000982302FB0210744A121D1160111D086041 +:10A160002046FFF752FF2046FFF734FD6E480321DB +:10A17000BDE810400C3006F085BB2DE9F0470446E1 +:10A1800091425CD007D901EB0200A0EB0201CAB2F8 +:10A19000A0EB0200C1B2C1EBC10000EB400004EB38 +:10A1A0008001C2EBC20000EB400004EB8000B1F97B +:10A1B0003250B0F9323081469D4200DA4B86CB8C6A +:10A1C000C58C2B44CB840B8D058D2B440B858B6963 +:10A1D00085692B448B61C769CE69CB68D9F80C00BF +:10A1E0004FEA234C4FEA20480CFB06FCF51907FB0D +:10A1F00008CC9CFBF5FC6CF31F430FFA83FC0CFBB3 +:10A2000006FC00B207FB00C090FBF5F060F30F0303 +:10A21000CD61CB6094F8EC04411E91420AD0C0EBB2 +:10A22000C00000EB400004EB800148465422543942 +:10A230000FF004F894F8EC04401E84F8EC04BDE838 +:10A24000F0872DE9FE4F16460F468346012B2FD18E +:10A2500001203A4A10E000BF17F8101011B1491E52 +:10A2600007F8101007EB400314785978641EA142D8 +:10A2700001DA491C5970401C97F82C108142EBD22E +:10A2800001202F4A10E000BF16F8101011B1491E2E +:10A2900006F8101006EB400113784C785B1E9C42C8 +:10A2A00001DA641C4C70401C96F82C108142EBD2F1 +:10A2B0001E484FF00109CA460068B0F88E024043BC +:10A2C0000290002001908CE0012082E000200090AC +:10A2D0009BF8EC043FE000BFC0EBC00101EB410282 +:10A2E0000BEB820202F1440116F818400B78A342EE +:10A2F00031D306EB48046478A3422CD8497817F888 +:10A300001930994227D307EB49035B78994222D849 +:10A310000C49097839B10C49097821B192F8241017 +:10A3200011F0060F17D111E090051000040710007E +:10A33000A851100060051000E80410008506100008 +:10A34000860610004406100046061000009A0AFA1D +:10A3500000F111430091401EBED2042168460DF069 +:10A36000BBFC012833DD00245246009901E0641C47 +:10A37000E4B202FA04F092460842F8D09BF8EC549A +:10A3800022E000BF00990AFA05F008421CD0C4EB95 +:10A39000C40000EB40010BEB8100C5EBC50101EBF4 +:10A3A00041010BEB81010C300C3108F0D6FF029912 +:10A3B000884209D2EAB221465846FFF7DEFE7049CC +:10A3C0000120019081F800A06D1EA542DAD808F1A5 +:10A3D000010096F82C1080464145BFF477AF09F193 +:10A3E000010997F82C104945BFF46EAF0198BDE8FC +:10A3F000FE8F644810B540780C46002856D062485D +:10A400000078002852D16148007800284ED1604879 +:10A4100094F8EC24006890F889128A4246D8002308 +:10A420000BE000BFC2EBC20101EB410104EB810173 +:10A43000B1F93210994200DD0B46521EF2D2554955 +:10A440000B80B0F88A12994230DBB0F98C120022EE +:10A450005148FBF7B0FB5049D1E90002104325D029 +:10A46000D1E90201084321D04B4A0123A2F158014E +:10A47000A1F15800FBF7BFF84748B03890F82C100E +:10A48000002913D0583090F82C0000280ED04143FA +:10A4900094F8EC040023814200D201233E4A204676 +:10A4A000583ABDE81040A2F15801CAE610BD39493A +:10A4B0000020C86038480F2110300EF01BBF90F804 +:10A4C0003E00400701D5012070470020704790F8FA +:10A4D0002401012800D00020704790F824010228B0 +:10A4E00005D0032803D0042801D0002070470120A4 +:10A4F000704710B590F83E10490603D5FFF7EDFF01 +:10A50000012800D0002010BD91F82421012A08D094 +:10A51000022A06D0062081F82401002081F82901B2 +:10A52000704701F0D3BCF0B591F9316193F9004067 +:10A5300092F93151771C02D06D1C15D00BE06E1CC6 +:10A540000BD000EB850200EB8400D26BC2F86C11DB +:10A55000C16381F831411C70F0BD641C64B240F8E5 +:10A56000241081F8314102E000EB8601C96B00EB59 +:10A570008400C1F86C21C26382F83141EBE700002E +:10A58000A8051000A8511000380510004205100061 +:10A590000407100090051000102910002DE9F0416B +:10A5A000044690F89200FF4E00270D467F284FD1B9 +:10A5B00004F10C01081D08F0D0FE0146204600F011 +:10A5C00021FB40B284F892000F2802DD0F2084F8AE +:10A5D0009200E08F80053BD56888B4F97AC0B4F961 +:10A5E0007830A0EB0C0001B22888A26FE266D6F8A2 +:10A5F00000E0C01A64229EF8C7E900290EFB01FEA4 +:10A600009EFBF2F100B201DD614401E0ACEB01011F +:10A61000A4F872103168002891F8C71901FB00F105 +:10A6200091FBF2F001DD184400E0181AA4F8700064 +:10A630006888B4F87210401AA4F876002888B4F834 +:10A640007010401AA4F87400306890F8C709E8B395 +:10A6500094F99200B5F90220C0F110015143B4F908 +:10A660007A2000FB021040F30F106880E18F89050B +:10A6700010D5B4F96E10884203DDB4F9722090420F +:10A6800005DC884206DAB4F97210884202DAB4F8BE +:10A690007200688094F99200B5F90020C0F11001B1 +:10A6A0005143B4F9782000FB021040F30F102880CA +:10A6B000E18F890523D5B4F96C10884203DDB4F924 +:10A6C0007020904207DC88420BDA00E02AE0B4F9FF +:10A6D0007010884205DAB4F870002880E08F800599 +:10A6E0000DD5B5F90000B4F97010884207D1B5F95D +:10A6F0000200B4F97210884201D184F89270316876 +:10A7000094F8920091F8C91901F00F01401A40B273 +:10A7100084F89200002801DA84F892702868A06713 +:10A72000BDE8F08184F89270012084F89000F7E78A +:10A730002DE9F04188460546012790F892103846E9 +:10A7400071B195F8901001290AD00322414605F114 +:10A750007C0008F0D2FD95F89100012803D04EE06E +:10A7600085F89000DCE70EF0FFFE8E4E0028306882 +:10A7700006D090F8CC1990F8CD0961F31F440DE094 +:10A7800090F8CA1990F8CB0961F31F4460F30F04E5 +:10A790008548017821B1C07860F31F4460F30F044D +:10A7A00023145B4322B202FB023405F178004146D8 +:10A7B00008F0D3FD0023A0421BDC3168EA8F91F83A +:10A7C000C50900EB80004000120504D591F8C409CA +:10A7D00000EB8000400010B1EA6A824209D891F88B +:10A7E0007E03000600D40027A86FC8F80000384692 +:10A7F00096E785F8913095F992000028F7DD4146FB +:10A800002846FFF7CBFEF2E72DE9F84F044601207A +:10A810000D464FF0000B00900EF0A6FEDFF884A16D +:10A820000028DAF8000011D090F8D66990F8D779AE +:10A830000322294604F17C0008F05FFDE08F00054B +:10A840001DD594F81A01012805D018E090F8D469B4 +:10A8500090F8D579ECE7DAF80000E16A90F8DC09C5 +:10A8600081420CD26888B4F87A10401AB4F88C107F +:10A870000844A4F88C002888B4F878100BE06888A5 +:10A88000B4F88210401AB4F88C100844A4F88C0074 +:10A890002888B4F88010401AB4F88E100844A4F840 +:10A8A0008E00B4F98C00002801DB014600E0414233 +:10A8B000B1425EDD4FF0010B002801DD811B00E09D +:10A8C00081190FFA81F9A0EB0900A4F88C0034F883 +:10A8D0007A1F01EB090000B22080DAF80010B1F90C +:10A8E000321008F002FD24F87A09B5F90210864604 +:10A8F000081A02B2002A01DB104600E05042B042C2 +:10A900004EDDB4F98200081A00D54042DAF8008022 +:10A910000FFA80FC98F8DA3998F8DB6998F8D809CA +:10A9200098F8D9199C450FDB9E420DD0B44501DD46 +:10A93000084609E0ACEB030C091A0CFB01FCF11A08 +:10A940009CFBF1F1084400B2B4F98C10514300298A +:10A9500006DDB9F1000F00DC40427044A4F87A0033 +:10A96000B8F93210B4F97A0008F0BFFCA4F87A0004 +:10A9700016E0DAF80010B4F97E00498E884203D15F +:10A98000B4F982208A4203D050B9B4F8821039B9A0 +:10A99000B4F97A10814203D0A4F87A004FF0010B89 +:10A9A00004E0000004071000D0061000B4F98E0087 +:10A9B000002801DB014600E04142B94256DD002893 +:10A9C00001DDC11B00E0C1190EB2801BA4F88E008E +:10A9D00034F8780F304400B22080DAF80010B1F972 +:10A9E000341008F082FC24F87809B5F9001081468B +:10A9F000081A02B2002A01DB104600E05042B842B9 +:10AA000053DDB4F98000081A00D54042DAF800801E +:10AA10000FFA80FC98F8DA3998F8DB7998F8D809B9 +:10AA200098F8D9199C450FDB9F420DD0BC4501DD3C +:10AA3000084609E0ACEB030C091A0CFB01FCF91AFF +:10AA40009CFBF1F1084400B2B4F98E105143002987 +:10AA500005DD002E00DC40424844A4F87800B8F937 +:10AA60003410B4F9780008F040FC12E0DAF8002065 +:10AA7000B4F97C00918E884203D1B4F980308B42C6 +:10AA800003D048B9B4F8801031B9B4F978108142D4 +:10AA900002D0A4F8780008E0BBF1000F05D192F8CD +:10AAA0007E03000601D400200090A06F286000986B +:10AAB000BDE8F88F10B5044690F8240104281AD197 +:10AAC000E08F400517D404F10C01081D08F045FC87 +:10AAD00001466348006890F8C629E08F5243430559 +:10AAE00009D4914202DA40F4007003E020F40070CF +:10AAF00040F48060E08710BD2DE9F0410E46044629 +:10AB00000125FFF7D7FF94F82401032804D0042877 +:10AB100007D0082825D027E03146204600F029F844 +:10AB200022E04F4F386890F87F03C00609D53146C0 +:10AB30002046FFF7FDFD054694F89000012803D05C +:10AB40000CE0012084F89000386890F87F0300073B +:10AB500004D531462046FFF757FE0546012D03D0A8 +:10AB600005E0D4F8880030603068C4F888002846D2 +:10AB7000D6E570B504460868A0670D46032204F1C7 +:10AB80007C0008F0C7FB3648026892F87F03C106D4 +:10AB90004FF000002ED533490E7801217F231EB3DC +:10ABA000E68F360520D594F82361012E15D084F860 +:10ABB000900084F8911084F89230D4F81E11A167A7 +:10ABC0006988B4F87A30C91AA4F876102988B4F8DC +:10ABD0007830C91AA4F874100CE084F8901084F846 +:10ABE000910084F8920005E084F8900084F89110B8 +:10ABF00084F8923092F87F13090702D524F88C0F5D +:10AC0000608070BD10B50C460EF0AEFC14490A68A9 +:10AC100080B192F8D30992F8D03900F00F01000901 +:10AC200092F8D1295B4352439C4202DD94420CDBF3 +:10AC3000084610BD92F8D20992F8CE3900F00F0103 +:10AC400000095B4392F8CF29EDE79A4200D1521CEC +:10AC5000E41A411A4C43D11A94FBF1F1401A10BD89 +:10AC60000407100047071000F0B5F64A00261768E1 +:10AC70007B8E97F8954ABA8E97F836701D465FEA34 +:10AC8000477C03D5A3EB204C6CF31F405FEA877C25 +:10AC900003D5A2EB000C6CF30F00FF0706D00314E2 +:10ACA00060F31F4063F30F0013462A46DFF898C392 +:10ACB0009CF80050C5B10514B5EB530F05B206DA88 +:10ACC000B5EB520F01DA002507E0012505E0B5EBF1 +:10ACD000520F01DA022500E003250127AF400F42A1 +:10ACE00002D00CEB0501CC780114A14202DB1B1B46 +:10ACF0008B4206DA00B2A04202DB111B814200DA6D +:10AD000001263046F0BDD0490022897809B1C068DB +:10AD1000AAE7104670472DE9F041CB4F0D463A4661 +:10AD20000646797892F803C013790020C54C527911 +:10AD30005FEA017E06D01946604608F077FA0146C0 +:10AD4000B87916E08F0702D01946604611E0BE4F71 +:10AD500011F00B0FBF7901D0394603E011F0050F58 +:10AD600002D06146104604E011F00A0F10D03946B7 +:10AD7000184608F066FA58B1216891F8A42A824270 +:10AD800006D391F89E0A3070206890F89F0A0EE072 +:10AD9000216891F8A42A82420CD291F8A52A824215 +:10ADA00008D391F8A00A3070206890F8A10A2870A2 +:10ADB000BDE8F08191F8A52A8242F9D291F8A62A3D +:10ADC0008242F5D391F8A20A3070206890F8A30A65 +:10ADD000EDE730B50124039D9C4035B10914914243 +:10ADE0000EDA81682143816030BD09B2914203DAF5 +:10ADF00001682143016030BD41682143416030BD9D +:10AE0000C1682143C16030BD9049B0F90000B1F97B +:10AE10002020824203DCB1F92210814201DA0120B4 +:10AE20007047002070478949B0F90200B1F91A1043 +:10AE3000884201DD01207047002070472DE9F8436A +:10AE400091460646DDE9087208790025DDF828C03C +:10AE50000C46032832D27B48DFF8F481016891F870 +:10AE60004214E170D8F80480B8F1000F06DDD0F884 +:10AE7000008098F84384A1EB0801E1700068316B11 +:10AE8000B0F84404814217DDDBB249463846CDF8BC +:10AE900000C0FFF79EFF2079401CC0B2207103283C +:10AEA00006D06C49B6F95400B1F90010884205DDAE +:10AEB00003202071012501E0002020712846BDE813 +:10AEC000F8832DE9F041044663480078002853D008 +:10AED0005C48006890F83804C0064DD594F93301F9 +:10AEE000002849DAE08F800446D4A08F0025400571 +:10AEF00000D5012504F10C00FFF786FF0346E08F23 +:10AF00004FF0010641044FF002074FF0030C1CD52F +:10AF10002B430BD084F8247140F00400E08794F8B0 +:10AF2000280103281FD284F828C11CE04BF6FB71CE +:10AF3000084040F42050E087002204F58F7120463D +:10AF400000F0A5FE84F81A610DE004F12000FFF77F +:10AF50005BFF012801D1012B0FD0E08F20F480404E +:10AF600040F40050E087E08F400405D53B4810F8DE +:10AF70005B1F41F0040101701AE7002DF3D0E08F50 +:10AF800044F204010843E08784F8247194F828010E +:10AF9000032801D284F828C10021C4F81811C4F88C +:10AFA0001C11C4F82011E168C4F81E1184F8226154 +:10AFB000D9E72DE9FC47234E04460025306890F878 +:10AFC0009E1A8DF8001090F89F1A8DF8041094F8CE +:10AFD000711139B994F872219AB390F831305B1E2F +:10AFE0009A423FD090F83020521E914202D194F8FC +:10AFF000723133B3914206D190F8310094F8721156 +:10B00000401E81422ED001A96846FFF784FE3268B7 +:10B01000B4F952009DF8043092F89C1AB1464843A6 +:10B02000642190FBF1F007B294F871110C48994239 +:10B030001AD294F872619DF800C0664514D20021BE +:10B0400020E00FE004071000D706100030291000A0 +:10B05000A005100028061000470710009055012099 +:10B06000AC06100001253CE0994213D292F8316001 +:10B070009DF8008094F872C1A6EB0808C44509DB6E +:10B08000761EF1B200680EF0B9FAB0F90000B842CD +:10B09000E8DC26E092F830C04E46ACEB0303994260 +:10B0A00007DB94F872C19DF80080C44501D20021ED +:10B0B0000CE0994215DB92F831109DF8002094F8CD +:10B0C00072318A1A93420CDB491EC9B200680EF035 +:10B0D00095FA316891F8301000EB410030F9020C1C +:10B0E000D5E72846BDE8FC872DE9F04F4FF0000B6F +:10B0F00085B00D4681465E464FF0020A4FF00108CA +:10B1000000F58057B0E100BF08FA06F0D7F808163E +:10B11000019001421BD0C6EB061000EB461109EB73 +:10B12000C10404F58C7004902046FFF7CAFEE18F3D +:10B1300048040CD4E0680090039094F8240101289E +:10B1400006D0022804D049077ED504287DD08AE1A4 +:10B15000FF4AB4F95210B2F900209142F7DB0128FE +:10B1600004D104980021016041608160F9480078B1 +:10B1700020B12046FFF7C7FD012807D0F5484178E8 +:10B18000E068FFF771FD012803D00DE084F87681B7 +:10B1900069E1F148006890F8920AC00604D520469B +:10B1A000FFF707FF012833D0EC4A0098B2F90010EE +:10B1B00000B288420DDBB2F90210884209DC009926 +:10B1C000B2F90A300914994203DCB2F90830994205 +:10B1D0005ADAE18F41F00401E1870499E368C1F88C +:10B1E0000630B2F90010884203DBB2F9023098420F +:10B1F00039DD00200095CDE90110DDE9032133465A +:10B200002046FFF71BFE0499834681F80AA02AE135 +:10B21000D148016891F89D2A84F87721B4F852202A +:10B22000A4F87421626EA266E18F41F00401E18707 +:10B230000499E268C1F80620049906228A72049AE9 +:10B2400082F80B80006801E0F1E06BE090F8950A6D +:10B250000095CDE90108DDE9032133462046FFF7DB +:10B26000EDFD8346FFE0B2F90810CDF80880CDE986 +:10B270000051DDE9032133462046FFF7DFFD834619 +:10B28000049804218172EEE0B2F9103098420BDB91 +:10B29000B2F91230984207DCB2F91A30994203DC55 +:10B2A000B2F91830994235DAE18F41F00401E187B3 +:10B2B0000499897A19B90499E368C1F80630049BA6 +:10B2C00083F80A80B2F91010884203DBB2F9123019 +:10B2D00098420EDD00200095CDE90110DDE9032143 +:10B2E00033462046FFF7AAFD8346049880F80A807B +:10B2F000B9E0B2F91810CDF80880CDE90051DDE9C8 +:10B30000032133462046FFF799FD04998346032025 +:10B310008872A8E004980021817228690199084385 +:10B320002861A0E00498807A06280DD08B4A009905 +:10B33000B2F9103009B2994203DBB2F912309942E6 +:10B3400061DD03285BD08EE0834894F861200068BB +:10B3500090F83010491E8A4202D094F8601041B92A +:10B3600090F8920AC00604D52046FFF722FE012875 +:10B3700012D094F87701A0B1B0F1010084F8770100 +:10B380007548CDF80080F3B200680399B0F9962AA9 +:10B390002846FFF71EFD66E06F48006890F89D0A9A +:10B3A000ECE700986D4A01B2B2F91000814203DB6C +:10B3B000B2F9123099420EDD00210095CDE901016C +:10B3C000DDE9032133462046FFF738FD0499834623 +:10B3D00081F80A800FE0B2F91810CDF80880CDE9A5 +:10B3E0000051DDE9032133462046FFF727FD04998C +:10B3F0008346032088725A4880F8008033E004991D +:10B4000081F80A800EE00099B2F91A3009149942C5 +:10B4100003DCB2F91820914225DA012823D10499DE +:10B42000032088720498E168C0F806101BE00098B9 +:10B4300001B24A48B0F91020914214DDB0F912204F +:10B44000914210DA0099B0F91A20091491420ADAEF +:10B45000B0F91800814206DD2969019A114329617A +:10B460003F4981F80080761C97F91006B042BFF67C +:10B470004BAE28686C68A968EB6840EA040241EAB0 +:10B4800003063243374E2A6901D022B105E022B1CA +:10B4900086F800A001E086F80080304A583216682D +:10B4A000B0432860506884436C6090688143A96011 +:10B4B000D0682D498343EB6028690978084305D19A +:10B4C00026492C222C3125480DF0B8FE05B05846EF +:10B4D000BDE8F08F30B5234B0021049A1B78012B77 +:10B4E00001D102B1012190F82421042A2DD11A4A58 +:10B4F000136893F83824520727D5B0F84820B0F8DD +:10B500004A40121B154C248DA2421EDD4FF491724D +:10B51000125C012A01D0022A0AD190F8614090F809 +:10B520006050641B93F84154AC4201DD01210CE0F2 +:10B53000032A01D0042A08D190F8632090F8620011 +:10B54000101A93F841249042F0DC084630BD000008 +:10B5500040061000D7061000040710003029100024 +:10B5600046061000A0051000B906100030B5FF4ACD +:10B570000021136893F8382452072BD590F8242122 +:10B58000042A27D1B0F84820B0F84A40121BF84CE2 +:10B59000248DA2421EDD4FF49172125C012A01D06B +:10B5A000022A0AD190F8614090F86050641B93F829 +:10B5B0004154AC4201DD01210CE0032A01D0042AF0 +:10B5C00008D190F8632090F86200101A93F8412493 +:10B5D0009042F0DC0846B9E72DE9F34F97B0E54813 +:10B5E000002415940078DFF888B301280BD118984F +:10B5F000006940B1DBF804A0DBF80C90DBF81480A4 +:10B60000DBF81C6007E0DBF800A0DBF80890DBF853 +:10B610001080DBF81860179F002507F5805703E2BC +:10B620000120A840D7F80816059001420FD0C5EBBD +:10B63000051000EB4511179800EBC1000290C08F78 +:10B64000410404D4400703D4CB4901200870EAE147 +:10B65000029800F58C7003900298C0680C900790D7 +:10B66000029890F82401012806D0022804D004286A +:10B670002ED005287ED0D6E118981422C1680091FA +:10B68000006901900CA818990DF093FD0DF1300C94 +:10B6900002989CE80E00FFF71DFF012801D10399D5 +:10B6A000487018981422C1680091006901900CA894 +:10B6B00018990DF07EFD0DF1300C02989CE80E00FB +:10B6C000FFF754FF0128C2D103990020C870AAE1F6 +:10B6D0000398807A012801D0032803D1DBF8148075 +:10B6E000DBF81C6018981422C16800910069019071 +:10B6F0000DA818990DF05DFD0DF1340C02989CE831 +:10B700000E00FFF733FF01280CD00398C07810B16A +:10B710000399401EC8709948008830B103990020F1 +:10B72000C87005E000200399F4E70398C07828B9B1 +:10B73000029890F82E110120884004431898142292 +:10B74000C1680091006901900DA818990DF031FDB4 +:10B750000DF1340C02989CE80E00FFF7BBFE0128A7 +:10B7600001D10399487003980079032820D20399E6 +:10B77000C97800E01BE1D9B102990A6B7B490968DD +:10B78000B1F844148A4210DD401C0399C0B203286A +:10B79000087107D002987A49B0F95400B1F9001045 +:10B7A000884205DD0120159002E003990020087110 +:10B7B0000398837A062B27D00C980FFA8AF200B2EE +:10B7C00090420DDB4FEA2A41884209DC0C994FEA8E +:10B7D000294C0914614503DC0FFA89FC614541DA03 +:10B7E000DDE902319042DB68C1F8063003DB4FEA45 +:10B7F0002A4188422DDD03980221EBB2817200209C +:10B8000000900799189891E01898059A016901200D +:10B81000114217D00299002291F82E1188408443DA +:10B82000DDE90201891D00F032FA02984FF6FB3182 +:10B83000C08F084040F400610298C187039901203D +:10B840008870F0E000904948EBB20068B0F9962AA1 +:10B85000D7E703980421EBB2817201200FFA89F235 +:10B860000090CEE70FFA88F20692904209DB4FEA89 +:10B870002842904205DC3014814202DC30B2814221 +:10B8800057DA022B02D0042B04D00BE003990120DD +:10B89000887202E0039803218172DDE90210C96811 +:10B8A000C0F806100398407850BB0398801D0090A4 +:10B8B0000298DBF824100591019090F822110C30C9 +:10B8C0000129009925D007F048FD059988420DDD32 +:10B8D000DDE90010002200F0DAF901984FF6FB31A3 +:10B8E000C08F084040F400610198C1870298C08F62 +:10B8F000000505D5029890F82E1101208840844358 +:10B900000398807A01280BD00120EBB232B200906C +:10B9100077E7B1F90210B0F90200081A4043D4E702 +:10B920000020DDE906210090EBB21898FFF751FAEC +:10B9300079E018980022016905980143189801617F +:10B94000DDE90201891D00F0A2F902984FF6FB31F2 +:10B95000C08F084040F400610298C187039901201C +:10B9600088700298B0F8401000480BE004071000FF +:10B9700030291000A0051000460610000E07100028 +:10B9800028061000006890F84E24914208D90299C8 +:10B9900090F84F0491F828110844029981F8280181 +:10B9A000029890F82E110120884084433BE00398D0 +:10B9B000807A012804D003280FD006280DD032E069 +:10B9C0000398C07878B30298B0F95410B948006869 +:10B9D000B0F8550481420CDC25E00298B0F954100F +:10B9E000B4480068B0F8500481421CDD0398C07868 +:10B9F000C8B1B148008888B9B048007801280DD096 +:10BA0000DDE902010122891D00F041F90298C08F91 +:10BA100020F0040040F400410298C1870298B0F879 +:10BA20005410A0F852106D1C97F91006A842BFF6EA +:10BA3000F7ADA3480CB1012100E000210170159879 +:10BA400019B045E530B59B490A689E49938E088038 +:10BA50001B1A4B8092F8474405198D801B1BCB8025 +:10BA6000528E0881101A48818D81001BC8816DE5B6 +:10BA7000904909688A8E93490884101A488470474F +:10BA80008C4B904A1B6840B171B1598E081A508393 +:10BA900093F84A14401AD083704711B1588E5083DE +:10BAA000F9E70020108303E0108393F84A14084458 +:10BAB000908370477F4A10B4136882499A8E60B1B0 +:10BAC0000882121A4A8293F84A4420448882101B42 +:10BAD000C88293F84D0410BCCAE7002008824A824D +:10BAE0008882CA8208844A8410BC704770B5714C41 +:10BAF000206890F84604FFF7A5FF206890F84B04F3 +:10BB0000FFF7D8FF2068012190F85404FFF7B8FF31 +:10BB10002068002190F85404FFF7B2FF2168694AB9 +:10BB200091F848044043506291F8490410856549F2 +:10BB30002C22A1F12C000DF081FB61480024634D03 +:10BB400004706148142104705E486C602C300DF064 +:10BB5000D1FB5F4804702C7070BD70B586B006468E +:10BB6000142168460DF0C6FB57480024694604704E +:10BB70003046FFF7B9FA054669463046FFF72CFD17 +:10BB800028435249012801D0486805E04948006827 +:10BB900090F84204401F4860002804DD401E4860C1 +:10BBA0004748007800B94C604648142269462C305A +:10BBB0000DF044FB06B070BD2DE9F04700F13806EA +:10BBC0000546B078434F0B460024B8B1424AF1789D +:10BBD0001078401E814258D1C1B2904618460DF0EF +:10BBE00007FD814698F80000401EC1B238680DF08C +:10BBF00005FD034630787278014611E000211846B1 +:10BC00000DF0F6FC81460021F0E700BF19F8006056 +:10BC100095F84770BE4201D1641CE4B2401CC0B22A +:10BC20008242F3D2234E61B13068B0F83A04491E23 +:10BC3000C9B233F91170874203DD641CE4B20029F4 +:10BC4000F5D126480078401E82420DDA31688242E2 +:10BC50000ADA521CD2B2B1F83AC433F9127067450D +:10BC600002DD641CE4B2F2E71D4880F85C403168F4 +:10BC700091F84C14A14208D2A98C41F48061A984A6 +:10BC800010F85B1F41F008010170BDE8F087022346 +:10BC900080F82431002380F828310123C362012A6F +:10BCA00004D00968016280F81831704703220C3013 +:10BCB00007F030BB040710000E0710002605100027 +:10BCC000440610005C29100046061000A005100074 +:10BCD00045061000AC061000850610008606100010 +:10BCE00090550120FBF7DCBD10B54FF4B8519F48CB +:10BCF0000DF000FB4FF49E619D480DF0FBFA9D484E +:10BD0000FF2180F8101600F080FCFEF7D0FBFFF753 +:10BD1000EDFE00F03BF9FDF76CF8FDF798FEFBF740 +:10BD2000C1FDBDE81040FCF791BC70B5924D0024F8 +:10BD30008E48AC7100F06FFC9048007828B18B48B9 +:10BD4000FFF70BFF894800F022F98848FDF75DF8FE +:10BD50008648FDF783FE8A4E307810B98348FBF79A +:10BD60008FFE8348347080F8EC448248B0F81406A3 +:10BD7000A5F81F0070BD2DE9F0417D4C7E4D94F873 +:10BD8000EC04B8B3A8717F487F4F0026067038686E +:10BD900090F88002800703D521467448FEF729FBFE +:10BDA0007349724800F073FC7448007810B16F4812 +:10BDB000FFF7D3FE386890F87E03C00702D06B48C7 +:10BDC000FEF79DF9694800F0E2F8684800F075F95F +:10BDD0006648FDF71AF86548FDF740FE6348FBF733 +:10BDE0004FFE84F8EC646348B0F81406A5F81F0011 +:10BDF000BDE8F081FFE7FFF798FFF4E710B55E4874 +:10BE000000248471594800F006FC5848FCF7FDFFF7 +:10BE10005648FBF7BEFD564880F8EC4410BD10B5FF +:10BE2000534C94F8EC04D8B15349887121464F48DB +:10BE300000F02DFC5448006890F87E03C00702D043 +:10BE40004A48FEF75CF9494800F0A1F84748FCF77A +:10BE5000DCFF4648FBF79DFD002084F8EC0410BD94 +:10BE6000BDE81040CAE710B5414C014694F8EC0417 +:10BE70000F280DD2C0EBC00000EB400004EB8000A7 +:10BE800054220DF0DBF994F8EC04401C84F8EC0427 +:10BE900010BD10B500F580500021D0F80836012201 +:10BEA00002FA01F423420BD18A401343C0F808364A +:10BEB00090F910268A4201DA80F8101648B210BDB7 +:10BEC000491C0F29ECDB4FF0FF3010BD10B500F519 +:10BED000805091F832410123D0F80826A3409A43BC +:10BEE000C0F80826002281F8242190F9102691F943 +:10BEF00032118A4207D1D0F80816B1FA81F1C1F1A6 +:10BF00001F0180F8101610BD30B500F580500022DA +:10BF1000D0F80C46012300BF03FA02F52C4206D1EB +:10BF200093401C43C0F80C4681F8332130BD521CAD +:10BF300052B20A2AF0DBFF2081F8330130BD10B580 +:10BF400000F5805091F833410123D0F80C26A3402E +:10BF50009A43C0F80C26FF2081F8330110BD044835 +:10BF60007047034890F8EC0470470000A0291000C7 +:10BF7000A0401000A0391000905501204707100084 +:10BF800010071000A80510000407100070472DE9E5 +:10BF9000F047054641F20860042128440BF09CFE5E +:10BFA00000240127DFF86C81DFF86C914FF0050A5F +:10BFB00005F580567BE000BFD6F8081607FA04F0B6 +:10BFC000014272D0C4EB041000EB441005EBC00139 +:10BFD00091F82401012804D0022802D0042840D07E +:10BFE00063E091F87601012808D091F82501032833 +:10BFF00008D0042806D001282CD056E0002081F873 +:10C00000760123E0454848F20403B0F90020C88FC8 +:10C01000184203D0424AB2F9002005E0030503D5D7 +:10C02000404A1268B2F95A24030702D53E4AB2F9CF +:10C030000020B1F95230934237DAC00506D5B8F97D +:10C040000000834202DD81F825712EE02846FFF7CB +:10C050003DFF2AE0B1F95220B8F900008242F5DB39 +:10C0600023E091F83C0010F0060F1ED091F83E003E +:10C0700040071AD42E4A2D481278B0F90000012A40 +:10C0800001D1B9F9000091F82521032A02D0022A32 +:10C0900005D00AE0B1F95220B9F9000001E0B1F988 +:10C0A0005220824201DA81F824A1641C64B296F91C +:10C0B0001006A04280DABDE8F087F0B50021012625 +:10C0C00000F5805304274FF00D0C00BFD3F808266D +:10C0D00006FA01F4224218D0C1EB011202EB411220 +:10C0E00000EBC202002592F82441092C06D00A2C4C +:10C0F00004D00B2C05D00C2C03D004E082F8247162 +:10C1000001E082F824C1C2F83851491CC9B20F2994 +:10C11000DCD3F0BD2C0610002E06100028061000FF +:10C1200040061000040710004A06100030061000F8 +:10C130004506100090F83C10090603D5C18F41F068 +:10C140000801C18770472DE9F05FDFF890A615461A +:10C150000C46834601F10C074FF000084FF0FF3901 +:10C1600002F10C069BB3012084F8240195F84600E7 +:10C1700084F8250184F8339184F8288184F8298192 +:10C18000A4F83E80C4F82C8084F8278184F82A81A2 +:10C1900095F8480084F82D01688EA4F85400E868EA +:10C1A000206203223146204607F0B4F803223146CC +:10C1B000384607F0AFF84FF40040A4F85E00A4F84A +:10C1C0005A00401EA4F85C00A4F858003CE0FFE7C9 +:10C1D0001146204600F037FBE06A0322401CE06273 +:10C1E0003146204607F089F803223146384607F0E9 +:10C1F00084F894F82C0184F82D01DAF80000E16A43 +:10C2000090F8DA0381421FD2E089618A401AB4F9BA +:10C210005A1000B2814201DAA4F85A00B4F9581059 +:10C22000814201DDA4F85800A089218A401AB4F99E +:10C230005E1000B2814201DAA4F85E00B4F95C102D +:10C24000814201DDA4F85C0094F82501042851D056 +:10C2500095F8460084F8250195F8460084F82501F4 +:10C2600095F8480084F82C0195F8470084F82E01D1 +:10C27000E88CA4F84000288DA4F84200688DA4F84A +:10C280004600E88DA4F84800288EA4F84A00288BC0 +:10C29000A4F84C00B5F93200A4F85200A969216352 +:10C2A000E9696163296AA163A98EA4F85610A98C73 +:10C2B000A187A96B21666969E16195F8491084F845 +:10C2C0002F1195F84A1084F83011B5F84E10A4F8E3 +:10C2D0004410B4F95410814201DAA4F85400C4F8AF +:10C2E0006C8184F83191A88C8005E08F16D540F4DC +:10C2F000807015E095F84610042908D094F93401AF +:10C30000002801DD401E06E084F82511A4E7DAF8D4 +:10C31000000090F8940A84F834019DE720F48070BE +:10C32000E08755F83C0F6066287A84F87101687AD6 +:10C3300084F872012146584600F05CFA2046BDE8B8 +:10C34000F05FF7E6F0B5B1F90260B2F90250782477 +:10C3500006FB05F7002F2ADDB1F90070B2F900C025 +:10C3600007FB0CF7002F22DD76435D4396FBF5F5C6 +:10C370002DB24580B1F90010B2F9002049435A436B +:10C3800091FBF2F10AB20280782D00DD4480B0F911 +:10C3900002306FF077018B4200DA4180782A00DDAD +:10C3A0000480B0F900208A4200DA0180F0BD00214B +:10C3B0004180FAE72DE9FF4FDFF8248483460F46DA +:10C3C000D8F8040087B00021016000F0CBFA002506 +:10C3D0000BF580564FF00109059088E0D6F8080665 +:10C3E00009FA05F108427DD0C5EB051000EB4511B7 +:10C3F0000BEBC10494F82401072876D0F74805997F +:10C4000001910068214690F88CA3201D06F0A5FF3D +:10C4100000FB0AF0019900FB0AF0884200DA0846A6 +:10C42000EE49096891F87F23920611D5E26A012A44 +:10C430000ED802D191F8D81302E04AB991F8D71377 +:10C44000019A01FB01F101FB02F1884200DA084682 +:10C4500082462246211D684606F075FF221D111DE9 +:10C4600003A806F070FFBDF900006430C82804D8A6 +:10C47000BDF902006430C82801D9012300E003237C +:10C4800003AA694602A8FFF75DFF6088BDF80A109D +:10C490000844ADF812002088BDF8081000240844B4 +:10C4A000ADF810001BE000BFC4EBC40000EB40007F +:10C4B00007EB800104A80C3106F04FFF50450CDA61 +:10C4C000D8F804100A6802EB420201EB4202506005 +:10C4D000547215720868401C0860641CE4B297F836 +:10C4E000EC0400E001E0A042DED86D1C6DB296F9CC +:10C4F0001006A842BFF672AFD8F80400464601689D +:10C5000000297FD000F00AFA00244FF0040A75E0F9 +:10C5100004EB440100EB410090F9085090F909C088 +:10C52000099809FA05F1036848460B4265D10A9A51 +:10C53000D2F8008000FA0CF218EA020F5DD10998D7 +:10C540000B43C84603600A980A9900230068104309 +:10C550000860C5EB051000EB4511CCEBCC0000EBFF +:10C5600040000BEBC10507EB800229465846FFF758 +:10C57000EAFD95F82401032808D0042809D00628EC +:10C580000DD00B2836D00C2834D036E085F8278122 +:10C5900002E0002085F8270185F824A12DE085F828 +:10C5A00024A195F83C0010F0060F26D095F83E0027 +:10C5B000400722D48B48B0F900108B48007801283E +:10C5C00002D18A48B0F9001095F82501032802D05D +:10C5D00002280AD011E08548B5F95210B0F90000E0 +:10C5E00081420ADA062006E00CE0B5F952008842E2 +:10C5F000F8DB02E00C2085F82401641C70680168F7 +:10C60000A14285DC0BB0BDE8F08F754800210170B8 +:10C610004160816070472DE9F041054641F2546068 +:10C620002E2128440CF066FE0024052705F58056CF +:10C6300020E00121D6F80806A140084219D0C4EB39 +:10C64000041000EB441005EBC00191F8240103280D +:10C6500016D0042814D0022815D0092810D00A2892 +:10C660000ED00B280FD00C280DD00D280BD00E2883 +:10C6700009D0641C96F91006A042DADABDE8F08110 +:10C6800081F82471F5E72846FFF720FCF1E72DE952 +:10C69000FC470446002552480F4600950121001D25 +:10C6A000019504F0D7F84E480521083004F0D2F87F +:10C6B00041F254602E2120440CF01CFE484EFF2213 +:10C6C0002D21B0680CF0ECFD357004F580564FF06C +:10C6D0000108D6F8080688B36B4601AA39462046F9 +:10C6E000FFF768FE4FF0050924E000BFD6F80816F2 +:10C6F00008FA05F001421CD00199084219D1C5EB96 +:10C70000051000EB451004EBC00191F8240103284B +:10C7100018D0042816D0022817D0092812D00A28C9 +:10C7200010D00B2811D00C280FD00D280DD00E28BA +:10C730000BD06D1C96F91006A842D7DAD6F8086619 +:10C7400000253AE081F82491F3E72046FFF7BEFB8D +:10C75000EFE700BF009908FA05F008422CD1204607 +:10C76000FFF797FB002827DBC0EB001101EB40111E +:10C7700004EBC109C5EBC50101EB410107EB8102E7 +:10C7800089F83201494601232046FFF7DCFC9EB9B7 +:10C7900017480078012809D109F1280109F10C0096 +:10C7A00006F017FE4846FBF7DDFE28B1B9F83E005B +:10C7B00040F48051A9F83E106D1C97F8EC04A84293 +:10C7C000C8D807480121001D04F05CF80448052181 +:10C7D000083004F057F8BDE8FC870000040710009B +:10C7E000AC05100030061000450610002E061000A3 +:10C7F0004C07100030B5714A91F82C519468635D74 +:10C80000FF2B05D1137863550F2B01D25B1C1370DE +:10C8100091F82C21A25C81F82C2100EB420202F558 +:10C82000805291F83251B2F854360124AC4023437F +:10C83000A2F8543691F82C1141F2726210440A5C4D +:10C84000521C0A5430BD2DE9F041044691F84600CF +:10C8500000260D46012801D184F82A6194F82501AB +:10C86000574FDFF8608101281FD195F84600032853 +:10C870004DD194F82401022804D0032806D00428BE +:10C8800004D01EE02046FCF73AFA0EE0D8F800107B +:10C8900094F82A0191F84B1301F00F01884202D855 +:10C8A0003978012906D084F82A6195F846000328D2 +:10C8B00007D008E0401C84F82A01012085F84600D2 +:10C8C00001E084F82B6194F8250103281FD195F825 +:10C8D000460001281BD194F82401042817D1387888 +:10C8E000B0B9D8F80000B4F954200321B0F852339D +:10C8F0009A4210DA94F82B2190F85403824207D21E +:10C9000085F8461094F82B01401C84F82B01B5E6FD +:10C9100084F82B61B2E685F84610F9E77CB5002172 +:10C920001CE001EB41034A1C00EB430312E002EB65 +:10C93000420400EB44045E686568AE4209DD00967F +:10C940001E89ADF804605D6025891D81009D6560CC +:10C950002681521C04689442E9DC491C02688A4220 +:10C96000DFDC7CBD70B5174D2868B0F882430CF051 +:10C97000FBFD80B128681449B0F88643B0F88A03FB +:10C980000968884207DA0CF0F9FD012803D128680C +:10C99000B0F8880304440D48007810B12868B0F856 +:10C9A00076420CF0EBFD012804D12868B0F884032E +:10C9B00000B1044604FB04F070BD0000AC0510009B +:10C9C0009106100004071000BC0610003805100086 +:10C9D000F0B500240646254620465F4209E000BF28 +:10C9E00036F91130934201DD1D4402E0BB4200DA0A +:10C9F0001C44491EF4D2002C00DA6442AC4200DD33 +:10CA00000120F0BD2DE9F047FF4D002047F6FF79EA +:10CA100001462A464B46FD4CFD4EB4F900403668AF +:10CA2000A4460AE036F91C70974200DD3A469F4260 +:10CA300000DA3B46381841EBE771BCF1010CF1D24A +:10CA4000F44FD21A4FEAE47A7A60224653460CF049 +:10CA50008CFB0FFA80FC00200146224606E000BF56 +:10CA600036F91230A3EB0C03C3FB0301521EF7D2BD +:10CA7000224653460CF079FB0A21386090FBF1F016 +:10CA8000E549E64B4A46A1F8790000200146A44654 +:10CA90001E680AE036F91C30AB4200DD1D469342A9 +:10CAA00000DA1A46181841EBE371BCF1010CF1D21F +:10CAB000AA1AFA60224653460CF057FB05B2002032 +:10CAC0000146224605E000BF36F912305B1BC3FB6E +:10CAD0000301521EF8D2224653460CF046FBB860C2 +:10CAE000BDE8F08730B41446CA4A15689368AB4273 +:10CAF00002DD5B1B834206DCD3685068834204DDA1 +:10CB0000181A884201DD012200E00022214630BCD3 +:10CB1000C34806F09ABB10B50C46C24909784A00D2 +:10CB20000146C1480CF045FBC04821460078420050 +:10CB3000BF480CF03EFBBF490120087010BDB3494F +:10CB400010B5B1F900104A000146B44800680CF075 +:10CB500030FBB9490120087010BD2DE9FF5FB048D6 +:10CB600000240C38DFF8D49244600470D9F8000037 +:10CB7000DFF8ACA2984690F8EB13264627462546E8 +:10CB80000907AAF1040A16D5A2490A890B88D31A03 +:10CB9000A14A22F8673F8B898988591A518090F8F9 +:10CBA0001224B0F81014D0F80C04FFF79BFF1227E2 +:10CBB0000446012601E08AF80450D9F8000090F8F4 +:10CBC000A502400701D59E4805708CBBDFF874B202 +:10CBD0009BF8000010B99BF8010018B10098F9F714 +:10CBE00004FC0AE09848007818B10021062005F0FE +:10CBF000E7FE95480570954805709BF8001011B93F +:10CC00009BF80100A0B1D9F80000DFF844B290F819 +:10CC1000EB03C0070DD08F4A8F49DBF8000000F00E +:10CC2000D5F804004FF030074FF0010603D012E0B2 +:10CC300024E08AF80150D9F8000090F8EB0380074F +:10CC400009D5844A8449DBF8000000F034F9312723 +:10CC50000446012601E08AF802506CB9D9F80000B8 +:10CC600090F8EA03400707D57A497B4800F060F95D +:10CC700021270446012601E08AF803500CF08AFCC3 +:10CC8000764BDFF8DCC1012118707648012C08D101 +:10CC9000D9F8002092F857241AB18CF800100280BD +:10CCA00007E0028812B1521E028001E08CF80050A9 +:10CCB0007CB3D9F8002092F8F021120600D576B99D +:10CCC0006EB188F800503946052005F079FE0098CD +:10CCD000FFF735FFDDE90101FFF71DFF15E088F8DB +:10CCE00000104F490C390F704A6842F002024A6046 +:10CCF000D9F8000090F85032DB0703D190F8800299 +:10CD0000C00702D042F008004860012004B0BDE82E +:10CD1000F09FFFE788F800501878F7E72DE9F05FFB +:10CD2000DFF8FCA00024AAF10C0ADFF81091CAF881 +:10CD3000044083468AF80040D9F800000E46274692 +:10CD400090F8EB132546A04649060BD590F8192418 +:10CD5000B0F81714D0F81304FFF7C4FE12250446E8 +:10CD6000012703E02E49091F81F804800CF012FC12 +:10CD700001463A480170E4B17FB186F80080D9F8E5 +:10CD8000000090F8EB03C00603D52946052005F006 +:10CD900017FE5846FFF7D3FE09E0012030708AF8ED +:10CDA0000050DAF8041041F00201CAF80410012022 +:10CDB000ADE786F800800078A9E7194900200C3912 +:10CDC0004860087008310860087170472DE9F74F16 +:10CDD000DFF868900B468246D9F80010114800260B +:10CDE000B1F9F27391F8F683B1F9F453027834464D +:10CDF0003946184600F0C0F883460C483946027898 +:10CE0000029800F0B9F82FE00080FFFF96061000AE +:10CE1000B00610002C14012090550120B40610001B +:10CE2000C405100085061000006F01208606100062 +:10CE30002A6F012045071000440710000407100066 +:10CE400042051000A85110003805100026051000FA +:10CE5000A8061000FA0C0120D00C01204E0610008C +:10CE60000C0710000E0710000146BBF1000F00D0A8 +:10CE7000A1B94E4852460024B0F9000009E000BFB5 +:10CE800032F91010002900DA4942A94201DD641C80 +:10CE9000E4B2401EF4D2444500D90126D9F800007E +:10CEA000324690F8F713424806F0CFF9414981F82D +:10CEB0003140BDE8FE8F2DE9F047DFF8FC80844665 +:10CEC0000B46D8F800003949002590F8FC73B0F9FA +:10CED000FA6391462C46B0F9F803B1F9001006E068 +:10CEE0003CF91120002A00DA5242824213DC491E2A +:10CEF000F6D2324831460278184600F049F8044626 +:10CF00002F4831460278484600F042F82044C4B227 +:10CF1000BC4200D90125D8F800002A4690F8FD133C +:10CF20002348401C06F091F9224981F83240D7E5A8 +:10CF300070B5214C05460E462068B0F90934B0F9A9 +:10CF400007241E4801782846FFF742FD0546206861 +:10CF5000B0F90934B0F90724194801783046FFF7D1 +:10CF600037FD40EA0502206890F80B14BDE87040D8 +:10CF70000F48801C06F069B906E000BF30F9123096 +:10CF80008B4201DD01207047521EF7D2002070470E +:10CF900010B50346002005E033F912408C4201DD54 +:10CFA000401CC0B2521EF7D210BD00009606100001 +:10CFB000C1051000905501200407100085061000DF +:10CFC000860610002DE9FF4F93B000200E90834697 +:10CFD000049005909C48894616460068B0F8C00247 +:10CFE0000D90897850680CF0FBFA0A9099F80210BD +:10CFF00030680CF0FDFA099099F8020047E000BF94 +:10D0000099F8004034E01398224600EBC800002154 +:10D01000D0E9005701200CF095F805400F403D4342 +:10D0200025D00A980D9930F91400009088421EDD31 +:10D030008548006890F8F70200070AD50998005D56 +:10D04000CF287BD028B196F84B10884201D0002021 +:10D050000090009904988B4404FB0100049005980B +:10D0600008FB010005900E98401C80B20E90641CD5 +:10D0700099F80100A042C6DA74490A98097800EBD1 +:10D0800041000A9009982830099008F1010099F8A8 +:10D09000031080464145B3DA6B48002504680598C3 +:10D0A000A18EC217A1FB003705FB007001FB020136 +:10D0B0004FF6FF77A3FB070C01FB07C103FB05112C +:10D0C00094F8313030345B1E8BFB03230CF04DF8A9 +:10D0D0007A108018B94641F100014A4600230CF04D +:10D0E00044F8804604986188C217A1FB003705FB0D +:10D0F000007001FB02024D46A3FB050702FB05720F +:10D10000002103FB012123785B1E8BFB03230CF022 +:10D110002CF86A10801841F100014A4600230CF0F7 +:10D1200024F8C6F81CB00E993185169948601699F6 +:10D13000C1F8008017B0BDE8F08FFFE700200F9026 +:10D14000451E089008EB0507F9B230680CF050FA5C +:10D150008246F9B270680CF043FA4FF0FF31631861 +:10D160001AF803208AB1CF2A0FD096F84B70974255 +:10D1700005D130F81370089A3A4492B2089230F808 +:10D1800013300F9A1A4492B20F92491C49B20129E6 +:10D19000E5DD6D1C6DB2012DD4DD089800283FF44B +:10D1A00058AF009948430F9990FBF1F050E710B544 +:10D1B0002549436800220968002B01DA426003E038 +:10D1C0004C8EA34200DD44600368002B01DA02604C +:10D1D00010BD898E8B42FBDD016010BD7CB514460D +:10D1E00000256B46FFF7EEFE19480178164829B175 +:10D1F000016891F80715090700D5042594F8461031 +:10D20000032902D0012907D00FE0006890F8070534 +:10D21000C0070AD0294605E0006890F807054007D6 +:10D2200003D50221684601F029FF6846FFF7BFFFDA +:10D230000198E0810098A08194F82400C00601D4F0 +:10D24000E06860617CBD00000407100086061000E5 +:10D25000440610002DE9F047054690F802800F467D +:10D2600088681446012641460CF0BAF98146A8F1B7 +:10D270000100C1B2B8680CF0B3F9297809EB41029A +:10D2800032F9022CA24203DB30F91110A14200DA7C +:10D290000026697809EB4102B2F90220A24203DBC1 +:10D2A00030F91100A04200DA002695F80380B86832 +:10D2B00041460CF095F9814608F10100C1B2B86809 +:10D2C0000CF08EF9297809EB410232F9022CA242C6 +:10D2D00003DB30F91110A14200DA0026697809EB6E +:10D2E0004102B2F90220A24203DB30F91100A04250 +:10D2F00000DA00263046BDE8F0872DE9FF4F97B0F1 +:10D3000099469246FE48DFF8FC83012204685146A4 +:10D31000D8F8000001F040FBFB480068B0F9B919EB +:10D32000119190F8B8090A90F8489AF802709AF8A2 +:10D33000036000789AF800B09AF80150401E8742C6 +:10D3400001DA7F1CFFB20EB1761EF6B2F049097801 +:10D35000491E8B4503DA0BF1010000F0FF0B0DB104 +:10D360006D1EEDB2B81EC1B2D9F808000CF038F944 +:10D370000B90781EC1B2D9F808000CF031F9049076 +:10D380003946D9F808000CF02BF90190781CC1B28D +:10D39000D9F808000CF024F90290B81CC1B2D9F8F1 +:10D3A00008000CF01DF90390394617980CF012F99B +:10D3B0000890D448394600680CF01AF986460020D7 +:10D3C0007AB2D44F0C90B7E04FFA8BF094E0002182 +:10D3D0000EF800100899189B095C994275D1DFF886 +:10D3E00028C3019BDCF800C033F91030BCF8BBC97E +:10D3F00063456ADA00211491139111991944049B31 +:10D4000009B233F9103010938B4206DD029B33F9D9 +:10D4100010308B4201DD01231393019B03EB40038A +:10D4200033F9028C884507DDB3F902C08C4503DD72 +:10D430004FF0010CCDF850C0012A0FDDDDF82CC0F3 +:10D440003CF910C08C4509DDDDF808C03CF910C07E +:10D450008C4503DD4FF0010CCDF84CC0DFF8ACC2B9 +:10D460009CF800C0ACF1020C62450DDADDF840C05A +:10D470008C4509DDDDF80CC03CF910C08C4503DD9E +:10D480004FF0010CCDF84CC001280BDD33F904CC72 +:10D490008C4507DDB3F902C08C4503DD4FF0010C6C +:10D4A000CDF850C0DFF868C29CF800C0ACF1020CA7 +:10D4B000604505DA884503DDB3F904308B4212DCA0 +:10D4C000149981B913990DE0FFE799B90199B7F95A +:10D4D000003031F9101099420CDA8B49096891F843 +:10D4E000AD19C90731B101210EF800100C99491C82 +:10D4F00089B20C91401C40B2A8427FF768AF8448C3 +:10D500000B990EF1280E007801EB40010B91049964 +:10D5100001EB40010491019901EB40010191029955 +:10D5200001EB40010291039901EB40000390089840 +:10D530002830521C52B20890B2427FF745AF0A9988 +:10D540000C9888422AD9002084F80E01DAF80000ED +:10D5500020606C4800231A462146006801F0C3FB96 +:10D56000012517E004EB85000646514600F07AF8E5 +:10D5700070B104EB4500B0F8B4100A98814207D9A5 +:10D580003046B7F900204946FFF764FE012806D06F +:10D590006D1CEDB294F80E01A842E3D200201BB03E +:10D5A000BDE8F08F2DE9F041574E0F4680463168B7 +:10D5B000144659481D469A69B1F8B53900789A421F +:10D5C00010DCEA8C042A0DD96278237891F8B71917 +:10D5D000D21A521C8A4205DCE278A378D21A521C75 +:10D5E0008A4202DD0020BDE8F0810028FBD14948D5 +:10D5F0002946B0F90020204600F048F80028F2D172 +:10D60000316891F8AC198907EDD52B462246394689 +:10D610004046BDE8F04170E62DE9F0471F00089E46 +:10D62000154681464FF000080CD42C7807E0F9B27B +:10D6300048460BF0DDFF00F80480641CE4B2687813 +:10D64000A042F4D2002E0CDBAC78474606E021461F +:10D6500048460BF0CDFF641C8755E4B2E878A04241 +:10D66000F5D248E602780B789A420BD942784B788B +:10D670009A4207D282788B789A4203D9C078C978C7 +:10D68000884201D300207047012070472DE9F84FF0 +:10D6900004461B48DFF86C8091468B4605680122E2 +:10D6A0002146D8F8000001F077F90027A6784FF05E +:10D6B000010A1DE03146D8F800000BF099FF0090F8 +:10D6C0003146DBF808000BF08BFF0146207852460C +:10D6D00009E000BF31F910C0CC4502DA009B0127F8 +:10D6E0001A54401CC0B263788342F3D2761CF6B25F +:10D6F000E078B042DED2012F3ED100200EE00000E3 +:10D70000FC051000E4051000040710008506100059 +:10D710008606100048061000C505100085F80E01A9 +:10D720002068286000231A462946D8F8000001F036 +:10D73000DAFA0126DFF848801AE000BF05EB860719 +:10D7400021463846FFF78EFF80B105EB4600B0F862 +:10D75000B410D8F8000090F8B809814206D93846CC +:10D760004A465946FFF776FD012806D0761CF6B2E8 +:10D7700095F80E01B042E1D20020BDE8F88F00001C +:10D780000407100070B5FE4C00EB4305049E00EB4F +:10D79000830386B18E69A660CE8C6680096861615C +:10D7A000B5F8B410A1801968E16090F80E012070FE +:10D7B0001068206170BDA6688E616688CE84666937 +:10D7C0000E60A188A5F8B410E1681960217880F88E +:10D7D0000E112069106070BD0146002091F82410E0 +:10D7E000099B1F9AC90610D4D9B2D2B2514301295C +:10D7F0000BD1E4498A78002A07D14978002904D15D +:10D80000E1490978002900D1012070472DE9F0474E +:10D810000F46994614469178089E0BF0DBFE0546AC +:10D82000A17870680BF0DCFE0646A178D7480BF0B3 +:10D83000DFFE0146A2781CE0207800230DE000BF47 +:10D8400015F800C0BC4506D136F91080C84501DB8B +:10D850000F5400E00B54401CC0B294F801C0844542 +:10D86000EED2CB48521C28310078D2B206EB4006EB +:10D870002835E0789042DFD2BDE8F0872DE9FF4FF0 +:10D8800083B00C461E469978129F109D0BF0B0FE97 +:10D890000090B17820460BF09DFE8346B178786801 +:10D8A0000BF09EFE81464FF0000ABA48CDF804A066 +:10D8B000C7F818A000682860B0784FE034783EE0E0 +:10D8C0001BF804000599884237D139F914101198D2 +:10D8D000814220DD0099059808552978204605F0F9 +:10D8E000ACFC28706978204605F0ABFC6870A9781C +:10D8F000404605F0A2FCA870E978404605F0A1FC7E +:10D90000E8700AF101001FFA80FA39F91400B969C8 +:10D910000844B86102E000990020085597F84600D5 +:10D9200003280AD19C4939F91400B1F90010884242 +:10D9300003DB0198401C80B20190641CE4B2707853 +:10D94000A042BDD20098924928300090097808F191 +:10D9500001000BF1280B09EB4109C0B2F1788046B8 +:10D960004145ABD2A7F826A00198A7F84E0007B012 +:10D97000BDE8F08F2DE9F043814693F84600874ECD +:10D98000ABB01C4615468846032832D1E08CA4F87B +:10D990004C002868E0633368B4F93210642293F8CD +:10D9A000BD0293F84B3A484390FBF2F007B27A4835 +:10D9B000642BB0F9000005D8594391FBF2F10BB28A +:10D9C000834200DA03462A46414648460094FFF760 +:10D9D0001DFFB4F93600B8420BDA03A8CDE9000701 +:10D9E00049462B46424602940846FFF747FF0398F4 +:10D9F00028606B4F387808B9787860B1306890F853 +:10DA00003002000707D523462A4641464846F7F725 +:10DA1000AAFE002854D063480178042029B139783F +:10DA200019B161490978012904D094F846100329F5 +:10DA300005D00CE03268E18C92F87A2203E032687B +:10DA4000E18C92F81F23914201D984F84600574B8C +:10DA50002A464146484600F06AFF002830D084F844 +:10DA60004B802868A06322462946504800F02AFED1 +:10DA70004F492046FEF7A0F858224E4914A80BF053 +:10DA8000DDFB50224C4968460BF0D8FB4A48083869 +:10DA9000D0E900232046FFF79FFE012803D1294645 +:10DAA000424800F0DDFE2946404800F0D9FE2246FB +:10DAB00029463E48FFF792FB2046FEF7D4F90120A5 +:10DAC0002BB0BDE8F0832DE9F0410D461F46164608 +:10DAD000044654210BF00EFC002084F84600374821 +:10DAE00000686060A06006EB450084F8485030F89C +:10DAF000B41F61850088E08406EB8500006820641F +:10DB00002F480088E0861E48816921600121A940D4 +:10DB1000394201D0406A2060BDE8F0812DE9F0472C +:10DB200089461C461646274D03F1440891780BF0B0 +:10DB300051FD0746B17860680BF052FD02460020A7 +:10DB4000A061B17845E0307814E000BF17F800C05C +:10DB5000CC450DD132F91030D4F818C0AB429C44FA +:10DB6000C4F818C004DD88F800001D4688F80110CC +:10DB7000401CC0B273788342E8D20548007823E0A5 +:10DB8000C80510004007100038051000D417012008 +:10DB900086061000CA9501002E061000040710002A +:10DBA000A851100024051000260510009045100013 +:10DBB0003C14012008241000B8231000A80610000F +:10DBC000360610000080FFFF491C02EB4002C9B27C +:10DBD0002837F0788842B6D2FE486586B0F9000052 +:10DBE000854202DD012084F8500045E62DE9FF4121 +:10DBF00017460AAA804692E83100F74A1E46B2F953 +:10DC00000020824202DB002004B085E703AACDE9B0 +:10DC1000002002943A464046FFF730FE0121286872 +:10DC2000B94008432860C4F80080E08C10B1039824 +:10DC30003060E8E70120E7E72DE9FF4F81B090462B +:10DC40000E9C8B4604EB880094F80E71DDF840A022 +:10DC500000681E46206001232146584601F043F823 +:10DC6000019858451FD0B5781AE0294601980BF065 +:10DC7000BFFC8146294658460BF0BAFC0146307875 +:10DC800009E000BF19F80030434502D10B5C09F8E8 +:10DC90000030401CC0B272788242F3D26D1CEDB2EB +:10DCA000F078A842E1D294F80E0100250121B84293 +:10DCB00012D0119878B17F1CF8B208E0DAF8002091 +:10DCC00001FA00F31A43401CC0B2CAF8002094F8CD +:10DCD0000E218242F2D2012500914346524620464F +:10DCE0000F99FFF74FFD284605B041E610B5BB4A36 +:10DCF000BB4C1368647893F81E2354B191F8241038 +:10DD000011F0090F02D093F8211301E093F82013CA +:10DD10000A44B449097809B193F86F22904201D9B5 +:10DD2000012010BD002010BD2DE9F0411C46154614 +:10DD30000E46074601F032FAA848E28C016891F8D5 +:10DD40002803824244D8032084F8460091F8F60262 +:10DD50000022830701D4400700D50122DFF880C2EA +:10DD6000B1F82203B1F826339CF801C0BCF1000FD2 +:10DD700008D0DFF874C29CF806C0BCF1000F01D1D6 +:10DD8000B1F8240399490978012903D1984201D9AE +:10DD9000C01A80B2A18D814203D29548007800B9A3 +:10DDA0000022608D03280CD3A08C10F4C07F08D112 +:10DDB0003AB123462A4631463846BDE8F04102F0E2 +:10DDC000B0B823462A4631463846BDE8F041D1E591 +:10DDD000042084F84600F4E78348C07858B17F48AF +:10DDE000844A0068126890F85713914207D290F85D +:10DDF0004003800703D58049002008707047012048 +:10DE0000704791F82410754ACB077C49126809784D +:10DE100006D011B192F8481305E092F8491302E0D8 +:10DE200059B192F846136E4B5B7813B192F84A23BE +:10DE30001144884204D90120704792F84713F2E751 +:10DE4000002070472DE9FF4F834687B066480027C2 +:10DE50000C46DDF850A001790126154606FA0AF6AF +:10DE6000B946E9B366486749B0F90000B1F9001056 +:10DE7000884237DA2968314234D1E18C042931D91A +:10DE80008DE83100DFF8808152460A9BD8F81810DF +:10DE9000D8F82400FFF7AAFE070023D12346206804 +:10DEA00051460A9AFFF77EFB58490870C0B1781EA8 +:10DEB0008DF810008DF814004848006890F8AD09FE +:10DEC000800709D552480078042805D105AA04A97D +:10DED0000A98F6F710FF50B1A08C40F0800000E0E7 +:10DEE00000E0A084A08C10F4C07F20D02AE0494933 +:10DEF0009DF9103001F8363F9DF9140048700090EC +:10DF0000206859460A9AFFF787FB01A8CDF800B0B0 +:10DF100080E830025246216804F14003D8F8180026 +:10DF2000FFF78AFE0028DDD001200BB020E528682D +:10DF3000304207D053462A4621465846CDF8009035 +:10DF4000FFF720FC3846F0E72DE9F04FDFF8B4A0EA +:10DF50003149E9B0BAF90000B1F900102F4ACDE912 +:10DF6000631011802E494FF00008C34608802648F0 +:10DF7000C146474601211C3002F0B6FC224801216F +:10DF8000243002F0B1FC20480221203002F0ACFC29 +:10DF90000221244802F05EFC0421234802F05AFCCE +:10DFA000194C4FF466752946E0690BF081F9294652 +:10DFB000606A0BF07DF91D48B0F900004100206A4D +:10DFC0000BF076F929461A480BF072F929461948E0 +:10DFD00032E000002806100036061000040710008A +:10DFE0004007100042051000A8511000B8061000AC +:10DFF000440610001C0610008F0610009106100049 +:10E00000480610002E061000C8051000C5051000B7 +:10E01000E804100090550120300610003E06100064 +:10E020003C061000F0051000FC05100096061000DC +:10E030003C140120D41701200BF03AF9A821FE4826 +:10E040000BF058F900266670F7F730FBF6F7ECFD99 +:10E05000FA488DF87E61012300681C9000221CA9FB +:10E06000A06900F040FEF64805960025B0F90010C2 +:10E07000BAF9000005F0E1F80FFA80FA9DF87E0188 +:10E08000012801D9EF48067017A8012461904CE1DE +:10E09000002001901CA800EB840060901CAA21467F +:10E0A00007A8059BFFF70FFD07AB2146609A07986D +:10E0B000FFF734FD01200090234605AA07A91CA8FC +:10E0C000FFF760FB18A800F0A5FB78B1BDF8400091 +:10E0D00040F00100ADF8400007A800F034FD28B181 +:10E0E000D948DA4900880880D9490880D948007899 +:10E0F00038B1BDF8400010F0060F02D1D6480068D4 +:10E100000890609800F098FB28B1BDF8400040F0FE +:10E110000800ADF84000BDF94E10514575DD009482 +:10E1200005AA07A91CA8609BFFF78CFE00287DD1DB +:10E130000120A04005990390084241D1BDF840005C +:10E1400010F4C07F3CD1C24805AA07A9B0F900006D +:10E150008DE80700C1482246609B8169406AFFF74D +:10E1600045FD0190BA4803990088ADF85200059A20 +:10E17000114223D0BA49BDF84220096891F82833EA +:10E180009A4205D891F8F6128A0717D4490715D490 +:10E19000012305AA07A91CA88DE80F00AF48224655 +:10E1A000619B416A8069FFF747FD01900120009063 +:10E1B000234605AA07A91CA8FFF7E4FA0198E8B9C5 +:10E1C000BDF8420007A9FFF791FDB8B19DF86C00BA +:10E1D00058B907A80090A3482146619AB0F90030C9 +:10E1E0009E48806900F0A7FA074607AB2146609A6F +:10E1F0000798FFF799FD4FF0010880E0234605AA34 +:10E2000007A91CA80096FFF7BDFA9649BDF94E0074 +:10E21000B1F90010884272DDFFF7DEFD00286ED0F4 +:10E220009DF86C0000286AD1012000E07BE0A0404E +:10E2300005990390084232D18A4805AA07A9B0F986 +:10E2400000008DE8070085482246609B8169406A8E +:10E25000FFF7CCFC019083480088ADF8520080485D +:10E26000006890F84003C00619D4059A039810423C +:10E2700015D0012305AA07A91CA88DE80F0077482F +:10E280002246619B416A8069FFF7D6FC019001201C +:10E290000090234605AA07A91CA8FFF773FA019866 +:10E2A00030BBBDF8420007A9FFF7ABFD00B30798EC +:10E2B0000090DDF8809107A8019001208DF86200A0 +:10E2C000DDE900034A46214600F068FF64484A46FB +:10E2D0002146006890F84003C006DDE9000302D53E +:10E2E00001F01FFE01E0FFF745FB4FF0010906E0DA +:10E2F000234605AA07A91CA80096FFF743FA0120A8 +:10E300000599A0400143514A0591639911805049F4 +:10E31000649A0A804B490A782AB105439DF87E0128 +:10E32000012800D90E70641CE4B29DF87E01A04261 +:10E33000BFF4AEAEC1B24C4841714C49A0F81D507B +:10E340004D4881F800B04A4981F80080494981F878 +:10E3500000900770FDF705FE9DF87E214749904229 +:10E3600002D90120087000E00E700221444802F03A +:10E3700089FA0421434802F085FA3848012118300F +:10E3800002F015FB354801211C3002F010FB334828 +:10E390000121243002F00BFB30480221203002F032 +:10E3A00006FB69B0BDE8F08F2DE9F04F00262B4841 +:10E3B000E5B0B146B046264F01211C3002F094FA78 +:10E3C00026480121243002F08FFA2448022120300F +:10E3D00002F08AFA02212A4802F03CFA0421294874 +:10E3E00002F038FA1D4C4FF466752946E0690AF0D0 +:10E3F0005FFF2946606A0AF05BFF2348B0F900001E +:10E400004100206A0AF054FF294620480AF050FFD4 +:10E4100029461F480AF04CFFA82107480AF06AFF66 +:10E420004FF0000A054884F801A08DF87EA15546FA +:10E430000068012352462DE090451000240610008C +:10E440004C061000C50510004206100030061000F2 +:10E450002E06100044061000AC061000C80510007F +:10E460000407100032061000905501208D061000A0 +:10E470008E0610008F06100090061000B8061000DF +:10E48000F0051000FC051000960610003C14012059 +:10E49000D41701201C901CA9A06900F024FCCC48D2 +:10E4A00060950025B0F90010B7F9000004F0C5FE32 +:10E4B00007B29DF87E01012802D9C64880F800A065 +:10E4C0000124A346A7E01CA800EB840005901CAA29 +:10E4D000214607A8609BFFF7F6FA07AB2146059A8D +:10E4E0000798FFF71BFB234660AA07A91CA8CDF8D5 +:10E4F00000B0FFF747F918A800F08CF928B1BDF873 +:10E50000400040F00100ADF84000059800F094F99B +:10E5100028B1BDF8400040F00800ADF84000BDF95A +:10E520004E00B84266DD009460AA07A91CA8059BAE +:10E53000FFF788FC00286CD10BFA04F06099039077 +:10E54000084241D1BDF8400010F4C07F3CD1A24840 +:10E5500060AA07A9B0F900008DE807009F4822468D +:10E56000059B8169406AFFF741FB01909A48609AD8 +:10E570000088ADF852000398104223D09848BDF8A7 +:10E580004220006890F828339A4205D890F8F602A5 +:10E59000820717D4400715D407AA1CABCDE9003277 +:10E5A00060A98E48CDE9021B416A17AB22468069FB +:10E5B000FFF742FBCDE900B0234660AA07A91CA8DB +:10E5C000FFF7E0F8019868B9BDF8420007A9FFF726 +:10E5D0008DFB38B107AB2146059A0798FFF7A4FBDE +:10E5E000012607E0234660AA07A91CA8CDF800A0D1 +:10E5F000FFF7C8F860990BFA04F001436091754980 +:10E600000A7832B105439DF87E01012801D981F8CD +:10E6100000A0641CE4B29DF87E01A042BFF453AF99 +:10E62000C1B270484171A0F81D506F48704980F820 +:10E6300000906E48067081F8008002216D4802F05B +:10E6400021F904216C4802F01DF9644801211830B9 +:10E6500002F0ADF9614801211C3002F0A8F95F48D1 +:10E660000121243002F0A3F95C480221203002F09D +:10E670009EF965B096E65C49002008705B49087019 +:10E680005B490870534908705C4908707047F2E7AD +:10E6900052490020574A08628861C8611060564A92 +:10E6A0001060514A1070514A1070514A1070494A16 +:10E6B000107048707047494900204870A8215048A0 +:10E6C0000AF018BE2DE9F74F44480D4641780F294E +:10E6D00001D2491C417001F0FF094A4982F8479074 +:10E6E00001EB890029680160A97847480AF080FF9A +:10E6F0008246A87819E000982C7800EBC80B0DE052 +:10E70000DBE900672246012000210AF01BFD0640DC +:10E710000F403E4301D00AF80490641C6878A04280 +:10E72000EEDA0AF1280A08F10100E978804641454D +:10E73000E1DABDE8FE8F2DE9FF5F8B461446917844 +:10E740000E9D0AF047FF0646A17868680AF048FF68 +:10E7500007464FF00009FFF73FFB30B12B49B5F9F1 +:10E760003200B1F90010884203DD002004B0BDE89A +:10E77000F09F2748A178E37890F800A019E020786E +:10E7800062780FE016F80080D84509D137F910807B +:10E79000DDF80CC0E04503DD09F1010C1FFA8CF92E +:10E7A000401CC0B28242EDD2491C07EB4A07C9B2F5 +:10E7B00028368B42E3D229464846FFF722FB002841 +:10E7C000D4D0A88C40F40070A8840120CEE70000CB +:10E7D0004C061000C50510002E061000C8051000DC +:10E7E00004071000905501208D0610008E061000C1 +:10E7F0008F061000F0051000FC051000B806100090 +:10E80000904510006C1B01203C14012028061000CC +:10E8100086061000017859B18B4A1278521E914237 +:10E8200006D0407820B189490978491E884201D133 +:10E830000120704700207047017829B18249427851 +:10E840000978491E8A4209D1817829B1C1787F4867 +:10E850000078401E814201D101207047002070479E +:10E86000F0B57B4D002205EBC2060023C6E900335C +:10E87000521CD2B2172AF6D38A782CE000EBC203DE +:10E88000D3E9007657EA060323D074084FEA37032A +:10E8900017EB070E46EB060C44EA0C04344343EA3C +:10E8A0000E0305EBC2063B43D6E9007C1F434CEA4E +:10E8B000040CC6E9007CD6E9027C1F434CEA040C38 +:10E8C000C6E9027CD6E9047C1F434CEA040CC6E985 +:10E8D000047C521CD2B2CB789342CFD200225B4B45 +:10E8E0000AE000BF05EBC20400EBC207D4E90264F2 +:10E8F000C7E90064521CD2B21C78A242F2D3087855 +:10E9000008B1401E0870504A48781278521E904252 +:10E9100001DA401C4870887808B1401E88701A7867 +:10E92000C878521E904201DA401CC870F0BD2DE933 +:10E93000FF5F9478164604EB84028B4600EBC2001E +:10E94000002100F1290820E0002081468246357828 +:10E9500077780FE018F805205A4509D12A4601209A +:10E9600000210AF0EFFB41EA0A0A40EA0909012105 +:10E970006D1CEDB2AF42EDD2039B08F1280803EB0A +:10E98000C403641CC3E9009AE4B2F078A042DBD26D +:10E9900004B00846BDE8F09F70B50C788B784D78D0 +:10E9A000C9789AB10CB1641EE4B2274A1278521E9B +:10E9B000954201DA6D1CEDB20BB15B1EDBB2234A4E +:10E9C0001278521E914201DA491CC9B203EB83024C +:10E9D00000EBC2020026293209E0204602E016546C +:10E9E000401CC0B2A842FAD95B1CDBB228328B4271 +:10E9F000F3D970BD2DE9F0439C7893F803C004EB84 +:10EA0000840500EBC505104890F8009004FB09F060 +:10EA100001EB40060020293512E019785F7808E004 +:10EA200015F80180904502D136F911804044491C07 +:10EA3000C9B28F42F4D2641C06EB4906E4B2283511 +:10EA4000A445EAD2BDE8F0838606100085061000D2 +:10EA5000384610002DE9F04780464A488C780D462C +:10EA60000078801E012C05D9E978814202DA002065 +:10EA7000BDE8F087022C01D2022701E0EF78C4B292 +:10EA80004FF000092146D8F808000AF0A9FD064613 +:10EA90002146D8F804000AF0A3FD01463A4802785E +:10EAA00015E028786B780AE036F910C031F910804B +:10EAB000C44502D04FF0010903E0401CC0B28342BC +:10EAC000F2D2641C06EB420601EB4201E4B2BC4206 +:10EAD000E7D94846CCE72DE9F04780462A480C465E +:10EAE0004E780178891E8E4201DA0020C0E7814607 +:10EAF000CFB24FF0000AA178D8F808000AF070FDF4 +:10EB00000546A178D8F804000AF06AFDA178E378F8 +:10EB100099F8002013E03C460AE000BF35F914C024 +:10EB200030F91480C44502D04FF0010A02E0641CA1 +:10EB3000B442F3D905EB420500EB4200491C8B427D +:10EB4000E9D2504694E70F4A00211278521ED3B200 +:10EB500090F845200AB19A4204D1818C41F002011B +:10EB600081840121084A90F844301278521ED2B2B2 +:10EB7000934204D1818C41F0040181840121084633 +:10EB80007047000085061000860610002DE9F05F32 +:10EB900007460025DFF85CB42DE000BFDBF8081065 +:10EBA0004E5DDBF8041001EB450A1AE00AEB0600A3 +:10EBB000804610F8011C10F8029C084600F00FFA7D +:10EBC0000446484600F00BFA844202D20146204631 +:10EBD0000C46DBF80410761EF6B201F8104008F877 +:10EBE000024C012EE2D804D1284600F0F8F98AF848 +:10EBF00000006D1CEDB2BD42D0D300221146DBF8FF +:10EC000004000DE000EB41031C788C4203D11A7024 +:10EC1000521CD2B202E010F814401C70491CC9B258 +:10EC2000B942EFD300221346114608E010F8114014 +:10EC30009C4202D0521CD2B22346491CC9B2B942EE +:10EC4000F4D3521CD0B2BDE8F09F30B5B0B18842C9 +:10EC500014D002D20A4601461046E64A536803EB36 +:10EC600040031C788C4209D05C788C4206D09568B1 +:10EC70002A5C022A02D2541C2C549954084630BDF6 +:10EC8000F0B503EB8204A57805EB850600EBC6061C +:10EC9000E0782836A8420FD3207807E0371897F895 +:10ECA00001C0944500D17970401CC0B2677887429A +:10ECB000F4D26D1CEDB2EBE703EB81002568056033 +:10ECC00003EB420003EB410130F8B42FA1F8B4206C +:10ECD000C949096821600021018093F80E01401E96 +:10ECE00083F80E01F0BD2DE9FF4F884608460978EC +:10ECF00087B0FF2915D0C14A8A46417812789142DF +:10ED000001D2491C00E01146CDB2BD4990F80290F5 +:10ED1000C0780978884201D2401C00E00846C6B29B +:10ED200004E04FF0000A5546D146564609984FF088 +:10ED3000000B08B198F80EB1AE4C206800F15A01F2 +:10ED4000C4E901015A210AF0B3FAD4E901122C20D6 +:10ED5000002301F810001354401EC0B2F8D20BF18A +:10ED600001000390C0B20090079809EB890100EB05 +:10ED7000C10709F10100029743E000BF0AF1010059 +:10ED80000197C4B2283738E03919086830B3385DC4 +:10ED900030B3CF282FD011F8011C002011B1CF299A +:10EDA00000D008460199095D19B1CF2901D0FFF7BC +:10EDB0004CFF0A9981B101992144059111F8011C78 +:10EDC00019B1CF2901D0FFF740FF0599497819B152 +:10EDD000CF2901D0FFF739FF18B10BE0E41CE4B2F2 +:10EDE00009E000982D2803D2411CC9B2009101E02E +:10EDF000401EC0B23855641CE4B2AC42C4D9049879 +:10EE0000401CC0B20490B042B8D90098FFF7BEFED3 +:10EE1000009003980022C0B2774B09E008EB800114 +:10EE20001C680C6008EB4001401CA1F8B420C0B283 +:10EE300000998842F2D302984F46283001903BE077 +:10EE4000544632E0204401210958E9B3417851B3D6 +:10EE5000CF2928D0674A526812F81110417008EB88 +:10EE6000410008EB810930F8B42F521C028099F858 +:10EE70000010204604F0E1F989F8000099F801102B +:10EE8000204604F0DEF989F8010099F802103846AE +:10EE900004F0D3F989F8020099F80310384604F019 +:10EEA000D0F989F80300641CE4B20198AC42C9D3DC +:10EEB00028307F1CFFB20190B742C1D30098401E9A +:10EEC000C2B288F80E2100E00DE0099800280DD0AC +:10EED000A2EB0B00012809D1099907980BB0434612 +:10EEE000BDE8F04FCCE6E41CE4B2DCE70BB0BDE8D3 +:10EEF000F08F2DE9FF4FAFB01C46012080463C98B3 +:10EF000090F80E11414544DBB82168460AF0F2F949 +:10EF10003C996B4601EB880008F0FF0100682E90D9 +:10EF20002EAA3098FFF703FD80B32EA96846FFF79D +:10EF300097FC9DF8BA1031980AF05AFB82469DF86A +:10EF4000BA001EE068469DF8B85000EBC90B10E00F +:10EF5000DBE900672A46012000210AF0F3F80640A9 +:10EF60000F403E4304D01AF80500401C0AF8050083 +:10EF70006D1C9DF8B900A842EADA0AF1280A09F1E5 +:10EF800001009DF8BB1081464945DBDA08F101001C +:10EF9000B4E7A17830980AF02BFB0546A1782F98AA +:10EFA0000AF026FB0646A17831980AF021FBA278E8 +:10EFB000CF230FE0217806E0475C022F02D36F5C7D +:10EFC00007B97354491C67788F42F5DA2830521C10 +:10EFD00028352836E1789142ECDA33B087E7054AE4 +:10EFE000D2E9011202E000BF11F81000135C002BFF +:10EFF000FAD17047F0051000CA950100860610008E +:10F0000085061000F0B5B2F900400668B44202DD92 +:10F01000B3F9001030E002EB410434F9025CB54270 +:10F0200004DA03EB410131F9021C25E000252C46EE +:10F030004F1E0CE032F914C0B44507DC02EB440C5F +:10F04000BCF902C0B44501DB25460C46641CBC4239 +:10F05000F0DB32F9154003EB450133F91530B1F916 +:10F06000021002EB4502361BC91AB2F902207143A5 +:10F07000121B91FBF2F119440160F0BD2DE9F04142 +:10F0800005463748036893F80705C40603F20F5096 +:10F0900021D5B3F8FA696C68B4421CDBB3F8FC699B +:10F0A000B44218DCB3F8FE692C68B44213DBB3F841 +:10F0B000006AB4420FDC074693F8040A93F8021A78 +:10F0C00093F8052A07EB400093F8034A00EB41064A +:10F0D00007EB420E10E039B302292CD0032935D0BA +:10F0E00004293AD193F8081593F8094593F80E3599 +:10F0F00000EB410600EB430E0A4422440EEB4107AD +:10F10000A02A2ADC012906DD05F1040C034672461B +:10F110006046FFF777FF012C1FDD284633463A464D +:10F120002146BDE8F0416DE793F8081593F80945CD +:10F1300093F80A2505E093F8081593F8094593F824 +:10F140000C2500EB410600EB420ED5E793F80815BD +:10F1500093F8094593F80D25F3E7BDE8F081000029 +:10F160000407100030B542780378CD8CD21AC378EA +:10F170008078521C1B1A5B1C05FB02F0D4185D43FF +:10F1800040006A00B0FBF4F0B2FBF4F2904202D906 +:10F19000C8850A8630BDCA85088630BD2DE9FF4F77 +:10F1A000002783B01546019700973E463C46BB4674 +:10F1B00091780AF00FFA8246AB7895F8039028E030 +:10F1C000297895F801C08E461DE000BF1AF801208D +:10F1D0000498824215D1A1EB0E02521CDDF800808A +:10F1E000A9EB030002FB0288401CCDF80080DDF88B +:10F1F0000480164402FB008200FB00BB04447F1C19 +:10F200000192491CC9B28C45E0D25B1C0AF1280A64 +:10F21000DBB29945D4D24FF47A70704390FBF7F18A +:10F220004FF47A70604390FBF7F34FF47A7201FB6E +:10F2300004F0714390FBF2F791FBF2F6634393FB0A +:10F24000F2F301980099C01B891BABEB0302069CEB +:10F250008B1A00D55B42002800DA404203EB4000E5 +:10F2600011440A18081A521040104FF47A7148439A +:10F2700090FBF2F0C0F57A70A085069907B0284699 +:10F28000BDE8F04F6EE700002DE9F84F9846DDE944 +:10F290000B7A16460B468146FE4AFF48DDF828B039 +:10F2A00012688079B2F9FC5208B1B2F96253FB4896 +:10F2B000007808B1B2F90A53594618460AF08AF99B +:10F2C0000446594648460AF093F981465946DAF809 +:10F2D00008000AF085F9024698F8000098F8011035 +:10F2E0004FF0010A48B92078B04205D1B2F90000C8 +:10F2F000B84201DD89F800A00120E94B93F800C075 +:10F30000ACF1010C614548D114F801C0B44505D1F8 +:10F3100032F911C0BC4501DD09F801A0491EC9B28E +:10F320003BE000BF14F800C0B44535D132F910C03D +:10F33000BC4531DDAC4402EB400B0FFA8CF83BF9D5 +:10F3400002CC4FF0000ECDF800C0C44505DDBBF97E +:10F3500002C0C44501DD4FF0010E012809D93BF977 +:10F3600004CCC44505DDBBF902C0C44501DD4FF046 +:10F37000010E93F800C0ACF1020C604507D2DDF835 +:10F3800000C0C44503DDBBF904C0C44504DCBEF1C4 +:10F39000000F01D109F800A0401C8842C2D9BDE885 +:10F3A000F88F2DE9FF4FBD489BB01D460178B94845 +:10F3B000289F006831B190F80943B0F90AA3B0F969 +:10F3C0000C0325E0B449897931B190F86843B0F96C +:10F3D00062A3B0F964031BE0B24990F8FB42B0F9B4 +:10F3E000FCA20978B0F9FE92012912D190F811130C +:10F3F0000C4490F81213514503DAAAEB01010FFAFD +:10F4000081FA90F81303484503DAA9EB000000B233 +:10F410008146ECB3DDE91C01119108A90F910AA9FD +:10F420000E91A9780AF0D6F80690A978B8680AF083 +:10F43000D7F886469A4847F6FF73AE7895F803B03A +:10F440000078DA430C901AE0297895F801C00DE0B5 +:10F4500010F801801198804507D13EF911009842BB +:10F4600000DA0346904200DD0246491C06988C45AE +:10F47000EED228300C9906900EEB410E761CB34567 +:10F48000E2D20F9803800E980280BDF9280000E0B8 +:10F490000FE0BDF92010401A6043642190FBF1F0A9 +:10F4A00081490988084400B2AC78EE78804624B1DE +:10F4B0000EE07D48B0F90000F6E7CDE900480DF117 +:10F4C0006C0B02979BE807002B46FFF7DDFE01243B +:10F4D00076480078401E86420BD1CDE900680DF1D8 +:10F4E0006C0B02979BE807002B46FFF7CDFE761EBC +:10F4F000F6B2601EC1B2B8680AF072F88346012CF9 +:10F5000006D9A01EC1B2B8680AF06AF8079001E0F7 +:10F51000CDF81CB02146B8680AF062F80D90601C66 +:10F52000C1B2B8680AF05CF80290A01CC1B2B86819 +:10F530000AF056F8069021461C980AF04BF80E90F7 +:10F5400021461B980AF054F88646002015900120A9 +:10F5500014900020139050480079C0B14D480068C5 +:10F5600090F8AC19090712D56A782978521A90F8E0 +:10F57000B719521C8A420ADCEB78AA789A1A521CF4 +:10F580008A4204DCB0F8B509B969814201DD002086 +:10F590001490E9E02878CBE00E990A5C1D998A4224 +:10F5A00076D100211291179116910D993BF910C057 +:10F5B00031F9102002EB0A0109B202EB09031BB278 +:10F5C0008C4507DD029F37F910708F4202DD01275D +:10F5D00012971697E8B3324F3F780C977F1EB842C8 +:10F5E0007DD00D9F07EB4007189737F9027C1097E5 +:10F5F0008F4207DD189FB7F902708F4202DD0127A5 +:10F60000129717970BEB40071A9737F9027C9F4226 +:10F6100008DD029F07EB4007B7F902709F4201DD4A +:10F62000012712971A9FB7F902709F4206DD029FC9 +:10F6300007EB400737F9027C9F4258DC129B43BB23 +:10F64000012C0ED9079B33F910308B4209DD029B48 +:10F6500000E044E033F910308B4202DD01231293C5 +:10F660001693124B1B789B1E9C4209D28C4507DDDA +:10F67000069B33F910308B4202DD0123129316935F +:10F6800001281DD9189B33F9043C8B4218DD0FE08B +:10F690004DE02CE004071000A851100042051000B6 +:10F6A00086061000B80610002E0610008506100011 +:10F6B000189BB3F902308B4202DD0123129317939A +:10F6C0000C9B9B1E98420AD2109B8B4207DD189B15 +:10F6D000B3F904308B4202DD0121179107E0129942 +:10F6E00029B9424503DD01210EF800101FE0F94958 +:10F6F0000B6893F8F7321B0704D5424502DDCF2390 +:10F700000EF80030179A92B1169A82B1149A72B11B +:10F7100001220EF80020139A521C92B2139209682B +:10F7200091F8B82913998A4201D201211591401C00 +:10F7300069788142BFF430AFE748CDF81CB00D992D +:10F7400000780EF1280E01EB40010D9102990BEBB0 +:10F75000400B01EB40010291069901EB400006903D +:10F760000E982830641C0E90B4427FF613AF1598A3 +:10F770001FB0BDE8F08F2DE9F0470446914260D0FC +:10F7800007D901EB0200A0EB0201CAB2A0EB020014 +:10F79000C1B2C1EBC10000EB400004EB8001C2EB41 +:10F7A000C20000EB400004EB8000B1F93250B0F928 +:10F7B000323081469D4200DA4B86CB8CC58C2B447F +:10F7C000CB840B8D058D2B440B854B8D458D2B44A8 +:10F7D0004B858B6985692B448B61C769CE69CB6882 +:10F7E000D9F80C004FEA234C4FEA20480CFB06FCEA +:10F7F000F51907FB08CC9CFBF5FC6CF31F430FFAD3 +:10F8000083FC0CFB06FC00B207FB00C090FBF5F08C +:10F8100060F30F03CD61CB6094F8EC04411E91427C +:10F820000AD0C0EBC00000EB400004EB800148466A +:10F830005422543909F002FD94F8EC04401E84F877 +:10F84000EC04BDE8F0872DE9FE4F0746A1488A4643 +:10F8500000250068B0F8001301FB01F99F49897980 +:10F8600019B1B0F8660300FB00F954464FF0010BE4 +:10F87000A3E000BF0BFA04F0264600906BE0009A6C +:10F880000BFA06F05946104264D0C6EBC60000EBF6 +:10F89000400007EB8000C26820464EE0B0424BD0EB +:10F8A000C0EBC00303EB430307EB8303DB684FEAC2 +:10F8B000234CACEB224C9B1A0FFA8CFC1BB26CF362 +:10F8C0001F4563F30F059E46824BCDF804C01B68AD +:10F8D00093F8F6C2CDF808C05FEA8C6C0AD593F8AD +:10F8E00003830EFB08FC4FF064089CFBF8FCF44417 +:10F8F0006CF30F05DDF808C05FEACC6C0CD593F80B +:10F900000333DDF804C00CFB03FC64239CFBF3FC15 +:10F91000019B634463F31F454FEA254C0CFB0CFC31 +:10F920002BB203FB03C34B4506D2DDF800C001FA3E +:10F9300000F343EA0C030093401C97F8EC34834235 +:10F94000ACD80421684608F0C7F9012802D1009814 +:10F9500040000090761C97F8EC04B0428FD8042148 +:10F96000684608F0B9F901280BD00421684608F070 +:10F97000B3F997F8EC64A6EB0A01884206D187F840 +:10F98000ECA4BDE8FE8F641CE4B201E0009A584686 +:10F9900000FA04F11142F6D0D84609E0009908FABD +:10F9A00006F0084204D0F2B221463846FFF7E3FEE3 +:10F9B000761EA642F2D8641CE4B297F8EC04A0428A +:10F9C0003FF658AFDDE72DE9F04F424C012B24689C +:10F9D00094F80F7394F80E6305D00B784C78404D73 +:10F9E0009C46690C0CE08B78CC78F8E730F91C80E9 +:10F9F000A84500DD4546884500DA41460CF1010C7A +:10FA0000A445F3D9B54200DA3546B14200DA3146B1 +:10FA1000691A7943642591FBF5F131440EB230F94E +:10FA200013500121B54205DD156801FA03FC45EAD2 +:10FA30000C05156030F91450B54205DD156801FA62 +:10FA400004FC45EA0C051560E51A05F0FF09B9F15B +:10FA5000010F37D95D1CEDB230F9158008EB070CAA +:10FA60000FFA8CFCB04511DD00EB450A3AF9028C27 +:10FA7000E04503DDBAF90280E04507DCD2F800C0BA +:10FA800001FA05F54CEA050CC2F800C0651EEDB29E +:10FA900030F9158008EB070C0FFA8CFCB04511DD2E +:10FAA00000EB450A3AF9028CE04503DDBAF9028021 +:10FAB000E04507DCD2F800C001FA05F54CEA050C78 +:10FAC000C2F800C0B9F1020F36D99D1CA4F1020999 +:10FAD00030E000000407100086061000A851100056 +:10FAE0000080FFFF30F915C0B44522DD00EB450B67 +:10FAF000BC443BF902EC0FFA8CFAD64503DDBBF9A6 +:10FB00000280D04515DC3BF9048CD04503DDBBF900 +:10FB10000280D0450DDCD64503DDBBF90480D0451D +:10FB200007DCD2F800C001FA05F84CEA080CC2F86C +:10FB300000C06D1C4D45D5D9002528460CE000BFFE +:10FB4000166801FA03F73E4204D025B90125401C8E +:10FB5000C0B200E000255B1CA342F1D909E62DE903 +:10FB6000FF4FFB488FB0DFF8EC9304684FF0FF3095 +:10FB70000C90002017460A900B901D4604F5887BD8 +:10FB8000012239464E46D9F80000FEF705FF0095E0 +:10FB9000DDE90F123B463068FFF703FC060006D094 +:10FBA000ED4901200870A88C40F08000A884EB4843 +:10FBB000007880B17EB995F8240010F0060F0AD1C4 +:10FBC00039462846FEF746FF060004D13946284646 +:10FBD000FEF781FF0646E248007800B10126DFF813 +:10FBE00084A3DAF8000090F8F70240073DD501231E +:10FBF0000AAA3946DC48FFF7E6FE804600230BAA36 +:10FC00003946DA48FFF7DFFE08FB00F001282CD167 +:10FC1000DAF80000B5F93210B0F8F402814224DAC3 +:10FC2000B8781EE008F0FF010F9809F0E1FC04909D +:10FC300008F0FF01D9F8000009F0DAFC0146387835 +:10FC4000012209E0049BDDF840C01B5C634502D142 +:10FC50000B5C03B90A54401C7B788342F2DA08F14A +:10FC60000100F97880464145DCDA002084F80E0175 +:10FC700038682060B7483346002221460068FFF705 +:10FC800032F894F80E014FF00008012870D9B548F9 +:10FC9000006890F8F70200070CD54FF46671B4487D +:10FCA00009F028FBAB4800943B460168B04A08467F +:10FCB000FFF71FF9FCF755F90090FCF750F9824661 +:10FCC0003A68DDE90F010792AA4B07AAFEF72FFE5B +:10FCD00060B107A9A748FEF7C3FD2A4607A9A548B2 +:10FCE000FDF77CFAE9686961E96929629C48007856 +:10FCF000E8B39C48006890F8F702800747D594F86D +:10FD00000E01012843D94FF00009012610E000BF81 +:10FD1000904804EB8603F2B2A9680068FEF76AFE19 +:10FD200093493C39484541F8260000DD8146761C60 +:10FD300094F80E11B142EBD2B9F1000F20DD894ADF +:10FD400001208B4B86463C3B126817E053F820603D +:10FD50004FF0640C06FB0CF696FBF9F692F808C31C +:10FD6000B4450ADD0EFA00F6DDF830C001E00EE021 +:10FD7000C4E02CEA060CCDF830C0401C8142E5D22C +:10FD800094F80E01012802D9002084F80E017A4867 +:10FD90007B4A0126B0F9001078480591DFF8C4913C +:10FDA000B0F9000008901180764908806EE0542276 +:10FDB0002946584609F042FAD9F8001004EB4600EB +:10FDC000B0F8B43091F8022393425ED901220C9B23 +:10FDD000B2401A4259D0BBF8242042F01003ABF8CD +:10FDE0002430B0F8B420ABF8262091F8F7020007D1 +:10FDF00003D558480168CBF8001004EB8600099041 +:10FE000059460790FFF7AEF95248F1B25B46079AA0 +:10FE10000068FDF783FE9BF8440060B15A490978F9 +:10FE2000491E884207D09BF8450020B15749097800 +:10FE3000491E88420FD1BBF8240040F0010158460A +:10FE4000ABF82410FEF77FFE28B151484C490088DA +:10FE500008804C4908804B48BBF93210B0F90000CB +:10FE600081420CDD3B48F1B25B46099A0068FDF720 +:10FE700081FD012803D108F1010000F0FF0840498D +:10FE8000059808803F4908980880761C94F80E0170 +:10FE9000B0428CD2D9F800004C4690F8F602000728 +:10FEA0000DD5B8F1010F0AD950460099FFF7CBFCE8 +:10FEB000FCF757F801460098081A00F0FF0821687F +:10FEC00091F8F602000613D540460FE0009A02446E +:10FED000D2B2C2EBC20202EB42030AEB830291F8F8 +:10FEE0001F33D28C9A4201D9009817E0401EEDD200 +:10FEF000B8F1010F0AD0B8F1000F05D1DDE90F010B +:10FF00002B463A46FDF736FD13B032E4144800782C +:10FF10000028F9D19AF8EC0400B1401E8AF8EC04EC +:10FF2000ECE7F0B414681C640E4C246894F8F652A4 +:10FF30006E0737D56D0609D5164D6D7875B3B4F8D3 +:10FF40000643154D64432D68A5422BDCF0BC06E644 +:10FF5000FC051000E4051000C50510004406100063 +:10FF60004205100004071000D00C0120FA0C0120FB +:10FF70002C471000904510003E0610003C06100073 +:10FF8000300610002E0610008606100085061000B0 +:10FF90004206100040071000BC061000FFE7B4F84E +:10FFA0000443CEE7F0BCFDF7E5BC00007047F0B5B8 +:10FFB0001446059F0BE000BF31F9145030F914606E +:10FFC00005EB030CB44519DBED1BB54216DC641ED2 +:10FFD000F2D1BD4B1B6893F845301B09C3F11004E7 +:10FFE0000AE000BF31F9125030F912605D4306FBA0 +:10FFF00004552D1121F81250521EF3D2F0BDF0B568 +:020000021000EC +:100000001446059F0BE000BF31F9145030F914601D +:1000100005EB030CB44519DBED1BB54216DC641E81 +:10002000F2D1A94B1B6893F8CA3A03F00F03C3F14E +:10003000100409E031F9125030F912605D4306FBFB +:1000400004552D1121F81250521EF3D2F0BD2DE9A6 +:10005000F8430E46044601F052F9002844D1F00757 +:1000600004D09A492068096800F0F3F8F0063BD5FF +:10007000954D974F2868B0F950100091B0F94E3067 +:100080003A7894492069FFF792FF2868DFF84882A0 +:10009000B0F954100091B0F9523098F800208F490F +:1000A0006069FFF784FF286890F8401089071BD427 +:1000B000310719D58A490978002915D1B0F9C41A30 +:1000C0000091B0F9C23A3A788649A06BFFF797FFE2 +:1000D0002868B0F9C81A0091B0F9C63A98F800201B +:1000E0008149E06BFFF78BFFBDE8F8837F4A10B5CD +:1000F00012780024022A05D0080706D501F0FFF87F +:1001000010B102E0000700D50124204610BD2DE902 +:10011000FF4F7749DDE90D94D1E9015686469346B4 +:100120000020694FDDF83CC028E000BF39F810100E +:1001300034F91030C91A0AB20021002A0EDAC2F1CD +:1001400000083A689246B2F8092B904502DDBAF8E9 +:100150000B1B01E076B90199494207E055B90FFA46 +:100160008EF15A4506DD03998A4201DD09B201E0AC +:100170000FFA8BF1194424F81010401C6045D5DBB0 +:10018000BDE8FF8F2DE9FE4302465A48884600210C +:1001900003785748012B00D10180544B1C784A4BFF +:1001A000022C1B682FD04468641C446093F8CC5A1E +:1001B000B4EB151F00DD4160846805F00F05641C79 +:1001C0008460A54200DA816093F8D24A210710D0FA +:1001D00093F8D35A01888D420BD9491C018093F8BA +:1001E000CD1A04F00F000D09454301F00F044443FC +:1001F00004E093F8CD0A050900F00F04B3F8056B8D +:10020000B3F8077B0AE04160816093F8CB0AB3F84A +:10021000CE6AB3F8D07A050900F00F042C483149B2 +:100220003B460078CDE9002102903246214628461F +:10023000FFF76DFF28482C4A3B460178CDF8008037 +:10024000CDE90121324621462846FFF760FFBDE88F +:10025000FE832DE9F0438146274803781A48052B91 +:10026000006890F844200CD030F9465F02F00F038C +:10027000B0F902602148C3F11004B0F90000024651 +:1002800011E030F94A5F1309B0F90260F2E700BFEC +:1002900031F9127039F912C007EB0508E04511DB9E +:1002A000BF1B67450EDC521EF2D209E031F9102067 +:1002B00039F910505A4305FB0422121121F810207D +:1002C000401EF3D2BDE8F08304071000B40610000E +:1002D00085061000006F0120860610002A6F01209D +:1002E000FC041000766F0120A06F0120E8041000CC +:1002F0000006100038071000840610009606100053 +:100300002DE9FC478146A248A24E88460178306814 +:10031000012511B9A049097811B1B0F9A1420DE048 +:100320009E49B0F99B424978012902D0022903D0A5 +:1003300004E0B0F99D4201E0B0F99F42022101A81A +:1003400000F0D2FA964F42464946B7F9003001987C +:1003500004F0ABF8306890F8A4120A0705D4C90677 +:1003600003D490F8A502C00708D0B7F9000001999E +:10037000009080238B4A084604F0AEF8306890F86D +:10038000A502800609D588480199894A007800901D +:10039000864803780846F6F75AFAB7F90010019A2A +:1003A0000DE000BF32F91100002801DB034600E038 +:1003B0004342A34203DD7F490025088001E0491E36 +:1003C000F0D2022101A800F0F2FA2846BDE8FC872D +:1003D0007048006890F89002400707D56F4876494A +:1003E000C0780978884201D001207047002070470A +:1003F000684810B5006890F89012890727D56F49B2 +:100400000A78521CD2B20A7090F8923293421ED2ED +:1004100000220A7090F850120324C90703D190F803 +:100420008002C00700D00B24EFF7E8FF64480168A2 +:1004300021430160EFF7E0FF1021052002F0C0FA30 +:10044000BDE810404FF48071002006F042BE10BDA0 +:100450004F49514A514809781278437811430B4368 +:1004600056494FF0000208D14B785B1CDBB24B7051 +:10047000052B03D90123437083704A7070472DE91F +:10048000F34F50480027DFF818A190F8008041484A +:1004900081B03C460068B94690F89002C0071AD077 +:1004A00000264FF0010B019D12E028460299FFF74C +:1004B00027FF10F0010F05D00BFA06F03843641C3B +:1004C000C7B2E4B2BAF90000761C05EB400536B2BB +:1004D0004645EADB01E04446FF273B4807704CB144 +:1004E0000094BAF800003B4682B24146019800F001 +:1004F00011F807E02F48B0F90010032002F060FA6D +:100500004FF001094846BDE8FE8F2C4800210170DC +:10051000417070472DE9F003069F002F1AD0012586 +:10052000012F02D01446A9462FE0002410E000BF9E +:1005300005FA04F61E420AD0002C0BD05300624389 +:10054000BDE8F00300EB42011A4608F032BE641C1D +:100550008C42EDDBBDE8F003704700BF002600EBE6 +:10056000440C35460BE000BF09FA05F818EA030F02 +:1005700002D0BCF9008046440CEB420C6D1C8D424D +:10058000F2DB96FBF7F520F81450641EE6D2E1E7A3 +:100590003805100004071000420510004007100045 +:1005A00096061000CE0D012086061000850610006C +:1005B000C60D012014061000870610000C0610005E +:1005C00014071000880610001106100010B5F5F78A +:1005D000DDF9F6F796F8BDE81040F4F723BB2DE9F6 +:1005E000FF5F9A4693460D460320DDF8388006F0FB +:1005F00010FE8B4801680098FFF741FF0446032076 +:1006000006F022FE4CB1FFF723FFFFF7F1FE85480D +:10061000047004B02046BDE8F09FFFF776FF15B1E7 +:10062000284600F02BFCDFF8009200257F4F804E1B +:10063000B8F1000F0ED07F4801784046F5F7CDF9AC +:10064000B87838B1D9F8000090F82802C00701D175 +:100650003570757008F072FF8046FFF7B9FE40EA0A +:100660000804D9F8000090F84003C0070BD0724886 +:10067000007840B90120F070B87808B9787810B1E6 +:100680006E48F5700570002CC1D15246594600984D +:1006900000F038F80446BAE710B500F081F8002001 +:1006A00010BD10B5F6F793FEFDF7F2FFFBF71CFB4C +:1006B000FFF78CFFFFF729FFFCF77FFB594900206C +:1006C00008704870488088808860C860086114316C +:1006D000087088705448006810F8302F4A704078CD +:1006E000C87010BD10B5F6F77AFEFDF7E4FFFBF712 +:1006F000F9FA00F059FCF6F711F84C480021417066 +:10070000817010BD2DE9F8430024804616460F463F +:1007100025468DF80040022006F07BFD3246394622 +:100720004046F6F7EFFC46490128CA7860F3030219 +:10073000CA7029D002282ED0042800D001246B468C +:10074000324639464046FCF708FA40EA04050220E2 +:1007500006F07AFD9DF8000098B1EFF74FFE39489A +:10076000394A0168126811430160EFF745FE3748C6 +:100770000178052002F024F94FF48071002006F082 +:10078000A8FC2846BDE8F88331480570FDF773FFE3 +:10079000FBF7CBFAD3E7FDF7D7FBFBF7ECFACEE795 +:1007A00038B5044600208DF80000022006F031FD27 +:1007B0002046F6F773FD22490128CA7860F3030248 +:1007C000CA7002D0022805D008E0FDF760FFFBF7F1 +:1007D00015FB03E0FDF7E8FDFBF721FB694620462A +:1007E000FCF79CFA0446022006F02EFD9DF800005E +:1007F00098B1EFF703FE1348134A016812681143DA +:100800000160EFF7F9FD11480178052002F0D8F8F2 +:100810004FF48071002006F05CFC204638BD0000DB +:10082000B406100010061000040710004007100066 +:10083000A851100044071000D00610008F061000C9 +:100840009055012014071000BC051000B8051000D9 +:100850004C071000062904D28B4A515C8B4A535C2A +:100860002BB1002101600146482001F060BD864B9C +:10087000083353F821300360854B43F821000120F1 +:10088000505470470A4630B40021062A11D27E4BDC +:100890009A5C72B17C4C0368083454F82240A3423D +:1008A00007D17A4B99547A4B43F82210016030BC3F +:1008B00070470160014630BC492001F038BD2DE988 +:1008C000F0410124714D724F0026285D38B12E553C +:1008D00057F824104A2001F02AFD47F82460641CD0 +:1008E000032CF2DBBDE8F0812DE9F041684D674B48 +:1008F00000270A460C350760596805F1140603F114 +:100900000804012A38D0022A1CD0032A3FD1002231 +:1009100004EB020CDCF800E0BEF1000F07D0521C23 +:10092000022AF5DB042930D301464C2031E055F88A +:100930002240046046F822004FF00330091FCCF833 +:10094000000032E05FF0000204EB020CBCF800E0B3 +:10095000BEF1000F05D0521C042AF5DB0229E3D2B8 +:1009600013E055F82240046046F8220040F20220CD +:10097000ACF80000891E18E05FF0040214F802C011 +:10098000BCF1000F09D0521EF8D2002FAAD10146A7 +:100990004B20BDE8F04101F0CABC55F8225005607B +:1009A00046F822000120A054491E59609AE7F0B48D +:1009B000374E364C002504220C36D0F8003008346F +:1009C00056F822709F4212D1A75C8F420FD1531C60 +:1009D00011D02F4D00232035036045F82230A35459 +:1009E000012911D0022911D0032904D108E0521E97 +:1009F000E6D2002D08D1F0BC01464D2001F097BC95 +:100A0000A01843708370C370F0BC7047A018437087 +:100A1000FAE770B51D4E1E4D0524083620350BE053 +:100A2000305D48B155F824104E2001F080FC315D56 +:100A300055F82400FFF7BBFF641EF1D270BD70B5FE +:100A40000120134B114A002143F820101154401C7F +:100A50000328F9DB012010700C4A05200C4B506074 +:100A60000C330A4C04200B4A083403F11405732696 +:100A7000464302EBC60643F82060215445F8201097 +:100A8000401EF4D270BD0000D09501005006100049 +:100A90007451100070641000F0B5A7B00D46064602 +:100AA00000249821684608F025FCFF4A002168468A +:100AB000137810E001FB03F7224609E007EB020E72 +:100AC00050F822C036F91EE0F44440F822C0521C0F +:100AD0009A42F3DB491CA942ECDB214607E000BF48 +:100AE00050F8212092FBF5F240F82120491C994250 +:100AF000F6DB002117E000273A460CE002FB034C2E +:100B000050F824E036F91CC0BCEB0E0C01D5CCF13A +:100B1000000C6744521CAA42F0DB97FBF5F28A42B4 +:100B200000DD1146641C9C42E5DBB1F5803F03DB30 +:100B30004FF6FF7027B0F0BD88B2FBE7F0B5DB4998 +:100B4000DB4B096891F8A422D20734D0D94A5778F0 +:100B50004FB191F8BB42B1F8B85204F00F02260928 +:100B6000B1F8B64208E091F8BA42B1F8B45204F0D4 +:100B70000F022609B1F8B242DFF83CC39CF800C06E +:100B8000BCF1030F06D191F8BC120FB10A0901E0C4 +:100B900001F00F02A04201DC1A60F0BDA84201DBA7 +:100BA0001E60F0BD001BB11A4843291B90FBF1F0F9 +:100BB00010441860F0BD0020FBE7BC48BD49006848 +:100BC0000A7800F5F970805CC87070472DE9F00F65 +:100BD000DFF8E0A28346B5489AF8007089466FF0C6 +:100BE000004231F817500168002091F80A6291F82C +:100BF00009124FEA11180B071FD001F00F0CAB4C74 +:100C000000210B462468B54294F8084205DBAE1B70 +:100C100006FB08F696FBFCF63444A44E9AF801C095 +:100C2000D0463668BCF1010F96F8F16108D0BCF1EE +:100C3000020F08D006F0030C12E04FF0010CDEE7C3 +:100C4000C6F3810C0CE0C6F3011C09E039F813600F +:100C5000B24201DD32461846B14200DA31465B1C31 +:100C60006345F3DDABF80010A91AA14201DC67452A +:100C700004DD88F80000BDE8F00F9EE7BDE8F00F46 +:100C800070478E4910B50B7888490022012B0968FE +:100C900002D18B4B1B784BB1B1F8FC31834218D297 +:100CA00091F8F0311B0714D5032225E0B1F8023288 +:100CB000834203D291F8F0311B07F5D4B1F800322A +:100CC000834203D291F8F0315B070AD4B1F8FE31C8 +:100CD0000BE0B1F8FA31834205D291F8F0315B07AD +:100CE00001D5022208E0B1F8F831834204D291F82C +:100CF000F001800700D5012272486E4C03789A42B9 +:100D000011D1617899421AD06F4A1278134307D0F3 +:100D10008168491E8160002911DC007860700EE056 +:100D200001708168F7E78AB1022A01D1012B0DD049 +:100D300091F8F61181600270002900DC627063484E +:100D40006278417B62F30301417310BD91F8F711A2 +:100D5000F0E7564A126892F8F021D20607D5421AF7 +:100D6000002A04DCC1EBC1110844C0F3CF10704766 +:100D7000504900204D4A48705249486088600870C8 +:100D8000126892F8A432DB0703D092F8BB22120952 +:100D900000E00022464B1A60C86008614861886123 +:100DA000C861086270472DE9F05F8B463E49DFF865 +:100DB00014914FF0100A0E7805463701002409F10E +:100DC0000C09DFF8008114E0324651462846FFF74F +:100DD00063FE29F81400BBF1010F10D0394B143316 +:100DE00033F81410FFF7B5FF23F8140005EB47059F +:100DF000641C98F801008442E6DDBDE8F09F314BA9 +:100E00001C33EDE738B5294C0020ADF80000206810 +:100E10004FF0000190F8F00180062D4808D5FFF74B +:100E2000C2FF01212B48FFF7BEFF26491C3103E01A +:100E3000FFF7B9FF234914316846FFF7C7FE206862 +:100E40001C4D90F8F001400602D5BDF8004004E0CA +:100E50001C492878143131F810401F48048020467E +:100E6000FFF70FFF2046FFF769FE164928780C317F +:100E700031F810001549A1F81B0038BD2DE9F14FDC +:100E800084B0002002900848102605780D484FEAEB +:100E90000518406890FBF6F106FB11000C49684309 +:100EA00001EB400A8B4619E086061000040710008B +:100EB0003806100040071000840610008D06100050 +:100EC0008E061000600610008C0610009055012060 +:100ED000AC1B0120AC2E0120120610004049049CDE +:100EE000096891F8F011890615D50BF5985101EBB9 +:100EF00040093C48477868007F1C009008E0214684 +:100F00004846009A08F055F904EB450409EB4809F6 +:100F10007F1EF4D2049CDFF8CC9099F801707F1CFE +:100F200024E02F48006890F8F011890615D5D9F80B +:100F3000041000290FDD02996A1AB0F90612CDE9F2 +:100F40000012B0F9043202980BEB400204EB4001AE +:100F5000084603F031FA0BEB480B6A002146504675 +:100F600008F027F904EB45040AEB480A7F1ED8D2A3 +:100F7000D9F804104FF0FF32491C02EB46024846F4 +:100F8000C9F804108A4200DA4660D9F80400B04279 +:100F900006DB05B01449BDE8F04FA1F5985031E7E4 +:100FA00005B0BDE8F08FE3E610B50D4C206890F871 +:100FB000F101C0F30112C0F3810100F0030002F05F +:100FC00035F9084948702068084990F8EB0000F0AE +:100FD00003000870FFF7F1FDBDE81040C8E600000F +:100FE0000407100060061000AC2E0120400710001E +:100FF00010B5FE48FE49002484610C604C600C7200 +:101000000462C461FFF76EFBFFF719FDF948048025 +:10101000BDE8104000F0A5B9F0B5F749F348F94F25 +:1010200091F83020427091F8313083705A4316B2F3 +:10103000468291F83340C47011F82C2F02704A7820 +:1010400002718A784271C9788171EC49416201F27A +:101050003C618162A1F67841C162E9490B6893F86D +:10106000F01109061AD503F5F97593F8F13100224C +:1010700003F0030311465B1C08E000BF15F801C034 +:10108000A44501D10A4603E0491CC9B28B42F5D8F8 +:10109000C271724307EB42010163F0BD0763F0BD0B +:1010A000D54890F82C10D3488170D04902790B7A3A +:1010B00063F300028B7A63F3C3024B7A63F3820219 +:1010C000CB7A63F341020B7B63F34512CE4BDB78A3 +:1010D00003728B7BC3714B7B63F304120271CB7B76 +:1010E000827B097C63F3030261F30712C7498273B1 +:1010F000097880F82810C6490988A0F82910C54940 +:101100000A7890F85B1062F3410180F85B10C249E5 +:101110000A78C17B62F30301C173C0490A78017C7C +:1011200062F30001BE4A127862F34101BD4A1278AF +:1011300062F3C301BC4A21F00401127880F87E20DA +:101140000174BA490A88A0F84020B94A1388038775 +:101150004B88A0F84230538843878B88A0F84430EE +:1011600093888387C988A0F84610D188C187A04991 +:101170008A7980F87B20097A80F87D10AD4909785A +:1011800080F87C10704770B50D4680EA0506F006C1 +:1011900001D5F5F7B6FA964CC5F300102070B006ED +:1011A00001D5F3F73FFDC5F34010607015F048001E +:1011B00000D00120A0719248006890F8AC0900F0BE +:1011C00001002071C5F30020E071C5F340202072BA +:1011D000C5F34000E07070BD2DE9F041834E864CB0 +:1011E000D6E907100843D4E9081241EA020180EA6F +:1011F000010503D111B1FFF7FBFE11E0E8070BD0A9 +:101200008D4F387820B108F0BFF908B90020387048 +:10121000FFF747FAFFF7C7FEE80601D5FFF7D6F953 +:10122000E169B069FFF7AFFFE069B061206A306241 +:10123000606AF061BDE8F041EEE670B57F4D2C6864 +:10124000002C0CD00022A0B2114601F0D9F9286878 +:10125000A043286003D1BDE8704001F043BA70BDDF +:10126000F8B5002601F03CF8012005F0D2FFFFF7A9 +:10127000B3FF5E4C604D94F82000000716D5D5E909 +:101280000E01F3F73AFF5E48006890F840008007CF +:1012900009D5D4E90701FEF729FF012803D1D5E9D3 +:1012A0000E01FEF76FFF66490020087094F82000D9 +:1012B000217F0843C00708D0E8680090D5E9000105 +:1012C000D5E90423FFF78BF90646E06950B14EB922 +:1012D000032005F09EFF4848E169FEF7B8FE0320B1 +:1012E00005F0B2FFFFF7DCFEFFF7A7FFFFF791FB6A +:1012F000FFF7E5FABDE8F840012005F0A5BF3B483F +:10130000417A012908D0817A012905D0C17A0129C1 +:1013100002D0807B002800D00120704708B5FFF77D +:1013200067FE6B4600220B21022005F01BFF009890 +:10133000C00705D00121022005F0F7FEFFF790FF5E +:101340000098800705D50221084605F0EEFE00F062 +:1013500033F800980007E4D50821022005F0E5FEE7 +:10136000DFE710B5264C2148226892F83110417011 +:1013700092F830208270514341822349C978C1706C +:101380000121017141718171017000218182C1735C +:101390000174FFF786F9F3F7DFFC2068294A90F81B +:1013A000381401F0010111702749B0F87600088067 +:1013B000BDE81040FEF7FABD70B5002400F090FFC4 +:1013C000012005F026FFFFF707FF084D95F82000E4 +:1013D000C00704D008480068FFF75EF90446E869D2 +:1013E000A0B39CBB032005F014FF30E0840610007E +:1013F000A85110009055012068761000E8470120A0 +:1014000004071000105601204007100011061000BC +:1014100014061000440610002605100024051000D4 +:10142000380510003E051000390510007406100044 +:101430007C061000D00610004B0710002C0710008F +:1014400038071000470710004807100006E00A4858 +:10145000E969FEF7FCFD032005F0F6FEFFF720FE2C +:10146000FFF7EBFEFFF7D5FAFFF729FABDE870406A +:10147000012005F0E9BE0000687610000D4D002047 +:101480000D4C28602868401C2860EEF7B7FF07F075 +:10149000BCFD0128206809D040F00400206006F05F +:1014A000DCFB00BFEEF7A8FF30BFEBE720F0040045 +:1014B0002060F7E7CC06100010ED00E070B5134C8B +:1014C00025462021114807F0F3FE104800F0E2FC09 +:1014D0002B78421E691C184600F056F918B10120FD +:1014E000216801F06DFA00F0EFFC0028E9D170BD31 +:1014F00038B50C46054605F0ECFD6946284605F072 +:1015000022FE00992142F8D138BD0000B1511000EF +:1015100070B5002300290EDD0278491E092A0AD27F +:10152000914D401C55F8324005EBC2025268914281 +:1015300001D1A0470346184670BD017811B98B4907 +:10154000407808800120704710B5894903780A78EF +:1015500073B1884B1B6893F88B3B1B060CD50AB9FB +:1015600001220A704078012806D1F7F737FB03E023 +:10157000012A01D100200870012010BD10B50178AA +:1015800021B1022906D003290BD106E04078FAF7F1 +:1015900091FA06E04078012101E040780021FAF755 +:1015A0006FFA012010BD0CB5016800918188ADF87B +:1015B000041080798DF806009DF8000000B39DF8B6 +:1015C0000100102803D29DF8020010280CD300203F +:1015D00068490090019009686A4691F8951A1318B5 +:1015E000401CD9700428FADB6348009940F8071FB3 +:1015F000BDF8041081809DF80610817101200CBD9A +:101600005D49C91D087000200CBD1CB50168009122 +:101610008188ADF8041081799DF800008DF80610DE +:10162000E8B354489DF802200068642A01D9642276 +:1016300002E01AB990F81A238DF802209DF80330C1 +:1016400090F8CA29934200D80BB98DF803209DF871 +:1016500004309DF80520934202D80AB10F2B08D917 +:1016600090F8BB2302F00F038DF8043012098DF8B7 +:101670000520022900D821B990F8BE0300098DF891 +:1016800006003D4800990160BDF8041081809DF876 +:101690000610817139490868820708D500E008E022 +:1016A00020F00200086008210120FFF721FF01203F +:1016B0001CBD3149087000201CBD10B502782F48B0 +:1016C000016812B141F0080101E021F00801016058 +:1016D00008210120FFF70CFF012010BD10B5027892 +:1016E0002648016812B141F4007101E021F4007153 +:1016F000016008210120FFF7FBFE012010BD1D49FC +:1017000010B5096891F8931A49070AD50078C207FD +:101710001A48016802D041F4807101E021F480711F +:10172000016008210120FFF7E3FE012010BD70B524 +:101730001349144A037809684FF00004CE010D499B +:101740004FF00105096802D54BB1032301E033B125 +:1017500002231370407881F81A0A012070BD1570B9 +:1017600081F81A4AF9E70000E495010048071000E3 +:101770004607100004071000D006100034071000C0 +:10178000600510004905100010B50C460023A0F1BB +:10179000A001092903D8FE4850F8213008E0C028EC +:1017A0000AD1FB49A0F1C000A1F1040151F8203099 +:1017B0001146204698470346184610BD0020704742 +:1017C00070B5F44C00230029236011DD0278491E16 +:1017D000042A0DD2EE4D401C283555F8324005EB59 +:1017E000C2025268002A03DB914201D1A04703469E +:1017F000184670BD10B500F0FFFB012010BD2DE9AB +:10180000F041064600240078E34D8106274607D5BF +:1018100001242C7000F002FC30B900F0EDFB03E075 +:10182000C00701D001242F703078400701D544F063 +:101830000404DA48042104600120FFF759FE2F70E8 +:101840000120BDE8F08110B510210120FFF750FE06 +:10185000D24900200860012010BD10B501460024C7 +:1018600009782046032918D005DC59B101290CD08C +:1018700002291AD10EE0042911D0102912D0112901 +:1018800013D111E00124002001E00224012000F026 +:1018900084FA0AE004240220F9E7202400E040242E +:1018A000012002E0082400E01024BA4914F0180FC7 +:1018B0000C60BA4C06D010210120FFF719FE002061 +:1018C000206007E02168814204D0206004210120CB +:1018D000FFF70EFE012010BD70B5002300290FDDBB +:1018E0000278491E052A0BD2A94D401C483555F8EF +:1018F000324005EBC2025268914201D1A047034633 +:10190000184670BD10B50078C207A548016802D01E +:1019100041F0020101E021F00201016008210120F3 +:10192000FFF7E6FD012010BD10B50078C2079C4806 +:10193000016802D041F0040101E021F004010160DE +:1019400008210120FFF7D4FD012010BD10B501785A +:10195000CB0793490A6802D042F0080201E022F066 +:1019600008020A600078800702D542F0400001E0DA +:1019700022F04000086008210120FFF7B9FD012096 +:1019800010BD10B5002103780A469C0601D5202120 +:1019900000229C0701D541F002015C0701D541F00E +:1019A00004011C0701D541F00801DC0601D541F016 +:1019B00010015C0601D541F040011B0601D541F044 +:1019C00080014378DC0701D041F480719C0701D588 +:1019D00041F400715C0701D541F480611C0701D519 +:1019E00041F40061DC0601D541F480519C0601D52B +:1019F00041F400515C0601D541F480411B0601D53C +:101A000041F400418378DC0701D041F480319C0728 +:101A100001D541F400315C0701D541F480211C0758 +:101A200001D541F40021DC0601D541F480119C066A +:101A300001D541F400115C0601D541F480011B067B +:101A400001D541F40001C078C00701D041F0807198 +:101A50005448C0E90012012010BD007800B10120F7 +:101A6000514908700120704770B5002300290FDD2F +:101A70000278491E0B2A0BD2454D401C703555F893 +:101A8000324005EBC2025268914201D1A0470346A1 +:101A9000184670BD014600200978052906D23C4849 +:101AA000C83050F82120002108461047704710B573 +:101AB00006F08FF8012010BD10B54FF40061002032 +:101AC000FFF716FD012010BD10B54FF48051002026 +:101AD000FFF70EFD012010BD10B54FF400010020EE +:101AE000FFF706FD012010BD10B50078C00702D039 +:101AF00000F011FA01E000F005FA012010BD10B568 +:101B000000880024C10700D00224810701D544F0D9 +:101B10000404410701D544F00804C00501D544F48C +:101B2000807494B1EEF76AFC20480168214301609B +:101B3000EEF762FC0221052000F042FF4FF48071B5 +:101B40000020FFF7D5FC012010BD002010BD10B50E +:101B500000880024C10700D00124810701D544F08A +:101B60000204410701D544F00404010701D544F003 +:101B70000804C00501D544F4807404B3EEF73EFCBC +:101B80000B48016821430160EEF736FC022111E0A9 +:101B9000309601003C0710004A0710003007100083 +:101BA00034071000600510004707100014071000EC +:101BB000180710000020FFF79BFC012010BD00203B +:101BC00010BD10B500880024C10700D00124810792 +:101BD00001D544F00204410701D544F00404000794 +:101BE00001D544F0080474B1EEF708FC6F480168B1 +:101BF00021430160EEF700FC4FF400110020FFF7D5 +:101C000077FC012010BD002010BD10B50088002415 +:101C1000C10700D00124810701D544F00204410727 +:101C200001D544F00404010701D544F00804C106BD +:101C300001D544F01004810601D544F0200441068A +:101C400001D544F04004010601D544F08004C105EB +:101C500001D544F48074810501D544F40074400535 +:101C600001D544F480646CB1EEF7C8FB50480168BC +:101C700021430160EEF7C0FB80210020FFF738FC14 +:101C8000012010BD002010BD10B500880024C10740 +:101C900000D00124800701D544F0020474B1EEF7AE +:101CA000ADFB4448016821430160EEF7A5FB4FF40A +:101CB00080010020FFF71CFC012010BD002010BD9A +:101CC00010B500780024C10700D00124810701D598 +:101CD00044F00204400701D544F0040474B1EEF767 +:101CE0008DFB3548016821430160EEF785FB4FF419 +:101CF00080610020FFF7FCFB012010BD002010BD1B +:101D000010B500780024522841D01CDC30283AD08D +:101D10000CDC112833D004DC01282DD0102834D15C +:101D20002DE012282BD013282FD128E033282AD0D9 +:101D300004DC312827D0322827D124E0502826D0AF +:101D4000512822D123E0732824D00CDC702821D024 +:101D500004DC53281BD0582817D118E0712819D05B +:101D6000722812D116E0742814D0752812D0762863 +:101D700010D0772809D10DE000F059FB01E000F008 +:101D8000F3FB012401E000F00FFC204610BD00F041 +:101D9000F9FBF6E700F0E7FCF3E7002118B10128B2 +:101DA00001D0022800D10521084670471C07100009 +:101DB000240710002807100020071000204908B54C +:101DC0000020204C08602049206008601F480068FF +:101DD00090F84003C00701D00220206000F027FBEC +:101DE00000F0DDFD6B4600221921032005F0BAF951 +:101DF0000098C00705D00121032005F096F9FFF7F0 +:101E00005DFB009800070BD50821032005F08DF934 +:101E10002068082140F0080020600120FFF768FBDF +:101E20000098C006DED51021032005F07EF9206859 +:101E3000082120F0080020600120FFF759FBD1E7BE +:101E400030071000340710003C0710000407100092 +:101E50001F480021017041708170704710B51C4C03 +:101E60000346A078102814D20F2900D90F21194851 +:101E7000227800EB02100A4600F8011B194607F011 +:101E800098F92078401C00F00F002070A078401CCA +:101E9000A07010BD70B50E4C0025A17891B10D4910 +:101EA000627801EB021111F8015B2A4607F081F913 +:101EB0006078401C00F00F00607072B6A078401E81 +:101EC000A07062B6284670BD014880787047000057 +:101ED000DE061000D151100010B54FF486715E4837 +:101EE00007F008FA5C490120C1F804015B480021B1 +:101EF0004160017007F0ACFA0021BDE810400120FC +:101F000006F06ABA10B572B600205449087007F09E +:101F10009FFA62B610BD10B572B601204F49087025 +:101F20004D48D0F8080108B107F0EEFA62B610BDCE +:101F300010B572B64849494B0A46D1F80841D2F863 +:101F40000021521C202C07D2641C22F02002C1F870 +:101F50000841C1F800210FE0D1F8044122F020022D +:101F6000641CC1F8002124F02002C1F804215A6841 +:101F7000521C5A60D1F80021046801EBC2021460BF +:101F8000406850601878012805D1D1F8080101286F +:101F900001D107F0B9FA62B610BD2F4AD2F8080194 +:101FA00000280ED0D2F8040102EBC000C37923F060 +:101FB0003F03C37192F80821521E02F03F021343FF +:101FC000C371704710B572B62348D0F8081159B1E3 +:101FD000491EC0F80811D0F8042102F1010222F0D4 +:101FE0002002C0F8042105D11C480078012801D145 +:101FF00007F02EFA62B610BD10B572B60020164971 +:102000000122C1F80801C1E940021449486008787A +:10201000012801D107F01CFA62B610BD70B50E4957 +:102020000020D1F80851002D12D00023D1F804214E +:102030000CE000BF01EBC2042678332E02D1647895 +:10204000B52C06D0521C22F020025B1C9D42F1D818 +:1020500070BD012070BD000060540120E406100036 +:10206000064900224FF470430A804B80044BC0E9BC +:10207000003102210172427270470000EC0610002C +:10208000119701002DE9F05FDFF83C92DFF834B2E0 +:102090000F4606464FF0010AA9F10805A846287820 +:1020A0000446072809D2DFE800F004292D49708B87 +:1020B0009C00012E02D0022E13D07EE0002F7CD097 +:1020C000804810300078862809D07E48F9B2103058 +:1020D000FFF7C4FE0121032004F0FBFF6DE00324A1 +:1020E0006BE06878012805D01021764807F0E0F809 +:1020F00000F0A2F8544689F800A05EE0022E5AD003 +:10210000002445E0022E1BD1704C6E48D8F8041014 +:10211000227807F04EF8032189F800102178A9F8F9 +:10212000041098F80000042488F8010088F80040A2 +:1021300033E0002488F801002C70AFE7022E02D0B3 +:10214000012EF6D039E0FFF728FF082170B15D4A73 +:10215000D0E90030C2E90030022289F80020594A53 +:10216000A9F80220A9F80410052426E068780628BA +:1021700004D00022CBF80020CBF80420032289F8F9 +:102180000020A9F80410062417E0022E08D002242B +:102190005FFA80F088F801002C704B48BDE8F09F92 +:1021A0006878042807D00BEB0700394610F8012C9B +:1021B000444807F075F889F800A0A8462878E9E7B0 +:1021C000022E04D0082F8AD1FFF7FCFE87E7FFF725 +:1021D000F9FE98F80000032488F8010088F8004010 +:1021E0005CE7022E4FF00304A4D0D1E73649002269 +:1021F00008390A704A70354A521C4A6034490160F5 +:10220000304981801031C18010210181704710B5A3 +:10221000044607F01DF92B4AD4E90001C2E9000188 +:102220002A480C3807F07AF928480C3806F0C8F923 +:10223000BDE8104007F068B970B5224C1034207822 +:10224000C12824D160781F4D052808D100F020F85E +:102250002048016829608188A9808079A871607808 +:10226000082814D11C4C207858B90F216170002126 +:10227000A1701A49E01C096891F8952A042107F019 +:102280000FF820682860A088A880A079A87170BD88 +:1022900010480178002913D141701049096891F85C +:1022A0001A23827091F8CA29C27091F8BB231309CE +:1022B000437102F00F02027191F8BE130909817196 +:1022C000704700006C550120F8061000E052100025 +:1022D00035200100D0061000D706100004071000BA +:1022E00070B50F4D802128462C8806F0E1FF641C54 +:1022F0002C8070BD0A48001F00210160704708490A +:10230000091F0A88024204D0C87818B1C878401E54 +:10231000C8707047A52088708878A528FCD07047C1 +:102320009055012037480021016041607047C0B2DC +:10233000012200F047FBFEE7344C0025324FC4E990 +:102340000225C4E90071064600682061706860617A +:10235000B068A061F068E061306920627069606215 +:10236000B069A062F069E062294890468946006839 +:102370002063274810380068606325480C380068DF +:10238000A063234808380068E0632148001D006806 +:1023900020641F483438006860641D4814380068A1 +:1023A000C4E9120504F0E5FF2065C4E91565E5659B +:1023B00025666566A566E56625676567C4E91E57F7 +:1023C00041464846FFF7B3FF10B50446C0B20022AD +:1023D00000F0F8FA0F490868082803DA094A14548B +:1023E000401C086010BD012806D0022808D1002238 +:1023F0001146132000F0E6BA002211461220F9E738 +:102400007047000070EF0120AF0550FA80EF012007 +:1024100038ED00E000071000FD48FE4A01689142D7 +:1024200004D1FD4902794A70002101607047F0B57E +:1024300085B040F24C71F64806F05CFF684605F046 +:10244000F3FEF34C012500266570A680A6710220DC +:10245000E07105F0A6FB208105F09FFB070205F067 +:102460009CFB47EA102060816020208242F26020BD +:102470006082EA480068418AA182018AE182E849D3 +:10248000B1F8FA2E2283B1F8F82E6283427D2277CA +:1024900091F8FC1E6177E3490968497CA177E677EA +:1024A00001992162009961620299A162DDE903123A +:1024B00041EA0221E16281692163C1696163DA490C +:1024C0000968A1630168E163418EA4F85010818E10 +:1024D000A4F8521090F8311004F8541F90F830000E +:1024E0006070D24824F82C0FD1482081D1486081F7 +:1024F000D148A081D148E081D1482082D148608272 +:10250000D148A082D148E082D1482083D14860835D +:10251000D148A083D148E083D1482086D148608645 +:10252000D148A086D148E086D1482087D14860872D +:10253000D148A087D148E087D148A4F85000D148BD +:10254000A4F85200D048A4F85400B349CF48A4F8E6 +:1025500056008888401C8880A52204F8802D65706C +:1025600060800D7005B0F0BD70B5AB4C0546002322 +:10257000A088A749401C82B2A280284601F0FBFC3B +:10258000257070BD70B5054640F24C71A04806F04C +:10259000B1FEA14C9E49A088401C82B2A280284670 +:1025A00001F02AFD257070BD70B59B4C0546207862 +:1025B000A84204D040F24C71954806F09BFEB44806 +:1025C000A5700F2101609248914A1030A0608020D0 +:1025D0001071924802F19005E560006890F83110A2 +:1025E00090F83030517101FB03F005EB4006937118 +:1025F00026610844D17105EB40006061137270BD23 +:1026000070B50546844CC00704D080228749A06875 +:1026100006F0CFFD814EA80712D5316891F8310040 +:1026200091F830104843A178302935D0312935D080 +:10263000322935D08049E3684200184606F0B9FDDA +:10264000680716D53068A17890F831209148302974 +:1026500028D0312931D00078322930D0022838D022 +:10266000052836D0062834D077495200206906F074 +:10267000A0FD280735D5306890F83020A0783028A4 +:1026800029D0312829D0322829D073496069BDE882 +:102690007040520006F08DBD6549CCE76549CAE738 +:1026A0006649C8E70078022805D0052803D0062827 +:1026B00001D06349D9E77349D7E76249D5E70228D2 +:1026C00005D0052803D0062801D06049CDE76F4921 +:1026D000CBE76D49C9E75E49D8E75E49D6E75F4970 +:1026E000D4E770BD4A4AA52010704B4881785170DC +:1026F00001708188491C81805180704730B587B056 +:102700000C4600218DF80C104FF4832504AB03AA6E +:10271000694600F0EBF89DF8100010B1112816D0B2 +:102720001AE09DF80C20BAB10098627105EB8001A7 +:1027300004F110000A78930703D002F0FC0208327B +:1027400000E0121DD2B206F034FD07B030BD3220D9 +:1027500000222071114603E0302000222071114632 +:1027600000F030F9F1E770B505464FF4C87128481C +:1027700006F0C0FD284C2649A088401CA0802846B1 +:10278000FFF7BCFF22482570A52101704570A18884 +:10279000418070BD2DE9F84F884606460C460D1D58 +:1027A00000239B220421404600F06EFD70BBA07800 +:1027B000B0422BD1217800239B22284600F064FDF3 +:1027C0006178884222D1207881070AD0022202EB68 +:1027D0009006002101E02954401CB0EB860FFAD38B +:1027E00002E0012101EB90060024DFF824B04FF451 +:1027F0008325A1464FF0330A55F8240005EB8407E2 +:10280000401C4ED000239B22042145E068E00000DC +:10281000000001204B4355465007100004071000EC +:10282000EC6F012008071000F0FF01009055012017 +:1028300020880120AC410120E847012010560120EA +:102840003C8501205A0C0120D00C0120006F012092 +:1028500066850120840C0120FA0C01202A6F0120DA +:1028600058820120320A0120A80A0120766F012037 +:10287000828201205C0A0120D20A0120A06F01207F +:102880006C810120DE090120080A0120B409012021 +:102890002C071000E8041000384600F0F5FC10B1D9 +:1028A00015E000940CE03878810704EB900401D027 +:1028B000A41C00E0641C602C9ED3B9F1000F06D06C +:1028C00031464046009A05F0A0FA00280CD00022BC +:1028D0008BF804A011463320BDE8F84F00F072B821 +:1028E000002211463120F7E7BDE8F88F2DE9FF5FA0 +:1028F00000260E601D4688464FF48327B1463446B5 +:10290000B3461E7057F8240007EB840A401C23D0FE +:1029100000239B220421504600F0B6FC18B112207F +:10292000287001261CE09AF8022000999AF800000D +:102930008A4208D10299029A4FF001090978491C8C +:102940001170C8F80040810704EB900401D0A41C6A +:1029500000E0641C602CD5D316B9B9F1010F0BD07F +:1029600056EA090606D111202870029981F800B0B4 +:10297000C8F800B0BDE8FF9FD8F80000002307EBBF +:102980008004201D21789B2200F07EFC6178884223 +:1029900002D185F800B0EDE712202870EAE700F0D8 +:1029A00017B838B504466946183000F012FD2046C5 +:1029B000009900F017F838BD0146032000F07CB8FC +:1029C00000F088B800F0A5B800F0B5B800F0BCB8C9 +:1029D0001CB56849D1E90001CDE900016846FFF75F +:1029E000A7FA1CBD1CB5634BD3E90223CDE9002334 +:1029F00090F82421032A1DD0082A21D00B2A1FD0A9 +:102A00009DF8002022F0F00212F120028DF8002043 +:102A100090F8252102F00F02012A17D0022A1BD0BC +:102A2000042A41D0052A9DF8012022F00F0241D04E +:102A3000521C16E09DF8002022F0F0021032E5E76B +:102A40009DF8002022F0F0023032DFE79DF80120EF +:102A500022F00F02921C04E09DF8012022F00F02E8 +:102A6000D21C8DF8012090F833219DF8013062F3DB +:102A700007138DF80130BDF802200B0C63F30B0235 +:102A8000ADF80220BDF8032061F30F12ADF803206A +:102A900030F8441F090A8DF8051000788DF80600FB +:102AA0006846FFF745FA1CBD9DF8012022F00F0291 +:102AB000121DD6E7521DD4E71CB52E4BD3E90423D3 +:102AC000CDE900238DF80100CDF802106846FFF72C +:102AD0002FFA1CBD1CB5284A126892F8A020930753 +:102AE00016D50A2814D2DFE800F0130507070707F8 +:102AF0000707130712060BD51E4BD3E90623CDE9B2 +:102B000000238DF80100CDF802106846FFF710FA97 +:102B10001CBD1CB5174CD4E90834CDE900348DF840 +:102B20000100CDF80210684612B1FFF770FB1CBD22 +:102B3000FFF7FEF91CBD1CB50168009140680190CB +:102B40006846FFF7F5F91CBD1CB54178002910D087 +:102B500005290ED2074AD2E90C12CDE90012D0F8AD +:102B60000210CDF80210C088ADF806006846FFF7E5 +:102B7000DFF91CBD1C970100040710002DE9FF417F +:102B800004F0F2F9234D0024C4EBC40105EB8100ED +:102B900000F10C03027EC8CBCDE90272CDE900360C +:102BA000D0E9012355F82100002104F087FB18B17A +:102BB00021464320FFF7BBFB641C052CE4DB154DCD +:102BC00000248C3505EBC4000021426855F8340020 +:102BD00004F0FBFA18B121464420FFF7A8FB641C5F +:102BE000062CEFDB0B4D002415F1BC05002155F838 +:102BF000240004F050FA18B121464520FFF797FB56 +:102C0000641C042CF2DBBDE8FF8101464620FFF77F +:102C10008EBB00005497010000F01F0301229A4070 +:102C200043099B0003F1E023C3F880224907090E02 +:102C3000002806DA00F00F0000F1E02080F8141DF3 +:102C400003E000F1E02080F80014C3F80021704791 +:102C50002DE9F041642707260025FE4CFE4805F0CB +:102C600086FAFD480368D91C40D04268D11C3DD08B +:102C7000816811F1030F39D0006910F1030F35D0CD +:102C8000B3F1FF3F35D013F1020F32D0B2F1FF3F65 +:102C90002FD012F1020F2CD0B1F1FF3F29D011F14A +:102CA000020F26D0B0F1FF3F23D010F1020F20D049 +:102CB000DFB2D6B2CDB204462A463146384604F0D9 +:102CC00095FF204604F09FFFE44805F026FA03280C +:102CD00014D0012815D0022813D0E048016801293A +:102CE00015D1BDE8F041001D04F089BB002124206E +:102CF00001E000212520FFF767FBDDE70021292007 +:102D000001E000212A20BDE8F041FFF75DBBBDE8EE +:102D1000F0812DE9FC41D24F012501AA69463846D0 +:102D200004F0ECFFCF4C4FF48C56012803D10098EF +:102D3000B0F58C6F04D000212220FFF745FB40E066 +:102D400032463946206806F034FA206804F0E9FF7C +:102D5000012804D000212320FFF736FB002521683D +:102D600028220F46C04801F5865106F022FA41F2AA +:102D7000E6003918BC482022283006F01AFA41F241 +:102D80001C103918B8482822483006F012FA41F2CF +:102D900042103918B4482022703006F00AFA41F285 +:102DA00064003918B0482022903006F002FA41F24F +:102DB0009A003918AC482822B03006F0FAF9002DF4 +:102DC00003D13146206806F073FABDE8FC81F8B5FE +:102DD0000D46064600246A4604F090FF012801D003 +:102DE00001240BE0286831468200A04806F026FA4C +:102DF0009E4804F096FF012800D002242046F8BD2A +:102E0000F8B59A4D9A4F103540F69871994806F0EA +:102E100071FA69463846FFF7DAFF012805D0022823 +:102E200006D0E87801280AD105E00021A02029E099 +:102E30000021A12026E0A87808B9288810B1002137 +:102E4000A2201FE08B48E9880024A0F8F81EA9887A +:102E5000A0F8FA1E297A80F8FC1E0098694607EB54 +:102E600080073846FFF7B3FF78B1012804D000216E +:102E70005FF0A600FFF7A8FAE00728D0A00728D443 +:102E80001121A720FFF7A0FAF8BD6E782946304639 +:102E900000F0F9FF60B1102E0DD0112E0ED0122EC1 +:102EA0000FD0132E10D0182ED7D144F04004D4E701 +:102EB0003146A820DEE744F00104CEE744F00204E6 +:102EC000CBE744F00804C8E744F01004C5E710213C +:102ED000D7E7694920070AD4086890F85022D2073A +:102EE00003D190F88002C00701D01221C9E7E006A3 +:102EF00001D41321C5E76006C6D4086890F85002D3 +:102F0000C007C1D01821BCE730B58DB0EDF776FA17 +:102F10000020012241B201F01F0302FA03F3490924 +:102F2000890001F1E021C1F88031401C1F28F1DB4C +:102F3000EDF762FA04F006FEFFF76EFA05F0CAF943 +:102F400007210A20FFF768FE07210B20FFF764FE28 +:102F5000FEF7C2FFFEF77CFF04A8FFF747F907A8BA +:102F6000FFF77EF804A8009007A802900AA8039033 +:102F7000684605F0C1FB02210020FFF74DFE06F078 +:102F8000C9FA0078C00701D1FEF7C5FFFFF7CAF9FB +:102F9000FFF75EFE04F022FE384D01AA694628467E +:102FA00004F0ACFE344C012802D00021202010E0B7 +:102FB0000098B0F53E7FF8D14FF43E622946206874 +:102FC00006F0F7F8206804F0ACFE012803D00021D9 +:102FD0002120FFF7ACF9FFF79CFE05F045F905004D +:102FE0005DD00121012D02D02E20FFF7A0F920682D +:102FF000017DA94202D02F20FFF799F9FFF700FFCA +:1030000000F052F803F080FC04F0CEF90023012216 +:103010001946052005F0DCFF00231A460121062091 +:1030200005F0D6FF03210120FFF7F6FD042107205C +:10303000FFF7F2FD04210820FFF7EEFD206890F86D +:103040006003C10726D0810724D500214009012350 +:103050001A4615E00090D00328891000508F100008 +:10306000F09F010008071000847F012070641000A9 +:10307000F0BF0100EC6F012004071000F0EF010029 +:10308000009105F0B6F92068002190F8600340092E +:1030900005F037F90DB0BDE83040FFF72BB900213E +:1030A0002D20FFF791F9A9E710B505F0E5FB002306 +:1030B00001221946184605F08BFF0023012219460C +:1030C000104605F085FF00231A460121022005F075 +:1030D0007FFF00231A460121032005F079FF00231A +:1030E0001A460121042005F073FF17480068017C8F +:1030F000A52908D04FF4FA4005F054FF00212820FC +:10310000FFF762F902E0406905F04CFF042102205C +:10311000FFF782FD04210320FFF77EFD042108460E +:10312000FFF77AFD04210520FFF776FD0421062034 +:10313000FFF772FD01210920FFF76EFD0421BDE8B4 +:1031400010400F2068E500000807100070B55A4BCA +:1031500016465C0C08E000BF31F91650A54200DAB3 +:103160002C469D4200DD2B46761EF5D20025002B15 +:1031700001DA1D4609E0002C07DD254605E000BF09 +:1031800031F812305B1B20F81230521EF8D270BD9D +:103190002DE9F047002591460F4680461C462E46F5 +:1031A0005A1E0120294605F0CDFF0BE038F9142006 +:1031B000BA4204DA4A44002A01DD05430E434908B5 +:1031C0004FEA3000641EF1D228463146BDE8F08750 +:1031D0002DE9F047994616461EE0021800F0010559 +:1031E0002A4341EB010707EA010503464F0802EABB +:1031F00003084FEA3004A9F101024FF001004FF03B +:10320000000105F09FFF00EA0800044329400F4336 +:1032100004EA080007EA0501761EDED2D6E78842F6 +:1032200000D30846904200D310467047884200D829 +:103230000846904200D810467047884200D308469E +:103240007047884200D80846704710B500231C46D6 +:1032500042B10278521CD2B202708A4203D9047081 +:10326000012300E00470184610BD30B5002401238E +:1032700005E00C44E41C04F00305641B5B1C934252 +:10328000F7DD00EB440030BD70B50546184600245C +:103290000EE02B5D58400823060602D582EA400066 +:1032A00000E040005B1EC0B213F0FF03F4D1641CC9 +:1032B0008C42EED370BD00000080FFFF30B5B0F946 +:1032C0000240B1F90250641B00D56442B0F900001D +:1032D000B1F90010401A00D54042944203DA9842F6 +:1032E00001DA012030BD002030BD884201DD0846F2 +:1032F00070470028FCDA0020704710B505E000BFD9 +:1033000000EB820353F8044C1C60521EF8D109688C +:10331000016010BD10B503E000EB82030C681C6077 +:10332000521EF9D210BD30B506E000BF00EBC2035B +:1033300073E90245C3E90245521EF7D1D1E90021E4 +:10334000C0E9002130BD10B553884C881B1B438059 +:1033500012880988511A018010BD08B50A46014635 +:103360006846FFF7F0FFBDF90010BDF902004943C0 +:1033700000FB001008BD10B58842029C01DC20460D +:1033800010BD904201DB184610BD8A4200D1521C8C +:10339000401AE31A5843511A90FBF1F0201A10BD5D +:1033A00010B5002A03D0431A934201DD881810BDDE +:1033B0005442A342FBDA881A10BD914201D100B2F7 +:1033C00070475043B0FBF1F000B29042F7D910467D +:1033D000F5E770B50B0002463DD0E64C2068468EFE +:1033E000858EB2F9020031B2FFF77FFF5880B2F943 +:1033F000000029B2FFF779FF1880216891F8361094 +:10340000490702D55988711A5980216891F83610F8 +:10341000890701D5281A1880206890F83610090706 +:1034200010D5B0F83720B3F902003146FFF7C5FFD9 +:10343000588020682946B0F83920B3F90000FFF71A +:10344000BCFF1880206890F83600C00703D0588869 +:1034500019885980188070BD2DE9F047D0F810C048 +:103460000568046A85FB0C12A1FB041242694368DB +:10347000914683FB02628269E246A6FB02677618E8 +:10348000D0E9021781FB07C8C069ACFB00C81CEB80 +:10349000060682FB0A2CA2FB011280FB0902A0FB9C +:1034A0000502401884FB0712A1FB03120818301A0A +:1034B0004FEAE071BDE8F0872DE9FF4F8146AD4846 +:1034C00000268DB000683746B04690F8804390F8EB +:1034D000810300F0030A04B90224BAF1000F01D1FC +:1034E0004FF0040A5FF0000109EBC1004068064498 +:1034F000484300FB0188491C07440629F4DB9E4D24 +:10350000009668680190A868CDE9020728690490D0 +:103510006869CDE90508E8690790286A0890684657 +:10352000FFF79AFF83460B912868CDE90006A8684B +:103530000290E868CDE9030768690590A869CDE9BC +:103540000608286A08906846FFF786FFCDE909015A +:10355000286800906868CDE90106E868039028694A +:10356000CDE90407A8690690E869CDE9070868462F +:10357000FFF772FF06468846DDE90901A0FB043526 +:10358000A6FB047C01FB0451002200FB021508FB92 +:1035900004C106FB0210A7FB04C100FB041007FBDB +:1035A000020013EB0C0345EB00010B9A13EB0B002D +:1035B00051414FF47562002305F0D7FD09EBCA01B4 +:1035C00048600E9948600F990B9AC1E900B2DDE995 +:1035D00009010F9AC2E902010F98C0E904680026A8 +:1035E0003746B0464FEA060059F830100E444143C2 +:1035F00001FB0088401C0F440628F5DB5E4D009659 +:1036000068680190A868CDE9020728690490686994 +:10361000CDE90508E8690790286A08906846FFF731 +:103620001BFFCDE909012868CDE90006A8680290D2 +:10363000E868CDE9030768690590A869CDE906083F +:10364000286A08906846FFF707FFCDE90B01286854 +:1036500000906868CDE90106E86803902869CDE923 +:103660000407A8690690E869CDE907086846FFF7EE +:10367000F3FE80468B46DDE90B01A0FB0453A8FB5B +:10368000046701FB0431002200FB02110BFB0473F1 +:1036900008FB0230A6FB043700FB047006FB0200A7 +:1036A000EB184141DDE90902181851414FF47562E8 +:1036B000002305F05AFD49F83A000E990860DDE94B +:1036C00009021099C1E90002DDE90B01109AC2E973 +:1036D00002011099C1E9048B11B0BDE8F08F2DE90A +:1036E000F05FD1E901651C46A5FB0438D1F80CC098 +:1036F00017460CFB048C0A6882464FF0000B05FB52 +:103700000BC0D318D1E9042104FB04F5A2FB05C8C2 +:1037100001FB058146414FEAE57902FB091213EBF3 +:103720000C0046EB02014FF475625B4605F01DFD8F +:10373000CAF8040097E80B00FA68A3FB04C802FB70 +:10374000048203FB0B2310EB0C025941D7E904342C +:10375000A3FB056704FB057403FB0943901959415A +:103760004FF47562002305F000FDCAF80000BDE8C3 +:10377000F09F0000040710006807100073B51D24B7 +:10378000DDE9005622460120002105F0DBFC28403F +:103790003140084301D1641EF4D50821684604F085 +:1037A0009BFAFF49C0B2096891F8E710C1F34111D3 +:1037B00002290ED310F0030005D0012805D00228FD +:1037C00005D01F200AE00F2008E07F2006E03F2000 +:1037D00004E0C00701D0072000E003200021621CA4 +:1037E00005F0B0FCDDE9002310431943CDE90001E9 +:1037F0007CBD10B5EB4C502818D00ADCA0F11000AD +:1038000009280ED2DFE800F0122828280D0D0D0D32 +:103810002F00512820D052281ED053281CD05828C1 +:1038200021D00020C4E90200014622E003F036F96D +:10383000C4E9020103F034F9C4E90401D84800687E +:1038400090F8E70010F0600F15D0D4E90201FFF7FF +:1038500095FFC4E902010EE003F020F9C4E902017A +:1038600003F01EF905E003F021F9C4E9020103F0B9 +:103870001FF9C4E90401CB480821083004F02CFAF0 +:103880002060C8480821103004F026FA606010BD9E +:103890002DE9FF5F0821DDE90FBA684604F01CFA44 +:1038A0008146082102A804F017FA074600242046A2 +:1038B0003AE042460120002105F044FCDDE9002306 +:1038C0001040194008432DD000252E4627E03246EF +:1038D0000120002105F036FCDDE9022310401940EB +:1038E00008431BD0119860B104FB07F00BEB0501F6 +:1038F0004156324601EB0A0321460E9803F03DFE85 +:103900000BE0324621460E9803F02CFE04FB07F133 +:103910000BEB0502A0EB0A0088546D1C761CBD421F +:10392000D5DB641C08F1010080464C45C1DBBDE8D5 +:10393000FF9F2DE9FF5F84B00821DDE912AB04A8E9 +:1039400004F0CAF98146082106A804F0C5F98046AA +:1039500000250AF1480002902030019048382C469A +:103960002F462E46009034E03A460120002105F013 +:10397000E9FBDDE9042310401940084327D01698DD +:1039800090B11BF8051014980844C2B23946029849 +:1039900003F05FFE05EB090141441BF901203946A4 +:1039A000504603F02EFE10E03946029803F04FFE19 +:1039B0001499401A0BF805003946504603F01AFED8 +:1039C00005EB090242440BF802006D1CEDB27F1CAE +:1039D000FFB24D45C8DB38E032460120002105F03A +:1039E000B1FBDDE906231040194008432BD016989F +:1039F000A0B104EB090115981BF801100844C2B2EC +:103A00003146019803F025FE04EB490141441BF9BE +:103A100001203146009803F0F4FD12E03146019890 +:103A200003F015FE159904EB0902401A0BF8020089 +:103A30003146009803F0DEFD04EB490242440BF8E6 +:103A40000200641CE4B2761CF6B24445C4DB08B044 +:103A5000BDE8F09F2DE9FF5F0821DDE90EBA684659 +:103A600004F03AF98146082102A804F035F9074626 +:103A70000024204629E042460120002105F062FB97 +:103A8000DDE900231040194008431CD000252E46D4 +:103A900016E032460120002105F054FBDDE9022347 +:103AA0001040194008430AD032462146584603F0D8 +:103AB00059FD04FB075280002AF812006D1C761C89 +:103AC000BD42E6DB641C08F1010080464C45D2DBB8 +:103AD0002DE72DE9FF5F0821DDE90E9B684604F024 +:103AE000FBF88246082102A804F0F6F8002580467B +:103AF0002C462F462E463DE03A460120002105F097 +:103B000021FBDDE9002310401940084330D039463D +:103B100009F1480003F09BFD214999F892C00A6819 +:103B200092F8413192F8402103F00F01491C0CFB3F +:103B300001FC012101EB131300FB03C399F8900072 +:103B400001EB121100FB0130109919B94FF6FF710A +:103B500001EA80002BF815003946484603F04AFD7B +:103B600005EB0A02800042446D1C2BF81200EDB2F6 +:103B70007F1CFFB25545BFDB44E0324601200021E7 +:103B800005F0E0FADDE9022310401940084337D080 +:103B9000314609F1680003F05AFD99F8935003E0AB +:103BA0000407100090071000F9490B6893F84311BF +:103BB00093F8423101F00F02521C5543012202EBEF +:103BC000111100FB015199F8910002EB131200FB57 +:103BD0000210109919B94FF6FF7101EA800004EB49 +:103BE0000A0231462BF8120009F1200003F002FD11 +:103BF00004EB4A0280004244641C2BF81200E4B239 +:103C0000761CF6B24445B8DB91E62DE9FF5F08214A +:103C1000DDE90E9B684604F05FF88246082102A8A1 +:103C200004F05AF8002580462C462F462E463DE0EB +:103C30003A460120002105F085FADDE90023104015 +:103C40001940084330D0394609F1480003F0FFFC21 +:103C5000CF4999F892C00A6892F8F93A92F8F82A8E +:103C600003F00F01491C0CFB01FC012101EB1313B4 +:103C700000FB03C399F8900001EB121100FB013027 +:103C8000109919B94FF6FF7101EA80002BF8150061 +:103C90003946484603F0AEFC05EB0A028000424478 +:103CA0006D1C2BF81200EDB27F1CFFB25545BFDB37 +:103CB0003FE032460120002105F044FADDE902230D +:103CC00010401940084332D0314609F1680003F032 +:103CD000BEFCAF4999F893500B6893F8FB1A93F820 +:103CE000FA3A01F00F02521C5543012202EB111166 +:103CF00000FB015199F8910002EB131200FB021036 +:103D0000109919B94FF6FF7101EA800004EB0A021D +:103D100031462BF8120009F1200003F06BFC04EB94 +:103D20004A0280004244641C2BF81200E4B2761C64 +:103D3000F6B24445BDDBFAE52DE9F043894600279C +:103D400087B0904604463E46FC2105F0B1FA914DFD +:103D5000B8F1010F28782071287960718E4890F8A9 +:103D6000821BA17190F8831BE17190F8841BA172F2 +:103D700090F8851BE17290F8801B217390F8810BFD +:103D8000607308D185480068817FA52903D190F927 +:103D90001F7090F920607E480021006890F834017F +:103DA000CDE9027600F00100CDE9041004F1100025 +:103DB0007B49CDE9001005F108000FC8FFF7B9FDF8 +:103DC000A520207012206070A4F80290D5E90001AF +:103DD0000844132101EB4000800807B0BDE8F083E0 +:103DE0002DE9F0438946002787B0904604463E46B9 +:103DF000FC2105F05DFA674DB8F1010F28782071BC +:103E000028796071644890F81A1CA17190F81B1C05 +:103E1000E17190F81C1CA17290F81D1CE17290F8E1 +:103E2000181C217390F8190C607309D15B48006865 +:103E300090F82110A52903D110F9227F90F9016093 +:103E400053480021006890F8E009CDE9027600F0BF +:103E50000100CDE90410524904F110009831CDE978 +:103E6000001005F108000FC8FFF763FDA5202070C2 +:103E700013206070A4F80290D5E90012114400EB01 +:103E800041008008A9E770B50E4605460024FFF7FB +:103E9000B0FC103D092D0ED2DFE805F005090F1327 +:103EA0000D0D0D0D1700304600F00CF902E0304604 +:103EB00000F02BF90446204670BD304600F047F96B +:103EC000F8E7304600F084F9F4E7304600F025FAD0 +:103ED000F0E72DE9F0438946002787B09046044675 +:103EE0003E46FC2105F0E4F92A4DB8F1010F28788F +:103EF000207128796071284890F8921FA17190F87C +:103F0000931FE17190F8941FA17290F8951FE172D0 +:103F100090F8901F217390F8910F607308D11F489B +:103F20000068817FA52903D110F92A7F90F90160EB +:103F300017480021006890F8EC0ACDE9027600F0FD +:103F40000100CDE9041004F110001649CDE900107C +:103F500005F108000FC8FFF7ECFCA5202070182021 +:103F60006070A4F80290D5E900010844132101EB28 +:103F70004000800831E72DE9F0411E46174688468B +:103F800005460024FFF735FC103D092D1FD20BE03C +:103F90000407100090071000EC6F012008071000C4 +:103FA000DC7A0120EC7E0120DFE805F0050B141A15 +:103FB00011111111200032463946404600F04AF9ED +:103FC00004E032463946404600F076F90446204681 +:103FD000BDE8F081324639464046FFF7ADFEF5E7D1 +:103FE000324639464046FFF7FBFEEFE73246394698 +:103FF0004046FFF76EFFE9E72DE9FF411746064609 +:104000000D46FFF7F6FBE548A6F1500205F1100456 +:104010000178297101796971E149092A4CD2DFE8F7 +:1040200002F00507121F4B4B4B4B3600DD4900E0F9 +:10403000DD49CDE9001484680C3090E80E0020467C +:10404000FFF708FD38E00968D84B91F8342191F862 +:10405000401102F0010201F00101CDE902120CE071 +:104060000968D24B91F8E02991F8EC1902F00102AD +:1040700001F00101CDE902129833CDE900348468E2 +:104080000C3090E80E002046FFF723FD14E009688D +:10409000C74B91F8EC2A91F8F81A02F0010201F0EE +:1040A0000101CDE90212CDE9003484680C3090E8BA +:1040B0000E002046FFF7A9FDA52028706E706F80C6 +:1040C000BDE8FF811FB5B54902790B689A4203D15B +:1040D00042794B689A4202D0002004B010BDB54B23 +:1040E00000221B689C7EA52C01D193F91B20AD4CAE +:1040F0000DF1040C0123103000948CE80D00083100 +:104100000FC9FFF7C5FB0120E7E71FB5A3490279F7 +:104110000B689A4203D142794B689A4201D0002041 +:10412000DBE7A44B00221B681C7FA52C01D193F96F +:104130001D209D4B0DF1040C0124103000938CE8E0 +:10414000150008310FC9FFF7A3FB0120C5E730B503 +:104150009249027987B00B689A4203D142794B6841 +:104160009A4202D0002007B030BD8E4A85790024E3 +:1041700082F8825BC57982F8835B857A82F8845BFA +:10418000C57A82F8855B057B82F8805B457B82F887 +:10419000815B884A23461268957FA52D03D192F949 +:1041A0001F4092F920307E4A0125103012680831F4 +:1041B00092F83421CDE9024302F00102CDE9045224 +:1041C0007A4ACDE900200FC9FFF7B3FB0120CAE707 +:1041D00030B57249027987B00B689A4203D14279AF +:1041E0004B689A4201D00020BDE76E4A85790024D1 +:1041F00082F81A5CC57982F81B5C857A82F81C5CAF +:10420000C57A82F81D5C057B82F8185C457B82F8D4 +:10421000195C684A2346126892F82150A52D03D1F3 +:1042200012F9224F92F901305D4A012510301268CF +:10423000083192F8E029CDE9024302F00102CDE90C +:1042400004525A4A9832CDE900200FC9FFF771FB9A +:10425000012088E72DE9FF410F4615460446002658 +:1042600040F27A3105F024F84C48012D0178217193 +:104270000179617106D14F4909688A7EA52A01D169 +:1042800091F91B6004F11001464BCDE90031002289 +:10429000CDE9026200F1080105460FC9FFF7F8FAFF +:1042A000A5202070102060706780D5E90001484388 +:1042B0001330800804B08BE62DE9FF410F46154608 +:1042C0000446002640F27A3104F0F2FF3348012D13 +:1042D000017821710179617106D1364909680A7F37 +:1042E000A52A01D191F91D6004F110012E4ACDE9F2 +:1042F00000210023CDE9026300F1080105460FC942 +:10430000FFF7C6FAA5202070112060706780D5E9FC +:104310000001484313308008CCE730B51F490279CB +:1043200087B00B689A4203D142794B689A4201D018 +:10433000002018E71B4A8579002482F8925FC5792E +:1043400082F8935F857A82F8945FC57A82F8955FE8 +:10435000057B82F8905F457B82F8915F154A234682 +:104360001268957FA52D03D112F92A4F92F90130D9 +:104370000B4A012510301268083192F8EC2ACDE979 +:10438000024302F00102CDE90452094ACDE90020BE +:104390000FC9FFF7CEFA0120E5E6000090071000F4 +:1043A00004071000EC6F012014750120DC7A012055 +:1043B000EC7E0120080710002DE9F04F47F6FF774B +:1043C000DDE909B58146FE4301209A4684462C4624 +:1043D00015E000BF32F8143031F81480A3EB080365 +:1043E0001BB2BB4200DA1F46B34200DD1E46002B63 +:1043F00002DD4FF0000C02E001DA4FF00000641E15 +:10440000E8D220B1BCF1000F01D0002309E050EA4E +:104410000C0306D020B9BCF1000F01D0334600E0F8 +:104420003B4600273C462846CBF1000C0EE000BF7F +:1044300032F8106031F81080A6EB0806F61A36B292 +:10444000564503DA664501DD3744641C401EEFD251 +:1044500004B9012497FBF4F0184404E031F8152066 +:10446000024429F815206D1EF8D2BDE8F08FF0B592 +:10447000002306461D4618460EE000BF36F91140DF +:10448000002C01DB274600E06742974204DD002C48 +:1044900001DD254400E02344491EEFD2002B00DA61 +:1044A0005B42AB4200DD0120F0BDF0B5724D6F42C2 +:1044B0006E0C0EE032F9134031F913C0A4EB0C047A +:1044C000BC4201DB344602E0AC4200DA2C4620F864 +:1044D00013405B1EEED2F0BD70B5049C09E000BF36 +:1044E00031F9145032F91460754395FBF3F520F857 +:1044F0001450641EF4D270BDF0B4049C1CB913B106 +:10450000C3F110040EE0F0BC520004F052BE00BF34 +:1045100030F9125031F912605D4306FB04552D113C +:1045200020F81250521EF3D2F0BC7047F0B4049C35 +:104530001CB913B1C3F180040EE0F0BC520004F0CA +:1045400038BE00BF30F9125031F912605D4306FBEE +:104550000455ED1120F81250521EF3D2E4E7F0B5E5 +:10456000002B19D0144615E000273E46E51A04EB4F +:10457000030C08E0002D05DB954203DA31F915E064 +:10458000761C77446D1CAC45F4DA1EB197FBF6F54A +:1045900020F81450641EE7D2F0BD70B50C461546E5 +:1045A000A04204D001466A00204604F002FE00202A +:1045B00017E00146421C07E034F9126034F911306B +:1045C0009E4200DA1146521CAA42F5D3884207D017 +:1045D00034F8102034F8113024F8103024F8112069 +:1045E000401CB0EB550FE4D9E90725F0010001D0DC +:1045F000205E70BD215E204430F9020C084440105A +:1046000070BD0346002004E033F91120824200DD32 +:104610001046491EF8D2704710B5002447F6FF73C4 +:1046200008E000BF30F91120A24200DD14469A4292 +:1046300000DA1346491EF5D2E01A00B210BD034657 +:1046400047F6FF7005E000BF33F91120824200DA1F +:104650001046491EF8D2002800DA002070470246B2 +:10466000B0F9000005E000BF32F91130834200DDEF +:104670001846491EF8D270470080FFFF70B505004C +:1046800003D0BDE8704002F0EFB9FE4C21466078DF +:10469000097930B10A46FC4901F1980002F036FA76 +:1046A0000BE0207802F000FB21794A00F64901EB8B +:1046B0004001F548983004F07CFDA078F34E28B115 +:1046C000F1482179983002F0EDFA01E0EE48983097 +:1046D000B062E07886F831002846D2E72DE9F05F35 +:1046E000DFF8ACA383460127DAF80000B84600F2F1 +:1046F0005E6490F8F41990F8F05901F01F0690F8F4 +:10470000F11901F00F0990F8DE19890609D590F822 +:10471000581690F859060A2204EB400002F032FACB +:104720000746DAF8000090F8DE19490609D590F836 +:10473000D21890F8D3080A2204EB400002F022FAC3 +:1047400080464FF48070854200D905461F2E00D95F +:104750001F26761C754309F101004543C5EB452032 +:104760007843DAF8002000FB08F0C01392F8871AAB +:10477000B0FA80F0C0F12000890611D50021BBF10C +:10478000010F06D192F88D1A0A0701F0070100D532 +:104790004942401801D5002002E01F2800DD1F20FB +:1047A000C0B2BDE8F09FF8B5044602F016FEB64868 +:1047B00002F018FEA4F8760002F0CEF9B14A0B46DA +:1047C000127800920246204603F0E1F802F0C9F99F +:1047D00002460B46204603F010F9204602F082FA0A +:1047E000AB4DB4F856102868B0F8C02062F3090148 +:1047F000A4F8561090F8BF0094F8551060F3030128 +:1048000084F855100521204602F017FE286890F81C +:10481000F009A0702868218EB0F8F62962F308012B +:10482000218690F8F10900F00F01204602F07CFE8D +:10483000286834F81A1FB0F8E82962F30B0124F84D +:104840001419B0F8E629618962F30B016181B0F8AF +:10485000E419E08861F30B00E08014F8050C20F007 +:104860000C0004F8050C2868217B90F8F22962F30B +:104870000101217390F8F229920862F387112173E4 +:1048800090F8DE19627861F30002627090F8E10935 +:10489000E070804890F8181C217690F8191CA177D8 +:1048A00090F81A1C617690F81B1CE17790F81C1C9C +:1048B000A17690F81D0C84F82000774802F092FD54 +:1048C000A4F87A007448203002F08CFDA4F87E0031 +:1048D000286814F8166F90F8EC19090961F30716A7 +:1048E00004F8066B90F8EE192278090961F30712B3 +:1048F000227090F8ED3914F8051C63F3030104F8F5 +:10490000051C90F8EF79637867F30303637090F800 +:10491000ED793F0967F3071104F8051C90F8EF19CA +:10492000090961F30713637090F8EC1961F300064D +:1049300004F8066C90F8EE1961F3000204F82229DD +:1049400090F8E2090109204602F0FAFD5248483881 +:1049500002F048FDA4F87E004F482734283802F0C2 +:1049600041FDA4F85B00296891F8E00982082078ED +:1049700062F38300207091F8E02962F30000207058 +:1049800091F8E029520862F3410004F8010B207805 +:1049900020F01000207091F8DE29D308E27A63F34A +:1049A0004512E27291F8DF1961F3451004F8280905 +:1049B000204602F069F9286890F8DF09C0F3410148 +:1049C000204602F08BFD296891F8DE09820914F86F +:1049D000330F62F3000004F81D0991F8DE29520933 +:1049E00062F34100607791F8F309E27D60F304021D +:1049F000E27591F8F419A07D61F30400A0752248D6 +:104A000094F849100838407860F30401224884F88B +:104A10004910E83002F0E6FCA4F86400286834F895 +:104A2000181FB0F8EA2962F30B0124F8041910F8F2 +:104A3000E31F227861F3030204F8012B01780A09CD +:104A4000217862F3030104F8091B90F8FB18CA09E6 +:104A5000217862F3000104F82B1B14F8571941F078 +:104A6000200184F8571090F810194A09217862F350 +:104A70000611217090F8FC184A09217C62F3C301E9 +:104A800021740BE0A8071000D4800120108F1000C3 +:104A900004071000EC6F0120BC7B012090F8FB089C +:104AA000400860F304112174F8BD2DE9F04104467B +:104AB000524D01200129A87008D00026504F02292C +:104AC00008D0032914D004292CD13AE0204600F064 +:104AD00091F827E04B48FFF766FE204600F08AF881 +:104AE000B87894F85F1060F3040184F85F1014E064 +:104AF0004448FFF758FE204600F07CF8F87894F818 +:104B00005F1060F3040184F85F1094F8270020F030 +:104B1000020040F0010084F827000021204602F046 +:104B200003FDAE7094F8270040F30000401CE870CD +:104B30003548006890F8DF09C0F380106870BDE860 +:104B4000F081204600F056F8204602F00CF9E8E724 +:104B50007CB502F001F8CDE900010821684603F0B8 +:104B6000BBF82649264D08710020286028710124D1 +:104B7000E0B2FFF7B3FD2855641C052CF8DB214893 +:104B8000FFF711FE7CBD30B5017AA9B079B3684654 +:104B9000FFF78BFF9DF8120000F0030002F044F8CD +:104BA000194C206800F25E6300F6D80590F858169C +:104BB00090F8590603EB400002F007F8206890F8DF +:104BC000D21890F8D30805EB400002F015F80B4816 +:104BD000417801B102210170C9B2684602F027FF95 +:104BE0000A49684602F058FF002029B030BDFFE7AF +:104BF0000120FAE7A422034904F0DBBAA807100059 +:104C0000CC8001203C891000040710002D460100D3 +:104C1000FE49C868401CC860022803D2FC4951F80C +:104C200020000047002001F01FBF002801D102F042 +:104C300024BF7047F54910B50A790120521CD2B241 +:104C40000A710B7A9A420AD8487A48B102F066FE95 +:104C50000320EBF7D5FBEF4802F054FE002010BD17 +:104C600002F00BFFFAE770B514460E46054653B93D +:104C7000A10004F03FFB06E055F8240036F91410BB +:104C8000084445F82400641EF6D270BD70B5E24CAD +:104C90006642650C0BE000BF51F82230B34201DBE5 +:104CA0002B4602E0A34200DA234620F81230521EBF +:104CB000F2D270BD70B518B1BDE8704001F0D4BE3D +:104CC000D24C207A08B1D54D01E0D44D763DCF4984 +:104CD0006079897801282FD0022833D0607801F0DC +:104CE000E3FFA178C0B24A00CD4901EB400128465C +:104CF00004F05FFAC9482379A27829464E30FFF7BD +:104D0000B2FFFFF797FF002825D0C449A2784E31A3 +:104D1000A1F1C400FFF7BAFFA079C24D012814D059 +:104D2000BE4876386863E07985F83E00207985F8DA +:104D30003C00BDE870406BE70A46B949284601F0DF +:104D4000E5FED7E74A00B649D1E7B448A1787638FE +:104D500001F0A8FFE6E770BD70B518B1BDE870407E +:104D600001F082BEA94C207A08B1AC4D01E0AB4DF8 +:104D70004C3DA6496079C97801282FD0022833D04C +:104D8000607801F097FFE178C0B24A00A44901EBD6 +:104D90004001284604F00DFAA0482379E27829461C +:104DA0004E30FFF760FFFFF745FF002825D09B49F5 +:104DB000E2784E31A1F19A00FFF768FFA079994D92 +:104DC000012814D095484C38A863E07985F83E0056 +:104DD000207985F83D00BDE8704019E70A46904902 +:104DE000284601F093FED7E74A008D49D1E78B486A +:104DF000E1784C3801F057FFE6E770BD2DE9F14F3F +:104E0000DFF824B20127B846DBF8000000F25E6448 +:104E100090F8001B90F801AB01F01F0690F8FD1A06 +:104E200090F8FC5A01F00F0990F8EA1A890609D5A2 +:104E300090F85A16B0F85B060A2204EB400001F025 +:104E4000A1FE0746DBF8000090F8EA1A490609D5EA +:104E500090F8D41890F8D5080A2204EB400001F02D +:104E600091FE80464FF48070854200D905461F2E82 +:104E700000D91F26761C754309F101004543C5EB97 +:104E80004520784300FB08F00AF101014843DBF8B4 +:104E90000020C013B0FA80F092F8871AC0F1200009 +:104EA00009061FD5009B0021012B06D0022B0FD035 +:104EB000032B0DD0042B07D10AE092F8E81A0A0759 +:104EC00001F0070100D54942401808D5002009E04B +:104ED00092F8E81A0A06C1F30211F4D4F4E71F2885 +:104EE00000DD1F20C0B2BDE8F88FF8B5044602F01F +:104EF00074FA4B4802F076FAA4F8760001F02CFE22 +:104F0000424E0B46727800920246204602F03FFD68 +:104F100001F027FE02460B46204602F06EFD2046B9 +:104F200001F0E0FE404DB4F856102868B0F8D72ADA +:104F300062F30901A4F8561090F8D60A94F85510B7 +:104F400060F3030184F855100521204602F075FA3C +:104F5000286890F8FC0AA0702868218EB0F8022B0F +:104F600062F30801218690F8FD0A00F00F01204647 +:104F700002F0DAFA286834F81A1FB0F8F42A62F35B +:104F80000B0124F81219B0F8F22A218962F30B01FF +:104F90002181B0F8F02AA18862F30B01A18090F87A +:104FA000FE2AA17A62F30101A17290F8FE2A92080A +:104FB00062F38711A17290F8EA1A14F8012C61F3D8 +:104FC000000204F8012C90F8ED0A6070174890F880 +:104FD000901FA17590F8911F217790F8921FE175AD +:104FE00090F8931F617790F8941F217690F8950FB1 +:104FF000A0770F4802F0F6F9A4F878000C482030AA +:1050000002F0F0F9A4F87C00286813E0B007100063 +:1050100020980100DB4B01000080FFFFCE820120C1 +:10502000C0810120108F100004071000EC6F0120D8 +:10503000347F012090F8F81A14F8147F090961F3FD +:10504000071704F8067B90F8FA1A0A09217862F328 +:105050000711217090F8F93A14F8052C63F3030254 +:1050600004F8052C90F8FBCA63786CF303036370B3 +:1050700090F8F9CA4FEA1C1C6CF3071204F8052CCF +:1050800090F8FB2A120962F30713637090F8F82A6C +:1050900062F3000704F8067C90F8FA2A62F3000134 +:1050A00004F8221990F8EE0A0109204602F048FAA5 +:1050B000D74802F097F9A4F87E00D548273420306D +:1050C00002F090F9A4F85B00296891F8EC0A8208D4 +:1050D000207862F38300207091F8EC2A62F30000DC +:1050E000207091F8EC2A520862F3410004F8010B99 +:1050F000207820F01000207091F8EA2AD308E27A94 +:1051000063F34512E27291F8EB1A61F3451004F86B +:105110002809204601F0D4FD286890F8EB0AC0F376 +:105120004101204602F0DAF9286890F8EA1A8A0963 +:1051300014F8331F62F3000104F8071990F8EA2A03 +:10514000520962F34101E17190F8FF1A627861F34C +:105150000402627090F8000B217860F30401AD48FE +:10516000217094F83310407860F3040184F8331010 +:10517000A94802F037F9A4F84E00286834F8021F55 +:10518000B0F8F62A62F30B0124F8181910F8E31F9F +:10519000227D61F30302227501780A09617D62F3C1 +:1051A0000301617590F8071ACA09A17F62F3000133 +:1051B000A17794F8491041F0200184F8491090F843 +:1051C0001D1A4A0914F80E1C62F3061104F80E1C8D +:1051D00090F8081A4A09A17862F3C301A17090F807 +:1051E000072A520862F30411A17090F8080A800996 +:1051F0007071F8BDA422894903F0DBBF2DE9F041AD +:10520000874D002601272E71AF712E720C466E72EB +:10521000012807D07F4F02282AD0032812D0042863 +:1052200038D13FE00846FFF7E5FF7E48016891F876 +:10523000EF0A42062ED591F8011B2972000629D5E6 +:105240006F7227E07548FFF750FE2046FFF7D2FF48 +:10525000F87894F85F1060F3040184F85F1094F814 +:10526000270020F0020040F0010084F827000CE045 +:105270006A48FFF73AFE2046FFF7BCFFB87894F87B +:105280005F1060F3040184F85F100021204602F0F3 +:105290004BF9AE7194F8270040F30000401CE87110 +:1052A000BDE8F0810846FFF7A5FF204601F05BFD51 +:1052B000EFE770B55B4D286800F25E6200F6D80437 +:1052C00090F85A16B0F85B0602EB400001F07DFC46 +:1052D000286890F8D41890F8D50804EB4000BDE891 +:1052E000704001F089BC70B54D4D4C4C6879A434C8 +:1052F000012826D0022826D0002068702146287870 +:10530000FFF77CFF47480168A07C91F8FE2A62F312 +:105310000100A07491F8FE1A890861F38710A07447 +:105320006978204602F083FBA07C00F0030001F0C6 +:105330007BFCFFF7BEFF2046BDE870403A4902F013 +:10534000ABBB0220D9E70820D7E770B5344D334C0A +:105350006879A434012827D0022827D0012068705A +:1053600021462878FFF74AFF2E48016891F8FE0A87 +:105370000209A07C62F30100A07491F8FE1A890969 +:1053800061F38710A0746978204602F050FBA07C7E +:1053900000F0030001F048FCFFF78BFF2046BDE85A +:1053A0007040224902F078BB0320D8E70920D6E7F5 +:1053B0007FB501F0D1FBCDE9000101F0D2FBCDE9D1 +:1053C00002010821684602F087FC154C0821A070F4 +:1053D00002A802F081FCE0700E4D0124E0B2FFF75C +:1053E0000DFD2855641C052CF8DB0C48FFF77DFDEE +:1053F0007FBD10B5C07A40B1094908704FF0FF3049 +:10540000C860FFF705FC002010BD012010BD0000A2 +:10541000EC7E0120B8810120A47C0120E0891000ED +:10542000B007100004071000654C0100094D010091 +:1054300010B5040003D0BDE8104001F015BB2548AD +:1054400025490078420001EB40012348983003F0E1 +:10545000B0FE21482149983048622046EBE71CB550 +:1054600001F07AFBCDE900010821684602F034FC26 +:1054700018491B4C0870204600F0D5FA164801F078 +:10548000B1FFA4F8760017480168A07C91F8462186 +:1054900062F30100A07491F84611890861F3871046 +:1054A000A0741CBD10B50E4CC07980B1A07C00F07A +:1054B000030001F0B9FB00F008FB0421204602F0D4 +:1054C000B6FA0949204602F0E7FA002010BD012093 +:1054D00010BD0000C0071000B4830120108F100021 +:1054E000288B100004071000E1530100FE49C86832 +:1054F000401CC860022803D2FC4951F82000004734 +:10550000002001F0B1BA002801D102F0B6BA70470C +:10551000F54910B50A790120521CD2B20A710B7AF2 +:105520009A420AD8487A48B102F0F8F90320EAF71B +:1055300067FFEF4802F0E6F9002010BD02F09DFA87 +:10554000FAE770B518B1BDE8704001F08DBAE64CCD +:10555000207A08B1E74D01E0E64D763DA078E649B6 +:10556000820001F5AE7003F069FE607928B1A2787F +:10557000E149284601F0CAFA0CE0A178607801F010 +:1055800093FBA178C0B24A00DB4901EB40012846F9 +:1055900003F00FFED7482379A2782946763801F028 +:1055A000C6FAFFF7B5FF002815D0A079D34D012822 +:1055B0000BD0D0487638A861E07985F830002079A2 +:1055C00085F82000BDE8704090E7CA48A178763899 +:1055D00001F068FBEFE770BD70B518B1BDE8704031 +:1055E00001F042BAC04C207A08B1C24D01E0C14D71 +:1055F0004C3DE078C049820001F5D87003F01EFEF2 +:10560000607928B1E278BC49284601F07FFA0CE0C5 +:10561000E178607801F04EFBE178C0B24A00B6490B +:1056200001EB4001284603F0C4FDB2482379E2783B +:1056300029464C3801F07BFAFFF76AFF002815D0A5 +:10564000A079AE4D01280BD0AA484C38E861E0792A +:1056500085F83000207985F82100BDE8704045E7E5 +:10566000A448E1784C3801F01EFBEFE770BD2DE94E +:10567000FF5FDFF88CB28C460127DBF80000109E3C +:10568000134690F8491190F8444101F0030A90F84C +:105690004811B84601F01F0590F8451190F8320105 +:1056A00001F00F09800605D50A221946604601F06F +:1056B00069FA0746DBF8000090F83201400605D58C +:1056C0000A220E99039801F05DFA80464FF480702B +:1056D000844200D904461F2D00D91F256D1C6C4340 +:1056E00009F101004443C4EB4420784300FB08F077 +:1056F0000AF101014843DBF80010C013B0FA80F052 +:1057000091F8871AC0F12000C9060FD5009A002130 +:10571000012A04D10F9909B1714200E031464018C5 +:1057200001D5002002E01F2800DD1F2004B0C0B218 +:10573000BDE8F09FF8B5044601F04FFE6E4801F059 +:1057400051FEA4F8760001F007FA674E0B46727816 +:1057500000920246204602F01AF901F002FA0246CF +:105760000B46204602F049F9204601F0BBFA644D91 +:10577000B4F856102868B0F8C02062F30901A4F804 +:10578000561090F8BF0094F8551060F3030184F8A8 +:1057900055100521204601F050FE286890F844017C +:1057A000A0702868218EB0F84A2162F30801218692 +:1057B00090F8450100F00F01204601F0B5FE286881 +:1057C00034F81A1FB0F83C2162F30B0124F81219C7 +:1057D000B0F83A21218962F30B012181B0F8382118 +:1057E000A18862F30B01A18090F84621A17A62F3AF +:1057F0000101A17290F84621920862F38711A1720B +:1058000090F8321114F8012C61F3000204F8012C15 +:1058100090F8350160703B4890F8801BA17590F8B6 +:10582000811B217790F8821BE17590F8831B6177CB +:1058300090F8841B217690F8850BA077324801F010 +:10584000D1FDA4F878003048203001F0CBFDA4F859 +:105850007C00286890F840110A0914F8141F62F3BC +:10586000071104F8061B90F842211309227863F30C +:105870000712227090F8417114F8053C67F3030396 +:1058800004F8053C90F843C167786CF30307677030 +:1058900090F841C14FEA1C1C6CF3071304F8053C57 +:1058A00090F843311B0963F30717677090F8403194 +:1058B00063F3000104F8061C90F8421161F3000242 +:1058C00004F8222990F836010109204601F038FE3B +:1058D0000D48483801F086FDA4F87E000A482734B8 +:1058E000283801F07FFD11E0C4071000289801005E +:1058F000B7540100B2850120A4840120108F10004C +:1059000004071000EC6F0120247B0120A4F85B0049 +:10591000296891F834018208207862F383002070AE +:1059200091F8342162F30000207091F8342152087C +:1059300062F3410004F8010B207820F01000207081 +:1059400091F83221D308E27A63F34512E27291F8BA +:10595000331161F3451004F82809204601F082F95B +:10596000286890F83301C0F34101204601F0B6FDEC +:10597000286890F832118A0914F8331F62F3000185 +:1059800004F8071990F83221520962F34101E171DC +:1059900090F84711627861F30402627090F8480150 +:1059A000217860F304012170CC4801F01BFDA4F8BC +:1059B0004E00286834F8021FB0F83E2162F30B0154 +:1059C00024F8181910F8E31F227D61F303022275F1 +:1059D00010F8451B0A09617D62F303016175817A44 +:1059E000CA09A17F62F30001A17794F8491041F040 +:1059F000200184F84910C17F4A0914F80E1C62F393 +:105A0000061104F80E1CC17A4A09A17862F3C30199 +:105A1000A170827A520862F30411A170C07AC0F3B7 +:105A200080107071F8BDA422AD4903F0C2BB2DE90E +:105A3000F041AC4C002601272671A77126720D4655 +:105A40006672012806D0022825D0032814D0042825 +:105A50002CD133E00846FFF7E6FFA348016891F830 +:105A60003701420622D591F84911000601F00301E1 +:105A700021721BD5677219E09948FFF75BFE284633 +:105A8000FFF7D1FF95F8270020F0020040F0010059 +:105A900085F8270005E09248FFF74CFE2846FFF7FF +:105AA000C2FF0021284601F03FFDA67195F82700AE +:105AB00040F30000401CE071BDE8F0810846FFF7AC +:105AC000B2FF284601F04FF9EFE770B5864D286820 +:105AD00000F25E6200F6D80490F8541690F855066D +:105AE00002EB400001F071F8286890F8CE1890F8A9 +:105AF000CF0804EB4000BDE8704001F07DB870B500 +:105B0000794D286800F25E6200F6D80490F85616C7 +:105B100090F8570602EB400001F057F8286890F81B +:105B2000D01890F8D10804EB4000BDE8704001F0B7 +:105B300063B870B56B4D6A4C6879A43400B102202B +:105B4000687021462878FFF772FF674928780A684D +:105B5000A17C92F8463163F30101A17492F84621C9 +:105B6000920862F38711A1746049085C94F85F1091 +:105B700060F3040184F85F106978204601F057FF54 +:105B8000A07C00F0030001F04FF8FFF79EFF2046D5 +:105B9000BDE87040564901F07FBF70B5514D504C83 +:105BA0006879A43408B1032000E001206870214620 +:105BB0002878FFF73CFF4C4928780A6892F846118C +:105BC0000B09A17C63F30101A17492F846219209AB +:105BD00062F38711A1744549491D085C94F85F1070 +:105BE00060F3040184F85F106978204601F01FFF1C +:105BF000A07C00F0030001F017F8FFF780FF2046BB +:105C0000BDE870403B4901F047BF2DE9F041364EF9 +:105C100088B0356805F25E6500F09EFFCDE90401AD +:105C200000F09FFFCDE90601082104A802F054F816 +:105C30002C4C0821A07006A802F04EF82B4FE07003 +:105C4000012407F10508306890F88C1A90F8CE38D6 +:105C500001F00702C1F3C0010093CDE9011290F8F1 +:105C6000CF1890F8542690F8550605EB410305EB44 +:105C70004001E0B2FFF7FBFC3855306890F88C1A11 +:105C800090F8D038C1F30212C9090093CDE901128E +:105C900090F8D11890F8562690F8570605EB410376 +:105CA00005EB4001E0B2FFF7E2FC08F80400641CD9 +:105CB000052CC8DB0A48FFF73DFD08B0FCE610B52F +:105CC000807940B1074908704FF0FF30C860FFF796 +:105CD0000DFC002010BD012010BD0000A47C01209F +:105CE000CC8B1000C407100004071000988401201A +:105CF000F35401008955010010B9714A6F491161CF +:105D000000F0B2BE70B56F4D0446286890F8F101FE +:105D1000C0F30112C0F3810100F00300FDF786FA21 +:105D2000401CC6B2204600F033FC644801F05AFB28 +:105D3000A4F8760000223146204601F059FDA079F2 +:105D400040F00200A07194F86F0066F3020084F83E +:105D50006F0094F86E0020F00F0084F86E00296840 +:105D6000A07C91F8082162F30100A07491F8082149 +:105D7000920862F38710A074A0896FF30B00A081D2 +:105D800091F80701A07094F85E00002120F0010056 +:105D900084F85E00204601F0C7FB286890F8F211F5 +:105DA00084F8661090F8F31184F8681090F8F411F4 +:105DB00084F86A1090F8F50184F86C003F4894F874 +:105DC0005F10001F407860F3040184F85F102046E4 +:105DD000BDE8704000F03ABF10B5384C0020241FD9 +:105DE0002080012000F02FF86070BDE81040364898 +:105DF00088E72DE9F041344E407910B3B07C00F0D3 +:105E0000030000F011FF2F4F3C6804F25E6094F82D +:105E10004F2604F6D80594F84E1600EB420000F029 +:105E2000D4FE386890F8C81890F8C90805EB40000F +:105E300000F0E2FE2549304601F01AFD0020BDE8E1 +:105E4000F0810120FBE730B51E494FF480750A68E8 +:105E500092F8071192F8F43092F8F14003F01F0322 +:105E600004F00F04A94200D929461F2B00D91F2393 +:105E70005B1C59434900641C6143C1EB4121C913B8 +:105E800092F8873AB1FA81F1C1F120019B0713D54D +:105E90000023012809D192F88B0A020703D500F0EC +:105EA0000700434201E000F00703C91801D50021B3 +:105EB00002E01F2900DD1F21C8B230BDF08601209D +:105EC000108F100004071000148D1000A95C010051 +:105ED0002DE9F05FDFF8A48583464FF00109D8F87B +:105EE00000000027ABF1020100F25E64CA460629F9 +:105EF00050D2DFE801F04F092C4F2C0310F8D46F7B +:105F0000007900F01F056DE090F8F41090F8026140 +:105F100001F01F0590F8F11001F00F0790F8E6105E +:105F2000890609D590F8501690F851060A2204EB1C +:105F3000400000F027FE8146D8F8000090F8E610F7 +:105F400049064FD590F8CA1890F8CB0844E090F86D +:105F5000FC1090F8F86001F01F0590F8F91001F0BE +:105F60000F0790F8E610890609D590F8521690F8B8 +:105F700053060A2204EB400000F004FE8146D8F8E4 +:105F8000000090F8E61049062CD590F8CC1890F84F +:105F9000CD0821E090F8F41090F8F06001F01F05B2 +:105FA00090F8F11001F00F0790F8E610890609D576 +:105FB00090F84E1690F84F060A2204EB400000F0CD +:105FC000E1FD8146D8F8000090F8E610490609D5B1 +:105FD00090F8C81890F8C9080A2204EB400000F0B5 +:105FE000D1FD82464FF48070864200D906461F2DAF +:105FF00000D91F256D1C6E4370007F1C7843C0EBD9 +:10600000402000FB09F000FB0AF0C013D8F8002084 +:10601000B0FA80F0C0F1200192F8870AC00725D0BD +:106020000020BBF10A0F13D2DFE80BF01205080BBA +:1060300016121212120592F8880A04E092F8880AE1 +:106040000CE092F8890A020700F0070000D54042F0 +:10605000091808D5002109E092F8890A0206C0F360 +:106060000210F4D4F4E71F2900DD1F21C8B2BDE8F7 +:10607000F09F70B5060003D0BDE8704000F0F4BC9E +:1060800000F018F8012814D1FD4DFE4C28780128A5 +:1060900009D0FD48A0606878E073E878A07328898B +:1060A000A0813046E8E76A792979F74800F0F9FDE0 +:1060B000F0E770BDF24B10B5D978F44C491CCAB268 +:1060C000DA70997801208A420ED8197958794143BB +:1060D000ED48FDF7CAF801F085F9A4F87600EC491F +:1060E000204601F0C5FB002010BD38B5044601F084 +:1060F00074F9E54801F076F9A4F8760000F02CFD7B +:10610000DE4D0B462A6892F8E720C2F34112009256 +:106110000246204601F04BFB00F023FD02460B46F1 +:10612000204601F070FBA07920F00200A07194F8E5 +:106130006F0020F0070084F86F0094F86E0020F0E4 +:106140000F0084F86E00286890F8E700C0F3411152 +:10615000204601F072FB286890F8E70010F0600F0D +:1061600094F85E007ED040F0010000BF84F85E002D +:10617000204600F0B7FD0521204601F05EF92868B1 +:1061800090F8F000A0702868218EB0F8F62062F335 +:106190000801218690F8F10000F00F01204601F07F +:1061A000C3F92868627D90F8EA1061F30302627512 +:1061B000B0F8EC20218A62F30B01218290F8F210F2 +:1061C000A27D61F30302A27510F8F11F0A09A17CF8 +:1061D00062F30101A17410F80B29920962F387118F +:1061E000A1740178E27961F30002E271C178617211 +:1061F00000790109204601F0A3F9A64801F0F2F860 +:10620000A4F87C00296811F8E80F820814F8270F19 +:1062100062F38300207011F8012962F300002070FE +:106220004A78520862F341002070087801096078CA +:1062300061F304106070984801F0D4F8A4F85F008E +:10624000286810F8E61FCA0814F80C1F62F34511FD +:1062500004F80B194078217860F3451104F82819E7 +:10626000204600E05CE000F0F1FC286890F8E700D0 +:10627000C0F34101204601F031F9286810F8E61F0B +:106280008A0914F8331F62F3000104F80B1902782D +:10629000520962F34101E172417B627961F30402C8 +:1062A0006271807B217960F304017C48217194F84C +:1062B0003710407860F3040184F83710784801F013 +:1062C00091F8A4F85200286834F8061FB0F8EE20C0 +:1062D00062F30B0124F8061B10F8E21F14F80A2CD5 +:1062E00061F3030204F80A2C01780A0914F8091C66 +:1062F00062F3030104F8091C01798A0814F80C1CE4 +:1063000062F3000104F80C1C0079C109207861F3E4 +:10631000000004F82B0B207840F02000207038BDDE +:1063200020F0010022E738B5044601F056F856483F +:1063300001F058F8A4F8760000F00EFC4F4D0B4623 +:106340002A6892F8C920C2F3411200920246204600 +:1063500001F02DFA00F005FC02460B46204601F044 +:1063600052FAA07920F00200A07194F86F0020F09A +:10637000070084F86F0094F86E0020F00F0084F896 +:106380006E00286890F8C900C0F34111204601F062 +:1063900054FA286890F8C90010F0600F94F85E0075 +:1063A0006BD040F0010000BF84F85E00204600F092 +:1063B00099FC286890F8D400A0702868218EB0F865 +:1063C000DA2062F30801218690F8D50000F00F0171 +:1063D000204601F0A9F82868627D90F8CC1061F39E +:1063E00003026275B0F8CE20218A62F30B0121828C +:1063F00090F8D610A27D61F30302A275B0F8D02008 +:10640000A18962F30B01A18110F8D51F0A09A17CB3 +:1064100062F30101A17410F80D29920962F387114A +:10642000A1740178E27961F30002E271C1786172CE +:1064300000790109204601F083F8164800F0D2FFE8 +:10644000A4F87C00296811F8CA0F820814F8270FF5 +:1064500062F38300207011F8012962F300002070BC +:106460004A78520862F34100207008780109607888 +:1064700061F304106070084814E086E0040710001F +:10648000D4071000108F1000208801205C8E1000AF +:1064900023600100EC6F01205C80012022A101201B +:1064A000A47C012000F09EFFA4F85F00286810F88B +:1064B000C81FCA0814F80C1F62F3451104F80B1921 +:1064C0004078217860F3451104F82819204600F03F +:1064D000BDFB286890F8C900C0F34101204600F0D8 +:1064E000FDFF296811F8C80F820914F8330F62F311 +:1064F000000004F80B090A78520962F34100E072C7 +:10650000C87B627960F304026271087C217960F3D0 +:106510000401F548217194F83710C07960F3040143 +:1065200084F83710F14800F05DFFA4F852002868A5 +:1065300034F8061FB0F8D22062F30B0124F8061BD2 +:1065400010F8E21F14F80A2C61F3030204F80A2C75 +:1065500010F81A190A0914F8091C62F3030104F867 +:10656000091C01788A0814F80C1C62F3000104F875 +:106570000C1C0078C109207861F3000004F82B0B93 +:10658000207840F02000207038BD20F001000BE79B +:1065900010B50446A422D64902F00BFED548C178B6 +:1065A000A08961F30B00A08110BD38B50446FFF748 +:1065B000EFFF00F0D1FA0022009202460B4620467F +:1065C00001F0F5F8CC4800F00DFFCC4DA4F87C00AC +:1065D000286890F8F800A070286890F8F90000F09A +:1065E0000F01204600F0A0FF286810F8F91F0A09E3 +:1065F000A17C62F30101A1740278920962F3871110 +:10660000A174817894F82D2061F3040284F82D2080 +:10661000C17894F82C2061F3040284F82C2040788F +:10662000A17D60F30301A1750021204601F005F969 +:1066300014F85E0F20F0010004F8010BAA4801795C +:10664000207861F3040004F82F092868B0F8FE10E0 +:10665000208861F30800208038BD70B5A74E03285C +:10666000346804F25E6204F6D80515D0042821D0FF +:1066700094F84F0694F84E1602EB400000F0A5FA8D +:10668000306890F8C81890F8C90800BF05EB4000C2 +:10669000BDE8704000F0B0BA94F8510694F8501676 +:1066A00002EB400000F091FA306890F8CA1890F8B8 +:1066B000CB08EBE794F8530694F8521602EB40002F +:1066C00000F083FA306890F8CC1890F8CD08DDE738 +:1066D0002DE9F8438A4D4FF00109002685F8009016 +:1066E000AE70814FDFF814820446EE700A2976D22C +:1066F000DFE801F07505091848334C62662F204623 +:10670000FFF746FF6BE02046FFF742FFB87894F8AA +:106710005F1060F3040184F85F10D8F8000090F86F +:10672000000112E02046FFF733FFD8F8001091F87F +:106730000211A170F97894F85F2061F3040284F8E3 +:106740005F20D8F8000090F8010100F00300A87065 +:1067500045E0204600F09DF841E02046FFF718FF95 +:106760000021204600F0E0FE94F85E0020F00100D9 +:1067700084F85E00787994F85F1060F3040184F87F +:106780005F1017E02046FFF710FF28E02046FFF7D4 +:106790000CFF0021204600F0C7FEB87994F85F1086 +:1067A00060F3040184F85F1094F85E0020F00100AB +:1067B00084F85E002E7012E02046FFF7B4FDF9E782 +:1067C0002046FFF7E5FE012200232046009600F058 +:1067D000EEFF204600F0C7FA204600F037FA94F8A2 +:1067E0002700C00701D06E7001E085F80190A089F4 +:1067F000C0F30B002881BDE8F8832DE9FF4100F0CC +:10680000ABF9CDE9000100F0ACF9CDE902010821B6 +:10681000684601F061FA3A4D0821287102A801F09A +:106820005BFA687130480026801E2F4F40F8026FD7 +:10683000012446600681E0B2FFF74AFB3855641C2C +:106840000A2CF8DB2A48FFF750FCAE71BDE8FF8147 +:1068500070B5274D0479A4358CB121462846FFF741 +:1068600037FFA87C00F0030000F0DEF92046FFF7B8 +:10687000F4FE2449284600F0FBFF002070BD0120F3 +:1068800070BD40F2FF10C1EB412191FBF0F0002000 +:10689000704770B50446FFF77BFE1848184A016838 +:1068A00001F5F97391F8F10100F0030592F9060082 +:1068B000854206DB1D5CA389401C65F30B03A381A5 +:1068C000907191F8F10192F9061000F003008842EE +:1068D00001DA00209071044814F85F1F407A60F3D9 +:1068E0000401217070BD000022A10120A47C0120C0 +:1068F000B88D100040071000147501200407100027 +:10690000D40710002360010010B500F079FAFFF7FA +:1069100074FFFFF761FAFFF778F9FEF749FDFEF71C +:1069200017F9FEF79CFD74490020486070217348F8 +:1069300002F0BEFC7248016891F8E700C00607D576 +:10694000BDE8104028226D4801F65A1102F031BC12 +:1069500010BD38B1012807D0022807D01720002128 +:10696000FBF7E5BC1420FAE71520F8E71620F6E758 +:106970000021016041608160C160704770B55E4C6C +:10698000604D206809E000BF55F820105E48884738 +:10699000002811D02068401C20600828F4D36068CB +:1069A0005949401C1031002260600A704860564806 +:1069B000016810308847012070BD70B50446007929 +:1069C000002550B9E07940B9A07930B9E07A20B912 +:1069D000207A10B9607900280ED04B484021103041 +:1069E00002F088FC1ECC484880E81E004248056042 +:1069F0004548FFF7C3FF012070BD10B5012000F02E +:106A000064F8072000F061F8082000F05EF8052027 +:106A100000F05BF80D2000F058F80C2000F055F85D +:106A2000012000F05DF8072000F05AF8082000F07F +:106A300057F8052000F054F80D2000F051F80C2014 +:106A400000F04EF802F0CFF800F0BFFC012000F09B +:106A500031F8072000F02EF8082000F02BF8BDE8F0 +:106A60001040052000F026B870B5234C05000ED06C +:106A7000FFF7C3FF60682449401C103160600D704F +:106A8000486021480168BDE8704010300847206820 +:106A9000401C2060BDE870401B486FE700F05CB808 +:106AA00000F05FB800F062B800F066B800F054B8CB +:106AB00000F057B800F01F0201219140400980000A +:106AC00000F1E020C0F80011704700F01F02012122 +:106AD00091404009800000F1E020C0F8801170472B +:106AE00000F01F02012191404009800000F1E020E8 +:106AF000C0F8801270470000E00710005C800120A1 +:106B00000407100030980100008F100070B50023BA +:106B1000144609E031F9135031F9146035446D1011 +:106B200020F813505B1C641C9342F3DB70BD30B43F +:106B300000244BB90CE000BF30F8143031F8145089 +:106B40002B4420F81430641C9442F5DB30BC7047B1 +:106B500030BC520002F02DBBA2480068C16A806AB6 +:106B60007047A0480068416A006A70479D48006805 +:106B700000F67C2003C870479A48006800F674202D +:106B800003C87047F0B500242546974E4FF40067C0 +:106B900014E000BF30F81530C3F30B035FEAD32CC9 +:106BA00000D03343002B00DA5B429C4200DA9CB2F7 +:106BB000BC4202D340F2FF7402E06D1C8D42E9DB5F +:106BC000D4400120A04080B2F0BD30B5884B874C46 +:106BD0005A68824202D1DA688A420AD0002206E06C +:106BE00030F81250C5F30B0524F81250521C8A429B +:106BF000F6DBD960586030BD30B57D4B7D4C9A686E +:106C0000824202D11A698A420DD0002207E000BFF9 +:106C100030F81250C5F30B0524F81250521C8A426A +:106C2000F6DB1961986030BD70B5044672480168A2 +:106C300002290AD16E4D29788C4206D000EB8400DF +:106C4000D0F89C0000F0E1FB2C7070BD10B504463C +:106C500090F82800800604D5684800F0C3FBA4F82B +:106C60008C0010BD10B5044690F8280080060AD5A7 +:106C70006248283000F0B6FB24F88E0F5F48483099 +:106C800000F0B0FB608010BD10B5044690F82800FD +:106C9000800605D55948703000F0A4FBA4F88E009A +:106CA00010BD70477047704702004FF0000000D1E0 +:106CB0000846704702460020012A00D10846704766 +:106CC00010B5044690F8280080060AD54B4890304D +:106CD00000F088FB24F88E0F4848B03000F082FBAB +:106CE000608010BD3F490A6892F8B020930910F8FF +:106CF0003E2B63F3820200F83E2C0B6893F8B03011 +:106D00005B0963F3451200F83E2C0968B1F8B7201F +:106D1000028291F8B620837F62F30713837791F89C +:106D2000B3201309027D63F30612027531F8B13FF7 +:106D3000028B63F30902028311F8012C9308827D10 +:106D400063F3861282758A78C37D62F30303C37589 +:106D5000B1F80330B0F81B2063F30802A0F81B2041 +:106D600009894182704710F8371F41F0100100F87F +:106D70001F1930F80C2CC17E6FF30B02103220F873 +:106D80000C2C30F8082C21F023016FF30B02403259 +:106D900020F8082C082200F8162C90F8472041F023 +:106DA0000C0122F01F0280F84720028B6FF30802CB +:106DB0000283C176C18A6FF30B013F31C182417DED +:106DC00021F01F014175017D21F01F01017590F82F +:106DD000461021F0010180F84610017C41F02001AD +:106DE000017470470407100000F0FFFFA47C01202D +:106DF000E8071000A47E0120508F1000847F01203E +:106E0000704710B500F095FD08B1012010BD08488D +:106E100000F078FD002010BD064810B5006890F81D +:106E20007000400701D500F079FD012010BD000081 +:106E3000196A0100040710003D48016821F00401AF +:106E4000016000F009BF10B5FFF7F6FF10BD10B5E7 +:106E5000FFF7F2FF10BD10B5FFF7EEFF10BD10B544 +:106E6000FFF7EAFF01F08DFC10BD10B5FFF7E4FF5E +:106E700000F0D8FA10BD10B5FFF7DEFF01F097FD66 +:106E800010BD10B5FFF7D8FF01F0FCFD10BD10B527 +:106E9000FFF7D2FF01F061FE10BD10B5FFF7CCFF88 +:106EA00001F0C8FE10BD10B5FFF7C6FF01F041FFAD +:106EB00010BD10B5FFF7C0FF01F0A8FF10BD10B561 +:106EC000FFF7BAFF02F00FF810BD10B5FFF7B4FFDF +:106ED00002F0E8FA10BD10B5FFF7AEFF02F0BEFAFF +:106EE00010BD10B5FFF7A8FF10BD10B5FFF7A4FF48 +:106EF00010BD10B5FFF7A0FF10BD10B5FFF79CFF48 +:106F000002F038F810BD10B5FFF796FF10BD10B5B0 +:106F1000FFF792FF10BD10B5FFF78EFF10BD10B543 +:106F2000FFF78AFF10BD10B5FFF786FF10BD704751 +:106F300010ED00E00EB5002000900190029009488D +:106F400000F033FE684600F034FEFBF7DDFFFBF790 +:106F500015FE00F031F800214720FBF7E8F9012089 +:106F60000EBD0000600060221A4910B501200870B3 +:106F70001949002008601949086019490860194931 +:106F8000086000F07FF900F019F900F07DF80020AA +:106F900010BD10B5124802F07FF8104908600E4984 +:106FA0000968884207D00B480078022803D1BDE861 +:106FB0001040E9F7DBB910BD10B5FFF7EAFF05494E +:106FC00002200870E9F7B6F94FF0FF3010BD01203C +:106FD0007047000044081000480810004C081000DA +:106FE000500810005408100070B50D460446C169E1 +:106FF0008068CC2202F054F9E169A06800220844BC +:107000004FF0807140F8041C216A40E9032140F8E8 +:10701000102C40F8142C40F8182C40F81C2C4FF081 +:107020000B3140E909154FF00A3140F8281C4FF0A8 +:10703000093140F82C1C4FF0083140F8301C4FF05B +:10704000073140F8341C4FF0063140F8381C4FF03F +:10705000053140F83C1C4FF0043140F8401D70BD34 +:1070600081694FF0CC330A689A4208D14A689A4243 +:1070700005D18A689A4202D1C968994202D0406813 +:10708000FBF7C3BD7047000010B5A021494802F0CE +:1070900031F9002010BD70B50646464800EB0614D5 +:1070A000E9F79CF90546207828B12846E9F79EF9CA +:1070B0006FF0010070BD0320207000206660E0606A +:1070C00004F1080001F0C2FF2846E9F78FF900201B +:1070D00070BD2DE9F0410F463649002501EB001443 +:1070E0002E46E9F77BF98046E0683843E06004F11A +:1070F0000800074601F0D0FF0CE0E168C26A1142C7 +:1071000003D000F00FF9012600E06D1C2946384637 +:1071100001F0B8FF0028F0D10EB1FFF73AFF40466A +:10712000E9F764F90020BDE8F08170B50D4621490A +:1071300001EB0014E9F752F9E168A943E160E9F7CE +:1071400055F9002070BD70B50C461A4901EB0015C9 +:1071500000202060E9F742F9E9682160E9F746F983 +:10716000002070BD2DE9F0410D4612491E469046A3 +:1071700001EB0014E9F732F907460F480068C562D1 +:10718000E168294203D104F1080100F0DDF8384636 +:10719000E9F72CF9E9F722F9E16829403160B8F103 +:1071A000010F02D1E168A943E160E9F71FF900206E +:1071B000B9E70000FC8F10004808100010B5C82186 +:1071C0002E4802F097F8002010BD2DE9F041064648 +:1071D0002A4900EB8600174601EB8004E9F7FEF828 +:1071E0000546207830B12846E9F700F96FF0010034 +:1071F000BDE8F0810220207000206660C4E90270C2 +:1072000004F1100001F022FF2846E9F7EFF8002012 +:10721000EEE770B5194900EB800001EB8004E9F757 +:10722000DDF80546D4E90201814205DB144804F18A +:107230001001006800F088F8E068401CE060284613 +:10724000E9F7D4F8002070BD70B50C4900EB800060 +:1072500001EB8004E9F7C2F80546E06808B1401E7A +:10726000E06004F1100001F017FF10B1206900F098 +:1072700011F82846E9F7BAF8002070BD9C9010007C +:107280004808100010B54FF4F0713C4802F032F895 +:10729000002010BD10B5044690F8240002280BD041 +:1072A000204601F0FBFE022084F8240034492046E9 +:1072B00001F0D0FEFFF76DFE002010BD2DE9F05F5C +:1072C00006460AA806EB460190E8000E2B481D462C +:1072D00000EB01149046207818B16FF00100BDE872 +:1072E000F09FE9F77BF8074601202070C4F814806E +:1072F000C4E9016504F11801002081E8200684F842 +:107300002400E0602061C4E90A8059462046FFF766 +:107310006BFEA0602046FFF7BDFF3846E9F766F830 +:107320000020DCE710B5044690F82400022809D0BC +:10733000204601F0B3FE022084F8240010492046C4 +:1073400001F088FE002010BD70B5044690F82400BE +:107350000D4602280BD1204601F0A0FE032084F840 +:1073600024002946204601F075FEFFF712FE00209A +:1073700070BD0448006840687047000064911000C8 +:107380005008100048081000724810B50021016034 +:10739000012202600160704C6920A0710420E9F7AD +:1073A0002FF80820A07110BD10B5FFF7EDFF6B4856 +:1073B00000210170416000F0F6F9BDE8104000F0D6 +:1073C000E2BA01F0FCBC01F067BD10B501F064FD4C +:1073D00001F0F5FCBDE81040E6E7A422604901F0A9 +:1073E000E8BE704710B50446800702D00220FFF7C0 +:1073F000B0FA4FF480302044C0F34F0010BD014676 +:1074000055489822A43001F0D4BE534AA43200213A +:1074100042F82100491C2629FADB704701F019BD0A +:1074200001F097BC4D4810B5406810B1BDE8104060 +:1074300000470020FFF78DFA10BD062937D2DFE89C +:1074400001F0112437243603017821F0120100F8ED +:107450004D1B017821F0030100F8071B017821F092 +:1074600080010CE0017821F0020141F0100100F8E8 +:107470004D1B017821F0030100F8071B12E000F812 +:10748000441B017821F0010110E00278012942F04B +:107490001202027000D0032110F84D2F61F3010297 +:1074A00000F8072B017841F08001E8E70170704790 +:1074B000017821F0020141F0100100F84D1B017824 +:1074C00021F00301891C00F8071B017841F08001BD +:1074D00000F8441B017841F00101E7E790F829200A +:1074E000022904D0032922F0400102D104E042F035 +:1074F000400121F0800101E041F0800180F8291075 +:10750000704790F82920012904D0022907D022F0E1 +:10751000100101E042F0100121F0200101E042F0F1 +:10752000300180F829107047C278002961F3030206 +:10753000C27004D010F85E1F41F004010170704762 +:10754000C27A012961F30302C27202D942F010012A +:10755000C17270479004002200000320FC07100055 +:107560005098010001EB810102EBC101405C010672 +:1075700002D500F07F0040427047002B04DA5B42E6 +:10758000DBB243F0800301E003F07F0301EB8101F4 +:1075900002EBC101435470472DE9F05F0025DDE99E +:1075A0000A7891469A4683462E462A4601200021B3 +:1075B00001F0C8FD00EA090001EA0A01084314D0FD +:1075C000002422460120002101F0BCFD384001EAE0 +:1075D0000801084305D00023224631465846FFF7EC +:1075E000CCFF641C282CECDB761C6D1C382DDCDBFE +:1075F000BDE8F09F405C010602D500F07F004042EC +:107600007047002A04DA5242D2B242F0800201E00E +:1076100002F07F0242547047F0B5002415460E4632 +:107620008446234601270FE006EBE30003F0070141 +:10763000007807FA01F2024205D00022194660469E +:10764000FFF7DFFF641C5B1CAC42EDDBF0BD405C70 +:10765000704742547047F0B50024234601260DE0E0 +:1076600001EBE30503F007072D7806FA07FC1CEA97 +:10767000050F02D00025C554641C5B1C9442EFDB4F +:10768000F0BD405C704742547047405C70474254C4 +:10769000704700002DE9F047334C54F83C8F676881 +:1076A000E668257CDFF8C4900121C9F800104FF48A +:1076B0002070E8F7A5FE0021C9F80010C4F800808A +:1076C0006760E6602574BDE8F08727480021C16344 +:1076D0000164816480F84C10704770B500240D4639 +:1076E00002460120214601F02DFD35B31E4A4832E5 +:1076F00010601171FFF7CEFF002000F023F800B1F9 +:107700000124FFF7C7FF012000F01CF808B144F086 +:107710000204FFF7BFFF022000F014F808B144F0A4 +:107720000404FFF7B7FF032000F00CF808B144F0A1 +:107730000804FFF7AFFF204670BD0B4A3C32C2E998 +:107740000001D7E740F02001074810B580F8A310EA +:10775000E52181714FF42070E8F752FE0448D0F81B +:10776000C002C0B210BD00000000032068146022F7 +:107770000010602253480168002901D00120084709 +:10778000704710B5FFF71FFE4F49022008704F49A0 +:10779000002008604B480168002903D0BDE8104074 +:1077A0000020084710BD47490020086070477FB59A +:1077B00004460399089DC1F314010391082102A80E +:1077C00000F08AFA012D02D0022D04D006E0C01C80 +:1077D00020F0010002E0C01D20F00300DDE90212EC +:1077E00044F83C1F6260217A60F3060121727FBD7C +:1077F000012340F83C3F002343605143027A61F388 +:107800000602027270471FB50446039902A801F0F0 +:107810003F010391082100F05FFADDE90212A16443 +:1078200084F84C2014F8701F60F3050104F81E1949 +:10783000E17F60F30501E1771FBD08B524A212685E +:1078400000921DF8012010F85D1F62F30101017024 +:1078500008BD1D49032008701C491E4808601E49C8 +:107860000120C1F8C0001D494FF4FA70FFF7D6BDE2 +:1078700010B50B46817921F00D0141F0E0018171D5 +:10788000817C8A091BD08A0962F3871181740D49B2 +:107890000D4A0B60032111700C4A0E49116001461C +:1078A000A4220F4801F085FC0B490120C1F8C0005B +:1078B000BDE8104009494FF4FA70FFF7AFBD01224F +:1078C000E2E7000004081000FC07100000081000A8 +:1078D00000010200337701000000602225770100DB +:1078E0000000032016480178012908D10221017007 +:1078F0001448016819B100220260104608470120AF +:10790000FFF727B80E4A012111700E4908600E4991 +:10791000E82088710D490C20FFF782BD0A49082034 +:1079200088710B4900200862054908700549086004 +:10793000704703480078002800D0012070470000FD +:10794000FC071000080810000000032095780100D3 +:107950000000602268480168002901D00120084722 +:10796000704710B5FFF72FFD644902200870644985 +:107970000020086060480168002903D0BDE810407D +:107980000020084710BD5C490020086070477FB5A3 +:1079900004460399089DC1F314010391082102A82C +:1079A00000F09AF9DDE90212E163226494F84420C0 +:1079B000C1B261F3060284F844200A2D0FD00B2DCA +:1079C0000DD014F8720F61F305002070607861F338 +:1079D00005006070A07820F00800A0707FBD14F84A +:1079E000721F401C60F305012170617860F305018E +:1079F0006170A07840F00800EFE71FB504460399D6 +:107A000002A801F03F010391082100F065F9DDE9CA +:107A10000212A16484F84C2014F8701F60F3050171 +:107A200004F81E19E17F60F30501E1771FBD30B551 +:107A300034A28CB03CCA8DE83C0036A20DF1100C8B +:107A40003CCA8CE83C0037A20DF1200C3CCA8CE803 +:107A50003C0004AA535C427E63F3050242761DF8A3 +:107A60000130027E63F34202027608AA525C8179F9 +:107A700062F3830181710CB030BD2049042008708D +:107A80001F492C4808602C490120C1F8C0002B492F +:107A90004FF4FA70FFF7C2BC10B50B46B0F85610A1 +:107AA00041F00101A0F85610817C8A0921D08A0991 +:107AB00062F3871181748179104A21F0010141F04C +:107AC000E00181710C490B60042111700C4A1949C5 +:107AD00011600146A4221A4801F06BFB16490120EF +:107AE000C1F8C000BDE8104014494FF4FA70FFF728 +:107AF00095BC0122DCE700000C081000FC07100018 +:107B00000008100000000202010103030303000249 +:107B1000000000000202020202020202010102024F +:107B20000101000002030203020302030203020236 +:107B300002030000137901000000602205790100B2 +:107B4000000003204E49012008601722410701F878 +:107B5000272F0B2281F841204949183908604FF03E +:107B60000851C1F8C403464B0022B0331A60454A9D +:107B70001060121D1060424A943A1060C1F8680308 +:107B8000C1F8740370473E4901209439086070477A +:107B90003B4900209439086070474FF0005000883E +:107BA00070474FF00050807870474FF000514860A8 +:107BB0007047354902680A6042684A608068886098 +:107BC000704731490A6802604A684260896881608A +:107BD00070472B4901203039086070474FF0005042 +:107BE00010F8221F21F00301017070474FF000537D +:107BF00003F81F0F5970987862F30300987070476C +:107C000022480068704721490860704710B54FF05E +:107C10000054E27E202322F0AF0203EA4013134314 +:107C2000042202EA8000034301F003000343E376E9 +:107C300010BD4FF0005090F8220010F0030005D066 +:107C4000012805D0022805D0114870471148704717 +:107C5000114870471148704770477047104901201C +:107C6000C1F8DC0070470E490020C1F8DC00704705 +:107C70000348F030006808B10120704702207047C7 +:107C8000CC040022801E00220800002010081000F2 +:107C900000127A000090D0030048E8010024F400AC +:107CA00000006022F0B50746002003462F4E10E08A +:107CB00057F8235003224FEAC20C45FA0CF484EA29 +:107CC0002064E4B2521E56F8244084EA0020F2D523 +:107CD0005B1C8B42ECDBF0BD30B50446234B00202F +:107CE000103B08E0625C02F00F0503EB12125D5DD1 +:107CF000127828441044491EF4D230BD10B584686F +:107D00000368E443A3420AD1C4684368E443A3423E +:107D100005D15B1C0B6000681060012010BD0020C5 +:107D200010BD3CB50446002501AA6946FFF7E6FFF1 +:107D3000012809D1009904F11000091FFFF7B2FFD3 +:107D40000199884200D1012528463CBD30B50D4639 +:107D50000446091F1030FFF7A5FF6D1E6560E9435B +:107D6000E1602060C043A06030BD000004990100C4 +:107D700001468000B1F5803F02D21038C0F31000F8 +:107D80007047C0F387207047B0F5802F02D21030C3 +:107D9000C0F31000C0F38F00704730B5FE4C0125D2 +:107DA0002560E50603F01F0385F86B30002304E02F +:107DB00051F8235040F823505B1C9342F8DB00201D +:107DC000206030BDF0B5F44F01233B605C0784F8C0 +:107DD0006B309B1E0360002312E051F8234040F8F3 +:107DE0002340002450F8235051F82360B54206D0B8 +:107DF0006D1C04D1641C40F82360032CF2D35B1C7F +:107E00009342EADB00203860F0BDF0B513460A4625 +:107E10000546002498184FF48326602801D90124D0 +:107E200011E0002107E05F1856F82700401C01D040 +:107E300011460224491C9142F5D324B906EB830074 +:107E40002946FFF7BFFF2046F0BD10B503460846A0 +:107E5000FFF78EFF0146BDE810409200184601F082 +:107E6000EDB92DE9F0414FF000580C46D8F81470E8 +:107E70000125C0F38F066FF48041C8F814100E205E +:107E800000F013FA204600F01BFA0200C3484FF03E +:107E9000010118D00160A4F58034404620F8726FCB +:107EA0004480602200F8012CBD4A1160BB4AC432F4 +:107EB000116030BF81797238890700D00025476191 +:107EC0002846BDE8F08100220260E6E72DE9F05F78 +:107ED0001546DFF8C4B2002601270A4604464FF0D3 +:107EE000005CB1F5882F15D3A30AFFF741FF59466F +:107EF000CBF8007003F01F038CF86B30002304E014 +:107F000052F8234040F823405B1CAB42F8DB0E6084 +:107F1000BDE8F09FDCF81490C1F38F08E2466FF4DF +:107F20008041CCF814100E2000F0BFF9CBF800709F +:107F3000204600F0C5F90100984819D00760A4F563 +:107F40008034AAF87280AAF874406D1EAAF87650A0 +:107F500040218AF8711092490E609049C4310F6037 +:107F60000AF1520030BFCBF8006040F83E9CCFE7EA +:107F70000660E6E72DE9F0414FF000540F4654F853 +:107F8000146F85086FF4804020600E2000F08DF99A +:107F90000020A066A4F85E507F1EA4F8627084F8EA +:107FA0005D007F4908607D490120C431086030BF11 +:107FB000E06E266085E770B506460C4601F11000BC +:107FC000111F154689B2FFF7D5FF2060681E60605B +:107FD00020682A46C043A06060682146C043E06034 +:107FE0003046BDE8704071E7F0B507460020044612 +:107FF0006C4E15E057F8245003234FEAC30C45FAA2 +:108000000CF280EA02600822002802DA86EA4000C8 +:1080100000E04000521E002AF6DC5B1EEDD5641C19 +:108020008C42E7DBF0BD30B550F8084B50F8085BE8 +:1080300030F80C1C491C89B2FFF7D6FF844204D1EA +:10804000E043854201D1012030BD002030BD2DE943 +:10805000F0410126750704466F696FF4804068613E +:108060000E2000F022F94FF00008C5F87C80204671 +:1080700000F026F9020049494FF0010015D00860D0 +:10808000A4F58034A5F87440202185F87110444986 +:1080900008604249C431086030BF95F87800800715 +:1080A00000D000266F6130460BE7C1F80080E9E799 +:1080B00000B50B46FFF75CFE82680168D24391422F +:1080C00008D14268C068C043824203D1521C1A8062 +:1080D000012000BD002000BDF8B5044610300D465B +:1080E0000646FFF7BEFE012801D00020F8BD694614 +:1080F0002846FFF7DDFFBDF80000001F81B23046C3 +:10810000FFF738FF2060BDF80010C043491E6160D2 +:10811000A060C843E0600120F8BDF0B5B1B00746EB +:108120006D46214E0124C021284601F0E3F80020CD +:1081300056F8201045F82010401C3028F8D31B4971 +:108140000098884210D1029881B205A80446FFF732 +:108150004BFF0199814206D1AC222146384601F0FD +:108160006DF8002400E0032431B02046F0BD70B566 +:1081700094B004466D460E4E5021284601F0BAF8E0 +:10818000002056F8201045F82010401C1428F8D381 +:1081900008486FF002050FE0C41B0022780D002292 +:1081A0001C0F00221B000080481D0400B2570E70F7 +:1081B000AC1E04005C000D60009981422ED1A81015 +:1081C00020606060A060E0602061029881B205A834 +:1081D000FFF70AFF0199814220D1BDF8381045F21E +:1081E000AA5081420CD19DF81D1021609DF81C10F1 +:1081F00001F00F0161609DF81E1001F00F01A160F8 +:10820000BDF83C10814201D10899E160BDF84010F1 +:10821000814201D10998206114B070BD256065606C +:10822000A560E5602561F7E770B586B004466D4648 +:10823000274E1421284601F05DF8002156F8210050 +:1082400045F82100491C0529F8D3009820600198C1 +:1082500060600298C0B2A0600398C0B2E060049869 +:10826000C0B2206106B070BD1CB50020184A009055 +:10827000843A6B460146019052F8214043F8214070 +:10828000491C0229F8D3BDF80010A1F5AA42AA3A68 +:108290000AD1BDF80420114206D19DF802109DF8C4 +:1082A0000620114200D108461CBD00F01F0201212A +:1082B00091404009800000F1E020C0F88012704732 +:1082C000B0F5803F01D200207047012070470000C8 +:1082D000601F04004FF00050002180F83D1080F82E +:1082E0003E1080F83F103F2280F8322000F8301F07 +:1082F000027141714270017241728172C172C17129 +:1083000070474FF00052062817D2DFE800F003064E +:10831000090F171A12F83D0F04E012F83D0F07E09D +:1083200012F83E0F20F00F00084305E012F83E0F50 +:1083300020F0F00040EA01101070704712F83F0F73 +:10834000F0E712F83F0FF3E730B50D460121814009 +:10835000CCB20021FFF7D5FF29784FF0005000295B +:1083600090F8321001D0214300E0A14380F8321090 +:108370006978002990F8301001D0214300E0A14332 +:1083800080F83010A978002990F8341001D02143EA +:1083900000E0A14380F83410E978002990F8351006 +:1083A00001D0214300E0A14380F83510297900294C +:1083B00090F8311001D0214300E0A14380F8311042 +:1083C000002180F8381080F8391080F83A1080F8D1 +:1083D0003B1080F8371030BD774A1160764A002193 +:1083E00034321160121D08B1116070470120106015 +:1083F000704730B501248440E0B24FF000540029AA +:10840000039D94F8321001D0014300E0814384F8C9 +:10841000321094F830100AB1014300E0814384F82F +:10842000301094F834100BB1014300E0814384F81C +:10843000341014F8351F0DB1014300E08143217061 +:1084400030BD01238340D8B24FF00053002993F888 +:10845000381001D0014300E0814383F8381013F84D +:10846000391F0AB1014300E08143197070470123AD +:108470008340D8B24FF00053002993F83A1001D04E +:10848000014300E0814383F83A1013F83A1F0AB120 +:10849000014300E08143197070472DE9F04705461C +:1084A0000120A840C4B21F46914688460A20DDF844 +:1084B00020A000F06BF80B2000F068F80A2000F014 +:1084C00070F80B2000F06DF84FF0005696F8380069 +:1084D000A04386F8380096F83A00A04386F83A00A0 +:1084E00096F82E00A04386F82E00344A0020B8F1FA +:1084F000000F42F825000BD096F83810214386F87B +:10850000381096F83A10214386F83A1042F8257050 +:1085100096F83910A14386F8391096F83B10A1431C +:1085200086F83B1096F82F10A14386F82F102349A8 +:108530002031B9F1000F41F825000BD096F8390031 +:10854000204386F8390096F83B00204386F83B002C +:1085500041F825A096F8380010B10A2000F00BF879 +:1085600096F83900002804D0BDE8F0470B2000F051 +:1085700002B8BDE8F08700F01F02012191404009D8 +:10858000800000F1E020C0F80011704700F01F02E9 +:10859000012191404009800000F1E020C0F88011E5 +:1085A000704700F01F02012191404009800000F156 +:1085B000E020C0F8801270470405002244931000A8 +:1085C0002DE9F047417ACA074FF0000101D0554A22 +:1085D000516001277D0785F8E57085F8E470C5F8DE +:1085E000C010C5F8E81085F8E11085F8E310DFF851 +:1085F00038A1067A04680AF10709072E00D9072670 +:1086000000216DE04A1CD3B201EB810214F8028014 +:108610000AF80180D0F804C022443CF8118029F8FF +:10862000118092F803C0BCF1010F02D0BCF1030F1E +:1086300007D195F8E5C007FA03F84CEA080C85F86D +:10864000E5C090F809C05FEACC7C0FD192F803C076 +:10865000BCF1020F02D0BCF1030F07D195F8E4C0C2 +:1086600007FA03F84CEA080C85F8E4C001EB410C6A +:1086700021F00108E04492F801C00CF0070C0CFA5C +:1086800008FCD5F8C0804CEA080CC5F8C0C092F8C8 +:1086900002C04FEA81080CF00F0C0CFA08FCD5F868 +:1086A000E8804CEA080CC5F8E8C090F809C05FEA19 +:1086B000CC7C14D11279D20707D095F8E12007FAC3 +:1086C00003FC42EA0C0285F8E1202279D20606D5A5 +:1086D00095F8E32007FA03F31A4385F8E320491CD1 +:1086E000B1428FD3D5F8E8006864BDE8F0870E4A40 +:1086F000D21D22F81010704710B504460B480068D0 +:1087000038B1A068FFF75CFF2068BDE8104000F0BA +:108710000FB8E068FFF754FF6068BDE8104000F054 +:10872000D3BC000000200022AB000020BC050022CA +:1087300010B54F4B016800249960818859800289E7 +:108740009A801C704FF00053A3F81A21A3F81E1151 +:10875000C088A3F8200147480122C0F8D821C0F8FA +:10876000DC21C0F8C421C0F8CC21C0F8D421C0F865 +:10877000802172B6D0F808120029FBD1426062B69F +:1087800010BD2DE9F0413B4DD5F85C01384F2E046A +:108790000124BA6850B3B6F81C815FEA08000FD014 +:1087A000D5F8540110B9D5F8000148B1414601206F +:1087B0009047C5F8D842D5F8540108B1C5F8D4425D +:1087C000BA684146022090470178022902D0032965 +:1087D00002D008E0418800E07988A6F81E11808860 +:1087E000A6F81A013C70C5F8DC4238E0D5F844011F +:1087F00080B1B6F81C1103209047387838B17888DA +:10880000A6F81E01B888A6F81A0100203870C5F82D +:10881000C44224E0D5F8580130B1B6F81C1101204B +:108820009047C5F8D8421AE0D5F84C0128B9D5F8D8 +:10883000540110B9D5F8000188B1B6F81C1119B16E +:1088400001209047C5F8D842D5F84C0110B1C5F8C1 +:10885000CC4204E0D5F8540108B1C5F8D442D5F8AB +:108860000001002801D0C5F88042BDE8F081000079 +:108870001408100000200022F64900200860091D9D +:108880000860091D0860091D0860091D0860091DB0 +:108890000860091D0860091D0860EF4901220A608F +:1088A000ED4914310860510701F8500FFF234B7058 +:1088B00001F8050C10234B808A80E8490860486065 +:1088C0008860C860086148618861C8610862704753 +:1088D0007047E24A1160DF4900220A6000EB800025 +:1088E0004FF6FF7202EA40004FF00052A2F8580023 +:1088F000012008607047D94B10B5D64A1960002195 +:1089000011604FF0005191F85140E40707D01B6A05 +:1089100058438009A1F858000120106010BD00EBF9 +:10892000C00303EB00104FF6FF7303EA8000F1E78A +:108930004FF00050B0F8580070474FF0005090F8DA +:108940002200C0F3810028B1012805D0022805D0FB +:10895000C3487047C3487047C3487047C34870470F +:1089600070B54FF0005494F85100BA49C2074FF067 +:10897000000001D0086070BD656972B6626942F09E +:10898000040262610860B4F8581009B1A4F85800F4 +:10899000FFF74FF90146FFF7D0FFB1FBF0F0E7F723 +:1089A0002FFD6561022000F03BFB62B670BDAB4855 +:1089B00010B5002104680160FFF7D2FF1CB1A44686 +:1089C000BDE8104060470020FFF782FF10BDA34ABA +:1089D0005160A0490022091D0A6000EB80004FF69B +:1089E000FF7202EA4000CA06A2F85A00012008609D +:1089F00070479A4B10B55960964A0021121D1160BC +:108A0000D10691F85140A40708D400EBC00303EB52 +:108A100000104FF6FF7303EA800002E01B6A584320 +:108A20008009A1F85A000120106010BD4FF00050DD +:108A3000B0F85A00704770B54FF0005494F85100E8 +:108A40008B4982074FF000001AD4656972B66269DB +:108A500042F0080262610860B4F85A1009B1A4F843 +:108A60005A00FFF7E6F80146FFF767FFB1FBF0F0A9 +:108A7000E7F7C6FC6561032000F0D2FA62B670BD6C +:108A8000086070BD754810B5002144684160FFF76B +:108A9000D2FF1CB1A446BDE8104060470120FFF79B +:108AA00017FF10BD6D4A916071490022091D0A60CF +:108AB00000EB80004FF6FF7202EA40008A06A2F83F +:108AC0005C00012008607047644B10B59960684AEB +:108AD0000021121D1160910691F85140640708D4DD +:108AE00000EBC00303EB00104FF6FF7303EA8000B6 +:108AF00002E01B6A58438009A1F85C000120106065 +:108B000010BD4FF00050B0F85C00704770B54FF0EA +:108B1000005494F85100574942074FF000001AD40E +:108B2000656972B6626942F0100262610860B4F869 +:108B30005C1009B1A4F85C00FFF77BF80146FFF771 +:108B4000FCFEB1FBF0F0E7F75BFC6561042000F090 +:108B500067FA62B670BD086070BD404810B500216C +:108B600084688160FFF7D2FF1CB1A446BDE81040C5 +:108B700060470220FFF7ACFE10BD384AD1603D4986 +:108B80000022091D0A6000EB80004FF6FF7202EA26 +:108B900040004FF00052A2F85E00012008607047CC +:108BA0002E4B10B5D960334A0021121D11604FF0D1 +:108BB000005191F85140240708D400EBC00303EBA7 +:108BC00000104FF6FF7303EA800002E01B6A58436F +:108BD0008009A1F85E000120106010BD4FF0005028 +:108BE000B0F85E00704770B54FF0005494F8510033 +:108BF000214902074FF000001AD4656972B6626914 +:108C000042F0200262610860B4F85E1009B1A4F875 +:108C10005E00FFF70EF80146FFF78FFEB1FBF0F0A4 +:108C2000E7F7EEFB6561052000F0FAF962B670BD6A +:108C3000086070BD094810B50021C468C160FFF725 +:108C4000D2FF1CB1A446BDE8104060470320FFF7E7 +:108C50003FFE10BD40090022C00400222008100081 +:108C600000093D000048E8010024F40000127A00E9 +:108C700044090022480900224C090022EE4A1161F1 +:108C8000EE4900220A6000EB80004FF6FF7202EA14 +:108C900040004FF00052A2F86000012008607047C9 +:108CA000E54B10B5E54A1961002111604FF0005104 +:108CB00091F85140E40608D400EBC00303EB001028 +:108CC0004FF6FF7303EA800002E01B6A58438009F5 +:108CD000A1F860000120106010BD4FF00050B0F806 +:108CE0006000704770B54FF0005494F85100D349BC +:108CF000C2064FF000001AD4656972B6626942F08C +:108D0000400262610860B4F8601009B1A4F8600024 +:108D1000FEF78FFF0146FFF710FEB1FBF0F0E7F71B +:108D20006FFB6561062000F07BF962B670BD0860DC +:108D300070BDC14810B5002104690161FFF7D2FF81 +:108D40001CB1A446BDE8104060470420FFF7C0FDF9 +:108D500010BDB94A5161B9490022091D0A6000EBF2 +:108D600080004FF6FF7202EA40004FF00052A2F876 +:108D70006200012008607047AF4B10B55961AF4ADF +:108D80000021121D11604FF0005191F85140A406CE +:108D900008D400EBC00303EB00104FF6FF7303EAA7 +:108DA000800002E01B6A58438009A1F8620001209C +:108DB000106010BD4FF00050B0F86200704770B501 +:108DC0004FF0005494F851009D4982064FF0000086 +:108DD0001AD4656972B6626942F080026261086005 +:108DE000B4F8621009B1A4F86200FEF722FF014650 +:108DF000FFF7A3FDB1FBF0F0E7F702FB6561072089 +:108E000000F00EF962B670BD086070BD8A4810B5FA +:108E1000002144694161FFF7D2FF1CB1A446BDE8BF +:108E2000104060470520FFF753FD10BD824A916155 +:108E300083490022091D0A6000EB80004FF6FF7293 +:108E400002EA40004FF00052A2F8640001200860DE +:108E50007047794B10B59961794A0021121D116054 +:108E60004FF0005191F85140640608D400EBC00364 +:108E700003EB00104FF6FF7303EA800002E01B6A69 +:108E800058438009A1F864000120106010BD4FF024 +:108E90000050B0F86400704770B54FF0005494F87B +:108EA0005100684942064FF000001AD4656972B655 +:108EB000626942F4807262610860B4F8641009B1BA +:108EC000A4F86400FEF7B5FE0146FFF736FDB1FBDE +:108ED000F0F0E7F795FA6561082000F0A1F862B6B6 +:108EE00070BD086070BD544810B50021846981616F +:108EF000FFF7D2FF1CB1A446BDE810406047062032 +:108F0000FFF7E6FC10BD10B5FEF77AFE4FF00051FA +:108F100091F8222042F21073B0FBF3F0C2F3810209 +:108F2000521CD040B1F85420C96C51438909B0FBA0 +:108F3000F1F010BD43490022091D0A603E4A126A41 +:108F400050434FF000528009A2F8660001200860EB +:108F500070473C490020091D086070473649C861C8 +:108F600039490120C1F8DC003649A0310860091DEB +:108F700008607047304A10B50020D169D061324A8C +:108F8000C2F8DC0051B12F4AA03210604FF00050FF +:108F9000C06CBDE8104020F07F400847FF20FFF77D +:108FA00097FC10BD10B50446FEF72AFE4FF00051A5 +:108FB00091F8221042F21072B0FBF2F0C1F381017D +:108FC000491CC8400003B0FBF4F01B49086210BD07 +:108FD00030B54FF000550124844095F8510009B197 +:108FE000204300E0A04385F8510095F84B000AB1FA +:108FF000204300E0A04385F84B0015F8500F0BB15B +:10900000204300E0A043287030BD4FF0005010F81E +:109010004A1FC079814301D001207047002070476A +:1090200000F01F02012191404009800000F1E02082 +:10903000C0F880127047000020081000500900227C +:10904000540900225809002200006022002101601A +:109050000846704730B50A6812B10B46846A08E0CA +:1090600000220860C0E903210AE002F10C03D26883 +:1090700012B1956AA542F8DC1A68C0E903211860AC +:10908000002030BD0068002201E0C068521C8A4206 +:1090900001D00028F9D170470068704702690AB111 +:1090A000116831B96FF00400704701F10C02C96812 +:1090B00039B18142F9D1C9681160002101610846C6 +:1090C00070476FF003007047017C31B14FF00051E1 +:1090D00011F82D2F42F002020A70194902680A6045 +:1090E00042684A6082688A60C068C860704730B46D +:1090F0004FF0005111F8E00F0A8AC968104BC407FD +:1091000008D09B68002B0BD0A2F57F44FF3C07D012 +:1091100030BC1847DB68002B02D0521C92B2F7E734 +:1091200030BC70474FF0005090F8E2000449C2078D +:1091300001D0096800E04968002900D0084770475D +:1091400058081000B2F120030AD5C2F1200301FA39 +:1091500002F120FA03F300FA02F041EA030170473A +:1091600000FA03F14FF00000704710B54C1084EA8C +:10917000530404D54042C1F1000138BF491E1B42CF +:1091800004D55242C3F1000338BF5B1E00F0D9F88A +:1091900014F0804F04D04042C1F1000138BF491E95 +:1091A00014F0004F04D05242C3F1000338BF5B1EDD +:1091B00010BD032A40F2308010F0030C00F015803F +:1091C00011F8013BBCF1020F624498BF11F801CBCA +:1091D00000F8013B38BF11F8013BA2F1040298BF2F +:1091E00000F801CB38BF00F8013B11F0030300F099 +:1091F0002580083AC0F0088051F8043B083A51F83D +:1092000004CBA0E80810F5E7121D5CBF51F8043B41 +:1092100040F8043BAFF30080D20724BF11F8013BB4 +:1092200011F801CB48BF11F8012B24BF00F8013B16 +:1092300000F801CB48BF00F8012B704710B5203A69 +:10924000C0F00B80B1E81850203AA0E81850B1E8FF +:109250001850A0E81850BFF4F5AF5FEA027C24BFB5 +:10926000B1E81850A0E8185044BF18C918C0BDE8AC +:1092700010405FEA827C24BF51F8043B40F8043B75 +:1092800008BF7047D20728BF31F8023B48BF11F82A +:10929000012B28BF20F8023B48BF00F8012B704784 +:1092A00002F0FF0343EA032242EA024200F002B85E +:1092B0004FF000020429C0F0128010F0030C00F0FF +:1092C0001B80CCF1040CBCF1020F18BF00F8012B7D +:1092D000A8BF20F8022BA1EB0C0100F00DB85FEA4B +:1092E000C17C24BF00F8012B00F8012B48BF00F817 +:1092F000012B70474FF0000200B513469446964686 +:10930000203922BFA0E80C50A0E80C50B1F1200198 +:10931000BFF4F7AF090728BFA0E80C5048BF0CC046 +:109320005DF804EB890028BF40F8042B08BF7047A4 +:1093300048BF20F8022B11F0804F18BF00F8012B16 +:10934000704753EA020C00F069802DE9F04B4FF0B2 +:109350000006002B1FBFB3FA83F503FA05F424FAC5 +:1093600005F65E4012BF1643B2FA82F502FA05F422 +:10937000C5F120051EBF22FA05FC44EA0C04203585 +:1093800056EA044C4FEA144418BF641C4FF000081E +:109390004FF00009904271EB030C39D3002919BF3B +:1093A000B1FA81F701FA07F6B0FA80F700FA07F68A +:1093B000C7F120071EBF20FA07FC46EA0C0620373B +:1093C000B6FBF4FCA7EB0507103F07F01F0BCBF132 +:1093D00020060CFA0BFB2CFA06F644BFB346002617 +:1093E000202FA4BF5E464FF0000B5BEA060C08BFBF +:1093F0004FF0010B19EB0B09ABFB027C48EB0608A5 +:10940000C01B06FB02CC0BFB03CC71EB0C01C1E7CC +:109410000B46024641464846BDE8F08B13B54FF077 +:1094200000004FF00001AFF30080BDE81C40704722 +:1094300010B50446AFF300802046BDE81040E6F7C3 +:10944000EDBE704701491820ABBEFEE726000200C2 +:109450000149002008607047380500222DE9F041DD +:109460000F4F00244FF001084FF0005608FA04F0A7 +:10947000C5B296F82F0028420CD096F83900284241 +:1094800008D057F8240000B1804796F82F00A84371 +:1094900086F82F00641C062CE8DBBDE8F081000094 +:1094A000649310002DE9F0410F4F00244FF00108A4 +:1094B0004FF0005608FA04F0C5B296F82E00284284 +:1094C0000CD096F83800284208D057F8240000B194 +:1094D000804796F82E00A84386F82E00641C062CC0 +:1094E000E8DBBDE8F08100004493100001218140D9 +:1094F000C8B24FF0005191F83310014201D0012061 +:109500007047002070470000014901200860704743 +:109510003805002200487047510710000549044AE9 +:109520000A80054AC0E90021012101724172704799 +:109530006C550120EC0610000C970100074841789B +:1095400049B1807838B106488079012803D10548AF +:109550000078012800D0002070470000400710006C +:10956000A8511000180510000348417811B98078FF +:10957000002800D001207047400710000148007803 +:109580007047000010061000014800787047000086 +:1095900058051000064841788278C3781144027853 +:1095A00000791A441144081800D0012070470000C7 +:1095B000C005100070B5D0E900214C084FEA320315 +:1095C000961841EB010533432C4313430C43C0E988 +:1095D000003470BD01EB810100EBC1002930704700 +:1095E000024A1278514300EB410070478606100092 +:1095F00001EB810100EBC10029307047024A12786B +:10960000514300EB41007047860610001000000037 +:109610000400000001000000FF00FF00FF00000048 +:10962000000101010202000000000000C44A100015 +:1096300010501000EB140100020000002D15010075 +:1096400002000000DF16010002000000F914010012 +:10965000020000006B16010001000000BB150100B4 +:10966000070000008D16010001000000AF16010088 +:10967000010000005715010007000000C11401009F +:10968000711701006D170100891801006D170100A5 +:10969000191A01006D1701006D1701006D17010007 +:1096A0006D1701006D170100AF17010001000000E8 +:1096B000F7170100000000006D1701000000000016 +:1096C0000B18010001000000B518010001000000A6 +:1096D000D918010001000000FD1801000100000080 +:1096E00033190100040000000B1A01000100000002 +:1096F000451A010001000000991A01000100000054 +:10970000AF1A010002000000FF1A01000200000071 +:10971000BB1B010002000000711C010001000000E1 +:10972000B11C010001000000731B010002000000D9 +:10973000391C0100020000006D170100000000004C +:109740006D170100000000005F1A0100A51701005D +:10975000691A0100791A0100891A010086000201C4 +:1097600000A6020F0300A8020B0300000300000084 +:109770000000000003000000000000005300000093 +:10978000000000004300000000000000F3000000A3 +:1097900000000000E3000000000000005302000091 +:1097A000000000000000000005000000A876100086 +:1097B000000400005D3A000000000000020000000C +:1097C0000100000004000000A87A1000000400005E +:1097D000F94A000000000000020000000200000042 +:1097E00003000000A87E100000080000CD12010058 +:1097F0000000000002000000030000000200000062 +:10980000A8861000000200006D1D0100000000008D +:10981000020000000400000001000000A888100001 +:10982000800000002D140100000000000200000074 +:109830000000000001000000010000000100000025 +:109840000200000001000000030000000100000011 +:1098500004000000010000000500000001000000FD +:1098600000000000010000000200000003000000F2 +:10987000FB520100975201004B5B0100E35A0100CB +:10988000B36D0100374B0100A35301005554010093 +:10989000A35D01006F5C010001680100C96D01005A +:1098A0000004400010210000001F0100060000001D +:1098B00030000100000406000802500060020C0C99 +:1098C000000060020C300C1A31100F0F00002F0046 +:1098D0000100AA2C0100000003000000FFFF0300AC +:1098E0000000000018000000FFFFFFFF3F00000025 +:1098F0000000000000010000000000006002018084 +:109900000001000000000C000C000C000C0007011E +:1099100026261212110000000038003C203DD041E4 +:10992000EC4108421C423042444260427442884248 +:10993000A442000000000000000000000000000041 +:1099400000000020000101020102020301020203E3 +:1099500002030304000000001B0000802D000080B3 +:1099600036000000410000805A0000006C0000003A +:10997000770000809900008082000000B4000000A1 +:10998000AF000080D8000000C3000080F500008018 +:10999000EE000000290100803201000004010000F7 +:1099A0001F010080680100007301008045010080F4 +:1099B0005E010000B0010000AB0100809D0100804D +:1099C00086010000F1010080EA010000DC010000D6 +:1099D000C7010080490200805202000064020000BA +:1099E0007F02008008020000130200802502008030 +:1099F0003E020000D0020000CB020080FD02008089 +:109A0000E6020000910200808A020000BC02000011 +:109A1000A7020080600300007B0300804D030080EC +:109A200056030000210300803A0300000C030000ED +:109A300017030080F9030080E2030000D403000054 +:109A4000CF030080B8030000A303008095030080CB +:109A50008E0300008904008092040000A40400002A +:109A6000BF040080C8040000D3040080E504008027 +:109A7000FE040000100400000B0400803D04008080 +:109A800026040000510400804A0400007C04000009 +:109A900067040080A0050000BB0500808D050080E4 +:109AA00096050000E1050080FA050000CC050000E5 +:109AB000D70500803905008022050000140500004C +:109AC0000F050080780500006305008055050080C3 +:109AD0004E050000C0060000DB060080ED06008099 +:109AE000F6060000810600809A060000AC06000021 +:109AF000B706008059060080420600007406000088 +:109B00006F060080180600000306008035060080FE +:109B10002E060000E9070080F2070000C4070000DD +:109B2000DF070080A8070000B307008085070080DA +:109B30009E070000700700006B0700805D07008033 +:109B400046070000310700802A0700001C070000BC +:109B5000070700800909008012090000240900009D +:109B60003F09008048090000530900806509008012 +:109B70007E090000900900008B090080BD0900806B +:109B8000A6090000D1090080CA090000FC090000F4 +:109B9000E7090080200800003B0800800D080080D5 +:109BA00016080000610800807A0800004C080000D8 +:109BB00057080080B9080080A2080000940800003F +:109BC0008F080080F8080000E3080080D5080080B6 +:109BD000CE080000400B00005B0B00806D0B008086 +:109BE000760B0000010B00801A0B00002C0B00000C +:109BF000370B0080D90B0080C20B0000F40B000073 +:109C0000EF0B0080980B0000830B0080B50B0080E9 +:109C1000AE0B0000690A0080720A0000440A0000CE +:109C20005F0A0080280A0000330A0080050A0080CD +:109C30001E0A0000F00A0000EB0A0080DD0A008026 +:109C4000C60A0000B10A0080AA0A00009C0A0000AF +:109C5000870A0080800D00009B0D0080AD0D008004 +:109C6000B60D0000C10D0080DA0D0000EC0D000003 +:109C7000F70D0080190D0080020D0000340D00006A +:109C80002F0D0080580D0000430D0080750D0080E1 +:109C90006E0D0000A90C0080B20C0000840C0000C6 +:109CA0009F0C0080E80C0000F30C0080C50C0080C5 +:109CB000DE0C0000300C00002B0C00801D0C00801E +:109CC000060C0000710C00806A0C00005C0C0000A7 +:109CD000470C0080C90F0080D20F0000E40F000085 +:109CE000FF0F0080880F0000930F0080A50F0080F9 +:109CF000BE0F0000500F00004B0F00807D0F008052 +:109D0000660F0000110F00800A0F00003C0F0000DA +:109D1000270F0080E00E0000FB0E0080CD0E0080BB +:109D2000D60E0000A10E0080BA0E00008C0E0000BE +:109D3000970E0080790E0080620E0000540E000025 +:109D40004F0E0080380E0000230E0080150E00809C +:109D50000E0E0000349D0100000410006804000095 +:109D60001C010000609D010000FC1000400000008C +:109D700078010000609D0100680810001C8B000045 +:109D80009401000001FF014103FFFFFF01C4075DD3 +:109D9000F00120F052103206320F9A37089AE1088B +:109DA000035ED303AAFF0C590101150B5390D08A0F +:109DB00030B572B601230C4D2B600C4A002481B1E2 +:109DC00013604FF0005100F01F0081F86A0007484F +:109DD0001C38036001680029FCD114602C6062B655 +:109DE00030BD1460EDE70000C01B0022780D00229A +:109DF0007C78A72BF7020000838758D408FDFFFF6B +:109E00003E0037000103000037F1000000000000B1 +:109E1000FFFFFFFF03000000FFFF00000000000045 +:109E20002210230937040F23093704B8010000006A +:109E30000320200A88AA40014001E803C8009600D8 +:109E40009600960096007000700008B000B0000008 +:109E50001BAA0A04C8000000000000000000000067 +:109E60000D050F0A190FF900023200000000000072 +:109E700000000000000000000000000000000000E2 +:109E80000B013C0096009600D0010000000000008D +:109E900082000064000000FF0000000000000000DD +:109EA0001608000208000600000000A0504C260121 +:109EB00008001300000000008D05094F04002C006D +:109EC00002002B002660060000000000BBBB401F04 +:109ED000C80088880000ADA50D1F24002F002E00AB +:109EE000266006000000000026600600000000005A +:109EF000000126000000002606000000000000000F +:109F000000008D11084F0400300006002F004010A3 +:109F1000060000000100000000000000000000003A +:109F20000000E8650D1F10003400300060001700CD +:109F30001001100020009923000100000000000023 +:109F40000000000000000000000000000000000011 +:109F50000000000000000000000000000000000001 +:109F600011002C01000000000100000000000000B2 +:109F70000000B80B000000000E0000000000000010 +:109F800000000000000002000000000000000000CF +:109F90000E000000000000000000000000000200B1 +:109FA00000000000000000000000000000000200AF +:109FB000000064006400D000800CF00AD00000159E +:109FC000001250015001001500125001800CF00ADF +:109FD000D0000000000000000000000000000000B1 +:109FE000932A020A0F00011E180000000000300032 +:109FF00000000000FF0FFF0F10140A000000000017 +:10A000000B00C800000000D00F1490019001FF7FEA +:10A01000FF7FF40100000000056400030000000061 +:10A02000090096009600960096003C0064001E0011 +:10A0300002003C0064003C00C80000000000640016 +:10A040000102F4015E01002C012C010819C8000076 +:10A050000B030521010164006400600090013201DE +:10A060000000000000235802C800FF2C012000005F +:10A070000300640032002000140A84032800000456 +:10A080000000200006000500050000000600050095 +:10A0900005000000815C0200000100018200C80090 +:10A0A0000001080018001E0000010064403220007A +:10A0B0001E003200C8008813401F0564006400645D +:10A0C0000010004600FA96FAC800000000000000E8 +:10A0D0000000000000000000000000000000000080 +:10A0E0000000000084030C0E2000101250008200BB +:10A0F0006400000A6400000F00016000600000407E +:10A10000400000000000C800900150007C010032B7 +:10A1100001000000000000005600000000000000E8 +:10A12000000000000000000000000000000000002F +:10A1300002008C001E2803050202021311550000C4 +:10A140005E01C8000632001EF4010000000000009D +:10A1500041007800960032004000C8000000000076 +:10A160000000000000000000000000000000617B13 +:10A170000103AA00000210010002640006640064EA +:10A180000014001400107800320000211A000010A2 +:10A190000F01000A001482111400100004100400C2 +:10A1A000400000200030D8100064005194941888BA +:10A1B0006210003000100030000A001800053C0555 +:10A1C0003C033CD80532F80301030A960684C80014 +:10A1D0000FE80A0030000F5100000443C800C80017 +:10A1E0000A0A3C007800000A50003C0001640000AC +:10A1F000000000000000003C00960014E80300008E +:10A20000640003E8030000FA0003000000000000FF +:10A21000000000000000000000000000000000003E +:10A220000000000000000000110096001E28000041 +:10A2300000051E00FA000000500A051E06640A020E +:10A24000C8001E0300900164FA00C0000000000076 +:10A2500000000000000000000000000000000000FE +:10A2600000000102030400010203500150015001EB +:10A27000500100000000000000000000000000008D +:10A2800000000000000000000000000000000000CE +:10A2900000000000000000000000000000000000BE +:10A2A00000000000000000000000000000000000AE +:10A2B0005A5A5A5A5A5A5A5A5A5A5A5A5A5A5A0058 +:10A2C000000000000000000000000000000000008E +:10A2D00060595B5D5F5E5F60616263636364646479 +:10A2E0006464696A6B6B6C6C6D6D6F7070706E6CB2 +:10A2F0006C710000000000010C0C22222200000002 +:10A300000000000A00140032006400BF08F1080FCA +:10A3100009190923092309000000000A001400326A +:10A32000006400D303050423042D0437043704001C +:10A33000000000000000000000000000000000001D +:10A34000000000000009000B000D0019004200E3AE +:10A35000080E09130916091909230900000A00113A +:10A3600000180028004600E8030E041F04240429F6 +:10A37000043704000000000000000000000000009E +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A4300000000000000000000000000058004C0078 +:10A440004C004C00404C408C10CC40DC00005F00C5 +:10A450006100670070007D008E00A300BA00D50087 +:10A46000F300140137015C018401AD01D80104023D +:10A4700031025F028D02BA02E70214033F036A034E +:10A480009203B903DD03FF031F043B0454046A0471 +:10A490007D048C0497049F04A304A3049F049704E1 +:10A4A0008C047D046A0454043B041F04FF03DD0391 +:10A4B000B90392036A033F031403E702BA028D0251 +:10A4C0005F0231020402D801AD0184015C01370151 +:10A4D0001401F300D500BA00A3008E007D007000C7 +:10A4E000670061005F0094009800A500B900D600E5 +:10A4F000FB0027015A019401D30118026102AF0247 +:10A50000FF025103A503FA034E04A204F30442051B +:10A510008D05D505170653068A06B906E206030718 +:10A520001C072C07350735072C071C070307E20615 +:10A53000B9068A0653061706D5058D054205F304AC +:10A54000A2044E04FA03A5035103FF02AF02610205 +:10A550001802D30194015A012701FB00D600B9006B +:10A56000A500980094009A009F00AC00C200E00093 +:10A57000060135016A01A601E90130027D02CE0221 +:10A5800022037803D00328048004D8042D057F0516 +:10A59000CE0518065D069D06D60608073207540745 +:10A5A0006E0780078907890780076E0754073207FF +:10A5B0000807D6069D065D061806CE057F052D0503 +:10A5C000D80480042804D00378032203CE027D023D +:10A5D0003002E901A6016A0135010601E000C2006E +:10A5E000AC009F009A009400DD00AD01DE023E0445 +:10A5F0008D0594062307230794068D053E04DE028D +:10A60000AD01DD009400350037003B0043004D00F4 +:10A610005A006A007D009200A800C100DC00F7002B +:10A620001401320150016F018D01AB01C901E50137 +:10A6300000021A02320248025B026C027B028702AD +:10A6400090029602990299029602900287027B027A +:10A650006C025B02480232021A020002E501C901E3 +:10A66000AB018D016F01500132011401F700DC00D4 +:10A67000C100A80092007D006A005A004D0043000E +:10A680003B0037003500AE035203F902A402530227 +:10A690000602C001800147011601EE00CE00B6009F +:10A6A000A800A4000000000000000000000000005E +:10A6B0000000000000000000010001000100040192 +:10A6C00004050409040D0000FF03FE07FE07FE0752 +:10A6D000FE07FE07FE07FE07FE07FE07FE07FE0752 +:10A6E000FE07FF07FF07FF07FF070000000000004D +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000030507080CE6 +:10A750000D0F0F0F0E0E0E0D0D0D0A08000000005C +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A790000000000000000000000000000302500064 +:10A7A00050004A0150204E0B0132001405000A20CF +:10A7B0001405F80002013C0001020F0F2323083C9E +:10A7C000083C40F805050A0A0105050F1400E86574 +:10A7D0000D1F100034003000600017001001100041 +:10A7E000080099E3000000000000000000000000E5 +:10A7F00000000000000000006400000000000000F5 +:10A8000000000A0014050000005028502814B02051 +:10A81000FF00D0000614142A3A4000323200146EB1 +:10A820006E471A38000000010F1E00200100FAB622 +:10A8300001810265073508461046100A1215081AEC +:10A8400005050000000000E920021F10002500257A +:10A85000005000240070018001100055000000002D +:10A8600000000000000000000000000000000000E8 +:10A8700000000000888800F799990000000100009E +:10A880000000100710961E000F6414000F00020253 +:10A890000302030396C8FF00000000000000000050 +:10A8A00000000000012800640AE8036404000000BE +:10A8B00000000001000100010001080018810000F3 +:10A8C0000000041000000108000E0000000000005D +:10A8D0000000000000000200AA00E8440D1F104024 +:10A8E0004C004C00600028000101010120005503CC +:10A8F000200500000080004000983AC800000D626A +:10A90000640064001414F401F401F401F401000083 +:10A910000014000000002C01320300880000000039 +:10A92000000000000000000000000000040800001B +:10A930003404F400700036000F000A000400000028 +:10A94000000004000A000F0036007000F400340418 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000008B10960000A6 +:10A9800000010A2C010414002C010000002C01100D +:10A990001E0FC800032800FFCCFFDFA36854433517 +:10A9A0002B221B15120E0B090706050400000000E0 +:10A9B000000000FFFFFFFFFFFFFFFFFFFFFF84031B +:10A9C0009001FA000F073223190000000000000078 +:04A9D000B09513002B +:00000001FF diff --git a/firmware/st_fts_f1x.ftb.ihex b/firmware/st_fts_f1x.ftb.ihex new file mode 100644 index 000000000000..13ee3267d23e --- /dev/null +++ b/firmware/st_fts_f1x.ftb.ihex @@ -0,0 +1,6360 @@ +:1000000055AA55AA01000000363900005823000007 +:10001000670000003E000000070000000000000034 +:100020000000000007FB0000000000003481010018 +:10003000E00B00000000000000000000B580D8D6F2 +:100040003D0DF67D4C600000C2F20982B39FFFFFB8 +:1000500000041000E101000039020000530200001A +:100060006D02000087020000A102000000000000F5 +:100070000000000000000000000000006F510100BF +:100080007751010000000000BB0200007F51010019 +:1000900087510100935101009F510100AB510100B4 +:1000A000B7510100C3510100CF510100DB510100E4 +:1000B000E7510100C9020000F3510100FF510100A6 +:1000C0000B520100135201001B5201002352010088 +:1000D0002F520100375201003F5201000000000082 +:1000E0000000000000000000000000004752010076 +:1000F0004F520100000000005752010000000000B4 +:1001000000000000000000000000000000000000EF +:10011000670058230100FFFF0000000000000000FE +:1001200000000000000000000000000000000000CF +:1001300000F002F800F068F80AA090E8000C824491 +:100140008344AAF10107DA4501D100F05DF8AFF26E +:10015000090EBAE80F0013F0010F18BFFB1A43F0A5 +:1001600001031847707F0100A07F01000A444FF08F +:10017000000C10F8013B13F0070408BF10F8014B06 +:100180001D1108BF10F8015B641E05D010F8016B4B +:10019000641E01F8016BF9D113F0080F1EBF10F8AF +:1001A000014BAD1C0C1B09D16D1E58BF01F801CBD2 +:1001B000FAD505E014F8016B01F8016B6D1EF9D555 +:1001C0009142D6D370470000103A24BF78C878C156 +:1001D000FAD8520724BF30C830C144BF04680C604D +:1001E000704700000023002400250026103A28BF95 +:1001F00078C1FBD8520728BF30C148BF0B60704799 +:100200001FB51FBD10B510BDDFF80CD0FFF7F8FF0C +:1002100015F04CF817F0CEFA0004100003B4FFF705 +:10022000F1FF03BC17F0D0FA40BA7047C0BA70476C +:1002300012481349A1EB00014FF0200391FBF3F2A8 +:1002400002FB13114FF0CC334FF0CC344FF0CC35D0 +:100250004FF0CC364FF0CC374FF0CC384FF0CC3994 +:100260004FF0CC3AA0E8F807013AFBD119B140F8B9 +:1002700004AB0439FBD10348004700000000100024 +:1002800000041000E10000001EF0040F0CBFEFF3AB +:100290000880EFF309804FF001014FF0000210F0E9 +:1002A000D9BF1EF0040F0CBFEFF30880EFF30980F5 +:1002B0004FF002014FF0000210F0CCBF1EF0040F0F +:1002C0000CBFEFF30880EFF309804FF003014FF00C +:1002D000000210F0BFBF1EF0040F0CBFEFF3088048 +:1002E000EFF309804FF004014FF0000210F0B2BFAD +:1002F0001EF0040F0CBFEFF30880EFF309804FF0FE +:1003000005014FF0000210F0A5BF00B514F050FF3A +:100310005DF804EB00F032B81EF0040F0CBFEFF3F1 +:100320000880EFF309804FF006014FF0000210F053 +:1003300091BF00000A484FF0FF0101704FF000002C +:1003400080F311884FF0000080F3098805484FF0D2 +:100350000201017062B604484FF08051016070479D +:1003600022ED00E00008100004ED00E002484FF02C +:10037000805101607047000004ED00E04FF0200064 +:1003800080F31188EFF3098098B112480068124990 +:100390000968884217D0EFF309800E49096820E9FF +:1003A000F00F886000B50B48006815F01BF85DF889 +:1003B00004EB084808490A68026000688168B1E8EF +:1003C000F00F81F309884EF0040E4FF0000080F327 +:1003D000118870470408100008081000EFF311801E +:1003E0004FF0200181F31188704700004FF00000AA +:1003F00080F311887047000062B6704772B670478C +:10040000401EFDD17047000010B501464022FD4856 +:1004100017F0D6F80121BDE81040002015F01BB8F8 +:1004200038B50446F848F74D2060204614F099FC92 +:1004300000226B460121104615F056F801210020DC +:1004400015F035F82878002802D010F05AFFECE7B4 +:1004500038BD2DE9F047DFF8B48382460127D8F88C +:100460000000EB4D90F8314010F8301F90F831004B +:100470004C4300F003008740A100284617F0FCF829 +:100480000026DFF8809312E0DE484030FFF7C8FF17 +:100490000020D9F8081007E055F8202031F9103075 +:1004A0001A4445F82020401CA042F5DB761CBE42D1 +:1004B000EADB40460AE000BF026855F8241092F8D3 +:1004C000612002F0030211412AF81410641EF3D2D5 +:1004D000BDE8F0872DE9F04FDFF830B34FF00109A8 +:1004E000CB4EDBF80000A7B090F8611090F83140D7 +:1004F000C1F3810890F8305009FA08FA60198100B8 +:1005000006EB8407304617F0B7F8BE48403014F0C9 +:1005100003FCBC49403181F80690DBF8000090F8FC +:100520006000820701D581F80490C00703D0B54868 +:100530004030FFF775FF00202BE0B2484030FFF756 +:100540006FFFDFF8C0B2620006A8DBF8181016F0E3 +:10055000F2FF6A0011A8DBF81C1016F0ECFF204631 +:1005600006A906E056F8202031F910301A4446F862 +:100570002020401EF6D2284611A906E057F8202078 +:1005800031F910301A4447F82020401EF6D209F104 +:10059000010081465045D0DB9E4905E056F8240015 +:1005A00040FA08F021F81400641EF7D29A4905E0D9 +:1005B00057F8250040FA08F021F815006D1EF7D213 +:1005C00027B0BDE8F08F2DE9F84F904D044628681C +:1005D00090F8311090F8300001FB00F88948403065 +:1005E00014F09AFB874801264030012C067106D191 +:1005F000296891F87010090701D404210171286855 +:10060000AB4600F5F97990F8611001F003018E40D6 +:100610008249002491F803A02AE000BF7F4819F81E +:1006200004100025C1707E4904FB08F001EB40076F +:100630004FEA4800009018E072484030FFF7F0FEA3 +:10064000704881680DB140460CE03846009A16F0BB +:1006500072FF09E037F9102031F910301A445210B6 +:1006600027F81020401EF5D26D1CB542E4DB641C57 +:10067000DBF8000090F8F10100F00300401CA042FC +:10068000CCD8664981F803A0BDE8F88F2DE9F04F7A +:100690005E4D85B0296891F8319091F83010009145 +:1006A00009FB01F002905748403014F035FB5548E3 +:1006B0000124403084710471C471286890F860008E +:1006C000C00703D04F484030FFF7AAFE28684FF01C +:1006D000000B90F8612000F5F97002F0030104FAB4 +:1006E00001FAC2F381024D4904FA02F20192C9787B +:1006F0005C46CDE9030157E00398015D4748C170AE +:1007000002984749604301EB4006002549E03D4817 +:100710004030FFF785FE3B48D0E9063187688846C0 +:100720002DB101998B452FDA48463A491AE04FEA34 +:1007300049021946374816F0FEFE0098414642002D +:10074000354816F0F8FE029839464200304616F059 +:10075000F2FE25E031F9102033F910C06244521046 +:1007600021F81020401EF5D22B49009808E000BF68 +:1007700031F9103038F910201A44521021F81020A5 +:10078000401EF5D20BF1010B029807E036F910205C +:1007900037F910101144491026F81010401EF5D2F8 +:1007A0006D1C5545B3DB641C1848006890F8F101D6 +:1007B00000F00300401CA0429ED801998B453EDA10 +:1007C0001048002140300C4601710199A1EB0B0546 +:1007D00033E00C484030FFF723FE0A480D49D0E9CA +:1007E0000623484608E000BF31F9106032F9107066 +:1007F0003E44761021F81060401EF5D2064900985C +:1008000018E0000024081000B9030000D80610000A +:1008100078641000286D0120526D0120100710002F +:100820003854012031F9102033F91060324452104D +:1008300021F81020401EF5D2641CA542C9DC9C4959 +:100840000498C87005B0BCE62DE9FF5FDFF864824C +:10085000994FD8F8000090F8314090F8305007EBED +:10086000840A6019810004FB05FB0AEB8506384603 +:1008700016F002FF4FEA8B01304616F0FDFE8F485E +:1008800014F04AFA8D494FF0010981F8069081F879 +:100890000490D8F8000090F86000C00702D0084625 +:1008A000FFF7BEFDD8F8000090F86100C0F38101A9 +:1008B000029100F0030103910299484609FA01F9F7 +:1008C000039988400190002031E07C48FFF7A8FDA3 +:1008D0007A484038D0E906328168204607E000BFF8 +:1008E00057F820C033F91080C44447F820C0401E98 +:1008F000F6D2284607E000BF5AF8203032F910C07F +:100900009C444AF820C0401EF6D2DDE90002904225 +:100910000BDA584607E000BF56F8202031F91030B6 +:100920001A4446F82020401EF6D20098401C009041 +:100930004845CADB019848451DDD604800218846CE +:1009400081710198A0EB090913E05C48FFF768FD8D +:100950005A4840388168584607E000BF56F82020C2 +:1009600031F910301A4446F82020401EF6D208F122 +:100970000108C145E9DC524906E000BF57F82400F0 +:10098000029A104121F81400641EF7D24D4905E087 +:100990005AF82500029A104121F815006D1EF7D271 +:1009A0005846494A06E000BF56F82010039B1941FB +:1009B00022F81010401EF7D2BDE8FF9F2DE9F04746 +:1009C0000546002014F0E7FD022014F0E4FD0320AA +:1009D00014F0E1FD3D4F00203870384814F09CF9C8 +:1009E000344EDFF8EC80DFF8EC9030684FF0010413 +:1009F00090F86010890712D5290718D5A90710D5D6 +:100A00003C7090F8F001000602D5FFF73FFE01E0D0 +:100A1000FFF71AFF88F8004089F8004001E0280736 +:100A200005D5387818B9FFF755FD88F80040DFF88C +:100A30008C80A80715D5387878BB306890F8F0011D +:100A4000000603D50020FFF7BEFD07E01B4814F0A9 +:100A500063F988F804401C48FFF7FBFC89F8004064 +:100A60001BE0680719D5306890F8F001000603D53F +:100A70000120FFF7A8FD10E0104814F04DF9306890 +:100A800090F87000000702D588F8044002E00421C5 +:100A900088F804100C48FFF7DCFC032014F096FDE6 +:100AA000022014F093FDBDE8F047002014F08EBD45 +:100AB00010071000D80610007864100064081000B9 +:100AC000286D0120526D01203854012000041000CF +:100AD000150710001407100010B501464022F84811 +:100AE00016F06EFD0121BDE81040002014F0B3BCEB +:100AF00038B50446F348F24D2060204614F031F931 +:100B000000226B460121104614F0EEFC012100206A +:100B100014F0CDFC2878002802D010F0F2FBECE7AE +:100B200038BD2DE9FF410024DDE90A760821684639 +:100B300015F094FA0546082102A815F08FFA02462E +:100B400000206FF07E0E14E0002100FB02F30DE0A8 +:100B500007EB010C13F90CC0B444F44501DA01248D +:100B600003E0BCF17F0F00DD0224491C9142EFDB62 +:100B7000401CA842E8DB204604B0BDE8F0812DE926 +:100B8000FF410AAC082194E8C0010024684615F032 +:100B900065FA0546082102A815F060FA0146002012 +:100BA00008E03256D21901D5012402E0FF2A00DD07 +:100BB0000224401CA842F4DB00200AE02A18B256A6 +:100BC00012EB080201D5012402E0FF2A00DD022415 +:100BD000401C8842F2DB2046CEE72DE9F04F87B07B +:100BE0004FF0010B14F02CF904460D4614F02AF9CD +:100BF000DFF8D48206460F46D8F8000090F8E700E8 +:100C000010F0600F05D02046294611F001FD044682 +:100C10000D46AD48016891F8310091F8301000FBA5 +:100C200001F8012104A80EF03FFEDFF8A092002099 +:100C3000DFF89CA2D9F80010049B324691F91B10F2 +:100C40000390CDF800A0CDE901313B46204629466E +:100C500011F05DFD012003900021049BCDF800A060 +:100C6000CDE9013132463B462046294611F04FFD81 +:100C70009348403014F050F89149052040310871F4 +:100C80000846FFF735FF8E480221D0F808A005A8D6 +:100C90000EF00AFE8C4842460168B1F9C20101908B +:100CA000B1F9C411009108444010029050460599D2 +:100CB00012F059FA8246022105A80EF058FE01985A +:100CC0004FF00008824502DC00998A450ADA7E4826 +:100CD00002990068AAEB0101B0F8C60191FBF0F09F +:100CE0004FFA80F80499CDE9001832463B46204679 +:100CF0002946FFF716FF01281DD0022824D0D9F875 +:100D000000100120724A81F81B800390049B8DE83B +:100D10000C0132463B462046294611F0F8FCD9F832 +:100D20000000A5218176012104A80EF020FE07B065 +:100D30005846BDE8F08FD9F800104FF0000B81F84D +:100D40001BB00121B02007E0D9F800104FF0000BD4 +:100D5000B12081F81BB0012110F0C4FADFE72DE9C2 +:100D6000F04FDFF8648189B04FF0010BD8F8000034 +:100D700090F831A090F83000079014F061F8044624 +:100D80000D4614F05FF80646D8F800000F4690F8BC +:100D9000E70010F0600F05D02046294611F038FC1E +:100DA00004460D46012104A80EF07EFDDFF81C91DB +:100DB0004FF00008049BD9F80000294690F91D2047 +:100DC000444805900090CDF80C80CDE901323246C0 +:100DD0003B46204611F09BFCDDE904030121CDE9EF +:100DE0000030CDE9028132463B462046294611F0CB +:100DF0008EFC3348403013F08FFF314906204031DC +:100E000008710846FFF774FE2D480221D0F80880CB +:100E100006A80EF049FD2C480068B0F9C811B0F9D9 +:100E2000CA01084440100090079806990AFB00F296 +:100E3000404612F098F98246022106A80EF097FD6E +:100E400021484FF000080068B0F9C821524503DB83 +:100E5000B0F9CA21524508DD009AB0F8CC01AAEBDE +:100E6000020191FBF0F04FFA80F80499CDE90018E7 +:100E700032463B4620462946FFF753FE4FF4807129 +:100E8000012829D002282FD0D9F80010012081F89C +:100E90001D80DDE90423CDE90032CDE90280324630 +:100EA0003B462046294611F032FCD9F80000A52126 +:100EB0000177012104A80EF05AFD584609B038E721 +:100EC00074081000890A0000D8061000DC06100023 +:100ED000A06D0120C8720120D9F800204FF0000B4E +:100EE000B02082F81DB006E0D9F800204FF0000BCA +:100EF000B12082F81DB010F0F5F9D6E72DE9F04FDA +:100F000091B0DFF8B4A301200F90DAF8000090F858 +:100F100031100E9190F830000D9013F091FF804643 +:100F2000894613F08FFF04460D46012106A80EF0F6 +:100F3000BBFCDAF8000002AB002690F8340100F0A8 +:100F40000101DE48006890F9202090F91F0005910A +:100F500083E84500DA4806990C90CDE90001224665 +:100F60002B464046494611F023FCDAF800000121E7 +:100F7000224690F83401029600F00100CDE90410F9 +:100F800006990C98CDE9000103962B464046494648 +:100F900011F00EFCCB4813F0BFFECA490320887144 +:100FA0000846FFF7A5FDC74802214038D0E906767C +:100FB000DAF80000B0F9CEA1B0F9D0B107A80EF070 +:100FC00073FC0AEB0B004010059038460E9A079907 +:100FD00012F0C9F80027504501DC584508DA059998 +:100FE000091AB5480068B0F8D20191FBF0F047B299 +:100FF00030460D9A079912F0B6F80026504501DCEC +:10100000584508DA0599091AAB480068B0F8D401C8 +:1010100091FBF0F046B2022107A80EF0A8FC06985A +:10102000CDE9000722462B46029640464946FFF787 +:10103000A6FD012826D002282ED0A0480121224654 +:1010400000682B46C77780F820609B48006890F8BE +:101050003401CDE9027600F00100CDE904100699D3 +:101060000C98CDE900014046494611F0A1FB934898 +:10107000A52100688177012106A80EF078FC0F9861 +:1010800011B056E68D4900200F900968C87781F8A5 +:1010900020001021B22008E0884900200F90096844 +:1010A000C87781F820001021B32010F01BF9DEE78B +:1010B0002DE9F04F8DB04FF0010913F0C1FE064647 +:1010C0000F4613F0BFFEDFF8F0810121D8F80000D1 +:1010D00090F831000A9006A80EF0E6FBD8F8000060 +:1010E000764C4FF0000A90F8E00902AB00F00101E5 +:1010F00020685546DFF8C8B190F9232090F9220006 +:10110000059183E8250006990BF1980BCDE900B114 +:10111000524653463046394611F04AFBD8F8000093 +:101120000121002290F8E009029500F00100CDE9CC +:10113000041006990395CDE900B1134630463946AF +:1011400011F036FB5F4813F0E7FD5E49032008729B +:101150000846FFF7CDFC5B4802214038856A09A8A4 +:101160000EF0A2FBD8F80000B0F9D611B0F9D80102 +:10117000084400EBD07040100190DDE909122846C8 +:1011800011F0F1FFD8F800100025AB46B1F9D621D7 +:10119000824203DBB1F9D821824206DD019AB1F81F +:1011A000DA11101A90FBF1F045B2022109A80EF0F5 +:1011B000DEFB069900228DE82208134630463946A8 +:1011C000FFF7DDFC012826D002282ED0216801225D +:1011D0003B4801F8225F81F801A0D8F8001091F88F +:1011E0003411029501F001010591CDE903A20699A0 +:1011F0000022CDE9000113463046394611F0D8FAF5 +:101200002168A52081F82100012106A80EF0AFFB7E +:1012100048460DB08DE521684FF0000901F822AF76 +:1012200081F801A04021B22008E021684FF00009B8 +:10123000B32001F822AF81F801A0402110F052F84C +:10124000DEE770B505460124002014F0A4F9022061 +:1012500014F0A1F9184E306890F8C0012840C0077A +:1012600003D0FFF7BAFC00F00104306890F8C00129 +:10127000800704D5A80702D5FFF771FD0440306848 +:1012800090F8C001400704D5680702D5FFF736FE85 +:101290000440306890F8C001000704D5280702D543 +:1012A000FFF706FF0440022014F090F9002014F02C +:1012B0008DF9204670BD0000D8061000DC06100035 +:1012C00090780120B408100070B56F4C4FF6FF7194 +:1012D0004FF43E7520684182294614F0F9FE002142 +:1012E0001F200EF1B5FC2A462168BDE870401F237F +:1012F000664814F014BF644810B50068644C417D22 +:10130000206841744FF48C6114F0E2FE00211A2031 +:101310000EF19EFC00211B200EF19AFC1A234FF4C3 +:1013200080625C48216814F0FAFE21681B23BDE846 +:1013300010406022584801F5805114F0F0BE2DE9AC +:10134000F041564D041D0E462146284614F0C0FEBD +:101350003068534900EB84038B4201D21C2312E016 +:10136000504A934212D288420CD28846091A8F08FA +:101370001C233A46294614F0D2FEE21B05EB8701F6 +:101380001D2311E01D23224629460EE0904214D26F +:10139000111A8F0890461D233A46294614F0BFFEC5 +:1013A000E21B05EB87011E23404614F0B8FE3068AF +:1013B00000EB84003060BDE8F0811E23E3E7F8B560 +:1013C000364C394800901034022014F0E4F8002123 +:1013D0001C200EF13DFC00211D200EF139FC0021E6 +:1013E0001E200EF135FC1021204616F023F90020B6 +:1013F0002080A0700120244DE0704FF6FF71A18085 +:101400002868028AE280437D28482372E688A0F893 +:10141000F86EA0F8FA1E042280F8FC3E69461046D9 +:10142000FFF78DFF012300222146102011F0F4FB6D +:101430006946FFF784FF012300222146112011F0A5 +:10144000EBFB6946FFF77BFF286890F85012C9074D +:1014500003D190F88002C00708D001230022214662 +:10146000122011F0D9FB6946FFF769FF0123002222 +:101470002146132011F0D0FB6946FFF760FF0220E0 +:1014800014F0A4F8F8BD0000D8061000F0EF010039 +:10149000DC061000F09F0100F0AF0100786410003E +:1014A000F0CF0100F0DF0100F0BF0100A06D0120CE +:1014B0000B4801785A2911D18188B1F57C7F0DD86C +:1014C000418800290AD1064940781031022805D008 +:1014D000A0F17002072A01D810F0E6B870470000AA +:1014E0000000012010B501464022FE4816F068F8C1 +:1014F0000121BDE81040002013F0ADBF2DE9F041FF +:10150000F94CA0F16006092ED4E91205D4E91423A0 +:1015100016D2DFE806F005162637465867788700AA +:1015200002462B46084600F09DF9024601200021A4 +:1015300015F0CAFFD4E9022310431943C4E902019C +:1015400075E0084600F08EF9012302460021184696 +:1015500015F0BAFFD4E90A2310431943C4E90A017C +:1015600065E002462B46084600F07CF90246012061 +:10157000002115F0A9FFD4E9062310431943C4E95B +:10158000060154E0084600F06DF9024601200021F2 +:1015900015F09AFFD4E90E2310431943C4E90E0154 +:1015A00045E002462B46084600F05CF9012302465E +:1015B0000021184615F088FFD4E90423104319438D +:1015C000C4E9040133E0084600F04CF9024601206A +:1015D000002115F079FFD4E90C2310431943C4E925 +:1015E0000C0124E002462B46084600F03BF9024677 +:1015F0000120002115F068FFD4E9082310431943A6 +:10160000C4E9080113E0084600F02CF90246012065 +:10161000002115F059FFD4E9102310431943C4E900 +:10162000100104E001208840616808436060206880 +:10163000401C2060BDE8F0812DE9F04117460446CA +:101640000D46002609E0E00703D0314638460FF08A +:1016500049FE761C6D084FEA340454EA0500F2D1C5 +:10166000E8E72DE9F041A04CD4E90223D4E906567D +:10167000104619462A433343D4E90A56D4E90EC723 +:1016800045EA0C053E43D4E9087C97432CEA030C59 +:10169000C4E9087CD4E91023AA43B343C4E9102366 +:1016A0002268002AC6D06022FFF7C6FFD4E90A01EB +:1016B0006122FFF7C1FFD4E906016222FFF7BCFFF8 +:1016C000D4E90E016322FFF7B7FFD4E904016422D5 +:1016D000FFF7B2FFD4E90C016522FFF7ADFFD4E9B3 +:1016E00008016622FFF7A8FFD4E910016722FFF77F +:1016F000A3FF6068BDE8F041682200219CE799E7FC +:101700002DE9F14F4FF0000913F09AFB0646884689 +:1017100013F098FB744A04460D46C2E91401C2E96D +:1017200012684FF01D0A4FF0260B14F090F90027B5 +:101730003A460120002115F0C7FE304001EA0801B9 +:10174000084322D0F8B2002114F089F9410705D5E9 +:101750000099C90602D54946622010E0C10705D0AC +:101760000099490702D54946602008E0009911F028 +:10177000C00F06D010F00A0F03D049466420FFF7CF +:10178000BDFE09F1010000F0FF097F1C5745CFDBCA +:1017900014F05DF900273E4632460120002115F085 +:1017A00093FE20402940084320D0F0B2012114F0DC +:1017B00056F9410705D50099890602D539466320B7 +:1017C00010E0C10705D00099090702D5394661200C +:1017D00008E0009911F4C07F06D010F00A0F03D082 +:1017E00039466520FFF78AFE7F1CFFB2761C5E45F6 +:1017F000D2DDBDE8F84F14F02AB910B50446002038 +:1018000013F0C9FE3849002014F00C0FC1E908009C +:10181000C1E90200C1E90400C1E90600C1E9100004 +:10182000C1E90A00C1E90C00C1E90E004860086086 +:1018300009D1E00607D4A00605D4600603D4E0056C +:1018400001D4200602D52046FFF75AFFA00702D098 +:10185000204600F022F8FFF704FFBDE8104000200A +:1018600013F0B4BE2DE9F04116461F4680464FF0F6 +:10187000FF35002422460120002115F025FE3040CE +:101880003940084304D06D1C454501D12046D1E6BE +:10189000641C402CEED30020CCE62DE9FF41044629 +:1018A000012000F038F8804613F0CAFACDE90001B3 +:1018B00013F0C8FACDE902010821684614F0CEFB06 +:1018C0000746082102A814F0C9FB0546074EE007A9 +:1018D00007D0306842462946B0F8DE30384600F07E +:1018E0004AF805E0C408100008041000D8061000EB +:1018F000A00707D5306842462946B0F8DE303846A2 +:1019000000F089F86A48016841F0020101600EF0B8 +:1019100074FCBDE8FF8130B585B00446684613F01D +:10192000FBF964480090022C15D007208DF80400C4 +:10193000614C684613F015FA002204AB01211046F1 +:1019400013F0D2FD0121002013F0B1FD207830B159 +:101950000FF0D7FCEDE703208DF80900E8E713F05E +:101960006FFA564DC5E9120113F06CFAC5E914017E +:10197000A06805B030BD2DE9FF5F9B4692460F463B +:10198000002544E000984FF000094C46A0F1010802 +:101990003AE000BF04FB075081B2601C00FB075017 +:1019A00080B23AF811203AF81000101A00B25845E7 +:1019B00002DDB9F1000F0AD0CBF10001884213DA41 +:1019C000B9F1000F06D04FF00009214618E04FF0A2 +:1019D000010914E0002604E031466620FFF78EFD81 +:1019E000761CA642F8D90EE0B9F1000F0BD02146C3 +:1019F0006620FFF783FD0098801E844203D1611C9E +:101A00006620FFF77BFD641C4445C3D36D1CBD42BB +:101A1000B8D3BDE8FF9F2DE9FF5F9B4692460D4678 +:101A2000002641E04FF000094C46A5F1010838E0DE +:101A300006FB0540611C06FB051180B289B23AF82D +:101A400010203AF81100101A00B2584502DDB9F121 +:101A5000000F0AD0CBF10001884213DAB9F1000F70 +:101A600006D04FF00009214617E04FF0010913E0BE +:101A7000002704E039466720FFF740FD7F1CA7429E +:101A8000F8D90DE0B9F1000F0AD021466720FFF721 +:101A900035FDA81E844203D1611C6720FFF72EFD8F +:101AA000641C4445C4D3761C00988642BAD3B0E780 +:101AB0000007100095140000C4081000080410006E +:101AC000144908604FF40051002013F0C4BC38B52D +:101AD000002013F060FDAFF2170015F001FC0022AA +:101AE0004FF400546B462146104613F0FDFC21468E +:101AF000002013F0DCFC002013F068FD0648A5224E +:101B0000016804480A74006820F07F424A6115F0B9 +:101B10000BFC38BD60041000DC061000020004D08D +:101B2000012A04D0022805D002E0012000E00420B0 +:101B300013F07DB80020704710B501464022FE48E2 +:101B400015F03EFD0121BDE81040002013F083BCDC +:101B500030B585B00446684613F0DEF8F7480090CB +:101B60000CB3012C21D0022C21D0032C19D1082038 +:101B70008DF80400F04D0324684613F0F2F80022BB +:101B800004AB0121104613F0AFFC0121002013F03B +:101B90008EFC2878002804D00FF0B3FB641E002CC4 +:101BA000EADC05B030BD0520E2E70620E0E70220D0 +:101BB0008DF80900DEE72DE9F14F88B013F040F908 +:101BC0008346029113F03EF98146DD4C08988A461F +:101BD0000028206807D0B0F87A110898FFF79EFF18 +:101BE0000490D84812E090F8E70010F0600F05D09C +:101BF0005846029910F00CFD834602912068B0F817 +:101C000072110898FFF78AFF0490CF480390402094 +:101C100007900690C848B821B83815F02DFD00206F +:101C200000900898FFF794FFC34800273E4680685D +:101C3000059001203D4601902A460120002115F023 +:101C400043FC029A00EA0B001140084341D00024F3 +:101C500022460120002115F037FC02460B4600EA1F +:101C6000090001EA0A01084320D0B348B83800EB64 +:101C7000C6018E4603C900EA020C01EA03085CEAC9 +:101C8000080C12D1DDF814C03CF91780DDF810C043 +:101C9000E04504DC10431943CEE9000105E022468B +:101CA0003146009B039813F02AFE7F1C0698641CA3 +:101CB0008442CDDBA048B83800EBC601D1E9000270 +:101CC00080EA090082EA0A02104301D00020019054 +:101CD000761C07986D1C8542AEDB0198012804D064 +:101CE0000098401C00907F289BDD019809B0BDE85A +:101CF000F08F2DE9F14F98B013F0A2F8CDE90C0167 +:101D000013F0A0F8CDE9100118988D4C00285CD094 +:101D10002068B0F87A111898FFF700FF0F908948F3 +:101D20000690402082460E9008210CA814F096F9E7 +:101D30000446082110A814F091F944438348019007 +:101D400000F5E6602146029015F074FC61000198F0 +:101D500015F070FC7848B821B83815F08DFC4FF0BC +:101D600000091898FFF7F4FE734800273C46806886 +:101D70000A90C9F100004FF0010B3E461390324625 +:101D80000120002115F0A0FBDDE90C2310401940D3 +:101D900008436ED000252A460120002115F094FB4F +:101DA000DDE9108C02460B4600EA080001EA0C014E +:101DB000084373D06048B83800EBC70CDCE9000179 +:101DC0001040194008430FD093E0DDE90C0110F0FA +:101DD0001FFCCDE90C012068B0F872111898FFF7CC +:101DE0009DFE0F9058489BE7B9F1000F0ADA0A9858 +:101DF00030F914100F98814201DB002100E001212D +:101E0000029801550A980F9930F91400884231DD83 +:101E10000299095D11B1012909D06AE0B9F17F0F7A +:101E200067DA019909F1010321F8140051E0DCE9B6 +:101E3000001011431843CCE90010019830F9141038 +:101E40000F98091A0A9830F914200F98A2EB000095 +:101E500000D54942002800DA4042814205DC139B4C +:101E60002A4639465B1C069836E0019820F8142073 +:101E70003FE052E037DA0299095D012901D071B1E2 +:101E800037E0139911F17F0F33DD01992A4621F8CC +:101E90001400139B39465B1E06981DE02AE0DCE91E +:101EA000001011431843CCE9001001980F9A30F943 +:101EB00014100F98081A0A9931F91410A1EB0202B4 +:101EC00000D54042002A00DA5242904207DCA9F1D4 +:101ED00001032A463946069813F011FD09E00198DE +:101EE00020F8141005E0DCE9001011431843CCE998 +:101EF0000010641C6D1C5545FFF64DAF0E48B838F8 +:101F000000EBC701D1E90001DDE910235040594041 +:101F1000084301D04FF0000B7F1C0E98761C8642C0 +:101F2000FFF62DAFBBF1010F05D009F10109B9F1A1 +:101F30007F0F7FF716AF0BE0C0091000E91A000011 +:101F4000D8061000C8720120A06D0120786410002E +:101F5000584619B0CBE62DE9F04F054685B0002074 +:101F600013F019FB022013F016FB12F06BFFCDE902 +:101F70000201F84804904027082102A814F06EF8E6 +:101F80000446012D71D1DDE90201CDE900010122F4 +:101F90000023049813F0C2FCDFF8BC8300216FF02B +:101FA0007E0508EB440A680C05E000BF28F8110024 +:101FB0000AF80150491CA142F8DBDFF8A0B3032066 +:101FC000FFF7C6FD0024DBF80890264632460120C4 +:101FD000002115F079FADDE9022310401940084389 +:101FE0001DD039F9141038F91400002900DA4942DB +:101FF000002800DA404281420ADA32460021049881 +:1020000013F072FC0AF8040039F8141028F81410C0 +:102010002B4632460021049813F071FC641C761C98 +:10202000BE42D3DB6D1C7F2DC9DD00252C46224628 +:102030000120002115F048FADDE902231040194083 +:10204000084307D01AF9053022460021049813F0FE +:1020500056FC6D1C641CBC42E9DBC1482622049975 +:10206000006800F5865015F066FA022013F0AEFA0B +:10207000002013F0ABFA05B039E62DE9F04F87B038 +:10208000002013F088FA022013F085FA4FF0000BBD +:1020900012F0D8FECDE90401AE480390082104A84F +:1020A00013F0DCFF06460020DFF8AC82CDE900002B +:1020B00008EB460505EB06090320FFF749FDDFF8AD +:1020C0009CA200242746DAF8080002901AE03A465B +:1020D0000120002115F0F8F9DDE904231040194032 +:1020E00008430ED03A460021039813F0FDFB285513 +:1020F000029830F8141028F81410002009F8040091 +:10210000641C7F1CB442E2DB00273C4615E02246FB +:102110000120002115F0D8F9DDE904231040194011 +:10212000084309D0EB577F2B05DA224600215B1CC0 +:10213000039813F0E4FB7F1C641CB742E7DB032029 +:10214000FFF706FD00200124DAF8083014E000BF94 +:1021500033F9102038F91010002A00DA5242002911 +:1021600000DA49428A4206DA29567F2903DA491CF5 +:10217000295409F80040401CB042E9DB00273C46E6 +:1021800016E022460120002115F09EF9DDE9042326 +:102190001040194008430AD0EB5713F17F0F05DDBB +:1021A000224600215B1E039813F0A9FB7F1C641CD0 +:1021B000B742E6DB0320FFF7CBFC684883680020CA +:1021C00019E000BF19F80010A1B933F9101038F95F +:1021D0001020002900DA4942002A00DA52429142D6 +:1021E00008DA295611F17F0F04DD491E2954022215 +:1021F00009F80020401CB042E4DB0024274627E019 +:102200003A460120002115F05FF9DDE904238246FA +:10221000029110401940084319D02B573A4600212B +:10222000039813F06CFB19F8040078B9DDE900237A +:1022300002994AEA02001943CDE9000138F9140075 +:10224000FE30B0F5FE7F01D94FF0010B641C7F1CFE +:10225000B442D5DB0821684613F000FFB04208DB2A +:10226000BBF1000F03D00021B4200FF03BF807B002 +:102270003DE5002036E00320FFF76AFC37480024E4 +:1022800027468068029023E03A460120002115F09D +:102290001BF9DDE9043C02468E46184001EA0C01B8 +:1022A000084314D0DDE9000302EA000C0EEA030142 +:1022B0005CEA010C0AD119F90410012935D0022970 +:1022C0006DD002434EEA0301CDE90021641C7F1C5E +:1022D000B442D9DB0821684613F0C0FEB04208DAE8 +:1022E0000AF1010082461F48006890F8E21151454A +:1022F000C1DC1B4826220399006800F5865015F0C2 +:102300001AF90821684613F0A9FEB04202DBBBF1BE +:10231000000F03D00021B4200EF0E4FF022013F0E0 +:1023200055F9002013F052F9A1E7029838F914107A +:1023300030F91400002801DB034600E04342002985 +:1023400000DA49428B420FDC295D7F290CD028F846 +:10235000140050E0387D012078641000C00910009E +:10236000DC061000D8061000002109F80410DDE991 +:102370000001024302984EEA0103CDE9002330F93F +:10238000141038F91400002900DA4942002800DA54 +:102390004042814232DD285D401E28552EE00298E1 +:1023A00030F9141038F91400002901DB0B4600E065 +:1023B0004B42002800DA4042834205DC28577F3038 +:1023C00002D028F81410E6E7002009F80400DDE93F +:1023D00000130A434EEA0300CDE90020029830F9C9 +:1023E000141038F91400002900DA4942002800DAF4 +:1023F0004042814202DD285D401CCEE72B573A4621 +:102400000021039813F07BFA60E72DE9F0410646BE +:102410000124002013F0BFF8022013F0BCF84A4D4D +:10242000F0074FF000074FF0A50808D000F01BF8A8 +:1024300010F0010403D02868C77680F81A80B0072E +:1024400008D500F056F82040040003D028684777EC +:1024500080F81C80002013F0B9F8022013F0B6F8C1 +:102460002046BDE8F0812DE9FC47012612F0E8FC8A +:1024700004460D4612F0E6FCDFF8D0900746884689 +:10248000D9F8000090F8E70010F0600F05D0204662 +:10249000294610F0BDF804460D46D9F8000090F822 +:1024A0007001C0071FD0CDE9007822462B4628488E +:1024B00013F034FAD9F8000090F87011C90712D05F +:1024C00090F8E700C0F3411002284FF0000002D35B +:1024D000FFF70FFC01E0FFF76EFB060003D10121BF +:1024E00074200EF0FFFE0020FFF732FB3046BDE8FF +:1024F000FC872DE9FC41012612F0A2FC04460D46A2 +:1025000012F0A0FC114F3A6892F87821D20715D04A +:10251000CDE9000122462B460E4813F0FFF938683A +:1025200090F87801C00709D00120FFF744FB0600AE +:1025300004D14FF4807174200EF0D4FE0120FFF717 +:1025400007FB3046BDE8FC81DC061000D806100011 +:10255000A06D0120C872012010B5FFF7B8FA012064 +:10256000FFF7F9FC012000F033F95320FFF74DFF8E +:1025700000F001044FF4D67001F081F8204205D03C +:10258000FEF71DFFBDE81040FEF7B5BE10BD10B54B +:10259000FFF79DFA0120FFF7DEFC012000F018F99B +:1025A00040F2FF10FEF74DFE002803D0BDE81040BA +:1025B000FEF7A1BE10BD000010B501464022FC4848 +:1025C00014F0FEFF0121BDE81040002012F043BFCF +:1025D00030B585B0684612F09FFBF64802220078BD +:1025E000E0B1032101280DD003280ED0022818D015 +:1025F000042205280CD004280DD008280ED0092864 +:102600000FD010E08DF806100DE08DF808100AE0EC +:102610008DF80A2007E08DF80A1004E08DF80620F6 +:1026200001E08DF80820E448E14D0324009068465D +:1026300012F097FB002204AB0121104612F054FF68 +:102640000121002012F033FF2878002804D00EF07A +:1026500058FE641E002CEADC05B030BD2DE9F04FB9 +:10266000D44E044687B008208846307012F0E8FB4C +:10267000CDE90401402003903620D04D029034B3C0 +:10268000012C30D0022C7DD109203070CC48009034 +:10269000DFF81C93286841F2421109F12809084427 +:1026A0000190082104A813F0D9FC0746B8F1010FE6 +:1026B00068D13A4604A9009813F070F9DFF8048352 +:1026C00000206FF07E0508EB470B690C23E0BC4847 +:1026D000DFF8DC9248380090296841F2E60009F101 +:1026E00018090844DCE712F0ADFBCDE90401B44859 +:1026F00041F21C11283800902868DFF8B492084491 +:102700000190262009F11C090290CAE728F8101050 +:102710000BF80050401CB842F8DB00BFFFF758FF31 +:102720000024D9F800A0264632460120002114F0EA +:10273000CBFEDDE904231040194008431BD03AF9D1 +:10274000141038F91400002900DA4942002800DA90 +:102750004042814209DA3146009813F00DF90BF836 +:1027600004003AF8141028F814102A46314600984C +:1027700013F009F9641CBC4203D00398761C86420E +:10278000D2DB00E021E06D1C7F2DC7DD00252C464B +:1027900022460120002114F097FEDDE904231040B9 +:1027A0001940084306D01BF905202146009813F074 +:1027B000EAF86D1CBD4203D00398641C8442E7DB39 +:1027C000DDE90010029A14F0B6FE07B0BDE8F08F04 +:1027D00010B50446002012F0DEFE022012F0DBFEEF +:1027E00021460020FFF73AFF21460120FFF736FF80 +:1027F00021460220FFF732FF022012F0E7FEBDE87B +:102800001040002012F0E2BE2DE9F04F694E044660 +:102810008DB00820307012F013FBCDE90A0136208C +:10282000069069481021654D006890F8E3B1079162 +:102830004CB3012C32D0022C7ED109213170604979 +:102840000391296841F24212594F114408912837E7 +:1028500090F8E4B1402007900020029008210AA8D7 +:1028600013F0FCFBDFF85CA106460AEB4605A8194D +:1028700001900020CDE90400FFF7AAFE00242046C5 +:10288000D7F8009035E04E48494F48380390296802 +:1028900041F2E600084418370890DDE712F0D2FA5A +:1028A000CDE90A014648424F28380390286841F292 +:1028B0001C1108441C37089026200690CCE70246DD +:1028C0000120002114F000FEDDE90A231040194028 +:1028D00008430CD04146039813F04EF8285539F8B8 +:1028E00014102AF81410019900200855641C08F1EE +:1028F00001008046B442E2DB0024204615E0024697 +:102900000120002114F0E0FDDDE90A231040194008 +:10291000084308D02A577F2A04DA4146521C0398FC +:1029200013F031F8641C08F101008046B442E6DB84 +:10293000FFF74EFE002000E0E5E001243B6813E0D5 +:1029400033F910103AF91020002900DA4942002A20 +:1029500000DA5242914206DA29567F2903DA491CED +:10296000295401990C54401CB042E9DB0024A046D4 +:102970006FF07E0915E042460120002114F0A4FD0D +:10298000DDE90A2310401940084308D02A574A4578 +:1029900004DD4146521E039812F0F5FF641C08F155 +:1029A0000108B442E7DBFFF713FE00203B6825E097 +:1029B000000A10006804100069250000DC06100001 +:1029C000A87D012078641000D80610000199095CE8 +:1029D00099B933F910103AF91020002900DA494268 +:1029E000002A00DA5242914207DA2956494504DDAD +:1029F000491E2954019902220A54401CB042E5DBC9 +:102A00000024204627E002460120002114F05CFD4E +:102A10000091DDE90A23814610401940084318D08F +:102A20002A574146039812F0AEFF0198005D78B92D +:102A3000DDE90423009849EA02011843CDE90410B6 +:102A40003AF91400FE30B0F5FE7F01D90120029062 +:102A5000641C08F101008046B442D4DB082104A8BC +:102A600013F0FCFAB04247DA002037E0FFF7B0FD80 +:102A7000386800240090204625E00246012000210D +:102A800014F022FDDDE90A8C02460B4600EA08003C +:102A900001EA0C01084314D0DDE9040C02EA00014C +:102AA00003EA0C0851EA08010AD1019909570129E2 +:102AB0002BD0022959D0024343EA0C03CDE9042369 +:102AC000641C09F101008146B442D6DB082104A848 +:102AD00013F0C4FAB04204DA0998401C0990584532 +:102AE000C4DB069A0399089814F025FD082104A870 +:102AF00013F0B4FAB04202DB0298002803D0B520EC +:102B000007990EF0EFFB0DB060E600983AF914104B +:102B100030F91400002801DB844601E0C0F1000C0C +:102B2000002900DA49428C4505DC295D7F2902D065 +:102B30002AF8140045E0019900200855DDE9040158 +:102B400002430B43CDE90423009830F914103AF9FD +:102B50001400002900DA4942002800DA404281428C +:102B600032DD285D401E28552EE000983AF91410F9 +:102B700030F91400002801DB844601E0C0F1000CAC +:102B8000002900DA49428C4505DC29577F3102D003 +:102B90002AF81400E5E7019800210155DDE9040158 +:102BA00002430B43CDE90423009830F914103AF99D +:102BB0001400002900DA4942002800DA404281422C +:102BC00002DD285D401CCEE72A574946039812F0E3 +:102BD000DAFE75E710B5002012F0DDFC022012F0DD +:102BE000DAFC0020FFF710FE0120FFF70DFE0220A7 +:102BF000FFF70AFE022012F0E9FCBDE810400020B9 +:102C000012F0E4BC2DE9F047FF4800252C46D0E93E +:102C10001478D0F834902E468246324601200021A6 +:102C200014F052FC384001EA0801084304D019F8B6 +:102C30000600A84200D90546761C402EEDD3DAE9FD +:102C40001678DAF83890002632460120002114F078 +:102C50003BFC384001EA0801084304D019F806009B +:102C6000A04200D90446761C402EEDD3DAF8442069 +:102C700050461570DAF848100C70DAF82C30DAF893 +:102C80002470DAF830601B783F782B443B44DAF844 +:102C9000287036783F7826443E44D0E9147C57EAC1 +:102CA0000C070DD0D0E9167C57EA0C070AD0FF2795 +:102CB000B34213D2F31A2B44FF2B07D813700BE047 +:102CC000147009E015700D70BDE8F0871770826907 +:102CD00042F40072CAF818200C70F5E79E420DD23B +:102CE0009B1B2344FF2B01D80B7005E00F708169FB +:102CF00041F40071CAF818101570E5E71570EBE79C +:102D00002DE9F0411F460D46002A1FDDBE4C77B16C +:102D1000B4F90A60114610F088FAB042287812DA45 +:102D2000FF2807D2401C28700020BDE8F081B4F9CC +:102D30000860EFE7A0691FB140F00200A06105E064 +:102D400040F40060FAE708B1401E28700120ECE76B +:102D50002DE9F0411E460D46002A1ADDAA4C66B147 +:102D6000B4F90A70114610F060FAB84211DD287803 +:102D700050B1102804D3103803E0B4F90870F1E71B +:102D8000002028700020D0E7A06926B140F00100A3 +:102D9000A0610120C9E740F48060F9E72DE9F14F17 +:102DA00082B000259848029A2C46FF2102B3D0F841 +:102DB0002C9002264FF0180B89F80010D0F83080C4 +:102DC00088F80010B0F90A703102009101690029F9 +:102DD00000DC01258C484069002800DC0124FFF755 +:102DE00011FFFFF7F5FB00980EF017FA85B121E00F +:102DF000D0F824904FF400664FF0180B89F80010BB +:102E0000D0F8288088F80010B0F90870F110DCE7DD +:102E1000DFF8F4A13A46DAF81C00DAF8101000687E +:102E200000F067FC012805D1DAF8181031430125BC +:102E3000CAF818108CB9DFF8D0A13A46DAF82000A9 +:102E4000DAF81410006800F054FC012805D1DAF813 +:102E5000181031430124CAF818100DB1002C4ED1BE +:102E60002F4626464FF0170A4FB96748029BC169A3 +:102E700002690F6849463846FFF76AFF07464EB9B0 +:102E80006148029B016A42690E6841463046FFF77D +:102E90005FFF0646FFF7B6FEFFF79AFB00980EF0BD +:102EA000BCF907B116B9BAF1010ADDD22F46564D69 +:102EB000ABF101063FB9E869029B494600682A69FF +:102EC000FFF71EFF07463CB9286A029B414600688F +:102ED0006A69FFF715FF0446FFF794FEFFF778FBDA +:102EE00000980EF09AF907B10CB9761EE2D2012FC4 +:102EF00005D1012C03D1A86920F40070A861BDE8B8 +:102F0000FE8F2DE9F04F9A46914600223E4B8346B4 +:102F10001446B3F90C7010460123904615E000BF2B +:102F200009EBE40504F0070C2E7803FA0CF53542A2 +:102F30000AD03BF91250BD4203DC0AF802300120EE +:102F400001E00AF80280521C641C8A42E8DB3DE47E +:102F50002DE9FF5F00244FF001089A4617462546E9 +:102F6000DFF8A4904646DDF83CB051E00AEBE500FE +:102F700005F00701007806FA01F2024247D01BF87B +:102F8000040001283FD00098B9F90C1030F9142042 +:102F90008A421DDA2946019812F01BFDFF280EDA3D +:102FA000401CC2B24FF000082946019812F013FDF0 +:102FB000009830F814100E9820F8141023E00BF845 +:102FC0000460D9F8181041F00801C9F818101AE087 +:102FD0000E9830F91400002813DD401AA2EB01010D +:102FE00000D54042002900DA4942884209DC2946DE +:102FF000019812F0EEFC401EC2B22946019812F070 +:10300000EAFC0BF8046001E068041000641C6D1C0D +:10301000BC42ABDB404604B0BDE8F09F2DE9FF5F4A +:1030200000244FF001089A46174625464646DFF829 +:103030007094DDF838B030E00AEBE50005F00702E7 +:10304000017806FA02F0084226D01BF80400012895 +:1030500021D0009830F91410B9F90C0081421ADD22 +:103060002946019812F0B5FC00280CDD4FF000084D +:10307000042801DB001F00E00020C2B229460198AD +:1030800012F0A9FC07E00BF80460D9F8181041F021 +:103090000401C9F81810641C6D1CBC42CCDB40460E +:1030A000B9E72DE9F04F95B00024254620210CA862 +:1030B00014F0E2FA282102A814F0DEFAF8480169B7 +:1030C000002900DC01244269002A00DC0125F44AC1 +:1030D00081460646FF235032406B00F014FBF04A55 +:1030E000FF2358327169B06B00F00DFBFFF78AFDCA +:1030F000FFF76EFA4FF4806A50460EF08EF88CB1EE +:10310000D9F81C00E64A4E4600680CAB5032D9F89C +:103110001010FFF7F6FE012804D1B069012440F039 +:103120000800B0618DB1D9F82000DD4A4E46006834 +:1031300002AB5832D9F81410FFF7E3FE012804D18E +:10314000B069012540F00800B0610CB1002D78D1C4 +:103150002646A84600276EB90CA80090D9F81C0096 +:10316000CF4BD9F8102000685033D9F83410FFF74E +:1031700055FF0646B8F1000F0DD102A80090D9F80E +:103180002010C74BD9F8142008685833D9F83810E4 +:10319000FFF744FF8046FFF735FDFFF719FA504669 +:1031A0000EF03BF816B1B8F1000F02D17F1C602F72 +:1031B000D1DBDFF8F0B2D9F81000264641000BF55C +:1031C000E6684C46584614F035FA606941004046BE +:1031D00014F030FA0027D146FFF7FAF948460EF00E +:1031E0001CF85EB90CA8CDE900B0E069AC4B2269CF +:1031F00000685033616BFFF7ABFE06465DB902A96C +:10320000CDE90081206AA64B626900685833A16B42 +:10321000FFF79EFE0546FFF7F5FCFFF7D9F9484694 +:103220000DF0FBFF06B115B97F1C602FD4DB012E1A +:1032300007D1012D05D1A069810502D520F40070C8 +:10324000A06115B083E62DE9FF5F4FF0010800256E +:103250009A4617462C46DFF848924646DDF83CB0C1 +:103260003AE000BF0AEBE40004F00702017806FA36 +:1032700002F008422FD01BF8040058BB21460198E9 +:1032800012F07AFB0099B9F90E2031F91530494650 +:10329000934212DD0E9A7F3A904208DD0E99421A4F +:1032A0002146019812F06FFB4FF0000812E0886988 +:1032B00040F04000C9F818000CE00BF804600E99CB +:1032C000C1F17F01814205DD0E9942182146019826 +:1032D00012F059FB6D1C641CBD42C3DB40469AE6EC +:1032E0002DE9F04F6E4C85B02169C9B300208346AB +:1032F0006069B0B300208246BBF1000F02D0BAF182 +:10330000000F5DD1684B02AD0DCB85E80D00644A1E +:103310007F235032E06B00F0F6F9614A7F23583288 +:103320006169206C00F0EFF90026A14602A85C4616 +:1033300050F8268055461D215C4814F09DF95B48E5 +:1033400026211D3014F076F9D9F81810002721F045 +:103350004001C9F8181000BFFFF73AF934B114E082 +:1033600000E001E00120C2E70120C4E74F494C4BD7 +:10337000CDE90081D9F81C105033D9F81020086825 +:10338000D9F83C10FFF75FFF04467DB94749444B2D +:103390001D31CDE90081D9F820105833D9F8142017 +:1033A0000868D9F84010FFF74EFF0546FFF72AFCE2 +:1033B00004B115B97F1C182FCEDB761C032EB5D3B4 +:1033C00005B0C4E570B5364C00260546A661012857 +:1033D0005CD0022D5CD001202070607968B1304A49 +:1033E000002350322169606B00F08DF92C4A0023D4 +:1033F00058326169A06B00F086F9A07958B128496C +:1034000022695031E06B12F0C9FA254962695831DE +:10341000206C12F0C3FAE07810B10020FFF7BEFC78 +:10342000207960B1E07838B16178606A00F059F9CC +:103430006178A06A00F055F90120FFF7AFFC6079D0 +:1034400008B1FFF72EFE012D24D0022D24D02670C6 +:10345000FFF7BEF8A07958B1207938B1A178E06AB9 +:1034600000F03FF9A178206B00F03BF9FFF738FF3F +:10347000FFF7AEF8012D1BD0022D1BD01021A06943 +:1034800000F056F9A069C0B1002070BD0320A3E789 +:103490000520A1E7022000E004202070D8E700000A +:1034A000680410007864100040790100400A1000A0 +:1034B0004021E4E74FF40071E1E7012070BD70B5F1 +:1034C000B64D0C46022828D011F0BAFCC5E914010B +:1034D00011F0B8FCC5E91601B0480821503012F0CF +:1034E000BDFD2861AD480821583012F0B7FD686174 +:1034F00004F190006862401CA862401CE862401C15 +:1035000028634B3868632030C5E90E0448382864C6 +:1035100074309534C5E9110470BD11F095FCC5E90E +:10352000140111F093FCD5E710B59D490020FFF779 +:10353000C6FF9A489B49C161091D01629A490B68FF +:1035400093F8882112F00104C4704FF0000204D0F7 +:10355000436A1A70836A1A7008E0446A93F89231D9 +:1035600023700B68846A93F8933123700B6893F887 +:103570008841C4F34004047114B1C36A1A7006E0B0 +:1035800093F89421C36A1A700A6892F89521036B24 +:103590001A70096891F88821C2F380034371C2F35D +:1035A000C0028271B1F88A210281B1F88C21428176 +:1035B000B1F88E218281B1F89021C28191F89621D3 +:1035C000427091F897118170BDE810400020F9E633 +:1035D000734910B598310120FFF771FF71496F48A9 +:1035E0001031C1610021C0E916110A4641616E49DE +:1035F0000B6893F8A04114F00104C47004D0436A2E +:103600001A70836A1A7008E0446A93F8AA3123702A +:103610000B68846A93F8AB3123700C6894F8A0317E +:10362000C3F34003037113B1C36A1A7006E0C36A9F +:1036300094F8AC211A700A6892F8AD21036B1A70E5 +:10364000096891F8A021C2F380034371C2F3C0025C +:103650008271B1F8A2210281B1F8A4214281B1F8AE +:10366000A6218281B1F8A821C28191F8AE214270D1 +:1036700091F8AF118170BDE810400120A2E62DE95C +:10368000F04107460124002011F085FF022011F0CF +:1036900082FF464E78074FF000054FF0A5080AD587 +:1036A000FFF742FF10F0010405D03068C57780F8BD +:1036B000205080F81E8038070AD5FFF789FF204088 +:1036C000040005D0306800F8225F457000F8018CD6 +:1036D000022011F07BFF002011F078FF2046BDE8AA +:1036E000F08102788A4201D9511A00E0002101706C +:1036F000704710B514460FF098FDA04201DC012080 +:1037000010BD002010BDF0B500252C4601260CE0B0 +:1037100002EBE40704F0070C3F7806FA0CFE1EEA01 +:10372000070F01D003556D1C641C8D42F0DBF0BD0A +:1037300070B504460D46C00702D083200DF0D2FDBF +:10374000A00703D5294684200DF0CCFD600703D5E2 +:10375000294685200DF0C6FD200703D52946862081 +:103760000DF0C0FD600603D529468B200DF0BAFD93 +:10377000200603D529468C200DF0B4FDE00503D5C5 +:10378000294687200DF0AEFDA00505D52946BDE8E8 +:10379000704088200DF0A6BD70BD000068041000C8 +:1037A00090780120180A1000D8061000DC061000DE +:1037B000DFF8849108B5614D0024DFF884A1C9F8D1 +:1037C0000040604E2C60DFF88081CAF80040DFF8CE +:1037D0007CB13460C8F80040CBF8004000226B4652 +:1037E0005B49104611F080FE0098810713D5FCF765 +:1037F00005FE2F682C60FCF7FFFD17F0530F02D079 +:103800003846FEF702FE17F4D67F02D03846FFF79F +:1038100036FF02218BE0810504D5FEF758F94FF4FD +:10382000007184E0410514D5FCF7E8FD3768346089 +:10383000FCF7E2FDF80701D0FDF746FDB80701D51A +:10384000FDF7BDFD780701D5FDF755FD4FF480610B +:103850006DE001060CD5FCF7D1FDD8F80070C8F872 +:103860000040FCF7C9FD3846FDF7C7FF80215EE048 +:1038700081020DD5FCF7C2FDDAF80070CAF80040ED +:10388000FCF7BAFD3846FDF7DCFC4FF400114EE0C2 +:10389000C10404D5FEF760FE4FF4805147E00102F9 +:1038A00004D5FDF705FE4FF4000140E0010504D505 +:1038B000FEF76DFE4FF4006139E0410227D5FCF7B9 +:1038C0009DFDDBF80070CBF80040FCF795FDF80794 +:1038D00001D0FEF7FCF8B80705D50120FEF73BFB49 +:1038E0000120FEF775FF38070ED51A4F386890F89B +:1038F000C101000601D5FEF7C0FB386890F8C10190 +:10390000400601D5FFF766F94FF480010FE0C005CE +:103910007FF564AFFCF772FDD9F80070C9F800407C +:10392000FCF76AFD3846FDF749F84FF48071002036 +:1039300011F0BDFD52E70000E8061000EC06100093 +:10394000F0061000F4061000F8061000FC06100047 +:10395000839FF000D80610002C4810B501682C4851 +:103960000268134692EA010F4ED02A4ACC07126829 +:1039700034D092F82B43E40702D043F001030360F4 +:103980008B072ED592F84033DB0703D0036843F052 +:10399000020303600B0728D592F86033DB0703D0DE +:1039A000036843F0080303604B0622D592F86033A6 +:1039B000DB0703D0036843F040030360CB051CD54D +:1039C00092F8932A520703D5026842F4807202608B +:1039D0008905016815D541F4007114E023F0010355 +:1039E000CDE7036823F00203D3E7036823F008035D +:1039F000D9E7036823F04003DFE7026822F480720E +:103A0000E5E721F40071016010BD00000807100017 +:103A1000F0041000D80610002DE9F047DFF81C92E2 +:103A2000874C0025D9F8000090F8311084F8301048 +:103A300090F83020834884F831205143037B84F888 +:103A4000333000F140032360837B0EB284F82D30C5 +:103A5000804677000FE02A463146D8F808000EF07D +:103A60004EFB0146226806FB05F002EB40003A4699 +:103A700013F061FD6D1C94F82D00A842EBDC724838 +:103A80007249007809780843400711D57048606092 +:103A9000D9F8001091F8F11189074A0F94F8311004 +:103AA000921C4A43D8F81010BDE8F04713F043BD0C +:103AB000BDE8F0872DE9F041634F644C00263D6876 +:103AC00020680543012011F066FD38215C4813F0A1 +:103AD000D3FDE80706D0FFF79FFFE80601D500F009 +:103AE0007EF801265B480078400603D5E80601D53C +:103AF0000CF083FB584801685148C1610562226897 +:103B00004262504A2946554D526882622A7880F8AE +:103B10002C20CA071CD00446C80619D5474F386860 +:103B200090F85002C00706D000F002FE18B9E06914 +:103B300040F01000E061386890F88002C0070CD0B7 +:103B400000F0F6FD48B9E06940F02000E06104E0D3 +:103B50003878400601D50CF050FB012011F036FDFD +:103B6000002E0CD02878052807D0062805D0012182 +:103B7000BDE8F041022011F06EBC0221F8E7BDE87B +:103B8000F081374810B50078002827D12D4CD4E9B2 +:103B9000060100F0D0FD94F83110A06A00F0F3FCAB +:103BA000FFF788FF2548006890F86003C10715D02B +:103BB000810713D50024400913F05AFE00B10124F7 +:103BC000284801788C4209D004700CB1082100E02B +:103BD0001021BDE81040032011F03DBC10BD2DE9BF +:103BE000F0411648174E164C0068B16990F83150F4 +:103BF00090F8307039B1164884F83050C2386A00F5 +:103C0000206113F098FCF16939B1114884F83170E2 +:103C100098387A00606113F08EFC0B480B490078ED +:103C2000097808438006AAD509484C38E0606A0044 +:103C3000716ABDE8F04113F07EBCA0E7D806100021 +:103C400070761000840A1000F4041000F8041000CC +:103C50000E0801200C071000F0041000E80410000A +:103C6000E9041000C8041000174810B5174904787B +:103C70000020086000F07CF800F096FB052C1AD0BC +:103C8000062C18D01249012008701248006890F8DC +:103C90007000000706D41048016821F0020141F0CD +:103CA00004010160012105200DF000FE4FF4807138 +:103CB000002011F0D0FB00F099FD0221BDE810407A +:103CC000012011F0C8BB0000E8041000EC04100053 +:103CD0001B071000D8061000E8061000504910B568 +:103CE0000978012909D0C0070DD04E480324006887 +:103CF00090F85012C9070BD106E04B480078012814 +:103D000001D14A49087010BD90F88002C00700D068 +:103D10000B24FCF773FB4648016821430160FCF764 +:103D20006BFB012105200DF0C1FDBDE810404FF4F3 +:103D30008071002011F08FBB10B5C00717D0394833 +:103D4000006890F8C101010601D440060FD5FCF7C8 +:103D500055FB3848016841F008010160FCF74CFB55 +:103D6000BDE810404FF48001002011F074BB10BD7D +:103D700010B500F03BFD0221012011F098FB01205D +:103D800011F009FC38212C4813F076FC2A49012057 +:103D900081F82C0011F01AFC0121022011F05BFBCC +:103DA000BDE8104000F0F9BA70B52448244E05680B +:103DB000306890EA050426D055B160B104EA0500E8 +:103DC0000446FFF7B9FF2046FFF788FF356070BD56 +:103DD000FFF7CEFFFAE700F009FD0221012011F004 +:103DE00066FB00F0F0F800F0D0FA2C402046FFF718 +:103DF000A3FF2046FFF772FF00F0B6FA0221012070 +:103E000011F029FBE2E7002DE1D10E4800780528EA +:103E100001D00628DBD13560BDE87040A8E700007E +:103E20001A071000D8061000980610001C07100092 +:103E3000E8061000FC061000707610000407100061 +:103E4000EC041000E80410002DE9F041F8480024CB +:103E50002646006890F84010C90738D0F54F3978E9 +:103E6000022912D0042903D005290BD0062909D034 +:103E700090F841500CF0D4F902460021EE48012A96 +:103E80000BD027E090F84350F4E790F8425090F8B8 +:103E90009000C006EED50126ECE73A78052A19D045 +:103EA0000A460160AA4212DDE44A1378B3B1016008 +:103EB00011703878052817D000F0BEF8044600F0DD +:103EC000C1F840EA040500F0CBF840EA05042046BA +:103ED000BDE8F0810268521C0260E3E716B10120E0 +:103EE0001070E6E70160E4E70124F0E710B5014651 +:103EF0004022D34813F064FB0121BDE8104008467E +:103F000011F0A9BA2DE9FF47CA48007802281CD051 +:103F1000032816D0C64EDFF82C93DFF82CA3012718 +:103F20004FF00408052814D0062868462DD000F06C +:103F300027F9C6480090684610F013FF04B0BDE8AA +:103F4000F087684600F0E3F8F3E7684600F0A4F86D +:103F5000EFE7684610F0E0FEFFF776FF04464025E5 +:103F6000C0070BD0306890F87000000704D500F04F +:103F700085F88DF8040001E08DF80480E00601D595 +:103F80008DF806708DF808700FE0002410F0C4FE64 +:103F90003068012590F87000000704D500F06EF835 +:103FA0008DF8040001E08DF80480C9F80040CAF8DB +:103FB0000050BEE710B500F019FC0221BDE810402A +:103FC000012011F048BA9C490020086070479A49C6 +:103FD00000200860704738B5002011F0DCFA9C48DA +:103FE000006810B100F041FA01E000F0EAF99148F0 +:103FF000007800F009F90446AFF2470100F0EEFB4B +:104000002046FFF77FFF01280ED101216B460022D9 +:10401000084611F069FA0121084611F048FA88486B +:10402000007830B10DF06DF9BDE83840002011F096 +:10403000CDBAFFF7A6FDF7E786480078C00700D0A5 +:104040000120704783480078C00707D0784800688F +:1040500090F85002C00701D0102070470020704730 +:104060007C480078C00707D07148006890F880024B +:10407000C00701D010207047002070476C49012014 +:10408000096891F8E710090603D57348407808B12C +:10409000032070470220704770B50646002510F0D7 +:1040A0003BFEFFF7D1FE04466A4861490078C0072D +:1040B00007D1086890F8F00114EAD01F02D0E0069A +:1040C00000D4402544EA0500C0070BD0086890F8EA +:1040D000F00114EAD01F02D058480078A8B1FFF7C9 +:1040E000CDFF307169074FF0010000D57071E10616 +:1040F00000D5B071690600D53072A90600D5F071FF +:10410000504804605048056070BD0920E9E72DE97A +:10411000F041054610F000FEFFF796FE0646FFF759 +:104120008BFF0446FFF78EFF0443FFF799FF04431C +:1041300000F0AFF840EA040700F0B9F840EA0704DD +:1041400046EA0407F8070BD03948006890F8F001F8 +:1041500016EAD01F01D0092001E0FFF78FFF287178 +:1041600061074FF0010000D56871F90600D5A8710C +:10417000A10600D5E8713348066033480460A7E61D +:104180002DE9F041064610F0C7FDFFF75DFE04463D +:10419000FFF752FF0546FFF755FF0543FFF760FFA6 +:1041A000054300F076F840EA050700F080F840EAA1 +:1041B000070527480068810602D50024012503E091 +:1041C000400601D50024102544EA0507F8070BD066 +:1041D0001748006890F8F00114EAD01F01D00920B8 +:1041E00001E0FFF74BFF307179074FF0010000D578 +:1041F0007071F90600D5B071A90600D5F0711148AB +:1042000004601148056063E638B50949801E052839 +:10421000096829D2DFE800F003060922250091F899 +:10422000734022E091F872401FE091F871401CE069 +:10423000D8061000E8041000CC041000E9041000B7 +:10424000840A1000F8041000F40410009D3E0000E1 +:104250000C071000EC0410001007100091F87440D7 +:1042600003E091F8754000E0012400250CF0BAFD50 +:1042700000B101256946032011F027F9009800B923 +:104280001DB1142C01D2142401E004B901242046EC +:1042900038BD0E480078C00707D00D48006890F878 +:1042A000F001C00701D00420704700207047074884 +:1042B0000078C00707D00648006890F81002C007D1 +:1042C00001D020207047002070470000EC0410004F +:1042D000D80610007A4810B5006890F87000C00742 +:1042E0000BD013F019FB012804D07648017829B1CE +:1042F000407818B174490020486010BD012010BDFD +:1043000010B5FFF7E7FF012814D100F011FA88B9C2 +:104310006E486D4C00886168401C00EB8000B1EB7A +:10432000400F07D913F0F8FA012801D0012010BD81 +:1043300000206060002010BD10B500F090F900F082 +:10434000F1F961490020486061490220087010BD00 +:1043500010B500F084F900F0E5F95B4900204860F1 +:104360005B490320087010BD10B500F078F900F02B +:10437000D9F955490020486055490420087055492D +:10438000012008705449087010BD4F490020486052 +:1043900070474D490020486070474B4900204860F5 +:1043A0004B4901200870704710B500F055F9464997 +:1043B000087000F054F900F0B5F94549052008707F +:1043C00010BD70B5424D00263F4C2878801E042851 +:1043D00010D2DFE800F03120023F00F05FF8012842 +:1043E00007D06068401C606000F060F8012802D0CF +:1043F0000CE0666070BD32486168006890F8780033 +:104400000A30884202D2BDE87040A1E7FFF778FF8A +:1044100001280ED070BD00F041F8012817D0606867 +:10442000401C6060FFF76CFF012802D000F03EF8EE +:104430000BE0BDE870407FE700F030F8012806D0BF +:104440006068401C6060FFF745FF0128E2D0BDE8CE +:10445000704089E700F000F908B1217809B12070B7 +:1044600070BD20700620287070BD00F0600151EA18 +:10447000C072174901D0042002E0820702D5032050 +:1044800008707047420701D50220F9E7020701D5FD +:104490000520F5E7C006F4D50620F1E710B500F0D9 +:1044A000DBF804460BF0BCFE204310BD0448006856 +:1044B00090F87000800701D50120704700207047F8 +:1044C000D8061000A4061000D00410001807100031 +:1044D000E804100014071000150710002DE9F04142 +:1044E0008B4C07460E462068002590F89820894896 +:1044F0000EF0A3FD02008848294640D0027801252D +:10450000521CD2B20270236893F89930934237D28A +:1045100001708048760032463946543813F00BF863 +:104520007C48324639462A3813F005F87B4F3878F4 +:10453000052825D02068032690F85012C90703D11A +:1045400090F88002C00700D00B26FBF757FF744895 +:10455000016831430160FBF74FFF3878052804D12B +:10456000206890F8EB03C00603D5202105200DF04C +:104570009DF94FF48071002010F06DFF00E0017094 +:104580002846BDE8F0812DE9F05F060059D0624C65 +:104590000025DFF88891E5702F4699F80000AA46BB +:1045A000022803D0032801D0052849D1B4F90450CA +:1045B0003046A278294600F065F8DFF85481A070F3 +:1045C000D8F8000090F89000800704D530462946BE +:1045D000FFF784FF074600214E4B08464FF0010BC2 +:1045E000D8F800200FE000BF33F91060B2F892C095 +:1045F000664506DD92F89160491C8E4201DC5D46FD +:1046000004E0401CC0B2A842EEDB554699F8000019 +:104610004E46022801D0032802D113F07DF905434C +:1046200075B13078022804D0032802D0052804D0C0 +:1046300006E0657084F803B006E0607800B917B151 +:104640006570BDE8F09F657000F0D0F8BDE8F05FE0 +:104650000221012010F0FFBE2F48407870472E48FD +:104660000021012201708270294A126892F83120DB +:1046700082802A4A1278052A02D0062A00D0417088 +:104680007047ECE72DE9FC418046234814460D466F +:104690004078164640B91F480A467F2341465438A1 +:1046A00000940EF029FD0026194F386890F89010FC +:1046B000C90700D0ECB117486A0041462A3812F009 +:1046C0003AFF144A2B46543A02F12A0111480EF0DF +:1046D000D2FC386890F89010490707D590F89A30C6 +:1046E00023B10C492A4608460EF01FFD3046BDE8AE +:1046F000FC81B0F99610CDE90015064AB0F9943066 +:10470000543A414602F12A000EF03CFCD9E7000081 +:10471000D806100092090120D8041000E804100007 +:10472000E80610000F480021017041607047F9E76A +:104730000C48007870470B4800210278012A01D00C +:10474000416070474268084B521C42601B6893F8F6 +:1047500081309342F5DA01704160002107200DF0AD +:10476000A5B80000E0041000D806100008B500F05D +:104770003FF8304C6B4600227E21012010F0B4FE41 +:104780000098410703D5FFF70FFB042119E001074B +:1047900003D5FFF7E1F8082113E0C10603D5FFF7C1 +:1047A00063FA10210DE0810608D52078052801D094 +:1047B000062801D1FFF758FA202102E0410604D56E +:1047C0004021012010F073FED4E78007D2D50221EA +:1047D000012010F06CFEFFF7FEFBCBE700EB800042 +:1047E0004FF6FF7202EA400012F01CBC12F03CBC13 +:1047F00010B5104C002001216060A06021700E49AE +:10480000607008700D4908700D490870FFF739FF96 +:10481000FFF78DFFFFF7DBFBFFF7BBFD09480068E3 +:1048200090F84003C00703D0A06840F00200A060E9 +:1048300010BD0000E80410001A0710001B0710004C +:104840001C071000D806100000F070BE45484078E4 +:1048500000280DD04448454990F82C0091F82C10C0 +:10486000C84205D10123424A40493F4800F015BAE9 +:10487000704770B50024012390F82C5008E0C6184A +:1048800096F921608E4202DB964200DC641C5B1CC0 +:104890009D42F4D2012C01DC012070BD002070BDCE +:1048A0002DE9F043994600231F4647F6FF764FF067 +:1048B000FF3C012590F82C400DE000BF00EB0508FF +:1048C00098F92180884505DB904503DC431993F96D +:1048D000213002E06D1CAC42F0D2641C0AE00519E4 +:1048E00095F921508D4205DB954203DC204490F977 +:1048F000217001E0641EF2D1BB4209D10AE000BF81 +:1049000039F91300B04202DA06464FFA83FC5B1C09 +:10491000BB42F5DD6046BDE8F0832DE9F041174666 +:104920000E460446C27881780F48FFF7A2FF0500C3 +:1049300006D1E278A1780F4B0B48FFF7B1FF30703A +:10494000627821780948FFF794FF060006D1627863 +:104950002178094B0548FFF7A3FF387005EA0600E8 +:10496000BDE8F081B0511000B823100010241000F1 +:1049700070261000F80A0120220B012010B55821E2 +:10498000FD4812F079FEFC485821583012F074FEB0 +:10499000F9480021B030C0E90011C0E9021110301F +:1049A000C0E90011C0E902111030C0E90011C0E9EE +:1049B00002110846F149086010BD2DE9FF5F064667 +:1049C0008946EF48EF49984600780968144601285F +:1049D00050D0B1F986A291F88852B1F9827211468D +:1049E00048460EF0F4FB8346214648460EF00DFC87 +:1049F0000090394658460DF06EFB0FFA80FB3946A1 +:104A000000980DF068FB00B2ABEB00006843642136 +:104A100090FBF1F0384405B2A8F80850701C002152 +:104A20000390C8F80010C8F80410B9F90000A842B3 +:104A300002DD03990120087009EB4400761C30F96F +:104A4000022C3119AA4202DD012201F8012CB9F928 +:104A5000023003EB0A0212B2AB4218DDB9F90030A2 +:104A6000934203DDB9F9043093420ADC039B01222F +:104A70005A700CE0B1F96AA291F86552B1F9667208 +:104A8000ADE7D8F8006046F00206C8F8006030F9DB +:104A9000043CA4F1020B03EB0A0212B2AB4216DD96 +:104AA00030F9063C934203DD30F9020C904203DCFE +:104AB000012001F8020C0AE0D8E900645A460120FE +:104AC000002112F001FD06430C43C8E900640224F2 +:104AD00058E000BF39F91400A84252DD09EB440147 +:104AE0000291504431F9021C00B2814204DD029A65 +:104AF000B2F90220824210DC029A32F9042C82427E +:104B000004DD029AB2F90220824206DC814235DDE0 +:104B10000299B1F90410814230DDD8E900672246DC +:104B20000120002112F0D0FCCDE9000106430F4323 +:104B3000621E01200021C8E9006712F0C5FC024690 +:104B40000B4606EA020007EA0301084319D002985F +:104B500039F9141030F9020C814209DA96439F4367 +:104B6000C8E9006703990120214401F8010C08E01D +:104B7000DDE900108E438743C8E9006703990120EF +:104B80000855641C5C45A5D3BDE8FF9F2DE9FF4F88 +:104B900081B0824600211D4683F82C100B209046E0 +:104BA0004B1E794C08E0002229188A7581F82130C3 +:104BB00005EB400122880A80401EF4D2704801783B +:104BC00070480129006806D0B0F984224FF0000B2C +:104BD0005946584616E0B0F96822F7E70AEB000399 +:104BE0005C7874B11AF800400CB9491CC9B259700C +:104BF000029B33F91030934203DD01238B4043EADB +:104C00000B0B401C4045E9D3604800900E984FF0D4 +:104C100000094C46C0E9009938E000BF0AEB0400E7 +:104C2000427892B30121914011EA0B0F02D1002189 +:104C300041702AE01AF8041039B909F1010101F0B4 +:104C4000FF095249009105F8194080F801900E982B +:104C500022460021D0E90067012012F035FC06430E +:104C60000E980F43C0E9006705EB0900817D491CE0 +:104C7000817505EB49014C700299009A31F91410C5 +:104C8000914202DD009180F82140641C4445C5D367 +:104C900085F82C9005B0BDE8F08F2DE9F84F0C4653 +:104CA00005461E4691461721394812F0C3FC2821BB +:104CB000384812F0BFFCDFF8E0A0384F09F10808CF +:104CC0009AF8001076B10A4605F1300334493048AD +:104CD000FFF773FE04F130033A7832492D48FFF7AD +:104CE0006CFE11E04A462A4800F0E9F8424639785D +:104CF000284800F0E4F80020C5E90C00C4E90C00E5 +:104D00002948008828872087284E288F2B4626F898 +:104D1000110F208F7080CDF800909AF80020204964 +:104D20001B48FFF733FFCDF8008023463A781D4932 +:104D30001848FFF72BFF95F82C10307961F303002A +:104D4000307194F82C1061F307103071BDE8F88FC2 +:104D500070B50C4C206890F83012090743D51449FF +:104D60000A780AB9497831B105490978012921D071 +:104D7000B0F8421220E036E0B8231000FC04100026 +:104D80000E051000D80610004C7901000080FFFFCE +:104D9000AE0B0120C50B0120590610005A06100069 +:104DA000F80A0120220B012014051000B85301203D +:104DB000B0511000B0F8481201220DB2B0F94412FF +:104DC0004B4800F04AFA20680022B0F946124848E1 +:104DD000103000F042FA2946BDE8704044480122F4 +:104DE000103800F03ABA42484FF0FF31C0E90011E4 +:104DF000C0E902111038C0E90011C0E902112030E9 +:104E0000C0E90011C0E9021170BD2DE9FF4F83B068 +:104E10001546069991F8461002290CD001290CD0AC +:104E2000334910398A464FF0000BA97812F0A2FDE1 +:104E30008146A87832E02E49F4E72D491031F1E798 +:104E400002462C780120002112F03EFBCDE9000142 +:104E50001DE000BF19F804100498814216D1DDE965 +:104E60000023DAE9000110401940084323D0DAE9B1 +:104E7000026722460120002112F026FB06400F4067 +:104E80003E4318D00BF101001FFA80FB641C6878C8 +:104E9000A042DFDA09F1280908F10100E97880462B +:104EA0004145CDDA06995FEA0B00A1F826B000D0A3 +:104EB000012007B0EFE6002009F80400E6E72DE93D +:104EC000F0479146451C0C464FF001080CE0D9E92B +:104ED000006722460120002112F0F6FA06400F403A +:104EE0003E4301D005F80480641EF0D2BDE8F0878F +:104EF000782410009D4A10B513680021B3F81422DD +:104F0000824205DA93F81022520701D5022108E007 +:104F1000B3F81222824204DA93F81002800700D517 +:104F200001219348934C4278914214D1A178914247 +:104F30000DD0914B1B781A43904B1B781A4307D026 +:104F40004168491E4160002901DC4078A07010BD15 +:104F500041704168F7E759B1022901D1012A07D010 +:104F600093F8182242604170002AF0DCA17010BD55 +:104F700093F81922F6E770B5814A824B7D4D167879 +:104F80007A4A9C7900211268AB78012E02D17E4EBC +:104F900036784EB1B2F81462864217DA92F810628F +:104FA000760713D5022125E0B2F81C62864203DAA7 +:104FB00092F810627607F5D4B2F81A6208E000BFE2 +:104FC00092F81002800705D5012113E0B2F81262B1 +:104FD0008642F5DB73B168480078012803D0674842 +:104FE0000078012803D192F81002000701D5012CA6 +:104FF00000D119465E4834B119B100BF92F81922A8 +:105000004260A97070BD0029F8D1002BF6D0446829 +:10501000002CF6DD92F810120A0755494968A1F1F3 +:10502000010102D5594A127802B141601946E8E7F8 +:105030004E484F49006890F81002C2064FF0000039 +:1050400003D44C4A9070487048600870704710B59F +:1050500004464648006890F81002C006204602D573 +:10506000FFF789FF01E0FFF745FF42488278484893 +:10507000417B62F307114173A0F82F4010BD2DE969 +:10508000FC5F8346434800250A46067800782F4691 +:1050900041002C46012A17D0DFF8D0A0DFF8F880B5 +:1050A000DFF8F890DAF8000090F81022920610D598 +:1050B000B0F92012CDE90016B0F91E324246594629 +:1050C00048460DF05FFF09E033484C3812F0B2FA61 +:1050D00042E00A465946314812F02DFA2E484C3823 +:1050E00035E000BF38F9142039F91410511A00D5F1 +:1050F0004942DAF8003009B293F8102252060BD573 +:10510000204A9279012A07D1254A127822B9B3F8A8 +:1051100022228A4200DA012730F914208A4202DA78 +:1051200093F8163201E093F817325A43C3F58073AF +:1051300001FB0321CA1701EB1261091220F81410B8 +:1051400030F91410A94200DD0D46641C24B2B442AB +:10515000C8DB2846FFF77BFF720059460E4812F065 +:10516000EAF903480770BDE8FC9F0000D80610006C +:105170000005100010071000600610000C0510005C +:1051800061061000B05110006206100066061000A3 +:10519000B853012059061000080A0120540A0120C2 +:1051A000200510002DE9F04F8146DDE909B5012009 +:1051B00047F6FF779A468446FE432C4615E000BF2B +:1051C00032F8143031F81480A3EB08031BB2BB4251 +:1051D00000DA1F46B34200DD1E46002B02DD4FF011 +:1051E000000C02E001DA4FF00000641EE8D220B1AA +:1051F000BCF1000F01D0002309E050EA0C0306D0F7 +:1052000020B9BCF1000F01D0334600E03B46002737 +:105210003C462846CBF1000C0EE000BF32F810608F +:1052200031F81080A6EB0806F61A36B2564503DAB6 +:10523000664501DD3744641C401EEFD204B90124E9 +:1052400097FBF4F0184404E031F81520024429F8E3 +:1052500015206D1EF8D2BDE8F08F2DE9F0411546FE +:105260000E46044603460A46FE480178FE4800F012 +:1052700099FCFE4804F108031F460178FA483246BB +:105280002A3000F08FFC002D07D0204612F054FB8E +:105290003846BDE8F04112F04FBBBDE8F0812DE982 +:1052A000F00FF3498246DDE909400968089E9146FE +:1052B00091F82B124FF0000B01F0030C012801D0E4 +:1052C000002236E000200BE004FB00F103EB41027A +:1052D000DAF800501560BAF80410401C918000B252 +:1052E0006045F1DBA6F800B0BDE8F00F704700BFE5 +:1052F0003AF91200B6F900500146002712E000BF4B +:1053000004FB052833F91880884500DA41468045BA +:1053100000DD4046002D02DD6D1E2DB200E00225AD +:105320007F1C3FB26745EBDB401A29F81200521C84 +:1053300012B2A242DCDB47F6FF71002007E000BF9B +:1053400039F910208A4200DA1146401C00B2A0420E +:10535000F6DB002007E000BF39F81020521A29F8C8 +:105360001020401C00B2A042F6DBB6F90000022873 +:1053700002DA401C308001E0A6F800B0B6F9000067 +:10538000620060435146BDE8F00F03EB400012F0AD +:10539000D2B830B5002B0DD1B54B1C6894F828322B +:1053A000B4F829429D07B34B04FB04F41B6802D5F3 +:1053B0009C4208DC30BD9C42FCDDAF4B9C7814B9AC +:1053C0005B78002BF6D000230AE000BF30F91350C1 +:1053D00031F91340A54201DA20F813405B1C1BB2DF +:1053E0009342F3DB30BD2DE9FE43804617468946E4 +:1053F000032010F0D0F8A14C9A4D00979A482A78D3 +:105400004146763823680DF05DFE984E0097964829 +:10541000327849464C3823680DF054FE944C20688D +:1054200090F83012C9071AD02A78B0F93412CDE9B1 +:1054300000128D49B0F932327639914A0846FFF7A9 +:10544000B1FE20683278B0F93812CDE900128649F1 +:10545000B0F936324C398B4A0846FFF7A3FE824931 +:105460002B78874A763980480DF005FE7E493378DF +:105470004C39844A01F176000DF0FDFD206890F86A +:1054800030128A0704D4804A12788AB149070FD5AE +:10549000754990F841322A7808460DF046FE20689A +:1054A0007149327890F841322A3108460DF03DFEBC +:1054B000206890F82802C10733D0400701D56A4818 +:1054C00000E040462978714ACDE90021704B0297EF +:1054D00003F5B1726A49FFF7E2FE3B462A786D494F +:1054E0006148FFF756FF206890F82802400702D570 +:1054F0005D482A3000E048463178644A644B921C8B +:10550000CDE900217E33029703F587725D49FFF7ED +:10551000C6FE604954483B4632782A312A30FFF7AC +:1055200038FFBDE8FE43032010F050B870B5574C6B +:105530005949083C0025A571012008704C48257187 +:1055400065710068B0F83A02A08100F07EFB256129 +:10555000656170BD2DE9F0410E464F494B4C074641 +:105560000D780020083C0870607100F06EFB2A4640 +:1055700031463846FFF737FF3F4841783C4800291D +:10558000A17915D0012919D00068B0F93C12414D1C +:10559000A181763501222846FFF75FFED5E900019B +:1055A00008430FD0D5E9020108430BD001200AE0DF +:1055B000012903D00068B0F93A12E8E70068B0F9B1 +:1055C0007812E4E70020207167E62DE9F34F834667 +:1055D0003248002740F6FF7401782548A7B02546D9 +:1055E0000068012909D02849097849B12C4909786E +:1055F000012908D002290BD00EE0B0F959420BE086 +:10560000B0F9524201E0B0F95442B0F9CE5B03E088 +:10561000B0F95442B0F9D05B124801214FF0000EAE +:105620000078204E801E00F0FF0910480278931E7B +:1056300003F0FF080BEB42039A460CE0704605E0CE +:1056400033F910C0B44500DD6646401C4045F7DD27 +:1056500003EB4203491C4945F0DDDFF8108052009E +:10566000514621E059061000F80A01205A061000A0 +:10567000D806100090061000100710000C0610004D +:10568000286D0120526D012020051000100510002A +:1056900098241000FA2510001507100026051000A8 +:1056A000210510000080FFFF684611F044FF98F8C4 +:1056B00000004142FE4A6B46128802EB410109B2EA +:1056C00042000BEB410103EB400011F034FF98F86E +:1056D00000006946420008460DF045FD301A289A40 +:1056E000F44900B2022A05D0A1F85000A84204DD16 +:1056F000022705E0A1F85200F8E7A04200DD0127EB +:10570000ED490A88521C0A80EC4A12784A808C8043 +:10571000CD800881384629B09DE52DE9F14FE84854 +:10572000E84A4FF000090068FF261278B0F8D2ABC3 +:1057300085B04946354632B1E04A1278012A05D093 +:10574000022A08D00BE090F8D46B01E090F8D56BFA +:1057500090F8D65B03E090F8D56B90F8D75BDA4809 +:1057600001230078801E00F0FF0E039003200490B8 +:10577000D6480278901E00F0FF0B0290059800EBCF +:105780004204019429E0DFF830C39FB204980CF181 +:10579000200C00971CE000BF04EB400834F91070A7 +:1057A00038F9048CB7EB080700D57F423FB2574564 +:1057B0000DDDACF80400DDF80080ACF80680DFF801 +:1057C000F882491C08F13008C9B2A8F80070401CE2 +:1057D0005845E1DD04EB42045B1C7345D3DDB6485C +:1057E0000323303002EB420481800398C0B2009062 +:1057F00001200390029800F0FF0B059800EB440C89 +:10580000019C32E04FF0000E039820E03CF910704C +:1058100034F91080B7EB080700D57F420FFA87F8FC +:10582000D04513DDA44F2037491CA7F800803881EC +:105830007B813CF81080A7F80C8034F81080A7F822 +:105840000E800EF1010707F0FF0EC9B2401C58454B +:10585000DCDD9F480CEB420C04EB42040778F04679 +:10586000774500D8474607705B1C00988342C9DD26 +:10587000A94201D9022002E0B14201D901208146AA +:105880008D4820304180484606B0E4E4F0B58A48AF +:105890008A4B0022018A491C01828D494C7844823E +:1058A0001E788682CD78C5828F780783A64205D17F +:1058B0008A70CA70C18B491CC183F0BDDFF800C279 +:1058C000B442DCF800C010D907F10107CA70FDB27C +:1058D0008D709CF8626206F00F06B542EDD91C701F +:1058E0008A70418B491C4183F0BDFDD26D1C8A70CA +:1058F000EDB2CD709CF86262B5EB161FF4D91C7046 +:10590000CA70818B491C8183F0BD2DE9F047DFF817 +:10591000B891054699F8000002285DD96D480078D5 +:1059200018B96D480078012856D06C4E0124022128 +:105930003068FFF74AFE074603212846FFF745FE79 +:1059400005463068FFF7E9FE0146AF4201D9284617 +:1059500000E03846814200D90846614A127802B117 +:105960000020574E5A4B326893F8008092F8D8CBFB +:10597000C44502D80020587002E0587000B10024DD +:105980004D4841818781C58192F85002000722D598 +:1059900099F8002053485449022A1CDB534D531EEA +:1059A00005E000BF30F91370AF4200DD3D465B1EDD +:1059B000F8D1801C921E0DF0D6FB3168281A3D4AA2 +:1059C00000B2B1F95712A2F85400884203DD3CB18D +:1059D0000220BDE8F0870CB10020FAE70120F8E7CB +:1059E0000320F6E72DE9F04107464148164600241A +:1059F0000078D8B33848334D007800B33D48344977 +:105A00001031006800F0EFF82D483149006810317E +:105A10000A68B0F85F329A4217DDB1F9061090F8C3 +:105A20006102814211DD3548334AB0F90010384631 +:105A300000F05CF9044644B100F02EF90CE02C783B +:105A4000012914D00029F6D1002496B12C49002058 +:105A50000870287800B10124FFF718FF294E287834 +:105A6000317888420CD038B1012106E00DE00124E4 +:105A7000E2E700F027F9ECE7002106200BF016FF23 +:105A8000287830700CB1012007E4002005E470B5DF +:105A9000044603200FF07FFD2046FFF736FF044643 +:105AA00003200FF093FD0349C87B64F305102BE03E +:105AB0006A061000B85301206E0B0120210510006A +:105AC000D806100020051000590610005A061000D4 +:105AD0000805100025051000260510008806100096 +:105AE000A4061000286D0120540A01200080FFFF49 +:105AF000B05110008006100070261000080610003B +:105B00002405100022051000C8735748017821B100 +:105B100000210170204600F062F9544D544821469E +:105B20002A790068FFF75EFFA87170BD70B5514A11 +:105B30000024234612782146521E52B24E4D0DE0EB +:105B400035F91260864202DD491CC9B204E08C427C +:105B500000D921460C460021521E52B2002AEFDA2B +:105B60008C4200D92146454C00222478641E65B23F +:105B7000414C2A340EE000BF34F91560864202DD44 +:105B8000521CD2B204E0934200D91A4613460022B6 +:105B90006D1E6DB2002DEFDA934200D91A468818B7 +:105BA000C0B270BD2DE9F0471D464FF00008C5E9B1 +:105BB0000088914682460C4611E000BF3AF9141065 +:105BC00049450CDDD5E900674FF001082246404603 +:105BD000002111F079FC06430F43C5E90067641EFC +:105BE000ECD24046F5E630B5254A1268B2F85D229F +:105BF000524213B20022CA808A800A60214AB2F956 +:105C0000002012E030F91240002C0EDA8C88641C5F +:105C10008C8030F912500C682C440C6030F9124022 +:105C20009C4202DACC88641CCC80521EEAD2164A0E +:105C3000887982F858000868002800DA4042A2F803 +:105C4000590008684042086030BD10480021C0E992 +:105C50000011C0E9021108460D4981F82C000D49D8 +:105C600081F82C0070470000250510000805100081 +:105C70008006100059061000F80A01205A0610008C +:105C8000D80610006A061000B853012070261000D4 +:105C9000B823100010241000574800210171027829 +:105CA000002A0ED1C278554B521CD2B2C2701B686A +:105CB00093F8623203F00F03934202D20122027082 +:105CC000C17070474C480021C1700278002A0CD086 +:105CD00002794A4B521CD2B202711B6893F86232AD +:105CE000B2EB131F01D90170017170472DE9F74F15 +:105CF00086B08B46D2E90001CDE90201D2E902016A +:105D0000CDE9040102A811F017FE04A811F014FE59 +:105D10003B4800252F4606782FE0F1B2069811F097 +:105D200021FE82463748324600210478012011F0D6 +:105D3000CBFB029A00EA0208039801EA0009DDE9B8 +:105D40000401CDE9000116E03AF91410594512DDBD +:105D500058EA09000DD022460120002111F0B4FBC1 +:105D6000DDE9002310401940084302D07F1CBFB278 +:105D700001E06D1CADB2641EE6D2761ECDD2224883 +:105D800000F8565F47701D48006890F85B12A94202 +:105D900007D890F85C02B84203D3012009B0BDE8EF +:105DA000F08F0020FAE7144810B5817801700021C7 +:105DB000C1700171FFF7BAFBBDE81040FEF7DEBD10 +:105DC0000D4800210D4A017041708170126892F8EF +:105DD0005022920700D501218171417170470B4912 +:105DE0000A780549012A04D08A79012A03D10028BA +:105DF00001D100208871704720051000D8061000DE +:105E0000590610005A061000B85301201C07100054 +:105E10002DE9FF5FFE4F0546DDF838B0386898463B +:105E200090F8A512B0F9AC42490607D590F83100B8 +:105E3000FF22C100F748103111F0F4FBF648417819 +:105E400009B9807810B13868B0F9AE420026DFF8A1 +:105E5000C493BA4621E000BF02990BFB06F001EBA8 +:105E6000400739465A4608460CF0BAF822465B46C7 +:105E7000114638460CF0D6F8DAF8002092F8A6223F +:105E800012B15B460CF0EEF809EBC602C2E9020162 +:105E900005EBC602761CC2E900014645DCDBDAF8F8 +:105EA000000090F8A502400619D500204B46DFF807 +:105EB0006CC310E003EBC00797E80601FE6801EA37 +:105EC00008013240D7E90467314005EBC0063A408B +:105ED000C6E90012401C9CF800108842EADB20460C +:105EE00004B0BDE8F09F08B5009380230DF0DAF808 +:105EF00008BD70B5B1F90050B2F90060049C75435B +:105F00005B1EEE17634305EB5665641EED11A4B2EC +:105F1000058031F91450B2F902609BB27543EE1757 +:105F200005EB5665ED1120F8145031F91350B2F914 +:105F300004607543EE1705EB5665ED1120F813501C +:105F40002344B2F9062031F913105143CA1701EB6B +:105F50005261C91120F8131070BD08B500931346A3 +:105F6000AF4AB2F900200DF0ADF808BD2DE9F05FA1 +:105F7000A94DAC4B00216A789878DFF8AC92022AE0 +:105F800000D230B189F80210022A00D208B189F893 +:105F9000031099F806209A46024301D089F80410AC +:105FA0009B4CA24920680978B0F91873B0F9428374 +:105FB000062901D1B0F9167399F8031029B19C494B +:105FC0000978012901D1B0F9507311F08FFC50B15B +:105FD000206890F81B1390F84503394440440FB2F1 +:105FE0000FFA80F808E06878022805D32068B0F836 +:105FF0001C1309B1B0F91C7399F8060080B1206830 +:10600000642190F8690300FB07F200FB08F092FBA3 +:10601000F1F290FBF1F03A44404417B20FFA80F8E5 +:10602000844E8549854D3780A1F80080206890F81E +:106030001A23BA1A2A8090F84423A8EB0203804A54 +:106040001380804B93F800C0BCF1000F02D09B7806 +:10605000FB1A2B8099F800304BB17B4B1B7833B186 +:10606000B0F86C32338090F86E72DB1B2B809AF89C +:106070000230D04633B1B0F86C32338090F86E0203 +:10608000181A288099F80230704823B9704F338865 +:106090003B802B88038099F80330CB461BB93388AB +:1060A0000B8029881180B0F90010B2F90020B5F9F1 +:1060B00000000BF0FEFF674FB146DFF8A0A138806B +:1060C0003088654E308066482988AAF8001000782C +:1060D000A8B111F00BFC10B1206890F83D042168C4 +:1060E000B1F83A241044308091F83C14401A01B2BF +:1060F000AAF80010B7F900000BF0E9FF3880594EFC +:106100005949B9F800003080584A08802888108022 +:106110009BF804005D46F8B12068B0F8B03923B1AF +:10612000AB7913B1B0F8B03904E0B0F8AE3913B1BF +:10613000B0F8AE393380B0F8B23933B1B0F8B23913 +:106140000B8090F8B409181A1080B2F90010B7F952 +:1061500000000BF0BCFF38803B48454F007818B179 +:106160002068B0F8C4020EE098F802000028F7D1C9 +:106170002068B0F9C20238802979002904D0B6F924 +:1061800000100BF0A4FF3880ABE62DE9FF4F85B07F +:106190000746082112A8149D0FF060FF0490002804 +:1061A00069DD4FF0000ADDE912015646D046D346BC +:1061B000D146CDF804A05446CDF800A0CDE90201A7 +:1061C00015E022460120002111F07EF9DDE90223CD +:1061D00010401940084309D037F9140004FB048823 +:1061E00004FB00990AF1010A26448344641CAC4272 +:1061F000E7DB08FB0AF006FB1602DAB309FB0AF03C +:1062000006FB1B0308FB0BF009FB1604002053E000 +:10621000D80610003827100010071000590610008B +:106220006A06100028051000B0511000E8041000A4 +:1062300065061000FC0510000006100002061000A4 +:1062400006061000A4061000200510000406100029 +:10625000FE051000080610001406100016061000B7 +:10626000160710001C0610001E0610002006100065 +:106270000A06100022E034E003FB004191FBF2F13A +:10628000069EB14201DD314603E0F14201D5069997 +:10629000494237F81060711A09B227F81010079EAA +:1062A000B14208DA0E44002E05DD019E3144019111 +:1062B0000099491C0091401CA842DDDBFE480068A3 +:1062C00090F8A712049881420BDDDDE9001090FBE5 +:1062D000F1F004E037F81510091A27F815106D1EB3 +:1062E000F8D209B0BDE8F08F2DE9FF5FF34C884686 +:1062F00000260746924635464FF4667140462660B2 +:1063000011F098F90021404611F034FB814600213C +:10631000384611F027FB0022E94BEA4F2AE0002122 +:106320004FF0010EDFF890B319E000BF30F9118093 +:10633000D04505DD09F801E030F911C0761C65444F +:10634000DBF800C030F91180BCF855C3E04505DD2D +:10635000D4F800C00CF1010CC4F800C0491C93F83B +:1063600000C06145E2DB0CF0FF0109F1280900EBF8 +:106370004100521C39788A42D1DB039805603046CF +:10638000AEE505E030F912308B4201DD01207047A7 +:10639000521EF7D2002070472DE9FE4FC64C8146B1 +:1063A000C94E20684FF0000590F8A532DB0607D5EE +:1063B000C64BB0F8D3021B684043834200DD356012 +:1063C00013463268C24E3068FFF7C7FD03200FF056 +:1063D000E2F82068BB4F90F84003C00714D0BD48D6 +:1063E000007888B93978BC480CF0FCFE2168BC4ABA +:1063F000B1F85833B949984204DCBA4883780BB9EC +:10640000407820B3CD701570B7483168B0F90030CE +:10641000B648026848460CF02EFE05F017FC032033 +:106420000FF0D4F82068A64E90F8A412090624D5DF +:10643000B0F9B0B2307800904A463B781146AC488B +:10644000FFF7E6FC82460025DFF8A48212E0012077 +:10645000C870D9E708EBC5023378D2E900128DE89D +:106460000E0003FB05F009EB40005A465146FFF7CA +:106470008CFE6D1C38788542ECDB206890F8A40215 +:10648000400708D533783A78494603B00846BDE856 +:10649000F04F00F08FBBBDE8FE8F2DE9F0410A46BA +:1064A00080460026934D3146104611F063FA0446AB +:1064B0000021404611F064FA024681480021037829 +:1064C000804890F800C012E0002009E0275C2FB15E +:1064D00032F91070AF4201DDC6B23D46401C00B239 +:1064E0009842F3DB491C02EB430209B228346145B0 +:1064F000EADB202E01D0212E1FD10721404611F0CA +:106500003FFA6D4C30F9401F6425226892F8B52A95 +:10651000514391FBF5F142881144418008214046E6 +:1065200011F02EFA226830F9401F92F8B52A514333 +:1065300091FBF5F1428811444180BDE8F0812DE9DD +:10654000F04780465C489946174605686A480E46FB +:106550000024006805F6A73511F004FAB8EB07022D +:10656000A6EB090100D55242002900DA4942501831 +:10657000C0B2142800D82C5C2046BDE8F0872DE975 +:10658000F04704464C485D4A006832F9118000F635 +:10659000C330B8F1000F05DD594D35F914A0BAF13B +:1065A000000F03DC807A4043000AE6E732F811204E +:1065B00035F8145002EB82024FEA4209514A05EBCA +:1065C00085056F00B2F900C0B2F9026099FBFCF3D7 +:1065D00097FBF6F5C3F10A03C5F10A05C35C455DF7 +:1065E00003FB05F0000AC828C7D9518199FBFCF1CB +:1065F000A2F80C80C1F10A01D18197FBF6F1138258 +:106600005482A2F814A0C1F10A01D18215835083EB +:10661000B3E770B520213B4811F00CF8294A00215E +:10662000364C3848137809E0B0F9005034F911209D +:10663000954200DD2A46491C0280C9B29942F3D333 +:106640001F4A00212E4C13780AE000BFB0F9022047 +:1066500034F91150AA4200DC2A46491C4280C9B2D2 +:106660009942F3D370BD2DE9F05F8A468346FFF768 +:10667000D0FF0026B146DFF84C805AE01E48314674 +:10668000006811F07DF9054600240D4F4CE000BF75 +:1066900035F91400002845DD53465A463146204658 +:1066A000FFF74DFF80B335F914104143081225F868 +:1066B00014003146204628E0D8061000F0051000EE +:1066C0005A061000590610000C0610009006100023 +:1066D00084061000A4061000286D0120B05110009F +:1066E00063061000100710006A06100088061000EC +:1066F000802610000080FFFF7C061000F80A0120B1 +:10670000220B01203212012018E0FFF738FFA8B158 +:1067100035F914104143091225F81410FE498C80F4 +:10672000CE800881641CE4B238788442B0D3761CF1 +:10673000F6B298F800008642A0D325E525F814901B +:10674000F0E72DE9F04700252C46DFF8D093DFF87D +:10675000D083F44EF44F17E02146D9F8000011F031 +:1067600001F90021424633780AE000BF30F911C038 +:10677000AC4503DD30F8115011705470491CC9B29A +:106780009942F3D3641CE4B238788442E4D3F4E64B +:106790002DE9F84F0646E5480025924604788B46D9 +:1067A0000570FFF7E3FBDE480221001D09F07CF8CD +:1067B0002246DB4C31466068FFF7EEFDDC4EDD4FD4 +:1067C000316891F8A402020705D4C00603D491F8F9 +:1067D000A502C00706D06168B7F90030D64A08465E +:1067E000FFF781FB3068B14690F8A50280060AD514 +:1067F000CC48D14A00780090CB486168083A0378C9 +:106800000846FFF776FBB7F9000061684200CB4805 +:10681000006810F090FEDFF8288398F8000010B9A7 +:1068200098F8010028B1514658466268FEF792FE7A +:1068300001E0C4480570B94EB7F900006168420034 +:10684000306810F078FEB6480221001D09F08FF87C +:1068500098F80000DFF8F0B2C24628B39BF80000B9 +:10686000012821D1D9F8000090F8A50240071BD5D6 +:10687000A078C8B90120A070FFF778FB012108209B +:106880000BF014F8B148007802280DD12078009060 +:1068900094F80180FFF755FF4046B8F1FF0F03D091 +:1068A00001460098FFF7DFFEA648007830B19AF85D +:1068B000010018B19BF80000022828D0A448B7F9BD +:1068C0000020B0F900103068FFF75BFDA149A24F2E +:1068D000F8B10120087001460224A04808F0E4FF46 +:1068E000A0489E4D9E4BB0F9002029683068FFF704 +:1068F000FBFC3860D9F8000090F8B40AC00703D058 +:1069000029683068FFF7C9FD2046BDE8F88F0420EC +:10691000FBE7FF202070607093483D600124056014 +:106920008F4805600D70EFE72DE9F84305467F4875 +:106930004FF00009047880F80090FFF717FB7848C3 +:106940000221001D08F0B0FF2246754C2946606800 +:10695000FFF722FDDFF8D881D8F8000090F8EB139C +:10696000490620D58149DFF808C28F680E68BA1B36 +:10697000ACF86720CD684B68E91AACF86910B742EB +:1069800003DDD0F81364B24205D89D420BDDB0F8A8 +:106990001724914207DD62480221001D08F0E7FF3D +:1069A0000020BDE8F88390F8A412624D0A0705D4D0 +:1069B000C90603D490F8A502C00706D06168B5F9EE +:1069C00000305D4A0846FFF78EFAD8F8000090F8CC +:1069D000A50280060AD55348574A007800905248CD +:1069E0006168083A03780846FFF783FAB5F90000B2 +:1069F0004A4E42006168306810F09DFDB5F9000014 +:106A0000616842004D48006810F095FD444802213D +:106A1000001D08F0ACFF4E48B5F90020B0F9001099 +:106A20003068FFF7AEFC4B4990B101200870014679 +:106A300002244A4808F038FF4A48494BB0F9002080 +:106A4000464801683068FFF74FFC4349086002E0A0 +:106A500081F8009001242046A3E731493D4A0020F7 +:106A600048601070887000F002B800F01AB8304822 +:106A700010B500683F49404BB0F818230A80B0F8C1 +:106A80002C133E4C1980B0F8423323803C4C2280BA +:106A90003C4A11803C490B803249B0F8C202088060 +:106AA00010BD2DE9F00F224B8024234E196891F878 +:106AB000312091F8305002FB05F001E026F810403B +:106AC000401EFBD291F8A5029A46C00722D01A4F69 +:106AD000002301F59C611BE003FB05F007EB400C74 +:106AE00000204FF0640910E00E5C4FEAC618B8FBB6 +:106AF000F9F83CF9106006FB08F64FEAE67806EB79 +:106B00005866F6112CF81060401CA842ECD35B1CB0 +:106B10009342E1D33AE00000321201207C061000DB +:106B2000280510005A06100059061000140710001E +:106B3000D80610006A061000F60B0120800610002F +:106B4000B05110000C0510000E05100021051000BA +:106B50000806100060061000EC051000C0051000CB +:106B6000F40510000A061000F00510005412012070 +:106B7000B8530120FC051000FE05100000061000AF +:106B8000020610000406100006061000DAF80000E5 +:106B900090F8A50280060AD55149032021F810403B +:106BA000401EFBD2BDE8F00F4D4800F05EB8BDE8D6 +:106BB000F00F70472DE9FF4F83B01E460F461C466D +:106BC0004EE000BF012047F6FF7900906FEA090808 +:106BD0000190059D24E04348224600EBC5000021BA +:106BE000D0E900A39B46012010F06EFC00EA0A00E9 +:106BF00001EA0B01084313D005FB064037F91000EA +:106C0000814500DD8146804500DA8046002803DAB0 +:106C10004FF00000019003E002DD4FF00000009013 +:106C20006D1ED8D2DDE9001008430AD0019810B1DA +:106C300030B119B104E019B1404602E0484600E025 +:106C4000002041000CD0059908E000BF01FB06427E +:106C5000039D37F812301B1A25F81230491EF5D261 +:106C6000641EAFD207B0BDE8F08F1F4B10B5196896 +:106C700091F8D512CA016421B2FBF1F4B0F90020F9 +:106C80006243D41702EB5462D21102801A6892F860 +:106C9000D622D201B2FBF1F4B0F902206243D4173C +:106CA00002EB5462D21142801B6893F8D722D201C2 +:106CB000B2FBF1F4B0F904206243D41702EB546242 +:106CC000D211828093F8D822D201B2FBF1F2B0F94E +:106CD00006105143CA1701EB5261C911C18010BDA2 +:106CE000EE0B012080261000D80610008C480021F1 +:106CF00001704180704730B58A49024601200C6816 +:106D000094F81F3A4BB1864DB2F840106D68491B9C +:106D100000D549428B4200DA002094F8201A00295D +:106D200012D07F4CB2F92A500834B2F92820B4F9B5 +:106D30000230B4F900405B1BA21A5B4302FB023233 +:106D400049438A4200DD002030BD2DE9F047754FF0 +:106D5000DFF8CC8106004FF005044FF0060510D097 +:106D600096F8240100F048FA0446386890F81E0AA4 +:106D700018B1B6F8401081422DD8B06A00F0A5F8DD +:106D800048B398F8000001214FF0000907280ED2FF +:106D9000DFE800F00404243C6E040400052C04D059 +:106DA000042C06D0012C07D015E088F80090BDE82F +:106DB000F08788F80010FAE7FFF798FF022088F8BC +:106DC0000000A8F80290B6F84000C8F80400B06AC5 +:106DD000C8F80800EBE788F80050E8E7B8F80200C8 +:106DE000401C80B2A8F80200032C03D0396891F847 +:106DF000191A48E0032088F80000A8F80290D6E7A6 +:106E0000052CD4D03046FFF776FF2EE0B8F80220EC +:106E1000521C92B2A8F80220012C1ED0386890F8BB +:106E20001A3A40469342C2D8057098F801000128EA +:106E300001D00328BBD13C48394A4170192108329E +:106E400081705188C170090A017111884171090A64 +:106E50008171BDE8F0470AF02FBD3046FFF74BFFC8 +:106E6000042288F80020A8F802900028B3D09EE7FA +:106E7000B8F80200401C80B2A8F80200032C05D02C +:106E8000396891F81B1A8142BAD8A4E7052088F81E +:106E900000008CE738B500210091694600F088F9C0 +:106EA0001F4C012802D90620207005E00098FFF74A +:106EB0004CFF2078052801D0002038BD1A48012158 +:106EC000417005218170012038BDF0B51549064695 +:106ED0000120096891F81C2A950091F81D2A2B467B +:106EE000940091F83620D7074A8E898EA2EB0502CE +:106EF000A1EB040112B209B20ED023460F462C4674 +:106F00003114994206DBB94204DC31B2A14201DB03 +:106F1000914200DD0020F0BD17460A46F0E7000070 +:106F200030051000D8061000F027100000F095BAC8 +:106F3000BB4890F82C00062801D0052807D1B94895 +:106F4000B949006890F8BA0200F00F000860B7492C +:106F50000020487000F0B8BA70B5B5490022097831 +:106F6000062903D011B1052900D00122B1490B78BF +:106F7000AE49012B04D0022B02D0032B00D04AB122 +:106F8000A848006890F8790048700A2801D20A20C1 +:106F9000487070BD4A7822B1521E12F0FF024A704A +:106FA000F7D105465FF00004C4EB041000EB441079 +:106FB00005EBC0063146284604F0ACF831462846B9 +:106FC00004F0E1F8641CE4B20F2CEDD39A48007889 +:106FD0000528DED0BDE87040102101200EF03BBA3C +:106FE0002DE9F0410024054600F580565FF00107C9 +:106FF000D6F8080607FA04F108420AD0C4EB0410D8 +:1070000000EB441005EBC00000F128010C300BF040 +:107010002AF9641CE4B20F2CEAD3BDE8F0812DE913 +:10702000F0470027814605463C4600F5805801267A +:10703000D8F8080606FA04F108420CD0C4EB041094 +:1070400000EB441005EBC00191F82401032802D1A4 +:10705000284604F07DF8641CE4B20F2CE8D34846BF +:10706000FFF7BEFF754C0020704D20606060A0608F +:10707000E060A868C00104D5484600F0D3FD0128AF +:1070800006D0287A800603D54846FFF703FF50B99B +:10709000A868C00115D5484600F016FBA1781A294A +:1070A00007D0182768B165480AF006FC182F02D0EF +:1070B00005E01A27F6E7614808300AF0FBFBFFF706 +:1070C00015FEB0464D46002409F5805608FA04F036 +:1070D000D6F80816014211D0C4EB041000EB44109E +:1070E00005EBC00797F82401082807D13946284640 +:1070F00004F049F83946284604F00CF8641CE4B260 +:107100000F2CE3D34846BDE8F04725E72DE9F84FBB +:1071100080464448006890F83C0AC00744D0404686 +:10712000FFF75EFF414F4FF00006B868C0013DD544 +:10713000404600F010FCDFF80491834609F1080096 +:1071400000244FF0010A08F58055009028E0D5F89A +:1071500008060AFA04F15646084220D0C4EB04108F +:1071600000EB441108EBC10090F87001012803D135 +:1071700030488079A04201D0387880B9BBF1000F47 +:107180000BD02E480AF098FB99F802001A2806D076 +:107190003E7000980AF08EFB01E000203870641CFD +:1071A00095F91006A042D2DABDE8F88F3E70FBE7F1 +:1071B00030B5054600200346C3EB031202EB431231 +:1071C00005EBC20494F82421012A0DD0022A0BD029 +:1071D000032A09D0042A07D0052A05D0062A03D09D +:1071E000072A01D0082A02D1401CC0B20C605B1CE7 +:1071F000DBB20F2BE0D330BD09280ED2DFE800F060 +:107200000D0505070909090B0B0004207047012033 +:107210007047022070470320704705207047000028 +:1072200070761000D80610000C0610004005100003 +:107230003005100058281000E8041000F027100056 +:107240002DE9FC4FFE4AB0F90270B0F90660D2F8A1 +:1072500000C0B0F90050B0F904409CF83620BCF8EA +:10726000323093465FEAC278BCF834204FEA4B785C +:1072700009D0B8F1000F21DA5D1B1C1B65F31F4913 +:1072800064F31F411EE0B8F1000F06DADF1B9E1BFE +:1072900067F31F4966F31F4103E066F31F4967F375 +:1072A0001F415FEA8B7604D5551B65F30F09141B4C +:1072B0000FE064F30F0965F30F0111E064F31F4958 +:1072C00065F31F415FEA8B7406D5D41B64F30F0985 +:1072D000941B64F30F0103E066F30F0967F30F01DA +:1072E0009CF83040551C9CF831C0A046B3FBF4F428 +:1072F000B5FBFCF524B22DB2002B76D0002A74D059 +:10730000002C72D0002D70D00E144FF0000B13D053 +:1073100096FBF4F767F3070A96FBF4F704FB17668E +:107320001FFA86F64FEA2947BB4209DCA8F10103A0 +:1073300063F30F2AA3B20CE06BF3070A0026F1E710 +:1073400097FBF4F363F30F2A97FBF4F304FB137337 +:107350009BB209B291B191FBF5F767F3174A91FB24 +:10736000F5F705FB171189B20FFA89F7BA4209DC64 +:10737000ACF1010262F31F6AAAB20CE06BF3174A88 +:107380000021F1E797FBF5F262F31F6A97FBF5F234 +:1073900005FB127292B201EB810106EB86064900F1 +:1073A000760003EB830391FBF5F15B00C1F10A0169 +:1073B0001FFA81F902EB820196FBF4F693FBF4F3DA +:1073C000490091FBF5F1C6F10A061FFA86FE9BB251 +:1073D0000AF0FF028FB200259346CAF307444FEA32 +:1073E0001A66CAF3072C009325E034E0934502D1D6 +:1073F0000FFA8EF807E0944503D100990FFA81F84F +:1074000001E04FF00A083BB221460FFA89FA0193D6 +:107410000DE08C4201D1534604E08E4201D1019B24 +:1074200000E00A2308FB0353491C1DB209B28E4237 +:10743000EFDA521C12B29445D8DA858180F808B090 +:1074400080F809C0A0F810E0009941828472C672E9 +:10745000A0F81490C782BDE8FC8F7A4810B5007878 +:1074600028B9794800218163C163A0F84010744CA9 +:107470007548216891F83D2AC28191F83E2A8276AA +:10748000B1F83F2A4280B1F8432A0280B1F8412A7C +:10749000C280B1F8452A828091F8472A027691F895 +:1074A000481A4176FFF7CCFE67491C2201F11C0007 +:1074B00010F041F8216864481C3091F8492A02769E +:1074C00091F84A1A417610BD5E480078002811D123 +:1074D0005D495D4A8863C863A1F84000383108708F +:1074E0005748006890F8471A117602F11C0190F88D +:1074F000490A087670472DE9F041044690F8337147 +:1075000090F8246190F825510B2084F8330108206D +:1075100084F82401052084F825012046A16A0AF098 +:10752000D7F984F83371474984F8246184F82551E8 +:1075300000200870BDE8F0812DE9FE4F0646434863 +:107540000C46002180F82F1004F110000290A08951 +:1075500004F1080808B947F6FF704FF0000B0190DE +:10756000DA46D94696F8667031E000BF98F8020016 +:10757000B8422BD898F80300B84227D3F9B2344860 +:1075800010F0F8F9009096F864501BE098F80000AD +:10759000A84216D898F80100A84212D30098405D7E +:1075A00078B1F9B2E8B24246029B00F05BFB584466 +:1075B0001FFA80FB0098405D18B109F101001FFA25 +:1075C00080F96D1C96F86500A842DFD27F1C96F802 +:1075D0006700B842CAD264200BFB00F10198B1FBEE +:1075E000F0F082B2B6F8440028B164234343B1FB03 +:1075F000F3F11FFA81FA96F87011012903D11349AA +:10760000012381F82F3011490872000A487281F86D +:107610000A904FEA1920C8720E48019920F85D1FA0 +:10762000A0F802B0B6F84410C180A0F8089002712A +:1076300080F805A0207E904212D8617E51450BE073 +:10764000D80610009806100020281000F02710001F +:10765000FC150120B853012002D80120BDE8FE8F9F +:107660000020FBE72DE9F04190F824210024032AB3 +:1076700001D0042A26D1FF4AB1F90230126892F8EB +:107680004C5A5B1BB0F92A50AB421BDCB1F90030FD +:1076900092F84E6A9E1BB0F928309E4212DCB1F976 +:1076A000066092F84D7A3E44AE420BDBB1F90450CD +:1076B00092F84F2A2A449A4204DBFFF73DFF012843 +:1076C00000D10224204635E72DE9F05FDFF8A893CA +:1076D0008046002799F800300126A9F13800DBB177 +:1076E000E5494D46DFF894A38979DFF89493C1EB1F +:1076F000011202EB4111024608EBC104927E4FF0E9 +:10770000040B04F12801012B3CD0022B7ED0032B6B +:107710007DD0042B7CD049E0002408F580558346B9 +:107720001BE000BFD5F8080606FA04F1084212D0A3 +:10773000C4EB041000EB4411CE4808EBC10A00680A +:1077400090F8471A8BF81810CB4950463839FFF794 +:1077500089FF022806D0641C64B295F91006A04285 +:10776000E0DA25E0C44A89F80060383ADAF82810EF +:10777000C2F83A1089F80640B9F80810491CA9F86F +:10778000081015E094F82431042B01D0062B0DD1FC +:1077900080461346A81C0AF0DBFC012806D1B64936 +:1077A00020463839FFF7C8FE012804D085F800B01C +:1077B0003846BDE8F09F2889B8F80E20904233D3B0 +:1077C0000220287014F8602F8AF8002062788AF866 +:1077D0000120A2788AF80220AA48E2788AF80320D9 +:1077E000067089F80160182289F8022014F8362CF6 +:1077F00089F8032034F8362C120A89F8042014F88A +:10780000382C89F8052034F8382C02E00FE05EE0CF +:107810009AE09848120A89F806200068012790F833 +:10782000500A88F81800C3E7401C2881C0E794F884 +:107830002401042801D0062818D11346A81C0AF0F8 +:1078400087FC012806D18C4920463839FFF774FEA1 +:10785000012813D094F82461082084F824012046DC +:10786000FFF749FE0320287084F8246194F824016E +:1078700008289DD12046FFF73EFE69E094F860108D +:107880008AF8001094F861108AF8011094F86210D8 +:107890008AF802107B4894F863108AF80310067087 +:1078A00089F80160182189F8021094F82A1089F8E3 +:1078B0000310618D090A89F8041094F8281089F8DA +:1078C0000510218D090A89F806100127CEE794F8E2 +:1078D0002401042801D0062836D11346A81C0AF03A +:1078E00037FC012830D1644920463839FFF724FE9F +:1078F000012829D194F860108AF8001094F86110DA +:107900008AF8011094F862108AF802105D4894F821 +:1079100063108AF80310067089F80160182189F84D +:10792000021094F82A1089F80310618D0127090AC2 +:1079300089F8041094F8281089F80510218D090A97 +:1079400089F806100220287094F82401082890D1A4 +:10795000FFF7BAFD2CE72DE9F05F05464948002600 +:107960000178DFF81491DFF80CB1A9F11C0939B1E5 +:10797000DBF8001091F8511A89F8181000210170F5 +:10798000DFF8F4A005F5805450469AF800804FF0D7 +:10799000010CB8F1000F1FD0864637480127364A40 +:1079A0008079DFF8DCA08740C0EB00111C3A01EBC6 +:1079B000401005EBC000927E00F12801B8F1010FE4 +:1079C0003ED0F146B8F1020F7DD0B8F1030F7BD065 +:1079D000B8F1040F79D006E10027CB46E0461AE063 +:1079E000D4F8081608FA07F0014212D0C7EB0710C6 +:1079F00000EB471005EBC0091E48006890F8491AD3 +:107A00008BF818101C4948463839FFF72BFE02281E +:107A100006D07F1C7FB294F91006B842E0DAE5E0A8 +:107A2000154A8AF80080383AD9F82810C2F83A1076 +:107A30008AF80670BAF80810491CAAF80810D5E0B0 +:107A4000D4F808367546E0463B427DD0044690F8AF +:107A50002401042801D0062819D11346A81C0AF0D5 +:107A600077FB012811D1044920461C39FFF764FD3A +:107A7000012809E0D80610005828100099061000C7 +:107A8000F02710009806100002D004202870ADE006 +:107A90002889B9F80E10884221D3022028708AF86C +:107AA000018018218AF8021014F82A1F8AF803109E +:107AB00034F80219090A8AF8041021788AF80510A6 +:107AC0002188090A02E00DE053E085E08AF80610FB +:107AD000DBF8000090F8510A89F818007AE0401CA1 +:107AE000288183E0D4F80836E0463B4201D128469D +:107AF0003CE0044690F82401042801D0062830D147 +:107B0000134609F102000AF023FB012805D171494F +:107B10002046FFF711FD012804D099F80000022843 +:107B200019D01EE08AF8018018218AF8021094F812 +:107B30002A108AF80310618D090A8AF8041094F853 +:107B400028108AF8051000E04DE0218D090A8AF816 +:107B50000610012605E02046FFF7CDFC032089F83A +:107B6000000094F82401082840D12046FFF7C3FC08 +:107B700036E0D4F8083665463B4231D0044690F8EA +:107B80002401042801D0062830D1134609F102004F +:107B90000AF0DEFA012829D14E492046FFF7CCFC35 +:107BA000012823D18AF8015018218AF8021014F80C +:107BB0002A1F8AF8031034F80219090A8AF80410F7 +:107BC00021788AF805102188090A8AF8061002200F +:107BD00089F80000012609E0D4F80806384205D1EA +:107BE000FFF772FC02E004208EF800003046E0E56A +:107BF0003849B0F92A201C39B1F902309A420FDB1A +:107C0000B0F92800B1F90030984209DBB1F906302B +:107C10009A4205DCB1F90410884201DC012070476A +:107C20000020704710B52B4990F8243100221C39F0 +:107C30005B1E052B14D8B0F92A30B1F90240A342DB +:107C40000EDBB0F92800B1F90040A04208DBB1F921 +:107C50000640A34204DCB1F90410884200DC012292 +:107C6000104610BD30B51478844204D25578854250 +:107C700001D90A2011E0844204D15578854201D00F +:107C8000187809E0844204D05478844201D198786D +:107C900002E018789C786043C0B294788C4204D299 +:107CA000D5788D4201D90A2111E08C4204D1D578D2 +:107CB0008D4201D0197909E08C4204D0D2788A42F1 +:107CC00001D1997902E019799A795143C9B24843AF +:107CD00030BD00003C2810005F490020487070470C +:107CE0002DE9F0415D4900F580534FF001050E6824 +:107CF0004FF00E0196F893CA5FEA8C7219D5D3F84B +:107D000008460A4605FA02F73C4210D0C2EB0217B9 +:107D100007EB421700EBC70797F825717F0706D5D9 +:107D20004D4A96F8944A921C1470557001E0521E08 +:107D3000E8D25FEA4C7225D5494AD279002A21D08F +:107D4000454C0022A280D3F8083600BF05FA01F79F +:107D50003B420FD0C1EB011707EB411700EBC70700 +:107D600097F825C15FEA4C7C04D0B7F8427097427F +:107D700000D93A46491EE9D2A280B6F9B90AFDF700 +:107D8000D5FE2070BDE8F0813449096891F8931A56 +:107D900089070AD53049891C10B10020487003E0DA +:107DA0000878002801D0401E087070472DE9F04186 +:107DB00006462A4800252C46006890F8931A4A0780 +:107DC00025D5274AD27912B3234A90F8B73A90F8CA +:107DD000BB1A5778012F08D190F8B8CA90F8BC0A9E +:107DE000A3EB0C03081ADBB2C1B29088984202D808 +:107DF0001078884203D9042086F825010124214601 +:107E000054708F4214D0092009F050FD10E088070B +:107E100007D51148801C4178012908D0007830B975 +:107E200006E0C80704D096F82501042800D10125F2 +:107E30002543A7D00B49AA20087096F824010328EF +:107E400005D0042801D006289CD1082000E002209B +:107E500086F8240196E7000058051000D8061000A7 +:107E6000B05110006606100090F8611090F8602084 +:107E70008A1AC18F521C022A0ED990F8632090F8FA +:107E800062309A4208D148F20402114204D141F012 +:107E90000101C1870120704721F00101C187002045 +:107EA000704770B50446002084F82801F848F94D61 +:107EB0000E460178286811B9F749097831B194F96B +:107EC000321190F86302B1421ED028E094F82511D7 +:107ED00001290BD00FF00AFD002894F9320135D0AA +:107EE000B042286890F89B0319D10DE0EB4909785E +:107EF00069B10FF0FBFC002894F932010AD0B042BE +:107F0000286890F84D030AD100F00F0008E090F8BF +:107F10004B03F9E7B042286890F84C03F4D000090D +:107F200084F828012046FFF79FFF01280DD1DC4887 +:107F30000078012809D9296894F8280191F89C1340 +:107F400001F00F01084484F8280170BDB04203D14C +:107F5000286890F89A03D7E794F83C00C006286890 +:107F600002D590F89C03DAE790F89A03D7E7CB495B +:107F700010B50C78C74990F82821096891F89A3310 +:107F800003F00F0364B191F84C1300BF01F00F012F +:107F9000C91A511A002900DC002180F8281110BDEF +:107FA00091F84B13F2E72DE9FC47BA4D04462868D7 +:107FB00090F87F03C00749D02146201D0AF017F929 +:107FC0008046214604F120000AF011F981460FF0A5 +:107FD0008DFC0028286805D0B0F89363B0F88F7343 +:107FE000764304E0B0F89163B0F88D737643296866 +:107FF000E06A7F4391F8DA13884216D3B04514DC67 +:10800000B4F8CC00ADF80200B4F8C800ADF8000038 +:10801000B4F8D400ADF80600B4F8D000ADF8040010 +:1080200001A968460AF0E3F880462A68E06A92F8F7 +:10803000DA1388420CD2B9450ADD92F8DB034043DB +:10804000814509DC204600F0EBF928B9BDE8FC8742 +:108050008842FBD3B045F9DDE08F40F00200E087B5 +:10806000F4E79049002008708D4908708B4908702A +:108070008D4908808D49087070472DE9F04F8BB00D +:10808000002500F5805604468DF810508DF81450E8 +:10809000B6F80806834F0004000C0DD02046FFF709 +:1080A0001FFE4FF0FF39387849464FF00048BB4675 +:1080B0004FF0010A38BB0CE079483D700570012093 +:1080C000FFF762FE78480580784805700BB0BDE880 +:1080D000F08F04F58052002092F9107622E000BF64 +:1080E000D2F808C60AFA00F31CEA030F18D0C0EB56 +:1080F000001303EB401304EBC30393F824C1BCF15A +:10810000010F01D049460FE0B3F840C0BCF1000FA9 +:1081100006D01B6B93FBFCF3984501DA98460146A9 +:10812000401C40B28742DBDA0091A8468BF8005031 +:108130000027DFF86091DFE0D6F808160AFA07F0AA +:1081400001426DD0C7EB071000EB471004EBC005F0 +:1081500095F82401012806D005280CD0092820D044 +:108160000D282DD010E028460099FFF79AFE022036 +:1081700085F8240133E0284600F0D4F8062085F87D +:1081800024012846FFF70FFF95F82401022826D086 +:10819000062846D007284FD00A280DD00E281AD01E +:1081A00058E0D9F8000090F89E0300F00F0085F821 +:1081B00028010A2085F8240195F8280178B349E0C0 +:1081C000D9F8000090F8A10300F00F0085F829010C +:1081D0000E2085F8240195F82901F0B13AE095F8D0 +:1081E0003E00C00713D02846FFF73EFE78B9D9F805 +:1081F000001095F8280191F89C1301F00F018842B6 +:1082000003D9401A85F8280101E085F82881E88F14 +:1082100040041FD495F82801DFE7032018E016E09A +:108220005CE095F82901A8B995F83E00800701D5D2 +:1082300007200DE008200BE0D9F8000090F87E033D +:108240008006F7D595F8A000012803D0F2E70B20AF +:1082500085F824012846FFF7A9FD95F82401022896 +:108260000AD0062824D00A2829D00E2820D0032896 +:1082700029D0042827D03DE0E88F40043AD400BF3D +:1082800095F8280150B3401E85F8280132E000001F +:1082900020051000D80610002A0510006506100001 +:1082A0008D061000660610005C05100058051000D1 +:1082B00095F8290190B1401E85F829011AE0284659 +:1082C000FFF771FEDCE79BF80000401C8BF8000014 +:1082D00095F82501012802D0032806D00AE09DF870 +:1082E0001400401C8DF8140004E09DF81000401CA0 +:1082F0008DF810007F1C7FB296F91006B842BFF6C9 +:108300001BAF05AA04A9204600F050F80020FFF793 +:108310003BFD5E499DF8100008705D499DF8140012 +:108320000870D3E670B50026044680F829615948E4 +:10833000594D0178286811B190F8640216E0574948 +:1083400009780029F8D10FF0D1FA60B12868012628 +:1083500090F89F035FEA101084F8290194F8250132 +:10836000012806D00EE0286890F89F0300F00F0067 +:10837000F2E7296894F8290191F84B1300EB1110EA +:1083800084F829011EB994F83E0080070DD42868AE +:10839000E16A90F8A00300F00F02914205D994F829 +:1083A000291101EB101084F8290170BDF0B50C788B +:1083B00013783B4F012534B17BB3002300F5805483 +:1083C0004FF0020C22E0002B29D03D7022E000BFCC +:1083D000D4F8086605FA03FE16EA0E0F14D0C3EBB4 +:1083E000031606EB431600EBC60696F824E1BEF131 +:1083F000030F09D196F825E1BEF1010F04D186F8EB +:1084000024C11678761E16705B1C5BB294F9106658 +:108410009E42DDDA0878002801D000203870F0BDD7 +:1084200030B5C18F0123090501D5012030BD1A4C9B +:10843000B0F95A20B0F95810246802FB01F5002D5C +:108440000CDA002A00DA524294F8DC53AA4205DD25 +:10845000002900DA4942A94200DD0023B0F95E108C +:10846000B0F95C0001FB00F2002A0CDA002900DA06 +:10847000494294F8DC23914205DD002800DA4042AD +:10848000904200DD0023184630BD00006706100052 +:108490006806100020051000D80610002A051000FC +:1084A000650610002DE9F8430746FF488946164641 +:1084B0000178FE480078FE4C01B990B1206890F830 +:1084C000C013B0F8CB2301F00F030D09B0F8C913A6 +:1084D000494352434846009509F097FE3560BDE890 +:1084E000F8830FF003FA58B1206890F8B613B0F88B +:1084F000B92301F00F030D09B0F8B7134943E8E7BA +:1085000097F82501022818D0012822D0246894F871 +:10851000E10394F8E0C300F00F030509E548017892 +:1085200031B194F8E72394F8E6C302F00F0315097C +:1085300097F82321012A18D02EE0206890F8BC1368 +:10854000B0F8C32301F00F030D09B0F8C11349437C +:10855000BFE7206890F8BD13B0F8C72301F00F0300 +:108560000D09B0F8C5134943B3E794F8998AFA6A3C +:10857000424511D294F89A1A94F8BB03B2FBF1F178 +:1085800094F8982A00F00F0302F00F02551AB5EB89 +:10859000101F1CDA05091AE0B7F84020624505D91A +:1085A000B4F8E213B4F8E423494392E794F8BB2308 +:1085B00002F00F03150909B10379457997F83C00DA +:1085C000C00604D594F8DD0300F00F03E2E7B4F829 +:1085D000C113B4F8C32349437BE72DE9F843884628 +:1085E00090F82411044600F1940703290DD0B04DF2 +:1085F000042928680FD0072942D008293FD14146D5 +:108600003846BDE8F84300F0B3BB41463846BDE804 +:10861000F84300F070BB90F8BE0304F10C010609AA +:10862000081D09F0E4FD01466A462046FFF73AFFBF +:10863000034694F82301012810D12868E16A90F8D4 +:10864000992A91420AD290F89A2A90F8BE03B1FB77 +:10865000F2F6B6EB101F05DD060903E09548017838 +:1086600001B1867954F89C1F3246184609F0E2FDA4 +:10867000054602464146384600F042FB25602EE79B +:1086800090F87F1300268A07314602D594F8A0207F +:1086900042B184F8A010324641463846BDE8F8435E +:1086A00000F046BB90F8BF0300F00F060FF01EF974 +:1086B00018B1286890F8BF030609012084F8A000CB +:1086C000E9E72DE9F041044600F1A805C08F0F4607 +:1086D00000054FF0050603D594F8180101281ED0B7 +:1086E000702128460EF0C8FF05EBC6017868486087 +:1086F000386845F83600761EF6D200BFD7E900018B +:10870000C5E90D010120286305F1580305F1400278 +:1087100005F134012846BDE8F04109F017BE1821E3 +:1087200005F140000EF0A8FF182105F158000EF0E9 +:10873000A3FF94F81A0101281FD194F822010128FF +:1087400002D003280DD018E094F8230110B9E08975 +:10875000A4F82001B4F820016084B4F81E0120843C +:108760000BE094F8230110B9A089A4F81E01B4F815 +:108770001E012084B4F82001608494F823010128AC +:108780003AD0B4F920117868E962401A90FBF6F00B +:10879000B4F9201100EB400201446962B4F92011E0 +:1087A00001EB4001E961B4F9201111446961B4F9A8 +:1087B000201101EB8000E86078686860B4F91E1150 +:1087C0003868A962401A90FBF6F0B4F91E1100EB6C +:1087D000400201442962B4F91E1101EB4001A96174 +:1087E000B4F91E1111442961B4F91E1101EB800086 +:1087F000A8603868286081E75FF0000005EBC002E0 +:10880000B4F920115160B4F91E1145F83010401C24 +:10881000C0B20628F2D371E710B50446D1E90002D0 +:10882000C4E90D020622204609F0C7FC206B04F1C2 +:108830005803401C206304F1400204F13401204637 +:10884000BDE8104009F082BDD1E90021C0E937211F +:10885000D0F8D8100023491CC0F8D81000F5807259 +:1088600000F1E801DC3009F084BE2DE9FC47DFF8B7 +:1088700048800C460968C8F80010DFF83490216879 +:108880000546C8F80410D9F8000017464FF0010A51 +:1088900090F87F03400631D5B4F90200019005F14C +:1088A000A806B4F9000009E0200510002A05100010 +:1088B000D8061000A40610005E051000009095F880 +:1088C0002401032808D004280BD0062809D0072843 +:1088D0000CD008280AD00DE069462846FFF7F1FEC3 +:1088E00008E069463046FFF797FF03E069462846EF +:1088F000FFF7AAFF308F6080B08E20802168C8F813 +:1089000008102168C8F80C10D9F800004E46B0F9DC +:108910003210B4F9020009F032FC60803068B0F91E +:108920003410B4F9000009F02AFC208095F82401E5 +:10893000032806D0042808D0072817D0082815D007 +:1089400017E03988A5F84E1013E03068B5F84E20CE +:1089500090F8BE0300F00F00C0F1100142433888C8 +:1089600000FB01200009A5F84E0001E0B5F84E001B +:108970003880D74A214605F1240000F0A0F950467E +:10898000BDE8FC872DE9F34FD24883B00025056090 +:10899000CF48DFF844932E46056089F80050039FC6 +:1089A000DFF838B34FF0010A07F58057ACE000BF9D +:1089B000D7F808160AFA06F001426ED0C6EB061088 +:1089C00000EB4611039800EBC10484F8705194F851 +:1089D000240103280BD0042809D0072807D0082831 +:1089E00005D0092803D00A2801D00B2855D1E0680A +:1089F0000090B4F84C00ADF8040004F10C01B54A45 +:108A0000081D00F05CF901AA69462046FFF72DFF1A +:108A10008046DBF8000090F87E03400604D56946E6 +:108A2000204601F08DF98046DBF8000090F87E03C7 +:108A3000800603D569462046FFF7CFFDDBF800002E +:108A400090F87F0340070CD5B8F1000F09D094F8D7 +:108A50002401032805D1608CADF80200208CADF80C +:108A6000000094F82501012808D19D48007828B914 +:108A700094F82401082801D04FF0000899480078A4 +:108A800028B399480078012808D094F83E004007A0 +:108A900015D500BF4FF0000819E034E004F12000C4 +:108AA000029001F0D5FA18B9029801F0E0FA08B185 +:108AB0004FF0000894F83E004007EBD407E094F82C +:108AC0001801012803D1206A009084F8185194F805 +:108AD000250103280CD199F80000401CC0B289F888 +:108AE000000094F83E20520702D5401E89F800008D +:108AF00000986062BDF80400A4F84E00B8F1010FC0 +:108B000016D084F87051761C97F91006B042BFF663 +:108B10004FAFDBF8000090F83804000720D599F833 +:108B200000107248B9B172490978012911D012E0D8 +:108B30000098A061BDF80400A4F85000049894F8CF +:108B4000322101680AFA02F21143016084F870A12F +:108B5000D9E780F800A0D7F80C16002900D10570DD +:108B600005B0BDE8F08F2DE9F0478946064600279D +:108B70004FF0010800F5805543E000BFD5F8080626 +:108B800008FA07F210423BD0C7EB071000EB471082 +:108B900006EBC00494F8240103280BD0042809D064 +:108BA000072807D0082805D0092803D00A2801D0B3 +:108BB0000B2825D194F83231D9F8002008FA03F1B6 +:108BC0000A421DD0032803D12146304602F0C0FAE4 +:108BD00094F93301002813DB94F8250100210128C2 +:108BE00004D0022804D0042804D004E0032102E0C9 +:108BF000042100E0052184F82611204608F04BFEF0 +:108C00007F1C95F91006B842B8DA00273DE000BF96 +:108C1000D5F8081608FA07F2114235D0C7EB07114C +:108C200001EB471106EBC10494F82411082902D086 +:108C30000B2915D028E094F83221D9F8001008FA51 +:108C400002F0014207D094F93301002803DB2146EA +:108C5000304602F098FA2146304602F05BFA13E003 +:108C600094F83221D9F8001008FA02F001420BD032 +:108C700094F93301002807DBE08F214620F40060DF +:108C8000E087304602F07FFA7F1C95F91006B84263 +:108C9000BEDABDE8F0870F49002008600C49086083 +:108CA00000F028B838B504460020009069462046F8 +:108CB000FFF768FE69462046FFF755FF38BD10B53F +:108CC000144609F094FA2168814200DA206010BD50 +:108CD00094061000900610008D061000D8061000B3 +:108CE00065061000160710001C071000190610007A +:108CF00018061000704700228260027300F03DB831 +:108D00007CB5044615460E46684600F036F80199D3 +:108D10002A46606800F043F8606000992A4620689F +:108D200000F03DF820602146304600F02FF87CBD71 +:108D30007FB50446406801902068009015460E46B5 +:108D400002A800F01AF803986060029820602A4692 +:108D50000399019800F023F801902A46029900989F +:108D600000F01DF800906946304600F00FF87FBD16 +:108D70000A460146104600F009B8B1F90220120275 +:108D80004260B1F900100902016070474A68803200 +:108D90001212428009688031091201807047C2F1C5 +:108DA0001003504301FB030000117047B0F840204E +:108DB000B1F840301A44A0F84020B0F84220B1F891 +:108DC00042301A44A0F84220026B0B6B1A44026333 +:108DD000426B4B6B1A444263B1F95220B0F95230E6 +:108DE0009A4201DDA0F85220B1F95420B0F9543074 +:108DF0009A4201DDA0F8542090F82C2191F82C31F2 +:108E00009A420AD030F8462FB1F846301A4420F87A +:108E10000E29896B02681144016070472DE9F04FFB +:108E200097B0804600F5805000261190BEE00020EB +:108E30000890059010901290814682468346054620 +:108E400007460A900B900C900D9008EB860000F5F9 +:108E500080501490D0F884060AAA044617E000BF98 +:108E600090F82C1108EB010C535C0CF5805C5B1C3A +:108E7000DBB253549CF872C6634506D1012B04D96A +:108E800001238B4012990B431293D0F86C010028F8 +:108E9000E6D140E094F82C11012000FA01FC12996F +:108EA0001CEA010F12D1606BB4F90E30059A4946E5 +:108EB000C0FB031205928946B4F90C3051465A465C +:108EC000C0FB03128A469346054419E008991CEA40 +:108ED000010F15D1A06BB4F91E30059A4946C0FBAD +:108EE000031205928946B4F91C3051465A46C0FB1C +:108EF00003128A46089905444CEA010093460890FB +:108F0000204600F00EFC012802D11098401C109061 +:108F1000D4F86C417F1C002CBCD1002F44DDE81735 +:108F2000044603462A46484605990EF0E0FAADF895 +:108F30001E002A462346504659460EF0D8FAADF890 +:108F40001C0014984FF0FF370025D0F8844623E02A +:108F5000204600F0E6FB012801D0109890B904F1FA +:108F6000100107A809F043F9B8420BD207463DB1FA +:108F700029462046FFF71AFF2946404600F0E8FB45 +:108F8000254607E021462846FFF710FF21464046C8 +:108F900000F0DEFBD4F86C41002CD9D10798E860D2 +:108FA000E88F40F04000E8871198761C90F8FC06A6 +:108FB000B0423FF73CAF17B0BDE8F08F2DE9F74F57 +:108FC00005460E46C1EB061000EB461082B005EBDD +:108FD000C00A00244FF00108DFF894B505F580576A +:108FE0007FE0D7F8081608FA04F9424611EA090F9B +:108FF00076D0B44274D0DBF80C00904630F81600FE +:1090000010EA090F6CD1C4EB041000EB441005EB1F +:10901000C000009000F07FFB012804D0009800F011 +:1090200080FB01285CD1009800F06DFBF0BB00993B +:109030000AF10C000C3109F0DAF80190DBF80C00B1 +:1090400008FA06F230F8163043EA090320F8163021 +:1090500030F81430134320F814305046DBF80490F5 +:1090600000F06BFB012804D1009800F054FB0128AC +:109070001BD0504600F04FFB012804D1009800F0AF +:109080005CFB012811D0504600F045FB01281CD1A3 +:10909000009800F040FB012817D100999AF83E0093 +:1090A00091F83E10084380060FD500E018E0BAF8AA +:1090B0003E00DBF8089040F02001AAF83E1000982E +:1090C000C08F40F020010098C1870198484507D221 +:1090D00041F2846051462844049B009A00F047FB0B +:1090E000641C97F91006A042BFF67BAF05B063E79A +:1090F0002DE9F84F88460646C1EB011101EB4810F7 +:1091000006EBC004DFF868A494F83E004FF0040BAF +:1091100040064FF0010906F580552DD5002704F1D2 +:109120000C0B23E0D5F8081609FA07F001421CD011 +:1091300047451AD0C7EB071000EB471006EBC000FD +:10914000009000F0E8FA01280FD1009800F0DBFA57 +:1091500058B900995846103109F049F8DAF8081062 +:10916000884202D2042084F824017F1C95F910065D +:10917000B842D7DABDE8F88FFE49E06A096891F88D +:1091800095138842F6D900272FE000BFD5F80816BE +:1091900009FA07F0014227D0474525D0C7EB071051 +:1091A00000EB471006EBC000009000F0B4FA012875 +:1091B0001AD1009894F82C1190F82D01814213D106 +:1091C000009800F0A0FA78B9009904F10C00103171 +:1091D00009F00DF8DAF80810884205D284F824B1B5 +:1091E000E08F40F04000E0877F1C95F91006B84200 +:1091F000CCDA002728E000BFD5F8081609FA07F0F6 +:10920000014220D047451ED0C7EB071000EB4710A6 +:1092100006EBC000834600F084FA012813D15846BB +:1092200000F071FA78B90BF1100104F10C0008F0AC +:10923000DEFFDAF80810884205D2BBF83E0040F0A5 +:109240004001ABF83E107F1C95F91006B842D3DA06 +:1092500090E72DE9F8430646FF2000258DF8000031 +:10926000012706F5805419E0C5EB051000EB451009 +:1092700006EBC008D4F8080607FA05F108420CD03E +:10928000404600F040FA012807D098F8240105284C +:1092900003D129463046FFF72BFF6D1C94F91006C9 +:1092A000A842E1DA00251BE0C5EB051000EB4510F4 +:1092B00006EBC008D4F8080607FA05F108420ED0FC +:1092C000404600F020FA012809D0404600F029FA73 +:1092D000012804D16A4629463046FFF76FFE6D1C0F +:1092E00094F91006A842DFDA0025B84620E000BF56 +:1092F000C5EB051000EB451006EBC007D4F80816C7 +:1093000008FA05F0014212D0384600F0FCF90128B5 +:109310000DD0384600F0FFF9012804D16A462946ED +:109320003046FFF74BFEF88F20F02000F8876D1CC9 +:1093300094F91006A842DBDA9DF80000401C84F87E +:10934000FC06BDE8F88310B50446894803210C30BB +:1093500006F060FA86481E21C0680EF06BF941F2F3 +:1093600084607C2120440EF087F98248026882489C +:10937000B2F896138079494310B1B2F86A134943A1 +:109380007E480068C00106D57D480078062802D1D5 +:10939000B2F8DE134943B2F8982302FB0210744A74 +:1093A000121D1160111D08602046FFF752FF204674 +:1093B000FFF734FD6E480321BDE810400C3006F085 +:1093C00041BA2DE9F047044691425CD007D901EB40 +:1093D0000200A0EB0201CAB2A0EB0200C1B2C1EBD5 +:1093E000C10000EB400004EB8001C2EBC20000EBC7 +:1093F000400004EB8000B1F93250B0F932308146C0 +:109400009D4200DA4B86CB8CC58C2B44CB840B8DD4 +:10941000058D2B440B858B6985692B448B61C7694E +:10942000CE69CB68D9F80C004FEA234C4FEA2048AC +:109430000CFB06FCF51907FB08CC9CFBF5FC6CF358 +:109440001F430FFA83FC0CFB06FC00B207FB00C0B5 +:1094500090FBF5F060F30F03CD61CB6094F8EC0462 +:10946000411E91420AD0C0EBC00000EB400004EB6B +:1094700080014846542254390EF0A2F894F8EC04C6 +:10948000401E84F8EC04BDE8F0872DE9FE4F164637 +:109490000F468346012B2FD101203A4A10E000BF2E +:1094A00017F8101011B1491E07F8101007EB400310 +:1094B00014785978641EA14201DA491C5970401C85 +:1094C00097F82C108142EBD201202F4A10E000BF08 +:1094D00016F8101011B1491E06F8101006EB4001E5 +:1094E00013784C785B1E9C4201DA641C4C70401C63 +:1094F00096F82C108142EBD21E484FF00109CA4663 +:109500000068B0F88E0240430290002001908CE089 +:10951000012082E0002000909BF8EC043FE000BFB7 +:10952000C0EBC00101EB41020BEB820202F14401EE +:1095300016F818400B78A34231D306EB4804647840 +:10954000A3422CD8497817F81930994227D307EB52 +:1095500049035B78994222D80C49097839B10C4902 +:10956000097821B192F8241011F0060F17D111E0FB +:1095700070051000D8061000B0511000480510000A +:10958000E8041000590610005A06100018061000D2 +:109590001A061000009A0AFA00F111430091401EC9 +:1095A000BED2042168460CF059FD012833DD0024A9 +:1095B0005246009901E0641CE4B202FA04F09246BB +:1095C0000842F8D09BF8EC5422E000BF00990AFA58 +:1095D00005F008421CD0C4EBC40000EB40010BEBCB +:1095E0008100C5EBC50101EB41010BEB81010C30A2 +:1095F0000C3108F0FCFD0299884209D2EAB22146FA +:109600005846FFF7DEFE70490120019081F800A066 +:109610006D1EA542DAD808F1010096F82C1080469C +:109620004145BFF477AF09F1010997F82C1049457E +:10963000BFF46EAF0198BDE8FE8F644810B5407866 +:109640000C46002856D062480078002852D1614864 +:10965000007800284ED1604894F8EC24006890F817 +:1096600089128A4246D800230BE000BFC2EBC20138 +:1096700001EB410104EB8101B1F93210994200DDA7 +:109680000B46521EF2D255490B80B0F88A1299420D +:1096900030DBB0F98C1200225148FBF7DEFD504957 +:1096A000D1E90002104325D0D1E90201084321D0BD +:1096B0004B4A0123A2F15801A1F15800FBF7EDFA42 +:1096C0004748B03890F82C10002913D0583090F843 +:1096D0002C0000280ED0414394F8EC040023814272 +:1096E00000D201233E4A2046583ABDE81040A2F17C +:1096F0005801CAE610BD39490020C86038480F211A +:1097000010300DF0B9BF90F83E00400701D50120A0 +:1097100070470020704790F82401012800D00020F5 +:10972000704790F82401022805D0032803D00428AC +:1097300001D0002070470120704710B590F83E100E +:10974000490603D5FFF7EDFF012800D0002010BD2A +:1097500091F82421012A08D0022A06D0062081F897 +:109760002401002081F82901704701F0D3BCF0B535 +:1097700091F9316193F9004092F93151771C02D08F +:109780006D1C15D00BE06E1C0BD000EB850200EBBE +:109790008400D26BC2F86C11C16381F831411C7036 +:1097A000F0BD641C64B240F8241081F8314102E03D +:1097B00000EB8601C96B00EB8400C1F86C21C26329 +:1097C00082F83141EBE7000088051000B05110002D +:1097D000200510002A051000D806100070051000A2 +:1097E000182910002DE9F041044690F89200FF4E30 +:1097F00000270D467F284FD104F10C01081D08F009 +:10980000F6FC0146204600F021FB40B284F89200AD +:109810000F2802DD0F2084F89200E08F80053BD5F1 +:109820006888B4F97AC0B4F97830A0EB0C0001B2C2 +:109830002888A26FE266D6F800E0C01A64229EF87B +:10984000C7E900290EFB01FE9EFBF2F100B201DD2B +:10985000614401E0ACEB0101A4F87210316800280A +:1098600091F8C71901FB00F191FBF2F001DD1844FA +:1098700000E0181AA4F870006888B4F87210401A52 +:10988000A4F876002888B4F87010401AA4F8740080 +:10989000306890F8C709E8B394F99200B5F902204E +:1098A000C0F110015143B4F97A2000FB021040F3DB +:1098B0000F106880E18F890510D5B4F96E108842C9 +:1098C00003DDB4F97220904205DC884206DAB4F96F +:1098D0007210884202DAB4F87200688094F992003B +:1098E000B5F90020C0F110015143B4F9782000FB14 +:1098F000021040F30F102880E18F890523D5B4F9B9 +:109900006C10884203DDB4F97020904207DC884275 +:109910000BDA00E02AE0B4F97010884205DAB4F8F6 +:1099200070002880E08F80050DD5B5F90000B4F9EE +:109930007010884207D1B5F90200B4F9721088425C +:1099400001D184F89270316894F8920091F8C919A5 +:1099500001F00F01401A40B284F89200002801DAA9 +:1099600084F892702868A067BDE8F08184F892704E +:10997000012084F89000F7E72DE9F041884605467C +:10998000012790F89210384671B195F8901001298E +:109990000AD00322414605F17C0008F0F8FB95F857 +:1099A0009100012803D04EE085F89000DCE70DF02F +:1099B0009DFF8E4E0028306806D090F8CC1990F8A4 +:1099C000CD0961F31F440DE090F8CA1990F8CB0956 +:1099D00061F31F4460F30F048548017821B1C0781A +:1099E00060F31F4460F30F0423145B4322B202FBB5 +:1099F000023405F17800414608F0F9FB0023A0424B +:109A00001BDC3168EA8F91F8C50900EB800040004B +:109A1000120504D591F8C40900EB8000400010B194 +:109A2000EA6A824209D891F87E03000600D4002732 +:109A3000A86FC8F80000384696E785F8913095F988 +:109A400092000028F7DD41462846FFF7CBFEF2E7FB +:109A50002DE9F84F044601200D464FF0000B009011 +:109A60000DF044FFDFF884A10028DAF8000011D0DF +:109A700090F8D66990F8D7790322294604F17C0042 +:109A800008F085FBE08F00051DD594F81A01012828 +:109A900005D018E090F8D46990F8D579ECE7DAF8B9 +:109AA0000000E16A90F8DC0981420CD26888B4F8C1 +:109AB0007A10401AB4F88C100844A4F88C00288856 +:109AC000B4F878100BE06888B4F88210401AB4F843 +:109AD0008C100844A4F88C002888B4F88010401A30 +:109AE000B4F88E100844A4F88E00B4F98C00002855 +:109AF00001DB014600E04142B1425EDD4FF0010B67 +:109B0000002801DD811B00E081190FFA81F9A0EB2B +:109B10000900A4F88C0034F87A1F01EB090000B2A8 +:109B20002080DAF80010B1F9321008F028FB24F890 +:109B30007A09B5F902108646081A02B2002A01DB3A +:109B4000104600E05042B0424EDDB4F98200081ADF +:109B500000D54042DAF800800FFA80FC98F8DA3934 +:109B600098F8DB6998F8D80998F8D9199C450FDB63 +:109B70009E420DD0B44501DD084609E0ACEB030C74 +:109B8000091A0CFB01FCF11A9CFBF1F1084400B22C +:109B9000B4F98C105143002906DDB9F1000F00DC47 +:109BA00040427044A4F87A00B8F93210B4F97A004F +:109BB00008F0E5FAA4F87A0016E0DAF80010B4F933 +:109BC0007E00498E884203D1B4F982208A4203D0B4 +:109BD00050B9B4F8821039B9B4F97A10814203D07F +:109BE000A4F87A004FF0010B04E00000D806100042 +:109BF000A4061000B4F98E00002801DB014600E045 +:109C00004142B94256DD002801DDC11B00E0C11907 +:109C10000EB2801BA4F88E0034F8780F304400B2E6 +:109C20002080DAF80010B1F9341008F0A8FA24F80E +:109C30007809B5F900108146081A02B2002A01DB42 +:109C4000104600E05042B84253DDB4F98000081AD3 +:109C500000D54042DAF800800FFA80FC98F8DA3933 +:109C600098F8DB7998F8D80998F8D9199C450FDB52 +:109C70009F420DD0BC4501DD084609E0ACEB030C6A +:109C8000091A0CFB01FCF91A9CFBF1F1084400B223 +:109C9000B4F98E105143002905DD002E00DC40424E +:109CA0004844A4F87800B8F93410B4F9780008F002 +:109CB00066FA12E0DAF80020B4F97C00918E88424E +:109CC00003D1B4F980308B4203D048B9B4F8801086 +:109CD00031B9B4F97810814202D0A4F8780008E0D4 +:109CE000BBF1000F05D192F87E03000601D40020DD +:109CF0000090A06F28600098BDE8F88F10B504466A +:109D000090F8240104281AD1E08F400517D404F1FB +:109D10000C01081D08F06BFA01466348006890F8D2 +:109D2000C629E08F5243430509D4914202DA40F438 +:109D3000007003E020F4007040F48060E08710BD04 +:109D40002DE9F0410E4604460125FFF7D7FF94F8B0 +:109D50002401032804D0042807D0082825D027E0B0 +:109D60003146204600F029F822E04F4F386890F83D +:109D70007F03C00609D531462046FFF7FDFD0546A5 +:109D800094F89000012803D00CE0012084F89000A2 +:109D9000386890F87F03000704D531462046FFF766 +:109DA00057FE0546012D03D005E0D4F88800306049 +:109DB0003068C4F888002846D6E570B504460868BF +:109DC000A0670D46032204F17C0008F0EDF9364847 +:109DD000026892F87F03C1064FF000002ED5334988 +:109DE0000E7801217F231EB3E68F360520D594F827 +:109DF0002361012E15D084F8900084F8911084F826 +:109E00009230D4F81E11A1676988B4F87A30C91A63 +:109E1000A4F876102988B4F87830C91AA4F8741018 +:109E20000CE084F8901084F8910084F8920005E02A +:109E300084F8900084F8911084F8923092F87F139F +:109E4000090702D524F88C0F608070BD10B50C4650 +:109E50000DF04CFD14490A6880B192F8D30992F8CC +:109E6000D03900F00F01000992F8D1295B43524329 +:109E70009C4202DD94420CDB084610BD92F8D209E8 +:109E800092F8CE3900F00F0100095B4392F8CF2918 +:109E9000EDE79A4200D1521CE41A411A4C43D11A00 +:109EA00094FBF1F1401A10BDD806100016071000FF +:109EB000F0B5F64A002617687B8E97F8954ABA8E59 +:109EC00097F836701D465FEA477C03D5A3EB204C1C +:109ED0006CF31F405FEA877C03D5A2EB000C6CF3A8 +:109EE0000F00FF0706D0031460F31F4063F30F0059 +:109EF00013462A46DFF898C39CF80050C5B10514F4 +:109F0000B5EB530F05B206DAB5EB520F01DA0025B7 +:109F100007E0012505E0B5EB520F01DA022500E06C +:109F200003250127AF400F4202D00CEB0501CC788E +:109F30000114A14202DB1B1B8B4206DA00B2A042D5 +:109F400002DB111B814200DA01263046F0BDD04908 +:109F50000022897809B1C068AAE7104670472DE948 +:109F6000F041CB4F0D463A460646797892F803C049 +:109F700013790020C54C52795FEA017E06D019465C +:109F8000604608F09DF80146B87916E08F0702D0C8 +:109F90001946604611E0BE4F11F00B0FBF7901D09A +:109FA000394603E011F0050F02D06146104604E087 +:109FB00011F00A0F10D03946184608F08CF858B145 +:109FC000216891F8A42A824206D391F89E0A307043 +:109FD000206890F89F0A0EE0216891F8A42A824236 +:109FE0000CD291F8A52A824208D391F8A00A3070C9 +:109FF000206890F8A10A2870BDE8F08191F8A52AA0 +:10A000008242F9D291F8A62A8242F5D391F8A20AA7 +:10A010003070206890F8A30AEDE730B50124039D65 +:10A020009C4035B1091491420EDA81682143816068 +:10A0300030BD09B2914203DA01682143016030BDAD +:10A0400041682143416030BDC1682143C16030BDDA +:10A050009049B0F90000B1F92020824203DCB1F947 +:10A060002210814201DA012070470020704789499F +:10A07000B0F90200B1F91A10884201DD01207047E1 +:10A08000002070472DE9F84391460646DDE9087245 +:10A0900008790025DDF828C00C46032832D27B4819 +:10A0A000DFF8F481016891F84214E170D8F8048077 +:10A0B000B8F1000F06DDD0F8008098F84384A1EBDA +:10A0C0000801E1700068316BB0F84404814217DD8B +:10A0D000DBB249463846CDF800C0FFF79EFF207935 +:10A0E000401CC0B22071032806D06C49B6F9540058 +:10A0F000B1F90010884205DD03202071012501E03F +:10A10000002020712846BDE8F8832DE9F04104467F +:10A1100063480078002853D05C48006890F8380401 +:10A12000C0064DD594F93301002849DAE08F800448 +:10A1300046D4A08F0025400500D5012504F10C0070 +:10A14000FFF786FF0346E08F4FF0010641044FF012 +:10A1500002074FF0030C1CD52B430BD084F824715D +:10A1600040F00400E08794F8280103281FD284F807 +:10A1700028C11CE04BF6FB71084040F42050E087FA +:10A18000002204F58F71204600F0A5FE84F81A61C4 +:10A190000DE004F12000FFF75BFF012801D1012B46 +:10A1A0000FD0E08F20F4804040F40050E087E08F33 +:10A1B000400405D53B4810F85B1F41F004010170D5 +:10A1C0001AE7002DF3D0E08F44F204010843E08742 +:10A1D00084F8247194F82801032801D284F828C156 +:10A1E0000021C4F81811C4F81C11C4F82011E1684A +:10A1F000C4F81E1184F82261D9E72DE9FC47234EEB +:10A2000004460025306890F89E1A8DF8001090F8EA +:10A210009F1A8DF8041094F8711139B994F87221CD +:10A220009AB390F831305B1E9A423FD090F83020BC +:10A23000521E914202D194F8723133B3914206D149 +:10A2400090F8310094F87211401E81422ED001A97D +:10A250006846FFF784FE3268B4F952009DF8043076 +:10A2600092F89C1AB1464843642190FBF1F007B282 +:10A2700094F871110C4899421AD294F872619DF8C1 +:10A2800000C0664514D2002120E00FE0D80610007F +:10A29000AB0610003829100080051000FC051000E6 +:10A2A00016071000B85301208006100001253CE07D +:10A2B000994213D292F831609DF8008094F872C1EF +:10A2C000A6EB0808C44509DB761EF1B200680DF064 +:10A2D00057FBB0F90000B842E8DC26E092F830C045 +:10A2E0004E46ACEB0303994207DB94F872C19DF82C +:10A2F0000080C44501D200210CE0994215DB92F8A0 +:10A3000031109DF8002094F872318A1A93420CDBC8 +:10A31000491EC9B200680DF033FB316891F8301066 +:10A3200000EB410030F9020CD5E72846BDE8FC8778 +:10A330002DE9F04F4FF0000B85B00D4681465E468B +:10A340004FF0020A4FF0010800F58057B0E100BF5E +:10A3500008FA06F0D7F80816019001421BD0C6EBA8 +:10A36000061000EB461109EBC10404F58C70049053 +:10A370002046FFF7CAFEE18F48040CD4E068009045 +:10A38000039094F82401012806D0022804D049073C +:10A390007ED504287DD08AE1FF4AB4F95210B2F983 +:10A3A00000209142F7DB012804D1049800210160CC +:10A3B00041608160F948007820B12046FFF7C7FD71 +:10A3C000012807D0F5484178E068FFF771FD0128C2 +:10A3D00003D00DE084F8768169E1F148006890F8D7 +:10A3E000920AC00604D52046FFF707FF012833D0A4 +:10A3F000EC4A0098B2F9001000B288420DDBB2F9C5 +:10A400000210884209DC0099B2F90A300914994215 +:10A4100003DCB2F9083099425ADAE18F41F00401C5 +:10A42000E1870499E368C1F80630B2F90010884268 +:10A4300003DBB2F90230984239DD00200095CDE906 +:10A440000110DDE9032133462046FFF71BFE049986 +:10A45000834681F80AA02AE1D148016891F89D2A33 +:10A4600084F87721B4F85220A4F87421626EA266B1 +:10A47000E18F41F00401E1870499E268C1F8062008 +:10A48000049906228A72049A82F80B80006801E01F +:10A49000F1E06BE090F8950A0095CDE90108DDE95F +:10A4A000032133462046FFF7EDFD8346FFE0B2F976 +:10A4B0000810CDF80880CDE90051DDE903213346CD +:10A4C0002046FFF7DFFD8346049804218172EEE009 +:10A4D000B2F9103098420BDBB2F91230984207DC27 +:10A4E000B2F91A30994203DCB2F91830994235DAE0 +:10A4F000E18F41F00401E1870499897A19B904993F +:10A50000E368C1F80630049B83F80A80B2F91010A2 +:10A51000884203DBB2F9123098420EDD002000952C +:10A52000CDE90110DDE9032133462046FFF7AAFDFE +:10A530008346049880F80A80B9E0B2F91810CDF883 +:10A540000880CDE90051DDE9032133462046FFF7BD +:10A5500099FD0499834603208872A8E0049800219D +:10A5600081722869019908432861A0E00498807AE3 +:10A5700006280DD08B4A0099B2F9103009B29942E1 +:10A5800003DBB2F91230994261DD03285BD08EE023 +:10A59000834894F86120006890F83010491E8A4280 +:10A5A00002D094F8601041B990F8920AC00604D520 +:10A5B0002046FFF722FE012812D094F87701A0B1BF +:10A5C000B0F1010084F877017548CDF80080F3B24E +:10A5D00000680399B0F9962A2846FFF71EFD66E049 +:10A5E0006F48006890F89D0AECE700986D4A01B248 +:10A5F000B2F91000814203DBB2F9123099420EDD4C +:10A6000000210095CDE90101DDE903213346204613 +:10A61000FFF738FD0499834681F80A800FE0B2F90C +:10A620001810CDF80880CDE90051DDE9032133464B +:10A630002046FFF727FD04998346032088725A4875 +:10A6400080F8008033E0049981F80A800EE00099D8 +:10A65000B2F91A300914994203DCB2F91820914278 +:10A6600025DA012823D10499032088720498E1682F +:10A67000C0F806101BE0009801B24A48B0F910205B +:10A68000914214DDB0F91220914210DA0099B0F92C +:10A690001A20091491420ADAB0F91800814206DD45 +:10A6A0002969019A114329613F4981F80080761C8C +:10A6B00097F91006B042BFF64BAE28686C68A968DF +:10A6C000EB6840EA040241EA03063243374E2A6946 +:10A6D00001D022B105E022B186F800A001E086F8A1 +:10A6E0000080304A58321668B0432860506884436E +:10A6F0006C6090688143A960D0682D498343EB600A +:10A7000028690978084305D126492C222C3125488F +:10A710000CF056FF05B05846BDE8F08F30B5234B1E +:10A720000021049A1B78012B01D102B1012190F87C +:10A730002421042A2DD11A4A136893F83824520789 +:10A7400027D5B0F84820B0F84A40121B154C248D8C +:10A75000A2421EDD4FF49172125C012A01D0022A3E +:10A760000AD190F8614090F86050641B93F841540E +:10A77000AC4201DD01210CE0032A01D0042A08D1FA +:10A7800090F8632090F86200101A93F841249042E8 +:10A79000F0DC084630BD000014061000AB061000C7 +:10A7A000D8061000382910001A0610008005100085 +:10A7B0008D06100030B5FF4A0021136893F8382445 +:10A7C00052072BD590F82421042A27D1B0F848202D +:10A7D000B0F84A40121BF84C248DA2421EDD4FF403 +:10A7E0009172125C012A01D0022A0AD190F86140CC +:10A7F00090F86050641B93F84154AC4201DD012194 +:10A800000CE0032A01D0042A08D190F8632090F8C4 +:10A810006200101A93F841249042F0DC0846B9E730 +:10A820002DE9F34F97B0E548002415940078DFF840 +:10A8300088B301280BD11898006940B1DBF804A057 +:10A84000DBF80C90DBF81480DBF81C6007E0DBF829 +:10A8500000A0DBF80890DBF81080DBF81860179F89 +:10A86000002507F5805703E20120A840D7F8081615 +:10A87000059001420FD0C5EB051000EB451117986C +:10A8800000EBC1000290C08F410404D4400703D400 +:10A89000CB4901200870EAE1029800F58C70039022 +:10A8A0000298C0680C900790029890F82401012843 +:10A8B00006D0022804D004282ED005287ED0D6E168 +:10A8C00018981422C1680091006901900CA8189989 +:10A8D0000CF031FE0DF1300C02989CE80E00FFF7F1 +:10A8E0001DFF012801D10399487018981422C168EE +:10A8F0000091006901900CA818990CF01CFE0DF154 +:10A90000300C02989CE80E00FFF754FF0128C2D1DA +:10A9100003990020C870AAE10398807A012801D029 +:10A92000032803D1DBF81480DBF81C60189814228C +:10A93000C1680091006901900DA818990CF0FBFD09 +:10A940000DF1340C02989CE80E00FFF733FF01284C +:10A950000CD00398C07810B10399401EC870994874 +:10A96000008830B103990020C87005E000200399E9 +:10A97000F4E70398C07828B9029890F82E110120C6 +:10A980008840044318981422C1680091006901901E +:10A990000DA818990CF0CFFD0DF1340C02989CE82D +:10A9A0000E00FFF7BBFE012801D103994870039800 +:10A9B0000079032820D20399C97800E01BE1D9B1BE +:10A9C00002990A6B7B490968B1F844148A4210DD88 +:10A9D000401C0399C0B20328087107D002987A4935 +:10A9E000B0F95400B1F90010884205DD012015903E +:10A9F00002E00399002008710398837A062B27D080 +:10AA00000C980FFA8AF200B290420DDB4FEA2A410D +:10AA1000884209DC0C994FEA294C0914614503DC92 +:10AA20000FFA89FC614541DADDE902319042DB68C9 +:10AA3000C1F8063003DB4FEA2A4188422DDD039836 +:10AA40000221EBB28172002000900799189891E0E2 +:10AA50001898059A01690120114217D00299002225 +:10AA600091F82E1188408443DDE90201891D00F030 +:10AA700032FA02984FF6FB31C08F084040F4006173 +:10AA80000298C187039901208870F0E0009049483E +:10AA9000EBB20068B0F9962AD7E703980421EBB22D +:10AAA000817201200FFA89F20090CEE70FFA88F246 +:10AAB0000692904209DB4FEA2842904205DC3014AE +:10AAC000814202DC30B2814257DA022B02D0042BE1 +:10AAD00004D00BE003990120887202E0039803215F +:10AAE0008172DDE90210C968C0F806100398407849 +:10AAF00050BB0398801D00900298DBF8241005914C +:10AB0000019090F822110C300129009925D007F00E +:10AB10006EFB059988420DDDDDE90010002200F092 +:10AB2000DAF901984FF6FB31C08F084040F400611C +:10AB30000198C1870298C08F000505D5029890F84A +:10AB40002E110120884084430398807A01280BD07D +:10AB50000120EBB232B2009077E7B1F90210B0F900 +:10AB60000200081A4043D4E70020DDE906210090E6 +:10AB7000EBB21898FFF751FA79E0189800220169B2 +:10AB80000598014318980161DDE90201891D00F073 +:10AB9000A2F902984FF6FB31C08F084040F40061E3 +:10ABA0000298C1870399012088700298B0F840107C +:10ABB00000480BE0D806100038291000800510006E +:10ABC0001A061000E2061000FC051000006890F85C +:10ABD0004E24914208D9029990F84F0491F8281117 +:10ABE0000844029981F82801029890F82E1101205A +:10ABF000884084433BE00398807A012804D00328EE +:10AC00000FD006280DD032E00398C07878B30298B0 +:10AC1000B0F95410B9480068B0F8550481420CDC12 +:10AC200025E00298B0F95410B4480068B0F8500418 +:10AC300081421CDD0398C078C8B1B148008888B94A +:10AC4000B048007801280DD0DDE902010122891DFC +:10AC500000F041F90298C08F20F0040040F4004158 +:10AC60000298C1870298B0F85410A0F852106D1CD9 +:10AC700097F91006A842BFF6F7ADA3480CB1012121 +:10AC800000E000210170159819B045E530B59B49E9 +:10AC90000A689E49938E08801B1A4B8092F847449D +:10ACA00005198D801B1BCB80528E0881101A48819C +:10ACB0008D81001BC8816DE5904909688A8E934992 +:10ACC0000884101A488470478C4B904A1B6840B126 +:10ACD00071B1598E081A508393F84A14401AD083E0 +:10ACE000704711B1588E5083F9E70020108303E0BC +:10ACF000108393F84A140844908370477F4A10B435 +:10AD0000136882499A8E60B10882121A4A8293F8B7 +:10AD10004A4420448882101BC88293F84D0410BC1A +:10AD2000CAE7002008824A828882CA8208844A844C +:10AD300010BC704770B5714C206890F84604FFF75E +:10AD4000A5FF206890F84B04FFF7D8FF2068012189 +:10AD500090F85404FFF7B8FF2068002190F85404DD +:10AD6000FFF7B2FF2168694A91F8480440435062F6 +:10AD700091F84904108565492C22A1F12C000CF0B2 +:10AD80001FFC61480024634D047061481421047065 +:10AD90005E486C602C300CF06FFC5F4804702C70C7 +:10ADA00070BD70B586B00646142168460CF064FC90 +:10ADB00057480024694604703046FFF7B9FA054643 +:10ADC00069463046FFF72CFD28435249012801D03F +:10ADD000486805E04948006890F84204401F486010 +:10ADE000002804DD401E48604748007800B94C60E8 +:10ADF0004648142269462C300CF0E2FB06B070BDC8 +:10AE00002DE9F04700F138060546B078434F0B4670 +:10AE10000024B8B1424AF1781078401E814258D1DE +:10AE2000C1B2904618460CF0A5FD814698F8000086 +:10AE3000401EC1B238680CF0A3FD0346307872782A +:10AE4000014611E0002118460CF094FD81460021D6 +:10AE5000F0E700BF19F8006095F84770BE4201D1D5 +:10AE6000641CE4B2401CC0B28242F3D2234E61B1F2 +:10AE70003068B0F83A04491EC9B233F911708742FC +:10AE800003DD641CE4B20029F5D126480078401E99 +:10AE900082420DDA316882420ADA521CD2B2B1F82B +:10AEA0003AC433F91270674502DD641CE4B2F2E77C +:10AEB0001D4880F85C40316891F84C14A14208D2DA +:10AEC000A98C41F48061A98410F85B1F41F008014E +:10AED0000170BDE8F087022380F82431002380F858 +:10AEE00028310123C362012A04D00968016280F875 +:10AEF0001831704703220C3007F056B9D8061000FD +:10AF0000E20610000E05100018061000642910005B +:10AF10001A061000800510001906100080061000A7 +:10AF2000590610005A061000B8530120FBF7FEBF67 +:10AF300010B54FF4B8519F480CF09EFB4FF49E6142 +:10AF40009D480CF099FB9D48FF2180F8101600F0F9 +:10AF500080FCFEF7D0FBFFF7EDFE00F03BF9FDF7BC +:10AF600080F8FDF798FEFBF7E3FFBDE81040FCF723 +:10AF7000B3BE70B5924D00248E48AC7100F06FFCEA +:10AF80009048007828B18B48FFF70BFF894800F004 +:10AF900022F98848FDF771F88648FDF783FE8A4E4E +:10AFA000307810B98348FCF7B1F88348347080F8E2 +:10AFB000EC448248B0F81406A5F81F0070BD2DE9D6 +:10AFC000F0417D4C7E4D94F8EC04B8B3A8717F48F5 +:10AFD0007F4F00260670386890F88002800703D5FE +:10AFE00021467448FEF729FB7349724800F073FC50 +:10AFF0007448007810B16F48FFF7D3FE386890F8B6 +:10B000007E03C00702D06B48FEF79DF9694800F047 +:10B01000E2F8684800F075F96648FDF72EF86548D3 +:10B02000FDF740FE6348FCF771F884F8EC64634870 +:10B03000B0F81406A5F81F00BDE8F081FFE7FFF7A0 +:10B0400098FFF4E710B55E4800248471594800F079 +:10B0500006FC5848FDF711F85648FBF7E0FF564844 +:10B0600080F8EC4410BD10B5534C94F8EC04D8B102 +:10B070005349887121464F4800F02DFC5448006820 +:10B0800090F87E03C00702D04A48FEF75CF94948B1 +:10B0900000F0A1F84748FCF7F0FF4648FBF7BFFF78 +:10B0A000002084F8EC0410BDBDE81040CAE710B5DC +:10B0B000414C014694F8EC040F280DD2C0EBC000BF +:10B0C00000EB400004EB800054220CF079FA94F875 +:10B0D000EC04401C84F8EC0410BD10B500F5805061 +:10B0E0000021D0F80836012202FA01F423420BD1E4 +:10B0F0008A401343C0F8083690F910268A4201DAD4 +:10B1000080F8101648B210BD491C0F29ECDB4FF037 +:10B11000FF3010BD10B500F5805091F83241012389 +:10B12000D0F80826A3409A43C0F80826002281F8E8 +:10B13000242190F9102691F932118A4207D1D0F8D2 +:10B140000816B1FA81F1C1F11F0180F8101610BD87 +:10B1500030B500F580500022D0F80C46012300BF26 +:10B1600003FA02F52C4206D193401C43C0F80C466A +:10B1700081F8332130BD521C52B20A2AF0DBFF2085 +:10B1800081F8330130BD10B500F5805091F833419E +:10B190000123D0F80C26A3409A43C0F80C26FF20C8 +:10B1A00081F8330110BD04487047034890F8EC045F +:10B1B00070470000A8291000A8401000A83910000E +:10B1C000B853012016071000E4061000880510008F +:10B1D000D806100070472DE9F047054641F2086097 +:10B1E000042128440AF03AFF00240127DFF86C818B +:10B1F000DFF86C914FF0050A05F580567BE000BF43 +:10B20000D6F8081607FA04F0014272D0C4EB041015 +:10B2100000EB441005EBC00191F82401012804D093 +:10B22000022802D0042840D063E091F8760101287A +:10B2300008D091F82501032808D0042806D0012859 +:10B240002CD056E0002081F8760123E0454848F2F2 +:10B250000403B0F90020C88F184203D0424AB2F963 +:10B26000002005E0030503D5404A1268B2F95A24CC +:10B27000030702D53E4AB2F90020B1F95230934299 +:10B2800037DAC00506D5B8F90000834202DD81F83F +:10B2900025712EE02846FFF73DFF2AE0B1F9522044 +:10B2A000B8F900008242F5DB23E091F83C0010F091 +:10B2B000060F1ED091F83E0040071AD42E4A2D48A2 +:10B2C0001278B0F90000012A01D1B9F9000091F813 +:10B2D0002521032A02D0022A05D00AE0B1F9522022 +:10B2E000B9F9000001E0B1F95220824201DA81F897 +:10B2F00024A1641C64B296F91006A04280DABDE86D +:10B30000F087F0B50021012600F5805304274FF0A7 +:10B310000D0C00BFD3F8082606FA01F4224218D01B +:10B32000C1EB011202EB411200EBC202002592F8C0 +:10B330002441092C06D00A2C04D00B2C05D00C2C4F +:10B3400003D004E082F8247101E082F824C1C2F83D +:10B350003851491CC9B20F29DCD3F0BD00061000DA +:10B3600002061000FC05100014061000D80610009C +:10B370001E061000040610001906100090F83C107C +:10B38000090603D5C18F41F00801C18770472DE937 +:10B39000F05FDFF890A615460C46834601F10C07D6 +:10B3A0004FF000084FF0FF3902F10C069BB301206B +:10B3B00084F8240195F8460084F8250184F8339137 +:10B3C00084F8288184F82981A4F83E80C4F82C8070 +:10B3D00084F8278184F82A8195F8480084F82D01A3 +:10B3E000688EA4F85400E8682062032231462046A3 +:10B3F00006F0DAFE03223146384606F0D5FE4FF459 +:10B400000040A4F85E00A4F85A00401EA4F85C00B6 +:10B41000A4F858003CE0FFE71146204600F037FB57 +:10B42000E06A0322401CE0623146204606F0AFFE8F +:10B4300003223146384606F0AAFE94F82C0184F81F +:10B440002D01DAF80000E16A90F8DA0381421FD298 +:10B45000E089618A401AB4F95A1000B2814201DAD7 +:10B46000A4F85A00B4F95810814201DDA4F858003C +:10B47000A089218A401AB4F95E1000B2814201DA33 +:10B48000A4F85E00B4F95C10814201DDA4F85C0010 +:10B4900094F82501042851D095F8460084F8250138 +:10B4A00095F8460084F8250195F8480084F82C01A9 +:10B4B00095F8470084F82E01E88CA4F84000288D08 +:10B4C000A4F84200688DA4F84600E88DA4F848006E +:10B4D000288EA4F84A00288BA4F84C00B5F9320055 +:10B4E000A4F85200A9692163E9696163296AA1632B +:10B4F000A98EA4F85610A98CA187A96B2166696949 +:10B50000E16195F8491084F82F1195F84A1084F8F4 +:10B510003011B5F84E10A4F84410B4F9541081421B +:10B5200001DAA4F85400C4F86C8184F83191A88C35 +:10B530008005E08F16D540F4807015E095F8461030 +:10B54000042908D094F93401002801DD401E06E0EA +:10B5500084F82511A4E7DAF8000090F8940A84F83A +:10B5600034019DE720F48070E08755F83C0F606659 +:10B57000287A84F87101687A84F872012146584665 +:10B5800000F05CFA2046BDE8F05FF7E6F0B5B1F9EF +:10B590000260B2F90250782406FB05F7002F2ADD7D +:10B5A000B1F90070B2F900C007FB0CF7002F22DDE3 +:10B5B00076435D4396FBF5F52DB24580B1F9001059 +:10B5C000B2F9002049435A4391FBF2F10AB20280DA +:10B5D000782D00DD4480B0F902306FF077018B42A6 +:10B5E00000DA4180782A00DD0480B0F900208A4228 +:10B5F00000DA0180F0BD00214180FAE72DE9FF4F1C +:10B60000DFF8248483460F46D8F8040087B0002171 +:10B61000016000F0CBFA00250BF580564FF00109D0 +:10B62000059088E0D6F8080609FA05F108427DD0B1 +:10B63000C5EB051000EB45110BEBC10494F8240198 +:10B64000072876D0F748059901910068214690F8BF +:10B650008CA3201D06F0CBFD00FB0AF0019900FB36 +:10B660000AF0884200DA0846EE49096891F87F231B +:10B67000920611D5E26A012A0ED802D191F8D813A8 +:10B6800002E04AB991F8D713019A01FB01F101FBDD +:10B6900002F1884200DA084682462246211D6846A9 +:10B6A00006F09BFD221D111D03A806F096FDBDF9B5 +:10B6B00000006430C82804D8BDF902006430C828EE +:10B6C00001D9012300E0032303AA694602A8FFF77A +:10B6D0005DFF6088BDF80A100844ADF812002088AC +:10B6E000BDF8081000240844ADF810001BE000BFAE +:10B6F000C4EBC40000EB400007EB800104A80C3150 +:10B7000006F075FD50450CDAD8F804100A6802EB13 +:10B71000420201EB42025060547215720868401CEC +:10B720000860641CE4B297F8EC0400E001E0A04279 +:10B73000DED86D1C6DB296F91006A842BFF672AF46 +:10B74000D8F804004646016800297FD000F00AFAC4 +:10B7500000244FF0040A75E004EB440100EB4100C3 +:10B7600090F9085090F909C0099809FA05F10368A1 +:10B7700048460B4265D10A9AD2F8008000FA0CF2D2 +:10B7800018EA020F5DD109980B43C84603600A9876 +:10B790000A990023006810430860C5EB051000EB10 +:10B7A0004511CCEBCC0000EB40000BEBC10507EBE7 +:10B7B000800229465846FFF7EAFD95F82401032840 +:10B7C00008D0042809D006280DD00B2836D00C2824 +:10B7D00034D036E085F8278102E0002085F8270183 +:10B7E00085F824A12DE085F824A195F83C0010F0FF +:10B7F000060F26D095F83E00400722D48B48B0F9BA +:10B8000000108B480078012802D18A48B0F9001056 +:10B8100095F82501032802D002280AD011E08548B6 +:10B82000B5F95210B0F9000081420ADA062006E0AC +:10B830000CE0B5F952008842F8DB02E00C2085F8F4 +:10B840002401641C70680168A14285DC0BB0BDE86E +:10B85000F08F7548002101704160816070472DE9CB +:10B86000F041054641F254602E2128440BF004FFBC +:10B870000024052705F5805620E00121D6F80806AA +:10B88000A140084219D0C4EB041000EB441005EBB2 +:10B89000C00191F82401032816D0042814D00228EE +:10B8A00015D0092810D00A280ED00B280FD00C284C +:10B8B0000DD00D280BD00E2809D0641C96F9100667 +:10B8C000A042DADABDE8F08181F82471F5E7284674 +:10B8D000FFF720FCF1E72DE9FC470446002552481C +:10B8E0000F4600950121001D019503F093FF4E487E +:10B8F0000521083003F08EFF41F254602E212044D0 +:10B900000BF0BAFE484EFF222D21B0680BF08AFEE4 +:10B91000357004F580564FF00108D6F8080688B354 +:10B920006B4601AA39462046FFF768FE4FF005092D +:10B9300024E000BFD6F8081608FA05F001421CD032 +:10B940000199084219D1C5EB051000EB451004EB35 +:10B95000C00191F82401032818D0042816D0022829 +:10B9600017D0092812D00A2810D00B2811D00C2883 +:10B970000FD00D280DD00E280BD06D1C96F9100697 +:10B98000A842D7DAD6F8086600253AE081F8249173 +:10B99000F3E72046FFF7BEFBEFE700BF009908FA88 +:10B9A00005F008422CD12046FFF797FB002827DB43 +:10B9B000C0EB001101EB401104EBC109C5EBC5015F +:10B9C00001EB410107EB810289F83201494601236D +:10B9D0002046FFF7DCFC9EB917480078012809D102 +:10B9E00009F1280109F10C0006F03DFC4846FCF77E +:10B9F000FFF828B1B9F83E0040F48051A9F83E1094 +:10BA00006D1C97F8EC04A842C8D807480121001D16 +:10BA100003F018FF04480521083003F013FFBDE8C8 +:10BA2000FC870000D80610008C05100004061000EA +:10BA300019061000020610001C07100030B5714AEC +:10BA400091F82C519468635DFF2B05D113786355F1 +:10BA50000F2B01D25B1C137091F82C21A25C81F892 +:10BA60002C2100EB420202F5805291F83251B2F8DB +:10BA700054360124AC402343A2F8543691F82C11DB +:10BA800041F2726210440A5C521C0A5430BD2DE926 +:10BA9000F041044691F8460000260D46012801D1E8 +:10BAA00084F82A6194F82501574FDFF86081012856 +:10BAB0001FD195F8460003284DD194F8240102289F +:10BAC00004D0032806D0042804D01EE02046FCF74A +:10BAD0004EFA0EE0D8F8001094F82A0191F84B13B2 +:10BAE00001F00F01884202D83978012906D084F884 +:10BAF0002A6195F84600032807D008E0401C84F826 +:10BB00002A01012085F8460001E084F82B6194F8B1 +:10BB1000250103281FD195F8460001281BD194F870 +:10BB20002401042817D13878B0B9D8F80000B4F946 +:10BB300054200321B0F852339A4210DA94F82B21A2 +:10BB400090F85403824207D285F8461094F82B01EE +:10BB5000401C84F82B01B5E684F82B61B2E685F829 +:10BB60004610F9E77CB500211CE001EB41034A1CBB +:10BB700000EB430312E002EB420400EB44045E6876 +:10BB80006568AE4209DD00961E89ADF804605D600F +:10BB900025891D81009D65602681521C04689442A0 +:10BBA000E9DC491C02688A42DFDC7CBD70B5174DB8 +:10BBB0002868B0F882430BF099FE80B128681449D8 +:10BBC000B0F88643B0F88A030968884207DA0BF0B8 +:10BBD00097FE012803D12868B0F8880304440D4873 +:10BBE000007810B12868B0F876420BF089FE012881 +:10BBF00004D12868B0F8840300B1044604FB04F0C3 +:10BC000070BD00008C05100065061000D8061000FD +:10BC10009006100020051000F0B5002406462546C9 +:10BC200020465F4209E000BF36F91130934201DD42 +:10BC30001D4402E0BB4200DA1C44491EF4D2002C31 +:10BC400000DA6442AC4200DD0120F0BD2DE9F0478E +:10BC5000FF4D002047F6FF7901462A464B46FD4C32 +:10BC6000FD4EB4F900403668A4460AE036F91C706F +:10BC7000974200DD3A469F4200DA3B46381841EBD6 +:10BC8000E771BCF1010CF1D2F44FD21A4FEAE47A19 +:10BC90007A60224653460BF02AFC0FFA80FC002003 +:10BCA0000146224606E000BF36F91230A3EB0C0332 +:10BCB000C3FB0301521EF7D2224653460BF017FC7A +:10BCC0000A21386090FBF1F0E549E64B4A46A1F8BD +:10BCD000790000200146A4461E680AE036F91C30AF +:10BCE000AB4200DD1D46934200DA1A46181841EBBC +:10BCF000E371BCF1010CF1D2AA1AFA602246534654 +:10BD00000BF0F5FB05B200200146224605E000BF1E +:10BD100036F912305B1BC3FB0301521EF8D22246D8 +:10BD200053460BF0E4FBB860BDE8F08730B414462E +:10BD3000CA4A15689368AB4202DD5B1B834206DC8E +:10BD4000D3685068834204DD181A884201DD01225D +:10BD500000E00022214630BCC34806F0C0B910B54F +:10BD60000C46C24909784A000146C1480BF0E3FB82 +:10BD7000C048214600784200BF480BF0DCFBBF49B9 +:10BD80000120087010BDB34910B5B1F900104A0088 +:10BD90000146B44800680BF0CEFBB9490120087099 +:10BDA00010BD2DE9FF5FB04800240C38DFF8D492B5 +:10BDB00044600470D9F80000DFF8ACA2984690F80F +:10BDC000EB132646274625460907AAF1040A16D58D +:10BDD000A2490A890B88D31AA14A22F8673F8B89A6 +:10BDE0008988591A518090F81224B0F81014D0F8AC +:10BDF0000C04FFF79BFF12270446012601E08AF896 +:10BE00000450D9F8000090F8A502400701D59E48DB +:10BE100005708CBBDFF874B29BF8000010B99BF87A +:10BE2000010018B10098F9F732FE0AE0984800784E +:10BE300018B10021062005F039FD95480570954898 +:10BE400005709BF8001011B99BF80100A0B1D9F85A +:10BE50000000DFF844B290F8EB03C0070DD08F4A22 +:10BE60008F49DBF8000000F0D5F804004FF03007F0 +:10BE70004FF0010603D012E024E08AF80150D9F80F +:10BE8000000090F8EB03800709D5844A8449DBF869 +:10BE9000000000F034F931270446012601E08AF859 +:10BEA00002506CB9D9F8000090F8EA03400707D5B2 +:10BEB0007A497B4800F060F921270446012601E019 +:10BEC0008AF803500BF028FD764BDFF8DCC1012126 +:10BED00018707648012C08D1D9F8002092F8572420 +:10BEE0001AB18CF80010028007E0028812B1521ECD +:10BEF000028001E08CF800507CB3D9F8002092F861 +:10BF0000F021120600D576B96EB188F80050394696 +:10BF1000052005F0CBFC0098FFF735FFDDE90101B6 +:10BF2000FFF71DFF15E088F800104F490C390F701E +:10BF30004A6842F002024A60D9F8000090F8503294 +:10BF4000DB0703D190F88002C00702D042F008005E +:10BF50004860012004B0BDE8F09FFFE788F800507A +:10BF60001878F7E72DE9F05FDFF8FCA00024AAF1CC +:10BF70000C0ADFF81091CAF8044083468AF80040A2 +:10BF8000D9F800000E46274690F8EB132546A04648 +:10BF900049060BD590F81924B0F81714D0F81304FB +:10BFA000FFF7C4FE12250446012703E02E49091FAE +:10BFB00081F804800BF0B0FC01463A480170E4B10E +:10BFC0007FB186F80080D9F8000090F8EB03C00636 +:10BFD00003D52946052005F069FC5846FFF7D3FE36 +:10BFE00009E0012030708AF80050DAF8041041F0BE +:10BFF0000201CAF804100120ADE786F8008000783D +:10C00000A9E7194900200C39486008700831086018 +:10C01000087170472DE9F74FDFF868900B468246AC +:10C02000D9F8001011480026B1F9F27391F8F6839F +:10C03000B1F9F453027834463946184600F0C0F896 +:10C0400083460C4839460278029800F0B9F82FE090 +:10C050000080FFFF6A0610008406100054120120C1 +:10C06000B853012088061000A405100059061000DE +:10C07000286D01205A061000526D0120150710008E +:10C0800014071000D80610002A051000B051100047 +:10C09000200510000E0510007C061000220B012068 +:10C0A000F80A012022061000E0061000E206100047 +:10C0B0000146BBF1000F00D0A1B94E485246002402 +:10C0C000B0F9000009E000BF32F91010002900DAD1 +:10C0D0004942A94201DD641CE4B2401EF4D2444549 +:10C0E00000D90126D9F80000324690F8F7134248EB +:10C0F00005F0F5FF414981F83140BDE8FE8F2DE99B +:10C10000F047DFF8FC8084460B46D8F80000394938 +:10C11000002590F8FC73B0F9FA6391462C46B0F90B +:10C12000F803B1F9001006E03CF91120002A00DA0A +:10C130005242824213DC491EF6D23248314602781E +:10C14000184600F049F804462F4831460278484620 +:10C1500000F042F82044C4B2BC4200D90125D8F80E +:10C1600000002A4690F8FD132348401C05F0B7FF55 +:10C17000224981F83240D7E570B5214C05460E467C +:10C180002068B0F90934B0F907241E480178284620 +:10C19000FFF742FD05462068B0F90934B0F90724DD +:10C1A000194801783046FFF737FD40EA050220685C +:10C1B00090F80B14BDE870400F48801C05F08FBF4D +:10C1C00006E000BF30F912308B4201DD01207047DC +:10C1D000521EF7D20020704710B50346002005E03C +:10C1E00033F912408C4201DD401CC0B2521EF7D21E +:10C1F00010BD00006A061000A1051000B853012010 +:10C20000D8061000590610005A0610002DE9FF4FFD +:10C2100093B000200E908346049005909C48894678 +:10C2200016460068B0F8C0020D90897850680BF08F +:10C2300099FB0A9099F8021030680BF09BFB09906B +:10C2400099F8020047E000BF99F8004034E01398E5 +:10C25000224600EBC8000021D0E9005701200BF076 +:10C2600033F905400F403D4325D00A980D9930F928 +:10C270001400009088421EDD8548006890F8F7029F +:10C2800000070AD50998005DCF287BD028B196F821 +:10C290004B10884201D000200090009904988B44F4 +:10C2A00004FB01000490059808FB010005900E981E +:10C2B000401C80B20E90641C99F80100A042C6DABE +:10C2C00074490A98097800EB41000A9009982830CF +:10C2D000099008F1010099F8031080464145B3DA4E +:10C2E0006B48002504680598A18EC217A1FB003792 +:10C2F00005FB007001FB02014FF6FF77A3FB070C63 +:10C3000001FB07C103FB051194F8313030345B1E8B +:10C310008BFB03230BF0EBF87A108018B94641F140 +:10C3200000014A4600230BF0E2F880460498618839 +:10C33000C217A1FB003705FB007001FB02024D464E +:10C34000A3FB050702FB0572002103FB01212378F3 +:10C350005B1E8BFB03230BF0CAF86A10801841F1B7 +:10C3600000014A4600230BF0C2F8C6F81CB00E9933 +:10C370003185169948601699C1F8008017B0BDE85C +:10C38000F08FFFE700200F90451E089008EB05078F +:10C39000F9B230680BF0EEFA8246F9B270680BF031 +:10C3A000E1FA4FF0FF3163181AF803208AB1CF2A5F +:10C3B0000FD096F84B70974205D130F81370089A59 +:10C3C0003A4492B2089230F813300F9A1A4492B25B +:10C3D0000F92491C49B20129E5DD6D1C6DB2012D9A +:10C3E000D4DD089800283FF458AF009948430F99CE +:10C3F00090FBF1F050E710B5254943680022096829 +:10C40000002B01DA426003E04C8EA34200DD446061 +:10C410000368002B01DA026010BD898E8B42FBDDC0 +:10C42000016010BD7CB5144600256B46FFF7EEFE9B +:10C4300019480178164829B1016891F807150907CC +:10C4400000D5042594F84610032902D0012907D00D +:10C450000FE0006890F80705C0070AD0294605E0FC +:10C46000006890F80705400703D50221684601F0EF +:10C47000F1FE6846FFF7BFFF0198E0810098A081B8 +:10C4800094F82400C00601D4E06860617CBD00001F +:10C49000D80610005A061000180610002DE9F047C3 +:10C4A000054690F802800F468868144601264146EA +:10C4B0000BF058FA8146A8F10100C1B2B8680BF040 +:10C4C00051FA297809EB410232F9022CA24203DB2E +:10C4D00030F91110A14200DA0026697809EB410217 +:10C4E000B2F90220A24203DB30F91100A04200DAC7 +:10C4F000002695F80380B86841460BF033FA814670 +:10C5000008F10100C1B2B8680BF02CFA297809EBE8 +:10C51000410232F9022CA24203DB30F91110A14290 +:10C5200000DA0026697809EB4102B2F90220A24242 +:10C5300003DB30F91100A04200DA00263046BDE8E6 +:10C54000F0872DE9FF4F97B099469246FE48DFF8F5 +:10C55000FC83012204685146D8F8000001F008FB72 +:10C56000FB480068B0F9B919119190F8B8090A9020 +:10C57000F8489AF802709AF8036000789AF800B0C8 +:10C580009AF80150401E874201DA7F1CFFB20EB1BB +:10C59000761EF6B2F0490978491E8B4503DA0BF195 +:10C5A000010000F0FF0B0DB16D1EEDB2B81EC1B25F +:10C5B000D9F808000BF0D6F90B90781EC1B2D9F863 +:10C5C00008000BF0CFF904903946D9F808000BF0B9 +:10C5D000C9F90190781CC1B2D9F808000BF0C2F972 +:10C5E0000290B81CC1B2D9F808000BF0BBF9039057 +:10C5F000394617980BF0B0F90890D44839460068CE +:10C600000BF0B8F9864600207AB2D44F0C90B7E010 +:10C610004FFA8BF094E000210EF800100899189B57 +:10C62000095C994275D1DFF828C3019BDCF800C092 +:10C6300033F91030BCF8BBC963456ADA00211491A4 +:10C64000139111991944049B09B233F910301093D6 +:10C650008B4206DD029B33F910308B4201DD012352 +:10C660001393019B03EB400333F9028C884507DDEC +:10C67000B3F902C08C4503DD4FF0010CCDF850C07A +:10C68000012A0FDDDDF82CC03CF910C08C4509DD16 +:10C69000DDF808C03CF910C08C4503DD4FF0010CFB +:10C6A000CDF84CC0DFF8ACC29CF800C0ACF1020C75 +:10C6B00062450DDADDF840C08C4509DDDDF80CC0BF +:10C6C0003CF910C08C4503DD4FF0010CCDF84CC097 +:10C6D00001280BDD33F904CC8C4507DDB3F902C02A +:10C6E0008C4503DD4FF0010CCDF850C0DFF868C277 +:10C6F0009CF800C0ACF1020C604505DA884503DD0A +:10C70000B3F904308B4212DC149981B913990DE00E +:10C71000FFE799B90199B7F9003031F91010994242 +:10C720000CDA8B49096891F8AD19C90731B10121BB +:10C730000EF800100C99491C89B20C91401C40B2B3 +:10C74000A8427FF768AF84480B990EF1280E007855 +:10C7500001EB40010B91049901EB40010491019917 +:10C7600001EB40010191029901EB40010291039913 +:10C7700001EB4000039008982830521C52B20890F8 +:10C78000B2427FF745AF0A990C9888422AD9002017 +:10C7900084F80E01DAF8000020606C4800231A4685 +:10C7A0002146006801F08BFB012517E004EB8500B2 +:10C7B0000646514600F07AF870B104EB4500B0F837 +:10C7C000B4100A98814207D93046B7F9002049468B +:10C7D000FFF764FE012806D06D1CEDB294F80E013F +:10C7E000A842E3D200201BB0BDE8F08F2DE9F04154 +:10C7F000574E0F4680463168144659481D469A697F +:10C80000B1F8B53900789A4210DCEA8C042A0DD9C7 +:10C810006278237891F8B719D21A521C8A4205DC43 +:10C82000E278A378D21A521C8A4202DD0020BDE8C9 +:10C83000F0810028FBD149482946B0F90020204664 +:10C8400000F048F80028F2D1316891F8AC19890756 +:10C85000EDD52B46224639464046BDE8F04170E60C +:10C860002DE9F0471F00089E154681464FF000084D +:10C870000CD42C7807E0F9B248460BF07BF800F8AE +:10C880000480641CE4B26878A042F4D2002E0CDB71 +:10C89000AC78474606E0214648460BF06BF8641C2E +:10C8A0008755E4B2E878A042F5D248E602780B78E2 +:10C8B0009A420BD942784B789A4207D282788B7889 +:10C8C0009A4203D9C078C978884201D300207047C2 +:10C8D000012070472DE9F84F04461B48DFF86C80B3 +:10C8E00091468B46056801222146D8F8000001F0E8 +:10C8F0003FF90027A6784FF0010A1DE03146D8F82D +:10C9000000000BF037F800903146DBF808000BF020 +:10C9100029F801462078524609E000BF31F910C0DD +:10C92000CC4502DA009B01271A54401CC0B2637840 +:10C930008342F3D2761CF6B2E078B042DED2012F09 +:10C940003ED100200EE00000DC051000C405100000 +:10C95000D8061000590610005A0610001C061000D8 +:10C96000A505100085F80E012068286000231A46EE +:10C970002946D8F8000001F0A2FA0126DFF8488025 +:10C980001AE000BF05EB860721463846FFF78EFF09 +:10C9900080B105EB4600B0F8B410D8F8000090F86C +:10C9A000B809814206D938464A465946FFF776FD0E +:10C9B000012806D0761CF6B295F80E01B042E1D2FD +:10C9C0000020BDE8F88F0000D806100070B5FE4CBE +:10C9D00000EB4305049E00EB830386B18E69A660DD +:10C9E000CE8C668009686161B5F8B410A1801968C1 +:10C9F000E16090F80E0120701068206170BDA6689B +:10CA00008E616688CE8466690E60A188A5F8B41030 +:10CA1000E1681960217880F80E112069106070BDFE +:10CA20002DE9F0470F46994614469178089E0AF082 +:10CA300093FF0546A17870680AF094FF0646A17836 +:10CA4000E2480AF097FF0146A2781CE02078002314 +:10CA50000DE000BF15F800C0BC4506D136F91080C6 +:10CA6000C84501DB0F5400E00B54401CC0B294F8E1 +:10CA700001C08445EED2D648521C28310078D2B28B +:10CA800006EB40062835E0789042DFD2BDE8F0871B +:10CA90002DE9FF4F83B00C461E469978129F109DDA +:10CAA0000AF068FF0090B17820460AF055FF8346EF +:10CAB000B17878680AF056FF81464FF0000AC54801 +:10CAC000CDF804A0C7F818A000682860B0784FE03F +:10CAD00034783EE01BF804000599884237D139F9D3 +:10CAE00014101198814220DD009905980855297885 +:10CAF000204605F0ECFA28706978204605F0EBFA3C +:10CB00006870A978404605F0E2FAA870E9784046D6 +:10CB100005F0E1FAE8700AF101001FFA80FA39F92C +:10CB20001400B9690844B86102E000990020085572 +:10CB300097F8460003280AD1A74939F91400B1F93A +:10CB40000010884203DB0198401C80B20190641CF5 +:10CB5000E4B27078A042BDD200989D492830009080 +:10CB6000097808F101000BF1280B09EB4109C0B26B +:10CB7000F17880464145ABD2A7F826A00198A7F8E6 +:10CB80004E0007B0BDE8F08F2DE9FF47814693F8CE +:10CB90004600924E1C4615468846032832D1E08C4A +:10CBA000A4F84C002868E0633368B4F932106422BA +:10CBB00093F8BD0293F84B3A484390FBF2F007B26A +:10CBC0008548642BB0F9000005D8594391FBF2F178 +:10CBD0000BB2834200DA03462A4641464846009497 +:10CBE000FFF71EFFB4F93600B8420BDA03A8CDE90F +:10CBF000000749462B46424602940846FFF748FF85 +:10CC000003982860764F387808B9787860B1306832 +:10CC100090F83002000707D523462A464146484689 +:10CC2000F8F7F3F800283DD06E480178042029B1C8 +:10CC3000397819B16C490978012904D094F8461063 +:10CC4000032905D00CE03268E18C92F87A2203E0E7 +:10CC50003268E18C92F81F23914201D984F8460092 +:10CC6000624B2A464146484600F04DFF002819D045 +:10CC700084F84B802868A063224629465B4800F070 +:10CC800011FE5B492046FEF7BBF82946574800F0E5 +:10CC9000D3FE224629465548FFF7C4FB2046FEF73F +:10CCA00006FA012004B0F1E62DE9F0410D461F46D9 +:10CCB0001646044654210AF0DFFC002084F84600A2 +:10CCC0004C4800686060A06006EB450084F848505E +:10CCD00030F8B41F61850088E08406EB85000068A9 +:10CCE000206445480088E086374881692160012139 +:10CCF000A940394201D0406A2060BDE8F0812DE9A9 +:10CD0000F04789461C4616463C4D03F1440891788D +:10CD10000AF022FE0746B17860680AF023FE024658 +:10CD20000020A061B1781FE0307813E017F800C050 +:10CD3000CC450DD132F91030D4F818C0AB429C4428 +:10CD4000C4F818C004DD88F800001D4688F80110FA +:10CD5000401CC0B273788342E8D21D48491CC9B256 +:10CD60000078283702EB4002F0788842DCD2244871 +:10CD70006586B0F90000854202DD012084F850008C +:10CD800084E62DE9FF4117460AAA804692E8310061 +:10CD9000194A1E46B2F90020824202DB002004B08C +:10CDA000ABE703AACDE9002002943A464046FFF7DC +:10CDB0006FFE01212868B94008432860C4F800804C +:10CDC000E08C08B303981DE0A8051000FC150120B5 +:10CDD0005A0610004E79010002061000D806100015 +:10CDE000B05110000C0510000E0510009845100001 +:10CDF000641201207C0610000A0610000080FFFF6C +:10CE0000FC0510003060C9E70120C8E72DE9FF4F9D +:10CE100081B090460E9C8B4604EB880094F80E710E +:10CE2000DDF840A000681E462060012321465846D8 +:10CE300001F045F8019858451FD0B5781AE0294609 +:10CE400001980AF097FD8146294658460AF092FD5E +:10CE50000146307809E000BF19F80030434502D19F +:10CE60000B5C09F80030401CC0B272788242F3D2E9 +:10CE70006D1CEDB2F078A842E1D294F80E010025C5 +:10CE80000121B84212D0119878B17F1CF8B208E0A5 +:10CE9000DAF8002001FA00F31A43401CC0B2CAF8C5 +:10CEA000002094F80E218242F2D2012500914346DF +:10CEB000524620460F99FFF789FD284605B061E6E6 +:10CEC00010B5FE4AFE4C1368647893F81E2354B1E3 +:10CED00091F8241011F0090F02D093F8211301E00A +:10CEE00093F820130A44F749097809B193F86F229F +:10CEF000904201D9012010BD002010BD2DE9F04164 +:10CF00001C4615460E46074601F034FAEB48E28C03 +:10CF1000016891F82803824244D8032084F846002F +:10CF200091F8F6020022830701D4400700D50122C0 +:10CF3000DFF88CC3B1F82203B1F826339CF801C0A6 +:10CF4000BCF1000F08D0DFF880C39CF806C0BCF12C +:10CF5000000F01D1B1F82403DC490978012903D17C +:10CF6000984201D9C01A80B2A18D814203D2D8481B +:10CF7000007800B90022608D03280CD3A08C10F437 +:10CF8000C07F08D13AB123462A4631463846BDE82B +:10CF9000F04102F0B2B823462A4631463846BDE891 +:10CFA000F041F1E5042084F84600F4E7C648C07873 +:10CFB00058B1C248C74A0068126890F857139142A6 +:10CFC00007D290F84003800703D5C34900200870BA +:10CFD00070470120704791F82410B84ACB07BF4929 +:10CFE0001268097806D011B192F8481305E092F85A +:10CFF000491302E059B192F84613B14B5B7813B173 +:10D0000092F84A231144884204D90120704792F8CB +:10D010004713F2E7002070472DE9FF4F834687B0A2 +:10D02000A94800270C46DDF850A0017901261546D5 +:10D0300006FA0AF6B946E9B3A948AA49B0F90000C8 +:10D04000B1F90010884237DA2968314234D1E18CD5 +:10D05000042931D98DE83100DFF88C8252460A9BD1 +:10D06000D8F81810D8F82400FFF78BFE070023D15A +:10D070002346206851460A9AFFF7B8FB9B4908707F +:10D08000C0B1781E8DF810008DF814008B48006830 +:10D0900090F8AD09800709D595480078042805D196 +:10D0A00005AA04A90A98F7F738FC50B1A08C40F003 +:10D0B000800000E000E0A084A08C10F4C07F20D0AD +:10D0C0002AE08C499DF9103001F8363F9DF9140093 +:10D0D00048700090206859460A9AFFF7C1FB01A8E2 +:10D0E000CDF800B080E830025246216804F14003D8 +:10D0F000D8F81800FFF78AFE0028DDD001200BB019 +:10D1000040E52868304207D053462A462146584613 +:10D11000CDF80090FFF75AFC3846F0E72DE9F04FC4 +:10D12000DFF8C0A17449E9B0BAF90000B1F9001004 +:10D13000724ACDE96310118071494FF00008C3466F +:10D1400008806948C146474601211C3002F0ACFB0B +:10D1500065480121243002F0A7FB634802212030FA +:10D1600002F0A2FB0221674802F054FB042166484A +:10D1700002F050FB5C4C4FF466752946E0690AF0FA +:10D1800059FA2946606A0AF055FA6048B0F9000079 +:10D190004100206A0AF04EFA29465D480AF04AFA30 +:10D1A00029465C480AF046FAA8215B480AF064FA6E +:10D1B00000266670F7F7CCFDF7F748FB57488DF867 +:10D1C0007E61012300681C9000221CA9A06900F068 +:10D1D00076FE534805960025B0F90010BAF9000014 +:10D1E00004F075FF0FFA80FA9DF87E01012801D93D +:10D1F0003E48067017A80124619088E10020019044 +:10D200001CA800EB840060901CAA214607A8059B7F +:10D21000FFF74AFD07AB2146609A0798FFF76FFDBD +:10D2200001200090234605AA07A91CA8FFF7CEFB02 +:10D2300018A800F0DBFB78B1BDF8400040F0010019 +:10D24000ADF8400007A800F06AFD28B135482A492A +:10D2500000880880234908801D48007838B1BDF84F +:10D26000400010F0060F02D12F4800680890609827 +:10D2700000F0CEFB28B1BDF8400040F00800ADF84A +:10D280004000BDF94E1051457EDD009405AA07A966 +:10D290001CA8609BFFF7C0FE002876D10120A040AB +:10D2A0000599039008427FD1BDF8400010F4C07F7B +:10D2B0007AD105AA07A90B4838E00000D80610006B +:10D2C000100710002A051000B05110008C06100045 +:10D2D00018061000F0051000630610006506100027 +:10D2E0001C06100002061000A8051000A50510007D +:10D2F000E8041000B85301200406100012061000C4 +:10D3000010061000D0051000DC0510006A061000A1 +:10D3100064120120FC15012098451000F80510004A +:10D32000200610001606100080061000B0F900005C +:10D330008DE80700FE482246609B8169406AFFF73E +:10D3400020FD0190FB4803990088ADF85200059A32 +:10D35000114227D0F849BDF84220096891F82833D6 +:10D360009A4205D891F8F6128A071BD4490719D4B6 +:10D37000012305AA07A91CA88DE80F00EC48224646 +:10D38000619B416A806902E033E0BEE00CE0FFF798 +:10D390003DFD019001200090234605AA07A91CA885 +:10D3A000FFF714FB0198E8B9BDF8420007A9FFF7A1 +:10D3B00087FDB8B19DF86C0058B907A80090DF4808 +:10D3C0002146619AB0F90030D948806900F0A4FA8A +:10D3D000074607AB2146609A0798FFF78FFD4FF08D +:10D3E00001087EE0234605AA07A91CA80096FFF7BE +:10D3F000EDFAD249BDF94E00B1F90010884270DD56 +:10D40000FFF7D4FD00286CD09DF86C00002868D18F +:10D410000120A04005990390084232D1C74805AACF +:10D4200007A9B0F900008DE80700C1482246609BBB +:10D430008169406AFFF7A5FC0190C0480088ADF8FB +:10D440005200BD48006890F84003C00619D4059A00 +:10D450000398104215D0012305AA07A91CA88DE83E +:10D460000F00B3482246619B416A8069FFF7CEFCFA +:10D47000019001200090234605AA07A91CA8FFF7E8 +:10D48000A5FA019830BBBDF8420007A9FFF7A3FD3C +:10D4900000B307980090DDF8809107A80190012063 +:10D4A0008DF86200DDE900034A46214600F062FF84 +:10D4B000A1484A462146006890F84003C006DDE9CD +:10D4C000000302D501F019FE01E0FFF75DFB4FF00C +:10D4D000010906E0234605AA07A91CA80096FFF744 +:10D4E00075FA01200599A0400143954A0591639979 +:10D4F00011809049649A0A8092490A782AB10543BA +:10D500009DF87E01012800D90E70641CE4B29DF8DC +:10D510007E01A042BFF472AEC1B28B4841718B490B +:10D52000A0F81D508C4881F800B0894981F800802E +:10D53000884981F800900770FDF737FE9DF87E213D +:10D540008649904202D90120087000E00E70022145 +:10D55000834802F077F90421824802F073F9744895 +:10D560000121183002F003FA714801211C3002F049 +:10D57000FEF96F480121243002F0F9F96C480221CC +:10D58000203002F0F4F969B0BDE8F08F2DE9F04FDA +:10D5900000266748E5B0B146B046664F01211C3011 +:10D5A00002F082F962480121243002F07DF96048DE +:10D5B0000221203002F078F90221694802F02AF9AC +:10D5C0000421684802F026F9594C4FF46675294643 +:10D5D000E0690AF02FF82946606A0AF02BF86248E1 +:10D5E000B0F900004100206A0AF024F829465F489B +:10D5F0000AF020F829465E480AF01CF8A8215D4888 +:10D600000AF03AF84FF0000A5B4884F801A08DF860 +:10D610007EA100681C905546012352461CA9A069B2 +:10D6200000F04DFC554860950025B0F90010B7F9A1 +:10D63000000004F04CFD07B29DF87E01012802D9DC +:10D64000404880F800A00124A346D3E01CA800EBCA +:10D65000840005901CAA214607A8609BFFF724FBC5 +:10D6600007AB2146059A0798FFF749FB234660AAB6 +:10D6700007A91CA8CDF800B0FFF7A8F918A800F07A +:10D68000B5F928B1BDF8400040F00100ADF8400008 +:10D69000059800F0BDF928B1BDF8400040F0080041 +:10D6A000ADF84000BDF94E00B84269DD009460AAB3 +:10D6B00007A91CA8059BFFF7AFFC00287ED10BFA39 +:10D6C00004F06099039008426BD1BDF8400010F45B +:10D6D000C07F66D1174860AA07A9B0F900008DE89D +:10D6E000070013482246059B8169406AFFF749FB02 +:10D6F00001901048609A0088ADF8520003981042DB +:10D700004DD00D48BDF84220006890F828339A4269 +:10D7100005D890F8F602820741D440073FD407AA03 +:10D720001CABCDE9003260A917AB2246004828E0C7 +:10D73000A805100002061000D8061000060610000A +:10D7400004061000A5051000B85301206106100062 +:10D750006206100063061000640610008C061000BC +:10D76000D0051000DC0510006A06100064120120CC +:10D77000FC15012098451000F80510002006100047 +:10D7800027E0CDE9021B416A8069FFF73FFBCDE945 +:10D7900000B0234660AA07A91CA8FFF717F9019853 +:10D7A00078B9BDF8420007A9FFF78AFB48B107AB7B +:10D7B0002146059A0798FFF7A1FB00E018E0012633 +:10D7C00007E0234660AA07A91CA8CDF800A0FFF730 +:10D7D000FDF860990BFA04F00143609175490A78ED +:10D7E00032B105439DF87E01012801D981F800A0DE +:10D7F000641CE4B29DF87E01A042BFF427AFC1B221 +:10D800006D484171A0F81D506C486E4980F8009039 +:10D810006B48067081F8008002216B4802F012F814 +:10D8200004216A4802F00EF80121694802F09FF8CD +:10D8300067480121001D02F09AF8654801210C306B +:10D8400002F095F862480221083002F090F865B0C5 +:10D850009AE65A49002008705949087059490870D9 +:10D86000544908705B4908707047F2E75849002036 +:10D870001839554A08628861C8611060534A1060BF +:10D880004E4A10704E4A10704E4A1070494A10703D +:10D89000487070474E49002018394870A8214E48FA +:10D8A00009F0EABE2DE9F74F49480D46183841788E +:10D8B0000F2901D2491C417001F0FF09474982F844 +:10D8C000479001EB890029680160A97844480AF073 +:10D8D00051F88246A87819E000982C7800EBC80B24 +:10D8E0000DE0DBE9006722460120002109F0ECFD94 +:10D8F00006400F403E4301D00AF80490641C68784B +:10D90000A042EEDA0AF1280A08F10100E97880461F +:10D910004145E1DABDE8FE8F2DE9FF5F8B461446F5 +:10D9200091780E9D0AF018F80646A17868680AF00A +:10D9300019F807464FF00009FFF738FB30B12949C5 +:10D94000B5F93200B1F90010884203DD002004B0BF +:10D95000BDE8F09F2448A178E37890F800A01AE091 +:10D960002078627810E000BF16F80080D84509D111 +:10D9700037F91080DDF80CC0E04503DD09F1010C3A +:10D980001FFA8CF9401CC0B28242EDD2491C07EB51 +:10D990004A07C9B228368B42E2D229464846FFF7E9 +:10D9A0001AFB0028D3D0A88C40F40070A884012072 +:10D9B000CDE70000A5051000B85301206106100056 +:10D9C0006206100063061000D0051000DC05100090 +:10D9D000C00510008C061000984510009419012015 +:10D9E00064120120FC0510005A061000017859B19C +:10D9F0008B4A1278521E914206D0407820B1894954 +:10DA00000978491E884201D10120704700207047E3 +:10DA1000017829B1824942780978491E8A4209D1A0 +:10DA2000817829B1C1787F480078401E814201D1B8 +:10DA30000120704700207047F0B57B4D002205EBB8 +:10DA4000C2060023C6E90033521CD2B2172AF6D30D +:10DA50008A782CE000EBC203D3E9007657EA06038C +:10DA600023D074084FEA370317EB070E46EB060C7A +:10DA700044EA0C04344343EA0E0305EBC2063B437D +:10DA8000D6E9007C1F434CEA040CC6E9007CD6E9C9 +:10DA9000027C1F434CEA040CC6E9027CD6E9047CF4 +:10DAA0001F434CEA040CC6E9047C521CD2B2CB786A +:10DAB0009342CFD200225B4B0AE000BF05EBC204C9 +:10DAC00000EBC207D4E90264C7E90064521CD2B279 +:10DAD0001C78A242F2D3087808B1401E0870504A60 +:10DAE00048781278521E904201DA401C48708878BB +:10DAF00008B1401E88701A78C878521E904201DA28 +:10DB0000401CC870F0BD2DE9FF5F9478164604EB09 +:10DB100084028B4600EBC200002100F1290820E0BE +:10DB2000002081468246357877780FE018F8052086 +:10DB30005A4509D12A460120002109F0C5FC41EAD5 +:10DB40000A0A40EA090901216D1CEDB2AF42EDD28B +:10DB5000039B08F1280803EBC403641CC3E9009A83 +:10DB6000E4B2F078A042DBD204B00846BDE8F09FF2 +:10DB700070B50C788B784D78C9789AB10CB1641E69 +:10DB8000E4B2274A1278521E954201DA6D1CEDB2BA +:10DB90000BB15B1EDBB2234A1278521E914201DAAE +:10DBA000491CC9B203EB830200EBC20200262932F2 +:10DBB00009E0204602E01654401CC0B2A842FAD93F +:10DBC0005B1CDBB228328B42F3D970BD2DE9F043E8 +:10DBD0009C7893F803C004EB840500EBC50510485E +:10DBE00090F8009004FB09F001EB40060020293575 +:10DBF00012E019785F7808E015F80180904502D1AD +:10DC000036F911804044491CC9B28F42F4D2641CD9 +:10DC100006EB4906E4B22835A445EAD2BDE8F08314 +:10DC20005A06100059061000404610002DE9F04732 +:10DC300080464A488C780D460078801E012C05D914 +:10DC4000E978814202DA0020BDE8F087022C01D297 +:10DC5000022701E0EF78C4B24FF000092146D8F85E +:10DC6000080009F07FFE06462146D8F8040009F0B6 +:10DC700079FE01463A48027815E028786B780AE088 +:10DC800036F910C031F91080C44502D04FF00109B7 +:10DC900003E0401CC0B28342F2D2641C06EB420691 +:10DCA00001EB4201E4B2BC42E7D94846CCE72DE99A +:10DCB000F04780462A480C464E780178891E8E42ED +:10DCC00001DA0020C0E78146CFB24FF0000AA17808 +:10DCD000D8F8080009F046FE0546A178D8F80400F7 +:10DCE00009F040FEA178E37899F8002013E03C4663 +:10DCF0000AE000BF35F914C030F91480C44502D0E1 +:10DD00004FF0010A02E0641CB442F3D905EB42056E +:10DD100000EB4200491C8B42E9D2504694E70F4A7F +:10DD200000211278521ED3B290F845200AB19A42CF +:10DD300004D1818C41F0020181840121084A90F8CC +:10DD400044301278521ED2B2934204D1818C41F0F9 +:10DD50000401818401210846704700005906100023 +:10DD60005A0610002DE9F05F07460025DFF85CB485 +:10DD70002DE000BFDBF808104E5DDBF8041001EB6E +:10DD8000450A1AE00AEB0600804610F8011C10F85C +:10DD9000029C084600F00FFA0446484600F00BFAD1 +:10DDA000844202D2014620460C46DBF80410761E5F +:10DDB000F6B201F8104008F8024C012EE2D804D166 +:10DDC000284600F0F8F98AF800006D1CEDB2BD425B +:10DDD000D0D300221146DBF804000DE000EB410334 +:10DDE0001C788C4203D11A70521CD2B202E010F897 +:10DDF00014401C70491CC9B2B942EFD3002213462B +:10DE0000114608E010F811409C4202D0521CD2B2D8 +:10DE10002346491CC9B2B942F4D3521CD0B2BDE862 +:10DE2000F09F30B5B0B1884214D002D20A46014604 +:10DE30001046E64A536803EB40031C788C4209D035 +:10DE40005C788C4206D095682A5C022A02D2541C67 +:10DE50002C549954084630BDF0B503EB8204A578E4 +:10DE600005EB850600EBC606E0782836A8420FD3FE +:10DE7000207807E0371897F801C0944500D17970F1 +:10DE8000401CC0B267788742F4D26D1CEDB2EBE75C +:10DE900003EB81002568056003EB420003EB4101C1 +:10DEA00030F8B42FA1F8B420C949096821600021D5 +:10DEB000018093F80E01401E83F80E01F0BD2DE99C +:10DEC000FF4F88460846097887B0FF2915D0C14A18 +:10DED0008A4641781278914201D2491C00E01146ED +:10DEE000CDB2BD4990F80290C0780978884201D23D +:10DEF000401C00E00846C6B204E04FF0000A554658 +:10DF0000D146564609984FF0000B08B198F80EB16B +:10DF1000AE4C206800F15A01C4E901015A2109F010 +:10DF200089FBD4E901122C20002301F810001354BE +:10DF3000401EC0B2F8D20BF101000390C0B20090B5 +:10DF4000079809EB890100EBC10709F1010002976D +:10DF500043E000BF0AF101000197C4B2283738E05E +:10DF60003919086830B3385D30B3CF282FD011F895 +:10DF7000011C002011B1CF2900D008460199095D8C +:10DF800019B1CF2901D0FFF74CFF0A9981B101994E +:10DF90002144059111F8011C19B1CF2901D0FFF7D7 +:10DFA00040FF0599497819B1CF2901D0FFF739FF12 +:10DFB00018B10BE0E41CE4B209E000982D2803D26C +:10DFC000411CC9B2009101E0401EC0B23855641C2A +:10DFD000E4B2AC42C4D90498401CC0B20490B04230 +:10DFE000B8D90098FFF7BEFE009003980022C0B297 +:10DFF000774B09E008EB80011C680C6008EB4001DE +:10E00000401CA1F8B420C0B200998842F2D3029813 +:10E010004F46283001903BE0544632E02044012135 +:10E020000958E9B3417851B3CF2928D0674A5268DB +:10E0300012F81110417008EB410008EB810930F82B +:10E04000B42F521C028099F80010204604F03FF8CB +:10E0500089F8000099F80110204604F03CF889F88E +:10E06000010099F80210384604F031F889F80200EE +:10E0700099F80310384604F02EF889F80300641C60 +:10E08000E4B20198AC42C9D328307F1CFFB20190A2 +:10E09000B742C1D30098401EC2B288F80E2100E0FA +:10E0A0000DE0099800280DD0A2EB0B00012809D142 +:10E0B000099907980BB04346BDE8F04FCCE6E41C45 +:10E0C000E4B2DCE70BB0BDE8F08F2DE9FF4FAFB055 +:10E0D0001C46012080463C9890F80E11414544DBD7 +:10E0E000B821684609F0C8FA3C996B4601EB8800F4 +:10E0F00008F0FF0100682E902EAA3098FFF703FD6C +:10E1000080B32EA96846FFF797FC9DF8BA103198A6 +:10E1100009F030FC82469DF8BA001EE068469DF882 +:10E12000B85000EBC90B10E0DBE900672A4601207C +:10E13000002109F0C9F906400F403E4304D01AF807 +:10E140000500401C0AF805006D1C9DF8B900A842A6 +:10E15000EADA0AF1280A09F101009DF8BB108146AC +:10E160004945DBDA08F10100B4E7A178309809F0FD +:10E1700001FC0546A1782F9809F0FCFB0646A17822 +:10E18000319809F0F7FBA278CF230FE0217806E061 +:10E19000475C022F02D36F5C07B97354491C677840 +:10E1A0008F42F5DA2830521C28352836E178914222 +:10E1B000ECDA33B087E7054AD2E9011202E000BF8A +:10E1C00011F81000135C002BFAD17047D005100035 +:10E1D0004E7901005A06100059061000F0B5B2F948 +:10E1E00000400668B44202DDB3F9001030E002EBF3 +:10E1F000410434F9025CB54204DA03EB410131F920 +:10E20000021C25E000252C464F1E0CE032F914C0FC +:10E21000B44507DC02EB440CBCF902C0B44501DB99 +:10E2200025460C46641CBC42F0DB32F9154003EB7A +:10E23000450133F91530B1F9021002EB4502361BE6 +:10E24000C91AB2F902207143121B91FBF2F1194471 +:10E250000160F0BD2DE9F04105463748036893F8A9 +:10E260000705C40603F20F5021D5B3F8FA696C68AC +:10E27000B4421CDBB3F8FC69B44218DCB3F8FE69A5 +:10E280002C68B44213DBB3F8006AB4420FDC0746D3 +:10E2900093F8040A93F8021A93F8052A07EB400052 +:10E2A00093F8034A00EB410607EB420E10E039B346 +:10E2B00002292CD0032935D004293AD193F8081526 +:10E2C00093F8094593F80E3500EB410600EB430E39 +:10E2D0000A4422440EEB4107A02A2ADC012906DD6C +:10E2E00005F1040C034672466046FFF777FF012CE8 +:10E2F0001FDD284633463A462146BDE8F0416DE72A +:10E3000093F8081593F8094593F80A2505E093F862 +:10E31000081593F8094593F80C2500EB410600EB2E +:10E32000420ED5E793F8081593F8094593F80D25A3 +:10E33000F3E7BDE8F0810000D806100030B5427860 +:10E340000378CD8CD21AC3788078521C1B1A5B1CC0 +:10E3500005FB02F0D4185D4340006A00B0FBF4F006 +:10E36000B2FBF4F2904202D9C8850A8630BDCA8554 +:10E37000088630BD2DE9FF4F002783B01546019771 +:10E3800000973E463C46BB46917809F0E5FA824646 +:10E39000AB7895F8039028E0297895F801C08E466F +:10E3A0001DE000BF1AF801200498824215D1A1EBAC +:10E3B0000E02521CDDF80080A9EB030002FB02886C +:10E3C000401CCDF80080DDF80480164402FB00827A +:10E3D00000FB00BB04447F1C0192491CC9B28C4560 +:10E3E000E0D25B1C0AF1280ADBB29945D4D24FF483 +:10E3F0007A70704390FBF7F14FF47A70604390FBB2 +:10E40000F7F34FF47A7201FB04F0714390FBF2F7DB +:10E4100091FBF2F6634393FBF2F301980099C01B62 +:10E42000891BABEB0302069C8B1A00D55B420028CC +:10E4300000DA404203EB400011440A18081A521057 +:10E4400040104FF47A71484390FBF2F0C0F57A70B7 +:10E45000A085069907B02846BDE8F04F6EE700009A +:10E460002DE9F84F9846DDE90B7A16460B468146B2 +:10E47000FE4AFF48DDF828B012688079B2F9FC52F4 +:10E4800008B1B2F96253FB48007808B1B2F90A53F7 +:10E490005946184609F060FA04465946484609F0BC +:10E4A00069FA81465946DAF8080009F05BFA024633 +:10E4B00098F8000098F801104FF0010A48B9207848 +:10E4C000B04205D1B2F90000B84201DD89F800A0E0 +:10E4D0000120E94B93F800C0ACF1010C614548D133 +:10E4E00014F801C0B44505D132F911C0BC4501DDB5 +:10E4F00009F801A0491EC9B23BE000BF14F800C0F2 +:10E50000B44535D132F910C0BC4531DDAC4402EB25 +:10E51000400B0FFA8CF83BF902CC4FF0000ECDF80F +:10E5200000C0C44505DDBBF902C0C44501DD4FF0A4 +:10E53000010E012809D93BF904CCC44505DDBBF91E +:10E5400002C0C44501DD4FF0010E93F800C0ACF1EC +:10E55000020C604507D2DDF800C0C44503DDBBF9FD +:10E5600004C0C44504DCBEF1000F01D109F800A0CD +:10E57000401C8842C2D9BDE8F88F2DE9FF4FBD4845 +:10E580009BB01D460178B948289F006831B190F8CA +:10E590000943B0F90AA3B0F90C0325E0B44989791D +:10E5A00031B190F86843B0F962A3B0F964031BE09D +:10E5B000B24990F8FB42B0F9FCA20978B0F9FE929A +:10E5C000012912D190F811130C4490F812135145FF +:10E5D00003DAAAEB01010FFA81FA90F81303484518 +:10E5E00003DAA9EB000000B28146ECB3DDE91C01BF +:10E5F000119108A90F910AA90E91A97809F0ACF917 +:10E600000690A978B86809F0ADF986469A4847F6A9 +:10E61000FF73AE7895F803B00078DA430C901AE0F7 +:10E62000297895F801C00DE010F801801198804517 +:10E6300007D13EF91100984200DA0346904200DD0E +:10E640000246491C06988C45EED228300C9906905B +:10E650000EEB410E761CB345E2D20F9803800E9864 +:10E660000280BDF9280000E00FE0BDF92010401A3B +:10E670006043642190FBF1F081490988084400B2AD +:10E68000AC78EE78804624B10EE07D48B0F9000009 +:10E69000F6E7CDE900480DF16C0B02979BE8070007 +:10E6A0002B46FFF7DDFE012476480078401E8642A7 +:10E6B0000BD1CDE900680DF16C0B02979BE80700C8 +:10E6C0002B46FFF7CDFE761EF6B2601EC1B2B868CB +:10E6D00009F048F98346012C06D9A01EC1B2B868DA +:10E6E00009F040F9079001E0CDF81CB02146B86868 +:10E6F00009F038F90D90601CC1B2B86809F032F920 +:10E700000290A01CC1B2B86809F02CF9069021460D +:10E710001C9809F021F90E9021461B9809F02AF95E +:10E720008646002015900120149000201390504838 +:10E730000079C0B14D48006890F8AC19090712D5AE +:10E740006A782978521A90F8B719521C8A420ADC62 +:10E75000EB78AA789A1A521C8A4204DCB0F8B50900 +:10E76000B969814201DD00201490E9E02878CBE00E +:10E770000E990A5C1D998A4276D100211291179157 +:10E7800016910D993BF910C031F9102002EB0A01E6 +:10E7900009B202EB09031BB28C4507DD029F37F972 +:10E7A00010708F4202DD012712971697E8B3324F9F +:10E7B0003F780C977F1EB8427DD00D9F07EB400736 +:10E7C000189737F9027C10978F4207DD189FB7F929 +:10E7D00002708F4202DD0127129717970BEB40075B +:10E7E0001A9737F9027C9F4208DD029F07EB40072A +:10E7F000B7F902709F4201DD012712971A9FB7F9FE +:10E8000002709F4206DD029F07EB400737F9027C4A +:10E810009F4258DC129B43BB012C0ED9079B33F956 +:10E8200010308B4209DD029B00E044E033F91030E8 +:10E830008B4202DD012312931693124B1B789B1E11 +:10E840009C4209D28C4507DD069B33F910308B4280 +:10E8500002DD01231293169301281DD9189B33F969 +:10E86000043C8B4218DD0FE04DE02CE0D806100090 +:10E87000B05110002A0510005A0610008C06100036 +:10E880000206100059061000189BB3F902308B42A3 +:10E8900002DD0123129317930C9B9B1E98420AD210 +:10E8A000109B8B4207DD189BB3F904308B4202DDCD +:10E8B0000121179107E0129929B9424503DD012191 +:10E8C0000EF800101FE0F9490B6893F8F7321B07A8 +:10E8D00004D5424502DDCF230EF80030179A92B1DD +:10E8E000169A82B1149A72B101220EF80020139A7E +:10E8F000521C92B21392096891F8B82913998A426E +:10E9000001D201211591401C69788142BFF430AFDA +:10E91000E748CDF81CB00D9900780EF1280E01EBF8 +:10E9200040010D9102990BEB400B01EB400102916C +:10E93000069901EB400006900E982830641C0E905A +:10E94000B4427FF613AF15981FB0BDE8F08F2DE9E4 +:10E95000F0470446914260D007D901EB0200A0EBDA +:10E960000201CAB2A0EB0200C1B2C1EBC10000EBD0 +:10E97000400004EB8001C2EBC20000EB400004EB5E +:10E980008000B1F93250B0F9323081469D4200DA50 +:10E990004B86CB8CC58C2B44CB840B8D058D2B44A7 +:10E9A0000B854B8D458D2B444B858B6985692B449D +:10E9B0008B61C769CE69CB68D9F80C004FEA234C4C +:10E9C0004FEA20480CFB06FCF51907FB08CC9CFB22 +:10E9D000F5FC6CF31F430FFA83FC0CFB06FC00B242 +:10E9E00007FB00C090FBF5F060F30F03CD61CB6037 +:10E9F00094F8EC04411E91420AD0C0EBC00000EB39 +:10EA0000400004EB800148465422543908F0D8FDF8 +:10EA100094F8EC04401E84F8EC04BDE8F0872DE97E +:10EA2000FE4F0746A1488A4600250068B0F800134B +:10EA300001FB01F99F49897919B1B0F8660300FB20 +:10EA400000F954464FF0010BA3E000BF0BFA04F0AD +:10EA5000264600906BE0009A0BFA06F059461042E9 +:10EA600064D0C6EBC60000EB400007EB8000C26834 +:10EA700020464EE0B0424BD0C0EBC00303EB430353 +:10EA800007EB8303DB684FEA234CACEB224C9B1A69 +:10EA90000FFA8CFC1BB26CF31F4563F30F059E4607 +:10EAA000824BCDF804C01B6893F8F6C2CDF808C0BD +:10EAB0005FEA8C6C0AD593F803830EFB08FC4FF0D9 +:10EAC00064089CFBF8FCF4446CF30F05DDF808C007 +:10EAD0005FEACC6C0CD593F80333DDF804C00CFB73 +:10EAE00003FC64239CFBF3FC019B634463F31F451D +:10EAF0004FEA254C0CFB0CFC2BB203FB03C34B452C +:10EB000006D2DDF800C001FA00F343EA0C030093DB +:10EB1000401C97F8EC348342ACD80421684607F0D7 +:10EB20009DFA012802D1009840000090761C97F8C9 +:10EB3000EC04B0428FD80421684607F08FFA012810 +:10EB40000BD00421684607F089FA97F8EC64A6EB2D +:10EB50000A01884206D187F8ECA4BDE8FE8F641C48 +:10EB6000E4B201E0009A584600FA04F11142F6D0EE +:10EB7000D84609E0009908FA06F0084204D0F2B23B +:10EB800021463846FFF7E3FE761EA642F2D8641C03 +:10EB9000E4B297F8EC04A0423FF658AFDDE72DE968 +:10EBA000F04F424C012B246894F80F7394F80E63D5 +:10EBB00005D00B784C78404D9C46690C0CE08B7866 +:10EBC000CC78F8E730F91C80A84500DD454688453B +:10EBD00000DA41460CF1010CA445F3D9B54200DA44 +:10EBE0003546B14200DA3146691A7943642591FB12 +:10EBF000F5F131440EB230F913500121B54205DD73 +:10EC0000156801FA03FC45EA0C05156030F914504B +:10EC1000B54205DD156801FA04FC45EA0C051560EE +:10EC2000E51A05F0FF09B9F1010F37D95D1CEDB206 +:10EC300030F9158008EB070C0FFA8CFCB04511DD9C +:10EC400000EB450A3AF9028CE04503DDBAF902808F +:10EC5000E04507DCD2F800C001FA05F54CEA050CE6 +:10EC6000C2F800C0651EEDB230F9158008EB070C44 +:10EC70000FFA8CFCB04511DD00EB450A3AF9028C25 +:10EC8000E04503DDBAF90280E04507DCD2F800C0B8 +:10EC900001FA05F54CEA050CC2F800C0B9F1020F03 +:10ECA00036D99D1CA4F1020930E00000D8061000FE +:10ECB0005A061000B05110000080FFFF30F915C057 +:10ECC000B44522DD00EB450BBC443BF902EC0FFAE6 +:10ECD0008CFAD64503DDBBF90280D04515DC3BF943 +:10ECE000048CD04503DDBBF90280D0450DDCD64550 +:10ECF00003DDBBF90480D04507DCD2F800C001FA7F +:10ED000005F84CEA080CC2F800C06D1C4D45D5D979 +:10ED1000002528460CE000BF166801FA03F73E42C2 +:10ED200004D025B90125401CC0B200E000255B1CC1 +:10ED3000A342F1D909E62DE9FF4FFB488FB0DFF878 +:10ED4000EC9304684FF0FF300C90002017460A90B7 +:10ED50000B901D4604F5887B012239464E46D9F8B2 +:10ED60000000FEF705FF0095DDE90F123B46306815 +:10ED7000FFF703FC060006D0ED4901200870A88CBF +:10ED800040F08000A884EB48007880B17EB995F807 +:10ED9000240010F0060F0AD139462846FEF746FF38 +:10EDA000060004D139462846FEF781FF0646E248B0 +:10EDB000007800B10126DFF884A3DAF8000090F8AB +:10EDC000F70240073DD501230AAA3946DC48FFF780 +:10EDD000E6FE804600230BAA3946DA48FFF7DFFE3D +:10EDE00008FB00F001282CD1DAF80000B5F9321048 +:10EDF000B0F8F402814224DAB8781EE008F0FF018E +:10EE00000F9808F0B7FD049008F0FF01D9F8000052 +:10EE100008F0B0FD01463878012209E0049BDDF8D6 +:10EE200040C01B5C634502D10B5C03B90A54401C13 +:10EE30007B788342F2DA08F10100F9788046414597 +:10EE4000DCDA002084F80E0138682060B7483346C9 +:10EE5000002221460068FFF732F894F80E014FF0C7 +:10EE60000008012870D9B548006890F8F70200073B +:10EE70000CD54FF46671B44808F0FEFBAB48009423 +:10EE80003B460168B04A0846FFF71FF9FCF78DF9C9 +:10EE90000090FCF788F982463A68DDE90F01079295 +:10EEA000AA4B07AAFEF72FFE60B107A9A748FEF7F5 +:10EEB000C3FD2A4607A9A548FDF7B4FAE9686961C8 +:10EEC000E96929629C480078E8B39C48006890F89A +:10EED000F702800747D594F80E01012843D94FF077 +:10EEE0000009012610E000BF904804EB8603F2B24F +:10EEF000A9680068FEF76AFE93493C39484541F825 +:10EF0000260000DD8146761C94F80E11B142EBD24A +:10EF1000B9F1000F20DD894A01208B4B86463C3B2E +:10EF2000126817E053F820604FF0640C06FB0CF6F3 +:10EF300096FBF9F692F808C3B4450ADD0EFA00F61E +:10EF4000DDF830C001E00EE0C4E02CEA060CCDF89C +:10EF500030C0401C8142E5D294F80E01012802D94C +:10EF6000002084F80E017A487B4A0126B0F900108F +:10EF700078480591DFF8C491B0F90000089011803D +:10EF8000764908806EE054222946584608F018FB5E +:10EF9000D9F8001004EB4600B0F8B43091F8022321 +:10EFA00093425ED901220C9BB2401A4259D0BBF861 +:10EFB000242042F01003ABF82430B0F8B420ABF8B2 +:10EFC000262091F8F702000703D558480168CBF8CE +:10EFD000001004EB8600099059460790FFF7AEF940 +:10EFE0005248F1B25B46079A0068FDF788FE9BF82D +:10EFF000440060B15A490978491E884207D09BF8FD +:10F00000450020B157490978491E88420FD1BBF805 +:10F01000240040F001015846ABF82410FEF77FFEB3 +:10F0200028B151484C49008808804C4908804B4819 +:10F03000BBF93210B0F9000081420CDD3B48F1B25F +:10F040005B46099A0068FDF79FFD012803D108F18E +:10F05000010000F0FF084049059808803F490898E2 +:10F060000880761C94F80E01B0428CD2D9F80000CA +:10F070004C4690F8F60200070DD5B8F1010F0AD9F9 +:10F0800050460099FFF7CBFCFCF78FF8014600983B +:10F09000081A00F0FF08216891F8F602000613D55F +:10F0A00040460FE0009A0244D2B2C2EBC20202EB29 +:10F0B00042030AEB830291F81F33D28C9A4201D9A2 +:10F0C000009817E0401EEDD2B8F1010F0AD0B8F158 +:10F0D000000F05D1DDE90F012B463A46FDF754FD3F +:10F0E00013B032E4144800780028F9D19AF8EC04FF +:10F0F00000B1401E8AF8EC04ECE7F0B414681C641C +:10F100000E4C246894F8F6526E0737D56D0609D573 +:10F11000164D6D7875B3B4F80643154D64432D68EC +:10F12000A5422BDCF0BC06E6DC051000C40510008F +:10F13000A5051000180610002A051000D8061000BA +:10F14000F80A0120220B01203447100098451000D6 +:10F15000120610001006100004061000020610002F +:10F160005A0610005906100016061000100710006D +:10F1700090061000FFE7B4F80443CEE7F0BCFDF7BB +:10F1800003BD00007047F0B51446059F0BE000BFBB +:10F1900031F9145030F9146005EB030CB44519DB58 +:10F1A000ED1BB54216DC641EF2D13D4B1B6893F893 +:10F1B00045301B09C3F110040AE000BF31F91250B9 +:10F1C00030F912605D4306FB04552D1121F81250F1 +:10F1D000521EF3D2F0BD38B50D46044601F020F8BA +:10F1E000002821D1E80704D02E492068096800F0E2 +:10F1F0001CF8E80618D52A4D2868B0F9501000917F +:10F200002949B0F94E3020690A782849FFF7BBFF39 +:10F210002868B0F9541000912549B0F9523060695E +:10F220000A782449FFF7AFFF38BD2DE9F043814646 +:10F23000214803781A48052B006890F844200CD028 +:10F2400030F9465F02F00F03B0F902601B48C3F1CA +:10F250001004B0F90000024611E030F94A5F1309CA +:10F26000B0F90260F2E700BF31F9127039F912C04B +:10F2700007EB0508E04511DBBF1B67450EDC521E9E +:10F28000F2D209E031F9102039F910505A4305FB48 +:10F290000422121121F81020401EF3D2BDE8F083A1 +:10F2A000D80610008806100059061000286D0120AD +:10F2B0005A061000526D0120580610006A06100010 +:10F2C0002DE9FC478146A248A24E88460178306865 +:10F2D000012511B9A049097811B1B0F9A1420DE099 +:10F2E0009E49B0F99B424978012902D0022903D0F6 +:10F2F00004E0B0F99D4201E0B0F99F42022101A86B +:10F3000000F0D2FA964F42464946B7F900300198CC +:10F3100003F0B1FE306890F8A4120A0705D4C906BC +:10F3200003D490F8A502C00708D0B7F900000199EE +:10F33000009080238B4A084603F0B4FE306890F8B2 +:10F34000A502800609D588480199894A007800906D +:10F35000864803780846F6F7CCFDB7F90010019A05 +:10F360000DE000BF32F91100002801DB034600E088 +:10F370004342A34203DD7F490025088001E0491E86 +:10F38000F0D2022101A800F0F2FA2846BDE8FC877D +:10F390007048006890F89002400707D56F4876499A +:10F3A000C0780978884201D001207047002070475A +:10F3B000684810B5006890F89012890727D56F4902 +:10F3C0000A78521CD2B20A7090F8923293421ED23E +:10F3D00000220A7090F850120324C90703D190F854 +:10F3E0008002C00700D00B24F1F708F864480168D8 +:10F3F00021430160F1F700F81021052002F056FAD0 +:10F40000BDE810404FF48071002006F024B810BD14 +:10F410004F49514A514809781278437811430B43B8 +:10F4200056494FF0000208D14B785B1CDBB24B70A1 +:10F43000052B03D90123437083704A7070472DE96F +:10F44000F34F50480027DFF818A190F8008041489A +:10F4500081B03C460068B94690F89002C0071AD0C7 +:10F4600000264FF0010B019D12E028460299FFF79C +:10F4700027FF10F0010F05D00BFA06F03843641C8B +:10F48000C7B2E4B2BAF90000761C05EB400536B20B +:10F490004645EADB01E04446FF273B4807704CB194 +:10F4A0000094BAF800003B4682B24146019800F051 +:10F4B00011F807E02F48B0F90010032002F0F6F928 +:10F4C0004FF001094846BDE8FE8F2C48002101702D +:10F4D000417070472DE9F003069F002F1AD00125D7 +:10F4E000012F02D01446A9462FE0002410E000BFEF +:10F4F00005FA04F61E420AD0002C0BD053006243DA +:10F50000BDE8F00300EB42011A4608F014B8641C91 +:10F510008C42EDDBBDE8F003704700BF002600EB36 +:10F52000440C35460BE000BF09FA05F818EA030F52 +:10F5300002D0BCF9008046440CEB420C6D1C8D429D +:10F54000F2DB96FBF7F520F81450641EE6D2E1E7F3 +:10F5500020051000D80610002A0510001007100022 +:10F560006A061000F60B01205A061000590610001A +:10F57000EE0B0120E80510005B061000E00510000E +:10F58000E80610005C061000E505100010B5F5F760 +:10F590004FFDF6F708FCBDE81040F5F755B92DE929 +:10F5A000FF5F9A4693460D460320DDF8388005F04C +:10F5B000F2FF8B4801680098FFF741FF04460320E3 +:10F5C00006F004F84CB1FFF723FFFFF7F1FE854882 +:10F5D000047004B02046BDE8F09FFFF776FF15B138 +:10F5E000284600F02BFCDFF8009200257F4F804E6C +:10F5F000B8F1000F0ED07F4801784046F5F73FFD87 +:10F60000B87838B1D9F8000090F82802C00701D1C5 +:10F610003570757008F054F98046FFF7B9FE40EA7E +:10F620000804D9F8000090F84003C0070BD07248D6 +:10F63000007840B90120F070B87808B9787810B136 +:10F640006E48F5700570002CC1D15246594600989D +:10F6500000F038F80446BAE710B500F081F8002051 +:10F6600010BD10B5F7F7F9F9FEF700F9FBF760FCEC +:10F67000FFF78CFFFFF729FFFCF7C3FC5949002077 +:10F6800008704870488088808860C86008611431BC +:10F69000087088705448006810F8302F4A7040781D +:10F6A000C87010BD10B5F7F7E0F9FEF7F3F8FBF7F7 +:10F6B0003DFC00F059FCF6F783FB4C4800214170FB +:10F6C000817010BD2DE9F8430024804616460F4690 +:10F6D00025468DF80040022005F05DFF3246394690 +:10F6E0004046F7F755F846490128CA7860F3030207 +:10F6F000CA7029D002282ED0042800D001246B46DD +:10F70000324639464046FCF74CFB40EA04050220ED +:10F7100005F05CFF9DF8000098B1F0F76FFE3948E6 +:10F72000394A0168126811430160F0F765FE3748F5 +:10F730000178052002F0BAF84FF48071002005F03E +:10F740008AFE2846BDE8F88331480570FEF781F847 +:10F75000FBF70FFCD3E7FDF7E1FCFBF730FCCEE74E +:10F7600038B5044600208DF80000022005F013FF94 +:10F770002046F7F7D9F822490128CA7860F3030236 +:10F78000CA7002D0022805D008E0FEF76EF8FBF739 +:10F7900059FC03E0FDF7FAFEFBF765FC69462046DD +:10F7A000FCF7E0FB0446022005F010FF9DF8000086 +:10F7B00098B1F0F723FE1348134A01681268114309 +:10F7C0000160F0F719FE11480178052002F06EF88B +:10F7D0004FF48071002005F03EFE204638BD000049 +:10F7E00088061000E4051000D8061000100710006D +:10F7F000B051100014071000A4061000630610009A +:10F80000B8530120E80610009C0510009805100070 +:10F810001C071000062904D28B4A515C8B4A535CAA +:10F820002BB1002101600146482001F00EBD864B3E +:10F83000083353F821300360854B43F82100012041 +:10F84000505470470A4630B40021062A11D27E4B2C +:10F850009A5C72B17C4C0368083454F82240A3428D +:10F8600007D17A4B99547A4B43F82210016030BC8F +:10F8700070470160014630BC492001F0E6BC2DE92B +:10F88000F0410124714D724F0026285D38B12E558C +:10F8900057F824104A2001F0D8FC47F82460641C73 +:10F8A000032CF2DBBDE8F0812DE9F041684D674B98 +:10F8B00000270A460C350760596805F1140603F164 +:10F8C0000804012A38D0022A1CD0032A3FD1002282 +:10F8D00004EB020CDCF800E0BEF1000F07D0521C74 +:10F8E000022AF5DB042930D301464C2031E055F8DB +:10F8F0002240046046F822004FF00330091FCCF884 +:10F90000000032E05FF0000204EB020CBCF800E003 +:10F91000BEF1000F05D0521C042AF5DB0229E3D208 +:10F9200013E055F82240046046F8220040F202201D +:10F93000ACF80000891E18E05FF0040214F802C061 +:10F94000BCF1000F09D0521EF8D2002FAAD10146F7 +:10F950004B20BDE8F04101F078BC55F8225005601D +:10F9600046F822000120A054491E59609AE7F0B4DD +:10F97000374E364C002504220C36D0F800300834BF +:10F9800056F822709F4212D1A75C8F420FD1531CB0 +:10F9900011D02F4D00232035036045F82230A354A9 +:10F9A000012911D0022911D0032904D108E0521EE7 +:10F9B000E6D2002D08D1F0BC01464D2001F045BC37 +:10F9C000A01843708370C370F0BC7047A0184370D8 +:10F9D000FAE770B51D4E1E4D0524083620350BE0A4 +:10F9E000305D48B155F824104E2001F02EFC315DF9 +:10F9F00055F82400FFF7BBFF641EF1D270BD70B54F +:10FA00000120134B114A002143F820101154401CCF +:10FA10000328F9DB012010700C4A05200C4B5060C4 +:10FA20000C330A4C04200B4A083403F114057326E6 +:10FA3000464302EBC60643F82060215445F82010E7 +:10FA4000401EF4D270BD000054790100240610005D +:10FA50007C51100078641000F0B5A7B00D46064642 +:10FA600000249821684607F007FEFF4A00216846F7 +:10FA7000137810E001FB03F7224609E007EB020EC2 +:10FA800050F822C036F91EE0F44440F822C0521C5F +:10FA90009A42F3DB491CA942ECDB214607E000BF98 +:10FAA00050F8212092FBF5F240F82120491C9942A0 +:10FAB000F6DB002117E000273A460CE002FB034C7E +:10FAC00050F824E036F91CC0BCEB0E0C01D5CCF18B +:10FAD000000C6744521CAA42F0DB97FBF5F28A4205 +:10FAE00000DD1146641C9C42E5DBB1F5803F03DB81 +:10FAF0004FF6FF7027B0F0BD88B2FBE7F0B5DB49E9 +:10FB0000DB4B096891F8A422D20734D0D94A577840 +:10FB10004FB191F8BB42B1F8B85204F00F02260978 +:10FB2000B1F8B64208E091F8BA42B1F8B45204F024 +:10FB30000F022609B1F8B242DFF83CC39CF800C0BE +:10FB4000BCF1030F06D191F8BC120FB10A0901E014 +:10FB500001F00F02A04201DC1A60F0BDA84201DBF7 +:10FB60001E60F0BD001BB11A4843291B90FBF1F049 +:10FB700010441860F0BD0020FBE7BC48BD49006898 +:10FB80000A7800F5F970805CC87070472DE9F00FB5 +:10FB9000DFF8E0A28346B5489AF8007089466FF016 +:10FBA000004231F817500168002091F80A6291F87C +:10FBB00009124FEA11180B071FD001F00F0CAB4CC4 +:10FBC00000210B462468B54294F8084205DBAE1BC1 +:10FBD00006FB08F696FBFCF63444A44E9AF801C0E6 +:10FBE000D0463668BCF1010F96F8F16108D0BCF13F +:10FBF000020F08D006F0030C12E04FF0010CDEE714 +:10FC0000C6F3810C0CE0C6F3011C09E039F813605F +:10FC1000B24201DD32461846B14200DA31465B1C81 +:10FC20006345F3DDABF80010A91AA14201DC67457A +:10FC300004DD88F80000BDE8F00F9EE7BDE8F00F96 +:10FC400070478E4910B50B7888490022012B09684E +:10FC500002D18B4B1B784BB1B1F8FC31834218D2E7 +:10FC600091F8F0311B0714D5032225E0B1F80232D8 +:10FC7000834203D291F8F0311B07F5D4B1F800327A +:10FC8000834203D291F8F0315B070AD4B1F8FE3118 +:10FC90000BE0B1F8FA31834205D291F8F0315B07FD +:10FCA00001D5022208E0B1F8F831834204D291F87C +:10FCB000F001800700D5012272486E4C03789A4209 +:10FCC00011D1617899421AD06F4A1278134307D044 +:10FCD0008168491E8160002911DC007860700EE0A7 +:10FCE00001708168F7E78AB1022A01D1012B0DD09A +:10FCF00091F8F61181600270002900DC627063489F +:10FD00006278417B62F30301417310BD91F8F711F2 +:10FD1000F0E7564A126892F8F021D20607D5421A47 +:10FD2000002A04DCC1EBC1110844C0F3CF107047B6 +:10FD3000504900204D4A4870524948608860087018 +:10FD4000126892F8A432DB0703D092F8BB221209A2 +:10FD500000E00022464B1A60C86008614861886173 +:10FD6000C861086270472DE9F05F8B463E49DFF8B5 +:10FD700014914FF0100A0E7805463701002409F15E +:10FD80000C09DFF8008114E0324651462846FFF79F +:10FD900063FE29F81400BBF1010F10D0394B143366 +:10FDA00033F81410FFF7B5FF23F8140005EB4705EF +:10FDB000641C98F801008442E6DDBDE8F09F314BF9 +:10FDC0001C33EDE738B5294C0020ADF80000206861 +:10FDD0004FF0000190F8F00180062D4808D5FFF79C +:10FDE000C2FF01212B48FFF7BEFF26491C3103E06B +:10FDF000FFF7B9FF234914316846FFF7C7FE2068B3 +:10FE00001C4D90F8F001400602D5BDF8004004E01A +:10FE10001C492878143131F810401F4804802046CE +:10FE2000FFF70FFF2046FFF769FE164928780C31CF +:10FE300031F810001549A1F81B0038BD2DE9F14F2C +:10FE400084B0002002900848102605780D484FEA3B +:10FE50000518406890FBF6F106FB11000C49684359 +:10FE600001EB400A8B4619E05A061000D806100034 +:10FE70000C06100010071000580610006106100054 +:10FE8000620610003406100060061000B85301200E +:10FE9000D4190120D42C0120E60510004049049C0F +:10FEA000096891F8F011890615D50BF5985101EB09 +:10FEB00040093C48477868007F1C009008E02146D4 +:10FEC0004846009A07F037FB04EB450409EB480964 +:10FED0007F1EF4D2049CDFF8CC9099F801707F1C4F +:10FEE00024E02F48006890F8F011890615D5D9F85C +:10FEF000041000290FDD02996A1AB0F90612CDE943 +:10FF00000012B0F9043202980BEB400204EB4001FE +:10FF1000084603F037F80BEB480B6A0021465046C1 +:10FF200007F009FB04EB45040AEB480A7F1ED8D210 +:10FF3000D9F804104FF0FF32491C02EB4602484644 +:10FF4000C9F804108A4200DA4660D9F80400B042C9 +:10FF500006DB05B01449BDE8F04FA1F5985031E734 +:10FF600005B0BDE8F08FE3E610B50D4C206890F8C1 +:10FF7000F101C0F30112C0F3810100F0030002F0AF +:10FF80009FF8084948702068084990F8EB0000F095 +:10FF900003000870FFF7F1FDBDE81040C8E600005F +:10FFA000D806100034061000D42C012010071000D1 +:10FFB00010B5F948F949002484610C604C600C725A +:10FFC0000462C461FFF76EFBFFF719FDF44804807B +:10FFD000BDE8104000F056B9F0B5F249EE48F44FD4 +:10FFE00091F83020427091F8313083705A4316B244 +:10FFF000468291F83340C47011F82C2F02704A7871 +:020000021000EC +:1000000002718A784271C9788171E749416201F2CF +:100010003C618162A1F67841C162E4490B6893F8C2 +:10002000F01109061AD503F5F97593F8F13100229C +:1000300003F0030311465B1C08E000BF15F801C084 +:10004000A44501D10A4603E0491CC9B28B42F5D848 +:10005000C271724307EB42010163F0BD0763F0BD5B +:10006000D04890F82C10CE488170CB4902790B7A99 +:1000700063F300028B7A63F3C3024B7A63F3820269 +:10008000CB7A63F341020B7B63F34512C94BDB78F8 +:1000900003728B7BC3714B7B63F304120271CB7BC6 +:1000A000827B097C63F3030261F30712C249827306 +:1000B000097880F82810C1490988A0F82910C0499A +:1000C0000A7890F85B1062F3410180F85B10BD493B +:1000D0000A78C17B62F30301C173BB490A78017CD2 +:1000E00062F30001B94A127862F34101B84A12780A +:1000F00062F3C301B74A21F00401127880F87E2030 +:100100000174B5490A88A0F84020B44A13880387CF +:100110004B88A0F84230538843878B88A0F844303E +:1001200093888387C988A0F84610D188C1879B49E6 +:100130008A7980F87B20097A80F87D10A8490978AF +:1001400080F87C10704770B50D4680EA0506F00611 +:1001500001D5F5F728FE914CC5F300102070B006CC +:1001600001D5F4F771FBC5F34010607015F048003D +:1001700000D00120A0718D48006890F8AC0900F013 +:1001800001002071C5F30020E071C5F3402020720A +:10019000C5F34000E07070BD2DE9F0417E4E814C0A +:1001A000D6E907100843D4E9081241EA020180EABF +:1001B000010503D111B1FFF7FBFE11E0E8070BD0F9 +:1001C000884F387820B107F0A1FB08B900203870BB +:1001D000FFF747FAFFF7C7FEE80601D5FFF7D6F9A4 +:1001E000E169B069FFF7AFFFE069B061206A306292 +:1001F000606AF061BDE8F041EEE670B57A4D2C68BA +:10020000002C0CD00022A0B2114601F083F928681E +:10021000A043286003D1BDE8704001F0EDB970BD86 +:100220005D48417A012908D0817A012905D0C17A37 +:10023000012902D0807B002800D00120704708B53A +:10024000FFF7B6FE6B4600220B21022005F04CF9A9 +:100250000098C00705D00121022005F028F900F020 +:100260003AF80098800705D50221084605F01FF9E5 +:1002700000F064F800980007E4D50821022005F09A +:1002800016F9DFE710B5494C4348226892F831105F +:10029000417092F830208270514341824549C978BB +:1002A000C170012101714171817101700021818250 +:1002B000C1730174FFF7D5F920684C4A90F83814DF +:1002C00001F0010111704A49B0F876000880BDE8DC +:1002D0001040FEF757BF38B5002400F08FFF012013 +:1002E00005F059F9FFF758FF2B4D95F82000297FAD +:1002F0000843C00708D02B48C1680091D0E9042307 +:1003000003C8FFF74CF90446E86950B14CB9032023 +:1003100005F041F92348E969FEF75DFF032005F088 +:1003200055F9FFF79DFEFFF768FFFFF752FBFFF758 +:10033000A6FABDE83840012005F048B970B50024A0 +:1003400000F05CFF012005F026F9FFF725FF124DB4 +:1003500095F82000C00704D012480068FFF77CF928 +:100360000446E86950B14CB9032005F014F90D4872 +:10037000E969FEF730FF032005F028F9FFF770FE6A +:10038000FFF73BFFFFF725FBFFF779FABDE8704069 +:10039000012005F01BB9000058061000B0511000F4 +:1003A000B85301207076100010460120D8061000C6 +:1003B0003854012010071000E5051000E805100072 +:1003C000180610000E0510000C0510002005100086 +:1003D00026051000210510004806100050061000E8 +:1003E000A40610001B0710000007100016071000DD +:1003F000180710000D4D00200D4C28602868401C87 +:100400002860EFF7FBFF06F0C2FF0128206809D043 +:1004100040F00400206005F0E2FD00BFEFF7ECFFC4 +:1004200030BFEBE720F004002060F7E7A0061000E3 +:1004300010ED00E070B5134C25462021114807F05F +:10044000F9F8104800F0B4FC2B78421E691C1846DD +:1004500000F03CF918B10120216801F027FA00F002 +:10046000C1FC0028E9D170BD38B50C46054604F042 +:10047000F2FF6946284605F028F800992142F8D194 +:1004800038BD0000B95110000020704770B500233E +:1004900000290EDD0278491E0A2A0AD2844D401C2A +:1004A00055F8324005EBC2025268914201D1A04793 +:1004B0000346184670BD017811B97E49407808801E +:1004C0000120704710B5017821B1022906D0032917 +:1004D0000BD106E04078FAF711FC06E040780121E4 +:1004E00001E040780021FAF7EFFB012010BD0CB5C8 +:1004F000016800918188ADF8041080798DF80600BC +:100500009DF8000000B39DF80100102803D29DF86B +:10051000020010280CD30020674900900190096860 +:100520006A4691F8951A1318401CD9700428FADB12 +:100530006248009940F8071FBDF8041081809DF8BB +:100540000610817101200CBD5C49C91D0870002096 +:100550000CBD1CB5016800918188ADF8041081794B +:100560009DF800008DF80610E8B353489DF802206E +:100570000068642A01D9642202E01AB990F81A23AB +:100580008DF802209DF8033090F8CA29934200D8D4 +:100590000BB98DF803209DF804309DF80520934297 +:1005A00002D80AB10F2B08D990F8BB2302F00F0331 +:1005B0008DF8043012098DF80520022900D821B9E0 +:1005C00090F8BE0300098DF806003C4800990160D0 +:1005D000BDF8041081809DF80610817138490868C3 +:1005E000820708D500E008E020F00200086008213A +:1005F0000120FFF739FF01201CBD304908700020A1 +:100600001CBD10B502782E48016812B141F00801F6 +:1006100001E021F00801016008210120FFF724FF1B +:10062000012010BD10B502782548016812B141F4CF +:10063000007101E021F40071016008210120FFF741 +:1006400013FF012010BD1C4910B5096891F8931AD9 +:1006500049070AD50078C2071948016802D041F459 +:10066000807101E021F48071016008210120FFF711 +:10067000FBFE012010BD70B51249134A03780968CA +:100680004FF00004CE010C494FF00105096802D576 +:100690004BB1032301E033B102231370407881F89A +:1006A0001A0A012070BD157081F81A4AF9E7000096 +:1006B0006879010018071000D8061000A406100081 +:1006C00008071000480510003105100010B50C4651 +:1006D0000023A0F1A001092903D8F84850F82130DF +:1006E00008E0C0280AD1F549A0F1C000A1F1040139 +:1006F00051F820301146204698470346184610BD51 +:100700000020704770B5EE4C00230029236011DDF6 +:100710000278491E042A0DD2E84D401C283555F8B0 +:10072000324005EBC2025268002A03DB914201D13C +:10073000A0470346184670BD10B500F0EBFB012042 +:1007400010BD70B500240078DE4D8106264607D521 +:1007500001242C7000F0F0FB30B900F0DBFB03E06B +:10076000C00701D001242E70D74804210460012065 +:10077000FFF77AFE2E70012070BD10B51021012008 +:10078000FFF772FED04900200860012010BD10B5AF +:100790000146002409782046032918D005DC59B108 +:1007A00001290CD002291AD10EE0042911D01029F8 +:1007B00012D0112913D111E00124002001E00224FC +:1007C000012000F077FA0AE004240220F9E720244F +:1007D00000E04024012002E0082400E01024B84991 +:1007E00014F0180F0C60B84C06D010210120FFF750 +:1007F0003BFE0020206007E02168814204D0206099 +:1008000004210120FFF730FE012010BD70B5002348 +:1008100000290FDD0278491E052A0BD2A74D401C86 +:10082000483555F8324005EBC2025268914201D179 +:10083000A0470346184670BD10B50078C207A3480C +:10084000016802D041F0020101E021F002010160E3 +:1008500008210120FFF708FE012010BD10B5007827 +:10086000C2079A48016802D041F0040101E021F07A +:100870000401016008210120FFF7F6FD012010BDF1 +:1008800010B50178CB0791490A6802D042F00802FE +:1008900001E022F008020A600078800702D542F0E9 +:1008A000400001E022F04000086008210120FFF72D +:1008B000DBFD012010BD10B5002103780A469C061F +:1008C00001D5202100229C0701D541F002015C07DF +:1008D00001D541F004011C0701D541F00801DC06F7 +:1008E00001D541F010015C0601D541F040011B0625 +:1008F00001D541F080014378DC0701D041F48071DB +:100900009C0701D541F400715C0701D541F4806179 +:100910001C0701D541F40061DC0601D541F480518A +:100920009C0601D541F400515C0601D541F480419B +:100930001B0601D541F400418378DC0701D041F466 +:1009400080319C0701D541F400315C0701D541F4A9 +:1009500080211C0701D541F40021DC0601D541F4BA +:1009600080119C0601D541F400115C0601D541F4CB +:1009700080011B0601D541F40001C078C00701D0F9 +:1009800041F080715248C0E90012012010BD00788A +:1009900000B101204F4908700120704770B5002355 +:1009A00000290FDD0278491E0B2A0BD2434D401C53 +:1009B000703555F8324005EBC2025268914201D1C0 +:1009C000A0470346184670BD014600200978052956 +:1009D00006D23A48C83050F8212000210846104776 +:1009E000704710B505F0B7FA012010BD10B54FF4EF +:1009F00000610020FFF738FD012010BD10B54FF455 +:100A000080510020FFF730FD012010BD10B54FF4DC +:100A100000010020FFF728FD012010BD10B500786F +:100A2000C00702D000F005FA01E000F0F9F901205A +:100A300010BD10B500880024C10700D00224810732 +:100A400001D544F00404400701D544F0080494B1F2 +:100A5000EFF7D4FC2048016821430160EFF7CCFC9C +:100A60000221052000F022FF4FF480710020FFF7E3 +:100A7000FBFC012010BD002010BD10B50088002433 +:100A8000C10700D00124810701D544F002044107C9 +:100A900001D544F00404000701D544F00804FCB17A +:100AA000EFF7ACFC0D48016821430160EFF7A4FCAF +:100AB00002210020FFF7D8FC012010BDBC79010005 +:100AC0000C0710001A071000040710000807100098 +:100AD0004805100016071000E8061000EC0610008C +:100AE0000020EAE710B500880024C10700D00124E7 +:100AF000810701D544F00204410701D544F0040404 +:100B0000000701D544F0080474B1EFF777FC6E4894 +:100B1000016821430160EFF76FFC4FF400110020E2 +:100B2000FFF7A2FC0120C8E70020C6E710B5008847 +:100B30000024C10700D00124810701D544F002043C +:100B4000410701D544F00404010701D544F008042D +:100B5000C10601D544F01004810601D544F02004FB +:100B6000410601D544F04004010601D544F080045B +:100B7000C10501D544F48074810501D544F40074A5 +:100B8000400501D544F480646CB1EFF737FC4F4861 +:100B9000016821430160EFF72FFC80210020FFF75F +:100BA00063FC012089E7002087E710B50088002456 +:100BB000C10700D00124800701D544F0020474B1BC +:100BC000EFF71CFC4248016821430160EFF714FC79 +:100BD0004FF480010020FFF747FC01206DE7002063 +:100BE0006BE710B500780024C10700D0012481070D +:100BF00001D544F00204400701D544F0040474B167 +:100C0000EFF7FCFB3348016821430160EFF7F4FB89 +:100C10004FF480610020FFF727FC01204DE7002002 +:100C20004BE710B50078002451283DD018DC30285F +:100C300036D00CDC11282FD004DC012829D0102854 +:100C400030D129E0122827D013282BD124E03128D5 +:100C500026D0322824D0332822D0502822D123E095 +:100C6000732824D00CDC702821D004DC52281BD03F +:100C7000532817D118E0712819D0722812D116E024 +:100C8000742814D0752812D0762810D0772809D16E +:100C90000DE000F05AFB01E000F0F0FB012401E060 +:100CA00000F00CFC204608E700F0F6FBF6E700F049 +:100CB000E4FCF3E7002118B1012801D0022800D19B +:100CC0000121084670470000F0061000F8061000E9 +:100CD000FC061000F4061000204908B50020204C46 +:100CE00008602049206008601F48006890F84003B1 +:100CF000C00701D00220206000F027FB00F0C9FDF2 +:100D00006B4600221921032004F0EEFB0098C00777 +:100D100005D00121032004F0CAFBFFF78BFB0098EC +:100D200000070BD50821032004F0C1FB206808212F +:100D300040F0080020600120FFF796FB0098C006F5 +:100D4000DED51021032004F0B2FB2068082120F03A +:100D5000080020600120FFF787FBD1E7040710009F +:100D6000080710000C071000D80610001F480021CB +:100D7000017041708170704710B51C4C0346A0781B +:100D8000102814D20F2900D90F211948227800EB1E +:100D900002100A4600F8011B194606F0CCFB207829 +:100DA000401C00F00F002070A078401CA07010BD07 +:100DB00070B50E4C0025A17891B10D49627801EB18 +:100DC000021111F8015B2A4606F0B5FB6078401C61 +:100DD00000F00F00607072B6A078401EA07062B67E +:100DE000284670BD0148807870470000B2061000A8 +:100DF000D951100010B54FF486715E4806F03CFCE6 +:100E00005C490120C1F804015B4800214160017088 +:100E100006F0E0FC0021BDE81040012005F09EBC7A +:100E200010B572B600205449087006F0D3FC62B6C3 +:100E300010BD10B572B601204F4908704D48D0F86A +:100E4000080108B106F022FD62B610BD10B572B6F9 +:100E50004849494B0A46D1F80841D2F80021521CB2 +:100E6000202C07D2641C22F02002C1F80841C1F8EE +:100E700000210FE0D1F8044122F02002641CC1F8E7 +:100E8000002124F02002C1F804215A68521C5A6043 +:100E9000D1F80021046801EBC20214604068506080 +:100EA0001878012805D1D1F80801012801D106F0F0 +:100EB000EDFC62B610BD2F4AD2F8080100280ED012 +:100EC000D2F8040102EBC000C37923F03F03C371E1 +:100ED00092F80821521E02F03F021343C37170477B +:100EE00010B572B62348D0F8081159B1491EC0F8A0 +:100EF0000811D0F8042102F1010222F02002C0F80A +:100F0000042105D11C480078012801D106F062FCBB +:100F100062B610BD10B572B6002016490122C1F8A4 +:100F20000801C1E94002144948600878012801D14C +:100F300006F050FC62B610BD70B50E490020D1F825 +:100F40000851002D12D00023D1F804210CE000BF7D +:100F500001EBC2042678332E02D16478B52C06D07A +:100F6000521C22F020025B1C9D42F1D870BD012072 +:100F700070BD000088520120B8061000064900220A +:100F80004FF470430A804B80044BC0E900310221CA +:100F90000172427270470000C00610009D7A010085 +:100FA0002DE9F05FDFF83C92DFF834B20F460646D9 +:100FB0004FF0010AA9F10805A84628780446072839 +:100FC00009D2DFE800F004292D49708B9C00012E26 +:100FD00002D0022E13D07EE0002F7CD0804810304B +:100FE0000078862809D07E48F9B21030FFF7C4FE99 +:100FF0000121032004F02FFA6DE003246BE06878F0 +:10100000012805D01021764806F014FB00F0A2F864 +:10101000544689F800A05EE0022E5AD0002445E034 +:10102000022E1BD1704C6E48D8F80410227806F0BE +:1010300082FA032189F800102178A9F8041098F8A1 +:101040000000042488F8010088F8004033E0002400 +:1010500088F801002C70AFE7022E02D0012EF6D0E6 +:1010600039E0FFF728FF082170B15D4AD0E9003070 +:10107000C2E90030022289F80020594AA9F802206A +:10108000A9F80410052426E06878062804D0002278 +:10109000CBF80020CBF80420032289F80020A9F81F +:1010A0000410062417E0022E08D002245FFA80F014 +:1010B00088F801002C704B48BDE8F09F6878042840 +:1010C00007D00BEB0700394610F8012C444806F016 +:1010D000A9FA89F800A0A8462878E9E7022E04D0EA +:1010E000082F8AD1FFF7FCFE87E7FFF7F9FE98F893 +:1010F0000000032488F8010088F800405CE7022E15 +:101100004FF00304A4D0D1E73649002208390A7011 +:101110004A70354A521C4A60344901603049818026 +:101120001031C18010210181704710B5044606F0CE +:1011300051FB2B4AD4E90001C2E900012A480C38CE +:1011400006F0AEFB28480C3805F0FCFBBDE810406B +:1011500006F09CBB70B5224C10342078C12824D1F5 +:1011600060781F4D052808D100F020F8204801685C +:1011700029608188A9808079A8716078082814D1B5 +:101180001C4C207858B90F2161700021A1701A49B8 +:10119000E01C096891F8952A042106F043FA2068BA +:1011A0002860A088A880A079A87170BD1048017837 +:1011B000002913D141701049096891F81A238270EF +:1011C00091F8CA29C27091F8BB231309437102F048 +:1011D0000F02027191F8BE13090981717047000076 +:1011E00094530120CC061000E8521000510F01006A +:1011F000A4061000AB061000D806100070B50F4D05 +:10120000802128462C8806F015FA641C2C8070BDBD +:101210000A48001F0021016070470849091F0A8819 +:10122000024204D0C87818B1C878401EC870704710 +:10123000A52088708878A528FCD07047B853012075 +:1012400037480021016041607047C0B2012200F0C0 +:101250002FFBFEE7344C0025324FC4E90225C4E9D8 +:10126000007106460068206170686061B068A06126 +:10127000F068E0613069206270696062B069A06204 +:10128000F069E06229489046894600682063274853 +:1012900010380068606325480C380068A063234854 +:1012A00008380068E0632148001D006820641F487A +:1012B0003438006860641D4814380068C4E91205B9 +:1012C00004F019FA2065C4E91565E56525666566CB +:1012D000A566E56625676567C4E91E574146484629 +:1012E000FFF7B3FF10B50446C0B2002200F0E0FAE9 +:1012F0000F490868082803DA094A1454401C08609A +:1013000010BD012806D0022808D100221146132062 +:1013100000F0CEBA002211461220F9E77047000013 +:1013200070EF0120AF0550FA80EF012038ED00E0AA +:10133000D4061000FD48FE4A0168914204D1FD49DF +:1013400002794A70002101607047F0B585B040F223 +:101350004C71F64806F090F9684605F027F9F34C11 +:10136000012500266570A680A6710220E07104F0B8 +:10137000DAFD208104F0D3FD070204F0D0FD47EA36 +:10138000102060816720208242F258306082EA4853 +:101390000068418AA182018AE182E849B1F8FA2E07 +:1013A0002283B1F8F82E6283427D227791F8FC1EE9 +:1013B0006177E3490968497CA177E6770199216261 +:1013C000009961620299A162DDE9031241EA0221FA +:1013D000E16281692163C1696163DA490968A163D6 +:1013E0000168E163418EA4F85010818EA4F8521078 +:1013F00090F8311084F8541090F8300084F85500BB +:10140000D148A4F88000D148A4F88800D048A4F8B6 +:101410008A00D048A4F88C00CF48A4F88E00CF48AA +:10142000A4F89000CE48A4F89200CE48A4F8940006 +:10143000CD48A4F89600CD48A4F89800CC48A4F86C +:101440009A00CC48A4F89C00CB48A4F89E00CB4856 +:10145000A4F8D000CA48A4F8D200CA48A4F8D4001E +:10146000B449C948A4F8D6008888401C8880A522C1 +:101470002270657060800D7005B0F0BD70B5AD4C28 +:1014800005460023A088A949401C82B2A2802846B4 +:1014900001F0C2FB257070BD70B5054640F24C717D +:1014A000A24806F0E9F8A34CA049A088401C82B2EB +:1014B000A280284601F0DDFB257070BD70B59D4C03 +:1014C00005462078A84204D040F24C71974806F0B7 +:1014D000D3F8AE48A5700F2101609448934A1030AC +:1014E000A06080201071944802F19005E5600068CA +:1014F00090F8311090F83030517101FB03F005EB9A +:101500004006937126610844D17105EB400060618B +:10151000137270BD70B50546864CC00704D080229A +:101520008949A06806F007F8834EA80712D53168EC +:1015300091F8310091F830104843A178302935D026 +:10154000312935D0322935D08249E3684200184626 +:1015500005F0F1FF680716D53068A17890F83120C2 +:101560008B48302928D0312931D00078322930D029 +:10157000022838D0052836D0062834D079495200C0 +:10158000206905F0D8FF280735D5306890F830205D +:10159000A078302829D0312829D0322829D075497F +:1015A0006069BDE87040520005F0C5BF6749CCE7EF +:1015B0006749CAE76849C8E70078022805D00528C6 +:1015C00003D0062801D06549D9E76D49D7E76449BA +:1015D000D5E7022805D0052803D0062801D06249A6 +:1015E000CDE76949CBE76749C9E76049D8E7604972 +:1015F000D6E76149D4E770BD4C4AA52010704D482C +:101600008178517001708188491C818051807047B8 +:1016100030B587B00C4600218DF80C104FF48325AF +:1016200004AB03AA694600F0DAF89DF8100010B187 +:10163000112816D01AE09DF80C20BAB100986271FA +:1016400005EB800104F110000A78930703D002F043 +:10165000FC02083200E0121DD2B205F06CFF07B0A8 +:1016600030BD322000222071114603E030200022DC +:101670002071114600F01CF9F1E770B505464FF4F2 +:10168000C8712A4805F0F8FF2A4C2849A088401C58 +:10169000A0802846FFF7BCFF24482570A5210170D3 +:1016A0004570A188418070BD2DE9F84F88460646F7 +:1016B0000C460D1D00239B220421404600F02EFD08 +:1016C00090BBA078B0422FD1217800239B222846DE +:1016D00000F024FD617888427BD1207881070AD010 +:1016E000022202EB9006002101E02954401CB0EBDD +:1016F000860FFAD302E0012101EB90060024DFF807 +:101700002CB04FF48325A1464FF0330A55F824003E +:1017100005EB8407401C3DD000239B220421384662 +:1017200000F0FCFC08B14BE053E035E00000012084 +:101730004B43554620071000D8061000A06D01202D +:10174000DC061000F0FF0100B85301209083012057 +:10175000D43F01201046012038540120AC800120E4 +:10176000820A0120F80A0120286D0120D68001207C +:10177000AC0A0120220B0120526D0120D87E0120ED +:1017800068090120920901203E090120000710008C +:10179000E804100000940CE03878810704EB900412 +:1017A00001D0A41C00E0641C602CAFD3B9F1000F81 +:1017B00006D031464046009A04F0E9FC00280CD0DF +:1017C00000228BF804A011463320BDE8F84F00F04A +:1017D0006FB8002211463120F7E7BDE8F88F2DE9F8 +:1017E000FF5F00260E601D4688464FF48327B146F2 +:1017F0003446B34683F8006057F8240007EB840AA8 +:10180000401C23D000239B220421504600F086FC7C +:1018100018B11220287001261CE09AF802200099C5 +:101820009AF800008A4208D10299029A4FF0010901 +:101830000978491C1170C8F80040810704EB900436 +:1018400001D0A41C00E0641C602CD5D316B9B9F1FA +:10185000010F0BD056EA090606D111202870029913 +:1018600081F800B0C8F800B0BDE8FF9FD8F80000CC +:10187000002307EB8004201D21789B2200F04EFC02 +:101880006178884202D185F800B0EDE71220287017 +:10189000EAE700F013B838B504466946183000F09E +:1018A000E2FC2046009900F013F838BD00F07AB849 +:1018B00000F097B800F0A7B800F0AEB81CB56149C9 +:1018C000D1E90001CDE900016846FFF7BFFA1CBD70 +:1018D0001CB55C4BD3E90223CDE9002390F8242109 +:1018E000032A1DD0082A21D00B2A1FD09DF80020E2 +:1018F00022F0F00212F120028DF8002090F825214C +:1019000002F00F02012A17D0022A1BD0042A41D06C +:10191000052A9DF8012022F00F0241D0521C16E04A +:101920009DF8002022F0F0021032E5E79DF800203B +:1019300022F0F0023032DFE79DF8012022F00F02A2 +:10194000921C04E09DF8012022F00F02D21C8DF8B9 +:10195000012090F833219DF8013062F307138DF8D0 +:101960000130BDF802200B0C63F30B02ADF802202E +:10197000BDF8032061F30F12ADF8032030F8441FC7 +:10198000090A8DF8051000788DF806006846FFF703 +:101990005DFA1CBD9DF8012022F00F02121DD6E752 +:1019A000521DD4E71CB5284A126892F8A02093076C +:1019B00016D50A2814D2DFE800F013050707070739 +:1019C0000707130712060BD51E4BD3E90623CDE9F3 +:1019D00000238DF80100CDF802106846FFF736FAB3 +:1019E0001CBD1CB5174CD4E90834CDE900348DF882 +:1019F0000100CDF80210684612B1FFF796FB1CBD3E +:101A0000FFF724FA1CBD1CB50168009140680190E5 +:101A10006846FFF71BFA1CBD1CB54178002910D0A1 +:101A200005290ED2074AD2E90C12CDE90012D0F8EE +:101A30000210CDF80210C088ADF806006846FFF726 +:101A400005FA1CBDA87A0100D80610002DE9FF4157 +:101A500003F04CFC234D0024C4EBC40105EB8100D2 +:101A600000F10C03027EC8CBCDE90272CDE900364D +:101A7000D0E9012355F82100002103F0E1FD18B160 +:101A800021464320FFF7E1FB641C052CE4DB154DE8 +:101A900000248C3505EBC4000021426855F8340061 +:101AA00003F055FD18B121464420FFF7CEFB641C1E +:101AB000062CEFDB0B4D002415F1BC05002155F879 +:101AC000240003F0AAFC18B121464520FFF7BDFB16 +:101AD000641C042CF2DBBDE8FF8101464620FFF7C1 +:101AE000B4BB0000E07A010000F01F0301229A401D +:101AF00043099B0003F1E023C3F880224907090E44 +:101B0000002806DA00F00F0000F1E02080F8141D34 +:101B100003E000F1E02080F80014C3F800217047D2 +:101B20002DE9F041642707260025F94CF94804F017 +:101B3000E0FCF8480368D91C40D04268D11C3DD075 +:101B4000816811F1030F39D0006910F1030F35D00E +:101B5000B3F1FF3F35D013F1020F32D0B2F1FF3FA6 +:101B60002FD012F1020F2CD0B1F1FF3F29D011F18B +:101B7000020F26D0B0F1FF3F23D010F1020F20D08A +:101B8000DFB2D6B2CDB204462A463146384604F01A +:101B9000EFF9204604F0F9F9DF4804F080FC03284F +:101BA00014D0012815D0022813D0DB480168012980 +:101BB00015D1BDE8F041001D03F0E3BD0021242054 +:101BC00001E000212520FFF78DFBDDE70021292022 +:101BD00001E000212A20BDE8F041FFF783BBBDE80A +:101BE000F0812DE9FC41CD4F012501AA6946384617 +:101BF00004F046FACA4C4FF48C56012803D10098E1 +:101C0000B0F58C6F04D000212220FFF76BFB30E091 +:101C100032463946206805F08EFC206804F043FA0D +:101C2000012804D000212320FFF75CFB0025216858 +:101C300028220F46BB4801F5865105F07CFC41F295 +:101C4000E6003918B7482022283005F074FC41F22C +:101C50001C103918B3482822483005F06CFC41F2BA +:101C600042103918AF482022703005F064FC002D76 +:101C700003D13146206805F0DDFCBDE8FC81F8B5F4 +:101C80000D46064600246A4604F0FAF9012801D000 +:101C900001240BE0286831468200A34805F090FC3F +:101CA000A14804F000FA012800D002242046F8BD23 +:101CB000F8B59D4D9D4F103540F698719C4805F044 +:101CC000DBFC69463846FFF7DAFF012805D0022819 +:101CD00006D0E87801280AD105E00021A02029E0FB +:101CE0000021A12026E0A87808B9288810B1002199 +:101CF000A2201FE08E48E9880024A0F8F81EA988D9 +:101D0000A0F8FA1E297A80F8FC1E0098694607EBB5 +:101D100080073846FFF7B3FF78B1012804D00021CF +:101D20005FF0A600FFF7DEFAE00723D0A00723D478 +:101D30001121A720FFF7D6FAF8BD6E782946304664 +:101D400000F049FF50B1102E0BD0112E0CD0122EE6 +:101D50000DD0132ED9D144F01004D6E73146A82077 +:101D6000E0E744F00104D0E744F00204CDE744F09A +:101D70000804CAE71021DCE720070BD46D4800688F +:101D800090F85012C90703D190F88002C00701D023 +:101D90001221CEE7E006CFD41321CAE730B58DB0CB +:101DA000EEF72CFB0020012241B201F01F0302FAE2 +:101DB00003F34909890001F1E021C1F88031401C99 +:101DC0001F28F1DBEEF718FB04F07EF8FFF7B2FAFC +:101DD00004F042FC07210A20FFF786FE07210B20B2 +:101DE000FFF782FEFFF706F8FEF7C0FF04A8FFF733 +:101DF0008BF907A8FFF7C2F804A8009007A8029083 +:101E00000AA80390684604F039FE02210020FFF77B +:101E10006BFE05F041FD0078C00701D1FFF709F81E +:101E2000FFF70EFAFFF77CFE04F09AF8424D01AA84 +:101E30006946284604F024F93E4C012802D00021CE +:101E4000202010E00098B0F53E7FF8D14FF43E62BC +:101E50002946206805F06FFB206804F024F901286A +:101E600003D000212120FFF7F0F9FFF7BAFE04F0BC +:101E7000BDFB050046D00121012D02D02E20FFF729 +:101E8000E4F92068017DA94202D02F20FFF7DDF997 +:101E9000FFF70EFF00F052F802F00CFF03F046FCD3 +:101EA000002301221946052005F054FA00231A46A2 +:101EB0000121062005F04EFA03210120FFF714FE50 +:101EC00004210720FFF710FE04210820FFF70CFE75 +:101ED000206890F86003C1070FD081070DD500215D +:101EE000012340091A46009104F045FC20680021B6 +:101EF00090F86003400904F0C6FB0DB0BDE8304027 +:101F0000FFF786B900212D20FFF7ECF9C0E70000AC +:101F10000090D00328891000088E1000F09F010067 +:101F2000DC061000387D012078641000F0BF01004D +:101F3000A06D0120D8061000F0EF010010B504F0EC +:101F40005DFE002301221946184605F003FA00231E +:101F500001221946104605F0FDF900231A46012119 +:101F6000022005F0F7F900231A460121032005F0AD +:101F7000F1F900231A460121042005F0EBF9174876 +:101F80000068017CA52908D04FF4FA4005F0CCF98F +:101F900000212820FFF7A6F902E0406905F0C4F906 +:101FA00004210220FFF7A0FD04210320FFF79CFD80 +:101FB00004210846FFF798FD04210520FFF794FD52 +:101FC00004210620FFF790FD01210920FFF78CFD79 +:101FD0000421BDE810400F2086E50000DC0610005B +:101FE00070B55A4B16465C0C08E000BF31F916502C +:101FF000A54200DA2C469D4200DD2B46761EF5D226 +:102000000025002B01DA1D4609E0002C07DD2546DE +:1020100005E000BF31F812305B1B20F81230521E71 +:10202000F8D270BD2DE9F047002591460F46804655 +:102030001C462E465A1E0120294605F045FA0BE0A3 +:1020400038F91420BA4204DA4A44002A01DD054373 +:102050000E4349084FEA3000641EF1D2284631464B +:10206000BDE8F0872DE9F047994616461EE00218B4 +:1020700000F001052A4341EB010707EA0105034689 +:102080004F0802EA03084FEA3004A9F101024FF0B9 +:1020900001004FF0000105F017FA00EA08000443C0 +:1020A00029400F4304EA080007EA0501761EDED244 +:1020B000D6E7884200D30846904200D310467047C6 +:1020C000884200D80846904200D81046704788429F +:1020D00000D308467047884200D80846704710B5BC +:1020E00000231C4642B10278521CD2B202708A42CE +:1020F00003D90470012300E00470184610BD30B508 +:102100000024012305E00C44E41C04F00305641BD7 +:102110005B1C9342F7DD00EB440030BD70B5054613 +:10212000184600240EE02B5D58400823060602D511 +:1021300082EA400000E040005B1EC0B213F0FF03E3 +:10214000F4D1641C8C42EED370BD00000080FFFF10 +:1021500030B5B0F90240B1F90250641B00D56442B9 +:10216000B0F90000B1F90010401A00D54042944285 +:1021700003DA984201DA012030BD002030BD8842E8 +:1021800001DD084670470028FCDA0020704710B5D2 +:1021900005E000BF00EB820353F8044C1C60521EA4 +:1021A000F8D10968016010BD10B503E000EB8203AF +:1021B0000C681C60521EF9D210BD30B506E000BF9D +:1021C00000EBC20373E90245C3E90245521EF7D191 +:1021D000D1E90021C0E9002130BD10B553884C88F9 +:1021E0001B1B438012880988511A018010BD08B555 +:1021F0000A4601466846FFF7F0FFBDF90010BDF939 +:102200000200494300FB001008BD10B58842029C43 +:1022100001DC204610BD904201DB184610BD8A4209 +:1022200000D1521C401AE31A5843511A90FBF1F0A6 +:10223000201A10BD10B5002A03D0431A934201DDC5 +:10224000881810BD5442A342FBDA881A10BD91428F +:1022500001D100B270475043B0FBF1F000B29042A0 +:10226000F7D91046F5E770B50B0002463DD0E64CB5 +:102270002068468E858EB2F9020031B2FFF77FFFEB +:102280005880B2F9000029B2FFF779FF1880216861 +:1022900091F83610490702D55988711A598021687A +:1022A00091F83610890701D5281A1880206890F80F +:1022B0003610090710D5B0F83720B3F902003146BF +:1022C000FFF7C5FF588020682946B0F83920B3F9D8 +:1022D0000000FFF7BCFF1880206890F83600C007A8 +:1022E00003D0588819885980188070BD2DE9F047AF +:1022F000D0F810C00568046A85FB0C12A1FB04121B +:1023000042694368914683FB02628269E246A6FB0A +:1023100002677618D0E9021781FB07C8C069ACFBD9 +:1023200000C81CEB060682FB0A2CA2FB011280FBF4 +:102330000902A0FB0502401884FB0712A1FB03124F +:102340000818301A4FEAE071BDE8F0872DE9FF4F19 +:102350008146AD4800268DB000683746B04690F8FB +:10236000804390F8810300F0030A04B90224BAF113 +:10237000000F01D14FF0040A5FF0000109EBC1002A +:1023800040680644484300FB0188491C074406296D +:10239000F4DB9E4D009668680190A868CDE90207BD +:1023A000286904906869CDE90508E8690790286AFA +:1023B00008906846FFF79AFF83460B912868CDE99D +:1023C0000006A8680290E868CDE9030768690590EF +:1023D000A869CDE90608286A08906846FFF786FFD5 +:1023E000CDE90901286800906868CDE90106E86830 +:1023F00003902869CDE90407A8690690E869CDE94A +:1024000007086846FFF772FF06468846DDE90901BE +:10241000A0FB0435A6FB047C01FB0451002200FB59 +:10242000021508FB04C106FB0210A7FB04C100FB58 +:10243000041007FB020013EB0C0345EB00010B9AA1 +:1024400013EB0B0051414FF47562002305F04FF878 +:1024500009EBCA0148600E9948600F990B9AC1E9CF +:1024600000B2DDE909010F9AC2E902010F98C0E943 +:10247000046800263746B0464FEA060059F8301087 +:102480000E44414301FB0088401C0F440628F5DB45 +:102490005E4D009668680190A868CDE9020728693A +:1024A00004906869CDE90508E8690790286A0890F2 +:1024B0006846FFF71BFFCDE909012868CDE9000652 +:1024C000A8680290E868CDE9030768690590A869E3 +:1024D000CDE90608286A08906846FFF707FFCDE9AE +:1024E0000B01286800906868CDE90106E868039050 +:1024F0002869CDE90407A8690690E869CDE90708CD +:102500006846FFF7F3FE80468B46DDE90B01A0FB32 +:102510000453A8FB046701FB0431002200FB0211F5 +:102520000BFB047308FB0230A6FB043700FB0470AE +:1025300006FB0200EB184141DDE909021818514180 +:102540004FF47562002304F0D2FF49F83A000E9967 +:102550000860DDE909021099C1E90002DDE90B011B +:10256000109AC2E902011099C1E9048B11B0BDE8CB +:10257000F08F2DE9F05FD1E901651C46A5FB043819 +:10258000D1F80CC017460CFB048C0A6882464FF049 +:10259000000B05FB0BC0D318D1E9042104FB04F5A3 +:1025A000A2FB05C801FB058146414FEAE57902FB24 +:1025B000091213EB0C0046EB02014FF475625B4607 +:1025C00004F095FFCAF8040097E80B00FA68A3FB33 +:1025D00004C802FB048203FB0B2310EB0C025941DD +:1025E000D7E90434A3FB056704FB057403FB094327 +:1025F000901959414FF47562002304F078FFCAF82E +:102600000000BDE8F09F0000D80610003807100059 +:1026100073B51D24DDE9005622460120002104F097 +:1026200053FF28403140084301D1641EF4D50821EE +:10263000684603F013FDFF49C0B2096891F8E7103E +:10264000C1F3411102290ED310F0030005D0012877 +:1026500005D0022805D01F200AE00F2008E07F20C7 +:1026600006E03F2004E0C00701D0072000E003207F +:102670000021621C04F028FFDDE900231043194308 +:10268000CDE900017CBD10B5EB4C502814D008DC1E +:10269000102811D0112825D0122823D0132806D1B4 +:1026A00020E051281ED052281CD053281AD00020D8 +:1026B000C4E9020001461BE002F0C2FBC4E90201CA +:1026C00002F0C0FBC4E90401DA48006890F8E700B2 +:1026D00010F0600F0ED0D4E90201FFF799FFC4E9B2 +:1026E000020107E002F0ACFBC4E9020102F0AAFB20 +:1026F000C4E90401D0480821083003F0AFFC206091 +:10270000CD480821103003F0A9FC606010BD2DE910 +:10271000FF5F0821DDE90FBA684603F09FFC8146A0 +:10272000082102A803F09AFC0746002420463AE05C +:1027300042460120002104F0C7FEDDE900231040DD +:10274000194008432DD000252E4627E032460120AF +:10275000002104F0B9FEDDE90223104019400843CE +:102760001BD0119860B104FB07F00BEB050141563B +:10277000324601EB0A0321460E9803F0C0F80BE045 +:10278000324621460E9803F0AFF804FB07F10BEB3D +:102790000502A0EB0A0088546D1C761CBD42D5DBF7 +:1027A000641C08F1010080464C45C1DBBDE8FF9F79 +:1027B0002DE9FF5F84B00821DDE912AB04A803F026 +:1027C0004DFC8146082106A803F048FC8046002500 +:1027D0000AF1480002902030019048382C462F46DC +:1027E0002E46009034E03A460120002104F06CFEB1 +:1027F000DDE9042310401940084327D0169890B112 +:102800001BF8051014980844C2B23946029803F028 +:10281000E2F805EB090141441BF901203946504615 +:1028200003F0B1F810E03946029803F0D2F8149999 +:10283000401A0BF805003946504603F09DF805EBA9 +:10284000090242440BF802006D1CEDB27F1CFFB27E +:102850004D45C8DB38E032460120002104F034FE4B +:10286000DDE906231040194008432BD01698A0B18B +:1028700004EB090115981BF801100844C2B2314657 +:10288000019803F0A8F804EB490141441BF9012029 +:102890003146009803F077F812E03146019803F0D2 +:1028A00098F8159904EB0902401A0BF8020031461A +:1028B000009803F061F804EB490242440BF802006F +:1028C000641CE4B2761CF6B24445C4DB08B0BDE833 +:1028D000F09F2DE9FF5F0821DDE90EBA684603F09D +:1028E000BDFB8146082102A803F0B8FB074600247F +:1028F000204629E042460120002104F0E5FDDDE903 +:1029000000231040194008431CD000252E4616E035 +:1029100032460120002104F0D7FDDDE902231040FA +:10292000194008430AD032462146584602F0DCFFDF +:1029300004FB075280002AF812006D1C761CBD4271 +:10294000E6DB641C08F1010080464C45D2DB2DE734 +:102950002DE9FF5F0821DDE90E9B684603F07EFB51 +:102960008246082102A803F079FB002580462C4608 +:102970002F462E463DE03A460120002104F0A4FDFA +:10298000DDE9002310401940084330D0394609F1F1 +:10299000480003F01EF8274999F892C00A6892F897 +:1029A000413192F8402103F00F01491C0CFB01FC5E +:1029B000012101EB131300FB03C399F8900001EB15 +:1029C000121100FB0130109919B94FF6FF7101EA9D +:1029D00080002BF815003946484602F0CDFF05EB84 +:1029E0000A02800042446D1C2BF81200EDB27F1CDD +:1029F000FFB25545BFDB44E032460120002104F020 +:102A000063FDDDE9022310401940084337D0314609 +:102A100009F1680002F0DDFF064999F893500B6850 +:102A200093F8431101F00F02521C5543012202EBAF +:102A3000111103E0D80610006007100000FB0151DF +:102A400093F8423199F8910002EB131200FB021047 +:102A5000109919B94FF6FF7101EA800004EB0A02E0 +:102A600031462BF8120009F1200002F085FF04EB3B +:102A70004A0280004244641C2BF81200E4B2761C27 +:102A8000F6B24445B8DB91E62DE9F04389460027CC +:102A900087B0904604463E46FC2104F0CBFDFD4D38 +:102AA000B8F1010F2878207128796071FA4890F800 +:102AB000821BA17190F8831BE17190F8841BA172B5 +:102AC00090F8851BE17290F8801B217390F8810BC0 +:102AD000607308D1F1480068817FA52903D190F97E +:102AE0001F7090F92060EE480021006890F83401D2 +:102AF000CDE9027600F00100CDE9041004F11000E8 +:102B0000E849CDE9001005F108000FC8FFF750FEB5 +:102B1000A520207012206070A4F80290D5E9000171 +:102B20000844132101EB4000800807B0BDE8F083A2 +:102B30002DE9F0438946002787B0904604463E467B +:102B4000FC2104F077FDD34DB8F1010F28782071F6 +:102B500028796071D04890F81A1CA17190F81B1C5C +:102B6000E17190F81C1CA17290F81D1CE17290F8A4 +:102B7000181C217390F8190C607309D1C7480068BC +:102B800090F82110A52903D110F9227F90F9016056 +:102B9000C3480021006890F8E009CDE9027600F012 +:102BA0000100CDE90410BF4904F110009831CDE9CE +:102BB000001005F108000FC8FFF7FAFDA5202070EE +:102BC00013206070A4F80290D5E90012114400EBC4 +:102BD00041008008A9E770B50E4604460025FFF7BE +:102BE00052FD102C06D0112C08D0122C0CD0132C16 +:102BF00008D10DE0304600F085F802E0304600F0E4 +:102C0000A4F80546284670BD304600F0C0F8F8E745 +:102C1000304600F0FDF8F4E72DE9F0411E46174676 +:102C2000884605460024FFF72EFD102D06D0112DF5 +:102C30000AD0122D11D0132D0CD114E03246394692 +:102C4000404600F033F904E032463946404600F091 +:102C50005FF904462046BDE8F081324639464046D9 +:102C6000FFF712FFF5E7324639464046FFF760FFAF +:102C7000EFE72DE9FF4117460C460646FFF703FD37 +:102C8000844D502E287820712879607104F110004D +:102C900007D0512E07D08249522E0DD0532E2BD162 +:102CA00015E07D4900E08049CDE90010083595E840 +:102CB0000F00FFF70EFE1FE009687A4B91F83421F0 +:102CC00091F8401102F0010201F001010AE00968E7 +:102CD000744B91F8E02991F8EC1902F0010201F02F +:102CE000010198330DF10408009388E807000835C6 +:102CF00095E80F00FFF72CFEA52020706670678016 +:102D0000BDE8FF811FB5634902790B689A4203D180 +:102D100042794B689A4202D0002004B010BD5F4B4C +:102D200000221B689C7EA52C01D193F91B205A4CD4 +:102D30000DF1040C0123103000948CE80D000831D3 +:102D40000FC9FFF7E4FC0120E7E71FB551490279FD +:102D50000B689A4203D142794B689A4201D0002015 +:102D6000DBE74E4B00221B681C7FA52C01D193F999 +:102D70001D204D4B0DF1040C0124103000938CE804 +:102D8000150008310FC9FFF7C2FC0120C5E730B5B7 +:102D90004049027987B00B689A4203D142794B6867 +:102DA0009A4202D0002007B030BD3B4A857900240A +:102DB00082F8825BC57982F8835B857A82F8845BCE +:102DC000C57A82F8855B057B82F8805B457B82F85B +:102DD000815B324A23461268957FA52D03D192F973 +:102DE0001F4092F920302E4A012510301268083118 +:102DF00092F83421CDE9024302F00102CDE90452F8 +:102E0000284ACDE900200FC9FFF7D2FC0120CAE70C +:102E100030B52049027987B00B689A4203D14279D4 +:102E20004B689A4201D00020BDE71B4A85790024F7 +:102E300082F81A5CC57982F81B5C857A82F81C5C82 +:102E4000C57A82F81D5C057B82F8185C457B82F8A8 +:102E5000195C124A2346126892F82150A52D03D11D +:102E600012F9224F92F901300D4A012510301268F3 +:102E7000083192F8E029CDE9024302F00102CDE9E0 +:102E80000452084A9832CDE900200FC9FFF790FCA0 +:102E9000012088E760071000A06D0120DC0610000B +:102EA000D806100090780120C87201202DE9FF415A +:102EB0000F4615460446002640F27A3104F0BAFB6C +:102EC0002C48012D017821710179617106D12A49BF +:102ED00009688A7EA52A01D191F91B6004F11001CD +:102EE000264BCDE900310022CDE9026200F1080154 +:102EF00005460FC9FFF70BFCA5202070102060705D +:102F00006780D5E9000148431330800804B0A2E689 +:102F10002DE9FF410F4615460446002640F27A315E +:102F200004F088FB1348012D01782171017961714A +:102F300006D1114909680A7FA52A01D191F91D60BE +:102F400004F110010E4ACDE900210023CDE902630E +:102F500000F1080105460FC9FFF7D9FBA520207035 +:102F6000112060706780D5E9000148431330800864 +:102F7000CCE7000060071000DC061000A06D012007 +:102F8000C87201202DE9F04F47F6FF77DDE909B55A +:102F90008146FE4301209A4684462C4615E000BF38 +:102FA00032F8143031F81480A3EB08031BB2BB4293 +:102FB00000DA1F46B34200DD1E46002B02DD4FF053 +:102FC000000C02E001DA4FF00000641EE8D220B1EC +:102FD000BCF1000F01D0002309E050EA0C0306D039 +:102FE00020B9BCF1000F01D0334600E03B4600277A +:102FF0003C462846CBF1000C0EE000BF32F81060D2 +:1030000031F81080A6EB0806F61A36B2564503DAF8 +:10301000664501DD3744641C401EEFD204B901242B +:1030200097FBF4F0184404E031F81520024429F825 +:1030300015206D1EF8D2BDE8F08FF0B500230646CE +:103040001D4618460EE000BF36F91140002C01DB8A +:10305000274600E06742974204DD002C01DD25444D +:1030600000E02344491EEFD2002B00DA5B42AB4262 +:1030700000DD0120F0BDF0B5724D6F426E0C0EE028 +:1030800032F9134031F913C0A4EB0C04BC4201DB4C +:10309000344602E0AC4200DA2C4620F813405B1EB6 +:1030A000EED2F0BD70B5049C09E000BF31F91450B8 +:1030B00032F91460754395FBF3F520F81450641E43 +:1030C000F4D270BDF0B4049C1CB913B1C3F1100468 +:1030D0000EE0F0BC520004F02EBA00BF30F91250DE +:1030E00031F912605D4306FB04552D1120F8125092 +:1030F000521EF3D2F0BC7047F0B4049C1CB913B15B +:10310000C3F180040EE0F0BC520004F014BA00BF1A +:1031100030F9125031F912605D4306FB0455ED1190 +:1031200020F81250521EF3D2E4E7F0B5002B19D06C +:10313000144615E000273E46E51A04EB030C08E0B0 +:10314000002D05DB954203DA31F915E0761C774452 +:103150006D1CAC45F4DA1EB197FBF6F520F814505F +:10316000641EE7D2F0BD70B50C461546A04204D0EF +:1031700001466A00204604F0DEF9002017E001460F +:10318000421C07E034F9126034F911309E4200DA33 +:103190001146521CAA42F5D3884207D034F81020B9 +:1031A00034F8113024F8103024F81120401CB0EB12 +:1031B000550FE4D9E90725F0010001D0205E70BD6C +:1031C000215E204430F9020C0844401070BD0346D3 +:1031D000002004E033F91120824200DD1046491E30 +:1031E000F8D2704710B5002447F6FF7308E000BF1F +:1031F00030F91120A24200DD14469A4200DA13464B +:10320000491EF5D2E01A00B210BD034647F6FF7022 +:1032100005E000BF33F91120824200DA1046491E52 +:10322000F8D2002800DA002070470246B0F900000A +:1032300005E000BF32F91130834200DD1846491E17 +:10324000F8D270470080FFFF70B5050003D0BDE8DD +:10325000704001F0DBBDFE4C21466078097930B149 +:103260000A46FC4901F1980001F01EFE0BE02078AF +:1032700001F0E8FE21794A00F64901EB4001F548EA +:10328000983004F058F9A078F34E28B1F14821792C +:10329000983001F0D5FE01E0EE489830B062E07859 +:1032A00086F831002846D2E72DE9F05FDFF8ACA3BD +:1032B00083460127DAF80000B84600F25E6490F811 +:1032C000F41990F8F05901F01F0690F8F11901F087 +:1032D0000F0990F8DE19890609D590F8581690F86C +:1032E00059060A2204EB400001F01AFE0746DAF8FC +:1032F000000090F8DE19490609D590F8D21890F828 +:10330000D3080A2204EB400001F00AFE80464FF485 +:103310008070854200D905461F2E00D91F26761CD5 +:10332000754309F101004543C5EB45207843DAF8C0 +:10333000002000FB08F0C01392F8871AB0FA80F062 +:10334000C0F12000890611D50021BBF1010F06D183 +:1033500092F88D1A0A0701F0070100D5494240187A +:1033600001D5002002E01F2800DD1F20C0B2BDE80B +:10337000F09FF8B5044602F0F2F9B64802F0F4F90D +:10338000A4F8760001F0B6FDB14A0B46127800921F +:103390000246204602F0BDFC01F0B1FD02460B469C +:1033A000204602F0ECFC204601F058FEAB4DB4F88C +:1033B00056102868B0F8C02062F30901A4F856102E +:1033C00090F8BF0094F8551060F3030184F855108D +:1033D0000521204602F0F3F9286890F8F009A07062 +:1033E0002868218EB0F8F62962F30801218690F84A +:1033F000F10900F00F01204602F058FA286834F86D +:103400001A1FB0F8E82962F30B0124F81419B0F878 +:10341000E629618962F30B016181B0F8E419E08863 +:1034200061F30B00E08014F8050C20F00C0004F8A8 +:10343000050C2868217B90F8F22962F301012173C1 +:1034400090F8F229920862F38711217390F8DE193F +:10345000627861F30002627090F8E109E0708048E0 +:1034600090F8181C217690F8191CA17790F81A1C76 +:10347000617690F81B1CE17790F81C1CA17690F8FF +:103480001D0C84F82000774802F06EF9A4F87A0049 +:103490007448203002F068F9A4F87E00286814F817 +:1034A000166F90F8EC19090961F3071604F8066B1A +:1034B00090F8EE192278090961F30712227090F84A +:1034C000ED3914F8051C63F3030104F8051C90F8AA +:1034D000EF79637867F30303637090F8ED793F0940 +:1034E00067F3071104F8051C90F8EF19090961F357 +:1034F0000713637090F8EC1961F3000604F8066C8A +:1035000090F8EE1961F3000204F8222990F8E2091C +:103510000109204602F0D6F95248483802F024F951 +:10352000A4F87E004F482734283802F01DF9A4F88B +:103530005B00296891F8E0098208207862F3830033 +:10354000207091F8E02962F30000207091F8E029E2 +:10355000520862F3410004F8010B207820F01000BB +:10356000207091F8DE29D308E27A63F34512E27203 +:1035700091F8DF1961F3451004F82809204601F09D +:1035800051FD286890F8DF09C0F34101204602F0A0 +:1035900067F9296891F8DE09820914F8330F62F39C +:1035A000000004F81D0991F8DE29520962F3410078 +:1035B000607791F8F309E27D60F30402E27591F817 +:1035C000F419A07D61F30400A075224894F8491015 +:1035D0000838407860F30401224884F84910E83044 +:1035E00002F0C2F8A4F86400286834F8181FB0F894 +:1035F000EA2962F30B0124F8041910F8E31F22787A +:1036000061F3030204F8012B01780A09217862F3BF +:10361000030104F8091B90F8FB18CA09217862F32A +:10362000000104F82B1B14F8571941F0200184F80D +:10363000571090F810194A09217862F30611217089 +:1036400090F8FC184A09217C62F3C30121740BE055 +:1036500078071000407E0120C88D1000D8061000A9 +:10366000A06D01207079012090F8FB08400860F3FC +:1036700004112174F8BD2DE9F0410446524D01209A +:103680000129A87008D00026504F022908D003292C +:1036900014D004292CD13AE0204600F091F827E01C +:1036A0004B48FFF766FE204600F08AF8B87894F899 +:1036B0005F1060F3040184F85F1014E04448FFF7E2 +:1036C00058FE204600F07CF8F87894F85F1060F31C +:1036D000040184F85F1094F8270020F0020040F005 +:1036E000010084F827000021204602F0DFF8AE70C8 +:1036F00094F8270040F30000401CE870354800684B +:1037000090F8DF09C0F380106870BDE8F0812046B2 +:1037100000F056F8204601F0E2FCE8E77CB501F045 +:10372000E9FBCDE900010821684602F097FC264933 +:10373000264D08710020286028710124E0B2FFF7AF +:10374000B3FD2855641C052CF8DB2148FFF711FE5A +:103750007CBD30B5017AA9B079B36846FFF78BFF1D +:103760009DF8120000F0030001F02CFC194C2068B9 +:1037700000F25E6300F6D80590F8581690F85906E6 +:1037800003EB400001F0EFFB206890F8D21890F8AE +:10379000D30805EB400001F0FDFB0B48417801B177 +:1037A00002210170C9B2684602F003FB0A4968466B +:1037B00002F034FB002029B030BDFFE70120FAE71A +:1037C000A422034903F0B7BE78071000387E012019 +:1037D0003C891000D8061000F931010010B5040032 +:1037E00003D0BDE8104001F011BB25482549007801 +:1037F000420001EB40012348983003F09CFE214831 +:103800002149983048622046EBE71CB501F072FB75 +:10381000CDE900010821684602F020FC18491B4C44 +:103820000870204600F0D5FA164801F09DFFA4F874 +:10383000760017480168A07C91F8462162F30100E8 +:10384000A07491F84611890861F38710A0741CBD1B +:1038500010B50E4CC07980B1A07C00F0030001F0DF +:10386000B1FB00F008FB0421204602F0A2FA09494E +:10387000204602F0D3FA002010BD012010BD000048 +:103880007D071000247F0120C88D1000E089100002 +:10389000D80610008D370100FE49C868401CC8607A +:1038A000022803D2FC4951F820000047002001F013 +:1038B000ADBA002801D102F0A2BA7047F54910B59F +:1038C0000A790120521CD2B20A710B7A9A420AD8A4 +:1038D000487A48B102F0E4F90320ECF791FDEF4893 +:1038E00002F0D2F9002010BD02F089FAFAE770B5B3 +:1038F00018B1BDE8704001F089BAE64C207A08B1F1 +:10390000E74D01E0E64D763DA078E649820001F5FD +:10391000AE7003F055FE607928B1A278E1492846DF +:1039200001F0C2FA0CE0A178607801F08BFBA1787D +:10393000C0B24A00DB4901EB4001284603F0FBFD21 +:10394000D7482379A2782946763801F0BEFAFFF7E6 +:10395000B5FF002815D0A079D34D01280BD0D04851 +:103960007638A861E07985F83000207985F8200064 +:10397000BDE8704090E7CA48A178763801F060FB56 +:10398000EFE770BD70B518B1BDE8704001F03EBA08 +:10399000C04C207A08B1C24D01E0C14D4C3DE078E9 +:1039A000C049820001F5D87003F00AFE607928B1A1 +:1039B000E278BC49284601F077FA0CE0E1786078BB +:1039C00001F046FBE178C0B24A00B64901EB400184 +:1039D000284603F0B0FDB2482379E27829464C38F6 +:1039E00001F073FAFFF76AFF002815D0A079AE4DF9 +:1039F00001280BD0AA484C38E861E07985F83000FE +:103A0000207985F82100BDE8704045E7A448E178B9 +:103A10004C3801F016FBEFE770BD2DE9FF5FDFF8D2 +:103A20008CB28C460127DBF80000109E134690F8FC +:103A3000491190F8444101F0030A90F84811B84642 +:103A400001F01F0590F8451190F8320101F00F09BF +:103A5000800605D50A221946604601F061FA07463C +:103A6000DBF8000090F83201400605D50A220E99D5 +:103A7000039801F055FA80464FF48070844200D9D3 +:103A800004461F2D00D91F256D1C6C4309F1010050 +:103A90004443C4EB4420784300FB08F00AF10101E1 +:103AA0004843DBF80010C013B0FA80F091F8871A91 +:103AB000C0F12000C9060FD5009A0021012A04D1C7 +:103AC0000F9909B1714200E03146401801D500203C +:103AD00002E01F2800DD1F2004B0C0B2BDE8F09F47 +:103AE000F8B5044601F03BFE6E4801F03DFEA4F837 +:103AF000760001F0FFF9674E0B467278009202469D +:103B0000204602F006F901F0FAF902460B4620467B +:103B100002F035F9204601F0A1FA644DB4F85610D0 +:103B20002868B0F8C02062F30901A4F8561090F894 +:103B3000BF0094F8551060F3030184F85510052177 +:103B4000204601F03CFE286890F84401A0702868E7 +:103B5000218EB0F84A2162F30801218690F84501D0 +:103B600000F00F01204601F0A1FE286834F81A1F6A +:103B7000B0F83C2162F30B0124F81219B0F83A2195 +:103B8000218962F30B012181B0F83821A18862F309 +:103B90000B01A18090F84621A17A62F30101A17284 +:103BA00090F84621920862F38711A17290F83211C1 +:103BB00014F8012C61F3000204F8012C90F835018F +:103BC00060703B4890F8801BA17590F8811B2177AD +:103BD00090F8821BE17590F8831B617790F8841B45 +:103BE000217690F8850BA077324801F0BDFDA4F84E +:103BF00078003048203001F0B7FDA4F87C00286838 +:103C000090F840110A0914F8141F62F3071104F820 +:103C1000061B90F842211309227863F307122270E1 +:103C200090F8417114F8053C67F3030304F8053C70 +:103C300090F843C167786CF30307677090F841C14F +:103C40004FEA1C1C6CF3071304F8053C90F8433151 +:103C50001B0963F30717677090F8403163F30001A5 +:103C600004F8061C90F8421161F3000204F82229BE +:103C700090F836010109204601F024FE0D4848382D +:103C800001F072FDA4F87E000A482734283801F0BC +:103C90006BFD11E080071000AC7B01006338010070 +:103CA0002281012014800120C88D1000D806100048 +:103CB000A06D0120D8780120A4F85B00296891F854 +:103CC00034018208207862F38300207091F8342157 +:103CD00062F30000207091F83421520862F3410031 +:103CE00004F8010B207820F01000207091F83221A8 +:103CF000D308E27A63F34512E27291F8331161F36B +:103D0000451004F82809204601F07AF9286890F84F +:103D10003301C0F34101204601F0A2FD286890F86C +:103D200032118A0914F8331F62F3000104F80719ED +:103D300090F83221520962F34101E17190F8471184 +:103D4000627861F30402627090F84801217860F3B0 +:103D500004012170CC4801F007FDA4F84E0028684A +:103D600034F8021FB0F83E2162F30B0124F8181951 +:103D700010F8E31F227D61F30302227510F8451B42 +:103D80000A09617D62F303016175817ACA09A17F25 +:103D900062F30001A17794F8491041F0200184F802 +:103DA0004910C17F4A0914F80E1C62F3061104F889 +:103DB0000E1CC17A4A09A17862F3C301A170827A0C +:103DC000520862F30411A170C07AC0F380107071C0 +:103DD000F8BDA422AD4903F0AEBB2DE9F041AC4CD7 +:103DE000002601272671A77126720D4666720128EA +:103DF00006D0022825D0032814D004282CD133E083 +:103E00000846FFF7E6FFA348016891F8370142062C +:103E100022D591F84911000601F0030121721BD54A +:103E2000677219E09948FFF75BFE2846FFF7D1FF5C +:103E300095F8270020F0020040F0010085F82700E7 +:103E400005E09248FFF74CFE2846FFF7C2FF00212D +:103E5000284601F02BFDA67195F8270040F30000DD +:103E6000401CE071BDE8F0810846FFF7B2FF28462C +:103E700001F035F9EFE770B5864D286800F25E6213 +:103E800000F6D80490F8541690F8550602EB40005E +:103E900001F069F8286890F8CE1890F8CF0804EB84 +:103EA0004000BDE8704001F075B870B5794D2868E4 +:103EB00000F25E6200F6D80490F8561690F85706A5 +:103EC00002EB400001F04FF8286890F8D01890F805 +:103ED000D10804EB4000BDE8704001F05BB870B55C +:103EE0006B4D6A4C6879A43400B102206870214699 +:103EF0002878FFF772FF674928780A68A17C92F852 +:103F0000463163F30101A17492F84621920862F3ED +:103F10008711A1746049085C94F85F1060F3040194 +:103F200084F85F106978204601F043FFA07C00F020 +:103F3000030001F047F8FFF79EFF2046BDE8704000 +:103F4000564901F06BBF70B5514D504C6879A4349F +:103F500008B1032000E00120687021462878FFF7AF +:103F60003CFF4C4928780A6892F846110B09A17C5D +:103F700063F30101A17492F84621920962F387115B +:103F8000A1744549491D085C94F85F1060F3040171 +:103F900084F85F106978204601F00BFFA07C00F0E8 +:103FA000030001F00FF8FFF780FF2046BDE87040E6 +:103FB0003B4901F033BF2DE9F041364E88B03568FA +:103FC00005F25E6500F096FFCDE9040100F097FF71 +:103FD000CDE90601082104A802F040F82C4C082184 +:103FE000A07006A802F03AF82B4FE070012407F108 +:103FF0000508306890F88C1A90F8CE3801F0070266 +:10400000C1F3C0010093CDE9011290F8CF1890F8E8 +:10401000542690F8550605EB410305EB4001E0B24C +:10402000FFF7FBFC3855306890F88C1A90F8D038C0 +:10403000C1F30212C9090093CDE9011290F8D11819 +:1040400090F8562690F8570605EB410305EB400122 +:10405000E0B2FFF7E2FC08F80400641C052CC8DBA2 +:104060000A48FFF73DFD08B0FCE610B5807940B185 +:10407000074908704FF0FF30C860FFF70DFC0020C3 +:1040800010BD012010BD0000587A0120848A100064 +:1040900080071000D8061000088001209F3801001A +:1040A0003539010010B9714A6F49116100F0AEBE97 +:1040B00070B56F4D0446286890F8F101C0F3011205 +:1040C000C0F3810100F00300FDF7FAFF401CC6B207 +:1040D000204600F033FC644801F046FBA4F876006B +:1040E00000223146204601F045FDA07940F0020053 +:1040F000A07194F86F0066F3020084F86F0094F8E2 +:104100006E0020F00F0084F86E002968A07C91F802 +:10411000082162F30100A07491F80821920862F36B +:104120008710A074A0896FF30B00A08191F807019C +:10413000A07094F85E00002120F0010084F85E0079 +:10414000204601F0B3FB286890F8F21184F866105D +:1041500090F8F31184F8681090F8F41184F86A105C +:1041600090F8F50184F86C003F4894F85F10001F48 +:10417000407860F3040184F85F102046BDE8704089 +:1041800000F032BF10B5384C0020241F20800120E1 +:1041900000F02FF86070BDE81040364888E72DE940 +:1041A000F041344E407910B3B07C00F0030000F0D1 +:1041B00009FF2F4F3C6804F25E6094F84F2604F626 +:1041C000D80594F84E1600EB420000F0CCFE38689B +:1041D00090F8C81890F8C90805EB400000F0DAFE26 +:1041E0002549304601F006FD0020BDE8F0810120A0 +:1041F000FBE730B51E494FF480750A6892F8071145 +:1042000092F8F43092F8F14003F01F0304F00F0429 +:10421000A94200D929461F2B00D91F235B1C5943F3 +:104220004900641C6143C1EB4121C91392F8873AEC +:10423000B1FA81F1C1F120019B0713D500230128B8 +:1042400009D192F88B0A020703D500F00700434218 +:1042500001E000F00703C91801D5002102E01F2981 +:1042600000DD1F21C8B230BD60820120C88D100062 +:10427000D8061000CC8B1000554001002DE9F05FEE +:10428000DFF8A48583464FF00109D8F80000002725 +:10429000ABF1020100F25E64CA46062950D2DFE8A3 +:1042A00001F04F092C4F2C0310F8D46F007900F067 +:1042B0001F056DE090F8F41090F8026101F01F0501 +:1042C00090F8F11001F00F0790F8E610890609D573 +:1042D00090F8501690F851060A2204EB400000F0C6 +:1042E0001FFE8146D8F8000090F8E61049064FD529 +:1042F00090F8CA1890F8CB0844E090F8FC1090F8B9 +:10430000F86001F01F0590F8F91001F00F0790F820 +:10431000E610890609D590F8521690F853060A223D +:1043200004EB400000F0FCFD8146D8F8000090F856 +:10433000E61049062CD590F8CC1890F8CD0821E06D +:1043400090F8F41090F8F06001F01F0590F8F1106B +:1043500001F00F0790F8E610890609D590F84E167F +:1043600090F84F060A2204EB400000F0D9FD814688 +:10437000D8F8000090F8E610490609D590F8C8185A +:1043800090F8C9080A2204EB400000F0C9FD8246FB +:104390004FF48070864200D906461F2D00D91F2594 +:1043A0006D1C6E4370007F1C7843C0EB402000FB07 +:1043B00009F000FB0AF0C013D8F80020B0FA80F032 +:1043C000C0F1200192F8870AC00725D00020BBF178 +:1043D0000A0F13D2DFE80BF01205080B16121212A7 +:1043E000120592F8880A04E092F8880A0CE092F824 +:1043F000890A020700F0070000D54042091808D5D5 +:10440000002109E092F8890A0206C0F30210F4D4F0 +:10441000F4E71F2900DD1F21C8B2BDE8F09F70B589 +:10442000060003D0BDE8704000F0F0BC00F018F8C2 +:10443000012814D1FD4DFE4C2878012809D0FD48F3 +:10444000A0606878E073E878A0732889A08130467E +:10445000E8E76A792979F74800F0F1FDF0E770BDE7 +:10446000F24B10B5D978F44C491CCAB2DA7099787D +:1044700001208A420ED8197958794143ED48FDF759 +:104480003EFE01F071F9A4F87600EC49204601F0F7 +:10449000B1FB002010BD38B5044601F060F9E548D5 +:1044A00001F062F9A4F8760000F024FDDE4D0B4621 +:1044B0002A6892F8E720C2F3411200920246204691 +:1044C00001F037FB00F01BFD02460B46204601F0D1 +:1044D0005CFBA07920F00200A07194F86F0020F03E +:1044E000070084F86F0094F86E0020F00F0084F845 +:1044F0006E00286890F8E700C0F34111204601F0F3 +:104500005EFB286890F8E70010F0600F94F85E00FA +:104510007ED040F0010000BF84F85E00204600F02D +:104520009DFD0521204601F04AF9286890F8F00029 +:10453000A0702868218EB0F8F62062F30801218669 +:1045400090F8F10000F00F01204601F0AFF9286863 +:10455000627D90F8EA1061F303026275B0F8EC2016 +:10456000218A62F30B01218290F8F210A27D61F39F +:104570000302A27510F8F11F0A09A17C62F3010180 +:10458000A17410F80B29920962F38711A1740178C4 +:10459000E27961F30002E271C17861720079010988 +:1045A000204601F08FF9A64801F0DEF8A4F87C005F +:1045B000296811F8E80F820814F8270F62F38300C6 +:1045C000207011F8012962F3000020704A78520827 +:1045D00062F34100207008780109607861F30410EB +:1045E0006070984801F0C0F8A4F85F00286810F8DF +:1045F000E61FCA0814F80C1F62F3451104F80B19E2 +:104600004078217860F3451104F82819204600E02D +:104610005CE000F0E9FC286890F8E700C0F3410195 +:10462000204601F01DF9286810F8E61F8A0914F8E1 +:10463000331F62F3000104F80B190278520962F388 +:104640004101E172417B627961F304026271807B16 +:10465000217960F304017C48217194F83710407887 +:1046600060F3040184F83710784801F07DF8A4F86D +:104670005200286834F8061FB0F8EE2062F30B01F0 +:1046800024F8061B10F8E21F14F80A2C61F3030249 +:1046900004F80A2C01780A0914F8091C62F30301D2 +:1046A00004F8091C01798A0814F80C1C62F3000153 +:1046B00004F80C1C0079C109207861F3000004F8AB +:1046C0002B0B207840F02000207038BD20F0010036 +:1046D00022E738B5044601F042F8564801F044F8A4 +:1046E000A4F8760000F006FC4F4D0B462A6892F8BD +:1046F000C920C2F3411200920246204601F019FA85 +:1047000000F0FDFB02460B46204601F03EFAA07980 +:1047100020F00200A07194F86F0020F0070084F8E8 +:104720006F0094F86E0020F00F0084F86E00286887 +:1047300090F8C900C0F34111204601F040FA286802 +:1047400090F8C90010F0600F94F85E006BD040F054 +:10475000010000BF84F85E00204600F07FFC28685E +:1047600090F8D400A0702868218EB0F8DA2062F3A7 +:104770000801218690F8D50000F00F01204601F0D5 +:1047800095F82868627D90F8CC1061F30302627599 +:10479000B0F8CE20218A62F30B01218290F8D61066 +:1047A000A27D61F30302A275B0F8D020A18962F363 +:1047B0000B01A18110F8D51F0A09A17C62F3010148 +:1047C000A17410F80D29920962F38711A174017880 +:1047D000E27961F30002E271C17861720079010946 +:1047E000204601F06FF8164800F0BEFFA4F87C00E8 +:1047F000296811F8CA0F820814F8270F62F38300A2 +:10480000207011F8012962F3000020704A785208E4 +:1048100062F34100207008780109607861F30410A8 +:104820006070084814E086E0D80610009007100079 +:10483000C88D100090830120148D1000CF4301001B +:10484000A06D0120C87D0120929C0120587A012092 +:1048500000F08AFFA4F85F00286810F8C81FCA0893 +:1048600014F80C1F62F3451104F80B1940782178F5 +:1048700060F3451104F82819204600F0B5FB2868BC +:1048800090F8C900C0F34101204600F0E9FF296813 +:1048900011F8C80F820914F8330F62F3000004F80E +:1048A0000B090A78520962F34100E072C87B627911 +:1048B00060F304026271087C217960F30401F54819 +:1048C000217194F83710C07960F3040184F837102F +:1048D000F14800F049FFA4F85200286834F8061F98 +:1048E000B0F8D22062F30B0124F8061B10F8E21F87 +:1048F00014F80A2C61F3030204F80A2C10F81A19B0 +:104900000A0914F8091C62F3030104F8091C017870 +:104910008A0814F80C1C62F3000104F80C1C0078DF +:10492000C109207861F3000004F82B0B207840F0D7 +:104930002000207038BD20F001000BE710B50446C0 +:10494000A422D64902F0F7FDD548C178A08961F3C9 +:104950000B00A08110BD38B50446FFF7EFFF00F053 +:10496000C9FA0022009202460B46204601F0E1F807 +:10497000CC4800F0F9FECC4DA4F87C00286890F8F3 +:10498000F800A070286890F8F90000F00F012046A8 +:1049900000F08CFF286810F8F91F0A09A17C62F367 +:1049A0000101A1740278920962F38711A1748178E0 +:1049B00094F82D2061F3040284F82D20C17894F836 +:1049C0002C2061F3040284F82C204078A17D60F350 +:1049D0000301A1750021204601F0F1F814F85E0FE3 +:1049E00020F0010004F8010BAA480179207861F356 +:1049F000040004F82F092868B0F8FE10208861F33D +:104A00000800208038BD70B5A74E0328346804F232 +:104A10005E6204F6D80515D0042821D094F84F061C +:104A200094F84E1602EB400000F09DFA306890F8C2 +:104A3000C81890F8C90800BF05EB4000BDE87040F9 +:104A400000F0A8BA94F8510694F8501602EB400012 +:104A500000F089FA306890F8CA1890F8CB08EBE7B4 +:104A600094F8530694F8521602EB400000F07BFADB +:104A7000306890F8CC1890F8CD08DDE72DE9F843C0 +:104A80008A4D4FF00109002685F80090AE70814FE5 +:104A9000DFF814820446EE700A2976D2DFE801F0CE +:104AA0007505091848334C62662F2046FFF746FF0C +:104AB0006BE02046FFF742FFB87894F85F1060F390 +:104AC000040184F85F10D8F8000090F8000112E0AB +:104AD0002046FFF733FFD8F8001091F80211A170BB +:104AE000F97894F85F2061F3040284F85F20D8F825 +:104AF000000090F8010100F00300A87045E0204696 +:104B000000F09DF841E02046FFF718FF0021204605 +:104B100000F0CCFE94F85E0020F0010084F85E0006 +:104B2000787994F85F1060F3040184F85F1017E05F +:104B30002046FFF710FF28E02046FFF70CFF00217A +:104B4000204600F0B3FEB87994F85F1060F30401DA +:104B500084F85F1094F85E0020F0010084F85E0095 +:104B60002E7012E02046FFF7B4FDF9E72046FFF76C +:104B7000E5FE012200232046009600F0DAFF2046E1 +:104B800000F0ADFA204600F02FFA94F82700C00795 +:104B900001D06E7001E085F80190A089C0F30B0090 +:104BA0002881BDE8F8832DE9FF4100F0A3F9CDE9A4 +:104BB000000100F0A4F9CDE902010821684601F0E6 +:104BC0004DFA3A4D0821287102A801F047FA6871A0 +:104BD00030480026801E2F4F40F8026F01244660A7 +:104BE0000681E0B2FFF74AFB3855641C0A2CF8DB5B +:104BF0002A48FFF750FCAE71BDE8FF8170B5274D24 +:104C00000479A4358CB121462846FFF737FFA87CEC +:104C100000F0030000F0D6F92046FFF7F4FE244927 +:104C2000284600F0E7FF002070BD012070BD40F273 +:104C3000FF10C1EB412191FBF0F00020704770B5EF +:104C40000446FFF77BFE1848184A016801F5F9731E +:104C500091F8F10100F0030592F90600854206DBA8 +:104C60001D5CA389401C65F30B03A381907191F82F +:104C7000F10192F9061000F00300884201DA0020E9 +:104C80009071044814F85F1F407A60F304012170AA +:104C900070BD0000929C0120587A0120708C100099 +:104CA00010071000C8720120D806100090071000ED +:104CB000CF43010010B500F05FFAFFF774FFFFF774 +:104CC00061FAFFF778F9FEF729FDFEF79EFD7149BD +:104CD000002048607021704802F0ACFC6F48016809 +:104CE00091F8E700C00607D5BDE8104028226A48C1 +:104CF00001F65A1102F01FBC10BD38B1012807D0CF +:104D0000022807D017200021FCF79FBA1420FAE7E9 +:104D10001520F8E71620F6E7002101604160816068 +:104D2000C160704770B55B4C5D4D206809E000BF05 +:104D300055F820105B488847002811D02068401C97 +:104D400020600728F4D360685649401C10310022C7 +:104D500060600A704860534801681030884701203D +:104D600070BD70B504460079002540B9E07930B9CE +:104D7000A07920B9207A10B9607900280ED049486E +:104D80004021103002F078FC1ECC464880E81E001E +:104D9000404805604348FFF7C5FF012070BD10B5CE +:104DA000012000F060F8072000F05DF8082000F016 +:104DB0005AF8052000F057F80D2000F054F80C20A8 +:104DC00000F051F8012000F059F8072000F056F8E3 +:104DD000082000F053F8052000F050F80D2000F0F6 +:104DE0004DF80C2000F04AF802F0BFF800F0AFFCDC +:104DF000012000F02DF8072000F02AF8082000F02C +:104E000027F8BDE81040052000F022B870B5214C0D +:104E100005000ED0FFF7C3FF60682249401C103127 +:104E200060600D7048601F480168BDE87040103038 +:104E300008472068401C2060BDE87040194871E7B1 +:104E400000F058B800F05BB800F05EB800F062B84F +:104E500000F01F02012191404009800000F1E02094 +:104E6000C0F80011704700F01F0201219140400975 +:104E7000800000F1E020C0F88011704700F01F02B0 +:104E8000012191404009800000F1E020C0F880122B +:104E9000704700009C071000C87D0120D806100054 +:104EA000B47B0100B88D100070B50023144609E0F2 +:104EB00031F9135031F9146035446D1020F8135056 +:104EC0005B1C641C9342F3DB70BD30B400244BB90F +:104ED0000CE000BF30F8143031F814502B4420F8A7 +:104EE0001430641C9442F5DB30BC704730BC520077 +:104EF00002F021BB99480068C16A806A70479748F0 +:104F00000068416A006A70479448006800F67C2097 +:104F100003C870479148006800F6742003C87047C2 +:104F2000F0B5002425468E4E4FF4006714E000BF14 +:104F300030F81530C3F30B035FEAD32C00D03343B2 +:104F4000002B00DA5B429C4200DA9CB2BC4202D3E6 +:104F500040F2FF7402E06D1C8D42E9DBD440012079 +:104F6000A04080B2F0BD30B57F4B7E4C5A68824283 +:104F700002D1DA688A420AD0002206E030F81250E4 +:104F8000C5F30B0524F81250521C8A42F6DBD96097 +:104F9000586030BD30B5744B744C9A68824202D16F +:104FA0001A698A420DD0002207E000BF30F8125083 +:104FB000C5F30B0524F81250521C8A42F6DB196126 +:104FC000986030BD70B504466948016802290AD16D +:104FD000654D29788C4206D000EB8400D0F89C0007 +:104FE00000F0D5FB2C7070BD10B5044690F8280079 +:104FF000800604D55F4800F0B7FBA4F88C0010BD14 +:1050000010B5044690F8280080060AD55948283083 +:1050100000F0AAFB24F88E0F5648483000F0A4FB9D +:10502000608010BD10B5044690F82800800605D5B4 +:105030005048703000F098FBA4F88E0010BD704707 +:105040007047704702004FF0000000D108467047DB +:1050500002460020012A00D1084670473F490A68ED +:1050600092F8B020930910F83E2B63F3820200F807 +:105070003E2C0B6893F8B0305B0963F3451200F8DF +:105080003E2C0968B1F8B720028291F8B620837FE0 +:1050900062F30713837791F8B3201309027D63F35A +:1050A0000612027531F8B13F028B63F309020283E5 +:1050B00011F8012C9308827D63F3861282758A7839 +:1050C000C37D62F30303C375B1F80330B0F81B204E +:1050D00063F30802A0F81B2009894182704710F889 +:1050E000371F41F0100100F81F1930F80C2CC17E59 +:1050F0006FF30B02103220F80C2C30F8082C21F042 +:1051000023016FF30B02403220F8082C082200F82C +:10511000162C90F8472041F00C0122F01F0280F875 +:105120004720028B6FF308020283C176C18A6FF3B6 +:105130000B013F31C182417D21F01F014175017D8D +:1051400021F01F01017590F8461021F0010180F84F +:105150004610017C41F0200101747047D806100010 +:1051600000F0FFFF587A0120A4071000587C0120AE +:10517000088E1000387D0120704710B500F09BFDAF +:1051800008B1012010BD084800F07EFD002010BDD0 +:10519000064810B5006890F87000400701D500F08F +:1051A0007FFD012010BD0000BD4D0100D80610009C +:1051B0003D48016821F00401016000F00FBF10B507 +:1051C000FFF7F6FF10BD10B5FFF7F2FF10BD10B5E9 +:1051D000FFF7EEFF10BD10B5FFF7EAFF01F093FCFB +:1051E00010BD10B5FFF7E4FF00F0DEFA10BD10B5FA +:1051F000FFF7DEFF01F09DFD10BD10B5FFF7D8FFF2 +:1052000001F002FE10BD10B5FFF7D2FF01F067FEFE +:1052100010BD10B5FFF7CCFF01F0CEFE10BD10B5EC +:10522000FFF7C6FF01F047FF10BD10B5FFF7C0FF45 +:1052300001F0AEFF10BD10B5FFF7BAFF02F015F890 +:1052400010BD10B5FFF7B4FF02F0EEFA10BD10B5B7 +:10525000FFF7AEFF02F0C4FA10BD10B5FFF7A8FFCC +:1052600010BD10B5FFF7A4FF10BD10B5FFF7A0FFEC +:1052700010BD10B5FFF79CFF02F03EF810BD10B551 +:10528000FFF796FF10BD10B5FFF792FF10BD10B5E8 +:10529000FFF78EFF10BD10B5FFF78AFF10BD10B5E8 +:1052A000FFF786FF10BD704710ED00E00EB50BA2B2 +:1052B00007CA8DE807000C4800F039FE684600F088 +:1052C0003AFEFCF76BFDFCF7C1FB00F037F800215C +:1052D0004720FBF7BAFF01200EBD000001000000CF +:1052E0000000000000000000670058231A4910B5B4 +:1052F00001200870194900200860194908601949FF +:1053000008601949086000F07FF900F019F900F011 +:105310007DF8002010BD10B5124802F07FF810494A +:1053200008600E490968884207D00B4800780228B7 +:1053300003D1BDE81040EBF719B810BD10B5FFF769 +:10534000EAFF054902200870EAF7F4FF4FF0FF304A +:1053500010BD012070470000000810000408100074 +:10536000080810000C0810001008100070B50D4659 +:105370000446C1698068CC2202F054F9E169A06852 +:10538000002208444FF0807140F8041C216A40E973 +:10539000032140F8102C40F8142C40F8182C40F849 +:1053A0001C2C4FF00B3140E909154FF00A3140F841 +:1053B000281C4FF0093140F82C1C4FF0083140F800 +:1053C000301C4FF0073140F8341C4FF0063140F8E4 +:1053D000381C4FF0053140F83C1C4FF0043140F8C8 +:1053E000401D70BD81694FF0CC330A689A4208D1E4 +:1053F0004A689A4205D18A689A4202D1C96899429C +:1054000002D04068FCF769BB7047000010B5A021CE +:10541000494802F031F9002010BD70B506464648F3 +:1054200000EB0614EAF7DAFF0546207828B1284693 +:10543000EAF7DCFF6FF0010070BD03202070002050 +:105440006660E06004F1080001F0C2FF2846EAF758 +:10545000CDFF002070BD2DE9F0410F4636490025F3 +:1054600001EB00142E46EAF7B9FF8046E0683843A6 +:10547000E06004F10800074601F0D0FF0CE0E168AD +:10548000C26A114203D000F00FF9012600E06D1C42 +:105490002946384601F0B8FF0028F0D10EB1FFF7D9 +:1054A0003AFF4046EAF7A2FF0020BDE8F08170B560 +:1054B0000D46214901EB0014EAF790FFE168A9438A +:1054C000E160EAF793FF002070BD70B50C461A4901 +:1054D00001EB001500202060EAF780FFE9682160F9 +:1054E000EAF784FF002070BD2DE9F0410D46124916 +:1054F0001E46904601EB0014EAF770FF07460F487E +:105500000068C562E168294203D104F1080100F096 +:10551000DDF83846EAF76AFFEAF760FFE1682940FC +:105520003160B8F1010F02D1E168A943E160EAF707 +:105530005DFF0020B9E70000B48E100004081000E1 +:1055400010B5C8212E4802F097F8002010BD2DE9B3 +:10555000F04106462A4900EB8600174601EB80041D +:10556000EAF73CFF0546207830B12846EAF73EFFCF +:105570006FF00100BDE8F08102202070002066601D +:10558000C4E9027004F1100001F022FF2846EAF796 +:105590002DFF0020EEE770B5194900EB800001EB0C +:1055A0008004EAF71BFF0546D4E90201814205DBCE +:1055B000144804F11001006800F088F8E068401C0D +:1055C000E0602846EAF712FF002070BD70B50C4974 +:1055D00000EB800001EB8004EAF700FF0546E0687D +:1055E00008B1401EE06004F1100001F017FF10B197 +:1055F000206900F011F82846EAF7F8FE002070BD97 +:10560000548F10000408100010B54FF4F0713C489E +:1056100002F032F8002010BD10B5044690F82400C6 +:1056200002280BD0204601F0FBFE022084F8240063 +:105630003449204601F0D0FEFFF76DFE002010BD7A +:105640002DE9F05F06460AA806EB460190E8000E39 +:105650002B481D4600EB01149046207818B16FF0DE +:105660000100BDE8F09FEAF7B9FE0746012020706F +:10567000C4F81480C4E9016504F11801002081E830 +:10568000200684F82400E0602061C4E90A805946BD +:105690002046FFF76BFEA0602046FFF7BDFF3846AF +:1056A000EAF7A4FE0020DCE710B5044690F82400D9 +:1056B000022809D0204601F0B3FE022084F824001D +:1056C0001049204601F088FE002010BD70B5044648 +:1056D00090F824000D4602280BD1204601F0A0FED0 +:1056E000032084F824002946204601F075FEFFF7C8 +:1056F00012FE002070BD044800684068704700003A +:105700001C9010000C08100004081000724810B51E +:1057100000210160012202600160704C6920A071CB +:105720000420EAF76DFE0820A07110BD10B5FFF748 +:10573000EDFF6B4800210170416000F0F6F9BDE813 +:10574000104000F0E2BA01F0FCBC01F067BD10B5FA +:1057500001F064FD01F0F5FCBDE81040E6E7A4228D +:10576000604901F0E8BE704710B50446800702D0DA +:105770000220FFF7C2FA4FF480302044C0F34F00FC +:1057800010BD014655489822A43001F0D4BE534ABA +:10579000A432002142F82100491C2629FADB704777 +:1057A00001F019BD01F097BC4D4810B5406810B12B +:1057B000BDE8104000470020FFF79FFA10BD062902 +:1057C00037D2DFE801F0112437243603017821F0C5 +:1057D000120100F84D1B017821F0030100F8071BAE +:1057E000017821F080010CE0017821F0020141F004 +:1057F000100100F84D1B017821F0030100F8071B90 +:1058000012E000F8441B017821F0010110E0027859 +:10581000012942F01202027000D0032110F84D2F2E +:1058200061F3010200F8072B017841F08001E8E7FD +:1058300001707047017821F0020141F0100100F879 +:105840004D1B017821F00301891C00F8071B01782A +:1058500041F0800100F8441B017841F00101E7E7C5 +:1058600090F82920022904D0032922F0400102D116 +:1058700004E042F0400121F0800101E041F08001AC +:1058800080F82910704790F82920012904D00229B6 +:1058900007D022F0100101E042F0100121F02001B8 +:1058A00001E042F0300180F829107047C2780029E9 +:1058B00061F30302C27004D010F85E1F41F00401CE +:1058C00001707047C27A012961F30302C27202D9E2 +:1058D00042F01001C17270479004002200000320C2 +:1058E000B8071000D07B010001EB810102EBC10180 +:1058F000405C010602D500F07F0040427047002B5B +:1059000004DA5B42DBB243F0800301E003F07F0383 +:1059100001EB810102EBC101435470472DE9F05FB7 +:105920000025DDE90A7891469A4683462E462A46A6 +:105930000120002101F0C8FD00EA090001EA0A0186 +:10594000084314D0002422460120002101F0BCFDB0 +:10595000384001EA0801084305D0002322463146B9 +:105960005846FFF7CCFF641C282CECDB761C6D1C22 +:10597000382DDCDBBDE8F09F405C010602D500F06D +:105980007F0040427047002A04DA5242D2B242F00D +:10599000800201E002F07F0242547047F0B500241B +:1059A00015460E468446234601270FE006EBE3002A +:1059B00003F00701007807FA01F2024205D0002245 +:1059C00019466046FFF7DFFF641C5B1CAC42EDDB51 +:1059D000F0BD405C704742547047F0B50024234648 +:1059E00001260DE001EBE30503F007072D7806FA29 +:1059F00007FC1CEA050F02D00025C554641C5B1C83 +:105A00009442EFDBF0BD405C704742547047405C0D +:105A100070474254704700002DE9F047334C54F86A +:105A20003C8F6768E668257CDFF8C4900121C9F8DF +:105A300000104FF42070EAF7E3FC0021C9F80010D1 +:105A4000C4F800806760E6602574BDE8F0872748E9 +:105A50000021C1630164816480F84C10704770B507 +:105A600000240D4602460120214601F02DFD35B3EC +:105A70001E4A483210601171FFF7CEFF002000F07F +:105A800023F800B10124FFF7C7FF012000F01CF844 +:105A900008B144F00204FFF7BFFF022000F014F841 +:105AA00008B144F00404FFF7B7FF032000F00CF83E +:105AB00008B144F00804FFF7AFFF204670BD0B4A61 +:105AC0003C32C2E90001D7E740F02001074810B599 +:105AD00080F8A310E52181714FF42070EAF790FC63 +:105AE0000448D0F8C002C0B210BD0000000003207E +:105AF000681460220010602253480168002901D018 +:105B000001200847704710B5FFF71FFE4F490220DC +:105B100008704F49002008604B480168002903D0F5 +:105B2000BDE810400020084710BD4749002008602C +:105B300070477FB504460399089DC1F31401039192 +:105B4000082102A800F08AFA012D02D0022D04D00B +:105B500006E0C01C20F0010002E0C01D20F00300A0 +:105B6000DDE9021244F83C1F6260217A60F306010D +:105B700021727FBD012340F83C3F00234360514325 +:105B8000027A61F30602027270471FB50446039958 +:105B900002A801F03F010391082100F05FFADDE95E +:105BA0000212A16484F84C2014F8701F60F3050100 +:105BB00004F81E19E17F60F30501E1771FBD08B508 +:105BC00024A2126800921DF8012010F85D1F62F3F4 +:105BD0000101017008BD1D49032008701C491E48C1 +:105BE00008601E490120C1F8C0001D494FF4FA7039 +:105BF000FFF7D6BD10B50B46817921F00D0141F0BC +:105C0000E0018171817C8A091BD08A0962F38711C6 +:105C100081740D490D4A0B60032111700C4A0E4925 +:105C200011600146A4220F4801F085FC0B490120B8 +:105C3000C1F8C000BDE8104009494FF4FA70FFF701 +:105C4000AFBD0122E2E70000C0071000B807100056 +:105C5000BC07100000010200B75A010000006022DA +:105C6000A95A01000000032016480178012908D133 +:105C7000022101701448016819B100220260104627 +:105C800008470120FFF739B80E4A012111700E496B +:105C900008600E49E82088710D490C20FFF782BD8D +:105CA0000A49082088710B490020086205490870DC +:105CB00005490860704703480078002800D001209B +:105CC00070470000B8071000C40710000000032050 +:105CD000195C01000000602268480168002901D0B9 +:105CE00001200847704710B5FFF72FFD64490220D7 +:105CF000087064490020086060480168002903D0EA +:105D0000BDE810400020084710BD5C490020086035 +:105D100070477FB504460399089DC1F314010391B0 +:105D2000082102A800F09AF9DDE90212E163226479 +:105D300094F84420C1B261F3060284F844200A2D8D +:105D40000FD00B2D0DD014F8720F61F305002070E9 +:105D5000607861F305006070A07820F00800A07002 +:105D60007FBD14F8721F401C60F30501217061783B +:105D700060F305016170A07840F00800EFE71FB5FF +:105D80000446039902A801F03F010391082100F0A5 +:105D900065F9DDE90212A16484F84C2014F8701F43 +:105DA00060F3050104F81E19E17F60F30501E17756 +:105DB0001FBD30B534A28CB03CCA8DE83C0036A281 +:105DC0000DF1100C3CCA8CE83C0037A20DF1200C00 +:105DD0003CCA8CE83C0004AA535C427E63F3050293 +:105DE00042761DF80130027E63F34202027608AA71 +:105DF000525C817962F3830181710CB030BD20491E +:105E0000042008701F492C4808602C490120C1F863 +:105E1000C0002B494FF4FA70FFF7C2BC10B50B4617 +:105E2000B0F8561041F00101A0F85610817C8A09A3 +:105E300021D08A0962F3871181748179104A21F097 +:105E4000010141F0E00181710C490B6004211170E6 +:105E50000C4A194911600146A4221A4801F06BFB53 +:105E600016490120C1F8C000BDE8104014494FF4A4 +:105E7000FA70FFF795BC0122DCE70000C8071000AC +:105E8000B8071000BC071000000002020101030364 +:105E900003030002000000000202020202020202EA +:105EA00001010202010100000203020302030203D6 +:105EB0000203020202030000975C0100000060225E +:105EC000895C0100000003204E4901200860172270 +:105ED000410701F8272F0B2281F841204949183941 +:105EE00008604FF00851C1F8C403464B0022B0339C +:105EF0001A60454A1060121D1060424A943A1060C0 +:105F0000C1F86803C1F8740370473E490120943911 +:105F1000086070473B4900209439086070474FF093 +:105F20000050008870474FF00050807870474FF065 +:105F3000005148607047354902680A6042684A600B +:105F400080688860704731490A6802604A68426028 +:105F50008968816070472B4901203039086070479B +:105F60004FF0005010F8221F21F00301017070471C +:105F70004FF0005303F81F0F5970987862F3030035 +:105F80009870704722480068704721490860704740 +:105F900010B54FF00054E27E202322F0AF0203EA56 +:105FA00040131343042202EA8000034301F003007C +:105FB0000343E37610BD4FF0005090F8220010F03C +:105FC000030005D0012805D0022805D011487047EC +:105FD0001148704711487047114870477047704723 +:105FE00010490120C1F8DC0070470E490020C1F8BB +:105FF000DC0070470348F030006808B101207047AA +:1060000002207047CC040022801E002208000020DD +:10601000CC07100000127A000090D0030048E8017D +:106020000024F40000006022F0B50746002003467B +:106030002F4E10E057F8235003224FEAC20C45FAC6 +:106040000CF484EA2064E4B2521E56F8244084EA38 +:106050000020F2D55B1C8B42ECDBF0BD30B5044672 +:10606000234B0020103B08E0625C02F00F0503EBBD +:1060700012125D5D127828441044491EF4D230BDDE +:1060800010B584680368E443A3420AD1C468436836 +:10609000E443A34205D15B1C0B6000681060012043 +:1060A00010BD002010BD3CB50446002501AA69467C +:1060B000FFF7E6FF012809D1009904F11000091F3C +:1060C000FFF7B2FF0199884200D1012528463CBD67 +:1060D00030B50D460446091F1030FFF7A5FF6D1EB1 +:1060E0006560E943E1602060C043A06030BD00000E +:1060F000847C010001468000B1F5803F02D2103857 +:10610000C0F310007047C0F387207047B0F5802FB0 +:1061100002D21030C0F31000C0F38F00704730B5CA +:10612000FE4C01252560E50603F01F0385F86B3062 +:10613000002304E051F8235040F823505B1C9342A5 +:10614000F8DB0020206030BDF0B5F44F01233B6048 +:106150005C0784F86B309B1E0360002312E051F84B +:10616000234040F82340002450F8235051F8236086 +:10617000B54206D06D1C04D1641C40F82360032C8A +:10618000F2D35B1C9342EADB00203860F0BDF0B52F +:1061900013460A460546002498184FF483266028C3 +:1061A00001D9012411E0002107E05F1856F827000B +:1061B000401C01D011460224491C9142F5D324B958 +:1061C00006EB83002946FFF7BFFF2046F0BD10B560 +:1061D00003460846FFF78EFF0146BDE810409200D7 +:1061E000184601F0EDB92DE9F0414FF000580C468A +:1061F000D8F814700125C0F38F066FF48041C8F8F9 +:1062000014100E2000F013FA204600F01BFA0200D2 +:10621000C3484FF0010118D00160A4F58034404616 +:1062200020F8726F4480602200F8012CBD4A116092 +:10623000BB4AC432116030BF81797238890700D0FF +:10624000002547612846BDE8F08100220260E6E7AC +:106250002DE9F05F1546DFF8C4B2002601270A4693 +:1062600004464FF0005CB1F5882F15D3A30AFFF761 +:1062700041FF5946CBF8007003F01F038CF86B30D8 +:10628000002304E052F8234040F823405B1CAB425B +:10629000F8DB0E60BDE8F09FDCF81490C1F38F08C6 +:1062A000E2466FF48041CCF814100E2000F0BFF9E4 +:1062B000CBF80070204600F0C5F90100984819D0CD +:1062C0000760A4F58034AAF87280AAF874406D1EA5 +:1062D000AAF8765040218AF8711092490E609049D0 +:1062E000C4310F600AF1520030BFCBF8006040F8B3 +:1062F0003E9CCFE70660E6E72DE9F0414FF0005401 +:106300000F4654F8146F85086FF4804020600E200B +:1063100000F08DF90020A066A4F85E507F1EA4F85E +:10632000627084F85D007F4908607D490120C431B6 +:10633000086030BFE06E266085E770B506460C4603 +:1063400001F11000111F154689B2FFF7D5FF20603B +:10635000681E606020682A46C043A06060682146CD +:10636000C043E0603046BDE8704071E7F0B50746D5 +:10637000002004466C4E15E057F8245003234FEAE2 +:10638000C30C45FA0CF280EA02600822002802DA07 +:1063900086EA400000E04000521E002AF6DC5B1E48 +:1063A000EDD5641C8C42E7DBF0BD30B550F8084BEE +:1063B00050F8085B30F80C1C491C89B2FFF7D6FF77 +:1063C000844204D1E043854201D1012030BD002048 +:1063D00030BD2DE9F0410126750704466F696FF461 +:1063E000804068610E2000F022F94FF00008C5F8E7 +:1063F0007C80204600F026F9020049494FF0010058 +:1064000015D00860A4F58034A5F87440202185F8E3 +:106410007110444908604249C431086030BF95F8A2 +:106420007800800700D000266F6130460BE7C1F886 +:106430000080E9E700B50B46FFF75CFE8268016863 +:10644000D243914208D14268C068C043824203D11E +:10645000521C1A80012000BD002000BDF8B5044682 +:1064600010300D460646FFF7BEFE012801D0002081 +:10647000F8BD69462846FFF7DDFFBDF80000001FA4 +:1064800081B23046FFF738FF2060BDF80010C043EE +:10649000491E6160A060C843E0600120F8BDF0B50E +:1064A000B1B007466D46214E0124C021284601F0B7 +:1064B000E3F8002056F8201045F82010401C302842 +:1064C000F8D31B490098884210D1029881B205A8E0 +:1064D0000446FFF74BFF0199814206D1AC222146C9 +:1064E000384601F06DF8002400E0032431B0204666 +:1064F000F0BD70B594B004466D460E4E502128464E +:1065000001F0BAF8002056F8201045F82010401C81 +:106510001428F8D308486FF002050FE0C41B0022CE +:10652000780D00221C0F00221B000080481D040073 +:10653000B2570E70AC1E04005C000D6000998142E1 +:106540002ED1A81020606060A060E06020610298F9 +:1065500081B205A8FFF70AFF0199814220D1BDF859 +:10656000381045F2AA5081420CD19DF81D102160CF +:106570009DF81C1001F00F0161609DF81E1001F0E4 +:106580000F01A160BDF83C10814201D10899E16082 +:10659000BDF84010814201D10998206114B070BD4E +:1065A00025606560A560E5602561F7E770B586B098 +:1065B00004466D46274E1421284601F05DF800215F +:1065C00056F8210045F82100491C0529F8D3009808 +:1065D0002060019860600298C0B2A0600398C0B2C9 +:1065E000E0600498C0B2206106B070BD1CB5002008 +:1065F000184A0090843A6B460146019052F82140B7 +:1066000043F82140491C0229F8D3BDF80010A1F538 +:10661000AA42AA3A0AD1BDF80420114206D19DF837 +:1066200002109DF80620114200D108461CBD00F062 +:106630001F02012191404009800000F1E020C0F8D4 +:1066400080127047B0F5803F01D2002070470120D2 +:1066500070470000601F04004FF00050002180F8D8 +:106660003D1080F83E1080F83F103F2280F8322025 +:1066700000F8301F027141714270017241728172E3 +:10668000C172C17170474FF00052062817D2DFE87F +:1066900000F00306090F171A12F83D0F04E012F874 +:1066A0003D0F07E012F83E0F20F00F00084305E011 +:1066B00012F83E0F20F0F00040EA01101070704711 +:1066C00012F83F0FF0E712F83F0FF3E730B50D4631 +:1066D00001218140CCB20021FFF7D5FF29784FF08E +:1066E0000050002990F8321001D0214300E0A1436E +:1066F00080F832106978002990F8301001D02143D9 +:1067000000E0A14380F83010A978002990F83410F7 +:1067100001D0214300E0A14380F83410E97800293A +:1067200090F8351001D0214300E0A14380F83510E6 +:106730002979002990F8311001D0214300E0A143CC +:1067400080F83110002180F8381080F8391080F876 +:106750003A1080F83B1080F8371030BD774A11604E +:10676000764A002134321160121D08B11160704761 +:1067700001201060704730B501248440E0B24FF032 +:1067800000540029039D94F8321001D0014300E029 +:10679000814384F8321094F830100AB1014300E0CC +:1067A000814384F8301094F834100BB1014300E0B9 +:1067B000814384F8341014F8351F0DB1014300E013 +:1067C0008143217030BD01238340D8B24FF0005384 +:1067D000002993F8381001D0014300E0814383F889 +:1067E000381013F8391F0AB1014300E081431970D2 +:1067F000704701238340D8B24FF00053002993F82B +:106800003A1001D0014300E0814383F83A1013F8B5 +:106810003A1F0AB1014300E08143197070472DE926 +:10682000F04705460120A840C4B21F46914688465D +:106830000A20DDF820A000F06BF80B2000F068F8CB +:106840000A2000F070F80B2000F06DF84FF00056B1 +:1068500096F83800A04386F8380096F83A00A0432E +:1068600086F83A0096F82E00A04386F82E00344AA7 +:106870000020B8F1000F42F825000BD096F8381030 +:10688000214386F8381096F83A10214386F83A10DA +:1068900042F8257096F83910A14386F8391096F819 +:1068A0003B10A14386F83B1096F82F10A14386F8C1 +:1068B0002F1023492031B9F1000F41F825000BD0EA +:1068C00096F83900204386F8390096F83B002043BB +:1068D00086F83B0041F825A096F8380010B10A2050 +:1068E00000F00BF896F83900002804D0BDE8F04716 +:1068F0000B2000F002B8BDE8F08700F01F02012174 +:1069000091404009800000F1E020C0F8001170477C +:1069100000F01F02012191404009800000F1E020B9 +:10692000C0F88011704700F01F020121914040091A +:10693000800000F1E020C0F88012704704050022BA +:10694000FC9110002DE9F047417ACA074FF0000191 +:1069500001D0554A516001277D0785F8E57085F81B +:10696000E470C5F8C010C5F8E81085F8E11085F8A6 +:10697000E310DFF838A1067A04680AF10709072E48 +:1069800000D9072600216DE04A1CD3B201EB810239 +:1069900014F802800AF80180D0F804C022443CF8C0 +:1069A000118029F8118092F803C0BCF1010F02D0C8 +:1069B000BCF1030F07D195F8E5C007FA03F84CEADC +:1069C000080C85F8E5C090F809C05FEACC7C0FD1CF +:1069D00092F803C0BCF1020F02D0BCF1030F07D143 +:1069E00095F8E4C007FA03F84CEA080C85F8E4C00F +:1069F00001EB410C21F00108E04492F801C00CF0D9 +:106A0000070C0CFA08FCD5F8C0804CEA080CC5F855 +:106A1000C0C092F802C04FEA81080CF00F0C0CFACB +:106A200008FCD5F8E8804CEA080CC5F8E8C090F8F6 +:106A300009C05FEACC7C14D11279D20707D095F84F +:106A4000E12007FA03FC42EA0C0285F8E1202279F2 +:106A5000D20606D595F8E32007FA03F31A4385F822 +:106A6000E320491CB1428FD3D5F8E8006864BDE843 +:106A7000F0870E4AD21D22F81010704710B5044658 +:106A80000B48006838B1A068FFF75CFF2068BDE8DC +:106A9000104000F00FB8E068FFF754FF6068BDE8F1 +:106AA000104000F0D3BC000000200022AB0000200A +:106AB000BC05002210B54F4B016800249960818805 +:106AC000598002899A801C704FF00053A3F81A2154 +:106AD000A3F81E11C088A3F8200147480122C0F87E +:106AE000D821C0F8DC21C0F8C421C0F8CC21C0F8FE +:106AF000D421C0F8802172B6D0F808120029FBD149 +:106B0000426062B610BD2DE9F0413B4DD5F85C0105 +:106B1000384F2E040124BA6850B3B6F81C815FEADE +:106B200008000FD0D5F8540110B9D5F8000148B1CC +:106B3000414601209047C5F8D842D5F8540108B124 +:106B4000C5F8D442BA68414602209047017802292C +:106B500002D0032902D008E0418800E07988A6F835 +:106B60001E118088A6F81A013C70C5F8DC4238E096 +:106B7000D5F8440180B1B6F81C110320904738784D +:106B800038B17888A6F81E01B888A6F81A01002046 +:106B90003870C5F8C44224E0D5F8580130B1B6F8D1 +:106BA0001C1101209047C5F8D8421AE0D5F84C01D5 +:106BB00028B9D5F8540110B9D5F8000188B1B6F854 +:106BC0001C1119B101209047C5F8D842D5F84C01E5 +:106BD00010B1C5F8CC4204E0D5F8540108B1C5F8AD +:106BE000D442D5F80001002801D0C5F88042BDE8A4 +:106BF000F0810000D007100000200022F64900209C +:106C00000860091D0860091D0860091D0860091D4C +:106C10000860091D0860091D0860091D0860EF492A +:106C200001220A60ED4914310860510701F8500F44 +:106C3000FF234B7001F8050C10234B808A80E84934 +:106C4000086048608860C860086148618861C86100 +:106C5000086270477047E24A1160DF4900220A600B +:106C600000EB80004FF6FF7202EA40004FF0005246 +:106C7000A2F85800012008607047D94B10B5D64AD9 +:106C80001960002111604FF0005191F85140E40764 +:106C900007D01B6A58438009A1F8580001201060F2 +:106CA00010BD00EBC00303EB00104FF6FF7303EAC7 +:106CB0008000F1E74FF00050B0F8580070474FF0F7 +:106CC000005090F82200C0F3810028B1012805D0BF +:106CD000022805D0C3487047C3487047C34870476F +:106CE000C348704770B54FF0005494F85100BA494A +:106CF000C2074FF0000001D0086070BD656972B630 +:106D0000626942F0040262610860B4F8581009B187 +:106D1000A4F85800FFF74FF90146FFF7D0FFB1FB89 +:106D2000F0F0E9F76DFB6561022000F03BFB62B615 +:106D300070BDAB4810B5002104680160FFF7D2FFB9 +:106D40001CB1A446BDE8104060470020FFF782FF59 +:106D500010BDA34A5160A0490022091D0A6000EB42 +:106D600080004FF6FF7202EA4000CA06A2F85A00FD +:106D70000120086070479A4B10B55960964A00216F +:106D8000121D1160D10691F85140A40708D400EB00 +:106D9000C00303EB00104FF6FF7303EA800002E02C +:106DA0001B6A58438009A1F85A000120106010BDE9 +:106DB0004FF00050B0F85A00704770B54FF00054D3 +:106DC00094F851008B4982074FF000001AD465698E +:106DD00072B6626942F0080262610860B4F85A1043 +:106DE00009B1A4F85A00FFF7E6F80146FFF767FF7C +:106DF000B1FBF0F0E9F704FB6561032000F0D2FA83 +:106E000062B670BD086070BD754810B50021446859 +:106E10004160FFF7D2FF1CB1A446BDE810406047B7 +:106E20000120FFF717FF10BD6D4A916071490022E4 +:106E3000091D0A6000EB80004FF6FF7202EA400075 +:106E40008A06A2F85C00012008607047644B10B508 +:106E50009960684A0021121D1160910691F8514015 +:106E6000640708D400EBC00303EB00104FF6FF7378 +:106E700003EA800002E01B6A58438009A1F85C0025 +:106E80000120106010BD4FF00050B0F85C0070475A +:106E900070B54FF0005494F85100574942074FF035 +:106EA00000001AD4656972B6626942F0100262612C +:106EB0000860B4F85C1009B1A4F85C00FFF77BF837 +:106EC0000146FFF7FCFEB1FBF0F0E9F799FA6561C6 +:106ED000042000F067FA62B670BD086070BD4048DB +:106EE00010B5002184688160FFF7D2FF1CB1A44671 +:106EF000BDE8104060470220FFF7ACFE10BD384AE5 +:106F0000D1603D490022091D0A6000EB80004FF668 +:106F1000FF7202EA40004FF00052A2F85E0001202A +:106F2000086070472E4B10B5D960334A0021121DFE +:106F300011604FF0005191F85140240708D400EB44 +:106F4000C00303EB00104FF6FF7303EA800002E07A +:106F50001B6A58438009A1F85E000120106010BD33 +:106F60004FF00050B0F85E00704770B54FF000541D +:106F700094F85100214902074FF000001AD46569C6 +:106F800072B6626942F0200262610860B4F85E1075 +:106F900009B1A4F85E00FFF70EF80146FFF78FFE77 +:106FA000B1FBF0F0E9F72CFA6561052000F0FAF981 +:106FB00062B670BD086070BD094810B50021C46894 +:106FC000C160FFF7D2FF1CB1A446BDE81040604786 +:106FD0000320FFF73FFE10BD40090022C00400223D +:106FE000DC07100000093D000048E8010024F4001F +:106FF00000127A0044090022480900224C090022AC +:10700000EE4A1161EE4900220A6000EB80004FF663 +:10701000FF7202EA40004FF00052A2F86000012027 +:1070200008607047E54B10B5E54A19610021116011 +:107030004FF0005191F85140E40608D400EBC00332 +:1070400003EB00104FF6FF7303EA800002E01B6AB7 +:1070500058438009A1F860000120106010BD4FF076 +:107060000050B0F86000704770B54FF0005494F8CD +:107070005100D349C2064FF000001AD4656972B6B8 +:10708000626942F0400262610860B4F8601009B1C0 +:10709000A4F86000FEF78FFF0146FFF710FEB1FB7A +:1070A000F0F0E9F7ADF96561062000F07BF962B612 +:1070B00070BD086070BDC14810B500210469016150 +:1070C000FFF7D2FF1CB1A446BDE810406047042082 +:1070D000FFF7C0FD10BDB94A5161B9490022091D31 +:1070E0000A6000EB80004FF6FF7202EA40004FF0AA +:1070F0000052A2F86200012008607047AF4B10B543 +:107100005961AF4A0021121D11604FF0005191F8F2 +:107110005140A40608D400EBC00303EB00104FF667 +:10712000FF7303EA800002E01B6A58438009A1F85C +:1071300062000120106010BD4FF00050B0F86200F6 +:10714000704770B54FF0005494F851009D49820685 +:107150004FF000001AD4656972B6626942F080028D +:1071600062610860B4F8621009B1A4F86200FEF729 +:1071700022FF0146FFF7A3FDB1FBF0F0E9F740F96C +:107180006561072000F00EF962B670BD086070BD41 +:107190008A4810B5002144694161FFF7D2FF1CB154 +:1071A000A446BDE8104060470520FFF753FD10BD21 +:1071B000824A916183490022091D0A6000EB800028 +:1071C0004FF6FF7202EA40004FF00052A2F864004E +:1071D000012008607047794B10B59961794A002108 +:1071E000121D11604FF0005191F85140640608D40F +:1071F00000EBC00303EB00104FF6FF7303EA8000BF +:1072000002E01B6A58438009A1F864000120106065 +:1072100010BD4FF00050B0F86400704770B54FF0EB +:10722000005494F85100684942064FF000001AD407 +:10723000656972B6626942F4807262610860B4F88E +:10724000641009B1A4F86400FEF7B5FE0146FFF72B +:1072500036FDB1FBF0F0E9F7D3F86561082000F0E6 +:10726000A1F862B670BD086070BD544810B5002129 +:1072700084698161FFF7D2FF1CB1A446BDE81040CC +:1072800060470620FFF7E6FC10BD10B5FEF77AFE5A +:107290004FF0005191F8222042F21073B0FBF3F04E +:1072A000C2F38102521CD040B1F85420C96C514342 +:1072B0008909B0FBF1F010BD43490022091D0A60A5 +:1072C0003E4A126A50434FF000528009A2F866000D +:1072D0000120086070473C490020091D0860704784 +:1072E0003649C86139490120C1F8DC003649A0316E +:1072F0000860091D08607047304A10B50020D16948 +:10730000D061324AC2F8DC0051B12F4AA03210607D +:107310004FF00050C06CBDE8104020F07F4008479F +:10732000FF20FFF797FC10BD10B50446FEF72AFEBC +:107330004FF0005191F8221042F21072B0FBF2F0BF +:10734000C1F38101491CC8400003B0FBF4F01B49A4 +:10735000086210BD30B54FF000550124844095F807 +:10736000510009B1204300E0A04385F8510095F891 +:107370004B000AB1204300E0A04385F84B0015F80C +:10738000500F0BB1204300E0A043287030BD4FF0F8 +:10739000005010F84A1FC079814301D00120704786 +:1073A0000020704700F01F02012191404009800039 +:1073B00000F1E020C0F8801270470000DC071000E8 +:1073C00050090022540900225809002200006022BE +:1073D000002101600846704730B50A6812B10B46BB +:1073E000846A08E000220860C0E903210AE002F193 +:1073F0000C03D26812B1956AA542F8DC1A68C0E99C +:1074000003211860002030BD0068002201E0C06840 +:10741000521C8A4201D00028F9D170470068704799 +:1074200002690AB1116831B96FF00400704701F1C7 +:107430000C02C96839B18142F9D1C96811600021D3 +:107440000161084670476FF003007047017C31B15D +:107450004FF0005111F82D2F42F002020A70194925 +:1074600002680A6042684A6082688A60C068C860D0 +:10747000704730B44FF0005111F8E00F0A8AC96824 +:10748000104BC40708D09B68002B0BD0A2F57F449B +:10749000FF3C07D030BC1847DB68002B02D0521CE1 +:1074A00092B2F7E730BC70474FF0005090F8E2001E +:1074B0000449C20701D0096800E04968002900D0EA +:1074C0000847704714081000B2F120030AD5C2F132 +:1074D000200301FA02F120FA03F300FA02F041EA74 +:1074E0000301704700FA03F14FF00000704710B538 +:1074F0004C1084EA530404D54042C1F1000138BF66 +:10750000491E1B4204D55242C3F1000338BF5B1E23 +:1075100000F0D9F814F0804F04D04042C1F10001CE +:1075200038BF491E14F0004F04D05242C3F100038B +:1075300038BF5B1E10BD032A40F2308010F0030CF0 +:1075400000F0158011F8013BBCF1020F624498BFB6 +:1075500011F801CB00F8013B38BF11F8013BA2F153 +:10756000040298BF00F801CB38BF00F8013B11F0CE +:10757000030300F02580083AC0F0088051F8043B6E +:10758000083A51F804CBA0E80810F5E7121D5CBFDB +:1075900051F8043B40F8043BAFF30080D20724BF0E +:1075A00011F8013B11F801CB48BF11F8012B24BFA2 +:1075B00000F8013B00F801CB48BF00F8012B7047F1 +:1075C00010B5203AC0F00B80B1E81850203AA0E87E +:1075D0001850B1E81850A0E81850BFF4F5AF5FEAB2 +:1075E000027C24BFB1E81850A0E8185044BF18C965 +:1075F00018C0BDE810405FEA827C24BF51F8043B0C +:1076000040F8043B08BF7047D20728BF31F8023B5F +:1076100048BF11F8012B28BF20F8023B48BF00F8F3 +:10762000012B704702F0FF0343EA032242EA0242C1 +:1076300000F002B84FF000020429C0F0128010F0F0 +:10764000030C00F01B80CCF1040CBCF1020F18BF3E +:1076500000F8012BA8BF20F8022BA1EB0C0100F0D1 +:107660000DB85FEAC17C24BF00F8012B00F8012BA4 +:1076700048BF00F8012B70474FF0000200B51346D9 +:1076800094469646203922BFA0E80C50A0E80C5042 +:10769000B1F12001BFF4F7AF090728BFA0E80C50F3 +:1076A00048BF0CC05DF804EB890028BF40F8042BEC +:1076B00008BF704748BF20F8022B11F0804F18BF59 +:1076C00000F8012B704753EA020C00F069802DE9A5 +:1076D000F04B4FF00006002B1FBFB3FA83F503FAFF +:1076E00005F424FA05F65E4012BF1643B2FA82F59D +:1076F00002FA05F4C5F120051EBF22FA05FC44EA92 +:107700000C04203556EA044C4FEA144418BF641C9C +:107710004FF000084FF00009904271EB030C39D391 +:10772000002919BFB1FA81F701FA07F6B0FA80F71C +:1077300000FA07F6C7F120071EBF20FA07FC46EA49 +:107740000C062037B6FBF4FCA7EB0507103F07F04B +:107750001F0BCBF120060CFA0BFB2CFA06F644BFEC +:10776000B3460026202FA4BF5E464FF0000B5BEA15 +:10777000060C08BF4FF0010B19EB0B09ABFB027CA9 +:1077800048EB0608C01B06FB02CC0BFB03CC71EBDD +:107790000C01C1E70B46024641464846BDE8F08B66 +:1077A00013B54FF000004FF00001AFF30080BDE8CB +:1077B0001C40704710B50446AFF300802046BDE87A +:1077C0001040E8F72BBD704701491820ABBEFEE71B +:1077D0002600020001490020086070473805002299 +:1077E0002DE9F0410F4F00244FF001084FF00056F3 +:1077F00008FA04F0C5B296F82F0028420CD096F88B +:107800003900284208D057F8240000B1804796F884 +:107810002F00A84386F82F00641C062CE8DBBDE887 +:10782000F08100001C9210002DE9F0410F4F002460 +:107830004FF001084FF0005608FA04F0C5B296F870 +:107840002E0028420CD096F83800284208D057F86D +:10785000240000B1804796F82E00A84386F82E0039 +:10786000641C062CE8DBBDE8F0810000FC911000F0 +:1078700001218140C8B24FF0005191F8331001420C +:1078800001D001207047002070470000014901200D +:107890000860704738050022004870472107100033 +:1078A0000549044A0A80054AC0E900210121017204 +:1078B0004172704794530120C0061000987A01006D +:1078C0000748417849B1807838B106488079012865 +:1078D00003D105480078012800D00020704700003F +:1078E00010071000B0511000000510000348417847 +:1078F00011B98078002800D00120704710071000CF +:107900000148007870470000E40510000148007845 +:107910007047000040051000064841788278C3781F +:107920001144027800791A441144081800D001204B +:1079300070470000A005100070B5D0E900214C0888 +:107940004FEA3203961841EB010533432C431343AE +:107950000C43C0E9003470BD01EB810100EBC100B4 +:1079600029307047024A1278514300EB41007047BA +:107970005A06100001EB810100EBC100293070476D +:10798000024A1278514300EB410070475A0610003A +:10799000100000000400000001000000FF00FF00D4 +:1079A000FF000000000101010202000000000000D1 +:1079B000CC4A1000185010006704010002000000BB +:1079C000750401000200000027060100020000000B +:1079D0003904010002000000B305010001000000AD +:1079E0000305010007000000D505010001000000AB +:1079F000F7050100010000009F04010007000000DE +:107A000039040100020000003D040100B506010038 +:107A1000B1060100BD070100B10601004D090100DA +:107A2000B1060100B1060100B1060100B106010076 +:107A3000B1060100F3060100010000002B07010060 +:107A400000000000B1060100000000003F07010037 +:107A500001000000E9070100010000000D0801001D +:107A6000010000003108010001000000670801006A +:107A7000040000003F090100010000007909010035 +:107A800001000000CD09010001000000E309010030 +:107A9000020000002B0A010002000000DD0A0100C4 +:107AA00002000000930B010001000000D30B010055 +:107AB00001000000950A0100020000005B0B0100BC +:107AC00002000000B106010000000000B106010044 +:107AD0000000000093090100E90601009D09010072 +:107AE000AD090100BD0901008600020100A6020FD8 +:107AF0000300A8020B0300000300000000000000C8 +:107B0000030000000000000053000000000000001F +:107B10004300000000000000F3000000000000002F +:107B2000E30000000000000053020000000000001D +:107B30000000000005000000A8761000000400000E +:107B4000613700000000000002000000010000009A +:107B500004000000A87A1000000400001D47000087 +:107B6000000000000200000002000000030000000E +:107B7000A87E100000080000EF01010000000000D6 +:107B8000020000000300000002000000A8861000B0 +:107B900000020000890C010000000000020000004B +:107BA0000400000001000000A88810008000000010 +:107BB000A50301000000000002000000000000001A +:107BC00001000000010000000100000002000000B0 +:107BD000010000000300000001000000040000009C +:107BE000010000000500000001000000000000008E +:107BF000010000000200000003000000F73E010049 +:107C00008F3E01002B5101000337010001380100B4 +:107C10004F4101001B400100AD4B010041510100EB +:107C20000004400010210000001F010006000000B9 +:107C300030000100000406000802500060020C0C35 +:107C4000000060020C300C1A31100F0F00002F00E2 +:107C50000100AA2C0100000003000000FFFF030048 +:107C60000000000018000000FFFFFFFF3F000000C1 +:107C70000000000000010000000000006002018020 +:107C80000001000000000C000C000C000C000701BB +:107C900026261212110000000038003C203DD04181 +:107CA000EC4108421C4230424442604274428842E5 +:107CB000A4420000000000000000000000000000DE +:107CC0000000002000010102010202030102020380 +:107CD00002030304000000001B0000802D00008050 +:107CE00036000000410000805A0000006C000000D7 +:107CF000770000809900008082000000B40000003E +:107D0000AF000080D8000000C3000080F5000080B4 +:107D1000EE00000029010080320100000401000093 +:107D20001F01008068010000730100804501008090 +:107D30005E010000B0010000AB0100809D010080E9 +:107D400086010000F1010080EA010000DC01000072 +:107D5000C701008049020080520200006402000056 +:107D60007F020080080200001302008025020080CC +:107D70003E020000D0020000CB020080FD02008025 +:107D8000E6020000910200808A020000BC020000AE +:107D9000A7020080600300007B0300804D03008089 +:107DA00056030000210300803A0300000C0300008A +:107DB00017030080F9030080E2030000D4030000F1 +:107DC000CF030080B8030000A30300809503008068 +:107DD0008E0300008904008092040000A4040000C7 +:107DE000BF040080C8040000D3040080E5040080C4 +:107DF000FE040000100400000B0400803D0400801D +:107E000026040000510400804A0400007C040000A5 +:107E100067040080A0050000BB0500808D05008080 +:107E200096050000E1050080FA050000CC05000081 +:107E3000D7050080390500802205000014050000E8 +:107E40000F0500807805000063050080550500805F +:107E50004E050000C0060000DB060080ED06008035 +:107E6000F6060000810600809A060000AC060000BD +:107E7000B706008059060080420600007406000024 +:107E80006F0600801806000003060080350600809B +:107E90002E060000E9070080F2070000C40700007A +:107EA000DF070080A8070000B30700808507008077 +:107EB0009E070000700700006B0700805D070080D0 +:107EC00046070000310700802A0700001C07000059 +:107ED000070700800909008012090000240900003A +:107EE0003F090080480900005309008065090080AF +:107EF0007E090000900900008B090080BD09008008 +:107F0000A6090000D1090080CA090000FC09000090 +:107F1000E7090080200800003B0800800D08008071 +:107F200016080000610800807A0800004C08000074 +:107F300057080080B9080080A208000094080000DB +:107F40008F080080F8080000E3080080D508008052 +:107F5000CE080000400B00005B0B00806D0B008022 +:107F6000760B0000010B00801A0B00002C0B0000A8 +:107F7000370B0080D90B0080C20B0000F40B00000F +:107F8000EF0B0080980B0000830B0080B50B008086 +:107F9000AE0B0000690A0080720A0000440A00006B +:107FA0005F0A0080280A0000330A0080050A00806A +:107FB0001E0A0000F00A0000EB0A0080DD0A0080C3 +:107FC000C60A0000B10A0080AA0A00009C0A00004C +:107FD000870A0080800D00009B0D0080AD0D0080A1 +:107FE000B60D0000C10D0080DA0D0000EC0D0000A0 +:107FF000F70D0080190D0080020D0000340D000007 +:108000002F0D0080580D0000430D0080750D00807D +:108010006E0D0000A90C0080B20C0000840C000062 +:108020009F0C0080E80C0000F30C0080C50C008061 +:10803000DE0C0000300C00002B0C00801D0C0080BA +:10804000060C0000710C00806A0C00005C0C000043 +:10805000470C0080C90F0080D20F0000E40F000021 +:10806000FF0F0080880F0000930F0080A50F008095 +:10807000BE0F0000500F00004B0F00807D0F0080EE +:10808000660F0000110F00800A0F00003C0F000077 +:10809000270F0080E00E0000FB0E0080CD0E008058 +:1080A000D60E0000A10E0080BA0E00008C0E00005B +:1080B000970E0080790E0080620E0000540E0000C2 +:1080C0004F0E0080380E0000230E0080150E008039 +:1080D0000E0E0000B4800100000410002404000013 +:1080E0001C010000E480010000FC100040000000C2 +:1080F00078010000E480010024081000188A0000C4 +:108100009401000001FF012903FFFFFF01B007599F +:10811000F00120F852103206320F9A37089AE1081F +:10812000034AD303AAFF0C590101150B4990D076DD +:10813000A100000030B572B601230C4D2B600C4A33 +:10814000002481B113604FF0005100F01F0081F84E +:108150006A0007481C38036001680029FCD11460DC +:108160002C6062B630BD1460EDE70000C01B002239 +:10817000780D0022FBBD33B7F70200000442CC4863 +:1081800008FDFFFF3E0007000103000007FB0000A1 +:1081900000000000FFFFFFFF03000000FFFF0000E2 +:1081A000000000002210230937040F23093704B808 +:1081B000010000000320200A88AA40014001E803D2 +:1081C000C80096009600960096007000700008B0F7 +:1081D00000B000001BAA0A04C80000000000000054 +:1081E000000000000D050F0A100FF9000232000018 +:1081F000000000000000000000000000000000007F +:10820000000000000B013C0096009600D001000029 +:108210000000000082000064000000FF0000000079 +:10822000000000001608000208000600000000A080 +:10823000504C260108001300000000008D05094F76 +:1082400004002C0002002B00266006000000000045 +:10825000BBBB401FC80088880000ADA50D1F2400CF +:108260002F002E0026600600000000002660060099 +:1082700000000000000126000000002606000000AB +:108280000000000000008D11084F040030000600BF +:108290002F00401006000000010000000000000058 +:1082A000000000000000E8650D1F100034003000E1 +:1082B0006000170010011000200099230001000049 +:1082C00000000000000000000000000000000000AE +:1082D000000000000000000000000000000000009E +:1082E0000000000011002C0100000000010000004F +:1082F000000000000000B80B000000000E000000AD +:10830000000000000000000000000200000000006B +:10831000000000000E00000000000000000000004F +:10832000000002000000000000000000000000004B +:1083300000000200000064006400D000800CF00A1D +:10834000D00000150012500150010015001250011C +:10835000800CF00AD00000000000000000000000C7 +:1083600000000000932A020A0F00011E18000000FE +:108370000000300000000000FF0FFF0F10140A0083 +:10838000000000000B00C800000000D00F14900196 +:108390009001FF7FFF7FF4010000000005640003EF +:1083A00000000000090096009600960096003C0030 +:1083B00064001E0002003C0064003C00C800000095 +:1083C000000064000102F4015E01002C012C010890 +:1083D00019C800000B03052101016400640060005E +:1083E000900132010000000000235802C800FF2C59 +:1083F000012000000300640032002000140AE8039A +:108400002800000400002000060005000500000010 +:108410000600050005000000815C0200000100016B +:108420008200C8000001080018001E00000100645E +:10843000403220001E003200C8008813401F05642F +:10844000006400640010004600FA96FAC8000000BC +:10845000000000000000000000000000000000001C +:10846000000000000000000084030C0E2000101229 +:10847000500082006400000A6400000F00016000E8 +:1084800060000040400000000000C8009001500063 +:108490007C010032010000000000000056000000D6 +:1084A00000000000000000000000000000000000CC +:1084B0000000000002008C001E28030502020213C7 +:1084C000115500005E01C8000632001EF4010000D4 +:1084D0000000000041007800960032004000C80013 +:1084E000000000000000000000000000000000008C +:1084F0000000617B0103AA00000210010002640079 +:10850000066400640014001400107800320000219A +:108510001A0000100F01000A00148211140010004C +:1085200004100400400000200030D810006400E077 +:10853000949428886208000800100030000A00188F +:1085400000053C053C033CD80532F80301030A96BC +:108550000684C8000FE8080008000FE80000044384 +:10856000C800C8000A0A3C007800001050003C0017 +:1085700001640000000000000000003C00960014B0 +:10858000E8030000640003E8030000FA00030000B1 +:1085900000000000000000000000000000000000DB +:1085A0000000000000000000000000001100960024 +:1085B0001E28000000051E00FA000000500A051EDB +:1085C00006640A02C8001E0300900164FA00C0009D +:1085D000000000000000000000000000000000009B +:1085E000000000000000010203040001020350012A +:1085F0005001500150010000000000000000000088 +:10860000000000000000000000000000000000006A +:10861000000000000000000000000000000000005A +:10862000000000000000000000000000000000004A +:10863000000000005A5A5A5A5A5A5A5A5A5A5A5A02 +:108640005A5A5A000000000000000000000000001C +:108650000000000060595B5D5F5E5F6061626363A4 +:10866000636464646464696A6B6B6C6C6D6D6F7079 +:1086700070706E6C6C710000000000010C0C222206 +:10868000220000000000000A00140032006400BF55 +:1086900008F1080F09190923092309000000000A3D +:1086A00000140032006400D303050423042D0437B2 +:1086B000043704000000000000000000000000007B +:1086C00000000000000000000009000B000D001970 +:1086D000004200E3080E09130916091909230900CD +:1086E000000A001100180028004600E8030E041FCD +:1086F00004240429043704000000000000000000E6 +:108700000000000000000000000000000000000069 +:108710000000000000000000000000000000000059 +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:108740000000000000000000000000000000000029 +:108750000000000000000000000000000000000019 +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800000000000000000000000000000000000E9 +:1087900000000000000000000000000000000000D9 +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00058004C004C004C00404C408C10CC40DC1D +:1087D00000005F006100670070007D008E00A30054 +:1087E000BA00D500F300140137015C018401AD012A +:1087F000D801040231025F028D02BA02E7021403BB +:108800003F036A039203B903DD03FF031F043B0424 +:1088100054046A047D048C0497049F04A304A304F5 +:108820009F0497048C047D046A0454043B041F04D1 +:10883000FF03DD03B90392036A033F031403E70256 +:10884000BA028D025F0231020402D801AD01840137 +:108850005C0137011401F300D500BA00A3008E00BB +:108860007D007000670061005F0094009800A50023 +:10887000B900D600FB0027015A019401D301180268 +:108880006102AF02FF025103A503FA034E04A204E2 +:10889000F30442058D05D505170653068A06B90669 +:1088A000E20603071C072C07350735072C071C07B2 +:1088B0000307E206B9068A0653061706D5058D0595 +:1088C0004205F304A2044E04FA03A5035103FF0278 +:1088D000AF0261021802D30194015A012701FB0083 +:1088E000D600B900A500980094009A009F00AC0043 +:1088F000C200E000060135016A01A601E90130026B +:108900007D02CE0222037803D00328048004D80419 +:108910002D057F05CE0518065D069D06D6060807BF +:10892000320754076E0780078907890780076E079B +:10893000540732070807D6069D065D061806CE05C1 +:108940007F052D05D80480042804D0037803220372 +:10895000CE027D023002E901A6016A01350106015D +:10896000E000C200AC009F009A009400DD00AD0161 +:10897000DE023E048D0594062307230794068D0529 +:108980003E04DE02AD01DD009400350037003B00FF +:1089900043004D005A006A007D009200A800C1000B +:1089A000DC00F7001401320150016F018D01AB01B1 +:1089B000C901E50100021A02320248025B026C02A0 +:1089C0007B02870290029602990299029602900217 +:1089D00087027B026C025B02480232021A0200022A +:1089E000E501C901AB018D016F0150013201140194 +:1089F000F700DC00C100A80092007D006A005A0068 +:108A00004D0043003B0037003500AE035203F9022E +:108A1000A40253020602C001800147011601EE00C4 +:108A2000CE00B600A800A400000000000000000076 +:108A30000000000000000000000000000100010034 +:108A40000100040104050409040D0000FF03FE07F2 +:108A5000FE07FE07FE07FE07FE07FE07FE07FE07EE +:108A6000FE07FE07FE07FF07FF07FF07FF070000DF +:108A700000000000000000000000000000000000F6 +:108A800000000000000000000000000000000000E6 +:108A900000000000000000000000000000000000D6 +:108AA00000000000000000000000000000000000C6 +:108AB00000000000000000000000000000000000B6 +:108AC00000000000000000000000000000000003A3 +:108AD0000507080C0D0F0F0F0E0E0E0D0D0D0A08D9 +:108AE0000000000000000000000000000000000086 +:108AF0000000000000000000000000000000000076 +:108B00000000000000000000000000000000000065 +:108B10000000000000000000000000000000000055 +:108B20000302500050004A0150204E0B0132001445 +:108B300005000A201405F80002013C0001020F0F95 +:108B40002323083C083C40F805050A0A0105050FE7 +:108B50001400E8650D1F100034003000600017009D +:108B600010011000080099E3000000000000000060 +:108B70000000000000000000000000006400000091 +:108B80000000000000000A001405000000502850FA +:108B90002814B020FF00D0000614142A3A400032F6 +:108BA0003200146E6E471A38000000010F1E0020BC +:108BB0000100FAA9018F025B073F08231023100A66 +:108BC00011130A1C05050000000000E920021F1017 +:108BD0000025002500500024007001800110005580 +:108BE0000000000000000000000000000000000085 +:108BF0000000000000000000888800F7999900003C +:108C0000000100000000100710961E000F64140001 +:108C10000F0002020302030396C8FF0000000000D9 +:108C20000000000000000000012800640AC80014D1 +:108C30000400000000000001000100010001080024 +:108C4000188100000000041000000108000E000060 +:108C5000000000000000000000000200AA00E8443C +:108C60000D1F10404C004C00600028000101010164 +:108C700020005503200500000080004000983AC8FD +:108C800000000D62640064001414F401F401F401A6 +:108C9000F40100000014000000002C0132030088E1 +:108CA00000000000000000000000000000000000C4 +:108CB000040800003404F400700036000F000A00BD +:108CC00004000000000004000A000F0036007000DD +:108CD000F400340400000000000000000000000068 +:108CE0000000000000000000000000000000000084 +:108CF0000000000000000000000000000000008BE9 +:108D00001096000000010A2C010414002C01000040 +:108D1000002C01101E0FC800032800FFCCFFDFA3AA +:108D2000685443352B221B15120E0B090706050448 +:108D300000000000000000FFFFFFFFFFFFFFFFFF3C +:108D4000FFFF84039001FA000F073223190000008F +:088D500000000000ADD89A00FC +:00000001FF diff --git a/firmware/st_fts_j2a.ftb.ihex b/firmware/st_fts_j2a.ftb.ihex new file mode 100644 index 000000000000..72db06d78d49 --- /dev/null +++ b/firmware/st_fts_j2a.ftb.ihex @@ -0,0 +1,7136 @@ +:1000000055AA55AA010000003639000093230000CC +:100010006700000000000000070000001C01020152 +:1000200000000000071200000000000050B00100B6 +:10003000480D000000000000000000008D55D4FCB9 +:100040001AB1F513136C0000E54E0AECEC93FFFFB8 +:1000500000041000E101000039020000530200001A +:100060006D02000087020000A102000000000000F5 +:10007000000000000000000000000000938101006B +:100080009B81010000000000BB020000A381010071 +:10009000AB810100B7810100C3810100CF81010064 +:1000A000DB810100E7810100F3810100FF81010094 +:1000B0000B820100C90200001782010023820100A7 +:1000C0002F820100378201003F8201004782010038 +:1000D000538201005B820100638201000000000086 +:1000E0000000000000000000000000006B82010022 +:1000F00073820100000000007B820100000000000C +:1001000000000000000000000000000000000000EF +:10011000670093231100FFFF1C0102010000000093 +:1001200000000000000000000000000000000000CF +:1001300000F002F800F068F80AA090E8000C824491 +:100140008344AAF10107DA4501D100F05DF8AFF26E +:10015000090EBAE80F0013F0010F18BFFB1A43F0A5 +:100160000103184754AE010084AE01000A444FF069 +:10017000000C10F8013B13F0070408BF10F8014B06 +:100180001D1108BF10F8015B641E05D010F8016B4B +:10019000641E01F8016BF9D113F0080F1EBF10F8AF +:1001A000014BAD1C0C1B09D16D1E58BF01F801CBD2 +:1001B000FAD505E014F8016B01F8016B6D1EF9D555 +:1001C0009142D6D370470000103A24BF78C878C156 +:1001D000FAD8520724BF30C830C144BF04680C604D +:1001E000704700000023002400250026103A28BF95 +:1001F00078C1FBD8520728BF30C148BF0B60704799 +:100200001FB51FBD10B510BDDFF80CD0FFF7F8FF0C +:1002100018F05EF81AF00BFA0004100003B4FFF7B0 +:10022000F1FF03BC1AF00CFA40BA7047C0BA70472D +:1002300012481349A1EB00014FF0200391FBF3F2A8 +:1002400002FB13114FF0CC334FF0CC344FF0CC35D0 +:100250004FF0CC364FF0CC374FF0CC384FF0CC3994 +:100260004FF0CC3AA0E8F807013AFBD119B140F8B9 +:1002700004AB0439FBD10348004700000000100024 +:1002800000041000E10000001EF0040F0CBFEFF3AB +:100290000880EFF309804FF001014FF0000213F0E6 +:1002A000C5BE1EF0040F0CBFEFF30880EFF309800A +:1002B0004FF002014FF0000213F0B8BE1EF0040F21 +:1002C0000CBFEFF30880EFF309804FF003014FF00C +:1002D000000213F0ABBE1EF0040F0CBFEFF308805A +:1002E000EFF309804FF004014FF0000213F09EBEBF +:1002F0001EF0040F0CBFEFF30880EFF309804FF0FE +:1003000005014FF0000213F091BE00B517F062FF37 +:100310005DF804EB00F032B81EF0040F0CBFEFF3F1 +:100320000880EFF309804FF006014FF0000213F050 +:100330007DBE00000A484FF0FF0101704FF0000041 +:1003400080F311884FF0000080F3098805484FF0D2 +:100350000201017062B604484FF08051016070479D +:1003600022ED00E0A408100004ED00E002484FF088 +:10037000805101607047000004ED00E04FF0200064 +:1003800080F31188EFF3098098B112480068124990 +:100390000968884217D0EFF309800E49096820E9FF +:1003A000F00F886000B50B48006818F02DF85DF874 +:1003B00004EB084808490A68026000688168B1E8EF +:1003C000F00F81F309884EF0040E4FF0000080F327 +:1003D00011887047A8081000AC081000EFF31180D6 +:1003E0004FF0200181F31188704700004FF00000AA +:1003F00080F311887047000062B6704772B670478C +:10040000401EFDD17047000010B501463C22FC485B +:100410001AF08AF80121BDE81040002018F02DB82C +:1004200038B50546F748F64C2860284617F04CFDCD +:1004300000226B460121104618F068F801210020C7 +:1004400018F047F82078002802D013F03EFEECE7C1 +:1004500038BD2DE9F14FEC4EEC4D82B030684FF0D5 +:10046000000990F8317090F830104F43297851B15D +:1004700090F86D1090F8BD0A01F00F08C00706D083 +:1004800085F8009003E090F86C0000F0030801206C +:1004900000FA08FADE4CB900204600911AF0A0F8E4 +:1004A000DC484FF0010B00780190D748006890F8C5 +:1004B000BD1AC9071AD02978C1B9D7490978A9B98D +:1004C000D6490978052911D006290FD090F8750171 +:1004D000C0F30112C0F3810100F0030014F0BBFC73 +:1004E000401C4FFA80FBCB4880F80090002636E095 +:1004F000C548006890F8311090F8300041430298E8 +:10050000714300EB4109204600991AF069F8002573 +:1005100012E0BB483C30FFF783FFB94881680020F8 +:1005200007E054F8202031F910301A4444F8202014 +:10053000401CB842F5DB6D1C5545EADB384605E04A +:1005400054F8201041FA08F129F81010401EF7D293 +:10055000B0480178491C017012F0F7F8761C5E452E +:10056000C6DBAC4901980870BDE8FE4F12F0EDB84B +:10057000A34810B53C3017F080FCA14907203C315E +:10058000A54C087101202070A548FFF762FF0020EC +:10059000207010BD2DE9F04F9C489B4B9FB0017817 +:1005A000186819B190F86D10090903E090F86C1003 +:1005B000C1F3810190F8315088464FF0010990F85D +:1005C000307009FA08FB924CE81981009A4604EB56 +:1005D000850620461AF004F889483C3017F04DFC97 +:1005E000874A3C3282F80790DAF8000090F86B00F6 +:1005F000810701D582F80490C00703D080483C30C1 +:10060000FFF70EFF00202BE07D483C30FFF708FF8E +:10061000DFF8ECA16A0013A8DAF8201019F03FFF08 +:100620007A006846DAF8241019F039FF284613A931 +:1006300006E054F8202031F910301A4444F8202004 +:10064000401EF6D23846694606E056F8202031F9B9 +:1006500010301A4446F82020401EF6D209F101005D +:1006600081465845D0DB28466E4A05E054F82010F4 +:1006700041FA08F122F81010401EF7D238466A4AB3 +:1006800005E056F8201041FA08F122F81010401E3B +:10069000F7D26C0022466349644819F000FF7D00E0 +:1006A0002A466149624819F0FAFE2146614819F06C +:1006B00075FF2946604819F071FF1FB0BDE8F08F43 +:1006C0002DE9F04F504E85B0DFF848A13068504C0E +:1006D00090F831B010F8301F01910BFB01F59AF83A +:1006E0000010049190F84501C0F30112C0F381019C +:1006F00000F0030014F0AFFB401C40B203904048F0 +:100700003C3017F0BAFB3E4801273C30C7713068D7 +:1007100090F86B00C00703D039483C30FFF780FEEB +:100720003A48007800283848006805D090F86D00F5 +:1007300000F00F09000905E090F86C0000F00309D3 +:10074000C0F38100012101FA00F001FA09F8014625 +:100750000090404614F08AFB02902E480021017060 +:1007600011F0F3FF002674E0254800213C30464597 +:100770000171C17101DA0121017100998E4201DA22 +:100780000121C1711E483C30FFF74AFE1C48D0E9E8 +:100790000812876892461EB146451EDA28461AE0BE +:1007A0004FEA4B021F4819F07AFE01985146420069 +:1007B0001D4819F074FE284603E037F9101044F87C +:1007C0002010401EF9D243E054F8202037F91030B1 +:1007D0001A4444F82020401EF6D20098864237DAA8 +:1007E0005846104A07E032F9103031F910703B4496 +:1007F0005B1022F81030401EF5D20B49019825E01D +:10080000C8081000B9030000A0071000740410000D +:100810001C721000D807100000041000F80410002B +:10082000CC570120F8760120227701206C0B0120A3 +:10083000960B0120580C0120820C012031F9103058 +:100840003AF910201A44521021F81020401EF5D217 +:10085000761C0298864287DB284606E054F8201072 +:10086000664A41FA09F122F81010401EF6D2644897 +:10087000006890F8BD0AC0074BD062480078D8BB2A +:1008800061480078052844D0062842D001273DE081 +:100890005E48077011F059FF5948DFF874B10068DD +:1008A00090F8311090F830004143794353480026C6 +:1008B00000EB410A1CE056483C30FFF7B1FDDBF885 +:1008C00008100EB1002010E0284603E031F9102096 +:1008D00044F82020401EF9D209E054F8202031F9D4 +:1008E00010301A4444F82020401CA842F5DB761C46 +:1008F0004645E0DB284606E00BE054F8201041FABC +:1009000009F12AF81010401EF7D27F1C0398874285 +:10091000BEDB3E490498087005B0BDE8F04F11F009 +:1009200014BF2DE9F0470446002017F046FE0220D0 +:1009300017F043FE032017F040FE364E0020707083 +:1009400033483C3017F099FADFF8B480324FDFF8C3 +:10095000CC90D8F800004FF0010590F86B008007AC +:100960004FEA04700AD500280FDAA00708D5757081 +:10097000FFF7A6FE3D7089F8005001E0002804DA78 +:10098000707810B9FFF706FE3D70214FA00707F100 +:100990003C0718D5707830BB384617F06EFA3D71B9 +:1009A000D8F8000090F8CE00000604D5174840782B +:1009B00038B1042038711148FFF74BFD89F8005019 +:1009C00011E00320F6E760070DD511483C3017F021 +:1009D00054FAD8F8000090F87100C00601D53D71B6 +:1009E000E9E70720E6E7032017F002FE022017F0F0 +:1009F000FFFDBDE8F047002017F0FABDCC570120FD +:100A0000A007100074041000F8041000D8071000AC +:100A1000C808100000041000DF071000DE071000F7 +:100A200070B55D4C4FF6FF7140F25235206841823F +:100A3000294618F06DFB00211F200FF109F92A4605 +:100A40002168BDE870401F23544818F088BB70B57A +:100A50005148534C4FF480650068417D20684174D3 +:100A6000294618F055FB00211C200FF1F1F82A4609 +:100A70002168BDE870401C234A4818F070BB2DE97E +:100A8000F041494F041D0D462146384618F040FB01 +:100A90002868464A00EB8401914201D21D2310E0F0 +:100AA00090420DD2111A8E0890461D2332463946C7 +:100AB00018F055FBA21B07EB86011E23404602E0FF +:100AC0001E232246394618F04AFB286800EB8400B2 +:100AD0002860BDE8F081F8B5334C354800901034FB +:100AE000022017F06AFD00211D200FF1B1F800214E +:100AF0001E200FF1ADF81021204619F04FFD002007 +:100B00002080A0700120244DE0704FF6FF73A38079 +:100B100028680422018AE1808EB22649407D207235 +:100B2000A1F8F86EA1F8FA3E81F8FC0E694610466D +:100B3000FFF7A5FF012300222146102015F04FF8F2 +:100B40006946FFF79CFF012300222146112015F082 +:100B500046F86946FFF793FF286890F80012C90726 +:100B600003D190F8BA00C00708D001230022214623 +:100B7000122015F034F86946FFF781FF01230022A7 +:100B80002146132015F02BF86946FFF778FF022065 +:100B900017F02EFDF8BD0000A0071000F0EF0100D7 +:100BA000A4071000F0BF01001C721000F0DF01006C +:100BB000F0CF0100747701200B4801785A2911D138 +:100BC0008188B1F57C7F0DD8418800290AD106497A +:100BD00040781031022805D0A0F17002072A01D810 +:100BE00013F039BC704700000000012010B519F067 +:100BF000DDF80021912013F059FAFA480121017023 +:100C0000C17010BD10B5F74C207800280BD1A0881A +:100C100050B1F548A1880068B0F8880688420AD328 +:100C2000A088401CA08010BDA088401CA08019F0A6 +:100C3000B8F8E08010BD19F0B4F8208119F0B6F8CA +:100C40000120207010BD70B5E64C00202070A080FF +:100C5000E08020810B2000F0FFF94FF0E0264FF4F8 +:100C60000065C6F88052E14941F28830843619F0B7 +:100C700069F8F56720780028FCD0E0882189401ABF +:100C800084B20B2000F0E8F9204670BD7047F8B53B +:100C900000242546D64818F013F8D34F00260096B6 +:100CA00038683346012290F89400314600F007007E +:100CB00018F09DFD3868002190F8940000F00700BE +:100CC00018F01DFDCB48009038680023012290F8F1 +:100CD0009400194600F0070018F0DDFD304600F0E2 +:100CE000C6F9FFF7B0FFBF4E7081F078012801D13F +:100CF0003220F8BD38687189B0F88A0688420BD96D +:100D00000A34E4B2204600F0B2F9FFF79CFF6D1CF4 +:100D1000EDB27081142DEDD938687189B0F88A066A +:100D2000884203D90021922013F0C0F900253868C9 +:100D30007189B0F88A0688420BD8641EE4B2204656 +:100D400000F095F9FFF77FFF6D1CEDB27081142D57 +:100D5000EDD938687189B0F88A06884203D8002135 +:100D6000922013F0A3F917F0B7FF2046F8BD10B595 +:100D700001463C22A04819F0D7FB0121BDE81040F4 +:100D8000002017F07ABB70B5044617F0FAFC954DB9 +:100D9000E86817F0FBFCA4F876000420A070208E11 +:100DA0006FF30800801C20862820C4F8620094F8A5 +:100DB0005D0020F0030084F85D0094F85E0020F0F0 +:100DC000010084F85E0094F8360040F0010084F8D9 +:100DD0003600A97831B1012908D0022918D0032999 +:100DE00009D119E020F07000403002E020F07000DE +:100DF000503084F83600687888B1012813D0022872 +:100E000016D0032803D1A07C40F00300A07470BD6D +:100E100020F070006030ECE740F07000E9E7A07C63 +:100E200020F00300F2E7A07C20F00300401CEDE777 +:100E3000A07C20F00300801CE8E7F8B56E4E074662 +:100E40000324384617F040F800226B460121104673 +:100E500017F05CFB0121002017F03BFB307838B124 +:100E6000002513F032F9641E002CEADC2846F8BD98 +:100E70000125FBE72DE9F04389B00646684616F0E8 +:100E8000FCFF584F5D480025F8605D4800900E203B +:100E90008DF804007E70BD706846FFF7CEFF4FF0FE +:100EA000FF39E8B350225748F96819F0F8FA0124DD +:100EB0000DF11808BC706846FFF7BFFF80B35022E1 +:100EC0005148F96819F0EBFA4E4A414628F8145097 +:100ED000002002EB400332F810C0B3F83037401C5A +:100EE000A3EB0C0331F814C02828634421F8143014 +:100EF000EFDB641CE4B2042CDCD3BDF81E00032E2F +:100F000015D0A022B0FBF2F1BDF81C00BDF81A30DC +:100F1000B0FBF2F0B3FBF2F2120642EA004000E04E +:100F200003E0084309B0BDE8F0834846FAE75022E1 +:100F3000E8E72DE9F0410125002017F03EFB0220F3 +:100F400017F03BFB2C4F0026DFF89C803C370FE06E +:100F500001250024E0B2FFF78DFF47F824000028A8 +:100F600000DA0025641C042CF4D3012D08D0761C73 +:100F7000D8F8000090F89406B042E9DC25B327E0E9 +:100F8000224E1D49102230683C31223019F087FA78 +:100F9000D8F800001E4C90F88D06800703D59821E4 +:100FA000201D19F01DFB144919483C319C308EC995 +:100FB00080E88E000221201D216017F0F4FB3168CB +:100FC0005A2081F8210003E00021302013F06EF850 +:100FD000002017F00DFB022017F00AFB2846BDE8A1 +:100FE000F081000004041000A00710009D0B000019 +:100FF0003D0C0000B50B00001C0910000000012092 +:101000001F0D00001C7210004C791000A407100086 +:10101000909C100010B5FFF78CFF00F0010400F069 +:101020002AF820420CD04E48006890F83210FA2975 +:1010300002D2491C80F83210BDE81040FFF707BD0E +:1010400010BD10B5FFF775FF10F0010F03D0BDE81C +:101050001040FFF7FCBC10BD00F01F0201219140C1 +:101060004009800000F1E020C0F8801170470A229A +:10107000072117F09DBF70B5002017F09EFA394C7C +:101080000020E070FFF703FE064600F019F8054661 +:1010900001460A22304617F08BFFE07830B930481D +:1010A00002685A20D67782F820509077002017F0F7 +:1010B0009FFAE078012801D0012070BD002070BDAA +:1010C0002DE9F84317F008FE274E00200090306805 +:1010D0000023012290F89400194600F0070018F050 +:1010E00086FB3068002190F8940000F0070018F0AB +:1010F00006FB1E48009030680023012290F89400FF +:10110000194600F0070018F0C6FBFFF79CFD0146EA +:10111000144800244FF6FF754181804621460A227B +:10112000322017F045FFFFF78EFDA8F80A0098F867 +:101130000310012911D03168B1F88A16401A00D580 +:10114000404280B2854201D905462746641CE4B27C +:10115000102CE3D33846BDE8F8830720FBE70000F6 +:10116000A407100004041000A0071000B50B000035 +:1011700010B501463C22F84819F0D6F90121BDE826 +:101180001040002017F079B930B587B004466846A2 +:1011900016F073FEF1490091022C05D0032C09D002 +:1011A000042C05D00A2006E003208DF80A0004E094 +:1011B000072000E00B208DF80400E74C684616F08D +:1011C00083FE002206AB0121104617F09FF9012192 +:1011D000002017F07EF9207810B112F076FFEDE7CD +:1011E00016F0B3FEDE4DC5E9120116F0B0FEC5E9FA +:1011F0001401A468302013F04BF811F0EEFE07B094 +:10120000204630BD2DE9F041D54CA0F16006092EF5 +:10121000D4E91220D4E9145316D2DFE806F00516FB +:1012200026374858687989000346084600F018FBBD +:10123000012302460021184619F0E7F8D4E90223F9 +:1012400010431943C4E9020177E02A46084600F03A +:1012500007FB02460120002119F0D7F8D4E90A2340 +:1012600010431943C4E90A0167E00346084600F049 +:10127000F7FA012302460021184619F0C6F8D4E90E +:10128000062310431943C4E9060156E02A460846DE +:1012900000F0E6FA012302460021184619F0B5F8DD +:1012A000D4E90E2310431943C4E90E0145E0034677 +:1012B000084600F0D5FA02460120002119F0A5F8F1 +:1012C000D4E9042310431943C4E9040135E02A4654 +:1012D000084600F0C5FA02460120002119F095F8F1 +:1012E000D4E90C2310431943C4E90C0125E003465B +:1012F000084600F0B5FA012302460021184619F00D +:1013000084F8D4E9082310431943C4E9080114E020 +:101310002A46084600F0A4FA02460120002119F0EE +:1013200074F8D4E9102310431943C4E9100104E010 +:10133000012088406168084360602068401C20608C +:10134000BDE8F0812DE9F041174604460D46002620 +:1013500009E0E00703D03146384612F0A7FE761CBC +:101360006D084FEA340454EA0500F2D1E8E72DE9AC +:10137000F0417B4CD4E90223D4E9065610461946C5 +:101380002A433343D4E90A56D4E90EC745EA0C058B +:101390003E43D4E9087C97432CEA030CC4E9087C5B +:1013A000D4E91023AA43B343C4E910232268002AD6 +:1013B000C6D06022FFF7C6FFD4E90A016122FFF719 +:1013C000C1FFD4E906016222FFF7BCFFD4E90E0198 +:1013D0006322FFF7B7FFD4E904016422FFF7B2FFED +:1013E000D4E90C016522FFF7ADFFD4E908016622BC +:1013F000FFF7A8FFD4E910016722FFF7A3FF606899 +:10140000BDE8F041682200219CE799E72DE9F84FFB +:101410000446002616F099FD0746884616F097FD0B +:1014200081464F488A4648304FF01D0B80E88007C0 +:101430002620009017F01DFB00252A4601200021E0 +:1014400018F0E3FF384001EA080108431DD0E8B274 +:10145000002117F016FB410704D5E10602D53146FD +:1014600062200EE0C10704D0610702D5314660203A +:1014700007E014F0C00F06D010F00A0F03D0314679 +:101480006420FFF7BFFE761CF6B26D1C5D45D4DB11 +:1014900017F0EFFA0026354629E02A460120002100 +:1014A00018F0B3FF00EA090001EA0A0108431DD061 +:1014B000E8B2012117F0E5FA410704D5A10602D5EB +:1014C000314663200EE0C10704D0210702D5314622 +:1014D000612007E014F4C07F06D010F00A0F03D09B +:1014E00031466520FFF78EFE761CF6B26D1C009823 +:1014F0008542D2DDBDE8F84F17F0BBBA2DE9FF4FAA +:1015000081B08846924600210E9A1E468B46009175 +:10151000100576D500244AE000274FF0FF393D46FC +:101520002DE005FB08403AF91010B14226D27F1C8D +:10153000B9F1FF3F00D1A9460199491E8D421DD145 +:10154000012F1BD1A8F101018C420BD12946662045 +:10155000FFF758FE12E0000068091000211100009A +:10156000180410000AEB4000B0F90210B14204D395 +:1015700024B130F9020CB04200D200276D1CC648DD +:10158000005DA842CDD80198A0EB0900B8420DD863 +:1015900021466720FFF736FE22460120002118F081 +:1015A00034FF009B40EA0B0B19430091641C444537 +:1015B000B2D3002522E0B94800273C4630F9151087 +:1015C000A8EB010912E005FB08413AF91100B0420D +:1015D0000BD222460120002118F017FF009A00EAE2 +:1015E0000B001140084300D17F1C641C4C45EAD31A +:1015F0001FB129466620FFF705FE6D1C0198854244 +:10160000D9D305B0BDE8F08F70B5044686B0002090 +:1016100016F0D3FFA248002114F00C0FC0E9081106 +:10162000C0E90211C0E90411C0E90611C0E91011B6 +:10163000C0E90A11C0E90C11C0E90E114160016056 +:1016400009D1E00607D4A00605D4600603D4E0055E +:1016500001D4200602D52046FFF7D8FEA00701D10D +:10166000200520D50120FFF78FFD054616F06DFC03 +:10167000CDE9020116F06BFCCDE90401082102A8B6 +:1016800017F00CFD0646082104A817F007FD0146D7 +:10169000200508D5834800942A46006890F8123B3C +:1016A0003046FFF72BFF14F4404F02D00320FFF722 +:1016B0006BFDFFF75CFE06B00020BDE8704016F041 +:1016C00097BF2DE9F04F044685B0002016F075FF56 +:1016D000022016F072FF032016F06FFFE0077DD0A6 +:1016E000FEF746FF6F4C206890F8311090F83000FC +:1016F0004A0042436C496D4818F0D1FE4FF0000A91 +:10170000A3469AE0654B91F83010DFF8A49113F8E6 +:101710001A004FF0FF3510F0FF00A1EB0002D4B229 +:10172000624A01FB0AF147F6FF7802EB41072E46B9 +:101730000BD0204600215A4602E027F81010401C2A +:10174000136893F830308342F7DC641E1DE037F9EC +:101750001400484500DD8146404500DA8046012CF2 +:1017600013D407EB440131F9021C401A00D5404262 +:10177000DBF80010B1F8F81A884206DB2246012097 +:10178000002118F042FE85438E43641EDFD2B9EB80 +:10179000080000D54042DBF800105C46B1F8F62A9C +:1017A000904248DAB1F8F40A484544DD4044002844 +:1017B00041DD91F8FA1A2A4688463346384605F044 +:1017C000FFFA014620683346B0F8F42A0020019061 +:1017D00000910290CDE903022A4600E034E0414640 +:1017E000384605F007FB2068334690F8302090F823 +:1017F000FA0AA2EB0801C9B2884607EB40002A4664 +:1018000005F0DEFA014620684FF0010C0DF10809E1 +:10181000B0F8F44A90F9FC3A90F9FB2ACDE9001CA3 +:1018200089E81C0090F8FA0A2A4607EB4000334684 +:10183000414605F0DFFA0AF1010ADBF8001091F8E1 +:10184000313053453FF75EAF032016F0D1FE022042 +:1018500016F0CEFE05B00020BDE8F04F16F0C8BE71 +:101860002DE9F04116461F4680464FF0FF35002413 +:1018700022460120002118F0C8FD304039400843BD +:1018800004D06D1C454501D1204659E5641C402C0F +:10189000EED3002054E500005E260120342601200E +:1018A00018041000A0071000CC570120948B0120D1 +:1018B0000080FFFF144908604FF40051002016F02B +:1018C000DCBD38B5002016F078FEAFF2170018F036 +:1018D00025FC00224FF400546B462146104616F0BA +:1018E00015FE2146002016F0F4FD002016F080FEC3 +:1018F0000648A522016804480A74006820F07F4267 +:101900004A6118F02FFC38BD70041000A4071000C5 +:10191000020004D0012A04D0022805D002E00120F0 +:1019200000E0072016F032BA0020704710B50146DB +:101930003C22FE4818F0F8FD0121BDE810400020CF +:1019400016F09BBD30B587B00446684616F095FA90 +:10195000F7480090FCB1012C1FD0022C19D10220B5 +:101960008DF80A00F14D0324684616F0ADFA002206 +:1019700006AB0121104616F0C9FD0121002016F02A +:10198000A8FD2878002804D012F09FFB641E002CCC +:10199000EADC07B030BD082000E009208DF8040023 +:1019A000E0E72DE9F14F8CB016F0CFFACDE9040154 +:1019B00016F0CDFACDE90601DE4C0C98002820681F +:1019C00007D0B0F832110C98FFF7A2FF8146DA4831 +:1019D00012E090F8CE0010F0600F05D0DDE90401B0 +:1019E00013F07AFECDE904012068B0F82C110C98B0 +:1019F000FFF78EFF8146D148029040200B900A905D +:101A0000082104A817F04AFB0446082106A817F08D +:101A100045FB4443DFF82883214608F5E66082460B +:101A200018F0BCFD6100404618F0B8FDBF48B82171 +:101A3000B83818F0D5FD02222146504618F0A6FD10 +:101A400000263546082106A817F028FB0390DDE99B +:101A50000401B346CDE900015A460120002118F0E7 +:101A6000D4FCDDE900231040194008432BD00024AA +:101A700025E022460120002118F0C7FCDDE9067CA4 +:101A800002460B46384001EA0C01084316D0AD4827 +:101A900030F9150088B1039996FBF1F701FB176740 +:101AA000081A874209DBA148B83800EBC500D0E925 +:101AB000001711431F43C0E90017761C641C0A98E5 +:101AC0008442D6DB6D1C0B990BF1010B8B45C3DBFC +:101AD000002008900C98FFF735FF94480024D0F8B8 +:101AE00008B00120099001942046D5E0024601206B +:101AF000002118F08AFCDDE9042310401940084356 +:101B000074D00020AFE002460120002118F07DFCD7 +:101B1000DDE9062306460F4610401940084371D000 +:101B200082480199B83800EBC105D5E90001304081 +:101B3000394008430FD1DDE90110009A16F0E6FEA6 +:101B40001AF804103BF91420022905D04A4554DD47 +:101B500019B301292ED083E04A4506DD7F2811DA2A +:101B600000220AF80420431C06E00BDA002809DDF5 +:101B700001220AF80420431EDDE90110009A16F044 +:101B8000D0FE05E0D5E9000130433943C5E9000145 +:101B90003BF8141028F8141062E07F2803DA28F8C4 +:101BA0001420431C35E0D5E9000130433943C5E931 +:101BB000000155E0D5E9002132433943C5E9002150 +:101BC00038F914203BF91430B2EB0901A3EB0902F8 +:101BD00000D54942002A00DA5242914207DC431CF8 +:101BE000DDE90110009A16F09CFE02E052E028F8B0 +:101BF000143002200AF8040032E05FDA012902D032 +:101C000069B12DE02DE010F17F0FCCDD28F8142014 +:101C1000431EDDE90110009A16F083FE20E0D5E9AD +:101C2000002132433943C5E9002138F914203BF93A +:101C30001430B2EB0901A3EB090200D54942002A96 +:101C400000DA5242914206DC431EDDE90110009A9F +:101C500016F067FE01E028F8143002210AF804109B +:101C6000641C0098401C00900A998842FFF64BAF14 +:101C70002E480199B83800EBC100D0E90010DDE929 +:101C8000062351405840014301D00020099001989B +:101C9000401C01900398401C0B9903908842FFF66A +:101CA00025AF0998012805D00898401C08907F2886 +:101CB0007FF710AF09980DB0BDE8F08F02210AF848 +:101CC000041070E72DE9F14F8EB04FF0000B16F0C5 +:101CD0003CF9CDE9000116F03AF9CDE904010E987E +:101CE00048B114480068B0F832110E98FFF710FEA2 +:101CF0000790114814E00F4C206890F8CE0010F0C7 +:101D0000600F05D0DDE9000113F0E6FCCDE900012C +:101D10002068B0F82C110E98FFF7FAFD07900748DD +:101D2000029040200C9008210B900DE0600A1000FA +:101D3000DD180000A00710009C7C012074770120B2 +:101D40001C72100034260120684617F0A7F90D9088 +:101D5000082104A817F0A2F90A90B821FE4818F04B +:101D60003FFCFD481721F43018F03AFC0120002711 +:101D700008903846824602460120002118F045FBB3 +:101D8000DDE9042305460E461040194008437DD086 +:101D900000200390F148006890F82A118A0720D5A6 +:101DA00047B1090709D5012F04D090F83000401E33 +:101DB000B84202D1CDF818A013E000240BE0214670 +:101DC000069A029816F0A2FD034652462146029852 +:101DD00016F0A7FD641C0D988442F0DBCDF818A026 +:101DE00057E00E98FFF7AEFDDB484FF00009B83022 +:101DF0008068099001200390484644E00246012093 +:101E0000002118F002FBDDE90023104019400843CF +:101E100037D0D14800EBC904D4E900012840314053 +:101E2000084325D152464946029816F06FFD0A999B +:101E300009FB0172099931F9122007998A4206DAE1 +:101E4000D4E9001029433043C4E9001010E07F2892 +:101E500006DA431C52464946029816F062FD07E036 +:101E6000D4E9000128433143C4E90001002008906F +:101E7000D4E9000128403140084300D1039009F122 +:101E8000010908F1010080460C9900E005E0884254 +:101E9000B4DB03980028A4D07F1C0AF101000B9941 +:101EA00082468842FFF667AF0020AFE04FF000099E +:101EB0004846A1E002460120002118F0A6FADDE91B +:101EC000042306460F461040194008437ED0B9F15E +:101ED000000F01D14FF0010B0E98FFF733FD9E4824 +:101EE0000024B8308068099001200390204675E0F6 +:101EF00002460120002118F088FADDE90023104095 +:101F00001940084368D0B9F1000F0EDD5246214652 +:101F1000029816F0FBFC90495246F43109570B1811 +:101F20002146029816F0FDFC55E0BBF1010F10D1DF +:101F300052462146029816F0E9FC8749F4310855CB +:101F4000854800EBC400D0E90021B243B943C0E9A1 +:101F50000021814800EBC405D5E90001304039403B +:101F600008432FD152462146029816F0CFFC0A9A18 +:101F7000099904FB029231F9122007998A420BDA7F +:101F8000D5E9001231433A43C5E900127249F431F0 +:101F90000A5D801A085515E07F2806DA431C524670 +:101FA0002146029816F0BDFC0CE0D5E90012314341 +:101FB0003A43C5E900126849F4310A5D801A0855B0 +:101FC00000200890D5E90001304000E012E03940DF +:101FD000084300D10390641C08F101000C9980466D +:101FE000884285DB03984FF0000B00283FF474AF64 +:101FF00009F101090AF101000B9982468842FFF6B6 +:1020000059AF0E98FFF79EFC0698401C0690534867 +:10201000006890F82A110698B0EB111FFFF646AF42 +:1020200008980FB048E62DE9F14F90B015F08DFFFC +:10203000CDE9040115F08BFFCDE908011098C8B374 +:1020400046480068B0F832111098FFF761FC074667 +:1020500043480290402003900790082104A817F0FD +:102060001DF80446082108A817F018F83D4E44430F +:1020700006F5E6652146284618F090FA61003046DC +:1020800018F08CFAB821344818F0AAFA0222214636 +:10209000284618F07BFA00200D901098FFF752FCAC +:1020A0002D484FF0010BB8300024806801940B904C +:1020B00020464DE1FFE7DDE9040113F00DFBCDE91A +:1020C000040126480068B0F82C111098FFF720FC96 +:1020D00007462548BDE702460120002118F095F982 +:1020E000DDE9042310401940084379D000200A900C +:1020F00020B20E901848019900EBC1008046D0E94B +:102100000010DDE9082351405840014301D101206E +:102110000A900020D3E00A460120002118F075F94A +:10212000DDE9082381468A461040194008437DD0E6 +:1021300000200690DDE90110009A16F0E7FBD8E9CF +:10214000001E01EA09030EEA0A02134301D101222B +:1021500006920A9A002A09E0A8091000A0071000B8 +:102160009C7C01201C721000747701200AD12A5D2A +:10217000022A08D00B9B33F91430BB425FDD82B3D7 +:10218000012A3ED098E00B9A32F91420BA4205DDBC +:102190007F2810DA00212955431C06E014DA10F1DB +:1021A0007F0F08DD01212955431EDDE90110009A4A +:1021B00016F0B7FB0EE041EA09014EEA0A02C8E94F +:1021C00000124FF0000B05E041EA09014EEA0A0255 +:1021D000C8E900120B9830F8140026F814006BE0E0 +:1021E000B4E0FFE77F2803DA26F81430431C31E01F +:1021F00041EA09014EEA0A02C8E900124FF0000B59 +:102200004BE0069A2AB141EA09014EEA0A03C8E9FD +:1022100000130B9A36F9141032F91430C91BA3EBD2 +:10222000070200D54942002A02DA00E045E05242A6 +:10223000914201DC431C2BE026F814302DE02FDA0C +:10224000012A01D062B137E010F17F0FD0DD26F80E +:102250001430431EDDE90110009A16F062FB2BE0FA +:10226000069A2AB141EA09014EEA0A03C8E90013B5 +:102270000B9A36F9141032F91430C91BA3EB07027C +:1022800000D54942002A00DA52429142D4DC431E72 +:10229000DDE90110009A16F044FB022028550BE0FE +:1022A00002202855069838B1D8E9001241EA090100 +:1022B00042EA0A02C8E90012641C0098401C014668 +:1022C000009007988142FFF626AFDDE90823D8E9A0 +:1022D000001051405840014302D04FF0000B32E053 +:1022E0000A9880BB0020DDF8389028E002460120E3 +:1022F000002118F08AF8DDE908231040194008434E +:102300001BD0DDE90110424616F000FB15F809105C +:1023100011B1012905D00CE010F17F0F09DD431E3A +:1023200002E07F2805DA431CDDE90110424616F081 +:10233000F8FA09F101000FFA80F908F10100079994 +:1023400080468842D2DB0198401C01900C98401CCA +:1023500003990C908842FFF6BEAEBBF1010F05D089 +:102360000D98401C0D907F287FF797AEFD480068C0 +:1023700090F82B0140077DD5082108A816F08EFEA5 +:102380000D90002001904FF0010BB821F64818F095 +:1023900027F9002094E102460120002118F035F8C9 +:1023A000DDE908238246884610401940084372D070 +:1023B00000200690EB480222006890F83110284671 +:1023C00018F0E4F80024204615E002460120002120 +:1023D00018F01BF8DDE9042310401940084308D029 +:1023E0002146009A029816F091FADF49F431085517 +:1023F000641C09F10100039981468842E5DBFBE09A +:102400001098FFF79FFAD8484FF00009B83080685D +:102410000B90012006904846E9E002460120002189 +:1024200017F0F3FFDDE904231040194008437DD085 +:10243000CD4800EBC904D4E9000100EA0A0001EA32 +:102440000801084315D14946009A029816F05EFA31 +:1024500015F809200199022A0DD0DDF834C00B9B34 +:1024600009FB0C1133F91130BB426BDDB2B3012A09 +:102470004AD0AFE029E10D9B0B9A09FB03110A91A9 +:1024800032F91110B94210DD7F2805DA002105F874 +:102490000910431C11E011E1D4E9000140EA0A00EF +:1024A00041EA0801C4E9000115E018DA10F17F0FD4 +:1024B00009DD012105F80910431E4946009A0298DA +:1024C00016F02FFA13E0D4E9001041EA0A0140EABD +:1024D0000800C4E900104FF0000B08E00EE0D4E95A +:1024E000000140EA0A0041EA0801C4E90001DDE90F +:1024F0000A0131F8101026F810106BE07F2832DA4C +:1025000026F81130431C28E0D4E9002342EA0A02ED +:1025100043EA0803C4E900230B9B36F9112033F981 +:1025200011C0D21BACEB070302D500E05DE05242C4 +:10253000002B00DA5B429A4201DC431C36E026F8AD +:1025400011C038E03BDA012A01D0BAB142E010F103 +:102550007F0F08DD26F81130431E4946009A029885 +:1025600016F0DFF936E0D4E9000140EA0A0041EA5A +:102570000801C4E900014FF0000B2BE0D4E900236F +:1025800042EA0A0243EA0803C4E900230B9B36F936 +:10259000112033F911C0D21BACEB070300D5524216 +:1025A000002B00DA5B429A42C9DC431E4946009A7E +:1025B000029816F0B6F9022005F809000AE0022098 +:1025C00005F80900D4E9000140EA0A0041EA0801DF +:1025D000C4E90001D4E9000100EA0A0001EA0801A7 +:1025E000084300D1069009F101090C98401C039999 +:1025F0000C908842FFF611AF069800283FF400AF18 +:102600000024DFF864A1204680460AF1F40A18E0AD +:1026100002460120002117F0F8FEDDE904231040F6 +:10262000194008430AD02146009A029816F06EF924 +:102630001AF80420801A0AF80400641C08F101004A +:10264000804603998845E3DB0098401C2FE0024652 +:102650000120002117F0D9FEDDE9082310401940C0 +:10266000084322D04FF0000844461BE022460120D8 +:10267000002117F0CAFEDDE9042310401940084389 +:102680000FD04A464146029816F040F91AF8081051 +:102690004A46084443B24146029816F042F908F10E +:1026A0000108641C03988442E0DB09F101000799EA +:1026B00081468842CBDB0198401C01900098401C69 +:1026C000079900908842FFF666AE11B05846BDE803 +:1026D000F08F2DE9FF5F4FF0400AD146082102A894 +:1026E00016F0DCFC08210EA816F0D8FC0025DFF857 +:1026F0007CB00FFA80F82F462E463246012000218A +:1027000017F083FEDDE9022310401940084324D06E +:1027100000241FE022460120002117F076FEDDE9AB +:102720000E2310401940084313D03BF9170038B16D +:1027300095FBF8F208FB1252A8EB0000824201DA86 +:10274000109B00E0119B22463946009816F0E9F8EC +:102750006D1C641C4C45DDDB7F1C761C5645CCDBB8 +:10276000BDE8FF9FA0071000A80910003426012033 +:1027700070B505460124002015F01FFF022015F05A +:102780001CFFE80703D000F014F800F00104A807CC +:1027900002D500F059F80440002015F029FF02206E +:1027A00015F026FFE80702D0012000F0AEF8204621 +:1027B00070BD2DE9FC47012615F0C7FB04460D4608 +:1027C00015F0C5FBDFF80C9107468846D9F80000E4 +:1027D00090F8CE0010F0600F05D02046294612F088 +:1027E0007BFF04460D46D9F8000090F82A01C00787 +:1027F00024D0CDE9007822462B46374816F0A0F8C1 +:10280000D9F8001091F82A01C20717D091F8CF101B +:10281000C90705D00020FFF7C4F806000AD00DE074 +:1028200040074FF0000002D5FFF7FDFBF5E7FFF78B +:1028300049FAF2E70121742011F038FC0020FFF77B +:1028400081F83046BDE8FC872DE9FF41012615F0EF +:102850007CFB04460D4615F07AFB1E4F3A6892F851 +:1028600030315FEAC37C2DD0DFF870C09B070BD5F9 +:1028700092F8353192F834218DE80F0022462B462C +:102880006046FFF726FF06E0CDE9000122462B4611 +:10289000604616F055F8386890F83011C90711D025 +:1028A00090F8E100C0064FF0010002D4FFF70AFAE9 +:1028B00001E0FFF776F8060004D14FF48071742030 +:1028C00011F0F4FB0120FFF73DF804B03046BDE8FD +:1028D000F0810000A0071000747701209C7C01208B +:1028E00010B5FEF7EEFF5320FFF742FF00F00104A2 +:1028F0004FF4D67001F0D0F9204205D0FEF7EBF886 +:10290000BDE81040FEF7A3B810BD2DE9F047224EF8 +:102910000546306890F87531C3F30112C3F38101A5 +:1029200003F0030012F097FA3268401CC4B292F828 +:10293000BD0AC00700D1012492F8C10CC00729D0FC +:10294000012D27D192F83110DFF8549092F8302001 +:10295000DFF850805143D9F80050012202200F4E79 +:102960000FB288F800203635FDF7DBFF002188F82C +:102970000010032015F021FED9F800007A00624310 +:1029800087863146284617F08AFDBDE8F0470320C8 +:1029900015F02EBEBDE8F087A0071000CC5701202F +:1029A000A40710007404100010B501463C2204482E +:1029B00017F0BAFD0121BDE81040002015F05DBD03 +:1029C000B40A100030B587B0684615F056FAFE48D4 +:1029D00002220078E0B1032101280DD003280ED097 +:1029E000022818D0042205280CD004280DD006286F +:1029F0000ED007280FD010E08DF807100DE08DF8ED +:102A000009100AE08DF80B2007E08DF80B1004E0A8 +:102A10008DF8072001E08DF80920EC48EC4D0324E7 +:102A20000090684615F050FA002206AB01211046CE +:102A300015F06CFD0121002015F04BFD28780028D1 +:102A400004D011F042FB641E002CEADC07B030BD5C +:102A50002DE9F047DFF8709300252C46D9E914875B +:102A60002E4632460120002117F0CFFC00EA080074 +:102A700039404A46084304D0906B805DA84200D993 +:102A80000546761C402EECD3976DD9F85C80002665 +:102A900032460120002117F0B8FC384001EA080155 +:102AA0004A46084305D0D9F83C00805DA04200D9D1 +:102AB0000446761C402EEBD3916C16460D70D06CFC +:102AC0000470126BB76A736B12783F782A443A44E9 +:102AD000F76A1B783F7823443B44D6E9147C57EAD5 +:102AE0000C070DD0D6E9167C57EA0C070AD0FF2751 +:102AF0009A4212D29A1A2A44FF2A07D80A700AE088 +:102B00000C7008E00D700570BDE8F0870F70F1697A +:102B100041F40071F1610470F6E793420CD2D21ACD +:102B20002244FF2A01D8027004E00770F06940F4E3 +:102B30000070F0610D70E7E70D70ECE72DE9F041F2 +:102B40001F460C46002A1FDD9F4E77B1B6F90C5088 +:102B5000114613F044FAA842207812DAFF2807D26F +:102B6000401C20700020BDE8F081B6F90A50EFE764 +:102B7000F0691FB140F00200F06105E040F4006030 +:102B8000FAE708B1401E20700120ECE72DE9F04182 +:102B90001E460C46002A1ADD8B4D66B1B5F90C7045 +:102BA000114613F01CFAB84211DD207850B11028FC +:102BB00004D3103803E0B5F90A70F1E70020207063 +:102BC0000020D0E7E86926B140F00100E86101206B +:102BD000C9E740F48060F9E72DE9F14F00247A4815 +:102BE000009A2546FF21DAB1D0F830B002268BF8E2 +:102BF0000010D0F834A08AF80010B0F90C704169C8 +:102C00004FF01809002900DC01246F488069002872 +:102C100000DC0125FFF71CFFFFF7D4FE6CB11EE0BE +:102C2000D0F828B04FF400668BF80010D0F82CA034 +:102C30008AF80010B0F90A70E1E7DFF88C813A46B3 +:102C4000D8F82000D8F81410006801F049F80128DD +:102C500005D1D8F81C1031430124C8F81C108DB9D7 +:102C6000DFF864813A46D8F82400D8F818100068D4 +:102C700001F036F8012805D1D8F81C1031430125A0 +:102C8000C8F81C100CB1002D45D126462F46C84669 +:102C900019E046B94C49009B086A4A6959460068E0 +:102CA000FFF774FF064647B94749009B486A8A699F +:102CB00051460068FFF76AFF0746FFF7C9FEFFF7B6 +:102CC00081FE06B117B9B8F10108E2D24E463E4F77 +:102CD00017E03CB9386A009B594600687A69FFF7EB +:102CE0002DFF04463DB9786A009B51460068BA69D9 +:102CF000FFF724FF0546FFF7ABFEFFF763FE04B1C5 +:102D00000DB9761EE5D2012C05D1012D03D1F8694C +:102D100020F40070F861BDE8F88F2DE9F04F002431 +:102D20008046254620464FF0010CDFF89CB0A246B5 +:102D300016E002EBE50605F0070936780CFA09F70C +:102D400037420CD038F91470BBF90E60B74203DC7F +:102D500003F804C0012001E003F804A0641C6D1C0A +:102D60008C42E6DBBDE8F08F2DE9FF5F00244FF0D9 +:102D7000010B80462546DFF850A05F46DDF83C9009 +:102D8000119E54E0039805F0070100EBE50007FAF7 +:102D900001F20078024249D0305D012845D038F96F +:102DA0001420BAF90E108A4225DA2946019815F046 +:102DB00022FEFF2817DA0E994FF0000B0844FF2877 +:102DC00000DBFF20C2B205E07804100059290000A2 +:102DD000B40A10002946019815F00FFE38F81410B7 +:102DE00029F8141021E03755DAF81C1041F00801D9 +:102DF000CAF81C1019E01098012815D139F91400EF +:102E0000401AA2EB010100D54042002900DA4942F4 +:102E1000884209DC2946019815F0EDFD401EC2B23A +:102E20002946019815F0E9FD3755641C6D1C029880 +:102E30008442A7DB584604B0BDE8F09F2DE9FF5F50 +:102E40000024DDE90E764FF0010A9B462546D04668 +:102E5000DFF884942FE00BEBE500017805F0070024 +:102E600008FA00F20A4225D0305D012821D00098EE +:102E700030F91410B9F90E0081421ADD2946019883 +:102E800015F0B9FD00280CDD4FF0000AB84201DB57 +:102E9000C01B00E00020C2B22946019815F0ADFD2C +:102EA00007E006F80480D9F81C1041F00401C9F8C5 +:102EB0001C10641C6D1C02988442CCDB5046BAE79F +:102EC0002DE9F04F95B00F460646002425461821FF +:102ED0000EA817F085FB282104A817F081FBFE48F7 +:102EE0004169002900DC01248269002A00DC0125F7 +:102EF0003346F94A814606465032806B00F0FAFEAE +:102F0000F54A3B465832B169F06B00F0F3FEFFF72B +:102F10009FFDFFF757FD8CB1D9F82000EE4A4E46D1 +:102F200000680EAB5032D9F81410FFF7F6FE0128F6 +:102F300004D1F069012440F00800F0618DB1D9F8A6 +:102F40002400E54A4E46006804AB5832D9F8181000 +:102F5000FFF7E3FE012804D1F069012540F00800E5 +:102F6000F0610CB1002D76D126462F464FF00008B7 +:102F70004FF0100A0DF1380B6EB9CDE900ABD9F85E +:102F80002010D54BD9F8142008685033D9F83810E0 +:102F9000FFF754FF064677B904A8CDE900A0D9F899 +:102FA0002410CD4BD9F8182008685833D9F83C10B4 +:102FB000FFF744FF0746FFF74BFDFFF703FD06B1A0 +:102FC00027B908F10108B8F1600FD5DBDFF80CA3D1 +:102FD000D9F814000AF5E66841004F46504617F04C +:102FE000DDFAB8694100404617F0D8FA00264FF0E4 +:102FF0000109FFF7E7FC64B9CDE9009ACDE9029B2E +:10300000386AB54B7A6900685033B96BFFF7ACFE8C +:1030100004466DB904AACDE90098CDE90292786A18 +:10302000AD4BBA6900685833F96BFFF79DFE054652 +:10303000FFF70EFDFFF7C6FC04B115B9761C602E34 +:10304000D7DB012C07D1012D05D1F869810502D507 +:1030500020F40070F86115B084E62DE9FF4F83B0CD +:1030600082460120DDE9117683460290A7F17F00B8 +:1030700001900024C7F17F008946DDF84C80254689 +:10308000009083E0109800EBE500017805F0070060 +:103090000BFA00F20A4278D02946059815F07EFC1A +:1030A0008D4918F804303AF91420B1F91010022BA8 +:1030B00007D08A423ADDF3B1019988422CDDC21B68 +:1030C0003BE08A4208DD0199884202DD08F804B03D +:1030D000F5E7705D40B109E006DA0099814205DD4F +:1030E000002208F8042027E006F805B03AF814108A +:1030F00029F8141017E039F914305B1AA2EB01011A +:1031000000D55B42002900DA49428B422FDC01994D +:10311000884203DDC21B25E0705D08B906F805B0E2 +:10312000022108F80410705D58B32DE022DA012B5B +:1031300008D000998142EFDDC2192946059815F0A3 +:1031400034FCD3E739F914305B1AA2EB010100D546 +:103150005B42002900DA49428B4208DC0099814237 +:10316000DCDDC2192946059815F01FFCD6E729F8C1 +:103170001420D3E7022008F8040006F805B003E0A5 +:1031800003E0FFE700200290641C6D1C0698844257 +:10319000FFF678AF0298012822D100252C461CE0CA +:1031A000109800EBE400017804F007000BFA00F23D +:1031B0000A4211D02146059815F0F0FB18F80510C9 +:1031C000022908D079B10099814204DDC219214653 +:1031D000059815F0EAFB6D1C641C06988542DFDB40 +:1031E000029807B0BEE501998842F4DDC21BEEE704 +:1031F0002DE9F34F3A4897B0374C0068169037489E +:1032000014906169DFF8DCA000EB410015900AEB37 +:10321000010B504617F0C2F95846A16917F0BEF9E4 +:1032200060694100149817F0B9F9A0694100159838 +:1032300017F0B4F918210EA817F0D2F9282104A824 +:1032400017F0CEF90027A14616A8DDE9175450F86B +:10325000278018210EA817F0C3F9282104A817F019 +:10326000BFF902224E465046D9F8141017F08EF9D5 +:1032700002225846B16917F089F90026FFF7A2FB30 +:1032800095B9154B0EAA5033CDF80CA00093CDE99B +:103290000182D9F82010D9F81430D9F840200868F4 +:1032A0001499FFF7DAFE054694B90B4B04AA58337C +:1032B000CDF80CB00093CDE90182D9F82410D9F8EB +:1032C0001830D9F8442008681599FFF7C6FE04465F +:1032D000FFF7BEFB4DB107E0780410001C72100030 +:1032E00098A701004C79100014B9761C7F2EC5DB1D +:1032F0007F1CA9D019B035E52DE9FF5F4FF000081C +:10330000DDE90EB5994692464646444621E00AEB71 +:10331000E4000122017804F0070082400A4217D03D +:103320002146009815F03AFB071E00DA784258450E +:103330000DDD2146019815F05EFB002F0DDDC5F176 +:10334000FF01814201DB28440AE04FF00108761CAE +:10335000641C4E45DBDB40466DE5A842F5DB401BB7 +:10336000C2B22146019815F048FBEEE72DE9FC4773 +:103370000E46070001D0002E51D10024DFF838940A +:10338000DFF83884254697B9D9F8000008F15002D3 +:1033900090F8731190F87201CDE90001D8F814305B +:1033A000D8F83810D8F84000FFF7A6FF044696B9C1 +:1033B000D9F8000090F8731190F87201CDE900017E +:1033C000FE4AD8F818305832D8F83C10D8F84400E3 +:1033D000FFF792FF0546FFF73BFB012C08D1F74AA8 +:1033E00000235032D8F81410D8F8400000F082FCC6 +:1033F000012D14D1F14A00235832D8F81810D8F80A +:10340000440000F077FC0EB1012100E0002117B16B +:103410000CB1012000E00020BDE8FC47E8E6BDE873 +:10342000FC872DE9FF5F4FF0000B1E4617468846CC +:103430005D465C464FF0010ADDF8389016E007EB78 +:10344000E400017804F007000AFA00F20A420CD006 +:10345000B44209DD2146009815F0A0FA00EB0902FC +:103460002146009815F0A1FA6D1C641C4545E6DB69 +:103470005846E0E42DE9F05F0E46DDE90A510746C3 +:103480001C4693464FF0010A4FF00009104615F014 +:1034900085FACA4995F80080B7F90020B1F91010F3 +:1034A000A4F17F03C4F17F0CB8F1020F0AD04FF0F2 +:1034B00002098A4231DDB8F1000F1ED0984252DD78 +:1034C000021B31E08A4205DD98420EDD01212970A0 +:1034D000021B05E009DA844509DD00212970021983 +:1034E00058460B9915F061FA01E04FF00109388850 +:1034F0003080B9F1000F1DD01EE0B6F900707F1AC0 +:10350000A2EB010100D57F42002900DA49428F4237 +:1035100028DC984227DD021B1FE024DAB8F1010FF6 +:103520000CD084451FDD021958460B9915F03DFA61 +:10353000388830804FF0000A50467DE4B6F90030FC +:103540005B1AA2EB010100D55B42002900DA494277 +:103550008B4207DC844506DD021958460B9915F0AD +:1035600024FA00E0328085F80090E5E72DE9FF4F6E +:103570008DB04FF0FF390F98C846002801DC0120BC +:1035800000E000200C901C98002801DC012000E0E5 +:1035900000200B9089498A48099049694FF0000B37 +:1035A00000EB41000A90DA461C990F9811F05EFC7E +:1035B000069000200646059087E001250F9806F04A +:1035C00007072C4680450FDA109800EBE6000178DB +:1035D0000120B840014207D008F1010831460C9D96 +:1035E0000E9815F0DBF983461C9989450FDA1D9872 +:1035F00000EBE60001780120B840014207D009F154 +:10360000010931460B9C1B9815F0C8F982460DB193 +:10361000002C59D102208DF81C008DF820000027C5 +:10362000FFF7D0F91DBB0F9907A8CDE90006049755 +:10363000CDE902180998012300EB48010D980E9A74 +:1036400000EB4800FFF716FF054601280FD1314671 +:103650000E9815F0A3F9A0EB0B0B4FFA8BF00DF1C0 +:10366000380C00909CE807003346FFF7DAFE1CBBDD +:1036700008A8CDE900061C99CDE902190A9804971B +:1036800000EB49011A98012300EB49001B9AFFF750 +:10369000F1FE044601280FD131461B9815F07EF942 +:1036A000A0EB0A0A4FFA8AF00DF16C0C00909CE82E +:1036B00007003346FFF7B5FE05B114B97F1C7F2F15 +:1036C000AEDB0598401C0590761CDDE905018842BB +:1036D000FFF673AF11B0BDE8F08F2DE9F04700257C +:1036E0001746884682462C46344E4FF001091CE0AE +:1036F00007EBE400017804F0070009FA00F20A423F +:1037000012D02146504615F049F910F17F0F02D032 +:103710007F2804D007E0F06940F0400002E0F06943 +:1037200040F08000F0616D1C641C4545E0DBBDE8A5 +:10373000F0872DE9FF41214E716949B30025B06939 +:1037400040B300240DB1002C53D11C4A0023503249 +:10375000306C00F0CFFA194A00235832B169706C0E +:1037600000F0C8FA21462846FFF742FD124F38689C +:1037700090F87101800703D521462846FFF7F6FD32 +:10378000386890F87101C00715D02DB19CB903E0DD +:103790000125D4E70124D5E7706A084BB2690068B7 +:1037A0005833716C8DE80F00306A083B726900680D +:1037B000316CFFF7DBFE05E0A00710007804100075 +:1037C0001C72100005B184B9F06920F0C000F061EE +:1037D00025B1F84A7169306CFFF77FFF2CB1F54ACB +:1037E000B1690832706CFFF778FFBDE8FF41FFF761 +:1037F000E9B8BDE8FF812DE9FF5F4FF00109DDE980 +:103800000E6700259B4682462C46C84634E00BEBEB +:10381000E400017804F0070008FA00F20A422AD016 +:10382000385D38BB2146019815F0B8F8E1493AF9FE +:1038300015205039B1F910309A4210DDA6F17F02FF +:10384000904207DD821B2146019815F0AEF84FF03B +:1038500000090FE0C86940F04000C8610AE0C6F105 +:103860007F0107F80480814204DD82192146019816 +:1038700015F09BF86D1C641C02988542C7DB484616 +:103880006AE52DE9F04FCB4C85B0503C6169B9B386 +:1038900000208346A069A0B300208246BBF1000F40 +:1038A00002D0BAF1000F5AD1C34802AD0DC885E865 +:1038B0000D007F23BF4A206C00F01CFABD4A7F2315 +:1038C0000832A169606C00F015FA0027A14602A831 +:1038D0005D4650F8278054461521B84816F080FE02 +:1038E000B6482621153016F059FED9F81C100026CE +:1038F00021F04001C9F81C10FFF764F835B113E05E +:1039000000E001E00120C4E70120C6E7AB49A94B74 +:10391000CDE90081D9F82010D9F814200868D9F829 +:103920004010FFF768FF05467CB9A449A14B15314B +:10393000CDE90081D9F824100833D9F81820086897 +:10394000D9F84410FFF757FF0446FFF781F805B197 +:1039500014B9761C182ECFDB7F1C032FB7D305B00C +:10396000B9E62DE9F041934D0026503D012704466C +:10397000EE61012849D02F70A879697A08430CD0EC +:1039800000238C4A6969A86B00F0B4F9894A0023C6 +:103990000832A969E86B00F0ADF9E879697A084363 +:1039A0000AD084496A69286C15F00AF88149AA6925 +:1039B0000831686C15F004F8287910B10020FFF781 +:1039C0000BF96879C0B1287938B16978A86A00F034 +:1039D0007FF96978E86A00F07BF90120FFF7FCF8CD +:1039E000687948B1A978286B00F072F9A978686BFA +:1039F00000F06EF9FFF72CF8A87900B3FF20704AA9 +:103A000001462CB1012C09D00DE003202870B3E74A +:103A1000116891F8490191F84A1104E0116891F890 +:103A20005A0191F85B11FFF74BFAE978286B00F027 +:103A30004FF9E978686B00F04BF9FFF709F8012CB2 +:103A400008D02E70FEF7BEFFE87970B1287A012801 +:103A500003D008E002202870F4E73846594F387048 +:103A6000FFF70FFF3E70FFF764FEFEF7ABFF012C80 +:103A700008D01021E86900F053F9E86920B100206E +:103A8000BDE8F0814021F5E70120F9E770B50C466B +:103A900014F05BFA474D503DC5E9140114F057FA94 +:103AA000C5E916010821434815F0F8FA68610821B4 +:103AB00005F1580015F0F2FAA86104F19000A8622F +:103AC000401CE862401C2863401C68634B38A863B4 +:103AD0002030C5E90F044838686474309534C5E96E +:103AE000120470BD10B538490020FFF7CFFF3149EF +:103AF000324850391C380862314B001D4862186842 +:103B00004FF0000490F8382112F001020A7104D03D +:103B1000886A0470C86A047008E08A6A90F84101F3 +:103B200010701868CA6A90F842011070186890F80E +:103B30003821C2F340024A7122B1086B0470486B0D +:103B4000047008E00A6B90F84301107018684A6B23 +:103B500090F844011070186890F83821C2F380037F +:103B60008B71C2F3C003CB71B0F839314B81B0F81F +:103B70003B318B81B0F83D31CB81B0F83F310B82C6 +:103B800090F845314B7090F846318B7090F8473182 +:103B9000CB7090F8040100F001000872100601D506 +:103BA00001200872C2F340104872BDE810400020A6 +:103BB000D7E60000C80410009CA70100F00A10001E +:103BC000A0071000A80710006482012010B56F49FB +:103BD0000120FFF75BFF6F4900226D484A61486290 +:103BE0006D4CC1E914222068134690F84C2112F064 +:103BF00001020A7104D0886A0370C86A037008E081 +:103C00008A6A90F8550110702068CA6A90F85601C7 +:103C10001070206890F84C21C2F340024A7122B122 +:103C2000086B0370486B037008E00A6B90F857014B +:103C3000107020684A6B90F858011070206890F856 +:103C40004C21C2F380038B71C2F3C003CB71B0F877 +:103C50004D314B81B0F84F318B81B0F85131CB8170 +:103C6000B0F853310B8290F859314B7090F85C31B9 +:103C70008B7090F85D31CB7090F8290600F0010050 +:103C80000872100601D501200872C2F34010487274 +:103C9000BDE81040012064E670B50546012400200F +:103CA00014F08BFC022014F088FC680703D5FFF7A2 +:103CB00019FF00F00104280702D5FFF787FF044031 +:103CC000022014F095FC002014F092FC204670BDF8 +:103CD00002788A4201D9511A00E000210170704730 +:103CE00010B5144612F07BF9A04201DC012010BD92 +:103CF000002010BDF0B500252C464FF0010C0CE063 +:103D000002EBE40604F0070736780CFA07FE1EEA19 +:103D1000060F01D003556D1C641C8D42F0DBF0BD15 +:103D200070B504460D46C00702D0832010F0BEF9DE +:103D3000A00703D52946842010F0B8F9600703D501 +:103D40002946852010F0B2F9200703D529468620A0 +:103D500010F0ACF9600603D529468B2010F0A6F9C7 +:103D6000200603D529468C2010F0A0F9E00503D5E4 +:103D70002946872010F09AF9A00505D52946BDE807 +:103D80007040882010F092B970BD0000FC820120C4 +:103D9000E40A100078041000A0071000DFF8588132 +:103DA00008B5564D00245648C8F80040DFF854A125 +:103DB0002C60DFF854910460544ECAF80040C9F8F2 +:103DC0000040DFF84CB1346000226B465946104683 +:103DD00014F09CFB0098810713D5FCF70FFB2F68AC +:103DE0002C60FCF709FB17F0530F02D03846FEF7A2 +:103DF000BFFC17F4D67F02D03846FFF74DFF0221F3 +:103E000076E0410516D5FCF7F9FADAF80070CAF841 +:103E10000040FCF7F1FAF80701D0FCF701FEB80703 +:103E200001D5FCF758FE780701D5FCF710FE4FF4DA +:103E300080615DE001060CD5FCF7E0FAD9F800706E +:103E4000C9F80040FCF7D8FA3846FDF7DDFB8021C1 +:103E50004EE0C1010CD5FCF7D1FA2E48076804608A +:103E6000FCF7CAFA3846FDF72CFC4FF080713FE0B2 +:103E7000C10404D5FEF734FD4FF4805138E001024F +:103E800004D5FCF799FE4FF4000131E0010502D59D +:103E90004FF400612CE041020CD5FCF7AFFA377803 +:103EA0003460FCF7A9FAF80701D0FDF70AFD4FF4DA +:103EB00080011DE0C1050DD5FCF7A0FAD8F800700F +:103EC000C8F80040FCF798FA3846FCF72AFD4FF492 +:103ED00080710DE0410104D5FDF79CF84FF0806141 +:103EE00006E000017FF570AFFDF7ABF84FF0006121 +:103EF000002014F0EEFA67E7AC071000B0071000DE +:103F0000B4071000B8071000BC071000C00710006D +:103F1000839FF00DC407100010B5114811490068C7 +:103F20000B6893EA000F13D00F4A8407126810D56C +:103F300092F8E642E40702D043F002030B60C005AA +:103F40000AD592F8960C400702D543F480700860B9 +:103F500010BD23F00203F1E723F48070F7E70000BF +:103F6000D007100000051000A00710002DE9F04157 +:103F70007A487C4F02687A4892F8311080F8301005 +:103F800092F8304080F831403A7B80F8332007F1D6 +:103F90003C0240F8242BBA7B42727A7B827697F8F7 +:103FA0003A30C37697F83B2002777D7DC5746E4D1D +:103FB00045612438012B00D111464C4325B2002421 +:103FC0006E0080460FE022462946B86810F0E8FFF0 +:103FD0000146D8F8002005FB04F002EB4000324611 +:103FE00016F05DFA641CB87BA042ECDC98F8370050 +:103FF0004446012806D194F830205B48921CB969E8 +:1040000016F04DFA59485A49007809780843400794 +:104010000DD5387D94F83110484301B252488E30A6 +:104020004A0060603969BDE8F04116F038BABDE871 +:10403000F0812DE9F0414D484D4E0025046830686F +:104040000443012014F0B9FA4421454816F0C8FA97 +:10405000E00706D0FFF78AFFE00601D500F059F827 +:1040600001254448454F02683D48C0E907243168AE +:1040700041623C49404E4B688362CB7B80F83530CF +:1040800091F8381080F836103178002380F82C1021 +:1040900080F84130062905D13978052902D101215E +:1040A00080F84110E10711D0E1060FD52B490968CE +:1040B00091F80032DB0702D042F01002C26191F8A1 +:1040C000BA10C90702D042F02001C161012014F0EA +:1040D0008FFA30783870002DA9D0052807D006282F +:1040E00005D00121BDE8F041022014F0C6B902213B +:1040F000F8E79CE7204810B50078082808D0194850 +:1041000090F83910006B00F048FDBDE8104090E7D2 +:1041100010BD2DE9F0411148124E114D0068316A71 +:10412000012790F8312090F8304049B10E4885F8C9 +:10413000302018305200286116F0B1F985F83D7032 +:10414000716A002909D0084885F831404230620080 +:10415000686116F0A4F985F83C7068E7A0071000C4 +:10416000148410002C0B10006007012004051000BF +:104170000805100000051000F8041000D804100015 +:104180002DE9F0412148234E0025047820484FF0C6 +:1041900001070560316891F87110C90600D5076004 +:1041A00000F082F8012000F03FFC052C1FD0062C07 +:1041B0001DD01948077008F017FE306890F871108C +:1041C000CA0616491BD50D6090F80022D20703D10C +:1041D00090F8BA00C00701D008200860012105202E +:1041E00010F03FFA4FF48071002014F046F900F00F +:1041F000D6FDBDE8F0410221012014F03EB9086867 +:1042000020F0020040F00400E7E70000F80410008E +:10421000FC041000A0071000FA041000AC07100006 +:1042200010B5040012D0FCF7E9F8584801682143A2 +:104230000160FCF7E1F80121052010F012FABDE859 +:1042400010404FF48071002014F017B910BD0146E2 +:104250000020C9070BD04E490320096891F80022BD +:10426000D20703D191F8BA10C90700D00B207047CC +:1042700010B5C00717D04648006890F8C10C010679 +:1042800001D440060FD5FCF7B9F84248016841F067 +:1042900008010160FCF7B0F8BDE810404FF4800160 +:1042A000002014F0EAB810BD10B500F078FD02212E +:1042B000012014F00EF9012014F07FF94421364852 +:1042C00016F08EF93449012081F82C0014F090F991 +:1042D0000121022014F0D1F8BDE8104000F09DBB90 +:1042E0002DE9F0412D4900260868020603D520F08B +:1042F0008000012608602A4F0446386890EA0405C9 +:1043000029D064B170B105EA04000546FFF7B0FF9B +:104310003146284600F02BF83C60BDE8F081FFF7FD +:10432000C3FFF9E700F03BFD0221012014F0D1F8B2 +:1043300000F09FFA00F069FB25402846FFF798FF40 +:104340003146284600F013F800F050FB022101200E +:1043500014F093F8E0E7002CDFD11248007805282C +:1043600001D00628D9D13C60BDE8F0419CE710B5EA +:10437000012904D0FFF76BFFBDE8104050E70A4861 +:104380000078012801D10949087010BDAC07100060 +:10439000A0071000C007100014841000CC07100004 +:1043A000FC041000F8041000AA051000E207100039 +:1043B0002DE9F047DFF8EC930027FB4ED9F8000019 +:1043C000B84690F84010C9075ED0F84D2978022908 +:1043D0000FD005290AD0062908D090F841400120C5 +:1043E0000EF00FFE0022012806D016E090F84340A0 +:1043F000F5E790F84240F2E7287805280DD01046FE +:10440000B260A04240DDD9F8000090F84010890762 +:104410000FD52978022904D00BE0B068401CB060A9 +:10442000EFE7B179491CC9B2B171022901D9012163 +:10443000B17190F8BD0AC0070ED02878022803D0C9 +:10444000042801D0052810D130797179401CB0FBC7 +:10445000F1F301FB130030712878022803D00428FF +:1044600001D0052801D14FF00108B2602878052855 +:104470000FD000F047FA054600F04AFA40EA05047A +:1044800000F054FA40EA040786F803803846BDE895 +:10449000F0870127F8E72DE9F0470446002513F0DF +:1044A000ECFCFFF785FF0646C1480078B043C00723 +:1044B00002D0F00600D44025DFF8E88246B1D8F8F3 +:1044C000000090F8F401000702D500F03EFA054321 +:1044D00046EA0500DFF8D092C0074FF001071CD074 +:1044E00000F041FA01462071D8F8000090F8BD2A8A +:1044F000D20705D099F80330237499F80420627428 +:1045000090F8CE20C2F34112022A06D390F8CF00D1 +:10451000000602D5042900D12775680700D5677108 +:10452000F00611D5E771D8F8000090F84000800738 +:104530000AD599F80600012802D0022802D003E02B +:10454000277301E002202073680600D5677299483E +:104550000660994805609AE770B59848924D984C66 +:104560000078022816D09748007898B996480078C5 +:1045700001280FD0954E307860B916F0EBF848B9A5 +:10458000A9782078814205D33178014302D0904840 +:10459000007808B1002000E001202178A97070BDEA +:1045A00070B580480025804C006890F8C46183484D +:1045B0000078022801D165702570FFF7CDFF58B152 +:1045C000607858B92078401CC0B22070B04205D93C +:1045D00025700120607001E065702570607870BD05 +:1045E0002DE9F047044613F048FCFFF7E1FE804652 +:1045F00000F088F9064600F08BF940EA060500F065 +:1046000095F940EA050600F0A0F9DFF8989140EA34 +:1046100006054FF00107D9F8000090F8B3014106F4 +:1046200001D480060BD5FFF7BBFF40B1D9F80000DD +:1046300090F8B301800600D5A77425F0100548EA6C +:104640000506F0072BD000F08EF901462071D9F84D +:10465000000090F8CE20C2F34112022A06D390F84F +:10466000CF20120602D5042900D1277590F87611C3 +:10467000090608D55749497829B9534909780129C4 +:1046800001D00421A1715FEAC87108D090F8BD0A79 +:10469000C00704D04448C178217400796074700761 +:1046A00000D56771F00604D54B48E771007800B17A +:1046B0002773E80602D4A07C012800D1E7713D49A8 +:1046C0003D48C1F800800560E1E610B501463C2296 +:1046D000424815F029FF0121BDE81040084613F0BB +:1046E000CCBE2DE9F047314886B00078022817D0BB +:1046F000DFF8B0902F4EDFF8C08001254FF0070A99 +:10470000052811D0062835D0082868466BD0FFF759 +:1047100067FF33480090684613F0D6FB06B0B6E654 +:104720006846FFF7B8FEF4E76846002713F0A5FBDC +:104730008DF81350FFF73CFE040000D14027E0073E +:104740000CD0D9F8000090F87100C00604D500F034 +:104750000AF98DF8040001E08DF804A0E00601D507 +:104760008DF80750780601D58DF809503460C8F8E7 +:104770000070CEE76846002413F07FFB8DF81350DD +:10478000D9F80000012590F87100C00604D500F0AA +:10479000EAF88DF8040001E08DF804A03460C8F850 +:1047A0000050B6E7A0071000DC041000F804100069 +:1047B000FC0410000805100004051000F9041000A6 +:1047C00032071000280510002905100018051000F8 +:1047D000E1071000D8071000380710002C0B10005C +:1047E0007B460000FFE7002413F047FB01200D216A +:1047F0008DF804103460C8F800008AE7F8B5614D00 +:10480000801E0528296810D2DFE800F0030F060992 +:104810000C0091F8734009E091F8724006E091F8BD +:10482000744003E091F8754000E0012400260FF089 +:10483000F7F900B101266946032013F058FE0098ED +:1048400000B94EB12968142091F87110090600D5FD +:10485000C820844200D2044604B901242046F8BD91 +:1048600010B500F09CFA0221BDE81040012013F0C1 +:1048700004BE10B5444C0020A0602071414800687F +:1048800090F87501C0F30112C0F3810100F003003C +:1048900010F0E1FA401C607110BDEAE738B5002065 +:1048A00013F08BFE394C3A4920780870394800687B +:1048B00010B100F0F6F801E000F0CCF82078FFF736 +:1048C0009DFF0446AFF2670100F05CFA2046FFF757 +:1048D00008FF01280ED101216B460022084613F083 +:1048E00015FE0121084613F0F4FD2B48007830B185 +:1048F0000FF0EBFBBDE83840002013F079BEFFF766 +:10490000F9FBF7E725480078C00700D00120704781 +:1049100022480078C00707D01A48006890F80002C3 +:10492000C00701D010207047002070471B48007856 +:10493000C1071448006890F8BA0003D0C10701D03D +:104940001020704700F00100704714480078C0073D +:1049500007D00C48006890F87401C00701D004200B +:1049600070470020704707490120096891F8CE1070 +:10497000090603D50A48407808B10420704703208F +:1049800070470000A0071000DC041000F8041000BD +:10499000F9041000D40710002C0B1000FC041000C8 +:1049A000D8071000614810B5006890F87100C00782 +:1049B0000BD015F0CFFE012804D05D48017829B155 +:1049C000407818B15B490020486010BD012010BD3F +:1049D00010B500F03BF957490020574A48600221C2 +:1049E0001170564908705649087010BD5149002091 +:1049F000514A486004211170524A01211170524AF3 +:104A000011704F49087000F021B94A4900204860F0 +:104A10007047484900204860704746490020486078 +:104A2000454901200870704710B5044600F00BF9A5 +:104A30004049087000F00AF905223F49012C04D0D2 +:104A40000878052803D0062800D10A7010BD06207A +:104A5000087010BD70B5384D364C287802280ED03D +:104A6000042808D0052805D100F0EDF808B1217818 +:104A700099B1207070BDBDE8704000F035B800F00D +:104A80002AF8012806D06068401C6060FFF78AFFA2 +:104A90000128EFD0BDE87040A8E7207006202870FC +:104AA00070BD2549C3074FF0040201D00A7070475A +:104AB0008307FBD4420701D5022002E0020702D59A +:104AC000052008707047C20601D50620F9E7800668 +:104AD000F8D50820F5E710B500F0B5F80446002039 +:104AE0000EF08FFA204310BD70B5FFF7F4FF0025DC +:104AF000104C012818D06068401C6060FFF752FF1E +:104B0000012812D109486168006890F87600401CBD +:104B100000EB8000B1EB400F07D915F01BFE012818 +:104B200002D0BDE8704053E7656070BDA00710007B +:104B300074071000E8041000F8041000E2041000EC +:104B4000DF041000DE071000DF07100070B56B4AAD +:104B5000002415686A4AB5F8F6611278052A01D171 +:104B6000B5F8FA61674AD2780AB1B5F8F86100225F +:104B70000FE030F91230002B00DA5B42B34206DD61 +:104B800095F8F531641CA34201DC012070BD521C74 +:104B9000D2B28A42EDDB002070BD2DE9F0410F4614 +:104BA000010049D0584D564E0024EC703078A04694 +:104BB000022803D0032801D0052811D1002007B115 +:104BC0000120AA88121A14B201EB4000AA782146EB +:104BD00000F04EF8A87021464C48FFF7B7FF044696 +:104BE0006878012701280AD0F4B1307848490228B2 +:104BF00009D0032807D0BCB1052807D01BE085F8F1 +:104C000001800124F1E72C70EF7002E0287870B980 +:104C10002C70086800280FD100F0C1F8BDE8F04101 +:104C20000221012013F029BC3078052803D115F0AA +:104C300091FD012802D02C70BDE8F0812F70EBE7C8 +:104C40003149487070473048007870472E4901203C +:104C500088702A48006890F83000888028480078DA +:104C6000052803D0062801D0002008707047EDE722 +:104C70002DE9FC41244F8046144638780D461646EF +:104C800050B9012C08D121480A467F234146983863 +:104C9000009411F08CF900261848006890F8F4117F +:104CA000C90700D08CB119486A0041464C3815F04C +:104CB000F6FB164A2B46983A02F14C01134811F0C4 +:104CC00051F9387820430ED015E0B0F9FE11CDE946 +:104CD00000150E4AB0F9FC31983A414602F14C00F9 +:104CE00011F0D2F9E5E709487F232A464146983872 +:104CF000009411F05CF93046BDE8FC81A00710007B +:104D0000F8041000945A1000F0041000B6090120B5 +:104D1000D4071000234908B50020486001228860AC +:104D20000A704A70204A1070887020490870FFF796 +:104D30009EFFFFF7B2FDFFF76CFE6B4600225E217F +:104D4000012013F0E3FB0098410703D5FFF7C8FAF1 +:104D500004210AE0010703D5FFF7DEF8082104E08B +:104D6000C10606D5FFF70CFA1021012013F0B1FBA4 +:104D7000E3E78007E1D50221012013F0AAFBFFF74A +:104D80008DFDDAE70A49096891F87110090602D425 +:104D900000EB8000400080B2064915F0C3B815F062 +:104DA000E4B80000F8041000E0071000E20710006B +:104DB000A00710001148000000F067BC30B50023C8 +:104DC0000380012309E000EB430431F8135034F869 +:104DD000024C2C4420F813405B1C9342F3DB30BDA3 +:104DE0002DE9F74F06468EB00020CDE90C000446B1 +:104DF000FE48002A04707DD0032013F0DEFBFC4D3A +:104E0000FC4A31462B78FC4811F0ACF8032013F033 +:104E1000EFFB2878F8494200F84815F040FBDFF82E +:104E2000E093D9F8000090F8B201C00609D52A78BD +:104E3000F149F448FFF7C2FF2A78F249F24810F02E +:104E400089F9DFF8BCA3A946DAF80000B0F8CA1166 +:104E500061F30F07B0F9CC11059161F31F47B0F86A +:104E6000CE1161F30F08B0F9D01161F31F488B46E2 +:104E700090F8D21161F3070690F8DB1190F8DC018D +:104E800061F30F2660F317462878CDE900780125F5 +:104E90000296CDE90350AF1E3B463A46DA490CA8CC +:104EA00000F0FFFEDAF800100026DFF8608391F8CA +:104EB000B2010DF1300AC0F30012C0F380131A40A2 +:104EC00012EAD01F13D091F8D30191F8D21199F8BA +:104ED0000020CDE90310CDF800A0CDE901523B46FA +:104EE0003A4698F80000002100F0C8FFC6B2C44856 +:104EF000006800E086E090F8B21109061CD5C449AC +:104F0000B0F9D501497801B15846CDE9066499F860 +:104F10000010CDE90105CDF800A0CDE903153B4611 +:104F20003A46B549B74801F006F899F80000B54986 +:104F30004200B14815F0B3FA99F80020AE49B548DF +:104F4000FFF73CFFDFF8B8B2DBF8000090F8B211D1 +:104F5000490616D5AE49B0F9D701497801B105988F +:104F6000CDE9066499F80010CDF800A0CDE903144E +:104F7000CDE90105A0483B463A46A649763000F007 +:104F8000DAFFDBF8000090F8B211C1F30012C1F3B0 +:104F900080131A4012EAD11F29D00F9A0021012A4A +:104FA00003D188F8004088F80240E6B190F8D311A8 +:104FB00090F8D421B0F9D90199F80030CDE9080270 +:104FC0000A91CDE90653CDE9046498F80200CDE9D1 +:104FD000020489483B463A468B49CDF800A076301A +:104FE00000F0F2FFC1B288F8006088F802100F9854 +:104FF00000908948804999F80020036876318748F5 +:1050000010F0BCFF11B0BDE8F08F2DE9F74F04465A +:105010008EB00020CDE90C00012A7CD1032013F0D2 +:10502000CCFA7F4D74487F4A2B7821462A3810F0FD +:1050300099FF032013F0DCFA28786F4942002A39DF +:10504000794815F02CFADFF8B881D8F8000090F80C +:10505000B201C0060AD568492A782A397348FFF791 +:10506000ADFE2A787149724810F074F8DFF890911B +:10507000A846D9F80000B0F8DF1161F30F06B0F9C7 +:10508000E111059161F31F46B0F8E31161F30F07D9 +:10509000B0F9E51161F31F478B4690F8E71161F312 +:1050A000070490F8F01190F8F10161F30F2460F318 +:1050B000174428780125CDE900670294CDE9035013 +:1050C000AE1E334632465A490CA800F0EAFDD9F824 +:1050D00000000024DFF8349190F8B2110DF1300A8D +:1050E000C1F30012C1F340131A4012EAD11F274640 +:1050F00015D090F8E81190F8E70198F80020CDE974 +:105100000301CDF800A0CDE901523346324699F8AB +:105110000100002100E0B3E000F0B0FEC4B2384866 +:10512000006890F8B21109061ED53949B0F9EA01B4 +:10513000497801B15846CDE9064798F80010CDE905 +:105140000105CDF800A0CDE903152B4933463246C1 +:105150002A39364800F0EFFE98F800003349420043 +:1051600025482A3815F09BF9234998F800202A3958 +:105170003048FFF723FEDFF888B0DBF8000090F836 +:10518000B211890615D52249B0F9EC01497801B16F +:105190000598CDE9064798F80010CDE900A0CDE9C3 +:1051A0000251154833463246049722494C3000F0EC +:1051B000C2FEDBF8000090F8B211C1F30012C1F397 +:1051C00040131A4012EAD11F50D00F9A0021012A31 +:1051D00003D189F8017089F8037034B190F8E811AF +:1051E00090F8E921B0F9EE0126E03BE01705100048 +:1051F00025071000227701202C0A0120960B0120A0 +:10520000A00710001C0B0120CE0C01200C05100083 +:10521000D80710000C0C0120E0061000820C0120C1 +:1052200024071000F87601206C0B0120EE0A012003 +:105230001A0D0120E20B012098F80030CDE9080298 +:105240000A91CDE90653CDE9044799F80300CDE969 +:105250000207334632460D49CDF800A00C4800F055 +:10526000B3FEC1B289F8014089F803100F9800908D +:10527000084898F8002006490368074810F07EFEA9 +:10528000C0E6064900200870704700001A0D012092 +:10529000780A0120E0061000580C01202B071000AE +:1052A0008B480021C0E90011C0E902111030C0E9AB +:1052B0000011C0E902111030C0E90011C0E902116B +:1052C00008468449087070472DE9F041DFF80482F0 +:1052D000814D002188F800102868804E804F90F89A +:1052E000B201804C80070BD50DF0B2FE296891F811 +:1052F000C31188420FDDE07810B17B48007850B1CF +:10530000286890F8B30100072CD53078012802D026 +:105310003878012826D1207808B9607810B3286839 +:105320003978B0F8BB41012902D03178012901D187 +:10533000B0F8C141B0F9BD11654801230A461030EB +:1053400000F0E0F828680123B0F9BF1160480A4670 +:10535000203000F0D7F822B2012311465C4800F05B +:10536000D1F811E05A484FF0FF311030C0E9001178 +:10537000C0E902111038C0E90011C0E90211203063 +:10538000C0E90011C0E90211584898F80020817B5B +:1053900062F386118173BDE8F0812DE9FF4F83B080 +:1053A0009346069991F84010022908D0012903D0AC +:1053B0000699898C890505D5454D20353CE0444D3D +:1053C000103539E04549424D0978012913D1484A41 +:1053D000127882B1474A1278012A0CD1464A1278D3 +:1053E000012A08D1454AD2E90034C5E90034D2E99E +:1053F0000232C5E90232384A126892F8B22112F03C +:105400000C0F19D0C1B936490978A9B93549C978FD +:1054100091B93B49097879B9C2F38101012902D0D8 +:10542000022905D008E04FF0FF31C5E9021103E081 +:105430004FF0FF31C5E900114FF0000A9BF8021050 +:1054400015F0C4F980469BF802002EE09BF800405E +:105450004A460120002114F0D8FFCDE900011CE0EC +:1054600018F804100498814216D1D5E90010DDE93E +:10547000002311401840014326D0D5E90267224697 +:105480000120002114F0C1FF06400F403E431BD015 +:105490000AF101001FFA80FA641C9BF80100A04287 +:1054A000DEDA08F1280809F101009BF803108146B3 +:1054B0004945CBDA06995FEA0A00A1F826A000D098 +:1054C000012007B0BDE8F08F002008F80400E3E7F2 +:1054D000201E100010051000A00710002905100064 +:1054E00018051000945A1000330710003857012097 +:1054F000320710002307100022071000501E100072 +:10550000B306100070B50446FC480D46007801282B +:105510000CD04FF0FF30C4E90000F94800780128B2 +:105520000ED04FF0FF30C4E9020070BDF5482346AD +:105530000178F54800F0A9FA204615F029F9ECE7C2 +:10554000F249F14804F108031C462A4609782A303A +:1055500000F09BFA2046BDE8704015F019B970B50F +:105560001C4605460123049EFFF7CCFF0020207057 +:105570003070E248E24A01210078012801D018B1D8 +:1055800005E0107870B102E01078012812D0D5E95A +:105590000002104319D0D5E90202104315D0217042 +:1055A000317014E0D5E90003184308D02170107859 +:1055B000012804D1D5E90202104300D031702078CF +:1055C000012804D03078012801D0002070BD0120CE +:1055D00070BD10B504460020024605E034F91230D3 +:1055E000834200DD1846521C8A42F7DB10BD10B51D +:1055F0000C461146FFF7EDFF6043642190FBF1F08C +:1056000000B210BD70B5C24EC24D30792968012874 +:1056100005D0C1484078A0B3B1F9B60170BD91F88A +:10562000010240062ED5B548B1F9B44100780128F1 +:1056300010D1B44891F82712007842B2B248FFF76F +:10564000D6FF30812968B1F8B421824202DBB1F87B +:10565000B4013081AA480078012810D1AB4891F8F4 +:105660002712007842B2A8482A30FFF7C0FF296805 +:105670000446B1F8B421A24201DBB1F9B44120469D +:1056800070BDFFE7B1F9B401FAE770B5A04CA349CA +:105690000025257101200870257065709D48A57052 +:1056A000E5700068B0F8B401E08000F00FFAFFF791 +:1056B000E8FDE5602561E3E72DE9F84381468F4881 +:1056C0008846964906788E48914C0F7805780020D8 +:1056D0000870E07000F0FAF99148007848B12A4665 +:1056E00039464046FFF77CFB324639464846FFF7CD +:1056F0008CFCFFF787FFE080014685482279801CFB +:10570000012AA0F10103009006D00A468548FFF760 +:1057100026FF2070BDE8F883B4F90820F6E72DE9EC +:10572000F04F0026DDE909BA9E463546DFF8E491E0 +:1057300026E093F830706F43002319E0FC1830F92D +:1057400014C0DC4504DDB1F80080C444A1F800C0F9 +:1057500030F91440CAF1000C644508DA761CB2F83E +:1057600000C0B6B2002C00DA6442644414805B1CB2 +:10577000D9F8004094F83040641E9C42DEDC6D1C79 +:10578000D9F8003093F83170AF42D2DCAEF8006047 +:10579000BDE8F08F2DE9FF4F87B000246248149DCB +:1057A000ADF80C40ADF81040ADF8184005944078C5 +:1057B000DFF85CB19046A146012875D0554A5B4B95 +:1057C00000211668B3F900300846B6F81E22DA4206 +:1057D00000D50121564A12781AB1564F002187F898 +:1057E00000902DB1534B1B7833B1012B53D0B2E055 +:1057F000504F002187F80090002A7DD1002D7BD0EA +:10580000002979D0B6F810723D4E424D3178012909 +:1058100005D13E4801783C482A3010F0E0FB296869 +:105820009BF80430B1F90E22012B03D1B1F82232DA +:105830001A4412B2404BB3F9003093425CDAB842DA +:1058400002DA3078012804D03C4A307812781043CC +:1058500052D1B1F814023A4AB1F8121200B2B2F9B8 +:10586000002009B28DE8070006AB04AA03A9404650 +:10587000FFF755FFBDF81000BDF80C1088426AD93B +:10588000012005902868B0F81612BDF81800814272 +:1058900061D801245CE047F6FF7596F83100EB43D0 +:1058A0000122A0F1010E1CE0A8E0264896F8307015 +:1058B000DFF894A030F91200A7EB000C5743022147 +:1058C000ACF1010C0AE007EB01083AF91800834239 +:1058D00000DA0346854200DD0546491C6145F2DBDE +:1058E000521C9645E1DCB6F818029842D1DBB6F8B6 +:1058F0001A024042A84229E02DE0000023071000D0 +:105900002207100024071000580C01202507100062 +:1059100014051000A0071000D8071000DF071000C2 +:105920002B071000501E1000AE051000800510005F +:1059300074071000290510007205100028051000DA +:105940003A07100034260120440D0120A1DC14B1D7 +:1059500000F0D8F801E000F0EBF8604E604D614FC8 +:105960003078012803D1387888B1012817D085F81C +:10597000009031783878814202D006200EF071FE16 +:1059800030783870BCB301218BF8041036E085F80C +:105990000090DDE90701012200F0F0F8E9E707F0E7 +:1059A0007CF9514995F800C0504B096891F81C22C8 +:1059B00002F00F02624504DA00F58050D0F8E00FE3 +:1059C00028B1B1F81802B3F9002090420FDD85F834 +:1059D0000090B1F81802B3F90010884202DC9BF87D +:1059E000000020B9DDE90701002200F0C7F828789F +:1059F000401C2870BDE7FFE78BF804903C480599F0 +:105A000020F85E1FBDF8181041809BF8041001714A +:105A10000BB0BDE670B5374A002423461278214604 +:105A2000521E52B2344D0DE035F91260864202DD4D +:105A3000491CC9B204E08C4200D921460C46002121 +:105A4000521E52B2002AEFDA8C4200D921462B4C6A +:105A5000294E00222478641E65B22A360DE036F9FC +:105A60001540844202DD521CD2B204E0934200D9B8 +:105A70001A46134600226D1E6DB2002DEFDA9342D6 +:105A800000D91A468818C0B2FAE52DE9F0471D463C +:105A90004FF00008C5E9008891460C46824610E0A8 +:105AA0003AF9141049450CDDD5E900674FF00108BB +:105AB00022464046002114F0A8FC06430F43C5E9E6 +:105AC0000067641EECD24046BDE8F0870C48002118 +:105AD000C0E90011C0E9021170470000290510005B +:105AE0002C0510002A051000A00710002E0510003C +:105AF0003857012024071000580C012025071000FA +:105B0000501E100041490022CA70487800280ED16A +:105B100008783F4B401CC0B208701B6893F80232F3 +:105B200003F00F03834202D2012048700A707047CD +:105B3000364900220A70487800280CD0C878344BC7 +:105B4000401CC0B2C8701B6893F80232B0EB131F40 +:105B500001D94A70CA7070472C4810B581784170DD +:105B600000210170C170FFF790FDBDE81040FFF704 +:105B700097BB264800214170817070472DE9F041A4 +:105B8000244B254C224DB3F90030012A05D02A6858 +:105B900092F81D62C6F1100212E002461E4810F093 +:105BA000E1F90FE030F9137031F913C0A7EB0C07DE +:105BB00034F913C057430CFB06773F1124F81370D8 +:105BC0005B1EEFD200210E4619E0144A12F8112094 +:105BD00012F0FF0390F83020A2EB030002FB01F269 +:105BE00004EB4202C0B2168003D107E022F8106035 +:105BF000401C2B6893F830308342F7DC491C28683E +:105C000090F831208A42E0DCBDE8F08128051000E0 +:105C1000A00710003A071000440D0120342601208F +:105C20002DE9F05F9846DDE90A9A93460E46044650 +:105C3000002532E02A460120002114F0E6FB00EAAC +:105C4000090001EA0A0108431DD0FE48FE4910F888 +:105C50001500097840B2091A4FB2410004EB470021 +:105C600014F09CFC00202080012009E004EB40019E +:105C700036F8102031F8021C114424F81010401C92 +:105C8000B842F3DB04E04FEA4801204614F086FCFA +:105C900006EB480604EB48046D1C5D45CADBBDE815 +:105CA000F09F2DE9FF5F86B0DDE914AB0FFA8AF0B3 +:105CB0000390DDF860800FFA8BF00490E3484078A1 +:105CC00028B14FEA2A4003904FEA2B400490002469 +:105CD00039E0079908FB04F001EB4005DDE9080114 +:105CE000224614F0A5FBC00724D0169ACDF800A0D8 +:105CF000CDE901B2DDE903214346284600F09CFCD2 +:105D0000064617980F46012817D0B8F1010F14D096 +:105D1000CC48012530F9149009E0A8EB05020120D8 +:105D2000002114F072FB86438F436D1CEDB2A94530 +:105D3000F3DA02E04FF0FF363746069800EBC40076 +:105D4000641CC0E9006717988442C2DB0AB0A6E76A +:105D50002DE9F05F1D46DDE90A9A93460F46064697 +:105D6000002420E0B7482246002110F81400281A29 +:105D700000F0FF08012014F048FB00EA090001EAE6 +:105D80000A01084305D04246394630460FF0E2F991 +:105D900004E04FEA4801304614F000FC07EB4507E9 +:105DA00006EB4506641C5C45DCDB78E72DE9F84F23 +:105DB00083460AA8002690E8280590B289460090FC +:105DC00031463446B446374630460FE0DA0708D04D +:105DD00039F9102000FB004400FB02770144944491 +:105DE000761C6D084FEA330300F101004045EDDBFE +:105DF00004FB06F001FB1105F5B107FB06F004FBFF +:105E00000CF407FB114701FB1C06002410E006FB05 +:105E1000047090FBF5F1A1EB0A00009900F0C9FFB6 +:105E200039F81420A2EB0A01081A2BF81400641C9C +:105E30004445ECDBBDE8F88F4FEA48024946584636 +:105E4000BDE8F84F14F02BBBF0B50026354609B17C +:105E500000240DE00020F0BDD70704D030F9147005 +:105E60006D1C3E44EDB25B084FEA320204F10104BE +:105E70008C42F1DB96FBF5F000B2F0BD2DE9FF5F3F +:105E800086B00025DDE91619A8464FEA510A4FEA07 +:105E9000590B2C4649E0DDE90801224614F0C8FA06 +:105EA000C00741D01498524600EBC4010491D1E9D7 +:105EB00000670120002114F0A8FA401E41F1FF31D3 +:105EC0000F4004990640CDE90067D1E90001524630 +:105ED00014F0AEFACDE902010821684613F0DEF8AD +:105EE000C7B2082102A813F0D9F8C6B2B819C0B2D7 +:105EF0000490DDE90601224614F09AFAC00704D0A6 +:105F0000DDE91701084400F0FF090498484503D370 +:105F10005F4501D35E4507D222460120002114F0DF +:105F200074FA054341EA0808641C15988442B2DB00 +:105F3000284641460AE72DE9F04F85B08146119F7A +:105F40000024780092469B468846049036E00E98DE +:105F500000EBC400D0E900561298012801D125F0C9 +:105F6000010550465946224614F062FAC0071CD07B +:105F7000DDE91401224614F05BFAC00705D0414662 +:105F80004846049A14F08BFA13E02A463346394601 +:105F90004046FFF759FFCDE90270CDE90056414672 +:105FA00048460F9AFFF702FF03E04846049914F0B1 +:105FB000F5FA08EB470809EB4709641C109884427E +:105FC000C5DB05B0BDE8F08F2DE9FF5F86B08A46DE +:105FD00000211B9F04907800884689460C46DDF816 +:105FE00074B0059058E01498224600EBC400D0E944 +:105FF0000056DDE9080114F01BFAC00741D0DDE9C5 +:106000001801224614F014FAC0073ED03A4628463A +:1060100031460FF0D3F80090DDE91601224614F066 +:1060200007FAC00704D0DDE91D01084400F0FF0BAA +:106030000098584516D92A46334639465046FFF748 +:1060400003FF05E03426012025071000D8071000C3 +:10605000CDE90270CDE9005651461C9A0498FFF72D +:10606000A5FE12E0DDE90402514614F018FA2246BA +:106070000120002114F0C9F940EA080841EA0909A1 +:1060800003E05046059914F089FA04980AEB470A90 +:1060900000EB4700641C04901A988442A3DB40463E +:1060A000494653E62DE9FF5F9846002537E0019900 +:1060B00008FB05F001EB400B0099002601EB400ABC +:1060C00037462A460120314614F09FF9DDE91023B6 +:1060D0001040194008431BD00E98002400EBC5095E +:1060E00014E0F848025D3BF812102AF81410D9E9C0 +:1060F000000114F09DF9C00706D0224601200021BE +:1061000014F083F906430F43641CE4B24445E8D31A +:106110000E9800EBC5006D1CC0E90067EDB2029857 +:106120008542C4D3BDE8FF9F2DE9FF4F81B099465A +:1061300000253BE0029909FB05F001EB40010091CD +:106140000199002601EB400B37462A4601203146D3 +:1061500014F05BF9DDE910231040194008431ED00C +:106160000E98002400EBC50A17E0D64810F804800A +:10617000009830F814202BF81820DAE900012246A4 +:1061800014F056F9C00706D042460120002114F051 +:106190003CF906430F43641CE4B24C45E5D30E982A +:1061A00000EBC5006D1CC0E90067EDB203988542A5 +:1061B000C0D306E72DE9F74FC34E0F468CB03068C9 +:1061C000002190F83120012014F01FF9441E41F104 +:1061D000FF35BC49002018390870B821BB4814F0BD +:1061E000FFF9032012F0E9F9306890F8E602C007E1 +:1061F00014D0B748007888B9B6480178B6480FF08F +:10620000FAFE3168B1F80923B449904202DCB4487F +:106210004078D0B1B34A0020D0700870B248DFF89F +:10622000D0923946B0F90030B0480268D9F8000081 +:106230000FF098FEA448006890F8010200064ED5C1 +:10624000AC480078012804D049E0A6490120C87074 +:10625000E4E70021DFF8A0A2DFF86CE239E0A74A0A +:1062600090F8300032F9112000FB01FB871A012061 +:106270002CE0D9F800600BEB000336F91320B2F1E3 +:10628000000C01DACCF10002BAF90080424513DDBE +:1062900091B1DEF8002092F83120521E8A420BD0D4 +:1062A000012809D07A1E904206D05FEA0C0201D57F +:1062B000CCF10002AAF80020DFF844C236F813201F +:1062C000401C3CF813C0624426F81320B842D0DBCF +:1062D000491CDEF8000090F831308B42BFDC03200F +:1062E00012F086F9784EDFF81CB2306890F81D0184 +:1062F000C00714D07B48417A89B9817A79B9C078CE +:1063000068B981480078012809D072489BF80020BC +:106310000178D9F8000001F048F904460D463068CC +:1063200090F83402400713D5CDE90045694F5E4629 +:106330009BF800303A78D9F800100C98FFF770FC01 +:10634000CDE9004533783A7870480C99FFF700FDA5 +:10635000DFF874A1049B039ADAF80000DFF8748177 +:10636000B0F8511261F30F03B0F95312059161F3C4 +:106370001F43B0F855121F4661F30F02B0F95712D0 +:10638000069161F31F4290F85932029990F85D62CC +:1063900063F3070190F85C3298F8000063F30F2173 +:1063A0009BF8003066F317410097CDE90121CDE954 +:1063B000030322462B4655495548FFF772FC3146E8 +:1063C00053480EF018FFDAF800100026DFF840A15D +:1063D00091F834023746C0F38002C0F3C0031A407C +:1063E000C0F34000024224D091F85A0291F85912A9 +:1063F0009BF8003098F80020CDF800A0CDE90123EB +:10640000CDE903102F48224618382B46D0E9021652 +:1064100008463146FFF732FD06460F46084308D0CE +:106420002948006890F85E2230460EF05DFE064670 +:106430000F462548006890F834128A0778D5B0F9DD +:106440004B0201902648407808B1069801908806D2 +:106450000ED5CDF800A0CDE902459BF8003098F8A4 +:1064600000202C48D9F80010FFF71CFE294901E054 +:10647000D9F80010CDE906679BF8003098F800C005 +:106480000120CDF808C0CDF800A0CDE903302246A8 +:106490002B460C98FFF74FFD0B48006890F834022C +:1064A00080063AD5CDE90245CDF800A09BF8003032 +:1064B00098F800200C99D9F80000FFF735FED9F8BC +:1064C00000102BE048051000A0071000181F100056 +:1064D0007407100024071000F87601203007100020 +:1064E000D8071000945A10003A07100058071000FF +:1064F00054071000290510002E0510003426012035 +:10650000440D01202507100018051000D04F012070 +:10651000601E1000801301200AE00C9998F800001A +:1065200042009BF800004243D9F8000013F0B7FF87 +:106530005448CDE90045C346037898F800205248F6 +:10654000D9F80010FFF76CFBDFF84081D8F80000A5 +:1065500090F83412090718D54D49B0F94D02497821 +:1065600001B105984749CDE9066700220B789BF8F1 +:106570000010CDF800A0CDE90332CDE9010122469B +:106580002B4641490C98FFF7D6FCD8F80000C146CD +:1065900090F83412C1F38002C1F3C0031A40C1F372 +:1065A00040010A4231D000220E9B1146012B05D139 +:1065B000384B9046C3E90288C3E9048856EA0703CA +:1065C0001ED0304B90F85A1290F85B22B0F94F026F +:1065D0001B78CDE9080207930A919BF80000049606 +:1065E000CDE905702B4822462B46D0E90410CDE9B1 +:1065F0000210CDF800A028490C98FFF7E5FC0246F0 +:106600002448C0E90421C0E90267D9F8000090F8E5 +:106610003402C00608D51B48CDE900459BF80010A0 +:1066200002780C980FF0F9FC204629460FB0C9E417 +:106630001A490020087070472DE9F0470F46994627 +:10664000804611460A9E0EF000FD04460D46002FBE +:1066500016D04B463A466FF0004140460EF014FD0E +:1066600004F00102024304EA0200294001220EF074 +:1066700064FDC6F30722002A02D04B460EF0BDFC93 +:10668000BDE8F0872507100080130120A007100047 +:10669000D807100030051000D04F01202A07100045 +:1066A0002DE9F05F1E4615460F46824600244FF046 +:1066B000AA094BE0305D08B9285DE8B306F80490FC +:1066C00037F9140000F0C8F827F81400285D98B3D3 +:1066D00005EB040818F8011C814218D0AA2816D02E +:1066E0000AEB440B08F8019C3BF9020C00F0B4F8EB +:1066F0002BF8020C311907EB440B01F8019C3BF914 +:10670000020C00F0A9F82BF8020C285DA0B198F853 +:106710000110285D814218D0AA2816D088F801906F +:106720000AEB4408B8F9020000F096F83119A8F80D +:10673000020081F8019000E007E007EB4408B8F997 +:10674000020000F089F8A8F80200641C0A9884424C +:10675000B0D3BDE8F09F48490020086070472DE99C +:10676000F74F464884B0924600788946002870D09A +:106770004348006890F8700C80076AD54148009043 +:106780004148DFF8F4B0012507784FF00008DBF846 +:1067900000601FE00120A84030421AD13B4800EBC6 +:1067A00085040098A17814F011F8A27843460DE012 +:1067B000217805E010F801C0AC4500D14354491CD4 +:1067C00094F801C08C45F5DA2830521CE1789142EA +:1067D000EEDA6D1CBD42DDD90021049813F0FCFFF8 +:1067E00002900121049813F0F7FF01900021254841 +:1067F00013F0ECFF07460121224813F0E7FF06469D +:10680000A9F10105E9B2049813F0E6FF6C1E0390AC +:10681000E1B2049813F0E0FF8146E9B2194813F0A1 +:10682000D5FF0546E1B2174813F0D0FF0446CDF876 +:1068300000A0DDE9011033463A46FFF731FF234659 +:106840002A464946CDF800A00398FFF729FFCBF868 +:10685000008007B0BDE8F08F0949096891F8782CED +:106860004243642092FBF0F0B1F8762C00B28242F1 +:1068700001DAB1F9760C70476C051000E8061000DB +:10688000A00710001E27012071061000B62A012063 +:106890002DE9F041FE4E2A21FE48376807F2826555 +:1068A000EC1C13F07BFEFB4897F8312097F8301072 +:1068B0002A3013F06BFE00221146F64F33681DE0BC +:1068C000A05C884201DA521CD2B2A85C27F8110001 +:1068D00090B193F83060DFF8BCC3301AC0B20CF14D +:1068E0002A0C05E01CF80060761E0CF80060401CC5 +:1068F00093F830608642F5DC491C49B293F83100C8 +:106900008842DDDCBDE8F0812DE9F04F89469246F2 +:1069100086460021DFF878B34FF0640C099E45E00D +:1069200001FB06E700203EE0DBF80020802492F81F +:106930002D5B5FEA45781FD592F8158C884503D109 +:1069400092F8168C804526D092F8178C884503D192 +:1069500092F8188C80451ED092F8198C884503D186 +:1069600092F81A8C804516D092F81B8C884503D17A +:1069700092F81C2C82420ED011B15A1E914219D1AC +:10698000AA0703D538B1721E904204D01AF800202D +:10699000D201B2FBFCF43A5C6243D41702EB5462BE +:1069A000D2093A54401CB042BED3491C9942B7D3D5 +:1069B000BDE8F08F19F80020EAE72DE9F05F944672 +:1069C000B54ADFF8D8A2DDF8308016789AF80020B2 +:1069D0003746761E06FB02F400EB440506FB02C0B8 +:1069E00008FB0306AE48DFF8A88201EB44040378F5 +:1069F000AC48DDF828B04FF000090279C178D8F82A +:106A000000006BB101B942B190F8131C90F8140C5E +:106A1000814200D30146894626E090F8130C03E03A +:106A200001B90AB390F8140C81461DE058463A4665 +:106A30000B9913F0FDFCC0070DD09AF8000008E098 +:106A4000335C34F9101003EB09025143C91125F8E6 +:106A50001010401EF4D2D8F8000090F83000A5EBDA +:106A60004005A4EB4004361A7F1EDFD2BDE8F09F3C +:106A700008B5009313468C4AB2F900200FF07EFA55 +:106A800008BD2DE9F05F874A1046D178007901B939 +:106A900008B1012400E0002484494B780021022B36 +:106AA00001D3917000E000B1D170DFF8E4A1D0789B +:106AB0009146DAF80010B1F9B9C2B1F9D462B1F96E +:106AC000E87228B17A480078012801D1B1F901C3F0 +:106AD00078480078052801D0062801D1B1F9B6C25E +:106AE000022B05D3B1F8BD2212B1B1F9BDC20DE040 +:106AF00063B191F8BC2262440FFA82FC91F8D7226C +:106B0000324416B291F8EB223A4417B26A4DDFF8DC +:106B1000ACE16B4AA5F800C0AEF800601780694A86 +:106B200005283DD006283BD091F8BB82DFF8A0B104 +:106B3000ACEB0808A2F8008091F8D682A6EB080812 +:106B4000614EA6F8008091F8EA82A7EB08085F4F33 +:106B5000A7F800809BF80080B8F1000F05D09BF8E3 +:106B60000280ACEB080CA2F800C099F800C0DFF876 +:106B700030B1BCF1000F1ED09BF800C0BCF1000F7B +:106B800019D0B1F805C2A5F800C0B1F807820528F0 +:106B9000ACEB080CA2F800C005D0062803D00AE030 +:106BA00091F8B882C2E7B1F80A022880B1F80CC2A5 +:106BB000A0EB0C00108099F8020028B9B5F800C0CD +:106BC000AEF800C01088308034B93D48B5F800C038 +:106BD000A0F800C01088388028883E4DDFF8F8C043 +:106BE0002880B2F900003D4AACF8000012786AB182 +:106BF00013B191F8752C00E00022B1F8723C1A44F0 +:106C00002A8091F8741C511AACF80010B7F90020D2 +:106C1000B6F900100EF018F9314908809BF8000011 +:106C200030490028DAF8000002D0B0F8450206E04A +:106C3000B0F843220A80002C02D0B0F84702088046 +:106C400014E72DE9FF4F82B00027DDE91142DDE9AD +:106C500013C80F9D224374D00026B146B646B346F2 +:106C6000B246BCF1000F01D0159D47463A4645E0BB +:106C70005FEAC47C0BD031F912C002FB029902FB1F +:106C80000CBB1644E6440AF1010ACDF800C02BE023 +:106C9000A00710003426012024071000250710004B +:106CA00029051000945A10003A071000D807100068 +:106CB0003107100021071000D0061000D206100086 +:106CC000D4061000D6061000D8061000DA06100010 +:106CD00074071000E4061000E606100039071000E3 +:106CE000DC061000DE061000DDF848C002F10102EB +:106CF0005FEA5C0C4FEA3404CDF848C0AA42B7DB27 +:106D000009FB0AF206FB16220092BAB30BFB0AF249 +:106D100006FB1E22019209FB0EF20BFB162A4FF016 +:106D2000000C62463C4622E0DDF80480009E08FB31 +:106D300004A898FBF6F6DDF81080464502DD4646CD +:106D400003E033E0DE4200D55E4231F81480A8EB68 +:106D5000060636B2B1469E4206DA06EB0308B8F1E3 +:106D6000000F01DDCC44521C20F81490641CAC428E +:106D7000DADB002A0BD09CFBF2F206E00EE030F8E2 +:106D80001710891A20F817107F1CAF42F7DB06B0E6 +:106D90000EE631F8172020F817207F1CAF42F8DBF1 +:106DA000F5E731F8172020F817207F1CAF42F8DBF9 +:106DB000EDE7884202DC4942884200DA0846704723 +:106DC000F0B50026354609B100240DE00020F0BDE5 +:106DD000D70704D030F914706D1C3E44EDB25B0847 +:106DE0004FEA320204F101048C42F1DB96FBF5F02C +:106DF00000B2F0BD2DE9F05F5FEA0109DDE90ACEDE +:106E00000E9E05467ED052EA03007BD04FF000086C +:106E10009A464046414647464446B346434611E0FB +:106E2000D60709D035F9136003FB031103FB0644B1 +:106E30001844374408F101085FEA5A0A4FEA32025F +:106E400003F101034B45EBDB01FB08F200FB1026CD +:106E5000002E57D004FB08F200FB1728794304FBEF +:106E600010175FEA0E0057D00024A9F1020210E0CB +:106E700008FB047090FBF6F0A0EB0C005946FFF7FE +:106E800098FF35F81410A1EB0C01081A25F814002E +:106E9000641C9442ECDB0C984FEAC01A0D984FEA40 +:106EA000C01B08FB047090FBF6F935F91400594635 +:106EB00000EB8000000290FBF9F00DF0DBFF514683 +:106EC0000DF0DCFF09FB00F14FF00A0991FBF9F02E +:106ED00035F81410A1EBE01025F81400641C08FB31 +:106EE000047090FBF6F635F91400594600EB80006B +:106EF000000290FBF6F00DF0BDFF51460DF0BEFF15 +:106F0000464300E007E096FBF9F035F81410A1EBDA +:106F1000E01025F81400A9E5002210E008FB02703B +:106F200090FBF6F0A0EB0C005946FFF742FF35F856 +:106F30001210A1EB0C01081A25F81200521C4A4548 +:106F4000ECDB93E52DE9FF5FDFF828A40E46002473 +:106F50000E9D1F4691464FF466713046CAF80040B8 +:106F600013F01CFB002130462C6013F02FFC04466C +:106F70000021009813F022FCDFF8FCB30246FF4E1C +:106F80009BF800C019E030784FF001080FE032F9AB +:106F900010304B4501DD04F8008032F91010F94241 +:106FA00005D52B68002900DA494219442960401EA2 +:106FB000EDD23078283402EB4002BCF1010CE2D271 +:106FC000EF48C07800281BD00021009813F0F6FB92 +:106FD000EC499BF80030524634780D680EE02146AB +:106FE00008E030F91160B5F8FB72BE4202DD1668A8 +:106FF000761C1660491EF4D200EB44005B1EEED2F4 +:10700000BDE8FF9F05E030F912308B4201DD012021 +:107010007047521EF7D2002070472DE9FC47DA482E +:10702000DA4DDB4FB0F90230B5F900003A88594328 +:10703000821A14B2642291FBF2F109B2814200DD9E +:1070400008462880CF48026892F88112490632D556 +:10705000D04EB2F89DC2B6F900109C4526DAB2F8BF +:107060009F328B4222DD8146CB48B2F8A4C2006831 +:107070000CEB8C08B0EB480F18DD8021CDE9003116 +:10708000B2F8A21292F8A13201EB81014A000CEB96 +:107090008C01C84649000EF029F901B2D8F8000069 +:1070A000B0F89F228A4201DAB0F99F12B6F90000C7 +:1070B000814200DD31802888001B3880BDE8FC87D4 +:1070C0002DE9FC47B548ADF80000ADF80400B44820 +:1070D0000027DFF8D082B0F90000DFF8CCA2420030 +:1070E0003E463D463C46D8F80010DAF8000013F062 +:1070F000D6F9A349A3480A781AB1AC4A1278012AF2 +:1071000002D0C978C1B11DE08146006890F8011233 +:10711000490708D5B0F92032A54ADAF80010D8F8A6 +:10712000000009F0C1FFD9F8000090F8011209072A +:1071300008D590F8244205E09E4900684978B9B125 +:1071400090F825419C4801AA69460378D8F80000C8 +:107150000EF0F3FF24B12146D8F80000FFF75DFFE1 +:10716000BDF90010BDF90400814204DD0A4603E0C8 +:1071700090F82641E6E70246834B5A808F4AB2F9DF +:107180000020914200DD01268D4AB2F90020904294 +:1071900000DD01258B4A2E43157000D001278A4A55 +:1071A00012F8873F67F3000365F341031370A2F8F9 +:1071B0000110A2F80300384680E72DE9F74F834F0E +:1071C00086B0DFF8C0B13E780496DBF80000914647 +:1071D000002190F83120012013F017F9441E41F1ED +:1071E000FF35304608F073FA4FF0000887F800804A +:1071F000FFF747FC64480221001D0BF099F9604F2E +:10720000614EDFF8CCA1387808B9787828B14946C2 +:1072100072680798FEF750FA01E08AF80080F87A61 +:10722000DFF88091012805D0787A012802D0B87A59 +:10723000012803D19AF8000001284BD06548007856 +:10724000012806D1049A06997068FEF7B3FF044638 +:107250000D46DBF8000090F835124A0605D4090601 +:1072600003D490F82D0BC0070CD05B485B4A007824 +:107270000094CDE901504A487168B0F900300846E1 +:10728000FFF79BFBDBF8000090F834120A0604D4E9 +:10729000490610D5F97801290DD1B0F9490201A9A3 +:1072A000009081E8310035487168037832480278EF +:1072B000084600F005FB314802782F4801787068D5 +:1072C000FFF74DFA4648049B71680268D9F8000040 +:1072D000FFF7CEFBDBF800005D4690F81D1CC907E8 +:1072E00015D0264B90F8161C90F8150C1C7800FB56 +:1072F0000414D9F8001021F8148028681B7890F83D +:10730000184C90F8170C00FB034021F810802868F7 +:1073100090F8441AC90706D0D9F8001090F8452A09 +:10732000084609F04BFC18480221001D0BF05EF9DD +:10733000F97A0020012905D0797A012902D0B97A99 +:10734000012903D19AF80010012901D0FFF7B8FEF6 +:10735000244A254E0121C2F80080064AC2F8008066 +:10736000224AC6F8008082F80080FB7A012B65D0A3 +:107370007B7A3DE0C40610002407100025071000AA +:10738000945A1000A007100070051000D0061000DD +:10739000D6061000DE061000600710000080FFFF18 +:1073A0003A0710004C071000500710002905100084 +:1073B00006A80100D807100074071000DC061000B2 +:1073C000E60610002D07100038570120DE071000D8 +:1073D000140510002A07100035071000BC19012001 +:1073E000E0061000C0061000C80610002C071000B0 +:1073F000012B23D0BB7A012B20D018B31170387821 +:1074000018B1F8480078012824D002240121F64858 +:107410000BF08EF82968F54AB1F86B0212780AB1C0 +:10742000B1F86002009603B2F148B0F90020EE48CE +:107430000168D9F80000FFF785FD04E09AF8000024 +:10744000012804D00124204609B0BDE8F08F0624AD +:107450001170F8E70324D9E7FEB50746E548002593 +:1074600006780570FFF70DFB0221E3480BF060F88A +:10747000E248E14C0078241F012804D13246394605 +:107480006068FEF797FEDE4EDE4F306890F83512EA +:107490004A0605D4090603D490F82D0BC0070DD079 +:1074A000D948DA4A007802904FF0FF30CDE9000069 +:1074B0006168B7F900300846FFF77FFA6168B7F9ED +:1074C0000000D34C4200206812F0E9FF306890F8C9 +:1074D0001D1CC90714D0CF4B90F8161C90F8150C42 +:1074E0001A7800FB0211206820F8115031681B78CF +:1074F00091F8182C91F8171C01FB032120F811506A +:10750000306890F8441AC90705D0216890F8452AD8 +:10751000084609F053FB0221B7480BF067F8BE4854 +:10752000B7F90020B0F900102068FFF76BFDBB49E8 +:10753000BB4E0D60BB4935600D7090B101200870E5 +:1075400001460225A8480AF0F3FFA948009647F62D +:10755000FF73B0F90020A44801682068FFF7F2FC2F +:1075600000E001252846FEBDA34910B5091F0020F3 +:107570004860AC490870AC490870FFF759F8FFF74C +:10758000EAF8BDE8104000F013B910B500F05CF95E +:10759000FFF77EF99A48006890F88102000603D54B +:1075A000BDE8104009F07DBE10BD2DE9F74F86B053 +:1075B0000020CDE90000CDE90200814690480F4649 +:1075C000164600680025B0F91E110591B0F920019A +:1075D00004902FE005FB06F00FFA80FB04980124CD +:1075E000C0F1000A2A462046002112F00EFFA446F0 +:1075F0000A460CFA05FC4FF0000817E006990BEB61 +:10760000040331F91310059B994201DC514506DA58 +:10761000DDE9003403431443CDE9003434464945E1 +:1076200002DDCDE902C88946641C24B2B442E5DB20 +:107630006D1C2DB2BD42CDDB714C206890F822212B +:107640002AB1DDE900010DF04FFDCDE90001206810 +:1076500090F81D01800762D5DDE9000108435ED086 +:107660000821684611F01AFDC1B2206890F8230184 +:10767000884254D9401E40F34702DDE902010DF073 +:1076800033FDCDE9020105460E463A4601200021B0 +:1076900012F0BBFE401E41F1FF3100EA050231400D +:1076A000CDE90221082102A811F0F8FC2168C0B23E +:1076B00091F8231181422CD97A1E0120002112F069 +:1076C000A4FEDDE9022310401940084310D0781EC3 +:1076D000012305E0029D03FA00F12943401E0291B7 +:1076E000216891F82311791A491E8142F2DB10E0DA +:1076F000D0070ED00020012306E0029D03FA00F11E +:107700002943401CC0B20291216891F823118142A3 +:10771000F3D89DE80F0010431943CDE9000120681C +:10772000002190F83120012012F06FFE401E41F13F +:10773000FF33DDE9001201401A40CDE90012206854 +:107740002D4D90F827012D1FF0B12B786BB15B1CEC +:10775000DBB22B70984201D3114301D0002012E01C +:10776000D5E90201CDE900010EE03048007858B1BA +:10777000114309D1D5E9020150EA010204D0CDE953 +:107780000001D8B2401C2870DDE9000108430BD18C +:107790002068002190F83120012012F036FE401EB2 +:1077A00041F1FF31CDE900010098C5E902014BE646 +:1077B000134810B500681E491E4AB0F8B9320B8054 +:1077C000B0F8D4121C4C1180B0F8E82222801B4C77 +:1077D00023801B4B19801B490A800549B0F84302DE +:1077E000088010BD2905100088061000B30610009F +:1077F000DE061000DE071000740510002A071000D6 +:10780000A00710003A07100035071000BC1901202E +:107810004C07100025071000DC061000C006100001 +:10782000C80610002C0710002D07100032071000AA +:10783000D0061000D2061000D4061000D6061000A4 +:10784000D8061000DA0610002DE9F84F3B4C2068EE +:1078500090F8319010F8307F90F8450100F0030265 +:10786000C0F38101C0F301100DF0F5FA25688046E0 +:107870004FEA89002B4605F62F367843304A80219F +:1078800005F6553500E01154401EFCD293F82D0B3F +:10789000C00713D000249246DFF8A8B00CE0009790 +:1078A000BBF900104B4604FB01A02A463146FFF706 +:1078B0002BF8641C4C354C364445F0D9BDE8F88FA4 +:1078C0002DE9FF4F8646DDE90FAB1D46DDF834900C +:1078D0002FE00199002601EB45071B4930464A5D20 +:1078E0000E991446C1F1000C09E004FB03F137F9CD +:1078F0001110494503DA614501DD0E44401C641E48 +:10790000F3D200B9012096FBF0FC504659460EEB2D +:1079100045060CE0C40707D002FB03F437F81480D7 +:10792000A8EB0C0826F8148049084FEA3000521ED4 +:10793000F0D26D1ECDD2BDE8FF8F0000A007100071 +:10794000BC1901203A0710005E2601209048002152 +:1079500001704180704730B58E49024601200B68A6 +:1079600093F84B464CB18A4DB2F842106D68491BF2 +:1079700000D549428C4200DA002093F84C36002BA7 +:1079800012D08349B2F91A500831B2F91820B1F96E +:107990000240B1F90010641B891A644301FB0141E4 +:1079A0005B43994200DD002030BD2DE9F047DFF850 +:1079B000E491DFF8DC8105004FF005044FF0060686 +:1079C00013D095F8C60100F04EFA0446D9F800002D +:1079D000012790F84A0618B1B5F84210814210D834 +:1079E000A86900F0AAF860B157B398F80000002722 +:1079F0000121072810D2DFE800F00606263F7206B4 +:107A000006000027F0E7052C04D0042C06D0012C3A +:107A100007D015E088F80070BDE8F08788F80010FE +:107A2000FAE7FFF793FF022088F80000A8F8027039 +:107A3000B5F84200C8F80400A869C8F80800EBE7E8 +:107A400088F80060E8E7B8F80200401C80B2A8F8A7 +:107A50000200032C04D0D9F8001091F845164AE032 +:107A6000032088F80000A8F80270D5E7052CD3D0D1 +:107A70002846FFF770FF2FE0B8F80200401C80B2E4 +:107A8000A8F80200012C1FD0D9F8002092F8463641 +:107A900042468342C0D8167098F80100012801D0F0 +:107AA0000328B9D13C483A4A417019210832817003 +:107AB0005188C170090A017111884171090A8171E7 +:107AC000BDE8F0470CF0D3BD2846FFF744FF042281 +:107AD00088F80020A8F802700028B1D09CE7B8F818 +:107AE0000200401C80B2A8F80200032C06D0D9F88E +:107AF000001091F847168142B8D8A1E7052088F810 +:107B0000000089E738B500210091694600F089F945 +:107B10001F4C012802D90620207005E00098FFF7CD +:107B200044FF2078052801D0002038BD1A480121E3 +:107B3000417005218170012038BDF0B51549064618 +:107B40000120096891F84826930091F849261D46BE +:107B5000940091F83620D7074A8E898EA2EB030253 +:107B6000A1EB040112B209B20ED023460F462C46F7 +:107B70003114994206DBB94204DC31B2A14201DB87 +:107B8000914200DD0020F0BD17460A46F0E70000F4 +:107B900084051000A0071000D01F100000F0ECBA00 +:107BA000BA4890F82C00062801D0052807D1B8481B +:107BB000B849006890F83E0200F00F000860B6492E +:107BC0000020487000F0E4BA70B50646B3480021C2 +:107BD0000278062A03D012B1052A00D00121B0484C +:107BE000AD4C0278012A2ED0022A2CD0032A2AD0AA +:107BF00049BB12F0AFFD012825D0AA48007806281D +:107C00002AD1607820B1401E10F0FF00607023D1AF +:107C1000002404EB041006EB40152946304604F01E +:107C2000F2FF2946304605F026F8641CE4B20F2C1A +:107C3000EFD39D48007805280ED0BDE87040102194 +:107C4000012010F01ABC9248006890F8780060702B +:107C50000A2801D20A20607070BD2DE9F04100248D +:107C6000054600F580560127D6F8E00F07FA04F123 +:107C7000084208D004EB041005EB401000F1180195 +:107C80000C300DF0E3FC641CE4B20F2CECD3BDE827 +:107C9000F0812DE9F0474FF000094FF0010A064648 +:107CA000C8464C4600F580575546D7F8E00F05FA10 +:107CB00004F108420AD004EB041106EB411191F8DB +:107CC000C601032802D1304604F0BBFF641CE4B2B5 +:107CD0000F2CEAD33046FFF7C0FF744800216E4CEA +:107CE000016041608160C160A068C00104D5304678 +:107CF00000F089FD012809D0BAF1000F06D0207AE2 +:107D0000800603D53046FFF7FDFE8146B9F1000F2E +:107D10000AD1A068C0011BD5304600F04DFB644974 +:107D200008704FF0180898B160480CF0A0FCB8F14A +:107D3000180F0BD15D4808300CF097FC584880793B +:107D400000EB001006EB40100CF07CFCFFF7FEFD92 +:107D50000024A84606F5805708FA04F0D7F8E01F7B +:107D600001420FD004EB041106EB411595F8C60152 +:107D7000082807D12946304604F07DFF29463046C1 +:107D800004F041FF641CE4B20F2CE5D33046BDE89B +:107D9000F04719E72DE9F84F06463D48006890F88E +:107DA000500CC00738D03046FFF757FF3A4F4FF01E +:107DB0000009B868C00131D5304600F0FEFB8046AE +:107DC0003A4800240830CA464FF0010B06F58055AA +:107DD000B94600901CE0D5F8E01F0BFA04F05A46B3 +:107DE000014214D004EB041006EB4017B8F1000F69 +:107DF0000BD089F800202D480CF039FC00980CF0CD +:107E000034FC38460CF01EFC01E089F800A0641C2C +:107E100095F9EC0FA042DEDABDE8F88F87F8009004 +:107E2000FAE730B505460020034603EB031205EBE5 +:107E3000421494F8C621012A0DD0022A0BD0032A3D +:107E400009D0042A07D0052A05D0062A03D0072A1C +:107E500001D0082A02D1401CC0B20C605B1CDBB20E +:107E60000F2BE2D330BD09280ED2DFE800F00D055C +:107E700005070909090B0B00042070470120704712 +:107E800002207047032070470520704714841000BB +:107E9000A0071000E00610009005100084051000F7 +:107EA0003820100021071000F8041000D01F100027 +:107EB000AA0510002DE9FE4FFE49B0F902C0B0F945 +:107EC00006700A68B0F90060934692F83690918E79 +:107ED0005FEAC978B0F90450528E4FEA497809D068 +:107EE000B8F1000F22DA961B551B66F31F4465F3A9 +:107EF0001F431FE0B8F1000F07DAA2EB0C0CD71BF1 +:107F00006CF31F4467F31F4303E067F31F446CF3F4 +:107F10001F435FEA897704D58E1B66F30F044D1B60 +:107F200010E065F30F0466F30F0312E065F31F44DE +:107F300066F31F435FEA897507D5A1EB0C0565F36E +:107F40000F04CD1B65F30F0303E067F30F046CF31D +:107F50000F039BF830804F1CB2FBF8F59BF8319073 +:107F60002EB2B7FBF9F52DB2002A75D0002973D0D7 +:107F7000002E71D0002D6FD01F144FF0000B12D0C7 +:107F800097FBF6FC6CF3070A97FBF6FC06FB1C77E5 +:107F9000BFB24FEA244C624509DCA8F1010262F34A +:107FA0000F2AB2B20CE06BF3070A0027F1E79CFB43 +:107FB000F6F262F30F2A9CFBF6F206FB12C292B2B3 +:107FC0001BB28BB193FBF5FC6CF3174A93FBF5FCEA +:107FD00005FB1C339BB224B2A14209DCA9F10101CB +:107FE00061F31F6AA9B20CE06BF3174A0023F2E7B2 +:107FF00094FBF5F161F31F6A94FBF5F105FB114168 +:1080000089B202EB8202520092FBF6F21FFA82FE64 +:1080100007EB870403EB83026400520001EB81014C +:1080200094FBF6F492FBF5F2490091FBF5F1C4F1F3 +:108030000A04C2F10A02A4B292B289B28DE8160013 +:108040000AF0FF034FF0000C9B46CAF307464FEAC5 +:108050001A65CAF3072726E036E09B4502D102994C +:108060000CB205E09F4202D10FFA8EF400E00A2420 +:10807000019A31460FFA82F9009A0FFA82F80EE05F +:108080008E4201D14A4604E08D4201D1424600E0D1 +:108090000A2204FB02C2491C0FFA82FC09B28D427B +:1080A000EEDA5B1C1BB29F42D7DAA0F80CC080F856 +:1080B00008B0477202990182A0F812E08672C57278 +:1080C000019981820099C182BDE8FE8F70B57A481E +:1080D000784D7A490378286801F11C0490F8512CF6 +:1080E000CA811BB390F8402C8A76B0F8412C4A80A4 +:1080F000B0F8452C0A80B0F8432CCA80B0F8472C61 +:108100008A8090F8492C0A7690F84A0C48760846FE +:10811000FFF7D0FE1C226949204612F0C0F92868FA +:1081200090F84C1C217690F84D0C23E090F8522CDE +:108130008A76B0F8532C4A80B0F8572C0A80B0F8F1 +:10814000552CCA80B0F8592C8A8090F85B2C0A769E +:1081500090F85C0C48765948FFF7ACFE57491C2252 +:1081600001F11C0012F09BF9286890F85D1C217643 +:1081700090F85E0C607670BD4F4900200870487022 +:10818000897821B94D498863C863A1F840009DE70B +:10819000494A9078002819D148498863C863A1F8F2 +:1081A000400038310870434813783839006801F1CD +:1081B0001C022BB190F8493C0B7690F84C0C04E073 +:1081C00090F85B3C0B7690F85D0C107670472DE9CB +:1081D000F041044690F80E7290F8C66190F8C751CD +:1081E0000B2084F80E02082084F8C601052084F8CC +:1081F000C7012046A1690CF065FA84F80E722E4979 +:1082000084F8C66184F8C75100208870BDE8F08109 +:108210002B4901224A7018228A70827ECA70428BD2 +:10822000120A0A71027E4A71008B000A8871704737 +:108230002DE9FE4F804622488B46002180F82F1002 +:108240000BF110000290BBF80C000BF1080608B906 +:1082500047F6FF704FF00009CDE900904F4698F8BF +:108260005B5036E0B078A84232D8F078A8422FD3DD +:10827000E9B2144812F0AAFA824698F8594017E079 +:108280003078A04213D87078A04210D31AF80400B6 +:1082900068B1E9B2E0B23246029B00F0D4FA484439 +:1082A0001FFA80F91AF8040008B17F1CBFB2641CE1 +:1082B0000AE00000A0071000A80510000020100030 +:1082C000D01F10001E27012098F85A00A042D7D2D4 +:1082D0006D1C98F85C00A842C4D2642009FB00F130 +:1082E0000198B1FBF0F082B2B8F8440028B16423E1 +:1082F0004343B1FBF3F189B20091FB49012381F8BB +:108300002F300872000A48728F72380AC872F74814 +:10831000019920F8731FA0F80290B8F84410C180AA +:1083200007810271009941719BF81800904206D8AC +:108330009BF819100098814201D80120C4E6002062 +:10834000C2E62DE9F041EA4AB1F90260B1F90070E4 +:108350001278B1F90650B1F9043000249AB9E54A0F +:10836000126892F860CCA6EB0C0692F862CC36B29A +:10837000A7EB0C0792F861CC92F8632C65441A4481 +:108380003FB22DB213B290F8C621032A01D0042ABD +:1083900010D1B0F91AC0B4450CDBB0F91820BA42BC +:1083A00008DBAC4506DC9A4204DCFFF741FF0128FC +:1083B00000D10124204629E72DE9F05FDFF8308362 +:1083C0000546002798F8010020B1FFF77FFE002145 +:1083D00088F80110DFF820B3DFF818A3ABF13800FC +:1083E0009BF8001061B15C4604264FF0020B012996 +:1083F00041D002297ED0032972D0042971D056E0E1 +:10840000002405F5805681461FE00120D6F8E01FC4 +:10841000A040014217D004EB041005EB4018B4480B +:1084200000780028DAF8000002D090F8491C01E03A +:1084300090F85B1C89F81810AF4940463839FFF7AF +:1084400080FF012806D0641C64B296F9EC0FA042AC +:10845000DBDA2DE0A84A01218BF80010383AD8F871 +:108460001810C2F83A108BF80640BBF80810491CE7 +:10847000ABF808101CE0A17901EB011105EB4115E7 +:1084800095F8C611042901D0062910D1827E8146B3 +:10849000134605F11801A01C0CF0F7FF012806D1C6 +:1084A000954928463839FFF7C3FE012803D02670C6 +:1084B0003846BDE8F09F2089B9F80E104B46884237 +:1084C00015D384F800B02846FFF7A2FE98F8000004 +:1084D0000028DAF8000005D090F84B0C04E009E021 +:1084E0003AE05EE090F8640C18760127E0E7401C63 +:1084F0002081DDE7A17901EB011105EB411595F82C +:10850000C611042907D0062905D00829D0D128464C +:10851000FFF75DFE4EE0827E05F118011346A01CB8 +:108520000CF0B3FF012806D1734928463839FFF70C +:108530007FFE01280CD095F8C661082085F8C60199 +:108540002846FFF744FE0320207085F8C661AFE798 +:108550002846FFF75DFEC8E7A17901EB011105EBA5 +:10856000411595F8C611042904D0062902D008291E +:1085700020D09DE7827E05F118011346A01C0CF067 +:1085800084FF012894D15C4928463839FFF750FE12 +:1085900001288DD12846FFF73BFE012784F800B063 +:1085A00086E7A07900EB001005EB401090F8C601BB +:1085B00008289BD1FFF7ECFD7AE72DE9F05F4C4DE1 +:1085C0000646002768783C4610B1FFF77FFD6C70C7 +:1085D000A878AA46DFF82081DFF81891A8F11C08D6 +:1085E00070B19AF8001050460029D9F8001002D056 +:1085F00091F84E1C01E091F8651C88F81810847001 +:10860000DFF8F4B0012106F580559BF8000058B161 +:108610005C464FF0040B012840D0022863D00328A9 +:108620006CD004286BD05AE0CA460024C1461FE033 +:108630000120D5F8E01FA040014217D004EB041040 +:1086400006EB40182A4800780028DAF8000002D02B +:1086500090F84C1C01E090F85D1C89F81810264930 +:1086600040461C39FFF76DFE012806D0641C64B239 +:1086700095F9EC0FA042DBDA33E01F4A01218BF8B9 +:108680000010383AD8F81810C2F83A108BF80640A3 +:10869000BBF80810491CABF8081022E0A079D5F807 +:1086A000E02F81400A421AD000EB001006EB401583 +:1086B00095F8C601042801D0062812D198F81A208E +:1086C00005F118011346A01C0CF0DFFE012806D1AD +:1086D000094928461C39FFF7ABFD012810D084F862 +:1086E00000B03846E5E627E0D01F100038570120DB +:1086F000A8051000A00710003820100054E079E011 +:108700002089B8F80E10884213D302202070284622 +:10871000FFF77EFD9AF800000028D9F8000002D08B +:1087200090F84E0C01E090F8650C88F818000127CD +:10873000D7E7401C2081D4E7A079D5F8E02F81400D +:108740000A4201D130462CE000EB001006EB401548 +:1087500095F8C601042801D006281DD198F81A20E2 +:1087600005F118011346A01C0CF08FFE012805D15D +:1087700050492846FFF75CFD012803D020780228E5 +:1087800005D009E02846FFF743FD012704E028460D +:10879000FFF71DFD0320207095F8C6010828A0D121 +:1087A0002846FFF714FD2BE0A079D5F8E02F814093 +:1087B0000A4225D000EB001006EB401595F8C601E3 +:1087C000042801D006288CD198F81A2005F1180148 +:1087D0001346A01C0CF059FE012882D135492846C9 +:1087E000FFF726FD0128A3D12846FFF711FD02203F +:1087F00020709CE7A279D5F8E00F9140084297D10C +:10880000FFF7C6FC6DE710B52A4990F8C631002283 +:108810001C395B1E052B14D8B0F91A30B1F902408F +:10882000A3420EDBB0F91800B1F90040A04208DB0A +:10883000B1F90640A34204DCB1F90410884200DC1F +:108840000122104610BD30B51478844204D2557808 +:10885000854201D90A2011E0844204D1557885422D +:1088600001D0187809E0844204D05478844201D1C0 +:10887000987802E018789C786043C0B294788C4273 +:1088800004D2D5788D4201D90A2111E08C4204D15D +:10889000D5788D4201D0197909E08C4204D0D27884 +:1088A0008A4201D1997902E019799A795143C9B282 +:1088B000484330BD1C201000BE48BF490068B0F8D6 +:1088C000FB290A80B0F8FD294A80B0F8021ABA489C +:1088D000801E01800021C0F806104181C160016145 +:1088E00070472DE9F843B34F8046002538682B4682 +:1088F0002A46418EB0F9346061F31F4466F30F04D9 +:10890000694640460CF04AFE3968BDF90220B1F8CC +:10891000043A91F83E004343934207DAB1F8063A2D +:108920004343934202DDB1F8082A01E0B1F8022A7C +:10893000424310B2D8F800200092B1F8F433BDF9E8 +:108940000020934203DAB1F8F61361F31F44824228 +:108950000ADB311A8A4207DCBDF90210814203DBCF +:10896000C0EB2440814200DD01252846BDE8F883A4 +:108970002DE9F84F054690480024001D05F1240616 +:10898000018809B9408820B1304600F0BAF80128C2 +:1089900020D089480788B0F802900CF044FE824647 +:1089A00000231A46694630460CF0F8FDDFF80482D1 +:1089B000BDF90010D8F8000090F83E0000FB07F267 +:1089C000914205DB0FFA8AF309FB1030884203DA83 +:1089D000012429E0042427E07748801E008820B184 +:1089E0003046FFF77EFF012804D073480A30018823 +:1089F00041B901E0022417E0418819B9818809B919 +:108A0000C08888B1304600F0A7F801280CD1D8F80A +:108A10000000E96A90F8000A884204D9B5F8140207 +:108A200028B1082803D010242046BDE8F88F082478 +:108A3000FAE72DE9F047044690F8C6010E464FF0DC +:108A40000109032807D000274FF00308042816D097 +:108A5000082853D13FE02046FFF78AFF05004DD09C +:108A600094F90D0204F0EAF9A4F814523068206277 +:108A7000E08F4FF0000940F40060E0873EE094F999 +:108A80000D0204F00CFA012838D12046FFF770FFE0 +:108A90000546B4F81402102803D0082801D085B187 +:108AA0002CE065B1314604F120000CF03BFD01469D +:108AB0004048006890F8010A4043884204DA206A7E +:108AC000306084F8C68113E0102D01D0082D15D137 +:108AD000A4F8145212E094F90D0204F0E0F9012810 +:108AE0000CD12046FFF744FFB4F814020828E6D062 +:108AF000A4F8147294F90D0204F0C6F94846BDE8D2 +:108B0000F0872DE9F8432C4E8046361D0025B6F936 +:108B100000400CF088FD074600231A46694640468F +:108B20000CF03CFD2348B188BDF90020006890F8A6 +:108B30003E004143914201DAB6F90240BDF902100C +:108B400000FB04F2914204DB3A1404FB102088423B +:108B500000DA0125284609E7F8B5064600250CF09D +:108B600062FD044600231A46694630460CF016FDA5 +:108B70001049114BBDF9022009680A33188891F891 +:108B80003E104843904211DC5E88201406FB110021 +:108B900090420BDB9A88BDF900004A43824205DC13 +:108BA000DB8822B203FB1121814200DA012528462D +:108BB000F8BD0000A0071000862601202DE9F04135 +:108BC0005B4900F580534FF001060D6895F8964C0F +:108BD000A10717D50F2113E0D3F8E02F06FA01F70C +:108BE0003A420DD001EB011200EB421292F8C7217C +:108BF000520705D54F4995F8972C0A704E7001E041 +:108C0000491EE9D2610724D54B49097B002920D0B0 +:108C1000484C0021A41EA1800F2113E0D3F8E02FBF +:108C200006FA01F73A420DD001EB011200EB4212B5 +:108C300092F8C7717F0705D0B2F84420A788BA42DE +:108C400000D9A280491EE9D2B5F9B60CFCF7E2FEC4 +:108C50002070BDE8F0813649096891F8961C8907B3 +:108C600009D5344910B10020487003E00878002885 +:108C700001D0401E087070472DE9F04104462C4891 +:108C800000263546006890F8961C4A072CD52A4ADB +:108C9000127B4AB3274F90F8B42CBF1E90F8B81C33 +:108CA0007B78012B08D190F8B5CC90F8B90CA2EBE9 +:108CB0000C02081AD2B2C1B2B888904202D83878F1 +:108CC000884203D9042084F8C70101257D70AB4296 +:108CD00003D029460A200BF0C4FC18487A78017B9F +:108CE00062F3000101730FE0880706D5114841784F +:108CF000012909D1007830B906E0C80704D094F8FA +:108D0000C701042800D101262E43A2D00C49AA2075 +:108D1000087094F8C601032805D0042801D006285D +:108D200097D1082000E0022084F8C60191E70000F6 +:108D3000A0071000AE051000945A1000385701200B +:108D40003207100070B50446002084F8CA01FC48C0 +:108D5000FC4D0378286833B194F90D228A4290F8CB +:108D6000031218D021E0F84B94F8C7611B78012E4C +:108D700007D09BB394F90D228A4290F8341314D192 +:108D800009E0F24A12784AB194F90D224BB18A42B5 +:108D900090F8F31209D101F00F0107E090F8F112F9 +:108DA000F9E78A4290F8F212F5D0090984F8CA115D +:108DB00090F80D13C9060BD5E18F890508D590F8F9 +:108DC000360394F8CA1100F00F00084484F8CA0171 +:108DD000204600F0F5F9012810D01DE0FFE794F9D6 +:108DE0000D328B4202D190F83313D4E7934202D173 +:108DF00090F83313D9E790F83513D6E7D4480078C4 +:108E0000012809D9296894F8CA0191F8351301F0AD +:108E10000F01084484F8CA01286890F80C1AC906A2 +:108E20000AD5CC490978002906D094F8CA1190F8DF +:108E30002A0A084484F8CA0170BDC44A10B51478DF +:108E4000C04A90F8CA11126892F8333303F00F0346 +:108E50005CB192F8F22202F00F02D21A891A0029AC +:108E600000DC002180F8CA1110BD92F8F122F2E76F +:108E7000B74900200870B8490870B4490870B5496E +:108E80000870B6490880B649087070472DE9FE4F52 +:108E900004460020B3498DF800008DF804000870E6 +:108EA000B14904F580554FF0FF390870B5F8E00F6F +:108EB000A74E10EA19400DD02046FFF77FFE31463D +:108EC000484609784FF000475FEA010E4FF0010B6A +:108ED00034D10FE0A048002434700470A34880F817 +:108EE00000900120FFF7B7FE9C4804809C48047066 +:108EF000BDE8FE8F04F5805C00219CF9EC8F1BE03F +:108F0000DCF8E03F0BFA01F2134213D001EB01123F +:108F100004EB421292F8C631012B01D048460DE015 +:108F2000B2F8426036B1126B92FBF6F39F4201DA5F +:108F30001F460846491C49B28845E1DA8246B0F12D +:108F4000FF3F02D0894981F800A088484A464FF087 +:108F5000004690F90080BEF1010F25D804F5805736 +:108F6000002097F9ECCF1DE0D7F8E03F0BFA00F1B5 +:108F70000B4215D0404513D000EB001304EB431116 +:108F800091F8C631012B01D04A460DE0B1F84230CC +:108F900033B1096B91FBF3F39E4201DA1E460246A0 +:108FA000401C40B28445DFDA694900200292087013 +:108FB0000746DFF890814FF00809EBE0D5F8E01F95 +:108FC0000BFA07F001427AD007EB071004EB4016CA +:108FD00096F8C601012806D0052810D0092824D00B +:108FE0000D2831D014E0304600F0C6F95146304625 +:108FF000029AFFF7A7FE022086F8C60133E030464A +:1090000000F0F7F8062086F8C601304600F067F950 +:1090100096F8C601022826D0062852D0072859D033 +:109020000A280DD00E281AD05CE0D8F8000090F87D +:10903000370300F00F0086F8CA010A2086F8C6013F +:1090400096F8CA01D0B34DE0D8F8000090F83A0382 +:1090500000F00F0086F8CB010E2086F8C60196F8C6 +:10906000CB0168B33EE096F83E00C00710D0304612 +:1090700000F0A6F860B9D8F8001096F8CA0191F887 +:10908000351301F00F01884206D9401A86F8CA014B +:1090900096F8CA0118B125E0002086F8CA0103201D +:1090A00086F8C601D8F8000090F80D03C00619D55F +:1090B000F08F800516D5306AF06013E00DE03EE0D9 +:1090C0000DE096F8CB0168B996F83E00800701D50F +:1090D000072005E086F8C69104E00B2000E003209D +:1090E00086F8C6013046FFF7C7FD96F8C60102288C +:1090F0000CD0062811D00A2808D00E280DD003283D +:1091000012D0042810D007283ED041E096F8CA01BA +:10911000A8B1401E86F8CA013AE096F8CB0170B1BA +:10912000401E86F8CB0133E009480178491C0170E4 +:1091300096F8C70101281BD003281FD028E027E09C +:1091400029051000A0071000B30610003107100019 +:1091500032071000E007100064071000B00510008F +:10916000AC0510003307100034071000B2051000E2 +:109170009DF80400401C8DF8040009E09DF80000F3 +:10918000401C8DF8000003E096F8C7010128EFD0DD +:109190007F1C7FB295F9EC0FB842BFF60FAF0020ED +:1091A000FFF759FD01AA6946204600F066F8884895 +:1091B0009DF80010017087489DF80410017097E633 +:1091C00090F85A1090F859208A1AC18F521C022A1E +:1091D0000AD990F85C2090F85B309A4204D141F0B3 +:1091E0000101C1870120704721F00101C1870020E2 +:1091F000704710B57849002280F8CB210B78774969 +:10920000096813B191F804320FE0754B1B7853B124 +:1092100091F8383301221B0980F8CB3190F8C7311F +:10922000012B05D00CE091F8383303F00F03F3E77E +:1092300090F8CB3191F8F14203EB141380F8CB3165 +:109240001AB990F83E2092070CD491F83913826A2B +:1092500001F00F039A4205D990F8CB2102EB1111CE +:1092600080F8CB1190F8CB11002905D1C18F0905E9 +:1092700002D5012180F8CB1110BDF0B50B7859490A +:1092800001254BB100230B701178002908D0002173 +:1092900000F5805402261DE01078002800D00D70E3 +:1092A000F0BDD4F8E03F05FA01F73B4210D001EBE6 +:1092B000011300EB431393F8C671032F08D193F801 +:1092C000C771012F04D183F8C66113785B1E137038 +:1092D000491C49B294F9EC3F8B42E2DAF0BD2DE92A +:1092E000FC41DFF8F8800746D8F8000090F80D033D +:1092F000C0073FD0002507F1A006012406EBC400FB +:1093000030F8041CADF8021030F8081DADF800105C +:109310008089ADF8060036F83400ADF8040001A9E4 +:1093200068460CF0FFF8854200DA0546641CE4B29A +:10933000052CE3D3394607F120000CF0F3F8024680 +:10934000274800780028D8F8000005D0B0F8271387 +:10935000B0F82303494304E0B0F82513B0F8210323 +:1093600049434043824205DD8D4203DDF88F40F0E2 +:109370000200F887BDE8FC8170B51849096891F8CA +:109380000D33DB0622D5046AB1F8F45323B2AB42A5 +:109390004D8E01DDA5F5967565F31F42B1F9345088 +:1093A00091F88C63241465F30F02B4420ADBC4EB1A +:1093B0002242B24206DB91F88D138B4202DBEA1A9D +:1093C0008A4203DAC18F41F40071C18770BD000089 +:1093D000330710003407100029051000A007100003 +:1093E000B3061000310710002DE9F843164600239C +:1093F00089461A46FE490C68B4F8927347B9B4F826 +:10940000941329B9B4F8961311B9B4F89813B9B1F3 +:10941000B0F90E50B0F90C10AF4210DC678EB4F802 +:1094200094C3A7EB0C07AF4209DBB4F896538D4207 +:1094300005DCA58EB4F89873ED1B8D4200DA01228D +:10944000EC49097801B10123EB494D78EB490978E2 +:10945000BDB194F86503050900F00F03012904D993 +:1094600094F8660300F00F03050922B194F8640331 +:1094700000F00F030509B4F86713B4F869234943F2 +:109480007EE08BB194F86B03050900F00F0301290E +:1094900004D994F86C0300F00F030509B4F86D13B8 +:1094A000B4F86F2349436BE0D54B1B78022B22D0D5 +:1094B00090F8C731022B30D0012B34D0DFF844C3F1 +:1094C00094F8655694F8648605F00F039CF80070D4 +:1094D0002D0937B194F86B5694F86A8605F00F039E +:1094E0002D09B0F8420040452ED9B4F86616B4F8FC +:1094F0006826494344E094F87103050900F00F031E +:10950000012904D994F8720300F00F030509B4F897 +:109510007313B4F87523494332E094F8790300F0EB +:109520000F03050927E094F87A0300F00F030509FB +:1095300022B194F8620300F00F030509B4F8811317 +:10954000B4F8832349431BE094F87703050900F03E +:109550000F03012904D994F8780300F00F030509DB +:1095600022B194F8630300F00F0305091FB19CF8C2 +:1095700004309CF80550B4F87D13B4F87F234943B8 +:109580005243484600950BF0DBFF3560BDE8F88399 +:109590002DE9F84F0D4690F8C611044600F18806F3 +:1095A00003290FD0924ADFF860A2042910680FD077 +:1095B00007296BD0082967D129463046BDE8F84F06 +:1095C00000F01DBE29463046BDE8F84F00F0D1BD81 +:1095D00090F87B0304F10C0107099046081D0BF07D +:1095E000A1FF0146D8F80000DFF818B290F88523F3 +:1095F00092072ED594F8C9210AB1C4F89810D4F86E +:1096000098C090F88823B1EB0C0902D502F00F0244 +:1096100000E012099BF8008090F86436B8F1000F62 +:1096200001D090F86A36B4F84280984508D990F88D +:109630006C06B9F1000F02D500F00F0200E002093C +:10964000C2F110000CFB02FC01FB00C00111C4F8C8 +:1096500098106A462046FFF7C7FE9BF800200AB123 +:109660009BF8067054F8901F3A460BF07EFF0746B1 +:1096700002462946304600F092FD27609AF84820BD +:1096800067F303028AF84820BDE8F88F90F80D13BD +:10969000002789070DD55D4990F87C03097800F013 +:1096A0000F0701B107093A462946304600F08FFD01 +:1096B00007E0B5F90200C4F88C00B5F90000C4F861 +:1096C00088009AF8480067F303008AF84800DBE74F +:1096D0004E49484A002009781278114300D00120F1 +:1096E00070472DE9FF4F89B09146DDE9160A00EB7E +:1096F000CA00D0E90045CDE90445D0E90240CDE9F2 +:109700000640CDE9021203EBCA00DDF80880D0E97B +:109710000210CDE9001006A904A800F0B1FC07462C +:109720008B46694602A800F0ABFC0E46054669462A +:1097300004A800F0A5FC0446401BB1412DDA2846E0 +:109740000BF0A0FB804620460BF09CFB0446BAF1D0 +:10975000000F00D16410791B7BEB060005DA384658 +:109760000BF090FBA04200DA0446B8F1000F0CD0D9 +:1097700001990398009A401A6043029990FBF8F00F +:10978000891A614391FBF8F101E000200146019A3A +:1097900002EB0009009800EB01080998C0E9008974 +:1097A0000DB0BDE8F08F2DE9FF4F00278BB090463C +:1097B0003E463D463946199C0AE0012878D053F8C8 +:1097C000312017444A4302FB0155491C1644C9B2D3 +:1097D000A142F2D30E4C206800906068CDE90107E9 +:1097E000E06803902069CDE90406A069069011E0C5 +:1097F000A007100029051000D8071000320710003C +:10980000180510007407100038570120B306100027 +:10981000B4051000E069CDE9070568460BF036FD98 +:1098200082462068CDE90007A0680290E068CDE993 +:10983000030660690590A069CDE90605206A0890D5 +:109840008B4668460BF022FD00970A9060680190F5 +:10985000A068CDE90206206904906069CDE905059C +:10986000E0690790206A0890894668460BF00EFD73 +:10987000AAFB08370D460BFB087104460C9F0A989B +:109880000022A0FB07C80AFB021609FB078100FBA8 +:10989000021013EB0C014641081946EB05014FF489 +:1098A0007562002310F0D7FD0C9929B11DE0FFE788 +:1098B00003EBC102526884E7FC49096891F831134F +:1098C000890612D50A98031849EB090113EB0A031C +:1098D00041EB0B01AA00A000181842EA9472514112 +:1098E0004FF47552002310F0B6FD1899C1E900AB92 +:1098F00018990A9BC1E902391899C1E904450FB0CA +:109900004FE72DE9F04F85B00546DFF8A0833030F2 +:109910000290D8F800000F46934690F8311305F1F5 +:10992000600601F01F04E24905F1680905F1800AAB +:10993000097811B190F8320307E005F0C5FE01285F +:1099400005D1D8F8000090F8A20300F01F04BBF185 +:10995000000F06D195F89810012220460BF005FE65 +:10996000C4B2BC4201D9781EC4B285F89840CDE992 +:10997000009704FB04FB2B465A4621460120FFF7C3 +:1099800012FF7060CDE900A72B465A462146002001 +:10999000FFF709FF3060D8F8001091F89A13C90753 +:1099A00011D00146029872688DE891002B4603A8F9 +:1099B000FFF797FEDDE9030105EBC402516071601A +:1099C00045F83400306005B0EBE62DE9F04104467F +:1099D00000F1A00590F8400017460E46000703D599 +:1099E00094F8B801012805D0A021284610F0F8FD10 +:1099F00006208DE0182105F1680010F0F1FD182116 +:109A000005F1800010F0ECFD94F8BA0101281FD197 +:109A100094F8C401012802D003280DD018E094F86E +:109A2000C50110B9E089A4F8C201B4F8C20160848C +:109A3000B4F8C00120840BE094F8C50110B9A089E6 +:109A4000A4F8C001B4F8C0012084B4F8C201608455 +:109A500094F8C50101283BD0B4F9C2117068052201 +:109A6000401A90FBF2F0E962B4F9C21100EB400336 +:109A700001446962B4F9C21101EB4001E961B4F932 +:109A8000C21119446961B4F9C21101EB8000E860A8 +:109A900070686860B4F9C0113068A962401A90FB20 +:109AA000F2F0B4F9C01100EB400201442962B4F9AC +:109AB000C01101EB4001A961B4F9C0111144296141 +:109AC000B4F9C01101EB8000A8603068286021E083 +:109AD000002005EBC001B4F9C2214A60B4F9C021ED +:109AE00045F83020B4F9C2214A63401CB4F9C021C2 +:109AF000C0B20A630628ECD30CE005EBC001726823 +:109B00004A60326845F8302072684A6332680A63F6 +:109B1000401EF2D20020C5E91A00C5E91C00C5E9C3 +:109B20001E00C5E92000C5E92200C5E92400D6E9E8 +:109B30000001C5E9180139462846BDE8F041012277 +:109B4000DFE670B50BE001EBC30474E90256C4E92B +:109B5000025600EBC30474E90256C4E902565B1EC8 +:109B6000F1D1D2E90034C1E90034D2E90012C0E9F0 +:109B7000001270BD70B515460446D1E90002C4E973 +:109B800018020A462B46214604F13000FFF7D9FFA0 +:109B900029462046BDE870400022B2E600B585B0F7 +:109BA0000321049100224FF47561CDE90212009265 +:109BB00000F5907300F5847200F1A00100F580704B +:109BC0000BF0A6FB05B000BD2DE9F041374F044670 +:109BD000164638680D464FF0010890F80C03000750 +:109BE00002D5204600F006FA386890F80D034006CA +:109BF00003D52946204600F04EFA3868B0F93210F5 +:109C0000B5F902000BF058FC68803868B0F93410E0 +:109C1000B5F900000BF050FC2880386890F89A03E2 +:109C2000800703D5286800F07AFA286094F8C60106 +:109C3000032806D0042808D0072817D0082815D0F4 +:109C400017E03188A4F84F1013E03868B4F84F20BB +:109C500090F87B0300F00F00C0F110014243308800 +:109C600000FB01200009A4F84F0001E0B4F84F0008 +:109C70003080104A294604F1240000F0B2F9404631 +:109C8000BDE8F0812DE9FC5F88460B498346002042 +:109C9000086008490646DFF814A0086007494FF03D +:109CA00001090BF580570870B1E00000A007100013 +:109CB000B30610006C07100068071000640710005E +:109CC000D7F8E01F09FA06F001427CD006EB061136 +:109CD0000BEB411494F8C60103280BD0042809D0DB +:109CE000072807D0082805D0092803D00A2801D062 +:109CF0000B2868D1E0680090B4F84D00ADF804007E +:109D000004F10C01F84A081D00F06BF901AA69463C +:109D10002046FFF759FF0546DAF8000090F80C03DB +:109D2000400604D56946204601F0C0FC0546DAF835 +:109D3000000090F80C03800603D569462046FFF723 +:109D400027FCDAF80000524690F8D60300060AD540 +:109D50004DB194F8C601032805D1608CADF802001E +:109D6000208CADF8000094F8C701012807D1DF4826 +:109D7000007820B994F8C601082800D00025DC48F6 +:109D8000007870B194F84000C00701D0002508E0C9 +:109D900094F8B801012804D1206A0090002084F8CA +:109DA000B80194F8C70103280AD1D2490878401CA9 +:109DB000C0B2087094F84030DB0701D0401E087034 +:109DC0000098606200E021E0BDF80400A4F84F00B4 +:109DD000106890F8FA09C00707D0012D16D169461E +:109DE0002046FEF726FE88B101E0012D0ED1009835 +:109DF000A061BDF80400A4F8510094F80D22D8F831 +:109E0000001009FA02F00143C8F80010761C97F917 +:109E1000EC0FB042BFF654AFDAF8000090F8700CC7 +:109E200000070ED5B3480178B34829B1B349097882 +:109E3000012901D180F80090D7F8E41F002900D152 +:109E40000170BDE8FC9F2DE9F047884606460027D3 +:109E50004FF0010900F5805553E0D5F8E00F09FAFD +:109E600007F108424CD007EB071006EB401494F8BA +:109E7000C60103280BD0042809D0072807D00828DA +:109E800005D0092803D00A2801D00B2838D194F92D +:109E90000D12D8F8003009FA01F2134230D003282D +:109EA00007D1084602F0FBFF18B92146304602F000 +:109EB000C8FE94F8C70104280AD194F8C6010728FF +:109EC00003D0082801D00B2802D1032084F8C70151 +:109ED00094F90E02002813DB94F8C7110020012921 +:109EE00004D0022904D0042904D004E0032002E0B5 +:109EF000042000E0052084F8C80120460AF0A4FBF5 +:109F00007F1C95F9EC0FB842A7DA00273EE009FA6A +:109F100007F2104239D007EB071006EB401494F813 +:109F2000C601082802D00B2815D02EE094F80D2287 +:109F3000D8F8000009FA02F1084207D094F90E029D +:109F4000002803DB2146304602F095FE21463046CC +:109F500002F059FE15E094F80D22D8F8000009FA35 +:109F600002F1084211D094F90E0200280DDBB4F87A +:109F70004000214620F00800A4F84000304602F0DE +:109F80007AFE94F90D0202F07FFF7F1C95F9EC0F29 +:109F9000B842D5F8E00FBADA06F5005628B116F83F +:109FA0009A0F401C3070BDE8F087002086F89A00B8 +:109FB000F9E74D4910B5002008605149086000F0EC +:109FC00097FBBDE8104000F0D3B838B500210091F0 +:109FD00004466946FFF756FE69462046FFF733FF01 +:109FE00038BD10B514460BF09DFA2168814200DAA5 +:109FF000206010BD70B5034690F8C6010D460328D9 +:10A000000DD002280BD0042809D0062807D00A2832 +:10A0100005D00B2803D00C2801D00E282FD193F89F +:10A02000B50103F5A074E0B193F85A0093F8591004 +:10A03000401A401CC3F8A80193F85C0093F85B1029 +:10A04000401A401CC3F8AC01586BC3F8A4012D485A +:10A0500029460088C3F8B0012046BDE8704000F0F2 +:10A060009DBB1846FFF734FB002808D0012083F879 +:10A07000B50129462046BDE8704000F04FBB70BDD9 +:10A080004A68436809680068D21A081A404302FB0C +:10A090000200C11770477CB50C46B1F9021001915E +:10A0A000B4F90010009190F8C62100F1A005032A30 +:10A0B0000ED0042A11D0062A0FD00A2A0DD00C2A5D +:10A0C0000BD00E2A09D0072A1ED0082A1CD01FE068 +:10A0D00006226946FFF779FC1AE0062269462846FF +:10A0E000FFF748FD14E0000068071000310710007A +:10A0F0003907100064071000E9061000E806100098 +:10A100006C071000B406100006226946FFF746FDF2 +:10A11000B5F864006080B5F8600020807CBD30B583 +:10A1200012490514096891F89D23B1F93240B1F93B +:10A130003430954201DC62F31F4091F89E23A21A4D +:10A140000414A24201DC62F31F4091F89F2304B281 +:10A15000944201DC62F30F0091F8A01302B2591A85 +:10A16000914201DC61F30F0030BD0000A007100038 +:10A170007047324A30B4126892F88533DC074FF0EA +:10A18000000304D092F8864324098460037392F894 +:10A190008523920700D5036130BC00F035B87CB54B +:10A1A000044615460E46684600F02EF801992A46E8 +:10A1B000606800F03BF8606000992A46206800F073 +:10A1C00035F820602146304600F027F87CBD7CB58C +:10A1D000044615460E46684600F016F801992A46D0 +:10A1E000606800F023F8606000992A46206800F05B +:10A1F0001DF820602146304600F00FF87CBD0A466D +:10A200000146104600F009B8B1F90220120242607E +:10A21000B1F900100902016070474A6880321212D9 +:10A22000428009688031091201807047C2F1100331 +:10A23000504301FB0300001170470000A00710000D +:10A240002DE9F041FE4A126851B3518E92F8303038 +:10A25000C26E446E006F0026400000FB024048437F +:10A26000A0FB0025002101FB005500FB01556421E6 +:10A27000A2FB010705FB017102FB06115C432246AC +:10A28000334610F04BF82246002310F047F8ED4B10 +:10A2900000221B1A8A4101D2EA480021BDE8F08160 +:10A2A000918E92F83130826ED3E72DE9F0478EB06F +:10A2B00000250224059506950795089509950A95A8 +:10A2C0000B950DF114080C95CDE90148064606F1F1 +:10A2D0001C03039404949A4622462146DA480094CB +:10A2E0000AF000FE0DF12409CDE90149D64B022206 +:10A2F000039404941033114605A800940AF0F2FD6B +:10A30000D149306E0223403100901A46A1F110006D +:10A310000AF0DCFDCC490427022340311A460846E6 +:10A3200000970AF0C6FDC84902235246403109A8E9 +:10A3300000940AF009FE059506950795089509957C +:10A340000A950B950C95CDE9014806F12C030222E4 +:10A35000039404941D461146BB4800940AF0C2FDC4 +:10A36000CDE90149B84B02220394049410331146FD +:10A3700005A800940AF0B6FDB349306E02234031BF +:10A3800000901A46A1F110000AF0A0FDAE49022388 +:10A3900040311A46084600970AF08BFDAA4902236D +:10A3A0002A46403109A800940AF0CEFD0EB0BDE85F +:10A3B000F0872DE9F04F0546A4480F468BB0D0E951 +:10A3C0000010CDE9081000260124059606960DF12F +:10A3D000140A0796CDE9014A4FF002099A489346BC +:10A3E00005F10C03039498464A4621461038CDF8EF +:10A3F000009004940AF076FDB5F902000599012356 +:10A40000401A05900090022206A938460AF05EFD27 +:10A410006427414601230222084600970AF056FDB0 +:10A420004246022306A9104600940AF08DFD4246DA +:10A43000022308A9104600940AF086FD4146012334 +:10A440000222084600970AF034FD05960696079604 +:10A45000CDE9014A7C4805F1140303941E4602220B +:10A4600001211038CDF8009004940AF03BFDB5F9B5 +:10A47000000005990123401A05900090022206A9C8 +:10A4800058460AF023FD3146012302220846009770 +:10A490000AF01CFD3246022306A9104600940AF079 +:10A4A00053FD3246022308A9104600940AF04CFDE1 +:10A4B000314601230222084600970AF0FAFC0BB04D +:10A4C000BDE8F08F2DE9F74F8AB00026089609966F +:10A4D0000596069601240DF1140807960225CDE98C +:10A4E0000148CDE903540746574B07F11C00083BD0 +:10A4F0002A462946824600950AF0F4FC0DF120090F +:10A50000CDE901595048CDE90345534602220121C6 +:10A51000103800950AF0E6FC0DF11C0ACDE9014A5D +:10A52000494B0394083B0222012108A8009504949A +:10A530000AF0D8FC01213846FFF782FE42494FF06D +:10A54000640B14390123086007990222084405A905 +:10A550000790CDF800B008460AF0B8FC07980090C4 +:10A560000123022205A80B990AF0A3FC089609967C +:10A57000059606960796CDE90148CDE90354324B7E +:10A58000022207F12C00083B1146064600950AF00E +:10A59000A9FCCDE901592C48CDE9034533460222F7 +:10A5A0000121103800950AF09DFCCDE9014A264BA7 +:10A5B0000394083B0222012108A8009504940AF0A4 +:10A5C00091FC00213846FFF73BFE1F490123143957 +:10A5D000022208600799CDF800B0084405A9079049 +:10A5E00008460AF073FC079800900123022205A890 +:10A5F0000C990AF05EFC0DB062E72DE9F74F8EB0C2 +:10A6000000250595069507950224089509950A9554 +:10A610000B9505AF0C95CDE901478C464FF0010A2B +:10A62000094B06460394103B524621466046CDF83E +:10A6300000A004940AF056FC05AA0223114607E084 +:10A64000A007100040420F00EC051000A8A7010071 +:10A65000BE4800940AF086FC0DF12408CDE90148BB +:10A6600006F11C030222039404949B46114605A89C +:10A6700000940AF037FC4FF0640902231A46594649 +:10A6800009A8CDF800900AF014FC059506950795E9 +:10A69000089509950A950B950C95CDE90147AB4BAB +:10A6A0000394303B01220221CDF800A004941098BD +:10A6B0000AF018FC05AA02231146A44800940AF0E7 +:10A6C00051FCCDE901480394049406F12C03009455 +:10A6D00002221C46114605A80AF004FC02231A4671 +:10A6E000214609A8CDF800900AF0E3FB11B0E7E697 +:10A6F000974808B5006864210223B0F84D031A4654 +:10A7000048439249800820310090A1F110000AF0DE +:10A71000DDFB8E4964203439086008BDF8B5044675 +:10A72000086844F8040B086844F8040B086844F807 +:10A73000040BB1F902000025E4E80205B1F90000BC +:10A74000E4E802058148824E10300FC80FC40FC4E0 +:10A75000306864210223B0F84D031A46484380084C +:10A76000A4F12001009008463C3C0AF0AFFB3068A1 +:10A7700064210223B0F84D031A464843800804F1CF +:10A780002C01009008460AF0A1FB94E8070004F1B0 +:10A790003C0383E8070084F87450F8BD7FB50D468C +:10A7A000044603220AF090FE204600F025F82046D9 +:10A7B00000F06AF82046FFF778FD00200090019035 +:10A7C0000290039002AA69462046FFF77BFE02AA88 +:10A7D00069462046FFF7EDFD02AA69462046FFF7CD +:10A7E0000CFFA0896880A08A28800322294604F1F2 +:10A7F0003C000AF069FE7FBD7CB50446B0F902104A +:10A80000B0F93E00B4F94220091A801A081A0190E2 +:10A81000B4F90010B4F93C00B4F94020091A801AC8 +:10A82000081A009004F148000322694605460AF020 +:10A8300060FE94F87400032802D2401C84F874006F +:10A84000C3B200221146184606E005EBC006766842 +:10A85000324455F830603144401EF6D292FBF3F09A +:10A8600091FBF3F16A68101A2A684043511A01FB00 +:10A87000010042F21071884200DD0846642148431D +:10A8800090FBF3F020667CBD2DE9F0430446B0F95F +:10A890000200B4F90610B4F90420411AB4F900001A +:10A8A0004943801A00FB00182769A66907FB07F0D7 +:10A8B00006FB060087B04FF00009404515D90AF0A5 +:10A8C000E1FA05000DD040460AF0DCFA784390FB2F +:10A8D000F5F0206140460AF0D5FA704390FBF5F0A0 +:10A8E00002E04846C4F81090A061CDF8149001250C +:10A8F0000DF11408CDF818900226CDE90158CDE9E4 +:10A90000036512484F4604F10C03324631462038A5 +:10A9100000960AF0E7FADDE90501C4E903010597AD +:10A920000697CDE90158CDE903650848022204F1F4 +:10A9300014031146203800960AF0D4FADDE9050127 +:10A94000C4E9050107B0BDE8F08300000C06100063 +:10A95000A0071000B0F84220B1F842301A44A0F825 +:10A960004220B0F84420B1F844301A44A0F8442002 +:10A97000026B0B6B1A440263426B4B6B1A444263CB +:10A98000B1F95320B0F953309A4201DDA0F85320B9 +:10A99000B1F95520B0F955309A4201DDA0F85520A3 +:10A9A00090F8CE2191F8CE319A420AD030F8462F55 +:10A9B000B1F846301A4420F80E29896B0268114418 +:10A9C000016070472DE9F14F8AB0002004900A9889 +:10A9D00000F500500890B5E0002105910691009126 +:10A9E000884689460E460F460D468A468B4601919B +:10A9F0000291039104990A98EC4600EB810000F55E +:10AA000000500990C1690C4616E091F8CE011CF87F +:10AA10000020521CD2B20CF800200A9B034403F51C +:10AA200000531B7B9A4205D1012A03D9012282409F +:10AA300042EA0B0BD1F81C120029E6D135E094F85C +:10AA4000CE110120884010EA0B0F0ED1606BB4F9D3 +:10AA50000E3041464A46C0FB03128846B4F90C103A +:10AA60009146C0FB0167054412E010EA0A0F0FD1BE +:10AA7000A16BB4F91EC042464B46C1FB0C23904665 +:10AA8000B4F91C209946C1FB02670D4440EA0A0A4A +:10AA9000204600F043FA012802D10598401C059099 +:10AAA0000698401C0690D4F81C42002CC7D106988A +:10AAB000002843DDE817044603462A464046494637 +:10AAC0000FF0C9FCADF81E002A4623463046394631 +:10AAD0000FF0C1FCADF81C0009984FF0FF360025BF +:10AAE000C46923E0204600F019FA012801D0059836 +:10AAF00090B904F1100107A80AF014FDB0420BD27E +:10AB000006463DB129462046FFF724FF29460A980C +:10AB100000F01BFA254607E021462846FFF71AFFFA +:10AB200021460A9800F011FAD4F81C42002CD9D121 +:10AB30000798E860E88F40F04000E8870498401CE0 +:10AB40000490089890F89410049881423FF744AF1D +:10AB50000BB0BDE8F08F2DE9F74F0D4601EB051165 +:10AB600082B0814600EB41170024DFF8B8B400F54D +:10AB7000805A78E00122DAF8E01F02FA04F811EABC +:10AB8000080F6FD0AC426DD0DBF8080030F815002C +:10AB900010EA080F66D104EB041109EB41163046A8 +:10ABA00000F0B6F9012804D0304600F0B7F90128CA +:10ABB00058D1304600F0A6F9F0BB06F10C0107F1C0 +:10ABC0000C000AF0AFFC0090DBF808000123AB405A +:10ABD00030F8151041EA080120F8151030F814106B +:10ABE000194320F814103846DBF8008000F0A2F971 +:10ABF000012804D1304600F08BF901281AD03846DC +:10AC000000F086F9012804D1304600F093F90128BC +:10AC100010D0384600F07CF9012817D1304600F0FA +:10AC200077F9012812D197F83E0096F83E100843B4 +:10AC300080060BD5F88F00E014E040F02000DBF830 +:10AC40000480F887F08F40F02000F087009840459E +:10AC500008D2324642F21C06394609EB0600049B34 +:10AC600000F0B4F9641C9AF9EC0FA04282DA05B046 +:10AC70006FE72DE9F84F8846074601EB081007EB10 +:10AC80004014DFF8A0B394F83E004FF0010A4006EC +:10AC900007F580552CD504F10C000026009021E02A +:10ACA000D5F8E01F0AFA06F001421AD0464518D03E +:10ACB00006EB061007EB4010814600F029F9012849 +:10ACC0000FD1484600F01EF958B909F1100100985B +:10ACD0000AF028FCDBF80410884202D2042084F831 +:10ACE000C601761C95F9EC0FB042D9DABDE8F88FB1 +:10ACF000CD49A06A096891F829138842F6D900263F +:10AD00002CE0D5F8E01F0AFA06F0014225D04645AE +:10AD100023D006EB061007EB4010814600F0F8F850 +:10AD200001281AD194F8CE1199F8CF01814214D19B +:10AD3000484600F0E7F880B909F1100104F10C0071 +:10AD40000AF0F0FBDBF80410884206D2042084F8F5 +:10AD5000C601E08F40F04000E087761C95F9EC0FCB +:10AD6000B042CEDA002604F10C0922E0D5F8E01F4B +:10AD70000AFA06F001421BD0464519D006EB061030 +:10AD800007EB4014204600F0C9F8012810D12046F6 +:10AD900000F0B8F860B904F1100148460AF0C2FBAF +:10ADA000DBF80410884203D2E08F40F04000E087D7 +:10ADB000761C95F9EC0FB042D8DA97E72DE9F84305 +:10ADC0000646FF208DF8000000254FF0010806F52B +:10ADD000805417E005EB051006EB4017D4F8E01F90 +:10ADE00008FA05F001420CD0384600F08BF8012833 +:10ADF00007D097F8C601052803D129463046FFF74A +:10AE000038FF6D1C94F9EC0FA842E3DA00254746A1 +:10AE100019E005EB051006EB4018D4F8E00F07FA2F +:10AE200005F108420ED0404600F06CF8012809D028 +:10AE3000404600F073F8012804D16A46294630469E +:10AE4000FFF789FE6D1C94F9EC0FA842E1DA0025AA +:10AE5000B8461DE005EB051006EB4017D4F8E01FDF +:10AE600008FA05F0014212D0384600F04BF80128EC +:10AE70000DD0384600F04CF8012804D16A46294626 +:10AE80003046FFF768FEF88F20F02000F8876D1C31 +:10AE900094F9EC0FA842DDDA9DF8000006F50056A3 +:10AEA000401C86F89400BDE8F88310B5044604F011 +:10AEB0000BFC012821D05B480321083007F0EEFA93 +:10AEC00058481E2180680FF069FB42F21C007C216B +:10AED00020440FF085FB5349091D081F00F044F87A +:10AEE0002046FFF76BFF2046FFF76CFD4D4803211E +:10AEF000BDE81040083007F0E9BA10BD494900200C +:10AF00008860704790F84000C00700D0012070476B +:10AF100090F8C601012800D00020704790F8C601C3 +:10AF2000022805D0032803D0042801D00020704750 +:10AF30000120704710B590F83E10490603D5FFF781 +:10AF4000EDFF012800D0002010BD91F8C621012A94 +:10AF500008D0022A06D0062081F8C601002081F818 +:10AF6000CB01704701F04FBE2DE9F0412E4F064650 +:10AF70000D463868B0F82A4390F83003644350B166 +:10AF800001F091FE0146386890F83023914202D8D2 +:10AF9000B0F82E4364433A682449B2F82C03497848 +:10AFA000404329B1B2F88E43B2F890036443404362 +:10AFB0001F49097829B1B2F82B42B2F82D02644337 +:10AFC0004043204434602860BDE8F081F0B591F939 +:10AFD0000C6293F9004092F90C52771C02D06D1C60 +:10AFE00015D00BE06E1C0BD000EB850200EB84004B +:10AFF000D26BC2F81C12C16381F80C421C70F0BD08 +:10B00000641C64B240F8241081F80C4202E000EBAA +:10B010008601C96B00EB8400C1F81C22C26382F870 +:10B020000C42EBE73C061000A0071000D807100008 +:10B03000290510002DE9F041044690F88400F94EEE +:10B0400000270D467F2851D104F10C01081D0AF09C +:10B0500069FA0146204600F0AEFB40B284F8840055 +:10B060000F2802DD0F2084F8840094F84000800748 +:10B070003CD56888B4F96C30B4F96A20C01A01B2C2 +:10B080002888D4F86AC0C4F85EC0D6F800E0801AF8 +:10B090004FF0640C9EF8DBE300290EFB01FE9EFBE3 +:10B0A000FCF100B201DD194400E0591AA4F8641063 +:10B0B0003168002891F8DB1301FB00F191FBFCF0F3 +:10B0C00001DD104400E0101AA4F862006888B4F8AA +:10B0D0006410401AA4F868002888B4F86210401A76 +:10B0E000A4F86600306890F8DB03E8B394F98400B4 +:10B0F000B5F90220C0F110015143B4F96C2000FBF6 +:10B10000021040F30F10688094F84010890710D5A2 +:10B11000B4F96010884203DDB4F96420904205DC84 +:10B12000884206DAB4F96410884202DAB4F864009E +:10B13000688094F98400B5F90020C0F110015143F2 +:10B14000B4F96A2000FB021040F30F10288094F835 +:10B150004010890724D5B4F95E10884203DDB4F9A4 +:10B160006220904207DC00E02EE088420ADAB4F95F +:10B170006210884206DAB4F86200288094F8400031 +:10B1800080070DD5B5F90000B4F96210884207D1E7 +:10B19000B5F90200B4F96410884201D184F88470D2 +:10B1A000316894F8840091F8DD1301F00F01401A22 +:10B1B00040B284F88400002801DA84F8847028689A +:10B1C000C4F86A00BDE8F08184F88470012084F836 +:10B1D0008200F7E72DE9F0470446012790F8840044 +:10B1E0008846B94668B194F88200012809D0032244 +:10B1F00004F16E000AF068F994F88300012805D084 +:10B200005AE0484684F88290BDE8F0878648854E2B +:10B2100040780028306806D090F8E01390F8E103F9 +:10B2200061F31F450DE090F8DE1390F8DF0361F342 +:10B230001F4560F30F057D48017821B1C07860F3A8 +:10B240001F4560F30F052A14524328B200FB002566 +:10B2500004F16A03414618460AF064F90022A84244 +:10B2600001DD104600E0484698B1316894F840305E +:10B2700091F8D90300EB800040001B0704D591F83A +:10B28000D80300EB8000400020B1A16A81420DD8B4 +:10B2900000E058B1306890F80C03000600D4002795 +:10B2A000D4F86A00C8F800003846ADE784F8832077 +:10B2B00094F984000028F7DD41462046FFF7BAFEE6 +:10B2C000F2E72DE9F84F0446012000905648DFF8D8 +:10B2D00054B10D464178DBF800004FF0000A91B1FF +:10B2E00090F8EA7390F8EB630322294604F16E00AC +:10B2F0000AF0EAF894F8400000071DD594F8BA0166 +:10B30000012805D018E090F8E87390F8E963EBE7BE +:10B31000DBF80000A16A90F8F00381420CD2688843 +:10B32000B4F86C10401AB4F87E100844A4F87E00FB +:10B330002888B4F86A100BE06888B4F87410401AD2 +:10B34000B4F87E100844A4F87E002888B4F872107F +:10B35000401AB4F880100844A4F88000B4F97E00C4 +:10B36000002801DB014600E04142B9427DDD4FF09B +:10B37000010A002801DDC11B00E0C1190FFA81F9A3 +:10B38000A0EB0900A4F87E0034F86C1F01EB090063 +:10B3900000B22080DBF80010B1F932100AF08CF80E +:10B3A00024F86C09B5F902108646081A0FFA80FCD9 +:10B3B000BCF1000F01DB604601E0CCF10000B842B7 +:10B3C00074DDB4F97400081A00D5404201B2DBF80C +:10B3D000000090F88523920737D594F8C9210AB167 +:10B3E000134A5180124AB2F90280B1EB080290F878 +:10B3F000882302D502F00F0200E012090B4F90F8EB +:10B4000064363F780FB190F86A36B4F842709F42C4 +:10B4100011D9D4F898208A1A90F86C260AD502F02F +:10B420000F0208E0A0071000D807100074071000F2 +:10B43000480610001209C2F1100308FB02F701FBD5 +:10B440000371F34A41F30F11518090F8EE2390F805 +:10B45000EF7390F8EC3390F8ED83914210DB974254 +:10B460000ED0B94202DD43460AE020E0891AA8EB7B +:10B47000030801FB08F1BA1A91FBF2F119440BB26F +:10B48000B4F97E1001FB0CF1002907DDB9F1000FC2 +:10B4900000DC5B420EEB0301A4F86C10B0F9321033 +:10B4A000B4F96C000AF008F8A4F86C0016E0DBF8B8 +:10B4B0000010B4F97000498E884203D1B4F97420A9 +:10B4C0008A4203D050B9B4F8741039B9B4F96C1089 +:10B4D000814203D0A4F86C004FF0010AB4F9800057 +:10B4E000002801DB014600E04142B14273DD002843 +:10B4F00001DD811B00E081190FB2C01BA4F88000A0 +:10B5000034F86A0F384400B22080DBF80010B1F93B +:10B51000341009F0D1FF24F86A09B5F9001081460A +:10B52000081A0FFA80F8B8F1000F01DB404601E07D +:10B53000C8F10000B0427DDDB4F97200081A00D5F0 +:10B54000404201B2DBF8000090F88523920732D523 +:10B5500094F8C9210AB1AE4A1180DFF8B4A2BAF951 +:10B560000030CA1A90F8882302D502F00F0200E0DA +:10B570001209DFF8A0C290F864669CF800C0BCF124 +:10B58000000F01D090F86A66B4F842C0B44509D9FA +:10B59000D4F898208A1A90F86C2602D502F00F028F +:10B5A00000E01209C2F11006534301FB063141F3DA +:10B5B0000F11AAF8001090F8EE2390F8EF6390F8BE +:10B5C000EC3390F8EDC3914210DB96420ED0B142BD +:10B5D00002DD63460AE01DE0891AACEB030C01FBB7 +:10B5E0000CF1B21A91FBF2F119440BB2B4F98010CC +:10B5F00001FB08F1002906DD002F00DC5B4209EBAE +:10B600000301A4F86A10B0F93410B4F96A0009F023 +:10B6100053FF14E0DBF80010B4F96E008A8E9042FC +:10B6200003D1B4F97230934203D058B9B4F8722000 +:10B6300042B900E00FE0B4F96A20824202D0A4F8D7 +:10B640006A0008E0BAF1000F05D191F80C0300067A +:10B6500001D400200090D4F86A0028600098BDE86A +:10B66000F88F10B5044690F8C60104281DD194F84F +:10B670004000400719D404F10C01081D09F052FFE5 +:10B6800002466548006890F8DA13B4F84000494370 +:10B6900043070AD48A4202DA40F0020003E020F0B5 +:10B6A000020040F00400A4F8400010BD2DE9F04174 +:10B6B0000E4604460125FFF7D4FF94F8C60103287F +:10B6C00004D0042807D0082825D027E0314620469A +:10B6D00000F029F822E0504F386890F8D603800730 +:10B6E00009D531462046FFF775FD054694F88200DE +:10B6F000012803D00CE0012084F88200386890F81B +:10B70000D603C00704D031462046FFF7DAFD0546D0 +:10B71000012D03D005E0D4F87A0030603068C4F819 +:10B720007A0028464EE570B504460868C4F86A00F9 +:10B730000D46032204F16E0009F0D2FE364800687F +:10B7400090F8D6138A074FF000012CD5334A1678AB +:10B7500001227F230EB394F8406036071DD594F87C +:10B76000C561012E12D084F8821084F8832084F8F9 +:10B7700084306A88B4F86C30D21AA4F868202A8819 +:10B78000B4F86A30D21AA4F866200CE084F882205B +:10B7900084F8831084F8841005E084F8821084F81B +:10B7A000832084F8843090F8D603C00702D024F8B0 +:10B7B0007E1F618070BD1A4810B543781648026834 +:10B7C00083B192F8E70392F8E43300F00F04000924 +:10B7D00092F8E5235B435243994202DD91420CDB30 +:10B7E000204610BD92F8E60392F8E23300F00F0411 +:10B7F00000095B4392F8E323EDE79A4200D1521C23 +:10B80000C91A041B6143D21A91FBF2F1401A10BD10 +:10B810004806100074071000A00710003907100038 +:10B82000D807100030B50124039D9C4035B10914A0 +:10B8300091420EDA81682143816030BD09B29142A4 +:10B8400003DA01682143016030BD41682143416052 +:10B8500030BDC1682143C16030BDFF49B0F900006F +:10B86000B1F92020824203DCB1F92210814201DAD1 +:10B8700001207047002070472DE9F84391460646A5 +:10B88000DDE9087288790025DDF828C00C46032818 +:10B890002FD2F248DFF8C883016891F87A0CA080B3 +:10B8A000D8F80880B8F1000F04DD91F87B8CA0EB8C +:10B8B0000800A080B1F87C1C306B884217DDDBB239 +:10B8C00049463846CDF800C0FFF7ACFFA079401CD0 +:10B8D000C0B2A071032806D0E249B6F95500B1F90B +:10B8E0000010884205DD0320A071012501E0002041 +:10B8F000A0712846BDE8F8832DE9F0410446DA48F6 +:10B900000078002859D0D548006890F8700CC0061F +:10B9100053D594F90E0200284FDA94F840008006BF +:10B920004BD4A08F0023C00400D5012304F10C00E8 +:10B93000FFF793FF0546B4F840004FF001064106BB +:10B940004FF002074FF0030C1DD51D430CD084F8B7 +:10B95000C67140F00100A4F8400094F8CA01032821 +:10B9600021D284F8CAC11EE020F0410040F0280036 +:10B97000A4F84000002204F5E071204601F03DF8F3 +:10B9800084F8BA610FE004F12000FFF766FF012898 +:10B9900001D1012D13D0B4F8400020F0400040F058 +:10B9A0002000A4F8400094F84000400605D5AF48B8 +:10B9B00010F87D1F41F004010170BDE8F081002BFB +:10B9C000F1D0B4F8400040F04100A4F8400084F801 +:10B9D000C67194F8CA01032801D284F8CAC10E21A5 +:10B9E00004F5DC700EF0FCFDE068C4F8C00184F8DA +:10B9F000C461D8E702B29948006890F8F61C8A4200 +:10BA000003DB808E401A904201DA0120704700204B +:10BA1000704730B591490246002009684C8EB1F854 +:10BA2000023DE51A131412B29D4205DAB1F8045D25 +:10BA3000AA4201DA012030BDB1F8065DAB4205DA59 +:10BA4000B1F8085DAA4201DA022030BDB1F80A5D02 +:10BA5000641B9C4207DA8C8EB1F80C5D641B944227 +:10BA600001DA042030BDB1F80E4DA342FADA8B8E14 +:10BA7000B1F8101D591A9142F4DA082030BD774907 +:10BA8000B0F90E200968B1F8EE3C9A4214DBB1F827 +:10BA9000F03C9A4210DCB0F90C20B1F8F23C9A422A +:10BAA0000ADBB1F8F43C9A4206DC806A91F8F71C94 +:10BAB000884201D800F0B4BF70472DE9F047674EC7 +:10BAC0000024326892F8ED3C9D0790F8163219D5A3 +:10BAD0003BB990F81752A5B392F831707F1EBD4262 +:10BAE00030D092F830506D1EAB4202D190F81772F0 +:10BAF0003FB3AB4206D192F8315090F817726D1EE9 +:10BB0000AF421FD092F8B15CB0F953804FF0640C93 +:10BB100008FB05F898FBFCF52DB24D4395FBFCF1B5 +:10BB20000DB25349B24692F8B06C92F8AF7CD1F89E +:10BB300000C0B34208D290F81712B94204D20021D3 +:10BB40000FE0FFE701243CE0B34212D292F831103B +:10BB500090F817828946C91B88450ADBA9F10100C4 +:10BB6000C1B260460EF038FEB0F90000A842E9DC30 +:10BB700027E092F83010D046891B8B420ADB90F800 +:10BB80001762BE4206D2002160460EF025FED8F8AC +:10BB900000100FE056468B4213DB90F8171292F814 +:10BBA0003100C21B91420CDB401EC1B260460EF058 +:10BBB00013FE316891F8301000EB410030F9020CAF +:10BBC000D4E72046BDE8F0872DE9F05F4FF0FF0A8B +:10BBD0004FF000090646D0464F4690F85B502DE0E6 +:10BBE0002348E9B200680EF0F7FD834696F8594005 +:10BBF0001FE01A483BF914100068B0F8F90C8142B4 +:10BC000016DD2146504609F02DF900F0FF0A2146C5 +:10BC1000484609F02BF900F0FF092946404609F093 +:10BC200021F900F0FF082946384609F01FF9C7B28C +:10BC3000641C96F85A00A042DBD26D1C96F85C009A +:10BC4000A842CDD2A9EB0A01A7EB0800CA01431C08 +:10BC5000803292FBF3F20DE044201000A0071000A8 +:10BC60004C061000D006100039071000385701208C +:10BC700050071000C0018030491C90FBF1F081B2E8 +:10BC8000FE4892B20068B0F8FD3C934203D3B0F88E +:10BC9000FF0C884202D20120BDE8F09F0020FBE7A4 +:10BCA0002DE9F047F64ADFF8D483F64C1578D8F83A +:10BCB0000070F54A90F81662B7F9FBAC00211278D3 +:10BCC00023684FF00109B6EB550F10D290F817C258 +:10BCD000BCEB520F0BD218460EF07EFD0188408857 +:10BCE0000D18012120680EF077FD00883FE0B6EBCB +:10BCF000550F19D290F817C2BCEB520F14D397F816 +:10BD000031004546401EC1B218460EF065FD01885F +:10BD100040880E18286890F83100801EC1B2206853 +:10BD20000EF05AFD00884BE0B6EB550F21D390F88A +:10BD300017C2BCEB520F1CD2002118460EF04CFD6E +:10BD4000D8F80010464691F8301000EB410030F86A +:10BD5000021C30F8040C0D18012120680EF03CFD87 +:10BD6000316891F8301000EB410030F8020C2844A3 +:10BD700027E0B6EB550F25D390F81702B0EB520F22 +:10BD800020D397F831004546401EC1B218460EF048 +:10BD900023FD296811F8302F00EB420030F8022C07 +:10BDA00030F8040C16184878801EC1B220680EF0D6 +:10BDB00013FD296891F8301000EB410030F8020CB7 +:10BDC000304401B2514501DA4FF000094846F9E626 +:10BDD00070B504460025C068FFF70CFE88B9A74877 +:10BDE0000068B0F8EA1CB0F8E80C091AB4F8BC0115 +:10BDF000814205DB28B1D4F8C00100F015FE00B97E +:10BE00000125284670BD10B5FFF703FE002809D0B4 +:10BE10009E494A8882434A808A8882438A80CA88A7 +:10BE20008243CA8010BD2DE9F34F984885B00E4675 +:10BE300000784FF0000920B19449401E087000F0CE +:10BE4000EFFD05984FF0000800F580504FF0010A13 +:10BE50000490ECE104980AFA08FBD0F8E01F11EA1C +:10BE60000B0F75D0059808EB081100EB411505F58F +:10BE7000DC742846FFF740FDB5F84010480667D44B +:10BE8000EF68039795F8C601012806D0022804D070 +:10BE9000C9077DD004287CD0A8E17D4AB5F95310AC +:10BEA000B2F90020914253DB012803D10E21204634 +:10BEB0000EF074FB002000907648007828B96F4897 +:10BEC000006890F8700C80064ED5E868FFF7A1FD79 +:10BED00038B1012000906948006890F8A50C85F8F9 +:10BEE00019020098A8B364212846FFF7E6FD01284F +:10BEF00030D02846FFF768FE01282ED00620207398 +:10BF0000B5F840005D4F40F00100A5F84000E8683A +:10BF1000A06084F80DA039684346284691F89D1C1E +:10BF20000096CDE9011A2146039AFFF7A5FC814648 +:10BF30003868B0F8EA0CA080E868FFF76AFD18B12D +:10BF400052498A8802438A8095F8C411072906D08D +:10BF50006AE109E0052185F81A120720CFE74B496D +:10BF6000CA880243CA805FE14B4A38B2B2F9101066 +:10BF700088420CDBB2F91210884208DCB2F91A30A0 +:10BF80003914994203DCB2F91830994233DA01E0EE +:10BF90000FE13AE0B5F8401041F00101A5F840107A +:10BFA000217B09B9E968A16084F80CA0B2F91010EE +:10BFB0005746884203DBB2F9123098420CDD00206C +:10BFC0000096CDE90110434621462846039AFFF723 +:10BFD00053FC8146277327E1B2F918004346CDE9A7 +:10BFE0000060029721462846039AFFF745FC8146E8 +:10BFF0000320207318E100202073306940EA0B0011 +:10C0000030612846FFF73BFD0EE1207B07282AD14F +:10C010001A48006890F8B21C2846FFF74EFD012828 +:10C020000BD02846FFF73CFE012806D095F81A02EF +:10C0300050B1401E85F81A0215E01048006890F8CB +:10C04000121D85F81A120EE006202073A068FFF773 +:10C05000E0FC18B10D49CA888243CA80A088012833 +:10C0600001D8A4F804A0207B062825D1A0880128A7 +:10C0700032D92846FFF7A8FD01280FE0A0071000DD +:10C080002507100050071000240710004C06100070 +:10C09000E4061000740710004420100009D10720A6 +:10C0A0002073A068FFF7B5FC18B1F949CA880243AC +:10C0B000CA80207B06280FD0C0B207280CD0F54AD2 +:10C0C00039B2B2F91030994203DBB2F91230994219 +:10C0D0005FDD03285AD089E0E868FFF79AFC30B1A9 +:10C0E000ED48006890F8A51C85F8191205E095F850 +:10C0F000190278B1401E85F81902E748CDF800A072 +:10C1000008F0FF0300680399B0F99E2C3046FFF752 +:10C1100089FB6BE0DF4A39B2B2F91000814203DBE0 +:10C12000B2F9123099420DDD00210096CDE90101EE +:10C13000434621462846039AFFF79EFB814684F832 +:10C140000CA01FE0B2F91A103814884203DCB2F9CF +:10C15000181088420FDAB2F918104346CDE9006191 +:10C16000CDF808A021462846039AFFF785FB8146B3 +:10C170000320207306E0316941EA0B013161C749B0 +:10C1800081F800A0A068FFF73EFE2FE084F80CA025 +:10C190000CE0B2F91A303914994203DCB2F91820D4 +:10C1A000914223DA012821D103202073E868A0609E +:10C1B0001CE0B84938B2B1F91020904216DDB1F94F +:10C1C0001220904212DAB1F91A20381490420DDA96 +:10C1D000B1F91810884209DD3169284641EA0B019E +:10C1E0003161AE4981F800A0FFF749FC95F8C6011E +:10C1F000052819D1A848B5F90E100068B0F8EE2C42 +:10C20000914211DBB0F8F02C91420DDCB5F90C1025 +:10C21000B0F8F22C914207DBB0F8F42C914203DC29 +:10C2200090F8F81C9A480170049808F1010890F9F8 +:10C23000EC1F4145BFF60EAE30687268B168F36816 +:10C2400040EA020441EA03052C43346901D02CB1D1 +:10C2500007E034B18E4C0225657002E08C4D85F804 +:10C2600001A08C4C58342568A84330606068824334 +:10C270007260A0688143B160E06889498343F360DC +:10C2800030690978084305D12C22A4F12C0181489A +:10C290000EF04AF907B04846BDE8F08F30B590F887 +:10C2A000C611002204292DD17B490B6893F8701C1C +:10C2B000490727D5B0F84810B0F84A40091B754C1B +:10C2C000248DA1421EDD4FF4E271095C012901D0E9 +:10C2D00002290AD190F85A4090F85950641B93F8FB +:10C2E000795CAC4201DD01220CE0032901D0042974 +:10C2F00008D190F85C1090F85B00081A93F8791C4C +:10C300008842F0DC104630BD30B5634900220B682E +:10C3100093F8701C49072BD590F8C611042927D132 +:10C32000B0F84810B0F84A40091B5A4C248DA1427D +:10C330001EDD4FF4E271095C012901D002290AD106 +:10C3400090F85A4090F85950641B93F8795CAC42CD +:10C3500001DD01220CE0032901D0042908D190F865 +:10C360005C1090F85B00081A93F8791C8842F0DCA6 +:10C37000104630BD2DE9F34F8BB0454800270A9792 +:10C3800040780E46012806D1306920B14148416904 +:10C390000391C06903E03F480169039180694FF050 +:10C3A000000882460B9800F580500990F9E1099841 +:10C3B0004FF0010909FA08FBD0F8E01F11EA0B0F52 +:10C3C00018D00B9808EB081100EB4115B5F84000A8 +:10C3D00041060FD4C0070ED0E868029095F8C60158 +:10C3E00005F5DC7401280AD0022808D004282FD0D3 +:10C3F000052875D0D2E1294981F80090CEE1F06896 +:10C400000090306901901422314604A80EF047F8DC +:10C410000DF1100B28469BE80E00FFF73FFF0128A7 +:10C4200001D184F80190F0680090306901901422E5 +:10C43000314604A80EF033F80DF11009284699E8AA +:10C440000E00FFF761FF0128D4D10020A080A5E1F4 +:10C45000207B012801D0032804D10E4841690391B3 +:10C46000D0F81CA0F0680090306901901422314689 +:10C4700004A80EF014F80DF1100C28469CE80E00EC +:10C48000FFF742FF01280DD0A08801280CD01CE046 +:10C490004C06100044201000A0071000EA0610000F +:10C4A00064071000002014E0207B06280FD12846E6 +:10C4B000FFF78EFC30B1316941EA0B013161FA4975 +:10C4C00081F80090A068FFF79EFCA08810B1A088BA +:10C4D000401EA080F548008818B10020A08002E02E +:10C4E0000CE1A08820B995F8D01109FA01F00743B2 +:10C4F000F0680090306901901422314604A80DF0D4 +:10C50000CEFF0DF1100C28469CE80E00FFF7C6FE8A +:10C51000012801D184F80190A079032819D2A188BB +:10C52000B9B1E3492A6B0968B1F87C1C8A420EDD77 +:10C53000401CC0B2A071032806D0DE49B5F95500F1 +:10C54000B1F90010884204DD01200A9001E00020CA +:10C55000A071207B06281BD0072819D0039ABDF9AB +:10C56000081012B2019291420DDB039A121491420B +:10C5700009DCBDF90A104FEA2A42914203DC0FFAA6 +:10C580008AF291427EDA022840D0042841D044E069 +:10C59000306910EA0B0F30D0C5486422016891F869 +:10C5A000010DB1F8EA1C4043494391FBF2F101FB54 +:10C5B00000F904F108018B4602A808F0B3FF4845D2 +:10C5C00007D2012202A9284600F017FA0298286231 +:10C5D00004E000225946284600F00FFA95F8D001F1 +:10C5E000012101FA00F0874335F8400F20F00500E3 +:10C5F00040F008002880A170D0E001200090AC48F5 +:10C6000008F0FF030068B0F99E2C38E084F80C9025 +:10C6100001E003202073E868A060607830BBA64981 +:10C6200004F1080B05F10C00496A009195F8C4115A +:10C6300001292BD0594608F075FF009988420CDD7E +:10C6400001225946284600F0D8F9B5F8400020F0FC +:10C65000050040F00801A5F8401095F840000007DB +:10C6600004D595F8D01109FA01F08743207B012801 +:10C6700013D008F0FF030FFA8AF2CDF8009030468D +:10C68000029900E011E0FFF7CDF887E0BBF9021056 +:10C69000B0F90200081A4043CFE700200090DDE91E +:10C6A000012108F0FF033046EBE73069002240EA41 +:10C6B0000B00306104F10801284600F09EF9B5F83E +:10C6C000400020F0050040F00800A5F84000784840 +:10C6D00084F80290B5F84210006890F8862C9142D8 +:10C6E00006D995F8CA1190F8870C084485F8CA0154 +:10C6F00095F8D01109FA01F087434FE0207B01281B +:10C7000004D003280BD0062814D017E0A088E8B383 +:10C710006748B5F955100068B0F88D0C07E0A0889F +:10C72000A0B36348B5F955100068B0F8880C814291 +:10C7300019DC33E02846FFF74BFBA0B9207B072824 +:10C7400022D1E868FFF756F9F0B95948006890F827 +:10C75000ED0CC00718D0B5F8BC01A8B1D5F8C001E0 +:10C7600000F062F980B9012204F10801284600F0C6 +:10C7700044F935F8400F20F0010040F08000288097 +:10C78000B5F81500A5F81300207B00E006E00628A8 +:10C7900001D0072802D1A068FFF735FB099808F1FE +:10C7A000010890F9EC1F4145BFF601AE43490FB1B6 +:10C7B000012000E0002008700A980DB06CE53C49AB +:10C7C0003D4A09682C32898E1084081A50847047BB +:10C7D000374A394B12682C3340B171B1518E081A67 +:10C7E000588392F8821C401AD883704711B1508E3A +:10C7F0005883F9E70020188303E0188392F8821C1D +:10C800000844988370472A4910B40B682A4A998EC5 +:10C810002C3260B11082091A518293F8824C204464 +:10C820009082081BD08293F8850C10BCC7E70020CB +:10C83000108251829082D1821084518410BC704742 +:10C8400070B51B4C206890F8830CFFF7DCFF206864 +:10C85000012190F88C0CFFF7BBFF2068002190F8B5 +:10C860008C0CFFF7B5FF2168134A91F8800C2C322D +:10C870004043506291F8810C10850F492C222C31D5 +:10C880000D480DF051FE0D4800240D4D0470064872 +:10C89000142104700848AC6058300DF0A1FE09481E +:10C8A00004706C7070BD0000EA0610001C071000D8 +:10C8B000A0071000D006100044201000E806100069 +:10C8C0004C061000E906100070B586B0064614212B +:10C8D00068460DF085FE5A480024694604703046CB +:10C8E000FFF7A1FA054669463046FFF743FD2843A6 +:10C8F0005449012801D0886805E05348006890F841 +:10C900007A0C401F8860002804DD401E88604F4874 +:10C91000007800B98C60142269464D480DF004FE81 +:10C9200006B0BFE72DE9F04700F136060546B078BE +:10C93000DFF820810A460024C0B14749F37808781F +:10C94000401E834257D18946C1B210460DF03EFFCA +:10C95000074699F80000401EC1B2D8F800000DF05B +:10C960003BFF03463078717802460FE00021104605 +:10C970000DF02CFF07460021EFE7BE5C95F841C0A3 +:10C98000664501D1641CE4B2521CD2B29142F4D289 +:10C990002D4A60B11668B6F8726C401EC0B233F909 +:10C9A0001070B74203DD641CE4B20028F5D12B48B7 +:10C9B0000078401E81420DDA166881420ADA491C6D +:10C9C000C9B2B6F872CC33F91170674502DD641C48 +:10C9D000E4B2F2E7224880F87E40116891F8841CA6 +:10C9E000A14208D2A98C41F48051A98410F87D1F7E +:10C9F00041F008010170BDE8F087022380F8C631DC +:10CA0000002380F8CA3101238362012A04D0096817 +:10CA1000016280F8B831704703220C3008F060BD25 +:10CA2000084881884180704710B50024FEF7F1FF67 +:10CA300020B104494988014200D00124204610BD9C +:10CA4000EA0610004C061000A0071000E8061000CF +:10CA50009C2010005007100024071000250710002C +:10CA600038570120FBF79AB810B542F2A001FB48F5 +:10CA70000DF0B6FD4FF4C461F9480DF0B1FDF94871 +:10CA8000FF2180F8EC1FF8490020088000F0FEFF2D +:10CA9000FEF734FAFFF7D4FE00F010FAFCF7E8F9DD +:10CAA000FDF787FABDE81040FBF77AB810B5EC4CFB +:10CAB000EE4994F8180688712146E84801F026F8F6 +:10CAC000EB48007810B1E548FFF7FEFEE948006842 +:10CAD00090F80C03C00702D0E048FEF7E6F9DF4803 +:10CAE00000F07BFBDD4800F009FDDC48FCF7CEF9E7 +:10CAF000DA48FDF76AFAD948FBF74CF9002084F8C8 +:10CB0000180610BD10B5D94800248471D34800F030 +:10CB1000C3FFD248FCF7BAF9D048FBF7BAF8D248BD +:10CB20000480CF4880F8184610BD10B5CC4C94F85E +:10CB3000180690B1CD4988712146C84800F0E6FF3B +:10CB4000C64800F04AFBC548FCF7A0F9C348FBF70C +:10CB5000A0F8002084F8180610BDBDE81040D1E709 +:10CB600010B5C24800248471BC4800F095FFC0484D +:10CB7000007828B1B948FFF7A7FEB84800F02DFBB0 +:10CB8000B648FCF783F9B548FDF71FFAB348FBF741 +:10CB900001F9B34880F8184610BD10B5B04C0146F5 +:10CBA00094F818060F280FD200EB800202EBC000A9 +:10CBB00004EBC00068220DF0B7FC94F81806401C86 +:10CBC00084F81806012010BD002010BD10B500F536 +:10CBD00080500021D0F8E02F1346D40706D0520829 +:10CBE000491C0F29F9DB4FF0FF3010BD01228A40AC +:10CBF0001343C0F8E03F90F9EC2F8A4201DA80F845 +:10CC0000EC1F48B210BD10B500F5805091F80D42F0 +:10CC10000123D0F8E02FA3409A43C0F8E02F002270 +:10CC200081F8C62190F9EC2F91F90D128A4207D1B3 +:10CC3000D0F8E01FB1FA81F1C1F11F0180F8EC1FBB +:10CC400010BD30B500F580500022D0F8E43F1C46FE +:10CC5000DD0708D0521C5B0852B20A2AF8DBFF201D +:10CC600081F80E0230BD012393401C43C0F8E44F0D +:10CC700081F80E2230BD10B500F5805091F80E42BB +:10CC80000123D0F8E42FA3409A43C0F8E42FFF20FB +:10CC900081F80E0210BD72487047704870477048A6 +:10CCA00090F8180670476E48A03890F89A007047C0 +:10CCB0006B4810B50421C0380CF0F0F9C0B210BDBB +:10CCC00070B56C480026664C01683546A4F1A00496 +:10CCD00091F86602C0062CD567480078012828D054 +:10CCE000664AB1F86D0212780AB1B1F8620264497D +:10CCF000097811B36349096888421ED25848042153 +:10CD0000C0380CF0CBF9014694F89900544AB8B1F8 +:10CD100092F8181694F8983099420ED9401C10F0E9 +:10CD2000FF0084F8990084F8981082F8185612D100 +:10CD300012E084F89950002070BD84F899500BE0FF +:10CD400092F81806884207D9012184F8991084F8CE +:10CD5000980082F818560126304670BD2DE9F04142 +:10CD60003F4F4FF0004597F81866002E3AD000204C +:10CD70000AE000EB800101EBC00107EBC101C969CA +:10CD8000A94200DD0D46401CB042F2DB002087F8CE +:10CD900018060446DFF8DC8022E004EB840000EB98 +:10CDA000C40007EBC0016422C869504390FBF5F052 +:10CDB000D8F8002000B2B2F8252282420FDA97F8A4 +:10CDC000180600EB800202EBC00007EBC0006822EF +:10CDD0000DF0AAFB97F81806401C87F81806641C8B +:10CDE000B442DADBBDE8F0812DE9F0411B4D0024AF +:10CDF00005F580560127D6F8E00F07FA04F108423E +:10CE000010D004EB041005EB401191F90E0200283C +:10CE100008DBD6F8E43F07FA00F2134202D02846B6 +:10CE2000FFF729FF641C64B20F2CE4DB042105F535 +:10CE3000FF500CF033F90C490880D3E70121814001 +:10CE4000002809DB0748D0F8E02F0A4204D0D0F8C8 +:10CE5000E82F0A43C0F8E82F70470000B020100008 +:10CE600050411000B0301000580610003857012013 +:10CE700039071000A007100018051000B3061000B5 +:10CE800032071000C80610000028E5DB01218140B0 +:10CE90000948D0F8E82F8A43C0F8E82FDCE70028DB +:10CEA00008DB054901228240D1F8E81F114201D078 +:10CEB0000120D1E70020CFE7B030100070470021FB +:10CEC000A0F8DC11C0F8D811A0F8DE11202100F57F +:10CED000F3700DF063BB02B90122521E12F0FF0283 +:10CEE00006D000EB420333F8023C20F81230F4E79E +:10CEF0000180704702B90122002303E020F81310DB +:10CF00005B1CDBB29342F9D3704770B590F8C62131 +:10CF10000CB200F5F375032A05D090F83C10C90651 +:10CF200007D5FFF7CCFF102221462846FFF7E2FF86 +:10CF300004E0102221462846FFF7CDFF2846BDE831 +:10CF40007040102109F04BB82DE9FC5F0546F94807 +:10CF50004FF000086E6B077895F8C601DFF8D8A38C +:10CF60004446C146C346CDF800800F282BD2DFE8E7 +:10CF700000F0E50808082BE5E5E5E52B2BF4F4E5E2 +:10CF8000F400002085F8E4012846FFF798FF95F8A3 +:10CF90003C004FEAC0704FB10028DAF8000002D020 +:10CFA000B0F8D84A0BE0B0F8D64A08E00028DAF822 +:10CFB000000002D0B0F8D04A01E0B0F8CE4AA64254 +:10CFC00071DA01208046B9E005F10C01081D08F076 +:10CFD000A9FA814695F8E40160B9DAF8000017B1C2 +:10CFE000B0F8CB0A01E0B0F8C90A864202DD0120A0 +:10CFF00085F8E401DAF80000D04B90F8CD2A1B78D0 +:10D000009A4213D395F8E42182B190F8EA0A01908C +:10D01000D04631462846FFF778FF8346D5F8080208 +:10D02000A9EB0001002905DCFE2204E02846FFF7F9 +:10D0300046FF7CE0C822494608F01CF98146019869 +:10D040004043484509DAD8F80000B0F8E81A5945D5 +:10D0500003DD2846FFF733FF63E02FB9D8F800005F +:10D0600090F8C81A89074DD5D8F80000002F95F818 +:10D070003C7090F8EB1A90F8EA2A90F8ED3A90F8A4 +:10D08000EC4A4FEAC7770FD037B1B0F8E48AB0F86E +:10D09000D87AB0F8DCCA15E0B0F8E28AB0F8D67AEF +:10D0A000B0F8DACA0EE096E037B1B0F8E08AB0F82E +:10D0B000D07AB0F8D4CA05E0B0F8DE8AB0F8CE7AFB +:10D0C000B0F8D2CAB0F8EF0AA7EB0C07BFB2B04273 +:10D0D00001DD3C4625E00120CDE9004052434943B3 +:10D0E000484607F06CFF0BFB00F10090642091FBB9 +:10D0F000F0F084B24046444501D3044611E0BC42FE +:10D10000E7D90EE095F83C10C90704D0B0F8D01A62 +:10D11000B0F8D40A03E0B0F8CE1AB0F8D20A081A70 +:10D1200084B2A64201DA012000E000208046C5F862 +:10D13000D891A5F8DCB10098A5F8DE01804820F868 +:10D14000644FDAF80010B1F8C91A4180C680A0F81F +:10D1500004904046BDE8FC9FFFE7774895F83C10F7 +:10D1600000684FEAC17177B131B1B0F8E42AB0F884 +:10D17000D81AB0F8DC3A14E0B0F8E22AB0F8D61ABF +:10D18000B0F8DA3A0DE031B1B0F8E02AB0F8D01AD0 +:10D19000B0F8D43A05E0B0F8DE2AB0F8CE1AB0F80C +:10D1A000D23AC91AB0F8E63A90F8EE0A1A44B5F93C +:10D1B000DE3192B21844B5F9DC3189B258436423A8 +:10D1C00090FBF3F084B2944201D31446F7E68C420C +:10D1D000FCD80C46F3E60020F4E62DE9F05F0746A4 +:10D1E0004FF0000907F58055CA46484695F9EC2FDF +:10D1F00015E00121D5F8E03F81400B420DD000EB56 +:10D20000001107EB411191F8C611012905D002293F +:10D2100003D009F1010101F0FF09401C40B2824234 +:10D22000E7DA0026E7E04FF0010ED5F8E01F0EFA2E +:10D2300006F001420BD006EB061007EB401494F801 +:10D24000C601012804D0022802D0042870D0D0E002 +:10D2500094F81802012808D094F8C721032A08D0AE +:10D26000042A06D0012A04D0C3E0002084F8180262 +:10D270008BE0344894F840300021B0F900004FF0C2 +:10D28000010BDB0702D03048B0F90000B9F1000F04 +:10D2900012D12E4B1B78012B0ED127482C4BD0F8E6 +:10D2A00000C01B78BCF90502052B01D0062B01D16B +:10D2B000BCF90A024FF0000BDFF898C09CF803801D +:10D2C000B8F1000F02D19CF8043063B1012A02D0FA +:10D2D000E28FD20507D50AF1010000F0FF0A1E48CF +:10D2E000B0F900003AE0BBF1000F37D0124A1368E2 +:10D2F000B3F8C922EAB1B3F9C922B8F1000F04D1D9 +:10D300009CF804C0BCF1000F01D0B3F9CD22B4F8F1 +:10D310003CC05FEA4C5C01D5B3F9CB22B4F9533081 +:10D32000834203DBB4F91002904227DA012125E0A1 +:10D3300038E013E074071000A00710003307100056 +:10D3400038570120D0061000E40610001805100020 +:10D3500021071000945A1000D4061000E28FD20565 +:10D3600008D5934AB4F95330B2F90020934201DD55 +:10D3700084F8C7E1B4F953208242D7DB94F8C7019F +:10D38000032807D0042805D029B321463846FFF7E3 +:10D390003AFC2EE00029F8D12046FFF7D5FD012800 +:10D3A000F3D026E094F83C0010F0060F21D094F85A +:10D3B0004000C0071DD180497E480978B0F90000BF +:10D3C000012902D17D48B0F9000094F8C711032962 +:10D3D00002D0022906D00CE07848B4F95310B0F915 +:10D3E000000001E0B4F95310814202DA052084F80C +:10D3F000C601761C76B295F9EC0FB042BFF613AFBA +:10D400006F4C206890F80D03400768D56D48007890 +:10D41000F0B36D484078D8B3042107F5FF500BF006 +:10D420003DFE02285BDD00210A4608464FF0010C54 +:10D4300095F9EC8F26681CE0D5F8E03F0CFA00F473 +:10D44000234214D000EB001307EB431494F8C631C9 +:10D45000012B03D0022B01D0042B08D1B4F9533097 +:10D46000B6F88A43A34202DD491CC9B21A44401CE3 +:10D4700040B28045E0DA022931D392FBF1F096F810 +:10D4800089134143642091FBF0F006B2002400E0D0 +:10D4900025E0E0461CE0D5F8E01F08FA04F0014260 +:10D4A00014D004EB041007EB401191F8C6010128D9 +:10D4B00001D002280AD191F83E00000706D4B1F944 +:10D4C0005300B04202DA3846FFF79DFB641C64B299 +:10D4D00095F9EC0FA042DEDA3C48A0F846603C48E3 +:10D4E000C078012808D1BAF1000F05D0D5F8E00FB7 +:10D4F000002801D137490870BDE8F09F2DE9F047B9 +:10D5000007463348C078002850D1334800780128B6 +:10D510004CD000254FF0010907F5805809FA05F0B5 +:10D52000D8F8E01F01423DD005EB051007EB401491 +:10D53000002694F90D02FFF7B2FC012832D094F8CE +:10D54000C701032801D004280AD11D48006890F8BB +:10D55000C80AC00704D02046FFF7F6FC01280AD00D +:10D5600094F8C601092816D00A2814D00B2814D024 +:10D570000C2812D014E094F8C6010126032806D026 +:10D58000042804D00D2804D00E2802D008E0092079 +:10D5900004E00C2002E0042000E00D2084F8C60125 +:10D5A000C4F8D4616D1CEDB20F2DB7D3BDE8F08780 +:10D5B000D4061000D8061000E9061000D6061000A8 +:10D5C000A007100032071000D807100038570120BC +:10D5D000945A10002F071000180510002DE9F05F75 +:10D5E000DFF8CC9515460C46834601F10C084FF048 +:10D5F000FF3A002602F10C07CBB3012084F8C601E4 +:10D6000095F8400084F8C70184F80EA284F8CA6136 +:10D6100084F8CB61E687A4F84060A662E66284F8ED +:10D62000C96184F8CC6195F8420084F8CF01688E16 +:10D63000A4F85500E868206203223946204607F026 +:10D640004FFF03223946404607F04AFFD9F8000051 +:10D6500090F8980C84F8120284F8B56194F90D02E0 +:10D66000002801DBFFF710FCA4F814622CE0FFE7B0 +:10D670001146204600F010FBA06A401CA06294F8FE +:10D68000C601042804D1E06A411C01D0401CE062BC +:10D6900003223946204607F017FF03223946404649 +:10D6A00007F012FF94F8CE0184F8CF0194F8C70177 +:10D6B00004285DD195F84000042859D094F812024E +:10D6C00010B1401E84F8120295F8400084F8C7019A +:10D6D00095F8410084F8D00195F8420084F8CE0115 +:10D6E000E88CA4F84200288DA4F84400688DA4F8C2 +:10D6F0004600E88DA4F84800288EA4F84A0095F862 +:10D70000490084F84C00288BA4F84D00B5F932008C +:10D71000A4F85300A9692163E9696163296AA163D7 +:10D72000A98EA4F85710A98CA187D5F83610C4F893 +:10D7300059106969E16195F8431084F8D11195F8A1 +:10D74000441084F8D211B5F84610A4F81012B4F9B8 +:10D750005510814201DAA4F85500C4F81C6284F81F +:10D760000CA2A88C8005E08F07D540F4807006E0FD +:10D77000D9F8000090F8980CA4E720F48070E087B6 +:10D78000A88C0005E08F02D540F4806001E020F411 +:10D790008060E08715F83E0F84F81602687884F8F8 +:10D7A000170221465846BDE8F05F00F04BBA2DE95C +:10D7B000FF4F0E46FF498346FD4D49688BB0002060 +:10D7C000086028689A46B0F80E430CF0B7FF0128AD +:10D7D00004D12868B0F8100300B10446F648007878 +:10D7E00060B12868F54AB0F816131268B0F8124311 +:10D7F0004943914202DAB0F814030444F048007837 +:10D80000002802D02868B0F82842E94804FB04F850 +:10D81000006890F8189301D090F82A920BF5805088 +:10D820004FF000050990A7E00998D0F8E01F4FF0ED +:10D83000010000FA05F001427AD005EB05110BEB6F +:10D84000411494F8C601072872D02146201D07F024 +:10D8500069FE00FB09F000FB09F794F8C6010328F4 +:10D8600005D1D3490968B1F8191301FB01F8414604 +:10D87000474500DA0F46042807D0062805D00A28B5 +:10D8800003D00C2801D00E281BD1CE4800780628E2 +:10D8900017D0052815D00420049000214FF475609E +:10D8A000CDE90201009104F5907304F5847204F14E +:10D8B000A00107A807F02CFD0898ADF8060007980E +:10D8C00020E0A06A10B30128224604F1040105A853 +:10D8D00021D007F01DFE221D111D06A807F018FE1D +:10D8E000BDF91600BDF91A10BDF918200844411001 +:10D8F000BDF91400104462881144ADF80610218867 +:10D9000001EB6000ADF8040000242EE06088ADF863 +:10D9100006002088F6E707F0FBFD6088BDF81610CA +:10D920000844ADF806002088BDF814100844E9E763 +:10D930001FE004EB840000EBC40006EBC00101A86B +:10D940000C3107F0EFFD0146B8420CDA9948406807 +:10D95000026802EB420200EB4202516054721572FF +:10D960000168491C0160641CE4B296F81806A042E4 +:10D97000DFD86D1C09986DB290F9EC0FA842BFF684 +:10D9800053AF8C4C6068016800297CD000F0ECF942 +:10D990000025DFF834824FF006096FE005EB450102 +:10D9A00000EB41000D9A90F908100127146890F9D6 +:10D9B000090007FA01F214425FD1DAF800C007FA51 +:10D9C00000F31CEA030F58D114430D9A1460DAF8DF +:10D9D00000201A43CAF8002001EB011200EB80017D +:10D9E0000BEB421401EBC00006EBC0020023214602 +:10D9F0005846FFF7F3FD94F8C601032808D0042821 +:10DA000009D006280CD00B2834D00C2832D034E0B2 +:10DA100084F8C97102E0002084F8C90104202AE0DA +:10DA2000042084F8C60194F83C0010F0060F24D0BE +:10DA300094F84000C00720D1654964480978B0F9DE +:10DA40000000012901D1B8F9000094F8C711032999 +:10DA500002D0022908D010E0B4F95310B8F9000040 +:10DA600004E084F8C69108E0B4F953108142F8DB71 +:10DA700003E008E00C2084F8C6016D1C4D484068A6 +:10DA80000168A9428ADC0FB0BDE8F08F4948002147 +:10DA900001704160816070472DE9F041064641F612 +:10DAA000EE702E2130440CF079FD0024052706F598 +:10DAB00080551EE00121D5F8E00FA140084217D0A3 +:10DAC00004EB041006EB401191F8C601032816D0B0 +:10DAD000042814D0022815D0092810D00A280ED006 +:10DAE0000B280FD00C280DD00D280BD00E2809D0F4 +:10DAF000641C95F9EC0FA042DCDABDE8F08181F8F6 +:10DB0000C671F5E73046FFF77EF8F1E72DE9FC47EF +:10DB10000546002427480F4600940121001D01946A +:10DB200004F0BCFC23480521083004F0B7FC41F6A2 +:10DB3000EE702E2128440CF031FD1E4EFF222D21C7 +:10DB4000B0680CF023FD347005F580564FF00109E4 +:10DB5000D6F8E00F58B36B4601AA39462846FFF7BE +:10DB600026FE4FF0050821E0D6F8E01F09FA04F080 +:10DB700001421AD00199084217D104EB041005EBB9 +:10DB8000401191F8C60103282BD0042829D002287F +:10DB90002AD0092825D00A2823D00B2824D00C28E5 +:10DBA00022D00D2820D00E281ED0641C12E015E0D3 +:10DBB000A00710005C061000B306100068071000F4 +:10DBC00029051000F8041000D6061000D806100031 +:10DBD000E906100096F9EC0FA042C5DA00244E4683 +:10DBE00021E081F8C681E0E72846FFF70CF8DCE782 +:10DBF000009906FA04F0084214D12846FEF7E6FF21 +:10DC000000280FDB00EB001105EB411104EB84024F +:10DC100002EBC40281F80D0207EBC2020123284681 +:10DC2000FFF7DCFC641C97F81806A042E0D801213D +:10DC30005F4804F04BFC5E480521001D04F046FCE3 +:10DC4000BDE8FC8730B55A4D91F8CE412D1FAB6829 +:10DC50001A5DFF2A05D12A781A550F2A01D2521CC3 +:10DC60002A7091F8CE2101249A5C81F8CE2100EB34 +:10DC7000420202F5805291F80D52B2F8EE3FAC40EC +:10DC80002343A2F8EE3F91F8CE1142F20C02104469 +:10DC90000A5C521C0A5430BD2DE9F041044691F84B +:10DCA000400000260D46012801D184F8CC6194F88B +:10DCB000C701404FDFF8008101281FD195F84000CF +:10DCC00003284DD194F8C601022804D0032806D0B9 +:10DCD000042804D01EE02046FBF7AFF80EE0D8F889 +:10DCE000001094F8CC0191F8F11201F00F01884274 +:10DCF00002D83978012906D084F8CC6195F8400023 +:10DD0000032807D008E0401C84F8CC01012085F8E6 +:10DD1000400001E084F8CD6194F8C70103281FD1C9 +:10DD200095F8400001281BD194F8C601042817D1AA +:10DD30003878B0B9D8F80000B4F95510B0F8F82226 +:10DD400091420EDA94F8CD1190F8FE02814207D28A +:10DD5000032085F8400094F8CD01401C84F8CD01E3 +:10DD6000CBE684F8CD61C8E67CB500221CE002EB6E +:10DD70004203511C00EB430312E001EB410400EBB2 +:10DD800044045E686568AE4209DD00961E89ADF800 +:10DD900004605D6025891D81009D65602681491CA8 +:10DDA00004688C42E9DC521C01689142DFDC7CBDD6 +:10DDB0006006100031071000A00710002DE9F74F92 +:10DDC000002282B09346904614460092FE4A15689F +:10DDD000FE4AAB8EB2F9002093427CD18946FC49C1 +:10DDE00082463635086890F8BD0AC00704D0F94865 +:10DDF0000078504305EB4005F748077866E0F748A0 +:10DE00004FF0000E10F81710F5480078401AF0494E +:10DE1000401EC0B20E6896F80C1A49064CD596F80A +:10DE2000310A96F830EA47E035F810203AF8101039 +:10DE300039F81030511AD21A09B213B2002901DB95 +:10DE40000A4600E04A425A4506DD002901DB0A463F +:10DE500000E04A420FFA82FB5A1A01D4944601E0CC +:10DE6000C2F1000CC44507DD002A01DB944601E045 +:10DE7000C2F1000C0FFA8CF8002A00DA5242B6F810 +:10DE80000DCA624517DD002B00DA5B420A1E00DA7C +:10DE90004A42934202DD641CA4B20CE0002900DA7D +:10DEA0004942B6F80F2A914205DD00270498012166 +:10DEB0003C46017002E0401E7045B5DAC848007863 +:10DEC00005EB40050AEB400A09EB40097F1E96D29C +:10DED000BF48006800E005E090F8110AA04201D2B6 +:10DEE00001200090BA48009A006890F8121ABD48C4 +:10DEF00007F046F8BC49A1F82280A1F824B081F8C7 +:10DF0000264005B0BDE8F08F70B5B54A0025012167 +:10DF100012782C46921ED3B2AD4A126892F80C6A5F +:10DF2000760603D592F8313A92F8301A4AB204E0F4 +:10DF300030F91260521C354452B29A42F8DD5A1A36 +:10DF400095FBF2F505E030F91120521B02FB02446B +:10DF5000491C9942F7DDC4F30F3070BD2DE9FF4F26 +:10DF6000B7B000212E91359131912D9101913091D1 +:10DF700095490B6895499C8EB1F900108C427DD172 +:10DF8000CDE93220994836332F9300683490904879 +:10DF9000026892F8BD2AD20705D08E4A12784A4309 +:10DFA00003EB42012F910127D9E08C48884A0024D5 +:10DFB00010F817108A4890F80090A9EB0100401E55 +:10DFC00000F0FF081068834690F80C0A400603D55D +:10DFD0009BF8318A9BF8304A329807AB00EB490036 +:10DFE00032902F9800EB49002F90339800EB4900B6 +:10DFF0003390349800EB490034900020014623F818 +:10E000001010401C2628FADB40460AE02F9931F810 +:10E010001030339931F81010591A07AB23F810104B +:10E02000401EA042F2DA00259BF80C0AAA464006E0 +:10E030000DD5464608E03246012000210CF0E5F9F6 +:10E04000054341EA0A0A761EA642F4DA25E0A9F160 +:10E050000100804522464FF001004FF000010ED133 +:10E060000CF0D3F905460E46621C012000210CF08D +:10E07000CCF905430E43A8F1010205E001E10CF0E3 +:10E08000C4F905460E46621C012000210CF0BDF9C2 +:10E090000E430543ED436FEA060A08F10100CDF88F +:10E0A0000090C0B20295CDE905400121CDE903A160 +:10E0B00007A9DFF81C91BBF93E3ABBF93C2A084698 +:10E0C000F8F7BFFD45461AAE0DF11C080FE0349875 +:10E0D00030F8150026F8150038F91500002800DA88 +:10E0E0004042319906F0C2FE80B26D1E3190A542C9 +:10E0F000EDDAD9F80000B0F8331A319881420CD229 +:10E100003848801D30F8741F491C018031994180C6 +:10E110003449002048703BB0F4E63298FFF7F4FE33 +:10E12000304DAD1D25F817001AA8FFF7EDFE05EBE1 +:10E130004704208407A8FFF7E7FEA4F84000208CDE +:10E140002D99884202D92D90B8B2359035F8170034 +:10E150000199884202D90190B8B230907F1C1E48C4 +:10E160000078401E8742FFF620AF194C4FF6FF752E +:10E17000216891F8320A80073FD52D98C0B319481D +:10E18000359A801D00EB42031226B3F8402082B37B +:10E1900017022D9AB1F8391AB7FBF2F292B29142F6 +:10E1A00008D901212E913A990E70B0F86210491CDD +:10E1B000A0F8621030F8601F491C018093F84010ED +:10E1C00005EA0121818015E0A40710003A0710003C +:10E1D000A0071000D80710002407100034260120E3 +:10E1E00025071000982601203857012054071000F9 +:10E1F00003E00CE02D99C1800281206890F8321A6A +:10E20000C90746D00199E1B32E9971B141E0B1F847 +:10E21000402A2D998A42F0D201212E913A990E700E +:10E2200030F8621F491C0180E7E7F749309A13264E +:10E2300001EB4204228C2AB3019B0827B7FBF3F3BE +:10E240009A40B0F8353A309F92B237B1EF4FDDF8CF +:10E25000C0C03F787F1E674501D1B0F8373A9A4277 +:10E2600008D201202E903A980670B1F86C00401C3C +:10E27000A1F86C0031F86A0F401C088094F8200067 +:10E2800001E006E00FE005EA002088800198C880E0 +:10E290000A81DF482E9A006890F83B1ADA48401F3E +:10E2A00006F06EFE37E7B0F8422A01988242F0D2BB +:10E2B00001202E903A98067031F86C0F401C0880AF +:10E2C000E7E72DE9F74FD24F034682B038684FF0A9 +:10E2D0000008C14690F8226AB0F9201A0091B0F9FE +:10E2E0001E1ACC48C346C246B0F9002045464446F3 +:10E2F0001846F8F787FED8B9C748007850B1C34828 +:10E3000000990278039800F04FF90546B04201D910 +:10E310004FF0010BC148007850B1C1480099027814 +:10E32000049800F041F90446B04201D94FF0010AC7 +:10E33000B948B54E0078B61F38B138685A4690F8DB +:10E34000231A301D06F01CFE8046B448007838B110 +:10E350003868524690F8231AF01C06F011FE8146E8 +:10E36000A54200D92C46AF4880F8314048EA090060 +:10E37000C7E570B50C46A849097861B1A34D297865 +:10E380004A000146A8480CF08AF82878A6494200BD +:10E39000A6480CF084F8A148007860B1A04D214651 +:10E3A00028784200A2480CF07AF82878A049420068 +:10E3B000A0480CF074F8A0490120087070BD2DE948 +:10E3C000FF4F83B000249D48109F8DF808408DF8C2 +:10E3D0000440DFF83C8244600470D8F80000DFF8A5 +:10E3E0002892DFF85CB290F80C0A25462646C00752 +:10E3F000A9F1060910D003200AF0DFF802AADBF821 +:10E4000000100398FFF7DAFC044611208DF8040091 +:10E4100003200AF0EDF801E089F80050D8F8000078 +:10E42000DFF820A290F8320AC10701D1800717D582 +:10E43000B4B98548007898B99DF8080001280FD034 +:10E4400003200AF0BAF801ABDAF80020DBF800107C +:10E450000398FFF783FD044603200AF0C9F801E0A2 +:10E4600089F80150F4BB03200AF0A7F89DF80800D2 +:10E470000090764BDAF80020DBF800100398F7F7ED +:10E4800089F903200AF0B4F8D8F80000DFF8C0B129 +:10E4900090F80C0A800713D59DF8080001280FD0CA +:10E4A0009BF8001011B99BF8010048B16949DAF8EE +:10E4B000000000F089F8044630208DF8040001E0E7 +:10E4C00089F80250D8F8000090F80C0A40071DD5D2 +:10E4D0005148524900780978084317D0B4B95E48CA +:10E4E000007800E016E088B99BF8001011B99BF89D +:10E4F000010058B1574A5949DAF80000FFF7E1FE28 +:10E50000044632208DF80400012603E089F8045007 +:10E5100089F803505249012C06D1D8F8000090F830 +:10E520008F0C08B1088003E0088808B1401EF9E7A5 +:10E530000CF010F94B4908700CF01CF901464A48E0 +:10E5400001702CB32EB13D70DDE90401FFF711FF1E +:10E550001BE040F23C6145480CF020F80120374AAE +:10E5600038709DF804001070506840F00200506050 +:10E57000D8F8001091F80032DB0703D191F8BA10F7 +:10E58000C90702D040F008005060012007B0B9E48C +:10E590003D700078FAE729490020486008701A4960 +:10E5A000891F08608880704710B50446002008E085 +:10E5B00034F91230002B00DA5B428B4201DD401C43 +:10E5C000C0B2521EF4D210BD2DE9F05F8A46104948 +:10E5D000834600200E682649024696F81CEA097810 +:10E5E000B6F918CAB6F91A7A0346002967D10C4859 +:10E5F00000240578054890F800904FE004FB05F0F2 +:10E600000BEB4008002046E09E2601202407100066 +:10E61000A00710003A07100023071000220710007F +:10E620002507100038570120F87601206C0B0120D7 +:10E6300022770120960B0120DF07100068061000EA +:10E64000580710004C07100038071000501E10002B +:10E65000945A1000820C012031071000580C012040 +:10E660001C071000B2061000EB061000440D01203C +:10E670002905100038F91010002900DA4942B94282 +:10E6800008DD3AF91010002900DA4942614501DA43 +:10E690005B1C9BB2401CA842ECDB641C4C45ADDB10 +:10E6A000FF2B00D9FF23DCB2744500D9012296F874 +:10E6B0001D1A044806F064FC034981F83040BDE8A7 +:10E6C000F09F00009A260120385701202DE9FF4FC6 +:10E6D00089B0002083460490039002909C488A46AB +:10E6E0000068B0F8410207900B98897840680CF0F8 +:10E6F00065F800909AF8021016980CF067F80190EF +:10E700009AF802003CE09AF800402AE00998224674 +:10E7100000EBC8000021D0E9005601200BF075FE87 +:10E7200005400E4035431BD0009830F9145007982F +:10E73000854215DD0198005DCF287ED018B117996C +:10E74000884200D000250398AB4404FB05000390E9 +:10E75000029808FB050002900498401C80B20490C7 +:10E76000641C9AF80100A042D0DA7A49009809782E +:10E7700000EB4100009001982830019008F1010061 +:10E780009AF8031080464145BDDA714800240268BA +:10E7900002981746918EC317A1FB002504FB005079 +:10E7A00001FB03054FF6FF71A2FB010605FB0161AA +:10E7B00002FB041197F831203037521E8BFB0223E5 +:10E7C0000BF049FE47F6FF7280184FF6FF7841F1D3 +:10E7D0000001424600230BF03EFE0546039978886F +:10E7E000CB17A0FB012604FB016100FB031340468D +:10E7F000A2FB004603FB0060002102FB01013A7806 +:10E800002046521E8BFB02230BF025FE47F6FF72BB +:10E81000801841F10001424600230BF01CFE0B9AC8 +:10E82000C2F81CB00B9A049911850C9948600C9998 +:10E830000D600DB0BDE8F08FFFE74FF000094F46C7 +:10E840004FF0FF3608EB0600C1B2059016980BF0AA +:10E85000BDFF06900598C1B20B9840680BF0AEFF63 +:10E860004FF0FF31069A6318D25C7AB1CF2A0DD0EF +:10E87000DDF85CC0624503D130F813203A4497B20A +:10E8800030F8133003EB09021FFA82F9491C49B230 +:10E890000129E7DD761C76B2012ED3DD002F3FF48F +:10E8A00052AF6F4397FBF9F54DE710B52849426821 +:10E8B00000240968002A01DA446003E04B8E9A4282 +:10E8C00000DD43600268002A01DA046010BD898E11 +:10E8D0008A42FBDD016010BD7FB50E4608991446E3 +:10E8E000CDE90031FF2502AB3146FFF7EFFE1A48B4 +:10E8F0001749007830B1086890F8F303000701D594 +:10E90000042513E094F84000032802D0012807D022 +:10E910000CE0086890F8F303C00707D0002505E075 +:10E92000086890F8F303400700D50225294602A89D +:10E9300001F0D2FE02A8FFF7B8FF0398E081029829 +:10E94000A08194F82400C00601D4E06860617FBD16 +:10E95000A007100025071000E80610002DE9F74F6A +:10E960000F46FD4988B0DFF8ECA31EC98DE81E00F4 +:10E97000002210F0FF010492059289466B4605D1F2 +:10E9800003F82120491C49B20429F9DBF34C24780F +:10E99000641EA14507D1002103EB8104491C49B243 +:10E9A000A2700429F8DBC0F30720B0F1000806D1FB +:10E9B00003EB8001401C40B24A700428F8DBE849B0 +:10E9C0000978491E884507D1002003EB8001401CCF +:10E9D00040B2CA700428F8DB0024684600EB8400CB +:10E9E000027809EB0201427861F3070608EB0201A5 +:10E9F000827861F31746C07809EB0201C9B240443E +:10EA0000C0B261F30F2660F31F668B4646F30745DD +:10EA1000069015E0E9B278680BF0D0FE71B204AB55 +:10EA20000AE030F91120002A04DD33F814C06244F2 +:10EA300023F81420491C49B28B45F2DA6D1C6DB2E3 +:10EA40000698A842E6DA641C64B2042CC5DB0020F8 +:10EA500004AD35F91010514500DD8A46401C40B226 +:10EA60000428F6DB0A98012818D0A7F846A0B9F1C7 +:10EA7000000F0CD0B9490978491E894507D0B8F173 +:10EA8000000F04D0B6490978491E884503D1B88CD7 +:10EA900040F48060B8840BB0BDE8F08FB14800212D +:10EAA000046897F8400094F8F432012803D194F8F0 +:10EAB000F602181AC3B2002035F91020D61702EB5F +:10EAC0009672B3EBA20F01DA491CC9B2401CC0B266 +:10EAD0000428F1D3A44894F8F7220078012807D03D +:10EAE0000020101A8842D6DCB88C40F40070D1E7C0 +:10EAF00094F80303F5E72DE9F84381469B48174650 +:10EB0000884601789A4E974D089A1C4609B9407874 +:10EB1000C0B1296891F8B20183079548007801D502 +:10EB2000012807D191F8B31109070BD5012A09D1A2 +:10EB3000012807D123463A4641464846F6F72DFCC0 +:10EB4000002844D08B4B3A464146484601F0DCFA57 +:10EB500000283CD094F84000032810D12968E08CAC +:10EB600091F8C01288420AD93078012807D00420D1 +:10EB700084F840008048017941F040010171386813 +:10EB8000C4F836002868B0F8C90238B1E08FADF893 +:10EB90000000002221460098FFF7E0FE2246394699 +:10EBA000744800F0E3FC75492046FDF7BBFE39468A +:10EBB000704801F043FA4B46224639466D48CDF87D +:10EBC0000080FFF789FE2046FDF7E7FF0120BDE842 +:10EBD000F8832DE9F0410D461F461646044668218C +:10EBE0000BF0FEFC002084F840006548006860607F +:10EBF000A06006EB450084F8425030F8B41F6185F0 +:10EC00000088E08406EB85000068C4F83A005D489F +:10EC1000816921600121A940394201D0406A206008 +:10EC2000BDE8F08170B5574C00EB4305049E00EB46 +:10EC3000830386B18E69A660CE8C668009686161A7 +:10EC4000B5F8B410A1801968E16090F80E01207049 +:10EC50001068206170BDA6688E616688CE84666982 +:10EC60000E60A188A5F8B410E1681960217880F8D9 +:10EC70000E112069106070BD2DE9FF4F81B00C4668 +:10EC800098469978109F0E9D0BF0A0FD814698F84C +:10EC9000021020460BF08CFD009098F80210786866 +:10ECA0000BF08CFD064638484FF0000AC7F818A054 +:10ECB0000068286098F8020042E098F800402FE0D1 +:10ECC0000098015D0398814228D136F914100F98FD +:10ECD000814220DD039809F804002978204606F0D7 +:10ECE000C1F828706978204606F0C0F86870A978E5 +:10ECF000584606F0B7F8A870E978584606F0B6F816 +:10ED0000E8700AF101001FFA80FA36F91410B869A8 +:10ED10000844B86102E0002009F80400641CE4B271 +:10ED200098F80100A042CBD2009809F128092830B8 +:10ED300000900A48007806EB40060BF10100C0B2D3 +:10ED400098F8031083465945B7D2A7F826A005B016 +:10ED5000A2E600000080FFFFB0A701002507100019 +:10ED600024071000A007100031071000945A10006B +:10ED70001805100070471000385701201E27012089 +:10ED80004C071000700610001AA801002DE9FF4F73 +:10ED900081B090460E9E8B4606EB880096F80EA139 +:10EDA000DDF8409000681C4630600123314658462B +:10EDB00001F0C5FA019858451CD0A57817E02946FE +:10EDC00001980BF003FD0746294658460BF0FEFC60 +:10EDD0000246207806E03B5C434501D1115C395482 +:10EDE000401CC0B261788142F5D26D1CEDB2E07872 +:10EDF000A842E4D296F80E1100240123514512D006 +:10EE0000119878B10AF1010007E0D9F8002003FA5F +:10EE100000F10A43401CC9F8002096F80E11C0B258 +:10EE20008142F2D20124009343464A4630460F996C +:10EE3000FFF7F8FE20468AE710B5FE4AFE4C13683D +:10EE4000647893F8BF224CB191F82410090702D5D9 +:10EE500093F8C31201E093F8C2120A44904201D918 +:10EE6000012010BD002010BD2DE9F04389B01C46E3 +:10EE700016468846814601F02CFDD4E9180150342D +:10EE8000CDE9000194E80F00503C01F098FCA0850A +:10EE900000208DF81400ADF81800ADF81C0002AD8C +:10EEA00007AA06A905A885E80700D4E91801503487 +:10EEB000CDE9000194E80F00503C01F0BAFCBDF828 +:10EEC0001800E085BDF81C102186DC4F9DF8141059 +:10EED00084F84910A7F88000208EA7F8820094F8E3 +:10EEE0004900D44DC0F1FF0087F88400E08C3881E0 +:10EEF0002968E08C4FF0010C91F8C822904254D858 +:10EF0000CF4A032084F8400012780020012A15D04F +:10EF100091F88022930702D45207002A00DA0120D8 +:10EF2000C54BB1F8C4225B780BB1B1F8C622A38DF2 +:10EF3000934208D2C34A127822B104E091F8012228 +:10EF40009206EAE70020A7F86D30628D032A00D20E +:10EF50000020A28C92051DD4E0B191F88102000638 +:10EF60000FD502F063FA2868B0F9410200900190D1 +:10EF7000B5480378B5480278B5480168304602F0D4 +:10EF80007EFA09B02346324641464846BDE8F04382 +:10EF900002F070BD2346324641464846CDF800C0D7 +:10EFA000FFF7A9FD09B0BDE8F083042084F8400014 +:10EFB000387940F040003871ECE7A648C07858B185 +:10EFC0009C48A54A0068126890F8FD12914205D24B +:10EFD00090F8E602800701D50020704701207047B5 +:10EFE00091F82410934ACB079C491268097806D0FF +:10EFF00011B192F8EE1205E092F8EF1202E059B169 +:10F0000092F8EC128C4B5B7813B192F8F022114419 +:10F01000884204D90120704792F8ED12F2E70020EF +:10F0200070472DE9F04188B0012516460F4680460D +:10F0300083F8405003F12C0401F04BFCD4E90D019E +:10F040002434CDE9000194E80F00243C01F0B7FB23 +:10F0500024F8340B00208DF81400ADF81800ADF83A +:10F060001C000DF1080C07AA06A905A88CE80700EA +:10F0700074E80401CDE9000194E80F00243C01F09C +:10F08000D8FBBDF818006080BDF81C10A1809DF869 +:10F09000141004F81D1F694921F8800F34F8190C69 +:10F0A000488014F84909C0F1FF0008716148006800 +:10F0B00090F8E602C00608D508B023463246394625 +:10F0C0004046BDE8F04102F0D5BC23463246394601 +:10F0D00040460095FFF70FFD08B0A1E52DE9F04F80 +:10F0E000E9B000206490834668905D485D49B0F9BE +:10F0F00000006790B1F90010CDE9650101215A487F +:10F1000003F016FA58480121083003F011FA564866 +:10F110000221001D03F00CFA0221544803F0BEF94D +:10F120000421534803F0BAF94F4F4FF466741C3F63 +:10F130002146F8690BF032FA2146786A0BF02EFA74 +:10F140004C48B0F900004100386A0BF027FA4048FB +:10F150000068F6F7B9F84FF0000947488DF81E919E +:10F160004C460068049001234A4604A9B86901F09E +:10F17000E6F8629401240DF5AD702646639001E136 +:10F1800004A800EB840804AA214648A8629BFFF764 +:10F1900020FD48AB42462146489801F018F8234626 +:10F1A00062AA48A904A80096FFF73CFD0DF5AF70D0 +:10F1B00000F01EFF78B1BDF8440140F00100ADF849 +:10F1C000440148A801F08BF828B12C482549008853 +:10F1D0000880234908801B48007838B1BDF84401F5 +:10F1E00010F0060F02D1264800684990404600F012 +:10F1F00011FF28B1BDF8440140F00800ADF844010A +:10F20000BDF95211679881424CDDBDF8460148A90D +:10F21000FFF712FEC0B348A800901A482146639A2F +:10F22000B0F90030B86900F0DBF948AB424621463E +:10F2300048982AE0A0071000D8071000385701208E +:10F2400018051000E806100025071000240710001C +:10F250004C071000945A1000C4061000310710002B +:10F26000D6061000D80610008C0610009C06100070 +:10F27000A80610003A071000CC061000E6061000A1 +:10F2800050071000DA06100004E0FFF7EDFD012042 +:10F2900064906AE0234662AA48A904A8CDF80090C9 +:10F2A000FFF7C0FCF348BDF95211B0F900008142EC +:10F2B0005BDDFFF782FE88B3629806FA04F505422B +:10F2C00045D1ED48006890F88102000728D5E9484B +:10F2D000DFF8A8C3D7F824A0B0F90000BCF900C03B +:10F2E000B969224648AB844501DB484617E00DF179 +:10F2F0000C0CCDF800C0CDE9010343465046FFF7A2 +:10F30000BBFC6299304629436291BDF84611CDF8A5 +:10F3100020A121B10399C8F80010E6E725E020BB41 +:10F32000D548006890F8E602C00610D462980542FD +:10F330000DD004A901AB62AA48A8009183E845005A +:10F340002246639B796AB869FFF720FDC0B9BDF812 +:10F35000460148A9FFF744FE38B148AB4246214672 +:10F360004898FFF75EFE4FF0010B629906FA04F031 +:10F370000843C349629066980880C249659808802E +:10F38000641CE4B29DF81E01A042BFF4F9AEBE4970 +:10F390004871BE4968980870BD4964980870BD49B5 +:10F3A00081F800B000F03DFDBB48007858B1BB4883 +:10F3B0000078012807D1B048006890F80102C00623 +:10F3C00001D5FDF7CBFC0221B54803F07FF80421FD +:10F3D000B44803F07BF80121B34803F007F9B248C1 +:10F3E0000121001D03F002F9AF4801210C3003F0A8 +:10F3F000FDF8AD480221083003F0F8F869B0BDE827 +:10F40000F08F2DE9F043A848DFB000260121001D50 +:10F4100003F08EF8A4480221083003F089F8022195 +:10F420009F4803F03BF804219E4803F037F89E4CB8 +:10F430004FF46671183CE0690BF0B0F89B48B0F9E6 +:10F4400000004100206A0BF0A9F8B14698488DF8F9 +:10F450000E914D460068009001234A466946A06916 +:10F4600000F06DFF012427463CE0684600EB84086D +:10F470002B466A46214644A8FFF7ABFB44AB424605 +:10F480002146449800F0A3FE0DF5A77000F0B0FDF2 +:10F4900028B1BDF8340140F00100ADF83401404618 +:10F4A00000F0B8FD28B1BDF8340140F00800ADF817 +:10F4B00034017449BDF94201B1F9001088420CDDF4 +:10F4C000BDF8360144A9FFF7B7FC30B144AB424662 +:10F4D00021464498FFF7C8FC012607FA04F00543CB +:10F4E000641CE4B29DF80E01A042BED26649487188 +:10F4F00067486649067081F800906649684881F857 +:10F500000090022102F0E2FF0421664802F0DEFFD3 +:10F510000121654803F06AF863480121001D03F0EA +:10F5200065F861480221083003F060F85FB03AE501 +:10F5300056490020087056490870564908707047AF +:10F54000F6E759490020183908628861C8615449B2 +:10F550000860544908604D4908704D4908704D498C +:10F5600008707047A82153480BF03AB82DE9F74FBF +:10F570000D464D49183948780F2801D2401C487073 +:10F5800000F0FF0A4C4982F841A001EB8A0029688B +:10F590000160A97849480BF019F98146A87819E06B +:10F5A00000992C7801EBC80B0DE0DBE900672246DF +:10F5B000012000210AF029FF06400F403E4301D000 +:10F5C00009F804A0641C6878A042EEDA09F1280961 +:10F5D00008F10100E97880464145E1DABDE8FE8F97 +:10F5E0002DE9FF5F9B4614469178DDF838800BF0DB +:10F5F000DFF80746A178D8F804000BF0DFF80646DC +:10F600000025FFF7DAFC002832D02D49B8F9320086 +:10F61000B1F9001088422BDC2A48A17894F80390B5 +:10F6200090F800A016E0207862780CE017F800C08F +:10F63000019B9C4505D136F910C0DC4501DD6D1CF0 +:10F64000ADB2401CC0B28242F0D2491C06EB4A0661 +:10F65000C9B228378945E6D241462846FFF7C0FCA3 +:10F66000002805D0B8F8240040F40071A8F8241050 +:10F67000BDE8FF9FDA061000A0071000DE061000AC +:10F68000D8061000D6061000385701202E071000AB +:10F690002F07100030071000945A100018051000B2 +:10F6A0009C061000A8061000880610003A071000FB +:10F6B000CC06100070471000B62A01201E2701203A +:10F6C000D006100025071000F84800787047F84968 +:10F6D000087070472DE9FC430022DFF8D8830092C0 +:10F6E000019298F800406F4600230BE002FB0436BD +:10F6F00037F9125030F91660B54201DA27F8126076 +:10F700005B1C1BB2A342F1DB521C12B2022AEBDBE0 +:10F71000DFF8A493002201AE99F8004000230BE02B +:10F7200002FB043C36F9125031F91CC0654501DA80 +:10F7300026F812C05B1C1BB24D46A342F0DB521CE4 +:10F7400012B2022AEADB0023B94600220FE003FBD3 +:10F7500004244FF47A7C30F91470521C07FB0CF728 +:10F7600039F913C012B297FBFCF720F8147098F81F +:10F770000040A242EBDB5B1C1BB2022BE5DB00224C +:10F7800000200EE002FB03034FF47A7731F91340B7 +:10F790007C4336F91270401C94FBF7F421F81340B7 +:10F7A00000B22B789842EDDB521C12B2022AE7DB42 +:10F7B000BDE8FC832DE9F047DFF8FC8282468946EC +:10F7C00098F8002000252C4631F91200BB492F463D +:10F7D0002E460B6809EB8202B3F8D013B3F8D2338C +:10F7E000884203DD32F902CC9C454ADC984203DDB5 +:10F7F00032F9020C884244DC49465046FFF76AFF62 +:10F80000AC490020097814E03AF91020002A09DDFB +:10F810000B183AF91320002A04DD0CB97F1CFFB243 +:10F82000012405E00CB16D1CEDB2032D00D90024BC +:10F83000401C8842E8DB002198F8003001200A468D +:10F840005C1E15E039F91050002D0ADD03EB000CA9 +:10F8500039F91C50002D04DD09B9761CF6B20121DE +:10F8600005E009B1521CD2B2012A00D90021401C86 +:10F87000A042E7DB012F01D8012E02D90120BDE80B +:10F88000F0870020FBE72DE9FF4F8C480024DDF8CE +:10F8900044C001682646254691F8A32391F8A43375 +:10F8A000B1F8B97391F8BB93B1F9CA832046A24667 +:10F8B0009A4200D81A469346814A12781AB1B1F892 +:10F8C000BC7391F8BE93BCF1010F05D1B1F8C173BF +:10F8D00091F8C393B1F9CC837A4A0023B2F900E0DE +:10F8E0001FE0009AB1F8C4C332F91320CCF1000C28 +:10F8F000624507DA002A01DB944601E0C2F1000C00 +:10F90000664436B20FFA87FC624501DD641CE4B23E +:10F910005A4501DD15442DB2424501DD4FF0010A83 +:10F920005B1C7345DDDBBAF1000F45D0614A664BC5 +:10F930004FF0000C92F800E0674603EB4E0B9A463E +:10F94000624611E03AF91280B8F1000F0BDD3BF985 +:10F950001230002B07DDB8EB030300D55B421BB26E +:10F960009C4500DA9C46521C7245EBDB564B524AD2 +:10F9700098339A4692F800E0002203EB4E0B11E018 +:10F980003AF91280B8F1000F0BDD3BF91230002B71 +:10F9900007DDB8EB030300D55B421BB29F4200DAE0 +:10F9A0001F46521C7245EBDBB1F8C623BA4203DD99 +:10F9B000624501DD40F4C070B1F9BF23AA4201DD08 +:10F9C00040F00800B1F9C813B14201DD40F0040075 +:10F9D0004C4501D940F480400D9A0F99914201DACB +:10F9E00040F010000E9A914201DA40F02000039A94 +:10F9F0000199914202D80299914201D940F0400008 +:10FA00001099012901D040F4007004B0BDE8F08FD6 +:10FA10002DE9F74F96B00C464C2101A80AF0E0FD05 +:10FA2000264AA646106890F8311090F830300B4402 +:10FA30001B1BDDB2002314930093A14207D190F861 +:10FA4000A37301201490601E00F0FF0E01E090F8F7 +:10FA5000A4731E48007810B116480078009000206A +:10FA60000DF1040B5FE0154900232BF810300968F5 +:10FA700091F83110A14207D1009A13498618169ABD +:10FA8000A94602EB460208E00F49169E00FB04F26D +:10FA9000983106EB42024FF0010905EB000C21F80A +:10FAA000103021F81C30149E39E000001848100076 +:10FAB000980610002507100024071000A00710006A +:10FAC000B30610003A071000F62A0120390710008B +:10FAD000B2F90030B3F1000A01DACAF10003DB1B0E +:10FAE000002B0CDD3BF8108008EB0A032BF81030DC +:10FAF00031F81030B2F80080434421F81030B2F9E8 +:10FB00000030A3EB0708B8F1000F04DD31F81C80CA +:10FB1000434421F81C30761C02EB4902F6B27645CC +:10FB2000D6D3401CC0B2A8429DD32946584606F001 +:10FB300056FA0446FE48FF492A46007800900868B5 +:10FB400001A990F8A533189806F031FA204619B0AB +:10FB50005CE72DE9F04F93B00F4604461E4615466C +:10FB60004C2168460AF03CFD4FF0000A50464FF029 +:10FB7000CF0EEC464CE034F91010002939DD4FF07F +:10FB8000010AD1460CF810A0411C0EE034F91030E7 +:10FB900034F9112062B1B3EB020809D5D21AB2428E +:10FBA00002DD0CF810E003E0491CC9B2B942EDD304 +:10FBB0000CEB400B411E8BF801900FE034F9103034 +:10FBC00034F9112068B162B1B3EB020809D5D21A39 +:10FBD000B24202DD8BF801E01FE0491E49B2002964 +:10FBE000ECDAB9F1CF0F18D01CF81010CF2918D0CB +:10FBF00005E000210CEB40020CF8101051700CEBEA +:10FC000040011CF81020497811432954401CC0B20F +:10FC1000B842B0D3504613B0F8E61CF81010CF2904 +:10FC200002D005F80090F1E705F800E0EEE7F0B546 +:10FC3000064600200446034629E0F55C012D02D06B +:10FC4000012C19D021E05CB900EB4004135530B110 +:10FC5000A51815F8027C5D1EAF4200DA1555012487 +:10FC60004D1EAB4211D1012C0FD100EB40051544C4 +:10FC7000401C6B70C0B208E000EB40041444401C10 +:10FC800063700024C0B20F2803D85B1CDBB28B4228 +:10FC9000D3D3F0BD2DE9FF4FA6480C4600250068E0 +:10FCA00081B0A946818E90F831302F46B1FBF3FB2D +:10FCB000418E90F830002E46B1FBF0FA54E000205F +:10FCC0004CE000233FE003EB830101EBC30104EBB5 +:10FCD000C101B1F824C02CF4006CA1F824C006EBDB +:10FCE000460CCDF800C012F80CC0B1F90EE00CFBC8 +:10FCF0000AFCF44525DCDDF800C094449CF801C002 +:10FD00000CFB0AFCF4451CDB00EB400C9444CDF8E2 +:10FD100000C09CF82D80B1F90CE008FB0BF8F04511 +:10FD20000FDCDDF800C09CF82EC00CFB0BFCF4458A +:10FD300007DB6F1C81F8487009F10101012701F010 +:10FD4000FF095B1CDBB294F818169942BBD8012F4F +:10FD500002D100276D1CEDB2401CC0B20199497858 +:10FD60008142AED8761CF6B201980078B042A6D88F +:10FD70000025B9F1010F51D994F818064AE0002680 +:10FD8000411E4BB200EB800101EBC00104EBC1014D +:10FD90003BE091F84820AAB303EB830707EBC307C6 +:10FDA00004EBC70797F84870BA422CD183422ED093 +:10FDB00003EB830202EBC30204EBC202CF89B2F869 +:10FDC0000EC0B2F80C80A7EB0C070FFA87FC8F89E6 +:10FDD0000CFB0CFCA7EB08073FB207FB07C7DDF8DD +:10FDE00010C0674513D28D8C45F400658D84918CCD +:10FDF00041F400619184C2B2D9B2204601F0E9F920 +:10FE0000012505E0FFE75B1E5BB2002BC1DA0EB1F6 +:10FE100094F91806401E40B20028B0DC284605B010 +:10FE2000F4E52DE9F04F8BB000200590FCF733FF8F +:10FE30000A9040484FF000080468B4F8A973B4F879 +:10FE4000AD5394F8B11306913B49B4F8A763097810 +:10FE500041B1B4F8B373B4F8B55394F8B213069142 +:10FE6000B4F8B763DFF8D4A09AF80010012906D1DE +:10FE7000B4F8AB1339448FB2B4F8AF130D448146D4 +:10FE800094F8A203000652D50A9890F818060128A3 +:10FE900002D84FF400500BE094F8A613884202D920 +:10FEA0004FF4806004E026480078012801D1C002A8 +:10FEB000804622485A219E3007900AF06FFB94F842 +:10FEC0003010204C1D4A921C2068FFF7A1FD83468C +:10FED000D9F80000194A90F831102C3200922068AD +:10FEE000FFF796FD184982460246A1F19800FFF7F8 +:10FEF00061FC0446012806D1D9F8000090F8CE1321 +:10FF000090F8CF630D440AFB06F0642190FBF1F0FA +:10FF100083B2D9F80000094A90F83010783208927C +:10FF20000098FFF716FE0090D9F800000EE04AE0B6 +:10FF300098061000A0071000B30610001848100023 +:10FF4000290510004C0710008E2B012090F830106E +:10FF5000DDE90720FFF76BFE8DF814000BFB06F0C0 +:10FF6000642190FBF1F083B2D9F800001D4E089A8D +:10FF700090F83110B01CFFF7ECFD0146009806F137 +:10FF8000CB0201430091D9F8000090F83110089895 +:10FF9000FFF74DFE8DF815000099CDF800B0CDE9C2 +:10FFA0000314CDE901A702460F489DF81410069BE3 +:10FFB0000068FFF768FC50EA080406D000203070A3 +:10FFC0000A48A0F885400BB020E505FB05F305A81D +:10FFD000079A0A99FFF75EFE30700028F0D14FF4BF +:10FFE0008054EDE7184810004C07100038570120E6 +:10FFF000017859B1954A1278521E914206D0407844 +:020000021000EC +:1000000020B193490978491E884201D101207047E7 +:1000100000207047017829B18C4942780978491E3F +:100020008A4209D1817829B1C17889480078401E77 +:10003000814201D10120704700207047F0B5854E04 +:10004000002206EBC2030024C3E90044521CD2B2D2 +:10005000172AF6D38B782CE000EBC302D2E90072AA +:1000600057EA020423D055084FEA370417EB070E6E +:1000700042EB020C45EA0C05154344EA0E0406EB7C +:10008000C3023C43D2E9007C27434CEA050CC2E999 +:10009000007CD2E9027C27434CEA050CC2E9027CD1 +:1000A000D2E9047C27434CEA050CC2E9047C5B1CC2 +:1000B000DBB2CA789A42CFD20022654F09E006EB44 +:1000C000C203D3E9024500EBC203521CC3E9004559 +:1000D000D2B23B789A42F2D3087808B1401E087039 +:1000E0005A4A48781278521E904201DA401C4870F1 +:1000F000887808B1401E88703A78C878521E9042BD +:1001000001DA401CC870F0BD2DE9FF5F8B4697787F +:100110009146014607EB870201EBC201002001F185 +:1001200029081FE000252E4699F8004099F801A003 +:100130000DE018F804205A4507D12246012000217D +:100140000AF063F905430E430120641CE4B2A245A2 +:10015000EFD2039908F1280801EBC7017F1CC1E920 +:100160000056FFB299F80310B942DBD204B0BDE8E3 +:10017000F09F70B50E788D784C78C9789AB10EB131 +:10018000761EF6B2314A1278521E944201DA641C8D +:10019000E4B20DB16D1EEDB22D4A1278521E91429D +:1001A00001DA491CC9B205EB850200EBC20000224E +:1001B000293009E0334602E0C2545B1CDBB2A342A3 +:1001C000FAD96D1CEDB228308D42F3D970BD2DE9FE +:1001D000F04789469178DFF874A001EB810400EBC9 +:1001E000C4079AF800405868614300EB41060020BC +:1001F0009861194D03F13E0C947829371FE010786F +:1002000013E017F80080C8450DD136F91010D3F867 +:100210001880A9428844C3F8188004DD8CF80000D7 +:100220000D468CF80140401CC0B251788142E8D2A2 +:100230009AF80000641C06EB4006E4B22837D07838 +:10024000A042DCD25D86BDE8F087000025071000E3 +:1002500024071000104910000080FFFF2DE9F0472F +:10026000804627488F780C460078801E012F05D9DC +:10027000E178814202DA0020BDE8F087022F01D246 +:10028000022601E0E678C7B24FF000093946D8F8F7 +:1002900008000AF093FA05463946D8F804000AF037 +:1002A0008DFA01461748027815E0207863780AE055 +:1002B00035F910C031F91080C44502D04FF0010962 +:1002C00003E0401CC0B28342F2D27F1C05EB420522 +:1002D00001EB4201FFB2B742E7D94846CCE70849F3 +:1002E0000978491ECAB290F83F1009B1914205D170 +:1002F000818C41F002018184012070470020704709 +:10030000240710002507100030B5B0B1884214D082 +:1003100002D20A4601461046CC4B5A6802EB400214 +:1003200014788C4209D054788C4206D09C68235CA7 +:10033000022B02D25D1C2554D154084630BD2DE954 +:10034000FF4F087887B00F46FF282CD0C04983465E +:1003500078780978884201D2401C00E0084600F015 +:10036000FF09B878BB490090F8780978884201D233 +:10037000401C00E00846C0B202900020019009989D +:1003800010B197F80E010190B04C206800F15A01AD +:10039000C4E901015A210AF001F9214622462D2023 +:1003A000496893680AE04FF0000BD9465846CDF8EB +:1003B00000B0E1E701F8100000221A54401EC0B25C +:1003C000F8D20198401CC5B20590009800EB80015E +:1003D000079800EBC10600980496401C3FE0B04629 +:1003E0000BF101002836C4B235E03119086880B13C +:1003F000305D70B3CF282CD011F8011C002001B162 +:10040000084618F8041009B1FFF77EFF0A9949B9A8 +:1004100002E0E41CE4B21CE08F49096891F8811203 +:1004200009060CD508EB0401039111F8011C09B170 +:10043000FFF76AFF0399497809B1FFF765FF38B9FB +:100440002D2D03D228466D1CEDB201E0681EC0B20E +:100450003055641CE4B24C45C7D90AF10100029939 +:1004600000F0FF0A8A45BAD9284600F066F88246AD +:1004700005980022C0B2794B09E007EB80011C68A7 +:100480000C6007EB4001401CA1F8B420C0B25045FD +:10049000F3D3049EDDF8008029362FE05D4626E088 +:1004A0007059E8B3705D00B36849496811F81000ED +:1004B000705507EB400107EB800431F8B42F284654 +:1004C000521C0A80217804F0CDFC20706178284607 +:1004D00004F0CCFC6070A178404604F0C3FCA0702E +:1004E000E178404604F0C2FCE0706D1CEDB24D4571 +:1004F000D6D308F1010000F0FF082836029988459C +:10050000CCD3AAF10100C2B287F80E2109980028C5 +:1005100010D00198101A01280CD13B46099900E02F +:1005200005E007980BB0BDE8F04F00F051B8ED1CA6 +:10053000EDB2DAE70BB0BDE8F08F2DE9F05F82464F +:100540000026DFF808B12AE0DBF808108C5DDBF844 +:10055000041001EB460719E03819804610F8011C19 +:1005600010F8029C084600F066F80546484600F080 +:1005700062F8854202D2014628460D46DBF8041097 +:10058000641EE4B201F8105008F8025C012CE3D8B4 +:1005900003D1304600F04FF83870761CF6B256455D +:1005A000D2D300200146DBF804400DE004EB410209 +:1005B00013788B4203D11070401CC0B202E014F8D3 +:1005C00013301370491CC9B25145EFD3BDE8F09FF9 +:1005D000F0B503EB8204A77807EB870500EBC506AF +:1005E000E0782836B8420FD3207807E0351895F820 +:1005F00001C0944500D16970401CC0B26578854245 +:10060000F4D27F1CFFB2EBE703EB810025680560A5 +:1006100003EB420003EB410130F8B42FA1F8B42002 +:100620000E49096821600021018093F80E01401EE7 +:1006300083F80E01F0BD054AD2E9011201E011F87C +:100640001000135C002BFAD1704700009C061000CC +:100650002507100024071000A00710001AA80100A9 +:10066000F0B5B2F900400568AC4202DDB3F9001004 +:1006700030E002EB410434F9026CAE4204DA03EBE1 +:10068000410131F9021C25E0002634464F1E0CE0E2 +:1006900032F914C0AC4507DC02EB440CBCF902C0D3 +:1006A000AC4501DB26460C46641CBC42F0DB32F94B +:1006B000161003EB460433F91630B4F9024002EB8E +:1006C00046026D1AE41AB2F902206C43511A94FBE7 +:1006D000F1F119440160F0BD2DE9F04104461948DB +:1006E0000F00036803F2FF3293F8F81393F8F953FD +:1006F00002EB41061BD0022F1CD0032F1DD0042F6C +:100700001ED193F8FE03012902EB400C0CEB4107CC +:1007100004DD1346201D6246FFF7A2FF012D0FDD09 +:10072000204633463A462946BDE8F04198E793F81B +:10073000FA03E8E793F8FC03E5E793F8FD03E2E743 +:10074000BDE8F081A0071000002819DD43F2DC713C +:10075000884201DA5520704744F68921884201DA3F +:100760005620704746F6DC71884201DA5720704700 +:100770004DF6C971884201DA5820704759207047F8 +:100780004DF6C971C84202DA6FF05900704746F65B +:10079000DC71C84202DA6FF05800704744F68921D4 +:1007A000C84202DA6FF05700704743F2DC71C8426A +:1007B00002DA6FF0560070476FF0550070472DE970 +:1007C000F0411546DDE90668971B1C4663EB0802FD +:1007D000A7FB073C02FB07CC07FB02C2A0FB007C87 +:1007E00001FB00CC00FB01C04FEA800CB8004CEAD2 +:1007F000977C181842EB0C0104F0F0FAAD1944EBA9 +:1008000008042A1844EB01032D1A64EB01044FF489 +:100810007A71A5FB010704FB0171002605FB061197 +:1008200009F019FE4FF47A71D0EB010080B2BDE8F7 +:10083000F0812DE9F05F8146DDE90A8B0C46001856 +:1008400092466141B2EB08021D4663EB0B0316466C +:100850001F4600F037F90C9932460870A2FB0201DE +:1008600007FB061106FB07134946A1FB012604FB03 +:10087000096609FB0461890041EA927192008018BF +:10088000594104F0ABFA1AEB080445EB0B030A4696 +:10089000261843EB0201241A63EB0205304604F0EC +:1008A0009DFA49084FEA300080B24FF00A06B0FBCB +:1008B000F6F10D9801802046294604F08FFA490888 +:1008C0004FEA300080B2B0FBF6F10E980180BDE82F +:1008D000F09F2DE9FF4FBDB00024CDE93144CDE9B3 +:1008E0002F44CDE93744CDE93544CDE9334412688E +:1008F0002E92A346A2466B462EAAFFF705FC2EA910 +:100900006846FFF79BFB40989DF8BA10406809F0D5 +:1009100055FF39909DF8BB009DF8BA503A908DE094 +:100920009DF8B8409DF8B9003C943B907AE0684649 +:1009300000EBC5002246D0E900670120002109F044 +:1009400064FD06400F403E436AD0399830F91400E8 +:10095000002865DD642148434099954AB1F9321079 +:10096000126890FBF1F03A99938E491B491C594348 +:1009700092F83130568E5B1E91FBF3F13C9B92F85E +:100980003020E31A5B1C7343521E93FBF2F3A0FB6F +:10099000032C4FEAE07E0EFB03C6DF17DDE931C80A +:1009A0001BEB000B4AEB0E0A00FB076618EB020874 +:1009B0004CEB060CCDE931C8A2FB03C806FB038350 +:1009C00002FB0733DDE935871CEB070743EB080320 +:1009D000CDE93537A2FB017C06FB01C64FEAE17980 +:1009E00002FB0962DDE93736BE195A41CDE93726E7 +:1009F000A0FB01270EFB017600FB0960DDE92F3625 +:100A0000B6184341CDE92F36A2FB016700FB017008 +:100A100002FB0900DDE9332171185041CDE93301B2 +:100A20003B98641CA04282DA61486D1C006890F813 +:100A30003010399800EB410039903A98A842BFF63F +:100A40006FAFDDE93131DDE92F42A1FB020503FB88 +:100A5000025201FB04215A46534609F0FCFCDDE931 +:100A600037231B1A409862EB0102C0E91432DDE91A +:100A70003112A2FB020301FB023302FB01315A4691 +:100A8000534609F0E8FCDDE935231B1A409862EB78 +:100A90000102C0E91632DDE92F12A2FB020301FBBD +:100AA000023302FB01315A46534609F0D4FCDDE91A +:100AB00033231B1A409862EB0102C0E9183241B09F +:100AC000BDE8F08F2DE9F04116461F4604460D465D +:100AD00000F029F8401056EA070107D0002211461D +:100AE000921BB94110DA2C430AD0A0E654EA050063 +:100AF00006D000210846091BA84103DA2D2096E6FE +:100B0000002094E65A2092E654EA050106D000221D +:100B10001146121BA94104DA5A3088E66FF05900D9 +:100B200085E65A3883E62DE9F0414FF47A74A0FB4C +:100B3000045701FB0471002600FB0611284609F04A +:100B40008AFC1C4A821A71F1FF3205DB42F6A64389 +:100B500000221B1A8A4102DABDE8F041F4E50023C5 +:100B6000154D1A4635F91240E617041B71EB0604C1 +:100B700009DB05EB4204B4F90240E617241A8E4162 +:100B800001DB13464622521C452AEBD303EB8302BA +:100B900035F9131005EB4303553A401AB3F9023007 +:100BA00000EB8000A3EB010190FBF1F010443EE666 +:100BB000A00710005AD3FFFFC0A701002DE9F74F8F +:100BC00098B0FE4C2020179023781546581EC6B2C8 +:100BD00000224FF0210B10460BE0F94931F81010BC +:100BE00029B1864200DDC6B2824200DAC2B2401CA0 +:100BF00000B29842F1DBF3484FF000094F4601681C +:100C00004B4601F646210C46002011F80080401C9E +:100C100000B2C1440328F8DB5B1C1BB2C91C032BC8 +:100C2000F2DB23460021002013F800C0401C00B274 +:100C300067440228F8DB491C09B2DB1C0329F2DBFC +:100C4000521CD0B2761E1690F6B22C21684609F0DE +:100C5000C7FC2C210BA809F0C3FC9BE0701EC1B29D +:100C6000199809F0ABFD824617998EE0D64A00200C +:100C70001278531E99420AEB410333F902CD34D165 +:100C8000AC4503DD94F800800CFB0800B3F902C00A +:100C9000AC4503DD94F801800CFB080003EB420334 +:100CA000B3F900C0AC4503DD94F803800CFB0800E9 +:100CB000B3F902C0AC4503DD94F804800CFB0800D6 +:100CC00003EB4202B2F90030AB4203DD94F806C0F8 +:100CD00003FB0C00B2F90220AA4202DDE37902FB19 +:100CE000030090FBF7F00BAA4BE0AC4503DD94F852 +:100CF00000800CFB0800B3F902C0AC4503DD94F89A +:100D000001800CFB0800B3F904C0AC4503DD94F886 +:100D100002800CFB080003EB4203B3F900C0AC45B2 +:100D200003DD94F803800CFB0800B3F902C0AC4566 +:100D300003DD94F804800CFB0800B3F904C0AC4553 +:100D400003DD94F805800CFB080003EB4202B2F9C6 +:100D50000030AB4203DD94F806C003FB0C00B2F98F +:100D60000230AB4203DD94F807C003FB0C00B2F97C +:100D70000420AA4202DD237A02FB030090FBF9F073 +:100D80006A46491C22F81600C9B259457FF66EAF73 +:100D9000761CF6B2169886427FF660AF0024DFF824 +:100DA00020826D460BAE854F12E038F8140068B112 +:100DB000E1B2189809F010FD36F9141030F9402FFF +:100DC000514335F9142091FBF2F14180641C24B2A7 +:100DD00038788442E9DB1BB0BDE8F08F2DE9FF5F76 +:100DE0000024DDF838908B4698461546274626465F +:100DF00009F0FF01009809F0E1FC30F91800A84261 +:100E00002DDDA9F1010509F1010A24E0002D1FDB08 +:100E10006A48007885421BDAE9B2009809F0CEFCF6 +:100E2000694AA8F101018B1C92F800900DE000299D +:100E300008DB494506DA3BF9142030F911C01644A5 +:100E40000CFB0277641CE4B2491C9942EFDD01E01F +:100E5000E41CE4B26D1C5545D8DD0EB101E0074637 +:100E6000012697FBF6F004B000B2BDE8F09F2DE933 +:100E7000FF4F83B01446DDE910120F7888784D7863 +:100E8000CE7832B18046B4F912005FEA000A7DD014 +:100E90009EE007B17F1EFFB200B1401EDFF828B10F +:100EA00000F0FF089BF80000411E8D4201DA6D1C26 +:100EB00000E00D464148EDB20078411E8E4201DA55 +:100EC000761C00E00E46F6B2CFB94046C14612E0AD +:100ED0000146039809F080FC82463B46CDF800901D +:100EE0002146069A0498FFF779FF2AF8170009F1BE +:100EF0000100C0B28146B145EAD97F1CFFB29BF820 +:100F00000000401E854219D14046C14612E001460C +:100F1000039809F061FC82462B46CDF800902146EB +:100F2000069A0498FFF75AFF2AF8150009F1010004 +:100F3000C0B28146B145EAD96D1EEDB2B8F10000EC +:100F40001AD10146039809F047FC8246B9460DE0E4 +:100F50004B46CDF800802146069A0498FFF73EFFE5 +:100F60002AF8190009F1010000F0FF09A945EFD99D +:100F700008F1010000F0FF0810480078401E86428A +:100F800081D13146039809F027FC00E01EE082463B +:100F9000B9460CE0034600962146069A0498FFF7EE +:100FA0001DFF2AF8190009F1010000F0FF09484669 +:100FB000A945EFD9761EF6B265E7000024071000B8 +:100FC00034260120A0071000250710004FF0010A69 +:100FD0004046C14664E00146039809F0FDFB0190DC +:100FE000A9F10100C1B2049809F0E8FB009049465C +:100FF000049809F0E3FB834638464BE03BF91010B8 +:10100000069A914241DD0099B4F900C001EB40011C +:10101000002231F9023DB4F9068003FB0C22B1F93C +:101020000230B4F902C003FB0C22B1F90430B4F968 +:1010300004C003FB0C23284A127801EB4201B1F9EA +:1010400000C00CFB0833B1F902C0B4F908800CFBF6 +:101050000833B1F904C0B4F90A8001EB42010CFB7A +:101060000833B1F90020B4F90CC002FB0C32B1F91D +:101070000230B4F90EC0B1F9041003FB0C22B4F92C +:10108000103001FB032191FBFAF1019A22F81010B4 +:10109000401CC0B2A842B1D909F10100C0B28146DA +:1010A000B14598D907B097E63EB502248DF80840BF +:1010B0008DF80A40094C246814F8305FED1E8DF855 +:1010C000095064780125E41E8DF80B4002ACCDE98F +:1010D0000045FFF7CCFE3EBD25071000A00710001D +:1010E0002DE9FF4FAFB092464FF46671FE4809F00C +:1010F00055FA01203EE0B821684609F071FA3298AD +:1011000008F0FF0100EB88006B4600682E902EAAC5 +:101110003098FEF7F9FF58B32EA96846FEF78EFF08 +:101120009DF8BA5020E0E9B2EF4809F04FFB814644 +:1011300068469DF8B84000EBC50B10E0DBE900679E +:1011400022460120002109F060F906400F403E438D +:1011500004D019F80400401C09F80400641C9DF830 +:10116000B900A042EADA6D1C9DF8BB00A842DADAA9 +:1011700008F101008046329890F80E114145BADA24 +:101180009AF802401EE0E1B2309809F01FFB0646D3 +:10119000E1B22F9809F01AFB0546E1B2D24809F0F6 +:1011A00015FB02469AF80010CF2006E0535C012B95 +:1011B00002D9735C03B96854491C9AF801308B4218 +:1011C000F4DA641C9AF80300A042DCDA33B0BDE81C +:1011D000F08F2DE9F0470446914260D007D901EB2A +:1011E0000200A0EB0201CAB2A0EB0200C1B201EB07 +:1011F000810000EBC10004EBC00102EB820000EBB8 +:10120000C20004EBC003B1F93250B3F93200994681 +:10121000854200DA4886C88CDD8C2844C884088D55 +:101220001D8D28440885488D5D8D28444885886932 +:101230009D6928448861DD69CE69CF68D9F80C3092 +:101240004FEA274C4FEA23480CFB06FC05FB08CC71 +:1012500070199CFBF0FC6CF31F470FFA87FC0CFB2A +:1012600006FC1BB205FB03C393FBF0F363F30F070C +:10127000CF60C86194F81806411E91420AD000EB75 +:10128000800101EBC00004EBC001484668226839C8 +:1012900009F04AF994F81806401E84F81806BDE8CB +:1012A000F08770B500231A46904C914E16E090F8E6 +:1012B000300002FB0061002008E028B10D1815F88D +:1012C000015C6D1C0D5400E00B70401C256895F806 +:1012D00030508542F1DC5B1CDBB2521C206890F878 +:1012E00031109142E3DC00231A4616E090F83000FA +:1012F000804902FB00110BE0256895F830506D1E07 +:10130000854204D00D186D786D1C0D5400E00B540F +:10131000401EF1D55B1CDBB2521C206890F83110E6 +:101320009142E3DC70BD2DE9FF4F83B00020DDF872 +:10133000409092468B4689F80000039A0121521E84 +:101340001FB202926EE00BEB410CBCF9024001941B +:101350003BF81120A41A26B23CF9024C0094A41ABE +:10136000BCF9048025B2A8EB02043CF904EC24B2D9 +:10137000AEEB020212B2012938D0DDF80CC0ACF19C +:10138000020C614500D10024DDF804C0BCF1000F5F +:1013900000DC3E46DDF800C0BCF1000F00DC3D463D +:1013A000B8F1000F00DC3C46BEF1000F00DC3A460D +:1013B000002E35DD002D33DD9E4201DD9D420BDC2C +:1013C0009C4201DD9D4207DC9E4201DD9A4203DC26 +:1013D0009C4225DD9A4223DD4FF0CF0C0AF801C074 +:1013E000DDF84480B8F1010F02D007E00022CBE71E +:1013F0000AEB010888F801C008F801CC99F800C090 +:10140000B0420CF1010C89F800C000DA3046A84265 +:1014100000DA2846A04200DA2046904200DA104660 +:10142000029A491C91428EDB07B0D0E610B54C21E0 +:10143000314809F0B3F830482A214C3009F0AEF8B1 +:101440002D487621763009F0A9F82B487621EC302A +:1014500009F0A4F82621294809F0A0F82748152109 +:10146000153809F09BF825483B21263009F096F8FD +:1014700022483B21BDE81040613009F08FB82DE9CA +:10148000F04F8E468278DDF824C047E002FB03F17E +:101490000EEB4104164902FB031B164902FB031A1B +:1014A000017837E034F911502E1E00DA7542654597 +:1014B00006DD114D4C3535F812703E4425F81260AA +:1014C00034F911700A9DAF4223DDDFF82C901BF830 +:1014D000016009F176091AF8015039F8168047447D +:1014E00029F816700CE0000004501000A00710004E +:1014F000C8491000E64C1000E22B0120592D0120B4 +:1015000009F1760634F8118036F81570474426F84C +:101510001570491C45788D42C4DA521CC17891423D +:10152000B4DA017817E00EEB41058278FE4E0EE04A +:1015300002FB03F435F91440271E00DA7C426445AF +:1015400004DD36F811403C4426F81140521CC478A2 +:101550009442EDDA491C42788A42E4DA37E62DE912 +:10156000FF4FF248F24F8DB08B46C179DDF86880AD +:1015700038681C4639B190F8B310059130F9AD6F59 +:10158000B0F9025014E090F885120591B0F9866226 +:10159000B0F9885290F89C0250B1FBF784FB39688F +:1015A00091F89C22904203D8B1F99862B1F99A520D +:1015B0000027DFF88093039704970297B2B2DA49C5 +:1015C00099F8000000F07EFA0DF1080ACDE900A7B5 +:1015D00083B2D94AD44999F80000FFF7A4FEB2B209 +:1015E000D64ED149ADF80C004C31307800F06AFA93 +:1015F0000DF10901CDE90017CF4A83B2153AA2F5E2 +:101600008B713078FFF78FFEC749ADF80E00AAB294 +:1016100076313B2000F056FA01260DF10A01C64A48 +:10162000CDE9001683B22632A2F227113B20FFF744 +:101630007AFEC149ADF81000AAB28B393B2000F008 +:1016400041FA0DF10B01BC4ACDE9001683B26132BB +:10165000A2F1EC013B20FFF766FE0025ADF8120079 +:101660002946284603AE53461A5CAA4202D91546BB +:1016700001460AE008D345B136F9112036F910C009 +:10168000624501DA5F5400E01F54401CC0B20428D8 +:10169000EAD3A0780090E0780C90D8F80800009980 +:1016A00009F08CF881465846009909F081F8824685 +:1016B00000990D9809F08AF806460598E8B30F9945 +:1016C0000B9101A90A9106A909915846A17809F040 +:1016D0006FF80746A178D8F8080009F06FF884463B +:1016E00094F802B0E0780890924847F6FF73DA4326 +:1016F0000078079019E0207894F801E00DE017F8E1 +:1017000000800B99884507D13CF91010994200DA06 +:101710000B46914200DD0A46401C8645EFD20798F1 +:101720000BF1010B0CEB400C283708985845E2D21E +:101730000A9803800998028000E00EE0BDF91800C5 +:10174000BDF90410411A05984143642091FBF0F063 +:101750007B490988084407B202E07948B0F9007073 +:10176000009A44E0217837E01AF801300F9883425C +:1017700031D1704BDFF8D0C11B788C4402FB03F0F1 +:10178000704B0B44C35C10F80C009DF808C0AC45CE +:1017900002D16948405C16E09DF809C0AC4503D110 +:1017A00065481538805C0EE09DF80AC0AC4503D151 +:1017B00061482630C05C06E09DF80B30AB4204D196 +:1017C0005D4B6133185CCF2805D039F91100B84260 +:1017D00001DD01207054491C60788842C4D255490B +:1017E000521C0AF1280A0978283609EB41090C989D +:1017F0008242B7D911B0EAE42DE9FF4F53488BB0CC +:1018000000270668524D781E09901C4606F5887818 +:1018100001220D992868FEF7ACFCDFF814B1DBF863 +:10182000000090F88102000606D50BA8009490E80D +:101830000E002868FFF793FE46483B46007848B103 +:1018400094F8240010F0060F04D120460D99FEF7FD +:1018500005FD0346002086F80E010D980022314652 +:1018600000683060AA462868FEF769FD96F80E0108 +:1018700001280CD9DBF8000090F88002C00706D0E0 +:10188000DAF8001033460D9A0846FFF729FC96F85F +:101890000E01002701287DD9FBF701FA0890FBF71C +:1018A000FAF981460B980290DDE90C502A4B00684A +:1018B000019001AA29460298FEF726FC70B101A901 +:1018C0002548FEF7BBFB0095224601A92248029B52 +:1018D000FDF702F8E1686161E169216201258BE0B1 +:1018E00068222146404608F01FFE114906EB4500DC +:1018F0000968B0F8B42091F88C128A427BD9012192 +:10190000099AA940114276D0B8F82410234641F034 +:101910001002A8F82420B0F8B410A8F82610DDE9C9 +:101920000C12DAF8000019E0E22B0120945A1000A2 +:10193000A007100025071000592D012024071000D2 +:10194000D6061000C8491000E64C1000A80610008A +:101950008C061000E806100070471000FEF7B9FF73 +:10196000D4E91801CDE9000104F150010FC9FEF7D7 +:1019700026FFA08500208DF81400ADF81800ADF802 +:101980001C0002AB07AA06A905A883E80700D4E952 +:10199000180100E05DE0CDE9000104F150010FC93C +:1019A000FEF747FFBDF81800E085BDF81C10218642 +:1019B0009DF8141084F849104B4906EB85029346B4 +:1019C00021F8800F208E488094F849004346C0F1EA +:1019D000FF000871E9B2DAF80000FEF7F8FB012019 +:1019E00000905A46E9B24346DAF80000FDF783F862 +:1019F00008B17F1CFFB26D1C96F80E01A842BFF41F +:101A00006FAF3A48026892F8800200061DD5394649 +:101A100019E0089892F8C0520844C0B200EB800365 +:101A200003EBC00309EBC300C38CAB4209D890F8A9 +:101A3000373090F83600181A92F8C132401C98429C +:101A400001DD089813E0491EE3D2012F0BD0002FCF +:101A500007D101200BAD009095E807002346FDF764 +:101A60004AF80FB07AE599F8180600B1401E89F8D7 +:101A70001806EEE738B51468C3F83A401C4C2578D0 +:101A80001A4C012D246803D094F880526D0714D5A8 +:101A900094F880526D0609D5164D6D7855B1B4F89D +:101AA0009042154D64432D68A54206DC01B0BDE8A7 +:101AB0003040A1E6B4F88E42F3E701240094FDF72C +:101AC0001AF838BD30B50024234605E031F913502B +:101AD000A54200DD2C465B1C8342F7DB54436420A7 +:101AE00094FBF0F000B230BD38570120A007100081 +:101AF00018051000D80710006807100070472DE97E +:101B0000F34F85B0002001907B488A4604787B48DB +:101B100090F800E07A4890F800B07A4803787A4864 +:101B200000935B1E016857E07848009E002210F881 +:101B3000145004FB06F0059E06EB400604960AEBE3 +:101B400040060296724E366806EB400003900098FD +:101B5000401B3FE0049DB1F84660BEF1010F35F92E +:101B60001090029D35F91070B1F8485002D0BBF1C9 +:101B7000010F03D1B1F86360B1F86550BEF1000FF9 +:101B800002D0BBF1010F0FD0834202D0012800D058 +:101B900050B94AB9DDF80CC0B1F867803CF910C003 +:101BA0001CEB080F00D5012207EB060CCC4502DB2D +:101BB0007E1B4E450EDD2AB1834208D0012806D097 +:101BC00040B904E0834205D0012803D010B10120C0 +:101BD000019001E0401EBDD2641EA5D20198B0B9AB +:101BE00091F8440000F00F014A48C1F11004B0F927 +:101BF00000000AE0059B3AF9102033F910304A43FF +:101C000003FB042213112AF81030401EF2D23E4882 +:101C1000006890F8010200060BD5384800780128CA +:101C200007D1059807B05146BDE8F04F0022F3F701 +:101C3000A5BF07B0BDE8F08FF0B501271446DDF869 +:101C400014C00BE031F9145030F9146005EB030EA9 +:101C5000B6451BDBA5EB0C05B54217DC641EF1D1C4 +:101C6000002F13D0284B1B6893F845301B09C3F194 +:101C7000100609E031F9125030F912405D4304FBBF +:101C80000654241121F81240521EF3D2F0BD38B58B +:101C90000D46044601F0CDF900282CD1E80708D004 +:101CA0001D4801681D480078012802D12068FFF70F +:101CB00026FFE8061FD51A48134D007858B128684A +:101CC000B0F9501000910C49B0F94E3020690A78F3 +:101CD0001449FFF7B1FF1448007800280BD028689A +:101CE000B0F9541000910749B0F9523060690A7890 +:101CF0000E49FFF7A1FF38BD240710002905100089 +:101D00001805100025071000A00710003426012038 +:101D10004C0710003A071000580710002A0710005F +:101D200023071000F87601202207100022770120F7 +:101D30002DE9F0478E488946089F01788D489246E4 +:101D4000006811B1B0F9692214E03FB18A49B0F9D5 +:101D50007122097871B1B0F96F220BE08749B0F9AF +:101D600073224978022902D3B0F9772202E009B13F +:101D7000B0F975228248012690F800C023E057B1DF +:101D800003FB0CF00AEB400409EB4005A41CAD1C5E +:101D9000ACEB060015E07B4810F81300401CC6B2FF +:101DA000EEE735F9101034F91080B1EB080100D5D9 +:101DB000494209B2914204DD734801800020BDE828 +:101DC000F087401EEDD25B1ED9D20120F7E76948AB +:101DD00010B5006890F86612890727D56B4A11780C +:101DE000491CC9B2117090F868328B421ED2002192 +:101DF000117090F800120324C90703D190F8BA00BB +:101E0000C00700D00B24EEF7F9FA614801682143BE +:101E10000160EEF7F1FA1021052002F022FCBDE886 +:101E200010404FF48071002006F027BB10BD2DE953 +:101E3000FF4F5848002681B090F8008056489146E0 +:101E40008A4600783546B34618B1544800780128D0 +:101E500022D04848006890F86602C0071CD00024D1 +:101E6000019F16E0DDF810C00E9B0093E0B23946EA +:101E700052466346FFF75CFF10F0010F05D00120CA +:101E8000A04030436D1CC6B2EDB2641C07EB49079D +:101E900024B24445E6DB01E04546FF264048067093 +:101EA00045B11FFA89F2334641460095019800F08A +:101EB00020F807E03448B0F90010032002F0D1FB0D +:101EC0004FF0010B2B48006890F86602C00608D559 +:101ED00034484FEA49020168019800F6784008F05A +:101EE000DEFA05B05846BDE8F08F2849002008709A +:101EF00070472DE9F003DDF818C0BCF1000F1AD0CF +:101F00000126BCF1010F02D01746B1462CE0002497 +:101F10000FE006FA04F51D420AD0002C0BD0530046 +:101F20006243BDE8F00300EB42011A4608F0B7BA7D +:101F3000641C8C42EDDBBDE8F0037047002600EB2B +:101F4000470534460AE009FA04F818EA030F02D0FC +:101F5000B5F90080464405EB4205641C8C42F2DB77 +:101F600096FBFCF420F817407F1EE7D2E3E7000061 +:101F700029051000A0071000B3061000D8071000B4 +:101F80002507100034260120BC061000AC06100006 +:101F9000AC07100027071000945A10001805100015 +:101FA000B10610004C07100010B5F3F7D5FDBDE8E1 +:101FB0001040F2F701BF2DE9FF4F83B000248146A6 +:101FC0009A46934626468DF80440022006F0F5FA1C +:101FD0005A4648460499F5F7F0F8F949F94FDFF801 +:101FE000E883CA7809F6784560F30302CA700628C8 +:101FF00006D0012819D002281ED003281CD02CE0BE +:10200000022006F0F5FAB7F9000029464200D8F898 +:10201000000008F044FAF2F7C2FE0221012006F0A7 +:102020002CFA002007B0BDE8F08FE8480670FDF7F5 +:102030007FFAFAF795FD11E0FDF750F8FAF740FE48 +:1020400090B3B7F9000029464200D8F8000008F024 +:1020500026FAFF21032002F004FB012401A80090CE +:1020600053465A4648460499FCF7A9F940EA040544 +:10207000022006F0BDFA9DF8040098B1EEF7BEF913 +:10208000D349D4480A68006802430A60EEF7B4F9FD +:10209000D1480178052002F0E4FA4FF48071002065 +:1020A00006F0EBF92846BDE7FFE7FAF7FFFCD5E7B6 +:1020B0002DE9F34F83B00221684600F039FA002180 +:1020C0008FE0C64F049B387801FB00F203EB42051A +:1020D00005EB400404EB400303EB400202EB400B32 +:1020E0000BEB400A0AEB400909EB4000019000208D +:1020F00071E03BF810C03AF8107039F81080BC4419 +:10210000019F01FB060637F8107047440CEB070EE1 +:1021100035F8107034F810C0DDF80080A7EB0C071C +:1021200033F810C0A7EB0C0C0CEB0E0732F810C004 +:10213000674428F8167034F8106035F81070DFF82E +:102140009CC2F61B33F810709CF800C03E4432F875 +:102150001070F61B06EB0E074E1C06FB0C06DFF894 +:102160007CC228F816703BF810703AF810609CF8A2 +:1021700000C0BF1B39F810603744019E36F810606C +:10218000A7EB060E35F8106034F810703E4433F8B3 +:102190001070F61B32F81070F71B8E1C06FB0C0635 +:1021A000774428F8167035F8106034F81070DFF8AE +:1021B0002CC23E4433F810709CF800C0BF1B07EBE4 +:1021C0000E0632F810703744CE1C06FB0C06401C7D +:1021D00028F8167080B2814E3678B04289D3091D36 +:1021E00089B27F4800788142FFF46BAF7C487B491D +:1021F00000780978484342000099039808F04FF9A5 +:102200000221684600F0F2F905B00CE72DE9FF4F16 +:1022100083B00B00DDE912124FF00006DFF8C4B105 +:10222000DFF8C4A1DFF8C481714F4FF001093546D2 +:102230001AD0184600F0C2FC6E4906469AF8000013 +:102240000978884210D0FAF733FD68B96A480078F7 +:1022500050B9DBF80000B0F89211B8F808008142DC +:1022600002D287F80B9000E0FD72032006F0A5F97A +:102270006248007888B16248CDF8009062490378DE +:102280006048B0F900200398FFF7D1FD040010D199 +:1022900003990846FFF70CFF0BE0514800950378BF +:1022A0004848B0F90020594801680398FFF7BFFD7E +:1022B0000446032006F09CF934B1FFF788FD88F846 +:1022C0000040012E27D027E0FFF70FFE9AF801000B +:1022D00008B1012100E0002188F80310019988422B +:1022E00002D008B9A8F80650DBF8001091F8E61201 +:1022F000C90708D04649097829B987F8039010B171 +:102300004448FD700570DDE90512119B0398FFF745 +:1023100052FE0446D3E70124204683E610B500F0C0 +:1023200037F8002010BD10B5F5F71EF9FDF709F9D3 +:10233000FAF79AFBFFF738FEFFF7D7FDFCF72BF90A +:102340002A490020087048708880C8804881088128 +:10235000888188700861486188611C3108708870C4 +:102360002048006810F8302F4A704078C87010BDBF +:1023700010B5F5F70AF9FDF7F5F8FAF773FB00F079 +:1023800064FCF3F7F6FB184800214170017110BDA1 +:102390001CB5044600208DF80400022006F00DF95B +:1023A0002046F5F759F806490628CA7860F3030273 +:1023B000CA7031D001283CD002283FD042E0000052 +:1023C000385701203A0710004C071000E2071000B0 +:1023D000AC0710006C0610006806100025071000FE +:1023E00024071000A0071000D8071000B006100046 +:1023F000945A1000350710003207100036071000FD +:10240000370710003C071000BC700120580710006F +:102410007407100030071000022006F0E9F8F2F708 +:10242000BEFC0120F2F70CFC0221012006F025F889 +:1024300008E0FDF785F8FAF765FB03E0FCF7E1FF3C +:10244000FAF773FB01A8002300901A4619462046AC +:10245000FBF7B5FF0446022006F0CAF89DF8040019 +:1024600098B1EDF7CBFF0A490A480A6800680243B1 +:102470000A60EDF7C1FF08480178052002F0F1F885 +:102480004FF48071002005F0F8FF20461CBD0000CD +:10249000AC0710006C06100068061000062904D274 +:1024A0008B4A525C8B498B5C2BB100210160014649 +:1024B000482001F0B6BD864B083353F82230036044 +:1024C000854B43F822000120885470470A4630B4F7 +:1024D0000021062A11D27E4B9A5C72B17C4C0368B3 +:1024E000083454F82240A34207D17A4B99547A4BCE +:1024F00043F82210016030BC70470160014630BCD7 +:10250000492001F08EBD2DE9F0410124714F724E3A +:102510000025385D38B13D5556F824104A2001F0A9 +:1025200080FD46F82450641C032CF2DBBDE8F081EA +:102530002DE9F041684E674C4FF0000C0C36C0F8A6 +:1025400000C0636806F1140704F1080501291DD0D5 +:10255000022902D0032938D128E00022A918B1F8B5 +:1025600000E0BEF1000F07D0521C042AF6DB022B5C +:1025700028D301464C202AE056F82250056047F83F +:10258000220040F2022008809B1E2DE0052101E080 +:102590006A5C12B1491EFBD214E056F82120026099 +:1025A00047F82100012068545B1E1DE00022A91895 +:1025B000D1F800E0BEF1000F0DD0521C022AF6DB6C +:1025C000042BD6D2BCF1000FB0D101464B20BDE8A0 +:1025D000F04101F026BD56F82250056047F8220070 +:1025E0004FF003301B1F086063609FE7F0B40C4698 +:1025F00039490026374D731E05220C3108350AE093 +:1026000051F82270D0F800C0674504D1AF5CA742F2 +:1026100001D1134601E0521EF2D2591C16D02E4AA7 +:1026200000212032016042F82310E954012C06D029 +:10263000022C02D0032C0BD103E0E8184170F0BC4F +:102640007047E81841708170C170F8E7002EF6D12C +:10265000F0BC01464D2001F0E4BC70B51D4D1E4E8E +:102660000524083520360BE0285D48B156F82410C3 +:102670004E2001F0D6FC295D56F82400FFF7B6FF86 +:10268000641EF1D270BD70B50120134A114B0021B8 +:1026900042F820101954401C0328F9DB012018705F +:1026A00005200C4A0C4C0D4B0C3402F1080504F1CA +:1026B0001406506008E07322424303EBC20244F860 +:1026C0002020295446F82010401EF4D270BD00008E +:1026D00020A80100EC061000605A10001C721000C7 +:1026E0002DE9F043FF4B894600211B78012B00D1D7 +:1026F0000121FD4B00271E781CE0B31E994218D023 +:1027000050F82130002593FBF2FC09EB41081446F8 +:1027100008E004FB06F338F91330B3EB0C0300D5E3 +:102720005B421D44641EF4D295FBF2F3BB4200DD14 +:102730001F46491CB142E0DBB7F5803F03DB4FF693 +:10274000FF70BDE8F083B8B2FBE7E848E8490068ED +:102750000A7800F27710805C487170472DE9F14FDC +:10276000DFF888B3DFF888E3DFF888A3DBF8001030 +:102770009EF800C0002591F88F0191F88E113AF86B +:102780001C606FF000444FEA11180A071ED001F0D8 +:102790000F01D64B002291461B68864293F88D713B +:1027A00005DB301A00FB08F090FBF1F00744CF483E +:1027B0009EF80110F0460068012990F8750107D0D5 +:1027C000022908D000F00303484611E00121E0E7A8 +:1027D000C0F38103F8E7C0F30113F5E73AF81010EE +:1027E0008C4201DD0C4605468A4200DA0A46401C4E +:1027F0009842F3DD00980280DBF8000090F8BC0AF4 +:10280000C10604D5C0F341108EF8000006E0301B6D +:10281000B84201DC9C4504DD8EF80050BDE8F84F5D +:1028200093E7BDE8F88F2DE9FF4FB0499A46DDE9FF +:102830000D3609684FF0000E934691F897417246A5 +:10284000F146E4071FD0012B1DD1AB4D00273C46BC +:102850002D783B46AD1C09E016F803C091F898812D +:10286000C44501D9641CE4B25B1CDBB2AB42F3D3B8 +:1028700091F89931A34200D20127A04B83F863401D +:102880000FB14FF001099A4C91F87671A6787B0749 +:1028900005D506B901989A4B1B7803B15046994B60 +:1028A0001B78012B02D1984B1B784BB1B1F88131C9 +:1028B00083421AD291F874311B0716D503222DE0FA +:1028C000B1F88731834203D291F874311B07F5D4F4 +:1028D000B1F88531834203D291F874315B070CD48F +:1028E000B1F88331834214D318E0B1F87F318342C9 +:1028F00005D291F874315B0701D502220EE0B1F8E0 +:102900007D31834205D3B1F89051AAEB0B03AB4262 +:1029100004DD91F874319B0700D50122754D183DF7 +:102920002B789A420CD19E4216D0784A1278012A0E +:10293000AA6801D1521EAA60002A0DDCA3700BE028 +:10294000AAB1022A01D1012B11D091F87B31AB60E1 +:102950002A70002B00DCA2703A0724D5B1F87F3131 +:102960005B450AD2B9F1000F07D0022206E091F8C8 +:102970007C3103EB83035B00E9E700226B789A422A +:1029800009D1E17899420ED0E968491EE960002931 +:1029900009DCE37007E052B191F89511E9606A70C3 +:1029A000002900DCE270E17839B1617007E091F84C +:1029B000961101EB81014900F0E7A2786270544A58 +:1029C0001388834200D210804C4810F8592F61F3CD +:1029D0000302A17861F3071200F8012962780178F7 +:1029E00062F30301017004B07046BDE8F08F3F4A06 +:1029F000126892F87421D20607D5421A002A04DC24 +:102A0000C1EBC1110844C0F3CF107047384910B56D +:102A1000002048708870C8703649344A18394860B8 +:102A2000886008704870126892F83432DB0703D06F +:102A300092F83F22120900E00022364B1A6008612A +:102A400048618861C8614FF49851334807F0A6FD8A +:102A5000BDE810404FF41871304807F0C1BD2DE9B2 +:102A6000F74F0746002084B01F49ADF80800DFF893 +:102A700084A091F8008010214FF6FF7605464FEABA +:102A800008190446AAF1080B009115E0234904FB3C +:102A900008F001EB800043463946009AFFF720FE1C +:102AA0002BF8140053463AF81410FFF7A0FF23F850 +:102AB000140007EB4907641C0E48183880788442DC +:102AC000E4DD02A8FFF74AFEDFF824805F4698F8AD +:102AD00000003AF810403BF81010114804800348F9 +:102AE00000681FE02A07100025071000A00710004B +:102AF000D8071000140710002407100038570120D1 +:102B0000B30610002E0710002F0710002C0710002E +:102B1000B6061000E0061000F82D0120F840012054 +:102B2000B406100090F8750100F00303C0F3011023 +:102B3000834200D80346002009E037F81020B24253 +:102B400000D21646AA4200D91546401C40B298420F +:102B5000F3DD64482B460580DDE90502CDE900027E +:102B600032462046FFF75FFE0546204600F088F813 +:102B700098F8000037F810105B4820F81A1F868775 +:102B8000BAF800200286BAF802204286BAF8042079 +:102B90008286BAF80610C186284607B025E730B508 +:102BA00009E031F9134032F91350641B50F82350F7 +:102BB0002C4440F823405B1EF3D230BD2DE9F74F83 +:102BC00082B0002100914949494A10270C78516888 +:102BD000064691FBF7F307FB1311464861439578CE +:102BE0004FEA041B00EB410800F598594FEA440AEC +:102BF0006D1C10E02346424631464846FFF7CFFFA2 +:102C000052463146404607F04AFC06EB440608EBC4 +:102C10004B0809EB84096D1EECD235494FF0FF32A9 +:102C200002EB47024868401C4860824200DA4F606D +:102C30004868B84202DA009805B0D6E6DDE903122A +:102C40002C48FFF70CFF0090F6E710B52A4C2068DF +:102C500090F87501C0F30112C0F3810100F0030088 +:102C600002F0F9F8224988702068244990F8D200CF +:102C700000F003000870FFF768FDBDE81040C5E6EE +:102C800030B51D491E4D096891F83422D20725D070 +:102C90001A4A52784AB191F83F2202F00F03140900 +:102CA000B1F83A22B1F83C1208E091F83E2202F065 +:102CB0000F031409B1F83622B1F83812904201DC42 +:102CC0002B6030BD884201DB2C6030BD801AE41AD5 +:102CD0006043891A90FBF1F0184400E0002028605E +:102CE00030BD0000B806100038570120250710003D +:102CF000FC061000F82D0120A0071000D8071000D6 +:102D0000E006100070B5FB4DFB4C296891F83100CE +:102D1000207191F83010617100FB01F26283401E56 +:102D2000C21700EB927020F003000830C0B2E075CB +:102D30004843A083F1484079A0710120E0712072DE +:102D4000607260700020E083A072E072E074207511 +:102D5000FFF7E9FA286890F8700C00F0010060763F +:102D6000FEF7CCFEBDE87040F5F7A6BD70B5E24DAC +:102D700000240D21E2482C6207F010FCAC626C626A +:102D8000FFF7F6FAFFF77FFCDE480480BDE87040ED +:102D9000B8E7F0B5DC49D848DE4F91F83020027131 +:102DA00091F8313043715A4314B2448391F833207F +:102DB000827191F82C20427091F82D30C37191F8F6 +:102DC0002E30037291F82F30437291F835308372B0 +:102DD00091F83630C372CD4BC362C94B0E330363D7 +:102DE000CB4B4363C34B1D6895F8BD3ADE070B46DA +:102DF00093F83E3008D0052A06D0062A04D05C435A +:102E000007EB4404846300E087630C68C24EC4632C +:102E10004FF400443480C14E641E34800024C04E00 +:102E20000464062A3480437591F83D30C37091F8EC +:102E30003C30837091F83F30837591F84030C37512 +:102E40000BD191F84100012807D1B64995F87800D7 +:102E500008700A2801D20A200870F0BDAA4810B5EF +:102E600090F82C10A7488170AF49C278097861F3B7 +:102E70000712A149C27002790B7B63F30002CB7B7E +:102E800063F3C3028B7B63F382020B7C63F3410227 +:102E90009B4B1C7B037B64F34103A44C247864F3B9 +:102EA00082030373954B5B7980F849308B7CC37147 +:102EB0004B7C63F304120271CB7C427B097D63F38C +:102EC000030261F307129A494273097880F82710C8 +:102ED00098490988018598490A78817B62F3030142 +:102EE000817396490A78C17B62F30001944A127893 +:102EF00062F3410121F00401C1739249097880F81D +:102F00007F1091490A7890F87D1062F3410180F8B2 +:102F10007D1010BD70B50C4680EA0406F00601D5A0 +:102F2000F2F71AFE764DC4F300102870B00601D5F2 +:102F3000F1F742FF744BC4F34010687093F82C0013 +:102F40000022042811D002280FD0EA702A71C4F39D +:102F50000021297302280CD005280AD06A7204289F +:102F60000CD006280AD0AA7270BDC4F34001E970E3 +:102F7000EDE7596A01B101216972F0E7586A00B1C1 +:102F80000120A87270BD2DE9F0415B4D5E4EA86A2C +:102F9000316A80EA010418B911B1FFF7E7FE0FE0CA +:102FA000E00709D0694F387820B107F0CDFB08B9A8 +:102FB00000203870FFF7B7F9E00601D5FEF7F4FFFF +:102FC000F169286AFFF7A6FFF0692862306AA862F3 +:102FD000706A6862BDE8F041DBE670B55C4D2C6854 +:102FE000002C0DD04449A0B2CA7A897A01F07CF94C +:102FF0002868A043286003D1BDE8704001F0D4B92F +:1030000070BD10B553493C4B0A78997BDC7B21435A +:103010001C7C9B7C2143194328B131B93AB14E48FD +:10302000007810B903E0114301D0012010BD002049 +:1030300010BD3148817BC27B1143027C1143427B2E +:10304000807C1143014301D001207047002070476C +:103050002948807C7047284A1178814207D0254949 +:10306000137E096823B1052381F872301070704710 +:103070000823F9E71CB5FFF779FE1F4C1D4D002012 +:103080002076286890F8E50CC00707D101200023BE +:10309000024600901946052006F0A9FB01AB00226C +:1030A0000B21022005F032FA0198C00711D001214E +:1030B000022005F00EFA286890F8E50CC00703D14D +:1030C000052007F013FB2076207EFFF7C4FF00F0F9 +:1030D00045F80198800705D50221084605F0F9F961 +:1030E00000F074F801980007D8D50821022005F0F7 +:1030F000F0F9D3E7A007100020071000D807100050 +:10310000945A10003857012014841000944901206B +:1031100058430120CC570120720510008005100093 +:103120002E05100091051000E0061000A805100003 +:10313000B1061000BC0610001805100014051000A0 +:103140002905100074071000E8061000FA041000AA +:10315000C8071000B2061000EB0610007FB500246F +:1031600000F04EFF012005F028FAFFF70CFF2E4D6E +:1031700095F82800C0070ED02C48C16890F8373069 +:10318000846B82698DE81E00D0E904234168E86BF6 +:10319000FFF73CF80446686A50B14CB9032005F0CB +:1031A0000CFA2248696AFEF772FD032005F020FA46 +:1031B000FFF754FEFFF711FFFFF74FFAFFF7A3F9F0 +:1031C00004B00120BDE8704005F012BA70B50024CB +:1031D00000F016FF012005F0F0F9FFF7D4FE124DC4 +:1031E00095F82800C00704D010480068FFF796F84B +:1031F0000446686A50B14CB9032005F0DEF90B486B +:10320000696AFEF744FD032005F0F2F9FFF726FE98 +:10321000FFF7E3FEFFF721FAFFF775F9BDE870400D +:10322000012005F0E5B9000020071000148410000B +:103230000D4D00200D4C28602868401C2860EDF7DB +:10324000DDF806F0C2FF0128206808D040F0040035 +:10325000206005F0E4FEEDF7CFF830BFECE720F09A +:1032600004002060F7E700007007100010ED00E098 +:1032700070B5134C25462021114807F08FF91048EE +:1032800000F0B4FC2B78421E691C184600F044F98B +:1032900018B10120216801F0E4F900F0C1FC002818 +:1032A000E9D170BD38B50C46054605F0E6F869462B +:1032B000284605F01CF9009A2242F8D138BD0000DA +:1032C000DE60100000207047034630B40020002963 +:1032D00010DD1A78491E0B2A0CD2864D5B1C55F85E +:1032E000324005EBC2025268914203D1A44630BC81 +:1032F0001846604730BC70470120704710B5017810 +:1033000021B1022906D003290BD106E04078F9F754 +:103310007AFA06E04078012101E040780021F9F7CF +:1033200057FA012010BD0178012908D1724930F8FF +:10333000012F0968A1F8E82C4088A1F8EA0C0120C7 +:103340007047016842686C48CBB20068A0F8023D43 +:10335000C1F30723A0F8043DC1F30743A0F8063DDD +:10336000090EA0F8081DD1B2A0F80A1DC2F307216A +:10337000A0F80C1DC2F30741A0F80E1D110EA0F815 +:10338000101D012070471CB5016800918188ADF8BF +:10339000041082799DF8000058498DF80620E0B3AA +:1033A00055489DF802300068642B01D9642302E07F +:1033B0001BB990F8BB328DF802309DF80330232BF7 +:1033C00000D81BB990F8DE338DF803309DF8043037 +:1033D0009DF80540A34202D80CB10F2B08D990F8F4 +:1033E000773303F00F048DF804401B098DF8053086 +:1033F000022A00D822B990F87B0300098DF8060054 +:1034000000980860BDF8040088809DF80600887167 +:103410003B490868820708D500E008E020F0020078 +:10342000086008210120FFF73DFF01201CBD087046 +:1034300000201CBD10B532490278086812B140F076 +:10344000080001E020F00800086008210120FFF7D3 +:1034500029FF012010BD284910B5096891F8961C74 +:1034600049070AD500782649C207086802D040F407 +:10347000807001E020F48070086008210120FFF7CF +:1034800011FF012010BD70B51E491F4B027809685D +:103490004FF00004CE0118494FF00105096802D52C +:1034A0004AB1032201E032B102221A70407881F859 +:1034B0004606012070BD1D7081F84646F9E7134AA3 +:1034C000007801211170124A08B1117001E000204A +:1034D00010700120704708490078096891F8E51CD0 +:1034E000C90704D00B490A78904200D00870012027 +:1034F0007047000034A80100A007100074071000F6 +:10350000D00710009805100085051000A9051000CF +:10351000A80510003807100030B40C460146002002 +:10352000A1F1A003092B03D8FE4850F8233008E08E +:10353000C0290AD1FB48A1F1C001A0F1040050F854 +:103540002130204630BC1146184730BC704700205F +:10355000704770B50E46F44904460025086838B136 +:1035600000200860F149086004210120FFF79AFE5D +:10357000002E12DD2278711E042A0ED2E948641C46 +:10358000283050F8323000EBC2004068002804DBDD +:10359000814202D1204698470546284670BD10B5A5 +:1035A00000780021820601D5812102E0C00700D009 +:1035B0000121DE48016004210120FFF773FE012094 +:1035C00010BD10B500F0C4FB012010BDD84810B5E7 +:1035D000006890F8500CC00701D000F0B9FB102132 +:1035E0000120FFF75FFE012010BD10B50146002449 +:1035F00009782046102915D005DC49B1012909D0E8 +:10360000022912D10BE011290ED020290DD113E08F +:10361000012412E00224012000F074FA05E00424E1 +:103620000220F9E7082400E01024BF4914F0180F25 +:103630000C6004D0102108E020240020ECE7BB49F6 +:103640000A68824204D0086004210120FFF72AFEA4 +:10365000012010BD034630B40020002911DD1A7886 +:10366000491E052A0DD2AF4D5B1C483555F8324036 +:1036700005EBC2025268914203D1A44630BC184601 +:10368000604762E710B50078AA49C207086802D00F +:1036900040F0020001E020F0020008600821012053 +:1036A000FFF700FE012010BD0120704710B5017822 +:1036B000CB07A0490A6802D042F0080201E022F0DC +:1036C00008020A600078800702D542F0400001E05D +:1036D00022F04000086008210120FFF7E3FD0120EF +:1036E00010BD10B5002103780A469C0601D52021A3 +:1036F00000229C0701D541F002015C0701D541F091 +:1037000004011C0701D541F00801DC0601D541F098 +:1037100010015C0601D541F040011B0601D541F0C6 +:1037200080014378DC0701D041F480719C0701D50A +:1037300041F400715C0701D541F480611C0701D59B +:1037400041F40061DC0601D541F480519C0601D5AD +:1037500041F400515C0601D541F480411B0601D5BE +:1037600041F400418378DC0701D041F480319C07AB +:1037700001D541F400315C0701D541F480211B07DC +:1037800001D541F40021C078C00701D041F080711B +:103790006948C0E90012012010BD002070470346AF +:1037A00030B40020002911DD1A78491E0B2A0DD2F1 +:1037B0005C4D5B1C703555F8324005EBC202526817 +:1037C000914203D1A44630BC18466047BDE601468D +:1037D00000200978072906D25248C83050F8212025 +:1037E000002108461047704710B505F0D4FB0120B2 +:1037F00010BD10B54FF400610020FFF753FD01200C +:1038000010BD10B54FF480510020FFF74BFD012093 +:1038100010BD10B54FF400010020FFF743FD01205B +:1038200010BD10B54FF080610020FFF73BFD012077 +:1038300010BD10B54FF000610020FFF733FD0120EF +:1038400010BD10B50078C00702D000F010FA01E0FA +:1038500000F004FA012010BD10B50188374800249B +:10386000CA07007804D0052802D0062800D0022418 +:103870008A0705D5052801D0062801D144F00404A3 +:10388000480701D544F0080494B1ECF7B7FD2C4883 +:10389000016821430160ECF7AFFD0221052000F033 +:1038A000E0FE4FF480710020FFF7FCFC012010BD0A +:1038B000002010BD10B500880024C10700D00124ED +:1038C000810701D544F00204410701D544F0040406 +:1038D000000701D544F008046CB1ECF78FFD1948DE +:1038E000016821430160ECF787FD02210020FFF70A +:1038F000D9FC012010BD002010BD0020704710B57C +:1039000000880024C10700D00124810701D544F0BC +:103910000204410701D544F00404010701D544F035 +:10392000080411E090A80100D4071000CC07100093 +:10393000A0071000D007100098051000F804100030 +:10394000AC071000B0071000C10601D544F0100408 +:10395000810601D544F02004410601D544F040041D +:10396000010601D544F08004C10501D544F48074FA +:10397000810501D544F40074410501D544F4806407 +:10398000010501D544F40064410401D544F48044A8 +:10399000010401D544F40044C10401D544F4805429 +:1039A000800401D544F400546CB1ECF727FD5A486B +:1039B000016821430160ECF71FFD80210020FFF723 +:1039C00071FC012010BD002010BD10B50078C007AB +:1039D0000ED0ECF713FD5148016841F00101016080 +:1039E000ECF70AFD4FF080710020FFF75BFC01202F +:1039F00010BD10B500880024C10700D00124800745 +:103A000001D544F0020474B1ECF7F8FC44480168B5 +:103A100021430160ECF7F0FC4FF480010020FFF738 +:103A200041FC012010BD002010BD10B5007800241D +:103A3000C10700D00124810701D544F002044007EA +:103A400001D544F0040474B1ECF7D8FC35480168A2 +:103A500021430160ECF7D0FC4FF480610020FFF7B8 +:103A600021FC012010BD002010BD10B500780024FD +:103A7000512841D01CDC172836D00CDC112833D05B +:103A800004DC01282DD0102834D12DE012282BD0B1 +:103A900013282FD128E032282AD004DC302827D060 +:103AA000312827D124E0332822D0502822D123E006 +:103AB000732824D00CDC702821D004DC52281BD0C1 +:103AC000532817D118E0712819D0722812D116E0A6 +:103AD000742814D0752812D0762810D0772809D1F0 +:103AE0000DE000F016FB01E000F0B2FB012401E064 +:103AF00000F0CEFB204610BD00F0B8FBF6E700F06A +:103B000093FCF3E7002118B1012801D0022800D16D +:103B10000121084670470000BC071000C4071000D0 +:103B2000C0071000B80710001C4908B500201C4C45 +:103B300008601C492060086000F0EBFA00F080FD8E +:103B40006B4600221921032004F0E0FC0098C00716 +:103B500005D00121032004F0BCFCFFF789FB00988D +:103B600000070BD50821032004F0B3FC20680821CE +:103B700040F0080020600120FFF794FB0098C00689 +:103B8000DED51021032004F0A4FC2068082120F0D9 +:103B9000080020600120FFF785FBD1E7CC0710006B +:103BA000D0071000D40710001F4800210170417099 +:103BB0008170704710B51C4C0346A078102814D2B1 +:103BC0000F2900D90F211948227800EB02100A466C +:103BD00000F8011B194606F062FC2078401C00F03A +:103BE0000F002070A078401CA07010BD70B50E4C66 +:103BF0000025A17891B10D49627801EB021111F80D +:103C0000015B2A4606F04BFC6078401C00F00F0078 +:103C1000607072B6A078401EA07062B6284670BD73 +:103C200001488078704700007B071000FE6010009C +:103C300010B54FF486714F4806F0D2FC4D49012073 +:103C4000C1F804014C4800214160017006F000FDFC +:103C50000021BDE81040012005F0BCBD10B572B6D2 +:103C600000204549087006F0F3FC62B610BD10B59F +:103C700072B60120404908703E48D0F8080108B1EA +:103C800006F042FD62B610BD10B572B6394B3A4C23 +:103C90001946D3F80821D1F80011491C202A07D26F +:103CA000521C21F02001C3F80821C3F800110FE0D5 +:103CB000D3F8042121F02001521CC3F8001122F096 +:103CC0002001C3F804116168491C6160D3F8001138 +:103CD000026803EBC1010A6040684860207801284F +:103CE00005D1D3F80801012801D106F00DFD62B617 +:103CF00010BD204BD3F8080100280ED0D3F80401E2 +:103D000003EBC000C27922F03F02C27193F8083180 +:103D10005B1E03F03F031A43C271704710B572B6C1 +:103D20001449D1F8080158B1401EC1F80801D1F872 +:103D3000042102F1010222F02002C1F8042105D180 +:103D40000D480078012801D106F082FC62B610BD52 +:103D500010B572B6002007490122C1F80801C1E977 +:103D60004002054948600878012801D106F070FC3E +:103D700062B610BD0C5601208007100010B5064C2D +:103D800000224FF47043228063800449C0E900148C +:103D900002230372427210BD8807100079A9010046 +:103DA00070B5914D2878C1281CD16878A5F1100410 +:103DB000052808D100F0FFF88C480168216081884F +:103DC000A1808079A0716878894908280BD01128D2 +:103DD00008D1086800F54861B0F8E80C2080B1F817 +:103DE0006A00608070BD086890F8021D217090F82C +:103DF000041D617090F8061DA17090F8081DE17017 +:103E000090F80A1D217190F80C1D617190F80E1D3B +:103E1000A17190F8100DE07170BD2DE9F05FDFF831 +:103E2000D481894605464FF0030B4FF0010AA8F1F3 +:103E3000080700263C78072C09D2DFE804F0043399 +:103E400037496A7C8700012D02D0022D1CD081E009 +:103E50005FEA09000CD06449097886290ED009F080 +:103E6000FF016148FFF7A6FE0121032004F005FBD6 +:103E70000020022804D0012804D06BE00220F8E7DB +:103E8000032467E0022465E07878012806D05648CC +:103E90001021103806F082FBFFF782FF88F800A09F +:103EA000012457E0022D43D0002453E0022D11D10C +:103EB000514C4D4879682278103806F0F0FA88F8AD +:103EC00000B02178A8F80410042443E0002440E066 +:103ED000022D02D0012DF9D03CE0FFF70AFF48B1D6 +:103EE000022288F80020A8F802000820A8F80400A0 +:103EF00005242FE07878062804D03B4810380021AC +:103F000001604160082188F800B0A8F80410062478 +:103F100020E0022DB6D17878042809D032484946ED +:103F20001038484410F8012C2F48103806F02EFBAA +:103F300088F800A00EE0022D05D0B9F1080F9FD13E +:103F4000FFF7ECFE9CE7FFF7E9FE01E0022D97D1B9 +:103F500003240126387878703C70002E7FF469AF16 +:103F60002448BDE8F09F2349002208390A704A70AE +:103F7000214A521C4A60214901601B491039818045 +:103F80001031C18010210181704710B5044606F040 +:103F90005FFB1548D4E900121038C0E9001216483A +:103FA0000C3806F0BBFB14480C3805F007FDBDE8E3 +:103FB000104006F0A9BB0D490878002813D14870BD +:103FC0000B48006890F8BB228A7090F8DE23CA7014 +:103FD00090F8772313094B7102F00F020A7190F8E1 +:103FE0007B0300098871704728570120740710006F +:103FF000A0071000940710000C621000CB3D0100D8 +:1040000070B5044D942128462C8806F0E9FA641C0A +:104010002C8070BD38570120334800210160416079 +:104020007047C0B2012200F01EFBFEE7884605463D +:10403000174680212D4806F0D3FA2C4C2C4EA76051 +:10404000C4E900682868206168686061A868A061A8 +:10405000E868E0612869206268696062A869A06216 +:10406000E869E0622348006820632248103800684D +:10407000606320480C380068A0631E480838006858 +:10408000E0631C48001D006820641A48343800684A +:104090006064184814380068A06404F03EFBE667CA +:1040A000C4E9140539464046FFF7BBFF10B5044686 +:1040B000C0B2002200F0D7FA0F480168082903DADD +:1040C000094A5454491C016010BD012806D0022839 +:1040D00008D100221146132000F0C5BA0022114673 +:1040E0001220F9E77047000070EF012080EF0120F7 +:1040F000AF0550FA38ED00E09C071000F648F74A8B +:104100000168914204D1F64902794A7000210160A8 +:104110007047F0B585B04FF4EC61EF4806F060FAF7 +:10412000684605F07DFAEC4C012600276670A780F2 +:10413000A7710220E07104F016FF208104F00FFF48 +:10414000050204F00CFF45EA102060816720208200 +:1041500042F293306082E3480068418AA182018A7A +:10416000E182E149B1F8FA2E2283B1F8F82E628398 +:10417000427D227791F8FC1E6177DC4909684A7C10 +:10418000A27790F89A2002F00102E277019A226267 +:10419000009A6262029AA262DDE9032342EA0322E4 +:1041A000E26282692263C2696263D14A1268A263D1 +:1041B0000368E363CF4BA36490F836301B0706D542 +:1041C000B0F83730A4F85030B0F8393003E0438EFF +:1041D000A4F85030838EA4F8523090F8313084F82F +:1041E000543090F8300084F85500A26591F8320000 +:1041F00024F85C0F91F821006080A780BE48A0845D +:10420000BE48A085BE48E085BE482086BE48608680 +:10421000BE48A086BE48E086BE482087BE4860876C +:10422000BE48A087BE48E087BE48A4F84000AC491D +:10423000BD48A4F842008888401C8880A52204F864 +:104240005C2C04F85B6C24F85A0C0E7005B0F0BDC1 +:1042500070B5A34C05460023A0889F49401C82B23C +:10426000A280284601F0BBFC257070BD70B50546E4 +:104270004FF4EC61984806F0B3F9994C9649A08840 +:10428000401C82B2A280284601F0D6FC257070BD89 +:1042900070B5934C05462078A84204D04FF4EC61E9 +:1042A0008D4806F09DF9A148A5700F2101608A484C +:1042B000894A1030A060942010718A4802F1A40548 +:1042C000E560016891F8310091F83010507100FB01 +:1042D00001F3917105EB43062661D071184405EB9B +:1042E00040006061117270BD2DE9F04104467C4DC3 +:1042F0001746C00704D094227F49A86806F0CFF87B +:10430000784EA00711D5306890F8312090F8300031 +:104310004243A87830282CD031282CD032282CD0F9 +:1043200078495200E86806F0BAF860070ED53068A0 +:1043300090F83120A878302822D0312822D0322895 +:1043400025D074495200286906F0A9F8200729D51C +:10435000306890F83020A87830281AD031281AD048 +:1043600032281DD06F496869BDE8F041520006F05F +:1043700096B86249D5E76249D3E76D480168D0E74E +:104380006249DFE76249002FDCD06A49DAE7624917 +:10439000D8E76249E7E76249002FE4D06649E2E7DF +:1043A0006149E0E7BDE8F0814B4A4D49A520107016 +:1043B0008878507008708888401C888050807047CA +:1043C0003EB50C4600218DF800104FF4832502AB5A +:1043D0006A4601A900F0D8F89DF8080010B111282C +:1043E00016D01AE09DF80010B9B10198617105EB83 +:1043F000800304F1100019788A0703D001F0FC0152 +:10440000083100E0091DCAB2194606F048F83EBD61 +:10441000322000222071114603E03020002220715A +:10442000114600F020F93EBD70B505464FF4C87145 +:10443000294806F0D5F82A4C2749A088401CA080BE +:104440002846FFF7BDFF24492570A52008704D7050 +:10445000A088488070BD2DE9F84F884605460C4677 +:104460000E1D00239B220421404600F04FFE90BB0E +:10447000A078A8422FD1217800239B22304600F05B +:1044800045FE6178884279D1207881070AD00222DE +:1044900002EB9005002101E03154401CB0EB850F88 +:1044A000FAD302E0012101EB90050024DFF828B0E7 +:1044B0004FF48326A1464FF0330A56F8240006EB4A +:1044C0008407401C3BD000239B220421384600F087 +:1044D0001DFE98B349E051E0000001204B435546D2 +:1044E000E4071000A007100074770120A407100053 +:1044F000F0FF01001C01020138570120948B0120BC +:104500005843012094490120CC570120F88801200C +:104510006C0B0120580C0120F87601202289012023 +:10452000960B0120820C012022770120C807100081 +:1045300058071000020A01202C0A012001E0009413 +:104540000CE03878810704EB900401D0A41C00E053 +:10455000641C602CB1D3B9F1000F06D02946404647 +:10456000009A04F034FE00280CD000228BF804A03E +:1045700011463320BDE8F84F00F075B8002211460F +:104580003120F7E7BDE8F88F2DE9FF5F4FF0000B12 +:10459000C1F800B01F46924688464FF48325D9469D +:1045A0005C4683F800B055F8240005EB8406401CF7 +:1045B00022D000239B220421304600F0A7FD20B129 +:1045C000122038704FF0010B1CE0B278009930785F +:1045D0008A4208D19AF800104FF00109491C8AF864 +:1045E0000010C8F80040810704EB900401D0A41C1F +:1045F00000E0641C602CD6D3BBF1000F02D1B9F1EE +:10460000010F0BD05BEA090006D1112038700020A1 +:104610008AF80000C8F80000BDE8FF9FD8F8000045 +:10462000002305EB8004201D21789B2200F06EFD05 +:104630006178884201D1002000E012203870EBE759 +:1046400000F018B800F020B81CB50446012301AAF8 +:104650006946183000F0A2FF2046009900F032F8B9 +:104660001CBD00F08FB800F0BDB800F0CDB800F070 +:10467000D4B800001CB57448D0E90010CDE9001092 +:104680006846FFF701FB1CBD1CB56F49D1E902214B +:10469000CDE9002130F8481F090A8DF80210017891 +:1046A0008DF803104188090A8DF8041081788DF87F +:1046B00005100079C0F1FF008DF806006846FFF78D +:1046C000E3FA1CBD1CB5604AD2E90432CDE90032E0 +:1046D00090F8C621032A1CD0082A20D00B2A1ED00D +:1046E0009DF8002022F0F00220328DF8002090F892 +:1046F000C72102F00F02012A17D0022A1BD0042A78 +:1047000038D0052A9DF8012022F00F0238D0521C23 +:1047100016E09DF8002022F0F0021032E5E79DF847 +:10472000002022F0F0023032DFE79DF8012022F075 +:104730000F02921C04E09DF8012022F00F02D21C0F +:104740008DF8012090F80E02D2B260F307128DF8B6 +:104750000120BDF802000A0C62F30B00ADF8020064 +:10476000BDF8030061F30F10ADF803006846FFF7D2 +:104770008BFA1CBD9DF8012022F00F02121DDFE70D +:10478000521DDDE71CB5314A0023126892F89A20C9 +:1047900094070ED50B2816D2DFE800F0150617088F +:1047A000170C171715171700120600E0D206002A7B +:1047B0000BDB1CBD520608D5254A1278052AF8D015 +:1047C000062AF6D001E0002BF3D01F4AD2E90832C6 +:1047D000CDE900328DF80100CDF802106846FFF7F0 +:1047E00053FA1CBD1CB5184BD3E90A43CDE900436D +:1047F0008DF80100CDF80210684612B1FFF7C5FB35 +:104800001CBDFFF741FA1CBD1CB501680091406852 +:1048100001906846FFF738FA1CBD1CB541780029A5 +:1048200010D005290ED20849D1E90E21CDE9002189 +:10483000D0F80210CDF80210C088ADF80600684626 +:10484000FFF722FA1CBD000084A90100A007100098 +:10485000F80410002DE9FF4103F05AFD224D002419 +:10486000C4EBC40105EB810000F10C02037EC4CA55 +:1048700003938DE8C400D0E9012355F821000021FD +:1048800003F0F0FE18B121464320FFF7CAFB641C79 +:10489000052CE5DB144D00248C3505EBC40000210C +:1048A000426855F8340003F064FE18B121464420F4 +:1048B000FFF7B7FB641C062CEFDB0B4D0024BC3567 +:1048C000002155F8240003F0BAFD18B12146452017 +:1048D000FFF7A7FB641C042CF2DBBDE8FF81014657 +:1048E0004620FFF79EBB0000C4A9010000F01F0393 +:1048F00001229A4043099B0003F1E023C3F8802280 +:104900004907090E002806DA00F00F0000F1E02048 +:1049100080F8141D03E000F1E02080F80014C3F8D3 +:10492000002170472DE9F05FDFF80CB464240726FE +:10493000DBF800000027DFF8FC8390F8CC004FEA9A +:104940005009FE4804F00CFEFC4ADFF8F4A3FD4DCC +:1049500011688AF8001050688AF80100CB1C26D034 +:10496000C31C24D0936813F1030F20D0126912F1F5 +:10497000030F1CD0B1F1FF3F20D011F1020F1DD069 +:10498000B0F1FF3F1AD010F1020F17D0B3F1FF3F83 +:1049900014D013F1020F11D0B2F1FF3F0ED012F17B +:1049A000020F0BD0CCB2C6B2DFB2904617E0286837 +:1049B000807F5A280ED00021242005E02868807FBF +:1049C0005A2807D000212520FFF770FB2868807F38 +:1049D0005A2804D128680727C47F90F82060DBF8A4 +:1049E000000090F8CC00C00702D004EB0900C4B26C +:1049F0000D34E0B2761CF1B28AF802008AF8031096 +:104A00003A4604F0D5FA404604F0DFFACE4804F006 +:104A100066FDCD4C032807D001280DD002280BD00D +:104A20002168012912D014E0286890F821005A2842 +:104A300014D00021292006E0286890F821005A2887 +:104A40000CD000212A20FFF731FB02E0201D03F0EB +:104A5000AAFE286890F821005A2812D1022121606C +:104A6000DBF8001091F88D16890703D59821201DD9 +:104A700005F0B6FDB448296810229C30223105F0BB +:104A80000EFD201DBDE8F05F03F08DBEF8B50E46AB +:104A9000054600246A4604F013FB012801D00124D6 +:104AA0000BE0306829468200A84805F03DFDA74884 +:104AB00004F019FB012800D002242046F8BDF8B507 +:104AC000A24EA34F10364FF47061A24805F088FD46 +:104AD00069463846FFF7DAFF012805D0022806D0DC +:104AE000F07801280AD105E00021A02028E000216B +:104AF000A12025E0B07808B9308810B10021A220AB +:104B00001EE09448F1880024A0F8F81EB188A0F8AF +:104B1000FA1E317A80F8FC1E0098694607EB800780 +:104B20003846FFF7B3FF70B1012803D00021A6205B +:104B3000FFF7BCFAE00723D0A00723D41121A72058 +:104B4000FFF7B4FAF8BD75783146284601F008F849 +:104B500050B1102D0BD0112D0CD0122D0DD0132DC6 +:104B6000DAD144F01004D7E72946A820E0E744F062 +:104B70000104D1E744F00204CEE744F00804CBE797 +:104B80001021DCE720070BD46B48006890F8001276 +:104B9000C90703D190F8BA00C00701D01221CEE7AF +:104BA000E006CFD41321CAE710B58EB0EBF726FC90 +:104BB0000020012341B201F01F0403FA04F2490965 +:104BC000890001F1E021C1F88021401C1F28F1DBA0 +:104BD000EBF712FC04F098F9FFF790FA04F078FD77 +:104BE00007210A20FFF782FE07210B20FFF77EFE38 +:104BF000FFF71EF8FEF7D8FF04A8FFF7B4F907A8DF +:104C0000FFF7BCF804A8009007A802900AA8039038 +:104C1000684604F06FFF02210020FFF767FE05F0F1 +:104C200079FD0078C00701D1FFF721F8FFF7F4F90B +:104C300004F0B6F9484C01AA6946204604F040FA4F +:104C4000012802D00021202012E00098A0F5407237 +:104C5000523AF7D12146384C40F64852206805F0C8 +:104C60001EFC206804F03FFA012803D00021212017 +:104C7000FFF7D7F900F024F8FFF754FEFFF71FFF06 +:104C800000F044F803F0D6F803F062FD002301229F +:104C90001946052005F07CFA00231A46012106205A +:104CA00005F076FA03210120FFF720FE04210720FA +:104CB000FFF71CFE0EB00421BDE81040082015E6E9 +:104CC0007CB5264E01AA6946304604F0F9F91D4C20 +:104CD0004FF48055012803D10098B0F5806F02D0C1 +:104CE000002122200BE02A463146206805F0D7FB40 +:104CF000206804F0F8F9012807D000212320FFF7ED +:104D0000D5F92946206805F049FC7CBD10B504F0B2 +:104D1000A5FF002301221946184605F039FA0023A1 +:104D200001221946104605F033FA002301211A46E4 +:104D3000022015E00090D003A0071000D8961000C4 +:104D40006E770120A4071000909C10001C721000C8 +:104D5000F0CF010074770120F0EF0100F0BF0100F7 +:104D600005F016FA00231A460121032005F010FA77 +:104D700000231A460121042005F00AFA16480068AB +:104D8000017CA52908D04FF4FA4005F0EBF9002189 +:104D90002820FFF78BF902E0406905F0E3F90421D0 +:104DA0000220FFF7A3FD04210320FFF79FFD04214C +:104DB0000846FFF79BFD04210520FFF797FD04211E +:104DC0000620FFF793FD01210920FFF78FFD042145 +:104DD000BDE810400F2089E5A4071000F0B5054696 +:104DE00000200C46014603464FF0804203E09B083A +:104DF00043EA82739208EE1A74EB0206F7D318E0C6 +:104E0000C71841EB0206B5EB070C74EB060C07D391 +:104E1000ED1B64EB0604DF1842EB02063818714103 +:104E20004FEA9303490843EA82734FEA30004FEA9E +:104E3000920253EA0206E3D1421B71EB040202D252 +:104E4000401C41F10001F0BD884200D30846904269 +:104E500000D310467047884200D80846904200D8D8 +:104E600010467047884200D308467047884200D8F1 +:104E700008467047884200DB08467047884200DCDD +:104E800008467047024600204FF0804100E0890844 +:104E90009142FCD807E04318934202D8D21A00EBA3 +:104EA0004100400889080029F5D1824200D9401C00 +:104EB000704710B55A43029C05E050F8223093FB2E +:104EC000F4F341F82230521EF7D210BD10B55A4308 +:104ED000029C04E050F82230634341F82230521E15 +:104EE000F8D210BD2DE9F04F8246DDE90906DDF864 +:104EF00034E08B46824225D1002421E004FB02F0FD +:104F00000AEB80090B9D04FB0EF0002105EB8005E8 +:104F100013E000200EE000FB06F803EB880859F8C8 +:104F200020C055F8217058F82180401C0CFB0877F0 +:104F300045F821709042EEDB491CB142E9DB641C6C +:104F40005C45DBDBBDE8F08F30B5039C634306E0D6 +:104F500050F8234051F823502C4442F823405B1E64 +:104F6000F6D230BD30B5039C634306E050F82340D1 +:104F700051F82350641B42F823405B1EF6D230BD2B +:104F800010B500231C4642B10278521CD2B2027006 +:104F90008A4203D90470012300E00470184610BD52 +:104FA00030B50024012305E00C44E41C04F00305A3 +:104FB000641B5B1C9342F7DD00EB440030BDF0B591 +:104FC000851ADDE905471E1B75438E1A012F02D095 +:104FD000904206DD0BE0904201DC1846F0BD8842AD +:104FE00001DB2046F0BD95FBF6F0181AF0BD8842B3 +:104FF000F3DA95FBF6F02044F0BD2DE9F047994631 +:1050000090461DE0051800F00106354341EB010410 +:1050100002464E0815400C404FEA3007A9F1010244 +:105020004FF001004FF0000105F0EFF900EA050232 +:1050300001EA040347EA020046EA0301284021404E +:10504000B8F10108DED2BDE8F0872DE9F047002471 +:105050001746884681461E4625465A1E012021468F +:1050600005F0D3F90BE039F91620424504DA3A4449 +:10507000002A01DD04430D4349084FEA3000761E43 +:10508000F1D220462946DEE72DE9F047844600208C +:1050900092468946014601260746024621E03CF930 +:1050A00012504D451ADA0CEB4208B8F902402C1B9D +:1050B00000D5644238F9028C24B2B5EB080500D55E +:1050C0006D422DB232B1A3F10108424501D0A54293 +:1050D00000DD2C46544501DA30433943B6197F418F +:1050E000521C9A42DBDBAEE770B50CE006180346B3 +:1050F00041EB01051E430D4349084FEA300040EAE9 +:10510000060041EA0501521EF0D270BD70B5054699 +:10511000184600240EE02B5D58400823060602D5F1 +:1051200082EA400000E040005B1EC0B213F0FF03C3 +:10513000F4D1641C8C42EED370BD30B507E0041886 +:1051400000F001031C4341EB010520402940521EA1 +:10515000F5D230BD2DE9F04700248246A6B0501E9E +:1051600000F0FF0C234620466E460DF14C0912E07C +:1051700031F910502C44451C2F4694FBF5F526F8C8 +:105180001050ACEB0005401C31F91580434493FBF3 +:10519000F7F729F815709042EADB4B460AE036F93A +:1051A000120033F91240204431F81240A4EB6000A1 +:1051B0002AF81200521EF2D226B044E72DE9F04739 +:1051C0000026914607468846344635460FE041465C +:1051D0002A46384605F02CF9C00705D0641CE4B215 +:1051E000A64202D2264600E000246D1CEDB24D45D9 +:1051F000EDD3304627E7F0B5DFF888C000220CEB8E +:10520000C2034FF0FF34C3E90044521C1A2AF6DBF4 +:10521000DFF874E00022DEF8004009E000EBC20392 +:10522000D3E900568B180CEBC303521CC3E900569C +:1052300094F831309342F1DC002314E04FF0FF3456 +:105240002546002207E09E180CEBC607D7E9006749 +:1052500034403D40521CB2EB410FF4DD00EBC30281 +:105260005B1CC2E90045DEF8002092F831209A422A +:10527000E4DCF0BDC2F58073504301FB0300001273 +:1052800070470000F0961000A00710002DE9F047CD +:10529000D0F810C00568046A85FB0C12A1FB0461FC +:1052A00041694368894683FB01128269E246A1FB9A +:1052B00002178E19D0E9021781FB07C8C069ACFB41 +:1052C00000C81CEB060682FB0A2CA2FB012180FB16 +:1052D0000901A0FB0501801884FB0712A1FB031242 +:1052E0000818301A4FEAE071BDE8F08770B542F255 +:1052F0001074049D521AED1A654395FBF2F2514366 +:1053000091FBF4F1591A424392FBF4F0084470BD4A +:105310002DE9FF4F83B01146DDE91278D1E900068F +:105320001D46D1E902238218D1E904015E4183467A +:1053300010180091002471413A46434605F08BF85D +:105340000646D5E90203D5E9001C0A18D5E904018F +:105350004CEB030C8246101889464CEB01013A468F +:10536000434605F078F8054658463A4643460099C4 +:1053700005F071F8C21783460192504649463A46F5 +:10538000434605F068F8C3170093BBEB060180465F +:105390001498019AA1FB007C4FEAE67962EB0902BE +:1053A00002FB00C0A34601FB0B0102225B4638460C +:1053B00005F051F8871941EB0909B8EB050114987C +:1053C000009BA1FB00C84FEAE57A63EB0A0303FBED +:1053D000008001FB0B0102220023604605F03BF830 +:1053E000401941EB0A08BB49A44663460968BCEB77 +:1053F000070C42F2107A73EB090307DA4A8E521E49 +:105400004FEAE27CBA1A79EB0C0313DB4FF0000C85 +:105410006346BCEB070C73EB090301DA4C8E641E88 +:10542000CDE9000A2B4631463A462046FFF75EFF9B +:10543000274623E04FF0000C62464346BCEB000CCD +:105440009A4107DA8A8E521E4FEAE27C821A73EB87 +:105450000C0313DB4FF0000C6346BCEB000C73EB4A +:10546000080301DA8C8E641ECDE9007A02463346C9 +:1054700029462046FFF73AFF0746204603994F602A +:105480000399086007B0BDE8F08F30B5B0F902406D +:10549000B1F90250641B00D56442B0F90000B1F9C3 +:1054A0000010401A00D54042944203DA984201DAD3 +:1054B000012030BD002030BD884201DD0846704724 +:1054C0000028FCDA0020704710B504E000EB8203EE +:1054D00053F8044C1C60521EF8D10968016010BDDD +:1054E00010B503E000EB82030C681C60521EF9D279 +:1054F00010BD30B505E000EBC20373E90245C3E916 +:105500000245521EF7D1D1E90021C0E9002130BD8A +:1055100010B553884C881B1B438012880988511A88 +:10552000018010BD08B50A4601466846FFF7F0FF46 +:10553000BDF90010BDF90200494300FB001008BD91 +:1055400010B58842029C01DC204610BD904201DB70 +:10555000184610BD8A4200D1521C401AE31A584323 +:10556000511A90FBF1F0201A10BD10B5002A03D09B +:10557000431A934201DD881810BD5442A342FBDA5E +:10558000881A10BD914201D100B270475043B0FB60 +:10559000F1F000B29042F7D91046F5E7F0B50C00F3 +:1055A00002463FD04B4F3868468E858EB2F90200D6 +:1055B00031B2FFF781FF6080B2F9000029B2FFF736 +:1055C0007BFF2080396891F83610490702D5618841 +:1055D000711A6180396891F83610890701D5281A47 +:1055E0002080386890F83610090712D5012B10D1A9 +:1055F000B0F83720B4F902003146FFF7C3FF6080EE +:1056000038682946B0F83920B4F90000FFF7BAFF2E +:105610002080386890F83600C00703D06088218861 +:1056200061802080F0BD2B490968B1F93220B1F9C1 +:10563000343091F8361062F31F4063F30F00C9074E +:1056400003D063F31F4062F30F00704770B50B0087 +:1056500002463DD01F4EB2F9020031684D8E8C8E4D +:1056600029B2FFF729FF5880B2F9000021B2FFF7F5 +:1056700023FF1880316891F83610490702D5598800 +:10568000691A5980316891F83610890701D5201AB6 +:105690001880306890F83610090710D5B0F8372018 +:1056A000B3F902002946FFF76DFF588030682146A4 +:1056B000B0F83920B3F90000FFF764FF18803068B4 +:1056C00090F83600C00703D0588819885980188090 +:1056D00070BD0000A007100073B51D24DDE9005661 +:1056E00022460120002104F090FE2840314008436A +:1056F00001D1641EF4D50821684603F0CFFCFF49B0 +:10570000C0B2096891F8CE10C1F3411102290ED33D +:1057100010F0030005D0012805D0022805D01F2075 +:105720000AE00F2008E07F2006E03F2004E0C007E9 +:1057300001D0072000E003200021621C04F065FE78 +:10574000DDE9002310431943CDE900017CBD10B50C +:10575000EB4C502814D008DC102811D0112825D08B +:10576000122823D0132806D120E051281ED0522819 +:105770001CD053281AD00020C4E9020001461BE0C7 +:1057800002F0E3FBC4E9020102F0E1FBC4E9040119 +:10579000DA48006890F8CE0010F0600F0ED0D4E91F +:1057A0000201FFF799FFC4E9020107E002F0CDFB17 +:1057B000C4E9020102F0CBFBC4E90401D04808218E +:1057C000083003F06BFC2060CD480821103003F056 +:1057D00065FC606010BD2DE9FF5F82B011AC08214F +:1057E00094E8000E02A803F059FC0090082104A8D8 +:1057F00003F054FC0746002528463BE042460120C2 +:10580000002104F002FEDDE90223104019400843A4 +:105810002ED00024264628E032460120002104F044 +:10582000F4FDDDE904231040194008431CD0BBF10E +:10583000000F0CD005FB07F009EB0401415632467E +:1058400001EB0A032946109803F06BF80BE032468F +:105850002946109803F05AF8A0EB0A0105FB07F05F +:1058600009EB04028154641C761CBC42D4DB6D1C21 +:1058700008F10100804600988542BFDB06B0BDE814 +:10588000F09F2DE9FF5F84B00821DDE9134B04A8E8 +:1058900003F004FC0746082106A803F0FFFB80463E +:1058A00012980026483002901298354668300190D0 +:1058B0001298B2462030B146009032E052460120A4 +:1058C000002104F0A2FDDDE9042310401940084343 +:1058D00023D0169880B1A15D01EB0B00C2B25146F6 +:1058E000029803F08AF8F11901EB0800225651469C +:1058F000129803F05AF80EE05146029803F07BF834 +:10590000A0EB0B00A0555146129803F047F8F2198E +:1059100002EB08016054761CF6B20AF1010000F0B7 +:10592000FF0ABE42CADB36E04A460120002104F0ED +:105930006CFDDDE9062310401940084327D0169876 +:1059400090B1E819215C15980844C2B24946019803 +:1059500003F053F805EB470101EB080022564946D6 +:10596000009803F022F810E04946019803F043F84C +:105970001599401AE91960544946009803F00EF849 +:1059800005EB470202EB080160546D1CEDB209F112 +:10599000010000F0FF094545C6DB08B06FE72DE9BF +:1059A000FF5F0821DDE90EB9684603F077FB824608 +:1059B000082102A803F072FB00268046374628E043 +:1059C0003A460120002104F020FDDDE900231040CB +:1059D000194008431CD00024254616E02A46012021 +:1059E000002104F012FDDDE90223104019400843B4 +:1059F0000AD02A463146584602F088FF06FB084284 +:105A0000800029F81200641C6D1C4445E6DB761CFE +:105A10007F1C5645D4DBBDE8FF9F2DE9FF5F0821C1 +:105A2000DDE90E48684603F039FB0746082102A865 +:105A300003F034FB002683463546B246B14641E0CA +:105A400052460120002104F0E0FCDDE90023104073 +:105A50001940084332D0514604F1480002F0CBFF10 +:105A60000246264894F89230006890F8111190F898 +:105A7000100101F00F0C0CF1010C03FB0CF34FF0C3 +:105A8000010C0CEB111102FB013194F890200CEB8E +:105A9000101002FB0010109919B94FF6FF7101EABE +:105AA000800028F816005146204602F077FFF219D0 +:105AB00080005A44761C28F81200F6B20AF1010060 +:105AC00000F0FF0ABE42BBDB47E04A46012000214E +:105AD00004F09BFCDDE9022310401940084338D054 +:105AE000494604F1680002F086FF0246034894F834 +:105AF0009360006890F8131104E00000A007100004 +:105B00000008100001F00F035B1C5E43012303EB50 +:105B1000111102FB016190F8120194F8912003EB3E +:105B2000101002FB0010109919B94FF6FF7101EA2D +:105B30008000EA19494628F8120004F1200002F01A +:105B40002DFF05EB470280005A446D1C28F8120017 +:105B5000EDB209F1010000F0FF095D45B5DB5AE740 +:105B60007FB50D4604460026FFF7F1FD0122F849F6 +:105B700005F11000102C06D0112C0FD0122C23D0C0 +:105B8000132C29D124E02B790C68A3420ED16B7918 +:105B90004C68A3420AD10023EE4C0BE02B790C6831 +:105BA000A34203D16B794C68A34201D0002613E0D5 +:105BB000E94C002300940392CDE9010308310FC999 +:105BC000FFF709FE012607E0284600F083F802E00F +:105BD000284600F0B8F80646304604B070BD2DE9FE +:105BE000F0411E461746884604460025FFF7AFFDE4 +:105BF000102C06D0112C0AD0122C11D0132C0CD141 +:105C000014E032463946404600F0D6F804E0324609 +:105C10003946404600F0F4F805462846BDE8F081D4 +:105C200032463946404600F00FF9F5E7324639462C +:105C3000404600F04BF9EFE72DE9FF4117460C46CF +:105C40000646FFF784FDC24804F11005502E017886 +:105C500021710179617107D0512E07D0BF49522EB1 +:105C60000FD0532E30D119E0BA4900E0BA49CDE93E +:105C7000001585680C3090E80E002846FFF78FFE6F +:105C800022E00968B64B91F8042191F8101102F056 +:105C9000010201F00101CDE902120CE00968B04BEC +:105CA00091F8292691F8351602F0010201F0010160 +:105CB000CDE902129833CDE9003585680C3090E8C3 +:105CC0000E002846FFF7A9FEA520207066706780A9 +:105CD000BDE8FF8130B59E4C017987B022689142C2 +:105CE00003D141796268914202D0002007B030BDF3 +:105CF00098498579002281F8825BC57981F8835BB8 +:105D0000857A81F8845BC57A81F8855B057B81F8AB +:105D1000805B457B81F8815B9049012513460968CA +:105D20001030083491F8041101F00101CDE904515B +:105D30008B4901AD009185E80D0094E80F00FFF755 +:105D4000A0FD0120D2E730B5814C017987B02268EF +:105D5000914203D141796268914201D00020C5E7A8 +:105D60007C498579002281F81A5CC57981F81B5C31 +:105D7000857A81F81C5CC57A81F81D5C057B81F809 +:105D8000185C457B81F8195C744901251346096844 +:105D90001030083491F8291601F00101CDE90451C1 +:105DA0006F4901AD9831009185E80D0094E80F002E +:105DB000FFF767FD012099E77FB50E46044640F2E4 +:105DC0007A3104F0EBFB624D624A04F1100128784D +:105DD00020712879607100200092CDE9011005F151 +:105DE000080103900FC9FFF7F6FCA52020701020D2 +:105DF00060706680D5E90001484313308008ECE606 +:105E00007FB50E46044640F27A3104F0C7FB504D90 +:105E1000514A04F11001287820712879607100201E +:105E20000092CDE9011005F1080103900FC9FFF7B9 +:105E3000D2FCA5202070112060706680D5E9000199 +:105E4000484313308008C8E670B50E4686B0044655 +:105E5000FC2104F0A3FB3E4D287820712879607165 +:105E60003C4890F8821BA17190F8831BE17190F877 +:105E7000841BA17290F8851BE17290F8801B21733E +:105E800090F8810B60733548006890F8040100F0C9 +:105E900001010020CDE904010290039004F11000FB +:105EA0002F49CDE9001005F108010FC9FFF7E9FC02 +:105EB000A5202070122060706680D5E9000108449A +:105EC000132101EB4000800806B070BD70B50E468E +:105ED00086B00446FC2104F061FB1D4D287820713A +:105EE000287960711B4890F81A1CA17190F81B1C4E +:105EF000E17190F81C1CA17290F81D1CE17290F8E1 +:105F0000181C217390F8190C60731448006890F8FD +:105F1000290600F001010020CDE90401104902909A +:105F2000039004F110009831CDE9001005F108014B +:105F30000FC9FFF7A6FCA5202070132060706680B3 +:105F4000D5E90012114400EB41008008BCE70000D5 +:105F500000081000747701209C7C0120A00710002D +:105F60006482012030B506E032F8134031F8135056 +:105F7000641B20F813405B1EF6D230BDF0B4049CC5 +:105F80001CB913B1C3F110050DE0F0BC520004F0D0 +:105F900086BA30F9124031F912605C4306FB0544C1 +:105FA000241120F81240521EF3D2F0BC7047F0B416 +:105FB000049C1CB913B1C3F180050DE0F0BC520084 +:105FC00004F06DBA30F9124031F912605C4306FBFF +:105FD0000544E41120F81240521EF3D2E5E70346CF +:105FE000B0F9000004E033F91120824200DD1046D0 +:105FF000491EF8D2704710B5002447F6FF7307E03A +:1060000030F91120A24200DD14469A4200DA13460C +:10601000491EF5D2E01A00B210BD2DE9F047164630 +:10602000DDE90878894604460025DFF884A227E0E8 +:106030002A460120002104F0E8F9384001EA08016D +:1060400008431AD00020524615E0136834F91010A6 +:1060500093F85F32594341F3CF1124F8101000290F +:1060600000DA49421368B3F87332994202DD012025 +:10607000BDE8F087401CB042E7DB04EB46046D1C32 +:106080004D45D5DB0020F3E72DE9F04F47F6FF76CD +:10609000DDE909B5F4439A4601278146BC462B4603 +:1060A00014E032F8130031F81380A0EB080000B2BE +:1060B000B04200DA0646A04200DD0446002802DDB8 +:1060C0004FF0000C02E001DA4FF000075B1EE8D24F +:1060D00027B1BCF1000F01D0002009E057EA0C0005 +:1060E00006D027B9BCF1000F01D0204600E03046B1 +:1060F00000231E462C46CBF1000C0DE032F8147044 +:1061000031F81480A7EB08073F1A3FB2574503DA6E +:10611000674501DD3B44761C641EEFD206B90126BB +:1061200093FBF6F2131804E031F81500184429F82F +:1061300015006D1EF8D2BDE8F08F2DE9FF4F5C48C9 +:106140008A465C49006891460978B0F832C085B04B +:10615000BCFBF1F2584C818E03912478B1FBF4F131 +:10616000564CB4F91A60B4F9185096FBF2F6F7B22F +:10617000B4F91060B4F9124095FBF2F596FBF1F614 +:1061800094FBF1F4EDB2F6B2E4B21BB990F8703CB6 +:106190009B0659D5B0F8023DACEB030393FBF2F339 +:1061A0001BB20293B0F8043DB3FBF1F31BB20093B2 +:1061B000B0F8063DB3FBF2F30FFA83F8B0F8083DF0 +:1061C000B3FBF1F31BB20193B0F80A3DACEB030350 +:1061D00093FBF2F30FFA83FEB0F80CCD039BA3EB15 +:1061E0000C0393FBF1F30FFA83FBB0F80E3DB0F80C +:1061F000100DB3FBF2F2039B12B2181A90FBF1F0F0 +:1062000003B2904501DB404600E010460299724619 +:10621000714500DC0A46DDE9001C614500DA614693 +:10622000DC469B4500DB6346854200DB2846C5B261 +:10623000974200DC3A46D7B28E4200DB3146CEB2FE +:106240009C4200DC2346DCB20021059804F0B6FA3B +:106250001949002291F800B025E0164B002193F86F +:1062600000C01AE0B24205DDA24203DAA94201DD14 +:10627000B94208DB30F91130B9F9008043450ADD35 +:10628000A9F8003007E030F91130BAF90080434531 +:1062900001DDAAF80030491C09B26145E2DB521C5D +:1062A00000EB4C0012B25A45D7DB09B043E70000BF +:1062B000A00710002507100024071000442010003C +:1062C00070B5050003D0BDE8704001F01CBEFE4C67 +:1062D000204662780179012A16D0022A1BD0207844 +:1062E00001F0CAFE21794A00F84901EB4001F74864 +:1062F000983004F0D4F8A078F54E78B1F3482179BD +:10630000983001F0B2FE0BE00A46F04901F1980026 +:1063100001F028FEEFE74A00EC49E8E7EB48983047 +:106320003063E07886F839002846CCE7E94901284F +:10633000096808D0022809D003280AD004280BD005 +:1063400091F83A0C704791F83B0C704791F83C0C6F +:10635000704791F83D0C704791F83E0C7047F8B5C6 +:10636000044602F00EFAD94802F010FAA4F87600BA +:1063700001F01EFED44A0B461278009202462046D7 +:1063800002F00CFD01F019FE02460B46204602F019 +:106390003BFD204601F076FECE4DB4F8561028683D +:1063A000B0F88E2062F30901A4F8561090F88D0021 +:1063B00094F8551060F3030184F855100521204628 +:1063C00002F00FFA286890F83906A0702868218E2C +:1063D000B0F83F2662F30801218690F83A0600F0F3 +:1063E0000F01204602F074FA286834F81A1FB0F83A +:1063F000312662F30B0124F81419B0F82F266189B5 +:1064000062F30B016181B0F82D16E08861F30B0097 +:10641000E08014F8050C20F00C0004F8050C286846 +:1064200090F83B160A09217B62F30101217390F871 +:106430003B26920962F38711217390F82716627840 +:1064400061F30002627090F82A06E070A24890F8AA +:10645000181C217690F8191CA17790F81A1C617607 +:1064600090F81B1CE17790F81C1CA17690F81D0C8D +:1064700084F82000994802F089F9A4F87A00974836 +:10648000203002F083F9A4F87E00286890F83516D1 +:106490000A0914F8161F62F3071104F8061B90F896 +:1064A00037261309227863F30712227090F83666B4 +:1064B00014F8053C66F3030304F8053C90F83876BD +:1064C000667867F30306667090F836763F0967F3DF +:1064D000071304F8053C90F838361B0963F30716D8 +:1064E000667090F8353663F3000104F8061C90F8E6 +:1064F000371661F3000204F8222990F82B060109EF +:10650000204602F0F1F97548483802F03FF9A4F846 +:106510007E0072482734283802F038F9A4F85B006E +:10652000286890F829168A08217862F3830121707F +:1065300090F8292662F30001217090F8292652086C +:1065400062F3410104F8011B217821F01001217050 +:1065500090F82726D308E27A63F34512E27290F8A6 +:10656000282662F3451104F8281990F82806C0F38C +:106570004101204602F086F9286890F827168A091A +:1065800014F8331F62F3000104F81D1990F8272650 +:10659000520962F34101617790F83C16E27D61F3A4 +:1065A0000402E27590F83D06A17D60F30401A17537 +:1065B0000120FFF7BBFE94F8491060F3040147483F +:1065C00084F84910E83002F0E1F8A4F86400286883 +:1065D00034F8181FB0F8332662F30B0124F80419BD +:1065E00010F8CA1F227861F3030204F8012B017826 +:1065F0000A09217862F3030104F8091B90F85D157C +:10660000CA09217862F3000104F82B1B14F857190A +:1066100041F0200184F8571090F872154A0921784A +:1066200062F30611217090F85E154A09217C62F32D +:10663000C301217490F85D05400860F304112174D2 +:10664000F8BD2DE9F04104461F4D0120DFF884809C +:10665000A870012908D00026022702290ED003299C +:106660004CD004292BD161E0204600F0B3F8D8F8D3 +:10667000000090F828068009687020E01848FFF7AD +:106680006EFE204600F0A6F80220FFF74FFE94F8B9 +:106690005F1060F30401134884F85F10007801284C +:1066A00007D194F8270020F0020040F0010184F89F +:1066B00027100021204602F00BF9AE706F7094F89D +:1066C000270040F300000FE0180810007C8701202D +:1066D000549C1000A007100074770120448301200F +:1066E000C0971000A8071000401CE870D8F8000000 +:1066F00090F8280680096870BDE8F0813748FFF7F8 +:106700002EFE204600F066F80320FFF70FFE94F8F7 +:106710005F1060F3040184F85F1094F8270020F004 +:10672000020040F0010084F82700C2E7204600F094 +:1067300051F8204601F0E7FCBFE71CB501F03DFC35 +:10674000CDE900010821684602F0A8FC244908713F +:106750002248FFF704FE1CBD30B5417AA9B091B3C1 +:106760006846FFF76EFF9DF8120000F0030001F08D +:1067700057FC1C4D286800F2B26200F2A55490F854 +:10678000A316B0F8A40602EB400001F01BFC286839 +:1067900090F8991590F89A0504EB400001F029FC57 +:1067A0000F494878022811D0012811D00120087023 +:1067B000C1B2684602F042FB0B49684602F073FB27 +:1067C000002029B030BDFFE70120FAE70920EEE7FD +:1067D0000320ECE7A422014903F061BEC09710003A +:1067E00018081000A00710007162010070B518B100 +:1067F000BDE8704001F087BBFE4CFD4DE078A5F18F +:106800009801820001F5887003F08EFEA1780129BD +:106810001DD0022922D0E178607801F027FCE178D0 +:10682000C0B24A00A5F1980101EB4001284603F0EF +:1068300036FEA079F04D012815D0ED482862E079A8 +:1068400085F83800607985F828000020D0E7E8490D +:10685000E2789839284601F085FBEAE7E078E449D8 +:1068600042009839E2E7E178E14801F0FDFBE5E715 +:1068700070B518B1BDE8704001F045BBDD4CDC4D92 +:1068800020792A358200A5F1C20101F5B27003F02A +:106890004BFEA17801291ED0022923D021796078EE +:1068A00001F0EAFB2179C0B24A00A5F1C20101EB77 +:1068B0004001284603F0F3FDA079CF4D012816D002 +:1068C000CB482A306862E07985F83800607985F82D +:1068D00029000020CEE7C64922799839284601F0E0 +:1068E00041FBE9E72079C24942009839E1E7C04815 +:1068F00021792A3001F0B9FBE4E7C049062809688C +:1069000013D2DFE800F0120306090C0F91F8350CE2 +:10691000704791F8360C704791F8370C704791F832 +:10692000380C704791F8390C704791F8340C704767 +:10693000F8B5044601F025FFAD48983801F026FF70 +:10694000A4F8760001F034FBAA4D0B466A78009259 +:106950000246204602F022FA01F02FFB02460B46C7 +:10696000204602F051FA204601F08CFBA34EB4F809 +:1069700056103068B0F88E2062F30901A4F8561062 +:1069800090F88D0094F8551060F3030184F85510C9 +:106990000521204601F025FF306890F81401A07011 +:1069A0003068218EB0F81A2162F30801218690F830 +:1069B000150100F00F01204601F08AFF306834F81D +:1069C0001A1FB0F80C2162F30B0124F81219B0F869 +:1069D0000A21218962F30B012181B0F80821A188E5 +:1069E00062F30B01A18090F81621A17A62F30101F4 +:1069F000A17290F81621920862F38711A17290F8A3 +:106A0000021114F8012C61F3000204F8012C90F833 +:106A1000050160707A4890F8801BA17590F8811B81 +:106A2000217790F8821BE17590F8831B617790F8CD +:106A3000841B217690F8850BA077724801F0A6FEA2 +:106A4000A4F878006F48203001F0A0FEA4F87C0084 +:106A5000306890F810110A0914F8141F62F3071136 +:106A600004F8061B90F812212378120962F3071329 +:106A7000237090F8112114F8057C62F3030704F8E1 +:106A8000057C90F813C162786CF30302627090F891 +:106A900011C14FEA1C1C6CF3071704F8057C90F831 +:106AA00013713F0967F30712627090F8102162F3C7 +:106AB000000104F8061C90F8121161F3000304F8B9 +:106AC000223990F806010109204601F00DFF4D48DA +:106AD000483801F05BFEA4F87E004A482734283885 +:106AE00001F054FEA4F85B00306890F804118A08A5 +:106AF000217862F38301217090F8042162F3000190 +:106B0000217090F80421520862F3410104F8011B3E +:106B1000217821F01001217090F80221D308E27A47 +:106B200063F34512E27290F8030160F3451104F833 +:106B30002819204601F086FA306890F80301C0F366 +:106B40004101204601F09EFE306890F802118A094A +:106B500014F8331F62F3000104F8071990F80221BA +:106B6000520962F34101E17190F81711627861F303 +:106B70000402627090F81801217860F3040121701A +:106B80000120FFF7BAFE94F8331060F3040184F893 +:106B900033101D4801F0FAFDA4F84E00306834F8B7 +:106BA000021FB0F80E2162F30B0124F8181910F837 +:106BB000CA1F227D61F30302227510F82E1B0A09F9 +:106BC000617D62F303016175817ACA09A17F62F375 +:106BD0000001A17794F8491041F0200184F8491090 +:106BE000C17F4A0914F80E1C62F306110EE0000082 +:106BF000F88801201D081000549C1000A007100008 +:106C000074770120AC8201202C84012004F80E1C32 +:106C1000C17A4A09A17862F3C301A170827A52084D +:106C200062F30411A170C07A8009A870F8BDA42293 +:106C3000884903F034BC2DE9F041874D0C4600260D +:106C400001216E71A971012807D00227022826D0E0 +:106C500003280CD004284CD143E02046FFF7E7FF7F +:106C60007E48006890F803018009A87041E07948E7 +:106C7000FFF75EFE2046FFF7DAFF0320FFF73DFE39 +:106C800094F85F1060F3040184F85F1094F8270013 +:106C900020F0020040F0010084F827001AE06D485F +:106CA000FFF746FE2046FFF7C2FF0220FFF725FE52 +:106CB00094F85F1060F30401694884F85F1000786D +:106CC000012807D194F8270020F0020040F00101CC +:106CD00084F827100021204601F0FAFDAE71AF7054 +:106CE00007E02046FFF7A3FF204601F00CFAAF7043 +:106CF000AE7194F8270040F30000401CE871BDE835 +:106D0000F08170B5554D286800F2B26200F2A554CA +:106D100090F8A016B0F8A10602EB400001F052F97D +:106D2000286890F8971590F8980504EB4000BDE8A6 +:106D3000704001F05EB970B5474D0146C079454CD1 +:106D40002870097BA434297250B3012928D0214628 +:106D5000FFF771FFA878012824D0022824D0002052 +:106D600068703E480168A07C91F8162162F301002A +:106D7000A07491F81611890861F38710A0746978DE +:106D8000204602F05BF8A07C00F0030001F048F917 +:106D9000FFF7B7FF3349204602F085F8002070BDA9 +:106DA000012070BD0220DBE70820D9E770B52A4D2D +:106DB0000146C079274C2870097BA434297258B346 +:106DC000022929D02146FFF736FFA878012825D0CF +:106DD000022825D0012068702048016891F816012A +:106DE0000209A07C62F30100A07491F816118909D0 +:106DF00061F38710A0746978204602F01FF8A07C28 +:106E000000F0030001F00CF9FFF77BFF1649204664 +:106E100002F049F8002070BD012070BD0320DAE7C0 +:106E20000920D8E71FB501F0C3F8CDE9000101F052 +:106E3000C4F8CDE902010821684602F02FF9064C9A +:106E40000821E07002A802F029F920710148FFF73B +:106E50006FFD1FBD649810001D081000A0071000F2 +:106E6000A80710009D6701002168010070B5B74DAB +:106E7000286800F2B26200F2A55490F89716B0F8B4 +:106E8000980602EB400001F09DF8286890F89115F3 +:106E900090F8920504EB4000BDE8704001F0A9B8FD +:106EA00008B101F030B8AB48A9490161AA49097895 +:106EB00001750020F5E770B5A44D0446286890F8E8 +:106EC0007501C0F30112C0F3810100F00300FDF76A +:106ED000C2FFA14E401C3070204600F0C4FD9C480B +:106EE00001F054FCA4F8760000223178204601F02D +:106EF0007CFEA07940F00200A071317894F86F0018 +:106F000061F3020084F86F0094F86E0020F00F0027 +:106F100084F86E002868A17C10F8EB2F62F3010161 +:106F2000A17410F80129920862F38711A174A18954 +:106F30006FF30B01A1810078A07094F85E0000212E +:106F400020F0010084F85E00204601F0C1FC2868B2 +:106F500090F8771184F8661090F8781184F868102A +:106F600090F8791184F86A1090F87A1184F86C100E +:106F700090F8300C14F85F1F60F30401217070BDAD +:106F80002DE9FC417548FFF796FF704F386890F87F +:106F90007611090639D56E4E0024083E00F27715A9 +:106FA0003460746000F0D1FFCDE900013A6892F8D6 +:106FB000CE2012F0600F03D0FEF78EFBCDE900016A +:106FC0000821684602F06AF800213B6807E06A5C25 +:106FD000424326F81120A24200D91446491C93F8D6 +:106FE000752102F00302521C8A42F0DC002005E009 +:106FF00036F81010611A26F81010401C93F875111D +:1070000001F00301491C8142F2DCBDE8FC8170B54E +:10701000524D4479A4355CB14C48006890F8750134 +:10702000400607D54E48007800F00300022801D240 +:10703000012070BD2146284600F083F8A87C00F0AE +:10704000030000F0EDFF2046FFF710FF45492846FA +:1070500001F00BFE002070BD70B544793B483F4DF8 +:107060000068A43590F87501400606D52CB13C485F +:10707000007800F00300022801D3012070BD2146F2 +:10708000284600F05EF8A87C00F0030000F0C8FF7E +:107090002046FFF7EBFE3349284601F0E6FD0020CD +:1070A00070BD002800F02FBF2DE9F0412B4C8579F1 +:1070B000A434EDB32C4E264F3078083F37F810003B +:1070C000B0B3A4222549204603F0E9F914F86F0F64 +:1070D00020F00700401C04F86D091C48006890F877 +:1070E000D70004F80E0B307837F81010208861F3C1 +:1070F0000B0024F8560B002004F85809E07F20F01C +:107100001F00E077A07F20F01F00A07734F8200F49 +:107110006FF30B00401C24F81C0914F8120900F04E +:10712000030000F07DFF2846FFF7A0FE0F4900E0B6 +:1071300005E0204601F099FD0020BDE8F081012026 +:10714000FBE7A422054903F0AAB90000A00710003C +:10715000648A0120549C100026081000AC9910008D +:107160003C081000516E0100D80710005370010058 +:10717000FE490F28096833D2DFE800F032080B0E11 +:107180001114171A1D202326292C2F0091F8210CE9 +:10719000704791F8220C704791F8230C704791F8D2 +:1071A000240C704791F8250C704791F8260C704715 +:1071B00091F8270C704791F8280C704791F8290C2A +:1071C000704791F82A0C704791F82B0C704791F892 +:1071D0002C0C704791F82D0C704791F82E0C7047CD +:1071E00091F8200C704770B5E04E0428346804F222 +:1071F000B26204F2A55518D0072824D00A2830D04E +:107200000B2833D0B4F8980694F8971602EB400098 +:1072100000F0D8FE306890F8911590F8920505EBD3 +:107220004000BDE8704000F0E4BEB4F89B0694F85E +:107230009A1602EB400000F0C5FE306890F89315F6 +:1072400090F89405EBE7B4F89E0694F89D1602EBCF +:10725000400000F0B7FE306890F8951590F896055C +:10726000DDE794F8A11594F8A205D8E794F8A315E2 +:1072700094F8A405D3E770B5060003D0BDE87040CC +:1072800000F041BE00F02EF801282AD1B84DB94CCB +:10729000287801281FD0B848A0606878E073E878A3 +:1072A000A073A87A2073287B6073E87984F83A0089 +:1072B000287A84F83B00AD48016891F8CD00C006FB +:1072C00007D591F89701C00703D0AC48A061012011 +:1072D00060753046D2E7AA79297AA74800F0C3FE44 +:1072E000DAE770BDA24B10B5D978A54C491CCAB2DB +:1072F000DA70997801208A420ED8197A9879414338 +:107300009D48FDF74DFE01F041FAA4F876009D4935 +:10731000204601F0AAFC002010BD38B5044601F05B +:1073200030FA954801F032FAA4F8760000F040FEF9 +:107330008E4D0B462A6892F8CE20C2F3411200927D +:107340000246204601F030FC00F037FE02460B46B4 +:10735000204601F055FCA07920F00200A07194F8BD +:107360006F0020F0070084F86F0094F86E0020F0A2 +:107370000F0084F86E00286890F8CE00C0F3411129 +:10738000204601F057FC286890F8CE1011F0600FED +:1073900094F85E107ED041F0010184F85E1090F800 +:1073A000CD004108E07961F3C710E071204600F09C +:1073B00069FE0521204601F014FA286890F8D700EC +:1073C000A0702868218EB0F8DD2062F308012186C4 +:1073D00090F8D80000F00F01204601F079FA2868F3 +:1073E000627D90F8D11061F303026275B0F8D3208A +:1073F000218A62F30B01218290F8D910A27D61F3FA +:107400000302A27510F8D81F0A09A17C62F30101DA +:10741000A17410F80B29920962F38711A174017805 +:10742000E27961F30002E271C178617200790109C9 +:10743000204601F059FA544801F0A8F9A4F87C005C +:10744000286810F8CF1F8A0814F8271F62F38301F9 +:10745000217010F8012962F300012170427852086E +:1074600062F34101217000780109607861F3041032 +:107470006070464801F08AF9A4F85F00286810F8A7 +:10748000CD1FCA0814F80C1F62F3451104F80B193C +:10749000427800E089E0217862F3451104F8281968 +:1074A0004078C0F34101204601F0ECF9286810F85B +:1074B000CD1F8A0914F8331F62F3000104F80B1979 +:1074C0000278520962F34101E172417B627961F312 +:1074D00004026271807B217960F304012171012033 +:1074E000FFF746FE94F8371060F3040184F8371074 +:1074F000274801F04BF9A4F85200286834F8061F19 +:10750000B0F8D52062F30B0124F8061B90F8C910DF +:1075100014F80A2C61F3030204F80A2C90F8C9103D +:107520000A0914F8091C62F3030104F8091C90F815 +:10753000CD108A0814F80C1C62F3000104F80C1C2E +:1075400090F8CD10CA09217862F3000104F82B1BD2 +:10755000217841F0200104F85F1990F89711C907CC +:1075600022D090F8CD00010914E00000A00710001F +:1075700028081000549C1000948B0120549E012078 +:10758000989B100027720100747701200C8701205E +:107590002C84012014F8330F61F304102070FE488E +:1075A00001F0F4F8A4F8450038BD21F00101F4E63B +:1075B00038B5044601F0E5F8F84801F0E7F8A4F81A +:1075C000760000F0F5FCF64D0B462A6892F8FF2A8B +:1075D000C2F3411200920246204601F0E5FA00F0A3 +:1075E000ECFC02460B46204601F00AFBA07920F095 +:1075F0000200A07194F86F0020F0070084F86F007B +:1076000094F86E0020F00F0084F86E00286890F85F +:10761000FF0AC0F34111204601F00CFB286890F8E6 +:10762000FF0A10F0600F94F85E007DD040F001007A +:1076300084F85E00204600F025FD286890F80A0BCB +:10764000A0702868218EB0F8102B62F30801218603 +:1076500090F80B0B00F00F01204601F039F9286873 +:10766000627D90F8021B61F303026275B0F8042B8F +:10767000218A62F30B01218290F80C1BA27D61F339 +:107680000302A275B0F8062BA18962F30B01A18158 +:1076900090F80B1B0A09A17C62F30101A17490F818 +:1076A0000B2B920962F38711A17490F8FE1AE2790C +:1076B00061F30002E27190F8011B617290F8020B15 +:1076C0000109204601F010F9B64801F05FF8A4F86E +:1076D0007C00286890F8001B8A0814F8271F62F3C2 +:1076E0008301217090F8002B62F30001217090F863 +:1076F000002B520862F34101217090F8FF0A010942 +:10770000607861F304106070A74801F03FF8A4F8B6 +:107710005F00286890F8FE1ACA0814F80C1F62F37C +:10772000451104F80B1900E066E090F8FF1A227882 +:1077300061F3451204F8282990F8FF0AC0F34101CB +:10774000204601F09FF8286890F8FE1A8A0914F87C +:10775000331F62F3000104F80B1990F8FE2A520956 +:1077600062F34101E17290F80D2B617962F304013B +:10777000617190F80E0B217960F3040121710A20E8 +:10778000FFF7F6FC94F8371060F3040184F8371023 +:10779000864800F0FBFFA4F85200286834F8061F62 +:1077A000B0F8082B62F30B0124F8061B10F8C91F70 +:1077B00014F80A2C61F3030204F80A2C01780A0970 +:1077C00014F8091C62F3030104F8091C90F8351A37 +:1077D0008A0814F80C1C62F3000104F80C1C90F8E1 +:1077E000350AC109207861F3000004F82B0B2078DA +:1077F00040F02000207038BD20F0010018E738B5B7 +:10780000044600F0BEFF654800F0C0FFA4F8760013 +:1078100000F0CEFB624D0B462A6892F8192BC2F39A +:10782000411200920246204601F0BEF900F0C5FB6D +:1078300002460B46204601F0E3F9A07920F0020051 +:10784000A07194F86F0020F0070084F86F0094F89E +:107850006E0020F00F0084F86E00286890F8190B75 +:10786000C0F34111204601F0E5F9286890F8190BA2 +:1078700010F0600F94F85E007DD040F0010084F8B5 +:107880005E00204600F0FEFB286890F8240BA070F4 +:107890002868218EB0F82A2B62F30801218690F81F +:1078A000250B00F00F01204601F012F82868627DD8 +:1078B00090F81C1B61F303026275B0F81E2B218A3D +:1078C00062F30B01218290F8261BA27D61F3030273 +:1078D000A275B0F8202BA18962F30B01A18190F869 +:1078E000251B0A09A17C62F30101A17490F8252BE4 +:1078F000920962F38711A17490F8181BE27961F381 +:107900000002E27190F81B1B617290F81C0B0109D8 +:10791000204600F0E9FF234800F038FFA4F87C007F +:10792000286890F81A1B8A0814F8271F62F383014D +:10793000217090F81A2B62F30001217090F81A2B35 +:10794000520862F34101217090F8190B0109607827 +:1079500061F304106070144800F018FFA4F85F0091 +:10796000286890F8181BCA0814F80C1F62F3451118 +:1079700004F80B1900E073E090F8191B227861F30A +:10798000451204F8282990F8190BC0F3410120464C +:1079900000F078FF28680BE0549E0120948B0120B2 +:1079A000A0071000747701200C8701202C8401208F +:1079B00090F8181B8A0914F8331F62F3000104F8C9 +:1079C0000B1990F8182B520962F34101E17290F8FB +:1079D000272B617962F30401617190F8280B2179FA +:1079E00060F3040121710B20FFF7C2FB94F83710FC +:1079F00060F3040184F83710FE4800F0C7FEA4F8D5 +:107A00005200286834F8061FB0F8222B62F30B01ED +:107A100024F8061B10F8C91F14F80A2C61F303029E +:107A200004F80A2C01780A0914F8091C62F303010E +:107A300004F8091C90F84F1A8A0814F80C1C62F319 +:107A4000000104F80C1C90F84F0AC109207861F37A +:107A5000000004F82B0B207840F02000207038BD87 +:107A600020F001000BE710B50446A422E24902F021 +:107A700016FDE2484179A08961F30B00A08110BD99 +:107A800038B50446FFF7EFFF00F092FA00220092AB +:107A900002460B46204601F087F8D94800F076FEF2 +:107AA000D84DA4F87C00286890F8DF00A070286802 +:107AB00090F8E00000F00F01204600F009FF286870 +:107AC00010F8E01F0A09A17C62F30101A174027899 +:107AD000920962F38711A174817894F82D2061F3E3 +:107AE000040284F82D20C17894F82C2061F304025C +:107AF00084F82C204078A17D60F30301A17500215A +:107B0000204601F097F814F85E0F20F00100207075 +:107B10000720FFF72DFB617860F30401617028688E +:107B200034F82E1CB0F8E42062F3080124F82E1C6F +:107B300010F8E11F0A0914F8371C62F3000104F879 +:107B4000371C0078400960F3410104F8371C38BD48 +:107B50002DE9F047AC4D4FF001094FF0000885F8D2 +:107B6000009085F8028085F80380064685F8078036 +:107B70002879A44F0C4628724FF0020A0F2A19D216 +:107B8000DFE802F0A208A2192DA220685273939791 +:107B9000A29B9F000846FFF766FF307D012809D1B0 +:107BA0006879287285F8079094F85E0020F001004B +:107BB00084F85E0088E0084600F0EAF8386890F83B +:107BC000E6002CE0084600F0E3F8386890F8E6009C +:107BD000C0F38100022825D985F802A074E0084688 +:107BE000FFF741FF386890F8E800A0700420FFF725 +:107BF000BFFA94F85F1060F3040184F85F10307DE1 +:107C0000012809D16879287285F8079094F85E00F8 +:107C100020F0010084F85E00386890F8E70000F07A +:107C20000300D7E7A8704FE00846FFF71CFF0021CC +:107C3000204600F04DFE14F85E0F20F00100207089 +:107C40000820FFF795FA14F8011F60F3040104F807 +:107C50005F1927E00846FFF713FF386890F8E9102E +:107C6000A08961F30B00A0812EE00846FFF708FF12 +:107C70000021204600F02CFE0920FFF779FA94F845 +:107C80005F1060F3040184F85F1094F85E0020F048 +:107C9000010084F85E00386890F8E910A08961F36B +:107CA0000B00A08185F800800EE00846FFF780FCFD +:107CB000F8E70846FFF7A3FDF4E7084600F075F87B +:107CC00002E00846E9F75FF894F82700C00702D001 +:107CD00085F8018001E085F80190386890F8BD1AB8 +:107CE000C90702D0317C012908D044480078A88116 +:107CF000A089C0F30B006881BDE8F087717C00F2B9 +:107D00007710415CA08961F30B00A081707CEEE7E5 +:107D100010B586B000F04CF9CDE9000100F04DF946 +:107D2000CDE902010821684601F0B8F9364C082176 +:107D3000207102A801F0B2F9A071DDE90001FDF7A0 +:107D4000CBFCCDE90401082104A801F0A7F960717A +:107D50002948FFF7E2FA06B010BD70B5264D047948 +:107D6000A4358CB122462946FFF7F2FEA87C00F02C +:107D7000030000F055F92046FFF735FA234928465D +:107D800000F073FF002070BD012070BD002070471F +:107D900010B50446FFF767FE0320FFF7E9F914F872 +:107DA0005F1F60F30401217010BD38B50446FFF772 +:107DB0005AFE00F0FDF80022009202460B462046D3 +:107DC00000F0F2FE0320A0700021204600F080FDAC +:107DD0000021204600F02EFF94F85E0020F0010004 +:107DE00084F85E00A07D20F00F00A075607D20F07B +:107DF0000F000DE02C840120F49A1000D807100029 +:107E00009C7C0120A00710002808100027720100A8 +:107E10006075208A6FF30B0000F6A6602082A089AF +:107E20006FF30B0000F6A660A081E08D6FF30B00EE +:107E3000E08538BD10B500F0B1F9FFF769FFFFF735 +:107E40009FF8FEF7EFFFFEF778FC424900204860FC +:107E5000BDE810407021404802F0A0BB38B10128B5 +:107E600007D0022807D017200021FCF7DAB8142029 +:107E7000FAE71520F8E71620F6E7182102F0B0BB64 +:107E800070B5344C354D206808E055F82010344862 +:107E90008847002817D02068401C20600928F4D3A8 +:107EA00060684EF66022401C00216060904200D362 +:107EB00061602B48183001706168416018380168B2 +:107EC00018308847012070BD10B50446007940B9CC +:107ED000E07930B9607A20B9607910B9A0790028CA +:107EE00010D01F483C21183002F07AFB182221469E +:107EF0001B4802F019FB1749002008601848FFF7DB +:107F0000BFFF012010BD70B5124C050016D0002037 +:107F100000F050F961684EF66020491C61608142B2 +:107F200001D3002060600E48183005706168416020 +:107F300018380168BDE87040183008472068401CB8 +:107F40002060BDE8704006489AE700F031B800F0C4 +:107F500034B80000380810000C87012090AA0100F6 +:107F60003C9C100070B5874B1B6893F80731DB070A +:107F70004FF000030ED0154609E031F9134031F9F6 +:107F800015603444641020F813405B1C6D1C934250 +:107F9000F3DB70BD144608E031F8135031F814607B +:107FA000354420F813505B1C641C9342F4DB70BD15 +:107FB00074480068C16A806A704772480068416A04 +:107FC000006A704730B5714C6F4B6268824202D1D3 +:107FD000E2688A420AD0002206E030F81250C5F367 +:107FE0000B0523F81250521C8A42F6DBE1606060F8 +:107FF00030BD30B5654C664BA268824202D1226921 +:108000008A420CD0002206E030F81250C5F30B056E +:1080100023F81250521C8A42F6DB2161A06030BD69 +:1080200070B504465B48016802290AD1574D29788A +:108030008C4206D000EB8400D0F89C0000F0B9FB25 +:108040002C7070BD10B5044690F82800800609D544 +:10805000514800F09BFB24F88E0F4F48203000F071 +:1080600095FB608010BD70477047704702004FF06D +:10807000000000D10846704702460020012A00D1C6 +:10808000084670473F4A116891F87D108B0910F837 +:108090003E1B63F3820100F83E1C136893F87D30A9 +:1080A0005B0963F3451100F83E1C1168B1F88520A7 +:1080B000028291F88420837F62F30713837791F81B +:1080C00081201309027D63F306120275B1F87F3037 +:1080D000028B63F30902028311F87D2F9308827DDE +:1080E00063F3861282750A79C37D62F30303C37555 +:1080F000B1F80530B0F81B2063F30802A0F81B208C +:1081000049894182704710F8371F41F0100100F88B +:108110001F1930F80C2CC17E6FF30B02103220F8BF +:108120000C2C30F8082C21F023016FF30B024032A5 +:1081300020F8082C082200F8162C90F8472041F06F +:108140000C0122F01F0280F84720028B6FF3080217 +:108150000283C176C18A6FF30B013F31C182417D39 +:1081600021F01F014175017D21F01F01017590F87B +:10817000461021F0010180F84610017C41F02001F9 +:1081800001747047A00710002C84012040081000E3 +:108190002C860120909C10009C860120704710B511 +:1081A00000F0A5FD08B1012010BD084800F088FDD1 +:1081B000002010BD064810B5006890F87100400717 +:1081C00001D500F089FD012010BD0000B77E01003F +:1081D000A00710003D48016821F00401016000F093 +:1081E0001DBF10B5FFF7F6FF10BD10B5FFF7F2FF8A +:1081F00010BD10B5FFF7EEFF10BD10B5FFF7EAFF99 +:1082000001F0BBFC10BD10B5FFF7E4FF00F0DEFA93 +:1082100010BD10B5FFF7DEFF01F085FD10BD10B5F4 +:10822000FFF7D8FF01F0C7FD10BD10B5FFF7D2FF73 +:1082300001F00AFE10BD10B5FFF7CCFF01F04FFEB4 +:1082400010BD10B5FFF7C6FF01F094FE10BD10B5CC +:10825000FFF7C0FF01F0D9FE10BD10B5FFF7BAFF60 +:1082600001F022FF10BD10B5FFF7B4FF02F01AFABB +:1082700010BD10B5FFF7AEFF02F0F0F910BD10B55C +:10828000FFF7A8FF10BD10B5FFF7A4FF10BD10B594 +:10829000FFF7A0FF10BD10B5FFF79CFF01F04AFFEC +:1082A00010BD10B5FFF796FF10BD10B5FFF792FF98 +:1082B00010BD10B5FFF78EFF10BD10B5FFF78AFF98 +:1082C00010BD10B5FFF786FF10BD704710ED00E040 +:1082D0000EB50BA007C88DE807000C4800F047FE5C +:1082E000684600F048FEFCF75FFCFCF7B3FA00F0CC +:1082F00037F800214720FBF794FE01200EBD000057 +:10830000110000000000000000000000670093233F +:108310001A4910B501200870194900200860194950 +:108320000860194908601949086000F07FF900F0F9 +:1083300019F900F07DF8002010BD10B5124801F0C9 +:1083400097FF104908600E490968884207D00B481A +:108350000078022803D1BDE81040E8F707B810BD47 +:1083600010B5FFF7EAFF054902200870E7F7E2FFC2 +:108370004FF0FF3010BD012070470000A40810002E +:10838000A8081000AC081000B0081000B4081000D5 +:1083900070B50D460446C1698068CC2202F0F6F83B +:1083A000E169A068002208444FF0807140F8041C85 +:1083B000216A40E9032140F8102C40F8142C40F8C1 +:1083C000182C40F81C2C4FF00B3140E909154FF0E8 +:1083D0000A3140F8281C4FF0093140F82C1C4FF0AE +:1083E000083140F8301C4FF0073140F8341C4FF092 +:1083F000063140F8381C4FF0053140F83C1C4FF076 +:10840000043140F8401D70BD81694FF0CC330A68DB +:108410009A4208D14A689A4205D18A689A4202D1A2 +:10842000C968994202D04068FCF759BA7047000009 +:1084300010B5A021494802F0D3F8002010BD70B556 +:108440000646464800EB0614E7F7C8FF05462078C5 +:1084500028B12846E7F7CAFF6FF0010070BD03207E +:10846000207000206660E06004F1080001F0DAFE90 +:108470002846E7F7BBFF002070BD2DE9F0410F460D +:108480003649002501EB00142E46E7F7A7FF80468A +:10849000E0683843E06004F10800074601F0E8FEB8 +:1084A0000CE0E168C26A114203D000F00FF9012626 +:1084B00000E06D1C2946384601F0D0FE0028F0D1BE +:1084C0000EB1FFF73AFF4046E7F790FF0020BDE806 +:1084D000F08170B50D46214901EB0014E7F77EFFEE +:1084E000E168A943E160E7F781FF002070BD70B546 +:1084F0000C461A4901EB001500202060E7F76EFFDB +:10850000E9682160E7F772FF002070BD2DE9F041B6 +:108510000D4612491E46904601EB0014E7F75EFF38 +:1085200007460F480068C562E168294203D104F19B +:10853000080100F0DDF83846E7F758FFE7F74EFF8F +:10854000E16829403160B8F1010F02D1E168A94327 +:10855000E160E7F74BFF0020B9E700003C9D100009 +:10856000A808100010B5C8212E4802F039F80020E4 +:1085700010BD2DE9F04106462A4900EB860017465A +:1085800001EB8004E7F72AFF0546207830B1284642 +:10859000E7F72CFF6FF00100BDE8F08102202070AA +:1085A00000206660C4E9027004F1100001F03AFE98 +:1085B0002846E7F71BFF0020EEE770B5194900EBEE +:1085C000800001EB8004E7F709FF0546D4E90201CA +:1085D000814205DB144804F11001006800F088F8BE +:1085E000E068401CE0602846E7F700FF002070BD0F +:1085F00070B50C4900EB800001EB8004E7F7EEFE5C +:108600000546E06808B1401EE06004F1100001F08A +:108610002FFE10B1206900F011F82846E7F7E6FEBA +:10862000002070BDDC9D1000A808100010B54FF4AC +:10863000F0713C4801F0D4FF002010BD10B5044695 +:1086400090F8240002280BD0204601F013FE0220EF +:1086500084F824003449204601F0E8FDFFF76DFE60 +:10866000002010BD2DE9F05F06460AA806EB460182 +:1086700090E8000E2B481D4600EB01149046207830 +:1086800018B16FF00100BDE8F09FE7F7A7FE0746BD +:1086900001202070C4F81480C4E9016504F11801B8 +:1086A000002081E8200684F82400E0602061C4E90D +:1086B0000A8059462046FFF76BFEA0602046FFF770 +:1086C000BDFF3846E7F792FE0020DCE710B5044610 +:1086D00090F82400022809D0204601F0CBFD0220AA +:1086E00084F824001049204601F0A0FD002010BDB0 +:1086F00070B5044690F824000D4602280BD12046A0 +:1087000001F0B8FD032084F824002946204601F03A +:108710008DFDFFF712FE002070BD04480068406820 +:1087200070470000A49E1000B0081000A8081000B8 +:10873000724810B500210160012202600160704C96 +:108740006920A0710420E7F75BFE0820A07110BD2E +:1087500010B5FFF7EDFF6B4800210170416000F09C +:108760001CFABDE8104000F012BB01F049BC01F05A +:1087700097BC10B501F094FC01F042FCBDE810403C +:10878000E6E7A422604901F08ABE704710B50446AE +:10879000800702D00220FFF761FB4FF480302044B5 +:1087A000C0F34F0010BD014655489822A43001F097 +:1087B00076BE534AA432002142F82100491C2629E2 +:1087C000FADB704701F04ABC01F0E4BB4D4810B53C +:1087D000406810B1BDE8104000470020FFF73EFBA5 +:1087E00010BD062937D2DFE801F011243724360303 +:1087F000017821F0120100F84D1B017821F00301EE +:1088000000F8071B017821F080010CE0017821F0CD +:10881000020141F0100100F84D1B017821F0030125 +:1088200000F8071B12E000F8441B017821F0010159 +:1088300010E00278012942F01202027000D00321F8 +:1088400010F84D2F61F3010200F8072B017841F079 +:108850008001E8E701707047017821F0020141F0E2 +:10886000100100F84D1B017821F00301891C00F86C +:10887000071B017841F0800100F8441B017841F0AA +:108880000101E7E790F82920022904D0032922F00A +:10889000400102D104E042F0400121F0800101E0FA +:1088A00041F0800180F82910704790F829200129B3 +:1088B00004D0022907D022F0100101E042F010019B +:1088C00021F0200101E042F0300180F829107047CA +:1088D000C278002961F30302C27004D010F85E1F51 +:1088E00041F0040101707047C27A012961F303026B +:1088F000C27202D942F01001C17270479004002286 +:108900000000032054081000B4AA010001EB81010B +:1089100002EBC101405C010602D500F07F0040423D +:108920007047002B04DA5B42DBB243F0800301E0C6 +:1089300003F07F0301EB810102EBC1014354704757 +:108940002DE9F05F0025DDE90A7891469A468346D5 +:108950002E462A460120002101F057FD00EA0900B9 +:1089600001EA0A01084314D0002422460120002114 +:1089700001F04BFD384001EA0801084305D000230F +:10898000224631465846FFF7CCFF641C282CECDB0E +:10899000761C6D1C382DDCDBBDE8F09F405C0106C9 +:1089A00002D500F07F0040427047002A04DA5242AC +:1089B000D2B242F0800201E002F07F0242547047DE +:1089C000F0B5002415460E468446234601270FE0E5 +:1089D00006EBE30003F00701007807FA01F2024218 +:1089E00005D0002219466046FFF7DFFF641C5B1CC0 +:1089F000AC42EDDBF0BD405C704742547047F0B5CF +:108A00000024234601260DE001EBE30503F00707F0 +:108A10002D7806FA07FC1CEA050F02D00025C55484 +:108A2000641C5B1C9442EFDBF0BD405C7047425419 +:108A30007047405C70474254704700002DE9F04792 +:108A4000334C54F83C8F6768E668257CDFF8C490A7 +:108A50000121C9F800104FF42070E7F7D1FC002184 +:108A6000C9F80010C4F800806760E6602574BDE8AE +:108A7000F08727480021C1630164816480F84C10AD +:108A8000704770B500240D4602460120214601F0D2 +:108A9000BCFC35B31E4A483210601171FFF7CEFF9F +:108AA000002000F023F800B10124FFF7C7FF0120E8 +:108AB00000F01CF808B144F00204FFF7BFFF0220E9 +:108AC00000F014F808B144F00404FFF7B7FF0320E6 +:108AD00000F00CF808B144F00804FFF7AFFF20469F +:108AE00070BD0B4A3C32C2E90001D7E740F02001DB +:108AF000074810B580F8A310E52181714FF420706C +:108B0000E7F77EFC0448D0F8C002C0B210BD0000F8 +:108B10000000032068146022001060225848416859 +:108B2000002901D001200847704710B5FFF71FFE4C +:108B30005449022008705449002008605048416898 +:108B4000002903D0BDE810400020084710BD10B533 +:108B5000817921F00D0141F0E0018171817C8A0968 +:108B600019D08A0962F38711464A81740321117072 +:108B7000454A464911600146A422454801F08FFC50 +:108B800044490120C1F8C0003D4843490088BDE880 +:108B90001040FFF717BE0122E4E739480021416089 +:108BA0004FF4FA71018070477FB504460399089D20 +:108BB000C1F314010391082102A800F06FFA012DFE +:108BC00002D0022D04D006E0C01C20F0010002E01B +:108BD000C01D20F00300DDE9021244F83C1F626072 +:108BE000217A60F3060121727FBD012340F83C3FEA +:108BF000002343605143027A61F306020272704718 +:108C00001FB50446039902A801F03F010391082112 +:108C100000F044FADDE90212A16484F84C2014F853 +:108C2000701F60F3050104F81E19E17F60F3050170 +:108C3000E1771FBD08B519A2126800921DF8012046 +:108C400010F85D1F62F30101017008BD0D4903209A +:108C500008700D490D4808600E490120C1F8C00098 +:108C600007480D490088FFF7ADBD054A51604FF434 +:108C7000FA7111806BE7024B59601A8067E70000B8 +:108C80005C0810005408100058081000DB8A01002E +:108C90000000032000006022CD8A010000010200D4 +:108CA00016480178012908D1022101701448016891 +:108CB00019B100220260104608470120FFF7CEB824 +:108CC0000E4A012111700E4908600E49E820887192 +:108CD0000D490C20FFF778BD0A49082088710B491F +:108CE000002008620549087005490860704703487C +:108CF0000078002800D001207047000054081000C0 +:108D00006408100000000320518C01000000602264 +:108D10006A484168002901D001200847704710B512 +:108D2000FFF725FD664902200870664900200860AB +:108D300062484168002903D0BDE810400020084780 +:108D400010BD10B5817C8A091FD08A0962F3871192 +:108D5000817481795A4A21F0010141F0E001817169 +:108D600004211170574A584911600146A4225748FE +:108D700001F095FB56490120C1F8C0004F48554904 +:108D80000088BDE81040FFF71DBD0122DEE74B481B +:108D9000002141604FF4FA71018070477FB50446AD +:108DA0000399089DC1F314010391082102A800F062 +:108DB00075F9DDE90212E163226494F84420C1B23E +:108DC00061F3060284F844200A2D0FD00B2D0DD03C +:108DD00014F8720F61F305002070607861F30500EC +:108DE0006070A07820F00800A0707FBD14F8721F9A +:108DF000401C60F305012170617860F3050161702A +:108E0000A07840F00800EFE71FB50446039902A8D8 +:108E100001F03F010391082100F040F9DDE9021261 +:108E2000A16484F84C2014F8701F60F3050104F865 +:108E30001E19E17F60F30501E1771FBD30B526A261 +:108E40008CB03CCA8DE83C0027A20DF1100C3CCA46 +:108E50008CE83C0028A20DF1200C3CCA8CE83C00B8 +:108E600004AA535C427E63F3050242761DF801308A +:108E7000027E63F34202027608AA525C817962F3B1 +:108E8000830181710CB030BD0D49042008700D497B +:108E90000D4808600E490120C1F8C00007480D497F +:108EA0000088FFF78FBC054A51604FF4FA711180BA +:108EB00047E7024B59601A8043E70000680810003A +:108EC0005408100058081000CF8C01000000032047 +:108ED00000006022C18C01000000020201010303B6 +:108EE000030300020000000002020202020202026A +:108EF0000101020201010000020302030203020356 +:108F000002030202020300004E49012008601722FA +:108F1000410701F8272F0B2281F8412049491839D0 +:108F200008604FF00851C1F8C403464B0022B0332B +:108F30001A60454A1060121D1060424A943A10604F +:108F4000C1F86803C1F8740370473E4901209439A1 +:108F5000086070473B4900209439086070474FF023 +:108F60000050008870474FF00050807870474FF0F5 +:108F7000005148607047354902680A6042684A609B +:108F800080688860704731490A6802604A684260B8 +:108F90008968816070472B4901203039086070472B +:108FA0004FF0005010F8221F21F0030101707047AC +:108FB0004FF0005303F81F0F5970987862F30300C5 +:108FC00098707047224800687047214908607047D0 +:108FD00010B54FF00054E27E202322F0AF0203EAE6 +:108FE00040131343042202EA8000034301F003000C +:108FF0000343E37610BD4FF0005090F8220010F0CC +:10900000030005D0012805D0022805D0114870477B +:1090100011487047114870471148704770477047B2 +:1090200010490120C1F8DC0070470E490020C1F84A +:10903000DC0070470348F030006808B10120704739 +:1090400002207047CC040022801E0022080000206D +:109050007008100000127A000090D0030048E80168 +:109060000024F40000006022F0B50746002003460B +:109070002F4E10E057F8235003224FEAC20C45FA56 +:109080000CF484EA2064E4B2521E56F8244084EAC8 +:109090000020F2D55B1C8B42ECDBF0BD30B5044602 +:1090A000234B0020103B08E0625C02F00F0503EB4D +:1090B00012125D5D127828441044491EF4D230BD6E +:1090C00010B584680368E443A3420AD1C4684368C6 +:1090D000E443A34205D15B1C0B60006810600120D3 +:1090E00010BD002010BD3CB50446002501AA69460C +:1090F000FFF7E6FF012809D1009904F11000091FCC +:10910000FFF7B2FF0199884200D1012528463CBDF6 +:1091100030B50D460446091F1030FFF7A5FF6D1E40 +:109120006560E943E1602060C043A06030BD00009D +:1091300068AB010001468000B1F5803F02D21038D3 +:10914000C0F310007047C0F387207047B0F5802F40 +:1091500002D21030C0F31000C0F38F00704730B55A +:10916000F94C01252560E50603F01F0385F86B30F7 +:10917000002304E051F8235040F823505B1C934235 +:10918000F8DB0020206030BDF0B5EF4F01233B60DD +:109190005C0784F86B309B1E0360002312E051F8DB +:1091A000234040F82340002450F8235051F8236016 +:1091B000B54206D06D1C04D1641C40F82360032C1A +:1091C000F2D35B1C9342EADB00203860F0BDF0B5BF +:1091D00013460A460546002498184FF48326602853 +:1091E00001D9012411E0002107E05F1856F827009B +:1091F000401C01D011460224491C9142F5D324B9E8 +:1092000006EB83002946FFF7BFFF2046F0BD10B5EF +:1092100003460846FFF78EFF0146BDE81040920066 +:10922000184601F081B92DE9F0414FF000580C4685 +:10923000D8F814700125C0F38F066FF48041C8F888 +:1092400014100E2000F02EFA204600F036FA02002C +:10925000BE484FF0010118D00160A4F580344046AB +:1092600020F8726F4480602200F8012CB84A116027 +:10927000B64AC432116030BF81797238890700D094 +:10928000002547612846BDE8F08100220260E6E73C +:109290002DE9F05F1546DFF8B0B2002601270A4637 +:1092A00004464FF0005CB1F5882F15D3A30AFFF7F1 +:1092B00041FF5946CBF8007003F01F038CF86B3068 +:1092C000002304E052F8234040F823405B1CAB42EB +:1092D000F8DB0E60BDE8F09FDCF81490C1F38F0856 +:1092E000E2466FF48041CCF814100E2000F0DAF959 +:1092F000CBF80070204600F0E0F90100934819D047 +:109300000760A4F58034AAF87280AAF874406D1E34 +:10931000AAF8765040218AF871108D490E608B4969 +:10932000C4310F600AF1520030BFCBF8006040F842 +:109330003E9CCFE70660E6E72DE9F0414FF0005490 +:109340000F4654F8146F85086FF4804020600E209B +:1093500000F0A8F90020A066A4F85E507F1EA4F8D3 +:10936000627084F85D007A49086078490120C43150 +:10937000086030BFE06E266085E770B506460C4693 +:1093800001F11000111F154689B2FFF7D5FF2060CB +:10939000681E606020682A46C043A060606821465D +:1093A000C043E0603046BDE8704071E7F0B5074665 +:1093B00000200446674E15E057F8245003234FEA77 +:1093C000C30C45FA0CF280EA02600822002802DA97 +:1093D00086EA400000E04000521E002AF6DC5B1ED8 +:1093E000EDD5641C8C42E7DBF0BD30B550F8084B7E +:1093F00050F8085B30F80C1C491C89B2FFF7D6FF07 +:10940000844204D1E043854201D1012030BD0020D7 +:1094100030BD2DE9F0410126750704466F696FF4F0 +:10942000804068610E2000F03DF94FF00008C5F85B +:109430007C80204600F041F9020044494FF00100D1 +:1094400015D00860A4F58034A5F87440202185F873 +:1094500071103F4908603D49C431086030BF95F83C +:109460007800800700D000266F6130460BE7C1F816 +:109470000080E9E700B50B46FFF75CFE82680168F3 +:10948000D243914208D14268C068C043824203D1AE +:10949000521C1A80012000BD002000BDF8B5044612 +:1094A00010300D460646FFF7BEFE012801D0002011 +:1094B000F8BD69462846FFF7DDFFBDF80000001F34 +:1094C00081B23046FFF738FF2060BDF80010C0437E +:1094D000491E6160A060C843E0600120F8BD2DE92D +:1094E000F041B0B01C4C80466E46002505AFC0214F +:1094F000684601F075F8002054F8201046F8201056 +:10950000401C3028F8D31549009804F5805488424F +:1095100010D1029881B23846FFF748FF0199814285 +:1095200006D1AC223946404600F0FEFF002002E0A2 +:10953000032000E001206D1CEDB2032D01D20328B1 +:10954000D5D030B09FE60000C41B0022780D002269 +:109550001C0F00221B000080481D0400B2570E7033 +:109560002DE9F04794B0584D00260446E8463746AA +:1095700045F2AA5A6FF002095021684601F030F80E +:10958000002055F8202048F82020401C1428F8D34B +:109590004E49009805F5805588420ED14FF0FF30B6 +:1095A00020606060A060E0602061029881B205A840 +:1095B000FFF7FCFE019981420AD0C4F80090C4F87C +:1095C0000490C4F80890C4F80C90C4F810901EE001 +:1095D000BDF83810504681420CD19DF81D10216015 +:1095E0009DF81C1001F00F0161609DF81E1001F044 +:1095F0000F01A160BDF83C10814201D10899E160E2 +:10960000BDF84010514501D1099820610127761C11 +:10961000F6B2032E01D2002FAED014B0BDE8F08711 +:1096200070B586B0284E04466D46B43614212846DF +:1096300000F0D6FF002156F8210045F82100491C12 +:109640000529F8D300982060019860600298C0B2A4 +:10965000A0600398C0B2E0600498C0B2206106B078 +:1096600070BD1CB50020184A009030326B46014690 +:10967000019052F8214043F82140491C0229F8D3B7 +:10968000BDF80010A1F5AA42AA3A0AD1BDF80420FB +:10969000114206D19DF802109DF80620114200D11A +:1096A00008461CBD00F01F020121914040098000C6 +:1096B00000F1E020C0F880127047B0F5803F01D281 +:1096C0000020704701207047AC1E04005C000D6054 +:1096D0004FF00050002180F83D1080F83E1080F8D7 +:1096E0003F103F2280F8322000F8301F0271417194 +:1096F0004270017241728172C172C17170474FF044 +:109700000052062817D2DFE800F00306090F171AE7 +:1097100012F83D0F04E012F83D0F07E012F83E0F7B +:1097200020F00F00084305E012F83E0F20F0F00093 +:1097300040EA01101070704712F83F0FF0E712F87E +:109740003F0FF3E730B50D4601218140CCB2002137 +:10975000FFF7D5FF29784FF00050002990F832101C +:1097600001D0214300E0A14380F83210697800293C +:1097700090F8301001D0214300E0A14380F8301070 +:10978000A978002990F8341001D0214300E0A143CA +:1097900080F83410E978002990F8351001D0214381 +:1097A00000E0A14380F835102979002990F83110A4 +:1097B00001D0214300E0A14380F83110002180F85E +:1097C000381080F8391080F83A1080F83B1080F893 +:1097D000371030BD774A1160764A0021343211606B +:1097E000121D08B11160704701201060704730B53C +:1097F00001248440E0B24FF000540029039D94F806 +:10980000321001D0014300E0814384F8321094F813 +:1098100030100AB1014300E0814384F8301094F81D +:1098200034100BB1014300E0814384F8341014F884 +:10983000351F0DB1014300E08143217030BD01238C +:109840008340D8B24FF00053002993F8381001D06C +:10985000014300E0814383F8381013F8391F0AB13F +:10986000014300E081431970704701238340D8B25F +:109870004FF00053002993F83A1001D0014300E063 +:10988000814383F83A1013F83A1F0AB1014300E00C +:109890008143197070472DE9F04705460120A84023 +:1098A000C4B21F46914688460A20DDF820A000F089 +:1098B0006BF80B2000F068F80A2000F070F80B201D +:1098C00000F06DF84FF0005696F83800A04386F887 +:1098D000380096F83A00A04386F83A0096F82E0031 +:1098E000A04386F82E00344A0020B8F1000F42F859 +:1098F00025000BD096F83810214386F8381096F8DA +:109900003A10214386F83A1042F8257096F839103B +:10991000A14386F8391096F83B10A14386F83B1016 +:1099200096F82F10A14386F82F1023492031B9F162 +:10993000000F41F825000BD096F83900204386F837 +:10994000390096F83B00204386F83B0041F825A0FB +:1099500096F8380010B10A2000F00BF896F839009C +:10996000002804D0BDE8F0470B2000F002B8BDE8A5 +:10997000F08700F01F02012191404009800000F1B2 +:10998000E020C0F80011704700F01F020121914053 +:109990004009800000F1E020C0F88011704700F01D +:1099A0001F02012191404009800000F1E020C0F831 +:1099B000801270470405002284A010002DE9F047B2 +:1099C000417ACA074FF0000101D0554A5160012782 +:1099D0007D0785F8E57085F8E470C5F8C010C5F816 +:1099E000E81085F8E11085F8E310DFF838A1067A71 +:1099F00004680AF10709072E00D9072600216DE047 +:109A00004A1CD3B201EB810214F802800AF80180EB +:109A1000D0F804C022443CF8118029F8118092F853 +:109A200003C0BCF1010F02D0BCF1030F07D195F8C0 +:109A3000E5C007FA03F84CEA080C85F8E5C090F891 +:109A400009C05FEACC7C0FD192F803C0BCF1020FD1 +:109A500002D0BCF1030F07D195F8E4C007FA03F870 +:109A60004CEA080C85F8E4C001EB410C21F0010838 +:109A7000E04492F801C00CF0070C0CFA08FCD5F891 +:109A8000C0804CEA080CC5F8C0C092F802C04FEA8A +:109A900081080CF00F0C0CFA08FCD5F8E8804CEAB1 +:109AA000080CC5F8E8C090F809C05FEACC7C14D176 +:109AB0001279D20707D095F8E12007FA03FC42EAB1 +:109AC0000C0285F8E1202279D20606D595F8E3202C +:109AD00007FA03F31A4385F8E320491CB1428FD3F8 +:109AE000D5F8E8006864BDE8F0870E4AD21D22F878 +:109AF0001010704710B504460B48006838B1A068D4 +:109B0000FFF75CFF2068BDE8104000F00FB8E06888 +:109B1000FFF754FF6068BDE8104000F0C1BB0000D3 +:109B200000200022AB000020BC05002210B5494BEC +:109B30000168002499608188598002899A801C708C +:109B40004FF00053A3F81A21A3F81E11C088A3F800 +:109B5000200141480122C0F8D821C0F8DC21C0F81A +:109B6000C421C0F8CC21C0F8D42172B6D0F80812B4 +:109B70000029FBD1426062B610BD2DE9F041364D9F +:109B8000D5F85C01334F2E040124BA6840B3B6F80F +:109B90001C815FEA08000CD0D5F8540148B1414659 +:109BA00001209047C5F8D842D5F8540108B1C5F84E +:109BB000D442BA684146022090470178022902D077 +:109BC000032902D008E0418800E07988A6F81E1138 +:109BD0008088A6F81A013C70C5F8DC42BDE8F08127 +:109BE000D5F8440180B1B6F81C11032090473878AD +:109BF00038B17888A6F81E01B888A6F81A010020A6 +:109C00003870C5F8C442E9E7D5F8580130B1B6F864 +:109C10001C1101209047C5F8D842DFE7D5F84C0168 +:109C200018B9D5F854010028D8D0B6F81C1119B1CC +:109C300001209047C5F8D842D5F84C0110B1C5F8BD +:109C4000CC42CBE7D5F854010028C7D0C5F8D442A0 +:109C5000C4E700007408100000200022FC49002026 +:109C60000860091D0860091D0860091D0860091DBC +:109C70000860091D0860091D0860091D0860F54994 +:109C800001220A60F34914310860510701F8500FAE +:109C9000FF234B7001F8050C10234B808A80EE499E +:109CA000086048608860C860086148618861C86170 +:109CB000086270477047E84A1160E54900220A606F +:109CC00000EB80004FF6FF7202EA40004FF00052B6 +:109CD000A2F85800012008607047DF4B10B5DC4A3D +:109CE0001960002111604FF0005191F85140E407D4 +:109CF00007D01B6A58438009A1F858000120106062 +:109D000010BD00EBC00303EB00104FF6FF7303EA36 +:109D10008000F1E74FF00050B0F858007047CC4990 +:109D2000002008607047CC4A10B50021106811600F +:109D3000C74A116010B1BDE8104000470020FFF78E +:109D4000B9FF10BDC44A5160C1490022091D0A6013 +:109D500000EB80004FF6FF7202EA4000CA06A2F84C +:109D60005A00012008607047BB4B10B55960B84AD3 +:109D70000021121D1160D10691F85140A40708D4AA +:109D800000EBC00303EB00104FF6FF7303EA800003 +:109D900002E01B6A58438009A1F85A0001201060B4 +:109DA00010BD4FF00050B0F85A007047A84900208D +:109DB000091D08607047A84A10B50021506851601D +:109DC000A34A121D116010B1BDE8104000470120E8 +:109DD000FFF770FF10BDA04A91609D490022083135 +:109DE0000A6000EB80004FF6FF7202EA40008A062C +:109DF000A2F85C00012008607047974B10B599608D +:109E0000934A002108321160910691F8514064078D +:109E100008D400EBC00303EB00104FF6FF7303EA16 +:109E2000800002E01B6A58438009A1F85C00012011 +:109E3000106010BD4FF00050B0F85C0070478449CE +:109E40000020083108607047834A10B500219068EF +:109E500091607F4A0832116010B1BDE810400047A0 +:109E60000220FFF727FF10BD7B4AD160784900220E +:109E70000C310A6000EB80004FF6FF7202EA4000EE +:109E80004FF00052A2F85E00012008607047724B4C +:109E900010B5D9606E4A00210C3211604FF00051AC +:109EA00091F85140240708D400EBC00303EB0010E5 +:109EB0004FF6FF7303EA800002E01B6A58438009F3 +:109EC000A1F85E000120106010BD4FF00050B0F806 +:109ED0005E0070475E4900200C31086070475E4AA2 +:109EE00010B50021D068D160594A0C32116010B110 +:109EF000BDE8104000470320FFF7DCFE10BD564AC6 +:109F000011615349002210310A6000EB80004FF6C6 +:109F1000FF7202EA40004FF00052A2F860000120F8 +:109F2000086070474C4B10B51961494A0021103246 +:109F300011604FF0005191F85140E40608D400EB55 +:109F4000C00303EB00104FF6FF7303EA800002E04A +:109F50001B6A58438009A1F860000120106010BD01 +:109F60004FF00050B0F860007047394900201031C0 +:109F700008607047384A10B5002110691161344AF1 +:109F80001032116010B1BDE8104000470420FFF707 +:109F900091FE10BD304A51612D49002214310A60F2 +:109FA00000EB80004FF6FF7202EA40004FF00052D3 +:109FB000A2F86200012008607047274B10B5596174 +:109FC000234A0021143211604FF0005191F85140A2 +:109FD000A40608D400EBC00303EB00104FF6FF7398 +:109FE00003EA800002E01B6A58438009A1F862007E +:109FF0000120106010BD4FF00050B0F862007047B3 +:10A0000013490020143108607047134A10B500212D +:10A01000506951610E4A1432116010B1BDE8104010 +:10A0200000470520FFF746FE10BD0B4A9161084925 +:10A03000002218310A6000EB80004FF6FF7202EA3E +:10A0400040004FF00052A2F8640001200860704701 +:10A0500040090022C0040022800810006A4B10B59D +:10A060006A4A9961002111604FF0005191F8514006 +:10A07000640608D400EBC00303EB00104FF6FF7337 +:10A0800003EA800002E01B6A58438009A1F86400DB +:10A090000120106010BD4FF00050B0F86400D6E70A +:10A0A0005A4900200860D2E7574A10B5002190694C +:10A0B0009161564A116010B1BDE81040004706207A +:10A0C000FFF7F8FD10BD10B5FEF77CFF4FF0005113 +:10A0D00091F8222042F21073B0FBF3F0C2F3810238 +:10A0E000521CD040B1F85420C96C51438909B0FBCF +:10A0F000F1F010BD45490022091D0A60424A126A6A +:10A1000050434FF000528009A2F866000120086019 +:10A110009DE73E490020091D086098E73A49C8615B +:10A120003B490120C1F8DC003849A0310860091D15 +:10A1300008608CE7344A10B50020D169D061344AF8 +:10A14000C2F8DC0051B1314AA03210604FF000502B +:10A15000C06CBDE8104020F07F400847FF20FFF7AB +:10A16000A9FD10BD10B50446FEF72CFF4FF00051BD +:10A1700091F8221042F21072B0FBF2F0C1F38101AB +:10A18000491CC8400003B0FBF4F01F49086210BD31 +:10A1900030B54FF000550124844095F8510009B1C5 +:10A1A000204300E0A04385F8510095F84B000AB128 +:10A1B000204300E0A04385F84B0015F8500F0BB189 +:10A1C000204300E0A043287030BD4FF0005010F84D +:10A1D0004A1FC079814301D0012038E7002036E7CB +:10A1E0004FF0005090F82200C0F3810028B1012800 +:10A1F00005D0022805D0074829E7074827E7074880 +:10A2000025E7074823E700008008100058090022CE +:10A210000000602200093D000048E8010024F4002D +:10A2200000127A00002101600846704730B50A68C4 +:10A2300012B10B46846A08E000220860C0E90321DD +:10A240000AE002F10C03D26812B1956AA542F8DC6B +:10A250001A68C0E903211860002030BD00680022A0 +:10A2600001E0C068521C8A4201D00028F9D1704731 +:10A270000068704702690AB1116831B96FF00400D3 +:10A28000704701F10C02C96839B18142F9D1C9683E +:10A29000116000210161084670476FF003007047AC +:10A2A000017C31B14FF0005111F82D2F42F0020224 +:10A2B0000A70194902680A6042684A6082688A60C6 +:10A2C000C068C860704730B44FF0005111F8E00F1B +:10A2D0000A8AC968104BC40708D09B68002B0BD0B2 +:10A2E000A2F57F44FF3C07D030BC1847DB68002B49 +:10A2F00002D0521C92B2F7E730BC70474FF00050CA +:10A3000090F8E2000449C20701D0096800E04968FA +:10A31000002900D008477047B808100053EA020C23 +:10A3200000F069802DE9F04B4FF00006002B1FBFB5 +:10A33000B3FA83F503FA05F424FA05F65E4012BF7A +:10A340001643B2FA82F502FA05F4C5F120051EBFE4 +:10A3500022FA05FC44EA0C04203556EA044C4FEA84 +:10A36000144418BF641C4FF000084FF000099042DD +:10A3700071EB030C39D3002919BFB1FA81F701FA47 +:10A3800007F6B0FA80F700FA07F6C7F120071EBFFC +:10A3900020FA07FC46EA0C062037B6FBF4FCA7EBD4 +:10A3A0000507103F07F01F0BCBF120060CFA0BFB43 +:10A3B0002CFA06F644BFB3460026202FA4BF5E4603 +:10A3C0004FF0000B5BEA060C08BF4FF0010B19EBD6 +:10A3D0000B09ABFB027C48EB0608C01B06FB02CC5A +:10A3E0000BFB03CC71EB0C01C1E70B460246414667 +:10A3F0004846BDE8F08B13B54FF000004FF0000168 +:10A40000AFF30080BDE81C407047B2F120030AD5CD +:10A41000C2F1200301FA02F120FA03F300FA02F07C +:10A4200041EA0301704700FA03F14FF00000704762 +:10A43000B2F120030AD5C2F1200320FA02F001FA9A +:10A4400003F321FA02F140EA0300704721FA03F016 +:10A450004FF00001704710B54C1084EA530404D546 +:10A460004042C1F1000138BF491E1B4204D552428F +:10A47000C3F1000338BF5B1EFFF750FF14F0804F9D +:10A4800004D04042C1F1000138BF491E14F0004F12 +:10A4900004D05242C3F1000338BF5B1E10BD032A33 +:10A4A00040F2308010F0030C00F0158011F8013BF1 +:10A4B000BCF1020F624498BF11F801CB00F8013BD8 +:10A4C00038BF11F8013BA2F1040298BF00F801CB9C +:10A4D00038BF00F8013B11F0030300F02580083A73 +:10A4E000C0F0088051F8043B083A51F804CBA0E8CA +:10A4F0000810F5E7121D5CBF51F8043B40F8043B1F +:10A50000AFF30080D20724BF11F8013B11F801CB53 +:10A5100048BF11F8012B24BF00F8013B00F801CB24 +:10A5200048BF00F8012B704710B5203AC0F00B80EF +:10A53000B1E81850203AA0E81850B1E81850A0E847 +:10A540001850BFF4F5AF5FEA027C24BFB1E81850A1 +:10A55000A0E8185044BF18C918C0BDE810405FEA11 +:10A56000827C24BF51F8043B40F8043B08BF70478D +:10A57000D20728BF31F8023B48BF11F8012B28BF92 +:10A5800020F8023B48BF00F8012B704702F0FF03A0 +:10A5900043EA032242EA024200F002B84FF000020E +:10A5A0000429C0F0128010F0030C00F01B80CCF1E5 +:10A5B000040CBCF1020F18BF00F8012BA8BF20F853 +:10A5C000022BA1EB0C0100F00DB85FEAC17C24BFA7 +:10A5D00000F8012B00F8012B48BF00F8012B704751 +:10A5E0004FF0000200B5134694469646203922BF2C +:10A5F000A0E80C50A0E80C50B1F12001BFF4F7AF77 +:10A60000090728BFA0E80C5048BF0CC05DF804EB58 +:10A61000890028BF40F8042B08BF704748BF20F8C6 +:10A62000022B11F0804F18BF00F8012B704710B5B6 +:10A630000446AFF300802046BDE81040E5F7EEBDCC +:10A6400001491820ABBEFEE726000200704700005B +:10A650000149002008607047380500222DE9F041CB +:10A660000F4F00244FF001084FF0005608FA04F095 +:10A67000C5B296F82F0028420CD096F8390028422F +:10A6800008D057F8240000B1804796F82F00A8435F +:10A6900086F82F00641C062CE8DBBDE8F081000082 +:10A6A000A4A010002DE9F0410F4F00244FF0010845 +:10A6B0004FF0005608FA04F0C5B296F82E00284272 +:10A6C0000CD096F83800284208D057F8240000B182 +:10A6D000804796F82E00A84386F82E00641C062CAE +:10A6E000E8DBBDE8F081000084A01000012181407A +:10A6F000C8B24FF0005191F83310014201D001204F +:10A700007047002070470000014901200860704731 +:10A710003805002200487047E50710000549044A43 +:10A720000A80054AC0E90021012101724172704787 +:10A73000185701208807100074A90100014800780B +:10A7400070470000B0061000014800787047000014 +:10A750009005100006488178012905D80178012963 +:10A7600002D84078012801D90120704700207047A5 +:10A770009826012005488178012902D8007801280F +:10A7800001D9012070470020704700009826012061 +:10A7900070B5D0E9001253084FEA31044E1842EB6D +:10A7A000020534432B430C431343C0E9004370BDFF +:10A7B00001EB810100EBC10029307047024A127899 +:10A7C000514300EB410070472507100001EB810168 +:10A7D00000EBC10029307047024A1278514300EB68 +:10A7E0004100704725071000010000001000000024 +:10A7F00004000000010000003200000032000000F0 +:10A80000FFFF000000FF0100FF0000010000010148 +:10A810005AD3D9E96CF145F59FF73CF96CFA58FB2E +:10A8200018FCB9FC44FDBFFD2EFE94FEF4FE50FF63 +:10A83000A9FF00005700B0000C016C01D2014102D9 +:10A84000BC024703E803A8049405C4066108BB0AD8 +:10A85000940E2716A62C0100010001000100020041 +:10A8600001000100010001000A00FF00FF000000DC +:10A870000001010102020000000000009C531000D2 +:10A88000E8581000A932010002000000AD320100BA +:10A8900002000000373401000200000075320100A0 +:10A8A00002000000E5330100010000003733010021 +:10A8B00007000000D7320100090000000734010042 +:10A8C00001000000F3320100080000006F340100B5 +:10A8D000010000008734010001000000793201000E +:10A8E00003350100FF34010005360100FF3401008B +:10A8F0004F370100FF340100FF340100FF34010035 +:10A90000FF340100FF3401004F3501000100000059 +:10A910007D35010000000000FF3401000000000050 +:10A920009B350100010000003536010001000000E8 +:10A9300059360100010000005D36010001000000F1 +:10A9400093360100040000004B37010001000000B5 +:10A950007F37010001000000F33701000100000013 +:10A960000938010002000000653801000200000003 +:10A97000AF38010002000000DB39010001000000D7 +:10A980001B3A010001000000AB380100020000008A +:10A99000A339010002000000FF34010000000000A4 +:10A9A0007B39010002000000993701007335010076 +:10A9B000A3370100B3370100C3370100D3370100CB +:10A9C000E33701008600020100A6020F0300A8027F +:10A9D0000B0300000300000000000000530400000F +:10A9E0000000000003000000000000005300000011 +:10A9F000000000004300000000000000F300000021 +:10AA000000000000E300000000000000530200000E +:10AA10000000000000000000050000005884100045 +:10AA2000000400004D3D0000000000000200000096 +:10AA3000010000000400000058881000000400001D +:10AA4000C54C0000000000000200000002000000F1 +:10AA500003000000588C10000008000025300100A1 +:10AA600000000000020000000300000002000000DF +:10AA70005894100000020000D93A010000000000C4 +:10AA800002000000040000000100000058961000C1 +:10AA900080000000E1310100000000000200000021 +:10AAA00000000000010000000100000001000000A3 +:10AAB000020000000100000003000000010000008F +:10AAC000040000000100000005000000010000007B +:10AAD0000000000001000000020000000300000070 +:10AAE0004F810100597001000967010009700100E0 +:10AAF0005D6D0100E76C0100BF6F01000B7D01007F +:10AB0000658101000004400010210000001F0100C9 +:10AB1000060000003000010000040600080250009A +:10AB200060020C0C000060020C300C1A31100F0F88 +:10AB300000002F000100AA2C01000000030000000B +:10AB4000FFFF03000000000018000000FFFFFFFFF0 +:10AB50003F000000000000000001000000000000B5 +:10AB6000600201800001000000000C000C000C00DD +:10AB70000C00070126261212110000000038003CCC +:10AB8000203DD041EC4108421C42304244426042E8 +:10AB900074428842A442000000000000000000004F +:10ABA0000000000000000020000101020102020379 +:10ABB0000102020302030304000000001B000080E6 +:10ABC0002D00008036000000410000805A00000087 +:10ABD0006C00000077000080990000808200000077 +:10ABE000B4000000AF000080D8000000C300008067 +:10ABF000F5000080EE000000290100803201000015 +:10AC0000040100001F010080680100007301008042 +:10AC1000450100805E010000B0010000AB01008032 +:10AC20009D01008086010000F1010080EA01000022 +:10AC3000DC010000C70100804902008052020000D0 +:10AC4000640200007F0200800802000013020080FE +:10AC5000250200803E020000D0020000CB020080EE +:10AC6000FD020080E6020000910200808A020000DE +:10AC7000BC020000A7020080600300007B0300808C +:10AC80004D03008056030000210300803A030000BA +:10AC90000C03000017030080F9030080E2030000AA +:10ACA000D4030000CF030080B8030000A30300809A +:10ACB000950300808E030000890400809204000048 +:10ACC000A4040000BF040080C8040000D304008076 +:10ACD000E5040080FE040000100400000B04008066 +:10ACE0003D04008026040000510400804A04000056 +:10ACF0007C04000067040080A0050000BB05008004 +:10AD00008D05008096050000E1050080FA05000031 +:10AD1000CC050000D7050080390500802205000021 +:10AD2000140500000F050080780500006305008011 +:10AD3000550500804E050000C0060000DB060080BF +:10AD4000ED060080F6060000810600809A060000ED +:10AD5000AC060000B70600805906008042060000DD +:10AD6000740600006F0600801806000003060080CD +:10AD7000350600802E060000E9070080F20700007B +:10AD8000C4070000DF070080A8070000B3070080A9 +:10AD9000850700809E070000700700006B07008099 +:10ADA0005D07008046070000310700802A07000089 +:10ADB0001C07000007070080090900801209000035 +:10ADC000240900003F090080480900005309008061 +:10ADD000650900807E090000900900008B09008051 +:10ADE000BD090080A6090000D1090080CA09000041 +:10ADF000FC090000E7090080200800003B080080F3 +:10AE00000D08008016080000610800807A08000024 +:10AE10004C08000057080080B9080080A208000014 +:10AE2000940800008F080080F8080000E308008004 +:10AE3000D5080080CE080000400B00005B0B0080AE +:10AE40006D0B0080760B0000010B00801A0B0000D8 +:10AE50002C0B0000370B0080D90B0080C20B0000C8 +:10AE6000F40B0000EF0B0080980B0000830B0080B8 +:10AE7000B50B0080AE0B0000690A0080720A00006A +:10AE8000440A00005F0A0080280A0000330A00809C +:10AE9000050A00801E0A0000F00A0000EB0A00808C +:10AEA000DD0A0080C60A0000B10A0080AA0A00007C +:10AEB0009C0A0000870A0080800D00009B0D008026 +:10AEC000AD0D0080B60D0000C10D0080DA0D000050 +:10AED000EC0D0000F70D0080190D0080020D000040 +:10AEE000340D00002F0D0080580D0000430D008030 +:10AEF000750D00806E0D0000A90C0080B20C0000E2 +:10AF0000840C00009F0C0080E80C0000F30C008013 +:10AF1000C50C0080DE0C0000300C00002B0C008003 +:10AF20001D0C0080060C0000710C00806A0C0000F3 +:10AF30005C0C0000470C0080C90F0080D20F00009D +:10AF4000E40F0000FF0F0080880F0000930F0080C7 +:10AF5000A50F0080BE0F0000500F00004B0F0080B7 +:10AF60007D0F0080660F0000110F00800A0F0000A7 +:10AF70003C0F0000270F0080E00E0000FB0E008059 +:10AF8000CD0E0080D60E0000A10E0080BA0E00008B +:10AF90008C0E0000970E0080790E0080620E00007B +:10AFA000540E00004F0E0080380E0000230E00806B +:10AFB000150E00800E0E000098AF01000004100076 +:10AFC000C80400001C01000000B0010000FC1000DB +:10AFD000400000007801000000B00100C808100027 +:10AFE000FC9700009401000001FF014A0022481074 +:10AFF000070C1502050609040E08030B1218130DA1 +:10B000001416171A0F111B1D191C201E1F010A21CF +:10B0100012FF3206320F9A37089AE10823D303143D +:10B02000905F017201A908091A0CB264290C291455 +:10B030005A02040A11041001FF01660799F0012069 +:10B040001C6210AAFF0C5901011D045490D003008A +:10B0500030B572B601230C4D2B600C4A002481B12F +:10B0600013604FF0005100F01F0081F86A0007489C +:10B070001C38036001680029FCD114602C6062B6A2 +:10B0800030BD1460EDE70000C01B0022780D0022E7 +:10B09000DBD3C21951030000242C3DE6AEFCFFFFB8 +:10B0A0000000070003070000071200000000000076 +:10B0B000F8FFFFFF3F000000FFFF0000000000005E +:10B0C0002310230937040B2309370444020103002A +:10B0D0000320200AAA99FA00FA00B004C80000016F +:10B0E0000001000100017000700009C800C80000E4 +:10B0F000000000960096000000000003AA44020031 +:10B100000015080A190FF902320000000016001E8F +:10B11000000008000600000000A050502601350085 +:10B12000000000001300000000009603000064000F +:10B130000000FF00E02E01FF000000004050007002 +:10B140000032004000C80000000001640064006498 +:10B15000001000000000000000FFFF0000BDA00A7A +:10B160004F2500260025004B600600000000004B24 +:10B1700060160000000004014B024B06008D110810 +:10B180004F0400300006002F0040100600000001B0 +:10B190000000A8606A1F200036002700500026002B +:10B1A000A023A0132D0066000000000000029600FE +:10B1B000960002050132190500001D040000000080 +:10B1C000010000002D0000008F00000000000000C2 +:10B1D0000000000000010100003030008F0000007E +:10B1E000000000000000000000010030010000002D +:10B1F000000F0000000000000000111A0000000015 +:10B2000000036402130A0403070B02023210000059 +:10B210000000000F0000000000FF0FFF0F0A141EC7 +:10B220000E01640001016400001400000A005000D7 +:10B23000000000D00F149001900180008000F40104 +:10B240000000FA086400640020000A6400640064DE +:10B2500000640003052C01F40100C2018A026400AD +:10B260009600031B039600FA00FA0001010100E8B2 +:10B2700003DC05C800FA00020B02FA00F401F40135 +:10B28000000101003B0164006400B4002C012C01AA +:10B2900005FCA121025E01640096F4013200F40174 +:10B2A000960096006400010096009600030E64006C +:10B2B000200058023214001E2003042C01960000C6 +:10B2C000000000008F01100050004000A00000A40A +:10B2D0000F28009600C800320096002300C800C85E +:10B2E00000C800F40123005000041004020105000E +:10B2F000C800C4090000310010FF7F5E01A00FD01C +:10B3000002D002080708070807000000000000003C +:10B310000D42200010122C012C019D00000A000F8C +:10B320006400411278009600C800C80000B004FA1A +:10B330000096B80BE8030000000001006400070D50 +:10B340000DE803A000005E01645E016400000000DF +:10B35000250B01008A028A02408A02C201F4010020 +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000008C001E2803050202EF +:10B380000213115546000003C8006432001E066413 +:10B390001E5E01012800F401FAF4010069F7EA00D9 +:10B3A000D4013801EA006400040C03320302400AAD +:10B3B000039C009C000F000F00109D004E00C80071 +:10B3C0000001010011000100101F00000A0014918B +:10B3D0001514001000061000060040000040001088 +:10B3E0000A0F0A200310EB0520D80532F80A32F8BC +:10B3F0000000EAECECC4E810003000CBE80A0018CA +:10B4000000C6F80A000A0051E494941844070007A3 +:10B41000001000300002D73A7E2858026400C800AD +:10B4200000015A005A005000500001000015151587 +:10B4300015008164643C042C01401FE80390012F37 +:10B44000000405401F9001BC02B60301B603028848 +:10B4500013000000000000000000000000000000D9 +:10B460000000000000000300020A3C0001020F0F70 +:10B470002323083C083C40F805050A0A0105050F8E +:10B48000140000014E0C09180C0C222222000000AE +:10B490000000000A00140032006400BF08F1080F29 +:10B4A00009190923092309000000000A00140032C9 +:10B4B000006400D303050423042D0437043704007B +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000100090020004500DD20 +:10B4E00008070919091F09230923090000000002A0 +:10B4F000000A0028005600E80314042C0434043722 +:10B5000004370400000000000000000000000000FC +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B620000008000000000000000000000000000012 +:10B630000004000000A4060000000000000000005C +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B00000000000000000A8A02A1F20003600277C +:10B6C0000050002600A023A0132D006600000000FB +:10B6D00000000000005028502814B020A0D0000620 +:10B6E00014142A3A400000146E6E471A38010F1ED7 +:10B6F000002000000FE80A0030000F510000000099 +:10B7000004640010FF7F0B646400000A201405F835 +:10B71000000000000006080F160672390002F5E16D +:10B72000826E4632020000960000960000960000ED +:10B730005AE0005AE0000000000000000000000095 +:10B7400000007B007B007D00800085008A00910066 +:10B750009900A300AD00B900C500D300E200F200DB +:10B760000301160129013D01520167017E01960185 +:10B77000AE01C701E001FA01150230024C02680275 +:10B780008502A202BF02DD02FA0218033603530348 +:10B7900071038F03AC03CA03E703030420043C04D2 +:10B7A000570472048D04A704C004D904F0040705EB +:10B7B0001E05330548055B056E057F0590059F0551 +:10B7C000AE05BB05C705D205DC05E505EC05F305AF +:10B7D000F805FB05FE05FF05FF05FE05FB05F80561 +:10B7E000F305EC05E505DC05D205C705BB05AE058F +:10B7F0009F0590057F056E055B05480533051E0511 +:10B800000705F004D904C004A7048D04720457048A +:10B810003C0420040304E703CA03AC038F03710351 +:10B82000530336031803FA02DD02BF02A2028502A7 +:10B8300068024C0230021502FA01E001C701AE01B4 +:10B8400096017E01670152013D01290116010301A4 +:10B85000F200E200D300C500B900AD00A3009900DA +:10B8600091008A00850080007D007B007B00000045 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B9000000007B007D0082008B009700A600B9003C +:10B91000CF00E80005012401450169019001B9014A +:10B92000E3010F023D026C029C02CD02FF023103D3 +:10B9300062039403C503F603250454048104AC0494 +:10B94000D604FE0423054605660584059F05B60555 +:10B95000CB05DC05EA05F405FB05FF05FF05FB0546 +:10B96000F405EA05DC05CB05B6059F0584056605EB +:10B9700046052305FE04D604AC04810454042504C2 +:10B98000F603C503940362033103FF02CD029C0258 +:10B990006C023D020F02E301B9019001690145010A +:10B9A00024010501E800CF00B900A60097008B0034 +:10B9B00082007D007B00000000000000000000000D +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000500050000AC +:10BA900032460000000000000000000047B400C86B +:10BAA00000010A00000096006400B400010AB4001E +:10BAB0006400010AB80BC409050200F401F4010591 +:10BAC000022003C80028000A0050003200000000D5 +:10BAD0000200020001280102010204020102010029 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000010000F4 +:10BB50000000000000000000010000B80B052602F4 +:10BB60002C01C800FA000003E8038001E8018813F3 +:10BB7000B80B400F400F0000204E0514003C1E4043 +:10BB80001F000000D007F4012C0100011400CD01BA +:10BB9000094F05003C000200230045600603030036 +:10BBA0000000FFBB0000C8008D00091F08002A012B +:10BBB0000200290128A00600000000000000004D3E +:10BBC0003D3D3E3E3F404040404243434444454665 +:10BBD00046474848494A4B4B4B4C4B4C4D4E4E4CBC +:10BBE00061000000004D403F40414345444545460B +:10BBF000474749494A4B4B4C4D4D4E4F5050505181 +:10BC000050505152525561000000004D3D3D3E3EA6 +:10BC10003F414142424445454748494A4B4C4D4EBD +:10BC20004E4F5050505150505151525264000000EC +:10BC3000004D4343434445474847484A4B4B4D4DCD +:10BC40004E505052535354555656555555545555BC +:10BC5000555764000000004B383837373739393AC8 +:10BC60003A3C3D3D3E3E3E3F3F40404041424343E3 +:10BC7000434442424343434258000000004B3F3D8F +:10BC80003F3E3F414140414243424545464546478C +:10BC9000474748494A4A494A4748494A494C58004F +:10BCA0000000001415072108210000000001000019 +:10BCB0000001000101000001010105010000010077 +:10BCC000010000010000010100010000010100006D +:10BCD000C8B60181029D066D071E0A141E0A1400D3 +:10BCE0000100C8AA018E020B07EF07461246120A8E +:10BCF0000C0C00200A0A00000000000000000000F8 +:10BD0000310096001E28000000051E00FA00000009 +:10BD1000500A052806640A02C80000030090016466 +:10BD2000FA00C000000004100A00100000961E0077 +:10BD30000F6414000000000000000000000000027A +:10BD400002505000460AC800100400000000000025 +:10BD50000001800CF00AD000800CF00AD000001521 +:10BD6000001250015001001500125001800CF00A21 +:10BD7000D0000000000000009600F4010003C8009D +:10BD80002F07C8006F03106464C80064001000101F +:10BD9000001096006400960064009600640096000F +:10BDA000640010000000000000000000000000001F +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:0CBDD000000000000000000043C6B0E2CC +:00000001FF diff --git a/firmware/st_fts_j2a_csot.ftb.ihex b/firmware/st_fts_j2a_csot.ftb.ihex new file mode 100644 index 000000000000..ea2e2b37c786 --- /dev/null +++ b/firmware/st_fts_j2a_csot.ftb.ihex @@ -0,0 +1,6948 @@ +:1000000055AA55AA01000000363900004723000018 +:100010005200000000000000040000001C0102016A +:1000200000000000041300000000000090A4010084 +:10003000480D000000000000000000007B3950D88F +:100040005C570D5323690000A3A8F2ACDC96FFFFB8 +:1000500000041000E101000039020000530200001A +:100060006D02000087020000A102000000000000F5 +:1000700000000000000000000000000013760100F6 +:100080001B76010000000000BB0200002376010087 +:100090002B76010037760100437601004F76010090 +:1000A0005B76010067760100737601007F760100C0 +:1000B0008B760100C902000097760100A37601004B +:1000C000AF760100B7760100BF760100C776010068 +:1000D000D3760100DB760100E3760100000000002A +:1000E000000000000000000000000000EB760100AE +:1000F000F376010000000000FB7601000000000024 +:1001000000000000000000000000000000000000EF +:10011000520047231100FFFF1C01020100000000F4 +:1001200000000000000000000000000000000000CF +:1001300000F002F800F068F80AA090E8000C824491 +:100140008344AAF10107DA4501D100F05DF8AFF26E +:10015000090EBAE80F0013F0010F18BFFB1A43F0A5 +:100160000103184794A20100C4A201000A444FF001 +:10017000000C10F8013B13F0070408BF10F8014B06 +:100180001D1108BF10F8015B641E05D010F8016B4B +:10019000641E01F8016BF9D113F0080F1EBF10F8AF +:1001A000014BAD1C0C1B09D16D1E58BF01F801CBD2 +:1001B000FAD505E014F8016B01F8016B6D1EF9D555 +:1001C0009142D6D370470000103A24BF78C878C156 +:1001D000FAD8520724BF30C830C144BF04680C604D +:1001E000704700000023002400250026103A28BF95 +:1001F00078C1FBD8520728BF30C148BF0B60704799 +:100200001FB51FBD10B510BDDFF80CD0FFF7F8FF0C +:1002100017F09EFA19F04BFC0004100003B4FFF72E +:10022000F1FF03BC19F04CFC40BA7047C0BA7047EC +:1002300012481349A1EB00014FF0200391FBF3F2A8 +:1002400002FB13114FF0CC334FF0CC344FF0CC35D0 +:100250004FF0CC364FF0CC374FF0CC384FF0CC3994 +:100260004FF0CC3AA0E8F807013AFBD119B140F8B9 +:1002700004AB0439FBD10348004700000000100024 +:1002800000041000E10000001EF0040F0CBFEFF3AB +:100290000880EFF309804FF001014FF0000213F0E6 +:1002A000B7B91EF0040F0CBFEFF30880EFF309801D +:1002B0004FF002014FF0000213F0AAB91EF0040F34 +:1002C0000CBFEFF30880EFF309804FF003014FF00C +:1002D000000213F09DB91EF0040F0CBFEFF308806D +:1002E000EFF309804FF004014FF0000213F090B9D2 +:1002F0001EF0040F0CBFEFF30880EFF309804FF0FE +:1003000005014FF0000213F083B900B517F0A2F910 +:100310005DF804EB00F032B81EF0040F0CBFEFF3F1 +:100320000880EFF309804FF006014FF0000213F050 +:100330006FB900000A484FF0FF0101704FF0000054 +:1003400080F311884FF0000080F3098805484FF0D2 +:100350000201017062B604484FF08051016070479D +:1003600022ED00E0A408100004ED00E002484FF088 +:10037000805101607047000004ED00E04FF0200064 +:1003800080F31188EFF3098098B112480068124990 +:100390000968884217D0EFF309800E49096820E9FF +:1003A000F00F886000B50B48006817F06DFA5DF833 +:1003B00004EB084808490A68026000688168B1E8EF +:1003C000F00F81F309884EF0040E4FF0000080F327 +:1003D00011887047A8081000AC081000EFF31180D6 +:1003E0004FF0200181F31188704700004FF00000AA +:1003F00080F311887047000062B6704772B670478C +:10040000401EFDD17047000010B501463C22FC485B +:1004100019F0CAFA0121BDE81040002017F06DBAAA +:1004200038B50546F748F64C2860284616F08CFF8C +:1004300000226B460121104617F0A8FA0121002086 +:1004400017F087FA2078002802D013F030F9ECE793 +:1004500038BD2DE9F14FEC4EEC4D82B030684FF0D5 +:10046000000990F8317090F830104F43297851B15D +:1004700090F86D1090F8BD0A01F00F08C00706D083 +:1004800085F8009003E090F86C0000F0030801206C +:1004900000FA08FADE4CB9002046009119F0E0FAA3 +:1004A000DC484FF0010B00780190D748006890F8C5 +:1004B000BD1AC9071AD02978C1B9D7490978A9B98D +:1004C000D6490978052911D006290FD090F8750171 +:1004D000C0F30112C0F3810100F0030013F09FFF8D +:1004E000401C4FFA80FBCB4880F80090002636E095 +:1004F000C548006890F8311090F8300041430298E8 +:10050000714300EB41092046009919F0A9FA002532 +:1005100012E0BB483C30FFF783FFB94881680020F8 +:1005200007E054F8202031F910301A4444F8202014 +:10053000401CB842F5DB6D1C5545EADB384605E04A +:1005400054F8201041FA08F129F81010401EF7D293 +:10055000B0480178491C017011F031FC761C5E45F1 +:10056000C6DBAC4901980870BDE8FE4F11F027BC0E +:10057000A34810B53C3016F0C0FEA14907203C311D +:10058000A54C087101202070A548FFF762FF0020EC +:10059000207010BD2DE9F04F9C489B4B9FB0017817 +:1005A000186819B190F86D10090903E090F86C1003 +:1005B000C1F3810190F8315088464FF0010990F85D +:1005C000307009FA08FB924CE81981009A4604EB56 +:1005D0008506204619F044FA89483C3016F08DFE15 +:1005E000874A3C3282F80790DAF8000090F86B00F6 +:1005F000810701D582F80490C00703D080483C30C1 +:10060000FFF70EFF00202BE07D483C30FFF708FF8E +:10061000DFF8ECA16A0013A8DAF8201019F07FF9CE +:100620007A006846DAF8241019F079F9284613A9F7 +:1006300006E054F8202031F910301A4444F8202004 +:10064000401EF6D23846694606E056F8202031F9B9 +:1006500010301A4446F82020401EF6D209F101005D +:1006600081465845D0DB28466E4A05E054F82010F4 +:1006700041FA08F122F81010401EF7D238466A4AB3 +:1006800005E056F8201041FA08F122F81010401E3B +:10069000F7D26C0022466349644819F040F97D00A6 +:1006A0002A466149624819F03AF92146614819F031 +:1006B000B5F92946604819F0B1F91FB0BDE8F08FCF +:1006C0002DE9F04F504E85B0DFF848A13068504C0E +:1006D00090F831B010F8301F01910BFB01F59AF83A +:1006E0000010049190F84501C0F30112C0F381019C +:1006F00000F0030013F093FE401C40B2039040480A +:100700003C3016F0FAFD3E4801273C30C771306896 +:1007100090F86B00C00703D039483C30FFF780FEEB +:100720003A48007800283848006805D090F86D00F5 +:1007300000F00F09000905E090F86C0000F00309D3 +:10074000C0F38100012101FA00F001FA09F8014625 +:100750000090404613F06EFE02902E48002101707A +:1007600011F02DFB002674E0254800213C30464561 +:100770000171C17101DA0121017100998E4201DA22 +:100780000121C1711E483C30FFF74AFE1C48D0E9E8 +:100790000812876892461EB146451EDA28461AE0BE +:1007A0004FEA4B021F4819F0BAF80198514642002F +:1007B0001D4819F0B4F8284603E037F9101044F842 +:1007C0002010401EF9D243E054F8202037F91030B1 +:1007D0001A4444F82020401EF6D20098864237DAA8 +:1007E0005846104A07E032F9103031F910703B4496 +:1007F0005B1022F81030401EF5D20B49019825E01D +:10080000C8081000B9030000A40710007404100009 +:100810001C721000DC07100000041000F804100027 +:10082000D8570120047701202E770120700B01207A +:100830009A0B01205C0C0120860C012031F910304C +:100840003AF910201A44521021F81020401EF5D217 +:10085000761C0298864287DB284606E054F8201072 +:10086000664A41FA09F122F81010401EF6D2644897 +:10087000006890F8BD0AC0074BD062480078D8BB2A +:1008800061480078052844D0062842D001273DE081 +:100890005E48077011F093FA5948DFF874B10068A8 +:1008A00090F8311090F830004143794353480026C6 +:1008B00000EB410A1CE056483C30FFF7B1FDDBF885 +:1008C00008100EB1002010E0284603E031F9102096 +:1008D00044F82020401EF9D209E054F8202031F9D4 +:1008E00010301A4444F82020401CA842F5DB761C46 +:1008F0004645E0DB284606E00BE054F8201041FABC +:1009000009F12AF81010401EF7D27F1C0398874285 +:10091000BEDB3E490498087005B0BDE8F04F11F009 +:100920004EBA2DE9F0470446002017F086F8022061 +:1009300017F083F8032017F080F8364E002070700F +:1009400033483C3016F0D9FCDFF8B480324FDFF882 +:10095000CC90D8F800004FF0010590F86B008007AC +:100960004FEA04700AD500280FDAA00708D5757081 +:10097000FFF7A6FE3D7089F8005001E0002804DA78 +:10098000707810B9FFF706FE3D70214FA00707F100 +:100990003C0718D5707830BB384616F0AEFC3D7178 +:1009A000D8F8000090F8CE00000604D5174840782B +:1009B00038B1042038711148FFF74BFD89F8005019 +:1009C00011E00320F6E760070DD511483C3016F022 +:1009D00094FCD8F8000090F87100C00601D53D7174 +:1009E000E9E70720E6E7032017F042F8022017F0B6 +:1009F0003FF8BDE8F047002017F03AB8D85701207B +:100A0000A407100074041000F8041000DC071000A4 +:100A1000C808100000041000E3071000E2071000EF +:100A200070B55D4C4FF6FF7140F25235206841823F +:100A3000294617F0ADFD00211F200FF109F92A46C4 +:100A40002168BDE870401F23544817F0C8BD70B539 +:100A50005148534C4FF480650068417D20684174D3 +:100A6000294617F095FD00211C200FF1F1F82A46C8 +:100A70002168BDE870401C234A4817F0B0BD2DE93D +:100A8000F041494F041D0D462146384617F080FDC0 +:100A90002868464A00EB8401914201D21D2310E0F0 +:100AA00090420DD2111A8E0890461D2332463946C7 +:100AB00017F095FDA21B07EB86011E23404602E0BE +:100AC0001E232246394617F08AFD286800EB840071 +:100AD0002860BDE8F081F8B5334C354800901034FB +:100AE000022016F0AAFF00211D200FF1B1F800210D +:100AF0001E200FF1ADF81021204618F08FFF0020C6 +:100B00002080A0700120244DE0704FF6FF73A38079 +:100B100028680422018AE1808EB22649407D207235 +:100B2000A1F8F86EA1F8FA3E81F8FC0E694610466D +:100B3000FFF7A5FF012300222146102014F033FB0C +:100B40006946FFF79CFF012300222146112014F083 +:100B50002AFB6946FFF793FF286890F80012C9073F +:100B600003D190F8BA00C00708D001230022214623 +:100B7000122014F018FB6946FFF781FF01230022C1 +:100B80002146132014F00FFB6946FFF778FF02207F +:100B900016F06EFFF8BD0000A4071000F0EF010092 +:100BA000A8071000F0BF01001C721000F0DF010068 +:100BB000F0CF01007C7701200B4801785A2911D130 +:100BC0008188B1F57C7F0DD8418800290AD106497A +:100BD00040781031022805D0A0F17002072A01D810 +:100BE00012F02BBF704700000000012010B518F074 +:100BF0001DFB0021912012F04BFDFA4801210170EC +:100C0000C17010BD10B5F74C207800280BD1A0881A +:100C100050B1F548A1880068B0F8820688420AD32E +:100C2000A088401CA08010BDA088401CA08018F0A7 +:100C3000F8FAE08010BD18F0F4FA208118F0F6FA06 +:100C40000120207010BD70B5E64C00202070A080FF +:100C5000E08020810B2000F0FFF94FF0E0264FF4F8 +:100C60000065C6F88052E14941F28830843618F0B8 +:100C7000A9FAF56720780028FCD0E0882189401A7D +:100C800084B20B2000F0E8F9204670BD7047F8B53B +:100C900000242546D64817F053FAD34F0026009675 +:100CA00038683346012290F89400314600F007007E +:100CB00017F0DDFF3868002190F8940000F007007D +:100CC00017F05DFFCB48009038680023012290F8B0 +:100CD0009400194600F0070018F01DF8304600F0A7 +:100CE000C6F9FFF7B0FFBF4E7081F078012801D13F +:100CF0003220F8BD38687189B0F8840688420BD973 +:100D00000A34E4B2204600F0B2F9FFF79CFF6D1CF4 +:100D1000EDB27081142DEDD938687189B0F8840670 +:100D2000884203D90021922012F0B2FC00253868D5 +:100D30007189B0F8840688420BD8641EE4B220465C +:100D400000F095F9FFF77FFF6D1CEDB27081142D57 +:100D5000EDD938687189B0F88406884203D800213B +:100D6000922012F095FC17F0F7F92046F8BD10B567 +:100D700001463C22A04818F017FE0121BDE81040B2 +:100D8000002016F0BABD70B5044616F03AFF954D36 +:100D9000E86816F03BFFA4F876000420A070208ECF +:100DA0006FF30800801C20862820C4F8620094F8A5 +:100DB0005D0020F0030084F85D0094F85E0020F0F0 +:100DC000010084F85E0094F8360040F0010084F8D9 +:100DD0003600A97831B1012908D0022918D0032999 +:100DE00009D119E020F07000403002E020F07000DE +:100DF000503084F83600687888B1012813D0022872 +:100E000016D0032803D1A07C40F00300A07470BD6D +:100E100020F070006030ECE740F07000E9E7A07C63 +:100E200020F00300F2E7A07C20F00300401CEDE777 +:100E3000A07C20F00300801CE8E7F8B56E4E074662 +:100E40000324384616F080FA00226B460121104632 +:100E500016F09CFD0121002016F07BFD307838B1A2 +:100E6000002512F024FC641E002CEADC2846F8BDA4 +:100E70000125FBE72DE9F04389B00646684616F0E8 +:100E80003CFA584F5D480025F8605D4800900E2000 +:100E90008DF804007E70BD706846FFF7CEFF4FF0FE +:100EA000FF39E8B350225748F96818F038FD01249B +:100EB0000DF11808BC706846FFF7BFFF80B35022E1 +:100EC0005148F96818F02BFD4E4A414628F8145055 +:100ED000002002EB400332F810C0B3F83037401C5A +:100EE000A3EB0C0331F814C02828634421F8143014 +:100EF000EFDB641CE4B2042CDCD3BDF81E00032E2F +:100F000015D0A022B0FBF2F1BDF81C00BDF81A30DC +:100F1000B0FBF2F0B3FBF2F2120642EA004000E04E +:100F200003E0084309B0BDE8F0834846FAE75022E1 +:100F3000E8E72DE9F0410125002016F07EFD0220B2 +:100F400016F07BFD2C4F0026DFF89C803C370FE02D +:100F500001250024E0B2FFF78DFF47F824000028A8 +:100F600000DA0025641C042CF4D3012D08D0761C73 +:100F7000D8F8000090F88E06B042E9DC25B327E0EF +:100F8000224E1D49102230683C31223018F0C7FC37 +:100F9000D8F800001E4C90F88706800703D59821EA +:100FA000201D18F05DFD144919483C319C308EC954 +:100FB00080E88E000221201D216016F034FE316889 +:100FC0005A2081F8210003E00021302012F060FB5C +:100FD000002016F04DFD022016F04AFD2846BDE81F +:100FE000F081000004041000A40710009D0B000015 +:100FF0003D0C0000B50B00001C0910000000012092 +:101000001F0D00001C7210004C791000A807100082 +:10101000909C100010B5FFF78CFF00F0010400F069 +:101020002AF820420CD04E48006890F83210FA2975 +:1010300002D2491C80F83210BDE81040FFF707BD0E +:1010400010BD10B5FFF775FF10F0010F03D0BDE81C +:101050001040FFF7FCBC10BD00F01F0201219140C1 +:101060004009800000F1E020C0F8801170470A229A +:10107000072117F0DDB970B5002016F0DEFC394C01 +:101080000020E070FFF703FE064600F019F8054661 +:1010900001460A22304617F0CBF9E07830B93048E3 +:1010A00002685A20D67782F820509077002016F0F8 +:1010B000DFFCE078012801D0012070BD002070BD68 +:1010C0002DE9F84317F048F8274E002000903068CB +:1010D0000023012290F89400194600F0070017F051 +:1010E000C6FD3068002190F8940000F0070017F06A +:1010F00046FD1E48009030680023012290F89400BD +:10110000194600F0070017F006FEFFF79CFD0146A8 +:10111000144800244FF6FF754181804621460A227B +:10112000322017F085F9FFF78EFDA8F80A0098F82D +:101130000310012911D03168B1F88416401A00D586 +:10114000404280B2854201D905462746641CE4B27C +:10115000102CE3D33846BDE8F8830720FBE70000F6 +:10116000A807100004041000A4071000B50B00002D +:1011700010B501463C22F84818F016FC0121BDE8E4 +:101180001040002016F0B9BB30B587B00446684661 +:1011900016F0B3F8F1490091022C05D0032C09D0C8 +:1011A000042C05D00A2006E003208DF80A0004E094 +:1011B000072000E00B208DF80400E74C684616F08D +:1011C000C3F8002206AB0121104616F0DFFB012117 +:1011D000002016F0BEFB207810B112F068FAEDE79F +:1011E00016F0F3F8DE4DC5E9120116F0F0F8C5E986 +:1011F0001401A468302012F03DFB11F028FA07B06A +:10120000204630BD2DE9F041D54CA0F16006092EF5 +:10121000D4E91220D4E9145316D2DFE806F00516FB +:1012200026374858687989000346084600F018FBBD +:10123000012302460021184618F027FBD4E90223B7 +:1012400010431943C4E9020177E02A46084600F03A +:1012500007FB02460120002118F017FBD4E90A23FE +:1012600010431943C4E90A0167E00346084600F049 +:10127000F7FA012302460021184618F006FBD4E9CC +:10128000062310431943C4E9060156E02A460846DE +:1012900000F0E6FA012302460021184618F0F5FA9C +:1012A000D4E90E2310431943C4E90E0145E0034677 +:1012B000084600F0D5FA02460120002118F0E5FAB0 +:1012C000D4E9042310431943C4E9040135E02A4654 +:1012D000084600F0C5FA02460120002118F0D5FAB0 +:1012E000D4E90C2310431943C4E90C0125E003465B +:1012F000084600F0B5FA012302460021184618F00E +:10130000C4FAD4E9082310431943C4E9080114E0DE +:101310002A46084600F0A4FA02460120002118F0EF +:10132000B4FAD4E9102310431943C4E9100104E0CE +:10133000012088406168084360602068401C20608C +:10134000BDE8F0812DE9F041174604460D46002620 +:1013500009E0E00703D03146384612F099F9761CCF +:101360006D084FEA340454EA0500F2D1E8E72DE9AC +:10137000F0417B4CD4E90223D4E9065610461946C5 +:101380002A433343D4E90A56D4E90EC745EA0C058B +:101390003E43D4E9087C97432CEA030CC4E9087C5B +:1013A000D4E91023AA43B343C4E910232268002AD6 +:1013B000C6D06022FFF7C6FFD4E90A016122FFF719 +:1013C000C1FFD4E906016222FFF7BCFFD4E90E0198 +:1013D0006322FFF7B7FFD4E904016422FFF7B2FFED +:1013E000D4E90C016522FFF7ADFFD4E908016622BC +:1013F000FFF7A8FFD4E910016722FFF7A3FF606899 +:10140000BDE8F041682200219CE799E72DE9F84FFB +:101410000446002615F0D9FF0746884615F0D7FF89 +:1014200081464F488A4648304FF01D0B80E88007C0 +:101430002620009016F05DFD00252A46012000219F +:1014400018F023FA384001EA080108431DD0E8B239 +:10145000002116F056FD410704D5E10602D53146BC +:1014600062200EE0C10704D0610702D5314660203A +:1014700007E014F0C00F06D010F00A0F03D0314679 +:101480006420FFF7BFFE761CF6B26D1C5D45D4DB11 +:1014900016F02FFD0026354629E02A4601200021BE +:1014A00018F0F3F900EA090001EA0A0108431DD027 +:1014B000E8B2012116F025FD410704D5A10602D5A9 +:1014C000314663200EE0C10704D0210702D5314622 +:1014D000612007E014F4C07F06D010F00A0F03D09B +:1014E00031466520FFF78EFE761CF6B26D1C009823 +:1014F0008542D2DDBDE8F84F16F0FBBC2DE9FF4F69 +:1015000081B08846924600210E9A1E468B46009175 +:10151000100576D500244AE000274FF0FF393D46FC +:101520002DE005FB08403AF91010B14226D27F1C8D +:10153000B9F1FF3F00D1A9460199491E8D421DD145 +:10154000012F1BD1A8F101018C420BD12946662045 +:10155000FFF758FE12E0000068091000211100009A +:10156000180410000AEB4000B0F90210B14204D395 +:1015700024B130F9020CB04200D200276D1CC648DD +:10158000005DA842CDD80198A0EB0900B8420DD863 +:1015900021466720FFF736FE22460120002118F081 +:1015A00074F9009B40EA0B0B19430091641C4445FD +:1015B000B2D3002522E0B94800273C4630F9151087 +:1015C000A8EB010912E005FB08413AF91100B0420D +:1015D0000BD222460120002118F057F9009A00EAA8 +:1015E0000B001140084300D17F1C641C4C45EAD31A +:1015F0001FB129466620FFF705FE6D1C0198854244 +:10160000D9D305B0BDE8F08F70B5044686B0002090 +:1016100016F013FAA248002114F00C0FC0E90811CB +:10162000C0E90211C0E90411C0E90611C0E91011B6 +:10163000C0E90A11C0E90C11C0E90E114160016056 +:1016400009D1E00607D4A00605D4600603D4E0055E +:1016500001D4200602D52046FFF7D8FEA00701D10D +:10166000200520D50120FFF78FFD054615F0ADFEC2 +:10167000CDE9020115F0ABFECDE90401082102A875 +:1016800016F04CFF0646082104A816F047FF014655 +:10169000200508D5834800942A46006890F8123B3C +:1016A0003046FFF72BFF14F4404F02D00320FFF722 +:1016B0006BFDFFF75CFE06B00020BDE8704016F041 +:1016C000D7B92DE9F04F044685B0002016F0B5F9E2 +:1016D000022016F0B2F9032016F0AFF9E0077DD032 +:1016E000FEF746FF6F4C206890F8311090F83000FC +:1016F0004A0042436C496D4818F011F94FF0000A56 +:10170000A3469AE0654B91F83010DFF8A49113F8E6 +:101710001A004FF0FF3510F0FF00A1EB0002D4B229 +:10172000624A01FB0AF147F6FF7802EB41072E46B9 +:101730000BD0204600215A4602E027F81010401C2A +:10174000136893F830308342F7DC641E1DE037F9EC +:101750001400484500DD8146404500DA8046012CF2 +:1017600013D407EB440131F9021C401A00D5404262 +:10177000DBF80010B1F8F81A884206DB2246012097 +:10178000002118F082F885438E43641EDFD2B9EB46 +:10179000080000D54042DBF800105C46B1F8F62A9C +:1017A000904248DAB1F8F40A484544DD4044002844 +:1017B00041DD91F8FA1A2A4688463346384605F044 +:1017C0003AFA014620683346B0F8F42A0020019026 +:1017D00000910290CDE903022A4600E034E0414640 +:1017E000384605F06FFA2068334690F8302090F8BC +:1017F000FA0AA2EB0801C9B2884607EB40002A4664 +:1018000005F019FA014620684FF0010C0DF10809A6 +:10181000B0F8F44A90F9FC3A90F9FB2ACDE9001CA3 +:1018200089E81C0090F8FA0A2A4607EB4000334684 +:10183000414605F047FA0AF1010ADBF8001091F879 +:10184000313053453FF75EAF032016F011F9022007 +:1018500016F00EF905B00020BDE8F04F16F008B9FB +:101860002DE9F04116461F4680464FF0FF35002413 +:1018700022460120002118F008F830403940084382 +:1018800004D06D1C454501D1204659E5641C402C0F +:10189000EED3002054E50000622601203826012006 +:1018A00018041000A4071000D85701209C8B0120B9 +:1018B0000080FFFF144908604FF40051002016F02B +:1018C0001CB838B5002016F0B8F8AFF2170017F0C2 +:1018D00065FE00224FF400546B462146104616F078 +:1018E00055F82146002016F034F8002016F0C0F814 +:1018F0000648A522016804480A74006820F07F4267 +:101900004A6117F06FFE38BD70041000A807100080 +:10191000020004D0012A04D0022805D002E00120F0 +:1019200000E0072015F072BC0020704710B501469A +:101930003C22FE4818F038F80121BDE81040002094 +:1019400015F0DBBF30B587B00446684615F0D5FC0E +:10195000F7480090FCB1012C1FD0022C19D10220B5 +:101960008DF80A00F14D0324684615F0EDFC0022C5 +:1019700006AB0121104616F009F80121002015F0F0 +:10198000E8FF2878002804D011F091FE641E002C96 +:10199000EADC07B030BD082000E009208DF8040023 +:1019A000E0E72DE9F14F8CB015F00FFDCDE9040112 +:1019B00015F00DFDCDE90601DE4C0C9800282068DD +:1019C00007D0B0F832110C98FFF7A2FF8146DA4831 +:1019D00012E090F8CE0010F0600F05D0DDE90401B0 +:1019E00013F05EF9CDE904012068B0F82C110C98D1 +:1019F000FFF78EFF8146D148029040200B900A905D +:101A0000082104A816F08AFD0446082106A816F04D +:101A100085FD4443DFF82883214608F5E6608246C9 +:101A200017F0FCFF6100404617F0F8FFBF48B821EF +:101A3000B83818F015F802222146504617F0E6FF94 +:101A400000263546082106A816F068FD0390DDE95A +:101A50000401B346CDE900015A460120002117F0E8 +:101A600014FFDDE900231040194008432BD0002467 +:101A700025E022460120002117F007FFDDE9067C62 +:101A800002460B46384001EA0C01084316D0AD4827 +:101A900030F9150088B1039996FBF1F701FB176740 +:101AA000081A874209DBA148B83800EBC500D0E925 +:101AB000001711431F43C0E90017761C641C0A98E5 +:101AC0008442D6DB6D1C0B990BF1010B8B45C3DBFC +:101AD000002008900C98FFF735FF94480024D0F8B8 +:101AE00008B00120099001942046D5E0024601206B +:101AF000002117F0CAFEDDE9042310401940084315 +:101B000074D00020AFE002460120002117F0BDFE96 +:101B1000DDE9062306460F4610401940084371D000 +:101B200082480199B83800EBC105D5E90001304081 +:101B3000394008430FD1DDE90110009A16F026F96B +:101B40001AF804103BF91420022905D04A4554DD47 +:101B500019B301292ED083E04A4506DD7F2811DA2A +:101B600000220AF80420431C06E00BDA002809DDF5 +:101B700001220AF80420431EDDE90110009A16F044 +:101B800010F905E0D5E9000130433943C5E900010A +:101B90003BF8141028F8141062E07F2803DA28F8C4 +:101BA0001420431C35E0D5E9000130433943C5E931 +:101BB000000155E0D5E9002132433943C5E9002150 +:101BC00038F914203BF91430B2EB0901A3EB0902F8 +:101BD00000D54942002A00DA5242914207DC431CF8 +:101BE000DDE90110009A16F0DCF802E052E028F876 +:101BF000143002200AF8040032E05FDA012902D032 +:101C000069B12DE02DE010F17F0FCCDD28F8142014 +:101C1000431EDDE90110009A16F0C3F820E0D5E973 +:101C2000002132433943C5E9002138F914203BF93A +:101C30001430B2EB0901A3EB090200D54942002A96 +:101C400000DA5242914206DC431EDDE90110009A9F +:101C500016F0A7F801E028F8143002210AF8041061 +:101C6000641C0098401C00900A998842FFF64BAF14 +:101C70002E480199B83800EBC100D0E90010DDE929 +:101C8000062351405840014301D00020099001989B +:101C9000401C01900398401C0B9903908842FFF66A +:101CA00025AF0998012805D00898401C08907F2886 +:101CB0007FF710AF09980DB0BDE8F08F02210AF848 +:101CC000041070E72DE9F14F8EB04FF0000B15F0C6 +:101CD0007CFBCDE9000115F07AFBCDE904010E98FB +:101CE00048B114480068B0F832110E98FFF710FEA2 +:101CF0000790114814E00F4C206890F8CE0010F0C7 +:101D0000600F05D0DDE9000112F0CAFFCDE9000146 +:101D10002068B0F82C110E98FFF7FAFD07900748DD +:101D2000029040200C9008210B900DE0600A1000FA +:101D3000DD180000A4071000A47C01207C7701209E +:101D40001C72100038260120684616F0E7FB0D9043 +:101D5000082104A816F0E2FB0A90B821FE4817F00B +:101D60007FFEFD481721F43017F07AFE012000278E +:101D700008903846824602460120002117F085FD72 +:101D8000DDE9042305460E461040194008437DD086 +:101D900000200390F148006890F82A118A0720D5A6 +:101DA00047B1090709D5012F04D090F83000401E33 +:101DB000B84202D1CDF818A013E000240BE0214670 +:101DC000069A029815F0E2FF034652462146029811 +:101DD00015F0E7FF641C0D988442F0DBCDF818A0E5 +:101DE00057E00E98FFF7AEFDDB484FF00009B83022 +:101DF0008068099001200390484644E00246012093 +:101E0000002117F042FDDDE900231040194008438E +:101E100037D0D14800EBC904D4E900012840314053 +:101E2000084325D152464946029815F0AFFF0A995A +:101E300009FB0172099931F9122007998A4206DAE1 +:101E4000D4E9001029433043C4E9001010E07F2892 +:101E500006DA431C52464946029815F0A2FF07E0F5 +:101E6000D4E9000128433143C4E90001002008906F +:101E7000D4E9000128403140084300D1039009F122 +:101E8000010908F1010080460C9900E005E0884254 +:101E9000B4DB03980028A4D07F1C0AF101000B9941 +:101EA00082468842FFF667AF0020AFE04FF000099E +:101EB0004846A1E002460120002117F0E6FCDDE9DA +:101EC000042306460F461040194008437ED0B9F15E +:101ED000000F01D14FF0010B0E98FFF733FD9E4824 +:101EE0000024B8308068099001200390204675E0F6 +:101EF00002460120002117F0C8FCDDE90023104054 +:101F00001940084368D0B9F1000F0EDD5246214652 +:101F1000029815F03BFF90495246F43109570B18CF +:101F20002146029815F03DFF55E0BBF1010F10D19D +:101F300052462146029815F029FF8749F431085589 +:101F4000854800EBC400D0E90021B243B943C0E9A1 +:101F50000021814800EBC405D5E90001304039403B +:101F600008432FD152462146029815F00FFF0A9AD6 +:101F7000099904FB029231F9122007998A420BDA7F +:101F8000D5E9001231433A43C5E900127249F431F0 +:101F90000A5D801A085515E07F2806DA431C524670 +:101FA0002146029815F0FDFE0CE0D5E90012314300 +:101FB0003A43C5E900126849F4310A5D801A0855B0 +:101FC00000200890D5E90001304000E012E03940DF +:101FD000084300D10390641C08F101000C9980466D +:101FE000884285DB03984FF0000B00283FF474AF64 +:101FF00009F101090AF101000B9982468842FFF6B6 +:1020000059AF0E98FFF79EFC0698401C0690534867 +:10201000006890F82A110698B0EB111FFFF646AF42 +:1020200008980FB048E62DE9F14F90B015F0CDF9C2 +:10203000CDE9040115F0CBF9CDE908011098C8B33A +:1020400046480068B0F832111098FFF761FC074667 +:1020500043480290402003900790082104A816F0FE +:102060005DFA0446082108A816F058FA3D4E44438C +:1020700006F5E6652146284617F0D0FC610030469B +:1020800017F0CCFCB821344817F0EAFC02222146B4 +:10209000284617F0BBFC00200D901098FFF752FC6B +:1020A0002D484FF0010BB8300024806801940B904C +:1020B00020464DE1FFE7DDE9040112F0F1FDCDE935 +:1020C000040126480068B0F82C111098FFF720FC96 +:1020D00007462548BDE702460120002117F0D5FB41 +:1020E000DDE9042310401940084379D000200A900C +:1020F00020B20E901848019900EBC1008046D0E94B +:102100000010DDE9082351405840014301D101206E +:102110000A900020D3E00A460120002117F0B5FB09 +:10212000DDE9082381468A461040194008437DD0E6 +:1021300000200690DDE90110009A15F027FED8E98D +:10214000001E01EA09030EEA0A02134301D101222B +:1021500006920A9A002A09E0A8091000A4071000B4 +:10216000A47C01201C7210007C7701200AD12A5D1A +:10217000022A08D00B9B33F91430BB425FDD82B3D7 +:10218000012A3ED098E00B9A32F91420BA4205DDBC +:102190007F2810DA00212955431C06E014DA10F1DB +:1021A0007F0F08DD01212955431EDDE90110009A4A +:1021B00015F0F7FD0EE041EA09014EEA0A02C8E90E +:1021C00000124FF0000B05E041EA09014EEA0A0255 +:1021D000C8E900120B9830F8140026F814006BE0E0 +:1021E000B4E0FFE77F2803DA26F81430431C31E01F +:1021F00041EA09014EEA0A02C8E900124FF0000B59 +:102200004BE0069A2AB141EA09014EEA0A03C8E9FD +:1022100000130B9A36F9141032F91430C91BA3EBD2 +:10222000070200D54942002A02DA00E045E05242A6 +:10223000914201DC431C2BE026F814302DE02FDA0C +:10224000012A01D062B137E010F17F0FD0DD26F80E +:102250001430431EDDE90110009A15F0A2FD2BE0B9 +:10226000069A2AB141EA09014EEA0A03C8E90013B5 +:102270000B9A36F9141032F91430C91BA3EB07027C +:1022800000D54942002A00DA52429142D4DC431E72 +:10229000DDE90110009A15F084FD022028550BE0BD +:1022A00002202855069838B1D8E9001241EA090100 +:1022B00042EA0A02C8E90012641C0098401C014668 +:1022C000009007988142FFF626AFDDE90823D8E9A0 +:1022D000001051405840014302D04FF0000B32E053 +:1022E0000A9880BB0020DDF8389028E002460120E3 +:1022F000002117F0CAFADDE908231040194008430D +:102300001BD0DDE90110424615F040FD15F809101B +:1023100011B1012905D00CE010F17F0F09DD431E3A +:1023200002E07F2805DA431CDDE90110424615F082 +:1023300038FD09F101000FFA80F908F10100079951 +:1023400080468842D2DB0198401C01900C98401CCA +:1023500003990C908842FFF6BEAEBBF1010F05D089 +:102360000D98401C0D907F287FF797AEFD480068C0 +:1023700090F82B0140077DD5082108A816F0CEF86B +:102380000D90002001904FF0010BB821F64817F096 +:1023900067FB002094E102460120002117F075FA46 +:1023A000DDE908238246884610401940084372D070 +:1023B00000200690EB480222006890F83110284671 +:1023C00017F024FB0024204615E0024601200021DE +:1023D00017F05BFADDE9042310401940084308D0E8 +:1023E0002146009A029815F0D1FCDF49F4310855D6 +:1023F000641C09F10100039981468842E5DBFBE09A +:102400001098FFF79FFAD8484FF00009B83080685D +:102410000B90012006904846E9E002460120002189 +:1024200017F033FADDE904231040194008437DD04A +:10243000CD4800EBC904D4E9000100EA0A0001EA32 +:102440000801084315D14946009A029815F09EFCF0 +:1024500015F809200199022A0DD0DDF834C00B9B34 +:1024600009FB0C1133F91130BB426BDDB2B3012A09 +:102470004AD0AFE029E10D9B0B9A09FB03110A91A9 +:1024800032F91110B94210DD7F2805DA002105F874 +:102490000910431C11E011E1D4E9000140EA0A00EF +:1024A00041EA0801C4E9000115E018DA10F17F0FD4 +:1024B00009DD012105F80910431E4946009A0298DA +:1024C00015F06FFC13E0D4E9001041EA0A0140EA7C +:1024D0000800C4E900104FF0000B08E00EE0D4E95A +:1024E000000140EA0A0041EA0801C4E90001DDE90F +:1024F0000A0131F8101026F810106BE07F2832DA4C +:1025000026F81130431C28E0D4E9002342EA0A02ED +:1025100043EA0803C4E900230B9B36F9112033F981 +:1025200011C0D21BACEB070302D500E05DE05242C4 +:10253000002B00DA5B429A4201DC431C36E026F8AD +:1025400011C038E03BDA012A01D0BAB142E010F103 +:102550007F0F08DD26F81130431E4946009A029885 +:1025600015F01FFC36E0D4E9000140EA0A0041EA18 +:102570000801C4E900014FF0000B2BE0D4E900236F +:1025800042EA0A0243EA0803C4E900230B9B36F936 +:10259000112033F911C0D21BACEB070300D5524216 +:1025A000002B00DA5B429A42C9DC431E4946009A7E +:1025B000029815F0F6FB022005F809000AE0022057 +:1025C00005F80900D4E9000140EA0A0041EA0801DF +:1025D000C4E90001D4E9000100EA0A0001EA0801A7 +:1025E000084300D1069009F101090C98401C039999 +:1025F0000C908842FFF611AF069800283FF400AF18 +:102600000024DFF864A1204680460AF1F40A18E0AD +:1026100002460120002117F038F9DDE904231040BB +:10262000194008430AD02146009A029815F0AEFBE3 +:102630001AF80420801A0AF80400641C08F101004A +:10264000804603998845E3DB0098401C2FE0024652 +:102650000120002117F019F9DDE908231040194085 +:10266000084322D04FF0000844461BE022460120D8 +:10267000002117F00AF9DDE904231040194008434E +:102680000FD04A464146029815F080FB1AF8081010 +:102690004A46084443B24146029815F082FB08F1CD +:1026A0000108641C03988442E0DB09F101000799EA +:1026B00081468842CBDB0198401C01900098401C69 +:1026C000079900908842FFF666AE11B05846BDE803 +:1026D000F08F2DE9FF5F4FF0400AD146082102A894 +:1026E00015F01CFF08210EA815F018FF0025DFF8D3 +:1026F0007CB00FFA80F82F462E463246012000218A +:1027000017F0C3F8DDE9022310401940084324D034 +:1027100000241FE022460120002117F0B6F8DDE971 +:102720000E2310401940084313D03BF9170038B16D +:1027300095FBF8F208FB1252A8EB0000824201DA86 +:10274000109B00E0119B22463946009815F029FBAA +:102750006D1C641C4C45DDDB7F1C761C5645CCDBB8 +:10276000BDE8FF9FA4071000A8091000382601202B +:1027700070B505460124002015F05FF9022015F020 +:102780005CF9E80703D000F014F800F00104A80792 +:1027900002D500F059F80440002015F069F9022034 +:1027A00015F066F9E80702D0012000F0AEF82046E7 +:1027B00070BD2DE9FC47012614F007FE04460D46C6 +:1027C00014F005FEDFF80C9107468846D9F80000A2 +:1027D00090F8CE0010F0600F05D02046294612F088 +:1027E0005FFA04460D46D9F8000090F82A01C007A8 +:1027F00024D0CDE9007822462B46374815F0E0FA80 +:10280000D9F8001091F82A01C20717D091F8CF101B +:10281000C90705D00020FFF7C4F806000AD00DE074 +:1028200040074FF0000002D5FFF7FDFBF5E7FFF78B +:1028300049FAF2E70121742010F02AFF0020FFF787 +:1028400081F83046BDE8FC872DE9FF41012614F0F0 +:10285000BCFD04460D4614F0BAFD1E4F3A6892F8CE +:1028600030315FEAC37C2DD0DFF870C09B070BD5F9 +:1028700092F8353192F834218DE80F0022462B462C +:102880006046FFF726FF06E0CDE9000122462B4611 +:10289000604615F095FA386890F83011C90711D0E4 +:1028A00090F8E100C0064FF0010002D4FFF70AFAE9 +:1028B00001E0FFF776F8060004D14FF48071742030 +:1028C00010F0E6FE0120FFF73DF804B03046BDE809 +:1028D000F0810000A40710007C770120A47C012077 +:1028E00010B5FEF7EEFF5320FFF742FF00F00104A2 +:1028F0004FF4D67001F0D0F9204205D0FEF7EBF886 +:10290000BDE81040FEF7A3B810BD2DE9F047224EF8 +:102910000546306890F87531C3F30112C3F38101A5 +:1029200003F0030011F07BFD3268401CC4B292F842 +:10293000BD0AC00700D1012492F8C10CC00729D0FC +:10294000012D27D192F83110DFF8549092F8302001 +:10295000DFF850805143D9F80050012202200F4E79 +:102960000FB288F800203635FDF7DBFF002188F82C +:102970000010032015F061F8D9F800007A006243D6 +:1029800087863146284616F0CAFFBDE8F047032087 +:1029900015F06EB8BDE8F087A4071000D8570120E5 +:1029A000A80710007404100010B501463C2204482A +:1029B00016F0FAFF0121BDE81040002014F09DBF81 +:1029C000B40A100030B587B0684614F096FCFE4893 +:1029D00002220078E0B1032101280DD003280ED097 +:1029E000022818D0042205280CD004280DD006286F +:1029F0000ED007280FD010E08DF807100DE08DF8ED +:102A000009100AE08DF80B2007E08DF80B1004E0A8 +:102A10008DF8072001E08DF80920EC48EC4D0324E7 +:102A20000090684614F090FC002206AB012110468D +:102A300014F0ACFF0121002014F08BFF287800284F +:102A400004D010F034FE641E002CEADC07B030BD68 +:102A50002DE9F047DFF8709300252C46D9E914875B +:102A60002E4632460120002116F00FFF00EA080032 +:102A700039404A46084304D0906B805DA84200D993 +:102A80000546761C402EECD3976DD9F85C80002665 +:102A900032460120002116F0F8FE384001EA080114 +:102AA0004A46084305D0D9F83C00805DA04200D9D1 +:102AB0000446761C402EEBD3916C16460D70D06CFC +:102AC0000470126BB76A736B12783F782A443A44E9 +:102AD000F76A1B783F7823443B44D6E9147C57EAD5 +:102AE0000C070DD0D6E9167C57EA0C070AD0FF2751 +:102AF0009A4212D29A1A2A44FF2A07D80A700AE088 +:102B00000C7008E00D700570BDE8F0870F70F1697A +:102B100041F40071F1610470F6E793420CD2D21ACD +:102B20002244FF2A01D8027004E00770F06940F4E3 +:102B30000070F0610D70E7E70D70ECE72DE9F041F2 +:102B40001F460C46002A1FDD9F4E77B1B6F90C5088 +:102B5000114612F043FDA842207812DAFF2807D26E +:102B6000401C20700020BDE8F081B6F90A50EFE764 +:102B7000F0691FB140F00200F06105E040F4006030 +:102B8000FAE708B1401E20700120ECE72DE9F04182 +:102B90001E460C46002A1ADD8B4D66B1B5F90C7045 +:102BA000114612F01BFDB84211DD207850B11028FB +:102BB00004D3103803E0B5F90A70F1E70020207063 +:102BC0000020D0E7E86926B140F00100E86101206B +:102BD000C9E740F48060F9E72DE9F14F00247A4815 +:102BE000009A2546FF21DAB1D0F830B002268BF8E2 +:102BF0000010D0F834A08AF80010B0F90C704169C8 +:102C00004FF01809002900DC01246F488069002872 +:102C100000DC0125FFF71CFFFFF7D4FE6CB11EE0BE +:102C2000D0F828B04FF400668BF80010D0F82CA034 +:102C30008AF80010B0F90A70E1E7DFF88C813A46B3 +:102C4000D8F82000D8F81410006801F049F80128DD +:102C500005D1D8F81C1031430124C8F81C108DB9D7 +:102C6000DFF864813A46D8F82400D8F818100068D4 +:102C700001F036F8012805D1D8F81C1031430125A0 +:102C8000C8F81C100CB1002D45D126462F46C84669 +:102C900019E046B94C49009B086A4A6959460068E0 +:102CA000FFF774FF064647B94749009B486A8A699F +:102CB00051460068FFF76AFF0746FFF7C9FEFFF7B6 +:102CC00081FE06B117B9B8F10108E2D24E463E4F77 +:102CD00017E03CB9386A009B594600687A69FFF7EB +:102CE0002DFF04463DB9786A009B51460068BA69D9 +:102CF000FFF724FF0546FFF7ABFEFFF763FE04B1C5 +:102D00000DB9761EE5D2012C05D1012D03D1F8694C +:102D100020F40070F861BDE8F88F2DE9F04F002431 +:102D20008046254620464FF0010CDFF89CB0A246B5 +:102D300016E002EBE50605F0070936780CFA09F70C +:102D400037420CD038F91470BBF90E60B74203DC7F +:102D500003F804C0012001E003F804A0641C6D1C0A +:102D60008C42E6DBBDE8F08F2DE9FF5F00244FF0D9 +:102D7000010B80462546DFF850A05F46DDF83C9009 +:102D8000119E54E0039805F0070100EBE50007FAF7 +:102D900001F20078024249D0305D012845D038F96F +:102DA0001420BAF90E108A4225DA2946019815F046 +:102DB00062F8FF2817DA0E994FF0000B0844FF283D +:102DC00000DBFF20C2B205E07804100059290000A2 +:102DD000B40A10002946019815F04FF838F814107D +:102DE00029F8141021E03755DAF81C1041F00801D9 +:102DF000CAF81C1019E01098012815D139F91400EF +:102E0000401AA2EB010100D54042002900DA4942F4 +:102E1000884209DC2946019815F02DF8401EC2B2FF +:102E20002946019815F029F83755641C6D1C029845 +:102E30008442A7DB584604B0BDE8F09F2DE9FF5F50 +:102E40000024DDE90E764FF0010A9B462546D04668 +:102E5000DFF884942FE00BEBE500017805F0070024 +:102E600008FA00F20A4225D0305D012821D00098EE +:102E700030F91410B9F90E0081421ADD2946019883 +:102E800014F0F9FF00280CDD4FF0000AB84201DB16 +:102E9000C01B00E00020C2B22946019814F0EDFFEB +:102EA00007E006F80480D9F81C1041F00401C9F8C5 +:102EB0001C10641C6D1C02988442CCDB5046BAE79F +:102EC0002DE9F04F95B00F460646002425461821FF +:102ED0000EA816F0C5FD282104A816F0C1FDFE4875 +:102EE0004169002900DC01248269002A00DC0125F7 +:102EF0003346F94A814606465032806B00F0FAFEAE +:102F0000F54A3B465832B169F06B00F0F3FEFFF72B +:102F10009FFDFFF757FD8CB1D9F82000EE4A4E46D1 +:102F200000680EAB5032D9F81410FFF7F6FE0128F6 +:102F300004D1F069012440F00800F0618DB1D9F8A6 +:102F40002400E54A4E46006804AB5832D9F8181000 +:102F5000FFF7E3FE012804D1F069012540F00800E5 +:102F6000F0610CB1002D76D126462F464FF00008B7 +:102F70004FF0100A0DF1380B6EB9CDE900ABD9F85E +:102F80002010D54BD9F8142008685033D9F83810E0 +:102F9000FFF754FF064677B904A8CDE900A0D9F899 +:102FA0002410CD4BD9F8182008685833D9F83C10B4 +:102FB000FFF744FF0746FFF74BFDFFF703FD06B1A0 +:102FC00027B908F10108B8F1600FD5DBDFF80CA3D1 +:102FD000D9F814000AF5E66841004F46504616F04D +:102FE0001DFDB8694100404616F018FD00264FF05F +:102FF0000109FFF7E7FC64B9CDE9009ACDE9029B2E +:10300000386AB54B7A6900685033B96BFFF7ACFE8C +:1030100004466DB904AACDE90098CDE90292786A18 +:10302000AD4BBA6900685833F96BFFF79DFE054652 +:10303000FFF70EFDFFF7C6FC04B115B9761C602E34 +:10304000D7DB012C07D1012D05D1F869810502D507 +:1030500020F40070F86115B084E62DE9FF4F83B0CD +:1030600082460120DDE9117683460290A7F17F00B8 +:1030700001900024C7F17F008946DDF84C80254689 +:10308000009083E0109800EBE500017805F0070060 +:103090000BFA00F20A4278D02946059814F0BEFED9 +:1030A0008D4918F804303AF91420B1F91010022BA8 +:1030B00007D08A423ADDF3B1019988422CDDC21B68 +:1030C0003BE08A4208DD0199884202DD08F804B03D +:1030D000F5E7705D40B109E006DA0099814205DD4F +:1030E000002208F8042027E006F805B03AF814108A +:1030F00029F8141017E039F914305B1AA2EB01011A +:1031000000D55B42002900DA49428B422FDC01994D +:10311000884203DDC21B25E0705D08B906F805B0E2 +:10312000022108F80410705D58B32DE022DA012B5B +:1031300008D000998142EFDDC2192946059814F0A4 +:1031400074FED3E739F914305B1AA2EB010100D504 +:103150005B42002900DA49428B4208DC0099814237 +:10316000DCDDC2192946059814F05FFED6E729F880 +:103170001420D3E7022008F8040006F805B003E0A5 +:1031800003E0FFE700200290641C6D1C0698844257 +:10319000FFF678AF0298012822D100252C461CE0CA +:1031A000109800EBE400017804F007000BFA00F23D +:1031B0000A4211D02146059814F030FE18F8051087 +:1031C000022908D079B10099814204DDC219214653 +:1031D000059814F02AFE6D1C641C06988542DFDBFE +:1031E000029807B0BEE501998842F4DDC21BEEE704 +:1031F0002DE9F34F3A4897B0374C0068169037489E +:1032000014906169DFF8DCA000EB410015900AEB37 +:10321000010B504616F002FC5846A16916F0FEFB61 +:1032200060694100149816F0F9FBA06941001598F7 +:1032300016F0F4FB18210EA816F012FC282104A8A1 +:1032400016F00EFC0027A14616A8DDE9175450F829 +:10325000278018210EA816F003FC282104A816F0D8 +:10326000FFFB02224E465046D9F8141016F0CEFB52 +:1032700002225846B16916F0C9FB0026FFF7A2FBEF +:1032800095B9154B0EAA5033CDF80CA00093CDE99B +:103290000182D9F82010D9F81430D9F840200868F4 +:1032A0001499FFF7DAFE054694B90B4B04AA58337C +:1032B000CDF80CB00093CDE90182D9F82410D9F8EB +:1032C0001830D9F8442008681599FFF7C6FE04465F +:1032D000FFF7BEFB4DB107E0780410001C72100030 +:1032E000E09B01004C79100014B9761C7F2EC5DBE1 +:1032F0007F1CA9D019B035E52DE9FF5F4FF000081C +:10330000DDE90EB5994692464646444621E00AEB71 +:10331000E4000122017804F0070082400A4217D03D +:103320002146009814F07AFD071E00DA78425845CD +:103330000DDD2146019814F09EFD002F0DDDC5F135 +:10334000FF01814201DB28440AE04FF00108761CAE +:10335000641C4E45DBDB40466DE5A842F5DB401BB7 +:10336000C2B22146019814F088FDEEE72DE9FC4732 +:103370000E46070001D0002E51D10024DFF838940A +:10338000DFF83884254697B9D9F8000008F15002D3 +:1033900090F8731190F87201CDE90001D8F814305B +:1033A000D8F83810D8F84000FFF7A6FF044696B9C1 +:1033B000D9F8000090F8731190F87201CDE900017E +:1033C000FE4AD8F818305832D8F83C10D8F84400E3 +:1033D000FFF792FF0546FFF73BFB012C08D1F74AA8 +:1033E00000235032D8F81410D8F8400000F082FCC6 +:1033F000012D14D1F14A00235832D8F81810D8F80A +:10340000440000F077FC0EB1012100E0002117B16B +:103410000CB1012000E00020BDE8FC47E8E6BDE873 +:10342000FC872DE9FF5F4FF0000B1E4617468846CC +:103430005D465C464FF0010ADDF8389016E007EB78 +:10344000E400017804F007000AFA00F20A420CD006 +:10345000B44209DD2146009814F0E0FC00EB0902BB +:103460002146009814F0E1FC6D1C641C4545E6DB28 +:103470005846E0E42DE9F05F0E46DDE90A510746C3 +:103480001C4693464FF0010A4FF00009104614F015 +:10349000C5FCCA4995F80080B7F90020B1F91010B1 +:1034A000A4F17F03C4F17F0CB8F1020F0AD04FF0F2 +:1034B00002098A4231DDB8F1000F1ED0984252DD78 +:1034C000021B31E08A4205DD98420EDD01212970A0 +:1034D000021B05E009DA844509DD00212970021983 +:1034E00058460B9914F0A1FC01E04FF0010938880F +:1034F0003080B9F1000F1DD01EE0B6F900707F1AC0 +:10350000A2EB010100D57F42002900DA49428F4237 +:1035100028DC984227DD021B1FE024DAB8F1010FF6 +:103520000CD084451FDD021958460B9914F07DFC20 +:10353000388830804FF0000A50467DE4B6F90030FC +:103540005B1AA2EB010100D55B42002900DA494277 +:103550008B4207DC844506DD021958460B9914F0AE +:1035600064FC00E0328085F80090E5E72DE9FF4F2C +:103570008DB04FF0FF390F98C846002801DC0120BC +:1035800000E000200C901C98002801DC012000E0E5 +:1035900000200B9089498A48099049694FF0000B37 +:1035A00000EB41000A90DA461C990F9810F042FF98 +:1035B000069000200646059087E001250F9806F04A +:1035C00007072C4680450FDA109800EBE6000178DB +:1035D0000120B840014207D008F1010831460C9D96 +:1035E0000E9814F01BFC83461C9989450FDA1D9830 +:1035F00000EBE60001780120B840014207D009F154 +:10360000010931460B9C1B9814F008FC82460DB151 +:10361000002C59D102208DF81C008DF820000027C5 +:10362000FFF7D0F91DBB0F9907A8CDE90006049755 +:10363000CDE902180998012300EB48010D980E9A74 +:1036400000EB4800FFF716FF054601280FD1314671 +:103650000E9814F0E3FBA0EB0B0B4FFA8BF00DF17F +:10366000380C00909CE807003346FFF7DAFE1CBBDD +:1036700008A8CDE900061C99CDE902190A9804971B +:1036800000EB49011A98012300EB49001B9AFFF750 +:10369000F1FE044601280FD131461B9814F0BEFB01 +:1036A000A0EB0A0A4FFA8AF00DF16C0C00909CE82E +:1036B00007003346FFF7B5FE05B114B97F1C7F2F15 +:1036C000AEDB0598401C0590761CDDE905018842BB +:1036D000FFF673AF11B0BDE8F08F2DE9F04700257C +:1036E0001746884682462C46344E4FF001091CE0AE +:1036F00007EBE400017804F0070009FA00F20A423F +:1037000012D02146504614F089FB10F17F0F02D0F1 +:103710007F2804D007E0F06940F0400002E0F06943 +:1037200040F08000F0616D1C641C4545E0DBBDE8A5 +:10373000F0872DE9FF41214E716949B30025B06939 +:1037400040B300240DB1002C53D11C4A0023503249 +:10375000306C00F0CFFA194A00235832B169706C0E +:1037600000F0C8FA21462846FFF742FD124F38689C +:1037700090F87101800703D521462846FFF7F6FD32 +:10378000386890F87101C00715D02DB19CB903E0DD +:103790000125D4E70124D5E7706A084BB2690068B7 +:1037A0005833716C8DE80F00306A083B726900680D +:1037B000316CFFF7DBFE05E0A40710007804100071 +:1037C0001C72100005B184B9F06920F0C000F061EE +:1037D00025B1F84A7169306CFFF77FFF2CB1F54ACB +:1037E000B1690832706CFFF778FFBDE8FF41FFF761 +:1037F000E9B8BDE8FF812DE9FF5F4FF00109DDE980 +:103800000E6700259B4682462C46C84634E00BEBEB +:10381000E400017804F0070008FA00F20A422AD016 +:10382000385D38BB2146019814F0F8FAE1493AF9BD +:1038300015205039B1F910309A4210DDA6F17F02FF +:10384000904207DD821B2146019814F0EEFA4FF0FA +:1038500000090FE0C86940F04000C8610AE0C6F105 +:103860007F0107F80480814204DD82192146019816 +:1038700014F0DBFA6D1C641C02988542C7DB4846D5 +:103880006AE52DE9F04FCB4C85B0503C6169B9B386 +:1038900000208346A069A0B300208246BBF1000F40 +:1038A00002D0BAF1000F5AD1C34802AD0DC885E865 +:1038B0000D007F23BF4A206C00F01CFABD4A7F2315 +:1038C0000832A169606C00F015FA0027A14602A831 +:1038D0005D4650F8278054461521B84816F0C0F8C8 +:1038E000B6482621153016F099F8D9F81C10002694 +:1038F00021F04001C9F81C10FFF764F835B113E05E +:1039000000E001E00120C4E70120C6E7AB49A94B74 +:10391000CDE90081D9F82010D9F814200868D9F829 +:103920004010FFF768FF05467CB9A449A14B15314B +:10393000CDE90081D9F824100833D9F81820086897 +:10394000D9F84410FFF757FF0446FFF781F805B197 +:1039500014B9761C182ECFDB7F1C032FB7D305B00C +:10396000B9E62DE9F041934D0026503D012704466C +:10397000EE61012849D02F70A879697A08430CD0EC +:1039800000238C4A6969A86B00F0B4F9894A0023C6 +:103990000832A969E86B00F0ADF9E879697A084363 +:1039A0000AD084496A69286C14F04AFA8149AA69E4 +:1039B0000831686C14F044FA287910B10020FFF740 +:1039C0000BF96879C0B1287938B16978A86A00F034 +:1039D0007FF96978E86A00F07BF90120FFF7FCF8CD +:1039E000687948B1A978286B00F072F9A978686BFA +:1039F00000F06EF9FFF72CF8A87900B3FF20704AA9 +:103A000001462CB1012C09D00DE003202870B3E74A +:103A1000116891F8490191F84A1104E0116891F890 +:103A20005A0191F85B11FFF74BFAE978286B00F027 +:103A30004FF9E978686B00F04BF9FFF709F8012CB2 +:103A400008D02E70FEF7BEFFE87970B1287A012801 +:103A500003D008E002202870F4E73846594F387048 +:103A6000FFF70FFF3E70FFF764FEFEF7ABFF012C80 +:103A700008D01021E86900F053F9E86920B100206E +:103A8000BDE8F0814021F5E70120F9E770B50C466B +:103A900013F09BFC474D503DC5E9140113F097FC12 +:103AA000C5E916010821434814F038FD6861082172 +:103AB00005F1580014F032FDA86104F19000A862ED +:103AC000401CE862401C2863401C68634B38A863B4 +:103AD0002030C5E90F044838686474309534C5E96E +:103AE000120470BD10B538490020FFF7CFFF3149EF +:103AF000324850391C380862314B001D4862186842 +:103B00004FF0000490F8382112F001020A7104D03D +:103B1000886A0470C86A047008E08A6A90F84101F3 +:103B200010701868CA6A90F842011070186890F80E +:103B30003821C2F340024A7122B1086B0470486B0D +:103B4000047008E00A6B90F84301107018684A6B23 +:103B500090F844011070186890F83821C2F380037F +:103B60008B71C2F3C003CB71B0F839314B81B0F81F +:103B70003B318B81B0F83D31CB81B0F83F310B82C6 +:103B800090F845314B7090F846318B7090F8473182 +:103B9000CB7090F8040100F001000872100601D506 +:103BA00001200872C2F340104872BDE810400020A6 +:103BB000D7E60000C8041000E49B0100F00A1000E2 +:103BC000A4071000AC0710006C82012010B56F49EB +:103BD0000120FFF75BFF6F4900226D484A61486290 +:103BE0006D4CC1E914222068134690F84C2112F064 +:103BF00001020A7104D0886A0370C86A037008E081 +:103C00008A6A90F8550110702068CA6A90F85601C7 +:103C10001070206890F84C21C2F340024A7122B122 +:103C2000086B0370486B037008E00A6B90F857014B +:103C3000107020684A6B90F858011070206890F856 +:103C40004C21C2F380038B71C2F3C003CB71B0F877 +:103C50004D314B81B0F84F318B81B0F85131CB8170 +:103C6000B0F853310B8290F859314B7090F85C31B9 +:103C70008B7090F85D31CB7090F8230600F0010056 +:103C80000872100601D501200872C2F34010487274 +:103C9000BDE81040012064E670B50546012400200F +:103CA00013F0CBFE022013F0C8FE680703D5FFF720 +:103CB00019FF00F00104280702D5FFF787FF044031 +:103CC000022013F0D5FE002013F0D2FE204670BD76 +:103CD00002788A4201D9511A00E000210170704730 +:103CE00010B5144611F07AFCA04201DC012010BD91 +:103CF000002010BDF0B500252C464FF0010C0CE063 +:103D000002EBE40604F0070736780CFA07FE1EEA19 +:103D1000060F01D003556D1C641C8D42F0DBF0BD15 +:103D200070B504460D46C00702D083200FF0B0FCEA +:103D3000A00703D5294684200FF0AAFC600703D50D +:103D4000294685200FF0A4FC200703D529468620AC +:103D50000FF09EFC600603D529468B200FF098FCDF +:103D6000200603D529468C200FF092FCE00503D5F0 +:103D7000294687200FF08CFCA00505D52946BDE813 +:103D8000704088200FF084BC70BD000004830120C7 +:103D9000E40A100078041000A4071000DFF858812E +:103DA00008B5564D00245648C8F80040DFF854A125 +:103DB0002C60DFF854910460544ECAF80040C9F8F2 +:103DC0000040DFF84CB1346000226B465946104683 +:103DD00013F0DCFD0098810713D5FCF70FFB2F686B +:103DE0002C60FCF709FB17F0530F02D03846FEF7A2 +:103DF000BFFC17F4D67F02D03846FFF74DFF0221F3 +:103E000076E0410516D5FCF7F9FADAF80070CAF841 +:103E10000040FCF7F1FAF80701D0FCF701FEB80703 +:103E200001D5FCF758FE780701D5FCF710FE4FF4DA +:103E300080615DE001060CD5FCF7E0FAD9F800706E +:103E4000C9F80040FCF7D8FA3846FDF7DDFB8021C1 +:103E50004EE0C1010CD5FCF7D1FA2E48076804608A +:103E6000FCF7CAFA3846FDF72CFC4FF080713FE0B2 +:103E7000C10404D5FEF734FD4FF4805138E001024F +:103E800004D5FCF799FE4FF4000131E0010502D59D +:103E90004FF400612CE041020CD5FCF7AFFA377803 +:103EA0003460FCF7A9FAF80701D0FDF70AFD4FF4DA +:103EB00080011DE0C1050DD5FCF7A0FAD8F800700F +:103EC000C8F80040FCF798FA3846FCF72AFD4FF492 +:103ED00080710DE0410104D5FDF79CF84FF0806141 +:103EE00006E000017FF570AFFDF7ABF84FF0006121 +:103EF000002013F02EFD67E7B0071000B407100094 +:103F0000B8071000BC071000C0071000C40710005D +:103F1000839FF00DC807100010B5114811490068C3 +:103F20000B6893EA000F13D00F4A8407126810D56C +:103F300092F8E642E40702D043F002030B60C005AA +:103F40000AD592F8960C400702D543F480700860B9 +:103F500010BD23F00203F1E723F48070F7E70000BF +:103F6000D407100000051000A40710002DE9F0414F +:103F70007A487C4F02687A4892F8311080F8301005 +:103F800092F8304080F831403A7B80F8332007F1D6 +:103F90003C0240F8242BBA7B42727A7B827697F8F7 +:103FA0003A30C37697F83B2002777D7DC5746E4D1D +:103FB00045612438012B00D111464C4325B2002421 +:103FC0006E0080460FE022462946B86810F0CCFA11 +:103FD0000146D8F8002005FB04F002EB4000324611 +:103FE00015F09DFC641CB87BA042ECDC98F837000F +:103FF0004446012806D194F830205B48921CB969E8 +:1040000015F08DFC59485A49007809780843400753 +:104010000DD5387D94F83110484301B252488E30A6 +:104020004A0060603969BDE8F04115F078BCBDE830 +:10403000F0812DE9F0414D484D4E0025046830686F +:104040000443012013F0F9FC4421454815F008FD14 +:10405000E00706D0FFF78AFFE00601D500F059F827 +:1040600001254448454F02683D48C0E907243168AE +:1040700041623C49404E4B688362CB7B80F83530CF +:1040800091F8381080F836103178002380F82C1021 +:1040900080F84130062905D13978052902D101215E +:1040A00080F84110E10711D0E1060FD52B490968CE +:1040B00091F80032DB0702D042F01002C26191F8A1 +:1040C000BA10C90702D042F02001C161012013F0EB +:1040D000CFFC30783870002DA9D0052807D00628ED +:1040E00005D00121BDE8F041022013F006BC0221F9 +:1040F000F8E79CE7204810B50078082808D0194850 +:1041000090F83910006B00F040FDBDE8104090E7DA +:1041100010BD2DE9F0411148124E114D0068316A71 +:10412000012790F8312090F8304049B10E4885F8C9 +:10413000302018305200286115F0F1FB85F83D70F1 +:10414000716A002909D0084885F831404230620080 +:10415000686115F0E4FB85F83C7068E7A40710007F +:10416000148410002C0B10006407012004051000BB +:104170000805100000051000F8041000D804100015 +:104180002DE9F0412148234E0025047820484FF0C6 +:1041900001070560316891F87110C90600D5076004 +:1041A00000F082F8012000F037FC052C1FD0062C0F +:1041B0001DD01948077008F023FC306890F8711082 +:1041C000CA0616491BD50D6090F80022D20703D10C +:1041D00090F8BA00C00701D008200860012105202E +:1041E0000FF031FD4FF48071002013F086FB00F0DA +:1041F000CEFDBDE8F0410221012013F07EBB08682E +:1042000020F0020040F00400E7E70000F80410008E +:10421000FC041000A4071000FA041000B0071000FE +:1042200010B5040012D0FCF7E9F8584801682143A2 +:104230000160FCF7E1F8012105200FF004FDBDE865 +:1042400010404FF48071002013F057BB10BD0146A1 +:104250000020C9070BD04E490320096891F80022BD +:10426000D20703D191F8BA10C90700D00B207047CC +:1042700010B5C00717D04648006890F8C10C010679 +:1042800001D440060FD5FCF7B9F84248016841F067 +:1042900008010160FCF7B0F8BDE810404FF4800160 +:1042A000002013F02ABB10BD10B500F070FD0221F4 +:1042B000012013F04EFB012013F0BFFB44213648D0 +:1042C00015F0CEFB3449012081F82C0013F0D0FB0F +:1042D0000121022013F011FBBDE8104000F095BB56 +:1042E0002DE9F0412D4900260868020603D520F08B +:1042F0008000012608602A4F0446386890EA0405C9 +:1043000029D064B170B105EA04000546FFF7B0FF9B +:104310003146284600F02BF83C60BDE8F081FFF7FD +:10432000C3FFF9E700F033FD0221012013F011FB78 +:1043300000F097FA00F061FB25402846FFF798FF50 +:104340003146284600F013F800F048FB0221012016 +:1043500013F0D3FAE0E7002CDFD1124800780528EB +:1043600001D00628D9D13C60BDE8F0419CE710B5EA +:10437000012904D0FFF76BFFBDE8104050E70A4861 +:104380000078012801D10949087010BDB00710005C +:10439000A4071000C407100014841000D0071000F8 +:1043A000FC041000F8041000B2051000E60710002D +:1043B0002DE9F047DFF8F8930027FE4ED9F800000A +:1043C000B84690F84010C9075DD0FB4D2978022906 +:1043D0000ED0052909D0062907D090F841400EF0EB +:1043E0004AF90022012806D016E090F84340F6E78B +:1043F00090F84240F3E7287805280DD01046B260C7 +:10440000A04240DDD9F8000090F8401089070FD590 +:104410002978022904D00BE0B068401CB060EFE7B7 +:10442000B179491CC9B2B171022901D90121B17117 +:1044300090F8BD0AC0070ED02878022803D00428BF +:1044400001D0052810D130797179401CB0FBF1F30F +:1044500001FB130030712878022803D0042801D012 +:10446000052801D14FF00108B260287805280FD047 +:1044700000F040FA054600F043FA40EA050400F077 +:104480004DFA40EA040786F803803846BDE8F08715 +:104490000127F8E72DE9F0470446002512F02DFF2B +:1044A000FFF786FF0646C5480078B043C00702D034 +:1044B000F00600D44025DFF8F88246B1D8F80000B5 +:1044C00090F8F401000702D500F037FA054346EAF8 +:1044D0000500DFF8E092C0074FF001071CD000F0A4 +:1044E0003AFA01462071D8F8000090F8BD2AD207A8 +:1044F00005D099F80330237499F80420627490F879 +:10450000CE20C2F34112022A06D390F8CF00000653 +:1045100002D5042900D12775680700D56771F00618 +:1045200011D5E771D8F8000090F8400080070AD54F +:1045300099F80600012802D0022802D003E0277370 +:1045400001E002202073680600D567729C4806606F +:104550009C4805609AE770B59B48964D9B4C007847 +:10456000022816D09A48007898B99A48007801280D +:104570000FD0994E307860B915F01EFB48B9A97874 +:104580002078814205D33178014302D093480078E6 +:1045900008B1002000E001202178A97070BD70B53D +:1045A00083480025834C006890F8C46186480078F1 +:1045B000022801D165702570FFF7CDFF58B16078F2 +:1045C00058B92078401CC0B22070B04205D925707F +:1045D0000120607001E065702570607870BD2DE984 +:1045E000F047044612F089FEFFF7E2FE804600F035 +:1045F00081F9054600F084F940EA050600F08EF9DD +:1046000040EA060700F099F9DFF8A49140EA0705AF +:104610004FF00107D9F8000090F8B301410601D42A +:1046200080060BD5FFF7BBFF40B1D9F8000090F82A +:10463000B301800600D5A77425F0100548EA0506E9 +:10464000F0072BD000F087F901462071D9F800005F +:1046500090F8CE20C2F34112022A06D390F8CF2060 +:10466000120602D5042900D1277590F876110906A3 +:1046700008D55B49497829B956490978012901D0FB +:104680000421A1715FEAC87108D090F8BD0AC00783 +:1046900004D04848C178217400796074700700D54F +:1046A0006771F00600D5E771E80602D4A07C012806 +:1046B00000D1E77142494348C1F800800560E5E652 +:1046C00010B501463C22474815F06EF90121BDE8BE +:1046D0001040084613F011B92DE9F047364886B06E +:1046E0000078022817D0DFF8C890354EDFF8D48064 +:1046F00001254FF0070A052811D0062835D00828D3 +:1047000068464AD0FFF76BFF37480090684612F0C2 +:104710001BFE06B0BAE66846FFF7BCFEF4E7684643 +:10472000002712F0EAFD8DF81350FFF741FE040058 +:1047300000D14027E0070CD0D9F8000090F87100B4 +:10474000C00604D500F007F98DF8040001E08DF8EB +:1047500004A0E00601D58DF80750780601D58DF844 +:1047600009503460C8F80070CEE76846002412F0A3 +:10477000C4FD8DF81350D9F80000012590F87100A0 +:10478000C00604D500F0E7F88DF8040001E08DF8CC +:1047900004A03460C8F80050B6E7002412F0ADFD64 +:1047A00001200D218DF804103460C8F80000ABE73B +:1047B000A4071000DC041000F8041000FC04100032 +:1047C0000805100004051000F9041000340710005B +:1047D000280510002905100018051000E507100035 +:1047E000DC0710002C0B100071460000F8B5614D7D +:1047F000801E0528296810D2DFE800F0030F0609A3 +:104800000C0091F8734009E091F8724006E091F8CD +:10481000744003E091F8754000E0012400260EF09A +:10482000F1FC00B101266946032013F0A0F80098BE +:1048300000B94EB12968142091F87110090600D50D +:10484000C820844200D2044604B901242046F8BDA1 +:1048500010B500F09CFA0221BDE81040012013F0D1 +:104860004CB810B5444C0020A0602071414800684D +:1048700090F87501C0F30112C0F3810100F003004C +:104880000FF0CDFD401C607110BDEAE738B5002087 +:1048900013F0D3F8394C3A49207808703948006849 +:1048A00010B100F0F6F801E000F0CCF82078FFF746 +:1048B0009DFF0446AFF2670100F05CFA2046FFF767 +:1048C0000BFF01280ED101216B460022084613F090 +:1048D0005DF80121084613F03CF82B48007830B110 +:1048E0000EF0E5FEBDE83840002013F0C1B8FFF738 +:1048F00001FCF7E725480078C00700D00120704789 +:1049000022480078C00707D01A48006890F80002D3 +:10491000C00701D010207047002070471B48007866 +:10492000C1071448006890F8BA0003D0C10701D04D +:104930001020704700F00100704714480078C0074D +:1049400007D00C48006890F87401C00701D004201B +:1049500070470020704707490120096891F8CE1080 +:10496000090603D50A48407808B10420704703209F +:1049700070470000A4071000DC041000F8041000C9 +:10498000F9041000D80710002C0B1000FC041000D4 +:10499000DC071000614810B5006890F87100C0078E +:1049A0000BD015F009F9012804D05D48017829B130 +:1049B000407818B15B490020486010BD012010BD4F +:1049C00010B500F03BF957490020574A48600221D2 +:1049D0001170564908705649087010BD51490020A1 +:1049E000514A486004211170524A01211170524A03 +:1049F00011704F49087000F021B94A490020486001 +:104A00007047484900204860704746490020486088 +:104A1000454901200870704710B5044600F00BF9B5 +:104A20004049087000F00AF905223F49012C04D0E2 +:104A30000878052803D0062800D10A7010BD06208A +:104A4000087010BD70B5384D364C287802280ED04D +:104A5000042808D0052805D100F0EDF808B1217828 +:104A600099B1207070BDBDE8704000F034B800F01E +:104A70002AF8012806D06068401C6060FFF78AFFB2 +:104A80000128EFD0BDE87040A8E72070062028700C +:104A900070BD2549C3074FF0040201D00A7070476A +:104AA0008307FBD4420701D5022002E0020702D5AA +:104AB000052008707047C20601D50620F9E7800678 +:104AC000F8D50820F5E710B500F0B5F804460DF06C +:104AD000D2FD204310BD70B5FFF7F5FF0025114C46 +:104AE000012818D06068401C6060FFF753FF012860 +:104AF00012D10A486168006890F87600401C00EB0B +:104B00008000B1EB400F07D915F056F8012802D00C +:104B1000BDE8704054E7656070BD0000A407100058 +:104B200078071000E8041000F8041000E2041000F8 +:104B3000DF041000E2071000E307100070B56B4AB5 +:104B4000002415686A4AB5F8F6611278052A01D181 +:104B5000B5F8FA61674AD2780AB1B5F8F86100226F +:104B60000FE030F91230002B00DA5B42B34206DD71 +:104B700095F8F531641CA34201DC012070BD521C84 +:104B8000D2B28A42EDDB002070BD2DE9F0410F4624 +:104B9000010049D0584D564E0024EC703078A046A4 +:104BA000022803D0032801D0052811D1002007B125 +:104BB0000120AA88121A14B201EB4000AA782146FB +:104BC00000F04EF8A87021464C48FFF7B7FF0446A6 +:104BD0006878012701280AD0F4B1307848490228C2 +:104BE00009D0032807D0BCB1052807D01BE085F801 +:104BF00001800124F1E72C70EF7002E0287870B991 +:104C00002C70086800280FD100F0C1F8BDE8F04111 +:104C10000221012012F071BE3078052803D114F072 +:104C2000CBFF012802D02C70BDE8F0812F70EBE79C +:104C30003149487070473048007870472E4901204C +:104C400088702A48006890F83000888028480078EA +:104C5000052803D0062801D0002008707047EDE732 +:104C60002DE9FC41244F8046144638780D461646FF +:104C700050B9012C08D121480A467F234146983873 +:104C8000009410F078FC00261848006890F8F411A1 +:104C9000C90700D08CB119486A0041464C3814F05D +:104CA0003EFE164A2B46983A02F14C01134810F08A +:104CB0003DFC387820430ED015E0B0F9FE11CDE967 +:104CC00000150E4AB0F9FC31983A414602F14C0009 +:104CD00010F0D9FCE5E709487F232A464146983879 +:104CE000009410F048FC3046BDE8FC81A407100099 +:104CF000F8041000945A1000F0041000BA090120C2 +:104D0000D8071000234908B50020486001228860B8 +:104D10000A704A70204A1070887020490870FFF7A6 +:104D20009EFFFFF7B2FDFFF76CFE6B4600225E218F +:104D3000012012F02BFE0098410703D5FFF7D0FAAF +:104D400004210AE0010703D5FFF7E6F8082104E093 +:104D5000C10606D5FFF714FA1021012012F0F9FD63 +:104D6000E3E78007E1D50221012012F0F2FDFFF711 +:104D70008DFDDAE70A49096891F87110090602D435 +:104D800000EB8000400080B2064914F00BBB14F029 +:104D90002CBB0000F8041000E4071000E607100028 +:104DA000A40710000148000000F067BC30B50023E4 +:104DB0000380012309E000EB430431F8135034F879 +:104DC000024C2C4420F813405B1C9342F3DB30BDB3 +:104DD0002DE9F74F06468EB00020CDE90C000446C1 +:104DE000FE48002A04707DD0032012F026FEFC4D00 +:104DF000FC4A31462B78FC4810F098FB032012F057 +:104E000037FE2878F8494200F84814F088FDDFF8AA +:104E1000E093D9F8000090F8B201C00609D52A78CD +:104E2000F149F448FFF7C2FF2A78F249F2480FF03F +:104E300075FCDFF8BCA3A946DAF80000B0F8CA1187 +:104E400061F30F07B0F9CC11059161F31F47B0F87A +:104E5000CE1161F30F08B0F9D01161F31F488B46F2 +:104E600090F8D21161F3070690F8DB1190F8DC019D +:104E700061F30F2660F317462878CDE90078012505 +:104E80000296CDE90350AF1E3B463A46DA490CA8DC +:104E900000F0EFFEDAF800100026DFF8608391F8EA +:104EA000B2010DF1300AC0F30012C0F380131A40B2 +:104EB00012EAD01F13D091F8D30191F8D21199F8CA +:104EC0000020CDE90310CDF800A0CDE901523B460A +:104ED0003A4698F80000002100F0B8FFC6B2C44876 +:104EE000006800E086E090F8B21109061CD5C449BC +:104EF000B0F9D501497801B15846CDE9066499F871 +:104F00000010CDE90105CDF800A0CDE903153B4621 +:104F10003A46B549B74800F0F6FF99F80000B549A0 +:104F20004200B14814F0FBFC99F80020AE49B548A6 +:104F3000FFF73CFFDFF8B8B2DBF8000090F8B211E1 +:104F4000490616D5AE49B0F9D701497801B105989F +:104F5000CDE9066499F80010CDF800A0CDE903145E +:104F6000CDE90105A0483B463A46A649763000F017 +:104F7000CAFFDBF8000090F8B211C1F30012C1F3D0 +:104F800080131A4012EAD11F29D00F9A0021012A5A +:104F900003D188F8004088F80240E6B190F8D311B8 +:104FA00090F8D421B0F9D90199F80030CDE9080280 +:104FB0000A91CDE90653CDE9046498F80200CDE9E1 +:104FC000020489483B463A468B49CDF800A076302A +:104FD00000F0E2FFC1B288F8006088F802100F9874 +:104FE00000908948804999F8002003687631874805 +:104FF00010F0A8FA11B0BDE8F08F2DE9F74F044684 +:105000008EB00020CDE90C00012A7CD1032012F0E3 +:1050100014FD7F4D74487F4A2B7821462A3810F0C2 +:1050200085FA032012F024FD28786F4942002A39BE +:10503000794814F074FCDFF8B881D8F8000090F8D3 +:10504000B201C0060AD568492A782A397348FFF7A1 +:10505000ADFE2A78714972480FF060FBDFF890913D +:10506000A846D9F80000B0F8DF1161F30F06B0F9D7 +:10507000E111059161F31F46B0F8E31161F30F07E9 +:10508000B0F9E51161F31F478B4690F8E71161F322 +:10509000070490F8F01190F8F10161F30F2460F328 +:1050A000174428780125CDE900670294CDE9035023 +:1050B000AE1E334632465A490CA800F0DAFDD9F844 +:1050C00000000024DFF8349190F8B2110DF1300A9D +:1050D000C1F30012C1F340131A4012EAD11F274650 +:1050E00015D090F8E81190F8E70198F80020CDE984 +:1050F0000301CDF800A0CDE901523346324699F8BC +:105100000100002100E0B3E000F0A0FEC4B2384886 +:10511000006890F8B21109061ED53949B0F9EA01C4 +:10512000497801B15846CDE9064798F80010CDE915 +:105130000105CDF800A0CDE903152B4933463246D1 +:105140002A39364800F0DFFE98F800003349420063 +:1051500025482A3814F0E3FB234998F800202A391F +:105160003048FFF723FEDFF888B0DBF8000090F846 +:10517000B211890615D52249B0F9EC01497801B17F +:105180000598CDE9064798F80010CDE900A0CDE9D3 +:105190000251154833463246049722494C3000F0FC +:1051A000B2FEDBF8000090F8B211C1F30012C1F3B7 +:1051B00040131A4012EAD11F50D00F9A0021012A41 +:1051C00003D189F8017089F8037034B190F8E811BF +:1051D00090F8E921B0F9EE0126E03BE01705100058 +:1051E000280710002E770120300A01209A0B012099 +:1051F000A4071000200B0120D20C01200C05100088 +:10520000DC071000100C0120E4061000860C0120C1 +:105210002707100004770120700B0120F20A0120FB +:105220001E0D0120E60B012098F80030CDE90802A0 +:105230000A91CDE90653CDE9044799F80300CDE979 +:105240000207334632460D49CDF800A00C4800F065 +:10525000A3FEC1B289F8014089F803100F980090AD +:10526000084898F8002006490368074810F06AF9D2 +:10527000C0E6064900200870704700001E0D01209E +:105280007C0A0120E40610005C0C01202E071000AF +:105290008B480021C0E90011C0E902111030C0E9BB +:1052A0000011C0E902111030C0E90011C0E902117B +:1052B00008468449087070472DE9F041DFF8048200 +:1052C000814D002188F800102868804E804F90F8AA +:1052D000B201804C80070BD50DF0EAF9296891F8EE +:1052E000C31188420FDDE07810B17B48007850B1DF +:1052F000286890F8B30100072CD53078012802D037 +:105300003878012826D1207808B9607810B3286849 +:105310003978B0F8BB41012902D03178012901D197 +:10532000B0F8C141B0F9BD11654801230A461030FB +:1053300000F0E0F828680123B0F9BF1160480A4680 +:10534000203000F0D7F822B2012311465C4800F06B +:10535000D1F811E05A484FF0FF311030C0E9001188 +:10536000C0E902111038C0E90011C0E90211203073 +:10537000C0E90011C0E90211584898F80020817B6B +:1053800062F386118173BDE8F0812DE9FF4F83B090 +:105390009346069991F84010022908D0012903D0BC +:1053A0000699898C890505D5454D20353CE0444D4D +:1053B000103539E04549424D0978012913D1484A51 +:1053C000127882B1474A1278012A0CD1464A1278E3 +:1053D000012A08D1454AD2E90034C5E90034D2E9AE +:1053E0000232C5E90232384A126892F8B22112F04C +:1053F0000C0F19D0C1B936490978A9B93549C9780E +:1054000091B93B49097879B9C2F38101012902D0E8 +:10541000022905D008E04FF0FF31C5E9021103E091 +:105420004FF0FF31C5E900114FF0000A9BF8021060 +:1054300014F0F0FB80469BF802002EE09BF8004041 +:105440004A460120002114F020FACDE900011CE0B9 +:1054500018F804100498814216D1D5E90010DDE94E +:10546000002311401840014326D0D5E902672246A7 +:105470000120002114F009FA06400F403E431BD0E2 +:105480000AF101001FFA80FA641C9BF80100A04297 +:10549000DEDA08F1280809F101009BF803108146C3 +:1054A0004945CBDA06995FEA0A00A1F826A000D0A8 +:1054B000012007B0BDE8F08F002008F80400E3E702 +:1054C000201E100010051000A40710002905100070 +:1054D00018051000945A100035071000405701209D +:1054E000340710002607100025071000501E10007A +:1054F000B706100070B50446F9480D46007801283B +:105500000CD04FF0FF30C4E90000F64800780128C5 +:105510000ED04FF0FF30C4E9020070BDF2482346C0 +:105520000178F24800F099FA204614F055FBECE7B8 +:10553000EF49EE4804F108031C462A4609782A3050 +:1055400000F08BFA2046BDE8704014F045BB70B502 +:105550001C4605460123049EFFF7CCFF0020207067 +:105560003070DF48DF4A01210078012801D018B1EE +:1055700005E0107870B102E01078012812D0D5E96A +:105580000002104319D0D5E90202104315D0217052 +:10559000317014E0D5E90003184308D02170107869 +:1055A000012804D1D5E90202104300D031702078DF +:1055B000012804D03078012801D0002070BD0120DE +:1055C00070BD10B504460020024605E034F91230E3 +:1055D000834200DD1846521C8A42F7DB10BD10B52D +:1055E0000C461146FFF7EDFF6043642190FBF1F09C +:1055F00000B210BD70B5BF4EBF4D3079296801288B +:1056000005D0BE484078A0B3B1F9B60170BD91F89D +:10561000010240062ED5B248B1F9B4410078012804 +:1056200010D1B14891F82712007842B2AF48FFF785 +:10563000D6FF30812968B1F8B421824202DBB1F88B +:10564000B4013081A7480078012810D1A84891F80A +:105650002712007842B2A5482A30FFF7C0FF296818 +:105660000446B1F8B421A24201DBB1F9B4412046AD +:1056700070BDFFE7B1F9B401FAE770B59D4CA049E0 +:105680000025257101200870257065709A48A57065 +:10569000E5700068B0F8B401E08000F0FFF9FFF7B2 +:1056A000E8FDE5602561E3E72DE9F84381468C4894 +:1056B0008846934906788B488E4C0F7805780020F1 +:1056C0000870E07000F0EAF98E48007848B12A4688 +:1056D00039464046FFF77CFB324639464846FFF7DD +:1056E0008CFCFFF787FFE080014682482279801C0E +:1056F000012AA0F10103009006D00A468248FFF774 +:1057000026FF2070BDE8F883B4F90820F6E72DE9FC +:10571000F04F0026DDE909BA9E463546DFF8D891FC +:1057200026E093F830706F43002319E0FC1830F93D +:1057300014C0DC4504DDB1F80080C444A1F800C009 +:1057400030F91440CAF1000C644508DA761CB2F84E +:1057500000C0B6B2002C00DA6442644414805B1CC2 +:10576000D9F8004094F83040641E9C42DEDC6D1C89 +:10577000D9F8003093F83170AF42D2DCAEF8006057 +:10578000BDE8F08F2DE9FF4F87B000245F48ADF8EA +:105790000C40ADF81040ADF8184005944078DFF8A3 +:1057A00054B19046A14601287AD0534A584B002163 +:1057B0001668B3F900300846B6F81E22DA4200D562 +:1057C0000121544A12781AB1534981F80090AFE090 +:1057D000514A127812B1012A4BD0A9E000297DD09C +:1057E000B6F810723F4E444D3178012905D140483A +:1057F00001783E482A300FF0F1FE29689BF804300A +:10580000B1F90E22012B03D1B1F822321A4412B29F +:10581000424BB3F90030934260DAB84202DA307892 +:10582000012804D03E4A30781278104356D1B1F89E +:1058300014023C4AB1F8121200B2B2F9002009B2C7 +:105840008DE8070006AB04AA03A94046FFF75FFFF7 +:10585000BDF81000BDF80C10884269D901200590F0 +:105860002868BDF81810B0F81602884260D80124E4 +:1058700031E047F6FF7596F83100EB430122A0F1C5 +:10588000010E1CE0284896F83070DFF8A0A030F92F +:105890001200A7EB000C57430221ACF1010C0BE006 +:1058A00094E007EB01083AF91800834200DA034656 +:1058B000854200DD0546491C6145F2DB521C9645D8 +:1058C000E0DCB6F818029842D1DBB6F81A02404282 +:1058D000A842CCDC14B100F0FDF82BE028E0000079 +:1058E0002607100025071000270710005C0C012078 +:1058F0002807100014051000A4071000DC07100092 +:10590000E30710002E071000501E1000B60510000F +:1059100074051000780710002905100072051000AA +:10592000280510003C07100038260120480D0120F2 +:1059300000F0E6F85D4EDFF878815E4D30780128A2 +:1059400004D198F8000058B1012811D085F80090D2 +:10595000317888F80010B4B301218BF8041035E0D9 +:1059600085F80090DDE90701012200F0EFF8EFE78C +:1059700006F09FFF50492F78504B096891F81C2280 +:1059800002F00F02BA4204DA00F58050D0F8E00FBE +:1059900028B1B1F81802B3F9002090420FDD85F864 +:1059A0000090B1F81802B3F90010884202DC9BF8AD +:1059B000000020B9DDE90701002200F0C7F82878CF +:1059C000401C2870C4E7FFE78BF804903C48059919 +:1059D00020F85E1FBDF8181041809BF8041001717B +:1059E0000BB0CDE670B5374A002423461278214625 +:1059F000521E52B2344D0DE035F91260864202DD7E +:105A0000491CC9B204E08C4200D921460C46002151 +:105A1000521E52B2002AEFDA8C4200D921462B4C9A +:105A2000294E00222478641E65B22A360DE036F92C +:105A30001540844202DD521CD2B204E0934200D9E8 +:105A40001A46134600226D1E6DB2002DEFDA934206 +:105A500000D91A468818C0B20AE62DE9F0471D465B +:105A60004FF00008C5E9008891460C46824610E0D8 +:105A70003AF9141049450CDDD5E900674FF00108EB +:105A800022464046002113F000FF06430F43C5E9BC +:105A90000067641EECD24046BDE8F0870C48002148 +:105AA000C0E90011C0E9021170470000290510008B +:105AB0002A0510002C051000A40710002E05100068 +:105AC00040570120270710005C0C01202807100018 +:105AD000501E100041490022CA70487800280ED19B +:105AE00008783F4B401CC0B208701B6893F8023224 +:105AF00003F00F03834202D2012048700A707047FE +:105B0000364900220A70487800280CD0C878344BF7 +:105B1000401CC0B2C8701B6893F80232B0EB131F70 +:105B200001D94A70CA7070472C4810B5817841700D +:105B300000210170C170FFF7A0FDBDE81040FFF724 +:105B4000A7BB264800214170817070472DE9F041C4 +:105B5000244B254C224DB3F90030012A05D02A6888 +:105B600092F81D62C6F1100212E002461E480FF0C4 +:105B7000DDFC0FE030F9137031F913C0A7EB0C070F +:105B800034F913C057430CFB06773F1124F8137008 +:105B90005B1EEFD200210E4619E0144A12F81120C4 +:105BA00012F0FF0390F83020A2EB030002FB01F299 +:105BB00004EB4202C0B2168003D107E022F8106065 +:105BC000401C2B6893F830308342F7DC491C28686E +:105BD00090F831208A42E0DCBDE8F0812805100011 +:105BE000A40710003C071000480D012038260120B2 +:105BF0002DE9F05F9846DDE90A9A93460E46044681 +:105C0000002532E02A460120002113F03EFE00EA82 +:105C1000090001EA0A0108431DD0FE48FE4910F8B8 +:105C20001500097840B2091A4FB2410004EB470051 +:105C300013F0F4FE00202080012009E004EB400175 +:105C400036F8102031F8021C114424F81010401CC2 +:105C5000B842F3DB04E04FEA4801204613F0DEFED1 +:105C600006EB480604EB48046D1C5D45CADBBDE845 +:105C7000F09F2DE9FF5F86B0DDE914AB0FFA8AF0E3 +:105C80000390DDF860800FFA8BF00490E3484078D1 +:105C900028B14FEA2A4003904FEA2B400490002499 +:105CA00039E0079908FB04F001EB4005DDE9080144 +:105CB000224613F0FDFDC00724D0169ACDF800A0AF +:105CC000CDE901B2DDE903214346284600F09CFC02 +:105CD000064617980F46012817D0B8F1010F14D0C7 +:105CE000CC48012530F9149009E0A8EB0502012009 +:105CF000002113F0CAFD86438F436D1CEDB2A94508 +:105D0000F3DA02E04FF0FF363746069800EBC400A6 +:105D1000641CC0E9006717988442C2DB0AB0A6E79A +:105D20002DE9F05F1D46DDE90A9A93460F460646C7 +:105D3000002420E0B7482246002110F81400281A59 +:105D400000F0FF08012013F0A0FD00EA090001EABD +:105D50000A01084305D04246394630460EF0DEFCC3 +:105D600004E04FEA4801304613F058FE07EB4507C0 +:105D700006EB4506641C5C45DCDB78E72DE9F84F53 +:105D800083460AA8002690E8280590B2894600902C +:105D900031463446B446374630460FE0DA0708D07D +:105DA00039F9102000FB004400FB027701449444C1 +:105DB000761C6D084FEA330300F101004045EDDB2E +:105DC00004FB06F001FB1105F5B107FB06F004FB2F +:105DD0000CF407FB114701FB1C06002410E006FB36 +:105DE000047090FBF5F1A1EB0A00009900F01CFF94 +:105DF00039F81420A2EB0A01081A2BF81400641CCD +:105E00004445ECDBBDE8F88F4FEA48024946584666 +:105E1000BDE8F84F13F083BDF0B50026354609B153 +:105E200000240DE00020F0BDD70704D030F9147035 +:105E30006D1C3E44EDB25B084FEA320204F10104EE +:105E40008C42F1DB96FBF5F000B2F0BD2DE9FF5F6F +:105E500086B00025DDE91619A8464FEA510A4FEA37 +:105E6000590B2C4649E0DDE90801224613F020FDDC +:105E7000C00741D01498524600EBC4010491D1E907 +:105E800000670120002113F000FD401E41F1FF31A9 +:105E90000F4004990640CDE90067D1E90001524660 +:105EA00013F006FDCDE902010821684612F036FB29 +:105EB000C7B2082102A812F031FBC6B2B819C0B2AD +:105EC0000490DDE90601224613F0F2FCC00704D07D +:105ED000DDE91701084400F0FF090498484503D3A1 +:105EE0005F4501D35E4507D222460120002113F011 +:105EF000CCFC054341EA0808641C15988442B2DBD7 +:105F0000284641460AE72DE9F04F85B08146119FAA +:105F10000024780092469B468846049036E00E980E +:105F200000EBC400D0E900561298012801D125F0F9 +:105F3000010550465946224613F0BAFCC0071CD052 +:105F4000DDE91401224613F0B3FCC00705D0414639 +:105F50004846049A13F0E3FC13E02A4633463946D8 +:105F60004046FFF759FFCDE90270CDE900564146A2 +:105F700048460F9AFFF702FF03E04846049913F0E2 +:105F80004DFD08EB470809EB4709641C1098844253 +:105F9000C5DB05B0BDE8F08F2DE9FF5F86B08A460E +:105FA00000211B9F04907800884689460C46DDF846 +:105FB00074B0059058E01498224600EBC400D0E974 +:105FC0000056DDE9080113F073FCC00741D0DDE99C +:105FD0001801224613F06CFCC0073ED03A46284612 +:105FE00031460EF0CFFB0090DDE91601224613F09A +:105FF0005FFCC00704D0DDE91D01084400F0FF0B81 +:106000000098584516D92A46334639465046FFF778 +:1060100003FF05E03826012028071000DC071000E8 +:10602000CDE90270CDE9005651461C9A0498FFF75D +:10603000A5FE12E0DDE90402514613F070FC224691 +:106040000120002113F021FC40EA080841EA090977 +:1060500003E05046059913F0E1FC04980AEB470A67 +:1060600000EB4700641C04901A988442A3DB40466E +:10607000494653E62DE9FF5F9846002537E0019930 +:1060800008FB05F001EB400B0099002601EB400AEC +:1060900037462A460120314613F0F7FBDDE910238D +:1060A0001040194008431BD00E98002400EBC5098E +:1060B00014E0F848025D3BF812102AF81410D9E9F0 +:1060C000000113F0F5FBC00706D022460120002195 +:1060D00013F0DBFB06430F43641CE4B24445E8D3F2 +:1060E0000E9800EBC5006D1CC0E90067EDB2029888 +:1060F0008542C4D3BDE8FF9F2DE9FF4F81B099468B +:1061000000253BE0029909FB05F001EB40010091FD +:106110000199002601EB400B37462A460120314603 +:1061200013F0B3FBDDE910231040194008431ED0E3 +:106130000E98002400EBC50A17E0D64810F804803A +:10614000009830F814202BF81820DAE900012246D4 +:1061500013F0AEFBC00706D042460120002113F029 +:1061600094FB06430F43641CE4B24C45E5D30E9800 +:1061700000EBC5006D1CC0E90067EDB203988542D5 +:10618000C0D306E72DE9F74FC34E0F468CB03068F9 +:10619000002190F83120012013F077FB441E41F1DB +:1061A000FF35BC49002018390870B821BB4813F0EE +:1061B00057FC032011F041FC306890F8E602C0075C +:1061C00014D0B748007888B9B6480178B6480FF0BF +:1061D00011FA3168B1F80923B449904202DCB4489D +:1061E0004078D0B1B34A0020D0700870B248DFF8D0 +:1061F000D0923946B0F90030B0480268D9F80000B2 +:106200000FF094F9A448006890F8010200064ED5FA +:10621000AC480078012804D049E0A6490120C870A4 +:10622000E4E70021DFF8A0A2DFF86CE239E0A74A3A +:1062300090F8300032F9112000FB01FB871A012091 +:106240002CE0D9F800600BEB000336F91320B2F113 +:10625000000C01DACCF10002BAF90080424513DDEE +:1062600091B1DEF8002092F83120521E8A420BD004 +:10627000012809D07A1E904206D05FEA0C0201D5AF +:10628000CCF10002AAF80020DFF844C236F813204F +:10629000401C3CF813C0624426F81320B842D0DBFF +:1062A000491CDEF8000090F831308B42BFDC03203F +:1062B00011F0DEFB784EDFF81CB2306890F81D015B +:1062C000C00714D07B48417A89B9817A79B9C078FE +:1062D00068B981480078012809D072489BF80020ED +:1062E0000178D9F8000001F085F804460D463068C1 +:1062F00090F83402400713D5CDE90045694F5E465A +:106300009BF800303A78D9F800100C98FFF770FC31 +:10631000CDE9004533783A7870480C99FFF700FDD5 +:10632000DFF874A1049B039ADAF80000DFF87481A7 +:10633000B0F8511261F30F03B0F95312059161F3F4 +:106340001F43B0F855121F4661F30F02B0F9571200 +:10635000069161F31F4290F85932029990F85D62FC +:1063600063F3070190F85C3298F8000063F30F21A3 +:106370009BF8003066F317410097CDE90121CDE984 +:10638000030322462B4655495548FFF772FC314618 +:1063900053480EF014FADAF800100026DFF840A196 +:1063A00091F834023746C0F38002C0F3C0031A40AC +:1063B000C0F34000024224D091F85A0291F85912D9 +:1063C0009BF8003098F80020CDF800A0CDE901231B +:1063D000CDE903102F48224618382B46D0E9021683 +:1063E00008463146FFF732FD06460F46084308D0FF +:1063F0002948006890F85E2230460EF059F90646AA +:106400000F462548006890F834128A0778D5B0F90D +:106410004B0201902648407808B106980190880602 +:106420000ED5CDF800A0CDE902459BF8003098F8D4 +:1064300000202C48D9F80010FFF71CFE294901E084 +:10644000D9F80010CDE906679BF8003098F800C035 +:106450000120CDF808C0CDF800A0CDE903302246D8 +:106460002B460C98FFF74FFD0B48006890F834025C +:1064700080063AD5CDE90245CDF800A09BF8003062 +:1064800098F800200C99D9F80000FFF735FED9F8EC +:1064900000102BE048051000A4071000181F100082 +:1064A000780710002707100004770120320710003A +:1064B000DC071000945A10003C0710005C07100025 +:1064C00058071000290510002E051000382601205D +:1064D000480D01202807100018051000D44F012096 +:1064E000601E1000841301200AE00C9998F8000047 +:1064F00042009BF800004243D9F8000013F00FFA65 +:106500005448CDE90045C346037898F80020524826 +:10651000D9F80010FFF76CFBDFF84081D8F80000D5 +:1065200090F83412090718D54D49B0F94D02497851 +:1065300001B105984749CDE9066700220B789BF821 +:106540000010CDF800A0CDE90332CDE901012246CB +:106550002B4641490C98FFF7D6FCD8F80000C146FD +:1065600090F83412C1F38002C1F3C0031A40C1F3A2 +:1065700040010A4231D000220E9B1146012B05D169 +:10658000384B9046C3E90288C3E9048856EA0703FA +:106590001ED0304B90F85A1290F85B22B0F94F029F +:1065A0001B78CDE9080207930A919BF80000049636 +:1065B000CDE905702B4822462B46D0E90410CDE9E1 +:1065C0000210CDF800A028490C98FFF7E5FC024620 +:1065D0002448C0E90421C0E90267D9F8000090F816 +:1065E0003402C00608D51B48CDE900459BF80010D1 +:1065F00002780C980FF010F8204629460FB0C9E435 +:106600001A490020087070472DE9F0470F46994657 +:10661000804611460A9E0DF0FCFF04460D46002FF1 +:1066200016D04B463A466FF0004140460EF010F847 +:1066300004F00102024304EA0200294001220EF0A4 +:1066400060F8C6F30722002A02D04B460DF0B9FFCE +:10665000BDE8F0872807100084130120A40710006C +:10666000DC07100030051000D44F01202D0710006A +:106670002DE9F05F1E4615460F46824600244FF076 +:10668000AA094BE0305D08B9285DE8B306F804902C +:1066900037F9140000F0C8F827F81400285D98B303 +:1066A00005EB040818F8011C814218D0AA2816D05E +:1066B0000AEB440B08F8019C3BF9020C00F0B4F81B +:1066C0002BF8020C311907EB440B01F8019C3BF944 +:1066D000020C00F0A9F82BF8020C285DA0B198F884 +:1066E0000110285D814218D0AA2816D088F80190A0 +:1066F0000AEB4408B8F9020000F096F83119A8F83E +:10670000020081F8019000E007E007EB4408B8F9C7 +:10671000020000F089F8A8F80200641C0A9884427C +:10672000B0D3BDE8F09F48490020086070472DE9CC +:10673000F74F464884B0924600788946002870D0CA +:106740004348006890F8700C80076AD54148009073 +:106750004148DFF8F4B0012507784FF00008DBF876 +:1067600000601FE00120A84030421AD13B4800EBF6 +:1067700085040098A17813F04DFAA27843460DE005 +:10678000217805E010F801C0AC4500D14354491C04 +:1067900094F801C08C45F5DA2830521CE17891421A +:1067A000EEDA6D1CBD42DDD90021049813F038FAF1 +:1067B00002900121049813F033FA0190002125483A +:1067C00013F028FA07460121224813F023FA06465F +:1067D000A9F10105E9B2049813F022FA6C1E0390A6 +:1067E000E1B2049813F01CFA8146E9B2194813F09B +:1067F00011FA0546E1B2174813F00CFA0446CDF839 +:1068000000A0DDE9011033463A46FFF731FF234689 +:106810002A464946CDF800A00398FFF729FFCBF898 +:10682000008007B0BDE8F08F0949096891F8782C1D +:106830004243642092FBF0F0B1F8762C00B2824221 +:1068400001DAB1F9760C70476C051000EC06100007 +:10685000A40710002227012075061000BA2A012083 +:106860002DE9F041F74E2A21F748376807F27C6599 +:10687000EC1C13F0D3F8F44897F8312097F8301057 +:106880002A3013F0C3F800221146EF4F33681DE0A1 +:10689000A05C884201DA521CD2B2A85C27F8110031 +:1068A00090B193F83060DFF8A0C3301AC0B20CF199 +:1068B0002A0C05E01CF80060761E0CF80060401CF5 +:1068C00093F830608642F5DC491C49B293F83100F8 +:1068D0008842DDDCBDE8F0812DE9F04F8946924623 +:1068E00086460021DFF85CB34FF0640C099E45E05A +:1068F00001FB06E700203EE0DBF80020802492F850 +:106900002D5B5FEA45781FD592F8158C884503D139 +:1069100092F8168C804526D092F8178C884503D1C2 +:1069200092F8188C80451ED092F8198C884503D1B6 +:1069300092F81A8C804516D092F81B8C884503D1AA +:1069400092F81C2C82420ED011B15A1E914219D1DC +:10695000AA0703D538B1721E904204D01AF800205D +:10696000D201B2FBFCF43A5C6243D41702EB5462EE +:10697000D2093A54401CB042BED3491C9942B7D305 +:10698000BDE8F08F19F80020EAE72DE9F05F9446A2 +:10699000AE4ADFF8BCA2DDF8308016789AF8002005 +:1069A0003746761E06FB02F400EB440506FB02C0E8 +:1069B00008FB0306A748DFF88C8201EB4404037848 +:1069C000A548DDF828B04FF000090279C178D8F861 +:1069D00000006BB101B942B190F8131C90F8140C8F +:1069E000814200D30146894626E090F8130C03E06B +:1069F00001B90AB390F8140C81461DE058463A4696 +:106A00000B9912F055FFC0070DD09AF8000008E06E +:106A1000335C34F9101003EB09025143C91125F816 +:106A20001010401EF4D2D8F8000090F83000A5EB0A +:106A30004005A4EB4004361A7F1EDFD2BDE8F09F6C +:106A400008B500931346854AB2F900200EF07AFD8E +:106A500008BD2DE9F05F804A1046D178007901B970 +:106A600008B1012400E000247D494B780021022B6D +:106A700001D3917000E000B1D170DFF8C8A1D078E7 +:106A80009146DAF80010B1F9B9C2B1F9D462B1F99E +:106A9000E87228B173480078012801D1B1F901C327 +:106AA00071480078052801D0062801D1B1F9B6C295 +:106AB000022B05D3B1F8BD2212B1B1F9BDC20DE070 +:106AC00063B191F8BC2262440FFA82FC91F8D7229C +:106AD000324416B291F8EB223A4417B2634DDFF814 +:106AE00090E1644AA5F800C0AEF800601780624AE1 +:106AF00005283DD006283BD091F8BB82DFF884B151 +:106B0000ACEB0808A2F8008091F8D682A6EB080842 +:106B10005A4EA6F8008091F8EA82A7EB0808584F71 +:106B2000A7F800809BF80080B8F1000F05D09BF813 +:106B30000280ACEB080CA2F800C099F800C0DFF8A6 +:106B400014B1BCF1000F1ED09BF800C0BCF1000FC7 +:106B500019D0B1F805C2A5F800C0B1F80782052820 +:106B6000ACEB080CA2F800C005D0062803D00AE060 +:106B700091F8B882C2E7B1F80A022880B1F80CC2D5 +:106B8000A0EB0C00108099F8020028B9B5F800C0FD +:106B9000AEF800C01088308034B93648B5F800C06F +:106BA000A0F800C010883880DFF8DCC02888374D96 +:106BB000ACF80000DFF8D880B2F90000288098F81F +:106BC00000206AB113B191F8752C00E00022B1F8F1 +:106BD000723C1A44ACF8002091F8741C511A2980B8 +:106BE000B7F90020B6F900100DF012FC294E00B2E2 +:106BF000308098F8001021B1B5F900100DF016FCA6 +:106C000030809BF8000024490028DAF8000002D008 +:106C1000B0F8450206E0B0F843220A80002C02D00A +:106C2000B0F84702088009E7884202DC49428842FE +:106C300000DA08467047F0B50026354609B1002451 +:106C40003AE02BE0A40710003826012027071000A7 +:106C50002807100029051000945A10003C07100066 +:106C6000DC0710003307100024071000D4061000C2 +:106C7000D6061000D8061000DA061000DC06100058 +:106C8000DE06100078071000E8061000EA06100083 +:106C90003A071000E0061000E20610000020F0BDE8 +:106CA000D70704D030F914706D1C3E44EDB25B0878 +:106CB0004FEA320204F101048C42F1DB96FBF5F05D +:106CC00000B2F0BD2DE9F05F5FEA0109DDE90ACE0F +:106CD0000E9E05467ED052EA03007BD04FF000089E +:106CE0009A464046414647464446B346434611E02D +:106CF000D60709D035F9136003FB031103FB0644E3 +:106D00001844374408F101085FEA5A0A4FEA320290 +:106D100003F101034B45EBDB01FB08F200FB1026FE +:106D2000002E57D004FB08F200FB1728794304FB20 +:106D300010175FEA0E0057D00024A9F1020210E0FC +:106D400008FB047090FBF6F0A0EB0C005946FFF72F +:106D50006BFF35F81410A1EB0C01081A25F814008C +:106D6000641C9442ECDB0C984FEAC01A0D984FEA71 +:106D7000C01B08FB047090FBF6F935F91400594666 +:106D800000EB8000000290FBF9F00DF057FB51463C +:106D90000DF058FB09FB00F14FF00A0991FBF9F0E7 +:106DA00035F81410A1EBE01025F81400641C08FB62 +:106DB000047090FBF6F635F91400594600EB80009C +:106DC000000290FBF6F00DF039FB51460DF03AFB56 +:106DD000464300E007E096FBF9F035F81410A1EB0C +:106DE000E01025F8140029E6002210E008FB0270EC +:106DF00090FBF6F0A0EB0C005946FFF715FF35F8B5 +:106E00001210A1EB0C01081A25F81200521C4A4579 +:106E1000ECDB13E62DE9FF5FDFF814A40E46002437 +:106E20000E9D1F4691464FF466713046CAF80040E9 +:106E300012F0F4FD002130462C6012F0EBFE044607 +:106E40000021009812F0DEFEDFF8E8B30246FA4EA9 +:106E50009BF800C019E030784FF001080FE032F9DC +:106E600010304B4501DD04F8008032F91010F94272 +:106E700005D52B68002900DA494219442960401ED3 +:106E8000EDD23078283402EB4002BCF1010CE2D2A2 +:106E9000EA48C07800281BD00021009812F0B2FE0A +:106EA000E7499BF80030524634780D680EE02146E1 +:106EB00008E030F91160B5F8FB72BE4202DD1668D9 +:106EC000761C1660491EF4D200EB44005B1EEED225 +:106ED000BDE8FF9F05E030F912308B4201DD012053 +:106EE0007047521EF7D2002070472DE9FC47D54865 +:106EF000D54DD64FB0F90230B5F900003A88594364 +:106F0000821A14B2642291FBF2F109B2814200DDCF +:106F100008462880CA48026892F88112490632D58C +:106F2000CB4EB2F89DC2B6F900109C4526DAB2F8F5 +:106F30009F328B4222DD8146C648B2F8A4C2006867 +:106F40000CEB8C08B0EB480F18DD8021CDE9003147 +:106F5000B2F8A21292F8A13201EB81014A000CEBC7 +:106F60008C01C84649000DF0A5FC01B2D8F800001C +:106F7000B0F89F228A4201DAB0F99F12B6F90000F8 +:106F8000814200DD31802888001B3880BDE8FC8705 +:106F90002DE9F843DFF8C092B04DDFF8C482B9F9AB +:106FA00000000026420034462968D8F8000012F09C +:106FB000B6FCA248A24F017819B1AA490978012963 +:106FC00002D0C078A8B11BE0386890F801124907D8 +:106FD00007D5B0F92032A44AD8F80010286809F083 +:106FE000CBFB386890F80112090709D590F82442C4 +:106FF00006E09E484078002838681FD090F8254168 +:107000009348904A934B0088121D80B20090B9F9C2 +:10701000001028680EF0C7FA8A4F78801CB121460C +:107020002868FFF762FF9249B7F90200B1F9001032 +:10703000884200DD01263046BDE8F88390F82641FD +:10704000DEE72DE9F74F8B4F86B0DFF8F4A13E78ED +:107050000496DAF800009346002190F831200120D0 +:1070600012F013FC441E41F1FF35304607F0F3FFE8 +:107070004FF0000887F80080FFF7EBFC7148022111 +:1070800008300AF08FFD6D4F6E4EDFF8EC913878C6 +:1070900008B9787828B15946B2680798FEF704FB1A +:1070A00001E089F80080F87ADFF8B0B1012805D056 +:1070B000787A012802D0B87A012803D199F8000023 +:1070C00001284BD06D480078012806D1049A069912 +:1070D000B068FFF757F804460D46DAF8000090F85C +:1070E00035124A0605D4090603D490F82D0BC007C3 +:1070F0000CD06348634A00780094CDE901505648AB +:10710000B168B0F900300846FFF73FFCDAF800003C +:1071100090F834120A0604D4490610D5F9780129EA +:107120000DD1B0F9490201A9009081E8310042482F +:10713000B16803783F480278084600F0E1FA3E481B +:1071400002783C480178B068FFF7F1FA4E48049B9A +:10715000B1680268DBF80000FFF772FCDAF80000A3 +:10716000554690F81D1CC90715D0334B90F8161CD6 +:1071700090F8150C1C7800FB0411DBF8000020F8D7 +:10718000118029681B7891F8184C91F8171C01FBA5 +:10719000034120F811802B48022108300AF060FDDD +:1071A000F97A0020012905D0797A012902D0B97A2B +:1071B000012903D199F80010012901D0FFF7E8FE59 +:1071C000324A334E0121C2F80080194AC2F80080C9 +:1071D000304AC6F8008082F80080FB7A012B5FD02D +:1071E0007B7A012B5CD0BB7A012B59D0F8B111709E +:1071F000387818B11B48007801285DD0022401219D +:1072000025480AF0CFFC2968244AB1F86B021278AD +:107210000AB1B1F86002009603B20D48B0F900203F +:107220001D480168DBF80000FFF7F4FD3DE03BE09E +:10723000C80610002707100028071000945A1000F5 +:10724000A407100070051000D4061000DA06100024 +:10725000E2061000640710003C0710005007100001 +:1072600054071000290510004E9C0100DC07100097 +:10727000E0061000E2071000140510002D071000B2 +:1072800037071000C0190120E4061000C4061000E2 +:10729000CC0610002F0710008C061000B706100057 +:1072A00099F80000012804D00124204609B0BDE867 +:1072B000F08F06241170F8E70324A0E7FEB5074617 +:1072C000F948002406780470FFF7C3FB0221F74851 +:1072D0000AF068FCF648F54D0078083D012804D115 +:1072E00032463946A868FEF74DFFF24EF24F30683D +:1072F00090F835124A0605D4090603D490F82D0BF0 +:10730000C0070DD0ED48EE4A007802904FF0FF30F4 +:10731000CDE90000A968B7F900300846FFF735FB52 +:10732000A968B7F90000E74D4200286812F0F7FAA3 +:10733000306890F81D1CC90714D0E34A90F8161C59 +:1073400090F8150C137800FB0311286820F8114001 +:107350003168127891F8183C91F8171C01FB023142 +:1073600020F811400221D1480AF07AFCD748B7F939 +:107370000020B0F900102868FFF7ACFDD449D54EC5 +:107380000C60D54934600C7090B101200870014642 +:107390000224D2480AF006FCD148009647F6FF7353 +:1073A000B0F90020CD4801682868FFF733FD00E000 +:1073B00001242046FEBDBD4910B508390020886073 +:1073C000C5490870FFF71CF9FFF7ADF9BDE810409B +:1073D00000F013B910B500F02AF9FFF741FAB548EB +:1073E000006890F88102000603D5BDE8104009F05E +:1073F000C2BA10BD2DE9F74F86B00020CDE90000DC +:10740000CDE902008146AB480F46164600680025CC +:10741000B0F91E110591B0F9200104902FE005FB91 +:1074200006F00FFA80FB04980124C0F1000A2A46F6 +:107430002046002112F029FAA4460A460CFA05FC5F +:107440004FF0000817E006990BEB040331F9131015 +:10745000059B994201DC514506DADDE9003403431E +:107460001443CDE900343446494502DDCDE902C874 +:107470008946641C24B2B442E5DB6D1C2DB2BD42CA +:10748000CDDB8C4C206890F822212AB1DDE9000187 +:107490000DF00EF9CDE90001206890F81D0180077C +:1074A00062D5DDE9000108435ED00821684611F08D +:1074B00035F8C1B2206890F82301884254D9401EA3 +:1074C00040F34702DDE902010DF0F2F8CDE90201D7 +:1074D00005460E463A460120002112F0D6F9401E1C +:1074E00041F1FF3100EA05023140CDE902210821D6 +:1074F00002A811F013F82168C0B291F8231181425B +:107500002CD97A1E0120002112F0BFF9DDE90223F7 +:1075100010401940084310D0781E012305E0029D59 +:1075200003FA00F12943401E0291216891F82311CA +:10753000791A491E8142F2DB10E0D0070ED00020FC +:10754000012306E0029D03FA00F12943401CC0B26A +:107550000291216891F823118142F3D89DE80F0030 +:1075600010431943CDE900012068002190F8312033 +:10757000012012F08AF9401E41F1FF33DDE90012CB +:1075800001401A40CDE900122068484D90F82701CB +:10759000083DF0B12B786BB15B1CDBB22B709842CD +:1075A00001D3114301D0002012E0D5E90401CDE957 +:1075B00000010EE04B48007858B1114309D1D5E9DC +:1075C000040150EA010204D0CDE90001D8B2401C08 +:1075D0002870DDE9000108430BD12068002190F8F4 +:1075E0003120012012F051F9401E41F1FF31CDE967 +:1075F00000010098C5E9040158E62E4810B500685E +:1076000039493A4AB0F8B9320B80B0F8D412384C44 +:107610001180B0F8E8222280364C2380364B198046 +:1076200036490A802E49B0F84302088010BD2DE982 +:10763000F84F204C206890F8319010F8307F90F887 +:10764000450100F00302C0F38101C0F301100CF00A +:10765000E6FE256880464FEA89002B4605F62F3660 +:107660007843174A802105F6553500E01154401E35 +:10767000FCD293F82D0BC00713D000249246DFF8FC +:1076800038B00CE00097BBF900104B4604FB01A09A +:107690002A463146FFF720F9641C4C354C364445E8 +:1076A000F0D9BDE8F88F0000E2071000780510005F +:1076B0002D071000A40710003C071000370710002A +:1076C000C01901205007100028071000E006100024 +:1076D000C4061000CC0610002F0710008C06100006 +:1076E000E206100034071000D4061000D606100081 +:1076F000D8061000DA061000DC061000DE061000C6 +:107700002DE9FF4F8646DDE90FAB1D46DDF83490CD +:107710002FE00199002601EB4507184930464A5DE4 +:107720000E991446C1F1000C09E004FB03F137F98E +:107730001110494503DA614501DD0E44401C641E09 +:10774000F3D200B9012096FBF0FC504659460EEBEF +:1077500045060CE0C40707D002FB03F437F8148099 +:10776000A8EB0C0826F8148049084FEA3000521E96 +:10777000F0D26D1ECDD2BDE8FF8F00006226012041 +:107780009048002101704180704730B58E49024613 +:1077900001200B6893F845464CB18A4DB2F842106F +:1077A0006D68491B00D549428C4200DA002093F8ED +:1077B0004636002B12D08349B2F91A500831B2F97B +:1077C0001820B1F90240B1F90010641B891A644312 +:1077D00001FB01415B43994200DD002030BD2DE9F2 +:1077E000F047DFF8E491DFF8DC8105004FF0050495 +:1077F0004FF0060613D095F8C60100F04EFA044685 +:10780000D9F80000012790F8440618B1B5F84210E5 +:10781000814210D8A86900F0AAF860B157B398F86F +:10782000000000270121072810D2DFE800F006063B +:10783000263F720606000027F0E7052C04D0042C32 +:1078400006D0012C07D015E088F80070BDE8F0875D +:1078500088F80010FAE7FFF793FF022088F800008D +:10786000A8F80270B5F84200C8F80400A869C8F882 +:107870000800EBE788F80060E8E7B8F80200401C71 +:1078800080B2A8F80200032C04D0D9F8001091F8B7 +:107890003F164AE0032088F80000A8F80270D5E7F8 +:1078A000052CD3D02846FFF770FF2FE0B8F8020070 +:1078B000401C80B2A8F80200012C1FD0D9F800208B +:1078C00092F8403642468342C0D8167098F80100BC +:1078D000012801D00328B9D13C483A4A4170192106 +:1078E000083281705188C170090A01711188417193 +:1078F000090A8171BDE8F0470CF0ABB92846FFF7E3 +:1079000044FF042288F80020A8F802700028B1D0B3 +:107910009CE7B8F80200401C80B2A8F80200032CD3 +:1079200006D0D9F8001091F841168142B8D8A1E7E5 +:10793000052088F8000089E738B5002100916946E4 +:1079400000F089F91F4C012802D90620207005E0BB +:107950000098FFF744FF2078052801D0002038BDAB +:107960001A480121417005218170012038BDF0B510 +:10797000154906460120096891F84226930091F8BE +:1079800043261D46940091F83620D7074A8E898EEB +:10799000A2EB0302A1EB040112B209B20ED02346FE +:1079A0000F462C463114994206DBB94204DC31B251 +:1079B000A14201DB914200DD0020F0BD17460A46DE +:1079C000F0E7000088051000A4071000D01F100089 +:1079D00000F0ECBABA4890F82C00062801D005282F +:1079E00007D1B848B849006890F83E0200F00F008F +:1079F0000860B6490020487000F0E4BA70B5064649 +:107A0000B34800210278062A03D012B1052A00D01B +:107A10000121B048AD4C0278012A2ED0022A2CD088 +:107A2000032A2AD049BB12F0C7F8012825D0AA485A +:107A3000007806282AD1607820B1401E10F0FF009F +:107A4000607023D1002404EB041006EB4015294696 +:107A5000304604F0E4FE2946304604F018FF641C6A +:107A6000E4B20F2CEFD39D48007805280ED0BDE876 +:107A70007040102101200FF040BF9248006890F83C +:107A8000780060700A2801D20A20607070BD2DE96C +:107A9000F0410024054600F580560127D6F8E00F96 +:107AA00007FA04F1084208D004EB041005EB40107B +:107AB00000F118010C300DF0ADF8641CE4B20F2C8D +:107AC000ECD3BDE8F0812DE9F0474FF000094FF00D +:107AD000010A0646C8464C4600F580575546D7F879 +:107AE000E00F05FA04F108420AD004EB041106EB9A +:107AF000411191F8C601032802D1304604F0ADFED1 +:107B0000641CE4B20F2CEAD33046FFF7C0FF744880 +:107B100000216E4C016041608160C160A068C001BD +:107B200004D5304600F089FD012809D0BAF1000FD4 +:107B300006D0207A800603D53046FFF7FDFE814649 +:107B4000B9F1000F0AD1A068C0011BD5304600F082 +:107B50004DFB644908704FF0180898B160480CF06C +:107B600078F8B8F1180F0BD15D4808300CF06FF8B9 +:107B70005848807900EB001006EB40100CF054F8E8 +:107B8000FFF7FEFD0024A84606F5805708FA04F02A +:107B9000D7F8E01F01420FD004EB041106EB4115AA +:107BA00095F8C601082807D12946304604F06FFE33 +:107BB0002946304604F033FE641CE4B20F2CE5D3B2 +:107BC0003046BDE8F04719E72DE9F84F06463D4835 +:107BD000006890F8500CC00738D03046FFF757FFC8 +:107BE0003A4F4FF00009B868C00131D5304600F077 +:107BF000FEFB80463A4800240830CA464FF0010B8D +:107C000006F58055B94600901CE0D5F8E01F0BFA48 +:107C100004F05A46014214D004EB041006EB40175E +:107C2000B8F1000F0BD089F800202D480CF011F8A6 +:107C300000980CF00CF838460BF0F6FF01E089F8DC +:107C400000A0641C95F9EC0FA042DEDABDE8F88FC5 +:107C500087F80090FAE730B505460020034603EBAD +:107C6000031205EB421494F8C621012A0DD0022A12 +:107C70000BD0032A09D0042A07D0052A05D0062AEA +:107C800003D0072A01D0082A02D1401CC0B20C60E0 +:107C90005B1CDBB20F2BE2D330BD09280ED2DFE82C +:107CA00000F00D0505070909090B0B0004207047BA +:107CB000012070470220704703207047052070475D +:107CC00014841000A4071000E406100098051000AA +:107CD000880510003820100024071000F804100058 +:107CE000D01F1000B20510002DE9FE4FFE49B0F97B +:107CF00002C0B0F906700A68B0F90060934692F8C5 +:107D00003690918E5FEAC978B0F90450528E4FEAEE +:107D1000497809D0B8F1000F22DA961B551B66F39B +:107D20001F4465F31F431FE0B8F1000F07DAA2EB11 +:107D30000C0CD71B6CF31F4467F31F4303E067F37E +:107D40001F446CF31F435FEA897704D58E1B66F3EB +:107D50000F044D1B10E065F30F0466F30F0312E0F0 +:107D600065F31F4466F31F435FEA897507D5A1EBEE +:107D70000C0565F30F04CD1B65F30F0303E067F3F8 +:107D80000F046CF30F039BF830804F1CB2FBF8F527 +:107D90009BF831902EB2B7FBF9F52DB2002A75D0C1 +:107DA000002973D0002E71D0002D6FD01F144FF01A +:107DB000000B12D097FBF6FC6CF3070A97FBF6FC5E +:107DC00006FB1C77BFB24FEA244C624509DCA8F1E0 +:107DD000010262F30F2AB2B20CE06BF3070A00272C +:107DE000F1E79CFBF6F262F30F2A9CFBF6F206FB2E +:107DF00012C292B21BB28BB193FBF5FC6CF3174A23 +:107E000093FBF5FC05FB1C339BB224B2A14209DCB9 +:107E1000A9F1010161F31F6AA9B20CE06BF3174AE3 +:107E20000023F2E794FBF5F161F31F6A94FBF5F18F +:107E300005FB114189B202EB8202520092FBF6F27D +:107E40001FFA82FE07EB870403EB830264005200F3 +:107E500001EB810194FBF6F492FBF5F2490091FBF2 +:107E6000F5F1C4F10A04C2F10A02A4B292B289B2D5 +:107E70008DE816000AF0FF034FF0000C9B46CAF392 +:107E800007464FEA1A65CAF3072726E036E09B4506 +:107E900002D102990CB205E09F4202D10FFA8EF492 +:107EA00000E00A24019A31460FFA82F9009A0FFA8B +:107EB00082F80EE08E4201D14A4604E08D4201D1A3 +:107EC000424600E00A2204FB02C2491C0FFA82FC6F +:107ED00009B28D42EEDA5B1C1BB29F42D7DAA0F8E2 +:107EE0000CC080F808B0477202990182A0F812E035 +:107EF0008672C572019981820099C182BDE8FE8FA8 +:107F000070B57A48784D7A490378286801F11C04E5 +:107F100090F8512CCA811BB390F8402C8A76B0F8A7 +:107F2000412C4A80B0F8452C0A80B0F8432CCA8016 +:107F3000B0F8472C8A8090F8492C0A7690F84A0CC1 +:107F400048760846FFF7D0FE1C226949204611F00A +:107F5000E6FC286890F84C1C217690F84D0C23E044 +:107F600090F8522C8A76B0F8532C4A80B0F8572CEF +:107F70000A80B0F8552CCA80B0F8592C8A8090F845 +:107F80005B2C0A7690F85C0C48765948FFF7ACFEFB +:107F900057491C2201F11C0011F0C1FC286890F81F +:107FA0005D1C217690F85E0C607670BD4F49002014 +:107FB00008704870897821B94D498863C863A1F871 +:107FC00040009DE7494A9078002819D148498863C4 +:107FD000C863A1F840003831087043481378383935 +:107FE000006801F11C022BB190F8493C0B7690F827 +:107FF0004C0C04E090F85B3C0B7690F85D0C10762E +:1080000070472DE9F041044690F80E7290F8C66171 +:1080100090F8C7510B2084F80E02082084F8C6019E +:10802000052084F8C7012046A1690BF03DFE84F8C5 +:108030000E722E4984F8C66184F8C75100208870FA +:10804000BDE8F0812B4901224A7018228A70827E95 +:10805000CA70428B120A0A71027E4A71008B000AB2 +:10806000887170472DE9FE4F804622488B460021DB +:1080700080F82F100BF110000290BBF80C000BF1F0 +:10808000080608B947F6FF704FF00009CDE90090E7 +:108090004F4698F85B5036E0B078A84232D8F07876 +:1080A000A8422FD3E9B2144811F0B4FD824698F8E3 +:1080B000594017E03078A04213D87078A04210D30E +:1080C0001AF8040068B1E9B2E0B23246029B00F04F +:1080D000D4FA48441FFA80F91AF8040008B17F1C4A +:1080E000BFB2641C0AE00000A4071000B005100035 +:1080F00000201000D01F10002227012098F85A00FD +:10810000A042D7D26D1C98F85C00A842C4D264206B +:1081100009FB00F10198B1FBF0F082B2B8F844001D +:1081200028B164234343B1FBF3F189B20091FB49C9 +:10813000012381F82F300872000A48728F72380AC2 +:10814000C872F748019920F8731FA0F80290B8F898 +:108150004410C18007810271009941719BF8180099 +:10816000904206D89BF819100098814201D801204E +:10817000C4E60020C2E62DE9F041EA4AB1F9026006 +:10818000B1F900701278B1F90650B1F90430002449 +:108190009AB9E54A126892F860CCA6EB0C0692F800 +:1081A00062CC36B2A7EB0C0792F861CC92F8632C44 +:1081B00065441A443FB22DB213B290F8C621032A87 +:1081C00001D0042A10D1B0F91AC0B4450CDBB0F9C3 +:1081D0001820BA4208DBAC4506DC9A4204DCFFF703 +:1081E00041FF012800D10124204629E72DE9F05F55 +:1081F000DFF830830546002798F8010020B1FFF72B +:108200007FFE002188F80110DFF820B3DFF818A303 +:10821000ABF138009BF8001061B15C4604264FF0CA +:10822000020B012941D002297ED0032972D00429F2 +:1082300071D056E0002405F5805681461FE00120EC +:10824000D6F8E01FA040014217D004EB041005EB64 +:108250004018B44800780028DAF8000002D090F8FE +:10826000491C01E090F85B1C89F81810AF494046A2 +:108270003839FFF780FF012806D0641C64B296F9F4 +:10828000EC0FA042DBDA2DE0A84A01218BF80010A8 +:10829000383AD8F81810C2F83A108BF80640BBF8F4 +:1082A0000810491CABF808101CE0A17901EB011182 +:1082B00005EB411595F8C611042901D0062910D106 +:1082C000827E8146134605F11801A01C0CF0C1FB0B +:1082D000012806D1954928463839FFF7C3FE012801 +:1082E00003D026703846BDE8F09F2089B9F80E10FB +:1082F0004B46884215D384F800B02846FFF7A2FE0B +:1083000098F800000028DAF8000005D090F84B0C2F +:1083100004E009E03AE05EE090F8640C187601278A +:10832000E0E7401C2081DDE7A17901EB011105EBBD +:10833000411595F8C611042907D0062905D008294A +:10834000D0D12846FFF75DFE4EE0827E05F1180190 +:108350001346A01C0CF07DFB012806D1734928466A +:108360003839FFF77FFE01280CD095F8C661082048 +:1083700085F8C6012846FFF744FE0320207085F8E3 +:10838000C661AFE72846FFF75DFEC8E7A17901EBBC +:10839000011105EB411595F8C611042904D00629F1 +:1083A00002D0082920D09DE7827E05F118011346EE +:1083B000A01C0CF04EFB012894D15C4928463839AA +:1083C000FFF750FE01288DD12846FFF73BFE01271D +:1083D00084F800B086E7A07900EB001005EB4010B0 +:1083E00090F8C60108289BD1FFF7ECFD7AE72DE94C +:1083F000F05F4C4D0646002768783C4610B1FFF709 +:108400007FFD6C70A878AA46DFF82081DFF818910C +:10841000A8F11C0870B19AF8001050460029D9F84C +:10842000001002D091F84E1C01E091F8651C88F80C +:1084300018108470DFF8F4B0012106F580559BF820 +:10844000000058B15C464FF0040B012840D00228D0 +:1084500063D003286CD004286BD05AE0CA460024AD +:10846000C1461FE00120D5F8E01FA040014217D00F +:1084700004EB041006EB40182A4800780028DAF8CC +:10848000000002D090F84C1C01E090F85D1C89F8C7 +:108490001810264940461C39FFF76DFE012806D00A +:1084A000641C64B295F9EC0FA042DBDA33E01F4A9A +:1084B00001218BF80010383AD8F81810C2F83A1099 +:1084C0008BF80640BBF80810491CABF8081022E0F6 +:1084D000A079D5F8E02F81400A421AD000EB0010B5 +:1084E00006EB401595F8C601042801D0062812D1E4 +:1084F00098F81A2005F118011346A01C0CF0A9FAEF +:10850000012806D1094928461C39FFF7ABFD01288F +:1085100010D084F800B03846E5E627E0D01F100000 +:1085200040570120B0051000A407100038201000AB +:1085300054E079E02089B8F80E10884213D3022065 +:1085400020702846FFF77EFD9AF800000028D9F831 +:10855000000002D090F84E0C01E090F8650C88F80D +:1085600018000127D7E7401C2081D4E7A079D5F86F +:10857000E02F81400A4201D130462CE000EB001090 +:1085800006EB401595F8C601042801D006281DD138 +:1085900098F81A2005F118011346A01C0CF059FA9E +:1085A000012805D150492846FFF75CFD012803D07A +:1085B0002078022805D009E02846FFF743FD01276F +:1085C00004E02846FFF71DFD0320207095F8C60142 +:1085D0000828A0D12846FFF714FD2BE0A079D5F894 +:1085E000E02F81400A4225D000EB001006EB401539 +:1085F00095F8C601042801D006288CD198F81A20D5 +:1086000005F118011346A01C0CF023FA012882D1B1 +:1086100035492846FFF726FD0128A3D12846FFF754 +:1086200011FD022020709CE7A279D5F8E00F91405F +:10863000084297D1FFF7C6FC6DE710B52A4990F8BC +:10864000C63100221C395B1E052B14D8B0F91A3034 +:10865000B1F90240A3420EDBB0F91800B1F90040B5 +:10866000A04208DBB1F90640A34204DCB1F90410D2 +:10867000884200DC0122104610BD30B514788442D7 +:1086800004D25578854201D90A2011E0844204D1F0 +:108690005578854201D0187809E0844204D0547896 +:1086A000844201D1987802E018789C786043C0B287 +:1086B00094788C4204D2D5788D4201D90A2111E0F8 +:1086C0008C4204D1D5788D4201D0197909E08C42D1 +:1086D00004D0D2788A4201D1997902E019799A7945 +:1086E0005143C9B2484330BD1C201000BE48BF49A9 +:1086F0000068B0F8F5290A80B0F8F7294A80B0F888 +:10870000FC19BA48801E01800021C0F80610418182 +:10871000C160016170472DE9F843B34F80460025E1 +:1087200038682B462A46418EB0F9346061F31F4405 +:1087300066F30F04694640460CF014FA3968BDF937 +:108740000220B1F8FE3991F83E004343934207DA24 +:10875000B1F8003A4343934202DDB1F8022A01E046 +:10876000B1F8FC29424310B2D8F800200092B1F8C9 +:10877000EE33BDF90020934203DAB1F8F01361F350 +:108780001F4482420ADB311A8A4207DCBDF902101B +:10879000814203DBC0EB2440814200DD01252846F5 +:1087A000BDE8F8832DE9F84F054690480024001DE8 +:1087B00005F12406018809B9408820B1304600F04F +:1087C000BAF8012820D089480788B0F802900CF048 +:1087D0000EFA824600231A46694630460CF0C2F96A +:1087E000DFF80482BDF90010D8F8000090F83E00D0 +:1087F00000FB07F2914205DB0FFA8AF309FB103008 +:10880000884203DA012429E0042427E07748801E07 +:10881000008820B13046FFF77EFF012804D073485E +:108820000A30018841B901E0022417E0418819B9F2 +:10883000818809B9C08888B1304600F0A7F80128BE +:108840000CD1D8F80000E96A90F8FA09884204D9F6 +:10885000B5F8140228B1082803D010242046BDE83A +:10886000F88F0824FAE72DE9F047044690F8C6018E +:108870000E464FF00109032807D000274FF00308E8 +:10888000042816D0082853D13FE02046FFF78AFF7E +:1088900005004DD094F90D0204F0DCF8A4F8145250 +:1088A00030682062E08F4FF0000940F40060E087FC +:1088B0003EE094F90D0204F0FEF8012838D120467C +:1088C000FFF770FF0546B4F81402102803D00828FB +:1088D00001D085B12CE065B1314604F120000CF0E7 +:1088E00005F901464048006890F8FB09404388427A +:1088F00004DA206A306084F8C68113E0102D01D0BC +:10890000082D15D1A4F8145212E094F90D0204F0C8 +:10891000D2F801280CD12046FFF744FFB4F8140226 +:108920000828E6D0A4F8147294F90D0204F0B8F8FF +:108930004846BDE8F0872DE9F8432C4E8046361DA9 +:108940000025B6F900400CF052F9074600231A46FC +:10895000694640460CF006F92348B188BDF900206D +:10896000006890F83E004143914201DAB6F90240B6 +:10897000BDF9021000FB04F2914204DB3A1404FB3F +:108980001020884200DA0125284609E7F8B5064696 +:1089900000250CF02CF9044600231A46694630469F +:1089A0000CF0E0F81049114BBDF9022009680A33B8 +:1089B000188891F83E104843904211DC5E882014DC +:1089C00006FB110090420BDB9A88BDF900004A4378 +:1089D000824205DCDB8822B203FB1121814200DAEE +:1089E00001252846F8BD0000A40710008A260120B2 +:1089F0002DE9F0415B4900F580534FF001060D6809 +:108A000095F8964CA10717D50F2113E0D3F8E02F66 +:108A100006FA01F73A420DD001EB011200EB4212C7 +:108A200092F8C721520705D54F4995F8972C0A703F +:108A30004E7001E0491EE9D2610724D54B49097BFC +:108A4000002920D0484C0021A41EA1800F2113E052 +:108A5000D3F8E02F06FA01F73A420DD001EB0112EC +:108A600000EB421292F8C7717F0705D0B2F844209C +:108A7000A788BA4200D9A280491EE9D2B5F9B60C3E +:108A8000FCF7B0FF2070BDE8F0813649096891F825 +:108A9000961C890709D5344910B10020487003E0BD +:108AA0000878002801D0401E087070472DE9F04179 +:108AB00004462C4800263546006890F8961C4A0764 +:108AC0002CD52A4A127B4AB3274F90F8B42CBF1EEC +:108AD00090F8B81C7B78012B08D190F8B5CC90F8B1 +:108AE000B90CA2EB0C02081AD2B2C1B2B8889042FB +:108AF00002D83878884203D9042084F8C7010125B8 +:108B00007D70AB4203D029460A200BF09CF8184830 +:108B10007A78017B62F3000101730FE0880706D5C4 +:108B200011484178012909D1007830B906E0C80719 +:108B300004D094F8C701042800D101262E43A2D006 +:108B40000C49AA20087094F8C601032805D004280F +:108B500001D0062897D1082000E0022084F8C60141 +:108B600091E70000A4071000B6051000945A100009 +:108B7000405701203407100070B50446002084F8E7 +:108B8000CA01FC48FC4D0378286833B194F90D22E2 +:108B90008A4290F8031218D021E0F84B94F8C7618C +:108BA0001B78012E07D09BB394F90D228A4290F8CE +:108BB000341314D109E0F24A12784AB194F90D2223 +:108BC0004BB18A4290F8F31209D101F00F0107E08E +:108BD00090F8F112F9E78A4290F8F212F5D00909FB +:108BE00084F8CA1190F80D13C9060BD5E18F8905D9 +:108BF00008D590F8360394F8CA1100F00F00084425 +:108C000084F8CA01204600F0F5F9012810D01DE0D3 +:108C1000FFE794F90D328B4202D190F83313D4E779 +:108C2000934202D190F83313D9E790F83513D6E781 +:108C3000D4480078012809D9296894F8CA0191F824 +:108C4000351301F00F01084484F8CA01286890F830 +:108C5000061AC9060AD5CC490978002906D094F825 +:108C6000CA1190F8210A084484F8CA0170BDC44AA8 +:108C700010B51478C04A90F8CA11126892F83333CC +:108C800003F00F035CB192F8F22202F00F02D21A45 +:108C9000891A002900DC002180F8CA1110BD92F861 +:108CA000F122F2E7B74900200870B8490870B449CA +:108CB0000870B5490870B6490880B6490870704711 +:108CC0002DE9FE4F04460020B3498DF800008DF8D1 +:108CD00004000870B14904F580554FF0FF39087061 +:108CE000B5F8E00FA74E10EA19400DD02046FFF767 +:108CF0007FFE3146484609784FF000475FEA010E93 +:108D00004FF0010B34D10FE0A04800243470047000 +:108D1000A34880F800900120FFF7B7FE9C4804802C +:108D20009C480470BDE8FE8F04F5805C00219CF92E +:108D3000EC8F1BE0DCF8E03F0BFA01F2134213D09A +:108D400001EB011204EB421292F8C631012B01D063 +:108D500048460DE0B2F8426036B1126B92FBF6F372 +:108D60009F4201DA1F460846491C49B28845E1DAAC +:108D70008246B0F1FF3F02D0894981F800A08848BF +:108D80004A464FF0004690F90080BEF1010F25D809 +:108D900004F58057002097F9ECCF1DE0D7F8E03FAD +:108DA0000BFA00F10B4215D0404513D000EB001335 +:108DB00004EB431191F8C631012B01D04A460DE076 +:108DC000B1F8423033B1096B91FBF3F39E4201DA03 +:108DD0001E460246401C40B28445DFDA6949002045 +:108DE000029208700746DFF890814FF00809EBE027 +:108DF000D5F8E01F0BFA07F001427AD007EB071015 +:108E000004EB401696F8C601012806D0052810D0BC +:108E1000092824D00D2831D014E0304600F0C6F9DE +:108E200051463046029AFFF7A7FE022086F8C60197 +:108E300033E0304600F0F7F8062086F8C6013046E9 +:108E400000F067F996F8C601022826D0062852D00D +:108E5000072859D00A280DD00E281AD05CE0D8F87F +:108E6000000090F8370300F00F0086F8CA010A20CE +:108E700086F8C60196F8CA01D0B34DE0D8F80000D4 +:108E800090F83A0300F00F0086F8CB010E2086F828 +:108E9000C60196F8CB0168B33EE096F83E00C007E5 +:108EA00010D0304600F0A6F860B9D8F8001096F857 +:108EB000CA0191F8351301F00F01884206D9401A12 +:108EC00086F8CA0196F8CA0118B125E0002086F894 +:108ED000CA01032086F8C601D8F8000090F80D03F7 +:108EE000C00619D5F08F800516D5306AF06013E002 +:108EF0000DE03EE00DE096F8CB0168B996F83E0033 +:108F0000800701D5072005E086F8C69104E00B2014 +:108F100000E0032086F8C6013046FFF7C7FD96F84B +:108F2000C60102280CD0062811D00A2808D00E2825 +:108F30000DD0032812D0042810D007283ED041E0DD +:108F400096F8CA01A8B1401E86F8CA013AE096F820 +:108F5000CB0170B1401E86F8CB0133E0094801789F +:108F6000491C017096F8C70101281BD003281FD0A7 +:108F700028E027E029051000A4071000B70610001C +:108F80003307100034071000E407100068071000D2 +:108F9000B8051000B40510003507100036071000A2 +:108FA000BA0510009DF80400401C8DF8040009E08B +:108FB0009DF80000401C8DF8000003E096F8C70102 +:108FC0000128EFD07F1C7FB295F9EC0FB842BFF6B5 +:108FD0000FAF0020FFF759FD01AA6946204600F0B7 +:108FE00066F888489DF80010017087489DF80410C5 +:108FF000017097E690F85A1090F859208A1AC18F9C +:10900000521C022A0AD990F85C2090F85B309A42F0 +:1090100004D141F00101C1870120704721F0010115 +:10902000C1870020704710B57849002280F8CB2115 +:109030000B787749096813B191F804320FE0754B4A +:109040001B7853B191F8383301221B0980F8CB31DA +:1090500090F8C731012B05D00CE091F8383303F0BC +:109060000F03F3E790F8CB3191F8F14203EB1413BF +:1090700080F8CB311AB990F83E2092070CD491F8C1 +:109080003913826A01F00F039A4205D990F8CB2177 +:1090900002EB111180F8CB1190F8CB11002905D10A +:1090A000C18F090502D5012180F8CB1110BDF0B5A3 +:1090B0000B78594901254BB100230B701178002919 +:1090C00008D0002100F5805402261DE01078002809 +:1090D00000D00D70F0BDD4F8E03F05FA01F73B4237 +:1090E00010D001EB011300EB431393F8C671032F6B +:1090F00008D193F8C771012F04D183F8C6611378A2 +:109100005B1E1370491C49B294F9EC3F8B42E2DAC2 +:10911000F0BD2DE9FC41DFF8F8800746D8F80000E3 +:1091200090F80D03C0073FD0002507F1A0060124E9 +:1091300006EBC40030F8041CADF8021030F8081D2E +:10914000ADF800108089ADF8060036F83400ADF8AF +:10915000040001A968460BF0C9FC854200DA054607 +:10916000641CE4B2052CE3D3394607F120000BF070 +:10917000BDFC0246274800780028D8F8000005D03A +:10918000B0F82713B0F82303494304E0B0F82513DF +:10919000B0F8210349434043824205DD8D4203DD9F +:1091A000F88F40F00200F887BDE8FC8170B51849DF +:1091B000096891F80D33DB0622D5046AB1F8EE5345 +:1091C00023B2AB424D8E01DDA5F5967565F31F42C6 +:1091D000B1F9345091F88C63241465F30F02B44252 +:1091E0000ADBC4EB2242B24206DB91F88D138B42BC +:1091F00002DBEA1A8A4203DAC18F41F40071C187A7 +:1092000070BD00003507100036071000290510005A +:10921000A4071000B7061000330710002DE9F8432B +:109220001646002389461A46FE490C68B4F8927324 +:1092300047B9B4F8941329B9B4F8961311B9B4F82E +:109240009813B9B1B0F90E50B0F90C10AF4210DC60 +:10925000678EB4F894C3A7EB0C07AF4209DBB4F8F0 +:1092600096538D4205DCA58EB4F89873ED1B8D42A4 +:1092700000DA0122EC49097801B10123EB494D786C +:10928000EB490978BDB194F86503050900F00F03B7 +:10929000012904D994F8660300F00F03050922B1EF +:1092A00094F8640300F00F030509B4F86713B4F8E9 +:1092B000692349437EE08BB194F86B03050900F004 +:1092C0000F03012904D994F86C0300F00F0305097A +:1092D000B4F86D13B4F86F2349436BE0D54B1B789A +:1092E000022B22D090F8C731022B30D0012B34D082 +:1092F000DFF844C394F85F5694F85E8605F00F03D8 +:109300009CF800702D0937B194F8655694F864867E +:1093100005F00F032D09B0F8420040452ED9B4F8EE +:109320006016B4F86226494344E094F871030509D5 +:1093300000F00F03012904D994F8720300F00F0321 +:109340000509B4F87313B4F87523494332E094F86F +:10935000790300F00F03050927E094F87A0300F081 +:109360000F03050922B194F8620300F00F03050909 +:10937000B4F88113B4F8832349431BE094F87703CE +:10938000050900F00F03012904D994F8780300F0CF +:109390000F03050922B194F8630300F00F030509D8 +:1093A0001FB19CF804309CF80550B4F87D13B4F854 +:1093B0007F2349435243484600950BF0A5FB356097 +:1093C000BDE8F8832DE9F8430E4690F8C61104462F +:1093D00000F1880703290FD09248DFF86082042942 +:1093E00000680FD0072931D00829E9D13146384625 +:1093F000BDE8F84300F0E3BD31463846BDE8F84328 +:1094000000F097BD90F87B0304F10C010509081DDD +:109410000BF06CFB01466A462046FFF7FFFE8649CB +:109420000A7802B18D7954F8901F2A460BF081FB1F +:10943000054602463146384600F091FD256098F811 +:10944000482065F3030288F84820B9E790F80D1327 +:10945000002589070DD57A4990F87C03097800F03A +:109460000F0501B105092A463146384600F08FFD47 +:1094700007E0B6F90200C4F88C00B6F90000C4F8A1 +:10948000880098F8481065F3030188F8481097E7BA +:109490006B49654A002009781278114300D00120F9 +:1094A00070472DE9FF4F89B09146DDE9160A00EBC0 +:1094B000CA00D0E90045CDE90445D0E90240CDE934 +:1094C0000640CDE9021203EBCA00DDF80880D0E9BE +:1094D0000210CDE9001006A904A800F0B1FC07466F +:1094E0008B46694602A800F0ABFC0E46054669466D +:1094F00004A800F0A5FC0446401BB1412DDA284623 +:109500000AF0A4FF804620460AF0A0FF0446BAF104 +:10951000000F00D16410791B7BEB060005DA38469A +:109520000AF094FFA04200DA0446B8F1000F0CD014 +:1095300001990398009A401A6043029990FBF8F051 +:10954000891A614391FBF8F101E000200146019A7C +:1095500002EB0009009800EB01080998C0E90089B6 +:109560000DB0BDE8F08F2DE9FF4F00278BB090467E +:109570003E463D463946199C0AE0012878D053F80A +:10958000312017444A4302FB0155491C1644C9B215 +:10959000A142F2D32B4C206800906068CDE901070E +:1095A000E06803902069CDE90406A0690690E069AF +:1095B000CDE9070568460BF04DF982462068CDE9F4 +:1095C0000007A0680290E068CDE903066069059095 +:1095D000A069CDE90605206A08908B4668460BF025 +:1095E00039F900970A9060680190A068CDE90206F9 +:1095F000206904906069CDE90505E0690790206A5B +:109600000890894668460BF025F9AAFB08370D46F5 +:109610000BFB0871002204460AFB02160C9F0A98F5 +:1096200012E025E0A407100029051000DC07100057 +:10963000340710001805100078071000405701206B +:10964000B7061000BC051000A0FB07C809FB078186 +:1096500000FB021013EB0C014641081946EB050113 +:109660004FF47562002310F036F90C9921B11CE01B +:1096700003EBC102526884E7FC49096891F8311391 +:10968000890612D50A98031849EB090113EB0A035E +:1096900041EB0B01AA00A000181842EA9472514154 +:1096A0004FF47552002310F016F91899C1E900AB78 +:1096B00018990A9BC1E902391899C1E904450FB00C +:1096C0004FE72DE9F04F85B00546DFF8A083303035 +:1096D0000290D8F800000F46934690F8311305F138 +:1096E000600601F01F04E24905F1680905F1800AEE +:1096F000097811B190F8320307E005F0A9FC0128C0 +:1097000005D1D8F8000090F8A20300F01F04BBF1C7 +:10971000000F06D195F89810012220460BF009FAA7 +:10972000C4B2BC4201D9781EC4B285F89840CDE9D4 +:10973000009704FB04FB2B465A4621460120FFF705 +:1097400012FF7060CDE900A72B465A462146002043 +:10975000FFF709FF3060D8F8001091F89A13C90795 +:1097600011D00146029872688DE891002B4603A83B +:10977000FFF797FEDDE9030105EBC402516071605C +:1097800045F83400306005B0EBE62DE9F0410446C1 +:1097900000F1A00590F8400017460E46000703D5DB +:1097A00094F8B801012805D0A021284610F058F9F6 +:1097B00006208DE0182105F1680010F051F91821FC +:1097C00005F1800010F04CF994F8BA0101281FD17E +:1097D00094F8C401012802D003280DD018E094F8B1 +:1097E000C50110B9E089A4F8C201B4F8C2016084CF +:1097F000B4F8C00120840BE094F8C50110B9A08929 +:10980000A4F8C001B4F8C0012084B4F8C201608497 +:1098100094F8C50101283BD0B4F9C2117068052243 +:10982000401A90FBF2F0E962B4F9C21100EB400378 +:1098300001446962B4F9C21101EB4001E961B4F974 +:10984000C21119446961B4F9C21101EB8000E860EA +:1098500070686860B4F9C0113068A962401A90FB62 +:10986000F2F0B4F9C01100EB400201442962B4F9EE +:10987000C01101EB4001A961B4F9C0111144296183 +:10988000B4F9C01101EB8000A8603068286021E0C5 +:10989000002005EBC001B4F9C2214A60B4F9C0212F +:1098A00045F83020B4F9C2214A63401CB4F9C02104 +:1098B000C0B20A630628ECD30CE005EBC001726865 +:1098C0004A60326845F8302072684A6332680A6339 +:1098D000401EF2D20020C5E91A00C5E91C00C5E906 +:1098E0001E00C5E92000C5E92200C5E92400D6E92B +:1098F0000001C5E9180139462846BDE8F0410122BA +:10990000DFE670B50BE001EBC30474E90256C4E96D +:10991000025600EBC30474E90256C4E902565B1E0A +:10992000F1D1D2E90034C1E90034D2E90012C0E932 +:10993000001270BD70B515460446D1E90002C4E9B5 +:1099400018020A462B46214604F13000FFF7D9FFE2 +:1099500029462046BDE870400022B2E600B585B039 +:109960000321049100224FF47561CDE902120092A7 +:1099700000F5907300F5847200F1A00100F580708D +:109980000AF0AAFF05B000BD2DE9F041374F0446AB +:10999000164638680D464FF0010890F80C03000792 +:1099A00002D5204600F006FA386890F80D0340060C +:1099B00003D52946204600F04EFA3868B0F9321037 +:1099C000B5F902000BF05CF868803868B0F9341023 +:1099D000B5F900000BF054F82880386890F89A0325 +:1099E000800703D5286800F07AFA286094F8C60149 +:1099F000032806D0042808D0072817D0082815D037 +:109A000017E03188A4F84F1013E03868B4F84F20FD +:109A100090F87B0300F00F00C0F110014243308842 +:109A200000FB01200009A4F84F0001E0B4F84F004A +:109A30003080104A294604F1240000F0B2F9404673 +:109A4000BDE8F0812DE9FC5F88460B498346002084 +:109A5000086008490646DFF814A0086007494FF07F +:109A600001090BF580570870B1E00000A407100051 +:109A7000B7061000700710006C0710006807100090 +:109A8000D7F8E01F09FA06F001427CD006EB061178 +:109A90000BEB411494F8C60103280BD0042809D01D +:109AA000072807D0082805D0092803D00A2801D0A4 +:109AB0000B2868D1E0680090B4F84D00ADF80400C0 +:109AC00004F10C01F84A081D00F06BF901AA69467F +:109AD0002046FFF759FF0546DAF8000090F80C031E +:109AE000400604D56946204601F04BFC0546DAF8ED +:109AF000000090F80C03800603D569462046FFF766 +:109B000061FCDAF80000524690F8D00300060AD54E +:109B10004DB194F8C601032805D1608CADF8020060 +:109B2000208CADF8000094F8C701012807D1DF4868 +:109B3000007820B994F8C601082800D00025DC4838 +:109B4000007870B194F84000C00701D0002508E00B +:109B500094F8B801012804D1206A0090002084F80C +:109B6000B80194F8C70103280AD1D2490878401CEB +:109B7000C0B2087094F84030DB0701D0401E087076 +:109B80000098606200E021E0BDF80400A4F84F00F6 +:109B9000106890F8F409C00707D0012D16D1694666 +:109BA0002046FEF760FE88B101E0012D0ED100983D +:109BB000A061BDF80400A4F8510094F80D22D8F873 +:109BC000001009FA02F00143C8F80010761C97F95A +:109BD000EC0FB042BFF654AFDAF8000090F8700C0A +:109BE00000070ED5B3480178B34829B1B3490978C5 +:109BF000012901D180F80090D7F8E41F002900D195 +:109C00000170BDE8FC9F2DE9F04788460646002715 +:109C10004FF0010900F5805553E0D5F8E00F09FA3F +:109C200007F108424CD007EB071006EB401494F8FC +:109C3000C60103280BD0042809D0072807D008281C +:109C400005D0092803D00A2801D00B2838D194F96F +:109C50000D12D8F8003009FA01F2134230D003286F +:109C600007D1084602F027FF18B92146304602F016 +:109C7000F4FD94F8C70104280AD194F8C601072816 +:109C800003D0082801D00B2802D1032084F8C70193 +:109C900094F90E02002813DB94F8C7110020012963 +:109CA00004D0022904D0042904D004E0032002E0F7 +:109CB000042000E0052084F8C801204609F0B6FF22 +:109CC0007F1C95F9EC0FB842A7DA00273EE009FAAD +:109CD00007F2104239D007EB071006EB401494F856 +:109CE000C601082802D00B2815D02EE094F80D22CA +:109CF000D8F8000009FA02F1084207D094F90E02E0 +:109D0000002803DB2146304602F0C1FD21463046E3 +:109D100002F085FD15E094F80D22D8F8000009FA4C +:109D200002F1084211D094F90E0200280DDBB4F8BC +:109D30004000214620F00800A4F84000304602F020 +:109D4000A6FD94F90D0202F0ABFE7F1C95F9EC0F15 +:109D5000B842D5F8E00FBADA06F5005628B116F881 +:109D60009A0F401C3070BDE8F087002086F89A00FA +:109D7000F9E74D4910B5002008605149086000F02E +:109D800097FBBDE8104000F0D3B838B50021009132 +:109D900004466946FFF756FE69462046FFF733FF43 +:109DA00038BD10B514460AF0A1FE2168814200DAE0 +:109DB000206010BD70B5034690F8C6010D4603281B +:109DC0000DD002280BD0042809D0062807D00A2875 +:109DD00005D00B2803D00C2801D00E282FD193F8E2 +:109DE000B50103F5A074E0B193F85A0093F8591047 +:109DF000401A401CC3F8A80193F85C0093F85B106C +:109E0000401A401CC3F8AC01586BC3F8A4012D489C +:109E100029460088C3F8B0012046BDE8704000F034 +:109E20009DBB1846FFF734FB002808D0012083F8BB +:109E3000B50129462046BDE8704000F04FBB70BD1B +:109E40004A68436809680068D21A081A404302FB4E +:109E50000200C11770477CB50C46B1F902100191A0 +:109E6000B4F90010009190F8C62100F1A005032A72 +:109E70000ED0042A11D0062A0FD00A2A0DD00C2A9F +:109E80000BD00E2A09D0072A1ED0082A1CD01FE0AA +:109E900006226946FFF779FC1AE006226946284641 +:109EA000FFF748FD14E000006C07100033071000B6 +:109EB0003A07100068071000ED061000EC061000CD +:109EC00070071000B806100006226946FFF746FD2D +:109ED000B5F864006080B5F8600020807CBD30B5C6 +:109EE00012490514096891F89D23B1F93240B1F97E +:109EF0003430954201DC62F31F4091F89E23A21A90 +:109F00000414A24201DC62F31F4091F89F2304B2C3 +:109F1000944201DC62F30F0091F8A01302B2591AC7 +:109F2000914201DC61F30F0030BD0000A407100076 +:109F30007047324A30B4126892F88533DC074FF02C +:109F4000000304D092F8864324098460037392F8D6 +:109F50008523920700D5036130BC00F035B87CB58D +:109F6000044615460E46684600F02EF801992A462A +:109F7000606800F03BF8606000992A46206800F0B5 +:109F800035F820602146304600F027F87CBD7CB5CE +:109F9000044615460E46684600F016F801992A4612 +:109FA000606800F023F8606000992A46206800F09D +:109FB0001DF820602146304600F00FF87CBD0A46AF +:109FC0000146104600F009B8B1F9022012024260C1 +:109FD000B1F900100902016070474A68803212121C +:109FE000428009688031091201807047C2F1100374 +:109FF000504301FB0300001170470000A40710004C +:10A000002DE9F041FE4A126851B3518E92F830307A +:10A01000C26E446E006F0026400000FB02404843C1 +:10A02000A0FB0025002101FB005500FB0155642128 +:10A03000A2FB010705FB017102FB06115C432246EE +:10A0400033460FF0ABFB224600230FF0A7FBED4B8E +:10A0500000221B1A8A4101D2EA480021BDE8F081A2 +:10A06000918E92F83130826ED3E72DE9F0478EB0B1 +:10A0700000250224059506950795089509950A95EA +:10A080000B950DF114080C95CDE90148064606F133 +:10A090001C03039404949A4622462146DA4800940D +:10A0A0000AF004FA0DF12409CDE90149D64B022248 +:10A0B000039404941033114605A800940AF0F6F9AD +:10A0C000D149306E0223403100901A46A1F11000B0 +:10A0D0000AF0E0F9CC490427022340311A46084629 +:10A0E00000970AF0CAF9C84902235246403109A82C +:10A0F00000940AF00DFA05950695079508950995BF +:10A100000A950B950C95CDE9014806F12C03022226 +:10A11000039404941D461146BB4800940AF0C6F906 +:10A12000CDE90149B84B022203940494103311463F +:10A1300005A800940AF0BAF9B349306E0223403101 +:10A1400000901A46A1F110000AF0A4F9AE490223CA +:10A1500040311A46084600970AF08FF9AA490223AF +:10A160002A46403109A800940AF0D2F90EB0BDE8A1 +:10A17000F0872DE9F04F0546A4480F468BB0D0E993 +:10A180000010CDE9081000260124059606960DF171 +:10A19000140A0796CDE9014A4FF002099A489346FE +:10A1A00005F10C03039498464A4621461038CDF831 +:10A1B000009004940AF07AF9B5F902000599012398 +:10A1C000401A05900090022206A938460AF062F96A +:10A1D0006427414601230222084600970AF05AF9F3 +:10A1E0004246022306A9104600940AF091F942461D +:10A1F000022308A9104600940AF08AF94146012377 +:10A200000222084600970AF038F905960696079646 +:10A21000CDE9014A7C4805F1140303941E4602224D +:10A2200001211038CDF8009004940AF03FF9B5F9F7 +:10A23000000005990123401A05900090022206A90A +:10A2400058460AF027F931460123022208460097B2 +:10A250000AF020F93246022306A9104600940AF0BB +:10A2600057F93246022308A9104600940AF050F923 +:10A27000314601230222084600970AF0FEF80BB08F +:10A28000BDE8F08F2DE9F74F8AB0002608960996B1 +:10A290000596069601240DF1140807960225CDE9CE +:10A2A0000148CDE903540746574B07F11C00083B12 +:10A2B0002A462946824600950AF0F8F80DF1200951 +:10A2C000CDE901595048CDE9034553460222012109 +:10A2D000103800950AF0EAF80DF11C0ACDE9014AA0 +:10A2E000494B0394083B0222012108A800950494DD +:10A2F0000AF0DCF801213846FFF782FE42494FF0B0 +:10A30000640B14390123086007990222084405A947 +:10A310000790CDF800B008460AF0BCF80798009006 +:10A320000123022205A80B990AF0A7F808960996BE +:10A33000059606960796CDE90148CDE90354324BC0 +:10A34000022207F12C00083B1146064600950AF050 +:10A35000ADF8CDE901592C48CDE903453346022239 +:10A360000121103800950AF0A1F8CDE9014A264BE9 +:10A370000394083B0222012108A8009504940AF0E6 +:10A3800095F800213846FFF73BFE1F490123143999 +:10A39000022208600799CDF800B0084405A907908B +:10A3A00008460AF077F8079800900123022205A8D2 +:10A3B0000C990AF062F80DB062E72DE9F74F8EB004 +:10A3C00000250595069507950224089509950A9597 +:10A3D0000B9505AF0C95CDE901478C464FF0010A6E +:10A3E000094B06460394103B524621466046CDF881 +:10A3F00000A004940AF05AF805AA0223114607E0C7 +:10A40000A407100040420F00F4051000F09B01006B +:10A41000BE4800940AF08AF80DF12408CDE90148FD +:10A4200006F11C030222039404949B46114605A8DE +:10A4300000940AF03BF84FF0640902231A4659468B +:10A4400009A8CDF800900AF018F80595069507952B +:10A45000089509950A950B950C95CDE90147AB4BED +:10A460000394303B01220221CDF800A004941098FF +:10A470000AF01CF805AA02231146A44800940AF029 +:10A4800055F8CDE901480394049406F12C03009497 +:10A4900002221C46114605A80AF008F802231A46B3 +:10A4A000214609A8CDF8009009F0E7FF11B0E7E6D2 +:10A4B000974808B5006864210223B0F84D031A4696 +:10A4C00048439249800820310090A1F1100009F022 +:10A4D000E1FF8E4964203439086008BDF8B50446B0 +:10A4E000086844F8040B086844F8040B086844F84A +:10A4F000040BB1F902000025E4E80205B1F90000FF +:10A50000E4E802058148824E10300FC80FC40FC422 +:10A51000306864210223B0F84D031A46484380088E +:10A52000A4F12001009008463C3C09F0B3FF3068DC +:10A5300064210223B0F84D031A464843800804F111 +:10A540002C010090084609F0A5FF94E8070004F1EB +:10A550003C0383E8070084F87450F8BD7FB50D46CE +:10A56000044603220AF094FA204600F025F820461B +:10A5700000F06AF82046FFF778FD00200090019077 +:10A580000290039002AA69462046FFF77BFE02AACA +:10A5900069462046FFF7EDFD02AA69462046FFF70F +:10A5A0000CFFA0896880A08A28800322294604F134 +:10A5B0003C000AF06DFA7FBD7CB50446B0F902108C +:10A5C000B0F93E00B4F94220091A801A081A019025 +:10A5D000B4F90010B4F93C00B4F94020091A801A0B +:10A5E000081A009004F148000322694605460AF063 +:10A5F00064FA94F87400032802D2401C84F87400B2 +:10A60000C3B200221146184606E005EBC006766884 +:10A61000324455F830603144401EF6D292FBF3F0DC +:10A6200091FBF3F16A68101A2A684043511A01FB42 +:10A63000010042F21071884200DD0846642148435F +:10A6400090FBF3F020667CBD2DE9F0430446B0F9A1 +:10A650000200B4F90610B4F90420411AB4F900005C +:10A660004943801A00FB00182769A66907FB07F019 +:10A6700006FB060087B04FF00009404515D909F0E8 +:10A68000E5FE05000DD0404609F0E0FE784390FB62 +:10A69000F5F02061404609F0D9FE704390FBF5F0DB +:10A6A00002E04846C4F81090A061CDF8149001254E +:10A6B0000DF11408CDF818900226CDE90158CDE926 +:10A6C000036512484F4604F10C03324631462038E8 +:10A6D000009609F0EBFEDDE90501C4E903010597E9 +:10A6E0000697CDE90158CDE903650848022204F137 +:10A6F000140311462038009609F0D8FEDDE9050163 +:10A70000C4E9050107B0BDE8F0830000140610009D +:10A71000A4071000B0F84220B1F842301A44A0F863 +:10A720004220B0F84420B1F844301A44A0F8442044 +:10A73000026B0B6B1A440263426B4B6B1A4442630D +:10A74000B1F95320B0F953309A4201DDA0F85320FB +:10A75000B1F95520B0F955309A4201DDA0F85520E5 +:10A7600090F8CE2191F8CE319A420AD030F8462F97 +:10A77000B1F846301A4420F80E29896B026811445A +:10A78000016070472DE9F14F8AB0002004900A98CB +:10A7900000F500500890B5E0002105910691009168 +:10A7A000884689460E460F460D468A468B460191DD +:10A7B0000291039104990A98EC4600EB810000F5A0 +:10A7C00000500990C1690C4616E091F8CE011CF8C2 +:10A7D0000020521CD2B20CF800200A9B034403F55F +:10A7E00000531B7B9A4205D1012A03D901228240E2 +:10A7F00042EA0B0BD1F81C120029E6D135E094F89F +:10A80000CE110120884010EA0B0F0ED1606BB4F915 +:10A810000E3041464A46C0FB03128846B4F90C107C +:10A820009146C0FB0167054412E010EA0A0F0FD100 +:10A83000A16BB4F91EC042464B46C1FB0C239046A7 +:10A84000B4F91C209946C1FB02670D4440EA0A0A8C +:10A85000204600F043FA012802D10598401C0590DB +:10A860000698401C0690D4F81C42002CC7D10698CC +:10A87000002843DDE817044603462A464046494679 +:10A880000FF029F8ADF81E002A4623463046394617 +:10A890000FF021F8ADF81C0009984FF0FF360025A5 +:10A8A000C46923E0204600F019FA012801D0059878 +:10A8B00090B904F1100107A80AF018F9B0420BD2C0 +:10A8C00006463DB129462046FFF724FF29460A984F +:10A8D00000F01BFA254607E021462846FFF71AFF3D +:10A8E00021460A9800F011FAD4F81C42002CD9D164 +:10A8F0000798E860E88F40F04000E8870498401C23 +:10A900000490089890F89410049881423FF744AF5F +:10A910000BB0BDE8F08F2DE9F74F0D4601EB0511A7 +:10A9200082B0814600EB41170024DFF8B8B400F58F +:10A93000805A78E00122DAF8E01F02FA04F811EAFE +:10A94000080F6FD0AC426DD0DBF8080030F815006E +:10A9500010EA080F66D104EB041109EB41163046EA +:10A9600000F0B6F9012804D0304600F0B7F901280C +:10A9700058D1304600F0A6F9F0BB06F10C0107F102 +:10A980000C000AF0B3F80090DBF808000123AB409C +:10A9900030F8151041EA080120F8151030F81410AD +:10A9A000194320F814103846DBF8008000F0A2F9B3 +:10A9B000012804D1304600F08BF901281AD038461E +:10A9C00000F086F9012804D1304600F093F90128FF +:10A9D00010D0384600F07CF9012817D1304600F03D +:10A9E00077F9012812D197F83E0096F83E100843F7 +:10A9F00080060BD5F88F00E014E040F02000DBF873 +:10AA00000480F887F08F40F02000F08700984045E0 +:10AA100008D2324642F21C06394609EB0600049B76 +:10AA200000F0B4F9641C9AF9EC0FA04282DA05B088 +:10AA30006FE72DE9F84F8846074601EB081007EB52 +:10AA40004014DFF8A0B394F83E004FF0010A40062E +:10AA500007F580552CD504F10C000026009021E06C +:10AA6000D5F8E01F0AFA06F001421AD0464518D080 +:10AA700006EB061007EB4010814600F029F901288B +:10AA80000FD1484600F01EF958B909F1100100989D +:10AA90000AF02CF8DBF80410884202D2042084F873 +:10AAA000C601761C95F9EC0FB042D9DABDE8F88FF3 +:10AAB000CD49A06A096891F829138842F6D9002681 +:10AAC0002CE0D5F8E01F0AFA06F0014225D04645F1 +:10AAD00023D006EB061007EB4010814600F0F8F893 +:10AAE00001281AD194F8CE1199F8CF01814214D1DE +:10AAF000484600F0E7F880B909F1100104F10C00B4 +:10AB000009F0F4FFDBF80410884206D2042084F830 +:10AB1000C601E08F40F04000E087761C95F9EC0F0D +:10AB2000B042CEDA002604F10C0922E0D5F8E01F8D +:10AB30000AFA06F001421BD0464519D006EB061072 +:10AB400007EB4014204600F0C9F8012810D1204638 +:10AB500000F0B8F860B904F11001484609F0C6FFEA +:10AB6000DBF80410884203D2E08F40F04000E08719 +:10AB7000761C95F9EC0FB042D8DA97E72DE9F84347 +:10AB80000646FF208DF8000000254FF0010806F56D +:10AB9000805417E005EB051006EB4017D4F8E01FD2 +:10ABA00008FA05F001420CD0384600F08BF8012875 +:10ABB00007D097F8C601052803D129463046FFF78C +:10ABC00038FF6D1C94F9EC0FA842E3DA00254746E4 +:10ABD00019E005EB051006EB4018D4F8E00F07FA72 +:10ABE00005F108420ED0404600F06CF8012809D06B +:10ABF000404600F073F8012804D16A4629463046E1 +:10AC0000FFF789FE6D1C94F9EC0FA842E1DA0025EC +:10AC1000B8461DE005EB051006EB4017D4F8E01F21 +:10AC200008FA05F0014212D0384600F04BF801282E +:10AC30000DD0384600F04CF8012804D16A46294668 +:10AC40003046FFF768FEF88F20F02000F8876D1C73 +:10AC500094F9EC0FA842DDDA9DF8000006F50056E5 +:10AC6000401C86F89400BDE8F88310B5044604F053 +:10AC7000EFF9012821D05B480321083006F048FF96 +:10AC800058481E2180680EF0C9FE42F21C007C214B +:10AC900020440EF0E5FE5349091D081F00F044F85A +:10ACA0002046FFF76BFF2046FFF76CFD4D48032160 +:10ACB000BDE81040083006F043BF10BD49490020F0 +:10ACC0008860704790F84000C00700D001207047AE +:10ACD00090F8C601012800D00020704790F8C60106 +:10ACE000022805D0032803D0042801D00020704793 +:10ACF0000120704710B590F83E10490603D5FFF7C4 +:10AD0000EDFF012800D0002010BD91F8C621012AD6 +:10AD100008D0022A06D0062081F8C601002081F85A +:10AD2000CB01704701F07BBD2DE9F0412E4F064667 +:10AD30000D463868B0F82A4390F83003644350B1A8 +:10AD400001F0BDFD0146386890F83023914202D8E9 +:10AD5000B0F82E4364433A682449B2F82C0349788A +:10AD6000404329B1B2F88E43B2F8900364434043A4 +:10AD70001F49097829B1B2F82B42B2F82D02644379 +:10AD80004043204434602860BDE8F081F0B591F97B +:10AD90000C6293F9004092F90C52771C02D06D1CA2 +:10ADA00015D00BE06E1C0BD000EB850200EB84008D +:10ADB000D26BC2F81C12C16381F80C421C70F0BD4A +:10ADC000641C64B240F8241081F80C4202E000EBED +:10ADD0008601C96B00EB8400C1F81C22C26382F8B3 +:10ADE0000C42EBE744061000A4071000DC0710003B +:10ADF000290510002DE9F041044690F88400FC4E2E +:10AE000000270D467F2851D104F10C01081D09F0DF +:10AE10006DFE0146204600F039FB40B284F8840004 +:10AE20000F2802DD0F2084F8840094F8400080078A +:10AE30003CD56888B4F96C30B4F96A20C01A01B204 +:10AE40002888D4F86AC0C4F85EC0D6F800E0801A3A +:10AE50004FF0640C9EF8D5E300290EFB01FE9EFB2B +:10AE6000FCF100B201DD194400E0591AA4F86410A5 +:10AE70003168002891F8D51301FB00F191FBFCF03B +:10AE800001DD104400E0101AA4F862006888B4F8EC +:10AE90006410401AA4F868002888B4F86210401AB8 +:10AEA000A4F86600306890F8D503E8B394F98400FC +:10AEB000B5F90220C0F110015143B4F96C2000FB38 +:10AEC000021040F30F10688094F84010890710D5E5 +:10AED000B4F96010884203DDB4F96420904205DCC7 +:10AEE000884206DAB4F96410884202DAB4F86400E1 +:10AEF000688094F98400B5F90020C0F11001514335 +:10AF0000B4F96A2000FB021040F30F10288094F877 +:10AF10004010890724D5B4F95E10884203DDB4F9E6 +:10AF20006220904207DC00E02EE088420ADAB4F9A1 +:10AF30006210884206DAB4F86200288094F8400073 +:10AF400080070DD5B5F90000B4F96210884207D129 +:10AF5000B5F90200B4F96410884201D184F8847014 +:10AF6000316894F8840091F8D71301F00F01401A6A +:10AF700040B284F88400002801DA84F884702868DC +:10AF8000C4F86A00BDE8F08184F88470012084F878 +:10AF90008200F7E72DE9F0470446012790F8840086 +:10AFA0008846B94668B194F88200012809D0032286 +:10AFB00004F16E0009F06CFD94F88300012805D0BF +:10AFC0005AE0484684F88290BDE8F0878948884E68 +:10AFD00040780028306806D090F8DA1390F8DB0348 +:10AFE00061F31F450DE090F8D81390F8D90361F391 +:10AFF0001F4560F30F058048017821B1C07860F3E8 +:10B000001F4560F30F052A14524328B200FB0025A8 +:10B0100004F16A034146184609F068FD0022A8427F +:10B0200001DD104600E0484698B1316894F84030A0 +:10B0300091F8D30300EB800040001B0704D591F882 +:10B04000D20300EB8000400020B1A16A81420DD8FC +:10B0500000E058B1306890F80C03000600D40027D7 +:10B06000D4F86A00C8F800003846ADE784F88320B9 +:10B0700094F984000028F7DD41462046FFF7BAFE28 +:10B08000F2E72DE9F84F0446012000905948DFF817 +:10B0900060B10D464178DBF800004FF0000A91B135 +:10B0A00090F8E47390F8E5630322294604F16E00FA +:10B0B00009F0EEFC94F8400000071DD594F8BA01A1 +:10B0C000012805D018E090F8E27390F8E363EBE70D +:10B0D000DBF80000A16A90F8EA0381420CD268888C +:10B0E000B4F86C10401AB4F87E100844A4F87E003E +:10B0F0002888B4F86A100BE06888B4F87410401A15 +:10B10000B4F87E100844A4F87E002888B4F87210C1 +:10B11000401AB4F880100844A4F88000B4F97E0006 +:10B12000002801DB014600E04142B94266DD4FF0F4 +:10B13000010A002801DDC11B00E0C1190FFA81F9E5 +:10B14000A0EB0900A4F87E0034F86C1F01EB0900A5 +:10B1500000B22080DBF80010B1F9321009F090FC49 +:10B1600024F86C09B5F902108646081A0FFA80FC1B +:10B17000BCF1000F01DB604601E0CCF10000B842F9 +:10B1800053DDB4F97400081A00D54042DBF80080A2 +:10B1900003B298F8E80398F8E92398F8E61398F8CA +:10B1A000E77383420DDB82420BD0934201DD3946C7 +:10B1B00007E01B1A7F1A7B43101A93FBF0F0084438 +:10B1C00001B2B4F97E0000FB0CF0002807DDB9F1F4 +:10B1D000000F00DC49420EEB0100A4F86C00B8F946 +:10B1E0003210B4F96C0009F04BFCA4F86C001CE0C0 +:10B1F000A4071000DC07100078071000DBF800102F +:10B20000B4F97000498E884203D1B4F974208A429F +:10B2100003D050B9B4F8741039B9B4F96C10814244 +:10B2200003D0A4F86C004FF0010AB4F980000028A4 +:10B2300001DB014600E04142B14258DD002801DD5A +:10B24000811B00E081190FB2C01BA4F8800034F804 +:10B250006A0F384400B22080DBF80010B1F93410D6 +:10B2600009F00EFC24F86A09B5F900108146081AA5 +:10B270000FFA80FCBCF1000F01DB604601E0CCF16D +:10B280000000B04252DDB4F97200081A00D5404205 +:10B29000DBF8008003B298F8E80398F8E92398F8FF +:10B2A000E61398F8E76383420DDB82420BD09342AA +:10B2B00001DD314607E01B1A761A7343101A93FB1F +:10B2C000F0F0084401B2B4F9800000FB0CF0002853 +:10B2D00006DD002F00DC494209EB0100A4F86A00FA +:10B2E000B8F93410B4F96A0009F0CAFB12E0DBF8CF +:10B2F0000020B4F96E00918E884203D1B4F9723007 +:10B300008B4203D048B9B4F8721031B9B4F96A105D +:10B31000814202D0A4F86A0008E0BAF1000F05D11A +:10B3200092F80C03000601D400200090D4F86A00C3 +:10B3300028600098BDE8F88F10B5044690F8C60163 +:10B3400004281DD194F84000400719D404F10C01E1 +:10B35000081D09F0CBFB02466348006890F8D4133F +:10B36000B4F84000494343070AD48A4202DA40F065 +:10B37000020003E020F0020040F00400A4F84000C6 +:10B3800010BD2DE9F0410E4604460125FFF7D4FF1C +:10B3900094F8C601032804D0042807D0082825D033 +:10B3A00027E03146204600F029F822E04E4F386869 +:10B3B00090F8D003800709D531462046FFF7EAFD13 +:10B3C000054694F88200012803D00CE0012084F89F +:10B3D0008200386890F8D003C00704D03146204678 +:10B3E000FFF74FFE0546012D03D005E0D4F87A00A3 +:10B3F00030603068C4F87A002846C3E570B504466A +:10B400000868C4F86A000D46032204F16E0009F0D2 +:10B410004BFB3548006890F8D0138A074FF00001C5 +:10B420002CD5324A167801227F230EB394F840605F +:10B4300036071DD594F8C561012E12D084F882100C +:10B4400084F8832084F884306A88B4F86C30D21A87 +:10B45000A4F868202A88B4F86A30D21AA4F86620C2 +:10B460000CE084F8822084F8831084F8841005E0CE +:10B4700084F8821084F8832084F8843090F8D00314 +:10B48000C00702D024F87E1F618070BD184810B537 +:10B4900043781548026883B192F8E10392F8DE33ED +:10B4A00000F00F04000992F8DF235B4352439942F6 +:10B4B00002DD91420CDB204610BD92F8E00392F8C9 +:10B4C000DC3300F00F0400095B4392F8DD23EDE765 +:10B4D0009A4200D1521CC91A041B6143D21A91FB33 +:10B4E000F2F1401A10BD0000A40710003A07100046 +:10B4F000DC07100030B50124039D9C4035B10914D0 +:10B5000091420EDA81682143816030BD09B29142D7 +:10B5100003DA01682143016030BD41682143416085 +:10B5200030BDC1682143C16030BDFF49B0F90000A2 +:10B53000B1F92020824203DCB1F92210814201DA04 +:10B5400001207047002070472DE9F84391460646D8 +:10B55000DDE9087288790025DDF828C00C4603284B +:10B560002FD2F248DFF8C883016891F87A0CA080E6 +:10B57000D8F80880B8F1000F04DD91F87B8CA0EBBF +:10B580000800A080B1F87C1C306B884217DDDBB26C +:10B5900049463846CDF800C0FFF7ACFFA079401C03 +:10B5A000C0B2A071032806D0E249B6F95500B1F93E +:10B5B0000010884205DD0320A071012501E0002074 +:10B5C000A0712846BDE8F8832DE9F0410446DA4829 +:10B5D0000078002859D0D548006890F8700CC00653 +:10B5E00053D594F90E0200284FDA94F840008006F3 +:10B5F0004BD4A08F0023C00400D5012304F10C001C +:10B60000FFF793FF0546B4F840004FF001064106EE +:10B610004FF002074FF0030C1DD51D430CD084F8EA +:10B62000C67140F00100A4F8400094F8CA01032854 +:10B6300021D284F8CAC11EE020F0410040F0280069 +:10B64000A4F84000002204F5E071204600F0EDFF70 +:10B6500084F8BA610FE004F12000FFF766FF0128CB +:10B6600001D1012D13D0B4F8400020F0400040F08B +:10B670002000A4F8400094F84000400605D5AF48EB +:10B6800010F87D1F41F004010170BDE8F081002B2E +:10B69000F1D0B4F8400040F04100A4F8400084F834 +:10B6A000C67194F8CA01032801D284F8CAC10E21D8 +:10B6B00004F5DC700EF0D4F9E068C4F8C00184F839 +:10B6C000C461D8E702B29948006890F8F61C8A4233 +:10B6D00003DB808E401A904201DA0120704700207F +:10B6E000704770B591490246002009684C8EB1F848 +:10B6F000003DE51A131412B29D4205DAB1F8025D5D +:10B70000AA4201DA012070BDB1F8045DAB4205DA4E +:10B71000B1F8065DAA4201DA022070BDB1F8085DF9 +:10B72000AB4207DA8D8EB1F80A6DAD1B954201DA96 +:10B73000042070BDB1F80C5D641B9C42F9DA8B8E5D +:10B74000B1F80E1D591A9142F3DA082070BD7749FD +:10B75000B0F90E200968B1F8EE3C9A4214DBB1F85A +:10B76000F03C9A4210DCB0F90C20B1F8F23C9A425D +:10B770000ADBB1F8F43C9A4206DC806A91F8F71CC7 +:10B78000884201D800F064BF70472DE9F047674E4A +:10B790000024326892F8ED3C9D0790F8163219D5D6 +:10B7A0003BB990F81752A5B392F831707F1EBD4295 +:10B7B00030D092F830506D1EAB4202D190F8177223 +:10B7C0003FB3AB4206D192F8315090F817726D1E1C +:10B7D000AF421FD092F8B15CB0F953804FF0640CC7 +:10B7E00008FB05F898FBFCF52DB24D4395FBFCF1E9 +:10B7F0000DB25349B24692F8B06C92F8AF7CD1F8D2 +:10B8000000C0B34208D290F81712B94204D2002106 +:10B810000FE0FFE701243CE0B34212D292F831106E +:10B8200090F817828946C91B88450ADBA9F10100F7 +:10B83000C1B260460EF0F4F9B0F90000A842E9DCAC +:10B8400027E092F83010D046891B8B420ADB90F833 +:10B850001762BE4206D2002160460EF0E1F9D8F828 +:10B8600000100FE056468B4213DB90F8171292F847 +:10B870003100C21B91420CDB401EC1B260460EF08B +:10B88000CFF9316891F8301000EB410030F9020C2B +:10B89000D4E72046BDE8F0872DE9F05F4FF0FF0ABE +:10B8A0004FF000090646D0464F4690F85B502DE019 +:10B8B0002348E9B200680EF0B3F9834696F8594080 +:10B8C0001FE01A483BF914100068B0F8F90C8142E7 +:10B8D00016DD2146504608F0A9FD00F0FF0A21467A +:10B8E000484608F0A7FD00F0FF092946404608F049 +:10B8F0009DFD00F0FF082946384608F09BFDC7B2C1 +:10B90000641C96F85A00A042DBD26D1C96F85C00CD +:10B91000A842CDD2A9EB0A00C001A7EB08018030F4 +:10B92000491C90FBF1F00DE044201000A40710002A +:10B9300050061000D40610003A07100040570120AE +:10B9400054071000FE4980B20968B1F8FD1C81421D +:10B9500002D20120BDE8F09F0020FBE72DE9F0476F +:10B96000F84AF74C90F816621578F74A27680021D4 +:10B970001368F64AB7F9FB9C4FF001081278B6EB52 +:10B98000550F05D290F817C2BCEB520F00D20BE056 +:10B99000B6EB550F0ED290F817C2BCEB520F09D37D +:10B9A00097F83100401EC1B218460EF039F9B0F9CF +:10B9B00000101FE0B6EB550F06D390F817C2BCEB92 +:10B9C000520F01D200210BE0B6EB550F12D390F8C5 +:10B9D0001702B0EB520F0DD397F83100401EC1B2E1 +:10B9E00018460EF01DF9216891F8301000EB410067 +:10B9F00030F9021C494501DA4FF00008404649E79A +:10BA000070B504460025C068FFF75CFE88B9CC48D5 +:10BA10000068B0F8EA1CB0F8E80C091AB4F8BC01E8 +:10BA2000814205DB28B1D4F8C00100F015FE00B951 +:10BA30000125284670BD10B5FFF753FE002809D038 +:10BA4000C3494A8882434A808A8882438A80CA8856 +:10BA50008243CA8010BD2DE9F34FBD4885B00E4624 +:10BA600000784FF0000920B1B949401E087000F07D +:10BA7000EFFD05984FF0000800F580504FF0010AE7 +:10BA80000490E3E104980AFA08FBD0F8E01F11EAF9 +:10BA90000B0F75D0059808EB081100EB411505F563 +:10BAA000DC742846FFF790FDB5F84010480667D4CF +:10BAB000EF68039795F8C601012806D0022804D044 +:10BAC000C9077DD004287CD09FE1A24AB5F9531064 +:10BAD000B2F90020914253DB012803D10E21204608 +:10BAE0000DF09CFF002000909B48007828B99448F6 +:10BAF000006890F8700C80064ED5E868FFF7F1FDFD +:10BB000038B1012000908E48006890F8A50C85F8A7 +:10BB100019020098A8B364212846FFF736FE0128D1 +:10BB200030D02846FFF7B8FE01282ED0062020731B +:10BB3000B5F84000824F40F00100A5F84000E868E9 +:10BB4000A06084F80DA039684346284691F89D1CF2 +:10BB50000096CDE9011A2146039AFFF7F5FC8146CC +:10BB60003868B0F8EA0CA080E868FFF7BAFD18B1B1 +:10BB700077498A8802438A8095F8C411072906D03C +:10BB800061E109E0052085F81A020720CFE7704936 +:10BB9000CA880243CA8056E1704A38B2B2F910101E +:10BBA00088420CDBB2F91210884208DCB2F91A3074 +:10BBB0003914994203DCB2F91830994233DA01E0C2 +:10BBC00006E13AE0B5F8401041F00101A5F8401057 +:10BBD000217B09B9E968A16084F80CA0B2F91010C2 +:10BBE0005746884203DBB2F9123098420CDD002040 +:10BBF0000096CDE90110434621462846039AFFF7F7 +:10BC0000A3FC814627731EE1B2F918004346CDE933 +:10BC10000060029721462846039AFFF795FC81466B +:10BC2000032020730FE100202073306940EA0B00ED +:10BC300030612846FFF78BFD05E1207B072820D1E6 +:10BC40003F48006890F8B21C2846FFF79EFD012887 +:10BC50000BD02846FFF782FE012806D095F81A027D +:10BC600028B1401E85F81A020BE00520FAE70620ED +:10BC70002073A068FFF735FD18B13549CA888243A3 +:10BC8000CA80207B062814D1A088012821D9284603 +:10BC9000FFF702FE012809D107202073A068FFF7F3 +:10BCA00020FD18B12A49CA880243CA80207B062891 +:10BCB0000FD0C0B207280CD0284A39B2B2F91030E0 +:10BCC000994203DBB2F91230994271DD03286BD03F +:10BCD0009BE0E868FFF705FD30B11948006890F86F +:10BCE000A51C85F8191205E095F8190278B1401ED7 +:10BCF00085F819021248CDF800A008F0FF0300688B +:10BD00000399B0F99E2C3046FFF7F4FB7DE0134A0F +:10BD100039B2B2F91000814203DBB2F91230994214 +:10BD20001EDD00210096CDE901014346214628464B +:10BD3000039AFFF709FC814684F80CA030E000006C +:10BD4000A407100028071000540710002707100050 +:10BD500050061000E806100078071000442010007C +:10BD6000B2F91A103814884203DCB2F9181088426C +:10BD70000FDAB2F918104346CDE90061CDF808A0FA +:10BD800021462846039AFFF7DFFB814603202073F4 +:10BD900006E0316941EA0B013161FE4981F800A0FA +:10BDA000A068FFF748FE30E084F80CA00DE0FFE744 +:10BDB000B2F91A303914994203DCB2F918209142D1 +:10BDC00023DA012821D103202073E868A0601CE059 +:10BDD000F14938B2B1F91020904216DDB1F91220C4 +:10BDE000904212DAB1F91A20381490420DDAB1F902 +:10BDF0001810884209DD3169284641EA0B0131619A +:10BE0000E44981F800A0FFF7A2FC95F8C6010528D7 +:10BE100019D1E248B5F90E100068B0F8EE2C914245 +:10BE200011DBB0F8F02C91420DDCB5F90C10B0F834 +:10BE3000F22C914207DBB0F8F42C914203DC90F82D +:10BE4000F81CD7480170049808F1010890F9EC1F1C +:10BE50004145BFF617AE30687268B168F36840EAD2 +:10BE6000020441EA03052C43346901D02CB107E0F8 +:10BE700034B1CB4C0225657002E0C94D85F801A0B4 +:10BE8000C54C58342568A8433060606882437260AE +:10BE9000A0688143B160E068C2498343F3603069C0 +:10BEA0000978084305D12C22A4F12C01BA480DF0E1 +:10BEB0007BFD07B04846BDE8F08F30B590F8C6115D +:10BEC000002204292DD1B5490B6893F8701C49074D +:10BED00027D5B0F84810B0F84A40091BAE4C248D65 +:10BEE000A1421EDD4FF4E271095C012901D0022953 +:10BEF0000AD190F85A4090F85950641B93F8795C35 +:10BF0000AC4201DD01220CE0032901D0042908D153 +:10BF100090F85C1090F85B00081A93F8791C88423E +:10BF2000F0DC104630BD30B59C4900220B6893F818 +:10BF3000701C49072BD590F8C611042927D1B0F8F9 +:10BF40004810B0F84A40091B934C248DA1421EDDD5 +:10BF50004FF4E271095C012901D002290AD190F85D +:10BF60005A4090F85950641B93F8795CAC4201DD5B +:10BF700001220CE0032901D0042908D190F85C10BB +:10BF800090F85B00081A93F8791C8842F0DC1046A0 +:10BF900030BD2DE9F34F8BB0814800270A974078D8 +:10BFA0000E46012806D1306920B17B4841690391D2 +:10BFB000C06903E078480169039180694FF0000887 +:10BFC00082460B9800F58050099001E209984FF0E5 +:10BFD000010909FA08FBD0F8E01F11EA0B0F18D08D +:10BFE0000B9808EB081100EB4115B5F8400041062D +:10BFF0000FD4C0070ED0E868029095F8C60105F589 +:10C00000DC7401280AD0022808D004282FD0052883 +:10C010007DD0DAE15F4981F80090D6E1F0680090C8 +:10C02000306901901422314604A80DF078FC0DF11E +:10C03000100B28469BE80E00FFF73FFF012801D1B7 +:10C0400084F80190F0680090306901901422314624 +:10C0500004A80DF064FC0DF11009284699E80E00C3 +:10C06000FFF761FF0128D4D10020A080ADE1207B43 +:10C07000012801D0032804D1474841690391D0F831 +:10C080001CA0F0680090306901901422314604A889 +:10C090000DF045FC0DF1100C28469CE80E00FFF752 +:10C0A00042FF012803D0A088012802D012E000201E +:10C0B00014E0207B06280FD12846FFF7A1FC30B101 +:10C0C000316941EA0B013161324981F80090A06881 +:10C0D000FFF7B1FCA08810B1A088401EA0803248B4 +:10C0E000008810B10020A08001E0A08820B995F858 +:10C0F000D01109FA01F00743F0680090306901900F +:10C100001422314604A80DF00AFC284600E00CE198 +:10C110000DF1100C9CE80E00FFF7CFFE012801D1B5 +:10C1200084F80190A079032819D2A188B9B11B49DC +:10C130002A6B0968B1F87C1C8A420EDD401CC0B233 +:10C14000A071032806D01949B5F95500B1F90010BE +:10C15000884204DD01200A9001E00020A071207BCC +:10C1600006282AD0072828D0039ABDF9081012B251 +:10C17000019291420DDB039A1214914209DCBDF940 +:10C180000A104FEA2A42914203DC0FFA8AF29142E6 +:10C190007EDA0DE0EE06100044201000A407100027 +:10C1A000500610006807100020071000D406100089 +:10C1B000022842D0042843D046E0306910EA0B0F31 +:10C1C00032D0FE486422016891F8FF0CB1F8EA1CF5 +:10C1D0004043494391FBF2F101FB00F904F10801EE +:10C1E0008B4602A808F082FC484502D2012202A92F +:10C1F00001E000225946284600F017FA95F8D011C0 +:10C200004FF0010909FA01F08743002259462846F8 +:10C2100000F00BFA35F8400F20F0050040F0080060 +:10C22000288084F80290D0E001200090E34808F0D4 +:10C23000FF030068B0F99E2C3AE084F80C9001E00E +:10C2400003202073E868A060607840BBDC4904F1FB +:10C25000080B05F10C00496A009195F8C4110129F9 +:10C260002BD0594608F042FC009988420CDD01228F +:10C270005946284600F0D9F9B5F8400020F00500ED +:10C2800040F00801A5F8401095F84000000700E0D4 +:10C2900022E004D595F8D01109FA01F08743207BFC +:10C2A000012811D008F0FF030FFA8AF2CDF80090B0 +:10C2B00030460299FFF71EF987E0BBF90210B0F98A +:10C2C0000200081A4043CFE700200090DDE9012179 +:10C2D00008F0FF033046EDE73069002240EA0B002A +:10C2E000306104F10801284600F09FF9B5F84000DC +:10C2F00020F0050040F00800A5F84000AF4884F8A1 +:10C300000290B5F84210006890F8862C914206D948 +:10C3100095F8CA1190F8870C084485F8CA0195F879 +:10C32000D01109FA01F087434FE0207B012804D0A7 +:10C3300003280BD0062814D017E0A088F0B39F483C +:10C34000B5F955100068B0F88D0C07E0A088A8B3C7 +:10C350009A48B5F955100068B0F8880C814219DC8C +:10C3600033E02846FFF74CFBA0B9207B072822D1F9 +:10C37000E868FFF7A7F9F0B99048006890F8ED0C6D +:10C38000C00718D0B5F8BC01A8B1D5F8C00100F0BD +:10C3900063F980B9012204F10801284600F045F94B +:10C3A00035F8400F20F0010040F080002880B5F8FB +:10C3B0001500A5F81300207B062800E005E001D059 +:10C3C000072802D1A068FFF736FB099808F1010899 +:10C3D00090F9EC1F4145BFF6F9AD7A490FB1012044 +:10C3E00000E0002008700A980DB064E57349744AB3 +:10C3F00009682C32898E1084081A508470476F4A5D +:10C400006F4B12682C3340B171B1518E081A5883AA +:10C4100092F8821C401AD883704711B1508E58830D +:10C42000F9E70020188303E0188392F8821C08447F +:10C4300098837047614910B40B68614A998E2C3219 +:10C4400060B11082091A518293F8824C2044908284 +:10C45000081BD08293F8850C10BCC7E7002010821F +:10C4600051829082D1821084518410BC704770B583 +:10C47000524C206890F8830CFFF7DCFF2068012104 +:10C4800090F88C0CFFF7BBFF2068002190F88C0C13 +:10C49000FFF7B5FF21684A4A91F8800C2C324043DF +:10C4A000506291F8810C108545492C222C3144486A +:10C4B0000DF07AFA43480024444D04704248142198 +:10C4C00004703F48AC6058300DF0CAFA4048047020 +:10C4D0006C7070BD70B586B00646142168460DF0CC +:10C4E000BFFA39480024694604703046FFF7B3FAB2 +:10C4F000054669463046FFF74CFD2843334901287D +:10C5000001D0886805E02D48006890F87A0C401F3B +:10C510008860002804DD401E88602A48007800B941 +:10C520008C6027481422694658300DF03DFA06B059 +:10C5300070BD2DE9F04700F136060546B078DFF80A +:10C5400094800A460024C0B12349F3780878401E3D +:10C55000834268D18946C1B210460DF05BFB0746A5 +:10C5600099F80000401EC1B2D8F800000DF058FB49 +:10C5700003463078717802460FE0002110460DF036 +:10C5800049FB07460021EFE7BE5C95F841C06645D0 +:10C5900001D1641CE4B2521CD2B29142F4D2074AD7 +:10C5A000E8B11668B6F8726C401EC0B233F910706C +:10C5B000B74214DD641CE4B200280FE0A4071000A9 +:10C5C00044201000EC061000EE061000500610008B +:10C5D000ED0610005407100027071000E4D124488E +:10C5E0000078401E81420DDA166881420ADA491C41 +:10C5F000C9B2B6F872CC33F91170674502DD641C1C +:10C60000E4B2F2E71B4880F87E40116891F8841C80 +:10C61000A14208D2A98C41F48051A98410F87D1F51 +:10C6200041F008010170BDE8F087022380F8C631AF +:10C63000002380F8CA3101238362012A04D00968EB +:10C64000016280F8B831704703220C3008F02CBA30 +:10C65000094881884180704710B50024FFF741F8F0 +:10C6600020B105494988014200D00124204610BD6F +:10C67000280710004057012050061000FBF7A8B90A +:10C6800010B542F2A001FB480DF0EAF94FF4C46185 +:10C69000F9480DF0E5F9F948FF2180F8EC1FF84959 +:10C6A0000020088000F06AFFFEF708FBFFF7DFFEBE +:10C6B00000F010FAFCF7F6FAFDF75BFBBDE810405E +:10C6C000FBF788B910B5EC4CEE4994F81806887160 +:10C6D0002146E84800F092FFEB48007810B1E548A9 +:10C6E000FFF7F8FEE948006890F80C03C00702D095 +:10C6F000E048FEF7BAFADF4800F0EDF9DD4800F057 +:10C700007DFCDC48FCF7DCFADA48FDF73EFBD94853 +:10C71000FBF75AFA002084F8180610BD10B5D94866 +:10C7200000248471D34800F02FFFD248FCF7C8FAE8 +:10C73000D048FBF7C8F9D2480480CF4880F81846A3 +:10C7400010BD10B5CC4C94F8180690B1CD49887145 +:10C750002146C84800F052FFC64800F0BCF9C54861 +:10C76000FCF7AEFAC348FBF7AEF9002084F81806D0 +:10C7700010BDBDE81040D1E710B5C2480024847157 +:10C78000BC4800F001FFC048007828B1B948FFF765 +:10C79000A1FEB84800F09FF9B648FCF791FAB548F9 +:10C7A000FDF7F3FAB348FBF70FFAB34880F81846E1 +:10C7B00010BD10B5B04C014694F818060F280FD2E2 +:10C7C00000EB800202EBC00004EBC00068220DF019 +:10C7D000EBF894F81806401C84F81806012010BDE8 +:10C7E000002010BD10B500F580500021D0F8E02FDA +:10C7F0001346D40706D05208491C0F29F9DB4FF025 +:10C80000FF3010BD01228A401343C0F8E03F90F989 +:10C81000EC2F8A4201DA80F8EC1F48B210BD10B547 +:10C8200000F5805091F80D420123D0F8E02FA3408D +:10C830009A43C0F8E02F002281F8C62190F9EC2F2E +:10C8400091F90D128A4207D1D0F8E01FB1FA81F1B7 +:10C85000C1F11F0180F8EC1F10BD30B500F580500C +:10C860000022D0F8E43F1C46DD0708D0521C5B08CC +:10C8700052B20A2AF8DBFF2081F80E0230BD0123F4 +:10C8800093401C43C0F8E44F81F80E2230BD10B530 +:10C8900000F5805091F80E420123D0F8E42FA34018 +:10C8A0009A43C0F8E42FFF2081F80E0210BD7248B1 +:10C8B000704770487047704890F8180670476E4887 +:10C8C000A03890F89A0070476B4810B50421C03822 +:10C8D0000BF024FEC0B210BD70B56C480026664C4B +:10C8E00001683546A4F1A00491F86602C0062CD573 +:10C8F00067480078012828D0664AB1F86D0212789E +:10C900000AB1B1F862026449097811B36349096850 +:10C9100088421ED258480421C0380BF0FFFD014662 +:10C9200094F89900544AB8B192F8181694F89830CF +:10C9300099420ED9401C10F0FF0084F8990084F849 +:10C94000981082F8185612D112E084F899500020FD +:10C9500070BD84F899500BE092F81806884207D908 +:10C96000012184F8991084F8980082F8185601265D +:10C97000304670BD2DE9F0413F4F4FF0004597F82C +:10C980001866002E3AD000200AE000EB800101EB8F +:10C99000C00107EBC101C969A94200DD0D46401C79 +:10C9A000B042F2DB002087F818060446DFF8DC808E +:10C9B00022E004EB840000EBC40007EBC00164221A +:10C9C000C869504390FBF5F0D8F8002000B2B2F8E7 +:10C9D000252282420FDA97F8180600EB800202EB5C +:10C9E000C00007EBC00068220CF0DEFF97F81806C5 +:10C9F000401C87F81806641CB442DADBBDE8F081FD +:10CA00002DE9F0411B4D002405F580560127D6F88D +:10CA1000E00F07FA04F1084210D004EB041005EB14 +:10CA2000401191F90E02002808DBD6F8E43F07FA1E +:10CA300000F2134202D02846FFF729FF641C64B2BB +:10CA40000F2CE4DB042105F5FF500BF067FD0C49CA +:10CA50000880D3E701218140002809DB0748D0F88E +:10CA6000E02F0A4204D0D0F8E82F0A43C0F8E82F9C +:10CA700070470000B020100050411000B03010008E +:10CA80005C061000405701203A071000A407100070 +:10CA900018051000B706100034071000CC0610006F +:10CAA0000028E5DB012181400948D0F8E82F8A43BE +:10CAB000C0F8E82FDCE7002808DB054901228240A6 +:10CAC000D1F8E81F114201D00120D1E70020CFE7C3 +:10CAD000B030100070472DE9F05F0646002706F5DC +:10CAE0008054B94638464FF0010B94F9EC2F13E00F +:10CAF000D4F8E03F0BFA00F10B420BD000EB001131 +:10CB000006EB411191F8C611012903D0022901D089 +:10CB10007F1CFFB2401C40B28242E9DA0025DFF8F8 +:10CB20002CA4BDE0D4F8E01F0BFA05F001420BD0B5 +:10CB300005EB051006EB401191F8C601012804D061 +:10CB4000022802D004287DD0A8E091F8180201281C +:10CB500008D091F8C721032A08D0042A06D0012A58 +:10CB600004D09BE0002081F818026AE0F84891F8B0 +:10CB700040C00123B0F900005FEACC7C02D0F54848 +:10CB8000B0F90000A7B9DFF8D0C39CF800C0BCF131 +:10CB9000010F0DD1F148F24BD0F800C01B78BCF961 +:10CBA0000502052B01D0062B01D1BCF90A02002396 +:10CBB0009AF803C0BCF1000F04D19AF80480B8F1D0 +:10CBC000000F0CD0012A02D0CA8FD20507D509F177 +:10CBD000010000F0FF09E348B0F9000021E003B3D1 +:10CBE000DE4A1368B3F8C922DAB1B3F9C922BCF13D +:10CBF000000F04D19AF804C0BCF1000F01D0B3F9C2 +:10CC0000CD22B1F83CC05FEA4C5C01D5B3F9CB2230 +:10CC1000B1F95330834214DBB1F91002904210DBBA +:10CC20003CE0CA8FD20508D5CE4AB1F95330B2F9EB +:10CC30000020934201DD81F8C7B1B1F9532082424F +:10CC40002CDA00E003E03046FFF7E9FD26E091F83A +:10CC50003C0010F0060F21D091F84000C0071DD114 +:10CC6000C24AC1481278B0F90000012A02D1C04876 +:10CC7000B0F9000091F8C721032A02D0022A06D099 +:10CC80000CE0BB48B1F95320B0F9000001E0B1F964 +:10CC90005320824202DA052081F8C6016D1C6DB274 +:10CCA00094F9EC0FA842BFF63DAFAC4D286890F860 +:10CCB0000D03400767D5AF480078E8B3AE48407829 +:10CCC000D0B3042106F5FF500BF028FC02285ADDF2 +:10CCD00000210A460846DC4694F9EC8F2F681CE0D8 +:10CCE000D4F8E03F0CFA00F52B4214D000EB00130F +:10CCF00006EB431595F8C631012B03D0022B01D06A +:10CD0000042B08D1B5F95330B7F88A53AB4202DD92 +:10CD1000491CC9B21A44401C40B28045E0DA0229DD +:10CD200031D392FBF1F097F889134143642091FBD2 +:10CD3000F0F007B2002500E025E0D8461CE0D4F86A +:10CD4000E01F08FA05F0014214D005EB051006EBD0 +:10CD5000401191F8C601012801D002280AD191F8AA +:10CD60003E00000706D4B1F95300B84202DA30465B +:10CD7000FFF755FD6D1C6DB294F9EC0FA842DEDA99 +:10CD80007E48A0F846709AF80300012808D1B9F14E +:10CD9000000F05D0D4F8E00F002801D178490870C1 +:10CDA000BDE8F09F0021A0F8DC11C0F8D811A0F870 +:10CDB000DE11202100F5F3700CF030BE02B9012223 +:10CDC000002303E020F813105B1CDBB29342F9D37D +:10CDD000704702B90122521E12F0FF0206D000EB8A +:10CDE000420333F8023C20F81230F4E70180704728 +:10CDF00070B590F8C6210CB200F5F375032A05D082 +:10CE000090F83C10C90607D5FFF7CCFF1022214649 +:10CE10002846FFF7D3FF04E0102221462846FFF7FB +:10CE2000D8FF2846BDE87040102108F0D7BB2DE997 +:10CE3000FC5F4FF0000A044690F8C601DFF81CB111 +:10CE4000676B55465646D146D0460F280FD2DFE8CD +:10CE500000F0C80808080FC8C8C8C80F0FA4A4C8A5 +:10CE6000A400002084F8E4012046FFF79BFFB8E00F +:10CE700004F10C01081D07F039FE064694F8E401A0 +:10CE800040B9DBF80000B0F8C90A874202DD012092 +:10CE900084F8E401DBF800003A4B90F8CB2A1B78C9 +:10CEA0009A4213D394F8E42182B190F8D40A009006 +:10CEB00039462046FFF79CFF804694F83C00C007A7 +:10CEC000DBF8000006D0B0F8CE0A05E02046FFF7F8 +:10CED00069FF5BE0B0F8CC0A8246D4F80802311A48 +:10CEE000002901DCFE2200E0C822314607F0A6FC42 +:10CEF000064600984043B04207DA44F62061884570 +:10CF000003DA2046FFF74EFF1CE0DBF800000125A6 +:10CF100090F8D51A90F8D42A90F8D73A90F8D60A13 +:10CF2000CDE9000552434943304607F02CFB8146CA +:10CF300008FB09F1642091FBF0F085B2504655459D +:10CF400000D30546AF421FDA01201EE0945A1000BC +:10CF5000D4061000E806100018051000A407100001 +:10CF600024071000D8061000DC061000ED061000A3 +:10CF7000DA06100034071000DC07100040570120CB +:10CF8000310710003507100000208246C4F8D86130 +:10CF9000A4F8DC81A4F8DE9123E094F83C00C107FA +:10CFA0004548006802D0B0F8CE1A01E0B0F8CC1ABB +:10CFB000B0F8D02A90F8D80A1144B4F9DE2189B229 +:10CFC0001044B4F9DC215043642290FBF2F085B2A6 +:10CFD0008D4200D30D46AF4201DA012000E000206F +:10CFE0008246364820F8645FDBF80010B1F8C91AB1 +:10CFF0004180C78086805046BDE8FC9F2DE9F04700 +:10D0000007462F480078002854D02E48C0780028C2 +:10D0100050D12D48007801284CD000254FF001094F +:10D0200007F5805809FA05F0D8F8E01F01423DD015 +:10D0300005EB051007EB4014002694F90D02FFF7ED +:10D040003AFD012832D094F8C701032801D0042802 +:10D050000AD11948006890F8C80AC00704D02046D1 +:10D06000FFF7E5FE01280AD094F8C601092816D07A +:10D070000A2814D00B2814D00C2812D014E094F8ED +:10D08000C6010126032806D0042804D00D2804D0A8 +:10D090000E2802D008E0092004E00C2002E0042061 +:10D0A00000E00D2084F8C601C4F8D4616D1CEDB217 +:10D0B0000F2DB7D3BDE8F087A4071000405701201B +:10D0C00078071000945A1000180510002DE9F05F41 +:10D0D000DFF8CC9515460C46834601F10C084FF05D +:10D0E000FF3A002602F10C07CBB3012084F8C601F9 +:10D0F00095F8400084F8C70184F80EA284F8CA614C +:10D1000084F8CB61E687A4F84060A662E66284F802 +:10D11000C96184F8CC6195F8420084F8CF01688E2B +:10D12000A4F85500E868206203223946204607F03B +:10D13000BBFC03223946404607F0B6FCD9F8000094 +:10D1400090F8980C84F8120284F8B56194F90D02F5 +:10D15000002801DBFFF7A4FCA4F814622CE0FFE731 +:10D160001146204600F010FBA06A401CA06294F813 +:10D17000C601042804D1E06A411C01D0401CE062D1 +:10D1800003223946204607F083FC032239464046F5 +:10D1900007F07EFC94F8CE0184F8CF0194F8C70123 +:10D1A00004285DD195F84000042859D094F8120263 +:10D1B00010B1401E84F8120295F8400084F8C701AF +:10D1C00095F8410084F8D00195F8420084F8CE012A +:10D1D000E88CA4F84200288DA4F84400688DA4F8D7 +:10D1E0004600E88DA4F84800288EA4F84A0095F877 +:10D1F000490084F84C00288BA4F84D00B5F93200A2 +:10D20000A4F85300A9692163E9696163296AA163EC +:10D21000A98EA4F85710A98CA187D5F83610C4F8A8 +:10D2200059106969E16195F8431084F8D11195F8B6 +:10D23000441084F8D211B5F84610A4F81012B4F9CD +:10D240005510814201DAA4F85500C4F81C6284F834 +:10D250000CA2A88C8005E08F07D540F4807006E012 +:10D26000D9F8000090F8980CA4E720F48070E087CB +:10D27000A88C0005E08F02D540F4806001E020F426 +:10D280008060E08715F83E0F84F81602687884F80D +:10D29000170221465846BDE8F05F00F04BBA2DE971 +:10D2A000FF4F0E46FF498346FD4D49688BB0002075 +:10D2B000086028689A46B0F80E430CF071FC01280B +:10D2C00004D12868B0F8100300B10446F64800788D +:10D2D00060B12868F54AB0F816131268B0F8124326 +:10D2E0004943914202DAB0F814030444F04800784C +:10D2F000002802D02868B0F82842E94804FB04F866 +:10D30000006890F8189301D090F82A920BF580509D +:10D310004FF000050990A7E00998D0F8E01F4FF002 +:10D32000010000FA05F001427AD005EB05110BEB84 +:10D33000411494F8C601072872D02146201D07F039 +:10D34000D5FB00FB09F000FB09F794F8C6010328A0 +:10D3500005D1D3490968B1F8191301FB01F8414619 +:10D36000474500DA0F46042807D0062805D00A28CA +:10D3700003D00C2801D00E281BD1CE4800780628F7 +:10D3800017D0052815D00420049000214FF47560B3 +:10D39000CDE90201009104F5907304F5847204F163 +:10D3A000A00107A807F098FA0898ADF806000798BA +:10D3B00020E0A06A10B30128224604F1040105A868 +:10D3C00021D007F089FB221D111D06A807F084FB60 +:10D3D000BDF91600BDF91A10BDF918200844411016 +:10D3E000BDF91400104462881144ADF8061021887C +:10D3F00001EB6000ADF8040000242EE06088ADF879 +:10D4000006002088F6E707F067FB6088BDF8161075 +:10D410000844ADF806002088BDF814100844E9E778 +:10D420001FE004EB840000EBC40006EBC00101A880 +:10D430000C3107F05BFB0146B8420CDA99484068B2 +:10D44000026802EB420200EB420251605472157214 +:10D450000168491C0160641CE4B296F81806A042F9 +:10D46000DFD86D1C09986DB290F9EC0FA842BFF699 +:10D4700053AF8C4C6068016800297CD000F0ECF957 +:10D480000025DFF834824FF006096FE005EB450117 +:10D4900000EB41000D9A90F908100127146890F9EB +:10D4A000090007FA01F214425FD1DAF800C007FA66 +:10D4B00000F31CEA030F58D114430D9A1460DAF8F4 +:10D4C00000201A43CAF8002001EB011200EB800192 +:10D4D0000BEB421401EBC00006EBC0020023214617 +:10D4E0005846FFF7F3FD94F8C601032808D0042836 +:10D4F00009D006280CD00B2834D00C2832D034E0C8 +:10D5000084F8C97102E0002084F8C90104202AE0EF +:10D51000042084F8C60194F83C0010F0060F24D0D3 +:10D5200094F84000C00720D1654964480978B0F9F3 +:10D530000000012901D1B8F9000094F8C7110329AE +:10D5400002D0022908D010E0B4F95310B8F9000055 +:10D5500004E084F8C69108E0B4F953108142F8DB86 +:10D5600003E008E00C2084F8C6016D1C4D484068BB +:10D570000168A9428ADC0FB0BDE8F08F494800215C +:10D5800001704160816070472DE9F041064641F627 +:10D59000EE702E2130440CF041FA0024052706F5E8 +:10D5A00080551EE00121D5F8E00FA140084217D0B8 +:10D5B00004EB041006EB401191F8C601032816D0C5 +:10D5C000042814D0022815D0092810D00A280ED01B +:10D5D0000B280FD00C280DD00D280BD00E2809D009 +:10D5E000641C95F9EC0FA042DCDABDE8F08181F80B +:10D5F000C671F5E73046FFF712F9F1E72DE9FC4770 +:10D600000546002427480F4600940121001D01947F +:10D6100004F07EFA23480521083004F079FA41F637 +:10D62000EE702E2128440CF0F9F91E4EFF222D2118 +:10D63000B0680CF0EBF9347005F580564FF0010935 +:10D64000D6F8E00F58B36B4601AA39462846FFF7D3 +:10D6500026FE4FF0050821E0D6F8E01F09FA04F095 +:10D6600001421AD00199084217D104EB041005EBCE +:10D67000401191F8C60103282BD0042829D0022894 +:10D680002AD0092825D00A2823D00B2824D00C28FA +:10D6900022D00D2820D00E281ED0641C12E015E0E8 +:10D6A000A407100060061000B70610006C071000F9 +:10D6B00029051000F8041000DA061000DC0610003E +:10D6C000ED06100096F9EC0FA042C5DA00244E4694 +:10D6D00021E081F8C681E0E72846FFF7A0F8DCE703 +:10D6E000009906FA04F0084214D12846FFF77AF8A8 +:10D6F00000280FDB00EB001105EB411104EB840265 +:10D7000002EBC40281F80D0207EBC2020123284696 +:10D71000FFF7DCFC641C97F81806A042E0D8012152 +:10D720005F4804F00DFA5E480521001D04F008FA78 +:10D73000BDE8FC8730B55A4D91F8CE412D1FAB683E +:10D740001A5DFF2A05D12A781A550F2A01D2521CD8 +:10D750002A7091F8CE2101249A5C81F8CE2100EB49 +:10D76000420202F5805291F80D52B2F8EE3FAC4001 +:10D770002343A2F8EE3F91F8CE1142F20C0210447E +:10D780000A5C521C0A5430BD2DE9F041044691F860 +:10D79000400000260D46012801D184F8CC6194F8A0 +:10D7A000C701404FDFF8008101281FD195F84000E4 +:10D7B00003284DD194F8C601022804D0032806D0CE +:10D7C000042804D01EE02046FBF751FA0EE0D8F8FA +:10D7D000001094F8CC0191F8F11201F00F01884289 +:10D7E00002D83978012906D084F8CC6195F8400038 +:10D7F000032807D008E0401C84F8CC01012085F8FC +:10D80000400001E084F8CD6194F8C70103281FD1DE +:10D8100095F8400001281BD194F8C601042817D1BF +:10D820003878B0B9D8F80000B4F95510B0F8F8223B +:10D8300091420EDA94F8CD1190F8FE02814207D29F +:10D84000032085F8400094F8CD01401C84F8CD01F8 +:10D85000CBE684F8CD61C8E67CB500221CE002EB83 +:10D860004203511C00EB430312E001EB410400EBC7 +:10D8700044045E686568AE4209DD00961E89ADF815 +:10D8800004605D6025891D81009D65602681491CBD +:10D8900004688C42E9DC521C01689142DFDC7CBDEB +:10D8A0006406100033071000A40710002DE9FC5F88 +:10D8B00000220192904614460092FE4A1568FE4AE4 +:10D8C000AE8EB2F90030FD4A9E4212687AD183468C +:10D8D00092F8BD0A36358A46C00704D0F848007869 +:10D8E000584305EB4005F7480778F74890F8009053 +:10D8F00060E0F6484FF0000E10F81710A9EB010099 +:10D90000401E92F8061AC0B249064BD592F8280A72 +:10D9100092F827EA46E035F810303BF810103AF854 +:10D920001060591A9B1B09B21EB2002901DB0B467D +:10D9300000E04B42DDF800C0634506DD002901DB55 +:10D940000B4600E04B421BB20093731A01D49C4675 +:10D9500001E0C3F1000CC44507DD002B01DB9C4650 +:10D9600001E0C3F1000C0FFA8CF8002B00DA5B42E7 +:10D97000B2F807CA634514DD002E00DA76420B1EAA +:10D9800000DA4B429E4202DD641CA4B209E0002989 +:10D9900000DA4942B2F8093A994202DD00273C46D2 +:10D9A00002E0401E7045B6DA05EB49050BEB490B6A +:10D9B0000AEB490A7F1E9CD292F80B0AA04201D2C0 +:10D9C0000120019092F80C1AC148019A06F0BCFDA2 +:10D9D000C049A1F82480009A4A8481F82640BDE815 +:10D9E000FC9F70B5B84A0025012112782C46921E82 +:10D9F000D3B2B24A126892F8066A760603D592F854 +:10DA0000283A92F8271A4AB204E030F91260521C00 +:10DA1000354452B29A42F8DD5A1A95FBF2F505E008 +:10DA200030F91120521B02FB0244491C9942F7DDD8 +:10DA3000C4F30F3070BD2DE9FF4F0B460021ABB092 +:10DA40008C46884627918A462991269199490F68E4 +:10DA50009949BC8EB1F900108C427DD12892974A29 +:10DA6000064636371068994690F8BD0AC00704D0BC +:10DA700093480078484307EB4007002573E093483C +:10DA80004FF0000B10F815108F480078401A401E18 +:10DA9000C4B28A48006890F8061A49061DD590F865 +:10DAA000284A90F827BA18E039F8140036F814100C +:10DAB000401A2DF8140037F8140036F81410401AE4 +:10DAC00000B213A9002821F8140000DA4042614690 +:10DAD00006F0B0FC1FFA80FC641E5C45E4DA77486F +:10DAE0000068B0F82A0A60450DD27948801D30F8E8 +:10DAF000741F491C01807649A0F802C000204870BC +:10DB00002FB0BDE8F08F2898FFF76BFFDFF8C0B1AA +:10DB10000BF1060B2BF815006846FFF762FF0BEBC5 +:10DB20004504208413A8FFF75CFFA4F84000208C74 +:10DB3000404502D98046A8B229903BF815005045CF +:10DB400002D98246A8B226905F482899007801EB56 +:10DB5000400107EB400700E072E006EB400609EBEE +:10DB600040096D1C289157480078854287DB534C4B +:10DB70004FF6FF75236893F8290A800727D5B8F177 +:10DB8000000F24D052482999801D00EB4102B3F8C0 +:10DB9000303AB2F840100E02B6FBF8F189B28B426F +:10DBA00009D9012327932E9B12261E70B0F86230EC +:10DBB0005B1CA0F8623030F8603F5B1C038092F879 +:10DBC000402005EA02228280A0F8068001812368B5 +:10DBD00093F8290AC00733D0B8F1000F30D0279846 +:10DBE00070BB0821B1FBFAF239482699801D00EB81 +:10DBF0004104269E218C9140B3F82C2A89B22EB183 +:10DC0000304E269F3678761EBE4201D1B3F82E2ABA +:10DC1000914209D2012227922E9A13231370B0F851 +:10DC20006C20521CA0F86C2030F86A2F521C028025 +:10DC300094F8202005EA02228280A0F806A0018143 +:10DC40001E48279A006890F8321A2148401C06F0B6 +:10DC50007BFC00287FF454AF2E9A002111704FE70F +:10DC60002DE9F74F154F034682B038684FF0000892 +:10DC7000C14690F8196AB0F9171A0091B0F9151A4F +:10DC80000D48C346C246B0F90020454644461846F2 +:10DC9000F9F720F980BB1048007850B10948009985 +:10DCA0000278039800F04AF90546B04201D94FF0D6 +:10DCB000010B13E0A80710003C071000A407100098 +:10DCC000DC07100027071000280710003826012065 +:10DCD0009C2601204057012026071000C4480078E8 +:10DCE00050B1C44800990278049800F027F904461E +:10DCF000B04201D94FF0010ABF48C04E007838B198 +:10DD000038685A4690F81A1A301D06F01DFC8046F5 +:10DD1000B748007838B13868524690F81A1AF01CA3 +:10DD200006F012FC8146A54200D92C46B44880F882 +:10DD3000314048EA090005B0E3E670B50C46AE494B +:10DD4000097861B1AF4D29784A000146AE480BF021 +:10DD5000E6FD2878AC494200AC480BF0E0FDA44851 +:10DD6000007860B1A34D214628784200A8480BF006 +:10DD7000D6FD2878A6494200A6480BF0D0FDA6495A +:10DD80000120087070BD2DE9FF4F81B0A348002429 +:10DD90000E9F8DF80040DFF8888244600470D8F848 +:10DDA0000000DFF880B2DFF8549290F8060A2646A9 +:10DDB0002546C0070FD0032009F03FFEDBF8001016 +:10DDC0000198FFF773FD044611208DF80000032031 +:10DDD00009F04EFE01E089F80050D8F80000DFF8A5 +:10DDE00048A290F8290AC10701D180070FD5032066 +:10DDF00009F023FE6B46DAF80020DBF800100198EA +:10DE0000FFF719FE0443032009F032FE01E089F810 +:10DE10000150ECBB032009F010FE844BDAF800201F +:10DE2000DBF800100198F7F7ADFC032009F020FEA5 +:10DE3000D8F80000DFF8F8B190F8060A800710D58E +:10DE40009BF8001011B99BF8010050B1794A7A494A +:10DE5000DAF8000000F082F8044630208DF8000067 +:10DE600001E089F80250D8F8000090F8060A40074F +:10DE70001CD561485E4900780978084316D06F4880 +:10DE8000007898B99BF8001021B99BF8010000E0D8 +:10DE900010E058B1674A6849DAF80000FFF7E0FE81 +:10DEA000044332208DF80000012603E089F8045075 +:10DEB00089F803506249012C06D1D8F8000090F887 +:10DEC0008F0C08B1088003E0088808B1401EF9E70C +:10DED0000BF072FE01465B48017024B32EB13D7019 +:10DEE000DDE90201FFF729FF1BE040F23C615648E3 +:10DEF0000BF094FD0120494A38709DF80000107025 +:10DF0000506840F002005060D8F8001091F80032DC +:10DF1000DB0703D191F8BA10C90702D040F008001E +:10DF20005060012007E73D70007804E73B4900207E +:10DF300048600870314908608880704710B5044611 +:10DF4000002008E034F91230002B00DA5B428B42EB +:10DF500001DD401CC0B2521EF4D210BD2DE9F74FB6 +:10DF6000DFF8BC900B460026D9F8000001253446A6 +:10DF700090F8138AB0F90F1AB0F911AA33488B46FA +:10DF80002F46007818B132480078B8B121E01A481D +:10DF90000078012805D11B4802781846F8F79AFF47 +:10DFA000054613480078012806D1124859460278E0 +:10DFB0000298F8F78FFF074605B157B92548514633 +:10DFC000B0F900200098FFF7B9FF0446404500D99A +:10DFD0000126D9F80000324690F8141A0748801C30 +:10DFE00006F0B2FA064981F83040BDE8FE8F000025 +:10DFF0002507100028071000260710009C26012086 +:10E00000405701202707100004770120700B0120E2 +:10E010002E7701209A0B0120E30710006C061000F8 +:10E02000A40710005C07100050071000501E1000DD +:10E03000945A1000860C01205C0C0120330710005C +:10E0400020071000B6061000480D01202905100019 +:10E05000140510003C0710002DE9FF4F89B0002087 +:10E0600083460490039002909C488A460068B0F86A +:10E07000410207900B98897840680BF0C3FD00902F +:10E080009AF8021016980BF0C5FD01909AF802005C +:10E090003CE09AF800402AE00998224600EBC800CC +:10E0A0000021D0E9005601200BF0EFFB05400E40A7 +:10E0B00035431BD0009830F914500798854215DD80 +:10E0C0000198005DCF287ED018B11799884200D002 +:10E0D00000250398AB4404FB05000390029808FB5D +:10E0E000050002900498401C80B20490641C9AF8C9 +:10E0F0000100A042D0DA7A490098097800EB41008B +:10E10000009001982830019008F101009AF803105E +:10E1100080464145BDDA71480024026802981746DE +:10E12000918EC317A1FB002504FB005001FB0305E2 +:10E130004FF6FF71A2FB010605FB016102FB041112 +:10E1400097F831203037521E8BFB02230BF0C3FBB4 +:10E1500047F6FF7280184FF6FF7841F10001424602 +:10E1600000230BF0B8FB054603997888CB17A0FB7A +:10E17000012604FB016100FB03134046A2FB00469D +:10E1800003FB0060002102FB01013A782046521E89 +:10E190008BFB02230BF09FFB47F6FF72801841F1C7 +:10E1A0000001424600230BF096FB0B9AC2F81CB00C +:10E1B0000B9A049911850C9948600C990D600DB06B +:10E1C000BDE8F08FFFE74FF000094F464FF0FF36F4 +:10E1D00008EB0600C1B2059016980BF01BFD0690E7 +:10E1E0000598C1B20B9840680BF00CFD4FF0FF3161 +:10E1F000069A6318D25C7AB1CF2A0DD0DDF85CC0E4 +:10E20000624503D130F813203A4497B230F8133006 +:10E2100003EB09021FFA82F9491C49B20129E7DD23 +:10E22000761C76B2012ED3DD002F3FF452AF6F4340 +:10E2300097FBF9F54DE710B52849426800240968B5 +:10E24000002A01DA446003E04B8E9A4200DD43600D +:10E250000268002A01DA046010BD898E8A42FBDD63 +:10E26000016010BD7FB50E4608991446CDE9003116 +:10E27000FF2502AB3146FFF7EFFE1A481749007839 +:10E2800030B1086890F8ED03000701D5042513E0CC +:10E2900094F84000032802D0012807D00CE0086859 +:10E2A00090F8ED03C00707D0002505E0086890F856 +:10E2B000ED03400700D50225294602A801F08CFE97 +:10E2C00002A8FFF7B8FF0398E0810298A08194F8B4 +:10E2D0002400C00601D4E06860617FBDA40710007F +:10E2E00028071000EC0610002DE9F74F0F46FD49F6 +:10E2F00088B0DFF8ECA31EC98DE81E00002210F0E4 +:10E30000FF010492059289466B4605D103F821204E +:10E31000491C49B20429F9DBF34C2478641EA14559 +:10E3200007D1002103EB8104491C49B2A2700429E2 +:10E33000F8DBC0F30720B0F1000806D103EB800141 +:10E34000401C40B24A700428F8DBE8490978491EAD +:10E35000884507D1002003EB8001401C40B2CA7001 +:10E360000428F8DB0024684600EB8400027809EBFF +:10E370000201427861F3070608EB0201827861F33B +:10E380001746C07809EB0201C9B24044C0B261F33C +:10E390000F2660F31F668B4646F30745069015E08F +:10E3A000E9B278680BF02EFC71B204AB0AE030F9E8 +:10E3B0001120002A04DD33F814C0624423F814202D +:10E3C000491C49B28B45F2DA6D1C6DB20698A84221 +:10E3D000E6DA641C64B2042CC5DB002004AD35F918 +:10E3E0001010514500DD8A46401C40B20428F6DB7F +:10E3F0000A98012818D0A7F846A0B9F1000F0CD050 +:10E40000B9490978491E894507D0B8F1000F04D0F1 +:10E41000B6490978491E884503D1B88C40F480601C +:10E42000B8840BB0BDE8F08FB1480021046897F8BC +:10E43000400094F8F432012803D194F8F602181A37 +:10E44000C3B2002035F91020D61702EB9672B3EB59 +:10E45000A20F01DA491CC9B2401CC0B20428F1D392 +:10E46000A44894F8F7220078012807D00020101A59 +:10E470008842D6DCB88C40F40070D1E794F80303EE +:10E48000F5E72DE9F84381469B4817468846017811 +:10E490009A4E974D089A1C4609B94078C0B1296830 +:10E4A00091F8B20183079548007801D5012807D17A +:10E4B00091F8B31109070BD5012A09D1012807D119 +:10E4C00023463A4641464846F6F75FFF002844D0C7 +:10E4D0008B4B3A464146484601F09EFA00283CD014 +:10E4E00094F84000032810D12968E08C91F8C012FC +:10E4F00088420AD93078012807D0042084F84000E7 +:10E500008048017941F0400101713868C4F8360053 +:10E510002868B0F8C90238B1E08FADF800000022D9 +:10E5200021460098FFF7E0FE22463946744800F085 +:10E53000E0FC75492046FDF7FCFF3946704801F0C4 +:10E5400005FA4B46224639466D48CDF80080FFF764 +:10E5500089FE2046FEF72DF90120BDE8F8832DE95C +:10E56000F0410D461F461646044668210BF078FA26 +:10E57000002084F84000654800686060A06006EBF9 +:10E58000450084F8425030F8B41F61850088E0846B +:10E5900006EB85000068C4F83A005D488169216097 +:10E5A0000121A940394201D0406A2060BDE8F081D4 +:10E5B00070B5574C00EB4305049E00EB830386B116 +:10E5C0008E69A660CE8C668009686161B5F8B4106A +:10E5D000A1801968E16090F80E0120701068206138 +:10E5E00070BDA6688E616688CE8466690E60A1885B +:10E5F000A5F8B410E1681960217880F80E1120693F +:10E60000106070BD2DE9FF4F81B00C469846997897 +:10E61000109F0E9D0BF0FEFA814698F802102046DE +:10E620000BF0EAFA009098F8021078680BF0EAFA1A +:10E63000064638484FF0000AC7F818A0006828605E +:10E6400098F8020042E098F800402FE00098015D41 +:10E650000398814228D136F914100F98814220DDA9 +:10E66000039809F804002978204605F0DFFE287099 +:10E670006978204605F0DEFE6870A978584605F0F6 +:10E68000D5FEA870E978584605F0D4FEE8700AF186 +:10E6900001001FFA80FA36F91410B8690844B8610D +:10E6A00002E0002009F80400641CE4B298F80100BC +:10E6B000A042CBD2009809F12809283000900A48DE +:10E6C000007806EB40060BF10100C0B298F8031089 +:10E6D00083465945B7D2A7F826A005B0A2E60000A8 +:10E6E0000080FFFFF89B010028071000270710009B +:10E6F000A407100033071000945A100018051000EA +:10E7000070471000405701202227012050071000B9 +:10E7100074061000629C01002DE9FF4F81B0904605 +:10E720000E9E8B4606EB880096F80EA1DDF8409011 +:10E7300000681C46306001233146584601F087FAD4 +:10E74000019858451CD0A57817E0294601980BF090 +:10E7500061FA0746294658460BF05CFA02462078D3 +:10E7600006E03B5C434501D1115C3954401CC0B20A +:10E7700061788142F5D26D1CEDB2E078A842E4D216 +:10E7800096F80E1100240123514512D0119878B14A +:10E790000AF1010007E0D9F8002003FA00F10A436A +:10E7A000401CC9F8002096F80E11C0B28142F2D286 +:10E7B0000124009343464A4630460F99FFF7F8FE7E +:10E7C00020468AE710B5FE4AFE4C1368647893F839 +:10E7D000BF224CB191F82410090702D593F8C31257 +:10E7E00001E093F8C2120A44904201D9012010BD01 +:10E7F000002010BD2DE9F04389B01C46164688461E +:10E80000814601F0E6FCD4E918015034CDE900015D +:10E8100094E80F00503C01F052FCA085002502AFA7 +:10E820008DF81450ADF81850ADF81C5007AA06A981 +:10E8300005A887E80700D4E918015034CDE90001A4 +:10E8400094E80F00503C01F074FCBDF81800E0851E +:10E85000BDF81C102186DC4F9DF8141084F8491077 +:10E86000A7F88000208EA7F8820094F849004FF0A6 +:10E87000010CC0F1FF0087F88400E08C3881D0489B +:10E88000E28C016891F8C802824251D8CF4A032035 +:10E8900084F8400012780020012A15D091F88022D7 +:10E8A000930702D45207002A00DA0120C54BB1F8C1 +:10E8B000C4225B780BB1B1F8C622A38D934208D273 +:10E8C000C34A127822B104E091F801229206EAE7E5 +:10E8D0000020A7F86D30628D032A00D20020A28CA0 +:10E8E00092051AD4C8B191F8810200060CD502F045 +:10E8F00007F9B848009501950378B7480278B748FA +:10E900000168304602F025F909B0234632464146F7 +:10E910004846BDE8F04302F017BC23463246414664 +:10E920004846CDF800C0FFF7ACFD09B0BDE8F08364 +:10E93000042084F84000387940F040003871ECE75A +:10E94000A748C07858B19E48A64A0068126890F857 +:10E95000FD12914205D290F8E602800701D5002011 +:10E9600070470120704791F82410954ACB079E49C3 +:10E970001268097806D011B192F8EE1205E092F80B +:10E98000EF1202E059B192F8EC128E4B5B7813B1A2 +:10E9900092F8F0221144884204D90120704792F87D +:10E9A000ED12F2E7002070472DE9F04188B0012513 +:10E9B00016460F46804683F8405003F12C0401F0C0 +:10E9C00008FCD4E90D012434CDE9000194E80F00DE +:10E9D000243C01F074FB24F8340B00208DF8140063 +:10E9E000ADF81800ADF81C000DF1080C07AA06A937 +:10E9F00005A88CE8070074E80401CDE9000194E85B +:10EA00000F00243C01F095FBBDF818006080BDF8B4 +:10EA10001C10A1809DF8141004F81D1F6A4921F8EC +:10EA2000800F34F8190C488014F84909C0F1FF0030 +:10EA300008716348006890F8E602C00608D508B07F +:10EA40002346324639464046BDE8F04102F07CBBE1 +:10EA500023463246394640460095FFF712FD08B07E +:10EA6000A4E52DE9F04FE9B000206490834668905A +:10EA70005E485F49B0F900006790B1F90010CDE938 +:10EA8000650101215B4803F08DF85A4801210830E7 +:10EA900003F088F857480221001D03F083F8022193 +:10EAA000554803F035F80421544803F031F8514F2C +:10EAB0004FF466741C3F2146F8690AF0AFFF214607 +:10EAC000786A0AF0ABFF4E48B0F900004100386A9E +:10EAD0000AF0A4FF41480068F6F7EEFB4FF000098A +:10EAE00048488DF81E914C460068049001234A4620 +:10EAF00004A9B86901F0ABF8629401240DF5AD707A +:10EB00002646639001E104A800EB840804AA21468C +:10EB100048A8629BFFF723FD48AB42462146489830 +:10EB200000F0DDFF234662AA48A904A80096FFF77B +:10EB30003FFD0DF5AF7000F0E3FE78B1BDF8440184 +:10EB400040F00100ADF8440148A801F050F828B1A8 +:10EB50002D48274900880880244908801C480078EF +:10EB600038B1BDF8440110F0060F02D12748006803 +:10EB70004990404600F0D6FE28B1BDF8440140F06F +:10EB80000800ADF84401BDF95211679881424CDD8F +:10EB9000BDF8460148A9FFF715FED8B348A8009074 +:10EBA0001B482146639AB0F90030B86900F0DBF9E0 +:10EBB00048AB424621464898FFF71CFE01202AE058 +:10EBC000A4071000DC0710004057012018051000B2 +:10EBD000EC0610002807100027071000500710004F +:10EBE000945A1000C806100033071000DA0610000F +:10EBF000DC06100090061000A0061000AC06100005 +:10EC00003C071000D0061000EA0610005407100060 +:10EC1000DE06100001E064906AE0234662AA48A97B +:10EC200004A8CDF80090FFF7C3FCF448BDF95211D9 +:10EC3000B0F9000081425BDDFFF782FE88B3629885 +:10EC400006FA04F5054245D1ED48006890F88102C6 +:10EC5000000728D5E948DFF8ACC3D7F824A0B0F9FD +:10EC60000000BCF900C0B969224648AB844501DB0D +:10EC7000484617E00DF10C0CCDF800C0CDE90103BA +:10EC800043465046FFF7BEFC6299304629436291E5 +:10EC9000BDF84611CDF820A121B10399C8F80010A4 +:10ECA000E6E725E020BBD648006890F8E602C006FB +:10ECB00010D4629805420DD004A901AB62AA48A8FD +:10ECC000009183E845002246639B796AB869FFF7A3 +:10ECD00023FDC0B9BDF8460148A9FFF744FE38B18D +:10ECE00048AB424621464898FFF75EFE4FF0010BC5 +:10ECF000629906FA04F00843C34962906698088056 +:10ED0000C24965980880641CE4B29DF81E01A042C7 +:10ED1000BFF4F9AEBE494871BE4968980870BE4953 +:10ED200064980870BD4981F800B000F016FDBC4839 +:10ED3000007858B1BB480078012807D1B048006876 +:10ED400090F80102C00601D5FDF714FE0221B64875 +:10ED500002F0F6FE0421B54802F0F2FE0121B448AB +:10ED600002F07EFFB2480121001D02F079FFB04899 +:10ED700001210C3002F074FFAD480221083002F08E +:10ED80006FFF69B0BDE8F08F2DE9F043A848DFB010 +:10ED900000260121001D02F005FFA54802210830D0 +:10EDA00002F000FF0221A04802F0B2FE04219F48B9 +:10EDB00002F0AEFE9E4C4FF46671183CE0690AF01A +:10EDC0002DFE9C48B0F900004100206A0AF026FEA2 +:10EDD000B14699488DF80E914D4600680090012388 +:10EDE0004A466946A06900F032FF012427463CE00C +:10EDF000684600EB84082B466A46214644A8FFF784 +:10EE0000AEFB44AB42462146449800F068FE0DF547 +:10EE1000A77000F075FD28B1BDF8340140F0010085 +:10EE2000ADF83401404600F07DFD28B1BDF8340155 +:10EE300040F00800ADF834017449BDF94201B1F960 +:10EE4000001088420CDDBDF8360144A9FFF7BAFC7A +:10EE500030B144AB424621464498FFF7CBFC012633 +:10EE600007FA04F00543641CE4B29DF80E01A042C9 +:10EE7000BED26749487168486649067081F80090BB +:10EE80006649694881F80090022102F059FE042188 +:10EE9000664802F055FE0121654802F0E1FE644833 +:10EEA0000121001D02F0DCFE61480221083002F061 +:10EEB000D7FE5FB03AE55749002008705649087000 +:10EEC000564908707047F6E759490020183908621A +:10EED0008861C86154490860544908604D49087008 +:10EEE0004D4908704D4908707047A82153480AF0F1 +:10EEF000B7BD2DE9F74F0D464D49183948780F2811 +:10EF000001D2401C487000F0FF0A4D4982F841A030 +:10EF100001EB8A0029680160A9784A480AF07AFE64 +:10EF20008146A87819E000992C7801EBC80B0DE018 +:10EF3000DBE900672246012000210AF0A6FC06401A +:10EF40000F403E4301D009F804A0641C6878A04239 +:10EF5000EEDA09F1280908F10100E9788046414517 +:10EF6000E1DABDE8FE8F2DE9FF5F9B4614469178FC +:10EF7000DDF838800AF040FE0746A178D8F8040092 +:10EF80000AF040FE06460025FFF7DAFC002832D0E2 +:10EF90002D49B8F93200B1F9001088422BDC2B481A +:10EFA000A17894F8039090F800A016E02078627899 +:10EFB0000CE017F800C0019B9C4505D136F910C044 +:10EFC000DC4501DD6D1CADB2401CC0B28242F0D206 +:10EFD000491C06EB4A06C9B228378945E6D24146A4 +:10EFE0002846FFF7C0FC002805D0B8F8240040F4FC +:10EFF0000071A8F82410BDE8FF9F0000DE06100095 +:10F00000A4071000E2061000DC061000DA0610006B +:10F010004057012030071000310710003207100060 +:10F02000945A100018051000A0061000AC0610003D +:10F030008C0610003C071000D0061000704710002E +:10F04000BA2A012022270120D40610002807100028 +:10F05000FE4800787047FE49087070472DE9FC4370 +:10F060000022DFF8F0830092019298F800406F468A +:10F0700000230BE002FB043637F9125030F916601A +:10F08000B54201DA27F812605B1C1BB2A342F1DB28 +:10F09000521C12B2022AEBDBDFF8BC93002201AE55 +:10F0A00099F8004000230BE002FB043C36F91250B3 +:10F0B00031F91CC0654501DA26F812C05B1C1BB291 +:10F0C0004D46A342F0DB521C12B2022AEADB0023B7 +:10F0D000B94600220FE003FB04244FF47A7C30F998 +:10F0E0001470521C07FB0CF739F913C012B297FBCE +:10F0F000FCF720F8147098F80040A242EBDB5B1C90 +:10F100001BB2022BE5DB002200200EE002FB030312 +:10F110004FF47A7731F913407C4336F91270401C72 +:10F1200094FBF7F421F8134000B22B789842EDDB02 +:10F13000521C12B2022AE7DBBDE8FC832DE9FF4F27 +:10F14000C64883B04FF000080068C246C146B0F818 +:10F15000B9B390F8BB130091B0F9CA13019190F8BC +:10F16000A31390F8A4234446474646464546914299 +:10F1700000D811460291BA49097821B1B0F8BCB360 +:10F1800090F8BE030090B749A1F19800FFF766FF21 +:10F19000B049DFF8D0E20020AEF1980E0A780FE017 +:10F1A0003EF91030002B09DD13183EF91310002929 +:10F1B00004DD0DB97F1CFFB2012500E00025401CD5 +:10F1C0009042EDDBA44B002108461B7812E0A54DD0 +:10F1D00035F910C0BCF1000F0ADD03EB000C35F966 +:10F1E0001C50002D04DD09B9761CF6B2012100E0A7 +:10F1F0000021401C9842EADB012F01D8012E11D9D1 +:10F20000964D2868B0F8C1B390F8C31300911499D3 +:10F2100090F8CE0309680144149801602868B0F999 +:10F22000CC03019090480021B0F900602CE08B4D98 +:10F2300003982D6830F91100B5F8C4536D42A84207 +:10F2400007DA002801DB054600E0454255440FFA85 +:10F2500085FA0FFA8BF5A84203DD08F1010505F0E8 +:10F26000FF08002801DB054600E04542029FED1B38 +:10F27000002D03DD00EB09050FFA85F9019DA84279 +:10F2800001DD44F48044491CB142D0DB009988453B +:10F2900041D90026DFF8CCC135460EEB4207ACF170 +:10F2A000980C304611E03CF9101000290CDD37F9BC +:10F2B0001080B8F1000F07DDB1EB080100D549421D +:10F2C00009B28E4200DA0E46401C9042EBDB6548E4 +:10F2D00000EB43020746002011E037F91010002927 +:10F2E0000CDD32F910C0BCF1000F07DDB1EB0C01F1 +:10F2F00000D5494209B28D4200DA0D46401C9842C1 +:10F30000EBDB56480068B0F8C603A84203DDB04204 +:10F3100001DD44F4C07451480068B0F9BF234A4588 +:10F3200001DD44F00804B0F9C813514501DD44F093 +:10F33000040410991298884201DA44F010041199DB +:10F34000884201DA44F0200406990498884202D8E1 +:10F350000598884201D944F040041398012801D04F +:10F3600044F4007407B02046BDE8F08F2DE9F74F54 +:10F3700094B00C464C2101A80AF072FB374A106881 +:10F3800090F8311090F830300B441B1BDDB2A142D5 +:10F3900002D190F8A37301E090F8A4730020864690 +:10F3A0000DF1040B4AE02D492BF810E07346096873 +:10F3B00091F83110A14206D12A49149A983902EBEA +:10F3C0004002A94607E0149E264900FB04F206EB22 +:10F3D00042024FF0010905EB000C21F8103021F832 +:10F3E0001C30002626E0B2F90030B3F1000A01DA41 +:10F3F000CAF10003DB1B002B0CDD3BF8108008EB8F +:10F400000A032BF8103031F81030B2F80080434472 +:10F4100021F81030B2F90030A3EB0708B8F1000F63 +:10F4200004DD31F81C80434421F81C30761C02EBCB +:10F430004902F6B2A642D6D3401CC0B2A842B2D30B +:10F440002946584606F0CAF804460FE0184810004E +:10F450009C0610002807100027071000A4071000C2 +:10F46000B7061000922B01203C071000FE48FF4910 +:10F470002A4600780090086801A990F8A5331698EC +:10F4800006F079F8204617B06EE72DE9F04F93B0FB +:10F490000F4604461E4615464C2168460AF0E0FA1F +:10F4A0004FF0000A50464FF0CF0EEC464CE034F9D6 +:10F4B0001010002939DD4FF0010AD1460CF810A0D8 +:10F4C000411C0EE034F9103034F9112062B1B3EB75 +:10F4D000020809D5D21AB24202DD0CF810E003E0AE +:10F4E000491CC9B2B942EDD30CEB400B411E8BF85D +:10F4F00001900FE034F9103034F9112068B162B195 +:10F50000B3EB020809D5D21AB24202DD8BF801E052 +:10F510001FE0491E49B20029ECDAB9F1CF0F18D02B +:10F520001CF81010CF2918D005E000210CEB400288 +:10F530000CF8101051700CEB40011CF810204978A9 +:10F5400011432954401CC0B2B842B0D3504613B046 +:10F550000AE71CF81010CF2902D005F80090F1E757 +:10F5600005F800E0EEE7F0B5064600200446034645 +:10F5700029E0F55C012D02D0012C19D021E05CB905 +:10F5800000EB4004135530B1A51815F8027C5D1E40 +:10F59000AF4200DA155501244D1EAB4211D1012CAA +:10F5A0000FD100EB40051544401C6B70C0B208E061 +:10F5B00000EB40041444401C63700024C0B20F28C8 +:10F5C00003D85B1CDBB28B42D3D3F0BD2DE9FF4FD8 +:10F5D000A6480C460025006881B0A946818E90F8A7 +:10F5E00031302F46B1FBF3FB418E90F830002E46B0 +:10F5F000B1FBF0FA54E000204CE000233FE003EBC5 +:10F60000830101EBC30104EBC101B1F824C02CF468 +:10F61000006CA1F824C006EB460CCDF800C012F82F +:10F620000CC0B1F90EE00CFB0AFCF44525DCDDF85A +:10F6300000C094449CF801C00CFB0AFCF4451CDBA0 +:10F6400000EB400C9444CDF800C09CF82D80B1F93B +:10F650000CE008FB0BF8F0450FDCDDF800C09CF86F +:10F660002EC00CFB0BFCF44507DB6F1C81F84870C7 +:10F6700009F10101012701F0FF095B1CDBB294F8DD +:10F6800018169942BBD8012F02D100276D1CEDB28C +:10F69000401CC0B2019949788142AED8761CF6B2BE +:10F6A00001980078B042A6D80025B9F1010F51D9D0 +:10F6B00094F818064AE00026411E4BB200EB800188 +:10F6C00001EBC00104EBC1013BE091F84820AAB373 +:10F6D00003EB830707EBC30704EBC70797F84870F2 +:10F6E000BA422CD183422ED003EB830202EBC30239 +:10F6F00004EBC202CF89B2F80EC0B2F80C80A7EBBF +:10F700000C070FFA87FC8F890CFB0CFCA7EB080792 +:10F710003FB207FB07C7DDF810C0674513D28D8CD9 +:10F7200045F400658D84918C41F400619184C2B2EE +:10F73000D9B2204601F0B7F8012505E0FFE75B1ECE +:10F740005BB2002BC1DA0EB194F91806401E40B22C +:10F750000028B0DC284605B006E62DE9F04F8BB056 +:10F7600000200A90FDF7A3F808904048002604689E +:10F77000B4F8A953B4F8AD1309913D4994F8B19385 +:10F78000B4F8A773097841B1B4F8B353B4F8B5131A +:10F79000099194F8B293B4F8B773DFF8D8A09AF847 +:10F7A0000010012908D1B4F8AB13099A29448DB28D +:10F7B000B4F8AF1311440991804694F8A2030006EF +:10F7C0007DD5089890F81806012802D84FF4005605 +:10F7D0000BE094F8A613884202D94FF4806604E047 +:10F7E00025480078012800D1C60222485A219E30BF +:10F7F00005900AF013F994F830105446DFF87CA015 +:10F80000A21CDAF80000FFF7B1FD0090D8F8000064 +:10F81000184A90F831102C320192DAF80000FFF704 +:10F82000A5FD834600FB07F1642091FBF0F083B255 +:10F83000D8F800000F4A90F83010783206920198FC +:10F84000FFF723FE0190D8F8000090F83010DDE9B2 +:10F850000520FFF788FE8DF8280000997943642081 +:10F8600091FBF0F083B20BE09C061000A40710009F +:10F87000B7061000184810002905100050071000A6 +:10F88000D8F80000069A90F83110A01CFFF7FDFD93 +:10F8900007460198184A0743D8F8000090F831103D +:10F8A0000698FFF760FE8DF8290009AACDE90372DA +:10F8B000CDE901B59DF828104B46024600E00BE06B +:10F8C000DAF80000FFF73AFC50EA060506D00020FF +:10F8D00020700A48A0F885500BB045E5099B0AA89E +:10F8E0005B43059A0899FFF771FE20700028F0D15C +:10F8F0004FF48055EDE70000E34810004057012029 +:10F90000017859B1954A1278521E914206D040783A +:10F9100020B193490978491E884201D101207047DE +:10F9200000207047017829B18C4942780978491E36 +:10F930008A4209D1817829B1C17889480078401E6E +:10F94000814201D10120704700207047F0B5854EFB +:10F95000002206EBC2030024C3E90044521CD2B2C9 +:10F96000172AF6D38B782CE000EBC302D2E90072A1 +:10F9700057EA020423D055084FEA370417EB070E65 +:10F9800042EB020C45EA0C05154344EA0E0406EB73 +:10F99000C3023C43D2E9007C27434CEA050CC2E990 +:10F9A000007CD2E9027C27434CEA050CC2E9027CC8 +:10F9B000D2E9047C27434CEA050CC2E9047C5B1CB9 +:10F9C000DBB2CA789A42CFD20022654F09E006EB3B +:10F9D000C203D3E9024500EBC203521CC3E9004550 +:10F9E000D2B23B789A42F2D3087808B1401E087030 +:10F9F0005A4A48781278521E904201DA401C4870E8 +:10FA0000887808B1401E88703A78C878521E9042B3 +:10FA100001DA401CC870F0BD2DE9FF5F8B46977876 +:10FA20009146014607EB870201EBC201002001F17C +:10FA300029081FE000252E4699F8004099F801A0FA +:10FA40000DE018F804205A4507D122460120002174 +:10FA500009F01BFF05430E430120641CE4B2A245DC +:10FA6000EFD2039908F1280801EBC7017F1CC1E917 +:10FA70000056FFB299F80310B942DBD204B0BDE8DA +:10FA8000F09F70B50E788D784C78C9789AB10EB128 +:10FA9000761EF6B2314A1278521E944201DA641C84 +:10FAA000E4B20DB16D1EEDB22D4A1278521E914294 +:10FAB00001DA491CC9B205EB850200EBC200002245 +:10FAC000293009E0334602E0C2545B1CDBB2A3429A +:10FAD000FAD96D1CEDB228308D42F3D970BD2DE9F5 +:10FAE000F04789469178DFF874A001EB810400EBC0 +:10FAF000C4079AF800405868614300EB41060020B3 +:10FB00009861194D03F13E0C947829371FE0107865 +:10FB100013E017F80080C8450DD136F91010D3F85E +:10FB20001880A9428844C3F8188004DD8CF80000CE +:10FB30000D468CF80140401CC0B251788142E8D299 +:10FB40009AF80000641C06EB4006E4B22837D0782F +:10FB5000A042DCD25D86BDE8F087000028071000D7 +:10FB600027071000104910000080FFFF2DE9F04723 +:10FB7000804627488F780C460078801E012F05D9D3 +:10FB8000E178814202DA0020BDE8F087022F01D23D +:10FB9000022601E0E678C7B24FF000093946D8F8EE +:10FBA00008000AF02FF805463946D8F804000AF094 +:10FBB00029F801461748027815E0207863780AE0B2 +:10FBC00035F910C031F91080C44502D04FF0010959 +:10FBD00003E0401CC0B28342F2D27F1C05EB420519 +:10FBE00001EB4201FFB2B742E7D94846CCE70849EA +:10FBF0000978491ECAB290F83F1009B1914205D167 +:10FC0000818C41F0020181840120704700207047FF +:10FC1000270710002807100030B5B0B1884214D073 +:10FC200002D20A4601461046C94B5A6802EB40020E +:10FC300014788C4209D054788C4206D09C68235C9E +:10FC4000022B02D25D1C2554D154084630BD2DE94B +:10FC5000FF4F087887B00F46FF282CD0BD49834658 +:10FC600078780978884201D2401C00E0084600F00C +:10FC7000FF09B878B8490090F8780978884201D22D +:10FC8000401C00E00846C0B2029000200190099894 +:10FC900010B197F80E010190AD4C206800F15A01A7 +:10FCA000C4E901015A2109F0B9FE214622462D205E +:10FCB000496893680AE04FF0000BD9465846CDF8E2 +:10FCC00000B0E1E701F8100000221A54401EC0B253 +:10FCD000F8D20198401CC5B20590009800EB800155 +:10FCE000079800EBC10600980496401C39E0B04626 +:10FCF0000BF101002836C4B22FE031190868F0B1C9 +:10FD0000305D40B3CF2826D011F8011C002001B18E +:10FD1000084618F8041009B1FFF77EFF0A9961B18F +:10FD200008EB0401039111F8011C09B1FFF774FFFE +:10FD30000399497809B1FFF76FFF18B10AE0E41C95 +:10FD4000E4B208E02D2D03D228466D1CEDB201E08F +:10FD5000681EC0B23055641CE4B24C45CDD90AF1DE +:10FD60000100029900F0FF0A8A45C0D9284600F038 +:10FD700066F8824605980022C0B2784B09E007EB8E +:10FD800080011C680C6007EB4001401CA1F8B42006 +:10FD9000C0B25045F3D3049EDDF8008029362FE031 +:10FDA0005D4626E07059E8B3705D00B36849496864 +:10FDB00011F81000705507EB400107EB800431F893 +:10FDC000B42F2846521C0A80217804F02FFB2070A3 +:10FDD0006178284604F02EFB6070A178404604F05C +:10FDE00025FBA070E178404604F024FBE0706D1C18 +:10FDF000EDB24D45D6D308F1010000F0FF082836DA +:10FE000002998845CCD3AAF10100C2B287F80E212D +:10FE10000998002810D00198101A01280CD13B46EF +:10FE2000099900E005E007980BB0BDE8F04F00F03D +:10FE300051B8ED1CEDB2DAE70BB0BDE8F08F2DE95B +:10FE4000F05F82460026DFF808B12AE0DBF80810F0 +:10FE50008C5DDBF8041001EB460719E03819804689 +:10FE600010F8011C10F8029C084600F066F80546E0 +:10FE7000484600F062F8854202D2014628460D4607 +:10FE8000DBF80410641EE4B201F8105008F8025CBC +:10FE9000012CE3D803D1304600F04FF83870761CBF +:10FEA000F6B25645D2D300200146DBF804400DE0FF +:10FEB00004EB410213788B4203D11070401CC0B296 +:10FEC00002E014F813301370491CC9B25145EFD346 +:10FED000BDE8F09FF0B503EB8204A77807EB870538 +:10FEE00000EBC506E0782836B8420FD3207807E04B +:10FEF000351895F801C0944500D16970401CC0B216 +:10FF000065788542F4D27F1CFFB2EBE703EB8100FA +:10FF10002568056003EB420003EB410130F8B42F84 +:10FF2000A1F8B4200D49096821600021018093F8EF +:10FF30000E01401E83F80E01F0BD054AD2E9011200 +:10FF400001E011F81000135C002BFAD1704700009B +:10FF5000A00610002807100027071000629C01006F +:10FF6000F0B5B2F900400568AC4202DDB3F900100B +:10FF700030E002EB410434F9026CAE4204DA03EBE8 +:10FF8000410131F9021C25E0002634464F1E0CE0E9 +:10FF900032F914C0AC4507DC02EB440CBCF902C0DA +:10FFA000AC4501DB26460C46641CBC42F0DB32F952 +:10FFB000161003EB460433F91630B4F9024002EB95 +:10FFC00046026D1AE41AB2F902206C43511A94FBEE +:10FFD000F1F119440160F0BD2DE9F04104461948E2 +:10FFE0000F00036803F2F93293F8F21393F8F35316 +:10FFF00002EB41061BD0022F1CD0032F1DD0042F73 +:020000021000EC +:100000001ED193F8F803012902EB400C0CEB4107D9 +:1000100004DD1346201D6246FFF7A2FF012D0FDD10 +:10002000204633463A462946BDE8F04198E793F822 +:10003000F403E8E793F8F603E5E793F8F703E2E75C +:10004000BDE8F081A4071000002819DD43F2DC713F +:10005000884201DA5520704744F68921884201DA46 +:100060005620704746F6DC71884201DA5720704707 +:100070004DF6C971884201DA5820704759207047FF +:100080004DF6C971C84202DA6FF05900704746F662 +:10009000DC71C84202DA6FF05800704744F68921DB +:1000A000C84202DA6FF05700704743F2DC71C84271 +:1000B00002DA6FF0560070476FF0550070472DE977 +:1000C000F0411546DDE90668971B1C4663EB080204 +:1000D000A7FB073C02FB07CC07FB02C2A0FB007C8E +:1000E00001FB00CC00FB01C04FEA800CB8004CEAD9 +:1000F000977C181842EB0C0104F054F9AD1944EB4D +:1001000008042A1844EB01032D1A64EB01044FF490 +:100110007A71A5FB010704FB0171002605FB06119E +:1001200009F0D9FB4FF47A71D0EB010080B2BDE841 +:10013000F0812DE9F05F8146DDE90A8B0C4600185D +:1001400092466141B2EB08021D4663EB0B03164673 +:100150001F4600F037F90C9932460870A2FB0201E5 +:1001600007FB061106FB07134946A1FB012604FB0A +:10017000096609FB0461890041EA927192008018C6 +:10018000594104F00FF91AEB080445EB0B030A463A +:10019000261843EB0201241A63EB0205304604F0F3 +:1001A00001F949084FEA300080B24FF00A06B0FB6F +:1001B000F6F10D9801802046294604F0F3F849082D +:1001C0004FEA300080B2B0FBF6F10E980180BDE836 +:1001D000F09F2DE9FF4FBDB00024CDE93144CDE9BA +:1001E0002F44CDE93744CDE93544CDE93344126895 +:1001F0002E92A346A2466B462EAAFFF70DFC2EA90F +:100200006846FFF7A3FB40989DF8BA10406809F0D4 +:10021000F9FC39909DF8BB009DF8BA503A908DE0FA +:100220009DF8B8409DF8B9003C943B907AE0684650 +:1002300000EBC5002246D0E900670120002109F04B +:1002400024FB06400F403E436AD0399830F9140031 +:10025000002865DD642148434099954AB1F9321080 +:10026000126890FBF1F03A99938E491B491C59434F +:1002700092F83130568E5B1E91FBF3F13C9B92F865 +:100280003020E31A5B1C7343521E93FBF2F3A0FB76 +:10029000032C4FEAE07E0EFB03C6DF17DDE931C811 +:1002A0001BEB000B4AEB0E0A00FB076618EB02087B +:1002B0004CEB060CCDE931C8A2FB03C806FB038357 +:1002C00002FB0733DDE935871CEB070743EB080327 +:1002D000CDE93537A2FB017C06FB01C64FEAE17987 +:1002E00002FB0962DDE93736BE195A41CDE93726EE +:1002F000A0FB01270EFB017600FB0960DDE92F362C +:10030000B6184341CDE92F36A2FB016700FB01700F +:1003100002FB0900DDE9332171185041CDE93301B9 +:100320003B98641CA04282DA61486D1C006890F81A +:100330003010399800EB410039903A98A842BFF646 +:100340006FAFDDE93131DDE92F42A1FB020503FB8F +:10035000025201FB04215A46534609F0BCFADDE97A +:1003600037231B1A409862EB0102C0E91432DDE921 +:100370003112A2FB020301FB023302FB01315A4698 +:10038000534609F0A8FADDE935231B1A409862EBC1 +:100390000102C0E91632DDE92F12A2FB020301FBC4 +:1003A000023302FB01315A46534609F094FADDE963 +:1003B00033231B1A409862EB0102C0E9183241B0A6 +:1003C000BDE8F08F2DE9F04116461F4604460D4664 +:1003D00000F029F8401056EA070107D00022114624 +:1003E000921BB94110DA2C430AD0A0E654EA05006A +:1003F00006D000210846091BA84103DA2D2096E605 +:10040000002094E65A2092E654EA050106D0002224 +:100410001146121BA94104DA5A3088E66FF05900E0 +:1004200085E65A3883E62DE9F0414FF47A74A0FB53 +:10043000045701FB0471002600FB0611284609F051 +:100440004AFA1C4A821A71F1FF3205DB42F6A643D2 +:1004500000221B1A8A4102DABDE8F041F4E50023CC +:10046000154D1A4635F91240E617041B71EB0604C8 +:1004700009DB05EB4204B4F90240E617241A8E4169 +:1004800001DB13464622521C452AEBD303EB8302C1 +:1004900035F9131005EB4303553A401AB3F902300E +:1004A00000EB8000A3EB010190FBF1F010443EE66D +:1004B000A40710005AD3FFFF089C01002DE9FF5F3D +:1004C0000024DDF838908B46984615462746264688 +:1004D00009F0FF01009809F095FB30F91800A842D7 +:1004E0002DDDA9F1010509F1010A24E0002D1FDB32 +:1004F000AD48007885421BDAE9B2009809F082FB2A +:10050000AA4AA8F101018B1C92F800900DE0002985 +:1005100008DB494506DA3BF9142030F911C01644CE +:100520000CFB0277641CE4B2491C9942EFDD01E048 +:10053000E41CE4B26D1C5545D8DD0EB101E0074660 +:10054000012697FBF6F004B000B2BDE8F09F2DE95C +:10055000FF4F83B01446DDE910120F7888784D788C +:10056000CE7832B18046B4F912005FEA000A7DD03D +:1005700095E007B17F1EFFB200B1401EDFF82CB23C +:1005800000F0FF089BF80000411E8D4201DA6D1C4F +:1005900000E00D468448EDB20078411E8E4201DA3B +:1005A000761C00E00E46F6B2CFB94046C14612E0D6 +:1005B0000146039809F034FB82463B46CDF8009093 +:1005C0002146069A0498FFF779FF2AF8170009F1E7 +:1005D0000100C0B28146B145EAD97F1CFFB29BF849 +:1005E0000000401E854219D14046C14612E0014636 +:1005F000039809F015FB82462B46CDF80090214662 +:10060000069A0498FFF75AFF2AF8150009F101002D +:10061000C0B28146B145EAD96D1EEDB2B8F1000015 +:100620001AD10146039809F0FBFA8246B9460DE05B +:100630004B46CDF800802146069A0498FFF73EFF0E +:100640002AF8190009F1010000F0FF09A945EFD9C6 +:1006500008F1010000F0FF0853480078401E864270 +:1006600081D13146039809F0DBFA00E015E08246BB +:10067000B9460CE0034600962146069A0498FFF717 +:100680001DFF2AF8190009F1010000F0FF09484692 +:10069000A945EFD9761EF6B265E74FF0010A40464C +:1006A000C14664E00146039809F0BAFA0190A9F145 +:1006B0000100C1B2049809F0A5FA009049460498D7 +:1006C00009F0A0FA834638464BE03BF91010069A31 +:1006D000914241DD0099B4F900C001EB40010022D4 +:1006E00031F9023DB4F9068003FB0C22B1F9023066 +:1006F000B4F902C003FB0C22B1F90430B4F904C010 +:1007000003FB0C23294A127801EB4201B1F900C026 +:100710000CFB0833B1F902C0B4F908800CFB0833B4 +:10072000B1F904C0B4F90A8001EB42010CFB0833B3 +:10073000B1F90020B4F90CC002FB0C32B1F902305F +:10074000B4F90EC0B1F9041003FB0C22B4F9103057 +:1007500001FB032191FBFAF1019A22F81010401CD1 +:10076000C0B2A842B1D909F10100C0B28146B14579 +:1007700098D907B0BDE8F08F3EB502248DF8084047 +:100780008DF80A400A4C246814F8305FED1E8DF88D +:10079000095064780125E41E8DF80B4002ACCDE9C8 +:1007A0000045FFF7D4FE3EBD2707100028071000C4 +:1007B000A40710002DE9FF4FAFB092464FF46671C9 +:1007C000FE4809F02BF901203EE0B821684609F007 +:1007D00047F9329808F0FF0100EB88006B4600688B +:1007E0002E902EAA3098FFF717F958B32EA9684615 +:1007F000FFF7ACF89DF8BA5020E0E9B2EF4809F0F5 +:1008000009FA814668469DF8B84000EBC50B10E038 +:10081000DBE9006722460120002109F036F8064096 +:100820000F403E4304D019F80400401C09F80400AE +:10083000641C9DF8B900A042EADA6D1C9DF8BB006B +:10084000A842DADA08F101008046329890F80E11D9 +:100850004145BADA9AF802401EE0E1B2309809F058 +:10086000D9F90646E1B22F9809F0D4F90546E1B26C +:10087000D24809F0CFF902469AF80010CF2006E0DE +:10088000535C012B02D9735C03B96854491C9AF874 +:1008900001308B42F4DA641C9AF80300A042DCDADF +:1008A00033B0BDE8F08F2DE9F0470446914260D0A7 +:1008B00007D901EB0200A0EB0201CAB2A0EB0200D3 +:1008C000C1B201EB810000EBC10004EBC00102EBFF +:1008D000820000EBC20004EBC003B1F93250B3F95F +:1008E00032009946854200DA4886C88CDD8C28445F +:1008F000C884088D1D8D28440885488D5D8D284449 +:10090000488588699D6928448861DD69CE69CF681A +:10091000D9F80C304FEA274C4FEA23480CFB06FC71 +:1009200005FB08CC70199CFBF0FC6CF31F470FFA19 +:1009300087FC0CFB06FC1BB205FB03C393FBF0F327 +:1009400063F30F07CF60C86194F81806411E914207 +:100950000AD000EB800101EBC00004EBC001484667 +:100960006822683909F020F894F81806401E84F8C7 +:100970001806BDE8F08770B500231A46904C914EDA +:1009800016E090F8300002FB0061002008E028B17A +:100990000D1815F8015C6D1C0D5400E00B70401C27 +:1009A000256895F830508542F1DC5B1CDBB2521CA7 +:1009B000206890F831109142E3DC00231A4616E0DB +:1009C00090F83000804902FB00110BE0256895F893 +:1009D00030506D1E854204D00D186D786D1C0D547D +:1009E00000E00B54401EF1D55B1CDBB2521C2068AA +:1009F00090F831109142E3DC70BD2DE9FF4F83B0D8 +:100A00000020DDF8409092468B4689F80000039A5A +:100A10000121521E1FB202926EE00BEB410CBCF999 +:100A2000024001943BF81120A41A26B23CF9024C72 +:100A30000094A41ABCF9048025B2A8EB02043CF986 +:100A400004EC24B2AEEB020212B2012938D0DDF878 +:100A50000CC0ACF1020C614500D10024DDF804C0EB +:100A6000BCF1000F00DC3E46DDF800C0BCF1000F19 +:100A700000DC3D46B8F1000F00DC3C46BEF1000F43 +:100A800000DC3A46002E35DD002D33DD9E4201DDCF +:100A90009D420BDC9C4201DD9D4207DC9E4201DD54 +:100AA0009A4203DC9C4225DD9A4223DD4FF0CF0CB5 +:100AB0000AF801C0DDF84480B8F1010F02D007E068 +:100AC0000022CBE70AEB010888F801C008F801CC46 +:100AD00099F800C0B0420CF1010C89F800C000DAAE +:100AE0003046A84200DA2846A04200DA204690426A +:100AF00000DA1046029A491C91428EDB07B0D0E61C +:100B000010B54C21314808F089FF30482A214C307B +:100B100008F084FF2D487621763008F07FFF2B48BF +:100B20007621EC3008F07AFF2621294808F076FF7C +:100B300027481521153808F071FF25483B2126303C +:100B400008F06CFF22483B21BDE81040613008F0FE +:100B500065BF2DE9F04F8E468278DDF824C047E06E +:100B600002FB03F10EEB4104164902FB031B16497D +:100B700002FB031A017837E034F911502E1E00DA17 +:100B80007542654506DD114D4C3535F812703E4411 +:100B900025F8126034F911700A9DAF4223DDDFF8A9 +:100BA0002C901BF8016009F176091AF8015039F808 +:100BB0001680474429F816700CE00000045010001D +:100BC000A4071000C8491000E64C1000E62B0120D5 +:100BD0005D2D012009F1760634F8118036F8157084 +:100BE000474426F81570491C45788D42C4DA521CDA +:100BF000C1789142B4DA017817E00EEB41058278B2 +:100C0000FE4E0EE002FB03F435F91440271E00DA15 +:100C10007C42644504DD36F811403C4426F811401E +:100C2000521CC4789442EDDA491C42788A42E4DAD4 +:100C300037E62DE9FF4FF248F24F8DB08B46C17970 +:100C4000DDF8688038681C4639B190F8B31005911A +:100C500030F9AD6FB0F9025014E090F885120591AB +:100C6000B0F98662B0F9885290F89C0250B1FBF757 +:100C700026FE396891F89C22904203D8B1F9986217 +:100C8000B1F99A520027DFF88093039704970297EF +:100C9000B2B2DA4999F8000000F07EFA0DF1080AC4 +:100CA000CDE900A783B2D94AD44999F80000FFF7EB +:100CB000A4FEB2B2D64ED149ADF80C004C3130781A +:100CC00000F06AFA0DF10901CDE90017CF4A83B2AD +:100CD000153AA2F58B713078FFF78FFEC749ADF852 +:100CE0000E00AAB276313B2000F056FA01260DF133 +:100CF0000A01C64ACDE9001683B22632A2F22711B4 +:100D00003B20FFF77AFEC149ADF81000AAB28B393B +:100D10003B2000F041FA0DF10B01BC4ACDE9001671 +:100D200083B26132A2F1EC013B20FFF766FE0025A1 +:100D3000ADF812002946284603AE53461A5CAA4273 +:100D400002D9154601460AE008D345B136F911200B +:100D500036F910C0624501DA5F5400E01F54401CB0 +:100D6000C0B20428EAD3A0780090E0780C90D8F8BC +:100D70000800009908F046FF81465846009908F09F +:100D80003BFF824600990D9808F044FF06460598FF +:100D9000E8B30F990B9101A90A9106A90991584648 +:100DA000A17808F029FF0746A178D8F8080008F0D4 +:100DB00029FF844694F802B0E0780890924847F6FC +:100DC000FF73DA430078079019E0207894F801E087 +:100DD0000DE017F800800B99884507D13CF91010F9 +:100DE000994200DA0B46914200DD0A46401C8645D6 +:100DF000EFD207980BF1010B0CEB400C2837089849 +:100E00005845E2D20A9803800998028000E00EE07B +:100E1000BDF91800BDF90410411A0598414364203A +:100E200091FBF0F07B490988084407B202E0794859 +:100E3000B0F90070009A44E0217837E01AF80130E8 +:100E40000F98834231D1704BDFF8D0C11B788C44AE +:100E500002FB03F0704B0B44C35C10F80C009DF8D0 +:100E600008C0AC4502D16948405C16E09DF809C055 +:100E7000AC4503D165481538805C0EE09DF80AC08A +:100E8000AC4503D161482630C05C06E09DF80B30CC +:100E9000AB4204D15D4B6133185CCF2805D039F9E2 +:100EA0001100B84201DD01207054491C607888426D +:100EB000C4D25549521C0AF1280A0978283609EB90 +:100EC00041090C988242B7D911B0EAE42DE9FF4FED +:100ED00053488BB000270668524D781E09901C4677 +:100EE00006F5887801220D992868FEF7CAFDDFF81B +:100EF00014B1DBF8000090F88102000606D50BA8BB +:100F0000009490E80E002868FFF793FE46483B46A1 +:100F1000007848B194F8240010F0060F04D1204660 +:100F20000D99FEF723FE0346002086F80E010D986A +:100F30000022314600683060AA462868FEF787FE26 +:100F400096F80E0101280CD9DBF8000090F8800219 +:100F5000C00706D0DAF8001033460D9A0846FFF7AE +:100F600029FC96F80E01002701287DD9FBF7A3FC88 +:100F70000890FBF79CFC81460B980290DDE90C5031 +:100F80002A4B0068019001AA29460298FEF744FD09 +:100F900070B101A92548FEF7D9FC0095224601A9A8 +:100FA0002248029BFDF75EF9E1686161E169216217 +:100FB00001258BE068222146404608F0F5FC1149E6 +:100FC00006EB45000968B0F8B42091F88C128A420B +:100FD0007BD90121099AA940114276D0B8F8241092 +:100FE000234641F01002A8F82420B0F8B410A8F865 +:100FF0002610DDE90C12DAF8000019E0E62B0120DA +:10100000945A1000A4071000280710005D2D01203D +:1010100027071000DA061000C8491000E64C10003F +:10102000AC06100090061000EC061000704710008F +:10103000FFF7CFF8D4E91801CDE9000104F1500120 +:101040000FC9FFF73CF8A08500208DF81400ADF81B +:101050001800ADF81C0002AB07AA06A905A883E892 +:101060000700D4E9180100E05DE0CDE9000104F1DA +:1010700050010FC9FFF75DF8BDF81800E085BDF815 +:101080001C1021869DF8141084F849104B4906EB7A +:101090008502934621F8800F208E488094F84900FD +:1010A0004346C0F1FF000871E9B2DAF80000FEF72C +:1010B00016FD012000905A46E9B24346DAF80000D6 +:1010C000FDF7DFF908B17F1CFFB26D1C96F80E0129 +:1010D000A842BFF46FAF3A48026892F88002000657 +:1010E0001DD5394619E0089892F8C0520844C0B29C +:1010F00000EB800303EBC00309EBC300C38CAB42DE +:1011000009D890F8373090F83600181A92F8C132A2 +:10111000401C984201DD089813E0491EE3D2012FDC +:101120000BD0002F07D101200BAD009095E80700F0 +:101130002346FDF7A6F90FB07AE599F8180600B135 +:10114000401E89F81806EEE738B51468C3F83A402F +:101150001C4C25781A4C012D246803D094F8805239 +:101160006D0714D594F880526D0609D5164D6D782B +:1011700055B1B4F89042154D64432D68A54206DC84 +:1011800001B0BDE83040A1E6B4F88E42F3E7012497 +:101190000094FDF776F938BD30B50024234605E00C +:1011A00031F91350A54200DD2C465B1C8342F7DB6E +:1011B0005443642094FBF0F000B230BD405701204E +:1011C000A407100018051000DC0710006C071000C1 +:1011D00070472DE9F05F824665484FF0000BDFF85D +:1011E00094E103786448026835E06448644C10F880 +:1011F00013002478401CC5B203FB04F00AEB400640 +:1012000001EB400C06F10209601B0CF1020C20E01E +:101210009EF8008039F910703CF91060B2F8465021 +:10122000B2F84840B8F1010F06D0DFF8588198F8BD +:101230000080B8F1010F03D1B2F86350B2F86540F5 +:101240003544BD4202DB341BBC4202DD4FF0010BD2 +:1012500001E0401EDCD25B1EC7D2BBF1000F15D1EE +:1012600092F8440000F00F024748C2F11005B0F9AF +:10127000000009E031F910303AF91040534304FB03 +:1012800005331B1121F81030401EF3D23A48006894 +:1012900090F80102000609D59EF80000012805D14A +:1012A0005046BDE8F05F0022F4F750BCBDE8F09F67 +:1012B000F0B501271446DDF814C00BE031F91450E5 +:1012C00030F9146005EB030EB6451BDBA5EB0C05EE +:1012D000B54217DC641EF1D1002F13D0264B1B68DA +:1012E00093F845301B09C3F1100609E031F912509B +:1012F00030F912405D4304FB0654241121F81240DA +:10130000521EF3D2F0BD38B50D46044601F0C3F9C4 +:1013100000282CD1E80708D01C4801681C48007838 +:10132000012802D12068FFF754FFE8061FD51948AD +:10133000114D007858B12868B0F9501000910C494F +:10134000B0F94E3020690A781349FFF7B1FF13480E +:10135000007800280BD02868B0F954100091084993 +:10136000B0F9523060690A780D49FFF7A1FF38BD26 +:101370002707100029051000A407100038260120B7 +:1013800028071000180510003C0710005C0710002B +:101390002D071000260710000477012025071000F4 +:1013A0002E7701202DE9F0478E488946089F017865 +:1013B0008D489246006811B1B0F9692214E03FB13E +:1013C0008A49B0F97122097871B1B0F96F220BE046 +:1013D0008749B0F973224978022902D3B0F97722FC +:1013E00002E009B1B0F975228248012690F800C0E8 +:1013F00023E057B103FB0CF00AEB400409EB400576 +:10140000A41CAD1CACEB060015E07B4810F81300E3 +:10141000401CC6B2EEE735F9101034F91080B1EB7C +:10142000080100D5494209B2914204DD73480180A8 +:101430000020BDE8F087401EEDD25B1ED9D201200E +:10144000F7E7694810B5006890F86612890727D554 +:101450006B4A1178491CC9B2117090F868328B42FE +:101460001ED20021117090F800120324C90703D185 +:1014700090F8BA00C00700D00B24EEF7BFFF614818 +:10148000016821430160EEF7B7FF1021052002F04B +:10149000DAFBBDE810404FF48071002006F02DBA51 +:1014A00010BD2DE9FF4F5848002681B090F800800C +:1014B000564891468A4600783546B34618B1544896 +:1014C0000078012822D04848006890F86602C007DA +:1014D0001CD00024019F16E0DDF810C00E9B009385 +:1014E000E0B2394652466346FFF75CFF10F0010F49 +:1014F00005D00120A04030436D1CC6B2EDB2641C83 +:1015000007EB490724B24445E6DB01E04546FF26E8 +:101510004048067045B11FFA89F2334641460095AE +:10152000019800F020F807E03448B0F900100320DB +:1015300002F089FB4FF0010B2B48006890F866021F +:10154000C00608D534484FEA49020168019800F600 +:10155000784008F0E4F905B05846BDE8F08F284916 +:101560000020087070472DE9F003DDF818C0BCF1C9 +:10157000000F1AD00126BCF1010F02D01746B14668 +:101580002CE000240FE006FA04F51D420AD0002CDE +:101590000BD053006243BDE8F00300EB42011A4652 +:1015A00008F0BDB9641C8C42EDDBBDE8F003704768 +:1015B000002600EB470534460AE009FA04F818EA69 +:1015C000030F02D0B5F90080464405EB4205641CC8 +:1015D0008C42F2DB96FBFCF420F817407F1EE7D22A +:1015E000E3E7000029051000A4071000B70610006B +:1015F000DC0710002807100038260120C006100064 +:10160000B0061000B00710002A071000945A10000E +:1016100018051000B50610005007100010B5F4F7BB +:1016200083FABDE81040F3F7BFBB2DE9FF4F83B04D +:10163000002481469A46934626468DF804400220AF +:1016400006F0FBF95A4648460499F5F7FAFCF949C1 +:10165000F94FDFF8E883CA7809F6784560F30302AA +:10166000CA70062806D0012819D002281ED00328E7 +:101670001CD02CE0022006F0FBF9B7F90000294647 +:101680004200D8F8000008F04AF9F3F780FB022185 +:10169000012006F032F9002007B0BDE8F08FE848DD +:1016A0000670FDF708FCFBF767F811E0FDF7D9F9C4 +:1016B000FBF712F990B3B7F9000029464200D8F8B9 +:1016C000000008F02CF9FF21032002F0BCFA0124ED +:1016D00001A8009053465A4648460499FCF753FB2C +:1016E00040EA0405022006F0C3F99DF8040098B111 +:1016F000EEF784FED349D4480A68006802430A60C2 +:10170000EEF77AFED1480178052002F09CFA4FF4FA +:101710008071002006F0F1F82846BDE7FFE7FAF7F0 +:10172000D1FFD5E72DE9F34F83B00221684600F0E1 +:1017300039FA00218FE0C64F049B387801FB00F294 +:1017400003EB420505EB400404EB400303EB4002CE +:1017500002EB400B0BEB400A0AEB400909EB40009F +:101760000190002071E03BF810C03AF8107039F891 +:101770001080BC44019F01FB060637F810704744F7 +:101780000CEB070E35F8107034F810C0DDF800804F +:10179000A7EB0C0733F810C0A7EB0C0C0CEB0E07F3 +:1017A00032F810C0674428F8167034F8106035F825 +:1017B0001070DFF89CC2F61B33F810709CF800C064 +:1017C0003E4432F81070F61B06EB0E074E1C06FB6B +:1017D0000C06DFF87CC228F816703BF810703AF857 +:1017E00010609CF800C0BF1B39F810603744019EA0 +:1017F00036F81060A7EB060E35F8106034F810705C +:101800003E4433F81070F61B32F81070F71B8E1C34 +:1018100006FB0C06774428F8167035F8106034F88B +:101820001070DFF82CC23E4433F810709CF800C0F2 +:10183000BF1B07EB0E0632F810703744CE1C06FBB8 +:101840000C06401C28F8167080B2814E3678B042E3 +:1018500089D3091D89B27F4800788142FFF46BAFBC +:101860007C487B49007809784843420000990398F6 +:1018700008F055F80221684600F0F2F905B00CE7CF +:101880002DE9FF4F83B00B00DDE912124FF0000687 +:10189000DFF8C4B1DFF8C4A1DFF8C481714F4FF0A5 +:1018A000010935461AD0184600F0C2FC6E490646BA +:1018B0009AF800000978884210D0FBF705F868B95B +:1018C0006A48007850B9DBF80000B0F89211B8F817 +:1018D0000800814202D287F80B9000E0FD720320DD +:1018E00006F0ABF86248007888B16248CDF8009005 +:1018F000624903786048B0F900200398FFF7D1FDF2 +:10190000040010D103990846FFF70CFF0BE0514883 +:10191000009503784848B0F90020594801680398B9 +:10192000FFF7BFFD0446032006F0A2F834B1FFF72D +:1019300088FD88F80040012E27D027E0FFF70FFE32 +:101940009AF8010008B1012100E0002188F8031095 +:101950000199884202D008B9A8F80650DBF80010B7 +:1019600091F8E612C90708D04649097829B987F8DD +:10197000039010B14448FD700570DDE90512119B1C +:101980000398FFF752FE0446D3E70124204683E67E +:1019900010B500F037F8002010BD10B5F5F70BFDBD +:1019A000FDF792FAFAF76CFEFFF738FEFFF7D7FD66 +:1019B000FCF7BCFA2A490020087048708880C8806B +:1019C00048810881888188700861486188611C317C +:1019D000087088702048006810F8302F4A704078EE +:1019E000C87010BD10B5F5F7F5FCFDF77EFAFAF7F3 +:1019F00045FE00F064FCF4F7A4F81848002141709B +:101A0000017110BD1CB5044600208DF804000220B1 +:101A100006F013F82046F5F751FC06490628CA7867 +:101A200060F30302CA7031D001283CD002283FD0B5 +:101A300042E00000405701203C0710005007100012 +:101A4000E6071000B0071000700610006C061000CA +:101A50002807100027071000A4071000DC0710005B +:101A6000B4061000945A1000370710003407100015 +:101A700038071000390710003E071000C870012019 +:101A80005C0710007807100032071000022005F0F4 +:101A9000EFFFF3F77CF90120F3F7CAF802210120E8 +:101AA00005F02BFF08E0FDF70EFAFAF737FE03E02A +:101AB000FDF76AF9FAF745FE01A8002300901A46DF +:101AC00019462046FCF75FF90446022005F0D0FFD6 +:101AD0009DF8040098B1EEF791FC0A490A480A689B +:101AE000006802430A60EEF787FC08480178052089 +:101AF00002F0A9F84FF48071002005F0FEFE2046A8 +:101B00001CBD0000B0071000700610006C0610002D +:101B1000062904D28B4A525C8B498B5C2BB1002185 +:101B200001600146482001F06EBD864B083353F832 +:101B300022300360854B43F822000120885470470F +:101B40000A4630B40021062A11D27E4B9A5C72B14B +:101B50007C4C0368083454F82240A34207D17A4BE6 +:101B600099547A4B43F82210016030BC70470160F1 +:101B7000014630BC492001F046BD2DE9F041012469 +:101B8000714F724E0025385D38B13D5556F824101E +:101B90004A2001F038FD46F82450641C032CF2DB87 +:101BA000BDE8F0812DE9F041684E674C4FF0000C24 +:101BB0000C36C0F800C0636806F1140704F108058C +:101BC00001291DD0022902D0032938D128E00022A2 +:101BD000A918B1F800E0BEF1000F07D0521C042A8A +:101BE000F6DB022B28D301464C202AE056F822507F +:101BF000056047F8220040F2022008809B1E2DE07D +:101C0000052101E06A5C12B1491EFBD214E056F8CE +:101C10002120026047F82100012068545B1E1DE06E +:101C20000022A918D1F800E0BEF1000F0DD0521C1F +:101C3000022AF6DB042BD6D2BCF1000FB0D101464C +:101C40004B20BDE8F04101F0DEBC56F822500560A3 +:101C500047F822004FF003301B1F086063609FE7C6 +:101C6000F0B40C4639490026374D731E05220C315D +:101C700008350AE051F82270D0F800C0674504D159 +:101C8000AF5CA74201D1134601E0521EF2D2591CAB +:101C900016D02E4A00212032016042F82310E95468 +:101CA000012C06D0022C02D0032C0BD103E0E81843 +:101CB0004170F0BC7047E81841708170C170F8E75E +:101CC000002EF6D1F0BC01464D2001F09CBC70B551 +:101CD0001D4D1E4E0524083520360BE0285D48B109 +:101CE00056F824104E2001F08EFC295D56F8240091 +:101CF000FFF7B6FF641EF1D270BD70B50120134A24 +:101D0000114B002142F820101954401C0328F9DB24 +:101D10000120187005200C4A0C4C0D4B0C3402F1BC +:101D2000080504F11406506008E07322424303EBF7 +:101D3000C20244F82020295446F82010401EF4D254 +:101D400070BD0000689C0100F0061000605A100091 +:101D50001C7210002DE9F043FF4B894600211B78CF +:101D6000012B00D10121FD4B00271E781CE0B31E82 +:101D7000994218D050F82130002593FBF2FC09EB72 +:101D80004108144608E004FB06F338F91330B3EBBE +:101D90000C0300D55B421D44641EF4D295FBF2F3A4 +:101DA000BB4200DD1F46491CB142E0DBB7F5803F76 +:101DB00003DB4FF6FF70BDE8F083B8B2FBE7E848FD +:101DC000E84900680A7800F27710805C4871704733 +:101DD0002DE9F14FDFF888B3DFF888E3DFF888A357 +:101DE000DBF800109EF800C0002591F88F0191F8F3 +:101DF0008E113AF81C606FF000444FEA11180A0780 +:101E00001ED001F00F01D64B002291461B6886427E +:101E100093F88D7105DB301A00FB08F090FBF1F0B0 +:101E20000744CF489EF80110F0460068012990F859 +:101E3000750107D0022908D000F00303484611E0DD +:101E40000121E0E7C0F38103F8E7C0F30113F5E7F0 +:101E50003AF810108C4201DD0C4605468A4200DA41 +:101E60000A46401C9842F3DD00980280DBF800002F +:101E700090F8BC0AC10604D5C0F341108EF80000EA +:101E800006E0301BB84201DC9C4504DD8EF80050B2 +:101E9000BDE8F84F93E7BDE8F88F2DE9FF4FB04953 +:101EA0009A46DDE90D3609684FF0000E934691F829 +:101EB00097417246F146E4071FD0012B1DD1AB4D6F +:101EC00000273C462D783B46AD1C09E016F803C0C0 +:101ED00091F89881C44501D9641CE4B25B1CDBB263 +:101EE000AB42F3D391F89931A34200D20127A04B22 +:101EF00083F863400FB14FF001099A4C91F8767165 +:101F0000A6787B0705D506B901989A4B1B7803B1D3 +:101F10005046994B1B78012B02D1984B1B784BB143 +:101F2000B1F8813183421AD291F874311B0716D56A +:101F300003222DE0B1F88731834203D291F8743146 +:101F40001B07F5D4B1F88531834203D291F874317F +:101F50005B070CD4B1F88331834214D318E0B1F895 +:101F60007F31834205D291F874315B0701D502229B +:101F70000EE0B1F87D31834205D3B1F89051AAEB60 +:101F80000B03AB4204DD91F874319B0700D50122AD +:101F9000754D183D2B789A420CD19E4216D0784A46 +:101FA0001278012AAA6801D1521EAA60002A0DDC0B +:101FB000A3700BE0AAB1022A01D1012B11D091F834 +:101FC0007B31AB602A70002B00DCA2703A0724D56D +:101FD000B1F87F315B450AD2B9F1000F07D0022278 +:101FE00006E091F87C3103EB83035B00E9E7002214 +:101FF0006B789A4209D1E17899420ED0E968491E7E +:10200000E960002909DCE37007E052B191F895110D +:10201000E9606A70002900DCE270E17839B1617032 +:1020200007E091F8961101EB81014900F0E7A278F1 +:102030006270544A1388834200D210804C4810F8D2 +:10204000592F61F30302A17861F3071200F8012907 +:102050006278017862F30301017004B07046BDE854 +:10206000F08F3F4A126892F87421D20607D5421ABF +:10207000002A04DCC1EBC1110844C0F3CF10704743 +:10208000384910B5002048708870C8703649344A05 +:1020900018394860886008704870126892F83432C5 +:1020A000DB0703D092F83F22120900E00022364BF2 +:1020B0001A60086148618861C8614FF498513348DB +:1020C00007F0ACFCBDE810404FF41871304807F041 +:1020D000C7BC2DE9F74F0746002084B01F49ADF873 +:1020E0000800DFF884A091F8008010214FF6FF76F9 +:1020F00005464FEA08190446AAF1080B009115E0BD +:10210000234904FB08F001EB800043463946009A5E +:10211000FFF720FE2BF8140053463AF81410FFF78F +:10212000A0FF23F8140007EB4907641C0E48183879 +:1021300080788442E4DD02A8FFF74AFEDFF82480BD +:102140005F4698F800003AF810403BF8101011482C +:102150000480034800681FE02D07100028071000C6 +:10216000A4071000DC071000180710002707100054 +:1021700040570120B706100030071000310710004B +:102180002F071000BA061000E4061000FC2D0120F5 +:10219000FC400120B806100090F8750100F0030320 +:1021A000C0F30110834200D80346002009E037F84D +:1021B0001020B24200D21646AA4200D91546401C51 +:1021C00040B29842F3DD64482B460580DDE9050204 +:1021D000CDE9000232462046FFF75FFE0546204665 +:1021E00000F088F898F8000037F810105B4820F8E5 +:1021F0001A1F8687BAF800200286BAF802204286A3 +:10220000BAF804208286BAF80610C186284607B0BC +:1022100025E730B509E031F9134032F91350641B5A +:1022200050F823502C4440F823405B1EF3D230BDBD +:102230002DE9F74F82B0002100914949494A102702 +:102240000C785168064691FBF7F307FB13114648DB +:10225000614395784FEA041B00EB410800F598595B +:102260004FEA440A6D1C10E0234642463146484678 +:10227000FFF7CFFF52463146404607F050FB06EBD2 +:10228000440608EB4B0809EB84096D1EECD2354976 +:102290004FF0FF3202EB47024868401C4860824220 +:1022A00000DA4F604868B84202DA009805B0D6E616 +:1022B000DDE903122C48FFF70CFF0090F6E710B59C +:1022C0002A4C206890F87501C0F30112C0F3810117 +:1022D00000F0030002F0A3F8224988702068244926 +:1022E00090F8D20000F003000870FFF768FDBDE829 +:1022F0001040C5E630B51D491E4D096891F83422DD +:10230000D20725D01A4A52784AB191F83F2202F0FA +:102310000F031409B1F83A22B1F83C1208E091F821 +:102320003E2202F00F031409B1F83622B1F8381238 +:10233000904201DC2B6030BD884201DB2C6030BD57 +:10234000801AE41A6043891A90FBF1F0184400E007 +:102350000020286030BD0000BC061000405701205E +:102360002807100000071000FC2D0120A407100012 +:10237000DC071000E406100070B5FC4DFC4C296829 +:1023800091F83100E07091F83010217100FB01F2FA +:102390002283401EC21700EB927020F00300083029 +:1023A000C0B2607548436083F24840796071012093 +:1023B000A071E071207220700020A0836072A07272 +:1023C0006074A074FFF7E9FA286890F8700C00F0C8 +:1023D0000100A075FEF7FCFEBDE87040F6F786B977 +:1023E00070B5E34D00240D21E3482C6207F016FB85 +:1023F000AC626C62FFF7F6FAFFF77FFCDF480480FF +:10240000BDE87040B8E7F0B5DD49D948DF4F91F835 +:102410003020C27091F8313003715A4314B20483F2 +:1024200091F83320427191F82C20027091F82D30F0 +:10243000837191F82E30C37191F82F30037291F8A7 +:102440003530437291F836308372CE4BC362CA4B3B +:102450000E330363CC4B4363C44B1D6895F8BD3A00 +:10246000DE070B4693F83E3008D0052A06D0062A30 +:1024700004D05C4307EB4404846300E087630C688A +:10248000C34EC4634FF400443480C24E641E348093 +:102490000024C14E0464062A3480C37491F83D3090 +:1024A000837091F83C30437091F83F30037591F898 +:1024B000403043750BD191F84100012807D1B7494D +:1024C00095F8780008700A2801D20A200870F0BD3B +:1024D000AB4810B590F82C10A8488170B049C2786C +:1024E000097861F30712A249C2700279CB7A63F3CB +:1024F00000024B7B63F3C3020B7B63F382028B7B93 +:1025000063F341029C4B1C7B037B64F34103A54CAA +:10251000247864F382030373964B5B7980F8493027 +:102520000B7CC371CB7B63F3041202714B7C427B47 +:10253000897C63F3030261F307129B4942730978B4 +:1025400080F8271099490988018599490A78817B83 +:1025500062F30301817397490A78C17B62F300013A +:10256000954A127862F3410121F00401C173934945 +:10257000097880F87F1092490A7890F87D1062F30C +:10258000410180F87D1010BD70B50C4680EA04064C +:10259000F00601D5F3F7C8FA774DC4F300102870A0 +:1025A000B00601D5F2F700FC754BC4F3401068701B +:1025B00093F82C000022042811D002280FD0EA70D2 +:1025C0002A71C4F30021297302280CD005280AD0EF +:1025D0006A7204280CD006280AD0AA7270BDC4F30F +:1025E0004001E970EDE7596A01B101216972F0E734 +:1025F000586A00B10120A87270BD2DE9F0415C4D10 +:102600005F4EA86A316A80EA010418B911B1FFF778 +:10261000E7FE0FE0E00709D06A4F387820B107F0F5 +:10262000C5FA08B900203870FFF7B7F9E00601D500 +:10263000FEF7F4FFF169286AFFF7A6FFF069286248 +:10264000306AA862706A6862BDE8F041DBE670B586 +:102650005D4D2C68002C0DD04549A0B28A7A497A8C +:1026600001F034F92868A043286003D1BDE8704028 +:1026700001F08CB970BD3E48017B427B1143827BE7 +:10268000007C1143014351480078014301D00120EF +:102690007047002070473648017B427B1143827BA4 +:1026A000007C1143014301D0012070470020704796 +:1026B0002F48007C704708B5FFF792FE6B4600225A +:1026C0000B21022005F062F90098C00705D0012116 +:1026D000022005F03EF900F011F80098800705D5BA +:1026E0000221084605F035F900F072F8009800075D +:1026F000E4D50821022005F02CF9DFE77FB500249E +:1027000000F070FF012005F098F9FFF776FF184DF3 +:1027100095F82800C0070ED01948C16890F83730E6 +:10272000846B82698DE81E00D0E904234168E86B60 +:10273000FFF7A6F80446686A50B14CB9032005F0CB +:102740007CF90F48696AFEF7DEFD032005F090F979 +:10275000FFF7BEFEFFF77BFFFFF7B9FAFFF70DFAB1 +:1027600004B00120BDE8704005F082B9A407100054 +:1027700024071000DC071000945A10004057012075 +:1027800014841000984901205C430120D85701208F +:1027900072051000740510002E0510009905100038 +:1027A000E4061000B0051000B5061000C0061000C9 +:1027B00018051000140510002905100078071000F6 +:1027C000EC061000FA041000CC071000B60610004A +:1027D00070B5002400F006FF012005F02EF9FFF788 +:1027E0000CFF124D95F82800C00704D0104800686F +:1027F000FFF7CEF80446686A50B14CB9032005F0E3 +:102800001CF90B48696AFEF77EFD032005F030F9DC +:10281000FFF75EFEFFF71BFFFFF759FAFFF7ADF971 +:10282000BDE87040012005F023B900002407100026 +:10283000148410000D4D00200D4C28602868401CA9 +:102840002860EDF7DBFD06F000FF0128206808D0C6 +:1028500040F00400206005F022FEEDF7CDFD30BF12 +:10286000ECE720F004002060F7E700007407100098 +:1028700010ED00E070B5134C25462021114807F0FB +:10288000CDF8104800F0A4FC2B78421E691C1846B5 +:1028900000F034F918B10120216801F0D4F900F0FA +:1028A000B1FC0028E9D170BD38B50C46054605F0ED +:1028B00024F86946284605F05AF8009A2242F8D1D1 +:1028C00038BD0000DE60100000207047034630B4C1 +:1028D0000020002910DD1A78491E0A2A0CD27F4DEB +:1028E0005B1C55F8324005EBC2025268914203D19D +:1028F000A44630BC1846604730BC70470120704782 +:1029000010B5017821B1022906D003290BD106E0C8 +:102910004078F9F78FFD06E04078012101E040782A +:102920000021F9F76CFD012010BD0178012908D1C3 +:102930006B4930F8012F0968A1F8E82C4088A1F80C +:10294000EA0C01207047016842686548CBB2006814 +:10295000A0F8003DC1F30723A0F8023DC1F30743EF +:10296000A0F8043D090EA0F8061DD1B2A0F8081D7C +:10297000C2F30721A0F80A1DC2F30741A0F80C1DFD +:10298000110EA0F80E1D012070471CB501680091C2 +:102990008188ADF8041082799DF8000051498DF8C6 +:1029A0000620E0B34E489DF802300068642B01D940 +:1029B000642302E01BB990F8BB328DF802309DF819 +:1029C0000330232B00D81BB990F8D8338DF803308F +:1029D0009DF804309DF80540A34202D80CB10F2B9E +:1029E00008D990F8773303F00F048DF804401B09E1 +:1029F0008DF80530022A00D822B990F87B0300092F +:102A00008DF8060000980860BDF8040088809DF8E5 +:102A10000600887134490868820708D500E008E09C +:102A200020F00200086008210120FFF73DFF01208F +:102A30001CBD087000201CBD10B52B490278086829 +:102A400012B140F0080001E020F008000860082101 +:102A50000120FFF729FF012010BD214910B50968A9 +:102A600091F8961C49070AD500781F49C2070868E3 +:102A700002D040F4807001E020F4807008600821EA +:102A80000120FFF711FF012010BD70B51749184B49 +:102A9000027809684FF00004CE0111494FF001059A +:102AA000096802D54AB1032201E032B102221A704C +:102AB000407881F84006012070BD1D7081F84046C5 +:102AC000F9E70C4A0078012111700B4A08B1117026 +:102AD00001E0002010700120704700007C9C010084 +:102AE000A407100078071000D4071000A0051000FC +:102AF00089051000B1051000B005100030B40C4677 +:102B000001460020A1F1A003092B03D8FE4850F88C +:102B1000233008E0C0290AD1FB48A1F1C001A0F18F +:102B2000040050F82130204630BC1146184730BC14 +:102B300070470020704770B50E46F44904460025E2 +:102B4000086838B100200860F149086004210120BC +:102B5000FFF7AAFE002E12DD2278711E042A0ED283 +:102B6000E948641C283050F8323000EBC20040685D +:102B7000002804DB814202D12046984705462846BA +:102B800070BD10B500780021820601D5812102E0D8 +:102B9000C00700D00121DE48016004210120FFF7B9 +:102BA00083FE012010BD10B500F0C4FB012010BD54 +:102BB000D84810B5006890F8500CC00701D000F05C +:102BC000B9FB10210120FFF76FFE012010BD10B5E9 +:102BD0000146002409782046102915D005DC49B1AA +:102BE000012909D0022912D10BE011290ED0202988 +:102BF0000DD113E0012412E00224012000F074FA48 +:102C000005E004240220F9E7082400E01024BF496D +:102C100014F0180F0C6004D0102108E020240020CC +:102C2000ECE7BB490A68824204D008600421012015 +:102C3000FFF73AFE012010BD034630B40020002902 +:102C400011DD1A78491E052A0DD2AF4D5B1C48359F +:102C500055F8324005EBC2025268914203D1A446B6 +:102C600030BC1846604762E710B50078AA49C20731 +:102C7000086802D040F0020001E020F00200086085 +:102C800008210120FFF710FE012010BD0120704730 +:102C900010B50178CB07A0490A6802D042F00802BB +:102CA00001E022F008020A600078800702D542F0B5 +:102CB000400001E022F04000086008210120FFF7F9 +:102CC000F3FD012010BD10B5002103780A469C06D3 +:102CD00001D5202100229C0701D541F002015C07AB +:102CE00001D541F004011C0701D541F00801DC06C3 +:102CF00001D541F010015C0601D541F040011B06F1 +:102D000001D541F080014378DC0701D041F48071A6 +:102D10009C0701D541F400715C0701D541F4806145 +:102D20001C0701D541F40061DC0601D541F4805156 +:102D30009C0601D541F400515C0601D541F4804167 +:102D40001B0601D541F400418378DC0701D041F432 +:102D500080319C0701D541F400315C0701D541F475 +:102D600080211B0701D541F40021C078C00701D0A4 +:102D700041F080716948C0E90012012010BD0020B7 +:102D80007047034630B40020002911DD1A78491E2F +:102D90000B2A0DD25C4D5B1C703555F8324005EBAB +:102DA000C2025268914203D1A44630BC1846604723 +:102DB000BDE6014600200978072906D25248C830EE +:102DC00050F82120002108461047704710B505F043 +:102DD00022FB012010BD10B54FF400610020FFF769 +:102DE00063FD012010BD10B54FF480510020FFF7A6 +:102DF0005BFD012010BD10B54FF400010020FFF76E +:102E000053FD012010BD10B54FF080610020FFF789 +:102E10004BFD012010BD10B54FF000610020FFF701 +:102E200043FD012010BD10B50078C00702D000F0AE +:102E300010FA01E000F004FA012010BD10B501887D +:102E400037480024CA07007804D0052802D0062895 +:102E500000D002248A0705D5052801D0062801D113 +:102E600044F00404480701D544F0080494B1EDF798 +:102E7000C5FA2C48016821430160EDF7BDFA022133 +:102E8000052000F0E0FE4FF480710020FFF70CFDFC +:102E9000012010BD002010BD10B500880024C1071E +:102EA00000D00124810701D544F00204410701D577 +:102EB00044F00404000701D544F008046CB1EDF7B8 +:102EC0009DFA1948016821430160EDF795FA022146 +:102ED0000020FFF7E9FC012010BD002010BD0020FC +:102EE000704710B500880024C10700D00124810775 +:102EF00001D544F00204410701D544F00404010760 +:102F000001D544F0080411E0D09C0100D80710005E +:102F1000D0071000A4071000D4071000A00510006F +:102F2000F8041000B0071000B4071000C10601D566 +:102F300044F01004810601D544F02004410601D577 +:102F400044F04004010601D544F08004C10501D5D8 +:102F500044F48074810501D544F40074410501D521 +:102F600044F48064010501D544F40064410401D5B2 +:102F700044F48044010401D544F40044C10401D563 +:102F800044F48054800401D544F400546CB1EDF74E +:102F900035FA5A48016821430160EDF72DFA802186 +:102FA0000020FFF781FC012010BD002010BD10B5EE +:102FB0000078C0070ED0EDF721FA5148016841F0C2 +:102FC00001010160EDF718FA4FF080710020FFF762 +:102FD0006BFC012010BD10B500880024C10700D093 +:102FE0000124800701D544F0020474B1EDF706FA1C +:102FF0004448016821430160EDF7FEF94FF4800178 +:103000000020FFF751FC012010BD002010BD10B5BD +:1030100000780024C10700D00124810701D544F0C5 +:103020000204400701D544F0040474B1EDF7E6F959 +:103030003548016821430160EDF7DEF94FF4806106 +:103040000020FFF731FC012010BD002010BD10B59D +:1030500000780024512841D01CDC172836D00CDC25 +:10306000112833D004DC01282DD0102834D12DE0D4 +:1030700012282BD013282FD128E032282AD004DCA4 +:10308000302827D0312827D124E0332822D05028D7 +:1030900022D123E0732824D00CDC702821D004DC5A +:1030A00052281BD0532817D118E0712819D0722844 +:1030B00012D116E0742814D0752812D0762810D0BA +:1030C000772809D10DE000F016FB01E000F0B2FB1B +:1030D000012401E000F0CEFB204610BD00F0B8FB5B +:1030E000F6E700F093FCF3E7002118B1012801D0C6 +:1030F000022800D10121084670470000C0071000D7 +:10310000C8071000C4071000BC0710001C4908B510 +:1031100000201C4C08601C492060086000F0EBFA9D +:1031200000F080FD6B4600221921032004F02EFCE4 +:103130000098C00705D00121032004F00AFCFFF726 +:1031400099FB009800070BD50821032004F001FC2F +:103150002068082140F0080020600120FFF7A4FB50 +:103160000098C006DED51021032004F0F2FB206891 +:10317000082120F0080020600120FFF795FBD1E72F +:10318000D0071000D4071000D80710001F480021F6 +:10319000017041708170704710B51C4C0346A078D7 +:1031A000102814D20F2900D90F211948227800EBDA +:1031B00002100A4600F8011B194606F0B0FB207801 +:1031C000401C00F00F002070A078401CA07010BDC3 +:1031D00070B50E4C0025A17891B10D49627801EBD4 +:1031E000021111F8015B2A4606F099FB6078401C39 +:1031F00000F00F00607072B6A078401EA07062B63A +:10320000284670BD01488078704700007F07100095 +:10321000FE60100010B54FF486714F4806F020FC98 +:103220004D490120C1F804014C4800214160017062 +:1032300006F04EFC0021BDE81040012005F00ABD5B +:1032400010B572B600204549087006F041FC62B620 +:1032500010BD10B572B60120404908703E48D0F844 +:10326000080108B106F082FC62B610BD10B572B656 +:10327000394B3A4C1946D3F80821D1F80011491CB2 +:10328000202A07D2521C21F02001C3F80821C3F8DC +:1032900000110FE0D3F8042121F02001521CC3F8E3 +:1032A000001122F02001C3F804116168491C61601B +:1032B000D3F80011026803EBC1010A60406848605E +:1032C0002078012805D1D3F80801012801D106F0A2 +:1032D0004DFC62B610BD204BD3F8080100280ED07B +:1032E000D3F8040103EBC000C27922F03F02C2719F +:1032F00093F808315B1E03F03F031A43C271704715 +:1033000010B572B61449D1F8080158B1401EC1F881 +:103310000801D1F8042102F1010222F02002C1F8D3 +:10332000042105D10D480078012801D106F0D0FB19 +:1033300062B610BD10B572B6002007490122C1F86F +:103340000801C1E94002054948600878012801D117 +:1033500006F0BEFB62B610BD1056012084071000B7 +:1033600010B5064C00224FF470432280638004495C +:10337000C0E9001402230372427210BD8C071000D2 +:10338000B99D010070B5914D2878C1281CD168788D +:10339000A5F11004052808D100F0FFF88C48016859 +:1033A00021608188A1808079A07168788949082886 +:1033B0000BD0112808D1086800F54861B0F8E80C76 +:1033C0002080B1F86A00608070BD086890F8001D28 +:1033D000217090F8021D617090F8041DA17090F8A2 +:1033E000061DE17090F8081D217190F80A1D6171A9 +:1033F00090F80C1DA17190F80E0DE07170BD2DE9D3 +:10340000F05FDFF8D481894605464FF0030B4FF09B +:10341000010AA8F1080700263C78072C09D2DFE84A +:1034200004F0043337496A7C8700012D02D0022D55 +:103430001CD081E05FEA09000CD064490978862934 +:103440000ED009F0FF016148FFF7A6FE012103201D +:1034500004F053FA0020022804D0012804D06BE0C5 +:103460000220F8E7032467E0022465E07878012869 +:1034700006D056481021103806F0D0FAFFF782FF28 +:1034800088F800A0012457E0022D43D0002453E027 +:10349000022D11D1514C4D4879682278103806F030 +:1034A0003EFA88F800B02178A8F80410042443E01C +:1034B000002440E0022D02D0012DF9D03CE0FFF7BE +:1034C0000AFF48B1022288F80020A8F8020008206C +:1034D000A8F8040005242FE07878062804D03B489B +:1034E0001038002101604160082188F800B0A8F878 +:1034F0000410062420E0022DB6D17878042809D0E3 +:10350000324849461038484410F8012C2F481038EA +:1035100006F07CFA88F800A00EE0022D05D0B9F183 +:10352000080F9FD1FFF7ECFE9CE7FFF7E9FE01E0F3 +:10353000022D97D103240126387878703C70002E34 +:103540007FF469AF2448BDE8F09F23490022083981 +:103550000A704A70214A521C4A60214901601B4985 +:10356000103981801031C18010210181704710B560 +:10357000044606F0ADFA1548D4E900121038C0E947 +:10358000001216480C3806F0FBFA14480C3805F007 +:1035900055FCBDE8104006F0E9BA0D49087800284E +:1035A00013D148700B48006890F8BB228A7090F8DD +:1035B000D823CA7090F8772313094B7102F00F02D9 +:1035C0000A7190F87B030009887170472C5701201D +:1035D00078071000A4071000980710000C62100074 +:1035E000AF33010070B5044D982128462C8806F0B1 +:1035F00037FA641C2C8070BD4057012033480021ED +:10360000016041607047C0B2012200F01EFBFEE77E +:1036100088460546174680212D4806F021FA2C4C95 +:103620002C4EA760C4E90068286820616868606162 +:10363000A868A061E868E061286920626869606242 +:10364000A869A062E869E062234800682063224814 +:1036500010380068606320480C380068A0631E487A +:1036600008380068E0631C48001D006820641A48A0 +:10367000343800686064184814380068A06404F0A6 +:103680008CFAE667C4E9140539464046FFF7BBFFEC +:1036900010B50446C0B2002200F0D7FA0F48016806 +:1036A000082903DA094A5454491C016010BD012855 +:1036B00006D0022808D100221146132000F0C5BA16 +:1036C000002211461220F9E77047000070EF012038 +:1036D00080EF0120AF0550FA38ED00E0A0071000A0 +:1036E000F648F74A0168914204D1F64902794A70D6 +:1036F000002101607047F0B585B040F26471EF4879 +:1037000006F0AEF9684605F0CBF9EC4C012600272F +:103710006670A780A7710220E07104F064FE20812A +:1037200004F05DFE050204F05AFE45EA10206081B7 +:103730005220208242F247306082E3480068418A8A +:10374000A182018AE182E149B1F8FA2E2283B1F81F +:10375000F82E6283427D227791F8FC1E6177DC4966 +:1037600009684A7CA27790F89A2002F00102E27779 +:10377000019A2262009A6262029AA262DDE9032340 +:1037800042EA0322E26282692263C2696263D14A29 +:103790001268A2630368E363CF4BA36490F83630EA +:1037A0001B0706D5B0F83730A4F85030B0F83930E0 +:1037B00003E0438EA4F85030838EA4F8523090F882 +:1037C000313084F8543090F8300084F85500A26508 +:1037D00091F8320024F85C0F91F821006080A780F6 +:1037E000BE48A084BE48A085BE48E085BE4820866D +:1037F000BE486086BE48A086BE48E086BE48208798 +:10380000BE486087BE48A087BE48E087BE48A4F88F +:103810004000AC49BD48A4F842008888401C88801C +:10382000A52204F85C2C04F85B6C24F85A0C0E708A +:1038300005B0F0BD70B5A34C05460023A0889F4994 +:10384000401C82B2A280284601F0ADFC257070BDFC +:1038500070B5054640F26471984806F001F9994C3C +:103860009649A088401C82B2A280284601F0C8FC7C +:10387000257070BD70B5934C05462078A84204D0E1 +:1038800040F264718D4806F0EBF8A148A5700F2155 +:1038900001608A48894A1030A060982010718A48D7 +:1038A00002F1A805E560016891F8310091F8301047 +:1038B000507100FB01F3917105EB43062661D07155 +:1038C000184405EB40006061117270BD2DE9F041B4 +:1038D00004467C4D1746C00704D098227F49A8684B +:1038E00006F01DF8784EA00711D5306890F8312009 +:1038F00090F830004243A87830282CD031282CD0C2 +:1039000032282CD078495200E86806F008F86007A1 +:103910000ED5306890F83120A878302822D0312890 +:1039200022D0322825D074495200286905F0F7FFCB +:10393000200729D5306890F83020A87830281AD090 +:1039400031281AD032281DD06F496869BDE8F0418E +:10395000520005F0E4BF6249D5E76249D3E76D48FC +:103960000168D0E76249DFE76249002FDCD06A498D +:10397000DAE76249D8E76249E7E76249002FE4D015 +:103980006649E2E76149E0E7BDE8F0814B4A4D490D +:10399000A52010708878507008708888401C888036 +:1039A000508070473EB50C4600218DF800104FF452 +:1039B000832502AB6A4601A900F0D8F89DF80800FB +:1039C00010B1112816D01AE09DF80010B9B1019875 +:1039D000617105EB800304F1100019788A0703D0A8 +:1039E00001F0FC01083100E0091DCAB2194605F0DA +:1039F00096FF3EBD322000222071114603E03020A8 +:103A000000222071114600F020F93EBD70B5054638 +:103A10004FF4C871294806F023F82A4C2749A0889A +:103A2000401CA0802846FFF7BDFF24492570A52033 +:103A300008704D70A088488070BD2DE9F84F884609 +:103A400005460C460E1D00239B220421404600F033 +:103A500041FE90BBA078A8422FD1217800239B2261 +:103A6000304600F037FE6178884279D120788107AE +:103A70000AD0022202EB9005002101E03154401CE3 +:103A8000B0EB850FFAD302E0012101EB9005002491 +:103A9000DFF828B04FF48326A1464FF0330A56F8DA +:103AA000240006EB8407401C3BD000239B2204210A +:103AB000384600F00FFE98B349E051E000000120C5 +:103AC0004B435546E8071000A40710007C770120FF +:103AD000A8071000F0FF01001C010201405701205F +:103AE0009C8B01205C43012098490120D85701207C +:103AF00000890120700B01205C0C0120047701205B +:103B00002A8901209A0B0120860C01202E770120A2 +:103B1000CC0710005C071000060A0120300A0120C3 +:103B200001E000940CE03878810704EB900401D0A8 +:103B3000A41C00E0641C602CB1D3B9F1000F06D0C6 +:103B400029464046009A04F082FD00280CD000224D +:103B50008BF804A011463320BDE8F84F00F075B88B +:103B6000002211463120F7E7BDE8F88F2DE9FF5F0D +:103B70004FF0000BC1F800B01F46924688464FF444 +:103B80008325D9465C4683F800B055F8240005EB40 +:103B90008406401C22D000239B220421304600F0E2 +:103BA00099FD20B1122038704FF0010B1CE0B27863 +:103BB000009930788A4208D19AF800104FF0010934 +:103BC000491C8AF80010C8F80040810704EB9004F3 +:103BD00001D0A41C00E0641C602CD6D3BBF1000F04 +:103BE00002D1B9F1010F0BD05BEA090006D1112017 +:103BF000387000208AF80000C8F80000BDE8FF9F78 +:103C0000D8F80000002305EB8004201D21789B22BA +:103C100000F060FD6178884201D1002000E01220B0 +:103C20003870EBE700F018B800F020B81CB5044677 +:103C3000012301AA6946183000F094FF204600993C +:103C400000F032F81CBD00F08FB800F0BDB800F0F5 +:103C5000CDB800F0D4B800001CB57448D0E900100D +:103C6000CDE900106846FFF701FB1CBD1CB56F498C +:103C7000D1E90221CDE9002130F8481F090A8DF869 +:103C8000021001788DF803104188090A8DF804109C +:103C900081788DF805100079C0F1FF008DF80600DD +:103CA0006846FFF7E3FA1CBD1CB5604AD2E904324E +:103CB000CDE9003290F8C621032A1CD0082A20D072 +:103CC0000B2A1ED09DF8002022F0F00220328DF841 +:103CD000002090F8C72102F00F02012A17D0022A13 +:103CE0001BD0042A38D0052A9DF8012022F00F02AB +:103CF00038D0521C16E09DF8002022F0F00210325D +:103D0000E5E79DF8002022F0F0023032DFE79DF871 +:103D1000012022F00F02921C04E09DF8012022F005 +:103D20000F02D21C8DF8012090F80E02D2B260F37F +:103D300007128DF80120BDF802000A0C62F30B0097 +:103D4000ADF80200BDF8030061F30F10ADF80300F9 +:103D50006846FFF78BFA1CBD9DF8012022F00F0288 +:103D6000121DDFE7521DDDE71CB5314A0023126842 +:103D700092F89A2094070ED50B2816D2DFE800F0AF +:103D800015061708170C171715171700120600E06D +:103D9000D206002A0BDB1CBD520608D5254A127834 +:103DA000052AF8D0062AF6D001E0002BF3D01F4AEE +:103DB000D2E90832CDE900328DF80100CDF80210C9 +:103DC0006846FFF753FA1CBD1CB5184BD3E90A43EC +:103DD000CDE900438DF80100CDF80210684612B11C +:103DE000FFF7C5FB1CBDFFF741FA1CBD1CB5016800 +:103DF0000091406801906846FFF738FA1CBD1CB579 +:103E00004178002910D005290ED20849D1E90E21A8 +:103E1000CDE90021D0F80210CDF80210C088ADF82D +:103E200006006846FFF722FA1CBD0000C49D010091 +:103E3000A4071000F80410002DE9FF4103F0A8FCCE +:103E4000224D0024C4EBC40105EB810000F10C02FB +:103E5000037EC4CA03938DE8C400D0E9012355F85A +:103E60002100002103F03EFE18B121464320FFF758 +:103E7000CAFB641C052CE5DB144D00248C3505EBD6 +:103E8000C4000021426855F8340003F0B2FD18B1B7 +:103E900021464420FFF7B7FB641C062CEFDB0B4DDB +:103EA0000024BC35002155F8240003F008FD18B1AA +:103EB00021464520FFF7A7FB641C042CF2DBBDE87C +:103EC000FF8101464620FFF79EBB0000049E0100D3 +:103ED00000F01F0301229A4043099B0003F1E023F5 +:103EE000C3F880224907090E002806DA00F00F0007 +:103EF00000F1E02080F8141D03E000F1E02080F8DC +:103F00000014C3F8002170472DE9F047DFF80CA436 +:103F100064240727DAF800000026DFF8FC8390F815 +:103F2000CC004FEA5009FE4804F05AFDFC48FD4D14 +:103F30000368D91C27D04268D11C24D0816811F1B4 +:103F4000030F20D0006910F1030F1CD0B3F1FF3F25 +:103F500020D013F1020F1DD0B2F1FF3F1AD012F1A1 +:103F6000020F17D0B1F1FF3F14D011F1020F11D0A1 +:103F7000B0F1FF3F0ED010F1020F0BD0DCB2D7B280 +:103F8000CEB2804617E02868807F5A280ED00021E4 +:103F9000242005E02868807F5A2807D000212520AA +:103FA000FFF776FB2868807F5A2804D12868072607 +:103FB000C47F90F82070DAF8000090F8CC00C007B9 +:103FC00002D004EB0900C4B232463946204604F060 +:103FD0002FFA404604F039FAD34804F0C0FCD24C22 +:103FE000032807D001280DD002280BD02168012911 +:103FF00012D014E0286890F821005A2814D000212B +:10400000292006E0286890F821005A280CD00021C9 +:104010002A20FFF73DFB02E0201D03F004FE286884 +:1040200090F821005A2812D102212160DAF80010FC +:1040300091F88716890703D59821201D05F010FDFA +:10404000B948296810229C30223105F068FC201DF7 +:10405000BDE8F04703F0E7BDF8B50E46054600247D +:104060006A4604F06DFA012801D001240BE03068A3 +:1040700029468200AD4805F097FCAC4804F073FA7D +:10408000012800D002242046F8BDF8B5A74EA84F5D +:1040900010364FF47061A74805F0E2FC69463846D7 +:1040A000FFF7DAFF012805D0022806D0F0780128B2 +:1040B0000AD105E00021A02028E00021A12025E070 +:1040C000B07808B9308810B10021A2201EE09948CC +:1040D000F1880024A0F8F81EB188A0F8FA1E317A01 +:1040E00080F8FC1E0098694607EB80073846FFF70A +:1040F000B3FF70B1012803D00021A620FFF7C8FA52 +:10410000E00723D0A00723D41121A720FFF7C0FA8E +:10411000F8BD75783146284601F006F850B1102DEB +:104120000BD0112D0CD0122D0DD0132DDAD144F05F +:104130001004D7E72946A820E0E744F00104D1E7BE +:1041400044F00204CEE744F00804CBE71021DCE79A +:1041500020070BD47148006890F80012C90703D1FA +:1041600090F8BA00C00701D01221CEE7E006CFD404 +:104170001321CAE710B58EB0ECF740F900200123F7 +:1041800041B201F01F0403FA04F24909890001F168 +:10419000E021C1F88021401C1F28F1DBECF72CF94D +:1041A00004F0F2F8FFF79CFA04F0D2FC07210A2091 +:1041B000FFF78EFE07210B20FFF78AFEFFF72AF894 +:1041C000FEF7E4FF04A8FFF7C0F907A8FFF7C8F857 +:1041D00004A8009007A802900AA80390684604F07B +:1041E000C9FE02210020FFF773FE05F0C5FC007830 +:1041F000C00701D1FFF72DF8FFF700FA04F010F91E +:104200004D4C01AA6946204604F09AF9012802D0D3 +:104210000021202012E00098A0F54072523AF7D118 +:1042200021463E4C40F64852206805F078FB206855 +:1042300004F099F9012803D000212120FFF7E3F9C8 +:1042400000F024F8FFF760FEFFF71FFF00F044F8CE +:1042500003F030F803F0BCFC0023012219460520CE +:1042600005F0D6F900231A460121062005F0D0F901 +:1042700003210120FFF72CFE04210720FFF728FE71 +:104280000EB00421BDE81040082021E67CB52B4E7D +:1042900001AA6946304604F053F9224C4FF4805588 +:1042A000012803D10098B0F5806F02D000212220B0 +:1042B0000BE02A463146206805F031FB206804F007 +:1042C00052F9012807D000212320FFF7E1F9294600 +:1042D000206805F0A3FB7CBD10B504F0FFFE0023B1 +:1042E00001221946184605F093F9002301221946C8 +:1042F000104605F08DF900231A460121022005F031 +:1043000087F900231A460121032005F081F90023D3 +:1043100001211A46042013E00090D003A4071000E6 +:10432000D8961000A8071000909C10001C72100076 +:10433000F0CF01007C770120F0EF0100F0BF010019 +:1043400005F066F916480068017CA52908D04FF4ED +:10435000FA4005F047F900212820FFF799F902E01B +:10436000406905F03FF904210220FFF7B1FD042167 +:104370000320FFF7ADFD04210846FFF7A9FD042146 +:104380000520FFF7A5FD04210620FFF7A1FD01216F +:104390000920FFF79DFD0421BDE810400F2097E59F +:1043A000A8071000F0B5054600200C46014603465C +:1043B0004FF0804203E09B0843EA82739208EE1AB2 +:1043C00074EB0206F7D318E0C71841EB0206B5EB11 +:1043D000070C74EB060C07D3ED1B64EB0604DF1827 +:1043E00042EB0206381871414FEA9303490843EA49 +:1043F00082734FEA30004FEA920253EA0206E3D199 +:10440000421B71EB040202D2401C41F10001F0BDDD +:10441000884200D30846904200D310467047884235 +:1044200000D80846904200D810467047884200D312 +:1044300008467047884200D808467047884200DB2B +:1044400008467047884200DC084670470246002054 +:104450004FF0804100E089089142FCD807E0431802 +:10446000934202D8D21A00EB410040088908002983 +:10447000F5D1824200D9401C704710B55A43029CC6 +:1044800005E050F8223093FBF4F341F82230521E3D +:10449000F7D210BD10B55A43029C04E050F8223008 +:1044A000634341F82230521EF8D210BD2DE9F04F7F +:1044B0008246DDE90906DDF834E08B46824225D1EB +:1044C000002421E004FB02F00AEB80090B9D04FBB1 +:1044D0000EF0002105EB800513E000200EE000FB4C +:1044E00006F803EB880859F820C055F8217058F8F1 +:1044F0002180401C0CFB087745F821709042EEDBD0 +:10450000491CB142E9DB641C5C45DBDBBDE8F08F94 +:1045100030B5039C634306E050F8234051F8235024 +:104520002C4442F823405B1EF6D230BD30B5039CCC +:10453000634306E050F8234051F82350641B42F8CF +:1045400023405B1EF6D230BD10B500231C4642B19D +:104550000278521CD2B202708A4203D9047001233D +:1045600000E00470184610BD30B50024012305E0BA +:104570000C44E41C04F00305641B5B1C9342F7DD50 +:1045800000EB440030BDF0B5851ADDE905471E1B80 +:1045900075438E1A012F02D0904206DD0BE0904247 +:1045A00001DC1846F0BD884201DB2046F0BD95FBDA +:1045B000F6F0181AF0BD8842F3DA95FBF6F02044C5 +:1045C000F0BD2DE9F047994690461DE0051800F032 +:1045D0000106354341EB010402464E0815400C40EC +:1045E0004FEA3007A9F101024FF001004FF000013E +:1045F00005F04BF900EA050201EA040347EA02006C +:1046000046EA030128402140B8F10108DED2BDE8A6 +:10461000F0872DE9F04700241746884681461E465C +:1046200025465A1E0120214605F02FF90BE039F9E5 +:104630001620424504DA3A44002A01DD04430D43C2 +:1046400049084FEA3000761EF1D220462946DEE7BF +:104650002DE9F0478446002092468946014601260E +:104660000746024621E03CF912504D451ADA0CEBA0 +:104670004208B8F902402C1B00D5644238F9028C7C +:1046800024B2B5EB080500D56D422DB232B1A3F1CD +:104690000108424501D0A54200DD2C46544501DA0F +:1046A00030433943B6197F41521C9A42DBDBAEE7F7 +:1046B00070B50CE00618034641EB01051E430D439F +:1046C00049084FEA300040EA060041EA0501521E5F +:1046D000F0D270BD70B50546184600240EE02B5D83 +:1046E00058400823060602D582EA400000E0400058 +:1046F0005B1EC0B213F0FF03F4D1641C8C42EED3F6 +:1047000070BD30B507E0041800F001031C4341EB15 +:10471000010520402940521EF5D230BD2DE9F04759 +:1047200000248246A6B0501E00F0FF0C234620460F +:104730006E460DF14C0912E031F910502C44451C25 +:104740002F4694FBF5F526F81050ACEB0005401C05 +:1047500031F91580434493FBF7F729F8157090421F +:10476000EADB4B460AE036F9120033F912402044E6 +:1047700031F81240A4EB60002AF81200521EF2D267 +:1047800026B044E72DE9F0470026914607468846C3 +:10479000344635460FE041462A46384605F088F84B +:1047A000C00705D0641CE4B2A64202D2264600E04F +:1047B00000246D1CEDB24D45EDD3304627E7F0B532 +:1047C000DFF888C000220CEBC2034FF0FF34C3E9CE +:1047D0000044521C1A2AF6DBDFF874E00022DEF8EF +:1047E000004009E000EBC203D3E900568B180CEB44 +:1047F000C303521CC3E9005694F831309342F1DCF4 +:10480000002314E04FF0FF342546002207E09E18F5 +:104810000CEBC607D7E9006734403D40521CB2EBB1 +:10482000410FF4DD00EBC3025B1CC2E90045DEF87A +:10483000002092F831209A42E4DCF0BDC2F580738A +:10484000504301FB0300001270470000F096100077 +:10485000A40710002DE9F047D0F810C00568046ADD +:1048600085FB0C12A1FB046141694368894683FB07 +:1048700001128269E246A1FB02178E19D0E90217E4 +:1048800081FB07C8C069ACFB00C81CEB060682FBB5 +:104890000A2CA2FB012180FB0901A0FB0501801865 +:1048A00084FB0712A1FB03120818301A4FEAE071CB +:1048B000BDE8F08770B542F21074049D521AED1AEB +:1048C000654395FBF2F2514391FBF4F1591A4243CF +:1048D00092FBF4F0084470BD2DE9FF4F83B0114600 +:1048E000DDE91278D1E900061D46D1E902238218DC +:1048F000D1E904015E418346101800910024714102 +:104900003A46434604F0E7FF0646D5E90203D5E9F7 +:10491000001C0A18D5E904014CEB030C8246101860 +:1049200089464CEB01013A46434604F0D4FF054664 +:1049300058463A464346009904F0CDFFC2178346D5 +:104940000192504649463A46434604F0C4FFC31715 +:104950000093BBEB060180461498019AA1FB007CF2 +:104960004FEAE67962EB090202FB00C0A34601FBB5 +:104970000B0102225B46384604F0ADFF871941EB7C +:104980000909B8EB05011498009BA1FB00C84FEA88 +:10499000E57A63EB0A0303FB008001FB0B010222B3 +:1049A0000023604604F097FF401941EB0A08BB4919 +:1049B000A44663460968BCEB070C42F2107A73EB1D +:1049C000090307DA4A8E521E4FEAE27CBA1A79EBE3 +:1049D0000C0313DB4FF0000C6346BCEB070C73EBCE +:1049E000090301DA4C8E641ECDE9000A2B463146DC +:1049F0003A462046FFF75EFF274623E04FF0000CC3 +:104A000062464346BCEB000C9A4107DA8A8E521E7E +:104A10004FEAE27C821A73EB0C0313DB4FF0000CBD +:104A20006346BCEB000C73EB080301DA8C8E641E4A +:104A3000CDE9007A0246334629462046FFF73AFF81 +:104A40000746204603994F600399086007B0BDE808 +:104A5000F08F30B5B0F90240B1F90250641B00D5B7 +:104A60006442B0F90000B1F90010401A00D540428C +:104A7000944203DA984201DA012030BD002030BDB3 +:104A8000884201DD084670470028FCDA00207047A4 +:104A900010B504E000EB820353F8044C1C60521E76 +:104AA000F8D10968016010BD10B503E000EB820386 +:104AB0000C681C60521EF9D210BD30B505E000EB49 +:104AC000C20373E90245C3E90245521EF7D1D1E999 +:104AD0000021C0E9002130BD10B553884C881B1B54 +:104AE000438012880988511A018010BD08B50A4612 +:104AF00001466846FFF7F0FFBDF90010BDF902005E +:104B0000494300FB001008BD10B58842029C01DC3F +:104B1000204610BD904201DB184610BD8A4200D1EC +:104B2000521C401AE31A5843511A90FBF1F0201A14 +:104B300010BD10B5002A03D0431A934201DD881836 +:104B400010BD5442A342FBDA881A10BD914201D134 +:104B500000B270475043B0FBF1F000B29042F7D979 +:104B60001046F5E7F0B50C0002463FD04B4F3868D1 +:104B7000468E858EB2F9020031B2FFF781FF608068 +:104B8000B2F9000029B2FFF77BFF2080396891F865 +:104B90003610490702D56188711A6180396891F829 +:104BA0003610890701D5281A2080386890F8361009 +:104BB000090712D5012B10D1B0F83720B4F9020043 +:104BC0003146FFF7C3FF608038682946B0F83920C6 +:104BD000B4F90000FFF7BAFF2080386890F836007B +:104BE000C00703D06088218861802080F0BD2B49F8 +:104BF0000968B1F93220B1F9343091F8361062F316 +:104C00001F4063F30F00C90703D063F31F4062F333 +:104C10000F00704770B50B0002463DD01F4EB2F931 +:104C2000020031684D8E8C8E29B2FFF729FF588023 +:104C3000B2F9000021B2FFF723FF1880316891F824 +:104C40003610490702D55988691A5980316891F898 +:104C50003610890701D5201A1880306890F8361070 +:104C6000090710D5B0F83720B3F902002946FFF73D +:104C70006DFF588030682146B0F83920B3F9000044 +:104C8000FFF764FF1880306890F83600C00703D043 +:104C9000588819885980188070BD0000A40710003A +:104CA00073B51D24DDE9005622460120002104F0E1 +:104CB000ECFD28403140084301D1641EF4D50821A1 +:104CC000684603F02BFCFF49C0B2096891F8CE108A +:104CD000C1F3411102290ED310F0030005D00128C1 +:104CE00005D0022805D01F200AE00F2008E07F2011 +:104CF00006E03F2004E0C00701D0072000E00320C9 +:104D00000021621C04F0C1FDDDE9002310431943BA +:104D1000CDE900017CBD10B5EB4C502814D008DC67 +:104D2000102811D0112825D0122823D0132806D1FD +:104D300020E051281ED052281CD053281AD0002021 +:104D4000C4E9020001461BE002F03FFBC4E9020196 +:104D500002F03DFBC4E90401DA48006890F8CE0097 +:104D600010F0600F0ED0D4E90201FFF799FFC4E9FB +:104D7000020107E002F029FBC4E9020102F027FB6F +:104D8000C4E90401D0480821083003F0C7FB2060C3 +:104D9000CD480821103003F0C1FB606010BD2DE943 +:104DA000FF5F82B011AC082194E8000E02A803F066 +:104DB000B5FB0090082104A803F0B0FB07460025CE +:104DC00028463BE042460120002104F05EFDDDE97B +:104DD00002231040194008432ED00024264628E024 +:104DE00032460120002104F050FDDDE9042310408B +:104DF000194008431CD0BBF1000F0CD005FB07F095 +:104E000009EB04014156324601EB0A03294610988A +:104E100002F0C7FF0BE032462946109802F0B6FFB9 +:104E2000A0EB0A0105FB07F009EB04028154641CA6 +:104E3000761CBC42D4DB6D1C08F101008046009852 +:104E40008542BFDB06B0BDE8F09F2DE9FF5F84B06F +:104E50000821DDE9134B04A803F060FB0746082195 +:104E600006A803F05BFB80461298002648300290AB +:104E700012983546683001901298B2462030B146FB +:104E8000009032E052460120002104F0FEFCDDE9F2 +:104E9000042310401940084323D0169880B1A15D27 +:104EA00001EB0B00C2B25146029802F0E6FFF11985 +:104EB00001EB080022565146129802F0B6FF0EE0B0 +:104EC0005146029802F0D7FFA0EB0B00A0555146C7 +:104ED000129802F0A3FFF21902EB08016054761C4D +:104EE000F6B20AF1010000F0FF0ABE42CADB36E06A +:104EF0004A460120002104F0C8FCDDE906231040E9 +:104F00001940084327D0169890B1E819215C1598EC +:104F10000844C2B24946019802F0AFFF05EB4701D1 +:104F200001EB080022564946009802F07EFF10E08F +:104F30004946019802F09FFF1599401AE9196054FB +:104F40004946009802F06AFF05EB470202EB0801B0 +:104F500060546D1CEDB209F1010000F0FF094545F8 +:104F6000C6DB08B06FE72DE9FF5F0821DDE90EB968 +:104F7000684603F0D3FA8246082102A803F0CEFA6D +:104F800000268046374628E03A460120002104F0FA +:104F90007CFCDDE900231040194008431CD00024AC +:104FA000254616E02A460120002104F06EFCDDE9CA +:104FB00002231040194008430AD02A463146584679 +:104FC00002F0E4FE06FB0842800029F81200641C8F +:104FD0006D1C4445E6DB761C7F1C5645D4DBBDE8E2 +:104FE000FF9F2DE9FF5F0821DDE90E48684603F0C9 +:104FF00095FA0746082102A803F090FA0026834696 +:105000003546B246B14641E052460120002104F047 +:105010003CFCDDE9002310401940084332D05146E2 +:1050200004F1480002F027FF0246264894F8923027 +:10503000006890F8111190F8100101F00F0C0CF1BC +:10504000010C03FB0CF34FF0010C0CEB111102FBF4 +:10505000013194F890200CEB101002FB0010109915 +:1050600019B94FF6FF7101EA800028F81600514681 +:10507000204602F0D3FEF21980005A44761C28F82C +:105080001200F6B20AF1010000F0FF0ABE42BBDBDB +:1050900047E04A460120002104F0F7FBDDE9022346 +:1050A00010401940084338D0494604F1680002F026 +:1050B000E2FE0246034894F89360006890F81311EA +:1050C00004E00000A40710000008100001F00F0326 +:1050D0005B1C5E43012303EB111102FB016190F89D +:1050E000120194F8912003EB101002FB00101099AC +:1050F00019B94FF6FF7101EA8000EA19494628F80C +:10510000120004F1200002F089FE05EB4702800046 +:105110005A446D1C28F81200EDB209F1010000F0AC +:10512000FF095D45B5DB5AE77FB50D46044600260D +:10513000FFF7F1FD0122F84905F11000102C06D00F +:10514000112C0FD0122C23D0132C29D124E02B7931 +:105150000C68A3420ED16B794C68A3420AD100239C +:10516000EE4C0BE02B790C68A34203D16B794C68B1 +:10517000A34201D0002613E0E94C002300940392DF +:10518000CDE9010308310FC9FFF709FE012607E049 +:10519000284600F083F802E0284600F0B8F80646FA +:1051A000304604B070BD2DE9F0411E4617468846D2 +:1051B00004460025FFF7AFFD102C06D0112C0AD0B5 +:1051C000122C11D0132C0CD114E032463946404633 +:1051D00000F0D6F804E032463946404600F0F4F8D4 +:1051E00005462846BDE8F08132463946404600F083 +:1051F0000FF9F5E732463946404600F04BF9EFE744 +:105200002DE9FF4117460C460646FFF784FDC248CC +:1052100004F11005502E017821710179617107D0D8 +:10522000512E07D0BF49522E0FD0532E30D119E046 +:10523000BA4900E0BA49CDE9001585680C3090E81C +:105240000E002846FFF78FFE22E00968B64B91F862 +:10525000042191F8101102F0010201F00101CDE9E1 +:1052600002120CE00968B04B91F8232691F82F1632 +:1052700002F0010201F00101CDE902129833CDE9FB +:10528000003585680C3090E80E002846FFF7A9FE2F +:10529000A520207066706780BDE8FF8130B59E4C08 +:1052A000017987B02268914203D1417962689142C5 +:1052B00002D0002007B030BD98498579002281F8DE +:1052C000825BC57981F8835B857A81F8845BC57AD6 +:1052D00081F8855B057B81F8805B457B81F8815B8C +:1052E00090490125134609681030083491F80411DB +:1052F00001F00101CDE904518B4901AD009185E830 +:105300000D0094E80F00FFF7A0FD0120D2E730B5B3 +:10531000814C017987B02268914203D1417962685A +:10532000914201D00020C5E77C498579002281F8AF +:105330001A5CC57981F81B5C857A81F81C5CC57A9A +:1053400081F81D5C057B81F8185C457B81F8195C50 +:1053500074490125134609681030083491F8231662 +:1053600001F00101CDE904516F4901AD983100917F +:1053700085E80D0094E80F00FFF767FD012099E72D +:105380007FB50E46044640F27A3104F047FB624D89 +:10539000624A04F110012878207128796071002098 +:1053A0000092CDE9011005F1080103900FC9FFF744 +:1053B000F6FCA5202070102060706680D5E9000101 +:1053C000484313308008ECE67FB50E46044640F2B1 +:1053D0007A3104F023FB504D514A04F11001287832 +:1053E00020712879607100200092CDE9011005F14B +:1053F000080103900FC9FFF7D2FCA52020701120EF +:1054000060706680D5E90001484313308008C8E623 +:1054100070B50E4686B00446FC2104F0FFFA3E4DFE +:1054200028782071287960713C4890F8821BA1711E +:1054300090F8831BE17190F8841BA17290F8851B92 +:10544000E17290F8801B217390F8810B60733548EE +:10545000006890F8040100F001010020CDE904018A +:105460000290039004F110002F49CDE9001005F1DE +:1054700008010FC9FFF7E9FCA52020701220607019 +:105480006680D5E900010844132101EB4000800843 +:1054900006B070BD70B50E4686B00446FC2104F01F +:1054A000BDFA1D4D28782071287960711B4890F84D +:1054B0001A1CA17190F81B1CE17190F81C1CA172C0 +:1054C00090F81D1CE17290F8181C217390F8190CCB +:1054D00060731448006890F8230600F00101002072 +:1054E000CDE9040110490290039004F110009831B5 +:1054F000CDE9001005F108010FC9FFF7A6FCA520B2 +:105500002070132060706680D5E90012114400EB12 +:1055100041008008BCE70000000810007C770120F3 +:10552000A47C0120A40710006C82012030B506E0A5 +:1055300032F8134031F81350641B20F813405B1EFF +:10554000F6D230BDF0B4049C1CB913B1C3F1100500 +:105550000DE0F0BC520004F0E2B930F9124031F92C +:1055600012605C4306FB0544241120F81240521ED1 +:10557000F3D2F0BC7047F0B4049C1CB913B1C3F172 +:1055800080050DE0F0BC520004F0C9B930F91240BA +:1055900031F912605C4306FB0544E41120F8124027 +:1055A000521EF3D2E5E7F0B507466348DDF814C0B4 +:1055B000450C00260AE037F91140844200DD204600 +:1055C000AC4200DA2546644500DD2644491EF2D28D +:1055D00002B11580002B00D01E60F0BD0346B0F96B +:1055E000000004E033F91120824200DD1046491E1C +:1055F000F8D2704710B5002447F6FF7307E030F982 +:105600001120A24200DD14469A4200DA1346491ED8 +:10561000F5D2E01A00B210BD2DE9F0471646DDE9DB +:105620000878894604460025DFF810A127E02A46BD +:105630000120002104F029F9384001EA080108435B +:105640001AD00020524615E0136834F9101093F870 +:105650005F32594341F3CF1124F81010002900DACA +:1056600049421368B3F87332994202DD0120BDE864 +:10567000F087401CB042E7DB04EB46046D1C4D454F +:10568000D5DB0020F3E72DE9F04F47F6FF76DDE9A3 +:1056900009B5F4439A4601278146BC462B4614E0DF +:1056A00032F8130031F81380A0EB080000B2B042CA +:1056B00000DA0646A04200DD0446002802DD4FF075 +:1056C000000C02E001DA4FF000075B1EE8D227B1C0 +:1056D000BCF1000F01D0002009E057EA0C0006D011 +:1056E00027B9BCF1000F01D0204600E0304600236E +:1056F0001E462C46CBF1000C0DE032F8147031F848 +:105700001480A7EB08073F1A3FB2574503DA6745F5 +:1057100001DD3B44761C641EEFD206B9012693FBE3 +:10572000F6F2131804E031F81500184429F81500B2 +:105730006D1EF8D2BDE8F08F0080FFFFA4071000B7 +:1057400070B5050003D0BDE8704001F01CBEFE4CF2 +:10575000204662780179012A16D0022A1BD02078CF +:1057600001F0CAFE21794A00F84901EB4001F748EF +:10577000983004F0D4F8A078F54E78B1F348217948 +:10578000983001F0B2FE0BE00A46F04901F19800B2 +:1057900001F028FEEFE74A00EC49E8E7EB489830D3 +:1057A0003063E07886F839002846CCE7E9490128DB +:1057B000096808D0022809D003280AD004280BD091 +:1057C00091F83A0C704791F83B0C704791F83C0CFB +:1057D000704791F83D0C704791F83E0C7047F8B552 +:1057E000044602F00EFAD94802F010FAA4F8760046 +:1057F00001F01EFED44A0B46127800920246204663 +:1058000002F00CFD01F019FE02460B46204602F0A4 +:105810003BFD204601F076FECE4DB4F856102868C8 +:10582000B0F88E2062F30901A4F8561090F88D00AC +:1058300094F8551060F3030184F8551005212046B3 +:1058400002F00FFA286890F83306A0702868218EBD +:10585000B0F8392662F30801218690F8340600F08A +:105860000F01204602F074FA286834F81A1FB0F8C5 +:105870002B2662F30B0124F81419B0F8292661894C +:1058800062F30B016181B0F82716E08861F30B0029 +:10589000E08014F8050C20F00C0004F8050C2868D2 +:1058A00090F835160A09217B62F30101217390F803 +:1058B0003526920962F38711217390F821166278D8 +:1058C00061F30002627090F82406E070A24890F83C +:1058D000181C217690F8191CA17790F81A1C617693 +:1058E00090F81B1CE17790F81C1CA17690F81D0C19 +:1058F00084F82000994802F089F9A4F87A009748C2 +:10590000203002F083F9A4F87E00286890F82F1662 +:105910000A0914F8161F62F3071104F8061B90F821 +:1059200031261309227863F30712227090F830664B +:1059300014F8053C66F3030304F8053C90F832764E +:10594000667867F30306667090F830763F0967F370 +:10595000071304F8053C90F832361B0963F3071669 +:10596000667090F82F3663F3000104F8061C90F877 +:10597000311661F3000204F8222990F82506010986 +:10598000204602F0F1F97548483802F03FF9A4F8D2 +:105990007E0072482734283802F038F9A4F85B00FA +:1059A000286890F823168A08217862F38301217011 +:1059B00090F8232662F30001217090F82326520804 +:1059C00062F3410104F8011B217821F010012170DC +:1059D00090F82126D308E27A63F34512E27290F838 +:1059E000222662F3451104F8281990F82206C0F324 +:1059F0004101204602F086F9286890F821168A09AC +:105A000014F8331F62F3000104F81D1990F82126E1 +:105A1000520962F34101617790F83616E27D61F335 +:105A20000402E27590F83706A17D60F30401A175C8 +:105A30000120FFF7BBFE94F8491060F304014748CA +:105A400084F84910E83002F0E1F8A4F8640028680E +:105A500034F8181FB0F82D2662F30B0124F804194E +:105A600010F8CA1F227861F3030204F8012B0178B1 +:105A70000A09217862F3030104F8091B90F857150D +:105A8000CA09217862F3000104F82B1B14F8571996 +:105A900041F0200184F8571090F86C154A092178DC +:105AA00062F30611217090F858154A09217C62F3BF +:105AB000C301217490F85705400860F30411217464 +:105AC000F8BD2DE9F04104461F4D0120DFF8848028 +:105AD000A870012908D00026022702290ED0032928 +:105AE0004CD004292BD161E0204600F0B3F8D8F85F +:105AF000000090F822068009687020E01848FFF73F +:105B00006EFE204600F0A6F80220FFF74FFE94F844 +:105B10005F1060F30401134884F85F1000780128D7 +:105B200007D194F8270020F0020040F0010184F82A +:105B300027100021204602F00BF9AE706F7094F828 +:105B4000270040F300000FE01808100084870120B0 +:105B5000549C1000A40710007C7701204C83012086 +:105B6000C0971000AC071000401CE870D8F8000087 +:105B700090F8220680096870BDE8F0813748FFF789 +:105B80002EFE204600F066F80320FFF70FFE94F883 +:105B90005F1060F3040184F85F1094F8270020F090 +:105BA000020040F0010084F82700C2E7204600F020 +:105BB00051F8204601F0E7FCBFE71CB501F03DFCC1 +:105BC000CDE900010821684602F0A8FC24490871CB +:105BD0002248FFF704FE1CBD30B5417AA9B091B34D +:105BE0006846FFF76EFF9DF8120000F0030001F019 +:105BF00057FC1C4D286800F2AC6200F29F5490F8EC +:105C00009D16B0F89E0602EB400001F01BFC2868D0 +:105C100090F8931590F8940504EB400001F029FCEE +:105C20000F494878022811D0012811D001200870AE +:105C3000C1B2684602F042FB0B49684602F073FBB2 +:105C4000002029B030BDFFE70120FAE70920EEE788 +:105C50000320ECE7A422014903F061BEC0971000C5 +:105C600018081000A4071000F156010070B518B113 +:105C7000BDE8704001F087BBFE4CFD4DE078A5F11A +:105C80009801820001F5887003F08EFEA178012949 +:105C90001DD0022922D0E178607801F027FCE1785C +:105CA000C0B24A00A5F1980101EB4001284603F07B +:105CB00036FEA079F04D012815D0ED482862E07934 +:105CC00085F83800607985F828000020D0E7E84999 +:105CD000E2789839284601F085FBEAE7E078E44964 +:105CE00042009839E2E7E178E14801F0FDFBE5E7A1 +:105CF00070B518B1BDE8704001F045BBDD4CDC4D1E +:105D000020792A358200A5F1C20101F5B27003F0B5 +:105D10004BFEA17801291ED0022923D02179607879 +:105D200001F0EAFB2179C0B24A00A5F1C20101EB02 +:105D30004001284603F0F3FDA079CF4D012816D08D +:105D4000CB482A306862E07985F83800607985F8B8 +:105D500029000020CEE7C64922799839284601F06B +:105D600041FBE9E72079C24942009839E1E7C048A0 +:105D700021792A3001F0B9FBE4E7C0490628096817 +:105D800013D2DFE800F0120306090C0F91F8350C6E +:105D9000704791F8360C704791F8370C704791F8BE +:105DA000380C704791F8390C704791F8340C7047F3 +:105DB000F8B5044601F025FFAD48983801F026FFFC +:105DC000A4F8760001F034FBAA4D0B466A780092E5 +:105DD0000246204602F022FA01F02FFB02460B4653 +:105DE000204602F051FA204601F08CFBA34EB4F895 +:105DF00056103068B0F88E2062F30901A4F85610EE +:105E000090F88D0094F8551060F3030184F8551054 +:105E10000521204601F025FF306890F81401A0709C +:105E20003068218EB0F81A2162F30801218690F8BB +:105E3000150100F00F01204601F08AFF306834F8A8 +:105E40001A1FB0F80C2162F30B0124F81219B0F8F4 +:105E50000A21218962F30B012181B0F80821A18870 +:105E600062F30B01A18090F81621A17A62F301017F +:105E7000A17290F81621920862F38711A17290F82E +:105E8000021114F8012C61F3000204F8012C90F8BF +:105E9000050160707A4890F8801BA17590F8811B0D +:105EA000217790F8821BE17590F8831B617790F859 +:105EB000841B217690F8850BA077724801F0A6FE2E +:105EC000A4F878006F48203001F0A0FEA4F87C0010 +:105ED000306890F810110A0914F8141F62F30711C2 +:105EE00004F8061B90F812212378120962F30713B5 +:105EF000237090F8112114F8057C62F3030704F86D +:105F0000057C90F813C162786CF30302627090F81C +:105F100011C14FEA1C1C6CF3071704F8057C90F8BC +:105F200013713F0967F30712627090F8102162F352 +:105F3000000104F8061C90F8121161F3000304F844 +:105F4000223990F806010109204601F00DFF4D4865 +:105F5000483801F05BFEA4F87E004A482734283810 +:105F600001F054FEA4F85B00306890F804118A0830 +:105F7000217862F38301217090F8042162F300011B +:105F8000217090F80421520862F3410104F8011BCA +:105F9000217821F01001217090F80221D308E27AD3 +:105FA00063F34512E27290F8030160F3451104F8BF +:105FB0002819204601F086FA306890F80301C0F3F2 +:105FC0004101204601F09EFE306890F802118A09D6 +:105FD00014F8331F62F3000104F8071990F8022146 +:105FE000520962F34101E17190F81711627861F38F +:105FF0000402627090F81801217860F304012170A6 +:106000000120FFF7BAFE94F8331060F3040184F81E +:1060100033101D4801F0FAFDA4F84E00306834F842 +:10602000021FB0F80E2162F30B0124F8181910F8C2 +:10603000CA1F227D61F30302227510F82E1B0A0984 +:10604000617D62F303016175817ACA09A17F62F300 +:106050000001A17794F8491041F0200184F849101B +:10606000C17F4A0914F80E1C62F306110EE000000D +:10607000008901201D081000549C1000A407100086 +:106080007C770120B48201203484012004F80E1CA6 +:10609000C17A4A09A17862F3C301A170827A5208D9 +:1060A00062F30411A170C07A8009A870F8BDA4221F +:1060B000884903F034BC2DE9F041874D0C46002699 +:1060C00001216E71A971012807D00227022826D06C +:1060D00003280CD004284CD143E02046FFF7E7FF0B +:1060E0007E48006890F803018009A87041E0794873 +:1060F000FFF75EFE2046FFF7DAFF0320FFF73DFEC5 +:1061000094F85F1060F3040184F85F1094F827009E +:1061100020F0020040F0010084F827001AE06D48EA +:10612000FFF746FE2046FFF7C2FF0220FFF725FEDD +:1061300094F85F1060F30401694884F85F100078F8 +:10614000012807D194F8270020F0020040F0010157 +:1061500084F827100021204601F0FAFDAE71AF70DF +:1061600007E02046FFF7A3FF204601F00CFAAF70CE +:10617000AE7194F8270040F30000401CE871BDE8C0 +:10618000F08170B5554D286800F2AC6200F29F5462 +:1061900090F89A16B0F89B0602EB400001F052F915 +:1061A000286890F8911590F8920504EB4000BDE83E +:1061B000704001F05EB970B5474D0146C079454C5D +:1061C0002870097BA434297250B3012928D02146B4 +:1061D000FFF771FFA878012824D0022824D00020DE +:1061E00068703E480168A07C91F8162162F30100B6 +:1061F000A07491F81611890861F38710A07469786A +:10620000204602F05BF8A07C00F0030001F048F9A2 +:10621000FFF7B7FF3349204602F085F8002070BD34 +:10622000012070BD0220DBE70820D9E770B52A4DB8 +:106230000146C079274C2870097BA434297258B3D1 +:10624000022929D02146FFF736FFA878012825D05A +:10625000022825D0012068702048016891F81601B5 +:106260000209A07C62F30100A07491F8161189095B +:1062700061F38710A0746978204602F01FF8A07CB3 +:1062800000F0030001F00CF9FFF77BFF16492046F0 +:1062900002F049F8002070BD012070BD0320DAE74C +:1062A0000920D8E71FB501F0C3F8CDE9000101F0DE +:1062B000C4F8CDE902010821684602F02FF9064C26 +:1062C0000821E07002A802F029F920710148FFF7C7 +:1062D0006FFD1FBD649810001D081000A40710007A +:1062E000AC0710001D5C0100A15C010070B5B74D4A +:1062F000286800F2AC6200F29F5490F89116B0F852 +:10630000920602EB400001F09DF8286890F88B158A +:1063100090F88C0504EB4000BDE8704001F0A9B88E +:1063200008B101F030B8AB48A9490161AA49097820 +:1063300001750020F5E770B5A44D0446286890F873 +:106340007501C0F30112C0F3810100F00300FEF7F4 +:1063500066F8A14E401C3070204600F0C4FD9C48F9 +:1063600001F054FCA4F8760000223178204601F0B8 +:106370007CFEA07940F00200A071317894F86F00A3 +:1063800061F3020084F86F0094F86E0020F00F00B3 +:1063900084F86E002868A17C10F8EB2F62F30101ED +:1063A000A17410F80129920862F38711A174A189E0 +:1063B0006FF30B01A1810078A07094F85E000021BA +:1063C00020F0010084F85E00204601F0C1FC28683E +:1063D00090F8771184F8661090F8781184F86810B6 +:1063E00090F8791184F86A1090F87A1184F86C109A +:1063F00090F8300C14F85F1F60F30401217070BD39 +:106400002DE9FC417548FFF796FF704F386890F80A +:106410007611090639D56E4E0024083E00F2771534 +:106420003460746000F0D1FFCDE900013A6892F861 +:10643000CE2012F0600F03D0FEF732FCCDE9000150 +:106440000821684602F06AF800213B6807E06A5CB0 +:10645000424326F81120A24200D91446491C93F861 +:10646000752102F00302521C8A42F0DC002005E094 +:1064700036F81010611A26F81010401C93F87511A8 +:1064800001F00301491C8142F2DCBDE8FC8170B5DA +:10649000524D4479A4355CB14C48006890F87501C0 +:1064A000400607D54E48007800F00300022801D2CC +:1064B000012070BD2146284600F083F8A87C00F03A +:1064C000030000F0EDFF2046FFF710FF4549284686 +:1064D00001F00BFE002070BD70B544793B483F4D84 +:1064E0000068A43590F87501400606D52CB13C48EB +:1064F000007800F00300022801D3012070BD21467E +:10650000284600F05EF8A87C00F0030000F0C8FF09 +:106510002046FFF7EBFE3349284601F0E6FD002058 +:1065200070BD002800F02FBF2DE9F0412B4C85797C +:10653000A434EDB32C4E264F3078083F37F81000C6 +:10654000B0B3A4222549204603F0E9F914F86F0FEF +:1065500020F00700401C04F86D091C48006890F802 +:10656000D70004F80E0B307837F81010208861F34C +:106570000B0024F8560B002004F85809E07F20F0A7 +:106580001F00E077A07F20F01F00A07734F8200FD5 +:106590006FF30B00401C24F81C0914F8120900F0DA +:1065A000030000F07DFF2846FFF7A0FE0F4900E042 +:1065B00005E0204601F099FD0020BDE8F0810120B2 +:1065C000FBE7A422054903F0AAB90000A4071000C4 +:1065D0006C8A0120549C100026081000AC99100011 +:1065E0003C081000D1620100DC071000D3640100F8 +:1065F000FE490F28096833D2DFE800F032080B0E9D +:106600001114171A1D202326292C2F0091F8210C74 +:10661000704791F8220C704791F8230C704791F85D +:10662000240C704791F8250C704791F8260C7047A0 +:1066300091F8270C704791F8280C704791F8290CB5 +:10664000704791F82A0C704791F82B0C704791F81D +:106650002C0C704791F82D0C704791F82E0C704758 +:1066600091F8200C704770B5E04E0428346804F2AD +:10667000AC6204F29F5518D0072824D00A2830D0E5 +:106680000B2833D0B4F8920694F8911602EB400030 +:1066900000F0D8FE306890F88B1590F88C0505EB6B +:1066A0004000BDE8704000F0E4BEB4F8950694F8F0 +:1066B000941602EB400000F0C5FE306890F88D158E +:1066C00090F88E05EBE7B4F8980694F8971602EB6D +:1066D000400000F0B7FE306890F88F1590F89005F4 +:1066E000DDE794F89B1594F89C05D8E794F89D1580 +:1066F00094F89E05D3E770B5060003D0BDE870405E +:1067000000F041BE00F02EF801282AD1B84DB94C56 +:10671000287801281FD0B848A0606878E073E8782E +:10672000A073A87A2073287B6073E87984F83A0014 +:10673000287A84F83B00AD48016891F8CD00C00686 +:1067400007D591F89701C00703D0AC48A06101209C +:1067500060753046D2E7AA79297AA74800F0C3FECF +:10676000DAE770BDA24B10B5D978A54C491CCAB266 +:10677000DA70997801208A420ED8197A98794143C3 +:106780009D48FDF7F1FE01F041FAA4F876009D491D +:10679000204601F0AAFC002010BD38B5044601F0E7 +:1067A00030FA954801F032FAA4F8760000F040FE85 +:1067B0008E4D0B462A6892F8CE20C2F34112009209 +:1067C0000246204601F030FC00F037FE02460B4640 +:1067D000204601F055FCA07920F00200A07194F849 +:1067E0006F0020F0070084F86F0094F86E0020F02E +:1067F0000F0084F86E00286890F8CE00C0F34111B5 +:10680000204601F057FC286890F8CE1011F0600F78 +:1068100094F85E107ED041F0010184F85E1090F88B +:10682000CD004108E07961F3C710E071204600F027 +:1068300069FE0521204601F014FA286890F8D70077 +:10684000A0702868218EB0F8DD2062F3080121864F +:1068500090F8D80000F00F01204601F079FA28687E +:10686000627D90F8D11061F303026275B0F8D32015 +:10687000218A62F30B01218290F8D910A27D61F385 +:106880000302A27510F8D81F0A09A17C62F3010166 +:10689000A17410F80B29920962F38711A174017891 +:1068A000E27961F30002E271C17861720079010955 +:1068B000204601F059FA544801F0A8F9A4F87C00E8 +:1068C000286810F8CF1F8A0814F8271F62F3830185 +:1068D000217010F8012962F30001217042785208FA +:1068E00062F34101217000780109607861F30410BE +:1068F0006070464801F08AF9A4F85F00286810F833 +:10690000CD1FCA0814F80C1F62F3451104F80B19C7 +:10691000427800E089E0217862F3451104F82819F3 +:106920004078C0F34101204601F0ECF9286810F8E6 +:10693000CD1F8A0914F8331F62F3000104F80B1904 +:106940000278520962F34101E172417B627961F39D +:1069500004026271807B217960F3040121710120BE +:10696000FFF746FE94F8371060F3040184F83710FF +:10697000274801F04BF9A4F85200286834F8061FA4 +:10698000B0F8D52062F30B0124F8061B90F8C9106B +:1069900014F80A2C61F3030204F80A2C90F8C910C9 +:1069A0000A0914F8091C62F3030104F8091C90F8A1 +:1069B000CD108A0814F80C1C62F3000104F80C1CBA +:1069C00090F8CD10CA09217862F3000104F82B1B5E +:1069D000217841F0200104F85F1990F89711C90758 +:1069E00022D090F8CD00010914E00000A4071000A7 +:1069F00028081000549C10009C8B01205C9E0120F4 +:106A0000989B1000A76601007C7701201487012065 +:106A10003484012014F8330F61F304102070FE4811 +:106A200001F0F4F8A4F8450038BD21F00101F4E6C6 +:106A300038B5044601F0E5F8F84801F0E7F8A4F8A5 +:106A4000760000F0F5FCF64D0B462A6892F8FF2A16 +:106A5000C2F3411200920246204601F0E5FA00F02E +:106A6000ECFC02460B46204601F00AFBA07920F020 +:106A70000200A07194F86F0020F0070084F86F0006 +:106A800094F86E0020F00F0084F86E00286890F8EB +:106A9000FF0AC0F34111204601F00CFB286890F872 +:106AA000FF0A10F0600F94F85E007DD040F0010006 +:106AB00084F85E00204600F025FD286890F80A0B57 +:106AC000A0702868218EB0F8102B62F3080121868F +:106AD00090F80B0B00F00F01204601F039F92868FF +:106AE000627D90F8021B61F303026275B0F8042B1B +:106AF000218A62F30B01218290F80C1BA27D61F3C5 +:106B00000302A275B0F8062BA18962F30B01A181E3 +:106B100090F80B1B0A09A17C62F30101A17490F8A3 +:106B20000B2B920962F38711A17490F8FE1AE27997 +:106B300061F30002E27190F8011B617290F8020BA0 +:106B40000109204601F010F9B64801F05FF8A4F8F9 +:106B50007C00286890F8001B8A0814F8271F62F34D +:106B60008301217090F8002B62F30001217090F8EE +:106B7000002B520862F34101217090F8FF0A0109CD +:106B8000607861F304106070A74801F03FF8A4F842 +:106B90005F00286890F8FE1ACA0814F80C1F62F308 +:106BA000451104F80B1900E066E090F8FF1A22780E +:106BB00061F3451204F8282990F8FF0AC0F3410157 +:106BC000204601F09FF8286890F8FE1A8A0914F808 +:106BD000331F62F3000104F80B1990F8FE2A5209E2 +:106BE00062F34101E17290F80D2B617962F30401C7 +:106BF000617190F80E0B217960F3040121710A2074 +:106C0000FFF7F6FC94F8371060F3040184F83710AE +:106C1000864800F0FBFFA4F85200286834F8061FED +:106C2000B0F8082B62F30B0124F8061B10F8C91FFB +:106C300014F80A2C61F3030204F80A2C01780A09FB +:106C400014F8091C62F3030104F8091C90F8351AC2 +:106C50008A0814F80C1C62F3000104F80C1C90F86C +:106C6000350AC109207861F3000004F82B0B207865 +:106C700040F02000207038BD20F0010018E738B542 +:106C8000044600F0BEFF654800F0C0FFA4F876009F +:106C900000F0CEFB624D0B462A6892F8192BC2F326 +:106CA000411200920246204601F0BEF900F0C5FBF9 +:106CB00002460B46204601F0E3F9A07920F00200DD +:106CC000A07194F86F0020F0070084F86F0094F82A +:106CD0006E0020F00F0084F86E00286890F8190B01 +:106CE000C0F34111204601F0E5F9286890F8190B2E +:106CF00010F0600F94F85E007DD040F0010084F841 +:106D00005E00204600F0FEFB286890F8240BA0707F +:106D10002868218EB0F82A2B62F30801218690F8AA +:106D2000250B00F00F01204601F012F82868627D63 +:106D300090F81C1B61F303026275B0F81E2B218AC8 +:106D400062F30B01218290F8261BA27D61F30302FE +:106D5000A275B0F8202BA18962F30B01A18190F8F4 +:106D6000251B0A09A17C62F30101A17490F8252B6F +:106D7000920962F38711A17490F8181BE27961F30C +:106D80000002E27190F81B1B617290F81C0B010964 +:106D9000204600F0E9FF234800F038FFA4F87C000B +:106DA000286890F81A1B8A0814F8271F62F38301D9 +:106DB000217090F81A2B62F30001217090F81A2BC1 +:106DC000520862F34101217090F8190B01096078B3 +:106DD00061F304106070144800F018FFA4F85F001D +:106DE000286890F8181BCA0814F80C1F62F34511A4 +:106DF00004F80B1900E073E090F8191B227861F396 +:106E0000451204F8282990F8190BC0F341012046D7 +:106E100000F078FF28680BE05C9E01209C8B01202D +:106E2000A40710007C7701201487012034840120FE +:106E300090F8181B8A0914F8331F62F3000104F854 +:106E40000B1990F8182B520962F34101E17290F886 +:106E5000272B617962F30401617190F8280B217985 +:106E600060F3040121710B20FFF7C2FB94F8371087 +:106E700060F3040184F83710FE4800F0C7FEA4F860 +:106E80005200286834F8061FB0F8222B62F30B0179 +:106E900024F8061B10F8C91F14F80A2C61F303022A +:106EA00004F80A2C01780A0914F8091C62F303019A +:106EB00004F8091C90F84F1A8A0814F80C1C62F3A5 +:106EC000000104F80C1C90F84F0AC109207861F306 +:106ED000000004F82B0B207840F02000207038BD13 +:106EE00020F001000BE710B50446A422E24902F0AD +:106EF00016FDE2484179A08961F30B00A08110BD25 +:106F000038B50446FFF7EFFF00F092FA0022009236 +:106F100002460B46204601F087F8D94800F076FE7D +:106F2000D84DA4F87C00286890F8DF00A07028688D +:106F300090F8E00000F00F01204600F009FF2868FB +:106F400010F8E01F0A09A17C62F30101A174027824 +:106F5000920962F38711A174817894F82D2061F36E +:106F6000040284F82D20C17894F82C2061F30402E7 +:106F700084F82C204078A17D60F30301A1750021E5 +:106F8000204601F097F814F85E0F20F00100207001 +:106F90000720FFF72DFB617860F30401617028681A +:106FA00034F82E1CB0F8E42062F3080124F82E1CFB +:106FB00010F8E11F0A0914F8371C62F3000104F805 +:106FC000371C0078400960F3410104F8371C38BDD4 +:106FD0002DE9F047AC4D4FF001094FF0000885F85E +:106FE000009085F8028085F80380064685F80780C2 +:106FF0002879A44F0C4628724FF0020A0F2A19D2A2 +:10700000DFE802F0A208A2192DA22068527393971C +:10701000A29B9F000846FFF766FF307D012809D13B +:107020006879287285F8079094F85E0020F00100D6 +:1070300084F85E0088E0084600F0EAF8386890F8C6 +:10704000E6002CE0084600F0E3F8386890F8E60027 +:10705000C0F38100022825D985F802A074E0084613 +:10706000FFF741FF386890F8E800A0700420FFF7B0 +:10707000BFFA94F85F1060F3040184F85F10307D6C +:10708000012809D16879287285F8079094F85E0084 +:1070900020F0010084F85E00386890F8E70000F006 +:1070A0000300D7E7A8704FE00846FFF71CFF002158 +:1070B000204600F04DFE14F85E0F20F00100207015 +:1070C0000820FFF795FA14F8011F60F3040104F893 +:1070D0005F1927E00846FFF713FF386890F8E910BA +:1070E000A08961F30B00A0812EE00846FFF708FF9E +:1070F0000021204600F02CFE0920FFF779FA94F8D1 +:107100005F1060F3040184F85F1094F85E0020F0D3 +:10711000010084F85E00386890F8E910A08961F3F6 +:107120000B00A08185F800800EE00846FFF780FC88 +:10713000F8E70846FFF7A3FDF4E7084600F075F806 +:1071400002E00846E9F71FFE94F82700C00702D0C6 +:1071500085F8018001E085F80190386890F8BD1A43 +:10716000C90702D0317C012908D044480078A881A1 +:10717000A089C0F30B006881BDE8F087717C00F244 +:107180007710415CA08961F30B00A081707CEEE771 +:1071900010B586B000F04CF9CDE9000100F04DF9D2 +:1071A000CDE902010821684601F0B8F9364C082102 +:1071B000207102A801F0B2F9A071DDE90001FDF72C +:1071C0006FFDCDE90401082104A801F0A7F9607161 +:1071D0002948FFF7E2FA06B010BD70B5264D0479D4 +:1071E000A4358CB122462946FFF7F2FEA87C00F0B8 +:1071F000030000F055F92046FFF735FA23492846E9 +:1072000000F073FF002070BD012070BD00207047AA +:1072100010B50446FFF767FE0320FFF7E9F914F8FD +:107220005F1F60F30401217010BD38B50446FFF7FD +:107230005AFE00F0FDF80022009202460B4620465E +:1072400000F0F2FE0320A0700021204600F080FD37 +:107250000021204600F02EFF94F85E0020F001008F +:1072600084F85E00A07D20F00F00A075607D20F006 +:107270000F000DE034840120F49A1000DC071000A8 +:10728000A47C0120A407100028081000A7660100B4 +:107290006075208A6FF30B0000F6A6602082A0893B +:1072A0006FF30B0000F6A660A081E08D6FF30B007A +:1072B000E08538BD10B500F0B1F9FFF769FFFFF7C1 +:1072C0009FF8FEF7EFFFFEF778FC42490020486088 +:1072D000BDE810407021404802F0A0BB38B1012841 +:1072E00007D0022807D017200021FCF78CB9142002 +:1072F000FAE71520F8E71620F6E7182102F0B0BBF0 +:1073000070B5344C354D206808E055F820103448ED +:107310008847002817D02068401C20600928F4D333 +:1073200060684EF66022401C00216060904200D3ED +:1073300061602B481830017061684160183801683D +:1073400018308847012070BD10B50446007940B957 +:10735000E07930B9607A20B9607910B9A079002855 +:1073600010D01F483C21183002F07AFB1822214629 +:107370001B4802F019FB1749002008601848FFF766 +:10738000BFFF012010BD70B5124C050016D00020C3 +:1073900000F050F961684EF66020491C616081423E +:1073A00001D3002060600E481830057061684160AC +:1073B00018380168BDE87040183008472068401C44 +:1073C0002060BDE8704006489AE700F031B800F050 +:1073D00034B800003808100014870120D09E010046 +:1073E0003C9C100070B5874B1B6893F80731DB0796 +:1073F0004FF000030ED0154609E031F9134031F982 +:1074000015603444641020F813405B1C6D1C9342DB +:10741000F3DB70BD144608E031F8135031F8146006 +:10742000354420F813505B1C641C9342F4DB70BDA0 +:1074300074480068C16A806A704772480068416A8F +:10744000006A704730B5714C6F4B6268824202D15E +:10745000E2688A420AD0002206E030F81250C5F3F2 +:107460000B0523F81250521C8A42F6DBE160606083 +:1074700030BD30B5654C664BA268824202D12269AC +:107480008A420CD0002206E030F81250C5F30B05FA +:1074900023F81250521C8A42F6DB2161A06030BDF5 +:1074A00070B504465B48016802290AD1574D297816 +:1074B0008C4206D000EB8400D0F89C0000F0B9FBB1 +:1074C0002C7070BD10B5044690F82800800609D5D0 +:1074D000514800F09BFB24F88E0F4F48203000F0FD +:1074E00095FB608010BD70477047704702004FF0F9 +:1074F000000000D10846704702460020012A00D152 +:10750000084670473F4A116891F87D108B0910F8C2 +:107510003E1B63F3820100F83E1C136893F87D3034 +:107520005B0963F3451100F83E1C1168B1F8852032 +:10753000028291F88420837F62F30713837791F8A6 +:1075400081201309027D63F306120275B1F87F30C2 +:10755000028B63F30902028311F87D2F9308827D69 +:1075600063F3861282750A79C37D62F30303C375E0 +:10757000B1F80530B0F81B2063F30802A0F81B2017 +:1075800049894182704710F8371F41F0100100F817 +:107590001F1930F80C2CC17E6FF30B02103220F84B +:1075A0000C2C30F8082C21F023016FF30B02403231 +:1075B00020F8082C082200F8162C90F8472041F0FB +:1075C0000C0122F01F0280F84720028B6FF30802A3 +:1075D0000283C176C18A6FF30B013F31C182417DC5 +:1075E00021F01F014175017D21F01F01017590F807 +:1075F000461021F0010180F84610017C41F0200185 +:1076000001747047A4071000348401204008100062 +:1076100034860120909C1000A4860120704710B58C +:1076200000F0A5FD08B1012010BD084800F088FD5C +:10763000002010BD064810B5006890F871004007A2 +:1076400001D500F089FD012010BD00003773010055 +:10765000A40710003D48016821F00401016000F01A +:107660001DBF10B5FFF7F6FF10BD10B5FFF7F2FF15 +:1076700010BD10B5FFF7EEFF10BD10B5FFF7EAFF24 +:1076800001F0BBFC10BD10B5FFF7E4FF00F0DEFA1F +:1076900010BD10B5FFF7DEFF01F085FD10BD10B580 +:1076A000FFF7D8FF01F0C7FD10BD10B5FFF7D2FFFF +:1076B00001F00AFE10BD10B5FFF7CCFF01F04FFE40 +:1076C00010BD10B5FFF7C6FF01F094FE10BD10B558 +:1076D000FFF7C0FF01F0D9FE10BD10B5FFF7BAFFEC +:1076E00001F022FF10BD10B5FFF7B4FF02F01AFA47 +:1076F00010BD10B5FFF7AEFF02F0F0F910BD10B5E8 +:10770000FFF7A8FF10BD10B5FFF7A4FF10BD10B51F +:10771000FFF7A0FF10BD10B5FFF79CFF01F04AFF77 +:1077200010BD10B5FFF796FF10BD10B5FFF792FF23 +:1077300010BD10B5FFF78EFF10BD10B5FFF78AFF23 +:1077400010BD10B5FFF786FF10BD704710ED00E0CB +:107750000EB50BA007C88DE807000C4800F047FEE7 +:10776000684600F048FEFCF705FDFCF765FB00F0FD +:1077700037F800214720FBF746FF01200EBD00002F +:10778000110000000000000000000000520047232C +:107790001A4910B5012008701949002008601949DC +:1077A0000860194908601949086000F07FF900F085 +:1077B00019F900F07DF8002010BD10B5124801F055 +:1077C00097FF104908600E490968884207D00B48A6 +:1077D0000078022803D1BDE81040E8F7C7BD10BD0E +:1077E00010B5FFF7EAFF054902200870E8F7A2FD8F +:1077F0004FF0FF3010BD012070470000A4081000BA +:10780000A8081000AC081000B0081000B408100060 +:1078100070B50D460446C1698068CC2202F0F6F8C6 +:10782000E169A068002208444FF0807140F8041C10 +:10783000216A40E9032140F8102C40F8142C40F84C +:10784000182C40F81C2C4FF00B3140E909154FF073 +:107850000A3140F8281C4FF0093140F82C1C4FF039 +:10786000083140F8301C4FF0073140F8341C4FF01D +:10787000063140F8381C4FF0053140F83C1C4FF001 +:10788000043140F8401D70BD81694FF0CC330A6867 +:107890009A4208D14A689A4205D18A689A4202D12E +:1078A000C968994202D04068FCF70BBB70470000E2 +:1078B00010B5A021494802F0D3F8002010BD70B5E2 +:1078C0000646464800EB0614E8F788FD0546207892 +:1078D00028B12846E8F78AFD6FF0010070BD03204B +:1078E000207000206660E06004F1080001F0DAFE1C +:1078F0002846E8F77BFD002070BD2DE9F0410F46DA +:107900003649002501EB00142E46E8F767FD804656 +:10791000E0683843E06004F10800074601F0E8FE43 +:107920000CE0E168C26A114203D000F00FF90126B1 +:1079300000E06D1C2946384601F0D0FE0028F0D149 +:107940000EB1FFF73AFF4046E8F750FD0020BDE8D2 +:10795000F08170B50D46214901EB0014E8F73EFDBA +:10796000E168A943E160E8F741FD002070BD70B512 +:107970000C461A4901EB001500202060E8F72EFDA7 +:10798000E9682160E8F732FD002070BD2DE9F04183 +:107990000D4612491E46904601EB0014E8F71EFD05 +:1079A00007460F480068C562E168294203D104F127 +:1079B000080100F0DDF83846E8F718FDE8F70EFD9D +:1079C000E16829403160B8F1010F02D1E168A943B3 +:1079D000E160E8F70BFD0020B9E700003C9D1000D6 +:1079E000A808100010B5C8212E4802F039F8002070 +:1079F00010BD2DE9F04106462A4900EB86001746E6 +:107A000001EB8004E8F7EAFC0546207830B128460F +:107A1000E8F7ECFC6FF00100BDE8F0810220207077 +:107A200000206660C4E9027004F1100001F03AFE23 +:107A30002846E8F7DBFC0020EEE770B5194900EBBB +:107A4000800001EB8004E8F7C9FC0546D4E9020197 +:107A5000814205DB144804F11001006800F088F849 +:107A6000E068401CE0602846E8F7C0FC002070BDDC +:107A700070B50C4900EB800001EB8004E8F7AEFC28 +:107A80000546E06808B1401EE06004F1100001F016 +:107A90002FFE10B1206900F011F82846E8F7A6FC87 +:107AA000002070BDDC9D1000A808100010B54FF438 +:107AB000F0713C4801F0D4FF002010BD10B5044621 +:107AC00090F8240002280BD0204601F013FE02207B +:107AD00084F824003449204601F0E8FDFFF76DFEEC +:107AE000002010BD2DE9F05F06460AA806EB46010E +:107AF00090E8000E2B481D4600EB011490462078BC +:107B000018B16FF00100BDE8F09FE8F767FC074689 +:107B100001202070C4F81480C4E9016504F1180143 +:107B2000002081E8200684F82400E0602061C4E998 +:107B30000A8059462046FFF76BFEA0602046FFF7FB +:107B4000BDFF3846E8F752FC0020DCE710B50446DC +:107B500090F82400022809D0204601F0CBFD022035 +:107B600084F824001049204601F0A0FD002010BD3B +:107B700070B5044690F824000D4602280BD120462B +:107B800001F0B8FD032084F824002946204601F0C6 +:107B90008DFDFFF712FE002070BD044800684068AC +:107BA00070470000A49E1000B0081000A808100044 +:107BB000724810B500210160012202600160704C22 +:107BC0006920A0710420E8F71BFC0820A07110BDFB +:107BD00010B5FFF7EDFF6B4800210170416000F028 +:107BE0001CFABDE8104000F012BB01F049BC01F0E6 +:107BF00097BC10B501F094FC01F042FCBDE81040C8 +:107C0000E6E7A422604901F08ABE704710B5044639 +:107C1000800702D00220FFF761FB4FF48030204440 +:107C2000C0F34F0010BD014655489822A43001F022 +:107C300076BE534AA432002142F82100491C26296D +:107C4000FADB704701F04ABC01F0E4BB4D4810B5C7 +:107C5000406810B1BDE8104000470020FFF73EFB30 +:107C600010BD062937D2DFE801F01124372436038E +:107C7000017821F0120100F84D1B017821F0030179 +:107C800000F8071B017821F080010CE0017821F059 +:107C9000020141F0100100F84D1B017821F00301B1 +:107CA00000F8071B12E000F8441B017821F00101E5 +:107CB00010E00278012942F01202027000D0032184 +:107CC00010F84D2F61F3010200F8072B017841F005 +:107CD0008001E8E701707047017821F0020141F06E +:107CE000100100F84D1B017821F00301891C00F8F8 +:107CF000071B017841F0800100F8441B017841F036 +:107D00000101E7E790F82920022904D0032922F095 +:107D1000400102D104E042F0400121F0800101E085 +:107D200041F0800180F82910704790F8292001293E +:107D300004D0022907D022F0100101E042F0100126 +:107D400021F0200101E042F0300180F82910704755 +:107D5000C278002961F30302C27004D010F85E1FDC +:107D600041F0040101707047C27A012961F30302F6 +:107D7000C27202D942F01001C17270479004002211 +:107D80000000032054081000F49E010001EB810163 +:107D900002EBC101405C010602D500F07F004042C9 +:107DA0007047002B04DA5B42DBB243F0800301E052 +:107DB00003F07F0301EB810102EBC10143547047E3 +:107DC0002DE9F05F0025DDE90A7891469A46834661 +:107DD0002E462A460120002101F057FD00EA090045 +:107DE00001EA0A01084314D00024224601200021A0 +:107DF00001F04BFD384001EA0801084305D000239B +:107E0000224631465846FFF7CCFF641C282CECDB99 +:107E1000761C6D1C382DDCDBBDE8F09F405C010654 +:107E200002D500F07F0040427047002A04DA524237 +:107E3000D2B242F0800201E002F07F024254704769 +:107E4000F0B5002415460E468446234601270FE070 +:107E500006EBE30003F00701007807FA01F20242A3 +:107E600005D0002219466046FFF7DFFF641C5B1C4B +:107E7000AC42EDDBF0BD405C704742547047F0B55A +:107E80000024234601260DE001EBE30503F007077C +:107E90002D7806FA07FC1CEA050F02D00025C55410 +:107EA000641C5B1C9442EFDBF0BD405C70474254A5 +:107EB0007047405C70474254704700002DE9F0471E +:107EC000334C54F83C8F6768E668257CDFF8C49033 +:107ED0000121C9F800104FF42070E8F791FA002151 +:107EE000C9F80010C4F800806760E6602574BDE83A +:107EF000F08727480021C1630164816480F84C1039 +:107F0000704770B500240D4602460120214601F05D +:107F1000BCFC35B31E4A483210601171FFF7CEFF2A +:107F2000002000F023F800B10124FFF7C7FF012073 +:107F300000F01CF808B144F00204FFF7BFFF022074 +:107F400000F014F808B144F00404FFF7B7FF032071 +:107F500000F00CF808B144F00804FFF7AFFF20462A +:107F600070BD0B4A3C32C2E90001D7E740F0200166 +:107F7000074810B580F8A310E52181714FF42070F7 +:107F8000E8F73EFA0448D0F8C002C0B210BD0000C5 +:107F900000000320681460220010602258484168E5 +:107FA000002901D001200847704710B5FFF71FFED8 +:107FB0005449022008705449002008605048416824 +:107FC000002903D0BDE810400020084710BD10B5BF +:107FD000817921F00D0141F0E0018171817C8A09F4 +:107FE00019D08A0962F38711464A817403211170FE +:107FF000454A464911600146A422454801F08FFCDC +:1080000044490120C1F8C0003D4843490088BDE80B +:108010001040FFF717BE0122E4E739480021416014 +:108020004FF4FA71018070477FB504460399089DAB +:10803000C1F314010391082102A800F06FFA012D89 +:1080400002D0022D04D006E0C01C20F0010002E0A6 +:10805000C01D20F00300DDE9021244F83C1F6260FD +:10806000217A60F3060121727FBD012340F83C3F75 +:10807000002343605143027A61F3060202727047A3 +:108080001FB50446039902A801F03F01039108219E +:1080900000F044FADDE90212A16484F84C2014F8DF +:1080A000701F60F3050104F81E19E17F60F30501FC +:1080B000E1771FBD08B519A2126800921DF80120D2 +:1080C00010F85D1F62F30101017008BD0D49032026 +:1080D00008700D490D4808600E490120C1F8C00024 +:1080E00007480D490088FFF7ADBD054A51604FF4C0 +:1080F000FA7111806BE7024B59601A8067E7000044 +:108100005C08100054081000580810005B7F010044 +:1081100000000320000060224D7F010000010200EA +:1081200016480178012908D102210170144801681C +:1081300019B100220260104608470120FFF7CEB8AF +:108140000E4A012111700E4908600E49E82088711D +:108150000D490C20FFF778BD0A49082088710B49AA +:108160000020086205490870054908607047034807 +:108170000078002800D0012070470000540810004B +:108180006408100000000320D1800100000060227C +:108190006A484168002901D001200847704710B59E +:1081A000FFF725FD66490220087066490020086037 +:1081B00062484168002903D0BDE81040002008470C +:1081C00010BD10B5817C8A091FD08A0962F387111E +:1081D000817481795A4A21F0010141F0E0018171F5 +:1081E00004211170574A584911600146A42257488A +:1081F00001F095FB56490120C1F8C0004F48554990 +:108200000088BDE81040FFF71DBD0122DEE74B48A6 +:10821000002141604FF4FA71018070477FB5044638 +:108220000399089DC1F314010391082102A800F0ED +:1082300075F9DDE90212E163226494F84420C1B2C9 +:1082400061F3060284F844200A2D0FD00B2D0DD0C7 +:1082500014F8720F61F305002070607861F3050077 +:108260006070A07820F00800A0707FBD14F8721F25 +:10827000401C60F305012170617860F305016170B5 +:10828000A07840F00800EFE71FB50446039902A864 +:1082900001F03F010391082100F040F9DDE90212ED +:1082A000A16484F84C2014F8701F60F3050104F8F1 +:1082B0001E19E17F60F30501E1771FBD30B526A2ED +:1082C0008CB03CCA8DE83C0027A20DF1100C3CCAD2 +:1082D0008CE83C0028A20DF1200C3CCA8CE83C0044 +:1082E00004AA535C427E63F3050242761DF8013016 +:1082F000027E63F34202027608AA525C817962F33D +:10830000830181710CB030BD0D49042008700D4906 +:108310000D4808600E490120C1F8C00007480D490A +:108320000088FFF78FBC054A51604FF4FA71118045 +:1083300047E7024B59601A8043E7000068081000C5 +:1083400054081000580810004F810100000003205D +:1083500000006022418101000000020201010303CC +:1083600003030002000000000202020202020202F5 +:1083700001010202010100000203020302030203E1 +:1083800002030202020300004E4901200860172286 +:10839000410701F8272F0B2281F84120494918395C +:1083A00008604FF00851C1F8C403464B0022B033B7 +:1083B0001A60454A1060121D1060424A943A1060DB +:1083C000C1F86803C1F8740370473E49012094392D +:1083D000086070473B4900209439086070474FF0AF +:1083E0000050008870474FF00050807870474FF081 +:1083F000005148607047354902680A6042684A6027 +:1084000080688860704731490A6802604A68426043 +:108410008968816070472B490120303908607047B6 +:108420004FF0005010F8221F21F003010170704737 +:108430004FF0005303F81F0F5970987862F3030050 +:10844000987070472248006870472149086070475B +:1084500010B54FF00054E27E202322F0AF0203EA71 +:1084600040131343042202EA8000034301F0030097 +:108470000343E37610BD4FF0005090F8220010F057 +:10848000030005D0012805D0022805D01148704707 +:10849000114870471148704711487047704770473E +:1084A00010490120C1F8DC0070470E490020C1F8D6 +:1084B000DC0070470348F030006808B101207047C5 +:1084C00002207047CC040022801E002208000020F9 +:1084D0007008100000127A000090D0030048E801F4 +:1084E0000024F40000006022F0B507460020034697 +:1084F0002F4E10E057F8235003224FEAC20C45FAE2 +:108500000CF484EA2064E4B2521E56F8244084EA53 +:108510000020F2D55B1C8B42ECDBF0BD30B504468D +:10852000234B0020103B08E0625C02F00F0503EBD8 +:1085300012125D5D127828441044491EF4D230BDF9 +:1085400010B584680368E443A3420AD1C468436851 +:10855000E443A34205D15B1C0B600068106001205E +:1085600010BD002010BD3CB50446002501AA694697 +:10857000FFF7E6FF012809D1009904F11000091F57 +:10858000FFF7B2FF0199884200D1012528463CBD82 +:1085900030B50D460446091F1030FFF7A5FF6D1ECC +:1085A0006560E943E1602060C043A06030BD000029 +:1085B000A89F010001468000B1F5803F02D210382B +:1085C000C0F310007047C0F387207047B0F5802FCC +:1085D00002D21030C0F31000C0F38F00704730B5E6 +:1085E000F94C01252560E50603F01F0385F86B3083 +:1085F000002304E051F8235040F823505B1C9342C1 +:10860000F8DB0020206030BDF0B5EF4F01233B6068 +:108610005C0784F86B309B1E0360002312E051F866 +:10862000234040F82340002450F8235051F82360A1 +:10863000B54206D06D1C04D1641C40F82360032CA5 +:10864000F2D35B1C9342EADB00203860F0BDF0B54A +:1086500013460A460546002498184FF483266028DE +:1086600001D9012411E0002107E05F1856F8270026 +:10867000401C01D011460224491C9142F5D324B973 +:1086800006EB83002946FFF7BFFF2046F0BD10B57B +:1086900003460846FFF78EFF0146BDE810409200F2 +:1086A000184601F081B92DE9F0414FF000580C4611 +:1086B000D8F814700125C0F38F066FF48041C8F814 +:1086C00014100E2000F02EFA204600F036FA0200B8 +:1086D000BE484FF0010118D00160A4F58034404637 +:1086E00020F8726F4480602200F8012CB84A1160B3 +:1086F000B64AC432116030BF81797238890700D020 +:10870000002547612846BDE8F08100220260E6E7C7 +:108710002DE9F05F1546DFF8B0B2002601270A46C2 +:1087200004464FF0005CB1F5882F15D3A30AFFF77C +:1087300041FF5946CBF8007003F01F038CF86B30F3 +:10874000002304E052F8234040F823405B1CAB4276 +:10875000F8DB0E60BDE8F09FDCF81490C1F38F08E1 +:10876000E2466FF48041CCF814100E2000F0DAF9E4 +:10877000CBF80070204600F0E0F90100934819D0D2 +:108780000760A4F58034AAF87280AAF874406D1EC0 +:10879000AAF8765040218AF871108D490E608B49F5 +:1087A000C4310F600AF1520030BFCBF8006040F8CE +:1087B0003E9CCFE70660E6E72DE9F0414FF000541C +:1087C0000F4654F8146F85086FF4804020600E2027 +:1087D00000F0A8F90020A066A4F85E507F1EA4F85F +:1087E000627084F85D007A49086078490120C431DC +:1087F000086030BFE06E266085E770B506460C461F +:1088000001F11000111F154689B2FFF7D5FF206056 +:10881000681E606020682A46C043A06060682146E8 +:10882000C043E0603046BDE8704071E7F0B50746F0 +:1088300000200446674E15E057F8245003234FEA02 +:10884000C30C45FA0CF280EA02600822002802DA22 +:1088500086EA400000E04000521E002AF6DC5B1E63 +:10886000EDD5641C8C42E7DBF0BD30B550F8084B09 +:1088700050F8085B30F80C1C491C89B2FFF7D6FF92 +:10888000844204D1E043854201D1012030BD002063 +:1088900030BD2DE9F0410126750704466F696FF47C +:1088A000804068610E2000F03DF94FF00008C5F8E7 +:1088B0007C80204600F041F9020044494FF001005D +:1088C00015D00860A4F58034A5F87440202185F8FF +:1088D00071103F4908603D49C431086030BF95F8C8 +:1088E0007800800700D000266F6130460BE7C1F8A2 +:1088F0000080E9E700B50B46FFF75CFE826801687F +:10890000D243914208D14268C068C043824203D139 +:10891000521C1A80012000BD002000BDF8B504469D +:1089200010300D460646FFF7BEFE012801D000209C +:10893000F8BD69462846FFF7DDFFBDF80000001FBF +:1089400081B23046FFF738FF2060BDF80010C04309 +:10895000491E6160A060C843E0600120F8BD2DE9B8 +:10896000F041B0B01C4C80466E46002505AFC021DA +:10897000684601F075F8002054F8201046F82010E1 +:10898000401C3028F8D31549009804F580548842DB +:1089900010D1029881B23846FFF748FF0199814211 +:1089A00006D1AC223946404600F0FEFF002002E02E +:1089B000032000E001206D1CEDB2032D01D203283D +:1089C000D5D030B09FE60000C41B0022780D0022F5 +:1089D0001C0F00221B000080481D0400B2570E70BF +:1089E0002DE9F04794B0584D00260446E846374636 +:1089F00045F2AA5A6FF002095021684601F030F89A +:108A0000002055F8202048F82020401C1428F8D3D6 +:108A10004E49009805F5805588420ED14FF0FF3041 +:108A200020606060A060E0602061029881B205A8CB +:108A3000FFF7FCFE019981420AD0C4F80090C4F807 +:108A40000490C4F80890C4F80C90C4F810901EE08C +:108A5000BDF83810504681420CD19DF81D102160A0 +:108A60009DF81C1001F00F0161609DF81E1001F0CF +:108A70000F01A160BDF83C10814201D10899E1606D +:108A8000BDF84010514501D1099820610127761C9D +:108A9000F6B2032E01D2002FAED014B0BDE8F0879D +:108AA00070B586B0284E04466D46B436142128466B +:108AB00000F0D6FF002156F8210045F82100491C9E +:108AC0000529F8D300982060019860600298C0B230 +:108AD000A0600398C0B2E0600498C0B2206106B004 +:108AE00070BD1CB50020184A009030326B4601461C +:108AF000019052F8214043F82140491C0229F8D343 +:108B0000BDF80010A1F5AA42AA3A0AD1BDF8042086 +:108B1000114206D19DF802109DF80620114200D1A5 +:108B200008461CBD00F01F02012191404009800051 +:108B300000F1E020C0F880127047B0F5803F01D20C +:108B40000020704701207047AC1E04005C000D60DF +:108B50004FF00050002180F83D1080F83E1080F862 +:108B60003F103F2280F8322000F8301F027141711F +:108B70004270017241728172C172C17170474FF0CF +:108B80000052062817D2DFE800F00306090F171A73 +:108B900012F83D0F04E012F83D0F07E012F83E0F07 +:108BA00020F00F00084305E012F83E0F20F0F0001F +:108BB00040EA01101070704712F83F0FF0E712F80A +:108BC0003F0FF3E730B50D4601218140CCB20021C3 +:108BD000FFF7D5FF29784FF00050002990F83210A8 +:108BE00001D0214300E0A14380F8321069780029C8 +:108BF00090F8301001D0214300E0A14380F83010FC +:108C0000A978002990F8341001D0214300E0A14355 +:108C100080F83410E978002990F8351001D021430C +:108C200000E0A14380F835102979002990F831102F +:108C300001D0214300E0A14380F83110002180F8E9 +:108C4000381080F8391080F83A1080F83B1080F81E +:108C5000371030BD774A1160764A002134321160F6 +:108C6000121D08B11160704701201060704730B5C7 +:108C700001248440E0B24FF000540029039D94F891 +:108C8000321001D0014300E0814384F8321094F89F +:108C900030100AB1014300E0814384F8301094F8A9 +:108CA00034100BB1014300E0814384F8341014F810 +:108CB000351F0DB1014300E08143217030BD012318 +:108CC0008340D8B24FF00053002993F8381001D0F8 +:108CD000014300E0814383F8381013F8391F0AB1CB +:108CE000014300E081431970704701238340D8B2EB +:108CF0004FF00053002993F83A1001D0014300E0EF +:108D0000814383F83A1013F83A1F0AB1014300E097 +:108D10008143197070472DE9F04705460120A840AE +:108D2000C4B21F46914688460A20DDF820A000F014 +:108D30006BF80B2000F068F80A2000F070F80B20A8 +:108D400000F06DF84FF0005696F83800A04386F812 +:108D5000380096F83A00A04386F83A0096F82E00BC +:108D6000A04386F82E00344A0020B8F1000F42F8E4 +:108D700025000BD096F83810214386F8381096F865 +:108D80003A10214386F83A1042F8257096F83910C7 +:108D9000A14386F8391096F83B10A14386F83B10A2 +:108DA00096F82F10A14386F82F1023492031B9F1EE +:108DB000000F41F825000BD096F83900204386F8C3 +:108DC000390096F83B00204386F83B0041F825A087 +:108DD00096F8380010B10A2000F00BF896F8390028 +:108DE000002804D0BDE8F0470B2000F002B8BDE831 +:108DF000F08700F01F02012191404009800000F13E +:108E0000E020C0F80011704700F01F0201219140DE +:108E10004009800000F1E020C0F88011704700F0A8 +:108E20001F02012191404009800000F1E020C0F8BC +:108E3000801270470405002284A010002DE9F0473D +:108E4000417ACA074FF0000101D0554A516001270D +:108E50007D0785F8E57085F8E470C5F8C010C5F8A1 +:108E6000E81085F8E11085F8E310DFF838A1067AFC +:108E700004680AF10709072E00D9072600216DE0D2 +:108E80004A1CD3B201EB810214F802800AF8018077 +:108E9000D0F804C022443CF8118029F8118092F8DF +:108EA00003C0BCF1010F02D0BCF1030F07D195F84C +:108EB000E5C007FA03F84CEA080C85F8E5C090F81D +:108EC00009C05FEACC7C0FD192F803C0BCF1020F5D +:108ED00002D0BCF1030F07D195F8E4C007FA03F8FC +:108EE0004CEA080C85F8E4C001EB410C21F00108C4 +:108EF000E04492F801C00CF0070C0CFA08FCD5F81D +:108F0000C0804CEA080CC5F8C0C092F802C04FEA15 +:108F100081080CF00F0C0CFA08FCD5F8E8804CEA3C +:108F2000080CC5F8E8C090F809C05FEACC7C14D101 +:108F30001279D20707D095F8E12007FA03FC42EA3C +:108F40000C0285F8E1202279D20606D595F8E320B7 +:108F500007FA03F31A4385F8E320491CB1428FD383 +:108F6000D5F8E8006864BDE8F0870E4AD21D22F803 +:108F70001010704710B504460B48006838B1A0685F +:108F8000FFF75CFF2068BDE8104000F00FB8E06814 +:108F9000FFF754FF6068BDE8104000F0C1BB00005F +:108FA00000200022AB000020BC05002210B5494B78 +:108FB0000168002499608188598002899A801C7018 +:108FC0004FF00053A3F81A21A3F81E11C088A3F88C +:108FD000200141480122C0F8D821C0F8DC21C0F8A6 +:108FE000C421C0F8CC21C0F8D42172B6D0F8081240 +:108FF0000029FBD1426062B610BD2DE9F041364D2B +:10900000D5F85C01334F2E040124BA6840B3B6F89A +:109010001C815FEA08000CD0D5F8540148B14146E4 +:1090200001209047C5F8D842D5F8540108B1C5F8D9 +:10903000D442BA684146022090470178022902D002 +:10904000032902D008E0418800E07988A6F81E11C3 +:109050008088A6F81A013C70C5F8DC42BDE8F081B2 +:10906000D5F8440180B1B6F81C1103209047387838 +:1090700038B17888A6F81E01B888A6F81A01002031 +:109080003870C5F8C442E9E7D5F8580130B1B6F8F0 +:109090001C1101209047C5F8D842DFE7D5F84C01F4 +:1090A00018B9D5F854010028D8D0B6F81C1119B158 +:1090B00001209047C5F8D842D5F84C0110B1C5F849 +:1090C000CC42CBE7D5F854010028C7D0C5F8D4422C +:1090D000C4E700007408100000200022FC490020B2 +:1090E0000860091D0860091D0860091D0860091D48 +:1090F0000860091D0860091D0860091D0860F54920 +:1091000001220A60F34914310860510701F8500F39 +:10911000FF234B7001F8050C10234B808A80EE4929 +:10912000086048608860C860086148618861C861FB +:10913000086270477047E84A1160E54900220A60FA +:1091400000EB80004FF6FF7202EA40004FF0005241 +:10915000A2F85800012008607047DF4B10B5DC4AC8 +:109160001960002111604FF0005191F85140E4075F +:1091700007D01B6A58438009A1F8580001201060ED +:1091800010BD00EBC00303EB00104FF6FF7303EAC2 +:109190008000F1E74FF00050B0F858007047CC491C +:1091A000002008607047CC4A10B50021106811609B +:1091B000C74A116010B1BDE8104000470020FFF71A +:1091C000B9FF10BDC44A5160C1490022091D0A609F +:1091D00000EB80004FF6FF7202EA4000CA06A2F8D8 +:1091E0005A00012008607047BB4B10B55960B84A5F +:1091F0000021121D1160D10691F85140A40708D436 +:1092000000EBC00303EB00104FF6FF7303EA80008E +:1092100002E01B6A58438009A1F85A00012010603F +:1092200010BD4FF00050B0F85A007047A849002018 +:10923000091D08607047A84A10B5002150685160A8 +:10924000A34A121D116010B1BDE810400047012073 +:10925000FFF770FF10BDA04A91609D4900220831C0 +:109260000A6000EB80004FF6FF7202EA40008A06B7 +:10927000A2F85C00012008607047974B10B5996018 +:10928000934A002108321160910691F85140640719 +:1092900008D400EBC00303EB00104FF6FF7303EAA2 +:1092A000800002E01B6A58438009A1F85C0001209D +:1092B000106010BD4FF00050B0F85C00704784495A +:1092C0000020083108607047834A10B5002190687B +:1092D00091607F4A0832116010B1BDE8104000472C +:1092E0000220FFF727FF10BD7B4AD160784900229A +:1092F0000C310A6000EB80004FF6FF7202EA40007A +:109300004FF00052A2F85E00012008607047724BD7 +:1093100010B5D9606E4A00210C3211604FF0005137 +:1093200091F85140240708D400EBC00303EB001070 +:109330004FF6FF7303EA800002E01B6A584380097E +:10934000A1F85E000120106010BD4FF00050B0F891 +:109350005E0070475E4900200C31086070475E4A2D +:1093600010B50021D068D160594A0C32116010B19B +:10937000BDE8104000470320FFF7DCFE10BD564A51 +:1093800011615349002210310A6000EB80004FF652 +:10939000FF7202EA40004FF00052A2F86000012084 +:1093A000086070474C4B10B51961494A00211032D2 +:1093B00011604FF0005191F85140E40608D400EBE1 +:1093C000C00303EB00104FF6FF7303EA800002E0D6 +:1093D0001B6A58438009A1F860000120106010BD8D +:1093E0004FF00050B0F8600070473949002010314C +:1093F00008607047384A10B5002110691161344A7D +:109400001032116010B1BDE8104000470420FFF792 +:1094100091FE10BD304A51612D49002214310A607D +:1094200000EB80004FF6FF7202EA40004FF000525E +:10943000A2F86200012008607047274B10B55961FF +:10944000234A0021143211604FF0005191F851402D +:10945000A40608D400EBC00303EB00104FF6FF7323 +:1094600003EA800002E01B6A58438009A1F8620009 +:109470000120106010BD4FF00050B0F8620070473E +:1094800013490020143108607047134A10B50021B9 +:10949000506951610E4A1432116010B1BDE810409C +:1094A00000470520FFF746FE10BD0B4A91610849B1 +:1094B000002218310A6000EB80004FF6FF7202EACA +:1094C00040004FF00052A2F864000120086070478D +:1094D00040090022C0040022800810006A4B10B529 +:1094E0006A4A9961002111604FF0005191F8514092 +:1094F000640608D400EBC00303EB00104FF6FF73C3 +:1095000003EA800002E01B6A58438009A1F8640066 +:109510000120106010BD4FF00050B0F86400D6E795 +:109520005A4900200860D2E7574A10B500219069D7 +:109530009161564A116010B1BDE810400047062005 +:10954000FFF7F8FD10BD10B5FEF77CFF4FF000519E +:1095500091F8222042F21073B0FBF3F0C2F38102C3 +:10956000521CD040B1F85420C96C51438909B0FB5A +:10957000F1F010BD45490022091D0A60424A126AF5 +:1095800050434FF000528009A2F8660001200860A5 +:109590009DE73E490020091D086098E73A49C861E7 +:1095A0003B490120C1F8DC003849A0310860091DA1 +:1095B00008608CE7344A10B50020D169D061344A84 +:1095C000C2F8DC0051B1314AA03210604FF00050B7 +:1095D000C06CBDE8104020F07F400847FF20FFF737 +:1095E000A9FD10BD10B50446FEF72CFF4FF0005149 +:1095F00091F8221042F21072B0FBF2F0C1F3810137 +:10960000491CC8400003B0FBF4F01F49086210BDBC +:1096100030B54FF000550124844095F8510009B150 +:10962000204300E0A04385F8510095F84B000AB1B3 +:10963000204300E0A04385F84B0015F8500F0BB114 +:10964000204300E0A043287030BD4FF0005010F8D8 +:109650004A1FC079814301D0012038E7002036E756 +:109660004FF0005090F82200C0F3810028B101288B +:1096700005D0022805D0074829E7074827E707480B +:1096800025E7074823E7000080081000580900225A +:109690000000602200093D000048E8010024F400B9 +:1096A00000127A00002101600846704730B50A6850 +:1096B00012B10B46846A08E000220860C0E9032169 +:1096C0000AE002F10C03D26812B1956AA542F8DCF7 +:1096D0001A68C0E903211860002030BD006800222C +:1096E00001E0C068521C8A4201D00028F9D17047BD +:1096F0000068704702690AB1116831B96FF004005F +:10970000704701F10C02C96839B18142F9D1C968C9 +:10971000116000210161084670476FF00300704737 +:10972000017C31B14FF0005111F82D2F42F00202AF +:109730000A70194902680A6042684A6082688A6051 +:10974000C068C860704730B44FF0005111F8E00FA6 +:109750000A8AC968104BC40708D09B68002B0BD03D +:10976000A2F57F44FF3C07D030BC1847DB68002BD4 +:1097700002D0521C92B2F7E730BC70474FF0005055 +:1097800090F8E2000449C20701D0096800E0496886 +:10979000002900D008477047B808100053EA020CAF +:1097A00000F069802DE9F04B4FF00006002B1FBF41 +:1097B000B3FA83F503FA05F424FA05F65E4012BF06 +:1097C0001643B2FA82F502FA05F4C5F120051EBF70 +:1097D00022FA05FC44EA0C04203556EA044C4FEA10 +:1097E000144418BF641C4FF000084FF00009904269 +:1097F00071EB030C39D3002919BFB1FA81F701FAD3 +:1098000007F6B0FA80F700FA07F6C7F120071EBF87 +:1098100020FA07FC46EA0C062037B6FBF4FCA7EB5F +:109820000507103F07F01F0BCBF120060CFA0BFBCE +:109830002CFA06F644BFB3460026202FA4BF5E468E +:109840004FF0000B5BEA060C08BF4FF0010B19EB61 +:109850000B09ABFB027C48EB0608C01B06FB02CCE5 +:109860000BFB03CC71EB0C01C1E70B4602464146F2 +:109870004846BDE8F08B13B54FF000004FF00001F3 +:10988000AFF30080BDE81C407047B2F120030AD559 +:10989000C2F1200301FA02F120FA03F300FA02F008 +:1098A00041EA0301704700FA03F14FF000007047EE +:1098B000B2F120030AD5C2F1200320FA02F001FA26 +:1098C00003F321FA02F140EA0300704721FA03F0A2 +:1098D0004FF00001704710B54C1084EA530404D5D2 +:1098E0004042C1F1000138BF491E1B4204D552421B +:1098F000C3F1000338BF5B1EFFF750FF14F0804F29 +:1099000004D04042C1F1000138BF491E14F0004F9D +:1099100004D05242C3F1000338BF5B1E10BD032ABE +:1099200040F2308010F0030C00F0158011F8013B7C +:10993000BCF1020F624498BF11F801CB00F8013B63 +:1099400038BF11F8013BA2F1040298BF00F801CB27 +:1099500038BF00F8013B11F0030300F02580083AFE +:10996000C0F0088051F8043B083A51F804CBA0E855 +:109970000810F5E7121D5CBF51F8043B40F8043BAA +:10998000AFF30080D20724BF11F8013B11F801CBDF +:1099900048BF11F8012B24BF00F8013B00F801CBB0 +:1099A00048BF00F8012B704710B5203AC0F00B807B +:1099B000B1E81850203AA0E81850B1E81850A0E8D3 +:1099C0001850BFF4F5AF5FEA027C24BFB1E818502D +:1099D000A0E8185044BF18C918C0BDE810405FEA9D +:1099E000827C24BF51F8043B40F8043B08BF704719 +:1099F000D20728BF31F8023B48BF11F8012B28BF1E +:109A000020F8023B48BF00F8012B704702F0FF032B +:109A100043EA032242EA024200F002B84FF0000299 +:109A20000429C0F0128010F0030C00F01B80CCF170 +:109A3000040CBCF1020F18BF00F8012BA8BF20F8DE +:109A4000022BA1EB0C0100F00DB85FEAC17C24BF32 +:109A500000F8012B00F8012B48BF00F8012B7047DC +:109A60004FF0000200B5134694469646203922BFB7 +:109A7000A0E80C50A0E80C50B1F12001BFF4F7AF02 +:109A8000090728BFA0E80C5048BF0CC05DF804EBE4 +:109A9000890028BF40F8042B08BF704748BF20F852 +:109AA000022B11F0804F18BF00F8012B704710B542 +:109AB0000446AFF300802046BDE81040E6F7AEBB99 +:109AC00001491820ABBEFEE72600020070470000E7 +:109AD0000149002008607047380500222DE9F04157 +:109AE0000F4F00244FF001084FF0005608FA04F021 +:109AF000C5B296F82F0028420CD096F839002842BB +:109B000008D057F8240000B1804796F82F00A843EA +:109B100086F82F00641C062CE8DBBDE8F08100000D +:109B2000A4A010002DE9F0410F4F00244FF00108D0 +:109B30004FF0005608FA04F0C5B296F82E002842FD +:109B40000CD096F83800284208D057F8240000B10D +:109B5000804796F82E00A84386F82E00641C062C39 +:109B6000E8DBBDE8F081000084A01000014901207D +:109B7000086070473805002200487047E907100068 +:109B80000549044A0A80054AC0E900210121017201 +:109B9000417270471C5701208C071000B49D0100D2 +:109BA0000148007870470000B406100001480078B2 +:109BB000704700009805100006488178012905D8F3 +:109BC0000178012902D84078012801D90120704785 +:109BD000002070479C26012070B5D0E90012530880 +:109BE0004FEA31044E1842EB020534432B430C4339 +:109BF0001343C0E9004370BD01EB810100EBC100DC +:109C000029307047024A1278514300EB41007047F7 +:109C10002807100001EB810100EBC10029307047DB +:109C2000024A1278514300EB4100704728071000A8 +:109C3000010000001000000004000000010000000E +:109C40003200000032000000FFFF000000FF0100B2 +:109C5000FF000001000001015AD3D9E96CF145F57C +:109C60009FF73CF96CFA58FB18FCB9FC44FDBFFDAA +:109C70002EFE94FEF4FE50FFA9FF00005700B00036 +:109C80000C016C01D2014102BC024703E803A804A5 +:109C90009405C4066108BB0A940E2716A62C010081 +:109CA00001000100010002000100010001000100AB +:109CB0000A00FF00FF000000000101010202000095 +:109CC000000000009C531000E8581000AD2801006F +:109CD00002000000B1280100020000003B2A010040 +:109CE000020000007928010002000000E9290100BB +:109CF000010000003B29010007000000DB280100F3 +:109D0000090000000B2A010001000000F7280100F3 +:109D100008000000732A0100010000007D280100F6 +:109D2000E72A0100E32A0100E92B0100E32A0100F0 +:109D3000332D0100E32A0100E32A0100E32A010098 +:109D4000E32A0100E32A0100332B01000100000097 +:109D5000612B010000000000E32A01000000000068 +:109D60007F2B010001000000192C01000100000000 +:109D70003D2C010001000000412C01000100000009 +:109D8000772C0100040000002F2D010001000000CD +:109D9000632D010001000000D72D0100010000002B +:109DA000ED2D010002000000492E0100020000001C +:109DB000932E010002000000BF2F010001000000EF +:109DC000FF2F0100010000008F2E010002000000A3 +:109DD000872F010002000000E32A010000000000BC +:109DE0005F2F0100020000007D2D0100572B0100B4 +:109DF000872D0100972D0100A72D0100B72D01002F +:109E0000C72D01008600020100A6020F0300A80270 +:109E10000B030000030000000000000053040000DA +:109E200000000000030000000000000053000000DC +:109E3000000000004300000000000000F3000000EC +:109E400000000000E30000000000000053020000DA +:109E50000000000000000000050000005884100011 +:109E6000000400004D3D0000000000000200000062 +:109E700001000000040000005888100000040000E9 +:109E8000B54C0000000000000200000002000000CD +:109E900003000000588C1000000800006726010035 +:109EA00000000000020000000300000002000000AB +:109EB0005894100000020000BD30010000000000B6 +:109EC000020000000400000001000000589610008D +:109ED00080000000E52701000000000002000000F3 +:109EE000000000000100000001000000010000006F +:109EF000020000000100000003000000010000005B +:109F00000400000001000000050000000100000046 +:109F1000000000000100000002000000030000003B +:109F2000CF750100D9640100895B010089640100DB +:109F3000DD610100676101003F6401008B71010078 +:109F4000E57501000004400010210000001F010021 +:109F50000600000030000100000406000802500066 +:109F600060020C0C000060020C300C1A31100F0F54 +:109F700000002F000100AA2C0100000003000000D7 +:109F8000FFFF03000000000018000000FFFFFFFFBC +:109F90003F00000000000000000100000000000081 +:109FA000600201800001000000000C000C000C00A9 +:109FB0000C00070126261212110000000038003C98 +:109FC000203DD041EC4108421C42304244426042B4 +:109FD00074428842A442000000000000000000001B +:109FE0000000000000000020000101020102020345 +:109FF0000102020302030304000000001B000080B2 +:10A000002D00008036000000410000805A00000052 +:10A010006C00000077000080990000808200000042 +:10A02000B4000000AF000080D8000000C300008032 +:10A03000F5000080EE0000002901008032010000E0 +:10A04000040100001F01008068010000730100800E +:10A05000450100805E010000B0010000AB010080FE +:10A060009D01008086010000F1010080EA010000EE +:10A07000DC010000C701008049020080520200009C +:10A08000640200007F0200800802000013020080CA +:10A09000250200803E020000D0020000CB020080BA +:10A0A000FD020080E6020000910200808A020000AA +:10A0B000BC020000A7020080600300007B03008058 +:10A0C0004D03008056030000210300803A03000086 +:10A0D0000C03000017030080F9030080E203000076 +:10A0E000D4030000CF030080B8030000A303008066 +:10A0F000950300808E030000890400809204000014 +:10A10000A4040000BF040080C8040000D304008041 +:10A11000E5040080FE040000100400000B04008031 +:10A120003D04008026040000510400804A04000021 +:10A130007C04000067040080A0050000BB050080CF +:10A140008D05008096050000E1050080FA050000FD +:10A15000CC050000D70500803905008022050000ED +:10A16000140500000F0500807805000063050080DD +:10A17000550500804E050000C0060000DB0600808B +:10A18000ED060080F6060000810600809A060000B9 +:10A19000AC060000B70600805906008042060000A9 +:10A1A000740600006F060080180600000306008099 +:10A1B000350600802E060000E9070080F207000047 +:10A1C000C4070000DF070080A8070000B307008075 +:10A1D000850700809E070000700700006B07008065 +:10A1E0005D07008046070000310700802A07000055 +:10A1F0001C07000007070080090900801209000001 +:10A20000240900003F09008048090000530900802C +:10A21000650900807E090000900900008B0900801C +:10A22000BD090080A6090000D1090080CA0900000C +:10A23000FC090000E7090080200800003B080080BE +:10A240000D08008016080000610800807A080000F0 +:10A250004C08000057080080B9080080A2080000E0 +:10A26000940800008F080080F8080000E3080080D0 +:10A27000D5080080CE080000400B00005B0B00807A +:10A280006D0B0080760B0000010B00801A0B0000A4 +:10A290002C0B0000370B0080D90B0080C20B000094 +:10A2A000F40B0000EF0B0080980B0000830B008084 +:10A2B000B50B0080AE0B0000690A0080720A000036 +:10A2C000440A00005F0A0080280A0000330A008068 +:10A2D000050A00801E0A0000F00A0000EB0A008058 +:10A2E000DD0A0080C60A0000B10A0080AA0A000048 +:10A2F0009C0A0000870A0080800D00009B0D0080F2 +:10A30000AD0D0080B60D0000C10D0080DA0D00001B +:10A31000EC0D0000F70D0080190D0080020D00000B +:10A32000340D00002F0D0080580D0000430D0080FB +:10A33000750D00806E0D0000A90C0080B20C0000AD +:10A34000840C00009F0C0080E80C0000F30C0080DF +:10A35000C50C0080DE0C0000300C00002B0C0080CF +:10A360001D0C0080060C0000710C00806A0C0000BF +:10A370005C0C0000470C0080C90F0080D20F000069 +:10A38000E40F0000FF0F0080880F0000930F008093 +:10A39000A50F0080BE0F0000500F00004B0F008083 +:10A3A0007D0F0080660F0000110F00800A0F000073 +:10A3B0003C0F0000270F0080E00E0000FB0E008025 +:10A3C000CD0E0080D60E0000A10E0080BA0E000057 +:10A3D0008C0E0000970E0080790E0080620E000047 +:10A3E000540E00004F0E0080380E0000230E008037 +:10A3F000150E00800E0E0000D8A30100000410000E +:10A40000C80400001C01000040A4010000FC100072 +:10A41000400000007801000040A40100C8081000BE +:10A42000FC9700009401000001FF014A0022501037 +:10A43000070C1502050609040E08030B1218130D6C +:10A440001416171A0F111B1D191C201E1F010A219B +:10A4500012FF3206320F9A37089AE10823D3031409 +:10A46000905F017201A908091A0CB264290C291421 +:10A470005A02040A11041001FF01620795F001203D +:10A480001C6210AAFF0C5901011D045490D0030056 +:10A4900030B572B601230C4D2B600C4A002481B1FB +:10A4A00013604FF0005100F01F0081F86A00074868 +:10A4B0001C38036001680029FCD114602C6062B66E +:10A4C00030BD1460EDE70000C01B0022780D0022B3 +:10A4D0008B2F6E735103000074D0918CAEFCFFFF84 +:10A4E000000004000303000004130000000000004B +:10A4F000FFFFFFFF1F000000FFFF01000000000042 +:10A500002511230937040B230937044402010300F2 +:10A510000320200AAA99FA00FA00B004C80000013A +:10A520000001000100017000700009C800C80000AF +:10A53000000000960096000000000003AA440200FC +:10A540000015050A190FF902320000000016001E5E +:10A55000000008000600000000A050502601350051 +:10A5600000000000130000000000960300006400DB +:10A570000000FF00E02E01FF0000000040500070CE +:10A580000032004000C80000000001640064006464 +:10A59000001000000000000000FFFF0000BDA00A46 +:10A5A0004F3500260025004B600600000000004BE0 +:10A5B00060160000000004014B024B06008D1108DC +:10A5C0004F0400300006002F00401006000000017C +:10A5D0000000A8606A1F20003600270050002600F7 +:10A5E000A023A0132D0066000000000000029600CA +:10A5F000960002050132190500001D04000000004C +:10A60000010000002D0000008F000000000000008D +:10A610000000000000010100003030008F00000049 +:10A6200000000000000000000001003001000000F8 +:10A63000000F0000000000000000111A00000000E0 +:10A6400000036402130A0403070B02023232000003 +:10A650000000000F0000000000FF0FFF0F0A141E93 +:10A660000E01640001016400001400000A005000A3 +:10A67000000000D00F149001900180008000F401D0 +:10A680000000FA086400640020000A6400640064AA +:10A6900000640003052C01F40100C2018A02640079 +:10A6A0009600031B039600FA00FA0001010100E87E +:10A6B00003DC05C800FA00020B02FA00F401F40101 +:10A6C000000101003B0164006400B4002C012C0176 +:10A6D00005FCA121025E01640096F4013200F40140 +:10A6E000960096006400010096009600030E640038 +:10A6F000200058023214001E2003042C0196000092 +:10A70000000000008F01100050004000A00000A4D5 +:10A710000F28009600C800320096002300C800C829 +:10A7200000C800F4012300500004100402010500D9 +:10A73000C800C4090000310010FF7F5E01A00FD0E7 +:10A7400002D0020807080708070000000000000008 +:10A750000D4220001012780096009D00000A000FA4 +:10A760006400411278009600C800C80000B004FAE6 +:10A770000096B80BE8030000000001006400070D1C +:10A780000DE803A000005E01645E016400000000AB +:10A79000250B01008A028A02408A02C201F40100EC +:10A7A00000000000000000000000000000000000A9 +:10A7B00000000000000000008C001E2803050202BB +:10A7C0000213115546000003C8006432001E0664DF +:10A7D0001E5E01012800F401FAF4010069F7EA00A5 +:10A7E000D4013801EA006400040C03320302400A79 +:10A7F000039C009C000F000F00109D004E00C8003D +:10A800000001010011000100101F00000A00149156 +:10A810001514001000061000060040000040001053 +:10A820000A0F0A200310EB0520D80532F80A32F887 +:10A830000000EAECECC4E810003000CBE80A001895 +:10A8400000C6F80A000A0051E4949418440700076F +:10A85000001000300002D73A7E2858026400C80079 +:10A8600000015A005A005000500001000015151553 +:10A8700015008164643C042C01401FE80390012F03 +:10A88000000405401F9001BC02B60301B603028814 +:10A8900013000000000000000000000000000000A5 +:10A8A0000300020A3C0001020F0F2323083C083C6E +:10A8B00040F805050A0A0105050F140000004E0CBA +:10A8C00009180C0C2222220000000000000A0014CB +:10A8D0000032006400BF08F1080F09190923092399 +:10A8E00009000000000A00140032006400D30305D0 +:10A8F0000423042D04370437040000000000000086 +:10A900000000000000000000000000000000000047 +:10A91000000100090020004500DD08070919091F92 +:10A9200009230923090000000002000A002800563C +:10A9300000E80314042C0434043704370400000036 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000800000000EE +:10AA6000000000000000000000000004000000A43E +:10AA700006000000000000000000000000000000D0 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000000000000000000076 +:10AAE0000000000000000000000000000000000066 +:10AAF00000A8A02A1F20003600270050002600A032 +:10AB000023A0132D0066000000000000000000508C +:10AB100028502814B020A0D0000614142A3A40006F +:10AB200000146E6E471A38010F1E002000000FE857 +:10AB30000A0030000F510000000004640010FF7F85 +:10AB40000B646400000A201405F8000000000006F1 +:10AB5000080F160672390002F5E1826E46320200D5 +:10AB6000009600009600009600005AE0005AE000AF +:10AB70000000000000000000000000007B007B00DF +:10AB80007D00800085008A0091009900A300AD003F +:10AB9000B900C500D300E200F2000301160129014B +:10ABA0003D01520167017E019601AE01C701E0013E +:10ABB000FA01150230024C0268028502A202BF02AD +:10ABC000DD02FA0218033603530371038F03AC034B +:10ABD000CA03E703030420043C04570472048D04F1 +:10ABE000A704C004D904F00407051E053305480571 +:10ABF0005B056E057F0590059F05AE05BB05C70586 +:10AC0000D205DC05E505EC05F305F805FB05FE05B9 +:10AC1000FF05FF05FE05FB05F805F305EC05E50559 +:10AC2000DC05D205C705BB05AE059F0590057F0570 +:10AC30006E055B05480533051E050705F004D904BC +:10AC4000C004A7048D04720457043C0420040304C8 +:10AC5000E703CA03AC038F037103530336031803DE +:10AC6000FA02DD02BF02A202850268024C02300233 +:10AC70001502FA01E001C701AE0196017E016701EC +:10AC800052013D01290116010301F200E200D30047 +:10AC9000C500B900AD00A300990091008A008500AD +:10ACA00080007D007B007B000000000000000000B1 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000007B007D001B +:10AD400082008B009700A600B900CF00E800050143 +:10AD50002401450169019001B901E3010F023D029F +:10AD60006C029C02CD02FF02310362039403C5030F +:10AD7000F603250454048104AC04D604FE04230520 +:10AD80004605660584059F05B605CB05DC05EA0585 +:10AD9000F405FB05FF05FF05FB05F405EA05DC05E9 +:10ADA000CB05B6059F058405660546052305FE040B +:10ADB000D604AC04810454042504F603C5039403AB +:10ADC00062033103FF02CD029C026C023D020F02BE +:10ADD000E301B90190016901450124010501E80081 +:10ADE000CF00B900A60097008B0082007D007B0099 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000050005000032460000000000 +:10AED00000000000000047B400C800010A960064AA +:10AEE00000B400010AB4006400010AB80BC40905EB +:10AEF0000200F401F40105022003C80028000A0042 +:10AF000050003200000000000000000000000000BF +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000010000C0 +:10AF90000000000000000000010000056842983A2F +:10AFA0000000204E0514003C3200000000000000AC +:10AFB0000000000000000000000000000000000091 +:10AFC00000000000D007F4012C0100011400CD01A5 +:10AFD000094F05003C000200230045600603030002 +:10AFE0000000FFBB0000C8008D00091F08002A01F7 +:10AFF0000200290128A00600000000000000004D0A +:10B000003D3D3E3E3F404040404243434444454630 +:10B0100046474848494A4B4B4B4C4B4C4D4E4E4C87 +:10B0200061000000004D403F4041434544454546D6 +:10B03000474749494A4B4B4C4D4D4E4F505050514C +:10B0400050505152525561000000004D3D3D3E3E72 +:10B050003F414142424445454748494A4B4C4D4E89 +:10B060004E4F5050505150505151525264000000B8 +:10B07000004D4343434445474847484A4B4B4D4D99 +:10B080004E50505253535455565655555554555588 +:10B09000555764000000004B383837373739393A94 +:10B0A0003A3C3D3D3E3E3E3F3F40404041424343AF +:10B0B000434442424343434258000000004B3F3D5B +:10B0C0003F3E3F4141404142434245454645464758 +:10B0D000474748494A4A494A4748494A494C58001B +:10B0E00000000014150721082100000000010000E5 +:10B0F0000001000101000001010105010000010043 +:10B100000100000100000101000100000101000038 +:10B11000FA5601D702CE0605081E0A141E0A1400AC +:10B120000100C8AA018E020B07EF07461246120A59 +:10B130000C0C00200A0A00000000000000000000C3 +:10B14000310096001E28000000051E00FA000000D5 +:10B15000500A052806640A02C80000030090016432 +:10B16000FA00C000000007100A00100000961E0040 +:10B170000F64140000000000000000000000000246 +:10B1800002505000460AC8001004000000000000F1 +:10B190000001800CF00AD000800CF00AD0000015ED +:10B1A000001250015001001500125001800CF00AED +:10B1B000D0000000000000009600F4010003C80069 +:10B1C0002F07C8006F03106464C8006400100010EB +:10B1D0009600640096006400960064009600640087 +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:0CB2100000000000000000003B2D75DE77 +:00000001FF diff --git a/firmware/st_fts_j2a_sdc.ftb.ihex b/firmware/st_fts_j2a_sdc.ftb.ihex new file mode 100644 index 000000000000..72db06d78d49 --- /dev/null +++ b/firmware/st_fts_j2a_sdc.ftb.ihex @@ -0,0 +1,7136 @@ +:1000000055AA55AA010000003639000093230000CC +:100010006700000000000000070000001C01020152 +:1000200000000000071200000000000050B00100B6 +:10003000480D000000000000000000008D55D4FCB9 +:100040001AB1F513136C0000E54E0AECEC93FFFFB8 +:1000500000041000E101000039020000530200001A +:100060006D02000087020000A102000000000000F5 +:10007000000000000000000000000000938101006B +:100080009B81010000000000BB020000A381010071 +:10009000AB810100B7810100C3810100CF81010064 +:1000A000DB810100E7810100F3810100FF81010094 +:1000B0000B820100C90200001782010023820100A7 +:1000C0002F820100378201003F8201004782010038 +:1000D000538201005B820100638201000000000086 +:1000E0000000000000000000000000006B82010022 +:1000F00073820100000000007B820100000000000C +:1001000000000000000000000000000000000000EF +:10011000670093231100FFFF1C0102010000000093 +:1001200000000000000000000000000000000000CF +:1001300000F002F800F068F80AA090E8000C824491 +:100140008344AAF10107DA4501D100F05DF8AFF26E +:10015000090EBAE80F0013F0010F18BFFB1A43F0A5 +:100160000103184754AE010084AE01000A444FF069 +:10017000000C10F8013B13F0070408BF10F8014B06 +:100180001D1108BF10F8015B641E05D010F8016B4B +:10019000641E01F8016BF9D113F0080F1EBF10F8AF +:1001A000014BAD1C0C1B09D16D1E58BF01F801CBD2 +:1001B000FAD505E014F8016B01F8016B6D1EF9D555 +:1001C0009142D6D370470000103A24BF78C878C156 +:1001D000FAD8520724BF30C830C144BF04680C604D +:1001E000704700000023002400250026103A28BF95 +:1001F00078C1FBD8520728BF30C148BF0B60704799 +:100200001FB51FBD10B510BDDFF80CD0FFF7F8FF0C +:1002100018F05EF81AF00BFA0004100003B4FFF7B0 +:10022000F1FF03BC1AF00CFA40BA7047C0BA70472D +:1002300012481349A1EB00014FF0200391FBF3F2A8 +:1002400002FB13114FF0CC334FF0CC344FF0CC35D0 +:100250004FF0CC364FF0CC374FF0CC384FF0CC3994 +:100260004FF0CC3AA0E8F807013AFBD119B140F8B9 +:1002700004AB0439FBD10348004700000000100024 +:1002800000041000E10000001EF0040F0CBFEFF3AB +:100290000880EFF309804FF001014FF0000213F0E6 +:1002A000C5BE1EF0040F0CBFEFF30880EFF309800A +:1002B0004FF002014FF0000213F0B8BE1EF0040F21 +:1002C0000CBFEFF30880EFF309804FF003014FF00C +:1002D000000213F0ABBE1EF0040F0CBFEFF308805A +:1002E000EFF309804FF004014FF0000213F09EBEBF +:1002F0001EF0040F0CBFEFF30880EFF309804FF0FE +:1003000005014FF0000213F091BE00B517F062FF37 +:100310005DF804EB00F032B81EF0040F0CBFEFF3F1 +:100320000880EFF309804FF006014FF0000213F050 +:100330007DBE00000A484FF0FF0101704FF0000041 +:1003400080F311884FF0000080F3098805484FF0D2 +:100350000201017062B604484FF08051016070479D +:1003600022ED00E0A408100004ED00E002484FF088 +:10037000805101607047000004ED00E04FF0200064 +:1003800080F31188EFF3098098B112480068124990 +:100390000968884217D0EFF309800E49096820E9FF +:1003A000F00F886000B50B48006818F02DF85DF874 +:1003B00004EB084808490A68026000688168B1E8EF +:1003C000F00F81F309884EF0040E4FF0000080F327 +:1003D00011887047A8081000AC081000EFF31180D6 +:1003E0004FF0200181F31188704700004FF00000AA +:1003F00080F311887047000062B6704772B670478C +:10040000401EFDD17047000010B501463C22FC485B +:100410001AF08AF80121BDE81040002018F02DB82C +:1004200038B50546F748F64C2860284617F04CFDCD +:1004300000226B460121104618F068F801210020C7 +:1004400018F047F82078002802D013F03EFEECE7C1 +:1004500038BD2DE9F14FEC4EEC4D82B030684FF0D5 +:10046000000990F8317090F830104F43297851B15D +:1004700090F86D1090F8BD0A01F00F08C00706D083 +:1004800085F8009003E090F86C0000F0030801206C +:1004900000FA08FADE4CB900204600911AF0A0F8E4 +:1004A000DC484FF0010B00780190D748006890F8C5 +:1004B000BD1AC9071AD02978C1B9D7490978A9B98D +:1004C000D6490978052911D006290FD090F8750171 +:1004D000C0F30112C0F3810100F0030014F0BBFC73 +:1004E000401C4FFA80FBCB4880F80090002636E095 +:1004F000C548006890F8311090F8300041430298E8 +:10050000714300EB4109204600991AF069F8002573 +:1005100012E0BB483C30FFF783FFB94881680020F8 +:1005200007E054F8202031F910301A4444F8202014 +:10053000401CB842F5DB6D1C5545EADB384605E04A +:1005400054F8201041FA08F129F81010401EF7D293 +:10055000B0480178491C017012F0F7F8761C5E452E +:10056000C6DBAC4901980870BDE8FE4F12F0EDB84B +:10057000A34810B53C3017F080FCA14907203C315E +:10058000A54C087101202070A548FFF762FF0020EC +:10059000207010BD2DE9F04F9C489B4B9FB0017817 +:1005A000186819B190F86D10090903E090F86C1003 +:1005B000C1F3810190F8315088464FF0010990F85D +:1005C000307009FA08FB924CE81981009A4604EB56 +:1005D000850620461AF004F889483C3017F04DFC97 +:1005E000874A3C3282F80790DAF8000090F86B00F6 +:1005F000810701D582F80490C00703D080483C30C1 +:10060000FFF70EFF00202BE07D483C30FFF708FF8E +:10061000DFF8ECA16A0013A8DAF8201019F03FFF08 +:100620007A006846DAF8241019F039FF284613A931 +:1006300006E054F8202031F910301A4444F8202004 +:10064000401EF6D23846694606E056F8202031F9B9 +:1006500010301A4446F82020401EF6D209F101005D +:1006600081465845D0DB28466E4A05E054F82010F4 +:1006700041FA08F122F81010401EF7D238466A4AB3 +:1006800005E056F8201041FA08F122F81010401E3B +:10069000F7D26C0022466349644819F000FF7D00E0 +:1006A0002A466149624819F0FAFE2146614819F06C +:1006B00075FF2946604819F071FF1FB0BDE8F08F43 +:1006C0002DE9F04F504E85B0DFF848A13068504C0E +:1006D00090F831B010F8301F01910BFB01F59AF83A +:1006E0000010049190F84501C0F30112C0F381019C +:1006F00000F0030014F0AFFB401C40B203904048F0 +:100700003C3017F0BAFB3E4801273C30C7713068D7 +:1007100090F86B00C00703D039483C30FFF780FEEB +:100720003A48007800283848006805D090F86D00F5 +:1007300000F00F09000905E090F86C0000F00309D3 +:10074000C0F38100012101FA00F001FA09F8014625 +:100750000090404614F08AFB02902E480021017060 +:1007600011F0F3FF002674E0254800213C30464597 +:100770000171C17101DA0121017100998E4201DA22 +:100780000121C1711E483C30FFF74AFE1C48D0E9E8 +:100790000812876892461EB146451EDA28461AE0BE +:1007A0004FEA4B021F4819F07AFE01985146420069 +:1007B0001D4819F074FE284603E037F9101044F87C +:1007C0002010401EF9D243E054F8202037F91030B1 +:1007D0001A4444F82020401EF6D20098864237DAA8 +:1007E0005846104A07E032F9103031F910703B4496 +:1007F0005B1022F81030401EF5D20B49019825E01D +:10080000C8081000B9030000A0071000740410000D +:100810001C721000D807100000041000F80410002B +:10082000CC570120F8760120227701206C0B0120A3 +:10083000960B0120580C0120820C012031F9103058 +:100840003AF910201A44521021F81020401EF5D217 +:10085000761C0298864287DB284606E054F8201072 +:10086000664A41FA09F122F81010401EF6D2644897 +:10087000006890F8BD0AC0074BD062480078D8BB2A +:1008800061480078052844D0062842D001273DE081 +:100890005E48077011F059FF5948DFF874B10068DD +:1008A00090F8311090F830004143794353480026C6 +:1008B00000EB410A1CE056483C30FFF7B1FDDBF885 +:1008C00008100EB1002010E0284603E031F9102096 +:1008D00044F82020401EF9D209E054F8202031F9D4 +:1008E00010301A4444F82020401CA842F5DB761C46 +:1008F0004645E0DB284606E00BE054F8201041FABC +:1009000009F12AF81010401EF7D27F1C0398874285 +:10091000BEDB3E490498087005B0BDE8F04F11F009 +:1009200014BF2DE9F0470446002017F046FE0220D0 +:1009300017F043FE032017F040FE364E0020707083 +:1009400033483C3017F099FADFF8B480324FDFF8C3 +:10095000CC90D8F800004FF0010590F86B008007AC +:100960004FEA04700AD500280FDAA00708D5757081 +:10097000FFF7A6FE3D7089F8005001E0002804DA78 +:10098000707810B9FFF706FE3D70214FA00707F100 +:100990003C0718D5707830BB384617F06EFA3D71B9 +:1009A000D8F8000090F8CE00000604D5174840782B +:1009B00038B1042038711148FFF74BFD89F8005019 +:1009C00011E00320F6E760070DD511483C3017F021 +:1009D00054FAD8F8000090F87100C00601D53D71B6 +:1009E000E9E70720E6E7032017F002FE022017F0F0 +:1009F000FFFDBDE8F047002017F0FABDCC570120FD +:100A0000A007100074041000F8041000D8071000AC +:100A1000C808100000041000DF071000DE071000F7 +:100A200070B55D4C4FF6FF7140F25235206841823F +:100A3000294618F06DFB00211F200FF109F92A4605 +:100A40002168BDE870401F23544818F088BB70B57A +:100A50005148534C4FF480650068417D20684174D3 +:100A6000294618F055FB00211C200FF1F1F82A4609 +:100A70002168BDE870401C234A4818F070BB2DE97E +:100A8000F041494F041D0D462146384618F040FB01 +:100A90002868464A00EB8401914201D21D2310E0F0 +:100AA00090420DD2111A8E0890461D2332463946C7 +:100AB00018F055FBA21B07EB86011E23404602E0FF +:100AC0001E232246394618F04AFB286800EB8400B2 +:100AD0002860BDE8F081F8B5334C354800901034FB +:100AE000022017F06AFD00211D200FF1B1F800214E +:100AF0001E200FF1ADF81021204619F04FFD002007 +:100B00002080A0700120244DE0704FF6FF73A38079 +:100B100028680422018AE1808EB22649407D207235 +:100B2000A1F8F86EA1F8FA3E81F8FC0E694610466D +:100B3000FFF7A5FF012300222146102015F04FF8F2 +:100B40006946FFF79CFF012300222146112015F082 +:100B500046F86946FFF793FF286890F80012C90726 +:100B600003D190F8BA00C00708D001230022214623 +:100B7000122015F034F86946FFF781FF01230022A7 +:100B80002146132015F02BF86946FFF778FF022065 +:100B900017F02EFDF8BD0000A0071000F0EF0100D7 +:100BA000A4071000F0BF01001C721000F0DF01006C +:100BB000F0CF0100747701200B4801785A2911D138 +:100BC0008188B1F57C7F0DD8418800290AD106497A +:100BD00040781031022805D0A0F17002072A01D810 +:100BE00013F039BC704700000000012010B519F067 +:100BF000DDF80021912013F059FAFA480121017023 +:100C0000C17010BD10B5F74C207800280BD1A0881A +:100C100050B1F548A1880068B0F8880688420AD328 +:100C2000A088401CA08010BDA088401CA08019F0A6 +:100C3000B8F8E08010BD19F0B4F8208119F0B6F8CA +:100C40000120207010BD70B5E64C00202070A080FF +:100C5000E08020810B2000F0FFF94FF0E0264FF4F8 +:100C60000065C6F88052E14941F28830843619F0B7 +:100C700069F8F56720780028FCD0E0882189401ABF +:100C800084B20B2000F0E8F9204670BD7047F8B53B +:100C900000242546D64818F013F8D34F00260096B6 +:100CA00038683346012290F89400314600F007007E +:100CB00018F09DFD3868002190F8940000F00700BE +:100CC00018F01DFDCB48009038680023012290F8F1 +:100CD0009400194600F0070018F0DDFD304600F0E2 +:100CE000C6F9FFF7B0FFBF4E7081F078012801D13F +:100CF0003220F8BD38687189B0F88A0688420BD96D +:100D00000A34E4B2204600F0B2F9FFF79CFF6D1CF4 +:100D1000EDB27081142DEDD938687189B0F88A066A +:100D2000884203D90021922013F0C0F900253868C9 +:100D30007189B0F88A0688420BD8641EE4B2204656 +:100D400000F095F9FFF77FFF6D1CEDB27081142D57 +:100D5000EDD938687189B0F88A06884203D8002135 +:100D6000922013F0A3F917F0B7FF2046F8BD10B595 +:100D700001463C22A04819F0D7FB0121BDE81040F4 +:100D8000002017F07ABB70B5044617F0FAFC954DB9 +:100D9000E86817F0FBFCA4F876000420A070208E11 +:100DA0006FF30800801C20862820C4F8620094F8A5 +:100DB0005D0020F0030084F85D0094F85E0020F0F0 +:100DC000010084F85E0094F8360040F0010084F8D9 +:100DD0003600A97831B1012908D0022918D0032999 +:100DE00009D119E020F07000403002E020F07000DE +:100DF000503084F83600687888B1012813D0022872 +:100E000016D0032803D1A07C40F00300A07470BD6D +:100E100020F070006030ECE740F07000E9E7A07C63 +:100E200020F00300F2E7A07C20F00300401CEDE777 +:100E3000A07C20F00300801CE8E7F8B56E4E074662 +:100E40000324384617F040F800226B460121104673 +:100E500017F05CFB0121002017F03BFB307838B124 +:100E6000002513F032F9641E002CEADC2846F8BD98 +:100E70000125FBE72DE9F04389B00646684616F0E8 +:100E8000FCFF584F5D480025F8605D4800900E203B +:100E90008DF804007E70BD706846FFF7CEFF4FF0FE +:100EA000FF39E8B350225748F96819F0F8FA0124DD +:100EB0000DF11808BC706846FFF7BFFF80B35022E1 +:100EC0005148F96819F0EBFA4E4A414628F8145097 +:100ED000002002EB400332F810C0B3F83037401C5A +:100EE000A3EB0C0331F814C02828634421F8143014 +:100EF000EFDB641CE4B2042CDCD3BDF81E00032E2F +:100F000015D0A022B0FBF2F1BDF81C00BDF81A30DC +:100F1000B0FBF2F0B3FBF2F2120642EA004000E04E +:100F200003E0084309B0BDE8F0834846FAE75022E1 +:100F3000E8E72DE9F0410125002017F03EFB0220F3 +:100F400017F03BFB2C4F0026DFF89C803C370FE06E +:100F500001250024E0B2FFF78DFF47F824000028A8 +:100F600000DA0025641C042CF4D3012D08D0761C73 +:100F7000D8F8000090F89406B042E9DC25B327E0E9 +:100F8000224E1D49102230683C31223019F087FA78 +:100F9000D8F800001E4C90F88D06800703D59821E4 +:100FA000201D19F01DFB144919483C319C308EC995 +:100FB00080E88E000221201D216017F0F4FB3168CB +:100FC0005A2081F8210003E00021302013F06EF850 +:100FD000002017F00DFB022017F00AFB2846BDE8A1 +:100FE000F081000004041000A00710009D0B000019 +:100FF0003D0C0000B50B00001C0910000000012092 +:101000001F0D00001C7210004C791000A407100086 +:10101000909C100010B5FFF78CFF00F0010400F069 +:101020002AF820420CD04E48006890F83210FA2975 +:1010300002D2491C80F83210BDE81040FFF707BD0E +:1010400010BD10B5FFF775FF10F0010F03D0BDE81C +:101050001040FFF7FCBC10BD00F01F0201219140C1 +:101060004009800000F1E020C0F8801170470A229A +:10107000072117F09DBF70B5002017F09EFA394C7C +:101080000020E070FFF703FE064600F019F8054661 +:1010900001460A22304617F08BFFE07830B930481D +:1010A00002685A20D67782F820509077002017F0F7 +:1010B0009FFAE078012801D0012070BD002070BDAA +:1010C0002DE9F84317F008FE274E00200090306805 +:1010D0000023012290F89400194600F0070018F050 +:1010E00086FB3068002190F8940000F0070018F0AB +:1010F00006FB1E48009030680023012290F89400FF +:10110000194600F0070018F0C6FBFFF79CFD0146EA +:10111000144800244FF6FF754181804621460A227B +:10112000322017F045FFFFF78EFDA8F80A0098F867 +:101130000310012911D03168B1F88A16401A00D580 +:10114000404280B2854201D905462746641CE4B27C +:10115000102CE3D33846BDE8F8830720FBE70000F6 +:10116000A407100004041000A0071000B50B000035 +:1011700010B501463C22F84819F0D6F90121BDE826 +:101180001040002017F079B930B587B004466846A2 +:1011900016F073FEF1490091022C05D0032C09D002 +:1011A000042C05D00A2006E003208DF80A0004E094 +:1011B000072000E00B208DF80400E74C684616F08D +:1011C00083FE002206AB0121104617F09FF9012192 +:1011D000002017F07EF9207810B112F076FFEDE7CD +:1011E00016F0B3FEDE4DC5E9120116F0B0FEC5E9FA +:1011F0001401A468302013F04BF811F0EEFE07B094 +:10120000204630BD2DE9F041D54CA0F16006092EF5 +:10121000D4E91220D4E9145316D2DFE806F00516FB +:1012200026374858687989000346084600F018FBBD +:10123000012302460021184619F0E7F8D4E90223F9 +:1012400010431943C4E9020177E02A46084600F03A +:1012500007FB02460120002119F0D7F8D4E90A2340 +:1012600010431943C4E90A0167E00346084600F049 +:10127000F7FA012302460021184619F0C6F8D4E90E +:10128000062310431943C4E9060156E02A460846DE +:1012900000F0E6FA012302460021184619F0B5F8DD +:1012A000D4E90E2310431943C4E90E0145E0034677 +:1012B000084600F0D5FA02460120002119F0A5F8F1 +:1012C000D4E9042310431943C4E9040135E02A4654 +:1012D000084600F0C5FA02460120002119F095F8F1 +:1012E000D4E90C2310431943C4E90C0125E003465B +:1012F000084600F0B5FA012302460021184619F00D +:1013000084F8D4E9082310431943C4E9080114E020 +:101310002A46084600F0A4FA02460120002119F0EE +:1013200074F8D4E9102310431943C4E9100104E010 +:10133000012088406168084360602068401C20608C +:10134000BDE8F0812DE9F041174604460D46002620 +:1013500009E0E00703D03146384612F0A7FE761CBC +:101360006D084FEA340454EA0500F2D1E8E72DE9AC +:10137000F0417B4CD4E90223D4E9065610461946C5 +:101380002A433343D4E90A56D4E90EC745EA0C058B +:101390003E43D4E9087C97432CEA030CC4E9087C5B +:1013A000D4E91023AA43B343C4E910232268002AD6 +:1013B000C6D06022FFF7C6FFD4E90A016122FFF719 +:1013C000C1FFD4E906016222FFF7BCFFD4E90E0198 +:1013D0006322FFF7B7FFD4E904016422FFF7B2FFED +:1013E000D4E90C016522FFF7ADFFD4E908016622BC +:1013F000FFF7A8FFD4E910016722FFF7A3FF606899 +:10140000BDE8F041682200219CE799E72DE9F84FFB +:101410000446002616F099FD0746884616F097FD0B +:1014200081464F488A4648304FF01D0B80E88007C0 +:101430002620009017F01DFB00252A4601200021E0 +:1014400018F0E3FF384001EA080108431DD0E8B274 +:10145000002117F016FB410704D5E10602D53146FD +:1014600062200EE0C10704D0610702D5314660203A +:1014700007E014F0C00F06D010F00A0F03D0314679 +:101480006420FFF7BFFE761CF6B26D1C5D45D4DB11 +:1014900017F0EFFA0026354629E02A460120002100 +:1014A00018F0B3FF00EA090001EA0A0108431DD061 +:1014B000E8B2012117F0E5FA410704D5A10602D5EB +:1014C000314663200EE0C10704D0210702D5314622 +:1014D000612007E014F4C07F06D010F00A0F03D09B +:1014E00031466520FFF78EFE761CF6B26D1C009823 +:1014F0008542D2DDBDE8F84F17F0BBBA2DE9FF4FAA +:1015000081B08846924600210E9A1E468B46009175 +:10151000100576D500244AE000274FF0FF393D46FC +:101520002DE005FB08403AF91010B14226D27F1C8D +:10153000B9F1FF3F00D1A9460199491E8D421DD145 +:10154000012F1BD1A8F101018C420BD12946662045 +:10155000FFF758FE12E0000068091000211100009A +:10156000180410000AEB4000B0F90210B14204D395 +:1015700024B130F9020CB04200D200276D1CC648DD +:10158000005DA842CDD80198A0EB0900B8420DD863 +:1015900021466720FFF736FE22460120002118F081 +:1015A00034FF009B40EA0B0B19430091641C444537 +:1015B000B2D3002522E0B94800273C4630F9151087 +:1015C000A8EB010912E005FB08413AF91100B0420D +:1015D0000BD222460120002118F017FF009A00EAE2 +:1015E0000B001140084300D17F1C641C4C45EAD31A +:1015F0001FB129466620FFF705FE6D1C0198854244 +:10160000D9D305B0BDE8F08F70B5044686B0002090 +:1016100016F0D3FFA248002114F00C0FC0E9081106 +:10162000C0E90211C0E90411C0E90611C0E91011B6 +:10163000C0E90A11C0E90C11C0E90E114160016056 +:1016400009D1E00607D4A00605D4600603D4E0055E +:1016500001D4200602D52046FFF7D8FEA00701D10D +:10166000200520D50120FFF78FFD054616F06DFC03 +:10167000CDE9020116F06BFCCDE90401082102A8B6 +:1016800017F00CFD0646082104A817F007FD0146D7 +:10169000200508D5834800942A46006890F8123B3C +:1016A0003046FFF72BFF14F4404F02D00320FFF722 +:1016B0006BFDFFF75CFE06B00020BDE8704016F041 +:1016C00097BF2DE9F04F044685B0002016F075FF56 +:1016D000022016F072FF032016F06FFFE0077DD0A6 +:1016E000FEF746FF6F4C206890F8311090F83000FC +:1016F0004A0042436C496D4818F0D1FE4FF0000A91 +:10170000A3469AE0654B91F83010DFF8A49113F8E6 +:101710001A004FF0FF3510F0FF00A1EB0002D4B229 +:10172000624A01FB0AF147F6FF7802EB41072E46B9 +:101730000BD0204600215A4602E027F81010401C2A +:10174000136893F830308342F7DC641E1DE037F9EC +:101750001400484500DD8146404500DA8046012CF2 +:1017600013D407EB440131F9021C401A00D5404262 +:10177000DBF80010B1F8F81A884206DB2246012097 +:10178000002118F042FE85438E43641EDFD2B9EB80 +:10179000080000D54042DBF800105C46B1F8F62A9C +:1017A000904248DAB1F8F40A484544DD4044002844 +:1017B00041DD91F8FA1A2A4688463346384605F044 +:1017C000FFFA014620683346B0F8F42A0020019061 +:1017D00000910290CDE903022A4600E034E0414640 +:1017E000384605F007FB2068334690F8302090F823 +:1017F000FA0AA2EB0801C9B2884607EB40002A4664 +:1018000005F0DEFA014620684FF0010C0DF10809E1 +:10181000B0F8F44A90F9FC3A90F9FB2ACDE9001CA3 +:1018200089E81C0090F8FA0A2A4607EB4000334684 +:10183000414605F0DFFA0AF1010ADBF8001091F8E1 +:10184000313053453FF75EAF032016F0D1FE022042 +:1018500016F0CEFE05B00020BDE8F04F16F0C8BE71 +:101860002DE9F04116461F4680464FF0FF35002413 +:1018700022460120002118F0C8FD304039400843BD +:1018800004D06D1C454501D1204659E5641C402C0F +:10189000EED3002054E500005E260120342601200E +:1018A00018041000A0071000CC570120948B0120D1 +:1018B0000080FFFF144908604FF40051002016F02B +:1018C000DCBD38B5002016F078FEAFF2170018F036 +:1018D00025FC00224FF400546B462146104616F0BA +:1018E00015FE2146002016F0F4FD002016F080FEC3 +:1018F0000648A522016804480A74006820F07F4267 +:101900004A6118F02FFC38BD70041000A4071000C5 +:10191000020004D0012A04D0022805D002E00120F0 +:1019200000E0072016F032BA0020704710B50146DB +:101930003C22FE4818F0F8FD0121BDE810400020CF +:1019400016F09BBD30B587B00446684616F095FA90 +:10195000F7480090FCB1012C1FD0022C19D10220B5 +:101960008DF80A00F14D0324684616F0ADFA002206 +:1019700006AB0121104616F0C9FD0121002016F02A +:10198000A8FD2878002804D012F09FFB641E002CCC +:10199000EADC07B030BD082000E009208DF8040023 +:1019A000E0E72DE9F14F8CB016F0CFFACDE9040154 +:1019B00016F0CDFACDE90601DE4C0C98002820681F +:1019C00007D0B0F832110C98FFF7A2FF8146DA4831 +:1019D00012E090F8CE0010F0600F05D0DDE90401B0 +:1019E00013F07AFECDE904012068B0F82C110C98B0 +:1019F000FFF78EFF8146D148029040200B900A905D +:101A0000082104A817F04AFB0446082106A817F08D +:101A100045FB4443DFF82883214608F5E66082460B +:101A200018F0BCFD6100404618F0B8FDBF48B82171 +:101A3000B83818F0D5FD02222146504618F0A6FD10 +:101A400000263546082106A817F028FB0390DDE99B +:101A50000401B346CDE900015A460120002118F0E7 +:101A6000D4FCDDE900231040194008432BD00024AA +:101A700025E022460120002118F0C7FCDDE9067CA4 +:101A800002460B46384001EA0C01084316D0AD4827 +:101A900030F9150088B1039996FBF1F701FB176740 +:101AA000081A874209DBA148B83800EBC500D0E925 +:101AB000001711431F43C0E90017761C641C0A98E5 +:101AC0008442D6DB6D1C0B990BF1010B8B45C3DBFC +:101AD000002008900C98FFF735FF94480024D0F8B8 +:101AE00008B00120099001942046D5E0024601206B +:101AF000002118F08AFCDDE9042310401940084356 +:101B000074D00020AFE002460120002118F07DFCD7 +:101B1000DDE9062306460F4610401940084371D000 +:101B200082480199B83800EBC105D5E90001304081 +:101B3000394008430FD1DDE90110009A16F0E6FEA6 +:101B40001AF804103BF91420022905D04A4554DD47 +:101B500019B301292ED083E04A4506DD7F2811DA2A +:101B600000220AF80420431C06E00BDA002809DDF5 +:101B700001220AF80420431EDDE90110009A16F044 +:101B8000D0FE05E0D5E9000130433943C5E9000145 +:101B90003BF8141028F8141062E07F2803DA28F8C4 +:101BA0001420431C35E0D5E9000130433943C5E931 +:101BB000000155E0D5E9002132433943C5E9002150 +:101BC00038F914203BF91430B2EB0901A3EB0902F8 +:101BD00000D54942002A00DA5242914207DC431CF8 +:101BE000DDE90110009A16F09CFE02E052E028F8B0 +:101BF000143002200AF8040032E05FDA012902D032 +:101C000069B12DE02DE010F17F0FCCDD28F8142014 +:101C1000431EDDE90110009A16F083FE20E0D5E9AD +:101C2000002132433943C5E9002138F914203BF93A +:101C30001430B2EB0901A3EB090200D54942002A96 +:101C400000DA5242914206DC431EDDE90110009A9F +:101C500016F067FE01E028F8143002210AF804109B +:101C6000641C0098401C00900A998842FFF64BAF14 +:101C70002E480199B83800EBC100D0E90010DDE929 +:101C8000062351405840014301D00020099001989B +:101C9000401C01900398401C0B9903908842FFF66A +:101CA00025AF0998012805D00898401C08907F2886 +:101CB0007FF710AF09980DB0BDE8F08F02210AF848 +:101CC000041070E72DE9F14F8EB04FF0000B16F0C5 +:101CD0003CF9CDE9000116F03AF9CDE904010E987E +:101CE00048B114480068B0F832110E98FFF710FEA2 +:101CF0000790114814E00F4C206890F8CE0010F0C7 +:101D0000600F05D0DDE9000113F0E6FCCDE900012C +:101D10002068B0F82C110E98FFF7FAFD07900748DD +:101D2000029040200C9008210B900DE0600A1000FA +:101D3000DD180000A00710009C7C012074770120B2 +:101D40001C72100034260120684617F0A7F90D9088 +:101D5000082104A817F0A2F90A90B821FE4818F04B +:101D60003FFCFD481721F43018F03AFC0120002711 +:101D700008903846824602460120002118F045FBB3 +:101D8000DDE9042305460E461040194008437DD086 +:101D900000200390F148006890F82A118A0720D5A6 +:101DA00047B1090709D5012F04D090F83000401E33 +:101DB000B84202D1CDF818A013E000240BE0214670 +:101DC000069A029816F0A2FD034652462146029852 +:101DD00016F0A7FD641C0D988442F0DBCDF818A026 +:101DE00057E00E98FFF7AEFDDB484FF00009B83022 +:101DF0008068099001200390484644E00246012093 +:101E0000002118F002FBDDE90023104019400843CF +:101E100037D0D14800EBC904D4E900012840314053 +:101E2000084325D152464946029816F06FFD0A999B +:101E300009FB0172099931F9122007998A4206DAE1 +:101E4000D4E9001029433043C4E9001010E07F2892 +:101E500006DA431C52464946029816F062FD07E036 +:101E6000D4E9000128433143C4E90001002008906F +:101E7000D4E9000128403140084300D1039009F122 +:101E8000010908F1010080460C9900E005E0884254 +:101E9000B4DB03980028A4D07F1C0AF101000B9941 +:101EA00082468842FFF667AF0020AFE04FF000099E +:101EB0004846A1E002460120002118F0A6FADDE91B +:101EC000042306460F461040194008437ED0B9F15E +:101ED000000F01D14FF0010B0E98FFF733FD9E4824 +:101EE0000024B8308068099001200390204675E0F6 +:101EF00002460120002118F088FADDE90023104095 +:101F00001940084368D0B9F1000F0EDD5246214652 +:101F1000029816F0FBFC90495246F43109570B1811 +:101F20002146029816F0FDFC55E0BBF1010F10D1DF +:101F300052462146029816F0E9FC8749F4310855CB +:101F4000854800EBC400D0E90021B243B943C0E9A1 +:101F50000021814800EBC405D5E90001304039403B +:101F600008432FD152462146029816F0CFFC0A9A18 +:101F7000099904FB029231F9122007998A420BDA7F +:101F8000D5E9001231433A43C5E900127249F431F0 +:101F90000A5D801A085515E07F2806DA431C524670 +:101FA0002146029816F0BDFC0CE0D5E90012314341 +:101FB0003A43C5E900126849F4310A5D801A0855B0 +:101FC00000200890D5E90001304000E012E03940DF +:101FD000084300D10390641C08F101000C9980466D +:101FE000884285DB03984FF0000B00283FF474AF64 +:101FF00009F101090AF101000B9982468842FFF6B6 +:1020000059AF0E98FFF79EFC0698401C0690534867 +:10201000006890F82A110698B0EB111FFFF646AF42 +:1020200008980FB048E62DE9F14F90B015F08DFFFC +:10203000CDE9040115F08BFFCDE908011098C8B374 +:1020400046480068B0F832111098FFF761FC074667 +:1020500043480290402003900790082104A817F0FD +:102060001DF80446082108A817F018F83D4E44430F +:1020700006F5E6652146284618F090FA61003046DC +:1020800018F08CFAB821344818F0AAFA0222214636 +:10209000284618F07BFA00200D901098FFF752FCAC +:1020A0002D484FF0010BB8300024806801940B904C +:1020B00020464DE1FFE7DDE9040113F00DFBCDE91A +:1020C000040126480068B0F82C111098FFF720FC96 +:1020D00007462548BDE702460120002118F095F982 +:1020E000DDE9042310401940084379D000200A900C +:1020F00020B20E901848019900EBC1008046D0E94B +:102100000010DDE9082351405840014301D101206E +:102110000A900020D3E00A460120002118F075F94A +:10212000DDE9082381468A461040194008437DD0E6 +:1021300000200690DDE90110009A16F0E7FBD8E9CF +:10214000001E01EA09030EEA0A02134301D101222B +:1021500006920A9A002A09E0A8091000A0071000B8 +:102160009C7C01201C721000747701200AD12A5D2A +:10217000022A08D00B9B33F91430BB425FDD82B3D7 +:10218000012A3ED098E00B9A32F91420BA4205DDBC +:102190007F2810DA00212955431C06E014DA10F1DB +:1021A0007F0F08DD01212955431EDDE90110009A4A +:1021B00016F0B7FB0EE041EA09014EEA0A02C8E94F +:1021C00000124FF0000B05E041EA09014EEA0A0255 +:1021D000C8E900120B9830F8140026F814006BE0E0 +:1021E000B4E0FFE77F2803DA26F81430431C31E01F +:1021F00041EA09014EEA0A02C8E900124FF0000B59 +:102200004BE0069A2AB141EA09014EEA0A03C8E9FD +:1022100000130B9A36F9141032F91430C91BA3EBD2 +:10222000070200D54942002A02DA00E045E05242A6 +:10223000914201DC431C2BE026F814302DE02FDA0C +:10224000012A01D062B137E010F17F0FD0DD26F80E +:102250001430431EDDE90110009A16F062FB2BE0FA +:10226000069A2AB141EA09014EEA0A03C8E90013B5 +:102270000B9A36F9141032F91430C91BA3EB07027C +:1022800000D54942002A00DA52429142D4DC431E72 +:10229000DDE90110009A16F044FB022028550BE0FE +:1022A00002202855069838B1D8E9001241EA090100 +:1022B00042EA0A02C8E90012641C0098401C014668 +:1022C000009007988142FFF626AFDDE90823D8E9A0 +:1022D000001051405840014302D04FF0000B32E053 +:1022E0000A9880BB0020DDF8389028E002460120E3 +:1022F000002118F08AF8DDE908231040194008434E +:102300001BD0DDE90110424616F000FB15F809105C +:1023100011B1012905D00CE010F17F0F09DD431E3A +:1023200002E07F2805DA431CDDE90110424616F081 +:10233000F8FA09F101000FFA80F908F10100079994 +:1023400080468842D2DB0198401C01900C98401CCA +:1023500003990C908842FFF6BEAEBBF1010F05D089 +:102360000D98401C0D907F287FF797AEFD480068C0 +:1023700090F82B0140077DD5082108A816F08EFEA5 +:102380000D90002001904FF0010BB821F64818F095 +:1023900027F9002094E102460120002118F035F8C9 +:1023A000DDE908238246884610401940084372D070 +:1023B00000200690EB480222006890F83110284671 +:1023C00018F0E4F80024204615E002460120002120 +:1023D00018F01BF8DDE9042310401940084308D029 +:1023E0002146009A029816F091FADF49F431085517 +:1023F000641C09F10100039981468842E5DBFBE09A +:102400001098FFF79FFAD8484FF00009B83080685D +:102410000B90012006904846E9E002460120002189 +:1024200017F0F3FFDDE904231040194008437DD085 +:10243000CD4800EBC904D4E9000100EA0A0001EA32 +:102440000801084315D14946009A029816F05EFA31 +:1024500015F809200199022A0DD0DDF834C00B9B34 +:1024600009FB0C1133F91130BB426BDDB2B3012A09 +:102470004AD0AFE029E10D9B0B9A09FB03110A91A9 +:1024800032F91110B94210DD7F2805DA002105F874 +:102490000910431C11E011E1D4E9000140EA0A00EF +:1024A00041EA0801C4E9000115E018DA10F17F0FD4 +:1024B00009DD012105F80910431E4946009A0298DA +:1024C00016F02FFA13E0D4E9001041EA0A0140EABD +:1024D0000800C4E900104FF0000B08E00EE0D4E95A +:1024E000000140EA0A0041EA0801C4E90001DDE90F +:1024F0000A0131F8101026F810106BE07F2832DA4C +:1025000026F81130431C28E0D4E9002342EA0A02ED +:1025100043EA0803C4E900230B9B36F9112033F981 +:1025200011C0D21BACEB070302D500E05DE05242C4 +:10253000002B00DA5B429A4201DC431C36E026F8AD +:1025400011C038E03BDA012A01D0BAB142E010F103 +:102550007F0F08DD26F81130431E4946009A029885 +:1025600016F0DFF936E0D4E9000140EA0A0041EA5A +:102570000801C4E900014FF0000B2BE0D4E900236F +:1025800042EA0A0243EA0803C4E900230B9B36F936 +:10259000112033F911C0D21BACEB070300D5524216 +:1025A000002B00DA5B429A42C9DC431E4946009A7E +:1025B000029816F0B6F9022005F809000AE0022098 +:1025C00005F80900D4E9000140EA0A0041EA0801DF +:1025D000C4E90001D4E9000100EA0A0001EA0801A7 +:1025E000084300D1069009F101090C98401C039999 +:1025F0000C908842FFF611AF069800283FF400AF18 +:102600000024DFF864A1204680460AF1F40A18E0AD +:1026100002460120002117F0F8FEDDE904231040F6 +:10262000194008430AD02146009A029816F06EF924 +:102630001AF80420801A0AF80400641C08F101004A +:10264000804603998845E3DB0098401C2FE0024652 +:102650000120002117F0D9FEDDE9082310401940C0 +:10266000084322D04FF0000844461BE022460120D8 +:10267000002117F0CAFEDDE9042310401940084389 +:102680000FD04A464146029816F040F91AF8081051 +:102690004A46084443B24146029816F042F908F10E +:1026A0000108641C03988442E0DB09F101000799EA +:1026B00081468842CBDB0198401C01900098401C69 +:1026C000079900908842FFF666AE11B05846BDE803 +:1026D000F08F2DE9FF5F4FF0400AD146082102A894 +:1026E00016F0DCFC08210EA816F0D8FC0025DFF857 +:1026F0007CB00FFA80F82F462E463246012000218A +:1027000017F083FEDDE9022310401940084324D06E +:1027100000241FE022460120002117F076FEDDE9AB +:102720000E2310401940084313D03BF9170038B16D +:1027300095FBF8F208FB1252A8EB0000824201DA86 +:10274000109B00E0119B22463946009816F0E9F8EC +:102750006D1C641C4C45DDDB7F1C761C5645CCDBB8 +:10276000BDE8FF9FA0071000A80910003426012033 +:1027700070B505460124002015F01FFF022015F05A +:102780001CFFE80703D000F014F800F00104A807CC +:1027900002D500F059F80440002015F029FF02206E +:1027A00015F026FFE80702D0012000F0AEF8204621 +:1027B00070BD2DE9FC47012615F0C7FB04460D4608 +:1027C00015F0C5FBDFF80C9107468846D9F80000E4 +:1027D00090F8CE0010F0600F05D02046294612F088 +:1027E0007BFF04460D46D9F8000090F82A01C00787 +:1027F00024D0CDE9007822462B46374816F0A0F8C1 +:10280000D9F8001091F82A01C20717D091F8CF101B +:10281000C90705D00020FFF7C4F806000AD00DE074 +:1028200040074FF0000002D5FFF7FDFBF5E7FFF78B +:1028300049FAF2E70121742011F038FC0020FFF77B +:1028400081F83046BDE8FC872DE9FF41012615F0EF +:102850007CFB04460D4615F07AFB1E4F3A6892F851 +:1028600030315FEAC37C2DD0DFF870C09B070BD5F9 +:1028700092F8353192F834218DE80F0022462B462C +:102880006046FFF726FF06E0CDE9000122462B4611 +:10289000604616F055F8386890F83011C90711D025 +:1028A00090F8E100C0064FF0010002D4FFF70AFAE9 +:1028B00001E0FFF776F8060004D14FF48071742030 +:1028C00011F0F4FB0120FFF73DF804B03046BDE8FD +:1028D000F0810000A0071000747701209C7C01208B +:1028E00010B5FEF7EEFF5320FFF742FF00F00104A2 +:1028F0004FF4D67001F0D0F9204205D0FEF7EBF886 +:10290000BDE81040FEF7A3B810BD2DE9F047224EF8 +:102910000546306890F87531C3F30112C3F38101A5 +:1029200003F0030012F097FA3268401CC4B292F828 +:10293000BD0AC00700D1012492F8C10CC00729D0FC +:10294000012D27D192F83110DFF8549092F8302001 +:10295000DFF850805143D9F80050012202200F4E79 +:102960000FB288F800203635FDF7DBFF002188F82C +:102970000010032015F021FED9F800007A00624310 +:1029800087863146284617F08AFDBDE8F0470320C8 +:1029900015F02EBEBDE8F087A0071000CC5701202F +:1029A000A40710007404100010B501463C2204482E +:1029B00017F0BAFD0121BDE81040002015F05DBD03 +:1029C000B40A100030B587B0684615F056FAFE48D4 +:1029D00002220078E0B1032101280DD003280ED097 +:1029E000022818D0042205280CD004280DD006286F +:1029F0000ED007280FD010E08DF807100DE08DF8ED +:102A000009100AE08DF80B2007E08DF80B1004E0A8 +:102A10008DF8072001E08DF80920EC48EC4D0324E7 +:102A20000090684615F050FA002206AB01211046CE +:102A300015F06CFD0121002015F04BFD28780028D1 +:102A400004D011F042FB641E002CEADC07B030BD5C +:102A50002DE9F047DFF8709300252C46D9E914875B +:102A60002E4632460120002117F0CFFC00EA080074 +:102A700039404A46084304D0906B805DA84200D993 +:102A80000546761C402EECD3976DD9F85C80002665 +:102A900032460120002117F0B8FC384001EA080155 +:102AA0004A46084305D0D9F83C00805DA04200D9D1 +:102AB0000446761C402EEBD3916C16460D70D06CFC +:102AC0000470126BB76A736B12783F782A443A44E9 +:102AD000F76A1B783F7823443B44D6E9147C57EAD5 +:102AE0000C070DD0D6E9167C57EA0C070AD0FF2751 +:102AF0009A4212D29A1A2A44FF2A07D80A700AE088 +:102B00000C7008E00D700570BDE8F0870F70F1697A +:102B100041F40071F1610470F6E793420CD2D21ACD +:102B20002244FF2A01D8027004E00770F06940F4E3 +:102B30000070F0610D70E7E70D70ECE72DE9F041F2 +:102B40001F460C46002A1FDD9F4E77B1B6F90C5088 +:102B5000114613F044FAA842207812DAFF2807D26F +:102B6000401C20700020BDE8F081B6F90A50EFE764 +:102B7000F0691FB140F00200F06105E040F4006030 +:102B8000FAE708B1401E20700120ECE72DE9F04182 +:102B90001E460C46002A1ADD8B4D66B1B5F90C7045 +:102BA000114613F01CFAB84211DD207850B11028FC +:102BB00004D3103803E0B5F90A70F1E70020207063 +:102BC0000020D0E7E86926B140F00100E86101206B +:102BD000C9E740F48060F9E72DE9F14F00247A4815 +:102BE000009A2546FF21DAB1D0F830B002268BF8E2 +:102BF0000010D0F834A08AF80010B0F90C704169C8 +:102C00004FF01809002900DC01246F488069002872 +:102C100000DC0125FFF71CFFFFF7D4FE6CB11EE0BE +:102C2000D0F828B04FF400668BF80010D0F82CA034 +:102C30008AF80010B0F90A70E1E7DFF88C813A46B3 +:102C4000D8F82000D8F81410006801F049F80128DD +:102C500005D1D8F81C1031430124C8F81C108DB9D7 +:102C6000DFF864813A46D8F82400D8F818100068D4 +:102C700001F036F8012805D1D8F81C1031430125A0 +:102C8000C8F81C100CB1002D45D126462F46C84669 +:102C900019E046B94C49009B086A4A6959460068E0 +:102CA000FFF774FF064647B94749009B486A8A699F +:102CB00051460068FFF76AFF0746FFF7C9FEFFF7B6 +:102CC00081FE06B117B9B8F10108E2D24E463E4F77 +:102CD00017E03CB9386A009B594600687A69FFF7EB +:102CE0002DFF04463DB9786A009B51460068BA69D9 +:102CF000FFF724FF0546FFF7ABFEFFF763FE04B1C5 +:102D00000DB9761EE5D2012C05D1012D03D1F8694C +:102D100020F40070F861BDE8F88F2DE9F04F002431 +:102D20008046254620464FF0010CDFF89CB0A246B5 +:102D300016E002EBE50605F0070936780CFA09F70C +:102D400037420CD038F91470BBF90E60B74203DC7F +:102D500003F804C0012001E003F804A0641C6D1C0A +:102D60008C42E6DBBDE8F08F2DE9FF5F00244FF0D9 +:102D7000010B80462546DFF850A05F46DDF83C9009 +:102D8000119E54E0039805F0070100EBE50007FAF7 +:102D900001F20078024249D0305D012845D038F96F +:102DA0001420BAF90E108A4225DA2946019815F046 +:102DB00022FEFF2817DA0E994FF0000B0844FF2877 +:102DC00000DBFF20C2B205E07804100059290000A2 +:102DD000B40A10002946019815F00FFE38F81410B7 +:102DE00029F8141021E03755DAF81C1041F00801D9 +:102DF000CAF81C1019E01098012815D139F91400EF +:102E0000401AA2EB010100D54042002900DA4942F4 +:102E1000884209DC2946019815F0EDFD401EC2B23A +:102E20002946019815F0E9FD3755641C6D1C029880 +:102E30008442A7DB584604B0BDE8F09F2DE9FF5F50 +:102E40000024DDE90E764FF0010A9B462546D04668 +:102E5000DFF884942FE00BEBE500017805F0070024 +:102E600008FA00F20A4225D0305D012821D00098EE +:102E700030F91410B9F90E0081421ADD2946019883 +:102E800015F0B9FD00280CDD4FF0000AB84201DB57 +:102E9000C01B00E00020C2B22946019815F0ADFD2C +:102EA00007E006F80480D9F81C1041F00401C9F8C5 +:102EB0001C10641C6D1C02988442CCDB5046BAE79F +:102EC0002DE9F04F95B00F460646002425461821FF +:102ED0000EA817F085FB282104A817F081FBFE48F7 +:102EE0004169002900DC01248269002A00DC0125F7 +:102EF0003346F94A814606465032806B00F0FAFEAE +:102F0000F54A3B465832B169F06B00F0F3FEFFF72B +:102F10009FFDFFF757FD8CB1D9F82000EE4A4E46D1 +:102F200000680EAB5032D9F81410FFF7F6FE0128F6 +:102F300004D1F069012440F00800F0618DB1D9F8A6 +:102F40002400E54A4E46006804AB5832D9F8181000 +:102F5000FFF7E3FE012804D1F069012540F00800E5 +:102F6000F0610CB1002D76D126462F464FF00008B7 +:102F70004FF0100A0DF1380B6EB9CDE900ABD9F85E +:102F80002010D54BD9F8142008685033D9F83810E0 +:102F9000FFF754FF064677B904A8CDE900A0D9F899 +:102FA0002410CD4BD9F8182008685833D9F83C10B4 +:102FB000FFF744FF0746FFF74BFDFFF703FD06B1A0 +:102FC00027B908F10108B8F1600FD5DBDFF80CA3D1 +:102FD000D9F814000AF5E66841004F46504617F04C +:102FE000DDFAB8694100404617F0D8FA00264FF0E4 +:102FF0000109FFF7E7FC64B9CDE9009ACDE9029B2E +:10300000386AB54B7A6900685033B96BFFF7ACFE8C +:1030100004466DB904AACDE90098CDE90292786A18 +:10302000AD4BBA6900685833F96BFFF79DFE054652 +:10303000FFF70EFDFFF7C6FC04B115B9761C602E34 +:10304000D7DB012C07D1012D05D1F869810502D507 +:1030500020F40070F86115B084E62DE9FF4F83B0CD +:1030600082460120DDE9117683460290A7F17F00B8 +:1030700001900024C7F17F008946DDF84C80254689 +:10308000009083E0109800EBE500017805F0070060 +:103090000BFA00F20A4278D02946059815F07EFC1A +:1030A0008D4918F804303AF91420B1F91010022BA8 +:1030B00007D08A423ADDF3B1019988422CDDC21B68 +:1030C0003BE08A4208DD0199884202DD08F804B03D +:1030D000F5E7705D40B109E006DA0099814205DD4F +:1030E000002208F8042027E006F805B03AF814108A +:1030F00029F8141017E039F914305B1AA2EB01011A +:1031000000D55B42002900DA49428B422FDC01994D +:10311000884203DDC21B25E0705D08B906F805B0E2 +:10312000022108F80410705D58B32DE022DA012B5B +:1031300008D000998142EFDDC2192946059815F0A3 +:1031400034FCD3E739F914305B1AA2EB010100D546 +:103150005B42002900DA49428B4208DC0099814237 +:10316000DCDDC2192946059815F01FFCD6E729F8C1 +:103170001420D3E7022008F8040006F805B003E0A5 +:1031800003E0FFE700200290641C6D1C0698844257 +:10319000FFF678AF0298012822D100252C461CE0CA +:1031A000109800EBE400017804F007000BFA00F23D +:1031B0000A4211D02146059815F0F0FB18F80510C9 +:1031C000022908D079B10099814204DDC219214653 +:1031D000059815F0EAFB6D1C641C06988542DFDB40 +:1031E000029807B0BEE501998842F4DDC21BEEE704 +:1031F0002DE9F34F3A4897B0374C0068169037489E +:1032000014906169DFF8DCA000EB410015900AEB37 +:10321000010B504617F0C2F95846A16917F0BEF9E4 +:1032200060694100149817F0B9F9A0694100159838 +:1032300017F0B4F918210EA817F0D2F9282104A824 +:1032400017F0CEF90027A14616A8DDE9175450F86B +:10325000278018210EA817F0C3F9282104A817F019 +:10326000BFF902224E465046D9F8141017F08EF9D5 +:1032700002225846B16917F089F90026FFF7A2FB30 +:1032800095B9154B0EAA5033CDF80CA00093CDE99B +:103290000182D9F82010D9F81430D9F840200868F4 +:1032A0001499FFF7DAFE054694B90B4B04AA58337C +:1032B000CDF80CB00093CDE90182D9F82410D9F8EB +:1032C0001830D9F8442008681599FFF7C6FE04465F +:1032D000FFF7BEFB4DB107E0780410001C72100030 +:1032E00098A701004C79100014B9761C7F2EC5DB1D +:1032F0007F1CA9D019B035E52DE9FF5F4FF000081C +:10330000DDE90EB5994692464646444621E00AEB71 +:10331000E4000122017804F0070082400A4217D03D +:103320002146009815F03AFB071E00DA784258450E +:103330000DDD2146019815F05EFB002F0DDDC5F176 +:10334000FF01814201DB28440AE04FF00108761CAE +:10335000641C4E45DBDB40466DE5A842F5DB401BB7 +:10336000C2B22146019815F048FBEEE72DE9FC4773 +:103370000E46070001D0002E51D10024DFF838940A +:10338000DFF83884254697B9D9F8000008F15002D3 +:1033900090F8731190F87201CDE90001D8F814305B +:1033A000D8F83810D8F84000FFF7A6FF044696B9C1 +:1033B000D9F8000090F8731190F87201CDE900017E +:1033C000FE4AD8F818305832D8F83C10D8F84400E3 +:1033D000FFF792FF0546FFF73BFB012C08D1F74AA8 +:1033E00000235032D8F81410D8F8400000F082FCC6 +:1033F000012D14D1F14A00235832D8F81810D8F80A +:10340000440000F077FC0EB1012100E0002117B16B +:103410000CB1012000E00020BDE8FC47E8E6BDE873 +:10342000FC872DE9FF5F4FF0000B1E4617468846CC +:103430005D465C464FF0010ADDF8389016E007EB78 +:10344000E400017804F007000AFA00F20A420CD006 +:10345000B44209DD2146009815F0A0FA00EB0902FC +:103460002146009815F0A1FA6D1C641C4545E6DB69 +:103470005846E0E42DE9F05F0E46DDE90A510746C3 +:103480001C4693464FF0010A4FF00009104615F014 +:1034900085FACA4995F80080B7F90020B1F91010F3 +:1034A000A4F17F03C4F17F0CB8F1020F0AD04FF0F2 +:1034B00002098A4231DDB8F1000F1ED0984252DD78 +:1034C000021B31E08A4205DD98420EDD01212970A0 +:1034D000021B05E009DA844509DD00212970021983 +:1034E00058460B9915F061FA01E04FF00109388850 +:1034F0003080B9F1000F1DD01EE0B6F900707F1AC0 +:10350000A2EB010100D57F42002900DA49428F4237 +:1035100028DC984227DD021B1FE024DAB8F1010FF6 +:103520000CD084451FDD021958460B9915F03DFA61 +:10353000388830804FF0000A50467DE4B6F90030FC +:103540005B1AA2EB010100D55B42002900DA494277 +:103550008B4207DC844506DD021958460B9915F0AD +:1035600024FA00E0328085F80090E5E72DE9FF4F6E +:103570008DB04FF0FF390F98C846002801DC0120BC +:1035800000E000200C901C98002801DC012000E0E5 +:1035900000200B9089498A48099049694FF0000B37 +:1035A00000EB41000A90DA461C990F9811F05EFC7E +:1035B000069000200646059087E001250F9806F04A +:1035C00007072C4680450FDA109800EBE6000178DB +:1035D0000120B840014207D008F1010831460C9D96 +:1035E0000E9815F0DBF983461C9989450FDA1D9872 +:1035F00000EBE60001780120B840014207D009F154 +:10360000010931460B9C1B9815F0C8F982460DB193 +:10361000002C59D102208DF81C008DF820000027C5 +:10362000FFF7D0F91DBB0F9907A8CDE90006049755 +:10363000CDE902180998012300EB48010D980E9A74 +:1036400000EB4800FFF716FF054601280FD1314671 +:103650000E9815F0A3F9A0EB0B0B4FFA8BF00DF1C0 +:10366000380C00909CE807003346FFF7DAFE1CBBDD +:1036700008A8CDE900061C99CDE902190A9804971B +:1036800000EB49011A98012300EB49001B9AFFF750 +:10369000F1FE044601280FD131461B9815F07EF942 +:1036A000A0EB0A0A4FFA8AF00DF16C0C00909CE82E +:1036B00007003346FFF7B5FE05B114B97F1C7F2F15 +:1036C000AEDB0598401C0590761CDDE905018842BB +:1036D000FFF673AF11B0BDE8F08F2DE9F04700257C +:1036E0001746884682462C46344E4FF001091CE0AE +:1036F00007EBE400017804F0070009FA00F20A423F +:1037000012D02146504615F049F910F17F0F02D032 +:103710007F2804D007E0F06940F0400002E0F06943 +:1037200040F08000F0616D1C641C4545E0DBBDE8A5 +:10373000F0872DE9FF41214E716949B30025B06939 +:1037400040B300240DB1002C53D11C4A0023503249 +:10375000306C00F0CFFA194A00235832B169706C0E +:1037600000F0C8FA21462846FFF742FD124F38689C +:1037700090F87101800703D521462846FFF7F6FD32 +:10378000386890F87101C00715D02DB19CB903E0DD +:103790000125D4E70124D5E7706A084BB2690068B7 +:1037A0005833716C8DE80F00306A083B726900680D +:1037B000316CFFF7DBFE05E0A00710007804100075 +:1037C0001C72100005B184B9F06920F0C000F061EE +:1037D00025B1F84A7169306CFFF77FFF2CB1F54ACB +:1037E000B1690832706CFFF778FFBDE8FF41FFF761 +:1037F000E9B8BDE8FF812DE9FF5F4FF00109DDE980 +:103800000E6700259B4682462C46C84634E00BEBEB +:10381000E400017804F0070008FA00F20A422AD016 +:10382000385D38BB2146019815F0B8F8E1493AF9FE +:1038300015205039B1F910309A4210DDA6F17F02FF +:10384000904207DD821B2146019815F0AEF84FF03B +:1038500000090FE0C86940F04000C8610AE0C6F105 +:103860007F0107F80480814204DD82192146019816 +:1038700015F09BF86D1C641C02988542C7DB484616 +:103880006AE52DE9F04FCB4C85B0503C6169B9B386 +:1038900000208346A069A0B300208246BBF1000F40 +:1038A00002D0BAF1000F5AD1C34802AD0DC885E865 +:1038B0000D007F23BF4A206C00F01CFABD4A7F2315 +:1038C0000832A169606C00F015FA0027A14602A831 +:1038D0005D4650F8278054461521B84816F080FE02 +:1038E000B6482621153016F059FED9F81C100026CE +:1038F00021F04001C9F81C10FFF764F835B113E05E +:1039000000E001E00120C4E70120C6E7AB49A94B74 +:10391000CDE90081D9F82010D9F814200868D9F829 +:103920004010FFF768FF05467CB9A449A14B15314B +:10393000CDE90081D9F824100833D9F81820086897 +:10394000D9F84410FFF757FF0446FFF781F805B197 +:1039500014B9761C182ECFDB7F1C032FB7D305B00C +:10396000B9E62DE9F041934D0026503D012704466C +:10397000EE61012849D02F70A879697A08430CD0EC +:1039800000238C4A6969A86B00F0B4F9894A0023C6 +:103990000832A969E86B00F0ADF9E879697A084363 +:1039A0000AD084496A69286C15F00AF88149AA6925 +:1039B0000831686C15F004F8287910B10020FFF781 +:1039C0000BF96879C0B1287938B16978A86A00F034 +:1039D0007FF96978E86A00F07BF90120FFF7FCF8CD +:1039E000687948B1A978286B00F072F9A978686BFA +:1039F00000F06EF9FFF72CF8A87900B3FF20704AA9 +:103A000001462CB1012C09D00DE003202870B3E74A +:103A1000116891F8490191F84A1104E0116891F890 +:103A20005A0191F85B11FFF74BFAE978286B00F027 +:103A30004FF9E978686B00F04BF9FFF709F8012CB2 +:103A400008D02E70FEF7BEFFE87970B1287A012801 +:103A500003D008E002202870F4E73846594F387048 +:103A6000FFF70FFF3E70FFF764FEFEF7ABFF012C80 +:103A700008D01021E86900F053F9E86920B100206E +:103A8000BDE8F0814021F5E70120F9E770B50C466B +:103A900014F05BFA474D503DC5E9140114F057FA94 +:103AA000C5E916010821434815F0F8FA68610821B4 +:103AB00005F1580015F0F2FAA86104F19000A8622F +:103AC000401CE862401C2863401C68634B38A863B4 +:103AD0002030C5E90F044838686474309534C5E96E +:103AE000120470BD10B538490020FFF7CFFF3149EF +:103AF000324850391C380862314B001D4862186842 +:103B00004FF0000490F8382112F001020A7104D03D +:103B1000886A0470C86A047008E08A6A90F84101F3 +:103B200010701868CA6A90F842011070186890F80E +:103B30003821C2F340024A7122B1086B0470486B0D +:103B4000047008E00A6B90F84301107018684A6B23 +:103B500090F844011070186890F83821C2F380037F +:103B60008B71C2F3C003CB71B0F839314B81B0F81F +:103B70003B318B81B0F83D31CB81B0F83F310B82C6 +:103B800090F845314B7090F846318B7090F8473182 +:103B9000CB7090F8040100F001000872100601D506 +:103BA00001200872C2F340104872BDE810400020A6 +:103BB000D7E60000C80410009CA70100F00A10001E +:103BC000A0071000A80710006482012010B56F49FB +:103BD0000120FFF75BFF6F4900226D484A61486290 +:103BE0006D4CC1E914222068134690F84C2112F064 +:103BF00001020A7104D0886A0370C86A037008E081 +:103C00008A6A90F8550110702068CA6A90F85601C7 +:103C10001070206890F84C21C2F340024A7122B122 +:103C2000086B0370486B037008E00A6B90F857014B +:103C3000107020684A6B90F858011070206890F856 +:103C40004C21C2F380038B71C2F3C003CB71B0F877 +:103C50004D314B81B0F84F318B81B0F85131CB8170 +:103C6000B0F853310B8290F859314B7090F85C31B9 +:103C70008B7090F85D31CB7090F8290600F0010050 +:103C80000872100601D501200872C2F34010487274 +:103C9000BDE81040012064E670B50546012400200F +:103CA00014F08BFC022014F088FC680703D5FFF7A2 +:103CB00019FF00F00104280702D5FFF787FF044031 +:103CC000022014F095FC002014F092FC204670BDF8 +:103CD00002788A4201D9511A00E000210170704730 +:103CE00010B5144612F07BF9A04201DC012010BD92 +:103CF000002010BDF0B500252C464FF0010C0CE063 +:103D000002EBE40604F0070736780CFA07FE1EEA19 +:103D1000060F01D003556D1C641C8D42F0DBF0BD15 +:103D200070B504460D46C00702D0832010F0BEF9DE +:103D3000A00703D52946842010F0B8F9600703D501 +:103D40002946852010F0B2F9200703D529468620A0 +:103D500010F0ACF9600603D529468B2010F0A6F9C7 +:103D6000200603D529468C2010F0A0F9E00503D5E4 +:103D70002946872010F09AF9A00505D52946BDE807 +:103D80007040882010F092B970BD0000FC820120C4 +:103D9000E40A100078041000A0071000DFF8588132 +:103DA00008B5564D00245648C8F80040DFF854A125 +:103DB0002C60DFF854910460544ECAF80040C9F8F2 +:103DC0000040DFF84CB1346000226B465946104683 +:103DD00014F09CFB0098810713D5FCF70FFB2F68AC +:103DE0002C60FCF709FB17F0530F02D03846FEF7A2 +:103DF000BFFC17F4D67F02D03846FFF74DFF0221F3 +:103E000076E0410516D5FCF7F9FADAF80070CAF841 +:103E10000040FCF7F1FAF80701D0FCF701FEB80703 +:103E200001D5FCF758FE780701D5FCF710FE4FF4DA +:103E300080615DE001060CD5FCF7E0FAD9F800706E +:103E4000C9F80040FCF7D8FA3846FDF7DDFB8021C1 +:103E50004EE0C1010CD5FCF7D1FA2E48076804608A +:103E6000FCF7CAFA3846FDF72CFC4FF080713FE0B2 +:103E7000C10404D5FEF734FD4FF4805138E001024F +:103E800004D5FCF799FE4FF4000131E0010502D59D +:103E90004FF400612CE041020CD5FCF7AFFA377803 +:103EA0003460FCF7A9FAF80701D0FDF70AFD4FF4DA +:103EB00080011DE0C1050DD5FCF7A0FAD8F800700F +:103EC000C8F80040FCF798FA3846FCF72AFD4FF492 +:103ED00080710DE0410104D5FDF79CF84FF0806141 +:103EE00006E000017FF570AFFDF7ABF84FF0006121 +:103EF000002014F0EEFA67E7AC071000B0071000DE +:103F0000B4071000B8071000BC071000C00710006D +:103F1000839FF00DC407100010B5114811490068C7 +:103F20000B6893EA000F13D00F4A8407126810D56C +:103F300092F8E642E40702D043F002030B60C005AA +:103F40000AD592F8960C400702D543F480700860B9 +:103F500010BD23F00203F1E723F48070F7E70000BF +:103F6000D007100000051000A00710002DE9F04157 +:103F70007A487C4F02687A4892F8311080F8301005 +:103F800092F8304080F831403A7B80F8332007F1D6 +:103F90003C0240F8242BBA7B42727A7B827697F8F7 +:103FA0003A30C37697F83B2002777D7DC5746E4D1D +:103FB00045612438012B00D111464C4325B2002421 +:103FC0006E0080460FE022462946B86810F0E8FFF0 +:103FD0000146D8F8002005FB04F002EB4000324611 +:103FE00016F05DFA641CB87BA042ECDC98F8370050 +:103FF0004446012806D194F830205B48921CB969E8 +:1040000016F04DFA59485A49007809780843400794 +:104010000DD5387D94F83110484301B252488E30A6 +:104020004A0060603969BDE8F04116F038BABDE871 +:10403000F0812DE9F0414D484D4E0025046830686F +:104040000443012014F0B9FA4421454816F0C8FA97 +:10405000E00706D0FFF78AFFE00601D500F059F827 +:1040600001254448454F02683D48C0E907243168AE +:1040700041623C49404E4B688362CB7B80F83530CF +:1040800091F8381080F836103178002380F82C1021 +:1040900080F84130062905D13978052902D101215E +:1040A00080F84110E10711D0E1060FD52B490968CE +:1040B00091F80032DB0702D042F01002C26191F8A1 +:1040C000BA10C90702D042F02001C161012014F0EA +:1040D0008FFA30783870002DA9D0052807D006282F +:1040E00005D00121BDE8F041022014F0C6B902213B +:1040F000F8E79CE7204810B50078082808D0194850 +:1041000090F83910006B00F048FDBDE8104090E7D2 +:1041100010BD2DE9F0411148124E114D0068316A71 +:10412000012790F8312090F8304049B10E4885F8C9 +:10413000302018305200286116F0B1F985F83D7032 +:10414000716A002909D0084885F831404230620080 +:10415000686116F0A4F985F83C7068E7A0071000C4 +:10416000148410002C0B10006007012004051000BF +:104170000805100000051000F8041000D804100015 +:104180002DE9F0412148234E0025047820484FF0C6 +:1041900001070560316891F87110C90600D5076004 +:1041A00000F082F8012000F03FFC052C1FD0062C07 +:1041B0001DD01948077008F017FE306890F871108C +:1041C000CA0616491BD50D6090F80022D20703D10C +:1041D00090F8BA00C00701D008200860012105202E +:1041E00010F03FFA4FF48071002014F046F900F00F +:1041F000D6FDBDE8F0410221012014F03EB9086867 +:1042000020F0020040F00400E7E70000F80410008E +:10421000FC041000A0071000FA041000AC07100006 +:1042200010B5040012D0FCF7E9F8584801682143A2 +:104230000160FCF7E1F80121052010F012FABDE859 +:1042400010404FF48071002014F017B910BD0146E2 +:104250000020C9070BD04E490320096891F80022BD +:10426000D20703D191F8BA10C90700D00B207047CC +:1042700010B5C00717D04648006890F8C10C010679 +:1042800001D440060FD5FCF7B9F84248016841F067 +:1042900008010160FCF7B0F8BDE810404FF4800160 +:1042A000002014F0EAB810BD10B500F078FD02212E +:1042B000012014F00EF9012014F07FF94421364852 +:1042C00016F08EF93449012081F82C0014F090F991 +:1042D0000121022014F0D1F8BDE8104000F09DBB90 +:1042E0002DE9F0412D4900260868020603D520F08B +:1042F0008000012608602A4F0446386890EA0405C9 +:1043000029D064B170B105EA04000546FFF7B0FF9B +:104310003146284600F02BF83C60BDE8F081FFF7FD +:10432000C3FFF9E700F03BFD0221012014F0D1F8B2 +:1043300000F09FFA00F069FB25402846FFF798FF40 +:104340003146284600F013F800F050FB022101200E +:1043500014F093F8E0E7002CDFD11248007805282C +:1043600001D00628D9D13C60BDE8F0419CE710B5EA +:10437000012904D0FFF76BFFBDE8104050E70A4861 +:104380000078012801D10949087010BDAC07100060 +:10439000A0071000C007100014841000CC07100004 +:1043A000FC041000F8041000AA051000E207100039 +:1043B0002DE9F047DFF8EC930027FB4ED9F8000019 +:1043C000B84690F84010C9075ED0F84D2978022908 +:1043D0000FD005290AD0062908D090F841400120C5 +:1043E0000EF00FFE0022012806D016E090F84340A0 +:1043F000F5E790F84240F2E7287805280DD01046FE +:10440000B260A04240DDD9F8000090F84010890762 +:104410000FD52978022904D00BE0B068401CB060A9 +:10442000EFE7B179491CC9B2B171022901D9012163 +:10443000B17190F8BD0AC0070ED02878022803D0C9 +:10444000042801D0052810D130797179401CB0FBC7 +:10445000F1F301FB130030712878022803D00428FF +:1044600001D0052801D14FF00108B2602878052855 +:104470000FD000F047FA054600F04AFA40EA05047A +:1044800000F054FA40EA040786F803803846BDE895 +:10449000F0870127F8E72DE9F0470446002513F0DF +:1044A000ECFCFFF785FF0646C1480078B043C00723 +:1044B00002D0F00600D44025DFF8E88246B1D8F8F3 +:1044C000000090F8F401000702D500F03EFA054321 +:1044D00046EA0500DFF8D092C0074FF001071CD074 +:1044E00000F041FA01462071D8F8000090F8BD2A8A +:1044F000D20705D099F80330237499F80420627428 +:1045000090F8CE20C2F34112022A06D390F8CF00D1 +:10451000000602D5042900D12775680700D5677108 +:10452000F00611D5E771D8F8000090F84000800738 +:104530000AD599F80600012802D0022802D003E02B +:10454000277301E002202073680600D5677299483E +:104550000660994805609AE770B59848924D984C66 +:104560000078022816D09748007898B996480078C5 +:1045700001280FD0954E307860B916F0EBF848B9A5 +:10458000A9782078814205D33178014302D0904840 +:10459000007808B1002000E001202178A97070BDEA +:1045A00070B580480025804C006890F8C46183484D +:1045B0000078022801D165702570FFF7CDFF58B152 +:1045C000607858B92078401CC0B22070B04205D93C +:1045D00025700120607001E065702570607870BD05 +:1045E0002DE9F047044613F048FCFFF7E1FE804652 +:1045F00000F088F9064600F08BF940EA060500F065 +:1046000095F940EA050600F0A0F9DFF8989140EA34 +:1046100006054FF00107D9F8000090F8B3014106F4 +:1046200001D480060BD5FFF7BBFF40B1D9F80000DD +:1046300090F8B301800600D5A77425F0100548EA6C +:104640000506F0072BD000F08EF901462071D9F84D +:10465000000090F8CE20C2F34112022A06D390F84F +:10466000CF20120602D5042900D1277590F87611C3 +:10467000090608D55749497829B9534909780129C4 +:1046800001D00421A1715FEAC87108D090F8BD0A79 +:10469000C00704D04448C178217400796074700761 +:1046A00000D56771F00604D54B48E771007800B17A +:1046B0002773E80602D4A07C012800D1E7713D49A8 +:1046C0003D48C1F800800560E1E610B501463C2296 +:1046D000424815F029FF0121BDE81040084613F0BB +:1046E000CCBE2DE9F047314886B00078022817D0BB +:1046F000DFF8B0902F4EDFF8C08001254FF0070A99 +:10470000052811D0062835D0082868466BD0FFF759 +:1047100067FF33480090684613F0D6FB06B0B6E654 +:104720006846FFF7B8FEF4E76846002713F0A5FBDC +:104730008DF81350FFF73CFE040000D14027E0073E +:104740000CD0D9F8000090F87100C00604D500F034 +:104750000AF98DF8040001E08DF804A0E00601D507 +:104760008DF80750780601D58DF809503460C8F8E7 +:104770000070CEE76846002413F07FFB8DF81350DD +:10478000D9F80000012590F87100C00604D500F0AA +:10479000EAF88DF8040001E08DF804A03460C8F850 +:1047A0000050B6E7A0071000DC041000F804100069 +:1047B000FC0410000805100004051000F9041000A6 +:1047C00032071000280510002905100018051000F8 +:1047D000E1071000D8071000380710002C0B10005C +:1047E0007B460000FFE7002413F047FB01200D216A +:1047F0008DF804103460C8F800008AE7F8B5614D00 +:10480000801E0528296810D2DFE800F0030F060992 +:104810000C0091F8734009E091F8724006E091F8BD +:10482000744003E091F8754000E0012400260FF089 +:10483000F7F900B101266946032013F058FE0098ED +:1048400000B94EB12968142091F87110090600D5FD +:10485000C820844200D2044604B901242046F8BD91 +:1048600010B500F09CFA0221BDE81040012013F0C1 +:1048700004BE10B5444C0020A0602071414800687F +:1048800090F87501C0F30112C0F3810100F003003C +:1048900010F0E1FA401C607110BDEAE738B5002065 +:1048A00013F08BFE394C3A4920780870394800687B +:1048B00010B100F0F6F801E000F0CCF82078FFF736 +:1048C0009DFF0446AFF2670100F05CFA2046FFF757 +:1048D00008FF01280ED101216B460022084613F083 +:1048E00015FE0121084613F0F4FD2B48007830B185 +:1048F0000FF0EBFBBDE83840002013F079BEFFF766 +:10490000F9FBF7E725480078C00700D00120704781 +:1049100022480078C00707D01A48006890F80002C3 +:10492000C00701D010207047002070471B48007856 +:10493000C1071448006890F8BA0003D0C10701D03D +:104940001020704700F00100704714480078C0073D +:1049500007D00C48006890F87401C00701D004200B +:1049600070470020704707490120096891F8CE1070 +:10497000090603D50A48407808B10420704703208F +:1049800070470000A0071000DC041000F8041000BD +:10499000F9041000D40710002C0B1000FC041000C8 +:1049A000D8071000614810B5006890F87100C00782 +:1049B0000BD015F0CFFE012804D05D48017829B155 +:1049C000407818B15B490020486010BD012010BD3F +:1049D00010B500F03BF957490020574A48600221C2 +:1049E0001170564908705649087010BD5149002091 +:1049F000514A486004211170524A01211170524AF3 +:104A000011704F49087000F021B94A4900204860F0 +:104A10007047484900204860704746490020486078 +:104A2000454901200870704710B5044600F00BF9A5 +:104A30004049087000F00AF905223F49012C04D0D2 +:104A40000878052803D0062800D10A7010BD06207A +:104A5000087010BD70B5384D364C287802280ED03D +:104A6000042808D0052805D100F0EDF808B1217818 +:104A700099B1207070BDBDE8704000F035B800F00D +:104A80002AF8012806D06068401C6060FFF78AFFA2 +:104A90000128EFD0BDE87040A8E7207006202870FC +:104AA00070BD2549C3074FF0040201D00A7070475A +:104AB0008307FBD4420701D5022002E0020702D59A +:104AC000052008707047C20601D50620F9E7800668 +:104AD000F8D50820F5E710B500F0B5F80446002039 +:104AE0000EF08FFA204310BD70B5FFF7F4FF0025DC +:104AF000104C012818D06068401C6060FFF752FF1E +:104B0000012812D109486168006890F87600401CBD +:104B100000EB8000B1EB400F07D915F01BFE012818 +:104B200002D0BDE8704053E7656070BDA00710007B +:104B300074071000E8041000F8041000E2041000EC +:104B4000DF041000DE071000DF07100070B56B4AAD +:104B5000002415686A4AB5F8F6611278052A01D171 +:104B6000B5F8FA61674AD2780AB1B5F8F86100225F +:104B70000FE030F91230002B00DA5B42B34206DD61 +:104B800095F8F531641CA34201DC012070BD521C74 +:104B9000D2B28A42EDDB002070BD2DE9F0410F4614 +:104BA000010049D0584D564E0024EC703078A04694 +:104BB000022803D0032801D0052811D1002007B115 +:104BC0000120AA88121A14B201EB4000AA782146EB +:104BD00000F04EF8A87021464C48FFF7B7FF044696 +:104BE0006878012701280AD0F4B1307848490228B2 +:104BF00009D0032807D0BCB1052807D01BE085F8F1 +:104C000001800124F1E72C70EF7002E0287870B980 +:104C10002C70086800280FD100F0C1F8BDE8F04101 +:104C20000221012013F029BC3078052803D115F0AA +:104C300091FD012802D02C70BDE8F0812F70EBE7C8 +:104C40003149487070473048007870472E4901203C +:104C500088702A48006890F83000888028480078DA +:104C6000052803D0062801D0002008707047EDE722 +:104C70002DE9FC41244F8046144638780D461646EF +:104C800050B9012C08D121480A467F234146983863 +:104C9000009411F08CF900261848006890F8F4117F +:104CA000C90700D08CB119486A0041464C3815F04C +:104CB000F6FB164A2B46983A02F14C01134811F0C4 +:104CC00051F9387820430ED015E0B0F9FE11CDE946 +:104CD00000150E4AB0F9FC31983A414602F14C00F9 +:104CE00011F0D2F9E5E709487F232A464146983872 +:104CF000009411F05CF93046BDE8FC81A00710007B +:104D0000F8041000945A1000F0041000B6090120B5 +:104D1000D4071000234908B50020486001228860AC +:104D20000A704A70204A1070887020490870FFF796 +:104D30009EFFFFF7B2FDFFF76CFE6B4600225E217F +:104D4000012013F0E3FB0098410703D5FFF7C8FAF1 +:104D500004210AE0010703D5FFF7DEF8082104E08B +:104D6000C10606D5FFF70CFA1021012013F0B1FBA4 +:104D7000E3E78007E1D50221012013F0AAFBFFF74A +:104D80008DFDDAE70A49096891F87110090602D425 +:104D900000EB8000400080B2064915F0C3B815F062 +:104DA000E4B80000F8041000E0071000E20710006B +:104DB000A00710001148000000F067BC30B50023C8 +:104DC0000380012309E000EB430431F8135034F869 +:104DD000024C2C4420F813405B1C9342F3DB30BDA3 +:104DE0002DE9F74F06468EB00020CDE90C000446B1 +:104DF000FE48002A04707DD0032013F0DEFBFC4D3A +:104E0000FC4A31462B78FC4811F0ACF8032013F033 +:104E1000EFFB2878F8494200F84815F040FBDFF82E +:104E2000E093D9F8000090F8B201C00609D52A78BD +:104E3000F149F448FFF7C2FF2A78F249F24810F02E +:104E400089F9DFF8BCA3A946DAF80000B0F8CA1166 +:104E500061F30F07B0F9CC11059161F31F47B0F86A +:104E6000CE1161F30F08B0F9D01161F31F488B46E2 +:104E700090F8D21161F3070690F8DB1190F8DC018D +:104E800061F30F2660F317462878CDE900780125F5 +:104E90000296CDE90350AF1E3B463A46DA490CA8CC +:104EA00000F0FFFEDAF800100026DFF8608391F8CA +:104EB000B2010DF1300AC0F30012C0F380131A40A2 +:104EC00012EAD01F13D091F8D30191F8D21199F8BA +:104ED0000020CDE90310CDF800A0CDE901523B46FA +:104EE0003A4698F80000002100F0C8FFC6B2C44856 +:104EF000006800E086E090F8B21109061CD5C449AC +:104F0000B0F9D501497801B15846CDE9066499F860 +:104F10000010CDE90105CDF800A0CDE903153B4611 +:104F20003A46B549B74801F006F899F80000B54986 +:104F30004200B14815F0B3FA99F80020AE49B548DF +:104F4000FFF73CFFDFF8B8B2DBF8000090F8B211D1 +:104F5000490616D5AE49B0F9D701497801B105988F +:104F6000CDE9066499F80010CDF800A0CDE903144E +:104F7000CDE90105A0483B463A46A649763000F007 +:104F8000DAFFDBF8000090F8B211C1F30012C1F3B0 +:104F900080131A4012EAD11F29D00F9A0021012A4A +:104FA00003D188F8004088F80240E6B190F8D311A8 +:104FB00090F8D421B0F9D90199F80030CDE9080270 +:104FC0000A91CDE90653CDE9046498F80200CDE9D1 +:104FD000020489483B463A468B49CDF800A076301A +:104FE00000F0F2FFC1B288F8006088F802100F9854 +:104FF00000908948804999F80020036876318748F5 +:1050000010F0BCFF11B0BDE8F08F2DE9F74F04465A +:105010008EB00020CDE90C00012A7CD1032013F0D2 +:10502000CCFA7F4D74487F4A2B7821462A3810F0FD +:1050300099FF032013F0DCFA28786F4942002A39DF +:10504000794815F02CFADFF8B881D8F8000090F80C +:10505000B201C0060AD568492A782A397348FFF791 +:10506000ADFE2A787149724810F074F8DFF890911B +:10507000A846D9F80000B0F8DF1161F30F06B0F9C7 +:10508000E111059161F31F46B0F8E31161F30F07D9 +:10509000B0F9E51161F31F478B4690F8E71161F312 +:1050A000070490F8F01190F8F10161F30F2460F318 +:1050B000174428780125CDE900670294CDE9035013 +:1050C000AE1E334632465A490CA800F0EAFDD9F824 +:1050D00000000024DFF8349190F8B2110DF1300A8D +:1050E000C1F30012C1F340131A4012EAD11F274640 +:1050F00015D090F8E81190F8E70198F80020CDE974 +:105100000301CDF800A0CDE901523346324699F8AB +:105110000100002100E0B3E000F0B0FEC4B2384866 +:10512000006890F8B21109061ED53949B0F9EA01B4 +:10513000497801B15846CDE9064798F80010CDE905 +:105140000105CDF800A0CDE903152B4933463246C1 +:105150002A39364800F0EFFE98F800003349420043 +:1051600025482A3815F09BF9234998F800202A3958 +:105170003048FFF723FEDFF888B0DBF8000090F836 +:10518000B211890615D52249B0F9EC01497801B16F +:105190000598CDE9064798F80010CDE900A0CDE9C3 +:1051A0000251154833463246049722494C3000F0EC +:1051B000C2FEDBF8000090F8B211C1F30012C1F397 +:1051C00040131A4012EAD11F50D00F9A0021012A31 +:1051D00003D189F8017089F8037034B190F8E811AF +:1051E00090F8E921B0F9EE0126E03BE01705100048 +:1051F00025071000227701202C0A0120960B0120A0 +:10520000A00710001C0B0120CE0C01200C05100083 +:10521000D80710000C0C0120E0061000820C0120C1 +:1052200024071000F87601206C0B0120EE0A012003 +:105230001A0D0120E20B012098F80030CDE9080298 +:105240000A91CDE90653CDE9044799F80300CDE969 +:105250000207334632460D49CDF800A00C4800F055 +:10526000B3FEC1B289F8014089F803100F9800908D +:10527000084898F8002006490368074810F07EFEA9 +:10528000C0E6064900200870704700001A0D012092 +:10529000780A0120E0061000580C01202B071000AE +:1052A0008B480021C0E90011C0E902111030C0E9AB +:1052B0000011C0E902111030C0E90011C0E902116B +:1052C00008468449087070472DE9F041DFF80482F0 +:1052D000814D002188F800102868804E804F90F89A +:1052E000B201804C80070BD50DF0B2FE296891F811 +:1052F000C31188420FDDE07810B17B48007850B1CF +:10530000286890F8B30100072CD53078012802D026 +:105310003878012826D1207808B9607810B3286839 +:105320003978B0F8BB41012902D03178012901D187 +:10533000B0F8C141B0F9BD11654801230A461030EB +:1053400000F0E0F828680123B0F9BF1160480A4670 +:10535000203000F0D7F822B2012311465C4800F05B +:10536000D1F811E05A484FF0FF311030C0E9001178 +:10537000C0E902111038C0E90011C0E90211203063 +:10538000C0E90011C0E90211584898F80020817B5B +:1053900062F386118173BDE8F0812DE9FF4F83B080 +:1053A0009346069991F84010022908D0012903D0AC +:1053B0000699898C890505D5454D20353CE0444D3D +:1053C000103539E04549424D0978012913D1484A41 +:1053D000127882B1474A1278012A0CD1464A1278D3 +:1053E000012A08D1454AD2E90034C5E90034D2E99E +:1053F0000232C5E90232384A126892F8B22112F03C +:105400000C0F19D0C1B936490978A9B93549C978FD +:1054100091B93B49097879B9C2F38101012902D0D8 +:10542000022905D008E04FF0FF31C5E9021103E081 +:105430004FF0FF31C5E900114FF0000A9BF8021050 +:1054400015F0C4F980469BF802002EE09BF800405E +:105450004A460120002114F0D8FFCDE900011CE0EC +:1054600018F804100498814216D1D5E90010DDE93E +:10547000002311401840014326D0D5E90267224697 +:105480000120002114F0C1FF06400F403E431BD015 +:105490000AF101001FFA80FA641C9BF80100A04287 +:1054A000DEDA08F1280809F101009BF803108146B3 +:1054B0004945CBDA06995FEA0A00A1F826A000D098 +:1054C000012007B0BDE8F08F002008F80400E3E7F2 +:1054D000201E100010051000A00710002905100064 +:1054E00018051000945A1000330710003857012097 +:1054F000320710002307100022071000501E100072 +:10550000B306100070B50446FC480D46007801282B +:105510000CD04FF0FF30C4E90000F94800780128B2 +:105520000ED04FF0FF30C4E9020070BDF5482346AD +:105530000178F54800F0A9FA204615F029F9ECE7C2 +:10554000F249F14804F108031C462A4609782A303A +:1055500000F09BFA2046BDE8704015F019B970B50F +:105560001C4605460123049EFFF7CCFF0020207057 +:105570003070E248E24A01210078012801D018B1D8 +:1055800005E0107870B102E01078012812D0D5E95A +:105590000002104319D0D5E90202104315D0217042 +:1055A000317014E0D5E90003184308D02170107859 +:1055B000012804D1D5E90202104300D031702078CF +:1055C000012804D03078012801D0002070BD0120CE +:1055D00070BD10B504460020024605E034F91230D3 +:1055E000834200DD1846521C8A42F7DB10BD10B51D +:1055F0000C461146FFF7EDFF6043642190FBF1F08C +:1056000000B210BD70B5C24EC24D30792968012874 +:1056100005D0C1484078A0B3B1F9B60170BD91F88A +:10562000010240062ED5B548B1F9B44100780128F1 +:1056300010D1B44891F82712007842B2B248FFF76F +:10564000D6FF30812968B1F8B421824202DBB1F87B +:10565000B4013081AA480078012810D1AB4891F8F4 +:105660002712007842B2A8482A30FFF7C0FF296805 +:105670000446B1F8B421A24201DBB1F9B44120469D +:1056800070BDFFE7B1F9B401FAE770B5A04CA349CA +:105690000025257101200870257065709D48A57052 +:1056A000E5700068B0F8B401E08000F00FFAFFF791 +:1056B000E8FDE5602561E3E72DE9F84381468F4881 +:1056C0008846964906788E48914C0F7805780020D8 +:1056D0000870E07000F0FAF99148007848B12A4665 +:1056E00039464046FFF77CFB324639464846FFF7CD +:1056F0008CFCFFF787FFE080014685482279801CFB +:10570000012AA0F10103009006D00A468548FFF760 +:1057100026FF2070BDE8F883B4F90820F6E72DE9EC +:10572000F04F0026DDE909BA9E463546DFF8E491E0 +:1057300026E093F830706F43002319E0FC1830F92D +:1057400014C0DC4504DDB1F80080C444A1F800C0F9 +:1057500030F91440CAF1000C644508DA761CB2F83E +:1057600000C0B6B2002C00DA6442644414805B1CB2 +:10577000D9F8004094F83040641E9C42DEDC6D1C79 +:10578000D9F8003093F83170AF42D2DCAEF8006047 +:10579000BDE8F08F2DE9FF4F87B000246248149DCB +:1057A000ADF80C40ADF81040ADF8184005944078C5 +:1057B000DFF85CB19046A146012875D0554A5B4B95 +:1057C00000211668B3F900300846B6F81E22DA4206 +:1057D00000D50121564A12781AB1564F002187F898 +:1057E00000902DB1534B1B7833B1012B53D0B2E055 +:1057F000504F002187F80090002A7DD1002D7BD0EA +:10580000002979D0B6F810723D4E424D3178012909 +:1058100005D13E4801783C482A3010F0E0FB296869 +:105820009BF80430B1F90E22012B03D1B1F82232DA +:105830001A4412B2404BB3F9003093425CDAB842DA +:1058400002DA3078012804D03C4A307812781043CC +:1058500052D1B1F814023A4AB1F8121200B2B2F9B8 +:10586000002009B28DE8070006AB04AA03A9404650 +:10587000FFF755FFBDF81000BDF80C1088426AD93B +:10588000012005902868B0F81612BDF81800814272 +:1058900061D801245CE047F6FF7596F83100EB43D0 +:1058A0000122A0F1010E1CE0A8E0264896F8307015 +:1058B000DFF894A030F91200A7EB000C5743022147 +:1058C000ACF1010C0AE007EB01083AF91800834239 +:1058D00000DA0346854200DD0546491C6145F2DBDE +:1058E000521C9645E1DCB6F818029842D1DBB6F8B6 +:1058F0001A024042A84229E02DE0000023071000D0 +:105900002207100024071000580C01202507100062 +:1059100014051000A0071000D8071000DF071000C2 +:105920002B071000501E1000AE051000800510005F +:1059300074071000290510007205100028051000DA +:105940003A07100034260120440D0120A1DC14B1D7 +:1059500000F0D8F801E000F0EBF8604E604D614FC8 +:105960003078012803D1387888B1012817D085F81C +:10597000009031783878814202D006200EF071FE16 +:1059800030783870BCB301218BF8041036E085F80C +:105990000090DDE90701012200F0F0F8E9E707F0E7 +:1059A0007CF9514995F800C0504B096891F81C22C8 +:1059B00002F00F02624504DA00F58050D0F8E00FE3 +:1059C00028B1B1F81802B3F9002090420FDD85F834 +:1059D0000090B1F81802B3F90010884202DC9BF87D +:1059E000000020B9DDE90701002200F0C7F828789F +:1059F000401C2870BDE7FFE78BF804903C480599F0 +:105A000020F85E1FBDF8181041809BF8041001714A +:105A10000BB0BDE670B5374A002423461278214604 +:105A2000521E52B2344D0DE035F91260864202DD4D +:105A3000491CC9B204E08C4200D921460C46002121 +:105A4000521E52B2002AEFDA8C4200D921462B4C6A +:105A5000294E00222478641E65B22A360DE036F9FC +:105A60001540844202DD521CD2B204E0934200D9B8 +:105A70001A46134600226D1E6DB2002DEFDA9342D6 +:105A800000D91A468818C0B2FAE52DE9F0471D463C +:105A90004FF00008C5E9008891460C46824610E0A8 +:105AA0003AF9141049450CDDD5E900674FF00108BB +:105AB00022464046002114F0A8FC06430F43C5E9E6 +:105AC0000067641EECD24046BDE8F0870C48002118 +:105AD000C0E90011C0E9021170470000290510005B +:105AE0002C0510002A051000A00710002E0510003C +:105AF0003857012024071000580C012025071000FA +:105B0000501E100041490022CA70487800280ED16A +:105B100008783F4B401CC0B208701B6893F80232F3 +:105B200003F00F03834202D2012048700A707047CD +:105B3000364900220A70487800280CD0C878344BC7 +:105B4000401CC0B2C8701B6893F80232B0EB131F40 +:105B500001D94A70CA7070472C4810B581784170DD +:105B600000210170C170FFF790FDBDE81040FFF704 +:105B700097BB264800214170817070472DE9F041A4 +:105B8000244B254C224DB3F90030012A05D02A6858 +:105B900092F81D62C6F1100212E002461E4810F093 +:105BA000E1F90FE030F9137031F913C0A7EB0C07DE +:105BB00034F913C057430CFB06773F1124F81370D8 +:105BC0005B1EEFD200210E4619E0144A12F8112094 +:105BD00012F0FF0390F83020A2EB030002FB01F269 +:105BE00004EB4202C0B2168003D107E022F8106035 +:105BF000401C2B6893F830308342F7DC491C28683E +:105C000090F831208A42E0DCBDE8F08128051000E0 +:105C1000A00710003A071000440D0120342601208F +:105C20002DE9F05F9846DDE90A9A93460E46044650 +:105C3000002532E02A460120002114F0E6FB00EAAC +:105C4000090001EA0A0108431DD0FE48FE4910F888 +:105C50001500097840B2091A4FB2410004EB470021 +:105C600014F09CFC00202080012009E004EB40019E +:105C700036F8102031F8021C114424F81010401C92 +:105C8000B842F3DB04E04FEA4801204614F086FCFA +:105C900006EB480604EB48046D1C5D45CADBBDE815 +:105CA000F09F2DE9FF5F86B0DDE914AB0FFA8AF0B3 +:105CB0000390DDF860800FFA8BF00490E3484078A1 +:105CC00028B14FEA2A4003904FEA2B400490002469 +:105CD00039E0079908FB04F001EB4005DDE9080114 +:105CE000224614F0A5FBC00724D0169ACDF800A0D8 +:105CF000CDE901B2DDE903214346284600F09CFCD2 +:105D0000064617980F46012817D0B8F1010F14D096 +:105D1000CC48012530F9149009E0A8EB05020120D8 +:105D2000002114F072FB86438F436D1CEDB2A94530 +:105D3000F3DA02E04FF0FF363746069800EBC40076 +:105D4000641CC0E9006717988442C2DB0AB0A6E76A +:105D50002DE9F05F1D46DDE90A9A93460F46064697 +:105D6000002420E0B7482246002110F81400281A29 +:105D700000F0FF08012014F048FB00EA090001EAE6 +:105D80000A01084305D04246394630460FF0E2F991 +:105D900004E04FEA4801304614F000FC07EB4507E9 +:105DA00006EB4506641C5C45DCDB78E72DE9F84F23 +:105DB00083460AA8002690E8280590B289460090FC +:105DC00031463446B446374630460FE0DA0708D04D +:105DD00039F9102000FB004400FB02770144944491 +:105DE000761C6D084FEA330300F101004045EDDBFE +:105DF00004FB06F001FB1105F5B107FB06F004FBFF +:105E00000CF407FB114701FB1C06002410E006FB05 +:105E1000047090FBF5F1A1EB0A00009900F0C9FFB6 +:105E200039F81420A2EB0A01081A2BF81400641C9C +:105E30004445ECDBBDE8F88F4FEA48024946584636 +:105E4000BDE8F84F14F02BBBF0B50026354609B17C +:105E500000240DE00020F0BDD70704D030F9147005 +:105E60006D1C3E44EDB25B084FEA320204F10104BE +:105E70008C42F1DB96FBF5F000B2F0BD2DE9FF5F3F +:105E800086B00025DDE91619A8464FEA510A4FEA07 +:105E9000590B2C4649E0DDE90801224614F0C8FA06 +:105EA000C00741D01498524600EBC4010491D1E9D7 +:105EB00000670120002114F0A8FA401E41F1FF31D3 +:105EC0000F4004990640CDE90067D1E90001524630 +:105ED00014F0AEFACDE902010821684613F0DEF8AD +:105EE000C7B2082102A813F0D9F8C6B2B819C0B2D7 +:105EF0000490DDE90601224614F09AFAC00704D0A6 +:105F0000DDE91701084400F0FF090498484503D370 +:105F10005F4501D35E4507D222460120002114F0DF +:105F200074FA054341EA0808641C15988442B2DB00 +:105F3000284641460AE72DE9F04F85B08146119F7A +:105F40000024780092469B468846049036E00E98DE +:105F500000EBC400D0E900561298012801D125F0C9 +:105F6000010550465946224614F062FAC0071CD07B +:105F7000DDE91401224614F05BFAC00705D0414662 +:105F80004846049A14F08BFA13E02A463346394601 +:105F90004046FFF759FFCDE90270CDE90056414672 +:105FA00048460F9AFFF702FF03E04846049914F0B1 +:105FB000F5FA08EB470809EB4709641C109884427E +:105FC000C5DB05B0BDE8F08F2DE9FF5F86B08A46DE +:105FD00000211B9F04907800884689460C46DDF816 +:105FE00074B0059058E01498224600EBC400D0E944 +:105FF0000056DDE9080114F01BFAC00741D0DDE9C5 +:106000001801224614F014FAC0073ED03A4628463A +:1060100031460FF0D3F80090DDE91601224614F066 +:1060200007FAC00704D0DDE91D01084400F0FF0BAA +:106030000098584516D92A46334639465046FFF748 +:1060400003FF05E03426012025071000D8071000C3 +:10605000CDE90270CDE9005651461C9A0498FFF72D +:10606000A5FE12E0DDE90402514614F018FA2246BA +:106070000120002114F0C9F940EA080841EA0909A1 +:1060800003E05046059914F089FA04980AEB470A90 +:1060900000EB4700641C04901A988442A3DB40463E +:1060A000494653E62DE9FF5F9846002537E0019900 +:1060B00008FB05F001EB400B0099002601EB400ABC +:1060C00037462A460120314614F09FF9DDE91023B6 +:1060D0001040194008431BD00E98002400EBC5095E +:1060E00014E0F848025D3BF812102AF81410D9E9C0 +:1060F000000114F09DF9C00706D0224601200021BE +:1061000014F083F906430F43641CE4B24445E8D31A +:106110000E9800EBC5006D1CC0E90067EDB2029857 +:106120008542C4D3BDE8FF9F2DE9FF4F81B099465A +:1061300000253BE0029909FB05F001EB40010091CD +:106140000199002601EB400B37462A4601203146D3 +:1061500014F05BF9DDE910231040194008431ED00C +:106160000E98002400EBC50A17E0D64810F804800A +:10617000009830F814202BF81820DAE900012246A4 +:1061800014F056F9C00706D042460120002114F051 +:106190003CF906430F43641CE4B24C45E5D30E982A +:1061A00000EBC5006D1CC0E90067EDB203988542A5 +:1061B000C0D306E72DE9F74FC34E0F468CB03068C9 +:1061C000002190F83120012014F01FF9441E41F104 +:1061D000FF35BC49002018390870B821BB4814F0BD +:1061E000FFF9032012F0E9F9306890F8E602C007E1 +:1061F00014D0B748007888B9B6480178B6480FF08F +:10620000FAFE3168B1F80923B449904202DCB4487F +:106210004078D0B1B34A0020D0700870B248DFF89F +:10622000D0923946B0F90030B0480268D9F8000081 +:106230000FF098FEA448006890F8010200064ED5C1 +:10624000AC480078012804D049E0A6490120C87074 +:10625000E4E70021DFF8A0A2DFF86CE239E0A74A0A +:1062600090F8300032F9112000FB01FB871A012061 +:106270002CE0D9F800600BEB000336F91320B2F1E3 +:10628000000C01DACCF10002BAF90080424513DDBE +:1062900091B1DEF8002092F83120521E8A420BD0D4 +:1062A000012809D07A1E904206D05FEA0C0201D57F +:1062B000CCF10002AAF80020DFF844C236F813201F +:1062C000401C3CF813C0624426F81320B842D0DBCF +:1062D000491CDEF8000090F831308B42BFDC03200F +:1062E00012F086F9784EDFF81CB2306890F81D0184 +:1062F000C00714D07B48417A89B9817A79B9C078CE +:1063000068B981480078012809D072489BF80020BC +:106310000178D9F8000001F048F904460D463068CC +:1063200090F83402400713D5CDE90045694F5E4629 +:106330009BF800303A78D9F800100C98FFF770FC01 +:10634000CDE9004533783A7870480C99FFF700FDA5 +:10635000DFF874A1049B039ADAF80000DFF8748177 +:10636000B0F8511261F30F03B0F95312059161F3C4 +:106370001F43B0F855121F4661F30F02B0F95712D0 +:10638000069161F31F4290F85932029990F85D62CC +:1063900063F3070190F85C3298F8000063F30F2173 +:1063A0009BF8003066F317410097CDE90121CDE954 +:1063B000030322462B4655495548FFF772FC3146E8 +:1063C00053480EF018FFDAF800100026DFF840A15D +:1063D00091F834023746C0F38002C0F3C0031A407C +:1063E000C0F34000024224D091F85A0291F85912A9 +:1063F0009BF8003098F80020CDF800A0CDE90123EB +:10640000CDE903102F48224618382B46D0E9021652 +:1064100008463146FFF732FD06460F46084308D0CE +:106420002948006890F85E2230460EF05DFE064670 +:106430000F462548006890F834128A0778D5B0F9DD +:106440004B0201902648407808B1069801908806D2 +:106450000ED5CDF800A0CDE902459BF8003098F8A4 +:1064600000202C48D9F80010FFF71CFE294901E054 +:10647000D9F80010CDE906679BF8003098F800C005 +:106480000120CDF808C0CDF800A0CDE903302246A8 +:106490002B460C98FFF74FFD0B48006890F834022C +:1064A00080063AD5CDE90245CDF800A09BF8003032 +:1064B00098F800200C99D9F80000FFF735FED9F8BC +:1064C00000102BE048051000A0071000181F100056 +:1064D0007407100024071000F87601203007100020 +:1064E000D8071000945A10003A07100058071000FF +:1064F00054071000290510002E0510003426012035 +:10650000440D01202507100018051000D04F012070 +:10651000601E1000801301200AE00C9998F800001A +:1065200042009BF800004243D9F8000013F0B7FF87 +:106530005448CDE90045C346037898F800205248F6 +:10654000D9F80010FFF76CFBDFF84081D8F80000A5 +:1065500090F83412090718D54D49B0F94D02497821 +:1065600001B105984749CDE9066700220B789BF8F1 +:106570000010CDF800A0CDE90332CDE9010122469B +:106580002B4641490C98FFF7D6FCD8F80000C146CD +:1065900090F83412C1F38002C1F3C0031A40C1F372 +:1065A00040010A4231D000220E9B1146012B05D139 +:1065B000384B9046C3E90288C3E9048856EA0703CA +:1065C0001ED0304B90F85A1290F85B22B0F94F026F +:1065D0001B78CDE9080207930A919BF80000049606 +:1065E000CDE905702B4822462B46D0E90410CDE9B1 +:1065F0000210CDF800A028490C98FFF7E5FC0246F0 +:106600002448C0E90421C0E90267D9F8000090F8E5 +:106610003402C00608D51B48CDE900459BF80010A0 +:1066200002780C980FF0F9FC204629460FB0C9E417 +:106630001A490020087070472DE9F0470F46994627 +:10664000804611460A9E0EF000FD04460D46002FBE +:1066500016D04B463A466FF0004140460EF014FD0E +:1066600004F00102024304EA0200294001220EF074 +:1066700064FDC6F30722002A02D04B460EF0BDFC93 +:10668000BDE8F0872507100080130120A007100047 +:10669000D807100030051000D04F01202A07100045 +:1066A0002DE9F05F1E4615460F46824600244FF046 +:1066B000AA094BE0305D08B9285DE8B306F80490FC +:1066C00037F9140000F0C8F827F81400285D98B3D3 +:1066D00005EB040818F8011C814218D0AA2816D02E +:1066E0000AEB440B08F8019C3BF9020C00F0B4F8EB +:1066F0002BF8020C311907EB440B01F8019C3BF914 +:10670000020C00F0A9F82BF8020C285DA0B198F853 +:106710000110285D814218D0AA2816D088F801906F +:106720000AEB4408B8F9020000F096F83119A8F80D +:10673000020081F8019000E007E007EB4408B8F997 +:10674000020000F089F8A8F80200641C0A9884424C +:10675000B0D3BDE8F09F48490020086070472DE99C +:10676000F74F464884B0924600788946002870D09A +:106770004348006890F8700C80076AD54148009043 +:106780004148DFF8F4B0012507784FF00008DBF846 +:1067900000601FE00120A84030421AD13B4800EBC6 +:1067A00085040098A17814F011F8A27843460DE012 +:1067B000217805E010F801C0AC4500D14354491CD4 +:1067C00094F801C08C45F5DA2830521CE1789142EA +:1067D000EEDA6D1CBD42DDD90021049813F0FCFFF8 +:1067E00002900121049813F0F7FF01900021254841 +:1067F00013F0ECFF07460121224813F0E7FF06469D +:10680000A9F10105E9B2049813F0E6FF6C1E0390AC +:10681000E1B2049813F0E0FF8146E9B2194813F0A1 +:10682000D5FF0546E1B2174813F0D0FF0446CDF876 +:1068300000A0DDE9011033463A46FFF731FF234659 +:106840002A464946CDF800A00398FFF729FFCBF868 +:10685000008007B0BDE8F08F0949096891F8782CED +:106860004243642092FBF0F0B1F8762C00B28242F1 +:1068700001DAB1F9760C70476C051000E8061000DB +:10688000A00710001E27012071061000B62A012063 +:106890002DE9F041FE4E2A21FE48376807F2826555 +:1068A000EC1C13F07BFEFB4897F8312097F8301072 +:1068B0002A3013F06BFE00221146F64F33681DE0BC +:1068C000A05C884201DA521CD2B2A85C27F8110001 +:1068D00090B193F83060DFF8BCC3301AC0B20CF14D +:1068E0002A0C05E01CF80060761E0CF80060401CC5 +:1068F00093F830608642F5DC491C49B293F83100C8 +:106900008842DDDCBDE8F0812DE9F04F89469246F2 +:1069100086460021DFF878B34FF0640C099E45E00D +:1069200001FB06E700203EE0DBF80020802492F81F +:106930002D5B5FEA45781FD592F8158C884503D109 +:1069400092F8168C804526D092F8178C884503D192 +:1069500092F8188C80451ED092F8198C884503D186 +:1069600092F81A8C804516D092F81B8C884503D17A +:1069700092F81C2C82420ED011B15A1E914219D1AC +:10698000AA0703D538B1721E904204D01AF800202D +:10699000D201B2FBFCF43A5C6243D41702EB5462BE +:1069A000D2093A54401CB042BED3491C9942B7D3D5 +:1069B000BDE8F08F19F80020EAE72DE9F05F944672 +:1069C000B54ADFF8D8A2DDF8308016789AF80020B2 +:1069D0003746761E06FB02F400EB440506FB02C0B8 +:1069E00008FB0306AE48DFF8A88201EB44040378F5 +:1069F000AC48DDF828B04FF000090279C178D8F82A +:106A000000006BB101B942B190F8131C90F8140C5E +:106A1000814200D30146894626E090F8130C03E03A +:106A200001B90AB390F8140C81461DE058463A4665 +:106A30000B9913F0FDFCC0070DD09AF8000008E098 +:106A4000335C34F9101003EB09025143C91125F8E6 +:106A50001010401EF4D2D8F8000090F83000A5EBDA +:106A60004005A4EB4004361A7F1EDFD2BDE8F09F3C +:106A700008B5009313468C4AB2F900200FF07EFA55 +:106A800008BD2DE9F05F874A1046D178007901B939 +:106A900008B1012400E0002484494B780021022B36 +:106AA00001D3917000E000B1D170DFF8E4A1D0789B +:106AB0009146DAF80010B1F9B9C2B1F9D462B1F96E +:106AC000E87228B17A480078012801D1B1F901C3F0 +:106AD00078480078052801D0062801D1B1F9B6C25E +:106AE000022B05D3B1F8BD2212B1B1F9BDC20DE040 +:106AF00063B191F8BC2262440FFA82FC91F8D7226C +:106B0000324416B291F8EB223A4417B26A4DDFF8DC +:106B1000ACE16B4AA5F800C0AEF800601780694A86 +:106B200005283DD006283BD091F8BB82DFF8A0B104 +:106B3000ACEB0808A2F8008091F8D682A6EB080812 +:106B4000614EA6F8008091F8EA82A7EB08085F4F33 +:106B5000A7F800809BF80080B8F1000F05D09BF8E3 +:106B60000280ACEB080CA2F800C099F800C0DFF876 +:106B700030B1BCF1000F1ED09BF800C0BCF1000F7B +:106B800019D0B1F805C2A5F800C0B1F807820528F0 +:106B9000ACEB080CA2F800C005D0062803D00AE030 +:106BA00091F8B882C2E7B1F80A022880B1F80CC2A5 +:106BB000A0EB0C00108099F8020028B9B5F800C0CD +:106BC000AEF800C01088308034B93D48B5F800C038 +:106BD000A0F800C01088388028883E4DDFF8F8C043 +:106BE0002880B2F900003D4AACF8000012786AB182 +:106BF00013B191F8752C00E00022B1F8723C1A44F0 +:106C00002A8091F8741C511AACF80010B7F90020D2 +:106C1000B6F900100EF018F9314908809BF8000011 +:106C200030490028DAF8000002D0B0F8450206E04A +:106C3000B0F843220A80002C02D0B0F84702088046 +:106C400014E72DE9FF4F82B00027DDE91142DDE9AD +:106C500013C80F9D224374D00026B146B646B346F2 +:106C6000B246BCF1000F01D0159D47463A4645E0BB +:106C70005FEAC47C0BD031F912C002FB029902FB1F +:106C80000CBB1644E6440AF1010ACDF800C02BE023 +:106C9000A00710003426012024071000250710004B +:106CA00029051000945A10003A071000D807100068 +:106CB0003107100021071000D0061000D206100086 +:106CC000D4061000D6061000D8061000DA06100010 +:106CD00074071000E4061000E606100039071000E3 +:106CE000DC061000DE061000DDF848C002F10102EB +:106CF0005FEA5C0C4FEA3404CDF848C0AA42B7DB27 +:106D000009FB0AF206FB16220092BAB30BFB0AF249 +:106D100006FB1E22019209FB0EF20BFB162A4FF016 +:106D2000000C62463C4622E0DDF80480009E08FB31 +:106D300004A898FBF6F6DDF81080464502DD4646CD +:106D400003E033E0DE4200D55E4231F81480A8EB68 +:106D5000060636B2B1469E4206DA06EB0308B8F1E3 +:106D6000000F01DDCC44521C20F81490641CAC428E +:106D7000DADB002A0BD09CFBF2F206E00EE030F8E2 +:106D80001710891A20F817107F1CAF42F7DB06B0E6 +:106D90000EE631F8172020F817207F1CAF42F8DBF1 +:106DA000F5E731F8172020F817207F1CAF42F8DBF9 +:106DB000EDE7884202DC4942884200DA0846704723 +:106DC000F0B50026354609B100240DE00020F0BDE5 +:106DD000D70704D030F914706D1C3E44EDB25B0847 +:106DE0004FEA320204F101048C42F1DB96FBF5F02C +:106DF00000B2F0BD2DE9F05F5FEA0109DDE90ACEDE +:106E00000E9E05467ED052EA03007BD04FF000086C +:106E10009A464046414647464446B346434611E0FB +:106E2000D60709D035F9136003FB031103FB0644B1 +:106E30001844374408F101085FEA5A0A4FEA32025F +:106E400003F101034B45EBDB01FB08F200FB1026CD +:106E5000002E57D004FB08F200FB1728794304FBEF +:106E600010175FEA0E0057D00024A9F1020210E0CB +:106E700008FB047090FBF6F0A0EB0C005946FFF7FE +:106E800098FF35F81410A1EB0C01081A25F814002E +:106E9000641C9442ECDB0C984FEAC01A0D984FEA40 +:106EA000C01B08FB047090FBF6F935F91400594635 +:106EB00000EB8000000290FBF9F00DF0DBFF514683 +:106EC0000DF0DCFF09FB00F14FF00A0991FBF9F02E +:106ED00035F81410A1EBE01025F81400641C08FB31 +:106EE000047090FBF6F635F91400594600EB80006B +:106EF000000290FBF6F00DF0BDFF51460DF0BEFF15 +:106F0000464300E007E096FBF9F035F81410A1EBDA +:106F1000E01025F81400A9E5002210E008FB02703B +:106F200090FBF6F0A0EB0C005946FFF742FF35F856 +:106F30001210A1EB0C01081A25F81200521C4A4548 +:106F4000ECDB93E52DE9FF5FDFF828A40E46002473 +:106F50000E9D1F4691464FF466713046CAF80040B8 +:106F600013F01CFB002130462C6013F02FFC04466C +:106F70000021009813F022FCDFF8FCB30246FF4E1C +:106F80009BF800C019E030784FF001080FE032F9AB +:106F900010304B4501DD04F8008032F91010F94241 +:106FA00005D52B68002900DA494219442960401EA2 +:106FB000EDD23078283402EB4002BCF1010CE2D271 +:106FC000EF48C07800281BD00021009813F0F6FB92 +:106FD000EC499BF80030524634780D680EE02146AB +:106FE00008E030F91160B5F8FB72BE4202DD1668A8 +:106FF000761C1660491EF4D200EB44005B1EEED2F4 +:10700000BDE8FF9F05E030F912308B4201DD012021 +:107010007047521EF7D2002070472DE9FC47DA482E +:10702000DA4DDB4FB0F90230B5F900003A88594328 +:10703000821A14B2642291FBF2F109B2814200DD9E +:1070400008462880CF48026892F88112490632D556 +:10705000D04EB2F89DC2B6F900109C4526DAB2F8BF +:107060009F328B4222DD8146CB48B2F8A4C2006831 +:107070000CEB8C08B0EB480F18DD8021CDE9003116 +:10708000B2F8A21292F8A13201EB81014A000CEB96 +:107090008C01C84649000EF029F901B2D8F8000069 +:1070A000B0F89F228A4201DAB0F99F12B6F90000C7 +:1070B000814200DD31802888001B3880BDE8FC87D4 +:1070C0002DE9FC47B548ADF80000ADF80400B44820 +:1070D0000027DFF8D082B0F90000DFF8CCA2420030 +:1070E0003E463D463C46D8F80010DAF8000013F062 +:1070F000D6F9A349A3480A781AB1AC4A1278012AF2 +:1071000002D0C978C1B11DE08146006890F8011233 +:10711000490708D5B0F92032A54ADAF80010D8F8A6 +:10712000000009F0C1FFD9F8000090F8011209072A +:1071300008D590F8244205E09E4900684978B9B125 +:1071400090F825419C4801AA69460378D8F80000C8 +:107150000EF0F3FF24B12146D8F80000FFF75DFFE1 +:10716000BDF90010BDF90400814204DD0A4603E0C8 +:1071700090F82641E6E70246834B5A808F4AB2F9DF +:107180000020914200DD01268D4AB2F90020904294 +:1071900000DD01258B4A2E43157000D001278A4A55 +:1071A00012F8873F67F3000365F341031370A2F8F9 +:1071B0000110A2F80300384680E72DE9F74F834F0E +:1071C00086B0DFF8C0B13E780496DBF80000914647 +:1071D000002190F83120012013F017F9441E41F1ED +:1071E000FF35304608F073FA4FF0000887F800804A +:1071F000FFF747FC64480221001D0BF099F9604F2E +:10720000614EDFF8CCA1387808B9787828B14946C2 +:1072100072680798FEF750FA01E08AF80080F87A61 +:10722000DFF88091012805D0787A012802D0B87A59 +:10723000012803D19AF8000001284BD06548007856 +:10724000012806D1049A06997068FEF7B3FF044638 +:107250000D46DBF8000090F835124A0605D4090601 +:1072600003D490F82D0BC0070CD05B485B4A007824 +:107270000094CDE901504A487168B0F900300846E1 +:10728000FFF79BFBDBF8000090F834120A0604D4E9 +:10729000490610D5F97801290DD1B0F9490201A9A3 +:1072A000009081E8310035487168037832480278EF +:1072B000084600F005FB314802782F4801787068D5 +:1072C000FFF74DFA4648049B71680268D9F8000040 +:1072D000FFF7CEFBDBF800005D4690F81D1CC907E8 +:1072E00015D0264B90F8161C90F8150C1C7800FB56 +:1072F0000414D9F8001021F8148028681B7890F83D +:10730000184C90F8170C00FB034021F810802868F7 +:1073100090F8441AC90706D0D9F8001090F8452A09 +:10732000084609F04BFC18480221001D0BF05EF9DD +:10733000F97A0020012905D0797A012902D0B97A99 +:10734000012903D19AF80010012901D0FFF7B8FEF6 +:10735000244A254E0121C2F80080064AC2F8008066 +:10736000224AC6F8008082F80080FB7A012B65D0A3 +:107370007B7A3DE0C40610002407100025071000AA +:10738000945A1000A007100070051000D0061000DD +:10739000D6061000DE061000600710000080FFFF18 +:1073A0003A0710004C071000500710002905100084 +:1073B00006A80100D807100074071000DC061000B2 +:1073C000E60610002D07100038570120DE071000D8 +:1073D000140510002A07100035071000BC19012001 +:1073E000E0061000C0061000C80610002C071000B0 +:1073F000012B23D0BB7A012B20D018B31170387821 +:1074000018B1F8480078012824D002240121F64858 +:107410000BF08EF82968F54AB1F86B0212780AB1C0 +:10742000B1F86002009603B2F148B0F90020EE48CE +:107430000168D9F80000FFF785FD04E09AF8000024 +:10744000012804D00124204609B0BDE8F08F0624AD +:107450001170F8E70324D9E7FEB50746E548002593 +:1074600006780570FFF70DFB0221E3480BF060F88A +:10747000E248E14C0078241F012804D13246394605 +:107480006068FEF797FEDE4EDE4F306890F83512EA +:107490004A0605D4090603D490F82D0BC0070DD079 +:1074A000D948DA4A007802904FF0FF30CDE9000069 +:1074B0006168B7F900300846FFF77FFA6168B7F9ED +:1074C0000000D34C4200206812F0E9FF306890F8C9 +:1074D0001D1CC90714D0CF4B90F8161C90F8150C42 +:1074E0001A7800FB0211206820F8115031681B78CF +:1074F00091F8182C91F8171C01FB032120F811506A +:10750000306890F8441AC90705D0216890F8452AD8 +:10751000084609F053FB0221B7480BF067F8BE4854 +:10752000B7F90020B0F900102068FFF76BFDBB49E8 +:10753000BB4E0D60BB4935600D7090B101200870E5 +:1075400001460225A8480AF0F3FFA948009647F62D +:10755000FF73B0F90020A44801682068FFF7F2FC2F +:1075600000E001252846FEBDA34910B5091F0020F3 +:107570004860AC490870AC490870FFF759F8FFF74C +:10758000EAF8BDE8104000F013B910B500F05CF95E +:10759000FFF77EF99A48006890F88102000603D54B +:1075A000BDE8104009F07DBE10BD2DE9F74F86B053 +:1075B0000020CDE90000CDE90200814690480F4649 +:1075C000164600680025B0F91E110591B0F920019A +:1075D00004902FE005FB06F00FFA80FB04980124CD +:1075E000C0F1000A2A462046002112F00EFFA446F0 +:1075F0000A460CFA05FC4FF0000817E006990BEB61 +:10760000040331F91310059B994201DC514506DA58 +:10761000DDE9003403431443CDE9003434464945E1 +:1076200002DDCDE902C88946641C24B2B442E5DB20 +:107630006D1C2DB2BD42CDDB714C206890F822212B +:107640002AB1DDE900010DF04FFDCDE90001206810 +:1076500090F81D01800762D5DDE9000108435ED086 +:107660000821684611F01AFDC1B2206890F8230184 +:10767000884254D9401E40F34702DDE902010DF073 +:1076800033FDCDE9020105460E463A4601200021B0 +:1076900012F0BBFE401E41F1FF3100EA050231400D +:1076A000CDE90221082102A811F0F8FC2168C0B23E +:1076B00091F8231181422CD97A1E0120002112F069 +:1076C000A4FEDDE9022310401940084310D0781EC3 +:1076D000012305E0029D03FA00F12943401E0291B7 +:1076E000216891F82311791A491E8142F2DB10E0DA +:1076F000D0070ED00020012306E0029D03FA00F11E +:107700002943401CC0B20291216891F823118142A3 +:10771000F3D89DE80F0010431943CDE9000120681C +:10772000002190F83120012012F06FFE401E41F13F +:10773000FF33DDE9001201401A40CDE90012206854 +:107740002D4D90F827012D1FF0B12B786BB15B1CEC +:10775000DBB22B70984201D3114301D0002012E01C +:10776000D5E90201CDE900010EE03048007858B1BA +:10777000114309D1D5E9020150EA010204D0CDE953 +:107780000001D8B2401C2870DDE9000108430BD18C +:107790002068002190F83120012012F036FE401EB2 +:1077A00041F1FF31CDE900010098C5E902014BE646 +:1077B000134810B500681E491E4AB0F8B9320B8054 +:1077C000B0F8D4121C4C1180B0F8E82222801B4C77 +:1077D00023801B4B19801B490A800549B0F84302DE +:1077E000088010BD2905100088061000B30610009F +:1077F000DE061000DE071000740510002A071000D6 +:10780000A00710003A07100035071000BC1901202E +:107810004C07100025071000DC061000C006100001 +:10782000C80610002C0710002D07100032071000AA +:10783000D0061000D2061000D4061000D6061000A4 +:10784000D8061000DA0610002DE9F84F3B4C2068EE +:1078500090F8319010F8307F90F8450100F0030265 +:10786000C0F38101C0F301100DF0F5FA25688046E0 +:107870004FEA89002B4605F62F367843304A80219F +:1078800005F6553500E01154401EFCD293F82D0B3F +:10789000C00713D000249246DFF8A8B00CE0009790 +:1078A000BBF900104B4604FB01A02A463146FFF706 +:1078B0002BF8641C4C354C364445F0D9BDE8F88FA4 +:1078C0002DE9FF4F8646DDE90FAB1D46DDF834900C +:1078D0002FE00199002601EB45071B4930464A5D20 +:1078E0000E991446C1F1000C09E004FB03F137F9CD +:1078F0001110494503DA614501DD0E44401C641E48 +:10790000F3D200B9012096FBF0FC504659460EEB2D +:1079100045060CE0C40707D002FB03F437F81480D7 +:10792000A8EB0C0826F8148049084FEA3000521ED4 +:10793000F0D26D1ECDD2BDE8FF8F0000A007100071 +:10794000BC1901203A0710005E2601209048002152 +:1079500001704180704730B58E49024601200B68A6 +:1079600093F84B464CB18A4DB2F842106D68491BF2 +:1079700000D549428C4200DA002093F84C36002BA7 +:1079800012D08349B2F91A500831B2F91820B1F96E +:107990000240B1F90010641B891A644301FB0141E4 +:1079A0005B43994200DD002030BD2DE9F047DFF850 +:1079B000E491DFF8DC8105004FF005044FF0060686 +:1079C00013D095F8C60100F04EFA0446D9F800002D +:1079D000012790F84A0618B1B5F84210814210D834 +:1079E000A86900F0AAF860B157B398F80000002722 +:1079F0000121072810D2DFE800F00606263F7206B4 +:107A000006000027F0E7052C04D0042C06D0012C3A +:107A100007D015E088F80070BDE8F08788F80010FE +:107A2000FAE7FFF793FF022088F80000A8F8027039 +:107A3000B5F84200C8F80400A869C8F80800EBE7E8 +:107A400088F80060E8E7B8F80200401C80B2A8F8A7 +:107A50000200032C04D0D9F8001091F845164AE032 +:107A6000032088F80000A8F80270D5E7052CD3D0D1 +:107A70002846FFF770FF2FE0B8F80200401C80B2E4 +:107A8000A8F80200012C1FD0D9F8002092F8463641 +:107A900042468342C0D8167098F80100012801D0F0 +:107AA0000328B9D13C483A4A417019210832817003 +:107AB0005188C170090A017111884171090A8171E7 +:107AC000BDE8F0470CF0D3BD2846FFF744FF042281 +:107AD00088F80020A8F802700028B1D09CE7B8F818 +:107AE0000200401C80B2A8F80200032C06D0D9F88E +:107AF000001091F847168142B8D8A1E7052088F810 +:107B0000000089E738B500210091694600F089F945 +:107B10001F4C012802D90620207005E00098FFF7CD +:107B200044FF2078052801D0002038BD1A480121E3 +:107B3000417005218170012038BDF0B51549064618 +:107B40000120096891F84826930091F849261D46BE +:107B5000940091F83620D7074A8E898EA2EB030253 +:107B6000A1EB040112B209B20ED023460F462C46F7 +:107B70003114994206DBB94204DC31B2A14201DB87 +:107B8000914200DD0020F0BD17460A46F0E70000F4 +:107B900084051000A0071000D01F100000F0ECBA00 +:107BA000BA4890F82C00062801D0052807D1B8481B +:107BB000B849006890F83E0200F00F000860B6492E +:107BC0000020487000F0E4BA70B50646B3480021C2 +:107BD0000278062A03D012B1052A00D00121B0484C +:107BE000AD4C0278012A2ED0022A2CD0032A2AD0AA +:107BF00049BB12F0AFFD012825D0AA48007806281D +:107C00002AD1607820B1401E10F0FF00607023D1AF +:107C1000002404EB041006EB40152946304604F01E +:107C2000F2FF2946304605F026F8641CE4B20F2C1A +:107C3000EFD39D48007805280ED0BDE87040102194 +:107C4000012010F01ABC9248006890F8780060702B +:107C50000A2801D20A20607070BD2DE9F04100248D +:107C6000054600F580560127D6F8E00F07FA04F123 +:107C7000084208D004EB041005EB401000F1180195 +:107C80000C300DF0E3FC641CE4B20F2CECD3BDE827 +:107C9000F0812DE9F0474FF000094FF0010A064648 +:107CA000C8464C4600F580575546D7F8E00F05FA10 +:107CB00004F108420AD004EB041106EB411191F8DB +:107CC000C601032802D1304604F0BBFF641CE4B2B5 +:107CD0000F2CEAD33046FFF7C0FF744800216E4CEA +:107CE000016041608160C160A068C00104D5304678 +:107CF00000F089FD012809D0BAF1000F06D0207AE2 +:107D0000800603D53046FFF7FDFE8146B9F1000F2E +:107D10000AD1A068C0011BD5304600F04DFB644974 +:107D200008704FF0180898B160480CF0A0FCB8F14A +:107D3000180F0BD15D4808300CF097FC584880793B +:107D400000EB001006EB40100CF07CFCFFF7FEFD92 +:107D50000024A84606F5805708FA04F0D7F8E01F7B +:107D600001420FD004EB041106EB411595F8C60152 +:107D7000082807D12946304604F07DFF29463046C1 +:107D800004F041FF641CE4B20F2CE5D33046BDE89B +:107D9000F04719E72DE9F84F06463D48006890F88E +:107DA000500CC00738D03046FFF757FF3A4F4FF01E +:107DB0000009B868C00131D5304600F0FEFB8046AE +:107DC0003A4800240830CA464FF0010B06F58055AA +:107DD000B94600901CE0D5F8E01F0BFA04F05A46B3 +:107DE000014214D004EB041006EB4017B8F1000F69 +:107DF0000BD089F800202D480CF039FC00980CF0CD +:107E000034FC38460CF01EFC01E089F800A0641C2C +:107E100095F9EC0FA042DEDABDE8F88F87F8009004 +:107E2000FAE730B505460020034603EB031205EBE5 +:107E3000421494F8C621012A0DD0022A0BD0032A3D +:107E400009D0042A07D0052A05D0062A03D0072A1C +:107E500001D0082A02D1401CC0B20C605B1CDBB20E +:107E60000F2BE2D330BD09280ED2DFE800F00D055C +:107E700005070909090B0B00042070470120704712 +:107E800002207047032070470520704714841000BB +:107E9000A0071000E00610009005100084051000F7 +:107EA0003820100021071000F8041000D01F100027 +:107EB000AA0510002DE9FE4FFE49B0F902C0B0F945 +:107EC00006700A68B0F90060934692F83690918E79 +:107ED0005FEAC978B0F90450528E4FEA497809D068 +:107EE000B8F1000F22DA961B551B66F31F4465F3A9 +:107EF0001F431FE0B8F1000F07DAA2EB0C0CD71BF1 +:107F00006CF31F4467F31F4303E067F31F446CF3F4 +:107F10001F435FEA897704D58E1B66F30F044D1B60 +:107F200010E065F30F0466F30F0312E065F31F44DE +:107F300066F31F435FEA897507D5A1EB0C0565F36E +:107F40000F04CD1B65F30F0303E067F30F046CF31D +:107F50000F039BF830804F1CB2FBF8F59BF8319073 +:107F60002EB2B7FBF9F52DB2002A75D0002973D0D7 +:107F7000002E71D0002D6FD01F144FF0000B12D0C7 +:107F800097FBF6FC6CF3070A97FBF6FC06FB1C77E5 +:107F9000BFB24FEA244C624509DCA8F1010262F34A +:107FA0000F2AB2B20CE06BF3070A0027F1E79CFB43 +:107FB000F6F262F30F2A9CFBF6F206FB12C292B2B3 +:107FC0001BB28BB193FBF5FC6CF3174A93FBF5FCEA +:107FD00005FB1C339BB224B2A14209DCA9F10101CB +:107FE00061F31F6AA9B20CE06BF3174A0023F2E7B2 +:107FF00094FBF5F161F31F6A94FBF5F105FB114168 +:1080000089B202EB8202520092FBF6F21FFA82FE64 +:1080100007EB870403EB83026400520001EB81014C +:1080200094FBF6F492FBF5F2490091FBF5F1C4F1F3 +:108030000A04C2F10A02A4B292B289B28DE8160013 +:108040000AF0FF034FF0000C9B46CAF307464FEAC5 +:108050001A65CAF3072726E036E09B4502D102994C +:108060000CB205E09F4202D10FFA8EF400E00A2420 +:10807000019A31460FFA82F9009A0FFA82F80EE05F +:108080008E4201D14A4604E08D4201D1424600E0D1 +:108090000A2204FB02C2491C0FFA82FC09B28D427B +:1080A000EEDA5B1C1BB29F42D7DAA0F80CC080F856 +:1080B00008B0477202990182A0F812E08672C57278 +:1080C000019981820099C182BDE8FE8F70B57A481E +:1080D000784D7A490378286801F11C0490F8512CF6 +:1080E000CA811BB390F8402C8A76B0F8412C4A80A4 +:1080F000B0F8452C0A80B0F8432CCA80B0F8472C61 +:108100008A8090F8492C0A7690F84A0C48760846FE +:10811000FFF7D0FE1C226949204612F0C0F92868FA +:1081200090F84C1C217690F84D0C23E090F8522CDE +:108130008A76B0F8532C4A80B0F8572C0A80B0F8F1 +:10814000552CCA80B0F8592C8A8090F85B2C0A769E +:1081500090F85C0C48765948FFF7ACFE57491C2252 +:1081600001F11C0012F09BF9286890F85D1C217643 +:1081700090F85E0C607670BD4F4900200870487022 +:10818000897821B94D498863C863A1F840009DE70B +:10819000494A9078002819D148498863C863A1F8F2 +:1081A000400038310870434813783839006801F1CD +:1081B0001C022BB190F8493C0B7690F84C0C04E073 +:1081C00090F85B3C0B7690F85D0C107670472DE9CB +:1081D000F041044690F80E7290F8C66190F8C751CD +:1081E0000B2084F80E02082084F8C601052084F8CC +:1081F000C7012046A1690CF065FA84F80E722E4979 +:1082000084F8C66184F8C75100208870BDE8F08109 +:108210002B4901224A7018228A70827ECA70428BD2 +:10822000120A0A71027E4A71008B000A8871704737 +:108230002DE9FE4F804622488B46002180F82F1002 +:108240000BF110000290BBF80C000BF1080608B906 +:1082500047F6FF704FF00009CDE900904F4698F8BF +:108260005B5036E0B078A84232D8F078A8422FD3DD +:10827000E9B2144812F0AAFA824698F8594017E079 +:108280003078A04213D87078A04210D31AF80400B6 +:1082900068B1E9B2E0B23246029B00F0D4FA484439 +:1082A0001FFA80F91AF8040008B17F1CBFB2641CE1 +:1082B0000AE00000A0071000A80510000020100030 +:1082C000D01F10001E27012098F85A00A042D7D2D4 +:1082D0006D1C98F85C00A842C4D2642009FB00F130 +:1082E0000198B1FBF0F082B2B8F8440028B16423E1 +:1082F0004343B1FBF3F189B20091FB49012381F8BB +:108300002F300872000A48728F72380AC872F74814 +:10831000019920F8731FA0F80290B8F84410C180AA +:1083200007810271009941719BF81800904206D8AC +:108330009BF819100098814201D80120C4E6002062 +:10834000C2E62DE9F041EA4AB1F90260B1F90070E4 +:108350001278B1F90650B1F9043000249AB9E54A0F +:10836000126892F860CCA6EB0C0692F862CC36B29A +:10837000A7EB0C0792F861CC92F8632C65441A4481 +:108380003FB22DB213B290F8C621032A01D0042ABD +:1083900010D1B0F91AC0B4450CDBB0F91820BA42BC +:1083A00008DBAC4506DC9A4204DCFFF741FF0128FC +:1083B00000D10124204629E72DE9F05FDFF8308362 +:1083C0000546002798F8010020B1FFF77FFE002145 +:1083D00088F80110DFF820B3DFF818A3ABF13800FC +:1083E0009BF8001061B15C4604264FF0020B012996 +:1083F00041D002297ED0032972D0042971D056E0E1 +:10840000002405F5805681461FE00120D6F8E01FC4 +:10841000A040014217D004EB041005EB4018B4480B +:1084200000780028DAF8000002D090F8491C01E03A +:1084300090F85B1C89F81810AF4940463839FFF7AF +:1084400080FF012806D0641C64B296F9EC0FA042AC +:10845000DBDA2DE0A84A01218BF80010383AD8F871 +:108460001810C2F83A108BF80640BBF80810491CE7 +:10847000ABF808101CE0A17901EB011105EB4115E7 +:1084800095F8C611042901D0062910D1827E8146B3 +:10849000134605F11801A01C0CF0F7FF012806D1C6 +:1084A000954928463839FFF7C3FE012803D02670C6 +:1084B0003846BDE8F09F2089B9F80E104B46884237 +:1084C00015D384F800B02846FFF7A2FE98F8000004 +:1084D0000028DAF8000005D090F84B0C04E009E021 +:1084E0003AE05EE090F8640C18760127E0E7401C63 +:1084F0002081DDE7A17901EB011105EB411595F82C +:10850000C611042907D0062905D00829D0D128464C +:10851000FFF75DFE4EE0827E05F118011346A01CB8 +:108520000CF0B3FF012806D1734928463839FFF70C +:108530007FFE01280CD095F8C661082085F8C60199 +:108540002846FFF744FE0320207085F8C661AFE798 +:108550002846FFF75DFEC8E7A17901EB011105EBA5 +:10856000411595F8C611042904D0062902D008291E +:1085700020D09DE7827E05F118011346A01C0CF067 +:1085800084FF012894D15C4928463839FFF750FE12 +:1085900001288DD12846FFF73BFE012784F800B063 +:1085A00086E7A07900EB001005EB401090F8C601BB +:1085B00008289BD1FFF7ECFD7AE72DE9F05F4C4DE1 +:1085C0000646002768783C4610B1FFF77FFD6C70C7 +:1085D000A878AA46DFF82081DFF81891A8F11C08D6 +:1085E00070B19AF8001050460029D9F8001002D056 +:1085F00091F84E1C01E091F8651C88F81810847001 +:10860000DFF8F4B0012106F580559BF8000058B161 +:108610005C464FF0040B012840D0022863D00328A9 +:108620006CD004286BD05AE0CA460024C1461FE033 +:108630000120D5F8E01FA040014217D004EB041040 +:1086400006EB40182A4800780028DAF8000002D02B +:1086500090F84C1C01E090F85D1C89F81810264930 +:1086600040461C39FFF76DFE012806D0641C64B239 +:1086700095F9EC0FA042DBDA33E01F4A01218BF8B9 +:108680000010383AD8F81810C2F83A108BF80640A3 +:10869000BBF80810491CABF8081022E0A079D5F807 +:1086A000E02F81400A421AD000EB001006EB401583 +:1086B00095F8C601042801D0062812D198F81A208E +:1086C00005F118011346A01C0CF0DFFE012806D1AD +:1086D000094928461C39FFF7ABFD012810D084F862 +:1086E00000B03846E5E627E0D01F100038570120DB +:1086F000A8051000A00710003820100054E079E011 +:108700002089B8F80E10884213D302202070284622 +:10871000FFF77EFD9AF800000028D9F8000002D08B +:1087200090F84E0C01E090F8650C88F818000127CD +:10873000D7E7401C2081D4E7A079D5F8E02F81400D +:108740000A4201D130462CE000EB001006EB401548 +:1087500095F8C601042801D006281DD198F81A20E2 +:1087600005F118011346A01C0CF08FFE012805D15D +:1087700050492846FFF75CFD012803D020780228E5 +:1087800005D009E02846FFF743FD012704E028460D +:10879000FFF71DFD0320207095F8C6010828A0D121 +:1087A0002846FFF714FD2BE0A079D5F8E02F814093 +:1087B0000A4225D000EB001006EB401595F8C601E3 +:1087C000042801D006288CD198F81A2005F1180148 +:1087D0001346A01C0CF059FE012882D135492846C9 +:1087E000FFF726FD0128A3D12846FFF711FD02203F +:1087F00020709CE7A279D5F8E00F9140084297D10C +:10880000FFF7C6FC6DE710B52A4990F8C631002283 +:108810001C395B1E052B14D8B0F91A30B1F902408F +:10882000A3420EDBB0F91800B1F90040A04208DB0A +:10883000B1F90640A34204DCB1F90410884200DC1F +:108840000122104610BD30B51478844204D2557808 +:10885000854201D90A2011E0844204D1557885422D +:1088600001D0187809E0844204D05478844201D1C0 +:10887000987802E018789C786043C0B294788C4273 +:1088800004D2D5788D4201D90A2111E08C4204D15D +:10889000D5788D4201D0197909E08C4204D0D27884 +:1088A0008A4201D1997902E019799A795143C9B282 +:1088B000484330BD1C201000BE48BF490068B0F8D6 +:1088C000FB290A80B0F8FD294A80B0F8021ABA489C +:1088D000801E01800021C0F806104181C160016145 +:1088E00070472DE9F843B34F8046002538682B4682 +:1088F0002A46418EB0F9346061F31F4466F30F04D9 +:10890000694640460CF04AFE3968BDF90220B1F8CC +:10891000043A91F83E004343934207DAB1F8063A2D +:108920004343934202DDB1F8082A01E0B1F8022A7C +:10893000424310B2D8F800200092B1F8F433BDF9E8 +:108940000020934203DAB1F8F61361F31F44824228 +:108950000ADB311A8A4207DCBDF90210814203DBCF +:10896000C0EB2440814200DD01252846BDE8F883A4 +:108970002DE9F84F054690480024001D05F1240616 +:10898000018809B9408820B1304600F0BAF80128C2 +:1089900020D089480788B0F802900CF044FE824647 +:1089A00000231A46694630460CF0F8FDDFF80482D1 +:1089B000BDF90010D8F8000090F83E0000FB07F267 +:1089C000914205DB0FFA8AF309FB1030884203DA83 +:1089D000012429E0042427E07748801E008820B184 +:1089E0003046FFF77EFF012804D073480A30018823 +:1089F00041B901E0022417E0418819B9818809B919 +:108A0000C08888B1304600F0A7F801280CD1D8F80A +:108A10000000E96A90F8000A884204D9B5F8140207 +:108A200028B1082803D010242046BDE8F88F082478 +:108A3000FAE72DE9F047044690F8C6010E464FF0DC +:108A40000109032807D000274FF00308042816D097 +:108A5000082853D13FE02046FFF78AFF05004DD09C +:108A600094F90D0204F0EAF9A4F814523068206277 +:108A7000E08F4FF0000940F40060E0873EE094F999 +:108A80000D0204F00CFA012838D12046FFF770FFE0 +:108A90000546B4F81402102803D0082801D085B187 +:108AA0002CE065B1314604F120000CF03BFD01469D +:108AB0004048006890F8010A4043884204DA206A7E +:108AC000306084F8C68113E0102D01D0082D15D137 +:108AD000A4F8145212E094F90D0204F0E0F9012810 +:108AE0000CD12046FFF744FFB4F814020828E6D062 +:108AF000A4F8147294F90D0204F0C6F94846BDE8D2 +:108B0000F0872DE9F8432C4E8046361D0025B6F936 +:108B100000400CF088FD074600231A46694640468F +:108B20000CF03CFD2348B188BDF90020006890F8A6 +:108B30003E004143914201DAB6F90240BDF902100C +:108B400000FB04F2914204DB3A1404FB102088423B +:108B500000DA0125284609E7F8B5064600250CF09D +:108B600062FD044600231A46694630460CF016FDA5 +:108B70001049114BBDF9022009680A33188891F891 +:108B80003E104843904211DC5E88201406FB110021 +:108B900090420BDB9A88BDF900004A43824205DC13 +:108BA000DB8822B203FB1121814200DA012528462D +:108BB000F8BD0000A0071000862601202DE9F04135 +:108BC0005B4900F580534FF001060D6895F8964C0F +:108BD000A10717D50F2113E0D3F8E02F06FA01F70C +:108BE0003A420DD001EB011200EB421292F8C7217C +:108BF000520705D54F4995F8972C0A704E7001E041 +:108C0000491EE9D2610724D54B49097B002920D0B0 +:108C1000484C0021A41EA1800F2113E0D3F8E02FBF +:108C200006FA01F73A420DD001EB011200EB4212B5 +:108C300092F8C7717F0705D0B2F84420A788BA42DE +:108C400000D9A280491EE9D2B5F9B60CFCF7E2FEC4 +:108C50002070BDE8F0813649096891F8961C8907B3 +:108C600009D5344910B10020487003E00878002885 +:108C700001D0401E087070472DE9F04104462C4891 +:108C800000263546006890F8961C4A072CD52A4ADB +:108C9000127B4AB3274F90F8B42CBF1E90F8B81C33 +:108CA0007B78012B08D190F8B5CC90F8B90CA2EBE9 +:108CB0000C02081AD2B2C1B2B888904202D83878F1 +:108CC000884203D9042084F8C70101257D70AB4296 +:108CD00003D029460A200BF0C4FC18487A78017B9F +:108CE00062F3000101730FE0880706D5114841784F +:108CF000012909D1007830B906E0C80704D094F8FA +:108D0000C701042800D101262E43A2D00C49AA2075 +:108D1000087094F8C601032805D0042801D006285D +:108D200097D1082000E0022084F8C60191E70000F6 +:108D3000A0071000AE051000945A1000385701200B +:108D40003207100070B50446002084F8CA01FC48C0 +:108D5000FC4D0378286833B194F90D228A4290F8CB +:108D6000031218D021E0F84B94F8C7611B78012E4C +:108D700007D09BB394F90D228A4290F8341314D192 +:108D800009E0F24A12784AB194F90D224BB18A42B5 +:108D900090F8F31209D101F00F0107E090F8F112F9 +:108DA000F9E78A4290F8F212F5D0090984F8CA115D +:108DB00090F80D13C9060BD5E18F890508D590F8F9 +:108DC000360394F8CA1100F00F00084484F8CA0171 +:108DD000204600F0F5F9012810D01DE0FFE794F9D6 +:108DE0000D328B4202D190F83313D4E7934202D173 +:108DF00090F83313D9E790F83513D6E7D4480078C4 +:108E0000012809D9296894F8CA0191F8351301F0AD +:108E10000F01084484F8CA01286890F80C1AC906A2 +:108E20000AD5CC490978002906D094F8CA1190F8DF +:108E30002A0A084484F8CA0170BDC44A10B51478DF +:108E4000C04A90F8CA11126892F8333303F00F0346 +:108E50005CB192F8F22202F00F02D21A891A0029AC +:108E600000DC002180F8CA1110BD92F8F122F2E76F +:108E7000B74900200870B8490870B4490870B5496E +:108E80000870B6490880B649087070472DE9FE4F52 +:108E900004460020B3498DF800008DF804000870E6 +:108EA000B14904F580554FF0FF390870B5F8E00F6F +:108EB000A74E10EA19400DD02046FFF77FFE31463D +:108EC000484609784FF000475FEA010E4FF0010B6A +:108ED00034D10FE0A048002434700470A34880F817 +:108EE00000900120FFF7B7FE9C4804809C48047066 +:108EF000BDE8FE8F04F5805C00219CF9EC8F1BE03F +:108F0000DCF8E03F0BFA01F2134213D001EB01123F +:108F100004EB421292F8C631012B01D048460DE015 +:108F2000B2F8426036B1126B92FBF6F39F4201DA5F +:108F30001F460846491C49B28845E1DA8246B0F12D +:108F4000FF3F02D0894981F800A088484A464FF087 +:108F5000004690F90080BEF1010F25D804F5805736 +:108F6000002097F9ECCF1DE0D7F8E03F0BFA00F1B5 +:108F70000B4215D0404513D000EB001304EB431116 +:108F800091F8C631012B01D04A460DE0B1F84230CC +:108F900033B1096B91FBF3F39E4201DA1E460246A0 +:108FA000401C40B28445DFDA694900200292087013 +:108FB0000746DFF890814FF00809EBE0D5F8E01F95 +:108FC0000BFA07F001427AD007EB071004EB4016CA +:108FD00096F8C601012806D0052810D0092824D00B +:108FE0000D2831D014E0304600F0C6F95146304625 +:108FF000029AFFF7A7FE022086F8C60133E030464A +:1090000000F0F7F8062086F8C601304600F067F950 +:1090100096F8C601022826D0062852D0072859D033 +:109020000A280DD00E281AD05CE0D8F8000090F87D +:10903000370300F00F0086F8CA010A2086F8C6013F +:1090400096F8CA01D0B34DE0D8F8000090F83A0382 +:1090500000F00F0086F8CB010E2086F8C60196F8C6 +:10906000CB0168B33EE096F83E00C00710D0304612 +:1090700000F0A6F860B9D8F8001096F8CA0191F887 +:10908000351301F00F01884206D9401A86F8CA014B +:1090900096F8CA0118B125E0002086F8CA0103201D +:1090A00086F8C601D8F8000090F80D03C00619D55F +:1090B000F08F800516D5306AF06013E00DE03EE0D9 +:1090C0000DE096F8CB0168B996F83E00800701D50F +:1090D000072005E086F8C69104E00B2000E003209D +:1090E00086F8C6013046FFF7C7FD96F8C60102288C +:1090F0000CD0062811D00A2808D00E280DD003283D +:1091000012D0042810D007283ED041E096F8CA01BA +:10911000A8B1401E86F8CA013AE096F8CB0170B1BA +:10912000401E86F8CB0133E009480178491C0170E4 +:1091300096F8C70101281BD003281FD028E027E09C +:1091400029051000A0071000B30610003107100019 +:1091500032071000E007100064071000B00510008F +:10916000AC0510003307100034071000B2051000E2 +:109170009DF80400401C8DF8040009E09DF80000F3 +:10918000401C8DF8000003E096F8C7010128EFD0DD +:109190007F1C7FB295F9EC0FB842BFF60FAF0020ED +:1091A000FFF759FD01AA6946204600F066F8884895 +:1091B0009DF80010017087489DF80410017097E633 +:1091C00090F85A1090F859208A1AC18F521C022A1E +:1091D0000AD990F85C2090F85B309A4204D141F0B3 +:1091E0000101C1870120704721F00101C1870020E2 +:1091F000704710B57849002280F8CB210B78774969 +:10920000096813B191F804320FE0754B1B7853B124 +:1092100091F8383301221B0980F8CB3190F8C7311F +:10922000012B05D00CE091F8383303F00F03F3E77E +:1092300090F8CB3191F8F14203EB141380F8CB3165 +:109240001AB990F83E2092070CD491F83913826A2B +:1092500001F00F039A4205D990F8CB2102EB1111CE +:1092600080F8CB1190F8CB11002905D1C18F0905E9 +:1092700002D5012180F8CB1110BDF0B50B7859490A +:1092800001254BB100230B701178002908D0002173 +:1092900000F5805402261DE01078002800D00D70E3 +:1092A000F0BDD4F8E03F05FA01F73B4210D001EBE6 +:1092B000011300EB431393F8C671032F08D193F801 +:1092C000C771012F04D183F8C66113785B1E137038 +:1092D000491C49B294F9EC3F8B42E2DAF0BD2DE92A +:1092E000FC41DFF8F8800746D8F8000090F80D033D +:1092F000C0073FD0002507F1A006012406EBC400FB +:1093000030F8041CADF8021030F8081DADF800105C +:109310008089ADF8060036F83400ADF8040001A9E4 +:1093200068460CF0FFF8854200DA0546641CE4B29A +:10933000052CE3D3394607F120000CF0F3F8024680 +:10934000274800780028D8F8000005D0B0F8271387 +:10935000B0F82303494304E0B0F82513B0F8210323 +:1093600049434043824205DD8D4203DDF88F40F0E2 +:109370000200F887BDE8FC8170B51849096891F8CA +:109380000D33DB0622D5046AB1F8F45323B2AB42A5 +:109390004D8E01DDA5F5967565F31F42B1F9345088 +:1093A00091F88C63241465F30F02B4420ADBC4EB1A +:1093B0002242B24206DB91F88D138B4202DBEA1A9D +:1093C0008A4203DAC18F41F40071C18770BD000089 +:1093D000330710003407100029051000A007100003 +:1093E000B3061000310710002DE9F843164600239C +:1093F00089461A46FE490C68B4F8927347B9B4F826 +:10940000941329B9B4F8961311B9B4F89813B9B1F3 +:10941000B0F90E50B0F90C10AF4210DC678EB4F802 +:1094200094C3A7EB0C07AF4209DBB4F896538D4207 +:1094300005DCA58EB4F89873ED1B8D4200DA01228D +:10944000EC49097801B10123EB494D78EB490978E2 +:10945000BDB194F86503050900F00F03012904D993 +:1094600094F8660300F00F03050922B194F8640331 +:1094700000F00F030509B4F86713B4F869234943F2 +:109480007EE08BB194F86B03050900F00F0301290E +:1094900004D994F86C0300F00F030509B4F86D13B8 +:1094A000B4F86F2349436BE0D54B1B78022B22D0D5 +:1094B00090F8C731022B30D0012B34D0DFF844C3F1 +:1094C00094F8655694F8648605F00F039CF80070D4 +:1094D0002D0937B194F86B5694F86A8605F00F039E +:1094E0002D09B0F8420040452ED9B4F86616B4F8FC +:1094F0006826494344E094F87103050900F00F031E +:10950000012904D994F8720300F00F030509B4F897 +:109510007313B4F87523494332E094F8790300F0EB +:109520000F03050927E094F87A0300F00F030509FB +:1095300022B194F8620300F00F030509B4F8811317 +:10954000B4F8832349431BE094F87703050900F03E +:109550000F03012904D994F8780300F00F030509DB +:1095600022B194F8630300F00F0305091FB19CF8C2 +:1095700004309CF80550B4F87D13B4F87F234943B8 +:109580005243484600950BF0DBFF3560BDE8F88399 +:109590002DE9F84F0D4690F8C611044600F18806F3 +:1095A00003290FD0924ADFF860A2042910680FD077 +:1095B00007296BD0082967D129463046BDE8F84F06 +:1095C00000F01DBE29463046BDE8F84F00F0D1BD81 +:1095D00090F87B0304F10C0107099046081D0BF07D +:1095E000A1FF0146D8F80000DFF818B290F88523F3 +:1095F00092072ED594F8C9210AB1C4F89810D4F86E +:1096000098C090F88823B1EB0C0902D502F00F0244 +:1096100000E012099BF8008090F86436B8F1000F62 +:1096200001D090F86A36B4F84280984508D990F88D +:109630006C06B9F1000F02D500F00F0200E002093C +:10964000C2F110000CFB02FC01FB00C00111C4F8C8 +:1096500098106A462046FFF7C7FE9BF800200AB123 +:109660009BF8067054F8901F3A460BF07EFF0746B1 +:1096700002462946304600F092FD27609AF84820BD +:1096800067F303028AF84820BDE8F88F90F80D13BD +:10969000002789070DD55D4990F87C03097800F013 +:1096A0000F0701B107093A462946304600F08FFD01 +:1096B00007E0B5F90200C4F88C00B5F90000C4F861 +:1096C00088009AF8480067F303008AF84800DBE74F +:1096D0004E49484A002009781278114300D00120F1 +:1096E00070472DE9FF4F89B09146DDE9160A00EB7E +:1096F000CA00D0E90045CDE90445D0E90240CDE9F2 +:109700000640CDE9021203EBCA00DDF80880D0E97B +:109710000210CDE9001006A904A800F0B1FC07462C +:109720008B46694602A800F0ABFC0E46054669462A +:1097300004A800F0A5FC0446401BB1412DDA2846E0 +:109740000BF0A0FB804620460BF09CFB0446BAF1D0 +:10975000000F00D16410791B7BEB060005DA384658 +:109760000BF090FBA04200DA0446B8F1000F0CD0D9 +:1097700001990398009A401A6043029990FBF8F00F +:10978000891A614391FBF8F101E000200146019A3A +:1097900002EB0009009800EB01080998C0E9008974 +:1097A0000DB0BDE8F08F2DE9FF4F00278BB090463C +:1097B0003E463D463946199C0AE0012878D053F8C8 +:1097C000312017444A4302FB0155491C1644C9B2D3 +:1097D000A142F2D30E4C206800906068CDE90107E9 +:1097E000E06803902069CDE90406A069069011E0C5 +:1097F000A007100029051000D8071000320710003C +:10980000180510007407100038570120B306100027 +:10981000B4051000E069CDE9070568460BF036FD98 +:1098200082462068CDE90007A0680290E068CDE993 +:10983000030660690590A069CDE90605206A0890D5 +:109840008B4668460BF022FD00970A9060680190F5 +:10985000A068CDE90206206904906069CDE905059C +:10986000E0690790206A0890894668460BF00EFD73 +:10987000AAFB08370D460BFB087104460C9F0A989B +:109880000022A0FB07C80AFB021609FB078100FBA8 +:10989000021013EB0C014641081946EB05014FF489 +:1098A0007562002310F0D7FD0C9929B11DE0FFE788 +:1098B00003EBC102526884E7FC49096891F831134F +:1098C000890612D50A98031849EB090113EB0A031C +:1098D00041EB0B01AA00A000181842EA9472514112 +:1098E0004FF47552002310F0B6FD1899C1E900AB92 +:1098F00018990A9BC1E902391899C1E904450FB0CA +:109900004FE72DE9F04F85B00546DFF8A0833030F2 +:109910000290D8F800000F46934690F8311305F1F5 +:10992000600601F01F04E24905F1680905F1800AAB +:10993000097811B190F8320307E005F0C5FE01285F +:1099400005D1D8F8000090F8A20300F01F04BBF185 +:10995000000F06D195F89810012220460BF005FE65 +:10996000C4B2BC4201D9781EC4B285F89840CDE992 +:10997000009704FB04FB2B465A4621460120FFF7C3 +:1099800012FF7060CDE900A72B465A462146002001 +:10999000FFF709FF3060D8F8001091F89A13C90753 +:1099A00011D00146029872688DE891002B4603A8F9 +:1099B000FFF797FEDDE9030105EBC402516071601A +:1099C00045F83400306005B0EBE62DE9F04104467F +:1099D00000F1A00590F8400017460E46000703D599 +:1099E00094F8B801012805D0A021284610F0F8FD10 +:1099F00006208DE0182105F1680010F0F1FD182116 +:109A000005F1800010F0ECFD94F8BA0101281FD197 +:109A100094F8C401012802D003280DD018E094F86E +:109A2000C50110B9E089A4F8C201B4F8C20160848C +:109A3000B4F8C00120840BE094F8C50110B9A089E6 +:109A4000A4F8C001B4F8C0012084B4F8C201608455 +:109A500094F8C50101283BD0B4F9C2117068052201 +:109A6000401A90FBF2F0E962B4F9C21100EB400336 +:109A700001446962B4F9C21101EB4001E961B4F932 +:109A8000C21119446961B4F9C21101EB8000E860A8 +:109A900070686860B4F9C0113068A962401A90FB20 +:109AA000F2F0B4F9C01100EB400201442962B4F9AC +:109AB000C01101EB4001A961B4F9C0111144296141 +:109AC000B4F9C01101EB8000A8603068286021E083 +:109AD000002005EBC001B4F9C2214A60B4F9C021ED +:109AE00045F83020B4F9C2214A63401CB4F9C021C2 +:109AF000C0B20A630628ECD30CE005EBC001726823 +:109B00004A60326845F8302072684A6332680A63F6 +:109B1000401EF2D20020C5E91A00C5E91C00C5E9C3 +:109B20001E00C5E92000C5E92200C5E92400D6E9E8 +:109B30000001C5E9180139462846BDE8F041012277 +:109B4000DFE670B50BE001EBC30474E90256C4E92B +:109B5000025600EBC30474E90256C4E902565B1EC8 +:109B6000F1D1D2E90034C1E90034D2E90012C0E9F0 +:109B7000001270BD70B515460446D1E90002C4E973 +:109B800018020A462B46214604F13000FFF7D9FFA0 +:109B900029462046BDE870400022B2E600B585B0F7 +:109BA0000321049100224FF47561CDE90212009265 +:109BB00000F5907300F5847200F1A00100F580704B +:109BC0000BF0A6FB05B000BD2DE9F041374F044670 +:109BD000164638680D464FF0010890F80C03000750 +:109BE00002D5204600F006FA386890F80D034006CA +:109BF00003D52946204600F04EFA3868B0F93210F5 +:109C0000B5F902000BF058FC68803868B0F93410E0 +:109C1000B5F900000BF050FC2880386890F89A03E2 +:109C2000800703D5286800F07AFA286094F8C60106 +:109C3000032806D0042808D0072817D0082815D0F4 +:109C400017E03188A4F84F1013E03868B4F84F20BB +:109C500090F87B0300F00F00C0F110014243308800 +:109C600000FB01200009A4F84F0001E0B4F84F0008 +:109C70003080104A294604F1240000F0B2F9404631 +:109C8000BDE8F0812DE9FC5F88460B498346002042 +:109C9000086008490646DFF814A0086007494FF03D +:109CA00001090BF580570870B1E00000A007100013 +:109CB000B30610006C07100068071000640710005E +:109CC000D7F8E01F09FA06F001427CD006EB061136 +:109CD0000BEB411494F8C60103280BD0042809D0DB +:109CE000072807D0082805D0092803D00A2801D062 +:109CF0000B2868D1E0680090B4F84D00ADF804007E +:109D000004F10C01F84A081D00F06BF901AA69463C +:109D10002046FFF759FF0546DAF8000090F80C03DB +:109D2000400604D56946204601F0C0FC0546DAF835 +:109D3000000090F80C03800603D569462046FFF723 +:109D400027FCDAF80000524690F8D60300060AD540 +:109D50004DB194F8C601032805D1608CADF802001E +:109D6000208CADF8000094F8C701012807D1DF4826 +:109D7000007820B994F8C601082800D00025DC48F6 +:109D8000007870B194F84000C00701D0002508E0C9 +:109D900094F8B801012804D1206A0090002084F8CA +:109DA000B80194F8C70103280AD1D2490878401CA9 +:109DB000C0B2087094F84030DB0701D0401E087034 +:109DC0000098606200E021E0BDF80400A4F84F00B4 +:109DD000106890F8FA09C00707D0012D16D169461E +:109DE0002046FEF726FE88B101E0012D0ED1009835 +:109DF000A061BDF80400A4F8510094F80D22D8F831 +:109E0000001009FA02F00143C8F80010761C97F917 +:109E1000EC0FB042BFF654AFDAF8000090F8700CC7 +:109E200000070ED5B3480178B34829B1B349097882 +:109E3000012901D180F80090D7F8E41F002900D152 +:109E40000170BDE8FC9F2DE9F047884606460027D3 +:109E50004FF0010900F5805553E0D5F8E00F09FAFD +:109E600007F108424CD007EB071006EB401494F8BA +:109E7000C60103280BD0042809D0072807D00828DA +:109E800005D0092803D00A2801D00B2838D194F92D +:109E90000D12D8F8003009FA01F2134230D003282D +:109EA00007D1084602F0FBFF18B92146304602F000 +:109EB000C8FE94F8C70104280AD194F8C6010728FF +:109EC00003D0082801D00B2802D1032084F8C70151 +:109ED00094F90E02002813DB94F8C7110020012921 +:109EE00004D0022904D0042904D004E0032002E0B5 +:109EF000042000E0052084F8C80120460AF0A4FBF5 +:109F00007F1C95F9EC0FB842A7DA00273EE009FA6A +:109F100007F2104239D007EB071006EB401494F813 +:109F2000C601082802D00B2815D02EE094F80D2287 +:109F3000D8F8000009FA02F1084207D094F90E029D +:109F4000002803DB2146304602F095FE21463046CC +:109F500002F059FE15E094F80D22D8F8000009FA35 +:109F600002F1084211D094F90E0200280DDBB4F87A +:109F70004000214620F00800A4F84000304602F0DE +:109F80007AFE94F90D0202F07FFF7F1C95F9EC0F29 +:109F9000B842D5F8E00FBADA06F5005628B116F83F +:109FA0009A0F401C3070BDE8F087002086F89A00B8 +:109FB000F9E74D4910B5002008605149086000F0EC +:109FC00097FBBDE8104000F0D3B838B500210091F0 +:109FD00004466946FFF756FE69462046FFF733FF01 +:109FE00038BD10B514460BF09DFA2168814200DAA5 +:109FF000206010BD70B5034690F8C6010D460328D9 +:10A000000DD002280BD0042809D0062807D00A2832 +:10A0100005D00B2803D00C2801D00E282FD193F89F +:10A02000B50103F5A074E0B193F85A0093F8591004 +:10A03000401A401CC3F8A80193F85C0093F85B1029 +:10A04000401A401CC3F8AC01586BC3F8A4012D485A +:10A0500029460088C3F8B0012046BDE8704000F0F2 +:10A060009DBB1846FFF734FB002808D0012083F879 +:10A07000B50129462046BDE8704000F04FBB70BDD9 +:10A080004A68436809680068D21A081A404302FB0C +:10A090000200C11770477CB50C46B1F9021001915E +:10A0A000B4F90010009190F8C62100F1A005032A30 +:10A0B0000ED0042A11D0062A0FD00A2A0DD00C2A5D +:10A0C0000BD00E2A09D0072A1ED0082A1CD01FE068 +:10A0D00006226946FFF779FC1AE0062269462846FF +:10A0E000FFF748FD14E0000068071000310710007A +:10A0F0003907100064071000E9061000E806100098 +:10A100006C071000B406100006226946FFF746FDF2 +:10A11000B5F864006080B5F8600020807CBD30B583 +:10A1200012490514096891F89D23B1F93240B1F93B +:10A130003430954201DC62F31F4091F89E23A21A4D +:10A140000414A24201DC62F31F4091F89F2304B281 +:10A15000944201DC62F30F0091F8A01302B2591A85 +:10A16000914201DC61F30F0030BD0000A007100038 +:10A170007047324A30B4126892F88533DC074FF0EA +:10A18000000304D092F8864324098460037392F894 +:10A190008523920700D5036130BC00F035B87CB54B +:10A1A000044615460E46684600F02EF801992A46E8 +:10A1B000606800F03BF8606000992A46206800F073 +:10A1C00035F820602146304600F027F87CBD7CB58C +:10A1D000044615460E46684600F016F801992A46D0 +:10A1E000606800F023F8606000992A46206800F05B +:10A1F0001DF820602146304600F00FF87CBD0A466D +:10A200000146104600F009B8B1F90220120242607E +:10A21000B1F900100902016070474A6880321212D9 +:10A22000428009688031091201807047C2F1100331 +:10A23000504301FB0300001170470000A00710000D +:10A240002DE9F041FE4A126851B3518E92F8303038 +:10A25000C26E446E006F0026400000FB024048437F +:10A26000A0FB0025002101FB005500FB01556421E6 +:10A27000A2FB010705FB017102FB06115C432246AC +:10A28000334610F04BF82246002310F047F8ED4B10 +:10A2900000221B1A8A4101D2EA480021BDE8F08160 +:10A2A000918E92F83130826ED3E72DE9F0478EB06F +:10A2B00000250224059506950795089509950A95A8 +:10A2C0000B950DF114080C95CDE90148064606F1F1 +:10A2D0001C03039404949A4622462146DA480094CB +:10A2E0000AF000FE0DF12409CDE90149D64B022206 +:10A2F000039404941033114605A800940AF0F2FD6B +:10A30000D149306E0223403100901A46A1F110006D +:10A310000AF0DCFDCC490427022340311A460846E6 +:10A3200000970AF0C6FDC84902235246403109A8E9 +:10A3300000940AF009FE059506950795089509957C +:10A340000A950B950C95CDE9014806F12C030222E4 +:10A35000039404941D461146BB4800940AF0C2FDC4 +:10A36000CDE90149B84B02220394049410331146FD +:10A3700005A800940AF0B6FDB349306E02234031BF +:10A3800000901A46A1F110000AF0A0FDAE49022388 +:10A3900040311A46084600970AF08BFDAA4902236D +:10A3A0002A46403109A800940AF0CEFD0EB0BDE85F +:10A3B000F0872DE9F04F0546A4480F468BB0D0E951 +:10A3C0000010CDE9081000260124059606960DF12F +:10A3D000140A0796CDE9014A4FF002099A489346BC +:10A3E00005F10C03039498464A4621461038CDF8EF +:10A3F000009004940AF076FDB5F902000599012356 +:10A40000401A05900090022206A938460AF05EFD27 +:10A410006427414601230222084600970AF056FDB0 +:10A420004246022306A9104600940AF08DFD4246DA +:10A43000022308A9104600940AF086FD4146012334 +:10A440000222084600970AF034FD05960696079604 +:10A45000CDE9014A7C4805F1140303941E4602220B +:10A4600001211038CDF8009004940AF03BFDB5F9B5 +:10A47000000005990123401A05900090022206A9C8 +:10A4800058460AF023FD3146012302220846009770 +:10A490000AF01CFD3246022306A9104600940AF079 +:10A4A00053FD3246022308A9104600940AF04CFDE1 +:10A4B000314601230222084600970AF0FAFC0BB04D +:10A4C000BDE8F08F2DE9F74F8AB00026089609966F +:10A4D0000596069601240DF1140807960225CDE98C +:10A4E0000148CDE903540746574B07F11C00083BD0 +:10A4F0002A462946824600950AF0F4FC0DF120090F +:10A50000CDE901595048CDE90345534602220121C6 +:10A51000103800950AF0E6FC0DF11C0ACDE9014A5D +:10A52000494B0394083B0222012108A8009504949A +:10A530000AF0D8FC01213846FFF782FE42494FF06D +:10A54000640B14390123086007990222084405A905 +:10A550000790CDF800B008460AF0B8FC07980090C4 +:10A560000123022205A80B990AF0A3FC089609967C +:10A57000059606960796CDE90148CDE90354324B7E +:10A58000022207F12C00083B1146064600950AF00E +:10A59000A9FCCDE901592C48CDE9034533460222F7 +:10A5A0000121103800950AF09DFCCDE9014A264BA7 +:10A5B0000394083B0222012108A8009504940AF0A4 +:10A5C00091FC00213846FFF73BFE1F490123143957 +:10A5D000022208600799CDF800B0084405A9079049 +:10A5E00008460AF073FC079800900123022205A890 +:10A5F0000C990AF05EFC0DB062E72DE9F74F8EB0C2 +:10A6000000250595069507950224089509950A9554 +:10A610000B9505AF0C95CDE901478C464FF0010A2B +:10A62000094B06460394103B524621466046CDF83E +:10A6300000A004940AF056FC05AA0223114607E084 +:10A64000A007100040420F00EC051000A8A7010071 +:10A65000BE4800940AF086FC0DF12408CDE90148BB +:10A6600006F11C030222039404949B46114605A89C +:10A6700000940AF037FC4FF0640902231A46594649 +:10A6800009A8CDF800900AF014FC059506950795E9 +:10A69000089509950A950B950C95CDE90147AB4BAB +:10A6A0000394303B01220221CDF800A004941098BD +:10A6B0000AF018FC05AA02231146A44800940AF0E7 +:10A6C00051FCCDE901480394049406F12C03009455 +:10A6D00002221C46114605A80AF004FC02231A4671 +:10A6E000214609A8CDF800900AF0E3FB11B0E7E697 +:10A6F000974808B5006864210223B0F84D031A4654 +:10A7000048439249800820310090A1F110000AF0DE +:10A71000DDFB8E4964203439086008BDF8B5044675 +:10A72000086844F8040B086844F8040B086844F807 +:10A73000040BB1F902000025E4E80205B1F90000BC +:10A74000E4E802058148824E10300FC80FC40FC4E0 +:10A75000306864210223B0F84D031A46484380084C +:10A76000A4F12001009008463C3C0AF0AFFB3068A1 +:10A7700064210223B0F84D031A464843800804F1CF +:10A780002C01009008460AF0A1FB94E8070004F1B0 +:10A790003C0383E8070084F87450F8BD7FB50D468C +:10A7A000044603220AF090FE204600F025F82046D9 +:10A7B00000F06AF82046FFF778FD00200090019035 +:10A7C0000290039002AA69462046FFF77BFE02AA88 +:10A7D00069462046FFF7EDFD02AA69462046FFF7CD +:10A7E0000CFFA0896880A08A28800322294604F1F2 +:10A7F0003C000AF069FE7FBD7CB50446B0F902104A +:10A80000B0F93E00B4F94220091A801A081A0190E2 +:10A81000B4F90010B4F93C00B4F94020091A801AC8 +:10A82000081A009004F148000322694605460AF020 +:10A8300060FE94F87400032802D2401C84F874006F +:10A84000C3B200221146184606E005EBC006766842 +:10A85000324455F830603144401EF6D292FBF3F09A +:10A8600091FBF3F16A68101A2A684043511A01FB00 +:10A87000010042F21071884200DD0846642148431D +:10A8800090FBF3F020667CBD2DE9F0430446B0F95F +:10A890000200B4F90610B4F90420411AB4F900001A +:10A8A0004943801A00FB00182769A66907FB07F0D7 +:10A8B00006FB060087B04FF00009404515D90AF0A5 +:10A8C000E1FA05000DD040460AF0DCFA784390FB2F +:10A8D000F5F0206140460AF0D5FA704390FBF5F0A0 +:10A8E00002E04846C4F81090A061CDF8149001250C +:10A8F0000DF11408CDF818900226CDE90158CDE9E4 +:10A90000036512484F4604F10C03324631462038A5 +:10A9100000960AF0E7FADDE90501C4E903010597AD +:10A920000697CDE90158CDE903650848022204F1F4 +:10A9300014031146203800960AF0D4FADDE9050127 +:10A94000C4E9050107B0BDE8F08300000C06100063 +:10A95000A0071000B0F84220B1F842301A44A0F825 +:10A960004220B0F84420B1F844301A44A0F8442002 +:10A97000026B0B6B1A440263426B4B6B1A444263CB +:10A98000B1F95320B0F953309A4201DDA0F85320B9 +:10A99000B1F95520B0F955309A4201DDA0F85520A3 +:10A9A00090F8CE2191F8CE319A420AD030F8462F55 +:10A9B000B1F846301A4420F80E29896B0268114418 +:10A9C000016070472DE9F14F8AB0002004900A9889 +:10A9D00000F500500890B5E0002105910691009126 +:10A9E000884689460E460F460D468A468B4601919B +:10A9F0000291039104990A98EC4600EB810000F55E +:10AA000000500990C1690C4616E091F8CE011CF87F +:10AA10000020521CD2B20CF800200A9B034403F51C +:10AA200000531B7B9A4205D1012A03D9012282409F +:10AA300042EA0B0BD1F81C120029E6D135E094F85C +:10AA4000CE110120884010EA0B0F0ED1606BB4F9D3 +:10AA50000E3041464A46C0FB03128846B4F90C103A +:10AA60009146C0FB0167054412E010EA0A0F0FD1BE +:10AA7000A16BB4F91EC042464B46C1FB0C23904665 +:10AA8000B4F91C209946C1FB02670D4440EA0A0A4A +:10AA9000204600F043FA012802D10598401C059099 +:10AAA0000698401C0690D4F81C42002CC7D106988A +:10AAB000002843DDE817044603462A464046494637 +:10AAC0000FF0C9FCADF81E002A4623463046394631 +:10AAD0000FF0C1FCADF81C0009984FF0FF360025BF +:10AAE000C46923E0204600F019FA012801D0059836 +:10AAF00090B904F1100107A80AF014FDB0420BD27E +:10AB000006463DB129462046FFF724FF29460A980C +:10AB100000F01BFA254607E021462846FFF71AFFFA +:10AB200021460A9800F011FAD4F81C42002CD9D121 +:10AB30000798E860E88F40F04000E8870498401CE0 +:10AB40000490089890F89410049881423FF744AF1D +:10AB50000BB0BDE8F08F2DE9F74F0D4601EB051165 +:10AB600082B0814600EB41170024DFF8B8B400F54D +:10AB7000805A78E00122DAF8E01F02FA04F811EABC +:10AB8000080F6FD0AC426DD0DBF8080030F815002C +:10AB900010EA080F66D104EB041109EB41163046A8 +:10ABA00000F0B6F9012804D0304600F0B7F90128CA +:10ABB00058D1304600F0A6F9F0BB06F10C0107F1C0 +:10ABC0000C000AF0AFFC0090DBF808000123AB405A +:10ABD00030F8151041EA080120F8151030F814106B +:10ABE000194320F814103846DBF8008000F0A2F971 +:10ABF000012804D1304600F08BF901281AD03846DC +:10AC000000F086F9012804D1304600F093F90128BC +:10AC100010D0384600F07CF9012817D1304600F0FA +:10AC200077F9012812D197F83E0096F83E100843B4 +:10AC300080060BD5F88F00E014E040F02000DBF830 +:10AC40000480F887F08F40F02000F087009840459E +:10AC500008D2324642F21C06394609EB0600049B34 +:10AC600000F0B4F9641C9AF9EC0FA04282DA05B046 +:10AC70006FE72DE9F84F8846074601EB081007EB10 +:10AC80004014DFF8A0B394F83E004FF0010A4006EC +:10AC900007F580552CD504F10C000026009021E02A +:10ACA000D5F8E01F0AFA06F001421AD0464518D03E +:10ACB00006EB061007EB4010814600F029F9012849 +:10ACC0000FD1484600F01EF958B909F1100100985B +:10ACD0000AF028FCDBF80410884202D2042084F831 +:10ACE000C601761C95F9EC0FB042D9DABDE8F88FB1 +:10ACF000CD49A06A096891F829138842F6D900263F +:10AD00002CE0D5F8E01F0AFA06F0014225D04645AE +:10AD100023D006EB061007EB4010814600F0F8F850 +:10AD200001281AD194F8CE1199F8CF01814214D19B +:10AD3000484600F0E7F880B909F1100104F10C0071 +:10AD40000AF0F0FBDBF80410884206D2042084F8F5 +:10AD5000C601E08F40F04000E087761C95F9EC0FCB +:10AD6000B042CEDA002604F10C0922E0D5F8E01F4B +:10AD70000AFA06F001421BD0464519D006EB061030 +:10AD800007EB4014204600F0C9F8012810D12046F6 +:10AD900000F0B8F860B904F1100148460AF0C2FBAF +:10ADA000DBF80410884203D2E08F40F04000E087D7 +:10ADB000761C95F9EC0FB042D8DA97E72DE9F84305 +:10ADC0000646FF208DF8000000254FF0010806F52B +:10ADD000805417E005EB051006EB4017D4F8E01F90 +:10ADE00008FA05F001420CD0384600F08BF8012833 +:10ADF00007D097F8C601052803D129463046FFF74A +:10AE000038FF6D1C94F9EC0FA842E3DA00254746A1 +:10AE100019E005EB051006EB4018D4F8E00F07FA2F +:10AE200005F108420ED0404600F06CF8012809D028 +:10AE3000404600F073F8012804D16A46294630469E +:10AE4000FFF789FE6D1C94F9EC0FA842E1DA0025AA +:10AE5000B8461DE005EB051006EB4017D4F8E01FDF +:10AE600008FA05F0014212D0384600F04BF80128EC +:10AE70000DD0384600F04CF8012804D16A46294626 +:10AE80003046FFF768FEF88F20F02000F8876D1C31 +:10AE900094F9EC0FA842DDDA9DF8000006F50056A3 +:10AEA000401C86F89400BDE8F88310B5044604F011 +:10AEB0000BFC012821D05B480321083007F0EEFA93 +:10AEC00058481E2180680FF069FB42F21C007C216B +:10AED00020440FF085FB5349091D081F00F044F87A +:10AEE0002046FFF76BFF2046FFF76CFD4D4803211E +:10AEF000BDE81040083007F0E9BA10BD494900200C +:10AF00008860704790F84000C00700D0012070476B +:10AF100090F8C601012800D00020704790F8C601C3 +:10AF2000022805D0032803D0042801D00020704750 +:10AF30000120704710B590F83E10490603D5FFF781 +:10AF4000EDFF012800D0002010BD91F8C621012A94 +:10AF500008D0022A06D0062081F8C601002081F818 +:10AF6000CB01704701F04FBE2DE9F0412E4F064650 +:10AF70000D463868B0F82A4390F83003644350B166 +:10AF800001F091FE0146386890F83023914202D8D2 +:10AF9000B0F82E4364433A682449B2F82C03497848 +:10AFA000404329B1B2F88E43B2F890036443404362 +:10AFB0001F49097829B1B2F82B42B2F82D02644337 +:10AFC0004043204434602860BDE8F081F0B591F939 +:10AFD0000C6293F9004092F90C52771C02D06D1C60 +:10AFE00015D00BE06E1C0BD000EB850200EB84004B +:10AFF000D26BC2F81C12C16381F80C421C70F0BD08 +:10B00000641C64B240F8241081F80C4202E000EBAA +:10B010008601C96B00EB8400C1F81C22C26382F870 +:10B020000C42EBE73C061000A0071000D807100008 +:10B03000290510002DE9F041044690F88400F94EEE +:10B0400000270D467F2851D104F10C01081D0AF09C +:10B0500069FA0146204600F0AEFB40B284F8840055 +:10B060000F2802DD0F2084F8840094F84000800748 +:10B070003CD56888B4F96C30B4F96A20C01A01B2C2 +:10B080002888D4F86AC0C4F85EC0D6F800E0801AF8 +:10B090004FF0640C9EF8DBE300290EFB01FE9EFBE3 +:10B0A000FCF100B201DD194400E0591AA4F8641063 +:10B0B0003168002891F8DB1301FB00F191FBFCF0F3 +:10B0C00001DD104400E0101AA4F862006888B4F8AA +:10B0D0006410401AA4F868002888B4F86210401A76 +:10B0E000A4F86600306890F8DB03E8B394F98400B4 +:10B0F000B5F90220C0F110015143B4F96C2000FBF6 +:10B10000021040F30F10688094F84010890710D5A2 +:10B11000B4F96010884203DDB4F96420904205DC84 +:10B12000884206DAB4F96410884202DAB4F864009E +:10B13000688094F98400B5F90020C0F110015143F2 +:10B14000B4F96A2000FB021040F30F10288094F835 +:10B150004010890724D5B4F95E10884203DDB4F9A4 +:10B160006220904207DC00E02EE088420ADAB4F95F +:10B170006210884206DAB4F86200288094F8400031 +:10B1800080070DD5B5F90000B4F96210884207D1E7 +:10B19000B5F90200B4F96410884201D184F88470D2 +:10B1A000316894F8840091F8DD1301F00F01401A22 +:10B1B00040B284F88400002801DA84F8847028689A +:10B1C000C4F86A00BDE8F08184F88470012084F836 +:10B1D0008200F7E72DE9F0470446012790F8840044 +:10B1E0008846B94668B194F88200012809D0032244 +:10B1F00004F16E000AF068F994F88300012805D084 +:10B200005AE0484684F88290BDE8F0878648854E2B +:10B2100040780028306806D090F8E01390F8E103F9 +:10B2200061F31F450DE090F8DE1390F8DF0361F342 +:10B230001F4560F30F057D48017821B1C07860F3A8 +:10B240001F4560F30F052A14524328B200FB002566 +:10B2500004F16A03414618460AF064F90022A84244 +:10B2600001DD104600E0484698B1316894F840305E +:10B2700091F8D90300EB800040001B0704D591F83A +:10B28000D80300EB8000400020B1A16A81420DD8B4 +:10B2900000E058B1306890F80C03000600D4002795 +:10B2A000D4F86A00C8F800003846ADE784F8832077 +:10B2B00094F984000028F7DD41462046FFF7BAFEE6 +:10B2C000F2E72DE9F84F0446012000905648DFF8D8 +:10B2D00054B10D464178DBF800004FF0000A91B1FF +:10B2E00090F8EA7390F8EB630322294604F16E00AC +:10B2F0000AF0EAF894F8400000071DD594F8BA0166 +:10B30000012805D018E090F8E87390F8E963EBE7BE +:10B31000DBF80000A16A90F8F00381420CD2688843 +:10B32000B4F86C10401AB4F87E100844A4F87E00FB +:10B330002888B4F86A100BE06888B4F87410401AD2 +:10B34000B4F87E100844A4F87E002888B4F872107F +:10B35000401AB4F880100844A4F88000B4F97E00C4 +:10B36000002801DB014600E04142B9427DDD4FF09B +:10B37000010A002801DDC11B00E0C1190FFA81F9A3 +:10B38000A0EB0900A4F87E0034F86C1F01EB090063 +:10B3900000B22080DBF80010B1F932100AF08CF80E +:10B3A00024F86C09B5F902108646081A0FFA80FCD9 +:10B3B000BCF1000F01DB604601E0CCF10000B842B7 +:10B3C00074DDB4F97400081A00D5404201B2DBF80C +:10B3D000000090F88523920737D594F8C9210AB167 +:10B3E000134A5180124AB2F90280B1EB080290F878 +:10B3F000882302D502F00F0200E012090B4F90F8EB +:10B4000064363F780FB190F86A36B4F842709F42C4 +:10B4100011D9D4F898208A1A90F86C260AD502F02F +:10B420000F0208E0A0071000D807100074071000F2 +:10B43000480610001209C2F1100308FB02F701FBD5 +:10B440000371F34A41F30F11518090F8EE2390F805 +:10B45000EF7390F8EC3390F8ED83914210DB974254 +:10B460000ED0B94202DD43460AE020E0891AA8EB7B +:10B47000030801FB08F1BA1A91FBF2F119440BB26F +:10B48000B4F97E1001FB0CF1002907DDB9F1000FC2 +:10B4900000DC5B420EEB0301A4F86C10B0F9321033 +:10B4A000B4F96C000AF008F8A4F86C0016E0DBF8B8 +:10B4B0000010B4F97000498E884203D1B4F97420A9 +:10B4C0008A4203D050B9B4F8741039B9B4F96C1089 +:10B4D000814203D0A4F86C004FF0010AB4F9800057 +:10B4E000002801DB014600E04142B14273DD002843 +:10B4F00001DD811B00E081190FB2C01BA4F88000A0 +:10B5000034F86A0F384400B22080DBF80010B1F93B +:10B51000341009F0D1FF24F86A09B5F9001081460A +:10B52000081A0FFA80F8B8F1000F01DB404601E07D +:10B53000C8F10000B0427DDDB4F97200081A00D5F0 +:10B54000404201B2DBF8000090F88523920732D523 +:10B5500094F8C9210AB1AE4A1180DFF8B4A2BAF951 +:10B560000030CA1A90F8882302D502F00F0200E0DA +:10B570001209DFF8A0C290F864669CF800C0BCF124 +:10B58000000F01D090F86A66B4F842C0B44509D9FA +:10B59000D4F898208A1A90F86C2602D502F00F028F +:10B5A00000E01209C2F11006534301FB063141F3DA +:10B5B0000F11AAF8001090F8EE2390F8EF6390F8BE +:10B5C000EC3390F8EDC3914210DB96420ED0B142BD +:10B5D00002DD63460AE01DE0891AACEB030C01FBB7 +:10B5E0000CF1B21A91FBF2F119440BB2B4F98010CC +:10B5F00001FB08F1002906DD002F00DC5B4209EBAE +:10B600000301A4F86A10B0F93410B4F96A0009F023 +:10B6100053FF14E0DBF80010B4F96E008A8E9042FC +:10B6200003D1B4F97230934203D058B9B4F8722000 +:10B6300042B900E00FE0B4F96A20824202D0A4F8D7 +:10B640006A0008E0BAF1000F05D191F80C0300067A +:10B6500001D400200090D4F86A0028600098BDE86A +:10B66000F88F10B5044690F8C60104281DD194F84F +:10B670004000400719D404F10C01081D09F052FFE5 +:10B6800002466548006890F8DA13B4F84000494370 +:10B6900043070AD48A4202DA40F0020003E020F0B5 +:10B6A000020040F00400A4F8400010BD2DE9F04174 +:10B6B0000E4604460125FFF7D4FF94F8C60103287F +:10B6C00004D0042807D0082825D027E0314620469A +:10B6D00000F029F822E0504F386890F8D603800730 +:10B6E00009D531462046FFF775FD054694F88200DE +:10B6F000012803D00CE0012084F88200386890F81B +:10B70000D603C00704D031462046FFF7DAFD0546D0 +:10B71000012D03D005E0D4F87A0030603068C4F819 +:10B720007A0028464EE570B504460868C4F86A00F9 +:10B730000D46032204F16E0009F0D2FE364800687F +:10B7400090F8D6138A074FF000012CD5334A1678AB +:10B7500001227F230EB394F8406036071DD594F87C +:10B76000C561012E12D084F8821084F8832084F8F9 +:10B7700084306A88B4F86C30D21AA4F868202A8819 +:10B78000B4F86A30D21AA4F866200CE084F882205B +:10B7900084F8831084F8841005E084F8821084F81B +:10B7A000832084F8843090F8D603C00702D024F8B0 +:10B7B0007E1F618070BD1A4810B543781648026834 +:10B7C00083B192F8E70392F8E43300F00F04000924 +:10B7D00092F8E5235B435243994202DD91420CDB30 +:10B7E000204610BD92F8E60392F8E23300F00F0411 +:10B7F00000095B4392F8E323EDE79A4200D1521C23 +:10B80000C91A041B6143D21A91FBF2F1401A10BD10 +:10B810004806100074071000A00710003907100038 +:10B82000D807100030B50124039D9C4035B10914A0 +:10B8300091420EDA81682143816030BD09B29142A4 +:10B8400003DA01682143016030BD41682143416052 +:10B8500030BDC1682143C16030BDFF49B0F900006F +:10B86000B1F92020824203DCB1F92210814201DAD1 +:10B8700001207047002070472DE9F84391460646A5 +:10B88000DDE9087288790025DDF828C00C46032818 +:10B890002FD2F248DFF8C883016891F87A0CA080B3 +:10B8A000D8F80880B8F1000F04DD91F87B8CA0EB8C +:10B8B0000800A080B1F87C1C306B884217DDDBB239 +:10B8C00049463846CDF800C0FFF7ACFFA079401CD0 +:10B8D000C0B2A071032806D0E249B6F95500B1F90B +:10B8E0000010884205DD0320A071012501E0002041 +:10B8F000A0712846BDE8F8832DE9F0410446DA48F6 +:10B900000078002859D0D548006890F8700CC0061F +:10B9100053D594F90E0200284FDA94F840008006BF +:10B920004BD4A08F0023C00400D5012304F10C00E8 +:10B93000FFF793FF0546B4F840004FF001064106BB +:10B940004FF002074FF0030C1DD51D430CD084F8B7 +:10B95000C67140F00100A4F8400094F8CA01032821 +:10B9600021D284F8CAC11EE020F0410040F0280036 +:10B97000A4F84000002204F5E071204601F03DF8F3 +:10B9800084F8BA610FE004F12000FFF766FF012898 +:10B9900001D1012D13D0B4F8400020F0400040F058 +:10B9A0002000A4F8400094F84000400605D5AF48B8 +:10B9B00010F87D1F41F004010170BDE8F081002BFB +:10B9C000F1D0B4F8400040F04100A4F8400084F801 +:10B9D000C67194F8CA01032801D284F8CAC10E21A5 +:10B9E00004F5DC700EF0FCFDE068C4F8C00184F8DA +:10B9F000C461D8E702B29948006890F8F61C8A4200 +:10BA000003DB808E401A904201DA0120704700204B +:10BA1000704730B591490246002009684C8EB1F854 +:10BA2000023DE51A131412B29D4205DAB1F8045D25 +:10BA3000AA4201DA012030BDB1F8065DAB4205DA59 +:10BA4000B1F8085DAA4201DA022030BDB1F80A5D02 +:10BA5000641B9C4207DA8C8EB1F80C5D641B944227 +:10BA600001DA042030BDB1F80E4DA342FADA8B8E14 +:10BA7000B1F8101D591A9142F4DA082030BD774907 +:10BA8000B0F90E200968B1F8EE3C9A4214DBB1F827 +:10BA9000F03C9A4210DCB0F90C20B1F8F23C9A422A +:10BAA0000ADBB1F8F43C9A4206DC806A91F8F71C94 +:10BAB000884201D800F0B4BF70472DE9F047674EC7 +:10BAC0000024326892F8ED3C9D0790F8163219D5A3 +:10BAD0003BB990F81752A5B392F831707F1EBD4262 +:10BAE00030D092F830506D1EAB4202D190F81772F0 +:10BAF0003FB3AB4206D192F8315090F817726D1EE9 +:10BB0000AF421FD092F8B15CB0F953804FF0640C93 +:10BB100008FB05F898FBFCF52DB24D4395FBFCF1B5 +:10BB20000DB25349B24692F8B06C92F8AF7CD1F89E +:10BB300000C0B34208D290F81712B94204D20021D3 +:10BB40000FE0FFE701243CE0B34212D292F831103B +:10BB500090F817828946C91B88450ADBA9F10100C4 +:10BB6000C1B260460EF038FEB0F90000A842E9DC30 +:10BB700027E092F83010D046891B8B420ADB90F800 +:10BB80001762BE4206D2002160460EF025FED8F8AC +:10BB900000100FE056468B4213DB90F8171292F814 +:10BBA0003100C21B91420CDB401EC1B260460EF058 +:10BBB00013FE316891F8301000EB410030F9020CAF +:10BBC000D4E72046BDE8F0872DE9F05F4FF0FF0A8B +:10BBD0004FF000090646D0464F4690F85B502DE0E6 +:10BBE0002348E9B200680EF0F7FD834696F8594005 +:10BBF0001FE01A483BF914100068B0F8F90C8142B4 +:10BC000016DD2146504609F02DF900F0FF0A2146C5 +:10BC1000484609F02BF900F0FF092946404609F093 +:10BC200021F900F0FF082946384609F01FF9C7B28C +:10BC3000641C96F85A00A042DBD26D1C96F85C009A +:10BC4000A842CDD2A9EB0A01A7EB0800CA01431C08 +:10BC5000803292FBF3F20DE044201000A0071000A8 +:10BC60004C061000D006100039071000385701208C +:10BC700050071000C0018030491C90FBF1F081B2E8 +:10BC8000FE4892B20068B0F8FD3C934203D3B0F88E +:10BC9000FF0C884202D20120BDE8F09F0020FBE7A4 +:10BCA0002DE9F047F64ADFF8D483F64C1578D8F83A +:10BCB0000070F54A90F81662B7F9FBAC00211278D3 +:10BCC00023684FF00109B6EB550F10D290F817C258 +:10BCD000BCEB520F0BD218460EF07EFD0188408857 +:10BCE0000D18012120680EF077FD00883FE0B6EBCB +:10BCF000550F19D290F817C2BCEB520F14D397F816 +:10BD000031004546401EC1B218460EF065FD01885F +:10BD100040880E18286890F83100801EC1B2206853 +:10BD20000EF05AFD00884BE0B6EB550F21D390F88A +:10BD300017C2BCEB520F1CD2002118460EF04CFD6E +:10BD4000D8F80010464691F8301000EB410030F86A +:10BD5000021C30F8040C0D18012120680EF03CFD87 +:10BD6000316891F8301000EB410030F8020C2844A3 +:10BD700027E0B6EB550F25D390F81702B0EB520F22 +:10BD800020D397F831004546401EC1B218460EF048 +:10BD900023FD296811F8302F00EB420030F8022C07 +:10BDA00030F8040C16184878801EC1B220680EF0D6 +:10BDB00013FD296891F8301000EB410030F8020CB7 +:10BDC000304401B2514501DA4FF000094846F9E626 +:10BDD00070B504460025C068FFF70CFE88B9A74877 +:10BDE0000068B0F8EA1CB0F8E80C091AB4F8BC0115 +:10BDF000814205DB28B1D4F8C00100F015FE00B97E +:10BE00000125284670BD10B5FFF703FE002809D0B4 +:10BE10009E494A8882434A808A8882438A80CA88A7 +:10BE20008243CA8010BD2DE9F34F984885B00E4675 +:10BE300000784FF0000920B19449401E087000F0CE +:10BE4000EFFD05984FF0000800F580504FF0010A13 +:10BE50000490ECE104980AFA08FBD0F8E01F11EA1C +:10BE60000B0F75D0059808EB081100EB411505F58F +:10BE7000DC742846FFF740FDB5F84010480667D44B +:10BE8000EF68039795F8C601012806D0022804D070 +:10BE9000C9077DD004287CD0A8E17D4AB5F95310AC +:10BEA000B2F90020914253DB012803D10E21204634 +:10BEB0000EF074FB002000907648007828B96F4897 +:10BEC000006890F8700C80064ED5E868FFF7A1FD79 +:10BED00038B1012000906948006890F8A50C85F8F9 +:10BEE00019020098A8B364212846FFF7E6FD01284F +:10BEF00030D02846FFF768FE01282ED00620207398 +:10BF0000B5F840005D4F40F00100A5F84000E8683A +:10BF1000A06084F80DA039684346284691F89D1C1E +:10BF20000096CDE9011A2146039AFFF7A5FC814648 +:10BF30003868B0F8EA0CA080E868FFF76AFD18B12D +:10BF400052498A8802438A8095F8C411072906D08D +:10BF50006AE109E0052185F81A120720CFE74B496D +:10BF6000CA880243CA805FE14B4A38B2B2F9101066 +:10BF700088420CDBB2F91210884208DCB2F91A30A0 +:10BF80003914994203DCB2F91830994233DA01E0EE +:10BF90000FE13AE0B5F8401041F00101A5F840107A +:10BFA000217B09B9E968A16084F80CA0B2F91010EE +:10BFB0005746884203DBB2F9123098420CDD00206C +:10BFC0000096CDE90110434621462846039AFFF723 +:10BFD00053FC8146277327E1B2F918004346CDE9A7 +:10BFE0000060029721462846039AFFF745FC8146E8 +:10BFF0000320207318E100202073306940EA0B0011 +:10C0000030612846FFF73BFD0EE1207B07282AD14F +:10C010001A48006890F8B21C2846FFF74EFD012828 +:10C020000BD02846FFF73CFE012806D095F81A02EF +:10C0300050B1401E85F81A0215E01048006890F8CB +:10C04000121D85F81A120EE006202073A068FFF773 +:10C05000E0FC18B10D49CA888243CA80A088012833 +:10C0600001D8A4F804A0207B062825D1A0880128A7 +:10C0700032D92846FFF7A8FD01280FE0A0071000DD +:10C080002507100050071000240710004C06100070 +:10C09000E4061000740710004420100009D10720A6 +:10C0A0002073A068FFF7B5FC18B1F949CA880243AC +:10C0B000CA80207B06280FD0C0B207280CD0F54AD2 +:10C0C00039B2B2F91030994203DBB2F91230994219 +:10C0D0005FDD03285AD089E0E868FFF79AFC30B1A9 +:10C0E000ED48006890F8A51C85F8191205E095F850 +:10C0F000190278B1401E85F81902E748CDF800A072 +:10C1000008F0FF0300680399B0F99E2C3046FFF752 +:10C1100089FB6BE0DF4A39B2B2F91000814203DBE0 +:10C12000B2F9123099420DDD00210096CDE90101EE +:10C13000434621462846039AFFF79EFB814684F832 +:10C140000CA01FE0B2F91A103814884203DCB2F9CF +:10C15000181088420FDAB2F918104346CDE9006191 +:10C16000CDF808A021462846039AFFF785FB8146B3 +:10C170000320207306E0316941EA0B013161C749B0 +:10C1800081F800A0A068FFF73EFE2FE084F80CA025 +:10C190000CE0B2F91A303914994203DCB2F91820D4 +:10C1A000914223DA012821D103202073E868A0609E +:10C1B0001CE0B84938B2B1F91020904216DDB1F94F +:10C1C0001220904212DAB1F91A20381490420DDA96 +:10C1D000B1F91810884209DD3169284641EA0B019E +:10C1E0003161AE4981F800A0FFF749FC95F8C6011E +:10C1F000052819D1A848B5F90E100068B0F8EE2C42 +:10C20000914211DBB0F8F02C91420DDCB5F90C1025 +:10C21000B0F8F22C914207DBB0F8F42C914203DC29 +:10C2200090F8F81C9A480170049808F1010890F9F8 +:10C23000EC1F4145BFF60EAE30687268B168F36816 +:10C2400040EA020441EA03052C43346901D02CB1D1 +:10C2500007E034B18E4C0225657002E08C4D85F804 +:10C2600001A08C4C58342568A84330606068824334 +:10C270007260A0688143B160E06889498343F360DC +:10C2800030690978084305D12C22A4F12C0181489A +:10C290000EF04AF907B04846BDE8F08F30B590F887 +:10C2A000C611002204292DD17B490B6893F8701C1C +:10C2B000490727D5B0F84810B0F84A40091B754C1B +:10C2C000248DA1421EDD4FF4E271095C012901D0E9 +:10C2D00002290AD190F85A4090F85950641B93F8FB +:10C2E000795CAC4201DD01220CE0032901D0042974 +:10C2F00008D190F85C1090F85B00081A93F8791C4C +:10C300008842F0DC104630BD30B5634900220B682E +:10C3100093F8701C49072BD590F8C611042927D132 +:10C32000B0F84810B0F84A40091B5A4C248DA1427D +:10C330001EDD4FF4E271095C012901D002290AD106 +:10C3400090F85A4090F85950641B93F8795CAC42CD +:10C3500001DD01220CE0032901D0042908D190F865 +:10C360005C1090F85B00081A93F8791C8842F0DCA6 +:10C37000104630BD2DE9F34F8BB0454800270A9792 +:10C3800040780E46012806D1306920B14148416904 +:10C390000391C06903E03F480169039180694FF050 +:10C3A000000882460B9800F580500990F9E1099841 +:10C3B0004FF0010909FA08FBD0F8E01F11EA0B0F52 +:10C3C00018D00B9808EB081100EB4115B5F84000A8 +:10C3D00041060FD4C0070ED0E868029095F8C60158 +:10C3E00005F5DC7401280AD0022808D004282FD0D3 +:10C3F000052875D0D2E1294981F80090CEE1F06896 +:10C400000090306901901422314604A80EF047F8DC +:10C410000DF1100B28469BE80E00FFF73FFF0128A7 +:10C4200001D184F80190F0680090306901901422E5 +:10C43000314604A80EF033F80DF11009284699E8AA +:10C440000E00FFF761FF0128D4D10020A080A5E1F4 +:10C45000207B012801D0032804D10E4841690391B3 +:10C46000D0F81CA0F0680090306901901422314689 +:10C4700004A80EF014F80DF1100C28469CE80E00EC +:10C48000FFF742FF01280DD0A08801280CD01CE046 +:10C490004C06100044201000A0071000EA0610000F +:10C4A00064071000002014E0207B06280FD12846E6 +:10C4B000FFF78EFC30B1316941EA0B013161FA4975 +:10C4C00081F80090A068FFF79EFCA08810B1A088BA +:10C4D000401EA080F548008818B10020A08002E02E +:10C4E0000CE1A08820B995F8D01109FA01F00743B2 +:10C4F000F0680090306901901422314604A80DF0D4 +:10C50000CEFF0DF1100C28469CE80E00FFF7C6FE8A +:10C51000012801D184F80190A079032819D2A188BB +:10C52000B9B1E3492A6B0968B1F87C1C8A420EDD77 +:10C53000401CC0B2A071032806D0DE49B5F95500F1 +:10C54000B1F90010884204DD01200A9001E00020CA +:10C55000A071207B06281BD0072819D0039ABDF9AB +:10C56000081012B2019291420DDB039A121491420B +:10C5700009DCBDF90A104FEA2A42914203DC0FFAA6 +:10C580008AF291427EDA022840D0042841D044E069 +:10C59000306910EA0B0F30D0C5486422016891F869 +:10C5A000010DB1F8EA1C4043494391FBF2F101FB54 +:10C5B00000F904F108018B4602A808F0B3FF4845D2 +:10C5C00007D2012202A9284600F017FA0298286231 +:10C5D00004E000225946284600F00FFA95F8D001F1 +:10C5E000012101FA00F0874335F8400F20F00500E3 +:10C5F00040F008002880A170D0E001200090AC48F5 +:10C6000008F0FF030068B0F99E2C38E084F80C9025 +:10C6100001E003202073E868A060607830BBA64981 +:10C6200004F1080B05F10C00496A009195F8C4115A +:10C6300001292BD0594608F075FF009988420CDD7E +:10C6400001225946284600F0D8F9B5F8400020F0FC +:10C65000050040F00801A5F8401095F840000007DB +:10C6600004D595F8D01109FA01F08743207B012801 +:10C6700013D008F0FF030FFA8AF2CDF8009030468D +:10C68000029900E011E0FFF7CDF887E0BBF9021056 +:10C69000B0F90200081A4043CFE700200090DDE91E +:10C6A000012108F0FF033046EBE73069002240EA41 +:10C6B0000B00306104F10801284600F09EF9B5F83E +:10C6C000400020F0050040F00800A5F84000784840 +:10C6D00084F80290B5F84210006890F8862C9142D8 +:10C6E00006D995F8CA1190F8870C084485F8CA0154 +:10C6F00095F8D01109FA01F087434FE0207B01281B +:10C7000004D003280BD0062814D017E0A088E8B383 +:10C710006748B5F955100068B0F88D0C07E0A0889F +:10C72000A0B36348B5F955100068B0F8880C814291 +:10C7300019DC33E02846FFF74BFBA0B9207B072824 +:10C7400022D1E868FFF756F9F0B95948006890F827 +:10C75000ED0CC00718D0B5F8BC01A8B1D5F8C001E0 +:10C7600000F062F980B9012204F10801284600F0C6 +:10C7700044F935F8400F20F0010040F08000288097 +:10C78000B5F81500A5F81300207B00E006E00628A8 +:10C7900001D0072802D1A068FFF735FB099808F1FE +:10C7A000010890F9EC1F4145BFF601AE43490FB1B6 +:10C7B000012000E0002008700A980DB06CE53C49AB +:10C7C0003D4A09682C32898E1084081A50847047BB +:10C7D000374A394B12682C3340B171B1518E081A67 +:10C7E000588392F8821C401AD883704711B1508E3A +:10C7F0005883F9E70020188303E0188392F8821C1D +:10C800000844988370472A4910B40B682A4A998EC5 +:10C810002C3260B11082091A518293F8824C204464 +:10C820009082081BD08293F8850C10BCC7E70020CB +:10C83000108251829082D1821084518410BC704742 +:10C8400070B51B4C206890F8830CFFF7DCFF206864 +:10C85000012190F88C0CFFF7BBFF2068002190F8B5 +:10C860008C0CFFF7B5FF2168134A91F8800C2C322D +:10C870004043506291F8810C10850F492C222C31D5 +:10C880000D480DF051FE0D4800240D4D0470064872 +:10C89000142104700848AC6058300DF0A1FE09481E +:10C8A00004706C7070BD0000EA0610001C071000D8 +:10C8B000A0071000D006100044201000E806100069 +:10C8C0004C061000E906100070B586B0064614212B +:10C8D00068460DF085FE5A480024694604703046CB +:10C8E000FFF7A1FA054669463046FFF743FD2843A6 +:10C8F0005449012801D0886805E05348006890F841 +:10C900007A0C401F8860002804DD401E88604F4874 +:10C91000007800B98C60142269464D480DF004FE81 +:10C9200006B0BFE72DE9F04700F136060546B078BE +:10C93000DFF820810A460024C0B14749F37808781F +:10C94000401E834257D18946C1B210460DF03EFFCA +:10C95000074699F80000401EC1B2D8F800000DF05B +:10C960003BFF03463078717802460FE00021104605 +:10C970000DF02CFF07460021EFE7BE5C95F841C0A3 +:10C98000664501D1641CE4B2521CD2B29142F4D289 +:10C990002D4A60B11668B6F8726C401EC0B233F909 +:10C9A0001070B74203DD641CE4B20028F5D12B48B7 +:10C9B0000078401E81420DDA166881420ADA491C6D +:10C9C000C9B2B6F872CC33F91170674502DD641C48 +:10C9D000E4B2F2E7224880F87E40116891F8841CA6 +:10C9E000A14208D2A98C41F48051A98410F87D1F7E +:10C9F00041F008010170BDE8F087022380F8C631DC +:10CA0000002380F8CA3101238362012A04D0096817 +:10CA1000016280F8B831704703220C3008F060BD25 +:10CA2000084881884180704710B50024FEF7F1FF67 +:10CA300020B104494988014200D00124204610BD9C +:10CA4000EA0610004C061000A0071000E8061000CF +:10CA50009C2010005007100024071000250710002C +:10CA600038570120FBF79AB810B542F2A001FB48F5 +:10CA70000DF0B6FD4FF4C461F9480DF0B1FDF94871 +:10CA8000FF2180F8EC1FF8490020088000F0FEFF2D +:10CA9000FEF734FAFFF7D4FE00F010FAFCF7E8F9DD +:10CAA000FDF787FABDE81040FBF77AB810B5EC4CFB +:10CAB000EE4994F8180688712146E84801F026F8F6 +:10CAC000EB48007810B1E548FFF7FEFEE948006842 +:10CAD00090F80C03C00702D0E048FEF7E6F9DF4803 +:10CAE00000F07BFBDD4800F009FDDC48FCF7CEF9E7 +:10CAF000DA48FDF76AFAD948FBF74CF9002084F8C8 +:10CB0000180610BD10B5D94800248471D34800F030 +:10CB1000C3FFD248FCF7BAF9D048FBF7BAF8D248BD +:10CB20000480CF4880F8184610BD10B5CC4C94F85E +:10CB3000180690B1CD4988712146C84800F0E6FF3B +:10CB4000C64800F04AFBC548FCF7A0F9C348FBF70C +:10CB5000A0F8002084F8180610BDBDE81040D1E709 +:10CB600010B5C24800248471BC4800F095FFC0484D +:10CB7000007828B1B948FFF7A7FEB84800F02DFBB0 +:10CB8000B648FCF783F9B548FDF71FFAB348FBF741 +:10CB900001F9B34880F8184610BD10B5B04C0146F5 +:10CBA00094F818060F280FD200EB800202EBC000A9 +:10CBB00004EBC00068220DF0B7FC94F81806401C86 +:10CBC00084F81806012010BD002010BD10B500F536 +:10CBD00080500021D0F8E02F1346D40706D0520829 +:10CBE000491C0F29F9DB4FF0FF3010BD01228A40AC +:10CBF0001343C0F8E03F90F9EC2F8A4201DA80F845 +:10CC0000EC1F48B210BD10B500F5805091F80D42F0 +:10CC10000123D0F8E02FA3409A43C0F8E02F002270 +:10CC200081F8C62190F9EC2F91F90D128A4207D1B3 +:10CC3000D0F8E01FB1FA81F1C1F11F0180F8EC1FBB +:10CC400010BD30B500F580500022D0F8E43F1C46FE +:10CC5000DD0708D0521C5B0852B20A2AF8DBFF201D +:10CC600081F80E0230BD012393401C43C0F8E44F0D +:10CC700081F80E2230BD10B500F5805091F80E42BB +:10CC80000123D0F8E42FA3409A43C0F8E42FFF20FB +:10CC900081F80E0210BD72487047704870477048A6 +:10CCA00090F8180670476E48A03890F89A007047C0 +:10CCB0006B4810B50421C0380CF0F0F9C0B210BDBB +:10CCC00070B56C480026664C01683546A4F1A00496 +:10CCD00091F86602C0062CD567480078012828D054 +:10CCE000664AB1F86D0212780AB1B1F8620264497D +:10CCF000097811B36349096888421ED25848042153 +:10CD0000C0380CF0CBF9014694F89900544AB8B1F8 +:10CD100092F8181694F8983099420ED9401C10F0E9 +:10CD2000FF0084F8990084F8981082F8185612D100 +:10CD300012E084F89950002070BD84F899500BE0FF +:10CD400092F81806884207D9012184F8991084F8CE +:10CD5000980082F818560126304670BD2DE9F04142 +:10CD60003F4F4FF0004597F81866002E3AD000204C +:10CD70000AE000EB800101EBC00107EBC101C969CA +:10CD8000A94200DD0D46401CB042F2DB002087F8CE +:10CD900018060446DFF8DC8022E004EB840000EB98 +:10CDA000C40007EBC0016422C869504390FBF5F052 +:10CDB000D8F8002000B2B2F8252282420FDA97F8A4 +:10CDC000180600EB800202EBC00007EBC0006822EF +:10CDD0000DF0AAFB97F81806401C87F81806641C8B +:10CDE000B442DADBBDE8F0812DE9F0411B4D0024AF +:10CDF00005F580560127D6F8E00F07FA04F108423E +:10CE000010D004EB041005EB401191F90E0200283C +:10CE100008DBD6F8E43F07FA00F2134202D02846B6 +:10CE2000FFF729FF641C64B20F2CE4DB042105F535 +:10CE3000FF500CF033F90C490880D3E70121814001 +:10CE4000002809DB0748D0F8E02F0A4204D0D0F8C8 +:10CE5000E82F0A43C0F8E82F70470000B020100008 +:10CE600050411000B0301000580610003857012013 +:10CE700039071000A007100018051000B3061000B5 +:10CE800032071000C80610000028E5DB01218140B0 +:10CE90000948D0F8E82F8A43C0F8E82FDCE70028DB +:10CEA00008DB054901228240D1F8E81F114201D078 +:10CEB0000120D1E70020CFE7B030100070470021FB +:10CEC000A0F8DC11C0F8D811A0F8DE11202100F57F +:10CED000F3700DF063BB02B90122521E12F0FF0283 +:10CEE00006D000EB420333F8023C20F81230F4E79E +:10CEF0000180704702B90122002303E020F81310DB +:10CF00005B1CDBB29342F9D3704770B590F8C62131 +:10CF10000CB200F5F375032A05D090F83C10C90651 +:10CF200007D5FFF7CCFF102221462846FFF7E2FF86 +:10CF300004E0102221462846FFF7CDFF2846BDE831 +:10CF40007040102109F04BB82DE9FC5F0546F94807 +:10CF50004FF000086E6B077895F8C601DFF8D8A38C +:10CF60004446C146C346CDF800800F282BD2DFE8E7 +:10CF700000F0E50808082BE5E5E5E52B2BF4F4E5E2 +:10CF8000F400002085F8E4012846FFF798FF95F8A3 +:10CF90003C004FEAC0704FB10028DAF8000002D020 +:10CFA000B0F8D84A0BE0B0F8D64A08E00028DAF822 +:10CFB000000002D0B0F8D04A01E0B0F8CE4AA64254 +:10CFC00071DA01208046B9E005F10C01081D08F076 +:10CFD000A9FA814695F8E40160B9DAF8000017B1C2 +:10CFE000B0F8CB0A01E0B0F8C90A864202DD0120A0 +:10CFF00085F8E401DAF80000D04B90F8CD2A1B78D0 +:10D000009A4213D395F8E42182B190F8EA0A01908C +:10D01000D04631462846FFF778FF8346D5F8080208 +:10D02000A9EB0001002905DCFE2204E02846FFF7F9 +:10D0300046FF7CE0C822494608F01CF98146019869 +:10D040004043484509DAD8F80000B0F8E81A5945D5 +:10D0500003DD2846FFF733FF63E02FB9D8F800005F +:10D0600090F8C81A89074DD5D8F80000002F95F818 +:10D070003C7090F8EB1A90F8EA2A90F8ED3A90F8A4 +:10D08000EC4A4FEAC7770FD037B1B0F8E48AB0F86E +:10D09000D87AB0F8DCCA15E0B0F8E28AB0F8D67AEF +:10D0A000B0F8DACA0EE096E037B1B0F8E08AB0F82E +:10D0B000D07AB0F8D4CA05E0B0F8DE8AB0F8CE7AFB +:10D0C000B0F8D2CAB0F8EF0AA7EB0C07BFB2B04273 +:10D0D00001DD3C4625E00120CDE9004052434943B3 +:10D0E000484607F06CFF0BFB00F10090642091FBB9 +:10D0F000F0F084B24046444501D3044611E0BC42FE +:10D10000E7D90EE095F83C10C90704D0B0F8D01A62 +:10D11000B0F8D40A03E0B0F8CE1AB0F8D20A081A70 +:10D1200084B2A64201DA012000E000208046C5F862 +:10D13000D891A5F8DCB10098A5F8DE01804820F868 +:10D14000644FDAF80010B1F8C91A4180C680A0F81F +:10D1500004904046BDE8FC9FFFE7774895F83C10F7 +:10D1600000684FEAC17177B131B1B0F8E42AB0F884 +:10D17000D81AB0F8DC3A14E0B0F8E22AB0F8D61ABF +:10D18000B0F8DA3A0DE031B1B0F8E02AB0F8D01AD0 +:10D19000B0F8D43A05E0B0F8DE2AB0F8CE1AB0F80C +:10D1A000D23AC91AB0F8E63A90F8EE0A1A44B5F93C +:10D1B000DE3192B21844B5F9DC3189B258436423A8 +:10D1C00090FBF3F084B2944201D31446F7E68C420C +:10D1D000FCD80C46F3E60020F4E62DE9F05F0746A4 +:10D1E0004FF0000907F58055CA46484695F9EC2FDF +:10D1F00015E00121D5F8E03F81400B420DD000EB56 +:10D20000001107EB411191F8C611012905D002293F +:10D2100003D009F1010101F0FF09401C40B2824234 +:10D22000E7DA0026E7E04FF0010ED5F8E01F0EFA2E +:10D2300006F001420BD006EB061007EB401494F801 +:10D24000C601012804D0022802D0042870D0D0E002 +:10D2500094F81802012808D094F8C721032A08D0AE +:10D26000042A06D0012A04D0C3E0002084F8180262 +:10D270008BE0344894F840300021B0F900004FF0C2 +:10D28000010BDB0702D03048B0F90000B9F1000F04 +:10D2900012D12E4B1B78012B0ED127482C4BD0F8E6 +:10D2A00000C01B78BCF90502052B01D0062B01D16B +:10D2B000BCF90A024FF0000BDFF898C09CF803801D +:10D2C000B8F1000F02D19CF8043063B1012A02D0FA +:10D2D000E28FD20507D50AF1010000F0FF0A1E48CF +:10D2E000B0F900003AE0BBF1000F37D0124A1368E2 +:10D2F000B3F8C922EAB1B3F9C922B8F1000F04D1D9 +:10D300009CF804C0BCF1000F01D0B3F9CD22B4F8F1 +:10D310003CC05FEA4C5C01D5B3F9CB22B4F9533081 +:10D32000834203DBB4F91002904227DA012125E0A1 +:10D3300038E013E074071000A00710003307100056 +:10D3400038570120D0061000E40610001805100020 +:10D3500021071000945A1000D4061000E28FD20565 +:10D3600008D5934AB4F95330B2F90020934201DD55 +:10D3700084F8C7E1B4F953208242D7DB94F8C7019F +:10D38000032807D0042805D029B321463846FFF7E3 +:10D390003AFC2EE00029F8D12046FFF7D5FD012800 +:10D3A000F3D026E094F83C0010F0060F21D094F85A +:10D3B0004000C0071DD180497E480978B0F90000BF +:10D3C000012902D17D48B0F9000094F8C711032962 +:10D3D00002D0022906D00CE07848B4F95310B0F915 +:10D3E000000001E0B4F95310814202DA052084F80C +:10D3F000C601761C76B295F9EC0FB042BFF613AFBA +:10D400006F4C206890F80D03400768D56D48007890 +:10D41000F0B36D484078D8B3042107F5FF500BF006 +:10D420003DFE02285BDD00210A4608464FF0010C54 +:10D4300095F9EC8F26681CE0D5F8E03F0CFA00F473 +:10D44000234214D000EB001307EB431494F8C631C9 +:10D45000012B03D0022B01D0042B08D1B4F9533097 +:10D46000B6F88A43A34202DD491CC9B21A44401CE3 +:10D4700040B28045E0DA022931D392FBF1F096F810 +:10D4800089134143642091FBF0F006B2002400E0D0 +:10D4900025E0E0461CE0D5F8E01F08FA04F0014260 +:10D4A00014D004EB041007EB401191F8C6010128D9 +:10D4B00001D002280AD191F83E00000706D4B1F944 +:10D4C0005300B04202DA3846FFF79DFB641C64B299 +:10D4D00095F9EC0FA042DEDA3C48A0F846603C48E3 +:10D4E000C078012808D1BAF1000F05D0D5F8E00FB7 +:10D4F000002801D137490870BDE8F09F2DE9F047B9 +:10D5000007463348C078002850D1334800780128B6 +:10D510004CD000254FF0010907F5805809FA05F0B5 +:10D52000D8F8E01F01423DD005EB051007EB401491 +:10D53000002694F90D02FFF7B2FC012832D094F8CE +:10D54000C701032801D004280AD11D48006890F8BB +:10D55000C80AC00704D02046FFF7F6FC01280AD00D +:10D5600094F8C601092816D00A2814D00B2814D024 +:10D570000C2812D014E094F8C6010126032806D026 +:10D58000042804D00D2804D00E2802D008E0092079 +:10D5900004E00C2002E0042000E00D2084F8C60125 +:10D5A000C4F8D4616D1CEDB20F2DB7D3BDE8F08780 +:10D5B000D4061000D8061000E9061000D6061000A8 +:10D5C000A007100032071000D807100038570120BC +:10D5D000945A10002F071000180510002DE9F05F75 +:10D5E000DFF8CC9515460C46834601F10C084FF048 +:10D5F000FF3A002602F10C07CBB3012084F8C601E4 +:10D6000095F8400084F8C70184F80EA284F8CA6136 +:10D6100084F8CB61E687A4F84060A662E66284F8ED +:10D62000C96184F8CC6195F8420084F8CF01688E16 +:10D63000A4F85500E868206203223946204607F026 +:10D640004FFF03223946404607F04AFFD9F8000051 +:10D6500090F8980C84F8120284F8B56194F90D02E0 +:10D66000002801DBFFF710FCA4F814622CE0FFE7B0 +:10D670001146204600F010FBA06A401CA06294F8FE +:10D68000C601042804D1E06A411C01D0401CE062BC +:10D6900003223946204607F017FF03223946404649 +:10D6A00007F012FF94F8CE0184F8CF0194F8C70177 +:10D6B00004285DD195F84000042859D094F812024E +:10D6C00010B1401E84F8120295F8400084F8C7019A +:10D6D00095F8410084F8D00195F8420084F8CE0115 +:10D6E000E88CA4F84200288DA4F84400688DA4F8C2 +:10D6F0004600E88DA4F84800288EA4F84A0095F862 +:10D70000490084F84C00288BA4F84D00B5F932008C +:10D71000A4F85300A9692163E9696163296AA163D7 +:10D72000A98EA4F85710A98CA187D5F83610C4F893 +:10D7300059106969E16195F8431084F8D11195F8A1 +:10D74000441084F8D211B5F84610A4F81012B4F9B8 +:10D750005510814201DAA4F85500C4F81C6284F81F +:10D760000CA2A88C8005E08F07D540F4807006E0FD +:10D77000D9F8000090F8980CA4E720F48070E087B6 +:10D78000A88C0005E08F02D540F4806001E020F411 +:10D790008060E08715F83E0F84F81602687884F8F8 +:10D7A000170221465846BDE8F05F00F04BBA2DE95C +:10D7B000FF4F0E46FF498346FD4D49688BB0002060 +:10D7C000086028689A46B0F80E430CF0B7FF0128AD +:10D7D00004D12868B0F8100300B10446F648007878 +:10D7E00060B12868F54AB0F816131268B0F8124311 +:10D7F0004943914202DAB0F814030444F048007837 +:10D80000002802D02868B0F82842E94804FB04F850 +:10D81000006890F8189301D090F82A920BF5805088 +:10D820004FF000050990A7E00998D0F8E01F4FF0ED +:10D83000010000FA05F001427AD005EB05110BEB6F +:10D84000411494F8C601072872D02146201D07F024 +:10D8500069FE00FB09F000FB09F794F8C6010328F4 +:10D8600005D1D3490968B1F8191301FB01F8414604 +:10D87000474500DA0F46042807D0062805D00A28B5 +:10D8800003D00C2801D00E281BD1CE4800780628E2 +:10D8900017D0052815D00420049000214FF475609E +:10D8A000CDE90201009104F5907304F5847204F14E +:10D8B000A00107A807F02CFD0898ADF8060007980E +:10D8C00020E0A06A10B30128224604F1040105A853 +:10D8D00021D007F01DFE221D111D06A807F018FE1D +:10D8E000BDF91600BDF91A10BDF918200844411001 +:10D8F000BDF91400104462881144ADF80610218867 +:10D9000001EB6000ADF8040000242EE06088ADF863 +:10D9100006002088F6E707F0FBFD6088BDF81610CA +:10D920000844ADF806002088BDF814100844E9E763 +:10D930001FE004EB840000EBC40006EBC00101A86B +:10D940000C3107F0EFFD0146B8420CDA9948406807 +:10D95000026802EB420200EB4202516054721572FF +:10D960000168491C0160641CE4B296F81806A042E4 +:10D97000DFD86D1C09986DB290F9EC0FA842BFF684 +:10D9800053AF8C4C6068016800297CD000F0ECF942 +:10D990000025DFF834824FF006096FE005EB450102 +:10D9A00000EB41000D9A90F908100127146890F9D6 +:10D9B000090007FA01F214425FD1DAF800C007FA51 +:10D9C00000F31CEA030F58D114430D9A1460DAF8DF +:10D9D00000201A43CAF8002001EB011200EB80017D +:10D9E0000BEB421401EBC00006EBC0020023214602 +:10D9F0005846FFF7F3FD94F8C601032808D0042821 +:10DA000009D006280CD00B2834D00C2832D034E0B2 +:10DA100084F8C97102E0002084F8C90104202AE0DA +:10DA2000042084F8C60194F83C0010F0060F24D0BE +:10DA300094F84000C00720D1654964480978B0F9DE +:10DA40000000012901D1B8F9000094F8C711032999 +:10DA500002D0022908D010E0B4F95310B8F9000040 +:10DA600004E084F8C69108E0B4F953108142F8DB71 +:10DA700003E008E00C2084F8C6016D1C4D484068A6 +:10DA80000168A9428ADC0FB0BDE8F08F4948002147 +:10DA900001704160816070472DE9F041064641F612 +:10DAA000EE702E2130440CF079FD0024052706F598 +:10DAB00080551EE00121D5F8E00FA140084217D0A3 +:10DAC00004EB041006EB401191F8C601032816D0B0 +:10DAD000042814D0022815D0092810D00A280ED006 +:10DAE0000B280FD00C280DD00D280BD00E2809D0F4 +:10DAF000641C95F9EC0FA042DCDABDE8F08181F8F6 +:10DB0000C671F5E73046FFF77EF8F1E72DE9FC47EF +:10DB10000546002427480F4600940121001D01946A +:10DB200004F0BCFC23480521083004F0B7FC41F6A2 +:10DB3000EE702E2128440CF031FD1E4EFF222D21C7 +:10DB4000B0680CF023FD347005F580564FF00109E4 +:10DB5000D6F8E00F58B36B4601AA39462846FFF7BE +:10DB600026FE4FF0050821E0D6F8E01F09FA04F080 +:10DB700001421AD00199084217D104EB041005EBB9 +:10DB8000401191F8C60103282BD0042829D002287F +:10DB90002AD0092825D00A2823D00B2824D00C28E5 +:10DBA00022D00D2820D00E281ED0641C12E015E0D3 +:10DBB000A00710005C061000B306100068071000F4 +:10DBC00029051000F8041000D6061000D806100031 +:10DBD000E906100096F9EC0FA042C5DA00244E4683 +:10DBE00021E081F8C681E0E72846FFF70CF8DCE782 +:10DBF000009906FA04F0084214D12846FEF7E6FF21 +:10DC000000280FDB00EB001105EB411104EB84024F +:10DC100002EBC40281F80D0207EBC2020123284681 +:10DC2000FFF7DCFC641C97F81806A042E0D801213D +:10DC30005F4804F04BFC5E480521001D04F046FCE3 +:10DC4000BDE8FC8730B55A4D91F8CE412D1FAB6829 +:10DC50001A5DFF2A05D12A781A550F2A01D2521CC3 +:10DC60002A7091F8CE2101249A5C81F8CE2100EB34 +:10DC7000420202F5805291F80D52B2F8EE3FAC40EC +:10DC80002343A2F8EE3F91F8CE1142F20C02104469 +:10DC90000A5C521C0A5430BD2DE9F041044691F84B +:10DCA000400000260D46012801D184F8CC6194F88B +:10DCB000C701404FDFF8008101281FD195F84000CF +:10DCC00003284DD194F8C601022804D0032806D0B9 +:10DCD000042804D01EE02046FBF7AFF80EE0D8F889 +:10DCE000001094F8CC0191F8F11201F00F01884274 +:10DCF00002D83978012906D084F8CC6195F8400023 +:10DD0000032807D008E0401C84F8CC01012085F8E6 +:10DD1000400001E084F8CD6194F8C70103281FD1C9 +:10DD200095F8400001281BD194F8C601042817D1AA +:10DD30003878B0B9D8F80000B4F95510B0F8F82226 +:10DD400091420EDA94F8CD1190F8FE02814207D28A +:10DD5000032085F8400094F8CD01401C84F8CD01E3 +:10DD6000CBE684F8CD61C8E67CB500221CE002EB6E +:10DD70004203511C00EB430312E001EB410400EBB2 +:10DD800044045E686568AE4209DD00961E89ADF800 +:10DD900004605D6025891D81009D65602681491CA8 +:10DDA00004688C42E9DC521C01689142DFDC7CBDD6 +:10DDB0006006100031071000A00710002DE9F74F92 +:10DDC000002282B09346904614460092FE4A15689F +:10DDD000FE4AAB8EB2F9002093427CD18946FC49C1 +:10DDE00082463635086890F8BD0AC00704D0F94865 +:10DDF0000078504305EB4005F748077866E0F748A0 +:10DE00004FF0000E10F81710F5480078401AF0494E +:10DE1000401EC0B20E6896F80C1A49064CD596F80A +:10DE2000310A96F830EA47E035F810203AF8101039 +:10DE300039F81030511AD21A09B213B2002901DB95 +:10DE40000A4600E04A425A4506DD002901DB0A463F +:10DE500000E04A420FFA82FB5A1A01D4944601E0CC +:10DE6000C2F1000CC44507DD002A01DB944601E045 +:10DE7000C2F1000C0FFA8CF8002A00DA5242B6F810 +:10DE80000DCA624517DD002B00DA5B420A1E00DA7C +:10DE90004A42934202DD641CA4B20CE0002900DA7D +:10DEA0004942B6F80F2A914205DD00270498012166 +:10DEB0003C46017002E0401E7045B5DAC848007863 +:10DEC00005EB40050AEB400A09EB40097F1E96D29C +:10DED000BF48006800E005E090F8110AA04201D2B6 +:10DEE00001200090BA48009A006890F8121ABD48C4 +:10DEF00007F046F8BC49A1F82280A1F824B081F8C7 +:10DF0000264005B0BDE8F08F70B5B54A0025012167 +:10DF100012782C46921ED3B2AD4A126892F80C6A5F +:10DF2000760603D592F8313A92F8301A4AB204E0F4 +:10DF300030F91260521C354452B29A42F8DD5A1A36 +:10DF400095FBF2F505E030F91120521B02FB02446B +:10DF5000491C9942F7DDC4F30F3070BD2DE9FF4F26 +:10DF6000B7B000212E91359131912D9101913091D1 +:10DF700095490B6895499C8EB1F900108C427DD172 +:10DF8000CDE93220994836332F9300683490904879 +:10DF9000026892F8BD2AD20705D08E4A12784A4309 +:10DFA00003EB42012F910127D9E08C48884A0024D5 +:10DFB00010F817108A4890F80090A9EB0100401E55 +:10DFC00000F0FF081068834690F80C0A400603D55D +:10DFD0009BF8318A9BF8304A329807AB00EB490036 +:10DFE00032902F9800EB49002F90339800EB4900B6 +:10DFF0003390349800EB490034900020014623F818 +:10E000001010401C2628FADB40460AE02F9931F810 +:10E010001030339931F81010591A07AB23F810104B +:10E02000401EA042F2DA00259BF80C0AAA464006E0 +:10E030000DD5464608E03246012000210CF0E5F9F6 +:10E04000054341EA0A0A761EA642F4DA25E0A9F160 +:10E050000100804522464FF001004FF000010ED133 +:10E060000CF0D3F905460E46621C012000210CF08D +:10E07000CCF905430E43A8F1010205E001E10CF0E3 +:10E08000C4F905460E46621C012000210CF0BDF9C2 +:10E090000E430543ED436FEA060A08F10100CDF88F +:10E0A0000090C0B20295CDE905400121CDE903A160 +:10E0B00007A9DFF81C91BBF93E3ABBF93C2A084698 +:10E0C000F8F7BFFD45461AAE0DF11C080FE0349875 +:10E0D00030F8150026F8150038F91500002800DA88 +:10E0E0004042319906F0C2FE80B26D1E3190A542C9 +:10E0F000EDDAD9F80000B0F8331A319881420CD229 +:10E100003848801D30F8741F491C018031994180C6 +:10E110003449002048703BB0F4E63298FFF7F4FE33 +:10E12000304DAD1D25F817001AA8FFF7EDFE05EBE1 +:10E130004704208407A8FFF7E7FEA4F84000208CDE +:10E140002D99884202D92D90B8B2359035F8170034 +:10E150000199884202D90190B8B230907F1C1E48C4 +:10E160000078401E8742FFF620AF194C4FF6FF752E +:10E17000216891F8320A80073FD52D98C0B319481D +:10E18000359A801D00EB42031226B3F8402082B37B +:10E1900017022D9AB1F8391AB7FBF2F292B29142F6 +:10E1A00008D901212E913A990E70B0F86210491CDD +:10E1B000A0F8621030F8601F491C018093F84010ED +:10E1C00005EA0121818015E0A40710003A0710003C +:10E1D000A0071000D80710002407100034260120E3 +:10E1E00025071000982601203857012054071000F9 +:10E1F00003E00CE02D99C1800281206890F8321A6A +:10E20000C90746D00199E1B32E9971B141E0B1F847 +:10E21000402A2D998A42F0D201212E913A990E700E +:10E2200030F8621F491C0180E7E7F749309A13264E +:10E2300001EB4204228C2AB3019B0827B7FBF3F3BE +:10E240009A40B0F8353A309F92B237B1EF4FDDF8CF +:10E25000C0C03F787F1E674501D1B0F8373A9A4277 +:10E2600008D201202E903A980670B1F86C00401C3C +:10E27000A1F86C0031F86A0F401C088094F8200067 +:10E2800001E006E00FE005EA002088800198C880E0 +:10E290000A81DF482E9A006890F83B1ADA48401F3E +:10E2A00006F06EFE37E7B0F8422A01988242F0D2BB +:10E2B00001202E903A98067031F86C0F401C0880AF +:10E2C000E7E72DE9F74FD24F034682B038684FF0A9 +:10E2D0000008C14690F8226AB0F9201A0091B0F9FE +:10E2E0001E1ACC48C346C246B0F9002045464446F3 +:10E2F0001846F8F787FED8B9C748007850B1C34828 +:10E3000000990278039800F04FF90546B04201D910 +:10E310004FF0010BC148007850B1C1480099027814 +:10E32000049800F041F90446B04201D94FF0010AC7 +:10E33000B948B54E0078B61F38B138685A4690F8DB +:10E34000231A301D06F01CFE8046B448007838B110 +:10E350003868524690F8231AF01C06F011FE8146E8 +:10E36000A54200D92C46AF4880F8314048EA090060 +:10E37000C7E570B50C46A849097861B1A34D297865 +:10E380004A000146A8480CF08AF82878A6494200BD +:10E39000A6480CF084F8A148007860B1A04D214651 +:10E3A00028784200A2480CF07AF82878A049420068 +:10E3B000A0480CF074F8A0490120087070BD2DE948 +:10E3C000FF4F83B000249D48109F8DF808408DF8C2 +:10E3D0000440DFF83C8244600470D8F80000DFF8A5 +:10E3E0002892DFF85CB290F80C0A25462646C00752 +:10E3F000A9F1060910D003200AF0DFF802AADBF821 +:10E4000000100398FFF7DAFC044611208DF8040091 +:10E4100003200AF0EDF801E089F80050D8F8000078 +:10E42000DFF820A290F8320AC10701D1800717D582 +:10E43000B4B98548007898B99DF8080001280FD034 +:10E4400003200AF0BAF801ABDAF80020DBF800107C +:10E450000398FFF783FD044603200AF0C9F801E0A2 +:10E4600089F80150F4BB03200AF0A7F89DF80800D2 +:10E470000090764BDAF80020DBF800100398F7F7ED +:10E4800089F903200AF0B4F8D8F80000DFF8C0B129 +:10E4900090F80C0A800713D59DF8080001280FD0CA +:10E4A0009BF8001011B99BF8010048B16949DAF8EE +:10E4B000000000F089F8044630208DF8040001E0E7 +:10E4C00089F80250D8F8000090F80C0A40071DD5D2 +:10E4D0005148524900780978084317D0B4B95E48CA +:10E4E000007800E016E088B99BF8001011B99BF89D +:10E4F000010058B1574A5949DAF80000FFF7E1FE28 +:10E50000044632208DF80400012603E089F8045007 +:10E5100089F803505249012C06D1D8F8000090F830 +:10E520008F0C08B1088003E0088808B1401EF9E7A5 +:10E530000CF010F94B4908700CF01CF901464A48E0 +:10E5400001702CB32EB13D70DDE90401FFF711FF1E +:10E550001BE040F23C6145480CF020F80120374AAE +:10E5600038709DF804001070506840F00200506050 +:10E57000D8F8001091F80032DB0703D191F8BA10F7 +:10E58000C90702D040F008005060012007B0B9E48C +:10E590003D700078FAE729490020486008701A4960 +:10E5A000891F08608880704710B50446002008E085 +:10E5B00034F91230002B00DA5B428B4201DD401C43 +:10E5C000C0B2521EF4D210BD2DE9F05F8A46104948 +:10E5D000834600200E682649024696F81CEA097810 +:10E5E000B6F918CAB6F91A7A0346002967D10C4859 +:10E5F00000240578054890F800904FE004FB05F0F2 +:10E600000BEB4008002046E09E2601202407100066 +:10E61000A00710003A07100023071000220710007F +:10E620002507100038570120F87601206C0B0120D7 +:10E6300022770120960B0120DF07100068061000EA +:10E64000580710004C07100038071000501E10002B +:10E65000945A1000820C012031071000580C012040 +:10E660001C071000B2061000EB061000440D01203C +:10E670002905100038F91010002900DA4942B94282 +:10E6800008DD3AF91010002900DA4942614501DA43 +:10E690005B1C9BB2401CA842ECDB641C4C45ADDB10 +:10E6A000FF2B00D9FF23DCB2744500D9012296F874 +:10E6B0001D1A044806F064FC034981F83040BDE8A7 +:10E6C000F09F00009A260120385701202DE9FF4FC6 +:10E6D00089B0002083460490039002909C488A46AB +:10E6E0000068B0F8410207900B98897840680CF0F8 +:10E6F00065F800909AF8021016980CF067F80190EF +:10E700009AF802003CE09AF800402AE00998224674 +:10E7100000EBC8000021D0E9005601200BF075FE87 +:10E7200005400E4035431BD0009830F9145007982F +:10E73000854215DD0198005DCF287ED018B117996C +:10E74000884200D000250398AB4404FB05000390E9 +:10E75000029808FB050002900498401C80B20490C7 +:10E76000641C9AF80100A042D0DA7A49009809782E +:10E7700000EB4100009001982830019008F1010061 +:10E780009AF8031080464145BDDA714800240268BA +:10E7900002981746918EC317A1FB002504FB005079 +:10E7A00001FB03054FF6FF71A2FB010605FB0161AA +:10E7B00002FB041197F831203037521E8BFB0223E5 +:10E7C0000BF049FE47F6FF7280184FF6FF7841F1D3 +:10E7D0000001424600230BF03EFE0546039978886F +:10E7E000CB17A0FB012604FB016100FB031340468D +:10E7F000A2FB004603FB0060002102FB01013A7806 +:10E800002046521E8BFB02230BF025FE47F6FF72BB +:10E81000801841F10001424600230BF01CFE0B9AC8 +:10E82000C2F81CB00B9A049911850C9948600C9998 +:10E830000D600DB0BDE8F08FFFE74FF000094F46C7 +:10E840004FF0FF3608EB0600C1B2059016980BF0AA +:10E85000BDFF06900598C1B20B9840680BF0AEFF63 +:10E860004FF0FF31069A6318D25C7AB1CF2A0DD0EF +:10E87000DDF85CC0624503D130F813203A4497B20A +:10E8800030F8133003EB09021FFA82F9491C49B230 +:10E890000129E7DD761C76B2012ED3DD002F3FF48F +:10E8A00052AF6F4397FBF9F54DE710B52849426821 +:10E8B00000240968002A01DA446003E04B8E9A4282 +:10E8C00000DD43600268002A01DA046010BD898E11 +:10E8D0008A42FBDD016010BD7FB50E4608991446E3 +:10E8E000CDE90031FF2502AB3146FFF7EFFE1A48B4 +:10E8F0001749007830B1086890F8F303000701D594 +:10E90000042513E094F84000032802D0012807D022 +:10E910000CE0086890F8F303C00707D0002505E075 +:10E92000086890F8F303400700D50225294602A89D +:10E9300001F0D2FE02A8FFF7B8FF0398E081029829 +:10E94000A08194F82400C00601D4E06860617FBD16 +:10E95000A007100025071000E80610002DE9F74F6A +:10E960000F46FD4988B0DFF8ECA31EC98DE81E00F4 +:10E97000002210F0FF010492059289466B4605D1F2 +:10E9800003F82120491C49B20429F9DBF34C24780F +:10E99000641EA14507D1002103EB8104491C49B243 +:10E9A000A2700429F8DBC0F30720B0F1000806D1FB +:10E9B00003EB8001401C40B24A700428F8DBE849B0 +:10E9C0000978491E884507D1002003EB8001401CCF +:10E9D00040B2CA700428F8DB0024684600EB8400CB +:10E9E000027809EB0201427861F3070608EB0201A5 +:10E9F000827861F31746C07809EB0201C9B240443E +:10EA0000C0B261F30F2660F31F668B4646F30745DD +:10EA1000069015E0E9B278680BF0D0FE71B204AB55 +:10EA20000AE030F91120002A04DD33F814C06244F2 +:10EA300023F81420491C49B28B45F2DA6D1C6DB2E3 +:10EA40000698A842E6DA641C64B2042CC5DB0020F8 +:10EA500004AD35F91010514500DD8A46401C40B226 +:10EA60000428F6DB0A98012818D0A7F846A0B9F1C7 +:10EA7000000F0CD0B9490978491E894507D0B8F173 +:10EA8000000F04D0B6490978491E884503D1B88CD7 +:10EA900040F48060B8840BB0BDE8F08FB14800212D +:10EAA000046897F8400094F8F432012803D194F8F0 +:10EAB000F602181AC3B2002035F91020D61702EB5F +:10EAC0009672B3EBA20F01DA491CC9B2401CC0B266 +:10EAD0000428F1D3A44894F8F7220078012807D03D +:10EAE0000020101A8842D6DCB88C40F40070D1E7C0 +:10EAF00094F80303F5E72DE9F84381469B48174650 +:10EB0000884601789A4E974D089A1C4609B9407874 +:10EB1000C0B1296891F8B20183079548007801D502 +:10EB2000012807D191F8B31109070BD5012A09D1A2 +:10EB3000012807D123463A4641464846F6F72DFCC0 +:10EB4000002844D08B4B3A464146484601F0DCFA57 +:10EB500000283CD094F84000032810D12968E08CAC +:10EB600091F8C01288420AD93078012807D00420D1 +:10EB700084F840008048017941F040010171386813 +:10EB8000C4F836002868B0F8C90238B1E08FADF893 +:10EB90000000002221460098FFF7E0FE2246394699 +:10EBA000744800F0E3FC75492046FDF7BBFE39468A +:10EBB000704801F043FA4B46224639466D48CDF87D +:10EBC0000080FFF789FE2046FDF7E7FF0120BDE842 +:10EBD000F8832DE9F0410D461F461646044668218C +:10EBE0000BF0FEFC002084F840006548006860607F +:10EBF000A06006EB450084F8425030F8B41F6185F0 +:10EC00000088E08406EB85000068C4F83A005D489F +:10EC1000816921600121A940394201D0406A206008 +:10EC2000BDE8F08170B5574C00EB4305049E00EB46 +:10EC3000830386B18E69A660CE8C668009686161A7 +:10EC4000B5F8B410A1801968E16090F80E01207049 +:10EC50001068206170BDA6688E616688CE84666982 +:10EC60000E60A188A5F8B410E1681960217880F8D9 +:10EC70000E112069106070BD2DE9FF4F81B00C4668 +:10EC800098469978109F0E9D0BF0A0FD814698F84C +:10EC9000021020460BF08CFD009098F80210786866 +:10ECA0000BF08CFD064638484FF0000AC7F818A054 +:10ECB0000068286098F8020042E098F800402FE0D1 +:10ECC0000098015D0398814228D136F914100F98FD +:10ECD000814220DD039809F804002978204606F0D7 +:10ECE000C1F828706978204606F0C0F86870A978E5 +:10ECF000584606F0B7F8A870E978584606F0B6F816 +:10ED0000E8700AF101001FFA80FA36F91410B869A8 +:10ED10000844B86102E0002009F80400641CE4B271 +:10ED200098F80100A042CBD2009809F128092830B8 +:10ED300000900A48007806EB40060BF10100C0B2D3 +:10ED400098F8031083465945B7D2A7F826A005B016 +:10ED5000A2E600000080FFFFB0A701002507100019 +:10ED600024071000A007100031071000945A10006B +:10ED70001805100070471000385701201E27012089 +:10ED80004C071000700610001AA801002DE9FF4F73 +:10ED900081B090460E9E8B4606EB880096F80EA139 +:10EDA000DDF8409000681C4630600123314658462B +:10EDB00001F0C5FA019858451CD0A57817E02946FE +:10EDC00001980BF003FD0746294658460BF0FEFC60 +:10EDD0000246207806E03B5C434501D1115C395482 +:10EDE000401CC0B261788142F5D26D1CEDB2E07872 +:10EDF000A842E4D296F80E1100240123514512D006 +:10EE0000119878B10AF1010007E0D9F8002003FA5F +:10EE100000F10A43401CC9F8002096F80E11C0B258 +:10EE20008142F2D20124009343464A4630460F996C +:10EE3000FFF7F8FE20468AE710B5FE4AFE4C13683D +:10EE4000647893F8BF224CB191F82410090702D5D9 +:10EE500093F8C31201E093F8C2120A44904201D918 +:10EE6000012010BD002010BD2DE9F04389B01C46E3 +:10EE700016468846814601F02CFDD4E9180150342D +:10EE8000CDE9000194E80F00503C01F098FCA0850A +:10EE900000208DF81400ADF81800ADF81C0002AD8C +:10EEA00007AA06A905A885E80700D4E91801503487 +:10EEB000CDE9000194E80F00503C01F0BAFCBDF828 +:10EEC0001800E085BDF81C102186DC4F9DF8141059 +:10EED00084F84910A7F88000208EA7F8820094F8E3 +:10EEE0004900D44DC0F1FF0087F88400E08C3881E0 +:10EEF0002968E08C4FF0010C91F8C822904254D858 +:10EF0000CF4A032084F8400012780020012A15D04F +:10EF100091F88022930702D45207002A00DA0120D8 +:10EF2000C54BB1F8C4225B780BB1B1F8C622A38DF2 +:10EF3000934208D2C34A127822B104E091F8012228 +:10EF40009206EAE70020A7F86D30628D032A00D20E +:10EF50000020A28C92051DD4E0B191F88102000638 +:10EF60000FD502F063FA2868B0F9410200900190D1 +:10EF7000B5480378B5480278B5480168304602F0D4 +:10EF80007EFA09B02346324641464846BDE8F04382 +:10EF900002F070BD2346324641464846CDF800C0D7 +:10EFA000FFF7A9FD09B0BDE8F083042084F8400014 +:10EFB000387940F040003871ECE7A648C07858B185 +:10EFC0009C48A54A0068126890F8FD12914205D24B +:10EFD00090F8E602800701D50020704701207047B5 +:10EFE00091F82410934ACB079C491268097806D0FF +:10EFF00011B192F8EE1205E092F8EF1202E059B169 +:10F0000092F8EC128C4B5B7813B192F8F022114419 +:10F01000884204D90120704792F8ED12F2E70020EF +:10F0200070472DE9F04188B0012516460F4680460D +:10F0300083F8405003F12C0401F04BFCD4E90D019E +:10F040002434CDE9000194E80F00243C01F0B7FB23 +:10F0500024F8340B00208DF81400ADF81800ADF83A +:10F060001C000DF1080C07AA06A905A88CE80700EA +:10F0700074E80401CDE9000194E80F00243C01F09C +:10F08000D8FBBDF818006080BDF81C10A1809DF869 +:10F09000141004F81D1F694921F8800F34F8190C69 +:10F0A000488014F84909C0F1FF0008716148006800 +:10F0B00090F8E602C00608D508B023463246394625 +:10F0C0004046BDE8F04102F0D5BC23463246394601 +:10F0D00040460095FFF70FFD08B0A1E52DE9F04F80 +:10F0E000E9B000206490834668905D485D49B0F9BE +:10F0F00000006790B1F90010CDE9650101215A487F +:10F1000003F016FA58480121083003F011FA564866 +:10F110000221001D03F00CFA0221544803F0BEF94D +:10F120000421534803F0BAF94F4F4FF466741C3F63 +:10F130002146F8690BF032FA2146786A0BF02EFA74 +:10F140004C48B0F900004100386A0BF027FA4048FB +:10F150000068F6F7B9F84FF0000947488DF81E919E +:10F160004C460068049001234A4604A9B86901F09E +:10F17000E6F8629401240DF5AD702646639001E136 +:10F1800004A800EB840804AA214648A8629BFFF764 +:10F1900020FD48AB42462146489801F018F8234626 +:10F1A00062AA48A904A80096FFF73CFD0DF5AF70D0 +:10F1B00000F01EFF78B1BDF8440140F00100ADF849 +:10F1C000440148A801F08BF828B12C482549008853 +:10F1D0000880234908801B48007838B1BDF84401F5 +:10F1E00010F0060F02D1264800684990404600F012 +:10F1F00011FF28B1BDF8440140F00800ADF844010A +:10F20000BDF95211679881424CDDBDF8460148A90D +:10F21000FFF712FEC0B348A800901A482146639A2F +:10F22000B0F90030B86900F0DBF948AB424621463E +:10F2300048982AE0A0071000D8071000385701208E +:10F2400018051000E806100025071000240710001C +:10F250004C071000945A1000C4061000310710002B +:10F26000D6061000D80610008C0610009C06100070 +:10F27000A80610003A071000CC061000E6061000A1 +:10F2800050071000DA06100004E0FFF7EDFD012042 +:10F2900064906AE0234662AA48A904A8CDF80090C9 +:10F2A000FFF7C0FCF348BDF95211B0F900008142EC +:10F2B0005BDDFFF782FE88B3629806FA04F505422B +:10F2C00045D1ED48006890F88102000728D5E9484B +:10F2D000DFF8A8C3D7F824A0B0F90000BCF900C03B +:10F2E000B969224648AB844501DB484617E00DF179 +:10F2F0000C0CCDF800C0CDE9010343465046FFF7A2 +:10F30000BBFC6299304629436291BDF84611CDF8A5 +:10F3100020A121B10399C8F80010E6E725E020BB41 +:10F32000D548006890F8E602C00610D462980542FD +:10F330000DD004A901AB62AA48A8009183E845005A +:10F340002246639B796AB869FFF720FDC0B9BDF812 +:10F35000460148A9FFF744FE38B148AB4246214672 +:10F360004898FFF75EFE4FF0010B629906FA04F031 +:10F370000843C349629066980880C249659808802E +:10F38000641CE4B29DF81E01A042BFF4F9AEBE4970 +:10F390004871BE4968980870BD4964980870BD49B5 +:10F3A00081F800B000F03DFDBB48007858B1BB4883 +:10F3B0000078012807D1B048006890F80102C00623 +:10F3C00001D5FDF7CBFC0221B54803F07FF80421FD +:10F3D000B44803F07BF80121B34803F007F9B248C1 +:10F3E0000121001D03F002F9AF4801210C3003F0A8 +:10F3F000FDF8AD480221083003F0F8F869B0BDE827 +:10F40000F08F2DE9F043A848DFB000260121001D50 +:10F4100003F08EF8A4480221083003F089F8022195 +:10F420009F4803F03BF804219E4803F037F89E4CB8 +:10F430004FF46671183CE0690BF0B0F89B48B0F9E6 +:10F4400000004100206A0BF0A9F8B14698488DF8F9 +:10F450000E914D460068009001234A466946A06916 +:10F4600000F06DFF012427463CE0684600EB84086D +:10F470002B466A46214644A8FFF7ABFB44AB424605 +:10F480002146449800F0A3FE0DF5A77000F0B0FDF2 +:10F4900028B1BDF8340140F00100ADF83401404618 +:10F4A00000F0B8FD28B1BDF8340140F00800ADF817 +:10F4B00034017449BDF94201B1F9001088420CDDF4 +:10F4C000BDF8360144A9FFF7B7FC30B144AB424662 +:10F4D00021464498FFF7C8FC012607FA04F00543CB +:10F4E000641CE4B29DF80E01A042BED26649487188 +:10F4F00067486649067081F800906649684881F857 +:10F500000090022102F0E2FF0421664802F0DEFFD3 +:10F510000121654803F06AF863480121001D03F0EA +:10F5200065F861480221083003F060F85FB03AE501 +:10F5300056490020087056490870564908707047AF +:10F54000F6E759490020183908628861C8615449B2 +:10F550000860544908604D4908704D4908704D498C +:10F5600008707047A82153480BF03AB82DE9F74FBF +:10F570000D464D49183948780F2801D2401C487073 +:10F5800000F0FF0A4C4982F841A001EB8A0029688B +:10F590000160A97849480BF019F98146A87819E06B +:10F5A00000992C7801EBC80B0DE0DBE900672246DF +:10F5B000012000210AF029FF06400F403E4301D000 +:10F5C00009F804A0641C6878A042EEDA09F1280961 +:10F5D00008F10100E97880464145E1DABDE8FE8F97 +:10F5E0002DE9FF5F9B4614469178DDF838800BF0DB +:10F5F000DFF80746A178D8F804000BF0DFF80646DC +:10F600000025FFF7DAFC002832D02D49B8F9320086 +:10F61000B1F9001088422BDC2A48A17894F80390B5 +:10F6200090F800A016E0207862780CE017F800C08F +:10F63000019B9C4505D136F910C0DC4501DD6D1CF0 +:10F64000ADB2401CC0B28242F0D2491C06EB4A0661 +:10F65000C9B228378945E6D241462846FFF7C0FCA3 +:10F66000002805D0B8F8240040F40071A8F8241050 +:10F67000BDE8FF9FDA061000A0071000DE061000AC +:10F68000D8061000D6061000385701202E071000AB +:10F690002F07100030071000945A100018051000B2 +:10F6A0009C061000A8061000880610003A071000FB +:10F6B000CC06100070471000B62A01201E2701203A +:10F6C000D006100025071000F84800787047F84968 +:10F6D000087070472DE9FC430022DFF8D8830092C0 +:10F6E000019298F800406F4600230BE002FB0436BD +:10F6F00037F9125030F91660B54201DA27F8126076 +:10F700005B1C1BB2A342F1DB521C12B2022AEBDBE0 +:10F71000DFF8A493002201AE99F8004000230BE02B +:10F7200002FB043C36F9125031F91CC0654501DA80 +:10F7300026F812C05B1C1BB24D46A342F0DB521CE4 +:10F7400012B2022AEADB0023B94600220FE003FBD3 +:10F7500004244FF47A7C30F91470521C07FB0CF728 +:10F7600039F913C012B297FBFCF720F8147098F81F +:10F770000040A242EBDB5B1C1BB2022BE5DB00224C +:10F7800000200EE002FB03034FF47A7731F91340B7 +:10F790007C4336F91270401C94FBF7F421F81340B7 +:10F7A00000B22B789842EDDB521C12B2022AE7DB42 +:10F7B000BDE8FC832DE9F047DFF8FC8282468946EC +:10F7C00098F8002000252C4631F91200BB492F463D +:10F7D0002E460B6809EB8202B3F8D013B3F8D2338C +:10F7E000884203DD32F902CC9C454ADC984203DDB5 +:10F7F00032F9020C884244DC49465046FFF76AFF62 +:10F80000AC490020097814E03AF91020002A09DDFB +:10F810000B183AF91320002A04DD0CB97F1CFFB243 +:10F82000012405E00CB16D1CEDB2032D00D90024BC +:10F83000401C8842E8DB002198F8003001200A468D +:10F840005C1E15E039F91050002D0ADD03EB000CA9 +:10F8500039F91C50002D04DD09B9761CF6B20121DE +:10F8600005E009B1521CD2B2012A00D90021401C86 +:10F87000A042E7DB012F01D8012E02D90120BDE80B +:10F88000F0870020FBE72DE9FF4F8C480024DDF8CE +:10F8900044C001682646254691F8A32391F8A43375 +:10F8A000B1F8B97391F8BB93B1F9CA832046A24667 +:10F8B0009A4200D81A469346814A12781AB1B1F892 +:10F8C000BC7391F8BE93BCF1010F05D1B1F8C173BF +:10F8D00091F8C393B1F9CC837A4A0023B2F900E0DE +:10F8E0001FE0009AB1F8C4C332F91320CCF1000C28 +:10F8F000624507DA002A01DB944601E0C2F1000C00 +:10F90000664436B20FFA87FC624501DD641CE4B23E +:10F910005A4501DD15442DB2424501DD4FF0010A83 +:10F920005B1C7345DDDBBAF1000F45D0614A664BC5 +:10F930004FF0000C92F800E0674603EB4E0B9A463E +:10F94000624611E03AF91280B8F1000F0BDD3BF985 +:10F950001230002B07DDB8EB030300D55B421BB26E +:10F960009C4500DA9C46521C7245EBDB564B524AD2 +:10F9700098339A4692F800E0002203EB4E0B11E018 +:10F980003AF91280B8F1000F0BDD3BF91230002B71 +:10F9900007DDB8EB030300D55B421BB29F4200DAE0 +:10F9A0001F46521C7245EBDBB1F8C623BA4203DD99 +:10F9B000624501DD40F4C070B1F9BF23AA4201DD08 +:10F9C00040F00800B1F9C813B14201DD40F0040075 +:10F9D0004C4501D940F480400D9A0F99914201DACB +:10F9E00040F010000E9A914201DA40F02000039A94 +:10F9F0000199914202D80299914201D940F0400008 +:10FA00001099012901D040F4007004B0BDE8F08FD6 +:10FA10002DE9F74F96B00C464C2101A80AF0E0FD05 +:10FA2000264AA646106890F8311090F830300B4402 +:10FA30001B1BDDB2002314930093A14207D190F861 +:10FA4000A37301201490601E00F0FF0E01E090F8F7 +:10FA5000A4731E48007810B116480078009000206A +:10FA60000DF1040B5FE0154900232BF810300968F5 +:10FA700091F83110A14207D1009A13498618169ABD +:10FA8000A94602EB460208E00F49169E00FB04F26D +:10FA9000983106EB42024FF0010905EB000C21F80A +:10FAA000103021F81C30149E39E000001848100076 +:10FAB000980610002507100024071000A00710006A +:10FAC000B30610003A071000F62A0120390710008B +:10FAD000B2F90030B3F1000A01DACAF10003DB1B0E +:10FAE000002B0CDD3BF8108008EB0A032BF81030DC +:10FAF00031F81030B2F80080434421F81030B2F9E8 +:10FB00000030A3EB0708B8F1000F04DD31F81C80CA +:10FB1000434421F81C30761C02EB4902F6B27645CC +:10FB2000D6D3401CC0B2A8429DD32946584606F001 +:10FB300056FA0446FE48FF492A46007800900868B5 +:10FB400001A990F8A533189806F031FA204619B0AB +:10FB50005CE72DE9F04F93B00F4604461E4615466C +:10FB60004C2168460AF03CFD4FF0000A50464FF029 +:10FB7000CF0EEC464CE034F91010002939DD4FF07F +:10FB8000010AD1460CF810A0411C0EE034F91030E7 +:10FB900034F9112062B1B3EB020809D5D21AB2428E +:10FBA00002DD0CF810E003E0491CC9B2B942EDD304 +:10FBB0000CEB400B411E8BF801900FE034F9103034 +:10FBC00034F9112068B162B1B3EB020809D5D21A39 +:10FBD000B24202DD8BF801E01FE0491E49B2002964 +:10FBE000ECDAB9F1CF0F18D01CF81010CF2918D0CB +:10FBF00005E000210CEB40020CF8101051700CEBEA +:10FC000040011CF81020497811432954401CC0B20F +:10FC1000B842B0D3504613B0F8E61CF81010CF2904 +:10FC200002D005F80090F1E705F800E0EEE7F0B546 +:10FC3000064600200446034629E0F55C012D02D06B +:10FC4000012C19D021E05CB900EB4004135530B110 +:10FC5000A51815F8027C5D1EAF4200DA1555012487 +:10FC60004D1EAB4211D1012C0FD100EB40051544C4 +:10FC7000401C6B70C0B208E000EB40041444401C10 +:10FC800063700024C0B20F2803D85B1CDBB28B4228 +:10FC9000D3D3F0BD2DE9FF4FA6480C4600250068E0 +:10FCA00081B0A946818E90F831302F46B1FBF3FB2D +:10FCB000418E90F830002E46B1FBF0FA54E000205F +:10FCC0004CE000233FE003EB830101EBC30104EBB5 +:10FCD000C101B1F824C02CF4006CA1F824C006EBDB +:10FCE000460CCDF800C012F80CC0B1F90EE00CFBC8 +:10FCF0000AFCF44525DCDDF800C094449CF801C002 +:10FD00000CFB0AFCF4451CDB00EB400C9444CDF8E2 +:10FD100000C09CF82D80B1F90CE008FB0BF8F04511 +:10FD20000FDCDDF800C09CF82EC00CFB0BFCF4458A +:10FD300007DB6F1C81F8487009F10101012701F010 +:10FD4000FF095B1CDBB294F818169942BBD8012F4F +:10FD500002D100276D1CEDB2401CC0B20199497858 +:10FD60008142AED8761CF6B201980078B042A6D88F +:10FD70000025B9F1010F51D994F818064AE0002680 +:10FD8000411E4BB200EB800101EBC00104EBC1014D +:10FD90003BE091F84820AAB303EB830707EBC307C6 +:10FDA00004EBC70797F84870BA422CD183422ED093 +:10FDB00003EB830202EBC30204EBC202CF89B2F869 +:10FDC0000EC0B2F80C80A7EB0C070FFA87FC8F89E6 +:10FDD0000CFB0CFCA7EB08073FB207FB07C7DDF8DD +:10FDE00010C0674513D28D8C45F400658D84918CCD +:10FDF00041F400619184C2B2D9B2204601F0E9F920 +:10FE0000012505E0FFE75B1E5BB2002BC1DA0EB1F6 +:10FE100094F91806401E40B20028B0DC284605B010 +:10FE2000F4E52DE9F04F8BB000200590FCF733FF8F +:10FE30000A9040484FF000080468B4F8A973B4F879 +:10FE4000AD5394F8B11306913B49B4F8A763097810 +:10FE500041B1B4F8B373B4F8B55394F8B213069142 +:10FE6000B4F8B763DFF8D4A09AF80010012906D1DE +:10FE7000B4F8AB1339448FB2B4F8AF130D448146D4 +:10FE800094F8A203000652D50A9890F818060128A3 +:10FE900002D84FF400500BE094F8A613884202D920 +:10FEA0004FF4806004E026480078012801D1C002A8 +:10FEB000804622485A219E3007900AF06FFB94F842 +:10FEC0003010204C1D4A921C2068FFF7A1FD83468C +:10FED000D9F80000194A90F831102C3200922068AD +:10FEE000FFF796FD184982460246A1F19800FFF7F8 +:10FEF00061FC0446012806D1D9F8000090F8CE1321 +:10FF000090F8CF630D440AFB06F0642190FBF1F0FA +:10FF100083B2D9F80000094A90F83010783208927C +:10FF20000098FFF716FE0090D9F800000EE04AE0B6 +:10FF300098061000A0071000B30610001848100023 +:10FF4000290510004C0710008E2B012090F830106E +:10FF5000DDE90720FFF76BFE8DF814000BFB06F0C0 +:10FF6000642190FBF1F083B2D9F800001D4E089A8D +:10FF700090F83110B01CFFF7ECFD0146009806F137 +:10FF8000CB0201430091D9F8000090F83110089895 +:10FF9000FFF74DFE8DF815000099CDF800B0CDE9C2 +:10FFA0000314CDE901A702460F489DF81410069BE3 +:10FFB0000068FFF768FC50EA080406D000203070A3 +:10FFC0000A48A0F885400BB020E505FB05F305A81D +:10FFD000079A0A99FFF75EFE30700028F0D14FF4BF +:10FFE0008054EDE7184810004C07100038570120E6 +:10FFF000017859B1954A1278521E914206D0407844 +:020000021000EC +:1000000020B193490978491E884201D101207047E7 +:1000100000207047017829B18C4942780978491E3F +:100020008A4209D1817829B1C17889480078401E77 +:10003000814201D10120704700207047F0B5854E04 +:10004000002206EBC2030024C3E90044521CD2B2D2 +:10005000172AF6D38B782CE000EBC302D2E90072AA +:1000600057EA020423D055084FEA370417EB070E6E +:1000700042EB020C45EA0C05154344EA0E0406EB7C +:10008000C3023C43D2E9007C27434CEA050CC2E999 +:10009000007CD2E9027C27434CEA050CC2E9027CD1 +:1000A000D2E9047C27434CEA050CC2E9047C5B1CC2 +:1000B000DBB2CA789A42CFD20022654F09E006EB44 +:1000C000C203D3E9024500EBC203521CC3E9004559 +:1000D000D2B23B789A42F2D3087808B1401E087039 +:1000E0005A4A48781278521E904201DA401C4870F1 +:1000F000887808B1401E88703A78C878521E9042BD +:1001000001DA401CC870F0BD2DE9FF5F8B4697787F +:100110009146014607EB870201EBC201002001F185 +:1001200029081FE000252E4699F8004099F801A003 +:100130000DE018F804205A4507D12246012000217D +:100140000AF063F905430E430120641CE4B2A245A2 +:10015000EFD2039908F1280801EBC7017F1CC1E920 +:100160000056FFB299F80310B942DBD204B0BDE8E3 +:10017000F09F70B50E788D784C78C9789AB10EB131 +:10018000761EF6B2314A1278521E944201DA641C8D +:10019000E4B20DB16D1EEDB22D4A1278521E91429D +:1001A00001DA491CC9B205EB850200EBC20000224E +:1001B000293009E0334602E0C2545B1CDBB2A342A3 +:1001C000FAD96D1CEDB228308D42F3D970BD2DE9FE +:1001D000F04789469178DFF874A001EB810400EBC9 +:1001E000C4079AF800405868614300EB41060020BC +:1001F0009861194D03F13E0C947829371FE010786F +:1002000013E017F80080C8450DD136F91010D3F867 +:100210001880A9428844C3F8188004DD8CF80000D7 +:100220000D468CF80140401CC0B251788142E8D2A2 +:100230009AF80000641C06EB4006E4B22837D07838 +:10024000A042DCD25D86BDE8F087000025071000E3 +:1002500024071000104910000080FFFF2DE9F0472F +:10026000804627488F780C460078801E012F05D9DC +:10027000E178814202DA0020BDE8F087022F01D246 +:10028000022601E0E678C7B24FF000093946D8F8F7 +:1002900008000AF093FA05463946D8F804000AF037 +:1002A0008DFA01461748027815E0207863780AE055 +:1002B00035F910C031F91080C44502D04FF0010962 +:1002C00003E0401CC0B28342F2D27F1C05EB420522 +:1002D00001EB4201FFB2B742E7D94846CCE70849F3 +:1002E0000978491ECAB290F83F1009B1914205D170 +:1002F000818C41F002018184012070470020704709 +:10030000240710002507100030B5B0B1884214D082 +:1003100002D20A4601461046CC4B5A6802EB400214 +:1003200014788C4209D054788C4206D09C68235CA7 +:10033000022B02D25D1C2554D154084630BD2DE954 +:10034000FF4F087887B00F46FF282CD0C04983465E +:1003500078780978884201D2401C00E0084600F015 +:10036000FF09B878BB490090F8780978884201D233 +:10037000401C00E00846C0B202900020019009989D +:1003800010B197F80E010190B04C206800F15A01AD +:10039000C4E901015A210AF001F9214622462D2023 +:1003A000496893680AE04FF0000BD9465846CDF8EB +:1003B00000B0E1E701F8100000221A54401EC0B25C +:1003C000F8D20198401CC5B20590009800EB80015E +:1003D000079800EBC10600980496401C3FE0B04629 +:1003E0000BF101002836C4B235E03119086880B13C +:1003F000305D70B3CF282CD011F8011C002001B162 +:10040000084618F8041009B1FFF77EFF0A9949B9A8 +:1004100002E0E41CE4B21CE08F49096891F8811203 +:1004200009060CD508EB0401039111F8011C09B170 +:10043000FFF76AFF0399497809B1FFF765FF38B9FB +:100440002D2D03D228466D1CEDB201E0681EC0B20E +:100450003055641CE4B24C45C7D90AF10100029939 +:1004600000F0FF0A8A45BAD9284600F066F88246AD +:1004700005980022C0B2794B09E007EB80011C68A7 +:100480000C6007EB4001401CA1F8B420C0B25045FD +:10049000F3D3049EDDF8008029362FE05D4626E088 +:1004A0007059E8B3705D00B36849496811F81000ED +:1004B000705507EB400107EB800431F8B42F284654 +:1004C000521C0A80217804F0CDFC20706178284607 +:1004D00004F0CCFC6070A178404604F0C3FCA0702E +:1004E000E178404604F0C2FCE0706D1CEDB24D4571 +:1004F000D6D308F1010000F0FF082836029988459C +:10050000CCD3AAF10100C2B287F80E2109980028C5 +:1005100010D00198101A01280CD13B46099900E02F +:1005200005E007980BB0BDE8F04F00F051B8ED1CA6 +:10053000EDB2DAE70BB0BDE8F08F2DE9F05F82464F +:100540000026DFF808B12AE0DBF808108C5DDBF844 +:10055000041001EB460719E03819804610F8011C19 +:1005600010F8029C084600F066F80546484600F080 +:1005700062F8854202D2014628460D46DBF8041097 +:10058000641EE4B201F8105008F8025C012CE3D8B4 +:1005900003D1304600F04FF83870761CF6B256455D +:1005A000D2D300200146DBF804400DE004EB410209 +:1005B00013788B4203D11070401CC0B202E014F8D3 +:1005C00013301370491CC9B25145EFD3BDE8F09FF9 +:1005D000F0B503EB8204A77807EB870500EBC506AF +:1005E000E0782836B8420FD3207807E0351895F820 +:1005F00001C0944500D16970401CC0B26578854245 +:10060000F4D27F1CFFB2EBE703EB810025680560A5 +:1006100003EB420003EB410130F8B42FA1F8B42002 +:100620000E49096821600021018093F80E01401EE7 +:1006300083F80E01F0BD054AD2E9011201E011F87C +:100640001000135C002BFAD1704700009C061000CC +:100650002507100024071000A00710001AA80100A9 +:10066000F0B5B2F900400568AC4202DDB3F9001004 +:1006700030E002EB410434F9026CAE4204DA03EBE1 +:10068000410131F9021C25E0002634464F1E0CE0E2 +:1006900032F914C0AC4507DC02EB440CBCF902C0D3 +:1006A000AC4501DB26460C46641CBC42F0DB32F94B +:1006B000161003EB460433F91630B4F9024002EB8E +:1006C00046026D1AE41AB2F902206C43511A94FBE7 +:1006D000F1F119440160F0BD2DE9F04104461948DB +:1006E0000F00036803F2FF3293F8F81393F8F953FD +:1006F00002EB41061BD0022F1CD0032F1DD0042F6C +:100700001ED193F8FE03012902EB400C0CEB4107CC +:1007100004DD1346201D6246FFF7A2FF012D0FDD09 +:10072000204633463A462946BDE8F04198E793F81B +:10073000FA03E8E793F8FC03E5E793F8FD03E2E743 +:10074000BDE8F081A0071000002819DD43F2DC713C +:10075000884201DA5520704744F68921884201DA3F +:100760005620704746F6DC71884201DA5720704700 +:100770004DF6C971884201DA5820704759207047F8 +:100780004DF6C971C84202DA6FF05900704746F65B +:10079000DC71C84202DA6FF05800704744F68921D4 +:1007A000C84202DA6FF05700704743F2DC71C8426A +:1007B00002DA6FF0560070476FF0550070472DE970 +:1007C000F0411546DDE90668971B1C4663EB0802FD +:1007D000A7FB073C02FB07CC07FB02C2A0FB007C87 +:1007E00001FB00CC00FB01C04FEA800CB8004CEAD2 +:1007F000977C181842EB0C0104F0F0FAAD1944EBA9 +:1008000008042A1844EB01032D1A64EB01044FF489 +:100810007A71A5FB010704FB0171002605FB061197 +:1008200009F019FE4FF47A71D0EB010080B2BDE8F7 +:10083000F0812DE9F05F8146DDE90A8B0C46001856 +:1008400092466141B2EB08021D4663EB0B0316466C +:100850001F4600F037F90C9932460870A2FB0201DE +:1008600007FB061106FB07134946A1FB012604FB03 +:10087000096609FB0461890041EA927192008018BF +:10088000594104F0ABFA1AEB080445EB0B030A4696 +:10089000261843EB0201241A63EB0205304604F0EC +:1008A0009DFA49084FEA300080B24FF00A06B0FBCB +:1008B000F6F10D9801802046294604F08FFA490888 +:1008C0004FEA300080B2B0FBF6F10E980180BDE82F +:1008D000F09F2DE9FF4FBDB00024CDE93144CDE9B3 +:1008E0002F44CDE93744CDE93544CDE9334412688E +:1008F0002E92A346A2466B462EAAFFF705FC2EA910 +:100900006846FFF79BFB40989DF8BA10406809F0D5 +:1009100055FF39909DF8BB009DF8BA503A908DE094 +:100920009DF8B8409DF8B9003C943B907AE0684649 +:1009300000EBC5002246D0E900670120002109F044 +:1009400064FD06400F403E436AD0399830F91400E8 +:10095000002865DD642148434099954AB1F9321079 +:10096000126890FBF1F03A99938E491B491C594348 +:1009700092F83130568E5B1E91FBF3F13C9B92F85E +:100980003020E31A5B1C7343521E93FBF2F3A0FB6F +:10099000032C4FEAE07E0EFB03C6DF17DDE931C80A +:1009A0001BEB000B4AEB0E0A00FB076618EB020874 +:1009B0004CEB060CCDE931C8A2FB03C806FB038350 +:1009C00002FB0733DDE935871CEB070743EB080320 +:1009D000CDE93537A2FB017C06FB01C64FEAE17980 +:1009E00002FB0962DDE93736BE195A41CDE93726E7 +:1009F000A0FB01270EFB017600FB0960DDE92F3625 +:100A0000B6184341CDE92F36A2FB016700FB017008 +:100A100002FB0900DDE9332171185041CDE93301B2 +:100A20003B98641CA04282DA61486D1C006890F813 +:100A30003010399800EB410039903A98A842BFF63F +:100A40006FAFDDE93131DDE92F42A1FB020503FB88 +:100A5000025201FB04215A46534609F0FCFCDDE931 +:100A600037231B1A409862EB0102C0E91432DDE91A +:100A70003112A2FB020301FB023302FB01315A4691 +:100A8000534609F0E8FCDDE935231B1A409862EB78 +:100A90000102C0E91632DDE92F12A2FB020301FBBD +:100AA000023302FB01315A46534609F0D4FCDDE91A +:100AB00033231B1A409862EB0102C0E9183241B09F +:100AC000BDE8F08F2DE9F04116461F4604460D465D +:100AD00000F029F8401056EA070107D0002211461D +:100AE000921BB94110DA2C430AD0A0E654EA050063 +:100AF00006D000210846091BA84103DA2D2096E6FE +:100B0000002094E65A2092E654EA050106D000221D +:100B10001146121BA94104DA5A3088E66FF05900D9 +:100B200085E65A3883E62DE9F0414FF47A74A0FB4C +:100B3000045701FB0471002600FB0611284609F04A +:100B40008AFC1C4A821A71F1FF3205DB42F6A64389 +:100B500000221B1A8A4102DABDE8F041F4E50023C5 +:100B6000154D1A4635F91240E617041B71EB0604C1 +:100B700009DB05EB4204B4F90240E617241A8E4162 +:100B800001DB13464622521C452AEBD303EB8302BA +:100B900035F9131005EB4303553A401AB3F9023007 +:100BA00000EB8000A3EB010190FBF1F010443EE666 +:100BB000A00710005AD3FFFFC0A701002DE9F74F8F +:100BC00098B0FE4C2020179023781546581EC6B2C8 +:100BD00000224FF0210B10460BE0F94931F81010BC +:100BE00029B1864200DDC6B2824200DAC2B2401CA0 +:100BF00000B29842F1DBF3484FF000094F4601681C +:100C00004B4601F646210C46002011F80080401C9E +:100C100000B2C1440328F8DB5B1C1BB2C91C032BC8 +:100C2000F2DB23460021002013F800C0401C00B274 +:100C300067440228F8DB491C09B2DB1C0329F2DBFC +:100C4000521CD0B2761E1690F6B22C21684609F0DE +:100C5000C7FC2C210BA809F0C3FC9BE0701EC1B29D +:100C6000199809F0ABFD824617998EE0D64A00200C +:100C70001278531E99420AEB410333F902CD34D165 +:100C8000AC4503DD94F800800CFB0800B3F902C00A +:100C9000AC4503DD94F801800CFB080003EB420334 +:100CA000B3F900C0AC4503DD94F803800CFB0800E9 +:100CB000B3F902C0AC4503DD94F804800CFB0800D6 +:100CC00003EB4202B2F90030AB4203DD94F806C0F8 +:100CD00003FB0C00B2F90220AA4202DDE37902FB19 +:100CE000030090FBF7F00BAA4BE0AC4503DD94F852 +:100CF00000800CFB0800B3F902C0AC4503DD94F89A +:100D000001800CFB0800B3F904C0AC4503DD94F886 +:100D100002800CFB080003EB4203B3F900C0AC45B2 +:100D200003DD94F803800CFB0800B3F902C0AC4566 +:100D300003DD94F804800CFB0800B3F904C0AC4553 +:100D400003DD94F805800CFB080003EB4202B2F9C6 +:100D50000030AB4203DD94F806C003FB0C00B2F98F +:100D60000230AB4203DD94F807C003FB0C00B2F97C +:100D70000420AA4202DD237A02FB030090FBF9F073 +:100D80006A46491C22F81600C9B259457FF66EAF73 +:100D9000761CF6B2169886427FF660AF0024DFF824 +:100DA00020826D460BAE854F12E038F8140068B112 +:100DB000E1B2189809F010FD36F9141030F9402FFF +:100DC000514335F9142091FBF2F14180641C24B2A7 +:100DD00038788442E9DB1BB0BDE8F08F2DE9FF5F76 +:100DE0000024DDF838908B4698461546274626465F +:100DF00009F0FF01009809F0E1FC30F91800A84261 +:100E00002DDDA9F1010509F1010A24E0002D1FDB08 +:100E10006A48007885421BDAE9B2009809F0CEFCF6 +:100E2000694AA8F101018B1C92F800900DE000299D +:100E300008DB494506DA3BF9142030F911C01644A5 +:100E40000CFB0277641CE4B2491C9942EFDD01E01F +:100E5000E41CE4B26D1C5545D8DD0EB101E0074637 +:100E6000012697FBF6F004B000B2BDE8F09F2DE933 +:100E7000FF4F83B01446DDE910120F7888784D7863 +:100E8000CE7832B18046B4F912005FEA000A7DD014 +:100E90009EE007B17F1EFFB200B1401EDFF828B10F +:100EA00000F0FF089BF80000411E8D4201DA6D1C26 +:100EB00000E00D464148EDB20078411E8E4201DA55 +:100EC000761C00E00E46F6B2CFB94046C14612E0AD +:100ED0000146039809F080FC82463B46CDF800901D +:100EE0002146069A0498FFF779FF2AF8170009F1BE +:100EF0000100C0B28146B145EAD97F1CFFB29BF820 +:100F00000000401E854219D14046C14612E001460C +:100F1000039809F061FC82462B46CDF800902146EB +:100F2000069A0498FFF75AFF2AF8150009F1010004 +:100F3000C0B28146B145EAD96D1EEDB2B8F10000EC +:100F40001AD10146039809F047FC8246B9460DE0E4 +:100F50004B46CDF800802146069A0498FFF73EFFE5 +:100F60002AF8190009F1010000F0FF09A945EFD99D +:100F700008F1010000F0FF0810480078401E86428A +:100F800081D13146039809F027FC00E01EE082463B +:100F9000B9460CE0034600962146069A0498FFF7EE +:100FA0001DFF2AF8190009F1010000F0FF09484669 +:100FB000A945EFD9761EF6B265E7000024071000B8 +:100FC00034260120A0071000250710004FF0010A69 +:100FD0004046C14664E00146039809F0FDFB0190DC +:100FE000A9F10100C1B2049809F0E8FB009049465C +:100FF000049809F0E3FB834638464BE03BF91010B8 +:10100000069A914241DD0099B4F900C001EB40011C +:10101000002231F9023DB4F9068003FB0C22B1F93C +:101020000230B4F902C003FB0C22B1F90430B4F968 +:1010300004C003FB0C23284A127801EB4201B1F9EA +:1010400000C00CFB0833B1F902C0B4F908800CFBF6 +:101050000833B1F904C0B4F90A8001EB42010CFB7A +:101060000833B1F90020B4F90CC002FB0C32B1F91D +:101070000230B4F90EC0B1F9041003FB0C22B4F92C +:10108000103001FB032191FBFAF1019A22F81010B4 +:10109000401CC0B2A842B1D909F10100C0B28146DA +:1010A000B14598D907B097E63EB502248DF80840BF +:1010B0008DF80A40094C246814F8305FED1E8DF855 +:1010C000095064780125E41E8DF80B4002ACCDE98F +:1010D0000045FFF7CCFE3EBD25071000A00710001D +:1010E0002DE9FF4FAFB092464FF46671FE4809F00C +:1010F00055FA01203EE0B821684609F071FA3298AD +:1011000008F0FF0100EB88006B4600682E902EAAC5 +:101110003098FEF7F9FF58B32EA96846FEF78EFF08 +:101120009DF8BA5020E0E9B2EF4809F04FFB814644 +:1011300068469DF8B84000EBC50B10E0DBE900679E +:1011400022460120002109F060F906400F403E438D +:1011500004D019F80400401C09F80400641C9DF830 +:10116000B900A042EADA6D1C9DF8BB00A842DADAA9 +:1011700008F101008046329890F80E114145BADA24 +:101180009AF802401EE0E1B2309809F01FFB0646D3 +:10119000E1B22F9809F01AFB0546E1B2D24809F0F6 +:1011A00015FB02469AF80010CF2006E0535C012B95 +:1011B00002D9735C03B96854491C9AF801308B4218 +:1011C000F4DA641C9AF80300A042DCDA33B0BDE81C +:1011D000F08F2DE9F0470446914260D007D901EB2A +:1011E0000200A0EB0201CAB2A0EB0200C1B201EB07 +:1011F000810000EBC10004EBC00102EB820000EBB8 +:10120000C20004EBC003B1F93250B3F93200994681 +:10121000854200DA4886C88CDD8C2844C884088D55 +:101220001D8D28440885488D5D8D28444885886932 +:101230009D6928448861DD69CE69CF68D9F80C3092 +:101240004FEA274C4FEA23480CFB06FC05FB08CC71 +:1012500070199CFBF0FC6CF31F470FFA87FC0CFB2A +:1012600006FC1BB205FB03C393FBF0F363F30F070C +:10127000CF60C86194F81806411E91420AD000EB75 +:10128000800101EBC00004EBC001484668226839C8 +:1012900009F04AF994F81806401E84F81806BDE8CB +:1012A000F08770B500231A46904C914E16E090F8E6 +:1012B000300002FB0061002008E028B10D1815F88D +:1012C000015C6D1C0D5400E00B70401C256895F806 +:1012D00030508542F1DC5B1CDBB2521C206890F878 +:1012E00031109142E3DC00231A4616E090F83000FA +:1012F000804902FB00110BE0256895F830506D1E07 +:10130000854204D00D186D786D1C0D5400E00B540F +:10131000401EF1D55B1CDBB2521C206890F83110E6 +:101320009142E3DC70BD2DE9FF4F83B00020DDF872 +:10133000409092468B4689F80000039A0121521E84 +:101340001FB202926EE00BEB410CBCF9024001941B +:101350003BF81120A41A26B23CF9024C0094A41ABE +:10136000BCF9048025B2A8EB02043CF904EC24B2D9 +:10137000AEEB020212B2012938D0DDF80CC0ACF19C +:10138000020C614500D10024DDF804C0BCF1000F5F +:1013900000DC3E46DDF800C0BCF1000F00DC3D463D +:1013A000B8F1000F00DC3C46BEF1000F00DC3A460D +:1013B000002E35DD002D33DD9E4201DD9D420BDC2C +:1013C0009C4201DD9D4207DC9E4201DD9A4203DC26 +:1013D0009C4225DD9A4223DD4FF0CF0C0AF801C074 +:1013E000DDF84480B8F1010F02D007E00022CBE71E +:1013F0000AEB010888F801C008F801CC99F800C090 +:10140000B0420CF1010C89F800C000DA3046A84265 +:1014100000DA2846A04200DA2046904200DA104660 +:10142000029A491C91428EDB07B0D0E610B54C21E0 +:10143000314809F0B3F830482A214C3009F0AEF8B1 +:101440002D487621763009F0A9F82B487621EC302A +:1014500009F0A4F82621294809F0A0F82748152109 +:10146000153809F09BF825483B21263009F096F8FD +:1014700022483B21BDE81040613009F08FB82DE9CA +:10148000F04F8E468278DDF824C047E002FB03F17E +:101490000EEB4104164902FB031B164902FB031A1B +:1014A000017837E034F911502E1E00DA7542654597 +:1014B00006DD114D4C3535F812703E4425F81260AA +:1014C00034F911700A9DAF4223DDDFF82C901BF830 +:1014D000016009F176091AF8015039F8168047447D +:1014E00029F816700CE0000004501000A00710004E +:1014F000C8491000E64C1000E22B0120592D0120B4 +:1015000009F1760634F8118036F81570474426F84C +:101510001570491C45788D42C4DA521CC17891423D +:10152000B4DA017817E00EEB41058278FE4E0EE04A +:1015300002FB03F435F91440271E00DA7C426445AF +:1015400004DD36F811403C4426F81140521CC478A2 +:101550009442EDDA491C42788A42E4DA37E62DE912 +:10156000FF4FF248F24F8DB08B46C179DDF86880AD +:1015700038681C4639B190F8B310059130F9AD6F59 +:10158000B0F9025014E090F885120591B0F9866226 +:10159000B0F9885290F89C0250B1FBF784FB39688F +:1015A00091F89C22904203D8B1F99862B1F99A520D +:1015B0000027DFF88093039704970297B2B2DA49C5 +:1015C00099F8000000F07EFA0DF1080ACDE900A7B5 +:1015D00083B2D94AD44999F80000FFF7A4FEB2B209 +:1015E000D64ED149ADF80C004C31307800F06AFA93 +:1015F0000DF10901CDE90017CF4A83B2153AA2F5E2 +:101600008B713078FFF78FFEC749ADF80E00AAB294 +:1016100076313B2000F056FA01260DF10A01C64A48 +:10162000CDE9001683B22632A2F227113B20FFF744 +:101630007AFEC149ADF81000AAB28B393B2000F008 +:1016400041FA0DF10B01BC4ACDE9001683B26132BB +:10165000A2F1EC013B20FFF766FE0025ADF8120079 +:101660002946284603AE53461A5CAA4202D91546BB +:1016700001460AE008D345B136F9112036F910C009 +:10168000624501DA5F5400E01F54401CC0B20428D8 +:10169000EAD3A0780090E0780C90D8F80800009980 +:1016A00009F08CF881465846009909F081F8824685 +:1016B00000990D9809F08AF806460598E8B30F9945 +:1016C0000B9101A90A9106A909915846A17809F040 +:1016D0006FF80746A178D8F8080009F06FF884463B +:1016E00094F802B0E0780890924847F6FF73DA4326 +:1016F0000078079019E0207894F801E00DE017F8E1 +:1017000000800B99884507D13CF91010994200DA06 +:101710000B46914200DD0A46401C8645EFD20798F1 +:101720000BF1010B0CEB400C283708985845E2D21E +:101730000A9803800998028000E00EE0BDF91800C5 +:10174000BDF90410411A05984143642091FBF0F063 +:101750007B490988084407B202E07948B0F9007073 +:10176000009A44E0217837E01AF801300F9883425C +:1017700031D1704BDFF8D0C11B788C4402FB03F0F1 +:10178000704B0B44C35C10F80C009DF808C0AC45CE +:1017900002D16948405C16E09DF809C0AC4503D110 +:1017A00065481538805C0EE09DF80AC0AC4503D151 +:1017B00061482630C05C06E09DF80B30AB4204D196 +:1017C0005D4B6133185CCF2805D039F91100B84260 +:1017D00001DD01207054491C60788842C4D255490B +:1017E000521C0AF1280A0978283609EB41090C989D +:1017F0008242B7D911B0EAE42DE9FF4F53488BB0CC +:1018000000270668524D781E09901C4606F5887818 +:1018100001220D992868FEF7ACFCDFF814B1DBF863 +:10182000000090F88102000606D50BA8009490E80D +:101830000E002868FFF793FE46483B46007848B103 +:1018400094F8240010F0060F04D120460D99FEF7FD +:1018500005FD0346002086F80E010D980022314652 +:1018600000683060AA462868FEF769FD96F80E0108 +:1018700001280CD9DBF8000090F88002C00706D0E0 +:10188000DAF8001033460D9A0846FFF729FC96F85F +:101890000E01002701287DD9FBF701FA0890FBF71C +:1018A000FAF981460B980290DDE90C502A4B00684A +:1018B000019001AA29460298FEF726FC70B101A901 +:1018C0002548FEF7BBFB0095224601A92248029B52 +:1018D000FDF702F8E1686161E169216201258BE0B1 +:1018E00068222146404608F01FFE114906EB4500DC +:1018F0000968B0F8B42091F88C128A427BD9012192 +:10190000099AA940114276D0B8F82410234641F034 +:101910001002A8F82420B0F8B410A8F82610DDE9C9 +:101920000C12DAF8000019E0E22B0120945A1000A2 +:10193000A007100025071000592D012024071000D2 +:10194000D6061000C8491000E64C1000A80610008A +:101950008C061000E806100070471000FEF7B9FF73 +:10196000D4E91801CDE9000104F150010FC9FEF7D7 +:1019700026FFA08500208DF81400ADF81800ADF802 +:101980001C0002AB07AA06A905A883E80700D4E952 +:10199000180100E05DE0CDE9000104F150010FC93C +:1019A000FEF747FFBDF81800E085BDF81C10218642 +:1019B0009DF8141084F849104B4906EB85029346B4 +:1019C00021F8800F208E488094F849004346C0F1EA +:1019D000FF000871E9B2DAF80000FEF7F8FB012019 +:1019E00000905A46E9B24346DAF80000FDF783F862 +:1019F00008B17F1CFFB26D1C96F80E01A842BFF41F +:101A00006FAF3A48026892F8800200061DD5394649 +:101A100019E0089892F8C0520844C0B200EB800365 +:101A200003EBC00309EBC300C38CAB4209D890F8A9 +:101A3000373090F83600181A92F8C132401C98429C +:101A400001DD089813E0491EE3D2012F0BD0002FCF +:101A500007D101200BAD009095E807002346FDF764 +:101A60004AF80FB07AE599F8180600B1401E89F8D7 +:101A70001806EEE738B51468C3F83A401C4C2578D0 +:101A80001A4C012D246803D094F880526D0714D5A8 +:101A900094F880526D0609D5164D6D7855B1B4F89D +:101AA0009042154D64432D68A54206DC01B0BDE8A7 +:101AB0003040A1E6B4F88E42F3E701240094FDF72C +:101AC0001AF838BD30B50024234605E031F913502B +:101AD000A54200DD2C465B1C8342F7DB54436420A7 +:101AE00094FBF0F000B230BD38570120A007100081 +:101AF00018051000D80710006807100070472DE97E +:101B0000F34F85B0002001907B488A4604787B48DB +:101B100090F800E07A4890F800B07A4803787A4864 +:101B200000935B1E016857E07848009E002210F881 +:101B3000145004FB06F0059E06EB400604960AEBE3 +:101B400040060296724E366806EB400003900098FD +:101B5000401B3FE0049DB1F84660BEF1010F35F92E +:101B60001090029D35F91070B1F8485002D0BBF1C9 +:101B7000010F03D1B1F86360B1F86550BEF1000FF9 +:101B800002D0BBF1010F0FD0834202D0012800D058 +:101B900050B94AB9DDF80CC0B1F867803CF910C003 +:101BA0001CEB080F00D5012207EB060CCC4502DB2D +:101BB0007E1B4E450EDD2AB1834208D0012806D097 +:101BC00040B904E0834205D0012803D010B10120C0 +:101BD000019001E0401EBDD2641EA5D20198B0B9AB +:101BE00091F8440000F00F014A48C1F11004B0F927 +:101BF00000000AE0059B3AF9102033F910304A43FF +:101C000003FB042213112AF81030401EF2D23E4882 +:101C1000006890F8010200060BD5384800780128CA +:101C200007D1059807B05146BDE8F04F0022F3F701 +:101C3000A5BF07B0BDE8F08FF0B501271446DDF869 +:101C400014C00BE031F9145030F9146005EB030EA9 +:101C5000B6451BDBA5EB0C05B54217DC641EF1D1C4 +:101C6000002F13D0284B1B6893F845301B09C3F194 +:101C7000100609E031F9125030F912405D4304FBBF +:101C80000654241121F81240521EF3D2F0BD38B58B +:101C90000D46044601F0CDF900282CD1E80708D004 +:101CA0001D4801681D480078012802D12068FFF70F +:101CB00026FFE8061FD51A48134D007858B128684A +:101CC000B0F9501000910C49B0F94E3020690A78F3 +:101CD0001449FFF7B1FF1448007800280BD028689A +:101CE000B0F9541000910749B0F9523060690A7890 +:101CF0000E49FFF7A1FF38BD240710002905100089 +:101D00001805100025071000A00710003426012038 +:101D10004C0710003A071000580710002A0710005F +:101D200023071000F87601202207100022770120F7 +:101D30002DE9F0478E488946089F01788D489246E4 +:101D4000006811B1B0F9692214E03FB18A49B0F9D5 +:101D50007122097871B1B0F96F220BE08749B0F9AF +:101D600073224978022902D3B0F9772202E009B13F +:101D7000B0F975228248012690F800C023E057B1DF +:101D800003FB0CF00AEB400409EB4005A41CAD1C5E +:101D9000ACEB060015E07B4810F81300401CC6B2FF +:101DA000EEE735F9101034F91080B1EB080100D5D9 +:101DB000494209B2914204DD734801800020BDE828 +:101DC000F087401EEDD25B1ED9D20120F7E76948AB +:101DD00010B5006890F86612890727D56B4A11780C +:101DE000491CC9B2117090F868328B421ED2002192 +:101DF000117090F800120324C90703D190F8BA00BB +:101E0000C00700D00B24EEF7F9FA614801682143BE +:101E10000160EEF7F1FA1021052002F022FCBDE886 +:101E200010404FF48071002006F027BB10BD2DE953 +:101E3000FF4F5848002681B090F8008056489146E0 +:101E40008A4600783546B34618B1544800780128D0 +:101E500022D04848006890F86602C0071CD00024D1 +:101E6000019F16E0DDF810C00E9B0093E0B23946EA +:101E700052466346FFF75CFF10F0010F05D00120CA +:101E8000A04030436D1CC6B2EDB2641C07EB49079D +:101E900024B24445E6DB01E04546FF264048067093 +:101EA00045B11FFA89F2334641460095019800F08A +:101EB00020F807E03448B0F90010032002F0D1FB0D +:101EC0004FF0010B2B48006890F86602C00608D559 +:101ED00034484FEA49020168019800F6784008F05A +:101EE000DEFA05B05846BDE8F08F2849002008709A +:101EF00070472DE9F003DDF818C0BCF1000F1AD0CF +:101F00000126BCF1010F02D01746B1462CE0002497 +:101F10000FE006FA04F51D420AD0002C0BD0530046 +:101F20006243BDE8F00300EB42011A4608F0B7BA7D +:101F3000641C8C42EDDBBDE8F0037047002600EB2B +:101F4000470534460AE009FA04F818EA030F02D0FC +:101F5000B5F90080464405EB4205641C8C42F2DB77 +:101F600096FBFCF420F817407F1EE7D2E3E7000061 +:101F700029051000A0071000B3061000D8071000B4 +:101F80002507100034260120BC061000AC06100006 +:101F9000AC07100027071000945A10001805100015 +:101FA000B10610004C07100010B5F3F7D5FDBDE8E1 +:101FB0001040F2F701BF2DE9FF4F83B000248146A6 +:101FC0009A46934626468DF80440022006F0F5FA1C +:101FD0005A4648460499F5F7F0F8F949F94FDFF801 +:101FE000E883CA7809F6784560F30302CA700628C8 +:101FF00006D0012819D002281ED003281CD02CE0BE +:10200000022006F0F5FAB7F9000029464200D8F898 +:10201000000008F044FAF2F7C2FE0221012006F0A7 +:102020002CFA002007B0BDE8F08FE8480670FDF7F5 +:102030007FFAFAF795FD11E0FDF750F8FAF740FE48 +:1020400090B3B7F9000029464200D8F8000008F024 +:1020500026FAFF21032002F004FB012401A80090CE +:1020600053465A4648460499FCF7A9F940EA040544 +:10207000022006F0BDFA9DF8040098B1EEF7BEF913 +:10208000D349D4480A68006802430A60EEF7B4F9FD +:10209000D1480178052002F0E4FA4FF48071002065 +:1020A00006F0EBF92846BDE7FFE7FAF7FFFCD5E7B6 +:1020B0002DE9F34F83B00221684600F039FA002180 +:1020C0008FE0C64F049B387801FB00F203EB42051A +:1020D00005EB400404EB400303EB400202EB400B32 +:1020E0000BEB400A0AEB400909EB4000019000208D +:1020F00071E03BF810C03AF8107039F81080BC4419 +:10210000019F01FB060637F8107047440CEB070EE1 +:1021100035F8107034F810C0DDF80080A7EB0C071C +:1021200033F810C0A7EB0C0C0CEB0E0732F810C004 +:10213000674428F8167034F8106035F81070DFF82E +:102140009CC2F61B33F810709CF800C03E4432F875 +:102150001070F61B06EB0E074E1C06FB0C06DFF894 +:102160007CC228F816703BF810703AF810609CF8A2 +:1021700000C0BF1B39F810603744019E36F810606C +:10218000A7EB060E35F8106034F810703E4433F8B3 +:102190001070F61B32F81070F71B8E1C06FB0C0635 +:1021A000774428F8167035F8106034F81070DFF8AE +:1021B0002CC23E4433F810709CF800C0BF1B07EBE4 +:1021C0000E0632F810703744CE1C06FB0C06401C7D +:1021D00028F8167080B2814E3678B04289D3091D36 +:1021E00089B27F4800788142FFF46BAF7C487B491D +:1021F00000780978484342000099039808F04FF9A5 +:102200000221684600F0F2F905B00CE72DE9FF4F16 +:1022100083B00B00DDE912124FF00006DFF8C4B105 +:10222000DFF8C4A1DFF8C481714F4FF001093546D2 +:102230001AD0184600F0C2FC6E4906469AF8000013 +:102240000978884210D0FAF733FD68B96A480078F7 +:1022500050B9DBF80000B0F89211B8F808008142DC +:1022600002D287F80B9000E0FD72032006F0A5F97A +:102270006248007888B16248CDF8009062490378DE +:102280006048B0F900200398FFF7D1FD040010D199 +:1022900003990846FFF70CFF0BE0514800950378BF +:1022A0004848B0F90020594801680398FFF7BFFD7E +:1022B0000446032006F09CF934B1FFF788FD88F846 +:1022C0000040012E27D027E0FFF70FFE9AF801000B +:1022D00008B1012100E0002188F80310019988422B +:1022E00002D008B9A8F80650DBF8001091F8E61201 +:1022F000C90708D04649097829B987F8039010B171 +:102300004448FD700570DDE90512119B0398FFF745 +:1023100052FE0446D3E70124204683E610B500F0C0 +:1023200037F8002010BD10B5F5F71EF9FDF709F9D3 +:10233000FAF79AFBFFF738FEFFF7D7FDFCF72BF90A +:102340002A490020087048708880C8804881088128 +:10235000888188700861486188611C3108708870C4 +:102360002048006810F8302F4A704078C87010BDBF +:1023700010B5F5F70AF9FDF7F5F8FAF773FB00F079 +:1023800064FCF3F7F6FB184800214170017110BDA1 +:102390001CB5044600208DF80400022006F00DF95B +:1023A0002046F5F759F806490628CA7860F3030273 +:1023B000CA7031D001283CD002283FD042E0000052 +:1023C000385701203A0710004C071000E2071000B0 +:1023D000AC0710006C0610006806100025071000FE +:1023E00024071000A0071000D8071000B006100046 +:1023F000945A1000350710003207100036071000FD +:10240000370710003C071000BC700120580710006F +:102410007407100030071000022006F0E9F8F2F708 +:10242000BEFC0120F2F70CFC0221012006F025F889 +:1024300008E0FDF785F8FAF765FB03E0FCF7E1FF3C +:10244000FAF773FB01A8002300901A4619462046AC +:10245000FBF7B5FF0446022006F0CAF89DF8040019 +:1024600098B1EDF7CBFF0A490A480A6800680243B1 +:102470000A60EDF7C1FF08480178052002F0F1F885 +:102480004FF48071002005F0F8FF20461CBD0000CD +:10249000AC0710006C06100068061000062904D274 +:1024A0008B4A525C8B498B5C2BB100210160014649 +:1024B000482001F0B6BD864B083353F82230036044 +:1024C000854B43F822000120885470470A4630B4F7 +:1024D0000021062A11D27E4B9A5C72B17C4C0368B3 +:1024E000083454F82240A34207D17A4B99547A4BCE +:1024F00043F82210016030BC70470160014630BCD7 +:10250000492001F08EBD2DE9F0410124714F724E3A +:102510000025385D38B13D5556F824104A2001F0A9 +:1025200080FD46F82450641C032CF2DBBDE8F081EA +:102530002DE9F041684E674C4FF0000C0C36C0F8A6 +:1025400000C0636806F1140704F1080501291DD0D5 +:10255000022902D0032938D128E00022A918B1F8B5 +:1025600000E0BEF1000F07D0521C042AF6DB022B5C +:1025700028D301464C202AE056F82250056047F83F +:10258000220040F2022008809B1E2DE0052101E080 +:102590006A5C12B1491EFBD214E056F82120026099 +:1025A00047F82100012068545B1E1DE00022A91895 +:1025B000D1F800E0BEF1000F0DD0521C022AF6DB6C +:1025C000042BD6D2BCF1000FB0D101464B20BDE8A0 +:1025D000F04101F026BD56F82250056047F8220070 +:1025E0004FF003301B1F086063609FE7F0B40C4698 +:1025F00039490026374D731E05220C3108350AE093 +:1026000051F82270D0F800C0674504D1AF5CA742F2 +:1026100001D1134601E0521EF2D2591C16D02E4AA7 +:1026200000212032016042F82310E954012C06D029 +:10263000022C02D0032C0BD103E0E8184170F0BC4F +:102640007047E81841708170C170F8E7002EF6D12C +:10265000F0BC01464D2001F0E4BC70B51D4D1E4E8E +:102660000524083520360BE0285D48B156F82410C3 +:102670004E2001F0D6FC295D56F82400FFF7B6FF86 +:10268000641EF1D270BD70B50120134A114B0021B8 +:1026900042F820101954401C0328F9DB012018705F +:1026A00005200C4A0C4C0D4B0C3402F1080504F1CA +:1026B0001406506008E07322424303EBC20244F860 +:1026C0002020295446F82010401EF4D270BD00008E +:1026D00020A80100EC061000605A10001C721000C7 +:1026E0002DE9F043FF4B894600211B78012B00D1D7 +:1026F0000121FD4B00271E781CE0B31E994218D023 +:1027000050F82130002593FBF2FC09EB41081446F8 +:1027100008E004FB06F338F91330B3EB0C0300D5E3 +:102720005B421D44641EF4D295FBF2F3BB4200DD14 +:102730001F46491CB142E0DBB7F5803F03DB4FF693 +:10274000FF70BDE8F083B8B2FBE7E848E8490068ED +:102750000A7800F27710805C487170472DE9F14FDC +:10276000DFF888B3DFF888E3DFF888A3DBF8001030 +:102770009EF800C0002591F88F0191F88E113AF86B +:102780001C606FF000444FEA11180A071ED001F0D8 +:102790000F01D64B002291461B68864293F88D713B +:1027A00005DB301A00FB08F090FBF1F00744CF483E +:1027B0009EF80110F0460068012990F8750107D0D5 +:1027C000022908D000F00303484611E00121E0E7A8 +:1027D000C0F38103F8E7C0F30113F5E73AF81010EE +:1027E0008C4201DD0C4605468A4200DA0A46401C4E +:1027F0009842F3DD00980280DBF8000090F8BC0AF4 +:10280000C10604D5C0F341108EF8000006E0301B6D +:10281000B84201DC9C4504DD8EF80050BDE8F84F5D +:1028200093E7BDE8F88F2DE9FF4FB0499A46DDE9FF +:102830000D3609684FF0000E934691F897417246A5 +:10284000F146E4071FD0012B1DD1AB4D00273C46BC +:102850002D783B46AD1C09E016F803C091F898812D +:10286000C44501D9641CE4B25B1CDBB2AB42F3D3B8 +:1028700091F89931A34200D20127A04B83F863401D +:102880000FB14FF001099A4C91F87671A6787B0749 +:1028900005D506B901989A4B1B7803B15046994B60 +:1028A0001B78012B02D1984B1B784BB1B1F88131C9 +:1028B00083421AD291F874311B0716D503222DE0FA +:1028C000B1F88731834203D291F874311B07F5D4F4 +:1028D000B1F88531834203D291F874315B070CD48F +:1028E000B1F88331834214D318E0B1F87F318342C9 +:1028F00005D291F874315B0701D502220EE0B1F8E0 +:102900007D31834205D3B1F89051AAEB0B03AB4262 +:1029100004DD91F874319B0700D50122754D183DF7 +:102920002B789A420CD19E4216D0784A1278012A0E +:10293000AA6801D1521EAA60002A0DDCA3700BE028 +:10294000AAB1022A01D1012B11D091F87B31AB60E1 +:102950002A70002B00DCA2703A0724D5B1F87F3131 +:102960005B450AD2B9F1000F07D0022206E091F8C8 +:102970007C3103EB83035B00E9E700226B789A422A +:1029800009D1E17899420ED0E968491EE960002931 +:1029900009DCE37007E052B191F89511E9606A70C3 +:1029A000002900DCE270E17839B1617007E091F84C +:1029B000961101EB81014900F0E7A2786270544A58 +:1029C0001388834200D210804C4810F8592F61F3CD +:1029D0000302A17861F3071200F8012962780178F7 +:1029E00062F30301017004B07046BDE8F08F3F4A06 +:1029F000126892F87421D20607D5421A002A04DC24 +:102A0000C1EBC1110844C0F3CF107047384910B56D +:102A1000002048708870C8703649344A18394860B8 +:102A2000886008704870126892F83432DB0703D06F +:102A300092F83F22120900E00022364B1A6008612A +:102A400048618861C8614FF49851334807F0A6FD8A +:102A5000BDE810404FF41871304807F0C1BD2DE9B2 +:102A6000F74F0746002084B01F49ADF80800DFF893 +:102A700084A091F8008010214FF6FF7605464FEABA +:102A800008190446AAF1080B009115E0234904FB3C +:102A900008F001EB800043463946009AFFF720FE1C +:102AA0002BF8140053463AF81410FFF7A0FF23F850 +:102AB000140007EB4907641C0E48183880788442DC +:102AC000E4DD02A8FFF74AFEDFF824805F4698F8AD +:102AD00000003AF810403BF81010114804800348F9 +:102AE00000681FE02A07100025071000A00710004B +:102AF000D8071000140710002407100038570120D1 +:102B0000B30610002E0710002F0710002C0710002E +:102B1000B6061000E0061000F82D0120F840012054 +:102B2000B406100090F8750100F00303C0F3011023 +:102B3000834200D80346002009E037F81020B24253 +:102B400000D21646AA4200D91546401C40B298420F +:102B5000F3DD64482B460580DDE90502CDE900027E +:102B600032462046FFF75FFE0546204600F088F813 +:102B700098F8000037F810105B4820F81A1F868775 +:102B8000BAF800200286BAF802204286BAF8042079 +:102B90008286BAF80610C186284607B025E730B508 +:102BA00009E031F9134032F91350641B50F82350F7 +:102BB0002C4440F823405B1EF3D230BD2DE9F74F83 +:102BC00082B0002100914949494A10270C78516888 +:102BD000064691FBF7F307FB1311464861439578CE +:102BE0004FEA041B00EB410800F598594FEA440AEC +:102BF0006D1C10E02346424631464846FFF7CFFFA2 +:102C000052463146404607F04AFC06EB440608EBC4 +:102C10004B0809EB84096D1EECD235494FF0FF32A9 +:102C200002EB47024868401C4860824200DA4F606D +:102C30004868B84202DA009805B0D6E6DDE903122A +:102C40002C48FFF70CFF0090F6E710B52A4C2068DF +:102C500090F87501C0F30112C0F3810100F0030088 +:102C600002F0F9F8224988702068244990F8D200CF +:102C700000F003000870FFF768FDBDE81040C5E6EE +:102C800030B51D491E4D096891F83422D20725D070 +:102C90001A4A52784AB191F83F2202F00F03140900 +:102CA000B1F83A22B1F83C1208E091F83E2202F065 +:102CB0000F031409B1F83622B1F83812904201DC42 +:102CC0002B6030BD884201DB2C6030BD801AE41AD5 +:102CD0006043891A90FBF1F0184400E0002028605E +:102CE00030BD0000B806100038570120250710003D +:102CF000FC061000F82D0120A0071000D8071000D6 +:102D0000E006100070B5FB4DFB4C296891F83100CE +:102D1000207191F83010617100FB01F26283401E56 +:102D2000C21700EB927020F003000830C0B2E075CB +:102D30004843A083F1484079A0710120E0712072DE +:102D4000607260700020E083A072E072E074207511 +:102D5000FFF7E9FA286890F8700C00F0010060763F +:102D6000FEF7CCFEBDE87040F5F7A6BD70B5E24DAC +:102D700000240D21E2482C6207F010FCAC626C626A +:102D8000FFF7F6FAFFF77FFCDE480480BDE87040ED +:102D9000B8E7F0B5DC49D848DE4F91F83020027131 +:102DA00091F8313043715A4314B2448391F833207F +:102DB000827191F82C20427091F82D30C37191F8F6 +:102DC0002E30037291F82F30437291F835308372B0 +:102DD00091F83630C372CD4BC362C94B0E330363D7 +:102DE000CB4B4363C34B1D6895F8BD3ADE070B46DA +:102DF00093F83E3008D0052A06D0062A04D05C435A +:102E000007EB4404846300E087630C68C24EC4632C +:102E10004FF400443480C14E641E34800024C04E00 +:102E20000464062A3480437591F83D30C37091F8EC +:102E30003C30837091F83F30837591F84030C37512 +:102E40000BD191F84100012807D1B64995F87800D7 +:102E500008700A2801D20A200870F0BDAA4810B5EF +:102E600090F82C10A7488170AF49C278097861F3B7 +:102E70000712A149C27002790B7B63F30002CB7B7E +:102E800063F3C3028B7B63F382020B7C63F3410227 +:102E90009B4B1C7B037B64F34103A44C247864F3B9 +:102EA00082030373954B5B7980F849308B7CC37147 +:102EB0004B7C63F304120271CB7C427B097D63F38C +:102EC000030261F307129A494273097880F82710C8 +:102ED00098490988018598490A78817B62F3030142 +:102EE000817396490A78C17B62F30001944A127893 +:102EF00062F3410121F00401C1739249097880F81D +:102F00007F1091490A7890F87D1062F3410180F8B2 +:102F10007D1010BD70B50C4680EA0406F00601D5A0 +:102F2000F2F71AFE764DC4F300102870B00601D5F2 +:102F3000F1F742FF744BC4F34010687093F82C0013 +:102F40000022042811D002280FD0EA702A71C4F39D +:102F50000021297302280CD005280AD06A7204289F +:102F60000CD006280AD0AA7270BDC4F34001E970E3 +:102F7000EDE7596A01B101216972F0E7586A00B1C1 +:102F80000120A87270BD2DE9F0415B4D5E4EA86A2C +:102F9000316A80EA010418B911B1FFF7E7FE0FE0CA +:102FA000E00709D0694F387820B107F0CDFB08B9A8 +:102FB00000203870FFF7B7F9E00601D5FEF7F4FFFF +:102FC000F169286AFFF7A6FFF0692862306AA862F3 +:102FD000706A6862BDE8F041DBE670B55C4D2C6854 +:102FE000002C0DD04449A0B2CA7A897A01F07CF94C +:102FF0002868A043286003D1BDE8704001F0D4B92F +:1030000070BD10B553493C4B0A78997BDC7B21435A +:103010001C7C9B7C2143194328B131B93AB14E48FD +:10302000007810B903E0114301D0012010BD002049 +:1030300010BD3148817BC27B1143027C1143427B2E +:10304000807C1143014301D001207047002070476C +:103050002948807C7047284A1178814207D0254949 +:10306000137E096823B1052381F872301070704710 +:103070000823F9E71CB5FFF779FE1F4C1D4D002012 +:103080002076286890F8E50CC00707D101200023BE +:10309000024600901946052006F0A9FB01AB00226C +:1030A0000B21022005F032FA0198C00711D001214E +:1030B000022005F00EFA286890F8E50CC00703D14D +:1030C000052007F013FB2076207EFFF7C4FF00F0F9 +:1030D00045F80198800705D50221084605F0F9F961 +:1030E00000F074F801980007D8D50821022005F0F7 +:1030F000F0F9D3E7A007100020071000D807100050 +:10310000945A10003857012014841000944901206B +:1031100058430120CC570120720510008005100093 +:103120002E05100091051000E0061000A805100003 +:10313000B1061000BC0610001805100014051000A0 +:103140002905100074071000E8061000FA041000AA +:10315000C8071000B2061000EB0610007FB500246F +:1031600000F04EFF012005F028FAFFF70CFF2E4D6E +:1031700095F82800C0070ED02C48C16890F8373069 +:10318000846B82698DE81E00D0E904234168E86BF6 +:10319000FFF73CF80446686A50B14CB9032005F0CB +:1031A0000CFA2248696AFEF772FD032005F020FA46 +:1031B000FFF754FEFFF711FFFFF74FFAFFF7A3F9F0 +:1031C00004B00120BDE8704005F012BA70B50024CB +:1031D00000F016FF012005F0F0F9FFF7D4FE124DC4 +:1031E00095F82800C00704D010480068FFF796F84B +:1031F0000446686A50B14CB9032005F0DEF90B486B +:10320000696AFEF744FD032005F0F2F9FFF726FE98 +:10321000FFF7E3FEFFF721FAFFF775F9BDE870400D +:10322000012005F0E5B9000020071000148410000B +:103230000D4D00200D4C28602868401C2860EDF7DB +:10324000DDF806F0C2FF0128206808D040F0040035 +:10325000206005F0E4FEEDF7CFF830BFECE720F09A +:1032600004002060F7E700007007100010ED00E098 +:1032700070B5134C25462021114807F08FF91048EE +:1032800000F0B4FC2B78421E691C184600F044F98B +:1032900018B10120216801F0E4F900F0C1FC002818 +:1032A000E9D170BD38B50C46054605F0E6F869462B +:1032B000284605F01CF9009A2242F8D138BD0000DA +:1032C000DE60100000207047034630B40020002963 +:1032D00010DD1A78491E0B2A0CD2864D5B1C55F85E +:1032E000324005EBC2025268914203D1A44630BC81 +:1032F0001846604730BC70470120704710B5017810 +:1033000021B1022906D003290BD106E04078F9F754 +:103310007AFA06E04078012101E040780021F9F7CF +:1033200057FA012010BD0178012908D1724930F8FF +:10333000012F0968A1F8E82C4088A1F8EA0C0120C7 +:103340007047016842686C48CBB20068A0F8023D43 +:10335000C1F30723A0F8043DC1F30743A0F8063DDD +:10336000090EA0F8081DD1B2A0F80A1DC2F307216A +:10337000A0F80C1DC2F30741A0F80E1D110EA0F815 +:10338000101D012070471CB5016800918188ADF8BF +:10339000041082799DF8000058498DF80620E0B3AA +:1033A00055489DF802300068642B01D9642302E07F +:1033B0001BB990F8BB328DF802309DF80330232BF7 +:1033C00000D81BB990F8DE338DF803309DF8043037 +:1033D0009DF80540A34202D80CB10F2B08D990F8F4 +:1033E000773303F00F048DF804401B098DF8053086 +:1033F000022A00D822B990F87B0300098DF8060054 +:1034000000980860BDF8040088809DF80600887167 +:103410003B490868820708D500E008E020F0020078 +:10342000086008210120FFF73DFF01201CBD087046 +:1034300000201CBD10B532490278086812B140F076 +:10344000080001E020F00800086008210120FFF7D3 +:1034500029FF012010BD284910B5096891F8961C74 +:1034600049070AD500782649C207086802D040F407 +:10347000807001E020F48070086008210120FFF7CF +:1034800011FF012010BD70B51E491F4B027809685D +:103490004FF00004CE0118494FF00105096802D52C +:1034A0004AB1032201E032B102221A70407881F859 +:1034B0004606012070BD1D7081F84646F9E7134AA3 +:1034C000007801211170124A08B1117001E000204A +:1034D00010700120704708490078096891F8E51CD0 +:1034E000C90704D00B490A78904200D00870012027 +:1034F0007047000034A80100A007100074071000F6 +:10350000D00710009805100085051000A9051000CF +:10351000A80510003807100030B40C460146002002 +:10352000A1F1A003092B03D8FE4850F8233008E08E +:10353000C0290AD1FB48A1F1C001A0F1040050F854 +:103540002130204630BC1146184730BC704700205F +:10355000704770B50E46F44904460025086838B136 +:1035600000200860F149086004210120FFF79AFE5D +:10357000002E12DD2278711E042A0ED2E948641C46 +:10358000283050F8323000EBC2004068002804DBDD +:10359000814202D1204698470546284670BD10B5A5 +:1035A00000780021820601D5812102E0C00700D009 +:1035B0000121DE48016004210120FFF773FE012094 +:1035C00010BD10B500F0C4FB012010BDD84810B5E7 +:1035D000006890F8500CC00701D000F0B9FB102132 +:1035E0000120FFF75FFE012010BD10B50146002449 +:1035F00009782046102915D005DC49B1012909D0E8 +:10360000022912D10BE011290ED020290DD113E08F +:10361000012412E00224012000F074FA05E00424E1 +:103620000220F9E7082400E01024BF4914F0180F25 +:103630000C6004D0102108E020240020ECE7BB49F6 +:103640000A68824204D0086004210120FFF72AFEA4 +:10365000012010BD034630B40020002911DD1A7886 +:10366000491E052A0DD2AF4D5B1C483555F8324036 +:1036700005EBC2025268914203D1A44630BC184601 +:10368000604762E710B50078AA49C207086802D00F +:1036900040F0020001E020F0020008600821012053 +:1036A000FFF700FE012010BD0120704710B5017822 +:1036B000CB07A0490A6802D042F0080201E022F0DC +:1036C00008020A600078800702D542F0400001E05D +:1036D00022F04000086008210120FFF7E3FD0120EF +:1036E00010BD10B5002103780A469C0601D52021A3 +:1036F00000229C0701D541F002015C0701D541F091 +:1037000004011C0701D541F00801DC0601D541F098 +:1037100010015C0601D541F040011B0601D541F0C6 +:1037200080014378DC0701D041F480719C0701D50A +:1037300041F400715C0701D541F480611C0701D59B +:1037400041F40061DC0601D541F480519C0601D5AD +:1037500041F400515C0601D541F480411B0601D5BE +:1037600041F400418378DC0701D041F480319C07AB +:1037700001D541F400315C0701D541F480211B07DC +:1037800001D541F40021C078C00701D041F080711B +:103790006948C0E90012012010BD002070470346AF +:1037A00030B40020002911DD1A78491E0B2A0DD2F1 +:1037B0005C4D5B1C703555F8324005EBC202526817 +:1037C000914203D1A44630BC18466047BDE601468D +:1037D00000200978072906D25248C83050F8212025 +:1037E000002108461047704710B505F0D4FB0120B2 +:1037F00010BD10B54FF400610020FFF753FD01200C +:1038000010BD10B54FF480510020FFF74BFD012093 +:1038100010BD10B54FF400010020FFF743FD01205B +:1038200010BD10B54FF080610020FFF73BFD012077 +:1038300010BD10B54FF000610020FFF733FD0120EF +:1038400010BD10B50078C00702D000F010FA01E0FA +:1038500000F004FA012010BD10B50188374800249B +:10386000CA07007804D0052802D0062800D0022418 +:103870008A0705D5052801D0062801D144F00404A3 +:10388000480701D544F0080494B1ECF7B7FD2C4883 +:10389000016821430160ECF7AFFD0221052000F033 +:1038A000E0FE4FF480710020FFF7FCFC012010BD0A +:1038B000002010BD10B500880024C10700D00124ED +:1038C000810701D544F00204410701D544F0040406 +:1038D000000701D544F008046CB1ECF78FFD1948DE +:1038E000016821430160ECF787FD02210020FFF70A +:1038F000D9FC012010BD002010BD0020704710B57C +:1039000000880024C10700D00124810701D544F0BC +:103910000204410701D544F00404010701D544F035 +:10392000080411E090A80100D4071000CC07100093 +:10393000A0071000D007100098051000F804100030 +:10394000AC071000B0071000C10601D544F0100408 +:10395000810601D544F02004410601D544F040041D +:10396000010601D544F08004C10501D544F48074FA +:10397000810501D544F40074410501D544F4806407 +:10398000010501D544F40064410401D544F48044A8 +:10399000010401D544F40044C10401D544F4805429 +:1039A000800401D544F400546CB1ECF727FD5A486B +:1039B000016821430160ECF71FFD80210020FFF723 +:1039C00071FC012010BD002010BD10B50078C007AB +:1039D0000ED0ECF713FD5148016841F00101016080 +:1039E000ECF70AFD4FF080710020FFF75BFC01202F +:1039F00010BD10B500880024C10700D00124800745 +:103A000001D544F0020474B1ECF7F8FC44480168B5 +:103A100021430160ECF7F0FC4FF480010020FFF738 +:103A200041FC012010BD002010BD10B5007800241D +:103A3000C10700D00124810701D544F002044007EA +:103A400001D544F0040474B1ECF7D8FC35480168A2 +:103A500021430160ECF7D0FC4FF480610020FFF7B8 +:103A600021FC012010BD002010BD10B500780024FD +:103A7000512841D01CDC172836D00CDC112833D05B +:103A800004DC01282DD0102834D12DE012282BD0B1 +:103A900013282FD128E032282AD004DC302827D060 +:103AA000312827D124E0332822D0502822D123E006 +:103AB000732824D00CDC702821D004DC52281BD0C1 +:103AC000532817D118E0712819D0722812D116E0A6 +:103AD000742814D0752812D0762810D0772809D1F0 +:103AE0000DE000F016FB01E000F0B2FB012401E064 +:103AF00000F0CEFB204610BD00F0B8FBF6E700F06A +:103B000093FCF3E7002118B1012801D0022800D16D +:103B10000121084670470000BC071000C4071000D0 +:103B2000C0071000B80710001C4908B500201C4C45 +:103B300008601C492060086000F0EBFA00F080FD8E +:103B40006B4600221921032004F0E0FC0098C00716 +:103B500005D00121032004F0BCFCFFF789FB00988D +:103B600000070BD50821032004F0B3FC20680821CE +:103B700040F0080020600120FFF794FB0098C00689 +:103B8000DED51021032004F0A4FC2068082120F0D9 +:103B9000080020600120FFF785FBD1E7CC0710006B +:103BA000D0071000D40710001F4800210170417099 +:103BB0008170704710B51C4C0346A078102814D2B1 +:103BC0000F2900D90F211948227800EB02100A466C +:103BD00000F8011B194606F062FC2078401C00F03A +:103BE0000F002070A078401CA07010BD70B50E4C66 +:103BF0000025A17891B10D49627801EB021111F80D +:103C0000015B2A4606F04BFC6078401C00F00F0078 +:103C1000607072B6A078401EA07062B6284670BD73 +:103C200001488078704700007B071000FE6010009C +:103C300010B54FF486714F4806F0D2FC4D49012073 +:103C4000C1F804014C4800214160017006F000FDFC +:103C50000021BDE81040012005F0BCBD10B572B6D2 +:103C600000204549087006F0F3FC62B610BD10B59F +:103C700072B60120404908703E48D0F8080108B1EA +:103C800006F042FD62B610BD10B572B6394B3A4C23 +:103C90001946D3F80821D1F80011491C202A07D26F +:103CA000521C21F02001C3F80821C3F800110FE0D5 +:103CB000D3F8042121F02001521CC3F8001122F096 +:103CC0002001C3F804116168491C6160D3F8001138 +:103CD000026803EBC1010A6040684860207801284F +:103CE00005D1D3F80801012801D106F00DFD62B617 +:103CF00010BD204BD3F8080100280ED0D3F80401E2 +:103D000003EBC000C27922F03F02C27193F8083180 +:103D10005B1E03F03F031A43C271704710B572B6C1 +:103D20001449D1F8080158B1401EC1F80801D1F872 +:103D3000042102F1010222F02002C1F8042105D180 +:103D40000D480078012801D106F082FC62B610BD52 +:103D500010B572B6002007490122C1F80801C1E977 +:103D60004002054948600878012801D106F070FC3E +:103D700062B610BD0C5601208007100010B5064C2D +:103D800000224FF47043228063800449C0E900148C +:103D900002230372427210BD8807100079A9010046 +:103DA00070B5914D2878C1281CD16878A5F1100410 +:103DB000052808D100F0FFF88C480168216081884F +:103DC000A1808079A0716878894908280BD01128D2 +:103DD00008D1086800F54861B0F8E80C2080B1F817 +:103DE0006A00608070BD086890F8021D217090F82C +:103DF000041D617090F8061DA17090F8081DE17017 +:103E000090F80A1D217190F80C1D617190F80E1D3B +:103E1000A17190F8100DE07170BD2DE9F05FDFF831 +:103E2000D481894605464FF0030B4FF0010AA8F1F3 +:103E3000080700263C78072C09D2DFE804F0043399 +:103E400037496A7C8700012D02D0022D1CD081E009 +:103E50005FEA09000CD06449097886290ED009F080 +:103E6000FF016148FFF7A6FE0121032004F005FBD6 +:103E70000020022804D0012804D06BE00220F8E7DB +:103E8000032467E0022465E07878012806D05648CC +:103E90001021103806F082FBFFF782FF88F800A09F +:103EA000012457E0022D43D0002453E0022D11D10C +:103EB000514C4D4879682278103806F0F0FA88F8AD +:103EC00000B02178A8F80410042443E0002440E066 +:103ED000022D02D0012DF9D03CE0FFF70AFF48B1D6 +:103EE000022288F80020A8F802000820A8F80400A0 +:103EF00005242FE07878062804D03B4810380021AC +:103F000001604160082188F800B0A8F80410062478 +:103F100020E0022DB6D17878042809D032484946ED +:103F20001038484410F8012C2F48103806F02EFBAA +:103F300088F800A00EE0022D05D0B9F1080F9FD13E +:103F4000FFF7ECFE9CE7FFF7E9FE01E0022D97D1B9 +:103F500003240126387878703C70002E7FF469AF16 +:103F60002448BDE8F09F2349002208390A704A70AE +:103F7000214A521C4A60214901601B491039818045 +:103F80001031C18010210181704710B5044606F040 +:103F90005FFB1548D4E900121038C0E9001216483A +:103FA0000C3806F0BBFB14480C3805F007FDBDE8E3 +:103FB000104006F0A9BB0D490878002813D14870BD +:103FC0000B48006890F8BB228A7090F8DE23CA7014 +:103FD00090F8772313094B7102F00F020A7190F8E1 +:103FE0007B0300098871704728570120740710006F +:103FF000A0071000940710000C621000CB3D0100D8 +:1040000070B5044D942128462C8806F0E9FA641C0A +:104010002C8070BD38570120334800210160416079 +:104020007047C0B2012200F01EFBFEE7884605463D +:10403000174680212D4806F0D3FA2C4C2C4EA76051 +:10404000C4E900682868206168686061A868A061A8 +:10405000E868E0612869206268696062A869A06216 +:10406000E869E0622348006820632248103800684D +:10407000606320480C380068A0631E480838006858 +:10408000E0631C48001D006820641A48343800684A +:104090006064184814380068A06404F03EFBE667CA +:1040A000C4E9140539464046FFF7BBFF10B5044686 +:1040B000C0B2002200F0D7FA0F480168082903DADD +:1040C000094A5454491C016010BD012806D0022839 +:1040D00008D100221146132000F0C5BA0022114673 +:1040E0001220F9E77047000070EF012080EF0120F7 +:1040F000AF0550FA38ED00E09C071000F648F74A8B +:104100000168914204D1F64902794A7000210160A8 +:104110007047F0B585B04FF4EC61EF4806F060FAF7 +:10412000684605F07DFAEC4C012600276670A780F2 +:10413000A7710220E07104F016FF208104F00FFF48 +:10414000050204F00CFF45EA102060816720208200 +:1041500042F293306082E3480068418AA182018A7A +:10416000E182E149B1F8FA2E2283B1F8F82E628398 +:10417000427D227791F8FC1E6177DC4909684A7C10 +:10418000A27790F89A2002F00102E277019A226267 +:10419000009A6262029AA262DDE9032342EA0322E4 +:1041A000E26282692263C2696263D14A1268A263D1 +:1041B0000368E363CF4BA36490F836301B0706D542 +:1041C000B0F83730A4F85030B0F8393003E0438EFF +:1041D000A4F85030838EA4F8523090F8313084F82F +:1041E000543090F8300084F85500A26591F8320000 +:1041F00024F85C0F91F821006080A780BE48A0845D +:10420000BE48A085BE48E085BE482086BE48608680 +:10421000BE48A086BE48E086BE482087BE4860876C +:10422000BE48A087BE48E087BE48A4F84000AC491D +:10423000BD48A4F842008888401C8880A52204F864 +:104240005C2C04F85B6C24F85A0C0E7005B0F0BDC1 +:1042500070B5A34C05460023A0889F49401C82B23C +:10426000A280284601F0BBFC257070BD70B50546E4 +:104270004FF4EC61984806F0B3F9994C9649A08840 +:10428000401C82B2A280284601F0D6FC257070BD89 +:1042900070B5934C05462078A84204D04FF4EC61E9 +:1042A0008D4806F09DF9A148A5700F2101608A484C +:1042B000894A1030A060942010718A4802F1A40548 +:1042C000E560016891F8310091F83010507100FB01 +:1042D00001F3917105EB43062661D071184405EB9B +:1042E00040006061117270BD2DE9F04104467C4DC3 +:1042F0001746C00704D094227F49A86806F0CFF87B +:10430000784EA00711D5306890F8312090F8300031 +:104310004243A87830282CD031282CD032282CD0F9 +:1043200078495200E86806F0BAF860070ED53068A0 +:1043300090F83120A878302822D0312822D0322895 +:1043400025D074495200286906F0A9F8200729D51C +:10435000306890F83020A87830281AD031281AD048 +:1043600032281DD06F496869BDE8F041520006F05F +:1043700096B86249D5E76249D3E76D480168D0E74E +:104380006249DFE76249002FDCD06A49DAE7624917 +:10439000D8E76249E7E76249002FE4D06649E2E7DF +:1043A0006149E0E7BDE8F0814B4A4D49A520107016 +:1043B0008878507008708888401C888050807047CA +:1043C0003EB50C4600218DF800104FF4832502AB5A +:1043D0006A4601A900F0D8F89DF8080010B111282C +:1043E00016D01AE09DF80010B9B10198617105EB83 +:1043F000800304F1100019788A0703D001F0FC0152 +:10440000083100E0091DCAB2194606F048F83EBD61 +:10441000322000222071114603E03020002220715A +:10442000114600F020F93EBD70B505464FF4C87145 +:10443000294806F0D5F82A4C2749A088401CA080BE +:104440002846FFF7BDFF24492570A52008704D7050 +:10445000A088488070BD2DE9F84F884605460C4677 +:104460000E1D00239B220421404600F04FFE90BB0E +:10447000A078A8422FD1217800239B22304600F05B +:1044800045FE6178884279D1207881070AD00222DE +:1044900002EB9005002101E03154401CB0EB850F88 +:1044A000FAD302E0012101EB90050024DFF828B0E7 +:1044B0004FF48326A1464FF0330A56F8240006EB4A +:1044C0008407401C3BD000239B220421384600F087 +:1044D0001DFE98B349E051E0000001204B435546D2 +:1044E000E4071000A007100074770120A407100053 +:1044F000F0FF01001C01020138570120948B0120BC +:104500005843012094490120CC570120F88801200C +:104510006C0B0120580C0120F87601202289012023 +:10452000960B0120820C012022770120C807100081 +:1045300058071000020A01202C0A012001E0009413 +:104540000CE03878810704EB900401D0A41C00E053 +:10455000641C602CB1D3B9F1000F06D02946404647 +:10456000009A04F034FE00280CD000228BF804A03E +:1045700011463320BDE8F84F00F075B8002211460F +:104580003120F7E7BDE8F88F2DE9FF5F4FF0000B12 +:10459000C1F800B01F46924688464FF48325D9469D +:1045A0005C4683F800B055F8240005EB8406401CF7 +:1045B00022D000239B220421304600F0A7FD20B129 +:1045C000122038704FF0010B1CE0B278009930785F +:1045D0008A4208D19AF800104FF00109491C8AF864 +:1045E0000010C8F80040810704EB900401D0A41C1F +:1045F00000E0641C602CD6D3BBF1000F02D1B9F1EE +:10460000010F0BD05BEA090006D1112038700020A1 +:104610008AF80000C8F80000BDE8FF9FD8F8000045 +:10462000002305EB8004201D21789B2200F06EFD05 +:104630006178884201D1002000E012203870EBE759 +:1046400000F018B800F020B81CB50446012301AAF8 +:104650006946183000F0A2FF2046009900F032F8B9 +:104660001CBD00F08FB800F0BDB800F0CDB800F070 +:10467000D4B800001CB57448D0E90010CDE9001092 +:104680006846FFF701FB1CBD1CB56F49D1E902214B +:10469000CDE9002130F8481F090A8DF80210017891 +:1046A0008DF803104188090A8DF8041081788DF87F +:1046B00005100079C0F1FF008DF806006846FFF78D +:1046C000E3FA1CBD1CB5604AD2E90432CDE90032E0 +:1046D00090F8C621032A1CD0082A20D00B2A1ED00D +:1046E0009DF8002022F0F00220328DF8002090F892 +:1046F000C72102F00F02012A17D0022A1BD0042A78 +:1047000038D0052A9DF8012022F00F0238D0521C23 +:1047100016E09DF8002022F0F0021032E5E79DF847 +:10472000002022F0F0023032DFE79DF8012022F075 +:104730000F02921C04E09DF8012022F00F02D21C0F +:104740008DF8012090F80E02D2B260F307128DF8B6 +:104750000120BDF802000A0C62F30B00ADF8020064 +:10476000BDF8030061F30F10ADF803006846FFF7D2 +:104770008BFA1CBD9DF8012022F00F02121DDFE70D +:10478000521DDDE71CB5314A0023126892F89A20C9 +:1047900094070ED50B2816D2DFE800F0150617088F +:1047A000170C171715171700120600E0D206002A7B +:1047B0000BDB1CBD520608D5254A1278052AF8D015 +:1047C000062AF6D001E0002BF3D01F4AD2E90832C6 +:1047D000CDE900328DF80100CDF802106846FFF7F0 +:1047E00053FA1CBD1CB5184BD3E90A43CDE900436D +:1047F0008DF80100CDF80210684612B1FFF7C5FB35 +:104800001CBDFFF741FA1CBD1CB501680091406852 +:1048100001906846FFF738FA1CBD1CB541780029A5 +:1048200010D005290ED20849D1E90E21CDE9002189 +:10483000D0F80210CDF80210C088ADF80600684626 +:10484000FFF722FA1CBD000084A90100A007100098 +:10485000F80410002DE9FF4103F05AFD224D002419 +:10486000C4EBC40105EB810000F10C02037EC4CA55 +:1048700003938DE8C400D0E9012355F821000021FD +:1048800003F0F0FE18B121464320FFF7CAFB641C79 +:10489000052CE5DB144D00248C3505EBC40000210C +:1048A000426855F8340003F064FE18B121464420F4 +:1048B000FFF7B7FB641C062CEFDB0B4D0024BC3567 +:1048C000002155F8240003F0BAFD18B12146452017 +:1048D000FFF7A7FB641C042CF2DBBDE8FF81014657 +:1048E0004620FFF79EBB0000C4A9010000F01F0393 +:1048F00001229A4043099B0003F1E023C3F8802280 +:104900004907090E002806DA00F00F0000F1E02048 +:1049100080F8141D03E000F1E02080F80014C3F8D3 +:10492000002170472DE9F05FDFF80CB464240726FE +:10493000DBF800000027DFF8FC8390F8CC004FEA9A +:104940005009FE4804F00CFEFC4ADFF8F4A3FD4DCC +:1049500011688AF8001050688AF80100CB1C26D034 +:10496000C31C24D0936813F1030F20D0126912F1F5 +:10497000030F1CD0B1F1FF3F20D011F1020F1DD069 +:10498000B0F1FF3F1AD010F1020F17D0B3F1FF3F83 +:1049900014D013F1020F11D0B2F1FF3F0ED012F17B +:1049A000020F0BD0CCB2C6B2DFB2904617E0286837 +:1049B000807F5A280ED00021242005E02868807FBF +:1049C0005A2807D000212520FFF770FB2868807F38 +:1049D0005A2804D128680727C47F90F82060DBF8A4 +:1049E000000090F8CC00C00702D004EB0900C4B26C +:1049F0000D34E0B2761CF1B28AF802008AF8031096 +:104A00003A4604F0D5FA404604F0DFFACE4804F006 +:104A100066FDCD4C032807D001280DD002280BD00D +:104A20002168012912D014E0286890F821005A2842 +:104A300014D00021292006E0286890F821005A2887 +:104A40000CD000212A20FFF731FB02E0201D03F0EB +:104A5000AAFE286890F821005A2812D1022121606C +:104A6000DBF8001091F88D16890703D59821201DD9 +:104A700005F0B6FDB448296810229C30223105F0BB +:104A80000EFD201DBDE8F05F03F08DBEF8B50E46AB +:104A9000054600246A4604F013FB012801D00124D6 +:104AA0000BE0306829468200A84805F03DFDA74884 +:104AB00004F019FB012800D002242046F8BDF8B507 +:104AC000A24EA34F10364FF47061A24805F088FD46 +:104AD00069463846FFF7DAFF012805D0022806D0DC +:104AE000F07801280AD105E00021A02028E000216B +:104AF000A12025E0B07808B9308810B10021A220AB +:104B00001EE09448F1880024A0F8F81EB188A0F8AF +:104B1000FA1E317A80F8FC1E0098694607EB800780 +:104B20003846FFF7B3FF70B1012803D00021A6205B +:104B3000FFF7BCFAE00723D0A00723D41121A72058 +:104B4000FFF7B4FAF8BD75783146284601F008F849 +:104B500050B1102D0BD0112D0CD0122D0DD0132DC6 +:104B6000DAD144F01004D7E72946A820E0E744F062 +:104B70000104D1E744F00204CEE744F00804CBE797 +:104B80001021DCE720070BD46B48006890F8001276 +:104B9000C90703D190F8BA00C00701D01221CEE7AF +:104BA000E006CFD41321CAE710B58EB0EBF726FC90 +:104BB0000020012341B201F01F0403FA04F2490965 +:104BC000890001F1E021C1F88021401C1F28F1DBA0 +:104BD000EBF712FC04F098F9FFF790FA04F078FD77 +:104BE00007210A20FFF782FE07210B20FFF77EFE38 +:104BF000FFF71EF8FEF7D8FF04A8FFF7B4F907A8DF +:104C0000FFF7BCF804A8009007A802900AA8039038 +:104C1000684604F06FFF02210020FFF767FE05F0F1 +:104C200079FD0078C00701D1FFF721F8FFF7F4F90B +:104C300004F0B6F9484C01AA6946204604F040FA4F +:104C4000012802D00021202012E00098A0F5407237 +:104C5000523AF7D12146384C40F64852206805F0C8 +:104C60001EFC206804F03FFA012803D00021212017 +:104C7000FFF7D7F900F024F8FFF754FEFFF71FFF06 +:104C800000F044F803F0D6F803F062FD002301229F +:104C90001946052005F07CFA00231A46012106205A +:104CA00005F076FA03210120FFF720FE04210720FA +:104CB000FFF71CFE0EB00421BDE81040082015E6E9 +:104CC0007CB5264E01AA6946304604F0F9F91D4C20 +:104CD0004FF48055012803D10098B0F5806F02D0C1 +:104CE000002122200BE02A463146206805F0D7FB40 +:104CF000206804F0F8F9012807D000212320FFF7ED +:104D0000D5F92946206805F049FC7CBD10B504F0B2 +:104D1000A5FF002301221946184605F039FA0023A1 +:104D200001221946104605F033FA002301211A46E4 +:104D3000022015E00090D003A0071000D8961000C4 +:104D40006E770120A4071000909C10001C721000C8 +:104D5000F0CF010074770120F0EF0100F0BF0100F7 +:104D600005F016FA00231A460121032005F010FA77 +:104D700000231A460121042005F00AFA16480068AB +:104D8000017CA52908D04FF4FA4005F0EBF9002189 +:104D90002820FFF78BF902E0406905F0E3F90421D0 +:104DA0000220FFF7A3FD04210320FFF79FFD04214C +:104DB0000846FFF79BFD04210520FFF797FD04211E +:104DC0000620FFF793FD01210920FFF78FFD042145 +:104DD000BDE810400F2089E5A4071000F0B5054696 +:104DE00000200C46014603464FF0804203E09B083A +:104DF00043EA82739208EE1A74EB0206F7D318E0C6 +:104E0000C71841EB0206B5EB070C74EB060C07D391 +:104E1000ED1B64EB0604DF1842EB02063818714103 +:104E20004FEA9303490843EA82734FEA30004FEA9E +:104E3000920253EA0206E3D1421B71EB040202D252 +:104E4000401C41F10001F0BD884200D30846904269 +:104E500000D310467047884200D80846904200D8D8 +:104E600010467047884200D308467047884200D8F1 +:104E700008467047884200DB08467047884200DCDD +:104E800008467047024600204FF0804100E0890844 +:104E90009142FCD807E04318934202D8D21A00EBA3 +:104EA0004100400889080029F5D1824200D9401C00 +:104EB000704710B55A43029C05E050F8223093FB2E +:104EC000F4F341F82230521EF7D210BD10B55A4308 +:104ED000029C04E050F82230634341F82230521E15 +:104EE000F8D210BD2DE9F04F8246DDE90906DDF864 +:104EF00034E08B46824225D1002421E004FB02F0FD +:104F00000AEB80090B9D04FB0EF0002105EB8005E8 +:104F100013E000200EE000FB06F803EB880859F8C8 +:104F200020C055F8217058F82180401C0CFB0877F0 +:104F300045F821709042EEDB491CB142E9DB641C6C +:104F40005C45DBDBBDE8F08F30B5039C634306E0D6 +:104F500050F8234051F823502C4442F823405B1E64 +:104F6000F6D230BD30B5039C634306E050F82340D1 +:104F700051F82350641B42F823405B1EF6D230BD2B +:104F800010B500231C4642B10278521CD2B2027006 +:104F90008A4203D90470012300E00470184610BD52 +:104FA00030B50024012305E00C44E41C04F00305A3 +:104FB000641B5B1C9342F7DD00EB440030BDF0B591 +:104FC000851ADDE905471E1B75438E1A012F02D095 +:104FD000904206DD0BE0904201DC1846F0BD8842AD +:104FE00001DB2046F0BD95FBF6F0181AF0BD8842B3 +:104FF000F3DA95FBF6F02044F0BD2DE9F047994631 +:1050000090461DE0051800F00106354341EB010410 +:1050100002464E0815400C404FEA3007A9F1010244 +:105020004FF001004FF0000105F0EFF900EA050232 +:1050300001EA040347EA020046EA0301284021404E +:10504000B8F10108DED2BDE8F0872DE9F047002471 +:105050001746884681461E4625465A1E012021468F +:1050600005F0D3F90BE039F91620424504DA3A4449 +:10507000002A01DD04430D4349084FEA3000761E43 +:10508000F1D220462946DEE72DE9F047844600208C +:1050900092468946014601260746024621E03CF930 +:1050A00012504D451ADA0CEB4208B8F902402C1B9D +:1050B00000D5644238F9028C24B2B5EB080500D55E +:1050C0006D422DB232B1A3F10108424501D0A54293 +:1050D00000DD2C46544501DA30433943B6197F418F +:1050E000521C9A42DBDBAEE770B50CE006180346B3 +:1050F00041EB01051E430D4349084FEA300040EAE9 +:10510000060041EA0501521EF0D270BD70B5054699 +:10511000184600240EE02B5D58400823060602D5F1 +:1051200082EA400000E040005B1EC0B213F0FF03C3 +:10513000F4D1641C8C42EED370BD30B507E0041886 +:1051400000F001031C4341EB010520402940521EA1 +:10515000F5D230BD2DE9F04700248246A6B0501E9E +:1051600000F0FF0C234620466E460DF14C0912E07C +:1051700031F910502C44451C2F4694FBF5F526F8C8 +:105180001050ACEB0005401C31F91580434493FBF3 +:10519000F7F729F815709042EADB4B460AE036F93A +:1051A000120033F91240204431F81240A4EB6000A1 +:1051B0002AF81200521EF2D226B044E72DE9F04739 +:1051C0000026914607468846344635460FE041465C +:1051D0002A46384605F02CF9C00705D0641CE4B215 +:1051E000A64202D2264600E000246D1CEDB24D45D9 +:1051F000EDD3304627E7F0B5DFF888C000220CEB8E +:10520000C2034FF0FF34C3E90044521C1A2AF6DBF4 +:10521000DFF874E00022DEF8004009E000EBC20392 +:10522000D3E900568B180CEBC303521CC3E900569C +:1052300094F831309342F1DC002314E04FF0FF3456 +:105240002546002207E09E180CEBC607D7E9006749 +:1052500034403D40521CB2EB410FF4DD00EBC30281 +:105260005B1CC2E90045DEF8002092F831209A422A +:10527000E4DCF0BDC2F58073504301FB0300001273 +:1052800070470000F0961000A00710002DE9F047CD +:10529000D0F810C00568046A85FB0C12A1FB0461FC +:1052A00041694368894683FB01128269E246A1FB9A +:1052B00002178E19D0E9021781FB07C8C069ACFB41 +:1052C00000C81CEB060682FB0A2CA2FB012180FB16 +:1052D0000901A0FB0501801884FB0712A1FB031242 +:1052E0000818301A4FEAE071BDE8F08770B542F255 +:1052F0001074049D521AED1A654395FBF2F2514366 +:1053000091FBF4F1591A424392FBF4F0084470BD4A +:105310002DE9FF4F83B01146DDE91278D1E900068F +:105320001D46D1E902238218D1E904015E4183467A +:1053300010180091002471413A46434605F08BF85D +:105340000646D5E90203D5E9001C0A18D5E904018F +:105350004CEB030C8246101889464CEB01013A468F +:10536000434605F078F8054658463A4643460099C4 +:1053700005F071F8C21783460192504649463A46F5 +:10538000434605F068F8C3170093BBEB060180465F +:105390001498019AA1FB007C4FEAE67962EB0902BE +:1053A00002FB00C0A34601FB0B0102225B4638460C +:1053B00005F051F8871941EB0909B8EB050114987C +:1053C000009BA1FB00C84FEAE57A63EB0A0303FBED +:1053D000008001FB0B0102220023604605F03BF830 +:1053E000401941EB0A08BB49A44663460968BCEB77 +:1053F000070C42F2107A73EB090307DA4A8E521E49 +:105400004FEAE27CBA1A79EB0C0313DB4FF0000C85 +:105410006346BCEB070C73EB090301DA4C8E641E88 +:10542000CDE9000A2B4631463A462046FFF75EFF9B +:10543000274623E04FF0000C62464346BCEB000CCD +:105440009A4107DA8A8E521E4FEAE27C821A73EB87 +:105450000C0313DB4FF0000C6346BCEB000C73EB4A +:10546000080301DA8C8E641ECDE9007A02463346C9 +:1054700029462046FFF73AFF0746204603994F602A +:105480000399086007B0BDE8F08F30B5B0F902406D +:10549000B1F90250641B00D56442B0F90000B1F9C3 +:1054A0000010401A00D54042944203DA984201DAD3 +:1054B000012030BD002030BD884201DD0846704724 +:1054C0000028FCDA0020704710B504E000EB8203EE +:1054D00053F8044C1C60521EF8D10968016010BDDD +:1054E00010B503E000EB82030C681C60521EF9D279 +:1054F00010BD30B505E000EBC20373E90245C3E916 +:105500000245521EF7D1D1E90021C0E9002130BD8A +:1055100010B553884C881B1B438012880988511A88 +:10552000018010BD08B50A4601466846FFF7F0FF46 +:10553000BDF90010BDF90200494300FB001008BD91 +:1055400010B58842029C01DC204610BD904201DB70 +:10555000184610BD8A4200D1521C401AE31A584323 +:10556000511A90FBF1F0201A10BD10B5002A03D09B +:10557000431A934201DD881810BD5442A342FBDA5E +:10558000881A10BD914201D100B270475043B0FB60 +:10559000F1F000B29042F7D91046F5E7F0B50C00F3 +:1055A00002463FD04B4F3868468E858EB2F90200D6 +:1055B00031B2FFF781FF6080B2F9000029B2FFF736 +:1055C0007BFF2080396891F83610490702D5618841 +:1055D000711A6180396891F83610890701D5281A47 +:1055E0002080386890F83610090712D5012B10D1A9 +:1055F000B0F83720B4F902003146FFF7C3FF6080EE +:1056000038682946B0F83920B4F90000FFF7BAFF2E +:105610002080386890F83600C00703D06088218861 +:1056200061802080F0BD2B490968B1F93220B1F9C1 +:10563000343091F8361062F31F4063F30F00C9074E +:1056400003D063F31F4062F30F00704770B50B0087 +:1056500002463DD01F4EB2F9020031684D8E8C8E4D +:1056600029B2FFF729FF5880B2F9000021B2FFF7F5 +:1056700023FF1880316891F83610490702D5598800 +:10568000691A5980316891F83610890701D5201AB6 +:105690001880306890F83610090710D5B0F8372018 +:1056A000B3F902002946FFF76DFF588030682146A4 +:1056B000B0F83920B3F90000FFF764FF18803068B4 +:1056C00090F83600C00703D0588819885980188090 +:1056D00070BD0000A007100073B51D24DDE9005661 +:1056E00022460120002104F090FE2840314008436A +:1056F00001D1641EF4D50821684603F0CFFCFF49B0 +:10570000C0B2096891F8CE10C1F3411102290ED33D +:1057100010F0030005D0012805D0022805D01F2075 +:105720000AE00F2008E07F2006E03F2004E0C007E9 +:1057300001D0072000E003200021621C04F065FE78 +:10574000DDE9002310431943CDE900017CBD10B50C +:10575000EB4C502814D008DC102811D0112825D08B +:10576000122823D0132806D120E051281ED0522819 +:105770001CD053281AD00020C4E9020001461BE0C7 +:1057800002F0E3FBC4E9020102F0E1FBC4E9040119 +:10579000DA48006890F8CE0010F0600F0ED0D4E91F +:1057A0000201FFF799FFC4E9020107E002F0CDFB17 +:1057B000C4E9020102F0CBFBC4E90401D04808218E +:1057C000083003F06BFC2060CD480821103003F056 +:1057D00065FC606010BD2DE9FF5F82B011AC08214F +:1057E00094E8000E02A803F059FC0090082104A8D8 +:1057F00003F054FC0746002528463BE042460120C2 +:10580000002104F002FEDDE90223104019400843A4 +:105810002ED00024264628E032460120002104F044 +:10582000F4FDDDE904231040194008431CD0BBF10E +:10583000000F0CD005FB07F009EB0401415632467E +:1058400001EB0A032946109803F06BF80BE032468F +:105850002946109803F05AF8A0EB0A0105FB07F05F +:1058600009EB04028154641C761CBC42D4DB6D1C21 +:1058700008F10100804600988542BFDB06B0BDE814 +:10588000F09F2DE9FF5F84B00821DDE9134B04A8E8 +:1058900003F004FC0746082106A803F0FFFB80463E +:1058A00012980026483002901298354668300190D0 +:1058B0001298B2462030B146009032E052460120A4 +:1058C000002104F0A2FDDDE9042310401940084343 +:1058D00023D0169880B1A15D01EB0B00C2B25146F6 +:1058E000029803F08AF8F11901EB0800225651469C +:1058F000129803F05AF80EE05146029803F07BF834 +:10590000A0EB0B00A0555146129803F047F8F2198E +:1059100002EB08016054761CF6B20AF1010000F0B7 +:10592000FF0ABE42CADB36E04A460120002104F0ED +:105930006CFDDDE9062310401940084327D0169876 +:1059400090B1E819215C15980844C2B24946019803 +:1059500003F053F805EB470101EB080022564946D6 +:10596000009803F022F810E04946019803F043F84C +:105970001599401AE91960544946009803F00EF849 +:1059800005EB470202EB080160546D1CEDB209F112 +:10599000010000F0FF094545C6DB08B06FE72DE9BF +:1059A000FF5F0821DDE90EB9684603F077FB824608 +:1059B000082102A803F072FB00268046374628E043 +:1059C0003A460120002104F020FDDDE900231040CB +:1059D000194008431CD00024254616E02A46012021 +:1059E000002104F012FDDDE90223104019400843B4 +:1059F0000AD02A463146584602F088FF06FB084284 +:105A0000800029F81200641C6D1C4445E6DB761CFE +:105A10007F1C5645D4DBBDE8FF9F2DE9FF5F0821C1 +:105A2000DDE90E48684603F039FB0746082102A865 +:105A300003F034FB002683463546B246B14641E0CA +:105A400052460120002104F0E0FCDDE90023104073 +:105A50001940084332D0514604F1480002F0CBFF10 +:105A60000246264894F89230006890F8111190F898 +:105A7000100101F00F0C0CF1010C03FB0CF34FF0C3 +:105A8000010C0CEB111102FB013194F890200CEB8E +:105A9000101002FB0010109919B94FF6FF7101EABE +:105AA000800028F816005146204602F077FFF219D0 +:105AB00080005A44761C28F81200F6B20AF1010060 +:105AC00000F0FF0ABE42BBDB47E04A46012000214E +:105AD00004F09BFCDDE9022310401940084338D054 +:105AE000494604F1680002F086FF0246034894F834 +:105AF0009360006890F8131104E00000A007100004 +:105B00000008100001F00F035B1C5E43012303EB50 +:105B1000111102FB016190F8120194F8912003EB3E +:105B2000101002FB0010109919B94FF6FF7101EA2D +:105B30008000EA19494628F8120004F1200002F01A +:105B40002DFF05EB470280005A446D1C28F8120017 +:105B5000EDB209F1010000F0FF095D45B5DB5AE740 +:105B60007FB50D4604460026FFF7F1FD0122F849F6 +:105B700005F11000102C06D0112C0FD0122C23D0C0 +:105B8000132C29D124E02B790C68A3420ED16B7918 +:105B90004C68A3420AD10023EE4C0BE02B790C6831 +:105BA000A34203D16B794C68A34201D0002613E0D5 +:105BB000E94C002300940392CDE9010308310FC999 +:105BC000FFF709FE012607E0284600F083F802E00F +:105BD000284600F0B8F80646304604B070BD2DE9FE +:105BE000F0411E461746884604460025FFF7AFFDE4 +:105BF000102C06D0112C0AD0122C11D0132C0CD141 +:105C000014E032463946404600F0D6F804E0324609 +:105C10003946404600F0F4F805462846BDE8F081D4 +:105C200032463946404600F00FF9F5E7324639462C +:105C3000404600F04BF9EFE72DE9FF4117460C46CF +:105C40000646FFF784FDC24804F11005502E017886 +:105C500021710179617107D0512E07D0BF49522EB1 +:105C60000FD0532E30D119E0BA4900E0BA49CDE93E +:105C7000001585680C3090E80E002846FFF78FFE6F +:105C800022E00968B64B91F8042191F8101102F056 +:105C9000010201F00101CDE902120CE00968B04BEC +:105CA00091F8292691F8351602F0010201F0010160 +:105CB000CDE902129833CDE9003585680C3090E8C3 +:105CC0000E002846FFF7A9FEA520207066706780A9 +:105CD000BDE8FF8130B59E4C017987B022689142C2 +:105CE00003D141796268914202D0002007B030BDF3 +:105CF00098498579002281F8825BC57981F8835BB8 +:105D0000857A81F8845BC57A81F8855B057B81F8AB +:105D1000805B457B81F8815B9049012513460968CA +:105D20001030083491F8041101F00101CDE904515B +:105D30008B4901AD009185E80D0094E80F00FFF755 +:105D4000A0FD0120D2E730B5814C017987B02268EF +:105D5000914203D141796268914201D00020C5E7A8 +:105D60007C498579002281F81A5CC57981F81B5C31 +:105D7000857A81F81C5CC57A81F81D5C057B81F809 +:105D8000185C457B81F8195C744901251346096844 +:105D90001030083491F8291601F00101CDE90451C1 +:105DA0006F4901AD9831009185E80D0094E80F002E +:105DB000FFF767FD012099E77FB50E46044640F2E4 +:105DC0007A3104F0EBFB624D624A04F1100128784D +:105DD00020712879607100200092CDE9011005F151 +:105DE000080103900FC9FFF7F6FCA52020701020D2 +:105DF00060706680D5E90001484313308008ECE606 +:105E00007FB50E46044640F27A3104F0C7FB504D90 +:105E1000514A04F11001287820712879607100201E +:105E20000092CDE9011005F1080103900FC9FFF7B9 +:105E3000D2FCA5202070112060706680D5E9000199 +:105E4000484313308008C8E670B50E4686B0044655 +:105E5000FC2104F0A3FB3E4D287820712879607165 +:105E60003C4890F8821BA17190F8831BE17190F877 +:105E7000841BA17290F8851BE17290F8801B21733E +:105E800090F8810B60733548006890F8040100F0C9 +:105E900001010020CDE904010290039004F11000FB +:105EA0002F49CDE9001005F108010FC9FFF7E9FC02 +:105EB000A5202070122060706680D5E9000108449A +:105EC000132101EB4000800806B070BD70B50E468E +:105ED00086B00446FC2104F061FB1D4D287820713A +:105EE000287960711B4890F81A1CA17190F81B1C4E +:105EF000E17190F81C1CA17290F81D1CE17290F8E1 +:105F0000181C217390F8190C60731448006890F8FD +:105F1000290600F001010020CDE90401104902909A +:105F2000039004F110009831CDE9001005F108014B +:105F30000FC9FFF7A6FCA5202070132060706680B3 +:105F4000D5E90012114400EB41008008BCE70000D5 +:105F500000081000747701209C7C0120A00710002D +:105F60006482012030B506E032F8134031F8135056 +:105F7000641B20F813405B1EF6D230BDF0B4049CC5 +:105F80001CB913B1C3F110050DE0F0BC520004F0D0 +:105F900086BA30F9124031F912605C4306FB0544C1 +:105FA000241120F81240521EF3D2F0BC7047F0B416 +:105FB000049C1CB913B1C3F180050DE0F0BC520084 +:105FC00004F06DBA30F9124031F912605C4306FBFF +:105FD0000544E41120F81240521EF3D2E5E70346CF +:105FE000B0F9000004E033F91120824200DD1046D0 +:105FF000491EF8D2704710B5002447F6FF7307E03A +:1060000030F91120A24200DD14469A4200DA13460C +:10601000491EF5D2E01A00B210BD2DE9F047164630 +:10602000DDE90878894604460025DFF884A227E0E8 +:106030002A460120002104F0E8F9384001EA08016D +:1060400008431AD00020524615E0136834F91010A6 +:1060500093F85F32594341F3CF1124F8101000290F +:1060600000DA49421368B3F87332994202DD012025 +:10607000BDE8F087401CB042E7DB04EB46046D1C32 +:106080004D45D5DB0020F3E72DE9F04F47F6FF76CD +:10609000DDE909B5F4439A4601278146BC462B4603 +:1060A00014E032F8130031F81380A0EB080000B2BE +:1060B000B04200DA0646A04200DD0446002802DDB8 +:1060C0004FF0000C02E001DA4FF000075B1EE8D24F +:1060D00027B1BCF1000F01D0002009E057EA0C0005 +:1060E00006D027B9BCF1000F01D0204600E03046B1 +:1060F00000231E462C46CBF1000C0DE032F8147044 +:1061000031F81480A7EB08073F1A3FB2574503DA6E +:10611000674501DD3B44761C641EEFD206B90126BB +:1061200093FBF6F2131804E031F81500184429F82F +:1061300015006D1EF8D2BDE8F08F2DE9FF4F5C48C9 +:106140008A465C49006891460978B0F832C085B04B +:10615000BCFBF1F2584C818E03912478B1FBF4F131 +:10616000564CB4F91A60B4F9185096FBF2F6F7B22F +:10617000B4F91060B4F9124095FBF2F596FBF1F614 +:1061800094FBF1F4EDB2F6B2E4B21BB990F8703CB6 +:106190009B0659D5B0F8023DACEB030393FBF2F339 +:1061A0001BB20293B0F8043DB3FBF1F31BB20093B2 +:1061B000B0F8063DB3FBF2F30FFA83F8B0F8083DF0 +:1061C000B3FBF1F31BB20193B0F80A3DACEB030350 +:1061D00093FBF2F30FFA83FEB0F80CCD039BA3EB15 +:1061E0000C0393FBF1F30FFA83FBB0F80E3DB0F80C +:1061F000100DB3FBF2F2039B12B2181A90FBF1F0F0 +:1062000003B2904501DB404600E010460299724619 +:10621000714500DC0A46DDE9001C614500DA614693 +:10622000DC469B4500DB6346854200DB2846C5B261 +:10623000974200DC3A46D7B28E4200DB3146CEB2FE +:106240009C4200DC2346DCB20021059804F0B6FA3B +:106250001949002291F800B025E0164B002193F86F +:1062600000C01AE0B24205DDA24203DAA94201DD14 +:10627000B94208DB30F91130B9F9008043450ADD35 +:10628000A9F8003007E030F91130BAF90080434531 +:1062900001DDAAF80030491C09B26145E2DB521C5D +:1062A00000EB4C0012B25A45D7DB09B043E70000BF +:1062B000A00710002507100024071000442010003C +:1062C00070B5050003D0BDE8704001F01CBEFE4C67 +:1062D000204662780179012A16D0022A1BD0207844 +:1062E00001F0CAFE21794A00F84901EB4001F74864 +:1062F000983004F0D4F8A078F54E78B1F3482179BD +:10630000983001F0B2FE0BE00A46F04901F1980026 +:1063100001F028FEEFE74A00EC49E8E7EB48983047 +:106320003063E07886F839002846CCE7E94901284F +:10633000096808D0022809D003280AD004280BD005 +:1063400091F83A0C704791F83B0C704791F83C0C6F +:10635000704791F83D0C704791F83E0C7047F8B5C6 +:10636000044602F00EFAD94802F010FAA4F87600BA +:1063700001F01EFED44A0B461278009202462046D7 +:1063800002F00CFD01F019FE02460B46204602F019 +:106390003BFD204601F076FECE4DB4F8561028683D +:1063A000B0F88E2062F30901A4F8561090F88D0021 +:1063B00094F8551060F3030184F855100521204628 +:1063C00002F00FFA286890F83906A0702868218E2C +:1063D000B0F83F2662F30801218690F83A0600F0F3 +:1063E0000F01204602F074FA286834F81A1FB0F83A +:1063F000312662F30B0124F81419B0F82F266189B5 +:1064000062F30B016181B0F82D16E08861F30B0097 +:10641000E08014F8050C20F00C0004F8050C286846 +:1064200090F83B160A09217B62F30101217390F871 +:106430003B26920962F38711217390F82716627840 +:1064400061F30002627090F82A06E070A24890F8AA +:10645000181C217690F8191CA17790F81A1C617607 +:1064600090F81B1CE17790F81C1CA17690F81D0C8D +:1064700084F82000994802F089F9A4F87A00974836 +:10648000203002F083F9A4F87E00286890F83516D1 +:106490000A0914F8161F62F3071104F8061B90F896 +:1064A00037261309227863F30712227090F83666B4 +:1064B00014F8053C66F3030304F8053C90F83876BD +:1064C000667867F30306667090F836763F0967F3DF +:1064D000071304F8053C90F838361B0963F30716D8 +:1064E000667090F8353663F3000104F8061C90F8E6 +:1064F000371661F3000204F8222990F82B060109EF +:10650000204602F0F1F97548483802F03FF9A4F846 +:106510007E0072482734283802F038F9A4F85B006E +:10652000286890F829168A08217862F3830121707F +:1065300090F8292662F30001217090F8292652086C +:1065400062F3410104F8011B217821F01001217050 +:1065500090F82726D308E27A63F34512E27290F8A6 +:10656000282662F3451104F8281990F82806C0F38C +:106570004101204602F086F9286890F827168A091A +:1065800014F8331F62F3000104F81D1990F8272650 +:10659000520962F34101617790F83C16E27D61F3A4 +:1065A0000402E27590F83D06A17D60F30401A17537 +:1065B0000120FFF7BBFE94F8491060F3040147483F +:1065C00084F84910E83002F0E1F8A4F86400286883 +:1065D00034F8181FB0F8332662F30B0124F80419BD +:1065E00010F8CA1F227861F3030204F8012B017826 +:1065F0000A09217862F3030104F8091B90F85D157C +:10660000CA09217862F3000104F82B1B14F857190A +:1066100041F0200184F8571090F872154A0921784A +:1066200062F30611217090F85E154A09217C62F32D +:10663000C301217490F85D05400860F304112174D2 +:10664000F8BD2DE9F04104461F4D0120DFF884809C +:10665000A870012908D00026022702290ED003299C +:106660004CD004292BD161E0204600F0B3F8D8F8D3 +:10667000000090F828068009687020E01848FFF7AD +:106680006EFE204600F0A6F80220FFF74FFE94F8B9 +:106690005F1060F30401134884F85F10007801284C +:1066A00007D194F8270020F0020040F0010184F89F +:1066B00027100021204602F00BF9AE706F7094F89D +:1066C000270040F300000FE0180810007C8701202D +:1066D000549C1000A007100074770120448301200F +:1066E000C0971000A8071000401CE870D8F8000000 +:1066F00090F8280680096870BDE8F0813748FFF7F8 +:106700002EFE204600F066F80320FFF70FFE94F8F7 +:106710005F1060F3040184F85F1094F8270020F004 +:10672000020040F0010084F82700C2E7204600F094 +:1067300051F8204601F0E7FCBFE71CB501F03DFC35 +:10674000CDE900010821684602F0A8FC244908713F +:106750002248FFF704FE1CBD30B5417AA9B091B3C1 +:106760006846FFF76EFF9DF8120000F0030001F08D +:1067700057FC1C4D286800F2B26200F2A55490F854 +:10678000A316B0F8A40602EB400001F01BFC286839 +:1067900090F8991590F89A0504EB400001F029FC57 +:1067A0000F494878022811D0012811D00120087023 +:1067B000C1B2684602F042FB0B49684602F073FB27 +:1067C000002029B030BDFFE70120FAE70920EEE7FD +:1067D0000320ECE7A422014903F061BEC09710003A +:1067E00018081000A00710007162010070B518B100 +:1067F000BDE8704001F087BBFE4CFD4DE078A5F18F +:106800009801820001F5887003F08EFEA1780129BD +:106810001DD0022922D0E178607801F027FCE178D0 +:10682000C0B24A00A5F1980101EB4001284603F0EF +:1068300036FEA079F04D012815D0ED482862E079A8 +:1068400085F83800607985F828000020D0E7E8490D +:10685000E2789839284601F085FBEAE7E078E449D8 +:1068600042009839E2E7E178E14801F0FDFBE5E715 +:1068700070B518B1BDE8704001F045BBDD4CDC4D92 +:1068800020792A358200A5F1C20101F5B27003F02A +:106890004BFEA17801291ED0022923D021796078EE +:1068A00001F0EAFB2179C0B24A00A5F1C20101EB77 +:1068B0004001284603F0F3FDA079CF4D012816D002 +:1068C000CB482A306862E07985F83800607985F82D +:1068D00029000020CEE7C64922799839284601F0E0 +:1068E00041FBE9E72079C24942009839E1E7C04815 +:1068F00021792A3001F0B9FBE4E7C049062809688C +:1069000013D2DFE800F0120306090C0F91F8350CE2 +:10691000704791F8360C704791F8370C704791F832 +:10692000380C704791F8390C704791F8340C704767 +:10693000F8B5044601F025FFAD48983801F026FF70 +:10694000A4F8760001F034FBAA4D0B466A78009259 +:106950000246204602F022FA01F02FFB02460B46C7 +:10696000204602F051FA204601F08CFBA34EB4F809 +:1069700056103068B0F88E2062F30901A4F8561062 +:1069800090F88D0094F8551060F3030184F85510C9 +:106990000521204601F025FF306890F81401A07011 +:1069A0003068218EB0F81A2162F30801218690F830 +:1069B000150100F00F01204601F08AFF306834F81D +:1069C0001A1FB0F80C2162F30B0124F81219B0F869 +:1069D0000A21218962F30B012181B0F80821A188E5 +:1069E00062F30B01A18090F81621A17A62F30101F4 +:1069F000A17290F81621920862F38711A17290F8A3 +:106A0000021114F8012C61F3000204F8012C90F833 +:106A1000050160707A4890F8801BA17590F8811B81 +:106A2000217790F8821BE17590F8831B617790F8CD +:106A3000841B217690F8850BA077724801F0A6FEA2 +:106A4000A4F878006F48203001F0A0FEA4F87C0084 +:106A5000306890F810110A0914F8141F62F3071136 +:106A600004F8061B90F812212378120962F3071329 +:106A7000237090F8112114F8057C62F3030704F8E1 +:106A8000057C90F813C162786CF30302627090F891 +:106A900011C14FEA1C1C6CF3071704F8057C90F831 +:106AA00013713F0967F30712627090F8102162F3C7 +:106AB000000104F8061C90F8121161F3000304F8B9 +:106AC000223990F806010109204601F00DFF4D48DA +:106AD000483801F05BFEA4F87E004A482734283885 +:106AE00001F054FEA4F85B00306890F804118A08A5 +:106AF000217862F38301217090F8042162F3000190 +:106B0000217090F80421520862F3410104F8011B3E +:106B1000217821F01001217090F80221D308E27A47 +:106B200063F34512E27290F8030160F3451104F833 +:106B30002819204601F086FA306890F80301C0F366 +:106B40004101204601F09EFE306890F802118A094A +:106B500014F8331F62F3000104F8071990F80221BA +:106B6000520962F34101E17190F81711627861F303 +:106B70000402627090F81801217860F3040121701A +:106B80000120FFF7BAFE94F8331060F3040184F893 +:106B900033101D4801F0FAFDA4F84E00306834F8B7 +:106BA000021FB0F80E2162F30B0124F8181910F837 +:106BB000CA1F227D61F30302227510F82E1B0A09F9 +:106BC000617D62F303016175817ACA09A17F62F375 +:106BD0000001A17794F8491041F0200184F8491090 +:106BE000C17F4A0914F80E1C62F306110EE0000082 +:106BF000F88801201D081000549C1000A007100008 +:106C000074770120AC8201202C84012004F80E1C32 +:106C1000C17A4A09A17862F3C301A170827A52084D +:106C200062F30411A170C07A8009A870F8BDA42293 +:106C3000884903F034BC2DE9F041874D0C4600260D +:106C400001216E71A971012807D00227022826D0E0 +:106C500003280CD004284CD143E02046FFF7E7FF7F +:106C60007E48006890F803018009A87041E07948E7 +:106C7000FFF75EFE2046FFF7DAFF0320FFF73DFE39 +:106C800094F85F1060F3040184F85F1094F8270013 +:106C900020F0020040F0010084F827001AE06D485F +:106CA000FFF746FE2046FFF7C2FF0220FFF725FE52 +:106CB00094F85F1060F30401694884F85F1000786D +:106CC000012807D194F8270020F0020040F00101CC +:106CD00084F827100021204601F0FAFDAE71AF7054 +:106CE00007E02046FFF7A3FF204601F00CFAAF7043 +:106CF000AE7194F8270040F30000401CE871BDE835 +:106D0000F08170B5554D286800F2B26200F2A554CA +:106D100090F8A016B0F8A10602EB400001F052F97D +:106D2000286890F8971590F8980504EB4000BDE8A6 +:106D3000704001F05EB970B5474D0146C079454CD1 +:106D40002870097BA434297250B3012928D0214628 +:106D5000FFF771FFA878012824D0022824D0002052 +:106D600068703E480168A07C91F8162162F301002A +:106D7000A07491F81611890861F38710A0746978DE +:106D8000204602F05BF8A07C00F0030001F048F917 +:106D9000FFF7B7FF3349204602F085F8002070BDA9 +:106DA000012070BD0220DBE70820D9E770B52A4D2D +:106DB0000146C079274C2870097BA434297258B346 +:106DC000022929D02146FFF736FFA878012825D0CF +:106DD000022825D0012068702048016891F816012A +:106DE0000209A07C62F30100A07491F816118909D0 +:106DF00061F38710A0746978204602F01FF8A07C28 +:106E000000F0030001F00CF9FFF77BFF1649204664 +:106E100002F049F8002070BD012070BD0320DAE7C0 +:106E20000920D8E71FB501F0C3F8CDE9000101F052 +:106E3000C4F8CDE902010821684602F02FF9064C9A +:106E40000821E07002A802F029F920710148FFF73B +:106E50006FFD1FBD649810001D081000A0071000F2 +:106E6000A80710009D6701002168010070B5B74DAB +:106E7000286800F2B26200F2A55490F89716B0F8B4 +:106E8000980602EB400001F09DF8286890F89115F3 +:106E900090F8920504EB4000BDE8704001F0A9B8FD +:106EA00008B101F030B8AB48A9490161AA49097895 +:106EB00001750020F5E770B5A44D0446286890F8E8 +:106EC0007501C0F30112C0F3810100F00300FDF76A +:106ED000C2FFA14E401C3070204600F0C4FD9C480B +:106EE00001F054FCA4F8760000223178204601F02D +:106EF0007CFEA07940F00200A071317894F86F0018 +:106F000061F3020084F86F0094F86E0020F00F0027 +:106F100084F86E002868A17C10F8EB2F62F3010161 +:106F2000A17410F80129920862F38711A174A18954 +:106F30006FF30B01A1810078A07094F85E0000212E +:106F400020F0010084F85E00204601F0C1FC2868B2 +:106F500090F8771184F8661090F8781184F868102A +:106F600090F8791184F86A1090F87A1184F86C100E +:106F700090F8300C14F85F1F60F30401217070BDAD +:106F80002DE9FC417548FFF796FF704F386890F87F +:106F90007611090639D56E4E0024083E00F27715A9 +:106FA0003460746000F0D1FFCDE900013A6892F8D6 +:106FB000CE2012F0600F03D0FEF78EFBCDE900016A +:106FC0000821684602F06AF800213B6807E06A5C25 +:106FD000424326F81120A24200D91446491C93F8D6 +:106FE000752102F00302521C8A42F0DC002005E009 +:106FF00036F81010611A26F81010401C93F875111D +:1070000001F00301491C8142F2DCBDE8FC8170B54E +:10701000524D4479A4355CB14C48006890F8750134 +:10702000400607D54E48007800F00300022801D240 +:10703000012070BD2146284600F083F8A87C00F0AE +:10704000030000F0EDFF2046FFF710FF45492846FA +:1070500001F00BFE002070BD70B544793B483F4DF8 +:107060000068A43590F87501400606D52CB13C485F +:10707000007800F00300022801D3012070BD2146F2 +:10708000284600F05EF8A87C00F0030000F0C8FF7E +:107090002046FFF7EBFE3349284601F0E6FD0020CD +:1070A00070BD002800F02FBF2DE9F0412B4C8579F1 +:1070B000A434EDB32C4E264F3078083F37F810003B +:1070C000B0B3A4222549204603F0E9F914F86F0F64 +:1070D00020F00700401C04F86D091C48006890F877 +:1070E000D70004F80E0B307837F81010208861F3C1 +:1070F0000B0024F8560B002004F85809E07F20F01C +:107100001F00E077A07F20F01F00A07734F8200F49 +:107110006FF30B00401C24F81C0914F8120900F04E +:10712000030000F07DFF2846FFF7A0FE0F4900E0B6 +:1071300005E0204601F099FD0020BDE8F081012026 +:10714000FBE7A422054903F0AAB90000A00710003C +:10715000648A0120549C100026081000AC9910008D +:107160003C081000516E0100D80710005370010058 +:10717000FE490F28096833D2DFE800F032080B0E11 +:107180001114171A1D202326292C2F0091F8210CE9 +:10719000704791F8220C704791F8230C704791F8D2 +:1071A000240C704791F8250C704791F8260C704715 +:1071B00091F8270C704791F8280C704791F8290C2A +:1071C000704791F82A0C704791F82B0C704791F892 +:1071D0002C0C704791F82D0C704791F82E0C7047CD +:1071E00091F8200C704770B5E04E0428346804F222 +:1071F000B26204F2A55518D0072824D00A2830D04E +:107200000B2833D0B4F8980694F8971602EB400098 +:1072100000F0D8FE306890F8911590F8920505EBD3 +:107220004000BDE8704000F0E4BEB4F89B0694F85E +:107230009A1602EB400000F0C5FE306890F89315F6 +:1072400090F89405EBE7B4F89E0694F89D1602EBCF +:10725000400000F0B7FE306890F8951590F896055C +:10726000DDE794F8A11594F8A205D8E794F8A315E2 +:1072700094F8A405D3E770B5060003D0BDE87040CC +:1072800000F041BE00F02EF801282AD1B84DB94CCB +:10729000287801281FD0B848A0606878E073E878A3 +:1072A000A073A87A2073287B6073E87984F83A0089 +:1072B000287A84F83B00AD48016891F8CD00C006FB +:1072C00007D591F89701C00703D0AC48A061012011 +:1072D00060753046D2E7AA79297AA74800F0C3FE44 +:1072E000DAE770BDA24B10B5D978A54C491CCAB2DB +:1072F000DA70997801208A420ED8197A9879414338 +:107300009D48FDF74DFE01F041FAA4F876009D4935 +:10731000204601F0AAFC002010BD38B5044601F05B +:1073200030FA954801F032FAA4F8760000F040FEF9 +:107330008E4D0B462A6892F8CE20C2F3411200927D +:107340000246204601F030FC00F037FE02460B46B4 +:10735000204601F055FCA07920F00200A07194F8BD +:107360006F0020F0070084F86F0094F86E0020F0A2 +:107370000F0084F86E00286890F8CE00C0F3411129 +:10738000204601F057FC286890F8CE1011F0600FED +:1073900094F85E107ED041F0010184F85E1090F800 +:1073A000CD004108E07961F3C710E071204600F09C +:1073B00069FE0521204601F014FA286890F8D700EC +:1073C000A0702868218EB0F8DD2062F308012186C4 +:1073D00090F8D80000F00F01204601F079FA2868F3 +:1073E000627D90F8D11061F303026275B0F8D3208A +:1073F000218A62F30B01218290F8D910A27D61F3FA +:107400000302A27510F8D81F0A09A17C62F30101DA +:10741000A17410F80B29920962F38711A174017805 +:10742000E27961F30002E271C178617200790109C9 +:10743000204601F059FA544801F0A8F9A4F87C005C +:10744000286810F8CF1F8A0814F8271F62F38301F9 +:10745000217010F8012962F300012170427852086E +:1074600062F34101217000780109607861F3041032 +:107470006070464801F08AF9A4F85F00286810F8A7 +:10748000CD1FCA0814F80C1F62F3451104F80B193C +:10749000427800E089E0217862F3451104F8281968 +:1074A0004078C0F34101204601F0ECF9286810F85B +:1074B000CD1F8A0914F8331F62F3000104F80B1979 +:1074C0000278520962F34101E172417B627961F312 +:1074D00004026271807B217960F304012171012033 +:1074E000FFF746FE94F8371060F3040184F8371074 +:1074F000274801F04BF9A4F85200286834F8061F19 +:10750000B0F8D52062F30B0124F8061B90F8C910DF +:1075100014F80A2C61F3030204F80A2C90F8C9103D +:107520000A0914F8091C62F3030104F8091C90F815 +:10753000CD108A0814F80C1C62F3000104F80C1C2E +:1075400090F8CD10CA09217862F3000104F82B1BD2 +:10755000217841F0200104F85F1990F89711C907CC +:1075600022D090F8CD00010914E00000A00710001F +:1075700028081000549C1000948B0120549E012078 +:10758000989B100027720100747701200C8701205E +:107590002C84012014F8330F61F304102070FE488E +:1075A00001F0F4F8A4F8450038BD21F00101F4E63B +:1075B00038B5044601F0E5F8F84801F0E7F8A4F81A +:1075C000760000F0F5FCF64D0B462A6892F8FF2A8B +:1075D000C2F3411200920246204601F0E5FA00F0A3 +:1075E000ECFC02460B46204601F00AFBA07920F095 +:1075F0000200A07194F86F0020F0070084F86F007B +:1076000094F86E0020F00F0084F86E00286890F85F +:10761000FF0AC0F34111204601F00CFB286890F8E6 +:10762000FF0A10F0600F94F85E007DD040F001007A +:1076300084F85E00204600F025FD286890F80A0BCB +:10764000A0702868218EB0F8102B62F30801218603 +:1076500090F80B0B00F00F01204601F039F9286873 +:10766000627D90F8021B61F303026275B0F8042B8F +:10767000218A62F30B01218290F80C1BA27D61F339 +:107680000302A275B0F8062BA18962F30B01A18158 +:1076900090F80B1B0A09A17C62F30101A17490F818 +:1076A0000B2B920962F38711A17490F8FE1AE2790C +:1076B00061F30002E27190F8011B617290F8020B15 +:1076C0000109204601F010F9B64801F05FF8A4F86E +:1076D0007C00286890F8001B8A0814F8271F62F3C2 +:1076E0008301217090F8002B62F30001217090F863 +:1076F000002B520862F34101217090F8FF0A010942 +:10770000607861F304106070A74801F03FF8A4F8B6 +:107710005F00286890F8FE1ACA0814F80C1F62F37C +:10772000451104F80B1900E066E090F8FF1A227882 +:1077300061F3451204F8282990F8FF0AC0F34101CB +:10774000204601F09FF8286890F8FE1A8A0914F87C +:10775000331F62F3000104F80B1990F8FE2A520956 +:1077600062F34101E17290F80D2B617962F304013B +:10777000617190F80E0B217960F3040121710A20E8 +:10778000FFF7F6FC94F8371060F3040184F8371023 +:10779000864800F0FBFFA4F85200286834F8061F62 +:1077A000B0F8082B62F30B0124F8061B10F8C91F70 +:1077B00014F80A2C61F3030204F80A2C01780A0970 +:1077C00014F8091C62F3030104F8091C90F8351A37 +:1077D0008A0814F80C1C62F3000104F80C1C90F8E1 +:1077E000350AC109207861F3000004F82B0B2078DA +:1077F00040F02000207038BD20F0010018E738B5B7 +:10780000044600F0BEFF654800F0C0FFA4F8760013 +:1078100000F0CEFB624D0B462A6892F8192BC2F39A +:10782000411200920246204601F0BEF900F0C5FB6D +:1078300002460B46204601F0E3F9A07920F0020051 +:10784000A07194F86F0020F0070084F86F0094F89E +:107850006E0020F00F0084F86E00286890F8190B75 +:10786000C0F34111204601F0E5F9286890F8190BA2 +:1078700010F0600F94F85E007DD040F0010084F8B5 +:107880005E00204600F0FEFB286890F8240BA070F4 +:107890002868218EB0F82A2B62F30801218690F81F +:1078A000250B00F00F01204601F012F82868627DD8 +:1078B00090F81C1B61F303026275B0F81E2B218A3D +:1078C00062F30B01218290F8261BA27D61F3030273 +:1078D000A275B0F8202BA18962F30B01A18190F869 +:1078E000251B0A09A17C62F30101A17490F8252BE4 +:1078F000920962F38711A17490F8181BE27961F381 +:107900000002E27190F81B1B617290F81C0B0109D8 +:10791000204600F0E9FF234800F038FFA4F87C007F +:10792000286890F81A1B8A0814F8271F62F383014D +:10793000217090F81A2B62F30001217090F81A2B35 +:10794000520862F34101217090F8190B0109607827 +:1079500061F304106070144800F018FFA4F85F0091 +:10796000286890F8181BCA0814F80C1F62F3451118 +:1079700004F80B1900E073E090F8191B227861F30A +:10798000451204F8282990F8190BC0F3410120464C +:1079900000F078FF28680BE0549E0120948B0120B2 +:1079A000A0071000747701200C8701202C8401208F +:1079B00090F8181B8A0914F8331F62F3000104F8C9 +:1079C0000B1990F8182B520962F34101E17290F8FB +:1079D000272B617962F30401617190F8280B2179FA +:1079E00060F3040121710B20FFF7C2FB94F83710FC +:1079F00060F3040184F83710FE4800F0C7FEA4F8D5 +:107A00005200286834F8061FB0F8222B62F30B01ED +:107A100024F8061B10F8C91F14F80A2C61F303029E +:107A200004F80A2C01780A0914F8091C62F303010E +:107A300004F8091C90F84F1A8A0814F80C1C62F319 +:107A4000000104F80C1C90F84F0AC109207861F37A +:107A5000000004F82B0B207840F02000207038BD87 +:107A600020F001000BE710B50446A422E24902F021 +:107A700016FDE2484179A08961F30B00A08110BD99 +:107A800038B50446FFF7EFFF00F092FA00220092AB +:107A900002460B46204601F087F8D94800F076FEF2 +:107AA000D84DA4F87C00286890F8DF00A070286802 +:107AB00090F8E00000F00F01204600F009FF286870 +:107AC00010F8E01F0A09A17C62F30101A174027899 +:107AD000920962F38711A174817894F82D2061F3E3 +:107AE000040284F82D20C17894F82C2061F304025C +:107AF00084F82C204078A17D60F30301A17500215A +:107B0000204601F097F814F85E0F20F00100207075 +:107B10000720FFF72DFB617860F30401617028688E +:107B200034F82E1CB0F8E42062F3080124F82E1C6F +:107B300010F8E11F0A0914F8371C62F3000104F879 +:107B4000371C0078400960F3410104F8371C38BD48 +:107B50002DE9F047AC4D4FF001094FF0000885F8D2 +:107B6000009085F8028085F80380064685F8078036 +:107B70002879A44F0C4628724FF0020A0F2A19D216 +:107B8000DFE802F0A208A2192DA220685273939791 +:107B9000A29B9F000846FFF766FF307D012809D1B0 +:107BA0006879287285F8079094F85E0020F001004B +:107BB00084F85E0088E0084600F0EAF8386890F83B +:107BC000E6002CE0084600F0E3F8386890F8E6009C +:107BD000C0F38100022825D985F802A074E0084688 +:107BE000FFF741FF386890F8E800A0700420FFF725 +:107BF000BFFA94F85F1060F3040184F85F10307DE1 +:107C0000012809D16879287285F8079094F85E00F8 +:107C100020F0010084F85E00386890F8E70000F07A +:107C20000300D7E7A8704FE00846FFF71CFF0021CC +:107C3000204600F04DFE14F85E0F20F00100207089 +:107C40000820FFF795FA14F8011F60F3040104F807 +:107C50005F1927E00846FFF713FF386890F8E9102E +:107C6000A08961F30B00A0812EE00846FFF708FF12 +:107C70000021204600F02CFE0920FFF779FA94F845 +:107C80005F1060F3040184F85F1094F85E0020F048 +:107C9000010084F85E00386890F8E910A08961F36B +:107CA0000B00A08185F800800EE00846FFF780FCFD +:107CB000F8E70846FFF7A3FDF4E7084600F075F87B +:107CC00002E00846E9F75FF894F82700C00702D001 +:107CD00085F8018001E085F80190386890F8BD1AB8 +:107CE000C90702D0317C012908D044480078A88116 +:107CF000A089C0F30B006881BDE8F087717C00F2B9 +:107D00007710415CA08961F30B00A081707CEEE7E5 +:107D100010B586B000F04CF9CDE9000100F04DF946 +:107D2000CDE902010821684601F0B8F9364C082176 +:107D3000207102A801F0B2F9A071DDE90001FDF7A0 +:107D4000CBFCCDE90401082104A801F0A7F960717A +:107D50002948FFF7E2FA06B010BD70B5264D047948 +:107D6000A4358CB122462946FFF7F2FEA87C00F02C +:107D7000030000F055F92046FFF735FA234928465D +:107D800000F073FF002070BD012070BD002070471F +:107D900010B50446FFF767FE0320FFF7E9F914F872 +:107DA0005F1F60F30401217010BD38B50446FFF772 +:107DB0005AFE00F0FDF80022009202460B462046D3 +:107DC00000F0F2FE0320A0700021204600F080FDAC +:107DD0000021204600F02EFF94F85E0020F0010004 +:107DE00084F85E00A07D20F00F00A075607D20F07B +:107DF0000F000DE02C840120F49A1000D807100029 +:107E00009C7C0120A00710002808100027720100A8 +:107E10006075208A6FF30B0000F6A6602082A089AF +:107E20006FF30B0000F6A660A081E08D6FF30B00EE +:107E3000E08538BD10B500F0B1F9FFF769FFFFF735 +:107E40009FF8FEF7EFFFFEF778FC424900204860FC +:107E5000BDE810407021404802F0A0BB38B10128B5 +:107E600007D0022807D017200021FCF7DAB8142029 +:107E7000FAE71520F8E71620F6E7182102F0B0BB64 +:107E800070B5344C354D206808E055F82010344862 +:107E90008847002817D02068401C20600928F4D3A8 +:107EA00060684EF66022401C00216060904200D362 +:107EB00061602B48183001706168416018380168B2 +:107EC00018308847012070BD10B50446007940B9CC +:107ED000E07930B9607A20B9607910B9A0790028CA +:107EE00010D01F483C21183002F07AFB182221469E +:107EF0001B4802F019FB1749002008601848FFF7DB +:107F0000BFFF012010BD70B5124C050016D0002037 +:107F100000F050F961684EF66020491C61608142B2 +:107F200001D3002060600E48183005706168416020 +:107F300018380168BDE87040183008472068401CB8 +:107F40002060BDE8704006489AE700F031B800F0C4 +:107F500034B80000380810000C87012090AA0100F6 +:107F60003C9C100070B5874B1B6893F80731DB070A +:107F70004FF000030ED0154609E031F9134031F9F6 +:107F800015603444641020F813405B1C6D1C934250 +:107F9000F3DB70BD144608E031F8135031F814607B +:107FA000354420F813505B1C641C9342F4DB70BD15 +:107FB00074480068C16A806A704772480068416A04 +:107FC000006A704730B5714C6F4B6268824202D1D3 +:107FD000E2688A420AD0002206E030F81250C5F367 +:107FE0000B0523F81250521C8A42F6DBE1606060F8 +:107FF00030BD30B5654C664BA268824202D1226921 +:108000008A420CD0002206E030F81250C5F30B056E +:1080100023F81250521C8A42F6DB2161A06030BD69 +:1080200070B504465B48016802290AD1574D29788A +:108030008C4206D000EB8400D0F89C0000F0B9FB25 +:108040002C7070BD10B5044690F82800800609D544 +:10805000514800F09BFB24F88E0F4F48203000F071 +:1080600095FB608010BD70477047704702004FF06D +:10807000000000D10846704702460020012A00D1C6 +:10808000084670473F4A116891F87D108B0910F837 +:108090003E1B63F3820100F83E1C136893F87D30A9 +:1080A0005B0963F3451100F83E1C1168B1F88520A7 +:1080B000028291F88420837F62F30713837791F81B +:1080C00081201309027D63F306120275B1F87F3037 +:1080D000028B63F30902028311F87D2F9308827DDE +:1080E00063F3861282750A79C37D62F30303C37555 +:1080F000B1F80530B0F81B2063F30802A0F81B208C +:1081000049894182704710F8371F41F0100100F88B +:108110001F1930F80C2CC17E6FF30B02103220F8BF +:108120000C2C30F8082C21F023016FF30B024032A5 +:1081300020F8082C082200F8162C90F8472041F06F +:108140000C0122F01F0280F84720028B6FF3080217 +:108150000283C176C18A6FF30B013F31C182417D39 +:1081600021F01F014175017D21F01F01017590F87B +:10817000461021F0010180F84610017C41F02001F9 +:1081800001747047A00710002C84012040081000E3 +:108190002C860120909C10009C860120704710B511 +:1081A00000F0A5FD08B1012010BD084800F088FDD1 +:1081B000002010BD064810B5006890F87100400717 +:1081C00001D500F089FD012010BD0000B77E01003F +:1081D000A00710003D48016821F00401016000F093 +:1081E0001DBF10B5FFF7F6FF10BD10B5FFF7F2FF8A +:1081F00010BD10B5FFF7EEFF10BD10B5FFF7EAFF99 +:1082000001F0BBFC10BD10B5FFF7E4FF00F0DEFA93 +:1082100010BD10B5FFF7DEFF01F085FD10BD10B5F4 +:10822000FFF7D8FF01F0C7FD10BD10B5FFF7D2FF73 +:1082300001F00AFE10BD10B5FFF7CCFF01F04FFEB4 +:1082400010BD10B5FFF7C6FF01F094FE10BD10B5CC +:10825000FFF7C0FF01F0D9FE10BD10B5FFF7BAFF60 +:1082600001F022FF10BD10B5FFF7B4FF02F01AFABB +:1082700010BD10B5FFF7AEFF02F0F0F910BD10B55C +:10828000FFF7A8FF10BD10B5FFF7A4FF10BD10B594 +:10829000FFF7A0FF10BD10B5FFF79CFF01F04AFFEC +:1082A00010BD10B5FFF796FF10BD10B5FFF792FF98 +:1082B00010BD10B5FFF78EFF10BD10B5FFF78AFF98 +:1082C00010BD10B5FFF786FF10BD704710ED00E040 +:1082D0000EB50BA007C88DE807000C4800F047FE5C +:1082E000684600F048FEFCF75FFCFCF7B3FA00F0CC +:1082F00037F800214720FBF794FE01200EBD000057 +:10830000110000000000000000000000670093233F +:108310001A4910B501200870194900200860194950 +:108320000860194908601949086000F07FF900F0F9 +:1083300019F900F07DF8002010BD10B5124801F0C9 +:1083400097FF104908600E490968884207D00B481A +:108350000078022803D1BDE81040E8F707B810BD47 +:1083600010B5FFF7EAFF054902200870E7F7E2FFC2 +:108370004FF0FF3010BD012070470000A40810002E +:10838000A8081000AC081000B0081000B4081000D5 +:1083900070B50D460446C1698068CC2202F0F6F83B +:1083A000E169A068002208444FF0807140F8041C85 +:1083B000216A40E9032140F8102C40F8142C40F8C1 +:1083C000182C40F81C2C4FF00B3140E909154FF0E8 +:1083D0000A3140F8281C4FF0093140F82C1C4FF0AE +:1083E000083140F8301C4FF0073140F8341C4FF092 +:1083F000063140F8381C4FF0053140F83C1C4FF076 +:10840000043140F8401D70BD81694FF0CC330A68DB +:108410009A4208D14A689A4205D18A689A4202D1A2 +:10842000C968994202D04068FCF759BA7047000009 +:1084300010B5A021494802F0D3F8002010BD70B556 +:108440000646464800EB0614E7F7C8FF05462078C5 +:1084500028B12846E7F7CAFF6FF0010070BD03207E +:10846000207000206660E06004F1080001F0DAFE90 +:108470002846E7F7BBFF002070BD2DE9F0410F460D +:108480003649002501EB00142E46E7F7A7FF80468A +:10849000E0683843E06004F10800074601F0E8FEB8 +:1084A0000CE0E168C26A114203D000F00FF9012626 +:1084B00000E06D1C2946384601F0D0FE0028F0D1BE +:1084C0000EB1FFF73AFF4046E7F790FF0020BDE806 +:1084D000F08170B50D46214901EB0014E7F77EFFEE +:1084E000E168A943E160E7F781FF002070BD70B546 +:1084F0000C461A4901EB001500202060E7F76EFFDB +:10850000E9682160E7F772FF002070BD2DE9F041B6 +:108510000D4612491E46904601EB0014E7F75EFF38 +:1085200007460F480068C562E168294203D104F19B +:10853000080100F0DDF83846E7F758FFE7F74EFF8F +:10854000E16829403160B8F1010F02D1E168A94327 +:10855000E160E7F74BFF0020B9E700003C9D100009 +:10856000A808100010B5C8212E4802F039F80020E4 +:1085700010BD2DE9F04106462A4900EB860017465A +:1085800001EB8004E7F72AFF0546207830B1284642 +:10859000E7F72CFF6FF00100BDE8F08102202070AA +:1085A00000206660C4E9027004F1100001F03AFE98 +:1085B0002846E7F71BFF0020EEE770B5194900EBEE +:1085C000800001EB8004E7F709FF0546D4E90201CA +:1085D000814205DB144804F11001006800F088F8BE +:1085E000E068401CE0602846E7F700FF002070BD0F +:1085F00070B50C4900EB800001EB8004E7F7EEFE5C +:108600000546E06808B1401EE06004F1100001F08A +:108610002FFE10B1206900F011F82846E7F7E6FEBA +:10862000002070BDDC9D1000A808100010B54FF4AC +:10863000F0713C4801F0D4FF002010BD10B5044695 +:1086400090F8240002280BD0204601F013FE0220EF +:1086500084F824003449204601F0E8FDFFF76DFE60 +:10866000002010BD2DE9F05F06460AA806EB460182 +:1086700090E8000E2B481D4600EB01149046207830 +:1086800018B16FF00100BDE8F09FE7F7A7FE0746BD +:1086900001202070C4F81480C4E9016504F11801B8 +:1086A000002081E8200684F82400E0602061C4E90D +:1086B0000A8059462046FFF76BFEA0602046FFF770 +:1086C000BDFF3846E7F792FE0020DCE710B5044610 +:1086D00090F82400022809D0204601F0CBFD0220AA +:1086E00084F824001049204601F0A0FD002010BDB0 +:1086F00070B5044690F824000D4602280BD12046A0 +:1087000001F0B8FD032084F824002946204601F03A +:108710008DFDFFF712FE002070BD04480068406820 +:1087200070470000A49E1000B0081000A8081000B8 +:10873000724810B500210160012202600160704C96 +:108740006920A0710420E7F75BFE0820A07110BD2E +:1087500010B5FFF7EDFF6B4800210170416000F09C +:108760001CFABDE8104000F012BB01F049BC01F05A +:1087700097BC10B501F094FC01F042FCBDE810403C +:10878000E6E7A422604901F08ABE704710B50446AE +:10879000800702D00220FFF761FB4FF480302044B5 +:1087A000C0F34F0010BD014655489822A43001F097 +:1087B00076BE534AA432002142F82100491C2629E2 +:1087C000FADB704701F04ABC01F0E4BB4D4810B53C +:1087D000406810B1BDE8104000470020FFF73EFBA5 +:1087E00010BD062937D2DFE801F011243724360303 +:1087F000017821F0120100F84D1B017821F00301EE +:1088000000F8071B017821F080010CE0017821F0CD +:10881000020141F0100100F84D1B017821F0030125 +:1088200000F8071B12E000F8441B017821F0010159 +:1088300010E00278012942F01202027000D00321F8 +:1088400010F84D2F61F3010200F8072B017841F079 +:108850008001E8E701707047017821F0020141F0E2 +:10886000100100F84D1B017821F00301891C00F86C +:10887000071B017841F0800100F8441B017841F0AA +:108880000101E7E790F82920022904D0032922F00A +:10889000400102D104E042F0400121F0800101E0FA +:1088A00041F0800180F82910704790F829200129B3 +:1088B00004D0022907D022F0100101E042F010019B +:1088C00021F0200101E042F0300180F829107047CA +:1088D000C278002961F30302C27004D010F85E1F51 +:1088E00041F0040101707047C27A012961F303026B +:1088F000C27202D942F01001C17270479004002286 +:108900000000032054081000B4AA010001EB81010B +:1089100002EBC101405C010602D500F07F0040423D +:108920007047002B04DA5B42DBB243F0800301E0C6 +:1089300003F07F0301EB810102EBC1014354704757 +:108940002DE9F05F0025DDE90A7891469A468346D5 +:108950002E462A460120002101F057FD00EA0900B9 +:1089600001EA0A01084314D0002422460120002114 +:1089700001F04BFD384001EA0801084305D000230F +:10898000224631465846FFF7CCFF641C282CECDB0E +:10899000761C6D1C382DDCDBBDE8F09F405C0106C9 +:1089A00002D500F07F0040427047002A04DA5242AC +:1089B000D2B242F0800201E002F07F0242547047DE +:1089C000F0B5002415460E468446234601270FE0E5 +:1089D00006EBE30003F00701007807FA01F2024218 +:1089E00005D0002219466046FFF7DFFF641C5B1CC0 +:1089F000AC42EDDBF0BD405C704742547047F0B5CF +:108A00000024234601260DE001EBE30503F00707F0 +:108A10002D7806FA07FC1CEA050F02D00025C55484 +:108A2000641C5B1C9442EFDBF0BD405C7047425419 +:108A30007047405C70474254704700002DE9F04792 +:108A4000334C54F83C8F6768E668257CDFF8C490A7 +:108A50000121C9F800104FF42070E7F7D1FC002184 +:108A6000C9F80010C4F800806760E6602574BDE8AE +:108A7000F08727480021C1630164816480F84C10AD +:108A8000704770B500240D4602460120214601F0D2 +:108A9000BCFC35B31E4A483210601171FFF7CEFF9F +:108AA000002000F023F800B10124FFF7C7FF0120E8 +:108AB00000F01CF808B144F00204FFF7BFFF0220E9 +:108AC00000F014F808B144F00404FFF7B7FF0320E6 +:108AD00000F00CF808B144F00804FFF7AFFF20469F +:108AE00070BD0B4A3C32C2E90001D7E740F02001DB +:108AF000074810B580F8A310E52181714FF420706C +:108B0000E7F77EFC0448D0F8C002C0B210BD0000F8 +:108B10000000032068146022001060225848416859 +:108B2000002901D001200847704710B5FFF71FFE4C +:108B30005449022008705449002008605048416898 +:108B4000002903D0BDE810400020084710BD10B533 +:108B5000817921F00D0141F0E0018171817C8A0968 +:108B600019D08A0962F38711464A81740321117072 +:108B7000454A464911600146A422454801F08FFC50 +:108B800044490120C1F8C0003D4843490088BDE880 +:108B90001040FFF717BE0122E4E739480021416089 +:108BA0004FF4FA71018070477FB504460399089D20 +:108BB000C1F314010391082102A800F06FFA012DFE +:108BC00002D0022D04D006E0C01C20F0010002E01B +:108BD000C01D20F00300DDE9021244F83C1F626072 +:108BE000217A60F3060121727FBD012340F83C3FEA +:108BF000002343605143027A61F306020272704718 +:108C00001FB50446039902A801F03F010391082112 +:108C100000F044FADDE90212A16484F84C2014F853 +:108C2000701F60F3050104F81E19E17F60F3050170 +:108C3000E1771FBD08B519A2126800921DF8012046 +:108C400010F85D1F62F30101017008BD0D4903209A +:108C500008700D490D4808600E490120C1F8C00098 +:108C600007480D490088FFF7ADBD054A51604FF434 +:108C7000FA7111806BE7024B59601A8067E70000B8 +:108C80005C0810005408100058081000DB8A01002E +:108C90000000032000006022CD8A010000010200D4 +:108CA00016480178012908D1022101701448016891 +:108CB00019B100220260104608470120FFF7CEB824 +:108CC0000E4A012111700E4908600E49E820887192 +:108CD0000D490C20FFF778BD0A49082088710B491F +:108CE000002008620549087005490860704703487C +:108CF0000078002800D001207047000054081000C0 +:108D00006408100000000320518C01000000602264 +:108D10006A484168002901D001200847704710B512 +:108D2000FFF725FD664902200870664900200860AB +:108D300062484168002903D0BDE810400020084780 +:108D400010BD10B5817C8A091FD08A0962F3871192 +:108D5000817481795A4A21F0010141F0E001817169 +:108D600004211170574A584911600146A4225748FE +:108D700001F095FB56490120C1F8C0004F48554904 +:108D80000088BDE81040FFF71DBD0122DEE74B481B +:108D9000002141604FF4FA71018070477FB50446AD +:108DA0000399089DC1F314010391082102A800F062 +:108DB00075F9DDE90212E163226494F84420C1B23E +:108DC00061F3060284F844200A2D0FD00B2D0DD03C +:108DD00014F8720F61F305002070607861F30500EC +:108DE0006070A07820F00800A0707FBD14F8721F9A +:108DF000401C60F305012170617860F3050161702A +:108E0000A07840F00800EFE71FB50446039902A8D8 +:108E100001F03F010391082100F040F9DDE9021261 +:108E2000A16484F84C2014F8701F60F3050104F865 +:108E30001E19E17F60F30501E1771FBD30B526A261 +:108E40008CB03CCA8DE83C0027A20DF1100C3CCA46 +:108E50008CE83C0028A20DF1200C3CCA8CE83C00B8 +:108E600004AA535C427E63F3050242761DF801308A +:108E7000027E63F34202027608AA525C817962F3B1 +:108E8000830181710CB030BD0D49042008700D497B +:108E90000D4808600E490120C1F8C00007480D497F +:108EA0000088FFF78FBC054A51604FF4FA711180BA +:108EB00047E7024B59601A8043E70000680810003A +:108EC0005408100058081000CF8C01000000032047 +:108ED00000006022C18C01000000020201010303B6 +:108EE000030300020000000002020202020202026A +:108EF0000101020201010000020302030203020356 +:108F000002030202020300004E49012008601722FA +:108F1000410701F8272F0B2281F8412049491839D0 +:108F200008604FF00851C1F8C403464B0022B0332B +:108F30001A60454A1060121D1060424A943A10604F +:108F4000C1F86803C1F8740370473E4901209439A1 +:108F5000086070473B4900209439086070474FF023 +:108F60000050008870474FF00050807870474FF0F5 +:108F7000005148607047354902680A6042684A609B +:108F800080688860704731490A6802604A684260B8 +:108F90008968816070472B4901203039086070472B +:108FA0004FF0005010F8221F21F0030101707047AC +:108FB0004FF0005303F81F0F5970987862F30300C5 +:108FC00098707047224800687047214908607047D0 +:108FD00010B54FF00054E27E202322F0AF0203EAE6 +:108FE00040131343042202EA8000034301F003000C +:108FF0000343E37610BD4FF0005090F8220010F0CC +:10900000030005D0012805D0022805D0114870477B +:1090100011487047114870471148704770477047B2 +:1090200010490120C1F8DC0070470E490020C1F84A +:10903000DC0070470348F030006808B10120704739 +:1090400002207047CC040022801E0022080000206D +:109050007008100000127A000090D0030048E80168 +:109060000024F40000006022F0B50746002003460B +:109070002F4E10E057F8235003224FEAC20C45FA56 +:109080000CF484EA2064E4B2521E56F8244084EAC8 +:109090000020F2D55B1C8B42ECDBF0BD30B5044602 +:1090A000234B0020103B08E0625C02F00F0503EB4D +:1090B00012125D5D127828441044491EF4D230BD6E +:1090C00010B584680368E443A3420AD1C4684368C6 +:1090D000E443A34205D15B1C0B60006810600120D3 +:1090E00010BD002010BD3CB50446002501AA69460C +:1090F000FFF7E6FF012809D1009904F11000091FCC +:10910000FFF7B2FF0199884200D1012528463CBDF6 +:1091100030B50D460446091F1030FFF7A5FF6D1E40 +:109120006560E943E1602060C043A06030BD00009D +:1091300068AB010001468000B1F5803F02D21038D3 +:10914000C0F310007047C0F387207047B0F5802F40 +:1091500002D21030C0F31000C0F38F00704730B55A +:10916000F94C01252560E50603F01F0385F86B30F7 +:10917000002304E051F8235040F823505B1C934235 +:10918000F8DB0020206030BDF0B5EF4F01233B60DD +:109190005C0784F86B309B1E0360002312E051F8DB +:1091A000234040F82340002450F8235051F8236016 +:1091B000B54206D06D1C04D1641C40F82360032C1A +:1091C000F2D35B1C9342EADB00203860F0BDF0B5BF +:1091D00013460A460546002498184FF48326602853 +:1091E00001D9012411E0002107E05F1856F827009B +:1091F000401C01D011460224491C9142F5D324B9E8 +:1092000006EB83002946FFF7BFFF2046F0BD10B5EF +:1092100003460846FFF78EFF0146BDE81040920066 +:10922000184601F081B92DE9F0414FF000580C4685 +:10923000D8F814700125C0F38F066FF48041C8F888 +:1092400014100E2000F02EFA204600F036FA02002C +:10925000BE484FF0010118D00160A4F580344046AB +:1092600020F8726F4480602200F8012CB84A116027 +:10927000B64AC432116030BF81797238890700D094 +:10928000002547612846BDE8F08100220260E6E73C +:109290002DE9F05F1546DFF8B0B2002601270A4637 +:1092A00004464FF0005CB1F5882F15D3A30AFFF7F1 +:1092B00041FF5946CBF8007003F01F038CF86B3068 +:1092C000002304E052F8234040F823405B1CAB42EB +:1092D000F8DB0E60BDE8F09FDCF81490C1F38F0856 +:1092E000E2466FF48041CCF814100E2000F0DAF959 +:1092F000CBF80070204600F0E0F90100934819D047 +:109300000760A4F58034AAF87280AAF874406D1E34 +:10931000AAF8765040218AF871108D490E608B4969 +:10932000C4310F600AF1520030BFCBF8006040F842 +:109330003E9CCFE70660E6E72DE9F0414FF0005490 +:109340000F4654F8146F85086FF4804020600E209B +:1093500000F0A8F90020A066A4F85E507F1EA4F8D3 +:10936000627084F85D007A49086078490120C43150 +:10937000086030BFE06E266085E770B506460C4693 +:1093800001F11000111F154689B2FFF7D5FF2060CB +:10939000681E606020682A46C043A060606821465D +:1093A000C043E0603046BDE8704071E7F0B5074665 +:1093B00000200446674E15E057F8245003234FEA77 +:1093C000C30C45FA0CF280EA02600822002802DA97 +:1093D00086EA400000E04000521E002AF6DC5B1ED8 +:1093E000EDD5641C8C42E7DBF0BD30B550F8084B7E +:1093F00050F8085B30F80C1C491C89B2FFF7D6FF07 +:10940000844204D1E043854201D1012030BD0020D7 +:1094100030BD2DE9F0410126750704466F696FF4F0 +:10942000804068610E2000F03DF94FF00008C5F85B +:109430007C80204600F041F9020044494FF00100D1 +:1094400015D00860A4F58034A5F87440202185F873 +:1094500071103F4908603D49C431086030BF95F83C +:109460007800800700D000266F6130460BE7C1F816 +:109470000080E9E700B50B46FFF75CFE82680168F3 +:10948000D243914208D14268C068C043824203D1AE +:10949000521C1A80012000BD002000BDF8B5044612 +:1094A00010300D460646FFF7BEFE012801D0002011 +:1094B000F8BD69462846FFF7DDFFBDF80000001F34 +:1094C00081B23046FFF738FF2060BDF80010C0437E +:1094D000491E6160A060C843E0600120F8BD2DE92D +:1094E000F041B0B01C4C80466E46002505AFC0214F +:1094F000684601F075F8002054F8201046F8201056 +:10950000401C3028F8D31549009804F5805488424F +:1095100010D1029881B23846FFF748FF0199814285 +:1095200006D1AC223946404600F0FEFF002002E0A2 +:10953000032000E001206D1CEDB2032D01D20328B1 +:10954000D5D030B09FE60000C41B0022780D002269 +:109550001C0F00221B000080481D0400B2570E7033 +:109560002DE9F04794B0584D00260446E8463746AA +:1095700045F2AA5A6FF002095021684601F030F80E +:10958000002055F8202048F82020401C1428F8D34B +:109590004E49009805F5805588420ED14FF0FF30B6 +:1095A00020606060A060E0602061029881B205A840 +:1095B000FFF7FCFE019981420AD0C4F80090C4F87C +:1095C0000490C4F80890C4F80C90C4F810901EE001 +:1095D000BDF83810504681420CD19DF81D10216015 +:1095E0009DF81C1001F00F0161609DF81E1001F044 +:1095F0000F01A160BDF83C10814201D10899E160E2 +:10960000BDF84010514501D1099820610127761C11 +:10961000F6B2032E01D2002FAED014B0BDE8F08711 +:1096200070B586B0284E04466D46B43614212846DF +:1096300000F0D6FF002156F8210045F82100491C12 +:109640000529F8D300982060019860600298C0B2A4 +:10965000A0600398C0B2E0600498C0B2206106B078 +:1096600070BD1CB50020184A009030326B46014690 +:10967000019052F8214043F82140491C0229F8D3B7 +:10968000BDF80010A1F5AA42AA3A0AD1BDF80420FB +:10969000114206D19DF802109DF80620114200D11A +:1096A00008461CBD00F01F020121914040098000C6 +:1096B00000F1E020C0F880127047B0F5803F01D281 +:1096C0000020704701207047AC1E04005C000D6054 +:1096D0004FF00050002180F83D1080F83E1080F8D7 +:1096E0003F103F2280F8322000F8301F0271417194 +:1096F0004270017241728172C172C17170474FF044 +:109700000052062817D2DFE800F00306090F171AE7 +:1097100012F83D0F04E012F83D0F07E012F83E0F7B +:1097200020F00F00084305E012F83E0F20F0F00093 +:1097300040EA01101070704712F83F0FF0E712F87E +:109740003F0FF3E730B50D4601218140CCB2002137 +:10975000FFF7D5FF29784FF00050002990F832101C +:1097600001D0214300E0A14380F83210697800293C +:1097700090F8301001D0214300E0A14380F8301070 +:10978000A978002990F8341001D0214300E0A143CA +:1097900080F83410E978002990F8351001D0214381 +:1097A00000E0A14380F835102979002990F83110A4 +:1097B00001D0214300E0A14380F83110002180F85E +:1097C000381080F8391080F83A1080F83B1080F893 +:1097D000371030BD774A1160764A0021343211606B +:1097E000121D08B11160704701201060704730B53C +:1097F00001248440E0B24FF000540029039D94F806 +:10980000321001D0014300E0814384F8321094F813 +:1098100030100AB1014300E0814384F8301094F81D +:1098200034100BB1014300E0814384F8341014F884 +:10983000351F0DB1014300E08143217030BD01238C +:109840008340D8B24FF00053002993F8381001D06C +:10985000014300E0814383F8381013F8391F0AB13F +:10986000014300E081431970704701238340D8B25F +:109870004FF00053002993F83A1001D0014300E063 +:10988000814383F83A1013F83A1F0AB1014300E00C +:109890008143197070472DE9F04705460120A84023 +:1098A000C4B21F46914688460A20DDF820A000F089 +:1098B0006BF80B2000F068F80A2000F070F80B201D +:1098C00000F06DF84FF0005696F83800A04386F887 +:1098D000380096F83A00A04386F83A0096F82E0031 +:1098E000A04386F82E00344A0020B8F1000F42F859 +:1098F00025000BD096F83810214386F8381096F8DA +:109900003A10214386F83A1042F8257096F839103B +:10991000A14386F8391096F83B10A14386F83B1016 +:1099200096F82F10A14386F82F1023492031B9F162 +:10993000000F41F825000BD096F83900204386F837 +:10994000390096F83B00204386F83B0041F825A0FB +:1099500096F8380010B10A2000F00BF896F839009C +:10996000002804D0BDE8F0470B2000F002B8BDE8A5 +:10997000F08700F01F02012191404009800000F1B2 +:10998000E020C0F80011704700F01F020121914053 +:109990004009800000F1E020C0F88011704700F01D +:1099A0001F02012191404009800000F1E020C0F831 +:1099B000801270470405002284A010002DE9F047B2 +:1099C000417ACA074FF0000101D0554A5160012782 +:1099D0007D0785F8E57085F8E470C5F8C010C5F816 +:1099E000E81085F8E11085F8E310DFF838A1067A71 +:1099F00004680AF10709072E00D9072600216DE047 +:109A00004A1CD3B201EB810214F802800AF80180EB +:109A1000D0F804C022443CF8118029F8118092F853 +:109A200003C0BCF1010F02D0BCF1030F07D195F8C0 +:109A3000E5C007FA03F84CEA080C85F8E5C090F891 +:109A400009C05FEACC7C0FD192F803C0BCF1020FD1 +:109A500002D0BCF1030F07D195F8E4C007FA03F870 +:109A60004CEA080C85F8E4C001EB410C21F0010838 +:109A7000E04492F801C00CF0070C0CFA08FCD5F891 +:109A8000C0804CEA080CC5F8C0C092F802C04FEA8A +:109A900081080CF00F0C0CFA08FCD5F8E8804CEAB1 +:109AA000080CC5F8E8C090F809C05FEACC7C14D176 +:109AB0001279D20707D095F8E12007FA03FC42EAB1 +:109AC0000C0285F8E1202279D20606D595F8E3202C +:109AD00007FA03F31A4385F8E320491CB1428FD3F8 +:109AE000D5F8E8006864BDE8F0870E4AD21D22F878 +:109AF0001010704710B504460B48006838B1A068D4 +:109B0000FFF75CFF2068BDE8104000F00FB8E06888 +:109B1000FFF754FF6068BDE8104000F0C1BB0000D3 +:109B200000200022AB000020BC05002210B5494BEC +:109B30000168002499608188598002899A801C708C +:109B40004FF00053A3F81A21A3F81E11C088A3F800 +:109B5000200141480122C0F8D821C0F8DC21C0F81A +:109B6000C421C0F8CC21C0F8D42172B6D0F80812B4 +:109B70000029FBD1426062B610BD2DE9F041364D9F +:109B8000D5F85C01334F2E040124BA6840B3B6F80F +:109B90001C815FEA08000CD0D5F8540148B1414659 +:109BA00001209047C5F8D842D5F8540108B1C5F84E +:109BB000D442BA684146022090470178022902D077 +:109BC000032902D008E0418800E07988A6F81E1138 +:109BD0008088A6F81A013C70C5F8DC42BDE8F08127 +:109BE000D5F8440180B1B6F81C11032090473878AD +:109BF00038B17888A6F81E01B888A6F81A010020A6 +:109C00003870C5F8C442E9E7D5F8580130B1B6F864 +:109C10001C1101209047C5F8D842DFE7D5F84C0168 +:109C200018B9D5F854010028D8D0B6F81C1119B1CC +:109C300001209047C5F8D842D5F84C0110B1C5F8BD +:109C4000CC42CBE7D5F854010028C7D0C5F8D442A0 +:109C5000C4E700007408100000200022FC49002026 +:109C60000860091D0860091D0860091D0860091DBC +:109C70000860091D0860091D0860091D0860F54994 +:109C800001220A60F34914310860510701F8500FAE +:109C9000FF234B7001F8050C10234B808A80EE499E +:109CA000086048608860C860086148618861C86170 +:109CB000086270477047E84A1160E54900220A606F +:109CC00000EB80004FF6FF7202EA40004FF00052B6 +:109CD000A2F85800012008607047DF4B10B5DC4A3D +:109CE0001960002111604FF0005191F85140E407D4 +:109CF00007D01B6A58438009A1F858000120106062 +:109D000010BD00EBC00303EB00104FF6FF7303EA36 +:109D10008000F1E74FF00050B0F858007047CC4990 +:109D2000002008607047CC4A10B50021106811600F +:109D3000C74A116010B1BDE8104000470020FFF78E +:109D4000B9FF10BDC44A5160C1490022091D0A6013 +:109D500000EB80004FF6FF7202EA4000CA06A2F84C +:109D60005A00012008607047BB4B10B55960B84AD3 +:109D70000021121D1160D10691F85140A40708D4AA +:109D800000EBC00303EB00104FF6FF7303EA800003 +:109D900002E01B6A58438009A1F85A0001201060B4 +:109DA00010BD4FF00050B0F85A007047A84900208D +:109DB000091D08607047A84A10B50021506851601D +:109DC000A34A121D116010B1BDE8104000470120E8 +:109DD000FFF770FF10BDA04A91609D490022083135 +:109DE0000A6000EB80004FF6FF7202EA40008A062C +:109DF000A2F85C00012008607047974B10B599608D +:109E0000934A002108321160910691F8514064078D +:109E100008D400EBC00303EB00104FF6FF7303EA16 +:109E2000800002E01B6A58438009A1F85C00012011 +:109E3000106010BD4FF00050B0F85C0070478449CE +:109E40000020083108607047834A10B500219068EF +:109E500091607F4A0832116010B1BDE810400047A0 +:109E60000220FFF727FF10BD7B4AD160784900220E +:109E70000C310A6000EB80004FF6FF7202EA4000EE +:109E80004FF00052A2F85E00012008607047724B4C +:109E900010B5D9606E4A00210C3211604FF00051AC +:109EA00091F85140240708D400EBC00303EB0010E5 +:109EB0004FF6FF7303EA800002E01B6A58438009F3 +:109EC000A1F85E000120106010BD4FF00050B0F806 +:109ED0005E0070475E4900200C31086070475E4AA2 +:109EE00010B50021D068D160594A0C32116010B110 +:109EF000BDE8104000470320FFF7DCFE10BD564AC6 +:109F000011615349002210310A6000EB80004FF6C6 +:109F1000FF7202EA40004FF00052A2F860000120F8 +:109F2000086070474C4B10B51961494A0021103246 +:109F300011604FF0005191F85140E40608D400EB55 +:109F4000C00303EB00104FF6FF7303EA800002E04A +:109F50001B6A58438009A1F860000120106010BD01 +:109F60004FF00050B0F860007047394900201031C0 +:109F700008607047384A10B5002110691161344AF1 +:109F80001032116010B1BDE8104000470420FFF707 +:109F900091FE10BD304A51612D49002214310A60F2 +:109FA00000EB80004FF6FF7202EA40004FF00052D3 +:109FB000A2F86200012008607047274B10B5596174 +:109FC000234A0021143211604FF0005191F85140A2 +:109FD000A40608D400EBC00303EB00104FF6FF7398 +:109FE00003EA800002E01B6A58438009A1F862007E +:109FF0000120106010BD4FF00050B0F862007047B3 +:10A0000013490020143108607047134A10B500212D +:10A01000506951610E4A1432116010B1BDE8104010 +:10A0200000470520FFF746FE10BD0B4A9161084925 +:10A03000002218310A6000EB80004FF6FF7202EA3E +:10A0400040004FF00052A2F8640001200860704701 +:10A0500040090022C0040022800810006A4B10B59D +:10A060006A4A9961002111604FF0005191F8514006 +:10A07000640608D400EBC00303EB00104FF6FF7337 +:10A0800003EA800002E01B6A58438009A1F86400DB +:10A090000120106010BD4FF00050B0F86400D6E70A +:10A0A0005A4900200860D2E7574A10B5002190694C +:10A0B0009161564A116010B1BDE81040004706207A +:10A0C000FFF7F8FD10BD10B5FEF77CFF4FF0005113 +:10A0D00091F8222042F21073B0FBF3F0C2F3810238 +:10A0E000521CD040B1F85420C96C51438909B0FBCF +:10A0F000F1F010BD45490022091D0A60424A126A6A +:10A1000050434FF000528009A2F866000120086019 +:10A110009DE73E490020091D086098E73A49C8615B +:10A120003B490120C1F8DC003849A0310860091D15 +:10A1300008608CE7344A10B50020D169D061344AF8 +:10A14000C2F8DC0051B1314AA03210604FF000502B +:10A15000C06CBDE8104020F07F400847FF20FFF7AB +:10A16000A9FD10BD10B50446FEF72CFF4FF00051BD +:10A1700091F8221042F21072B0FBF2F0C1F38101AB +:10A18000491CC8400003B0FBF4F01F49086210BD31 +:10A1900030B54FF000550124844095F8510009B1C5 +:10A1A000204300E0A04385F8510095F84B000AB128 +:10A1B000204300E0A04385F84B0015F8500F0BB189 +:10A1C000204300E0A043287030BD4FF0005010F84D +:10A1D0004A1FC079814301D0012038E7002036E7CB +:10A1E0004FF0005090F82200C0F3810028B1012800 +:10A1F00005D0022805D0074829E7074827E7074880 +:10A2000025E7074823E700008008100058090022CE +:10A210000000602200093D000048E8010024F4002D +:10A2200000127A00002101600846704730B50A68C4 +:10A2300012B10B46846A08E000220860C0E90321DD +:10A240000AE002F10C03D26812B1956AA542F8DC6B +:10A250001A68C0E903211860002030BD00680022A0 +:10A2600001E0C068521C8A4201D00028F9D1704731 +:10A270000068704702690AB1116831B96FF00400D3 +:10A28000704701F10C02C96839B18142F9D1C9683E +:10A29000116000210161084670476FF003007047AC +:10A2A000017C31B14FF0005111F82D2F42F0020224 +:10A2B0000A70194902680A6042684A6082688A60C6 +:10A2C000C068C860704730B44FF0005111F8E00F1B +:10A2D0000A8AC968104BC40708D09B68002B0BD0B2 +:10A2E000A2F57F44FF3C07D030BC1847DB68002B49 +:10A2F00002D0521C92B2F7E730BC70474FF00050CA +:10A3000090F8E2000449C20701D0096800E04968FA +:10A31000002900D008477047B808100053EA020C23 +:10A3200000F069802DE9F04B4FF00006002B1FBFB5 +:10A33000B3FA83F503FA05F424FA05F65E4012BF7A +:10A340001643B2FA82F502FA05F4C5F120051EBFE4 +:10A3500022FA05FC44EA0C04203556EA044C4FEA84 +:10A36000144418BF641C4FF000084FF000099042DD +:10A3700071EB030C39D3002919BFB1FA81F701FA47 +:10A3800007F6B0FA80F700FA07F6C7F120071EBFFC +:10A3900020FA07FC46EA0C062037B6FBF4FCA7EBD4 +:10A3A0000507103F07F01F0BCBF120060CFA0BFB43 +:10A3B0002CFA06F644BFB3460026202FA4BF5E4603 +:10A3C0004FF0000B5BEA060C08BF4FF0010B19EBD6 +:10A3D0000B09ABFB027C48EB0608C01B06FB02CC5A +:10A3E0000BFB03CC71EB0C01C1E70B460246414667 +:10A3F0004846BDE8F08B13B54FF000004FF0000168 +:10A40000AFF30080BDE81C407047B2F120030AD5CD +:10A41000C2F1200301FA02F120FA03F300FA02F07C +:10A4200041EA0301704700FA03F14FF00000704762 +:10A43000B2F120030AD5C2F1200320FA02F001FA9A +:10A4400003F321FA02F140EA0300704721FA03F016 +:10A450004FF00001704710B54C1084EA530404D546 +:10A460004042C1F1000138BF491E1B4204D552428F +:10A47000C3F1000338BF5B1EFFF750FF14F0804F9D +:10A4800004D04042C1F1000138BF491E14F0004F12 +:10A4900004D05242C3F1000338BF5B1E10BD032A33 +:10A4A00040F2308010F0030C00F0158011F8013BF1 +:10A4B000BCF1020F624498BF11F801CB00F8013BD8 +:10A4C00038BF11F8013BA2F1040298BF00F801CB9C +:10A4D00038BF00F8013B11F0030300F02580083A73 +:10A4E000C0F0088051F8043B083A51F804CBA0E8CA +:10A4F0000810F5E7121D5CBF51F8043B40F8043B1F +:10A50000AFF30080D20724BF11F8013B11F801CB53 +:10A5100048BF11F8012B24BF00F8013B00F801CB24 +:10A5200048BF00F8012B704710B5203AC0F00B80EF +:10A53000B1E81850203AA0E81850B1E81850A0E847 +:10A540001850BFF4F5AF5FEA027C24BFB1E81850A1 +:10A55000A0E8185044BF18C918C0BDE810405FEA11 +:10A56000827C24BF51F8043B40F8043B08BF70478D +:10A57000D20728BF31F8023B48BF11F8012B28BF92 +:10A5800020F8023B48BF00F8012B704702F0FF03A0 +:10A5900043EA032242EA024200F002B84FF000020E +:10A5A0000429C0F0128010F0030C00F01B80CCF1E5 +:10A5B000040CBCF1020F18BF00F8012BA8BF20F853 +:10A5C000022BA1EB0C0100F00DB85FEAC17C24BFA7 +:10A5D00000F8012B00F8012B48BF00F8012B704751 +:10A5E0004FF0000200B5134694469646203922BF2C +:10A5F000A0E80C50A0E80C50B1F12001BFF4F7AF77 +:10A60000090728BFA0E80C5048BF0CC05DF804EB58 +:10A61000890028BF40F8042B08BF704748BF20F8C6 +:10A62000022B11F0804F18BF00F8012B704710B5B6 +:10A630000446AFF300802046BDE81040E5F7EEBDCC +:10A6400001491820ABBEFEE726000200704700005B +:10A650000149002008607047380500222DE9F041CB +:10A660000F4F00244FF001084FF0005608FA04F095 +:10A67000C5B296F82F0028420CD096F8390028422F +:10A6800008D057F8240000B1804796F82F00A8435F +:10A6900086F82F00641C062CE8DBBDE8F081000082 +:10A6A000A4A010002DE9F0410F4F00244FF0010845 +:10A6B0004FF0005608FA04F0C5B296F82E00284272 +:10A6C0000CD096F83800284208D057F8240000B182 +:10A6D000804796F82E00A84386F82E00641C062CAE +:10A6E000E8DBBDE8F081000084A01000012181407A +:10A6F000C8B24FF0005191F83310014201D001204F +:10A700007047002070470000014901200860704731 +:10A710003805002200487047E50710000549044A43 +:10A720000A80054AC0E90021012101724172704787 +:10A73000185701208807100074A90100014800780B +:10A7400070470000B0061000014800787047000014 +:10A750009005100006488178012905D80178012963 +:10A7600002D84078012801D90120704700207047A5 +:10A770009826012005488178012902D8007801280F +:10A7800001D9012070470020704700009826012061 +:10A7900070B5D0E9001253084FEA31044E1842EB6D +:10A7A000020534432B430C431343C0E9004370BDFF +:10A7B00001EB810100EBC10029307047024A127899 +:10A7C000514300EB410070472507100001EB810168 +:10A7D00000EBC10029307047024A1278514300EB68 +:10A7E0004100704725071000010000001000000024 +:10A7F00004000000010000003200000032000000F0 +:10A80000FFFF000000FF0100FF0000010000010148 +:10A810005AD3D9E96CF145F59FF73CF96CFA58FB2E +:10A8200018FCB9FC44FDBFFD2EFE94FEF4FE50FF63 +:10A83000A9FF00005700B0000C016C01D2014102D9 +:10A84000BC024703E803A8049405C4066108BB0AD8 +:10A85000940E2716A62C0100010001000100020041 +:10A8600001000100010001000A00FF00FF000000DC +:10A870000001010102020000000000009C531000D2 +:10A88000E8581000A932010002000000AD320100BA +:10A8900002000000373401000200000075320100A0 +:10A8A00002000000E5330100010000003733010021 +:10A8B00007000000D7320100090000000734010042 +:10A8C00001000000F3320100080000006F340100B5 +:10A8D000010000008734010001000000793201000E +:10A8E00003350100FF34010005360100FF3401008B +:10A8F0004F370100FF340100FF340100FF34010035 +:10A90000FF340100FF3401004F3501000100000059 +:10A910007D35010000000000FF3401000000000050 +:10A920009B350100010000003536010001000000E8 +:10A9300059360100010000005D36010001000000F1 +:10A9400093360100040000004B37010001000000B5 +:10A950007F37010001000000F33701000100000013 +:10A960000938010002000000653801000200000003 +:10A97000AF38010002000000DB39010001000000D7 +:10A980001B3A010001000000AB380100020000008A +:10A99000A339010002000000FF34010000000000A4 +:10A9A0007B39010002000000993701007335010076 +:10A9B000A3370100B3370100C3370100D3370100CB +:10A9C000E33701008600020100A6020F0300A8027F +:10A9D0000B0300000300000000000000530400000F +:10A9E0000000000003000000000000005300000011 +:10A9F000000000004300000000000000F300000021 +:10AA000000000000E300000000000000530200000E +:10AA10000000000000000000050000005884100045 +:10AA2000000400004D3D0000000000000200000096 +:10AA3000010000000400000058881000000400001D +:10AA4000C54C0000000000000200000002000000F1 +:10AA500003000000588C10000008000025300100A1 +:10AA600000000000020000000300000002000000DF +:10AA70005894100000020000D93A010000000000C4 +:10AA800002000000040000000100000058961000C1 +:10AA900080000000E1310100000000000200000021 +:10AAA00000000000010000000100000001000000A3 +:10AAB000020000000100000003000000010000008F +:10AAC000040000000100000005000000010000007B +:10AAD0000000000001000000020000000300000070 +:10AAE0004F810100597001000967010009700100E0 +:10AAF0005D6D0100E76C0100BF6F01000B7D01007F +:10AB0000658101000004400010210000001F0100C9 +:10AB1000060000003000010000040600080250009A +:10AB200060020C0C000060020C300C1A31100F0F88 +:10AB300000002F000100AA2C01000000030000000B +:10AB4000FFFF03000000000018000000FFFFFFFFF0 +:10AB50003F000000000000000001000000000000B5 +:10AB6000600201800001000000000C000C000C00DD +:10AB70000C00070126261212110000000038003CCC +:10AB8000203DD041EC4108421C42304244426042E8 +:10AB900074428842A442000000000000000000004F +:10ABA0000000000000000020000101020102020379 +:10ABB0000102020302030304000000001B000080E6 +:10ABC0002D00008036000000410000805A00000087 +:10ABD0006C00000077000080990000808200000077 +:10ABE000B4000000AF000080D8000000C300008067 +:10ABF000F5000080EE000000290100803201000015 +:10AC0000040100001F010080680100007301008042 +:10AC1000450100805E010000B0010000AB01008032 +:10AC20009D01008086010000F1010080EA01000022 +:10AC3000DC010000C70100804902008052020000D0 +:10AC4000640200007F0200800802000013020080FE +:10AC5000250200803E020000D0020000CB020080EE +:10AC6000FD020080E6020000910200808A020000DE +:10AC7000BC020000A7020080600300007B0300808C +:10AC80004D03008056030000210300803A030000BA +:10AC90000C03000017030080F9030080E2030000AA +:10ACA000D4030000CF030080B8030000A30300809A +:10ACB000950300808E030000890400809204000048 +:10ACC000A4040000BF040080C8040000D304008076 +:10ACD000E5040080FE040000100400000B04008066 +:10ACE0003D04008026040000510400804A04000056 +:10ACF0007C04000067040080A0050000BB05008004 +:10AD00008D05008096050000E1050080FA05000031 +:10AD1000CC050000D7050080390500802205000021 +:10AD2000140500000F050080780500006305008011 +:10AD3000550500804E050000C0060000DB060080BF +:10AD4000ED060080F6060000810600809A060000ED +:10AD5000AC060000B70600805906008042060000DD +:10AD6000740600006F0600801806000003060080CD +:10AD7000350600802E060000E9070080F20700007B +:10AD8000C4070000DF070080A8070000B3070080A9 +:10AD9000850700809E070000700700006B07008099 +:10ADA0005D07008046070000310700802A07000089 +:10ADB0001C07000007070080090900801209000035 +:10ADC000240900003F090080480900005309008061 +:10ADD000650900807E090000900900008B09008051 +:10ADE000BD090080A6090000D1090080CA09000041 +:10ADF000FC090000E7090080200800003B080080F3 +:10AE00000D08008016080000610800807A08000024 +:10AE10004C08000057080080B9080080A208000014 +:10AE2000940800008F080080F8080000E308008004 +:10AE3000D5080080CE080000400B00005B0B0080AE +:10AE40006D0B0080760B0000010B00801A0B0000D8 +:10AE50002C0B0000370B0080D90B0080C20B0000C8 +:10AE6000F40B0000EF0B0080980B0000830B0080B8 +:10AE7000B50B0080AE0B0000690A0080720A00006A +:10AE8000440A00005F0A0080280A0000330A00809C +:10AE9000050A00801E0A0000F00A0000EB0A00808C +:10AEA000DD0A0080C60A0000B10A0080AA0A00007C +:10AEB0009C0A0000870A0080800D00009B0D008026 +:10AEC000AD0D0080B60D0000C10D0080DA0D000050 +:10AED000EC0D0000F70D0080190D0080020D000040 +:10AEE000340D00002F0D0080580D0000430D008030 +:10AEF000750D00806E0D0000A90C0080B20C0000E2 +:10AF0000840C00009F0C0080E80C0000F30C008013 +:10AF1000C50C0080DE0C0000300C00002B0C008003 +:10AF20001D0C0080060C0000710C00806A0C0000F3 +:10AF30005C0C0000470C0080C90F0080D20F00009D +:10AF4000E40F0000FF0F0080880F0000930F0080C7 +:10AF5000A50F0080BE0F0000500F00004B0F0080B7 +:10AF60007D0F0080660F0000110F00800A0F0000A7 +:10AF70003C0F0000270F0080E00E0000FB0E008059 +:10AF8000CD0E0080D60E0000A10E0080BA0E00008B +:10AF90008C0E0000970E0080790E0080620E00007B +:10AFA000540E00004F0E0080380E0000230E00806B +:10AFB000150E00800E0E000098AF01000004100076 +:10AFC000C80400001C01000000B0010000FC1000DB +:10AFD000400000007801000000B00100C808100027 +:10AFE000FC9700009401000001FF014A0022481074 +:10AFF000070C1502050609040E08030B1218130DA1 +:10B000001416171A0F111B1D191C201E1F010A21CF +:10B0100012FF3206320F9A37089AE10823D303143D +:10B02000905F017201A908091A0CB264290C291455 +:10B030005A02040A11041001FF01660799F0012069 +:10B040001C6210AAFF0C5901011D045490D003008A +:10B0500030B572B601230C4D2B600C4A002481B12F +:10B0600013604FF0005100F01F0081F86A0007489C +:10B070001C38036001680029FCD114602C6062B6A2 +:10B0800030BD1460EDE70000C01B0022780D0022E7 +:10B09000DBD3C21951030000242C3DE6AEFCFFFFB8 +:10B0A0000000070003070000071200000000000076 +:10B0B000F8FFFFFF3F000000FFFF0000000000005E +:10B0C0002310230937040B2309370444020103002A +:10B0D0000320200AAA99FA00FA00B004C80000016F +:10B0E0000001000100017000700009C800C80000E4 +:10B0F000000000960096000000000003AA44020031 +:10B100000015080A190FF902320000000016001E8F +:10B11000000008000600000000A050502601350085 +:10B12000000000001300000000009603000064000F +:10B130000000FF00E02E01FF000000004050007002 +:10B140000032004000C80000000001640064006498 +:10B15000001000000000000000FFFF0000BDA00A7A +:10B160004F2500260025004B600600000000004B24 +:10B1700060160000000004014B024B06008D110810 +:10B180004F0400300006002F0040100600000001B0 +:10B190000000A8606A1F200036002700500026002B +:10B1A000A023A0132D0066000000000000029600FE +:10B1B000960002050132190500001D040000000080 +:10B1C000010000002D0000008F00000000000000C2 +:10B1D0000000000000010100003030008F0000007E +:10B1E000000000000000000000010030010000002D +:10B1F000000F0000000000000000111A0000000015 +:10B2000000036402130A0403070B02023210000059 +:10B210000000000F0000000000FF0FFF0F0A141EC7 +:10B220000E01640001016400001400000A005000D7 +:10B23000000000D00F149001900180008000F40104 +:10B240000000FA086400640020000A6400640064DE +:10B2500000640003052C01F40100C2018A026400AD +:10B260009600031B039600FA00FA0001010100E8B2 +:10B2700003DC05C800FA00020B02FA00F401F40135 +:10B28000000101003B0164006400B4002C012C01AA +:10B2900005FCA121025E01640096F4013200F40174 +:10B2A000960096006400010096009600030E64006C +:10B2B000200058023214001E2003042C01960000C6 +:10B2C000000000008F01100050004000A00000A40A +:10B2D0000F28009600C800320096002300C800C85E +:10B2E00000C800F40123005000041004020105000E +:10B2F000C800C4090000310010FF7F5E01A00FD01C +:10B3000002D002080708070807000000000000003C +:10B310000D42200010122C012C019D00000A000F8C +:10B320006400411278009600C800C80000B004FA1A +:10B330000096B80BE8030000000001006400070D50 +:10B340000DE803A000005E01645E016400000000DF +:10B35000250B01008A028A02408A02C201F4010020 +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000008C001E2803050202EF +:10B380000213115546000003C8006432001E066413 +:10B390001E5E01012800F401FAF4010069F7EA00D9 +:10B3A000D4013801EA006400040C03320302400AAD +:10B3B000039C009C000F000F00109D004E00C80071 +:10B3C0000001010011000100101F00000A0014918B +:10B3D0001514001000061000060040000040001088 +:10B3E0000A0F0A200310EB0520D80532F80A32F8BC +:10B3F0000000EAECECC4E810003000CBE80A0018CA +:10B4000000C6F80A000A0051E494941844070007A3 +:10B41000001000300002D73A7E2858026400C800AD +:10B4200000015A005A005000500001000015151587 +:10B4300015008164643C042C01401FE80390012F37 +:10B44000000405401F9001BC02B60301B603028848 +:10B4500013000000000000000000000000000000D9 +:10B460000000000000000300020A3C0001020F0F70 +:10B470002323083C083C40F805050A0A0105050F8E +:10B48000140000014E0C09180C0C222222000000AE +:10B490000000000A00140032006400BF08F1080F29 +:10B4A00009190923092309000000000A00140032C9 +:10B4B000006400D303050423042D0437043704007B +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000100090020004500DD20 +:10B4E00008070919091F09230923090000000002A0 +:10B4F000000A0028005600E80314042C0434043722 +:10B5000004370400000000000000000000000000FC +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B620000008000000000000000000000000000012 +:10B630000004000000A4060000000000000000005C +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B00000000000000000A8A02A1F20003600277C +:10B6C0000050002600A023A0132D006600000000FB +:10B6D00000000000005028502814B020A0D0000620 +:10B6E00014142A3A400000146E6E471A38010F1ED7 +:10B6F000002000000FE80A0030000F510000000099 +:10B7000004640010FF7F0B646400000A201405F835 +:10B71000000000000006080F160672390002F5E16D +:10B72000826E4632020000960000960000960000ED +:10B730005AE0005AE0000000000000000000000095 +:10B7400000007B007B007D00800085008A00910066 +:10B750009900A300AD00B900C500D300E200F200DB +:10B760000301160129013D01520167017E01960185 +:10B77000AE01C701E001FA01150230024C02680275 +:10B780008502A202BF02DD02FA0218033603530348 +:10B7900071038F03AC03CA03E703030420043C04D2 +:10B7A000570472048D04A704C004D904F0040705EB +:10B7B0001E05330548055B056E057F0590059F0551 +:10B7C000AE05BB05C705D205DC05E505EC05F305AF +:10B7D000F805FB05FE05FF05FF05FE05FB05F80561 +:10B7E000F305EC05E505DC05D205C705BB05AE058F +:10B7F0009F0590057F056E055B05480533051E0511 +:10B800000705F004D904C004A7048D04720457048A +:10B810003C0420040304E703CA03AC038F03710351 +:10B82000530336031803FA02DD02BF02A2028502A7 +:10B8300068024C0230021502FA01E001C701AE01B4 +:10B8400096017E01670152013D01290116010301A4 +:10B85000F200E200D300C500B900AD00A3009900DA +:10B8600091008A00850080007D007B007B00000045 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B9000000007B007D0082008B009700A600B9003C +:10B91000CF00E80005012401450169019001B9014A +:10B92000E3010F023D026C029C02CD02FF023103D3 +:10B9300062039403C503F603250454048104AC0494 +:10B94000D604FE0423054605660584059F05B60555 +:10B95000CB05DC05EA05F405FB05FF05FF05FB0546 +:10B96000F405EA05DC05CB05B6059F0584056605EB +:10B9700046052305FE04D604AC04810454042504C2 +:10B98000F603C503940362033103FF02CD029C0258 +:10B990006C023D020F02E301B9019001690145010A +:10B9A00024010501E800CF00B900A60097008B0034 +:10B9B00082007D007B00000000000000000000000D +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000500050000AC +:10BA900032460000000000000000000047B400C86B +:10BAA00000010A00000096006400B400010AB4001E +:10BAB0006400010AB80BC409050200F401F4010591 +:10BAC000022003C80028000A0050003200000000D5 +:10BAD0000200020001280102010204020102010029 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000010000F4 +:10BB50000000000000000000010000B80B052602F4 +:10BB60002C01C800FA000003E8038001E8018813F3 +:10BB7000B80B400F400F0000204E0514003C1E4043 +:10BB80001F000000D007F4012C0100011400CD01BA +:10BB9000094F05003C000200230045600603030036 +:10BBA0000000FFBB0000C8008D00091F08002A012B +:10BBB0000200290128A00600000000000000004D3E +:10BBC0003D3D3E3E3F404040404243434444454665 +:10BBD00046474848494A4B4B4B4C4B4C4D4E4E4CBC +:10BBE00061000000004D403F40414345444545460B +:10BBF000474749494A4B4B4C4D4D4E4F5050505181 +:10BC000050505152525561000000004D3D3D3E3EA6 +:10BC10003F414142424445454748494A4B4C4D4EBD +:10BC20004E4F5050505150505151525264000000EC +:10BC3000004D4343434445474847484A4B4B4D4DCD +:10BC40004E505052535354555656555555545555BC +:10BC5000555764000000004B383837373739393AC8 +:10BC60003A3C3D3D3E3E3E3F3F40404041424343E3 +:10BC7000434442424343434258000000004B3F3D8F +:10BC80003F3E3F414140414243424545464546478C +:10BC9000474748494A4A494A4748494A494C58004F +:10BCA0000000001415072108210000000001000019 +:10BCB0000001000101000001010105010000010077 +:10BCC000010000010000010100010000010100006D +:10BCD000C8B60181029D066D071E0A141E0A1400D3 +:10BCE0000100C8AA018E020B07EF07461246120A8E +:10BCF0000C0C00200A0A00000000000000000000F8 +:10BD0000310096001E28000000051E00FA00000009 +:10BD1000500A052806640A02C80000030090016466 +:10BD2000FA00C000000004100A00100000961E0077 +:10BD30000F6414000000000000000000000000027A +:10BD400002505000460AC800100400000000000025 +:10BD50000001800CF00AD000800CF00AD000001521 +:10BD6000001250015001001500125001800CF00A21 +:10BD7000D0000000000000009600F4010003C8009D +:10BD80002F07C8006F03106464C80064001000101F +:10BD9000001096006400960064009600640096000F +:10BDA000640010000000000000000000000000001F +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:0CBDD000000000000000000043C6B0E2CC +:00000001FF diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index dae4dde06926..7048ef8ca1a9 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h @@ -418,6 +418,7 @@ #define BTN_WHEEL 0x150 #define BTN_GEAR_DOWN 0x150 #define BTN_GEAR_UP 0x151 +#define BTN_INFO 0x152 #define KEY_OK 0x160 #define KEY_SELECT 0x161 From a645ae3e579da35a9b802b90c9fe780fc77e1ab8 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 6 Nov 2023 11:50:55 +0100 Subject: [PATCH 056/226] drivers: input: touchscreen: xiaomi: Use MSM DRM notifier Change-Id: I7ceaeb165b790ba69621074a7470569acf1f07aa Signed-off-by: firebird11 --- .../input/touchscreen/xiaomi/fts_521/fts.c | 30 +++--- .../goodix_driver_gt9886/goodix_cfg_bin.c | 4 +- .../goodix_driver_gt9886/goodix_ts_core.c | 21 ++-- .../goodix_driver_gt9886/goodix_ts_core.h | 2 +- .../touchscreen/xiaomi/nt36523/nt36xxx.c | 100 ++++++++---------- .../touchscreen/xiaomi/nt36523/nt36xxx.h | 4 +- .../touchscreen/xiaomi/nt36672c/nt36xxx.c | 20 ++-- 7 files changed, 85 insertions(+), 96 deletions(-) diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts.c b/drivers/input/touchscreen/xiaomi/fts_521/fts.c index e03e326c2241..f00d2eb9cce4 100644 --- a/drivers/input/touchscreen/xiaomi/fts_521/fts.c +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts.c @@ -56,7 +56,7 @@ #include #ifdef CONFIG_DRM -#include +#include #endif #include @@ -1235,7 +1235,7 @@ static ssize_t stm_fts_cmd_show(struct device *dev, goto END; } #ifdef CONFIG_DRM - res = drm_unregister_client(&info->notifier); + res = msm_drm_unregister_client(&info->notifier); if (res < 0) { logError(1, "%s ERROR: unregister notifier failed!\n", tag); @@ -1467,7 +1467,7 @@ static ssize_t stm_fts_cmd_show(struct device *dev, res = ERROR_OP_NOT_ALLOW; } #ifdef CONFIG_DRM - if (drm_register_client(&info->notifier) < 0) { + if (msm_drm_register_client(&info->notifier) < 0) { logError(1, "%s ERROR: register notifier failed!\n", tag); } #endif @@ -4738,7 +4738,7 @@ static int fts_init_sensing(struct fts_ts_info *info) { int error = 0; #ifdef CONFIG_DRM - error |= drm_register_client(&info->notifier); + error |= msm_drm_register_client(&info->notifier); #endif error |= fts_interrupt_install(info); error |= fts_mode_handler(info, 0); @@ -5794,7 +5794,7 @@ static int fts_drm_state_chg_callback(struct notifier_block *nb, { struct fts_ts_info *info = container_of(nb, struct fts_ts_info, notifier); - struct drm_notify_data *evdata = data; + struct msm_drm_notifier *evdata = data; unsigned int blank; logError(0, "%s %s: fts notifier begin!\n", tag, __func__); @@ -5804,20 +5804,22 @@ static int fts_drm_state_chg_callback(struct notifier_block *nb, logError(1, "%s %s: val:%lu,blank:%u\n", tag, __func__, val, blank); - if (val == DRM_EARLY_EVENT_BLANK && - (blank == DRM_BLANK_POWERDOWN || blank == DRM_BLANK_LP1 || - blank == DRM_BLANK_LP2)) { + if (val == MSM_DRM_EARLY_EVENT_BLANK && + (blank == MSM_DRM_BLANK_POWERDOWN || + blank == MSM_DRM_BLANK_LP1 || + blank == MSM_DRM_BLANK_LP2)) { if (info->sensor_sleep) return NOTIFY_OK; logError(1, "%s %s: FB_BLANK %s\n", tag, __func__, - blank == DRM_BLANK_POWERDOWN ? "POWER DOWN" : - "LP"); + blank == MSM_DRM_BLANK_POWERDOWN ? + "POWER DOWN" : + "LP"); flush_workqueue(info->event_wq); queue_work(info->event_wq, &info->suspend_work); - } else if (val == DRM_EVENT_BLANK && - blank == DRM_BLANK_UNBLANK) { + } else if (val == MSM_DRM_EVENT_BLANK && + blank == MSM_DRM_BLANK_UNBLANK) { if (!info->sensor_sleep) return NOTIFY_OK; @@ -7363,7 +7365,7 @@ static int fts_probe(struct spi_device *client) kfree(info->dma_buf->wrBuf); #endif #ifdef CONFIG_DRM - drm_unregister_client(&info->notifier); + msm_drm_unregister_client(&info->notifier); #endif ProbeErrorExit_6: @@ -7412,7 +7414,7 @@ static int fts_remove(struct spi_device *client) fts_interrupt_uninstall(info); /*backlight_unregister_notifier(&info->bl_notifier);*/ #ifdef CONFIG_DRM - drm_unregister_client(&info->notifier); + msm_drm_unregister_client(&info->notifier); #endif /* unregister the device */ diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_cfg_bin.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_cfg_bin.c index d1025106a6a5..ee539cdcf643 100644 --- a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_cfg_bin.c +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_cfg_bin.c @@ -1,5 +1,5 @@ #include "goodix_cfg_bin.h" -#include +#include extern int goodix_i2c_write(struct goodix_ts_device *dev, unsigned int reg, unsigned char *data, unsigned int len); @@ -291,7 +291,7 @@ int goodix_cfg_bin_proc(void *data) #ifdef CONFIG_DRM core_data->fb_notifier.notifier_call = goodix_ts_fb_notifier_callback; - if (drm_register_client(&core_data->fb_notifier)) + if (msm_drm_register_client(&core_data->fb_notifier)) ts_err("Failed to register fb notifier client:%d", r); #elif defined(CONFIG_HAS_EARLYSUSPEND) core_data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c index 37eadcd09e81..3ba99ad25043 100644 --- a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c @@ -28,7 +28,7 @@ #include #include #ifdef CONFIG_DRM -#include +#include #include #include #endif @@ -1903,27 +1903,28 @@ int goodix_ts_fb_notifier_callback(struct notifier_block *self, { struct goodix_ts_core *core_data = container_of(self, struct goodix_ts_core, fb_notifier); - struct drm_notify_data *fb_event = data; + struct msm_drm_notifier *fb_event = data; int blank; if (fb_event && fb_event->data && core_data) { blank = *(int *)(fb_event->data); flush_workqueue(core_data->event_wq); - if (event == DRM_EVENT_BLANK && - (blank == DRM_BLANK_POWERDOWN || blank == DRM_BLANK_LP1 || - blank == DRM_BLANK_LP2)) { + if (event == MSM_DRM_EVENT_BLANK && + (blank == MSM_DRM_BLANK_POWERDOWN || + blank == MSM_DRM_BLANK_LP1 || + blank == MSM_DRM_BLANK_LP2)) { ts_info("touchpanel suspend .....blank=%d\n", blank); ts_info("touchpanel suspend .....suspend_stat=%d\n", atomic_read(&core_data->suspend_stat)); if (atomic_read(&core_data->suspend_stat)) return 0; ts_info("touchpanel suspend by %s", - blank == DRM_BLANK_POWERDOWN ? "blank" : - "doze"); + blank == MSM_DRM_BLANK_POWERDOWN ? "blank" : + "doze"); queue_work(core_data->event_wq, &core_data->suspend_work); - } else if (event == DRM_EVENT_BLANK && - blank == DRM_BLANK_UNBLANK) { + } else if (event == MSM_DRM_EVENT_BLANK && + blank == MSM_DRM_BLANK_UNBLANK) { //if (!atomic_read(&core_data->suspend_stat)) ts_info("core_data->suspend_stat = %d\n", atomic_read(&core_data->suspend_stat)); @@ -2845,7 +2846,7 @@ static int goodix_ts_remove(struct platform_device *pdev) { struct goodix_ts_core *core_data = platform_get_drvdata(pdev); #ifdef CONFIG_DRM - drm_unregister_client(&core_data->fb_notifier); + msm_drm_unregister_client(&core_data->fb_notifier); #endif //wake_lock_destroy(&core_data->tp_wakelock); power_supply_unreg_notifier(&core_data->power_supply_notifier); diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.h b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.h index c6033562578a..ac6600cf8b36 100644 --- a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.h +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.h @@ -48,7 +48,7 @@ #include #endif #ifdef CONFIG_DRM -#include +#include #include #include #endif diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c index 1851c7c5b5e6..39f9746cda1f 100644 --- a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c @@ -27,10 +27,9 @@ #include #include -#if defined(CONFIG_FB) #ifdef CONFIG_DRM -#include -#endif +#include +#elif defined(CONFIG_FB) #include #include #elif defined(CONFIG_HAS_EARLYSUSPEND) @@ -75,14 +74,12 @@ static struct workqueue_struct *nvt_lockdown_wq; extern void Boot_Update_Firmware(struct work_struct *work); #endif -#if defined(CONFIG_FB) #ifdef CONFIG_DRM static int nvt_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data); -#else +#elif defined(CONFIG_FB) static int nvt_fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data); -#endif #elif defined(CONFIG_HAS_EARLYSUSPEND) static void nvt_ts_early_suspend(struct early_suspend *h); static void nvt_ts_late_resume(struct early_suspend *h); @@ -3260,22 +3257,20 @@ static int32_t nvt_ts_probe(struct spi_device *client) ret); goto err_register_pen_charge_state_failed; } -#if defined(CONFIG_FB) #ifdef CONFIG_DRM ts->drm_notif.notifier_call = nvt_drm_notifier_callback; - ret = drm_register_client(&ts->drm_notif); + ret = msm_drm_register_client(&ts->drm_notif); if (ret) { NVT_ERR("register drm_notifier failed. ret=%d\n", ret); goto err_register_drm_notif_failed; } -#else +#elif defined(CONFIG_FB) ts->fb_notif.notifier_call = nvt_fb_notifier_callback; ret = fb_register_client(&ts->fb_notif); if (ret) { NVT_ERR("register fb_notifier failed. ret=%d\n", ret); goto err_register_fb_notif_failed; } -#endif #elif defined(CONFIG_HAS_EARLYSUSPEND) ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; ts->early_suspend.suspend = nvt_ts_early_suspend; @@ -3318,16 +3313,14 @@ static int32_t nvt_ts_probe(struct spi_device *client) return 0; -#if defined(CONFIG_FB) #ifdef CONFIG_DRM - if (drm_unregister_client(&ts->drm_notif)) + if (msm_drm_unregister_client(&ts->drm_notif)) NVT_ERR("Error occurred while unregistering drm_notifier.\n"); err_register_drm_notif_failed: -#else +#elif defined(CONFIG_FB) if (fb_unregister_client(&ts->fb_notif)) NVT_ERR("Error occurred while unregistering fb_notifier.\n"); err_register_fb_notif_failed: -#endif #elif defined(CONFIG_HAS_EARLYSUSPEND) unregister_early_suspend(&ts->early_suspend); err_register_early_suspend_failed: @@ -3438,14 +3431,12 @@ static int32_t nvt_ts_remove(struct spi_device *client) { NVT_LOG("Removing driver...\n"); -#if defined(CONFIG_FB) #ifdef CONFIG_DRM - if (drm_unregister_client(&ts->drm_notif)) + if (msm_drm_unregister_client(&ts->drm_notif)) NVT_ERR("Error occurred while unregistering drm_notifier.\n"); -#else +#elif defined(CONFIG_FB) if (fb_unregister_client(&ts->fb_notif)) NVT_ERR("Error occurred while unregistering fb_notifier.\n"); -#endif #elif defined(CONFIG_HAS_EARLYSUSPEND) unregister_early_suspend(&ts->early_suspend); #endif @@ -3524,14 +3515,12 @@ static void nvt_ts_shutdown(struct spi_device *client) nvt_irq_enable(false); -#if defined(CONFIG_FB) #ifdef CONFIG_DRM - if (drm_unregister_client(&ts->drm_notif)) + if (msm_drm_unregister_client(&ts->drm_notif)) NVT_ERR("Error occurred while unregistering drm_notifier.\n"); -#else +#elif defined(CONFIG_FB) if (fb_unregister_client(&ts->fb_notif)) NVT_ERR("Error occurred while unregistering fb_notifier.\n"); -#endif #elif defined(CONFIG_HAS_EARLYSUSPEND) unregister_early_suspend(&ts->early_suspend); #endif @@ -3773,12 +3762,11 @@ static int32_t nvt_ts_resume(struct device *dev) return 0; } -#if defined(CONFIG_FB) #ifdef CONFIG_DRM static int nvt_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data) { - struct drm_notify_data *evdata = data; + struct msm_drm_notifier *evdata = data; int *blank; struct nvt_ts_data *ts_data = container_of(self, struct nvt_ts_data, drm_notif); @@ -3788,22 +3776,22 @@ static int nvt_drm_notifier_callback(struct notifier_block *self, if (evdata && ts_data) { blank = evdata->data; - if (event == DRM_EARLY_EVENT_BLANK) { - if (*blank == DRM_BLANK_POWERDOWN) { + if (event == MSM_DRM_EARLY_EVENT_BLANK) { + if (*blank == MSM_DRM_BLANK_POWERDOWN) { NVT_LOG("event=%lu, *blank=%d\n", event, *blank); flush_workqueue(ts_data->event_wq); queue_work(ts_data->event_wq, &ts_data->suspend_work); } - } else if (event == DRM_R_EARLY_EVENT_BLANK) { - if (*blank == DRM_BLANK_POWERDOWN) { + } else if (event == MSM_DRM_R_EARLY_EVENT_BLANK) { + if (*blank == MSM_DRM_BLANK_POWERDOWN) { NVT_LOG("event=%lu, *blank=%d\n", event, *blank); nvt_enable_doubleclick(); } - } else if (event == DRM_EVENT_BLANK) { - if (*blank == DRM_BLANK_UNBLANK) { + } else if (event == MSM_DRM_EVENT_BLANK) { + if (*blank == MSM_DRM_BLANK_UNBLANK) { NVT_LOG("event=%lu, *blank=%d\n", event, *blank); flush_workqueue(ts_data->event_wq); @@ -3815,7 +3803,7 @@ static int nvt_drm_notifier_callback(struct notifier_block *self, return 0; } -#else +#elif defined(CONFIG_FB) static int nvt_fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) { @@ -3840,8 +3828,33 @@ static int nvt_fb_notifier_callback(struct notifier_block *self, return 0; } +#elif defined(CONFIG_HAS_EARLYSUSPEND) +/******************************************************* +Description: + Novatek touchscreen driver early suspend function. + +return: + n.a. +*******************************************************/ +static void nvt_ts_early_suspend(struct early_suspend *h) +{ + nvt_ts_suspend(ts->client, PMSG_SUSPEND); +} + +/******************************************************* +Description: + Novatek touchscreen driver late resume function. + +return: + n.a. +*******************************************************/ +static void nvt_ts_late_resume(struct early_suspend *h) +{ + nvt_ts_resume(ts->client); +} #endif +#ifdef CONFIG_PM static int nvt_pm_suspend(struct device *dev) { if (device_may_wakeup(dev) && ts->db_wakeup) { @@ -3870,31 +3883,6 @@ static const struct dev_pm_ops nvt_dev_pm_ops = { .suspend = nvt_pm_suspend, .resume = nvt_pm_resume, }; - -#elif defined(CONFIG_HAS_EARLYSUSPEND) -/******************************************************* -Description: - Novatek touchscreen driver early suspend function. - -return: - n.a. -*******************************************************/ -static void nvt_ts_early_suspend(struct early_suspend *h) -{ - nvt_ts_suspend(ts->client, PMSG_SUSPEND); -} - -/******************************************************* -Description: - Novatek touchscreen driver late resume function. - -return: - n.a. -*******************************************************/ -static void nvt_ts_late_resume(struct early_suspend *h) -{ - nvt_ts_resume(ts->client); -} #endif static const struct spi_device_id nvt_ts_id[] = { { NVT_SPI_NAME, 0 }, {} }; diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.h b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.h index fcc59ba5cf78..2f79af798a64 100644 --- a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.h +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.h @@ -146,12 +146,10 @@ struct nvt_ts_data { struct notifier_block pen_charge_state_notifier; uint16_t addr; int8_t phys[32]; -#if defined(CONFIG_FB) #ifdef CONFIG_DRM struct notifier_block drm_notif; -#else +#elif defined(CONFIG_FB) struct notifier_block fb_notif; -#endif #elif defined(CONFIG_HAS_EARLYSUSPEND) struct early_suspend early_suspend; #endif diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c index cb4c52513ded..bb18ef46c2e1 100644 --- a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c +++ b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c @@ -33,7 +33,7 @@ #include #ifdef CONFIG_DRM -#include +#include #endif #include @@ -2680,7 +2680,7 @@ static int32_t nvt_ts_probe(struct platform_device *pdev) #ifdef CONFIG_DRM ts->drm_notif.notifier_call = nvt_drm_notifier_callback; - ret = drm_register_client(&ts->drm_notif); + ret = msm_drm_register_client(&ts->drm_notif); if (ret) { NVT_ERR("register drm_notifier failed. ret=%d\n", ret); goto err_register_drm_notif_failed; @@ -2735,7 +2735,7 @@ static int32_t nvt_ts_probe(struct platform_device *pdev) return 0; #ifdef CONFIG_DRM - if (drm_unregister_client(&ts->drm_notif)) + if (msm_drm_unregister_client(&ts->drm_notif)) NVT_ERR("Error occurred while unregistering drm_notifier.\n"); err_register_drm_notif_failed: #else @@ -2830,7 +2830,7 @@ static int32_t nvt_ts_remove(struct platform_device *pdev) NVT_LOG("Removing driver...\n"); #ifdef CONFIG_DRM - if (drm_unregister_client(&ts->drm_notif)) + if (msm_drm_unregister_client(&ts->drm_notif)) NVT_ERR("Error occurred while unregistering drm_notifier.\n"); #else if (fb_unregister_client(&ts->fb_notif)) @@ -2904,7 +2904,7 @@ static void nvt_ts_shutdown(struct platform_device *pdev) nvt_irq_enable(false); #ifdef CONFIG_DRM - if (drm_unregister_client(&ts->drm_notif)) + if (msm_drm_unregister_client(&ts->drm_notif)) NVT_ERR("Error occurred while unregistering drm_notifier.\n"); #else if (fb_unregister_client(&ts->fb_notif)) @@ -3139,7 +3139,7 @@ static int32_t nvt_ts_resume(struct device *dev) static int nvt_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data) { - struct drm_notify_data *evdata = data; + struct msm_drm_notifier *evdata = data; int *blank; struct nvt_ts_data *ts_data = container_of(self, struct nvt_ts_data, drm_notif); @@ -3148,15 +3148,15 @@ static int nvt_drm_notifier_callback(struct notifier_block *self, blank = evdata->data; NVT_LOG("%s: event:%lu,blank:%u\n", event, blank); - if (event == DRM_EARLY_EVENT_BLANK) { - if (*blank == DRM_BLANK_POWERDOWN) { + if (event == MSM_DRM_EARLY_EVENT_BLANK) { + if (*blank == MSM_DRM_BLANK_POWERDOWN) { NVT_LOG("event=%lu, *blank=%d\n", event, *blank); flush_workqueue(ts_data->event_wq); nvt_ts_suspend(&ts_data->client->dev); } - } else if (event == DRM_EVENT_BLANK) { - if (*blank == DRM_BLANK_UNBLANK) { + } else if (event == MSM_DRM_EVENT_BLANK) { + if (*blank == MSM_DRM_BLANK_UNBLANK) { NVT_LOG("event=%lu, *blank=%d\n", event, *blank); flush_workqueue(ts_data->event_wq); From 341dbd00ef558b196062d09ef1361de0f246d66b Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 11 Oct 2023 15:37:05 +0200 Subject: [PATCH 057/226] drivers: input: touchscreen: xiaomi: Drop touch_irq_boost Change-Id: I0f82537d75f453fc88e389d494117b34cd7cdc4f Signed-off-by: firebird11 --- drivers/input/touchscreen/xiaomi/fts_521/fts.c | 1 - drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c | 2 -- drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c | 3 --- 3 files changed, 6 deletions(-) diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts.c b/drivers/input/touchscreen/xiaomi/fts_521/fts.c index f00d2eb9cce4..965d0214e0f7 100644 --- a/drivers/input/touchscreen/xiaomi/fts_521/fts.c +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts.c @@ -151,7 +151,6 @@ static int fts_chip_initialization(struct fts_ts_info *info, int init_type); static const char *fts_get_limit(struct fts_ts_info *info); static irqreturn_t fts_event_handler(int irq, void *ts_info); extern void lpm_disable_for_input(bool on); -extern void touch_irq_boost(void); /** * Release all the touches in the linux input subsystem diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c index 39f9746cda1f..4e1bdb5f4795 100644 --- a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c @@ -89,7 +89,6 @@ static int32_t nvt_ts_suspend(struct device *dev); static int32_t nvt_ts_resume(struct device *dev); extern int dsi_panel_lockdown_info_read(unsigned char *plockdowninfo); extern void dsi_panel_doubleclick_enable(bool on); -extern void touch_irq_boost(void); extern void lpm_disable_for_input(bool on); extern int pen_charge_state_notifier_register_client(struct notifier_block *nb); extern int @@ -1664,7 +1663,6 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) } #endif - touch_irq_boost(); lpm_disable_for_input(true); mutex_lock(&ts->lock); diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c index bb18ef46c2e1..93ba8565e00a 100644 --- a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c +++ b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c @@ -97,7 +97,6 @@ extern void dsi_panel_doubleclick_enable(bool on); #ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE static int32_t nvt_check_palm(uint8_t input_id, uint8_t *data); #endif -extern void touch_irq_boost(void); extern void lpm_disable_for_input(bool on); uint32_t ENG_RST_ADDR = 0x7FFF80; uint32_t SWRST_N8_ADDR = 0; /* read from dtsi */ @@ -1419,8 +1418,6 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) pm_wakeup_event(&ts->input_dev->dev, 5000); } #endif - if (ts->debug_flag == TOUCH_IRQ_BOOST) - touch_irq_boost(); mutex_lock(&ts->lock); if (ts->debug_flag >= TOUCH_DISABLE_LPM) lpm_disable_for_input(true); From 0bc9a89b48f929fccbcc1d1850ec57332370411a Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Sun, 28 Jan 2024 03:09:02 +0100 Subject: [PATCH 058/226] drivers: input: touchscreen: xiaomi: Drop lpm_disable_for_input Change-Id: I3b8c72c63dc3e20c00e54ef28925126345075a38 Signed-off-by: firebird11 --- drivers/input/touchscreen/xiaomi/fts_521/fts.c | 10 ---------- .../input/touchscreen/xiaomi/nt36523/nt36xxx.c | 6 ------ .../input/touchscreen/xiaomi/nt36672c/nt36xxx.c | 17 ----------------- 3 files changed, 33 deletions(-) diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts.c b/drivers/input/touchscreen/xiaomi/fts_521/fts.c index 965d0214e0f7..d5fa0b5ec0a2 100644 --- a/drivers/input/touchscreen/xiaomi/fts_521/fts.c +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts.c @@ -150,7 +150,6 @@ static int fts_mode_handler(struct fts_ts_info *info, int force); static int fts_chip_initialization(struct fts_ts_info *info, int init_type); static const char *fts_get_limit(struct fts_ts_info *info); static irqreturn_t fts_event_handler(int irq, void *ts_info); -extern void lpm_disable_for_input(bool on); /** * Release all the touches in the linux input subsystem @@ -181,7 +180,6 @@ void release_all_touches(struct fts_ts_info *info) #ifdef STYLUS_MODE info->stylus_id = 0; #endif - lpm_disable_for_input(false); } /** @@ -3395,7 +3393,6 @@ static void fts_leave_pointer_event_handler(struct fts_ts_info *info, input_mt_report_slot_state(info->input_dev, tool, 0); if (info->touch_id == 0) { input_report_key(info->input_dev, BTN_TOUCH, touch_condition); - lpm_disable_for_input(false); if (!touch_condition) input_report_key(info->input_dev, BTN_TOOL_FINGER, 0); #ifdef CONFIG_FTS_FOD_AREA_REPORT @@ -4116,7 +4113,6 @@ static void fts_ts_sleep_work(struct work_struct *work) tag); pm_relax(info->dev); fts_enableInterrupt(); - lpm_disable_for_input(false); return; } else { logError( @@ -4176,7 +4172,6 @@ static void fts_ts_sleep_work(struct work_struct *work) #endif pm_relax(info->dev); fts_enableInterrupt(); - lpm_disable_for_input(false); return; } @@ -4214,8 +4209,6 @@ static irqreturn_t fts_event_handler(int irq, void *ts_info) return IRQ_HANDLED; } #endif - lpm_disable_for_input(true); - info->irq_status = true; error = fts_writeReadU8UX(regAdd, 0, 0, data, FIFO_EVENT_SIZE, DUMMY_FIFO); @@ -4261,8 +4254,6 @@ static irqreturn_t fts_event_handler(int irq, void *ts_info) } input_sync(info->input_dev); info->irq_status = false; - if (!info->touch_id) - lpm_disable_for_input(false); #ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE wake_up(&info->wait_queue); #endif @@ -5778,7 +5769,6 @@ static void fts_suspend_work(struct work_struct *work) sysfs_notify(&fts_info->fts_touch_dev->kobj, NULL, "touch_suspend_notify"); #endif - lpm_disable_for_input(false); } #ifdef CONFIG_DRM diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c index 4e1bdb5f4795..914e1598dfd6 100644 --- a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c @@ -89,7 +89,6 @@ static int32_t nvt_ts_suspend(struct device *dev); static int32_t nvt_ts_resume(struct device *dev); extern int dsi_panel_lockdown_info_read(unsigned char *plockdowninfo); extern void dsi_panel_doubleclick_enable(bool on); -extern void lpm_disable_for_input(bool on); extern int pen_charge_state_notifier_register_client(struct notifier_block *nb); extern int pen_charge_state_notifier_unregister_client(struct notifier_block *nb); @@ -1663,8 +1662,6 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) } #endif - lpm_disable_for_input(true); - mutex_lock(&ts->lock); if (ts->dev_pm_suspend) { @@ -1672,7 +1669,6 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) &ts->dev_pm_suspend_completion, msecs_to_jiffies(500)); if (!ret) { NVT_ERR("system(spi) can't finished resuming procedure, skip it\n"); - lpm_disable_for_input(false); goto XFER_ERROR; } } @@ -1738,7 +1734,6 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) input_id = (uint8_t)(point_data[1] >> 3); nvt_ts_wakeup_gesture_report(input_id, point_data); mutex_unlock(&ts->lock); - lpm_disable_for_input(false); return IRQ_HANDLED; } #endif @@ -1929,7 +1924,6 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) XFER_ERROR: mutex_unlock(&ts->lock); - lpm_disable_for_input(false); return IRQ_HANDLED; } diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c index 93ba8565e00a..17eb850be3cb 100644 --- a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c +++ b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c @@ -97,7 +97,6 @@ extern void dsi_panel_doubleclick_enable(bool on); #ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE static int32_t nvt_check_palm(uint8_t input_id, uint8_t *data); #endif -extern void lpm_disable_for_input(bool on); uint32_t ENG_RST_ADDR = 0x7FFF80; uint32_t SWRST_N8_ADDR = 0; /* read from dtsi */ uint32_t SPI_RD_FAST_ADDR = 0; /* read from dtsi */ @@ -1419,15 +1418,11 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) } #endif mutex_lock(&ts->lock); - if (ts->debug_flag >= TOUCH_DISABLE_LPM) - lpm_disable_for_input(true); if (ts->dev_pm_suspend) { ret = wait_for_completion_timeout( &ts->dev_pm_suspend_completion, msecs_to_jiffies(500)); if (!ret) { NVT_ERR("system(spi) can't finished resuming procedure, skip it\n"); - if (ts->debug_flag >= TOUCH_DISABLE_LPM) - lpm_disable_for_input(false); goto XFER_ERROR; } } @@ -1435,8 +1430,6 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) ret = CTP_SPI_READ(ts->client, point_data, POINT_DATA_LEN + 1); if (ret < 0) { NVT_ERR("CTP_SPI_READ failed.(%d)\n", ret); - if (ts->debug_flag >= TOUCH_DISABLE_LPM) - lpm_disable_for_input(false); goto XFER_ERROR; } /* @@ -1463,8 +1456,6 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) } else { nvt_update_firmware(ts->fw_name); } - if (ts->debug_flag >= TOUCH_DISABLE_LPM) - lpm_disable_for_input(false); goto XFER_ERROR; } #endif /* #if NVT_TOUCH_WDT_RECOVERY */ @@ -1473,8 +1464,6 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) /* ESD protect by FW handshake */ if (nvt_fw_recovery(point_data)) { nvt_esd_check_enable(true); - if (ts->debug_flag >= TOUCH_DISABLE_LPM) - lpm_disable_for_input(false); goto XFER_ERROR; } #endif /* #if NVT_TOUCH_ESD_PROTECT */ @@ -1482,8 +1471,6 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) #ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE input_id = (uint8_t)(point_data[1] >> 3); if (nvt_check_palm(input_id, point_data)) { - if (ts->debug_flag >= TOUCH_DISABLE_LPM) - lpm_disable_for_input(false); goto XFER_ERROR; /* to skip point data parsing */ } #endif @@ -1492,8 +1479,6 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) if (bTouchIsAwake == 0) { input_id = (uint8_t)(point_data[1] >> 3); nvt_ts_wakeup_gesture_report(input_id, point_data); - if (ts->debug_flag >= TOUCH_DISABLE_LPM) - lpm_disable_for_input(false); mutex_unlock(&ts->lock); return IRQ_HANDLED; } @@ -1579,8 +1564,6 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) input_report_key(ts->input_dev, BTN_TOUCH, 0); input_report_key(ts->input_dev, BTN_TOOL_FINGER, 0); - if (ts->debug_flag >= TOUCH_DISABLE_LPM) - lpm_disable_for_input(false); } clear_bit(i, ts->slot_map); } From 54d30d5e09a96f043a90373b541c1969b70b995d Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 11 Oct 2023 15:30:25 +0200 Subject: [PATCH 059/226] drivers: input: touchscreen: xiaomi: Make it compile without xiaomi_touch Change-Id: I05c378d3bf348bfcc96e44fbca96e14cd7f3b677 Signed-off-by: firebird11 --- .../input/touchscreen/xiaomi/fts_521/fts.c | 48 +++---- .../input/touchscreen/xiaomi/fts_521/fts.h | 2 +- .../goodix_driver_gt9886/goodix_ts_core.c | 2 + .../touchscreen/xiaomi/nt36523/nt36xxx.c | 118 +++++++++--------- 4 files changed, 90 insertions(+), 80 deletions(-) diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts.c b/drivers/input/touchscreen/xiaomi/fts_521/fts.c index d5fa0b5ec0a2..c1d3da688342 100644 --- a/drivers/input/touchscreen/xiaomi/fts_521/fts.c +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts.c @@ -68,7 +68,9 @@ #ifdef KERNEL_ABOVE_2_6_38 #include #endif +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE #include "../xiaomi/xiaomi_touch.h" +#endif #include "fts.h" #include "fts_lib/ftsCompensation.h" #include "fts_lib/ftsCore.h" @@ -5000,6 +5002,29 @@ static int fts_mode_handler(struct fts_ts_info *info, int force) return res; } +int fts_palm_sensor_cmd(int on) +{ + int ret; + u8 cmd_on[] = { 0xc0, 0x07, 0x01 }; + u8 cmd_off[] = { 0xc0, 0x07, 0x00 }; + + if (on) { + ret = fts_write_dma_safe(cmd_on, sizeof(cmd_on)); + } else { + ret = fts_write_dma_safe(cmd_off, sizeof(cmd_off)); + } + + if (ret < OK) { + logError(1, + "%s %s: write anti mis-touch cmd on...ERROR %08X !\n", + tag, __func__, ret); + return -EINVAL; + } + logError(1, "%s %s %d\n", tag, __func__, on); + + return 0; +} + #ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE static struct xiaomi_touch_interface xiaomi_touch_interfaces; @@ -5648,29 +5673,6 @@ int fts_p_sensor_write(int value) return ret; } -int fts_palm_sensor_cmd(int on) -{ - int ret; - u8 cmd_on[] = { 0xc0, 0x07, 0x01 }; - u8 cmd_off[] = { 0xc0, 0x07, 0x00 }; - - if (on) { - ret = fts_write_dma_safe(cmd_on, sizeof(cmd_on)); - } else { - ret = fts_write_dma_safe(cmd_off, sizeof(cmd_off)); - } - - if (ret < OK) { - logError(1, - "%s %s: write anti mis-touch cmd on...ERROR %08X !\n", - tag, __func__, ret); - return -EINVAL; - } - logError(1, "%s %s %d\n", tag, __func__, on); - - return 0; -} - int fts_palm_sensor_write(int value) { int ret = 0; diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts.h b/drivers/input/touchscreen/xiaomi/fts_521/fts.h index 0e5522d2e7b8..118d750d37ea 100644 --- a/drivers/input/touchscreen/xiaomi/fts_521/fts.h +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts.h @@ -388,9 +388,9 @@ bool fts_is_infod(void); void fts_get_pointer(int *touch_flag, int *x, int *y); #endif void fts_restore_regvalues(void); +int fts_palm_sensor_cmd(int input); #ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE -int fts_palm_sensor_cmd(int input); int fts_p_sensor_cmd(int input); bool fts_touchmode_edgefilter(unsigned int touch_id, int x, int y); #endif diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c index 3ba99ad25043..fa59135c89c3 100644 --- a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c @@ -42,7 +42,9 @@ #define INPUT_TYPE_B_PROTOCOL #endif #include +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE #include "../xiaomi/xiaomi_touch.h" +#endif #include "test_core/test_param_init.h" #define INPUT_EVENT_START 0 diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c index 914e1598dfd6..707cacb27fca 100644 --- a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c @@ -2013,6 +2013,62 @@ static void nvt_switch_mode_work(struct work_struct *work) } } +static int disable_pen_input_device(bool disable) +{ + uint8_t buf[8] = { 0 }; + int32_t ret = 0; + + NVT_LOG("++\n"); + if (!bTouchIsAwake || !ts) { + NVT_LOG("touch suspend, stop set pen state %s", + disable ? "DISABLE" : "ENABLE"); + goto nvt_set_pen_enable_out; + } + + msleep(35); + disable = (!(ts->pen_input_dev_enable) || ts->pen_is_charge) ? true : + disable; + + //---set xdata index to EVENT BUF ADDR--- + ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); + if (ret < 0) { + NVT_ERR("Set event buffer index fail!\n"); + goto nvt_set_pen_enable_out; + } + + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x7B; + buf[2] = !!disable; + ret = CTP_SPI_WRITE(ts->client, buf, 3); + if (ret < 0) { + NVT_ERR("set pen %s failed!\n", disable ? "DISABLE" : "ENABLE"); + goto nvt_set_pen_enable_out; + } + NVT_LOG("pen charge state is %s, %s pen input device\n", + ts->pen_is_charge ? "ENABLE" : "DISABLE", + disable ? "DISABLE" : "ENABLE"); + +nvt_set_pen_enable_out: + NVT_LOG("--\n"); + return ret; +} + +static int nvt_pen_charge_state_notifier_callback(struct notifier_block *self, + unsigned long event, + void *data) +{ + ts->pen_is_charge = !!event; + release_pen_event(); + schedule_work(&ts->pen_charge_state_change_work); + return 0; +} + +static void nvt_pen_charge_state_change_work(struct work_struct *work) +{ + NVT_LOG("pen charge is %s", ts->pen_is_charge ? "ENABLE" : "DISABLE"); + disable_pen_input_device(ts->pen_is_charge); +} + #ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE static struct xiaomi_touch_interface xiaomi_touch_interfaces; @@ -2323,62 +2379,6 @@ static void update_touchfeature_value_work(struct work_struct *work) NVT_LOG("exit"); } -static int disable_pen_input_device(bool disable) -{ - uint8_t buf[8] = { 0 }; - int32_t ret = 0; - - NVT_LOG("++\n"); - if (!bTouchIsAwake || !ts) { - NVT_LOG("touch suspend, stop set pen state %s", - disable ? "DISABLE" : "ENABLE"); - goto nvt_set_pen_enable_out; - } - - msleep(35); - disable = (!(ts->pen_input_dev_enable) || ts->pen_is_charge) ? true : - disable; - - //---set xdata index to EVENT BUF ADDR--- - ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD); - if (ret < 0) { - NVT_ERR("Set event buffer index fail!\n"); - goto nvt_set_pen_enable_out; - } - - buf[0] = EVENT_MAP_HOST_CMD; - buf[1] = 0x7B; - buf[2] = !!disable; - ret = CTP_SPI_WRITE(ts->client, buf, 3); - if (ret < 0) { - NVT_ERR("set pen %s failed!\n", disable ? "DISABLE" : "ENABLE"); - goto nvt_set_pen_enable_out; - } - NVT_LOG("pen charge state is %s, %s pen input device\n", - ts->pen_is_charge ? "ENABLE" : "DISABLE", - disable ? "DISABLE" : "ENABLE"); - -nvt_set_pen_enable_out: - NVT_LOG("--\n"); - return ret; -} - -static int nvt_pen_charge_state_notifier_callback(struct notifier_block *self, - unsigned long event, - void *data) -{ - ts->pen_is_charge = !!event; - release_pen_event(); - schedule_work(&ts->pen_charge_state_change_work); - return 0; -} - -static void nvt_pen_charge_state_change_work(struct work_struct *work) -{ - NVT_LOG("pen charge is %s", ts->pen_is_charge ? "ENABLE" : "DISABLE"); - disable_pen_input_device(ts->pen_is_charge); -} - static int nvt_set_cur_value(int nvt_mode, int nvt_value) { if (nvt_mode >= Touch_Mode_NUM && nvt_mode < 0) { @@ -3231,6 +3231,7 @@ static int32_t nvt_ts_probe(struct spi_device *client) } INIT_WORK(&ts->resume_work, nvt_resume_work); INIT_WORK(&ts->suspend_work, nvt_suspend_work); +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE ts->set_touchfeature_wq = create_singlethread_workqueue("nvt-set-touchfeature-queue"); if (!ts->set_touchfeature_wq) { @@ -3239,6 +3240,7 @@ static int32_t nvt_ts_probe(struct spi_device *client) goto err_create_set_touchfeature_work_queue; } INIT_WORK(&ts->set_touchfeature_work, update_touchfeature_value_work); +#endif ts->pen_charge_state_notifier.notifier_call = nvt_pen_charge_state_notifier_callback; @@ -3321,8 +3323,10 @@ static int32_t nvt_ts_probe(struct spi_device *client) &ts->pen_charge_state_notifier)) NVT_ERR("Error occurred while unregistering pen charge state notifier.\n"); err_register_pen_charge_state_failed: +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE destroy_workqueue(ts->set_touchfeature_wq); err_create_set_touchfeature_work_queue: +#endif destroy_workqueue(ts->event_wq); err_alloc_work_thread_failed: #ifndef NVT_SAVE_TESTDATA_IN_FILE @@ -3490,8 +3494,10 @@ static int32_t nvt_ts_remove(struct spi_device *client) spi_set_drvdata(client, NULL); +#ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE if (ts->set_touchfeature_wq) destroy_workqueue(ts->set_touchfeature_wq); +#endif if (ts) { kfree(ts); From d585a109032b760409f819f7fc16d3231a9e0aee Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Tue, 16 Apr 2024 03:39:57 +0200 Subject: [PATCH 060/226] drivers: input: touchscreen: xiaomi: nt36523: Fix function declaration args Change-Id: Ieea79fa899abf340d1ea5827e0b660e42559d2ad Signed-off-by: firebird11 --- drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c index 707cacb27fca..d9dc28329656 100644 --- a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c @@ -1113,7 +1113,7 @@ void nvt_ts_wakeup_gesture_report(uint8_t gesture_id, uint8_t *data) } #endif -static void release_pen_event() +static void release_pen_event(void) { if (ts && ts->pen_input_dev) { input_report_abs(ts->pen_input_dev, ABS_X, 0); From d0f8caf706b6f16c43e529a3d2619b67083fc243 Mon Sep 17 00:00:00 2001 From: Yumi Yukimura Date: Wed, 7 Feb 2024 23:57:30 +0800 Subject: [PATCH 061/226] drivers: input: touchscreen: xiaomi: fts_521: Fix strict-prototypes error Change-Id: Iddba34c831a691f4b6f5e3bb8a2ddf178f89f965 Signed-off-by: firebird11 --- drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsIO.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsIO.c b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsIO.c index 9c24d52936e2..4e328b91483e 100644 --- a/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsIO.c +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_lib/ftsIO.c @@ -101,7 +101,7 @@ int changeSAD(u8 sad) * Retrieve the pointer to the device struct of the IC * @return a the device struct pointer if client was previously set or NULL in all the other cases */ -struct device *getDev() +struct device *getDev(void) { if (client != NULL) return &(getClient()->dev); @@ -114,7 +114,7 @@ struct device *getDev() * Retrieve the pointer of the i2c_client struct representing the IC as i2c slave * @return client if it was previously set or NULL in all the other cases */ -struct i2c_client *getClient() +struct i2c_client *getClient(void) { if (client != NULL) return (struct i2c_client *)client; @@ -126,7 +126,7 @@ struct i2c_client *getClient() * Retrieve the pointer of the spi_device struct representing the IC as spi slave * @return client if it was previously set or NULL in all the other cases */ -struct spi_device *getClient() +struct spi_device *getClient(void) { if (client != NULL) return (struct spi_device *)client; From 8dc4138b3649baee213f3db0b14ad0be789c627d Mon Sep 17 00:00:00 2001 From: Yumi Yukimura Date: Thu, 8 Feb 2024 15:22:30 +0800 Subject: [PATCH 062/226] drivers: input: touchscreen: xiaomi: fts_521: Fix sscanf() buffer overflow Change-Id: I20dcdc3e0242ae61b0bce256575c3c9bc315f810 Signed-off-by: firebird11 --- drivers/input/touchscreen/xiaomi/fts_521/fts.c | 2 +- drivers/input/touchscreen/xiaomi/fts_521/fts_proc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts.c b/drivers/input/touchscreen/xiaomi/fts_521/fts.c index c1d3da688342..421d31f599e3 100644 --- a/drivers/input/touchscreen/xiaomi/fts_521/fts.c +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts.c @@ -225,7 +225,7 @@ static ssize_t fts_fwupdate_store(struct device *dev, mode[1] = 1; /* reading out firmware upgrade parameters */ - sscanf(buf, "%100s %d %d", path, &mode[0], &mode[1]); + sscanf(buf, "%99s %d %d", path, &mode[0], &mode[1]); logError(1, "%s fts_fwupdate_store: mode = %s \n", tag, path); ret = flashProcedure(path, mode[0], mode[1]); diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts_proc.c b/drivers/input/touchscreen/xiaomi/fts_521/fts_proc.c index 2b1b5fa8dd0c..5ce24e9f52fe 100644 --- a/drivers/input/touchscreen/xiaomi/fts_521/fts_proc.c +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts_proc.c @@ -466,7 +466,7 @@ static ssize_t fts_driver_test_write(struct file *file, const char __user *buf, case CMD_GETLIMITSFILE: if (count - 2 - 1 > 1) { numberParam = 2; - sscanf(p, "%100s", path); + sscanf(p, "%99s", path); } break; From c685e85d7fc0bf2d591820f2f8cb104cb43e38d7 Mon Sep 17 00:00:00 2001 From: dianlujitao Date: Wed, 19 Feb 2020 16:48:25 +0800 Subject: [PATCH 063/226] drivers: input: touchscreen: Add an interface to expose TP features to userspace * Needs to implement and register ops from TP driver * Access them via /sys/touchpanel/* Change-Id: I2baa61c6055ca6f6207ac0d6f627fe03048ccfb6 Signed-off-by: firebird11 --- drivers/input/touchscreen/Kconfig | 9 +++++++++ drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/tp_common.c | 26 ++++++++++++++++++++++++++ include/linux/input/tp_common.h | 13 +++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 drivers/input/touchscreen/tp_common.c create mode 100644 include/linux/input/tp_common.h diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 7f85cd5deb14..580d995e3a19 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -1300,4 +1300,13 @@ source "drivers/input/touchscreen/focaltech_touch/Kconfig" source "drivers/input/touchscreen/xiaomi/Kconfig" +config TOUCHSCREEN_COMMON + bool "Common touchscreen interface to interact with userspace" + default y + help + Say Y here if you want to control touchpanel features via + /sys/touchpanel. + + If unsure, say N. + endif diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 17aa95412a5e..86bc6541e70a 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -113,3 +113,4 @@ obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5xx.o obj-$(CONFIG_TOUCHSCREEN_ST) += st/ obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_touch/ obj-y += xiaomi/ +obj-$(CONFIG_TOUCHSCREEN_COMMON) += tp_common.o diff --git a/drivers/input/touchscreen/tp_common.c b/drivers/input/touchscreen/tp_common.c new file mode 100644 index 000000000000..d3a5498457b7 --- /dev/null +++ b/drivers/input/touchscreen/tp_common.c @@ -0,0 +1,26 @@ +#include + +struct kobject *touchpanel_kobj; + +#define TS_ENABLE_FOPS(type) \ + int tp_common_set_##type##_ops(struct tp_common_ops *ops) \ + { \ + static struct kobj_attribute kattr = \ + __ATTR(type, (S_IWUSR | S_IRUGO), NULL, NULL); \ + kattr.show = ops->show; \ + kattr.store = ops->store; \ + return sysfs_create_file(touchpanel_kobj, &kattr.attr); \ + } + +TS_ENABLE_FOPS(double_tap) +TS_ENABLE_FOPS(fod_status) + +static int __init tp_common_init(void) +{ + touchpanel_kobj = kobject_create_and_add("touchpanel", NULL); + if (!touchpanel_kobj) + return -ENOMEM; + + return 0; +} +core_initcall(tp_common_init); diff --git a/include/linux/input/tp_common.h b/include/linux/input/tp_common.h new file mode 100644 index 000000000000..0428a046f9fd --- /dev/null +++ b/include/linux/input/tp_common.h @@ -0,0 +1,13 @@ +#include + +extern struct kobject *touchpanel_kobj; + +struct tp_common_ops { + ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); + ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count); +}; + +int tp_common_set_double_tap_ops(struct tp_common_ops *ops); +int tp_common_set_fod_status_ops(struct tp_common_ops *ops); From 53316130ab4227e1b68b8105149f450c42bdda50 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Tue, 11 Jun 2024 22:37:40 +0200 Subject: [PATCH 064/226] drivers: input: touchscreen: tp_common: Add pen node Change-Id: I5d4046dba7a13d58cd78d2fafdc89e57e4747873 Signed-off-by: firebird11 --- drivers/input/touchscreen/tp_common.c | 1 + include/linux/input/tp_common.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/input/touchscreen/tp_common.c b/drivers/input/touchscreen/tp_common.c index d3a5498457b7..404994c4c865 100644 --- a/drivers/input/touchscreen/tp_common.c +++ b/drivers/input/touchscreen/tp_common.c @@ -14,6 +14,7 @@ struct kobject *touchpanel_kobj; TS_ENABLE_FOPS(double_tap) TS_ENABLE_FOPS(fod_status) +TS_ENABLE_FOPS(pen) static int __init tp_common_init(void) { diff --git a/include/linux/input/tp_common.h b/include/linux/input/tp_common.h index 0428a046f9fd..9cb74e80c9ed 100644 --- a/include/linux/input/tp_common.h +++ b/include/linux/input/tp_common.h @@ -11,3 +11,4 @@ struct tp_common_ops { int tp_common_set_double_tap_ops(struct tp_common_ops *ops); int tp_common_set_fod_status_ops(struct tp_common_ops *ops); +int tp_common_set_pen_ops(struct tp_common_ops *ops); From c8b9396535a04b0ca39f6eff36e9ea9de46fcdd1 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 11 Oct 2023 15:40:02 +0200 Subject: [PATCH 065/226] drivers: input: touchscreen: xiaomi: fts_521: Implement double_tap node Change-Id: I219ef6b0305649690594e5e053a0c4ce4b719ef6 Signed-off-by: firebird11 --- .../input/touchscreen/xiaomi/fts_521/fts.c | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts.c b/drivers/input/touchscreen/xiaomi/fts_521/fts.c index 421d31f599e3..9854ee503248 100644 --- a/drivers/input/touchscreen/xiaomi/fts_521/fts.c +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts.c @@ -83,6 +83,10 @@ #include "fts_lib/ftsTime.h" #include "fts_lib/ftsTool.h" +#ifdef CONFIG_TOUCHSCREEN_COMMON +#include +#endif + /** * Event handler installer helpers */ @@ -2726,6 +2730,34 @@ static ssize_t fts_touchgame_show(struct device *dev, } #endif +#if defined(CONFIG_TOUCHSCREEN_COMMON) && defined(GESTURE_MODE) +static ssize_t double_tap_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", fts_info->gesture_enabled); +} + +static ssize_t double_tap_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, + size_t count) +{ + int rc, val; + + rc = kstrtoint(buf, 10, &val); + if (rc) + return -EINVAL; + + fts_info->gesture_enabled = !!val; + + return count; +} + +static struct tp_common_ops double_tap_ops = { + .show = double_tap_show, + .store = double_tap_store, +}; +#endif + #ifdef CONFIG_SECURE_TOUCH static void fts_secure_touch_notify(struct fts_ts_info *info) { @@ -7335,6 +7367,16 @@ static int fts_probe(struct spi_device *client) msecs_to_jiffies(EXP_FN_WORK_DELAY_MS)); #endif +#ifdef CONFIG_TOUCHSCREEN_COMMON +#ifdef GESTURE_MODE + retval = tp_common_set_double_tap_ops(&double_tap_ops); + if (retval < 0) { + logError(1, "%s %s: Failed to create double_tap node err=%d\n", + tag, __func__, retval); + } +#endif +#endif + logError(1, "%s Probe Finished! \n", tag); return OK; #ifdef CONFIG_FTS_TOUCH_COUNT_DUMP From 822bd48c4a85c3b6f95318772bd7fa03684a33c5 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 11 Oct 2023 15:47:49 +0200 Subject: [PATCH 066/226] drivers: input: touchscreen: xiaomI: fts_521: Give fod_status ops to tp_common Change-Id: Ic55e03042f934989df4a484969ff174db2a06df5 Signed-off-by: firebird11 --- .../input/touchscreen/xiaomi/fts_521/fts.c | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/drivers/input/touchscreen/xiaomi/fts_521/fts.c b/drivers/input/touchscreen/xiaomi/fts_521/fts.c index 9854ee503248..753c063bac34 100644 --- a/drivers/input/touchscreen/xiaomi/fts_521/fts.c +++ b/drivers/input/touchscreen/xiaomi/fts_521/fts.c @@ -2581,31 +2581,28 @@ static ssize_t fts_grip_area_store(struct device *dev, } return count; } -#ifdef CONFIG_FTS_FOD_AREA_REPORT -static ssize_t fts_fod_status_show(struct device *dev, - struct device_attribute *attr, char *buf) +#if defined(CONFIG_TOUCHSCREEN_COMMON) && defined(CONFIG_FTS_FOD_AREA_REPORT) +static ssize_t fts_fod_status_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) { - struct fts_ts_info *info = dev_get_drvdata(dev); - - return snprintf(buf, TSP_BUF_SIZE, "%d\n", info->fod_status); + return snprintf(buf, TSP_BUF_SIZE, "%d\n", fts_info->fod_status); } -static ssize_t fts_fod_status_store(struct device *dev, - struct device_attribute *attr, +static ssize_t fts_fod_status_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) { - struct fts_ts_info *info = dev_get_drvdata(dev); int res = 0; u8 gesture_cmd[6] = { 0xA2, 0x03, 0x20, 0x00, 0x00, 0x01 }; u8 single_only_cmd[4] = { 0xC0, 0x02, 0x00, 0x00 }; u8 single_double_cmd[4] = { 0xC0, 0x02, 0x01, 0x1E }; logError(1, " %s %s buf:%c,count:%zu\n", tag, __func__, buf[0], count); - sscanf(buf, "%u", &info->fod_status); + sscanf(buf, "%u", &fts_info->fod_status); - mutex_lock(&info->fod_mutex); - if (info->fod_status) { - if (info->fod_status_set) { + mutex_lock(&fts_info->fod_mutex); + if (fts_info->fod_status) { + if (fts_info->fod_status_set) { logError(1, " %s %s fod status has set\n", tag, __func__); } else { @@ -2617,13 +2614,13 @@ static ssize_t fts_fod_status_store(struct device *dev, "%s %s: enter gesture and longpress failed! ERROR %08X recovery in senseOff...\n", tag, __func__, res); - if (info->sensor_sleep) { + if (fts_info->sensor_sleep) { logError( 1, " %s %s set fod cmd in sensor off status\n", tag, __func__); res = setScanMode(SCAN_MODE_LOW_POWER, 0); - if (info->gesture_enabled == 1) { + if (fts_info->gesture_enabled == 1) { res = fts_write_dma_safe( single_double_cmd, ARRAY_SIZE(single_double_cmd)); @@ -2644,15 +2641,22 @@ static ssize_t fts_fod_status_store(struct device *dev, } } fts_enableInterrupt(); - info->fod_status_set = true; + fts_info->fod_status_set = true; } } - mutex_unlock(&info->fod_mutex); + mutex_unlock(&fts_info->fod_mutex); logError(1, " %s %s end\n", tag, __func__); return count; } +static struct tp_common_ops fod_status_ops = { + .show = fts_fod_status_show, + .store = fts_fod_status_store, +}; +#endif + +#ifdef CONFIG_FTS_FOD_AREA_REPORT static ssize_t fts_fod_test_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -3118,9 +3122,6 @@ static DEVICE_ATTR(touch_suspend_notify, (S_IRUGO | S_IRGRP), fts_touch_suspend_notify_show, NULL); #endif #ifdef CONFIG_FTS_FOD_AREA_REPORT -static DEVICE_ATTR(fod_status, (S_IRUGO | S_IWUSR | S_IWGRP), - fts_fod_status_show, fts_fod_status_store); - static DEVICE_ATTR(fod_test, (S_IRUGO | S_IWUSR | S_IWGRP), NULL, fts_fod_test_store); #endif @@ -7314,13 +7315,6 @@ static int fts_probe(struct spi_device *client) #ifdef CONFIG_FTS_FOD_AREA_REPORT mutex_init(&(info->fod_mutex)); - error = sysfs_create_file(&info->fts_touch_dev->kobj, - &dev_attr_fod_status.attr); - if (error) { - logError(1, - "%s ERROR: Failed to create fod_status sysfs group!\n", - tag); - } error = sysfs_create_file(&info->fts_touch_dev->kobj, &dev_attr_fod_test.attr); if (error) { @@ -7377,6 +7371,14 @@ static int fts_probe(struct spi_device *client) #endif #endif +#if defined(CONFIG_TOUCHSCREEN_COMMON) && defined(CONFIG_FTS_FOD_AREA_REPORT) + retval = tp_common_set_fod_status_ops(&fod_status_ops); + if (retval < 0) { + logError(1, "%s %s: Failed to create fod_status node err=%d\n", + tag, __func__, retval); + } +#endif + logError(1, "%s Probe Finished! \n", tag); return OK; #ifdef CONFIG_FTS_TOUCH_COUNT_DUMP From c75b2ce8ea44fe385e3396a9b995a0f944c7cff2 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 11 Oct 2023 15:50:51 +0200 Subject: [PATCH 067/226] drivers: input: touchscreen: xiaomi: goodix_driver_gt9886: Implement double_tap node Change-Id: I128b90427ae7399a6d4b98b9f89b10a5c74deece Signed-off-by: firebird11 --- .../goodix_driver_gt9886/goodix_ts_core.c | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c index fa59135c89c3..6e5a5ec29db7 100644 --- a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c @@ -47,6 +47,10 @@ #endif #include "test_core/test_param_init.h" +#ifdef CONFIG_TOUCHSCREEN_COMMON +#include +#endif + #define INPUT_EVENT_START 0 #define INPUT_EVENT_SENSITIVE_MODE_OFF 0 #define INPUT_EVENT_SENSITIVE_MODE_ON 1 @@ -741,6 +745,45 @@ static ssize_t goodix_ts_tp_get_testcfg_show(struct device *dev, ts_info("test finish!"); return ret; } + +#ifdef CONFIG_TOUCHSCREEN_COMMON +static ssize_t double_tap_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", goodix_core_data->double_wakeup); +} + +static ssize_t double_tap_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, + size_t count) +{ + int rc, val; + + rc = kstrtoint(buf, 10, &val); + if (rc) + return -EINVAL; + + goodix_core_data->double_wakeup = !!val; + if (goodix_core_data->fod_status == -1 || + goodix_core_data->fod_status == 100) + goodix_core_data->gesture_enabled = + goodix_core_data->double_wakeup | + goodix_core_data->aod_status; + else + goodix_core_data->gesture_enabled = + goodix_core_data->double_wakeup | + goodix_core_data->fod_status | + goodix_core_data->aod_status; + + return count; +} + +static struct tp_common_ops double_tap_ops = { + .show = double_tap_show, + .store = double_tap_store, +}; +#endif + static DEVICE_ATTR(extmod_info, S_IRUGO, goodix_ts_extmod_show, NULL); static DEVICE_ATTR(driver_info, S_IRUGO, goodix_ts_driver_info_show, NULL); static DEVICE_ATTR(chip_info, S_IRUGO, goodix_ts_chip_info_show, NULL); @@ -2717,6 +2760,13 @@ static int goodix_ts_probe(struct platform_device *pdev) /*create sysfs files*/ goodix_ts_sysfs_init(core_data); +#ifdef CONFIG_TOUCHSCREEN_COMMON + r = tp_common_set_double_tap_ops(&double_tap_ops); + if (r < 0) { + ts_err("Failed to create double_tap node err=%d\n", r); + } +#endif + r = ts_device->hw_ops->reset(ts_device); if (r < 0) { pr_err("goodix_hw_ops->reset fail \n"); From 46e368082c55ba163e00f97cfbfbf9fdc8e357d4 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 11 Oct 2023 15:53:20 +0200 Subject: [PATCH 068/226] drivers: input: touchscreen: xiaomi: goodix_driver_gt9886: Give fod_status ops to tp_common Change-Id: I785bfd8cb1c89742c55bdb1f82933289545214ed Signed-off-by: firebird11 --- .../goodix_driver_gt9886/goodix_ts_core.c | 44 +++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c index 6e5a5ec29db7..b8c7ddb5ce41 100644 --- a/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c +++ b/drivers/input/touchscreen/xiaomi/goodix_driver_gt9886/goodix_ts_core.c @@ -1332,32 +1332,31 @@ static ssize_t gtp_fod_test_store(struct device *dev, return count; } -static ssize_t gtp_fod_status_show(struct device *dev, - struct device_attribute *attr, char *buf) +#ifdef CONFIG_TOUCHSCREEN_COMMON +static ssize_t gtp_fod_status_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) { - struct goodix_ts_core *core_data = dev_get_drvdata(dev); - - return snprintf(buf, 10, "%d\n", core_data->fod_status); + return snprintf(buf, 10, "%d\n", goodix_core_data->fod_status); } -static ssize_t gtp_fod_status_store(struct device *dev, - struct device_attribute *attr, +static ssize_t gtp_fod_status_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) { - struct goodix_ts_core *core_data = dev_get_drvdata(dev); - //struct goodix_ts_event *ts_event = &core_data->ts_event; - ts_info("buf:%s, count:%zu\n", buf, count); - sscanf(buf, "%u", &core_data->fod_status); + sscanf(buf, "%u", &goodix_core_data->fod_status); - //goodix_ts_input_report(core_data->input_dev,&ts_event->event_data.touch_data); - core_data->gesture_enabled = core_data->double_wakeup | - core_data->fod_status; - goodix_check_gesture_stat(!!core_data->fod_status); + goodix_core_data->gesture_enabled = goodix_core_data->double_wakeup | + goodix_core_data->fod_status; + goodix_check_gesture_stat(!!goodix_core_data->fod_status); return count; } -static DEVICE_ATTR(fod_status, (S_IRUGO | S_IWUSR | S_IWGRP), - gtp_fod_status_show, gtp_fod_status_store); + +static struct tp_common_ops fod_status_ops = { + .show = gtp_fod_status_show, + .store = gtp_fod_status_store, +}; +#endif static DEVICE_ATTR(fod_test, (S_IRUGO | S_IWUSR | S_IWGRP), NULL, gtp_fod_test_store); @@ -2765,6 +2764,11 @@ static int goodix_ts_probe(struct platform_device *pdev) if (r < 0) { ts_err("Failed to create double_tap node err=%d\n", r); } + + r = tp_common_set_fod_status_ops(&fod_status_ops); + if (r < 0) { + ts_err("Failed to create fod_status node err=%d\n", r); + } #endif r = ts_device->hw_ops->reset(ts_device); @@ -2849,12 +2853,6 @@ static int goodix_ts_probe(struct platform_device *pdev) goto out; } - if (sysfs_create_file(&core_data->gtp_touch_dev->kobj, - &dev_attr_fod_status.attr)) { - ts_err("Failed to create fod_status sysfs group!\n"); - goto out; - } - if (sysfs_create_file(&core_data->gtp_touch_dev->kobj, &dev_attr_fod_test.attr)) { ts_err("Failed to create fod_test sysfs group!"); From 4b5f7487fc2d15261a76109d6b20b90c93102f27 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Sun, 28 Jan 2024 16:22:06 +0100 Subject: [PATCH 069/226] drivers: input: touchscreen: xiaomi: nt36523: Implement double_tap node Change-Id: Icaa46478fac2293a9c89a464f9975c679d7b3f4f Signed-off-by: firebird11 --- .../touchscreen/xiaomi/nt36523/nt36xxx.c | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c index d9dc28329656..592164fd6146 100644 --- a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c @@ -48,6 +48,10 @@ #include "../xiaomi/xiaomi_touch.h" #endif +#if WAKEUP_GESTURE && defined(CONFIG_TOUCHSCREEN_COMMON) +#include +#endif + #if NVT_TOUCH_ESD_PROTECT static struct delayed_work nvt_esd_check_work; static struct workqueue_struct *nvt_esd_check_wq; @@ -119,6 +123,33 @@ const uint16_t gesture_key_array[] = { KEY_POWER, //GESTURE_SLIDE_RIGHT KEY_WAKEUP, //GESTURE_PEN_ONE_CLICK }; + +#ifdef CONFIG_TOUCHSCREEN_COMMON +static ssize_t double_tap_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", ts->db_wakeup); +} + +static ssize_t double_tap_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, + size_t count) +{ + int rc, val; + + rc = kstrtoint(buf, 10, &val); + if (rc) + return -EINVAL; + + ts->db_wakeup = !!val; + return count; +} + +static struct tp_common_ops double_tap_ops = { + .show = double_tap_show, + .store = double_tap_store, +}; +#endif #endif #ifdef CONFIG_MTK_SPI @@ -3024,6 +3055,14 @@ static int32_t nvt_ts_probe(struct spi_device *client) input_set_capability(ts->input_dev, EV_KEY, gesture_key_array[retry]); } + +#ifdef CONFIG_TOUCHSCREEN_COMMON + ret = tp_common_set_double_tap_ops(&double_tap_ops); + if (ret < 0) { + NVT_ERR("%s: Failed to create double_tap node err=%d\n", + __func__, ret); + } +#endif #endif sprintf(ts->phys, "input/ts"); From 4f0ba8e3b88639d5c64eab33ed8d7ef14823d9fe Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Tue, 11 Jun 2024 23:25:40 +0200 Subject: [PATCH 070/226] drivers: input: touchscreen: xiaomi: nt36523: Implement pen node Change-Id: I7dd9174f7e2d9bfd5e1f3d2a43ed4df23f92fa00 Signed-off-by: firebird11 --- .../touchscreen/xiaomi/nt36523/nt36xxx.c | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c index 592164fd6146..a8b45aae3e6b 100644 --- a/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c +++ b/drivers/input/touchscreen/xiaomi/nt36523/nt36xxx.c @@ -2100,6 +2100,35 @@ static void nvt_pen_charge_state_change_work(struct work_struct *work) disable_pen_input_device(ts->pen_is_charge); } +#ifdef CONFIG_TOUCHSCREEN_COMMON +static ssize_t pen_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", ts->pen_input_dev_enable); +} + +static ssize_t pen_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int rc, val; + + rc = kstrtoint(buf, 10, &val); + if (rc) + return -EINVAL; + + ts->pen_input_dev_enable = !!val; + disable_pen_input_device(!ts->pen_input_dev_enable); + release_pen_event(); + + return count; +} + +static struct tp_common_ops pen_ops = { + .show = pen_show, + .store = pen_store, +}; +#endif + #ifdef CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE static struct xiaomi_touch_interface xiaomi_touch_interfaces; @@ -3134,6 +3163,14 @@ static int32_t nvt_ts_probe(struct spi_device *client) ts->pen_input_dev->name, ret); goto err_pen_input_register_device_failed; } + +#ifdef CONFIG_TOUCHSCREEN_COMMON + ret = tp_common_set_pen_ops(&pen_ops); + if (ret < 0) { + NVT_ERR("%s: Failed to create pen node err=%d\n", + __func__, ret); + } +#endif } /* if (ts->pen_support) */ //---set int-pin & request irq--- From e1a481afdfc44e39ba32ce8d737adb36d2ed2d67 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 6 Nov 2023 22:36:30 +0100 Subject: [PATCH 071/226] drivers: input: touchscreen: xiaomi: nt36672c: Implement double_tap node Change-Id: I1ff68f35ed5b0c21f993ef339ffc3df111c60e74 Signed-off-by: firebird11 --- .../touchscreen/xiaomi/nt36672c/nt36xxx.c | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c index 17eb850be3cb..197812c16fe1 100644 --- a/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c +++ b/drivers/input/touchscreen/xiaomi/nt36672c/nt36xxx.c @@ -53,6 +53,10 @@ #include "../xiaomi/xiaomi_touch.h" #endif +#if WAKEUP_GESTURE && defined(CONFIG_TOUCHSCREEN_COMMON) +#include +#endif + #if NVT_TOUCH_ESD_PROTECT static struct delayed_work nvt_esd_check_work; static struct workqueue_struct *nvt_esd_check_wq; @@ -975,6 +979,31 @@ void nvt_ts_wakeup_gesture_report(uint8_t gesture_id, uint8_t *data) break; } } + +#ifdef CONFIG_TOUCHSCREEN_COMMON +static ssize_t double_tap_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", ts->db_wakeup); +} + +static ssize_t double_tap_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, + size_t count) +{ + int rc, val; + + rc = kstrtoint(buf, 10, &val); + if (rc) + return -EINVAL; + + ts->db_wakeup = !!val; + return count; +} + +static struct tp_common_ops double_tap_ops = { .show = double_tap_show, + .store = double_tap_store }; +#endif #endif /******************************************************* @@ -2521,6 +2550,14 @@ static int32_t nvt_ts_probe(struct platform_device *pdev) #if WAKEUP_GESTURE input_set_capability(ts->input_dev, EV_KEY, KEY_WAKEUP); + +#ifdef CONFIG_TOUCHSCREEN_COMMON + ret = tp_common_set_double_tap_ops(&double_tap_ops); + if (ret < 0) { + NVT_ERR("%s: Failed to create double_tap node err=%d\n", + __func__, ret); + } +#endif #endif sprintf(ts->phys, "input/ts"); From 3744ffaec16be583bbd8f49d37f5e06f739ea842 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 18:18:37 +0200 Subject: [PATCH 072/226] drivers: leds: Import Xiaomi changes Change-Id: I12973f2400bd2abbd9e3b9333d4a7be1ec0b7a4b Signed-off-by: firebird11 --- drivers/leds/leds-qpnp-flash-v2.c | 45 +++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c index 719b5fe07bd1..6191e148c152 100644 --- a/drivers/leds/leds-qpnp-flash-v2.c +++ b/drivers/leds/leds-qpnp-flash-v2.c @@ -354,6 +354,13 @@ static int max_ires_curr_ma_table[MAX_IRES_LEVELS] = { FLASH_LED_IRES7P5_MAX_CURR_MA, FLASH_LED_IRES5P0_MAX_CURR_MA }; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +struct flash_node_data *g_torch_0 = NULL; +struct flash_node_data *g_torch_1 = NULL; +struct flash_switch_data *g_switch_0 = NULL; +struct flash_switch_data *g_switch_1 = NULL; +#endif + static inline int get_current_reg_code(int target_curr_ma, int ires_ua) { if (!ires_ua || !target_curr_ma || (target_curr_ma < (ires_ua / 1000))) @@ -1751,6 +1758,11 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev, strlen("led:torch"))) { fnode = container_of(led_cdev, struct flash_node_data, cdev); led = dev_get_drvdata(&fnode->pdev->dev); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + } else if (!strncmp(led_cdev->name, "flashlight", strlen("flashlight"))) { + fnode = container_of(led_cdev, struct flash_node_data, cdev); + led = dev_get_drvdata(&fnode->pdev->dev); +#endif } if (!led) { @@ -1764,7 +1776,20 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev, if (rc < 0) pr_err("Failed to set flash LED switch rc=%d\n", rc); } else if (fnode) { +#ifndef CONFIG_MACH_XIAOMI_SM8150 qpnp_flash_led_node_set(fnode, value); +#else + if (!strncmp(led_cdev->name, "flashlight", strlen("flashlight"))) { + if (g_torch_0 && g_torch_1 && g_switch_0 && g_switch_1) { + qpnp_flash_led_node_set(g_torch_0, value); + qpnp_flash_led_node_set(g_torch_1, value); + qpnp_flash_led_switch_set(g_switch_0, value > 0); + qpnp_flash_led_switch_set(g_switch_1, value > 0); + } + } else { + qpnp_flash_led_node_set(fnode, value); + } +#endif } spin_unlock(&led->lock); @@ -2667,6 +2692,10 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) const char *temp_string; unsigned int base; int rc, i = 0, j = 0; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct flash_node_data *fnode; + struct flash_switch_data *snode; +#endif node = pdev->dev.of_node; if (!node) { @@ -2759,12 +2788,28 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) i, rc); goto error_led_register; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + fnode = &led->fnode[i]; + if (!strcmp("led:torch_0", fnode->cdev.name)) { + g_torch_0 = fnode; + } else if (!strcmp("led:torch_1", fnode->cdev.name)){ + g_torch_1 = fnode; + } +#endif i++; } if (!strcmp("switch", temp_string)) { rc = qpnp_flash_led_parse_and_register_switch(led, &led->snode[j], temp); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + snode = &led->snode[j]; + if (!strcmp("led:switch_0", snode->cdev.name)) { + g_switch_0 = snode; + } else if (!strcmp("led:switch_1", snode->cdev.name)) { + g_switch_1 = snode; + } +#endif if (rc < 0) { pr_err("Unable to parse and register switch node, rc=%d\n", rc); From 608b56e2d7dee5e5f36eb62077d80dba50acf01b Mon Sep 17 00:00:00 2001 From: UtsavBalar1231 Date: Thu, 3 Dec 2020 21:33:14 +0530 Subject: [PATCH 073/226] drivers: media: platform: msm: camera: Import Xiaomi changes Co-authored-by: Sebastiano Barezzi Change-Id: I20a82c9e77f92405d77a0d16621ce12209dfd194 Signed-off-by: firebird11 --- drivers/media/platform/msm/Kconfig | 8 + .../camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c | 19 + .../icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c | 25 + .../msm/camera/cam_isp/cam_isp_context.c | 40 ++ .../isp_hw/ife_csid_hw/cam_ife_csid_core.c | 60 ++ .../isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c | 4 + .../cam_actuator/cam_actuator_core.c | 207 +++++++ .../cam_sensor_module/cam_cci/cam_cci_core.c | 6 +- .../cam_csiphy/cam_csiphy_soc.c | 9 + .../cam_csiphy/include/cam_csiphy_1_1_hwreg.h | 345 +++++++---- .../include/cam_csiphy_1_1_hwreg_vayu.h | 585 ++++++++++++++++++ .../cam_eeprom/cam_eeprom_core.c | 8 + .../cam_sensor_module/cam_ois/cam_ois_core.c | 87 +++ .../cam_sensor/cam_sensor_core.c | 112 ++++ .../msm/camera/cam_sync/cam_sync_private.h | 4 + .../msm/camera/cam_sync/cam_sync_util.c | 10 + .../msm/camera/cam_utils/cam_soc_util.h | 4 + include/uapi/media/cam_defs.h | 5 + include/uapi/media/cam_req_mgr.h | 4 + include/uapi/media/cam_sensor.h | 3 + 20 files changed, 1431 insertions(+), 114 deletions(-) create mode 100644 drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_1_hwreg_vayu.h diff --git a/drivers/media/platform/msm/Kconfig b/drivers/media/platform/msm/Kconfig index aba3e316e8b6..6a704e37ae9b 100644 --- a/drivers/media/platform/msm/Kconfig +++ b/drivers/media/platform/msm/Kconfig @@ -57,6 +57,14 @@ if MSMB_CAMERA source "drivers/media/platform/msm/camera_v2/Kconfig" endif # MSMB_CAMERA +config USE_ROHM_BU64753 + bool "use ROHM BU64753 acculator" + default n + +config VCM_AK7374 + bool "use ak7374 vcm" + default n + source "drivers/media/platform/msm/vidc_3x/Kconfig" source "drivers/media/platform/msm/vidc/Kconfig" source "drivers/media/platform/msm/sde/Kconfig" diff --git a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c index 2caf6d0a844d..60e1c9793f94 100644 --- a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c @@ -880,7 +880,9 @@ static int cam_fd_mgr_util_submit_frame(void *priv, void *data) trace_cam_submit_to_hw("FD", frame_req->request_id); list_del_init(&frame_req->list); +#ifndef CONFIG_MACH_XIAOMI_NABU mutex_unlock(&hw_mgr->frame_req_mutex); +#endif if (hw_device->hw_intf->hw_ops.start) { start_args.hw_ctx = hw_ctx; @@ -896,20 +898,30 @@ static int cam_fd_mgr_util_submit_frame(void *priv, void *data) if (rc) { CAM_ERR(CAM_FD, "Failed in HW Start %d", rc); mutex_unlock(&hw_device->lock); +#ifdef CONFIG_MACH_XIAOMI_NABU + mutex_unlock(&hw_mgr->frame_req_mutex); +#endif goto put_req_into_free_list; } } else { CAM_ERR(CAM_FD, "Invalid hw_ops.start"); mutex_unlock(&hw_device->lock); rc = -EPERM; +#ifdef CONFIG_MACH_XIAOMI_NABU + mutex_unlock(&hw_mgr->frame_req_mutex); +#endif goto put_req_into_free_list; } hw_device->ready_to_process = false; hw_device->cur_hw_ctx = hw_ctx; hw_device->req_id = frame_req->request_id; +#ifdef CONFIG_MACH_XIAOMI_NABU + list_add_tail(&frame_req->list, &hw_mgr->frame_processing_list); +#endif mutex_unlock(&hw_device->lock); +#ifndef CONFIG_MACH_XIAOMI_NABU cam_common_util_get_curr_timestamp(&frame_req->submit_timestamp); rc = cam_fd_mgr_util_put_frame_req( &hw_mgr->frame_processing_list, &frame_req); @@ -918,9 +930,15 @@ static int cam_fd_mgr_util_submit_frame(void *priv, void *data) "Failed in putting frame req in processing list"); goto stop_unlock; } +#endif + +#ifdef CONFIG_MACH_XIAOMI_NABU + mutex_unlock(&hw_mgr->frame_req_mutex); +#endif return rc; +#ifndef CONFIG_MACH_XIAOMI_NABU stop_unlock: if (hw_device->hw_intf->hw_ops.stop) { struct cam_fd_hw_stop_args stop_args; @@ -933,6 +951,7 @@ static int cam_fd_mgr_util_submit_frame(void *priv, void *data) sizeof(stop_args))) CAM_ERR(CAM_FD, "Failed in HW Stop %d", rc); } +#endif put_req_into_free_list: cam_fd_mgr_util_put_frame_req(&hw_mgr->frame_free_list, &frame_req); diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 4bc666984083..8af7a17a73e8 100644 --- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -51,6 +51,9 @@ #include "cam_trace.h" #include "cam_cpas_api.h" #include "cam_common_util.h" +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#include "../cam_sync/cam_sync_private.h" +#endif #define ICP_WORKQ_TASK_CMD_TYPE 1 #define ICP_WORKQ_TASK_MSG_TYPE 2 @@ -58,7 +61,11 @@ #define ICP_DEV_TYPE_TO_CLK_TYPE(dev_type) \ ((dev_type == CAM_ICP_RES_TYPE_BPS) ? ICP_CLK_HW_BPS : ICP_CLK_HW_IPE) +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define ICP_DEVICE_IDLE_TIMEOUT 3000 +#else #define ICP_DEVICE_IDLE_TIMEOUT 400 +#endif static struct cam_icp_hw_mgr icp_hw_mgr; @@ -3571,6 +3578,24 @@ static bool cam_icp_mgr_is_valid_inconfig(struct cam_packet *packet) packet->num_io_configs, IPE_IO_IMAGES_MAX, num_in_map_entries, CAM_MAX_IN_RES); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* + * From the input parameter side, we add the + * protection to avoid the kernel mem bort which + * introduced from userspace, since we have the + * limit on CAM_SYNC_MAX_OBJS for icp sync_obj num. + */ + for (i = 0 ; i < packet->num_io_configs; i++) { + if ((io_cfg_ptr[i].direction == CAM_BUF_INPUT) && + (io_cfg_ptr[i].fence >= CAM_SYNC_MAX_OBJS)) { + in_config_valid = false; + CAM_ERR(CAM_ICP, + "In config fence/sync_obj(%u) more than allowed(%u)", + io_cfg_ptr[i].fence, (CAM_SYNC_MAX_OBJS - 1)); + } + } +#endif + return in_config_valid; } diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c index adf01832aea9..8cb5b4ff240c 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c @@ -596,6 +596,10 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( struct cam_isp_ctx_req *req_isp; struct cam_context *ctx = ctx_isp->base; uint64_t buf_done_req_id; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct cam_ctx_request *next_req; + struct cam_isp_ctx_req *next_req_isp; +#endif if (list_empty(&ctx->active_req_list)) { CAM_INFO(CAM_ISP, "Buf done with no active request!"); @@ -772,6 +776,33 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( ctx_isp->active_req_cnt--; } ctx_isp->irq_delay_detect = false; + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (ctx_isp->active_req_cnt > 0) { + if (list_empty(&ctx->active_req_list)) { + CAM_DBG(CAM_ISP, "Buf done with no active request!"); + goto end; + } + next_req = list_first_entry(&ctx->active_req_list, struct cam_ctx_request, list); + CAM_DBG(CAM_REQ, "next_req:%p, active_reqcnt:%d", next_req, ctx_isp->active_req_cnt); + + next_req_isp = (struct cam_isp_ctx_req *) next_req->req_priv; + + CAM_DBG(CAM_REQ, "next_req_isp:bubble_detected:%d,bubble_report:%d", + next_req_isp->bubble_detected, next_req_isp->bubble_report); + if (next_req_isp->bubble_detected && next_req_isp->bubble_report) { + next_req_isp->num_acked = 0; + next_req_isp->bubble_detected = false; + list_del_init(&next_req->list); + list_add(&next_req->list, &ctx->pending_req_list); + atomic_set(&ctx_isp->process_bubble, 0); + ctx_isp->active_req_cnt--; + CAM_DBG(CAM_REQ, + "Move active request %lld to pending list(cnt = %d) [bubble recovery], ctx %u", + next_req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id); + } + } +#endif end: return rc; } @@ -782,6 +813,11 @@ static void __cam_isp_ctx_send_sof_boot_timestamp( { struct cam_req_mgr_message req_msg; +#ifdef CONFIG_MACH_XIAOMI_NABU + if (0 == request_id) + return; +#endif + req_msg.session_hdl = ctx_isp->base->session_hdl; req_msg.u.frame_msg.frame_id = ctx_isp->frame_id; req_msg.u.frame_msg.request_id = request_id; @@ -3496,6 +3532,10 @@ static int __cam_isp_ctx_config_dev_in_top_state( list_add_tail(&req->list, &ctx->free_req_list); spin_unlock_bh(&ctx->lock); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + atomic_set(&ctx_isp->process_bubble, 0); +#endif + return rc; } diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index 27311e862b60..22b104d90c8e 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -368,6 +368,9 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw) int rc = 0; uint32_t val = 0, i; uint32_t status; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + unsigned long flags; +#endif soc_info = &csid_hw->hw_info->soc_info; csid_reg = csid_hw->csid_info->csid_reg; @@ -382,6 +385,10 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw) CAM_DBG(CAM_ISP, "CSID:%d Csid reset", csid_hw->hw_intf->hw_idx); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags); +#endif + /* Mask all interrupts */ cam_io_w_mb(0, soc_info->reg_map[0].mem_base + csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); @@ -424,6 +431,10 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw) cam_io_w_mb(1, soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->csid_irq_cmd_addr); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags); +#endif + cam_io_w_mb(0x80, soc_info->reg_map[0].mem_base + csid_hw->csid_info->csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr); @@ -1045,6 +1056,9 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw) const struct cam_ife_csid_reg_offset *csid_reg; struct cam_hw_soc_info *soc_info; uint32_t i, val, clk_lvl; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + unsigned long flags; +#endif csid_reg = csid_hw->csid_info->csid_reg; soc_info = &csid_hw->hw_info->soc_info; @@ -1083,6 +1097,10 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw) goto disable_soc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags); +#endif + /* clear all interrupts */ cam_io_w_mb(1, soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->csid_top_irq_clear_addr); @@ -1109,6 +1127,10 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw) cam_io_w_mb(1, soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->csid_irq_cmd_addr); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags); +#endif + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->csid_hw_version_addr); CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x", @@ -2682,6 +2704,10 @@ static int cam_ife_csid_reset(void *hw_priv, csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info; reset = (struct cam_csid_reset_cfg_args *)reset_args; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + mutex_lock(&csid_hw->hw_info->hw_mutex); +#endif + switch (reset->reset_type) { case CAM_IFE_CSID_RESET_GLOBAL: rc = cam_ife_csid_global_reset(csid_hw); @@ -2696,6 +2722,10 @@ static int cam_ife_csid_reset(void *hw_priv, break; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + mutex_unlock(&csid_hw->hw_info->hw_mutex); +#endif + return rc; } @@ -2838,8 +2868,16 @@ static int cam_ife_csid_reset_retain_sw_reg( const struct cam_ife_csid_reg_offset *csid_reg = csid_hw->csid_info->csid_reg; struct cam_hw_soc_info *soc_info; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + unsigned long flags; +#endif soc_info = &csid_hw->hw_info->soc_info; + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags); +#endif + /* clear the top interrupt first */ cam_io_w_mb(1, soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->csid_top_irq_clear_addr); @@ -2852,6 +2890,11 @@ static int cam_ife_csid_reset_retain_sw_reg( cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb, soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->csid_rst_strobes_addr); + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags); +#endif + rc = readl_poll_timeout(soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->csid_top_irq_status_addr, status, (status & 0x1) == 0x1, @@ -2865,11 +2908,20 @@ static int cam_ife_csid_reset_retain_sw_reg( csid_hw->hw_intf->hw_idx, rc); rc = 0; } + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags); +#endif + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->csid_top_irq_clear_addr); cam_io_w_mb(1, soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->csid_irq_cmd_addr); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags); +#endif + return rc; } @@ -3577,6 +3629,10 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) cam_io_r_mb(soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[i]->csid_rdi_irq_status_addr); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags); +#endif + /* clear */ cam_io_w_mb(irq_status[CSID_IRQ_STATUS_RX], soc_info->reg_map[0].mem_base + @@ -3599,6 +3655,10 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) cam_io_w_mb(1, soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->csid_irq_cmd_addr); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags); +#endif + if (irq_status[CSID_IRQ_STATUS_RX] & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) { CAM_DBG(CAM_ISP, "csi rx reset complete"); diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c index 19c73f06c49f..7f7560bf7bb7 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c @@ -436,7 +436,11 @@ void cam_isp_hw_get_timestamp(struct cam_isp_timestamp *time_stamp) { struct timespec ts; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + ktime_get_ts(&ts); +#else get_monotonic_boottime(&ts); +#endif time_stamp->mono_time.tv_sec = ts.tv_sec; time_stamp->mono_time.tv_usec = ts.tv_nsec/1000; time_stamp->time_usecs = ts.tv_sec * 1000000 + diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c index 25e1644933f2..acce1128d723 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -408,6 +408,209 @@ int32_t cam_actuator_publish_dev_info(struct cam_req_mgr_device_info *info) return 0; } +#ifdef CONFIG_VCM_AK7374 +/* ---------------------------------------------------- +* Anti-Actuator-Noise logic start, +* Re-config actuator eeprom values +------------------------------------------------------*/ +#define AAN_AK7374_MASK 0xE8 +#define AAN_AK7374_WRITE_NUM 25 +#define AAN_AK7374_READ_NUM 22 + +unsigned int aan_already_write; + +unsigned int aan_ak7374_setting[AAN_AK7374_WRITE_NUM][2] = { + {0xAE, 0x3B}, {0x10, 0x36}, {0x11, 0x23}, {0x12, 0xDC}, + {0x13, 0x78}, {0x14, 0x14}, {0x15, 0x1E}, {0x16, 0x1A}, + {0x17, 0x5E}, {0x18, 0xDB}, {0x19, 0xC8}, {0x1A, 0x28}, + {0x1C, 0x00}, {0x1D, 0x00}, {0x1E, 0x00}, {0x20, 0x6E}, + {0x21, 0x01}, {0x22, 0x00}, {0x23, 0x1A}, {0x24, 0x00}, + {0x25, 0x00}, {0x03, 0x01}, {0x03, 0x02}, {0x03, 0x04}, + {0x03, 0x08} +}; + + /* +read-check: 0xE9,0x4B, 0x0 +write:0xE8,0xAE, 0x0 +power off +power on +wait 10ms + */ +unsigned int aan_ak7374_verify[AAN_AK7374_READ_NUM][2] = { + {0x0A, 0x89}, {0x0B, 0x84}, {0x10, 0x36}, {0x11, 0x23}, + {0x12, 0xDC}, {0x13, 0x78}, {0x14, 0x14}, {0x15, 0x1E}, + {0x16, 0x1A}, {0x17, 0x5E}, {0x18, 0xDB}, {0x19, 0xC8}, + {0x1A, 0x28}, {0x1C, 0x00}, {0x1D, 0x00}, {0x1E, 0x00}, + {0x20, 0x6E}, {0x21, 0x01}, {0x22, 0x00}, {0x23, 0x1A}, + {0x24, 0x00}, {0x25, 0x00} +}; + +static void aan_i2c_read(struct camera_io_master *io_master_info, struct i2c_settings_list *i2c_list, unsigned short addr, unsigned short *data) +{ + int rc = 0; + + i2c_list->i2c_settings.addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE; + i2c_list->i2c_settings.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE; + + rc = camera_io_dev_read( + io_master_info, + addr, + (uint32_t *)(data), + i2c_list->i2c_settings.addr_type, + i2c_list->i2c_settings.data_type); + + if (rc < 0) { + CAM_ERR(CAM_ACTUATOR, "aan, aan_i2c_read failed: %d", rc); + } else { + CAM_DBG(CAM_ACTUATOR, "aan, aan_i2c_read, addr=0x%x, data=0x%x, data_addr=0x%x, sid=0x%x", + addr, *data, data, io_master_info->cci_client->sid); + } +} + +static void aan_i2c_write(struct camera_io_master *io_master_info, struct i2c_settings_list *i2c_list, unsigned short addr, unsigned short data) +{ + int32_t rc = 0; + + i2c_list->i2c_settings.reg_setting[0].reg_addr = addr; + i2c_list->i2c_settings.reg_setting[0].reg_data = data; + i2c_list->i2c_settings.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE; + i2c_list->i2c_settings.addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE; + i2c_list->op_code == CAM_SENSOR_I2C_WRITE_RANDOM; + i2c_list->i2c_settings.size = 1; + + rc = camera_io_dev_write(io_master_info, &(i2c_list->i2c_settings)); + if (rc < 0) { + CAM_ERR(CAM_ACTUATOR, "aan, aan_i2c_write failed: %d", rc); + } else { + CAM_DBG(CAM_ACTUATOR, "aan, aan_i2c_write, addr=0x%x, data=0x%x, sid=%d", addr, data, io_master_info->cci_client->sid); + } +} + +static int32_t cam_actuator_anti_noise(struct cam_actuator_ctrl_t *a_ctrl, struct i2c_settings_array *i2c_set) +{ + unsigned int i = 0; + unsigned short dat = 0; + struct i2c_settings_list *i2c_list; + unsigned int ret = 0; + unsigned int sid_backup; + + if (aan_already_write == 1) { + CAM_DBG(CAM_ACTUATOR, "aan, eeprom already set"); + return 0; + } else { + CAM_DBG(CAM_ACTUATOR, "aan, in"); + } + + if (a_ctrl != NULL && a_ctrl->io_master_info.cci_client != NULL) { + sid_backup = a_ctrl->io_master_info.cci_client->sid; + } else { + CAM_ERR(CAM_ACTUATOR, "aan, invalid param, a_ctrl or cci_client is NULL, a_ctrl=0x%p", a_ctrl); + return 0; + } + CAM_DBG(CAM_ACTUATOR, "aan, orig a_ctrl->io_master_info.cci_client->sid=%d", sid_backup); + + if ((AAN_AK7374_MASK >> 1) != a_ctrl->io_master_info.cci_client->sid) { + CAM_ERR(CAM_ACTUATOR, "aan, not 2nd provider module, no need update."); + return 0; + } + + if (a_ctrl == NULL || i2c_set == NULL) { + CAM_ERR(CAM_ACTUATOR, "aan, cam_actuator_anti_noise, Invalid Args"); + ret = -EINVAL; + goto aan_out; + } + + if (i2c_set->is_settings_valid != 1) { + CAM_ERR(CAM_ACTUATOR, "aan, cam_actuator_anti_noise, Invalid Args"); + ret = -EINVAL; + goto aan_out; + } + + list_for_each_entry(i2c_list, &(i2c_set->list_head), list) { + CAM_DBG(CAM_ACTUATOR, "aan, cam_actuator_anti_noise start. sid=%d, master_type=%d, i2c_set->request_id=%d", + a_ctrl->io_master_info.cci_client->sid, a_ctrl->io_master_info.master_type, i2c_set->request_id); + + // for 2nd provider AK7374 + a_ctrl->io_master_info.cci_client->sid = AAN_AK7374_MASK>>1; //AK7374 EEPROM mask + aan_i2c_read(&(a_ctrl->io_master_info), i2c_list, 0x03, &dat); + if (dat == 0x0E) { + //Step 1: Check whethre need to update the eeprom. + for (i = 0; i < AAN_AK7374_READ_NUM; i++) { + aan_i2c_read(&(a_ctrl->io_master_info), i2c_list, aan_ak7374_verify[i][0], &dat); + if (dat != aan_ak7374_verify[i][1]) { + CAM_ERR(CAM_ACTUATOR, "aan, eeprom data not match, i=%d, addr=0x%x, expect=0x%x, real=0x%x", + i, aan_ak7374_verify[i][0], aan_ak7374_verify[i][1], dat); + break; + } + } + if (i == AAN_AK7374_READ_NUM) { + CAM_ERR(CAM_ACTUATOR, "aan, do not need update"); + aan_already_write = 1; + goto aan_out; + } + + //Step 2: Update the eeprom PID. + for (i = 0; i < AAN_AK7374_WRITE_NUM; i++) { + aan_i2c_write(&(a_ctrl->io_master_info), i2c_list, aan_ak7374_setting[i][0], aan_ak7374_setting[i][1]); + if (0x03 == aan_ak7374_setting[i][0]) { + msleep(100); + } + } + + //Step 3: Check registers flag1 + aan_i2c_read(&(a_ctrl->io_master_info), i2c_list, 0x4B, &dat); + if (dat != 0) { + for (i = AAN_AK7374_WRITE_NUM-4; i < AAN_AK7374_WRITE_NUM; i++) { + aan_i2c_write(&(a_ctrl->io_master_info), i2c_list, aan_ak7374_setting[i][0], aan_ak7374_setting[i][1]); + } + aan_i2c_read(&(a_ctrl->io_master_info), i2c_list, 0x4B, &dat); + if (dat != 0) { + CAM_ERR(CAM_ACTUATOR, "aan, ak7374_write failed, 0x4B=0x%x", dat); + goto aan_out; + } + } + + //Step 4: Check register flag2 + aan_i2c_write(&(a_ctrl->io_master_info), i2c_list, 0x03, 0x10); + msleep(100); + aan_i2c_write(&(a_ctrl->io_master_info), i2c_list, 0xAE, 0x0); + msleep(100); + aan_i2c_read(&(a_ctrl->io_master_info), i2c_list, 0x0A, &dat); + if (dat != 0x89) { + CAM_ERR(CAM_ACTUATOR, "aan, ak7374 flag2 failed, 0x0A, expect=0x89, real=0x%x", dat); + } + CAM_DBG(CAM_ACTUATOR, "aan, ak7374_write done"); + + //Step 5: Verify PID data + for (i = 0; i < AAN_AK7374_READ_NUM; i++) { + aan_i2c_read(&(a_ctrl->io_master_info), i2c_list, aan_ak7374_verify[i][0], &dat); + if (dat != aan_ak7374_verify[i][1]) { + CAM_ERR(CAM_ACTUATOR, "aan, ak7374_write failed, i=%d, addr=0x%x,, expect=0x%x, real=0x%x", + i, aan_ak7374_verify[i][0], aan_ak7374_verify[i][1], dat); + break; + } + } + if (i == AAN_AK7374_READ_NUM) { + CAM_DBG(CAM_ACTUATOR, "aan, ak7374_write success."); + } else { + CAM_ERR(CAM_ACTUATOR, "aan, ak7374_write failed."); + } + goto aan_out; + } else { + CAM_ERR(CAM_ACTUATOR, "aan, not ak7374, 0x03=0x%x", dat); + } + } +aan_out: + a_ctrl->io_master_info.cci_client->sid = sid_backup; + aan_already_write = 1; + CAM_DBG(CAM_ACTUATOR, "aan, cam_actuator_anti_noise done"); + return 0; +} +/* ---------------------------------------------------- +* Anti-Actuator-Noise logic end +------------------------------------------------------*/ +#endif + int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, void *arg) { @@ -596,6 +799,10 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, goto rel_pkt_buf; } +#ifdef CONFIG_VCM_AK7374 + cam_actuator_anti_noise(a_ctrl, &a_ctrl->i2c_data.init_settings); +#endif + /* Delete the request even if the apply is failed */ rc = delete_request(&a_ctrl->i2c_data.init_settings); if (rc < 0) { diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c index a06a4c6c6339..9ab01270750d 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c @@ -471,6 +471,8 @@ static int32_t cam_cci_calc_cmd_len(struct cci_device *cci_dev, for (i = 0; i < pack_max_len;) { if (cmd->delay || ((cmd - i2c_cmd) >= (cmd_size - 1))) break; + /* delete for E5G ois setting write */ +#ifndef CONFIG_USE_ROHM_BU64753 if (cmd->reg_addr + 1 == (cmd+1)->reg_addr) { len += data_len; @@ -479,7 +481,9 @@ static int32_t cam_cci_calc_cmd_len(struct cci_device *cci_dev, break; } (*pack)++; - } else { + } +#endif + else { break; } i += data_len; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c index 1c6037370a2b..d8d197364d2f 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c @@ -12,7 +12,11 @@ #include "cam_csiphy_soc.h" #include "cam_csiphy_core.h" +#ifdef CONFIG_MACH_XIAOMI_VAYU +#include "include/cam_csiphy_1_1_hwreg_vayu.h" +#else #include "include/cam_csiphy_1_1_hwreg.h" +#endif #include "include/cam_csiphy_1_0_hwreg.h" #include "include/cam_csiphy_1_2_hwreg.h" #include "include/cam_csiphy_1_2_2_hwreg.h" @@ -254,7 +258,12 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev, csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW; csiphy_dev->hw_version = CSIPHY_VERSION_V11; csiphy_dev->clk_lane = 0; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + csiphy_dev->ctrl_reg->data_rates_settings_table = + &data_rate_delta_table_1_1; +#else csiphy_dev->ctrl_reg->data_rates_settings_table = NULL; +#endif } else if (of_device_is_compatible(soc_info->dev->of_node, "qcom,csiphy-v1.2")) { csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v1_2_reg; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_1_hwreg.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_1_hwreg.h index 9c31dd458cf5..4fd632314c46 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_1_hwreg.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_1_hwreg.h @@ -19,10 +19,10 @@ struct csiphy_reg_parms_t csiphy_v1_1 = { .mipi_csiphy_interrupt_status0_addr = 0x8B0, .mipi_csiphy_interrupt_clear0_addr = 0x858, .mipi_csiphy_glbl_irq_cmd_addr = 0x828, - .csiphy_common_array_size = 5, + .csiphy_common_array_size = 6, .csiphy_reset_array_size = 5, .csiphy_2ph_config_array_size = 16, - .csiphy_3ph_config_array_size = 28, + .csiphy_3ph_config_array_size = 43, .csiphy_2ph_clock_lane = 0x1, .csiphy_2ph_combo_ck_ln = 0x10, }; @@ -31,6 +31,7 @@ struct csiphy_reg_t csiphy_common_reg_1_1[] = { {0x0814, 0xd5, 0x00, CSIPHY_LANE_ENABLE}, {0x0818, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x081C, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x081C, 0x72, 0x00, CSIPHY_3PH_REGS}, {0x0800, 0x01, 0x01, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, }; @@ -60,27 +61,25 @@ struct csiphy_reg_t csiphy_irq_reg_1_1[] = { struct csiphy_reg_t csiphy_2ph_v1_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { { - {0x0030, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0034, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x001C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0028, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0000, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0008, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0060, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0064, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { - {0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0704, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0720, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0734, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x071C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -89,169 +88,179 @@ csiphy_reg_t csiphy_2ph_v1_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x073C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0708, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, - {0x070C, 0x16, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x070C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0760, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0764, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { - {0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0220, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0234, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x021C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0228, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0200, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0208, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x020C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0260, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0264, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { - {0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0420, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0434, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x041C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0428, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0428, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x043C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0400, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0408, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x040C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0460, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0464, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { - {0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0620, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0634, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x061C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0628, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0628, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0600, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0608, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x060C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0660, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0664, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, }; struct csiphy_reg_t csiphy_2ph_v1_1_combo_mode_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { { - {0x0030, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0034, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x001C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0034, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x001C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0000, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0000, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0008, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x000C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0060, 0x31, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0064, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { - {0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0720, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0704, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0734, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x071C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0734, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x071C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0714, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x073C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0708, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, - {0x070C, 0x16, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x070C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0760, 0x31, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0764, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { - {0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0220, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0234, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x021C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0234, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x021C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0200, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0200, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0208, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x020C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, - + {0x0260, 0x31, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0264, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { - {0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0420, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0434, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0434, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0418, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x041C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0428, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x043C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0400, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0400, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0408, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x040C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0460, 0x31, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0464, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { - {0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0620, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0634, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x061C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0634, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x061C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0624, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0628, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0600, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0608, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, - {0x060C, 0x16, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x060C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0638, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0660, 0x31, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0664, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, }; struct csiphy_reg_t csiphy_3ph_v1_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { { - {0x015C, 0xC8, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x016C, 0x19, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0144, 0xB6, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0990, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0994, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0998, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0990, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0994, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0998, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x098C, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x098C, 0x5F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0168, 0x8E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x016C, 0x59, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0104, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x010C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0108, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, @@ -266,22 +275,37 @@ csiphy_reg_t csiphy_3ph_v1_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x0124, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0128, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x012C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0144, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0144, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0160, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x01CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0164, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x01DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x09B0, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0164, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0980, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B0, 0x23, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0984, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0988, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x09AC, 0x55, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0164, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { - {0x035C, 0xC8, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x036C, 0x19, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0344, 0xB6, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A90, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A94, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A98, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A8C, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A8C, 0x5F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0368, 0x8E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x036C, 0x59, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x030C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0308, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, @@ -296,22 +320,37 @@ csiphy_reg_t csiphy_3ph_v1_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x0324, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0328, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x032C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0344, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0344, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0360, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x03CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0364, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x03DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0AB0, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0364, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A80, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x23, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A84, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A88, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0AAC, 0x55, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0364, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { - {0x055C, 0xC8, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x056C, 0x19, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0544, 0xB6, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B90, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B94, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B98, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B8C, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B8C, 0x5F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0568, 0x8E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x056C, 0x59, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0504, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x050C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0508, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, @@ -326,16 +365,22 @@ csiphy_reg_t csiphy_3ph_v1_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x0524, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0528, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x052C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0544, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0544, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0560, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x05CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0564, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x05DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0BB0, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0564, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B80, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x23, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B84, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B88, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0BAC, 0x55, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0564, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, }; @@ -343,9 +388,18 @@ csiphy_reg_t csiphy_3ph_v1_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { struct csiphy_reg_t csiphy_3ph_v1_1_combo_mode_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { { - {0x015C, 0xC8, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x016C, 0x19, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0144, 0xB6, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0990, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0994, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0998, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0990, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0994, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0998, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x098C, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x098C, 0x5F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0168, 0x8E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x016C, 0x59, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0104, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x010C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0108, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, @@ -360,22 +414,37 @@ struct csiphy_reg_t {0x0124, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0128, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x012C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0144, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0144, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0160, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x01CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0164, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x01DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x09B0, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0164, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0980, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B0, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0984, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0988, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x09AC, 0x55, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0164, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DNP_PARAMS}, }, { - {0x035C, 0xC8, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x036C, 0x19, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0344, 0xB6, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A90, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A94, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A98, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A8C, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A8C, 0x5F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0368, 0x8E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x036C, 0x59, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x030C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0308, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, @@ -390,22 +459,37 @@ struct csiphy_reg_t {0x0324, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0328, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x032C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0344, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0344, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0360, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x03CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0364, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x03DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0AB0, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0364, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A80, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A84, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A88, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0AAC, 0x55, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0364, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DNP_PARAMS}, }, { - {0x055C, 0xC8, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x056C, 0x19, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0544, 0xB6, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B90, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B94, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B98, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B8C, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B8C, 0x5F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0568, 0x8E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x056C, 0x59, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0504, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x050C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0508, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, @@ -420,18 +504,53 @@ struct csiphy_reg_t {0x0524, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0528, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x052C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0544, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0544, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0560, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x05CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0564, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x05DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0BB0, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0564, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B80, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B84, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B88, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0BAC, 0x55, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0564, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, }; + +struct data_rate_settings_t data_rate_delta_table_1_1 = { + .num_data_rate_settings = 2, + .data_rate_settings = { + { + // data rate <= 2.3 Gsps + // max bandwidth = 2.3 * 2.28 * (10**3) Mbps + .bandwidth = 5243000000, + .data_rate_reg_array_size = 3, + .csiphy_data_rate_regs = { + {0x09B0, 0x23, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x23, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x23, 0x00, CSIPHY_DEFAULT_PARAMS} + } + }, + { + // 2.3 Gsps <= data rate <= 2.5 Gsps + // max bandwidth = 2.5 * 2.28 * (10**3) Mbps + .bandwidth = 5700000000, + .data_rate_reg_array_size = 3, + .csiphy_data_rate_regs = { + {0x09B0, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS} + } + } + } +}; + #endif /* _CAM_CSIPHY_1_1_HWREG_H_ */ diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_1_hwreg_vayu.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_1_hwreg_vayu.h new file mode 100644 index 000000000000..bbaad56a41be --- /dev/null +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_1_hwreg_vayu.h @@ -0,0 +1,585 @@ +/* Copyright (c) 2018-2020, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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 _CAM_CSIPHY_1_1_HWREG_H_ +#define _CAM_CSIPHY_1_1_HWREG_H_ + +#include "../cam_csiphy_dev.h" + +struct csiphy_reg_parms_t csiphy_v1_1 = { + .mipi_csiphy_interrupt_status0_addr = 0x8B0, + .mipi_csiphy_interrupt_clear0_addr = 0x858, + .mipi_csiphy_glbl_irq_cmd_addr = 0x828, + .csiphy_common_array_size = 5, + .csiphy_reset_array_size = 5, + .csiphy_2ph_config_array_size = 18, + .csiphy_3ph_config_array_size = 43, + .csiphy_2ph_clock_lane = 0x1, + .csiphy_2ph_combo_ck_ln = 0x10, +}; + +struct csiphy_reg_t csiphy_common_reg_1_1[] = { + {0x0814, 0xd5, 0x00, CSIPHY_LANE_ENABLE}, + {0x0818, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x081C, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x01, 0x01, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, +}; + +struct csiphy_reg_t csiphy_reset_reg_1_1[] = { + {0x0814, 0x00, 0x05, CSIPHY_LANE_ENABLE}, + {0x0818, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x081C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x01, 0x01, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, +}; + +struct csiphy_reg_t csiphy_irq_reg_1_1[] = { + {0x082c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0830, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0834, 0xFB, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0838, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x083c, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0840, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0844, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0848, 0xEF, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x084c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0850, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0854, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, +}; + +struct +csiphy_reg_t csiphy_2ph_v1_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { + { + {0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0034, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x001C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0000, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0008, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0060, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0064, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + }, + { + {0x0704, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0734, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x071C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0714, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x073C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0708, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x070C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0760, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0764, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + }, + { + {0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0234, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x021C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0200, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0208, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x020C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0260, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0264, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + }, + { + {0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0434, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x041C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0428, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x043C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0400, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0408, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x040C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0460, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0464, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + }, + { + {0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0634, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x061C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0628, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0600, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0608, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x060C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0660, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0664, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + }, +}; + +struct csiphy_reg_t + csiphy_2ph_v1_1_combo_mode_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { + { + {0x0024, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0900, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0908, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0904, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0034, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x001C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0000, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0008, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x000C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0060, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0064, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + }, + { + {0x0724, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0C80, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0C88, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0C84, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0704, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0734, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x071C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0714, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x073C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0708, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x070C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0760, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0764, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + }, + { + {0x0224, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0A00, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A08, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A04, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0234, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x021C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0200, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0208, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x020C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0260, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0264, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + }, + { + {0x0424, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0B00, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B08, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B04, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0434, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0418, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x041C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0428, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x043C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0400, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0408, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x040C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0460, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0464, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + }, + { + {0x0624, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0C00, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0C08, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0C04, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0634, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x061C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0624, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0628, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0600, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0608, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x060C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0638, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0660, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0664, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + }, +}; + +struct +csiphy_reg_t csiphy_3ph_v1_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { + { + {0x0144, 0xB6, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0990, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0994, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0998, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0990, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0994, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0998, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x098C, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x098C, 0x5F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0168, 0x8E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x016C, 0x59, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0104, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x010C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0108, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0114, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0150, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0188, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x018C, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0190, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0118, 0x3e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x011C, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0120, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0124, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0128, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x012C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0144, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0160, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0164, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0980, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B0, 0x24, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0984, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0988, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09AC, 0x55, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0164, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + }, + { + {0x0344, 0xB6, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A90, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A94, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A98, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A8C, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A8C, 0x5F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0368, 0x8E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x036C, 0x59, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x030C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0308, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0314, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0350, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0388, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x038C, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0390, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0318, 0x3e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x031C, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0320, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0324, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0328, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x032C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0344, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0360, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0364, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A80, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x24, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A84, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A88, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AAC, 0x55, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0364, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + }, + { + {0x0544, 0xB6, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B90, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B94, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B98, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B8C, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B8C, 0x5F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0568, 0x8E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x056C, 0x59, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0504, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x050C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0508, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0514, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0550, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0588, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x058C, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0590, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0518, 0x3e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x051C, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0520, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0524, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0528, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x052C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0544, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0560, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0564, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B80, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x24, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B84, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B88, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BAC, 0x55, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0564, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + }, +}; + +struct csiphy_reg_t + csiphy_3ph_v1_1_combo_mode_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { + { + {0x0144, 0xB6, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0990, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0994, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0998, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0990, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0994, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0998, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x098C, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x098C, 0x5F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0168, 0x8E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x016C, 0x59, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0104, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x010C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0108, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0114, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0150, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0188, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x018C, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0190, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0118, 0x3e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x011C, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0120, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0124, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0128, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x012C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0144, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0160, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0164, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0980, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B0, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0984, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0988, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09AC, 0x55, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0164, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DNP_PARAMS}, + }, + { + {0x0344, 0xB6, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A90, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A94, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A98, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A8C, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A8C, 0x5F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0368, 0x8E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x036C, 0x59, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x030C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0308, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0314, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0350, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0388, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x038C, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0390, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0318, 0x3e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x031C, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0320, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0324, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0328, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x032C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0344, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0360, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0364, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A80, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A84, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A88, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AAC, 0x55, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0364, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DNP_PARAMS}, + }, + { + {0x0544, 0xB6, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B90, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B94, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B98, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B8C, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B8C, 0x5F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0568, 0x8E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x056C, 0x59, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0504, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x050C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0508, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0514, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0550, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0588, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x058C, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0590, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0518, 0x3e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x051C, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0520, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0524, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0528, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x052C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0544, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0560, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0564, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B80, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x48, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B84, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B88, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BAC, 0x55, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05DC, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0564, 0x2B, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + }, +}; + + +struct data_rate_settings_t data_rate_delta_table_1_1 = { + .num_data_rate_settings = 2, + .data_rate_settings = { + { + // data rate <= 2.3 Gsps + // max bandwidth = 2.3 * 2.28 * (10**3) Mbps + .bandwidth = 5243000000, + .data_rate_reg_array_size = 3, + .csiphy_data_rate_regs = { + {0x09B0, 0x23, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x23, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x23, 0x00, CSIPHY_DEFAULT_PARAMS} + } + }, + { + // 2.3 Gsps <= data rate <= 2.5 Gsps + // max bandwidth = 2.5 * 2.28 * (10**3) Mbps + .bandwidth = 5700000000, + .data_rate_reg_array_size = 3, + .csiphy_data_rate_regs = { + {0x09B0, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS} + } + } + } +}; + +#endif /* _CAM_CSIPHY_1_1_HWREG_H_ */ diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 6f1f32e80e03..07e1f0ec6c60 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -905,6 +905,14 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) if (rc) { CAM_ERR(CAM_EEPROM, "read_eeprom_memory failed"); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + cam_destroy_device_hdl(e_ctrl->bridge_intf.device_hdl); + CAM_ERR(CAM_EEPROM, "destroying the device hdl"); + + e_ctrl->bridge_intf.device_hdl = -1; + e_ctrl->bridge_intf.link_hdl = -1; + e_ctrl->bridge_intf.session_hdl = -1; +#endif goto power_down; } diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c index 0123cb3a83d5..b3cdd9898af2 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c @@ -64,6 +64,11 @@ int32_t cam_ois_construct_default_power_setting( } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define CUSTOM_INIT_DL +#define OIS_TRANS_SIZE 64 +#endif + /** * cam_ois_get_dev_handle - get device handle * @o_ctrl: ctrl structure @@ -300,6 +305,40 @@ static int cam_ois_slaveInfo_pkt_parser(struct cam_ois_ctrl_t *o_ctrl, return rc; } +#ifdef CUSTOM_INIT_DL +struct cam_sensor_i2c_reg_array ois_init0_array[]= { + {0x8262, 0xFF02, 0x0, 0x0}, + {0x8263, 0x9F05, 0x0, 0x0}, + {0x8264, 0x6040, 0x0, 0x0}, + {0x8260, 0x1130, 0x0, 0x0}, + {0x8265, 0x8000, 0x0, 0x0}, + {0x8261, 0x0280, 0x0, 0x0}, + {0x8261, 0x0380, 0x0, 0x0}, + {0x8261, 0x0988, 0x0, 0x0}, +}; + +static int cam_ois_fw_init0(struct cam_ois_ctrl_t *o_ctrl) +{ + int32_t rc = 0; + struct cam_sensor_i2c_reg_setting write_setting; + write_setting.size= sizeof(ois_init0_array)/sizeof(struct cam_sensor_i2c_reg_array); + write_setting.addr_type =CAMERA_SENSOR_I2C_TYPE_WORD; + write_setting.data_type= CAMERA_SENSOR_I2C_TYPE_WORD; + write_setting.delay=0; + write_setting.reg_setting= ois_init0_array; + + rc = camera_io_dev_write(&(o_ctrl->io_master_info), + &write_setting); + if (rc < 0) { + CAM_ERR(CAM_OIS, + "{debug-ois}Failed in Applying i2c wrt settings"); + return rc; + } + + return rc; +} +#endif + static int cam_ois_fw_download(struct cam_ois_ctrl_t *o_ctrl) { uint16_t total_bytes = 0; @@ -314,6 +353,9 @@ static int cam_ois_fw_download(struct cam_ois_ctrl_t *o_ctrl) struct device *dev = &(o_ctrl->pdev->dev); struct cam_sensor_i2c_reg_setting i2c_reg_setting; struct page *page = NULL; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int32_t i; +#endif if (!o_ctrl) { CAM_ERR(CAM_OIS, "Invalid Args"); @@ -328,6 +370,10 @@ static int cam_ois_fw_download(struct cam_ois_ctrl_t *o_ctrl) fw_name_prog = name_prog; fw_name_coeff = name_coeff; +#ifdef CUSTOM_INIT_DL + cam_ois_fw_init0(o_ctrl); +#endif + /* Load FW */ rc = request_firmware(&fw, fw_name_prog, dev); if (rc) { @@ -353,6 +399,26 @@ static int cam_ois_fw_download(struct cam_ois_ctrl_t *o_ctrl) i2c_reg_setting.reg_setting = (struct cam_sensor_i2c_reg_array *) ( page_address(page)); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + for (i = 0, ptr = (uint8_t *)fw->data; i < total_bytes;) { + for (cnt = 0; cnt < OIS_TRANS_SIZE && i < total_bytes; + cnt++, ptr++, i++) { + i2c_reg_setting.reg_setting[cnt].reg_addr = + o_ctrl->opcode.prog; + i2c_reg_setting.reg_setting[cnt].reg_data = *ptr; + i2c_reg_setting.reg_setting[cnt].delay = 0; + i2c_reg_setting.reg_setting[cnt].data_mask = 0; + } + i2c_reg_setting.size = cnt; + + rc = camera_io_dev_write_continuous(&(o_ctrl->io_master_info), + &i2c_reg_setting, 1); + if (rc < 0) { + CAM_ERR(CAM_OIS, "OIS FW download failed %d", rc); + goto release_firmware; + } + } +#else for (cnt = 0, ptr = (uint8_t *)fw->data; cnt < total_bytes; cnt++, ptr++) { i2c_reg_setting.reg_setting[cnt].reg_addr = @@ -368,6 +434,7 @@ static int cam_ois_fw_download(struct cam_ois_ctrl_t *o_ctrl) CAM_ERR(CAM_OIS, "OIS FW download failed %d", rc); goto release_firmware; } +#endif cma_release(dev_get_cma_area((o_ctrl->soc_info.dev)), page, fw_size); page = NULL; @@ -398,6 +465,25 @@ static int cam_ois_fw_download(struct cam_ois_ctrl_t *o_ctrl) i2c_reg_setting.reg_setting = (struct cam_sensor_i2c_reg_array *) ( page_address(page)); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + for (i = 0, ptr = (uint8_t *)fw->data; i < total_bytes;) { + for (cnt = 0; cnt < OIS_TRANS_SIZE && i < total_bytes; + cnt++, ptr++, i++) { + i2c_reg_setting.reg_setting[cnt].reg_addr = + o_ctrl->opcode.coeff; + i2c_reg_setting.reg_setting[cnt].reg_data = *ptr; + i2c_reg_setting.reg_setting[cnt].delay = 0; + i2c_reg_setting.reg_setting[cnt].data_mask = 0; + } + + i2c_reg_setting.size = cnt; + + rc = camera_io_dev_write_continuous(&(o_ctrl->io_master_info), + &i2c_reg_setting, 1); + if (rc < 0) + CAM_ERR(CAM_OIS, "OIS FW download failed %d", rc); + } +#else for (cnt = 0, ptr = (uint8_t *)fw->data; cnt < total_bytes; cnt++, ptr++) { i2c_reg_setting.reg_setting[cnt].reg_addr = @@ -411,6 +497,7 @@ static int cam_ois_fw_download(struct cam_ois_ctrl_t *o_ctrl) &i2c_reg_setting, 1); if (rc < 0) CAM_ERR(CAM_OIS, "OIS FW download failed %d", rc); +#endif release_firmware: cma_release(dev_get_cma_area((o_ctrl->soc_info.dev)), diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c index a20ac4962345..655187b65686 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -647,6 +647,9 @@ int cam_sensor_match_id(struct cam_sensor_ctrl_t *s_ctrl) return rc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +uint32_t operation_mode = 0; +#endif int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, void *arg) { @@ -775,6 +778,10 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, goto release_mutex; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + operation_mode = sensor_acq_dev.operation_mode; +#endif + bridge_params.session_hdl = sensor_acq_dev.session_handle; bridge_params.ops = &s_ctrl->bridge_intf.ops; bridge_params.v4l2_sub_dev_flag = 0; @@ -997,6 +1004,100 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, } } break; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case CAM_UPDATE_REG: { + struct cam_sensor_i2c_reg_setting user_reg_setting; + struct cam_sensor_i2c_reg_array *i2c_reg_setting = NULL; + int i; + + rc = copy_from_user(&user_reg_setting, (void __user *)cmd->handle, sizeof(user_reg_setting)); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, "Copy data from user space failed\n"); + goto release_mutex; + } + + CAM_DBG(CAM_SENSOR, "CAM_UPDATE_REG reg setting size = %d", user_reg_setting.size); + i2c_reg_setting = kzalloc(sizeof(struct cam_sensor_i2c_reg_array) * + user_reg_setting.size, GFP_KERNEL); + if (!i2c_reg_setting) { + rc = -ENOMEM; + CAM_ERR(CAM_SENSOR, "kzalloc memory failed\n"); + goto release_mutex; + } + + rc = copy_from_user(i2c_reg_setting, (void __user *)user_reg_setting.reg_setting, + sizeof(struct cam_sensor_i2c_reg_array) * user_reg_setting.size); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, "Copy i2c setting from user space failed\n"); + kfree(i2c_reg_setting); + goto release_mutex; + } + user_reg_setting.reg_setting = i2c_reg_setting; + + for (i = 0; i < user_reg_setting.size; i++) { + CAM_DBG(CAM_SENSOR, "CAM_UPDATE_REG reg_addr=0x%x, reg_value=0x%x", + i2c_reg_setting[i].reg_addr, i2c_reg_setting[i].reg_data); + } + + rc = camera_io_dev_write(&s_ctrl->io_master_info, &user_reg_setting); + if (rc < 0) + CAM_ERR(CAM_SENSOR, "Write setting failed, rc = %d\n", rc); + + kfree(i2c_reg_setting); + } + break; + case CAM_READ_REG: { + struct cam_sensor_i2c_reg_setting user_reg_setting; + struct cam_sensor_i2c_reg_array *i2c_reg_setting; + int ret = 0; + int i; + + rc = copy_from_user(&user_reg_setting, (void __user *)cmd->handle, sizeof(user_reg_setting)); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, "Copy data from user space failed"); + goto release_mutex; + } + + CAM_DBG(CAM_SENSOR, "CAM_READ_REG reg setting size = %d", user_reg_setting.size); + i2c_reg_setting = kzalloc(sizeof(struct cam_sensor_i2c_reg_array) * + user_reg_setting.size, GFP_KERNEL); + if (!i2c_reg_setting) { + rc = -ENOMEM; + CAM_ERR(CAM_SENSOR, "kzalloc memory failed\n"); + goto release_mutex; + } + + rc = copy_from_user(i2c_reg_setting, (void __user *)user_reg_setting.reg_setting, + sizeof(struct cam_sensor_i2c_reg_array) * user_reg_setting.size); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, "Copy i2c setting from user space failed"); + kfree(i2c_reg_setting); + goto release_mutex; + } + + for (i = 0; i < user_reg_setting.size; i++) { + ret += camera_io_dev_read( + &(s_ctrl->io_master_info), + i2c_reg_setting[i].reg_addr, + &i2c_reg_setting[i].reg_data, CAMERA_SENSOR_I2C_TYPE_WORD, + CAMERA_SENSOR_I2C_TYPE_BYTE); + CAM_DBG(CAM_SENSOR, "CAM_READ_REG reg_addr=0x%x, reg_value=0x%x, sid = 0x%x", + i2c_reg_setting[i].reg_addr, i2c_reg_setting[i].reg_data, s_ctrl->io_master_info.cci_client->sid); + } + + if (copy_to_user((void __user *)user_reg_setting.reg_setting, i2c_reg_setting, + sizeof(struct cam_sensor_i2c_reg_array) * user_reg_setting.size) || ret != 0) { + CAM_ERR(CAM_SENSOR, "Copy data to user space failed"); + rc = -EFAULT; + } + if (copy_to_user((void __user *)cmd->handle, &user_reg_setting, sizeof(user_reg_setting)) || ret != 0) { + CAM_ERR(CAM_SENSOR, "Copy data to user space failed"); + rc = -EFAULT; + } + kfree(i2c_reg_setting); + } + break; +#endif default: CAM_ERR(CAM_SENSOR, "Invalid Opcode: %d", cmd->op_code); rc = -EINVAL; @@ -1036,12 +1137,23 @@ int cam_sensor_publish_dev_info(struct cam_req_mgr_device_info *info) info->dev_id = CAM_REQ_MGR_DEVICE_SENSOR; strlcpy(info->name, CAM_SENSOR_NAME, sizeof(info->name)); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (s_ctrl->pipeline_delay >= 0 && s_ctrl->pipeline_delay <= 3) +#else if (s_ctrl->pipeline_delay >= 1 && s_ctrl->pipeline_delay <= 3) +#endif info->p_delay = s_ctrl->pipeline_delay; else info->p_delay = 2; info->trigger = CAM_TRIGGER_POINT_SOF; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (operation_mode == 0x8006) + info->p_delay = 0; + if (operation_mode == 0x8002) + info->p_delay = 1; +#endif + return rc; } diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h b/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h index c3cb345a13fa..a4d6fb5d6a92 100644 --- a/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h +++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h @@ -31,7 +31,11 @@ #endif #define CAM_SYNC_OBJ_NAME_LEN 64 +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define CAM_SYNC_MAX_OBJS 1280 +#else #define CAM_SYNC_MAX_OBJS 1024 +#endif #define CAM_SYNC_MAX_V4L2_EVENTS 50 #define CAM_SYNC_DEBUG_FILENAME "cam_debug" #define CAM_SYNC_DEBUG_BASEDIR "cam" diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.c b/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.c index 7935ada7bd53..29babcc37c7e 100644 --- a/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.c +++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.c @@ -80,6 +80,16 @@ int cam_sync_init_group_object(struct sync_table_row *table, */ for (i = 0; i < num_objs; i++) { child_row = table + sync_objs[i]; + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (idx == sync_objs[i] || (sync_objs[i] >= CAM_SYNC_MAX_OBJS)) { + CAM_ERR(CAM_SYNC, "invalid fence:%d should be released", + sync_objs[i]); + rc = -EINVAL; + goto clean_children_info; + } +#endif + spin_lock_bh(&sync_dev->row_spinlocks[sync_objs[i]]); /* validate child */ diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h index d0bab027790e..9e6e14024893 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h +++ b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h @@ -36,7 +36,11 @@ #define CAM_SOC_MAX_BASE CAM_SOC_MAX_BLOCK /* maximum number of device regulator */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define CAM_SOC_MAX_REGULATOR 6 +#else #define CAM_SOC_MAX_REGULATOR 5 +#endif /* maximum number of device clock */ #define CAM_SOC_MAX_CLK 32 diff --git a/include/uapi/media/cam_defs.h b/include/uapi/media/cam_defs.h index 0fa3777ee7a5..abdda6339daa 100644 --- a/include/uapi/media/cam_defs.h +++ b/include/uapi/media/cam_defs.h @@ -26,6 +26,11 @@ #define CAM_EXT_OPCODE_BASE 0x200 #define CAM_CONFIG_DEV_EXTERNAL (CAM_EXT_OPCODE_BASE + 0x1) +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define CAM_UPDATE_REG (CAM_EXT_OPCODE_BASE + 0x2) +#define CAM_READ_REG (CAM_EXT_OPCODE_BASE + 0x3) +#endif + /* camera handle type */ #define CAM_HANDLE_USER_POINTER 1 #define CAM_HANDLE_MEM_HANDLE 2 diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h index 50b81276d0e1..c1b8abd29c40 100644 --- a/include/uapi/media/cam_req_mgr.h +++ b/include/uapi/media/cam_req_mgr.h @@ -35,7 +35,11 @@ * Max handles supported by cam_req_mgr * It includes both session and device handles */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define CAM_REQ_MGR_MAX_HANDLES 128 +#else #define CAM_REQ_MGR_MAX_HANDLES 64 +#endif #define CAM_REQ_MGR_MAX_HANDLES_V2 128 #define MAX_LINKS_PER_SESSION 2 diff --git a/include/uapi/media/cam_sensor.h b/include/uapi/media/cam_sensor.h index 8fc180b7b632..72b6ee4053c9 100644 --- a/include/uapi/media/cam_sensor.h +++ b/include/uapi/media/cam_sensor.h @@ -370,6 +370,9 @@ struct cam_sensor_acquire_dev { uint32_t handle_type; uint32_t reserved; uint64_t info_handle; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + uint32_t operation_mode; +#endif } __attribute__((packed)); /** From 10fecf7a22762dc338c3549713b9c288406558f0 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 28 Aug 2024 17:02:20 +0200 Subject: [PATCH 074/226] arch: arm64: boot: dts: qcom: xiaomi: Commonize IR binding Change-Id: I377682516716686626b94c220f27f93207b46553 Signed-off-by: firebird11 --- .../qcom/xiaomi/overlay/cepheus/cepheus-sm8150.dtsi | 10 +--------- arch/arm64/boot/dts/qcom/xiaomi/overlay/common/ir.dtsi | 9 +++++++++ .../boot/dts/qcom/xiaomi/overlay/crux/crux-sm8150.dtsi | 10 +--------- .../boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi | 10 +--------- .../boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi | 10 +--------- 5 files changed, 13 insertions(+), 36 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/xiaomi/overlay/common/ir.dtsi diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-sm8150.dtsi index 5a3a024b5cff..d9789a1dba6f 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/cepheus/cepheus-sm8150.dtsi @@ -315,15 +315,7 @@ And public attribution of xiaomi platforms(like F1 and so and) }; -&qupv3_se1_spi { - status = "ok"; - irled@0 { - compatible = "ir-spi"; - reg = <0x0>; - status = "ok"; - spi-max-frequency = <19200000>; - }; -}; +#include "../common/ir.dtsi" &pm8150l_lpg { qcom,lut-patterns = <0 1 2 3 4 5 7 9 11 13 15 diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/ir.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/ir.dtsi new file mode 100644 index 000000000000..e7c91aa569e2 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/ir.dtsi @@ -0,0 +1,9 @@ +&qupv3_se1_spi { + status = "ok"; + irled@0 { + compatible = "ir-spi"; + reg = <0x0>; + status = "ok"; + spi-max-frequency = <19200000>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-sm8150.dtsi index 13907b71874d..63bf537c35e6 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/crux/crux-sm8150.dtsi @@ -789,15 +789,7 @@ And public attribution of xiaomi platforms(like F1X and so and) // qcom,esd-err-irq-gpio = <&tlmm 101 0x2002>; //}; -&qupv3_se1_spi { - status = "ok"; - irled@0 { - compatible = "ir-spi"; - reg = <0x0>; - status = "ok"; - spi-max-frequency = <19200000>; - }; -}; +#include "../common/ir.dtsi" &qupv3_se7_i2c { status = "ok"; diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi index f31136085341..2a542400b64e 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/nabu/nabu-sm8150.dtsi @@ -780,15 +780,7 @@ And public attribution of xiaomi platforms(like J20S and so and) }; }; -&qupv3_se1_spi { - status = "ok"; - irled@0 { - compatible = "ir-spi"; - reg = <0x0>; - status = "ok"; - spi-max-frequency = <19200000>; - }; -}; +#include "../common/ir.dtsi" &pm8150l_lpg { qcom,lut-patterns = <0 1 2 3 4 5 7 9 11 13 15 diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi index b65899889e98..2e2470c20d76 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/vayu/vayu-sm8150.dtsi @@ -1539,15 +1539,7 @@ And public attribution of xiaomi platforms(like J20S and so and) }; }; -&qupv3_se1_spi { - status = "ok"; - irled@0 { - compatible = "ir-spi"; - reg = <0x0>; - status = "ok"; - spi-max-frequency = <19200000>; - }; -}; +#include "../common/ir.dtsi" &pm8150l_lpg { qcom,lut-patterns = <0 1 2 3 4 5 7 9 11 13 15 From 15d74a88d23cb8d972afc6bfc515e70569004315 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 28 Aug 2024 17:04:14 +0200 Subject: [PATCH 075/226] arch: arm64: boot: dts: qcom: xiaomi: Adapt IR SPI binding for upstream driver Change-Id: I9002f2e8d3a214195fe6131cc38d2a09e4c4c6f2 Signed-off-by: firebird11 --- arch/arm64/boot/dts/qcom/xiaomi/overlay/common/ir.dtsi | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/ir.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/ir.dtsi index e7c91aa569e2..538d11a8b054 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/ir.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/overlay/common/ir.dtsi @@ -1,8 +1,16 @@ +&soc { + irda_regulator: irda-regulator { + compatible = "regulator-dummy"; + regulator-name = "irda_regulator"; + }; +}; + &qupv3_se1_spi { status = "ok"; irled@0 { - compatible = "ir-spi"; + compatible = "ir-spi-led"; reg = <0x0>; + power-supply = <&irda_regulator>; status = "ok"; spi-max-frequency = <19200000>; }; From 2e17daa96f7472116129edf826949352a98c3ef3 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 18:26:43 +0200 Subject: [PATCH 076/226] drivers: mfd: Import Xiaomi speaker ID driver * Run clang-format on source files Change-Id: Ibc8087ded16d22bb368ce8c3f10f9e1d79ae03fa Signed-off-by: firebird11 --- drivers/mfd/Kconfig | 5 + drivers/mfd/Makefile | 2 + drivers/mfd/spk-id.c | 235 +++++++++++++++++++++++++++++++++++++ include/linux/mfd/spk-id.h | 34 ++++++ 4 files changed, 276 insertions(+) create mode 100644 drivers/mfd/spk-id.c create mode 100644 include/linux/mfd/spk-id.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 99776c7768fd..aae080c9e012 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1829,5 +1829,10 @@ config MFD_VEXPRESS_SYSREG System Registers are the platform configuration block on the ARM Ltd. Versatile Express board. +config MFD_SPK_ID + bool "Versatile Express System Registers" + help + Xiaomi speaker ID driver. + endmenu endif diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index aef0d81d77c6..df705872a47a 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -228,3 +228,5 @@ obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o obj-$(CONFIG_MFD_STM32_LPTIMER) += stm32-lptimer.o obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o + +obj-$(CONFIG_MFD_SPK_ID) += spk-id.o diff --git a/drivers/mfd/spk-id.c b/drivers/mfd/spk-id.c new file mode 100644 index 000000000000..6860fed7fb5f --- /dev/null +++ b/drivers/mfd/spk-id.c @@ -0,0 +1,235 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ +#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct spk_id_info { + struct pinctrl *pinctrl; + struct pinctrl_state *pull_down; + struct pinctrl_state *pull_up; + struct pinctrl_state *no_pull; + int gpio; + int state; +}; + +static struct spk_id_info *spk_id_get_info(struct device_node *np) +{ + struct platform_device *pdev; + struct spk_id_info *info; + + if (!np) { + pr_err("%s: device node is null\n", __func__); + return NULL; + } + + pdev = of_find_device_by_node(np); + if (!pdev) { + pr_err("%s: platform device not found!\n", __func__); + return NULL; + } + + info = dev_get_drvdata(&pdev->dev); + if (!info) + dev_err(&pdev->dev, "%s: cannot find spk id info\n", __func__); + + return info; +} + +int spk_id_get_pin_3state(struct device_node *np) +{ + struct spk_id_info *info; + int pu = 0; + int pd = 0; + + info = spk_id_get_info(np); + if (!info) + return -EINVAL; + + if (IS_ERR_OR_NULL(info->pinctrl)) { + pr_err("%s: pin ctrl is invalid:%ld\n", __func__, + PTR_ERR(info->pinctrl)); + return -EINVAL; + } + + if (!gpio_is_valid(info->gpio)) { + pr_err("%s: gpio is invalid:%d\n", __func__, info->gpio); + return -EINVAL; + } + + pinctrl_select_state(info->pinctrl, info->pull_down); + msleep(3); + pd = gpio_get_value(info->gpio); + + pinctrl_select_state(info->pinctrl, info->pull_up); + msleep(3); + pu = gpio_get_value(info->gpio); + + if ((pd == pu) && (pd == 0)) { + pr_info("%s: id pin%d = %d\n", __func__, info->gpio, pd); + pinctrl_select_state(info->pinctrl, info->pull_down); + info->state = PIN_PULL_DOWN; + } else if ((pd == pu) && (pd == 1)) { + pr_info("%s: id pin%d = %d\n", __func__, info->gpio, pd); + pinctrl_select_state(info->pinctrl, info->pull_up); + info->state = PIN_PULL_UP; + } else { + pr_info("%s: id pin%d = 2\n", __func__, info->gpio); + pinctrl_select_state(info->pinctrl, info->no_pull); + info->state = PIN_FLOAT; + } + + return info->state; +} +EXPORT_SYMBOL(spk_id_get_pin_3state); + +int spk_id_get(struct device_node *np) +{ + int id; + int state; + + state = spk_id_get_pin_3state(np); + if (state < 0) { + pr_err("%s: Can not get id pin state, %d\n", __func__, state); + return VENDOR_ID_NONE; + } + + switch (state) { + case PIN_PULL_DOWN: + id = VENDOR_ID_AAC; + break; + case PIN_PULL_UP: + id = VENDOR_ID_UNKNOWN; + break; + case PIN_FLOAT: + id = VENDOR_ID_GOER; + break; + default: + id = VENDOR_ID_UNKNOWN; + break; + } + return id; +} +EXPORT_SYMBOL(spk_id_get); + +static int spk_id_probe(struct platform_device *pdev) +{ + int ret = 0; + struct spk_id_info *info; + + info = devm_kzalloc(&pdev->dev, sizeof(struct spk_id_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + dev_dbg(&pdev->dev, "%s: device %s\n", __func__, pdev->name); + info->pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR_OR_NULL(info->pinctrl)) { + dev_err(&pdev->dev, + "%s: Cannot get speaker id gpio pinctrl:%ld\n", + __func__, PTR_ERR(info->pinctrl)); + ret = PTR_ERR(info->pinctrl); + goto err_pctrl_get; + } + + info->pull_down = pinctrl_lookup_state(info->pinctrl, "pull_down"); + if (IS_ERR_OR_NULL(info->pull_down)) { + dev_err(&pdev->dev, + "%s: Cannot get pull_down pinctrl state:%ld\n", + __func__, PTR_ERR(info->pull_down)); + ret = PTR_ERR(info->pull_down); + goto err_lookup_state; + } + + info->pull_up = pinctrl_lookup_state(info->pinctrl, "pull_up"); + if (IS_ERR_OR_NULL(info->pull_up)) { + dev_err(&pdev->dev, + "%s: Cannot get pull_up pinctrl state:%ld\n", __func__, + PTR_ERR(info->pull_up)); + ret = PTR_ERR(info->pull_up); + goto err_lookup_state; + } + + info->no_pull = pinctrl_lookup_state(info->pinctrl, "no_pull"); + if (IS_ERR_OR_NULL(info->no_pull)) { + dev_err(&pdev->dev, + "%s: Cannot get no_pull pinctrl state:%ld\n", __func__, + PTR_ERR(info->no_pull)); + ret = PTR_ERR(info->no_pull); + goto err_lookup_state; + } + + info->gpio = of_get_named_gpio(pdev->dev.of_node, + "audio,speaker-id-gpio", 0); + if (gpio_is_valid(info->gpio)) { + ret = gpio_request(info->gpio, "speaker-id"); + if (ret) { + dev_err(&pdev->dev, "%s: Failed to request gpio %d\n", + __func__, info->gpio); + goto err_lookup_state; + } + } + + dev_set_drvdata(&pdev->dev, info); + return 0; + +err_lookup_state: + devm_pinctrl_put(info->pinctrl); +err_pctrl_get: + devm_kfree(&pdev->dev, info); + return ret; +} + +static int spk_id_remove(struct platform_device *pdev) +{ + struct spk_id_info *info; + + info = dev_get_drvdata(&pdev->dev); + + if (info) { + if (info->pinctrl) + devm_pinctrl_put(info->pinctrl); + if (gpio_is_valid(info->gpio)) + gpio_free(info->gpio); + } + + devm_kfree(&pdev->dev, info); + return 0; +} + +static const struct of_device_id spk_id_match[] = { + { .compatible = "audio,speaker-id" }, + {} +}; + +static struct platform_driver spk_id_driver = { + .driver = { + .name = "spk-id", + .owner = THIS_MODULE, + .of_match_table = spk_id_match, + }, + .probe = spk_id_probe, + .remove = spk_id_remove, +}; +module_platform_driver(spk_id_driver); + +MODULE_DESCRIPTION("Speaker ID platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mfd/spk-id.h b/include/linux/mfd/spk-id.h new file mode 100644 index 000000000000..1ca22e186ccd --- /dev/null +++ b/include/linux/mfd/spk-id.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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 __SPK_ID_H_ +#define __SPK_ID_H_ + +#include +#include + +#define PIN_PULL_DOWN 0 +#define PIN_PULL_UP 1 +#define PIN_FLOAT 2 + +#define VENDOR_ID_NONE 0 +#define VENDOR_ID_AAC 1 +#define VENDOR_ID_SSI 2 +#define VENDOR_ID_GOER 3 + +#define VENDOR_ID_UNKNOWN 4 + +int spk_id_get_pin_3state(struct device_node *np); +int spk_id_get(struct device_node *np); + +#endif From 69d662e8253416e991b7c082cbc7bbfddaa0a6e4 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 18:29:11 +0200 Subject: [PATCH 077/226] drivers: misc: Import AKM09970 driver * Run clang-format on source files Change-Id: I7b65cf4c0807c09d6d2a9f06e83ccdfe34afe43f Signed-off-by: firebird11 --- drivers/misc/Kconfig | 10 + drivers/misc/Makefile | 1 + drivers/misc/akm09970.c | 863 ++++++++++++++++++++++++++++++++++ include/uapi/linux/akm09970.h | 98 ++++ 4 files changed, 972 insertions(+) create mode 100644 drivers/misc/akm09970.c create mode 100644 include/uapi/linux/akm09970.h diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 2d4c9718efc8..d840c5508e77 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -595,6 +595,16 @@ config TEST_IRQ_REQUESTER If in doubt, say N. +config AKM09970 + tristate "INPUT_AK09970 digital hall sensor support" + depends on I2C + help + Say Y here if you have AKM Sensortec's AK09970 magnet + sensor hooked to an I2C bus. + + To compile this driver as a module, choose M here: the + module will be called akm09970. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 89fb698afadf..b8d2536975d7 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -65,6 +65,7 @@ obj-$(CONFIG_FPR_FPC) += fpr_FingerprintCard/ obj-$(CONFIG_UID_SYS_STATS) += uid_sys_stats.o obj-$(CONFIG_MEMORY_STATE_TIME) += memory_state_time.o obj-$(CONFIG_QPNP_MISC) += qpnp-misc.o +obj-$(CONFIG_AKM09970) += akm09970.o obj-$(CONFIG_OKL4_USER_VIRQ) += okl4-virq.o obj-$(CONFIG_OKL4_RINGBUF) += okl4-ringbuf.o diff --git a/drivers/misc/akm09970.c b/drivers/misc/akm09970.c new file mode 100644 index 000000000000..0ca357f936bb --- /dev/null +++ b/drivers/misc/akm09970.c @@ -0,0 +1,863 @@ +/* drivers/intput/misc/akm09970.c - akm09970 compass driver + * + * Copyright (c) 2018-2019, Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +//#define DEBUG +#define pr_fmt(fmt) "akm09970: %s: %d " fmt, __func__, __LINE__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "uapi/linux/akm09970.h" + +#define CLEAR_IRQ_TIME 20 + +static DECLARE_WAIT_QUEUE_HEAD(poll_wait_queue); + +struct akm09970_soc_ctrl { + uint8_t chip_info[AKM_SENSOR_INFO_SIZE]; + uint8_t chip_data[AKM_SENSOR_DATA_SIZE]; + uint8_t measure_range; + uint32_t measure_freq_hz; + bool read_flag; + + atomic_t power_enabled; + atomic_t data_ready; + + int gpio_reset; + int gpio_irq; + int irq; + + struct akm09970_platform_data pdata; + + dev_t dev_num; + struct device *dev; + struct cdev cdev; + struct class *chr_class; + struct device *chr_dev; + + struct device_node *of_node; + + struct i2c_client *client; + + struct pinctrl *pinctrl; + struct pinctrl_state *gpio_state_active; + struct pinctrl_state *gpio_state_suspend; + + struct regulator *vdd; + + struct hrtimer timer; + + struct work_struct report_work; + struct workqueue_struct *work_queue; +}; + +static int akm09970_write_byte(struct i2c_client *client, u8 reg, u8 val) +{ + int rc; + + if (client->irq) + disable_irq_nosync(client->irq); + + rc = i2c_smbus_write_byte_data(client, reg, val); + + if (client->irq) + enable_irq(client->irq); + + return rc; +} + +static int akm09970_set_reg_bits(struct i2c_client *client, int val, int shift, + u8 mask, u8 reg) +{ + int data; + + data = i2c_smbus_read_byte_data(client, reg); + if (data < 0) + return data; + + data = (data & ~mask) | ((val << shift) & mask); + pr_info("reg: 0x%x, data: 0x%x", reg, data); + return akm09970_write_byte(client, reg, data); +} + +static int akm09970_set_mode(struct akm09970_soc_ctrl *c_ctrl, uint8_t mode) +{ + int rc; + + rc = akm09970_set_reg_bits(c_ctrl->client, mode, AK09970_MODE_POS, + AK09970_MODE_MSK, AK09970_MODE_REG); + + return rc; +} + +static enum hrtimer_restart hrtimer_handler(struct hrtimer *timer_t) +{ + struct akm09970_soc_ctrl *c_ctrl = + container_of(timer_t, struct akm09970_soc_ctrl, timer); + + if (!c_ctrl->read_flag) + queue_work(c_ctrl->work_queue, &c_ctrl->report_work); + + return HRTIMER_NORESTART; +} + +static void akm09970_reset(struct akm09970_soc_ctrl *c_ctrl) +{ + gpio_set_value(c_ctrl->gpio_reset, 0); + udelay(50); + gpio_set_value(c_ctrl->gpio_reset, 1); + udelay(100); + + return; +} + +static int akm09970_power_down(struct akm09970_soc_ctrl *c_ctrl) +{ + int rc = 0; + + if (atomic_read(&c_ctrl->power_enabled)) { + gpio_set_value(c_ctrl->gpio_reset, 0); + + rc = regulator_disable(c_ctrl->vdd); + if (rc) { + pr_err("Regulator vdd disable failed rc=%d\n", rc); + } + atomic_set(&c_ctrl->power_enabled, 0); + pr_debug("Power down successfully"); + } + + return rc; +} + +static int akm09970_power_up(struct akm09970_soc_ctrl *c_ctrl) +{ + int rc = 0; + + if (!atomic_read(&c_ctrl->power_enabled)) { + rc = regulator_enable(c_ctrl->vdd); + if (rc) { + pr_err("Regulator vdd enable failed rc=%d\n", rc); + return rc; + } + udelay(20); + akm09970_reset(c_ctrl); + atomic_set(&c_ctrl->power_enabled, 1); + pr_debug("Power down successfully"); + } + + return rc; +} + +static int akm09970_active(struct akm09970_soc_ctrl *c_ctrl, bool on) +{ + int rc = 0; + uint8_t mode = 0x00; + + pr_info("akm sensor %s\n", on ? "on" : "off"); + + if (!atomic_read(&c_ctrl->power_enabled) && on) { + rc = akm09970_power_up(c_ctrl); + if (rc) { + pr_err("Sensor power up fail!\n"); + return rc; + } + + if (c_ctrl->measure_freq_hz >= 100) + mode = AK09970_MODE_CONTINUOUS_100HZ; + else if (c_ctrl->measure_freq_hz >= 50 && + c_ctrl->measure_freq_hz < 100) + mode = AK09970_MODE_CONTINUOUS_50HZ; + else if (c_ctrl->measure_freq_hz >= 20 && + c_ctrl->measure_freq_hz < 50) + mode = AK09970_MODE_CONTINUOUS_20HZ; + else + mode = AK09970_MODE_CONTINUOUS_10HZ; + + c_ctrl->measure_range = 0; + + rc = akm09970_write_byte(c_ctrl->client, AK09970_MODE_REG, + (mode | c_ctrl->measure_range)); + if (rc < 0) { + pr_err("Failed to set mode and smr."); + akm09970_power_down(c_ctrl); + return rc; + } + pr_info("reg: 0x%x, data: 0x%x", AK09970_MODE_REG, + (mode | c_ctrl->measure_range)); + + enable_irq(c_ctrl->irq); + hrtimer_start(&c_ctrl->timer, + ktime_set(CLEAR_IRQ_TIME / MSEC_PER_SEC, + (CLEAR_IRQ_TIME % MSEC_PER_SEC) * + NSEC_PER_MSEC), + HRTIMER_MODE_REL); + c_ctrl->read_flag = false; + pr_debug("Enable irq successfully"); + } else if (atomic_read(&c_ctrl->power_enabled) && !on) { + disable_irq_nosync(c_ctrl->irq); + cancel_work_sync(&c_ctrl->report_work); + c_ctrl->read_flag = false; + pr_err("Disable irq successfully"); + + rc = akm09970_set_mode(c_ctrl, AK09970_MODE_POWERDOWN); + if (rc) + pr_warn("Failed to set to POWERDOWN mode.\n"); + + akm09970_power_down(c_ctrl); + } else { + pr_info("The same power state, do nothing!"); + } + + return 0; +} + +static int akm09970_read_data(struct akm09970_soc_ctrl *c_ctrl) +{ + int rc = 0; + + rc = i2c_smbus_read_i2c_block_data(c_ctrl->client, AK09970_REG_ST_XYZ, + AKM_SENSOR_DATA_SIZE, + c_ctrl->chip_data); + if (rc < 0) { + pr_err("read data failed!"); + return rc; + } + + if (AKM_ERRADC_IS_HIGH(c_ctrl->chip_data[0])) { + pr_err("ADC over run!\n"); + rc = -EIO; + } + + if (AKM_ERRXY_IS_HIGH(c_ctrl->chip_data[1])) { + pr_err("Errxy over run!\n"); + rc = -EIO; + } + + return 0; +} + +static void akm09970_dev_work_queue(struct work_struct *work) +{ + int rc = 0; + struct akm09970_soc_ctrl *c_ctrl = + container_of(work, struct akm09970_soc_ctrl, report_work); + + rc = akm09970_read_data(c_ctrl); + if (rc < 0) { + atomic_set(&c_ctrl->data_ready, 0); + pr_warn("Failed to read data"); + } else { + atomic_set(&c_ctrl->data_ready, 1); + wake_up(&poll_wait_queue); + c_ctrl->read_flag = true; + } +} + +static irqreturn_t akm09970_irq_handler(int irq, void *dev_id) +{ + struct akm09970_soc_ctrl *c_ctrl = dev_id; + + queue_work(c_ctrl->work_queue, &c_ctrl->report_work); + + return IRQ_HANDLED; +} + +static int akm09970_release(struct inode *inp, struct file *filp) +{ + int rc = 0; + + return rc; +} + +static int akm09970_open(struct inode *inp, struct file *filp) +{ + int rc = 0; + struct akm09970_soc_ctrl *c_ctrl = + container_of(inp->i_cdev, struct akm09970_soc_ctrl, cdev); + + filp->private_data = c_ctrl; + + pr_debug("open enter, irq = %d\n", c_ctrl->irq); + + return rc; +} + +static ssize_t akm09970_write(struct file *filp, const char *buf, size_t len, + loff_t *fseek) +{ + int rc = 0; + + return rc; +} + +static ssize_t akm09970_read(struct file *filp, char *buf, size_t len, + loff_t *fseek) +{ + int rc = 0; + + return rc; +} + +static unsigned int akm09970_poll(struct file *filp, poll_table *wait) +{ + unsigned int mask = 0; + struct akm09970_soc_ctrl *c_ctrl = filp->private_data; + + pr_debug("Poll enter\n"); + + poll_wait(filp, &poll_wait_queue, wait); + if (atomic_read(&c_ctrl->data_ready)) { + atomic_set(&c_ctrl->data_ready, 0); + mask = POLLIN | POLLRDNORM; + } + + return mask; +} + +static long akm09970_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + int rc = 0; + int i = 0; + struct akm09970_soc_ctrl *c_ctrl = filp->private_data; + + if (NULL == c_ctrl) { + pr_err("NULL"); + return -EFAULT; + } + + if (_IOC_TYPE(cmd) != AKM_IOC_MAGIC) { + pr_err("magic number worng"); + return -ENODEV; + } + + if (_IOC_DIR(cmd) & _IOC_READ) + rc = !access_ok(VERIFY_WRITE, (void __user *)arg, + _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + rc = !access_ok(VERIFY_READ, (void __user *)arg, + _IOC_SIZE(cmd)); + if (rc) { + pr_err("access failed"); + return -EFAULT; + } + + if (_IOC_DIR(cmd) & _IOC_WRITE) { + if (copy_from_user(&c_ctrl->pdata, (void __user *)arg, + sizeof(struct akm09970_platform_data))) { + pr_err("Copy data from user space failed"); + return -EFAULT; + } + } + + switch (cmd) { + case AKM_IOC_SET_ACTIVE: + pr_err("AKM_IOC_SET_ACTIVE, c_ctrl->pdata.sensor_state = %d\n", + c_ctrl->pdata.sensor_state); + rc = akm09970_active(c_ctrl, c_ctrl->pdata.sensor_state); + break; + case AKM_IOC_SET_MODE: + pr_err("AKM_IOC_SET_MODE, c_ctrl->pdata.sensor_mode = %d\n", + c_ctrl->pdata.sensor_mode); + c_ctrl->measure_freq_hz = c_ctrl->pdata.sensor_mode; + //rc = akm09970_set_mode(pctrl, mode); + break; + case AKM_IOC_GET_SENSSMR: + pr_err("AKM_IOC_GET_SENSSMR, c_ctrl->measure_range = %d", + c_ctrl->measure_range); + c_ctrl->pdata.sensor_smr = c_ctrl->measure_range; + break; + case AKM_IOC_GET_SENSEDATA: + pr_debug("AKM_IOC_GET_SENSEDATA"); + for (i = 0; i < AKM_SENSOR_DATA_SIZE; i++) { + c_ctrl->pdata.data[i] = c_ctrl->chip_data[i]; + pr_debug("data%d = %d\n", i, c_ctrl->chip_data[i]); + } + break; + default: + pr_warn("unsupport cmd:0x%x\n", cmd); + break; + } + + if (_IOC_DIR(cmd) & _IOC_READ) { + if (copy_to_user((void __user *)arg, &c_ctrl->pdata, + sizeof(struct akm09970_platform_data))) { + pr_err("Copy data from user space failed"); + return -EFAULT; + } + } + + return rc; +} + +#ifdef CONFIG_COMPAT +static long akm09970_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + return akm09970_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); +} +#endif + +static const struct file_operations akm09970_fops = { + .owner = THIS_MODULE, + .open = akm09970_open, + .release = akm09970_release, + .read = akm09970_read, + .write = akm09970_write, + .unlocked_ioctl = akm09970_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = akm09970_compat_ioctl, +#endif + .poll = akm09970_poll, +}; + +static int akm09970_check_device_id(struct akm09970_soc_ctrl *c_ctrl) +{ + int rc = 0; + + rc = akm09970_power_up(c_ctrl); + if (rc < 0) + return rc; + + rc = i2c_smbus_read_i2c_block_data(c_ctrl->client, AK09970_REG_WIA, + AKM_SENSOR_INFO_SIZE, + c_ctrl->chip_info); + if (rc < 0) + goto exit; + + if ((c_ctrl->chip_info[0] != AK09970_WIA1_VALUE) || + (c_ctrl->chip_info[1] != AK09970_WIA2_VALUE)) { + pr_err("The device is not AKM Hall sensor\n"); + rc = -ENXIO; + } + +exit: + akm09970_power_down(c_ctrl); + + return rc; +} + +static ssize_t akm09970_chip_rev_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct akm09970_soc_ctrl *c_ctrl = dev_get_drvdata(dev); + + return sprintf(buf, "%x,%x\n", (char)c_ctrl->chip_info[0], + (char)c_ctrl->chip_info[1]); +} +static DEVICE_ATTR(chip_rev, S_IRUGO, akm09970_chip_rev_show, NULL); + +static struct device_attribute *akm_attrs[] = { + &dev_attr_chip_rev, +}; + +static int akm09970_regulator_init(struct akm09970_soc_ctrl *c_ctrl, bool on) +{ + int rc; + + if (on) { + c_ctrl->vdd = regulator_get(&c_ctrl->client->dev, "vdd"); + if (IS_ERR(c_ctrl->vdd)) { + rc = PTR_ERR(c_ctrl->vdd); + pr_err("Regulator get failed vdd rc=%d", rc); + return rc; + } + + if (regulator_count_voltages(c_ctrl->vdd) > 0) { + rc = regulator_set_voltage(c_ctrl->vdd, + AKM09970_VDD_MIN_UV, + AKM09970_VDD_MAX_UV); + if (rc) { + pr_err("Regulator set failed vdd rc=%d", rc); + regulator_put(c_ctrl->vdd); + return rc; + } + } + } else { + if (regulator_count_voltages(c_ctrl->vdd) > 0) + regulator_set_voltage(c_ctrl->vdd, 0, + AKM09970_VDD_MAX_UV); + + regulator_put(c_ctrl->vdd); + } + + return 0; +} + +static int akm09970_gpio_config(struct akm09970_soc_ctrl *c_ctrl) +{ + int32_t rc = 0; + + rc = gpio_request_one(c_ctrl->gpio_reset, GPIOF_OUT_INIT_LOW, + "akm09970-reset"); + if (rc < 0) { + pr_err("Failed to request power enable GPIO %d", + c_ctrl->gpio_reset); + goto reset_gpio_req_err; + } + gpio_direction_output(c_ctrl->gpio_reset, 0); + + rc = gpio_request_one(c_ctrl->gpio_irq, GPIOF_IN, "akm09970-irq"); + if (rc < 0) { + pr_err("Failed to request power enable GPIO %d", + c_ctrl->gpio_irq); + goto irq_gpio_req_err; + } else { + gpio_direction_input(c_ctrl->gpio_irq); + c_ctrl->irq = gpio_to_irq(c_ctrl->gpio_irq); + rc = request_threaded_irq(c_ctrl->irq, akm09970_irq_handler, + NULL, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "akm09970_irq", c_ctrl); + if (rc < 0) { + pr_err("Unable to request irq\n"); + goto irq_req_err; + } + disable_irq_nosync(c_ctrl->irq); + } + + return 0; + +irq_req_err: + if (gpio_is_valid(c_ctrl->gpio_irq)) { + if (c_ctrl->irq) + free_irq(c_ctrl->irq, c_ctrl); + gpio_free(c_ctrl->gpio_irq); + } + +irq_gpio_req_err: + if (gpio_is_valid(c_ctrl->gpio_reset)) + gpio_free(c_ctrl->gpio_reset); + +reset_gpio_req_err: + return rc; +} + +static int akm09970_pinctrl_select(struct akm09970_soc_ctrl *c_ctrl, bool state) +{ + int rc = 0; + struct pinctrl_state *pins_state = state ? (c_ctrl->gpio_state_active) : + (c_ctrl->gpio_state_suspend); + + rc = pinctrl_select_state(c_ctrl->pinctrl, pins_state); + if (rc < 0) + pr_err("Failed to select pins state %s\n", + state ? "active" : "suspend"); + + return rc; +} + +static int akm09970_pinctrl_init(struct akm09970_soc_ctrl *c_ctrl) +{ + int rc = 0; + struct device *dev = c_ctrl->dev; + + c_ctrl->pinctrl = devm_pinctrl_get(dev); + if (IS_ERR_OR_NULL(c_ctrl->pinctrl)) { + rc = PTR_ERR(c_ctrl->pinctrl); + pr_err("Unable to acquire pinctrl %d", rc); + goto err_pinctrl_get; + } + + c_ctrl->gpio_state_active = + pinctrl_lookup_state(c_ctrl->pinctrl, "akm09970_gpio_active"); + if (IS_ERR_OR_NULL(c_ctrl->gpio_state_active)) { + pr_err("Cannot lookup active pinctrl state\n"); + rc = PTR_ERR(c_ctrl->gpio_state_active); + goto err_pinctrl_lookup; + } + + c_ctrl->gpio_state_suspend = + pinctrl_lookup_state(c_ctrl->pinctrl, "akm09970_gpio_suspend"); + if (IS_ERR_OR_NULL(c_ctrl->gpio_state_suspend)) { + pr_err("Cannot lookup suspend pinctrl state\n"); + rc = PTR_ERR(c_ctrl->gpio_state_suspend); + goto err_pinctrl_lookup; + } + + return 0; + +err_pinctrl_lookup: + devm_pinctrl_put(c_ctrl->pinctrl); +err_pinctrl_get: + c_ctrl->pinctrl = NULL; + + return rc; +} + +static int akm09970_parse_dt(struct device *dev, + struct akm09970_soc_ctrl *c_ctrl) +{ + int rc = 0; + + c_ctrl->gpio_reset = of_get_named_gpio_flags(dev->of_node, + "akm,gpio-reset", 0, NULL); + if (!gpio_is_valid(c_ctrl->gpio_reset)) { + pr_err("Gpio reset pin %d is invalid.", c_ctrl->gpio_reset); + return -EINVAL; + } + + c_ctrl->gpio_irq = + of_get_named_gpio_flags(dev->of_node, "akm,gpio-irq", 0, NULL); + if (!gpio_is_valid(c_ctrl->gpio_irq)) { + pr_err("gpio irq pin %d is invalid.", c_ctrl->gpio_irq); + return -EINVAL; + } + + return rc; +} + +static int akm09970_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int rc = 0; + struct akm09970_soc_ctrl *c_ctrl = NULL; + + pr_debug("Probe enter"); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + pr_err("check_functionality failed."); + return -ENODEV; + } + + /* Allocate memory for driver data */ + c_ctrl = devm_kzalloc(&client->dev, sizeof(struct akm09970_soc_ctrl), + GFP_KERNEL); + if (!c_ctrl) { + pr_err("Alloc memory failed."); + return -ENOMEM; + } + + pr_debug("Start parse device tree"); + if (client->dev.of_node) { + rc = akm09970_parse_dt(&client->dev, c_ctrl); + if (rc < 0) { + pr_err("Unable to parse platfrom data rc=%d\n", rc); + goto exit; + } + } + + c_ctrl->dev = &client->dev; + c_ctrl->client = client; + i2c_set_clientdata(client, c_ctrl); + + rc = akm09970_pinctrl_init(c_ctrl); + if (rc) { + pr_err("Failed to initialize pinctrl\n"); + goto exit; + } else { + if (c_ctrl->pinctrl) { + rc = akm09970_pinctrl_select(c_ctrl, true); + if (rc < 0) { + pr_err("Failed to select default pinstate %d\n", + rc); + goto err_select_pinctrl; + } + } + } + + rc = akm09970_gpio_config(c_ctrl); + if (rc < 0) { + pr_err("Failed to config gpio\n"); + goto err_select_pinctrl; + } + + rc = akm09970_regulator_init(c_ctrl, true); + if (rc < 0) + goto err_regulator_init; + + rc = akm09970_check_device_id(c_ctrl); + if (rc < 0) + goto err_check_device; + + atomic_set(&c_ctrl->power_enabled, 0); + + pr_err("IRQ is #%d.", c_ctrl->irq); + + hrtimer_init(&c_ctrl->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + c_ctrl->timer.function = hrtimer_handler; + c_ctrl->work_queue = + alloc_workqueue("akm09970_poll_work_queue", + WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_HIGHPRI, 1); + INIT_WORK(&c_ctrl->report_work, akm09970_dev_work_queue); + + c_ctrl->chr_class = class_create(THIS_MODULE, AKM09970_CLASS_NAME); + if (c_ctrl->chr_class == NULL) { + pr_err("Failed to create class.\n"); + rc = -ENODEV; + goto err_check_device; + } + + rc = alloc_chrdev_region(&c_ctrl->dev_num, 0, 1, AKM09970_DRV_NAME); + if (rc < 0) { + pr_err("Failed to allocate chrdev region\n"); + goto err_destroy_class; + } + + c_ctrl->chr_dev = device_create(c_ctrl->chr_class, NULL, + c_ctrl->dev_num, c_ctrl, + AKM09970_DRV_NAME); + if (IS_ERR(c_ctrl->chr_dev)) { + pr_err("Failed to create char device\n"); + rc = PTR_ERR(c_ctrl->chr_dev); + goto err_unregister_chrdev; + } + + cdev_init(&(c_ctrl->cdev), &akm09970_fops); + c_ctrl->cdev.owner = THIS_MODULE; + + rc = cdev_add(&(c_ctrl->cdev), c_ctrl->dev_num, 1); + if (rc < 0) { + pr_err("Failed to add cdev\n"); + goto err_destroy_device; + } + + rc = device_create_file(c_ctrl->chr_dev, akm_attrs[0]); + if (rc < 0) + pr_err("Failed to create debug file: %d\n", rc); + + pr_err("Probe exit"); + + return 0; + +err_destroy_device: + if (c_ctrl->chr_dev) + device_destroy(c_ctrl->chr_class, c_ctrl->dev_num); + +err_unregister_chrdev: + unregister_chrdev_region(c_ctrl->dev_num, 1); +err_destroy_class: + if (c_ctrl->chr_class) + class_destroy(c_ctrl->chr_class); + +err_check_device: + akm09970_regulator_init(c_ctrl, false); + +err_regulator_init: + if (gpio_is_valid(c_ctrl->gpio_irq)) { + if (c_ctrl->irq) + free_irq(c_ctrl->irq, c_ctrl); + gpio_free(c_ctrl->gpio_irq); + } + + if (gpio_is_valid(c_ctrl->gpio_reset)) + gpio_free(c_ctrl->gpio_reset); + +err_select_pinctrl: + if (c_ctrl->pinctrl) { + devm_pinctrl_put(c_ctrl->pinctrl); + c_ctrl->pinctrl = NULL; + } + +exit: + return rc; +} + +static int akm09970_remove(struct i2c_client *client) +{ + struct akm09970_soc_ctrl *c_ctrl = i2c_get_clientdata(client); + + cancel_work_sync(&c_ctrl->report_work); + destroy_workqueue(c_ctrl->work_queue); + + if (&(c_ctrl->cdev)) + cdev_del(&(c_ctrl->cdev)); + + if (c_ctrl->chr_dev) + device_destroy(c_ctrl->chr_class, c_ctrl->dev_num); + + unregister_chrdev_region(c_ctrl->dev_num, 1); + if (c_ctrl->chr_class) + class_destroy(c_ctrl->chr_class); + + akm09970_power_down(c_ctrl); + + akm09970_regulator_init(c_ctrl, false); + + if (gpio_is_valid(c_ctrl->gpio_irq)) { + if (c_ctrl->irq) + free_irq(c_ctrl->irq, c_ctrl); + gpio_free(c_ctrl->gpio_irq); + } + + if (gpio_is_valid(c_ctrl->gpio_reset)) + gpio_free(c_ctrl->gpio_reset); + + if (c_ctrl->pinctrl) { + devm_pinctrl_put(c_ctrl->pinctrl); + c_ctrl->pinctrl = NULL; + } + + pr_debug("Removed exit"); + + return 0; +} + +static const struct i2c_device_id akm09970_id[] = { + { AKM09970_DRV_NAME, 0 }, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, akm09970_id); + +static struct of_device_id akm09970_match_table[] = { + { + .compatible = "akm,akm09970", + }, + {}, +}; + +static struct i2c_driver akm09970_driver = { + .driver = { + .name = AKM09970_DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = akm09970_match_table, + }, + .probe = akm09970_probe, + .remove = akm09970_remove, + .id_table = akm09970_id, +}; + +module_i2c_driver(akm09970_driver); + +MODULE_AUTHOR("zhunengjin "); +MODULE_DESCRIPTION("AKM compass driver"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("2.0"); diff --git a/include/uapi/linux/akm09970.h b/include/uapi/linux/akm09970.h new file mode 100644 index 000000000000..c6f8cc4874d4 --- /dev/null +++ b/include/uapi/linux/akm09970.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * Copyright (c) 2018-2019, Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * 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. + */ + +#ifndef __AKM09970_H__ +#define __AKM09970_H__ + +#include +#include + +//#define pr_fmt(fmt) "akm09970: %s: %d " fmt, __func__, __LINE__ + +#define AKM09970_DRV_NAME "akm09970" +#define AKM09970_CLASS_NAME "akm" + +/* AKM09970 Driver Magic Number */ +#define AKM_IOC_MAGIC 'M' + +#define AKM_PRIVATE 109 + +/* Device specific constant values */ +#define AK09970_REG_WIA 0x00 +#define AK09970_REG_ST_XYZ 0x17 +#define AK09970_REG_CNTL1 0x20 +#define AK09970_REG_CNTL2 0x21 +#define AK09970_REG_RESET 0x30 + +#define AK09970_RESET_DATA 0x01 + +#define AK09970_WIA1_VALUE 0x48 +#define AK09970_WIA2_VALUE 0xC0 + +#define AK09970_MODE_POWERDOWN 0x00 +#define AK09970_MODE_CONTINUOUS_10HZ 0x08 /* 10Hz */ +#define AK09970_MODE_CONTINUOUS_20HZ 0x0A /* 20Hz */ +#define AK09970_MODE_CONTINUOUS_50HZ 0x0C /* 50Hz */ +#define AK09970_MODE_CONTINUOUS_100HZ 0x0E /* 100Hz */ + +#define AKM_SENSOR_INFO_SIZE 2 +#define AKM_SENSOR_CONF_SIZE 3 +#define AKM_SENSOR_DATA_SIZE 8 + +#define AK09970_MODE_POS 0 +#define AK09970_MODE_MSK 0x0F +#define AK09970_MODE_REG AK09970_REG_CNTL2 + +#define AK09970_SDR_MODE_POS 4 +#define AK09970_SDR_MODE_MSK 0x10 +#define AK09970_SDR_MODE_REG AK09970_REG_CNTL2 + +#define AK09970_SMR_MODE_POS 5 +#define AK09970_SMR_MODE_MSK 0x20 +#define AK09970_SMR_MODE_REG AK09970_REG_CNTL2 + +#define AKM_DRDY_IS_HIGH(x) ((x) & 0x01) +#define AKM_DOR_IS_HIGH(x) ((x) & 0x02) +#define AKM_ERRADC_IS_HIGH(x) ((x) & 0x01) +#define AKM_ERRXY_IS_HIGH(x) ((x) & 0x80) + +#define AK09970_SENS_Q16 ((int32_t)(72090)) /* 1.1uT in Q16 format */ + +#define AKM_DRDY_TIMEOUT_MS 100 +#define AKM_DEFAULT_MEASURE_HZ 10 + +/* POWER SUPPLY VOLTAGE RANGE */ +#define AKM09970_VDD_MIN_UV 1800000 +#define AKM09970_VDD_MAX_UV 1800000 + +#define PWM_PERIOD_DEFAULT_NS 1000000 + +struct akm09970_platform_data { + uint8_t sensor_smr; + uint8_t sensor_mode; + uint8_t sensor_state; + uint8_t data[AKM_SENSOR_DATA_SIZE]; +}; + +/* IOC CMD */ +#define AKM_IOC_SET_ACTIVE \ + _IOW(AKM_IOC_MAGIC, AKM_PRIVATE + 1, struct akm09970_platform_data) + +#define AKM_IOC_SET_MODE \ + _IOW(AKM_IOC_MAGIC, AKM_PRIVATE + 2, struct akm09970_platform_data) + +#define AKM_IOC_GET_SENSEDATA \ + _IOR(AKM_IOC_MAGIC, AKM_PRIVATE + 4, struct akm09970_platform_data) + +#define AKM_IOC_GET_SENSSMR \ + _IOR(AKM_IOC_MAGIC, AKM_PRIVATE + 5, struct akm09970_platform_data) + +#endif /* __AKM09970_H__ */ From 8944550297fcb8a5971f3b80199f10a6afe926f0 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 18:29:53 +0200 Subject: [PATCH 078/226] drivers: misc: Import DRV8846 driver * Run clang-format on source files Change-Id: I41c3c9ba9400cdfefe1c0d523a7cefcce86ee5f7 Signed-off-by: firebird11 --- drivers/misc/Kconfig | 8 + drivers/misc/Makefile | 1 + drivers/misc/drv8846.c | 741 ++++++++++++++++++++++++++++++++++++ include/uapi/misc/drv8846.h | 48 +++ 4 files changed, 798 insertions(+) create mode 100644 drivers/misc/drv8846.c create mode 100644 include/uapi/misc/drv8846.h diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index d840c5508e77..f3c1f626d72e 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -605,6 +605,14 @@ config AKM09970 To compile this driver as a module, choose M here: the module will be called akm09970. +config TI_DRV8846 + tristate "TI step motor driver IC" + depends on PWM + help + Say 'y' here to include support for the H-Bridge Stepper + Motor Driver. The MISC peripheral holds the pwm and the + driver provides an API to drive stepper motor. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b8d2536975d7..c7d61c0d1ac7 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -66,6 +66,7 @@ obj-$(CONFIG_UID_SYS_STATS) += uid_sys_stats.o obj-$(CONFIG_MEMORY_STATE_TIME) += memory_state_time.o obj-$(CONFIG_QPNP_MISC) += qpnp-misc.o obj-$(CONFIG_AKM09970) += akm09970.o +obj-$(CONFIG_TI_DRV8846) += drv8846.o obj-$(CONFIG_OKL4_USER_VIRQ) += okl4-virq.o obj-$(CONFIG_OKL4_RINGBUF) += okl4-ringbuf.o diff --git a/drivers/misc/drv8846.c b/drivers/misc/drv8846.c new file mode 100644 index 000000000000..6b46408f0c41 --- /dev/null +++ b/drivers/misc/drv8846.c @@ -0,0 +1,741 @@ +/* drivers/misc/drv8846.c - drv8846 step motor soc driver + * + * Copyright (c) 2014-2015, Linux Foundation. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#define DEBUG +#define pr_fmt(fmt) "drv8846: %s: %d " fmt, __func__, __LINE__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV8846_DEV_NAME "ti,drv8846" + +#define PWM_PERIOD_DEFAULT_NS 1000000 +#define RAMP_PERIOD_DEFAULT_NS 625000 +#define RAMP_DURATION_DEFAULT_MS 50 +#define HIGH_PERIOD_DEFAULT_NS 52083 +#define HIGH_DURATION_DEFAULT_MS 700 +#define DEFAULT_STEP_MODE 2 + +static DECLARE_WAIT_QUEUE_HEAD(poll_wait_queue); + +struct pwm_setting { + u64 pre_period_ns; + u64 period_ns; + u64 duty_ns; +}; + +struct drv8846_soc_ctrl { + struct platform_device *pdev; + struct miscdevice miscdev; + struct dentry *debugfs; + struct device_node *of_node; + struct pinctrl *pinctrl; + struct pinctrl_state *pinctrl_default; + + struct pwm_device *pwm_dev; + struct pwm_setting pwm_setting; + struct hrtimer pwm_timer; + struct work_struct pwm_apply_work; + + atomic_t move_done; + + struct mutex motor_mutex; + struct fasync_struct *async; + + uint32_t rampup_period_ns; + uint32_t high_period_ns; + uint32_t rampdown_period_ns; + uint32_t high_duration_ms; + uint32_t rampup_duration_ms; + uint32_t rampdown_duration_ms; + uint32_t step_mode; + uint32_t direction; + + int gpio_mode0; + int gpio_mode1; + int gpio_dir; + int gpio_sleep; + int gpio_pwren; + + enum running_state state; +}; + +static int __drv8846_config_pwm(struct drv8846_soc_ctrl *mctrl, + struct pwm_setting *pwm) +{ + int rc; + struct pwm_state pstate; + + pwm_get_state(mctrl->pwm_dev, &pstate); + pstate.enabled = !!(pwm->duty_ns != 0); + pstate.period = pwm->period_ns; + pstate.duty_cycle = pwm->duty_ns; + pstate.output_type = PWM_OUTPUT_FIXED; + pstate.output_pattern = NULL; + pr_debug("enable %d\n", pstate.enabled); + rc = pwm_apply_state(mctrl->pwm_dev, &pstate); + if (rc < 0) + pr_err("Apply PWM state failed, rc=%d\n", rc); + + if (pstate.enabled == false) { + gpio_direction_output(mctrl->gpio_sleep, 0); + kill_fasync(&mctrl->async, SIGIO, POLL_IN); + atomic_set(&mctrl->move_done, 1); + wake_up(&poll_wait_queue); + } else { + gpio_direction_output(mctrl->gpio_sleep, 1); + } + return rc; +} + +static void pwm_config_work(struct work_struct *work) +{ + struct drv8846_soc_ctrl *mctrl = + container_of(work, struct drv8846_soc_ctrl, pwm_apply_work); + struct pwm_setting setting; + + setting = mctrl->pwm_setting; + + __drv8846_config_pwm(mctrl, &setting); +} + +static enum hrtimer_restart pwm_hrtimer_handler(struct hrtimer *timer) +{ + uint32_t duration_ms = 0; + struct drv8846_soc_ctrl *mctrl = + container_of(timer, struct drv8846_soc_ctrl, pwm_timer); + + switch (mctrl->state) { + case SPEEDUP: + mctrl->state = FULLSTEAM; + duration_ms = mctrl->high_duration_ms; + /* reconfig the pwm and timer to fast running mode. */ + mctrl->pwm_setting.period_ns = mctrl->high_period_ns; + mctrl->pwm_setting.pre_period_ns = mctrl->high_period_ns; + mctrl->pwm_setting.duty_ns = mctrl->high_period_ns >> 1; + if (mctrl->direction == DOWN) + duration_ms += DELTAMS; + hrtimer_forward_now(&mctrl->pwm_timer, + ktime_set(duration_ms / MSEC_PER_SEC, + (duration_ms % MSEC_PER_SEC) * + NSEC_PER_MSEC)); + break; + case FULLSTEAM: + mctrl->state = SLOWDOWN; + duration_ms = mctrl->rampdown_duration_ms; + /* reconfig the pwm and timer to slow mode(brake down) */ + mctrl->pwm_setting.period_ns = mctrl->rampdown_period_ns; + mctrl->pwm_setting.pre_period_ns = mctrl->rampdown_period_ns; + mctrl->pwm_setting.duty_ns = mctrl->rampdown_period_ns >> 1; + hrtimer_forward_now(&mctrl->pwm_timer, + ktime_set(duration_ms / MSEC_PER_SEC, + (duration_ms % MSEC_PER_SEC) * + NSEC_PER_MSEC)); + break; + case SLOWDOWN: + case UNIFORMSPEED: + mctrl->state = STILL; + /* should stop timer and pwm. */ + mctrl->pwm_setting.duty_ns = 0; + break; + default: + mctrl->pwm_setting.duty_ns = 0; + pr_info("default state."); + } + schedule_work(&mctrl->pwm_apply_work); + + if (mctrl->state == STILL) + return HRTIMER_NORESTART; + else + return HRTIMER_RESTART; +} + +void drv8846_move(struct drv8846_soc_ctrl *mctrl, uint8_t dir) +{ + pr_debug("move %s\n", dir ? "up" : "down"); + + hrtimer_start(&mctrl->pwm_timer, + ktime_set(mctrl->rampup_duration_ms / MSEC_PER_SEC, + (mctrl->rampup_duration_ms % MSEC_PER_SEC) * + NSEC_PER_MSEC), + HRTIMER_MODE_REL); + mctrl->state = SPEEDUP; + mctrl->direction = dir; + + gpio_direction_output(mctrl->gpio_dir, (dir == UP) ? 0 : 1); + gpio_direction_output(mctrl->gpio_sleep, 1); + + mctrl->pwm_setting.period_ns = mctrl->rampup_period_ns; + mctrl->pwm_setting.pre_period_ns = mctrl->rampup_period_ns; + mctrl->pwm_setting.duty_ns = mctrl->rampup_period_ns >> 1; + schedule_work(&mctrl->pwm_apply_work); +} + +static int drv8846_fasync(int fd, struct file *filp, int mode) +{ + struct drv8846_soc_ctrl *mctrl = filp->private_data; + + pr_debug("mctrl %p, application fasync!", mctrl); + return fasync_helper(fd, filp, mode, &mctrl->async); +} + +static unsigned int drv8846_poll(struct file *filp, poll_table *wait) +{ + unsigned int mask = 0; + struct drv8846_soc_ctrl *mctrl = filp->private_data; + + pr_debug("Poll enter\n"); + + poll_wait(filp, &poll_wait_queue, wait); + if (atomic_read(&mctrl->move_done)) { + atomic_set(&mctrl->move_done, 0); + mask = POLLIN | POLLRDNORM; + } + + return mask; +} + +static long drv8846_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + int rc = 0; + uint8_t direction = 0; + ktime_t time_rem; + long time_ms = 0; + struct op_parameter parameters; + struct drv8846_soc_ctrl *mctrl = filp->private_data; + + pr_debug("enter, mctrl %p", mctrl); + + if (mctrl == NULL) + return -EFAULT; + + switch (cmd) { + case MOTOR_IOC_SET_AUTORUN: + pr_debug("MOTOR_IOCAUTORUN."); + if (copy_from_user(&direction, (uint8_t *)arg, + sizeof(uint8_t))) { + pr_err("Failed to copy direction from user to kernel\n"); + rc = -EFAULT; + break; + } + drv8846_move(mctrl, direction); + break; + case MOTOR_IOC_SET_MANUALRUN: + pr_debug("MOTOR_IOCMANUAL\n"); + if (copy_from_user(¶meters, (struct op_parameter *)arg, + sizeof(struct op_parameter))) { + pr_err("Failed to copy target position from user to kernel\n"); + rc = -EFAULT; + break; + } + pr_debug("dir %d, duration %dms, period %dns.", parameters.dir, + parameters.duration_ms, parameters.period_ns); + + /* configure pwm */ + gpio_direction_output(mctrl->gpio_dir, + (parameters.dir == UP) ? 0 : 1); + gpio_direction_output(mctrl->gpio_sleep, 1); + + mctrl->pwm_setting.period_ns = parameters.period_ns; + mctrl->pwm_setting.pre_period_ns = parameters.period_ns; + mctrl->pwm_setting.duty_ns = parameters.period_ns >> 1; + schedule_work(&mctrl->pwm_apply_work); + /* start hrtimer */ + hrtimer_start( + &mctrl->pwm_timer, + ktime_set(parameters.duration_ms / MSEC_PER_SEC, + (parameters.duration_ms % MSEC_PER_SEC) * + NSEC_PER_MSEC), + HRTIMER_MODE_REL); + mctrl->state = UNIFORMSPEED; + break; + case MOTOR_IOC_GET_REMAIN_TIME: + if (hrtimer_active(&mctrl->pwm_timer)) { + time_rem = hrtimer_get_remaining(&mctrl->pwm_timer); + time_ms = (long)ktime_to_ms(time_rem); + } + if (copy_to_user((void __user *)arg, &time_ms, sizeof(long))) { + pr_err("copy_to_user failed."); + return -EFAULT; + } + break; + case MOTOR_IOC_GET_STATE: + if (copy_to_user((void __user *)arg, &mctrl->state, + sizeof(enum running_state))) { + pr_err("copy_to_user failed."); + return -EFAULT; + } + break; + default: + pr_warn("unsupport cmd:0x%x\n", cmd); + break; + } + + return rc; +} + +#ifdef CONFIG_COMPAT +static long drv8846_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + return drv8846_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); +} +#endif + +static int drv8846_open(struct inode *inode, struct file *filp) +{ + struct drv8846_soc_ctrl *mctrl = NULL; + + pr_debug("enter\n"); + + mctrl = container_of(filp->private_data, struct drv8846_soc_ctrl, + miscdev); + filp->private_data = mctrl; + + atomic_set(&mctrl->move_done, 0); + + pr_debug("mctrl: %p\n", mctrl); + + return 0; +} + +static int drv8846_release(struct inode *inode, struct file *file) +{ + struct drv8846_soc_ctrl *mctrl = file->private_data; + + atomic_set(&mctrl->move_done, 0); + + pr_debug("mctrl %p.", mctrl); + + return 0; +} + +static const struct file_operations drv8846_fops = { + .owner = THIS_MODULE, + .open = drv8846_open, + .release = drv8846_release, + .unlocked_ioctl = drv8846_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = drv8846_compat_ioctl, +#endif + .fasync = drv8846_fasync, + .poll = drv8846_poll, +}; + +static int drv8846_pinctrl_init(struct drv8846_soc_ctrl *mctrl) +{ + int rc = 0; + /* Get pinctrl if target uses pinctrl */ + mctrl->pinctrl = devm_pinctrl_get(&mctrl->pdev->dev); + + if (IS_ERR_OR_NULL(mctrl->pinctrl)) { + rc = PTR_ERR(mctrl->pinctrl); + pr_err("Target does not use pinctrl %d\n", rc); + goto err_pinctrl_get; + } + + mctrl->pinctrl_default = + pinctrl_lookup_state(mctrl->pinctrl, "default"); + + if (IS_ERR_OR_NULL(mctrl->pinctrl_default)) { + rc = PTR_ERR(mctrl->pinctrl_default); + pr_err("Can not lookup default pinstate %d\n", rc); + goto err_pinctrl_lookup; + } + + return 0; + +err_pinctrl_lookup: + devm_pinctrl_put(mctrl->pinctrl); +err_pinctrl_get: + mctrl->pinctrl = NULL; + + return rc; +} + +static int drv8846_gpio_config(struct drv8846_soc_ctrl *mctrl) +{ + int32_t rc = 0; + + rc = gpio_request_one(mctrl->gpio_mode0, GPIOF_OUT_INIT_HIGH, + "motor-mode0"); + if (rc < 0) { + pr_err("Failed to request mode0 GPIO %d", mctrl->gpio_mode0); + goto fail0; + } + gpio_direction_output(mctrl->gpio_mode0, (mctrl->step_mode & 0x01)); + + rc = gpio_request_one(mctrl->gpio_mode1, GPIOF_OUT_INIT_HIGH, + "motor-mode1"); + if (rc < 0) { + pr_err("Failed to request mode1 GPIO %d", mctrl->gpio_mode1); + goto fail1; + } + gpio_direction_output(mctrl->gpio_mode1, (mctrl->step_mode & 0x02)); + + rc = gpio_request_one(mctrl->gpio_dir, GPIOF_OUT_INIT_HIGH, + "motor-dir"); + if (rc < 0) { + pr_err("Failed to request dir GPIO %d\n", mctrl->gpio_dir); + goto fail2; + } + gpio_direction_output(mctrl->gpio_dir, 0); + + rc = gpio_request_one(mctrl->gpio_sleep, GPIOF_OUT_INIT_HIGH, + "motor-sleep"); + if (rc < 0) { + pr_err("Failed to request sleep GPIO %d", mctrl->gpio_sleep); + goto fail3; + } + gpio_direction_output(mctrl->gpio_sleep, 0); + + rc = gpio_request_one(mctrl->gpio_pwren, GPIOF_OUT_INIT_HIGH, + "motor-pwr"); + if (rc < 0) { + pr_err("Failed to request power enable GPIO %d", + mctrl->gpio_pwren); + goto fail4; + } + gpio_direction_output(mctrl->gpio_pwren, 1); + + return 0; + +fail4: + if (gpio_is_valid(mctrl->gpio_sleep)) + gpio_free(mctrl->gpio_sleep); +fail3: + if (gpio_is_valid(mctrl->gpio_dir)) + gpio_free(mctrl->gpio_dir); +fail2: + if (gpio_is_valid(mctrl->gpio_mode1)) + gpio_free(mctrl->gpio_mode1); +fail1: + if (gpio_is_valid(mctrl->gpio_mode0)) + gpio_free(mctrl->gpio_mode0); +fail0: + return rc; +} + +int drv8846_parse_dt(struct drv8846_soc_ctrl *mctrl) +{ + int rc = 0; + struct device_node *of_node = NULL; + + of_node = mctrl->pdev->dev.of_node; + + mctrl->pwm_dev = devm_of_pwm_get(&mctrl->pdev->dev, of_node, NULL); + if (IS_ERR(mctrl->pwm_dev)) { + rc = PTR_ERR(mctrl->pwm_dev); + if (rc != -EPROBE_DEFER) + pr_err("Get pwm device for motor failed, rc=%d\n", rc); + return rc; + } + + mctrl->pwm_setting.duty_ns = 0; + mctrl->pwm_setting.period_ns = PWM_PERIOD_DEFAULT_NS; + + mctrl->gpio_mode0 = + of_get_named_gpio_flags(of_node, "motor,gpio-mode0", 0, NULL); + if (!gpio_is_valid(mctrl->gpio_mode0)) { + pr_info("mctrl->motor_data.gpio_mode0 is invalid."); + return -EINVAL; + } + + mctrl->gpio_mode1 = + of_get_named_gpio_flags(of_node, "motor,gpio-mode1", 0, NULL); + if (!gpio_is_valid(mctrl->gpio_mode1)) { + pr_info("motor,mode1-gpio is invalid."); + return -EINVAL; + } + + mctrl->gpio_sleep = + of_get_named_gpio_flags(of_node, "motor,gpio-sleep", 0, NULL); + if (!gpio_is_valid(mctrl->gpio_sleep)) { + pr_info("motor,sleep-gpio is invalid."); + return -EINVAL; + } + + mctrl->gpio_dir = + of_get_named_gpio_flags(of_node, "motor,gpio-dir", 0, NULL); + if (!gpio_is_valid(mctrl->gpio_dir)) { + pr_info("motor,dir-gpio is invalid."); + return -EINVAL; + } + + mctrl->gpio_pwren = + of_get_named_gpio_flags(of_node, "motor,gpio-pwren", 0, NULL); + if (!gpio_is_valid(mctrl->gpio_pwren)) { + pr_info("power,en-gpio is invalid."); + return -EINVAL; + } + + rc = of_property_read_u32(of_node, "motor,rampup-pwm-period-ns", + &mctrl->rampup_period_ns); + if (rc < 0) { + pr_info("motor,rampup-pwm-period-ns not set, use default."); + mctrl->rampup_period_ns = RAMP_PERIOD_DEFAULT_NS; + } + + rc = of_property_read_u32(of_node, "motor,high-pwm-period-ns", + &mctrl->high_period_ns); + if (rc < 0) { + pr_info("motor,high-pwm-period-ns not set, use default."); + mctrl->high_period_ns = HIGH_PERIOD_DEFAULT_NS; + } + + rc = of_property_read_u32(of_node, "motor,rampdown-pwm-period-ns", + &mctrl->rampdown_period_ns); + if (rc < 0) { + pr_info("motor,rampdown-pwm-period-ns not set, use default."); + mctrl->rampdown_period_ns = RAMP_PERIOD_DEFAULT_NS; + } + + rc = of_property_read_u32(of_node, "motor,rampup-duration-ms", + &mctrl->rampup_duration_ms); + if (rc < 0) { + pr_info("motor,rampup-duration-ms not set, use default."); + mctrl->rampup_duration_ms = RAMP_DURATION_DEFAULT_MS; + } + + rc = of_property_read_u32(of_node, "motor,high-duration-ms", + &mctrl->high_duration_ms); + if (rc < 0) { + pr_info("motor,high-duration-ms not set, use default."); + mctrl->high_duration_ms = HIGH_DURATION_DEFAULT_MS; + } + + rc = of_property_read_u32(of_node, "motor,rampdown-duration-ms", + &mctrl->rampdown_duration_ms); + if (rc < 0) { + pr_info("motor,rampdown-duration-ms not set, use default."); + mctrl->rampdown_duration_ms = RAMP_DURATION_DEFAULT_MS; + } + + rc = of_property_read_u32(of_node, "motor,step-mode", + &mctrl->step_mode); + if (rc < 0) { + pr_info("motor,step-mode not set, use default."); + mctrl->step_mode = DEFAULT_STEP_MODE; + } + + return 0; +} + +static int step_mode_dbgfs_read(void *data, u64 *val) +{ + struct drv8846_soc_ctrl *mctrl = (struct drv8846_soc_ctrl *)data; + + *val = mctrl->step_mode; + + return 0; +} + +static int step_mode_dbgfs_write(void *data, u64 val) +{ + struct drv8846_soc_ctrl *mctrl = (struct drv8846_soc_ctrl *)data; + + mctrl->step_mode = val & 0x03; + gpio_direction_output(mctrl->gpio_mode0, (val & 0x01)); + gpio_direction_output(mctrl->gpio_mode1, (val & 0x02)); + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(step_mode_debugfs_ops, step_mode_dbgfs_read, + step_mode_dbgfs_write, "%llu\n"); + +static int drv8846_probe(struct platform_device *pdev) +{ + int32_t rc = 0; + struct drv8846_soc_ctrl *mctrl = NULL; + + pr_debug("Enter"); + if (!pdev->dev.of_node) { + pr_err("of_node NULL"); + return -EINVAL; + } + + mctrl = kzalloc(sizeof(struct drv8846_soc_ctrl), GFP_KERNEL); + if (!mctrl) + return -ENOMEM; + + pr_debug("mctrl: %p\n", mctrl); + mctrl->pdev = pdev; + platform_set_drvdata(pdev, mctrl); + + mutex_init(&mctrl->motor_mutex); + + rc = drv8846_parse_dt(mctrl); + if (rc < 0) { + pr_err("parse dt failed"); + goto fail; + } + + rc = drv8846_pinctrl_init(mctrl); + if (!rc && mctrl->pinctrl) { + rc = pinctrl_select_state(mctrl->pinctrl, + mctrl->pinctrl_default); + if (rc < 0) { + pr_err("Failed to select default pinstate %d\n", rc); + } + } else { + pr_err("Failed to init pinctrl\n"); + } + + rc = drv8846_gpio_config(mctrl); + if (rc < 0) { + pr_err("Failed to config gpio\n"); + goto fail; + } + + INIT_WORK(&mctrl->pwm_apply_work, pwm_config_work); + + hrtimer_init(&mctrl->pwm_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + mctrl->pwm_timer.function = pwm_hrtimer_handler; + + mctrl->miscdev.minor = MISC_DYNAMIC_MINOR; + mctrl->miscdev.name = DRV8846_MISC_NAME; + mctrl->miscdev.fops = &drv8846_fops; + mctrl->miscdev.parent = &pdev->dev; + + rc = misc_register(&mctrl->miscdev); + if (rc < 0) { + pr_err("register misc device fail"); + goto register_fail; + } + + mctrl->debugfs = debugfs_create_dir("pwm_motor", NULL); + if (mctrl->debugfs) { + debugfs_create_u32("rampup_period_ns", 0666, mctrl->debugfs, + &mctrl->rampup_period_ns); + debugfs_create_u32("high_period_ns", 0666, mctrl->debugfs, + &mctrl->high_period_ns); + debugfs_create_u32("rampdown_period_ns", 0666, mctrl->debugfs, + &mctrl->rampdown_period_ns); + debugfs_create_u32("rampup_duration_ms", 0666, mctrl->debugfs, + &mctrl->rampup_duration_ms); + debugfs_create_u32("high_duration_ms", 0666, mctrl->debugfs, + &mctrl->high_duration_ms); + debugfs_create_u32("rampdown_duration_ms", 0666, mctrl->debugfs, + &mctrl->rampdown_duration_ms); + debugfs_create_file("step_mode", 0666, mctrl->debugfs, mctrl, + &step_mode_debugfs_ops); + } + + pr_debug("successfully probed."); + return 0; + +register_fail: + cancel_work_sync(&mctrl->pwm_apply_work); + hrtimer_cancel(&mctrl->pwm_timer); +fail: + mutex_destroy(&mctrl->motor_mutex); + kfree(mctrl); + platform_set_drvdata(pdev, NULL); + return rc; +} + +static int drv8846_remove(struct platform_device *pdev) +{ + struct drv8846_soc_ctrl *mctrl = platform_get_drvdata(pdev); + + cancel_work_sync(&mctrl->pwm_apply_work); + hrtimer_cancel(&mctrl->pwm_timer); + mutex_destroy(&mctrl->motor_mutex); + misc_deregister(&mctrl->miscdev); + platform_set_drvdata(pdev, NULL); + kfree(mctrl); + + return 0; +} + +static int drv8846_suspend(struct device *dev) +{ + struct drv8846_soc_ctrl *mctrl = dev_get_drvdata(dev); + + return gpio_direction_output(mctrl->gpio_pwren, 0); +} + +static int drv8846_resume(struct device *dev) +{ + struct drv8846_soc_ctrl *mctrl = dev_get_drvdata(dev); + + return gpio_direction_output(mctrl->gpio_pwren, 1); +} + +static const struct dev_pm_ops drv8846_pm_ops = { + .suspend = drv8846_suspend, + .resume = drv8846_resume, +}; + +static const struct of_device_id drv8846_match_table[] = { + { .compatible = DRV8846_DEV_NAME }, + {} +}; + +static struct platform_driver drv8846_driver = { + .driver = { + .name = DRV8846_DEV_NAME, + .owner = THIS_MODULE, + .of_match_table = drv8846_match_table, + .pm = &drv8846_pm_ops, + }, + .probe = drv8846_probe, + .remove = drv8846_remove, +}; + +static int __init drv8846_init(void) +{ + return platform_driver_register(&drv8846_driver); +} + +static void __exit drv8846_exit(void) +{ + return platform_driver_unregister(&drv8846_driver); +} + +module_init(drv8846_init); +module_exit(drv8846_exit); + +MODULE_AUTHOR("ran fei "); +MODULE_DESCRIPTION("TI Dual H-Bridge Stepper Motor Driver"); +MODULE_LICENSE("GPL"); diff --git a/include/uapi/misc/drv8846.h b/include/uapi/misc/drv8846.h new file mode 100644 index 000000000000..ed764dfa8084 --- /dev/null +++ b/include/uapi/misc/drv8846.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * Copyright (c) 2014-2015, Linux Foundation. + * Copyright (C) 2021 XiaoMi, Inc. + * + * 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. + */ + +#ifndef _UAPI_MISC_DRV8846_H +#define _UAPI_MISC_DRV8846_H + +#include +#include + +#define DRV8846_MISC_NAME "drv8846_dev" + +#define UP 1 +#define DOWN 0 + +/* Move back add delta ms to guarantee go home success */ +#define DELTAMS 5 + +enum running_state { + STILL = 0, + SPEEDUP, + FULLSTEAM, + SLOWDOWN, + UNIFORMSPEED, +}; + +struct op_parameter { + uint32_t dir; + uint32_t duration_ms; + uint32_t period_ns; +}; + +/* ioctl numbers */ +#define MOTOR_MAGIC 0xD3 +/* AFU devices */ +#define MOTOR_IOC_SET_AUTORUN _IOW(MOTOR_MAGIC, 0x01, uint8_t) +#define MOTOR_IOC_SET_MANUALRUN _IOW(MOTOR_MAGIC, 0x02, struct op_parameter) +#define MOTOR_IOC_GET_REMAIN_TIME _IOR(MOTOR_MAGIC, 0x10, long) +#define MOTOR_IOC_GET_STATE _IOR(MOTOR_MAGIC, 0x11, enum running_state) + +#endif /* _UAPI_MISC_DRV8846_H */ From 80913ec3c4812b401ebe6a13d98865235fe6caa6 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 18:58:49 +0200 Subject: [PATCH 079/226] drivers: misc: Import Xiaomi SIM tray status driver * Run clang-format on source files Change-Id: Ie173550660a4dbaca7700c29d680fc7563fe2877 Signed-off-by: firebird11 --- drivers/misc/Kconfig | 6 +++ drivers/misc/Makefile | 1 + drivers/misc/simtray.c | 87 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 drivers/misc/simtray.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index f3c1f626d72e..d54829fc5b72 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -613,6 +613,12 @@ config TI_DRV8846 Motor Driver. The MISC peripheral holds the pwm and the driver provides an API to drive stepper motor. +config SIMTRAY_STATUS + tristate "Xiaomi SIM tray status" + default n + help + Say 'y' here to support SIM tray GPIO detection + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index c7d61c0d1ac7..ab94fd1adb17 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_MEMORY_STATE_TIME) += memory_state_time.o obj-$(CONFIG_QPNP_MISC) += qpnp-misc.o obj-$(CONFIG_AKM09970) += akm09970.o obj-$(CONFIG_TI_DRV8846) += drv8846.o +obj-$(CONFIG_SIMTRAY_STATUS) += simtray.o obj-$(CONFIG_OKL4_USER_VIRQ) += okl4-virq.o obj-$(CONFIG_OKL4_RINGBUF) += okl4-ringbuf.o diff --git a/drivers/misc/simtray.c b/drivers/misc/simtray.c new file mode 100644 index 000000000000..dc941ab6921d --- /dev/null +++ b/drivers/misc/simtray.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct simtray_data { + struct device *dev; + int status_gpio; +}; + +static ssize_t simtray_status_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct simtray_data *data = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", + gpio_get_value(data->status_gpio)); +} +static DEVICE_ATTR(status, 0444, simtray_status_show, NULL); + +static int simtray_probe(struct platform_device *pdev) +{ + int ret = 0; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct simtray_data *data; + + pr_info("%s enter\n", __func__); + + data = devm_kzalloc(dev, sizeof(struct simtray_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->status_gpio = of_get_named_gpio(np, "status-gpio", 0); + if (data->status_gpio < 0) + return -EINVAL; + + ret = sysfs_create_file(&dev->kobj, &dev_attr_status.attr); + if (ret < 0) { + dev_err(dev, "Failed to create sysfs node.\n"); + return -EINVAL; + } + + data->dev = dev; + platform_set_drvdata(pdev, data); + + return ret; +} + +static int simtray_remove(struct platform_device *pdev) +{ + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_status.attr); + return 0; +} + +static const struct of_device_id simtray_of_match[] = { + { + .compatible = "xiaomi,simtray-status", + }, + {}, +}; + +static struct platform_driver simtray_status_driver = { + .driver = { + .name = "simtray-status", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(simtray_of_match), + }, + .probe = simtray_probe, + .remove = simtray_remove, +}; + +module_platform_driver(simtray_status_driver); +MODULE_AUTHOR("Tao Jun"); +MODULE_DESCRIPTION("Xiaomi SIM tray status"); +MODULE_LICENSE("GPL"); From 494fbada3d079015821fa8cd91cc1f327ad305bf Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:00:39 +0200 Subject: [PATCH 080/226] drivers: nfc: Import Xiaomi changes Change-Id: I09de882a627ebec1821f4cfc21312f956a8da653 Signed-off-by: firebird11 --- drivers/nfc/nq-nci.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 5f8cc5f061aa..c6c8b7c0adaf 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -153,6 +153,7 @@ static irqreturn_t nqx_dev_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +#ifndef CONFIG_MACH_XIAOMI_SM8150 static int is_data_available_for_read(struct nqx_dev *nqx_dev) { int ret; @@ -162,6 +163,7 @@ static int is_data_available_for_read(struct nqx_dev *nqx_dev) !nqx_dev->irq_enabled, msecs_to_jiffies(MAX_IRQ_WAIT_TIME)); return ret; } +#endif static ssize_t nfc_read(struct file *filp, char __user *buf, size_t count, loff_t *offset) @@ -348,9 +350,13 @@ static int sn100_ese_pwr(struct nqx_dev *nqx_dev, unsigned long int arg) * VEN state will remain HIGH if NFC is enabled otherwise * it will be set as LOW */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (!gpio_get_value(nqx_dev->en_gpio)) { +#else nqx_dev->nfc_ven_enabled = gpio_get_value(nqx_dev->en_gpio); if (!nqx_dev->nfc_ven_enabled) { +#endif dev_dbg(&nqx_dev->client->dev, "eSE HAL service setting en_gpio HIGH\n"); gpio_set_value(nqx_dev->en_gpio, 1); /* hardware dependent delay */ @@ -792,6 +798,7 @@ static const struct file_operations nfc_dev_fops = { #endif }; +#ifndef CONFIG_MACH_XIAOMI_SM8150 /* * function: get_nfcc_hw_info() * @@ -1112,6 +1119,7 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev) return ret; } +#endif /* * Routine to enable clock. @@ -1430,8 +1438,13 @@ static int nqx_probe(struct i2c_client *client, /* NFC_INT IRQ */ nqx_dev->irq_enabled = true; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + r = request_irq(client->irq, nqx_dev_irq_handler, + IRQF_TRIGGER_RISING, client->name, nqx_dev); +#else r = request_irq(client->irq, nqx_dev_irq_handler, IRQF_TRIGGER_HIGH, client->name, nqx_dev); +#endif if (r) { dev_err(&client->dev, "%s: request_irq failed\n", __func__); goto err_request_irq_failed; @@ -1443,6 +1456,7 @@ static int nqx_probe(struct i2c_client *client, * present before attempting further hardware initialisation. * */ +#ifndef CONFIG_MACH_XIAOMI_SM8150 r = nfcc_hw_check(client, nqx_dev); if (r) { /* make sure NFCC is not enabled */ @@ -1450,6 +1464,7 @@ static int nqx_probe(struct i2c_client *client, /* We don't think there is hardware switch NFC OFF */ goto err_request_hw_check_failed; } +#endif /* Register reboot notifier here */ r = register_reboot_notifier(&nfcc_notifier); @@ -1465,12 +1480,23 @@ static int nqx_probe(struct i2c_client *client, } #ifdef NFC_KERNEL_BU +#ifndef CONFIG_MACH_XIAOMI_SM8150 r = nqx_clock_select(nqx_dev); if (r < 0) { dev_err(&client->dev, "%s: nqx_clock_select failed\n", __func__); goto err_clock_en_failed; } +#else + if (nqx_dev->pdata->clk_pin_voting) { + r = nqx_clock_select(nqx_dev); + if (r < 0) { + dev_err(&client->dev, + "%s: nqx_clock_select failed\n", __func__); + goto err_clock_en_failed; + } + } +#endif gpio_set_value(platform_data->en_gpio, 1); #endif device_init_wakeup(&client->dev, true); From 5a6c2852f2990ca9babd6bca275a5b798db07539 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:01:55 +0200 Subject: [PATCH 081/226] drivers: of: Import Xiaomi changes Change-Id: I816c5168b4e419ca32a0b8a0d22f6738676eb86f Signed-off-by: firebird11 --- drivers/of/of_batterydata.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/of/of_batterydata.c b/drivers/of/of_batterydata.c index b275a8c0aad0..0aff4632beb9 100644 --- a/drivers/of/of_batterydata.c +++ b/drivers/of/of_batterydata.c @@ -321,6 +321,9 @@ struct device_node *of_batterydata_get_best_profile( { struct batt_ids batt_ids; struct device_node *node, *best_node = NULL; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct device_node *generic_node = NULL; +#endif const char *battery_type = NULL; int delta = 0, best_delta = 0, best_id_kohm = 0, id_range_pct, i = 0, rc = 0, limit = 0; @@ -374,9 +377,19 @@ struct device_node *of_batterydata_get_best_profile( } } } + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = of_property_read_string(node, "qcom,battery-type", + &battery_type); + if (!rc && strcmp(battery_type, "itech_3000mah") == 0) + generic_node = node; +#endif } if (best_node == NULL) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + best_node = generic_node; +#endif pr_err("No battery data found\n"); return best_node; } From 46028cccd72f45683659cb77273e4a3d9fc6fee3 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:06:57 +0200 Subject: [PATCH 082/226] drivers: pinctrl: qcom: Import Xiaomi changes Change-Id: I8dbbab6cf0a7c55e7fc4d26a51e2a64c3ddcee81 Signed-off-by: firebird11 --- drivers/pinctrl/qcom/pinctrl-msm.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 6c63b2ff3fae..9f90b60e5877 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -40,6 +40,9 @@ #include "../pinconf.h" #include "pinctrl-msm.h" #include "../pinctrl-utils.h" +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#include +#endif #include #ifdef CONFIG_HIBERNATION #include @@ -382,6 +385,12 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev, u32 val; int i; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* gpio 0~3 is NFC spi, gpio 126~129 is FP spi */ + if (group < 4 || (group > 125 && group < 130)) + return 0; +#endif + g = &pctrl->soc->groups[group]; base = reassign_pctrl_reg(pctrl->soc, group); @@ -623,6 +632,19 @@ static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) unsigned i; for (i = 0; i < chip->ngpio; i++, gpio++) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* gpio 0~3 is NFC spi, gpio 126~129 is FP spi */ + if (i < 4 || (i > 125 && i < 130)) + continue; + + /*only for E5G*/ + if (HARDWARE_PLATFORM_ANDROMEDA == get_hw_version_platform()){ + /*skip 5G related gpio: 5G IPC HS-UART, 5G RF HS-UART*/ + if ((i >= 4 && i <= 7) || (i >= 83 && i <= 86)) + continue; + } +#endif + msm_gpio_dbg_show_one(s, NULL, chip, i, gpio); seq_puts(s, "\n"); } From eed2c3c6cea72e5731bc86bf6fc18827fda9f6b5 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 5 Jul 2021 22:47:50 +0200 Subject: [PATCH 083/226] drivers: power: supply: Import Xiaomi drivers * From nabu-r-oss * idtp9220 driver from cepheus-q-oss * rx1619 driver from cmi-r-oss * Run clang-format on source files Change-Id: I615c5b86bb9a4143304a436667a6e0d523c60494 Signed-off-by: firebird11 --- drivers/power/supply/Kconfig | 8 + drivers/power/supply/Makefile | 8 + drivers/power/supply/halo/Kconfig | 14 + drivers/power/supply/halo/Makefile | 1 + drivers/power/supply/halo/halo_7221_cp.c | 737 ++ drivers/power/supply/lionsemi/Kconfig | 14 + drivers/power/supply/lionsemi/Makefile | 1 + drivers/power/supply/lionsemi/ln8282.c | 1088 +++ drivers/power/supply/maxim/Kconfig | 27 + drivers/power/supply/maxim/Makefile | 4 + drivers/power/supply/maxim/ds28e16.c | 1904 ++++++ drivers/power/supply/maxim/ds28e16.h | 133 + drivers/power/supply/maxim/ds28e16_common.h | 84 + drivers/power/supply/maxim/ds28e16_master.c | 1915 ++++++ drivers/power/supply/maxim/ds28e16_master.h | 55 + drivers/power/supply/maxim/ds28e16_slave.c | 1959 ++++++ drivers/power/supply/maxim/ds28e16_slave.h | 58 + drivers/power/supply/maxim/onewire_gpio.c | 613 ++ drivers/power/supply/maxim/onewire_gpio.h | 10 + .../power/supply/maxim/onewire_gpio_master.c | 604 ++ .../power/supply/maxim/onewire_gpio_master.h | 10 + .../power/supply/maxim/onewire_gpio_slave.c | 611 ++ .../power/supply/maxim/onewire_gpio_slave.h | 10 + drivers/power/supply/maxim/sha384_software.c | 109 + drivers/power/supply/maxim/sha384_software.h | 30 + drivers/power/supply/maxim/ucl_hash.h | 53 + drivers/power/supply/maxim/ucl_retdefs.h | 237 + drivers/power/supply/maxim/ucl_sha3.c | 429 ++ drivers/power/supply/maxim/ucl_sha3.h | 269 + drivers/power/supply/nuvolta/Kconfig | 30 + drivers/power/supply/nuvolta/Makefile | 3 + drivers/power/supply/nuvolta/rx1618.c | 1635 +++++ drivers/power/supply/nuvolta/rx1618.h | 1263 ++++ drivers/power/supply/nuvolta/rx1619.c | 4695 +++++++++++++ drivers/power/supply/nuvolta/rx1619.h | 2741 ++++++++ drivers/power/supply/nuvolta/rx1619_trim.c | 170 + drivers/power/supply/renesas/Kconfig | 25 + drivers/power/supply/renesas/Makefile | 2 + drivers/power/supply/renesas/idtp9220.c | 2223 ++++++ drivers/power/supply/renesas/idtp9220.h | 2263 +++++++ drivers/power/supply/renesas/idtp9418.c | 5971 +++++++++++++++++ drivers/power/supply/renesas/idtp9418.h | 507 ++ drivers/power/supply/renesas/idtp9418_fw.h | 3083 +++++++++ drivers/power/supply/ti/Kconfig | 24 + drivers/power/supply/ti/Makefile | 3 + drivers/power/supply/ti/bq25970_reg.h | 791 +++ drivers/power/supply/ti/bq2597x_charger.c | 2462 +++++++ drivers/power/supply/ti/bq27z561_fg.c | 2134 ++++++ drivers/power/supply/ti/cp_qc30.c | 1527 +++++ drivers/power/supply/ti/cp_qc30.h | 251 + drivers/power/supply/ti/ln8000_charger.c | 1826 +++++ drivers/power/supply/ti/ln8000_charger.h | 344 + drivers/power/supply/ti/pd_policy_manager.c | 1589 +++++ drivers/power/supply/ti/pd_policy_manager.h | 237 + include/linux/power/ln8282.h | 40 + 55 files changed, 46834 insertions(+) create mode 100644 drivers/power/supply/halo/Kconfig create mode 100644 drivers/power/supply/halo/Makefile create mode 100644 drivers/power/supply/halo/halo_7221_cp.c create mode 100644 drivers/power/supply/lionsemi/Kconfig create mode 100644 drivers/power/supply/lionsemi/Makefile create mode 100644 drivers/power/supply/lionsemi/ln8282.c create mode 100644 drivers/power/supply/maxim/Kconfig create mode 100644 drivers/power/supply/maxim/Makefile create mode 100644 drivers/power/supply/maxim/ds28e16.c create mode 100644 drivers/power/supply/maxim/ds28e16.h create mode 100644 drivers/power/supply/maxim/ds28e16_common.h create mode 100644 drivers/power/supply/maxim/ds28e16_master.c create mode 100644 drivers/power/supply/maxim/ds28e16_master.h create mode 100644 drivers/power/supply/maxim/ds28e16_slave.c create mode 100644 drivers/power/supply/maxim/ds28e16_slave.h create mode 100644 drivers/power/supply/maxim/onewire_gpio.c create mode 100644 drivers/power/supply/maxim/onewire_gpio.h create mode 100644 drivers/power/supply/maxim/onewire_gpio_master.c create mode 100644 drivers/power/supply/maxim/onewire_gpio_master.h create mode 100644 drivers/power/supply/maxim/onewire_gpio_slave.c create mode 100644 drivers/power/supply/maxim/onewire_gpio_slave.h create mode 100644 drivers/power/supply/maxim/sha384_software.c create mode 100644 drivers/power/supply/maxim/sha384_software.h create mode 100644 drivers/power/supply/maxim/ucl_hash.h create mode 100644 drivers/power/supply/maxim/ucl_retdefs.h create mode 100644 drivers/power/supply/maxim/ucl_sha3.c create mode 100644 drivers/power/supply/maxim/ucl_sha3.h create mode 100644 drivers/power/supply/nuvolta/Kconfig create mode 100644 drivers/power/supply/nuvolta/Makefile create mode 100644 drivers/power/supply/nuvolta/rx1618.c create mode 100644 drivers/power/supply/nuvolta/rx1618.h create mode 100644 drivers/power/supply/nuvolta/rx1619.c create mode 100644 drivers/power/supply/nuvolta/rx1619.h create mode 100644 drivers/power/supply/nuvolta/rx1619_trim.c create mode 100644 drivers/power/supply/renesas/Kconfig create mode 100644 drivers/power/supply/renesas/Makefile create mode 100644 drivers/power/supply/renesas/idtp9220.c create mode 100644 drivers/power/supply/renesas/idtp9220.h create mode 100644 drivers/power/supply/renesas/idtp9418.c create mode 100644 drivers/power/supply/renesas/idtp9418.h create mode 100644 drivers/power/supply/renesas/idtp9418_fw.h create mode 100644 drivers/power/supply/ti/Kconfig create mode 100644 drivers/power/supply/ti/Makefile create mode 100644 drivers/power/supply/ti/bq25970_reg.h create mode 100644 drivers/power/supply/ti/bq2597x_charger.c create mode 100644 drivers/power/supply/ti/bq27z561_fg.c create mode 100644 drivers/power/supply/ti/cp_qc30.c create mode 100644 drivers/power/supply/ti/cp_qc30.h create mode 100644 drivers/power/supply/ti/ln8000_charger.c create mode 100644 drivers/power/supply/ti/ln8000_charger.h create mode 100644 drivers/power/supply/ti/pd_policy_manager.c create mode 100644 drivers/power/supply/ti/pd_policy_manager.h create mode 100644 include/linux/power/ln8282.h diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index 7c217d5a673a..75105e6769c3 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -613,4 +613,12 @@ config CHARGER_RT9455 source "drivers/power/supply/qcom/Kconfig" +# Xiaomi +source "drivers/power/supply/halo/Kconfig" +source "drivers/power/supply/lionsemi/Kconfig" +source "drivers/power/supply/maxim/Kconfig" +source "drivers/power/supply/nuvolta/Kconfig" +source "drivers/power/supply/renesas/Kconfig" +source "drivers/power/supply/ti/Kconfig" + endif # POWER_SUPPLY diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index 4187af3ff90f..403137176c47 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -83,3 +83,11 @@ obj-$(CONFIG_CHARGER_TPS65217) += tps65217_charger.o obj-$(CONFIG_AXP288_FUEL_GAUGE) += axp288_fuel_gauge.o obj-$(CONFIG_AXP288_CHARGER) += axp288_charger.o obj-$(CONFIG_ARCH_QCOM) += qcom/ + +# xiaomi +obj-y += halo/ +obj-y += lionsemi/ +obj-y += maxim/ +obj-y += nuvolta/ +obj-y += renesas/ +obj-y += ti/ diff --git a/drivers/power/supply/halo/Kconfig b/drivers/power/supply/halo/Kconfig new file mode 100644 index 000000000000..d9bb3583a802 --- /dev/null +++ b/drivers/power/supply/halo/Kconfig @@ -0,0 +1,14 @@ +menu "HALO Electronics, Inc. Charger support" + +config HALO_7221 + tristate "HALO7221 Charge Pump" + depends on I2C + help + Say Y to include support for HALO 7221 charger pump. + HALO 7221 is a charger pump chip. + The driver supports charger enable/disable. + The driver reports the charger status via the power supply framework. + The driver controls 7221 via I2C and + supports device-tree interface. + +endmenu diff --git a/drivers/power/supply/halo/Makefile b/drivers/power/supply/halo/Makefile new file mode 100644 index 000000000000..11b23af0a422 --- /dev/null +++ b/drivers/power/supply/halo/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_HALO_7221) += halo_7221_cp.o diff --git a/drivers/power/supply/halo/halo_7221_cp.c b/drivers/power/supply/halo/halo_7221_cp.c new file mode 100644 index 000000000000..be7df83a213d --- /dev/null +++ b/drivers/power/supply/halo/halo_7221_cp.c @@ -0,0 +1,737 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEVICE_NAME "HALO7221_cp" + +struct halo7221_dev; + +struct halo7221_dt_props { + unsigned int enable_gpio; +}; + +struct halo7221_func { + int (*read)(struct halo7221_dev *di, u16 reg, u8 *val); + int (*write)(struct halo7221_dev *di, u16 reg, u8 val); + int (*read_buf)(struct halo7221_dev *di, u16 reg, u8 *buf, u32 size); + int (*write_buf)(struct halo7221_dev *di, u16 reg, u8 *buf, u32 size); + int (*write_masked)(struct halo7221_dev *di, u16 reg, u8 mask, u8 val); +}; + +struct halo7221_dev { + char *name; + struct i2c_client *client; + struct device *dev; + struct regmap *regmap; + struct halo7221_func bus; + struct halo7221_dt_props dt_props; + + struct pinctrl *halo_pinctrl; + struct pinctrl_state *halo_gpio_active; + struct pinctrl_state *halo_gpio_suspend; + struct power_supply *halo_psy; +}; + +/* +typedef union{ + u16 value; + u8 ptr[2]; +}vuc; +*/ + +extern char *saved_command_line; +static int get_board_version(void) +{ + char boot[5] = { '\0' }; + char *match = (char *)strnstr( + saved_command_line, + "androidboot.hwlevel=", strlen(saved_command_line)); + if (match) { + memcpy(boot, (match + strlen("androidboot.hwlevel=")), + sizeof(boot) - 1); + printk("%s: hwlevel is %s\n", __func__, boot); + if (!strncmp(boot, "P1.3", strlen("P1.3"))) + return 1; + } + return 0; +} + +int halo7221_read(struct halo7221_dev *chip, u16 reg, u8 *val) +{ + unsigned int temp; + int rc; + + rc = regmap_read(chip->regmap, reg, &temp); + if (rc >= 0) + *val = (u8)temp; + + return rc; +} + +int halo7221_write(struct halo7221_dev *chip, u16 reg, u8 val) +{ + int rc = 0; + + rc = regmap_write(chip->regmap, reg, val); + if (rc < 0) + dev_err(chip->dev, "%s: write error: %d\n", __func__, rc); + + return rc; +} + +int halo7221_read_buffer(struct halo7221_dev *chip, u16 reg, u8 *buf, u32 size) +{ + return regmap_bulk_read(chip->regmap, reg, buf, size); +} + +int halo7221_write_buffer(struct halo7221_dev *chip, u16 reg, u8 *buf, u32 size) +{ + int rc = 0; + + while (size--) { + rc = chip->bus.write(chip, reg++, *buf++); + if (rc < 0) { + dev_err(chip->dev, "write error: %d\n", rc); + return rc; + } + } + + return rc; +} + +int halo7221_write_masked(struct halo7221_dev *chip, u16 reg, u8 mask, u8 val) +{ + return regmap_update_bits(chip->regmap, reg, mask, val); +} +#define REG_NONE_ACCESS 0 +#define REG_RD_ACCESS (1 << 0) +#define REG_WR_ACCESS (1 << 1) +#define REG_BIT_ACCESS (1 << 2) + +#define REG_MAX 0x0F + +static int halo7221_set_enable(struct halo7221_dev *chip, int enable) +{ + int ret = 0; + + if (gpio_is_valid(chip->dt_props.enable_gpio)) { + ret = gpio_request(chip->dt_props.enable_gpio, + "halo-enable-gpio"); + if (ret) { + dev_err(chip->dev, + "%s: unable to request halo enable gpio [%d]\n", + __func__, chip->dt_props.enable_gpio); + } + ret = gpio_direction_output(chip->dt_props.enable_gpio, enable); + if (ret) { + dev_err(chip->dev, + "%s: cannot set direction for halo enable gpio [%d]\n", + __func__, chip->dt_props.enable_gpio); + } + gpio_free(chip->dt_props.enable_gpio); + } + return ret; +} + +static int halo7221_hw_init(struct halo7221_dev *chip) +{ + int rc = 0; + + rc = chip->bus.write(chip, 0x61, 0x80); + msleep(200); + rc = chip->bus.write(chip, 0x61, 0x00); + msleep(200); + rc = chip->bus.write_masked(chip, 0x03, GENMASK(1, 0), + 0x01); // set 11v to enable cp mode + msleep(50); + rc = chip->bus.write_masked(chip, 0x01, GENMASK(7, 3), + 0x1A); // Iin_Limit 1500mA + + return rc; +} + +/* chip enable attrs */ +static ssize_t chip_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct halo7221_dev *chip = i2c_get_clientdata(client); + + if (gpio_is_valid(chip->dt_props.enable_gpio)) + ret = gpio_get_value(chip->dt_props.enable_gpio); + else { + dev_err(chip->dev, "%s: enable gpio not provided\n", __func__); + ret = -1; + } + + dev_info(chip->dev, "chip enable gpio: %d\n", ret); + + return snprintf(buf, sizeof(buf), "Chip enable: %d\n", ret); +} + +static ssize_t chip_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + int ret, enable; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct halo7221_dev *chip = i2c_get_clientdata(client); + + ret = (int)simple_strtoul(buf, NULL, 10); + enable = !!ret; + + halo7221_set_enable(chip, enable); + + return count; +} + +static ssize_t chip_init_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret = 0; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct halo7221_dev *chip = i2c_get_clientdata(client); + + ret = halo7221_hw_init(chip); + if (ret < 0) { + dev_err(chip->dev, "%s: chip hw init error [%d]\n", __func__, + ret); + } + return snprintf(buf, sizeof(buf), "Chip init: %d\n", ret); +} + +/* +enum REG_INDEX +{ + CHIPID = 0, + VOUT, + INT_FLAG, + INTCTLR, + VOUTSET, + VFC, + CMD, + INDEX_MAX, +}; + +const u16 reg_access[INDEX_MAX][2] = { + [CHIPID] = {REG_CHIPID, REG_RD_ACCESS}, + [VOUT] = {REG_VOUT, REG_RD_ACCESS}, + [INT_FLAG] = {REG_INTFLAG,REG_RD_ACCESS}, + [INTCTLR] = {REG_INTCLR,REG_WR_ACCESS}, + [VOUTSET] = {REG_VOUTSET, REG_RD_ACCESS|REG_WR_ACCESS}, + [VFC] = {REG_VFC, REG_RD_ACCESS|REG_WR_ACCESS}, + [CMD] = {REG_CMD, REG_RD_ACCESS|REG_WR_ACCESS|REG_BIT_ACCESS}, +}; + + +static ssize_t get_reg(struct device* cd,struct device_attribute *attr, char* buf) +{ + u8 val[2]; + ssize_t len = 0; + int i = 0; + + for(i = 0; i< INDEX_MAX ;i++) { + if(reg_access[i][1] & REG_RD_ACCESS) { + halo7221_read_buffer(mte,reg_access[i][0],val,2); + len += snprintf(buf+len, PAGE_SIZE-len, "reg:0x%02x=0x%02x%02x\n", reg_access[i][0],val[0],val[1]); + } + } + + return len; +} + +static ssize_t set_reg(struct device* cd, struct device_attribute *attr, const char* buf, size_t len) +{ + unsigned int databuf[2]; + vuc val; + u8 tmp[2]; + u16 regdata; + int i = 0; + int ret = 0; + + ret = sscanf(buf,"%x %x",&databuf[0], &databuf[1]); + printk("%s : %d 0x%x 0x%x\n", __func__, ret, databuf[0],databuf[1]); + if(2 == ret) { + for(i = 0; i< INDEX_MAX ;i++) { + if(databuf[0] == reg_access[i][0]) { + if (reg_access[i][1] & REG_WR_ACCESS) { + val.ptr[1] = databuf[1]& 0x00ff; //big endian + val.ptr[0] = (databuf[1]& 0xff00) >> 8; + if (reg_access[i][1] & REG_BIT_ACCESS) { + halo7221_read_buffer(mte,databuf[0],tmp,2); + regdata = tmp[0]<<8|tmp[1]; + val.value |= regdata; + printk("get reg: 0x%04x set reg: 0x%04x \n", regdata,val.value); + halo7221_write_buffer(mte,databuf[0],val.ptr,2); + } + else { + printk("Set reg : [0x%04x] 0x%x 0x%x \n",databuf[1], val.ptr[0], val.ptr[1]); + halo7221_write_buffer(mte,databuf[0],val.ptr,2); + } + } + break; + } + } + } + return len; +} + +static ssize_t chip_version_show(struct device* dev, struct device_attribute* attr, char* buf) +{ + u8 fwver[2]; + ssize_t len = 0; // must to set 0 + pr_debug("chip_version_show\n"); + halo7221_read_buffer(mte,REG_FW_VER,fwver,2); + pr_debug("chip_version : 0x%02x,0x%02x\n",fwver[0],fwver[1]); + len += snprintf(buf+len, PAGE_SIZE-len, "chip_version : %02x,%02x\n", fwver[0],fwver[1]); + return len; +} +*/ + +/* voltage limit attrs */ +/* +static ssize_t chip_vout_show(struct device* dev, struct device_attribute* attr, char* buf) +{ + unsigned char fwver[2]; + unsigned short vout_value; + ssize_t len = 0; + pr_debug("chip_vout_show\n"); + // data_list = self.read(REG_VOUT, 2) + // val = data_list[1]|(data_list[0]<<8) + // self.insertPlainText('Vout: %0.3fV\n'%(val/1000.0)) + halo7221_read_buffer(mte,REG_VOUT,fwver,2); + vout_value = fwver[0] << 8 | fwver[1]; + pr_debug("chip Vout : %d\n",vout_value); + len += snprintf(buf+len, PAGE_SIZE-len, "chip Vout : %d mV\n",vout_value); + return len; +} + +static ssize_t chip_vout_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count) +{ + vuc val; + int error; + unsigned int temp; + u8 vptemp; + error = kstrtouint(buf, 10, &temp); + if (error) + return error; + if( (temp < 0) ||( temp > 20000)){ + pr_debug(" Parameter error\n"); + return count; + } + val.value = temp; + vptemp = val.ptr[0]; + val.ptr[0] = val.ptr[1]; + val.ptr[1] = vptemp; + halo7221_write_buffer(mte,REG_VOUTSET,val.ptr,2); + pr_debug("Set Vout : %d \n", val.value); + // mv=int(self.dsbVout.value()*1000) + // self.write(REG_VOUTSET, [(mv>>8)&0xff, mv&0xff]) + // self.insertPlainText('Set Vout: %0.3fV\n'%(mv/1000.0)) + + return count; +} + +static ssize_t fast_charging_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count) +{ + vuc val; + int error; + unsigned int temp; + u8 fcflag; + error = kstrtouint(buf, 10, &temp); + if (error) + return error; + if( (temp < 0) ||( temp > 20000)){ + pr_debug(" Parameter error\n"); + return count; + } + val.value = temp; + fcflag = val.ptr[0]; + val.ptr[0] = val.ptr[1]; + val.ptr[1] = fcflag; + halo7221_write_buffer(mte,REG_VFC,val.ptr,2); + pr_debug("FC send data : 0x%02x,0x%02x \n", val.ptr[0],val.ptr[1]); + val.value = FASTCHARGE; + halo7221_write_buffer(mte,REG_CMD,val.ptr,2); + return count; +} +static ssize_t fast_charging_show(struct device* dev, struct device_attribute* attr, char* buf) +{ + unsigned char fwver[2]; + unsigned short fc_value; + ssize_t len = 0; + pr_debug("fast_charging_show\n"); + // data_list = self.read(REG_VOUT, 2) + // val = data_list[1]|(data_list[0]<<8) + // self.insertPlainText('Vout: %0.3fV\n'%(val/1000.0)) + halo7221_read_buffer(mte,REG_VFC,fwver,2); + fc_value = fwver[0] << 8 | fwver[1]; + pr_debug("FC read data : %d\n",fc_value); + len += snprintf(buf+len, PAGE_SIZE-len, "FC read data : %d mV\n",fc_value); + return len; +} +*/ + +/* +static DEVICE_ATTR(chip_version, S_IRUGO | S_IWUSR, chip_version_show, NULL); +static DEVICE_ATTR(chip_vout, S_IRUGO | S_IWUSR, chip_vout_show, chip_vout_store); +static DEVICE_ATTR(fast_charging,S_IRUGO | S_IWUSR, fast_charging_show, fast_charging_store); +static DEVICE_ATTR(reg,S_IRUGO | S_IWUSR, get_reg, set_reg); +*/ +static DEVICE_ATTR(chip_enable, S_IWUSR | S_IRUGO, chip_enable_show, + chip_enable_store); +static DEVICE_ATTR(chip_init, S_IWUSR | S_IRUGO, chip_init_show, NULL); + +static struct attribute *halo7221_sysfs_attrs[] = { + /* + &dev_attr_chip_version.attr, + &dev_attr_chip_vout.attr, + &dev_attr_fast_charging.attr, + &dev_attr_reg.attr, +*/ + &dev_attr_chip_enable.attr, + &dev_attr_chip_init.attr, + NULL, +}; + +static const struct attribute_group halo7221_sysfs_group = { + .name = "halo7221group", + .attrs = halo7221_sysfs_attrs, +}; + +static const struct of_device_id match_table[] = { + { + .compatible = "halo7221,halo7221_cp", + }, + {}, +}; + +static const struct regmap_config halo7221_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0xFFFF, +}; + +static int halo7221_parse_dt(struct halo7221_dev *chip) +{ + struct device_node *node = chip->dev->of_node; + if (!node) { + dev_err(chip->dev, "device tree node missing\n"); + return -EINVAL; + } + + chip->dt_props.enable_gpio = of_get_named_gpio(node, "halo,enable", 0); + if ((!gpio_is_valid(chip->dt_props.enable_gpio))) + return -EINVAL; + + return 0; +} + +static int halo7221_gpio_init(struct halo7221_dev *chip) +{ + int ret = 0; + + chip->halo_pinctrl = devm_pinctrl_get(chip->dev); + if (IS_ERR_OR_NULL(chip->halo_pinctrl)) { + dev_err(chip->dev, "No pinctrl config specified\n"); + ret = PTR_ERR(chip->dev); + return ret; + } + chip->halo_gpio_active = + pinctrl_lookup_state(chip->halo_pinctrl, "halo7221_active"); + if (IS_ERR_OR_NULL(chip->halo_gpio_active)) { + dev_err(chip->dev, "No active config specified\n"); + ret = PTR_ERR(chip->halo_gpio_active); + return ret; + } + chip->halo_gpio_suspend = + pinctrl_lookup_state(chip->halo_pinctrl, "halo7221_suspend"); + if (IS_ERR_OR_NULL(chip->halo_gpio_suspend)) { + dev_err(chip->dev, "No suspend config specified\n"); + ret = PTR_ERR(chip->halo_gpio_suspend); + return ret; + } + + ret = pinctrl_select_state(chip->halo_pinctrl, chip->halo_gpio_active); + if (ret < 0) { + dev_err(chip->dev, "fail to select pinctrl active rc=%d\n", + ret); + return ret; + } + + return ret; +} + +static int halo_get_mode(struct halo7221_dev *chip) +{ + int rc, ret; + u8 val; + + rc = chip->bus.read(chip, 0x08, &val); + dev_info(chip->dev, "get status is: 0x%x\n", val); + if (rc < 0) + ret = -1; + else { + ret = val & BIT(5); + } + if (ret == 0) + ret = 2; // return switching mode + + dev_info(chip->dev, "get opmode is: %d\n", ret); + + return ret; +} + +#define FORWARD_BYPASS 1 +#define FORWARD_SWITCH 2 +#define REVERSE_SWITCH 3 +static int halo_set_mode(struct halo7221_dev *chip, int mode) +{ + int rc = 0; + switch (mode) { + case FORWARD_BYPASS: + rc = chip->bus.write(chip, 0x00, 0xff); + rc = chip->bus.write(chip, 0x07, 0x78); + rc = chip->bus.write(chip, 0xA7, 0xf9); + rc = chip->bus.write(chip, 0x0A, 0x10); + rc = chip->bus.write(chip, 0x02, 0xa8); //set ilim to 1500mA + rc = chip->bus.write(chip, 0x05, 0x61); + rc = chip->bus.write(chip, 0x03, 0x53); + break; + case FORWARD_SWITCH: + rc = chip->bus.write(chip, 0x00, 0xff); + rc = chip->bus.write(chip, 0x07, 0x78); + rc = chip->bus.write(chip, 0xA7, 0xf9); + rc = chip->bus.write(chip, 0x0A, 0x10); + rc = chip->bus.write(chip, 0x02, 0xa9); //set ilim to 1500mA + rc = chip->bus.write(chip, 0x05, 0x61); + rc = chip->bus.write(chip, 0x03, 0x53); + break; + case REVERSE_SWITCH: + rc = chip->bus.write(chip, 0x00, 0xff); + rc = chip->bus.write(chip, 0x07, 0x78); + rc = chip->bus.write(chip, 0xA7, 0xf9); + rc = chip->bus.write(chip, 0x0A, 0x10); + rc = chip->bus.write(chip, 0x0B, 0x01); + break; + default: + dev_err(chip->dev, "%s: invalid settings\n", __func__); + } + + return rc; +} + +static enum power_supply_property halo_props[] = { + POWER_SUPPLY_PROP_DIV_2_MODE, +}; + +static int halo_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct halo7221_dev *chip = power_supply_get_drvdata(psy); + + switch (psp) { + case POWER_SUPPLY_PROP_DIV_2_MODE: + val->intval = halo_get_mode(chip); + break; + default: + return -EINVAL; + } + return 0; +} + +static int halo_set_prop(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + struct halo7221_dev *chip = power_supply_get_drvdata(psy); + int rc = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_DIV_2_MODE: + rc = halo_set_mode(chip, val->intval); + break; + default: + return -EINVAL; + } + + return rc; +} + +static int halo_prop_is_writeable(struct power_supply *psy, + enum power_supply_property psp) +{ + int rc; + + switch (psp) { + case POWER_SUPPLY_PROP_DIV_2_MODE: + return 1; + default: + rc = 0; + break; + } + + return rc; +} + +static const struct power_supply_desc halo_psy_desc = { + .name = "halo", + .type = POWER_SUPPLY_TYPE_WIRELESS, + .properties = halo_props, + .num_properties = ARRAY_SIZE(halo_props), + .get_property = halo_get_prop, + .set_property = halo_set_prop, + .property_is_writeable = halo_prop_is_writeable, +}; + +static int halo7221_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct halo7221_dev *chip; + int rc = 0, ret = 0; + struct power_supply_config halo_cfg = {}; + //vuc chipid; + + dev_info(&client->dev, "halo7221 probe!\n"); + + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) { + dev_err(&client->dev, + "i2c allocated device info data failed!\n"); + return -ENOMEM; + } + + chip->regmap = regmap_init_i2c(client, &halo7221_regmap_config); + if (!chip->regmap) { + pr_err("parent regmap is missing\n"); + return -EINVAL; + } + chip->name = DEVICE_NAME; + chip->client = client; + chip->dev = &client->dev; + + chip->bus.read = halo7221_read; + chip->bus.write = halo7221_write; + chip->bus.read_buf = halo7221_read_buffer; + chip->bus.write_buf = halo7221_write_buffer; + chip->bus.write_masked = halo7221_write_masked; + + device_init_wakeup(chip->dev, true); + i2c_set_clientdata(client, chip); + + ret = halo7221_parse_dt(chip); + if (ret < 0) { + dev_err(chip->dev, "%s: parse dt error [%d]\n", __func__, ret); + goto cleanup; + } + + ret = halo7221_gpio_init(chip); + if (ret < 0) { + dev_err(chip->dev, "%s: gpio init error [%d]\n", __func__, ret); + goto cleanup; + } + /* + ret = halo7221_hw_init(chip); + if (ret < 0) { + dev_err(chip->dev, "%s: chip hw init error [%d]\n", + __func__, ret); + goto cleanup; + } +*/ + + sysfs_create_group(&client->dev.kobj, &halo7221_sysfs_group); + + halo_cfg.drv_data = chip; + chip->halo_psy = + power_supply_register(chip->dev, &halo_psy_desc, &halo_cfg); + + dev_info(chip->dev, "Success probe halo7221 driver\n"); + + return 0; +cleanup: + i2c_set_clientdata(client, NULL); + + return rc; +} + +static int halo7221_remove(struct i2c_client *client) +{ + sysfs_remove_group(&client->dev.kobj, &halo7221_sysfs_group); + + return 0; +} + +static const struct i2c_device_id halo7221_dev_id[] = { + { DEVICE_NAME, 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, halo7221_dev_id); + +static struct i2c_driver halo7221_driver = { + .driver = { + .name = DEVICE_NAME, + .owner = THIS_MODULE, + .of_match_table = match_table, + }, + .probe = halo7221_probe, + .remove = halo7221_remove, + .id_table = halo7221_dev_id, +}; + +static int __init halo7221_init(void) +{ + int ret; + int drv_load = 0; + + drv_load = get_board_version(); + if (!drv_load) + return 0; + + ret = i2c_add_driver(&halo7221_driver); + if (ret) + printk(KERN_ERR "halo7221 i2c driver init failed!\n"); + + return ret; +} + +static void __exit halo7221_exit(void) +{ + i2c_del_driver(&halo7221_driver); +} + +module_init(halo7221_init); +module_exit(halo7221_exit); + +MODULE_AUTHOR("Yangwl@maxictech.com"); +MODULE_DESCRIPTION("halo7221 Wireless Power Receiver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/power/supply/lionsemi/Kconfig b/drivers/power/supply/lionsemi/Kconfig new file mode 100644 index 000000000000..4c4c97abd925 --- /dev/null +++ b/drivers/power/supply/lionsemi/Kconfig @@ -0,0 +1,14 @@ +menu "Lion Semiconductor Inc. Charger Support" + +config LN8282 + tristate "LN8282 Charge Pump" + depends on I2C + help + Say Y to include support for LN8282 charger pump. + LN8282 is a charger pump chip. + The driver supports charger enable/disable. + The driver reports the charger status via the power supply framework. + The driver controls 8282 via I2C and + supports device-tree interface. + +endmenu diff --git a/drivers/power/supply/lionsemi/Makefile b/drivers/power/supply/lionsemi/Makefile new file mode 100644 index 000000000000..a3ad4b3b5aba --- /dev/null +++ b/drivers/power/supply/lionsemi/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_LN8282) += ln8282.o diff --git a/drivers/power/supply/lionsemi/ln8282.c b/drivers/power/supply/lionsemi/ln8282.c new file mode 100644 index 000000000000..29a9f372a6b0 --- /dev/null +++ b/drivers/power/supply/lionsemi/ln8282.c @@ -0,0 +1,1088 @@ +/* + * Driver (skeleton code) for LIONSEMI LN8282 SC Voltage Regulator + * + * Copyright (C) 2019 Lion Semiconductor Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * + * Author: Jae Lee + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define LN8282_DRIVER_NAME "ln8282" +#define LN8282_HW_REV_Bx + +#define LN8282_DEBUG_OTP_CTRL + +/********************************************************************************* + * DESIGN GUIDE: + *********************************************************************************/ + +/********************************************************************************* + * register map + *********************************************************************************/ + +#define LN8282_MASK_SC_OPERATION_MODE 0x03 +#define LN8282_MASK_POWERON_IRQ_EN 0x04 +#define LN8282_MASK_SWAP_EN 0x80 + +#ifdef LN8282_HW_REV_Bx +#define LN8282_MASK_BC_SYS 0x1F +#else +#define LN8282_MASK_BC_SYS 0x0F +#endif + +#define LN8282_INT_BYTES 3 + +#define LN8282_REG_DEVICE_ID 0x00 +#define LN8282_REG_INT_DEVICE_0 0x01 +#define LN8282_REG_INT_DEVICE_1 0x02 +#define LN8282_REG_INT_HV_SC_0 0x03 +#define LN8282_REG_INT_HV_SC_1 0x04 +#define LN8282_REG_INT_DEVICE_0_MSK 0x05 +#define LN8282_REG_INT_DEVICE_1_MSK 0x06 +#define LN8282_REG_INT_HV_SC_0_MSK 0x07 +#define LN8282_REG_INT_HV_SC_1_MSK 0x08 +#define LN8282_REG_INT_DEVICE_0_STS 0x09 +#define LN8282_REG_INT_DEVICE_1_STS 0x0A +#define LN8282_REG_INT_HV_SC_0_STS 0x0B +#define LN8282_REG_INT_HV_SC_1_STS 0x0C +#define LN8282_REG_DEVICE_CTRL_0 0x0D +#define LN8282_REG_DEVICE_CTRL_1 0x0E +#define LN8282_REG_HV_SC_CTRL_0 0x0F +#define LN8282_REG_HV_SC_CTRL_1 0x10 +#define LN8282_REG_HV_SC_CTRL_2 0x11 +#define LN8282_REG_SC_DITHER_CTRL 0x12 +#define LN8282_REG_GLITCH_CTRL 0x13 +#define LN8282_REG_FAULT_CTRL 0x14 +#define LN8282_REG_TRACK_CTRL 0x15 +#define LN8282_REG_LION_CTRL 0x20 + +#define LN8282_REG_TRIM_4 0x25 +#define LN8282_REG_TRIM_7 0x28 + +#ifdef LN8282_HW_REV_Bx +#define LN8282_REG_BC_OP_SUPPORT_CTRL 0x2E +#define LN8282_REG_NVM_DIN 0x38 +#define LN8282_REG_NVM_CTRL 0x39 +#define LN8282_REG_NVM_DOUT 0x3A +#define LN8282_REG_STS_F 0x42 +#define LN8282_REG_STS_G 0x43 +#define LN8282_REG_INTERNAL_RSVD 0x4D +#define LN8282_MAX_REGISTER LN8282_REG_INTERNAL_RSVD +#else +#define LN8282_REG_BC_OP_SUPPORT_CTRL 0x2D +#define LN8282_REG_NVM_DIN 0x32 +#define LN8282_REG_NVM_CTRL 0x33 +#define LN8282_REG_NVM_DOUT 0x34 +#define LN8282_REG_STS_D 0x3A +#define LN8282_REG_DEVICE_MARKER 0x46 +#define LN8282_MAX_REGISTER LN8282_REG_DEVICE_MARKER +#endif + +#define LN8282_REG_PRINT(regmap, reg_addr, val) \ + do { \ + regmap_read(regmap, reg_addr, &val); \ + pr_info("ln8282_reg: --> [%-30s] 0x%02X : 0x%02X\n", \ + #reg_addr, reg_addr, val & 0xFF); \ + } while (0) + +/********************************************************************************* + * data structures / platform data + *********************************************************************************/ + +enum { + LN8282_STATE_UNKNOWN = -1, + LN8282_STATE_IDLE = 2, + LN8282_STATE_SW_ACTIVE = 7, + LN8282_STATE_BYPASS_ACTIVE = 12, +}; + +#define LN8282_TIMER_INIT 3 + +/** + * struct ln8282_info - ln8282 regulator instance + * @monitor_wake_lock: lock to enter the suspend mode + * @lock: protects concurrent access to online variables + * @client: pointer to client + * @regmap: pointer to driver regmap + * @op_mode : chip operation mode (STANDBY, BYPASS, SWITCHING) + * @reverse_power : enable reverse power path + * @pdata: pointer to platform data + */ + +struct ln8282_dt_props { + unsigned int enable_gpio; +}; + +struct ln8282_info { + char *name; + struct device *dev; + struct i2c_client *client; + struct mutex lock; + struct regmap *regmap; + + int op_mode; + bool reverse_power; + bool auto_recovery; + + struct ln8282_dt_props dt_props; + struct pinctrl *ln_pinctrl; + struct pinctrl_state *ln_gpio_active; + struct pinctrl_state *ln_gpio_suspend; + + struct power_supply *ln_psy; +}; + +static struct ln8282_info *g_info; + +static const struct regmap_config ln8282_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = LN8282_MAX_REGISTER, +}; + +/********************************************************************************* + * supported CORE functionality + *********************************************************************************/ + +void ln8282_use_ext_5V(struct ln8282_info *info, unsigned int enable) +{ + regmap_update_bits(info->regmap, LN8282_REG_DEVICE_CTRL_1, 0x01, + (enable & 0x01)); +} +EXPORT_SYMBOL(ln8282_use_ext_5V); + +void ln8282_set_infet(struct ln8282_info *info, unsigned int enable) +{ + regmap_update_bits(info->regmap, LN8282_REG_DEVICE_CTRL_0, 0x01, + (enable & 0x01)); +} +EXPORT_SYMBOL(ln8282_set_infet); + +void ln8282_set_powerpath(struct ln8282_info *info, bool forward_path) +{ + info->reverse_power = (!forward_path); +} +EXPORT_SYMBOL(ln8282_set_powerpath); + +/* add for other module run */ +/* +void ln8282_set_powerpath_ext(bool forward_path) +{ + g_info->reverse_power = (!forward_path); + printk("%s:reverse_power:%d\n", __func__, g_info->reverse_power); +} +*/ + +static inline int ln8282_get_opmode(struct ln8282_info *info) +{ + int val; + if (regmap_read(info->regmap, LN8282_REG_HV_SC_CTRL_0, &val) < 0) + val = LN8282_OPMODE_UNKNOWN; + return (val & LN8282_MASK_SC_OPERATION_MODE); +} + +/* add for wireless driver get opmode */ +/* +unsigned int ln8282_get_opmode_ext(void) +{ + int val; + if (regmap_read(g_info->regmap, LN8282_REG_HV_SC_CTRL_0, &val) < 0) + val = LN8282_OPMODE_UNKNOWN; + return (val & LN8282_MASK_SC_OPERATION_MODE); +} +*/ +static inline void ln8282_auto_recovery(struct ln8282_info *info, + unsigned int enable) +{ + regmap_update_bits(info->regmap, LN8282_REG_DEVICE_CTRL_1, 0x40, + (enable << 6)); +} + +/* configure minimum set of control registers */ +static inline void ln8282_set_base_opt_Bx(struct ln8282_info *info, + unsigned int sc_out_precharge_cfg, + unsigned int vbus_in_max_ov_cfg, + unsigned int track_cfg) +{ + regmap_update_bits(info->regmap, LN8282_REG_HV_SC_CTRL_1, 0x60, + (vbus_in_max_ov_cfg << 6) | + (sc_out_precharge_cfg << 5)); + regmap_update_bits(info->regmap, LN8282_REG_TRACK_CTRL, 0x10, + (track_cfg << 4)); + + ln8282_auto_recovery(info, 1); +} + +static inline void ln8282_set_vbus_uv_track(struct ln8282_info *info, + unsigned int disable) +{ + regmap_update_bits(info->regmap, LN8282_REG_TRACK_CTRL, 0x04, + (disable << 2)); +} + +static inline void ln8282_set_switch_seq(struct ln8282_info *info, + unsigned int alt_en) +{ + regmap_write(info->regmap, LN8282_REG_LION_CTRL, 0x5B); + regmap_update_bits(info->regmap, LN8282_REG_TRIM_4, 0x04, + (alt_en << 2)); + regmap_write(info->regmap, LN8282_REG_LION_CTRL, 0x00); +} + +static void ln8282_enter_standby(struct ln8282_info *info) +{ + regmap_update_bits(info->regmap, LN8282_REG_HV_SC_CTRL_0, + LN8282_MASK_SC_OPERATION_MODE, + LN8282_OPMODE_STANDBY); + ln8282_set_base_opt_Bx(info, 1, 0, 1); + regmap_write(info->regmap, LN8282_REG_FAULT_CTRL, 0x04); +} + +static void ln8282_enter_bypass(struct ln8282_info *info) +{ + ln8282_set_base_opt_Bx(info, 1, 0, 1); + + if (info->reverse_power) + regmap_write(info->regmap, LN8282_REG_FAULT_CTRL, 0x0B); + else + regmap_write(info->regmap, LN8282_REG_FAULT_CTRL, 0x0C); + + regmap_update_bits(info->regmap, LN8282_REG_HV_SC_CTRL_0, + LN8282_MASK_SC_OPERATION_MODE, LN8282_OPMODE_BYPASS); +} + +static bool ln8282_vin_switch_ok(struct ln8282_info *info) +{ + int val; + if (regmap_read(info->regmap, LN8282_REG_INT_DEVICE_0_STS, &val) < 0) { + pr_warn("%s: Unable to read INT_DEVICE_0_STS\n", __func__); + return false; + } + + if ((val & 0x08) <= 0) { + pr_warn("%s: INVALID VIN range for switching operation.\n", + __func__); + return false; + } + + return true; +} + +static void ln8282_enter_switching(struct ln8282_info *info) +{ + if (info->reverse_power) { + pr_info("%s:set switch in reverse mode\n"); + ln8282_set_switch_seq(info, 0); + ln8282_set_base_opt_Bx(info, 0, 1, 0); + ln8282_set_vbus_uv_track(info, 1); + regmap_write(info->regmap, LN8282_REG_FAULT_CTRL, 0x09); + } else { + if (!ln8282_vin_switch_ok(info)) { + pr_warn("%s: Failed to transition to forward SWITCHING mode.\n", + __func__); + return; + } + pr_info("%s:set switch in forward mode\n"); + ln8282_set_switch_seq(info, 1); + ln8282_set_base_opt_Bx(info, 0, 1, 0); + regmap_write(info->regmap, LN8282_REG_FAULT_CTRL, 0x04); + } + + regmap_update_bits(info->regmap, LN8282_REG_HV_SC_CTRL_0, + LN8282_MASK_SC_OPERATION_MODE, + LN8282_OPMODE_SWITCHING); + + if (info->reverse_power) { + msleep(50); + ln8282_set_vbus_uv_track(info, 0); + } else { + msleep(100); + regmap_write(info->regmap, LN8282_REG_FAULT_CTRL, 0x0C); + } +} +/* main function for setting/changing operation mode */ +bool ln8282_change_opmode(struct ln8282_info *info, unsigned int target_mode) +{ + bool ret; + + info->op_mode = ln8282_get_opmode(info); + if (target_mode < 0 || target_mode > LN8282_OPMODE_SWITCHING_ALT) { + pr_err("%s: target operation mode (0x%02X) is invalid\n", + __func__, target_mode); + return false; + } + /* NOTE: + * CUSTOMER should know/indicate if power path is forward/reverse mode + * based on power connections before attempting to change operation mode + */ + + dev_info(info->dev, "opmode from %d change to %d\n", info->op_mode, + target_mode); + ret = true; + switch (target_mode) { + case LN8282_OPMODE_STANDBY: + ln8282_enter_standby(info); + break; + case LN8282_OPMODE_BYPASS: + ln8282_enter_bypass(info); + break; + case LN8282_OPMODE_SWITCHING: + case LN8282_OPMODE_SWITCHING_ALT: + ln8282_enter_switching(info); + break; + default: + ret = false; + } + return ret; +} +EXPORT_SYMBOL(ln8282_change_opmode); + +/* +bool ln8282_change_opmode_ext(unsigned int target_mode) +{ + g_info->op_mode = ln8282_get_opmode(g_info); + + if (target_mode < 0 || target_mode > LN8282_OPMODE_SWITCHING_ALT) { + pr_err("%s: target operation mode (0x%02X) is invalid\n", + __func__, target_mode); + return false; + } + printk("opmode from %d change to %d\n", g_info->op_mode, target_mode); + switch (target_mode) { + case LN8282_OPMODE_STANDBY: + ln8282_enter_standby(g_info); + break; + case LN8282_OPMODE_BYPASS: + ln8282_enter_bypass(g_info); + break; + case LN8282_OPMODE_SWITCHING: + case LN8282_OPMODE_SWITCHING_ALT: + ln8282_enter_switching(g_info); + break; + default: + return false; + } + return true; +} +*/ + +int ln8282_hw_init(struct ln8282_info *info) +{ + /* NOTES: + * When power source is removed, LN8282 is powered off and all register settings are lost + * So, LN8282 should be re-initialized every time it is powered on + * This routine should be called when the RX IC or PMIC detects a new power source + */ + + /* CUSTOMER should add basic initialization tasks + * -- unmasking interrupts + * -- overriding OTP settings, etc + */ + pr_info("%s: HW initialization\n", __func__); + +#ifdef LN8282_HW_REV_A1 + regmap_update_bits(info->regmap, LN8282_REG_HV_SC_CTRL_1, 0x10, + (1 << 4)); + regmap_update_bits(info->regmap, LN8282_REG_TRACK_CTRL, 0x04, (1 << 2)); +#endif + +#ifdef LN8282_HW_REV_Bx + regmap_write(info->regmap, LN8282_REG_LION_CTRL, 0x5B); + + regmap_update_bits(info->regmap, LN8282_REG_TRIM_7, LN8282_MASK_SWAP_EN, + 0 /*<<7*/); + regmap_write(info->regmap, LN8282_REG_LION_CTRL, 0x00); +#endif + + info->reverse_power = false; + + return 1; +} +EXPORT_SYMBOL(ln8282_hw_init); + +/********************************************************************************* + * (experimental) OTP support : NEVER use this in production releases + *********************************************************************************/ + +#ifdef LN8282_DEBUG_OTP_CTRL +#define LN8282_OTP_MASK_WRITE_EN 0x10 +#define LN8282_OTP_MASK_CS 0x80 +#define LN8282_OTP_MASK_ADDR 0x0F +#define LN8282_OTP_MASK_PROG 0x20 +static void ln8282_otp_power(struct ln8282_info *info, const bool enable) +{ + if (enable) { + msleep(2); + regmap_update_bits(info->regmap, LN8282_REG_BC_OP_SUPPORT_CTRL, + 0x02, (1 << 1)); //VPP_to_HV=1 + msleep(1); + } else { + //power down (lower VPP) + msleep(2); + regmap_update_bits(info->regmap, LN8282_REG_BC_OP_SUPPORT_CTRL, + 0x02, (0 << 1)); //VPP_to_HV=0 + msleep(1); + } +} + +static void ln8282_otp_write(struct ln8282_info *info, unsigned int otp_addr, + unsigned int otp_data) +{ + unsigned int nvm_ctrl; //NVM_CTRL value + + regmap_write(info->regmap, LN8282_REG_LION_CTRL, 0x5B); + ln8282_otp_power(info, true /*power-up*/); + + regmap_write(info->regmap, LN8282_REG_NVM_DIN, 0xFF); + nvm_ctrl = 0xFF & LN8282_OTP_MASK_WRITE_EN; + regmap_write(info->regmap, LN8282_REG_NVM_CTRL, nvm_ctrl); + + msleep(1); + + nvm_ctrl |= (0xFF & LN8282_OTP_MASK_CS); //CS = 1 + regmap_write(info->regmap, LN8282_REG_NVM_CTRL, nvm_ctrl); + + regmap_write(info->regmap, LN8282_REG_NVM_DIN, otp_data); + + nvm_ctrl |= (LN8282_OTP_MASK_ADDR & otp_addr); + regmap_write(info->regmap, LN8282_REG_NVM_CTRL, nvm_ctrl); + udelay(6); + + nvm_ctrl |= (0xFF & LN8282_OTP_MASK_PROG); + regmap_write(info->regmap, LN8282_REG_NVM_CTRL, nvm_ctrl); + + udelay(220); + + nvm_ctrl &= (0xFF & ~LN8282_OTP_MASK_PROG); + regmap_write(info->regmap, LN8282_REG_NVM_CTRL, nvm_ctrl); + + udelay(6 * 2); + + regmap_write(info->regmap, LN8282_REG_NVM_DIN, 0xFF); + + nvm_ctrl &= (0xFF & ~LN8282_OTP_MASK_CS); + regmap_write(info->regmap, LN8282_REG_NVM_CTRL, nvm_ctrl); + + udelay(6); + + nvm_ctrl &= (0xFF & ~LN8282_OTP_MASK_WRITE_EN); + regmap_write(info->regmap, LN8282_REG_NVM_CTRL, nvm_ctrl); + + ln8282_otp_power(info, false /*power-down*/); + regmap_write(info->regmap, LN8282_REG_LION_CTRL, 0x00); +} + +#endif + +/********************************************************************************* + * LION-DEBUG: user-space interaction through sysfs (for testing only) + *********************************************************************************/ + +static unsigned int ln8282_regcmd_addr; +static unsigned int ln8282_regcmd_data; +static bool ln8282_regcmd_valid; + +static ssize_t ln8282_sysfs_show_regcmd(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (ln8282_regcmd_valid) { + pr_info("%s: /sysfs/ return stored data value (0x%02X)\n", + __func__, ln8282_regcmd_data & 0xFF); + return scnprintf(buf, PAGE_SIZE, "0x%02x\n", + ln8282_regcmd_data & 0xFF); + } else { + pr_warn("%s: /sysfs/ regcmd is invalid or was not issued\n", + __func__); + return scnprintf(buf, PAGE_SIZE, "NA\n"); + } +} + +static ssize_t ln8282_sysfs_store_regcmd(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ln8282_info *info = dev_get_drvdata(dev); + bool write_cmd; + int ret; + /* command format: + * >>read,0x01 : read from 0x01 + * >>write,0x01,0xAA : write to 0x01 + */ + + ln8282_regcmd_valid = false; + if (strncmp("read,", buf, 5) == 0) + write_cmd = false; + else if (strncmp("write,", buf, 6) == 0) + write_cmd = true; + else { + pr_warn("%s: /sysfs/ invalid command: %s\n", __func__, buf); + goto parse_error; + } + + if (write_cmd) { + if (sscanf(buf, "write,%x,%x", &ln8282_regcmd_addr, + &ln8282_regcmd_data) != 2) + goto parse_error; + if (ln8282_regcmd_addr > LN8282_MAX_REGISTER || + ln8282_regcmd_data > 0xFF) { + pr_warn("%s: /sysfs/ write command addr/data out of bounds\n", + __func__); + goto parse_error; + } + + pr_info("%s: /sysfs/ writing to addr 0x%02X (data=0x%02X)\n", + __func__, ln8282_regcmd_addr, ln8282_regcmd_data); + ret = regmap_write(info->regmap, ln8282_regcmd_addr, + ln8282_regcmd_data); + } else { + if (sscanf(buf, "read,%x", &ln8282_regcmd_addr) != 1) + goto parse_error; + if (ln8282_regcmd_addr > LN8282_MAX_REGISTER) { + pr_warn("%s: /sysfs/ read command addr out of bounds\n", + __func__); + goto parse_error; + } + + pr_info("%s: /sysfs/ reading from addr 0x%02X\n", __func__, + ln8282_regcmd_addr); + ret = regmap_read(info->regmap, ln8282_regcmd_addr, + &ln8282_regcmd_data); + } + if (ret < 0) + return ret; + + ln8282_regcmd_valid = true; + return count; + +parse_error: + pr_warn("%s: /sysfs/ unable to parse command (%s)\n", __func__, buf); + return count; +} + +static ssize_t ln8282_sysfs_show_opmode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ln8282_info *info = dev_get_drvdata(dev); + int ret; + + pr_info("%s: /sysfs/ retrieve op_mode\n", __func__); + + info->op_mode = ln8282_get_opmode(info); + switch (info->op_mode) { + case LN8282_OPMODE_STANDBY: + ret = scnprintf(buf, PAGE_SIZE, "standby\n"); + break; + case LN8282_OPMODE_BYPASS: + ret = scnprintf(buf, PAGE_SIZE, "bypass\n"); + break; + case LN8282_OPMODE_SWITCHING: + case LN8282_OPMODE_SWITCHING_ALT: + ret = scnprintf(buf, PAGE_SIZE, "switching\n"); + break; + case LN8282_OPMODE_UNKNOWN: + default: + ret = scnprintf(buf, PAGE_SIZE, "unknown\n"); + } + return ret; +} + +static ssize_t ln8282_sysfs_show_dump(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ln8282_info *info = dev_get_drvdata(dev); + int val; + + pr_info("----------------------/dump/---------------------\n"); + pr_info("ln8282_reg: [ %-19s] /addr/ : /value/\n", + "Register Name"); + LN8282_REG_PRINT(info->regmap, LN8282_REG_DEVICE_CTRL_0, val); + LN8282_REG_PRINT(info->regmap, LN8282_REG_HV_SC_CTRL_0, val); + LN8282_REG_PRINT(info->regmap, LN8282_REG_HV_SC_CTRL_1, val); + LN8282_REG_PRINT(info->regmap, LN8282_REG_FAULT_CTRL, val); + LN8282_REG_PRINT(info->regmap, LN8282_REG_TRACK_CTRL, val); + +#ifdef LN8282_HW_REV_Bx + LN8282_REG_PRINT(info->regmap, LN8282_REG_STS_F, val); + LN8282_REG_PRINT(info->regmap, LN8282_REG_STS_G, val); +#else + LN8282_REG_PRINT(info->regmap, LN8282_REG_STS_D, val); +#endif + + pr_info("----------------------/dump/---------------------\n"); + return scnprintf(buf, PAGE_SIZE, "done\n"); +} + +static ssize_t ln8282_sysfs_store_opmode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ln8282_info *info = dev_get_drvdata(dev); + int opmode; + + if (strncmp("standby", buf, 7) == 0) + opmode = LN8282_OPMODE_STANDBY; + else if (strncmp("bypass", buf, 6) == 0) + opmode = LN8282_OPMODE_BYPASS; + else if (strncmp("switching", buf, 9) == 0) + opmode = LN8282_OPMODE_SWITCHING; + else + opmode = LN8282_OPMODE_UNKNOWN; + pr_info("%s: /sysfs/ set op_mode to 0x%02X==%s", __func__, opmode, buf); + + if (!ln8282_change_opmode(info, opmode)) + pr_warn("%s: /sysfs/ unable to enter %s\n", __func__, buf); + return count; +} + +static ssize_t ln8282_sysfs_store_infet(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ln8282_info *info = dev_get_drvdata(dev); + unsigned int enable; + if (strncmp("1", buf, 1) == 0) + enable = 1; + else + enable = 0; + ln8282_set_infet(info, enable); + return count; +} + +static ssize_t ln8282_sysfs_store_ext_5v(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ln8282_info *info = dev_get_drvdata(dev); + unsigned int enable; + if (strncmp("1", buf, 1) == 0) + enable = 1; + else + enable = 0; + ln8282_use_ext_5V(info, enable); + return count; +} + +static ssize_t ln8282_sysfs_store_powerpath(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ln8282_info *info = dev_get_drvdata(dev); + bool forward; + if (strncmp("forward", buf, 1) == 0) + forward = true; + else + forward = false; + ln8282_set_powerpath(info, forward); + return count; +} + +static ssize_t ln8282_sysfs_hw_init(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ln8282_info *info = dev_get_drvdata(dev); + + ln8282_hw_init(info); + return scnprintf(buf, PAGE_SIZE, "done\n"); +} + +#ifdef LN8282_DEBUG_OTP_CTRL +static ssize_t ln8282_sysfs_otp_overwrite(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ln8282_info *info = dev_get_drvdata(dev); + +#ifdef LN8282_HW_REV_Bx + pr_info("%s: ********************** WARNING **********************\n", + __func__); + pr_info("%s: --> this is an experimental feature (temporary fix)\n", + __func__); + pr_info("%s: NEVER use this in production release\n", __func__); + pr_info("%s: --> begin to overwrite OTP cell [0xF] to 0xF8\n", + __func__); + + ln8282_otp_write(info, 0x0F /*OTP cell addr*/, 0xF8 /*new OTP value*/); + + pr_info("%s: --> finished overwriting OTP cell\n", __func__); + pr_info("%s: --> now, unplug/re-plugin VIN to power-up chip\n", + __func__); + pr_info("%s: *****************************************************\n", + __func__); +#endif + + return scnprintf(buf, PAGE_SIZE, + "unplug VIN to power-up LN8282 again\n"); +} +static DEVICE_ATTR(otp_overwrite, 0444, ln8282_sysfs_otp_overwrite, NULL); +#endif + +static DEVICE_ATTR(dump, 0444, ln8282_sysfs_show_dump, NULL); +static DEVICE_ATTR(hw_init, 0444, ln8282_sysfs_hw_init, NULL); +static DEVICE_ATTR(infet, 0200, NULL, ln8282_sysfs_store_infet); +static DEVICE_ATTR(ext_5v, 0200, NULL, ln8282_sysfs_store_ext_5v); +static DEVICE_ATTR(powerpath, 0200, NULL, ln8282_sysfs_store_powerpath); +static DEVICE_ATTR(opmode, 0644, ln8282_sysfs_show_opmode, + ln8282_sysfs_store_opmode); +static DEVICE_ATTR(regcmd, 0644, ln8282_sysfs_show_regcmd, + ln8282_sysfs_store_regcmd); +static struct attribute *ln8282_info_attr[] = { + &dev_attr_dump.attr, &dev_attr_hw_init.attr, +#ifdef LN8282_DEBUG_OTP_CTRL + &dev_attr_otp_overwrite.attr, +#endif + &dev_attr_regcmd.attr, &dev_attr_opmode.attr, + &dev_attr_infet.attr, &dev_attr_ext_5v.attr, + &dev_attr_powerpath.attr, NULL, +}; + +static const struct attribute_group ln8282_attr_group = { + .attrs = ln8282_info_attr, +}; + +/********************************************************************************* + * device layer + *********************************************************************************/ + +static int ln8282_parse_dt(struct ln8282_info *info) +{ + struct device_node *node = info->dev->of_node; + if (!node) { + dev_err(info->dev, "device tree node missing\n"); + return -EINVAL; + } + + info->dt_props.enable_gpio = of_get_named_gpio(node, "ln,enable", 0); + if ((!gpio_is_valid(info->dt_props.enable_gpio))) + return -EINVAL; + + return 0; +} + +static int ln8282_gpio_init(struct ln8282_info *info) +{ + int ret = 0; + + info->ln_pinctrl = devm_pinctrl_get(info->dev); + if (IS_ERR_OR_NULL(info->ln_pinctrl)) { + dev_err(info->dev, "No pinctrl config specified\n"); + ret = PTR_ERR(info->dev); + return ret; + } + info->ln_gpio_active = + pinctrl_lookup_state(info->ln_pinctrl, "ln8282_active"); + if (IS_ERR_OR_NULL(info->ln_gpio_active)) { + dev_err(info->dev, "No active config specified\n"); + ret = PTR_ERR(info->ln_gpio_active); + return ret; + } + info->ln_gpio_suspend = + pinctrl_lookup_state(info->ln_pinctrl, "ln8282_suspend"); + if (IS_ERR_OR_NULL(info->ln_gpio_suspend)) { + dev_err(info->dev, "No suspend config specified\n"); + ret = PTR_ERR(info->ln_gpio_suspend); + return ret; + } + + ret = pinctrl_select_state(info->ln_pinctrl, info->ln_gpio_active); + if (ret < 0) { + dev_err(info->dev, "fail to select pinctrl active rc=%d\n", + ret); + return ret; + } + + return ret; +} + +extern char *saved_command_line; + +static int get_board_version(void) +{ + char boot[5] = { '\0' }; + char *match = (char *)strnstr( + saved_command_line, + "androidboot.hwlevel=", strlen(saved_command_line)); + if (match) { + memcpy(boot, (match + strlen("androidboot.hwlevel=")), + sizeof(boot) - 1); + printk("%s: hwlevel is %s\n", __func__, boot); + if (!strncmp(boot, "P1.3", strlen("P1.3"))) + return 0; + } + return 1; +} + +#define FORWARD_BYPASS 1 +#define FORWARD_SWITCH 2 +#define REVERSE_SWITCH 3 +#define REVERSE_BYPASS 4 +static int ln8282_set_mode(struct ln8282_info *info, int mode) +{ + int ret = 0; + switch (mode) { + case FORWARD_BYPASS: + ln8282_set_powerpath(info, true); + ln8282_change_opmode(info, LN8282_OPMODE_BYPASS); + break; + case FORWARD_SWITCH: + ln8282_set_powerpath(info, true); + ln8282_change_opmode(info, LN8282_OPMODE_SWITCHING); + break; + case REVERSE_SWITCH: + ln8282_set_powerpath(info, false); + ln8282_change_opmode(info, LN8282_OPMODE_SWITCHING); + break; + case REVERSE_BYPASS: + ln8282_set_powerpath(info, false); + ln8282_change_opmode(info, LN8282_OPMODE_BYPASS); + default: + dev_err(info->dev, "%s: invalid settings\n", __func__); + } + + info->op_mode = ln8282_get_opmode(info); + + return ret; +} + +static enum power_supply_property ln8282_props[] = { + POWER_SUPPLY_PROP_DIV_2_MODE, + POWER_SUPPLY_PROP_RESET_DIV_2_MODE, +}; + +static int ln8282_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct ln8282_info *info = power_supply_get_drvdata(psy); + + switch (psp) { + case POWER_SUPPLY_PROP_DIV_2_MODE: + val->intval = info->op_mode; + break; + default: + return -EINVAL; + } + return 0; +} + +static int ln8282_set_prop(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + struct ln8282_info *info = power_supply_get_drvdata(psy); + int rc = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_DIV_2_MODE: + rc = ln8282_set_mode(info, val->intval); + break; + case POWER_SUPPLY_PROP_RESET_DIV_2_MODE: + info->op_mode = 0; + break; + default: + return -EINVAL; + } + + return rc; +} + +static int ln8282_prop_is_writeable(struct power_supply *psy, + enum power_supply_property psp) +{ + int rc; + + switch (psp) { + case POWER_SUPPLY_PROP_DIV_2_MODE: + case POWER_SUPPLY_PROP_RESET_DIV_2_MODE: + return 1; + default: + rc = 0; + break; + } + + return rc; +} + +static const struct power_supply_desc ln_psy_desc = { + .name = "lionsemi", + .type = POWER_SUPPLY_TYPE_WIRELESS, + .properties = ln8282_props, + .num_properties = ARRAY_SIZE(ln8282_props), + .get_property = ln8282_get_prop, + .set_property = ln8282_set_prop, + .property_is_writeable = ln8282_prop_is_writeable, +}; + +static int ln8282_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ln8282_info *info; + struct power_supply_config ln_cfg = {}; + int ret = 0; + pr_info("%s: =/START-PROBE/=\n", __func__); + + /* allocate memory for our device state and initialize it */ + info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL); + if (info == NULL) + return -ENOMEM; + + mutex_init(&info->lock); + info->name = LN8282_DRIVER_NAME; + info->client = client; + info->dev = &client->dev; + i2c_set_clientdata(client, info); + + info->regmap = devm_regmap_init_i2c(client, &ln8282_regmap_config); + if (IS_ERR(info->regmap)) { + pr_err("%s: failed to initialize regmap\n", __func__); + return PTR_ERR(info->regmap); + } + + ret = ln8282_parse_dt(info); + if (ret < 0) { + dev_err(info->dev, "%s: parse dt error [%d]\n", __func__, ret); + goto cleanup; + } + + ret = ln8282_gpio_init(info); + if (ret < 0) { + dev_err(info->dev, "%s: gpio init error [%d]\n", __func__, ret); + goto cleanup; + } + + /* LION-DEBUG: test user-app through sysfs */ + if (sysfs_create_group(&info->client->dev.kobj, &ln8282_attr_group) < + 0) { + pr_err("%s: unable to create sysfs entries\n", __func__); + return -EINVAL; + } + + g_info = info; + + ln_cfg.drv_data = info; + info->ln_psy = power_supply_register(info->dev, &ln_psy_desc, &ln_cfg); + + pr_info("[ln8282]%s: success probe!\n", __func__); + return 0; + +cleanup: + i2c_set_clientdata(client, NULL); + return 0; +} + +static int ln8282_remove(struct i2c_client *client) +{ + struct ln8282_info *info = i2c_get_clientdata(client); + + dev_err(info->dev, "%s: driver remove\n", __func__); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int ln8282_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ln8282_info *info = i2c_get_clientdata(client); + + /* don't set bypass when suspend for reverse charge + ln8282_change_opmode(info, LN8282_OPMODE_BYPASS); + */ + dev_info(info->dev, "%s: suspend\n", __func__); + + return 0; +} + +static int ln8282_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ln8282_info *info = i2c_get_clientdata(client); + + pr_info("%s: update/resume\n", __func__); + dev_err(info->dev, "%s: resume\n", __func__); + return 0; +} +#endif +static SIMPLE_DEV_PM_OPS(ln8282_pm_ops, ln8282_suspend, ln8282_resume); + +#ifdef CONFIG_OF +static const struct of_device_id ln8282_dt_match[] = { + { .compatible = "lionsemi,ln8282" }, + {}, +}; +MODULE_DEVICE_TABLE(of, ln8282_dt_match); +#endif + +static const struct i2c_device_id ln8282_id[] = { { "ln8282", 0 }, {} }; +MODULE_DEVICE_TABLE(i2c, ln8282_id); + +static struct i2c_driver ln8282_driver = { + .driver = { + .name = LN8282_DRIVER_NAME, + .of_match_table = of_match_ptr(ln8282_dt_match), + .pm = &ln8282_pm_ops, + }, + .probe = ln8282_probe, + .remove = ln8282_remove, + .id_table = ln8282_id, +}; + +static int __init ln8282_init(void) +{ + int ret; + int drv_load = 0; + + drv_load = get_board_version(); + if (!drv_load) + return 0; + + ret = i2c_add_driver(&ln8282_driver); + if (ret) + printk(KERN_ERR "ln8282 i2c driver init failed!\n"); + + return ret; +} + +static void __exit ln8282_exit(void) +{ + i2c_del_driver(&ln8282_driver); +} + +module_init(ln8282_init); +module_exit(ln8282_exit); + +MODULE_AUTHOR("Jae Lee"); +MODULE_DESCRIPTION("LN8282 driver"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("0.3.0"); diff --git a/drivers/power/supply/maxim/Kconfig b/drivers/power/supply/maxim/Kconfig new file mode 100644 index 000000000000..8a7e1448e4c8 --- /dev/null +++ b/drivers/power/supply/maxim/Kconfig @@ -0,0 +1,27 @@ +menu "Maxim Integrated Products, Inc. Charger support" + +config BATT_VERIFY_BY_DS28E16 + tristate + prompt "Support ds28e16 as encryption IC." + help + It needs a onewire physical controller to work. + +config ONEWIRE_GPIO + tristate + prompt "Support Onewire Driver." + help + It's an onewire driver. + +config BATT_VERIFY_BY_DS28E16_NABU + tristate + prompt "Support ds28e16 as encryption IC." + help + It needs a onewire physical controller to work. + +config ONEWIRE_GPIO_NABU + tristate + prompt "Support Onewire Driver." + help + It's an onewire driver. + +endmenu diff --git a/drivers/power/supply/maxim/Makefile b/drivers/power/supply/maxim/Makefile new file mode 100644 index 000000000000..2e1cbc021058 --- /dev/null +++ b/drivers/power/supply/maxim/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_ONEWIRE_GPIO) += onewire_gpio.o +obj-$(CONFIG_BATT_VERIFY_BY_DS28E16) += onewire_gpio.o ucl_sha3.o sha384_software.o ds28e16.o +obj-$(CONFIG_ONEWIRE_GPIO_NABU) += onewire_gpio_master.o onewire_gpio_slave.o +obj-$(CONFIG_BATT_VERIFY_BY_DS28E16_NABU) += onewire_gpio_master.o onewire_gpio_slave.o ucl_sha3.o sha384_software.o ds28e16_master.o ds28e16_slave.o diff --git a/drivers/power/supply/maxim/ds28e16.c b/drivers/power/supply/maxim/ds28e16.c new file mode 100644 index 000000000000..2947b5b361c8 --- /dev/null +++ b/drivers/power/supply/maxim/ds28e16.c @@ -0,0 +1,1904 @@ +/******************************************************************************* + * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved. + * + ******************************************************************************* + * + * DS28E16.c - DS28E16 device module. Requires low level 1-Wire connection. + */ +#define pr_fmt(fmt) "[ds28e16] %s: " fmt, __func__ + +#include /* kfree() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sha384_software.h" +#include "ds28e16.h" +#include "onewire_gpio.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ds_info pr_err +#define ds_dbg pr_err +#define ds_err pr_err +#define ds_log pr_err + +struct ds28e16_data { + struct platform_device *pdev; + struct device *dev; + + int version; + + struct power_supply *verify_psy; + struct power_supply_desc verify_psy_d; + + struct delayed_work authentic_work; +}; + +unsigned int attr_trytimes = 1; + +unsigned char session_seed[32] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA }; +unsigned char S_secret[32] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA }; +unsigned char challenge[32] = { 0x00 }; +int auth_ANON = 1; +int auth_BDCONST = 1; +int pagenumber = 1; + +// maxim define +int tm = 1; +unsigned short CRC16; +const short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; +unsigned char last_result_byte = RESULT_SUCCESS; + +unsigned char MANID[2] = { 0x00 }; + +// mi add +unsigned char flag_mi_romid = 0; +unsigned char flag_mi_status = 0; +unsigned char flag_mi_page0_data = 0; +unsigned char flag_mi_page1_data = 0; +unsigned char flag_mi_counter = 0; +unsigned char flag_mi_auth_result = 0; +unsigned char mi_romid[8] = { 0x00 }; +unsigned char mi_status[8] = { 0x00 }; +unsigned char mi_page0_data[16] = { 0x00 }; +unsigned char mi_page1_data[16] = { 0x00 }; +unsigned char mi_counter[16] = { 0x00 }; +int mi_auth_result = 0x00; + +unsigned char crc_low_first(unsigned char *ptr, unsigned char len) +{ + unsigned char i; + unsigned char crc = 0x00; + + while (len--) { + crc ^= *ptr++; + for (i = 0; i < 8; ++i) { + if (crc & 0x01) + crc = (crc >> 1) ^ 0x8c; + else + crc = (crc >> 1); + } + } + + return (crc); +} + +short Read_RomID(unsigned char *RomID) +{ + unsigned char i; + unsigned char crc = 0x00; + + if (flag_mi_romid == 2) { + memcpy(RomID, mi_romid, 8); + ds_log("lvchen---Read_RomID00\n"); + return DS_TRUE; + } + + if ((ow_reset()) != 0) { + ds_err("Read_RomID: Failed to reset ds28e16!\n"); + ow_reset(); + return ERROR_NO_DEVICE; + } + + ds_dbg("Ready to write 0x33 to maxim IC!\n"); + write_byte(CMD_READ_ROM); + Delay_us(10); + for (i = 0; i < 8; i++) + RomID[i] = read_byte(); + + ds_dbg("RomID = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", RomID[0], + RomID[1], RomID[2], RomID[3], RomID[4], RomID[5], RomID[6], + RomID[7]); + + crc = crc_low_first(RomID, 7); + ds_dbg("crc_low_first = %02x\n", crc); + + if (crc == RomID[7]) { + memcpy(mi_romid, RomID, 8); + if (mi_romid[0] == FAMILY_CODE && + mi_romid[6] == CUSTOM_ID_MSB && + (mi_romid[5] & 0xF0) == CUSTOM_ID_LSB) + flag_mi_romid = 2; + return DS_TRUE; + } else { + ow_reset(); + ds_log("lvchen---Read_RomID33\n"); + return DS_FALSE; + } +} + +unsigned short docrc16(unsigned short data) +{ + data = (data ^ (CRC16 & 0xff)) & 0xff; + CRC16 >>= 8; + + if (oddparity[data & 0xf] ^ oddparity[data >> 4]) + CRC16 ^= 0xc001; + + data <<= 6; + CRC16 ^= data; + data <<= 1; + CRC16 ^= data; + + return CRC16; +} + +int DS28E16_standard_cmd_flow(unsigned char *write_buf, int delay_ms, + unsigned char *read_buf, int *read_len, + int write_len) +{ + unsigned char buf[128]; + int i; + int buf_len = 0; + int expected_read_len = *read_len; + + //NEW FLOW + /*'1 Wire + ''''''''''''''''''''''' + ? + ? + ?TX: Start Command + ?TX: Length Byte + ?TX: Memory Command + ?TX: Parameter, TX: Data + ?RX: CRC16 + ?TX: Release Byte + ? + ?RX: Dummy Byte + ?RX: Length Byte + ?RX: Result byte + ?RX: CRC16 + ?< wait for reset> + '''''''''''''''''''''''*/ + ds_dbg("DS28E16_standard_cmd_flow start\n"); + + if ((ow_reset()) != 0) { + ds_err("Failed to reset ds28e16!\n"); + ow_reset(); + return ERROR_NO_DEVICE; + } + + write_byte(CMD_SKIP_ROM); + + buf[buf_len++] = CMD_START; + memcpy(&buf[buf_len], write_buf, write_len); + buf_len += write_len; + for (i = 0; i < buf_len; i++) + write_byte(buf[i]); + + buf[buf_len++] = read_byte(); + buf[buf_len++] = read_byte(); + + CRC16 = 0; + for (i = 0; i < buf_len; i++) + docrc16(buf[i]); + + if (CRC16 != 0xB001) { + ow_reset(); + ds_dbg("DS28E16_standard_cmd_flow: crc error!\n"); + return DS_FALSE; + } + + // check for strong pull-up + if (delay_ms > 0) { + write_byte(CMD_RELEASE_BYTE); + Delay_us(1000 * delay_ms); + } + + read_byte(); + *read_len = read_byte(); + + if (expected_read_len != *read_len) { + ow_reset(); + ds_dbg("DS28E16_standard_cmd_flow: len error!\n"); + return DS_FALSE; + } + + buf_len = *read_len + 2; + for (i = 0; i < buf_len; i++) + buf[i] = read_byte(); + + CRC16 = 0; + docrc16(*read_len); + for (i = 0; i < buf_len; i++) + docrc16(buf[i]); + + if (CRC16 != 0xB001) { + ow_reset(); + ds_dbg("DS28E16_standard_cmd_flow: crc2 error!\n"); + return DS_FALSE; + } + + memcpy(read_buf, buf, *read_len); + ds_dbg("DS28E16_standard_cmd_flow success!\n"); + return DS_TRUE; +} + +//-------------------------------------------------------------------------- +/// 'Read Status' command +/// +/// @param[out] data +/// pointer to unsigned char (buffer of length 1) for page protection data +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_readStatus(unsigned char *data) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int len_byte = 1; + int read_len = 7; + + ds_dbg("lvchen--data = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + data[0], data[1], data[2], data[3], data[4], data[5], data[6], + data[7]); + ds_dbg("lvchen--mi_status = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + mi_status[0], mi_status[1], mi_status[2], mi_status[3], + mi_status[4], mi_status[5], mi_status[6], mi_status[7]); + if (flag_mi_status) { + memcpy(data, mi_status, 8); + ds_log("lvchen---DS28E16_cmd_readStatus00\n"); + return DS_TRUE; + } + + last_result_byte = RESULT_FAIL_NONE; + /* + ? + ?TX: Read Page Protection command + ?TX: Length (SMBus) [always 1] + ?TX: Parameter + ? + ? + ? + ?RX: Length (SMBus) [always 1] + ?RX: Protection Data + ? + */ + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_READ_STATUS; + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_READ * tm, + read_buf, &read_len, write_len)) { + if (read_buf[0] == RESULT_SUCCESS) { + last_result_byte = read_buf[0]; + memcpy(data, &read_buf[1], 8); + flag_mi_status = 1; + memcpy(mi_status, data, 8); + MANID[0] = data[4]; + ds_dbg("lvchen--data = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + data[0], data[1], data[2], data[3], data[4], + data[5], data[6], data[7]); + ds_dbg("lvchen--mi_status = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + mi_status[0], mi_status[1], mi_status[2], + mi_status[3], mi_status[4], mi_status[5], + mi_status[6], mi_status[7]); + ds_log("lvchen---DS28E16_cmd_readStatus11\n"); + return DS_TRUE; + } + } + + ow_reset(); + ds_log("lvchen---DS28E16_cmd_readStatus22\n"); + return DS_FALSE; +} + +//-------------------------------------------------------------------------- +/// 'Read Memory' command +/// +/// @param[in] pg +/// page number to read +/// @param[out] data +/// buffer length must be at least 32 bytes to hold memory read +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_readMemory(int pg, unsigned char *data) +{ + unsigned char write_buf[3]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 33; + int length_byte = 2; + unsigned char pagenum = (unsigned char)pg & 0x03; + + switch (pagenum) { + case 0x00: + if (flag_mi_page0_data) { + memcpy(data, mi_page0_data, 16); + return DS_TRUE; + } + break; + case 0x01: + if (flag_mi_page1_data) { + memcpy(data, mi_page1_data, 16); + return DS_TRUE; + } + break; + case 0x02: + if (flag_mi_counter) { + memcpy(data, mi_counter, 16); + return DS_TRUE; + } + break; + default: + return DS_FALSE; + } + + last_result_byte = RESULT_FAIL_NONE; + + /* + ? + ?TX: Read Memory Command + ?TX: Length (SMBus) + ?TX: Parameter + ? + ? + ? + ?RX: Length (SMBus) + ?RX: Result byte + ?RX: Data + ? + */ + + write_buf[write_len++] = length_byte; + write_buf[write_len++] = CMD_READ_MEM; + write_buf[write_len++] = pagenum; + + ds_dbg("DS28E16_cmd_readMemory write_buf:\n"); + ds_dbg("%02x %02x %02x", write_buf[0], write_buf[1], write_buf[2]); + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_READ * tm, + read_buf, &read_len, write_len)) { + if (read_len == 33) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) { + memcpy(data, &read_buf[1], 16); + if (pagenum == 0x00) { + flag_mi_page0_data = 1; + memcpy(mi_page0_data, data, 16); + } + if (pagenum == 0x01) { + flag_mi_page1_data = 1; + memcpy(mi_page1_data, data, 16); + } + return DS_TRUE; + } else { + if (read_buf[0] == 0x55 && pagenum == 2) { + memcpy(data, &read_buf[1], 16); + flag_mi_counter = 1; + memcpy(mi_counter, data, 16); + return DS_TRUE; + } + } + } + } + + ow_reset(); + return DS_FALSE; +} + +//-------------------------------------------------------------------------- +/// 'Write Memory' command +/// +/// @param[in] pg +/// page number to write +/// @param[in] data +/// buffer must be at least 32 bytes +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_writeMemory(int pg, unsigned char *data) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 1; + int len_byte = 18; + unsigned char pagenum = (unsigned char)pg & 0x03; + + last_result_byte = RESULT_FAIL_NONE; + /* + ? + ?TX: Write Memory Command + ?TX: Length (SMBus) [always 33] + ?TX: Parameter + ?TX: Data + ? + ? + ? + ?RX: Length (SMBus) [always 1] + ?RX: Result byte + ? + */ + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_WRITE_MEM; + write_buf[write_len++] = pagenum; + memcpy(&write_buf[write_len], data, 16); + write_len += 16; + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_WRITE * tm, + read_buf, &read_len, write_len)) { + if (read_len == 1) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) { + if (pagenum == 0x00) { + flag_mi_page0_data = 0; + memset(mi_page0_data, 0x00, 16); + } + if (pagenum == 0x01) { + flag_mi_page1_data = 0; + memset(mi_page0_data, 0x00, 16); + } + if (pagenum == 0x02) { + flag_mi_counter = 0; + memset(mi_counter, 0x00, 16); + } + return DS_TRUE; + } + } + } + + ow_reset(); + return DS_FALSE; +} + +//-------------------------------------------------------------------------- +/// 'Decrement Counter' command +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_decrementCounter(void) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 1; + + last_result_byte = RESULT_FAIL_NONE; + /* + ? + ?TX: Decrement Counter Command + ? + ? + ? + ?RX: Length (SMBus) [always 1] + ?RX: Result byte + ? + */ + + write_buf[write_len++] = 1; + write_buf[write_len++] = CMD_DECREMENT_CNT; + + if (DS28E16_standard_cmd_flow(write_buf, 50, read_buf, &read_len, + write_len)) { + if (read_len == 1) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) + return DS_TRUE; + } + } + + ow_reset(); + return DS_FALSE; +} + +//-------------------------------------------------------------------------- +/// 'Set Page Protection' command +/// +/// @param[in] pg +/// block to set protection +/// @param[in] prot +/// protection value to set +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_setPageProtection(int page, unsigned char prot) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 1; + int len_byte = 3; + + last_result_byte = RESULT_FAIL_NONE; + /* + ? + ?TX: Set Page Protection Command + ?TX: Length (SMBus) [always 2] + ?TX: Parameter + ?TX: Protection Data + ? + ? + ? + ?RX: Length (SMBus) [always 1] + ?RX: Result byte + ? + */ + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_SET_PAGE_PROT; + write_buf[write_len++] = page & 0x03; + write_buf[write_len++] = prot & 0x03; + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_WRITE * tm, + read_buf, &read_len, write_len)) { + if (read_len == 1) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) + return DS_TRUE; + } + } + + ow_reset(); + return DS_FALSE; +} + +int DS28E16_cmd_device_disable(int op, unsigned char *password) +{ + unsigned char write_buf[64]; + unsigned char read_buf[64]; + int write_len = 0; + int read_len = 1; + int length_byte = 10; + + last_result_byte = RESULT_FAIL_NONE; + /* + ? + ?TX: Length + ?TX: Device Disable Command + ?TX: Parameter + ? + ? + ? + ?RX: Length (SMBus) + ?RX: Result byte + ?RX: Data + ? + */ + + write_buf[write_len++] = length_byte; + write_buf[write_len++] = CMD_DISABLE_DEVICE; + write_buf[write_len++] = op & 0x0F; + memcpy(&write_buf[write_len], password, 8); + write_len += 8; + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_WRITE, + read_buf, &read_len, write_len)) { + if (read_len == 1) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) + return DS_TRUE; + } + } + + ow_reset(); + return DS_FALSE; +} + +// -------------------------------------------------------------------------- +/// 'Compute and Read Page Authentication' command +/// +/// @param[in] anon - boolean parameter +/// @param[in] pg - Page number 2,计数å™? 0,page0; 1,page1; +/// @param[in] challenge +/// @param[out] hmac 返回的计算结æž?2个字èŠ?/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_computeReadPageAuthentication(int anon, int pg, + unsigned char *challenge, + unsigned char *hmac) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 33; + int len_byte = 35; + + last_result_byte = RESULT_FAIL_NONE; + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_COMP_READ_AUTH; + write_buf[write_len] = pg & 0x03; + if (anon) + write_buf[write_len] = (write_buf[write_len] | 0xE0); + + write_len++; + write_buf[write_len++] = 0x02; // Fixed Parameter + memcpy(&write_buf[write_len], challenge, 32); // Challenge + write_len += 32; + + ds_dbg("computeReadPageAuthen:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + write_buf[0], write_buf[1], write_buf[2], write_buf[3], + write_buf[4], write_buf[5], write_buf[6], write_buf[7], + write_buf[8], write_buf[9], write_buf[10], write_buf[11], + write_buf[12], write_buf[13], write_buf[14], write_buf[15], + write_buf[16], write_buf[17], write_buf[18], write_buf[19], + write_buf[20], write_buf[21], write_buf[22], write_buf[23], + write_buf[24], write_buf[25], write_buf[26], write_buf[27], + write_buf[28], write_buf[29], write_buf[30], write_buf[31], + write_buf[32], write_buf[33], write_buf[34]); + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_WRITE, + read_buf, &read_len, write_len)) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) { + ds_dbg("hmac read_buf:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + read_buf[0], read_buf[1], read_buf[2], + read_buf[3], read_buf[4], read_buf[5], + read_buf[6], read_buf[7], read_buf[8], + read_buf[9], read_buf[10], read_buf[11], + read_buf[12], read_buf[13], read_buf[14], + read_buf[15], read_buf[16], read_buf[17], + read_buf[18], read_buf[19], read_buf[20], + read_buf[21], read_buf[22], read_buf[23], + read_buf[24], read_buf[25], read_buf[26], + read_buf[27], read_buf[28], read_buf[29], + read_buf[30], read_buf[31], read_buf[32]); + memcpy(hmac, &read_buf[1], 32); + ds_dbg("hmac:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + hmac[0], hmac[1], hmac[2], hmac[3], hmac[4], + hmac[5], hmac[6], hmac[7], hmac[8], hmac[9], + hmac[10], hmac[11], hmac[12], hmac[13], hmac[14], + hmac[15], hmac[16], hmac[17], hmac[18], hmac[19], + hmac[20], hmac[21], hmac[22], hmac[23], hmac[24], + hmac[25], hmac[26], hmac[27], hmac[28], hmac[29], + hmac[30], hmac[31]); + return DS_TRUE; + } + } + + ow_reset(); + return DS_FALSE; +} + +// -------------------------------------------------------------------------- +/// 'Compute Secret S' command +/// +/// @param[in] anon - boolean parameter +/// @param[in] bdconst - boolean parameter +/// @param[in] pg - Page number é¡µé¢ +/// @param[in] partial secret 32个字节的ç§å­ +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_computeS_Secret(int anon, int bdconst, int pg, + unsigned char *partial) +{ + unsigned char write_buf[40]; + unsigned char read_buf[40]; + int write_len = 0; + int read_len = 1; + int len_byte = 35; + int param = pg & 0x03; + + last_result_byte = RESULT_FAIL_NONE; + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_COMP_S_SECRET; + + if (bdconst) + param = param | 0x04; + if (anon) + param = param | 0xE0; + + write_buf[write_len] = param; + write_len++; + write_buf[write_len++] = 0x08; // Fixed Parameter + memcpy(&write_buf[write_len], partial, 32); // Partial Secret + write_len += 32; + + ds_dbg("computeS_Secret:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + write_buf[0], write_buf[1], write_buf[2], write_buf[3], + write_buf[4], write_buf[5], write_buf[6], write_buf[7], + write_buf[8], write_buf[9], write_buf[10], write_buf[11], + write_buf[12], write_buf[13], write_buf[14], write_buf[15], + write_buf[16], write_buf[17], write_buf[18], write_buf[19], + write_buf[20], write_buf[21], write_buf[22], write_buf[23], + write_buf[24], write_buf[25], write_buf[26], write_buf[27], + write_buf[28], write_buf[29], write_buf[30], write_buf[31], + write_buf[32], write_buf[33], write_buf[34]); + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_WRITE, + read_buf, &read_len, write_len)) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) + return DS_TRUE; + } + + ow_reset(); + return DS_FALSE; +} + +int AuthenticateDS28E16(int anon, int bdconst, int S_Secret_PageNum, + int PageNum, unsigned char *Challenge, + unsigned char *Secret_Seeds, unsigned char *S_Secret) +{ + unsigned char PageData[32], MAC_Read_Value[32], CAL_MAC[32]; + unsigned char status_chip[16]; + unsigned char MAC_Computer_Datainput[128]; + int i = 0; + int msg_len = 0; + unsigned char flag = DS_FALSE; + + //if (flag_mi_auth_result) + if (mi_auth_result == DS_TRUE) + return mi_auth_result; + + if (anon != ANONYMOUS) { + if (ds28el16_get_page_status_retry(status_chip) == DS_TRUE) { + MANID[0] = status_chip[4]; + } else { + ow_reset(); + return ERROR_R_STATUS; + } + + if (ds28el16_Read_RomID_retry(mi_romid) != DS_TRUE) { + ow_reset(); + return ERROR_R_ROMID; + } + } + + // DS28E16 calculate its session secret + flag = DS28E16_cmd_computeS_Secret_retry( + anon, bdconst, S_Secret_PageNum, Secret_Seeds); + if (flag == DS_FALSE) { + ds_err("DS28E16_cmd_computeS_Secret error"); + ow_reset(); + return ERROR_S_SECRET; + } + + // DS28E16 compute its MAC based on above sessio secret + flag = DS28E16_cmd_computeReadPageAuthentication_retry( + anon, PageNum, Challenge, MAC_Read_Value); + if (flag == DS_FALSE) { + ds_err("DS28E16_cmd_computeReadPageAuthentication error"); + ow_reset(); + return ERROR_COMPUTE_MAC; + } + + ds_dbg("%02x %02x %02x %02x", anon, bdconst, S_Secret_PageNum, PageNum); + + ds_dbg("Seeds:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + Secret_Seeds[0], Secret_Seeds[1], Secret_Seeds[2], + Secret_Seeds[3], Secret_Seeds[4], Secret_Seeds[5], + Secret_Seeds[6], Secret_Seeds[7], Secret_Seeds[8], + Secret_Seeds[9], Secret_Seeds[10], Secret_Seeds[11], + Secret_Seeds[12], Secret_Seeds[13], Secret_Seeds[14], + Secret_Seeds[15], Secret_Seeds[16], Secret_Seeds[17], + Secret_Seeds[18], Secret_Seeds[19], Secret_Seeds[20], + Secret_Seeds[21], Secret_Seeds[22], Secret_Seeds[23], + Secret_Seeds[24], Secret_Seeds[25], Secret_Seeds[26], + Secret_Seeds[27], Secret_Seeds[28], Secret_Seeds[29], + Secret_Seeds[30], Secret_Seeds[31]); + + ds_dbg("S_Secret:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + S_Secret[0], S_Secret[1], S_Secret[2], S_Secret[3], S_Secret[4], + S_Secret[5], S_Secret[6], S_Secret[7], S_Secret[8], S_Secret[9], + S_Secret[10], S_Secret[11], S_Secret[12], S_Secret[13], + S_Secret[14], S_Secret[15], S_Secret[16], S_Secret[17], + S_Secret[18], S_Secret[19], S_Secret[20], S_Secret[21], + S_Secret[22], S_Secret[23], S_Secret[24], S_Secret[25], + S_Secret[26], S_Secret[27], S_Secret[28], S_Secret[29], + S_Secret[30], S_Secret[31]); + + ds_dbg("Challenge:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + Challenge[0], Challenge[1], Challenge[2], Challenge[3], + Challenge[4], Challenge[5], Challenge[6], Challenge[7], + Challenge[8], Challenge[9], Challenge[10], Challenge[11], + Challenge[12], Challenge[13], Challenge[14], Challenge[15], + Challenge[16], Challenge[17], Challenge[18], Challenge[19], + Challenge[20], Challenge[21], Challenge[22], Challenge[23], + Challenge[24], Challenge[25], Challenge[26], Challenge[27], + Challenge[28], Challenge[29], Challenge[30], Challenge[31]); + + ds_dbg("MAC_Read_Value:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + MAC_Read_Value[0], MAC_Read_Value[1], MAC_Read_Value[2], + MAC_Read_Value[3], MAC_Read_Value[4], MAC_Read_Value[5], + MAC_Read_Value[6], MAC_Read_Value[7], MAC_Read_Value[8], + MAC_Read_Value[9], MAC_Read_Value[10], MAC_Read_Value[11], + MAC_Read_Value[12], MAC_Read_Value[13], MAC_Read_Value[14], + MAC_Read_Value[15], MAC_Read_Value[16], MAC_Read_Value[17], + MAC_Read_Value[18], MAC_Read_Value[19], MAC_Read_Value[20], + MAC_Read_Value[21], MAC_Read_Value[22], MAC_Read_Value[23], + MAC_Read_Value[24], MAC_Read_Value[25], MAC_Read_Value[26], + MAC_Read_Value[27], MAC_Read_Value[28], MAC_Read_Value[29], + MAC_Read_Value[30], MAC_Read_Value[31]); + + // read the page data + flag = ds28el16_get_page_data_retry(PageNum, PageData); + if (flag != DS_TRUE) { + ds_err("DS28E16_cmd_readMemory error"); + ow_reset(); + return ERROR_R_PAGEDATA; + } + + // insert mi_romid + if (anon != ANONYMOUS) + memcpy(MAC_Computer_Datainput, mi_romid, 8); + else + memset(MAC_Computer_Datainput, 0xff, 8); + msg_len += 8; + + // insert Page Data + memcpy(&MAC_Computer_Datainput[msg_len], PageData, 16); + msg_len += 16; + memset(&MAC_Computer_Datainput[msg_len], 0x00, 16); + msg_len += 16; + + // insert Challenge + memcpy(&MAC_Computer_Datainput[msg_len], Challenge, 32); + msg_len += 32; + + // insert Bind Data Page number + MAC_Computer_Datainput[msg_len] = PageNum & 0x03; + MAC_Computer_Datainput[msg_len] = MAC_Computer_Datainput[msg_len] & + 0x03; + msg_len += 1; + + // insert MANID + memcpy(&MAC_Computer_Datainput[msg_len], MANID, 2); + msg_len += 2; + + // calculate the MAC + sha3_256_hmac(S_Secret, 32, MAC_Computer_Datainput, msg_len, CAL_MAC); + + ds_dbg("host data:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + MAC_Computer_Datainput[0], MAC_Computer_Datainput[1], + MAC_Computer_Datainput[2], MAC_Computer_Datainput[3], + MAC_Computer_Datainput[4], MAC_Computer_Datainput[5], + MAC_Computer_Datainput[6], MAC_Computer_Datainput[7], + MAC_Computer_Datainput[8], MAC_Computer_Datainput[9], + MAC_Computer_Datainput[10], MAC_Computer_Datainput[11], + MAC_Computer_Datainput[12], MAC_Computer_Datainput[13], + MAC_Computer_Datainput[14], MAC_Computer_Datainput[15], + MAC_Computer_Datainput[16], MAC_Computer_Datainput[17], + MAC_Computer_Datainput[18], MAC_Computer_Datainput[19], + MAC_Computer_Datainput[20], MAC_Computer_Datainput[21], + MAC_Computer_Datainput[22], MAC_Computer_Datainput[23], + MAC_Computer_Datainput[24], MAC_Computer_Datainput[25], + MAC_Computer_Datainput[26], MAC_Computer_Datainput[27], + MAC_Computer_Datainput[28], MAC_Computer_Datainput[29], + MAC_Computer_Datainput[30], MAC_Computer_Datainput[31], + MAC_Computer_Datainput[32], MAC_Computer_Datainput[33], + MAC_Computer_Datainput[34], MAC_Computer_Datainput[35], + MAC_Computer_Datainput[36], MAC_Computer_Datainput[37], + MAC_Computer_Datainput[38], MAC_Computer_Datainput[39], + MAC_Computer_Datainput[40], MAC_Computer_Datainput[41], + MAC_Computer_Datainput[42], MAC_Computer_Datainput[43], + MAC_Computer_Datainput[44], MAC_Computer_Datainput[45], + MAC_Computer_Datainput[46], MAC_Computer_Datainput[47], + MAC_Computer_Datainput[48], MAC_Computer_Datainput[49], + MAC_Computer_Datainput[50], MAC_Computer_Datainput[51], + MAC_Computer_Datainput[52], MAC_Computer_Datainput[53], + MAC_Computer_Datainput[54], MAC_Computer_Datainput[55], + MAC_Computer_Datainput[56], MAC_Computer_Datainput[57], + MAC_Computer_Datainput[58], MAC_Computer_Datainput[59], + MAC_Computer_Datainput[60], MAC_Computer_Datainput[61], + MAC_Computer_Datainput[62], MAC_Computer_Datainput[63], + MAC_Computer_Datainput[64], MAC_Computer_Datainput[65], + MAC_Computer_Datainput[66], MAC_Computer_Datainput[67], + MAC_Computer_Datainput[68], MAC_Computer_Datainput[69], + MAC_Computer_Datainput[70], MAC_Computer_Datainput[71], + MAC_Computer_Datainput[72], MAC_Computer_Datainput[73], + MAC_Computer_Datainput[74], MAC_Computer_Datainput[75], + MAC_Computer_Datainput[76], MAC_Computer_Datainput[77], + MAC_Computer_Datainput[78], MAC_Computer_Datainput[79]); + + ds_dbg("host mac:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + CAL_MAC[0], CAL_MAC[1], CAL_MAC[2], CAL_MAC[3], CAL_MAC[4], + CAL_MAC[5], CAL_MAC[6], CAL_MAC[7], CAL_MAC[8], CAL_MAC[9], + CAL_MAC[10], CAL_MAC[11], CAL_MAC[12], CAL_MAC[13], CAL_MAC[14], + CAL_MAC[15], CAL_MAC[16], CAL_MAC[17], CAL_MAC[18], CAL_MAC[19], + CAL_MAC[20], CAL_MAC[21], CAL_MAC[22], CAL_MAC[23], CAL_MAC[24], + CAL_MAC[25], CAL_MAC[26], CAL_MAC[27], CAL_MAC[28], CAL_MAC[29], + CAL_MAC[30], CAL_MAC[31]); + + for (i = 0; i < 32; i++) { + if (CAL_MAC[i] != MAC_Read_Value[i]) + break; + } + + if (i != 32) { + flag_mi_auth_result = 1; + mi_auth_result = ERROR_UNMATCH_MAC; + // for debug + ds_dbg("hmac is not match. result=ERROR_UNMATCH_MAC\n"); + flag_mi_page1_data = 0; + return ERROR_UNMATCH_MAC; + } else { + flag_mi_auth_result = 1; + ds_dbg("hmac is match. result=DS_TRUE\n"); + mi_auth_result = DS_TRUE; + return DS_TRUE; + } +} + +// retry interface start // +static int ds28el16_Read_RomID_retry(unsigned char *RomID) +{ + int i; + unsigned char data[50]; + + for (i = 0; i < GET_ROM_ID_RETRY; i++) { + ds_info("read rom id communication start %d...\n", i); + if (DS28E16_cmd_readStatus(data) == DS_TRUE) { + if (Read_RomID(RomID) == DS_TRUE) + return DS_TRUE; + } + } + ds_log("ds28el16_Read_RomID_retry fail\n"); + return DS_FALSE; +} + +static int ds28el16_get_page_status_retry(unsigned char *data) +{ + int i; + + for (i = 0; i < GET_BLOCK_STATUS_RETRY; i++) { + ds_info("read page status communication start... %d\n", i); + + if (DS28E16_cmd_readStatus(data) == DS_TRUE) + return DS_TRUE; + } + + return DS_FALSE; +} + +/* +static int ds28el16_set_page_status_retry(unsigned char page, unsigned char status) +{ + int i; + + for (i = 0; i < SET_BLOCK_STATUS_RETRY; i++) { + ds_info("set page status communication start... %d\n", i); + + if (DS28E16_cmd_setPageProtection(page, status) == TRUE) + return DS_TRUE; + } + + return DS_FALSE; +} +*/ + +static int ds28el16_get_page_data_retry(int page, unsigned char *data) +{ + int i; + + if (page >= MAX_PAGENUM) + return DS_FALSE; + + for (i = 0; i < GET_USER_MEMORY_RETRY; i++) { + ds_dbg("read page data communication start... %d\n", i); + + if (DS28E16_cmd_readMemory(page, data) == DS_TRUE) { + ds_dbg("page number is %d\n", page); + ds_dbg("page data:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + data[0], data[1], data[2], data[3], data[4], + data[5], data[6], data[7], data[8], data[9], + data[10], data[11], data[12], data[13], data[14], + data[15]); + ds_dbg("flag_mi_page0_data is %d\n", + flag_mi_page0_data); + ds_dbg("mi_page0_data data:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + mi_page0_data[0], mi_page0_data[1], + mi_page0_data[2], mi_page0_data[3], + mi_page0_data[4], mi_page0_data[5], + mi_page0_data[6], mi_page0_data[7], + mi_page0_data[8], mi_page0_data[9], + mi_page0_data[10], mi_page0_data[11], + mi_page0_data[12], mi_page0_data[13], + mi_page0_data[14], mi_page0_data[15]); + ds_dbg("flag_mi_page1_data is %d\n", + flag_mi_page1_data); + ds_dbg("mi_page1_data data:\n"); + ds_dbg("%%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + mi_page1_data[0], mi_page1_data[1], + mi_page1_data[2], mi_page1_data[3], + mi_page1_data[4], mi_page1_data[5], + mi_page1_data[6], mi_page1_data[7], + mi_page1_data[8], mi_page1_data[9], + mi_page1_data[10], mi_page1_data[11], + mi_page1_data[12], mi_page1_data[13], + mi_page1_data[14], mi_page1_data[15]); + ds_dbg("flag_mi_counter is %d\n", flag_mi_counter); + return DS_TRUE; + } + } + + return DS_FALSE; +} + +static int DS28E16_cmd_computeS_Secret_retry(int anon, int bdconst, int pg, + unsigned char *partial) +{ + int i; + + if (pg >= MAX_PAGENUM) + return DS_FALSE; + + for (i = 0; i < GET_S_SECRET_RETRY; i++) { + if (DS28E16_cmd_computeS_Secret(anon, bdconst, pg, partial) == + DS_TRUE) + return DS_TRUE; + } + + return DS_FALSE; +} + +static int DS28E16_cmd_computeReadPageAuthentication_retry( + int anon, int pg, unsigned char *challenge, unsigned char *hmac) +{ + int i; + + if (pg >= MAX_PAGENUM) + return DS_FALSE; + + for (i = 0; i < GET_MAC_RETRY; i++) { + if (DS28E16_cmd_computeReadPageAuthentication( + anon, pg, challenge, hmac) == DS_TRUE) + return DS_TRUE; + } + + return DS_FALSE; +} + +// retry interface end // + +/* All power supply functions here */ + +static enum power_supply_property verify_props[] = { + POWER_SUPPLY_PROP_ROMID, + POWER_SUPPLY_PROP_DS_STATUS, + POWER_SUPPLY_PROP_PAGENUMBER, + POWER_SUPPLY_PROP_PAGEDATA, + POWER_SUPPLY_PROP_AUTHEN_RESULT, + POWER_SUPPLY_PROP_SESSION_SEED, + POWER_SUPPLY_PROP_S_SECRET, + POWER_SUPPLY_PROP_CHALLENGE, + POWER_SUPPLY_PROP_AUTH_ANON, + POWER_SUPPLY_PROP_AUTH_BDCONST, + POWER_SUPPLY_PROP_PAGE0_DATA, + POWER_SUPPLY_PROP_PAGE1_DATA, + POWER_SUPPLY_PROP_VERIFY_MODEL_NAME, + POWER_SUPPLY_PROP_CHIP_OK, +}; + +static int verify_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret; + unsigned char buf[50]; + + switch (psp) { + case POWER_SUPPLY_PROP_VERIFY_MODEL_NAME: + ret = ds28el16_Read_RomID_retry(mi_romid); + if (ret == DS_TRUE) + val->strval = "ds28e16"; + else + val->strval = "unknown"; + break; + case POWER_SUPPLY_PROP_AUTHEN_RESULT: + ret = AuthenticateDS28E16(auth_ANON, auth_BDCONST, 0, + pagenumber, challenge, session_seed, + S_secret); + if (ret == DS_TRUE) + val->intval = true; + else + val->intval = false; + break; + case POWER_SUPPLY_PROP_PAGENUMBER: + val->intval = pagenumber; + break; + case POWER_SUPPLY_PROP_ROMID: + ret = ds28el16_Read_RomID_retry(mi_romid); + memcpy(val->arrayval, mi_romid, 8); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_CHIP_OK: + ds_log("lvchen---POWER_SUPPLY_PROP_CHIP_OK\n"); + ret = ds28el16_Read_RomID_retry(mi_romid); + if ((mi_romid[0] == FAMILY_CODE) && + (mi_romid[6] == CUSTOM_ID_MSB) && + ((mi_romid[5] & 0xf0) == CUSTOM_ID_LSB)) + val->intval = true; + else + val->intval = false; + ds_log("lvchen---flag_mi_romid: %d, flag_mi_status: %d\n", + flag_mi_romid, flag_mi_status); + break; + case POWER_SUPPLY_PROP_DS_STATUS: + ret = ds28el16_get_page_status_retry(buf); + memcpy(val->arrayval, buf, 8); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_PAGEDATA: + ret = ds28el16_get_page_data_retry(pagenumber, buf); + memcpy(val->arrayval, buf, 16); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_PAGE0_DATA: + ret = ds28el16_get_page_data_retry(0, buf); + memcpy(val->arrayval, buf, 16); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_PAGE1_DATA: + ret = ds28el16_get_page_data_retry(1, buf); + memcpy(val->arrayval, buf, 16); + if (ret != DS_TRUE) + return -EAGAIN; + break; + default: + ds_err("unsupported property %d\n", psp); + return -ENODATA; + } + + return 0; +} + +static int verify_set_property(struct power_supply *psy, + enum power_supply_property prop, + const union power_supply_propval *val) +{ + //int ret; + //unsigned char buf[50]; + + switch (prop) { + case POWER_SUPPLY_PROP_PAGENUMBER: + pagenumber = val->intval; + break; + /* + case POWER_SUPPLY_PROP_PAGEDATA: + memcpy(buf, val->arrayval, 16); + ret = DS28E16_cmd_writeMemory(pagenumber, buf); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_SESSION_SEED: + memcpy(session_seed, val->arrayval, 32); + break; + case POWER_SUPPLY_PROP_S_SECRET: + memcpy(S_secret, val->arrayval, 32); + break; + case POWER_SUPPLY_PROP_CHALLENGE: + memcpy(challenge, val->arrayval, 32); + break; +*/ + case POWER_SUPPLY_PROP_AUTH_ANON: + auth_ANON = val->intval; + break; + case POWER_SUPPLY_PROP_AUTH_BDCONST: + auth_BDCONST = val->intval; + break; + default: + ds_err("unsupported property %d\n", prop); + return -ENODATA; + } + + return 0; +} + +static int verify_prop_is_writeable(struct power_supply *psy, + enum power_supply_property prop) +{ + int ret; + + switch (prop) { + case POWER_SUPPLY_PROP_PAGENUMBER: + case POWER_SUPPLY_PROP_PAGEDATA: + case POWER_SUPPLY_PROP_SESSION_SEED: + case POWER_SUPPLY_PROP_S_SECRET: + case POWER_SUPPLY_PROP_CHALLENGE: + case POWER_SUPPLY_PROP_AUTH_ANON: + case POWER_SUPPLY_PROP_AUTH_BDCONST: + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +static int verify_psy_register(struct ds28e16_data *ds) +{ + struct power_supply_config verify_psy_cfg = {}; + + ds->verify_psy_d.name = "batt_verify"; + ds->verify_psy_d.type = POWER_SUPPLY_TYPE_BATT_VERIFY; + ds->verify_psy_d.properties = verify_props; + ds->verify_psy_d.num_properties = ARRAY_SIZE(verify_props); + ds->verify_psy_d.get_property = verify_get_property; + ds->verify_psy_d.set_property = verify_set_property; + ds->verify_psy_d.property_is_writeable = verify_prop_is_writeable; + + verify_psy_cfg.drv_data = ds; + verify_psy_cfg.of_node = ds->dev->of_node; + verify_psy_cfg.num_supplicants = 0; + ds->verify_psy = devm_power_supply_register(ds->dev, &ds->verify_psy_d, + &verify_psy_cfg); + if (IS_ERR(ds->verify_psy)) { + ds_err("Failed to register verify_psy"); + return PTR_ERR(ds->verify_psy); + } + + ds_log("%s power supply register successfully\n", + ds->verify_psy_d.name); + return 0; +} + +static void verify_psy_unregister(struct ds28e16_data *ds) +{ + power_supply_unregister(ds->verify_psy); +} + +// parse dts +static int ds28e16_parse_dt(struct device *dev, struct ds28e16_data *pdata) +{ + int error, val; + struct device_node *np = dev->of_node; + + // parse version + pdata->version = 0; + error = of_property_read_u32(np, "maxim,version", &val); + if (error && (error != -EINVAL)) + ds_err("Unable to read bootloader address\n"); + else if (error != -EINVAL) + pdata->version = val; + + return 0; +} + +// read data from file +static ssize_t ds28e16_ds_Auth_Result_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int result; + + result = AuthenticateDS28E16(auth_ANON, auth_BDCONST, 0, pagenumber, + challenge, session_seed, S_secret); + if (result == ERROR_R_STATUS) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : ERROR_R_STATUS!\n"); + else if (result == ERROR_UNMATCH_MAC) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : MAC is not match!\n"); + else if (result == ERROR_R_ROMID) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : ERROR_R_ROMID!\n"); + else if (result == ERROR_COMPUTE_MAC) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : ERROR_COMPUTE_MAC!\n"); + else if (result == ERROR_S_SECRET) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : ERROR_S_SECRET!\n"); + else if (result == DS_TRUE) + return scnprintf(buf, PAGE_SIZE, "Authenticate success!!!\n"); + else + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : other reason.\n"); +} + +static ssize_t ds28e16_ds_romid_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + short status; + unsigned char RomID[10] = { 0x00 }; + int i = 0; + int count = 0; + + for (i = 0; i < attr_trytimes; i++) { + status = ds28el16_Read_RomID_retry(RomID); + + if (status == DS_TRUE) { + count++; + ds_log("Read_RomID success!\n"); + } else { + ds_log("Read_RomID fail!\n"); + } + ds_dbg("RomID = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + RomID[0], RomID[1], RomID[2], RomID[3], RomID[4], + RomID[5], RomID[6], RomID[7]); + Delay_us(1000); + } + + /*ds_dbg("RomID = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + RomID[0], RomID[1], RomID[2], RomID[3], + RomID[4], RomID[5], RomID[6], RomID[7]); + */ + ds_log("test done\nsuccess time : %d\n", count); + return scnprintf( + buf, PAGE_SIZE, + "Success = %d\nRomID = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + count, RomID[0], RomID[1], RomID[2], RomID[3], RomID[4], + RomID[5], RomID[6], RomID[7]); +} + +static ssize_t ds28e16_ds_pagenumber_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%02x\n", pagenumber); +} + +static ssize_t ds28e16_ds_pagenumber_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int buf_int; + + if (sscanf(buf, "%d", &buf_int) != 1) + return -EINVAL; + + ds_dbg("new pagenumber = %d\n", buf_int); + + if ((buf_int >= 0) && (buf_int <= 3)) + pagenumber = buf_int; + + return count; +} + +static ssize_t ds28e16_ds_pagedata_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int result; + unsigned char pagedata[16] = { 0x00 }; + int i = 0; + int count = 0; + + for (i = 0; i < attr_trytimes; i++) { + result = ds28el16_get_page_data_retry(pagenumber, pagedata); + + if (result == DS_TRUE) { + count++; + ds_log("DS28E16_cmd_readMemory success!\n"); + } else { + ds_log("DS28E16_cmd_readMemory fail!\n"); + } + ds_dbg("pagedata = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + pagedata[0], pagedata[1], pagedata[2], pagedata[3], + pagedata[4], pagedata[5], pagedata[6], pagedata[7], + pagedata[8], pagedata[9], pagedata[10], pagedata[11], + pagedata[12], pagedata[13], pagedata[14], pagedata[15]); + Delay_us(1000); + } + ds_log("test done\nsuccess time : %d\n", count); + return scnprintf( + buf, PAGE_SIZE, + "Success = %d\npagedata = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + count, pagedata[0], pagedata[1], pagedata[2], pagedata[3], + pagedata[4], pagedata[5], pagedata[6], pagedata[7], pagedata[8], + pagedata[9], pagedata[10], pagedata[11], pagedata[12], + pagedata[13], pagedata[14], pagedata[15]); +} + +static ssize_t ds28e16_ds_pagedata_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int result; + unsigned char pagedata[16] = { 0x00 }; + + if (sscanf(buf, + "%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx", + &pagedata[0], &pagedata[1], &pagedata[2], &pagedata[3], + &pagedata[4], &pagedata[5], &pagedata[6], &pagedata[7], + &pagedata[8], &pagedata[9], &pagedata[10], &pagedata[11], + &pagedata[12], &pagedata[13], &pagedata[14], + &pagedata[15]) != 16) + return -EINVAL; + + ds_dbg("new data = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + pagedata[0], pagedata[1], pagedata[2], pagedata[3], pagedata[4], + pagedata[5], pagedata[6], pagedata[7], pagedata[8], pagedata[9], + pagedata[10], pagedata[11], pagedata[12], pagedata[13], + pagedata[14], pagedata[15]); + + result = DS28E16_cmd_writeMemory(pagenumber, pagedata); + if (result == DS_TRUE) + ds_log("DS28E16_cmd_writeMemory success!\n"); + else + ds_log("DS28E16_cmd_writeMemory fail!\n"); + + return count; +} + +static ssize_t ds28e16_ds_time_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d\n", attr_trytimes); +} + +static ssize_t ds28e16_ds_time_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int buf_int; + + if (sscanf(buf, "%d", &buf_int) != 1) + return -EINVAL; + + ds_log("new trytimes = %d\n", buf_int); + + if (buf_int > 0) + attr_trytimes = buf_int; + + return count; +} + +static ssize_t +ds28e16_ds_session_seed_status_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, + "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n", + session_seed[0], session_seed[1], session_seed[2], + session_seed[3], session_seed[4], session_seed[5], + session_seed[6], session_seed[7], session_seed[8], + session_seed[9], session_seed[10], session_seed[11], + session_seed[12], session_seed[13], session_seed[14], + session_seed[15], session_seed[16], session_seed[17], + session_seed[18], session_seed[19], session_seed[20], + session_seed[21], session_seed[22], session_seed[23], + session_seed[24], session_seed[25], session_seed[26], + session_seed[27], session_seed[28], session_seed[29], + session_seed[30], session_seed[31]); +} + +static ssize_t ds28e16_ds_session_seed_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, + "%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx", + &session_seed[0], &session_seed[1], &session_seed[2], + &session_seed[3], &session_seed[4], &session_seed[5], + &session_seed[6], &session_seed[7], &session_seed[8], + &session_seed[9], &session_seed[10], &session_seed[11], + &session_seed[12], &session_seed[13], &session_seed[14], + &session_seed[15], &session_seed[16], &session_seed[17], + &session_seed[18], &session_seed[19], &session_seed[20], + &session_seed[21], &session_seed[22], &session_seed[23], + &session_seed[24], &session_seed[25], &session_seed[26], + &session_seed[27], &session_seed[28], &session_seed[29], + &session_seed[30], &session_seed[31]) != 32) + return -EINVAL; + + return count; +} + +static ssize_t ds28e16_ds_challenge_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, + "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n", + challenge[0], challenge[1], challenge[2], challenge[3], + challenge[4], challenge[5], challenge[6], challenge[7], + challenge[8], challenge[9], challenge[10], challenge[11], + challenge[12], challenge[13], challenge[14], challenge[15], + challenge[16], challenge[17], challenge[18], challenge[19], + challenge[20], challenge[21], challenge[22], challenge[23], + challenge[24], challenge[25], challenge[26], challenge[27], + challenge[28], challenge[29], challenge[30], challenge[31]); +} + +static ssize_t ds28e16_ds_challenge_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, + "%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx", + &challenge[0], &challenge[1], &challenge[2], &challenge[3], + &challenge[4], &challenge[5], &challenge[6], &challenge[7], + &challenge[8], &challenge[9], &challenge[10], &challenge[11], + &challenge[12], &challenge[13], &challenge[14], + &challenge[15], &challenge[16], &challenge[17], + &challenge[18], &challenge[19], &challenge[20], + &challenge[21], &challenge[22], &challenge[23], + &challenge[24], &challenge[25], &challenge[26], + &challenge[27], &challenge[28], &challenge[29], + &challenge[30], &challenge[31]) != 32) + return -EINVAL; + + return count; +} + +static ssize_t ds28e16_ds_S_secret_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, + "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n", + S_secret[0], S_secret[1], S_secret[2], S_secret[3], S_secret[4], + S_secret[5], S_secret[6], S_secret[7], S_secret[8], S_secret[9], + S_secret[10], S_secret[11], S_secret[12], S_secret[13], + S_secret[14], S_secret[15], S_secret[16], S_secret[17], + S_secret[18], S_secret[19], S_secret[20], S_secret[21], + S_secret[22], S_secret[23], S_secret[24], S_secret[25], + S_secret[26], S_secret[27], S_secret[28], S_secret[29], + S_secret[30], S_secret[31]); +} + +static ssize_t ds28e16_ds_S_secret_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, + "%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx", + &S_secret[0], &S_secret[1], &S_secret[2], &S_secret[3], + &S_secret[4], &S_secret[5], &S_secret[6], &S_secret[7], + &S_secret[8], &S_secret[9], &S_secret[10], &S_secret[11], + &S_secret[12], &S_secret[13], &S_secret[14], &S_secret[15], + &S_secret[16], &S_secret[17], &S_secret[18], &S_secret[19], + &S_secret[20], &S_secret[21], &S_secret[22], &S_secret[23], + &S_secret[24], &S_secret[25], &S_secret[26], &S_secret[27], + &S_secret[28], &S_secret[29], &S_secret[30], + &S_secret[31]) != 32) + return -EINVAL; + + return count; +} + +static ssize_t ds28e16_ds_auth_ANON_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%02x\n", auth_ANON); +} + +static ssize_t ds28e16_ds_auth_ANON_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, "%d", &auth_ANON) != 1) + return -EINVAL; + + return count; +} + +static ssize_t +ds28e16_ds_auth_BDCONST_status_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%02x\n", auth_BDCONST); +} + +static ssize_t ds28e16_ds_auth_BDCONST_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, "%d", &auth_BDCONST) != 1) + return -EINVAL; + + return count; +} + +static ssize_t ds28e16_ds_readstatus_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int result; + unsigned char status[16] = { 0x00 }; + int i = 0; + int count = 0; + + for (i = 0; i < attr_trytimes; i++) { + result = ds28el16_get_page_status_retry(status); + + if (result == DS_TRUE) { + count++; + ds_log("DS28E16_cmd_readStatus success!\n"); + } else { + ds_log("DS28E16_cmd_readStatus fail!\n"); + } + ds_dbg("Status = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + status[0], status[1], status[2], status[3], status[4], + status[5], status[6], status[7], status[8], status[9], + status[10], status[11], status[12], status[13], + status[14], status[15]); + Delay_us(1000); + } + ds_log("test done\nsuccess time : %d\n", count); + return scnprintf( + buf, PAGE_SIZE, + "Success = %d\nStatus = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + count, status[0], status[1], status[2], status[3], status[4], + status[5], status[6], status[7], status[8], status[9], + status[10], status[11], status[12], status[13], status[14], + status[15]); +} + +static DEVICE_ATTR(ds_readstatus, S_IRUGO, ds28e16_ds_readstatus_status_read, + NULL); +static DEVICE_ATTR(ds_romid, S_IRUGO, ds28e16_ds_romid_status_read, NULL); +static DEVICE_ATTR(ds_pagenumber, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_pagenumber_status_read, + ds28e16_ds_pagenumber_store); +static DEVICE_ATTR(ds_pagedata, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_pagedata_status_read, ds28e16_ds_pagedata_store); +static DEVICE_ATTR(ds_time, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_time_status_read, ds28e16_ds_time_store); +static DEVICE_ATTR(ds_session_seed, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_session_seed_status_read, + ds28e16_ds_session_seed_store); +static DEVICE_ATTR(ds_challenge, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_challenge_status_read, + ds28e16_ds_challenge_store); +static DEVICE_ATTR(ds_S_secret, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_S_secret_status_read, ds28e16_ds_S_secret_store); +static DEVICE_ATTR(ds_auth_ANON, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_auth_ANON_status_read, + ds28e16_ds_auth_ANON_store); +static DEVICE_ATTR(ds_auth_BDCONST, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_auth_BDCONST_status_read, + ds28e16_ds_auth_BDCONST_store); +static DEVICE_ATTR(ds_Auth_Result, S_IRUGO, ds28e16_ds_Auth_Result_status_read, + NULL); + +static struct attribute *ds_attributes[] = { + &dev_attr_ds_readstatus.attr, &dev_attr_ds_romid.attr, + &dev_attr_ds_pagenumber.attr, &dev_attr_ds_pagedata.attr, + &dev_attr_ds_time.attr, &dev_attr_ds_session_seed.attr, + &dev_attr_ds_challenge.attr, &dev_attr_ds_S_secret.attr, + &dev_attr_ds_auth_ANON.attr, &dev_attr_ds_auth_BDCONST.attr, + &dev_attr_ds_Auth_Result.attr, NULL, +}; + +static const struct attribute_group ds_attr_group = { + .attrs = ds_attributes, +}; + +static int authentic_period_ms = 5000; +#define AUTHENTIC_COUNT_MAX 5 +int retry_authentic; +static void authentic_work(struct work_struct *work) +{ + int rc; + union power_supply_propval pval = { + 0, + }; + + struct ds28e16_data *ds28e16_data = + container_of(work, struct ds28e16_data, authentic_work.work); + + rc = power_supply_get_property(ds28e16_data->verify_psy, + POWER_SUPPLY_PROP_AUTHEN_RESULT, &pval); + if (pval.intval != true) { + retry_authentic++; + if (retry_authentic < AUTHENTIC_COUNT_MAX) { + ds_log("battery authentic work begin to restart, retry = %d\n", + retry_authentic); + schedule_delayed_work( + &ds28e16_data->authentic_work, + msecs_to_jiffies(authentic_period_ms)); + } + + if (retry_authentic == AUTHENTIC_COUNT_MAX) { + ds_log("authentic result is %d\n", pval.intval); + } + } else { + ds_log("authentic result is %d\n", pval.intval); + } +} + +static int ds28e16_probe(struct platform_device *pdev) +{ + int retval = 0; + struct ds28e16_data *ds28e16_data; + union power_supply_propval b_val = { + 0, + }; + + ds_log("%s entry.", __func__); + ds_dbg("platform_device is %s", pdev->name); + if (strcmp(pdev->name, "soc:maxim_ds28e16") != 0) + return -ENODEV; + + if (!pdev->dev.of_node || !of_device_is_available(pdev->dev.of_node)) + return -ENODEV; + + if (pdev->dev.of_node) { + ds28e16_data = devm_kzalloc( + &pdev->dev, sizeof(struct ds28e16_data), GFP_KERNEL); + if (!ds28e16_data) { + ds_err("Failed to allocate memory\n"); + return -ENOMEM; + } + + retval = ds28e16_parse_dt(&pdev->dev, ds28e16_data); + if (retval) { + retval = -EINVAL; + goto ds28e16_parse_dt_err; + } + } else { + ds28e16_data = pdev->dev.platform_data; + } + + if (!ds28e16_data) { + ds_err("No platform data found\n"); + return -EINVAL; + } + + ds28e16_data->dev = &pdev->dev; + ds28e16_data->pdev = pdev; + platform_set_drvdata(pdev, ds28e16_data); + INIT_DELAYED_WORK(&ds28e16_data->authentic_work, authentic_work); + + retval = verify_psy_register(ds28e16_data); + if (retval) { + ds_err("Failed to verify_psy_register, err:%d\n", retval); + goto ds28e16_psy_register_err; + } + + retval = sysfs_create_group(&ds28e16_data->dev->kobj, &ds_attr_group); + if (retval) { + ds_err("Failed to register sysfs, err:%d\n", retval); + goto ds28e16_create_group_err; + } + + retval = power_supply_get_property(ds28e16_data->verify_psy, + POWER_SUPPLY_PROP_AUTHEN_RESULT, + &b_val); + if (b_val.intval != true) { + schedule_delayed_work(&ds28e16_data->authentic_work, + msecs_to_jiffies(0)); + } + return 0; + +ds28e16_create_group_err: +//sysfs_remove_groups(&ds28e16_data->dev->kobj, &(&ds_attr_group)); +ds28e16_psy_register_err: + dev_set_drvdata(ds28e16_data->dev, NULL); +ds28e16_parse_dt_err: + kfree(ds28e16_data); + return retval; +} + +static int ds28e16_remove(struct platform_device *pdev) +{ + struct ds28e16_data *ds28e16_data = platform_get_drvdata(pdev); + + verify_psy_unregister(ds28e16_data); + kfree(ds28e16_data); + return 0; +} + +static long ds28e16_dev_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + ds_log("%d, cmd: 0x%x\n", __LINE__, cmd); + return 0; +} +static int ds28e16_dev_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int ds28e16_dev_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations ds28e16_dev_fops = { + .owner = THIS_MODULE, + .open = ds28e16_dev_open, + .unlocked_ioctl = ds28e16_dev_ioctl, + .release = ds28e16_dev_release, +}; + +static const struct of_device_id ds28e16_dt_match[] = { + { .compatible = "maxim,ds28e16" }, + {}, +}; + +static struct platform_driver ds28e16_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "maxim_ds28e16", + .of_match_table = ds28e16_dt_match, + }, + .probe = ds28e16_probe, + .remove = ds28e16_remove, +}; + +static int __init ds28e16_init(void) +{ + ds_log("%s entry.", __func__); + + return platform_driver_register(&ds28e16_driver); +} + +static void __exit ds28e16_exit(void) +{ + ds_log("%s entry.", __func__); + platform_driver_unregister(&ds28e16_driver); +} + +module_init(ds28e16_init); +module_exit(ds28e16_exit); + +MODULE_AUTHOR("xiaomi Inc."); +MODULE_DESCRIPTION("ds28e16 driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/power/supply/maxim/ds28e16.h b/drivers/power/supply/maxim/ds28e16.h new file mode 100644 index 000000000000..a812b4675969 --- /dev/null +++ b/drivers/power/supply/maxim/ds28e16.h @@ -0,0 +1,133 @@ +// DS28E16.h - Include file for DS28E16/DS28E50? +// +#ifndef __DS28E16_H__ +#define __DS28E16_H__ + +#define ERROR_NO_DEVICE -1 +#define ERROR_R_STATUS -2 +#define ERROR_R_ROMID -3 +#define ERROR_R_PAGEDATA -4 +#define ERROR_COMPUTE_MAC -5 +#define ERROR_S_SECRET -6 +#define ERROR_UNMATCH_MAC -7 +#define DS_TRUE 1 +#define DS_FALSE 0 + +#define CMD_RELEASE_BYTE 0xAA +// 1-wire ROM commands +#define CMD_SEARCH_ROM 0xF0 +#define CMD_READ_ROM 0x33 +#define CMD_MATCH_ROM 0x55 +#define CMD_SKIP_ROM 0xCC +#define CMD_RESUME_ROM 0xA5 + +// DS28E16 commands +#define CMD_START 0x66 +#define CMD_WRITE_MEM 0x96 +#define CMD_READ_MEM 0x44 +#define CMD_READ_STATUS 0xAA +#define CMD_SET_PAGE_PROT 0xC3 +#define CMD_COMP_READ_AUTH 0xA5 +#define CMD_COMP_S_SECRET 0x3C +#define CMD_DECREMENT_CNT 0xC9 +#define CMD_DISABLE_DEVICE 0x33 + +#define CMD_READ_RNG 0xD2 + +// Result bytes +#define RESULT_SUCCESS 0xAA +#define RESULT_FAIL_PROTECTION 0x55 +#define RESULT_FAIL_PARAMETETER 0x77 +#define RESULT_FAIL_DEVICEDISABLED 0x88 +#define RESULT_FAIL_COUNTERINVALID 0x22 +#define RESULT_FAIL_COUNTERNOSET 0x33 +#define RESULT_FAIL_SEQUENCEWRONG 0x00 +#define RESULT_FAIL_NONE 0xFF + +// Delays +#define DELAY_DS28E16_EE_WRITE 100 +#define DELAY_DS28E16_EE_READ 50 +#define DELAY_DS28E16_RNG_READ 40 +#define DELAY_DS28E16_ENC_READ 40 + +// DS28E16 +#define PROT_RP 0x01 +#define PROT_WP 0x02 +#define PROT_WP_RP 0x03 +#define PROT_DC 0x08 + +// page number +#define PAGE0 0x00 +#define PAGE1 0x01 +#define DC_PAGE 0x02 +#define SECRET_PAGE 0x03 +#define MAX_PAGENUM 0x04 + +#define ANONYMOUS 1 + +//retry times config +#define SET_SRAM_RETRY 4 +#define GET_USER_MEMORY_RETRY 8 +#define GET_PERSONALITY_RETRY 8 +#define GET_ROM_ID_RETRY 8 +#define GET_BLOCK_STATUS_RETRY 8 +#define SET_BLOCK_STATUS_RETRY 8 +#define GET_MAC_RETRY 8 +#define GET_VERIFY_RETRY 8 +#define GET_S_SECRET_RETRY 4 + +// xiaomi's battery identity +#define FAMILY_CODE 0x9f +#define CUSTOM_ID_MSB 0x04 +#define CUSTOM_ID_LSB 0xF0 + +extern unsigned char last_result_byte; + +// Command functions +// 1-Wire ROMID commands +unsigned char crc_low_first(unsigned char *ptr, unsigned char len); +short Read_RomID(unsigned char *RomID); + +// Common Functions +unsigned short docrc16(unsigned short data); +int DS28E16_standard_cmd_flow(unsigned char *write_buf, int delay_ms, + unsigned char *read_buf, int *read_len, + int write_len); + +// Command Functions (no high level verification) +int DS28E16_cmd_readStatus( + unsigned char * + data); // 读入芯片的页é¢ä¿æŠ¤å±žæ€§ã€ä¸€ä¸ªMAN_ID字节和一个芯片版本字节,åˆè®¡6个字节 +int DS28E16_cmd_readMemory( + int pg, + unsigned char * + data); // pg=0,1,2页é¢ï¼Œä¸€æ¬¡è¯»å…¥32个字节,å‰16个字节为有效数æ®ï¼ŒåŽç»­16个字节固定为0x00或0xFF +int DS28E16_cmd_writeMemory( + int pg, unsigned char *data); // pg=0,1,2页é¢ï¼Œä¸€æ¬¡å¿…须完整写入16个字节 +int DS28E16_cmd_decrementCounter(void); // 执行此函数,完æˆ17ä½è®¡æ•°å™¨å‡1æ“作 +int DS28E16_cmd_setPageProtection(int pg, + unsigned char prot); // 设置芯片的页é¢å±žæ€§ +int DS28E16_cmd_device_disable(int op, + unsigned char *password); // 芯片自æ¯ï¼Œä¸èƒ½æ¢å¤ +int DS28E16_cmd_computeReadPageAuthentication( + int anon, int pg, unsigned char *challenge, + unsigned char * + hmac); // 器件基于会è¯å¯†ç ã€éšæœºæ•°ã€é¡µé¢æ•°æ®å’ŒROMID,返回器件的算法结果 +int DS28E16_cmd_computeS_Secret( + int anon, int bdconst, int pg, + unsigned char + *partial); // 基于主机å‘é€çš„密钥ç§å­ï¼Œå™¨ä»¶åœ¨å†…部计算出会è¯å¯†ç  + +// host functions +int AuthenticateDS28E16(int anon, int bdconst, int S_Secret_PageNum, + int PageNum, unsigned char *Challenge, + unsigned char *Secret_Seeds, unsigned char *S_Secret); + +static int ds28el16_Read_RomID_retry(unsigned char *RomID); +static int ds28el16_get_page_status_retry(unsigned char *data); +static int DS28E16_cmd_computeS_Secret_retry(int anon, int bdconst, int pg, + unsigned char *session_seed); +static int DS28E16_cmd_computeReadPageAuthentication_retry( + int anon, int pg, unsigned char *challenge, unsigned char *hmac); +static int ds28el16_get_page_data_retry(int page, unsigned char *data); +#endif diff --git a/drivers/power/supply/maxim/ds28e16_common.h b/drivers/power/supply/maxim/ds28e16_common.h new file mode 100644 index 000000000000..564f05bd0434 --- /dev/null +++ b/drivers/power/supply/maxim/ds28e16_common.h @@ -0,0 +1,84 @@ +// DS28E16.h - Include file for DS28E16/DS28E50? +// +#ifndef __DS28E16_COMMON_H__ +#define __DS28E16_COMMON_H__ + +#define ERROR_NO_DEVICE -1 +#define ERROR_R_STATUS -2 +#define ERROR_R_ROMID -3 +#define ERROR_R_PAGEDATA -4 +#define ERROR_COMPUTE_MAC -5 +#define ERROR_S_SECRET -6 +#define ERROR_UNMATCH_MAC -7 +#define DS_TRUE 1 +#define DS_FALSE 0 + +#define CMD_RELEASE_BYTE 0xAA +// 1-wire ROM commands +#define CMD_SEARCH_ROM 0xF0 +#define CMD_READ_ROM 0x33 +#define CMD_MATCH_ROM 0x55 +#define CMD_SKIP_ROM 0xCC +#define CMD_RESUME_ROM 0xA5 + +// DS28E16 commands +#define CMD_START 0x66 +#define CMD_WRITE_MEM 0x96 +#define CMD_READ_MEM 0x44 +#define CMD_READ_STATUS 0xAA +#define CMD_SET_PAGE_PROT 0xC3 +#define CMD_COMP_READ_AUTH 0xA5 +#define CMD_COMP_S_SECRET 0x3C +#define CMD_DECREMENT_CNT 0xC9 +#define CMD_DISABLE_DEVICE 0x33 + +#define CMD_READ_RNG 0xD2 + +// Result bytes +#define RESULT_SUCCESS 0xAA +#define RESULT_FAIL_PROTECTION 0x55 +#define RESULT_FAIL_PARAMETETER 0x77 +#define RESULT_FAIL_DEVICEDISABLED 0x88 +#define RESULT_FAIL_COUNTERINVALID 0x22 +#define RESULT_FAIL_COUNTERNOSET 0x33 +#define RESULT_FAIL_SEQUENCEWRONG 0x00 +#define RESULT_FAIL_NONE 0xFF + +// Delays +#define DELAY_DS28E16_EE_WRITE 100 +#define DELAY_DS28E16_EE_READ 50 +#define DELAY_DS28E16_RNG_READ 40 +#define DELAY_DS28E16_ENC_READ 40 + +// DS28E16 +#define PROT_RP 0x01 +#define PROT_WP 0x02 +#define PROT_WP_RP 0x03 +#define PROT_DC 0x08 + +// page number +#define PAGE0 0x00 +#define PAGE1 0x01 +#define DC_PAGE 0x02 +#define SECRET_PAGE 0x03 +#define MAX_PAGENUM 0x04 + +#define ANONYMOUS 1 + +//retry times config +#define SET_SRAM_RETRY 4 +#define GET_USER_MEMORY_RETRY 8 +#define GET_PERSONALITY_RETRY 8 +#define GET_ROM_ID_RETRY 8 +#define GET_BLOCK_STATUS_RETRY 8 +#define SET_BLOCK_STATUS_RETRY 8 +#define GET_MAC_RETRY 8 +#define GET_VERIFY_RETRY 8 +#define GET_S_SECRET_RETRY 4 + +// xiaomi's battery identity +#define FAMILY_CODE 0x9f +#define CUSTOM_ID_MSB 0x04 +#define CUSTOM_ID_LSB 0xF0 + +#endif diff --git a/drivers/power/supply/maxim/ds28e16_master.c b/drivers/power/supply/maxim/ds28e16_master.c new file mode 100644 index 000000000000..b5a526eaa166 --- /dev/null +++ b/drivers/power/supply/maxim/ds28e16_master.c @@ -0,0 +1,1915 @@ +/******************************************************************************* + * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + ******************************************************************************* + * + * DS28E16.c - DS28E16 device module. Requires low level 1-Wire connection. + */ +#define pr_fmt(fmt) "[ds28e16] %s: " fmt, __func__ + +#include /* kfree() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sha384_software.h" +#include "ds28e16_master.h" +#include "onewire_gpio_master.h" +#include "ds28e16_common.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ds_info pr_err +#define ds_dbg pr_err +#define ds_err pr_err +#define ds_log pr_err + +struct ds28e16_data { + struct platform_device *pdev; + struct device *dev; + + int version; + + struct power_supply *verify_psy; + struct power_supply_desc verify_psy_d; + + struct delayed_work authentic_work; +}; + +unsigned int attr_trytimes = 1; + +unsigned char session_seed[32] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA }; +unsigned char S_secret[32] = { 0x0C, 0x99, 0x2B, 0xD3, 0x95, 0xDB, 0xA0, 0xB4, + 0xEF, 0x07, 0xB3, 0xD8, 0x75, 0xF3, 0xC7, 0xAE, + 0xDA, 0xC4, 0x41, 0x2F, 0x48, 0x93, 0xB5, 0xD9, + 0xE1, 0xE5, 0x4B, 0x20, 0x9B, 0xF3, 0x77, 0x39 }; +unsigned char challenge[32] = { 0x00 }; +int auth_ANON = 1; +int auth_BDCONST = 1; +int pagenumber = 1; + +// maxim define +int tm = 1; +unsigned short CRC16; +const short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; +unsigned char last_result_byte = RESULT_SUCCESS; + +unsigned char MANID[2] = { 0x00 }; + +// mi add +unsigned char flag_mi_romid = 0; +unsigned char flag_mi_status = 0; +unsigned char flag_mi_page0_data = 0; +unsigned char flag_mi_page1_data = 0; +unsigned char flag_mi_counter = 0; +unsigned char flag_mi_auth_result = 0; +unsigned char mi_romid[8] = { 0x00 }; +unsigned char mi_status[8] = { 0x00 }; +unsigned char mi_page0_data[16] = { 0x00 }; +unsigned char mi_page1_data[16] = { 0x00 }; +unsigned char mi_counter[16] = { 0x00 }; +int mi_auth_result = 0x00; +static bool batt_verified_result_from_uefi; +static bool batt_chip_ok_result_from_uefi; + +unsigned char crc_low_first(unsigned char *ptr, unsigned char len) +{ + unsigned char i; + unsigned char crc = 0x00; + + while (len--) { + crc ^= *ptr++; + for (i = 0; i < 8; ++i) { + if (crc & 0x01) + crc = (crc >> 1) ^ 0x8c; + else + crc = (crc >> 1); + } + } + + return (crc); +} + +short Read_RomID(unsigned char *RomID) +{ + unsigned char i; + unsigned char crc = 0x00; + + if (flag_mi_romid == 2) { + memcpy(RomID, mi_romid, 8); + return DS_TRUE; + } + + if ((ow_reset()) != 0) { + ds_err("Read_RomID: Failed to reset ds28e16!\n"); + ow_reset(); + return ERROR_NO_DEVICE; + } + + ds_dbg("Ready to write 0x33 to maxim IC!\n"); + write_byte(CMD_READ_ROM); + Delay_us(10); + for (i = 0; i < 8; i++) + RomID[i] = read_byte(); + + ds_dbg("RomID = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", RomID[0], + RomID[1], RomID[2], RomID[3], RomID[4], RomID[5], RomID[6], + RomID[7]); + + crc = crc_low_first(RomID, 7); + ds_dbg("crc_low_first = %02x\n", crc); + + if (crc == RomID[7]) { + memcpy(mi_romid, RomID, 8); + if (mi_romid[0] == FAMILY_CODE && + mi_romid[6] == CUSTOM_ID_MSB && + (mi_romid[5] & 0xF0) == CUSTOM_ID_LSB) + flag_mi_romid = 2; + return DS_TRUE; + } else { + ow_reset(); + return DS_FALSE; + } +} + +unsigned short docrc16(unsigned short data) +{ + data = (data ^ (CRC16 & 0xff)) & 0xff; + CRC16 >>= 8; + + if (oddparity[data & 0xf] ^ oddparity[data >> 4]) + CRC16 ^= 0xc001; + + data <<= 6; + CRC16 ^= data; + data <<= 1; + CRC16 ^= data; + + return CRC16; +} + +int DS28E16_standard_cmd_flow(unsigned char *write_buf, int delay_ms, + unsigned char *read_buf, int *read_len, + int write_len) +{ + unsigned char buf[128]; + int i; + int buf_len = 0; + int expected_read_len = *read_len; + + //NEW FLOW + /*'1 Wire + ''''''''''''''''''''''' + ? + ? + ?TX: Start Command + ?TX: Length Byte + ?TX: Memory Command + ?TX: Parameter, TX: Data + ?RX: CRC16 + ?TX: Release Byte + ? + ?RX: Dummy Byte + ?RX: Length Byte + ?RX: Result byte + ?RX: CRC16 + ?< wait for reset> + '''''''''''''''''''''''*/ + ds_dbg("DS28E16_standard_cmd_flow start\n"); + + if ((ow_reset()) != 0) { + ds_err("Failed to reset ds28e16!\n"); + ow_reset(); + return ERROR_NO_DEVICE; + } + + write_byte(CMD_SKIP_ROM); + + buf[buf_len++] = CMD_START; + memcpy(&buf[buf_len], write_buf, write_len); + buf_len += write_len; + for (i = 0; i < buf_len; i++) + write_byte(buf[i]); + + buf[buf_len++] = read_byte(); + buf[buf_len++] = read_byte(); + + CRC16 = 0; + for (i = 0; i < buf_len; i++) + docrc16(buf[i]); + + if (CRC16 != 0xB001) { + ow_reset(); + ds_dbg("DS28E16_standard_cmd_flow: crc error!\n"); + return DS_FALSE; + } + + // check for strong pull-up + if (delay_ms > 0) { + write_byte(CMD_RELEASE_BYTE); + Delay_us(1000 * delay_ms); + } + + read_byte(); + *read_len = read_byte(); + + if (expected_read_len != *read_len) { + ow_reset(); + ds_dbg("DS28E16_standard_cmd_flow: len error!\n"); + return DS_FALSE; + } + + buf_len = *read_len + 2; + for (i = 0; i < buf_len; i++) + buf[i] = read_byte(); + + CRC16 = 0; + docrc16(*read_len); + for (i = 0; i < buf_len; i++) + docrc16(buf[i]); + + if (CRC16 != 0xB001) { + ow_reset(); + ds_dbg("DS28E16_standard_cmd_flow: crc2 error!\n"); + return DS_FALSE; + } + + memcpy(read_buf, buf, *read_len); + ds_dbg("DS28E16_standard_cmd_flow success!\n"); + return DS_TRUE; +} + +//-------------------------------------------------------------------------- +/// 'Read Status' command +/// +/// @param[out] data +/// pointer to unsigned char (buffer of length 1) for page protection data +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_readStatus(unsigned char *data) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int len_byte = 1; + int read_len = 7; + + if (flag_mi_status) { + memcpy(data, mi_status, 8); + return DS_TRUE; + } + + last_result_byte = RESULT_FAIL_NONE; + /* + ? + ?TX: Read Page Protection command + ?TX: Length (SMBus) [always 1] + ?TX: Parameter + ? + ? + ? + ?RX: Length (SMBus) [always 1] + ?RX: Protection Data + ? + */ + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_READ_STATUS; + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_READ * tm, + read_buf, &read_len, write_len)) { + if (read_buf[0] == RESULT_SUCCESS) { + last_result_byte = read_buf[0]; + memcpy(data, &read_buf[1], 8); + flag_mi_status = 1; + memcpy(mi_status, data, 8); + MANID[0] = data[4]; + return DS_TRUE; + } + } + + ow_reset(); + return DS_FALSE; +} + +//-------------------------------------------------------------------------- +/// 'Read Memory' command +/// +/// @param[in] pg +/// page number to read +/// @param[out] data +/// buffer length must be at least 32 bytes to hold memory read +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_readMemory(int pg, unsigned char *data) +{ + unsigned char write_buf[3]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 33; + int length_byte = 2; + unsigned char pagenum = (unsigned char)pg & 0x03; + + switch (pagenum) { + case 0x00: + if (flag_mi_page0_data) { + memcpy(data, mi_page0_data, 16); + return DS_TRUE; + } + break; + case 0x01: + if (flag_mi_page1_data) { + memcpy(data, mi_page1_data, 16); + return DS_TRUE; + } + break; + case 0x02: + if (flag_mi_counter) { + memcpy(data, mi_counter, 16); + return DS_TRUE; + } + break; + default: + return DS_FALSE; + } + + last_result_byte = RESULT_FAIL_NONE; + + /* + ? + ?TX: Read Memory Command + ?TX: Length (SMBus) + ?TX: Parameter + ? + ? + ? + ?RX: Length (SMBus) + ?RX: Result byte + ?RX: Data + ? + */ + + write_buf[write_len++] = length_byte; + write_buf[write_len++] = CMD_READ_MEM; + write_buf[write_len++] = pagenum; + + ds_dbg("DS28E16_cmd_readMemory write_buf:\n"); + ds_dbg("%02x %02x %02x", write_buf[0], write_buf[1], write_buf[2]); + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_READ * tm, + read_buf, &read_len, write_len)) { + if (read_len == 33) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) { + memcpy(data, &read_buf[1], 16); + if (pagenum == 0x00) { + flag_mi_page0_data = 1; + memcpy(mi_page0_data, data, 16); + } + if (pagenum == 0x01) { + flag_mi_page1_data = 1; + memcpy(mi_page1_data, data, 16); + } + return DS_TRUE; + } else { + if (read_buf[0] == 0x55 && pagenum == 2) { + memcpy(data, &read_buf[1], 16); + flag_mi_counter = 1; + memcpy(mi_counter, data, 16); + return DS_TRUE; + } + } + } + } + + ow_reset(); + return DS_FALSE; +} + +//-------------------------------------------------------------------------- +/// 'Write Memory' command +/// +/// @param[in] pg +/// page number to write +/// @param[in] data +/// buffer must be at least 32 bytes +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_writeMemory(int pg, unsigned char *data) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 1; + int len_byte = 18; + unsigned char pagenum = (unsigned char)pg & 0x03; + + last_result_byte = RESULT_FAIL_NONE; + /* + ? + ?TX: Write Memory Command + ?TX: Length (SMBus) [always 33] + ?TX: Parameter + ?TX: Data + ? + ? + ? + ?RX: Length (SMBus) [always 1] + ?RX: Result byte + ? + */ + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_WRITE_MEM; + write_buf[write_len++] = pagenum; + memcpy(&write_buf[write_len], data, 16); + write_len += 16; + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_WRITE * tm, + read_buf, &read_len, write_len)) { + if (read_len == 1) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) { + if (pagenum == 0x00) { + flag_mi_page0_data = 0; + memset(mi_page0_data, 0x00, 16); + } + if (pagenum == 0x01) { + flag_mi_page1_data = 0; + memset(mi_page0_data, 0x00, 16); + } + if (pagenum == 0x02) { + flag_mi_counter = 0; + memset(mi_counter, 0x00, 16); + } + return DS_TRUE; + } + } + } + + ow_reset(); + return DS_FALSE; +} + +//-------------------------------------------------------------------------- +/// 'Decrement Counter' command +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_decrementCounter(void) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 1; + + last_result_byte = RESULT_FAIL_NONE; + /* + ? + ?TX: Decrement Counter Command + ? + ? + ? + ?RX: Length (SMBus) [always 1] + ?RX: Result byte + ? + */ + + write_buf[write_len++] = 1; + write_buf[write_len++] = CMD_DECREMENT_CNT; + + if (DS28E16_standard_cmd_flow(write_buf, 50, read_buf, &read_len, + write_len)) { + if (read_len == 1) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) + return DS_TRUE; + } + } + + ow_reset(); + return DS_FALSE; +} + +//-------------------------------------------------------------------------- +/// 'Set Page Protection' command +/// +/// @param[in] pg +/// block to set protection +/// @param[in] prot +/// protection value to set +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_setPageProtection(int page, unsigned char prot) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 1; + int len_byte = 3; + + last_result_byte = RESULT_FAIL_NONE; + /* + ? + ?TX: Set Page Protection Command + ?TX: Length (SMBus) [always 2] + ?TX: Parameter + ?TX: Protection Data + ? + ? + ? + ?RX: Length (SMBus) [always 1] + ?RX: Result byte + ? + */ + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_SET_PAGE_PROT; + write_buf[write_len++] = page & 0x03; + write_buf[write_len++] = prot & 0x03; + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_WRITE * tm, + read_buf, &read_len, write_len)) { + if (read_len == 1) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) + return DS_TRUE; + } + } + + ow_reset(); + return DS_FALSE; +} + +int DS28E16_cmd_device_disable(int op, unsigned char *password) +{ + unsigned char write_buf[64]; + unsigned char read_buf[64]; + int write_len = 0; + int read_len = 1; + int length_byte = 10; + + last_result_byte = RESULT_FAIL_NONE; + /* + ? + ?TX: Length + ?TX: Device Disable Command + ?TX: Parameter + ? + ? + ? + ?RX: Length (SMBus) + ?RX: Result byte + ?RX: Data + ? + */ + + write_buf[write_len++] = length_byte; + write_buf[write_len++] = CMD_DISABLE_DEVICE; + write_buf[write_len++] = op & 0x0F; + memcpy(&write_buf[write_len], password, 8); + write_len += 8; + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_WRITE, + read_buf, &read_len, write_len)) { + if (read_len == 1) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) + return DS_TRUE; + } + } + + ow_reset(); + return DS_FALSE; +} + +// -------------------------------------------------------------------------- +/// 'Compute and Read Page Authentication' command +/// +/// @param[in] anon - boolean parameter +/// @param[in] pg - Page number 2,计数å™? 0,page0; 1,page1; +/// @param[in] challenge +/// @param[out] hmac 返回的计算结æž?2个字èŠ?/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_computeReadPageAuthentication(int anon, int pg, + unsigned char *challenge, + unsigned char *hmac) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 33; + int len_byte = 35; + + last_result_byte = RESULT_FAIL_NONE; + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_COMP_READ_AUTH; + write_buf[write_len] = pg & 0x03; + if (anon) + write_buf[write_len] = (write_buf[write_len] | 0xE0); + + write_len++; + write_buf[write_len++] = 0x02; // Fixed Parameter + memcpy(&write_buf[write_len], challenge, 32); // Challenge + write_len += 32; + + ds_dbg("computeReadPageAuthen:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + write_buf[0], write_buf[1], write_buf[2], write_buf[3], + write_buf[4], write_buf[5], write_buf[6], write_buf[7], + write_buf[8], write_buf[9], write_buf[10], write_buf[11], + write_buf[12], write_buf[13], write_buf[14], write_buf[15], + write_buf[16], write_buf[17], write_buf[18], write_buf[19], + write_buf[20], write_buf[21], write_buf[22], write_buf[23], + write_buf[24], write_buf[25], write_buf[26], write_buf[27], + write_buf[28], write_buf[29], write_buf[30], write_buf[31], + write_buf[32], write_buf[33], write_buf[34]); + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_WRITE, + read_buf, &read_len, write_len)) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) { + ds_dbg("hmac read_buf:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + read_buf[0], read_buf[1], read_buf[2], + read_buf[3], read_buf[4], read_buf[5], + read_buf[6], read_buf[7], read_buf[8], + read_buf[9], read_buf[10], read_buf[11], + read_buf[12], read_buf[13], read_buf[14], + read_buf[15], read_buf[16], read_buf[17], + read_buf[18], read_buf[19], read_buf[20], + read_buf[21], read_buf[22], read_buf[23], + read_buf[24], read_buf[25], read_buf[26], + read_buf[27], read_buf[28], read_buf[29], + read_buf[30], read_buf[31], read_buf[32]); + memcpy(hmac, &read_buf[1], 32); + ds_dbg("hmac:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + hmac[0], hmac[1], hmac[2], hmac[3], hmac[4], + hmac[5], hmac[6], hmac[7], hmac[8], hmac[9], + hmac[10], hmac[11], hmac[12], hmac[13], hmac[14], + hmac[15], hmac[16], hmac[17], hmac[18], hmac[19], + hmac[20], hmac[21], hmac[22], hmac[23], hmac[24], + hmac[25], hmac[26], hmac[27], hmac[28], hmac[29], + hmac[30], hmac[31]); + return DS_TRUE; + } + } + + ow_reset(); + return DS_FALSE; +} + +// -------------------------------------------------------------------------- +/// 'Compute Secret S' command +/// +/// @param[in] anon - boolean parameter +/// @param[in] bdconst - boolean parameter +/// @param[in] pg - Page number é¡µé¢ +/// @param[in] partial secret 32个字节的ç§å­ +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_computeS_Secret(int anon, int bdconst, int pg, + unsigned char *partial) +{ + unsigned char write_buf[40]; + unsigned char read_buf[40]; + int write_len = 0; + int read_len = 1; + int len_byte = 35; + int param = pg & 0x03; + + last_result_byte = RESULT_FAIL_NONE; + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_COMP_S_SECRET; + + if (bdconst) + param = param | 0x04; + if (anon) + param = param | 0xE0; + + write_buf[write_len] = param; + write_len++; + write_buf[write_len++] = 0x08; // Fixed Parameter + memcpy(&write_buf[write_len], partial, 32); // Partial Secret + write_len += 32; + + ds_dbg("computeS_Secret:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + write_buf[0], write_buf[1], write_buf[2], write_buf[3], + write_buf[4], write_buf[5], write_buf[6], write_buf[7], + write_buf[8], write_buf[9], write_buf[10], write_buf[11], + write_buf[12], write_buf[13], write_buf[14], write_buf[15], + write_buf[16], write_buf[17], write_buf[18], write_buf[19], + write_buf[20], write_buf[21], write_buf[22], write_buf[23], + write_buf[24], write_buf[25], write_buf[26], write_buf[27], + write_buf[28], write_buf[29], write_buf[30], write_buf[31], + write_buf[32], write_buf[33], write_buf[34]); + + if (DS28E16_standard_cmd_flow(write_buf, DELAY_DS28E16_EE_WRITE, + read_buf, &read_len, write_len)) { + last_result_byte = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) + return DS_TRUE; + } + + ow_reset(); + return DS_FALSE; +} + +int AuthenticateDS28E16(int anon, int bdconst, int S_Secret_PageNum, + int PageNum, unsigned char *Challenge, + unsigned char *Secret_Seeds, unsigned char *S_Secret) +{ + unsigned char PageData[32], MAC_Read_Value[32], CAL_MAC[32]; + unsigned char status_chip[16]; + unsigned char MAC_Computer_Datainput[128]; + int i = 0; + int msg_len = 0; + unsigned char flag = DS_FALSE; + + //if (flag_mi_auth_result) + if (mi_auth_result == DS_TRUE) + return mi_auth_result; + + if (anon != ANONYMOUS) { + if (ds28el16_get_page_status_retry(status_chip) == DS_TRUE) { + MANID[0] = status_chip[4]; + } else { + ow_reset(); + return ERROR_R_STATUS; + } + + if (ds28el16_Read_RomID_retry(mi_romid) != DS_TRUE) { + ow_reset(); + return ERROR_R_ROMID; + } + } + + // DS28E16 calculate its session secret + flag = DS28E16_cmd_computeS_Secret_retry( + anon, bdconst, S_Secret_PageNum, Secret_Seeds); + if (flag == DS_FALSE) { + ds_err("DS28E16_cmd_computeS_Secret error"); + ow_reset(); + return ERROR_S_SECRET; + } + + // DS28E16 compute its MAC based on above sessio secret + flag = DS28E16_cmd_computeReadPageAuthentication_retry( + anon, PageNum, Challenge, MAC_Read_Value); + if (flag == DS_FALSE) { + ds_err("DS28E16_cmd_computeReadPageAuthentication error"); + ow_reset(); + return ERROR_COMPUTE_MAC; + } + + ds_dbg("%02x %02x %02x %02x", anon, bdconst, S_Secret_PageNum, PageNum); + + ds_dbg("Seeds:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + Secret_Seeds[0], Secret_Seeds[1], Secret_Seeds[2], + Secret_Seeds[3], Secret_Seeds[4], Secret_Seeds[5], + Secret_Seeds[6], Secret_Seeds[7], Secret_Seeds[8], + Secret_Seeds[9], Secret_Seeds[10], Secret_Seeds[11], + Secret_Seeds[12], Secret_Seeds[13], Secret_Seeds[14], + Secret_Seeds[15], Secret_Seeds[16], Secret_Seeds[17], + Secret_Seeds[18], Secret_Seeds[19], Secret_Seeds[20], + Secret_Seeds[21], Secret_Seeds[22], Secret_Seeds[23], + Secret_Seeds[24], Secret_Seeds[25], Secret_Seeds[26], + Secret_Seeds[27], Secret_Seeds[28], Secret_Seeds[29], + Secret_Seeds[30], Secret_Seeds[31]); + + ds_dbg("S_Secret:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + S_Secret[0], S_Secret[1], S_Secret[2], S_Secret[3], S_Secret[4], + S_Secret[5], S_Secret[6], S_Secret[7], S_Secret[8], S_Secret[9], + S_Secret[10], S_Secret[11], S_Secret[12], S_Secret[13], + S_Secret[14], S_Secret[15], S_Secret[16], S_Secret[17], + S_Secret[18], S_Secret[19], S_Secret[20], S_Secret[21], + S_Secret[22], S_Secret[23], S_Secret[24], S_Secret[25], + S_Secret[26], S_Secret[27], S_Secret[28], S_Secret[29], + S_Secret[30], S_Secret[31]); + + ds_dbg("Challenge:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + Challenge[0], Challenge[1], Challenge[2], Challenge[3], + Challenge[4], Challenge[5], Challenge[6], Challenge[7], + Challenge[8], Challenge[9], Challenge[10], Challenge[11], + Challenge[12], Challenge[13], Challenge[14], Challenge[15], + Challenge[16], Challenge[17], Challenge[18], Challenge[19], + Challenge[20], Challenge[21], Challenge[22], Challenge[23], + Challenge[24], Challenge[25], Challenge[26], Challenge[27], + Challenge[28], Challenge[29], Challenge[30], Challenge[31]); + + ds_dbg("MAC_Read_Value:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + MAC_Read_Value[0], MAC_Read_Value[1], MAC_Read_Value[2], + MAC_Read_Value[3], MAC_Read_Value[4], MAC_Read_Value[5], + MAC_Read_Value[6], MAC_Read_Value[7], MAC_Read_Value[8], + MAC_Read_Value[9], MAC_Read_Value[10], MAC_Read_Value[11], + MAC_Read_Value[12], MAC_Read_Value[13], MAC_Read_Value[14], + MAC_Read_Value[15], MAC_Read_Value[16], MAC_Read_Value[17], + MAC_Read_Value[18], MAC_Read_Value[19], MAC_Read_Value[20], + MAC_Read_Value[21], MAC_Read_Value[22], MAC_Read_Value[23], + MAC_Read_Value[24], MAC_Read_Value[25], MAC_Read_Value[26], + MAC_Read_Value[27], MAC_Read_Value[28], MAC_Read_Value[29], + MAC_Read_Value[30], MAC_Read_Value[31]); + + // read the page data + flag = ds28el16_get_page_data_retry(PageNum, PageData); + if (flag != DS_TRUE) { + ds_err("DS28E16_cmd_readMemory error"); + ow_reset(); + return ERROR_R_PAGEDATA; + } + + // insert mi_romid + if (anon != ANONYMOUS) + memcpy(MAC_Computer_Datainput, mi_romid, 8); + else + memset(MAC_Computer_Datainput, 0xff, 8); + msg_len += 8; + + // insert Page Data + memcpy(&MAC_Computer_Datainput[msg_len], PageData, 16); + msg_len += 16; + memset(&MAC_Computer_Datainput[msg_len], 0x00, 16); + msg_len += 16; + + // insert Challenge + memcpy(&MAC_Computer_Datainput[msg_len], Challenge, 32); + msg_len += 32; + + // insert Bind Data Page number + MAC_Computer_Datainput[msg_len] = PageNum & 0x03; + MAC_Computer_Datainput[msg_len] = MAC_Computer_Datainput[msg_len] & + 0x03; + msg_len += 1; + + // insert MANID + memcpy(&MAC_Computer_Datainput[msg_len], MANID, 2); + msg_len += 2; + + // calculate the MAC + sha3_256_hmac(S_Secret, 32, MAC_Computer_Datainput, msg_len, CAL_MAC); + + ds_dbg("host data:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + MAC_Computer_Datainput[0], MAC_Computer_Datainput[1], + MAC_Computer_Datainput[2], MAC_Computer_Datainput[3], + MAC_Computer_Datainput[4], MAC_Computer_Datainput[5], + MAC_Computer_Datainput[6], MAC_Computer_Datainput[7], + MAC_Computer_Datainput[8], MAC_Computer_Datainput[9], + MAC_Computer_Datainput[10], MAC_Computer_Datainput[11], + MAC_Computer_Datainput[12], MAC_Computer_Datainput[13], + MAC_Computer_Datainput[14], MAC_Computer_Datainput[15], + MAC_Computer_Datainput[16], MAC_Computer_Datainput[17], + MAC_Computer_Datainput[18], MAC_Computer_Datainput[19], + MAC_Computer_Datainput[20], MAC_Computer_Datainput[21], + MAC_Computer_Datainput[22], MAC_Computer_Datainput[23], + MAC_Computer_Datainput[24], MAC_Computer_Datainput[25], + MAC_Computer_Datainput[26], MAC_Computer_Datainput[27], + MAC_Computer_Datainput[28], MAC_Computer_Datainput[29], + MAC_Computer_Datainput[30], MAC_Computer_Datainput[31], + MAC_Computer_Datainput[32], MAC_Computer_Datainput[33], + MAC_Computer_Datainput[34], MAC_Computer_Datainput[35], + MAC_Computer_Datainput[36], MAC_Computer_Datainput[37], + MAC_Computer_Datainput[38], MAC_Computer_Datainput[39], + MAC_Computer_Datainput[40], MAC_Computer_Datainput[41], + MAC_Computer_Datainput[42], MAC_Computer_Datainput[43], + MAC_Computer_Datainput[44], MAC_Computer_Datainput[45], + MAC_Computer_Datainput[46], MAC_Computer_Datainput[47], + MAC_Computer_Datainput[48], MAC_Computer_Datainput[49], + MAC_Computer_Datainput[50], MAC_Computer_Datainput[51], + MAC_Computer_Datainput[52], MAC_Computer_Datainput[53], + MAC_Computer_Datainput[54], MAC_Computer_Datainput[55], + MAC_Computer_Datainput[56], MAC_Computer_Datainput[57], + MAC_Computer_Datainput[58], MAC_Computer_Datainput[59], + MAC_Computer_Datainput[60], MAC_Computer_Datainput[61], + MAC_Computer_Datainput[62], MAC_Computer_Datainput[63], + MAC_Computer_Datainput[64], MAC_Computer_Datainput[65], + MAC_Computer_Datainput[66], MAC_Computer_Datainput[67], + MAC_Computer_Datainput[68], MAC_Computer_Datainput[69], + MAC_Computer_Datainput[70], MAC_Computer_Datainput[71], + MAC_Computer_Datainput[72], MAC_Computer_Datainput[73], + MAC_Computer_Datainput[74], MAC_Computer_Datainput[75], + MAC_Computer_Datainput[76], MAC_Computer_Datainput[77], + MAC_Computer_Datainput[78], MAC_Computer_Datainput[79]); + + ds_dbg("host mac:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + CAL_MAC[0], CAL_MAC[1], CAL_MAC[2], CAL_MAC[3], CAL_MAC[4], + CAL_MAC[5], CAL_MAC[6], CAL_MAC[7], CAL_MAC[8], CAL_MAC[9], + CAL_MAC[10], CAL_MAC[11], CAL_MAC[12], CAL_MAC[13], CAL_MAC[14], + CAL_MAC[15], CAL_MAC[16], CAL_MAC[17], CAL_MAC[18], CAL_MAC[19], + CAL_MAC[20], CAL_MAC[21], CAL_MAC[22], CAL_MAC[23], CAL_MAC[24], + CAL_MAC[25], CAL_MAC[26], CAL_MAC[27], CAL_MAC[28], CAL_MAC[29], + CAL_MAC[30], CAL_MAC[31]); + + for (i = 0; i < 32; i++) { + if (CAL_MAC[i] != MAC_Read_Value[i]) + break; + } + + if (i != 32) { + flag_mi_auth_result = 1; + mi_auth_result = ERROR_UNMATCH_MAC; + // for debug + ds_dbg("hmac is not match. result=ERROR_UNMATCH_MAC\n"); + flag_mi_page1_data = 0; + return ERROR_UNMATCH_MAC; + } else { + flag_mi_auth_result = 1; + ds_dbg("hmac is match. result=DS_TRUE\n"); + mi_auth_result = DS_TRUE; + return DS_TRUE; + } +} + +// retry interface start // +static int ds28el16_Read_RomID_retry(unsigned char *RomID) +{ + int i; + unsigned char data[50]; + + for (i = 0; i < GET_ROM_ID_RETRY; i++) { + ds_info("read rom id communication start %d...\n", i); + if (DS28E16_cmd_readStatus(data) == DS_TRUE) { + if (Read_RomID(RomID) == DS_TRUE) + return DS_TRUE; + } + } + ds_log("ds28el16_Read_RomID_retry fail\n"); + return DS_FALSE; +} + +static int ds28el16_get_page_status_retry(unsigned char *data) +{ + int i; + + for (i = 0; i < GET_BLOCK_STATUS_RETRY; i++) { + ds_info("read page status communication start... %d\n", i); + + if (DS28E16_cmd_readStatus(data) == DS_TRUE) + return DS_TRUE; + } + + return DS_FALSE; +} + +/* +static int ds28el16_set_page_status_retry(unsigned char page, unsigned char status) +{ + int i; + + for (i = 0; i < SET_BLOCK_STATUS_RETRY; i++) { + ds_info("set page status communication start... %d\n", i); + + if (DS28E16_cmd_setPageProtection(page, status) == TRUE) + return DS_TRUE; + } + + return DS_FALSE; +} +*/ + +static int ds28el16_get_page_data_retry(int page, unsigned char *data) +{ + int i; + + if (page >= MAX_PAGENUM) + return DS_FALSE; + + for (i = 0; i < GET_USER_MEMORY_RETRY; i++) { + ds_dbg("read page data communication start... %d\n", i); + + if (DS28E16_cmd_readMemory(page, data) == DS_TRUE) { + ds_dbg("page number is %d\n", page); + ds_dbg("page data:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + data[0], data[1], data[2], data[3], data[4], + data[5], data[6], data[7], data[8], data[9], + data[10], data[11], data[12], data[13], data[14], + data[15]); + ds_dbg("flag_mi_page0_data is %d\n", + flag_mi_page0_data); + ds_dbg("mi_page0_data data:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + mi_page0_data[0], mi_page0_data[1], + mi_page0_data[2], mi_page0_data[3], + mi_page0_data[4], mi_page0_data[5], + mi_page0_data[6], mi_page0_data[7], + mi_page0_data[8], mi_page0_data[9], + mi_page0_data[10], mi_page0_data[11], + mi_page0_data[12], mi_page0_data[13], + mi_page0_data[14], mi_page0_data[15]); + ds_dbg("flag_mi_page1_data is %d\n", + flag_mi_page1_data); + ds_dbg("mi_page1_data data:\n"); + ds_dbg("%%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + mi_page1_data[0], mi_page1_data[1], + mi_page1_data[2], mi_page1_data[3], + mi_page1_data[4], mi_page1_data[5], + mi_page1_data[6], mi_page1_data[7], + mi_page1_data[8], mi_page1_data[9], + mi_page1_data[10], mi_page1_data[11], + mi_page1_data[12], mi_page1_data[13], + mi_page1_data[14], mi_page1_data[15]); + ds_dbg("flag_mi_counter is %d\n", flag_mi_counter); + return DS_TRUE; + } + } + + return DS_FALSE; +} + +static int DS28E16_cmd_computeS_Secret_retry(int anon, int bdconst, int pg, + unsigned char *partial) +{ + int i; + + if (pg >= MAX_PAGENUM) + return DS_FALSE; + + for (i = 0; i < GET_S_SECRET_RETRY; i++) { + if (DS28E16_cmd_computeS_Secret(anon, bdconst, pg, partial) == + DS_TRUE) + return DS_TRUE; + } + + return DS_FALSE; +} + +static int DS28E16_cmd_computeReadPageAuthentication_retry( + int anon, int pg, unsigned char *challenge, unsigned char *hmac) +{ + int i; + + if (pg >= MAX_PAGENUM) + return DS_FALSE; + + for (i = 0; i < GET_MAC_RETRY; i++) { + if (DS28E16_cmd_computeReadPageAuthentication( + anon, pg, challenge, hmac) == DS_TRUE) + return DS_TRUE; + } + + return DS_FALSE; +} + +// retry interface end // + +/* All power supply functions here */ + +static enum power_supply_property verify_props[] = { + POWER_SUPPLY_PROP_ROMID, + POWER_SUPPLY_PROP_DS_STATUS, + POWER_SUPPLY_PROP_PAGENUMBER, + POWER_SUPPLY_PROP_PAGEDATA, + POWER_SUPPLY_PROP_AUTHEN_RESULT, + POWER_SUPPLY_PROP_SESSION_SEED, + POWER_SUPPLY_PROP_S_SECRET, + POWER_SUPPLY_PROP_CHALLENGE, + POWER_SUPPLY_PROP_AUTH_ANON, + POWER_SUPPLY_PROP_AUTH_BDCONST, + POWER_SUPPLY_PROP_PAGE0_DATA, + POWER_SUPPLY_PROP_PAGE1_DATA, + POWER_SUPPLY_PROP_VERIFY_MODEL_NAME, + POWER_SUPPLY_PROP_CHIP_OK, +}; + +static int verify_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret; + unsigned char buf[50]; + + switch (psp) { + case POWER_SUPPLY_PROP_VERIFY_MODEL_NAME: + ret = ds28el16_Read_RomID_retry(mi_romid); + if (ret == DS_TRUE) + val->strval = "ds28e16"; + else + val->strval = "unknown"; + break; + case POWER_SUPPLY_PROP_AUTHEN_RESULT: + if (batt_verified_result_from_uefi) { + val->intval = true; + ds_info("batt_verified_result_from_uefi is true\n"); + break; + } + ret = AuthenticateDS28E16(auth_ANON, auth_BDCONST, 0, + pagenumber, challenge, session_seed, + S_secret); + if (ret == DS_TRUE) + val->intval = true; + else + val->intval = false; + break; + case POWER_SUPPLY_PROP_PAGENUMBER: + val->intval = pagenumber; + break; + case POWER_SUPPLY_PROP_ROMID: + ret = ds28el16_Read_RomID_retry(mi_romid); + memcpy(val->arrayval, mi_romid, 8); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_CHIP_OK: + if (batt_chip_ok_result_from_uefi) { + val->intval = true; + ds_log("batt_chip_ok_result_from_uefi is true already\n"); + break; + } + ret = ds28el16_Read_RomID_retry(mi_romid); + if ((mi_romid[0] == FAMILY_CODE) && + (mi_romid[6] == CUSTOM_ID_MSB) && + ((mi_romid[5] & 0xf0) == CUSTOM_ID_LSB)) + val->intval = true; + else + val->intval = false; + break; + case POWER_SUPPLY_PROP_DS_STATUS: + ret = ds28el16_get_page_status_retry(buf); + memcpy(val->arrayval, buf, 8); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_PAGEDATA: + ret = ds28el16_get_page_data_retry(pagenumber, buf); + memcpy(val->arrayval, buf, 16); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_PAGE0_DATA: + ret = ds28el16_get_page_data_retry(0, buf); + memcpy(val->arrayval, buf, 16); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_PAGE1_DATA: + ret = ds28el16_get_page_data_retry(1, buf); + memcpy(val->arrayval, buf, 16); + if (ret != DS_TRUE) + return -EAGAIN; + break; + default: + ds_err("unsupported property %d\n", psp); + return -ENODATA; + } + + return 0; +} + +static int verify_set_property(struct power_supply *psy, + enum power_supply_property prop, + const union power_supply_propval *val) +{ + //int ret; + //unsigned char buf[50]; + + switch (prop) { + case POWER_SUPPLY_PROP_PAGENUMBER: + pagenumber = val->intval; + break; + /* + case POWER_SUPPLY_PROP_PAGEDATA: + memcpy(buf, val->arrayval, 16); + ret = DS28E16_cmd_writeMemory(pagenumber, buf); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_SESSION_SEED: + memcpy(session_seed, val->arrayval, 32); + break; + case POWER_SUPPLY_PROP_S_SECRET: + memcpy(S_secret, val->arrayval, 32); + break; + case POWER_SUPPLY_PROP_CHALLENGE: + memcpy(challenge, val->arrayval, 32); + break; +*/ + case POWER_SUPPLY_PROP_AUTH_ANON: + auth_ANON = val->intval; + break; + case POWER_SUPPLY_PROP_AUTH_BDCONST: + auth_BDCONST = val->intval; + break; + default: + ds_err("unsupported property %d\n", prop); + return -ENODATA; + } + + return 0; +} + +static int verify_prop_is_writeable(struct power_supply *psy, + enum power_supply_property prop) +{ + int ret; + + switch (prop) { + case POWER_SUPPLY_PROP_PAGENUMBER: + case POWER_SUPPLY_PROP_PAGEDATA: + case POWER_SUPPLY_PROP_SESSION_SEED: + case POWER_SUPPLY_PROP_S_SECRET: + case POWER_SUPPLY_PROP_CHALLENGE: + case POWER_SUPPLY_PROP_AUTH_ANON: + case POWER_SUPPLY_PROP_AUTH_BDCONST: + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +static int verify_psy_register(struct ds28e16_data *ds) +{ + struct power_supply_config verify_psy_cfg = {}; + + ds->verify_psy_d.name = "batt_verify"; + ds->verify_psy_d.type = POWER_SUPPLY_TYPE_BATT_VERIFY; + ds->verify_psy_d.properties = verify_props; + ds->verify_psy_d.num_properties = ARRAY_SIZE(verify_props); + ds->verify_psy_d.get_property = verify_get_property; + ds->verify_psy_d.set_property = verify_set_property; + ds->verify_psy_d.property_is_writeable = verify_prop_is_writeable; + + verify_psy_cfg.drv_data = ds; + verify_psy_cfg.of_node = ds->dev->of_node; + verify_psy_cfg.num_supplicants = 0; + ds->verify_psy = devm_power_supply_register(ds->dev, &ds->verify_psy_d, + &verify_psy_cfg); + if (IS_ERR(ds->verify_psy)) { + ds_err("Failed to register verify_psy"); + return PTR_ERR(ds->verify_psy); + } + + ds_log("%s power supply register successfully\n", + ds->verify_psy_d.name); + return 0; +} + +static void verify_psy_unregister(struct ds28e16_data *ds) +{ + power_supply_unregister(ds->verify_psy); +} + +// parse dts +static int ds28e16_parse_dt(struct device *dev, struct ds28e16_data *pdata) +{ + int error, val; + struct device_node *np = dev->of_node; + + // parse version + pdata->version = 0; + error = of_property_read_u32(np, "maxim,version", &val); + if (error && (error != -EINVAL)) + ds_err("Unable to read bootloader address\n"); + else if (error != -EINVAL) + pdata->version = val; + + return 0; +} + +// read data from file +static ssize_t ds28e16_ds_Auth_Result_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int result; + + result = AuthenticateDS28E16(auth_ANON, auth_BDCONST, 0, pagenumber, + challenge, session_seed, S_secret); + if (result == ERROR_R_STATUS) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : ERROR_R_STATUS!\n"); + else if (result == ERROR_UNMATCH_MAC) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : MAC is not match!\n"); + else if (result == ERROR_R_ROMID) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : ERROR_R_ROMID!\n"); + else if (result == ERROR_COMPUTE_MAC) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : ERROR_COMPUTE_MAC!\n"); + else if (result == ERROR_S_SECRET) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : ERROR_S_SECRET!\n"); + else if (result == DS_TRUE) + return scnprintf(buf, PAGE_SIZE, "Authenticate success!!!\n"); + else + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : other reason.\n"); +} + +static ssize_t ds28e16_ds_romid_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + short status; + unsigned char RomID[10] = { 0x00 }; + int i = 0; + int count = 0; + + for (i = 0; i < attr_trytimes; i++) { + status = ds28el16_Read_RomID_retry(RomID); + + if (status == DS_TRUE) { + count++; + ds_log("Read_RomID success!\n"); + } else { + ds_log("Read_RomID fail!\n"); + } + ds_dbg("RomID = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + RomID[0], RomID[1], RomID[2], RomID[3], RomID[4], + RomID[5], RomID[6], RomID[7]); + Delay_us(1000); + } + + /*ds_dbg("RomID = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + RomID[0], RomID[1], RomID[2], RomID[3], + RomID[4], RomID[5], RomID[6], RomID[7]); + */ + ds_log("test done\nsuccess time : %d\n", count); + return scnprintf( + buf, PAGE_SIZE, + "Success = %d\nRomID = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + count, RomID[0], RomID[1], RomID[2], RomID[3], RomID[4], + RomID[5], RomID[6], RomID[7]); +} + +static ssize_t ds28e16_ds_pagenumber_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%02x\n", pagenumber); +} + +static ssize_t ds28e16_ds_pagenumber_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int buf_int; + + if (sscanf(buf, "%d", &buf_int) != 1) + return -EINVAL; + + ds_dbg("new pagenumber = %d\n", buf_int); + + if ((buf_int >= 0) && (buf_int <= 3)) + pagenumber = buf_int; + + return count; +} + +static ssize_t ds28e16_ds_pagedata_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int result; + unsigned char pagedata[16] = { 0x00 }; + int i = 0; + int count = 0; + + for (i = 0; i < attr_trytimes; i++) { + result = ds28el16_get_page_data_retry(pagenumber, pagedata); + + if (result == DS_TRUE) { + count++; + ds_log("DS28E16_cmd_readMemory success!\n"); + } else { + ds_log("DS28E16_cmd_readMemory fail!\n"); + } + ds_dbg("pagedata = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + pagedata[0], pagedata[1], pagedata[2], pagedata[3], + pagedata[4], pagedata[5], pagedata[6], pagedata[7], + pagedata[8], pagedata[9], pagedata[10], pagedata[11], + pagedata[12], pagedata[13], pagedata[14], pagedata[15]); + Delay_us(1000); + } + ds_log("test done\nsuccess time : %d\n", count); + return scnprintf( + buf, PAGE_SIZE, + "Success = %d\npagedata = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + count, pagedata[0], pagedata[1], pagedata[2], pagedata[3], + pagedata[4], pagedata[5], pagedata[6], pagedata[7], pagedata[8], + pagedata[9], pagedata[10], pagedata[11], pagedata[12], + pagedata[13], pagedata[14], pagedata[15]); +} + +static ssize_t ds28e16_ds_pagedata_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int result; + unsigned char pagedata[16] = { 0x00 }; + + if (sscanf(buf, + "%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx", + &pagedata[0], &pagedata[1], &pagedata[2], &pagedata[3], + &pagedata[4], &pagedata[5], &pagedata[6], &pagedata[7], + &pagedata[8], &pagedata[9], &pagedata[10], &pagedata[11], + &pagedata[12], &pagedata[13], &pagedata[14], + &pagedata[15]) != 16) + return -EINVAL; + + ds_dbg("new data = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + pagedata[0], pagedata[1], pagedata[2], pagedata[3], pagedata[4], + pagedata[5], pagedata[6], pagedata[7], pagedata[8], pagedata[9], + pagedata[10], pagedata[11], pagedata[12], pagedata[13], + pagedata[14], pagedata[15]); + + result = DS28E16_cmd_writeMemory(pagenumber, pagedata); + if (result == DS_TRUE) + ds_log("DS28E16_cmd_writeMemory success!\n"); + else + ds_log("DS28E16_cmd_writeMemory fail!\n"); + + return count; +} + +static ssize_t ds28e16_ds_time_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d\n", attr_trytimes); +} + +static ssize_t ds28e16_ds_time_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int buf_int; + + if (sscanf(buf, "%d", &buf_int) != 1) + return -EINVAL; + + ds_log("new trytimes = %d\n", buf_int); + + if (buf_int > 0) + attr_trytimes = buf_int; + + return count; +} + +static ssize_t +ds28e16_ds_session_seed_status_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, + "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n", + session_seed[0], session_seed[1], session_seed[2], + session_seed[3], session_seed[4], session_seed[5], + session_seed[6], session_seed[7], session_seed[8], + session_seed[9], session_seed[10], session_seed[11], + session_seed[12], session_seed[13], session_seed[14], + session_seed[15], session_seed[16], session_seed[17], + session_seed[18], session_seed[19], session_seed[20], + session_seed[21], session_seed[22], session_seed[23], + session_seed[24], session_seed[25], session_seed[26], + session_seed[27], session_seed[28], session_seed[29], + session_seed[30], session_seed[31]); +} + +static ssize_t ds28e16_ds_session_seed_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, + "%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx", + &session_seed[0], &session_seed[1], &session_seed[2], + &session_seed[3], &session_seed[4], &session_seed[5], + &session_seed[6], &session_seed[7], &session_seed[8], + &session_seed[9], &session_seed[10], &session_seed[11], + &session_seed[12], &session_seed[13], &session_seed[14], + &session_seed[15], &session_seed[16], &session_seed[17], + &session_seed[18], &session_seed[19], &session_seed[20], + &session_seed[21], &session_seed[22], &session_seed[23], + &session_seed[24], &session_seed[25], &session_seed[26], + &session_seed[27], &session_seed[28], &session_seed[29], + &session_seed[30], &session_seed[31]) != 32) + return -EINVAL; + + return count; +} + +static ssize_t ds28e16_ds_challenge_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, + "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n", + challenge[0], challenge[1], challenge[2], challenge[3], + challenge[4], challenge[5], challenge[6], challenge[7], + challenge[8], challenge[9], challenge[10], challenge[11], + challenge[12], challenge[13], challenge[14], challenge[15], + challenge[16], challenge[17], challenge[18], challenge[19], + challenge[20], challenge[21], challenge[22], challenge[23], + challenge[24], challenge[25], challenge[26], challenge[27], + challenge[28], challenge[29], challenge[30], challenge[31]); +} + +static ssize_t ds28e16_ds_challenge_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, + "%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx", + &challenge[0], &challenge[1], &challenge[2], &challenge[3], + &challenge[4], &challenge[5], &challenge[6], &challenge[7], + &challenge[8], &challenge[9], &challenge[10], &challenge[11], + &challenge[12], &challenge[13], &challenge[14], + &challenge[15], &challenge[16], &challenge[17], + &challenge[18], &challenge[19], &challenge[20], + &challenge[21], &challenge[22], &challenge[23], + &challenge[24], &challenge[25], &challenge[26], + &challenge[27], &challenge[28], &challenge[29], + &challenge[30], &challenge[31]) != 32) + return -EINVAL; + + return count; +} + +static ssize_t ds28e16_ds_S_secret_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, + "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n", + S_secret[0], S_secret[1], S_secret[2], S_secret[3], S_secret[4], + S_secret[5], S_secret[6], S_secret[7], S_secret[8], S_secret[9], + S_secret[10], S_secret[11], S_secret[12], S_secret[13], + S_secret[14], S_secret[15], S_secret[16], S_secret[17], + S_secret[18], S_secret[19], S_secret[20], S_secret[21], + S_secret[22], S_secret[23], S_secret[24], S_secret[25], + S_secret[26], S_secret[27], S_secret[28], S_secret[29], + S_secret[30], S_secret[31]); +} + +static ssize_t ds28e16_ds_S_secret_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, + "%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx", + &S_secret[0], &S_secret[1], &S_secret[2], &S_secret[3], + &S_secret[4], &S_secret[5], &S_secret[6], &S_secret[7], + &S_secret[8], &S_secret[9], &S_secret[10], &S_secret[11], + &S_secret[12], &S_secret[13], &S_secret[14], &S_secret[15], + &S_secret[16], &S_secret[17], &S_secret[18], &S_secret[19], + &S_secret[20], &S_secret[21], &S_secret[22], &S_secret[23], + &S_secret[24], &S_secret[25], &S_secret[26], &S_secret[27], + &S_secret[28], &S_secret[29], &S_secret[30], + &S_secret[31]) != 32) + return -EINVAL; + + return count; +} + +static ssize_t ds28e16_ds_auth_ANON_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%02x\n", auth_ANON); +} + +static ssize_t ds28e16_ds_auth_ANON_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, "%d", &auth_ANON) != 1) + return -EINVAL; + + return count; +} + +static ssize_t +ds28e16_ds_auth_BDCONST_status_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%02x\n", auth_BDCONST); +} + +static ssize_t ds28e16_ds_auth_BDCONST_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, "%d", &auth_BDCONST) != 1) + return -EINVAL; + + return count; +} + +static ssize_t ds28e16_ds_readstatus_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int result; + unsigned char status[16] = { 0x00 }; + int i = 0; + int count = 0; + + for (i = 0; i < attr_trytimes; i++) { + result = ds28el16_get_page_status_retry(status); + + if (result == DS_TRUE) { + count++; + ds_log("DS28E16_cmd_readStatus success!\n"); + } else { + ds_log("DS28E16_cmd_readStatus fail!\n"); + } + ds_dbg("Status = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + status[0], status[1], status[2], status[3], status[4], + status[5], status[6], status[7], status[8], status[9], + status[10], status[11], status[12], status[13], + status[14], status[15]); + Delay_us(1000); + } + ds_log("test done\nsuccess time : %d\n", count); + return scnprintf( + buf, PAGE_SIZE, + "Success = %d\nStatus = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + count, status[0], status[1], status[2], status[3], status[4], + status[5], status[6], status[7], status[8], status[9], + status[10], status[11], status[12], status[13], status[14], + status[15]); +} + +static DEVICE_ATTR(ds_readstatus, S_IRUGO, ds28e16_ds_readstatus_status_read, + NULL); +static DEVICE_ATTR(ds_romid, S_IRUGO, ds28e16_ds_romid_status_read, NULL); +static DEVICE_ATTR(ds_pagenumber, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_pagenumber_status_read, + ds28e16_ds_pagenumber_store); +static DEVICE_ATTR(ds_pagedata, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_pagedata_status_read, ds28e16_ds_pagedata_store); +static DEVICE_ATTR(ds_time, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_time_status_read, ds28e16_ds_time_store); +static DEVICE_ATTR(ds_session_seed, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_session_seed_status_read, + ds28e16_ds_session_seed_store); +static DEVICE_ATTR(ds_challenge, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_challenge_status_read, + ds28e16_ds_challenge_store); +static DEVICE_ATTR(ds_S_secret, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_S_secret_status_read, ds28e16_ds_S_secret_store); +static DEVICE_ATTR(ds_auth_ANON, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_auth_ANON_status_read, + ds28e16_ds_auth_ANON_store); +static DEVICE_ATTR(ds_auth_BDCONST, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_auth_BDCONST_status_read, + ds28e16_ds_auth_BDCONST_store); +static DEVICE_ATTR(ds_Auth_Result, S_IRUGO, ds28e16_ds_Auth_Result_status_read, + NULL); + +static struct attribute *ds_attributes[] = { + &dev_attr_ds_readstatus.attr, &dev_attr_ds_romid.attr, + &dev_attr_ds_pagenumber.attr, &dev_attr_ds_pagedata.attr, + &dev_attr_ds_time.attr, &dev_attr_ds_session_seed.attr, + &dev_attr_ds_challenge.attr, &dev_attr_ds_S_secret.attr, + &dev_attr_ds_auth_ANON.attr, &dev_attr_ds_auth_BDCONST.attr, + &dev_attr_ds_Auth_Result.attr, NULL, +}; + +static const struct attribute_group ds_attr_group = { + .attrs = ds_attributes, +}; + +static int authentic_period_ms = 5000; +#define AUTHENTIC_COUNT_MAX 5 +int retry_authentic; +static void authentic_work(struct work_struct *work) +{ + int rc; + union power_supply_propval pval = { + 0, + }; + + struct ds28e16_data *ds28e16_data = + container_of(work, struct ds28e16_data, authentic_work.work); + + rc = power_supply_get_property(ds28e16_data->verify_psy, + POWER_SUPPLY_PROP_AUTHEN_RESULT, &pval); + if (pval.intval != true) { + retry_authentic++; + if (retry_authentic < AUTHENTIC_COUNT_MAX) { + ds_log("battery authentic work begin to restart, retry = %d\n", + retry_authentic); + schedule_delayed_work( + &ds28e16_data->authentic_work, + msecs_to_jiffies(authentic_period_ms)); + } + + if (retry_authentic == AUTHENTIC_COUNT_MAX) { + ds_log("authentic result is %d\n", pval.intval); + } + } else { + ds_log("authentic result is %d\n", pval.intval); + } +} + +static int ds28e16_probe(struct platform_device *pdev) +{ + int retval = 0; + struct ds28e16_data *ds28e16_data; + union power_supply_propval b_val = { + 0, + }; + + ds_log("%s entry.", __func__); + ds_dbg("platform_device is %s", pdev->name); + if (strcmp(pdev->name, "soc:maxim_ds28e16") != 0) + return -ENODEV; + + if (!pdev->dev.of_node || !of_device_is_available(pdev->dev.of_node)) + return -ENODEV; + + if (pdev->dev.of_node) { + ds28e16_data = devm_kzalloc( + &pdev->dev, sizeof(struct ds28e16_data), GFP_KERNEL); + if (!ds28e16_data) { + ds_err("Failed to allocate memory\n"); + return -ENOMEM; + } + + retval = ds28e16_parse_dt(&pdev->dev, ds28e16_data); + if (retval) { + retval = -EINVAL; + goto ds28e16_parse_dt_err; + } + } else { + ds28e16_data = pdev->dev.platform_data; + } + + if (!ds28e16_data) { + ds_err("No platform data found\n"); + return -EINVAL; + } + + ds28e16_data->dev = &pdev->dev; + ds28e16_data->pdev = pdev; + platform_set_drvdata(pdev, ds28e16_data); + INIT_DELAYED_WORK(&ds28e16_data->authentic_work, authentic_work); + + retval = verify_psy_register(ds28e16_data); + if (retval) { + ds_err("Failed to verify_psy_register, err:%d\n", retval); + goto ds28e16_psy_register_err; + } + + retval = sysfs_create_group(&ds28e16_data->dev->kobj, &ds_attr_group); + if (retval) { + ds_err("Failed to register sysfs, err:%d\n", retval); + goto ds28e16_create_group_err; + } + + retval = power_supply_get_property(ds28e16_data->verify_psy, + POWER_SUPPLY_PROP_AUTHEN_RESULT, + &b_val); + if (b_val.intval != true) { + schedule_delayed_work(&ds28e16_data->authentic_work, + msecs_to_jiffies(0)); + } + return 0; + +ds28e16_create_group_err: +//sysfs_remove_groups(&ds28e16_data->dev->kobj, &(&ds_attr_group)); +ds28e16_psy_register_err: + dev_set_drvdata(ds28e16_data->dev, NULL); +ds28e16_parse_dt_err: + kfree(ds28e16_data); + return retval; +} + +static int ds28e16_remove(struct platform_device *pdev) +{ + struct ds28e16_data *ds28e16_data = platform_get_drvdata(pdev); + + verify_psy_unregister(ds28e16_data); + kfree(ds28e16_data); + return 0; +} + +static long ds28e16_dev_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + ds_log("%d, cmd: 0x%x\n", __LINE__, cmd); + return 0; +} +static int ds28e16_dev_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int ds28e16_dev_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations ds28e16_dev_fops = { + .owner = THIS_MODULE, + .open = ds28e16_dev_open, + .unlocked_ioctl = ds28e16_dev_ioctl, + .release = ds28e16_dev_release, +}; + +static const struct of_device_id ds28e16_dt_match[] = { + { .compatible = "maxim,ds28e16" }, + {}, +}; + +static struct platform_driver ds28e16_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "maxim_ds28e16", + .of_match_table = ds28e16_dt_match, + }, + .probe = ds28e16_probe, + .remove = ds28e16_remove, +}; + +static int __init ds28e16_init(void) +{ + ds_log("%s entry.", __func__); + + return platform_driver_register(&ds28e16_driver); +} + +static void __exit ds28e16_exit(void) +{ + ds_log("%s entry.", __func__); + platform_driver_unregister(&ds28e16_driver); +} + +static int __init early_parse_batt_verified_result(char *p) +{ + if (*p == '1') { + batt_verified_result_from_uefi = true; + } else { + batt_verified_result_from_uefi = false; + } + if (*(p + 1) == '1') { + batt_chip_ok_result_from_uefi = true; + } else { + batt_chip_ok_result_from_uefi = false; + } + + return 0; +} +early_param("androidboot.batt_verified_result", + early_parse_batt_verified_result); + +module_init(ds28e16_init); +module_exit(ds28e16_exit); + +MODULE_AUTHOR("xiaomi Inc."); +MODULE_DESCRIPTION("ds28e16 driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/power/supply/maxim/ds28e16_master.h b/drivers/power/supply/maxim/ds28e16_master.h new file mode 100644 index 000000000000..1429752b0226 --- /dev/null +++ b/drivers/power/supply/maxim/ds28e16_master.h @@ -0,0 +1,55 @@ +// DS28E16.h - Include file for DS28E16/DS28E50? +// +#ifndef __DS28E16_MASTER_H__ +#define __DS28E16_MASTER_H__ + +extern unsigned char last_result_byte; + +// Command functions +// 1-Wire ROMID commands +unsigned char crc_low_first(unsigned char *ptr, unsigned char len); +short Read_RomID(unsigned char *RomID); + +// Common Functions +unsigned short docrc16(unsigned short data); +int DS28E16_standard_cmd_flow(unsigned char *write_buf, int delay_ms, + unsigned char *read_buf, int *read_len, + int write_len); + +// Command Functions (no high level verification) +int DS28E16_cmd_readStatus( + unsigned char * + data); // 读入芯片的页é¢ä¿æŠ¤å±žæ€§ã€ä¸€ä¸ªMAN_ID字节和一个芯片版本字节,åˆè®¡6个字节 +int DS28E16_cmd_readMemory( + int pg, + unsigned char * + data); // pg=0,1,2页é¢ï¼Œä¸€æ¬¡è¯»å…¥32个字节,å‰16个字节为有效数æ®ï¼ŒåŽç»­16个字节固定为0x00或0xFF +int DS28E16_cmd_writeMemory( + int pg, unsigned char *data); // pg=0,1,2页é¢ï¼Œä¸€æ¬¡å¿…须完整写入16个字节 +int DS28E16_cmd_decrementCounter(void); // 执行此函数,完æˆ17ä½è®¡æ•°å™¨å‡1æ“作 +int DS28E16_cmd_setPageProtection(int pg, + unsigned char prot); // 设置芯片的页é¢å±žæ€§ +int DS28E16_cmd_device_disable(int op, + unsigned char *password); // 芯片自æ¯ï¼Œä¸èƒ½æ¢å¤ +int DS28E16_cmd_computeReadPageAuthentication( + int anon, int pg, unsigned char *challenge, + unsigned char * + hmac); // 器件基于会è¯å¯†ç ã€éšæœºæ•°ã€é¡µé¢æ•°æ®å’ŒROMID,返回器件的算法结果 +int DS28E16_cmd_computeS_Secret( + int anon, int bdconst, int pg, + unsigned char + *partial); // 基于主机å‘é€çš„密钥ç§å­ï¼Œå™¨ä»¶åœ¨å†…部计算出会è¯å¯†ç  + +// host functions +int AuthenticateDS28E16(int anon, int bdconst, int S_Secret_PageNum, + int PageNum, unsigned char *Challenge, + unsigned char *Secret_Seeds, unsigned char *S_Secret); + +static int ds28el16_Read_RomID_retry(unsigned char *RomID); +static int ds28el16_get_page_status_retry(unsigned char *data); +static int DS28E16_cmd_computeS_Secret_retry(int anon, int bdconst, int pg, + unsigned char *session_seed); +static int DS28E16_cmd_computeReadPageAuthentication_retry( + int anon, int pg, unsigned char *challenge, unsigned char *hmac); +static int ds28el16_get_page_data_retry(int page, unsigned char *data); +#endif diff --git a/drivers/power/supply/maxim/ds28e16_slave.c b/drivers/power/supply/maxim/ds28e16_slave.c new file mode 100644 index 000000000000..7e030c486f77 --- /dev/null +++ b/drivers/power/supply/maxim/ds28e16_slave.c @@ -0,0 +1,1959 @@ +/******************************************************************************* + * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + ******************************************************************************* + * + * DS28E16.c - DS28E16 device module. Requires low level 1-Wire connection. + */ +#define pr_fmt(fmt) "[ds28e16] %s: " fmt, __func__ + +#include /* kfree() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sha384_software.h" +#include "ds28e16_slave.h" +#include "onewire_gpio_slave.h" +#include "ds28e16_common.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ds_info pr_err +#define ds_dbg pr_err +#define ds_err pr_err +#define ds_log pr_err + +struct ds28e16_data { + struct platform_device *pdev; + struct device *dev; + + int version; + + struct power_supply *verify_psy; + struct power_supply_desc verify_psy_d; + + struct delayed_work authentic_work; +}; + +unsigned int attr_trytimes_slave = 1; + +unsigned char session_seed_slave[32] = { + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA +}; +unsigned char S_secret_slave[32] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA }; +unsigned char challenge_slave[32] = { 0x00 }; +int auth_ANON_slave = 1; +int auth_BDCONST_slave = 1; +int pagenumber_slave = 1; + +// maxim define +int tm_slave = 1; +unsigned short CRC16_slave; +const short oddparity_slave[16] = { 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0 }; +unsigned char last_result_byte_slave = RESULT_SUCCESS; + +unsigned char MANID_slave[2] = { 0x00 }; + +// mi add +unsigned char flag_mi_romid_slave = 0; +unsigned char flag_mi_status_slave = 0; +unsigned char flag_mi_page0_data_slave = 0; +unsigned char flag_mi_page1_data_slave = 0; +unsigned char flag_mi_counter_slave = 0; +unsigned char flag_mi_auth_result_slave = 0; +unsigned char mi_romid_slave[8] = { 0x00 }; +unsigned char mi_status_slave[8] = { 0x00 }; +unsigned char mi_page0_data_slave[16] = { 0x00 }; +unsigned char mi_page1_data_slave[16] = { 0x00 }; +unsigned char mi_counter_slave[16] = { 0x00 }; +int mi_auth_result_slave = 0x00; + +static bool batt_verified_result_from_uefi; +static bool batt_chip_ok_result_from_uefi; + +unsigned char crc_low_first_slave(unsigned char *ptr, unsigned char len) +{ + unsigned char i; + unsigned char crc = 0x00; + + while (len--) { + crc ^= *ptr++; + for (i = 0; i < 8; ++i) { + if (crc & 0x01) + crc = (crc >> 1) ^ 0x8c; + else + crc = (crc >> 1); + } + } + + return (crc); +} + +short Read_RomID_slave(unsigned char *RomID) +{ + unsigned char i; + unsigned char crc = 0x00; + + if (flag_mi_romid_slave == 2) { + memcpy(RomID, mi_romid_slave, 8); + return DS_TRUE; + } + + if ((ow_reset_slave()) != 0) { + ds_err("Read_RomID_slave: Failed to reset ds28e16!\n"); + ow_reset_slave(); + return ERROR_NO_DEVICE; + } + + ds_dbg("Ready to write 0x33 to maxim IC!\n"); + write_byte_slave(CMD_READ_ROM); + Delay_us_slave(10); + for (i = 0; i < 8; i++) + RomID[i] = read_byte_slave(); + + ds_dbg("RomID = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", RomID[0], + RomID[1], RomID[2], RomID[3], RomID[4], RomID[5], RomID[6], + RomID[7]); + + crc = crc_low_first_slave(RomID, 7); + ds_dbg("crc_low_first_slave = %02x\n", crc); + + if (crc == RomID[7]) { + memcpy(mi_romid_slave, RomID, 8); + if (mi_romid_slave[0] == FAMILY_CODE && + mi_romid_slave[6] == CUSTOM_ID_MSB && + (mi_romid_slave[5] & 0xF0) == CUSTOM_ID_LSB) + flag_mi_romid_slave = 2; + return DS_TRUE; + } else { + ow_reset_slave(); + return DS_FALSE; + } +} + +unsigned short docrc16_slave(unsigned short data) +{ + data = (data ^ (CRC16_slave & 0xff)) & 0xff; + CRC16_slave >>= 8; + + if (oddparity_slave[data & 0xf] ^ oddparity_slave[data >> 4]) + CRC16_slave ^= 0xc001; + + data <<= 6; + CRC16_slave ^= data; + data <<= 1; + CRC16_slave ^= data; + + return CRC16_slave; +} + +int DS28E16_standard_cmd_flow_slave(unsigned char *write_buf, int delay_ms, + unsigned char *read_buf, int *read_len, + int write_len) +{ + unsigned char buf[128]; + int i; + int buf_len = 0; + int expected_read_len = *read_len; + + //NEW FLOW + /*'1 Wire + ''''''''''''''''''''''' + ? + ? + ?TX: Start Command + ?TX: Length Byte + ?TX: Memory Command + ?TX: Parameter, TX: Data + ?RX: CRC16_slave + ?TX: Release Byte + ? + ?RX: Dummy Byte + ?RX: Length Byte + ?RX: Result byte + ?RX: CRC16_slave + ?< wait for reset> + '''''''''''''''''''''''*/ + ds_dbg("DS28E16_standard_cmd_flow_slave start\n"); + + if ((ow_reset_slave()) != 0) { + ds_err("Failed to reset ds28e16!\n"); + ow_reset_slave(); + return ERROR_NO_DEVICE; + } + + write_byte_slave(CMD_SKIP_ROM); + + buf[buf_len++] = CMD_START; + memcpy(&buf[buf_len], write_buf, write_len); + buf_len += write_len; + for (i = 0; i < buf_len; i++) + write_byte_slave(buf[i]); + + buf[buf_len++] = read_byte_slave(); + buf[buf_len++] = read_byte_slave(); + + CRC16_slave = 0; + for (i = 0; i < buf_len; i++) + docrc16_slave(buf[i]); + + if (CRC16_slave != 0xB001) { + ow_reset_slave(); + ds_dbg("DS28E16_standard_cmd_flow_slave: crc error!\n"); + return DS_FALSE; + } + + // check for strong pull-up + if (delay_ms > 0) { + write_byte_slave(CMD_RELEASE_BYTE); + Delay_us_slave(1000 * delay_ms); + } + + read_byte_slave(); + *read_len = read_byte_slave(); + + if (expected_read_len != *read_len) { + ow_reset_slave(); + ds_dbg("DS28E16_standard_cmd_flow_slave: len error!\n"); + return DS_FALSE; + } + + buf_len = *read_len + 2; + for (i = 0; i < buf_len; i++) + buf[i] = read_byte_slave(); + + CRC16_slave = 0; + docrc16_slave(*read_len); + for (i = 0; i < buf_len; i++) + docrc16_slave(buf[i]); + + if (CRC16_slave != 0xB001) { + ow_reset_slave(); + ds_dbg("DS28E16_standard_cmd_flow_slave: crc2 error!\n"); + return DS_FALSE; + } + + memcpy(read_buf, buf, *read_len); + ds_dbg("DS28E16_standard_cmd_flow_slave success!\n"); + return DS_TRUE; +} + +//-------------------------------------------------------------------------- +/// 'Read Status' command +/// +/// @param[out] data +/// pointer to unsigned char (buffer of length 1) for page protection data +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_readStatus_slave(unsigned char *data) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int len_byte = 1; + int read_len = 7; + + if (flag_mi_status_slave) { + memcpy(data, mi_status_slave, 8); + return DS_TRUE; + } + + last_result_byte_slave = RESULT_FAIL_NONE; + /* + ? + ?TX: Read Page Protection command + ?TX: Length (SMBus) [always 1] + ?TX: Parameter + ? + ? + ? + ?RX: Length (SMBus) [always 1] + ?RX: Protection Data + ? + */ + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_READ_STATUS; + + if (DS28E16_standard_cmd_flow_slave(write_buf, + DELAY_DS28E16_EE_READ * tm_slave, + read_buf, &read_len, write_len)) { + if (read_buf[0] == RESULT_SUCCESS) { + last_result_byte_slave = read_buf[0]; + memcpy(data, &read_buf[1], 8); + flag_mi_status_slave = 1; + memcpy(mi_status_slave, data, 8); + MANID_slave[0] = data[4]; + return DS_TRUE; + } + } + + ow_reset_slave(); + return DS_FALSE; +} + +//-------------------------------------------------------------------------- +/// 'Read Memory' command +/// +/// @param[in] pg +/// page number to read +/// @param[out] data +/// buffer length must be at least 32 bytes to hold memory read +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_readMemory_slave(int pg, unsigned char *data) +{ + unsigned char write_buf[3]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 33; + int length_byte = 2; + unsigned char pagenum = (unsigned char)pg & 0x03; + + switch (pagenum) { + case 0x00: + if (flag_mi_page0_data_slave) { + memcpy(data, mi_page0_data_slave, 16); + return DS_TRUE; + } + break; + case 0x01: + if (flag_mi_page1_data_slave) { + memcpy(data, mi_page1_data_slave, 16); + return DS_TRUE; + } + break; + case 0x02: + if (flag_mi_counter_slave) { + memcpy(data, mi_counter_slave, 16); + return DS_TRUE; + } + break; + default: + return DS_FALSE; + } + + last_result_byte_slave = RESULT_FAIL_NONE; + + /* + ? + ?TX: Read Memory Command + ?TX: Length (SMBus) + ?TX: Parameter + ? + ? + ? + ?RX: Length (SMBus) + ?RX: Result byte + ?RX: Data + ? + */ + + write_buf[write_len++] = length_byte; + write_buf[write_len++] = CMD_READ_MEM; + write_buf[write_len++] = pagenum; + + ds_dbg("DS28E16_cmd_readMemory_slave write_buf:\n"); + ds_dbg("%02x %02x %02x", write_buf[0], write_buf[1], write_buf[2]); + + if (DS28E16_standard_cmd_flow_slave(write_buf, + DELAY_DS28E16_EE_READ * tm_slave, + read_buf, &read_len, write_len)) { + if (read_len == 33) { + last_result_byte_slave = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) { + memcpy(data, &read_buf[1], 16); + if (pagenum == 0x00) { + flag_mi_page0_data_slave = 1; + memcpy(mi_page0_data_slave, data, 16); + } + if (pagenum == 0x01) { + flag_mi_page1_data_slave = 1; + memcpy(mi_page1_data_slave, data, 16); + } + return DS_TRUE; + } else { + if (read_buf[0] == 0x55 && pagenum == 2) { + memcpy(data, &read_buf[1], 16); + flag_mi_counter_slave = 1; + memcpy(mi_counter_slave, data, 16); + return DS_TRUE; + } + } + } + } + + ow_reset_slave(); + return DS_FALSE; +} + +//-------------------------------------------------------------------------- +/// 'Write Memory' command +/// +/// @param[in] pg +/// page number to write +/// @param[in] data +/// buffer must be at least 32 bytes +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_writeMemory_slave(int pg, unsigned char *data) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 1; + int len_byte = 18; + unsigned char pagenum = (unsigned char)pg & 0x03; + + last_result_byte_slave = RESULT_FAIL_NONE; + /* + ? + ?TX: Write Memory Command + ?TX: Length (SMBus) [always 33] + ?TX: Parameter + ?TX: Data + ? + ? + ? + ?RX: Length (SMBus) [always 1] + ?RX: Result byte + ? + */ + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_WRITE_MEM; + write_buf[write_len++] = pagenum; + memcpy(&write_buf[write_len], data, 16); + write_len += 16; + + if (DS28E16_standard_cmd_flow_slave(write_buf, + DELAY_DS28E16_EE_WRITE * tm_slave, + read_buf, &read_len, write_len)) { + if (read_len == 1) { + last_result_byte_slave = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) { + if (pagenum == 0x00) { + flag_mi_page0_data_slave = 0; + memset(mi_page0_data_slave, 0x00, 16); + } + if (pagenum == 0x01) { + flag_mi_page1_data_slave = 0; + memset(mi_page0_data_slave, 0x00, 16); + } + if (pagenum == 0x02) { + flag_mi_counter_slave = 0; + memset(mi_counter_slave, 0x00, 16); + } + return DS_TRUE; + } + } + } + + ow_reset_slave(); + return DS_FALSE; +} + +//-------------------------------------------------------------------------- +/// 'Decrement Counter' command +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_decrementCounter_slave(void) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 1; + + last_result_byte_slave = RESULT_FAIL_NONE; + /* + ? + ?TX: Decrement Counter Command + ? + ? + ? + ?RX: Length (SMBus) [always 1] + ?RX: Result byte + ? + */ + + write_buf[write_len++] = 1; + write_buf[write_len++] = CMD_DECREMENT_CNT; + + if (DS28E16_standard_cmd_flow_slave(write_buf, 50, read_buf, &read_len, + write_len)) { + if (read_len == 1) { + last_result_byte_slave = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) + return DS_TRUE; + } + } + + ow_reset_slave(); + return DS_FALSE; +} + +//-------------------------------------------------------------------------- +/// 'Set Page Protection' command +/// +/// @param[in] pg +/// block to set protection +/// @param[in] prot +/// protection value to set +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_setPageProtection_slave(int page, unsigned char prot) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 1; + int len_byte = 3; + + last_result_byte_slave = RESULT_FAIL_NONE; + /* + ? + ?TX: Set Page Protection Command + ?TX: Length (SMBus) [always 2] + ?TX: Parameter + ?TX: Protection Data + ? + ? + ? + ?RX: Length (SMBus) [always 1] + ?RX: Result byte + ? + */ + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_SET_PAGE_PROT; + write_buf[write_len++] = page & 0x03; + write_buf[write_len++] = prot & 0x03; + + if (DS28E16_standard_cmd_flow_slave(write_buf, + DELAY_DS28E16_EE_WRITE * tm_slave, + read_buf, &read_len, write_len)) { + if (read_len == 1) { + last_result_byte_slave = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) + return DS_TRUE; + } + } + + ow_reset_slave(); + return DS_FALSE; +} + +int DS28E16_cmd_device_disable_slave(int op, unsigned char *password) +{ + unsigned char write_buf[64]; + unsigned char read_buf[64]; + int write_len = 0; + int read_len = 1; + int length_byte = 10; + + last_result_byte_slave = RESULT_FAIL_NONE; + /* + ? + ?TX: Length + ?TX: Device Disable Command + ?TX: Parameter + ? + ? + ? + ?RX: Length (SMBus) + ?RX: Result byte + ?RX: Data + ? + */ + + write_buf[write_len++] = length_byte; + write_buf[write_len++] = CMD_DISABLE_DEVICE; + write_buf[write_len++] = op & 0x0F; + memcpy(&write_buf[write_len], password, 8); + write_len += 8; + + if (DS28E16_standard_cmd_flow_slave(write_buf, DELAY_DS28E16_EE_WRITE, + read_buf, &read_len, write_len)) { + if (read_len == 1) { + last_result_byte_slave = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) + return DS_TRUE; + } + } + + ow_reset_slave(); + return DS_FALSE; +} + +// -------------------------------------------------------------------------- +/// 'Compute and Read Page Authentication' command +/// +/// @param[in] anon - boolean parameter +/// @param[in] pg - Page number 2,¿¿¿? 0,page0; 1,page1; +/// @param[in] challenge_slave +/// @param[out] hmac ¿¿¿¿¿¿¿?2¿¿¿?/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_computeReadPageAuthentication_slave( + int anon, int pg, unsigned char *challenge_slave, unsigned char *hmac) +{ + unsigned char write_buf[255]; + unsigned char read_buf[255]; + int write_len = 0; + int read_len = 33; + int len_byte = 35; + + last_result_byte_slave = RESULT_FAIL_NONE; + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_COMP_READ_AUTH; + write_buf[write_len] = pg & 0x03; + if (anon) + write_buf[write_len] = (write_buf[write_len] | 0xE0); + + write_len++; + write_buf[write_len++] = 0x02; // Fixed Parameter + memcpy(&write_buf[write_len], challenge_slave, 32); // Challenge + write_len += 32; + + ds_dbg("computeReadPageAuthen:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + write_buf[0], write_buf[1], write_buf[2], write_buf[3], + write_buf[4], write_buf[5], write_buf[6], write_buf[7], + write_buf[8], write_buf[9], write_buf[10], write_buf[11], + write_buf[12], write_buf[13], write_buf[14], write_buf[15], + write_buf[16], write_buf[17], write_buf[18], write_buf[19], + write_buf[20], write_buf[21], write_buf[22], write_buf[23], + write_buf[24], write_buf[25], write_buf[26], write_buf[27], + write_buf[28], write_buf[29], write_buf[30], write_buf[31], + write_buf[32], write_buf[33], write_buf[34]); + + if (DS28E16_standard_cmd_flow_slave(write_buf, DELAY_DS28E16_EE_WRITE, + read_buf, &read_len, write_len)) { + last_result_byte_slave = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) { + ds_dbg("hmac read_buf:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + read_buf[0], read_buf[1], read_buf[2], + read_buf[3], read_buf[4], read_buf[5], + read_buf[6], read_buf[7], read_buf[8], + read_buf[9], read_buf[10], read_buf[11], + read_buf[12], read_buf[13], read_buf[14], + read_buf[15], read_buf[16], read_buf[17], + read_buf[18], read_buf[19], read_buf[20], + read_buf[21], read_buf[22], read_buf[23], + read_buf[24], read_buf[25], read_buf[26], + read_buf[27], read_buf[28], read_buf[29], + read_buf[30], read_buf[31], read_buf[32]); + memcpy(hmac, &read_buf[1], 32); + ds_dbg("hmac:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + hmac[0], hmac[1], hmac[2], hmac[3], hmac[4], + hmac[5], hmac[6], hmac[7], hmac[8], hmac[9], + hmac[10], hmac[11], hmac[12], hmac[13], hmac[14], + hmac[15], hmac[16], hmac[17], hmac[18], hmac[19], + hmac[20], hmac[21], hmac[22], hmac[23], hmac[24], + hmac[25], hmac[26], hmac[27], hmac[28], hmac[29], + hmac[30], hmac[31]); + return DS_TRUE; + } + } + + ow_reset_slave(); + return DS_FALSE; +} + +// -------------------------------------------------------------------------- +/// 'Compute Secret S' command +/// +/// @param[in] anon - boolean parameter +/// @param[in] bdconst - boolean parameter +/// @param[in] pg - Page number ¿¿ +/// @param[in] partial secret 32¿¿¿¿¿¿ +/// +/// @return +/// DS_TRUE - command successful @n +/// DS_FALSE - command failed +/// +int DS28E16_cmd_computeS_Secret_slave(int anon, int bdconst, int pg, + unsigned char *partial) +{ + unsigned char write_buf[40]; + unsigned char read_buf[40]; + int write_len = 0; + int read_len = 1; + int len_byte = 35; + int param = pg & 0x03; + + last_result_byte_slave = RESULT_FAIL_NONE; + + write_buf[write_len++] = len_byte; + write_buf[write_len++] = CMD_COMP_S_SECRET; + + if (bdconst) + param = param | 0x04; + if (anon) + param = param | 0xE0; + + write_buf[write_len] = param; + write_len++; + write_buf[write_len++] = 0x08; // Fixed Parameter + memcpy(&write_buf[write_len], partial, 32); // Partial Secret + write_len += 32; + + ds_dbg("computeS_Secret:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + write_buf[0], write_buf[1], write_buf[2], write_buf[3], + write_buf[4], write_buf[5], write_buf[6], write_buf[7], + write_buf[8], write_buf[9], write_buf[10], write_buf[11], + write_buf[12], write_buf[13], write_buf[14], write_buf[15], + write_buf[16], write_buf[17], write_buf[18], write_buf[19], + write_buf[20], write_buf[21], write_buf[22], write_buf[23], + write_buf[24], write_buf[25], write_buf[26], write_buf[27], + write_buf[28], write_buf[29], write_buf[30], write_buf[31], + write_buf[32], write_buf[33], write_buf[34]); + + if (DS28E16_standard_cmd_flow_slave(write_buf, DELAY_DS28E16_EE_WRITE, + read_buf, &read_len, write_len)) { + last_result_byte_slave = read_buf[0]; + if (read_buf[0] == RESULT_SUCCESS) + return DS_TRUE; + } + + ow_reset_slave(); + return DS_FALSE; +} + +int AuthenticateDS28E16_slave(int anon, int bdconst, int S_Secret_PageNum, + int PageNum, unsigned char *Challenge, + unsigned char *Secret_Seeds, + unsigned char *S_Secret) +{ + unsigned char PageData[32], MAC_Read_Value[32], CAL_MAC[32]; + unsigned char status_chip[16]; + unsigned char MAC_Computer_Datainput[128]; + int i = 0; + int msg_len = 0; + unsigned char flag = DS_FALSE; + + //if (flag_mi_auth_result_slave) + if (mi_auth_result_slave == DS_TRUE) + return mi_auth_result_slave; + + if (anon != ANONYMOUS) { + if (ds28el16_get_page_status_retry_slave(status_chip) == + DS_TRUE) { + MANID_slave[0] = status_chip[4]; + } else { + ow_reset_slave(); + return ERROR_R_STATUS; + } + + if (ds28el16_Read_RomID_retry_slave(mi_romid_slave) != + DS_TRUE) { + ow_reset_slave(); + return ERROR_R_ROMID; + } + } + + // DS28E16 calculate its session secret + flag = DS28E16_cmd_computeS_Secret_retry_slave( + anon, bdconst, S_Secret_PageNum, Secret_Seeds); + if (flag == DS_FALSE) { + ds_err("DS28E16_cmd_computeS_Secret_slave error"); + ow_reset_slave(); + return ERROR_S_SECRET; + } + + // DS28E16 compute its MAC based on above sessio secret + flag = DS28E16_cmd_computeReadPageAuthentication_retry_slave( + anon, PageNum, Challenge, MAC_Read_Value); + if (flag == DS_FALSE) { + ds_err("DS28E16_cmd_computeReadPageAuthentication_slave error"); + ow_reset_slave(); + return ERROR_COMPUTE_MAC; + } + + ds_dbg("%02x %02x %02x %02x", anon, bdconst, S_Secret_PageNum, PageNum); + + ds_dbg("Seeds:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + Secret_Seeds[0], Secret_Seeds[1], Secret_Seeds[2], + Secret_Seeds[3], Secret_Seeds[4], Secret_Seeds[5], + Secret_Seeds[6], Secret_Seeds[7], Secret_Seeds[8], + Secret_Seeds[9], Secret_Seeds[10], Secret_Seeds[11], + Secret_Seeds[12], Secret_Seeds[13], Secret_Seeds[14], + Secret_Seeds[15], Secret_Seeds[16], Secret_Seeds[17], + Secret_Seeds[18], Secret_Seeds[19], Secret_Seeds[20], + Secret_Seeds[21], Secret_Seeds[22], Secret_Seeds[23], + Secret_Seeds[24], Secret_Seeds[25], Secret_Seeds[26], + Secret_Seeds[27], Secret_Seeds[28], Secret_Seeds[29], + Secret_Seeds[30], Secret_Seeds[31]); + + ds_dbg("S_Secret:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + S_Secret[0], S_Secret[1], S_Secret[2], S_Secret[3], S_Secret[4], + S_Secret[5], S_Secret[6], S_Secret[7], S_Secret[8], S_Secret[9], + S_Secret[10], S_Secret[11], S_Secret[12], S_Secret[13], + S_Secret[14], S_Secret[15], S_Secret[16], S_Secret[17], + S_Secret[18], S_Secret[19], S_Secret[20], S_Secret[21], + S_Secret[22], S_Secret[23], S_Secret[24], S_Secret[25], + S_Secret[26], S_Secret[27], S_Secret[28], S_Secret[29], + S_Secret[30], S_Secret[31]); + + ds_dbg("Challenge:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + Challenge[0], Challenge[1], Challenge[2], Challenge[3], + Challenge[4], Challenge[5], Challenge[6], Challenge[7], + Challenge[8], Challenge[9], Challenge[10], Challenge[11], + Challenge[12], Challenge[13], Challenge[14], Challenge[15], + Challenge[16], Challenge[17], Challenge[18], Challenge[19], + Challenge[20], Challenge[21], Challenge[22], Challenge[23], + Challenge[24], Challenge[25], Challenge[26], Challenge[27], + Challenge[28], Challenge[29], Challenge[30], Challenge[31]); + + ds_dbg("MAC_Read_Value:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + MAC_Read_Value[0], MAC_Read_Value[1], MAC_Read_Value[2], + MAC_Read_Value[3], MAC_Read_Value[4], MAC_Read_Value[5], + MAC_Read_Value[6], MAC_Read_Value[7], MAC_Read_Value[8], + MAC_Read_Value[9], MAC_Read_Value[10], MAC_Read_Value[11], + MAC_Read_Value[12], MAC_Read_Value[13], MAC_Read_Value[14], + MAC_Read_Value[15], MAC_Read_Value[16], MAC_Read_Value[17], + MAC_Read_Value[18], MAC_Read_Value[19], MAC_Read_Value[20], + MAC_Read_Value[21], MAC_Read_Value[22], MAC_Read_Value[23], + MAC_Read_Value[24], MAC_Read_Value[25], MAC_Read_Value[26], + MAC_Read_Value[27], MAC_Read_Value[28], MAC_Read_Value[29], + MAC_Read_Value[30], MAC_Read_Value[31]); + + // read the page data + flag = ds28el16_get_page_data_retry_slave(PageNum, PageData); + if (flag != DS_TRUE) { + ds_err("DS28E16_cmd_readMemory_slave error"); + ow_reset_slave(); + return ERROR_R_PAGEDATA; + } + + // insert mi_romid_slave + if (anon != ANONYMOUS) + memcpy(MAC_Computer_Datainput, mi_romid_slave, 8); + else + memset(MAC_Computer_Datainput, 0xff, 8); + msg_len += 8; + + // insert Page Data + memcpy(&MAC_Computer_Datainput[msg_len], PageData, 16); + msg_len += 16; + memset(&MAC_Computer_Datainput[msg_len], 0x00, 16); + msg_len += 16; + + // insert Challenge + memcpy(&MAC_Computer_Datainput[msg_len], Challenge, 32); + msg_len += 32; + + // insert Bind Data Page number + MAC_Computer_Datainput[msg_len] = PageNum & 0x03; + MAC_Computer_Datainput[msg_len] = MAC_Computer_Datainput[msg_len] & + 0x03; + msg_len += 1; + + // insert MANID_slave + memcpy(&MAC_Computer_Datainput[msg_len], MANID_slave, 2); + msg_len += 2; + + // calculate the MAC + sha3_256_hmac(S_Secret, 32, MAC_Computer_Datainput, msg_len, CAL_MAC); + + ds_dbg("host data:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + MAC_Computer_Datainput[0], MAC_Computer_Datainput[1], + MAC_Computer_Datainput[2], MAC_Computer_Datainput[3], + MAC_Computer_Datainput[4], MAC_Computer_Datainput[5], + MAC_Computer_Datainput[6], MAC_Computer_Datainput[7], + MAC_Computer_Datainput[8], MAC_Computer_Datainput[9], + MAC_Computer_Datainput[10], MAC_Computer_Datainput[11], + MAC_Computer_Datainput[12], MAC_Computer_Datainput[13], + MAC_Computer_Datainput[14], MAC_Computer_Datainput[15], + MAC_Computer_Datainput[16], MAC_Computer_Datainput[17], + MAC_Computer_Datainput[18], MAC_Computer_Datainput[19], + MAC_Computer_Datainput[20], MAC_Computer_Datainput[21], + MAC_Computer_Datainput[22], MAC_Computer_Datainput[23], + MAC_Computer_Datainput[24], MAC_Computer_Datainput[25], + MAC_Computer_Datainput[26], MAC_Computer_Datainput[27], + MAC_Computer_Datainput[28], MAC_Computer_Datainput[29], + MAC_Computer_Datainput[30], MAC_Computer_Datainput[31], + MAC_Computer_Datainput[32], MAC_Computer_Datainput[33], + MAC_Computer_Datainput[34], MAC_Computer_Datainput[35], + MAC_Computer_Datainput[36], MAC_Computer_Datainput[37], + MAC_Computer_Datainput[38], MAC_Computer_Datainput[39], + MAC_Computer_Datainput[40], MAC_Computer_Datainput[41], + MAC_Computer_Datainput[42], MAC_Computer_Datainput[43], + MAC_Computer_Datainput[44], MAC_Computer_Datainput[45], + MAC_Computer_Datainput[46], MAC_Computer_Datainput[47], + MAC_Computer_Datainput[48], MAC_Computer_Datainput[49], + MAC_Computer_Datainput[50], MAC_Computer_Datainput[51], + MAC_Computer_Datainput[52], MAC_Computer_Datainput[53], + MAC_Computer_Datainput[54], MAC_Computer_Datainput[55], + MAC_Computer_Datainput[56], MAC_Computer_Datainput[57], + MAC_Computer_Datainput[58], MAC_Computer_Datainput[59], + MAC_Computer_Datainput[60], MAC_Computer_Datainput[61], + MAC_Computer_Datainput[62], MAC_Computer_Datainput[63], + MAC_Computer_Datainput[64], MAC_Computer_Datainput[65], + MAC_Computer_Datainput[66], MAC_Computer_Datainput[67], + MAC_Computer_Datainput[68], MAC_Computer_Datainput[69], + MAC_Computer_Datainput[70], MAC_Computer_Datainput[71], + MAC_Computer_Datainput[72], MAC_Computer_Datainput[73], + MAC_Computer_Datainput[74], MAC_Computer_Datainput[75], + MAC_Computer_Datainput[76], MAC_Computer_Datainput[77], + MAC_Computer_Datainput[78], MAC_Computer_Datainput[79]); + + ds_dbg("host mac:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + CAL_MAC[0], CAL_MAC[1], CAL_MAC[2], CAL_MAC[3], CAL_MAC[4], + CAL_MAC[5], CAL_MAC[6], CAL_MAC[7], CAL_MAC[8], CAL_MAC[9], + CAL_MAC[10], CAL_MAC[11], CAL_MAC[12], CAL_MAC[13], CAL_MAC[14], + CAL_MAC[15], CAL_MAC[16], CAL_MAC[17], CAL_MAC[18], CAL_MAC[19], + CAL_MAC[20], CAL_MAC[21], CAL_MAC[22], CAL_MAC[23], CAL_MAC[24], + CAL_MAC[25], CAL_MAC[26], CAL_MAC[27], CAL_MAC[28], CAL_MAC[29], + CAL_MAC[30], CAL_MAC[31]); + + for (i = 0; i < 32; i++) { + if (CAL_MAC[i] != MAC_Read_Value[i]) + break; + } + + if (i != 32) { + flag_mi_auth_result_slave = 1; + mi_auth_result_slave = ERROR_UNMATCH_MAC; + // for debug + ds_dbg("hmac is not match. result=ERROR_UNMATCH_MAC\n"); + flag_mi_page1_data_slave = 0; + return ERROR_UNMATCH_MAC; + } else { + flag_mi_auth_result_slave = 1; + ds_dbg("hmac is match. result=DS_TRUE\n"); + mi_auth_result_slave = DS_TRUE; + return DS_TRUE; + } +} + +// retry interface start // +static int ds28el16_Read_RomID_retry_slave(unsigned char *RomID) +{ + int i; + unsigned char data[50]; + + for (i = 0; i < GET_ROM_ID_RETRY; i++) { + ds_info("read rom id communication start %d...\n", i); + if (DS28E16_cmd_readStatus_slave(data) == DS_TRUE) { + if (Read_RomID_slave(RomID) == DS_TRUE) + return DS_TRUE; + } + } + ds_log("ds28el16_Read_RomID_retry_slave fail\n"); + return DS_FALSE; +} + +static int ds28el16_get_page_status_retry_slave(unsigned char *data) +{ + int i; + + for (i = 0; i < GET_BLOCK_STATUS_RETRY; i++) { + ds_info("read page status communication start... %d\n", i); + + if (DS28E16_cmd_readStatus_slave(data) == DS_TRUE) + return DS_TRUE; + } + + return DS_FALSE; +} + +/* +static int ds28el16_set_page_status_retry(unsigned char page, unsigned char status) +{ + int i; + + for (i = 0; i < SET_BLOCK_STATUS_RETRY; i++) { + ds_info("set page status communication start... %d\n", i); + + if (DS28E16_cmd_setPageProtection_slave(page, status) == TRUE) + return DS_TRUE; + } + + return DS_FALSE; +} +*/ + +static int ds28el16_get_page_data_retry_slave(int page, unsigned char *data) +{ + int i; + + if (page >= MAX_PAGENUM) + return DS_FALSE; + + for (i = 0; i < GET_USER_MEMORY_RETRY; i++) { + ds_dbg("read page data communication start... %d\n", i); + + if (DS28E16_cmd_readMemory_slave(page, data) == DS_TRUE) { + ds_dbg("page number is %d\n", page); + ds_dbg("page data:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + data[0], data[1], data[2], data[3], data[4], + data[5], data[6], data[7], data[8], data[9], + data[10], data[11], data[12], data[13], data[14], + data[15]); + ds_dbg("flag_mi_page0_data_slave is %d\n", + flag_mi_page0_data_slave); + ds_dbg("mi_page0_data_slave data:\n"); + ds_dbg("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + mi_page0_data_slave[0], mi_page0_data_slave[1], + mi_page0_data_slave[2], mi_page0_data_slave[3], + mi_page0_data_slave[4], mi_page0_data_slave[5], + mi_page0_data_slave[6], mi_page0_data_slave[7], + mi_page0_data_slave[8], mi_page0_data_slave[9], + mi_page0_data_slave[10], mi_page0_data_slave[11], + mi_page0_data_slave[12], mi_page0_data_slave[13], + mi_page0_data_slave[14], + mi_page0_data_slave[15]); + ds_dbg("flag_mi_page1_data_slave is %d\n", + flag_mi_page1_data_slave); + ds_dbg("mi_page1_data_slave data:\n"); + ds_dbg("%%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + mi_page1_data_slave[0], mi_page1_data_slave[1], + mi_page1_data_slave[2], mi_page1_data_slave[3], + mi_page1_data_slave[4], mi_page1_data_slave[5], + mi_page1_data_slave[6], mi_page1_data_slave[7], + mi_page1_data_slave[8], mi_page1_data_slave[9], + mi_page1_data_slave[10], mi_page1_data_slave[11], + mi_page1_data_slave[12], mi_page1_data_slave[13], + mi_page1_data_slave[14], + mi_page1_data_slave[15]); + ds_dbg("flag_mi_counter_slave is %d\n", + flag_mi_counter_slave); + return DS_TRUE; + } + } + + return DS_FALSE; +} + +static int DS28E16_cmd_computeS_Secret_retry_slave(int anon, int bdconst, + int pg, + unsigned char *partial) +{ + int i; + + if (pg >= MAX_PAGENUM) + return DS_FALSE; + + for (i = 0; i < GET_S_SECRET_RETRY; i++) { + if (DS28E16_cmd_computeS_Secret_slave(anon, bdconst, pg, + partial) == DS_TRUE) + return DS_TRUE; + } + + return DS_FALSE; +} + +static int DS28E16_cmd_computeReadPageAuthentication_retry_slave( + int anon, int pg, unsigned char *challenge_slave, unsigned char *hmac) +{ + int i; + + if (pg >= MAX_PAGENUM) + return DS_FALSE; + + for (i = 0; i < GET_MAC_RETRY; i++) { + if (DS28E16_cmd_computeReadPageAuthentication_slave( + anon, pg, challenge_slave, hmac) == DS_TRUE) + return DS_TRUE; + } + + return DS_FALSE; +} + +// retry interface end // + +/* All power supply functions here */ + +static enum power_supply_property verify_props[] = { + POWER_SUPPLY_PROP_ROMID, + POWER_SUPPLY_PROP_DS_STATUS, + POWER_SUPPLY_PROP_PAGENUMBER, + POWER_SUPPLY_PROP_PAGEDATA, + POWER_SUPPLY_PROP_AUTHEN_RESULT, + POWER_SUPPLY_PROP_SESSION_SEED, + POWER_SUPPLY_PROP_S_SECRET, + POWER_SUPPLY_PROP_CHALLENGE, + POWER_SUPPLY_PROP_AUTH_ANON, + POWER_SUPPLY_PROP_AUTH_BDCONST, + POWER_SUPPLY_PROP_PAGE0_DATA, + POWER_SUPPLY_PROP_PAGE1_DATA, + POWER_SUPPLY_PROP_VERIFY_MODEL_NAME, + POWER_SUPPLY_PROP_CHIP_OK, +}; + +static int verify_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret; + unsigned char buf[50]; + + switch (psp) { + case POWER_SUPPLY_PROP_VERIFY_MODEL_NAME: + ret = ds28el16_Read_RomID_retry_slave(mi_romid_slave); + if (ret == DS_TRUE) + val->strval = "ds28e16"; + else + val->strval = "unknown"; + break; + case POWER_SUPPLY_PROP_AUTHEN_RESULT: + if (batt_verified_result_from_uefi) { + val->intval = true; + ds_info("batt_verified_result_from_uefi is true\n"); + break; + } + ret = AuthenticateDS28E16_slave( + auth_ANON_slave, auth_BDCONST_slave, 0, + pagenumber_slave, challenge_slave, session_seed_slave, + S_secret_slave); + if (ret == DS_TRUE) + val->intval = true; + else + val->intval = false; + break; + case POWER_SUPPLY_PROP_PAGENUMBER: + val->intval = pagenumber_slave; + break; + case POWER_SUPPLY_PROP_ROMID: + ret = ds28el16_Read_RomID_retry_slave(mi_romid_slave); + memcpy(val->arrayval, mi_romid_slave, 8); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_CHIP_OK: + if (batt_chip_ok_result_from_uefi) { + val->intval = true; + ds_info("batt_chip_ok_result_from_uefi is true already\n"); + break; + } + ret = ds28el16_Read_RomID_retry_slave(mi_romid_slave); + if ((mi_romid_slave[0] == FAMILY_CODE) && + (mi_romid_slave[6] == CUSTOM_ID_MSB) && + ((mi_romid_slave[5] & 0xf0) == CUSTOM_ID_LSB)) + val->intval = true; + else + val->intval = false; + break; + case POWER_SUPPLY_PROP_DS_STATUS: + ret = ds28el16_get_page_status_retry_slave(buf); + memcpy(val->arrayval, buf, 8); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_PAGEDATA: + ret = ds28el16_get_page_data_retry_slave(pagenumber_slave, buf); + memcpy(val->arrayval, buf, 16); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_PAGE0_DATA: + ret = ds28el16_get_page_data_retry_slave(0, buf); + memcpy(val->arrayval, buf, 16); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_PAGE1_DATA: + ret = ds28el16_get_page_data_retry_slave(1, buf); + memcpy(val->arrayval, buf, 16); + if (ret != DS_TRUE) + return -EAGAIN; + break; + default: + ds_err("unsupported property %d\n", psp); + return -ENODATA; + } + + return 0; +} + +static int verify_set_property(struct power_supply *psy, + enum power_supply_property prop, + const union power_supply_propval *val) +{ + //int ret; + //unsigned char buf[50]; + + switch (prop) { + case POWER_SUPPLY_PROP_PAGENUMBER: + pagenumber_slave = val->intval; + break; + /* + case POWER_SUPPLY_PROP_PAGEDATA: + memcpy(buf, val->arrayval, 16); + ret = DS28E16_cmd_writeMemory_slave(pagenumber_slave, buf); + if (ret != DS_TRUE) + return -EAGAIN; + break; + case POWER_SUPPLY_PROP_SESSION_SEED: + memcpy(session_seed_slave, val->arrayval, 32); + break; + case POWER_SUPPLY_PROP_S_SECRET: + memcpy(S_secret_slave, val->arrayval, 32); + break; + case POWER_SUPPLY_PROP_CHALLENGE: + memcpy(challenge_slave, val->arrayval, 32); + break; +*/ + case POWER_SUPPLY_PROP_AUTH_ANON: + auth_ANON_slave = val->intval; + break; + case POWER_SUPPLY_PROP_AUTH_BDCONST: + auth_BDCONST_slave = val->intval; + break; + default: + ds_err("unsupported property %d\n", prop); + return -ENODATA; + } + + return 0; +} + +static int verify_prop_is_writeable(struct power_supply *psy, + enum power_supply_property prop) +{ + int ret; + + switch (prop) { + case POWER_SUPPLY_PROP_PAGENUMBER: + case POWER_SUPPLY_PROP_PAGEDATA: + case POWER_SUPPLY_PROP_SESSION_SEED: + case POWER_SUPPLY_PROP_S_SECRET: + case POWER_SUPPLY_PROP_CHALLENGE: + case POWER_SUPPLY_PROP_AUTH_ANON: + case POWER_SUPPLY_PROP_AUTH_BDCONST: + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +static int verify_psy_register(struct ds28e16_data *ds) +{ + struct power_supply_config verify_psy_cfg = {}; + + ds->verify_psy_d.name = "batt_verify_slave"; + ds->verify_psy_d.type = POWER_SUPPLY_TYPE_BATT_VERIFY; + ds->verify_psy_d.properties = verify_props; + ds->verify_psy_d.num_properties = ARRAY_SIZE(verify_props); + ds->verify_psy_d.get_property = verify_get_property; + ds->verify_psy_d.set_property = verify_set_property; + ds->verify_psy_d.property_is_writeable = verify_prop_is_writeable; + + verify_psy_cfg.drv_data = ds; + verify_psy_cfg.of_node = ds->dev->of_node; + verify_psy_cfg.num_supplicants = 0; + ds->verify_psy = devm_power_supply_register(ds->dev, &ds->verify_psy_d, + &verify_psy_cfg); + if (IS_ERR(ds->verify_psy)) { + ds_err("Failed to register verify_psy slave"); + return PTR_ERR(ds->verify_psy); + } + + ds_log("%s power supply register successfully\n", + ds->verify_psy_d.name); + return 0; +} + +static void verify_psy_unregister(struct ds28e16_data *ds) +{ + power_supply_unregister(ds->verify_psy); +} + +// parse dts +static int ds28e16_parse_dt(struct device *dev, struct ds28e16_data *pdata) +{ + int error, val; + struct device_node *np = dev->of_node; + + // parse version + pdata->version = 0; + error = of_property_read_u32(np, "maxim,version", &val); + if (error && (error != -EINVAL)) + ds_err("Unable to read bootloader address\n"); + else if (error != -EINVAL) + pdata->version = val; + + return 0; +} + +// read data from file +static ssize_t ds28e16_ds_Auth_Result_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int result; + + result = AuthenticateDS28E16_slave(auth_ANON_slave, auth_BDCONST_slave, + 0, pagenumber_slave, challenge_slave, + session_seed_slave, S_secret_slave); + if (result == ERROR_R_STATUS) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : ERROR_R_STATUS!\n"); + else if (result == ERROR_UNMATCH_MAC) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : MAC is not match!\n"); + else if (result == ERROR_R_ROMID) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : ERROR_R_ROMID!\n"); + else if (result == ERROR_COMPUTE_MAC) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : ERROR_COMPUTE_MAC!\n"); + else if (result == ERROR_S_SECRET) + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : ERROR_S_SECRET!\n"); + else if (result == DS_TRUE) + return scnprintf(buf, PAGE_SIZE, "Authenticate success!!!\n"); + else + return scnprintf(buf, PAGE_SIZE, + "Authenticate failed : other reason.\n"); +} + +static ssize_t ds28e16_ds_romid_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + short status; + unsigned char RomID[10] = { 0x00 }; + int i = 0; + int count = 0; + + for (i = 0; i < attr_trytimes_slave; i++) { + status = ds28el16_Read_RomID_retry_slave(RomID); + + if (status == DS_TRUE) { + count++; + ds_log("Read_RomID_slave success!\n"); + } else { + ds_log("Read_RomID_slave fail!\n"); + } + ds_dbg("RomID = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + RomID[0], RomID[1], RomID[2], RomID[3], RomID[4], + RomID[5], RomID[6], RomID[7]); + Delay_us_slave(1000); + } + + /*ds_dbg("RomID = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + RomID[0], RomID[1], RomID[2], RomID[3], + RomID[4], RomID[5], RomID[6], RomID[7]); + */ + ds_log("test done\nsuccess time : %d\n", count); + return scnprintf( + buf, PAGE_SIZE, + "Success = %d\nRomID = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + count, RomID[0], RomID[1], RomID[2], RomID[3], RomID[4], + RomID[5], RomID[6], RomID[7]); +} + +static ssize_t ds28e16_ds_pagenumber_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%02x\n", pagenumber_slave); +} + +static ssize_t ds28e16_ds_pagenumber_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int buf_int; + + if (sscanf(buf, "%d", &buf_int) != 1) + return -EINVAL; + + ds_dbg("new pagenumber_slave = %d\n", buf_int); + + if ((buf_int >= 0) && (buf_int <= 3)) + pagenumber_slave = buf_int; + + return count; +} + +static ssize_t ds28e16_ds_pagedata_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int result; + unsigned char pagedata[16] = { 0x00 }; + int i = 0; + int count = 0; + + for (i = 0; i < attr_trytimes_slave; i++) { + result = ds28el16_get_page_data_retry_slave(pagenumber_slave, + pagedata); + + if (result == DS_TRUE) { + count++; + ds_log("DS28E16_cmd_readMemory_slave success!\n"); + } else { + ds_log("DS28E16_cmd_readMemory_slave fail!\n"); + } + ds_dbg("pagedata = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + pagedata[0], pagedata[1], pagedata[2], pagedata[3], + pagedata[4], pagedata[5], pagedata[6], pagedata[7], + pagedata[8], pagedata[9], pagedata[10], pagedata[11], + pagedata[12], pagedata[13], pagedata[14], pagedata[15]); + Delay_us_slave(1000); + } + ds_log("test done\nsuccess time : %d\n", count); + return scnprintf( + buf, PAGE_SIZE, + "Success = %d\npagedata = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + count, pagedata[0], pagedata[1], pagedata[2], pagedata[3], + pagedata[4], pagedata[5], pagedata[6], pagedata[7], pagedata[8], + pagedata[9], pagedata[10], pagedata[11], pagedata[12], + pagedata[13], pagedata[14], pagedata[15]); +} + +static ssize_t ds28e16_ds_pagedata_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int result; + unsigned char pagedata[16] = { 0x00 }; + + if (sscanf(buf, + "%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx", + &pagedata[0], &pagedata[1], &pagedata[2], &pagedata[3], + &pagedata[4], &pagedata[5], &pagedata[6], &pagedata[7], + &pagedata[8], &pagedata[9], &pagedata[10], &pagedata[11], + &pagedata[12], &pagedata[13], &pagedata[14], + &pagedata[15]) != 16) + return -EINVAL; + + ds_dbg("new data = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + pagedata[0], pagedata[1], pagedata[2], pagedata[3], pagedata[4], + pagedata[5], pagedata[6], pagedata[7], pagedata[8], pagedata[9], + pagedata[10], pagedata[11], pagedata[12], pagedata[13], + pagedata[14], pagedata[15]); + + result = DS28E16_cmd_writeMemory_slave(pagenumber_slave, pagedata); + if (result == DS_TRUE) + ds_log("DS28E16_cmd_writeMemory_slave success!\n"); + else + ds_log("DS28E16_cmd_writeMemory_slave fail!\n"); + + return count; +} + +static ssize_t ds28e16_ds_time_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d\n", attr_trytimes_slave); +} + +static ssize_t ds28e16_ds_time_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int buf_int; + + if (sscanf(buf, "%d", &buf_int) != 1) + return -EINVAL; + + ds_log("new trytimes = %d\n", buf_int); + + if (buf_int > 0) + attr_trytimes_slave = buf_int; + + return count; +} + +static ssize_t +ds28e16_ds_session_seed_status_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, + "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n", + session_seed_slave[0], session_seed_slave[1], + session_seed_slave[2], session_seed_slave[3], + session_seed_slave[4], session_seed_slave[5], + session_seed_slave[6], session_seed_slave[7], + session_seed_slave[8], session_seed_slave[9], + session_seed_slave[10], session_seed_slave[11], + session_seed_slave[12], session_seed_slave[13], + session_seed_slave[14], session_seed_slave[15], + session_seed_slave[16], session_seed_slave[17], + session_seed_slave[18], session_seed_slave[19], + session_seed_slave[20], session_seed_slave[21], + session_seed_slave[22], session_seed_slave[23], + session_seed_slave[24], session_seed_slave[25], + session_seed_slave[26], session_seed_slave[27], + session_seed_slave[28], session_seed_slave[29], + session_seed_slave[30], session_seed_slave[31]); +} + +static ssize_t ds28e16_ds_session_seed_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, + "%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx", + &session_seed_slave[0], &session_seed_slave[1], + &session_seed_slave[2], &session_seed_slave[3], + &session_seed_slave[4], &session_seed_slave[5], + &session_seed_slave[6], &session_seed_slave[7], + &session_seed_slave[8], &session_seed_slave[9], + &session_seed_slave[10], &session_seed_slave[11], + &session_seed_slave[12], &session_seed_slave[13], + &session_seed_slave[14], &session_seed_slave[15], + &session_seed_slave[16], &session_seed_slave[17], + &session_seed_slave[18], &session_seed_slave[19], + &session_seed_slave[20], &session_seed_slave[21], + &session_seed_slave[22], &session_seed_slave[23], + &session_seed_slave[24], &session_seed_slave[25], + &session_seed_slave[26], &session_seed_slave[27], + &session_seed_slave[28], &session_seed_slave[29], + &session_seed_slave[30], &session_seed_slave[31]) != 32) + return -EINVAL; + + return count; +} + +static ssize_t ds28e16_ds_challenge_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, + "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n", + challenge_slave[0], challenge_slave[1], challenge_slave[2], + challenge_slave[3], challenge_slave[4], challenge_slave[5], + challenge_slave[6], challenge_slave[7], challenge_slave[8], + challenge_slave[9], challenge_slave[10], challenge_slave[11], + challenge_slave[12], challenge_slave[13], challenge_slave[14], + challenge_slave[15], challenge_slave[16], challenge_slave[17], + challenge_slave[18], challenge_slave[19], challenge_slave[20], + challenge_slave[21], challenge_slave[22], challenge_slave[23], + challenge_slave[24], challenge_slave[25], challenge_slave[26], + challenge_slave[27], challenge_slave[28], challenge_slave[29], + challenge_slave[30], challenge_slave[31]); +} + +static ssize_t ds28e16_ds_challenge_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, + "%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx", + &challenge_slave[0], &challenge_slave[1], + &challenge_slave[2], &challenge_slave[3], + &challenge_slave[4], &challenge_slave[5], + &challenge_slave[6], &challenge_slave[7], + &challenge_slave[8], &challenge_slave[9], + &challenge_slave[10], &challenge_slave[11], + &challenge_slave[12], &challenge_slave[13], + &challenge_slave[14], &challenge_slave[15], + &challenge_slave[16], &challenge_slave[17], + &challenge_slave[18], &challenge_slave[19], + &challenge_slave[20], &challenge_slave[21], + &challenge_slave[22], &challenge_slave[23], + &challenge_slave[24], &challenge_slave[25], + &challenge_slave[26], &challenge_slave[27], + &challenge_slave[28], &challenge_slave[29], + &challenge_slave[30], &challenge_slave[31]) != 32) + return -EINVAL; + + return count; +} + +static ssize_t ds28e16_ds_S_secret_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, + "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,\n", + S_secret_slave[0], S_secret_slave[1], S_secret_slave[2], + S_secret_slave[3], S_secret_slave[4], S_secret_slave[5], + S_secret_slave[6], S_secret_slave[7], S_secret_slave[8], + S_secret_slave[9], S_secret_slave[10], S_secret_slave[11], + S_secret_slave[12], S_secret_slave[13], S_secret_slave[14], + S_secret_slave[15], S_secret_slave[16], S_secret_slave[17], + S_secret_slave[18], S_secret_slave[19], S_secret_slave[20], + S_secret_slave[21], S_secret_slave[22], S_secret_slave[23], + S_secret_slave[24], S_secret_slave[25], S_secret_slave[26], + S_secret_slave[27], S_secret_slave[28], S_secret_slave[29], + S_secret_slave[30], S_secret_slave[31]); +} + +static ssize_t ds28e16_ds_S_secret_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, + "%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx,%2hhx", + &S_secret_slave[0], &S_secret_slave[1], &S_secret_slave[2], + &S_secret_slave[3], &S_secret_slave[4], &S_secret_slave[5], + &S_secret_slave[6], &S_secret_slave[7], &S_secret_slave[8], + &S_secret_slave[9], &S_secret_slave[10], &S_secret_slave[11], + &S_secret_slave[12], &S_secret_slave[13], + &S_secret_slave[14], &S_secret_slave[15], + &S_secret_slave[16], &S_secret_slave[17], + &S_secret_slave[18], &S_secret_slave[19], + &S_secret_slave[20], &S_secret_slave[21], + &S_secret_slave[22], &S_secret_slave[23], + &S_secret_slave[24], &S_secret_slave[25], + &S_secret_slave[26], &S_secret_slave[27], + &S_secret_slave[28], &S_secret_slave[29], + &S_secret_slave[30], &S_secret_slave[31]) != 32) + return -EINVAL; + + return count; +} + +static ssize_t ds28e16_ds_auth_ANON_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%02x\n", auth_ANON_slave); +} + +static ssize_t ds28e16_ds_auth_ANON_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, "%d", &auth_ANON_slave) != 1) + return -EINVAL; + + return count; +} + +static ssize_t +ds28e16_ds_auth_BDCONST_status_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%02x\n", auth_BDCONST_slave); +} + +static ssize_t ds28e16_ds_auth_BDCONST_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (sscanf(buf, "%d", &auth_BDCONST_slave) != 1) + return -EINVAL; + + return count; +} + +static ssize_t ds28e16_ds_readstatus_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int result; + unsigned char status[16] = { 0x00 }; + int i = 0; + int count = 0; + + for (i = 0; i < attr_trytimes_slave; i++) { + result = ds28el16_get_page_status_retry_slave(status); + + if (result == DS_TRUE) { + count++; + ds_log("DS28E16_cmd_readStatus_slave success!\n"); + } else { + ds_log("DS28E16_cmd_readStatus_slave fail!\n"); + } + ds_dbg("Status = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + status[0], status[1], status[2], status[3], status[4], + status[5], status[6], status[7], status[8], status[9], + status[10], status[11], status[12], status[13], + status[14], status[15]); + Delay_us_slave(1000); + } + ds_log("test done\nsuccess time : %d\n", count); + return scnprintf( + buf, PAGE_SIZE, + "Success = %d\nStatus = %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + count, status[0], status[1], status[2], status[3], status[4], + status[5], status[6], status[7], status[8], status[9], + status[10], status[11], status[12], status[13], status[14], + status[15]); +} + +static DEVICE_ATTR(ds_readstatus, S_IRUGO, ds28e16_ds_readstatus_status_read, + NULL); +static DEVICE_ATTR(ds_romid, S_IRUGO, ds28e16_ds_romid_status_read, NULL); +static DEVICE_ATTR(ds_pagenumber, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_pagenumber_status_read, + ds28e16_ds_pagenumber_store); +static DEVICE_ATTR(ds_pagedata, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_pagedata_status_read, ds28e16_ds_pagedata_store); +static DEVICE_ATTR(ds_time, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_time_status_read, ds28e16_ds_time_store); +static DEVICE_ATTR(ds_session_seed, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_session_seed_status_read, + ds28e16_ds_session_seed_store); +static DEVICE_ATTR(ds_challenge, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_challenge_status_read, + ds28e16_ds_challenge_store); +static DEVICE_ATTR(ds_S_secret, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_S_secret_status_read, ds28e16_ds_S_secret_store); +static DEVICE_ATTR(ds_auth_ANON, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_auth_ANON_status_read, + ds28e16_ds_auth_ANON_store); +static DEVICE_ATTR(ds_auth_BDCONST, S_IRUGO | S_IWUSR | S_IWGRP, + ds28e16_ds_auth_BDCONST_status_read, + ds28e16_ds_auth_BDCONST_store); +static DEVICE_ATTR(ds_Auth_Result, S_IRUGO, ds28e16_ds_Auth_Result_status_read, + NULL); + +static struct attribute *ds_attributes[] = { + &dev_attr_ds_readstatus.attr, &dev_attr_ds_romid.attr, + &dev_attr_ds_pagenumber.attr, &dev_attr_ds_pagedata.attr, + &dev_attr_ds_time.attr, &dev_attr_ds_session_seed.attr, + &dev_attr_ds_challenge.attr, &dev_attr_ds_S_secret.attr, + &dev_attr_ds_auth_ANON.attr, &dev_attr_ds_auth_BDCONST.attr, + &dev_attr_ds_Auth_Result.attr, NULL, +}; + +static const struct attribute_group ds_attr_group = { + .attrs = ds_attributes, +}; + +static int authentic_period_ms = 5000; +#define AUTHENTIC_COUNT_MAX 5 +static int retry_authentic; +static void authentic_work(struct work_struct *work) +{ + int rc; + union power_supply_propval pval = { + 0, + }; + + struct ds28e16_data *ds28e16_data = + container_of(work, struct ds28e16_data, authentic_work.work); + + rc = power_supply_get_property(ds28e16_data->verify_psy, + POWER_SUPPLY_PROP_AUTHEN_RESULT, &pval); + if (pval.intval != true) { + retry_authentic++; + if (retry_authentic < AUTHENTIC_COUNT_MAX) { + ds_log("battery authentic work begin to restart, retry = %d\n", + retry_authentic); + schedule_delayed_work( + &ds28e16_data->authentic_work, + msecs_to_jiffies(authentic_period_ms)); + } + + if (retry_authentic == AUTHENTIC_COUNT_MAX) { + ds_log("authentic result is %d\n", pval.intval); + } + } else { + ds_log("authentic result is %d\n", pval.intval); + } +} + +static int ds28e16_probe(struct platform_device *pdev) +{ + int retval = 0; + struct ds28e16_data *ds28e16_data; + union power_supply_propval b_val = { + 0, + }; + + ds_log("%s entry.", __func__); + ds_dbg("platform_device is %s", pdev->name); + if (strcmp(pdev->name, "soc:maxim_ds28e16_slave") != 0) + return -ENODEV; + + if (!pdev->dev.of_node || !of_device_is_available(pdev->dev.of_node)) + return -ENODEV; + + if (pdev->dev.of_node) { + ds28e16_data = devm_kzalloc( + &pdev->dev, sizeof(struct ds28e16_data), GFP_KERNEL); + if (!ds28e16_data) { + ds_err("Failed to allocate memory\n"); + return -ENOMEM; + } + + retval = ds28e16_parse_dt(&pdev->dev, ds28e16_data); + if (retval) { + retval = -EINVAL; + goto ds28e16_parse_dt_err; + } + } else { + ds28e16_data = pdev->dev.platform_data; + } + + if (!ds28e16_data) { + ds_err("No platform data found\n"); + return -EINVAL; + } + + ds28e16_data->dev = &pdev->dev; + ds28e16_data->pdev = pdev; + platform_set_drvdata(pdev, ds28e16_data); + INIT_DELAYED_WORK(&ds28e16_data->authentic_work, authentic_work); + + retval = verify_psy_register(ds28e16_data); + if (retval) { + ds_err("Failed to verify_psy_register, err:%d\n", retval); + goto ds28e16_psy_register_err; + } + + retval = sysfs_create_group(&ds28e16_data->dev->kobj, &ds_attr_group); + if (retval) { + ds_err("Failed to register sysfs, err:%d\n", retval); + goto ds28e16_create_group_err; + } + + retval = power_supply_get_property(ds28e16_data->verify_psy, + POWER_SUPPLY_PROP_AUTHEN_RESULT, + &b_val); + if (b_val.intval != true) { + schedule_delayed_work(&ds28e16_data->authentic_work, + msecs_to_jiffies(0)); + } + return 0; + +ds28e16_create_group_err: +//sysfs_remove_groups(&ds28e16_data->dev->kobj, &(&ds_attr_group)); +ds28e16_psy_register_err: + dev_set_drvdata(ds28e16_data->dev, NULL); +ds28e16_parse_dt_err: + kfree(ds28e16_data); + return retval; +} + +static int ds28e16_remove(struct platform_device *pdev) +{ + struct ds28e16_data *ds28e16_data = platform_get_drvdata(pdev); + + verify_psy_unregister(ds28e16_data); + kfree(ds28e16_data); + return 0; +} + +static long ds28e16_dev_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + ds_log("%d, cmd: 0x%x\n", __LINE__, cmd); + return 0; +} +static int ds28e16_dev_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int ds28e16_dev_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations ds28e16_dev_fops = { + .owner = THIS_MODULE, + .open = ds28e16_dev_open, + .unlocked_ioctl = ds28e16_dev_ioctl, + .release = ds28e16_dev_release, +}; + +static const struct of_device_id ds28e16_dt_match[] = { + { .compatible = "maxim,ds28e16_slave" }, + {}, +}; + +static struct platform_driver ds28e16_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "maxim_ds28e16_slave", + .of_match_table = ds28e16_dt_match, + }, + .probe = ds28e16_probe, + .remove = ds28e16_remove, +}; + +static int __init ds28e16_init(void) +{ + ds_log("%s entry.", __func__); + + return platform_driver_register(&ds28e16_driver); +} + +static void __exit ds28e16_exit(void) +{ + ds_log("%s entry.", __func__); + platform_driver_unregister(&ds28e16_driver); +} + +static int __init early_parse_batt_verified_result(char *p) +{ + if (*(p + 2) == '1') { + batt_verified_result_from_uefi = true; + } else { + batt_verified_result_from_uefi = false; + } + if (*(p + 3) == '1') { + batt_chip_ok_result_from_uefi = true; + } else { + batt_chip_ok_result_from_uefi = false; + } + + return 0; +} + +early_param("androidboot.batt_verified_result", + early_parse_batt_verified_result); + +module_init(ds28e16_init); +module_exit(ds28e16_exit); + +MODULE_AUTHOR("xiaomi Inc."); +MODULE_DESCRIPTION("ds28e16 driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/power/supply/maxim/ds28e16_slave.h b/drivers/power/supply/maxim/ds28e16_slave.h new file mode 100644 index 000000000000..dc1cbf3a9165 --- /dev/null +++ b/drivers/power/supply/maxim/ds28e16_slave.h @@ -0,0 +1,58 @@ +// DS28E16.h - Include file for DS28E16/DS28E50? +// +#ifndef __DS28E16_SLAVE_H__ +#define __DS28E16_SLAVE_H__ + +extern unsigned char last_result_byte_slave; + +// Command functions +// 1-Wire ROMID commands +unsigned char crc_low_first_slave(unsigned char *ptr, unsigned char len); +short Read_RomID_slave(unsigned char *RomID); + +// Common Functions +unsigned short docrc16_slave(unsigned short data); +int DS28E16_standard_cmd_flow_slave(unsigned char *write_buf, int delay_ms, + unsigned char *read_buf, int *read_len, + int write_len); + +// Command Functions (no high level verification) +int DS28E16_cmd_readStatus_slave( + unsigned char * + data); // 读入芯片的页é¢ä¿æŠ¤å±žæ€§ã€ä¸€ä¸ªMAN_ID字节和一个芯片版本字节,åˆè®¡6个字节 +int DS28E16_cmd_readMemory_slave( + int pg, + unsigned char * + data); // pg=0,1,2页é¢ï¼Œä¸€æ¬¡è¯»å…¥32个字节,å‰16个字节为有效数æ®ï¼ŒåŽç»­16个字节固定为0x00或0xFF +int DS28E16_cmd_writeMemory_slave( + int pg, unsigned char *data); // pg=0,1,2页é¢ï¼Œä¸€æ¬¡å¿…须完整写入16个字节 +int DS28E16_cmd_decrementCounter_slave( + void); // 执行此函数,完æˆ17ä½è®¡æ•°å™¨å‡1æ“作 +int DS28E16_cmd_setPageProtection_slave( + int pg, unsigned char prot); // 设置芯片的页é¢å±žæ€§ +int DS28E16_cmd_device_disable_slave( + int op, unsigned char *password); // 芯片自æ¯ï¼Œä¸èƒ½æ¢å¤ +int DS28E16_cmd_computeReadPageAuthentication_slave( + int anon, int pg, unsigned char *challenge, + unsigned char * + hmac); // 器件基于会è¯å¯†ç ã€éšæœºæ•°ã€é¡µé¢æ•°æ®å’ŒROMID,返回器件的算法结果 +int DS28E16_cmd_computeS_Secret_slave( + int anon, int bdconst, int pg, + unsigned char + *partial); // 基于主机å‘é€çš„密钥ç§å­ï¼Œå™¨ä»¶åœ¨å†…部计算出会è¯å¯†ç  + +// host functions +int AuthenticateDS28E16_slave(int anon, int bdconst, int S_Secret_PageNum, + int PageNum, unsigned char *Challenge, + unsigned char *Secret_Seeds, + unsigned char *S_Secret); + +static int ds28el16_Read_RomID_retry_slave(unsigned char *RomID); +static int ds28el16_get_page_status_retry_slave(unsigned char *data); +static int DS28E16_cmd_computeS_Secret_retry_slave(int anon, int bdconst, + int pg, + unsigned char *session_seed); +static int DS28E16_cmd_computeReadPageAuthentication_retry_slave( + int anon, int pg, unsigned char *challenge, unsigned char *hmac); +static int ds28el16_get_page_data_retry_slave(int page, unsigned char *data); +#endif diff --git a/drivers/power/supply/maxim/onewire_gpio.c b/drivers/power/supply/maxim/onewire_gpio.c new file mode 100644 index 000000000000..e9ece5dc3eaa --- /dev/null +++ b/drivers/power/supply/maxim/onewire_gpio.c @@ -0,0 +1,613 @@ +/* + * Copyright (c) 2016 xiaomi Inc. + */ +#define pr_fmt(fmt) "[Onewire] %s: " fmt, __func__ + +#include /* kfree() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ow_info pr_err +#define ow_dbg pr_err +#define ow_err pr_err +#define ow_log pr_err + +#define DRV_STRENGTH_16MA (0x7 << 6) +#define DRV_STRENGTH_4MA (0x1 << 6) +#define GPIO_OUTPUT (0x1 << 9) +#define GPIO_INPUT (0x0 << 9) +#define GPIO_PULL_UP 0x3 +#define OUTPUT_HIGH (0x1 << 1) +#define OUTPUT_LOW 0x1 + +#define ONE_WIRE_CONFIG_OUT \ + writel_relaxed(DRV_STRENGTH_16MA | GPIO_OUTPUT | GPIO_PULL_UP, \ + g_onewire_data->gpio_cfg66_reg) // OUT +#define ONE_WIRE_CONFIG_IN \ + writel_relaxed(DRV_STRENGTH_16MA | GPIO_INPUT | GPIO_PULL_UP, \ + g_onewire_data->gpio_cfg66_reg) // IN +#define ONE_WIRE_OUT_HIGH \ + writel_relaxed(OUTPUT_HIGH, g_onewire_data->gpio_in_out_reg) // OUT: 1 +#define ONE_WIRE_OUT_LOW \ + writel_relaxed(OUTPUT_LOW, g_onewire_data->gpio_in_out_reg) // OUT: 0 + +struct onewire_gpio_data { + struct platform_device *pdev; + struct device *dev; + + int ow_gpio; + + struct gpio_desc *ow_gpio_desc; + struct gpio_chip *ow_gpio_chip; + void *gpio_in_out_reg; + void *gpio_cfg66_reg; + + raw_spinlock_t lock; + + struct pinctrl *ow_gpio_pinctrl; + struct pinctrl_state *pinctrl_state_active; + struct pinctrl_state *pinctrl_state_sleep; + + int version; + + int gpio_num; + + unsigned int onewire_gpio_cfg_addr; + unsigned int onewire_gpio_level_addr; + unsigned int gpio_offset; + unsigned int gpio_reg[2]; +}; + +static struct class *onewire_class; +static int onewire_major; + +static int onewire_gpio_detected; +static struct onewire_gpio_data *g_onewire_data; + +void Delay_us(unsigned int T) +{ + udelay(T); +} +EXPORT_SYMBOL(Delay_us); + +void Delay_ns(unsigned int T) +{ + ndelay(T); +} +EXPORT_SYMBOL(Delay_ns); + +unsigned char ow_reset(void) +{ + unsigned char presence = 0xFF; + unsigned long flags; + + raw_spin_lock_irqsave(&g_onewire_data->lock, flags); + + ONE_WIRE_CONFIG_OUT; + ONE_WIRE_OUT_LOW; + Delay_us(50); // 48 + ONE_WIRE_OUT_HIGH; + ONE_WIRE_CONFIG_IN; + Delay_us(7); + presence = + (unsigned char)readl_relaxed(g_onewire_data->gpio_in_out_reg) & + 0x01; // Read + Delay_us(50); + + raw_spin_unlock_irqrestore(&g_onewire_data->lock, flags); + return presence; +} +EXPORT_SYMBOL(ow_reset); + +unsigned char read_bit(void) +{ + unsigned int vamm; + + ONE_WIRE_CONFIG_OUT; + ONE_WIRE_OUT_LOW; + Delay_us(1); //// + ONE_WIRE_CONFIG_IN; + Delay_ns(500); // + vamm = readl_relaxed(g_onewire_data->gpio_in_out_reg); // Read + Delay_us(5); + ONE_WIRE_OUT_HIGH; + ONE_WIRE_CONFIG_OUT; + Delay_us(6); + return ((unsigned char)vamm & 0x01); +} + +void write_bit(char bitval) +{ + ONE_WIRE_OUT_LOW; + Delay_us(1); // + if (bitval != 0) + ONE_WIRE_OUT_HIGH; + Delay_us(10); + ONE_WIRE_OUT_HIGH; + Delay_us(6); +} + +unsigned char read_byte(void) +{ + unsigned char i; + unsigned char value = 0; + unsigned long flags; + + raw_spin_lock_irqsave(&g_onewire_data->lock, flags); + for (i = 0; i < 8; i++) { + if (read_bit()) + value |= + 0x01 + << i; // reads byte in, one byte at a time and then shifts it left + } + + raw_spin_unlock_irqrestore(&g_onewire_data->lock, flags); + return value; +} +EXPORT_SYMBOL(read_byte); + +void write_byte(char val) +{ + unsigned char i; + unsigned char temp; + unsigned long flags; + + raw_spin_lock_irqsave(&g_onewire_data->lock, flags); + ONE_WIRE_CONFIG_OUT; + // writes byte, one bit at a time + for (i = 0; i < 8; i++) { + temp = val >> i; // shifts val right ‘i’ spaces + temp &= 0x01; // copy that bit to temp + write_bit(temp); // write bit in temp into + } + raw_spin_unlock_irqrestore(&g_onewire_data->lock, flags); +} +EXPORT_SYMBOL(write_byte); + +int onewire_gpio_get_status(void) +{ + return onewire_gpio_detected; +} +EXPORT_SYMBOL(onewire_gpio_get_status); + +// parse dts +static int onewire_gpio_parse_dt(struct device *dev, + struct onewire_gpio_data *pdata) +{ + int error, val; + struct device_node *np = dev->of_node; + + // parse version + pdata->version = 0; + error = of_property_read_u32(np, "xiaomi,version", &val); + if (error && (error != -EINVAL)) + ow_err("Unable to read version\n"); + else if (error != -EINVAL) + pdata->version = val; + + // parse gpio + pdata->ow_gpio = of_get_named_gpio_flags(np, "xiaomi,ow_gpio", 0, NULL); + ow_dbg("ow_gpio: %d\n", pdata->ow_gpio); + + // parse gpio_num + pdata->gpio_num = 0; + error = of_property_read_u32(np, "xiaomi,gpio_number", &val); + if (error && (error != -EINVAL)) + ow_err("Unable to read gpio number\n"); + else if (error != -EINVAL) + pdata->gpio_num = val; + + error = of_property_read_u32_array(np, "mi,onewire-gpio-cfg-addr", + pdata->gpio_reg, 2); + if (error < 0) + ow_err("Unable to read onewire gpio addr\n"); + + pdata->onewire_gpio_cfg_addr = pdata->gpio_reg[0]; + pdata->gpio_offset = pdata->gpio_reg[1]; + pdata->onewire_gpio_level_addr = + pdata->onewire_gpio_cfg_addr + pdata->gpio_offset; + + return 0; +} + +// pinctrl init +static int onewire_gpio_pinctrl_init(struct onewire_gpio_data *onewire_data) +{ + int retval; + + onewire_data->ow_gpio_pinctrl = + devm_pinctrl_get(&onewire_data->pdev->dev); + if (IS_ERR_OR_NULL(onewire_data->ow_gpio_pinctrl)) { + retval = PTR_ERR(onewire_data->ow_gpio_pinctrl); + ow_err("Target does not use pinctrl %d\n", retval); + goto ow_gpio_err_pinctrl_get; + } + + onewire_data->pinctrl_state_active = pinctrl_lookup_state( + onewire_data->ow_gpio_pinctrl, "onewire_active"); + if (IS_ERR_OR_NULL(onewire_data->pinctrl_state_active)) { + retval = PTR_ERR(onewire_data->pinctrl_state_active); + ow_err("Can not lookup onewire_active pinstate %d\n", retval); + goto ow_gpio_err_pinctrl_lookup; + } + + onewire_data->pinctrl_state_sleep = pinctrl_lookup_state( + onewire_data->ow_gpio_pinctrl, "onewire_sleep"); + if (IS_ERR_OR_NULL(onewire_data->pinctrl_state_sleep)) { + retval = PTR_ERR(onewire_data->pinctrl_state_sleep); + ow_err("Can not lookup onewire_sleep pinstate %d\n", retval); + goto ow_gpio_err_pinctrl_lookup; + } + + return 0; + +ow_gpio_err_pinctrl_get: + devm_pinctrl_put(onewire_data->ow_gpio_pinctrl); +ow_gpio_err_pinctrl_lookup: + onewire_data->ow_gpio_pinctrl = NULL; + + return retval; +} + +// read data from file +static ssize_t onewire_gpio_ow_gpio_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int status; + struct onewire_gpio_data *onewire_data = dev_get_drvdata(dev); + + status = gpio_get_value(onewire_data->ow_gpio); + + return scnprintf(buf, PAGE_SIZE, "%d", status); +} + +// write data to file +static ssize_t onewire_gpio_ow_gpio_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned char result = 0x01; + int buf_int; + unsigned char i; + unsigned char RomID[8] = { 0 }; + + if (sscanf(buf, "%1u", &buf_int) != 1) + return -EINVAL; + + if (buf_int == 0) { + ONE_WIRE_OUT_LOW; + ow_log("gpio : OUT 0"); + } else if (buf_int == 1) { + ONE_WIRE_OUT_HIGH; + ow_log("gpio : OUT 1"); + } else if (buf_int == 2) { + ONE_WIRE_CONFIG_OUT; + ow_log("gpio : OUT"); + } else if (buf_int == 3) { + ONE_WIRE_CONFIG_IN; + ow_log("gpio : IN"); + } else if (buf_int == 4) { + result = ow_reset(); + if (result) + ow_log("ow_reset: no device.result = %02x", result); + else + ow_log("ow_reset: device exist.result = %02x", result); + } else if (buf_int == 5) { + result = read_bit(); + ow_log("read_bit: %02x", result); + } else if (buf_int == 6) { + write_bit(0x01); + ow_log("write_bit 0"); + } else if (buf_int == 7) { + result = ow_reset(); + if (result) + ow_log("ow_reset: no device.result = %02x", result); + else + ow_log("ow_reset: device exist.result = %02x", result); + + ow_dbg("Ready to write 0x33 to maxim IC!\n"); + write_byte(0x33); + + for (i = 0; i < 8; i++) + RomID[i] = read_byte(); + + ow_log("RomID = %02x%02x%02x%02x%02x%02x%02x%02x\n", RomID[0], + RomID[1], RomID[2], RomID[3], RomID[4], RomID[5], + RomID[6], RomID[7]); + } else if (buf_int == 8) { + ONE_WIRE_CONFIG_OUT; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + + Delay_us(1000); + ONE_WIRE_OUT_HIGH; + Delay_us(1); + ONE_WIRE_OUT_LOW; + Delay_us(1); + ONE_WIRE_OUT_HIGH; + Delay_us(1); + ONE_WIRE_OUT_LOW; + Delay_us(1); + ONE_WIRE_OUT_HIGH; + Delay_us(1); + ONE_WIRE_OUT_LOW; + Delay_us(1); + ONE_WIRE_OUT_HIGH; + Delay_us(1); + ONE_WIRE_OUT_LOW; + Delay_us(1); + ONE_WIRE_OUT_HIGH; + Delay_us(1); + ONE_WIRE_OUT_LOW; + Delay_us(1); + + Delay_us(1000); + ONE_WIRE_OUT_HIGH; + Delay_us(5); + ONE_WIRE_OUT_LOW; + Delay_us(5); + ONE_WIRE_OUT_HIGH; + Delay_us(5); + ONE_WIRE_OUT_LOW; + Delay_us(5); + ONE_WIRE_OUT_HIGH; + Delay_us(5); + ONE_WIRE_OUT_LOW; + Delay_us(5); + ONE_WIRE_OUT_HIGH; + Delay_us(5); + ONE_WIRE_OUT_LOW; + Delay_us(5); + ONE_WIRE_OUT_HIGH; + Delay_us(5); + ONE_WIRE_OUT_LOW; + Delay_us(5); + } + + return count; +} + +static DEVICE_ATTR(ow_gpio, S_IRUGO | S_IWUSR | S_IWGRP, + onewire_gpio_ow_gpio_status_read, + onewire_gpio_ow_gpio_store); + +static int onewire_gpio_probe(struct platform_device *pdev) +{ + int retval = 0; + struct onewire_gpio_data *onewire_data; + struct kobject *p; + + ow_log("onewire probe entry"); + + if (!pdev->dev.of_node || !of_device_is_available(pdev->dev.of_node)) + return -ENODEV; + ow_log("lvchen1\n"); + if (pdev->dev.of_node) { + onewire_data = devm_kzalloc(&pdev->dev, + sizeof(struct onewire_gpio_data), + GFP_KERNEL); + if (!onewire_data) { + ow_err("Failed to allocate memory\n"); + return -ENOMEM; + } + ow_log("lvchen2\n"); + retval = onewire_gpio_parse_dt(&pdev->dev, onewire_data); + if (retval) { + retval = -EINVAL; + ow_log("lvchen3\n"); + goto onewire_parse_dt_err; + } + } else { + onewire_data = pdev->dev.platform_data; + } + ow_log("lvchen4\n"); + if (!onewire_data) { + ow_err("No platform data found\n"); + return -EINVAL; + } + ow_log("lvchen5\n"); + g_onewire_data = onewire_data; + onewire_data->pdev = pdev; + platform_set_drvdata(pdev, onewire_data); + + raw_spin_lock_init(&g_onewire_data->lock); + + // pinctrl init + retval = onewire_gpio_pinctrl_init(onewire_data); + if (!retval && onewire_data->ow_gpio_pinctrl) { + retval = pinctrl_select_state( + onewire_data->ow_gpio_pinctrl, + onewire_data->pinctrl_state_active); + if (retval < 0) + ow_err("Failed to select active pinstate %d\n", retval); + } + if (retval) + goto onewire_pinctrl_err; + ow_log("lvchen6\n"); + // request onewire gpio + gpio_free(onewire_data->ow_gpio); + if (gpio_is_valid(onewire_data->ow_gpio)) { + retval = gpio_request(onewire_data->ow_gpio, "onewire gpio"); + } else { + retval = -EINVAL; + } + if (retval) { + ow_err("request onewire gpio failed, retval=%d\n", retval); + goto onewire_ow_gpio_err; + } + ow_log("lvchen7\n"); + // gpio output 1 + gpio_direction_output(onewire_data->ow_gpio, 1); + + onewire_data->ow_gpio_desc = gpio_to_desc(onewire_data->ow_gpio); + onewire_data->ow_gpio_chip = gpiod_to_chip(onewire_data->ow_gpio_desc); + + onewire_data->gpio_in_out_reg = devm_ioremap( + &pdev->dev, (uint32_t)onewire_data->onewire_gpio_level_addr, + 0x4); + onewire_data->gpio_cfg66_reg = devm_ioremap( + &pdev->dev, (uint32_t)onewire_data->onewire_gpio_cfg_addr, 0x4); + ow_log("onewire_gpio_level_addr is %x; onewire_gpio_cfg_addr is %x", + (uint32_t)(onewire_data->onewire_gpio_level_addr), + (uint32_t)(onewire_data->onewire_gpio_cfg_addr)); + ow_log("onewire_data->gpio_cfg66_reg is %x; onewire_data->gpio_in_out_reg is %x", + (uint32_t)(onewire_data->gpio_cfg66_reg), + (uint32_t)(onewire_data->gpio_in_out_reg)); + + // create device node + onewire_data->dev = + device_create(onewire_class, pdev->dev.parent->parent, + onewire_major, onewire_data, "onewirectrl"); + if (IS_ERR(onewire_data->dev)) { + ow_err("Failed to create interface device\n"); + goto onewire_interface_dev_create_err; + } + ow_log("lvchen8\n"); + p = &onewire_data->dev->kobj; + + // create attr file + retval = sysfs_create_file(p, &dev_attr_ow_gpio.attr); + if (retval < 0) { + ow_err("Failed to create sysfs attr file\n"); + goto onewire_sysfs_ow_gpio_err; + } + ow_log("lvchen9\n"); + retval = sysfs_create_link(&onewire_data->dev->kobj, &pdev->dev.kobj, + "pltdev"); + if (retval) { + ow_err("Failed to create sysfs link\n"); + goto onewire_syfs_create_link_err; + } + ow_log("lvchen10\n"); + return 0; +onewire_syfs_create_link_err: + if (gpio_is_valid(onewire_data->ow_gpio)) + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_ow_gpio.attr); +onewire_sysfs_ow_gpio_err: + device_destroy(onewire_class, onewire_major); +onewire_interface_dev_create_err: + if (gpio_is_valid(onewire_data->ow_gpio)) + gpio_free(onewire_data->ow_gpio); +onewire_ow_gpio_err: +onewire_pinctrl_err: +onewire_parse_dt_err: + kfree(onewire_data); + return retval; +} + +static int onewire_gpio_remove(struct platform_device *pdev) +{ + struct onewire_gpio_data *onewire_data = platform_get_drvdata(pdev); + + if (gpio_is_valid(onewire_data->ow_gpio)) { + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_ow_gpio.attr); + gpio_free(onewire_data->ow_gpio); + } + kfree(onewire_data); + + return 0; +} + +static long onewire_dev_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + ow_dbg("%d, cmd: 0x%x\n", __LINE__, cmd); + return 0; +} +static int onewire_dev_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int onewire_dev_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations onewire_dev_fops = { + .owner = THIS_MODULE, + .open = onewire_dev_open, + .unlocked_ioctl = onewire_dev_ioctl, + .release = onewire_dev_release, +}; + +static const struct of_device_id onewire_gpio_dt_match[] = { + { .compatible = "xiaomi,onewire_gpio" }, + {}, +}; + +static struct platform_driver onewire_gpio_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "onewire_gpio", + .of_match_table = onewire_gpio_dt_match, + }, + .probe = onewire_gpio_probe, + .remove = onewire_gpio_remove, +}; + +static int __init onewire_gpio_init(void) +{ + int retval; + onewire_gpio_detected = false; + + ow_log("onewire gpio init entry."); + + onewire_class = class_create(THIS_MODULE, "onewire"); + if (IS_ERR(onewire_class)) { + ow_err("coudn't create class"); + return PTR_ERR(onewire_class); + } + + onewire_major = register_chrdev(0, "onewirectrl", &onewire_dev_fops); + if (onewire_major < 0) { + ow_err("failed to allocate char dev\n"); + retval = onewire_major; + goto class_unreg; + } + + return platform_driver_register(&onewire_gpio_driver); + +class_unreg: + class_destroy(onewire_class); + return retval; +} + +static void __exit onewire_gpio_exit(void) +{ + ow_log("onewire gpio exit entry."); + platform_driver_unregister(&onewire_gpio_driver); + + unregister_chrdev(onewire_major, "onewirectrl"); + class_destroy(onewire_class); +} + +module_init(onewire_gpio_init); +module_exit(onewire_gpio_exit); + +MODULE_AUTHOR("xiaomi Inc."); +MODULE_DESCRIPTION("onewire driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/power/supply/maxim/onewire_gpio.h b/drivers/power/supply/maxim/onewire_gpio.h new file mode 100644 index 000000000000..f62e4a73fb76 --- /dev/null +++ b/drivers/power/supply/maxim/onewire_gpio.h @@ -0,0 +1,10 @@ +#ifndef __ONEWIRE_GPIO_H__ +#define __ONEWIRE_GPIO_H__ + +void Delay_us(unsigned int T); +void Delay_ns(unsigned int T); +unsigned char ow_reset(void); +unsigned char read_byte(void); +void write_byte(char val); + +#endif diff --git a/drivers/power/supply/maxim/onewire_gpio_master.c b/drivers/power/supply/maxim/onewire_gpio_master.c new file mode 100644 index 000000000000..b7c6ec642f85 --- /dev/null +++ b/drivers/power/supply/maxim/onewire_gpio_master.c @@ -0,0 +1,604 @@ +/* + * Copyright (c) 2016 xiaomi Inc. + * Copyright (C) 2021 XiaoMi, Inc. + */ +#define pr_fmt(fmt) "[Onewire] %s: " fmt, __func__ + +#include /* kfree() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ow_info pr_err +#define ow_dbg pr_err +#define ow_err pr_err +#define ow_log pr_err + +#define DRV_STRENGTH_16MA (0x7 << 6) +#define DRV_STRENGTH_4MA (0x1 << 6) +#define GPIO_OUTPUT (0x1 << 9) +#define GPIO_INPUT (0x0 << 9) +#define GPIO_PULL_UP 0x3 +#define OUTPUT_HIGH (0x1 << 1) +#define OUTPUT_LOW 0x1 + +#define ONE_WIRE_CONFIG_OUT \ + writel_relaxed(DRV_STRENGTH_16MA | GPIO_OUTPUT | GPIO_PULL_UP, \ + g_onewire_data->gpio_cfg66_reg) // OUT +#define ONE_WIRE_CONFIG_IN \ + writel_relaxed(DRV_STRENGTH_16MA | GPIO_INPUT | GPIO_PULL_UP, \ + g_onewire_data->gpio_cfg66_reg) // IN +#define ONE_WIRE_OUT_HIGH \ + writel_relaxed(OUTPUT_HIGH, g_onewire_data->gpio_in_out_reg) // OUT: 1 +#define ONE_WIRE_OUT_LOW \ + writel_relaxed(OUTPUT_LOW, g_onewire_data->gpio_in_out_reg) // OUT: 0 + +struct onewire_gpio_data { + struct platform_device *pdev; + struct device *dev; + + int ow_gpio; + + struct gpio_desc *ow_gpio_desc; + struct gpio_chip *ow_gpio_chip; + void *gpio_in_out_reg; + void *gpio_cfg66_reg; + + raw_spinlock_t lock; + + struct pinctrl *ow_gpio_pinctrl; + struct pinctrl_state *pinctrl_state_active; + struct pinctrl_state *pinctrl_state_sleep; + + int version; + + int gpio_num; + + unsigned int onewire_gpio_cfg_addr; + unsigned int onewire_gpio_level_addr; + unsigned int gpio_offset; + unsigned int gpio_reg[2]; +}; + +static struct class *onewire_class; +static int onewire_major; + +static int onewire_gpio_detected; +static struct onewire_gpio_data *g_onewire_data; + +void Delay_us(unsigned int T) +{ + udelay(T); +} +EXPORT_SYMBOL(Delay_us); + +void Delay_ns(unsigned int T) +{ + ndelay(T); +} +EXPORT_SYMBOL(Delay_ns); + +unsigned char ow_reset(void) +{ + unsigned char presence = 0xFF; + unsigned long flags; + + raw_spin_lock_irqsave(&g_onewire_data->lock, flags); + + ONE_WIRE_CONFIG_OUT; + ONE_WIRE_OUT_LOW; + Delay_us(50); // 48 + ONE_WIRE_OUT_HIGH; + ONE_WIRE_CONFIG_IN; + Delay_us(7); + presence = + (unsigned char)readl_relaxed(g_onewire_data->gpio_in_out_reg) & + 0x01; // Read + Delay_us(50); + + raw_spin_unlock_irqrestore(&g_onewire_data->lock, flags); + return presence; +} +EXPORT_SYMBOL(ow_reset); + +unsigned char read_bit(void) +{ + unsigned int vamm; + + ONE_WIRE_CONFIG_OUT; + ONE_WIRE_OUT_LOW; + Delay_us(1); //// + ONE_WIRE_CONFIG_IN; + Delay_ns(500); // + vamm = readl_relaxed(g_onewire_data->gpio_in_out_reg); // Read + Delay_us(5); + ONE_WIRE_OUT_HIGH; + ONE_WIRE_CONFIG_OUT; + Delay_us(6); + return ((unsigned char)vamm & 0x01); +} + +void write_bit(char bitval) +{ + ONE_WIRE_OUT_LOW; + Delay_us(1); // + if (bitval != 0) + ONE_WIRE_OUT_HIGH; + Delay_us(10); + ONE_WIRE_OUT_HIGH; + Delay_us(6); +} + +unsigned char read_byte(void) +{ + unsigned char i; + unsigned char value = 0; + unsigned long flags; + + raw_spin_lock_irqsave(&g_onewire_data->lock, flags); + for (i = 0; i < 8; i++) { + if (read_bit()) + value |= + 0x01 + << i; // reads byte in, one byte at a time and then shifts it left + } + + raw_spin_unlock_irqrestore(&g_onewire_data->lock, flags); + return value; +} +EXPORT_SYMBOL(read_byte); + +void write_byte(char val) +{ + unsigned char i; + unsigned char temp; + unsigned long flags; + + raw_spin_lock_irqsave(&g_onewire_data->lock, flags); + ONE_WIRE_CONFIG_OUT; + // writes byte, one bit at a time + for (i = 0; i < 8; i++) { + temp = val >> i; // shifts val right ‘i’ spaces + temp &= 0x01; // copy that bit to temp + write_bit(temp); // write bit in temp into + } + raw_spin_unlock_irqrestore(&g_onewire_data->lock, flags); +} +EXPORT_SYMBOL(write_byte); + +int onewire_gpio_get_status(void) +{ + return onewire_gpio_detected; +} +EXPORT_SYMBOL(onewire_gpio_get_status); + +// parse dts +static int onewire_gpio_parse_dt(struct device *dev, + struct onewire_gpio_data *pdata) +{ + int error, val; + struct device_node *np = dev->of_node; + + // parse version + pdata->version = 0; + error = of_property_read_u32(np, "xiaomi,version", &val); + if (error && (error != -EINVAL)) + ow_err("Unable to read version\n"); + else if (error != -EINVAL) + pdata->version = val; + + // parse gpio + pdata->ow_gpio = of_get_named_gpio_flags(np, "xiaomi,ow_gpio", 0, NULL); + ow_dbg("ow_gpio: %d\n", pdata->ow_gpio); + + // parse gpio_num + pdata->gpio_num = 0; + error = of_property_read_u32(np, "xiaomi,gpio_number", &val); + if (error && (error != -EINVAL)) + ow_err("Unable to read gpio number\n"); + else if (error != -EINVAL) + pdata->gpio_num = val; + + error = of_property_read_u32_array(np, "mi,onewire-gpio-cfg-addr", + pdata->gpio_reg, 2); + if (error < 0) + ow_err("Unable to read onewire gpio addr\n"); + + pdata->onewire_gpio_cfg_addr = pdata->gpio_reg[0]; + pdata->gpio_offset = pdata->gpio_reg[1]; + pdata->onewire_gpio_level_addr = + pdata->onewire_gpio_cfg_addr + pdata->gpio_offset; + + return 0; +} + +// pinctrl init +static int onewire_gpio_pinctrl_init(struct onewire_gpio_data *onewire_data) +{ + int retval; + + onewire_data->ow_gpio_pinctrl = + devm_pinctrl_get(&onewire_data->pdev->dev); + if (IS_ERR_OR_NULL(onewire_data->ow_gpio_pinctrl)) { + retval = PTR_ERR(onewire_data->ow_gpio_pinctrl); + ow_err("Target does not use pinctrl %d\n", retval); + goto ow_gpio_err_pinctrl_get; + } + + onewire_data->pinctrl_state_active = pinctrl_lookup_state( + onewire_data->ow_gpio_pinctrl, "onewire_active"); + if (IS_ERR_OR_NULL(onewire_data->pinctrl_state_active)) { + retval = PTR_ERR(onewire_data->pinctrl_state_active); + ow_err("Can not lookup onewire_active pinstate %d\n", retval); + goto ow_gpio_err_pinctrl_lookup; + } + + onewire_data->pinctrl_state_sleep = pinctrl_lookup_state( + onewire_data->ow_gpio_pinctrl, "onewire_sleep"); + if (IS_ERR_OR_NULL(onewire_data->pinctrl_state_sleep)) { + retval = PTR_ERR(onewire_data->pinctrl_state_sleep); + ow_err("Can not lookup onewire_sleep pinstate %d\n", retval); + goto ow_gpio_err_pinctrl_lookup; + } + + return 0; + +ow_gpio_err_pinctrl_get: + devm_pinctrl_put(onewire_data->ow_gpio_pinctrl); +ow_gpio_err_pinctrl_lookup: + onewire_data->ow_gpio_pinctrl = NULL; + + return retval; +} + +// read data from file +static ssize_t onewire_gpio_ow_gpio_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int status; + struct onewire_gpio_data *onewire_data = dev_get_drvdata(dev); + + status = gpio_get_value(onewire_data->ow_gpio); + + return scnprintf(buf, PAGE_SIZE, "%d", status); +} + +// write data to file +static ssize_t onewire_gpio_ow_gpio_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned char result = 0x01; + int buf_int; + unsigned char i; + unsigned char RomID[8] = { 0 }; + + if (sscanf(buf, "%1u", &buf_int) != 1) + return -EINVAL; + + if (buf_int == 0) { + ONE_WIRE_OUT_LOW; + ow_log("gpio : OUT 0"); + } else if (buf_int == 1) { + ONE_WIRE_OUT_HIGH; + ow_log("gpio : OUT 1"); + } else if (buf_int == 2) { + ONE_WIRE_CONFIG_OUT; + ow_log("gpio : OUT"); + } else if (buf_int == 3) { + ONE_WIRE_CONFIG_IN; + ow_log("gpio : IN"); + } else if (buf_int == 4) { + result = ow_reset(); + if (result) + ow_log("ow_reset: no device.result = %02x", result); + else + ow_log("ow_reset: device exist.result = %02x", result); + } else if (buf_int == 5) { + result = read_bit(); + ow_log("read_bit: %02x", result); + } else if (buf_int == 6) { + write_bit(0x01); + ow_log("write_bit 0"); + } else if (buf_int == 7) { + result = ow_reset(); + if (result) + ow_log("ow_reset: no device.result = %02x", result); + else + ow_log("ow_reset: device exist.result = %02x", result); + + ow_dbg("Ready to write 0x33 to maxim IC!\n"); + write_byte(0x33); + + for (i = 0; i < 8; i++) + RomID[i] = read_byte(); + + ow_log("RomID = %02x%02x%02x%02x%02x%02x%02x%02x\n", RomID[0], + RomID[1], RomID[2], RomID[3], RomID[4], RomID[5], + RomID[6], RomID[7]); + } else if (buf_int == 8) { + ONE_WIRE_CONFIG_OUT; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + + Delay_us(1000); + ONE_WIRE_OUT_HIGH; + Delay_us(1); + ONE_WIRE_OUT_LOW; + Delay_us(1); + ONE_WIRE_OUT_HIGH; + Delay_us(1); + ONE_WIRE_OUT_LOW; + Delay_us(1); + ONE_WIRE_OUT_HIGH; + Delay_us(1); + ONE_WIRE_OUT_LOW; + Delay_us(1); + ONE_WIRE_OUT_HIGH; + Delay_us(1); + ONE_WIRE_OUT_LOW; + Delay_us(1); + ONE_WIRE_OUT_HIGH; + Delay_us(1); + ONE_WIRE_OUT_LOW; + Delay_us(1); + + Delay_us(1000); + ONE_WIRE_OUT_HIGH; + Delay_us(5); + ONE_WIRE_OUT_LOW; + Delay_us(5); + ONE_WIRE_OUT_HIGH; + Delay_us(5); + ONE_WIRE_OUT_LOW; + Delay_us(5); + ONE_WIRE_OUT_HIGH; + Delay_us(5); + ONE_WIRE_OUT_LOW; + Delay_us(5); + ONE_WIRE_OUT_HIGH; + Delay_us(5); + ONE_WIRE_OUT_LOW; + Delay_us(5); + ONE_WIRE_OUT_HIGH; + Delay_us(5); + ONE_WIRE_OUT_LOW; + Delay_us(5); + } + + return count; +} + +static DEVICE_ATTR(ow_gpio, S_IRUGO | S_IWUSR | S_IWGRP, + onewire_gpio_ow_gpio_status_read, + onewire_gpio_ow_gpio_store); + +static int onewire_gpio_probe(struct platform_device *pdev) +{ + int retval = 0; + struct onewire_gpio_data *onewire_data; + struct kobject *p; + + ow_log("onewire probe entry"); + + if (!pdev->dev.of_node || !of_device_is_available(pdev->dev.of_node)) + return -ENODEV; + if (pdev->dev.of_node) { + onewire_data = devm_kzalloc(&pdev->dev, + sizeof(struct onewire_gpio_data), + GFP_KERNEL); + if (!onewire_data) { + ow_err("Failed to allocate memory\n"); + return -ENOMEM; + } + retval = onewire_gpio_parse_dt(&pdev->dev, onewire_data); + if (retval) { + retval = -EINVAL; + goto onewire_parse_dt_err; + } + } else { + onewire_data = pdev->dev.platform_data; + } + if (!onewire_data) { + ow_err("No platform data found\n"); + return -EINVAL; + } + g_onewire_data = onewire_data; + onewire_data->pdev = pdev; + platform_set_drvdata(pdev, onewire_data); + + raw_spin_lock_init(&g_onewire_data->lock); + + // pinctrl init + retval = onewire_gpio_pinctrl_init(onewire_data); + if (!retval && onewire_data->ow_gpio_pinctrl) { + retval = pinctrl_select_state( + onewire_data->ow_gpio_pinctrl, + onewire_data->pinctrl_state_active); + if (retval < 0) + ow_err("Failed to select active pinstate %d\n", retval); + } + if (retval) + goto onewire_pinctrl_err; + // request onewire gpio + gpio_free(onewire_data->ow_gpio); + if (gpio_is_valid(onewire_data->ow_gpio)) { + retval = gpio_request(onewire_data->ow_gpio, "onewire gpio"); + } else { + retval = -EINVAL; + } + if (retval) { + ow_err("request onewire gpio failed, retval=%d\n", retval); + goto onewire_ow_gpio_err; + } + // gpio output 1 + gpio_direction_output(onewire_data->ow_gpio, 1); + + onewire_data->ow_gpio_desc = gpio_to_desc(onewire_data->ow_gpio); + onewire_data->ow_gpio_chip = gpiod_to_chip(onewire_data->ow_gpio_desc); + + onewire_data->gpio_in_out_reg = devm_ioremap( + &pdev->dev, (uint32_t)onewire_data->onewire_gpio_level_addr, + 0x4); + onewire_data->gpio_cfg66_reg = devm_ioremap( + &pdev->dev, (uint32_t)onewire_data->onewire_gpio_cfg_addr, 0x4); + ow_log("onewire_gpio_level_addr is %x; onewire_gpio_cfg_addr is %x", + (uint32_t)(onewire_data->onewire_gpio_level_addr), + (uint32_t)(onewire_data->onewire_gpio_cfg_addr)); + ow_log("onewire_data->gpio_cfg66_reg is %x; onewire_data->gpio_in_out_reg is %x", + (uint32_t)(onewire_data->gpio_cfg66_reg), + (uint32_t)(onewire_data->gpio_in_out_reg)); + + // create device node + onewire_data->dev = + device_create(onewire_class, pdev->dev.parent->parent, + onewire_major, onewire_data, "onewirectrl"); + if (IS_ERR(onewire_data->dev)) { + ow_err("Failed to create interface device\n"); + goto onewire_interface_dev_create_err; + } + p = &onewire_data->dev->kobj; + + // create attr file + retval = sysfs_create_file(p, &dev_attr_ow_gpio.attr); + if (retval < 0) { + ow_err("Failed to create sysfs attr file\n"); + goto onewire_sysfs_ow_gpio_err; + } + retval = sysfs_create_link(&onewire_data->dev->kobj, &pdev->dev.kobj, + "pltdev"); + if (retval) { + ow_err("Failed to create sysfs link\n"); + goto onewire_syfs_create_link_err; + } + return 0; +onewire_syfs_create_link_err: + if (gpio_is_valid(onewire_data->ow_gpio)) + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_ow_gpio.attr); +onewire_sysfs_ow_gpio_err: + device_destroy(onewire_class, onewire_major); +onewire_interface_dev_create_err: + if (gpio_is_valid(onewire_data->ow_gpio)) + gpio_free(onewire_data->ow_gpio); +onewire_ow_gpio_err: +onewire_pinctrl_err: +onewire_parse_dt_err: + kfree(onewire_data); + return retval; +} + +static int onewire_gpio_remove(struct platform_device *pdev) +{ + struct onewire_gpio_data *onewire_data = platform_get_drvdata(pdev); + + if (gpio_is_valid(onewire_data->ow_gpio)) { + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_ow_gpio.attr); + gpio_free(onewire_data->ow_gpio); + } + kfree(onewire_data); + + return 0; +} + +static long onewire_dev_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + ow_dbg("%d, cmd: 0x%x\n", __LINE__, cmd); + return 0; +} +static int onewire_dev_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int onewire_dev_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations onewire_dev_fops = { + .owner = THIS_MODULE, + .open = onewire_dev_open, + .unlocked_ioctl = onewire_dev_ioctl, + .release = onewire_dev_release, +}; + +static const struct of_device_id onewire_gpio_dt_match[] = { + { .compatible = "xiaomi,onewire_gpio" }, + {}, +}; + +static struct platform_driver onewire_gpio_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "onewire_gpio", + .of_match_table = onewire_gpio_dt_match, + }, + .probe = onewire_gpio_probe, + .remove = onewire_gpio_remove, +}; + +static int __init onewire_gpio_init(void) +{ + int retval; + onewire_gpio_detected = false; + + ow_log("onewire gpio init entry."); + + onewire_class = class_create(THIS_MODULE, "onewire"); + if (IS_ERR(onewire_class)) { + ow_err("coudn't create class"); + return PTR_ERR(onewire_class); + } + + onewire_major = register_chrdev(0, "onewirectrl", &onewire_dev_fops); + if (onewire_major < 0) { + ow_err("failed to allocate char dev\n"); + retval = onewire_major; + goto class_unreg; + } + + return platform_driver_register(&onewire_gpio_driver); + +class_unreg: + class_destroy(onewire_class); + return retval; +} + +static void __exit onewire_gpio_exit(void) +{ + ow_log("onewire gpio exit entry."); + platform_driver_unregister(&onewire_gpio_driver); + + unregister_chrdev(onewire_major, "onewirectrl"); + class_destroy(onewire_class); +} + +module_init(onewire_gpio_init); +module_exit(onewire_gpio_exit); + +MODULE_AUTHOR("xiaomi Inc."); +MODULE_DESCRIPTION("onewire driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/power/supply/maxim/onewire_gpio_master.h b/drivers/power/supply/maxim/onewire_gpio_master.h new file mode 100644 index 000000000000..b08c41182f64 --- /dev/null +++ b/drivers/power/supply/maxim/onewire_gpio_master.h @@ -0,0 +1,10 @@ +#ifndef __ONEWIRE_GPIO_MASTER_H__ +#define __ONEWIRE_GPIO_MASTER_H__ + +void Delay_us(unsigned int T); +void Delay_ns(unsigned int T); +unsigned char ow_reset(void); +unsigned char read_byte(void); +void write_byte(char val); + +#endif diff --git a/drivers/power/supply/maxim/onewire_gpio_slave.c b/drivers/power/supply/maxim/onewire_gpio_slave.c new file mode 100644 index 000000000000..4982d10f1b18 --- /dev/null +++ b/drivers/power/supply/maxim/onewire_gpio_slave.c @@ -0,0 +1,611 @@ +/* + * Copyright (c) 2016 xiaomi Inc. + * Copyright (C) 2021 XiaoMi, Inc. + */ +#define pr_fmt(fmt) "[Onewire] %s: " fmt, __func__ + +#include /* kfree() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ow_info pr_err +#define ow_dbg pr_err +#define ow_err pr_err +#define ow_log pr_err + +#define DRV_STRENGTH_16MA (0x7 << 6) +#define DRV_STRENGTH_4MA (0x1 << 6) +#define GPIO_OUTPUT (0x1 << 9) +#define GPIO_INPUT (0x0 << 9) +#define GPIO_PULL_UP 0x3 +#define OUTPUT_HIGH (0x1 << 1) +#define OUTPUT_LOW 0x1 + +#define ONE_WIRE_CONFIG_OUT \ + writel_relaxed(DRV_STRENGTH_16MA | GPIO_OUTPUT | GPIO_PULL_UP, \ + g_onewire_data->gpio_cfg66_reg) // OUT +#define ONE_WIRE_CONFIG_IN \ + writel_relaxed(DRV_STRENGTH_16MA | GPIO_INPUT | GPIO_PULL_UP, \ + g_onewire_data->gpio_cfg66_reg) // IN +#define ONE_WIRE_OUT_HIGH \ + writel_relaxed(OUTPUT_HIGH, g_onewire_data->gpio_in_out_reg) // OUT: 1 +#define ONE_WIRE_OUT_LOW \ + writel_relaxed(OUTPUT_LOW, g_onewire_data->gpio_in_out_reg) // OUT: 0 + +struct onewire_gpio_data { + struct platform_device *pdev; + struct device *dev; + + int ow_gpio; + + struct gpio_desc *ow_gpio_desc; + struct gpio_chip *ow_gpio_chip; + void *gpio_in_out_reg; + void *gpio_cfg66_reg; + + raw_spinlock_t lock; + + struct pinctrl *ow_gpio_pinctrl; + struct pinctrl_state *pinctrl_state_active; + struct pinctrl_state *pinctrl_state_sleep; + + int version; + + int gpio_num; + + unsigned int onewire_gpio_cfg_addr; + unsigned int onewire_gpio_level_addr; + unsigned int gpio_offset; + unsigned int gpio_reg[2]; +}; + +static struct class *onewire_class; +static int onewire_major; + +static int onewire_gpio_detected; +static struct onewire_gpio_data *g_onewire_data; + +void Delay_us_slave(unsigned int T) +{ + udelay(T); +} +EXPORT_SYMBOL(Delay_us_slave); + +void Delay_ns_slave(unsigned int T) +{ + ndelay(T); +} +EXPORT_SYMBOL(Delay_ns_slave); + +unsigned char ow_reset_slave(void) +{ + unsigned char presence = 0xFF; + unsigned long flags; + + raw_spin_lock_irqsave(&g_onewire_data->lock, flags); + + ONE_WIRE_CONFIG_OUT; + ONE_WIRE_OUT_LOW; + Delay_us_slave(50); // 48 + ONE_WIRE_OUT_HIGH; + ONE_WIRE_CONFIG_IN; + Delay_us_slave(7); + presence = + (unsigned char)readl_relaxed(g_onewire_data->gpio_in_out_reg) & + 0x01; // Read + Delay_us_slave(50); + + raw_spin_unlock_irqrestore(&g_onewire_data->lock, flags); + return presence; +} +EXPORT_SYMBOL(ow_reset_slave); + +static unsigned char read_bit(void) +{ + unsigned int vamm; + + ONE_WIRE_CONFIG_OUT; + ONE_WIRE_OUT_LOW; + Delay_us_slave(1); //// + ONE_WIRE_CONFIG_IN; + Delay_ns_slave(500); // + vamm = readl_relaxed(g_onewire_data->gpio_in_out_reg); // Read + Delay_us_slave(5); + ONE_WIRE_OUT_HIGH; + ONE_WIRE_CONFIG_OUT; + Delay_us_slave(6); + return ((unsigned char)vamm & 0x01); +} + +static void write_bit(char bitval) +{ + ONE_WIRE_OUT_LOW; + Delay_us_slave(1); // + if (bitval != 0) + ONE_WIRE_OUT_HIGH; + Delay_us_slave(10); + ONE_WIRE_OUT_HIGH; + Delay_us_slave(6); +} + +unsigned char read_byte_slave(void) +{ + unsigned char i; + unsigned char value = 0; + unsigned long flags; + + raw_spin_lock_irqsave(&g_onewire_data->lock, flags); + for (i = 0; i < 8; i++) { + if (read_bit()) + value |= + 0x01 + << i; // reads byte in, one byte at a time and then shifts it left + } + + raw_spin_unlock_irqrestore(&g_onewire_data->lock, flags); + return value; +} +EXPORT_SYMBOL(read_byte_slave); + +void write_byte_slave(char val) +{ + unsigned char i; + unsigned char temp; + unsigned long flags; + + raw_spin_lock_irqsave(&g_onewire_data->lock, flags); + ONE_WIRE_CONFIG_OUT; + // writes byte, one bit at a time + for (i = 0; i < 8; i++) { + temp = val >> i; // shifts val right ‘i’ spaces + temp &= 0x01; // copy that bit to temp + write_bit(temp); // write bit in temp into + } + raw_spin_unlock_irqrestore(&g_onewire_data->lock, flags); +} +EXPORT_SYMBOL(write_byte_slave); + +int onewire_gpio_get_status_slave(void) +{ + return onewire_gpio_detected; +} +EXPORT_SYMBOL(onewire_gpio_get_status_slave); + +// parse dts +static int onewire_gpio_parse_dt(struct device *dev, + struct onewire_gpio_data *pdata) +{ + int error, val; + struct device_node *np = dev->of_node; + + // parse version + pdata->version = 0; + error = of_property_read_u32(np, "xiaomi,version", &val); + if (error && (error != -EINVAL)) + ow_err("Unable to read version\n"); + else if (error != -EINVAL) + pdata->version = val; + + // parse gpio + pdata->ow_gpio = of_get_named_gpio_flags(np, "xiaomi,ow_gpio", 0, NULL); + ow_dbg("ow_gpio: %d\n", pdata->ow_gpio); + + // parse gpio_num + pdata->gpio_num = 0; + error = of_property_read_u32(np, "xiaomi,gpio_number", &val); + if (error && (error != -EINVAL)) + ow_err("Unable to read gpio number\n"); + else if (error != -EINVAL) + pdata->gpio_num = val; + + error = of_property_read_u32_array(np, "mi,onewire-gpio-cfg-addr", + pdata->gpio_reg, 2); + if (error < 0) + ow_err("Unable to read onewire gpio addr\n"); + + pdata->onewire_gpio_cfg_addr = pdata->gpio_reg[0]; + pdata->gpio_offset = pdata->gpio_reg[1]; + pdata->onewire_gpio_level_addr = + pdata->onewire_gpio_cfg_addr + pdata->gpio_offset; + + return 0; +} + +// pinctrl init +static int onewire_gpio_pinctrl_init(struct onewire_gpio_data *onewire_data) +{ + int retval; + + onewire_data->ow_gpio_pinctrl = + devm_pinctrl_get(&onewire_data->pdev->dev); + if (IS_ERR_OR_NULL(onewire_data->ow_gpio_pinctrl)) { + retval = PTR_ERR(onewire_data->ow_gpio_pinctrl); + ow_err("Target does not use pinctrl %d\n", retval); + goto ow_gpio_err_pinctrl_get; + } + + onewire_data->pinctrl_state_active = pinctrl_lookup_state( + onewire_data->ow_gpio_pinctrl, "onewire_slave_active"); + if (IS_ERR_OR_NULL(onewire_data->pinctrl_state_active)) { + retval = PTR_ERR(onewire_data->pinctrl_state_active); + ow_err("Can not lookup onewire_slave_active pinstate %d\n", + retval); + goto ow_gpio_err_pinctrl_lookup; + } + + onewire_data->pinctrl_state_sleep = pinctrl_lookup_state( + onewire_data->ow_gpio_pinctrl, "onewire_slave_sleep"); + if (IS_ERR_OR_NULL(onewire_data->pinctrl_state_sleep)) { + retval = PTR_ERR(onewire_data->pinctrl_state_sleep); + ow_err("Can not lookup onewire_slave_sleep pinstate %d\n", + retval); + goto ow_gpio_err_pinctrl_lookup; + } + + return 0; + +ow_gpio_err_pinctrl_get: + devm_pinctrl_put(onewire_data->ow_gpio_pinctrl); +ow_gpio_err_pinctrl_lookup: + onewire_data->ow_gpio_pinctrl = NULL; + + return retval; +} + +// read data from file +static ssize_t onewire_gpio_ow_gpio_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int status; + struct onewire_gpio_data *onewire_data = dev_get_drvdata(dev); + + status = gpio_get_value(onewire_data->ow_gpio); + + return scnprintf(buf, PAGE_SIZE, "%d", status); +} + +// write data to file +static ssize_t onewire_gpio_ow_gpio_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned char result = 0x01; + int buf_int; + unsigned char i; + unsigned char RomID[8] = { 0 }; + + if (sscanf(buf, "%1u", &buf_int) != 1) + return -EINVAL; + + if (buf_int == 0) { + ONE_WIRE_OUT_LOW; + ow_log("gpio : OUT 0"); + } else if (buf_int == 1) { + ONE_WIRE_OUT_HIGH; + ow_log("gpio : OUT 1"); + } else if (buf_int == 2) { + ONE_WIRE_CONFIG_OUT; + ow_log("gpio : OUT"); + } else if (buf_int == 3) { + ONE_WIRE_CONFIG_IN; + ow_log("gpio : IN"); + } else if (buf_int == 4) { + result = ow_reset_slave(); + if (result) + ow_log("ow_reset_slave: no device.result = %02x", + result); + else + ow_log("ow_reset_slave: device exist.result = %02x", + result); + } else if (buf_int == 5) { + result = read_bit(); + ow_log("read_bit: %02x", result); + } else if (buf_int == 6) { + write_bit(0x01); + ow_log("write_bit 0"); + } else if (buf_int == 7) { + result = ow_reset_slave(); + if (result) + ow_log("ow_reset_slave: no device.result = %02x", + result); + else + ow_log("ow_reset_slave: device exist.result = %02x", + result); + + ow_dbg("Ready to write 0x33 to maxim IC!\n"); + write_byte_slave(0x33); + + for (i = 0; i < 8; i++) + RomID[i] = read_byte_slave(); + + ow_log("RomID = %02x%02x%02x%02x%02x%02x%02x%02x\n", RomID[0], + RomID[1], RomID[2], RomID[3], RomID[4], RomID[5], + RomID[6], RomID[7]); + } else if (buf_int == 8) { + ONE_WIRE_CONFIG_OUT; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + ONE_WIRE_OUT_HIGH; + ONE_WIRE_OUT_LOW; + + Delay_us_slave(1000); + ONE_WIRE_OUT_HIGH; + Delay_us_slave(1); + ONE_WIRE_OUT_LOW; + Delay_us_slave(1); + ONE_WIRE_OUT_HIGH; + Delay_us_slave(1); + ONE_WIRE_OUT_LOW; + Delay_us_slave(1); + ONE_WIRE_OUT_HIGH; + Delay_us_slave(1); + ONE_WIRE_OUT_LOW; + Delay_us_slave(1); + ONE_WIRE_OUT_HIGH; + Delay_us_slave(1); + ONE_WIRE_OUT_LOW; + Delay_us_slave(1); + ONE_WIRE_OUT_HIGH; + Delay_us_slave(1); + ONE_WIRE_OUT_LOW; + Delay_us_slave(1); + + Delay_us_slave(1000); + ONE_WIRE_OUT_HIGH; + Delay_us_slave(5); + ONE_WIRE_OUT_LOW; + Delay_us_slave(5); + ONE_WIRE_OUT_HIGH; + Delay_us_slave(5); + ONE_WIRE_OUT_LOW; + Delay_us_slave(5); + ONE_WIRE_OUT_HIGH; + Delay_us_slave(5); + ONE_WIRE_OUT_LOW; + Delay_us_slave(5); + ONE_WIRE_OUT_HIGH; + Delay_us_slave(5); + ONE_WIRE_OUT_LOW; + Delay_us_slave(5); + ONE_WIRE_OUT_HIGH; + Delay_us_slave(5); + ONE_WIRE_OUT_LOW; + Delay_us_slave(5); + } + + return count; +} + +static DEVICE_ATTR(ow_gpio, S_IRUGO | S_IWUSR | S_IWGRP, + onewire_gpio_ow_gpio_status_read, + onewire_gpio_ow_gpio_store); + +static int onewire_gpio_probe(struct platform_device *pdev) +{ + int retval = 0; + struct onewire_gpio_data *onewire_data; + struct kobject *p; + + ow_log("onewire probe entry"); + + if (!pdev->dev.of_node || !of_device_is_available(pdev->dev.of_node)) + return -ENODEV; + if (pdev->dev.of_node) { + onewire_data = devm_kzalloc(&pdev->dev, + sizeof(struct onewire_gpio_data), + GFP_KERNEL); + if (!onewire_data) { + ow_err("Failed to allocate memory\n"); + return -ENOMEM; + } + retval = onewire_gpio_parse_dt(&pdev->dev, onewire_data); + if (retval) { + retval = -EINVAL; + goto onewire_parse_dt_err; + } + } else { + onewire_data = pdev->dev.platform_data; + } + if (!onewire_data) { + ow_err("No platform data found\n"); + return -EINVAL; + } + g_onewire_data = onewire_data; + onewire_data->pdev = pdev; + platform_set_drvdata(pdev, onewire_data); + + raw_spin_lock_init(&g_onewire_data->lock); + + // pinctrl init + retval = onewire_gpio_pinctrl_init(onewire_data); + if (!retval && onewire_data->ow_gpio_pinctrl) { + retval = pinctrl_select_state( + onewire_data->ow_gpio_pinctrl, + onewire_data->pinctrl_state_active); + if (retval < 0) + ow_err("Failed to select active pinstate %d\n", retval); + } + if (retval) + goto onewire_pinctrl_err; + // request onewire gpio + gpio_free(onewire_data->ow_gpio); + if (gpio_is_valid(onewire_data->ow_gpio)) { + retval = gpio_request(onewire_data->ow_gpio, "onewire gpio"); + } else { + retval = -EINVAL; + } + if (retval) { + ow_err("request onewire gpio failed, retval=%d\n", retval); + goto onewire_ow_gpio_err; + } + // gpio output 1 + gpio_direction_output(onewire_data->ow_gpio, 1); + + onewire_data->ow_gpio_desc = gpio_to_desc(onewire_data->ow_gpio); + onewire_data->ow_gpio_chip = gpiod_to_chip(onewire_data->ow_gpio_desc); + + onewire_data->gpio_in_out_reg = devm_ioremap( + &pdev->dev, (uint32_t)onewire_data->onewire_gpio_level_addr, + 0x4); + onewire_data->gpio_cfg66_reg = devm_ioremap( + &pdev->dev, (uint32_t)onewire_data->onewire_gpio_cfg_addr, 0x4); + ow_log("onewire_gpio_level_addr is %x; onewire_gpio_cfg_addr is %x", + (uint32_t)(onewire_data->onewire_gpio_level_addr), + (uint32_t)(onewire_data->onewire_gpio_cfg_addr)); + ow_log("onewire_data->gpio_cfg66_reg is %x; onewire_data->gpio_in_out_reg is %x", + (uint32_t)(onewire_data->gpio_cfg66_reg), + (uint32_t)(onewire_data->gpio_in_out_reg)); + + // create device node + onewire_data->dev = + device_create(onewire_class, pdev->dev.parent->parent, + onewire_major, onewire_data, "onewireslavectrl"); + if (IS_ERR(onewire_data->dev)) { + ow_err("Failed to create interface device\n"); + goto onewire_interface_dev_create_err; + } + p = &onewire_data->dev->kobj; + + // create attr file + retval = sysfs_create_file(p, &dev_attr_ow_gpio.attr); + if (retval < 0) { + ow_err("Failed to create sysfs attr file\n"); + goto onewire_sysfs_ow_gpio_err; + } + retval = sysfs_create_link(&onewire_data->dev->kobj, &pdev->dev.kobj, + "pltdev"); + if (retval) { + ow_err("Failed to create sysfs link\n"); + goto onewire_syfs_create_link_err; + } + return 0; +onewire_syfs_create_link_err: + if (gpio_is_valid(onewire_data->ow_gpio)) + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_ow_gpio.attr); +onewire_sysfs_ow_gpio_err: + device_destroy(onewire_class, onewire_major); +onewire_interface_dev_create_err: + if (gpio_is_valid(onewire_data->ow_gpio)) + gpio_free(onewire_data->ow_gpio); +onewire_ow_gpio_err: +onewire_pinctrl_err: +onewire_parse_dt_err: + kfree(onewire_data); + return retval; +} + +static int onewire_gpio_remove(struct platform_device *pdev) +{ + struct onewire_gpio_data *onewire_data = platform_get_drvdata(pdev); + + if (gpio_is_valid(onewire_data->ow_gpio)) { + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_ow_gpio.attr); + gpio_free(onewire_data->ow_gpio); + } + kfree(onewire_data); + + return 0; +} + +static long onewire_dev_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + ow_dbg("%d, cmd: 0x%x\n", __LINE__, cmd); + return 0; +} +static int onewire_dev_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int onewire_dev_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations onewire_dev_fops = { + .owner = THIS_MODULE, + .open = onewire_dev_open, + .unlocked_ioctl = onewire_dev_ioctl, + .release = onewire_dev_release, +}; + +static const struct of_device_id onewire_gpio_dt_match[] = { + { .compatible = "xiaomi,onewire_slave_gpio" }, + {}, +}; + +static struct platform_driver onewire_gpio_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "onewire_slave_gpio", + .of_match_table = onewire_gpio_dt_match, + }, + .probe = onewire_gpio_probe, + .remove = onewire_gpio_remove, +}; + +static int __init onewire_gpio_init(void) +{ + int retval; + onewire_gpio_detected = false; + + ow_log("onewire gpio init entry."); + + onewire_class = class_create(THIS_MODULE, "onewire_slave"); + if (IS_ERR(onewire_class)) { + ow_err("coudn't create class"); + return PTR_ERR(onewire_class); + } + + onewire_major = + register_chrdev(0, "onewireslavectrl", &onewire_dev_fops); + if (onewire_major < 0) { + ow_err("failed to allocate char dev\n"); + retval = onewire_major; + goto class_unreg; + } + + return platform_driver_register(&onewire_gpio_driver); + +class_unreg: + class_destroy(onewire_class); + return retval; +} + +static void __exit onewire_gpio_exit(void) +{ + ow_log("onewire gpio exit entry."); + platform_driver_unregister(&onewire_gpio_driver); + + unregister_chrdev(onewire_major, "onewireslavectrl"); + class_destroy(onewire_class); +} + +module_init(onewire_gpio_init); +module_exit(onewire_gpio_exit); + +MODULE_AUTHOR("xiaomi Inc."); +MODULE_DESCRIPTION("onewire driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/power/supply/maxim/onewire_gpio_slave.h b/drivers/power/supply/maxim/onewire_gpio_slave.h new file mode 100644 index 000000000000..c653b92fe1e6 --- /dev/null +++ b/drivers/power/supply/maxim/onewire_gpio_slave.h @@ -0,0 +1,10 @@ +#ifndef __ONEWIRE_GPIO_SLAVE_H__ +#define __ONEWIRE_GPIO_SLAVE_H__ + +void Delay_us_slave(unsigned int T); +void Delay_ns_slave(unsigned int T); +unsigned char ow_reset_slave(void); +unsigned char read_byte_slave(void); +void write_byte_slave(char val); + +#endif diff --git a/drivers/power/supply/maxim/sha384_software.c b/drivers/power/supply/maxim/sha384_software.c new file mode 100644 index 000000000000..c4766fa028cf --- /dev/null +++ b/drivers/power/supply/maxim/sha384_software.c @@ -0,0 +1,109 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ +// SHA3_HMAC - HMAC using SHA3-256 +#include "ucl_sha3.h" +#include +#define SHA3_256_HMAC +#include "sha384_software.h" + +//--------------------------------------------------------------------------- +/// Compute HMAC using SHA3-256. +/// +/// @param[in] key +/// buffer for key +/// @param[in] ken_len +/// length of key +/// @param[in] message +/// buffer for message +/// @param[in] msg_len +/// length of message +/// @param[out] mac +/// 32 byte output mac +/// +/// Restrictions: +/// Key length limited to 32 bytes. +/// Message Length is limited to 512 bytes. +/// +/// @return +/// TRUE - command successful @n +/// FALSE - command failed +/// +int sha3_256_hmac(unsigned char *key, int key_len, unsigned char *message, + int msg_len, unsigned char *mac) +{ + int i; + unsigned char thash[256]; + unsigned char tmac[256]; + unsigned char cat_input_thash[1024]; + unsigned char cat_input_final[1024]; + + int blocksize = 136; + int hashsize = 32; + unsigned char opad[136]; + unsigned char ipad[136]; + + memset(opad, 0x5C, blocksize); + memset(ipad, 0x36, blocksize); + + // Check to see if key is larger then blocksize + if (key_len > blocksize) + return 0; // Not supported + + // check for blocks too big + if (msg_len > 512) + return 0; + + // Loop through bytes of ipad/opad and XOR with key + for (i = 0; i < key_len; i++) { + // XOR ipad with key + ipad[i] ^= key[i]; + // XOR opad with key + opad[i] ^= key[i]; + } + + // thash = hash(ipad || message) + memcpy(cat_input_thash, ipad, blocksize); + memcpy(&cat_input_thash[blocksize], message, msg_len); + + ucl_sha3_256(thash, cat_input_thash, blocksize + msg_len); + + // return hash(opad || thash) + memcpy(cat_input_final, opad, blocksize); + memcpy(&cat_input_final[blocksize], thash, hashsize); + + ucl_sha3_256(tmac, cat_input_final, blocksize + hashsize); + + memcpy(mac, tmac, hashsize); + + return 1; +} diff --git a/drivers/power/supply/maxim/sha384_software.h b/drivers/power/supply/maxim/sha384_software.h new file mode 100644 index 000000000000..54986da60a40 --- /dev/null +++ b/drivers/power/supply/maxim/sha384_software.h @@ -0,0 +1,30 @@ +//------------Copyright (C) 2017 Maxim Integrated Products -------------- +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL MAXIM INTEGRATED PRODCUTS BE LIABLE FOR ANY CLAIM, DAMAGES +// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// Except as contained in this notice, the name of Maxim Integrated Products +// shall not be used except as stated in the Maxim Integrated Products +// Branding Policy. +// --------------------------------------------------------------------------- +// +// sha3_hmac.h - Include file for sha3_hmac module. +// + +int sha3_256_hmac(unsigned char *key, int key_len, unsigned char *message, + int msg_len, unsigned char *mac); diff --git a/drivers/power/supply/maxim/ucl_hash.h b/drivers/power/supply/maxim/ucl_hash.h new file mode 100644 index 000000000000..9a92ef044c15 --- /dev/null +++ b/drivers/power/supply/maxim/ucl_hash.h @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (C) 2015 Maxim Integrated Products, Inc., All rights Reserved. +* * This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +* Module Name: UCL +* Description: hash definition +* Filename: ucl_hash.h +* Author: LSL +* Compiler: gcc +* + ******************************************************************************* + */ +//these defines are used to select or not hash functions +//useful on platforms with limited resources + +#ifndef _UCL_HASH_H +#define _UCL_HASH_H + +#define HASH_SHA256 +#define HASH_SIA256 +#define HASH_SHA3 + +#define MAX_HASH_FUNCTIONS 3 + +extern int hash_size[MAX_HASH_FUNCTIONS]; +#endif //UCL_HASH diff --git a/drivers/power/supply/maxim/ucl_retdefs.h b/drivers/power/supply/maxim/ucl_retdefs.h new file mode 100644 index 000000000000..0483ecda112c --- /dev/null +++ b/drivers/power/supply/maxim/ucl_retdefs.h @@ -0,0 +1,237 @@ +/******************************************************************************* +* Copyright (C) 2015 Maxim Integrated Products, Inc., All rights Reserved. +* * This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +* Module Name: UCL +* Description: return definition +* Filename: ucl_retdefs.h +* Author: LSL +* Compiler: gcc +* + ******************************************************************************* + */ +#ifndef UCL_RETDEFS_H_ +#define UCL_RETDEFS_H_ + +/** @file ucl_retdefs.h + * @defgroup UCL_RETURN Definitions of returns + * + * @par Header: + * @link ucl_retdefs.h ucl_retdefs.h @endlink + * + * @ingroup UCL_DEFINITIONS + */ + +/** Carry. + * @ingroup UCL_RETURN + */ +#define UCL_CARRY 1 + +/** True. + * @ingroup UCL_RETURN + */ +#define UCL_TRUE 1 +/** False. + * @ingroup UCL_RETURN + */ +#define UCL_FALSE 0 + +/* ========================================================================== */ + +/** No error occured. + * @ingroup UCL_RETURN + */ +#define UCL_OK 0 +/** Generic Error. + * @ingroup UCL_RETURN + */ +#define UCL_ERROR -1 +/** Not a failure but no operation was performed. + * @ingroup UCL_RETURN + */ +#define UCL_NOP -2 +/** Invalid cipher specified. + * @ingroup UCL_RETURN + */ +#define UCL_INVALID_CIPHER -3 +/** Invalid hash specified. + * @ingroup UCL_RETURN + */ +#define UCL_INVALID_HASH -4 +/** Generic invalid argument. + * @ingroup UCL_RETURN + */ +#define UCL_INVALID_ARG -5 +/** Invalid argument input. + * @ingroup UCL_RETURN + */ +#define UCL_INVALID_INPUT -6 +/** Invalid argument output. + * @ingroup UCL_RETURN + */ +#define UCL_INVALID_OUTPUT -7 +/** Invalid precision for Fixed-Precision Aritmetic. + * @ingroup UCL_RETURN + */ +#define UCL_INVALID_PRECISION -8 +/** Invalid RSA public key. + * @ingroup UCL_RETURN + */ +#define UCL_INVALID_RSAPUBKEY -9 +/** Invalid RSA private key. + * @ingroup UCL_RETURN + */ +#define UCL_INVALID_RSAPRIVKEY -10 +/** Invalid RSA CRT key. + * @ingroup UCL_RETURN + */ +#define UCL_INVALID_RSACRTKEY -11 +/** Invalid RSA CRT alternative key. + * @ingroup UCL_RETURN + */ +#define UCL_INVALID_RSACRTALTKEY -12 +/** Error during CRT recomposition. + * @ingroup UCL_RETURN + */ +#define UCL_RSACRT_ERROR -13 +/** Error, division by zero. + * @ingroup UCL_RETURN + */ +#define UCL_DIVISION_BY_ZERO -14 +/** Invalid chosen mode. + * @ingroup UCL_RETURN + */ +#define UCL_INVALID_MODE -15 +/** Large number with invalid sign. + * @ingroup UCL_RETURN + */ +#define UCL_INVALID_SIGN -16 +/** Invalid input for RSA. + * @ingroup UCL_RETURN + */ +#define UCL_RSA_INVALID_INPUT -17 +/** TRNG timeout. + * @ingroup UCL_RETURN + */ +#define UCL_RNGTIMEOUT -18 +/** RSA PKCS1-v1.5 decryption error. + * @ingroup UCL_RETURN + */ +#define UCL_RSAPKCS1_DECRYPTERR -19 +/** Overflow. + * @ingroup UCL_RETURN + */ +#define UCL_OVERFLOW -20 +/** Error in the case of the function is disabled. + * @ingroup UCL_RETURN + */ +#define UCL_FUNCTION_DISABLED -21 +/** (Big) Integer not odd. + * @ingroup UCL_RETURN + */ +#define UCL_INTEGER_NOT_ODD -22 +/** Invalid exponant of RSA key. + * @ingroup UCL_RETURN + */ +#define UCL_RSA_INVALID_EXPONANT -23 +/** UCL Stack overflow. + * Not enough memory. + * @ingroup UCL_RETURN + */ +#define UCL_STACK_OVERFLOW -24 +/** UCL Stack not init. + * @see ucl_stack_init + * @ingroup UCL_RETURN + */ +#define UCL_STACK_NOT_INIT -25 +/** Invalid UCL Stack free. + * @ingroup UCL_RETURN + */ +#define UCL_STACK_INVALID_FREE -26 +/** The UCL Stack is disabled. + * @ingroup UCL_RETURN + */ +#define UCL_STACK_DEFAULT -27 +/** Use default UCL stack. + * @ingroup UCL_RETURN + */ +#define UCL_STACK_ERROR -28 +/** General Warning. + * @ingroup UCL_RETURN + */ +#define UCL_WARNING -29 +/** PKCS1V25 Error - Invalid Signature . + * @ingroup UCL_RETURN + */ +#define UCL_PKCS1_INVALID_SIGNATURE -30 +/** No Interface for USIP® AES. + * @ingroup UCL_RETURN + */ +#define UCL_NO_UAES_INTERFACE -31 +/** USIP® AES Corrupted. + * @ingroup UCL_RETURN + */ +#define UCL_UAES_CORRUPTED -32 +/** USIP® AES Error. + * @ingroup UCL_RETURN + */ +#define UCL_UAES_ERROR -33 +/** USIP® TRNG Error. + * @ingroup UCL_RETURN + */ +#define UCL_TRNG_ERROR -34 +/** No Interface for USIP® TRNG. + * @ingroup UCL_RETURN + */ +#define UCL_NO_TRNG_INTERFACE -35 +/** No Interface for USIP® TRNG. + * @ingroup UCL_RETURN + */ +#define UCL_TRNG_CORRUPTED -36 +/** USIP® UCL Not Init. + * @ingroup UCL_RETURN + */ +#define UCL_NOT_INIT -37 +/** ECC key is invalid. + * @ingroup UCL_RETURN + */ +#define UCL_ECC_INVALID_KEY -38 + +/** RNG Interface Error. + * @ingroup UCL_RETURN + */ +#define UCL_RNG_ERROR -39 + +/** Functionality not implemented. + * @ingroup UCL_RETURN + */ +#define UCL_NOT_IMPLEMENTED -99 + +#endif /* UCL_RETDEFS_H_ */ diff --git a/drivers/power/supply/maxim/ucl_sha3.c b/drivers/power/supply/maxim/ucl_sha3.c new file mode 100644 index 000000000000..81d44d8de14e --- /dev/null +++ b/drivers/power/supply/maxim/ucl_sha3.c @@ -0,0 +1,429 @@ +//SHA3 implementation +//this implementation used the implementation from Markku-Juhani O.Saarinen +//as a starting point +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* + +The MIT License (MIT) + +Copyright (c) 2015 Markku-Juhani O. Saarinen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +#include "ucl_hash.h" +#ifdef HASH_SHA3 + +#include +#include "ucl_retdefs.h" +#include "ucl_sha3.h" + +#define N_ROUNDS 24 // the specialization for keccak-f from keccak-p +#define ROTL64(x, y) \ + (((x) << (y)) | ((x) >> ((sizeof(unsigned long long) * 8) - (y)))) + +const unsigned long long kcf_rc[24] = { + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, + 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, + 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, + 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, + 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, + 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, + 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 +}; +static const unsigned char kcf_rho[24] = { 1, 3, 6, 10, 15, 21, 28, 36, + 45, 55, 2, 14, 27, 41, 56, 8, + 25, 43, 62, 18, 39, 61, 20, 44 }; +static const unsigned char kcf_pilane[24] = { 10, 7, 11, 17, 18, 3, 5, 16, + 8, 21, 24, 4, 15, 23, 19, 13, + 12, 2, 20, 14, 22, 9, 6, 1 }; + +// generally called after SHA3_SPONGE_WORDS-ctx->capacityWords words +// are XORed into the state s +static void kcf(unsigned long long state[25]) +{ + int i, j, round; + unsigned long long t, c[5]; + + //I(chi(Pi(ro(theta( + for (round = 0; round < N_ROUNDS; round++) { + // Theta + for (i = 0; i < 5; i++) + c[i] = state[i] ^ state[i + 5] ^ state[i + 10] ^ + state[i + 15] ^ state[i + 20]; + + for (i = 0; i < 5; i++) { + t = c[(i + 4) % 5] ^ + (unsigned long long)ROTL64(c[(i + 1) % 5], 1); + for (j = 0; j < 25; j += 5) + state[j + i] ^= t; + } + + // Rho Pi + t = state[1]; + for (i = 0; i < 24; i++) { + j = (int)kcf_pilane[i]; + c[0] = state[j]; + state[j] = (unsigned long long)ROTL64(t, kcf_rho[i]); + t = c[0]; + } + + // Chi + for (j = 0; j < 25; j += 5) { + for (i = 0; i < 5; i++) + c[i] = state[j + i]; + for (i = 0; i < 5; i++) + state[j + i] ^= (~c[(i + 1) % 5]) & + c[(i + 2) % 5]; + } + // Iota + state[0] ^= kcf_rc[round]; + } +} + +int ucl_shake128_init(ucl_sha3_ctx_t *ctx) +{ + if (ctx == NULL) + return UCL_INVALID_INPUT; + memset(ctx, 0, sizeof(*ctx)); + ctx->capacityWords = 2 * 128 / (8 * sizeof(unsigned long long)); + return UCL_OK; +} + +int ucl_sha3_224_init(ucl_sha3_ctx_t *ctx) +{ + if (ctx == NULL) + return UCL_INVALID_INPUT; + memset(ctx, 0, sizeof(*ctx)); + ctx->capacityWords = 448 / (8 * sizeof(unsigned long long)); + return UCL_OK; +} + +int ucl_sha3_256_init(ucl_sha3_ctx_t *ctx) +{ + if (ctx == NULL) + return UCL_INVALID_INPUT; + memset(ctx, 0, sizeof(*ctx)); + ctx->capacityWords = 512 / (8 * sizeof(unsigned long long)); + return UCL_OK; +} + +int ucl_shake256_init(ucl_sha3_ctx_t *ctx) +{ + return ucl_sha3_256_init(ctx); +} + +int ucl_sha3_384_init(ucl_sha3_ctx_t *ctx) +{ + if (ctx == NULL) + return UCL_INVALID_INPUT; + memset(ctx, 0, sizeof(*ctx)); + ctx->capacityWords = 768 / (8 * sizeof(unsigned long long)); + return UCL_OK; +} + +int ucl_sha3_512_init(ucl_sha3_ctx_t *ctx) +{ + if (ctx == NULL) + return UCL_INVALID_INPUT; + memset(ctx, 0, sizeof(*ctx)); + ctx->capacityWords = 1024 / (8 * sizeof(unsigned long long)); + return UCL_OK; +} + +int ucl_sha3_core(ucl_sha3_ctx_t *ctx, const unsigned char *bufIn, + unsigned int len) +{ + unsigned int old_tail = (8 - ctx->byteIndex) & 7; + size_t words; + int tail; + size_t i; + const unsigned char *buf = bufIn; + + if (ctx == NULL) + return UCL_INVALID_INPUT; + if (bufIn == NULL) + return UCL_INVALID_INPUT; + if (len < old_tail) { + while (len--) + ctx->saved |= (unsigned long long)(*(buf++)) + << ((ctx->byteIndex++) * 8); + return UCL_OK; + } + + if (old_tail) { + len -= old_tail; + while (old_tail--) + ctx->saved |= (unsigned long long)(*(buf++)) + << ((ctx->byteIndex++) * 8); + ctx->s[ctx->wordIndex] ^= ctx->saved; + ctx->byteIndex = 0; + ctx->saved = 0; + if (++ctx->wordIndex == + ((int)SHA3_SPONGE_WORDS - ctx->capacityWords)) { + kcf(ctx->s); + ctx->wordIndex = 0; + } + } + + words = len / sizeof(unsigned long long); + tail = (int)(len - words * sizeof(unsigned long long)); + for (i = 0; i < words; i++, buf += sizeof(unsigned long long)) { + const unsigned long long t = + (unsigned long long)(buf[0]) | + ((unsigned long long)(buf[1]) << 8 * 1) | + ((unsigned long long)(buf[2]) << 8 * 2) | + ((unsigned long long)(buf[3]) << 8 * 3) | + ((unsigned long long)(buf[4]) << 8 * 4) | + ((unsigned long long)(buf[5]) << 8 * 5) | + ((unsigned long long)(buf[6]) << 8 * 6) | + ((unsigned long long)(buf[7]) << 8 * 7); + ctx->s[ctx->wordIndex] ^= t; + + if (++ctx->wordIndex == + ((int)SHA3_SPONGE_WORDS - ctx->capacityWords)) { + kcf(ctx->s); + ctx->wordIndex = 0; + } + } + + while (tail--) + ctx->saved |= (unsigned long long)(*(buf++)) + << ((ctx->byteIndex++) * 8); + + return UCL_OK; +} + +int ucl_sha3_finish(unsigned char *digest, ucl_sha3_ctx_t *ctx) +{ + int i; + + // SHA3 version + ctx->s[ctx->wordIndex] ^= + (ctx->saved ^ + ((unsigned long long)((unsigned long long)(0x02 | (1 << 2)) + << ((ctx->byteIndex) * 8)))); + ctx->s[(int)SHA3_SPONGE_WORDS - ctx->capacityWords - 1] ^= + (unsigned long long)0x8000000000000000UL; + kcf(ctx->s); + + if (digest == NULL) + return UCL_INVALID_OUTPUT; + if (ctx == NULL) + return UCL_INVALID_INPUT; + + for (i = 0; i < (int)SHA3_SPONGE_WORDS; i++) { + const unsigned int t1 = (unsigned int)ctx->s[i]; + const unsigned int t2 = (unsigned int)((ctx->s[i] >> 16) >> 16); + + ctx->sb[i * 8 + 0] = (unsigned char)(t1); + ctx->sb[i * 8 + 1] = (unsigned char)(t1 >> 8); + ctx->sb[i * 8 + 2] = (unsigned char)(t1 >> 16); + ctx->sb[i * 8 + 3] = (unsigned char)(t1 >> 24); + ctx->sb[i * 8 + 4] = (unsigned char)(t2); + ctx->sb[i * 8 + 5] = (unsigned char)(t2 >> 8); + ctx->sb[i * 8 + 6] = (unsigned char)(t2 >> 16); + ctx->sb[i * 8 + 7] = (unsigned char)(t2 >> 24); + } + + for (i = 0; i < (int)SHA3_SPONGE_WORDS * 8; i++) + digest[i] = ctx->sb[i]; + + return UCL_OK; +} + +int ucl_shake_finish(unsigned char *digest, ucl_sha3_ctx_t *ctx) +{ + int i; + + if (ctx == NULL) + return UCL_INVALID_INPUT; + if (digest == NULL) + return UCL_INVALID_OUTPUT; + + ctx->s[ctx->wordIndex] ^= (ctx->saved ^ ((unsigned long long)(0x1F) + << ((ctx->byteIndex) * 8))); + i = (int)SHA3_SPONGE_WORDS - ctx->capacityWords - 1; + ctx->s[(int)SHA3_SPONGE_WORDS - ctx->capacityWords - 1] ^= + (unsigned long long)(0x8000000000000000UL); + kcf(ctx->s); + + for (i = 0; i < (int)SHA3_SPONGE_WORDS; i++) { + const unsigned int t1 = (unsigned int)ctx->s[i]; + const unsigned int t2 = (unsigned int)((ctx->s[i] >> 16) >> 16); + + ctx->sb[i * 8 + 0] = (unsigned char)(t1); + ctx->sb[i * 8 + 1] = (unsigned char)(t1 >> 8); + ctx->sb[i * 8 + 2] = (unsigned char)(t1 >> 16); + ctx->sb[i * 8 + 3] = (unsigned char)(t1 >> 24); + ctx->sb[i * 8 + 4] = (unsigned char)(t2); + ctx->sb[i * 8 + 5] = (unsigned char)(t2 >> 8); + ctx->sb[i * 8 + 6] = (unsigned char)(t2 >> 16); + ctx->sb[i * 8 + 7] = (unsigned char)(t2 >> 24); + } + + for (i = 0; i < (int)SHA3_SPONGE_WORDS * 8; i++) + digest[i] = ctx->sb[i]; + + return UCL_OK; +} + +int ucl_sha3_224(unsigned char *digest, unsigned char *msg, unsigned int msgLen) +{ + ucl_sha3_ctx_t ctx; + + if (msg == NULL) + return UCL_INVALID_INPUT; + if (digest == NULL) + return UCL_INVALID_OUTPUT; + if (ucl_sha3_224_init(&ctx) != UCL_OK) + return (UCL_ERROR); + if (ucl_sha3_core(&ctx, msg, msgLen) != UCL_OK) + return (UCL_ERROR); + if (ucl_sha3_finish(digest, &ctx) != UCL_OK) + return (UCL_ERROR); + + return UCL_OK; +} + +int ucl_sha3_256(unsigned char *digest, unsigned char *msg, unsigned int msgLen) +{ + ucl_sha3_ctx_t ctx; + + if (msg == NULL) + return UCL_INVALID_INPUT; + if (digest == NULL) + return UCL_INVALID_OUTPUT; + + if (ucl_sha3_256_init(&ctx) != UCL_OK) + return (UCL_ERROR); + if (ucl_sha3_core(&ctx, msg, msgLen) != UCL_OK) + return (UCL_ERROR); + if (ucl_sha3_finish(digest, &ctx) != UCL_OK) + return (UCL_ERROR); + + return UCL_OK; +} + +int ucl_shake128(unsigned char *digest, unsigned char *msg, unsigned int msgLen) +{ + ucl_sha3_ctx_t ctx; + + if (msg == NULL) + return UCL_INVALID_INPUT; + if (digest == NULL) + return UCL_INVALID_OUTPUT; + + if (ucl_shake128_init(&ctx) != UCL_OK) + return (UCL_ERROR); + if (ucl_sha3_core(&ctx, msg, msgLen) != UCL_OK) + return (UCL_ERROR); + if (ucl_shake_finish(digest, &ctx) != UCL_OK) + return (UCL_ERROR); + + return UCL_OK; +} + +int ucl_sha3_384(unsigned char *digest, unsigned char *msg, unsigned int msgLen) +{ + ucl_sha3_ctx_t ctx; + + if (msg == NULL) + return UCL_INVALID_INPUT; + if (digest == NULL) + return UCL_INVALID_OUTPUT; + + if (ucl_sha3_384_init(&ctx) != UCL_OK) + return (UCL_ERROR); + if (ucl_sha3_core(&ctx, msg, msgLen) != UCL_OK) + return (UCL_ERROR); + if (ucl_sha3_finish(digest, &ctx) != UCL_OK) + return (UCL_ERROR); + + return UCL_OK; +} + +int ucl_sha3_512(unsigned char *digest, unsigned char *msg, unsigned int msgLen) +{ + ucl_sha3_ctx_t ctx; + + if (msg == NULL) + return UCL_INVALID_INPUT; + if (digest == NULL) + return UCL_INVALID_OUTPUT; + + if (UCL_OK != ucl_sha3_512_init(&ctx)) + return (UCL_ERROR); + if (ucl_sha3_core(&ctx, msg, msgLen) != UCL_OK) + return (UCL_ERROR); + if (ucl_sha3_finish(digest, &ctx) != UCL_OK) + return (UCL_ERROR); + + return UCL_OK; +} +int ucl_shake256(unsigned char *digest, unsigned char *msg, unsigned int msgLen) +{ + ucl_sha3_ctx_t ctx; + + if (msg == NULL) + return UCL_INVALID_INPUT; + if (digest == NULL) + return UCL_INVALID_OUTPUT; + + if (ucl_shake256_init(&ctx) != UCL_OK) + return (UCL_ERROR); + if (ucl_sha3_core(&ctx, msg, msgLen) != UCL_OK) + return (UCL_ERROR); + if (ucl_shake_finish(digest, &ctx) != UCL_OK) + return (UCL_ERROR); + + return UCL_OK; +} +#endif //SHA3 diff --git a/drivers/power/supply/maxim/ucl_sha3.h b/drivers/power/supply/maxim/ucl_sha3.h new file mode 100644 index 000000000000..706056d96b8f --- /dev/null +++ b/drivers/power/supply/maxim/ucl_sha3.h @@ -0,0 +1,269 @@ +/* sha3.h */ +#ifndef _UCL_SHA3_H +#define _UCL_SHA3_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define UCL_SHA3_224_HASHSIZE 28 +#define UCL_SHA3_256_HASHSIZE 32 +#define UCL_SHA3_384_HASHSIZE 48 +#define UCL_SHA3_512_HASHSIZE 64 +#define UCL_SHA3_MAX_PERMSIZE 25 +#define UCL_SHA3_MAXQRATE_QWORDS 24 + +#define UCL_SHA3 2 +#define UCL_SHA3_224 9 +#define UCL_SHA3_256 10 +#define UCL_SHA3_384 11 +#define UCL_SHA3_512 12 +/** +* SHA3 Algorithm context. +*/ +/** @file ucl_sha3.h +* @defgroup UCL_SHA3 SHA3 +* Secure Hash Algorithm 3, from FIPS 202. +* +* @par Header: +* @link ucl_sha3.h ucl_sha3.h @endlink +* +* SHA-3 is a data-digest algorithm and a component of +* the Standard FIPS 202. +* The algorithm takes as input a data of arbitrary length and +* produces as output 224-bit, 256-bit, 384-bit or 512-bit "fingerprint" or "data digest" +* of the input.@n +* @n +* +* SHA3 Descriptor: @n +* @li Hash length : 224/256/384/512 bits +* +* @ingroup UCL_HASH +*/ + +/** The SHA3 context. +* This structure is associated to the 'step by step' process. +* +* @ingroup UCL_SHA3 +*/ + +typedef struct sha3_ctx { + /* 1600 bits algorithm hashing state */ + unsigned long long hash[UCL_SHA3_MAX_PERMSIZE]; + /* 1536-bit buffer for leftovers */ + unsigned long long message[UCL_SHA3_MAXQRATE_QWORDS]; + /* count of bytes in the message[] buffer */ + unsigned int rest; + /* size of a message block processed at once */ + unsigned int block_size; +} sha3_ctx; + +#define SHA3_SPONGE_WORDS \ + (((1600) / 8 /*bits to byte*/) / sizeof(unsigned long long)) + +typedef struct sha3_context_ { + unsigned long long saved; + union { + unsigned long long s[SHA3_SPONGE_WORDS]; + unsigned char sb[SHA3_SPONGE_WORDS * 8]; + }; + int byteIndex; /* 0..7--the next byte after the set one + * (starts from 0; 0--none are buffered) */ + int wordIndex; /* 0..24--the next word to integrate input + * (starts from 0) */ + int capacityWords; /* the double size of the hash output in + * words (e.g. 16 for Keccak 512) */ +} ucl_sha3_ctx_t; + +// methods for calculating the hash function + +/*============================================================================*/ +/** SHA3-224 Init. +* The initialisation of SHA3-224. +* +* @param[in,out] context Pointer to the context +* +* @return Error code +* +* @retval #UCL_OK if no error occurred +* @retval #UCL_INVALID_INPUT if @p context is #NULL +* +* @ingroup UCL_SHA3 +*/ +int ucl_sha3_224_init(ucl_sha3_ctx_t *ctx); +/*============================================================================*/ +/** SHA3-256 Init. +* The initialisation of SHA3-256. +* +* @param[in,out] context Pointer to the context +* +* @return Error code +* +* @retval #UCL_OK if no error occurred +* @retval #UCL_INVALID_INPUT if @p context is #NULL +* +* @ingroup UCL_SHA3 +*/ +int ucl_sha3_256_init(ucl_sha3_ctx_t *ctx); +/*============================================================================*/ +/** SHA3-384 Init. +* The initialisation of SHA3-384. +* +* @param[in,out] context Pointer to the context +* +* @return Error code +* +* @retval #UCL_OK if no error occurred +* @retval #UCL_INVALID_INPUT if @p context is #NULL +* +* @ingroup UCL_SHA3 +*/ +int ucl_sha3_384_init(ucl_sha3_ctx_t *ctx); +/*============================================================================*/ +/** SHA3-512 Init. +* The initialisation of SHA3-512. +* +* @param[in,out] context Pointer to the context +* +* @return Error code +* +* @retval #UCL_OK if no error occurred +* @retval #UCL_INVALID_INPUT if @p context is #NULL +* +* @ingroup UCL_SHA3 +*/ +int ucl_sha3_512_init(ucl_sha3_ctx_t *ctx); +/*============================================================================*/ +/** SHA3 Core. +* The core of SHA3, common to all SHA3 hash functions. +* +* @param[in,out] context Pointer to the context +* @param[in] data Pointer to the data +* @param[in] data_byteLen Data byte length +* +* @warning #ucl_sha3-*_init must be processed before, and +* #ucl_sha3_finish should be processed to get the final hash. +* +* @return Error code +* +* @retval #UCL_OK if no error occurred +* @retval #UCL_NOP if @p data_byteLen = 0 or if @p data is the pointer #NULL +* +* @ingroup UCL_SHA3 +*/ +int ucl_sha3_core(ucl_sha3_ctx_t *ctx, const unsigned char *bufIn, + unsigned int len); +/*============================================================================*/ +/** SHA3 Finish. +* Finish the process of SHA3, common to all SHA3 hash functions. +* +* @pre Hash byte length is equal to 28/32/48 or 64 bytes +* +* @param[out] hash Pointer to the digest +* @param[in,out] context Pointer to the context +* +* @warning #ucl_sha3_*_init and #ucl_sha3_core must be processed before. +* +* @return Error code +* +* @retval #UCL_OK if no error occurred +* @retval #UCL_INVALID_OUTPUT if @p hash is the pointer #NULL +* @retval #UCL_INVALID_INPUT if @p context is the pointer #NULL +* +* @ingroup UCL_SHA3 +*/ + +int ucl_sha3_finish(unsigned char *digest, ucl_sha3_ctx_t *ctx); + +/*============================================================================*/ +/** SHA3-224. +* The complete process of SHA3-224. +* +* @pre Hash byte length is equal to 28 +* +* @param[out] hash Pointer to the digest +* @param[in] data Pointer to the data +* @param[in] data_byteLen Data byte length +* +* @return Error code +* +* @retval #UCL_OK if no error occurred +* @retval #UCL_INVALID_OUTPUT if @p hash is #NULL +* +* @ingroup UCL_SHA3 +*/ + +int ucl_sha3_224(unsigned char *digest, unsigned char *msg, + unsigned int msgLen); + +/*============================================================================*/ +/** SHA3-256. +* The complete process of SHA3-256. +* +* @pre Hash byte length is equal to 32 +* +* @param[out] hash Pointer to the digest +* @param[in] data Pointer to the data +* @param[in] data_byteLen Data byte length +* +* @return Error code +* +* @retval #UCL_OK if no error occurred +* @retval #UCL_INVALID_OUTPUT if @p hash is #NULL +* +* @ingroup UCL_SHA3 +*/ +int ucl_sha3_256(unsigned char *digest, unsigned char *msg, + unsigned int msgLen); + +/*============================================================================*/ +/** SHA3-384. +* The complete process of SHA3-384. +* +* @pre Hash byte length is equal to 48 +* +* @param[out] hash Pointer to the digest +* @param[in] data Pointer to the data +* @param[in] data_byteLen Data byte length +* +* @return Error code +* +* @retval #UCL_OK if no error occurred +* @retval #UCL_INVALID_OUTPUT if @p hash is #NULL +* +* @ingroup UCL_SHA3 +*/ +int ucl_sha3_384(unsigned char *digest, unsigned char *msg, + unsigned int msgLen); + +/*============================================================================*/ +/** SHA3-512. +* The complete process of SHA3-512. +* +* @pre Hash byte length is equal to 64 +* +* @param[out] hash Pointer to the digest +* @param[in] data Pointer to the data +* @param[in] data_byteLen Data byte length +* +* @return Error code +* +* @retval #UCL_OK if no error occurred +* @retval #UCL_INVALID_OUTPUT if @p hash is #NULL +* +* @ingroup UCL_SHA3 +*/ +int ucl_sha3_512(unsigned char *digest, unsigned char *msg, + unsigned int msgLen); +int ucl_shake128_init(ucl_sha3_ctx_t *ctx); +int ucl_shake256_init(ucl_sha3_ctx_t *ctx); +int ucl_shake_finish(unsigned char *hash, ucl_sha3_ctx_t *ctx); +int ucl_shake128(unsigned char *digest, unsigned char *msg, + unsigned int msgLen); +int ucl_shake256(unsigned char *digest, unsigned char *msg, + unsigned int msgLen); +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* _UCL_SHA3_H */ diff --git a/drivers/power/supply/nuvolta/Kconfig b/drivers/power/supply/nuvolta/Kconfig new file mode 100644 index 000000000000..416a0cecd229 --- /dev/null +++ b/drivers/power/supply/nuvolta/Kconfig @@ -0,0 +1,30 @@ +menu "NuVolta Technologies Inc. Charger support" + +config CHARGER_NU1618 + tristate "nuvolta nu1618 wireless charger driver" + help + say y here to enable support for nu1618 charger driver. + +config RX1619_TRIM + tristate "RX1619 TRIM" + depends on I2C + help + Say Y to include support for rx1619 wireless Charger. + RX1619 is a wireless battery charger chip. + The driver supports charger enable/disable. + The driver reports the charger status via the power supply framework. + The driver controls rx1619 via I2C and + supports device-tree interface. + +config RX1619 + tristate "RX1619 wireless Charger" + depends on I2C + help + Say Y to include support for rx1619 wireless Charger. + RX1619 is a wireless battery charger chip. + The driver supports charger enable/disable. + The driver reports the charger status via the power supply framework. + The driver controls rx1619 via I2C and + supports device-tree interface. + +endmenu diff --git a/drivers/power/supply/nuvolta/Makefile b/drivers/power/supply/nuvolta/Makefile new file mode 100644 index 000000000000..1de8b38b5eca --- /dev/null +++ b/drivers/power/supply/nuvolta/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_CHARGER_NU1618) += rx1618.o +obj-$(CONFIG_RX1619_TRIM) += rx1619_trim.o +obj-$(CONFIG_RX1619) += rx1619.o diff --git a/drivers/power/supply/nuvolta/rx1618.c b/drivers/power/supply/nuvolta/rx1618.c new file mode 100644 index 000000000000..f5d4edf23836 --- /dev/null +++ b/drivers/power/supply/nuvolta/rx1618.c @@ -0,0 +1,1635 @@ +/** + * @file rx1618.c + * @author + * @date Tuesday, January 9th 2018 + * + * @brief + * + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rx1618.h" + +#define RX1618_DELAY_MS 30000 +#define EPP_MODE 1 +#define BPP_MODE 0 +#define MIN_VBUCK 4000 +#define MAX_VBUCK 11000 +#define AP_REV_DATA_OK 0xaa +#define AP_SENT_DATA_OK 0x55 +#define PRIVATE_VBUCK_SET_CMD 0x80 +#define PRIVATE_ID_CMD 0x86 +#define PRIVATE_USB_TYPE_CMD 0x87 +#define PRIVATE_FAST_CHG_CMD 0x88 +#define PRIVATE_PRODUCT_TEST_CMD 0x89 +#define PRIVATE_FOD_TEST_CMD 0x8A +#define PRIVATE_TX_HW_ID_CMD 0x8b + +/* used registers define */ +#define REG_RX_SENT_CMD 0x0000 +#define REG_RX_SENT_DATA1 0x0001 +#define REG_RX_SENT_DATA2 0x0002 +#define REG_RX_SENT_DATA3 0x0003 +#define REG_RX_SENT_DATA4 0x0004 +#define REG_RX_SENT_DATA5 0x0005 +#define REG_RX_REV_CMD 0x0020 +#define REG_RX_REV_DATA1 0x0021 +#define REG_RX_REV_DATA2 0x0022 +#define REG_RX_REV_DATA3 0x0023 +#define REG_RX_REV_DATA4 0x0024 +#define REG_RX_REV_DATA5 0x0025 +#define REG_RX_VRECT 0x000a +#define REG_RX_IRECT 0x000b +#define REG_RX_VBUCK_1 0x0008 +#define REG_RX_VBUCK_2 0x0009 +#define REG_AP_RX_COMM 0x000C + +static struct rx1618_chg *g_chip; +static int g_Delta = 0; +static bool int_done_flag = false; +static u8 g_light_screen_flag = 0; +static u8 g_sar_done_flag = 0; +static u8 g_fast_chg_flag = 0; +static u8 g_id_done_flag = 0; +static u8 g_cali_done_flag = 0; +static u8 g_usb_type_flag = 0; +static u8 g_fw_id = 0; +static u8 g_hw_id_h, g_hw_id_l; +static u8 g_epp_or_bpp = BPP_MODE; + +struct rx1618_chg { + char *name; + struct i2c_client *client; + struct device *dev; + struct regmap *regmap; + int irq_gpio; + int enable_gpio; + int chip_enable; + int online; + struct delayed_work wireless_work; + struct delayed_work wireless_int_work; + struct mutex irq_complete; + struct mutex wireless_chg_lock; + struct mutex wireless_chg_int_lock; + + struct power_supply *wip_psy; + struct power_supply *dc_psy; + struct power_supply_desc wip_psy_d; + struct power_supply *wireless_psy; + int epp; + int auth; +}; + +static int rx1618_read(struct rx1618_chg *chip, u8 *val, u16 addr) +{ + unsigned int temp; + int rc; + + rc = regmap_read(chip->regmap, addr, &temp); + if (rc >= 0) { + *val = (u8)temp; + //dev_err(chip->dev, "[rx1618] [%s] [0x%04x] = [0x%x] \n", __func__, addr, *val); + } + + return rc; +} + +static int rx1618_write(struct rx1618_chg *chip, u8 val, u16 addr) +{ + int rc = 0; + + rc = regmap_write(chip->regmap, addr, val); + if (rc >= 0) { + //dev_err(chip->dev, "[rx1618] [%s] [0x%04x] = [0x%x] \n", __func__, addr, *val); + } + + return rc; +} + +unsigned int rx1618_get_rx_vrect(struct rx1618_chg *chip) +{ + u8 data = 0; + u16 vrect = 0; + + //if(!chip->online) + // return -EINVAL; + + rx1618_read(chip, &data, REG_RX_VRECT); + vrect = (22500 * data) >> 8; + + dev_err(chip->dev, "[rx1618] [%s] data = 0x%x, vrect=%d mV\n", __func__, + data, vrect); + + return vrect; +} + +unsigned int rx1618_get_rx_irect(struct rx1618_chg *chip) +{ + u8 data = 0; + u16 irect = 0; + + //if(!chip->online) + // return -EINVAL; + + rx1618_read(chip, &data, REG_RX_IRECT); + irect = (2500 * data) >> 8; + + dev_err(chip->dev, "[rx1618] [%s] data = 0x%x, irect=%d mA \n", + __func__, data, irect); + + return irect; +} + +unsigned int rx1618_get_rx_vbuck(struct rx1618_chg *chip) +{ + u16 vbuck = 0; + u8 data1 = 0; + u8 data2 = 0; + u16 data = 0; + + // if(!chip->online) + // return -EINVAL; + + rx1618_read(chip, &data1, REG_RX_VBUCK_1); + rx1618_read(chip, &data2, REG_RX_VBUCK_2); + + data = (data1 << 2) + (data2 & 0x03); + vbuck = (2500 * 590 / 120 * data) >> 10; + + dev_err(chip->dev, + "[rx1618] [%s] Vbuck: data=0x%x, vbuck=%d mV ,data1 = 0x%x, data2= 0x%x \n", + __func__, data, vbuck, data1, data2); + + return vbuck; +} + +unsigned int rx1618_get_rx_ibuck(struct rx1618_chg *chip) +{ + u16 ibuck = 0; + + //if(!chip->online) + // return -EINVAL; + + ibuck = (rx1618_get_rx_vrect(chip) * rx1618_get_rx_irect(chip) * 95) / + (rx1618_get_rx_vbuck(chip) * 100); + + dev_err(chip->dev, "[rx1618] [%s] Ibuck = %d mA\n", __func__, ibuck); + + return ibuck; +} + +bool rx1618_is_vbuck_on(struct rx1618_chg *chip) +{ + bool vbuck_status = false; + unsigned int voltage = 0; + + voltage = rx1618_get_rx_vbuck(chip); + + dev_err(chip->dev, "[rx1618] [%s] Vbuck = %d \n", __func__, voltage); + + if ((voltage > MIN_VBUCK) && (voltage < MAX_VBUCK)) //4V~11V + { + vbuck_status = true; + } else { + vbuck_status = false; + } + + return vbuck_status; +} + +int rx1618_set_vbuck(struct rx1618_chg *chip, int volt) +{ + u8 data = 0; + + if ((volt < 5166) && + (volt > 9609)) //V bus_set =5166000uV+21224uV*[Vbus_set(0:7)] DEC + { + data = 0; + } else { + data = (volt - 5166) * 1000 / 21224; + } + + data = data + g_Delta; + dev_err(chip->dev, "[rx1618] [%s] data = 0x%x, g_Delta=%d \n", __func__, + data, g_Delta); + + rx1618_write(chip, PRIVATE_VBUCK_SET_CMD, + REG_RX_SENT_CMD); //sent set vbuck cmd + rx1618_write(chip, data, REG_RX_SENT_DATA1); //sent data0 + + rx1618_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); + + return 0; +} + +bool rx1618_check_firmware(struct rx1618_chg *chip) +{ + u8 *read_buffer = NULL; + int i = 0; + + read_buffer = (u8 *)vmalloc(20000); + + rx1618_write(chip, 0xB2, 0x0017); + rx1618_write(chip, 0xB3, 0x0017); + + dev_err(chip->dev, "[rx1618] [%s] enter \n", __func__); + + for (i = 0; i < (sizeof(fw_data) / 4); i++) { + rx1618_write(chip, ((0 + i * 4) / 256), 0x0010); //address_H + rx1618_write(chip, ((0 + i * 4) % 256), 0x0011); //address_L + + rx1618_read(chip, (read_buffer + 4 * i + 0), 0x0013); + rx1618_read(chip, (read_buffer + 4 * i + 1), 0x0014); + rx1618_read(chip, (read_buffer + 4 * i + 2), 0x0015); + rx1618_read(chip, (read_buffer + 4 * i + 3), 0x0016); + } + + rx1618_write(chip, 0xB2, 0x0017); + rx1618_write(chip, 0x00, 0x0017); + rx1618_write(chip, 0x55, 0x2017); + + for (i = 0; i < sizeof(fw_data); i++) { + if (read_buffer[i] != ((~fw_data[i]) & 0xff)) { + dev_err(chip->dev, + "[rx1618] [%s] fw download Fail! read_buffer[i]=0x%x, ~fw_data[i]=0x%x, i=%d, sizeof(fw_data)=%ld\n", + __func__, read_buffer[i], (~fw_data[i]) & 0xff, + i, sizeof(fw_data)); + + vfree(read_buffer); + return false; + } + } + + dev_err(chip->dev, "[rx1618] [%s] i=%d, sizeof(fw_data)=%ld\n", + __func__, i, sizeof(fw_data)); + + if (i == sizeof(fw_data)) { + dev_err(chip->dev, "[rx1618] [%s] fw download Success! \n", + __func__); + vfree(read_buffer); + return true; + } else { + vfree(read_buffer); + return false; + } +} + +bool rx1618_download_firmware(struct rx1618_chg *chip) +{ + bool check_status = false; + int i = 0; + + cancel_delayed_work_sync(&chip->wireless_work); + cancel_delayed_work_sync(&chip->wireless_int_work); + + rx1618_write(chip, 0x55, 0x2017); + rx1618_write(chip, 0x69, 0x2017); + rx1618_write(chip, 0x96, 0x2017); + rx1618_write(chip, 0x66, 0x2017); + rx1618_write(chip, 0x99, 0x2017); + rx1618_write(chip, 0x00, 0x2018); + rx1618_write(chip, 0x00, 0x2019); + rx1618_write(chip, 0x5A, 0x0001); + rx1618_write(chip, 0x3C, 0x0002); + rx1618_write(chip, 0xA5, 0x0003); + rx1618_write(chip, 0xC3, 0x0004); + rx1618_write(chip, 0x60, 0x1000); + rx1618_write(chip, 0x9C, 0x0017); + rx1618_write(chip, 0x9D, 0x0017); + rx1618_write(chip, 0x00, 0x0010); + rx1618_write(chip, 0x00, 0x0011); + rx1618_write(chip, 0x01, 0x0019); + mdelay(180); + rx1618_write(chip, 0x00, 0x0019); + rx1618_write(chip, 0x9C, 0x0017); + rx1618_write(chip, 0xA2, 0x0017); + rx1618_write(chip, 0xA3, 0x0017); + rx1618_write(chip, 0x01, 0x0019); + mdelay(20); + rx1618_write(chip, 0x00, 0x0019); + rx1618_write(chip, 0xA2, 0x0017); + rx1618_write(chip, 0x80, 0x0017); + mdelay(20); + rx1618_write(chip, 0x5A, 0x0001); + rx1618_write(chip, 0x3C, 0x0002); + rx1618_write(chip, 0xA5, 0x0003); + rx1618_write(chip, 0xC3, 0x0004); + rx1618_write(chip, 0x60, 0x1000); + rx1618_write(chip, 0x9C, 0x0017); + rx1618_write(chip, 0x9D, 0x0017); + rx1618_write(chip, 0x00, 0x0010); + rx1618_write(chip, 0x00, 0x0011); + rx1618_write(chip, 0x01, 0x0019); + mdelay(180); + rx1618_write(chip, 0x00, 0x0019); + rx1618_write(chip, 0x9C, 0x0017); + rx1618_write(chip, 0xA2, 0x0017); + rx1618_write(chip, 0xA3, 0x0017); + rx1618_write(chip, 0x01, 0x0019); + mdelay(20); + rx1618_write(chip, 0x00, 0x0019); + rx1618_write(chip, 0xA2, 0x0017); + rx1618_write(chip, 0x80, 0x0017); + rx1618_write(chip, 0x9C, 0x0017); + rx1618_write(chip, 0x9D, 0x0017); + rx1618_write(chip, 0x20, 0x0010); + rx1618_write(chip, 0x00, 0x0011); + rx1618_write(chip, 0x01, 0x0019); + rx1618_write(chip, 0x00, 0x0019); + rx1618_write(chip, 0x9C, 0x0017); + rx1618_write(chip, 0xA2, 0x0017); + rx1618_write(chip, 0xA3, 0x0017); + rx1618_write(chip, 0x01, 0x0019); + mdelay(20); + rx1618_write(chip, 0x00, 0x0019); + rx1618_write(chip, 0xA2, 0x0017); + rx1618_write(chip, 0x80, 0x0017); + rx1618_write(chip, 0x00, 0x0010); + rx1618_write(chip, 0x00, 0x0011); + + rx1618_write(chip, (~fw_data[0]), 0x0012); + rx1618_write(chip, 0x92, 0x0017); + rx1618_write(chip, 0x93, 0x0017); + rx1618_write(chip, 0x69, 0x001A); + + for (i = 1; i < (sizeof(fw_data)); i++) { + rx1618_write(chip, (~fw_data[i]), 0x0012); + udelay(20); + } + + dev_err(chip->dev, + "[rx1618] [%s] fw download Success! Firmware total data: %d bytes \n", + __func__, i); + + rx1618_write(chip, 0x92, 0x0017); + rx1618_write(chip, 0x80, 0x0017); + rx1618_write(chip, 0x77, 0x001A); + + mdelay(500); + check_status = rx1618_check_firmware(chip); + + if (check_status) { + dev_err(chip->dev, + "[rx1618] [%s] RX1618 download firmware and check firmware Success! \n", + __func__); + return true; + } else { + dev_err(chip->dev, + "[rx1618] [%s] RX1618 download firmware Fail, Please try again !!! \n", + __func__); + return false; + } +} + +static void determine_initial_status(struct rx1618_chg *chip) +{ + bool vbuck_on = false; + //union power_supply_propval prop = {0, }; + + vbuck_on = rx1618_is_vbuck_on(chip); + if (vbuck_on && !chip->online) { + chip->online = 1; + //prop.intval = vbuck_on; + //power_supply_set_property(chip->batt_psy, POWER_SUPPLY_PROP_WIRELESS_ONLINE, &prop); + } + + dev_err(chip->dev, "[rx1618] [%s] initial vbuck_on = %d, online = %d\n", + __func__, vbuck_on, chip->online); +} + +int rx1618_chip_init(struct rx1618_chg *chip) +{ + return 0; +} + +void rx1618_dump_reg(void) +{ + u8 data[32] = { 0 }; + + rx1618_read(g_chip, &data[0], 0x0000); + rx1618_read(g_chip, &data[1], 0x0001); + rx1618_read(g_chip, &data[2], 0x0002); + rx1618_read(g_chip, &data[3], 0x0003); + rx1618_read(g_chip, &data[4], 0x0004); + rx1618_read(g_chip, &data[5], 0x0005); + rx1618_read(g_chip, &data[6], 0x0008); + rx1618_read(g_chip, &data[7], 0x0009); + rx1618_read(g_chip, &data[8], 0x000A); + rx1618_read(g_chip, &data[9], 0x000B); + rx1618_read(g_chip, &data[10], 0x000C); + rx1618_read(g_chip, &data[11], 0x0020); + rx1618_read(g_chip, &data[12], 0x0021); + rx1618_read(g_chip, &data[13], 0x0022); + rx1618_read(g_chip, &data[14], 0x0023); + rx1618_read(g_chip, &data[15], 0x0024); + + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x0000=0x%x\n", __func__, + data[0]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x0001=0x%x\n", __func__, + data[1]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x0002=0x%x\n", __func__, + data[2]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x0003=0x%x\n", __func__, + data[3]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x0004=0x%x\n", __func__, + data[4]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x0005=0x%x\n", __func__, + data[5]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x0008=0x%x\n", __func__, + data[6]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x0009=0x%x\n", __func__, + data[7]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x000A=0x%x\n", __func__, + data[8]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x000B=0x%x\n", __func__, + data[9]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x000C=0x%x\n", __func__, + data[10]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x0020=0x%x\n", __func__, + data[11]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x0021=0x%x\n", __func__, + data[12]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x0022=0x%x\n", __func__, + data[13]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x0023=0x%x\n", __func__, + data[14]); + dev_err(g_chip->dev, "[rx1618] [%s] REG:0x0024=0x%x\n", __func__, + data[15]); +} + +#define N 2 +//0x000b[0:3] 0000:no charger, 0001:SDP, 0010:CDP, 0011:DCP, 0101:QC2-other, +//0110:QC3-other, 0111:PD, 1000:fail charger, 1001:QC3-27W, 1010:PD-27W +#define EPP_MODE_CURRENT 300000 * N +#define DC_OTHER_CURRENT 400000 * N +#define DC_LOW_CURRENT 100000 * N //200mA +#define DC_SDP_CURRENT 400000 * N +#define DC_DCP_CURRENT 400000 * N +#define DC_CDP_CURRENT 400000 * N +#define DC_QC2_CURRENT 500000 * N +#define DC_QC3_CURRENT 500000 * N +#define DC_QC3_20W_CURRENT 1000000 * N //2A +#define DC_PD_CURRENT 500000 * N +#define DC_PD_20W_CURRENT 1000000 * N //2A +void rx1618_set_pmi_icl(struct rx1618_chg *chip, int mA) +{ + union power_supply_propval val = { + 0, + }; + + if (!chip->dc_psy) { + chip->dc_psy = power_supply_get_by_name("dc"); + if (!chip->dc_psy) { + dev_err(chip->dev, "[rx1618] [%s] no dc_psy,return\n", + __func__); + return; + } + } + val.intval = mA; + power_supply_set_property(chip->dc_psy, POWER_SUPPLY_PROP_CURRENT_MAX, + &val); + dev_err(chip->dev, "[rx1618] [%s] [rx1618] set icl: %d\n", __func__, + val.intval); +} + +static void rx1618_wireless_work(struct work_struct *work) +{ + struct rx1618_chg *chip = + container_of(work, struct rx1618_chg, wireless_work.work); + + mutex_lock(&chip->wireless_chg_lock); + schedule_delayed_work(&chip->wireless_work, + msecs_to_jiffies(RX1618_DELAY_MS)); + mutex_unlock(&chip->wireless_chg_lock); + + dev_err(chip->dev, "[rx1618] [%s] enter \n", __func__); + + return; +} + +static void rx1618_wireless_int_work(struct work_struct *work) +{ + int i = 0; + int uA = 0; + u16 irect = 0; + u16 vrect = 0; + u8 data1, data2, data3, data4, privite_cmd, tx_cmd, usb_type; + u8 data_h, data_l, header, header_length; + union power_supply_propval val = { + 0, + }; + + struct rx1618_chg *chip = + container_of(work, struct rx1618_chg, wireless_int_work.work); + + chip->wireless_psy = power_supply_get_by_name("wireless"); + if (!chip->wireless_psy) { + dev_err(chip->dev, "[rx1618] no wireless_psy,return\n"); + } + + mutex_lock(&chip->wireless_chg_int_lock); + dev_err(chip->dev, "[rx1618] [%s] enter \n", __func__); + + //read data + rx1618_read(chip, &privite_cmd, REG_RX_REV_CMD); + rx1618_read(chip, &data1, REG_RX_REV_DATA1); + rx1618_read(chip, &data2, REG_RX_REV_DATA2); + rx1618_read(chip, &data3, REG_RX_REV_DATA3); + rx1618_read(chip, &data4, REG_RX_REV_DATA4); + + dev_err(chip->dev, + "[rx1618] [%s] privite_cmd,data=0x%x,0x%x,0x%x,0x%x,0x%x\n", + __func__, privite_cmd, data1, data2, data3, data4); + + switch (privite_cmd) { + case 0x01: //Vrect10 + rx1618_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + msleep(10); + break; + case 0x02: //Duty L + rx1618_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + msleep(10); + break; + case 0x03: //Duty H + rx1618_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + msleep(10); + break; + case 0x04: //OVPH + rx1618_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + msleep(10); + break; + case 0x05: //OCPH + rx1618_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + msleep(10); + break; + case 0x06: //Plimit + rx1618_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + msleep(10); + break; + case 0x07: //FCM20 + rx1618_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + msleep(10); + break; + + case 0x08: //calibration + if (g_cali_done_flag == 0) { + rx1618_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + chip->epp = 1; + g_cali_done_flag = 1; + dev_err(chip->dev, "[rx1618] [%s] Calibration OK! \n", + __func__); + + for (i = 0; i <= 2; i++) { + uA = (EPP_MODE_CURRENT + N * 50000 * i); + rx1618_set_pmi_icl(chip, uA); + msleep(100); + } + } + break; + + case 0x09: //ID ok + if (g_id_done_flag == 0) { + rx1618_write(chip, AP_REV_DATA_OK, + REG_AP_RX_COMM); //receive ok + msleep(10); + + rx1618_write(chip, PRIVATE_ID_CMD, + REG_RX_SENT_CMD); //sent sar + rx1618_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); + g_id_done_flag = 1; + dev_err(chip->dev, "[rx1618] [%s] ID OK! \n", __func__); + } + break; + + case 0x0A: //SAR ok + if (g_sar_done_flag == 0) { + rx1618_write(chip, AP_REV_DATA_OK, + REG_AP_RX_COMM); //receive ok + msleep(10); + + rx1618_write(chip, PRIVATE_USB_TYPE_CMD, + REG_RX_SENT_CMD); //sent usb type + rx1618_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); + g_sar_done_flag = 1; + dev_err(chip->dev, "[rx1618] [%s] SAR OK! \n", + __func__); + chip->auth = 1; + } + break; + + case 0x12: //fast charge ok + if (g_fast_chg_flag == 0) { + rx1618_write(chip, AP_REV_DATA_OK, + REG_AP_RX_COMM); //receive ok + msleep(10); + + g_fast_chg_flag = 1; + dev_err(chip->dev, "[rx1618] [%s] Fast charge ok! \n", + __func__); + + rx1618_write(chip, 0x18, REG_RX_SENT_DATA1); + rx1618_write(chip, 0x4c, REG_RX_SENT_DATA2); + rx1618_write(chip, PRIVATE_TX_HW_ID_CMD, + REG_RX_SENT_CMD); //sent tx hw id req + rx1618_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); + dev_err(chip->dev, "[rx1618] [%s] sent tx hw id req\n", + __func__); + } + + break; + + case 0x0B: //USB type + if (g_usb_type_flag == 0) { + rx1618_write(chip, AP_REV_DATA_OK, + REG_AP_RX_COMM); //receive ok + msleep(10); + + rx1618_read(chip, &usb_type, 0x0021); + + rx1618_write(chip, PRIVATE_FAST_CHG_CMD, + REG_RX_SENT_CMD); //sent fast charge + rx1618_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); + g_usb_type_flag = 1; + dev_err(chip->dev, "[rx1618] [%s] usb_type=0x%x \n", + __func__, usb_type); + + switch (usb_type) { + case 0: //other charger + if ((g_id_done_flag == 0) && + (g_epp_or_bpp == BPP_MODE)) //bpp and no id + { + rx1618_set_pmi_icl(chip, + DC_OTHER_CURRENT); + dev_err(chip->dev, + "[rx1618] [%s] bpp and no id---800mA \n", + __func__); + } else //ID ok + { + rx1618_set_pmi_icl(chip, + DC_LOW_CURRENT); + dev_err(chip->dev, + "[rx1618] [%s] bpp and id ok---200mA \n", + __func__); + } + break; + + case 1: //SDP--1W + rx1618_set_pmi_icl(chip, DC_SDP_CURRENT); + dev_err(chip->dev, "[rx1618] [%s] SDP--1W \n", + __func__); + break; + + case 2: //CDP--1W + rx1618_set_pmi_icl(chip, DC_CDP_CURRENT); + dev_err(chip->dev, "[rx1618] [%s] CDP--1W \n", + __func__); + break; + + case 3: //DCP--1W + rx1618_set_pmi_icl(chip, DC_DCP_CURRENT); + dev_err(chip->dev, "[rx1618] [%s] DCP--1W \n", + __func__); + break; + + case 5: //QC2-other -- 7.5W + for (i = 0; i <= 8; i++) { + uA = (DC_LOW_CURRENT + N * 50000 * i); + rx1618_set_pmi_icl(chip, uA); + msleep(100); + } + dev_err(chip->dev, + "[rx1618] [%s] QC2 other--7.5W \n", + __func__); + break; + + case 6: //QC3-other -- 10W + for (i = 0; i <= 8; i++) { + uA = (DC_LOW_CURRENT + N * 50000 * i); + rx1618_set_pmi_icl(chip, uA); + msleep(100); + } + dev_err(chip->dev, + "[rx1618] [%s] QC3 other--10W \n", + __func__); + break; + + case 7: //PD-other -- 10W + for (i = 0; i <= 8; i++) { + uA = (DC_LOW_CURRENT + N * 50000 * i); + rx1618_set_pmi_icl(chip, uA); + msleep(100); + } + dev_err(chip->dev, + "[rx1618] [%s] PD other--7.5W \n", + __func__); + break; + + case 8: //fail charger + break; + + case 9: //QC3-27W(20W) + for (i = 0; i <= 11; i++) { + uA = (DC_QC3_CURRENT + N * 50000 * i); + rx1618_set_pmi_icl(chip, uA); + msleep(100); + } + if (chip->epp && chip->auth && + chip->wireless_psy) { + val.intval = 1; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, + &val); + } + dev_err(chip->dev, + "[rx1618] [%s] QC3-27W(20W) \n", + __func__); + break; + + case 10: //PD-27W(20W) + for (i = 0; i <= 11; i++) { + uA = (DC_QC3_CURRENT + N * 50000 * i); + rx1618_set_pmi_icl(chip, uA); + msleep(100); + } + if (chip->epp && chip->auth && + chip->wireless_psy) { + val.intval = 1; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, + &val); + } + dev_err(chip->dev, + "[rx1618] [%s] PD-27W(20W) \n", + __func__); + break; + + default: + dev_err(chip->dev, + "[rx1618] [%s] other Usb_type\n", + __func__); + break; + } + } + break; + + case 0x0C: //Light screen + if (g_light_screen_flag == 0) { + rx1618_write(chip, AP_REV_DATA_OK, + REG_AP_RX_COMM); //receive ok + msleep(10); + + rx1618_read(chip, &g_hw_id_h, REG_RX_REV_DATA1); + rx1618_read(chip, &g_hw_id_l, REG_RX_REV_DATA2); + rx1618_read(chip, &g_fw_id, REG_RX_REV_DATA3); + rx1618_read(chip, &g_epp_or_bpp, REG_RX_REV_DATA4); + + if (g_epp_or_bpp == EPP_MODE) //EPP + { + rx1618_set_pmi_icl(chip, EPP_MODE_CURRENT); + dev_err(chip->dev, + "[rx1618] [%s] EPP--600mA \n", + __func__); + } else //BPP mode + { + rx1618_set_pmi_icl(chip, DC_LOW_CURRENT); + dev_err(chip->dev, + "[rx1618] [%s] BPP--200mA \n", + __func__); + } + + g_light_screen_flag = 1; + + dev_err(chip->dev, + "[rx1618] [%s] Light screen,fw_id,hw_id_h,hw_id_l,g_epp_or_bpp=0x%x, 0x%x, 0x%x, 0x%x\n", + __func__, g_fw_id, g_hw_id_h, g_hw_id_l, + g_epp_or_bpp); + } + break; + + case 0x4C: //tx hw id + rx1618_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + msleep(10); + + rx1618_read(chip, &data1, REG_RX_REV_DATA1); + rx1618_read(chip, &data2, REG_RX_REV_DATA2); + rx1618_read(chip, &data3, REG_RX_REV_DATA3); + + dev_err(chip->dev, + "[rx1618] [%s] tx hw id,data1-3=0x%x, 0x%x, 0x%x, 0x%x\n", + __func__, data1, data2, data3, data4); + break; + + case 0x0D: //TX test request + rx1618_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + msleep(10); + + rx1618_read(chip, &header, REG_RX_REV_DATA1); + header_length = ((header & 0xf0) >> 4); + + dev_err(chip->dev, + "[rx1618] [%s] product Test mode, header=0x%x, header_length=0x%x\n", + __func__, header, header_length); + + switch (header_length) { + case 1: + rx1618_read(chip, &tx_cmd, REG_RX_REV_DATA2); + break; + + case 2: + rx1618_read(chip, &tx_cmd, REG_RX_REV_DATA2); + rx1618_read(chip, &data1, REG_RX_REV_DATA3); + break; + + case 3: + rx1618_read(chip, &tx_cmd, REG_RX_REV_DATA2); + rx1618_read(chip, &data1, REG_RX_REV_DATA3); + rx1618_read(chip, &data2, REG_RX_REV_DATA4); + break; + + case 4: + rx1618_read(chip, &tx_cmd, REG_RX_REV_DATA2); + rx1618_read(chip, &data1, REG_RX_REV_DATA3); + rx1618_read(chip, &data2, REG_RX_REV_DATA4); + rx1618_read(chip, &data3, REG_RX_REV_DATA5); + break; + + default: + break; + } + + dev_err(chip->dev, + "[rx1618] [%s] tx_cmd,data=0x%x, 0x%x, 0x%x, 0x%x\n", + __func__, tx_cmd, data1, data2, data3); + + if (tx_cmd == 0x12) //irect + { + rx1618_write(chip, 0x38, + REG_RX_SENT_DATA1); //sent header + rx1618_write(chip, 0x12, REG_RX_SENT_DATA2); //sent cmd + + irect = rx1618_get_rx_irect(chip); + data_h = (irect & 0xff00) >> 8; + rx1618_write(chip, data_h, 0x0003); + data_l = (irect & 0x00ff); + rx1618_write(chip, data_l, 0x0004); + dev_err(chip->dev, + "[rx1618] [%s] product test--0x12--irect=%d \n", + __func__, irect); + } else if (tx_cmd == 0x13) //vrect + { + rx1618_write(chip, 0x38, + REG_RX_SENT_DATA1); //sent header + rx1618_write(chip, 0x13, REG_RX_SENT_DATA2); //sent cmd + + vrect = rx1618_get_rx_vrect(chip); + data_h = (vrect & 0xff00) >> 8; + rx1618_write(chip, data_h, 0x0003); + data_l = (vrect & 0x00ff); + rx1618_write(chip, data_l, 0x0004); + dev_err(chip->dev, + "[rx1618] [%s] product test--0x13--vrect=%d \n", + __func__, vrect); + } else if (tx_cmd == 0x24) //fw id + { + rx1618_write(chip, 0x28, + REG_RX_SENT_DATA1); //sent header + rx1618_write(chip, 0x24, REG_RX_SENT_DATA2); //sent cmd + rx1618_write(chip, g_fw_id, 0x0003); + dev_err(chip->dev, + "[rx1618] [%s] product test--0x24--g_fw_id=0x%x \n", + __func__, g_fw_id); + } else if (tx_cmd == 0x25) //hw id + { + rx1618_write(chip, 0x38, + REG_RX_SENT_DATA1); //sent header + rx1618_write(chip, 0x25, REG_RX_SENT_DATA2); //sent cmd + rx1618_write(chip, g_hw_id_h, 0x0003); + rx1618_write(chip, g_hw_id_l, 0x0004); + dev_err(chip->dev, + "[rx1618] [%s] product test--0x25--g_hw_id=0x%x, 0x%x \n", + __func__, g_hw_id_h, g_hw_id_l); + } else { + dev_err(chip->dev, + "[rx1618] [%s] product test--other cmd \n", + __func__); + break; + } + + dev_err(chip->dev, + "[rx1618] [%s] header,tx_cmd,data=0x%x, 0x%x, 0x%x, 0x%x, 0x%x \n", + __func__, header, tx_cmd, data1, data2, data3); + + rx1618_write(chip, PRIVATE_PRODUCT_TEST_CMD, + REG_RX_SENT_CMD); //sent test cmd + rx1618_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); + break; + + default: + rx1618_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); //receive ok + msleep(10); + dev_err(chip->dev, "[rx1618] [%s] other private cmd \n", + __func__); + break; + } + + int_done_flag = false; + mutex_unlock(&chip->wireless_chg_int_lock); + + dev_err(chip->dev, "[rx1618] [%s] exit \n", __func__); + + return; +} + +static irqreturn_t rx1618_chg_stat_handler(int irq, void *dev_id) +{ + struct rx1618_chg *chip = dev_id; + u8 rev_cmd = 0; + + mutex_lock(&chip->irq_complete); + + if (!int_done_flag) { + rx1618_read(chip, &rev_cmd, REG_RX_REV_CMD); + if (rev_cmd == 0) { + mdelay(100); + int_done_flag = false; + //chip->online = 0; + g_light_screen_flag = 0; + g_cali_done_flag = 0; + g_id_done_flag = 0; + g_sar_done_flag = 0; + g_fast_chg_flag = 0; + g_usb_type_flag = 0; + g_epp_or_bpp = BPP_MODE; + chip->epp = 0; + chip->auth = 0; + cancel_delayed_work_sync(&chip->wireless_work); + cancel_delayed_work_sync(&chip->wireless_int_work); + dev_err(chip->dev, "[rx1618] [%s] Wireless Offline \n", + __func__); + } else { + int_done_flag = true; + //chip->online = 1; + + schedule_delayed_work(&chip->wireless_work, 0); + schedule_delayed_work(&chip->wireless_int_work, 0); + dev_err(chip->dev, "[rx1618] [%s] Wireless Online \n", + __func__); + } + } + + mutex_unlock(&chip->irq_complete); + + dev_err(chip->dev, "[rx1618] [%s] enter \n", __func__); + + return IRQ_HANDLED; +} + +static int rx1618_parse_dt(struct rx1618_chg *chip) +{ + int ret = 0; + + struct device_node *node = chip->dev->of_node; + if (!node) { + dev_err(chip->dev, "[rx1618] [%s] No DT data Failing Probe\n", + __func__); + return -EINVAL; + } + + //Get the Interrupt GPIO resource + chip->irq_gpio = of_get_named_gpio(node, "rx1618_irq_gpio", 0); + if (gpio_is_valid(chip->irq_gpio)) { + ret = gpio_request(chip->irq_gpio, "rx1618_irq_gpio"); + if (ret) { + dev_err(chip->dev, + "[rx1618] [%s] irq gpio request failed, ret = %d\n", + __func__, ret); + return -EPROBE_DEFER; + } + ret = gpio_direction_input(chip->irq_gpio); + if (ret) { + dev_err(chip->dev, + "[rx1618] [%s] set direction failed, ret = %d\n", + __func__, ret); + goto fail_irq_gpio; + } + + chip->client->irq = gpio_to_irq(chip->irq_gpio); + if (chip->client->irq) { + dev_err(chip->dev, + "[rx1618] [%s] gpio_to_irq Success! \n", + __func__); + } else { + dev_err(chip->dev, "[rx1618] [%s] gpio_to_irq Fail! \n", + __func__); + goto fail_irq_gpio; + } + } else { + goto fail_irq_gpio; + } + + return ret; + +fail_irq_gpio: + dev_err(chip->dev, "[rx1618] [%s] fail_irq_gpio \n", __func__); + if (gpio_is_valid(chip->irq_gpio)) + gpio_free(chip->irq_gpio); + + return ret; +} + +/*************FOD**************/ +//CMD : 0x8A +//DATA0 : Power Level, (2W, 4W, 8W, 6W, 10W… 20W) +//DATA1 : gain * 1024 hight 8bits +//DATA2 : gain * 1024 low 8bits +//DATA3: offset(mW) hight 8bits +//DATA4: offset(mW) low 8bits +/*************FOD**************/ +u8 g_power_level = 0; +u8 g_gain_h = 0; +u8 g_gain_l = 0; +u8 g_offset_h = 0; +u8 g_offset_l = 0; +void FODturring(void) +{ + rx1618_write(g_chip, g_power_level, REG_RX_SENT_DATA1); + rx1618_write(g_chip, g_gain_h, REG_RX_SENT_DATA2); + rx1618_write(g_chip, g_gain_l, REG_RX_SENT_DATA3); + rx1618_write(g_chip, g_offset_h, REG_RX_SENT_DATA4); + rx1618_write(g_chip, g_offset_l, REG_RX_SENT_DATA5); + + dev_err(g_chip->dev, + "[rx1618] [%s] FODturring:g_power_level,g_gain_h,g_gain_l,g_offset_h,g_offset_l %d,%d,%d,%d,%d\n", + __func__, g_power_level, g_gain_h, g_gain_l, g_offset_h, + g_offset_l); + + msleep(5); + + rx1618_write(g_chip, PRIVATE_FOD_TEST_CMD, REG_RX_SENT_CMD); + rx1618_write(g_chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); +} + +static ssize_t chip_fod_power_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int index; + index = (int)simple_strtoul(buf, NULL, 10); + + g_power_level = (index & 0xff); + dev_err(g_chip->dev, "[rx1618] [%s] g_power_level=0x%x \n", __func__, + g_power_level); + + return count; +} + +static ssize_t chip_fod_gain_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + u16 index; + index = (u16)simple_strtoul(buf, NULL, 10); + + g_gain_l = (index & 0x00ff); + g_gain_h = (index & 0xff00) >> 8; + + dev_err(g_chip->dev, "[rx1618] [%s] g_gain_l=0x%x, g_gain_h=0x%x \n", + __func__, g_gain_l, g_gain_h); + + return count; +} + +static ssize_t chip_fod_offset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + u16 index; + index = (u16)simple_strtoul(buf, NULL, 10); + + g_offset_l = (index & 0x00ff); + g_offset_h = (index & 0xff00) >> 8; + + dev_err(g_chip->dev, + "[rx1618] [%s] g_offset_l=0x%x, g_offset_h=0x%x \n", __func__, + g_offset_l, g_offset_h); + + FODturring(); + + return count; +} + +static ssize_t chip_ibuck_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned int ibuck = 0; + + ibuck = rx1618_get_rx_ibuck(g_chip); + + return sprintf(buf, "rx1618 Ibuck: %d mA\n", ibuck); +} + +static ssize_t chip_vrect_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned int vrect = 0; + + vrect = rx1618_get_rx_vrect(g_chip); + + return sprintf(buf, "rx1618 Vrect : %d mV\n", vrect); +} + +static ssize_t chip_irect_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned int irect = 0; + + irect = rx1618_get_rx_irect(g_chip); + + return sprintf(buf, "rx1618 Irect: %d mA\n", irect); +} + +static ssize_t chip_vbuck_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + int index; + + index = (int)simple_strtoul(buf, NULL, 10); + dev_err(g_chip->dev, "[rx1618] [%s] --Store output_voltage = %d\n", + __func__, index); + if ((index < 5166) || (index > 9609)) { + dev_err(g_chip->dev, + "[rx1618] [%s] Store Voltage %s is invalid\n", __func__, + buf); + rx1618_set_vbuck(g_chip, 0); + return count; + } + + rx1618_set_vbuck(g_chip, index); + + return count; +} + +static ssize_t chip_vbuck_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned int vbuck = 0; + + vbuck = rx1618_get_rx_vbuck(g_chip); + + return sprintf(buf, "rx1618 Vbuck : %d mV\n", vbuck); +} + +static ssize_t chip_ap_req_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + //int index; + //index = (int)simple_strtoul(buf, NULL, 10); + return count; +} + +static ssize_t chip_ap_req_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data = 0; + return sprintf(buf, "AP REQ DATA : 0x%x \n", data); +} + +static ssize_t chip_firmware_update_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + bool enable = strncmp(buf, "update", 6) ? false : true; + + dev_err(g_chip->dev, "[rx1618] [%s] Firmware Update enable = %d\n", + __func__, enable); + if (enable) { + int ret = rx1618_download_firmware(g_chip); + if (!ret) { + dev_err(g_chip->dev, + "[rx1618] [%s] Firmware Update failed! Please try again! \n", + __func__); + } + dev_err(g_chip->dev, + "[rx1618] [%s] Firmware Update Success!!! \n", + __func__); + } + + return count; +} + +static ssize_t chip_firmware_update_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + bool ret = rx1618_check_firmware(g_chip); + if (ret) { + return sprintf(buf, + "rx1618_download_firmware check Success!!!\n"); + } else { + return sprintf(buf, "rx1618_download_firmware check Fail!!!\n"); + } +} + +static ssize_t chip_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + //bool enable = strncmp(buf, "1", 1) ? false : true; + + //rx1618_chip_enable(g_chip, enable); + //dev_err(g_chip->dev, "[rx1618] [%s] chip enable:%d\n",__func__,enable); + + return count; +} + +static ssize_t chip_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "rx1618 chip enable status: %d \n", + g_chip->chip_enable); +} + +static ssize_t chip_fw_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "Firmware ID: 0x%x \t\n", g_fw_id); +} + +static ssize_t chip_hw_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "Hardware ID: 0x%x, 0x%x \t\n", g_hw_id_h, + g_hw_id_l); +} + +static ssize_t chip_vbuck_calibration_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int index = 0; + + index = (int)simple_strtoul(buf, NULL, 10); + + g_Delta = index; + dev_err(g_chip->dev, "[rx1618] [%s] g_Delta = %d \n", __func__, + g_Delta); + + return count; +} + +static DEVICE_ATTR(chip_fod_power, S_IWUSR, NULL, chip_fod_power_store); +static DEVICE_ATTR(chip_fod_gain, S_IWUSR, NULL, chip_fod_gain_store); +static DEVICE_ATTR(chip_fod_offset, S_IWUSR, NULL, chip_fod_offset_store); +static DEVICE_ATTR(chip_vrect, S_IRUGO, chip_vrect_show, NULL); +static DEVICE_ATTR(chip_irect, S_IRUGO, chip_irect_show, NULL); +static DEVICE_ATTR(chip_vbuck_calibration, S_IWUSR, NULL, + chip_vbuck_calibration_store); +static DEVICE_ATTR(chip_firmware_update, S_IWUSR | S_IRUGO, + chip_firmware_update_show, chip_firmware_update_store); +static DEVICE_ATTR(chip_fw_version, S_IRUGO, chip_fw_version_show, NULL); +static DEVICE_ATTR(chip_hw_version, S_IRUGO, chip_hw_version_show, NULL); +static DEVICE_ATTR(chip_enable, S_IWUSR | S_IRUGO, chip_enable_show, + chip_enable_store); +static DEVICE_ATTR(chip_vbuck, S_IWUSR | S_IRUGO, chip_vbuck_show, + chip_vbuck_store); +static DEVICE_ATTR(chip_ibuck, S_IRUGO, chip_ibuck_show, NULL); +static DEVICE_ATTR(chip_ap_req, S_IWUSR | S_IRUGO, chip_ap_req_show, + chip_ap_req_store); + +static struct attribute *rx1618_sysfs_attrs[] = { + &dev_attr_chip_vrect.attr, + &dev_attr_chip_irect.attr, + &dev_attr_chip_fw_version.attr, + &dev_attr_chip_hw_version.attr, + &dev_attr_chip_enable.attr, + &dev_attr_chip_vbuck.attr, + &dev_attr_chip_ibuck.attr, + &dev_attr_chip_ap_req.attr, + &dev_attr_chip_firmware_update.attr, + &dev_attr_chip_vbuck_calibration.attr, + &dev_attr_chip_fod_power.attr, + &dev_attr_chip_fod_gain.attr, + &dev_attr_chip_fod_offset.attr, + NULL, +}; + +static const struct attribute_group rx1618_sysfs_group_attrs = { + .attrs = rx1618_sysfs_attrs, +}; + +#if 1 +static enum power_supply_property rx1618_wireless_properties[] = { + /* + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_CHARGING_ENABLED, + POWER_SUPPLY_PROP_RX_CHIP_ID, //RX chip id + POWER_SUPPLY_PROP_RX_VRECT, //RX vrect + POWER_SUPPLY_PROP_RX_IOUT, //RX output current + POWER_SUPPLY_PROP_RX_VOUT, //RX output voltage + POWER_SUPPLY_PROP_RX_ILIMIT, //RX Main LDO output current limit + POWER_SUPPLY_PROP_VOUT_SET, //Vout voltage set + */ + POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, +}; + +static int rx1618_wireless_set_property(struct power_supply *psy, + enum power_supply_property prop, + const union power_supply_propval *val) +{ + int ret; + struct rx1618_chg *chip = power_supply_get_drvdata(psy); + int data; + + switch (prop) { + /* + case POWER_SUPPLY_PROP_PRESENT: + break; + case POWER_SUPPLY_PROP_CHARGING_ENABLED: + rx1618_chip_enable(chip, val->intval); + break; + case POWER_SUPPLY_PROP_VOUT_SET: + ret = rx1618_set_vbuck(chip, val->intval); + if(ret < 0) + return ret; + break; + */ + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + data = val->intval / 1000; + ret = rx1618_set_vbuck(chip, data); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int rx1618_wireless_get_property(struct power_supply *psy, + enum power_supply_property prop, + union power_supply_propval *val) +{ + struct rx1618_chg *chip = power_supply_get_drvdata(psy); + + switch (prop) { + /* + case POWER_SUPPLY_PROP_PRESENT: + val->intval = rx1618_is_rx_present(chip); + break; + case POWER_SUPPLY_PROP_ONLINE: + val->intval = chip->online; + break; + case POWER_SUPPLY_PROP_CHARGING_ENABLED: + val->intval = chip->chip_enable; + break; + case POWER_SUPPLY_PROP_RX_CHIP_ID: + val->intval = rx1618_get_rx_chip_id(chip); + break; + case POWER_SUPPLY_PROP_RX_VRECT: + val->intval = rx1618_get_rx_vrect(chip); + break; + case POWER_SUPPLY_PROP_RX_IOUT: + val->intval = rx1618_get_rx_ibuck(chip); + break; + case POWER_SUPPLY_PROP_RX_VOUT: + val->intval = rx1618_get_rx_vbuck(chip); + break; + case POWER_SUPPLY_PROP_VOUT_SET: + val->intval = 0; + break; + */ + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + val->intval = rx1618_get_rx_vbuck(chip); + break; + default: + return -EINVAL; + } + return 0; +} +#endif + +// first step: define regmap_config +static const struct regmap_config rx1618_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .max_register = 0xFFFF, +}; + +static int rx1618_prop_is_writeable(struct power_supply *psy, + enum power_supply_property psp) +{ + int rc; + + switch (psp) { + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + return 1; + default: + rc = 0; + break; + } + + return rc; +} + +static int rx1618_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0; + struct rx1618_chg *chip; + struct kobject *rx1618_kobj; + + struct power_supply_config wip_psy_cfg = {}; + int hw_id; + /* + struct power_supply *batt_psy; + + batt_psy = power_supply_get_by_name("battery"); + if (!batt_psy) { + dev_err(&client->dev, "Battery supply not found; defer probe\n"); + return -EPROBE_DEFER; + } + */ + + hw_id = get_hw_country_version(); + dev_info(&client->dev, "[rx1618] %s: hw_id is %d\n", __func__, hw_id); + if (hw_id) /*hw_id=1 is idt */ + return 0; + + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) { + dev_err(&client->dev, + "i2c allocated device info data failed!\n"); + return -ENOMEM; + } + + chip->regmap = regmap_init_i2c(client, &rx1618_regmap_config); + if (!chip->regmap) { + dev_err(&client->dev, "parent regmap is missing\n"); + return -EINVAL; + } + + chip->client = client; + chip->dev = &client->dev; + + //chip->batt_psy = batt_psy; + //chip->online = 0; + chip->chip_enable = false; + + device_init_wakeup(&client->dev, true); + i2c_set_clientdata(client, chip); + + rx1618_parse_dt(chip); + + mutex_init(&chip->irq_complete); + mutex_init(&chip->wireless_chg_lock); + mutex_init(&chip->wireless_chg_int_lock); + INIT_DELAYED_WORK(&chip->wireless_work, rx1618_wireless_work); + INIT_DELAYED_WORK(&chip->wireless_int_work, rx1618_wireless_int_work); + + chip->wip_psy_d.name = "rx1618"; + chip->wip_psy_d.type = POWER_SUPPLY_TYPE_WIRELESS; + chip->wip_psy_d.get_property = rx1618_wireless_get_property; + chip->wip_psy_d.set_property = rx1618_wireless_set_property; + chip->wip_psy_d.properties = rx1618_wireless_properties; + chip->wip_psy_d.num_properties = ARRAY_SIZE(rx1618_wireless_properties); + chip->wip_psy_d.property_is_writeable = rx1618_prop_is_writeable, + + wip_psy_cfg.drv_data = chip; + + chip->wip_psy = devm_power_supply_register(chip->dev, &chip->wip_psy_d, + &wip_psy_cfg); + if (IS_ERR(chip->wip_psy)) { + dev_err(chip->dev, "Couldn't register wip psy rc=%ld\n", + PTR_ERR(chip->wip_psy)); + return ret; + } + + if (chip->client->irq) { + ret = devm_request_threaded_irq( + &chip->client->dev, chip->client->irq, NULL, + rx1618_chg_stat_handler, + (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | + IRQF_ONESHOT), + "rx1618_chg_stat_irq", chip); + if (ret) { + dev_err(chip->dev, "Failed irq = %d ret = %d\n", + chip->client->irq, ret); + } + } + + enable_irq_wake(chip->client->irq); + + rx1618_kobj = kobject_create_and_add("rx1618", NULL); + if (!rx1618_kobj) { + dev_err(chip->dev, "sysfs_create_group fail"); + goto error_sysfs; + } + ret = sysfs_create_group(rx1618_kobj, &rx1618_sysfs_group_attrs); + if (ret < 0) { + dev_err(chip->dev, "sysfs_create_group fail %d\n", ret); + goto error_sysfs; + } + + g_chip = chip; + + determine_initial_status(chip); + rx1618_chip_init(chip); + + rx1618_dump_reg(); + + dev_err(chip->dev, "[rx1618] [%s] success! \n", __func__); + + return 0; + +error_sysfs: + sysfs_remove_group(rx1618_kobj, &rx1618_sysfs_group_attrs); + dev_err(chip->dev, "[rx1618] [%s] rx1618 probe error_sysfs! \n", + __func__); + + mutex_destroy(&chip->irq_complete); + mutex_destroy(&chip->wireless_chg_lock); + mutex_destroy(&chip->wireless_chg_int_lock); + if (chip->irq_gpio > 0) + gpio_free(chip->irq_gpio); + + return 0; +} + +static int rx1618_remove(struct i2c_client *client) +{ + struct rx1618_chg *chip = i2c_get_clientdata(client); + + mutex_destroy(&chip->irq_complete); + cancel_delayed_work_sync(&chip->wireless_work); + cancel_delayed_work_sync(&chip->wireless_int_work); + + return 0; +} + +static const struct i2c_device_id rx1618_id[] = { + { rx1618_DRIVER_NAME, 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, rx1618_id); + +static struct of_device_id rx1618_match_table[] = { + { + .compatible = "nuvolta,wl_charger_rx1618", + }, + {} +}; + +static struct i2c_driver rx1618_driver = { + .driver = { + .name = rx1618_DRIVER_NAME, + .of_match_table = rx1618_match_table, + }, + .probe = rx1618_probe, + .remove = rx1618_remove, + .id_table = rx1618_id, +}; + +static int __init rx1618_init(void) +{ + int ret; + + ret = i2c_add_driver(&rx1618_driver); + if (ret) + printk(KERN_ERR "rx1618 i2c driver init failed!\n"); + + return ret; +} + +static void __exit rx1618_exit(void) +{ + i2c_del_driver(&rx1618_driver); +} + +module_init(rx1618_init); +module_exit(rx1618_exit); + +MODULE_AUTHOR("colin"); +MODULE_DESCRIPTION("NUVOLTA Wireless Power Charger Monitor driver"); +MODULE_LICENSE("GPL/BSD"); diff --git a/drivers/power/supply/nuvolta/rx1618.h b/drivers/power/supply/nuvolta/rx1618.h new file mode 100644 index 000000000000..dd4debdd0994 --- /dev/null +++ b/drivers/power/supply/nuvolta/rx1618.h @@ -0,0 +1,1263 @@ +/** + * @file rx1618.h + * @author + * @date Tuesday, January 9th 2018 + * + * @brief + * + * + */ +#ifndef __RX1618_H__ +#define __RX1618_H__ + +#define rx1618_DRIVER_NAME "rx1618" +#define rx1618_I2C_ADDR 0x60 + +/* bits mask */ +#define BIT0 (1 << 0) +#define BIT1 (1 << 1) +#define BIT2 (1 << 2) +#define BIT3 (1 << 3) +#define BIT4 (1 << 4) +#define BIT5 (1 << 5) +#define BIT6 (1 << 6) +#define BIT7 (1 << 7) + +const u8 fw_data[] = { + 0x60, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, + 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, + 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, + 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, + 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, + 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, + 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, + 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, + 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, + 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, + 0xC8, 0x01, 0x00, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x84, 0x32, 0x00, 0x00, + 0x1C, 0x2D, 0x00, 0x00, 0x9C, 0x32, 0x00, 0x00, 0xA4, 0x32, 0x00, 0x00, + 0xAC, 0x32, 0x00, 0x00, 0xB4, 0x33, 0x00, 0x00, 0x1C, 0x2B, 0x00, 0x00, + 0x3C, 0x2D, 0x00, 0x00, 0xB4, 0x32, 0x00, 0x00, 0xBC, 0x32, 0x00, 0x00, + 0xD0, 0x32, 0x00, 0x00, 0x58, 0x33, 0x00, 0x00, 0x94, 0x33, 0x00, 0x00, + 0x9C, 0x33, 0x00, 0x00, 0xA4, 0x33, 0x00, 0x00, 0xAC, 0x33, 0x00, 0x00, + 0xB4, 0x33, 0x00, 0x00, 0xB4, 0x33, 0x00, 0x00, 0xB4, 0x33, 0x00, 0x00, + 0xB4, 0x33, 0x00, 0x00, 0xB4, 0x33, 0x00, 0x00, 0xB4, 0x33, 0x00, 0x00, + 0xB4, 0x33, 0x00, 0x00, 0xB4, 0x33, 0x00, 0x00, 0xB4, 0x33, 0x00, 0x00, + 0xB4, 0x33, 0x00, 0x00, 0xB4, 0x33, 0x00, 0x00, 0xB4, 0x33, 0x00, 0x00, + 0xB4, 0x33, 0x00, 0x00, 0xB4, 0x33, 0x00, 0x00, 0xB4, 0x33, 0x00, 0x00, + 0xB4, 0x33, 0x00, 0x00, 0x44, 0x74, 0x89, 0x74, 0x40, 0x3A, 0x0A, 0x0C, + 0xC3, 0x6C, 0x00, 0x20, 0x00, 0x2A, 0x89, 0x74, 0x08, 0x58, 0x20, 0xA3, + 0x00, 0x23, 0x0E, 0x64, 0xFD, 0x0B, 0x3C, 0x78, 0xC2, 0x14, 0x89, 0x74, + 0x40, 0x3A, 0x0C, 0x0C, 0xA3, 0x5A, 0x55, 0x75, 0x00, 0x25, 0x00, 0x33, + 0x4C, 0x58, 0x8C, 0x59, 0x80, 0x84, 0x80, 0xA2, 0x00, 0x23, 0x4E, 0x65, + 0xFA, 0x0B, 0x82, 0x14, 0x67, 0x10, 0x60, 0x83, 0x41, 0x3B, 0x03, 0x08, + 0x00, 0x30, 0x02, 0x04, 0x05, 0x10, 0x3C, 0x78, 0x04, 0x10, 0x3C, 0x78, + 0x00, 0x32, 0x62, 0x10, 0x40, 0xA3, 0x3C, 0x78, 0x14, 0x00, 0x00, 0x20, + 0x15, 0x00, 0x00, 0x20, 0x72, 0x10, 0x03, 0xC0, 0x20, 0x64, 0x52, 0x10, + 0x02, 0xC0, 0x21, 0x64, 0x31, 0x10, 0x87, 0x6F, 0xF1, 0x10, 0xD2, 0x10, + 0xB2, 0x10, 0x9C, 0x65, 0x07, 0x08, 0x80, 0x95, 0x80, 0xB7, 0x03, 0x25, + 0x03, 0x27, 0x9C, 0x65, 0xFB, 0x0F, 0x6F, 0x10, 0x4F, 0x10, 0x8E, 0x60, + 0x42, 0x4A, 0x40, 0x3A, 0x07, 0x0C, 0x00, 0x31, 0x20, 0xB3, 0x03, 0x23, + 0x00, 0x2A, 0x40, 0x3A, 0xFC, 0x0B, 0x00, 0xE0, 0x01, 0x13, 0x00, 0xE0, + 0xD3, 0x1A, 0x00, 0x04, 0x00, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0xF8, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x14, 0x00, 0x00, 0x20, + 0xC4, 0x39, 0x00, 0x00, 0x14, 0x00, 0x00, 0x20, 0x28, 0x01, 0x00, 0x20, + 0x00, 0xE0, 0x16, 0x18, 0x00, 0xC0, 0x20, 0x40, 0x3C, 0x78, 0x00, 0x00, + 0x3C, 0x78, 0x00, 0x00, 0x03, 0x32, 0x62, 0x10, 0x40, 0xA3, 0x3C, 0x78, + 0x2B, 0x00, 0x00, 0x20, 0xD1, 0x14, 0x01, 0x75, 0x00, 0xE0, 0x56, 0x0F, + 0x40, 0x38, 0x04, 0x0C, 0x00, 0x32, 0x6A, 0x11, 0x40, 0xA3, 0x40, 0x33, + 0xD2, 0x64, 0x24, 0x0C, 0x0C, 0x65, 0x06, 0x0C, 0x41, 0x3C, 0x16, 0x0C, + 0x44, 0x3C, 0x2E, 0x08, 0x1D, 0x04, 0x80, 0x33, 0x61, 0x43, 0xD2, 0x64, + 0x19, 0x0C, 0x80, 0x33, 0x62, 0x43, 0xD2, 0x64, 0x15, 0x0C, 0x80, 0x33, + 0xD2, 0x64, 0x22, 0x08, 0x03, 0x32, 0x7E, 0x10, 0x40, 0xA3, 0x03, 0x30, + 0x00, 0xE0, 0x28, 0x0F, 0x1B, 0x04, 0x7B, 0x10, 0x60, 0x83, 0x42, 0x3B, + 0x17, 0x08, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0xE0, 0x6E, 0x17, + 0x11, 0x04, 0x76, 0x10, 0x60, 0x83, 0x42, 0x3B, 0x0D, 0x08, 0x03, 0x32, + 0x73, 0x10, 0x40, 0xA3, 0x0C, 0x30, 0x00, 0xE0, 0xAD, 0x0A, 0x06, 0x30, + 0x00, 0xE0, 0x10, 0x0F, 0x00, 0x30, 0x00, 0xE0, 0x73, 0x03, 0x6E, 0x10, + 0x60, 0x83, 0x40, 0x3B, 0x04, 0x0C, 0x41, 0x3B, 0x15, 0x08, 0x0D, 0x04, + 0x00, 0xE0, 0x3A, 0x10, 0x40, 0x38, 0x10, 0x0C, 0x69, 0x10, 0x41, 0x93, + 0x86, 0x3A, 0x41, 0xB3, 0x01, 0x32, 0x66, 0x10, 0x40, 0xA3, 0x08, 0x04, + 0x00, 0xE0, 0x42, 0x10, 0x40, 0x38, 0x04, 0x0C, 0x02, 0x32, 0x62, 0x10, + 0x40, 0xA3, 0x91, 0x14, 0x2B, 0x00, 0x00, 0x20, 0x00, 0xA0, 0x00, 0x40, + 0x46, 0x10, 0x00, 0x33, 0x60, 0xA2, 0x61, 0xA2, 0x62, 0xA2, 0x63, 0xA2, + 0x03, 0x22, 0x60, 0xA2, 0x61, 0xA2, 0x00, 0x33, 0x61, 0xAA, 0x3C, 0x78, + 0x2C, 0x00, 0x00, 0x20, 0xD1, 0x14, 0x01, 0x75, 0x00, 0xE0, 0xEA, 0x0E, + 0x40, 0x38, 0x0B, 0x0C, 0x7E, 0x12, 0x00, 0x32, 0x41, 0xA3, 0x0A, 0x32, + 0x40, 0xA3, 0x02, 0x30, 0x00, 0x31, 0x04, 0x32, 0x00, 0xE0, 0x3A, 0x0F, + 0x40, 0x33, 0xD2, 0x64, 0x16, 0x0C, 0x0C, 0x65, 0x08, 0x0C, 0x42, 0x3C, + 0x44, 0x0C, 0x44, 0x3C, 0x10, 0x0C, 0x41, 0x3C, 0x9E, 0x08, 0x23, 0x04, + 0x80, 0x33, 0x61, 0x43, 0xD2, 0x64, 0x84, 0x0C, 0x80, 0x33, 0x62, 0x43, + 0xD2, 0x64, 0x80, 0x0C, 0x80, 0x33, 0xD2, 0x64, 0x92, 0x08, 0x51, 0x04, + 0xFF, 0xE3, 0x22, 0xFF, 0x6C, 0x12, 0x63, 0x83, 0x02, 0x3B, 0x0A, 0x08, + 0x00, 0x23, 0x4A, 0x12, 0x63, 0xA2, 0x02, 0x30, 0x00, 0x31, 0x04, 0x32, + 0x00, 0xE0, 0x14, 0x0F, 0x82, 0x04, 0x08, 0x30, 0x00, 0xE0, 0xD6, 0x0E, + 0x0A, 0x32, 0x64, 0x12, 0x41, 0xA3, 0x7B, 0x04, 0x62, 0x12, 0x61, 0x83, + 0x43, 0x3B, 0x09, 0x08, 0xFF, 0xE3, 0xFE, 0xFE, 0x83, 0x6C, 0x01, 0x30, + 0x05, 0x31, 0x00, 0xE0, 0xE7, 0x16, 0x6F, 0x04, 0x44, 0x3B, 0x09, 0x08, + 0xFF, 0xE3, 0xF4, 0xFE, 0x83, 0x6C, 0x01, 0x30, 0x05, 0x31, 0x00, 0xE0, + 0xDD, 0x16, 0x65, 0x04, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0xE0, + 0xD7, 0x16, 0x5F, 0x04, 0x74, 0x11, 0x61, 0x83, 0x43, 0x3B, 0x0C, 0x08, + 0xFF, 0xE3, 0xEA, 0xFE, 0x42, 0x80, 0x48, 0x42, 0x63, 0x80, 0x8C, 0x6C, + 0x70, 0x11, 0x41, 0xAB, 0xFF, 0xE3, 0xE4, 0xFE, 0x10, 0x04, 0x44, 0x3B, + 0x0E, 0x08, 0xFF, 0xE3, 0xDD, 0xFE, 0x6C, 0x11, 0x41, 0x80, 0x5A, 0x42, + 0x5A, 0x4A, 0x40, 0xA3, 0x42, 0x80, 0x5A, 0x42, 0x5A, 0x4A, 0x41, 0xA3, + 0xFF, 0xE3, 0xD4, 0xFE, 0x65, 0x11, 0x00, 0x32, 0x43, 0xA3, 0x61, 0x83, + 0x40, 0x3B, 0x06, 0x08, 0x00, 0xE0, 0x32, 0x0A, 0x0C, 0x30, 0x00, 0xE0, + 0xF7, 0x09, 0x60, 0x11, 0x61, 0x83, 0x06, 0x3B, 0x16, 0x08, 0x00, 0x23, + 0xCC, 0x74, 0x5D, 0x10, 0x61, 0xA2, 0x42, 0x3B, 0x04, 0x08, 0x03, 0x32, + 0x7A, 0x10, 0x41, 0xA3, 0x42, 0x3C, 0x05, 0x08, 0x01, 0x32, 0x78, 0x10, + 0x42, 0xA3, 0x23, 0x04, 0x02, 0x30, 0x00, 0x31, 0x04, 0x32, 0x00, 0xE0, + 0xAF, 0x0E, 0x1D, 0x04, 0x05, 0x30, 0x00, 0xE0, 0x41, 0x0E, 0x0A, 0x32, + 0x71, 0x10, 0x41, 0xA3, 0x16, 0x04, 0x70, 0x10, 0x00, 0x32, 0x43, 0xA3, + 0x61, 0x83, 0x01, 0x32, 0xC8, 0x64, 0x03, 0x08, 0x47, 0x3B, 0x05, 0x08, + 0x08, 0x30, 0x00, 0xE0, 0x61, 0x0E, 0x09, 0x04, 0x00, 0x23, 0x49, 0x10, + 0x61, 0xA2, 0x02, 0x30, 0x00, 0x31, 0x04, 0x32, 0x00, 0xE0, 0x92, 0x0E, + 0x00, 0xE0, 0x40, 0x0F, 0x40, 0x38, 0x42, 0x0C, 0x63, 0x10, 0x62, 0x83, + 0x41, 0x3B, 0x3E, 0x08, 0x06, 0x04, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, + 0x30, 0x00, 0x00, 0x20, 0x66, 0x11, 0x00, 0x32, 0x42, 0xA3, 0x41, 0x83, + 0x07, 0x3A, 0x32, 0x08, 0x64, 0x11, 0x43, 0xC4, 0x43, 0x08, 0x60, 0x93, + 0x0C, 0x78, 0x23, 0x30, 0x00, 0xE0, 0xF6, 0x0F, 0x29, 0x04, 0x31, 0x30, + 0x00, 0xE0, 0x00, 0x10, 0x25, 0x04, 0x00, 0xE0, 0x0B, 0x10, 0x22, 0x04, + 0x00, 0xE0, 0x14, 0x10, 0x1F, 0x04, 0x7C, 0x10, 0x00, 0x83, 0x80, 0x74, + 0x14, 0x33, 0x8C, 0x64, 0x02, 0x08, 0x14, 0x30, 0x00, 0x74, 0x00, 0xE0, + 0x15, 0x10, 0x14, 0x04, 0x76, 0x10, 0x01, 0x83, 0x80, 0x74, 0x14, 0x33, + 0x8C, 0x64, 0x02, 0x08, 0x14, 0x30, 0x00, 0x74, 0x00, 0xE0, 0x1A, 0x10, + 0x09, 0x04, 0x71, 0x10, 0x60, 0x83, 0x0A, 0x3B, 0x00, 0xC4, 0x00, 0x05, + 0x01, 0x20, 0x00, 0xE0, 0x21, 0x10, 0x91, 0x14, 0x6C, 0x10, 0x01, 0x83, + 0x3C, 0x78, 0x00, 0x00, 0x6A, 0x10, 0x61, 0x8B, 0x40, 0x3B, 0x03, 0x64, + 0x3C, 0x78, 0x00, 0x00, 0x67, 0x10, 0x61, 0x8B, 0x40, 0x3B, 0x03, 0x64, + 0x3C, 0x78, 0x00, 0x00, 0x01, 0x32, 0x62, 0x10, 0x42, 0xA3, 0x3C, 0x78, + 0x2C, 0x00, 0x00, 0x20, 0xB0, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, + 0x00, 0x32, 0x62, 0x10, 0x40, 0xA3, 0x3C, 0x78, 0x34, 0x00, 0x00, 0x20, + 0xD2, 0x14, 0x01, 0x75, 0x00, 0xE0, 0xCC, 0x0D, 0x40, 0x38, 0x10, 0x0C, + 0x00, 0x30, 0x00, 0xE0, 0xF3, 0x0B, 0xAA, 0x10, 0x03, 0x48, 0x00, 0xA5, + 0x00, 0xE0, 0xC2, 0x0E, 0x68, 0x10, 0x41, 0x93, 0xA6, 0x3A, 0x41, 0xB3, + 0x00, 0x85, 0x00, 0xE0, 0xCD, 0x0E, 0x41, 0x3C, 0x04, 0x08, 0x02, 0x30, + 0x00, 0xE0, 0xA8, 0x0D, 0x92, 0x14, 0x00, 0x00, 0x34, 0x00, 0x00, 0x20, + 0x00, 0xA0, 0x00, 0x40, 0xC1, 0x14, 0x73, 0x10, 0x40, 0x93, 0x33, 0x10, + 0x84, 0x68, 0x40, 0xB3, 0x06, 0x31, 0x24, 0xA3, 0x03, 0x31, 0x25, 0xA3, + 0x30, 0x4A, 0x21, 0xE4, 0xFC, 0x20, 0x8F, 0x10, 0x82, 0xC4, 0x20, 0x20, + 0x00, 0xE4, 0x07, 0x30, 0x48, 0x4A, 0x42, 0xE4, 0x3C, 0x30, 0x41, 0xA3, + 0x00, 0xE4, 0x38, 0x30, 0x00, 0xA3, 0x40, 0x8B, 0x42, 0xE4, 0x80, 0x33, + 0x40, 0xAB, 0x21, 0xE4, 0x3C, 0x30, 0x22, 0xA3, 0x41, 0x8B, 0x42, 0xE4, + 0x3F, 0x20, 0x41, 0xAB, 0x81, 0x14, 0x00, 0x00, 0x38, 0x00, 0x00, 0x20, + 0xFF, 0x3F, 0xFE, 0xFF, 0xBF, 0x3F, 0xFE, 0xFF, 0xD2, 0x14, 0x01, 0x75, + 0x00, 0xE0, 0x80, 0x0D, 0x40, 0x38, 0x23, 0x0C, 0x62, 0x13, 0x03, 0x32, + 0x45, 0xA3, 0x42, 0x83, 0x81, 0x3A, 0x42, 0xA3, 0x41, 0x83, 0x42, 0xE4, + 0x3C, 0x30, 0x41, 0xA3, 0x40, 0x93, 0x1E, 0x12, 0x80, 0x68, 0xAE, 0x3A, + 0x40, 0xB3, 0x3D, 0x12, 0x84, 0x68, 0x42, 0xE4, 0x07, 0x30, 0x42, 0xEC, + 0x06, 0x00, 0x40, 0xA3, 0x60, 0x93, 0x63, 0x4B, 0x63, 0xE4, 0x07, 0x20, + 0x20, 0x3B, 0x04, 0x08, 0x06, 0x32, 0x74, 0x12, 0x45, 0xA3, 0x08, 0x30, + 0x00, 0xE0, 0x64, 0x0D, 0x50, 0x3C, 0x21, 0x0C, 0x10, 0x3C, 0x0D, 0x08, + 0x42, 0x3C, 0xDE, 0x0C, 0x02, 0x3C, 0x04, 0x08, 0x41, 0x3C, 0x5D, 0x09, + 0x82, 0x04, 0x44, 0x3C, 0x37, 0x0C, 0x48, 0x3C, 0x58, 0x09, 0x13, 0x04, + 0x80, 0x33, 0xD2, 0x64, 0xC1, 0x0C, 0x0C, 0x65, 0x05, 0x0C, 0x40, 0x33, + 0xD2, 0x64, 0x4F, 0x09, 0x2B, 0x04, 0x80, 0x33, 0x61, 0x43, 0xD2, 0x64, + 0x27, 0x0C, 0x80, 0x33, 0x62, 0x43, 0xD2, 0x64, 0x46, 0x09, 0x22, 0x04, + 0x00, 0x30, 0x00, 0xE0, 0x87, 0x0E, 0x41, 0x38, 0x40, 0x09, 0x5E, 0x11, + 0x20, 0x92, 0x6E, 0x49, 0x06, 0x23, 0x63, 0xE4, 0x07, 0x20, 0x6E, 0x43, + 0x1B, 0x11, 0x40, 0x68, 0xC4, 0x6C, 0x60, 0xB2, 0xE0, 0x31, 0x29, 0x41, + 0xC4, 0x68, 0x40, 0x3B, 0x07, 0x0C, 0x07, 0x30, 0x00, 0x31, 0x64, 0x32, + 0x00, 0xE0, 0x7C, 0x0D, 0x2A, 0x05, 0x02, 0x30, 0x00, 0x31, 0x64, 0x32, + 0x00, 0xE0, 0x76, 0x0D, 0x24, 0x05, 0x70, 0x11, 0x40, 0x93, 0x4A, 0x4A, + 0x00, 0x22, 0x42, 0xE4, 0x0F, 0x20, 0x02, 0x42, 0x21, 0x83, 0x21, 0xE4, + 0x3C, 0x30, 0x40, 0x6C, 0x21, 0xA3, 0x20, 0x3A, 0x34, 0x08, 0x8F, 0x6C, + 0x65, 0x83, 0x00, 0x2B, 0xCC, 0x74, 0x65, 0xA2, 0x40, 0x3B, 0x1F, 0x0C, + 0xCB, 0x6C, 0x41, 0x82, 0x42, 0xE4, 0x3C, 0x30, 0x41, 0xA3, 0x40, 0x83, + 0x86, 0x3A, 0x4B, 0x6C, 0x40, 0xA3, 0x40, 0x93, 0x42, 0xE4, 0x07, 0x20, + 0x43, 0x42, 0x21, 0xE4, 0x38, 0x30, 0x84, 0x6C, 0x42, 0xE4, 0x07, 0x30, + 0x42, 0xEC, 0x06, 0x00, 0x40, 0xA3, 0x40, 0x93, 0x1B, 0x10, 0x80, 0x68, + 0xAE, 0x3A, 0x40, 0xB3, 0x08, 0x30, 0x00, 0xE0, 0xEF, 0x0C, 0x14, 0x04, + 0x76, 0x10, 0x42, 0x83, 0xA1, 0x3A, 0x42, 0xA3, 0x06, 0x30, 0x00, 0xE0, + 0xFF, 0x09, 0x11, 0x30, 0x00, 0xE0, 0x68, 0x08, 0x05, 0x30, 0x00, 0xE0, + 0xCB, 0x0C, 0x06, 0x04, 0x02, 0x30, 0x00, 0x31, 0x64, 0x32, 0x00, 0xE0, + 0x2F, 0x0D, 0xFF, 0xE3, 0x2F, 0xFD, 0xDB, 0x04, 0x6B, 0x10, 0x60, 0x93, + 0x63, 0xE4, 0x07, 0x20, 0x06, 0x3B, 0xD5, 0x08, 0x4B, 0x10, 0x62, 0xC4, + 0x42, 0x08, 0x40, 0x92, 0x08, 0x78, 0x4A, 0x10, 0x6C, 0x5A, 0x80, 0x83, + 0xFF, 0xE3, 0x14, 0xFD, 0x83, 0x6C, 0x01, 0x30, 0x53, 0x6C, 0x00, 0xE0, + 0xFD, 0x14, 0xC5, 0x04, 0x38, 0x00, 0x00, 0x20, 0xFF, 0x3F, 0xFE, 0xFF, + 0xBF, 0x7F, 0xFE, 0xFF, 0xD0, 0x38, 0x00, 0x00, 0x04, 0x39, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0xE0, 0xED, 0x14, 0xB5, 0x04, + 0x04, 0x30, 0x00, 0xE0, 0xC7, 0x09, 0x05, 0x30, 0x00, 0xE0, 0x96, 0x0C, + 0xAE, 0x04, 0xFF, 0xE3, 0xF5, 0xFC, 0x83, 0x6C, 0x01, 0x30, 0x07, 0x31, + 0x00, 0xE0, 0xDE, 0x14, 0xA6, 0x04, 0x69, 0x13, 0x60, 0x93, 0xE0, 0x31, + 0x29, 0x41, 0xC4, 0x68, 0x40, 0x3B, 0x9F, 0x08, 0x65, 0x13, 0x20, 0x93, + 0x23, 0x49, 0x21, 0xE4, 0x07, 0x20, 0x40, 0x83, 0x42, 0xE4, 0x07, 0x30, + 0x84, 0x6C, 0x40, 0xA3, 0x94, 0x04, 0x12, 0x30, 0x00, 0xE0, 0x12, 0x08, + 0x03, 0x30, 0x00, 0xE0, 0xA3, 0x09, 0x05, 0x30, 0x00, 0xE0, 0x72, 0x0C, + 0x7B, 0x12, 0x04, 0x83, 0x05, 0x38, 0x87, 0x08, 0x00, 0xE0, 0x6C, 0x07, + 0x84, 0x04, 0x78, 0x12, 0x41, 0x83, 0x42, 0xE4, 0x3C, 0x30, 0x41, 0xA3, + 0x60, 0x83, 0x63, 0xE4, 0x07, 0x20, 0x40, 0x3B, 0x13, 0x08, 0xFF, 0xE3, + 0xC9, 0xFC, 0x03, 0x6D, 0x09, 0x30, 0x00, 0xE0, 0xF5, 0x07, 0x70, 0x12, + 0x22, 0x84, 0x26, 0x41, 0x41, 0x8B, 0x42, 0xE4, 0x3F, 0x20, 0x84, 0x6C, + 0x41, 0xAB, 0x00, 0x30, 0x00, 0xE0, 0x7E, 0x09, 0x63, 0x04, 0x41, 0x3B, + 0x0A, 0x08, 0xFF, 0xE3, 0xB5, 0xFC, 0x0A, 0x30, 0x00, 0xE0, 0xE2, 0x07, + 0x01, 0x30, 0x00, 0xE0, 0x73, 0x09, 0x58, 0x04, 0x42, 0x3B, 0x4E, 0x08, + 0xFF, 0xE3, 0xAA, 0xFC, 0x03, 0x6D, 0x62, 0x80, 0x42, 0x12, 0x6C, 0x5A, + 0xA0, 0x83, 0x00, 0xE0, 0x81, 0x04, 0x41, 0x38, 0x19, 0x08, 0x28, 0x33, + 0xD6, 0x64, 0x0B, 0x08, 0x7C, 0x11, 0x05, 0x32, 0x44, 0xA3, 0x40, 0x8B, + 0x42, 0xE4, 0x80, 0x33, 0x42, 0xEC, 0x80, 0x02, 0x40, 0xAB, 0x25, 0x04, + 0x54, 0x3D, 0x23, 0x08, 0x76, 0x11, 0x04, 0x32, 0x44, 0xA3, 0x40, 0x8B, + 0x42, 0xE4, 0x80, 0x33, 0xA9, 0x3A, 0x40, 0xAB, 0x1A, 0x04, 0x4F, 0x3D, + 0x0A, 0x08, 0x71, 0x11, 0x01, 0x32, 0x44, 0xA3, 0x40, 0x8B, 0x42, 0xE4, + 0x80, 0x33, 0xA8, 0x3A, 0x40, 0xAB, 0x0F, 0x04, 0x54, 0x3D, 0x04, 0x0C, + 0x28, 0x33, 0xD6, 0x64, 0x0A, 0x08, 0x6A, 0x11, 0x02, 0x32, 0x44, 0xA3, + 0x40, 0x8B, 0x42, 0xE4, 0x80, 0x33, 0x42, 0xEC, 0x80, 0x01, 0x40, 0xAB, + 0x65, 0x11, 0x22, 0x84, 0x21, 0xE4, 0x0F, 0x20, 0x22, 0x41, 0x42, 0x83, + 0x42, 0xE4, 0x3C, 0x30, 0x84, 0x6C, 0x42, 0xA3, 0x0B, 0x30, 0x00, 0xE0, + 0x93, 0x07, 0x02, 0x30, 0x00, 0xE0, 0x24, 0x09, 0x09, 0x04, 0x45, 0x3B, + 0x07, 0x08, 0x4C, 0x30, 0x00, 0xE0, 0x8A, 0x07, 0x05, 0x30, 0x00, 0xE0, + 0x1B, 0x09, 0x05, 0x30, 0x00, 0xE0, 0xEA, 0x0B, 0xFF, 0xE3, 0x54, 0xFC, + 0x76, 0x10, 0x60, 0x83, 0x63, 0xE4, 0x40, 0x20, 0xCC, 0x74, 0x40, 0x3B, + 0x40, 0x0C, 0x73, 0x10, 0x60, 0x93, 0x63, 0xE4, 0x07, 0x20, 0x05, 0x3B, + 0x3A, 0x08, 0x52, 0x10, 0x62, 0xC4, 0x43, 0x08, 0x60, 0x93, 0x0C, 0x78, + 0x00, 0xE0, 0x20, 0x0E, 0x41, 0x38, 0x31, 0x08, 0x6B, 0x10, 0x40, 0x83, + 0x86, 0x3A, 0x40, 0xA3, 0x2C, 0x04, 0x00, 0xE0, 0x29, 0x0E, 0x41, 0x38, + 0x28, 0x08, 0x67, 0x10, 0x40, 0x83, 0x86, 0x3A, 0x40, 0xA3, 0x23, 0x04, + 0x00, 0xE0, 0x32, 0x0E, 0x41, 0x38, 0x1F, 0x08, 0x62, 0x10, 0x40, 0x83, + 0x08, 0x04, 0x00, 0x00, 0x38, 0x00, 0x00, 0x20, 0x08, 0x39, 0x00, 0x00, + 0xEC, 0x38, 0x00, 0x00, 0x86, 0x3A, 0x40, 0xA3, 0x12, 0x04, 0x00, 0xE0, + 0x33, 0x0E, 0x41, 0x38, 0x0E, 0x08, 0x76, 0x10, 0x40, 0x83, 0x86, 0x3A, + 0x40, 0xA3, 0x09, 0x04, 0x00, 0xE0, 0x3C, 0x0E, 0x41, 0x38, 0x05, 0x08, + 0x71, 0x10, 0x40, 0x83, 0x86, 0x3A, 0x40, 0xA3, 0x92, 0x14, 0x00, 0x00, + 0x6E, 0x10, 0x00, 0x93, 0x3C, 0x78, 0x00, 0x00, 0x6C, 0x10, 0x00, 0xE4, + 0x07, 0x20, 0x03, 0x40, 0x40, 0x83, 0x42, 0xE4, 0x38, 0x30, 0x80, 0x6C, + 0x40, 0xA3, 0x3C, 0x78, 0x67, 0x10, 0x62, 0x83, 0x63, 0xE4, 0x02, 0x20, + 0xCC, 0x74, 0x40, 0x3B, 0x03, 0x64, 0x3C, 0x78, 0x63, 0x10, 0x40, 0x83, + 0xA6, 0x3A, 0x40, 0xA3, 0x3C, 0x78, 0x00, 0x00, 0x38, 0x00, 0x00, 0x20, + 0x00, 0x32, 0x62, 0x10, 0x40, 0xA3, 0x3C, 0x78, 0x3E, 0x00, 0x00, 0x20, + 0xD0, 0x14, 0x00, 0x30, 0x00, 0xE0, 0xB2, 0x09, 0xBB, 0x33, 0x0C, 0x64, + 0x0D, 0x08, 0x6A, 0x10, 0x60, 0x83, 0x40, 0x3B, 0x09, 0x08, 0x01, 0x32, + 0x67, 0x10, 0x40, 0xA3, 0x02, 0x30, 0x00, 0x31, 0x08, 0x32, 0x00, 0xE0, + 0xD3, 0x0B, 0x90, 0x14, 0xD0, 0x14, 0x01, 0x30, 0x00, 0xE0, 0x64, 0x0B, + 0x90, 0x14, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x20, 0xD0, 0x14, 0x00, 0x74, + 0x05, 0x38, 0x59, 0x08, 0x6D, 0x11, 0x03, 0xC4, 0x40, 0x08, 0x60, 0x90, + 0x0C, 0x78, 0x6C, 0x11, 0x41, 0x8B, 0x42, 0xE4, 0x3F, 0x20, 0x42, 0xEC, + 0x00, 0x39, 0x41, 0xAB, 0xBC, 0x30, 0x00, 0xE0, 0x23, 0x07, 0x49, 0x04, + 0x66, 0x11, 0x41, 0x8B, 0x42, 0xE4, 0x3F, 0x20, 0x42, 0xEC, 0xC0, 0x4F, + 0x41, 0xAB, 0xBC, 0x30, 0x00, 0xE0, 0x18, 0x07, 0x3E, 0x04, 0x61, 0x11, + 0x41, 0x8B, 0x42, 0xE4, 0x3F, 0x20, 0x42, 0xEC, 0x80, 0x66, 0x41, 0xAB, + 0x79, 0x30, 0x00, 0xE0, 0x0D, 0x07, 0x33, 0x04, 0x7B, 0x10, 0x41, 0x8B, + 0x42, 0xE4, 0x3F, 0x20, 0x3A, 0x10, 0x84, 0x6C, 0x41, 0xAB, 0x19, 0x30, + 0x00, 0xE0, 0x02, 0x07, 0x28, 0x04, 0xFF, 0xE3, 0x49, 0xFD, 0x50, 0x38, + 0x0F, 0x08, 0x03, 0x30, 0x00, 0xE0, 0x24, 0x06, 0x72, 0x10, 0x41, 0x8B, + 0x42, 0xE4, 0x3F, 0x20, 0x42, 0xEC, 0x80, 0x66, 0x41, 0xAB, 0x79, 0x30, + 0x00, 0xE0, 0xF0, 0x06, 0x16, 0x04, 0x04, 0x30, 0x00, 0xE0, 0x16, 0x06, + 0x6B, 0x10, 0x41, 0x8B, 0x42, 0xE4, 0x3F, 0x20, 0x2A, 0x10, 0x84, 0x6C, + 0x41, 0xAB, 0x19, 0x30, 0x00, 0xE0, 0xE2, 0x06, 0x08, 0x04, 0x66, 0x10, + 0x41, 0x8B, 0x42, 0xE4, 0x3F, 0x20, 0x26, 0x10, 0x84, 0x6C, 0x41, 0xAB, + 0x90, 0x14, 0x00, 0x00, 0x14, 0x39, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, + 0x80, 0x88, 0xFF, 0xFF, 0xC0, 0xBB, 0xFF, 0xFF, 0xD0, 0x14, 0x00, 0x74, + 0x69, 0x13, 0x64, 0x83, 0x40, 0x3B, 0x2B, 0x08, 0x01, 0x32, 0x67, 0x13, + 0x44, 0xA3, 0x40, 0x38, 0x14, 0x08, 0x00, 0xE0, 0xED, 0x05, 0x64, 0x13, + 0x42, 0x83, 0x80, 0x3A, 0x81, 0x3A, 0x42, 0xA3, 0x41, 0x83, 0x20, 0x83, + 0x21, 0xE4, 0x0F, 0x20, 0x00, 0x30, 0x5F, 0x28, 0x40, 0x6C, 0x20, 0xA3, + 0x42, 0xE4, 0x1F, 0x20, 0x41, 0xA3, 0x13, 0x04, 0x41, 0x38, 0x11, 0x08, + 0x7A, 0x12, 0x41, 0x83, 0x22, 0x83, 0x80, 0x39, 0x81, 0x39, 0xA0, 0x39, + 0x22, 0xA3, 0x42, 0xE4, 0x07, 0x20, 0x41, 0xA3, 0x40, 0x83, 0x42, 0xE4, + 0x0F, 0x20, 0x42, 0xEC, 0x30, 0x00, 0x40, 0xA3, 0x90, 0x14, 0x00, 0x00, + 0xD0, 0x14, 0x00, 0xE0, 0xF1, 0x08, 0xFA, 0x33, 0x63, 0x43, 0x0C, 0x64, + 0x08, 0x0C, 0x6E, 0x12, 0x42, 0x83, 0x82, 0x3A, 0x83, 0x3A, 0xA2, 0x3A, + 0x42, 0xA3, 0x0A, 0x04, 0x03, 0xEA, 0xC4, 0x09, 0x0C, 0x64, 0x06, 0x08, + 0x68, 0x12, 0x42, 0x83, 0x82, 0x3A, 0x83, 0x3A, 0x42, 0xA3, 0x66, 0x12, + 0x62, 0x83, 0x63, 0xE4, 0x0C, 0x20, 0x44, 0x3B, 0x30, 0x08, 0x64, 0x12, + 0x61, 0x93, 0x63, 0xE4, 0x0F, 0x20, 0x21, 0x3B, 0x20, 0x08, 0x00, 0xE0, + 0x3D, 0x10, 0x40, 0x38, 0x1C, 0x08, 0x7E, 0x11, 0x40, 0x93, 0x48, 0x4A, + 0x00, 0x22, 0x42, 0xE4, 0x07, 0x20, 0x21, 0x83, 0x21, 0xE4, 0x07, 0x30, + 0x48, 0x6C, 0x21, 0xA3, 0x24, 0x3A, 0x1E, 0x08, 0x78, 0x11, 0x01, 0x93, + 0x00, 0xE4, 0x0F, 0x20, 0x00, 0x28, 0x00, 0x74, 0x00, 0xE0, 0x72, 0x0F, + 0x73, 0x11, 0x41, 0x83, 0x42, 0xE4, 0x07, 0x30, 0x41, 0xA3, 0x10, 0x04, + 0x71, 0x11, 0x61, 0x93, 0x63, 0xE4, 0x0F, 0x20, 0x20, 0x3B, 0x0A, 0x0C, + 0x01, 0x30, 0x00, 0xE0, 0x63, 0x0F, 0x06, 0x04, 0x6C, 0x11, 0x41, 0x93, + 0x42, 0xE4, 0x0F, 0x30, 0x41, 0xB3, 0x90, 0x14, 0xD0, 0x14, 0x01, 0x74, + 0x67, 0x11, 0x60, 0x93, 0x6E, 0x4B, 0x63, 0xE4, 0x03, 0x20, 0x40, 0x3B, + 0x04, 0x0C, 0x42, 0x3B, 0x28, 0x08, 0x25, 0x04, 0x62, 0x11, 0x60, 0x93, + 0x6B, 0x4B, 0x63, 0xE4, 0x03, 0x20, 0x20, 0x3B, 0x20, 0x08, 0x7F, 0x10, + 0x60, 0x93, 0x76, 0x4B, 0x2D, 0x2B, 0x0D, 0x64, 0x1A, 0x0C, 0x00, 0x30, + 0x00, 0xE0, 0x22, 0x10, 0x7B, 0x10, 0x40, 0x93, 0x42, 0xEC, 0x0C, 0x00, + 0x40, 0xB3, 0x78, 0x10, 0x41, 0x83, 0x42, 0xE4, 0x3F, 0x20, 0x00, 0x31, + 0x7F, 0x29, 0x84, 0x6C, 0x41, 0xA3, 0x02, 0x30, 0x00, 0x31, 0xFA, 0x32, + 0x42, 0x42, 0x00, 0xE0, 0xB1, 0x0A, 0x03, 0x04, 0xFF, 0xE3, 0x7E, 0xFF, + 0x90, 0x14, 0x00, 0x00, 0xD0, 0x14, 0x01, 0x74, 0x6D, 0x10, 0x60, 0x93, + 0x6E, 0x4B, 0x63, 0xE4, 0x03, 0x20, 0x40, 0x3B, 0x04, 0x0C, 0x42, 0x3B, + 0x2D, 0x08, 0x2A, 0x04, 0x03, 0xEA, 0x11, 0x01, 0x0C, 0x64, 0x28, 0x08, + 0xFF, 0xE3, 0xA0, 0xFE, 0x40, 0x38, 0x11, 0x0C, 0x64, 0x10, 0x61, 0x83, + 0x63, 0xE4, 0x20, 0x20, 0xCC, 0x74, 0x40, 0x3B, 0x0A, 0x08, 0x05, 0x04, + 0x40, 0x00, 0x00, 0x20, 0x00, 0xA0, 0x00, 0x40, 0x64, 0x13, 0x65, 0x83, + 0x41, 0x3B, 0x14, 0x08, 0x00, 0x30, 0x00, 0xE0, 0xE3, 0x0F, 0x62, 0x13, + 0x40, 0x93, 0x42, 0xEC, 0x0C, 0x00, 0x40, 0xB3, 0x7E, 0x12, 0x41, 0x83, + 0x42, 0xE4, 0x3F, 0x20, 0x00, 0x31, 0x7F, 0x29, 0x84, 0x6C, 0x41, 0xA3, + 0x03, 0x04, 0xFF, 0xE3, 0x45, 0xFF, 0x90, 0x14, 0x78, 0x12, 0x00, 0x32, + 0x46, 0xA3, 0x44, 0xA3, 0x45, 0xA3, 0x02, 0x32, 0x47, 0xA3, 0x22, 0x83, + 0x80, 0x39, 0x81, 0x39, 0x84, 0x6C, 0x42, 0xA3, 0x41, 0x83, 0x85, 0x3A, + 0x00, 0x31, 0x3F, 0x29, 0x84, 0x6C, 0x41, 0xA3, 0x4B, 0x83, 0x42, 0xE4, + 0x01, 0x20, 0x42, 0xEC, 0x1C, 0x00, 0x4B, 0xA3, 0x45, 0x8B, 0x42, 0xE4, + 0xFC, 0x31, 0x42, 0xEC, 0x38, 0x00, 0x45, 0xAB, 0x42, 0x93, 0x2B, 0x12, + 0x84, 0x68, 0x42, 0xB3, 0x42, 0xE4, 0xC0, 0x3F, 0x44, 0xAB, 0x42, 0xE4, + 0x3F, 0x30, 0x48, 0xA3, 0x3C, 0x78, 0x00, 0x00, 0xD4, 0x14, 0x01, 0x75, + 0x00, 0xE0, 0xEA, 0x09, 0x41, 0x38, 0x67, 0x08, 0x00, 0xE0, 0xDE, 0x09, + 0x43, 0x38, 0x0C, 0x08, 0x01, 0x30, 0xFF, 0xE3, 0xDB, 0xFE, 0x04, 0x30, + 0xFF, 0xE3, 0x72, 0xFE, 0x7B, 0x11, 0x41, 0x83, 0xA5, 0x3A, 0x41, 0xA3, + 0x4F, 0x04, 0x46, 0x38, 0x4D, 0x08, 0xFF, 0xE3, 0x29, 0xFE, 0x43, 0x6D, + 0xC0, 0xE4, 0x07, 0x20, 0xE7, 0x48, 0xE7, 0xE4, 0x07, 0x20, 0xFF, 0xE3, + 0x2F, 0xFE, 0x41, 0x38, 0x2C, 0x08, 0x42, 0x3E, 0x12, 0x0C, 0x43, 0x3E, + 0x1A, 0x0C, 0x40, 0x3E, 0x3B, 0x08, 0x6F, 0x11, 0x62, 0x83, 0x63, 0xE4, + 0x03, 0x20, 0x42, 0x3B, 0x35, 0x08, 0x00, 0x30, 0xFF, 0xE3, 0xB6, 0xFE, + 0x01, 0x30, 0xFF, 0xE3, 0x4D, 0xFE, 0x2E, 0x04, 0x68, 0x11, 0x62, 0x83, + 0x63, 0xE4, 0x03, 0x20, 0x41, 0x3B, 0x28, 0x08, 0x1F, 0x6C, 0xFF, 0xE3, + 0x43, 0xFE, 0x24, 0x04, 0x63, 0x11, 0x62, 0x83, 0x63, 0xE4, 0x03, 0x20, + 0x40, 0x3B, 0x1E, 0x08, 0x1F, 0x6C, 0xFF, 0xE3, 0x39, 0xFE, 0x7F, 0x10, + 0x41, 0x83, 0xA5, 0x3A, 0x41, 0xA3, 0x16, 0x04, 0xA5, 0xE4, 0x07, 0x30, + 0x58, 0x6D, 0x65, 0xE4, 0x80, 0x33, 0x63, 0xE4, 0x07, 0x20, 0x40, 0x3B, + 0x04, 0x08, 0x00, 0x30, 0xFF, 0xE3, 0x8E, 0xFE, 0x76, 0x10, 0x62, 0x83, + 0x63, 0xE4, 0x03, 0x20, 0x40, 0x3B, 0x04, 0x08, 0x00, 0x30, 0xFF, 0xE3, + 0x1F, 0xFE, 0x72, 0x10, 0x42, 0x83, 0x84, 0x3A, 0x85, 0x3A, 0xA5, 0x3A, + 0x42, 0xA3, 0x08, 0x30, 0x00, 0xE0, 0x8A, 0x09, 0x50, 0x3C, 0x01, 0x0D, + 0x10, 0x3C, 0x0D, 0x08, 0x42, 0x3C, 0x43, 0x0D, 0x02, 0x3C, 0x04, 0x08, + 0x41, 0x3C, 0x7D, 0x09, 0x16, 0x05, 0x44, 0x3C, 0x70, 0x0D, 0x48, 0x3C, + 0x78, 0x09, 0x1A, 0x04, 0x80, 0x33, 0xD2, 0x64, 0x44, 0x0D, 0x0C, 0x65, + 0x0C, 0x0C, 0x40, 0x33, 0xD2, 0x64, 0x6F, 0x09, 0x64, 0x05, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x20, 0x00, 0xA0, 0x00, 0x40, 0xFF, 0x0F, 0xFC, 0xFF, + 0x80, 0x33, 0x61, 0x43, 0xD2, 0x64, 0x59, 0x0D, 0x80, 0x33, 0x62, 0x43, + 0xD2, 0x64, 0x5F, 0x09, 0x54, 0x05, 0x00, 0xE0, 0xC7, 0x06, 0x41, 0x38, + 0x04, 0x08, 0x00, 0xE0, 0x83, 0x06, 0x57, 0x05, 0x00, 0x30, 0x00, 0xE0, + 0x43, 0x07, 0x03, 0x6D, 0x64, 0x13, 0x60, 0x93, 0x43, 0xE4, 0x0F, 0x20, + 0x64, 0x4B, 0x63, 0xE4, 0x0F, 0x20, 0x00, 0x2B, 0xCA, 0x64, 0x0A, 0x0C, + 0x7F, 0x12, 0x00, 0x93, 0x16, 0x48, 0x11, 0x58, 0x07, 0x40, 0x53, 0x6C, + 0x00, 0xE0, 0xA0, 0x14, 0x02, 0x04, 0x00, 0x30, 0xC3, 0x6C, 0x00, 0x32, + 0x30, 0x2A, 0x81, 0x64, 0x02, 0x0C, 0xCB, 0x6C, 0x0F, 0x6C, 0x31, 0x32, + 0xC9, 0x64, 0x02, 0x0C, 0x31, 0x30, 0x00, 0x74, 0x00, 0xE0, 0x7C, 0x0A, + 0x41, 0x38, 0x2F, 0x09, 0x72, 0x12, 0x20, 0x93, 0x00, 0x21, 0x21, 0xE4, + 0x0F, 0x20, 0x40, 0x83, 0x42, 0xE4, 0x0F, 0x30, 0x84, 0x6C, 0x40, 0xA3, + 0x6E, 0x12, 0x61, 0x93, 0xC0, 0x3B, 0x7E, 0x0C, 0x6B, 0x12, 0x60, 0x93, + 0x76, 0x4B, 0x43, 0xE4, 0x16, 0x10, 0x09, 0x65, 0x14, 0x0C, 0x68, 0x12, + 0x22, 0x93, 0x4E, 0x41, 0x5A, 0x4A, 0x00, 0x22, 0x42, 0xE4, 0x3F, 0x20, + 0x4C, 0x42, 0x06, 0x12, 0x40, 0x68, 0x84, 0x6C, 0x42, 0xB3, 0x42, 0xE4, + 0xC0, 0x3F, 0x44, 0xAB, 0x42, 0xE4, 0x3F, 0x30, 0x48, 0xA3, 0x2A, 0x04, + 0x43, 0x2B, 0x0D, 0x65, 0x14, 0x0C, 0x7D, 0x11, 0x42, 0x93, 0x3E, 0x11, + 0x84, 0x68, 0x42, 0xB3, 0x34, 0x42, 0x3A, 0x49, 0x00, 0x21, 0x21, 0xE4, + 0x3F, 0x20, 0x26, 0x41, 0x42, 0xE4, 0xC0, 0x3F, 0x84, 0x6C, 0x44, 0xAB, + 0x42, 0xE4, 0x3F, 0x30, 0x48, 0xA3, 0x14, 0x04, 0x73, 0x11, 0x42, 0x93, + 0x14, 0x11, 0x80, 0x68, 0x42, 0xB3, 0x42, 0xE4, 0xC0, 0x3F, 0x44, 0xAB, + 0x22, 0x93, 0x3A, 0x41, 0x3A, 0x49, 0x00, 0x21, 0x21, 0xE4, 0x3F, 0x20, + 0x48, 0x83, 0x42, 0xE4, 0x3F, 0x30, 0x84, 0x6C, 0x48, 0xA3, 0x6A, 0x11, + 0x62, 0x93, 0x6E, 0x43, 0x7A, 0x4B, 0x2F, 0x3B, 0x09, 0x08, 0x67, 0x11, + 0x4B, 0x83, 0x42, 0xE4, 0x01, 0x20, 0x42, 0xEC, 0x1C, 0x00, 0x4B, 0xA3, + 0x1B, 0x04, 0x63, 0x11, 0x62, 0x93, 0x74, 0x43, 0x7A, 0x4B, 0x2F, 0x3B, + 0x09, 0x08, 0x60, 0x11, 0x4B, 0x83, 0x42, 0xE4, 0x01, 0x20, 0x42, 0xEC, + 0x1E, 0x00, 0x4B, 0xA3, 0x0D, 0x04, 0x7C, 0x10, 0x62, 0x93, 0x7A, 0x43, + 0x7A, 0x4B, 0x2F, 0x3B, 0x07, 0x08, 0x79, 0x10, 0x4B, 0x83, 0x42, 0xE4, + 0x01, 0x20, 0xA5, 0x3A, 0x4B, 0xA3, 0x76, 0x10, 0x62, 0x93, 0x19, 0x4B, + 0x67, 0x43, 0x79, 0x4B, 0x0E, 0x64, 0x03, 0x0C, 0x00, 0xE0, 0x34, 0x04, + 0x71, 0x10, 0x22, 0x93, 0x39, 0x49, 0x22, 0x41, 0x45, 0x8B, 0x42, 0xE4, + 0xFC, 0x31, 0x84, 0x6C, 0x45, 0xAB, 0x08, 0x30, 0x00, 0xE0, 0x18, 0x09, + 0x6B, 0x10, 0x67, 0x83, 0x41, 0x3B, 0x0D, 0x08, 0x69, 0x10, 0x42, 0x83, + 0x84, 0x3A, 0x85, 0x3A, 0xA4, 0x3A, 0x42, 0xA3, 0x07, 0x30, 0x00, 0x31, + 0xB4, 0x32, 0x00, 0xE0, 0xE9, 0x08, 0x91, 0x04, 0x07, 0x30, 0x00, 0x31, + 0x96, 0x32, 0x00, 0xE0, 0xE3, 0x08, 0x8B, 0x04, 0x40, 0x00, 0x00, 0x20, + 0x00, 0x50, 0x00, 0x40, 0xFF, 0x0F, 0xFC, 0xFF, 0x7F, 0x12, 0x00, 0x93, + 0x10, 0x48, 0x00, 0xE4, 0x03, 0x20, 0x00, 0xE0, 0xE1, 0x09, 0x40, 0x38, + 0x7C, 0x0C, 0x08, 0x30, 0x00, 0xE0, 0xF0, 0x08, 0x79, 0x12, 0x62, 0x83, + 0x63, 0xE4, 0x03, 0x20, 0x40, 0x3B, 0x07, 0x08, 0x07, 0x30, 0x00, 0x31, + 0x96, 0x32, 0x00, 0xE0, 0xC5, 0x08, 0x6D, 0x04, 0x73, 0x12, 0x42, 0x83, + 0x84, 0x3A, 0x85, 0x3A, 0x42, 0xA3, 0x67, 0x04, 0x70, 0x12, 0x62, 0x83, + 0x63, 0xE4, 0x30, 0x20, 0x40, 0x3B, 0x0D, 0x08, 0x00, 0x30, 0x00, 0x31, + 0x00, 0x32, 0x00, 0xE0, 0x99, 0x10, 0x6B, 0x12, 0x42, 0x83, 0x84, 0x3A, + 0x85, 0x3A, 0xA5, 0x3A, 0x42, 0xA3, 0x55, 0x04, 0x50, 0x3B, 0x0F, 0x08, + 0xFF, 0xE3, 0xA0, 0xF8, 0x83, 0x6C, 0x01, 0x30, 0x1F, 0x31, 0x00, 0xE0, + 0x89, 0x10, 0x63, 0x12, 0x42, 0x83, 0x84, 0x3A, 0x85, 0x3A, 0xA5, 0x3A, + 0x42, 0xA3, 0x45, 0x04, 0x04, 0x30, 0x00, 0x31, 0x14, 0x32, 0x00, 0xE0, + 0x97, 0x08, 0x3F, 0x04, 0x0D, 0x30, 0x00, 0xE0, 0xC3, 0x03, 0x07, 0x30, + 0x00, 0x31, 0x4B, 0x32, 0x00, 0xE0, 0x8E, 0x08, 0x04, 0x30, 0x00, 0x31, + 0x05, 0x32, 0x00, 0xE0, 0x89, 0x08, 0x31, 0x04, 0x75, 0x11, 0x61, 0x83, + 0x63, 0xE4, 0x18, 0x20, 0x40, 0x3B, 0x0F, 0x08, 0x72, 0x11, 0x41, 0x83, + 0x83, 0x3A, 0x84, 0x3A, 0xA3, 0x3A, 0x41, 0xA3, 0x40, 0x83, 0x42, 0xE4, + 0x0F, 0x20, 0x00, 0x31, 0x5F, 0x29, 0x84, 0x6C, 0x40, 0xA3, 0x13, 0x04, + 0x48, 0x3B, 0x11, 0x08, 0x6A, 0x11, 0x41, 0x83, 0x83, 0x3A, 0x84, 0x3A, + 0xA4, 0x3A, 0x41, 0xA3, 0x40, 0x83, 0x42, 0xE4, 0x0F, 0x20, 0x00, 0x30, + 0x5F, 0x28, 0x80, 0x6C, 0x40, 0xA3, 0x00, 0x30, 0x00, 0xE0, 0xD4, 0x03, + 0x07, 0x30, 0x00, 0x31, 0x4B, 0x32, 0x00, 0xE0, 0x5D, 0x08, 0x04, 0x30, + 0x00, 0x31, 0x05, 0x32, 0x00, 0xE0, 0x58, 0x08, 0x94, 0x14, 0x00, 0x00, + 0xD0, 0x14, 0x7C, 0x10, 0x60, 0x93, 0x43, 0xE4, 0x0F, 0x20, 0x64, 0x4B, + 0x63, 0xE4, 0x0F, 0x20, 0xC9, 0x64, 0x0A, 0x08, 0x77, 0x10, 0x40, 0x83, + 0x42, 0xE4, 0x0F, 0x30, 0x40, 0xA3, 0x10, 0x30, 0x00, 0xE0, 0xF0, 0x07, + 0x04, 0x04, 0x08, 0x30, 0x00, 0xE0, 0xEC, 0x07, 0x90, 0x14, 0x00, 0x00, + 0xD1, 0x14, 0x70, 0x10, 0x60, 0x93, 0x6E, 0x4B, 0x63, 0xE4, 0x0C, 0x20, + 0x4E, 0x10, 0x6C, 0x5A, 0x80, 0x93, 0x00, 0x30, 0x00, 0xE0, 0xCA, 0x05, + 0xD1, 0x7B, 0x08, 0x30, 0x01, 0x31, 0x05, 0x32, 0x00, 0xE0, 0x2C, 0x08, + 0x91, 0x14, 0x00, 0x00, 0x66, 0x10, 0x00, 0x93, 0x12, 0x48, 0x00, 0xE4, + 0x03, 0x20, 0x3C, 0x78, 0x63, 0x10, 0x00, 0x93, 0x10, 0x48, 0x00, 0xE4, + 0x03, 0x20, 0x3C, 0x78, 0x40, 0x00, 0x00, 0x20, 0x2C, 0x39, 0x00, 0x00, + 0x7C, 0x10, 0x00, 0x93, 0x0E, 0x48, 0x00, 0xE4, 0x03, 0x20, 0x3C, 0x78, + 0x79, 0x10, 0x00, 0x93, 0x0B, 0x48, 0x00, 0xE4, 0x03, 0x20, 0x3C, 0x78, + 0xD1, 0x14, 0x76, 0x10, 0x60, 0x93, 0x6E, 0x4B, 0x63, 0xE4, 0x0C, 0x20, + 0x54, 0x10, 0x6C, 0x5A, 0x80, 0x93, 0x00, 0x30, 0x00, 0xE0, 0x9A, 0x05, + 0xD1, 0x7B, 0x91, 0x14, 0xD0, 0x14, 0x6F, 0x10, 0x62, 0x83, 0x63, 0xE4, + 0x03, 0x20, 0x41, 0x3B, 0x04, 0x08, 0x08, 0x30, 0x00, 0xE0, 0x26, 0x03, + 0x90, 0x14, 0x00, 0x00, 0xD0, 0x14, 0x00, 0x74, 0x4C, 0x38, 0x03, 0x0C, + 0x49, 0x38, 0x0C, 0x08, 0x66, 0x10, 0x01, 0x32, 0x45, 0xA3, 0x62, 0x83, + 0x63, 0xE4, 0x03, 0x20, 0x41, 0x3B, 0x04, 0x0C, 0x00, 0x30, 0xFF, 0xE3, + 0x1B, 0xFC, 0x90, 0x14, 0x40, 0x00, 0x00, 0x20, 0x2C, 0x39, 0x00, 0x00, + 0xC3, 0x6C, 0x84, 0x74, 0x41, 0x3A, 0x0C, 0x0C, 0x22, 0x58, 0x01, 0x2A, + 0x88, 0x74, 0x28, 0x59, 0x00, 0x30, 0x40, 0x83, 0x09, 0x6C, 0x00, 0x23, + 0x4E, 0x64, 0xFC, 0x0B, 0x02, 0x04, 0x00, 0x30, 0x3C, 0x78, 0x00, 0x00, + 0xD1, 0x14, 0x03, 0x6D, 0xC4, 0x74, 0x48, 0x74, 0x40, 0x38, 0x09, 0x0C, + 0x02, 0x32, 0x40, 0xA0, 0x61, 0xA0, 0xFF, 0xE3, 0xE5, 0xFF, 0x02, 0xA4, + 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, 0xD1, 0x14, 0x03, 0x6D, + 0xC4, 0x74, 0x48, 0x74, 0x40, 0x38, 0x09, 0x0C, 0x01, 0x32, 0x40, 0xA0, + 0x61, 0xA0, 0xFF, 0xE3, 0xD5, 0xFF, 0x02, 0xA4, 0x01, 0x30, 0x02, 0x04, + 0x00, 0x30, 0x91, 0x14, 0xD2, 0x14, 0x22, 0x14, 0x03, 0x6D, 0x44, 0x75, + 0x01, 0x1B, 0x00, 0x32, 0x40, 0xA3, 0x6E, 0x31, 0x21, 0xA3, 0x4E, 0xDC, + 0x00, 0x00, 0x4E, 0xDC, 0x01, 0x00, 0x00, 0x32, 0x38, 0x2A, 0x4E, 0xDC, + 0x02, 0x00, 0x3D, 0x32, 0x4E, 0xDC, 0x03, 0x00, 0x40, 0x38, 0x16, 0x0C, + 0x71, 0x33, 0x60, 0xA0, 0x12, 0x33, 0x61, 0xA0, 0x01, 0x20, 0x01, 0x19, + 0x02, 0x32, 0xFF, 0xE3, 0x75, 0xF7, 0x0E, 0x5C, 0x7B, 0x6C, 0x04, 0x32, + 0xFF, 0xE3, 0x70, 0xF7, 0x13, 0x6C, 0x57, 0x6C, 0xFF, 0xE3, 0xA8, 0xFF, + 0x08, 0xA4, 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x02, 0x14, 0x92, 0x14, + 0xD1, 0x14, 0x03, 0x6D, 0xC4, 0x74, 0x48, 0x74, 0x40, 0x38, 0x09, 0x0C, + 0x06, 0x32, 0x40, 0xA0, 0x61, 0xA0, 0xFF, 0xE3, 0x97, 0xFF, 0x02, 0xA4, + 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, 0xD1, 0x14, 0x03, 0x6D, + 0x44, 0x74, 0x40, 0x38, 0x14, 0x0C, 0x51, 0x33, 0x60, 0xA0, 0x0A, 0x33, + 0x61, 0xA0, 0x00, 0x33, 0x62, 0xA0, 0x00, 0x33, 0x7F, 0x2B, 0x63, 0xA0, + 0x2A, 0x33, 0x64, 0xA0, 0x00, 0x33, 0x4F, 0x2B, 0x65, 0xA0, 0xFF, 0xE3, + 0x7D, 0xFF, 0x06, 0xA4, 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, + 0xD1, 0x14, 0x03, 0x6D, 0x44, 0x74, 0x88, 0x74, 0x40, 0x38, 0x0B, 0x0C, + 0x20, 0x33, 0x60, 0xA0, 0x21, 0xA0, 0x42, 0xA0, 0x04, 0x31, 0xFF, 0xE3, + 0x6B, 0xFF, 0x03, 0xA4, 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, + 0xD1, 0x14, 0x03, 0x6D, 0x44, 0x74, 0x40, 0x38, 0x0A, 0x0C, 0x07, 0x33, + 0x60, 0xA0, 0x21, 0xA0, 0x03, 0x31, 0xFF, 0xE3, 0x5B, 0xFF, 0x02, 0xA4, + 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, 0xD1, 0x14, 0x03, 0x6D, + 0x44, 0x74, 0x88, 0x74, 0x40, 0x38, 0x0B, 0x0C, 0x22, 0x33, 0x60, 0xA0, + 0x21, 0xA0, 0x42, 0xA0, 0x04, 0x31, 0xFF, 0xE3, 0x49, 0xFF, 0x03, 0xA4, + 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, 0xD1, 0x14, 0x03, 0x6D, + 0x44, 0x74, 0x89, 0x74, 0x40, 0x38, 0x0D, 0x0C, 0x31, 0x33, 0x60, 0xA0, + 0x21, 0xA0, 0x68, 0x4A, 0x62, 0xA0, 0x43, 0xA0, 0x05, 0x31, 0xFF, 0xE3, + 0x35, 0xFF, 0x04, 0xA4, 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, + 0xD1, 0x14, 0x03, 0x6D, 0x44, 0x74, 0x40, 0x38, 0x0A, 0x0C, 0x04, 0x33, + 0x60, 0xA0, 0x21, 0xA0, 0x03, 0x31, 0xFF, 0xE3, 0x25, 0xFF, 0x02, 0xA4, + 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, 0xD1, 0x14, 0x03, 0x6D, + 0x44, 0x74, 0x40, 0x38, 0x0A, 0x0C, 0x03, 0x33, 0x60, 0xA0, 0x21, 0xA0, + 0x03, 0x31, 0xFF, 0xE3, 0x15, 0xFF, 0x02, 0xA4, 0x01, 0x30, 0x02, 0x04, + 0x00, 0x30, 0x91, 0x14, 0xD1, 0x14, 0x03, 0x6D, 0x38, 0x33, 0x60, 0xA0, + 0x3B, 0x33, 0x61, 0xA0, 0x02, 0x33, 0x62, 0xA0, 0x00, 0x33, 0x44, 0x2B, + 0x63, 0xA0, 0x05, 0x31, 0xFF, 0xE3, 0x02, 0xFF, 0x04, 0xA4, 0x91, 0x14, + 0xD3, 0x14, 0x22, 0x14, 0x03, 0x6D, 0x01, 0x1D, 0xBB, 0x6D, 0x17, 0x6C, + 0x7B, 0x6C, 0x00, 0xE0, 0xD3, 0x0A, 0x00, 0x33, 0x5B, 0x2B, 0x60, 0xA4, + 0x08, 0x33, 0x61, 0xA4, 0x60, 0x95, 0x62, 0xA4, 0x48, 0x4B, 0x43, 0xA4, + 0x50, 0x4B, 0x44, 0xA4, 0x78, 0x4B, 0x65, 0xA4, 0x60, 0x98, 0x66, 0xA4, + 0x48, 0x4B, 0x47, 0xA4, 0x50, 0x4B, 0x48, 0xA4, 0x78, 0x4B, 0x69, 0xA4, + 0x00, 0x33, 0x6A, 0xA4, 0x6B, 0xA4, 0x6C, 0xA4, 0x13, 0x6C, 0x0B, 0x31, + 0xFF, 0xE3, 0xDA, 0xFE, 0x0D, 0xA4, 0x02, 0x14, 0x93, 0x14, 0x00, 0x00, + 0xD1, 0x14, 0x03, 0x6D, 0x18, 0x33, 0x60, 0xA0, 0x0B, 0x33, 0x61, 0xA0, + 0x03, 0x31, 0xFF, 0xE3, 0xCD, 0xFE, 0x02, 0xA4, 0x91, 0x14, 0x00, 0x00, + 0xD1, 0x14, 0x03, 0x6D, 0x38, 0x33, 0x60, 0xA0, 0x0A, 0x33, 0x61, 0xA0, + 0x28, 0x33, 0x62, 0xA0, 0x23, 0x33, 0x63, 0xA0, 0x05, 0x31, 0xFF, 0xE3, + 0xBD, 0xFE, 0x04, 0xA4, 0x91, 0x14, 0x00, 0x00, 0xD1, 0x14, 0x03, 0x6D, + 0x72, 0x11, 0x60, 0x93, 0x03, 0xC4, 0x83, 0x70, 0x60, 0xA0, 0x38, 0x32, + 0x8E, 0x64, 0x25, 0x0C, 0xC8, 0x64, 0x07, 0x0C, 0x58, 0x3B, 0x0C, 0x0C, + 0x28, 0x32, 0x8E, 0x64, 0x50, 0x08, 0x11, 0x04, 0x48, 0x32, 0x8E, 0x64, + 0x28, 0x0C, 0x58, 0x32, 0x8E, 0x64, 0x49, 0x08, 0x35, 0x04, 0x67, 0x11, + 0x60, 0x93, 0x70, 0x4B, 0x61, 0xA0, 0x03, 0x31, 0xFF, 0xE3, 0x9A, 0xFE, + 0x02, 0xA4, 0x3F, 0x04, 0x62, 0x11, 0x40, 0x93, 0x50, 0x4A, 0x41, 0xA0, + 0x60, 0x93, 0x78, 0x4B, 0x62, 0xA0, 0x04, 0x31, 0xFF, 0xE3, 0x8E, 0xFE, + 0x03, 0xA4, 0x33, 0x04, 0x7C, 0x10, 0x40, 0x93, 0x50, 0x4A, 0x41, 0xA0, + 0x40, 0x93, 0x58, 0x4A, 0x42, 0xA0, 0x61, 0x93, 0x63, 0xA0, 0x05, 0x31, + 0xFF, 0xE3, 0x80, 0xFE, 0x04, 0xA4, 0x25, 0x04, 0x75, 0x10, 0x40, 0x93, + 0x50, 0x4A, 0x41, 0xA0, 0x40, 0x93, 0x58, 0x4A, 0x42, 0xA0, 0x41, 0x93, + 0x43, 0xA0, 0x61, 0x93, 0x68, 0x4B, 0x64, 0xA0, 0x06, 0x31, 0xFF, 0xE3, + 0x6F, 0xFE, 0x05, 0xA4, 0x14, 0x04, 0x6D, 0x10, 0x40, 0x93, 0x50, 0x4A, + 0x41, 0xA0, 0x40, 0x93, 0x58, 0x4A, 0x42, 0xA0, 0x41, 0x93, 0x43, 0xA0, + 0x41, 0x93, 0x48, 0x4A, 0x44, 0xA0, 0x61, 0x93, 0x70, 0x4B, 0x65, 0xA0, + 0x07, 0x31, 0xFF, 0xE3, 0x5B, 0xFE, 0x06, 0xA4, 0x63, 0x10, 0x00, 0x93, + 0x00, 0xC4, 0x80, 0x70, 0x04, 0x48, 0x91, 0x14, 0x00, 0x90, 0x00, 0x40, + 0xD4, 0x14, 0xC7, 0x6D, 0x80, 0x75, 0x03, 0x30, 0x00, 0xE0, 0xC0, 0x03, + 0x03, 0x6D, 0x00, 0x30, 0x00, 0xE0, 0xBC, 0x03, 0x43, 0x6D, 0x43, 0x44, + 0x66, 0x44, 0x6C, 0x5A, 0x71, 0x5B, 0x42, 0x43, 0x6D, 0x5A, 0x43, 0x43, + 0x4D, 0x5A, 0x44, 0xC4, 0x42, 0x08, 0x54, 0x4A, 0x80, 0xC4, 0x23, 0x84, + 0x23, 0x43, 0x06, 0x43, 0x25, 0x58, 0x6D, 0x59, 0x6A, 0x4B, 0x08, 0x7D, + 0x90, 0x5B, 0x00, 0xE0, 0xC3, 0x0A, 0x40, 0x7D, 0xA5, 0xC4, 0x25, 0x08, + 0x64, 0x45, 0xB5, 0x5B, 0xAB, 0x4D, 0x94, 0x5C, 0xFA, 0x33, 0x63, 0x43, + 0x0C, 0x65, 0x23, 0x08, 0xFA, 0x33, 0x64, 0x43, 0x0C, 0x65, 0x21, 0x08, + 0x03, 0xEA, 0x70, 0x17, 0x0C, 0x65, 0x1F, 0x08, 0xFA, 0x33, 0x65, 0x43, + 0x0C, 0x65, 0x1D, 0x08, 0x03, 0xEA, 0x10, 0x27, 0x0C, 0x65, 0x1B, 0x08, + 0x63, 0xE4, 0xCF, 0x07, 0x0C, 0x65, 0x19, 0x08, 0x63, 0xE4, 0xCF, 0x07, + 0x0C, 0x65, 0x17, 0x08, 0xFA, 0x33, 0x66, 0x43, 0x0C, 0x65, 0x15, 0x08, + 0x03, 0xEA, 0x50, 0x46, 0x0C, 0x65, 0xC3, 0x64, 0x07, 0x23, 0x10, 0x04, + 0x00, 0x33, 0x0E, 0x04, 0x01, 0x33, 0x0C, 0x04, 0x02, 0x33, 0x0A, 0x04, + 0x03, 0x33, 0x08, 0x04, 0x04, 0x33, 0x06, 0x04, 0x05, 0x33, 0x04, 0x04, + 0x06, 0x33, 0x02, 0x04, 0x07, 0x33, 0x52, 0x11, 0x62, 0xC4, 0x42, 0x08, + 0x40, 0x82, 0xC0, 0x3A, 0x0A, 0x0C, 0x4F, 0x11, 0x62, 0xC4, 0x43, 0x08, + 0x40, 0x8B, 0x41, 0x4A, 0x08, 0x7D, 0x8A, 0x4C, 0x61, 0x8B, 0x8C, 0x5C, + 0x40, 0x3E, 0x2A, 0x08, 0x84, 0xE4, 0xE7, 0x03, 0x68, 0x11, 0x63, 0xD8, + 0x28, 0x00, 0x40, 0x3B, 0x08, 0x08, 0x63, 0x44, 0xA6, 0x44, 0x6D, 0x5D, + 0xA4, 0x43, 0xAD, 0x5D, 0xB1, 0x5D, 0x12, 0x04, 0x41, 0x3B, 0x08, 0x08, + 0xA4, 0x44, 0x66, 0x44, 0x6C, 0x5D, 0xA3, 0x43, 0xAD, 0x5D, 0xB1, 0x5D, + 0x09, 0x04, 0x42, 0x3B, 0x07, 0x08, 0x62, 0x44, 0x45, 0x44, 0x6D, 0x5A, + 0xA4, 0x43, 0x6D, 0x5D, 0xB1, 0x5B, 0xAF, 0x4D, 0x54, 0x75, 0xA0, 0xA7, + 0xFF, 0x33, 0xD6, 0x64, 0x2C, 0x08, 0x00, 0x33, 0x00, 0x2B, 0x60, 0xA7, + 0x28, 0x04, 0x41, 0x3E, 0x26, 0x08, 0x74, 0x10, 0x63, 0xD8, 0x28, 0x00, + 0x43, 0x3B, 0x0A, 0x08, 0xA7, 0x44, 0x85, 0xC4, 0x45, 0x08, 0xB1, 0x5D, + 0xA4, 0x45, 0xB0, 0x5D, 0xA4, 0xC4, 0x45, 0x08, 0x16, 0x04, 0x44, 0x3B, + 0x0A, 0x08, 0x63, 0x44, 0x46, 0x44, 0x6D, 0x5A, 0xA4, 0x43, 0xAD, 0x5D, + 0xB1, 0x5D, 0xA3, 0x45, 0xB1, 0x5D, 0x0B, 0x04, 0x45, 0x3B, 0x09, 0x08, + 0x65, 0x44, 0x47, 0x44, 0x6D, 0x5A, 0xA3, 0x43, 0xAD, 0x5D, 0xB1, 0x5D, + 0xA5, 0xC4, 0x45, 0x08, 0xAB, 0x4D, 0xA0, 0xAF, 0x94, 0x14, 0x00, 0x00, + 0x4C, 0x00, 0x00, 0x20, 0x74, 0x11, 0x03, 0xDC, 0x28, 0x00, 0x3C, 0x78, + 0x00, 0x74, 0x45, 0x74, 0x89, 0x74, 0x67, 0x58, 0xCC, 0x74, 0x13, 0x3B, + 0x10, 0x08, 0x01, 0x48, 0x00, 0x28, 0x6E, 0x11, 0x03, 0xC4, 0x40, 0x08, + 0x60, 0x80, 0xA0, 0x3B, 0x60, 0xA0, 0x21, 0x41, 0x60, 0x88, 0x63, 0xE4, + 0x01, 0x20, 0x4C, 0x6C, 0x20, 0xA8, 0x41, 0xA8, 0x3C, 0x78, 0x00, 0x00, + 0xD1, 0x14, 0x86, 0x11, 0x00, 0x33, 0x64, 0xDC, 0x28, 0x00, 0x13, 0x6C, + 0x00, 0x31, 0x28, 0x32, 0xFF, 0xE3, 0x20, 0xF5, 0x60, 0x84, 0x01, 0x32, + 0xC8, 0x6C, 0x60, 0xA4, 0x20, 0x8C, 0x01, 0x33, 0x4C, 0x68, 0xAB, 0x39, + 0x20, 0xAC, 0x91, 0x31, 0x22, 0x41, 0x21, 0xAC, 0x24, 0x84, 0x48, 0x6C, + 0x24, 0xA4, 0x22, 0x8C, 0x4C, 0x68, 0x21, 0xEC, 0x4C, 0x07, 0x22, 0xAC, + 0xDA, 0x31, 0x22, 0x41, 0x23, 0xAC, 0x28, 0x84, 0x48, 0x6C, 0x28, 0xA4, + 0x24, 0x8C, 0x4C, 0x68, 0x21, 0xEC, 0x30, 0x09, 0x24, 0xAC, 0xC2, 0x31, + 0x25, 0xAC, 0x2C, 0x84, 0x48, 0x6C, 0x2C, 0xA4, 0x26, 0x8C, 0x4C, 0x68, + 0x21, 0xEC, 0xD6, 0x07, 0x26, 0xAC, 0xEE, 0x31, 0x22, 0x41, 0x27, 0xAC, + 0x30, 0x84, 0x48, 0x6C, 0x30, 0xA4, 0x28, 0x8C, 0x4C, 0x68, 0x21, 0xEC, + 0x16, 0x08, 0x28, 0xAC, 0x01, 0xEA, 0x36, 0x03, 0x29, 0xAC, 0x34, 0x84, + 0x84, 0x6C, 0x54, 0xA4, 0x4A, 0x8C, 0xC8, 0x68, 0xAB, 0x3B, 0x6A, 0xAC, + 0x03, 0xEA, 0x01, 0x04, 0x6B, 0xAC, 0x91, 0x14, 0x4C, 0x00, 0x00, 0x20, + 0x68, 0x10, 0x40, 0x93, 0xA1, 0x3A, 0x40, 0xB3, 0x14, 0x33, 0x03, 0x6C, + 0x00, 0x2B, 0xCC, 0x74, 0x40, 0x3B, 0xFC, 0x0B, 0x63, 0x10, 0x40, 0x93, + 0x81, 0x3A, 0x40, 0xB3, 0x3C, 0x78, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x40, + 0xD0, 0x14, 0x01, 0x13, 0x00, 0x33, 0x60, 0xA0, 0x61, 0xA0, 0x62, 0xA0, + 0x01, 0x32, 0x43, 0xA0, 0x64, 0xA0, 0x65, 0xA0, 0x66, 0xA0, 0x67, 0xA0, + 0x68, 0xA0, 0x0B, 0x20, 0x00, 0x31, 0x0C, 0x32, 0xFF, 0xE3, 0xB8, 0xF4, + 0xB2, 0x30, 0x00, 0xE0, 0xF7, 0x0E, 0x06, 0x30, 0x01, 0x31, 0x0B, 0x32, + 0x00, 0xE0, 0xD6, 0x04, 0x00, 0xE0, 0xEA, 0x0E, 0x90, 0x14, 0x00, 0x00, + 0xD0, 0x14, 0x00, 0x74, 0x71, 0x12, 0x25, 0x83, 0x42, 0x59, 0x42, 0xE4, + 0x07, 0x20, 0x64, 0x83, 0x8E, 0x64, 0x19, 0x0C, 0x6D, 0x12, 0x24, 0x5B, + 0x18, 0xA1, 0x45, 0xA3, 0x4D, 0x38, 0x09, 0x08, 0xFF, 0xE3, 0xC0, 0xF4, + 0x43, 0x6C, 0x0A, 0x12, 0x06, 0x32, 0xFF, 0xE3, 0xA3, 0xF4, 0x0B, 0x04, + 0x4C, 0x33, 0xC2, 0x64, 0x08, 0x08, 0xFF, 0xE3, 0xB5, 0xF4, 0x43, 0x6C, + 0x05, 0x12, 0x06, 0x32, 0xFF, 0xE3, 0x98, 0xF4, 0x90, 0x14, 0x00, 0x00, + 0x63, 0x12, 0x43, 0x93, 0x88, 0x74, 0xAA, 0x33, 0xCA, 0x64, 0x05, 0x08, + 0x01, 0x32, 0x7D, 0x11, 0x43, 0xA3, 0x0A, 0x04, 0x7E, 0x11, 0x43, 0x93, + 0x88, 0x74, 0x55, 0x33, 0xCA, 0x64, 0x04, 0x08, 0x01, 0x32, 0x78, 0x11, + 0x40, 0xA3, 0x3C, 0x78, 0x01, 0x32, 0x76, 0x11, 0x48, 0xA3, 0x3C, 0x78, + 0xD0, 0x14, 0x00, 0x74, 0x00, 0xE0, 0xAE, 0x0E, 0x90, 0x14, 0x00, 0x00, + 0x00, 0x74, 0x71, 0x11, 0x01, 0x32, 0x02, 0xC4, 0x20, 0x40, 0x41, 0x83, + 0x08, 0x6C, 0x01, 0xA3, 0x46, 0x83, 0xA0, 0x3A, 0x46, 0xA3, 0x3C, 0x78, + 0xD2, 0x14, 0x6B, 0x11, 0x63, 0x83, 0x41, 0x3B, 0x92, 0x08, 0x69, 0x11, + 0x00, 0x32, 0x47, 0xA3, 0x44, 0x83, 0x65, 0x83, 0x8E, 0x64, 0xA5, 0x0C, + 0x25, 0x11, 0x68, 0x59, 0x78, 0x83, 0x00, 0x22, 0x42, 0xE4, 0x07, 0x20, + 0x44, 0xA1, 0x45, 0x11, 0x2C, 0x92, 0x21, 0xE4, 0xFF, 0x30, 0x4C, 0x6C, + 0x2C, 0xB2, 0x4C, 0x3B, 0x18, 0x0C, 0x0C, 0x3B, 0x04, 0x08, 0x4B, 0x3B, + 0x6C, 0x08, 0x07, 0x04, 0x4D, 0x3B, 0x2B, 0x0C, 0x4C, 0x32, 0x8E, 0x64, + 0x66, 0x08, 0x49, 0x04, 0x9B, 0x10, 0xAD, 0x94, 0x5B, 0x10, 0x48, 0x69, + 0xFF, 0xE3, 0x50, 0xF8, 0x6A, 0x48, 0x63, 0xE4, 0x00, 0x2F, 0x4C, 0x6D, + 0xAD, 0xB4, 0x10, 0x05, 0x75, 0x10, 0x2D, 0x93, 0x55, 0x10, 0x48, 0x68, + 0x21, 0xEC, 0x00, 0x16, 0x2D, 0xB3, 0x2D, 0x93, 0x21, 0xE4, 0xFF, 0x30, + 0x21, 0xEC, 0x18, 0x00, 0x2D, 0xB3, 0x2E, 0x93, 0x84, 0x68, 0x42, 0xEC, + 0x00, 0x14, 0x4E, 0xB3, 0x4E, 0x93, 0x42, 0xE4, 0xFF, 0x30, 0x28, 0x10, + 0x28, 0x81, 0x84, 0x6C, 0x4E, 0xB3, 0xF6, 0x04, 0x68, 0x10, 0x0D, 0x93, + 0x28, 0x10, 0x04, 0x68, 0x44, 0x10, 0x80, 0x82, 0x88, 0x44, 0x10, 0x6C, + 0x0C, 0x04, 0x00, 0x00, 0x78, 0x00, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, + 0x8A, 0x00, 0x00, 0x20, 0x00, 0x90, 0x00, 0x40, 0xFF, 0x00, 0xFF, 0xFF, + 0x0D, 0xB3, 0x0D, 0x93, 0x00, 0xE4, 0xFF, 0x30, 0x81, 0x82, 0x10, 0x6C, + 0x0D, 0xB3, 0x0E, 0x93, 0x40, 0x68, 0x42, 0x82, 0x48, 0x42, 0x84, 0x6C, + 0x4E, 0xB3, 0xD4, 0x04, 0x62, 0x13, 0x0D, 0x93, 0x22, 0x13, 0x04, 0x68, + 0x42, 0x13, 0x88, 0x82, 0x88, 0x44, 0x10, 0x6C, 0x0D, 0xB3, 0x0D, 0x93, + 0x00, 0xE4, 0xFF, 0x30, 0x89, 0x82, 0x10, 0x6C, 0x0D, 0xB3, 0x0E, 0x93, + 0x40, 0x68, 0x0A, 0x82, 0x08, 0x40, 0x40, 0x6C, 0x2E, 0xB3, 0x2E, 0x93, + 0x21, 0xE4, 0xFF, 0x30, 0x4B, 0x82, 0x84, 0x6C, 0x4E, 0xB3, 0xB8, 0x04, + 0x00, 0x31, 0x57, 0x12, 0x22, 0xA2, 0x06, 0x32, 0xC8, 0x64, 0x04, 0x08, + 0x00, 0x32, 0x74, 0x12, 0x43, 0xA3, 0xFF, 0xE3, 0xEF, 0xFE, 0x1B, 0x04, + 0x51, 0x12, 0x62, 0x82, 0x00, 0x23, 0xCC, 0x74, 0x62, 0xA2, 0x4B, 0x32, + 0xC8, 0x64, 0x13, 0x08, 0x8D, 0x12, 0x00, 0x33, 0x62, 0xA4, 0xFF, 0xE3, + 0xE1, 0xFE, 0x67, 0x84, 0x00, 0x23, 0xCC, 0x74, 0x67, 0xA4, 0x04, 0x32, + 0xC8, 0x64, 0x07, 0x08, 0x47, 0xA4, 0x64, 0x12, 0x0C, 0x93, 0x00, 0x74, + 0xFF, 0xE3, 0xE2, 0xFB, 0x64, 0x12, 0x60, 0x83, 0x41, 0x3B, 0x55, 0x08, + 0x7F, 0x11, 0x60, 0x93, 0x7F, 0x2B, 0x8C, 0x74, 0x0A, 0x3A, 0x4C, 0x08, + 0xCB, 0x6C, 0x40, 0x12, 0x62, 0xC4, 0x43, 0x08, 0x60, 0x93, 0x0C, 0x78, + 0x79, 0x11, 0x60, 0x93, 0x03, 0xC4, 0x83, 0x70, 0x27, 0x43, 0x4D, 0x43, + 0x48, 0x59, 0x4D, 0x5A, 0x43, 0xC4, 0x43, 0x08, 0x6F, 0x53, 0xD1, 0x32, + 0xC8, 0x64, 0x02, 0x08, 0xD1, 0x33, 0xD1, 0x30, 0x6D, 0x58, 0x0C, 0x74, + 0x00, 0xE0, 0xCC, 0x0D, 0x31, 0x04, 0x20, 0x30, 0x00, 0xE0, 0x72, 0x03, + 0x2D, 0x04, 0x72, 0x11, 0x41, 0x93, 0xA6, 0x3A, 0x41, 0xB3, 0x00, 0x30, + 0x00, 0xE0, 0x14, 0x09, 0x25, 0x04, 0x01, 0x30, 0xFF, 0xE3, 0x12, 0xFF, + 0x21, 0x04, 0x02, 0x30, 0xFF, 0xE3, 0x0E, 0xFF, 0x1D, 0x04, 0x03, 0x30, + 0xFF, 0xE3, 0x0A, 0xFF, 0x19, 0x04, 0x04, 0x30, 0xFF, 0xE3, 0x06, 0xFF, + 0x15, 0x04, 0x61, 0x11, 0x00, 0x93, 0xA0, 0x93, 0x20, 0x93, 0x81, 0x93, + 0x41, 0x93, 0x00, 0xC4, 0x80, 0x70, 0x05, 0xC4, 0x43, 0x70, 0x68, 0x43, + 0x38, 0x49, 0x4C, 0x6C, 0xD0, 0x74, 0x68, 0x43, 0x02, 0xC4, 0x82, 0x70, + 0x8C, 0x6C, 0xFF, 0xE3, 0x19, 0xFE, 0x00, 0x32, 0x79, 0x10, 0x40, 0xA3, + 0x06, 0x30, 0x00, 0xE0, 0x11, 0x01, 0x94, 0x10, 0x62, 0x94, 0x63, 0xE4, + 0xFF, 0x30, 0x42, 0x48, 0x88, 0x74, 0xC8, 0x6C, 0x62, 0xB4, 0x62, 0x94, + 0x50, 0x10, 0xC8, 0x68, 0x00, 0xE4, 0x03, 0x20, 0x08, 0x40, 0x0C, 0x6C, + 0x02, 0xB4, 0xA2, 0x94, 0x71, 0x10, 0x4C, 0x69, 0x00, 0x30, 0x00, 0xE0, + 0xFB, 0x00, 0x62, 0x48, 0xCC, 0x74, 0x70, 0x43, 0x4C, 0x6D, 0xA2, 0xB4, + 0xA2, 0x94, 0xA8, 0x45, 0xA8, 0x4D, 0x03, 0x30, 0x00, 0xE0, 0xF0, 0x00, + 0x02, 0x48, 0x18, 0x40, 0x40, 0x6D, 0xA2, 0xB4, 0x10, 0x04, 0x00, 0x00, + 0x00, 0x90, 0x00, 0x40, 0xFF, 0x00, 0xFF, 0xFF, 0x84, 0x00, 0x00, 0x20, + 0x78, 0x00, 0x00, 0x20, 0x34, 0x39, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x40, + 0xFF, 0xFF, 0x00, 0xFF, 0x92, 0x14, 0x00, 0x32, 0x70, 0x11, 0x42, 0xA3, + 0x4C, 0x07, 0x00, 0x00, 0x00, 0x74, 0x05, 0x33, 0x0C, 0x64, 0x05, 0x08, + 0x00, 0x32, 0x6C, 0x11, 0x41, 0xA3, 0x08, 0x04, 0x4A, 0x11, 0x00, 0x33, + 0x01, 0x2B, 0xC3, 0x70, 0x21, 0x82, 0xC4, 0x68, 0x61, 0xA2, 0x3C, 0x78, + 0xD0, 0x14, 0x66, 0x11, 0x66, 0x83, 0xC0, 0x3B, 0x2F, 0x0C, 0x44, 0x11, + 0x80, 0x3B, 0x66, 0xA2, 0x61, 0x82, 0xC0, 0x3B, 0x05, 0x0C, 0x00, 0x30, + 0xFF, 0xE3, 0x1C, 0xF7, 0x1E, 0x04, 0xC1, 0x3B, 0x05, 0x0C, 0x01, 0x30, + 0xFF, 0xE3, 0x16, 0xF7, 0x18, 0x04, 0xC2, 0x3B, 0x05, 0x0C, 0x02, 0x30, + 0xFF, 0xE3, 0x10, 0xF7, 0x12, 0x04, 0xC3, 0x3B, 0x05, 0x0C, 0x03, 0x30, + 0xFF, 0xE3, 0x0A, 0xF7, 0x0C, 0x04, 0xC4, 0x3B, 0x05, 0x0C, 0x04, 0x30, + 0xFF, 0xE3, 0x04, 0xF7, 0x06, 0x04, 0xC5, 0x3B, 0x04, 0x0C, 0x05, 0x30, + 0xFF, 0xE3, 0xFE, 0xF6, 0x08, 0x30, 0x00, 0xE0, 0x1F, 0x03, 0x06, 0x30, + 0x00, 0xE0, 0x92, 0x02, 0x06, 0x04, 0xC1, 0x3B, 0x04, 0x0C, 0x81, 0x3B, + 0x4B, 0x10, 0x66, 0xA2, 0x90, 0x14, 0x00, 0x00, 0x69, 0x10, 0x46, 0x83, + 0x08, 0x6C, 0x06, 0xA3, 0x3C, 0x78, 0x00, 0x00, 0x66, 0x10, 0x61, 0x83, + 0x40, 0x3B, 0x07, 0x08, 0x64, 0x10, 0x66, 0x83, 0x40, 0x3B, 0x00, 0xC4, + 0x00, 0x05, 0x02, 0x04, 0x01, 0x30, 0x3C, 0x78, 0x78, 0x00, 0x00, 0x20, + 0xD1, 0x14, 0x00, 0xE0, 0xF7, 0x06, 0x91, 0x10, 0x00, 0xE4, 0xFF, 0x23, + 0x60, 0x8C, 0x63, 0xE4, 0xFF, 0x33, 0xC0, 0x6C, 0x60, 0xAC, 0x00, 0x30, + 0x00, 0xE0, 0x10, 0x07, 0x60, 0xE4, 0xFF, 0x23, 0x6A, 0x43, 0x00, 0x94, + 0x4A, 0x10, 0x08, 0x68, 0x0C, 0x6C, 0x00, 0xB4, 0x03, 0x30, 0x00, 0xE0, + 0x05, 0x07, 0x60, 0xE4, 0xFF, 0x23, 0x64, 0x43, 0x01, 0x8C, 0x46, 0x10, + 0x08, 0x68, 0x0C, 0x6C, 0x01, 0xAC, 0x00, 0xE0, 0xED, 0x06, 0x91, 0x14, + 0x98, 0x00, 0x00, 0x20, 0xFF, 0x03, 0xF0, 0xFF, 0x0F, 0xC0, 0xFF, 0xFF, + 0xD4, 0x14, 0x92, 0x12, 0xA0, 0x94, 0xB6, 0x45, 0xB6, 0x4D, 0x62, 0x55, + 0xAD, 0x5D, 0xA5, 0xE4, 0xFF, 0x23, 0x60, 0x8C, 0x63, 0xE4, 0xFF, 0x33, + 0xD4, 0x6C, 0x60, 0xAC, 0x00, 0xE0, 0xC0, 0x06, 0x02, 0x48, 0xA0, 0x5D, + 0xA5, 0xE4, 0xFF, 0x23, 0x60, 0x8C, 0x63, 0xE4, 0xFF, 0x33, 0xD4, 0x6C, + 0x60, 0xAC, 0x60, 0x94, 0xAC, 0x43, 0xB6, 0x4D, 0x42, 0x55, 0xA9, 0x5D, + 0xA5, 0xE4, 0xFF, 0x23, 0x4A, 0x45, 0xC3, 0x12, 0xD8, 0x68, 0xC8, 0x6C, + 0x60, 0xB4, 0x00, 0x30, 0x00, 0xE0, 0xCC, 0x06, 0x02, 0x48, 0xA0, 0x5D, + 0xA5, 0xE4, 0xFF, 0x23, 0xAA, 0x45, 0x60, 0x94, 0x8C, 0x69, 0x94, 0x6D, + 0xC0, 0xB4, 0xA2, 0x46, 0xB6, 0x4D, 0x62, 0x55, 0xAD, 0x5D, 0xA5, 0xE4, + 0xFF, 0x23, 0x64, 0x45, 0xD0, 0x4E, 0xF8, 0x11, 0x9C, 0x69, 0x8C, 0x6D, + 0xC1, 0xAC, 0x06, 0x30, 0x00, 0xE0, 0xB4, 0x06, 0x02, 0x48, 0xA0, 0x5D, + 0xA5, 0xE4, 0xFF, 0x23, 0xA4, 0x45, 0x61, 0x8C, 0xCC, 0x69, 0xD4, 0x6D, + 0xE1, 0xAC, 0x00, 0xE0, 0x9B, 0x06, 0x94, 0x14, 0x00, 0x74, 0x40, 0x38, + 0x0C, 0x08, 0x6B, 0x11, 0x60, 0x93, 0x4D, 0x11, 0xC8, 0x68, 0x40, 0x3B, + 0x1B, 0x0C, 0x68, 0x11, 0x00, 0x93, 0x0C, 0x40, 0x16, 0x48, 0x1C, 0x04, + 0x46, 0x38, 0x0D, 0x08, 0x64, 0x11, 0x61, 0x8B, 0x02, 0xEA, 0xF0, 0x3F, + 0xC8, 0x68, 0x40, 0x3B, 0x0F, 0x0C, 0x61, 0x11, 0x00, 0x93, 0x02, 0x40, + 0x16, 0x48, 0x0E, 0x04, 0x43, 0x38, 0x0A, 0x08, 0x7D, 0x10, 0x00, 0x93, + 0x16, 0x40, 0x16, 0x48, 0x07, 0x04, 0x01, 0x30, 0x05, 0x04, 0x01, 0x30, + 0x03, 0x04, 0x00, 0xEA, 0xFF, 0x03, 0x3C, 0x78, 0x77, 0x10, 0x40, 0x93, + 0x6C, 0x42, 0x76, 0x4B, 0x56, 0x42, 0x56, 0x4A, 0xC8, 0x7C, 0x43, 0x43, + 0x06, 0x43, 0x09, 0x58, 0x6D, 0x58, 0x0A, 0x53, 0x3C, 0x78, 0x00, 0x00, + 0xD4, 0x14, 0x21, 0x14, 0xC0, 0x75, 0x00, 0x35, 0x06, 0xEA, 0xFF, 0xFF, + 0xA0, 0xB8, 0x00, 0x34, 0x1F, 0x6C, 0x00, 0xE0, 0x65, 0x06, 0xA0, 0x5D, + 0x80, 0x65, 0x05, 0x0C, 0x60, 0x98, 0x0C, 0x64, 0x04, 0x0C, 0x04, 0x04, + 0x83, 0x6D, 0x02, 0x04, 0x00, 0xB8, 0x00, 0x24, 0x10, 0x75, 0x44, 0x3C, + 0xF0, 0x0B, 0x19, 0x5D, 0x60, 0x98, 0x0D, 0x58, 0x01, 0x48, 0x01, 0x74, + 0x01, 0x14, 0x94, 0x14, 0x98, 0x00, 0x00, 0x20, 0xFF, 0x03, 0xF0, 0xFF, + 0x0F, 0xC0, 0xFF, 0xFF, 0x00, 0xFC, 0x0F, 0x00, 0x68, 0x10, 0x00, 0x32, + 0x40, 0xA3, 0x00, 0x32, 0x44, 0xA3, 0x48, 0x83, 0x80, 0x3A, 0x48, 0xA3, + 0x42, 0x93, 0x42, 0xE4, 0x01, 0x20, 0x42, 0xB3, 0x00, 0x32, 0x46, 0xAB, + 0x3C, 0x78, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x20, 0xD2, 0x14, 0xFF, 0xE3, + 0xD3, 0xF9, 0x41, 0x38, 0x15, 0x08, 0xFF, 0xE3, 0xDF, 0xF9, 0x42, 0x38, + 0x27, 0x08, 0x00, 0x30, 0xFF, 0xE3, 0x84, 0xFF, 0x03, 0xEA, 0x6B, 0x01, + 0x0C, 0x64, 0x06, 0x0C, 0x63, 0x13, 0x46, 0x8B, 0x00, 0x22, 0x46, 0xAB, + 0x1B, 0x04, 0x00, 0x32, 0x60, 0x13, 0x46, 0xAB, 0x2B, 0x04, 0xFF, 0xE3, + 0xBB, 0xF9, 0x40, 0x38, 0x13, 0x08, 0x7E, 0x12, 0x61, 0x93, 0xC0, 0x3B, + 0x0F, 0x0C, 0xFF, 0xE3, 0x6D, 0xFF, 0xF9, 0x33, 0x0C, 0x64, 0x06, 0x0C, + 0x78, 0x12, 0x46, 0x8B, 0x00, 0x22, 0x46, 0xAB, 0x05, 0x04, 0x00, 0x32, + 0x75, 0x12, 0x46, 0xAB, 0x15, 0x04, 0x74, 0x12, 0x46, 0x8B, 0x03, 0xEA, + 0x8F, 0x01, 0x8C, 0x64, 0x0F, 0x08, 0xC8, 0x33, 0x61, 0x43, 0x50, 0x12, + 0x66, 0xAA, 0x71, 0x12, 0x41, 0x93, 0xA6, 0x3A, 0x41, 0xB3, 0x00, 0x30, + 0x00, 0xE0, 0x28, 0x07, 0x20, 0x30, 0x00, 0xE0, 0x7B, 0x01, 0x6B, 0x12, + 0x61, 0x93, 0xC0, 0x3B, 0x28, 0x0C, 0x68, 0x12, 0x64, 0x83, 0xC0, 0x3B, + 0x12, 0x0C, 0x06, 0x30, 0xFF, 0xE3, 0x42, 0xFF, 0xF9, 0x33, 0x0C, 0x64, + 0x0C, 0x0C, 0x65, 0x12, 0x41, 0x93, 0xA6, 0x3A, 0x41, 0xB3, 0x00, 0x30, + 0x00, 0xE0, 0x10, 0x07, 0x20, 0x30, 0x00, 0xE0, 0x63, 0x01, 0x13, 0x04, + 0x5D, 0x11, 0x24, 0x82, 0x78, 0x41, 0x79, 0x4B, 0x00, 0x23, 0x63, 0xE4, + 0x7F, 0x20, 0x01, 0x43, 0x21, 0xE4, 0x01, 0x20, 0x40, 0x6C, 0x24, 0xA2, + 0x45, 0x3B, 0x05, 0x08, 0xCB, 0x6C, 0x44, 0x82, 0xA0, 0x3A, 0x44, 0xA3, + 0x00, 0x30, 0xFF, 0xE3, 0x1F, 0xFF, 0x03, 0x6D, 0x03, 0xEA, 0x8E, 0x03, + 0x0C, 0x64, 0x0C, 0x08, 0x72, 0x11, 0x41, 0x93, 0xA6, 0x3A, 0x41, 0xB3, + 0x01, 0x30, 0x00, 0xE0, 0x41, 0x01, 0x04, 0x30, 0xFF, 0xE3, 0xA8, 0xFC, + 0x1D, 0x04, 0xC7, 0x33, 0x62, 0x43, 0x0C, 0x64, 0x16, 0x08, 0x49, 0x11, + 0x6E, 0x82, 0x00, 0x23, 0xCC, 0x74, 0x6E, 0xA2, 0x32, 0x32, 0xC8, 0x64, + 0x11, 0x08, 0x65, 0x11, 0x4E, 0xA3, 0x66, 0x11, 0x41, 0x93, 0xA6, 0x3A, + 0x41, 0xB3, 0x01, 0x30, 0x00, 0xE0, 0x28, 0x01, 0x04, 0x30, 0xFF, 0xE3, + 0x8F, 0xFC, 0x04, 0x04, 0x00, 0x32, 0x7E, 0x10, 0x4E, 0xA3, 0x00, 0xE0, + 0xF9, 0x00, 0x04, 0x38, 0x0B, 0x08, 0xB6, 0x33, 0x61, 0x43, 0x0C, 0x65, + 0x07, 0x08, 0x00, 0x30, 0x00, 0xE0, 0xCC, 0x05, 0x10, 0x30, 0x00, 0xE0, + 0x13, 0x01, 0x03, 0x30, 0xFF, 0xE3, 0xE2, 0xFE, 0x80, 0x33, 0x63, 0x43, + 0x0C, 0x64, 0x0E, 0x08, 0x74, 0x10, 0x41, 0x93, 0xA6, 0x3A, 0x41, 0xB3, + 0x00, 0x30, 0x00, 0xE0, 0xAF, 0x06, 0x02, 0x30, 0x00, 0xE0, 0x02, 0x01, + 0x05, 0x30, 0xFF, 0xE3, 0x69, 0xFC, 0x6E, 0x10, 0x61, 0x93, 0xC6, 0x3B, + 0x2A, 0x0C, 0x6A, 0x10, 0x60, 0x83, 0xFA, 0x32, 0xC8, 0x64, 0x21, 0x08, + 0x00, 0x30, 0xFF, 0xE3, 0xC5, 0xFE, 0x03, 0xEA, 0x1B, 0x03, 0x0C, 0x64, + 0x21, 0x0C, 0x00, 0xE0, 0x49, 0x04, 0x40, 0x38, 0x1D, 0x08, 0x64, 0x10, + 0x41, 0x93, 0x07, 0x04, 0x9C, 0x00, 0x00, 0x20, 0x00, 0x50, 0x00, 0x40, + 0x00, 0xA0, 0x00, 0x40, 0x86, 0x3A, 0x41, 0xB3, 0x41, 0x93, 0xA8, 0x3A, + 0x41, 0xB3, 0x41, 0x93, 0x88, 0x3A, 0x41, 0xB3, 0x41, 0x93, 0x86, 0x3A, + 0x41, 0xB3, 0x08, 0x04, 0x00, 0x23, 0x44, 0x11, 0x60, 0xA2, 0x04, 0x04, + 0x00, 0x32, 0x62, 0x11, 0x40, 0xA3, 0xFF, 0xE3, 0xEF, 0xF8, 0x42, 0x38, + 0x06, 0x08, 0x7F, 0x10, 0x48, 0x83, 0x80, 0x3A, 0x48, 0xA3, 0x38, 0x04, + 0x7C, 0x10, 0x68, 0x83, 0xC0, 0x3B, 0x19, 0x08, 0x7B, 0x10, 0x61, 0x93, + 0x63, 0xE4, 0x0F, 0x20, 0x25, 0x3B, 0x2E, 0x08, 0x97, 0x10, 0x68, 0x84, + 0x01, 0x35, 0xD4, 0x6C, 0x68, 0xA4, 0x00, 0xE0, 0x69, 0x01, 0x52, 0x58, + 0x41, 0x42, 0x62, 0x94, 0x63, 0xE4, 0x01, 0x20, 0xC8, 0x6C, 0x62, 0xB4, + 0xD4, 0x68, 0xCC, 0x74, 0x40, 0x3B, 0x1C, 0x0C, 0x00, 0xE0, 0x5C, 0x01, + 0x6D, 0x10, 0x62, 0x93, 0x61, 0x4B, 0x0C, 0x64, 0x15, 0x08, 0x00, 0xE0, + 0x0B, 0x06, 0x40, 0x38, 0x11, 0x08, 0x6A, 0x10, 0x61, 0x93, 0x63, 0xE4, + 0x0F, 0x20, 0x01, 0x32, 0xC8, 0x64, 0x06, 0x08, 0x00, 0x2B, 0x0C, 0x74, + 0x00, 0xE0, 0x4A, 0x05, 0x05, 0x04, 0x63, 0x10, 0x48, 0x83, 0x80, 0x3A, + 0x48, 0xA3, 0x92, 0x14, 0x9C, 0x00, 0x00, 0x20, 0x00, 0xA0, 0x00, 0x40, + 0xD0, 0x14, 0x6F, 0x10, 0x00, 0x32, 0x40, 0xAB, 0x41, 0xAB, 0x44, 0xA3, + 0x45, 0xA3, 0x02, 0x32, 0x46, 0xA3, 0x07, 0x23, 0x07, 0x32, 0x40, 0xA3, + 0x41, 0xA3, 0x42, 0xA3, 0xFF, 0xE3, 0xCA, 0xF4, 0xFF, 0xE3, 0x82, 0xF2, + 0xFF, 0xE3, 0xF6, 0xF0, 0xFF, 0xE3, 0x58, 0xF1, 0xFF, 0xE3, 0xEE, 0xF0, + 0xFF, 0xE3, 0x38, 0xF6, 0xFF, 0xE3, 0x9E, 0xF2, 0x90, 0x14, 0x00, 0x00, + 0xAC, 0x00, 0x00, 0x20, 0x7E, 0x11, 0x5E, 0x5B, 0x00, 0x31, 0x21, 0xA2, + 0x22, 0xA2, 0x01, 0x32, 0x46, 0xA3, 0x3C, 0x78, 0xD2, 0x14, 0x7A, 0x11, + 0x01, 0x8B, 0x40, 0x38, 0x05, 0x0C, 0x00, 0x74, 0x00, 0xE0, 0x2A, 0x03, + 0x26, 0x04, 0x76, 0x11, 0x44, 0x83, 0x65, 0x83, 0x8E, 0x64, 0x0D, 0x0C, + 0x73, 0x11, 0x43, 0xC4, 0x21, 0x08, 0xA6, 0x89, 0x20, 0x8B, 0x55, 0x68, + 0x20, 0xAB, 0x00, 0x22, 0x42, 0xE4, 0x07, 0x20, 0x44, 0xA3, 0x02, 0x04, + 0x00, 0x35, 0x8E, 0x11, 0x41, 0x84, 0x6E, 0x11, 0x43, 0xC4, 0x43, 0x08, + 0x60, 0x93, 0x17, 0x6C, 0xCD, 0x7B, 0x61, 0x84, 0x60, 0xA4, 0x42, 0x84, + 0x8E, 0x64, 0x07, 0x0C, 0x40, 0x3D, 0x05, 0x08, 0x65, 0x11, 0x49, 0xA3, + 0x01, 0x32, 0x46, 0xA3, 0x92, 0x14, 0x00, 0x00, 0x62, 0x11, 0x00, 0x32, + 0x46, 0xA3, 0x0A, 0xA3, 0x3C, 0x78, 0x00, 0x00, 0x60, 0x11, 0x00, 0x83, + 0x3C, 0x78, 0x00, 0x00, 0x7E, 0x10, 0x01, 0x83, 0x3C, 0x78, 0x00, 0x00, + 0x7C, 0x10, 0x40, 0x83, 0x61, 0x83, 0xCA, 0x64, 0x00, 0xC4, 0x00, 0x05, + 0x3C, 0x78, 0x00, 0x00, 0xC1, 0x14, 0x01, 0x74, 0x76, 0x10, 0x66, 0x83, + 0x40, 0x3B, 0x14, 0x0C, 0x74, 0x10, 0x60, 0x8B, 0xC2, 0x68, 0x10, 0x08, + 0x32, 0x10, 0x45, 0x81, 0x82, 0x5A, 0x84, 0xE4, 0x07, 0x20, 0x24, 0x81, + 0x52, 0x64, 0x08, 0x0C, 0x2E, 0x10, 0xC0, 0x6C, 0x60, 0xA9, 0x41, 0xC4, + 0x23, 0x08, 0x06, 0xAB, 0x85, 0xA1, 0x81, 0x14, 0x00, 0x74, 0x6A, 0x10, + 0x41, 0x8B, 0x08, 0x6C, 0x01, 0xAB, 0x3C, 0x78, 0x00, 0x74, 0x67, 0x10, + 0x41, 0x8B, 0x02, 0xC4, 0x40, 0x20, 0x01, 0xAB, 0x3C, 0x78, 0x00, 0x00, + 0x63, 0x10, 0x61, 0x8B, 0x40, 0x3B, 0x00, 0xC4, 0x00, 0x05, 0x3C, 0x78, + 0xAC, 0x00, 0x00, 0x20, 0xB4, 0x00, 0x00, 0x20, 0x60, 0x39, 0x00, 0x00, + 0x4A, 0x10, 0x60, 0x92, 0x01, 0x92, 0x0E, 0x64, 0x0E, 0x0C, 0xC0, 0x64, + 0x04, 0x08, 0x01, 0x5B, 0x01, 0x74, 0x0A, 0x04, 0x45, 0x10, 0x28, 0x82, + 0x00, 0x21, 0x28, 0xA2, 0x02, 0x6C, 0x0C, 0x58, 0x01, 0x74, 0x02, 0x04, + 0x00, 0x30, 0x3C, 0x78, 0xC8, 0x00, 0x00, 0x20, 0x68, 0x12, 0x00, 0x32, + 0x00, 0x2A, 0x45, 0xAB, 0x00, 0x32, 0x41, 0xB3, 0x40, 0xB3, 0x48, 0xA3, + 0x3C, 0x78, 0x00, 0x00, 0xD2, 0x14, 0x00, 0x74, 0x49, 0x75, 0x62, 0x12, + 0x00, 0x32, 0x01, 0x2A, 0x83, 0x70, 0x85, 0x8B, 0x90, 0x68, 0x45, 0xAB, + 0x83, 0xE4, 0x0B, 0x00, 0x04, 0xC4, 0x44, 0x08, 0x21, 0xE4, 0x01, 0x20, + 0x60, 0x84, 0x80, 0x3B, 0x4C, 0x6C, 0x20, 0xA4, 0x41, 0x45, 0x60, 0x8C, + 0x63, 0xE4, 0x01, 0x20, 0xC8, 0x6C, 0x60, 0xAC, 0xFF, 0xE3, 0xC6, 0xFF, + 0xB4, 0x58, 0xA1, 0xAC, 0x92, 0x14, 0x00, 0x00, 0x00, 0x74, 0x73, 0x11, + 0x01, 0x32, 0x02, 0xC4, 0x20, 0x40, 0x45, 0x8B, 0x08, 0x6C, 0x05, 0xAB, + 0x3C, 0x78, 0x00, 0x00, 0x00, 0x74, 0x4E, 0x11, 0x00, 0x33, 0x01, 0x2B, + 0xC3, 0x70, 0x25, 0x8A, 0xC4, 0x68, 0x65, 0xAA, 0x3C, 0x78, 0x00, 0x00, + 0x69, 0x11, 0x40, 0x93, 0x00, 0x22, 0x40, 0xB3, 0x3C, 0x78, 0x00, 0x00, + 0xD4, 0x14, 0x23, 0x14, 0xFF, 0xE3, 0xA4, 0xFF, 0x01, 0xB8, 0x64, 0x11, + 0x40, 0x93, 0x41, 0xB3, 0x40, 0x38, 0x31, 0x0C, 0xA2, 0x11, 0xC3, 0x11, + 0x00, 0x34, 0xCF, 0x6D, 0x0B, 0x23, 0x62, 0xB8, 0x65, 0x8F, 0x83, 0xC4, + 0x81, 0x40, 0xC0, 0x39, 0x21, 0x08, 0xA0, 0xB8, 0x20, 0x8D, 0x01, 0x98, + 0x40, 0x64, 0x04, 0x08, 0x21, 0x59, 0x20, 0xAD, 0x19, 0x04, 0x00, 0x31, + 0x20, 0xAD, 0x02, 0x98, 0x80, 0xC4, 0x41, 0x08, 0x20, 0x81, 0xC0, 0x39, + 0x08, 0x0C, 0x80, 0xC4, 0x42, 0x08, 0x60, 0x8A, 0x61, 0x4B, 0x40, 0x98, + 0x60, 0xAA, 0x06, 0x04, 0x01, 0x31, 0x81, 0xC4, 0x22, 0x40, 0xC8, 0x6C, + 0x65, 0xAF, 0x60, 0x96, 0x40, 0x3B, 0x02, 0x0C, 0xCD, 0x7B, 0x00, 0x24, + 0x03, 0x25, 0x03, 0x26, 0x4A, 0x3C, 0xD7, 0x0B, 0x03, 0x14, 0x94, 0x14, + 0x68, 0x10, 0x00, 0x93, 0x3C, 0x78, 0x00, 0x00, 0x66, 0x10, 0x48, 0x83, + 0x16, 0x42, 0x49, 0x58, 0x60, 0x93, 0x6A, 0x4B, 0x0C, 0x5A, 0x3C, 0x78, + 0x62, 0x10, 0x00, 0x93, 0x3C, 0x78, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x20, + 0xD6, 0x00, 0x00, 0x20, 0x7C, 0x39, 0x00, 0x00, 0x6A, 0x10, 0x41, 0x8B, + 0x42, 0xE4, 0x1F, 0x20, 0x41, 0xAB, 0x40, 0x83, 0x00, 0x31, 0x07, 0x29, + 0x84, 0x68, 0x40, 0xA3, 0x40, 0x8B, 0x42, 0xE4, 0xF8, 0x37, 0x40, 0xAB, + 0x40, 0x93, 0x24, 0x10, 0x84, 0x68, 0x40, 0xB3, 0x3C, 0x78, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0x20, 0xFF, 0x07, 0xE0, 0xFF, 0x6D, 0x13, 0x40, 0x83, + 0xA0, 0x3A, 0x40, 0xA3, 0x3C, 0x78, 0x00, 0x00, 0x6A, 0x13, 0x40, 0x83, + 0x80, 0x3A, 0x40, 0xA3, 0x3C, 0x78, 0x00, 0x00, 0x67, 0x13, 0x00, 0x93, + 0x00, 0xE4, 0x01, 0x20, 0x3C, 0x78, 0x00, 0x00, 0xD2, 0x14, 0x00, 0x75, + 0xFF, 0xE3, 0xF8, 0xFF, 0x40, 0x38, 0x0E, 0x0C, 0xFF, 0xE3, 0x3C, 0xEF, + 0x43, 0x6D, 0x53, 0x6C, 0x03, 0x32, 0xFF, 0xE3, 0x85, 0xF7, 0x03, 0x30, + 0x57, 0x6C, 0x00, 0xE0, 0x73, 0x04, 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, + 0x92, 0x14, 0x00, 0x00, 0xD1, 0x14, 0xFF, 0xE3, 0xE3, 0xFF, 0x40, 0x38, + 0x0D, 0x0C, 0xFF, 0xE3, 0x27, 0xEF, 0x03, 0x6D, 0x09, 0x31, 0xFF, 0xE3, + 0x81, 0xF7, 0x09, 0x30, 0x53, 0x6C, 0x00, 0xE0, 0x5F, 0x04, 0x01, 0x30, + 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, 0x00, 0x00, 0xD1, 0x14, 0xFF, 0xE3, + 0xCF, 0xFF, 0x40, 0x38, 0x0D, 0x0C, 0xFF, 0xE3, 0x13, 0xEF, 0x03, 0x6D, + 0x07, 0x31, 0xFF, 0xE3, 0xAB, 0xF7, 0x07, 0x30, 0x53, 0x6C, 0x00, 0xE0, + 0x4B, 0x04, 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, 0x00, 0x00, + 0xD2, 0x14, 0x00, 0x75, 0xFF, 0xE3, 0xBA, 0xFF, 0x40, 0x38, 0x0D, 0x0C, + 0xFF, 0xE3, 0xFE, 0xEE, 0x43, 0x6D, 0x53, 0x6C, 0xFF, 0xE3, 0x08, 0xF8, + 0x03, 0x30, 0x57, 0x6C, 0x00, 0xE0, 0x36, 0x04, 0x01, 0x30, 0x05, 0x04, + 0x08, 0x30, 0xFF, 0xE3, 0xA5, 0xFE, 0x00, 0x30, 0x92, 0x14, 0x00, 0x00, + 0xD2, 0x14, 0x21, 0x14, 0x00, 0x75, 0xFF, 0xE3, 0xA1, 0xFF, 0x40, 0x38, + 0x50, 0x0C, 0xFF, 0xE3, 0xE5, 0xEE, 0x43, 0x6D, 0x40, 0x3C, 0x13, 0x08, + 0x8E, 0xE4, 0x01, 0x00, 0x00, 0x33, 0x60, 0xA4, 0x00, 0x30, 0x53, 0x6C, + 0xFF, 0xE3, 0xB6, 0xF8, 0x20, 0x84, 0x17, 0x6C, 0xFF, 0xE3, 0xD4, 0xF7, + 0x03, 0x30, 0x57, 0x6C, 0x00, 0xE0, 0x12, 0x04, 0x01, 0x30, 0x3D, 0x04, + 0x2E, 0xE4, 0x01, 0x00, 0x00, 0x33, 0x60, 0xA9, 0x13, 0x6C, 0xFF, 0xE3, + 0xA5, 0xF8, 0xFF, 0xE3, 0xBD, 0xF6, 0x40, 0x38, 0x15, 0x08, 0x6E, 0xE4, + 0x01, 0x00, 0x40, 0x8B, 0x03, 0xEA, 0x89, 0x08, 0x8C, 0x64, 0x06, 0x08, + 0x02, 0xEA, 0x89, 0x08, 0x6E, 0xE4, 0x01, 0x00, 0x40, 0xAB, 0x6E, 0xE4, + 0x01, 0x00, 0x40, 0x8B, 0x17, 0x6C, 0x01, 0x31, 0xFF, 0xE3, 0x9C, 0xF7, + 0x14, 0x04, 0xFF, 0xE3, 0xA5, 0xF6, 0x41, 0x38, 0x09, 0x08, 0x6E, 0xE4, + 0x01, 0x00, 0x40, 0x8B, 0x17, 0x6C, 0x02, 0x31, 0xFF, 0xE3, 0x90, 0xF7, + 0x08, 0x04, 0x6E, 0xE4, 0x01, 0x00, 0x40, 0x8B, 0x17, 0x6C, 0x00, 0x31, + 0xFF, 0xE3, 0x88, 0xF7, 0x05, 0x30, 0x57, 0x6C, 0x00, 0xE0, 0xDA, 0x03, + 0x01, 0x30, 0x05, 0x04, 0x10, 0x30, 0xFF, 0xE3, 0x49, 0xFE, 0x00, 0x30, + 0x01, 0x14, 0x92, 0x14, 0xD2, 0x14, 0x00, 0x75, 0xFF, 0xE3, 0x46, 0xFF, + 0x40, 0x38, 0x0E, 0x0C, 0xFF, 0xE3, 0x8A, 0xEE, 0x43, 0x6D, 0x53, 0x6C, + 0x03, 0x32, 0xFF, 0xE3, 0xC3, 0xF6, 0x03, 0x30, 0x57, 0x6C, 0x00, 0xE0, + 0xC1, 0x03, 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x92, 0x14, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0x20, 0xD2, 0x14, 0x40, 0x75, 0xFF, 0xE3, 0x76, 0xEE, + 0x03, 0x6D, 0x00, 0x31, 0x97, 0x6C, 0xFF, 0xE3, 0x49, 0xF7, 0x04, 0x30, + 0x53, 0x6C, 0x00, 0xE0, 0xAD, 0x03, 0x92, 0x14, 0xD2, 0x14, 0x40, 0x75, + 0xFF, 0xE3, 0x68, 0xEE, 0x03, 0x6D, 0x02, 0x31, 0x97, 0x6C, 0xFF, 0xE3, + 0x19, 0xF7, 0x04, 0x30, 0x53, 0x6C, 0x00, 0xE0, 0x9F, 0x03, 0x92, 0x14, + 0xD1, 0x14, 0xFF, 0xE3, 0x5B, 0xEE, 0x03, 0x6D, 0x30, 0x31, 0xFF, 0xE3, + 0x1F, 0xF7, 0x03, 0x30, 0x53, 0x6C, 0x00, 0xE0, 0x93, 0x03, 0x91, 0x14, + 0xD1, 0x14, 0xFF, 0xE3, 0x4F, 0xEE, 0x03, 0x6D, 0x31, 0x31, 0xFF, 0xE3, + 0x13, 0xF7, 0x03, 0x30, 0x53, 0x6C, 0x00, 0xE0, 0x87, 0x03, 0x91, 0x14, + 0xD2, 0x14, 0x40, 0x75, 0xFF, 0xE3, 0x42, 0xEE, 0x03, 0x6D, 0x45, 0xE4, + 0x3F, 0x20, 0x01, 0x31, 0xFF, 0xE3, 0xF2, 0xF6, 0x04, 0x30, 0x53, 0x6C, + 0x00, 0xE0, 0x78, 0x03, 0x92, 0x14, 0x00, 0x00, 0xD2, 0x14, 0x40, 0x75, + 0xFF, 0xE3, 0x32, 0xEE, 0x03, 0x6D, 0x45, 0xE4, 0x3F, 0x20, 0x04, 0x31, + 0xFF, 0xE3, 0xE2, 0xF6, 0x04, 0x30, 0x53, 0x6C, 0x00, 0xE0, 0x68, 0x03, + 0x92, 0x14, 0x00, 0x00, 0xD2, 0x14, 0x40, 0x75, 0xFF, 0xE3, 0x22, 0xEE, + 0x03, 0x6D, 0x00, 0x31, 0x97, 0x6C, 0xFF, 0xE3, 0xD3, 0xF6, 0x04, 0x30, + 0x53, 0x6C, 0x00, 0xE0, 0x59, 0x03, 0x92, 0x14, 0xD1, 0x14, 0xFF, 0xE3, + 0xCD, 0xFE, 0x40, 0x38, 0x0C, 0x0C, 0xFF, 0xE3, 0x11, 0xEE, 0x03, 0x6D, + 0xFF, 0xE3, 0x2C, 0xF7, 0x05, 0x30, 0x53, 0x6C, 0x00, 0xE0, 0x4A, 0x03, + 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, 0xD1, 0x14, 0xFF, 0xE3, + 0xBB, 0xFE, 0x40, 0x38, 0x0C, 0x0C, 0xFF, 0xE3, 0xFF, 0xED, 0x03, 0x6D, + 0xFF, 0xE3, 0x2A, 0xF7, 0x0E, 0x30, 0x53, 0x6C, 0x00, 0xE0, 0x38, 0x03, + 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, 0xD1, 0x14, 0xFF, 0xE3, + 0xA9, 0xFE, 0x40, 0x38, 0x0C, 0x0C, 0xFF, 0xE3, 0xED, 0xED, 0x03, 0x6D, + 0xFF, 0xE3, 0x42, 0xF7, 0x03, 0x30, 0x53, 0x6C, 0x00, 0xE0, 0x26, 0x03, + 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, 0xD1, 0x14, 0xFF, 0xE3, + 0x97, 0xFE, 0x40, 0x38, 0x0C, 0x0C, 0xFF, 0xE3, 0xDB, 0xED, 0x03, 0x6D, + 0xFF, 0xE3, 0x3C, 0xF7, 0x05, 0x30, 0x53, 0x6C, 0x00, 0xE0, 0x14, 0x03, + 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, 0xD1, 0x14, 0xFF, 0xE3, + 0x85, 0xFE, 0x40, 0x38, 0x0D, 0x0C, 0xFF, 0xE3, 0xC9, 0xED, 0x03, 0x6D, + 0xFF, 0xE3, 0x3A, 0xF7, 0x01, 0x20, 0x00, 0x74, 0x53, 0x6C, 0x00, 0xE0, + 0x01, 0x03, 0x01, 0x30, 0x02, 0x04, 0x00, 0x30, 0x91, 0x14, 0x00, 0x00, + 0xD1, 0x14, 0x00, 0x30, 0xFF, 0xE3, 0x58, 0xFB, 0x03, 0xEA, 0x7B, 0x03, + 0x0C, 0x64, 0x48, 0x0C, 0x63, 0x13, 0x60, 0x93, 0x75, 0x43, 0x78, 0x4B, + 0x09, 0x3B, 0x3A, 0x08, 0x60, 0x13, 0x60, 0x93, 0x6B, 0x43, 0x76, 0x4B, + 0xC1, 0x64, 0x05, 0x08, 0x03, 0xEA, 0xAA, 0x02, 0x0C, 0x64, 0x1E, 0x0C, + 0x9B, 0x12, 0x60, 0x8C, 0x63, 0xE4, 0xF8, 0x37, 0x60, 0xAC, 0x7A, 0x12, + 0x41, 0x93, 0xA9, 0x3A, 0x41, 0xB3, 0x41, 0x93, 0x87, 0x3A, 0x41, 0xB3, + 0x41, 0x93, 0x86, 0x3A, 0x41, 0xB3, 0x40, 0x93, 0x42, 0xEC, 0x0C, 0x00, + 0x40, 0xB3, 0x05, 0x30, 0xFF, 0xE3, 0xB6, 0xFD, 0x01, 0x30, 0xFF, 0xE3, + 0x5F, 0xFD, 0x60, 0x84, 0xA1, 0x3B, 0x60, 0xA4, 0x22, 0x04, 0xA0, 0x30, + 0xFF, 0xE3, 0x80, 0xFE, 0x40, 0x38, 0x1D, 0x0C, 0x6A, 0x12, 0x20, 0x93, + 0x35, 0x41, 0x38, 0x49, 0x00, 0x21, 0x44, 0x74, 0x23, 0x41, 0x40, 0x8B, + 0x42, 0xE4, 0xF8, 0x37, 0x84, 0x6C, 0x40, 0xAB, 0x10, 0x04, 0x64, 0x12, + 0x40, 0x83, 0xA2, 0x3A, 0x40, 0xA3, 0x05, 0x30, 0xFF, 0xE3, 0x96, 0xFD, + 0x08, 0x04, 0x60, 0x12, 0x40, 0x83, 0xA2, 0x3A, 0x40, 0xA3, 0x05, 0x30, + 0xFF, 0xE3, 0x8E, 0xFD, 0x91, 0x14, 0x00, 0x00, 0xD4, 0x14, 0x21, 0x14, + 0x00, 0x75, 0xFF, 0xE3, 0x07, 0xFD, 0x04, 0x28, 0x00, 0x74, 0x00, 0xB8, + 0x01, 0x38, 0x04, 0x08, 0x07, 0x30, 0xFF, 0xE3, 0x7F, 0xFD, 0x00, 0xE0, + 0x9F, 0x05, 0x74, 0x11, 0x40, 0x83, 0x81, 0x3A, 0xA2, 0x3A, 0x40, 0xA3, + 0xC4, 0x3C, 0x2C, 0x08, 0xC1, 0x3C, 0x2C, 0x08, 0xC2, 0x3C, 0x2C, 0x08, + 0xC3, 0x3C, 0x2C, 0x08, 0xC0, 0x3C, 0x2C, 0x0C, 0x06, 0x30, 0xFF, 0xE3, + 0xE3, 0xFA, 0x31, 0x33, 0x0C, 0x64, 0x06, 0x0C, 0x00, 0x30, 0x00, 0xE0, + 0xB5, 0x02, 0x04, 0x37, 0x22, 0x04, 0x87, 0x11, 0x60, 0x84, 0x82, 0x3B, + 0x60, 0xA4, 0x00, 0x30, 0xFF, 0xE3, 0xD4, 0xFA, 0x60, 0xE4, 0xE3, 0x10, + 0x63, 0xE4, 0xFF, 0x23, 0x6B, 0x43, 0x40, 0x94, 0x22, 0x11, 0x84, 0x68, + 0xC8, 0x6C, 0x60, 0xB4, 0x05, 0x30, 0x01, 0x31, 0x1E, 0x32, 0xFF, 0xE3, + 0x2D, 0xFD, 0x04, 0x37, 0x0A, 0x04, 0x0B, 0x37, 0x08, 0x04, 0x05, 0x37, + 0x06, 0x04, 0x03, 0x37, 0x04, 0x04, 0x0A, 0x37, 0x02, 0x04, 0x00, 0x37, + 0x03, 0x30, 0x00, 0x31, 0x07, 0x32, 0xFF, 0xE3, 0x1D, 0xFD, 0x94, 0x10, + 0x04, 0x35, 0x02, 0x36, 0xFF, 0xE3, 0x52, 0xFD, 0x60, 0x84, 0x4E, 0x69, + 0x04, 0x0C, 0x1F, 0x6C, 0xFF, 0xE3, 0x7A, 0xFE, 0x60, 0x84, 0x8E, 0x69, + 0xF6, 0x0F, 0x6D, 0x10, 0x40, 0x83, 0x81, 0x3A, 0x40, 0xA3, 0x8C, 0x10, + 0x62, 0x94, 0x70, 0x4B, 0x70, 0x43, 0x62, 0xB4, 0x63, 0x94, 0x70, 0x4B, + 0x70, 0x43, 0x63, 0xB4, 0x0A, 0x30, 0x00, 0xE0, 0xC5, 0x06, 0x0B, 0x30, + 0x00, 0xE0, 0xC2, 0x06, 0x60, 0x94, 0x98, 0x3B, 0x60, 0xB4, 0x60, 0x94, + 0x08, 0x04, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x20, 0x00, 0xA0, 0x00, 0x40, + 0xFF, 0x07, 0xE0, 0xFF, 0x98, 0x3B, 0x60, 0xB4, 0x03, 0x30, 0x00, 0x31, + 0x06, 0x32, 0xFF, 0xE3, 0xE9, 0xFC, 0x60, 0x98, 0x01, 0x3B, 0x04, 0x08, + 0x07, 0x30, 0xFF, 0xE3, 0x0D, 0xFD, 0x01, 0x14, 0x94, 0x14, 0x00, 0x00, + 0x63, 0x10, 0x00, 0x93, 0x02, 0x48, 0x00, 0xE4, 0x01, 0x20, 0x3C, 0x78, + 0xFC, 0x00, 0x00, 0x20, 0xD4, 0x14, 0x36, 0x16, 0x7C, 0x12, 0x00, 0x93, + 0x00, 0xB8, 0x81, 0x93, 0xA2, 0x93, 0xC3, 0x93, 0x64, 0x93, 0x62, 0xB8, + 0x04, 0x1F, 0xA4, 0x32, 0x41, 0x42, 0x1F, 0x6C, 0x00, 0x31, 0x00, 0xE0, + 0x07, 0x08, 0x40, 0x31, 0x2F, 0xB7, 0x75, 0x12, 0x55, 0x12, 0x40, 0xB3, + 0x20, 0x33, 0x61, 0xB8, 0xF4, 0x12, 0xA3, 0xB8, 0x53, 0x6D, 0x20, 0x34, + 0x00, 0x30, 0x00, 0xE0, 0xF7, 0x00, 0x00, 0xE4, 0x01, 0x20, 0x00, 0x74, + 0x60, 0x97, 0x60, 0xC4, 0x20, 0x08, 0x00, 0xB7, 0x01, 0x30, 0x00, 0xE0, + 0xED, 0x00, 0x00, 0xE4, 0x01, 0x20, 0x00, 0x74, 0x61, 0x97, 0x60, 0xC4, + 0x20, 0x08, 0x01, 0xB7, 0x00, 0x2C, 0x10, 0x75, 0x40, 0x3C, 0xE9, 0x0B, + 0x17, 0x6D, 0xA3, 0x98, 0x63, 0x12, 0x00, 0x37, 0xE0, 0xB3, 0x44, 0x12, + 0x20, 0x92, 0x04, 0x1B, 0x20, 0xB3, 0x41, 0x92, 0x41, 0xB3, 0x80, 0x30, + 0x18, 0x40, 0x02, 0xB3, 0x23, 0xDC, 0x50, 0x20, 0x43, 0xDC, 0x51, 0x20, + 0x8F, 0x6C, 0xE3, 0xE4, 0xFF, 0x00, 0x08, 0x93, 0x2D, 0x93, 0x05, 0x6C, + 0x22, 0x93, 0x05, 0x6C, 0x20, 0x93, 0x41, 0x6C, 0x21, 0xC4, 0x01, 0x49, + 0x30, 0xB3, 0x03, 0x23, 0xCE, 0x65, 0xF4, 0x0B, 0x00, 0x33, 0x00, 0x98, + 0x13, 0x3B, 0x0A, 0x08, 0x86, 0xC4, 0x47, 0x20, 0x85, 0xC4, 0x21, 0x20, + 0x5C, 0x6C, 0x20, 0xB8, 0x31, 0x11, 0x21, 0xB8, 0x25, 0x04, 0x27, 0x37, + 0xDC, 0x64, 0x08, 0x0C, 0x85, 0xC4, 0x41, 0x24, 0x59, 0x6C, 0x20, 0xB8, + 0x2D, 0x11, 0x21, 0xB8, 0x1B, 0x04, 0x3B, 0x37, 0xDC, 0x64, 0x0B, 0x0C, + 0xA6, 0xC4, 0x27, 0x24, 0xD0, 0x69, 0xA6, 0xC4, 0x21, 0x20, 0x5C, 0x6C, + 0x20, 0xB8, 0x28, 0x11, 0x21, 0xB8, 0x0E, 0x04, 0x4F, 0x31, 0xC4, 0x64, + 0x08, 0x0C, 0x85, 0xC4, 0x41, 0x24, 0x59, 0x6C, 0x20, 0xB8, 0xE4, 0x11, + 0xE1, 0xB8, 0x04, 0x04, 0x00, 0x31, 0x21, 0xB8, 0x20, 0xB8, 0xE0, 0x92, + 0x22, 0x98, 0xE4, 0x5F, 0xA0, 0xC4, 0x01, 0x49, 0x24, 0x5F, 0xE0, 0x98, + 0x3C, 0x59, 0xE1, 0x98, 0x3C, 0x59, 0x00, 0x23, 0xCC, 0x74, 0x03, 0x22, + 0x50, 0x37, 0xCE, 0x65, 0x09, 0x0C, 0xC4, 0xC7, 0x07, 0x49, 0x03, 0x6D, + 0xC2, 0xB8, 0x97, 0x6D, 0x5F, 0x6D, 0x07, 0x6C, 0xBA, 0x07, 0x00, 0xB8, + 0x6D, 0x10, 0x40, 0x93, 0x28, 0x59, 0x20, 0xB3, 0x41, 0x93, 0x40, 0x5A, + 0x41, 0xB3, 0x42, 0x93, 0x40, 0x5A, 0x42, 0xB3, 0x43, 0x93, 0xA8, 0x5D, + 0xA3, 0xB3, 0x44, 0x93, 0xC8, 0x5E, 0xC4, 0xB3, 0x68, 0x10, 0x04, 0x1A, + 0x02, 0xD8, 0x50, 0x20, 0x00, 0xB3, 0x42, 0xD8, 0x51, 0x20, 0x41, 0xB3, + 0x16, 0x16, 0x94, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0xA0, 0x00, 0x40, + 0x80, 0xFE, 0xFE, 0x00, 0x00, 0x01, 0x00, 0x20, 0x99, 0x79, 0x82, 0x5A, + 0xA1, 0xEB, 0xD9, 0x6E, 0xDC, 0xBC, 0x1B, 0x8F, 0xD6, 0xC1, 0x62, 0xCA, + 0x70, 0x10, 0x40, 0x93, 0x40, 0xB0, 0x41, 0x93, 0x41, 0xB0, 0x42, 0x93, + 0x42, 0xB0, 0x43, 0x93, 0x43, 0xB0, 0x64, 0x93, 0x64, 0xB0, 0x3C, 0x78, + 0x6B, 0x10, 0x40, 0x93, 0x40, 0xB0, 0x61, 0x93, 0x60, 0xB1, 0x3C, 0x78, + 0x3C, 0x78, 0x00, 0x00, 0xD0, 0x14, 0xFF, 0xE3, 0x97, 0xFB, 0x67, 0x10, + 0x03, 0xC4, 0x40, 0x08, 0x60, 0x90, 0x40, 0x3B, 0x02, 0x0C, 0xCD, 0x7B, + 0x90, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x20, + 0xA4, 0x39, 0x00, 0x00, 0xC1, 0x14, 0x00, 0x33, 0x09, 0x10, 0x01, 0x31, + 0x04, 0xEA, 0x10, 0x27, 0x05, 0x04, 0x00, 0x23, 0xCD, 0x74, 0x0E, 0x65, + 0x04, 0x0C, 0x40, 0x90, 0x4A, 0x68, 0xFA, 0x0F, 0x63, 0x10, 0x04, 0x93, + 0x00, 0xE4, 0xFF, 0x23, 0x81, 0x14, 0x00, 0x00, 0x00, 0x80, 0x00, 0x40, + 0x74, 0x10, 0x02, 0xEA, 0xCC, 0x07, 0x40, 0xB3, 0x3C, 0x78, 0x00, 0x00, + 0xD0, 0x14, 0x71, 0x10, 0x00, 0x32, 0x40, 0xB3, 0xFF, 0xE3, 0xF6, 0xFF, + 0x90, 0x14, 0x00, 0x00, 0x00, 0x74, 0x6D, 0x10, 0x00, 0x32, 0x40, 0xB3, + 0x03, 0x6C, 0x42, 0x40, 0x42, 0xEC, 0x80, 0x07, 0x40, 0xB3, 0x03, 0x6C, + 0x4F, 0x6C, 0x01, 0x32, 0x60, 0x91, 0x8E, 0x68, 0xFE, 0x0F, 0x66, 0x10, + 0x40, 0x93, 0x89, 0x3A, 0x40, 0xB3, 0x65, 0x10, 0x0C, 0x58, 0x02, 0x40, + 0x00, 0x90, 0x00, 0xE4, 0xFF, 0x23, 0x3C, 0x78, 0x00, 0x80, 0x00, 0x40, + 0x01, 0x20, 0x00, 0x10, 0x00, 0x74, 0x67, 0x10, 0x60, 0x93, 0x82, 0x74, + 0xDF, 0x3A, 0x02, 0x0C, 0x7F, 0x30, 0x45, 0x10, 0xC8, 0x68, 0x09, 0x40, + 0x0C, 0x6C, 0x62, 0x10, 0x00, 0xB3, 0x3C, 0x78, 0x00, 0xA0, 0x00, 0x40, + 0xFF, 0x01, 0xFF, 0xFF, 0x00, 0x74, 0x7B, 0x11, 0x60, 0x93, 0x82, 0x74, + 0xDF, 0x3A, 0x02, 0x0C, 0x7F, 0x30, 0x59, 0x11, 0xC8, 0x68, 0x11, 0x40, + 0x0C, 0x6C, 0x76, 0x11, 0x00, 0xB3, 0x3C, 0x78, 0x74, 0x11, 0x41, 0x93, + 0x42, 0xE4, 0x0F, 0x30, 0x00, 0xE4, 0x0F, 0x20, 0x80, 0x6C, 0x41, 0xB3, + 0x3C, 0x78, 0x00, 0x00, 0xD0, 0x14, 0x7D, 0x30, 0xFF, 0xE3, 0xD4, 0xFF, + 0x7F, 0x30, 0xFF, 0xE3, 0xE3, 0xFF, 0x6C, 0x11, 0x40, 0x93, 0xA7, 0x3A, + 0x40, 0xB3, 0x40, 0x93, 0xBC, 0x3A, 0x40, 0xB3, 0x40, 0x93, 0x90, 0x3A, + 0x40, 0xB3, 0x40, 0x93, 0xBB, 0x3A, 0x40, 0xB3, 0x40, 0x93, 0x98, 0x3A, + 0x40, 0xB3, 0x40, 0x93, 0xBD, 0x3A, 0x40, 0xB3, 0x40, 0x93, 0x98, 0x3A, + 0x40, 0xB3, 0x41, 0x93, 0x8B, 0x3A, 0x41, 0xB3, 0x41, 0x93, 0xAA, 0x3A, + 0x41, 0xB3, 0x40, 0x93, 0xA4, 0x3A, 0x40, 0xB3, 0x41, 0x93, 0xA9, 0x3A, + 0x41, 0xB3, 0x40, 0x93, 0x81, 0x3A, 0x40, 0xB3, 0x08, 0x30, 0xFF, 0xE3, + 0xC9, 0xFF, 0x90, 0x14, 0x77, 0x10, 0x61, 0x93, 0x63, 0xE4, 0x01, 0x20, + 0x40, 0x3B, 0x00, 0xC4, 0x00, 0x05, 0x03, 0x40, 0x73, 0x10, 0x61, 0x93, + 0xC1, 0x3B, 0x03, 0x0C, 0x08, 0x20, 0x00, 0x74, 0x70, 0x10, 0x61, 0x93, + 0xC2, 0x3B, 0x03, 0x0C, 0x10, 0x20, 0x00, 0x74, 0x6D, 0x10, 0x61, 0x93, + 0xC3, 0x3B, 0x03, 0x0C, 0x21, 0x20, 0x00, 0x74, 0x3C, 0x78, 0x00, 0x00, + 0x32, 0x32, 0x69, 0x10, 0x01, 0x30, 0x20, 0x93, 0x40, 0x6C, 0x20, 0xB3, + 0x03, 0x6C, 0x03, 0x6C, 0x20, 0x93, 0x80, 0x39, 0x20, 0xB3, 0x03, 0x6C, + 0x00, 0x2A, 0x88, 0x74, 0x40, 0x3A, 0xF4, 0x0B, 0x3C, 0x78, 0x00, 0x00, + 0x00, 0xA0, 0x00, 0x40, 0xFF, 0xFF, 0x01, 0xFF, 0x60, 0x14, 0x62, 0x14, + 0xD0, 0x14, 0x7D, 0x10, 0x60, 0x83, 0xCC, 0x74, 0x40, 0x3B, 0x13, 0x0C, + 0x5B, 0x10, 0x60, 0x92, 0x8B, 0x3B, 0x60, 0xB2, 0x78, 0x10, 0x21, 0x93, + 0x00, 0x81, 0x01, 0xB2, 0x00, 0xEA, 0xC1, 0x01, 0x00, 0xB2, 0x00, 0x21, + 0x21, 0xB3, 0x40, 0x83, 0x00, 0x2A, 0x88, 0x74, 0x40, 0xA3, 0x1D, 0x04, + 0x72, 0x10, 0x00, 0x32, 0x40, 0xB3, 0x70, 0x10, 0x48, 0xA3, 0xFF, 0xE3, + 0xFB, 0xEA, 0xFF, 0xE3, 0xCB, 0xFA, 0x40, 0x38, 0x04, 0x08, 0x01, 0x30, + 0xFF, 0xE3, 0x9E, 0xFA, 0x6A, 0x10, 0x09, 0x83, 0x40, 0x38, 0x06, 0x0C, + 0xFF, 0xE3, 0x68, 0xFF, 0x00, 0x32, 0x67, 0x10, 0x49, 0xA3, 0x03, 0x30, + 0x00, 0x31, 0x07, 0x32, 0xFF, 0xE3, 0xE4, 0xFA, 0xEE, 0xD9, 0x00, 0x20, + 0x01, 0x14, 0x63, 0x14, 0x61, 0x14, 0x00, 0x00, 0x08, 0x01, 0x00, 0x20, + 0x00, 0x60, 0x00, 0x40, 0x00, 0x32, 0x78, 0x10, 0x40, 0xB3, 0x78, 0x10, + 0x48, 0xA3, 0x41, 0xB3, 0x40, 0xA3, 0x3C, 0x78, 0x75, 0x10, 0x68, 0x83, + 0xCC, 0x74, 0x40, 0x3B, 0x00, 0xC4, 0x00, 0x05, 0x3C, 0x78, 0x00, 0x00, + 0xD0, 0x14, 0x00, 0x74, 0x70, 0x10, 0x21, 0xB3, 0x00, 0xA3, 0x01, 0x32, + 0x48, 0xA3, 0xFF, 0xE3, 0x99, 0xF2, 0x41, 0x38, 0x0B, 0x08, 0x6D, 0x10, + 0x41, 0x93, 0x42, 0xE4, 0x0F, 0x20, 0x6A, 0x10, 0x49, 0xA3, 0x0F, 0x30, + 0xFF, 0xE3, 0x32, 0xFF, 0x04, 0x04, 0x00, 0x32, 0x66, 0x10, 0x49, 0xA3, + 0xFF, 0xE3, 0x5A, 0xFB, 0x63, 0x10, 0x02, 0xEA, 0xC1, 0x09, 0x40, 0xB3, + 0x90, 0x14, 0x00, 0x00, 0x00, 0x60, 0x00, 0x40, 0x08, 0x01, 0x00, 0x20, + 0x00, 0xA0, 0x00, 0x40, 0x64, 0x10, 0x41, 0x93, 0x01, 0x31, 0x01, 0xC4, + 0x20, 0x40, 0x08, 0x6C, 0x01, 0xB3, 0x3C, 0x78, 0x00, 0x50, 0x00, 0x40, + 0x7E, 0x11, 0x61, 0x93, 0x03, 0xC4, 0x40, 0x40, 0x00, 0xE4, 0x01, 0x20, + 0x3C, 0x78, 0x00, 0x00, 0x5A, 0x11, 0x21, 0x92, 0x00, 0x33, 0x01, 0x2B, + 0xC3, 0x70, 0xC4, 0x68, 0x61, 0xB2, 0x3C, 0x78, 0xD0, 0x14, 0x76, 0x11, + 0x61, 0x93, 0x01, 0x32, 0x80, 0x70, 0xCA, 0x68, 0x04, 0x0C, 0xFF, 0xE3, + 0xF1, 0xFF, 0x03, 0x04, 0xFF, 0xE3, 0xDC, 0xFF, 0x90, 0x14, 0x00, 0x00, + 0x6F, 0x11, 0x43, 0x93, 0x01, 0x31, 0x01, 0xC4, 0x20, 0x40, 0x80, 0x6C, + 0x43, 0xB3, 0x45, 0x93, 0x08, 0x6C, 0x05, 0xB3, 0x3C, 0x78, 0x00, 0x00, + 0x69, 0x11, 0x43, 0x93, 0x01, 0x31, 0x01, 0xC4, 0x20, 0x40, 0x80, 0x6C, + 0x43, 0xB3, 0x45, 0x93, 0x80, 0x6C, 0x45, 0xB3, 0x47, 0x93, 0x08, 0x6C, + 0x07, 0xB3, 0x3C, 0x78, 0x62, 0x11, 0x20, 0x93, 0x00, 0x32, 0x01, 0x2A, + 0x80, 0x70, 0x48, 0x68, 0x20, 0xB3, 0x23, 0x93, 0x84, 0x68, 0x43, 0xB3, + 0x3C, 0x78, 0x00, 0x00, 0x7C, 0x10, 0x42, 0x93, 0x01, 0x31, 0x01, 0xC4, + 0x20, 0x40, 0x08, 0x6C, 0x02, 0xB3, 0x3C, 0x78, 0xD0, 0x14, 0x03, 0x30, + 0xFF, 0xE3, 0xF6, 0xFF, 0x00, 0x30, 0xFF, 0xE3, 0xF3, 0xFF, 0x02, 0x30, + 0xFF, 0xE3, 0xF0, 0xFF, 0x03, 0x30, 0xFF, 0xE3, 0xE1, 0xFF, 0x00, 0x30, + 0xFF, 0xE3, 0xDE, 0xFF, 0x02, 0x30, 0xFF, 0xE3, 0xDB, 0xFF, 0x01, 0x30, + 0xFF, 0xE3, 0xE4, 0xFF, 0x01, 0x30, 0xFF, 0xE3, 0xD5, 0xFF, 0x00, 0x30, + 0xFF, 0xE3, 0xA2, 0xFF, 0x01, 0x30, 0xFF, 0xE3, 0x8D, 0xFF, 0x00, 0x30, + 0xFF, 0xE3, 0x9C, 0xFF, 0x02, 0x30, 0xFF, 0xE3, 0x99, 0xFF, 0x90, 0x14, + 0x65, 0x10, 0x60, 0x93, 0x45, 0x10, 0x00, 0x5A, 0x40, 0x80, 0xC8, 0x68, + 0x40, 0x3B, 0x00, 0xC4, 0x00, 0x05, 0x3C, 0x78, 0x00, 0x50, 0x00, 0x40, + 0xC0, 0x39, 0x00, 0x00, 0x60, 0x14, 0x62, 0x14, 0x65, 0x10, 0x40, 0x93, + 0xA3, 0x3A, 0x40, 0xB3, 0x64, 0x10, 0x00, 0x32, 0x40, 0xB3, 0x63, 0x14, + 0x61, 0x14, 0x00, 0x00, 0x00, 0x70, 0x00, 0x40, 0x00, 0x10, 0x00, 0x40, + 0x60, 0x14, 0x62, 0x14, 0xD1, 0x14, 0x63, 0x13, 0x63, 0x83, 0x63, 0xE4, + 0x3F, 0x30, 0xCC, 0x74, 0x80, 0x32, 0x8E, 0x64, 0x78, 0x09, 0x60, 0x13, + 0x41, 0x93, 0x7E, 0x12, 0x62, 0x8B, 0xCD, 0x74, 0x89, 0x74, 0x8C, 0x64, + 0x08, 0x08, 0x7C, 0x12, 0x41, 0x93, 0x7A, 0x12, 0x62, 0x8B, 0x4D, 0x5A, + 0x88, 0x74, 0x07, 0x04, 0x77, 0x12, 0x42, 0x8B, 0x77, 0x12, 0x61, 0x93, + 0x4D, 0x5A, 0x88, 0x74, 0x04, 0x33, 0x8C, 0x64, 0x06, 0x08, 0x73, 0x12, + 0x40, 0x83, 0xA0, 0x3A, 0x40, 0xA3, 0x05, 0x04, 0x70, 0x12, 0x40, 0x83, + 0x80, 0x3A, 0x40, 0xA3, 0x6E, 0x12, 0x60, 0x83, 0x41, 0x4B, 0x63, 0xE4, + 0x01, 0x20, 0x42, 0xE4, 0x01, 0x20, 0x8E, 0x64, 0x20, 0x08, 0x2A, 0x12, + 0x60, 0x81, 0x43, 0x4B, 0x00, 0x22, 0x42, 0xE4, 0x0F, 0x20, 0x03, 0x42, + 0x63, 0xE4, 0x78, 0x30, 0xC0, 0x6C, 0x60, 0xA1, 0x2C, 0x3A, 0x41, 0x08, + 0x60, 0x81, 0x63, 0xE4, 0x04, 0x20, 0xCC, 0x74, 0x40, 0x3B, 0x07, 0x08, + 0x40, 0x81, 0x42, 0xE4, 0x78, 0x30, 0xA6, 0x3A, 0x40, 0xA1, 0x07, 0x04, + 0x7D, 0x11, 0x40, 0x83, 0x42, 0xE4, 0x78, 0x30, 0xA5, 0x3A, 0x40, 0xA3, + 0x7A, 0x11, 0x60, 0x83, 0x63, 0xE4, 0x04, 0x20, 0xCC, 0x74, 0x40, 0x3B, + 0x13, 0x08, 0x77, 0x11, 0x60, 0x83, 0x63, 0x4B, 0x63, 0xE4, 0x0F, 0x20, + 0x25, 0x3B, 0x06, 0x0C, 0x73, 0x11, 0x40, 0x83, 0xA2, 0x3A, 0x40, 0xA3, + 0x17, 0x04, 0x71, 0x11, 0x42, 0x83, 0x80, 0x3A, 0x81, 0x3A, 0x42, 0xA3, + 0x11, 0x04, 0x6E, 0x11, 0x60, 0x83, 0x63, 0x4B, 0x63, 0xE4, 0x0F, 0x20, + 0x25, 0x3B, 0x0A, 0x0C, 0x6A, 0x11, 0x42, 0x83, 0x80, 0x3A, 0x81, 0x3A, + 0xA0, 0x3A, 0x42, 0xA3, 0x40, 0x83, 0x82, 0x3A, 0x40, 0xA3, 0x66, 0x11, + 0x40, 0x83, 0x42, 0xE4, 0x78, 0x30, 0x40, 0xA3, 0x63, 0x11, 0x40, 0x83, + 0x22, 0xE4, 0x01, 0x20, 0x21, 0x41, 0x81, 0x3A, 0x84, 0x6C, 0x40, 0xA3, + 0x62, 0x83, 0x63, 0xE4, 0x03, 0x20, 0x21, 0x3B, 0x2D, 0x0D, 0x5D, 0x10, + 0x42, 0x82, 0x22, 0xE4, 0x04, 0x20, 0x44, 0x74, 0x40, 0x39, 0x43, 0x08, + 0x79, 0x10, 0x26, 0x83, 0x21, 0x49, 0x26, 0xA3, 0x42, 0xE4, 0x03, 0x20, + 0x41, 0x3A, 0x05, 0x08, 0x00, 0x30, 0x7F, 0x28, 0x40, 0x6C, 0x26, 0xA3, + 0x33, 0x10, 0x62, 0x81, 0x43, 0x4B, 0x00, 0x22, 0x42, 0xE4, 0x0F, 0x20, + 0x03, 0x42, 0x63, 0xE4, 0x78, 0x30, 0xC0, 0x6C, 0x62, 0xA1, 0x48, 0x3A, + 0xC5, 0x08, 0x6E, 0x10, 0x40, 0x93, 0x83, 0x3A, 0x40, 0xB3, 0x66, 0x81, + 0x26, 0x5B, 0x44, 0x74, 0x01, 0x32, 0x48, 0x64, 0x04, 0x08, 0x3C, 0x32, + 0x8E, 0x64, 0x05, 0x08, 0x80, 0x30, 0xFF, 0xE3, 0xF7, 0xF8, 0xB4, 0x04, + 0x40, 0x3B, 0x0B, 0x08, 0x80, 0x30, 0x02, 0x40, 0xFF, 0xE3, 0xF0, 0xF8, + 0xAD, 0x04, 0x00, 0x00, 0x14, 0x01, 0x00, 0x20, 0x00, 0x70, 0x00, 0x40, + 0x55, 0x32, 0x8E, 0x64, 0x06, 0x08, 0x80, 0x30, 0x01, 0x40, 0xFF, 0xE3, + 0xE3, 0xF8, 0xA0, 0x04, 0x40, 0x30, 0xFF, 0xE3, 0xDF, 0xF8, 0x9C, 0x04, + 0x24, 0x13, 0x23, 0x81, 0x21, 0xE4, 0x3E, 0x20, 0x40, 0x39, 0x8F, 0x0C, + 0x21, 0x13, 0x21, 0x89, 0x27, 0x49, 0x21, 0xE4, 0x03, 0x20, 0x41, 0x39, + 0x1A, 0x0C, 0x21, 0x39, 0x04, 0x0C, 0x40, 0x39, 0x07, 0x0C, 0x8A, 0x04, + 0x42, 0x39, 0x5E, 0x0C, 0x43, 0x39, 0x86, 0x08, 0x66, 0x04, 0x42, 0xE4, + 0x03, 0x20, 0x40, 0x3A, 0x88, 0x08, 0x77, 0x12, 0x41, 0x8B, 0x87, 0x3A, + 0x88, 0x3A, 0xA7, 0x3A, 0x41, 0xAB, 0x40, 0x83, 0x42, 0xE4, 0x7F, 0x20, + 0x40, 0xA3, 0x76, 0x04, 0x71, 0x12, 0x62, 0x93, 0x20, 0x83, 0x44, 0x74, + 0x21, 0x49, 0x20, 0xA3, 0x42, 0xE4, 0x03, 0x20, 0x41, 0x3A, 0x12, 0x08, + 0x40, 0x83, 0x00, 0x31, 0x7F, 0x29, 0x84, 0x6C, 0x88, 0x74, 0x40, 0xA3, + 0x49, 0x12, 0x20, 0x82, 0x07, 0x49, 0x00, 0xE4, 0x01, 0x20, 0x02, 0x6C, + 0x07, 0x40, 0x21, 0xE4, 0x7F, 0x20, 0x40, 0x6C, 0x20, 0xA2, 0x04, 0x12, + 0x42, 0x80, 0x23, 0x4A, 0x00, 0x21, 0x21, 0xE4, 0x0F, 0x20, 0x83, 0x41, + 0x42, 0xE4, 0x78, 0x30, 0x90, 0x6C, 0x42, 0xA0, 0x48, 0x39, 0x4E, 0x08, + 0x22, 0x80, 0x21, 0xE4, 0x78, 0x30, 0x22, 0xA0, 0x21, 0x88, 0x87, 0x39, + 0x88, 0x39, 0xA8, 0x39, 0x21, 0xA8, 0x4C, 0x80, 0x40, 0x3A, 0x13, 0x08, + 0x01, 0x31, 0x2C, 0xA0, 0x23, 0x80, 0x21, 0xE4, 0x3E, 0x20, 0x3E, 0x32, + 0x86, 0x64, 0x0B, 0x08, 0x20, 0x83, 0x44, 0x74, 0x24, 0x49, 0x01, 0x21, + 0x21, 0x41, 0x43, 0x80, 0x42, 0xE4, 0x3E, 0x30, 0x84, 0x6C, 0x43, 0xA0, + 0x6E, 0x11, 0x42, 0x93, 0x00, 0x22, 0x42, 0xB3, 0x2B, 0x04, 0x4C, 0x11, + 0x40, 0x82, 0x47, 0x4A, 0x8E, 0x64, 0x2D, 0x08, 0x69, 0x11, 0x41, 0x8B, + 0x42, 0xEC, 0x80, 0x01, 0x41, 0xAB, 0x20, 0x04, 0x42, 0xE4, 0x03, 0x20, + 0x41, 0x3A, 0x23, 0x08, 0x64, 0x11, 0x21, 0x8B, 0x87, 0x39, 0x88, 0x39, + 0x00, 0xEA, 0x7F, 0xFE, 0x01, 0xC4, 0x22, 0x20, 0x21, 0xAB, 0x48, 0x4A, + 0x21, 0x4A, 0x1E, 0x21, 0x21, 0xE4, 0x1F, 0x20, 0x21, 0x41, 0x42, 0xE4, + 0x3E, 0x30, 0x84, 0x6C, 0x43, 0xA3, 0x08, 0x04, 0x7B, 0x10, 0x40, 0x93, + 0x83, 0x3A, 0x40, 0xB3, 0x02, 0x30, 0xFF, 0xE3, 0x43, 0xF8, 0x77, 0x10, + 0x42, 0x83, 0x80, 0x3A, 0x81, 0x3A, 0xA1, 0x3A, 0x42, 0xA3, 0x42, 0x04, + 0x74, 0x10, 0x40, 0x93, 0x83, 0x3A, 0x40, 0xB3, 0x40, 0x30, 0xFF, 0xE3, + 0x35, 0xF8, 0x3A, 0x04, 0x40, 0x3B, 0x0C, 0x08, 0x6F, 0x10, 0x41, 0x93, + 0x89, 0x74, 0x6D, 0x10, 0x42, 0xAB, 0x43, 0x83, 0x42, 0xE4, 0x3F, 0x20, + 0xA6, 0x3A, 0x43, 0xA3, 0x2D, 0x04, 0x40, 0x32, 0x8E, 0x64, 0x2A, 0x08, + 0x68, 0x10, 0x41, 0x93, 0x66, 0x10, 0x62, 0x8B, 0xCD, 0x74, 0x89, 0x74, + 0x8C, 0x64, 0x0E, 0x08, 0x64, 0x10, 0x41, 0x93, 0x62, 0x10, 0x62, 0x8B, + 0x06, 0x04, 0x00, 0x00, 0x14, 0x01, 0x00, 0x20, 0x00, 0x70, 0x00, 0x40, + 0x4D, 0x5A, 0x88, 0x74, 0x07, 0x04, 0x76, 0x12, 0x42, 0x8B, 0x76, 0x12, + 0x61, 0x93, 0x4D, 0x5A, 0x88, 0x74, 0x04, 0x33, 0x8C, 0x64, 0x0C, 0x08, + 0x71, 0x12, 0x43, 0x83, 0x42, 0xE4, 0x3F, 0x20, 0x00, 0x31, 0x7F, 0x29, + 0x84, 0x6C, 0x43, 0xA3, 0x09, 0x30, 0xFF, 0xE3, 0x6F, 0xF8, 0xEE, 0xD9, + 0x01, 0x20, 0x80, 0x98, 0x02, 0x14, 0x63, 0x14, 0x61, 0x14, 0x00, 0x00, + 0x69, 0x12, 0x00, 0x32, 0x40, 0xB3, 0x20, 0x93, 0x21, 0xEC, 0x03, 0x00, + 0x20, 0xB3, 0x20, 0x93, 0xA2, 0x39, 0x20, 0xB3, 0x63, 0x12, 0x46, 0xA3, + 0x00, 0x31, 0x2C, 0xA3, 0x42, 0xAB, 0x40, 0x83, 0x42, 0xE4, 0x78, 0x20, + 0x42, 0xE4, 0x78, 0x30, 0x40, 0xA3, 0x42, 0x83, 0x80, 0x3A, 0x81, 0x3A, + 0x42, 0xA3, 0x41, 0x8B, 0x87, 0x3A, 0x88, 0x3A, 0x00, 0xEA, 0x7F, 0xFE, + 0x02, 0xC4, 0x21, 0x20, 0x28, 0x49, 0x21, 0xE4, 0x3E, 0x30, 0x19, 0x11, + 0x80, 0x68, 0x42, 0xE4, 0x78, 0x30, 0x42, 0xA3, 0x21, 0xE4, 0x3E, 0x20, + 0x23, 0xA3, 0x3C, 0x78, 0xD3, 0x14, 0x00, 0x74, 0x44, 0x74, 0x71, 0x11, + 0x63, 0x83, 0x63, 0xE4, 0x3F, 0x30, 0xCC, 0x74, 0xC0, 0x34, 0x0E, 0x65, + 0x46, 0x0C, 0x6D, 0x11, 0x42, 0xB3, 0x40, 0x83, 0x02, 0x35, 0x94, 0x6C, + 0x42, 0xE4, 0x78, 0x30, 0x82, 0x3A, 0x40, 0xA3, 0x81, 0x8B, 0x87, 0x3C, + 0x88, 0x3C, 0x06, 0xEA, 0x7F, 0xFE, 0xC4, 0xC4, 0x22, 0x20, 0xC8, 0x11, + 0x18, 0x69, 0x14, 0x6D, 0x84, 0xE4, 0x78, 0x30, 0x00, 0x35, 0xAC, 0xA3, + 0x00, 0xE4, 0x01, 0x20, 0x02, 0x40, 0x82, 0x3C, 0x10, 0x6C, 0x02, 0xA3, + 0x21, 0xE4, 0x1F, 0x20, 0x21, 0x41, 0x48, 0x4A, 0x42, 0xE4, 0x3E, 0x30, + 0x84, 0x6C, 0x42, 0xE4, 0x3F, 0x20, 0x43, 0xA3, 0x7A, 0x10, 0x40, 0x93, + 0x83, 0x3A, 0x40, 0xB3, 0x7B, 0x10, 0x00, 0x32, 0x40, 0xB3, 0x40, 0x93, + 0xA5, 0x3A, 0x40, 0xB3, 0x40, 0x93, 0x40, 0xB3, 0x40, 0x93, 0xA1, 0x3A, + 0x40, 0xB3, 0x40, 0x93, 0xA6, 0x3A, 0x40, 0xB3, 0xFA, 0x32, 0x42, 0x42, + 0x41, 0xB3, 0x42, 0xB3, 0x40, 0x93, 0xA9, 0x3A, 0x40, 0xB3, 0x09, 0x30, + 0x00, 0x31, 0x2D, 0x32, 0xFF, 0xE3, 0xCC, 0xF7, 0x93, 0x14, 0x00, 0x00, + 0xD0, 0x14, 0x6A, 0x10, 0x40, 0x93, 0x83, 0x3A, 0x40, 0xB3, 0x04, 0x30, + 0xFF, 0xE3, 0x6E, 0xF7, 0x90, 0x14, 0x00, 0x00, 0x68, 0x10, 0x00, 0x32, + 0x40, 0xB3, 0x64, 0x10, 0x40, 0x93, 0x83, 0x3A, 0x40, 0xB3, 0x3C, 0x78, + 0x14, 0x01, 0x00, 0x20, 0x00, 0x70, 0x00, 0x40, 0x7B, 0xFE, 0xFF, 0xFF, + 0x7C, 0xFE, 0xFF, 0xFF, 0x00, 0x10, 0x00, 0x40, 0x60, 0x14, 0x62, 0x14, + 0xC4, 0x14, 0x21, 0x14, 0x02, 0x32, 0x4E, 0xDC, 0x00, 0x00, 0x00, 0x31, + 0x2E, 0xDC, 0x01, 0x00, 0x4E, 0xDC, 0x02, 0x00, 0x00, 0x36, 0x03, 0x32, + 0x00, 0x35, 0x3B, 0x10, 0x9C, 0x30, 0x04, 0x40, 0x3B, 0x6D, 0x20, 0x04, + 0x00, 0x33, 0x60, 0xB1, 0x40, 0x3D, 0x04, 0x0C, 0x41, 0x3D, 0x1A, 0x08, + 0x0B, 0x04, 0x00, 0xB1, 0x10, 0x35, 0x60, 0x91, 0x4E, 0x69, 0xFE, 0x0F, + 0x60, 0x91, 0x8B, 0x3B, 0x60, 0xB1, 0x01, 0x35, 0x0F, 0x04, 0x78, 0x5C, + 0x60, 0x83, 0x61, 0xB1, 0x00, 0x26, 0x98, 0x75, 0xE0, 0x33, 0x61, 0x43, + 0x60, 0xB1, 0x10, 0x37, 0x60, 0x91, 0xCE, 0x69, 0xFE, 0x0F, 0x00, 0x2A, + 0x88, 0x74, 0x40, 0x3A, 0xE0, 0x0B, 0x00, 0x33, 0x60, 0xB1, 0x03, 0xEA, + 0x98, 0x3A, 0x02, 0xEA, 0xFF, 0xFF, 0x00, 0x2B, 0xCD, 0x74, 0x8E, 0x64, + 0xFD, 0x0B, 0x00, 0x36, 0x03, 0x32, 0x00, 0x35, 0xF1, 0x07, 0x00, 0x00, + 0x00, 0x60, 0x00, 0x40, 0x3C, 0x78, 0x00, 0x00, 0x60, 0x14, 0x62, 0x14, + 0xD0, 0x14, 0x00, 0xE0, 0x17, 0x02, 0xFF, 0xE3, 0x93, 0xF7, 0xEE, 0xD9, + 0x00, 0x20, 0x01, 0x14, 0x63, 0x14, 0x61, 0x14, 0x60, 0x14, 0x62, 0x14, + 0x63, 0x14, 0x61, 0x14, 0x60, 0x14, 0x62, 0x14, 0x63, 0x14, 0x61, 0x14, + 0x60, 0x14, 0x62, 0x14, 0x63, 0x14, 0x61, 0x14, 0x60, 0x14, 0x62, 0x14, + 0x63, 0x14, 0x61, 0x14, 0x60, 0x14, 0x62, 0x14, 0xD0, 0x14, 0xFF, 0xE3, + 0x99, 0xF2, 0xEE, 0xD9, 0x00, 0x20, 0x01, 0x14, 0x63, 0x14, 0x61, 0x14, + 0x60, 0x14, 0x62, 0x14, 0xD1, 0x14, 0x7C, 0x12, 0x62, 0x93, 0xC0, 0x3B, + 0x18, 0x0C, 0x9A, 0x12, 0x61, 0x94, 0xA6, 0x3B, 0x61, 0xB4, 0x00, 0x30, + 0xFF, 0xE3, 0xA2, 0xFC, 0x0A, 0x30, 0x00, 0xE0, 0xFD, 0x00, 0x60, 0x94, + 0xB8, 0x3B, 0x60, 0xB4, 0x62, 0x94, 0x80, 0x3B, 0x62, 0xB4, 0x04, 0x30, + 0xFF, 0xE3, 0xEC, 0xF6, 0x05, 0x30, 0xFF, 0xE3, 0x53, 0xF2, 0x20, 0x04, + 0x6E, 0x12, 0x41, 0x93, 0xA6, 0x3A, 0x41, 0xB3, 0x62, 0x93, 0xC4, 0x3B, + 0x08, 0x0C, 0x00, 0x30, 0xFF, 0xE3, 0x88, 0xFC, 0x05, 0x30, 0xFF, 0xE3, + 0x45, 0xF2, 0x04, 0x04, 0x04, 0x30, 0xFF, 0xE3, 0x41, 0xF2, 0x86, 0x12, + 0x62, 0x94, 0x63, 0xE4, 0x3F, 0x30, 0x62, 0xB4, 0x01, 0x30, 0xFF, 0xE3, + 0xCF, 0xF6, 0x0A, 0x30, 0x00, 0xE0, 0xD4, 0x00, 0x60, 0x94, 0xB8, 0x3B, + 0x60, 0xB4, 0xEE, 0xD9, 0x01, 0x20, 0x80, 0x98, 0x02, 0x14, 0x63, 0x14, + 0x61, 0x14, 0x00, 0x00, 0x60, 0x14, 0x62, 0x14, 0xD1, 0x14, 0x9A, 0x11, + 0x61, 0x94, 0xA6, 0x3B, 0x61, 0xB4, 0x04, 0x30, 0xFF, 0xE3, 0x22, 0xF2, + 0x01, 0x30, 0xFF, 0xE3, 0xB5, 0xF6, 0x0B, 0x30, 0x00, 0xE0, 0xBA, 0x00, + 0x60, 0x94, 0xBA, 0x3B, 0x60, 0xB4, 0x63, 0x94, 0x63, 0xE4, 0xFF, 0x30, + 0x63, 0xB4, 0xEE, 0xD9, 0x01, 0x20, 0x80, 0x98, 0x02, 0x14, 0x63, 0x14, + 0x61, 0x14, 0x00, 0x00, 0x60, 0x14, 0x62, 0x14, 0x63, 0x14, 0x61, 0x14, + 0x60, 0x14, 0x62, 0x14, 0x63, 0x14, 0x61, 0x14, 0x60, 0x14, 0x62, 0x14, + 0x63, 0x14, 0x61, 0x14, 0x60, 0x14, 0x62, 0x14, 0x63, 0x14, 0x61, 0x14, + 0x60, 0x14, 0x62, 0x14, 0x63, 0x14, 0x61, 0x14, 0xD0, 0x14, 0x00, 0xE0, + 0x47, 0x00, 0x00, 0xE0, 0x83, 0x00, 0x00, 0x30, 0x00, 0xE0, 0x88, 0x00, + 0x01, 0x30, 0x00, 0xE0, 0x85, 0x00, 0x02, 0x30, 0x00, 0xE0, 0x82, 0x00, + 0x0B, 0x30, 0x00, 0xE0, 0x7F, 0x00, 0x0A, 0x30, 0x00, 0xE0, 0x7C, 0x00, + 0x07, 0x30, 0x00, 0xE0, 0x79, 0x00, 0x78, 0x10, 0x47, 0x93, 0xA0, 0x3A, + 0x47, 0xB3, 0x09, 0x30, 0x00, 0xE0, 0x72, 0x00, 0x04, 0x30, 0x00, 0xE0, + 0x77, 0x00, 0x06, 0x30, 0x00, 0xE0, 0x6C, 0x00, 0x06, 0x30, 0x01, 0x31, + 0x00, 0xE0, 0x80, 0x00, 0x0A, 0x30, 0x00, 0x31, 0x00, 0xE0, 0x7C, 0x00, + 0x0B, 0x30, 0x00, 0x31, 0x00, 0xE0, 0x78, 0x00, 0x09, 0x30, 0x00, 0x31, + 0x00, 0xE0, 0x74, 0x00, 0x07, 0x30, 0x02, 0x31, 0x00, 0xE0, 0x70, 0x00, + 0x01, 0x30, 0x01, 0x31, 0x00, 0xE0, 0x6C, 0x00, 0x00, 0x30, 0x03, 0x31, + 0x00, 0xE0, 0x68, 0x00, 0x90, 0x14, 0x00, 0x00, 0x3C, 0x78, 0x00, 0x00, + 0x00, 0xA0, 0x00, 0x40, 0x00, 0x90, 0x00, 0x40, 0x71, 0x10, 0x52, 0x10, + 0x60, 0xB2, 0x52, 0x10, 0x43, 0xDC, 0x00, 0x21, 0x51, 0x10, 0x43, 0xDC, + 0x01, 0x21, 0x51, 0x10, 0x43, 0xDC, 0x02, 0x21, 0x50, 0x10, 0x43, 0xDC, + 0x03, 0x21, 0x50, 0x10, 0x43, 0xDC, 0x04, 0x21, 0x4F, 0x10, 0x43, 0xDC, + 0x05, 0x21, 0x4F, 0x10, 0x43, 0xDC, 0x06, 0x21, 0x4E, 0x10, 0x43, 0xDC, + 0x07, 0x21, 0x00, 0x32, 0x43, 0xDC, 0x01, 0x23, 0x43, 0xDC, 0xC0, 0x20, + 0x3C, 0x78, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xE0, 0x24, 0x01, 0x00, 0x20, + 0x03, 0x02, 0x01, 0x00, 0x07, 0x06, 0x05, 0x04, 0x0B, 0x0A, 0x09, 0x08, + 0x0F, 0x0E, 0x0D, 0x0C, 0x13, 0x12, 0x11, 0x10, 0x17, 0x16, 0x15, 0x14, + 0x1B, 0x1A, 0x19, 0x18, 0x1F, 0x1E, 0x1D, 0x1C, 0x61, 0x11, 0x60, 0x93, + 0x01, 0x32, 0x02, 0xC4, 0x20, 0x40, 0x03, 0xDC, 0x80, 0x20, 0x3C, 0x78, + 0x80, 0xC1, 0x20, 0x74, 0x3C, 0x78, 0x00, 0x00, 0x80, 0xC0, 0x20, 0x70, + 0x3C, 0x78, 0x00, 0x00, 0x79, 0x10, 0x60, 0x93, 0x01, 0x32, 0x02, 0xC4, + 0x20, 0x40, 0x03, 0xDC, 0x40, 0x20, 0x3C, 0x78, 0x75, 0x10, 0x60, 0x93, + 0x01, 0x32, 0x02, 0xC4, 0x20, 0x40, 0x03, 0xDC, 0x60, 0x20, 0x3C, 0x78, + 0x71, 0x10, 0x60, 0x93, 0x01, 0x32, 0x02, 0xC4, 0x20, 0x40, 0x03, 0xDC, + 0xA0, 0x20, 0x3C, 0x78, 0xC1, 0x14, 0xDF, 0x38, 0x16, 0x08, 0x60, 0xE4, + 0x03, 0x20, 0x63, 0x43, 0x4A, 0x10, 0x40, 0x92, 0x02, 0x50, 0x00, 0x74, + 0xFF, 0x20, 0x02, 0xC4, 0x40, 0x08, 0x80, 0x90, 0xFF, 0x32, 0x8C, 0x70, + 0x44, 0xC4, 0x42, 0x20, 0x40, 0xB0, 0x40, 0x90, 0x05, 0x23, 0x4C, 0x70, + 0x48, 0x6C, 0x20, 0xB0, 0x81, 0x14, 0x00, 0x00, 0x24, 0x01, 0x00, 0x20, + 0x6B, 0x10, 0x00, 0x32, 0x40, 0xB3, 0x40, 0x93, 0xA5, 0x3A, 0x40, 0xB3, + 0x40, 0x93, 0x40, 0xB3, 0x40, 0x93, 0x40, 0xB3, 0xFF, 0x32, 0x41, 0xB3, + 0x42, 0xB3, 0x66, 0x10, 0x42, 0x93, 0xA2, 0x3A, 0x42, 0xB3, 0x65, 0x10, + 0x00, 0x32, 0x42, 0xB3, 0x3C, 0x78, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40, + 0x00, 0x50, 0x00, 0x40, 0x00, 0x30, 0x00, 0x40, 0x68, 0x10, 0x40, 0x93, + 0xA9, 0x3A, 0x40, 0xB3, 0x3C, 0x78, 0x00, 0x00, 0x00, 0x74, 0x66, 0x10, + 0x02, 0xB3, 0x3C, 0x78, 0x63, 0x10, 0x40, 0x93, 0x89, 0x3A, 0x40, 0xB3, + 0x3C, 0x78, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40, 0x00, 0x30, 0x00, 0x40, + 0x80, 0x33, 0x77, 0x43, 0x00, 0x32, 0x40, 0xB3, 0x40, 0x93, 0xA6, 0x3A, + 0x40, 0xB3, 0x40, 0x93, 0xA5, 0x3A, 0x40, 0xB3, 0x40, 0x93, 0x40, 0xB3, + 0x40, 0x93, 0xA1, 0x3A, 0x40, 0xB3, 0xFA, 0x32, 0x42, 0x42, 0x41, 0xB3, + 0x42, 0xB3, 0x3C, 0x78, 0x80, 0x33, 0x77, 0x43, 0x40, 0x93, 0xA9, 0x3A, + 0x40, 0xB3, 0x3C, 0x78, 0x3C, 0x78, 0x00, 0x00, 0x3C, 0x78, 0x00, 0x00, + 0xD0, 0x14, 0x21, 0x14, 0x00, 0xE0, 0x48, 0x01, 0x00, 0x74, 0x6E, 0xE4, + 0x02, 0x00, 0x00, 0xA3, 0x8F, 0x6C, 0x60, 0x82, 0xCC, 0x74, 0x23, 0x5B, + 0x44, 0x74, 0x20, 0xA2, 0x40, 0x3B, 0xFA, 0x0B, 0x01, 0x14, 0x90, 0x14, + 0x21, 0x14, 0x00, 0x74, 0x44, 0x48, 0x6E, 0xE4, 0x02, 0x00, 0x40, 0xA3, + 0x60, 0x83, 0xCC, 0x74, 0x09, 0x3B, 0x07, 0x08, 0x6E, 0xE4, 0x02, 0x00, + 0x40, 0x83, 0x2F, 0x22, 0x88, 0x74, 0x06, 0x04, 0x6E, 0xE4, 0x02, 0x00, + 0x40, 0x83, 0x36, 0x22, 0x88, 0x74, 0x6E, 0xE4, 0x02, 0x00, 0x40, 0xA3, + 0x40, 0x83, 0x00, 0xE4, 0x0F, 0x20, 0x00, 0xA3, 0x60, 0x83, 0xCC, 0x74, + 0x09, 0x3B, 0x07, 0x08, 0x6E, 0xE4, 0x02, 0x00, 0x40, 0x83, 0x2F, 0x22, + 0x88, 0x74, 0x06, 0x04, 0x6E, 0xE4, 0x02, 0x00, 0x40, 0x83, 0x36, 0x22, + 0x88, 0x74, 0x6E, 0xE4, 0x02, 0x00, 0x40, 0xA3, 0x60, 0x83, 0x01, 0x14, + 0x3C, 0x78, 0x00, 0x00, 0xD1, 0x14, 0x01, 0x75, 0x08, 0x4C, 0xFF, 0xE3, + 0xCB, 0xFF, 0x10, 0x74, 0xFF, 0xE3, 0xC8, 0xFF, 0x91, 0x14, 0x00, 0x00, + 0xD1, 0x14, 0x03, 0x6D, 0x18, 0x48, 0xFF, 0xE3, 0xC1, 0xFF, 0x04, 0xC4, + 0x40, 0x70, 0xFF, 0xE3, 0xBD, 0xFF, 0x04, 0xC4, 0x80, 0x70, 0xFF, 0xE3, + 0xB9, 0xFF, 0x10, 0x74, 0xFF, 0xE3, 0xB6, 0xFF, 0x91, 0x14, 0x00, 0x00, + 0x66, 0x10, 0x42, 0x93, 0xA1, 0x3A, 0x42, 0xB3, 0x42, 0x93, 0xA0, 0x3A, + 0x42, 0xB3, 0xE0, 0xC6, 0x22, 0x50, 0x40, 0xB3, 0x3C, 0x78, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x40, 0x64, 0x10, 0x45, 0x10, 0x40, 0xB3, 0x3C, 0x78, + 0x62, 0x10, 0x00, 0x32, 0x42, 0xB3, 0x3C, 0x78, 0x00, 0x40, 0x00, 0x40, + 0x40, 0x42, 0x0F, 0x00, 0xD0, 0x14, 0xFF, 0xE3, 0xC3, 0xF9, 0xFF, 0xE3, + 0xF5, 0xFC, 0xFF, 0xE3, 0x71, 0xFE, 0xFF, 0xE3, 0xEB, 0xFA, 0xFF, 0xE3, + 0x6B, 0xF9, 0xFF, 0xE3, 0x5B, 0xFA, 0xFF, 0xE3, 0xEB, 0xFC, 0xFF, 0xE3, + 0x73, 0xFF, 0xFF, 0xE3, 0x57, 0xFF, 0xFF, 0xE3, 0x25, 0xFF, 0xFF, 0xE3, + 0xD1, 0xFF, 0xFF, 0xE3, 0xB3, 0xF5, 0xFF, 0xE3, 0x1B, 0xF5, 0xFF, 0xE3, + 0x1B, 0xF3, 0xFF, 0xE3, 0x33, 0xF0, 0xFF, 0xE3, 0x41, 0xF2, 0xFF, 0xE3, + 0xCF, 0xEF, 0xFF, 0xE3, 0x59, 0xF4, 0x90, 0x14, 0xD0, 0x14, 0x00, 0x30, + 0x01, 0x31, 0x02, 0x32, 0xFF, 0xE3, 0x14, 0xF5, 0x01, 0x30, 0x01, 0x31, + 0x02, 0x32, 0xFF, 0xE3, 0x0F, 0xF5, 0xFF, 0xE3, 0x6B, 0xF4, 0xFF, 0xE3, + 0x49, 0xFF, 0x90, 0x14, 0xD0, 0x14, 0xFF, 0xE3, 0x41, 0xF5, 0xFF, 0xE3, + 0x6B, 0xF4, 0xFC, 0x07, 0xD0, 0x14, 0xFF, 0xE3, 0xC3, 0xFF, 0xFF, 0xE3, + 0xE7, 0xFF, 0xFF, 0xE3, 0xF5, 0xFF, 0x00, 0x30, 0x90, 0x14, 0x00, 0x00, + 0x40, 0x39, 0x03, 0x08, 0x00, 0xC0, 0x20, 0x2C, 0x40, 0x38, 0x02, 0x08, + 0x3C, 0x78, 0xC2, 0x14, 0x43, 0x6D, 0x45, 0x6D, 0xE0, 0xC7, 0x80, 0x28, + 0x03, 0x0C, 0x02, 0x6C, 0x00, 0x20, 0xE1, 0xC7, 0x80, 0x28, 0x03, 0x0C, + 0x46, 0x6C, 0x00, 0x21, 0x01, 0x32, 0xC3, 0x6C, 0x03, 0xC4, 0x44, 0x7C, + 0x90, 0x70, 0x10, 0x70, 0xC7, 0x6C, 0x03, 0xC4, 0x44, 0x7C, 0x00, 0x24, + 0xC3, 0x6C, 0xD1, 0x70, 0x12, 0x6D, 0x20, 0x24, 0x90, 0x70, 0x10, 0x70, + 0x40, 0x3A, 0x09, 0x0C, 0x00, 0xC4, 0x20, 0x4C, 0xCD, 0x60, 0x4C, 0x64, + 0x02, 0x0C, 0xC6, 0x60, 0x89, 0x60, 0xF9, 0x0F, 0x0B, 0x6C, 0x4F, 0x6C, + 0x05, 0xC4, 0x25, 0x4C, 0x05, 0x0C, 0x02, 0x6C, 0x00, 0x20, 0x46, 0x6C, + 0x00, 0x21, 0x82, 0x14, 0x40, 0x3A, 0x25, 0x0C, 0x43, 0x6F, 0x80, 0xE5, + 0x03, 0x20, 0x4C, 0xEB, 0x00, 0x00, 0x20, 0x0C, 0x2D, 0xDC, 0x00, 0x00, + 0x00, 0x2A, 0x40, 0x3A, 0x1A, 0x0C, 0xAD, 0xE5, 0x00, 0x00, 0x8D, 0xE5, + 0x03, 0x20, 0x4C, 0xEB, 0x00, 0x00, 0x14, 0x0C, 0x2D, 0xDC, 0x00, 0x00, + 0x00, 0x2A, 0x40, 0x3A, 0x0E, 0x0C, 0xAD, 0xE5, 0x00, 0x00, 0x8D, 0xE5, + 0x03, 0x20, 0x4C, 0xEB, 0x00, 0x00, 0x08, 0x0C, 0x2D, 0xDC, 0x00, 0x00, + 0x00, 0x2A, 0xAD, 0xE5, 0x00, 0x00, 0x02, 0x04, 0x3C, 0x78, 0x68, 0x41, + 0x4C, 0x6C, 0x70, 0x41, 0x4C, 0x6C, 0x2F, 0x3A, 0x0E, 0x08, 0x2D, 0xDC, + 0x00, 0x20, 0x2D, 0xDC, 0x01, 0x20, 0x2D, 0xDC, 0x02, 0x20, 0x2D, 0xDC, + 0x03, 0x20, 0x0F, 0x2A, 0xAD, 0xE5, 0x0F, 0x00, 0x2F, 0x3A, 0xF4, 0x0F, + 0x23, 0x3A, 0x08, 0x08, 0x03, 0x2A, 0x2D, 0xDC, 0x00, 0x20, 0xAD, 0xE5, + 0x03, 0x00, 0x23, 0x3A, 0xFA, 0x0F, 0x40, 0x3A, 0xE2, 0x0F, 0x00, 0x2A, + 0x2D, 0xDC, 0x00, 0x00, 0x40, 0x3A, 0xDD, 0x0F, 0x00, 0x2A, 0x2D, 0xDC, + 0x01, 0x00, 0x40, 0x3A, 0xD8, 0x0F, 0x2D, 0xDC, 0x02, 0x00, 0x3C, 0x78, + 0x43, 0x6C, 0x00, 0xE4, 0x03, 0x20, 0x40, 0x38, 0x08, 0x0C, 0x00, 0x30, + 0x40, 0x81, 0x40, 0x3A, 0x16, 0x0C, 0x00, 0x21, 0x00, 0x20, 0xFB, 0x07, + 0x40, 0x91, 0x0B, 0x68, 0x04, 0x0C, 0x03, 0x21, 0x03, 0x20, 0xFB, 0x07, + 0x02, 0xC4, 0x03, 0x71, 0x0A, 0x0C, 0x00, 0x20, 0x02, 0xC4, 0x83, 0x70, + 0x06, 0x0C, 0x00, 0x20, 0x02, 0xC4, 0x43, 0x70, 0x02, 0x0C, 0x00, 0x20, + 0x3C, 0x78, 0x00, 0x00, 0x5E, 0x04, 0x00, 0x00, 0x66, 0x04, 0x00, 0x00, + 0xB6, 0x04, 0x00, 0x00, 0x6E, 0x04, 0x00, 0x00, 0x74, 0x04, 0x00, 0x00, + 0x7A, 0x04, 0x00, 0x00, 0x90, 0x04, 0x00, 0x00, 0xA6, 0x04, 0x00, 0x00, + 0x0E, 0x07, 0x00, 0x00, 0x0E, 0x07, 0x00, 0x00, 0x0E, 0x07, 0x00, 0x00, + 0x38, 0x07, 0x00, 0x00, 0x44, 0x07, 0x00, 0x00, 0x52, 0x07, 0x00, 0x00, + 0x62, 0x07, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, 0xE2, 0x08, 0x00, 0x00, + 0xF4, 0x08, 0x00, 0x00, 0x16, 0x09, 0x00, 0x00, 0x28, 0x09, 0x00, 0x00, + 0x28, 0x09, 0x00, 0x00, 0x05, 0x06, 0x04, 0x00, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x0F, 0x14, 0x14, 0x06, 0x28, 0x28, 0x00, 0xE4, 0x09, 0x00, 0x00, + 0xCE, 0x09, 0x00, 0x00, 0xFA, 0x09, 0x00, 0x00, 0x10, 0x0A, 0x00, 0x00, + 0x26, 0x0A, 0x00, 0x00, 0x66, 0x0A, 0x00, 0x00, 0xF8, 0x0B, 0x00, 0x00, + 0x90, 0x0B, 0x00, 0x00, 0xC8, 0x19, 0x00, 0x00, 0x52, 0x1A, 0x00, 0x00, + 0x52, 0x1A, 0x00, 0x00, 0x52, 0x1A, 0x00, 0x00, 0xF2, 0x19, 0x00, 0x00, + 0xFA, 0x19, 0x00, 0x00, 0x0A, 0x1A, 0x00, 0x00, 0x12, 0x1A, 0x00, 0x00, + 0x1A, 0x1A, 0x00, 0x00, 0x22, 0x1A, 0x00, 0x00, 0x2A, 0x1A, 0x00, 0x00, + 0x84, 0x09, 0x00, 0x00, 0xF8, 0x04, 0x00, 0x00, 0xE4, 0x01, 0x00, 0x00, + 0xBC, 0x02, 0x00, 0x00, 0xD4, 0x01, 0x00, 0x00, 0xBC, 0x0C, 0x00, 0x00, + 0x90, 0x05, 0x00, 0x00, 0xE4, 0x1B, 0x00, 0x00, 0x60, 0x1D, 0x00, 0x00, + 0x5C, 0x29, 0x00, 0x00, 0x94, 0x22, 0x00, 0x00, 0xD4, 0x10, 0x00, 0x00, + 0xC8, 0x25, 0x00, 0x00, 0x48, 0x18, 0x00, 0x00, 0xA4, 0x10, 0x00, 0x00, + 0x34, 0x11, 0x00, 0x00, 0xBC, 0x31, 0x00, 0x00, 0xAC, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x11, 0x00, 0x00, 0x68, 0x09, 0x00, 0x00, + 0x01, 0x02, 0x04, 0x08, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0xF0, 0xE1, 0xD2, 0xC3 +}; + +#endif diff --git a/drivers/power/supply/nuvolta/rx1619.c b/drivers/power/supply/nuvolta/rx1619.c new file mode 100644 index 000000000000..62fa5b97cc63 --- /dev/null +++ b/drivers/power/supply/nuvolta/rx1619.c @@ -0,0 +1,4695 @@ +/** + * Copyright “Copyright (C) 2019 XiaoMi, Inc + * Copyright (C) 2021 XiaoMi, Inc. + * + * L.D + * + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +/* add for get hw country */ +#include +#include "rx1619.h" + +#define rx1619_DRIVER_NAME "rx1619" + +#define GOOD 0 +#define STILL 1 +#define LIMIT 2 +#define EPP_MODE 1 +#define BPP_MODE 0 +#define MIN_VOUT 4000 +#define MAX_VOUT 15000 +#define AP_REV_DATA_OK 0xaa +#define AP_SENT_DATA_OK 0x55 +#define PRIVATE_VBUCK_SET_CMD 0x80 +#define PRIVATE_ID_CMD 0x86 +#define PRIVATE_USB_TYPE_CMD 0x87 +#define PRIVATE_FAST_CHG_CMD 0x88 +#define PRIVATE_PRODUCT_TEST_CMD 0x8D +#define PRIVATE_TX_HW_ID_CMD 0x8b +#define FW_ERROR_CODE 0xFE +#define FW_EMPTY_CODE 0xFF +/*adapter type*/ +#define ADAPTER_NONE 0x00 +#define ADAPTER_SDP 0x01 +#define ADAPTER_CDP 0x02 +#define ADAPTER_DCP 0x03 +#define ADAPTER_QC2 0x05 +#define ADAPTER_QC3 0x06 +#define ADAPTER_PD 0x07 +#define ADAPTER_AUTH_FAILED 0x08 +#define ADAPTER_XIAOMI_QC3 0x09 +#define ADAPTER_XIAOMI_PD 0x0a +#define ADAPTER_ZIMI_CAR_POWER 0x0b +#define ADAPTER_XIAOMI_PD_40W 0x0c +#define ADAPTER_VOICE_BOX 0x0d +#define ADAPTER_XIAOMI_PD_50W 0x0e +#define ADAPTER_XIAOMI_PD_60W 0x0f + +//0x000b[0:3] 0000:no charger, 0001:SDP, 0010:CDP, 0011:DCP, 0101:QC2-other, +//0110:QC3-other, 0111:PD, 1000:fail charger, 1001:QC3-27W, 1010:PD-27W +#define EPP_MODE_CURRENT 600000 +#define DC_OTHER_CURRENT 750000 +#define DC_LOW_CURRENT 200000 //200mA +#define DC_DCP_CURRENT 700000 +#define DC_CDP_CURRENT 800000 +#define DC_QC2_CURRENT 1000000 +#define DC_QC3_CURRENT 1800000 +#define DC_QC3_BPP_CURRENT 900000 +#define DC_TURBO_CURRENT 1100000 +#define DC_QC3_20W_CURRENT 2100000 //2.1A +#define DC_PD_CURRENT 1000000 +#define DC_PD_20W_CURRENT 2000000 //2A +#define DC_PD_40W_CURRENT 3100000 //3.1A +#define DC_BPP_CURRENT 850000 +#define DC_SDP_CURRENT 500000 +#define SCREEN_OFF_FUL_CURRENT 250000 +#define DC_FULL_CURRENT 350000 +#define DC_BPP_AUTH_FAIL_CURRENT 750000 +#define USB_20W_PLUS_BASE_CURRENT_UA 1000000 //1.0A +#define USB_20W_PLUS_CURRENT_UA 1800000 //1.8A + +#define ADAPTER_DEFAULT_VOL 6000 +#define ADAPTER_BPP_LIMIT_VOL 6500 +#define ADAPTER_VOUT_LIMIT_VOL 6000 +#define ADAPTER_BPP_PLUS_VOL 9000 +#define ADAPTER_EPP_QC3_VOL 11000 +#define EPP_VOL_THRESHOLD 12000 +#define ADAPTER_EPP_MI_VOL 15000 +#define ADAPTER_BPP_QC2_VOL 6500 + +#define LIMIT_SOC 95 +#define FULL_SOC 100 +#define LIMIT_EPP_IOUT 500 +#define EXCHANGE_9V 0x0 +#define EXCHANGE_5V 0x1 +#define EXCHANGE_15V 0x0 +#define EXCHANGE_10V 0x1 +#define ICL_EXCHANGE_COUNT 2 /*5 = 1min*/ +#define LIMIT_EPP_IOUT 500 +#define LIMIT_BPP_IOUT 500 +#define HIGH_THERMAL_LEVEL_THR 12 + +/* used registers define */ +#define REG_RX_SENT_CMD 0x0000 +#define REG_RX_SENT_DATA1 0x0001 +#define REG_RX_SENT_DATA2 0x0002 +#define REG_RX_SENT_DATA3 0x0003 +#define REG_RX_SENT_DATA4 0x0004 +#define REG_RX_SENT_DATA5 0x0005 +#define REG_RX_SENT_DATA6 0x0006 +#define REG_RX_REV_CMD 0x0020 +#define REG_RX_REV_DATA1 0x0021 +#define REG_RX_REV_DATA2 0x0022 +#define REG_RX_REV_DATA3 0x0023 +#define REG_RX_REV_DATA4 0x0024 + +#define REG_CEP_VALUE 0x0008 +#define REG_RX_VOUT 0x0009 +#define REG_RX_VRECT 0x000a +#define REG_RX_IOUT 0x000b + +#define REG_AP_RX_COMM 0x000C +#define ADDR_RX 256 +#define ADDR_TX 4864 + +#define ID_CMD 0x3b +#define AUTH_CMD 0x86 +#define UUID_CMD 0x90 + +u8 fod_param[8] = { 0x44, 0x64, 0x44, 0x78, 0x3A, 0x67, 0x37, 0x67 }; + +static struct rx1619_chg *g_chip; +static int g_Delta; +static u8 g_project_id_h; +static u8 g_project_id_l; +static u8 g_fw_boot_id; +static u8 g_id_done_flag; +static u8 g_fw_rx_id; +static u8 g_fw_tx_id; +static u8 g_hw_id_h, g_hw_id_l; +static u8 g_epp_or_bpp = BPP_MODE; +static u8 g_USB_TYPE = 0; +static int g_current_now = DC_LOW_CURRENT; +static bool g_rx1619_restart_flag = false; +static bool g_rx1619_first_flag; +static u8 rx_bin_project_id_h; +static u8 rx_bin_project_id_l; +static bool is_nvt_rx; + +static u32 g_fw_data_lenth; +static u8 boot_fw_version; +static u8 rx_fw_version; +static u8 tx_fw_version; + +static int rx_set_enable_mode(struct rx1619_chg *chip, int enable); +static int rx_get_reverse_chg_mode(struct rx1619_chg *chip); +static int rx_set_reverse_gpio(struct rx1619_chg *chip, int enable); +static int rx_set_reverse_chg_mode(struct rx1619_chg *chip, int enable); + +#define BOOT_AREA 0 +#define RX_AREA 1 +#define TX_AREA 2 + +#define NORMAL_MODE 0x1 +#define TAPER_MODE 0x2 +#define FULL_MODE 0x3 +#define RECHG_MODE 0x4 + +//fw version to update +#define FW_VERSION 0x15 + +struct rx1619_chg { + char *name; + struct i2c_client *client; + struct device *dev; + struct regmap *regmap; + unsigned int tx_on_gpio; + unsigned int irq_gpio; + unsigned int power_good_gpio; + unsigned int power_good_irq; + unsigned int enable_gpio; + unsigned int chip_enable; + int online; + struct pinctrl *rx_pinctrl; + struct pinctrl_state *rx_gpio_active; + struct pinctrl_state *rx_gpio_suspend; + struct delayed_work wireless_int_work; + struct delayed_work wpc_det_work; + struct delayed_work chg_monitor_work; + struct delayed_work chg_detect_work; + struct delayed_work reverse_sent_state_work; + struct delayed_work reverse_chg_state_work; + struct delayed_work reverse_dping_state_work; + struct delayed_work dc_check_work; + struct delayed_work cmd_timeout_work; + struct delayed_work fw_download_work; + struct delayed_work pan_tx_work; + struct delayed_work voice_tx_work; + struct delayed_work rx_first_boot; + struct mutex wireless_chg_lock; + struct mutex wireless_chg_int_lock; + struct mutex sysfs_op_lock; + + struct power_supply *wip_psy; + struct power_supply *dc_psy; + struct power_supply_desc wip_psy_d; + struct power_supply *wireless_psy; + struct power_supply *batt_psy; + struct power_supply *usb_psy; + struct power_supply *pc_port_psy; + struct power_supply *ln_psy; + struct alarm reverse_dping_alarm; + struct alarm reverse_chg_alarm; + struct alarm cmd_timeout_alarm; + int epp; + int auth; + int op_mode; + int dcin_present; + u8 epp_max_power; + int target_vol; + int target_curr; + int is_vin_limit; + int epp_exchange; + int count_5v; + int count_9v; + int count_10v; + int count_15v; + int status; + int last_vin; + int last_icl; + int exchange; + int last_qc3_icl; + int power_off_mode; + + /* product related */ + bool wireless_by_usbin; + int power_good_flag; + int ss; + int is_reverse_chg; + int is_reverse_gpio; + u8 fod_mode; + int is_car_tx; + int is_voice_box_tx; + int is_compatible_hwid; + int is_f1_tx; + u8 epp_tx_id_h; + u8 epp_tx_id_l; + u8 *rx_fw_bin; + int rx_fw_len; + bool enabled_aicl; + bool fw_update; + int fw_version; + int chip_ok; + int hw_country; + int reverse_gpio_state; + int is_otg_insert; + int is_pan_tx; + bool disable_bq; + struct votable *fcc_votable; +}; + +/*extern char *saved_command_line; +static int get_board_version(void) +{ + char boot[5] = {'\0'}; + char *match = (char *) strnstr(saved_command_line, + "androidboot.hwlevel=", + strlen(saved_command_line)); + if (match) { + memcpy(boot, (match + strlen("androidboot.hwlevel=")), + sizeof(boot) - 1); + printk("%s: hwlevel is %s\n", __func__, boot); + if (!strncmp(boot, "P1.2", strlen("P1.2"))) + return 1; + else if (!strncmp(boot, "P1.6", strlen("P1.6"))) + return 1; + } + return 0; +}*/ + +static int rx1619_read(struct rx1619_chg *chip, u8 *val, u16 addr) +{ + unsigned int temp; + int rc; + + rc = regmap_read(chip->regmap, addr, &temp); + if (rc >= 0) { + *val = (u8)temp; + //dev_err(chip->dev, "[rx1619] [%s] [0x%04x] = [0x%x] \n", __func__, addr, *val); + } + + return rc; +} + +static int rx1619_write(struct rx1619_chg *chip, u8 val, u16 addr) +{ + int rc = 0; + + rc = regmap_write(chip->regmap, addr, val); + if (rc >= 0) { + //dev_err(chip->dev, "[rx1619] [%s] [0x%04x] = [0x%x] \n", __func__, addr, *val); + } + + return rc; +} + +//mode1: gain_code = gain/1000*65535/100; offset_code = offset/100 +//mode2,3,4: gain_code = gain/1000*65535; offset_code = offset/10 +void rx1619_set_fod_param(struct rx1619_chg *chip, u8 mode) +{ + rx1619_write(chip, 0x85, REG_RX_SENT_CMD); //send fod parameters + + if (mode == 1) { + rx1619_write(chip, 0x1, REG_RX_SENT_DATA1); + rx1619_write(chip, fod_param[0], REG_RX_SENT_DATA2); + rx1619_write(chip, fod_param[1], REG_RX_SENT_DATA3); + chip->fod_mode = 0x1; + dev_info(chip->dev, "[%s] 0x%x,0x%x \n", __func__, fod_param[0], + fod_param[1]); + } else if (mode == 2) { + rx1619_write(chip, 0x2, REG_RX_SENT_DATA1); + rx1619_write(chip, fod_param[2], REG_RX_SENT_DATA2); + rx1619_write(chip, fod_param[3], REG_RX_SENT_DATA3); + chip->fod_mode = 0x2; + dev_info(chip->dev, "[%s] 0x%x,0x%x \n", __func__, fod_param[2], + fod_param[3]); + } else if (mode == 3) { + rx1619_write(chip, 0x3, REG_RX_SENT_DATA1); + rx1619_write(chip, fod_param[4], REG_RX_SENT_DATA2); + rx1619_write(chip, fod_param[5], REG_RX_SENT_DATA3); + chip->fod_mode = 0x3; + dev_info(chip->dev, "[%s] 0x%x,0x%x \n", __func__, fod_param[4], + fod_param[5]); + } else if (mode == 4) { + rx1619_write(chip, 0x4, REG_RX_SENT_DATA1); + rx1619_write(chip, fod_param[6], REG_RX_SENT_DATA2); + rx1619_write(chip, fod_param[7], REG_RX_SENT_DATA3); + chip->fod_mode = 0x4; + dev_info(chip->dev, "[%s] 0x%x,0x%x \n", __func__, fod_param[6], + fod_param[7]); + } + + rx1619_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); + dev_info(chip->dev, "[%s] mode = 0x%x \n", __func__, mode); +} + +void rx1619_set_adap_vol(struct rx1619_chg *chip, u16 mv) +{ + dev_info(chip->dev, "set adapter vol to %d\n", mv); + rx1619_write(chip, PRIVATE_FAST_CHG_CMD, + REG_RX_SENT_CMD); //0x87 usb type req + rx1619_write(chip, mv & 0xff, REG_RX_SENT_DATA1); //LSB + rx1619_write(chip, (mv >> 8) & 0xff, REG_RX_SENT_DATA2); //MSB + rx1619_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); +} + +void rx1619_request_uuid(struct rx1619_chg *chip, int is_epp) +{ + rx1619_write(chip, UUID_CMD, REG_RX_SENT_CMD); //0x8f request high addr + + if (is_epp) { + rx1619_write(chip, 0x4C, REG_RX_SENT_DATA1); + chip->is_compatible_hwid = 0; + } else { + rx1619_write(chip, 0x3F, REG_RX_SENT_DATA1); + chip->is_compatible_hwid = 1; + } + + rx1619_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); //0x8b sent BLEOK +} + +void rx1619_retry_id_auth(struct rx1619_chg *chip) +{ + rx1619_write(chip, PRIVATE_ID_CMD, REG_RX_SENT_CMD); + rx1619_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); +} + +void rx1619_send_device_auth(struct rx1619_chg *chip) +{ + rx1619_write(chip, PRIVATE_USB_TYPE_CMD, REG_RX_SENT_CMD); + rx1619_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); +} + +static int rx_get_property_names(struct rx1619_chg *chip) +{ + chip->batt_psy = power_supply_get_by_name("battery"); + if (!chip->batt_psy) { + dev_err(chip->dev, "no batt_psy,return\n"); + return -EINVAL; + } + + chip->dc_psy = power_supply_get_by_name("dc"); + if (!chip->dc_psy) { + dev_err(chip->dev, "no dc_psy,return\n"); + return -EINVAL; + } + + chip->wireless_psy = power_supply_get_by_name("wireless"); + if (!chip->wireless_psy) { + dev_err(chip->dev, "no wireless_psy,return\n"); + return -EINVAL; + } + + chip->usb_psy = power_supply_get_by_name("usb"); + if (!chip->usb_psy) { + dev_err(chip->dev, "[idt] no usb_psy,return\n"); + return -EINVAL; + } + + chip->pc_port_psy = power_supply_get_by_name("pc_port"); + if (!chip->pc_port_psy) { + dev_err(chip->dev, "[idt] no pc_port_psy,return\n"); + return -EINVAL; + } + + return 0; +} +/* +reverse charging function +*/ +unsigned int rx1619_start_tx_function(struct rx1619_chg *chip) +{ + u16 ret = 0; + + ret = rx1619_write(chip, 0x20, 0x000d); //0x10 rx, 0x20 tx + dev_info(chip->dev, "[%s] ret = %d\n", __func__, ret); + + return ret; +} + +unsigned int rx1619_is_tx_mode(struct rx1619_chg *chip) +{ + u8 data = 0; + + rx1619_read(chip, &data, 0x000d); + dev_info(chip->dev, "[%s] data = %d\n", __func__, data); + if (data == 0x20) + return 1; + else + return 0; +} + +/* +0x00 close TX mode +0x11 none otg mode +0x12 otg mode +*/ +/* +unsigned char rx1619_set_tx_mode(struct rx1619_chg *chip, u8 mode) +{ + u8 ret = 0; + + ret = rx1619_write(chip, mode, 0x0000); + dev_info(chip->dev, "[%s] mode = %d\n", __func__, mode); + + return ret; +} +*/ + +/* +unsigned int rx1619_get_tx_iout(struct rx1619_chg *chip) +{ + u8 data = 0; + u32 tx_iout = 0; + + //Iout = 2.5(A)*value/256 + rx1619_read(chip, &data, 0x0008);//0x0008 + tx_iout = 2500*data/256; + dev_err(chip->dev, "[rx1619] [%s] data=%d, tx_iout=%d \n", __func__, data,tx_iout); + + return tx_iout; +} + + +unsigned int rx1619_get_tx_vout(struct rx1619_chg *chip) +{ + u8 data = 0; + u32 tx_vout = 0; + + //Vout = 22.5(V)*value/256 + rx1619_read(chip, &data, 0x0009);//0x0009 + tx_vout = 22500*data/256; + dev_err(chip->dev, "[rx1619] [%s] data=%d, tx_vout=%d \n", __func__, data,tx_vout); + + return tx_vout; +} +*/ + +#define TX_NORMAL 0x00 +#define TX_OVP 0x01 +#define TX_OCP 0x02 +#define TX_UV 0x03 +#define TX_OTP 0x04 +#define TX_FOD 0x05 +#define TX_LOW 0x06 + +unsigned char rx1619_get_tx_status(struct rx1619_chg *chip) +{ + u8 data = 0; + + rx1619_read(chip, &data, 0x000a); //0x000a + dev_err(chip->dev, "[%s] data=%d\n", __func__, data); + + return data; +} + +/* +init 0x00 +ping phase 0x1 +power transfer 0x02 +power limit 0x03 +*/ +#define PING 0x1 +#define TRANSFER 0x2 +#define POWER_LIM 0x3 +#define CONFIGURE_CNF 0x4 +#define CONFIGURE_ERR 0x5 + +unsigned char rx1619_get_tx_phase(struct rx1619_chg *chip) +{ + u8 data = 0; + + rx1619_read(chip, &data, 0x000b); + dev_info(chip->dev, "[%s] data=%d\n", __func__, data); + + return data; +} + +unsigned int rx1619_get_rx_vrect(struct rx1619_chg *chip) +{ + u16 vrect = 0; + u8 data = 0; + + rx1619_read(chip, &data, 0x000A); //vrect-0x000A + vrect = (data * 27500) >> 8; + dev_err(chip->dev, "[rx1619] [%s] data=%d, Vrect=%d mV \n", __func__, + data, vrect); + + return vrect; +} + +unsigned int rx1619_get_rx_vout(struct rx1619_chg *chip) +{ + u16 vout = 0; + u8 data = 0; + + rx1619_read(chip, &data, 0x0009); //vout-0x0009 + vout = (int)(data * 22500) >> 8; + dev_err(chip->dev, "[rx1619] [%s] data=%d, Vout=%d mV \n", __func__, + data, vout); + + return vout; +} + +unsigned int rx1619_get_rx_iout(struct rx1619_chg *chip) +{ + u16 iout = 0; + u8 data = 0; + + rx1619_read(chip, &data, 0x000B); //Iout-0x000B + iout = (int)(data * 2500) >> 8; + dev_err(chip->dev, "[rx1619] [%s] data=%d, iout=%d mA \n", __func__, + data, iout); + + return iout; +} + +int rx1619_set_vout(struct rx1619_chg *chip, int volt) +{ + u8 value_h, value_l, ret; + u16 vout_set, vrect_set; + + if ((volt < 4000) && (volt > 21000)) { + volt = 6000; //6V + } + + volt += g_Delta; + dev_info(chip->dev, "[rx1619] [%s] volt = %d, g_Delta=%d \n", __func__, + volt, g_Delta); + + vout_set = (u16)((volt * 3352) >> 16); //(u16)(volt*1023/20000) + vrect_set = + (u16)(((volt + 200) * 2438) >> 16); //((volt+200)*1023/27500) + /* + dev_info(chip->dev, "[rx1619] [%s] vout_set = 0x%x, vrect_set=0x%x \n", + __func__, vout_set, vrect_set); +*/ + + value_h = (u8)(vout_set >> 8); + value_l = (u8)(vout_set & 0xFF); + ret = rx1619_write(chip, value_h, 0x0001); + ret = rx1619_write(chip, value_l, 0x0002); + /* + dev_info(chip->dev, "[rx1619] [%s] vout value_h = 0x%x, value_l=0x%x \n", + __func__, value_h, value_l); +*/ + + value_h = (u8)(vrect_set >> 8); + value_l = (u8)(vrect_set & 0xFF); + ret = rx1619_write(chip, value_h, 0x0003); + ret = rx1619_write(chip, value_l, 0x0004); + /* + dev_info(chip->dev, "[rx1619] [%s] vrect value_h = 0x%x, value_l=0x%x \n", + __func__, value_h, value_l); +*/ + + ret = rx1619_write(chip, 0x80, 0x0000); + ret = rx1619_write(chip, 0x55, 0x000C); + + return ret; +} + +bool rx1619_is_vout_on(struct rx1619_chg *chip) +{ + bool vout_status = false; + unsigned int voltage = 0; + + voltage = rx1619_get_rx_vout(chip); + + dev_err(chip->dev, "[rx1619] [%s] Vout = %d \n", __func__, voltage); + + if ((voltage > MIN_VOUT) && (voltage < MAX_VOUT)) //4V~15V + { + vout_status = true; + } else { + vout_status = false; + } + + return vout_status; +} + +#define REVERSE_PARAM_CMD 0x13 +#define REVERSE_PARAM_CMD_ADDR 0x0000 +#define REVERSE_PARAM_MODE_ADDE 0x0001 +#define REVERSE_PARAM_IIN_ADDR 0x0002 + +static void rx1619_set_reverse_parameter(struct rx1619_chg *chip, u8 mode, + u8 iin) +{ + dev_info(chip->dev, "mode: %d, iin:%d\n", mode, iin); + rx1619_write(chip, REVERSE_PARAM_CMD, REVERSE_PARAM_CMD_ADDR); + rx1619_write(chip, mode, REVERSE_PARAM_MODE_ADDE); + rx1619_write(chip, iin, REVERSE_PARAM_IIN_ADDR); + return; +} + +#define REVERSE_FOD_COMPENSATION_ADDR 0x0003 +#define REVERSE_FOD_THRESHOLD_ADDR 0x0004 + +static void rx1619_set_reverse_fod(struct rx1619_chg *chip, u8 compensation, + u8 threshold) +{ + dev_info(chip->dev, "compensation: %d, threshold:%d\n", compensation, + threshold); + rx1619_write(chip, compensation, REVERSE_FOD_COMPENSATION_ADDR); + rx1619_write(chip, threshold, REVERSE_FOD_THRESHOLD_ADDR); + return; +} + +static void determine_initial_status(struct rx1619_chg *chip) +{ + bool vout_on = false; + + vout_on = rx1619_is_vout_on(chip); + if (vout_on) { + g_rx1619_restart_flag = true; + } + + dev_err(chip->dev, "[%s] initial vout_on = %d \n", __func__, vout_on); +} + +static bool rx1619_check_firmware_version(struct rx1619_chg *chip, u8 area) +{ + static u16 addr; + u8 addr_h, addr_l; + int i = 0; + u8 read_buf[20]; + char *fw_data = NULL; + + dev_err(chip->dev, "[rx1619] [%s] enter \n", __func__); + + if (area == BOOT_AREA) { + addr = 0; + g_fw_data_lenth = sizeof(fw_data_boot); + fw_data = fw_data_boot; + } else if (area == RX_AREA) { + addr = 256; + g_fw_data_lenth = sizeof(fw_data_rx); + fw_data = fw_data_rx; + } else if (area == TX_AREA) { + addr = 4864; + g_fw_data_lenth = sizeof(fw_data_tx); + fw_data = fw_data_tx; + } + + /************prepare_for_mtp_read************/ + rx1619_write(chip, 0x69, 0x2017); + rx1619_write(chip, 0x96, 0x2017); + rx1619_write(chip, 0x66, 0x2017); + rx1619_write(chip, 0x99, 0x2017); + rx1619_write(chip, 0xff, 0x2018); + rx1619_write(chip, 0xff, 0x2019); + rx1619_write(chip, 0x5a, 0x0001); + rx1619_write(chip, 0xa5, 0x0003); + + rx1619_write(chip, 0x01, 0x0017); + /************prepare_for_mtp_read************/ + + msleep(10); + + /*************read 12 byte before fw_data_end addr************/ + addr += (g_fw_data_lenth / 4); + + for (i = 0; i < 12; i += 4) { + /************write_mtp_addr************/ + addr_h = (u8)(addr >> 8); + addr_l = (u8)(addr & 0xff); + rx1619_write(chip, addr_h, 0x0010); + rx1619_write(chip, addr_l, 0x0011); + /************write_mtp_addr************/ + + addr--; + + /************read pause************/ + rx1619_write(chip, 0x02, 0x0018); + rx1619_write(chip, 0x00, 0x0018); + /************read pause************/ + + /************read data************/ + rx1619_read(chip, &read_buf[i + 3], 0x0013); + rx1619_read(chip, &read_buf[i + 2], 0x0014); + rx1619_read(chip, &read_buf[i + 1], 0x0015); + rx1619_read(chip, &read_buf[i + 0], 0x0016); + /************read data************/ + } + /*************read 12 byte before fw_data_end addr************/ + + /***********end************/ + rx1619_write(chip, 0x00, 0x0017); + /***********end************/ + + /************exit dtm************/ + rx1619_write(chip, 0x00, 0x2018); + rx1619_write(chip, 0x00, 0x2019); + rx1619_write(chip, 0x00, 0x0001); + rx1619_write(chip, 0x00, 0x0003); + rx1619_write(chip, 0x55, 0x2017); + /************exit dtm************/ + + dev_info(chip->dev, "confirm data =0x%x, 0x%x, 0x%x, 0x%x\n", + read_buf[0], read_buf[1], read_buf[2], read_buf[3]); + + dev_info( + chip->dev, + "chip_data version=0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", + read_buf[4], read_buf[5], read_buf[6], read_buf[7], read_buf[8], + read_buf[9], read_buf[10], read_buf[11]); + + dev_info( + chip->dev, + "fw_data version=0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", + fw_data[g_fw_data_lenth - 4], fw_data[g_fw_data_lenth - 3], + fw_data[g_fw_data_lenth - 2], fw_data[g_fw_data_lenth - 1], + fw_data[g_fw_data_lenth - 8], fw_data[g_fw_data_lenth - 7], + fw_data[g_fw_data_lenth - 6], fw_data[g_fw_data_lenth - 5]); + + if (area == RX_AREA) { + if (read_buf[0] == 0x66) { + g_project_id_h = (~read_buf[5]); + g_project_id_l = (~read_buf[6]); + g_fw_rx_id = (~read_buf[7]); + g_hw_id_h = (~read_buf[10]); + g_hw_id_l = (~read_buf[11]); + } else { + g_project_id_h = 0x00; + g_project_id_l = 0x00; + g_fw_rx_id = FW_ERROR_CODE; + g_hw_id_h = 0x00; + g_hw_id_l = 0x00; + } + } else if (area == TX_AREA) { + if (read_buf[0] == 0x66) { + g_project_id_h = (~read_buf[5]); + g_project_id_l = (~read_buf[6]); + g_fw_tx_id = (~read_buf[7]); + } else { + g_project_id_h = 0x00; + g_project_id_l = 0x00; + g_fw_tx_id = FW_ERROR_CODE; + } + } else if (area == BOOT_AREA) { + if (read_buf[0] == 0x66) { + g_project_id_h = (~read_buf[5]); + g_project_id_l = (~read_buf[6]); + g_fw_boot_id = (~read_buf[7]); + } else { + g_project_id_h = 0x00; + g_project_id_l = 0x00; + g_fw_boot_id = FW_ERROR_CODE; + } + } + + if ((read_buf[7] == fw_data[g_fw_data_lenth - 1]) && + (read_buf[0] == + 0x66)) { //read_buf[7] is vesion, read_buf[0] is confirm value + dev_info(chip->dev, "g_fw_data_lenth=%d, fw version = 0x%x\n", + g_fw_data_lenth, (~read_buf[7]) & 0xff); + return true; + } + + return false; +} + +static bool rx1619_update_fw_confirm_data(struct rx1619_chg *chip, u8 area, + u8 confirm_data) +{ + u16 addr = 0; + u8 addr_h, addr_l; + u8 data[4] = { 0, 0, 0, 0 }; + + /************prepare_for_mtp_write************/ + rx1619_write(chip, 0x69, 0x2017); + rx1619_write(chip, 0x96, 0x2017); + rx1619_write(chip, 0x66, 0x2017); + rx1619_write(chip, 0x99, 0x2017); + rx1619_write(chip, 0xff, 0x2018); + rx1619_write(chip, 0xff, 0x2019); + rx1619_write(chip, 0x5a, 0x0001); + rx1619_write(chip, 0xa5, 0x0003); + + // rx1619_write(chip, 0x19, 0x0018); + rx1619_write(chip, 0x10, 0x1000); + rx1619_write(chip, 0x3e, 0x1130); + /************prepare_for_mtp_write************/ + + msleep(20); + + /************write_mtp_addr************/ + if (area == BOOT_AREA) { + addr = 0; + g_fw_data_lenth = sizeof(fw_data_boot); + } else if (area == RX_AREA) { + addr = 256; + g_fw_data_lenth = sizeof(fw_data_rx); + } else if (area == TX_AREA) { + addr = 4864; + g_fw_data_lenth = sizeof(fw_data_tx); + } + + addr += (g_fw_data_lenth / 4); + + addr_h = (u8)(addr >> 8); + addr_l = (u8)(addr & 0xff); + rx1619_write(chip, addr_h, 0x0010); + rx1619_write(chip, addr_l, 0x0011); + /************write_mtp_addr************/ + + /************enable write************/ + rx1619_write(chip, 0x01, 0x0017); + rx1619_write(chip, 0x30, 0x1000); + rx1619_write(chip, 0x5a, 0x001a); + /************enable write************/ + + /************write data************/ + usleep_range(2000, 2100); + rx1619_write(chip, 0x00, 0x0012); + usleep_range(2000, 2100); + rx1619_write(chip, 0x00, 0x0012); + usleep_range(2000, 2100); + rx1619_write(chip, 0x00, 0x0012); + usleep_range(2000, 2100); + rx1619_write(chip, confirm_data, 0x0012); + /************write data************/ + + /************end************/ + rx1619_write(chip, 0x00, 0x001a); + rx1619_write(chip, 0x00, 0x0017); + /************end************/ + + /************exit dtm************/ + rx1619_write(chip, 0x00, 0x2018); + rx1619_write(chip, 0x00, 0x2019); + rx1619_write(chip, 0x00, 0x0001); + rx1619_write(chip, 0x00, 0x0003); + rx1619_write(chip, 0x55, 0x2017); + /************exit dtm************/ + + msleep(100); // + + /************prepare_for_mtp_read************/ + rx1619_write(chip, 0x69, 0x2017); + rx1619_write(chip, 0x96, 0x2017); + rx1619_write(chip, 0x66, 0x2017); + rx1619_write(chip, 0x99, 0x2017); + rx1619_write(chip, 0xff, 0x2018); + rx1619_write(chip, 0xff, 0x2019); + rx1619_write(chip, 0x5a, 0x0001); + rx1619_write(chip, 0xa5, 0x0003); + + rx1619_write(chip, 0x01, 0x0017); + /************prepare_for_mtp_read************/ + + msleep(10); + + /************write_mtp_addr************/ + addr_h = (u8)(addr >> 8); + addr_l = (u8)(addr & 0xff); + rx1619_write(chip, addr_h, 0x0010); + rx1619_write(chip, addr_l, 0x0011); + /************write_mtp_addr************/ + + /************read pause************/ + rx1619_write(chip, 0x02, 0x0018); + rx1619_write(chip, 0x00, 0x0018); + /************read pause************/ + + /************read data************/ + rx1619_read(chip, &data[3], 0x0013); + rx1619_read(chip, &data[2], 0x0014); + rx1619_read(chip, &data[1], 0x0015); + rx1619_read(chip, &data[0], 0x0016); + /************read data************/ + + /***********end************/ + rx1619_write(chip, 0x00, 0x0017); + /***********end************/ + + /************exit dtm************/ + rx1619_write(chip, 0x00, 0x2018); + rx1619_write(chip, 0x00, 0x2019); + rx1619_write(chip, 0x00, 0x0001); + rx1619_write(chip, 0x00, 0x0003); + rx1619_write(chip, 0x55, 0x2017); + /************exit dtm************/ + + dev_err(chip->dev, "addr=%d confirm data = 0x%x, 0x%x, 0x%x, 0x%x\n", + addr, data[0], data[1], data[2], data[3]); + + if (data[0] == confirm_data) { + dev_err(chip->dev, "Update Confirm data Success!!!\n"); + return true; + } else { + dev_err(chip->dev, "Update Confirm data Failed!!! \n"); + return false; + } +} + +static bool rx1619_download_firmware(struct rx1619_chg *chip, u8 area) +{ + u16 addr = 0; + u8 addr_h, addr_l; + int i = 0; + u8 j = 0; + char *fw_data = NULL; + u32 count = 0; + + dev_err(chip->dev, "[rx1619] [%s] enter \n", __func__); + + /************prepare_for_mtp_write************/ + rx1619_write(chip, 0x69, 0x2017); + rx1619_write(chip, 0x96, 0x2017); + rx1619_write(chip, 0x66, 0x2017); + rx1619_write(chip, 0x99, 0x2017); + rx1619_write(chip, 0xff, 0x2018); + rx1619_write(chip, 0xff, 0x2019); + rx1619_write(chip, 0x5a, 0x0001); + rx1619_write(chip, 0xa5, 0x0003); + + // rx1619_write(chip, 0x19, 0x0018); + rx1619_write(chip, 0x10, 0x1000); + rx1619_write(chip, 0x3e, 0x1130); + /************prepare_for_mtp_write************/ + + msleep(20); + + /************write_mtp_addr************/ + if (area == BOOT_AREA) { + addr = 0; + g_fw_data_lenth = sizeof(fw_data_boot); + fw_data = fw_data_boot; + } else if (area == RX_AREA) { + addr = 256; + g_fw_data_lenth = sizeof(fw_data_rx); + fw_data = fw_data_rx; + } else if (area == TX_AREA) { + addr = 4864; + g_fw_data_lenth = sizeof(fw_data_tx); + fw_data = fw_data_tx; + } + addr_h = (u8)(addr >> 8); + addr_l = (u8)(addr & 0xff); + rx1619_write(chip, addr_h, 0x0010); + rx1619_write(chip, addr_l, 0x0011); + /************write_mtp_addr************/ + + /************enable write************/ + rx1619_write(chip, 0x01, 0x0017); + rx1619_write(chip, 0x30, 0x1000); + rx1619_write(chip, 0x5a, 0x001a); + /************enable write************/ + + /************write data************/ + for (i = 0; i < g_fw_data_lenth; i += 4) { + rx1619_write(chip, fw_data[i + 3], 0x0012); + for (j = 0; j < 4; j++) { + if (gpio_get_value(chip->power_good_gpio) == 1) { + usleep_range(300, 350); + if (gpio_get_value(chip->power_good_gpio) == + 0) { + break; + } + } else if (gpio_get_value(chip->power_good_gpio) == 0) { + usleep_range(900, 950); + count++; + break; + } + } + + rx1619_write(chip, fw_data[i + 2], 0x0012); + for (j = 0; j < 4; j++) { + if (gpio_get_value(chip->power_good_gpio) == 1) { + usleep_range(300, 350); + if (gpio_get_value(chip->power_good_gpio) == + 0) { + break; + } + } else if (gpio_get_value(chip->power_good_gpio) == 0) { + usleep_range(900, 950); + count++; + break; + } + } + + rx1619_write(chip, fw_data[i + 1], 0x0012); + for (j = 0; j < 4; j++) { + if (gpio_get_value(chip->power_good_gpio) == 1) { + usleep_range(300, 350); + if (gpio_get_value(chip->power_good_gpio) == + 0) { + break; + } + } else if (gpio_get_value(chip->power_good_gpio) == 0) { + usleep_range(900, 950); + count++; + break; + } + } + + rx1619_write(chip, fw_data[i + 0], 0x0012); + for (j = 0; j < 4; j++) { + if (gpio_get_value(chip->power_good_gpio) == 1) { + usleep_range(300, 350); + if (gpio_get_value(chip->power_good_gpio) == + 0) { + break; + } + } else if (gpio_get_value(chip->power_good_gpio) == 0) { + usleep_range(900, 950); + count++; + break; + } + } + } + /************write data************/ + + /************end************/ + rx1619_write(chip, 0x00, 0x001a); + rx1619_write(chip, 0x00, 0x0017); + /************end************/ + + /************exit dtm************/ + rx1619_write(chip, 0x00, 0x2018); + rx1619_write(chip, 0x00, 0x2019); + rx1619_write(chip, 0x00, 0x0001); + rx1619_write(chip, 0x00, 0x0003); + rx1619_write(chip, 0x55, 0x2017); + /************exit dtm************/ + + dev_err(chip->dev, + "[rx1619] [%s] area=%d,addr=%d, g_fw_data_lenth=%d, count=%d\n", + __func__, area, addr, g_fw_data_lenth, count); + dev_err(chip->dev, "[rx1619] [%s] exit \n", __func__); + + return 0; +} + +static int rx1619_check_firmware(struct rx1619_chg *chip, u8 area) +{ + u32 success_count = 0; + u16 addr = 0; + u8 addr_h, addr_l; + int i = 0; + int j = 0; + u8 read_buf[4] = { 0, 0, 0, 0 }; + char *fw_data = NULL; + + success_count = 0; + + dev_info(chip->dev, "[rx1619] [%s] enter \n", __func__); + + if (area == BOOT_AREA) { + addr = 0; + g_fw_data_lenth = sizeof(fw_data_boot); + fw_data = fw_data_boot; + } else if (area == RX_AREA) { + addr = 256; + g_fw_data_lenth = sizeof(fw_data_rx); + fw_data = fw_data_rx; + } else if (area == TX_AREA) { + addr = 4864; + g_fw_data_lenth = sizeof(fw_data_tx); + fw_data = fw_data_tx; + } + + /************prepare_for_mtp_read************/ + rx1619_write(chip, 0x69, 0x2017); + rx1619_write(chip, 0x96, 0x2017); + rx1619_write(chip, 0x66, 0x2017); + rx1619_write(chip, 0x99, 0x2017); + rx1619_write(chip, 0xff, 0x2018); + rx1619_write(chip, 0xff, 0x2019); + rx1619_write(chip, 0x5a, 0x0001); + rx1619_write(chip, 0xa5, 0x0003); + + rx1619_write(chip, 0x01, 0x0017); + /************prepare_for_mtp_read************/ + + msleep(10); + + for (i = 0; i < g_fw_data_lenth; i += 4) { + /************write_mtp_addr************/ + addr_h = (u8)(addr >> 8); + addr_l = (u8)(addr & 0xff); + rx1619_write(chip, addr_h, 0x0010); + rx1619_write(chip, addr_l, 0x0011); + /************write_mtp_addr************/ + + addr++; + + /************read pause************/ + rx1619_write(chip, 0x02, 0x0018); + rx1619_write(chip, 0x00, 0x0018); + /************read pause************/ + + /************read data************/ + rx1619_read(chip, &read_buf[3], 0x0013); + rx1619_read(chip, &read_buf[2], 0x0014); + rx1619_read(chip, &read_buf[1], 0x0015); + rx1619_read(chip, &read_buf[0], 0x0016); + /************read data************/ + + if ((read_buf[0] == fw_data[i + 0]) && + (read_buf[1] == fw_data[i + 1]) && + (read_buf[2] == fw_data[i + 2]) && + (read_buf[3] == fw_data[i + 3])) { + success_count++; + } else { + j++; + if (j >= 50) { //if error adrr >= 50,new IC + goto CCC; + } + } + } + +CCC: + /***********end************/ + rx1619_write(chip, 0x00, 0x0017); + /***********end************/ + + /************exit dtm************/ + rx1619_write(chip, 0x00, 0x2018); + rx1619_write(chip, 0x00, 0x2019); + rx1619_write(chip, 0x00, 0x0001); + rx1619_write(chip, 0x00, 0x0003); + rx1619_write(chip, 0x55, 0x2017); + /************exit dtm************/ + + dev_err(chip->dev, "error_conut= %d, success_count=%d\n", j, + success_count); + + dev_info( + chip->dev, + "(sizeof(fw_data_boot)) = %ld (sizeof(fw_data_rx)) = %ld (sizeof(fw_data_tx)) = %ld \n", + (sizeof(fw_data_boot)), (sizeof(fw_data_rx)), + (sizeof(fw_data_tx))); + + return success_count; +} + +static bool rx1619_push_rx_firmware(struct rx1619_chg *chip) +{ + u16 addr = 256; + u8 addr_h, addr_l; + int i = 0; + int j = 0; + u8 read_buf[4] = { 0, 0, 0, 0 }; + char *fw_data = NULL; + int pass_count = 0; + + if (chip->rx_fw_bin == NULL) { + dev_err(chip->dev, "[rx1619] g_chip->rx_fw_bin == NULL \n"); + return false; + } + + dev_err(chip->dev, "[rx1619] g_chip->rx_fw_bin != NULL \n"); + dev_err(chip->dev, "[rx1619] [%s] download rx enter \n", __func__); + + addr = 256; + g_fw_data_lenth = chip->rx_fw_len; + fw_data = chip->rx_fw_bin; + + /************prepare_for_mtp_write************/ + rx1619_write(chip, 0x69, 0x2017); + rx1619_write(chip, 0x96, 0x2017); + rx1619_write(chip, 0x66, 0x2017); + rx1619_write(chip, 0x99, 0x2017); + rx1619_write(chip, 0xff, 0x2018); + rx1619_write(chip, 0xff, 0x2019); + rx1619_write(chip, 0x5a, 0x0001); + rx1619_write(chip, 0xa5, 0x0003); + + //rx1619_write(chip, 0x19, 0x0018); + rx1619_write(chip, 0x10, 0x1000); + rx1619_write(chip, 0x3e, 0x1130); + /************prepare_for_mtp_write************/ + + msleep(20); + + /************write_mtp_addr************/ + addr_h = (u8)(addr >> 8); + addr_l = (u8)(addr & 0xff); + rx1619_write(chip, addr_h, 0x0010); + rx1619_write(chip, addr_l, 0x0011); + /************write_mtp_addr************/ + + /************enable write************/ + rx1619_write(chip, 0x01, 0x0017); + rx1619_write(chip, 0x30, 0x1000); + rx1619_write(chip, 0x5a, 0x001a); + /************enable write************/ + + /************write data************/ + for (i = 0; i < g_fw_data_lenth; i += 4) { + rx1619_write(chip, 0xff & (~fw_data[i + 3]), 0x0012); + usleep_range(1000, 1100); + rx1619_write(chip, 0xff & (~fw_data[i + 2]), 0x0012); + usleep_range(1000, 1100); + rx1619_write(chip, 0xff & (~fw_data[i + 1]), 0x0012); + usleep_range(1000, 1100); + rx1619_write(chip, 0xff & (~fw_data[i + 0]), 0x0012); + usleep_range(1000, 1100); + } + /************write data************/ + + /************end************/ + rx1619_write(chip, 0x00, 0x001a); + rx1619_write(chip, 0x00, 0x0017); + /************end************/ + + /************exit dtm************/ + rx1619_write(chip, 0x00, 0x2018); + rx1619_write(chip, 0x00, 0x2019); + rx1619_write(chip, 0x00, 0x0001); + rx1619_write(chip, 0x00, 0x0003); + rx1619_write(chip, 0x55, 0x2017); + /************exit dtm************/ + + dev_err(chip->dev, "[rx1619] [%s] download rx exit \n", __func__); + + msleep(500); + + dev_info(chip->dev, "[rx1619] [%s] check rx enter \n", __func__); + pass_count = 0; + + /************prepare_for_mtp_read************/ + rx1619_write(chip, 0x69, 0x2017); + rx1619_write(chip, 0x96, 0x2017); + rx1619_write(chip, 0x66, 0x2017); + rx1619_write(chip, 0x99, 0x2017); + rx1619_write(chip, 0xff, 0x2018); + rx1619_write(chip, 0xff, 0x2019); + rx1619_write(chip, 0x5a, 0x0001); + rx1619_write(chip, 0xa5, 0x0003); + + rx1619_write(chip, 0x01, 0x0017); + /************prepare_for_mtp_read************/ + + msleep(10); + + for (i = 0; i < g_fw_data_lenth; i += 4) { + /************write_mtp_addr************/ + addr_h = (u8)(addr >> 8); + addr_l = (u8)(addr & 0xff); + rx1619_write(chip, addr_h, 0x0010); + rx1619_write(chip, addr_l, 0x0011); + /************write_mtp_addr************/ + + addr++; + + /************read pause************/ + rx1619_write(chip, 0x02, 0x0018); + rx1619_write(chip, 0x00, 0x0018); + /************read pause************/ + + /************read data************/ + rx1619_read(chip, &read_buf[3], 0x0013); + rx1619_read(chip, &read_buf[2], 0x0014); + rx1619_read(chip, &read_buf[1], 0x0015); + rx1619_read(chip, &read_buf[0], 0x0016); + /************read data************/ + + if ((read_buf[0] == (0xff & (~fw_data[i + 0]))) && + (read_buf[1] == (0xff & (~fw_data[i + 1]))) && + (read_buf[2] == (0xff & (~fw_data[i + 2]))) && + (read_buf[3] == (0xff & (~fw_data[i + 3])))) { + pass_count++; + } else { + j++; + if (j >= 50) { + goto CCC; + } + } + } + +CCC: + /***********end************/ + rx1619_write(chip, 0x00, 0x0017); + /***********end************/ + + /************exit dtm************/ + rx1619_write(chip, 0x00, 0x2018); + rx1619_write(chip, 0x00, 0x2019); + rx1619_write(chip, 0x00, 0x0001); + rx1619_write(chip, 0x00, 0x0003); + rx1619_write(chip, 0x55, 0x2017); + /************exit dtm************/ + + dev_err(chip->dev, + "error_conut= %d, pass_count=%d, (sizeof(fw_data_rx)) = %ld \n", + j, pass_count, (sizeof(fw_data_rx))); + + dev_info(chip->dev, "fw_data version=0x%x, 0x%x, 0x%x, 0x%x \n", + 0xff & (~fw_data[g_fw_data_lenth - 4]), + 0xff & (~fw_data[g_fw_data_lenth - 3]), + 0xff & (~fw_data[g_fw_data_lenth - 2]), + 0xff & (~fw_data[g_fw_data_lenth - 1])); + + rx_fw_version = fw_data[g_fw_data_lenth - 1]; + rx_bin_project_id_h = fw_data[g_fw_data_lenth - 3]; + rx_bin_project_id_l = fw_data[g_fw_data_lenth - 2]; + + dev_info(chip->dev, "[rx1619] [%s] check rx exit \n", __func__); + + if (g_fw_data_lenth == (pass_count * 4)) { + dev_info(chip->dev, "[rx1619] [%s] Push rx success! \n", + __func__); + return true; + } else { + dev_info(chip->dev, "[rx1619] [%s] Push rx fail! \n", __func__); + return false; + } +} + +bool rx1619_check_i2c_is_ok(struct rx1619_chg *chip) +{ + u8 read_data = 0; + + rx1619_write(chip, 0x88, 0x0000); + msleep(10); + rx1619_read(chip, &read_data, 0x0000); + + if (read_data == 0x88) { + return true; + } else { + return false; + } +} + +#define RETRY_COUNT 2 +bool rx1619_download_area_firmware(struct rx1619_chg *chip, u8 area) +{ + bool status = false; + u8 count = 0; + u32 ret = 0; + + dev_err(chip->dev, "[rx1619] [%s] enter , area=%d \n", __func__, area); + + if (rx1619_check_firmware_version(chip, area) == true) { + dev_err(chip->dev, + "[rx1619] [%s] Same fw Version, no upgrade required! \n", + __func__); + return true; + } + msleep(20); + +RETRY: + count++; + dev_err(chip->dev, "count=%d \n", count); + status = rx1619_update_fw_confirm_data(chip, area, 0x00); //clear 0 + if (!status) { + return false; + } + rx1619_download_firmware(chip, area); + msleep(20); + ret = rx1619_check_firmware(chip, area); + dev_err(chip->dev, + "download_area:%d success_cout=%d, g_fw_data_lenth=%d\n", area, + ret, g_fw_data_lenth); + if (g_fw_data_lenth == (ret * 4)) { + status = rx1619_update_fw_confirm_data( + chip, area, 0x66); //0x66(check success) + if (!status) { + dev_err(chip->dev, + "area:%d update firmware confirm data fail! \n", + area); + return false; + } else { + dev_info(chip->dev, "download area:%d fw success! \n", + area); + } + } else { + if (count > RETRY_COUNT) { + dev_info(chip->dev, "download area:%d fw failed! \n", + area); + return false; + } else { + goto RETRY; + } + } + + return true; +} + +bool rx1619_onekey_download_firmware(struct rx1619_chg *chip) +{ + bool ret = false; + + dev_err(chip->dev, "[rx1619] [%s] enter \n", __func__); + + if (!rx1619_check_i2c_is_ok(chip)) { + dev_err(chip->dev, " i2c error! \n"); + return false; + } + + ret = rx1619_download_area_firmware(chip, BOOT_AREA); + if (!ret) { + dev_err(chip->dev, "BOOT_AREA download fail!!! \n"); + return false; + } + + msleep(20); + + ret = rx1619_download_area_firmware(chip, RX_AREA); + if (!ret) { + dev_err(chip->dev, "RX_AREA download fail!!! \n"); + return false; + } + + msleep(20); + + ret = rx1619_download_area_firmware(chip, TX_AREA); + if (!ret) { + dev_err(chip->dev, "TX_AREA download fail!!! \n"); + return false; + } + + msleep(20); + + return true; +} + +void rx1619_dump_reg(void) +{ + u8 data[32] = { 0 }; + + rx1619_read(g_chip, &data[0], 0x0000); + rx1619_read(g_chip, &data[1], 0x0001); + rx1619_read(g_chip, &data[2], 0x0002); + rx1619_read(g_chip, &data[3], 0x0003); + rx1619_read(g_chip, &data[4], 0x0004); + rx1619_read(g_chip, &data[5], 0x0005); + rx1619_read(g_chip, &data[6], 0x0008); + rx1619_read(g_chip, &data[7], 0x0009); + rx1619_read(g_chip, &data[8], 0x000A); + rx1619_read(g_chip, &data[9], 0x000B); + rx1619_read(g_chip, &data[10], 0x000C); + rx1619_read(g_chip, &data[11], 0x0020); + rx1619_read(g_chip, &data[12], 0x0021); + rx1619_read(g_chip, &data[13], 0x0022); + rx1619_read(g_chip, &data[14], 0x0023); + rx1619_read(g_chip, &data[15], 0x0024); + + dev_info(g_chip->dev, "reave--[rx1619] [%s] REG:0x0000=0x%x\n", + __func__, data[0]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x0001=0x%x\n", __func__, + data[1]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x0002=0x%x\n", __func__, + data[2]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x0003=0x%x\n", __func__, + data[3]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x0004=0x%x\n", __func__, + data[4]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x0005=0x%x\n", __func__, + data[5]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x0008=0x%x\n", __func__, + data[6]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x0009=0x%x\n", __func__, + data[7]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x000A=0x%x\n", __func__, + data[8]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x000B=0x%x\n", __func__, + data[9]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x000C=0x%x\n", __func__, + data[10]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x0020=0x%x\n", __func__, + data[11]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x0021=0x%x\n", __func__, + data[12]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x0022=0x%x\n", __func__, + data[13]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x0023=0x%x\n", __func__, + data[14]); + dev_info(g_chip->dev, "[rx1619] [%s] REG:0x0024=0x%x\n", __func__, + data[15]); + rx1619_write(g_chip, AP_REV_DATA_OK, REG_AP_RX_COMM); +} + +void rx1619_set_pmi_icl(struct rx1619_chg *chip, int mA) +{ + union power_supply_propval val = { + 0, + }; + + val.intval = mA; + + if (chip->wireless_by_usbin) { + if (!chip->usb_psy) + chip->usb_psy = power_supply_get_by_name("usb"); + + if (chip->usb_psy) + power_supply_set_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, + &val); + + } else { + if (!chip->dc_psy) + chip->dc_psy = power_supply_get_by_name("dc"); + + if (chip->dc_psy) + power_supply_set_property(chip->dc_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, + &val); + } + + dev_info(chip->dev, "[rx1619] [%s] [rx1619] set icl: %d\n", __func__, + val.intval); +} + +void rx1619_get_pmi_icl(struct rx1619_chg *chip) +{ + union power_supply_propval val = { + 0, + }; + + if (chip->wireless_by_usbin) { + if (!chip->usb_psy) + chip->usb_psy = power_supply_get_by_name("usb"); + + if (chip->usb_psy) + power_supply_get_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, + &val); + } else { + if (!chip->dc_psy) + chip->dc_psy = power_supply_get_by_name("dc"); + + if (chip->dc_psy) + power_supply_get_property(chip->dc_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, + &val); + } + + dev_info(chip->dev, "[rx1619] [%s] [rx1619] get icl: %d\n", __func__, + val.intval); + g_current_now = val.intval; +} + +void set_usb_type_current(struct rx1619_chg *chip, u8 data) +{ + int i = 0; + int uA = 0; + //int vol_now = 0; + union power_supply_propval val = { + 0, + }; + + dev_info(chip->dev, "[%s] data=0x%x \n", __func__, data); + + switch (data) { + case 0: //other charger + if ((chip->auth == 0) && (chip->epp == 0)) { //bpp and auth fail + rx1619_set_pmi_icl(chip, DC_OTHER_CURRENT); + dev_info(chip->dev, + "[rx1619] [%s] bpp and no id---800mA \n", + __func__); + } else { //auth ok + rx1619_set_pmi_icl(chip, DC_LOW_CURRENT); + dev_info(chip->dev, + "[rx1619] [%s] bpp and id ok---200mA \n", + __func__); + } + break; + + case 1: + rx1619_set_pmi_icl(chip, DC_SDP_CURRENT); + chip->target_vol = ADAPTER_DEFAULT_VOL; + chip->target_curr = DC_SDP_CURRENT; + break; + + case 2: + case 3: + rx1619_set_pmi_icl(chip, DC_BPP_AUTH_FAIL_CURRENT); + chip->target_vol = ADAPTER_DEFAULT_VOL; + chip->target_curr = DC_BPP_AUTH_FAIL_CURRENT; + break; + + case 5: //QC2-other -- 6.5W + for (i = 0; i <= 8; i++) { + uA = (DC_LOW_CURRENT + 100000 * i); + rx1619_set_pmi_icl(chip, uA); + msleep(100); + } + chip->target_vol = ADAPTER_BPP_QC2_VOL; + chip->target_curr = uA; + break; + + case 6: //QC3-other -- 10W + case 7: //PD-other -- 10W + if (chip->epp) { + for (i = 0; i <= 8; i++) { + uA = (DC_LOW_CURRENT + 200000 * i); + rx1619_set_pmi_icl(chip, uA); + msleep(100); + } + chip->target_vol = ADAPTER_EPP_QC3_VOL; + chip->target_curr = uA; + } else { + for (i = 0; i <= 9; i++) { + uA = (DC_LOW_CURRENT + 100000 * i); + rx1619_set_pmi_icl(chip, uA); + msleep(100); + } + chip->target_vol = ADAPTER_BPP_LIMIT_VOL; + chip->target_curr = uA; + } + chip->last_qc3_icl = chip->target_curr; + break; + + case 8: //fail charger + break; + + case 9: //QC3-27W(20W) + case 10: //PD-27W(20W) + case 11: //PD-27W(20W) + if (chip->op_mode != LN8282_OPMODE_SWITCHING) { + dev_info(chip->dev, + "[20W]not switch mode, don't rise voltage \n"); + break; + } + /* + chip->batt_psy = power_supply_get_by_name("battery"); + if (!chip->batt_psy) { + dev_err(chip->dev, "Battery supply not found\n"); + vol_now = 15000; + } else { + power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_VOLTAGE_NOW, &val); + vol_now = val.intval; + vol_now = (vol_now*4) / 1000 + 200; //delta + } +*/ + chip->target_vol = ADAPTER_EPP_MI_VOL; + rx1619_set_pmi_icl(chip, 1000000); + msleep(100); + if (chip->epp && chip->auth && chip->wireless_psy) { + val.intval = 1; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, &val); + msleep(200); + } + /* for usb-in design, set max usb icl to 1.8A*/ + for (i = 0; i <= 10; i++) { + uA = (USB_20W_PLUS_BASE_CURRENT_UA + 100000 * i); + rx1619_set_pmi_icl(chip, uA); + msleep(100); + } + chip->target_curr = uA; + chip->last_icl = chip->target_curr; + dev_info(chip->dev, "[%s] 27W adapter \n", __func__); + break; + + case 12: //40w + case 13: + case 14: + if (chip->op_mode != LN8282_OPMODE_SWITCHING) { + dev_info(chip->dev, + "[30W]not switch mode, don't rise voltage \n"); + break; + } + /* + chip->batt_psy = power_supply_get_by_name("battery"); + if (!chip->batt_psy) { + dev_err(chip->dev, "Battery supply not found\n"); + vol_now = 15000; + } else { + power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_VOLTAGE_NOW, &val); + vol_now = val.intval; + vol_now = (vol_now*4) / 1000 + 200; //delta + } +*/ + chip->target_vol = ADAPTER_EPP_MI_VOL; + rx1619_set_pmi_icl(chip, 1000000); + msleep(100); + if (chip->epp && chip->auth && chip->wireless_psy) { + val.intval = 1; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, &val); + msleep(200); + } + /* for usb-in design, set max usb icl to 1.8A*/ + for (i = 0; i <= 4; i++) { + uA = (USB_20W_PLUS_BASE_CURRENT_UA + 200000 * i); + rx1619_set_pmi_icl(chip, uA); + msleep(100); + } + chip->target_curr = uA; + chip->last_icl = chip->target_curr; + dev_info(chip->dev, "[%s] 40W adapter \n", __func__); + break; + + default: + dev_info(chip->dev, "[%s] other Usb_type\n", __func__); + break; + } +} + +static void rx_charging_info(struct rx1619_chg *chip) +{ + int vout, iout, vrect; + if (!chip) + return; + + vout = rx1619_get_rx_vout(chip); + iout = rx1619_get_rx_iout(chip); + vrect = rx1619_get_rx_vrect(chip); + + dev_info(chip->dev, "%s:Vout:%dmV, Iout:%dmA, Vrect:%dmV\n", __func__, + vout, iout, vrect); +} + +void get_usb_type_current(struct rx1619_chg *chip, u8 data) +{ + dev_info(chip->dev, "[%s] data=0x%x \n", __func__, data); + + switch (data) { + case ADAPTER_NONE: //other charger + if ((chip->auth == 0) && (chip->epp == 0)) { //bpp and auth fail + chip->target_curr = DC_OTHER_CURRENT; + dev_info(chip->dev, + "[rx1619] [%s] bpp and no id---800mA \n", + __func__); + } else { //auth ok + chip->target_curr = DC_LOW_CURRENT; + dev_info(chip->dev, + "[rx1619] [%s] bpp and id ok---200mA \n", + __func__); + } + break; + + case ADAPTER_SDP: + chip->target_vol = ADAPTER_DEFAULT_VOL; + chip->target_curr = DC_SDP_CURRENT; + break; + + case ADAPTER_CDP: + case ADAPTER_DCP: + chip->target_vol = ADAPTER_DEFAULT_VOL; + chip->target_curr = DC_BPP_AUTH_FAIL_CURRENT; + break; + + case ADAPTER_QC2: //QC2-other -- 6.5W + chip->target_vol = ADAPTER_BPP_QC2_VOL; + chip->target_curr = DC_QC2_CURRENT; //1A + break; + + case ADAPTER_QC3: //QC3-other -- 10W + case ADAPTER_PD: //PD-other -- 10W + if (chip->epp) { + chip->target_vol = ADAPTER_EPP_QC3_VOL; + chip->target_curr = DC_QC3_CURRENT; //1.8A + } else { + chip->target_vol = ADAPTER_DEFAULT_VOL; + chip->target_curr = DC_QC3_BPP_CURRENT; //0.9A + } + break; + + case ADAPTER_AUTH_FAILED: //fail charger + break; + + case ADAPTER_XIAOMI_QC3: //QC3-27W(20W) + case ADAPTER_XIAOMI_PD: //PD-27W(20W) + case ADAPTER_ZIMI_CAR_POWER: //PD-27W(20W) + chip->target_vol = ADAPTER_EPP_MI_VOL; + /* for usb-in design, set max usb icl to 1.8A*/ + chip->target_curr = USB_20W_PLUS_CURRENT_UA; //1.8A + break; + + case ADAPTER_XIAOMI_PD_40W: //40w + case ADAPTER_XIAOMI_PD_50W: + case ADAPTER_XIAOMI_PD_60W: + case ADAPTER_VOICE_BOX: + chip->target_vol = ADAPTER_EPP_MI_VOL; + /* for usb-in design, set max usb icl to 1.8A*/ + chip->target_curr = USB_20W_PLUS_CURRENT_UA; //1.8A + break; + + default: + break; + } +} +static void rx_set_charging_param(struct rx1619_chg *chip) +{ + union power_supply_propval val = { + 0, + }; + union power_supply_propval wk_val = { + 0, + }; + int soc = 0, health = 0, batt_sts = 0; + int vol_now = 0, cur_now = 0, dc_level = 0; + int iout = 0, ret = 0; + bool vout_change = false; + int last_icl = 0; + int last_vin = 0; + + get_usb_type_current(chip, g_USB_TYPE); + + if (!chip->batt_psy) { + ret = rx_get_property_names(chip); + if (ret < 0) + return; + } + + power_supply_get_property(chip->batt_psy, POWER_SUPPLY_PROP_STATUS, + &val); + batt_sts = val.intval; + + power_supply_get_property(chip->batt_psy, POWER_SUPPLY_PROP_CAPACITY, + &val); + soc = val.intval; + + power_supply_get_property(chip->batt_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, + &val); + vol_now = val.intval; + + power_supply_get_property(chip->batt_psy, POWER_SUPPLY_PROP_CURRENT_NOW, + &val); + cur_now = val.intval; + + power_supply_get_property(chip->batt_psy, POWER_SUPPLY_PROP_HEALTH, + &val); + health = val.intval; + + power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_DC_THERMAL_LEVELS, &val); + dc_level = val.intval; + + dev_info( + chip->dev, + "soc:%d,vol_now:%d,cur_now:%d,health:%d, bat_status:%d, dc_level:%d\n", + soc, vol_now, cur_now, health, batt_sts, dc_level); + /*epp 10W*/ + if ((g_USB_TYPE >= 6 && g_USB_TYPE <= 7) && (chip->epp)) { + dev_info(chip->dev, "standard epp logic\n"); + if (soc >= 97) + chip->target_curr = DC_BPP_CURRENT; + if (soc == 100) + chip->target_curr = DC_SDP_CURRENT; + if (soc == FULL_SOC && batt_sts == POWER_SUPPLY_STATUS_FULL) + chip->target_curr = SCREEN_OFF_FUL_CURRENT; + + if (chip->target_curr != chip->last_qc3_icl) { + dev_info(chip->dev, + "qc3_epp, set new icl: %d, last_icl: %d\n", + chip->target_curr, chip->last_qc3_icl); + chip->last_qc3_icl = chip->target_curr; + rx1619_set_pmi_icl(chip, chip->target_curr); + msleep(100); + } + } + /*epp plus*/ + if (g_USB_TYPE >= 9) { + if (chip->op_mode != LN8282_OPMODE_SWITCHING) { + dev_info(chip->dev, + "not switch mode, don't adjust voltage \n"); + goto out; + } + + if (chip->is_pan_tx) { + schedule_delayed_work(&chip->pan_tx_work, + msecs_to_jiffies(0)); + goto out; + } + + if (chip->is_voice_box_tx) { + dev_info(chip->dev, "enter voice work\n"); + schedule_delayed_work(&chip->voice_tx_work, + msecs_to_jiffies(0)); + goto out; + } + + if ((dc_level >= HIGH_THERMAL_LEVEL_THR) || + (soc >= LIMIT_SOC)) { + dev_info(chip->dev, + "set vin 12V for dc_level:%d, soc:%d\n", + dc_level, soc); + //chip->target_vol = EPP_VOL_THRESHOLD; + chip->is_vin_limit = 1; + } else + chip->is_vin_limit = 0; + + iout = rx1619_get_rx_iout(chip); + /* function start + * set adapter vol by iout value, threshold is 500mA + * lower than threshold will reduce to 12V, more than + * threshold will lift to 15V: + * 15V-->12V check 3 times + * 12V-->15v check 3 times + */ + if (iout < LIMIT_EPP_IOUT && + chip->epp_exchange == EXCHANGE_15V) { + chip->count_10v++; + chip->count_15v = 0; + } else if (iout > LIMIT_EPP_IOUT && + chip->epp_exchange == EXCHANGE_10V) { + chip->count_15v++; + chip->count_10v = 0; + } else { + chip->count_10v = 0; + chip->count_15v = 0; + } + if (chip->count_10v > ICL_EXCHANGE_COUNT || + (chip->epp_exchange == EXCHANGE_10V && + chip->count_15v <= ICL_EXCHANGE_COUNT)) { + dev_info(chip->dev, + "iout less than 500mA ,set vin to 12V\n"); + //chip->target_vol = EPP_VOL_THRESHOLD; + chip->epp_exchange = EXCHANGE_10V; + } else if (chip->count_15v > (ICL_EXCHANGE_COUNT)) + chip->epp_exchange = EXCHANGE_15V; + /* function end */ + switch (chip->status) { + case NORMAL_MODE: + if (soc >= 97) { + //chip->target_curr = min(DC_BPP_CURRENT, chip->target_curr); + dev_info(chip->dev, "set curr to %d\n", + chip->target_curr); + } + if (soc >= FULL_SOC) { + chip->status = TAPER_MODE; + //chip->target_vol = EPP_VOL_THRESHOLD; + //chip->target_curr = min(DC_SDP_CURRENT, chip->target_curr); + dev_info( + chip->dev, + "ready to taper_mode ,set vin to %d, curr to %d\n", + chip->target_vol, chip->target_curr); + } + break; + case TAPER_MODE: + //chip->target_vol = EPP_VOL_THRESHOLD; + //chip->target_curr = min(DC_SDP_CURRENT, chip->target_curr); + + dev_info( + chip->dev, + "ready to full_mode ,set vin to %d, curr to %d\n", + chip->target_vol, chip->target_curr); + if (soc == FULL_SOC && + batt_sts == POWER_SUPPLY_STATUS_FULL) + chip->status = FULL_MODE; + else if (soc < FULL_SOC - 1) + chip->status = NORMAL_MODE; + break; + case FULL_MODE: + dev_info(chip->dev, "charge full set Vin 11V\n"); + chip->target_vol = ADAPTER_EPP_QC3_VOL; + chip->target_curr = SCREEN_OFF_FUL_CURRENT; + + if (batt_sts == POWER_SUPPLY_STATUS_CHARGING) { + dev_info(chip->dev, + "full mode -> recharge mode\n"); + chip->status = RECHG_MODE; + chip->target_curr = DC_FULL_CURRENT; + } + break; + case RECHG_MODE: + if (batt_sts == POWER_SUPPLY_STATUS_FULL) { + dev_info(chip->dev, + "recharge mode -> full mode\n"); + chip->status = FULL_MODE; + chip->target_curr = SCREEN_OFF_FUL_CURRENT; + chip->target_vol = ADAPTER_EPP_QC3_VOL; + if (chip->wireless_psy) { + wk_val.intval = 0; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, + &wk_val); + } + break; + } + dev_info(chip->dev, "recharge mode set icl to 350mA\n"); + chip->target_vol = ADAPTER_EPP_QC3_VOL; + chip->target_curr = DC_FULL_CURRENT; + + if (chip->wireless_psy) { + wk_val.intval = 1; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, + &wk_val); + } + break; + default: + break; + } + switch (health) { + case POWER_SUPPLY_HEALTH_GOOD: + break; + case POWER_SUPPLY_HEALTH_COOL: + break; + case POWER_SUPPLY_HEALTH_WARM: + //chip->target_vol = min(EPP_VOL_THRESHOLD, chip->target_vol); + chip->target_curr = + min(DC_SDP_CURRENT, chip->target_curr); + break; + case POWER_SUPPLY_HEALTH_OVERVOLTAGE: + //chip->target_vol = min(EPP_VOL_THRESHOLD, chip->target_vol); + chip->target_curr = + min(SCREEN_OFF_FUL_CURRENT, chip->target_curr); + break; + case POWER_SUPPLY_HEALTH_COLD: + case POWER_SUPPLY_HEALTH_HOT: + //chip->target_vol = min(EPP_VOL_THRESHOLD, chip->target_vol); + chip->target_curr = SCREEN_OFF_FUL_CURRENT; + break; + default: + break; + } + last_vin = chip->last_vin; + last_icl = chip->last_icl; + if (chip->target_vol > 0 && + chip->target_vol != chip->last_vin) { + ret = rx1619_set_vout(chip, chip->target_vol); + chip->last_vin = chip->target_vol; + vout_change = true; + + if (chip->target_vol <= EPP_VOL_THRESHOLD) { + val.intval = 0; + } else { + val.intval = 1; + } + if (chip->wireless_psy) { + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, &val); + } + } + if ((chip->target_curr > 0 && + chip->target_curr != chip->last_icl) || + vout_change) { + chip->last_icl = chip->target_curr; + rx1619_set_pmi_icl(chip, chip->target_curr); + } + } +out: + dev_info( + chip->dev, + "status:0x%x,adapter_vol=%d,icl_curr=%d,last_vin=%d,last_icl=%d\n", + chip->status, chip->target_vol, chip->target_curr, last_vin, + last_icl); +} + +static void rx1619_dc_check_work(struct work_struct *work) +{ + struct rx1619_chg *chip = + container_of(work, struct rx1619_chg, dc_check_work.work); + + dev_info(chip->dev, "[rx1619] dc present: %d\n", chip->dcin_present); + if (chip->dcin_present) { + chip->ss = 1; + dev_info(chip->dev, "dcin present, quit dc check work\n"); + return; + } else { + chip->ss = 0; + dev_info(chip->dev, + "dcin no present, continue dc check work\n"); + schedule_delayed_work(&chip->dc_check_work, + msecs_to_jiffies(2500)); + } + if (chip->wireless_psy) + power_supply_changed(chip->wireless_psy); +} + +static void rx1619_cmd_timeout_work(struct work_struct *work) +{ + struct rx1619_chg *chip = + container_of(work, struct rx1619_chg, cmd_timeout_work.work); + + dev_info(chip->dev, "[%s] Cmd timeout set 700mA \n", __func__); + rx1619_set_pmi_icl(chip, DC_BPP_AUTH_FAIL_CURRENT); + chip->target_curr = DC_BPP_AUTH_FAIL_CURRENT; +} + +static void rx1619_rx_first_boot(struct work_struct *work) +{ + struct rx1619_chg *chip = + container_of(work, struct rx1619_chg, rx_first_boot.work); + g_rx1619_first_flag = true; + if (chip->wip_psy) + power_supply_changed(chip->wip_psy); +} +#define CHARGING_PERIOD_S 10 +static void rx_monitor_work(struct work_struct *work) +{ + struct rx1619_chg *chip = + container_of(work, struct rx1619_chg, chg_monitor_work.work); + rx_charging_info(chip); + + rx_set_charging_param(chip); + + schedule_delayed_work(&chip->chg_monitor_work, CHARGING_PERIOD_S * HZ); +} + +static void rx1619_fw_download_work(struct work_struct *work) +{ + struct rx1619_chg *chip = + container_of(work, struct rx1619_chg, fw_download_work.work); + + union power_supply_propval val = { + 0, + }; + bool is_valid_fw = true; + + if (chip->fw_update) { + dev_info(chip->dev, "[rx1619] [%s] FW Update is on going!\n", + __func__); + return; + } + + power_supply_get_property(chip->dc_psy, POWER_SUPPLY_PROP_ONLINE, &val); + if (!val.intval) { + pm_stay_awake(chip->dev); + chip->fw_update = true; + rx_set_reverse_gpio(chip, true); + msleep(100); + rx1619_check_firmware_version(chip, BOOT_AREA); + rx1619_check_firmware_version(chip, RX_AREA); + rx1619_check_firmware_version(chip, TX_AREA); + if (g_fw_rx_id == FW_EMPTY_CODE || + g_fw_rx_id == FW_ERROR_CODE || + g_fw_tx_id == FW_ERROR_CODE || + g_fw_boot_id == FW_ERROR_CODE) + is_valid_fw = false; + + chip->fw_version = g_fw_rx_id; + dev_info(chip->dev, "[rx1619] %s: FW Version is 0x%x\n", + __func__, g_fw_rx_id); + if (g_fw_rx_id) + chip->chip_ok = 1; + else + chip->chip_ok = 0; + + if (is_valid_fw && (g_fw_rx_id >= FW_VERSION)) { + dev_info( + chip->dev, + "[rx1619] %s: FW Version correct so skip upgrade\n", + __func__); + } else { + dev_info(chip->dev, "[rx1619] %s: FW download start\n", + __func__); + if (!rx1619_onekey_download_firmware(chip)) + dev_err(chip->dev, + "[rx1619] [%s] program fw failed!\n", + __func__); + else { + dev_info(chip->dev, + "[rx1619] [%s] FW Update Success!\n", + __func__); + boot_fw_version = + (~fw_data_boot[sizeof(fw_data_boot) - + 1]) & + 0xff; + tx_fw_version = + (~fw_data_tx[sizeof(fw_data_tx) - 1]) & + 0xff; + rx_fw_version = + (~fw_data_rx[sizeof(fw_data_rx) - 1]) & + 0xff; + dev_info( + chip->dev, + "boot_fw_version=0x%x, tx_fw_version=0x%x, rx_fw_version=0x%x\n", + boot_fw_version, tx_fw_version, + rx_fw_version); + chip->fw_version = g_fw_rx_id; + } + } + rx_set_reverse_gpio(chip, false); + chip->fw_update = false; + pm_relax(chip->dev); + } else + dev_err(chip->dev, + "%s: Skip FW download due to wireless charging\n", + __func__); +} + +static void rx1619_pan_tx_work(struct work_struct *work) +{ + struct rx1619_chg *chip = + container_of(work, struct rx1619_chg, pan_tx_work.work); + + int soc = 0, batt_sts = 0, dc_level = 0; + int last_icl = 0; + int last_vin = 0; + int ret = 0; + unsigned int vout = 0; + bool vout_change = false; + union power_supply_propval val = { + 0, + }; + union power_supply_propval wk_val = { + 0, + }; + + chip->target_vol = ADAPTER_EPP_MI_VOL; + chip->target_curr = 2000000; + + if (chip->batt_psy) { + power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_STATUS, &val); + batt_sts = val.intval; + + power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &val); + soc = val.intval; + + power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_DC_THERMAL_LEVELS, + &val); + dc_level = val.intval; + } + + dev_info(chip->dev, "soc:%d, dc_level:%d, bat_status:%d\n", soc, + dc_level, batt_sts); + + if (dc_level) { + dev_info(chip->dev, "Disable bq, dc_level:%d\n", dc_level); + chip->target_vol = ADAPTER_EPP_QC3_VOL; + } + + switch (chip->status) { + case NORMAL_MODE: + if (soc >= FULL_SOC) + chip->status = TAPER_MODE; + break; + case TAPER_MODE: + if (soc == FULL_SOC && batt_sts == POWER_SUPPLY_STATUS_FULL) + chip->status = FULL_MODE; + else if (soc < FULL_SOC - 1) + chip->status = NORMAL_MODE; + break; + case FULL_MODE: + dev_info(chip->dev, "[pan]charge full set Vin 11V\n"); + chip->target_vol = ADAPTER_EPP_QC3_VOL; + chip->target_curr = SCREEN_OFF_FUL_CURRENT; + + if (batt_sts == POWER_SUPPLY_STATUS_CHARGING) { + dev_info(chip->dev, + "[pan]full mode -> recharge mode\n"); + chip->status = RECHG_MODE; + chip->target_curr = DC_LOW_CURRENT; + } + break; + case RECHG_MODE: + if (batt_sts == POWER_SUPPLY_STATUS_FULL) { + dev_info(chip->dev, + "[pan]recharge mode -> full mode\n"); + chip->status = FULL_MODE; + chip->target_curr = SCREEN_OFF_FUL_CURRENT; + if (chip->wireless_psy) { + wk_val.intval = 0; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, + &wk_val); + } + break; + } + + dev_info(chip->dev, "[pan]recharge mode set icl to 350mA\n"); + chip->target_vol = ADAPTER_EPP_QC3_VOL; + chip->target_curr = DC_LOW_CURRENT; + + if (chip->wireless_psy) { + wk_val.intval = 1; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, &wk_val); + } + break; + default: + break; + } + + last_vin = chip->last_vin; + last_icl = chip->last_icl; + + if (chip->target_vol > 0 && chip->target_vol != chip->last_vin) { + if (chip->target_vol == ADAPTER_EPP_MI_VOL) { + chip->disable_bq = false; + ret = rx1619_set_vout(chip, chip->target_vol); + if (chip->wireless_psy) { + val.intval = 1; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, &val); + } + } else if (chip->target_vol == ADAPTER_EPP_QC3_VOL) { + chip->disable_bq = true; + /* enable 8150b charge */ + if (chip->batt_psy) { + val.intval = 1; + power_supply_set_property( + chip->batt_psy, + POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED, + &val); + } + if (chip->wireless_psy) { + val.intval = 0; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, &val); + } + + vout = rx1619_get_rx_vout(chip); + while (vout > ADAPTER_EPP_QC3_VOL) { + vout = vout - 1000; + ret = rx1619_set_vout(chip, vout); + msleep(200); + } + ret = rx1619_set_vout(chip, ADAPTER_EPP_QC3_VOL); + } + chip->last_vin = chip->target_vol; + vout_change = true; + } + + if ((chip->target_curr > 0 && chip->target_curr != chip->last_icl) || + vout_change) { + chip->last_icl = chip->target_curr; + rx1619_set_pmi_icl(chip, chip->target_curr); + } + + dev_info( + chip->dev, + "di->status:0x%x,adapter_vol=%d,icl_curr=%d,last_vin=%d,last_icl=%d, bq_dis:%d\n", + chip->status, chip->target_vol, chip->target_curr, + chip->last_vin, chip->last_icl, chip->disable_bq); +} + +static int rx1619_get_effective_fcc(struct rx1619_chg *chip) +{ + int effective_fcc_val = 0; + + if (!chip->fcc_votable) + chip->fcc_votable = find_votable("FCC"); + + if (!chip->fcc_votable) + return -EINVAL; + + effective_fcc_val = get_effective_result(chip->fcc_votable); + effective_fcc_val = effective_fcc_val / 1000; + dev_info(chip->dev, "effective_fcc: %d\n", effective_fcc_val); + return effective_fcc_val; +} + +#define VOICE_LIMIT_FCC_VOTER "VOICE_LIMIT_FCC_VOTER" +#define VOICE_LIMIT_FCC_1A_VOTER "VOICE_LIMIT_FCC_1A_VOTER" +static void rx1619_voice_tx_work(struct work_struct *work) +{ + struct rx1619_chg *chip = + container_of(work, struct rx1619_chg, voice_tx_work.work); + + int soc = 0, batt_sts = 0, dc_level = 0, batt_temp = 0; + int last_icl = 0; + int last_vin = 0; + int ret = 0; + int effective_fcc = 0; + unsigned int vout = 0; + bool vout_change = false; + union power_supply_propval val = { + 0, + }; + union power_supply_propval wk_val = { + 0, + }; + + chip->target_vol = ADAPTER_EPP_MI_VOL; + chip->target_curr = 2000000; + + if (chip->batt_psy) { + power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_STATUS, &val); + batt_sts = val.intval; + + power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &val); + soc = val.intval; + + power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_DC_THERMAL_LEVELS, + &val); + dc_level = val.intval; + + power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_TEMP, &val); + batt_temp = val.intval; + } + + dev_info(chip->dev, + "soc:%d, dc_level:%d, bat_status:%d, batt_temp:%d\n", soc, + dc_level, batt_sts, batt_temp); + + if (batt_temp >= 402) { + dev_info(chip->dev, "[voice]Tbat limit fcc 1A\n"); + effective_fcc = rx1619_get_effective_fcc(chip); + if (chip->fcc_votable) { + effective_fcc = 1000; + vote(chip->fcc_votable, VOICE_LIMIT_FCC_1A_VOTER, true, + effective_fcc * 1000); + } + } else if (batt_temp < 400) { + if (chip->fcc_votable) + vote(chip->fcc_votable, VOICE_LIMIT_FCC_1A_VOTER, false, + 0); + } + + if (batt_temp >= 375) { + dev_info(chip->dev, "[voice]Tbat limit fcc 3.2A\n"); + effective_fcc = rx1619_get_effective_fcc(chip); + if (chip->fcc_votable) { + effective_fcc = 2600; + vote(chip->fcc_votable, VOICE_LIMIT_FCC_VOTER, true, + effective_fcc * 1000); + } + } else if (batt_temp < 367) { + if (chip->fcc_votable) + vote(chip->fcc_votable, VOICE_LIMIT_FCC_VOTER, false, + 0); + } + + if (dc_level > 2) { + dev_info(chip->dev, "[voice]Disable bq, dc_level:%d\n", + dc_level); + chip->target_vol = ADAPTER_EPP_QC3_VOL; + } + + switch (chip->status) { + case NORMAL_MODE: + if (soc >= 95) + chip->status = TAPER_MODE; + break; + case TAPER_MODE: + dev_info(chip->dev, "[voice]taper mode set Vin 11V\n"); + chip->target_vol = ADAPTER_EPP_QC3_VOL; + if (soc == FULL_SOC && batt_sts == POWER_SUPPLY_STATUS_FULL) + chip->status = FULL_MODE; + else if (soc < 95) + chip->status = NORMAL_MODE; + break; + case FULL_MODE: + dev_info(chip->dev, "[voice]charge full set Vin 11V\n"); + chip->target_vol = ADAPTER_EPP_QC3_VOL; + chip->target_curr = SCREEN_OFF_FUL_CURRENT; + + if (batt_sts == POWER_SUPPLY_STATUS_CHARGING) { + dev_info(chip->dev, + "[voice]full mode -> recharge mode\n"); + chip->status = RECHG_MODE; + chip->target_curr = DC_LOW_CURRENT; + } + break; + case RECHG_MODE: + if (batt_sts == POWER_SUPPLY_STATUS_FULL) { + dev_info(chip->dev, + "[voice]recharge mode -> full mode\n"); + chip->status = FULL_MODE; + chip->target_curr = SCREEN_OFF_FUL_CURRENT; + if (chip->wireless_psy) { + wk_val.intval = 0; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, + &wk_val); + } + break; + } + + dev_info(chip->dev, "[voice]recharge mode set icl to 350mA\n"); + chip->target_vol = ADAPTER_EPP_QC3_VOL; + chip->target_curr = DC_LOW_CURRENT; + + if (chip->wireless_psy) { + wk_val.intval = 1; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, &wk_val); + } + break; + default: + break; + } + + last_vin = chip->last_vin; + last_icl = chip->last_icl; + + if (chip->target_vol > 0 && chip->target_vol != chip->last_vin) { + if (chip->target_vol == ADAPTER_EPP_MI_VOL) { + chip->disable_bq = false; + ret = rx1619_set_vout(chip, chip->target_vol); + if (chip->wireless_psy) { + val.intval = 1; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, &val); + } + } else if (chip->target_vol == ADAPTER_EPP_QC3_VOL) { + chip->disable_bq = true; + /* enable 8150b charge */ + if (chip->batt_psy) { + val.intval = 1; + power_supply_set_property( + chip->batt_psy, + POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED, + &val); + } + if (chip->wireless_psy) { + val.intval = 0; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, &val); + } + + vout = rx1619_get_rx_vout(chip); + while (vout > ADAPTER_EPP_QC3_VOL) { + vout = vout - 1000; + ret = rx1619_set_vout(chip, vout); + msleep(200); + } + ret = rx1619_set_vout(chip, ADAPTER_EPP_QC3_VOL); + } + chip->last_vin = chip->target_vol; + vout_change = true; + } + + if ((chip->target_curr > 0 && chip->target_curr != chip->last_icl) || + vout_change) { + chip->last_icl = chip->target_curr; + rx1619_set_pmi_icl(chip, chip->target_curr); + } + + dev_info( + chip->dev, + "di->status:0x%x,adapter_vol=%d,icl_curr=%d,last_vin=%d,last_icl=%d, bq_dis:%d\n", + chip->status, chip->target_vol, chip->target_curr, + chip->last_vin, chip->last_icl, chip->disable_bq); +} + +static void rx_chg_detect_work(struct work_struct *work) +{ + struct rx1619_chg *chip = + container_of(work, struct rx1619_chg, chg_detect_work.work); + union power_supply_propval val = { + 0, + }; + union power_supply_propval pc_val = { + 0, + }; + union power_supply_propval wk_val = { + 0, + }; + int rc; + + dev_info(chip->dev, "[idt] enter %s\n", __func__); + + rc = rx_get_property_names(chip); + if (rc < 0) + return; + + g_chip = chip; + power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_ONLINE, + &val); + power_supply_get_property(chip->pc_port_psy, POWER_SUPPLY_PROP_ONLINE, + &pc_val); + if (val.intval || pc_val.intval) { + dev_info(chip->dev, + "usb_online:%d, pc online:%d set chip disable\n", + val.intval, pc_val.intval); + rx_set_enable_mode(chip, 0); + schedule_delayed_work(&chip->fw_download_work, 1 * HZ); + return; + } + + if (chip->dc_psy) { + power_supply_get_property(chip->dc_psy, + POWER_SUPPLY_PROP_ONLINE, &val); + dev_info(chip->dev, "dc_online %d\n", val.intval); + if (val.intval && chip->wireless_psy) { + wk_val.intval = 1; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, &wk_val); + + if (!chip->power_off_mode) { + rx_set_enable_mode(chip, false); + usleep_range(20000, 25000); + rx_set_enable_mode(chip, true); + } + + schedule_delayed_work(&chip->wireless_int_work, + msecs_to_jiffies(30)); + } + } +} + +static void reverse_chg_sent_state_work(struct work_struct *work) +{ + struct rx1619_chg *chip = container_of(work, struct rx1619_chg, + reverse_sent_state_work.work); + + union power_supply_propval val = { + 0, + }; + + if (chip->wireless_psy) { + val.intval = chip->is_reverse_chg; + power_supply_set_property(chip->wireless_psy, + POWER_SUPPLY_PROP_REVERSE_CHG_STATE, + &val); + dev_info(chip->dev, "sent tx_mode_uevent\n"); + power_supply_changed(chip->wireless_psy); + } else + dev_err(chip->dev, "get wls property error\n"); +} + +static void reverse_chg_state_set_work(struct work_struct *work) +{ + struct rx1619_chg *chip = container_of(work, struct rx1619_chg, + reverse_chg_state_work.work); + int ret; + + dev_info(chip->dev, "no rx found and disable reverse charging\n"); + ret = rx_set_reverse_chg_mode(chip, false); + chip->is_reverse_chg = 1; + schedule_delayed_work(&chip->reverse_sent_state_work, 0); + + return; +} + +static void reverse_dping_state_set_work(struct work_struct *work) +{ + struct rx1619_chg *chip = container_of(work, struct rx1619_chg, + reverse_dping_state_work.work); + int ret; + + dev_info(chip->dev, "tx mode fault and disable reverse charging\n"); + ret = rx_set_reverse_chg_mode(chip, false); + chip->is_reverse_chg = 2; + schedule_delayed_work(&chip->reverse_sent_state_work, 0); + return; +} + +/* power good work */ +static void rx1619_wpc_det_work(struct work_struct *work) +{ + struct rx1619_chg *chip = + container_of(work, struct rx1619_chg, wpc_det_work.work); + union power_supply_propval val = { + 0, + }; + int ret = 0; + + chip->wireless_psy = power_supply_get_by_name("wireless"); + if (!chip->wireless_psy) { + dev_err(chip->dev, "[rx1619] no wireless_psy, return\n"); + return; + } + + if (gpio_is_valid(chip->power_good_gpio)) { + ret = gpio_get_value(chip->power_good_gpio); + if (ret) { + dev_info(chip->dev, + "power_good high, wireless attached\n"); + chip->power_good_flag = 1; + val.intval = 1; + schedule_delayed_work(&chip->dc_check_work, + msecs_to_jiffies(2500)); + } else { + dev_info(chip->dev, + "power_good low, wireless detached\n"); + cancel_delayed_work(&chip->dc_check_work); + chip->power_good_flag = 0; + chip->ss = 2; + val.intval = 0; + chip->ln_psy = power_supply_get_by_name("lionsemi"); + if (chip->ln_psy) + power_supply_set_property( + chip->ln_psy, + POWER_SUPPLY_PROP_RESET_DIV_2_MODE, + &val); + } + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN, &val); + } +} +static void rx1619_enable_aicl(struct rx1619_chg *chip, bool enable) +{ + union power_supply_propval val = { + 0, + }; + if (chip->wireless_psy) { + if (chip->enabled_aicl != enable) { + val.intval = enable ? 1 : 0; + power_supply_set_property(chip->wireless_psy, + POWER_SUPPLY_PROP_AICL_ENABLE, + &val); + chip->enabled_aicl = enable; + return; + } + } + return; +} +/************AP->RX************/ +//AP set Vout = 0x80 +//AP set Iout = 0x81 +//charge done = 0x82 +//recharge = 0x83 +//sent EPT = 0x84 +//fod factor = 0x85 +//authen req = 0x86 +//usb type req = 0x87 +//fast charge req = 0x88 +//rx fw version = 0x89 +//ap private data pkt = 0x8D +/************AP->RX************/ + +/************RX->AP************/ +//RX NONE = 0x00 +//RX light screen = 0x01 +//RX cali start = 0x02 +//RX cali ok = 0x03 +//RX private id = 0x04 +//RX private authen res = 0x05 +//RX private usb type = 0x06 +//RX private fc status = 0x07 +//RX private data error = 0x0F +/************RX->AP************/ +#define REVERSE_CHG_CHECK_DELAY_MS 100000 +#define REVERSE_DPING_CHECK_DELAY_MS 10000 +#define CMD_TIMEOUT_DELAY_MS 5000 +#define REVERSE_CHG_TX_SWITCH_DONE 8 +static void rx1619_wireless_int_work(struct work_struct *work) +{ + int i = 0; + int uA = 0; + u16 iout = 0; + u16 vout = 0; + u8 usb_type; + u8 rx_rev_data[4] = { 0, 0, 0, 0 }; + u8 data_h, data_l; + u8 tx_req = 0; + u8 rx_req = 0; + u8 g_tx_id_h = 0; + u8 g_tx_id_l = 0; + u8 g_shaone_data_h = 0; + u8 g_shaone_data_l = 0; + u8 g_fc_status = 0; + u8 g_uuid_data[4] = { 0 }; + int tx_gpio, ret; + u8 tx_status, tx_phase; + u8 err_cmd; + static int retry; + static int retry_id; + int rc; + int cnt; + union power_supply_propval cp_val = { + 0, + }; + int fc_flag = 0; + int vol = 0; + + struct rx1619_chg *chip = + container_of(work, struct rx1619_chg, wireless_int_work.work); + + chip->wireless_psy = power_supply_get_by_name("wireless"); + if (!chip->wireless_psy) { + dev_err(chip->dev, "[rx1619] no wireless_psy, return\n"); + return; + } + + tx_gpio = rx_get_reverse_chg_mode(chip); + if (tx_gpio) { + if (rx1619_is_tx_mode(chip)) { + rx1619_write(chip, AP_REV_DATA_OK, + REG_AP_RX_COMM); //receive ok + tx_status = rx1619_get_tx_status(chip); + if (tx_status && + tx_status != REVERSE_CHG_TX_SWITCH_DONE) { + ret = rx_set_reverse_chg_mode(chip, false); + chip->is_reverse_chg = 2; + schedule_delayed_work( + &chip->reverse_sent_state_work, 0); + } else if (tx_status == REVERSE_CHG_TX_SWITCH_DONE) { + dev_err(chip->dev, + "[rx1619] restart because of OTG \n"); + } + tx_phase = rx1619_get_tx_phase(chip); + switch (tx_phase) { + case PING: + //schedule_delayed_work(&chip->reverse_chg_state_work, 80 * HZ); + alarm_start_relative( + &chip->reverse_chg_alarm, + ms_to_ktime( + REVERSE_CHG_CHECK_DELAY_MS)); + //cancel_delayed_work(&chip->reverse_dping_state_work); + rc = alarm_cancel(&chip->reverse_dping_alarm); + if (rc < 0) + dev_err(chip->dev, + "Couldn't cancel reverse_dping_alarm\n"); + pm_relax(chip->dev); + if (tx_status == REVERSE_CHG_TX_SWITCH_DONE) + dev_err(chip->dev, + "reverse restart because of otg insertion\n"); + break; + case TRANSFER: + //cancel_delayed_work(&chip->reverse_chg_state_work); + rc = alarm_cancel(&chip->reverse_chg_alarm); + if (rc < 0) + dev_err(chip->dev, + "Couldn't cancel reverse_dping_alarm\n"); + pm_stay_awake(chip->dev); + /* set reverse charging state to started*/ + chip->is_reverse_chg = 4; + schedule_delayed_work( + &chip->reverse_sent_state_work, 0); + dev_info(chip->dev, "tx mode power transfer\n"); + break; + case POWER_LIM: + dev_info(chip->dev, "tx mode power limit\n"); + break; + case CONFIGURE_CNF: + dev_info(chip->dev, "tx mode CONFIGURE_CNF\n"); + break; + + case CONFIGURE_ERR: + dev_err(chip->dev, "tx mode CONFIGURE_ERR\n"); + break; + default: + dev_err(chip->dev, "tx phase invalid\n"); + break; + } + } + return; + } + + rx1619_read(chip, &rx_req, REG_RX_REV_CMD); //0x0020 + if (rx_req <= 0) { + dev_info(chip->dev, "rx cmd error:%d\n", rx_req); + return; + } + + dev_info(chip->dev, "rx_req = 0x%x\n", rx_req); + + mutex_lock(&chip->wireless_chg_int_lock); + + //read data + rx1619_read(chip, &rx_rev_data[0], REG_RX_REV_DATA1); //0x0021 + rx1619_read(chip, &rx_rev_data[1], REG_RX_REV_DATA2); //0x0022 + rx1619_read(chip, &rx_rev_data[2], REG_RX_REV_DATA3); //0x0023 + rx1619_read(chip, &rx_rev_data[3], REG_RX_REV_DATA4); //0x0024 + + dev_err(chip->dev, "[%s] rx_req,rx_rev_data=0x%x,0x%x,0x%x,0x%x,0x%x\n", + __func__, rx_req, rx_rev_data[0], rx_rev_data[1], + rx_rev_data[2], rx_rev_data[3]); + + switch (rx_req) { + case 0x10: //get epp tx id + rx1619_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); //receive ok + msleep(10); + chip->epp_tx_id_h = rx_rev_data[0]; //epp tx id high byte + chip->epp_tx_id_l = rx_rev_data[1]; //epp tx id low byte + + if (chip->epp_tx_id_l == 0x59) { + dev_info(chip->dev, + "mophie tx, start dc check after 8s\n"); + schedule_delayed_work(&chip->dc_check_work, + msecs_to_jiffies(8000)); + } else + schedule_delayed_work(&chip->dc_check_work, + msecs_to_jiffies(2500)); + + dev_info(chip->dev, "epp_tx_id_h = 0x%x, epp_tx_id_l = 0x%x\n", + chip->epp_tx_id_h, chip->epp_tx_id_l); + break; + + case 0x01: //LDO on Int + rx1619_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); //receive ok + chip->epp_max_power = 5; + msleep(10); + + dev_info(chip->dev, "[%s] LDO on Int \n", __func__); + + chip->epp = (rx_rev_data[0] >> 7) & 0xff; + chip->epp_max_power = (rx_rev_data[0] & 0x7f); + g_hw_id_h = rx_rev_data[1]; //0x16 + g_hw_id_l = rx_rev_data[2]; //0x19 + g_fw_rx_id = rx_rev_data[3]; + g_fw_tx_id = (~(fw_data_tx[sizeof(fw_data_tx) - 1])) & 0xff; + if (chip->epp) { //EPP + chip->epp = 1; + rx1619_set_pmi_icl(chip, 30000); + dev_info(chip->dev, + "[%s] EPP--10mA and epp max power is %d\n", + __func__, chip->epp_max_power); + if (chip->wireless_psy) { + cp_val.intval = 2; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_DIV_2_MODE, &cp_val); + msleep(10); + power_supply_get_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_DIV_2_MODE, &cp_val); + chip->op_mode = cp_val.intval; + dev_info(chip->dev, + "loop ln8282 set switch and get: %d\n", + chip->op_mode); + } + msleep(50); + + if (chip->op_mode == LN8282_OPMODE_SWITCHING) { + for (i = 0; i <= 1; i++) { + uA = (600000 + 800000 * i); + rx1619_set_pmi_icl(chip, uA); + usleep_range(10000, 11000); + usleep_range(10000, 11000); + usleep_range(10000, 11000); + usleep_range(10000, 11000); + usleep_range(10000, 11000); + } + } else { + for (i = 0; i <= 1; i++) { + uA = (300000 + 400000 * i); + rx1619_set_pmi_icl(chip, uA); + usleep_range(10000, 11000); + usleep_range(10000, 11000); + usleep_range(10000, 11000); + usleep_range(10000, 11000); + usleep_range(10000, 11000); + } + } + } else + rx1619_set_pmi_icl(chip, DC_LOW_CURRENT); + + dev_info( + chip->dev, + "[%s] hw_id_h=0x%x,hw_id_l=0x%x,fw_rx_id=0x%x,g_fw_tx_id=0x%x,g_epp_or_bpp=0x%x\n", + __func__, g_hw_id_h, g_hw_id_l, g_fw_rx_id, g_fw_tx_id, + g_epp_or_bpp); + rx1619_set_fod_param(chip, 0x1); + rx1619_enable_aicl(chip, false); + break; + + case 0x02: //null + rx1619_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); //receive ok + if (chip->fod_mode == 0x1) { + rx1619_set_fod_param(chip, 0x2); + } else if (chip->fod_mode == 0x2) { + rx1619_set_fod_param(chip, 0x3); + } else if (chip->fod_mode == 0x3) { + rx1619_set_fod_param(chip, 0x4); + } + dev_info(chip->dev, "[rx1619] [%s] fod param setting \n", + __func__); + break; + + case 0x03: //cali ok + rx1619_enable_aicl(chip, true); + + rx1619_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + msleep(10); + dev_info(chip->dev, "[rx1619] [%s] Calibration OK! \n", + __func__); + if (chip->epp && chip->epp_max_power == 10) { //EPP + if (chip->op_mode == LN8282_OPMODE_SWITCHING) + rx1619_set_pmi_icl(chip, 1800000); //10W + else + rx1619_set_pmi_icl(chip, 900000); + } + break; + + case 0x04: //id ok + rx1619_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); //receive ok + msleep(10); + + rx1619_read(chip, &g_tx_id_h, REG_RX_REV_DATA1); //0x0021 + rx1619_read(chip, &g_tx_id_l, REG_RX_REV_DATA2); //0x0022 + + rx1619_write(chip, PRIVATE_ID_CMD, + REG_RX_SENT_CMD); //0x86 authen req + rx1619_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); + dev_err(chip->dev, "[rx1619] [%s] ID OK! \n", __func__); + break; + + case 0x05: //sha one ok + rx1619_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); //receive ok + msleep(10); + + rx1619_read(chip, &g_shaone_data_h, REG_RX_REV_DATA1); //0x0021 + rx1619_read(chip, &g_shaone_data_l, REG_RX_REV_DATA2); //0x0022 + + rx1619_request_uuid(chip, chip->epp); + //rx1619_write(chip, PRIVATE_USB_TYPE_CMD, REG_RX_SENT_CMD);//0x87 usb type req + //rx1619_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); + dev_info(chip->dev, "[rx1619] [%s] SHA ONE OK! \n", __func__); + chip->auth = 1; + if (!chip->epp) + alarm_start_relative(&chip->cmd_timeout_alarm, + ms_to_ktime(CMD_TIMEOUT_DELAY_MS)); + break; + + case 0x06: //USB type 0x6,0x14,0x0,0x19,0x5 + rx1619_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); //receive ok + msleep(10); + + rx1619_read(chip, &usb_type, REG_RX_REV_DATA1); + + /* + rx1619_write(chip, PRIVATE_FAST_CHG_CMD, REG_RX_SENT_CMD); //0x88 fast charge req + rx1619_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); +*/ + + if (chip->is_car_tx && (usb_type >= ADAPTER_XIAOMI_QC3)) + usb_type = ADAPTER_ZIMI_CAR_POWER; + + if (chip->is_voice_box_tx) + usb_type = ADAPTER_VOICE_BOX; + dev_info(chip->dev, "[rx1619] [%s] usb_type=0x%x\n", __func__, + usb_type); + g_USB_TYPE = usb_type; + switch (g_USB_TYPE) { + case ADAPTER_QC2: + if (!chip->epp && !chip->is_f1_tx) + chip->target_vol = ADAPTER_BPP_PLUS_VOL; + else + fc_flag = 1; + break; + case ADAPTER_AUTH_FAILED: + case ADAPTER_DCP: + case ADAPTER_CDP: + case ADAPTER_SDP: + fc_flag = 1; + break; + case ADAPTER_QC3: + case ADAPTER_PD: + if (!chip->epp) + chip->target_vol = ADAPTER_BPP_PLUS_VOL; + else + fc_flag = 1; + break; + case ADAPTER_XIAOMI_QC3: + case ADAPTER_XIAOMI_PD: + case ADAPTER_ZIMI_CAR_POWER: + case ADAPTER_XIAOMI_PD_40W: + case ADAPTER_XIAOMI_PD_50W: + case ADAPTER_XIAOMI_PD_60W: + case ADAPTER_VOICE_BOX: + chip->target_vol = ADAPTER_EPP_MI_VOL; + break; + default: + dev_info(chip->dev, "[%s] other Usb_type\n", __func__); + break; + } + if (fc_flag) { + set_usb_type_current(chip, g_USB_TYPE); + schedule_delayed_work(&chip->chg_monitor_work, + msecs_to_jiffies(1000)); + } else { + if (chip->target_vol > 0) { + rx1619_set_adap_vol(chip, chip->target_vol); + chip->last_vin = chip->target_vol; + } + } + + if (chip->wireless_psy) + power_supply_changed(chip->wireless_psy); + break; + + case 0x07: //FC status 0x7,0x1,0x0,0x19,0x5 + rx1619_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + msleep(10); + + rx1619_read(chip, &g_fc_status, REG_RX_REV_DATA1); + dev_info(chip->dev, "[%s] FC status = %d\n", __func__, + g_fc_status); + if (g_fc_status == 1) { + set_usb_type_current(chip, g_USB_TYPE); + dev_info(chip->dev, "[%s] fast charge success!!! \n", + __func__); + schedule_delayed_work(&chip->chg_monitor_work, + msecs_to_jiffies(1000)); + } else { + dev_info(chip->dev, "[%s] fast charge fail!!! \n", + __func__); + if (!chip->epp) { + rx1619_set_pmi_icl(chip, + DC_BPP_AUTH_FAIL_CURRENT); + chip->target_curr = DC_BPP_AUTH_FAIL_CURRENT; + } + } + break; + case 0x0d: + rx1619_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); //receive ok + if (!chip->epp) + alarm_cancel(&chip->cmd_timeout_alarm); + if (chip->is_compatible_hwid) { + for (i = 0; i < 2; i++) + g_uuid_data[i] = rx_rev_data[i]; + + dev_info(chip->dev, "TX hwid: 0x%x 0x%x\n", + g_uuid_data[0], g_uuid_data[1]); + + if (g_uuid_data[0] == 0x12 && g_uuid_data[1]) + chip->is_f1_tx = 0; + + if (g_uuid_data[0] == 0x16 && g_uuid_data[1] == 0x11) + chip->is_f1_tx = 1; + } else { + for (i = 0; i < 4; i++) + g_uuid_data[i] = rx_rev_data[i]; + + dev_info( + chip->dev, + "vendor:0x%x, module:0x%x, hw:0x%x and power:0x%x\n", + g_uuid_data[0], g_uuid_data[1], g_uuid_data[2], + g_uuid_data[3]); + + if (g_uuid_data[3] == 0x01 && g_uuid_data[1] == 0x2 && + g_uuid_data[2] == 0x8 && g_uuid_data[0] == 0x6) { + chip->is_car_tx = 1; + } else if (g_uuid_data[3] == 0x07 && + g_uuid_data[1] == 0x8 && + g_uuid_data[2] == 0x6 && + g_uuid_data[0] == 0x9) { + chip->is_voice_box_tx = 1; + } else if (g_uuid_data[3] == 0x06 && + g_uuid_data[1] == 0x1 && + g_uuid_data[2] == 0x5 && + g_uuid_data[0] == 0x9) { + chip->is_pan_tx = 1; + } + } + rx1619_write(chip, PRIVATE_USB_TYPE_CMD, + REG_RX_SENT_CMD); //0x87 usb type req + rx1619_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); + + break; + case 0x0f: //error cmd + rx1619_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + err_cmd = rx_rev_data[0]; + cnt = 0; + dev_info(chip->dev, "[%s] Receive error cmd %d\n", __func__, + err_cmd); + if (!chip->epp && + ((err_cmd == ID_CMD) || (err_cmd == AUTH_CMD) || + (err_cmd == UUID_CMD) || + (err_cmd == PRIVATE_USB_TYPE_CMD))) { + if (err_cmd == ID_CMD && (retry_id < 3)) { + //send device idauth + retry_id++; + rx1619_retry_id_auth(chip); + dev_info(chip->dev, + "[rx1619] id auth failed retry %d\n", + retry_id); + break; + } else if (err_cmd == AUTH_CMD && retry < 3) { + //send device auth + rx1619_send_device_auth(chip); + retry++; + dev_info(chip->dev, + "[rx1619] dev auth failed retry %d\n", + retry); + break; + } else { + retry = 0; + retry_id = 0; + } + g_USB_TYPE = ADAPTER_AUTH_FAILED; + dev_info( + chip->dev, + "[rx1619]auth failed tx charger type set 0x%x\n", + g_USB_TYPE); + alarm_cancel(&chip->cmd_timeout_alarm); + if (chip->epp) { + chip->target_vol = ADAPTER_EPP_QC3_VOL; + if (chip->epp_max_power < 10000) { + uA = ((chip->epp_max_power - 1000) / + 11) * + 1000; + if (chip->op_mode == + LN8282_OPMODE_SWITCHING) + uA = uA * 2; + } else { + if (chip->op_mode == + LN8282_OPMODE_SWITCHING) + uA = USB_20W_PLUS_CURRENT_UA; + else + uA = USB_20W_PLUS_CURRENT_UA / + 2; + } + rx1619_set_pmi_icl(chip, uA); + rx1619_set_vout(chip, chip->target_vol); + } else { + for (i = 0; i < 7; i++) { + uA = (100000 + 100000 * i); + rx1619_set_pmi_icl(chip, uA); + msleep(400); + vol = rx1619_get_rx_vout(chip); + if (vol < 5200) { + msleep(400); + vol = rx1619_get_rx_vout(chip); + if (vol < 5200 && uA > 200000) { + uA = (uA - 100000); + rx1619_set_pmi_icl(chip, + uA); + rx1619_set_vout(chip, + 6000); + break; + } + } + } + + if (i >= 7) { + /*do{ + msleep(400); + vol = rx1619_get_rx_vout(chip); + if (vol < 6300){ + uA = 500000; + rx1619_set_pmi_icl(chip, uA); + break; + } + }while(cnt++<3); + if (cnt == 3) + rx1619_set_pmi_icl(chip, 750000); + */ + rx1619_set_pmi_icl(chip, 750000); + } + dev_info(chip->dev, "[%s] BPP--750mA \n", + __func__); + chip->target_curr = DC_BPP_AUTH_FAIL_CURRENT; + } + } + + if (chip->wireless_psy) + power_supply_changed(chip->wireless_psy); + break; + + case 0x1f: //for product test + rx1619_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); + msleep(10); + + rx1619_read(chip, &tx_req, REG_RX_REV_DATA1); //0x0021 + + dev_info(chip->dev, "[rx1619] [%s] tx_req=0x%x \n", __func__, + tx_req); + + if (tx_req == 0x12) { //iout + rx1619_write(chip, 0x38, + REG_RX_SENT_DATA1); //sent header + rx1619_write(chip, 0x12, REG_RX_SENT_DATA2); //sent cmd + + iout = rx1619_get_rx_iout(chip); + data_h = (iout & 0x00ff); + data_l = (iout & 0xff00) >> 8; + rx1619_write(chip, data_h, 0x0003); + rx1619_write(chip, data_l, 0x0004); + dev_info( + chip->dev, + "[rx1619] [%s] product test--0x12--0x%x,0x%x iout=%d \n", + __func__, data_h, data_l, iout); + } else if (tx_req == 0x13) { //vout + rx1619_write(chip, 0x38, + REG_RX_SENT_DATA1); //sent header + rx1619_write(chip, 0x13, REG_RX_SENT_DATA2); //sent cmd + + vout = rx1619_get_rx_vout(chip); + data_h = (vout & 0x00ff); + data_l = (vout & 0xff00) >> 8; + rx1619_write(chip, data_h, 0x0003); + rx1619_write(chip, data_l, 0x0004); + dev_info( + chip->dev, + "[rx1619] [%s] product test--0x13--0x%x,0x%x vout=%d \n", + __func__, data_h, data_l, vout); + } else if (tx_req == 0x24) { //firmware Version + rx1619_write(chip, 0x58, + REG_RX_SENT_DATA1); //sent header + rx1619_write(chip, 0x24, REG_RX_SENT_DATA2); //sent cmd + rx1619_write(chip, 0x00, REG_RX_SENT_DATA3); + rx1619_write(chip, 0x00, REG_RX_SENT_DATA4); + rx1619_write(chip, g_fw_rx_id, REG_RX_SENT_DATA5); + rx1619_write(chip, g_fw_tx_id, REG_RX_SENT_DATA6); + dev_info( + chip->dev, + "[rx1619] [%s] product test--0x24--rxtx_fw_version=0x%x,0x%x\n", + __func__, g_fw_rx_id, g_fw_tx_id); + } else if (tx_req == 0x23) { //RX chip ID + rx1619_write(chip, 0x38, + REG_RX_SENT_DATA1); //sent header + rx1619_write(chip, 0x23, REG_RX_SENT_DATA2); //sent cmd + rx1619_write(chip, g_hw_id_h, REG_RX_SENT_DATA3); + rx1619_write(chip, g_hw_id_l, REG_RX_SENT_DATA4); + dev_info( + chip->dev, + "[rx1619] [%s] product test--0x23--rx_hw_id=0x%x,0x%x\n", + __func__, g_hw_id_h, g_hw_id_l); + } else if (tx_req == 0x0b) { //USB type + rx1619_write(chip, 0x28, + REG_RX_SENT_DATA1); //sent header + rx1619_write(chip, 0x0b, REG_RX_SENT_DATA2); //sent cmd + rx1619_write(chip, g_USB_TYPE, REG_RX_SENT_DATA3); + dev_info( + chip->dev, + "[rx1619] [%s] product test--0x25--g_USB_TYPE=0x%x \n", + __func__, g_USB_TYPE); + } else + dev_err(chip->dev, + "[rx1619] [%s] product test--other cmd \n", + __func__); + + rx1619_write(chip, PRIVATE_PRODUCT_TEST_CMD, + REG_RX_SENT_CMD); //sent test cmd + rx1619_write(chip, AP_SENT_DATA_OK, REG_AP_RX_COMM); + break; + + default: + rx1619_write(chip, AP_REV_DATA_OK, REG_AP_RX_COMM); //receive ok + msleep(10); + dev_err(chip->dev, "[rx1619] [%s] other private cmd \n", + __func__); + break; + } + + mutex_unlock(&chip->wireless_chg_int_lock); + + return; +} + +static irqreturn_t rx1619_chg_stat_handler(int irq, void *dev_id) +{ + struct rx1619_chg *chip = dev_id; + //u8 rx_req = 0; + + dev_info(chip->dev, "[%s]\n", __func__); + + schedule_delayed_work(&chip->wireless_int_work, 0); + + return IRQ_HANDLED; +} + +static irqreturn_t rx1619_power_good_handler(int irq, void *dev_id) +{ + struct rx1619_chg *chip = dev_id; + + if (chip->fw_update) + return IRQ_HANDLED; + schedule_delayed_work(&chip->wpc_det_work, msecs_to_jiffies(0)); + + return IRQ_HANDLED; +} + +static int rx1619_parse_dt(struct rx1619_chg *chip) +{ + struct device_node *node = chip->dev->of_node; + + if (!node) { + dev_err(chip->dev, "[rx1619] [%s] No DT data Failing Probe\n", + __func__); + return -EINVAL; + } + + chip->tx_on_gpio = of_get_named_gpio(node, "rx,tx_on_gpio", 0); + if (!gpio_is_valid(chip->tx_on_gpio)) { + dev_err(chip->dev, "[rx1619] [%s] fail_tx_on gpio %d\n", + __func__, chip->tx_on_gpio); + return -EINVAL; + } + + chip->enable_gpio = of_get_named_gpio(node, "rx,enable", 0); + if ((!gpio_is_valid(chip->enable_gpio))) + return -EINVAL; + + chip->irq_gpio = of_get_named_gpio(node, "rx,irq_gpio", 0); + if (!gpio_is_valid(chip->irq_gpio)) { + dev_err(chip->dev, "[rx1619] [%s] fail_irq_gpio %d\n", __func__, + chip->irq_gpio); + return -EINVAL; + } + + chip->power_good_gpio = of_get_named_gpio(node, "rx,power_good", 0); + if (!gpio_is_valid(chip->power_good_gpio)) { + dev_err(chip->dev, "[rx1619] [%s] fail_power_good_gpio %d\n", + __func__, chip->power_good_gpio); + return -EINVAL; + } + + chip->wireless_by_usbin = + of_property_read_bool(node, "mi,wireless-by-usbin"); + + return 0; +} + +static int rx1619_gpio_init(struct rx1619_chg *chip) +{ + int ret = 0; + chip->rx_pinctrl = devm_pinctrl_get(chip->dev); + if (IS_ERR_OR_NULL(chip->rx_pinctrl)) { + dev_err(chip->dev, "No pinctrl config specified\n"); + ret = PTR_ERR(chip->dev); + return ret; + } + + chip->rx_gpio_active = + pinctrl_lookup_state(chip->rx_pinctrl, "nu_active"); + if (IS_ERR_OR_NULL(chip->rx_gpio_active)) { + dev_err(chip->dev, "No active config specified\n"); + ret = PTR_ERR(chip->rx_gpio_active); + return ret; + } + chip->rx_gpio_suspend = + pinctrl_lookup_state(chip->rx_pinctrl, "nu_suspend"); + if (IS_ERR_OR_NULL(chip->rx_gpio_suspend)) { + dev_err(chip->dev, "No suspend config specified\n"); + ret = PTR_ERR(chip->rx_gpio_suspend); + return ret; + } + + ret = pinctrl_select_state(chip->rx_pinctrl, chip->rx_gpio_active); + if (ret < 0) { + dev_err(chip->dev, "fail to select pinctrl active rc=%d\n", + ret); + return ret; + } + + if (gpio_is_valid(chip->irq_gpio)) { + chip->client->irq = gpio_to_irq(chip->irq_gpio); + if (chip->client->irq < 0) { + dev_err(chip->dev, "[rx1619] [%s] gpio_to_irq Fail! \n", + __func__); + goto fail_irq_gpio; + } + } else { + dev_err(chip->dev, "%s: irq gpio not provided\n", __func__); + goto fail_irq_gpio; + } + + if (gpio_is_valid(chip->power_good_gpio)) { + chip->power_good_irq = gpio_to_irq(chip->power_good_gpio); + if (chip->power_good_irq < 0) { + dev_err(chip->dev, "[rx1619] [%s] gpio_to_irq Fail! \n", + __func__); + goto fail_power_good_gpio; + } + } else { + dev_err(chip->dev, "%s: power good gpio not provided\n", + __func__); + goto fail_power_good_gpio; + } + + return ret; + +fail_irq_gpio: + gpio_free(chip->irq_gpio); +fail_power_good_gpio: + gpio_free(chip->power_good_gpio); + + return ret; +} + +/******************************************************* + * SET GPIO STATE TO SMB FOR IGNORE DC_POWER_ON IRQ* + *******************************************************/ +/* define for reverse state of wireless charging */ +#define REVERSE_GPIO_STATE_UNSET 0 +#define REVERSE_GPIO_STATE_START 1 +#define REVERSE_GPIO_STATE_END 2 +static int rx1619_set_reverse_gpio_state(struct rx1619_chg *chip, int enable) +{ + union power_supply_propval reverse_val = { + 0, + }; + chip->reverse_gpio_state = !!enable; + if (!chip->wireless_psy) + chip->wireless_psy = power_supply_get_by_name("wireless"); + + if (chip->wireless_psy) { + dev_dbg(chip->dev, "set_reverse_gpio_state\n", + reverse_val.intval); + if (enable) { + reverse_val.intval = REVERSE_GPIO_STATE_START; + } else { + reverse_val.intval = REVERSE_GPIO_STATE_END; + } + power_supply_set_property(chip->wireless_psy, + POWER_SUPPLY_PROP_REVERSE_GPIO_STATE, + &reverse_val); + } else { + dev_err(chip->dev, "no wireless_psy,return\n"); + return -EINVAL; + } + return 0; +} +static int rx_set_reverse_gpio(struct rx1619_chg *chip, int enable) +{ + int ret; + union power_supply_propval val = { + 0, + }; + + chip->wireless_psy = power_supply_get_by_name("wireless"); + if (!chip->wireless_psy) { + dev_err(chip->dev, "[idt] no wireless_psy,return\n"); + return -EINVAL; + } + + if (enable) { + val.intval = 1; + power_supply_set_property(chip->wireless_psy, + POWER_SUPPLY_PROP_SW_DISABLE_DC_EN, + &val); + } else { + val.intval = 0; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN, &val); + } + + if (gpio_is_valid(chip->tx_on_gpio)) { + rx1619_set_reverse_gpio_state(chip, enable); + ret = gpio_request(chip->tx_on_gpio, "tx-on-gpio"); + if (ret) { + dev_err(chip->dev, + "%s: unable to request tx_on gpio 130\n", + __func__); + } + ret = gpio_direction_output(chip->tx_on_gpio, enable); + if (ret) { + dev_err(chip->dev, + "%s: cannot set direction for tx_on gpio 130\n", + __func__); + } + + ret = gpio_get_value(chip->tx_on_gpio); + dev_info(chip->dev, "txon gpio: %d\n", ret); + gpio_free(chip->tx_on_gpio); + } else + dev_err(chip->dev, "%s: unable to set tx_on gpio_130\n"); + + return ret; +} + +static int rx_get_reverse_chg_mode(struct rx1619_chg *chip) +{ + int ret; + + if (gpio_is_valid(chip->tx_on_gpio)) + ret = gpio_get_value(chip->tx_on_gpio); + else { + dev_err(chip->dev, "%s: txon gpio not provided\n", __func__); + ret = -1; + } + dev_info(chip->dev, "txon gpio: %d\n", ret); + + return ret; +} + +#define REVERSE_COUNTRY_DOMESTIC 0 +#define REVERSE_COUNTRY_INTERNATIONAL 1 + +#define REVERSE_CURRENT_1000MA 0x0A +#define REVERSE_CURRENT_500MA 0x05 + +static int rx_set_reverse_chg_mode(struct rx1619_chg *chip, int enable) +{ + union power_supply_propval cp_val = { + 0, + }; + union power_supply_propval val = { + 0, + }; + union power_supply_propval wk_val = { + 0, + }; + int ret, rc; + + chip->wireless_psy = power_supply_get_by_name("wireless"); + if (!chip->wireless_psy) { + dev_err(chip->dev, "[idt] no wireless_psy,return\n"); + return -EINVAL; + } + + if (enable) { + val.intval = 1; + power_supply_set_property(chip->wireless_psy, + POWER_SUPPLY_PROP_SW_DISABLE_DC_EN, + &val); + } else { + val.intval = 0; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN, &val); + } + + if (gpio_is_valid(chip->tx_on_gpio)) { + rx1619_set_reverse_gpio_state(chip, enable); + ret = gpio_request(chip->tx_on_gpio, "tx-on-gpio"); + if (ret) { + dev_err(chip->dev, + "%s: unable to request tx_on gpio 130\n", + __func__); + } + ret = gpio_direction_output(chip->tx_on_gpio, enable); + if (ret) { + dev_err(chip->dev, + "%s: cannot set direction for tx_on gpio 130\n", + __func__); + } + gpio_free(chip->tx_on_gpio); + power_supply_changed(chip->wireless_psy); + dev_info(chip->dev, + "reverse_charge, set ln8282 powerpath and opmode\n"); + msleep(100); + if (enable) { + if (chip->wireless_psy) { + cp_val.intval = 3; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_DIV_2_MODE, &cp_val); + wk_val.intval = 1; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, + &wk_val); + } + msleep(100); + /* set reverse mode according to hw country */ + if (chip->hw_country == CountryGlobal || + chip->is_otg_insert) { + rx1619_set_reverse_parameter( + chip, REVERSE_COUNTRY_INTERNATIONAL, + REVERSE_CURRENT_500MA); + } else { + rx1619_set_reverse_parameter( + chip, REVERSE_COUNTRY_DOMESTIC, + REVERSE_CURRENT_1000MA); + } + /* set reverse fod */ + rx1619_set_reverse_fod(chip, 0, 0); + rx1619_start_tx_function(chip); + alarm_start_relative( + &chip->reverse_dping_alarm, + ms_to_ktime(REVERSE_DPING_CHECK_DELAY_MS)); + //schedule_delayed_work(&chip->reverse_dping_state_work, 10 * HZ); + } else { + dev_info(chip->dev, + "disable reverse charging for wireless\n"); + if (chip->wireless_psy) { + wk_val.intval = 0; + power_supply_set_property( + chip->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, + &wk_val); + } + cancel_delayed_work(&chip->reverse_chg_state_work); + cancel_delayed_work(&chip->reverse_dping_state_work); + + rc = alarm_cancel(&chip->reverse_dping_alarm); + if (rc < 0) + dev_err(chip->dev, + "Couldn't cancel reverse_dping_alarm\n"); + + rc = alarm_cancel(&chip->reverse_chg_alarm); + if (rc < 0) + dev_err(chip->dev, + "Couldn't cancel reverse_chg_alarm\n"); + pm_relax(chip->dev); + } + } else + dev_err(chip->dev, "%s: unable to set tx_on gpio_130\n"); + + return ret; +} + +static enum alarmtimer_restart reverse_chg_alarm_cb(struct alarm *alarm, + ktime_t now) +{ + struct rx1619_chg *chip = + container_of(alarm, struct rx1619_chg, reverse_chg_alarm); + + dev_info(chip->dev, " Reverse Chg Alarm Triggered %lld\n", + ktime_to_ms(now)); + + /* Atomic context, cannot use voter */ + pm_stay_awake(chip->dev); + schedule_delayed_work(&chip->reverse_chg_state_work, 0); + + return ALARMTIMER_NORESTART; +} + +static enum alarmtimer_restart cmd_timeout_alarm_cb(struct alarm *alarm, + ktime_t now) +{ + struct rx1619_chg *chip = + container_of(alarm, struct rx1619_chg, cmd_timeout_alarm); + + dev_info(chip->dev, " CMD_timeout_alarm Triggered %lld\n", + ktime_to_ms(now)); + + /* Atomic context, cannot use voter */ + schedule_delayed_work(&chip->cmd_timeout_work, 0); + + return ALARMTIMER_NORESTART; +} + +static enum alarmtimer_restart reverse_dping_alarm_cb(struct alarm *alarm, + ktime_t now) +{ + struct rx1619_chg *chip = + container_of(alarm, struct rx1619_chg, reverse_dping_alarm); + + dev_info(chip->dev, "Reverse Dping Alarm Triggered %lld\n", + ktime_to_ms(now)); + + /* Atomic context, cannot use voter */ + pm_stay_awake(chip->dev); + schedule_delayed_work(&chip->reverse_dping_state_work, 0); + + return ALARMTIMER_NORESTART; +} + +static void rx1619_set_present(struct rx1619_chg *chip, int enable) +{ + union power_supply_propval val = { + 0, + }; + + dev_info(chip->dev, "dc plug %s\n", enable ? "in" : "out"); + + if (enable) { + chip->dcin_present = 1; + } else { + chip->dcin_present = 0; + g_id_done_flag = 0; + g_epp_or_bpp = BPP_MODE; + chip->epp = 0; + chip->auth = 0; + chip->count_10v = 0; + chip->count_15v = 0; + chip->epp_exchange = 0; + chip->exchange = 0; + chip->last_vin = 0; + chip->last_icl = 0; + chip->last_qc3_icl = 0; + chip->op_mode = LN8282_OPMODE_UNKNOWN; + chip->status = NORMAL_MODE; + chip->target_vol = 0; + chip->target_curr = 0; + chip->is_car_tx = 0; + chip->is_voice_box_tx = 0; + g_USB_TYPE = 0; + chip->is_pan_tx = 0; + chip->disable_bq = false; + cancel_delayed_work_sync(&chip->wireless_int_work); + cancel_delayed_work(&chip->chg_monitor_work); + chip->ln_psy = power_supply_get_by_name("lionsemi"); + if (chip->ln_psy) + power_supply_set_property( + chip->ln_psy, + POWER_SUPPLY_PROP_RESET_DIV_2_MODE, &val); + + /* enable aicl if disabled by wireless earlier */ + rx1619_enable_aicl(chip, true); + if (chip->fcc_votable) { + vote(chip->fcc_votable, VOICE_LIMIT_FCC_VOTER, false, + 0); + vote(chip->fcc_votable, VOICE_LIMIT_FCC_1A_VOTER, false, + 0); + } + } +} +/* set otg state while reverse status */ +#define OTG_REG_ADDR 0x00 +#define OTG_PLUGIN_CMD 0x12 +#define OTG_PLUGOUT_CMD 0x11 +#define OTG_STATUS_CMD 0x0000 +#define OTG_TRIGGER_ADDR 0x000C +#define OTG_TRIGGER_CMD 0x55 + +static int rx_set_otg_state(struct rx1619_chg *chip, int plugin) +{ + int otg_status_cmd; + + chip->is_otg_insert = !!plugin; + + if (plugin) + otg_status_cmd = OTG_PLUGIN_CMD; + else + otg_status_cmd = OTG_PLUGOUT_CMD; + + dev_info(g_chip->dev, "set otg state: %d\n", plugin); + + if (chip->reverse_gpio_state) { + rx1619_write(chip, otg_status_cmd, OTG_REG_ADDR); + rx1619_write(chip, OTG_TRIGGER_CMD, OTG_TRIGGER_ADDR); + } + + return 0; +} + +static int rx_set_enable_mode(struct rx1619_chg *chip, int enable) +{ + int ret = 0; + int gpio_enable_val = 0; + + if (gpio_is_valid(chip->enable_gpio)) { + ret = gpio_request(chip->enable_gpio, "rx-enable-gpio"); + if (ret) { + dev_err(chip->dev, + "%s: unable to request enable gpio [%d]\n", + __func__, chip->enable_gpio); + } + + ret = gpio_direction_output(chip->enable_gpio, !enable); + if (ret) { + dev_err(chip->dev, + "%s: cannot set direction for idt enable gpio [%d]\n", + __func__, chip->enable_gpio); + } + gpio_enable_val = gpio_get_value(chip->enable_gpio); + pr_info("rx1619 enable gpio val is :%d\n", gpio_enable_val); + gpio_free(chip->enable_gpio); + } + + return ret; +} + +static ssize_t chip_vrect_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned int vrect = 0; + + vrect = rx1619_get_rx_vrect(g_chip); + + return scnprintf(buf, PAGE_SIZE, "rx1619 Vrect : %d mV\n", vrect); +} + +static ssize_t chip_vout_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + unsigned int vout = 0; + + vout = rx1619_get_rx_vout(g_chip); + + return scnprintf(buf, PAGE_SIZE, "%d\n", vout); +} + +static ssize_t chip_iout_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + unsigned int iout = 0; + + iout = rx1619_get_rx_iout(g_chip); + + return scnprintf(buf, PAGE_SIZE, "%d\n", iout); +} + +static ssize_t chip_vout_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + int index; + + index = (int)simple_strtoul(buf, NULL, 10); + dev_info(g_chip->dev, "[rx1619] [%s] --Store output_voltage = %d\n", + __func__, index); + if ((index < 4000) || (index > 21000)) { + dev_err(g_chip->dev, + "[rx1619] [%s] Store Voltage %s is invalid\n", __func__, + buf); + rx1619_set_vout(g_chip, 0); + return count; + } + + rx1619_set_vout(g_chip, index); + + return count; +} + +static ssize_t chip_debug_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data = 0; + + rx1619_dump_reg(); + msleep(100); + rx1619_get_rx_vout(g_chip); + rx1619_get_rx_vrect(g_chip); + rx1619_get_rx_iout(g_chip); + + return scnprintf(buf, PAGE_SIZE, "AP REQ DATA : 0x%x \n", data); +} + +static ssize_t chip_debug_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + return count; +} + +static ssize_t chip_fod_parameter_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int i; + for (i = 0; i < 8; i++) { + fod_param[i] = + (char)simple_strtoul(buf, NULL, 16); //fod_param[0] + buf += 3; + } + + for (i = 0; i < 8; i++) + dev_info(g_chip->dev, "[%s]: fod_param[%d] = 0x%x\n", __func__, + i, fod_param[i]); + + return count; +} + +static ssize_t chip_firmware_update_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + bool ret = false; + u8 boot_project_id_h = 0; + u8 boot_project_id_l = 0; + u8 tx_project_id_h = 0; + u8 tx_project_id_l = 0; + u8 rx_project_id_h = 0; + u8 rx_project_id_l = 0; + + dev_info(g_chip->dev, "[rx1619] [%s] Firmware Update begin\n", + __func__); + + if (g_chip->fw_update) { + dev_err(g_chip->dev, + "[rx1619] [%s] Firmware Update is on going!\n", + __func__); + return scnprintf(buf, PAGE_SIZE, "Firmware Update:Failed\n"); + } + + g_chip->fw_update = true; + rx_set_reverse_gpio(g_chip, true); + msleep(100); + ret = rx1619_onekey_download_firmware(g_chip); + if (!ret) { + dev_err(g_chip->dev, + "[rx1619] [%s] Firmware Update failed! Please try again!\n", + __func__); + rx_set_reverse_gpio(g_chip, false); + g_chip->fw_update = false; + return scnprintf(buf, PAGE_SIZE, "Firmware Update:Failed\n"); + + } else { + boot_fw_version = (~fw_data_boot[sizeof(fw_data_boot) - 1]) & + 0xff; + tx_fw_version = (~fw_data_tx[sizeof(fw_data_tx) - 1]) & 0xff; + rx_fw_version = (~fw_data_rx[sizeof(fw_data_rx) - 1]) & 0xff; + boot_project_id_h = (~fw_data_boot[sizeof(fw_data_boot) - 3]) & + 0xff; + boot_project_id_l = (~fw_data_boot[sizeof(fw_data_boot) - 2]) & + 0xff; + tx_project_id_h = (~fw_data_tx[sizeof(fw_data_tx) - 3]) & 0xff; + tx_project_id_l = (~fw_data_tx[sizeof(fw_data_tx) - 2]) & 0xff; + rx_project_id_h = (~fw_data_rx[sizeof(fw_data_rx) - 3]) & 0xff; + rx_project_id_l = (~fw_data_rx[sizeof(fw_data_rx) - 2]) & 0xff; + + dev_info( + g_chip->dev, + "boot_fw_version=%c%c_V%02x, tx_fw_version=%c%c_V%02x, rx_fw_version=%c%c_V%02x \n", + boot_project_id_h, boot_project_id_l, boot_fw_version, + tx_project_id_h, tx_project_id_l, tx_fw_version, + rx_project_id_h, rx_project_id_l, rx_fw_version); + + dev_info(g_chip->dev, + "[rx1619] [%s] Firmware Update Success!!! \n", + __func__); + rx_set_reverse_gpio(g_chip, false); + g_chip->fw_update = false; + g_chip->fw_version = g_fw_rx_id; + return scnprintf(buf, PAGE_SIZE, "Firmware Update:Success\n"); + } +} + +static ssize_t chip_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + if (!g_chip->fw_update) { + g_chip->fw_update = true; + rx_set_reverse_gpio(g_chip, true); + msleep(100); + rx1619_check_firmware_version(g_chip, BOOT_AREA); + rx1619_check_firmware_version(g_chip, TX_AREA); + rx1619_check_firmware_version(g_chip, RX_AREA); + rx_set_reverse_gpio(g_chip, false); + g_chip->fw_update = false; + return scnprintf(buf, PAGE_SIZE, + "app_ver:%02x.%02x.%02x.%x%x\n", g_fw_boot_id, + g_fw_tx_id, g_fw_rx_id, g_hw_id_h, g_hw_id_l); + } else { + return scnprintf(buf, PAGE_SIZE, + "fw update on going, cannot show version\n"); + } +} + +static ssize_t chip_vout_calibration_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int index = 0; + + index = (int)simple_strtoul(buf, NULL, 10); + + g_Delta = index; + dev_err(g_chip->dev, "[rx1619] [%s] g_Delta = %d \n", __func__, + g_Delta); + + return count; +} + +static ssize_t txon_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int mode; + + mode = rx_get_reverse_chg_mode(g_chip); + + return scnprintf(buf, PAGE_SIZE, "reverse chg mode : %d\n", mode); +} + +static ssize_t txon_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret, enable; + + ret = (int)simple_strtoul(buf, NULL, 10); + enable = !!ret; + + rx_set_reverse_gpio(g_chip, enable); + + return count; +} + +static ssize_t attr_firmware_bin_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + bool ret = false; + ret = rx1619_push_rx_firmware(g_chip); + if (!ret) { + dev_err(g_chip->dev, + "[rx1619] [%s] RX Firmware Push failed! Please try again!\n", + __func__); + return scnprintf( + buf, PAGE_SIZE, + "RX Firmware Push failed! Please try again! \n"); + + } else { + dev_info(g_chip->dev, "rx_fw_version=%c%c_V%02x \n", + rx_bin_project_id_h, rx_bin_project_id_l, + rx_fw_version); + dev_info(g_chip->dev, + "[rx1619] [%s] RX Firmware Push Success!!! \n", + __func__); + return scnprintf( + buf, PAGE_SIZE, + "RX Firmware Push Success!!! rx_fw_ver=%c%c_V%02x\n", + rx_bin_project_id_h, rx_bin_project_id_l, + rx_fw_version); + } +} + +static ssize_t attr_firmware_bin_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + u8 *rx_fw_bin = NULL; + if (g_chip->rx_fw_len + count >= 3 * 1024 * 1024) { + dev_err(g_chip->dev, "The firmware is too large.\n"); + goto out; + } + + rx_fw_bin = kmalloc(count + g_chip->rx_fw_len, GFP_KERNEL); + if (rx_fw_bin == NULL) { + dev_err(g_chip->dev, "write %d bytes failed.\n", (int)count); + goto out; + } + + memcpy(rx_fw_bin, g_chip->rx_fw_bin, g_chip->rx_fw_len); + memcpy(rx_fw_bin + g_chip->rx_fw_len, buf, count); + if (g_chip->rx_fw_bin != NULL) { + kfree(g_chip->rx_fw_bin); + } + g_chip->rx_fw_bin = rx_fw_bin; + g_chip->rx_fw_len += count; + +out: + return count; +} +static DEVICE_ATTR(chip_vrect, S_IRUGO, chip_vrect_show, NULL); +static DEVICE_ATTR(chip_vout_calibration, S_IWUSR, NULL, + chip_vout_calibration_store); +static DEVICE_ATTR(chip_firmware_update, S_IWUSR | S_IRUGO, + chip_firmware_update_show, NULL); +static DEVICE_ATTR(chip_fw_bin, S_IWUSR | S_IRUGO, attr_firmware_bin_show, + attr_firmware_bin_store); +static DEVICE_ATTR(chip_version, S_IRUGO, chip_version_show, NULL); +static DEVICE_ATTR(chip_vout, S_IWUSR | S_IRUGO, chip_vout_show, + chip_vout_store); +static DEVICE_ATTR(chip_iout, S_IRUGO, chip_iout_show, NULL); +static DEVICE_ATTR(chip_debug, S_IWUSR | S_IRUGO, chip_debug_show, + chip_debug_store); +static DEVICE_ATTR(txon, S_IWUSR | S_IRUGO, txon_show, txon_store); +static DEVICE_ATTR(chip_fod_parameter, S_IWUSR | S_IRUGO, NULL, + chip_fod_parameter_store); + +static struct attribute *rx1619_sysfs_attrs[] = { + &dev_attr_chip_vrect.attr, + &dev_attr_chip_version.attr, + &dev_attr_chip_vout.attr, + &dev_attr_chip_iout.attr, + &dev_attr_chip_debug.attr, + &dev_attr_chip_fw_bin.attr, + &dev_attr_chip_firmware_update.attr, + &dev_attr_chip_vout_calibration.attr, + &dev_attr_txon.attr, + &dev_attr_chip_fod_parameter.attr, + NULL, +}; + +static const struct attribute_group rx1619_sysfs_group_attrs = { + .attrs = rx1619_sysfs_attrs, +}; + +#if 1 +static enum power_supply_property rx1619_wireless_properties[] = { + /* + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_CHARGING_ENABLED, + POWER_SUPPLY_PROP_RX_CHIP_ID, //RX chip id + POWER_SUPPLY_PROP_RX_VRECT, //RX vrect + POWER_SUPPLY_PROP_RX_IOUT, //RX output current + POWER_SUPPLY_PROP_RX_VOUT, //RX output voltage + POWER_SUPPLY_PROP_RX_ILIMIT, //RX Main LDO output current limit + POWER_SUPPLY_PROP_VOUT_SET, //Vout voltage set + */ + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_SIGNAL_STRENGTH, + POWER_SUPPLY_PROP_PIN_ENABLED, + POWER_SUPPLY_PROP_REVERSE_CHG_MODE, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_VRECT, + POWER_SUPPLY_PROP_RX_IOUT, + POWER_SUPPLY_PROP_TX_ADAPTER, + POWER_SUPPLY_PROP_WIRELESS_VERSION, + POWER_SUPPLY_PROP_WIRELESS_FW_VERSION, + POWER_SUPPLY_PROP_CHIP_OK, + POWER_SUPPLY_PROP_OTG_STATE, +}; + +static int rx1619_wireless_set_property(struct power_supply *psy, + enum power_supply_property prop, + const union power_supply_propval *val) +{ + int ret; + struct rx1619_chg *chip = power_supply_get_drvdata(psy); + int data; + + switch (prop) { + /* + case POWER_SUPPLY_PROP_PRESENT: + break; + case POWER_SUPPLY_PROP_CHARGING_ENABLED: + rx1619_chip_enable(chip, val->intval); + break; + case POWER_SUPPLY_PROP_VOUT_SET: + ret = rx1619_set_vout(chip, val->intval); + if(ret < 0) + return ret; + break; + */ + case POWER_SUPPLY_PROP_PRESENT: + rx1619_set_present(chip, val->intval); + break; + case POWER_SUPPLY_PROP_SIGNAL_STRENGTH: + chip->ss = val->intval; + if (chip->wireless_psy) + power_supply_changed(chip->wireless_psy); + break; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + data = val->intval / 1000; + if (data < ADAPTER_VOUT_LIMIT_VOL) + data = ADAPTER_VOUT_LIMIT_VOL; + else if (data > 10000) + data = 10000; + if (chip->op_mode == LN8282_OPMODE_SWITCHING) + data *= 2; + else if (chip->epp) + data = EPP_VOL_THRESHOLD; + if (!chip->disable_bq) + ret = rx1619_set_vout(chip, data); + break; + case POWER_SUPPLY_PROP_PIN_ENABLED: + ret = rx_set_enable_mode(chip, val->intval); + break; + case POWER_SUPPLY_PROP_REVERSE_CHG_MODE: + if (chip->fw_update) { + dev_info(chip->dev, "fw update going, break\n"); + break; + } + chip->is_reverse_chg = 0; + schedule_delayed_work(&chip->reverse_sent_state_work, 0); + if (!chip->power_good_flag) { + ret = rx_set_reverse_chg_mode(chip, val->intval); + } else { + chip->is_reverse_chg = 3; + schedule_delayed_work(&chip->reverse_sent_state_work, + 0); + } + break; + case POWER_SUPPLY_PROP_OTG_STATE: + rx_set_otg_state(chip, val->intval); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int rx1619_wireless_get_property(struct power_supply *psy, + enum power_supply_property prop, + union power_supply_propval *val) +{ + int tmp; + struct rx1619_chg *chip = power_supply_get_drvdata(psy); + + switch (prop) { + /* + case POWER_SUPPLY_PROP_ONLINE: + val->intval = chip->online; + break; + case POWER_SUPPLY_PROP_CHARGING_ENABLED: + val->intval = chip->chip_enable; + break; + case POWER_SUPPLY_PROP_RX_CHIP_ID: + val->intval = rx1619_get_rx_chip_id(chip); + break; + case POWER_SUPPLY_PROP_RX_VRECT: + val->intval = rx1619_get_rx_vrect(chip); + break; + case POWER_SUPPLY_PROP_RX_IOUT: + val->intval = rx1619_get_rx_iout(chip); + break; + case POWER_SUPPLY_PROP_RX_VOUT: + val->intval = rx1619_get_rx_vout(chip); + break; + case POWER_SUPPLY_PROP_VOUT_SET: + val->intval = 0; + break; + */ + case POWER_SUPPLY_PROP_WIRELESS_VERSION: + val->intval = chip->epp; + break; + case POWER_SUPPLY_PROP_WIRELESS_FW_VERSION: + val->intval = chip->fw_version; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = chip->dcin_present; + break; + case POWER_SUPPLY_PROP_SIGNAL_STRENGTH: + val->intval = chip->ss; + break; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + if (!chip->power_good_flag) { + val->intval = 0; + break; + } + tmp = rx1619_get_rx_vout(chip); + if (chip->op_mode == LN8282_OPMODE_SWITCHING) + val->intval = tmp / 2; + else + val->intval = tmp; + break; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_VRECT: + val->intval = rx1619_get_rx_vrect(chip); + break; + case POWER_SUPPLY_PROP_RX_IOUT: + val->intval = rx1619_get_rx_iout(chip); + break; + case POWER_SUPPLY_PROP_PIN_ENABLED: + val->intval = !gpio_get_value(chip->enable_gpio); + break; + case POWER_SUPPLY_PROP_REVERSE_CHG_MODE: + val->intval = rx_get_reverse_chg_mode(chip); + break; + case POWER_SUPPLY_PROP_TX_ADAPTER: + val->intval = g_USB_TYPE; + break; + case POWER_SUPPLY_PROP_CHIP_OK: + val->intval = chip->chip_ok; + break; + default: + return -EINVAL; + } + return 0; +} +#endif + +// first step: define regmap_config +static const struct regmap_config rx1619_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .max_register = 0xFFFF, +}; + +static int rx1619_prop_is_writeable(struct power_supply *psy, + enum power_supply_property psp) +{ + int rc; + + switch (psp) { + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + case POWER_SUPPLY_PROP_PIN_ENABLED: + case POWER_SUPPLY_PROP_REVERSE_CHG_MODE: + case POWER_SUPPLY_PROP_PRESENT: + case POWER_SUPPLY_PROP_SIGNAL_STRENGTH: + return 1; + default: + rc = 0; + break; + } + + return rc; +} + +extern char *saved_command_line; + +static int get_cmdline(struct rx1619_chg *chip) +{ + if (strnstr(saved_command_line, + "androidboot.mode=", strlen(saved_command_line))) { + chip->power_off_mode = 1; + dev_info(chip->dev, + "[idtp9220]: enter power off charging app\n"); + } else { + chip->power_off_mode = 0; + dev_info(chip->dev, "[idtp9220]: enter normal boot mode\n"); + } + return 1; +} + +static int rx1619_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0; + struct rx1619_chg *chip; + struct kobject *rx1619_kobj; + //int drv_load = 0; + + struct power_supply_config wip_psy_cfg = {}; + /* + drv_load = get_board_version(); + if (!drv_load) + return 0; +*/ + + /* + int hw_id; + + struct power_supply *batt_psy; + + batt_psy = power_supply_get_by_name("battery"); + if (!batt_psy) { + dev_err(&client->dev, "Battery supply not found; defer probe\n"); + return -EPROBE_DEFER; + } + + hw_id = get_hw_country_version(); + dev_info(&client->dev, "[rx1619] %s: hw_id is %d\n", __func__, hw_id); + if (hw_id) //hw_id=1 is idt + return 0; + */ + + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) { + dev_err(&client->dev, + "i2c allocated device info data failed!\n"); + return -ENOMEM; + } + + chip->regmap = regmap_init_i2c(client, &rx1619_regmap_config); + if (!chip->regmap) { + dev_err(&client->dev, "parent regmap is missing\n"); + return -EINVAL; + } + + chip->client = client; + chip->dev = &client->dev; + + //chip->batt_psy = batt_psy; + //chip->online = 0; + chip->chip_enable = false; + chip->ss = 2; + chip->fw_update = false; + chip->fw_version = 0; + + device_init_wakeup(&client->dev, true); + i2c_set_clientdata(client, chip); + + rx1619_parse_dt(chip); + rx1619_gpio_init(chip); + + mutex_init(&chip->wireless_chg_lock); + mutex_init(&chip->wireless_chg_int_lock); + mutex_init(&chip->sysfs_op_lock); + INIT_DELAYED_WORK(&chip->wireless_int_work, rx1619_wireless_int_work); + INIT_DELAYED_WORK(&chip->wpc_det_work, rx1619_wpc_det_work); + INIT_DELAYED_WORK(&chip->chg_monitor_work, rx_monitor_work); + INIT_DELAYED_WORK(&chip->chg_detect_work, rx_chg_detect_work); + INIT_DELAYED_WORK(&chip->reverse_sent_state_work, + reverse_chg_sent_state_work); + INIT_DELAYED_WORK(&chip->reverse_chg_state_work, + reverse_chg_state_set_work); + INIT_DELAYED_WORK(&chip->reverse_dping_state_work, + reverse_dping_state_set_work); + INIT_DELAYED_WORK(&chip->dc_check_work, rx1619_dc_check_work); + INIT_DELAYED_WORK(&chip->cmd_timeout_work, rx1619_cmd_timeout_work); + INIT_DELAYED_WORK(&chip->fw_download_work, rx1619_fw_download_work); + INIT_DELAYED_WORK(&chip->rx_first_boot, rx1619_rx_first_boot); + INIT_DELAYED_WORK(&chip->pan_tx_work, rx1619_pan_tx_work); + INIT_DELAYED_WORK(&chip->voice_tx_work, rx1619_voice_tx_work); + + chip->wip_psy_d.name = "rx1619"; + chip->wip_psy_d.type = POWER_SUPPLY_TYPE_WIRELESS; + chip->wip_psy_d.get_property = rx1619_wireless_get_property; + chip->wip_psy_d.set_property = rx1619_wireless_set_property; + chip->wip_psy_d.properties = rx1619_wireless_properties; + chip->wip_psy_d.num_properties = ARRAY_SIZE(rx1619_wireless_properties); + chip->wip_psy_d.property_is_writeable = rx1619_prop_is_writeable, + + wip_psy_cfg.drv_data = chip; + + chip->wip_psy = devm_power_supply_register(chip->dev, &chip->wip_psy_d, + &wip_psy_cfg); + if (IS_ERR(chip->wip_psy)) { + dev_err(chip->dev, "Couldn't register wip psy rc=%ld\n", + PTR_ERR(chip->wip_psy)); + return ret; + } + + if (chip->client->irq) { + ret = devm_request_threaded_irq( + &chip->client->dev, chip->client->irq, NULL, + rx1619_chg_stat_handler, + (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | + IRQF_ONESHOT), + "rx1619_chg_stat_irq", chip); + if (ret) { + dev_err(chip->dev, "Failed irq = %d ret = %d\n", + chip->client->irq, ret); + } + } + enable_irq_wake(chip->client->irq); + + if (chip->power_good_irq) { + ret = devm_request_threaded_irq( + &chip->client->dev, chip->power_good_irq, NULL, + rx1619_power_good_handler, + (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | + IRQF_ONESHOT), + "rx1619_power_good_irq", chip); + if (ret) { + dev_err(chip->dev, "Failed irq = %d ret = %d\n", + chip->power_good_irq, ret); + } + } + enable_irq_wake(chip->power_good_irq); + + rx1619_kobj = kobject_create_and_add("rx1619", NULL); + if (!rx1619_kobj) { + dev_err(chip->dev, "sysfs_create_group fail"); + goto error_sysfs; + } + ret = sysfs_create_group(rx1619_kobj, &rx1619_sysfs_group_attrs); + if (ret < 0) { + dev_err(chip->dev, "sysfs_create_group fail %d\n", ret); + goto error_sysfs; + } + + determine_initial_status(chip); + + //rx1619_dump_reg(); + g_chip = chip; + + if (alarmtimer_get_rtcdev()) { + alarm_init(&chip->reverse_dping_alarm, ALARM_BOOTTIME, + reverse_dping_alarm_cb); + } else { + dev_err(chip->dev, + "Failed to initialize reverse dping alarm\n"); + return -ENODEV; + } + + if (alarmtimer_get_rtcdev()) { + alarm_init(&chip->reverse_chg_alarm, ALARM_BOOTTIME, + reverse_chg_alarm_cb); + } else { + dev_err(chip->dev, "Failed to initialize reverse chg alarm\n"); + return -ENODEV; + } + + if (alarmtimer_get_rtcdev()) { + alarm_init(&chip->cmd_timeout_alarm, ALARM_BOOTTIME, + cmd_timeout_alarm_cb); + } else { + dev_err(chip->dev, "Failed to initialize cmd_timeout_alarm\n"); + return -ENODEV; + } + chip->hw_country = get_hw_country_version(); + dev_info(&client->dev, "hw_country: %d\n", chip->hw_country); + + dev_err(chip->dev, "[rx1619] [%s] success! \n", __func__); + get_cmdline(chip); + + if (chip->power_off_mode) { + rx_set_enable_mode(chip, false); + usleep_range(20000, 25000); + rx_set_enable_mode(chip, true); + } else { + schedule_delayed_work(&chip->chg_detect_work, 3 * HZ); + } + if (!g_rx1619_first_flag) + schedule_delayed_work(&chip->rx_first_boot, + msecs_to_jiffies(45000)); + return 0; + +error_sysfs: + sysfs_remove_group(rx1619_kobj, &rx1619_sysfs_group_attrs); + dev_err(chip->dev, "[rx1619] [%s] rx1619 probe error_sysfs! \n", + __func__); + + if (chip->irq_gpio > 0) + gpio_free(chip->irq_gpio); + + return 0; +} + +static void rx1619_shutdown(struct i2c_client *client) +{ + struct rx1619_chg *chip = i2c_get_clientdata(client); + + if (chip->power_good_flag) { + rx_set_enable_mode(chip, false); + usleep_range(20000, 25000); + rx_set_enable_mode(chip, true); + } +} + +static int rx1619_remove(struct i2c_client *client) +{ + struct rx1619_chg *chip = i2c_get_clientdata(client); + cancel_delayed_work_sync(&chip->wireless_int_work); + + return 0; +} +static const struct i2c_device_id rx1619_id[] = { + { rx1619_DRIVER_NAME, 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, rx1619_id); + +static struct of_device_id rx1619_match_table[] = { + { + .compatible = "nuvolta,wl_charger_rx1619", + }, + {} +}; + +static struct i2c_driver rx1619_driver = { + .driver = { + .name = rx1619_DRIVER_NAME, + .of_match_table = rx1619_match_table, + }, + .probe = rx1619_probe, + .remove = rx1619_remove, + .shutdown = rx1619_shutdown, + .id_table = rx1619_id, +}; + +static int __init rx1619_init(void) +{ + int ret; + uint32_t hw_version = 0; +#ifdef CONFIG_RX1619_REMOVE + return 0; +#endif + hw_version = get_hw_version_platform(); + printk("rx1619: hw version: %d\n", hw_version); + + printk("is_nvt_rx flag is:%d\n", is_nvt_rx); + if (!is_nvt_rx) + return 0; + + ret = i2c_add_driver(&rx1619_driver); + if (ret) + printk(KERN_ERR "rx1619 i2c driver init failed!\n"); + + return ret; +} + +static void __exit rx1619_exit(void) +{ + i2c_del_driver(&rx1619_driver); +} + +static int __init early_parse_oled_pmic_id(char *p) +{ + if (p) { + if (!strcmp(p, "0B") || !strcmp(p, "0C")) + is_nvt_rx = true; + } + + return 0; +} +early_param("androidboot.oled_pmic_id", early_parse_oled_pmic_id); + +late_initcall(rx1619_init); +module_exit(rx1619_exit); + +MODULE_AUTHOR("colin"); +MODULE_DESCRIPTION("NUVOLTA Wireless Power Charger Monitor driver"); +MODULE_LICENSE("GPL/BSD"); diff --git a/drivers/power/supply/nuvolta/rx1619.h b/drivers/power/supply/nuvolta/rx1619.h new file mode 100644 index 000000000000..8791019582fe --- /dev/null +++ b/drivers/power/supply/nuvolta/rx1619.h @@ -0,0 +1,2741 @@ +u8 chip_default_data[2] = { 0x47, 0x10 }; + +//J2 fw version 0x15 +u8 fw_data_boot[1016] = { + 0xff, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, + 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, + 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, + 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, + 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, + 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, + 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, + 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, + 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, + 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, + 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xaf, 0xfe, 0xff, 0xff, + 0xb7, 0xfe, 0xff, 0xff, 0xa7, 0xfe, 0xff, 0xff, 0x8f, 0xfe, 0xff, 0xff, + 0x87, 0xfe, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0x77, 0xfe, 0xff, 0xff, + 0x6f, 0xfe, 0xff, 0xff, 0x67, 0xfe, 0xff, 0xff, 0x5f, 0xfe, 0xff, 0xff, + 0x57, 0xfe, 0xff, 0xff, 0x4f, 0xfe, 0xff, 0xff, 0x47, 0xfe, 0xff, 0xff, + 0x9f, 0xfe, 0xff, 0xff, 0x97, 0xfe, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, + 0x37, 0xfe, 0xff, 0xff, 0x2f, 0xfe, 0xff, 0xff, 0x27, 0xfe, 0xff, 0xff, + 0x1f, 0xfe, 0xff, 0xff, 0x17, 0xfe, 0xff, 0xff, 0x0f, 0xfe, 0xff, 0xff, + 0x07, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xf7, 0xfd, 0xff, 0xff, + 0xef, 0xfd, 0xff, 0xff, 0xef, 0xfd, 0xff, 0xff, 0xef, 0xfd, 0xff, 0xff, + 0xef, 0xfd, 0xff, 0xff, 0xef, 0xfd, 0xff, 0xff, 0xef, 0xfd, 0xff, 0xff, + 0xef, 0xfd, 0xff, 0xff, 0x94, 0xef, 0xfc, 0x3f, 0xdf, 0x9b, 0xb4, 0xef, + 0xfd, 0x3f, 0xde, 0x9b, 0xb5, 0xef, 0x9f, 0x6d, 0xbc, 0x14, 0xdf, 0xff, + 0xf8, 0xf7, 0xfd, 0x15, 0xff, 0xb3, 0x9f, 0x6d, 0xf3, 0x87, 0xff, 0x1f, + 0x7e, 0xff, 0xfd, 0x15, 0xff, 0xfb, 0x9f, 0x6d, 0xf3, 0x87, 0xff, 0xfb, + 0xff, 0xfe, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xef, 0x6f, 0xff, 0xbf, + 0xff, 0x1f, 0xfb, 0xff, 0xff, 0x3f, 0xdf, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xc3, 0x87, 0xff, 0xff, + 0xc3, 0x87, 0xff, 0xff, 0xff, 0xcf, 0xc3, 0x87, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xb1, 0xaa, 0xe9, 0xe6, 0xdf, 0xb5, 0xcd, 0xea +}; + +u8 fw_data_tx[13304] = { + 0xff, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, + 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, + 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, 0x93, 0xb2, 0xff, 0xff, + 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, + 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, + 0x9b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, + 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, + 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, + 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, + 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, + 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, 0x63, 0x8b, 0xff, 0xff, + 0xff, 0x8a, 0xff, 0xff, 0x4f, 0x8b, 0xff, 0xff, 0x2b, 0x8b, 0xff, 0xff, + 0x23, 0x8b, 0xff, 0xff, 0xeb, 0x8a, 0xff, 0xff, 0xe3, 0x8a, 0xff, 0xff, + 0x1b, 0x8b, 0xff, 0xff, 0x13, 0x8b, 0xff, 0xff, 0xcb, 0x8a, 0xff, 0xff, + 0x9f, 0x8a, 0xff, 0xff, 0x97, 0x8a, 0xff, 0xff, 0x8f, 0x8a, 0xff, 0xff, + 0x3b, 0x8b, 0xff, 0xff, 0x33, 0x8b, 0xff, 0xff, 0x87, 0x8a, 0xff, 0xff, + 0x7f, 0x8a, 0xff, 0xff, 0x77, 0x8a, 0xff, 0xff, 0x5b, 0x8a, 0xff, 0xff, + 0x53, 0x8a, 0xff, 0xff, 0x4b, 0x8a, 0xff, 0xff, 0x43, 0x8a, 0xff, 0xff, + 0x3b, 0x8a, 0xff, 0xff, 0x33, 0x8a, 0xff, 0xff, 0x2b, 0x8a, 0xff, 0xff, + 0x23, 0x8a, 0xff, 0xff, 0x23, 0x8a, 0xff, 0xff, 0x23, 0x8a, 0xff, 0xff, + 0x23, 0x8a, 0xff, 0xff, 0x23, 0x8a, 0xff, 0xff, 0x23, 0x8a, 0xff, 0xff, + 0x23, 0x8a, 0xff, 0xff, 0x8e, 0xef, 0xfc, 0x3f, 0xdf, 0x9b, 0xae, 0xef, + 0xfd, 0x3f, 0xde, 0x9b, 0xcf, 0xef, 0x78, 0x90, 0x0f, 0xef, 0x2e, 0xef, + 0x4e, 0xef, 0x63, 0x9a, 0xf8, 0xf7, 0x7f, 0x6a, 0x7f, 0x48, 0xfc, 0xda, + 0xfc, 0xd8, 0x63, 0x9a, 0x04, 0xf0, 0x91, 0xef, 0xb1, 0xef, 0x71, 0x9f, + 0xbd, 0xb5, 0xbf, 0xc5, 0xf8, 0xf3, 0xff, 0xce, 0xdf, 0x4c, 0xfc, 0xdc, + 0xff, 0xd5, 0xbf, 0xc5, 0x03, 0xf4, 0xff, 0x1f, 0x0a, 0xe9, 0xff, 0xfb, + 0xff, 0xfe, 0xff, 0x7f, 0xff, 0xb3, 0xff, 0xff, 0x07, 0xfd, 0xff, 0xdf, + 0xff, 0xff, 0xff, 0xdf, 0xfb, 0xff, 0xff, 0xdf, 0x47, 0x82, 0xff, 0xff, + 0xfb, 0xff, 0xff, 0xdf, 0x7f, 0xfe, 0xff, 0xdf, 0xff, 0x1f, 0xa7, 0xec, + 0xff, 0x3f, 0xdf, 0xbf, 0xff, 0x1f, 0x89, 0xec, 0xff, 0x3f, 0xdf, 0xbf, + 0xff, 0x1f, 0xd1, 0xec, 0xff, 0x3f, 0xdf, 0xbf, 0xbf, 0xc6, 0xfc, 0xf7, + 0xff, 0x3f, 0xdf, 0xd3, 0xbf, 0xc7, 0xfd, 0xf7, 0xc3, 0x87, 0x3d, 0xeb, + 0xbc, 0x92, 0xba, 0x92, 0x1f, 0x38, 0x7f, 0xd7, 0xfc, 0xf3, 0xfd, 0x93, + 0xff, 0xdf, 0x1e, 0x38, 0x7f, 0xd7, 0xfc, 0xf3, 0xb9, 0x93, 0xff, 0xde, + 0xfe, 0xcd, 0x3c, 0x93, 0xfc, 0x3b, 0xbb, 0x83, 0x6f, 0x8f, 0xef, 0x8f, + 0x38, 0x93, 0xfc, 0x3b, 0xbb, 0x83, 0xff, 0xdb, 0x3c, 0x93, 0x2e, 0x8f, + 0xed, 0x92, 0xdf, 0xdb, 0x6f, 0x8f, 0xef, 0x8f, 0xbf, 0xc5, 0xf6, 0xf3, + 0xff, 0x3b, 0xdf, 0xb3, 0x32, 0x9f, 0xb3, 0x9b, 0xfd, 0xf3, 0x39, 0x9f, + 0x76, 0x9f, 0x06, 0xf0, 0xf4, 0x93, 0xb0, 0x93, 0xfa, 0x3b, 0xda, 0xb3, + 0xfa, 0xf3, 0xfd, 0x93, 0xff, 0xdf, 0xb9, 0x93, 0xff, 0xde, 0x7d, 0xeb, + 0xbf, 0xc6, 0xfc, 0xf7, 0xff, 0x3f, 0xdf, 0xd3, 0xbf, 0xc7, 0xfd, 0xf7, + 0xc3, 0x87, 0x3e, 0xeb, 0xfe, 0xcd, 0x3c, 0x93, 0xfc, 0x3b, 0xbb, 0x83, + 0x6f, 0x8f, 0xef, 0x8f, 0x38, 0x93, 0xfc, 0x3b, 0xbb, 0x83, 0xff, 0xdb, + 0x3c, 0x93, 0x2e, 0x8f, 0xed, 0x92, 0xdf, 0xdb, 0x6f, 0x8f, 0xef, 0x8f, + 0xbf, 0xc5, 0xf6, 0xf3, 0xff, 0x3b, 0xdf, 0xb3, 0x32, 0x9f, 0xb3, 0x9b, + 0xfd, 0xf3, 0x39, 0x9f, 0x76, 0x9f, 0x06, 0xf0, 0xf4, 0x93, 0xb0, 0x93, + 0x7e, 0xeb, 0xff, 0xff, 0xbf, 0xc6, 0xfc, 0xf7, 0xff, 0x3f, 0xdf, 0xd3, + 0xbf, 0xc7, 0xfd, 0xf7, 0xc3, 0x87, 0x7c, 0x93, 0xfd, 0x3b, 0xbc, 0x83, + 0xfe, 0xcd, 0x73, 0x8f, 0xf3, 0x8f, 0xff, 0xcc, 0xff, 0x3b, 0xdf, 0xb3, + 0x32, 0x9f, 0xb3, 0x9b, 0xfd, 0xf3, 0x39, 0x9f, 0x76, 0x9f, 0x06, 0xf0, + 0xf0, 0x93, 0xc3, 0x87, 0x2e, 0xeb, 0x61, 0xce, 0xc8, 0xbe, 0xfc, 0x92, + 0xff, 0x1f, 0x9d, 0xfe, 0x1f, 0x38, 0x7f, 0xd7, 0xfa, 0xf3, 0xec, 0x93, + 0xff, 0x1f, 0x59, 0xfe, 0x6e, 0xeb, 0x61, 0xce, 0xc8, 0xbe, 0xec, 0x93, + 0xff, 0x1f, 0x31, 0xff, 0xff, 0x1f, 0x61, 0xfe, 0x7f, 0xcc, 0x87, 0xbc, + 0xf3, 0xa7, 0x6e, 0xeb, 0x3b, 0xeb, 0xde, 0xeb, 0x7f, 0x6f, 0xfe, 0xca, + 0xeb, 0x9a, 0xba, 0xf7, 0x9f, 0x6e, 0x2b, 0x9b, 0x7b, 0xf7, 0xbb, 0xc3, + 0x69, 0xf3, 0xbb, 0xc4, 0x7f, 0xf3, 0xbd, 0xc4, 0xa5, 0xf3, 0xbd, 0xc3, + 0x83, 0xf3, 0x9c, 0x6f, 0x7d, 0x6f, 0x1d, 0x6e, 0x9f, 0x47, 0x82, 0xa3, + 0x1c, 0x38, 0x7f, 0xd7, 0x5c, 0x6e, 0x70, 0x92, 0x92, 0xf7, 0xc0, 0xc1, + 0xcf, 0xf3, 0xdf, 0xc4, 0x8e, 0xf7, 0xfe, 0xcc, 0x27, 0x8f, 0xff, 0xd4, + 0x3a, 0x3b, 0xb8, 0xbf, 0xb3, 0x96, 0xbf, 0xc2, 0xff, 0x3b, 0xfa, 0xfa, + 0xa3, 0x92, 0x9e, 0x6f, 0xde, 0x6e, 0xb1, 0x9b, 0xd8, 0xf3, 0xbf, 0xc4, + 0xb6, 0xf3, 0x3f, 0x67, 0x46, 0xa2, 0x1a, 0x38, 0x7f, 0xd7, 0xb6, 0xf7, + 0xff, 0xc9, 0x3e, 0x4d, 0x7d, 0x4d, 0x5c, 0x4d, 0x9c, 0xa2, 0xe7, 0xee, + 0x3f, 0x9b, 0xf6, 0xf3, 0x9d, 0x6d, 0x5e, 0xba, 0xdc, 0xa2, 0xbf, 0x9b, + 0xff, 0xd4, 0x03, 0xf4, 0x5c, 0x4d, 0x9d, 0x4d, 0xfc, 0xcc, 0x1a, 0x38, + 0x7f, 0xd7, 0x9f, 0x4d, 0xea, 0xf7, 0xf4, 0x93, 0xfe, 0xeb, 0x7b, 0xeb, + 0xe2, 0x9a, 0xc9, 0xf3, 0x9e, 0x6f, 0xde, 0x6e, 0xb1, 0x9b, 0xff, 0xca, + 0x24, 0xf4, 0x3f, 0x67, 0x47, 0xa2, 0x9e, 0x4d, 0x1a, 0x38, 0x7f, 0xd7, + 0xfc, 0xcc, 0x7d, 0x4d, 0x5c, 0x4d, 0x9f, 0x4d, 0x12, 0xf0, 0x9a, 0x1b, + 0xfe, 0xdf, 0x5e, 0xb2, 0xb3, 0x92, 0x9d, 0x6d, 0xff, 0xdc, 0xf4, 0x93, + 0x5c, 0x4d, 0x9d, 0x4d, 0xfe, 0xeb, 0x7b, 0xeb, 0xbd, 0xc3, 0x1e, 0xf4, + 0x9f, 0x4d, 0x3e, 0x6f, 0x3e, 0x4d, 0x9d, 0x6f, 0x9d, 0x4d, 0x3c, 0x6f, + 0x3c, 0x4d, 0x9e, 0x6f, 0xde, 0x6e, 0x3b, 0x97, 0x9e, 0x4d, 0xf4, 0x93, + 0x2b, 0xf8, 0x9f, 0x67, 0x4a, 0xa4, 0x1a, 0x38, 0x7f, 0xd7, 0x46, 0xf0, + 0xfe, 0xcc, 0x9e, 0x4d, 0xff, 0xcc, 0x4a, 0xa4, 0x7d, 0x4d, 0x5c, 0x4d, + 0x49, 0xf8, 0xff, 0xcc, 0xe0, 0x92, 0x9f, 0x47, 0x5c, 0xf8, 0xff, 0xc9, + 0x32, 0xa1, 0xc0, 0xc1, 0x3d, 0xf0, 0x6d, 0xf8, 0xf8, 0x93, 0xfe, 0xeb, + 0x7b, 0xeb, 0xbf, 0xc4, 0x66, 0xf0, 0x9f, 0x67, 0x3c, 0x3b, 0xb8, 0xbf, + 0xfe, 0xcc, 0x27, 0x8f, 0x67, 0xa3, 0xff, 0xd4, 0x3f, 0x67, 0x27, 0x97, + 0xbf, 0xc4, 0xff, 0x3b, 0xfc, 0xfa, 0x23, 0x93, 0x9f, 0x47, 0x75, 0xf8, + 0xbb, 0xc4, 0x56, 0xf4, 0xbe, 0x6f, 0x9e, 0x6e, 0x35, 0x9b, 0x5a, 0xf0, + 0xfd, 0xef, 0x5c, 0xf8, 0x01, 0x00, 0x00, 0xc0, 0xef, 0x83, 0xff, 0xff, + 0x2c, 0xeb, 0xd1, 0xeb, 0x3c, 0x93, 0xf3, 0xe1, 0xf2, 0xe7, 0xf7, 0xe2, + 0x9f, 0x4f, 0xfb, 0xe3, 0xdf, 0x49, 0xa8, 0x93, 0xff, 0x1f, 0x8b, 0xfe, + 0xe4, 0x93, 0xac, 0x93, 0xff, 0x1f, 0x8f, 0xfe, 0x44, 0x93, 0xac, 0x93, + 0xe8, 0x93, 0x00, 0x1c, 0xbe, 0x00, 0xff, 0x1f, 0xf8, 0xfe, 0xf1, 0xeb, + 0x6c, 0xeb, 0xff, 0xff, 0x2c, 0xeb, 0xd1, 0xeb, 0x3c, 0x93, 0xf3, 0xe1, + 0xf2, 0xe7, 0xf7, 0xe2, 0xfb, 0xe3, 0x9f, 0x4f, 0xdf, 0x49, 0xa8, 0x93, + 0xff, 0x1f, 0xa5, 0xfe, 0xe4, 0x93, 0xac, 0x93, 0xff, 0x1f, 0xa9, 0xfe, + 0x9e, 0x6b, 0x9c, 0x1b, 0xfe, 0xbf, 0x44, 0x93, 0xac, 0x93, 0xe8, 0x93, + 0x9e, 0x4b, 0x00, 0x1c, 0xdc, 0x00, 0xff, 0x1f, 0x16, 0xff, 0xf1, 0xeb, + 0x6c, 0xeb, 0xff, 0xff, 0x2b, 0xeb, 0xd5, 0xeb, 0x3c, 0x93, 0xf7, 0xe1, + 0xf6, 0xe7, 0xfb, 0xe3, 0x9f, 0x4f, 0xdf, 0x49, 0xac, 0x93, 0xff, 0x1f, + 0xc2, 0xfe, 0x84, 0x93, 0xe4, 0x93, 0xff, 0x1f, 0xc6, 0xfe, 0x9f, 0x6b, + 0xfe, 0xce, 0x3b, 0x9b, 0x84, 0x92, 0xc4, 0xf7, 0xbf, 0x67, 0x7b, 0x9b, + 0xb5, 0xf7, 0xde, 0x6b, 0xfe, 0x67, 0xbe, 0x93, 0xbb, 0xc4, 0xde, 0x4b, + 0xc8, 0xf3, 0xbd, 0xc4, 0xca, 0xf3, 0xbb, 0xc5, 0xbd, 0xf3, 0xbd, 0xc5, + 0xd5, 0xf3, 0xbd, 0x6b, 0x9d, 0x67, 0xb2, 0xa5, 0xdc, 0x67, 0x9c, 0x6b, + 0xb3, 0x9b, 0xbd, 0x4b, 0xe1, 0xf3, 0x7f, 0xcd, 0xe0, 0xcf, 0xa8, 0xbd, + 0xff, 0xca, 0xb3, 0x9b, 0xba, 0x3b, 0xd8, 0xdb, 0x3a, 0xa4, 0xfd, 0xf7, + 0x70, 0x92, 0xb3, 0x9b, 0xfd, 0xf3, 0xa0, 0x92, 0xff, 0xd7, 0xbf, 0xc7, + 0xbe, 0xb5, 0x9e, 0xb9, 0x0c, 0xf4, 0xba, 0x1b, 0x80, 0xdf, 0xbf, 0xce, + 0xb5, 0x9b, 0xe9, 0xf3, 0x5c, 0x4b, 0xec, 0x93, 0xff, 0x1f, 0x5f, 0xff, + 0xf5, 0xeb, 0x6b, 0xeb, 0xff, 0xd5, 0x9e, 0xbc, 0xbd, 0x4b, 0x1f, 0xf8, + 0xfb, 0xcc, 0x9f, 0x4b, 0xec, 0x93, 0xff, 0x1f, 0x6a, 0xff, 0xf5, 0xeb, + 0x6b, 0xeb, 0x71, 0x9b, 0x05, 0xf4, 0xf5, 0xef, 0x11, 0xf8, 0x1a, 0x3b, + 0x7f, 0xd7, 0x16, 0xf4, 0xbf, 0xc4, 0x18, 0xf0, 0x57, 0xa2, 0x5a, 0x1b, + 0x80, 0xcf, 0x1c, 0xf8, 0xc4, 0x93, 0x1c, 0xf8, 0xff, 0xcc, 0x9c, 0x4b, + 0x9d, 0x4b, 0xec, 0x93, 0x21, 0xf8, 0xff, 0xff, 0xef, 0x83, 0xff, 0xff, + 0x2c, 0xeb, 0xd5, 0xeb, 0x3c, 0x93, 0xf7, 0xe1, 0xf6, 0xe7, 0xfb, 0xe3, + 0x9f, 0x4f, 0xdf, 0x49, 0xac, 0x93, 0xff, 0x1f, 0x2c, 0xff, 0xe4, 0x93, + 0x84, 0x93, 0xff, 0x1f, 0x30, 0xff, 0xbf, 0x6b, 0xfe, 0xcc, 0x73, 0x9b, + 0x84, 0x92, 0xf5, 0xf7, 0xbf, 0x67, 0x73, 0x9b, 0xf8, 0xf7, 0xec, 0x93, + 0x84, 0x93, 0xff, 0x1f, 0x00, 0xff, 0xf5, 0xeb, 0x6c, 0xeb, 0xff, 0xcf, + 0xff, 0xd7, 0x03, 0xf8, 0x2f, 0xeb, 0xdb, 0xeb, 0xfc, 0xce, 0xa0, 0xb7, + 0xbf, 0xc7, 0x04, 0x93, 0xdf, 0x47, 0xbe, 0x47, 0xf7, 0xf7, 0xfd, 0xcd, + 0xbf, 0x47, 0xc4, 0x93, 0xff, 0x1f, 0xb1, 0xff, 0xfb, 0xeb, 0x6f, 0xeb, + 0xe1, 0xce, 0xbf, 0xc5, 0xdd, 0x47, 0xf8, 0xf3, 0x7f, 0xcd, 0xa7, 0xbd, + 0x7d, 0x9b, 0xf0, 0xf3, 0xff, 0xcd, 0xfe, 0xa5, 0xff, 0x3b, 0xbd, 0x83, + 0xff, 0xd5, 0xdf, 0xc5, 0xfc, 0x4c, 0x13, 0xf4, 0xe1, 0xce, 0xf7, 0x8f, + 0xb6, 0xa6, 0xfc, 0x4c, 0xbd, 0x4c, 0x19, 0xf8, 0x30, 0xcf, 0xe7, 0xbf, + 0x19, 0xf8, 0xff, 0xff, 0x2e, 0xeb, 0xda, 0xeb, 0x3c, 0x93, 0xfb, 0xe7, + 0x9f, 0x4f, 0x84, 0x93, 0xff, 0x1f, 0x73, 0xff, 0x9f, 0x67, 0xbd, 0xc4, + 0xc4, 0x92, 0xe1, 0xf3, 0xfe, 0xcd, 0x37, 0x9b, 0xe4, 0xf7, 0xbb, 0xc4, + 0xf8, 0xf3, 0x9d, 0x67, 0x1c, 0x38, 0x7f, 0xd7, 0xea, 0xf7, 0xc1, 0xc4, + 0xf7, 0xf7, 0x9e, 0x6b, 0xbf, 0xc4, 0xec, 0xf7, 0x3f, 0x38, 0xdf, 0xaf, + 0xfa, 0xeb, 0x6e, 0xeb, 0xe1, 0xcf, 0x92, 0xa7, 0xfc, 0x67, 0xf2, 0x8f, + 0x9e, 0x67, 0xbf, 0xc4, 0x07, 0xf0, 0xff, 0xcc, 0xfe, 0xa4, 0xfa, 0xeb, + 0x6e, 0xeb, 0xff, 0xcf, 0xfa, 0xeb, 0x6e, 0xeb, 0x7f, 0xcf, 0xe7, 0xbf, + 0xfa, 0xeb, 0x6e, 0xeb, 0x3e, 0xeb, 0xbf, 0x6f, 0xfe, 0xc5, 0x9c, 0x6f, + 0xde, 0x6f, 0xcb, 0xf3, 0xbb, 0xc5, 0xd1, 0xf3, 0xbd, 0xc5, 0xe1, 0xf3, + 0xbf, 0xc4, 0xe3, 0xf3, 0xbd, 0x6f, 0xff, 0xcf, 0x82, 0xd7, 0xf6, 0x9b, + 0xd0, 0xf7, 0x80, 0xcf, 0x7e, 0x9b, 0xdd, 0xf7, 0xfc, 0x1b, 0x80, 0xdf, + 0xbf, 0xcb, 0xfd, 0x9a, 0x81, 0xdd, 0xeb, 0xf3, 0xc1, 0xdc, 0x1c, 0x38, + 0x7f, 0xd7, 0xea, 0xf7, 0x9d, 0xbc, 0xbd, 0x1b, 0x00, 0xdf, 0xa8, 0xbd, + 0x96, 0xb4, 0x37, 0x93, 0xe0, 0xbe, 0xf3, 0x93, 0x7e, 0xeb, 0xff, 0xcd, + 0xff, 0xcc, 0x37, 0x93, 0xe0, 0xbe, 0xf3, 0x93, 0x7e, 0xeb, 0x1c, 0x3b, + 0x7f, 0xd7, 0x13, 0xf0, 0x9f, 0xa4, 0x15, 0xf8, 0x9e, 0xb4, 0xff, 0xdd, + 0x15, 0xf8, 0x00, 0xcd, 0xa8, 0xbd, 0xff, 0xcc, 0x0e, 0xf8, 0x4b, 0xc4, + 0x96, 0xbc, 0x00, 0xcd, 0x96, 0xb4, 0xa8, 0xbd, 0x14, 0xf8, 0xf6, 0xa7, + 0xc6, 0xc7, 0xe2, 0xf3, 0xfe, 0xcb, 0xfc, 0x3b, 0xbd, 0xbf, 0xfb, 0x3b, + 0xdf, 0xbf, 0xff, 0xd7, 0x3f, 0x97, 0xbf, 0xc4, 0xff, 0x3b, 0xfc, 0xfa, + 0x73, 0x93, 0x9d, 0x1b, 0x80, 0xdf, 0xbf, 0xcf, 0xf1, 0x9b, 0xf1, 0xf7, + 0x1d, 0x3b, 0x7f, 0xd7, 0xfd, 0xf3, 0xb3, 0xa5, 0x5f, 0x38, 0xdf, 0xaf, + 0x7f, 0x9b, 0x9d, 0xbd, 0x7c, 0x9b, 0x96, 0xb4, 0xa8, 0xbd, 0x33, 0xf8, + 0xff, 0xcd, 0xc1, 0xdd, 0x09, 0xf8, 0xff, 0xff, 0x3e, 0xeb, 0x9f, 0x6f, + 0xe8, 0xb4, 0xff, 0x1b, 0x00, 0xdf, 0xb6, 0xbc, 0x60, 0xb4, 0xbf, 0xc7, + 0xb6, 0xb5, 0x7e, 0x4e, 0xea, 0xf7, 0xbf, 0xc5, 0xe1, 0xf3, 0xff, 0xcc, + 0x82, 0xd4, 0xfc, 0xcf, 0x9d, 0x4e, 0xff, 0xcc, 0xff, 0x4e, 0xb8, 0xbd, + 0x81, 0xd4, 0x5f, 0x38, 0xdf, 0xaf, 0xbe, 0xbd, 0x7f, 0x9b, 0xf0, 0x92, + 0xff, 0xd4, 0x03, 0xf4, 0x7d, 0x4e, 0xbc, 0x4e, 0x7e, 0xeb, 0x00, 0xcb, + 0xfd, 0x9a, 0xf3, 0xf3, 0xb8, 0xbd, 0x81, 0xd7, 0xfc, 0xcc, 0x41, 0xc5, + 0xfd, 0x4e, 0x9f, 0x4e, 0xbc, 0x4e, 0x7e, 0xeb, 0xfd, 0xcf, 0xff, 0x4e, + 0x7e, 0xeb, 0xbf, 0xc5, 0xf5, 0xf3, 0x7f, 0xcf, 0xf2, 0xbf, 0x3f, 0x97, + 0xbf, 0xc4, 0xff, 0x3b, 0xfc, 0xfa, 0x9f, 0x4e, 0xbc, 0x4e, 0x7e, 0xeb, + 0xfb, 0xcc, 0x9f, 0x4e, 0x7e, 0xeb, 0xff, 0xff, 0x3e, 0xeb, 0x9f, 0x6f, + 0xfe, 0xcb, 0x2f, 0x9b, 0xed, 0xf7, 0xbf, 0x6e, 0x6f, 0x9b, 0xf0, 0xf7, + 0xbb, 0xc4, 0xd2, 0xf3, 0xbb, 0xc5, 0xf0, 0xf3, 0xbd, 0xc4, 0xf4, 0xf3, + 0xbd, 0xc5, 0xee, 0xf3, 0x9e, 0x6f, 0xbe, 0x6e, 0x71, 0x9b, 0xed, 0xf3, + 0xbf, 0xc4, 0xf7, 0xf7, 0xfe, 0xcf, 0x7e, 0xeb, 0xbd, 0xc5, 0xe4, 0xf3, + 0x9e, 0x6e, 0xbf, 0xc4, 0x05, 0xf4, 0xff, 0xcf, 0xff, 0xd7, 0x7e, 0xeb, + 0x9e, 0x6f, 0xbf, 0xc4, 0x04, 0xf4, 0xfe, 0xcf, 0x0c, 0xf8, 0x7d, 0x6f, + 0xbd, 0x6e, 0xf6, 0x9a, 0x13, 0xf4, 0x6e, 0x9b, 0xf8, 0xf7, 0xfc, 0x6f, + 0xbc, 0x6e, 0xf7, 0x9b, 0x19, 0xf0, 0x7f, 0x9b, 0xfb, 0xf7, 0xbf, 0xc4, + 0x14, 0xf0, 0x1c, 0xf8, 0xff, 0xcf, 0x7e, 0xeb, 0xbb, 0xc5, 0x16, 0xf4, + 0xbe, 0x6e, 0x9e, 0x6f, 0xf2, 0xa5, 0x7e, 0xeb, 0x2f, 0xeb, 0xff, 0x8b, + 0xff, 0x1f, 0xfb, 0xec, 0x6f, 0xeb, 0xff, 0xff, 0x2e, 0xeb, 0xfc, 0x92, + 0xff, 0x7f, 0xbf, 0xc7, 0xf8, 0xf3, 0xff, 0xdb, 0x00, 0x1c, 0x0b, 0x00, + 0xff, 0x7b, 0xbf, 0xc7, 0x04, 0xf4, 0x6e, 0xeb, 0x2b, 0xeb, 0xd7, 0xeb, + 0xff, 0x47, 0x3a, 0x8a, 0x77, 0x8b, 0xbd, 0x47, 0x33, 0x8b, 0x9e, 0x47, + 0xff, 0xcd, 0xfc, 0xe4, 0xac, 0x5c, 0x20, 0xc7, 0xfb, 0xf3, 0xff, 0xca, + 0x5e, 0xa2, 0xfd, 0xfb, 0x5f, 0x67, 0xff, 0xc9, 0x71, 0x1b, 0xe1, 0xff, + 0x20, 0x8a, 0xff, 0xd3, 0xe8, 0x93, 0xa0, 0x93, 0x00, 0x1c, 0xfb, 0x02, + 0x88, 0xef, 0xf3, 0xa7, 0x9f, 0x7f, 0x9f, 0x5b, 0xff, 0xd9, 0x67, 0x8a, + 0xe8, 0x93, 0xa0, 0x93, 0x00, 0x1c, 0x2b, 0x03, 0xbc, 0x92, 0xbf, 0xc7, + 0x10, 0xf4, 0x6c, 0x93, 0x9e, 0x67, 0xbf, 0xc4, 0xec, 0xf3, 0x27, 0x9b, + 0xee, 0xf7, 0x26, 0xa4, 0x67, 0x8a, 0xbf, 0xc1, 0xf2, 0xf3, 0xff, 0xd1, + 0x67, 0x8a, 0x9c, 0xa3, 0x86, 0xa4, 0xdd, 0x67, 0xff, 0xd3, 0xdf, 0x5b, + 0x2d, 0x9b, 0x02, 0xf4, 0x39, 0x3b, 0x7b, 0xdb, 0x6f, 0xa5, 0x9f, 0x67, + 0x20, 0xc4, 0xfb, 0xf3, 0xff, 0xd3, 0xd2, 0xcc, 0x9f, 0x5b, 0xec, 0x93, + 0x00, 0x1c, 0x4f, 0x00, 0xf7, 0xeb, 0x6b, 0xeb, 0x37, 0x84, 0xff, 0xff, + 0xdb, 0xeb, 0x9c, 0x47, 0xbd, 0x47, 0xde, 0x47, 0xff, 0x47, 0x2b, 0xeb, + 0xde, 0xeb, 0x79, 0x67, 0xff, 0x7b, 0xbf, 0xc7, 0x99, 0xf3, 0xf8, 0xe1, + 0xff, 0xca, 0xdf, 0xcd, 0xbf, 0x47, 0xda, 0xc8, 0x3d, 0x9a, 0xfb, 0xf3, + 0x00, 0x1c, 0x6d, 0x00, 0xa7, 0xfb, 0xff, 0xdb, 0x9f, 0x7b, 0xcf, 0xcd, + 0x71, 0x9b, 0xfc, 0xf7, 0xff, 0xdb, 0xbf, 0x47, 0xff, 0x7b, 0x9f, 0x1b, + 0xd0, 0xef, 0x33, 0x8b, 0xf6, 0xc4, 0xf1, 0xf7, 0xf6, 0xcd, 0x9c, 0xba, + 0x5c, 0x3b, 0xda, 0xf7, 0x5f, 0xa2, 0xd0, 0xd2, 0xff, 0xdb, 0xff, 0x7b, + 0x9f, 0x1b, 0xd0, 0xef, 0x33, 0x8b, 0x37, 0x9b, 0x0a, 0xf4, 0x9f, 0x1b, + 0x9d, 0xef, 0x73, 0x8b, 0xea, 0xc5, 0xc8, 0xf7, 0x34, 0x93, 0xbc, 0xee, + 0x9d, 0x3b, 0xbc, 0xf7, 0x9f, 0x6c, 0xf3, 0x87, 0xfc, 0xd9, 0x90, 0xa1, + 0xff, 0x6c, 0x2b, 0x8b, 0xf5, 0xce, 0xbf, 0x67, 0x00, 0x1c, 0x89, 0x00, + 0xd5, 0xfb, 0xfc, 0xd9, 0x90, 0xa1, 0xff, 0x6c, 0x2b, 0x8b, 0xf7, 0xce, + 0xbf, 0x67, 0x00, 0x1c, 0x92, 0x00, 0xde, 0xfb, 0xfc, 0xd9, 0x90, 0xa1, + 0xff, 0x6c, 0x2b, 0x8b, 0xf5, 0xce, 0xbf, 0x67, 0x00, 0x1c, 0x9b, 0x00, + 0xe7, 0xfb, 0xfc, 0xd9, 0x90, 0xa1, 0xff, 0x6c, 0x2b, 0x8b, 0xef, 0xce, + 0xbf, 0x67, 0x00, 0x1c, 0xa4, 0x00, 0xf0, 0xfb, 0xfc, 0xd9, 0x90, 0xa1, + 0xff, 0x7c, 0x00, 0x1c, 0xbc, 0x00, 0xf6, 0xfb, 0xfc, 0xd9, 0x90, 0xa1, + 0xff, 0x6c, 0x00, 0x1c, 0xbc, 0x00, 0xfc, 0xfb, 0x00, 0x1c, 0xc5, 0x00, + 0xff, 0xdb, 0xff, 0x7b, 0xbf, 0xc7, 0x5e, 0xf4, 0xfe, 0xeb, 0x11, 0x26, + 0xfb, 0xdf, 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, 0x7f, 0x67, 0xf6, 0xeb, + 0xc3, 0x87, 0xff, 0xff, 0x8f, 0x84, 0xff, 0xff, 0x8e, 0xef, 0xad, 0xef, + 0x9f, 0x4d, 0xad, 0xef, 0xbc, 0x23, 0xff, 0xde, 0xae, 0xef, 0xbc, 0x23, + 0xfe, 0xde, 0xae, 0xef, 0xbc, 0x23, 0xfd, 0xde, 0xaf, 0xef, 0xbc, 0x23, + 0xfc, 0xde, 0xaf, 0xef, 0xbc, 0x23, 0xfb, 0xde, 0xb0, 0xef, 0xbc, 0x23, + 0xfa, 0xde, 0xb0, 0xef, 0xbc, 0x23, 0xf9, 0xde, 0xb1, 0xef, 0xbc, 0x23, + 0xf8, 0xde, 0xff, 0xcd, 0xbc, 0x23, 0xfe, 0xdc, 0xbc, 0x23, 0x3f, 0xdf, + 0xc3, 0x87, 0xff, 0xff, 0xff, 0x1f, 0xff, 0x1f, 0x83, 0xfe, 0xff, 0xdf, + 0xfc, 0xfd, 0xfe, 0xff, 0xf8, 0xf9, 0xfa, 0xfb, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf0, 0xf1, 0xf2, 0xf3, 0xec, 0xed, 0xee, 0xef, 0xe8, 0xe9, 0xea, 0xeb, + 0xe4, 0xe5, 0xe6, 0xe7, 0xe0, 0xe1, 0xe2, 0xe3, 0x7f, 0x3e, 0xdf, 0x8b, + 0xc3, 0x87, 0xff, 0xff, 0x9b, 0xef, 0x9f, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, + 0xdf, 0xbf, 0xfc, 0x23, 0xbf, 0xdf, 0xc3, 0x87, 0x83, 0xfe, 0xff, 0xdf, + 0x9b, 0xef, 0x9f, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, 0xfc, 0x23, + 0x9f, 0xdf, 0xc3, 0x87, 0x83, 0xfe, 0xff, 0xdf, 0x3e, 0xeb, 0x20, 0xc7, + 0xe9, 0xf7, 0x9f, 0x1b, 0xfc, 0xdf, 0x9c, 0xbc, 0xb5, 0xef, 0xbf, 0x6d, + 0xfd, 0xaf, 0xff, 0x8b, 0x00, 0xdf, 0xfd, 0x3b, 0xbf, 0xf7, 0x7f, 0x6f, + 0x00, 0xcd, 0x73, 0x8f, 0xbb, 0x3b, 0xbd, 0xdf, 0xbf, 0x4f, 0xbf, 0x6f, + 0xfa, 0xdc, 0xb3, 0x8f, 0xb7, 0x93, 0xdf, 0x4f, 0x7e, 0xeb, 0xff, 0xff, + 0x83, 0xfe, 0xff, 0xdf, 0x2e, 0xeb, 0x80, 0xef, 0xfc, 0xcd, 0xbf, 0x3b, + 0xde, 0xdf, 0xfb, 0x7c, 0x7f, 0xc7, 0x7e, 0xc7, 0xfb, 0x93, 0x5c, 0xc7, + 0xfb, 0x5c, 0xde, 0x6c, 0xe5, 0xef, 0xbf, 0x97, 0xde, 0x4c, 0xe5, 0xef, + 0xbf, 0x97, 0xdb, 0x5c, 0x7b, 0x97, 0x77, 0x8b, 0xbf, 0xc5, 0xf7, 0xf7, + 0xee, 0xcf, 0xff, 0x1f, 0x4e, 0xf0, 0xfe, 0xcf, 0xff, 0x1f, 0x51, 0xf0, + 0xf8, 0xfb, 0xee, 0xcf, 0xff, 0x1f, 0x5b, 0xf0, 0xfe, 0xcf, 0xff, 0x1f, + 0x5e, 0xf0, 0xff, 0xcf, 0xff, 0xce, 0xff, 0xcd, 0xff, 0x1f, 0x3f, 0xf2, + 0xff, 0xcf, 0xff, 0x1f, 0x56, 0xf2, 0xff, 0x1f, 0xa4, 0xee, 0xff, 0xcf, + 0xff, 0x1f, 0x3f, 0xef, 0x75, 0xef, 0xec, 0x93, 0x46, 0xce, 0xde, 0xbe, + 0xfe, 0xcd, 0xff, 0x1f, 0x9e, 0xee, 0x9d, 0x6b, 0x9e, 0x4b, 0x9f, 0x6b, + 0x56, 0xc4, 0x9f, 0x4b, 0x6e, 0xeb, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, + 0xf0, 0xff, 0x01, 0x00, 0xf4, 0xff, 0x01, 0x00, 0xff, 0xdf, 0xff, 0xbf, + 0x2b, 0xeb, 0xdb, 0xeb, 0xbf, 0x8a, 0x82, 0xed, 0xbf, 0x7c, 0x00, 0xcc, + 0x35, 0x9b, 0xe4, 0xf7, 0x65, 0xed, 0xff, 0xcc, 0x9f, 0x5b, 0xff, 0xce, + 0xdd, 0x4b, 0xdc, 0x4b, 0xdb, 0x4b, 0xda, 0x4b, 0x05, 0xcc, 0x9e, 0xbc, + 0x9c, 0x53, 0xff, 0x1f, 0x70, 0xef, 0xfd, 0x53, 0xff, 0xcc, 0x9e, 0x5b, + 0xff, 0x1f, 0x5d, 0xee, 0xbe, 0xc7, 0xfb, 0xf7, 0xff, 0xcd, 0xbd, 0x5b, + 0xfb, 0xfb, 0xff, 0xcd, 0x91, 0xed, 0xbd, 0x5c, 0xa9, 0x8a, 0x72, 0xed, + 0x5d, 0x4b, 0x9b, 0x6b, 0x93, 0xa2, 0x9e, 0x47, 0x9b, 0x4b, 0x1c, 0x6b, + 0x02, 0xa2, 0x1a, 0x4b, 0x5c, 0x4b, 0xfa, 0xba, 0x98, 0xba, 0xf3, 0xa7, + 0xff, 0x3b, 0xbf, 0xf7, 0x05, 0xce, 0xdd, 0xbe, 0x00, 0x1c, 0xeb, 0x04, + 0x7c, 0x92, 0x1f, 0x47, 0xfc, 0xed, 0xa4, 0x93, 0x68, 0x93, 0x9e, 0x67, + 0x00, 0x1c, 0x67, 0x01, 0xff, 0xcc, 0xff, 0xd4, 0xbd, 0x6b, 0x35, 0x9b, + 0xfd, 0xf7, 0x70, 0x92, 0xff, 0x1f, 0x89, 0xee, 0xbf, 0xc7, 0xf3, 0xf3, + 0x24, 0x93, 0xff, 0xcd, 0xe7, 0xd5, 0x66, 0x9b, 0xfd, 0xf3, 0x34, 0x93, + 0xb0, 0x92, 0xc6, 0xc4, 0xf2, 0xf7, 0xe6, 0xca, 0xf4, 0xfb, 0x24, 0x93, + 0xff, 0xcd, 0xe2, 0xd5, 0x66, 0x9b, 0xfd, 0xf3, 0x34, 0x93, 0xb0, 0x92, + 0xc1, 0xc4, 0xfd, 0xf7, 0xe1, 0xca, 0xff, 0x1f, 0xba, 0xef, 0x70, 0xee, + 0xfd, 0x53, 0xff, 0x1f, 0x04, 0xf0, 0xfc, 0x53, 0x9e, 0x7b, 0xbf, 0xc4, + 0x0d, 0xf7, 0xff, 0x1f, 0xac, 0xee, 0xbe, 0xc7, 0xf6, 0xf3, 0xff, 0x1f, + 0xb0, 0xee, 0xbd, 0xc7, 0xf6, 0xf3, 0x7d, 0xcd, 0xbc, 0x47, 0x4b, 0xcf, + 0xf7, 0xfb, 0x8c, 0xcc, 0x9c, 0x47, 0x6c, 0xcf, 0xfb, 0xfb, 0x8c, 0xce, + 0xdc, 0x47, 0x6c, 0xcf, 0x6a, 0x8b, 0xbd, 0x47, 0x9f, 0xee, 0x7d, 0x74, + 0x77, 0xa3, 0xee, 0x8a, 0x7d, 0x54, 0x2c, 0x8a, 0x00, 0x1c, 0x3d, 0x03, + 0xbc, 0x93, 0x81, 0xef, 0xff, 0x6c, 0x00, 0x1c, 0xcc, 0x03, 0x82, 0xef, + 0xdf, 0x6c, 0x00, 0x1c, 0x08, 0x04, 0x00, 0x1c, 0xce, 0x04, 0x7c, 0x92, + 0x3e, 0x8b, 0x9e, 0x47, 0x22, 0x9b, 0xdb, 0xf3, 0x8b, 0xef, 0x9d, 0x7c, + 0xbe, 0xc4, 0xfb, 0xf7, 0xfe, 0xcd, 0x8d, 0xef, 0xbe, 0x5c, 0x8e, 0xef, + 0x3d, 0x54, 0xff, 0x1f, 0xe2, 0xee, 0xbe, 0xc7, 0xc6, 0xf6, 0x91, 0xef, + 0x9d, 0x7c, 0xbf, 0xc4, 0xca, 0xf6, 0x20, 0xc2, 0xcc, 0xf2, 0xb4, 0xef, + 0x9c, 0x75, 0xdd, 0x67, 0x9b, 0xa4, 0x32, 0x8b, 0x9c, 0x55, 0x30, 0x8b, + 0xfd, 0x15, 0xd4, 0xfe, 0x36, 0x9b, 0xd7, 0xf6, 0x69, 0xcc, 0x9e, 0xbc, + 0xbb, 0xef, 0x9c, 0x55, 0xdc, 0xfa, 0x9c, 0xef, 0x9d, 0x7c, 0xbf, 0xc4, + 0xe3, 0xf7, 0xf6, 0xfb, 0xef, 0xff, 0xff, 0xdf, 0xd7, 0x83, 0xff, 0xff, + 0xdf, 0x83, 0xff, 0xff, 0xdb, 0x83, 0xff, 0xff, 0xfc, 0x67, 0x00, 0x1c, + 0x80, 0x03, 0xbc, 0x93, 0x83, 0xed, 0xff, 0x6c, 0x00, 0x1c, 0x0f, 0x04, + 0x84, 0xed, 0xdf, 0x6c, 0x00, 0x1c, 0x4b, 0x04, 0x00, 0x1c, 0x11, 0x05, + 0xfe, 0x8b, 0x3e, 0x9a, 0xe0, 0xf7, 0xfb, 0xfa, 0xbe, 0xc4, 0xfd, 0xf6, + 0xec, 0x8a, 0x6c, 0xcc, 0x9d, 0xbc, 0xf2, 0x9a, 0xf6, 0xf3, 0xff, 0x1f, + 0x22, 0xef, 0xbf, 0xc7, 0xf0, 0xf3, 0x8d, 0xed, 0x9d, 0x7c, 0xbe, 0xc4, + 0x0a, 0xf7, 0x8f, 0xed, 0x9d, 0x74, 0x30, 0x8b, 0xbe, 0x67, 0x36, 0x9b, + 0x10, 0xf3, 0xff, 0x1f, 0x30, 0xef, 0xbe, 0xc7, 0x14, 0xf7, 0x94, 0xed, + 0x9d, 0x7c, 0xbf, 0xc4, 0xa5, 0xf7, 0xff, 0x1f, 0x38, 0xef, 0xbe, 0xc7, + 0xd5, 0xf7, 0x98, 0xed, 0x9c, 0x74, 0xb0, 0x8b, 0xfd, 0x15, 0x0c, 0xfe, + 0xb6, 0x9b, 0xdc, 0xf7, 0xdf, 0xc2, 0xde, 0xf7, 0xdd, 0x67, 0x9b, 0xa4, + 0x32, 0x8b, 0xbe, 0xed, 0x9c, 0x55, 0x70, 0x8b, 0x05, 0xcc, 0x9e, 0xbc, + 0x72, 0x9b, 0xfa, 0xf3, 0x05, 0xcc, 0x9e, 0xbc, 0xa3, 0xee, 0x9c, 0x55, + 0x64, 0xee, 0xdd, 0x7b, 0xbe, 0x7b, 0x9d, 0x73, 0x30, 0x8b, 0xfc, 0x73, + 0xfc, 0x8b, 0xff, 0x47, 0xe7, 0xee, 0x00, 0x1c, 0x42, 0x02, 0xfd, 0x73, + 0xdc, 0x73, 0xbd, 0x7b, 0xfe, 0xcc, 0xff, 0x1f, 0x60, 0xf0, 0x24, 0xfb, + 0xff, 0x1f, 0x65, 0xef, 0xbe, 0xc7, 0x49, 0xf3, 0x8d, 0xee, 0xbc, 0x1b, + 0xf4, 0xff, 0xfe, 0xce, 0xdd, 0x5d, 0x3d, 0x55, 0x8d, 0x74, 0xa5, 0xcd, + 0x71, 0x9b, 0xf8, 0xf7, 0x94, 0xee, 0x69, 0xcd, 0xbc, 0x54, 0xfe, 0xcd, + 0xbe, 0x5c, 0x59, 0xfb, 0x91, 0xcd, 0x71, 0x9b, 0xf8, 0xf7, 0x98, 0xee, + 0x05, 0xcd, 0xbc, 0x54, 0xfe, 0xcd, 0xbe, 0x5c, 0x62, 0xfb, 0x05, 0xcc, + 0x9e, 0xbc, 0xbc, 0xee, 0x9c, 0x55, 0xff, 0x1f, 0x86, 0xef, 0xbe, 0xc7, + 0x6a, 0xf7, 0xbf, 0xee, 0xfe, 0xcc, 0x9e, 0x5d, 0x69, 0xcc, 0x9e, 0xbc, + 0x9c, 0x55, 0x71, 0xfb, 0xff, 0x1f, 0x91, 0xef, 0xbe, 0xc7, 0xfb, 0xf7, + 0x85, 0xef, 0x3d, 0x54, 0x78, 0xfb, 0x6c, 0xcc, 0x9d, 0xbc, 0xa7, 0xef, + 0x9d, 0x55, 0x7d, 0xfb, 0xbe, 0xc4, 0x7f, 0xf7, 0xff, 0x1f, 0x9f, 0xef, + 0xbd, 0xc7, 0xf7, 0xf7, 0x8a, 0xef, 0xad, 0x74, 0x91, 0xcc, 0x35, 0x9b, + 0xf9, 0xf7, 0x19, 0xcb, 0xf9, 0xfb, 0x05, 0xcb, 0x7e, 0xbb, 0xfc, 0xfb, + 0x69, 0xcb, 0x7e, 0xbb, 0x90, 0xef, 0xbc, 0x1b, 0xf4, 0xff, 0xdc, 0x75, + 0x5b, 0xa2, 0xaa, 0x8a, 0x5c, 0x55, 0xad, 0x74, 0x91, 0xcc, 0x35, 0x9b, + 0xcd, 0xf7, 0xff, 0x1f, 0xba, 0xef, 0xbd, 0xc7, 0xe3, 0xf7, 0x99, 0xef, + 0x9c, 0x74, 0xb0, 0x8b, 0x9c, 0xcd, 0xb6, 0x9b, 0xef, 0xf7, 0xf4, 0xfb, + 0xdf, 0x83, 0xff, 0xff, 0xdb, 0x83, 0xff, 0xff, 0xef, 0xff, 0xff, 0xdf, + 0xb7, 0x83, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, 0x9b, 0xcd, 0x86, 0xee, + 0xbc, 0x54, 0xb3, 0xfb, 0x30, 0x8b, 0x2e, 0x9b, 0xb6, 0xf3, 0x89, 0xee, + 0x7c, 0x54, 0xb9, 0xfb, 0x8b, 0xee, 0x9c, 0x74, 0xb0, 0x8b, 0x06, 0xcd, + 0xb6, 0x9b, 0xfa, 0xf7, 0x05, 0xcd, 0x8e, 0xee, 0xbc, 0x54, 0xc3, 0xfb, + 0x30, 0x8b, 0x2e, 0x9b, 0xc6, 0xf3, 0x91, 0xee, 0x7c, 0x54, 0xff, 0xcd, + 0xbe, 0x5c, 0xcb, 0xfb, 0x68, 0x8b, 0x9c, 0xcc, 0x72, 0x9b, 0xdb, 0xf7, + 0x96, 0xee, 0x9d, 0x7c, 0xbe, 0xc4, 0xe7, 0xf7, 0x58, 0xee, 0xec, 0x93, + 0x00, 0x1c, 0x6b, 0x04, 0xbc, 0x93, 0x99, 0xee, 0xff, 0x6c, 0x00, 0x1c, + 0xfa, 0x04, 0x9a, 0xee, 0xdf, 0x6c, 0x00, 0x1c, 0x36, 0x05, 0x00, 0x1c, + 0xfc, 0x05, 0xfd, 0x52, 0x05, 0xcc, 0x9e, 0xbc, 0x9c, 0x52, 0xff, 0xcc, + 0x9d, 0x5a, 0x9e, 0x5a, 0xea, 0xfb, 0xff, 0x1f, 0x0a, 0xf0, 0xbf, 0xc7, + 0xee, 0xf7, 0x9b, 0xcd, 0x86, 0xef, 0xbc, 0x54, 0xf2, 0xfb, 0xa8, 0x8a, + 0xae, 0x9a, 0xf5, 0xf3, 0x89, 0xef, 0x7c, 0x54, 0xff, 0x1f, 0x17, 0xf0, + 0xbf, 0xc7, 0xfb, 0xf7, 0xff, 0xcd, 0x8c, 0xef, 0xbe, 0x5c, 0x6a, 0xef, + 0xfb, 0x1b, 0xf4, 0xff, 0xdd, 0x7f, 0xbe, 0x7f, 0x9d, 0x77, 0x30, 0x8b, + 0xfc, 0x77, 0xfc, 0x8b, 0xff, 0x47, 0xee, 0xef, 0x00, 0x1c, 0x0f, 0x03, + 0xad, 0x73, 0xa5, 0xcc, 0x35, 0x9b, 0xf5, 0xf7, 0x96, 0xef, 0x9c, 0x74, + 0x64, 0xd4, 0x32, 0x8b, 0xf3, 0xc4, 0xfb, 0xf7, 0x4b, 0xcd, 0x99, 0xef, + 0xbc, 0x54, 0x9a, 0xef, 0xfd, 0x74, 0xdc, 0x74, 0xbd, 0x7c, 0xfe, 0xcc, + 0xff, 0x1f, 0x3b, 0xf1, 0xfb, 0xeb, 0x6b, 0xeb, 0xef, 0xff, 0xff, 0xdf, + 0xdf, 0x83, 0xff, 0xff, 0xdb, 0x83, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, + 0xb7, 0x83, 0xff, 0xff, 0x2c, 0xeb, 0xff, 0x8b, 0xbb, 0x8b, 0xbb, 0xc7, + 0xe3, 0xf7, 0x71, 0xee, 0x9d, 0x6b, 0x97, 0xbc, 0x97, 0xb4, 0x45, 0xc4, + 0x9d, 0x4b, 0x3d, 0x6b, 0xff, 0x1f, 0x57, 0xf0, 0xbc, 0x92, 0xff, 0x1f, + 0x4e, 0xf0, 0x5a, 0x1b, 0xf0, 0xdf, 0x97, 0xee, 0x73, 0x96, 0xa7, 0x92, + 0x9f, 0x1b, 0x0f, 0xdf, 0x8f, 0xbc, 0xb3, 0x92, 0x5d, 0x4b, 0xff, 0x1f, + 0x26, 0xf4, 0xff, 0x1f, 0x28, 0xf4, 0xbf, 0xfb, 0xba, 0xc7, 0xec, 0xf7, + 0x80, 0xef, 0xbd, 0x6c, 0x20, 0xef, 0x67, 0x97, 0xcf, 0xbe, 0xb7, 0x93, + 0xdd, 0x4c, 0xbd, 0x6c, 0xb7, 0xbd, 0xb7, 0xb5, 0x47, 0xc5, 0x45, 0xc5, + 0xbd, 0x4c, 0xff, 0x1f, 0x3a, 0xf4, 0xff, 0x1f, 0x3c, 0xf4, 0xd3, 0xfb, + 0x47, 0xef, 0x7a, 0x1b, 0xd8, 0xff, 0xde, 0x5b, 0xff, 0x5b, 0x8b, 0xef, + 0xbd, 0x6c, 0x2b, 0xef, 0x67, 0x97, 0xcf, 0xbe, 0xb7, 0x93, 0xdd, 0x4c, + 0xbd, 0x6c, 0xb7, 0xbd, 0xb7, 0xb5, 0xe7, 0xbf, 0xf7, 0x93, 0xfd, 0x4c, + 0xff, 0x1f, 0x51, 0xf4, 0xfe, 0xcc, 0x9a, 0x23, 0xd5, 0xff, 0x9f, 0x7b, + 0xfe, 0xc4, 0xed, 0xf7, 0xfe, 0xcf, 0x7f, 0xce, 0xd9, 0xbe, 0xff, 0x1f, + 0xe2, 0xf7, 0x95, 0xef, 0x9f, 0x7c, 0xbf, 0xc4, 0xf6, 0xf7, 0xff, 0x1f, + 0x1c, 0xf1, 0x97, 0xef, 0xbf, 0x6c, 0x76, 0xc5, 0xbf, 0x4c, 0xbd, 0x6c, + 0x9e, 0x6c, 0x6c, 0xeb, 0xff, 0x6f, 0xff, 0xbf, 0x00, 0x00, 0xff, 0x00, + 0xfb, 0xff, 0xff, 0xdf, 0xd3, 0xff, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xbf, + 0xbc, 0xc7, 0xf3, 0xf7, 0x90, 0xef, 0x9f, 0x74, 0xbd, 0xbc, 0xd8, 0xbc, + 0xb6, 0xa6, 0x93, 0xa5, 0x9c, 0x3b, 0xbc, 0xf7, 0xf7, 0xac, 0xfe, 0x8b, + 0xed, 0xfb, 0xbe, 0xc7, 0xf0, 0xf7, 0x96, 0xef, 0x9e, 0x74, 0xbb, 0xbc, + 0x9d, 0x3b, 0xbc, 0xf7, 0x9c, 0x3b, 0xbc, 0xf7, 0xfb, 0xbc, 0x92, 0xa7, + 0xfb, 0xbc, 0xf2, 0xa7, 0xf5, 0xaf, 0xfe, 0x8b, 0xfd, 0xfb, 0xff, 0xcf, + 0xc3, 0x87, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xdf, 0xb8, 0xef, 0xde, 0x75, + 0x9f, 0x75, 0x3b, 0x83, 0xbc, 0xbc, 0xf9, 0xbc, 0xf6, 0xa7, 0xf2, 0xa7, + 0xfb, 0xbf, 0xf3, 0xa7, 0xfd, 0xbf, 0x92, 0xa7, 0xef, 0xac, 0xc3, 0x87, + 0xcf, 0xff, 0xff, 0xdf, 0x2b, 0xeb, 0xdd, 0xeb, 0xbe, 0x8a, 0xff, 0x1f, + 0xde, 0xf0, 0x3e, 0xc2, 0x36, 0xf3, 0x98, 0xec, 0x9c, 0x6c, 0x37, 0xc4, + 0xba, 0xf3, 0x93, 0xbf, 0xf1, 0xbf, 0xff, 0xa4, 0xff, 0x3b, 0xbf, 0xf7, + 0xfe, 0x15, 0x3b, 0xf6, 0x00, 0x1c, 0x6b, 0x07, 0x3e, 0x8a, 0x7e, 0xec, + 0x9f, 0x73, 0x3d, 0xb4, 0x86, 0xa4, 0x72, 0x8a, 0x3f, 0x53, 0xff, 0x1f, + 0xa6, 0xf5, 0xfd, 0xb7, 0x3f, 0xa1, 0x66, 0x8a, 0x3f, 0x53, 0x83, 0xed, + 0xbd, 0x6c, 0xbd, 0x1b, 0x00, 0xcf, 0x3d, 0xb1, 0x67, 0x8a, 0x67, 0x93, + 0xbd, 0x4c, 0xff, 0x1f, 0x10, 0xf1, 0xbe, 0xc7, 0xed, 0xf7, 0xbf, 0x73, + 0x37, 0xcc, 0x9e, 0xbc, 0x73, 0x9b, 0xf9, 0xf7, 0xff, 0xcf, 0xfd, 0xce, + 0x00, 0x1c, 0xcf, 0x00, 0xe6, 0xfb, 0x63, 0x9b, 0xe8, 0xf7, 0xfc, 0xcf, + 0xff, 0xce, 0x00, 0x1c, 0xd6, 0x00, 0xed, 0xfb, 0x93, 0xed, 0x9f, 0x74, + 0xb8, 0x1b, 0xb0, 0xff, 0x36, 0x9b, 0xf9, 0xf3, 0xff, 0xcf, 0xfd, 0xce, + 0x00, 0x1c, 0xe1, 0x00, 0xf8, 0xfb, 0x23, 0x9b, 0xfa, 0xf7, 0xfc, 0xcf, + 0xff, 0xce, 0x00, 0x1c, 0xe8, 0x00, 0x99, 0xed, 0x9b, 0x7c, 0x9c, 0x1b, + 0xfb, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0x89, 0xf7, 0xff, 0x1f, 0x25, 0xf1, + 0xfc, 0x92, 0x9e, 0xed, 0x9c, 0x27, 0xcf, 0xff, 0xbe, 0xc4, 0xb8, 0xf7, + 0xbf, 0xc7, 0xba, 0xf3, 0xff, 0xcf, 0xff, 0x1f, 0xc4, 0xf5, 0x23, 0xee, + 0x99, 0xbf, 0xb7, 0xbf, 0x92, 0xa5, 0x9e, 0xa4, 0xbc, 0xbc, 0x97, 0xa4, + 0x9d, 0xbc, 0x9e, 0xa4, 0x97, 0xb4, 0x86, 0x51, 0xfe, 0xcf, 0xff, 0x1f, + 0xd2, 0xf5, 0x9b, 0xbf, 0xfc, 0x3b, 0xbc, 0xf7, 0x9c, 0x3b, 0xbc, 0xf7, + 0xbb, 0xbc, 0x92, 0xa5, 0xbb, 0xbc, 0x92, 0xa5, 0x95, 0xac, 0x32, 0x8b, + 0x85, 0x51, 0xa6, 0x71, 0x96, 0xa4, 0xbc, 0xbb, 0x7d, 0x3b, 0xdb, 0xf7, + 0xf2, 0x9a, 0xe2, 0xf3, 0x99, 0x27, 0xc9, 0xff, 0xff, 0xdc, 0x33, 0x8b, + 0x99, 0x23, 0xc9, 0xff, 0xfc, 0xcd, 0x37, 0x9b, 0xe7, 0xf7, 0xbe, 0x69, + 0xd8, 0xee, 0x7b, 0x97, 0xbe, 0x49, 0xd8, 0xee, 0x7b, 0x97, 0xbb, 0x59, + 0xff, 0x1f, 0xf5, 0xf1, 0x80, 0xef, 0xbd, 0x6c, 0xdb, 0xee, 0x7b, 0x97, + 0xbd, 0x4c, 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, 0x38, 0x01, 0xfa, 0xfb, + 0xff, 0xcd, 0x82, 0xef, 0xbc, 0x23, 0xc9, 0xff, 0x66, 0xef, 0x9e, 0x73, + 0x3d, 0xb4, 0x86, 0xa4, 0x72, 0x8a, 0x3e, 0x53, 0xfe, 0xcf, 0xff, 0x1f, + 0x0e, 0xf6, 0xfd, 0xb7, 0x3f, 0xa1, 0x66, 0x8a, 0x3e, 0x53, 0x8b, 0xef, + 0xdd, 0x6c, 0xa7, 0xef, 0xb7, 0x97, 0xbd, 0xb1, 0x77, 0x8b, 0xb7, 0xbd, + 0x7b, 0x93, 0xbd, 0x4c, 0xfc, 0x15, 0x0a, 0xfe, 0x73, 0x9a, 0xf9, 0xf7, + 0xff, 0xcf, 0xfe, 0xce, 0x00, 0x1c, 0x5b, 0x01, 0xf6, 0xfb, 0xfc, 0x15, + 0x94, 0xfe, 0x73, 0x9a, 0xfa, 0xf3, 0xff, 0xcf, 0xfc, 0xce, 0x00, 0x1c, + 0x64, 0x01, 0xff, 0x1f, 0x3e, 0xf6, 0x5a, 0x1b, 0xfd, 0xbf, 0x31, 0xc2, + 0x99, 0xf3, 0xba, 0xef, 0xff, 0xcc, 0xee, 0xfb, 0xff, 0x5f, 0xff, 0xbf, + 0xcf, 0xff, 0xff, 0xdf, 0xff, 0x6f, 0xff, 0xbf, 0xfb, 0xff, 0xff, 0xdf, + 0xf0, 0xff, 0x01, 0x00, 0xf4, 0xff, 0x01, 0x00, 0x00, 0x00, 0xf0, 0x00, + 0x00, 0xff, 0x00, 0x00, 0xff, 0xd4, 0x93, 0x5d, 0xfd, 0x27, 0xc8, 0xff, + 0x7f, 0xce, 0xd8, 0xbe, 0xff, 0x1f, 0x77, 0xf9, 0x7c, 0x92, 0xbe, 0x6f, + 0x9f, 0x7d, 0xbe, 0xc4, 0xe3, 0xf3, 0xbf, 0xc4, 0xf9, 0xf3, 0xbd, 0xc4, + 0xdf, 0xf3, 0xbc, 0xc4, 0xc5, 0xf7, 0xcf, 0xfb, 0x92, 0xec, 0xbf, 0x6c, + 0x76, 0xc5, 0xbf, 0x4c, 0xbd, 0x6c, 0x9e, 0x6c, 0x94, 0xec, 0xbb, 0x7c, + 0x7d, 0xc5, 0xbb, 0x5c, 0x95, 0xec, 0xbd, 0x6c, 0xd5, 0xec, 0x7b, 0x97, + 0xbd, 0x4c, 0x95, 0xec, 0xff, 0xcd, 0xbf, 0x4c, 0xbe, 0x4c, 0xda, 0xfb, + 0xbe, 0x75, 0x9b, 0xec, 0xad, 0x54, 0xfd, 0xcf, 0xff, 0xce, 0x00, 0x1c, + 0xac, 0x01, 0xe2, 0xfb, 0xff, 0xcd, 0x9f, 0xec, 0xad, 0x54, 0xff, 0x1f, + 0x78, 0xf2, 0x7d, 0xec, 0xff, 0x1f, 0x0f, 0xf2, 0xff, 0xd3, 0xbf, 0xc3, + 0x03, 0xf4, 0xfe, 0xcf, 0x00, 0x1c, 0x07, 0x04, 0xfe, 0xcf, 0xff, 0xce, + 0x00, 0x1c, 0xbf, 0x01, 0xf5, 0xfb, 0xff, 0xcd, 0x89, 0xed, 0xad, 0x54, + 0xff, 0x1f, 0x8b, 0xf2, 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, 0xc9, 0x01, + 0xe4, 0x93, 0xff, 0x1f, 0xce, 0xf9, 0x7f, 0xcc, 0x98, 0xbc, 0xb2, 0x92, + 0x33, 0xc2, 0x8a, 0xf3, 0xfc, 0xcf, 0x00, 0x1c, 0x6a, 0x01, 0xfc, 0x92, + 0x93, 0xed, 0xfc, 0x27, 0xc8, 0xff, 0x7f, 0xce, 0xda, 0xbe, 0xff, 0x1f, + 0xce, 0xf9, 0x9e, 0x6f, 0x3f, 0x7c, 0xff, 0x1f, 0xe2, 0xf9, 0xf3, 0xed, + 0xac, 0x93, 0x00, 0x1c, 0x16, 0x05, 0xff, 0x1f, 0x26, 0xf2, 0x9b, 0xbf, + 0xfc, 0x3b, 0xbf, 0xf7, 0xff, 0x3b, 0xbf, 0xf7, 0xee, 0x9b, 0xec, 0xf3, + 0xff, 0x1f, 0x2f, 0xf2, 0x9b, 0xbf, 0xfc, 0x3b, 0xbf, 0xf7, 0xff, 0x3b, + 0xbf, 0xf7, 0xec, 0xd7, 0xfe, 0x9a, 0xfa, 0xf3, 0x25, 0x8b, 0xdf, 0xc4, + 0xfd, 0xf7, 0xfd, 0xc9, 0xe5, 0x8b, 0x00, 0x1c, 0x04, 0x04, 0xbb, 0xfb, + 0xff, 0x1f, 0x41, 0xf2, 0x9b, 0xbf, 0xfc, 0x3b, 0xbf, 0xf7, 0xff, 0x3b, + 0xbf, 0xf7, 0x74, 0xdf, 0xee, 0x9b, 0xf9, 0xf7, 0xff, 0xcf, 0xf8, 0xd7, + 0x00, 0x1c, 0x13, 0x04, 0xca, 0xfb, 0xff, 0x1f, 0x50, 0xf2, 0x9d, 0xa7, + 0xbb, 0xbc, 0x9d, 0x3b, 0xbc, 0xf7, 0x9c, 0x3b, 0xbc, 0xf7, 0x2e, 0x9b, + 0xf9, 0xf7, 0xff, 0xcf, 0xfc, 0xd7, 0x00, 0x1c, 0x22, 0x04, 0xd9, 0xfb, + 0xff, 0x1f, 0x5f, 0xf2, 0x9b, 0xbf, 0xfc, 0x3b, 0xbc, 0xf7, 0x9c, 0x3b, + 0xbc, 0xf7, 0xce, 0xdc, 0x2e, 0x9b, 0xf9, 0xf7, 0xff, 0xcf, 0xfe, 0xd7, + 0x00, 0x1c, 0x31, 0x04, 0xe8, 0xfb, 0xff, 0x1f, 0x6e, 0xf2, 0x9b, 0xbf, + 0xfc, 0x3b, 0xbc, 0xf7, 0x9c, 0x3b, 0xbc, 0xf7, 0x2e, 0x9b, 0xf1, 0xf7, + 0x67, 0x8a, 0x65, 0x8b, 0xff, 0xcc, 0xff, 0xd4, 0x36, 0x9b, 0xfa, 0xf3, + 0xf4, 0x93, 0x00, 0x1c, 0x44, 0x04, 0xfb, 0xfb, 0xff, 0xcf, 0x00, 0x1c, + 0x48, 0x04, 0x7f, 0xce, 0xda, 0xbe, 0xba, 0x92, 0x34, 0xc2, 0x94, 0xf3, + 0x8c, 0xef, 0xfc, 0x27, 0xc8, 0xff, 0x7f, 0xce, 0xdb, 0xbe, 0xff, 0x1f, + 0x40, 0xfa, 0xfe, 0x47, 0x9e, 0x6f, 0x9f, 0x7c, 0xbd, 0xbc, 0xd8, 0xbc, + 0xb6, 0xa6, 0x93, 0xa5, 0x9c, 0x3b, 0xbc, 0xf7, 0x1b, 0xac, 0x00, 0x1c, + 0xce, 0x01, 0x7c, 0x92, 0xfc, 0xcf, 0x00, 0x1c, 0xf4, 0x01, 0xfc, 0x92, + 0xff, 0x1f, 0x9b, 0xf2, 0x9c, 0xbf, 0xfc, 0x3b, 0xdf, 0xf7, 0x03, 0xa7, + 0x9d, 0xbb, 0xbb, 0xbb, 0x92, 0xa5, 0x8e, 0xa4, 0xef, 0xfb, 0xff, 0xff, + 0xff, 0xdf, 0xff, 0xbf, 0xfb, 0xff, 0xff, 0xdf, 0xff, 0x5f, 0xff, 0xbf, + 0x00, 0x00, 0xf0, 0x00, 0xff, 0x8f, 0xff, 0xbf, 0xbf, 0xf2, 0xfc, 0xff, + 0x93, 0x83, 0xff, 0xff, 0xbc, 0xbc, 0x92, 0xa5, 0x99, 0xac, 0x13, 0xa0, + 0x82, 0xa1, 0x9f, 0x47, 0xf9, 0xee, 0xa0, 0x93, 0x64, 0x93, 0x2c, 0x93, + 0x00, 0x1c, 0xb7, 0x05, 0x63, 0x9a, 0xe5, 0xf7, 0x22, 0xa1, 0x66, 0x8a, + 0x05, 0xcc, 0x9b, 0xbc, 0x73, 0x9a, 0xe6, 0xf3, 0xfc, 0x15, 0x23, 0xfa, + 0x73, 0x9a, 0xf4, 0xf7, 0xa1, 0xef, 0x9d, 0x27, 0xc7, 0xff, 0xff, 0xdc, + 0x33, 0x8b, 0x9d, 0x23, 0xc7, 0xff, 0xfd, 0xc4, 0xec, 0xf3, 0xf4, 0xfb, + 0xff, 0xcd, 0x86, 0xef, 0xbc, 0x23, 0xc7, 0xff, 0xf2, 0xfb, 0xff, 0xcd, + 0x89, 0xef, 0xbc, 0x23, 0xc7, 0xff, 0xf7, 0xfb, 0xff, 0xcf, 0x00, 0x1c, + 0xf4, 0x04, 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, 0xac, 0x02, 0xfe, 0x67, + 0xff, 0x1f, 0xb1, 0xfa, 0x5a, 0x1b, 0xff, 0xb7, 0x3d, 0xc2, 0xf5, 0xf3, + 0xfe, 0xcf, 0x00, 0x1c, 0x02, 0x05, 0xfe, 0xcf, 0xff, 0xce, 0x00, 0x1c, + 0xba, 0x02, 0x5a, 0x1b, 0xfb, 0xbf, 0x3f, 0xc2, 0xf5, 0xf3, 0xff, 0x1f, + 0x1a, 0xf3, 0x98, 0xef, 0x9c, 0x27, 0xd5, 0xff, 0xbf, 0xc4, 0xfc, 0xf3, + 0xff, 0x1f, 0xd3, 0xf6, 0xff, 0xcf, 0xfd, 0xeb, 0x6b, 0xeb, 0xff, 0xff, + 0x87, 0x83, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, 0x2e, 0xeb, 0xff, 0x1f, + 0x50, 0xf5, 0xff, 0x1f, 0xa0, 0xf7, 0xff, 0x1f, 0x92, 0xf6, 0xff, 0x1f, + 0x74, 0xf3, 0xff, 0x1f, 0x1a, 0xf5, 0xff, 0x1f, 0x4c, 0xf3, 0xff, 0x1f, + 0x88, 0xf7, 0x7f, 0xcb, 0x68, 0xbb, 0xec, 0x93, 0x46, 0xce, 0xdd, 0xbe, + 0xfe, 0xcd, 0xff, 0x1f, 0x9c, 0xf3, 0x9d, 0x6b, 0x9e, 0x4b, 0x9f, 0x6b, + 0x56, 0xc4, 0x9f, 0x4b, 0x6e, 0xeb, 0xff, 0xff, 0x2e, 0xeb, 0xe9, 0xef, + 0xff, 0x1f, 0xcd, 0xf9, 0x6a, 0xef, 0xfb, 0x23, 0xc8, 0xff, 0xff, 0x1f, + 0xc0, 0xf4, 0xbc, 0x93, 0xec, 0xef, 0x00, 0x1c, 0x2c, 0x06, 0xff, 0xcc, + 0x9b, 0x23, 0xc6, 0xff, 0x9b, 0x23, 0xd5, 0xff, 0xfe, 0xcf, 0xff, 0x1f, + 0xca, 0xf7, 0xe8, 0x53, 0xfb, 0x27, 0xc8, 0xff, 0xfe, 0xce, 0x05, 0xcd, + 0xbe, 0xbd, 0xfe, 0xcc, 0xff, 0x1f, 0x6b, 0xfb, 0xfb, 0x27, 0xc8, 0xff, + 0xfd, 0xce, 0xf8, 0xcd, 0xfe, 0xcc, 0xff, 0x1f, 0x72, 0xfb, 0xfb, 0x27, + 0xc8, 0xff, 0xfb, 0xce, 0xff, 0x1f, 0xa9, 0xfa, 0x6e, 0xeb, 0xff, 0xff, + 0xcf, 0xa3, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, 0x67, 0x83, 0xff, 0xff, + 0x2c, 0xeb, 0x9d, 0xec, 0x9b, 0x7c, 0x9c, 0x1b, 0xfb, 0xdf, 0x33, 0x8b, + 0xbf, 0xc4, 0x2c, 0xf3, 0xa1, 0xed, 0xde, 0x6d, 0x90, 0xbe, 0x8c, 0xb4, + 0xff, 0xdc, 0x8c, 0xbc, 0x90, 0xb4, 0xe3, 0xed, 0xbf, 0x97, 0x3b, 0x93, + 0x9e, 0x4d, 0xc4, 0xed, 0xdc, 0x3b, 0xdd, 0xdf, 0xdf, 0xcc, 0x35, 0x9b, + 0xf2, 0xf7, 0x86, 0xed, 0xbc, 0x6c, 0x57, 0xc5, 0xbc, 0x4c, 0xbd, 0x6c, + 0x0f, 0xca, 0x4f, 0xba, 0x6b, 0x93, 0xbd, 0x4c, 0xff, 0x1f, 0x1b, 0xf8, + 0xcf, 0xfa, 0x5f, 0xcc, 0x9b, 0xbc, 0x35, 0x9b, 0xb7, 0xf7, 0xff, 0x1f, + 0x10, 0xf4, 0x8f, 0xed, 0xbd, 0x6c, 0xef, 0xed, 0x7f, 0x97, 0xbd, 0x4c, + 0x95, 0xed, 0x5b, 0x7c, 0x9a, 0x1b, 0xfc, 0xdf, 0xbf, 0xc4, 0xce, 0xf7, + 0x78, 0xed, 0x3d, 0x6b, 0xf7, 0xb9, 0xf7, 0xb7, 0xdc, 0x73, 0xc8, 0xbe, + 0xc7, 0xb6, 0x00, 0x1c, 0x1c, 0x0a, 0xf7, 0xbf, 0xf7, 0xb7, 0x27, 0xb1, + 0x27, 0xb9, 0x7f, 0x92, 0x3d, 0x4b, 0x5a, 0x1b, 0xf7, 0xdf, 0xab, 0x8a, + 0xbf, 0xc2, 0xfc, 0xf3, 0xfe, 0x53, 0xed, 0xfb, 0x83, 0xee, 0x9e, 0x74, + 0xfb, 0xd4, 0x3e, 0x9b, 0xf2, 0xf3, 0x85, 0xee, 0xbb, 0x7c, 0x7f, 0xc5, + 0x7e, 0xc5, 0x5f, 0xc5, 0xbb, 0x5c, 0xee, 0xcf, 0xff, 0x1f, 0x03, 0xf6, + 0xfe, 0xcf, 0xff, 0x1f, 0x06, 0xf6, 0x8b, 0xee, 0xbd, 0x6c, 0xa7, 0xb5, + 0xa7, 0xbd, 0xbd, 0x4c, 0xbc, 0x74, 0xbd, 0x1b, 0x01, 0xce, 0xbc, 0x54, + 0x90, 0xee, 0xbb, 0x7c, 0x7d, 0xc5, 0x7c, 0xc5, 0xbb, 0x5c, 0xbe, 0x6c, + 0xd2, 0xee, 0x7b, 0x97, 0xbe, 0x4c, 0x1a, 0xfb, 0xff, 0x1f, 0x71, 0xf8, + 0xfc, 0x92, 0xff, 0x1f, 0x3e, 0xf5, 0x92, 0xee, 0x9f, 0x74, 0xba, 0xdc, + 0xf2, 0x9a, 0xdd, 0xf3, 0x9a, 0xee, 0xbe, 0x6c, 0x5a, 0xee, 0x6b, 0x97, + 0xbe, 0x4c, 0xf6, 0xee, 0x7f, 0x97, 0xbb, 0x5c, 0xff, 0x1f, 0x69, 0xf4, + 0x9c, 0xee, 0xbd, 0x6c, 0xdc, 0xee, 0x7b, 0x97, 0xbd, 0x4c, 0x9c, 0xee, + 0x9f, 0x74, 0x88, 0xdc, 0xf2, 0x9a, 0xf6, 0xf7, 0xa4, 0xef, 0x9f, 0x7d, + 0xff, 0xdc, 0x33, 0x8b, 0x9f, 0x5d, 0xfd, 0xcd, 0x37, 0x9b, 0x40, 0xf7, + 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, 0xb9, 0x03, 0x45, 0xfb, 0x8a, 0xef, + 0xbe, 0x6c, 0xb0, 0xbd, 0xac, 0xb5, 0xaf, 0xcc, 0x72, 0x9b, 0xfb, 0xf3, + 0xff, 0xcd, 0x8e, 0xef, 0xbf, 0x5c, 0xfc, 0x15, 0x0c, 0xfe, 0xf3, 0x9b, + 0xf9, 0xf3, 0xce, 0xdf, 0xfe, 0x8b, 0xff, 0x1f, 0x90, 0xf5, 0x58, 0xfb, + 0x94, 0xef, 0x9b, 0x7c, 0x9c, 0x1b, 0xfc, 0xdf, 0xbf, 0xc4, 0x5e, 0xf7, + 0x97, 0xef, 0xbc, 0x74, 0xc8, 0xbd, 0xc7, 0xb6, 0xff, 0xde, 0xbb, 0x8b, + 0xde, 0xbe, 0xbd, 0x1b, 0x01, 0xce, 0x7b, 0x93, 0xbc, 0x54, 0xbd, 0x6c, + 0xd7, 0xbd, 0xd7, 0xb6, 0xef, 0xfb, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, + 0xf0, 0xff, 0x01, 0x00, 0x0f, 0x00, 0xfe, 0xff, 0xff, 0x5f, 0xff, 0xbf, + 0x00, 0x00, 0xf0, 0x00, 0x8b, 0xfe, 0xff, 0xdf, 0xf4, 0xff, 0x01, 0x00, + 0x7b, 0xa3, 0x77, 0xbb, 0x77, 0xb3, 0xa7, 0xb5, 0xa7, 0xbd, 0x6f, 0x93, + 0xbd, 0x4c, 0x84, 0xfb, 0xc1, 0xee, 0xfe, 0x6e, 0x90, 0xbf, 0x8c, 0xb4, + 0xff, 0xdc, 0x8c, 0xbc, 0x8c, 0xb4, 0x7b, 0xbc, 0x44, 0xee, 0x5f, 0x3b, + 0xdd, 0xdf, 0x6f, 0x93, 0xbe, 0x4e, 0xe5, 0xee, 0x7f, 0x97, 0xaf, 0xc5, + 0xf3, 0xf7, 0xa6, 0xee, 0xff, 0xce, 0xdf, 0x4d, 0xdf, 0x6d, 0xdf, 0x4d, + 0xdf, 0x6d, 0x5d, 0xc6, 0xdf, 0x4d, 0xdf, 0x6d, 0x5c, 0xc6, 0xdf, 0x4d, + 0xaf, 0xee, 0xbb, 0x7d, 0xbd, 0x1b, 0xf7, 0xdf, 0x77, 0x8b, 0xbf, 0xc5, + 0xfa, 0xf3, 0x9c, 0xcd, 0x36, 0x9b, 0xf9, 0xf7, 0xb6, 0xfb, 0xfd, 0x15, + 0x30, 0xf8, 0x36, 0x9b, 0xba, 0xf3, 0x96, 0xee, 0xff, 0xcd, 0xbc, 0x23, + 0xcf, 0xff, 0xbb, 0x7c, 0x5d, 0xc5, 0xbb, 0x5c, 0xbe, 0x6c, 0x59, 0xee, + 0x6b, 0x97, 0xbe, 0x4c, 0x99, 0xee, 0xff, 0xcf, 0xff, 0x4c, 0xff, 0x1f, + 0x80, 0xf4, 0xbe, 0xc7, 0xfa, 0xf3, 0xff, 0x1f, 0x84, 0xf4, 0xbd, 0xc7, + 0xe8, 0xf7, 0x81, 0xef, 0x9b, 0x7c, 0x9c, 0x1b, 0xfc, 0xdf, 0xbf, 0xc4, + 0xf6, 0xf7, 0x55, 0xcf, 0xfd, 0xbf, 0xcd, 0xce, 0xff, 0xcd, 0xfe, 0xcc, + 0xff, 0x1f, 0x91, 0xf5, 0xe1, 0xfb, 0x55, 0xcf, 0xfd, 0xbf, 0xcd, 0xce, + 0xff, 0xcd, 0xfe, 0xcc, 0xff, 0x1f, 0x99, 0xf5, 0xe9, 0xfb, 0x8c, 0xef, + 0x9b, 0x7c, 0x9c, 0x1b, 0xfc, 0xdf, 0xbf, 0xc4, 0xf6, 0xf7, 0x74, 0xcf, + 0xfd, 0xbf, 0xcd, 0xce, 0xff, 0xcd, 0xfe, 0xcc, 0xff, 0x1f, 0xa7, 0xf5, + 0xf7, 0xfb, 0xff, 0x15, 0x7a, 0xfd, 0xcd, 0xce, 0xff, 0xcd, 0xfe, 0xcc, + 0xff, 0x1f, 0xaf, 0xf5, 0xff, 0x1f, 0xf3, 0xf8, 0xf3, 0xfb, 0xdb, 0xc4, + 0xf9, 0xf7, 0xfe, 0xcd, 0x9a, 0xef, 0xbc, 0x23, 0xcf, 0xff, 0xfa, 0xfb, + 0xff, 0xcd, 0x9c, 0xef, 0xbc, 0x23, 0xcf, 0xff, 0x6c, 0xeb, 0xff, 0xff, + 0xfb, 0xff, 0xff, 0xdf, 0xf0, 0xff, 0x01, 0x00, 0x0f, 0x00, 0xfe, 0xff, + 0xff, 0x8f, 0xff, 0xbf, 0x2d, 0xeb, 0x9c, 0xee, 0xbc, 0x6c, 0x77, 0x8b, + 0x55, 0xcc, 0x35, 0x9b, 0xf9, 0xf7, 0xff, 0xcd, 0x9f, 0xee, 0xbc, 0x23, + 0xd5, 0xff, 0xc5, 0xfb, 0x82, 0xef, 0xbc, 0x6c, 0x77, 0x8b, 0xaa, 0xcc, + 0x35, 0x9b, 0xcb, 0xf7, 0x85, 0xef, 0x9f, 0x6c, 0x33, 0x8b, 0xae, 0xc4, + 0xf7, 0xf3, 0xad, 0xc4, 0xf4, 0xf3, 0xbf, 0xc4, 0xd4, 0xf7, 0xff, 0x1f, + 0x60, 0xf5, 0xd7, 0xfb, 0xff, 0xcd, 0x8a, 0xef, 0xbc, 0x23, 0xc6, 0xff, + 0xdc, 0xfb, 0xfe, 0xcd, 0x8d, 0xef, 0xbc, 0x23, 0xc6, 0xff, 0xff, 0x1f, + 0xf2, 0xf4, 0xbf, 0xc7, 0xe4, 0xf7, 0xff, 0xcd, 0x91, 0xef, 0xad, 0x54, + 0xfe, 0xcf, 0xff, 0x1f, 0x00, 0xf5, 0xfa, 0xcf, 0xff, 0x1f, 0xf7, 0xf4, + 0xff, 0x1f, 0x79, 0xf5, 0x55, 0xef, 0xff, 0xcb, 0xff, 0xd3, 0xff, 0x1f, + 0x12, 0xf5, 0xff, 0xd2, 0xe9, 0x9a, 0x03, 0xf4, 0xfe, 0xcf, 0x00, 0x1c, + 0x0a, 0x07, 0xfe, 0xcf, 0xf7, 0xce, 0x00, 0x1c, 0xc2, 0x04, 0x6d, 0xeb, + 0xff, 0x6f, 0xff, 0xbf, 0xfb, 0xff, 0xff, 0xdf, 0xc0, 0xf2, 0xfc, 0xff, + 0x2e, 0xeb, 0xff, 0x8a, 0x94, 0xef, 0x7f, 0x5c, 0xf7, 0xcf, 0xff, 0x1f, + 0xea, 0xfc, 0xbf, 0xc7, 0xf5, 0xf3, 0x7f, 0xcc, 0x98, 0xbc, 0x9e, 0x57, + 0xfd, 0xcc, 0x9f, 0x5f, 0x9a, 0xef, 0x9e, 0x4f, 0xff, 0x1f, 0xd9, 0xfb, + 0xfb, 0xef, 0xac, 0x93, 0x00, 0x1c, 0x11, 0x08, 0x6e, 0xeb, 0xff, 0xff, + 0xbf, 0xff, 0xff, 0xdf, 0x53, 0x83, 0xff, 0xff, 0x2b, 0xeb, 0xdc, 0xeb, + 0xbe, 0x8a, 0x32, 0xc2, 0xf2, 0xf3, 0x63, 0xed, 0x31, 0xa3, 0xe5, 0xa3, + 0xff, 0x1f, 0x19, 0xfd, 0xff, 0xcc, 0x9f, 0x59, 0xfe, 0xcc, 0x9e, 0x5b, + 0x7f, 0xcf, 0xf9, 0xbf, 0xbe, 0x92, 0x28, 0x8b, 0x20, 0xc4, 0x07, 0xf3, + 0x8b, 0xed, 0xf7, 0x7c, 0x7f, 0xce, 0xd7, 0xbe, 0xff, 0x1f, 0xf1, 0xfc, + 0xfd, 0x47, 0xde, 0x6f, 0xde, 0x47, 0xb9, 0xa6, 0xbf, 0x47, 0x7e, 0x7e, + 0xf0, 0xed, 0x00, 0x1c, 0x3a, 0x08, 0xbf, 0xc3, 0xf3, 0xf3, 0x3f, 0x67, + 0x12, 0xed, 0xdf, 0x79, 0xff, 0xd9, 0xe0, 0x93, 0x00, 0x1c, 0x43, 0x08, + 0xff, 0xd3, 0xef, 0x8a, 0xbf, 0xc3, 0x07, 0xf4, 0x96, 0xed, 0xff, 0xcd, + 0xbf, 0x5c, 0xbc, 0x7c, 0x00, 0xcc, 0x35, 0x9b, 0xec, 0xf7, 0x7c, 0xed, + 0x9b, 0x1b, 0xf4, 0xff, 0xbf, 0x7c, 0xbd, 0x1b, 0x03, 0xdf, 0xbd, 0x1b, + 0xe3, 0xcf, 0xbd, 0x1b, 0xe3, 0xdf, 0xbf, 0x5c, 0xf7, 0x7b, 0xfe, 0xce, + 0x69, 0xcd, 0xfe, 0xcc, 0xff, 0x1f, 0x8d, 0xfd, 0xf8, 0x5b, 0x9e, 0x67, + 0x7e, 0x7c, 0xbe, 0xc3, 0xed, 0xf3, 0xfe, 0xd3, 0xef, 0x8a, 0xdf, 0x67, + 0xfd, 0xa6, 0xef, 0xa7, 0x38, 0x93, 0xff, 0xcd, 0xdf, 0x7c, 0x7a, 0x93, + 0xff, 0xdc, 0xf1, 0x9b, 0x03, 0xf4, 0xff, 0xdb, 0x9f, 0x67, 0x8f, 0xa4, + 0x9f, 0x47, 0xfd, 0xfb, 0xff, 0xcd, 0xff, 0x67, 0x9f, 0x7f, 0x71, 0x9b, + 0xea, 0xf3, 0xee, 0xee, 0x00, 0x1c, 0x7d, 0x08, 0xb1, 0xee, 0x9e, 0x7d, + 0xff, 0xdc, 0x33, 0x8b, 0x9e, 0x5d, 0xf5, 0xcd, 0x37, 0x9b, 0x67, 0xf7, + 0xff, 0xcd, 0x95, 0xee, 0xbe, 0x5c, 0xff, 0x1f, 0x7c, 0xf9, 0xf5, 0xee, + 0x00, 0x1c, 0x8d, 0x08, 0x70, 0xfb, 0xff, 0xcd, 0x9a, 0xee, 0xbe, 0x5c, + 0xde, 0x67, 0x9f, 0x7e, 0xbc, 0xc4, 0xa9, 0xf3, 0xfc, 0xc4, 0xf9, 0xf7, + 0xbe, 0xc4, 0xe0, 0xf3, 0xbd, 0xc4, 0x7d, 0xf7, 0xf5, 0xfb, 0xae, 0xcd, + 0x71, 0x9b, 0xcd, 0xf3, 0x8e, 0xcd, 0x71, 0x9b, 0xde, 0xf3, 0xbb, 0xc4, + 0x86, 0xf7, 0xa4, 0xfb, 0xfe, 0xcd, 0x88, 0xef, 0xbe, 0x5c, 0xbe, 0x67, + 0x9c, 0x7d, 0xb4, 0xc4, 0xfa, 0xf7, 0xfd, 0xcf, 0x00, 0x1c, 0xb1, 0x00, + 0xfb, 0xfb, 0xfc, 0xcf, 0x00, 0x1c, 0xb5, 0x00, 0xe9, 0xef, 0xff, 0x1f, + 0xae, 0xfd, 0x99, 0xfb, 0x91, 0xef, 0x9e, 0x7c, 0xbe, 0xc4, 0xa3, 0xf7, + 0xfd, 0xcd, 0x93, 0xef, 0xbe, 0x5c, 0xff, 0xcf, 0x00, 0x1c, 0xc3, 0x00, + 0xa4, 0xfb, 0x96, 0xef, 0x9e, 0x7c, 0xbd, 0xc4, 0xae, 0xf7, 0x98, 0xef, + 0xfc, 0xcd, 0xbe, 0x5c, 0xfe, 0x67, 0xdb, 0x7f, 0xd7, 0xbe, 0xba, 0x7f, + 0x7b, 0x93, 0xbe, 0x54, 0xb2, 0xfb, 0x9d, 0xef, 0x9e, 0x7c, 0xf0, 0xfb, + 0xbf, 0xff, 0xff, 0xdf, 0x3f, 0x83, 0xff, 0xff, 0x3b, 0x83, 0xff, 0xff, + 0xbb, 0xff, 0xff, 0xdf, 0x33, 0x83, 0xff, 0xff, 0x23, 0x83, 0xff, 0xff, + 0xb8, 0xff, 0xff, 0xdf, 0xbc, 0xc4, 0xcb, 0xf7, 0xfb, 0xcd, 0x97, 0xec, + 0xbe, 0x5c, 0xfe, 0xcf, 0x00, 0x1c, 0xeb, 0x00, 0xcc, 0xfb, 0x9a, 0xec, + 0x9e, 0x7c, 0xbb, 0xc4, 0xd6, 0xf7, 0xf7, 0xcf, 0xff, 0x1f, 0xd9, 0xfd, + 0xdd, 0x67, 0xbf, 0xc6, 0xd6, 0xf3, 0x7f, 0xcc, 0x9a, 0xbc, 0x9e, 0x57, + 0xfd, 0xcc, 0x9f, 0x5f, 0xbe, 0x67, 0x95, 0xa5, 0x9e, 0x4f, 0xff, 0x1f, + 0xca, 0xfc, 0xe1, 0xfb, 0x85, 0xed, 0x9e, 0x7c, 0xbb, 0xc4, 0xeb, 0xf7, + 0xff, 0xcd, 0x86, 0xed, 0xbd, 0x5c, 0xf7, 0xcf, 0xff, 0x1f, 0xf1, 0xfd, + 0xbf, 0xc7, 0xed, 0xf3, 0x7f, 0xcc, 0x9b, 0xbc, 0x9e, 0x57, 0xfd, 0xcc, + 0x9f, 0x5f, 0xde, 0x67, 0x95, 0xa6, 0x9e, 0x4f, 0xff, 0x1f, 0xe1, 0xfc, + 0xf8, 0xfb, 0xfe, 0xcd, 0x91, 0xed, 0xbe, 0x5c, 0xfd, 0xcf, 0x00, 0x1c, + 0x1e, 0x01, 0xfd, 0x67, 0xff, 0x1f, 0xef, 0xfd, 0x7f, 0xcd, 0xb7, 0xbd, + 0xb6, 0x92, 0x3f, 0xc2, 0xa4, 0xf2, 0xb6, 0xed, 0x9f, 0x7d, 0xff, 0xdc, + 0x33, 0x8b, 0x9f, 0x5d, 0xf2, 0xc4, 0xc6, 0xf6, 0xb9, 0xed, 0x9d, 0x3b, + 0xbc, 0xf7, 0x9f, 0x6c, 0xf3, 0x87, 0x9a, 0xed, 0x9f, 0x7c, 0x9c, 0x1b, + 0xe3, 0xdf, 0xa3, 0xc4, 0xfc, 0xf3, 0xab, 0xc4, 0xf8, 0xf7, 0x9e, 0xed, + 0xbf, 0x7c, 0xbd, 0x1b, 0xe3, 0xcf, 0xbf, 0x5c, 0xf3, 0xfb, 0xa1, 0xee, + 0x9f, 0x7d, 0xdd, 0xb4, 0xff, 0xde, 0xde, 0x1b, 0xf8, 0xdf, 0xdd, 0xbe, + 0x9c, 0x1b, 0xe3, 0xcf, 0x3b, 0x93, 0x9f, 0x5d, 0x87, 0xee, 0x9f, 0x7c, + 0xfc, 0x1b, 0xfc, 0xdf, 0xdd, 0xb4, 0xde, 0x1b, 0xf8, 0xdf, 0x9a, 0xb4, + 0xbc, 0x1b, 0xf8, 0xdf, 0xff, 0x1f, 0x89, 0xfa, 0xec, 0xee, 0x00, 0x1c, + 0x58, 0x09, 0xf4, 0xfa, 0x8f, 0xee, 0x9f, 0x7c, 0x9c, 0x1b, 0xe3, 0xdf, + 0xbf, 0xc4, 0xf6, 0xf7, 0x92, 0xee, 0xbf, 0x7c, 0xbd, 0x1b, 0xe3, 0xcf, + 0xbd, 0x13, 0xe7, 0xff, 0xbf, 0x5c, 0xe5, 0xfb, 0xbb, 0xc4, 0xf8, 0xf7, + 0x97, 0xee, 0xbf, 0x7c, 0xbd, 0x13, 0xe3, 0xff, 0xbf, 0x5c, 0xed, 0xfb, + 0x9a, 0xee, 0x9f, 0x7c, 0x9d, 0xb4, 0x9c, 0x1b, 0xf8, 0xdf, 0xda, 0xc4, + 0xf4, 0xf3, 0xbd, 0xee, 0xfe, 0xd4, 0xdc, 0x1b, 0xf8, 0xdf, 0xdd, 0xbe, + 0x9f, 0x7d, 0x9c, 0x1b, 0xe3, 0xcf, 0x3b, 0x93, 0x9f, 0x5d, 0x82, 0xef, + 0x9f, 0x7c, 0xfc, 0x1b, 0xfc, 0xdf, 0xdd, 0xb4, 0xde, 0x1b, 0xf8, 0xdf, + 0x9a, 0xb4, 0xbc, 0x1b, 0xf8, 0xdf, 0xff, 0x1f, 0xc0, 0xfa, 0xe6, 0xef, + 0x00, 0x1c, 0x8f, 0x09, 0x2b, 0xfb, 0x6a, 0xef, 0x9f, 0x7b, 0x9c, 0x1b, + 0xe3, 0xcf, 0x9c, 0x1b, 0xe0, 0xdf, 0x9f, 0x5b, 0xff, 0x1f, 0xcb, 0xf7, + 0xfe, 0x53, 0xff, 0x1f, 0x14, 0xf8, 0xfd, 0x53, 0xff, 0x1f, 0xb9, 0xf6, + 0xbe, 0xc7, 0xfb, 0xf3, 0x7d, 0xcd, 0x4b, 0xcf, 0xfc, 0xfb, 0x8c, 0xcd, + 0x6c, 0xcf, 0x95, 0xef, 0x9e, 0x7c, 0xbf, 0xc4, 0xdb, 0xf3, 0x00, 0x1c, + 0x3c, 0x0b, 0xbc, 0x93, 0x96, 0xef, 0xff, 0x6c, 0x00, 0x1c, 0xcb, 0x0b, + 0xef, 0xfb, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xdf, 0xbb, 0xff, 0xff, 0xdf, + 0x27, 0x84, 0xff, 0xff, 0xb3, 0xff, 0xff, 0xdf, 0x1b, 0x83, 0xff, 0xff, + 0x13, 0x83, 0xff, 0xff, 0xdf, 0x83, 0xff, 0xff, 0x9a, 0xec, 0xdf, 0x6c, + 0x00, 0x1c, 0x17, 0x0c, 0x00, 0x1c, 0xdd, 0x0c, 0x9c, 0xec, 0xbe, 0x74, + 0x3e, 0x8b, 0x73, 0x9b, 0xea, 0xf7, 0x4a, 0xfb, 0xf4, 0x93, 0x00, 0x1c, + 0x60, 0x0b, 0xbc, 0x93, 0x80, 0xed, 0xff, 0x6c, 0x00, 0x1c, 0xef, 0x0b, + 0x84, 0xed, 0xdf, 0x6c, 0x00, 0x1c, 0x2b, 0x0c, 0x00, 0x1c, 0xf1, 0x0c, + 0x86, 0xed, 0xbe, 0x74, 0x3e, 0x8b, 0x37, 0x9b, 0x5d, 0xf7, 0x88, 0xed, + 0xfe, 0xcd, 0xbe, 0x5c, 0x9d, 0x74, 0x24, 0xcd, 0x37, 0x9b, 0xf7, 0xf3, + 0xea, 0xdc, 0xf2, 0x8b, 0x8d, 0xed, 0xfd, 0x54, 0xff, 0x1f, 0x7f, 0xf8, + 0xfa, 0xfb, 0x8f, 0xed, 0xbe, 0x74, 0xea, 0xdd, 0xbe, 0x54, 0xef, 0xed, + 0x00, 0x1c, 0xf5, 0x09, 0x73, 0xed, 0x9f, 0x7b, 0xfc, 0x1b, 0xfc, 0xdf, + 0xdd, 0xb4, 0xde, 0x1b, 0xf8, 0xdf, 0x9a, 0xb4, 0xbc, 0x1b, 0xf8, 0xdf, + 0xff, 0x1f, 0x35, 0xfb, 0xfe, 0x73, 0xff, 0x1f, 0x76, 0xf8, 0xa0, 0xfb, + 0xff, 0x1f, 0x43, 0xfb, 0xff, 0x1b, 0xf8, 0xdf, 0xbd, 0xed, 0x9a, 0xbf, + 0xdf, 0x7d, 0xde, 0x1b, 0xe0, 0xdf, 0xb3, 0x93, 0x38, 0x93, 0xdf, 0x5d, + 0x9c, 0x1b, 0xe0, 0xcf, 0x33, 0x8b, 0xbf, 0xc4, 0xed, 0xf7, 0xbd, 0xa7, + 0xbd, 0x1b, 0xf8, 0xdf, 0xc5, 0xee, 0x9a, 0xbd, 0xff, 0x7e, 0xff, 0x1b, + 0xe0, 0xdf, 0x3f, 0x93, 0x9f, 0x5e, 0xfc, 0x1b, 0xfc, 0xdf, 0x9d, 0xb4, + 0xdc, 0x1b, 0xf8, 0xdf, 0xff, 0x1f, 0x5b, 0xfb, 0xe9, 0xee, 0x00, 0x1c, + 0x2a, 0x0a, 0xc6, 0xfb, 0x8e, 0xee, 0x9f, 0x7c, 0x9c, 0x1b, 0xe0, 0xcf, + 0x73, 0x8b, 0xdf, 0xcc, 0x35, 0x9b, 0xef, 0xf7, 0xb2, 0xee, 0x9f, 0x7d, + 0x9c, 0x1b, 0xe0, 0xdf, 0x9c, 0x13, 0x9f, 0xff, 0x9f, 0x5d, 0xfc, 0x1b, + 0xfc, 0xdf, 0x9d, 0xb4, 0xdc, 0x1b, 0xf8, 0xdf, 0xfc, 0xcd, 0xff, 0x1f, + 0x76, 0xfb, 0xf5, 0xee, 0x00, 0x1c, 0x45, 0x0a, 0xe1, 0xfb, 0xff, 0x1f, + 0x3a, 0xfb, 0xf7, 0xee, 0x00, 0x1c, 0x4b, 0x0a, 0xe7, 0xfb, 0x78, 0xee, + 0x91, 0xa3, 0xff, 0xcd, 0xbf, 0x5c, 0xe5, 0xa3, 0xff, 0x1f, 0x4b, 0xff, + 0xfe, 0xcc, 0x9e, 0x5b, 0xff, 0x1f, 0xeb, 0xf7, 0x7d, 0xee, 0xff, 0x1f, + 0x82, 0xf7, 0xff, 0xd3, 0xbf, 0xc3, 0x03, 0xf4, 0xfd, 0xcf, 0x00, 0x1c, + 0x62, 0x02, 0xe0, 0xef, 0x00, 0x1c, 0x63, 0x0a, 0xff, 0x1f, 0xbf, 0xfb, + 0xa2, 0xef, 0x9d, 0x7d, 0xff, 0xdc, 0x33, 0x8b, 0x9d, 0x5d, 0x5f, 0xcd, + 0x37, 0x9b, 0xef, 0xf7, 0xe9, 0xef, 0xfe, 0xcc, 0x9e, 0x5f, 0x91, 0xa7, + 0xff, 0xcd, 0xbd, 0x5c, 0xf9, 0xdf, 0xff, 0x1f, 0x6e, 0xff, 0xfd, 0xcf, + 0x00, 0x1c, 0x7b, 0x02, 0xeb, 0xef, 0x00, 0x1c, 0x7c, 0x0a, 0x5a, 0x1b, + 0xfe, 0xbf, 0xe8, 0x93, 0xfc, 0xeb, 0x6b, 0xeb, 0x99, 0xef, 0xff, 0xcd, + 0xbe, 0x5c, 0xbe, 0x74, 0xea, 0xd5, 0xbe, 0x54, 0xf1, 0xef, 0x00, 0x1c, + 0x8a, 0x0a, 0x94, 0xf8, 0xdb, 0x83, 0xff, 0xff, 0xb3, 0xff, 0xff, 0xdf, + 0xdf, 0x83, 0xff, 0xff, 0x0b, 0x83, 0xff, 0xff, 0xff, 0x82, 0xff, 0xff, + 0xf3, 0x82, 0xff, 0xff, 0xe7, 0x82, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xdf, + 0x5f, 0x79, 0xfe, 0xff, 0xd3, 0x82, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xdf, + 0xbb, 0x82, 0xff, 0xff, 0xab, 0x82, 0xff, 0xff, 0x2f, 0xeb, 0xf3, 0xef, + 0xff, 0x1f, 0x53, 0xfe, 0x94, 0xef, 0xf7, 0x5c, 0xbc, 0x1b, 0xf4, 0xff, + 0xdf, 0x7d, 0xde, 0x1b, 0x03, 0xdf, 0xde, 0x1b, 0xe3, 0xcf, 0xde, 0x1b, + 0xe3, 0xdf, 0xdf, 0x5d, 0xfa, 0xcd, 0xbf, 0x5c, 0xfe, 0xcd, 0xbe, 0x5c, + 0xff, 0xcd, 0xff, 0xd5, 0xb8, 0x5c, 0x6f, 0xeb, 0x37, 0x9b, 0xff, 0xff, + 0xbf, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xf7, 0x7c, 0xc3, 0x87, 0xff, 0xff, + 0xbf, 0xff, 0xff, 0xdf, 0x9c, 0xef, 0xbf, 0x6c, 0xff, 0xdd, 0xbf, 0x4c, + 0xc3, 0x87, 0xff, 0xff, 0xab, 0xff, 0xff, 0xdf, 0x3b, 0xeb, 0x3f, 0x8a, + 0xba, 0x8b, 0x76, 0x8b, 0xe9, 0xef, 0x7e, 0x7f, 0x00, 0xcf, 0xed, 0x9b, + 0xed, 0xf3, 0x6a, 0xef, 0xfe, 0xcf, 0x00, 0xc9, 0x5f, 0x7b, 0x69, 0x9a, + 0xf7, 0xf3, 0xff, 0xdf, 0xff, 0x8b, 0xf8, 0xdb, 0xb7, 0xc7, 0x06, 0xf4, + 0x00, 0xcf, 0xe5, 0xfb, 0x00, 0xcb, 0xfd, 0x9a, 0xfc, 0xf7, 0xe9, 0xfb, + 0xff, 0xcf, 0xbc, 0x92, 0x7c, 0xbf, 0x35, 0xef, 0x6f, 0xa1, 0x1e, 0x5b, + 0xde, 0x53, 0xbd, 0x53, 0xbe, 0xc4, 0xfd, 0xf3, 0xff, 0xcd, 0x97, 0xef, + 0x71, 0xa4, 0xdc, 0xba, 0xdb, 0xa3, 0xbc, 0x56, 0xbc, 0x27, 0xbb, 0xff, + 0xbf, 0x5e, 0xfc, 0x23, 0xbb, 0xff, 0x7b, 0xeb, 0xa7, 0xff, 0xff, 0xdf, + 0x9e, 0xff, 0xff, 0xdf, 0xab, 0xff, 0xff, 0xdf, 0x9f, 0x7f, 0x00, 0xcd, + 0x71, 0x9b, 0xf6, 0xf3, 0x9c, 0xbc, 0xba, 0xef, 0x93, 0xa5, 0xff, 0xcd, + 0xbe, 0x54, 0xff, 0xcc, 0xff, 0xd4, 0x9f, 0x5f, 0xc3, 0x87, 0xff, 0xff, + 0xa7, 0xff, 0xff, 0xdf, 0xff, 0x8b, 0xef, 0xc7, 0xed, 0xf7, 0x95, 0xef, + 0x9f, 0x7c, 0xbf, 0xc4, 0xf3, 0xf3, 0x97, 0xef, 0xfd, 0x6c, 0xde, 0x6f, + 0xdd, 0x4c, 0xbe, 0x6f, 0xdf, 0x6f, 0xdf, 0x4d, 0xbf, 0x7c, 0xff, 0xd5, + 0xbf, 0x5c, 0xfb, 0xfb, 0xff, 0xcf, 0xfd, 0xfb, 0xff, 0xcf, 0xc3, 0x87, + 0x63, 0xff, 0xff, 0xdf, 0x98, 0xef, 0xbe, 0x6c, 0xbe, 0x6d, 0xbe, 0x4f, + 0xbe, 0x6c, 0xbf, 0x4f, 0xbe, 0x6c, 0xfe, 0x4d, 0xfe, 0x4c, 0xbf, 0x7c, + 0xff, 0xdd, 0xbf, 0x5c, 0xc3, 0x87, 0xff, 0xff, 0x63, 0xff, 0xff, 0xdf, + 0x3c, 0xeb, 0xbf, 0x8a, 0xba, 0x8b, 0xb3, 0xef, 0xff, 0xcc, 0x70, 0x92, + 0xff, 0x6d, 0x7f, 0x7f, 0xad, 0x9a, 0xf5, 0xf7, 0x7e, 0x77, 0xad, 0x9b, + 0xf8, 0xf7, 0x98, 0xef, 0x3c, 0x3b, 0xb9, 0xf7, 0xff, 0xcc, 0x9f, 0x49, + 0xf9, 0xfb, 0xff, 0xdc, 0xfc, 0xdd, 0xba, 0xc4, 0x10, 0xf4, 0xff, 0xcf, + 0x7c, 0xeb, 0xff, 0xff, 0x57, 0xff, 0xff, 0xdf, 0x3c, 0xeb, 0xa1, 0xef, + 0x9d, 0x1b, 0xb8, 0xff, 0xd1, 0xa4, 0xde, 0x4c, 0xdd, 0x4c, 0xff, 0xce, + 0xdf, 0x5c, 0x9d, 0x1b, 0x98, 0xff, 0xbc, 0x1b, 0xc0, 0xff, 0x73, 0x9b, + 0xe9, 0xf7, 0x87, 0xef, 0x5c, 0x1b, 0xc0, 0xff, 0xff, 0xce, 0xe8, 0xef, + 0xef, 0xcb, 0x9f, 0x4c, 0x9e, 0x4c, 0xbe, 0x6f, 0x3e, 0x6d, 0x3e, 0x4c, + 0xbf, 0x4c, 0x9e, 0x4d, 0x9e, 0x4f, 0xff, 0xde, 0xbb, 0x8b, 0x8f, 0xa4, + 0xb1, 0x9a, 0x0b, 0xf4, 0x90, 0xef, 0xdf, 0x5c, 0x73, 0xef, 0xff, 0xcc, + 0xff, 0xd4, 0x9b, 0x23, 0xbb, 0xff, 0x8d, 0xa3, 0xbb, 0xdb, 0xff, 0xcf, + 0xff, 0xd7, 0xff, 0xce, 0xff, 0x5c, 0xad, 0xa4, 0xdf, 0x55, 0xf8, 0xdc, + 0xf1, 0x9a, 0x04, 0xf4, 0x98, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xbe, 0x4c, + 0xbd, 0x4c, 0xbc, 0x4c, 0xbb, 0x4c, 0x7c, 0xeb, 0xab, 0xff, 0xff, 0xdf, + 0x43, 0xff, 0xff, 0xdf, 0x63, 0xff, 0xff, 0xdf, 0x57, 0xff, 0xff, 0xdf, + 0xff, 0x8b, 0xba, 0x8b, 0xfb, 0xc7, 0xf8, 0xf7, 0x9b, 0xef, 0xfc, 0x3b, + 0xdf, 0xf7, 0x9f, 0x77, 0xb3, 0x93, 0xdf, 0x57, 0xc3, 0x87, 0xff, 0xff, + 0x03, 0xff, 0xff, 0xdf, 0x2b, 0xeb, 0xdd, 0xeb, 0x81, 0xee, 0x5c, 0x27, + 0xbb, 0xff, 0xbf, 0x6c, 0xdc, 0x27, 0xd2, 0xdf, 0xda, 0xa5, 0xdf, 0x47, + 0xbc, 0x23, 0xd2, 0xdf, 0xbf, 0xc6, 0xb4, 0xf3, 0x00, 0xcc, 0x29, 0x9b, + 0xb7, 0xf3, 0x00, 0xc8, 0xc9, 0xee, 0x71, 0xa6, 0xfc, 0xfb, 0x28, 0x92, + 0xb0, 0x92, 0x68, 0x92, 0x9c, 0xba, 0x93, 0xa3, 0x9d, 0x74, 0xbf, 0x67, + 0x37, 0x9b, 0xf8, 0xf7, 0xbc, 0xba, 0xb7, 0xa3, 0xbe, 0x75, 0xbf, 0xc5, + 0xea, 0xf3, 0xd5, 0xfb, 0x9c, 0xba, 0x93, 0xa3, 0xde, 0x74, 0xbf, 0xc6, + 0xf0, 0xf3, 0x9c, 0xba, 0x93, 0xa3, 0x9e, 0x47, 0xfe, 0x7c, 0x00, 0x1c, + 0x3a, 0x00, 0xde, 0x67, 0x9c, 0x76, 0xbf, 0xc4, 0xfa, 0xf3, 0xbc, 0xba, + 0xb7, 0xa3, 0x9d, 0x55, 0xe3, 0xfb, 0x00, 0xcd, 0x61, 0x9b, 0xf7, 0xf7, + 0x9c, 0xb9, 0x93, 0xa3, 0x9f, 0x7c, 0xde, 0xee, 0x9e, 0x23, 0xbb, 0xff, + 0xf8, 0xfb, 0x1c, 0xb8, 0x03, 0xa3, 0x9c, 0xb9, 0x93, 0xa3, 0x9f, 0x7c, + 0x9f, 0x58, 0x9c, 0xb9, 0x93, 0xa3, 0xff, 0xcd, 0xff, 0xd5, 0xbe, 0x5c, + 0xf9, 0xfb, 0xbc, 0xba, 0xb7, 0xa3, 0xdf, 0x67, 0x9a, 0xa4, 0x9d, 0x55, + 0x3c, 0xb9, 0x27, 0xa3, 0x9f, 0x79, 0x00, 0xcd, 0x71, 0x9b, 0x41, 0xf4, + 0xab, 0xef, 0xff, 0xcc, 0xdf, 0x75, 0xbf, 0xc6, 0xf8, 0xf7, 0xff, 0xdc, + 0x33, 0x8b, 0xfe, 0xdd, 0xba, 0xc4, 0x06, 0xf4, 0xe6, 0xfb, 0xfb, 0xc4, + 0xe8, 0xf7, 0x52, 0xef, 0x7a, 0x1b, 0x58, 0xff, 0x9b, 0x3b, 0xdb, 0xf7, + 0xff, 0x73, 0xff, 0xcd, 0xbf, 0x53, 0x9a, 0x23, 0x47, 0xff, 0x9a, 0x3b, + 0xbc, 0xf7, 0x9c, 0x27, 0xd0, 0xdf, 0x32, 0x84, 0xff, 0xcc, 0xff, 0xd4, + 0x9a, 0x23, 0x47, 0xff, 0x9f, 0x73, 0xf3, 0x93, 0xff, 0x53, 0xfd, 0xeb, + 0x6b, 0xeb, 0xff, 0xff, 0xab, 0xff, 0xff, 0xdf, 0x03, 0xff, 0xff, 0xdf, + 0x2f, 0xeb, 0x00, 0x1c, 0x82, 0x00, 0x01, 0xf8, 0x2e, 0xeb, 0x90, 0xef, + 0x9f, 0x6c, 0xbf, 0xc4, 0xf6, 0xf3, 0xb1, 0xef, 0xff, 0xcc, 0xff, 0xdc, + 0xf0, 0x92, 0xdf, 0x6d, 0xbf, 0xc6, 0xf1, 0xf7, 0xfd, 0xfb, 0xff, 0xcb, + 0x97, 0xef, 0x7c, 0x3b, 0xbb, 0xf7, 0xff, 0x4b, 0x9f, 0x7f, 0xde, 0x77, + 0xf0, 0x93, 0x00, 0x1c, 0xa8, 0x00, 0xfe, 0xcf, 0xfa, 0xfb, 0xfc, 0xdd, + 0xbb, 0xc4, 0x13, 0xf4, 0xff, 0xcf, 0x6e, 0xeb, 0x57, 0xff, 0xff, 0xdf, + 0x53, 0xff, 0xff, 0xdf, 0x3d, 0xeb, 0xbc, 0x92, 0x91, 0xef, 0x9f, 0x6c, + 0xbf, 0xc4, 0xf5, 0xf3, 0xb2, 0xef, 0xff, 0xcc, 0xfe, 0xcf, 0xff, 0xdc, + 0xf0, 0x92, 0xdf, 0x6d, 0xbf, 0xc6, 0xf6, 0xf7, 0xfc, 0xfb, 0xff, 0xcb, + 0xff, 0xcf, 0x98, 0xef, 0x7c, 0x3b, 0xbb, 0xf7, 0x5f, 0x4b, 0xf8, 0xfb, + 0xdd, 0xa7, 0xfb, 0x8b, 0xfc, 0xdd, 0xba, 0xc7, 0x10, 0xf4, 0x00, 0xcf, + 0x7d, 0xeb, 0xff, 0xff, 0xef, 0xfe, 0xff, 0xdf, 0xeb, 0xfe, 0xff, 0xdf, + 0x2b, 0xeb, 0xd8, 0xeb, 0xfe, 0x8b, 0xff, 0x47, 0x32, 0xc7, 0xef, 0xf3, + 0xa5, 0xed, 0xff, 0xcc, 0x9f, 0x5d, 0xfc, 0xdd, 0x93, 0x5d, 0x92, 0x5d, + 0x9f, 0x5d, 0x9c, 0x5d, 0x9b, 0x5d, 0x9d, 0x5d, 0x9e, 0x5d, 0x7f, 0xce, + 0xd9, 0xbe, 0xfa, 0x93, 0xff, 0x47, 0xbf, 0x67, 0x3f, 0xc5, 0x40, 0xf3, + 0xce, 0xed, 0xb1, 0xa6, 0x32, 0x7d, 0x9d, 0x6d, 0x9a, 0x47, 0x5d, 0xa4, + 0x59, 0x47, 0x93, 0x7d, 0x7e, 0x7d, 0xfd, 0x7d, 0x5c, 0x7d, 0x5e, 0x47, + 0x5b, 0x7d, 0x5b, 0x47, 0xd2, 0x6e, 0xdd, 0x47, 0xbf, 0x7d, 0xbc, 0x47, + 0x16, 0xed, 0x78, 0xfb, 0xb3, 0xa0, 0x51, 0x7d, 0xff, 0xdc, 0x9c, 0x1b, + 0xe0, 0xdf, 0xdc, 0xa3, 0xfd, 0xcd, 0xb7, 0x9b, 0x81, 0xf3, 0xbe, 0xc7, + 0xf0, 0xf3, 0xbf, 0xc7, 0xf9, 0xf3, 0xbd, 0xc7, 0xe2, 0xf3, 0xbc, 0xc7, + 0x89, 0xf7, 0xe1, 0xfb, 0xbf, 0xc2, 0x93, 0xf3, 0xff, 0xce, 0xdb, 0x47, + 0xde, 0x47, 0xff, 0xcb, 0x91, 0xfb, 0xdd, 0x67, 0xbf, 0x7e, 0xbe, 0xb5, + 0xbf, 0xc2, 0xff, 0x3b, 0xfe, 0xfa, 0xd8, 0xbe, 0x7b, 0x93, 0x5d, 0x67, + 0xbf, 0x5a, 0xde, 0x67, 0xbd, 0xa6, 0x77, 0x8b, 0xbe, 0x47, 0xb7, 0xc5, + 0xa1, 0xf7, 0xfd, 0xcf, 0xa3, 0xfb, 0xff, 0xcd, 0xbe, 0x47, 0xfc, 0xcf, + 0xa7, 0xfb, 0xbf, 0xc2, 0xae, 0xf3, 0xbe, 0xc3, 0xd4, 0xf7, 0x5d, 0x67, + 0xbf, 0x7a, 0xe0, 0xce, 0x7b, 0x9b, 0xe3, 0xf7, 0x81, 0xce, 0x7b, 0x9b, + 0xf7, 0xf3, 0xdd, 0x1b, 0xe0, 0xef, 0xdb, 0xae, 0xfe, 0xde, 0xbb, 0x8b, + 0xdc, 0x47, 0xeb, 0xfb, 0x21, 0xce, 0x7b, 0x9b, 0xf7, 0xf3, 0xdd, 0x1b, + 0x80, 0xef, 0xdc, 0xae, 0xf8, 0xde, 0xbb, 0x8b, 0xdc, 0x47, 0xf5, 0xfb, + 0xdd, 0x1b, 0x20, 0xef, 0xdd, 0xae, 0xec, 0xde, 0xbb, 0x8b, 0xdc, 0x47, + 0xfc, 0xfb, 0xfe, 0xcf, 0xfc, 0x47, 0xda, 0x67, 0xbf, 0x5e, 0x5c, 0x67, + 0xb9, 0xa2, 0xf9, 0x67, 0xbf, 0x5f, 0xfd, 0xcb, 0xe1, 0xfb, 0xbd, 0xc3, + 0xf6, 0xf7, 0xdc, 0x67, 0xbc, 0xa6, 0x77, 0x8b, 0xbc, 0x47, 0xbf, 0xc5, + 0xe9, 0xf7, 0xfc, 0xcb, 0xeb, 0xfb, 0xcb, 0xef, 0xb1, 0xa6, 0x93, 0x5d, + 0xff, 0xcc, 0x9d, 0x5d, 0x5d, 0x67, 0x52, 0x4e, 0xfc, 0x67, 0xff, 0x5d, + 0x9c, 0x5d, 0x9b, 0x5d, 0x9e, 0x5d, 0xf7, 0xcf, 0x00, 0x1c, 0xff, 0x01, + 0xfc, 0x92, 0xbf, 0xc7, 0xdb, 0xf7, 0xd2, 0xfb, 0xdd, 0x67, 0xff, 0xde, + 0xdd, 0x47, 0xff, 0xcf, 0xf7, 0xfb, 0xfe, 0xcf, 0xf9, 0xfb, 0xff, 0xcd, + 0xbb, 0x47, 0xbe, 0x47, 0xff, 0xcf, 0xff, 0xcb, 0x25, 0x9b, 0x86, 0xf4, + 0xdc, 0xef, 0xb1, 0xa6, 0x93, 0x5d, 0x7e, 0x5d, 0xf9, 0xfb, 0xff, 0xff, + 0xdb, 0xfe, 0xff, 0xdf, 0xd7, 0xfe, 0xff, 0xdf, 0xfd, 0x5d, 0x9e, 0x67, + 0x9c, 0x5d, 0x5b, 0x67, 0x5b, 0x5d, 0xfd, 0x67, 0xf2, 0x4e, 0xdc, 0x67, + 0xdf, 0x5d, 0xf4, 0xfb, 0x96, 0xef, 0x9e, 0x57, 0x00, 0x1c, 0x7d, 0x02, + 0xff, 0x5b, 0xb7, 0xef, 0xbe, 0x4b, 0xec, 0x93, 0x00, 0x1c, 0x13, 0x01, + 0x9f, 0x67, 0x9c, 0x1b, 0xfe, 0xbf, 0x9f, 0x47, 0xff, 0x67, 0xf8, 0xeb, + 0x6b, 0xeb, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xa3, 0xfe, 0xff, 0xdf, + 0x2e, 0xeb, 0x73, 0xef, 0x9b, 0x1b, 0xc8, 0xff, 0x9c, 0x4b, 0xf4, 0xef, + 0x00, 0x1c, 0x05, 0x01, 0xbc, 0x93, 0xfb, 0x23, 0xb7, 0xff, 0x00, 0xcc, + 0x3d, 0x9b, 0xfb, 0xf3, 0xf8, 0xef, 0x00, 0x1c, 0x64, 0x0d, 0xf8, 0xef, + 0x46, 0xce, 0xdd, 0xbe, 0xff, 0xcd, 0xff, 0x1f, 0xee, 0xfa, 0x6e, 0xeb, + 0xdb, 0xfe, 0xff, 0xdf, 0x7b, 0x92, 0xff, 0xff, 0x9f, 0x82, 0xff, 0xff, + 0xff, 0xef, 0xff, 0xbf, 0x96, 0xef, 0xbf, 0x6c, 0x76, 0xc5, 0xbf, 0x4c, + 0xbd, 0x6c, 0x9e, 0x6c, 0xb8, 0xef, 0xff, 0xcc, 0x9f, 0x5d, 0xfc, 0xdd, + 0x93, 0x5d, 0x92, 0x5d, 0x9f, 0x5d, 0x9c, 0x5d, 0x9b, 0x5d, 0x9d, 0x5d, + 0x9e, 0x5d, 0xc3, 0x87, 0xff, 0xef, 0xff, 0xbf, 0xdb, 0xfe, 0xff, 0xdf, + 0x2e, 0xeb, 0x8a, 0xed, 0xbf, 0x6c, 0x76, 0xc5, 0xbf, 0x4c, 0xdd, 0x6c, + 0xbe, 0x6c, 0xb6, 0xa6, 0xdd, 0x6c, 0xde, 0x4c, 0xdf, 0x6c, 0x56, 0xc6, + 0xdf, 0x4c, 0xb6, 0xcc, 0x73, 0x9b, 0xf2, 0xf3, 0xb1, 0xed, 0xff, 0xcc, + 0x9f, 0x5d, 0xfc, 0xdd, 0x93, 0x5d, 0x92, 0x5d, 0x9f, 0x5d, 0x9c, 0x5d, + 0x9b, 0x5d, 0x9d, 0x5d, 0x9e, 0x5d, 0x72, 0xfb, 0x75, 0xcc, 0x9e, 0xbc, + 0x73, 0x9b, 0xee, 0xf7, 0xfc, 0x15, 0xb0, 0xfd, 0x73, 0x9b, 0xf0, 0xf7, + 0xbb, 0xed, 0xff, 0xcc, 0x9f, 0x5d, 0xfc, 0xdd, 0x93, 0x5d, 0x92, 0x5d, + 0x9f, 0x5d, 0x9c, 0x5d, 0x9b, 0x5d, 0x9d, 0x5d, 0x9e, 0x5d, 0x86, 0xfb, + 0xfe, 0xcc, 0xfd, 0xfb, 0xff, 0xcc, 0xa1, 0xee, 0xbe, 0x7d, 0xbf, 0xc5, + 0xde, 0xf7, 0xbf, 0xc4, 0xf3, 0xf3, 0xa4, 0xee, 0x9b, 0x7d, 0xff, 0xdc, + 0x33, 0x8b, 0x9b, 0x5d, 0xeb, 0xcd, 0x37, 0x9b, 0x97, 0xf7, 0x88, 0xee, + 0xbb, 0x5c, 0x9a, 0xfb, 0x8a, 0xee, 0xbb, 0x7c, 0xfa, 0xcc, 0x73, 0x9b, + 0xf4, 0xf7, 0x8d, 0xee, 0xb1, 0xa4, 0xdd, 0x6d, 0xfe, 0xde, 0xd2, 0x4c, + 0xfe, 0xce, 0xdd, 0x5d, 0xde, 0x5d, 0xff, 0xcd, 0xbf, 0x5c, 0xff, 0xcd, + 0x92, 0xee, 0xbb, 0x5c, 0xad, 0xfb, 0xb4, 0xee, 0xbf, 0x7d, 0xbf, 0xc5, + 0xf5, 0xf7, 0xbf, 0xc4, 0xfa, 0xf7, 0x97, 0xee, 0xbf, 0x5c, 0xff, 0xcc, + 0xc0, 0xfb, 0xb9, 0xee, 0x9f, 0x5d, 0xba, 0xfb, 0xbe, 0xc5, 0xf0, 0xf7, + 0xbc, 0xa4, 0xbf, 0xc5, 0xfa, 0xf7, 0x9d, 0xee, 0xbf, 0x5c, 0xfe, 0xcc, + 0xcc, 0xfb, 0xbf, 0xc4, 0xc5, 0xf7, 0xff, 0xcd, 0x81, 0xef, 0xbf, 0x5c, + 0xfe, 0xcc, 0xd3, 0xfb, 0xbd, 0xc5, 0xcc, 0xf7, 0xbf, 0xc4, 0xea, 0xf7, + 0x85, 0xef, 0xff, 0xcd, 0xbf, 0x5c, 0xfc, 0xdc, 0xd2, 0x7c, 0xf3, 0xcf, + 0x7b, 0xa4, 0x7f, 0xa3, 0xbd, 0x5b, 0xff, 0xde, 0xde, 0x1b, 0xe0, 0xdf, + 0x7b, 0xa4, 0xff, 0xa3, 0xbd, 0x5f, 0xbd, 0xa6, 0xbd, 0x1b, 0xe0, 0xdf, + 0xb2, 0x5c, 0xf2, 0xfb, 0xbe, 0xc4, 0xf9, 0xf7, 0xff, 0xcd, 0x90, 0xef, + 0xbf, 0x5c, 0xfe, 0xcc, 0xf2, 0xfb, 0xfe, 0xcd, 0x93, 0xef, 0xbf, 0x5c, + 0xff, 0xcc, 0xf7, 0xfb, 0x95, 0xef, 0xfc, 0x27, 0xb7, 0xff, 0xfe, 0xce, + 0x00, 0x1c, 0x87, 0x02, 0xf5, 0xfb, 0xb7, 0xef, 0xd2, 0x7d, 0xfb, 0xa5, + 0x91, 0x5f, 0x9d, 0xa6, 0x9c, 0x1b, 0xe0, 0xdf, 0x92, 0x5d, 0x0e, 0xf8, + 0x6e, 0xeb, 0xff, 0xff, 0xff, 0xef, 0xff, 0xbf, 0xdb, 0xfe, 0xff, 0xdf, + 0xd7, 0xfe, 0xff, 0xdf, 0x9d, 0xef, 0xff, 0x54, 0xc3, 0x87, 0xff, 0xff, + 0x91, 0xfe, 0xff, 0xdf, 0x99, 0xef, 0xfb, 0x6c, 0xff, 0x1b, 0x00, 0xdc, + 0xd8, 0xdf, 0x9a, 0xef, 0x9f, 0x74, 0xf3, 0x9b, 0xfc, 0xf7, 0xf2, 0xa7, + 0xfe, 0x8b, 0xc3, 0x87, 0xff, 0x7f, 0xff, 0xbf, 0x91, 0xfe, 0xff, 0xdf, + 0x9c, 0xef, 0xfb, 0x6c, 0xff, 0x1b, 0x00, 0xdc, 0xc3, 0x87, 0xff, 0xff, + 0xff, 0x7f, 0xff, 0xbf, 0x9a, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xfc, 0x93, + 0xfc, 0x93, 0xbd, 0x1b, 0x34, 0xf8, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, + 0xff, 0x7f, 0xff, 0xbf, 0x2f, 0xeb, 0x00, 0x1c, 0x0c, 0x00, 0x6f, 0xeb, + 0xff, 0x8b, 0x92, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xfc, 0x93, 0xfc, 0x93, + 0xfc, 0x93, 0xfd, 0xbf, 0xbf, 0x13, 0x7f, 0xf8, 0xbf, 0x4c, 0xfc, 0x93, + 0xb0, 0x93, 0xfe, 0xcd, 0x9f, 0x6e, 0x71, 0x97, 0x01, 0xf0, 0x99, 0xef, + 0xf3, 0xa7, 0xff, 0x6f, 0xff, 0x1b, 0x00, 0xdc, 0x9d, 0xef, 0xff, 0xcd, + 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0x7f, 0xff, 0xbf, 0xfb, 0x7f, 0xff, 0xbf, + 0x91, 0xef, 0xbc, 0x6c, 0x50, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, 0x79, 0xc5, + 0x78, 0xc5, 0xbc, 0x4c, 0xdc, 0x6c, 0xcc, 0xb6, 0xcc, 0xbe, 0xbc, 0x6c, + 0xb2, 0xbd, 0xb2, 0xb5, 0x7b, 0x93, 0xbc, 0x4c, 0xbc, 0x6c, 0x53, 0xc5, + 0xbc, 0x4c, 0xbc, 0x6c, 0x72, 0xc5, 0x71, 0xc5, 0x52, 0xc5, 0xbc, 0x4c, + 0xbf, 0x6c, 0x7e, 0xc5, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, + 0x97, 0xef, 0xbc, 0x6c, 0x70, 0xc5, 0xbc, 0x4c, 0xfc, 0x93, 0xfc, 0x93, + 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, + 0xbc, 0x6c, 0x50, 0xc5, 0xbc, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, + 0x9a, 0xef, 0xbf, 0x1b, 0xfc, 0xdf, 0xb9, 0xbd, 0xfc, 0x6c, 0x79, 0xc7, + 0x78, 0xc7, 0xf7, 0x93, 0xfc, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, + 0x9c, 0xef, 0xfc, 0x6c, 0xe6, 0xb7, 0xff, 0x1b, 0xfc, 0xdf, 0xc3, 0x87, + 0xff, 0x5f, 0xff, 0xbf, 0x3d, 0xeb, 0xff, 0x8b, 0xbb, 0x8b, 0x77, 0x8b, + 0x81, 0xef, 0x5c, 0x6c, 0x4c, 0xb2, 0x5a, 0x1b, 0x00, 0xd8, 0x4c, 0xba, + 0x7c, 0x6c, 0x72, 0xbb, 0x72, 0xb3, 0xeb, 0x92, 0x7c, 0x4c, 0x5c, 0x6c, + 0x4c, 0xb2, 0x74, 0xbf, 0xeb, 0x92, 0x6c, 0xbb, 0xfc, 0x6c, 0xf2, 0xbf, + 0xf2, 0xb7, 0xef, 0x93, 0xfc, 0x4c, 0x7c, 0x6c, 0xdf, 0x15, 0x07, 0x38, + 0xff, 0x96, 0xfc, 0x6c, 0xf2, 0xbf, 0xf2, 0xb7, 0xef, 0x93, 0xfc, 0x4c, + 0x7c, 0x6c, 0x6c, 0xb3, 0xf7, 0xbe, 0xef, 0x93, 0xec, 0xbf, 0xdc, 0x6c, + 0xd2, 0xbe, 0xd2, 0xb6, 0xbf, 0x93, 0xdc, 0x4c, 0xfc, 0x6c, 0xde, 0x15, + 0x07, 0x06, 0xfb, 0x97, 0xdc, 0x6c, 0xd2, 0xbe, 0xd2, 0xb6, 0xbf, 0x93, + 0xdc, 0x4c, 0xfc, 0x6c, 0xec, 0xb7, 0xd9, 0xbd, 0xbf, 0x93, 0xcc, 0xbe, + 0xbc, 0x6c, 0xb2, 0xbd, 0xb2, 0xb5, 0x7b, 0x93, 0xbc, 0x4c, 0x7d, 0xeb, + 0xff, 0x5f, 0xff, 0xbf, 0x94, 0xef, 0x9c, 0x6c, 0x9c, 0x1b, 0x3f, 0xdf, + 0xbf, 0xc4, 0xf6, 0xf7, 0x97, 0xef, 0xbc, 0x6c, 0x79, 0xc5, 0x78, 0xc5, + 0x59, 0xc5, 0xbc, 0x4c, 0xfe, 0xcf, 0xf8, 0xfb, 0x9b, 0xef, 0xbc, 0x6c, + 0x79, 0xc5, 0x78, 0xc5, 0xbc, 0x4c, 0xff, 0xcf, 0xc3, 0x87, 0xff, 0xff, + 0xff, 0x5f, 0xff, 0xbf, 0x98, 0xef, 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, + 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, + 0xbf, 0x6c, 0x7e, 0xc5, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, + 0xff, 0x8b, 0x9a, 0xef, 0xbe, 0x6c, 0xfe, 0xce, 0xfe, 0x3b, 0xdf, 0xbf, + 0xf7, 0x93, 0xfe, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xbf, + 0xff, 0x8b, 0xba, 0xef, 0xde, 0x6d, 0xff, 0xcc, 0xfe, 0xd4, 0x3c, 0x8f, + 0x3b, 0x97, 0x9e, 0x4d, 0xc3, 0x87, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xbf, + 0xff, 0x8b, 0x95, 0xef, 0x9e, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, + 0x3d, 0x97, 0xf8, 0xf3, 0x99, 0xef, 0xbe, 0x6c, 0xfd, 0x3b, 0xbf, 0xdf, + 0xfe, 0x4c, 0xfa, 0xfb, 0x9c, 0xef, 0xbe, 0x6c, 0xf7, 0x93, 0xfe, 0x4c, + 0xc3, 0x87, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xbf, 0xff, 0x8b, 0x97, 0xef, + 0xbd, 0x6c, 0xfe, 0xce, 0xfe, 0x3b, 0xdf, 0xbf, 0x7f, 0x93, 0xbd, 0x4c, + 0xbf, 0x6c, 0xfd, 0x93, 0x7f, 0x97, 0xbf, 0x4c, 0xbc, 0x6c, 0xf7, 0x97, + 0xfc, 0x4c, 0xc3, 0x87, 0xff, 0xaf, 0xff, 0xbf, 0x2f, 0xeb, 0x8c, 0xef, + 0xdc, 0x6c, 0xde, 0xb6, 0xde, 0x1b, 0xe0, 0xdf, 0x5f, 0xc6, 0xde, 0xbe, + 0xbc, 0x6c, 0xbd, 0x1b, 0xc1, 0xcf, 0x7b, 0x93, 0xbc, 0x4c, 0xff, 0xcf, + 0x00, 0x1c, 0x1f, 0x00, 0xff, 0xcf, 0x00, 0x1c, 0x50, 0x00, 0xfe, 0xcf, + 0x00, 0x1c, 0x25, 0x00, 0xfe, 0xcf, 0x00, 0x1c, 0x56, 0x00, 0xfa, 0xcf, + 0x00, 0x1c, 0x2b, 0x00, 0xfc, 0xcf, 0x00, 0x1c, 0x2e, 0x00, 0xfc, 0xcf, + 0x00, 0x1c, 0x53, 0x00, 0xfb, 0xcf, 0x00, 0x1c, 0x34, 0x00, 0x6f, 0xeb, + 0xff, 0x5f, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, 0x93, 0xef, 0xb2, 0xef, + 0xbf, 0x4c, 0x92, 0xef, 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, + 0x5f, 0xc5, 0xbd, 0x4c, 0xfd, 0xcd, 0xbf, 0x4c, 0xb6, 0xef, 0xfd, 0xce, + 0xad, 0xcc, 0x9e, 0x4d, 0x9f, 0x6d, 0xb1, 0x97, 0x01, 0xf0, 0x9f, 0x6d, + 0x7e, 0xc4, 0x9f, 0x4d, 0x07, 0xf8, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xbf, + 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xcf, 0xff, 0xbf, + 0x9f, 0xeb, 0x9d, 0xeb, 0x93, 0xef, 0xb2, 0xef, 0xbf, 0x4c, 0x92, 0xef, + 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0x5f, 0xc5, 0xbd, 0x4c, + 0xfd, 0xcd, 0xbf, 0x4c, 0xb6, 0xef, 0xfd, 0xce, 0xb4, 0xcc, 0x9e, 0x4d, + 0x9f, 0x6d, 0xb1, 0x97, 0x01, 0xf0, 0x9f, 0x6d, 0x7e, 0xc4, 0x9f, 0x4d, + 0x07, 0xf8, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xbf, 0xae, 0x1a, 0x33, 0xe5, + 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xcf, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, + 0x93, 0xef, 0xb2, 0xef, 0xbf, 0x4c, 0x92, 0xef, 0xbd, 0x6c, 0x5e, 0xc5, + 0xbd, 0x4c, 0xbd, 0x6c, 0x5f, 0xc5, 0xbd, 0x4c, 0xfd, 0xcd, 0xbf, 0x4c, + 0xb6, 0xef, 0xfd, 0xce, 0xba, 0xcc, 0x9e, 0x4d, 0x9f, 0x6d, 0xb1, 0x97, + 0x01, 0xf0, 0x9f, 0x6d, 0x7e, 0xc4, 0x9f, 0x4d, 0x07, 0xf8, 0xff, 0xff, + 0xff, 0xbb, 0xff, 0xbf, 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, + 0xff, 0xcf, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, + 0x3c, 0x05, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, 0xbc, 0x09, 0x11, 0x26, + 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, 0x7c, 0x08, 0x11, 0x26, + 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x2f, 0xeb, 0x00, 0x1c, 0xc2, 0x02, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, + 0x16, 0x0d, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x96, 0xef, 0x9f, 0x6c, 0x3b, 0xc4, + 0xfa, 0xf7, 0x98, 0xef, 0x9f, 0x6c, 0x3f, 0xc4, 0xfa, 0xf3, 0xff, 0xcf, + 0xfd, 0xce, 0x00, 0x1c, 0x2a, 0x0d, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0xff, 0x5f, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0xff, 0xcf, 0x00, 0x1c, 0x2f, 0x01, + 0x00, 0x1c, 0xf3, 0x02, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, + 0x9e, 0xeb, 0xff, 0xff, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x2f, 0xeb, 0xff, 0x8b, + 0x00, 0x1c, 0xf3, 0x0f, 0x6f, 0xeb, 0xff, 0xff, 0x2f, 0xeb, 0xff, 0x8b, + 0x00, 0x1c, 0xef, 0x0f, 0x6f, 0xeb, 0xff, 0xff, 0x2f, 0xeb, 0x00, 0x1c, + 0x38, 0x10, 0x00, 0x1c, 0x04, 0x10, 0x83, 0xef, 0xb8, 0x6c, 0x5f, 0xc5, + 0xb8, 0x4c, 0xf9, 0xcf, 0x00, 0x1c, 0x07, 0x10, 0xf9, 0xcf, 0xff, 0xce, + 0x00, 0x1c, 0xf7, 0x0f, 0xf6, 0xcf, 0x00, 0x1c, 0x0e, 0x10, 0xf6, 0xcf, + 0xff, 0xce, 0x00, 0x1c, 0xfe, 0x0f, 0xf7, 0xcf, 0x00, 0x1c, 0x15, 0x10, + 0xf7, 0xcf, 0xff, 0xce, 0x00, 0x1c, 0x05, 0x10, 0xee, 0xcf, 0x00, 0x1c, + 0x1c, 0x10, 0xee, 0xcf, 0xff, 0xce, 0x00, 0x1c, 0x0c, 0x10, 0xfe, 0xcf, + 0x00, 0x1c, 0x23, 0x10, 0xfe, 0xcf, 0xff, 0xce, 0x00, 0x1c, 0x13, 0x10, + 0xfd, 0xcf, 0x00, 0x1c, 0x2a, 0x10, 0xfd, 0xcf, 0xfc, 0xce, 0x00, 0x1c, + 0x1a, 0x10, 0xff, 0xcf, 0x00, 0x1c, 0x31, 0x10, 0xff, 0xcf, 0xfd, 0xce, + 0x00, 0x1c, 0x21, 0x10, 0x6f, 0xeb, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xbf, + 0x2e, 0xeb, 0x89, 0xee, 0xbb, 0x6c, 0x7f, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, + 0x7c, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, 0x7b, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, + 0x7a, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, 0x58, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, + 0x79, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, 0xb3, 0xbd, 0xb3, 0xb5, 0xde, 0x15, + 0x4f, 0xdc, 0x7b, 0x93, 0xbb, 0x4c, 0xbb, 0x6c, 0xd6, 0xee, 0x7b, 0x97, + 0xd6, 0xee, 0x7b, 0x93, 0xbb, 0x4c, 0xbc, 0x6c, 0x4d, 0xc5, 0xbc, 0x4c, + 0xbc, 0x6c, 0x50, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, 0x4f, 0xc5, 0x4e, 0xc5, + 0xbc, 0x4c, 0xbc, 0x6c, 0x5f, 0xc5, 0xbc, 0x4c, 0xbe, 0x6c, 0x50, 0xc5, + 0xbe, 0x4c, 0xbd, 0x6c, 0x45, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0x43, 0xc5, + 0xbd, 0x4c, 0xff, 0xcc, 0xff, 0xdc, 0xaf, 0xc4, 0x01, 0xf4, 0xff, 0xcc, + 0xff, 0xd4, 0xa4, 0xef, 0x9f, 0x5d, 0x88, 0xef, 0xbd, 0x6c, 0x0f, 0xce, + 0xcf, 0xbe, 0x7b, 0x93, 0xbd, 0x4c, 0xbc, 0x6c, 0x57, 0xc5, 0xbc, 0x4c, + 0x00, 0x1c, 0xdf, 0x02, 0xff, 0xcc, 0xfd, 0x15, 0xfe, 0xfb, 0xff, 0xdc, + 0x71, 0x9b, 0x01, 0xf4, 0x6e, 0xef, 0xff, 0xcc, 0xff, 0xd4, 0x9e, 0x53, + 0x00, 0x1c, 0xf3, 0x02, 0xfd, 0x53, 0x00, 0x1c, 0x0c, 0x03, 0x95, 0xef, + 0xbc, 0x6c, 0x77, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, 0x7f, 0xc5, 0xbc, 0x4c, + 0xbd, 0x6c, 0x65, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0xd7, 0xef, 0x7b, 0x97, + 0xbd, 0x4c, 0xbb, 0x6c, 0x78, 0xc5, 0xbb, 0x4c, 0x6e, 0xeb, 0xff, 0xff, + 0xff, 0x5f, 0xff, 0xbf, 0x00, 0xff, 0x0f, 0x00, 0xff, 0xe2, 0xfe, 0xff, + 0x8f, 0xfe, 0xff, 0xdf, 0x00, 0x00, 0xf0, 0x00, 0x9d, 0xef, 0xfd, 0x74, + 0xc3, 0x87, 0xff, 0xff, 0x8f, 0xfe, 0xff, 0xdf, 0xfe, 0x8b, 0x95, 0xef, + 0xbb, 0x6c, 0xab, 0xb5, 0xd6, 0xef, 0xfe, 0x56, 0xd9, 0xbd, 0xb7, 0xa6, + 0xf7, 0x83, 0xef, 0xaf, 0xff, 0x1b, 0x00, 0xd0, 0xf7, 0xbf, 0xbb, 0x6c, + 0xda, 0xef, 0x7b, 0x97, 0x7f, 0x93, 0xbb, 0x4c, 0xc3, 0x87, 0xff, 0xff, + 0xff, 0x5f, 0xff, 0xbf, 0x8f, 0xfe, 0xff, 0xdf, 0x00, 0xff, 0x0f, 0x00, + 0x9d, 0xef, 0xfe, 0x74, 0xc3, 0x87, 0xff, 0xff, 0x8f, 0xfe, 0xff, 0xdf, + 0x2e, 0xeb, 0xfe, 0x8a, 0xff, 0x1f, 0xa9, 0xfe, 0xbe, 0xc7, 0xf2, 0xf7, + 0xfc, 0x15, 0x58, 0xfd, 0xf3, 0x9a, 0xea, 0xf7, 0x6c, 0x93, 0x41, 0xdc, + 0xf3, 0x9a, 0xfc, 0xf7, 0xfd, 0x15, 0x99, 0xfc, 0x76, 0x8b, 0xed, 0xfb, + 0xfc, 0x15, 0xd4, 0xfd, 0xf3, 0x9a, 0xf3, 0xf7, 0x6c, 0x93, 0x2a, 0xdc, + 0xf3, 0x9a, 0xfc, 0xf7, 0xfd, 0x15, 0xfe, 0xfc, 0x76, 0x8b, 0xf9, 0xfb, + 0x55, 0xcd, 0xbd, 0xbd, 0xfc, 0xfb, 0x74, 0xcd, 0xbd, 0xbd, 0x93, 0xef, + 0xeb, 0xbd, 0xdb, 0x6c, 0xd3, 0xbe, 0xd3, 0xb6, 0xbf, 0x93, 0xdb, 0x4c, + 0xd6, 0xef, 0xde, 0x76, 0xf9, 0xbe, 0xdb, 0xa7, 0xb7, 0x83, 0xcf, 0xae, + 0xde, 0x1b, 0x00, 0xd0, 0xd7, 0xbe, 0xbb, 0x6c, 0xfa, 0xef, 0x7f, 0x97, + 0x7b, 0x93, 0xbb, 0x4c, 0x6e, 0xeb, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xbf, + 0x8f, 0xfe, 0xff, 0xdf, 0x00, 0xff, 0x0f, 0x00, 0x9d, 0xef, 0xfb, 0x6c, + 0xeb, 0xb7, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, 0xbf, 0xc7, 0xf6, 0xf7, + 0x97, 0xef, 0xbb, 0x6c, 0x7a, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, 0x7f, 0xc5, + 0xbb, 0x4c, 0xf7, 0xfb, 0x9b, 0xef, 0xbb, 0x6c, 0x5a, 0xc5, 0xbb, 0x4c, + 0xbb, 0x6c, 0x7f, 0xc5, 0xbb, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, + 0x2b, 0xeb, 0xde, 0xeb, 0xbf, 0x47, 0x30, 0x92, 0x7e, 0x8a, 0xba, 0x8a, + 0xff, 0x1f, 0x07, 0xff, 0xbe, 0xc7, 0xf2, 0xf7, 0xfc, 0x15, 0x58, 0xfd, + 0x73, 0x9a, 0xea, 0xf7, 0xe4, 0x92, 0x41, 0xdc, 0x73, 0x9a, 0xfc, 0xf7, + 0xfb, 0x15, 0x99, 0xfc, 0xee, 0x8a, 0xed, 0xfb, 0xfc, 0x15, 0xd4, 0xfd, + 0x73, 0x9a, 0xf3, 0xf7, 0xe4, 0x92, 0x2a, 0xdc, 0x73, 0x9a, 0xfc, 0xf7, + 0xfb, 0x15, 0xfe, 0xfc, 0xee, 0x8a, 0xf9, 0xfb, 0x55, 0xcb, 0x7d, 0xbb, + 0xfc, 0xfb, 0x74, 0xcb, 0x7d, 0xbb, 0x93, 0xee, 0x5e, 0x54, 0x93, 0xee, + 0x9d, 0x6c, 0x25, 0xc4, 0xd6, 0xf7, 0xbf, 0xc0, 0xd8, 0xf3, 0xfe, 0xcf, + 0x00, 0x1c, 0x43, 0x00, 0x98, 0xee, 0xcb, 0xbb, 0xbb, 0x6c, 0xb3, 0xbd, + 0xb3, 0xb5, 0x7b, 0x93, 0xbb, 0x4c, 0x7b, 0x3b, 0xbd, 0xf7, 0xd9, 0xbd, + 0xdb, 0xa5, 0xcf, 0xb6, 0xd7, 0xbe, 0xbb, 0x6c, 0xfe, 0xee, 0x7f, 0x97, + 0x7b, 0x93, 0xbb, 0x4c, 0xbb, 0x6c, 0x58, 0xc5, 0xbb, 0x4c, 0xbc, 0x6c, + 0x5f, 0xc5, 0xbc, 0x4c, 0xbd, 0x6c, 0x45, 0xc5, 0xbd, 0x4c, 0xff, 0xcc, + 0xff, 0xdc, 0xbb, 0xc4, 0x01, 0xf4, 0xff, 0xcc, 0xff, 0xd4, 0xa9, 0xef, + 0x9f, 0x5d, 0x89, 0xef, 0xcb, 0xbb, 0xbb, 0x6c, 0xb3, 0xbd, 0xb3, 0xb5, + 0x7b, 0x93, 0xbb, 0x4c, 0xb9, 0xba, 0x4b, 0xa5, 0xeb, 0x82, 0x6f, 0xab, + 0x7b, 0x1b, 0x00, 0xd0, 0x77, 0xbb, 0xbb, 0x6c, 0xd0, 0xef, 0x7b, 0x97, + 0x6f, 0x93, 0xbb, 0x4c, 0xbe, 0xc0, 0x7c, 0x9b, 0xf8, 0xbd, 0xdb, 0x6c, + 0x78, 0xc6, 0xbf, 0x93, 0xdb, 0x4c, 0xdc, 0x6c, 0x7f, 0xc6, 0xb7, 0x93, + 0xdc, 0x4c, 0xa5, 0xbd, 0xdd, 0x6c, 0x65, 0xc6, 0x7b, 0x93, 0xbd, 0x4c, + 0xff, 0x67, 0x00, 0x1c, 0x8c, 0x00, 0xfe, 0xeb, 0x6b, 0xeb, 0xff, 0xff, + 0x8f, 0xfe, 0xff, 0xdf, 0xff, 0x5f, 0xff, 0xbf, 0x00, 0xff, 0x0f, 0x00, + 0x98, 0xef, 0xbc, 0x6c, 0x7f, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, 0x77, 0xc5, + 0xbc, 0x4c, 0xbd, 0x6c, 0x65, 0xc5, 0xbd, 0x4c, 0xbb, 0x6c, 0x78, 0xc5, + 0xbb, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, 0xde, 0x4f, 0xdd, 0x4f, + 0x9f, 0x6f, 0x9c, 0x1b, 0xe0, 0xcf, 0x5e, 0xc4, 0x9f, 0x4f, 0x9f, 0x6f, + 0x78, 0xc4, 0x77, 0xc4, 0x9f, 0x4f, 0x9f, 0x6f, 0x59, 0xc4, 0x9f, 0x4f, + 0xbe, 0xc5, 0x7c, 0x9b, 0xba, 0xbd, 0x9f, 0x6f, 0x7a, 0xc4, 0x37, 0x93, + 0x9f, 0x4f, 0x9f, 0x6f, 0x76, 0xc4, 0x9f, 0x4f, 0xc3, 0x87, 0xff, 0xff, + 0x97, 0xef, 0xb7, 0x6c, 0x5f, 0xc5, 0xb7, 0x4c, 0x98, 0xef, 0xbf, 0x6c, + 0x59, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x5b, 0xc5, 0xbf, 0x4c, 0x01, 0xcd, + 0xb9, 0x4c, 0x00, 0xcd, 0xb8, 0x4c, 0xc3, 0x87, 0xff, 0xaf, 0xff, 0xbf, + 0xff, 0xcf, 0xff, 0xbf, 0x3e, 0xeb, 0xff, 0x8b, 0x95, 0xef, 0xfe, 0x4c, + 0xff, 0xcc, 0xf6, 0xef, 0xfd, 0xce, 0xfb, 0x15, 0xae, 0x3c, 0xfb, 0xfb, + 0xff, 0xdc, 0xf1, 0x9a, 0xfb, 0xf3, 0xbf, 0x6f, 0xb5, 0x97, 0x04, 0xf0, + 0x9c, 0xef, 0xbf, 0x6c, 0x7e, 0xc5, 0xbf, 0x4c, 0x7e, 0xeb, 0xff, 0xff, + 0xff, 0xcf, 0xff, 0xbf, 0x98, 0xef, 0xb7, 0xef, 0xbf, 0x4c, 0x97, 0xef, + 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0x5f, 0xc5, 0xbd, 0x4c, + 0xba, 0xef, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xbf, + 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, 0x3f, 0x04, 0xc6, 0xff, + 0x9d, 0xef, 0xbc, 0xef, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xbf, 0xff, 0xbf, + 0x3f, 0x04, 0xc6, 0xff, 0x9d, 0xef, 0xff, 0x5c, 0xc3, 0x87, 0xff, 0xff, + 0x89, 0xfe, 0xff, 0xdf, 0x9d, 0xef, 0xff, 0x7c, 0xc3, 0x87, 0xff, 0xff, + 0x89, 0xfe, 0xff, 0xdf, 0x9d, 0xef, 0xff, 0x5c, 0xc3, 0x87, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xff, 0x7c, 0xc3, 0x87, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xfe, 0x7c, 0xc3, 0x87, 0xff, 0xff, + 0x89, 0xfe, 0xff, 0xdf, 0x9d, 0xef, 0xfd, 0x7c, 0xc3, 0x87, 0xff, 0xff, + 0x89, 0xfe, 0xff, 0xdf, 0x2c, 0xeb, 0x9f, 0xee, 0xbf, 0x6c, 0xdf, 0x6c, + 0x7f, 0x6c, 0x5f, 0x6c, 0x3e, 0x6c, 0x37, 0x8b, 0xac, 0xc4, 0xd7, 0xf7, + 0xfe, 0x3b, 0x7e, 0x8f, 0xfd, 0xc6, 0xe0, 0xf7, 0xfb, 0x3b, 0xbb, 0x8f, + 0xe7, 0xc3, 0xe4, 0xf7, 0xbf, 0xc7, 0xec, 0xf3, 0x67, 0x8a, 0x88, 0xef, + 0xdf, 0x5c, 0x47, 0xb2, 0x5e, 0x5c, 0xbf, 0xc1, 0xfb, 0xf7, 0xeb, 0xcd, + 0xbd, 0x5c, 0xf6, 0xfb, 0xfd, 0xc1, 0xfa, 0xf7, 0xff, 0xcd, 0x8e, 0xef, + 0xbd, 0x5c, 0xfc, 0xfb, 0x90, 0xef, 0x3d, 0x5c, 0x90, 0xef, 0x7f, 0x5c, + 0xfb, 0xcf, 0x00, 0x1c, 0xfa, 0x0f, 0xec, 0xfb, 0xfa, 0xcf, 0xfe, 0xce, + 0x00, 0x1c, 0xff, 0x0f, 0xf1, 0xfb, 0xfe, 0xcd, 0x97, 0xef, 0xbf, 0x5c, + 0xfa, 0xcd, 0x97, 0xef, 0xbf, 0x5c, 0xbf, 0xc7, 0xf9, 0xf3, 0x9a, 0xef, + 0xff, 0xcd, 0xbe, 0x5c, 0xeb, 0xcd, 0xbd, 0x5c, 0x6c, 0xeb, 0xff, 0xff, + 0xff, 0x6f, 0xff, 0xbf, 0x89, 0xfe, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xdf, + 0x2f, 0xeb, 0xde, 0xeb, 0x00, 0x1c, 0x47, 0x0d, 0x00, 0x1c, 0xf1, 0x07, + 0xfe, 0xcf, 0x00, 0x1c, 0x4c, 0x00, 0xf4, 0xef, 0xdf, 0x7f, 0x94, 0xef, + 0xbf, 0x7c, 0x9e, 0x7f, 0xfd, 0x7f, 0xff, 0x47, 0xf6, 0xef, 0x00, 0x1c, + 0x5a, 0x13, 0x00, 0x1c, 0x06, 0x06, 0x00, 0x1c, 0xb6, 0x08, 0x00, 0x1c, + 0x3e, 0x0d, 0x00, 0x1c, 0x32, 0x07, 0xff, 0xcf, 0xfe, 0xeb, 0x6f, 0xeb, + 0x89, 0xfe, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xdf, 0x87, 0x82, 0xff, 0xff, + 0xaf, 0xaa, 0xff, 0xff, 0xf7, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, + 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, + 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, + 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, + 0xe5, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, + 0x97, 0xaa, 0xff, 0xff, 0xa3, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, + 0xd3, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, + 0xc1, 0xaa, 0xff, 0xff, 0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8, + 0xc7, 0xc6, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0x9f, 0x96, 0xff, 0xff, + 0x9f, 0x96, 0xff, 0xff, 0x05, 0x99, 0xff, 0xff, 0x9f, 0x96, 0xff, 0xff, + 0xb3, 0x98, 0xff, 0xff, 0x5b, 0x97, 0xff, 0xff, 0x9f, 0x96, 0xff, 0xff, + 0x0f, 0x97, 0xff, 0xff, 0x9f, 0x96, 0xff, 0xff, 0xd9, 0x96, 0xff, 0xff, + 0x9f, 0x96, 0xff, 0xff, 0x45, 0x98, 0xff, 0xff, 0x9f, 0x96, 0xff, 0xff, + 0xcd, 0x96, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0x3c, 0xb8, + 0xff, 0xff, 0xff, 0xc0, 0xd3, 0xdf, 0x8f, 0x96, 0x9b, 0xc5, 0xdf, 0xda, + 0x9b, 0xd7, 0x9a, 0x8d, 0x8d, 0xc5, 0xdf, 0xda, 0x9b, 0xd3, 0xdf, 0x96, + 0xc5, 0xda, 0x9b, 0xd3, 0xdf, 0x9b, 0xc5, 0xda, 0x9b, 0xd6, 0xff, 0xff, + 0xdf, 0x9a, 0x92, 0xc5, 0xda, 0x9b, 0xd3, 0xdf, 0x9c, 0x92, 0xc5, 0xdf, + 0xda, 0x9b, 0xd3, 0xdf, 0x99, 0x8d, 0x9a, 0x8e, 0xc5, 0xda, 0x9b, 0xd3, + 0xdf, 0x9b, 0x8a, 0x8b, 0x86, 0xdf, 0xda, 0x9b, 0xff, 0xff, 0xff, 0xff, + 0xdf, 0x96, 0xc5, 0xdf, 0xda, 0x9b, 0xdf, 0x92, 0xbe, 0xff, 0xff, 0xff, + 0xf2, 0xf5, 0xdf, 0x8d, 0x87, 0xc5, 0xda, 0x9b, 0xd3, 0xdf, 0x8b, 0x87, + 0xc5, 0xda, 0x9b, 0xd3, 0xdf, 0x96, 0xc5, 0xda, 0x9b, 0xd3, 0xdf, 0x93, + 0x90, 0x8c, 0x8c, 0xc5, 0xda, 0x9b, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x9c, + 0x9e, 0x93, 0x96, 0xdf, 0x8d, 0x9a, 0x8c, 0xdf, 0x96, 0x8c, 0xdf, 0xda, + 0x9b, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x91, 0x88, 0x94, 0xdf, 0x8c, + 0x8b, 0x9e, 0x8b, 0x9a, 0xdf, 0x8b, 0x90, 0xdf, 0xda, 0x9b, 0xff, 0xff, + 0xf2, 0xf5, 0xff, 0xff, 0xdf, 0xda, 0xcf, 0xcd, 0x87, 0xff, 0xff, 0xff, + 0xdf, 0x9c, 0x97, 0x94, 0x8c, 0x8a, 0x92, 0xdf, 0x9a, 0x8d, 0x8d, 0xd1, + 0xd1, 0xd1, 0xff, 0xff, 0xdf, 0x9b, 0x92, 0xd2, 0xc1, 0xda, 0x9b, 0xff, + 0xf2, 0xf5, 0xdf, 0x97, 0x86, 0x8c, 0xd4, 0xff, 0xf2, 0xf5, 0xdf, 0x97, + 0x86, 0x8c, 0xd2, 0xff, 0xf2, 0xf5, 0xdf, 0x99, 0x8d, 0x9a, 0x8e, 0xd4, + 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x8f, 0x90, 0x93, 0x9a, 0xd4, + 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x8f, 0x90, 0x93, 0x9a, 0xd2, + 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x9b, 0x92, 0xdf, 0x9c, 0x97, + 0x9e, 0x91, 0x98, 0x9a, 0x9b, 0xd1, 0xdf, 0xda, 0x9b, 0xff, 0xff, 0xff, + 0xf2, 0xf5, 0xdf, 0x8f, 0x9e, 0x9c, 0x94, 0x9a, 0x8b, 0xdf, 0x8b, 0x96, + 0x92, 0x9a, 0x90, 0x8a, 0x8b, 0xd1, 0xd1, 0xd1, 0xff, 0xff, 0xff, 0xff, + 0xf2, 0xf5, 0xdf, 0x8d, 0x8f, 0x8f, 0xdf, 0x8b, 0x96, 0x92, 0x9a, 0x90, + 0x8a, 0x8b, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x99, 0x8d, 0x9a, 0x8e, 0xd2, + 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x8f, 0x97, 0x86, 0xdf, 0x8b, + 0x9e, 0x8c, 0x94, 0xdf, 0x96, 0x9b, 0xdf, 0x96, 0x8c, 0xdf, 0xda, 0x9b, + 0xff, 0xff, 0xff, 0xff, 0x8b, 0x87, 0xa0, 0x92, 0x90, 0x9b, 0x9a, 0xc2, + 0xdf, 0xda, 0x9b, 0xd3, 0xdf, 0x96, 0x96, 0x91, 0xa0, 0x92, 0x9e, 0x87, + 0xc2, 0xdf, 0xda, 0x9b, 0xd3, 0xdf, 0x99, 0x90, 0x9b, 0xa0, 0x90, 0x99, + 0x99, 0x8c, 0x9a, 0x8b, 0xc2, 0xdf, 0xda, 0x9b, 0xd3, 0xdf, 0x8f, 0x96, + 0x91, 0x98, 0xa0, 0x90, 0x99, 0x99, 0x8c, 0x9a, 0x8b, 0xc2, 0xdf, 0xda, + 0x9b, 0xdf, 0xf2, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xb1, 0xaa, 0xe9, 0xe6, 0xdf, 0xb5, 0xcd, 0xea +}; + +u8 fw_data_rx[18424] = { + 0xff, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, + 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, + 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, + 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, + 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, + 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, + 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, + 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, + 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, + 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, + 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0xff, 0xb9, 0xff, 0xff, + 0x67, 0xc1, 0xff, 0xff, 0x8b, 0xb9, 0xff, 0xff, 0x7b, 0xb9, 0xff, 0xff, + 0x73, 0xb9, 0xff, 0xff, 0xf3, 0xc6, 0xff, 0xff, 0x67, 0xc0, 0xff, 0xff, + 0x6b, 0xb9, 0xff, 0xff, 0x63, 0xb9, 0xff, 0xff, 0x4f, 0xb9, 0xff, 0xff, + 0x3b, 0xb9, 0xff, 0xff, 0x33, 0xb9, 0xff, 0xff, 0x2b, 0xb9, 0xff, 0xff, + 0xeb, 0xc6, 0xff, 0xff, 0x83, 0xb9, 0xff, 0xff, 0x23, 0xb9, 0xff, 0xff, + 0x1b, 0xb9, 0xff, 0xff, 0x13, 0xb9, 0xff, 0xff, 0x0b, 0xb9, 0xff, 0xff, + 0x03, 0xb9, 0xff, 0xff, 0xef, 0xb8, 0xff, 0xff, 0xe7, 0xb8, 0xff, 0xff, + 0xdf, 0xb8, 0xff, 0xff, 0xd7, 0xb8, 0xff, 0xff, 0xcf, 0xb8, 0xff, 0xff, + 0xc7, 0xb8, 0xff, 0xff, 0xc7, 0xb8, 0xff, 0xff, 0xc7, 0xb8, 0xff, 0xff, + 0xc7, 0xb8, 0xff, 0xff, 0xc7, 0xb8, 0xff, 0xff, 0xc7, 0xb8, 0xff, 0xff, + 0xc7, 0xb8, 0xff, 0xff, 0x8d, 0xef, 0xfc, 0x3f, 0xdf, 0x9b, 0xad, 0xef, + 0xfd, 0x3f, 0xde, 0x9b, 0xce, 0xef, 0x78, 0x90, 0x0e, 0xef, 0x2d, 0xef, + 0x4d, 0xef, 0x63, 0x9a, 0xf8, 0xf7, 0x7f, 0x6a, 0x7f, 0x48, 0xfc, 0xda, + 0xfc, 0xd8, 0x63, 0x9a, 0x04, 0xf0, 0x90, 0xef, 0xb0, 0xef, 0x71, 0x9f, + 0xbd, 0xb5, 0xbf, 0xc5, 0xf8, 0xf3, 0xff, 0xce, 0xdf, 0x4c, 0xfc, 0xdc, + 0xff, 0xd5, 0xbf, 0xc5, 0x03, 0xf4, 0xff, 0x1f, 0xe6, 0xff, 0xff, 0x1f, + 0x5a, 0xe7, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0x7f, 0xff, 0xfb, 0xff, 0xff, + 0x07, 0xfd, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xdf, 0xd7, 0xff, 0xff, 0xdf, + 0xaf, 0xb4, 0xff, 0xff, 0xd7, 0xff, 0xff, 0xdf, 0x3f, 0xfe, 0xff, 0xdf, + 0xff, 0x1f, 0xd5, 0xdf, 0xff, 0x3f, 0xdf, 0xbf, 0x2b, 0xeb, 0xcc, 0xe9, + 0x8d, 0xed, 0xff, 0xce, 0xda, 0x4c, 0xd9, 0x4c, 0x5f, 0xcd, 0xbe, 0xbd, + 0xfc, 0xe7, 0xff, 0x1f, 0x00, 0xff, 0xdf, 0xca, 0x72, 0xed, 0xfe, 0xc9, + 0xff, 0xcf, 0xff, 0x1f, 0x3a, 0xe7, 0xe7, 0x97, 0xff, 0x8b, 0x9a, 0x6b, + 0x9f, 0x3b, 0xdf, 0xf7, 0xfa, 0x4b, 0xff, 0xcf, 0xff, 0x1f, 0x43, 0xe7, + 0xe7, 0x97, 0xff, 0x8b, 0x99, 0x6b, 0x9f, 0x3b, 0xdf, 0xf7, 0xf9, 0x4b, + 0xff, 0xd2, 0xab, 0x8a, 0xbf, 0xc2, 0x14, 0xf4, 0xfc, 0xe4, 0xbe, 0xed, + 0x3a, 0x6d, 0x3f, 0x4c, 0xb9, 0x6d, 0xbe, 0x4c, 0x00, 0xee, 0x1d, 0x4c, + 0xc0, 0xee, 0xdc, 0x4c, 0x7f, 0xcd, 0xa7, 0xbd, 0xbb, 0x4c, 0x7f, 0xc9, + 0x30, 0x4c, 0xf0, 0x92, 0xfc, 0x1b, 0x00, 0xff, 0xd7, 0x6c, 0xb2, 0x6c, + 0x7a, 0x93, 0xdd, 0x6c, 0x7a, 0x93, 0xdf, 0x6c, 0x7a, 0x93, 0xdd, 0x3b, + 0xfd, 0xb6, 0xaf, 0x4c, 0xfc, 0xdc, 0xf1, 0x9b, 0x0b, 0xf4, 0x0a, 0xee, + 0xca, 0xee, 0xe9, 0xee, 0xa9, 0xee, 0x48, 0xee, 0xff, 0xcc, 0x1f, 0x47, + 0xec, 0xc4, 0xf5, 0xf7, 0xbe, 0x3b, 0xb8, 0xdf, 0xbf, 0x3b, 0xd9, 0xdf, + 0x27, 0x92, 0x1e, 0x47, 0x2d, 0xee, 0x3d, 0x47, 0xd8, 0xfb, 0xd8, 0xc8, + 0x23, 0x9b, 0xf7, 0xf3, 0xbf, 0x3b, 0xb9, 0xdb, 0x7a, 0x92, 0x3e, 0x47, + 0x31, 0xee, 0x3d, 0x47, 0xe2, 0xfb, 0xc4, 0xc8, 0x23, 0x9b, 0xf2, 0xf3, + 0xfe, 0x3b, 0xd9, 0xdb, 0x77, 0x96, 0x3e, 0x47, 0xfe, 0x3b, 0xd9, 0xdf, + 0x1e, 0x67, 0x27, 0x92, 0x1e, 0x47, 0x37, 0xee, 0x3d, 0x47, 0xf1, 0xfb, + 0xb0, 0xc9, 0x27, 0x9b, 0xf7, 0xf3, 0xbf, 0x3b, 0xb9, 0xdb, 0x7a, 0x92, + 0x3e, 0x47, 0x1b, 0xee, 0x1d, 0x47, 0xfb, 0xfb, 0xff, 0xc9, 0x3d, 0x47, + 0x3e, 0x47, 0x3f, 0x6b, 0x1f, 0x67, 0x07, 0xa0, 0x5a, 0x3b, 0xf9, 0xb6, + 0x27, 0xa0, 0x1e, 0x67, 0x23, 0xa1, 0x1d, 0x67, 0x23, 0xa1, 0xff, 0xdc, + 0x33, 0x8b, 0xfc, 0xdb, 0xaf, 0xc8, 0x31, 0x9a, 0xf6, 0xf3, 0x3d, 0x38, + 0xf8, 0xb6, 0x68, 0x93, 0xdf, 0x47, 0xbc, 0x93, 0xe0, 0x93, 0xa4, 0x92, + 0x47, 0xf8, 0x95, 0xef, 0xbf, 0x6c, 0x37, 0xa1, 0x3f, 0x4c, 0xbe, 0x6c, + 0xb7, 0xa2, 0xbe, 0x4c, 0xbd, 0x6c, 0x57, 0xa2, 0x5d, 0x4c, 0xbc, 0x6c, + 0xf7, 0xa7, 0xfc, 0x4c, 0xbb, 0x6c, 0xd7, 0xa6, 0xdb, 0x4c, 0xec, 0xe9, + 0x6b, 0xeb, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xdf, 0x3e, 0x2b, 0x91, 0x06, + 0xa7, 0x48, 0xd5, 0x1c, 0x0f, 0x1e, 0x2d, 0x3c, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x23, 0x45, 0x67, 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, + 0x66, 0x86, 0x7d, 0xa5, 0x5e, 0x14, 0x26, 0x91, 0x23, 0x43, 0xe4, 0x70, + 0x29, 0x3e, 0x9d, 0x35, 0x97, 0xef, 0xbf, 0x6c, 0xbf, 0x4f, 0xbe, 0x6c, + 0xbe, 0x4f, 0xbd, 0x6c, 0xbd, 0x4f, 0xbc, 0x6c, 0xbc, 0x4f, 0xbb, 0x6c, + 0xbb, 0x4f, 0xba, 0x6c, 0xba, 0x4f, 0x99, 0x6c, 0x99, 0x4f, 0xc3, 0x87, + 0xf3, 0xff, 0xff, 0xdf, 0xbf, 0xc6, 0xfc, 0xf7, 0xff, 0x3f, 0xdf, 0xd3, + 0xbf, 0xc7, 0xfd, 0xf7, 0xc3, 0x87, 0x3d, 0xeb, 0xbc, 0x92, 0xba, 0x92, + 0x1f, 0x38, 0x7f, 0xd7, 0xfc, 0xf3, 0xfd, 0x93, 0xff, 0xdf, 0x1e, 0x38, + 0x7f, 0xd7, 0xfc, 0xf3, 0xb9, 0x93, 0xff, 0xde, 0xfe, 0xcd, 0x3c, 0x93, + 0xfc, 0x3b, 0xbb, 0x83, 0x6f, 0x8f, 0xef, 0x8f, 0x38, 0x93, 0xfc, 0x3b, + 0xbb, 0x83, 0xff, 0xdb, 0x3c, 0x93, 0x2e, 0x8f, 0xed, 0x92, 0xdf, 0xdb, + 0x6f, 0x8f, 0xef, 0x8f, 0xbf, 0xc5, 0xf6, 0xf3, 0xff, 0x3b, 0xdf, 0xb3, + 0x32, 0x9f, 0xb3, 0x9b, 0xfd, 0xf3, 0x39, 0x9f, 0x76, 0x9f, 0x06, 0xf0, + 0xf4, 0x93, 0xb0, 0x93, 0xfa, 0x3b, 0xda, 0xb3, 0xfa, 0xf3, 0xfd, 0x93, + 0xff, 0xdf, 0xb9, 0x93, 0xff, 0xde, 0x7d, 0xeb, 0xbf, 0xc5, 0xda, 0xf3, + 0xbc, 0x90, 0x7f, 0x1a, 0xfc, 0xdf, 0xb3, 0x14, 0xff, 0xff, 0xdf, 0xf3, + 0xd2, 0x23, 0xff, 0xff, 0xff, 0xd5, 0xbf, 0xc5, 0xe5, 0xf3, 0x52, 0x1a, + 0xff, 0xff, 0x72, 0x1a, 0xfc, 0xdf, 0xb3, 0x14, 0xff, 0xff, 0xeb, 0xf3, + 0xd2, 0x23, 0xff, 0xff, 0xff, 0xd5, 0xbf, 0xc5, 0xf1, 0xf3, 0x52, 0x1a, + 0xff, 0xff, 0x72, 0x1a, 0xfc, 0xdf, 0xb3, 0x14, 0xff, 0xff, 0xf7, 0xf3, + 0xd2, 0x23, 0xff, 0xff, 0xff, 0xd5, 0x52, 0x1a, 0xff, 0xff, 0xfd, 0xfb, + 0xc3, 0x87, 0x97, 0xbe, 0xb3, 0x93, 0x8f, 0xbe, 0xb3, 0x93, 0xd0, 0xc5, + 0xf1, 0xf7, 0xd2, 0x23, 0xff, 0xdf, 0xd2, 0x23, 0xfe, 0xdf, 0xd2, 0x23, + 0xfd, 0xdf, 0xd2, 0x23, 0xfc, 0xdf, 0xf0, 0xd5, 0x52, 0x1a, 0xf0, 0xff, + 0xd0, 0xc5, 0x0b, 0xf0, 0xdc, 0xc5, 0xf7, 0xf7, 0xfc, 0xd5, 0xd2, 0x23, + 0xff, 0xdf, 0x52, 0x1a, 0xfc, 0xff, 0xdc, 0xc5, 0x05, 0xf0, 0xbf, 0xc5, + 0x1d, 0xf0, 0xff, 0xd5, 0xd2, 0x23, 0xff, 0xff, 0xbf, 0xc5, 0x22, 0xf0, + 0xff, 0xd5, 0xd2, 0x23, 0xfe, 0xff, 0xbf, 0xc5, 0x27, 0xf0, 0xd2, 0x23, + 0xfd, 0xff, 0xc3, 0x87, 0x3d, 0xeb, 0x77, 0x8b, 0xbf, 0xc5, 0xf3, 0xf3, + 0x5c, 0xa5, 0xab, 0x8a, 0xff, 0xda, 0xff, 0xcc, 0xb3, 0xa6, 0x73, 0xa7, + 0xff, 0xdc, 0x7f, 0x7b, 0xb1, 0x9a, 0x7f, 0x5d, 0x05, 0xf4, 0x7d, 0xeb, + 0xb7, 0xef, 0x9d, 0x1b, 0xf4, 0xff, 0xdc, 0x1b, 0xf0, 0xff, 0xf1, 0xa5, + 0x9e, 0x4f, 0xff, 0x4c, 0xfe, 0x4e, 0x9f, 0x4e, 0xde, 0x4c, 0xfd, 0xcc, + 0xde, 0x4d, 0x9f, 0x5d, 0xc3, 0x87, 0xff, 0xff, 0xd7, 0xff, 0xff, 0xdf, + 0xff, 0x8b, 0xef, 0xc7, 0xf0, 0xf7, 0x96, 0xef, 0xbf, 0x7c, 0xbf, 0xc5, + 0xf4, 0xf3, 0xfd, 0x6c, 0xde, 0x6f, 0xdd, 0x4c, 0xbe, 0x6f, 0xdf, 0x6f, + 0xdf, 0x4d, 0xbf, 0x7c, 0xff, 0xd5, 0xbf, 0x5c, 0xc3, 0x87, 0xff, 0xcf, + 0xc3, 0x87, 0xff, 0xff, 0xd7, 0xff, 0xff, 0xdf, 0x93, 0xef, 0xbc, 0x1b, + 0xf4, 0xff, 0x7f, 0x9b, 0xed, 0xf3, 0xbc, 0x1b, 0xd4, 0xff, 0xf7, 0x9b, + 0xf1, 0xf3, 0xff, 0xcd, 0xbf, 0x5f, 0xbe, 0x5f, 0xbe, 0x6c, 0xbf, 0x4f, + 0xde, 0x6d, 0xbe, 0x6c, 0xde, 0x4f, 0xfe, 0x4d, 0xbf, 0x7c, 0xff, 0xdd, + 0xfe, 0x4c, 0xbf, 0x5c, 0xc3, 0x87, 0xff, 0xff, 0xd7, 0xff, 0xff, 0xdf, + 0x77, 0x8b, 0xbf, 0xc5, 0xbb, 0x8b, 0xf6, 0xf3, 0xff, 0xd5, 0x9d, 0xa7, + 0x77, 0x8b, 0x97, 0xa4, 0xdf, 0x5f, 0xff, 0xdf, 0x3d, 0x9b, 0x02, 0xf4, + 0xc3, 0x87, 0xff, 0xff, 0x9f, 0x6f, 0x73, 0x9b, 0xfa, 0xf3, 0x3b, 0x9b, + 0xfd, 0xf7, 0xdf, 0x4f, 0xc3, 0x87, 0xbf, 0x4f, 0xc3, 0x87, 0xff, 0xff, + 0xff, 0xcd, 0x9d, 0xef, 0xbf, 0x5c, 0xc3, 0x87, 0xab, 0xff, 0xff, 0xdf, + 0x2e, 0xeb, 0xfc, 0x92, 0xff, 0x1f, 0xc7, 0xea, 0xbf, 0xc7, 0xeb, 0xf7, + 0x9f, 0x73, 0xbd, 0xc4, 0xe1, 0xf3, 0xb9, 0xc4, 0xdf, 0xf3, 0xbe, 0xc4, + 0xfd, 0xf3, 0x6e, 0xeb, 0xba, 0xee, 0xdf, 0x7d, 0x9a, 0xee, 0xfc, 0xbe, + 0xff, 0xa4, 0xfe, 0x7f, 0xbf, 0xc7, 0xdd, 0xf3, 0xff, 0x1f, 0x6b, 0xf4, + 0x6e, 0xeb, 0x9f, 0xee, 0x9f, 0x7c, 0xbf, 0xee, 0x9c, 0xbc, 0x93, 0xa5, + 0xff, 0x7c, 0xde, 0x6c, 0xf7, 0xcd, 0xff, 0x1f, 0xe6, 0xf5, 0x9f, 0x73, + 0xbd, 0xc4, 0x1b, 0xf4, 0xff, 0xcf, 0xff, 0x1f, 0x0a, 0xeb, 0x6e, 0xeb, + 0x88, 0xef, 0x9f, 0x7c, 0x9c, 0xbc, 0xa8, 0xef, 0x93, 0xa5, 0x9f, 0x7c, + 0xbd, 0xc4, 0x7e, 0x6b, 0xef, 0xf3, 0xec, 0x93, 0x00, 0x1c, 0x6b, 0x00, + 0x6e, 0xeb, 0xff, 0xde, 0xbb, 0x8b, 0xdf, 0x5d, 0xdc, 0xbe, 0x9b, 0xa4, + 0xff, 0x7c, 0xde, 0x6c, 0xf7, 0xcd, 0xff, 0x1f, 0x04, 0xf6, 0x6e, 0xeb, + 0x9e, 0x7b, 0xbf, 0xc4, 0xfb, 0xf7, 0x9f, 0x7b, 0xbe, 0xc4, 0xf7, 0xf3, + 0xfc, 0xcf, 0xff, 0x1f, 0xda, 0xe5, 0xfb, 0xcf, 0xff, 0x1f, 0x2f, 0xeb, + 0x1a, 0xf8, 0xbc, 0x7b, 0x00, 0xcc, 0x35, 0x9b, 0x09, 0xf4, 0xfc, 0xcf, + 0xff, 0x1f, 0x37, 0xeb, 0x22, 0xf8, 0xff, 0xff, 0xab, 0xff, 0xff, 0xdf, + 0x1f, 0xb7, 0xff, 0xff, 0x98, 0xef, 0xff, 0xcd, 0xbf, 0x5c, 0xbe, 0x5c, + 0xff, 0xcd, 0xbe, 0x54, 0x9a, 0xef, 0xdf, 0xcd, 0xbf, 0x5c, 0xfe, 0xcd, + 0xbe, 0x5c, 0xeb, 0xcd, 0xbd, 0x5c, 0xc3, 0x87, 0xa9, 0xff, 0xff, 0xdf, + 0xff, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xfe, 0x74, 0xc3, 0x87, 0xff, 0xff, + 0xa9, 0xff, 0xff, 0xdf, 0x2c, 0xeb, 0xfc, 0x92, 0xff, 0x1f, 0x3b, 0xeb, + 0xbf, 0xc7, 0xed, 0xf7, 0x9f, 0x73, 0xbd, 0xc4, 0xe5, 0xf3, 0xb9, 0xc4, + 0xe3, 0xf3, 0xbe, 0xc4, 0xfd, 0xf3, 0x6c, 0xeb, 0x87, 0xed, 0x9f, 0x7c, + 0xa7, 0xed, 0x9c, 0xbc, 0x93, 0xa5, 0xfe, 0x7c, 0xff, 0x1f, 0xdd, 0xf4, + 0x6c, 0xeb, 0x8b, 0xed, 0xff, 0xcd, 0xbf, 0x5c, 0xfc, 0xcf, 0xcb, 0xed, + 0xfb, 0xcd, 0xff, 0x1f, 0x56, 0xf6, 0x9f, 0x73, 0xbd, 0xc4, 0x17, 0xf4, + 0xff, 0xcf, 0xff, 0x1f, 0x7a, 0xeb, 0x6c, 0xeb, 0x7e, 0x6b, 0x9e, 0x7b, + 0xbf, 0xc4, 0xe8, 0xf3, 0xfd, 0xc4, 0xee, 0xf7, 0x96, 0xed, 0xbe, 0x7c, + 0xff, 0xdd, 0x77, 0x8b, 0xbc, 0xc5, 0xbe, 0x5c, 0xb1, 0xf3, 0x9f, 0x7c, + 0x9c, 0xbc, 0xb9, 0xed, 0x93, 0xa5, 0xff, 0x7c, 0xde, 0x6c, 0xfb, 0xcd, + 0xff, 0x1f, 0x73, 0xf6, 0xec, 0x93, 0x00, 0x1c, 0xe8, 0x00, 0x6c, 0xeb, + 0x40, 0xee, 0x9e, 0x5a, 0x9f, 0x7b, 0xbe, 0xc4, 0xb9, 0xa3, 0xdf, 0xf3, + 0x9f, 0x7a, 0xbc, 0xbc, 0x23, 0xee, 0xb7, 0xa1, 0xbf, 0x7d, 0xff, 0xdc, + 0x33, 0x8b, 0xba, 0xc5, 0x9f, 0x5a, 0xf6, 0xf3, 0x9c, 0xbc, 0x33, 0xa1, + 0xff, 0x79, 0xde, 0x69, 0xfb, 0xcd, 0xff, 0x1f, 0x8e, 0xf6, 0x1a, 0xf8, + 0x95, 0xa3, 0xbd, 0x7c, 0xb7, 0xbd, 0x9c, 0x7c, 0x37, 0x93, 0x9e, 0x52, + 0xef, 0xcf, 0xd9, 0xa2, 0xff, 0xcd, 0xff, 0x1f, 0xe2, 0xf4, 0x9f, 0x7a, + 0x13, 0xf8, 0x9e, 0x7d, 0xfe, 0xdc, 0x33, 0x8b, 0xfe, 0xc4, 0xdf, 0xf3, + 0xbf, 0x7a, 0x94, 0xee, 0xdc, 0xbd, 0xdb, 0xa4, 0xff, 0x7e, 0x24, 0xa7, + 0x67, 0x8a, 0xfe, 0xc1, 0xd2, 0xf3, 0xff, 0xdd, 0x77, 0x8b, 0xbf, 0x5a, + 0xbc, 0xbd, 0x97, 0xa4, 0xde, 0x6c, 0xbf, 0xc6, 0xce, 0xf3, 0xff, 0x7c, + 0xfb, 0xcd, 0xff, 0x1f, 0xb6, 0xf6, 0x42, 0xf8, 0xbf, 0x7c, 0xff, 0xdd, + 0x77, 0x8b, 0xff, 0xce, 0xbf, 0x5c, 0xde, 0x5c, 0xbc, 0xbd, 0x82, 0xef, + 0x51, 0xf8, 0x9f, 0x7a, 0x24, 0xef, 0xbc, 0xbc, 0xb7, 0xa1, 0xbf, 0x7d, + 0xb8, 0xc5, 0xdb, 0xf3, 0xbc, 0xc5, 0xd7, 0xf3, 0xff, 0xdc, 0x33, 0x8b, + 0x9f, 0x5a, 0x9c, 0xbc, 0x33, 0xa1, 0xde, 0x69, 0xbf, 0xc6, 0xed, 0xf3, + 0xff, 0x79, 0xfb, 0xcd, 0xff, 0x1f, 0xd5, 0xf6, 0x61, 0xf8, 0x8c, 0xef, + 0xbd, 0x7c, 0xf5, 0xca, 0x6b, 0x9b, 0xf3, 0xf7, 0xfe, 0xd5, 0xbd, 0x5c, + 0xde, 0x6e, 0xfb, 0xcd, 0xff, 0x1f, 0xe1, 0xf6, 0x6d, 0xf8, 0xfb, 0xcf, + 0xff, 0x1f, 0x03, 0xec, 0x71, 0xf8, 0xf9, 0xcf, 0xff, 0x1f, 0xb1, 0xec, + 0x75, 0xf8, 0xb6, 0xef, 0xfb, 0xce, 0xde, 0x5d, 0xeb, 0xce, 0xdd, 0x5d, + 0x25, 0xf8, 0xfc, 0xcf, 0xff, 0x1f, 0xbf, 0xe6, 0x9f, 0x7a, 0x2a, 0xf8, + 0xa9, 0xff, 0xff, 0xdf, 0xf3, 0xb6, 0xff, 0xff, 0xf7, 0xb6, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xfd, 0x7c, 0xfe, 0xb7, 0xc3, 0x87, + 0xff, 0xff, 0xff, 0xdf, 0xc3, 0x87, 0xff, 0xff, 0x2e, 0xeb, 0xfc, 0x92, + 0xff, 0x1f, 0x09, 0xec, 0xbf, 0xc7, 0xf0, 0xf7, 0x9f, 0x73, 0xbe, 0xc4, + 0xf7, 0xf3, 0xbd, 0xc4, 0xfd, 0xf3, 0x6e, 0xeb, 0xff, 0xcf, 0xff, 0x1f, + 0x32, 0xec, 0x6e, 0xeb, 0xfd, 0xcf, 0xff, 0x1f, 0x36, 0xec, 0x6e, 0xeb, + 0xff, 0xcf, 0xff, 0xce, 0xf7, 0xcd, 0xff, 0x1f, 0x1e, 0xf7, 0x12, 0xf8, + 0x2f, 0xeb, 0xfe, 0xcf, 0xff, 0x1f, 0x41, 0xec, 0xfd, 0xef, 0xff, 0x1f, + 0x8a, 0xeb, 0x6f, 0xeb, 0xa5, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0xfe, 0xce, + 0xbc, 0xef, 0xfb, 0xef, 0xff, 0x1f, 0xc7, 0xeb, 0x6f, 0xeb, 0xff, 0xff, + 0x43, 0xf4, 0xff, 0xff, 0xa5, 0xff, 0xff, 0xdf, 0x2e, 0xeb, 0xfc, 0x92, + 0xff, 0x1f, 0x39, 0xec, 0xbe, 0xc7, 0xe4, 0xf3, 0x9f, 0x73, 0xbe, 0xc4, + 0xfd, 0xf3, 0x6e, 0xeb, 0xff, 0x1f, 0xfd, 0xfb, 0xbf, 0xc7, 0xf1, 0xf7, + 0xf5, 0xcf, 0xff, 0xce, 0xf0, 0xcd, 0xff, 0x1f, 0x48, 0xf7, 0x8b, 0xef, + 0xbe, 0x7c, 0xff, 0xdd, 0xbe, 0x5c, 0xfc, 0xcf, 0xff, 0x1f, 0x1d, 0xf5, + 0x6e, 0xeb, 0xff, 0x1f, 0x0c, 0xed, 0xb4, 0xc7, 0x0f, 0xf4, 0x0b, 0xf8, + 0xff, 0x1f, 0x65, 0xec, 0xba, 0xc7, 0xef, 0xf3, 0xf2, 0xcf, 0xff, 0xce, + 0xf0, 0xcd, 0xff, 0x1f, 0x5e, 0xf7, 0xff, 0xcd, 0x97, 0xef, 0xbe, 0x5c, + 0xff, 0x1f, 0x1f, 0xfc, 0xbf, 0xc7, 0x28, 0xf0, 0xff, 0x1f, 0x0d, 0xea, + 0x2b, 0xf8, 0x9b, 0xef, 0xff, 0x7c, 0xfd, 0xce, 0xff, 0xcd, 0xff, 0x1f, + 0xaa, 0xeb, 0x32, 0xf8, 0xa5, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0x8e, 0xee, + 0xbb, 0x7c, 0xdd, 0xa5, 0xde, 0x1b, 0xe0, 0xdf, 0xbd, 0x1b, 0xe0, 0xcf, + 0x7b, 0x93, 0xbb, 0x5c, 0xbc, 0x7c, 0xbd, 0xb5, 0xbd, 0x1b, 0xe0, 0xdf, + 0xb6, 0x9b, 0xdd, 0xf3, 0xff, 0x6c, 0xbe, 0x7c, 0xf2, 0xb7, 0xff, 0x1b, + 0xe0, 0xdf, 0xbd, 0x1b, 0xe0, 0xcf, 0x7f, 0x93, 0xbe, 0x5c, 0xbd, 0x1b, + 0xe0, 0xdf, 0xf2, 0xd5, 0x77, 0x8b, 0xfd, 0xc5, 0xff, 0x3b, 0xfe, 0xfa, + 0xbd, 0x74, 0xff, 0xde, 0xd8, 0xbe, 0x78, 0xc5, 0x77, 0xc5, 0x7b, 0x93, + 0xbd, 0x54, 0xbd, 0x1b, 0xe0, 0xcf, 0xbb, 0x5c, 0xbe, 0x74, 0xa9, 0xbd, + 0xa7, 0xb5, 0xff, 0xce, 0xff, 0x1f, 0xa1, 0xf7, 0x6f, 0xeb, 0x7a, 0x9b, + 0xe4, 0xf7, 0xa1, 0xa4, 0xde, 0x7c, 0xde, 0x1b, 0xe0, 0xcf, 0xde, 0x13, + 0xf2, 0xff, 0xde, 0x5c, 0xbf, 0x7d, 0xbd, 0x1b, 0xf9, 0xdf, 0xbf, 0xc5, + 0xf8, 0x93, 0xe5, 0xf3, 0xf2, 0xcf, 0xbd, 0x74, 0x78, 0xc5, 0x77, 0xc5, + 0x57, 0xc5, 0xbd, 0x54, 0xbe, 0x74, 0xa9, 0xbd, 0xa7, 0xb5, 0xff, 0xce, + 0xff, 0x1f, 0xbd, 0xf7, 0x6f, 0xeb, 0xa1, 0xa4, 0xde, 0x7d, 0x3f, 0xc6, + 0x1b, 0xf4, 0xbe, 0x7c, 0xbd, 0x1b, 0xe0, 0xcf, 0xbd, 0x13, 0xf4, 0xff, + 0xbe, 0x5c, 0xf4, 0xcf, 0x16, 0xf8, 0xff, 0x1b, 0xe0, 0xcf, 0xff, 0x13, + 0xf4, 0xff, 0xbc, 0xef, 0xfe, 0x5d, 0xf4, 0xcf, 0x1e, 0xf8, 0xff, 0xff, + 0xa3, 0xff, 0xff, 0xdf, 0x2d, 0xeb, 0xfc, 0x92, 0xff, 0xcf, 0xff, 0x1f, + 0x10, 0xf0, 0x91, 0xef, 0xdf, 0x73, 0xbe, 0x74, 0x5e, 0x1b, 0x00, 0xdc, + 0xbd, 0x1b, 0x00, 0xcc, 0x6b, 0x93, 0xbe, 0x54, 0xbe, 0x73, 0x7f, 0x9b, + 0xf7, 0xf3, 0xdf, 0x7c, 0x5c, 0xc6, 0xdf, 0x5c, 0xf4, 0x93, 0xff, 0x1f, + 0x06, 0xf8, 0x6d, 0xeb, 0xf8, 0x93, 0xff, 0x1f, 0xb8, 0xea, 0xbe, 0x73, + 0xf4, 0x93, 0xff, 0x1f, 0x0e, 0xf8, 0x6d, 0xeb, 0x9b, 0xff, 0xff, 0xdf, + 0x2e, 0xeb, 0x79, 0xed, 0xa1, 0xa3, 0xdf, 0x7d, 0x9e, 0x1b, 0xf9, 0xdf, + 0xbf, 0xc4, 0xa8, 0xf3, 0xbd, 0xc4, 0xd4, 0xf3, 0xbb, 0xc4, 0xfd, 0xf3, + 0x6e, 0xeb, 0x8f, 0x7b, 0xbc, 0x1b, 0xfc, 0xdf, 0xbe, 0xc5, 0x04, 0xf0, + 0x7f, 0xc4, 0x7e, 0xc4, 0x5f, 0xc4, 0x8f, 0x5b, 0x9e, 0x73, 0x9c, 0x1b, + 0x03, 0xcc, 0x9c, 0x13, 0x73, 0xff, 0x9e, 0x53, 0x97, 0xb4, 0x9c, 0x1b, + 0x83, 0xcf, 0x9c, 0x13, 0xeb, 0xff, 0x9c, 0x5b, 0x9e, 0x7b, 0x9c, 0x1b, + 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5b, 0x9f, 0x6b, 0xac, 0xee, + 0x37, 0x97, 0x52, 0xc4, 0x4e, 0xc4, 0x9f, 0x4b, 0x9d, 0x73, 0x78, 0xc4, + 0x77, 0xc4, 0x57, 0xc4, 0x9d, 0x53, 0x6e, 0xeb, 0x91, 0xee, 0x9e, 0x6c, + 0x3f, 0xc4, 0x2a, 0xf0, 0x7e, 0xc6, 0x7d, 0xc6, 0xff, 0xcc, 0x5d, 0xc6, + 0x91, 0x5b, 0xff, 0x15, 0x60, 0xfe, 0xdf, 0x5d, 0xff, 0x1f, 0x53, 0xf8, + 0xff, 0xcd, 0xfc, 0xcf, 0xff, 0xce, 0xff, 0x1f, 0x86, 0xf6, 0x9e, 0x73, + 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, 0x73, 0xff, 0x9e, 0x53, 0x97, 0xb4, + 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0xc7, 0xff, 0x9c, 0x5b, 0x9e, 0x7b, + 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5b, 0x9f, 0x6b, + 0xa5, 0xef, 0x37, 0x97, 0x4e, 0xc4, 0x2f, 0xf8, 0x9e, 0x7d, 0x7f, 0xc4, + 0x9e, 0x5d, 0xff, 0xcc, 0xc9, 0xd4, 0xb3, 0x97, 0x5e, 0xc6, 0x1c, 0xcf, + 0xdf, 0x5d, 0xfe, 0xbf, 0xff, 0x1f, 0x7b, 0xf8, 0x9e, 0x73, 0x9c, 0x1b, + 0x03, 0xcc, 0x9c, 0x13, 0x3b, 0xff, 0x9e, 0x53, 0x97, 0xb4, 0x9c, 0x1b, + 0x83, 0xcf, 0x9c, 0x13, 0x9b, 0xff, 0x9c, 0x5b, 0x9e, 0x7b, 0x9c, 0x1b, + 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5b, 0x9f, 0x6b, 0xb6, 0xef, + 0x37, 0x97, 0x0f, 0xcd, 0xb6, 0xbd, 0x37, 0x93, 0x9f, 0x4b, 0x9d, 0x73, + 0x78, 0xc4, 0x77, 0xc4, 0x58, 0xc4, 0x9d, 0x53, 0x9c, 0x1b, 0xe0, 0xcf, + 0x9b, 0x5b, 0x6e, 0xeb, 0xa3, 0xff, 0xff, 0xdf, 0x00, 0xe0, 0x03, 0x00, + 0xff, 0x5f, 0xff, 0xbf, 0x2e, 0xeb, 0xde, 0xeb, 0x6c, 0xef, 0x9e, 0x7b, + 0x9c, 0x1b, 0xf9, 0xdf, 0xbf, 0xc4, 0xf9, 0xf3, 0xee, 0xef, 0xff, 0x1f, + 0xf8, 0xec, 0xfe, 0xeb, 0x6e, 0xeb, 0xff, 0xcf, 0xff, 0x1f, 0x3f, 0xf3, + 0xff, 0xcd, 0x9e, 0x7b, 0xf8, 0xd5, 0x37, 0x97, 0x5d, 0xc4, 0x9e, 0x5b, + 0x9f, 0x7b, 0x3f, 0xc4, 0x0f, 0xf4, 0xfc, 0x15, 0xb2, 0xfe, 0xc4, 0x93, + 0x91, 0x23, 0xff, 0xef, 0x07, 0xcc, 0x91, 0x23, 0xfe, 0xef, 0x00, 0x1c, + 0xd4, 0x00, 0xfb, 0xef, 0xff, 0x1f, 0x13, 0xed, 0xfe, 0xeb, 0x6e, 0xeb, + 0x9b, 0xff, 0xff, 0xdf, 0x92, 0xff, 0xff, 0xdf, 0x2b, 0xeb, 0xdb, 0xeb, + 0x7a, 0xec, 0x9a, 0x6b, 0xbe, 0xc4, 0xbc, 0x92, 0xe4, 0xf2, 0x9f, 0x7a, + 0x9b, 0xb4, 0xfd, 0xdc, 0x9c, 0x1b, 0xfc, 0xdf, 0xfe, 0xc4, 0x56, 0xf3, + 0xff, 0x1f, 0x3b, 0xe9, 0xbf, 0xc7, 0xfc, 0xf3, 0xfb, 0xeb, 0x6b, 0xeb, + 0xff, 0x1f, 0x01, 0xf1, 0x7c, 0x92, 0xff, 0x1f, 0xd4, 0xf8, 0xbe, 0x7a, + 0xbd, 0x1b, 0xf9, 0xdf, 0xbf, 0xc5, 0x3c, 0x93, 0xbf, 0xf7, 0x07, 0xed, + 0xbd, 0x70, 0xa9, 0xbd, 0xa9, 0xb5, 0x76, 0x9a, 0xc5, 0xf3, 0xff, 0x47, + 0xff, 0x1f, 0x67, 0xf3, 0xf7, 0xcd, 0xf7, 0x9b, 0x9f, 0x67, 0x81, 0xf6, + 0x72, 0xcf, 0xfd, 0xbf, 0xff, 0x1f, 0xff, 0xf8, 0x3f, 0xcf, 0xfd, 0xbf, + 0xff, 0x1f, 0xb1, 0xeb, 0x9f, 0x67, 0xff, 0xcd, 0xac, 0x53, 0xff, 0xcf, + 0xbe, 0x7a, 0xf8, 0xd7, 0x7f, 0x97, 0x5e, 0xc5, 0xbe, 0x5a, 0xbe, 0x73, + 0xbd, 0x1b, 0x03, 0xcc, 0xbd, 0x13, 0x37, 0xff, 0xbe, 0x53, 0xb7, 0xb5, + 0xbd, 0x1b, 0x83, 0xcf, 0xbd, 0x13, 0xc7, 0xff, 0xbc, 0x5b, 0xbe, 0x7b, + 0xbd, 0x1b, 0xe0, 0xcf, 0xbd, 0x13, 0xf4, 0xff, 0xbe, 0x5b, 0xbf, 0x78, + 0x3f, 0xc5, 0x65, 0xf6, 0xf3, 0xce, 0xbf, 0x6b, 0xe1, 0xee, 0xd2, 0xbe, + 0x7f, 0x97, 0x7b, 0x93, 0xbf, 0x4b, 0xbd, 0x73, 0x78, 0xc5, 0x77, 0xc5, + 0x57, 0xc5, 0xbd, 0x53, 0xdf, 0x7a, 0xbb, 0xb6, 0xbd, 0x1b, 0xfc, 0xdf, + 0xbe, 0xc5, 0x0e, 0xf3, 0xbd, 0xc5, 0x8e, 0xf3, 0xbf, 0xc5, 0x54, 0xf4, + 0xed, 0xd4, 0x73, 0x9a, 0xca, 0xf6, 0x9f, 0x7a, 0x7b, 0xc4, 0x7a, 0xc4, + 0x5b, 0xc4, 0x9f, 0x5a, 0x3f, 0xc4, 0x36, 0xf6, 0xbb, 0x7b, 0xbd, 0x1b, + 0xe0, 0xdf, 0xdd, 0xc5, 0xa9, 0xf2, 0x7b, 0xc4, 0x7a, 0xc4, 0x9f, 0x5a, + 0xff, 0xcd, 0xbb, 0x23, 0xdb, 0xff, 0xbf, 0x7a, 0x98, 0xee, 0x3f, 0xc5, + 0x9d, 0xf6, 0xcc, 0x74, 0x66, 0xcd, 0xb7, 0x9b, 0xd0, 0xf7, 0xbe, 0x74, + 0xbd, 0x1b, 0x03, 0xcc, 0xbd, 0x13, 0x73, 0xff, 0xbe, 0x54, 0xb7, 0xb5, + 0xbd, 0x1b, 0x83, 0xcf, 0xbd, 0x13, 0xeb, 0xff, 0xbc, 0x5c, 0xbe, 0x7c, + 0xbd, 0x1b, 0xe0, 0xcf, 0xbd, 0x13, 0xf4, 0xff, 0xbe, 0x5c, 0xbf, 0x6c, + 0xc3, 0xef, 0x7b, 0x97, 0x52, 0xc5, 0x4e, 0xc5, 0xbf, 0x4c, 0xbd, 0x74, + 0x78, 0xc5, 0x77, 0xc5, 0x57, 0xc5, 0xbd, 0x54, 0x9f, 0x7a, 0x9c, 0x1b, + 0xfe, 0xdf, 0xd1, 0x1b, 0xf1, 0xff, 0xfe, 0xcd, 0x9f, 0x5e, 0xba, 0x4b, + 0xfe, 0xcf, 0xff, 0xcd, 0xff, 0x1f, 0xab, 0xf7, 0x9f, 0x7a, 0x7b, 0xc4, + 0x7a, 0xc4, 0x5a, 0xc4, 0x9f, 0x5a, 0xff, 0xcc, 0x8c, 0x53, 0xa2, 0xf8, + 0x91, 0xef, 0x9d, 0x6c, 0x3d, 0xc4, 0xaa, 0xf4, 0x9b, 0x27, 0xdb, 0xff, + 0xbd, 0xa4, 0xbb, 0x23, 0xdb, 0xff, 0xfa, 0xcd, 0x37, 0x9b, 0xb2, 0xf4, + 0x96, 0xef, 0xff, 0xce, 0xdd, 0x4c, 0xfd, 0xcf, 0xff, 0x1f, 0x25, 0xe9, + 0xfd, 0xcf, 0xff, 0x1f, 0x4c, 0xe9, 0xbc, 0xf8, 0xa3, 0xff, 0xff, 0xdf, + 0x9b, 0xff, 0xff, 0xdf, 0x00, 0xe0, 0x03, 0x00, 0xff, 0xaf, 0xff, 0xbf, + 0xff, 0xcf, 0xff, 0xbf, 0xff, 0x1f, 0xe1, 0xeb, 0x9e, 0x7a, 0x9c, 0xb4, + 0x9c, 0x1b, 0xf8, 0xdf, 0xf2, 0x9b, 0xe4, 0xf6, 0x3e, 0x9b, 0x25, 0xf7, + 0xfc, 0xcf, 0xff, 0x1f, 0xce, 0xf1, 0x7a, 0xcc, 0x9e, 0xbc, 0xf3, 0x9b, + 0xf4, 0xf7, 0x9f, 0x7a, 0x9c, 0x1b, 0xfe, 0xdf, 0xbf, 0xc4, 0xff, 0x3b, + 0xfc, 0xfa, 0xf4, 0xcf, 0xf2, 0xa7, 0xff, 0x1f, 0x9c, 0xef, 0x18, 0xec, + 0x9c, 0x78, 0xbc, 0x1b, 0xfb, 0xdf, 0x77, 0x8b, 0xbf, 0xc5, 0x66, 0xf7, + 0x9f, 0x7a, 0x9c, 0x1b, 0xf7, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0xff, 0xf6, + 0xbe, 0x7a, 0x37, 0x8b, 0xdc, 0x1b, 0xb9, 0xdf, 0xbd, 0xc6, 0xef, 0xf2, + 0x9c, 0x1b, 0x80, 0xcf, 0xbf, 0xc4, 0xf3, 0xf3, 0x39, 0x1b, 0xd0, 0xed, + 0x66, 0x8a, 0xef, 0xc1, 0xf8, 0xf7, 0xbd, 0x1b, 0x80, 0xdf, 0xbe, 0x5a, + 0xfe, 0xcf, 0xff, 0x1f, 0x6e, 0xf4, 0x8b, 0x73, 0xff, 0xdc, 0x32, 0x8b, + 0x9c, 0xcd, 0x37, 0x9b, 0x8b, 0x53, 0x06, 0xf5, 0xff, 0xcd, 0x8c, 0xed, + 0xab, 0x54, 0xfb, 0xcf, 0xff, 0x1f, 0xa3, 0xf7, 0x0d, 0xf9, 0xfc, 0xcf, + 0xff, 0x1f, 0x0f, 0xf2, 0x93, 0x73, 0xb3, 0xa7, 0x92, 0x73, 0xff, 0xdc, + 0x32, 0x8b, 0x76, 0x8b, 0xfe, 0x15, 0x82, 0xfb, 0xbe, 0xb5, 0x3b, 0x9b, + 0xb3, 0x53, 0x92, 0x53, 0xf9, 0xf7, 0xff, 0xcc, 0x92, 0x53, 0xc4, 0xcc, + 0x73, 0x9b, 0x70, 0xf7, 0x98, 0x6b, 0xbe, 0xc4, 0xbb, 0xed, 0x66, 0xf3, + 0x97, 0x6b, 0xbe, 0xc4, 0xbd, 0xed, 0x35, 0xf5, 0xd2, 0x75, 0x9c, 0x1b, + 0xe2, 0xfc, 0xb3, 0x9b, 0x3a, 0xf5, 0xff, 0xcf, 0xff, 0xcc, 0xfa, 0x4d, + 0xf7, 0x4d, 0x92, 0x55, 0x9f, 0x7a, 0x3f, 0xc4, 0xf8, 0xf2, 0xff, 0x1b, + 0x61, 0xfe, 0xff, 0x1f, 0x1e, 0xfa, 0xff, 0x15, 0xcc, 0xfd, 0xff, 0x1f, + 0xd0, 0xec, 0x4b, 0xf9, 0x3f, 0xc6, 0x67, 0xf3, 0xfe, 0xcf, 0xff, 0x1f, + 0x44, 0xf2, 0x32, 0xcc, 0x9e, 0xbc, 0xf3, 0x9b, 0x49, 0xf5, 0x9f, 0x7a, + 0xd1, 0x1b, 0xf1, 0xff, 0x9c, 0x1b, 0xfe, 0xdf, 0x9f, 0x5e, 0xfe, 0xcf, + 0xfe, 0xcc, 0xff, 0xcd, 0x9a, 0x4b, 0xff, 0x1f, 0x66, 0xf8, 0x9f, 0x7a, + 0x34, 0xee, 0x3f, 0xc4, 0xe1, 0xf7, 0x9e, 0x71, 0x9c, 0x1b, 0x03, 0xcc, + 0x9c, 0x13, 0x73, 0xff, 0x9e, 0x51, 0x97, 0xb4, 0x9c, 0x1b, 0x83, 0xcf, + 0x9c, 0x13, 0xeb, 0xff, 0x9c, 0x59, 0x9e, 0x79, 0x9c, 0x1b, 0xe0, 0xcf, + 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x59, 0x9f, 0x69, 0xfe, 0xee, 0x3f, 0x97, + 0x52, 0xc4, 0x4e, 0xc4, 0x9f, 0x49, 0x9d, 0x71, 0x78, 0xc4, 0x77, 0xc4, + 0x57, 0xc4, 0x9d, 0x51, 0x9f, 0x7a, 0x7b, 0xc4, 0x7a, 0xc4, 0x5a, 0xc4, + 0x9f, 0x5a, 0x7c, 0xf9, 0x20, 0xcd, 0xbe, 0xbd, 0x77, 0x9a, 0x9a, 0xf0, + 0x7d, 0xc4, 0xfa, 0xcf, 0xff, 0xce, 0x9c, 0x58, 0xff, 0x1f, 0x53, 0xea, + 0xff, 0x15, 0xcc, 0xfd, 0xff, 0x1f, 0x1b, 0xed, 0xa5, 0xf8, 0x3f, 0xc6, + 0x6e, 0xf7, 0x8c, 0x73, 0xff, 0xdc, 0x32, 0x8b, 0x66, 0xcd, 0x37, 0x9b, + 0x8c, 0x53, 0x3b, 0xf1, 0x95, 0xf9, 0xbe, 0x7a, 0x59, 0xc5, 0xbe, 0x5a, + 0xfe, 0xcf, 0x9f, 0x47, 0xff, 0x1f, 0x0b, 0xf5, 0xbf, 0x7a, 0x9f, 0x67, + 0x3f, 0xc5, 0x70, 0xf3, 0xfc, 0xcf, 0xff, 0x1f, 0xf0, 0xfa, 0x9f, 0x67, + 0x82, 0xf9, 0xff, 0xdf, 0xff, 0x8b, 0xff, 0x1f, 0xd4, 0xec, 0xdc, 0xf8, + 0x9b, 0xff, 0xff, 0xdf, 0xa3, 0xff, 0xff, 0xdf, 0x00, 0xe0, 0x03, 0x00, + 0xfe, 0xcf, 0xf8, 0x4b, 0x0d, 0xcf, 0xff, 0x1f, 0x98, 0xfa, 0xff, 0x1f, + 0x26, 0xed, 0x94, 0xf8, 0xff, 0x15, 0xb2, 0xfe, 0x84, 0xce, 0xff, 0x1f, + 0x44, 0xed, 0x56, 0xf9, 0xd2, 0x75, 0x6a, 0xcc, 0xb3, 0x9b, 0x9a, 0xf4, + 0xff, 0xcc, 0xff, 0xce, 0x92, 0x55, 0xfe, 0xcc, 0xd8, 0x4d, 0x97, 0x4d, + 0xff, 0x15, 0xcc, 0xfe, 0x84, 0xce, 0xff, 0x1f, 0x54, 0xed, 0xa6, 0xf8, + 0xac, 0x74, 0x00, 0xcc, 0x73, 0x9b, 0x31, 0xf5, 0xff, 0x15, 0x60, 0xfe, + 0xff, 0x1f, 0xb9, 0xfa, 0x47, 0xf9, 0xef, 0xce, 0x98, 0xf9, 0xfe, 0xcf, + 0xff, 0x1f, 0xdb, 0xf2, 0xfc, 0x15, 0xee, 0xfe, 0xf3, 0x9b, 0x95, 0xf0, + 0x9f, 0x7a, 0x3f, 0xc4, 0xe3, 0xf1, 0xa0, 0xf8, 0xff, 0xd7, 0xff, 0x8b, + 0xff, 0x1f, 0x13, 0xed, 0x1b, 0xf9, 0xff, 0x1f, 0x12, 0xf5, 0xfe, 0xe4, + 0xff, 0x54, 0xef, 0xb7, 0xfe, 0x54, 0x9f, 0x6c, 0xfd, 0xe5, 0x9f, 0x4d, + 0x8f, 0xb4, 0xf9, 0xdc, 0x73, 0x9a, 0x0a, 0xf1, 0xfe, 0x70, 0xe9, 0xbf, + 0xe9, 0xb7, 0xff, 0x1f, 0x8c, 0xed, 0x9f, 0x7a, 0x7c, 0xc4, 0x9f, 0x5a, + 0x13, 0xf9, 0x78, 0xcc, 0x9d, 0xbc, 0x73, 0x9a, 0xbb, 0xf3, 0x8c, 0x73, + 0xff, 0xdc, 0x32, 0x8b, 0xca, 0xcd, 0x37, 0x9b, 0x8c, 0x53, 0x09, 0xf5, + 0xfd, 0xe7, 0xfc, 0x15, 0xcc, 0xfd, 0x9f, 0x57, 0xfc, 0x15, 0x60, 0xfe, + 0x9e, 0x57, 0x9e, 0x7a, 0x59, 0xc4, 0x9e, 0x5a, 0xff, 0xcd, 0x81, 0xef, + 0xac, 0x54, 0x00, 0x1c, 0x0a, 0x03, 0xff, 0xcf, 0xff, 0x1f, 0x8b, 0xf5, + 0x1c, 0xf9, 0x8c, 0x73, 0xff, 0xdc, 0x32, 0x8b, 0x00, 0xcd, 0x37, 0x9b, + 0x8c, 0x53, 0xcb, 0xf1, 0xff, 0x17, 0x25, 0x02, 0xff, 0x15, 0xcc, 0xfd, + 0x84, 0xce, 0xff, 0x1f, 0xb2, 0xed, 0xfe, 0xcc, 0x91, 0x5b, 0xc6, 0xf9, + 0xfd, 0xe7, 0xfd, 0x15, 0xb2, 0xfe, 0xbf, 0x57, 0x07, 0xcd, 0xbe, 0x57, + 0x9f, 0x47, 0x00, 0x1c, 0x28, 0x03, 0xfe, 0xcf, 0xff, 0x1f, 0x87, 0xfb, + 0x9f, 0x67, 0xff, 0x17, 0x19, 0x02, 0x07, 0xcf, 0xff, 0x1f, 0x23, 0xfb, + 0xff, 0x15, 0xb2, 0xfe, 0xff, 0x1f, 0xd5, 0xed, 0xff, 0x17, 0x50, 0x02, + 0xff, 0xce, 0xc0, 0xd6, 0x7b, 0x93, 0xbe, 0x5a, 0xff, 0xcc, 0xfc, 0xcf, + 0x8c, 0x53, 0xff, 0x1f, 0x9c, 0xfb, 0x4f, 0xf9, 0xa3, 0xff, 0xff, 0xdf, + 0x2d, 0xeb, 0x6d, 0xef, 0x41, 0xa3, 0xec, 0x93, 0xff, 0xce, 0xf7, 0xcd, + 0x00, 0x1c, 0x7b, 0x05, 0xf9, 0xcd, 0xe8, 0x93, 0xff, 0xce, 0x00, 0x1c, + 0x80, 0x05, 0xff, 0xcd, 0x9f, 0x7a, 0x8f, 0xd5, 0x37, 0x97, 0x9f, 0x5a, + 0x9e, 0x7a, 0x9c, 0x13, 0xf9, 0xff, 0x9c, 0x1b, 0xc7, 0xcf, 0x5b, 0xc4, + 0x9e, 0x5a, 0x8f, 0x7b, 0x97, 0xdd, 0x37, 0x97, 0x5e, 0xc4, 0x8f, 0x5b, + 0xf0, 0xcc, 0x8e, 0x5b, 0xff, 0xcc, 0x8c, 0x53, 0x6d, 0xeb, 0xff, 0xff, + 0xa3, 0xff, 0xff, 0xdf, 0x9c, 0xef, 0xff, 0x7c, 0xfd, 0x93, 0xff, 0x1b, + 0xfe, 0xdf, 0xc3, 0x87, 0x9b, 0xff, 0xff, 0xdf, 0x2b, 0xeb, 0xd6, 0xeb, + 0xfc, 0x92, 0xff, 0x1f, 0x4e, 0xf0, 0xbe, 0xc7, 0x39, 0xf3, 0x9f, 0x73, + 0xf9, 0xc4, 0xdc, 0xf7, 0xb6, 0xec, 0x9d, 0x3b, 0xbc, 0xf7, 0x9f, 0x6c, + 0xf3, 0x87, 0x57, 0xec, 0x97, 0x7a, 0x9c, 0x1b, 0x80, 0xcf, 0x33, 0x8b, + 0xbf, 0xc4, 0x9f, 0x17, 0xcb, 0xfd, 0x6f, 0x7a, 0x7b, 0x1b, 0xfb, 0xdf, + 0xef, 0x8a, 0xbf, 0xc3, 0xf8, 0xf7, 0x9e, 0x7a, 0x9c, 0x1b, 0xe0, 0xdf, + 0xd2, 0xc4, 0x9f, 0x17, 0xd2, 0xfd, 0xfd, 0x72, 0xf8, 0xb7, 0xff, 0x1b, + 0xfc, 0xdf, 0xff, 0x1f, 0x02, 0xfa, 0xfe, 0xcc, 0x9a, 0x23, 0xd4, 0xff, + 0xf6, 0xeb, 0x6b, 0xeb, 0x7e, 0x6b, 0x9e, 0x7b, 0xbf, 0xc4, 0x12, 0xf7, + 0xbf, 0x7b, 0xbe, 0xc5, 0x39, 0xa3, 0xbf, 0x17, 0x9b, 0xfd, 0xbd, 0xc5, + 0xb8, 0xf2, 0x4c, 0xed, 0xec, 0x93, 0x00, 0x1c, 0xf8, 0x05, 0x00, 0x1c, + 0x14, 0x04, 0xff, 0xcc, 0x8b, 0x52, 0xf6, 0xeb, 0x6b, 0xeb, 0x9e, 0x6b, + 0xbd, 0x7c, 0xbd, 0x1b, 0xf0, 0xdf, 0xbd, 0xc5, 0xd5, 0xf2, 0xfd, 0x74, + 0xe9, 0xbf, 0xe9, 0xb7, 0xff, 0x1f, 0xb1, 0xfb, 0x9e, 0x6b, 0x9d, 0x7c, + 0x9c, 0x1b, 0xf0, 0xdf, 0xbc, 0xc4, 0x26, 0xf4, 0x99, 0xed, 0xbf, 0x7c, + 0xbe, 0xc5, 0x2a, 0xf4, 0xff, 0xcd, 0xbf, 0x5c, 0xfb, 0xed, 0x00, 0x1c, + 0xce, 0x03, 0xf6, 0xeb, 0x6b, 0xeb, 0x9e, 0x6b, 0xff, 0x7c, 0x7d, 0xed, + 0x9f, 0x7b, 0xff, 0x1b, 0xfe, 0xdf, 0xb9, 0xbf, 0x79, 0xc4, 0x37, 0x93, + 0x9f, 0x5b, 0xff, 0x1f, 0x40, 0xee, 0x9f, 0x7b, 0x9c, 0x1b, 0xbf, 0xdf, + 0x33, 0x8b, 0xbf, 0xc4, 0x06, 0xf7, 0xff, 0xcf, 0xff, 0x1f, 0xf3, 0xf3, + 0xfc, 0x15, 0xd0, 0xfd, 0xf3, 0x9b, 0xfd, 0xf2, 0x45, 0xcc, 0x9e, 0xbc, + 0xf3, 0x9b, 0x24, 0xf6, 0x9e, 0x7b, 0x9c, 0x1b, 0xc7, 0xcf, 0x5b, 0xc4, + 0x9e, 0x5b, 0xfe, 0xcf, 0xfe, 0xce, 0xff, 0x1f, 0xd2, 0xeb, 0x58, 0xf8, + 0xfe, 0x6b, 0xbf, 0x77, 0xfc, 0x15, 0xcc, 0xfe, 0x73, 0x9b, 0x2f, 0xf0, + 0x93, 0xee, 0x9f, 0x7c, 0x3f, 0xc4, 0x33, 0xf4, 0x94, 0xee, 0xfe, 0xcd, + 0xbf, 0x4c, 0x00, 0x1c, 0x06, 0x04, 0x37, 0xf8, 0xff, 0xcf, 0xff, 0x1f, + 0x18, 0xf4, 0xfc, 0x15, 0x16, 0xfd, 0xf3, 0x9b, 0x7c, 0x92, 0x58, 0xf2, + 0x5f, 0xee, 0x9e, 0x72, 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, 0x37, 0xff, + 0x9e, 0x52, 0x97, 0xb4, 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0xeb, 0xff, + 0x9c, 0x5a, 0x9e, 0x7a, 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, + 0x9e, 0x5a, 0x9e, 0x6b, 0xbf, 0x7c, 0xbd, 0x1b, 0xe0, 0xdf, 0x9f, 0x6a, + 0xc6, 0xef, 0xb2, 0xbd, 0x3b, 0x97, 0x37, 0x93, 0x9f, 0x4a, 0x9d, 0x72, + 0x78, 0xc4, 0x77, 0xc4, 0x57, 0xc4, 0x9d, 0x52, 0x9e, 0x6b, 0x9f, 0x7c, + 0xab, 0xc4, 0xad, 0xf2, 0xa6, 0xc4, 0x98, 0xf4, 0x9c, 0x7a, 0x9c, 0x1b, + 0x83, 0xcf, 0x5c, 0xc4, 0x9c, 0x5a, 0x9e, 0xf8, 0xff, 0x1f, 0x25, 0xf1, + 0xbc, 0xc7, 0x14, 0xf3, 0x58, 0xef, 0x21, 0xa2, 0xff, 0xce, 0x9f, 0x79, + 0xce, 0xd6, 0x3b, 0x97, 0x9f, 0x59, 0xff, 0xcf, 0xff, 0x1f, 0xa7, 0xfc, + 0x07, 0xcf, 0xf0, 0xfb, 0xa3, 0xb6, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xdf, + 0x3b, 0xff, 0xff, 0xdf, 0x4b, 0xfe, 0xff, 0xdf, 0x9b, 0xff, 0xff, 0xdf, + 0x47, 0xfe, 0xff, 0xdf, 0x00, 0xe0, 0x03, 0x00, 0xff, 0x1f, 0x4f, 0xfc, + 0x9e, 0x72, 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, 0x73, 0xff, 0x9e, 0x52, + 0x97, 0xb4, 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0xc7, 0xff, 0x9c, 0x5a, + 0x9e, 0x7a, 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5a, + 0x9f, 0x6a, 0xb4, 0xec, 0x37, 0x97, 0x50, 0xc4, 0x4f, 0xc4, 0x9f, 0x4a, + 0x9d, 0x72, 0x78, 0xc4, 0x77, 0xc4, 0x57, 0xc4, 0x9d, 0x52, 0xf4, 0xcf, + 0xff, 0xce, 0xf7, 0xcd, 0x5a, 0xec, 0xff, 0x1f, 0x58, 0xfc, 0xfa, 0x1b, + 0xd6, 0xff, 0xff, 0xce, 0xbc, 0xec, 0xff, 0x1f, 0xf6, 0xf0, 0xbf, 0xc7, + 0x0e, 0xf5, 0xfa, 0x27, 0xd5, 0xff, 0xf2, 0xce, 0xa1, 0xa2, 0xff, 0x1f, + 0xa2, 0xf0, 0x15, 0xf9, 0x9f, 0x7b, 0xbe, 0xc4, 0xbf, 0xf2, 0x44, 0xed, + 0x9e, 0x7a, 0xbc, 0x1b, 0xe0, 0xdf, 0xd2, 0xc5, 0xeb, 0xf4, 0xab, 0xc5, + 0x61, 0xf2, 0x9f, 0x7a, 0xff, 0xdc, 0x33, 0x8b, 0xfd, 0xce, 0x3b, 0x9b, + 0x9f, 0x5a, 0xf4, 0xf4, 0xab, 0xc5, 0x48, 0xf2, 0xa6, 0xc5, 0x4a, 0xf2, + 0xae, 0xc5, 0xbf, 0x17, 0xea, 0xfd, 0xf0, 0xcf, 0xff, 0xce, 0xff, 0xcd, + 0xff, 0x1f, 0xcd, 0xfa, 0x30, 0xed, 0x9e, 0x79, 0x7f, 0xc4, 0x9e, 0x59, + 0x9e, 0x72, 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, 0x37, 0xff, 0x9e, 0x52, + 0x97, 0xb4, 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0xc7, 0xff, 0x9c, 0x5a, + 0x9e, 0x7a, 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5a, + 0x9f, 0x79, 0x3f, 0xc4, 0x96, 0xf6, 0xf3, 0xcd, 0x9f, 0x6a, 0xc0, 0xee, + 0xb2, 0xbd, 0x3b, 0x97, 0x37, 0x93, 0x9f, 0x4a, 0x9d, 0x72, 0x78, 0xc4, + 0x77, 0xc4, 0x57, 0xc4, 0x9d, 0x52, 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, + 0xf4, 0xff, 0x9b, 0x5a, 0xff, 0xcc, 0x9f, 0x5a, 0x2d, 0xf9, 0x9e, 0x7b, + 0x9c, 0x1b, 0xc7, 0xcf, 0x9e, 0x5b, 0xfe, 0xcf, 0xff, 0xce, 0xff, 0x1f, + 0xbe, 0xec, 0x44, 0xf9, 0x8b, 0xee, 0xff, 0xce, 0xbf, 0x7c, 0x80, 0xd6, + 0x7b, 0x93, 0xbf, 0x5c, 0x4b, 0xf9, 0x9e, 0x7b, 0x9c, 0x1b, 0xc7, 0xcf, + 0x5c, 0xc4, 0x9e, 0x5b, 0xfc, 0xf8, 0x53, 0xee, 0x9f, 0x5a, 0x15, 0xa3, + 0xbf, 0x78, 0xc0, 0xce, 0xb5, 0x9b, 0x7a, 0xf2, 0x7b, 0x9b, 0x9a, 0xf2, + 0xa0, 0xc5, 0x4e, 0xf2, 0xd0, 0xcc, 0x35, 0x9b, 0x74, 0xf2, 0xbe, 0x7a, + 0xbd, 0x1b, 0xe0, 0xdf, 0xab, 0xc5, 0xf9, 0xf3, 0xf0, 0xcf, 0xff, 0xce, + 0xff, 0xcd, 0xff, 0x1f, 0x28, 0xfb, 0x3d, 0xee, 0x9e, 0x72, 0x9c, 0x1b, + 0x03, 0xcc, 0x9c, 0x13, 0x37, 0xff, 0x9e, 0x52, 0x97, 0xb4, 0x9c, 0x1b, + 0x83, 0xcf, 0x9c, 0x13, 0xc7, 0xff, 0x9c, 0x5a, 0x9e, 0x7a, 0x9c, 0x1b, + 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5a, 0x9f, 0x79, 0x3f, 0xc4, + 0xc1, 0xf2, 0xef, 0xcd, 0x9f, 0x6a, 0xcc, 0xef, 0xb2, 0xbd, 0x3b, 0x97, + 0x37, 0x93, 0x9f, 0x4a, 0x9d, 0x72, 0x78, 0xc4, 0x77, 0xc4, 0x57, 0xc4, + 0x9d, 0x52, 0x7e, 0xf9, 0x51, 0xef, 0x21, 0xa2, 0x9f, 0x79, 0x9c, 0x13, + 0xce, 0xff, 0x9f, 0x59, 0xfd, 0xcf, 0xff, 0x1f, 0x90, 0xfd, 0x9e, 0x72, + 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, 0x73, 0xff, 0x9e, 0x52, 0x97, 0xb4, + 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0xf3, 0xff, 0x9c, 0x5a, 0x9e, 0x7a, + 0x9c, 0x1b, 0xe0, 0xcf, 0xf5, 0xfb, 0xff, 0xff, 0x00, 0xe0, 0x03, 0x00, + 0xa3, 0xff, 0xff, 0xdf, 0x17, 0xf1, 0xff, 0xff, 0x9b, 0xff, 0xff, 0xdf, + 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5a, 0x9f, 0x6a, 0xcf, 0xec, 0x1f, 0xcd, + 0x3b, 0x97, 0xb6, 0xbd, 0x37, 0x93, 0x9f, 0x4a, 0x9d, 0x72, 0x78, 0xc4, + 0x77, 0xc4, 0x58, 0xc4, 0x9d, 0x52, 0xbe, 0x79, 0x7f, 0xc5, 0x9c, 0x1b, + 0xe0, 0xcf, 0xbe, 0x59, 0x5d, 0xc4, 0xff, 0x15, 0x40, 0xfe, 0x9b, 0x5a, + 0xff, 0x1f, 0x59, 0xfd, 0x9e, 0x72, 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, + 0x73, 0xff, 0x9e, 0x52, 0x97, 0xb4, 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, + 0xe7, 0xff, 0x9c, 0x5a, 0x9e, 0x7a, 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, + 0xf4, 0xff, 0x9e, 0x5a, 0x9f, 0x6a, 0xc3, 0xed, 0x1f, 0xcd, 0x3b, 0x97, + 0xb6, 0xbd, 0x37, 0x93, 0x9f, 0x4a, 0x9d, 0x72, 0x78, 0xc4, 0x77, 0xc4, + 0x58, 0xc4, 0x9d, 0x52, 0x0a, 0xf9, 0xee, 0x7a, 0xb0, 0xc7, 0x63, 0xf3, + 0xfe, 0x15, 0x47, 0xf4, 0xff, 0xcd, 0xff, 0x1f, 0xa2, 0xf1, 0xcc, 0xed, + 0x81, 0xa6, 0xfe, 0x7c, 0x5f, 0xc7, 0xdf, 0x3b, 0xdd, 0xd7, 0x7d, 0xc5, + 0xbe, 0x5c, 0xdb, 0xd9, 0xbd, 0x74, 0x39, 0x1b, 0x00, 0xdc, 0xbd, 0x1b, + 0x00, 0xcc, 0x67, 0x93, 0xbd, 0x54, 0xbf, 0x7c, 0x3f, 0xc5, 0x9f, 0x17, + 0x02, 0x02, 0xff, 0xcd, 0xf8, 0xd5, 0xf7, 0x97, 0xfe, 0x5c, 0x9c, 0x7e, + 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0xd7, 0xff, 0x9c, 0x5e, 0xff, 0x15, + 0x4c, 0xfe, 0xff, 0x1f, 0x50, 0xf0, 0x32, 0xcf, 0xff, 0x1f, 0xa5, 0xfd, + 0xff, 0x17, 0x15, 0x02, 0xfe, 0xcf, 0xff, 0x1f, 0x36, 0xf8, 0xff, 0x17, + 0x1a, 0x02, 0xff, 0xcf, 0xff, 0x1f, 0xb3, 0xf2, 0xff, 0x17, 0x1f, 0x02, + 0x00, 0x1c, 0x25, 0x06, 0xfd, 0xcc, 0x6b, 0x52, 0x9a, 0x23, 0xd4, 0xff, + 0xff, 0x17, 0x27, 0x02, 0x45, 0xcc, 0xf3, 0x9b, 0xab, 0xf7, 0x9e, 0x7b, + 0x9c, 0x1b, 0xc7, 0xcf, 0x9c, 0x13, 0xe7, 0xff, 0x9e, 0x5b, 0xdd, 0xf9, + 0x4e, 0xee, 0x9e, 0x7a, 0x9c, 0x1b, 0xe0, 0xdf, 0xd0, 0xc4, 0xf7, 0xf3, + 0x9f, 0x7a, 0xff, 0xdc, 0x33, 0x8b, 0xfb, 0xcd, 0x37, 0x9b, 0x9f, 0x5a, + 0x26, 0xf3, 0x8f, 0x7a, 0x9c, 0x1b, 0xfb, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, + 0x37, 0xee, 0x9f, 0x17, 0x38, 0x02, 0x9e, 0x79, 0x9c, 0x1b, 0xe0, 0xdf, + 0xb0, 0xc4, 0x1e, 0xf3, 0xaf, 0xc4, 0x9f, 0x17, 0x40, 0x02, 0xff, 0xcf, + 0xff, 0x1f, 0xff, 0xf5, 0xfc, 0x15, 0x40, 0xfe, 0xf3, 0x9b, 0x9f, 0x17, + 0x48, 0x02, 0x81, 0xa1, 0xbc, 0x7c, 0xdd, 0x1b, 0xfb, 0xdf, 0xbf, 0xc6, + 0x9f, 0x17, 0x4f, 0x02, 0x5d, 0xc5, 0xdf, 0x59, 0xfa, 0xcf, 0xbc, 0x5c, + 0xfe, 0xce, 0xff, 0x1f, 0xe0, 0xed, 0xff, 0x15, 0x65, 0xfd, 0xff, 0x1f, + 0xa8, 0xf0, 0xff, 0x17, 0x5c, 0x02, 0xbe, 0x79, 0xfe, 0xdd, 0x77, 0x8b, + 0xfe, 0xc5, 0x48, 0xf3, 0x4d, 0xef, 0xbf, 0x7a, 0xff, 0xdd, 0x77, 0x8b, + 0xfb, 0xce, 0x7b, 0x9b, 0xbf, 0x5a, 0x9f, 0x17, 0x6a, 0x02, 0x9f, 0x5a, + 0x00, 0x1c, 0xf9, 0x05, 0xff, 0x17, 0x6f, 0x02, 0x9e, 0x7b, 0x9c, 0x1b, + 0xc7, 0xcf, 0x5a, 0xc4, 0x9e, 0x5b, 0xff, 0x17, 0x2f, 0x02, 0xfa, 0x1b, + 0xef, 0xff, 0xfe, 0xce, 0xb8, 0xef, 0xff, 0x1f, 0x9a, 0xf2, 0xbf, 0xc7, + 0x9c, 0xf4, 0xee, 0x7a, 0xa3, 0xf8, 0xef, 0xcd, 0x67, 0xf9, 0xff, 0xff, + 0x00, 0xe0, 0x03, 0x00, 0xa3, 0xff, 0xff, 0xdf, 0x6f, 0xf1, 0xff, 0xff, + 0xc1, 0xa2, 0xfe, 0x7e, 0xff, 0x1b, 0xf9, 0xdf, 0xbd, 0xc7, 0xa1, 0xf5, + 0xff, 0xcd, 0xbf, 0x5a, 0xbe, 0x72, 0xbd, 0x1b, 0x03, 0xcc, 0xbd, 0x13, + 0x37, 0xff, 0xbe, 0x52, 0xb7, 0xb5, 0xbd, 0x1b, 0x83, 0xcf, 0x9c, 0x1b, + 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0xbd, 0x13, 0xc7, 0xff, 0xbc, 0x5a, + 0x9e, 0x5a, 0x9f, 0x7e, 0x3f, 0xc4, 0x78, 0xf3, 0xef, 0xcc, 0xbf, 0x6a, + 0xdd, 0xec, 0x92, 0xbc, 0x7b, 0x97, 0x34, 0xf9, 0x3e, 0xec, 0xa8, 0xf9, + 0xf3, 0xcd, 0x3c, 0xf9, 0xb0, 0xce, 0xb5, 0x9b, 0xc6, 0xf3, 0xa0, 0xcc, + 0x35, 0x9b, 0x63, 0xf5, 0xbe, 0x78, 0xb3, 0xcc, 0x35, 0x9b, 0x67, 0xf5, + 0xbd, 0x78, 0x9c, 0x78, 0x8f, 0xbc, 0xa7, 0xbd, 0x73, 0x93, 0x9a, 0x78, + 0x73, 0x93, 0x9b, 0x78, 0x97, 0xbc, 0x73, 0x93, 0x89, 0xed, 0x35, 0x9b, + 0x51, 0xf3, 0xd9, 0xa0, 0xf2, 0xcf, 0xfb, 0xcd, 0xff, 0x1f, 0x99, 0xfc, + 0x2e, 0xed, 0x70, 0xf9, 0x9e, 0x78, 0xc4, 0xce, 0xb1, 0x9b, 0x9c, 0xf3, + 0x71, 0x9b, 0x81, 0xf5, 0xcd, 0xa3, 0xf2, 0xcf, 0xfd, 0xcd, 0xff, 0x1f, + 0xa6, 0xfc, 0x21, 0xa2, 0x7d, 0xf9, 0x9e, 0x78, 0xb4, 0xc4, 0x8b, 0xf5, + 0x9d, 0x78, 0xd1, 0x1b, 0xde, 0xff, 0x9f, 0x5e, 0x21, 0xa2, 0xf9, 0xcf, + 0xff, 0xcd, 0xff, 0x1f, 0xb4, 0xfc, 0x9e, 0x79, 0x7f, 0xc4, 0x9e, 0x59, + 0x8d, 0xf9, 0xbe, 0x7a, 0xbd, 0x1b, 0xe0, 0xdf, 0xad, 0xc5, 0xa0, 0xf3, + 0x9e, 0x78, 0x49, 0xce, 0xb1, 0x9b, 0xab, 0xf3, 0x48, 0xce, 0xb1, 0x9b, + 0xa1, 0xf5, 0xcd, 0xa3, 0xf5, 0xcf, 0xfc, 0xcd, 0xff, 0x1f, 0xc9, 0xfc, + 0x21, 0xa2, 0xa0, 0xf9, 0xbe, 0x78, 0x00, 0xcc, 0x35, 0x9b, 0xaf, 0xf1, + 0xbf, 0x79, 0xf7, 0xcf, 0xa0, 0x93, 0xff, 0x1f, 0xd4, 0xfc, 0x21, 0xa2, + 0xab, 0xf9, 0xff, 0xcc, 0x9f, 0x5a, 0x00, 0x1c, 0x98, 0x06, 0xdb, 0xf8, + 0xd1, 0x1b, 0xde, 0xff, 0xc4, 0xcc, 0x9f, 0x5e, 0xfe, 0xcd, 0xf0, 0xcf, + 0xff, 0x1f, 0xe3, 0xfc, 0xff, 0x17, 0x15, 0x02, 0x52, 0xee, 0x9f, 0x5a, + 0x00, 0x1c, 0xa7, 0x06, 0xff, 0x17, 0x1d, 0x03, 0xfc, 0xcf, 0xff, 0x1f, + 0xdc, 0xf6, 0x66, 0xcc, 0x9e, 0xbc, 0xf3, 0x9b, 0xf5, 0xf3, 0xff, 0xce, + 0xff, 0xcd, 0xfc, 0xcf, 0xff, 0x1f, 0xf7, 0xfc, 0xff, 0x17, 0x2b, 0x03, + 0xf3, 0xcc, 0x85, 0xf8, 0xff, 0x15, 0x60, 0xfe, 0xff, 0x1f, 0xd1, 0xfe, + 0xff, 0x17, 0x33, 0x03, 0xbd, 0x78, 0x9c, 0x78, 0xb7, 0xbd, 0x37, 0x93, + 0xd1, 0x1b, 0xde, 0xff, 0x9f, 0x56, 0xfb, 0xcf, 0xff, 0xcd, 0x21, 0xa2, + 0xff, 0x1f, 0x0d, 0xfd, 0x9f, 0x79, 0x3f, 0xc4, 0xe5, 0xf5, 0x9e, 0x79, + 0x5f, 0xc4, 0x9e, 0x59, 0xe9, 0xf9, 0xcd, 0xa3, 0xf6, 0xcf, 0xfc, 0xcd, + 0xff, 0x1f, 0x19, 0xfd, 0x21, 0xa2, 0xf0, 0xf9, 0x11, 0x1b, 0xde, 0xff, + 0x9f, 0x58, 0xfe, 0xe4, 0xf0, 0x93, 0x9f, 0x47, 0x00, 0x1c, 0x21, 0x0a, + 0xdd, 0x79, 0xbc, 0x79, 0xaf, 0xbd, 0xc7, 0xbe, 0xb7, 0x93, 0xba, 0x79, + 0xb7, 0x93, 0xbb, 0x79, 0xb7, 0xbd, 0x9f, 0x67, 0x7b, 0x93, 0x9f, 0x6c, + 0x35, 0x9b, 0xe5, 0xf3, 0xfa, 0xcf, 0xa0, 0x93, 0xff, 0xcd, 0xff, 0x1f, + 0x36, 0xfd, 0x3c, 0xef, 0xff, 0x17, 0x0d, 0x02, 0x00, 0xe0, 0x03, 0x00, + 0x9b, 0xff, 0xff, 0xdf, 0xfe, 0xfe, 0xfe, 0xf9, 0xa3, 0xff, 0xff, 0xdf, + 0x00, 0x1c, 0xc7, 0x08, 0x6f, 0xcc, 0x99, 0xbc, 0x3d, 0x9b, 0xb1, 0xf4, + 0xff, 0x1f, 0x31, 0xff, 0xb4, 0xf8, 0xfe, 0xcc, 0x9f, 0x58, 0x8f, 0x7a, + 0x5d, 0xc4, 0x8f, 0x5a, 0x1d, 0xf8, 0xff, 0xff, 0x2c, 0xeb, 0xde, 0xeb, + 0xff, 0x1f, 0xf7, 0xf6, 0xff, 0x47, 0x4e, 0xee, 0xff, 0xcf, 0xff, 0x1f, + 0x48, 0xf7, 0x9f, 0x7a, 0xfe, 0xc4, 0xc4, 0x92, 0xb3, 0xf3, 0xbd, 0xc4, + 0xc8, 0xf3, 0xbc, 0xc4, 0xce, 0xf3, 0xfc, 0xcf, 0xff, 0x1f, 0x53, 0xf7, + 0xb8, 0xbf, 0x9d, 0xbf, 0x92, 0xa5, 0xff, 0xa4, 0xff, 0x3b, 0xbf, 0xf7, + 0x9d, 0xbf, 0x95, 0xac, 0x9c, 0x3b, 0xde, 0x7b, 0x97, 0xb4, 0xba, 0xee, + 0x9c, 0x1b, 0x01, 0xde, 0x93, 0xa5, 0xbf, 0x7c, 0x9e, 0x7c, 0x7b, 0x83, + 0xdc, 0xbc, 0x9e, 0x3b, 0xdc, 0xf7, 0xdf, 0x6b, 0x9b, 0xa4, 0xaf, 0xb5, + 0x97, 0xa4, 0x9f, 0x4b, 0x9f, 0x7a, 0x21, 0xef, 0x9c, 0xbc, 0x93, 0xa1, + 0xdf, 0x74, 0xc4, 0x93, 0xde, 0xbe, 0xff, 0xcd, 0x00, 0x1c, 0x8b, 0x09, + 0x9f, 0x7a, 0x9c, 0xbc, 0x33, 0xa1, 0xff, 0x6b, 0x9e, 0x69, 0xf3, 0x83, + 0xf0, 0xb7, 0xfe, 0xeb, 0x6c, 0xeb, 0x7d, 0xcd, 0xbd, 0xbd, 0xf7, 0x9b, + 0x32, 0xf0, 0xdf, 0x6b, 0xb5, 0xb6, 0x77, 0x8b, 0xf0, 0xcf, 0x7f, 0x9b, + 0xe9, 0xf3, 0xee, 0xef, 0xbf, 0x3b, 0xdd, 0xf7, 0xfe, 0x7d, 0xbf, 0x7d, + 0x3c, 0xbf, 0xb7, 0x83, 0xf9, 0x3b, 0xdf, 0xf7, 0xd8, 0xb6, 0xfb, 0xa7, + 0xff, 0x4b, 0x27, 0xf8, 0xdf, 0x67, 0xb5, 0xb6, 0x77, 0x8b, 0xf6, 0xcf, + 0x7f, 0x9b, 0xfa, 0xf3, 0xf7, 0xef, 0x12, 0xf8, 0xf0, 0xcd, 0x15, 0xf8, + 0xf6, 0xcd, 0xf9, 0xef, 0x17, 0xf8, 0xff, 0xff, 0x77, 0xff, 0xff, 0xdf, + 0xfb, 0xff, 0xff, 0xdf, 0x53, 0xb6, 0xff, 0xff, 0x73, 0xb6, 0xff, 0xff, + 0x87, 0xb6, 0xff, 0xff, 0x9d, 0xef, 0xff, 0x5c, 0xc3, 0x87, 0xff, 0xff, + 0x77, 0xff, 0xff, 0xdf, 0xc3, 0x87, 0xff, 0xff, 0xff, 0x8b, 0xfc, 0xc7, + 0xbb, 0x8b, 0x77, 0x8b, 0xf9, 0xf7, 0x9b, 0xef, 0xfc, 0x3b, 0xdf, 0xf7, + 0xdf, 0x5f, 0xbe, 0x5f, 0xc3, 0x87, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, + 0x2f, 0xeb, 0x9f, 0x7f, 0xe0, 0xcd, 0x37, 0x9b, 0xe8, 0xf7, 0x81, 0xcd, + 0x37, 0x9b, 0xf3, 0xf7, 0x21, 0xcd, 0x37, 0x9b, 0xea, 0xf7, 0xdc, 0x1b, + 0x20, 0xef, 0xdd, 0xae, 0xe1, 0xde, 0xbb, 0x8b, 0xff, 0x1f, 0x0f, 0xf0, + 0x6f, 0xeb, 0xdc, 0x1b, 0xe0, 0xef, 0xdb, 0xae, 0xfd, 0xde, 0xbb, 0x8b, + 0xff, 0x1f, 0x17, 0xf0, 0x6f, 0xeb, 0xfd, 0xce, 0xff, 0x1f, 0x1b, 0xf0, + 0x6f, 0xeb, 0xdc, 0x1b, 0x80, 0xef, 0xdc, 0xae, 0xf7, 0xde, 0xbb, 0x8b, + 0xff, 0x1f, 0x23, 0xf0, 0x6f, 0xeb, 0xff, 0xff, 0x2f, 0xeb, 0xff, 0x1f, + 0x3c, 0xec, 0xff, 0x1f, 0x48, 0xf0, 0xff, 0x1f, 0xd2, 0xf2, 0xff, 0x1f, + 0xdc, 0xea, 0xff, 0x1f, 0x60, 0xef, 0xff, 0x1f, 0x28, 0xea, 0xff, 0x1f, + 0x20, 0xf3, 0xff, 0x1f, 0x2a, 0xea, 0x6f, 0xeb, 0x2f, 0xeb, 0xff, 0x1f, + 0x4a, 0xea, 0x6f, 0xeb, 0xfe, 0xcd, 0x9d, 0xef, 0xbf, 0x5c, 0xc3, 0x87, + 0x75, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0xf9, 0xef, 0xff, 0xcc, 0x9e, 0x57, + 0x9f, 0x5f, 0xfe, 0xce, 0xbb, 0xef, 0xfc, 0xdf, 0xff, 0x1f, 0x75, 0xf4, + 0x6f, 0xeb, 0xff, 0xff, 0x75, 0xff, 0xff, 0xdf, 0x63, 0xe3, 0xff, 0xff, + 0x9d, 0xef, 0xfe, 0x54, 0xc3, 0x87, 0xff, 0xff, 0x75, 0xff, 0xff, 0xdf, + 0xfe, 0x8b, 0xbf, 0xc7, 0x9a, 0xef, 0xfb, 0xf7, 0xbf, 0xcd, 0xba, 0x5c, + 0xc3, 0x87, 0xff, 0xcd, 0x80, 0xd5, 0xba, 0x5c, 0xc3, 0x87, 0xff, 0xff, + 0x75, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xfe, 0x74, 0xc3, 0x87, 0xff, 0xff, + 0x75, 0xff, 0xff, 0xdf, 0x2b, 0xeb, 0xd6, 0xeb, 0xbf, 0xc6, 0x38, 0x93, + 0x7f, 0x8a, 0xf6, 0x8a, 0xf6, 0xf3, 0xa7, 0xed, 0xfb, 0x7d, 0xac, 0x93, + 0x70, 0x93, 0xff, 0x1f, 0x46, 0xf4, 0xf6, 0xeb, 0x6b, 0xeb, 0xef, 0xcf, + 0x00, 0x1c, 0x97, 0x0a, 0xbc, 0x92, 0xff, 0xcf, 0xff, 0x1f, 0x49, 0xf8, + 0xe3, 0xc1, 0xbc, 0x93, 0xe7, 0xf7, 0x8f, 0xed, 0x3c, 0x3b, 0xbc, 0xf7, + 0x9f, 0x6c, 0xf3, 0x87, 0xfe, 0xcc, 0x9f, 0x5a, 0xbe, 0x8b, 0xfc, 0x15, + 0xd9, 0xfd, 0xb3, 0x9b, 0xfd, 0xf7, 0xb0, 0x93, 0x9a, 0xbe, 0x9b, 0xa4, + 0xb9, 0xbc, 0x97, 0xa4, 0x9e, 0x3b, 0xde, 0xf7, 0x9c, 0xbe, 0x9a, 0xa4, + 0x8f, 0xac, 0x9e, 0x5a, 0x3c, 0xed, 0xfb, 0x79, 0xac, 0x93, 0x68, 0x93, + 0xff, 0x1f, 0x6f, 0xf4, 0xf6, 0xeb, 0x6b, 0xeb, 0xe7, 0xcc, 0x9f, 0x5a, + 0xff, 0x1f, 0xb7, 0xfe, 0x9f, 0x7f, 0xb3, 0xcd, 0x71, 0x9b, 0xdc, 0xf3, + 0xc0, 0xce, 0xb1, 0x9b, 0xdf, 0xf3, 0xbe, 0x5a, 0x26, 0xee, 0x13, 0xf8, + 0xe7, 0xcc, 0x9f, 0x5a, 0xff, 0xcc, 0xb7, 0xd4, 0x9e, 0x5a, 0x29, 0xee, + 0x1a, 0xf8, 0xe7, 0xcc, 0x9f, 0x5a, 0xff, 0xcc, 0xb6, 0xd4, 0x9e, 0x5a, + 0x2d, 0xee, 0x21, 0xf8, 0xff, 0x1f, 0xd1, 0xfe, 0x9f, 0x7f, 0xd7, 0xcd, + 0x71, 0x9b, 0x9f, 0x5a, 0x5c, 0xf3, 0x37, 0x9b, 0x69, 0xf3, 0xe8, 0xd4, + 0xfe, 0xcd, 0x37, 0x9b, 0x2f, 0xf0, 0x9e, 0x7f, 0x9e, 0x5a, 0x32, 0xf8, + 0xc7, 0xcc, 0x9f, 0x5a, 0xf5, 0xcc, 0x9e, 0x5a, 0xff, 0x1f, 0xe5, 0xfe, + 0x9f, 0x7f, 0xbf, 0xc4, 0x6a, 0xf3, 0xff, 0xdf, 0x9d, 0x5a, 0x9f, 0x7f, + 0x9c, 0x5a, 0x3c, 0xee, 0x40, 0xf8, 0xfe, 0xe1, 0xe4, 0x93, 0x00, 0x1c, + 0xba, 0x0b, 0xff, 0xce, 0xa4, 0xd6, 0xba, 0x69, 0x99, 0x69, 0xdf, 0x5a, + 0xf7, 0xce, 0xde, 0x5a, 0xc7, 0xb5, 0xdd, 0x5a, 0xcf, 0xb5, 0xdc, 0x5a, + 0xba, 0x5a, 0xd7, 0xb5, 0xa7, 0xb4, 0xb9, 0x5a, 0xaf, 0xb4, 0xb8, 0x5a, + 0x96, 0x5a, 0xb7, 0xb4, 0xff, 0xcc, 0xdb, 0x5a, 0xb7, 0x5a, 0x95, 0x5a, + 0x94, 0x5a, 0x93, 0x5a, 0x2c, 0xef, 0x5f, 0xf8, 0xc7, 0xcc, 0x9f, 0x5a, + 0xc4, 0xcc, 0x9e, 0x5a, 0xfd, 0xcc, 0x9d, 0x5a, 0xff, 0xcc, 0xbb, 0xd4, + 0x9c, 0x5a, 0x31, 0xef, 0x6a, 0xf8, 0x00, 0x1c, 0x90, 0x01, 0xf7, 0xe6, + 0xf2, 0xc1, 0xff, 0x4e, 0x97, 0xf7, 0xfb, 0xcc, 0x9f, 0x5a, 0x9f, 0x6e, + 0x9e, 0x5a, 0x37, 0xef, 0xff, 0xcd, 0xf3, 0xcf, 0xff, 0x1f, 0xf1, 0xfe, + 0x7a, 0xf8, 0xfc, 0xcc, 0xb2, 0xc1, 0x9f, 0x5a, 0x1d, 0xa2, 0x90, 0xf3, + 0xfe, 0xcf, 0x3d, 0xef, 0xdf, 0x47, 0xfa, 0xfb, 0x75, 0xff, 0xff, 0xdf, + 0x33, 0xb6, 0xff, 0xff, 0xff, 0x1f, 0xef, 0xf8, 0xdf, 0x67, 0xfe, 0x71, + 0xfa, 0xa7, 0xf8, 0xbf, 0x00, 0x1c, 0xf3, 0x0b, 0xff, 0xcd, 0x81, 0xd5, + 0x7e, 0x9b, 0xfd, 0xf3, 0xf4, 0x93, 0x80, 0xcd, 0xf6, 0x9b, 0x3c, 0x93, + 0xfd, 0xf3, 0x80, 0xcc, 0xaf, 0xed, 0xbf, 0x7d, 0xbf, 0xc5, 0xf6, 0xf3, + 0xdb, 0xc4, 0x8f, 0xf3, 0xff, 0xcd, 0xfc, 0xd5, 0x72, 0x9b, 0xfc, 0xf3, + 0xff, 0xcc, 0xfb, 0xd4, 0x9f, 0x47, 0xff, 0x1f, 0x72, 0xfb, 0xbe, 0xc7, + 0x9f, 0x67, 0xb3, 0xf3, 0x99, 0x59, 0x33, 0x8b, 0x9f, 0x58, 0xaf, 0xf8, + 0xfd, 0xcc, 0x9f, 0x5a, 0xff, 0x1f, 0x9d, 0xf6, 0xfe, 0x5a, 0xff, 0xcf, + 0xff, 0x1f, 0x87, 0xf1, 0x3d, 0xed, 0xb9, 0xf8, 0xe7, 0xcc, 0x9f, 0x5a, + 0xf4, 0xcc, 0x9e, 0x5a, 0x20, 0xee, 0xbf, 0xf8, 0xb7, 0xcd, 0x71, 0x9b, + 0xcd, 0xf3, 0xa7, 0xcd, 0x71, 0x9b, 0xd2, 0xf3, 0xc7, 0xcd, 0x71, 0x9b, + 0xc9, 0xf4, 0x9c, 0x7f, 0x9c, 0x5a, 0x9d, 0x7f, 0x9d, 0x5a, 0x9e, 0x7f, + 0x9d, 0xf8, 0xff, 0xcc, 0x98, 0xd4, 0x9f, 0x5f, 0xc5, 0xcd, 0xff, 0xdf, + 0xbf, 0x5f, 0x9c, 0x1b, 0x67, 0xdf, 0x9a, 0xf8, 0xce, 0xcc, 0xb1, 0xc1, + 0x9f, 0x5a, 0xbf, 0xf3, 0xb0, 0xc1, 0xcb, 0xf3, 0xff, 0xcc, 0x9e, 0x5a, + 0x31, 0xee, 0x99, 0x79, 0x31, 0x8b, 0xde, 0xc4, 0xca, 0xf7, 0x9f, 0x6e, + 0x9c, 0x1b, 0x71, 0xfd, 0x9f, 0x4e, 0x97, 0xb4, 0x9d, 0x5a, 0x9f, 0x6e, + 0x9c, 0x5a, 0x76, 0xf8, 0xff, 0xcc, 0x38, 0xee, 0x9f, 0x58, 0xf1, 0xf8, + 0x9a, 0x7f, 0x9a, 0x5a, 0x9b, 0x7f, 0x9b, 0x5a, 0x2c, 0xf8, 0xbf, 0x79, + 0xbf, 0xc5, 0xf8, 0xf3, 0xbe, 0xc4, 0xc5, 0xf3, 0xff, 0xcd, 0xff, 0xd5, + 0x71, 0x9b, 0xcc, 0xf3, 0xbf, 0xc4, 0x54, 0xf4, 0xba, 0x79, 0xbf, 0xc5, + 0x57, 0xf0, 0xb5, 0x8b, 0x20, 0xc6, 0xcf, 0xf7, 0x39, 0xc5, 0xfc, 0xf3, + 0xff, 0xcc, 0xff, 0xd4, 0xff, 0xcd, 0xba, 0x59, 0x61, 0xf8, 0xfa, 0xcc, + 0x69, 0xf8, 0xfd, 0xcc, 0x9e, 0x5a, 0x9f, 0x6e, 0x9c, 0x1b, 0x0c, 0xee, + 0x9f, 0x4e, 0x2c, 0xef, 0x2e, 0xf8, 0x9f, 0x6e, 0x30, 0xf8, 0xfe, 0xcc, + 0x9e, 0x5a, 0xdf, 0x47, 0x00, 0x1c, 0x1b, 0x0b, 0x3f, 0x8b, 0x87, 0xcd, + 0x71, 0x9b, 0xdf, 0x67, 0xf6, 0xf3, 0xaf, 0xcd, 0x71, 0x9b, 0xf9, 0xf3, + 0xfc, 0x15, 0x47, 0xf4, 0x9f, 0x4e, 0x36, 0xef, 0x42, 0xf8, 0xfc, 0x15, + 0xa1, 0xf5, 0x9f, 0x4e, 0x39, 0xef, 0x47, 0xf8, 0xff, 0xcc, 0xfe, 0xd4, + 0x87, 0xf8, 0xfd, 0xcc, 0x89, 0xf8, 0xfe, 0xcc, 0x2b, 0xf8, 0xff, 0xff, + 0x95, 0xff, 0xff, 0xdf, 0x75, 0xff, 0xff, 0xdf, 0x2e, 0xeb, 0xff, 0x8a, + 0xf0, 0xcf, 0x00, 0x1c, 0xfa, 0x0b, 0xbf, 0xc7, 0xbc, 0x93, 0xfb, 0xf3, + 0xec, 0x93, 0xff, 0x1f, 0x9e, 0xed, 0x6e, 0xeb, 0x9d, 0xef, 0xf9, 0x7c, + 0xc3, 0x87, 0xff, 0xff, 0x75, 0xff, 0xff, 0xdf, 0xfe, 0xef, 0xc3, 0x87, + 0x6a, 0xff, 0xff, 0xdf, 0x2d, 0xeb, 0x8a, 0xef, 0xb8, 0x6c, 0x6a, 0xef, + 0x5f, 0xc5, 0xb8, 0x4c, 0xff, 0xca, 0xfb, 0x1b, 0xf4, 0xff, 0xff, 0xce, + 0xf3, 0xcd, 0x58, 0x5b, 0x57, 0x5b, 0x00, 0x1c, 0xea, 0x0b, 0x9b, 0x1b, + 0xe8, 0xff, 0xb0, 0xef, 0xbe, 0x4c, 0xfc, 0xcd, 0xbd, 0x5c, 0x5f, 0x5c, + 0x5e, 0x5c, 0x98, 0x7b, 0x5f, 0xc4, 0xfb, 0x1b, 0xdc, 0xff, 0xff, 0xce, + 0xb5, 0xef, 0x98, 0x5b, 0xff, 0x1f, 0x3b, 0xf6, 0xbf, 0xc7, 0xfd, 0xf3, + 0x6d, 0xeb, 0xfb, 0x27, 0xdb, 0xff, 0xea, 0xce, 0xa5, 0xa3, 0xff, 0x1f, + 0xe8, 0xf5, 0x6d, 0xeb, 0xff, 0x6f, 0xff, 0xbf, 0x6b, 0xff, 0xff, 0xdf, + 0x4b, 0xff, 0xff, 0xdf, 0x67, 0xdc, 0xff, 0xff, 0x2e, 0xeb, 0xff, 0x8a, + 0xb3, 0xc3, 0x77, 0x8b, 0xe5, 0xf3, 0xeb, 0xc3, 0xec, 0xf3, 0x89, 0xee, + 0xbe, 0x7c, 0x77, 0x8b, 0xdd, 0x7c, 0xff, 0xdd, 0x7b, 0x97, 0xdf, 0x7c, + 0xbb, 0x8b, 0xb5, 0x9b, 0xa1, 0xf3, 0xde, 0x7c, 0xfe, 0x6c, 0xbb, 0x8b, + 0xdb, 0xa7, 0x7f, 0x5e, 0xfe, 0xcf, 0xbe, 0x5c, 0x6e, 0xeb, 0x91, 0xee, + 0x7c, 0x3b, 0xbc, 0xf7, 0x9f, 0x6c, 0xf3, 0x87, 0x93, 0xee, 0x8f, 0xa4, + 0xbf, 0x7c, 0x3a, 0xc5, 0xfb, 0xf3, 0xbf, 0x6e, 0xbb, 0x54, 0x1d, 0xf8, + 0xff, 0xcf, 0x6e, 0xeb, 0xbf, 0xc5, 0x21, 0xf0, 0xbf, 0x7e, 0x98, 0xee, + 0xb9, 0x5c, 0x25, 0xf8, 0xbf, 0x76, 0x9a, 0xee, 0xba, 0x54, 0x29, 0xf8, + 0xbf, 0xc5, 0x2b, 0xf0, 0xbf, 0x7e, 0x9d, 0xee, 0xba, 0x5c, 0x2f, 0xf8, + 0xfa, 0xcc, 0x73, 0x9b, 0xf8, 0xf7, 0xfa, 0xcd, 0xf8, 0x93, 0xc2, 0xef, + 0x00, 0x1c, 0x9f, 0x0c, 0x38, 0xf8, 0xbf, 0xc5, 0x3a, 0xf0, 0x06, 0xf8, + 0xbf, 0x7e, 0x85, 0xef, 0xbf, 0xc5, 0xff, 0x3b, 0xfe, 0xfa, 0xbf, 0x7c, + 0xde, 0xbe, 0x7e, 0xc5, 0x7b, 0x93, 0xbf, 0x5c, 0x46, 0xf8, 0xbf, 0x7e, + 0x8b, 0xef, 0xbd, 0x5c, 0x4a, 0xf8, 0xbf, 0x7e, 0x8d, 0xef, 0xbf, 0xc5, + 0xbf, 0x7c, 0xff, 0x3b, 0xfe, 0xfa, 0x7f, 0xc5, 0x7b, 0x93, 0xbf, 0x5c, + 0x54, 0xf8, 0xbf, 0x76, 0x92, 0xef, 0xb7, 0xb5, 0xbc, 0x5c, 0xbf, 0x76, + 0xbb, 0x5c, 0x5b, 0xf8, 0x95, 0xef, 0xdf, 0x7e, 0xbf, 0x7c, 0xde, 0x1b, + 0xfe, 0xdf, 0xdd, 0xbe, 0x7d, 0xc5, 0x7b, 0x93, 0xbf, 0x5c, 0x65, 0xf8, + 0xfe, 0xcf, 0x6e, 0xeb, 0x9b, 0xef, 0x4d, 0xf8, 0x53, 0xff, 0xff, 0xdf, + 0xbf, 0xb5, 0xff, 0xff, 0x6b, 0xff, 0xff, 0xdf, 0x5f, 0xff, 0xff, 0xdf, + 0x2f, 0xeb, 0xde, 0xeb, 0xd1, 0x1b, 0xfd, 0xff, 0xff, 0x5e, 0xfe, 0xcd, + 0xeb, 0xcf, 0x00, 0x1c, 0x80, 0x00, 0xfe, 0xeb, 0x6f, 0xeb, 0xff, 0xff, + 0x2c, 0xeb, 0x9c, 0xec, 0x7f, 0x6c, 0xef, 0x8a, 0x9b, 0x1b, 0x7f, 0xbf, + 0xef, 0xc4, 0xda, 0xf7, 0xbf, 0xec, 0x9d, 0x3b, 0xbc, 0xf7, 0x9f, 0x6c, + 0xf3, 0x87, 0xa2, 0xed, 0xde, 0x6d, 0x81, 0xed, 0xcf, 0xb6, 0xd9, 0x5c, + 0xde, 0x6d, 0xd7, 0xb6, 0xda, 0x5c, 0xde, 0x6d, 0xdb, 0x5c, 0xbf, 0x6d, + 0xa7, 0xb5, 0xbc, 0x5c, 0xa9, 0xed, 0xbf, 0x6d, 0xaf, 0xb5, 0xbd, 0x5c, + 0xab, 0xed, 0xbf, 0x6d, 0xb7, 0xb5, 0xbe, 0x5c, 0xfa, 0xcd, 0xab, 0x54, + 0xac, 0xed, 0xb4, 0x4c, 0xbb, 0x1b, 0x8c, 0xef, 0xbf, 0x5c, 0xed, 0xed, + 0xff, 0x1f, 0x5b, 0xf7, 0x4e, 0xed, 0x7a, 0x5a, 0x6c, 0xeb, 0x93, 0xed, + 0xdf, 0x6c, 0xbe, 0x6c, 0x87, 0xb6, 0x97, 0xbc, 0x77, 0x8b, 0x73, 0x93, + 0xfe, 0x15, 0x1e, 0xfd, 0x93, 0xed, 0x7b, 0x9b, 0xbe, 0x54, 0x9a, 0xf3, + 0xff, 0xce, 0xba, 0xed, 0xff, 0x6d, 0x5f, 0x6d, 0xff, 0x3b, 0x7d, 0x8f, + 0xfa, 0x3b, 0xba, 0x8f, 0xb7, 0xbd, 0xb7, 0x92, 0x5f, 0x54, 0xfc, 0x15, + 0x09, 0xfc, 0xb3, 0x9a, 0x9d, 0xf7, 0xbc, 0xed, 0x9f, 0x55, 0xff, 0x1f, + 0x4c, 0xf8, 0xbf, 0xc7, 0x7c, 0x92, 0x98, 0xf7, 0x43, 0xee, 0xfb, 0xcc, + 0xa1, 0xee, 0x8b, 0x52, 0xb4, 0x4a, 0xfa, 0x1b, 0xd8, 0xff, 0xff, 0x1f, + 0x8a, 0xf7, 0x3a, 0x23, 0xcf, 0xff, 0xfe, 0xcf, 0x00, 0x1c, 0x69, 0x00, + 0xf4, 0xda, 0x33, 0xf8, 0xf9, 0xcf, 0xff, 0x1f, 0x68, 0xf8, 0x4a, 0xee, + 0x38, 0xf8, 0x8f, 0xee, 0xff, 0x6c, 0xf7, 0xb7, 0xdf, 0x6c, 0xff, 0xd7, + 0xbf, 0x6c, 0xff, 0x8b, 0xfe, 0x3b, 0xbe, 0x8f, 0xa7, 0xb5, 0x00, 0x1c, + 0x2a, 0x03, 0xfd, 0xcf, 0xff, 0xce, 0xff, 0xcd, 0x00, 0x1c, 0xfb, 0x00, + 0x54, 0xee, 0x4b, 0xf8, 0xfe, 0xcf, 0xff, 0xce, 0xff, 0xcd, 0x00, 0x1c, + 0x02, 0x01, 0x57, 0xee, 0x52, 0xf8, 0x9c, 0xee, 0x9f, 0x6c, 0xfc, 0x3b, + 0x7c, 0x8f, 0xbf, 0xc4, 0xe2, 0xf3, 0x5b, 0xee, 0x9f, 0x7a, 0xbc, 0xb4, + 0xbd, 0x1b, 0xf9, 0xdf, 0x5f, 0xc5, 0xbc, 0xbd, 0x9c, 0x1b, 0xc7, 0xcf, + 0x37, 0x93, 0x9f, 0x5a, 0x64, 0xf8, 0xf4, 0xcf, 0xff, 0xce, 0xff, 0xcd, + 0x00, 0x1c, 0x1b, 0x01, 0x44, 0xef, 0x6b, 0xf8, 0x87, 0xef, 0x7c, 0xf8, + 0x88, 0xef, 0x82, 0xf8, 0x89, 0xef, 0x7c, 0xf8, 0xde, 0x54, 0xfe, 0xce, + 0x64, 0xf8, 0x49, 0xef, 0x9f, 0x7a, 0xbc, 0x1b, 0xef, 0xdf, 0x9c, 0x1b, + 0xc7, 0xcf, 0x37, 0x93, 0x9f, 0x5a, 0x7d, 0xf8, 0xbf, 0xc6, 0x5f, 0xf4, + 0xff, 0x1f, 0x37, 0xf5, 0xbf, 0x9a, 0xef, 0xf3, 0xeb, 0x9b, 0x65, 0xf4, + 0xff, 0xcf, 0x00, 0x1c, 0x06, 0x03, 0x69, 0xf8, 0x56, 0xef, 0xfe, 0xcc, + 0x9a, 0x23, 0xcf, 0xff, 0xfd, 0xcf, 0x00, 0x1c, 0xc8, 0x00, 0xf4, 0xda, + 0x92, 0xf8, 0xfe, 0xcf, 0x00, 0x1c, 0x13, 0x03, 0x76, 0xf8, 0xff, 0xff, + 0xff, 0x6f, 0xff, 0xbf, 0x6b, 0xb5, 0xff, 0xff, 0x6b, 0xff, 0xff, 0xdf, + 0x43, 0xff, 0xff, 0xdf, 0x5f, 0xff, 0xff, 0xdf, 0x4b, 0xfe, 0xff, 0xdf, + 0x2b, 0xeb, 0x9f, 0x7f, 0xbc, 0x92, 0x3f, 0xc4, 0x6a, 0xf7, 0x7a, 0xec, + 0x3a, 0xec, 0x3d, 0xc4, 0xf7, 0xf3, 0x97, 0x79, 0xff, 0xdc, 0x33, 0x8b, + 0xf5, 0xcd, 0x37, 0x9b, 0x97, 0x59, 0x4b, 0xf3, 0x5e, 0xec, 0x9c, 0x6a, + 0xb9, 0x27, 0xce, 0xff, 0x33, 0x8b, 0x35, 0x9b, 0xf9, 0xf3, 0xbc, 0x6a, + 0x77, 0x8b, 0xaa, 0xcc, 0x35, 0x9b, 0x3c, 0xf3, 0x00, 0x1c, 0xaf, 0x01, + 0xbf, 0x8a, 0x91, 0xa2, 0x33, 0x8b, 0xf7, 0xc4, 0xa8, 0xf7, 0xbf, 0x7b, + 0x9c, 0xb5, 0x9c, 0x1b, 0xfa, 0xdf, 0x5e, 0xc4, 0xdc, 0xbc, 0xbd, 0x1b, + 0xc7, 0xcf, 0x7b, 0x93, 0xb4, 0x93, 0xbf, 0x5b, 0x3f, 0xc4, 0xa2, 0xf7, + 0xbe, 0x7b, 0xbd, 0x1b, 0xf8, 0xdf, 0x35, 0x9b, 0xe7, 0xf3, 0x9c, 0x1b, + 0xfb, 0xdf, 0xbf, 0xc4, 0xaf, 0xf7, 0xff, 0xcf, 0xff, 0x1f, 0xe9, 0xf3, + 0x9f, 0x7b, 0x9c, 0xb4, 0x9c, 0x1b, 0xf8, 0xdf, 0x3f, 0xc4, 0xf4, 0xf3, + 0xf4, 0xcf, 0xff, 0xce, 0xff, 0xcd, 0x00, 0x1c, 0x9c, 0x01, 0x9b, 0xed, + 0x9f, 0x7c, 0x9c, 0xb4, 0x9c, 0x1b, 0xf8, 0xdf, 0xbe, 0x7b, 0xbd, 0x1b, + 0xf8, 0xcf, 0x37, 0x93, 0x9e, 0x5b, 0x7e, 0xed, 0x9d, 0x6b, 0x9c, 0x1b, + 0x00, 0xcf, 0xb3, 0x92, 0x5d, 0x4b, 0x80, 0xee, 0x5d, 0x6b, 0xfe, 0xcf, + 0xb3, 0x96, 0xff, 0x1f, 0xa0, 0xfb, 0x9d, 0xb7, 0xff, 0xdc, 0x33, 0x8b, + 0x97, 0xbc, 0xb3, 0x92, 0x5d, 0x4b, 0xc5, 0xee, 0x5d, 0x6b, 0xff, 0xcf, + 0xbb, 0x96, 0xff, 0x1f, 0xac, 0xfb, 0x9d, 0xb7, 0x33, 0x8b, 0x8f, 0xbc, + 0xb3, 0x92, 0x5d, 0x4b, 0xfc, 0xcf, 0x5d, 0x6b, 0xff, 0x1f, 0xb5, 0xfb, + 0x57, 0xba, 0xfd, 0xb7, 0x57, 0xb2, 0xe7, 0xbf, 0xbf, 0x92, 0x5d, 0x4b, + 0x6b, 0xeb, 0x9a, 0x1b, 0xf6, 0xff, 0x33, 0x8b, 0xeb, 0xc4, 0xe8, 0xf3, + 0xbf, 0x7b, 0x9c, 0xb5, 0x9c, 0x1b, 0xfe, 0xdf, 0xdc, 0xbc, 0xbd, 0x1b, + 0xc7, 0xcf, 0x7b, 0x93, 0xbf, 0x5b, 0x56, 0xf8, 0xfe, 0xcf, 0xff, 0x1f, + 0x38, 0xf4, 0x4e, 0xf8, 0x5d, 0xc4, 0xbc, 0xbc, 0xde, 0x1b, 0xc7, 0xcf, + 0xb7, 0x93, 0xa0, 0xef, 0xdf, 0x5d, 0x62, 0xf8, 0x9f, 0x7b, 0x9c, 0xb4, + 0x9c, 0x1b, 0xf8, 0xdf, 0x67, 0xf8, 0x9c, 0x1b, 0x04, 0xdf, 0x9f, 0x5f, + 0xa1, 0xef, 0xff, 0x7d, 0xde, 0x7d, 0xff, 0x8b, 0xbb, 0x8b, 0xbd, 0x9b, + 0x9c, 0xf0, 0xdf, 0x7d, 0xbb, 0x8b, 0x9e, 0x6d, 0x9b, 0xa4, 0xff, 0xde, + 0xbb, 0x8b, 0x9f, 0x7c, 0xdf, 0x5d, 0xdf, 0x7d, 0xfd, 0x7d, 0xbf, 0x97, + 0xdf, 0x5d, 0xad, 0xef, 0xd3, 0x6d, 0xde, 0x1b, 0x00, 0xcf, 0xb3, 0x93, + 0xeb, 0xc4, 0xd3, 0x4d, 0xec, 0xf3, 0x73, 0xef, 0x33, 0xef, 0xff, 0xcc, + 0x97, 0x59, 0xff, 0x1f, 0x10, 0xf6, 0x9f, 0x7a, 0x5d, 0xc4, 0x9c, 0x1b, + 0x01, 0xdf, 0x9f, 0x5a, 0xba, 0xf8, 0xff, 0xcd, 0x99, 0xef, 0xb7, 0x5c, + 0xff, 0x1f, 0x1b, 0xf6, 0xb7, 0xf8, 0xb6, 0xef, 0x9d, 0x3b, 0xbc, 0xf7, + 0xef, 0xfb, 0xff, 0xff, 0x5f, 0xff, 0xff, 0xdf, 0x6b, 0xff, 0xff, 0xdf, + 0xff, 0x6f, 0xff, 0xbf, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x53, 0xff, 0xff, 0xdf, 0x27, 0xb5, 0xff, 0xff, 0x9f, 0x6c, 0xf3, 0x87, + 0x00, 0x1c, 0xaf, 0x01, 0xbc, 0x6a, 0x80, 0xed, 0xbc, 0x23, 0xce, 0xff, + 0xc7, 0xf8, 0x21, 0xed, 0xb2, 0x69, 0x81, 0xed, 0x61, 0xed, 0x73, 0x97, + 0x99, 0x7b, 0xd7, 0xbc, 0x7b, 0x93, 0xb2, 0x49, 0xb1, 0x69, 0xbd, 0x1b, + 0x00, 0xcf, 0xbe, 0xc4, 0xb1, 0x49, 0xe1, 0xf2, 0xbc, 0xc4, 0xc9, 0xf2, + 0xbb, 0xc4, 0xee, 0xf2, 0x2c, 0xed, 0x3f, 0xf8, 0x8c, 0xed, 0xd2, 0x6c, + 0xac, 0xed, 0x6b, 0xed, 0xb7, 0x97, 0xba, 0x73, 0xf7, 0xb5, 0xf7, 0xbf, + 0xbf, 0x93, 0xd2, 0x4c, 0xd2, 0x6c, 0xde, 0x1b, 0x00, 0xcf, 0x77, 0x8b, + 0x7b, 0x93, 0xb2, 0x4c, 0x35, 0xed, 0x51, 0xf8, 0x95, 0xed, 0xd4, 0xed, + 0xb2, 0x6c, 0x74, 0xed, 0x7b, 0x97, 0xda, 0x7b, 0xd7, 0xbe, 0x7b, 0x93, + 0xb2, 0x4c, 0xb2, 0x6c, 0xbd, 0x1b, 0x00, 0xcf, 0xb2, 0x4c, 0x3c, 0xed, + 0x60, 0xf8, 0x9c, 0xed, 0xb2, 0x6c, 0x3e, 0xed, 0xdd, 0xed, 0x7b, 0x97, + 0xdf, 0x79, 0xd7, 0xbe, 0x7b, 0x93, 0xb2, 0x4c, 0xb2, 0x6c, 0xde, 0x79, + 0xbd, 0x1b, 0x00, 0xcf, 0x7b, 0x93, 0xb2, 0x4c, 0xb1, 0x6c, 0xc3, 0xee, + 0x7b, 0x97, 0xdd, 0x79, 0xd7, 0xbe, 0x7b, 0x93, 0xb1, 0x4c, 0xb1, 0x6c, + 0xdc, 0x79, 0xbd, 0x1b, 0x00, 0xcf, 0x7b, 0x93, 0xb1, 0x4c, 0x79, 0x1b, + 0xf4, 0xff, 0x7f, 0xf8, 0x8c, 0xee, 0xd2, 0x6c, 0x6b, 0xee, 0xac, 0xee, + 0xb7, 0x97, 0xbb, 0x73, 0xf7, 0xb5, 0xf7, 0xbf, 0xbf, 0x93, 0xd2, 0x4c, + 0xd2, 0x6c, 0xde, 0x1b, 0x00, 0xcf, 0x77, 0x8b, 0x7b, 0x93, 0xb2, 0x4c, + 0xd1, 0x6c, 0xb3, 0xee, 0xb7, 0x97, 0xb8, 0x7b, 0xf7, 0xbd, 0xbf, 0x93, + 0xff, 0xdd, 0xb8, 0x5b, 0x39, 0xee, 0xd1, 0x4c, 0x9a, 0xf8, 0x99, 0xee, + 0xb2, 0x6c, 0xd9, 0xee, 0x79, 0xee, 0x7b, 0x97, 0xdf, 0x7b, 0xda, 0xbe, + 0xde, 0x1b, 0xff, 0xd8, 0x7b, 0x93, 0xb2, 0x4c, 0x20, 0xef, 0xa7, 0xf8, + 0x80, 0xef, 0xb2, 0x6c, 0x22, 0xef, 0xc0, 0xef, 0x7b, 0x97, 0xdf, 0x79, + 0xd7, 0xbe, 0x7b, 0x93, 0xb2, 0x4c, 0xb2, 0x6c, 0xde, 0x79, 0xbd, 0x1b, + 0x00, 0xcf, 0x7b, 0x93, 0xb2, 0x4c, 0xb1, 0x6c, 0xc7, 0xef, 0x7b, 0x97, + 0xdd, 0x79, 0xd7, 0xbe, 0x7b, 0x93, 0xb1, 0x4c, 0x79, 0x1b, 0xf4, 0xff, + 0xc0, 0xf8, 0x8c, 0xef, 0xb3, 0x6c, 0x2e, 0xef, 0xdf, 0x79, 0xbd, 0x1b, + 0x00, 0xcf, 0x7b, 0x93, 0xb3, 0x4c, 0xb2, 0x6c, 0xd0, 0xef, 0x7b, 0x97, + 0xde, 0x79, 0xd7, 0xbe, 0x7b, 0x93, 0xb2, 0x4c, 0xb2, 0x6c, 0xdd, 0x79, + 0xbd, 0x1b, 0x00, 0xcf, 0x7b, 0x93, 0xb2, 0x4c, 0xb1, 0x6c, 0xd6, 0xef, + 0x7b, 0x97, 0xdc, 0x79, 0xd7, 0xbe, 0x7b, 0x93, 0xb1, 0x4c, 0xb1, 0x6c, + 0xdb, 0x79, 0xbd, 0x1b, 0x00, 0xcf, 0x7b, 0x93, 0xb1, 0x4c, 0xf6, 0xfb, + 0x6b, 0xff, 0xff, 0xdf, 0xff, 0x6f, 0xff, 0xbf, 0x00, 0xff, 0x00, 0x00, + 0x5f, 0xff, 0xff, 0xdf, 0x79, 0x1b, 0xf4, 0xff, 0xee, 0xf8, 0x95, 0xed, + 0xd5, 0xed, 0xb2, 0x6c, 0x75, 0xed, 0x7b, 0x97, 0xdf, 0x7b, 0xd8, 0xbe, + 0xde, 0x1b, 0xff, 0xde, 0x9e, 0xf8, 0x9a, 0xed, 0xda, 0xed, 0xb2, 0x6c, + 0x7a, 0xed, 0x7b, 0x97, 0xdd, 0x7b, 0xd7, 0xbe, 0xa6, 0xf8, 0x9e, 0xed, + 0xde, 0xed, 0xb2, 0x6c, 0x7e, 0xed, 0x7b, 0x97, 0xdf, 0x7b, 0xde, 0x1b, + 0xfe, 0xdf, 0xd7, 0xbe, 0xb0, 0xf8, 0x83, 0xee, 0xb2, 0x6c, 0xc3, 0xee, + 0x63, 0xee, 0x7b, 0x97, 0xdc, 0x7b, 0xd7, 0xbe, 0x7b, 0x93, 0xb2, 0x4c, + 0xb2, 0x6c, 0xdb, 0x7b, 0xbd, 0x1b, 0x00, 0xcf, 0x7b, 0x93, 0xb2, 0x4c, + 0x28, 0xee, 0x1b, 0xf9, 0x6c, 0xee, 0x8b, 0xee, 0x32, 0x6b, 0x73, 0x96, + 0x00, 0x1c, 0xe9, 0x0d, 0x97, 0xbf, 0x73, 0x92, 0x32, 0x4b, 0x27, 0xf9, + 0x6f, 0xee, 0x9f, 0x7b, 0x9d, 0xb4, 0x9c, 0x1b, 0xfe, 0xdf, 0xbe, 0xc4, + 0x7c, 0x9a, 0x00, 0x1c, 0xf6, 0x0d, 0x95, 0xee, 0xb2, 0x6c, 0x38, 0xb9, + 0xd6, 0xee, 0x7b, 0x97, 0xf9, 0x3b, 0xde, 0xdb, 0xbb, 0x8b, 0xd7, 0xbe, + 0x7b, 0x93, 0xb2, 0x4c, 0xb2, 0x6c, 0xbd, 0x1b, 0x00, 0xcf, 0xbd, 0x13, + 0xe9, 0xff, 0xb2, 0x4c, 0xb1, 0x6c, 0xdd, 0xee, 0x7b, 0x97, 0xbd, 0x13, + 0xff, 0xe6, 0xb1, 0x4c, 0xb1, 0x6c, 0xbd, 0x1b, 0x00, 0xcf, 0xbd, 0x13, + 0xea, 0xff, 0xb1, 0x4c, 0x21, 0xef, 0x4d, 0xf9, 0x92, 0x69, 0xa1, 0xef, + 0xbf, 0x7d, 0x9c, 0x1b, 0x00, 0xcf, 0x37, 0x93, 0x92, 0x49, 0x25, 0xef, + 0x56, 0xf9, 0x92, 0x69, 0xbc, 0x1b, 0x00, 0xcf, 0x86, 0xef, 0x9e, 0x74, + 0xd7, 0xb4, 0x7b, 0x93, 0xb2, 0x49, 0xb1, 0x69, 0xcd, 0xef, 0x33, 0x8b, + 0x7b, 0x97, 0x97, 0xbc, 0x37, 0x93, 0x91, 0x49, 0x11, 0x69, 0x00, 0x1c, + 0x36, 0x05, 0x9d, 0xb7, 0x18, 0x1b, 0x00, 0xcf, 0x33, 0x8b, 0x33, 0x92, + 0x11, 0x49, 0x32, 0xef, 0x70, 0xf9, 0x12, 0x69, 0x18, 0x1b, 0x00, 0xcf, + 0xff, 0x1f, 0xf7, 0xfa, 0x3f, 0x92, 0x12, 0x49, 0x91, 0x69, 0xb9, 0xef, + 0x37, 0x97, 0xb5, 0xef, 0xbf, 0x7d, 0xb7, 0xbd, 0x37, 0x93, 0x91, 0x49, + 0x3b, 0xef, 0x81, 0xf9, 0xff, 0x6f, 0xff, 0xbf, 0x00, 0xff, 0x00, 0x00, + 0x5f, 0xff, 0xff, 0xdf, 0x6b, 0xff, 0xff, 0xdf, 0x78, 0xff, 0xff, 0xdf, + 0x4b, 0xfe, 0xff, 0xdf, 0x0f, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0xde, 0xeb, + 0xd1, 0x1b, 0xfd, 0xff, 0xff, 0x5e, 0xff, 0xcd, 0xf8, 0xcf, 0x00, 0x1c, + 0xa8, 0x03, 0xfe, 0xeb, 0x6f, 0xeb, 0xff, 0xff, 0x98, 0xef, 0xdd, 0x7c, + 0xf7, 0xcd, 0xb7, 0x9b, 0xf7, 0xf7, 0x9f, 0x7c, 0x9c, 0x1b, 0xfd, 0xdf, + 0xbf, 0xc4, 0xff, 0x3b, 0xff, 0xfa, 0xc3, 0x87, 0xff, 0xcf, 0xc3, 0x87, + 0x5f, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xfd, 0x7c, 0xc3, 0x87, 0xff, 0xff, + 0x5f, 0xff, 0xff, 0xdf, 0x2e, 0xeb, 0x6f, 0xef, 0xbc, 0x6b, 0x77, 0x8b, + 0x55, 0xcc, 0x35, 0x9b, 0xee, 0xf3, 0xbc, 0x6b, 0x77, 0x8b, 0xaa, 0xcc, + 0x35, 0x9b, 0xfd, 0xf3, 0x6e, 0xeb, 0x00, 0x1c, 0x4a, 0x03, 0xbc, 0x6b, + 0x96, 0xef, 0xbc, 0x23, 0xce, 0xff, 0x96, 0xef, 0xff, 0xcd, 0xbf, 0x4c, + 0x6e, 0xeb, 0x99, 0xef, 0xb8, 0x7c, 0x5f, 0xc5, 0xb8, 0x5c, 0x9a, 0xef, + 0xff, 0xcd, 0xbf, 0x4c, 0x6e, 0xeb, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xbf, + 0x6b, 0xff, 0xff, 0xdf, 0x8f, 0xff, 0xff, 0xdf, 0xde, 0xeb, 0x9a, 0xef, + 0x9f, 0x6c, 0xf2, 0x8b, 0x8f, 0xb4, 0x8f, 0xbc, 0xf3, 0x93, 0xfe, 0xeb, + 0xc3, 0x87, 0xff, 0xff, 0x4b, 0xfe, 0xff, 0xdf, 0x2c, 0xeb, 0x80, 0xed, + 0xe0, 0xed, 0xff, 0x4c, 0xff, 0x1f, 0x27, 0xf6, 0xbf, 0xc7, 0xa7, 0xf7, + 0x82, 0xed, 0x9e, 0x6c, 0x3f, 0xc4, 0x67, 0xf7, 0x63, 0xed, 0xff, 0xcf, + 0xff, 0x1f, 0xeb, 0xf8, 0xb4, 0x73, 0xf5, 0x9b, 0xbc, 0x92, 0x86, 0xed, + 0xfa, 0xf2, 0xff, 0xcd, 0xb3, 0x54, 0x9f, 0x6b, 0x89, 0xbc, 0x89, 0xb4, + 0xbd, 0xac, 0x96, 0xa4, 0x54, 0x53, 0x5d, 0xb2, 0x4b, 0xa4, 0x9f, 0x73, + 0x5a, 0x1b, 0x00, 0xdc, 0x9c, 0x1b, 0x00, 0xcc, 0x2b, 0x93, 0x9f, 0x53, + 0xfc, 0x15, 0x8c, 0xfe, 0xb3, 0x9a, 0x31, 0xed, 0x99, 0xf3, 0x91, 0xed, + 0x9e, 0x6c, 0x3b, 0xc4, 0x1b, 0xf7, 0x20, 0xcc, 0x9e, 0xbc, 0xb3, 0x9a, + 0xe8, 0xf6, 0x9f, 0x6b, 0x53, 0xbc, 0x49, 0xb2, 0xbd, 0xaa, 0x56, 0xa2, + 0x5a, 0x1b, 0x00, 0xdc, 0xf8, 0xed, 0xb5, 0xba, 0x3f, 0x97, 0x37, 0x93, + 0xfe, 0xcf, 0x9f, 0x4b, 0xff, 0x1f, 0x1d, 0xf9, 0xfd, 0xb7, 0x5f, 0xa2, + 0x5a, 0x1b, 0x00, 0xdc, 0x9f, 0x6b, 0xde, 0xed, 0xb5, 0xba, 0x3b, 0x97, + 0x37, 0x93, 0x9f, 0x4b, 0xfc, 0x15, 0xde, 0xfd, 0xb3, 0x9a, 0xb2, 0xf3, + 0x86, 0xee, 0xbf, 0x6c, 0x43, 0xee, 0x6b, 0x97, 0x55, 0xc5, 0xbf, 0x4c, + 0xff, 0xcc, 0x85, 0x5b, 0xff, 0x1f, 0x41, 0xf9, 0xff, 0x1f, 0x0f, 0xfb, + 0xfc, 0xc7, 0xeb, 0xf3, 0x6c, 0xeb, 0xac, 0xee, 0x85, 0x7d, 0xff, 0xdc, + 0x33, 0x8b, 0x85, 0x5d, 0x69, 0xcd, 0x37, 0x9b, 0x0b, 0xf4, 0xfb, 0xcf, + 0xff, 0x1f, 0xdd, 0xfb, 0xfc, 0xcd, 0x8e, 0xee, 0xbf, 0x5c, 0xff, 0x1f, + 0x22, 0xfb, 0xfc, 0xc7, 0x11, 0xf4, 0xff, 0xcf, 0xff, 0x1f, 0x4f, 0xf9, + 0xfc, 0x15, 0xd0, 0xfd, 0xf3, 0x9b, 0x18, 0xf4, 0x9a, 0xee, 0xbe, 0x6c, + 0xa9, 0xb5, 0xfc, 0x15, 0x00, 0xfd, 0x73, 0x9b, 0xfa, 0xf3, 0x97, 0xee, + 0x9f, 0x7c, 0xbf, 0xc4, 0xf6, 0xf2, 0xfd, 0xcf, 0xff, 0x1f, 0x9f, 0xf8, + 0xfa, 0xcf, 0xff, 0x1f, 0x96, 0xf8, 0xfb, 0xcf, 0xff, 0x1f, 0xe7, 0xfd, + 0xfb, 0xcd, 0x9f, 0xee, 0xbf, 0x5c, 0x6c, 0xeb, 0xfc, 0x15, 0xd0, 0xfd, + 0xb3, 0x9a, 0x88, 0xf3, 0x0d, 0xcc, 0x9e, 0xbc, 0xb3, 0x9a, 0x67, 0xf4, + 0xfe, 0xcf, 0xff, 0x1f, 0xb4, 0xf8, 0x67, 0xf8, 0x8c, 0xef, 0xbf, 0x6c, + 0xe9, 0xef, 0x7f, 0x97, 0x53, 0xc5, 0xbf, 0x4c, 0x4b, 0xf8, 0x6e, 0xef, + 0xff, 0x1f, 0x9f, 0xf9, 0x9f, 0x6b, 0x9d, 0xbc, 0x89, 0xb4, 0xbd, 0xac, + 0x96, 0xa4, 0xfd, 0xb7, 0xbf, 0xa4, 0xbd, 0x1b, 0x00, 0xdc, 0x9e, 0x73, + 0xfd, 0x1b, 0x00, 0xdc, 0x50, 0xef, 0xdb, 0xbf, 0x2b, 0x97, 0x3b, 0x93, + 0x7f, 0xce, 0xde, 0xbe, 0x7b, 0x9b, 0x9e, 0x53, 0x34, 0x93, 0xc3, 0xf7, + 0xe9, 0xfb, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xbf, 0x04, 0x00, 0xdd, 0xff, + 0xff, 0x5f, 0xff, 0xbf, 0x37, 0xff, 0xff, 0xdf, 0xff, 0xaf, 0xff, 0xbf, + 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xdf, + 0x6f, 0xfe, 0xff, 0xdf, 0xf0, 0x3f, 0x00, 0x00, 0x9a, 0x73, 0xdb, 0xb4, + 0xde, 0x1b, 0xe0, 0xdf, 0x5d, 0xa6, 0x5a, 0x1b, 0xe0, 0xdf, 0x5b, 0xba, + 0x9c, 0x1b, 0x0f, 0xce, 0x2b, 0x93, 0xd6, 0xc6, 0xb0, 0x92, 0x9a, 0x53, + 0x78, 0xf3, 0x9d, 0x6b, 0xd3, 0xbc, 0xd3, 0xb6, 0xdb, 0xa5, 0xd3, 0xbe, + 0x8b, 0xb4, 0xd3, 0xb6, 0x8b, 0xbc, 0x3b, 0x93, 0x9d, 0x4b, 0x9e, 0x6b, + 0xd3, 0xbc, 0xc9, 0xb6, 0xb6, 0x9b, 0x3e, 0xf3, 0xc8, 0xed, 0xf5, 0xbf, + 0x3b, 0x97, 0x3f, 0x93, 0x9e, 0x4b, 0x9d, 0xbc, 0x89, 0xb4, 0xca, 0xed, + 0xbd, 0x76, 0xbf, 0xc5, 0xc9, 0xf3, 0x73, 0x9b, 0x97, 0xf3, 0xf6, 0xa4, + 0xfe, 0x8b, 0xf3, 0xc7, 0xcf, 0xf7, 0x5e, 0x76, 0x29, 0x9b, 0xf0, 0xed, + 0xdc, 0xf3, 0x9e, 0x57, 0xfe, 0xcc, 0x9f, 0x5f, 0x34, 0x93, 0xd7, 0xfb, + 0xff, 0x1f, 0xbf, 0xfb, 0xbb, 0xc7, 0x7b, 0xf3, 0x5f, 0x69, 0x49, 0xba, + 0x49, 0xb2, 0x7c, 0xf8, 0xfb, 0xcf, 0xff, 0x1f, 0x82, 0xf6, 0x5f, 0x69, + 0x49, 0xba, 0x49, 0xb2, 0x83, 0xf8, 0xb3, 0x74, 0xff, 0xdd, 0x76, 0x8b, + 0xb3, 0x54, 0x9b, 0xcc, 0x73, 0x9b, 0x07, 0xf5, 0xfb, 0xcf, 0xff, 0x1f, + 0x96, 0xfc, 0xfd, 0xcd, 0x80, 0xee, 0xbf, 0x5c, 0x0e, 0xf9, 0x5f, 0x7f, + 0xff, 0xda, 0xab, 0x8a, 0x5f, 0x5f, 0xec, 0xcf, 0xbf, 0x9a, 0x6f, 0xf7, + 0x35, 0x9b, 0xfd, 0xf3, 0x9d, 0x56, 0xd7, 0xcd, 0x37, 0x9b, 0xe5, 0xf3, + 0x8c, 0x7b, 0xff, 0xdc, 0x33, 0x8b, 0xf5, 0xcd, 0xff, 0xcf, 0x37, 0x9b, + 0xca, 0xee, 0xed, 0x5b, 0x8c, 0x5b, 0xf6, 0xf7, 0x8b, 0x7e, 0xbe, 0xc4, + 0xac, 0x5e, 0xfa, 0xf7, 0xeb, 0x5e, 0xed, 0xee, 0xff, 0x1f, 0xe5, 0xfb, + 0xff, 0xcc, 0x8d, 0x5b, 0x3a, 0xf9, 0xfc, 0xcf, 0xff, 0x1f, 0x65, 0xf9, + 0x18, 0xf9, 0xff, 0xce, 0xcc, 0x5b, 0x84, 0xce, 0x3b, 0x9b, 0xb5, 0xee, + 0x0b, 0xf4, 0x8d, 0x7d, 0xff, 0xdc, 0x33, 0x8b, 0xf5, 0xce, 0x3b, 0x9b, + 0x8d, 0x5d, 0x4b, 0xf5, 0x8b, 0x7d, 0xbf, 0xc4, 0xcd, 0x5d, 0x4f, 0xf5, + 0xfe, 0xcc, 0x8b, 0x5d, 0xfc, 0xee, 0xff, 0x1f, 0x02, 0xfc, 0x55, 0xf9, + 0xf2, 0xa5, 0xfe, 0x8b, 0x66, 0xf8, 0xbd, 0x6b, 0x9d, 0x73, 0xb3, 0xbd, + 0x89, 0xbc, 0xb3, 0xb5, 0x89, 0xb4, 0x92, 0xa5, 0xbe, 0x6b, 0x93, 0xbc, + 0xb3, 0xbd, 0xa9, 0xb5, 0x93, 0xb4, 0x96, 0xa4, 0x8c, 0xbc, 0xbc, 0x73, + 0x89, 0xb4, 0xe6, 0xef, 0xdb, 0xbc, 0x7f, 0x97, 0x5a, 0x1b, 0x0f, 0xce, + 0x7b, 0x93, 0x5a, 0x53, 0xbc, 0x53, 0xbd, 0x6b, 0xab, 0xb5, 0xab, 0xbd, + 0xbd, 0x4b, 0xcb, 0xef, 0xbe, 0x6b, 0x7b, 0x93, 0xbe, 0x4b, 0xbd, 0x1b, + 0x00, 0xcc, 0xbd, 0x53, 0x92, 0xf8, 0x3f, 0xcf, 0xfd, 0xbf, 0x84, 0xce, + 0xff, 0x1f, 0xf9, 0xf9, 0x0c, 0xf9, 0x91, 0xef, 0x9e, 0x6c, 0x3b, 0xc4, + 0x85, 0xf4, 0x92, 0xef, 0x9f, 0x7c, 0xbf, 0xc4, 0x89, 0xf4, 0xfb, 0xcf, + 0xff, 0x1f, 0x13, 0xf7, 0x8d, 0xf8, 0xff, 0xff, 0x00, 0xfc, 0x0f, 0x00, + 0x2b, 0xff, 0xff, 0xdf, 0x0f, 0xff, 0xff, 0xdf, 0x37, 0xff, 0xff, 0xdf, + 0xd3, 0xb4, 0xff, 0xff, 0xf0, 0x3f, 0x00, 0x00, 0xff, 0x03, 0xf0, 0xff, + 0xff, 0xaf, 0xff, 0xbf, 0x6f, 0xfe, 0xff, 0xdf, 0x9d, 0x73, 0xc9, 0xbc, + 0xc9, 0xb6, 0x7a, 0x9b, 0xfa, 0xf3, 0x9c, 0x1b, 0x00, 0xcc, 0xf3, 0x93, + 0xfd, 0x53, 0x9c, 0x73, 0x8d, 0xbc, 0x89, 0xb4, 0xc4, 0xf8, 0x34, 0x93, + 0x8c, 0xf8, 0xff, 0xff, 0x2e, 0xeb, 0x77, 0xee, 0xff, 0xcc, 0xbb, 0x1b, + 0xf4, 0xff, 0x8c, 0x5b, 0x8d, 0x5b, 0x8b, 0x5b, 0xff, 0xcc, 0x9d, 0x55, + 0x9e, 0x55, 0x9f, 0x5d, 0x93, 0x53, 0x85, 0x5b, 0x9a, 0x73, 0x9c, 0x1b, + 0x0f, 0xce, 0x9a, 0x53, 0x9d, 0x6b, 0x8b, 0xb4, 0x8b, 0xbc, 0x9d, 0x4b, + 0x9d, 0x73, 0x9c, 0x1b, 0x00, 0xcc, 0x9d, 0x53, 0x9e, 0x6b, 0xa3, 0xef, + 0x37, 0x93, 0x9e, 0x4b, 0xff, 0x1f, 0xd9, 0xfa, 0x9f, 0x1b, 0x00, 0xdc, + 0xa6, 0xef, 0xfe, 0x73, 0xf7, 0x97, 0x9b, 0xbc, 0xf3, 0x93, 0xfe, 0x53, + 0xff, 0xcf, 0xff, 0x1f, 0xc6, 0xfa, 0x9f, 0x73, 0xff, 0x1b, 0x00, 0xdc, + 0x9c, 0x1b, 0x00, 0xcc, 0x3f, 0x93, 0xfe, 0xcf, 0x9f, 0x53, 0xff, 0x1f, + 0xd0, 0xfa, 0x9f, 0x1b, 0x00, 0xdc, 0xaf, 0xef, 0xff, 0x6b, 0x95, 0xbc, + 0xf7, 0x97, 0xf3, 0x93, 0xff, 0x4b, 0xff, 0x1f, 0xe6, 0xfa, 0xfb, 0x1b, + 0xe5, 0xff, 0xff, 0xce, 0xb4, 0xef, 0xff, 0x1f, 0x48, 0xfc, 0xbf, 0xc7, + 0xf9, 0xf7, 0xe4, 0x7b, 0xfc, 0xce, 0xff, 0xcd, 0xff, 0x1f, 0xf3, 0xfb, + 0x98, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0x6e, 0xeb, 0x37, 0xff, 0xff, 0xdf, + 0xff, 0x03, 0xf0, 0xff, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, + 0x2b, 0xd7, 0xff, 0xff, 0x47, 0xfe, 0xff, 0xdf, 0xff, 0x8b, 0xbf, 0xc7, + 0xf4, 0xf7, 0x8e, 0xef, 0xbf, 0x74, 0xbd, 0x1b, 0x00, 0xdc, 0xbf, 0xc5, + 0xec, 0xf3, 0xff, 0x6c, 0xe9, 0xbf, 0xe9, 0xb7, 0xc3, 0x87, 0xbe, 0xc7, + 0xf9, 0xf3, 0xbc, 0xc7, 0xf2, 0xf3, 0xff, 0x15, 0x00, 0xfc, 0xc3, 0x87, + 0x97, 0xef, 0xff, 0x6c, 0xb7, 0xef, 0xbf, 0x3b, 0xdc, 0xdf, 0xbf, 0xc4, + 0xf9, 0xf7, 0xfe, 0xcf, 0xc3, 0x87, 0x99, 0xef, 0xfd, 0x74, 0xc3, 0x87, + 0xf3, 0xbf, 0xe9, 0xb7, 0xc3, 0x87, 0xff, 0xff, 0x37, 0xff, 0xff, 0xdf, + 0xff, 0x03, 0xf0, 0xff, 0x2b, 0xff, 0xff, 0xdf, 0x3e, 0xeb, 0x8f, 0xef, + 0xd7, 0x74, 0x9f, 0x6c, 0xa9, 0xbc, 0xa9, 0xb5, 0x7b, 0x83, 0x7a, 0xbd, + 0xf7, 0xbd, 0xff, 0xa3, 0x93, 0xbc, 0xb6, 0xa7, 0x89, 0xb4, 0x3b, 0x83, + 0xfb, 0xbd, 0xb6, 0xa7, 0xdc, 0xbc, 0xf9, 0xbc, 0xda, 0xa7, 0xd2, 0xa6, + 0xdb, 0xbe, 0xd3, 0xa6, 0xdd, 0xbe, 0x92, 0xa6, 0xaf, 0xad, 0x8f, 0xac, + 0x37, 0x9b, 0xfc, 0xf3, 0xf2, 0xa5, 0x7e, 0xeb, 0xff, 0xcf, 0x7e, 0xeb, + 0x37, 0xff, 0xff, 0xdf, 0x3e, 0xeb, 0x85, 0xef, 0x9d, 0x6c, 0x2c, 0xc4, + 0xdb, 0xf7, 0x86, 0xef, 0xbf, 0x6c, 0xa9, 0xbd, 0xa9, 0xb5, 0xff, 0xce, + 0x8a, 0xef, 0x0f, 0xcb, 0xfd, 0x6c, 0x6f, 0xbb, 0xef, 0x97, 0xbf, 0xc7, + 0xf1, 0xf3, 0x9d, 0x6c, 0x8b, 0xb4, 0x9c, 0x1b, 0xf0, 0xdf, 0xfc, 0xbc, + 0x9f, 0x3b, 0xdc, 0xf7, 0xfd, 0xbc, 0x9a, 0xbc, 0x9e, 0xa4, 0x37, 0x83, + 0x95, 0xac, 0xd3, 0xa6, 0x92, 0xef, 0x9d, 0x74, 0xf9, 0xbc, 0x9f, 0x3b, + 0xbf, 0xf7, 0xf2, 0xa7, 0xf7, 0x83, 0xf5, 0xaf, 0xff, 0xa6, 0x7e, 0xeb, + 0x98, 0xef, 0xbf, 0x6c, 0xa9, 0xbd, 0xa9, 0xb5, 0xbd, 0x3b, 0xdc, 0x7b, + 0xdb, 0xbc, 0x9e, 0x3b, 0xbe, 0xf7, 0xd2, 0xa6, 0xd1, 0xae, 0x28, 0xf8, + 0xff, 0x5f, 0xff, 0xbf, 0x37, 0xff, 0xff, 0xdf, 0x2b, 0xff, 0xff, 0xdf, + 0x2d, 0xeb, 0x6c, 0xee, 0xbf, 0x8a, 0x9f, 0x73, 0x5c, 0x3b, 0x7d, 0xbf, + 0xfe, 0xce, 0x3f, 0xc5, 0xed, 0xf7, 0xbf, 0xc2, 0xee, 0xf3, 0xbe, 0xc2, + 0xdc, 0xf3, 0xbd, 0x7b, 0xbd, 0x1b, 0xf0, 0xcf, 0x5e, 0x3b, 0xda, 0xbf, + 0x5e, 0xc5, 0x2b, 0x93, 0xd7, 0x5b, 0xbd, 0x5b, 0x9f, 0x53, 0xf6, 0xee, + 0xff, 0x1f, 0x5b, 0xfd, 0x6d, 0xeb, 0xfb, 0xcf, 0xff, 0xce, 0xff, 0x1f, + 0x70, 0xf8, 0x9d, 0x7b, 0x9c, 0x1b, 0xf0, 0xcf, 0x9c, 0x13, 0xfc, 0xff, + 0x9d, 0x5b, 0xbe, 0x73, 0x9d, 0x73, 0xad, 0xbd, 0xa9, 0xb5, 0x9c, 0x1b, + 0x00, 0xcc, 0x37, 0x93, 0x9d, 0x53, 0x57, 0x5b, 0x16, 0xf8, 0xfe, 0xce, + 0xfb, 0xcf, 0x57, 0x5b, 0xff, 0x1f, 0x85, 0xf8, 0x9d, 0x7b, 0x9c, 0x1b, + 0xf0, 0xcf, 0x5f, 0xc4, 0x9d, 0x5b, 0x00, 0x1c, 0x8e, 0x08, 0xbf, 0x1b, + 0x00, 0xdc, 0x9e, 0x73, 0xc9, 0xef, 0xbb, 0xbd, 0x3b, 0x97, 0x37, 0x93, + 0x9e, 0x53, 0x00, 0x1c, 0x98, 0x08, 0xfc, 0x15, 0x40, 0xfe, 0xf3, 0x9b, + 0xf4, 0xf7, 0x9d, 0x73, 0x9c, 0x1b, 0x00, 0xcc, 0x9c, 0x13, 0x40, 0xfe, + 0x9d, 0x53, 0x9f, 0x73, 0x5e, 0xc4, 0x9f, 0x53, 0x3a, 0xf8, 0xbe, 0x73, + 0x9d, 0x73, 0xad, 0xbd, 0xa9, 0xb5, 0x9c, 0x1b, 0x00, 0xcc, 0x37, 0x93, + 0x9d, 0x53, 0x00, 0x1c, 0x66, 0x0d, 0xbf, 0xc7, 0x0e, 0xf0, 0x9d, 0x73, + 0x9c, 0x1b, 0x00, 0xcc, 0x9c, 0x13, 0x8b, 0xfe, 0x9d, 0x53, 0x15, 0xf8, + 0x1b, 0xff, 0xff, 0xdf, 0xcb, 0xb4, 0xff, 0xff, 0xf0, 0x3f, 0x00, 0x00, + 0x2c, 0xeb, 0x7c, 0x92, 0xff, 0xcf, 0x00, 0x1c, 0xf4, 0x00, 0xfc, 0x15, + 0xb9, 0xfc, 0xf3, 0x9b, 0xbc, 0x92, 0x75, 0xf3, 0x00, 0x1c, 0xd1, 0x00, + 0xfc, 0x15, 0x3b, 0xf6, 0xf3, 0x9b, 0x8d, 0xf3, 0xfc, 0x15, 0x23, 0xfa, + 0xf3, 0x9b, 0xcb, 0xf3, 0x6d, 0xed, 0xff, 0xcc, 0x98, 0x53, 0x9a, 0x53, + 0x9f, 0x71, 0x3e, 0xc4, 0xf8, 0xf3, 0x9d, 0x73, 0x89, 0xbc, 0x89, 0xb4, + 0xdb, 0xdc, 0x2b, 0x9b, 0x7a, 0xf3, 0x92, 0xed, 0xbe, 0x6c, 0x3f, 0xc5, + 0xa5, 0xf3, 0x9d, 0x6c, 0x2c, 0xc4, 0xa8, 0xf3, 0x97, 0x73, 0xff, 0xdc, + 0x32, 0x8b, 0xfd, 0x15, 0x6a, 0xfa, 0x37, 0x9b, 0x97, 0x53, 0x8f, 0xf3, + 0xfe, 0xcf, 0x00, 0x1c, 0x22, 0x01, 0x9f, 0x73, 0xbc, 0x92, 0x35, 0xc4, + 0xd9, 0xf3, 0xfd, 0x15, 0x66, 0xfe, 0xf7, 0x9b, 0xdd, 0xf3, 0xfb, 0xcf, + 0x00, 0x1c, 0xa7, 0x00, 0xf7, 0xcc, 0x93, 0x5b, 0x82, 0xee, 0x9e, 0x6c, + 0x3f, 0xc4, 0xdd, 0xf7, 0xff, 0xcc, 0x8d, 0x5b, 0x6c, 0xeb, 0x66, 0xee, + 0xff, 0xcc, 0xb8, 0x73, 0x9a, 0x53, 0xff, 0xdd, 0x70, 0xcc, 0x76, 0x8b, + 0x9e, 0xbc, 0x73, 0x9b, 0xb8, 0x53, 0x38, 0xf4, 0xff, 0x15, 0x09, 0xfc, + 0xff, 0x1f, 0xd7, 0xfb, 0xfb, 0xcf, 0x00, 0x1c, 0xc2, 0x00, 0xf8, 0xcc, + 0x93, 0x5b, 0x42, 0xf8, 0x34, 0xc4, 0x1c, 0xf0, 0x61, 0xcc, 0xb3, 0x9a, + 0x24, 0xf4, 0x92, 0xee, 0x9e, 0x6c, 0x3f, 0xc4, 0x1f, 0xf0, 0xfc, 0xcf, + 0x00, 0x1c, 0x57, 0x01, 0xfc, 0x15, 0x51, 0xfc, 0xf3, 0x9b, 0xcf, 0xf7, + 0x8d, 0x7b, 0xff, 0xdc, 0x33, 0x8b, 0xb9, 0xcd, 0x37, 0x9b, 0x8d, 0x5b, + 0x2b, 0xf4, 0x77, 0xcc, 0xb3, 0x9a, 0xfa, 0xf3, 0x9d, 0xee, 0xbe, 0x6c, + 0x7f, 0xc5, 0xbe, 0x4c, 0xfd, 0xcf, 0x00, 0x1c, 0xe6, 0x00, 0x6c, 0xeb, + 0xff, 0xcc, 0x97, 0x53, 0x4f, 0xf8, 0x63, 0xef, 0xff, 0x15, 0x09, 0xfc, + 0xff, 0x1f, 0x07, 0xfc, 0x9a, 0x73, 0xff, 0xdc, 0x32, 0x8b, 0xf1, 0xcd, + 0x37, 0x9b, 0x9a, 0x53, 0x73, 0xf4, 0xfb, 0xcf, 0x00, 0x1c, 0xf9, 0x00, + 0xf9, 0xcc, 0x93, 0x5b, 0x79, 0xf8, 0x8b, 0xef, 0xbd, 0x6c, 0x4c, 0xc5, + 0xbd, 0x4c, 0xfe, 0xcf, 0x00, 0x1c, 0x03, 0x01, 0x8f, 0xf8, 0x77, 0xcc, + 0xb3, 0x9a, 0x58, 0xf0, 0x31, 0xf8, 0x92, 0xef, 0xb7, 0x54, 0xf8, 0xcf, + 0x00, 0x1c, 0x0d, 0x01, 0x73, 0xf8, 0xff, 0xcd, 0x96, 0xef, 0xb7, 0x54, + 0xff, 0x1f, 0x01, 0xfc, 0x97, 0xef, 0xbd, 0x6c, 0x6c, 0xc5, 0xbd, 0x4c, + 0xbd, 0x6c, 0x56, 0xc5, 0xbd, 0x4c, 0xff, 0xcf, 0x00, 0x1c, 0x1d, 0x01, + 0x9f, 0x71, 0x7e, 0xc4, 0x9f, 0x51, 0x95, 0xf8, 0x1b, 0xff, 0xff, 0xdf, + 0xff, 0x5f, 0xff, 0xbf, 0x2e, 0xeb, 0x82, 0xef, 0xb9, 0x6c, 0x3a, 0xc5, + 0xfb, 0xf7, 0xb9, 0x6c, 0x34, 0xc5, 0xe2, 0xf3, 0x86, 0xef, 0xbd, 0x6c, + 0x4c, 0xc5, 0xbd, 0x4c, 0xfe, 0xcf, 0x00, 0x1c, 0x34, 0x01, 0xff, 0xcf, + 0xff, 0x1f, 0x03, 0xf9, 0xbf, 0xc7, 0xf1, 0xf3, 0x6b, 0xef, 0x8c, 0x7b, + 0xff, 0xdc, 0x33, 0x8b, 0xf4, 0xcd, 0x37, 0x9b, 0x8c, 0x5b, 0xfa, 0xf7, + 0x8e, 0xef, 0x9f, 0x7c, 0xbf, 0xc4, 0xf0, 0xf3, 0x6e, 0xeb, 0x91, 0xef, + 0xec, 0x5c, 0x6e, 0xeb, 0xb9, 0x6c, 0x3c, 0xc5, 0x1d, 0xf4, 0xb9, 0x6c, + 0x3d, 0xc5, 0x20, 0xf4, 0x99, 0x6c, 0x35, 0xc4, 0x1c, 0xf0, 0x24, 0xf8, + 0xfb, 0xcf, 0x8c, 0x5b, 0x00, 0x1c, 0x57, 0x01, 0xfa, 0xcc, 0xfb, 0xcf, + 0xfe, 0xce, 0x93, 0x5b, 0xff, 0x1f, 0xb1, 0xf9, 0x6e, 0xeb, 0xff, 0xff, + 0xff, 0x5f, 0xff, 0xbf, 0x1b, 0xff, 0xff, 0xdf, 0x6f, 0xfe, 0xff, 0xdf, + 0x2e, 0xeb, 0x6d, 0xef, 0xbd, 0x7b, 0xbd, 0x1b, 0xf0, 0xcf, 0xbd, 0x5b, + 0xbe, 0x73, 0xcf, 0xef, 0x7b, 0x97, 0xbe, 0x53, 0xbd, 0x73, 0xbd, 0x1b, + 0x00, 0xcc, 0xff, 0xcc, 0xbd, 0x53, 0xfb, 0x1b, 0xec, 0xff, 0xff, 0xce, + 0xb4, 0xef, 0x97, 0x53, 0x9a, 0x53, 0x98, 0x53, 0x97, 0x5b, 0x9f, 0x53, + 0xff, 0x1f, 0x67, 0xfe, 0xbf, 0xc7, 0xfd, 0xf3, 0x6e, 0xeb, 0xeb, 0x7b, + 0xf8, 0xce, 0x6c, 0x93, 0xff, 0x1f, 0x13, 0xfe, 0x6e, 0xeb, 0xff, 0xff, + 0x1b, 0xff, 0xff, 0xdf, 0xf0, 0x3f, 0x00, 0x00, 0x0f, 0xd1, 0xff, 0xff, + 0x2f, 0xeb, 0x8e, 0xef, 0xb9, 0x6c, 0x3b, 0xc5, 0xfb, 0xf7, 0xb9, 0x6c, + 0x3f, 0xc5, 0xfa, 0xf3, 0xfd, 0xcf, 0x00, 0x1c, 0x9a, 0x01, 0x6f, 0xeb, + 0xbd, 0x6c, 0x4c, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0xd5, 0xef, 0x7b, 0x97, + 0x4b, 0xc5, 0x49, 0xc5, 0xbd, 0x4c, 0x96, 0xef, 0xbf, 0x74, 0x5e, 0xc5, + 0xbf, 0x54, 0xfb, 0xcf, 0xfe, 0xce, 0xff, 0x1f, 0x00, 0xfa, 0xf9, 0xcf, + 0x00, 0x1c, 0xaf, 0x01, 0x6f, 0xeb, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xbf, + 0x00, 0x00, 0xf0, 0x00, 0x1b, 0xff, 0xff, 0xdf, 0x9a, 0xef, 0xfe, 0xcd, + 0xff, 0x8b, 0xfd, 0x3b, 0xdf, 0xbf, 0xbf, 0x74, 0xf7, 0x93, 0xff, 0x54, + 0xc3, 0x87, 0xff, 0xff, 0x1b, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0xff, 0xcf, + 0xff, 0x1f, 0x93, 0xf9, 0xbe, 0xc7, 0xfd, 0xf3, 0x6f, 0xeb, 0x94, 0xef, + 0xff, 0x5c, 0xfb, 0xcf, 0xff, 0x1f, 0xe1, 0xf9, 0x96, 0xef, 0xbd, 0x6c, + 0x4c, 0xc5, 0xbd, 0x4c, 0xfb, 0xcf, 0x00, 0x1c, 0xd6, 0x01, 0xf5, 0xcd, + 0x99, 0xef, 0xb3, 0x5c, 0xfb, 0xcf, 0xfe, 0xce, 0xff, 0x1f, 0x31, 0xfa, + 0x6f, 0xeb, 0xff, 0xff, 0x6f, 0xfe, 0xff, 0xdf, 0xff, 0x5f, 0xff, 0xbf, + 0x1b, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0xff, 0x8b, 0x00, 0x1c, 0xe9, 0x01, + 0x6f, 0xeb, 0xff, 0xff, 0x9c, 0xef, 0x97, 0x7c, 0xbf, 0xc4, 0xff, 0x3b, + 0xff, 0xfa, 0xc3, 0x87, 0x1b, 0xff, 0xff, 0xdf, 0x95, 0xef, 0x9f, 0x74, + 0x3e, 0xc4, 0xf4, 0xf7, 0x3d, 0xc4, 0xf8, 0xf7, 0x3a, 0xc4, 0xf4, 0xf7, + 0x3b, 0xc4, 0xf8, 0xf3, 0xf4, 0xcf, 0xc3, 0x87, 0xfa, 0xcf, 0xc3, 0x87, + 0xfb, 0xcf, 0xc3, 0x87, 0xff, 0xcf, 0xc3, 0x87, 0xf5, 0xcf, 0xc3, 0x87, + 0x1b, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0x8e, 0xef, 0xbf, 0x7c, 0xdd, 0x1b, + 0xf0, 0xcf, 0x5f, 0xc6, 0xf0, 0xcd, 0xb7, 0x97, 0xdf, 0x5c, 0xde, 0x7c, + 0xde, 0x1b, 0xf0, 0xcf, 0x7b, 0x97, 0xdc, 0x1b, 0xf4, 0xff, 0xbe, 0x5c, + 0xdd, 0x4c, 0xff, 0xcd, 0xf8, 0xce, 0xbb, 0x5c, 0xbe, 0x54, 0xd9, 0x5c, + 0xba, 0x5c, 0x00, 0x1c, 0x46, 0x13, 0x00, 0x1c, 0x6e, 0x13, 0x00, 0x1c, + 0xb6, 0x14, 0x00, 0x1c, 0x56, 0x14, 0x00, 0x1c, 0x5c, 0x0f, 0x6f, 0xeb, + 0x03, 0xff, 0xff, 0xdf, 0x98, 0xef, 0xdf, 0x7c, 0xf0, 0xcd, 0xb7, 0x97, + 0xde, 0x13, 0xaf, 0xff, 0xdf, 0x5c, 0xde, 0x7c, 0xde, 0x1b, 0xf0, 0xcf, + 0x7b, 0x97, 0xbe, 0x5c, 0xc3, 0x87, 0xff, 0xff, 0x03, 0xff, 0xff, 0xdf, + 0x2c, 0xeb, 0xde, 0xeb, 0xff, 0xcd, 0x79, 0xee, 0xdb, 0x7b, 0xbf, 0x47, + 0xba, 0x7b, 0xbb, 0x8b, 0x77, 0x8b, 0x79, 0x9b, 0xc8, 0xf3, 0x7f, 0x3f, + 0xdf, 0x8f, 0xbb, 0x7b, 0x77, 0x8b, 0xdd, 0x6b, 0xbe, 0x3b, 0xbe, 0xf7, + 0xff, 0xdd, 0x77, 0x8b, 0x5f, 0x6e, 0xbb, 0x5b, 0x9b, 0x7b, 0xb9, 0x7b, + 0x37, 0x97, 0x9b, 0x5b, 0x5f, 0x47, 0x7f, 0x3f, 0xdf, 0x8b, 0xff, 0xcc, + 0xbf, 0x72, 0xfe, 0xd4, 0x34, 0x8f, 0xbe, 0x73, 0x37, 0x97, 0x9e, 0x53, + 0x9e, 0x7b, 0xa9, 0xef, 0x9c, 0x1b, 0xf0, 0xdf, 0x9d, 0x3b, 0xbc, 0xf7, + 0x9f, 0x6c, 0xe8, 0x93, 0x32, 0x84, 0x9e, 0x7b, 0xbc, 0x1b, 0xf0, 0xdf, + 0xdf, 0x7b, 0xfb, 0xbd, 0xde, 0x1b, 0xf0, 0xdf, 0xbf, 0x93, 0xf8, 0x93, + 0xdf, 0x5b, 0xdb, 0xb4, 0xde, 0x1b, 0xf0, 0xdf, 0xb5, 0x9b, 0x35, 0xef, + 0xfc, 0xf3, 0xbf, 0xc2, 0xfa, 0xf3, 0xfe, 0xeb, 0x6c, 0xeb, 0xff, 0xca, + 0x1d, 0xf8, 0x9c, 0x1b, 0xf0, 0xcf, 0xff, 0x1b, 0xf0, 0xcf, 0xb3, 0x93, + 0x5f, 0xc7, 0xde, 0x59, 0xff, 0x59, 0xfe, 0xeb, 0x6c, 0xeb, 0xff, 0xff, + 0x03, 0xff, 0xff, 0xdf, 0xc3, 0xb4, 0xff, 0xff, 0x98, 0xef, 0xbf, 0x7c, + 0xff, 0x8b, 0xbd, 0x1b, 0xf0, 0xcf, 0xbf, 0x5c, 0xbb, 0xbf, 0xfe, 0x7c, + 0xff, 0x1b, 0xf0, 0xdf, 0xf7, 0x93, 0xfe, 0x5c, 0xc3, 0x87, 0xff, 0xff, + 0x03, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xff, 0x7c, 0xfb, 0xb7, 0xc3, 0x87, + 0x03, 0xff, 0xff, 0xdf, 0x9c, 0xef, 0xfe, 0x7c, 0xff, 0x1b, 0xf0, 0xdf, + 0xc3, 0x87, 0xff, 0xff, 0x03, 0xff, 0xff, 0xdf, 0x9a, 0xef, 0xbf, 0x7c, + 0x9e, 0x7c, 0xbb, 0xb5, 0x9c, 0x1b, 0xf0, 0xdf, 0x35, 0x9b, 0xff, 0x3b, + 0xff, 0xfa, 0xc3, 0x87, 0x03, 0xff, 0xff, 0xdf, 0x3e, 0xeb, 0x8e, 0xef, + 0xbf, 0x7c, 0xbd, 0x1b, 0xf0, 0xdf, 0xbf, 0xc5, 0xe4, 0xf3, 0xde, 0x74, + 0xbf, 0x77, 0xbe, 0x3b, 0x7d, 0xbf, 0x3f, 0xc5, 0xea, 0xf7, 0xba, 0x7c, + 0x77, 0x8b, 0xd9, 0x7c, 0xff, 0xdd, 0x7b, 0x97, 0xdb, 0x7c, 0xbb, 0x8b, + 0xb5, 0x9b, 0xf3, 0xf3, 0x7f, 0x3f, 0xdf, 0x8f, 0x7a, 0x7c, 0xdd, 0x6c, + 0xef, 0x8a, 0x7e, 0x3b, 0xbe, 0xf7, 0xff, 0x4e, 0xba, 0x5c, 0x7f, 0x3f, + 0xdf, 0x8b, 0x7e, 0xeb, 0x03, 0xff, 0xff, 0xdf, 0x9c, 0xef, 0xbf, 0x6c, + 0xff, 0xdd, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0xd7, 0xfe, 0xff, 0xdf, + 0xf0, 0xcd, 0x88, 0xef, 0xbb, 0x5c, 0xf8, 0xdc, 0xff, 0x7c, 0x7f, 0xc7, + 0xd3, 0x7c, 0xf7, 0x97, 0x5b, 0xc7, 0x7f, 0xc6, 0xb7, 0x97, 0xff, 0x5c, + 0xe7, 0x7c, 0x5a, 0xc6, 0x7f, 0xc7, 0xf7, 0x97, 0xd3, 0x5c, 0xdc, 0x27, + 0xdb, 0xff, 0xff, 0x13, 0xcf, 0xff, 0x7f, 0xc6, 0xb7, 0x97, 0xe7, 0x5c, + 0xfc, 0x27, 0xcf, 0xff, 0x7f, 0xc7, 0x59, 0xc6, 0x7f, 0x97, 0xdc, 0x23, + 0xdb, 0xff, 0xff, 0xcf, 0xdc, 0x27, 0xc3, 0xff, 0xbd, 0x13, 0xaf, 0xff, + 0x7f, 0xc6, 0xf0, 0xd7, 0xbc, 0x23, 0xcf, 0xff, 0xfe, 0x3b, 0xdd, 0xdb, + 0xbc, 0x23, 0xc3, 0xff, 0xc3, 0x87, 0xff, 0xff, 0xd7, 0xfe, 0xff, 0xdf, + 0x3c, 0xeb, 0xbf, 0xc7, 0xfc, 0xf3, 0xfe, 0xc6, 0xfc, 0xf3, 0xfe, 0xcf, + 0x7c, 0xeb, 0xbf, 0xc5, 0x02, 0xf0, 0x8a, 0xef, 0x7b, 0x7c, 0x3b, 0x1b, + 0xf0, 0xcf, 0x67, 0x8a, 0x0f, 0xca, 0xa5, 0x9a, 0xdf, 0xf3, 0x7b, 0xb3, + 0x7b, 0x1b, 0xf0, 0xdf, 0xaf, 0x8a, 0x7f, 0x5f, 0x7d, 0xba, 0x5b, 0xba, + 0x4e, 0xa2, 0xe1, 0xa4, 0xeb, 0xa7, 0x5f, 0x7f, 0x7b, 0x7c, 0x5b, 0xb2, + 0x5b, 0xba, 0x7b, 0x1b, 0xf0, 0xdf, 0xeb, 0x92, 0x7b, 0x5c, 0x9f, 0x7f, + 0xff, 0xcb, 0xf1, 0xd3, 0x5f, 0xc4, 0xde, 0x1b, 0xfc, 0xdf, 0x2f, 0x97, + 0xde, 0xbe, 0xb3, 0x93, 0xdf, 0x5f, 0xbe, 0x4f, 0xff, 0xcf, 0x7c, 0xeb, + 0xfd, 0xcf, 0x7c, 0xeb, 0xd7, 0xfe, 0xff, 0xdf, 0x3d, 0xeb, 0x9f, 0x7f, + 0xb0, 0xc4, 0xe2, 0xf3, 0xdd, 0xbc, 0xae, 0xef, 0x9b, 0xbc, 0x61, 0xa5, + 0xda, 0xa4, 0xdb, 0xa3, 0x7f, 0x7e, 0x3c, 0xc3, 0xe9, 0xf7, 0xfb, 0x3b, + 0xda, 0xd7, 0x5f, 0x5e, 0x5b, 0x7d, 0x5b, 0xb2, 0x5b, 0xba, 0x7b, 0x1b, + 0xf1, 0xdf, 0xeb, 0x92, 0x7f, 0x5e, 0xdb, 0x7d, 0xde, 0x1b, 0xf0, 0xdf, + 0x3b, 0x93, 0x9b, 0x5d, 0xf0, 0xcc, 0x9f, 0x5f, 0xff, 0xcf, 0x7d, 0xeb, + 0xfe, 0xcf, 0x7d, 0xeb, 0x7c, 0xc3, 0x7f, 0x5e, 0xff, 0xcf, 0x7d, 0xeb, + 0xd7, 0xfe, 0xff, 0xdf, 0x3c, 0xeb, 0xff, 0x8b, 0x66, 0xef, 0x9d, 0xbf, + 0x3b, 0xbf, 0x41, 0xa3, 0x92, 0xa1, 0x93, 0xa2, 0x5f, 0x7c, 0x3f, 0xc2, + 0xfc, 0xf7, 0xfe, 0xcf, 0x7c, 0xeb, 0x3c, 0xc2, 0xdc, 0xf7, 0x5e, 0x74, + 0xde, 0x1b, 0x00, 0xd0, 0x3b, 0xbe, 0x5a, 0x1b, 0xf0, 0xdf, 0xa7, 0x92, + 0x5e, 0x54, 0x5f, 0x6c, 0x30, 0xef, 0xa7, 0x96, 0xd7, 0xbe, 0xab, 0x93, + 0xdf, 0x4c, 0x5c, 0xc6, 0xdf, 0x5c, 0xbd, 0x4c, 0xbb, 0x7b, 0xbd, 0x1b, + 0xf0, 0xdf, 0xbb, 0xbd, 0xde, 0x1b, 0xf0, 0xdf, 0xb7, 0x93, 0xdf, 0x5c, + 0x9b, 0x7b, 0x9c, 0x1b, 0xf0, 0xcf, 0xff, 0x1b, 0xf0, 0xdf, 0xf3, 0x93, + 0xfb, 0x5b, 0xff, 0xcf, 0x7c, 0xeb, 0xfc, 0xcf, 0x7c, 0xeb, 0xff, 0xff, + 0xd7, 0xfe, 0xff, 0xdf, 0x00, 0xff, 0x0f, 0x00, 0x2b, 0xeb, 0xde, 0xeb, + 0x9c, 0xed, 0xbf, 0x6c, 0x2b, 0x6c, 0x26, 0xa5, 0x66, 0x8a, 0xbf, 0xc1, + 0xab, 0x4c, 0xc7, 0xf3, 0x5b, 0x7c, 0x5a, 0x1b, 0xf0, 0xdf, 0xb0, 0xc2, + 0xcc, 0xf3, 0xf0, 0xcf, 0x3f, 0x47, 0xef, 0xfb, 0x1f, 0x7b, 0x3e, 0xb0, + 0x39, 0x1b, 0xfc, 0xdf, 0xbf, 0xc1, 0xc8, 0xf3, 0xbe, 0xc1, 0xbd, 0xf3, + 0x1b, 0xb0, 0x18, 0x1b, 0xf0, 0xdf, 0xb0, 0xc0, 0xdc, 0xf3, 0xe8, 0x93, + 0xa0, 0x92, 0xbd, 0xba, 0xdb, 0xba, 0x8b, 0xee, 0x76, 0xa6, 0x73, 0xa3, + 0x9f, 0x6b, 0x33, 0xbc, 0x2b, 0xb1, 0x1f, 0x67, 0x62, 0x9a, 0x18, 0xf0, + 0x1f, 0x7b, 0x3c, 0xc0, 0xea, 0xf7, 0xb0, 0xc7, 0xbb, 0xf3, 0x9d, 0xbf, + 0xfb, 0xbf, 0xf2, 0xa7, 0xb4, 0xee, 0xf7, 0xa7, 0x9f, 0x7f, 0x18, 0x1b, + 0x0f, 0xdf, 0x9c, 0x1b, 0xf0, 0xdf, 0x33, 0x92, 0x1f, 0x5f, 0x1f, 0x7b, + 0x1b, 0xb0, 0xb0, 0xc0, 0x20, 0xf4, 0xfe, 0xeb, 0x6b, 0xeb, 0x1f, 0x67, + 0x22, 0xa1, 0x39, 0x1b, 0x00, 0xd0, 0xfc, 0xee, 0x37, 0xb9, 0x3f, 0x97, + 0x3c, 0x3b, 0xd8, 0xdb, 0x1f, 0x4b, 0x32, 0xf8, 0xbe, 0x73, 0xe0, 0xef, + 0xbb, 0xb5, 0xb7, 0xbd, 0x3f, 0x97, 0x37, 0x93, 0x9f, 0x4b, 0xfd, 0x6b, + 0x9e, 0x6b, 0x32, 0x84, 0x1f, 0x7b, 0x1b, 0xb0, 0x3c, 0xf8, 0x7c, 0xc0, + 0xb0, 0xc7, 0x1f, 0x5b, 0xdf, 0xf3, 0x9d, 0xbf, 0xfb, 0xbf, 0xf2, 0xa7, + 0x8b, 0xef, 0xf3, 0xa7, 0x9f, 0x7f, 0x18, 0x1b, 0x0f, 0xdf, 0x9c, 0x1b, + 0xf0, 0xdf, 0x33, 0x92, 0x1f, 0x5f, 0x1f, 0x7b, 0x1b, 0xb0, 0xb6, 0xa6, + 0xf1, 0xef, 0xbf, 0xa5, 0xfd, 0x6d, 0x9e, 0x6d, 0x32, 0x84, 0x55, 0xf8, + 0xd5, 0xef, 0x9b, 0x7e, 0x1b, 0xb0, 0x18, 0x1b, 0xf0, 0xdf, 0x9c, 0x1b, + 0xf0, 0xcf, 0x23, 0x93, 0x9b, 0x5e, 0x5f, 0xf8, 0xfa, 0xef, 0x9b, 0x7f, + 0x1b, 0xb0, 0x18, 0x1b, 0xf0, 0xdf, 0x9c, 0x1b, 0xf0, 0xcf, 0x23, 0x93, + 0x9b, 0x5f, 0x19, 0xf8, 0xd7, 0xfe, 0xff, 0xdf, 0xcf, 0xfe, 0xff, 0xdf, + 0x00, 0xff, 0x0f, 0x00, 0x2f, 0xeb, 0x00, 0x1c, 0xd0, 0x0c, 0x00, 0x1c, + 0x26, 0x17, 0x00, 0x1c, 0x56, 0x01, 0x00, 0x1c, 0xba, 0x0c, 0x00, 0x1c, + 0xda, 0x02, 0x00, 0x1c, 0x26, 0x05, 0x00, 0x1c, 0x10, 0x0b, 0x00, 0x1c, + 0x16, 0x0d, 0x00, 0x1c, 0x3e, 0x02, 0x00, 0x1c, 0x1c, 0x02, 0x00, 0x1c, + 0xd2, 0x0c, 0x00, 0x1c, 0xa4, 0x00, 0x00, 0x1c, 0x12, 0x02, 0x03, 0xf8, + 0x9a, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xfc, 0x93, 0xfc, 0x93, 0xbd, 0x1b, + 0x34, 0xf8, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xbf, + 0x97, 0xef, 0xfb, 0x6c, 0xff, 0x1b, 0x00, 0xdc, 0xd6, 0xcc, 0xf3, 0x9b, + 0xf7, 0xf7, 0xd7, 0xd7, 0xfe, 0x8b, 0x0a, 0xdc, 0xf3, 0x9b, 0xfc, 0xf7, + 0xfc, 0xd7, 0xfe, 0x8b, 0xc3, 0x87, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xbf, + 0x9a, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xfc, 0x93, 0xfc, 0x93, 0xbd, 0x1b, + 0x34, 0xf8, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xbf, + 0xb3, 0xef, 0xff, 0xcc, 0x9f, 0x4d, 0xff, 0x8b, 0xfc, 0x93, 0xfc, 0x93, + 0xfc, 0x93, 0xfd, 0xbf, 0x9f, 0x13, 0x7f, 0xf8, 0x9f, 0x4d, 0xfc, 0x93, + 0x9f, 0x6d, 0x3f, 0xc4, 0x01, 0xf0, 0xb9, 0xef, 0xf7, 0xa7, 0xff, 0x6f, + 0x9c, 0xef, 0xff, 0xcd, 0xff, 0x1b, 0x00, 0xdc, 0xbf, 0x4c, 0xc3, 0x87, + 0xff, 0x7f, 0xff, 0xbf, 0xfb, 0x7f, 0xff, 0xbf, 0x9d, 0xee, 0xff, 0xce, + 0xdd, 0x4c, 0xbc, 0x6c, 0x53, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, 0x72, 0xc5, + 0x71, 0xc5, 0x51, 0xc5, 0xbc, 0x4c, 0xbf, 0x6c, 0x77, 0xc5, 0x76, 0xc5, + 0x57, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0xc4, 0xef, 0x7b, 0x97, 0xbf, 0x4c, + 0xc2, 0xcd, 0xb7, 0x5c, 0xbd, 0x6c, 0xc6, 0xef, 0x7b, 0x97, 0x50, 0xc5, + 0xbd, 0x4c, 0xbd, 0x6c, 0x56, 0xc5, 0xbd, 0x4c, 0xbf, 0x6c, 0x7e, 0xc5, + 0xbf, 0x4c, 0xbd, 0x6c, 0x4c, 0xc5, 0xbd, 0x4c, 0xdc, 0x6c, 0xde, 0xb6, + 0xde, 0x1b, 0xe0, 0xdf, 0xbc, 0x6c, 0x5d, 0xc6, 0xde, 0xbe, 0xbd, 0x1b, + 0xc1, 0xcf, 0x7b, 0x93, 0xbc, 0x4c, 0xdc, 0x6c, 0xde, 0xb6, 0xde, 0x1b, + 0xe0, 0xdf, 0xbc, 0x6c, 0x5e, 0xc6, 0xde, 0xbe, 0xbd, 0x1b, 0xc1, 0xcf, + 0x7b, 0x93, 0xbc, 0x4c, 0xbd, 0x6c, 0xd7, 0xef, 0x7b, 0x97, 0x4a, 0xc5, + 0xbd, 0x4c, 0xbf, 0x6c, 0xbd, 0x13, 0xcf, 0xff, 0xbf, 0x4c, 0xc3, 0x87, + 0xff, 0x5f, 0xff, 0xbf, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x00, 0x9b, 0xef, 0xa9, 0xbf, 0xfe, 0x6c, 0xf5, 0xbf, + 0xf5, 0xb7, 0xf7, 0x93, 0xfe, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, + 0x95, 0xef, 0xbe, 0x6c, 0xb5, 0xbd, 0xb5, 0xb5, 0xe9, 0xbf, 0xf7, 0x93, + 0xfe, 0x4c, 0xbe, 0x1b, 0x80, 0xdf, 0xf8, 0xef, 0xde, 0x6c, 0xb7, 0xbd, + 0xbf, 0x97, 0xb7, 0x93, 0xde, 0x4c, 0xbe, 0x6c, 0x5f, 0xc5, 0xbe, 0x4c, + 0xc3, 0x87, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xbf, 0x00, 0x7f, 0x00, 0x00, + 0x9c, 0xef, 0xbe, 0x6c, 0x7f, 0xc5, 0xbe, 0x4c, 0xc3, 0x87, 0xff, 0xff, + 0xff, 0x5f, 0xff, 0xbf, 0x98, 0xef, 0xff, 0xcd, 0xb7, 0x5c, 0xdd, 0x6c, + 0xb9, 0xef, 0xb7, 0x97, 0xdd, 0x4c, 0xfe, 0xce, 0xd7, 0x5c, 0xdd, 0x6c, + 0x7b, 0x97, 0x50, 0xc5, 0xbd, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, + 0x00, 0xf0, 0x00, 0x00, 0xff, 0x8b, 0xbf, 0xc7, 0xf6, 0xf7, 0x93, 0xef, + 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x7d, 0xc5, 0xbf, 0x4c, + 0xc3, 0x87, 0x97, 0xef, 0xbf, 0x6c, 0x5c, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, + 0x5d, 0xc5, 0xbf, 0x4c, 0xbd, 0x6c, 0xda, 0xef, 0x7b, 0x97, 0xbd, 0x4c, + 0xbd, 0x6c, 0x6c, 0xc5, 0xbd, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, + 0x00, 0x00, 0xf0, 0x00, 0x9a, 0xef, 0xbf, 0x1b, 0xfc, 0xdf, 0xff, 0x6c, + 0xbb, 0xbd, 0x7b, 0xc7, 0x7a, 0xc7, 0xf7, 0x93, 0xff, 0x4c, 0xc3, 0x87, + 0xff, 0x5f, 0xff, 0xbf, 0x9a, 0xef, 0xbf, 0x1b, 0xf0, 0xdf, 0xda, 0xef, + 0xfd, 0x6c, 0xab, 0xbd, 0xfb, 0x97, 0xf7, 0x93, 0xfd, 0x4c, 0xc3, 0x87, + 0xff, 0x5f, 0xff, 0xbf, 0x00, 0x00, 0xf0, 0x00, 0x9c, 0xef, 0xfd, 0x6c, + 0xeb, 0xb7, 0xff, 0x1b, 0xf0, 0xdf, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, + 0x9d, 0xef, 0xfe, 0x6c, 0xe9, 0xb7, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, + 0x98, 0xef, 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, 0xfc, 0x93, 0xfc, 0x93, + 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xbf, 0x6c, 0x7e, 0xc5, + 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x2d, 0xeb, 0x7c, 0xec, + 0x9f, 0x7b, 0x3b, 0xc4, 0x96, 0xf7, 0xbe, 0x7b, 0xff, 0xdd, 0x77, 0x8b, + 0x80, 0xed, 0xbe, 0x5b, 0x3f, 0xc5, 0xea, 0xf3, 0x3f, 0xcd, 0xb6, 0xbd, + 0xde, 0x6c, 0xbe, 0x3b, 0xdf, 0xdf, 0x7f, 0xcd, 0xb6, 0xbd, 0x7d, 0x9b, + 0x5f, 0xf3, 0xba, 0x7c, 0xb7, 0x8b, 0x3f, 0xc6, 0xa6, 0xf7, 0x11, 0x26, + 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0xab, 0xed, 0xf1, 0xce, 0xdf, 0x5d, 0xbf, 0x7c, 0x39, 0xc5, 0xe9, 0xf7, + 0xda, 0x7c, 0xbe, 0x1b, 0xbf, 0xdf, 0xbf, 0xc5, 0x7c, 0x9b, 0xb9, 0xbd, + 0x79, 0xc6, 0x7b, 0x93, 0xba, 0x5c, 0xbd, 0x1b, 0xbf, 0xdf, 0x77, 0x8b, + 0xbf, 0xc5, 0x3d, 0xf7, 0x94, 0xed, 0xbf, 0x6c, 0x7d, 0xc5, 0xbf, 0x4c, + 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, 0xff, 0xcd, 0xbe, 0x5b, 0x3f, 0xcd, + 0xb6, 0xbd, 0xde, 0x6b, 0xbe, 0x3b, 0xdf, 0xdf, 0x7f, 0xcd, 0xb7, 0xbd, + 0x7d, 0x9b, 0x9e, 0xed, 0x48, 0xf3, 0xbb, 0x7c, 0xfd, 0x1b, 0xe0, 0xcf, + 0xbf, 0x8a, 0xbf, 0xc2, 0xb9, 0xf7, 0xff, 0xde, 0xde, 0x1b, 0xe0, 0xdf, + 0xdf, 0x3b, 0xdd, 0xdb, 0xd0, 0xc6, 0xb4, 0x92, 0xbb, 0x5c, 0x43, 0xf7, + 0x5a, 0x1b, 0xe0, 0xcf, 0x5b, 0x5c, 0xf3, 0x5c, 0x9a, 0x7b, 0x9c, 0x1b, + 0x01, 0xdf, 0x9c, 0x1b, 0xe1, 0xcf, 0x5a, 0xc4, 0x9a, 0x5b, 0x9b, 0x7b, + 0x9c, 0x1b, 0xe0, 0xdf, 0x59, 0xc4, 0x9b, 0x5b, 0x11, 0x26, 0xfd, 0xdf, + 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xf8, 0xcf, + 0x00, 0x1c, 0x9f, 0x00, 0x6a, 0xf8, 0xf3, 0xee, 0xf2, 0xcb, 0x7f, 0x5f, + 0xff, 0x7c, 0x39, 0xc7, 0x5c, 0xf4, 0xde, 0x1b, 0xbf, 0xdf, 0xbf, 0xc6, + 0xbc, 0x9b, 0xd9, 0xbe, 0x79, 0xc5, 0x7b, 0x93, 0xba, 0x5c, 0xbd, 0x1b, + 0xbf, 0xdf, 0x77, 0x8b, 0xbf, 0xc5, 0x1d, 0xf7, 0x9c, 0xee, 0xbf, 0x6c, + 0x7d, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, 0x11, 0x26, + 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0xfa, 0xb6, 0xff, 0x1b, 0xf8, 0xdf, 0xbd, 0xc7, 0x7a, 0xf3, 0xdd, 0xc7, + 0x8f, 0xf7, 0xbc, 0xc7, 0x48, 0xf3, 0xbb, 0xc7, 0x82, 0xf4, 0xbd, 0x1b, + 0xe0, 0xdf, 0x5a, 0xc5, 0xbb, 0x5c, 0xb2, 0x7c, 0xda, 0x7c, 0x77, 0x8b, + 0x5f, 0xc6, 0xbf, 0xc5, 0xda, 0x5c, 0x2d, 0xf7, 0xbe, 0x6c, 0x70, 0xc5, + 0x6f, 0xc5, 0x50, 0xc5, 0xbe, 0x4c, 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, + 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xf3, 0xcf, 0xb5, 0xef, + 0xff, 0x5d, 0xb4, 0xef, 0xff, 0x6d, 0x76, 0xc7, 0xff, 0x4d, 0xff, 0x6d, + 0x79, 0xc7, 0xff, 0x4d, 0xfd, 0x6d, 0xbe, 0x6d, 0xff, 0xcf, 0xba, 0xef, + 0xff, 0x4d, 0x70, 0xc6, 0x6f, 0xc6, 0xf6, 0xfb, 0x83, 0xfe, 0xff, 0xdf, + 0x78, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0xbf, 0xff, 0x4f, 0xff, 0xbf, + 0xbf, 0x7c, 0xde, 0x4c, 0xbd, 0x1b, 0x01, 0xdf, 0xbf, 0x5c, 0xb9, 0x7c, + 0xdd, 0x1b, 0xfd, 0xdf, 0xbb, 0x8b, 0xbf, 0xc6, 0xf8, 0xf3, 0xdf, 0x7c, + 0xbb, 0x8b, 0x59, 0xc6, 0x7e, 0xc5, 0xdf, 0x5c, 0xb9, 0x5c, 0x7f, 0xcc, + 0xfd, 0x6b, 0x89, 0xbc, 0xf2, 0x9b, 0xf5, 0xf7, 0xff, 0x1f, 0x03, 0xfb, + 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, + 0x9e, 0xeb, 0x00, 0x1c, 0x2e, 0x19, 0x90, 0xed, 0xff, 0xce, 0xdd, 0x4c, + 0xff, 0x1f, 0x11, 0xfb, 0x0d, 0xf8, 0x92, 0xed, 0xbf, 0x6c, 0x5d, 0xc5, + 0xbf, 0x4c, 0xbf, 0x6c, 0x7e, 0xc5, 0xbf, 0x4c, 0xc0, 0xf8, 0x70, 0xc6, + 0x6f, 0xc6, 0x4f, 0xc6, 0xde, 0x4c, 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, + 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xbe, 0xc7, 0xae, 0xf0, + 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, + 0x9e, 0xeb, 0xba, 0x7c, 0x5f, 0xc5, 0xba, 0x5c, 0x11, 0x26, 0xfd, 0xdf, + 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xb2, 0x7c, + 0xb2, 0x7c, 0x77, 0x8b, 0xbf, 0xc5, 0xa7, 0xf3, 0x9b, 0x6c, 0xdf, 0x7c, + 0x9e, 0x6b, 0x96, 0xb4, 0x9c, 0x1b, 0xf0, 0xdf, 0xb1, 0x8f, 0xac, 0xee, + 0x3f, 0xc6, 0xb5, 0xf3, 0xda, 0x7d, 0x5f, 0xc6, 0xfe, 0x1b, 0xdf, 0xdf, + 0xbf, 0xc7, 0xfc, 0x9b, 0xfa, 0xbf, 0x7a, 0xc6, 0xbf, 0x93, 0xda, 0x5d, + 0xff, 0xdc, 0x9c, 0x1b, 0xf0, 0xdf, 0xda, 0x7b, 0xde, 0x1b, 0xe1, 0xcf, + 0xbe, 0xbc, 0x7b, 0x93, 0xb7, 0xc4, 0xf7, 0xee, 0xb4, 0x93, 0xba, 0x5b, + 0x26, 0xf5, 0x9b, 0x7f, 0x9c, 0x1b, 0xe0, 0xdf, 0xde, 0x1b, 0xe1, 0xcf, + 0x9c, 0x13, 0x9f, 0xff, 0xda, 0x5f, 0x9b, 0x5f, 0x11, 0x26, 0xfd, 0xdf, + 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xfa, 0x7c, + 0xd2, 0xb6, 0x7f, 0xc7, 0xde, 0x1b, 0xfe, 0xdf, 0xbf, 0x93, 0xff, 0xcf, + 0xbd, 0x1b, 0xe0, 0xdf, 0x80, 0xd7, 0x7f, 0x93, 0xda, 0x5c, 0xbb, 0x5c, + 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, + 0x9e, 0xeb, 0x8a, 0xef, 0xbf, 0x6c, 0x5d, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, + 0x7e, 0xc5, 0xbf, 0x4c, 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, + 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xda, 0x7d, 0x7f, 0xc6, 0xda, 0x5d, + 0x41, 0xf8, 0xd3, 0x7c, 0x55, 0xf8, 0xbb, 0x6c, 0xff, 0x7d, 0xff, 0xdd, + 0xbb, 0x4c, 0xb2, 0x7c, 0xd3, 0x7c, 0xff, 0xd5, 0xbe, 0x93, 0x77, 0x8b, + 0xd3, 0x5c, 0xb2, 0x5c, 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, + 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xff, 0xff, 0x83, 0xfe, 0xff, 0xdf, + 0xff, 0x9f, 0xff, 0xbf, 0xff, 0x8b, 0xbf, 0xc7, 0xf5, 0xf7, 0x97, 0xef, + 0xb9, 0x7c, 0x7e, 0xc5, 0xb9, 0x5c, 0xbf, 0x7c, 0xbd, 0x1b, 0x40, 0xdf, + 0xbf, 0x5c, 0xc3, 0x87, 0x9c, 0xef, 0xb9, 0x7c, 0x5e, 0xc5, 0xb9, 0x5c, + 0xc3, 0x87, 0xff, 0xff, 0x83, 0xfe, 0xff, 0xdf, 0x2e, 0xeb, 0xff, 0xcc, + 0x77, 0xef, 0xb6, 0xef, 0x9f, 0x4d, 0xf1, 0xa3, 0xff, 0xce, 0xfb, 0xcd, + 0x9f, 0x5b, 0x9b, 0x4b, 0x92, 0x5b, 0x00, 0x1c, 0xd6, 0x19, 0x9f, 0x7b, + 0x33, 0x8b, 0x5e, 0xc4, 0x9f, 0x5b, 0x6e, 0xeb, 0x83, 0xfe, 0xff, 0xdf, + 0xff, 0x9f, 0xff, 0xbf, 0x9c, 0xef, 0xff, 0x7c, 0xff, 0x1b, 0xfe, 0xdf, + 0xc3, 0x87, 0xff, 0xff, 0x83, 0xfe, 0xff, 0xdf, 0x2e, 0xeb, 0x70, 0xee, + 0xff, 0xcc, 0xbb, 0x8b, 0x93, 0x5b, 0x9e, 0x5b, 0x9a, 0x7b, 0xd2, 0x5b, + 0x7f, 0xc4, 0x79, 0xc4, 0x9a, 0x5b, 0x9f, 0x7b, 0x33, 0x8b, 0x5f, 0xc4, + 0xbb, 0x7b, 0x9f, 0x5b, 0xbd, 0x1b, 0xe0, 0xdf, 0x9f, 0x7b, 0xfb, 0x4b, + 0xfd, 0x4b, 0xbb, 0x5b, 0x3e, 0xc4, 0xf4, 0xf3, 0x9f, 0x7b, 0x3b, 0xc4, + 0xcc, 0xf7, 0xfa, 0xcf, 0x00, 0x1c, 0x0f, 0x02, 0x9e, 0xee, 0xbd, 0x6c, + 0x4c, 0xc5, 0xbd, 0x4c, 0x9f, 0x7b, 0x3a, 0xc4, 0xd2, 0xf7, 0x80, 0xef, + 0xbf, 0x6c, 0x5c, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x58, 0xc5, 0xbf, 0x4c, + 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, 0x84, 0xef, 0x9f, 0x6c, 0xbe, 0xc4, + 0xd8, 0xf3, 0xf4, 0xcd, 0x86, 0xef, 0xbf, 0x5c, 0x86, 0xef, 0xbf, 0x6c, + 0xbd, 0x1b, 0xe0, 0xcf, 0x5e, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x78, 0xc5, + 0x77, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, + 0x59, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x5a, 0xc5, 0xbf, 0x4c, 0x46, 0xcd, + 0xbe, 0x4c, 0xbd, 0x4c, 0x6e, 0xeb, 0xf8, 0xcf, 0x00, 0x1c, 0x41, 0x02, + 0x31, 0xf8, 0xf0, 0xcf, 0x00, 0x1c, 0x45, 0x02, 0x99, 0xef, 0xbd, 0x6c, + 0x4c, 0xc5, 0xbd, 0x4c, 0x32, 0xf8, 0xfd, 0xcf, 0x00, 0x1c, 0x59, 0x02, + 0x28, 0xf8, 0xff, 0xff, 0x83, 0xfe, 0xff, 0xdf, 0xff, 0x5f, 0xff, 0xbf, + 0xff, 0x9f, 0xff, 0xbf, 0x47, 0xfe, 0xff, 0xdf, 0x78, 0xff, 0xff, 0xdf, + 0xff, 0x4f, 0xff, 0xbf, 0xbf, 0xc6, 0xff, 0x8b, 0xf4, 0xf7, 0xb5, 0xef, + 0xff, 0xcc, 0xdf, 0x7d, 0xfe, 0xd4, 0xbb, 0x8b, 0xfc, 0x3b, 0xff, 0xbe, + 0xfb, 0x97, 0xff, 0x5d, 0xc3, 0x87, 0xba, 0xef, 0xfe, 0xcc, 0xdf, 0x7d, + 0xfc, 0x3b, 0xdf, 0xbf, 0xfb, 0x93, 0xff, 0x8b, 0xff, 0x5d, 0xc3, 0x87, + 0x83, 0xfe, 0xff, 0xdf, 0x2f, 0xeb, 0x91, 0xef, 0xbf, 0x7c, 0x3b, 0xc5, + 0xfa, 0xf7, 0xb2, 0xef, 0xdd, 0x6d, 0x6c, 0xc6, 0xdd, 0x4d, 0x9f, 0x7c, + 0x3e, 0xc4, 0xf2, 0xf3, 0x97, 0xef, 0x9f, 0x7c, 0x3b, 0xc4, 0xfa, 0xf3, + 0xf8, 0xcf, 0x00, 0x1c, 0x86, 0x02, 0x6f, 0xeb, 0xfa, 0xcf, 0x00, 0x1c, + 0x8a, 0x02, 0x6f, 0xeb, 0xff, 0xcf, 0x00, 0x1c, 0x8e, 0x02, 0x6f, 0xeb, + 0x83, 0xfe, 0xff, 0xdf, 0xff, 0x5f, 0xff, 0xbf, 0x9b, 0xef, 0xfe, 0xce, + 0xbe, 0x6c, 0xfe, 0x3b, 0xdf, 0xbf, 0xf7, 0x93, 0xfe, 0x4c, 0xc3, 0x87, + 0xff, 0xaf, 0xff, 0xbf, 0xff, 0xcc, 0xbb, 0xef, 0xfe, 0xd4, 0xde, 0x6d, + 0x3c, 0x8f, 0x3b, 0x97, 0x9e, 0x4d, 0xc3, 0x87, 0xff, 0xaf, 0xff, 0xbf, + 0x98, 0xef, 0xfe, 0xce, 0xbc, 0x6c, 0xfe, 0x3b, 0xdf, 0xbf, 0x7f, 0x93, + 0xbc, 0x4c, 0xb8, 0x6c, 0x7f, 0x93, 0xb8, 0x4c, 0xba, 0x6c, 0xf7, 0x93, + 0xfa, 0x4c, 0xc3, 0x87, 0xff, 0xaf, 0xff, 0xbf, 0x9b, 0xef, 0xfe, 0xce, + 0xbd, 0x6c, 0xfe, 0x3b, 0xdf, 0xbf, 0xf7, 0x93, 0xfd, 0x4c, 0xc3, 0x87, + 0xff, 0xaf, 0xff, 0xbf, 0x2e, 0xeb, 0x70, 0xef, 0x9d, 0x6b, 0x5e, 0xc4, + 0x9d, 0x4b, 0x9e, 0x6b, 0x5e, 0xc4, 0x9e, 0x4b, 0x9d, 0x6b, 0x5c, 0xc4, + 0x9d, 0x4b, 0x9e, 0x6b, 0x7c, 0xc4, 0x9e, 0x4b, 0x9d, 0x6b, 0x5b, 0xc4, + 0x9d, 0x4b, 0x9e, 0x6b, 0x7b, 0xc4, 0x9e, 0x4b, 0xff, 0xcf, 0x00, 0x1c, + 0x2e, 0x00, 0xff, 0xcd, 0x9b, 0xef, 0xbf, 0x5c, 0x9f, 0x6b, 0x3f, 0xc4, + 0x01, 0xf4, 0x6e, 0xeb, 0xff, 0xaf, 0xff, 0xbf, 0x6f, 0xfe, 0xff, 0xdf, + 0xfe, 0xcd, 0x9a, 0xef, 0x9f, 0x6c, 0xfd, 0x3b, 0xdf, 0xbf, 0xf3, 0x97, + 0xbf, 0xc7, 0xff, 0x3b, 0xff, 0xfa, 0xc3, 0x87, 0xff, 0xaf, 0xff, 0xbf, + 0x9f, 0xeb, 0x9d, 0xeb, 0x2e, 0xeb, 0x66, 0xee, 0x9f, 0x7b, 0xbf, 0xc4, + 0xdc, 0xf7, 0x9e, 0x7b, 0xff, 0xdc, 0x33, 0x8b, 0xfd, 0xcd, 0x37, 0x9b, + 0x9e, 0x5b, 0xc4, 0xf3, 0xfd, 0xcc, 0xff, 0xcf, 0x9f, 0x5b, 0xfd, 0x4b, + 0xfe, 0xcc, 0xed, 0xee, 0x9d, 0x53, 0x00, 0x1c, 0x98, 0x05, 0xfc, 0xcd, + 0x8f, 0xee, 0xbf, 0x5c, 0x00, 0x1c, 0x95, 0x00, 0x90, 0xee, 0xff, 0xcd, + 0xbf, 0x4c, 0x90, 0xee, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0x11, 0x26, + 0xfe, 0xdf, 0x7f, 0x67, 0xfd, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x3f, 0xcf, + 0xbb, 0x6b, 0x3f, 0xcc, 0xf6, 0xbf, 0x96, 0xbc, 0xfd, 0x3b, 0xde, 0xdf, + 0x39, 0x9b, 0xdb, 0xf3, 0x9b, 0xee, 0xff, 0xcd, 0xbf, 0x4c, 0x9b, 0xee, + 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0x9d, 0x6b, 0xfd, 0xcd, 0xbe, 0x5c, + 0xf1, 0xa3, 0x00, 0x1c, 0xc0, 0x05, 0xfa, 0xcd, 0x83, 0xef, 0xbf, 0x5c, + 0x11, 0x26, 0xfe, 0xdf, 0x7f, 0x67, 0xfd, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0xfc, 0xcf, 0x00, 0x1c, 0x9a, 0x00, 0xfb, 0xcf, 0x00, 0x1c, 0x9d, 0x00, + 0xfb, 0xcf, 0x00, 0x1c, 0xa6, 0x06, 0xfe, 0xcd, 0x89, 0xef, 0xbf, 0x5c, + 0x45, 0xf8, 0x8b, 0xef, 0xdf, 0x6c, 0x70, 0xc5, 0x6f, 0xc5, 0x5c, 0xc6, + 0xdf, 0x4c, 0xbb, 0x4b, 0x90, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xbf, 0x6c, + 0xbd, 0x13, 0x9d, 0xff, 0xff, 0x15, 0x77, 0x6f, 0xbf, 0x4c, 0xfe, 0x4c, + 0xfd, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, 0xbf, 0x4c, 0xfb, 0xcd, 0x98, 0xef, + 0xbf, 0x5c, 0x11, 0x26, 0xfe, 0xdf, 0x7f, 0x67, 0xfd, 0xeb, 0x9c, 0xeb, + 0x9e, 0xeb, 0xff, 0xff, 0x6b, 0xfe, 0xff, 0xdf, 0x67, 0xfe, 0xff, 0xdf, + 0x78, 0xff, 0xff, 0xdf, 0xff, 0xef, 0xff, 0xbf, 0xff, 0x8f, 0xff, 0xbf, + 0x0f, 0xff, 0xff, 0xdf, 0x9f, 0xeb, 0x9d, 0xeb, 0x2b, 0xeb, 0x7e, 0xec, + 0x9f, 0x7b, 0xbf, 0xc4, 0xd4, 0xf3, 0x3f, 0xcc, 0x96, 0xbc, 0xdb, 0x6b, + 0x9e, 0x3b, 0xdd, 0xdf, 0x7f, 0xcc, 0x96, 0xbc, 0x35, 0x9b, 0x86, 0xf3, + 0xbf, 0xc5, 0xf1, 0xf3, 0x7f, 0xcc, 0x97, 0xbc, 0x35, 0x9b, 0xc4, 0xf3, + 0x11, 0x26, 0xfb, 0xdf, 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, 0x7f, 0x67, + 0xfa, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x8b, 0xed, 0x9e, 0x6c, 0x8d, 0xbc, + 0x70, 0xc6, 0x6f, 0xc6, 0x8d, 0xb4, 0x50, 0xc6, 0x95, 0x53, 0xdb, 0x4b, + 0x11, 0x26, 0xfb, 0xdf, 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, 0x7f, 0x67, + 0xfa, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xb3, 0xed, 0xff, 0xce, 0xdf, 0x4d, + 0xb6, 0xed, 0xdf, 0x6d, 0x7c, 0xc6, 0xdf, 0x4d, 0x9e, 0x5b, 0xfd, 0xcc, + 0x9f, 0x5b, 0xff, 0xcd, 0xfe, 0xcc, 0xf1, 0xa3, 0x9d, 0x53, 0xbd, 0x4b, + 0x00, 0x1c, 0x43, 0x06, 0xf9, 0xcd, 0x9b, 0xed, 0xbf, 0x5c, 0x00, 0x1c, + 0x40, 0x01, 0x11, 0x26, 0xfb, 0xdf, 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, + 0x7f, 0x67, 0xfa, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x84, 0xee, 0xde, 0x6c, + 0xcd, 0xbe, 0xb5, 0x73, 0xcd, 0xb6, 0x76, 0x8b, 0xb7, 0x9b, 0xd7, 0xf7, + 0xbe, 0x6c, 0xad, 0xbd, 0x95, 0x73, 0xad, 0xb5, 0x32, 0x8b, 0x92, 0xa5, + 0xdb, 0xc4, 0x3c, 0x9b, 0xbf, 0xc4, 0x4a, 0xf0, 0x9b, 0x6b, 0x70, 0xc4, + 0x6f, 0xc4, 0x4f, 0xc4, 0x9b, 0x4b, 0xff, 0xcd, 0x8f, 0xee, 0xbf, 0x4c, + 0xbf, 0x4c, 0xbf, 0x6c, 0xbd, 0x13, 0x9d, 0xff, 0xfe, 0x15, 0x8b, 0xf1, + 0xbf, 0x4c, 0xde, 0x4c, 0xdd, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, 0xbf, 0x4c, + 0x11, 0x26, 0xfb, 0xdf, 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, 0x7f, 0x67, + 0xfa, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xb5, 0x73, 0x9e, 0x6c, 0x8d, 0xbc, + 0x76, 0x8b, 0x8d, 0xb4, 0x92, 0xa5, 0xdb, 0xc4, 0x3c, 0x9b, 0x26, 0xf8, + 0x9f, 0xee, 0xfe, 0x15, 0x8b, 0xf1, 0xde, 0x4c, 0x82, 0xef, 0xde, 0x6c, + 0xcd, 0xbe, 0xb5, 0x73, 0xcd, 0xb6, 0x76, 0x8b, 0xb7, 0x9b, 0xa9, 0xf3, + 0xb5, 0x73, 0x9e, 0x6c, 0x8d, 0xbc, 0x8d, 0xb4, 0xb2, 0xa5, 0x77, 0x8b, + 0xfb, 0xcc, 0x73, 0x9b, 0xab, 0xf7, 0x93, 0x7b, 0x5f, 0xc4, 0x93, 0x5b, + 0xfe, 0xcc, 0xb3, 0x7b, 0xde, 0xb5, 0xde, 0x1b, 0xfe, 0xdf, 0x39, 0x9b, + 0x50, 0xef, 0xa9, 0xf3, 0xff, 0xcc, 0xbc, 0xb5, 0x89, 0x5a, 0xbd, 0x1b, + 0xf0, 0xdf, 0x93, 0x7b, 0xdc, 0x1b, 0xfb, 0xdf, 0xbb, 0x8b, 0xbf, 0xc6, + 0x56, 0xef, 0xbd, 0xf7, 0xde, 0xc5, 0x26, 0xf7, 0xda, 0xc5, 0xa2, 0xf3, + 0x5d, 0xc4, 0xaf, 0x7a, 0x93, 0x5a, 0xbd, 0x1b, 0xfc, 0xdf, 0x93, 0x7b, + 0x9c, 0x1b, 0x87, 0xcf, 0x93, 0x5b, 0x9c, 0x1b, 0xfe, 0xdf, 0xf6, 0xfb, + 0x6b, 0xfe, 0xff, 0xdf, 0xff, 0x8f, 0xff, 0xbf, 0xff, 0xef, 0xff, 0xbf, + 0x78, 0xff, 0xff, 0xdf, 0xd3, 0x7b, 0x9e, 0xbc, 0x7e, 0xc6, 0x3b, 0x93, + 0x93, 0x5b, 0xde, 0xc5, 0xbb, 0xf0, 0xcf, 0x7b, 0x9e, 0x1b, 0xf3, 0xdf, + 0xbb, 0xc4, 0xfe, 0xec, 0xa9, 0xf3, 0xb7, 0xc4, 0x86, 0xf3, 0x8f, 0x7b, + 0x7f, 0xc4, 0x7e, 0xc4, 0x5e, 0xc4, 0x8f, 0x5b, 0x11, 0x26, 0xfb, 0xdf, + 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, 0x7f, 0x67, 0xfa, 0xeb, 0x9c, 0xeb, + 0x9e, 0xeb, 0xbe, 0x6c, 0xad, 0xbd, 0xad, 0xb5, 0x95, 0x73, 0xb2, 0xa5, + 0x77, 0x8b, 0x54, 0xf8, 0x93, 0x7b, 0x7f, 0xc4, 0x93, 0x5b, 0xff, 0xcc, + 0x52, 0xf8, 0xde, 0xc5, 0x71, 0xf7, 0xda, 0xc5, 0xdd, 0xf7, 0xaf, 0x7a, + 0xbd, 0x1b, 0xfc, 0xdf, 0x3e, 0xf8, 0xfc, 0xb5, 0xff, 0xdf, 0xc9, 0x7a, + 0xff, 0x1b, 0xf0, 0xdf, 0x3c, 0xbf, 0xff, 0xde, 0xbd, 0x1b, 0x87, 0xcf, + 0x67, 0x93, 0xbb, 0x8b, 0xdf, 0xc9, 0xa7, 0x9b, 0xc9, 0x5a, 0x34, 0x92, + 0xb3, 0x5a, 0x9f, 0xf3, 0xd3, 0xc7, 0xeb, 0xf3, 0xaf, 0x7a, 0xbd, 0x1b, + 0xfc, 0xdf, 0x46, 0xf8, 0x8f, 0x7a, 0x7f, 0xc4, 0x7e, 0xc4, 0x8f, 0x5a, + 0xff, 0xcd, 0x5b, 0xf8, 0xaf, 0x7a, 0x7f, 0xc5, 0x7e, 0xc5, 0x5f, 0xc5, + 0x7d, 0xc4, 0xaf, 0x5a, 0x93, 0x5a, 0xfe, 0xcd, 0x64, 0xf8, 0x9d, 0x1b, + 0xfb, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0xa8, 0xf7, 0x98, 0x1b, 0x87, 0xcf, + 0x59, 0xc4, 0x93, 0x5a, 0xf7, 0xcd, 0x7f, 0xf8, 0x99, 0x6f, 0xbf, 0x7c, + 0x77, 0x8b, 0xde, 0x1b, 0xfc, 0xdf, 0xbe, 0xb5, 0xbe, 0xc6, 0xbf, 0x5c, + 0x7a, 0xf3, 0xaf, 0x7b, 0x9b, 0xb5, 0xff, 0xdc, 0x9c, 0x1b, 0xf0, 0xdf, + 0xdb, 0xbc, 0xbd, 0x1b, 0xf0, 0xdf, 0x7b, 0x93, 0xb7, 0xc4, 0xf3, 0xee, + 0xaf, 0x5b, 0x67, 0xf4, 0x94, 0xee, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, + 0xff, 0xcd, 0x95, 0xee, 0xbf, 0x4c, 0x9d, 0x6f, 0xbe, 0x5c, 0xfe, 0xcd, + 0xbd, 0x5c, 0xfc, 0xdf, 0x00, 0x1c, 0x53, 0x07, 0x76, 0xf8, 0x8e, 0x7f, + 0x5c, 0x1b, 0x83, 0xdf, 0xbf, 0xc2, 0x94, 0xf3, 0x5c, 0x1b, 0xfc, 0xdf, + 0xbd, 0xc2, 0x8b, 0xf3, 0xbc, 0xc2, 0x66, 0xf3, 0xbe, 0xc2, 0x87, 0xf3, + 0xde, 0x1b, 0xfc, 0xdf, 0xbf, 0xc6, 0xbd, 0xf7, 0x7f, 0xc4, 0x7e, 0xc4, + 0x5f, 0xc4, 0x8e, 0x5f, 0x93, 0x7f, 0x9c, 0x1b, 0x80, 0xdf, 0x93, 0x5f, + 0x90, 0xf8, 0x88, 0xef, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0x89, 0xef, + 0xff, 0xcd, 0xbf, 0x4c, 0x9d, 0x6a, 0xfd, 0xcd, 0xbe, 0x5c, 0xf1, 0xa2, + 0x00, 0x1c, 0x7b, 0x07, 0xaf, 0x7a, 0xbd, 0x1b, 0xfc, 0xdf, 0xab, 0xf8, + 0x98, 0x1b, 0x87, 0xcf, 0x5a, 0xc4, 0x93, 0x5a, 0xfb, 0xcd, 0xd5, 0xf8, + 0x94, 0xef, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0x95, 0xef, 0xff, 0xcd, + 0xbf, 0x4c, 0x9d, 0x6a, 0xfe, 0xcd, 0x16, 0xf8, 0x99, 0xef, 0xbf, 0x6c, + 0x7c, 0xc5, 0xbf, 0x4c, 0x9a, 0xef, 0xdf, 0x4c, 0x9d, 0x6a, 0xfe, 0xcd, + 0x1f, 0xf8, 0xff, 0xff, 0x6b, 0xfe, 0xff, 0xdf, 0xff, 0x8f, 0xff, 0xbf, + 0xff, 0xef, 0xff, 0xbf, 0xb9, 0x6c, 0xbf, 0x7d, 0x83, 0x7c, 0x77, 0x8b, + 0x33, 0x8b, 0x35, 0x9b, 0x84, 0xf3, 0x9e, 0xec, 0xbf, 0x6c, 0x7c, 0xc5, + 0xbf, 0x4c, 0xff, 0xce, 0x80, 0xed, 0xdf, 0x4c, 0x9d, 0x6b, 0xfe, 0xcd, + 0xbe, 0x5c, 0xe1, 0xed, 0x00, 0x1c, 0xb3, 0x07, 0x11, 0x26, 0xfb, 0xdf, + 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, 0x7f, 0x67, 0xfa, 0xeb, 0x9c, 0xeb, + 0x9e, 0xeb, 0xff, 0xce, 0xbf, 0x7c, 0x80, 0xd6, 0x7b, 0x93, 0x77, 0x8b, + 0xbf, 0x5c, 0x89, 0xf8, 0x8d, 0xed, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, + 0x8e, 0xed, 0xff, 0xcd, 0xbf, 0x4c, 0x9d, 0x6f, 0x5e, 0x5c, 0xfc, 0xdf, + 0x00, 0x1c, 0xcf, 0x07, 0xf2, 0xf8, 0xd3, 0x7f, 0xd8, 0xb6, 0x79, 0x9b, + 0x2c, 0xf4, 0x9c, 0x13, 0xfc, 0xff, 0x8e, 0x5f, 0xfa, 0xf8, 0x99, 0x6f, + 0xbf, 0x7c, 0x77, 0x8b, 0xde, 0x1b, 0xfc, 0xdf, 0xbe, 0xb5, 0xbe, 0xc6, + 0xbf, 0x5c, 0x98, 0xf3, 0xef, 0x7b, 0xdb, 0xb7, 0xff, 0xde, 0xde, 0x1b, + 0xf0, 0xdf, 0xbb, 0xbe, 0xff, 0x1b, 0xf0, 0xdf, 0x7f, 0x93, 0xb7, 0xc6, + 0x9e, 0xed, 0xaf, 0x5b, 0x10, 0xf5, 0xbd, 0x1b, 0xf0, 0xdf, 0xaf, 0x5c, + 0xae, 0x7c, 0x7f, 0xc5, 0x7e, 0xc5, 0x5e, 0xc5, 0xae, 0x5c, 0x19, 0xf9, + 0xde, 0x1b, 0xfc, 0xdf, 0xbe, 0xc6, 0x53, 0xf4, 0x8d, 0x7f, 0xbc, 0x1b, + 0xfd, 0xdf, 0x77, 0x8b, 0xbf, 0xc5, 0xe5, 0xf7, 0x5e, 0xc4, 0x8d, 0x5f, + 0x99, 0x6f, 0x9f, 0x7c, 0x33, 0x8b, 0xe0, 0xcd, 0x37, 0x9b, 0xaf, 0xf7, + 0x81, 0xcd, 0x37, 0x9b, 0xb0, 0xf3, 0xe0, 0xd4, 0x9b, 0xac, 0xfc, 0xdc, + 0x33, 0x8b, 0xae, 0x7b, 0x9c, 0x1b, 0xe0, 0xdf, 0xdd, 0xbc, 0xbd, 0x1b, + 0x83, 0xcf, 0x7b, 0x93, 0xae, 0x5b, 0xbd, 0x6b, 0x9d, 0x5d, 0xae, 0x7b, + 0xbd, 0x1b, 0x83, 0xdf, 0xbb, 0xc5, 0x97, 0xee, 0x7f, 0xf0, 0x99, 0x6b, + 0xbf, 0x7c, 0xc3, 0x7b, 0xff, 0xdc, 0x7a, 0x93, 0x99, 0x4b, 0x8e, 0x7b, + 0x77, 0x8b, 0x7f, 0xc4, 0x7e, 0xc4, 0xa3, 0x5b, 0x70, 0x93, 0x9d, 0xb4, + 0xe1, 0xdc, 0x9c, 0x1b, 0xe0, 0xdf, 0x9d, 0xbc, 0xbd, 0x1b, 0x83, 0xcf, + 0x37, 0x93, 0x8e, 0x5b, 0x9c, 0x1b, 0x83, 0xdf, 0xbf, 0xc4, 0xe4, 0xef, + 0x5c, 0xf5, 0xa8, 0xef, 0xdf, 0x6d, 0x7c, 0xc6, 0xdf, 0x4d, 0xa9, 0xef, + 0xff, 0xce, 0xdf, 0x4d, 0xbd, 0x6f, 0x9e, 0x5d, 0xfc, 0xdf, 0x00, 0x1c, + 0x46, 0x08, 0x69, 0xf9, 0xff, 0xce, 0xbf, 0x7c, 0x80, 0xd6, 0x7b, 0x93, + 0x77, 0x8b, 0xbf, 0x5c, 0x93, 0x7f, 0xb8, 0xb4, 0xbd, 0x1b, 0xfe, 0xdf, + 0x75, 0x93, 0xb8, 0xbd, 0x9c, 0x1b, 0x80, 0xdf, 0x37, 0x93, 0x93, 0x5f, + 0x75, 0xf8, 0xfc, 0xcc, 0x48, 0xf8, 0x21, 0xcd, 0x37, 0x9b, 0xf9, 0xf3, + 0x80, 0xd4, 0x9c, 0xac, 0xf6, 0xdc, 0x33, 0x8b, 0x50, 0xf8, 0x20, 0xd4, + 0x9d, 0xac, 0xe0, 0xdc, 0x33, 0x8b, 0x55, 0xf8, 0xff, 0x8f, 0xff, 0xbf, + 0xff, 0xef, 0xff, 0xbf, 0x67, 0xfe, 0xff, 0xdf, 0x6b, 0xfe, 0xff, 0xdf, + 0xe8, 0xef, 0xff, 0xcc, 0x9f, 0x4f, 0x9f, 0x6f, 0x9c, 0x13, 0xfc, 0xff, + 0x9f, 0x4f, 0x9f, 0x6f, 0x5d, 0xc4, 0x9f, 0x4f, 0x9b, 0xce, 0x9e, 0x6f, + 0x3b, 0x9b, 0xae, 0xef, 0x02, 0xf4, 0x9f, 0x6d, 0x7c, 0xc4, 0x9f, 0x4d, + 0x90, 0xef, 0xff, 0xcd, 0xbe, 0x5c, 0xa2, 0x5c, 0xff, 0xcd, 0xb5, 0x54, + 0xb3, 0x7c, 0xbd, 0x1b, 0x87, 0xdf, 0xbd, 0x1b, 0x87, 0xcf, 0xb3, 0x5c, + 0xae, 0x7c, 0xbd, 0x1b, 0x03, 0xdf, 0xbd, 0x1b, 0x83, 0xcf, 0xae, 0x5c, + 0xff, 0xcd, 0xaf, 0x5c, 0xbb, 0x6c, 0x70, 0xc5, 0x6f, 0xc5, 0xbb, 0x4c, + 0xaf, 0xb5, 0x7e, 0xc5, 0xad, 0x5c, 0xc3, 0x87, 0xff, 0x8f, 0xff, 0xbf, + 0x6b, 0xfe, 0xff, 0xdf, 0x2f, 0xeb, 0xad, 0xef, 0xff, 0xcc, 0x9f, 0x5d, + 0xff, 0xce, 0x8e, 0xef, 0xdf, 0x4c, 0xdf, 0x6c, 0xdf, 0x4c, 0xdf, 0x6c, + 0x5d, 0xc6, 0xdf, 0x4c, 0x9e, 0x7d, 0xbf, 0xc4, 0xfb, 0xf3, 0xf0, 0xcf, + 0x00, 0x1c, 0x21, 0x06, 0x95, 0xef, 0xbf, 0x6c, 0x5c, 0xc5, 0xbf, 0x4c, + 0x96, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xbf, 0x6c, 0xbd, 0x13, 0x9d, 0xff, + 0x46, 0xce, 0xbf, 0x4c, 0xde, 0x4c, 0xdd, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, + 0xbf, 0x4c, 0x6f, 0xeb, 0x6b, 0xfe, 0xff, 0xdf, 0xff, 0x8f, 0xff, 0xbf, + 0xff, 0xef, 0xff, 0xbf, 0x9e, 0xee, 0xff, 0x8b, 0xf9, 0xcd, 0xbd, 0x54, + 0xdd, 0x4c, 0xff, 0x5e, 0xfd, 0xde, 0xd9, 0x4c, 0xb3, 0x7c, 0xfd, 0xce, + 0x7b, 0x93, 0xbd, 0x1b, 0x87, 0xcf, 0x7d, 0xc5, 0xb3, 0x5c, 0xae, 0x7c, + 0xbd, 0x1b, 0x03, 0xdf, 0xff, 0x1b, 0xfc, 0xdf, 0xfd, 0xbf, 0xbd, 0x1b, + 0x83, 0xcf, 0xbf, 0x93, 0x5d, 0xc5, 0xcf, 0x5c, 0xae, 0x5c, 0xbb, 0x6c, + 0x50, 0xc5, 0x4f, 0xc5, 0xbb, 0x4c, 0xaf, 0xb5, 0x7e, 0xc5, 0xad, 0x5c, + 0xff, 0xce, 0xae, 0xef, 0xdf, 0x4d, 0xff, 0x6d, 0xff, 0x13, 0xfc, 0xff, + 0xff, 0x4d, 0xff, 0x6d, 0x5d, 0xc7, 0xff, 0x4d, 0xff, 0x6d, 0x7c, 0xc7, + 0xff, 0x4d, 0xfe, 0xcd, 0xc3, 0x5c, 0xbf, 0x5c, 0xc9, 0x5c, 0x95, 0xef, + 0xdf, 0x4c, 0xbf, 0x6c, 0xbd, 0x13, 0x9d, 0xff, 0xbf, 0x4c, 0xfd, 0x15, + 0xa9, 0xfb, 0xbe, 0x4c, 0xbd, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, 0xbf, 0x4c, + 0xc3, 0x87, 0xff, 0xff, 0x6b, 0xfe, 0xff, 0xdf, 0xff, 0x8f, 0xff, 0xbf, + 0xff, 0xef, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, 0x93, 0xef, 0xb2, 0xef, + 0xbf, 0x4c, 0x92, 0xef, 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, + 0x5f, 0xc5, 0xbd, 0x4c, 0xfd, 0xcd, 0xbf, 0x4c, 0xd6, 0xef, 0xba, 0xcc, + 0x9e, 0x4e, 0x9f, 0x6e, 0xb8, 0xef, 0x3e, 0xc4, 0x02, 0xf0, 0x9f, 0x6d, + 0x7e, 0xc4, 0x9f, 0x4d, 0x08, 0xf8, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xbf, + 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xcf, 0xff, 0xbf, + 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x88, 0xef, 0x99, 0x6c, 0x2f, 0xc4, + 0xf2, 0xf3, 0xff, 0xcd, 0x8a, 0xef, 0xbf, 0x5c, 0x00, 0x1c, 0xd5, 0x0a, + 0x00, 0x1c, 0x1f, 0x09, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, + 0x9e, 0xeb, 0xff, 0xcf, 0x00, 0x1c, 0x8d, 0x0c, 0xfc, 0x15, 0xd1, 0xfd, + 0xf3, 0x9b, 0x11, 0xf0, 0xb3, 0xef, 0x9f, 0x7d, 0xff, 0xdc, 0x33, 0x8b, + 0x9f, 0x5d, 0xfc, 0xcd, 0x37, 0x9b, 0x16, 0xf4, 0x96, 0xef, 0xb5, 0xef, + 0xbf, 0x4c, 0x95, 0xef, 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, + 0x5f, 0xc5, 0xbd, 0x4c, 0xfd, 0xcd, 0xbf, 0x4c, 0x23, 0xf8, 0xff, 0xff, + 0xff, 0x5f, 0xff, 0xbf, 0x4d, 0xfe, 0xff, 0xdf, 0xff, 0xbb, 0xff, 0xbf, + 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, 0x18, 0x0f, 0x11, 0x26, + 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x2f, 0xeb, 0x00, 0x1c, 0xbc, 0x0a, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, 0xae, 0x0a, 0x11, 0x26, + 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x2f, 0xeb, 0xff, 0x1f, + 0xc2, 0xff, 0xff, 0x1f, 0x8e, 0xff, 0xf6, 0xcf, 0xff, 0x1f, 0x8d, 0xff, + 0xff, 0xce, 0xf6, 0xcf, 0xff, 0x1f, 0x87, 0xff, 0xf5, 0xcf, 0xff, 0x1f, + 0x94, 0xff, 0xff, 0xce, 0xf5, 0xcf, 0xff, 0x1f, 0x8e, 0xff, 0xec, 0xcf, + 0xff, 0x1f, 0x9b, 0xff, 0xfe, 0xce, 0xec, 0xcf, 0xff, 0x1f, 0x95, 0xff, + 0xf2, 0xcf, 0xff, 0x1f, 0xa2, 0xff, 0xfe, 0xce, 0xf2, 0xcf, 0xff, 0x1f, + 0x9c, 0xff, 0xfe, 0xcf, 0xff, 0x1f, 0xa9, 0xff, 0xfe, 0xce, 0xfe, 0xcf, + 0xff, 0x1f, 0xa3, 0xff, 0xf9, 0xcf, 0xff, 0x1f, 0xb0, 0xff, 0xfd, 0xce, + 0xf9, 0xcf, 0xff, 0x1f, 0xaa, 0xff, 0xf7, 0xcf, 0xff, 0x1f, 0xb7, 0xff, + 0xfc, 0xce, 0xf7, 0xcf, 0xff, 0x1f, 0xb1, 0xff, 0xff, 0xcf, 0xff, 0x1f, + 0xbe, 0xff, 0xff, 0xcf, 0xfc, 0xce, 0xff, 0x1f, 0xb8, 0xff, 0x6f, 0xeb, + 0x8e, 0xef, 0xad, 0xef, 0x9f, 0x4d, 0xad, 0xef, 0xbc, 0x23, 0xff, 0xde, + 0xae, 0xef, 0xbc, 0x23, 0xfe, 0xde, 0xae, 0xef, 0xbc, 0x23, 0xfd, 0xde, + 0xaf, 0xef, 0xbc, 0x23, 0xfc, 0xde, 0xaf, 0xef, 0xbc, 0x23, 0xfb, 0xde, + 0xb0, 0xef, 0xbc, 0x23, 0xfa, 0xde, 0xb0, 0xef, 0xbc, 0x23, 0xf9, 0xde, + 0xb1, 0xef, 0xbc, 0x23, 0xf8, 0xde, 0xff, 0xcd, 0xbc, 0x23, 0xfe, 0xdc, + 0xbc, 0x23, 0x3f, 0xdf, 0xc3, 0x87, 0xff, 0xff, 0xff, 0x1f, 0xff, 0x1f, + 0x43, 0xfe, 0xff, 0xdf, 0xfc, 0xfd, 0xfe, 0xff, 0xf8, 0xf9, 0xfa, 0xfb, + 0xf4, 0xf5, 0xf6, 0xf7, 0xf0, 0xf1, 0xf2, 0xf3, 0xec, 0xed, 0xee, 0xef, + 0xe8, 0xe9, 0xea, 0xeb, 0xe4, 0xe5, 0xe6, 0xe7, 0xe0, 0xe1, 0xe2, 0xe3, + 0x7f, 0x3e, 0xdf, 0x8b, 0xc3, 0x87, 0xff, 0xff, 0x9b, 0xef, 0xfe, 0xcd, + 0x9f, 0x6c, 0xfd, 0x3b, 0xdf, 0xbf, 0xfc, 0x23, 0xbf, 0xdf, 0xc3, 0x87, + 0x43, 0xfe, 0xff, 0xdf, 0x3e, 0xeb, 0x20, 0xc7, 0xe9, 0xf7, 0x9f, 0x1b, + 0xfc, 0xdf, 0xfd, 0xaf, 0xb5, 0xef, 0xff, 0x8b, 0xbf, 0x6d, 0x00, 0xdf, + 0xfd, 0x3b, 0xbf, 0xf7, 0x9c, 0xbc, 0x00, 0xcd, 0x7f, 0x6f, 0x73, 0x8f, + 0xbb, 0x3b, 0xbd, 0xdf, 0xbf, 0x4f, 0xfa, 0xdc, 0xbf, 0x6f, 0xb3, 0x8f, + 0xb7, 0x93, 0xdf, 0x4f, 0x7e, 0xeb, 0xff, 0xff, 0x43, 0xfe, 0xff, 0xdf, + 0x7f, 0xcc, 0x88, 0xbc, 0xbf, 0x6c, 0xbd, 0x1b, 0xe0, 0xcf, 0x5e, 0xc5, + 0xbf, 0x4c, 0xbf, 0x6c, 0x78, 0xc5, 0x77, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, + 0x56, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x59, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, + 0x5a, 0xc5, 0xbf, 0x4c, 0x46, 0xcd, 0xbd, 0xbd, 0xbe, 0x4c, 0xbd, 0x4c, + 0xc3, 0x87, 0xff, 0xff, 0xc3, 0x87, 0xff, 0xff, 0x98, 0xef, 0xb7, 0xef, + 0xbf, 0x4c, 0x97, 0xef, 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, + 0x5f, 0xc5, 0xbd, 0x4c, 0xba, 0xef, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, + 0xff, 0xbb, 0xff, 0xbf, 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, + 0x00, 0x00, 0xf9, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x07, 0xb7, 0xff, 0xff, + 0xfd, 0xfe, 0xff, 0xff, 0xff, 0xb6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x8e, 0xed, 0xff, 0x91, 0xff, 0xff, 0x9b, 0x54, + 0xae, 0xf5, 0xff, 0xff, 0xbc, 0x2f, 0xff, 0xff, 0xdd, 0xff, 0xcf, 0xff, + 0xfc, 0xfe, 0xff, 0xff, 0xf7, 0xb6, 0xff, 0xff, 0xfb, 0xfe, 0xff, 0xff, + 0xb3, 0xb6, 0xff, 0xff, 0xfa, 0xfd, 0xff, 0xff, 0xaf, 0xb6, 0xff, 0xff, + 0xf9, 0xfd, 0xff, 0xff, 0xab, 0xb6, 0xff, 0xff, 0xf8, 0xfe, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xdf, 0xf7, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, + 0xf6, 0xfe, 0xff, 0xff, 0xa7, 0xb6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xdf, 0xfd, 0xce, 0xff, 0xf8, 0xcf, 0xff, 0xff, + 0xf8, 0xce, 0xff, 0xff, 0xdf, 0xff, 0xfc, 0xff, 0x97, 0xeb, 0xff, 0xff, + 0xd1, 0xeb, 0xff, 0xff, 0x69, 0xeb, 0xff, 0xff, 0x31, 0xeb, 0xff, 0xff, + 0xe3, 0xea, 0xff, 0xff, 0xc3, 0xea, 0xff, 0xff, 0x93, 0xeb, 0xff, 0xff, + 0x7f, 0xf5, 0x59, 0xf5, 0x59, 0xf5, 0x59, 0xd7, 0x79, 0xd7, 0x79, 0xd7, + 0x79, 0xd7, 0x79, 0xd7, 0x79, 0xcd, 0x79, 0xc3, 0x59, 0xd7, 0x59, 0xd7, + 0x67, 0xc3, 0x67, 0xd7, 0x72, 0xd7, 0x72, 0xd7, 0x72, 0xc3, 0x72, 0xe1, + 0x72, 0xe1, 0x72, 0xe1, 0x72, 0xe1, 0x72, 0xeb, 0x72, 0xeb, 0x72, 0xeb, + 0x72, 0xeb, 0xff, 0xff, 0x77, 0xec, 0xff, 0xff, 0xb8, 0xfc, 0xff, 0xff, + 0xef, 0xd8, 0xff, 0xff, 0x5b, 0xfe, 0xff, 0xff, 0xef, 0xd8, 0xff, 0xff, + 0x91, 0x5c, 0xfe, 0xff, 0xdf, 0xb1, 0xff, 0xff, 0x48, 0x2e, 0xff, 0xff, + 0x4b, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, + 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, + 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, + 0x27, 0xe2, 0xff, 0xff, 0xc3, 0xe0, 0xff, 0xff, 0x2d, 0xe1, 0xff, 0xff, + 0x4d, 0xe1, 0xff, 0xff, 0x2d, 0xe1, 0xff, 0xff, 0x4d, 0xe1, 0xff, 0xff, + 0x4d, 0xe1, 0xff, 0xff, 0x4d, 0xe1, 0xff, 0xff, 0x63, 0xe1, 0xff, 0xff, + 0xa1, 0xe1, 0xff, 0xff, 0xaf, 0xe0, 0xff, 0xff, 0xbf, 0xe1, 0xff, 0xff, + 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, + 0x27, 0xe2, 0xff, 0xff, 0xdf, 0xe1, 0xff, 0xff, 0xed, 0xe1, 0xff, 0xff, + 0xfb, 0xe1, 0xff, 0xff, 0x17, 0xe2, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, + 0x4f, 0xde, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, + 0x5d, 0xde, 0xff, 0xff, 0x71, 0xde, 0xff, 0xff, 0x79, 0xde, 0xff, 0xff, + 0x8f, 0xde, 0xff, 0xff, 0xa7, 0xde, 0xff, 0xff, 0xa7, 0xde, 0xff, 0xff, + 0xa7, 0xde, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, 0x37, 0xde, 0xff, 0xff, + 0xa7, 0xde, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, 0xb3, 0xde, 0xff, 0xff, + 0xbb, 0xde, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, + 0x09, 0xdf, 0xff, 0xff, 0xc7, 0xde, 0xff, 0xff, 0xad, 0xdd, 0xff, 0xff, + 0xb3, 0xdd, 0xff, 0xff, 0xb3, 0xdd, 0xff, 0xff, 0xb3, 0xdd, 0xff, 0xff, + 0x47, 0xdd, 0xff, 0xff, 0x3d, 0xdd, 0xff, 0xff, 0xcf, 0xdc, 0xff, 0xff, + 0xcf, 0xdc, 0xff, 0xff, 0xd3, 0xdc, 0xff, 0xff, 0x17, 0xdd, 0xff, 0xff, + 0xb3, 0xdd, 0xff, 0xff, 0x09, 0xdd, 0xff, 0xff, 0xe5, 0xdc, 0xff, 0xff, + 0xf1, 0xdd, 0xff, 0xff, 0xcf, 0xdc, 0xff, 0xff, 0xcf, 0xdc, 0xff, 0xff, + 0xd7, 0xdc, 0xff, 0xff, 0xf9, 0xda, 0xff, 0xff, 0xa7, 0xd8, 0xff, 0xff, + 0xf9, 0xda, 0xff, 0xff, 0xbb, 0xd8, 0xff, 0xff, 0xdd, 0xd8, 0xff, 0xff, + 0xf1, 0xd8, 0xff, 0xff, 0x01, 0xd9, 0xff, 0xff, 0x15, 0xd9, 0xff, 0xff, + 0x71, 0xd9, 0xff, 0xff, 0xa3, 0xd9, 0xff, 0xff, 0xa3, 0xd9, 0xff, 0xff, + 0xbd, 0xd9, 0xff, 0xff, 0xf3, 0xd9, 0xff, 0xff, 0x31, 0xda, 0xff, 0xff, + 0xf9, 0xda, 0xff, 0xff, 0x4f, 0xda, 0xff, 0xff, 0x73, 0xda, 0xff, 0xff, + 0xf9, 0xda, 0xff, 0xff, 0xf9, 0xda, 0xff, 0xff, 0xf9, 0xda, 0xff, 0xff, + 0x9d, 0xda, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x23, 0xff, 0xff, 0xdf, + 0xfd, 0xff, 0xff, 0xff, 0x1b, 0xff, 0xff, 0xdf, 0x17, 0xf4, 0xff, 0xff, + 0x77, 0xf4, 0xff, 0xff, 0xfb, 0xf6, 0xff, 0xff, 0x13, 0xf6, 0xff, 0xff, + 0xef, 0xeb, 0xff, 0xff, 0xdf, 0xfe, 0xeb, 0xff, 0xbb, 0x9b, 0xbb, 0x87, + 0xc5, 0x98, 0xc8, 0x98, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x0f, 0x1e, 0x2d, 0x3c, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb1, 0xaa, 0xe9, 0xe6, + 0xdf, 0xb5, 0xcd, 0xea +}; diff --git a/drivers/power/supply/nuvolta/rx1619_trim.c b/drivers/power/supply/nuvolta/rx1619_trim.c new file mode 100644 index 000000000000..eeb652956e3f --- /dev/null +++ b/drivers/power/supply/nuvolta/rx1619_trim.c @@ -0,0 +1,170 @@ +/** + * @file rx1619_1.c + * @author + * @date 2019-04-09 + * + * @brief + * + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +#define rx1619_1_DRIVER_NAME "rx1619_trim" + +static struct rx1619_1_chg *g_chip; + +struct rx1619_1_chg { + char *name; + struct i2c_client *client; + struct device *dev; + struct regmap *regmap; +}; + +/* +static int rx1619_1_read(struct rx1619_1_chg *chip, u8 *val, u16 addr) +{ + unsigned int temp; + int rc; + + rc = regmap_read(chip->regmap, addr, &temp); + if (rc >= 0) { + *val = (u8)temp; + //dev_err(chip->dev, "[rx1619_1] [%s] [0x%04x] = [0x%x] \n", __func__, addr, *val); + } + + return rc; +}*/ + +static int rx1619_1_write(struct rx1619_1_chg *chip, u8 val, u16 addr) +{ + int rc = 0; + + rc = regmap_write(chip->regmap, addr, val); + + return rc; +} + +void rx1619_1_trim(void) +{ + printk("--------------rx1619_1_trim++\n"); + + /************prepare_for_mtp_write************/ + rx1619_1_write(g_chip, 0x69, 0x2017); + rx1619_1_write(g_chip, 0x96, 0x2017); + rx1619_1_write(g_chip, 0x66, 0x2017); + rx1619_1_write(g_chip, 0x99, 0x2017); + rx1619_1_write(g_chip, 0xff, 0x2018); + rx1619_1_write(g_chip, 0xff, 0x2019); + rx1619_1_write(g_chip, 0x5a, 0x0001); + rx1619_1_write(g_chip, 0xa5, 0x0003); + /************prepare_for_mtp_write************/ + + printk("--------------rx1619_1_trim--\n"); +} + +// first step: define regmap_config +static const struct regmap_config rx1619_1_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .max_register = 0xFFFF, +}; + +static int rx1619_1_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct rx1619_1_chg *chip; + + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) { + dev_err(&client->dev, + "i2c allocated device info data failed!\n"); + return -ENOMEM; + } + + chip->regmap = regmap_init_i2c(client, &rx1619_1_regmap_config); + if (!chip->regmap) { + dev_err(&client->dev, "parent regmap is missing\n"); + return -EINVAL; + } + + chip->client = client; + chip->dev = &client->dev; + + device_init_wakeup(&client->dev, true); + i2c_set_clientdata(client, chip); + + //rx1619_1_dump_reg(); + g_chip = chip; + + dev_err(chip->dev, "[rx1619_1] [%s] success! \n", __func__); + + return 0; +} + +static int rx1619_1_remove(struct i2c_client *client) +{ + return 0; +} + +static const struct i2c_device_id rx1619_1_id[] = { + { rx1619_1_DRIVER_NAME, 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, rx1619_1_id); + +static struct of_device_id rx1619_1_match_table[] = { + { + .compatible = "nuvolta,wl_rx1619_trim", + }, + {} +}; + +static struct i2c_driver rx1619_1_driver = { + .driver = { + .name = rx1619_1_DRIVER_NAME, + .of_match_table = rx1619_1_match_table, + }, + .probe = rx1619_1_probe, + .remove = rx1619_1_remove, + .id_table = rx1619_1_id, +}; + +static int __init rx1619_1_init(void) +{ + int ret; + + ret = i2c_add_driver(&rx1619_1_driver); + if (ret) + printk(KERN_ERR "rx1619_1 i2c driver init failed!\n"); + + return ret; +} + +static void __exit rx1619_1_exit(void) +{ + i2c_del_driver(&rx1619_1_driver); +} + +module_init(rx1619_1_init); +module_exit(rx1619_1_exit); + +MODULE_AUTHOR("colin"); +MODULE_DESCRIPTION("NUVOLTA Wireless Power Charger Monitor driver"); +MODULE_LICENSE("GPL/BSD"); diff --git a/drivers/power/supply/renesas/Kconfig b/drivers/power/supply/renesas/Kconfig new file mode 100644 index 000000000000..b28587484baa --- /dev/null +++ b/drivers/power/supply/renesas/Kconfig @@ -0,0 +1,25 @@ +menu "Renesas Electronics Corporation Charger support" + +config IDT_P9220 + tristate "idtp9220 wireless Charger" + depends on I2C + help + Say Y to include support for idtp9220 wireless Charger. + idtp9220 is a wireless battery charger. + The driver supports charger enable/disable. + The driver reports the charger status via the power supply framework. + The driver controls idtp9220 via I2C and + supports device-tree interface. + +config IDT_P9418 + tristate "idtp9418 wireless Charger" + depends on I2C + help + Say Y to include support for idtp9418 wireless Charger. + idtp9418 is a wireless battery charger. + The driver supports charger enable/disable. + The driver reports the charger status via the power supply framework. + The driver controls idtp9418 via I2C and + supports device-tree interface. + +endmenu diff --git a/drivers/power/supply/renesas/Makefile b/drivers/power/supply/renesas/Makefile new file mode 100644 index 000000000000..970140c2cb8b --- /dev/null +++ b/drivers/power/supply/renesas/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_IDT_P9220) += idtp9220.o +obj-$(CONFIG_IDT_P9418) += idtp9418.o diff --git a/drivers/power/supply/renesas/idtp9220.c b/drivers/power/supply/renesas/idtp9220.c new file mode 100644 index 000000000000..d6285209461b --- /dev/null +++ b/drivers/power/supply/renesas/idtp9220.c @@ -0,0 +1,2223 @@ +/** + * Copyright “Copyright (C) 2018 XiaoMi, Inc + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +/*add for sdm845 request*/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* +#ifdef CONFIG_DRM +#include +#endif +*/ + +static struct idtp9220_device_info *g_di; + +struct idtp9220_access_func { + int (*read)(struct idtp9220_device_info *di, u16 reg, u8 *val); + int (*write)(struct idtp9220_device_info *di, u16 reg, u8 val); + int (*read_buf)(struct idtp9220_device_info *di, u16 reg, u8 *buf, + u32 size); + int (*write_buf)(struct idtp9220_device_info *di, u16 reg, u8 *buf, + u32 size); +}; + +struct idtp9220_dt_props { + unsigned int irq_gpio; + unsigned int enable_gpio; + unsigned int wpc_det_gpio; +}; + +struct idtp9220_device_info { + int chip_enable; + char *name; + struct device *dev; + struct idtp9220_access_func bus; + struct regmap *regmap; + struct idtp9220_dt_props dt_props; + int irq; + int wpc_irq; + struct delayed_work irq_work; + struct delayed_work wpc_det_work; + struct pinctrl *idt_pinctrl; + struct pinctrl_state *idt_gpio_active; + struct pinctrl_state *idt_gpio_suspend; + struct power_supply *usb_psy; + struct power_supply *dc_psy; + struct power_supply *batt_psy; + struct power_supply *idtp_psy; + struct power_supply *wireless_psy; + struct mutex read_lock; + struct mutex write_lock; + struct delayed_work chg_monitor_work; + struct delayed_work chg_detect_work; + struct delayed_work bpp_connect_load_work; + struct delayed_work epp_connect_load_work; + struct delayed_work cmd_check_work; + struct delayed_work vout_regulator_work; + struct delayed_work rx_vout_work; + struct delayed_work dc_check_work; + struct delayed_work fast_operate_work; + struct delayed_work mophie_tx_work; + struct delayed_work bpp_e5_tx_work; + struct delayed_work qc2_f1_tx_work; + struct delayed_work qc3_epp_work; + + bool screen_on; + int tx_charger_type; + int status; + int count_5v; + int count_9v; + int count_12v; + int count_15v; + int exchange; + int epp_exchange; + int dcin_present; + int epp; + int vbuck; + int power_off_mode; + int power_max; + u8 header; + u8 cmd; + int is_compatible_hwid; + int last_vin; + int last_vbuck; + int is_car_tx; + int last_icl; + int power_good_flag; + + /*idt9220 charging info*/ + int vout; + int iout; + int f; + int vrect; + int ss; + int is_vin_limit; + int is_epp_qc3; + /* bpp e5_tx info*/ + int last_bpp_icl; + int last_bpp_vout; + /* qc2+f1_tx info*/ + int is_f1_tx; + int bpp_vout_rise; + int last_qc2_vout; + int last_qc2_icl; + /* qc3_epp+f1_tx info*/ + int last_qc3_vout; + int last_qc3_icl; +}; + +void idtp922x_request_adapter(struct idtp9220_device_info *di); +static void idtp9220_set_charging_param(struct idtp9220_device_info *di); + +/*static int idt_signal_strength = 0; +module_param_named(ss, idt_signal_strength, int, 0600); +*/ + +static int idt_signal_range = 2; +module_param_named(signal_range, idt_signal_range, int, 0644); + +static int idtp9220_get_property_names(struct idtp9220_device_info *di) +{ + di->batt_psy = power_supply_get_by_name("battery"); + if (!di->batt_psy) { + dev_err(di->dev, "[idt] no batt_psy,return\n"); + return -EINVAL; + } + di->dc_psy = power_supply_get_by_name("dc"); + if (!di->dc_psy) { + dev_err(di->dev, "[idt] no dc_psy,return\n"); + return -EINVAL; + } + di->usb_psy = power_supply_get_by_name("usb"); + if (!di->usb_psy) { + dev_err(di->dev, "[idt] no usb_psy,return\n"); + return -EINVAL; + } + di->wireless_psy = power_supply_get_by_name("wireless"); + if (!di->wireless_psy) { + dev_err(di->dev, "[idt] no wireless_psy,return\n"); + return -EINVAL; + } + return 0; +} + +int idtp9220_read(struct idtp9220_device_info *di, u16 reg, u8 *val) +{ + unsigned int temp; + int rc; + + mutex_lock(&di->read_lock); + rc = regmap_read(di->regmap, reg, &temp); + if (rc >= 0) + *val = (u8)temp; + + mutex_unlock(&di->read_lock); + return rc; +} + +int idtp9220_write(struct idtp9220_device_info *di, u16 reg, u8 val) +{ + int rc = 0; + + mutex_lock(&di->write_lock); + rc = regmap_write(di->regmap, reg, val); + if (rc < 0) + dev_err(di->dev, "[idt] idtp9220 write error: %d\n", rc); + + mutex_unlock(&di->write_lock); + return rc; +} + +int idtp9220_read_buffer(struct idtp9220_device_info *di, u16 reg, u8 *buf, + u32 size) +{ + int rc = 0; + + while (size--) { + rc = di->bus.read(di, reg++, buf++); + if (rc < 0) { + dev_err(di->dev, "[idt] write error: %d\n", rc); + return rc; + } + } + + return rc; +} + +int idtp9220_write_buffer(struct idtp9220_device_info *di, u16 reg, u8 *buf, + u32 size) +{ + int rc = 0; + + while (size--) { + rc = di->bus.write(di, reg++, *buf++); + if (rc < 0) { + dev_err(di->dev, "[idt] write error: %d\n", rc); + return rc; + } + } + + return rc; +} + +u32 ExtractPacketSize(u8 hdr) +{ + if (hdr < 0x20) + return 1; + if (hdr < 0x80) + return (2 + ((hdr - 0x20) >> 4)); + if (hdr < 0xe0) + return (8 + ((hdr - 0x80) >> 3)); + return (20 + ((hdr - 0xe0) >> 2)); +} + +void idtp922x_clrInt(struct idtp9220_device_info *di, u8 *buf, u32 size) +{ + di->bus.write_buf(di, REG_SSINTCLR, buf, size); + di->bus.write(di, REG_SSCMND, CLRINT); +} + +void idtp922x_sendPkt(struct idtp9220_device_info *di, ProPkt_Type *pkt) +{ + u32 size = ExtractPacketSize(pkt->header) + 1; + di->bus.write_buf(di, REG_PROPPKT, (u8 *)pkt, + size); // write data into proprietary packet buffer + di->bus.write(di, REG_SSCMND, SENDPROPP); // send proprietary packet + + dev_info(di->dev, "pkt header: 0x%x and cmd: 0x%x\n", pkt->header, + pkt->cmd); + di->header = pkt->header; + di->cmd = pkt->cmd; +} + +void idtp922x_receivePkt(struct idtp9220_device_info *di, u8 *buf) +{ + u8 header; + int rc; + u32 size; + + di->bus.read(di, REG_BCHEADER, &header); + size = ExtractPacketSize(header) + 1; + rc = di->bus.read_buf(di, REG_BCDATA, buf, size); + if (rc < 0) + dev_err(di->dev, "[idt] read Tx data error: %d\n", rc); +} + +void idtp922x_set_adap_vol(struct idtp9220_device_info *di, u16 mv) +{ + dev_info(di->dev, "set adapter vol to %d\n", mv); + di->bus.write(di, REG_FC_VOLTAGE_L, mv & 0xff); + di->bus.write(di, REG_FC_VOLTAGE_H, (mv >> 8) & 0xff); + di->bus.write(di, REG_SSCMND, VSWITCH); +} + +void idtp922x_set_pmi_icl(struct idtp9220_device_info *di, int mA) +{ + union power_supply_propval val = { + 0, + }; + int rc; + + rc = idtp9220_get_property_names(di); + val.intval = mA; + power_supply_set_property(di->dc_psy, POWER_SUPPLY_PROP_CURRENT_MAX, + &val); +} + +/* Adapter Type */ +/* Adapter_list = {0x00:'ADAPTER_UNKNOWN', */ +/* 0x01:'SDP 500mA', */ +/* 0x02:'CDP 1.1A', */ +/* 0x03:'DCP 1.5A', */ +/* 0x05:'QC2.0', */ +/* 0x06:'QC3.0', */ +/* 0x07:'PD',} */ +void idtp922x_request_adapter(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY18; + pkt.cmd = BC_ADAPTER_TYPE; + + idtp922x_sendPkt(di, &pkt); +} + +void idtp922x_request_uuid(struct idtp9220_device_info *di, int is_epp) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY18; + if (is_epp) + pkt.cmd = BC_TX_HWID; + else + pkt.cmd = BC_TX_COMPATIBLE_HWID; + idtp922x_sendPkt(di, &pkt); +} + +void idtp922x_get_tx_vin(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY18; + pkt.cmd = BC_READ_Vin; + + idtp922x_sendPkt(di, &pkt); +} + +void idtp922x_retry_cmd(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + pkt.header = di->header; + pkt.cmd = di->cmd; + + idtp922x_sendPkt(di, &pkt); +} + +static void idtp9220_int_enable(struct idtp9220_device_info *di) +{ + u8 int_val; + di->bus.read(di, REG_INTR_EN_L, &int_val); + di->bus.write(di, REG_INTR_EN_L, (int_val | OVER_EVENT_OCCUR)); + dev_info(di->dev, "[idtp9220]: int enabled status 0x%x\n", + (int_val | OVER_EVENT_OCCUR)); +} + +static int idtp9220_get_vout_regulator(struct idtp9220_device_info *di) +{ + u8 vout_l, vout_h; + u16 vout; + + if (!di) + return 0; + + di->bus.read(di, REG_REGULATOR_L, &vout_l); + di->bus.read(di, REG_REGULATOR_H, &vout_h); + vout = vout_l | ((vout_h & 0xff) << 8); + dev_info(di->dev, "vout regulator get vol: %d\n", vout); + + return vout; +} + +void idtp9220_set_toggle_mode(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY18; + pkt.cmd = BC_TX_TOGGLE; + idtp922x_sendPkt(di, &pkt); +} + +void idtp9220_retry_id_auth(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY38; + pkt.cmd = BC_RX_ID_AUTH; + + pkt.data[0] = 0x02; + pkt.data[1] = 0xbb; + + idtp922x_sendPkt(di, &pkt); +} + +static int idtp9220_set_vout_regulator(struct idtp9220_device_info *di, int mv) +{ + u8 vout_l, vout_h; + u16 vout; + + if (!di) + return 0; + vout_l = mv & 0xff; + vout_h = mv >> 8; + + dev_info(di->dev, "vout regulator vout_l: 0x%x and vout_h: 0x%x\n", + vout_l, vout_h); + di->bus.write(di, REG_REGULATOR_L, vout_l); + di->bus.write(di, REG_REGULATOR_H, vout_h); + + vout = vout_l | ((vout_h & 0xff) << 8); + dev_info(di->dev, "vout regulator set vol: %d\n", vout); + + return vout; +} + +static int idtp9220_get_vbuck(struct idtp9220_device_info *di) +{ + u8 vbuck_l, vbuck_h; + u16 vbuck_ret; + + if (!di) + return 0; + + di->bus.read(di, 0x08, &vbuck_l); + di->bus.read(di, 0x09, &vbuck_h); + vbuck_ret = vbuck_l | (vbuck_h << 8); + + return vbuck_ret; +} + +static int idtp9220_get_vout(struct idtp9220_device_info *di) +{ + u8 vout_l, vout_h; + + if (!di) + return 0; + + di->bus.read(di, REG_ADC_VOUT_L, &vout_l); + di->bus.read(di, REG_ADC_VOUT_H, &vout_h); + di->vout = vout_l | ((vout_h & 0xf) << 8); + di->vout = di->vout * 10 * 21 * 1000 / 40950 + + ADJUST_METE_MV; //vout = val/4095*10*2.1 + + return di->vout; +} + +static void idtp9220_set_vout(struct idtp9220_device_info *di, int mv) +{ + u8 val; + if (!di) + return; + val = (mv - 3500) / 100; + di->bus.write(di, REG_VOUT_SET, val); + dev_info(di->dev, "[idtp9220]: set vout voltage is 0x%x\n", val); +} + +static void idtp9220_set_reset(struct idtp9220_device_info *di) +{ + if (!di) + return; + di->bus.write(di, REG_RX_RESET, 0x01); + dev_info(di->dev, "[idtp9220]: set RX reset\n"); +} +extern char *saved_command_line; + +static int get_cmdline(struct idtp9220_device_info *di) +{ + if (strnstr(saved_command_line, + "androidboot.mode=", strlen(saved_command_line))) { + di->power_off_mode = 1; + dev_info(di->dev, "[idtp9220]: enter power off charging app\n"); + } else { + di->power_off_mode = 0; + dev_info(di->dev, "[idtp9220]: enter normal boot mode\n"); + } + return 1; +} + +static int idtp9220_get_iout(struct idtp9220_device_info *di) +{ + u8 cout_l, cout_h; + + if (!di) + return 0; + + di->bus.read(di, REG_RX_LOUT_L, &cout_l); + di->bus.read(di, REG_RX_LOUT_H, &cout_h); + di->iout = cout_l | (cout_h << 8); + + return di->iout; +} + +static int idtp9220_get_power_profile(struct idtp9220_device_info *di) +{ + u8 mode; + int ret; + + di->bus.read(di, REG_WPC_MODE, &mode); + ret = mode & BIT(3); + dev_info(di->dev, "tx is epp ? ret is 0x%x\n", mode); + + return ret; +} + +static int idtp9220_get_freq(struct idtp9220_device_info *di) +{ + u8 data_list[2]; + + di->bus.read_buf(di, REG_FREQ_ADDR, data_list, 2); + di->f = 64 * HSCLK / (data_list[0] | (data_list[1] << 8)) / 10; + + return di->f; +} + +static int idtp9220_get_vrect(struct idtp9220_device_info *di) +{ + u8 data_list[2]; + + di->bus.read_buf(di, REG_ADC_VRECT, data_list, 2); + di->vrect = data_list[0] | ((data_list[1] & 0xf) << 8); + di->vrect = + di->vrect * 10 * 21 * 1000 / 40950; //vrect = val/4095*10*2.1 + + return di->vrect; +} + +static int idtp9220_get_power_max(struct idtp9220_device_info *di) +{ + int power_max; + u8 val; + + di->bus.read(di, REG_POWER_MAX, &val); + power_max = (val / 2) * 1000; + dev_info(di->dev, "rx power max is %dmW\n", power_max); + + return power_max; +} + +static void idtp9220_send_device_auth(struct idtp9220_device_info *di) +{ + di->bus.write(di, REG_SSCMND, SEND_DEVICE_AUTH); +} + +static ssize_t chip_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 chip_id_l, chip_id_h, chip_rev, cust_id, status, vset; + u8 fw_otp_ver[4], fw_app_ver[4]; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + di->bus.read(di, REG_STATUS_L, &status); + di->bus.read(di, REG_VOUT_SET, &vset); + + di->bus.read(di, REG_CHIP_ID_L, &chip_id_l); + di->bus.read(di, REG_CHIP_ID_H, &chip_id_h); + di->bus.read(di, REG_CHIP_REV, &chip_rev); + chip_rev = chip_rev >> 4; + di->bus.read(di, REG_CTM_ID, &cust_id); + di->bus.read_buf(di, REG_OTPFWVER_ADDR, fw_otp_ver, 4); + di->bus.read_buf(di, REG_EPRFWVER_ADDR, fw_app_ver, 4); + + return sprintf( + buf, + "chip_id_l:%02x\nchip_id_h:%02x\nchip_rev:%02x\ncust_id:%02x status:%02x vset:%02x\n otp_ver:%x.%x.%x.%x\n app_ver:%x.%x.%x.%x\n", + chip_id_l, chip_id_h, chip_rev, cust_id, status, vset, + fw_otp_ver[0], fw_otp_ver[1], fw_otp_ver[2], fw_otp_ver[3], + fw_app_ver[0], fw_app_ver[1], fw_app_ver[2], fw_app_ver[3]); +} + +/* voltage limit attrs */ +static ssize_t chip_vout_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + int vout; + + vout = idtp9220_get_vout(di); + return sprintf(buf, "Vout ADC Value: %dMV\n", vout); +} + +static ssize_t chip_vout_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + int index; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + index = (int)simple_strtoul(buf, NULL, 16); + /* + if ((index < VOUT_VAL_3500_MV) || (index > VOUT_VAL_5000_MV)) { + dev_err(di->dev, "Store Val %s is invalid!\n", buf); + return count; + } +*/ + + idtp9220_set_vout(di, index); + + return count; +} + +static ssize_t vout_regulator_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + int vout; + + vout = idtp9220_get_vout_regulator(di); + + return sprintf(buf, "Vout ADC Value: %dMV\n", vout); +} + +#define VOUT_MIN_4900_MV 4900 +#define VOUT_MAX_10000_MV 10000 +static ssize_t vout_regulator_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int vout; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + vout = (int)simple_strtoul(buf, NULL, 10); + if ((vout <= VOUT_MIN_4900_MV) || (vout > VOUT_MAX_10000_MV)) { + dev_err(di->dev, "Store Val %s : %ld is invalid!\n", buf, vout); + return count; + } + idtp9220_set_vout_regulator(di, vout); + + return count; +} + +/* current attrs */ +static ssize_t chip_iout_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + int cout; + + cout = idtp9220_get_iout(di); + + return sprintf(buf, "Output Current: %dMA\n", cout); +} + +static ssize_t chip_iout_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + int index; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + index = (int)simple_strtoul(buf, NULL, 10); + + if ((index < CURR_VAL_100_MA) || (index > CURR_VAL_1300_MA)) { + dev_err(di->dev, "Store Val %s is invalid", buf); + return count; + } + + di->bus.write(di, REG_ILIM_SET, index); + + return count; +} + +static ssize_t chip_freq_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + int f; + + f = idtp9220_get_freq(di); + + return sprintf(buf, "Output Current: %dkHz\n", f); +} + +static void idtp9220_charging_info(struct idtp9220_device_info *di) +{ + int vbuck_ret = 0; + if (!di) + return; + + idtp9220_get_vout(di); + idtp9220_get_iout(di); + idtp9220_get_freq(di); + idtp9220_get_vrect(di); + vbuck_ret = idtp9220_get_vbuck(di); + + dev_info( + di->dev, + "%s:Vout:%dmV,Iout:%dmA,Freq:%dKHz,Vrect:%dmV,SS:%d, Vbuck:%d\n", + __func__, di->vout, di->iout, di->f, di->vrect, di->ss, + vbuck_ret); +} + +/* chip enable attrs */ +static ssize_t chip_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + if (gpio_is_valid(di->dt_props.enable_gpio)) + ret = gpio_get_value(di->dt_props.enable_gpio); + else { + dev_err(di->dev, "%s: sleep gpio not provided\n", __func__); + ret = -1; + } + + dev_info(di->dev, "chip enable gpio: %d\n", ret); + + return sprintf(buf, "Chip enable: %d\n", !ret); +} + +static int idtp9220_set_present(struct idtp9220_device_info *di, int enable) +{ + int ret = 0; + + dev_info(di->dev, "[idtp] dc plug %s\n", enable ? "in" : "out"); + if (enable) { + di->dcin_present = true; + di->ss = 1; + } else { + schedule_delayed_work(&di->fast_operate_work, + msecs_to_jiffies(200)); + di->status = NORMAL_MODE; + di->count_9v = 0; + di->count_5v = 0; + di->count_12v = 0; + di->count_15v = 0; + di->exchange = 0; + di->epp_exchange = 0; + di->dcin_present = false; + idt_signal_range = 2; + di->ss = 2; + di->vbuck = 0; + di->epp = 0; + di->last_vin = 0; + di->last_icl = 0; + di->last_vbuck = 0; + di->is_car_tx = 0; + di->power_off_mode = 0; + di->is_epp_qc3 = 0; + di->is_vin_limit = 0; + di->bpp_vout_rise = 0; + di->is_f1_tx = 0; + di->last_bpp_vout = 0; + di->last_bpp_icl = 0; + di->last_qc2_vout = 0; + di->last_qc2_icl = 0; + di->last_qc3_vout = 0; + di->last_qc3_icl = 0; + di->tx_charger_type = ADAPTER_NONE; + cancel_delayed_work(&di->chg_monitor_work); + cancel_delayed_work(&di->cmd_check_work); + } + + return ret; +} + +static int idtp9220_set_enable_mode(struct idtp9220_device_info *di, int enable) +{ + int ret = 0; + + if (gpio_is_valid(di->dt_props.enable_gpio)) { + ret = gpio_request(di->dt_props.enable_gpio, "idt-enable-gpio"); + if (ret) { + dev_err(di->dev, + "%s: unable to request idt enable gpio [%d]\n", + __func__, di->dt_props.enable_gpio); + } + + ret = gpio_direction_output(di->dt_props.enable_gpio, !enable); + if (ret) { + dev_err(di->dev, + "%s: cannot set direction for idt enable gpio [%d]\n", + __func__, di->dt_props.enable_gpio); + } + gpio_free(di->dt_props.enable_gpio); + } + + return ret; +} + +static ssize_t chip_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + int ret, enable; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + ret = (int)simple_strtoul(buf, NULL, 10); + enable = !!ret; + + idtp9220_set_enable_mode(di, enable); + + return count; +} + +static DEVICE_ATTR(chip_enable, S_IWUSR | S_IRUGO, chip_enable_show, + chip_enable_store); +static DEVICE_ATTR(chip_version, S_IRUGO, chip_version_show, NULL); +static DEVICE_ATTR(chip_vout, S_IWUSR | S_IRUGO, chip_vout_show, + chip_vout_store); +static DEVICE_ATTR(chip_iout, S_IWUSR | S_IRUGO, chip_iout_show, + chip_iout_store); +static DEVICE_ATTR(chip_freq, S_IRUGO, chip_freq_show, NULL); +static DEVICE_ATTR(vout_regulator, S_IWUSR | S_IRUGO, vout_regulator_show, + vout_regulator_store); + +static struct attribute *sysfs_attrs[] = { + &dev_attr_chip_version.attr, + &dev_attr_chip_vout.attr, + &dev_attr_chip_iout.attr, + &dev_attr_chip_freq.attr, + &dev_attr_chip_enable.attr, + &dev_attr_vout_regulator.attr, + NULL, +}; + +static const struct attribute_group sysfs_group_attrs = { + .attrs = sysfs_attrs, +}; + +static int idtp9220_parse_dt(struct idtp9220_device_info *di) +{ + struct device_node *node = di->dev->of_node; + + if (!node) { + dev_err(di->dev, "device tree node missing\n"); + return -EINVAL; + } + + di->dt_props.irq_gpio = of_get_named_gpio(node, "idt,irq", 0); + if ((!gpio_is_valid(di->dt_props.irq_gpio))) + return -EINVAL; + + di->dt_props.enable_gpio = of_get_named_gpio(node, "idt,enable", 0); + if ((!gpio_is_valid(di->dt_props.enable_gpio))) + return -EINVAL; + + di->dt_props.wpc_det_gpio = of_get_named_gpio(node, "idt,wpc-det", 0); + if ((!gpio_is_valid(di->dt_props.irq_gpio))) + return -EINVAL; + + return 0; +} + +static int idtp9220_gpio_init(struct idtp9220_device_info *di) +{ + int ret = 0; + int irqn = 0; + int wpc_irq = 0; + + di->idt_pinctrl = devm_pinctrl_get(di->dev); + if (IS_ERR_OR_NULL(di->idt_pinctrl)) { + dev_err(di->dev, "No pinctrl config specified\n"); + ret = PTR_ERR(di->dev); + return ret; + } + di->idt_gpio_active = + pinctrl_lookup_state(di->idt_pinctrl, "idt_active"); + if (IS_ERR_OR_NULL(di->idt_gpio_active)) { + dev_err(di->dev, "No active config specified\n"); + ret = PTR_ERR(di->idt_gpio_active); + return ret; + } + di->idt_gpio_suspend = + pinctrl_lookup_state(di->idt_pinctrl, "idt_suspend"); + if (IS_ERR_OR_NULL(di->idt_gpio_suspend)) { + dev_err(di->dev, "No suspend config specified\n"); + ret = PTR_ERR(di->idt_gpio_suspend); + return ret; + } + + ret = pinctrl_select_state(di->idt_pinctrl, di->idt_gpio_active); + if (ret < 0) { + dev_err(di->dev, "fail to select pinctrl active rc=%d\n", ret); + return ret; + } + + if (gpio_is_valid(di->dt_props.irq_gpio)) { + irqn = gpio_to_irq(di->dt_props.irq_gpio); + if (irqn < 0) { + ret = irqn; + goto err_irq_gpio; + } + di->irq = irqn; + } else { + dev_err(di->dev, "%s: irq gpio not provided\n", __func__); + goto err_irq_gpio; + } + + if (gpio_is_valid(di->dt_props.wpc_det_gpio)) { + wpc_irq = gpio_to_irq(di->dt_props.wpc_det_gpio); + if (wpc_irq < 0) { + ret = wpc_irq; + goto err_wpc_irq; + } + di->wpc_irq = wpc_irq; + } else { + dev_err(di->dev, "%s: wpc irq gpio not provided\n", __func__); + goto err_wpc_irq; + } + +err_wpc_irq: + gpio_free(di->dt_props.wpc_det_gpio); +err_irq_gpio: + gpio_free(di->dt_props.irq_gpio); + return ret; +} + +static bool need_irq_cleared(struct idtp9220_device_info *di) +{ + u8 int_buf[2]; + u16 int_val; + int rc = -1; + + rc = di->bus.read_buf(di, REG_INTR_L, int_buf, 2); + if (rc < 0) { + dev_err(di->dev, "%s: read int state error\n", __func__); + return true; + } + int_val = int_buf[0] | (int_buf[1] << 8); + if (int_val != 0) { + dev_info(di->dev, "irq not clear right: 0x%04x\n", int_val); + return true; + } + + if (gpio_is_valid(di->dt_props.irq_gpio)) + rc = gpio_get_value(di->dt_props.irq_gpio); + else { + dev_err(di->dev, "%s: irq gpio not provided\n", __func__); + rc = -1; + } + if (!rc) { + dev_info(di->dev, "irq low, need clear int: %d\n", rc); + return true; + } + return false; +} + +#define VBUCK_QC_VOL 7000 +#define VBUCK_FULL_VOL 7000 +#define VBUCK_DEFAULT_VOL 5500 +#define ADAPTER_BPP_QC_VOL 9000 +#define ADAPTER_BPP_LIMIT_VOL 6500 +#define BPP_VOL_THRESHOLD 8000 +#define ADAPTER_BPP_VOL 5000 +#define ADAPTER_EPP_MI_VOL 15000 +#define EPP_VOL_THRESHOLD 12000 +#define EPP_VOL_LIM_THRESHOLD 13000 +#define BPP_VOL_LIM_THRESHOLD 10000 +#define CHARGING_PERIOD_S 10 +#define TAPER_CURR_Limit 950000 + +static void idtp9220_monitor_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, chg_monitor_work.work); + + idtp9220_charging_info(di); + + idtp9220_set_charging_param(di); + + schedule_delayed_work(&di->chg_monitor_work, CHARGING_PERIOD_S * HZ); +} + +static void idtp9220_rx_vout_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, rx_vout_work.work); + + idtp9220_set_charging_param(di); +} + +static void idtp9220_dc_check_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, dc_check_work.work); + + dev_info(di->dev, "[idt] dc present: %d\n", di->dcin_present); + if (di->dcin_present) { + di->ss = 1; + dev_info(di->dev, "dcin present, quit dc check work\n"); + return; + } else { + di->ss = 0; + dev_info(di->dev, "dcin no present, continue dc check work\n"); + schedule_delayed_work(&di->dc_check_work, + msecs_to_jiffies(2500)); + } + power_supply_changed(di->idtp_psy); +} + +static void idtp9220_fast_operate_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, fast_operate_work.work); + int ret = -1; + int usb_present, typec_mode; + union power_supply_propval val = { + 0, + }; + + ret = idtp9220_get_property_names(di); + if (ret < 0) + return; + + power_supply_get_property(di->usb_psy, POWER_SUPPLY_PROP_PRESENT, &val); + usb_present = val.intval; + + power_supply_get_property(di->usb_psy, POWER_SUPPLY_PROP_TYPEC_MODE, + &val); + typec_mode = val.intval; + + dev_info(di->dev, "usb present:%d typec mode:%d\n", usb_present, + typec_mode); + + if (gpio_is_valid(di->dt_props.wpc_det_gpio)) { + ret = gpio_get_value(di->dt_props.wpc_det_gpio); + /* power good irq will not trigger after insert typec audio/charger + * connector while wireless charging. WR for this situation. + */ + if ((!usb_present && ret) || + (usb_present && ret && + (typec_mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER || + typec_mode == POWER_SUPPLY_TYPEC_NONE))) { + dev_info( + di->dev, + "dc out but power_good high, reset by sleep\n"); + idtp9220_set_enable_mode(di, false); + msleep(10); + idtp9220_set_enable_mode(di, true); + } + } +} + +static void idtp9220_chg_detect_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, chg_detect_work.work); + + union power_supply_propval val = { + 0, + }; + union power_supply_propval wk_val = { + 0, + }; + int rc; + + dev_info(di->dev, "[idt] enter %s\n", __func__); + + rc = idtp9220_get_property_names(di); + if (rc < 0) + return; + + /*set idtp9220 into sleep mode when usbin*/ + + power_supply_get_property(di->usb_psy, POWER_SUPPLY_PROP_ONLINE, &val); + if (val.intval) { + dev_info(di->dev, "[idt] usb_online:%d set chip disable\n", + val.intval); + idtp9220_set_enable_mode(di, false); + return; + } + + if (di->dc_psy) { + power_supply_get_property(di->dc_psy, POWER_SUPPLY_PROP_ONLINE, + &val); + dev_info(di->dev, "[idt] dc_online %d\n", val.intval); + if (val.intval && di->wireless_psy) { + idtp9220_int_enable(di); + wk_val.intval = 1; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, &wk_val); + di->epp = idtp9220_get_power_profile(di); + + get_cmdline(di); + if (!di->power_off_mode) + idtp9220_set_reset(di); + else + schedule_delayed_work(&di->irq_work, + msecs_to_jiffies(30)); + } + } +} + +#define DC_LOAD_CURRENT 2000000 +#define DC_FUL_CURRENT 50000 +#define SCREEN_OFF_FUL_CURRENT 220000 +#define DC_LOW_CURRENT 350000 +#define DC_SDP_CURRENT 500000 +#define DC_DCP_CURRENT 500000 +#define DC_PD_CURRENT 800000 +#define DC_MI_CURRENT 2100000 +#define DC_MI_STEP1_CURRENT 1200000 +#define DC_QC3_CURRENT 1400000 +#define DC_QC2_CURRENT 1100000 +#define DC_BPP_CURRENT 850000 +#define DC_BPP_AUTH_FAIL_CURRENT 800000 +#define ICL_EXCHANGE_CURRENT 600000 +#define ICL_EXCHANGE_COUNT 5 /*5 = 1min*/ +#define EXCHANGE_9V 0x0 +#define EXCHANGE_5V 0x1 +#define EXCHANGE_15V 0x0 +#define EXCHANGE_12V 0x1 +#define LIMIT_EPP_IOUT 500 +#define LIMIT_BPP_IOUT 400 +#define LIMIT_SOC 80 +#define TAPER_SOC 95 +#define FULL_SOC 100 +#define TAPER_VOL 4350000 +#define TAPER_CUR -500000 + +static void idtp9220_bpp_connect_load_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, bpp_connect_load_work.work); + + idtp922x_set_pmi_icl(di, DC_DCP_CURRENT); +} + +static void idtp9220_epp_connect_load_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, epp_connect_load_work.work); + int dc_load_curr = 0; + + if (di->power_max <= 10000) + dc_load_curr = (di->power_max - 1000) / 5 * 1000; + else + dc_load_curr = DC_LOAD_CURRENT; + + idtp922x_set_pmi_icl(di, dc_load_curr); +} + +static void idtp9220_cmd_check_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, cmd_check_work.work); + + dev_info(di->dev, "[idt] %s: \n", __func__); + idtp922x_get_tx_vin(di); + if (di->power_off_mode) { + schedule_delayed_work(&di->vout_regulator_work, + msecs_to_jiffies(10)); + } +} + +static void idtp9220_mophie_tx_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, mophie_tx_work.work); + int ret = 0; + u8 buf[2] = { 0 }; + u16 int_val = 0; + + ret = idtp9220_get_power_profile(di); + if (ret) { + ret = di->bus.read_buf(di, REG_TX_TYPE, buf, 2); + if (ret < 0) + dev_err(di->dev, "read tx type error: %d\n", ret); + else { + int_val = buf[0] | (buf[1] << 8); + dev_info(di->dev, "tx type: 0x%04x\n", int_val); + if (int_val == 0x0059) { + dev_info(di->dev, "write vrect target\n"); + di->bus.write(di, 0x0090, 0x0); + di->bus.write(di, 0x0091, 0x8); + di->bus.write(di, 0x003E, 0x41); + } + } + } +} + +static void idtp9220_bpp_e5_tx_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, bpp_e5_tx_work.work); + int icl_curr = 0, vbuck = 0, adapter_vol = 0; + int soc = 0, batt_sts = 0, health = 0; + int icl_setted = 0; + union power_supply_propval val = { + 0, + }; + union power_supply_propval wk_val = { + 0, + }; + + if (di->batt_psy) { + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_STATUS, &val); + batt_sts = val.intval; + + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &val); + soc = val.intval; + + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_HEALTH, &val); + health = val.intval; + } + + if (di->tx_charger_type == ADAPTER_QC3) { + adapter_vol = ADAPTER_BPP_QC_VOL; + vbuck = VBUCK_QC_VOL; + icl_curr = DC_QC3_CURRENT; + } else if (di->tx_charger_type == ADAPTER_QC2) { + adapter_vol = ADAPTER_BPP_QC_VOL; + vbuck = VBUCK_QC_VOL; + icl_curr = DC_QC2_CURRENT; + } + + if (di->iout < LIMIT_BPP_IOUT && di->exchange == EXCHANGE_9V) { + di->count_5v++; + di->count_9v = 0; + } else if (di->iout > LIMIT_BPP_IOUT && di->exchange == EXCHANGE_5V) { + di->count_9v++; + di->count_5v = 0; + } else { + di->count_5v = 0; + di->count_9v = 0; + } + /* + * 9V-->5V check 6 times + * 5V-->9v check 3 times + */ + if (di->count_5v > ICL_EXCHANGE_COUNT || + (di->exchange == EXCHANGE_5V && + di->count_9v <= ICL_EXCHANGE_COUNT - 3)) { + dev_info(di->dev, "iout less than 500mA ,set vout to 6.5v\n"); + adapter_vol = ADAPTER_BPP_LIMIT_VOL; + vbuck = VBUCK_DEFAULT_VOL; + icl_curr = DC_BPP_CURRENT; + di->exchange = EXCHANGE_5V; + } else if (di->count_9v > (ICL_EXCHANGE_COUNT - 3)) + di->exchange = EXCHANGE_9V; + + if (soc > 90) + icl_curr = DC_BPP_CURRENT; + + switch (di->status) { + case NORMAL_MODE: + if (soc >= TAPER_SOC) { + di->status = TAPER_MODE; + adapter_vol = ADAPTER_BPP_LIMIT_VOL; + vbuck = VBUCK_DEFAULT_VOL; + icl_curr = min(DC_SDP_CURRENT, icl_curr); + } + break; + case TAPER_MODE: + dev_info(di->dev, "[bpp] taper mode set vout to 6.5v\n"); + adapter_vol = ADAPTER_BPP_LIMIT_VOL; + vbuck = VBUCK_DEFAULT_VOL; + icl_curr = min(DC_SDP_CURRENT, icl_curr); + + if (soc == FULL_SOC && batt_sts == POWER_SUPPLY_STATUS_FULL) + di->status = FULL_MODE; + else if (soc < TAPER_SOC - 1) + di->status = NORMAL_MODE; + break; + case FULL_MODE: + dev_info(di->dev, "[bpp] charge full set vout to 6.5v\n"); + adapter_vol = ADAPTER_BPP_LIMIT_VOL; + vbuck = VBUCK_DEFAULT_VOL; + icl_curr = SCREEN_OFF_FUL_CURRENT; + + if (batt_sts == POWER_SUPPLY_STATUS_CHARGING) { + di->status = RECHG_MODE; + icl_curr = DC_LOW_CURRENT; + } + break; + case RECHG_MODE: + dev_info(di->dev, "[bpp] recharge mode set icl to 300mA\n"); + adapter_vol = ADAPTER_BPP_LIMIT_VOL; + vbuck = VBUCK_DEFAULT_VOL; + icl_curr = DC_LOW_CURRENT; + + if (soc < TAPER_SOC - 1) + di->status = NORMAL_MODE; + else if (batt_sts == POWER_SUPPLY_STATUS_FULL) + di->status = FULL_MODE; + + if (di->wireless_psy) { + wk_val.intval = 1; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, &wk_val); + } + break; + default: + break; + } + + switch (health) { + case POWER_SUPPLY_HEALTH_GOOD: + break; + case POWER_SUPPLY_HEALTH_COOL: + break; + case POWER_SUPPLY_HEALTH_WARM: + adapter_vol = ADAPTER_BPP_LIMIT_VOL; + vbuck = VBUCK_DEFAULT_VOL; + icl_curr = min(DC_SDP_CURRENT, icl_curr); + break; + case POWER_SUPPLY_HEALTH_OVERVOLTAGE: + adapter_vol = ADAPTER_BPP_LIMIT_VOL; + vbuck = VBUCK_DEFAULT_VOL; + icl_curr = min(SCREEN_OFF_FUL_CURRENT, icl_curr); + break; + case POWER_SUPPLY_HEALTH_COLD: + case POWER_SUPPLY_HEALTH_HOT: + adapter_vol = ADAPTER_BPP_LIMIT_VOL; + vbuck = VBUCK_DEFAULT_VOL; + icl_curr = SCREEN_OFF_FUL_CURRENT; + break; + default: + break; + } + + if (adapter_vol != di->last_bpp_vout) { + dev_info(di->dev, "bpp_10w, set new vout: %d, last_vout: %d\n", + adapter_vol, di->last_bpp_vout); + if (adapter_vol > BPP_VOL_THRESHOLD) { + idtp922x_set_adap_vol(di, adapter_vol); + msleep(200); + idtp9220_set_vout_regulator(di, vbuck); + msleep(200); + } else { + idtp9220_set_vout_regulator(di, 5800); + msleep(100); + idtp922x_set_pmi_icl(di, 100000); + msleep(100); + idtp922x_set_adap_vol(di, adapter_vol); + msleep(2000); + idtp922x_set_pmi_icl(di, DC_SDP_CURRENT); + msleep(100); + icl_setted = 1; + } + di->last_bpp_vout = adapter_vol; + } + + if ((icl_curr != di->last_bpp_icl) || (icl_setted)) { + dev_info(di->dev, "bpp_10w, set new icl: %d, last_icl: %d\n", + icl_curr, di->last_bpp_icl); + di->last_bpp_icl = icl_curr; + if ((adapter_vol == ADAPTER_BPP_QC_VOL) && + (!di->bpp_vout_rise)) { + dev_info(di->dev, + "bpp_10w, vout lower than 8v, set 500mA\n"); + icl_curr = min(DC_SDP_CURRENT, icl_curr); + } + idtp922x_set_pmi_icl(di, icl_curr); + } +} + +static void idtp9220_qc2_f1_tx_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, qc2_f1_tx_work.work); + int soc = 0, batt_sts = 0; + int vout = VOUT_VAL_6500_MV; + int dc_icl = DC_QC2_CURRENT; + union power_supply_propval val = { + 0, + }; + + if (di->batt_psy) { + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_STATUS, &val); + batt_sts = val.intval; + + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &val); + soc = val.intval; + } + + if (vout != di->last_qc2_vout) { + dev_info(di->dev, + "qc2+f1_tx, set new vout: %d, last_vout: %d\n", vout, + di->last_qc2_vout); + di->last_qc2_vout = vout; + di->bus.write(di, 0x003E, vout); + msleep(100); + idtp9220_set_vout_regulator(di, VBUCK_DEFAULT_VOL); + msleep(100); + } + + if (dc_icl != di->last_qc2_icl) { + dev_info(di->dev, "qc2+f1_tx, set new icl: %d, last_icl: %d\n", + dc_icl, di->last_qc2_icl); + di->last_qc2_icl = dc_icl; + idtp922x_set_pmi_icl(di, dc_icl); + } +} + +static void idtp9220_qc3_epp_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, qc3_epp_work.work); + int adapter_vol = 0; + int dc_icl = DC_MI_STEP1_CURRENT; + + if (adapter_vol != di->last_qc3_vout) { + dev_info(di->dev, "qc3 epp, set new vout: %d, last_vout: %d\n", + adapter_vol, di->last_qc3_vout); + di->last_qc3_vout = adapter_vol; + idtp922x_set_adap_vol(di, adapter_vol); + msleep(200); + } + + if (dc_icl != di->last_qc3_icl) { + dev_info(di->dev, "qc3_epp, set new icl: %d, last_icl: %d\n", + dc_icl, di->last_qc3_icl); + di->last_qc3_icl = dc_icl; + if (dc_icl == DC_MI_STEP1_CURRENT) { + schedule_delayed_work(&di->vout_regulator_work, + msecs_to_jiffies(0)); + } + idtp922x_set_pmi_icl(di, dc_icl); + } +} + +static void idtp9220_vout_regulator_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, vout_regulator_work.work); + + union power_supply_propval val = { + 0, + }; + int ret; + int vinc = 0; + int soc = 0; + + if (di->batt_psy) { + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &val); + soc = val.intval; + } + + if (di) + idtp9220_get_vout(di); + else + return; + + if (di->epp) + vinc = (di->vout > EPP_VOL_THRESHOLD) ? 1 : 0; + else + vinc = (di->vout > BPP_VOL_THRESHOLD) ? 1 : 0; + + if (vinc && !di->epp) { + di->bpp_vout_rise = 1; + goto out; + } else if (!vinc && !di->epp) { + di->bpp_vout_rise = 0; + goto out; + } + + if (di->epp && (vinc || di->is_epp_qc3 || di->is_vin_limit) && + soc < 95) { + ret = idtp9220_get_property_names(di); + if (di->wireless_psy) { + val.intval = 1; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, &val); + msleep(200); + if (!di->is_epp_qc3 && !di->is_vin_limit) + idtp922x_set_pmi_icl(di, DC_MI_CURRENT); + } else + dev_err(di->dev, "[idt] no wireless psy\n"); + } +out: + dev_info(di->dev, "[idt] %s: epp=%d vbuck=%d vout= %d\n", __func__, + di->epp, di->vbuck, di->vout); + return; +} + +static void idtp9220_set_charging_param(struct idtp9220_device_info *di) +{ + int soc = 0, health = 0, batt_sts = 0; + int adapter_vol = 0, icl_curr = 0; + int cur_now = 0, vol_now = 0, vin_inc = 0; + union power_supply_propval val = { + 0, + }; + + switch (di->tx_charger_type) { + case ADAPTER_QC2: + adapter_vol = ADAPTER_BPP_QC_VOL; + di->vbuck = VBUCK_QC_VOL; + icl_curr = DC_QC2_CURRENT; + break; + case ADAPTER_QC3: + if (!di->epp) { + adapter_vol = ADAPTER_BPP_QC_VOL; + di->vbuck = VBUCK_QC_VOL; + icl_curr = DC_QC3_CURRENT; + } else { + di->is_epp_qc3 = 1; + icl_curr = DC_MI_STEP1_CURRENT; + } + break; + case ADAPTER_XIAOMI_PD: + case ADAPTER_PD: + if (di->epp) { + di->vbuck = VBUCK_QC_VOL; + icl_curr = DC_QC3_CURRENT; + } else { + di->vbuck = VBUCK_DEFAULT_VOL; + icl_curr = DC_PD_CURRENT; + } + break; + case ADAPTER_AUTH_FAILED: + if (di->epp) { + di->vbuck = VBUCK_QC_VOL; + if (di->power_max <= 10000) + icl_curr = ((di->power_max - 1000) / + (VBUCK_QC_VOL / 1000)) * + 1000; + else + icl_curr = DC_QC3_CURRENT; + } else { + di->vbuck = VBUCK_DEFAULT_VOL; + icl_curr = DC_BPP_AUTH_FAIL_CURRENT; + } + break; + case ADAPTER_DCP: + case ADAPTER_CDP: + di->vbuck = VBUCK_DEFAULT_VOL; + if (di->is_compatible_hwid) + icl_curr = DC_BPP_AUTH_FAIL_CURRENT; + else + icl_curr = DC_DCP_CURRENT; + break; + case ADAPTER_SDP: + di->vbuck = VBUCK_DEFAULT_VOL; + icl_curr = DC_SDP_CURRENT; + break; + case ADAPTER_XIAOMI_QC3: + case ADAPTER_ZIMI_CAR_POWER: + case ADAPTER_XIAOMI_PD_40W: + if (di->epp) { + adapter_vol = ADAPTER_EPP_MI_VOL; + icl_curr = DC_MI_STEP1_CURRENT; + } else { + di->vbuck = VBUCK_QC_VOL; + icl_curr = DC_QC3_CURRENT; + } + break; + default: + icl_curr = 0; + break; + } + + power_supply_get_property(di->batt_psy, POWER_SUPPLY_PROP_STATUS, &val); + batt_sts = val.intval; + + power_supply_get_property(di->batt_psy, POWER_SUPPLY_PROP_CAPACITY, + &val); + soc = val.intval; + + power_supply_get_property(di->batt_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, + &val); + vol_now = val.intval; + + power_supply_get_property(di->batt_psy, POWER_SUPPLY_PROP_CURRENT_NOW, + &val); + cur_now = val.intval; + + power_supply_get_property(di->batt_psy, POWER_SUPPLY_PROP_HEALTH, &val); + health = val.intval; + + idtp9220_get_iout(di); + + if ((batt_sts == POWER_SUPPLY_STATUS_DISCHARGING) && di->dcin_present && + di->power_good_flag) { + dev_info(di->dev, + "discharge when dc and pwr present, reset chip\n"); + schedule_delayed_work(&di->fast_operate_work, + msecs_to_jiffies(0)); + return; + } + dev_info( + di->dev, + "[idtp] soc:%d,vol_now:%d,cur_now:%d,health:%d, bat_status:%d\n", + soc, vol_now, cur_now, health, batt_sts); + + /* adapter:qc2/qc3; tx:e5/d5x_10W; + * vout/vbuck/psns is setted in delayed work + */ + if (adapter_vol == ADAPTER_BPP_QC_VOL && di->is_compatible_hwid) { + schedule_delayed_work(&di->bpp_e5_tx_work, msecs_to_jiffies(0)); + goto out; + } + + /* adapter:qc2; tx:F1_27W; + * vout/vbuck/psns is setted in delayed work + */ + if (di->tx_charger_type == ADAPTER_QC2 && di->is_f1_tx) { + schedule_delayed_work(&di->qc2_f1_tx_work, msecs_to_jiffies(0)); + goto out; + } + + /* adapter:qc3_epp; tx:F1_27W; + * vout/vbuck/psns is setted in delayed work + */ + if (di->is_epp_qc3) { + schedule_delayed_work(&di->qc3_epp_work, msecs_to_jiffies(0)); + goto out; + } + + if (adapter_vol > 0 && adapter_vol != di->last_vin) { + idtp922x_set_adap_vol(di, adapter_vol); + vin_inc = 1; + di->last_vin = adapter_vol; + if (adapter_vol == ADAPTER_EPP_MI_VOL || + adapter_vol == EPP_VOL_THRESHOLD) { + msleep(100); + idtp922x_set_pmi_icl(di, icl_curr); + di->last_icl = icl_curr; + if (di->is_vin_limit) + schedule_delayed_work(&di->vout_regulator_work, + msecs_to_jiffies(0)); + } + } else { + if (((di->tx_charger_type == ADAPTER_QC2) || + (di->tx_charger_type == ADAPTER_QC3)) && + !di->epp && !di->bpp_vout_rise && icl_curr > DC_DCP_CURRENT) + dev_info( + di->dev, + "don't set curr with qc2/qc3 of bpp when vout low\n"); + else { + if (icl_curr > 0 && icl_curr != di->last_icl) { + idtp922x_set_pmi_icl(di, icl_curr); + di->last_icl = icl_curr; + } + msleep(150); + if (di->vbuck > 0 && di->vbuck != di->last_vbuck) { + idtp9220_set_vout_regulator(di, di->vbuck); + di->last_vbuck = di->vbuck; + } + } + } + + printk("[idtp] di->status:0x%x,adapter_vol =%d,icl_curr=%d, vbuck=%d, last_vin=%d, last_icl=%d\n", + di->status, adapter_vol, icl_curr, di->vbuck, di->last_vin, + di->last_icl); + + if (adapter_vol == ADAPTER_EPP_MI_VOL || + adapter_vol == ADAPTER_BPP_QC_VOL || + adapter_vol == VBUCK_FULL_VOL) { + if (vin_inc && (!di->is_vin_limit && !di->is_epp_qc3)) + schedule_delayed_work(&di->cmd_check_work, + msecs_to_jiffies(8000)); + } + +out: + return; +} + +static void idtp9220_wpc_det_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, wpc_det_work.work); + union power_supply_propval val = { + 0, + }; + int ret = 0; + + ret = idtp9220_get_property_names(di); + if (ret < 0) { + dev_err(di->dev, "get property error: %d\n", ret); + return; + } + + if (gpio_is_valid(di->dt_props.wpc_det_gpio)) { + ret = gpio_get_value(di->dt_props.wpc_det_gpio); + if (ret) { + /* check if mophie tx after 100ms */ + schedule_delayed_work(&di->mophie_tx_work, + msecs_to_jiffies(100)); + /* check dc present to judge device skewing */ + schedule_delayed_work(&di->dc_check_work, + msecs_to_jiffies(2500)); + di->power_good_flag = 1; + val.intval = 1; + idtp9220_int_enable(di); + } else { + cancel_delayed_work(&di->dc_check_work); + di->power_good_flag = 0; + val.intval = 0; + di->ss = 2; + } + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN, &val); + } + + return; +} + +static void idtp9220_irq_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = + container_of(work, struct idtp9220_device_info, irq_work.work); + u8 int_buf[2] = { 0 }; + u16 int_val = 0; + int rc = 0; + u8 recive_data[5] = { 0 }; + static int retry = 0; + static int retry_id = 0; + static int retry_count = 0; + int tx_vin = 0; + int irq_level; + + if (gpio_is_valid(di->dt_props.irq_gpio)) + irq_level = gpio_get_value(di->dt_props.irq_gpio); + else { + dev_err(di->dev, "%s: irq gpio not provided\n", __func__); + irq_level = -1; + return; + } + if (irq_level) { + return; + } + + rc = di->bus.read_buf(di, REG_INTR_L, int_buf, 2); + if (rc < 0) { + dev_err(di->dev, "[idt]read int state error: %d\n", rc); + goto out; + } + /* clear int and enable irq immediately when read int register*/ + idtp922x_clrInt(di, int_buf, 2); + + int_val = int_buf[0] | (int_buf[1] << 8); + dev_info(di->dev, "[idt] int: 0x%04x\n", int_val); + + msleep(5); + + if (need_irq_cleared(di)) { + u8 clr_buf[2] = { 0xFF, 0xFF }; + idtp922x_clrInt(di, clr_buf, 2); + msleep(5); + } + if ((int_val & INT_OV_CURR) || (int_val & INT_OV_TEMP)) { + dev_info(di->dev, "[idt] ocp or otp found \n"); + schedule_delayed_work(&di->chg_monitor_work, + msecs_to_jiffies(0)); + goto out; + } + + if (int_val & INT_VOUT_ON) { + di->epp = idtp9220_get_power_profile(di); + if (di->epp) { + di->power_max = idtp9220_get_power_max(di); + schedule_delayed_work(&di->epp_connect_load_work, + msecs_to_jiffies(0)); + } else + schedule_delayed_work(&di->bpp_connect_load_work, + msecs_to_jiffies(0)); + if (int_val & INT_IDAUTH_SUCESS) + idtp9220_send_device_auth(di); + goto out; + } + + if (int_val & INT_VSWITCH_SUCESS) { + schedule_delayed_work(&di->vout_regulator_work, + msecs_to_jiffies(50)); + cancel_delayed_work(&di->cmd_check_work); + goto out; + } + + if (int_val & INT_IDAUTH_SUCESS) { + idtp9220_send_device_auth(di); + //idtp922x_request_adapter(di); + goto out; + } + + if (int_val & INT_AUTH_SUCESS) { + idtp922x_request_uuid(di, di->epp); + goto out; + } + /* + idtp9220_get_signal_strength(di); + di->tx_charger_type = ADAPTER_QC3; + schedule_delayed_work(&di->chg_monitor_work, + msecs_to_jiffies(0)); + goto out; +*/ + + if ((int_val & INT_IDAUTH_FAIL) || (int_val & INT_AUTH_FAIL) || + int_val == 0) { + if (((int_val & INT_AUTH_FAIL) || (int_val == 0)) && + (retry < 5)) { + idtp9220_send_device_auth(di); + retry++; + dev_info(di->dev, "[idtp] dev auth failed retry %d\n", + retry); + goto out; + } else if ((int_val & INT_IDAUTH_FAIL) && retry_id < 5) { + idtp9220_retry_id_auth(di); + retry_id++; + dev_info(di->dev, "[idtp] id auth failed retry %d\n", + retry); + goto out; + } else { + retry = 0; + retry_id = 0; + } + di->tx_charger_type = ADAPTER_AUTH_FAILED; + + schedule_delayed_work(&di->rx_vout_work, msecs_to_jiffies(0)); + schedule_delayed_work(&di->chg_monitor_work, + msecs_to_jiffies(0)); + goto out; + } else + retry = 0; + /* + if (int_val & INT_IDAUTH_FAIL) { + idtp922x_request_adapter(di); + goto out; + } +*/ + + if (int_val & INT_SEND_TIMEOUT) { + if (retry_count < 3) { + dev_info(di->dev, "timeout retry %d\n", retry_count); + idtp922x_retry_cmd(di); + retry_count++; + goto out; + } else { + dev_err(di->dev, "%s: retry failed\n", __func__); + di->tx_charger_type = ADAPTER_AUTH_FAILED; + schedule_delayed_work(&di->rx_vout_work, + msecs_to_jiffies(0)); + schedule_delayed_work(&di->chg_monitor_work, + msecs_to_jiffies(0)); + retry_count = 0; + goto out; + } + } else { + retry_count = 0; + } + + if (int_val & INT_TX_DATA_RECV) { + idtp922x_receivePkt(di, recive_data); + dev_info(di->dev, "[idt] cmd: %x\n", recive_data[0]); + + switch (recive_data[0]) { + case BC_TX_HWID: + if (recive_data[4] == 0x01 && recive_data[2] == 0x2 && + recive_data[3] == 0x8 && recive_data[1] == 0x6) { + di->is_car_tx = 1; + } + idtp922x_request_adapter(di); + break; + case BC_TX_COMPATIBLE_HWID: + if (recive_data[1] == 0x12 && recive_data[2]) + di->is_compatible_hwid = 1; + if (recive_data[1] == 0x16 && recive_data[2] == 0x11) + di->is_f1_tx = 1; + idtp922x_request_adapter(di); + break; + case BC_ADAPTER_TYPE: + if (di->is_car_tx && + (recive_data[1] == ADAPTER_XIAOMI_QC3)) + + di->tx_charger_type = ADAPTER_ZIMI_CAR_POWER; + else + di->tx_charger_type = recive_data[1]; + + if (!di->epp && (di->tx_charger_type == ADAPTER_QC3 || + di->tx_charger_type == ADAPTER_QC2)) { + idtp922x_set_adap_vol(di, ADAPTER_BPP_VOL); + } + schedule_delayed_work(&di->rx_vout_work, + msecs_to_jiffies(100)); + schedule_delayed_work(&di->chg_monitor_work, + msecs_to_jiffies(1000)); + if (di->wireless_psy) + power_supply_changed(di->wireless_psy); + break; + case BC_READ_Vin: + tx_vin = recive_data[1] | (recive_data[2] << 8); + if (!di->power_off_mode) { + if (di->epp) + idtp922x_set_adap_vol( + di, ADAPTER_EPP_MI_VOL); + else + idtp922x_set_adap_vol( + di, ADAPTER_BPP_QC_VOL); + } + break; + case BC_RX_ID_AUTH: + idtp9220_send_device_auth(di); + break; + default: + dev_info(di->dev, "[idt] unsupport cmd: %x\n", + recive_data[0]); + break; + } + } + +out: + return; +} + +static irqreturn_t idtp9220_wpc_det_irq_handler(int irq, void *dev_id) +{ + struct idtp9220_device_info *di = dev_id; + + schedule_delayed_work(&di->wpc_det_work, msecs_to_jiffies(0)); + + return IRQ_HANDLED; +} + +static irqreturn_t idtp9220_irq_handler(int irq, void *dev_id) +{ + struct idtp9220_device_info *di = dev_id; + + schedule_delayed_work(&di->irq_work, msecs_to_jiffies(30)); + + return IRQ_HANDLED; +} + +static int idtp9220_irq_request(struct idtp9220_device_info *di) +{ + int ret = 0; + + if (!di->irq) { + dev_err(di->dev, "%s: irq is wrong\n", __func__); + return -EINVAL; + } + + ret = request_irq(di->irq, idtp9220_irq_handler, IRQF_TRIGGER_FALLING, + di->name, di); + if (ret) { + dev_err(di->dev, "%s: request_irq failed\n", __func__); + return ret; + } + + ret = enable_irq_wake(di->irq); + if (ret) { + dev_err(di->dev, "%s: enable_irq_wake failed\n", __func__); + return ret; + } + + if (!di->wpc_irq) { + dev_err(di->dev, "%s: wpc irq is wrong\n", __func__); + return -EINVAL; + } + + ret = request_irq(di->wpc_irq, idtp9220_wpc_det_irq_handler, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "wpc_det", + di); + if (ret) { + dev_err(di->dev, "%s: wpc request_irq failed\n", __func__); + return ret; + } + + ret = enable_irq_wake(di->wpc_irq); + if (ret) { + dev_err(di->dev, "%s: enable_irq_wake failed\n", __func__); + return ret; + } + + return 0; +} + +static struct regmap_config i2c_idtp9220_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .max_register = 0xFFFF, +}; + +/* +static int idtp9220_get_version(struct idtp9220_device_info *di) +{ + int id_val = 0; + u8 chip_id[2] = {0}; + + di->bus.read_buf(di, REG_CHIP_ID_L, chip_id, 2); + id_val = (chip_id[1] << 8) | chip_id[0]; + + return id_val; +} +*/ + +static enum power_supply_property idtp9220_props[] = { + POWER_SUPPLY_PROP_PIN_ENABLED, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_WIRELESS_VERSION, + POWER_SUPPLY_PROP_SIGNAL_STRENGTH, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, + POWER_SUPPLY_PROP_TX_ADAPTER, +}; + +static int idtp9220_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct idtp9220_device_info *di = power_supply_get_drvdata(psy); + + switch (psp) { + case POWER_SUPPLY_PROP_PIN_ENABLED: + val->intval = gpio_get_value(di->dt_props.enable_gpio); + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = di->dcin_present; + break; + case POWER_SUPPLY_PROP_WIRELESS_VERSION: + val->intval = di->epp; + break; + case POWER_SUPPLY_PROP_SIGNAL_STRENGTH: + val->intval = di->ss; + break; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + val->intval = idtp9220_get_vout_regulator(di); + break; + case POWER_SUPPLY_PROP_TX_ADAPTER: + val->intval = di->tx_charger_type; + break; + default: + return -EINVAL; + } + return 0; +} + +static int idtp9220_set_prop(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + struct idtp9220_device_info *di = power_supply_get_drvdata(psy); + int rc = 0; + + int data; + + switch (psp) { + case POWER_SUPPLY_PROP_PIN_ENABLED: + rc = idtp9220_set_enable_mode(di, val->intval); + break; + case POWER_SUPPLY_PROP_PRESENT: + rc = idtp9220_set_present(di, val->intval); + break; + case POWER_SUPPLY_PROP_SIGNAL_STRENGTH: + di->ss = val->intval; + power_supply_changed(di->idtp_psy); + break; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + data = val->intval / 1000; + if (data >= 6000) { + idtp9220_set_vout_regulator(di, data); + dev_info(di->dev, "[idt] set buck %s\n", __func__); + } + break; + default: + return -EINVAL; + } + + return rc; +} + +static int idtp9220_prop_is_writeable(struct power_supply *psy, + enum power_supply_property psp) +{ + int rc; + + switch (psp) { + case POWER_SUPPLY_PROP_PIN_ENABLED: + case POWER_SUPPLY_PROP_PRESENT: + case POWER_SUPPLY_PROP_SIGNAL_STRENGTH: + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + return 1; + default: + rc = 0; + break; + } + + return rc; +} + +static const struct power_supply_desc idtp_psy_desc = { + .name = "idt", + .type = POWER_SUPPLY_TYPE_WIRELESS, + .properties = idtp9220_props, + .num_properties = ARRAY_SIZE(idtp9220_props), + .get_property = idtp9220_get_prop, + .set_property = idtp9220_set_prop, + .property_is_writeable = idtp9220_prop_is_writeable, +}; + +static int idtp9220_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0; + struct idtp9220_device_info *di; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct power_supply_config idtp_cfg = {}; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) { + dev_err(&client->dev, "i2c check functionality failed!\n"); + return -EIO; + } + + di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL); + if (!di) { + dev_err(&client->dev, + "i2c allocated device info data failed!\n"); + return -ENOMEM; + } + + di->name = IDT_DRIVER_NAME; + di->dev = &client->dev; + di->chip_enable = 1; + di->ss = 2; + di->status = NORMAL_MODE; + di->regmap = devm_regmap_init_i2c(client, &i2c_idtp9220_regmap_config); + if (!di->regmap) + return -ENODEV; + di->bus.read = idtp9220_read; + di->bus.write = idtp9220_write; + di->bus.read_buf = idtp9220_read_buffer; + di->bus.write_buf = idtp9220_write_buffer; + INIT_DELAYED_WORK(&di->irq_work, idtp9220_irq_work); + INIT_DELAYED_WORK(&di->wpc_det_work, idtp9220_wpc_det_work); + mutex_init(&di->read_lock); + mutex_init(&di->write_lock); + device_init_wakeup(&client->dev, true); + i2c_set_clientdata(client, di); + g_di = di; + + ret = idtp9220_parse_dt(di); + if (ret < 0) { + dev_err(di->dev, "%s: parse dt error [%d]\n", __func__, ret); + goto cleanup; + } + + ret = idtp9220_gpio_init(di); + if (ret < 0) { + dev_err(di->dev, "%s: gpio init error [%d]\n", __func__, ret); + goto cleanup; + } + + ret = idtp9220_irq_request(di); + if (ret < 0) { + dev_err(di->dev, "%s: request irq error [%d]\n", __func__, ret); + goto cleanup; + } + + if (sysfs_create_group(&client->dev.kobj, &sysfs_group_attrs)) { + dev_err(&client->dev, "create sysfs attrs failed!\n"); + ret = -EIO; + goto cleanup; + } + idtp_cfg.drv_data = di; + di->idtp_psy = + power_supply_register(di->dev, &idtp_psy_desc, &idtp_cfg); + + INIT_DELAYED_WORK(&di->chg_monitor_work, idtp9220_monitor_work); + INIT_DELAYED_WORK(&di->chg_detect_work, idtp9220_chg_detect_work); + INIT_DELAYED_WORK(&di->bpp_connect_load_work, + idtp9220_bpp_connect_load_work); + INIT_DELAYED_WORK(&di->epp_connect_load_work, + idtp9220_epp_connect_load_work); + INIT_DELAYED_WORK(&di->cmd_check_work, idtp9220_cmd_check_work); + INIT_DELAYED_WORK(&di->vout_regulator_work, + idtp9220_vout_regulator_work); + INIT_DELAYED_WORK(&di->rx_vout_work, idtp9220_rx_vout_work); + INIT_DELAYED_WORK(&di->dc_check_work, idtp9220_dc_check_work); + INIT_DELAYED_WORK(&di->fast_operate_work, idtp9220_fast_operate_work); + INIT_DELAYED_WORK(&di->mophie_tx_work, idtp9220_mophie_tx_work); + INIT_DELAYED_WORK(&di->bpp_e5_tx_work, idtp9220_bpp_e5_tx_work); + INIT_DELAYED_WORK(&di->qc2_f1_tx_work, idtp9220_qc2_f1_tx_work); + INIT_DELAYED_WORK(&di->qc3_epp_work, idtp9220_qc3_epp_work); + + dev_info(di->dev, "[idt] success probe idtp922x driver\n"); + schedule_delayed_work(&di->chg_detect_work, 3 * HZ); + + return 0; + +cleanup: + free_irq(di->irq, di); + cancel_delayed_work_sync(&di->irq_work); + i2c_set_clientdata(client, NULL); + + return ret; +} + +static int idtp9220_remove(struct i2c_client *client) +{ + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + gpio_free(di->dt_props.enable_gpio); + cancel_delayed_work_sync(&di->irq_work); + i2c_set_clientdata(client, NULL); + + return 0; +} + +static void idtp9220_shutdown(struct i2c_client *client) +{ + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + if (di->power_good_flag) + idtp9220_set_reset(di); +} + +static const struct i2c_device_id idtp9220_id[] = { + { IDT_DRIVER_NAME, 0 }, + {}, +}; + +static const struct of_device_id idt_match_table[] = { { .compatible = + "idt,p9220" }, + {} }; + +MODULE_DEVICE_TABLE(i2c, idtp9220_id); + +static struct i2c_driver idtp9220_driver = { + .driver = { + .name = IDT_DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = idt_match_table, + }, + .probe = idtp9220_probe, + .remove = idtp9220_remove, + .shutdown = idtp9220_shutdown, + .id_table = idtp9220_id, +}; + +module_i2c_driver(idtp9220_driver); + +MODULE_AUTHOR("bsp-charging@xiaomi.com"); +MODULE_DESCRIPTION("IDTP9220 Wireless Power Charger Monitor driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/power/supply/renesas/idtp9220.h b/drivers/power/supply/renesas/idtp9220.h new file mode 100644 index 000000000000..f3a067e6358a --- /dev/null +++ b/drivers/power/supply/renesas/idtp9220.h @@ -0,0 +1,2263 @@ +/** + * @file idtp9220.h + * @author + * @date Sun Nov 22 11:49:55 2015 + * + * @brief + * + * + */ +#ifndef __IDTP9220_H__ +#define __IDTP9220_H__ + +#include +#include +#include + +#define IDT_DRIVER_NAME "idtp9220" +#define IDT_I2C_ADDR 0x61 + +#define HSCLK 60000 + +#define ADJUST_METE_MV 35 +#define IDTP9220_DELAY 2000 +#define CHARGING_FULL 100 +#define CHARGING_NEED 95 + +/* status low regiter bits define */ +#define STATUS_VOUT_ON (1 << 7) +#define STATUS_VOUT_OFF (1 << 6) +#define STATUS_TX_DATA_RECV (1 << 4) +#define STATUS_OV_TEMP (1 << 2) +#define STATUS_OV_VOL (1 << 1) +#define STATUS_OV_CURR (1 << 0) + +#define OVER_EVENT_OCCUR (STATUS_OV_TEMP | STATUS_OV_VOL | STATUS_OV_CURR) +#define TOGGLE_LDO_ON_OFF (1 << 1) + +/* interrupt register bits define */ +#define INT_IDAUTH_SUCESS (1 << 13) +#define INT_IDAUTH_FAIL (1 << 12) +#define INT_SEND_SUCESS (1 << 11) +#define INT_SEND_TIMEOUT (1 << 10) +#define INT_AUTH_SUCESS (1 << 9) +#define INT_AUTH_FAIL (1 << 8) +#define INT_VOUT_OFF (1 << 7) +#define INT_VOUT_ON (1 << 6) +#define INT_MODE_CHANGE (1 << 5) +#define INT_TX_DATA_RECV (1 << 4) +#define INT_VSWITCH_SUCESS (1 << 3) +#define INT_OV_TEMP (1 << 2) +#define INT_OV_VOL (1 << 1) +#define INT_OV_CURR (1 << 0) + +/* used registers define */ +#define REG_CHIP_ID_L 0x0000 +#define REG_CHIP_ID_H 0x0001 +#define REG_CHIP_REV 0x0002 +#define REG_CTM_ID 0x0003 +#define REG_OTPFWVER_ADDR 0x0004 // OTP firmware version +#define REG_EPRFWVER_ADDR 0x001c // EEPROM firmware version +#define REG_STATUS_L 0x0034 +#define REG_STATUS_H 0x0035 +#define REG_INTR_L 0x0036 +#define REG_INTR_H 0x0037 +#define REG_INTR_EN_L 0x0038 +#define REG_INTR_EN_H 0x0039 +#define REG_CHG_STATUS 0x003A +#define REG_ADC_VOUT_L 0x003C +#define REG_ADC_VOUT_H 0x003D +#define REG_VOUT_SET 0x003E +#define REG_VRECT_ADJ 0x003F +#define REG_ADC_VRECT 0x0040 +#define REG_RX_LOUT_L 0x0044 +#define REG_RX_LOUT_H 0x0045 +#define REG_FREQ_ADDR \ + 0x0048 // Operating Frequency, Fop(KHz) = 64 * 6000 /value * 256) +#define REG_ILIM_SET 0x004A +#define REG_SIGNAL_STRENGTH 0x004B +#define REG_WPC_MODE 0x004D +#define REG_SSCMND 0x004e // Command Register, COM (0x4E) +#define REG_RX_RESET 0x004F +#define REG_PROPPKT \ + 0x0050 // Proprietary Packet Header Register, PPP_Header (0x50) +#define REG_PPPDATA \ + 0x0051 // PPP Data Value Register(0X51, 0x52, 0x53, 0x54, 0x55) +#define REG_SSINTCLR 0x0056 // Interrupt Clear Registers, INT_Clear_L (0x56) +#define REG_BCHEADER 0x0058 // Back Channel Packet Register (0x58) +#define REG_BCDATA \ + 0x0059 // Back Channel Packet Register (0x59, 0x5A, 0x5B, 0x5C) +#define REG_FC_VOLTAGE_L 0x0078 // Fast Charging Voltage Register +#define REG_FC_VOLTAGE_H 0x0079 +#define REG_REGULATOR_L 0x000C +#define REG_REGULATOR_H 0x000d +#define REG_POWER_MAX 0x0084 //Get the TX power on EPP mode. +#define REG_TX_TYPE 0x00A2 //Get the TX type. + +// RX -> TX +#define PROPRIETARY18 0x18 +#define PROPRIETARY28 0x28 +#define PROPRIETARY38 0x38 +#define PROPRIETARY48 0x48 +#define PROPRIETARY58 0x58 + +// bitmap for customer command +#define BC_NONE 0x00 +#define BC_SET_FREQ 0x03 +#define BC_GET_FREQ 0x04 +#define BC_READ_FW_VER 0x05 +#define BC_READ_Iin 0x06 +#define BC_READ_Vin 0x07 +#define BC_SET_Vin 0x0a + +#define BC_ADAPTER_TYPE 0x0b +#define BC_RESET 0x0c +#define BC_READ_I2C 0x0d +#define BC_WRITE_I2C 0x0e +#define BC_VI2C_INIT 0x10 +#define BC_RX_ID_AUTH 0x3b +#define BC_TX_COMPATIBLE_HWID 0x3f +#define BC_TX_HWID 0x4c +#define BC_TX_TOGGLE 0xc4 + +//Factory test command +#define BC_READ_IOUT 0x12 +#define BC_READ_VOUT 0x13 +#define BC_START_CHARGE 0x30 +#define BC_SET_AP_OVERLOAD 0x31 +#define BC_ENABLE_FAST_CHARGE 0x32 + +/* Adapter_list = {0x00:'ADAPTER_UNKNOWN', */ +/* 0x01:'SDP 500mA', */ +/* 0x02:'CDP 1.1A', */ +/* 0x03:'DCP 1.5A', */ +/* 0x05:'QC2.0', */ +/* 0x06:'QC3.0', */ +/* 0x07:'PD',} */ +//define adapter type +#define ADAPTER_NONE 0x00 +#define ADAPTER_SDP 0x01 +#define ADAPTER_CDP 0x02 +#define ADAPTER_DCP 0x03 +#define ADAPTER_QC2 0x05 +#define ADAPTER_QC3 0x06 +#define ADAPTER_PD 0x07 +#define ADAPTER_AUTH_FAILED 0x08 +#define ADAPTER_XIAOMI_QC3 0x09 +#define ADAPTER_XIAOMI_PD 0x0a +#define ADAPTER_ZIMI_CAR_POWER 0x0b +#define ADAPTER_XIAOMI_PD_40W 0x0c + +#define NORMAL_MODE 0x1 +#define TAPER_MODE 0x2 +#define FULL_MODE 0x3 +#define RECHG_MODE 0x4 + +// bitmap for status flags +// 1: indicates a pending interrupt for LDO Vout state change – from OFF to ON +#define VOUTCHANGED BIT(7) // Stat_Vout_ON +// 1: indicates a pending interrupt for TX Data Received. (Change from “No Received Data†state to “Data Received†state) +#define TXDATARCVD BIT(4) // TX Data Received + +// bitmap for SSCmnd register 0x4e +#define VSWITCH BIT(7) +// If AP sets this bit to "1" then IDTP9220 M0 clears the interrupt corresponding to the bit(s) which has a value of “1†+#define CLRINT BIT(5) // Clear Interrupt +// If AP sets this bit to "1" then IDTP9220 M0 toggles LDO output once (from on to off, or from off to on), and then sets this bit to “0†+#define LDOTGL BIT(1) // Toggle LDO On/OFF +// If AP sets this bit to “1†then IDTP9220 M0 sends the Proprietary Packet +#define SENDPROPP BIT(0) // SEND RX Data + +#define SEND_DEVICE_AUTH BIT(2) + +enum VOUT_SET_VAL { + VOUT_VAL_3500_MV = 0, + VOUT_VAL_3600_MV, + VOUT_VAL_3700_MV, + VOUT_VAL_3800_MV, + VOUT_VAL_3900_MV, + VOUT_VAL_4000_MV, + VOUT_VAL_4100_MV, + VOUT_VAL_4200_MV, + VOUT_VAL_4300_MV, + VOUT_VAL_4400_MV, + VOUT_VAL_4500_MV, + VOUT_VAL_4600_MV, + VOUT_VAL_4700_MV, + VOUT_VAL_4800_MV, + VOUT_VAL_4900_MV, + VOUT_VAL_5000_MV, + VOUT_VAL_5100_MV, + VOUT_VAL_5200_MV, + VOUT_VAL_5300_MV, + VOUT_VAL_5400_MV, + VOUT_VAL_5500_MV, + VOUT_VAL_5600_MV, + VOUT_VAL_5700_MV, + VOUT_VAL_5800_MV, + VOUT_VAL_5900_MV, + VOUT_VAL_6000_MV, + VOUT_VAL_6100_MV, + VOUT_VAL_6200_MV, + VOUT_VAL_6300_MV, + VOUT_VAL_6400_MV, + VOUT_VAL_6500_MV, + VOUT_VAL_6600_MV, + VOUT_VAL_6700_MV, + VOUT_VAL_6800_MV, + VOUT_VAL_6900_MV, + VOUT_VAL_7000_MV, + VOUT_VAL_7100_MV, + VOUT_VAL_7200_MV, + VOUT_VAL_7300_MV, + VOUT_VAL_7400_MV, + VOUT_VAL_7500_MV, + VOUT_VAL_7600_MV, + VOUT_VAL_7700_MV, + VOUT_VAL_7800_MV, + VOUT_VAL_7900_MV, + VOUT_VAL_8000_MV, +}; + +enum IMIL_SET_VAL { + CURR_VAL_100_MA = 0, + CURR_VAL_200_MA, + CURR_VAL_300_MA, + CURR_VAL_400_MA, + CURR_VAL_500_MA, + CURR_VAL_600_MA, + CURR_VAL_700_MA, + CURR_VAL_800_MA, + CURR_VAL_900_MA, + CURR_VAL_1000_MA, + CURR_VAL_1100_MA, + CURR_VAL_1200_MA, + CURR_VAL_1300_MA, +}; + +struct vol_curr_table { + int index; + char *val; +}; +/* +struct idtp9220_platform_data { + enum VOUT_SET_VAL vout_val_default; + enum IMIL_SET_VAL curr_val_default; + unsigned long gpio_en; +}; +*/ +typedef struct { // write to structure at SRAM address 0x0400 + u16 status; // Read/Write by both 9220 and 9220 host + u16 startAddr; // OTP image address of the current packet + u16 codeLength; // The size of the OTP image data in the current packet + u16 dataChksum; // Checksum of the current packet + u8 dataBuf[128]; // OTP image data of the current packet +} idtp9220_packet_t; + +// proprietary packet type +typedef struct { + u8 header; // The header consists of a single byte that indicates the Packet type. + u8 cmd; // Back channel command + u8 data[4]; // Send data buffer +} ProPkt_Type; + +#if 1 +static char bootloader_data[] = { + 0x00, 0x04, 0x00, 0x20, 0xe3, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, /// 0x10 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /// 0x20 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, /// 0x30 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /// 0x40 + 0xfe, 0xe7, 0x00, 0x00, 0xf0, 0xb5, 0x3e, 0x49, + 0x00, 0x20, 0x0a, 0x88, 0x05, 0x46, 0x93, 0x06, /// 0x50 + 0x00, 0xd5, 0x04, 0x20, 0xd2, 0x06, 0x07, 0xd5, + 0x8a, 0x78, 0x0b, 0x79, 0x1a, 0x43, 0x92, 0x07, /// 0x60 + 0x02, 0xd1, 0x20, 0x22, 0x10, 0x43, 0x01, 0x25, + 0x36, 0x4b, 0x5a, 0x22, 0x1a, 0x74, 0x35, 0x4b, /// 0x70 + 0x20, 0x3b, 0x18, 0x72, 0x02, 0x20, 0x40, 0x1c, + 0x20, 0x28, 0xfc, 0xd3, 0x32, 0x4c, 0x00, 0x26, /// 0x80 + 0xa6, 0x81, 0x48, 0x88, 0xe2, 0x13, 0x82, 0x18, + 0x00, 0x2d, 0x09, 0xd0, 0x00, 0x20, 0x03, 0xe0, /// 0x90 + 0x45, 0x18, 0xad, 0x68, 0x15, 0x50, 0x00, 0x1d, + 0x8d, 0x88, 0x85, 0x42, 0xf8, 0xd8, 0x08, 0xe0, /// 0xa0 + 0x00, 0x20, 0x03, 0xe0, 0x45, 0x18, 0x2d, 0x7a, + 0x15, 0x54, 0x40, 0x1c, 0x8d, 0x88, 0x85, 0x42, /// 0xb0 + 0xf8, 0xd8, 0x1e, 0x72, 0x25, 0x48, 0xa0, 0x81, + 0x02, 0x20, 0x00, 0x24, 0x23, 0x46, 0x0b, 0xe0, /// 0xc0 + 0x5f, 0x18, 0x3e, 0x7a, 0xd5, 0x5c, 0xae, 0x42, + 0x05, 0xd0, 0x3d, 0x72, 0x00, 0x2c, 0x00, 0xd1, /// 0xd0 + 0x4b, 0x80, 0x04, 0x20, 0x64, 0x1c, 0x5b, 0x1c, + 0x8d, 0x88, 0x9d, 0x42, 0xf0, 0xd8, 0x8c, 0x80, /// 0xe0 + 0xf0, 0xbd, 0x1c, 0x49, 0x1a, 0x48, 0x08, 0x60, + 0x17, 0x48, 0x5a, 0x21, 0x40, 0x38, 0x01, 0x70, /// 0xf0 + 0x01, 0x21, 0x01, 0x71, 0x05, 0x21, 0x01, 0x72, + 0x17, 0x49, 0x81, 0x81, 0x08, 0x25, 0x10, 0x4f, /// 0x100 + 0x02, 0x26, 0x38, 0x78, 0x3c, 0x46, 0xc0, 0x07, + 0xfb, 0xd0, 0x60, 0x88, 0xa2, 0x88, 0x10, 0x18, /// 0x110 + 0x81, 0xb2, 0x00, 0x20, 0x04, 0xe0, 0x03, 0x19, + 0x1b, 0x7a, 0x59, 0x18, 0x89, 0xb2, 0x40, 0x1c, /// 0x120 + 0x82, 0x42, 0xf8, 0xd8, 0xe0, 0x88, 0x88, 0x42, + 0x01, 0xd0, 0x3d, 0x80, 0xe9, 0xe7, 0x00, 0x2a, /// 0x130 + 0x03, 0xd0, 0xff, 0xf7, 0x87, 0xff, 0x20, 0x80, + 0xe3, 0xe7, 0x3e, 0x80, 0xe1, 0xe7, 0x00, 0x00, /// 0x140 + 0x00, 0x04, 0x00, 0x20, 0x40, 0x5c, 0x00, 0x40, + 0x40, 0x30, 0x00, 0x40, 0xff, 0x01, 0x00, 0x00, /// 0x150 + 0xff, 0x0f, 0x00, 0x00, 0x80, 0xe1, 0x00, 0xe0, + 0x04, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char idt_firmware_otp[] = { + /// ver 2.3.1.42 + 0x00, 0x08, 0x00, 0x20, 0xa9, 0x02, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, + 0x73, 0x00, 0x00, 0x00, /// 0x10 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /// 0x20 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x75, 0x00, 0x00, 0x00, /// 0x30 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /// 0x40 + 0x81, 0x0e, 0x00, 0x00, 0x87, 0x0e, 0x00, 0x00, 0x8d, 0x0e, 0x00, 0x00, + 0x93, 0x0e, 0x00, 0x00, /// 0x50 + 0x99, 0x0e, 0x00, 0x00, 0x9f, 0x0e, 0x00, 0x00, 0xa5, 0x0e, 0x00, 0x00, + 0xab, 0x0e, 0x00, 0x00, /// 0x60 + 0xb1, 0x0e, 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x00, 0xbd, 0x0e, 0x00, 0x00, + 0xc3, 0x0e, 0x00, 0x00, /// 0x70 + 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0x00, 0x20, + 0x00, 0x68, 0x80, 0xf3, /// 0x80 + 0x08, 0x88, 0x70, 0x47, 0xb6, 0x48, 0x00, 0x21, 0x01, 0x72, 0x41, 0x72, + 0x70, 0x47, 0x10, 0xb5, /// 0x90 + 0xb3, 0x4b, 0x1a, 0x7a, 0x5c, 0x7a, 0x51, 0x1c, 0x09, 0x07, 0x09, 0x0f, + 0x8c, 0x42, 0x01, 0xd1, /// 0xa0 + 0x01, 0x20, 0x10, 0xbd, 0xaf, 0x4c, 0x92, 0x00, 0x12, 0x19, 0xff, 0x32, + 0x01, 0x32, 0x90, 0x60, /// 0xb0 + 0x19, 0x72, 0x00, 0x20, 0x10, 0xbd, 0xab, 0x4e, 0x34, 0x46, 0xff, 0x34, + 0x41, 0x34, 0x21, 0x7a, /// 0xc0 + 0x60, 0x7a, 0x81, 0x42, 0x01, 0xd1, 0x30, 0xbf, 0xf9, 0xe7, 0x81, 0x00, + 0x89, 0x19, 0xff, 0x31, /// 0xd0 + 0x01, 0x31, 0x8d, 0x68, 0x00, 0x2d, 0x0c, 0xd0, 0x40, 0x1c, 0x00, 0x07, + 0x00, 0x0f, 0x60, 0x72, /// 0xe0 + 0xa8, 0x47, 0x00, 0x28, 0xeb, 0xd0, 0x72, 0xb6, 0x28, 0x46, 0xff, 0xf7, + 0xd0, 0xff, 0x62, 0xb6, /// 0xf0 + 0xe5, 0xe7, 0xff, 0xf7, 0xc7, 0xff, 0xe2, 0xe7, 0x9c, 0x49, 0x9b, 0x48, + 0x08, 0x60, 0xff, 0xf7, /// 0x100 + 0xbc, 0xff, 0x9b, 0x48, 0x5a, 0x21, 0x01, 0x70, 0x00, 0x24, 0x04, 0x71, + 0x09, 0x21, 0x01, 0x72, /// 0x110 + 0x98, 0x49, 0x81, 0x81, 0x0a, 0x21, 0x81, 0x82, 0x97, 0x49, 0x01, 0x83, + 0x08, 0x21, 0x81, 0x83, /// 0x120 + 0x93, 0x49, 0x02, 0x20, 0x20, 0x31, 0x08, 0x76, 0x94, 0x48, 0x84, 0x80, + 0x93, 0x49, 0x94, 0x48, /// 0x130 + 0x08, 0x80, 0x39, 0x20, 0x00, 0x02, 0x08, 0x82, 0x92, 0x48, 0x01, 0x26, + 0x06, 0x80, 0x81, 0x27, /// 0x140 + 0x07, 0x80, 0x90, 0x48, 0x90, 0x49, 0x20, 0x30, 0x01, 0x80, 0x90, 0x49, + 0x89, 0x78, 0x31, 0x43, /// 0x150 + 0x01, 0x71, 0x8f, 0x49, 0x40, 0x20, 0x08, 0x72, 0x20, 0x20, 0x08, 0x76, + 0x0c, 0x77, 0x8c, 0x49, /// 0x160 + 0x20, 0x31, 0x08, 0x70, 0x0c, 0x71, 0x08, 0x73, 0x08, 0x74, 0x8a, 0x48, + 0x81, 0xb2, 0x8a, 0x48, /// 0x170 + 0x00, 0xf0, 0xff, 0xfb, 0x30, 0x22, 0x89, 0x49, 0x89, 0x48, 0x00, 0xf0, + 0xea, 0xfb, 0x89, 0x4d, /// 0x180 + 0x0e, 0x20, 0xa8, 0x72, 0x07, 0x20, 0xe8, 0x73, 0x4b, 0x20, 0x00, 0x01, + 0x00, 0xf0, 0xdc, 0xfb, /// 0x190 + 0x85, 0x48, 0x06, 0x70, 0x07, 0x70, 0x84, 0x49, 0x3b, 0x20, 0x08, 0x71, + 0x3f, 0x20, 0x08, 0x81, /// 0x1a0 + 0x21, 0x20, 0x08, 0x70, 0x00, 0xf0, 0xec, 0xfb, 0x00, 0xf0, 0x6f, 0xfb, + 0x7f, 0x49, 0x06, 0x20, /// 0x1b0 + 0x08, 0x60, 0x6e, 0x49, 0x80, 0x39, 0x08, 0x60, 0x7d, 0x48, 0x06, 0x80, + 0x03, 0x21, 0x01, 0x80, /// 0x1c0 + 0x41, 0x21, 0x01, 0x76, 0x7b, 0x48, 0x00, 0xf0, 0x55, 0xf9, 0x7b, 0x48, + 0x04, 0x71, 0x7b, 0x48, /// 0x1d0 + 0x44, 0x70, 0x00, 0xf0, 0xd1, 0xfd, 0x2f, 0x46, 0x60, 0x3f, 0x78, 0x73, + 0x00, 0xf0, 0xe7, 0xfa, /// 0x1e0 + 0x75, 0x48, 0x01, 0x7a, 0x89, 0x07, 0xfc, 0xd5, 0x73, 0x49, 0x20, 0x31, + 0x0c, 0x70, 0x02, 0x21, /// 0x1f0 + 0x01, 0x72, 0x5b, 0x49, 0x10, 0x22, 0x4c, 0x31, 0x88, 0x18, 0x00, 0xf0, + 0xaa, 0xfb, 0x07, 0x22, /// 0x200 + 0x01, 0x21, 0x00, 0x20, 0x00, 0xf0, 0x20, 0xf9, 0x40, 0x03, 0x01, 0x0c, + 0x65, 0x48, 0x20, 0x38, /// 0x210 + 0x81, 0x85, 0x78, 0x7b, 0xc0, 0x07, 0x0d, 0xd0, 0x61, 0x48, 0x69, 0x49, + 0x81, 0x61, 0x48, 0x20, /// 0x220 + 0xe8, 0x72, 0x00, 0xf0, 0xab, 0xfa, 0x01, 0xf0, 0x07, 0xf9, 0x4d, 0x48, + 0x44, 0x30, 0x00, 0xf0, /// 0x230 + 0x21, 0xf9, 0x01, 0xe0, 0x00, 0xf0, 0xe8, 0xfa, 0x62, 0x48, 0x01, 0x7d, + 0x59, 0x4e, 0xa0, 0x3e, /// 0x240 + 0x31, 0x70, 0x01, 0x7c, 0x71, 0x70, 0x00, 0x7e, 0xb0, 0x70, 0x02, 0x20, + 0xf0, 0x70, 0xff, 0x20, /// 0x250 + 0x02, 0x30, 0x70, 0x60, 0x5c, 0x48, 0xf0, 0x61, 0x0d, 0x20, 0xb8, 0x72, + 0x30, 0x46, 0x01, 0x27, /// 0x260 + 0x60, 0x30, 0x87, 0x70, 0x00, 0xf0, 0xa8, 0xfd, 0xa8, 0x73, 0x00, 0xf0, + 0x51, 0xf9, 0x57, 0x48, /// 0x270 + 0x07, 0x70, 0x81, 0x21, 0x01, 0x70, 0x0d, 0x21, 0x01, 0x70, 0x54, 0x4a, + 0x95, 0x21, 0x20, 0x32, /// 0x280 + 0x11, 0x80, 0xff, 0x21, 0x81, 0x82, 0x03, 0x21, 0x09, 0x02, 0x01, 0x82, + 0x04, 0x71, 0x47, 0x49, /// 0x290 + 0x61, 0x20, 0x08, 0x60, 0x35, 0x49, 0x80, 0x39, 0x08, 0x60, 0x4d, 0x48, + 0x30, 0x87, 0x40, 0x48, /// 0x2a0 + 0x4c, 0x49, 0x41, 0x60, 0xff, 0xf7, 0x07, 0xff, 0x08, 0x20, 0x00, 0xf0, + 0x4d, 0xfb, 0x30, 0x48, /// 0x2b0 + 0x40, 0x30, 0x01, 0x78, 0x49, 0x06, 0xfc, 0xd4, 0xff, 0xf7, 0x1e, 0xff, + 0x30, 0xb5, 0x28, 0x4c, /// 0x2c0 + 0x38, 0x4d, 0x40, 0x3c, 0x20, 0x68, 0x40, 0x1c, 0x20, 0x3d, 0x20, 0x60, + 0x28, 0x78, 0x80, 0x07, /// 0x2d0 + 0x04, 0xd4, 0x72, 0xb6, 0x60, 0x68, 0xff, 0xf7, 0xda, 0xfe, 0x62, 0xb6, + 0x28, 0x78, 0x40, 0x07, /// 0x2e0 + 0x0a, 0xd5, 0x1f, 0x48, 0x20, 0x30, 0x81, 0x7d, 0xc0, 0x7d, 0x81, 0x42, + 0x04, 0xd0, 0x72, 0xb6, /// 0x2f0 + 0x39, 0x48, 0xff, 0xf7, 0xcc, 0xfe, 0x62, 0xb6, 0x72, 0xb6, 0xa0, 0x6f, + 0xff, 0xf7, 0xc7, 0xfe, /// 0x300 + 0x62, 0xb6, 0x00, 0x20, 0x30, 0xbd, 0x70, 0xb5, 0x00, 0x25, 0x27, 0x4c, + 0x08, 0x26, 0x0a, 0xe0, /// 0x310 + 0x20, 0x78, 0x30, 0x43, 0x20, 0x70, 0x6d, 0x1c, 0x0a, 0x2d, 0x01, 0xd3, + 0xff, 0xf7, 0xec, 0xfe, /// 0x320 + 0x14, 0x20, 0x00, 0xf0, 0x11, 0xfb, 0x20, 0x78, 0x00, 0x07, 0xf1, 0xd4, + 0x15, 0x48, 0x20, 0x30, /// 0x330 + 0x01, 0x88, 0xc9, 0x04, 0x11, 0xd5, 0x0a, 0x49, 0x40, 0x39, 0x0a, 0x68, + 0x80, 0x31, 0x09, 0x6e, /// 0x340 + 0x51, 0x1a, 0x02, 0x15, 0x91, 0x42, 0x08, 0xdb, 0x01, 0x88, 0x82, 0x14, + 0x91, 0x43, 0x01, 0x80, /// 0x350 + 0x07, 0x48, 0x01, 0x8b, 0x42, 0x14, 0x91, 0x43, 0x01, 0x83, 0x00, 0x20, + 0x70, 0xbd, 0x00, 0x00, /// 0x360 + 0x70, 0x02, 0x00, 0x20, 0x30, 0x01, 0x00, 0x20, 0xff, 0x0f, 0x00, 0x00, + 0x80, 0xe1, 0x00, 0xe0, /// 0x370 + 0x00, 0x30, 0x00, 0x40, 0x05, 0x1d, 0x00, 0x00, 0x3b, 0x23, 0x00, 0x00, + 0x00, 0x34, 0x00, 0x40, /// 0x380 + 0x01, 0x0a, 0x00, 0x00, 0x00, 0x38, 0x00, 0x40, 0x0e, 0x30, 0x00, 0x00, + 0x60, 0x47, 0x00, 0x00, /// 0x390 + 0x00, 0x6c, 0x00, 0x40, 0xc8, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, + 0xe4, 0x14, 0x00, 0x00, /// 0x3a0 + 0x00, 0x01, 0x00, 0x20, 0xa0, 0x00, 0x00, 0x20, 0x00, 0x3c, 0x00, 0x40, + 0x80, 0xe2, 0x00, 0xe0, /// 0x3b0 + 0x00, 0x44, 0x00, 0x40, 0xdc, 0x14, 0x00, 0x00, 0x00, 0x60, 0x00, 0x40, + 0x70, 0x03, 0x00, 0x20, /// 0x3c0 + 0xff, 0x0f, 0x00, 0x00, 0x60, 0x58, 0x00, 0x40, 0x46, 0x01, 0x03, 0x02, + 0x00, 0x64, 0x00, 0x40, /// 0x3d0 + 0x07, 0x40, 0x00, 0x00, 0x71, 0x10, 0x00, 0x00, 0x0d, 0x0e, 0x00, 0x00, + 0x70, 0xb5, 0xf7, 0x49, /// 0x3e0 + 0x8a, 0x88, 0xd2, 0x43, 0x92, 0x07, 0x06, 0xd0, 0xf5, 0x4a, 0x92, 0x7f, + 0x32, 0x2a, 0x02, 0xd3, /// 0x3f0 + 0x40, 0x09, 0x00, 0x23, 0x03, 0xe0, 0xc2, 0x00, 0x10, 0x1a, 0xc0, 0x09, + 0x01, 0x23, 0x3c, 0x28, /// 0x400 + 0x01, 0xd2, 0x3c, 0x20, 0x02, 0xe0, 0xff, 0x28, 0x00, 0xd9, 0xff, 0x20, + 0x0a, 0x8a, 0xed, 0x4c, /// 0x410 + 0x12, 0x0a, 0xc0, 0x1e, 0x82, 0x42, 0x15, 0xd0, 0x00, 0x2b, 0x02, 0xd1, + 0x25, 0x79, 0x01, 0x2d, /// 0x420 + 0x03, 0xd0, 0x55, 0x1d, 0xa8, 0x42, 0x00, 0xd9, 0x28, 0x46, 0x0a, 0x8a, + 0x40, 0x25, 0x2a, 0x43, /// 0x430 + 0x0a, 0x82, 0x0a, 0x8a, 0x4f, 0x26, 0x32, 0x40, 0x00, 0x02, 0x02, 0x43, + 0x0a, 0x82, 0x08, 0x8a, /// 0x440 + 0xa8, 0x43, 0x08, 0x82, 0x23, 0x71, 0x70, 0xbd, 0x70, 0xb5, 0x00, 0x23, + 0xde, 0x4d, 0x0b, 0xe0, /// 0x450 + 0x44, 0x00, 0x64, 0x19, 0xff, 0x34, 0x81, 0x34, 0xa4, 0x8b, 0x26, 0x0b, + 0x96, 0x42, 0x07, 0xd1, /// 0x460 + 0x24, 0x05, 0x24, 0x0d, 0xe3, 0x18, 0x40, 0x18, 0x08, 0x28, 0xf1, 0xd3, + 0x18, 0x46, 0x70, 0xbd, /// 0x470 + 0xd6, 0x48, 0x70, 0xbd, 0x10, 0xb5, 0xd6, 0x4a, 0x00, 0x21, 0x11, 0x70, + 0xd1, 0x4b, 0x01, 0x21, /// 0x480 + 0x40, 0x3b, 0x59, 0x70, 0xd3, 0x49, 0x03, 0x88, 0x8b, 0x80, 0x43, 0x88, + 0x0b, 0x81, 0x83, 0x88, /// 0x490 + 0x8b, 0x81, 0xc0, 0x88, 0x08, 0x82, 0xb4, 0x20, 0x10, 0x70, 0xca, 0x48, + 0xf4, 0x38, 0x10, 0x81, /// 0x4a0 + 0x07, 0x20, 0x90, 0x80, 0xca, 0x48, 0x02, 0x22, 0x20, 0x38, 0x02, 0x72, + 0x03, 0x79, 0x72, 0xb6, /// 0x4b0 + 0x13, 0x43, 0x03, 0x71, 0x62, 0xb6, 0x11, 0x20, 0x08, 0x80, 0x10, 0xbd, + 0x01, 0x88, 0x42, 0x88, /// 0x4c0 + 0x51, 0x18, 0x82, 0x88, 0xc0, 0x88, 0x51, 0x18, 0x40, 0x18, 0xc3, 0x49, + 0x00, 0x22, 0x8a, 0x5e, /// 0x4d0 + 0x80, 0x10, 0x80, 0x1a, 0x00, 0xd5, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x49, + 0x4a, 0x14, 0x0b, 0x8b, /// 0x4e0 + 0x00, 0x28, 0x05, 0xd0, 0x93, 0x43, 0x0b, 0x83, 0x03, 0x28, 0x03, 0xd9, + 0x00, 0x22, 0x07, 0xe0, /// 0x4f0 + 0x13, 0x43, 0x0b, 0x83, 0x03, 0x21, 0x48, 0x40, 0x01, 0x21, 0x40, 0x03, + 0x09, 0x03, 0x42, 0x18, /// 0x500 + 0xb7, 0x48, 0x01, 0x88, 0x07, 0x23, 0x1b, 0x03, 0x99, 0x43, 0x11, 0x43, + 0x01, 0x80, 0x70, 0x47, /// 0x510 + 0xf8, 0xb5, 0xb2, 0x48, 0x00, 0x8b, 0x47, 0x26, 0xc0, 0x04, 0x36, 0x02, + 0xc1, 0x0e, 0xb5, 0x8a, /// 0x520 + 0x30, 0x8b, 0x4f, 0x1c, 0x2c, 0x1a, 0xaf, 0x48, 0x21, 0x46, 0x78, 0x43, + 0x00, 0xf0, 0x9e, 0xff, /// 0x530 + 0xa4, 0x49, 0xc8, 0x22, 0x40, 0x39, 0x00, 0x91, 0x88, 0x87, 0x28, 0x46, + 0x21, 0x46, 0x50, 0x43, /// 0x540 + 0x00, 0xf0, 0xaa, 0xff, 0xff, 0x21, 0x91, 0x31, 0x08, 0x1a, 0x00, 0x99, + 0xc8, 0x87, 0xf5, 0x8b, /// 0x550 + 0xf0, 0x8a, 0x29, 0x1a, 0xa4, 0x48, 0x78, 0x43, 0x00, 0xf0, 0x88, 0xff, + 0x99, 0x4c, 0x80, 0xb2, /// 0x560 + 0x20, 0x80, 0x39, 0x46, 0x15, 0x22, 0x68, 0x43, 0x51, 0x43, 0x00, 0xf0, + 0x7f, 0xff, 0x19, 0x21, /// 0x570 + 0x80, 0x09, 0x49, 0x01, 0x08, 0x1a, 0x00, 0xb2, 0x8d, 0x21, 0x48, 0x43, + 0xc1, 0x17, 0x09, 0x0e, /// 0x580 + 0x08, 0x18, 0x00, 0x12, 0x60, 0x80, 0xf8, 0xbd, 0x70, 0xb5, 0x05, 0x46, + 0x93, 0x48, 0x00, 0x8b, /// 0x590 + 0x8c, 0x4c, 0xc0, 0x04, 0x40, 0x3c, 0x61, 0x7a, 0xc0, 0x0e, 0x81, 0x42, + 0x02, 0xd0, 0x60, 0x72, /// 0x5a0 + 0xff, 0xf7, 0xb6, 0xff, 0x91, 0x48, 0x85, 0x42, 0x03, 0xd8, 0x3e, 0x22, + 0xa1, 0x8f, 0xa2, 0x5e, /// 0x5b0 + 0x1f, 0xe0, 0x8e, 0x49, 0x83, 0x48, 0x40, 0x31, 0x8d, 0x42, 0x03, 0xd3, + 0x02, 0x22, 0x01, 0x88, /// 0x5c0 + 0x82, 0x5e, 0x16, 0xe0, 0x89, 0x49, 0xa3, 0x8f, 0x49, 0x42, 0x6a, 0x18, + 0x01, 0x88, 0xc9, 0x1a, /// 0x5d0 + 0x51, 0x43, 0xce, 0x17, 0xb6, 0x0e, 0x71, 0x18, 0x89, 0x11, 0xc9, 0x18, + 0x02, 0x26, 0x3e, 0x23, /// 0x5e0 + 0x86, 0x5f, 0xe3, 0x5e, 0xf0, 0x1a, 0x50, 0x43, 0xc2, 0x17, 0x92, 0x0e, + 0x10, 0x18, 0x80, 0x11, /// 0x5f0 + 0xc2, 0x18, 0x4d, 0x43, 0x28, 0x0c, 0x80, 0x18, 0x00, 0xd5, 0x00, 0x20, + 0x70, 0xbd, 0xf8, 0xb5, /// 0x600 + 0x02, 0x22, 0x04, 0x21, 0x00, 0x20, 0xff, 0xf7, 0x1f, 0xff, 0x6e, 0x4d, + 0x6e, 0x4e, 0x20, 0x3d, /// 0x610 + 0xa9, 0x79, 0x09, 0x27, 0x49, 0x00, 0xc0, 0x03, 0x89, 0x19, 0xbf, 0x01, + 0x00, 0x0c, 0xc9, 0x19, /// 0x620 + 0x88, 0x81, 0x01, 0x22, 0x04, 0x21, 0x10, 0x46, 0xff, 0xf7, 0x0e, 0xff, + 0xa9, 0x79, 0xc0, 0x03, /// 0x630 + 0x49, 0x00, 0x89, 0x19, 0x00, 0x0c, 0xc9, 0x19, 0x88, 0x83, 0x03, 0x22, + 0x08, 0x21, 0x10, 0x46, /// 0x640 + 0xff, 0xf7, 0x02, 0xff, 0xa9, 0x79, 0x0f, 0x22, 0x49, 0x00, 0x89, 0x19, + 0xc9, 0x19, 0x88, 0x82, /// 0x650 + 0x04, 0x21, 0x02, 0x20, 0xff, 0xf7, 0xf8, 0xfe, 0xc0, 0x03, 0x01, 0x0c, + 0xa8, 0x79, 0x40, 0x00, /// 0x660 + 0x82, 0x19, 0x05, 0x20, 0xc0, 0x01, 0x10, 0x18, 0x81, 0x81, 0x04, 0x22, + 0x08, 0x21, 0x07, 0x20, /// 0x670 + 0xff, 0xf7, 0xea, 0xfe, 0x52, 0x4c, 0x20, 0x34, 0x23, 0x46, 0xe0, 0x80, + 0x40, 0x3b, 0x98, 0x69, /// 0x680 + 0x41, 0x00, 0x58, 0x69, 0xc2, 0x0f, 0x11, 0x43, 0x99, 0x61, 0x41, 0x00, + 0xa8, 0x79, 0x42, 0x00, /// 0x690 + 0x92, 0x19, 0xd2, 0x19, 0x12, 0x7b, 0x40, 0x1c, 0xd2, 0x07, 0xd2, 0x0f, + 0x11, 0x43, 0x80, 0x07, /// 0x6a0 + 0x80, 0x0f, 0x59, 0x61, 0xa8, 0x71, 0x28, 0x46, 0x14, 0x38, 0xff, 0xf7, + 0x07, 0xff, 0x21, 0x46, /// 0x6b0 + 0x60, 0x31, 0x0e, 0x22, 0x8a, 0x56, 0x80, 0x18, 0x20, 0x80, 0x28, 0x1f, + 0xff, 0xf7, 0xfe, 0xfe, /// 0x6c0 + 0x60, 0x87, 0x28, 0x46, 0x0c, 0x38, 0xff, 0xf7, 0xf9, 0xfe, 0x98, 0x87, + 0x28, 0x46, 0x2c, 0x30, /// 0x6d0 + 0xff, 0xf7, 0xf4, 0xfe, 0x40, 0x08, 0x01, 0x01, 0x40, 0x18, 0x27, 0x46, + 0x58, 0x81, 0x40, 0x37, /// 0x6e0 + 0x38, 0x78, 0xc0, 0x06, 0x48, 0xd5, 0x60, 0x8f, 0xff, 0xf7, 0x4e, 0xff, + 0xa1, 0x88, 0x08, 0x1a, /// 0x6f0 + 0x00, 0xd5, 0x40, 0x42, 0xc8, 0x28, 0x3f, 0xdd, 0xa8, 0x79, 0x40, 0x1e, + 0x80, 0x07, 0x40, 0x0f, /// 0x700 + 0x81, 0x19, 0x09, 0x20, 0x80, 0x01, 0x08, 0x18, 0x2e, 0x49, 0x80, 0x8b, + 0x40, 0x39, 0x88, 0x83, /// 0x710 + 0xc8, 0x83, 0x08, 0x84, 0x48, 0x84, 0x60, 0x87, 0xff, 0xf7, 0x36, 0xff, + 0xa1, 0x88, 0x05, 0x46, /// 0x720 + 0xa9, 0x42, 0x25, 0xd9, 0x38, 0x78, 0xc0, 0x07, 0x22, 0xd1, 0x40, 0x2d, + 0x01, 0xd2, 0xff, 0xf7, /// 0x730 + 0xd4, 0xfe, 0x22, 0x49, 0x80, 0x2d, 0x02, 0xd2, 0x01, 0x20, 0x88, 0x80, + 0x03, 0xe0, 0xff, 0x20, /// 0x740 + 0x41, 0x30, 0x85, 0x42, 0x01, 0xd2, 0x00, 0x20, 0x0c, 0xe0, 0xff, 0x20, + 0xe1, 0x30, 0x85, 0x42, /// 0x750 + 0x01, 0xd2, 0x01, 0x20, 0x06, 0xe0, 0x05, 0x20, 0xc0, 0x01, 0x85, 0x42, + 0x01, 0xd2, 0x02, 0x20, /// 0x760 + 0x00, 0xe0, 0x03, 0x20, 0x0a, 0x88, 0xf0, 0x23, 0x9a, 0x43, 0x80, 0x01, + 0x02, 0x43, 0x0a, 0x80, /// 0x770 + 0x1f, 0x48, 0xa5, 0x80, 0x32, 0x21, 0x41, 0x66, 0x00, 0x20, 0xf8, 0xbd, + 0x1d, 0x48, 0x01, 0x78, /// 0x780 + 0x42, 0x22, 0x11, 0x43, 0x01, 0x70, 0x1c, 0x49, 0xc0, 0x14, 0x08, 0x60, + 0x1b, 0x49, 0x08, 0x60, /// 0x790 + 0x70, 0x47, 0x0b, 0x49, 0x20, 0x39, 0xca, 0x8e, 0x02, 0x43, 0x08, 0x8f, + 0x10, 0x40, 0xc8, 0x86, /// 0x7a0 + 0x04, 0xd0, 0x17, 0x48, 0x01, 0x7f, 0xfb, 0x22, 0x11, 0x40, 0x01, 0x77, + 0x70, 0x47, 0x15, 0x48, /// 0x7b0 + 0x81, 0x21, 0x01, 0x80, 0x00, 0x21, 0x01, 0x80, 0x70, 0x47, 0x00, 0x00, + 0x00, 0x34, 0x00, 0x40, /// 0x7c0 + 0x20, 0x00, 0x00, 0x20, 0xb0, 0x03, 0x00, 0x20, 0x30, 0x01, 0x00, 0x20, + 0xff, 0xff, 0x00, 0x00, /// 0x7d0 + 0x20, 0x60, 0x00, 0x40, 0x00, 0x44, 0x00, 0x40, 0x20, 0x47, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x40, /// 0x7e0 + 0x20, 0x38, 0x00, 0x40, 0x00, 0x1a, 0x04, 0x00, 0x80, 0x92, 0x08, 0x00, + 0xda, 0x02, 0x00, 0x00, /// 0x7f0 + 0xb0, 0x02, 0x00, 0x20, 0x00, 0x3c, 0x00, 0x40, 0x80, 0xe2, 0x00, 0xe0, + 0x00, 0xe1, 0x00, 0xe0, /// 0x800 + 0x20, 0x6c, 0x00, 0x40, 0x00, 0x4c, 0x00, 0x40, 0x10, 0xb5, 0xff, 0x49, + 0x08, 0x20, 0x88, 0x83, /// 0x810 + 0xfe, 0x48, 0x00, 0x22, 0x82, 0x80, 0xfe, 0x4b, 0x03, 0x80, 0x39, 0x23, + 0x1b, 0x02, 0x03, 0x82, /// 0x820 + 0xfc, 0x48, 0x08, 0x83, 0xfc, 0x49, 0x81, 0x20, 0x08, 0x80, 0xfc, 0x48, + 0x0e, 0x21, 0x81, 0x72, /// 0x830 + 0x07, 0x21, 0xc1, 0x73, 0xf8, 0x48, 0xfa, 0x49, 0x20, 0x30, 0x01, 0x80, + 0xf9, 0x49, 0x01, 0x23, /// 0x840 + 0x89, 0x78, 0x19, 0x43, 0x01, 0x71, 0xf8, 0x49, 0x09, 0x20, 0x08, 0x70, + 0xff, 0xf7, 0xaf, 0xff, /// 0x850 + 0xf7, 0x48, 0xf6, 0x49, 0x41, 0x60, 0xf7, 0x49, 0x0b, 0x78, 0xfb, 0x24, + 0x23, 0x40, 0x0b, 0x70, /// 0x860 + 0xf5, 0x49, 0x81, 0x67, 0x01, 0x68, 0x80, 0x30, 0x01, 0x66, 0xec, 0x48, + 0x60, 0x38, 0x01, 0x46, /// 0x870 + 0x42, 0x73, 0x40, 0x39, 0x88, 0x8e, 0x40, 0x22, 0x90, 0x43, 0x20, 0x22, + 0x10, 0x43, 0x88, 0x86, /// 0x880 + 0x10, 0x46, 0xff, 0xf7, 0x86, 0xff, 0x00, 0x20, 0x10, 0xbd, 0xec, 0x48, + 0x00, 0x21, 0x01, 0x72, /// 0x890 + 0x41, 0x72, 0xeb, 0x48, 0x01, 0x21, 0x01, 0x80, 0x01, 0x15, 0x81, 0x80, + 0x0f, 0x21, 0x01, 0x80, /// 0x8a0 + 0x02, 0x22, 0x02, 0x81, 0x01, 0x83, 0x04, 0x21, 0x81, 0x82, 0x85, 0xe7, + 0xe5, 0x48, 0x01, 0x21, /// 0x8b0 + 0x01, 0x80, 0x02, 0x15, 0x82, 0x80, 0x2b, 0x22, 0x02, 0x80, 0x01, 0x81, + 0xe1, 0x49, 0x96, 0x22, /// 0x8c0 + 0x20, 0x31, 0x0a, 0x80, 0x7d, 0x22, 0x8a, 0x80, 0x0f, 0x21, 0x01, 0x83, + 0x08, 0x21, 0x81, 0x82, /// 0x8d0 + 0x72, 0xe7, 0x00, 0x28, 0x09, 0xd0, 0x00, 0x29, 0x07, 0xd0, 0x81, 0x42, + 0x01, 0xd9, 0x41, 0x1e, /// 0x8e0 + 0x89, 0xb2, 0xd8, 0x4a, 0x20, 0x32, 0x91, 0x80, 0x10, 0x80, 0x65, 0xe7, + 0x40, 0x1a, 0x10, 0xb5, /// 0x8f0 + 0x00, 0x23, 0x02, 0xb2, 0x00, 0x2a, 0x02, 0xda, 0x01, 0x23, 0x50, 0x42, + 0x02, 0xb2, 0xc7, 0x48, /// 0x900 + 0xa0, 0x38, 0xc4, 0x7c, 0x94, 0x42, 0x1e, 0xda, 0x19, 0x24, 0x64, 0x01, + 0xa2, 0x42, 0x0b, 0xdc, /// 0x910 + 0x01, 0x46, 0x09, 0x8a, 0x00, 0x2b, 0x01, 0xd0, 0x49, 0x1e, 0x00, 0xe0, + 0x49, 0x1c, 0x01, 0x82, /// 0x920 + 0x09, 0x04, 0x09, 0x0c, 0x08, 0xd0, 0x09, 0xe0, 0xff, 0x22, 0x15, 0x32, + 0x51, 0x43, 0xc6, 0x4a, /// 0x930 + 0x51, 0x1a, 0x89, 0x00, 0x09, 0x0c, 0xf2, 0xe7, 0x01, 0x21, 0x01, 0x82, + 0x8a, 0xb2, 0xc1, 0x89, /// 0x940 + 0x8a, 0x42, 0x00, 0xd9, 0x01, 0x82, 0x10, 0xbd, 0x00, 0xe0, 0x00, 0xbf, + 0x40, 0x1e, 0xfc, 0xd2, /// 0x950 + 0x32, 0xe7, 0x82, 0x18, 0x01, 0xe0, 0x08, 0xc9, 0x08, 0xc0, 0x90, 0x42, + 0xfb, 0xd3, 0x2b, 0xe7, /// 0x960 + 0x82, 0x18, 0x03, 0xe0, 0x0b, 0x78, 0x03, 0x70, 0x40, 0x1c, 0x49, 0x1c, + 0x90, 0x42, 0xf9, 0xd3, /// 0x970 + 0x22, 0xe7, 0x41, 0x18, 0x00, 0x22, 0x00, 0xe0, 0x04, 0xc0, 0x88, 0x42, + 0xfc, 0xd3, 0x1b, 0xe7, /// 0x980 + 0xb2, 0x48, 0x01, 0x21, 0x01, 0x70, 0xb1, 0x4a, 0x05, 0x21, 0x40, 0x32, + 0x11, 0x80, 0x00, 0x22, /// 0x990 + 0x02, 0x74, 0xae, 0x49, 0x20, 0x31, 0x0a, 0x74, 0xad, 0x4a, 0x8a, 0x81, + 0x13, 0x22, 0x0a, 0x70, /// 0x9a0 + 0x07, 0x21, 0x01, 0x72, 0x08, 0xe7, 0x9d, 0x4a, 0xa0, 0x3a, 0x11, 0x46, + 0x40, 0x31, 0xd0, 0x8e, /// 0x9b0 + 0xcb, 0x8a, 0x98, 0x43, 0xd0, 0x86, 0x00, 0x22, 0xca, 0x82, 0x00, 0x28, + 0x05, 0xd1, 0x9d, 0x48, /// 0x9c0 + 0x20, 0x38, 0x01, 0x7f, 0x04, 0x22, 0x11, 0x43, 0x01, 0x77, 0xf5, 0xe6, + 0x8f, 0x48, 0x00, 0x21, /// 0x9d0 + 0x80, 0x88, 0x00, 0x07, 0x00, 0xd5, 0x02, 0x21, 0x8b, 0x48, 0x80, 0x8b, + 0xc0, 0x04, 0x01, 0xd5, /// 0x9e0 + 0x01, 0x20, 0x01, 0x43, 0x9b, 0x48, 0x80, 0x89, 0xc0, 0x06, 0x01, 0xd5, + 0x04, 0x20, 0x01, 0x43, /// 0x9f0 + 0x8a, 0x4b, 0xa0, 0x3b, 0x9a, 0x8e, 0x50, 0x07, 0x40, 0x0f, 0x48, 0x40, + 0x04, 0xd0, 0xd2, 0x08, /// 0xa00 + 0xd2, 0x00, 0x0a, 0x43, 0x9a, 0x86, 0xc4, 0xe6, 0xd6, 0xe6, 0x02, 0x46, + 0x00, 0x20, 0x02, 0xe0, /// 0xa10 + 0x13, 0x78, 0x58, 0x40, 0x52, 0x1c, 0x49, 0x1e, 0xfa, 0xd2, 0xcd, 0xe6, + 0x08, 0x22, 0x01, 0x21, /// 0xa20 + 0x01, 0xe0, 0x09, 0x18, 0x40, 0x08, 0x52, 0x1e, 0xfb, 0xd2, 0xc8, 0x07, + 0xc0, 0x0f, 0xc3, 0xe6, /// 0xa30 + 0xf8, 0xb5, 0x89, 0x4c, 0x00, 0x26, 0x20, 0x46, 0xff, 0x30, 0xa1, 0x30, + 0x84, 0x46, 0x0c, 0x30, /// 0xa40 + 0x01, 0x27, 0xff, 0x34, 0x35, 0x46, 0xc1, 0x34, 0x00, 0x90, 0x60, 0x7a, + 0x00, 0x28, 0x0e, 0xd1, /// 0xa50 + 0x60, 0x46, 0xa1, 0x7a, 0x00, 0x7b, 0x81, 0x42, 0x06, 0xd2, 0x01, 0x20, + 0xb0, 0x40, 0x49, 0x1c, /// 0xa60 + 0x05, 0x43, 0xa1, 0x72, 0xb6, 0x1c, 0x36, 0xe0, 0x00, 0x20, 0xa0, 0x72, + 0x67, 0x72, 0x61, 0x7a, /// 0xa70 + 0x20, 0x7a, 0x81, 0x42, 0x1d, 0xd2, 0xa0, 0x7a, 0x00, 0x28, 0x1d, 0xd0, + 0x09, 0x28, 0x06, 0xd2, /// 0xa80 + 0x00, 0x9a, 0x40, 0x1e, 0x89, 0x5c, 0xc1, 0x40, 0xc8, 0x07, 0xc0, 0x0f, + 0x14, 0xe0, 0x09, 0x28, /// 0xa90 + 0x05, 0xd0, 0xff, 0x22, 0x01, 0x20, 0xa2, 0x72, 0x49, 0x1c, 0x61, 0x72, + 0x0c, 0xe0, 0x00, 0x98, /// 0xaa0 + 0x08, 0x5c, 0xff, 0xf7, 0xbb, 0xff, 0x61, 0x46, 0x09, 0x7b, 0x00, 0x29, + 0x04, 0xd1, 0x78, 0x40, /// 0xab0 + 0x02, 0xe0, 0x60, 0x7d, 0xa7, 0x75, 0x78, 0x40, 0x61, 0x7d, 0x79, 0x40, + 0x48, 0x40, 0x60, 0x75, /// 0xac0 + 0x40, 0x00, 0x08, 0x43, 0xb0, 0x40, 0x05, 0x43, 0xa0, 0x7a, 0xb6, 0x1c, + 0x40, 0x1c, 0xa0, 0x72, /// 0xad0 + 0xa0, 0x7d, 0x01, 0x28, 0x01, 0xd0, 0x10, 0x2e, 0xb7, 0xd3, 0x76, 0x1e, + 0x26, 0x75, 0x65, 0x82, /// 0xae0 + 0xf8, 0xbd, 0x70, 0xb5, 0x05, 0x46, 0x41, 0x1c, 0x54, 0x48, 0x53, 0x38, + 0xff, 0xf7, 0x8d, 0xff, /// 0xaf0 + 0x59, 0x49, 0x52, 0x4c, 0x49, 0x19, 0xff, 0x31, 0xa1, 0x31, 0x88, 0x73, + 0x40, 0x3c, 0xed, 0x1c, /// 0xb00 + 0x25, 0x72, 0x20, 0x7b, 0xe0, 0x72, 0x00, 0x20, 0x60, 0x72, 0xa0, 0x72, + 0x60, 0x75, 0x02, 0x26, /// 0xb10 + 0xa6, 0x75, 0xff, 0xf7, 0x8d, 0xff, 0x40, 0x48, 0x20, 0x30, 0x01, 0x88, + 0xc9, 0x04, 0x61, 0x7b, /// 0xb20 + 0x03, 0xd5, 0x20, 0x22, 0x11, 0x43, 0x61, 0x73, 0x07, 0xe0, 0xdf, 0x22, + 0x11, 0x40, 0x61, 0x73, /// 0xb30 + 0x01, 0x88, 0x01, 0x22, 0x12, 0x03, 0x11, 0x43, 0x01, 0x80, 0x34, 0x49, + 0x0a, 0x8a, 0x0c, 0x23, /// 0xb40 + 0x1a, 0x43, 0x0a, 0x82, 0x03, 0x88, 0x03, 0x21, 0x09, 0x02, 0x8b, 0x43, + 0x33, 0x49, 0x30, 0x25, /// 0xb50 + 0xca, 0x7a, 0x15, 0x40, 0x2d, 0x01, 0x2b, 0x43, 0x03, 0x80, 0x2f, 0x4d, + 0x3f, 0x4b, 0xab, 0x80, /// 0xb60 + 0x2e, 0x81, 0x00, 0x23, 0xdb, 0x43, 0xab, 0x81, 0x48, 0x23, 0x1a, 0x40, + 0x25, 0x32, 0x2a, 0x80, /// 0xb70 + 0x62, 0x8a, 0x2a, 0x82, 0x22, 0x7d, 0x2a, 0x75, 0xa2, 0x7b, 0x00, 0x2a, + 0x14, 0xd1, 0x0a, 0x46, /// 0xb80 + 0x60, 0x3a, 0x33, 0x4b, 0xd2, 0x8f, 0xb4, 0x3b, 0x9a, 0x42, 0x0d, 0xd9, + 0xca, 0x7b, 0x1f, 0x2a, /// 0xb90 + 0x01, 0xd9, 0x1f, 0x22, 0xca, 0x73, 0x02, 0x88, 0xc9, 0x7b, 0x52, 0x09, + 0x52, 0x01, 0x0a, 0x43, /// 0xba0 + 0x02, 0x80, 0x01, 0x79, 0x31, 0x43, 0x01, 0x71, 0xff, 0xf7, 0x42, 0xff, + 0xff, 0x20, 0x00, 0x02, /// 0xbb0 + 0xa8, 0x81, 0x70, 0xbd, 0x70, 0xb5, 0x00, 0x20, 0xff, 0xf7, 0x8f, 0xfc, + 0x1d, 0x49, 0x08, 0x78, /// 0xbc0 + 0xdf, 0x22, 0x10, 0x40, 0x08, 0x70, 0x15, 0x48, 0xef, 0x24, 0xa0, 0x38, + 0x82, 0x7c, 0x22, 0x40, /// 0xbd0 + 0x82, 0x74, 0x0d, 0x4a, 0x08, 0x23, 0x93, 0x83, 0x1d, 0x4b, 0xac, 0x3b, + 0x13, 0x83, 0x39, 0x22, /// 0xbe0 + 0x0a, 0x4b, 0x12, 0x02, 0x1a, 0x82, 0x00, 0x22, 0x9a, 0x80, 0x1d, 0x88, + 0xf0, 0x26, 0xb5, 0x43, /// 0xbf0 + 0x1d, 0x80, 0x12, 0x4b, 0xfb, 0x25, 0x40, 0x3b, 0x5e, 0x7b, 0x2e, 0x40, + 0x5e, 0x73, 0x0b, 0x78, /// 0xc00 + 0x2b, 0x40, 0x0b, 0x70, 0x82, 0x87, 0x2b, 0xe0, 0x00, 0x30, 0x00, 0x40, + 0x00, 0x34, 0x00, 0x40, /// 0xc10 + 0x01, 0x0a, 0x00, 0x00, 0x3b, 0x3b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x40, + 0xa0, 0x00, 0x00, 0x20, /// 0xc20 + 0x0e, 0x30, 0x00, 0x00, 0x60, 0x47, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x40, + 0x07, 0x03, 0x00, 0x00, /// 0xc30 + 0x30, 0x02, 0x00, 0x20, 0x40, 0x6c, 0x00, 0x40, 0x3d, 0x15, 0x00, 0x00, + 0x30, 0x03, 0x00, 0x20, /// 0xc40 + 0x00, 0x4c, 0x00, 0x40, 0x00, 0x50, 0x00, 0x40, 0x55, 0x32, 0x34, 0x00, + 0x00, 0x54, 0x00, 0x40, /// 0xc50 + 0xe7, 0x03, 0x00, 0x00, 0x20, 0x48, 0x00, 0x40, 0x30, 0x01, 0x00, 0x20, + 0xdb, 0x05, 0x00, 0x00, /// 0xc60 + 0x01, 0x46, 0x40, 0x31, 0x8a, 0x87, 0x8a, 0x80, 0x40, 0x31, 0x0a, 0x78, + 0x22, 0x40, 0x0a, 0x70, /// 0xc70 + 0x81, 0x8e, 0x80, 0x22, 0x11, 0x43, 0x81, 0x86, 0x10, 0x46, 0xff, 0xf7, + 0x8a, 0xfd, 0x70, 0xbd, /// 0xc80 + 0x51, 0x4a, 0x10, 0x8b, 0xc0, 0x04, 0xc1, 0x0e, 0x50, 0x48, 0x80, 0x7a, + 0x40, 0x00, 0x40, 0x1c, /// 0xc90 + 0x1f, 0x28, 0x00, 0xdd, 0x1f, 0x20, 0x81, 0x42, 0x00, 0xd2, 0x48, 0x1c, + 0x11, 0x8b, 0x1f, 0x23, /// 0xca0 + 0x1b, 0x02, 0x99, 0x43, 0x00, 0x02, 0x01, 0x43, 0x11, 0x83, 0x49, 0x49, + 0x08, 0x88, 0x07, 0x22, /// 0xcb0 + 0x12, 0x02, 0x90, 0x43, 0x45, 0x4a, 0x20, 0x32, 0x92, 0x78, 0x52, 0x07, + 0x52, 0x0d, 0x10, 0x43, /// 0xcc0 + 0x08, 0x80, 0x42, 0x48, 0x60, 0x30, 0x81, 0x7a, 0x1f, 0x29, 0x01, 0xd9, + 0x1f, 0x21, 0x81, 0x72, /// 0xcd0 + 0x40, 0x49, 0x0a, 0x88, 0x80, 0x7a, 0x52, 0x09, 0x52, 0x01, 0x02, 0x43, + 0x0a, 0x80, 0x6b, 0xe5, /// 0xce0 + 0xf8, 0xb5, 0x41, 0x09, 0x3c, 0x4a, 0x00, 0x29, 0x0a, 0xd0, 0x20, 0x29, + 0x01, 0xdb, 0x1f, 0x21, /// 0xcf0 + 0x06, 0xe0, 0x93, 0x7b, 0x8b, 0x42, 0x01, 0xda, 0x49, 0x1e, 0x01, 0xe0, + 0x8b, 0x42, 0x00, 0xdd, /// 0xd00 + 0x91, 0x73, 0x47, 0x21, 0x09, 0x02, 0x0e, 0x22, 0x8a, 0x56, 0x30, 0x49, + 0x20, 0x39, 0x8e, 0x7f, /// 0xd10 + 0xc9, 0x7f, 0xb3, 0x00, 0x8f, 0x07, 0xbf, 0x0f, 0x39, 0x46, 0xd2, 0x18, + 0x1c, 0x31, 0x51, 0x18, /// 0xd20 + 0x29, 0x4a, 0x11, 0x82, 0x23, 0x36, 0x7d, 0x21, 0x70, 0x43, 0xc9, 0x00, + 0x00, 0xf0, 0x9e, 0xfb, /// 0xd30 + 0x26, 0x4c, 0x40, 0x34, 0xa1, 0x7c, 0x08, 0x1a, 0x04, 0xd4, 0xe1, 0x7c, + 0x40, 0x43, 0x41, 0x43, /// 0xd40 + 0x48, 0x11, 0x00, 0xe0, 0x00, 0x20, 0xe1, 0x8a, 0x0d, 0x18, 0xa0, 0x8a, + 0xa8, 0x42, 0x00, 0xd2, /// 0xd50 + 0x05, 0x46, 0x96, 0x2e, 0x00, 0xd1, 0x00, 0x25, 0xb0, 0x00, 0xc0, 0x19, + 0x80, 0x02, 0xd2, 0x21, /// 0xd60 + 0x00, 0xf0, 0x84, 0xfb, 0x1e, 0x21, 0x61, 0x56, 0x40, 0x19, 0x08, 0x18, + 0x1b, 0x49, 0x88, 0x42, /// 0xd70 + 0x00, 0xd9, 0x08, 0x46, 0x20, 0x82, 0xf8, 0xbd, 0x17, 0x48, 0x17, 0x49, + 0x10, 0xb5, 0xc0, 0x38, /// 0xd80 + 0x17, 0x4a, 0x48, 0x31, 0x13, 0x78, 0x5b, 0x06, 0x02, 0xd4, 0x03, 0x68, + 0x05, 0x2b, 0x01, 0xd3, /// 0xd90 + 0x00, 0x20, 0x10, 0xbd, 0x0b, 0x78, 0x05, 0x2b, 0xf4, 0xd9, 0x0f, 0x48, + 0x81, 0x8d, 0xc2, 0x8d, /// 0xda0 + 0x51, 0x18, 0x02, 0x8e, 0x40, 0x8e, 0x51, 0x18, 0x41, 0x18, 0x0e, 0x48, + 0x00, 0xf0, 0x5e, 0xfb, /// 0xdb0 + 0x06, 0x49, 0x08, 0x84, 0x01, 0x20, 0x10, 0xbd, 0x0b, 0x48, 0x0c, 0x4a, + 0x01, 0x89, 0x51, 0x1a, /// 0xdc0 + 0x00, 0x22, 0x82, 0x5e, 0x88, 0x18, 0xf7, 0xe4, 0x00, 0x30, 0x00, 0x40, + 0x40, 0x00, 0x00, 0x20, /// 0xdd0 + 0x00, 0x34, 0x00, 0x40, 0x20, 0x38, 0x00, 0x40, 0xf0, 0x02, 0x00, 0x20, + 0xff, 0x0f, 0x00, 0x00, /// 0xde0 + 0x00, 0x3c, 0x00, 0x40, 0x00, 0x70, 0x17, 0x00, 0x20, 0x47, 0x00, 0x00, + 0x31, 0x04, 0x00, 0x00, /// 0xdf0 + 0x1e, 0x49, 0x1f, 0x4b, 0x8a, 0x7d, 0x92, 0x00, 0xd2, 0x18, 0xff, 0x32, + 0x01, 0x32, 0xd0, 0x64, /// 0xe00 + 0x88, 0x7d, 0x40, 0x1c, 0x40, 0x07, 0x40, 0x0f, 0x88, 0x75, 0x70, 0x47, + 0x30, 0xb5, 0x19, 0x48, /// 0xe10 + 0x01, 0x79, 0x89, 0x06, 0x28, 0xd4, 0x18, 0x49, 0x40, 0x22, 0x0a, 0x70, + 0x80, 0x22, 0x0a, 0x74, /// 0xe20 + 0x12, 0x4a, 0x13, 0x4d, 0xd4, 0x7d, 0xa3, 0x00, 0x5b, 0x19, 0xff, 0x33, + 0x4d, 0x33, 0x0b, 0x83, /// 0xe30 + 0x04, 0x23, 0x8b, 0x82, 0x01, 0x23, 0x0b, 0x72, 0x0d, 0x79, 0x72, 0xb6, + 0x1d, 0x43, 0x0d, 0x71, /// 0xe40 + 0x64, 0x1c, 0x61, 0x07, 0x49, 0x0f, 0xd1, 0x75, 0x05, 0x21, 0x51, 0x75, + 0x62, 0xb6, 0x58, 0x21, /// 0xe50 + 0x01, 0x77, 0xff, 0x21, 0x81, 0x82, 0x09, 0x49, 0x01, 0x82, 0x30, 0x21, + 0x01, 0x71, 0x0f, 0x21, /// 0xe60 + 0x01, 0x70, 0x01, 0x79, 0x19, 0x43, 0x01, 0x71, 0x00, 0x20, 0x30, 0xbd, + 0x90, 0x02, 0x00, 0x20, /// 0xe70 + 0x30, 0x01, 0x00, 0x20, 0x00, 0x64, 0x00, 0x40, 0x00, 0x60, 0x00, 0x40, + 0xc6, 0x03, 0x00, 0x00, /// 0xe80 + 0x95, 0x48, 0x00, 0x68, 0x00, 0x47, 0x94, 0x48, 0x40, 0x68, 0x00, 0x47, + 0x92, 0x48, 0x80, 0x68, /// 0xe90 + 0x00, 0x47, 0x91, 0x48, 0xc0, 0x68, 0x00, 0x47, 0x8f, 0x48, 0x00, 0x69, + 0x00, 0x47, 0x8e, 0x48, /// 0xea0 + 0x40, 0x69, 0x00, 0x47, 0x8c, 0x48, 0x80, 0x69, 0x00, 0x47, 0x8b, 0x48, + 0xc0, 0x69, 0x00, 0x47, /// 0xeb0 + 0x89, 0x48, 0x00, 0x6a, 0x00, 0x47, 0x88, 0x48, 0x40, 0x6a, 0x00, 0x47, + 0x86, 0x48, 0x80, 0x6a, /// 0xec0 + 0x00, 0x47, 0x85, 0x48, 0xc0, 0x6a, 0x00, 0x47, 0xf8, 0xb5, 0x84, 0x48, + 0x02, 0x7a, 0x01, 0x79, /// 0xed0 + 0x0a, 0x40, 0x02, 0x72, 0xd1, 0x07, 0x19, 0xd0, 0x01, 0x79, 0x49, 0x08, + 0x49, 0x00, 0x01, 0x71, /// 0xee0 + 0x00, 0x21, 0x01, 0x74, 0x01, 0x70, 0x7e, 0x4c, 0x65, 0x7d, 0x7e, 0x49, + 0x02, 0x23, 0x05, 0x2d, /// 0xef0 + 0x09, 0xd0, 0x0e, 0x79, 0x04, 0x25, 0x2e, 0x43, 0x0e, 0x71, 0x0e, 0x8a, + 0xc1, 0x27, 0xbf, 0x00, /// 0xf00 + 0xbe, 0x43, 0x0e, 0x82, 0x65, 0x75, 0x0c, 0x79, 0x1c, 0x43, 0x0c, 0x71, + 0x91, 0x07, 0x10, 0xd5, /// 0xf10 + 0x01, 0x79, 0xfd, 0x22, 0x11, 0x40, 0x01, 0x71, 0x70, 0x48, 0x00, 0x24, + 0x20, 0x30, 0x04, 0x70, /// 0xf20 + 0x6f, 0x49, 0x10, 0x22, 0x2c, 0x31, 0x88, 0x18, 0xff, 0xf7, 0x13, 0xfd, + 0x6c, 0x48, 0xe0, 0x30, /// 0xf30 + 0x44, 0x70, 0xf8, 0xbd, 0xf8, 0xb5, 0x6b, 0x4c, 0xa0, 0x8a, 0x21, 0x8a, + 0x08, 0x40, 0xff, 0x21, /// 0xf40 + 0xa1, 0x82, 0xc6, 0x21, 0x06, 0x46, 0xff, 0x22, 0x0e, 0x40, 0x67, 0x4d, + 0x6d, 0x32, 0x11, 0x1d, /// 0xf50 + 0x52, 0x59, 0x49, 0x5b, 0xff, 0x35, 0x02, 0x23, 0x61, 0x35, 0x00, 0x2e, + 0x25, 0xd0, 0xc4, 0x26, /// 0xf60 + 0x30, 0x40, 0x00, 0x26, 0x00, 0x28, 0x08, 0xd0, 0x20, 0x79, 0x18, 0x43, + 0x20, 0x71, 0x20, 0x20, /// 0xf70 + 0xff, 0xf7, 0xea, 0xfc, 0x06, 0x20, 0x68, 0x75, 0x07, 0xe0, 0x68, 0x7d, + 0x04, 0x28, 0x03, 0xd1, /// 0xf80 + 0x20, 0x7b, 0x51, 0x18, 0x20, 0x39, 0xc8, 0x77, 0x6e, 0x75, 0x0d, 0x20, + 0x20, 0x70, 0x03, 0x20, /// 0xf90 + 0x00, 0x02, 0x20, 0x82, 0xfc, 0x20, 0x20, 0x77, 0x26, 0x71, 0x50, 0x48, + 0x06, 0x70, 0x06, 0x74, /// 0xfa0 + 0x01, 0x79, 0x49, 0x08, 0x49, 0x00, 0x01, 0x71, 0xf8, 0xbd, 0x4d, 0x4e, + 0xc7, 0x07, 0x20, 0x3e, /// 0xfb0 + 0x76, 0x8e, 0x00, 0x2f, 0x03, 0xd0, 0x30, 0x0a, 0x20, 0x73, 0x6b, 0x75, + 0xf8, 0xbd, 0xc0, 0x06, /// 0xfc0 + 0xfc, 0xd5, 0x68, 0x7d, 0x02, 0x28, 0x12, 0xd0, 0x21, 0x20, 0x20, 0x71, + 0xff, 0x20, 0xc3, 0x30, /// 0xfd0 + 0x20, 0x82, 0x42, 0x48, 0x40, 0x23, 0x03, 0x70, 0x90, 0x23, 0x03, 0x74, + 0x02, 0x83, 0x89, 0x1e, /// 0xfe0 + 0x81, 0x82, 0x01, 0x21, 0x01, 0x72, 0x02, 0x79, 0x0a, 0x43, 0x02, 0x71, + 0xf8, 0xbd, 0x26, 0x73, /// 0xff0 + 0x03, 0x20, 0x68, 0x75, 0xf8, 0xbd, 0x3d, 0x49, 0x81, 0x20, 0x08, 0x80, + 0x70, 0x47, 0x70, 0xb5, /// 0x1000 + 0x3a, 0x4b, 0x30, 0x20, 0x18, 0x76, 0x36, 0x48, 0x00, 0x24, 0x60, 0x30, + 0x81, 0x7d, 0x00, 0x29, /// 0x1010 + 0x0a, 0xd0, 0x42, 0x8a, 0x1a, 0x82, 0x02, 0x7d, 0x1a, 0x75, 0x01, 0x29, + 0x02, 0xd0, 0xff, 0xf7, /// 0x1020 + 0x07, 0xfd, 0x70, 0xbd, 0x84, 0x75, 0x70, 0xbd, 0x30, 0x4a, 0x20, 0x32, + 0x11, 0x79, 0xfd, 0x25, /// 0x1030 + 0x29, 0x40, 0x11, 0x71, 0x2e, 0x49, 0x8d, 0x7a, 0x1f, 0x2d, 0x01, 0xd9, + 0x1f, 0x25, 0x8d, 0x72, /// 0x1040 + 0x15, 0x88, 0x89, 0x7a, 0x6d, 0x09, 0x6d, 0x01, 0x0d, 0x43, 0x15, 0x80, + 0x01, 0x21, 0x19, 0x80, /// 0x1050 + 0x04, 0x72, 0x28, 0x48, 0x01, 0x8a, 0x0c, 0x22, 0x91, 0x43, 0x01, 0x82, + 0x70, 0xbd, 0x20, 0x48, /// 0x1060 + 0x60, 0x38, 0x01, 0x68, 0x49, 0x1c, 0x01, 0x60, 0x23, 0x49, 0x07, 0x20, + 0x08, 0x72, 0x70, 0x47, /// 0x1070 + 0x10, 0xb5, 0x21, 0x4c, 0x20, 0x7a, 0x80, 0x07, 0x02, 0xd5, 0x20, 0x48, + 0xff, 0xf7, 0x07, 0xf8, /// 0x1080 + 0x07, 0x20, 0x20, 0x72, 0x10, 0xbd, 0x10, 0xb5, 0x1d, 0x49, 0x8b, 0x89, + 0x14, 0x48, 0x16, 0x4c, /// 0x1090 + 0xa0, 0x30, 0x02, 0x7a, 0x52, 0x00, 0x12, 0x19, 0xff, 0x32, 0xc1, 0x32, + 0x13, 0x85, 0x02, 0x7a, /// 0x10a0 + 0x52, 0x1c, 0x12, 0x07, 0x12, 0x0f, 0x02, 0x72, 0x0f, 0x20, 0x08, 0x83, + 0x10, 0xbd, 0x15, 0x49, /// 0x10b0 + 0x0f, 0x20, 0x08, 0x83, 0x70, 0x47, 0x10, 0xb5, 0x13, 0x48, 0x01, 0x78, + 0x49, 0x06, 0x04, 0xd5, /// 0x10c0 + 0x41, 0x21, 0x01, 0x70, 0x11, 0x48, 0xfe, 0xf7, 0xe2, 0xff, 0x11, 0x48, + 0x01, 0x79, 0xc9, 0x07, /// 0x10d0 + 0x01, 0xd0, 0x10, 0x21, 0x01, 0x71, 0x10, 0xbd, 0x00, 0x01, 0x00, 0x20, + 0x00, 0x60, 0x00, 0x40, /// 0x10e0 + 0x90, 0x02, 0x00, 0x20, 0x00, 0x64, 0x00, 0x40, 0x30, 0x01, 0x00, 0x20, + 0x00, 0x38, 0x00, 0x40, /// 0x10f0 + 0xa0, 0x00, 0x00, 0x20, 0x00, 0x34, 0x00, 0x40, 0x00, 0x54, 0x00, 0x40, + 0xbd, 0x02, 0x00, 0x00, /// 0x1100 + 0x00, 0x4c, 0x00, 0x40, 0x00, 0x50, 0x00, 0x40, 0x00, 0x3c, 0x00, 0x40, + 0x09, 0x08, 0x00, 0x00, /// 0x1110 + 0x40, 0x30, 0x00, 0x40, 0x00, 0x21, 0x41, 0x61, 0x81, 0x61, 0xbb, 0x4a, + 0x02, 0x60, 0xc1, 0x61, /// 0x1120 + 0xba, 0x4a, 0x42, 0x60, 0xb8, 0x4a, 0xd2, 0x43, 0x82, 0x60, 0xb8, 0x4a, + 0xd2, 0x43, 0xc2, 0x60, /// 0x1130 + 0xb7, 0x4a, 0x01, 0x66, 0x02, 0x61, 0x41, 0x66, 0x70, 0x47, 0xf0, 0xb5, + 0xb5, 0x4b, 0x84, 0x46, /// 0x1140 + 0x0f, 0xcb, 0xd9, 0xb0, 0x6c, 0x46, 0x0f, 0xc4, 0x00, 0x23, 0x09, 0xa8, + 0x9a, 0x00, 0x61, 0x46, /// 0x1150 + 0x54, 0x18, 0x20, 0x34, 0x21, 0x78, 0x5b, 0x1c, 0x09, 0x06, 0x81, 0x50, + 0x65, 0x78, 0x2d, 0x04, /// 0x1160 + 0x29, 0x43, 0x81, 0x50, 0xa5, 0x78, 0x2d, 0x02, 0x29, 0x43, 0x81, 0x50, + 0xe4, 0x78, 0x21, 0x43, /// 0x1170 + 0x81, 0x50, 0x10, 0x2b, 0xea, 0xdb, 0x10, 0x21, 0x8c, 0x00, 0x22, 0x18, + 0x80, 0x3a, 0x15, 0x6e, /// 0x1180 + 0x53, 0x6f, 0x6b, 0x40, 0x95, 0x6c, 0x12, 0x6c, 0x55, 0x40, 0x6b, 0x40, + 0x1f, 0x22, 0xd3, 0x41, /// 0x1190 + 0x49, 0x1c, 0x03, 0x51, 0x50, 0x29, 0xef, 0xdb, 0x61, 0x46, 0x0a, 0x68, + 0x08, 0x92, 0x49, 0x68, /// 0x11a0 + 0x63, 0x46, 0x07, 0x91, 0x9b, 0x68, 0x64, 0x46, 0x06, 0x93, 0xe4, 0x68, + 0x65, 0x46, 0x05, 0x94, /// 0x11b0 + 0x2d, 0x69, 0x00, 0x26, 0xb6, 0x46, 0x04, 0x95, 0x70, 0x46, 0x86, 0x00, + 0x09, 0xa8, 0x87, 0x59, /// 0x11c0 + 0x1b, 0x20, 0x16, 0x46, 0xc6, 0x41, 0xb8, 0x19, 0x0e, 0x46, 0x27, 0x46, + 0x1e, 0x40, 0x8f, 0x43, /// 0x11d0 + 0x3e, 0x43, 0x75, 0x19, 0x45, 0x19, 0x00, 0x98, 0x28, 0x18, 0x25, 0x46, + 0x1c, 0x46, 0x0b, 0x46, /// 0x11e0 + 0x02, 0x21, 0xcb, 0x41, 0x11, 0x46, 0x02, 0x46, 0x70, 0x46, 0x40, 0x1c, + 0x86, 0x46, 0x14, 0x28, /// 0x11f0 + 0xe2, 0xdb, 0x14, 0x20, 0x86, 0x46, 0x86, 0x00, 0x09, 0xa8, 0x87, 0x59, + 0x1b, 0x20, 0x16, 0x46, /// 0x1200 + 0xc6, 0x41, 0xb8, 0x19, 0x0e, 0x46, 0x5e, 0x40, 0x66, 0x40, 0x75, 0x19, + 0x45, 0x19, 0x01, 0x98, /// 0x1210 + 0x28, 0x18, 0x25, 0x46, 0x1c, 0x46, 0x0b, 0x46, 0x02, 0x21, 0xcb, 0x41, + 0x11, 0x46, 0x02, 0x46, /// 0x1220 + 0x70, 0x46, 0x40, 0x1c, 0x86, 0x46, 0x28, 0x28, 0xe5, 0xdb, 0x28, 0x20, + 0x86, 0x46, 0x86, 0x00, /// 0x1230 + 0x09, 0xa8, 0x87, 0x59, 0x1b, 0x20, 0x16, 0x46, 0xc6, 0x41, 0xbf, 0x19, + 0x1e, 0x46, 0x26, 0x43, /// 0x1240 + 0x18, 0x46, 0x0e, 0x40, 0x20, 0x40, 0x06, 0x43, 0x70, 0x19, 0x3d, 0x18, + 0x02, 0x98, 0x28, 0x18, /// 0x1250 + 0x25, 0x46, 0x1c, 0x46, 0x02, 0x23, 0xd9, 0x41, 0x0b, 0x46, 0x11, 0x46, + 0x02, 0x46, 0x70, 0x46, /// 0x1260 + 0x40, 0x1c, 0x86, 0x46, 0x3c, 0x28, 0xe2, 0xdb, 0x3c, 0x20, 0x86, 0x46, + 0x86, 0x00, 0x09, 0xa8, /// 0x1270 + 0x87, 0x59, 0x1b, 0x20, 0x16, 0x46, 0xc6, 0x41, 0xb8, 0x19, 0x0e, 0x46, + 0x5e, 0x40, 0x66, 0x40, /// 0x1280 + 0x75, 0x19, 0x45, 0x19, 0x03, 0x98, 0x28, 0x18, 0x25, 0x46, 0x1c, 0x46, + 0x02, 0x23, 0xd9, 0x41, /// 0x1290 + 0x0b, 0x46, 0x11, 0x46, 0x02, 0x46, 0x70, 0x46, 0x40, 0x1c, 0x86, 0x46, + 0x50, 0x28, 0xe5, 0xdb, /// 0x12a0 + 0x08, 0x98, 0x82, 0x18, 0x60, 0x46, 0x02, 0x60, 0x07, 0x98, 0x41, 0x18, + 0x60, 0x46, 0x41, 0x60, /// 0x12b0 + 0x06, 0x98, 0xc1, 0x18, 0x60, 0x46, 0x81, 0x60, 0x05, 0x98, 0x01, 0x19, + 0x60, 0x46, 0xc1, 0x60, /// 0x12c0 + 0x04, 0x98, 0x41, 0x19, 0x60, 0x46, 0x01, 0x61, 0x00, 0x21, 0xc1, 0x61, + 0x59, 0xb0, 0xf0, 0xbd, /// 0x12d0 + 0x70, 0xb5, 0x04, 0x46, 0xc0, 0x69, 0x25, 0x46, 0x41, 0x1c, 0x80, 0x22, + 0x20, 0x35, 0x00, 0x26, /// 0x12e0 + 0xe1, 0x61, 0x37, 0x28, 0x42, 0x55, 0x03, 0xdc, 0x13, 0xe0, 0x41, 0x1c, + 0xe1, 0x61, 0x46, 0x55, /// 0x12f0 + 0xe0, 0x69, 0x40, 0x28, 0xf9, 0xdb, 0x20, 0x46, 0xff, 0xf7, 0x1f, 0xff, + 0x02, 0xe0, 0x41, 0x1c, /// 0x1300 + 0xe1, 0x61, 0x46, 0x55, 0xe0, 0x69, 0x38, 0x28, 0xf9, 0xdb, 0x05, 0xe0, + 0x41, 0x1c, 0xe1, 0x61, /// 0x1310 + 0x46, 0x55, 0xe0, 0x69, 0x38, 0x28, 0xf9, 0xdb, 0xa1, 0x69, 0x20, 0x46, + 0x0a, 0x0e, 0x40, 0x30, /// 0x1320 + 0x02, 0x76, 0x0a, 0x0c, 0x42, 0x76, 0x0a, 0x0a, 0x82, 0x76, 0xc1, 0x76, + 0x61, 0x69, 0x0a, 0x0e, /// 0x1330 + 0x02, 0x77, 0x0a, 0x0c, 0x42, 0x77, 0x0a, 0x0a, 0x82, 0x77, 0xc1, 0x77, + 0x20, 0x46, 0xff, 0xf7, /// 0x1340 + 0xfc, 0xfe, 0x70, 0xbd, 0x30, 0xb5, 0x0d, 0x46, 0x04, 0x00, 0x08, 0xd0, + 0x00, 0x2d, 0x06, 0xd0, /// 0x1350 + 0x60, 0x6e, 0x00, 0x28, 0x04, 0xd1, 0x20, 0x6e, 0x00, 0x28, 0x02, 0xd0, + 0x10, 0xe0, 0x01, 0x20, /// 0x1360 + 0x30, 0xbd, 0x20, 0x46, 0xff, 0xf7, 0xb4, 0xff, 0x00, 0x20, 0x01, 0x46, + 0x22, 0x18, 0x20, 0x32, /// 0x1370 + 0x40, 0x1c, 0x11, 0x70, 0x40, 0x28, 0xf9, 0xdb, 0x61, 0x61, 0x01, 0x20, + 0xa1, 0x61, 0x20, 0x66, /// 0x1380 + 0x00, 0x20, 0x03, 0x22, 0x81, 0x08, 0x83, 0x07, 0x89, 0x00, 0x9b, 0x0f, + 0x61, 0x58, 0xd3, 0x1a, /// 0x1390 + 0xdb, 0x00, 0xd9, 0x40, 0x29, 0x54, 0x40, 0x1c, 0x14, 0x28, 0xf3, 0xdb, + 0x00, 0x20, 0x30, 0xbd, /// 0x13a0 + 0xf0, 0xb5, 0x15, 0x00, 0x0e, 0x46, 0x04, 0x46, 0x15, 0xd0, 0x00, 0x2c, + 0x07, 0xd0, 0x00, 0x2e, /// 0x13b0 + 0x05, 0xd0, 0x20, 0x6e, 0x00, 0x28, 0x04, 0xd0, 0x03, 0x20, 0x60, 0x66, + 0xf0, 0xbd, 0x01, 0x20, /// 0x13c0 + 0xf0, 0xbd, 0x60, 0x6e, 0x00, 0x28, 0xfb, 0xd1, 0x27, 0x46, 0x20, 0x37, + 0x6d, 0x1e, 0x02, 0xd3, /// 0x13d0 + 0x60, 0x6e, 0x00, 0x28, 0x01, 0xd0, 0x00, 0x20, 0xf0, 0xbd, 0xe0, 0x69, + 0x31, 0x78, 0x42, 0x1c, /// 0x13e0 + 0xe2, 0x61, 0xc1, 0x55, 0x60, 0x69, 0x08, 0x30, 0x60, 0x61, 0x05, 0xd1, + 0xa0, 0x69, 0x40, 0x1c, /// 0x13f0 + 0xa0, 0x61, 0x01, 0xd1, 0x01, 0x20, 0x60, 0x66, 0xe0, 0x69, 0x40, 0x28, + 0x02, 0xd1, 0x20, 0x46, /// 0x1400 + 0xff, 0xf7, 0x9b, 0xfe, 0x76, 0x1c, 0xe1, 0xe7, 0x01, 0x23, 0x45, 0x67, + 0x89, 0xab, 0xcd, 0xef, /// 0x1410 + 0xf0, 0xe1, 0xd2, 0xc3, 0x14, 0x15, 0x00, 0x00, 0x10, 0xb5, 0x06, 0x49, + 0x0c, 0x22, 0x0a, 0x73, /// 0x1420 + 0x19, 0x22, 0x4a, 0x73, 0x88, 0x73, 0x10, 0x20, 0x80, 0x31, 0xc8, 0x77, + 0x01, 0x20, 0xff, 0xf7, /// 0x1430 + 0x58, 0xfb, 0x10, 0xbd, 0xd0, 0x02, 0x00, 0x20, 0x10, 0xb5, 0x09, 0x48, + 0x07, 0x49, 0x41, 0x60, /// 0x1440 + 0x08, 0x49, 0x81, 0x67, 0x08, 0x22, 0x08, 0x49, 0x7c, 0x30, 0xff, 0xf7, + 0x82, 0xfa, 0x04, 0x48, /// 0x1450 + 0x08, 0x22, 0x05, 0x49, 0x84, 0x30, 0xff, 0xf7, 0x7c, 0xfa, 0x10, 0xbd, + 0xa5, 0x18, 0x00, 0x00, /// 0x1460 + 0x30, 0x02, 0x00, 0x20, 0x3d, 0x15, 0x00, 0x00, 0x64, 0x1b, 0x00, 0x00, + 0x30, 0xb5, 0x0b, 0x46, /// 0x1470 + 0x01, 0x46, 0x00, 0x20, 0x20, 0x22, 0x01, 0x24, 0x09, 0xe0, 0x0d, 0x46, + 0xd5, 0x40, 0x9d, 0x42, /// 0x1480 + 0x05, 0xd3, 0x1d, 0x46, 0x95, 0x40, 0x49, 0x1b, 0x25, 0x46, 0x95, 0x40, + 0x40, 0x19, 0x15, 0x46, /// 0x1490 + 0x52, 0x1e, 0x00, 0x2d, 0xf1, 0xdc, 0x30, 0xbd, 0x70, 0xb5, 0x00, 0x24, + 0x25, 0x46, 0x00, 0x28, /// 0x14a0 + 0x01, 0xda, 0x01, 0x24, 0x40, 0x42, 0x00, 0x29, 0x01, 0xda, 0x01, 0x25, + 0x49, 0x42, 0xff, 0xf7, /// 0x14b0 + 0xdd, 0xff, 0xac, 0x42, 0x00, 0xd0, 0x40, 0x42, 0x00, 0x2c, 0x00, 0xd0, + 0x49, 0x42, 0x70, 0xbd, /// 0x14c0 + 0x30, 0xb4, 0x74, 0x46, 0x64, 0x1e, 0x25, 0x78, 0x64, 0x1c, 0xab, 0x42, + 0x00, 0xd2, 0x1d, 0x46, /// 0x14d0 + 0x63, 0x5d, 0x5b, 0x00, 0xe3, 0x18, 0x30, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x07, 0x07, 0x07, 0x07, /// 0x14e0 + 0x07, 0x07, 0x07, 0x07, 0xc9, 0x0e, 0x00, 0x00, 0x5f, 0x10, 0x00, 0x00, + 0x87, 0x10, 0x00, 0x00, /// 0x14f0 + 0xaf, 0x10, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x35, 0x0f, 0x00, 0x00, + 0xf7, 0x0f, 0x00, 0x00, /// 0x1500 + 0x79, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, + 0x79, 0x00, 0x00, 0x00, /// 0x1510 + 0xb7, 0x10, 0x00, 0x00, 0x99, 0x79, 0x82, 0x5a, 0xa1, 0xeb, 0xd9, 0x6e, + 0xdc, 0xbc, 0x1b, 0x8f, /// 0x1520 + 0xd6, 0xc1, 0x62, 0xca, 0xfe, 0x48, 0x32, 0x21, 0x41, 0x66, 0x01, 0x46, + 0x08, 0x22, 0x40, 0x39, /// 0x1530 + 0x8a, 0x72, 0x40, 0x39, 0x09, 0x68, 0x32, 0x39, 0x81, 0x65, 0x70, 0x47, + 0xf8, 0xb5, 0xff, 0xf7, /// 0x1540 + 0x45, 0xfa, 0xf8, 0x4e, 0xf4, 0x89, 0x00, 0x2c, 0x6b, 0xd0, 0x00, 0x27, + 0x35, 0x46, 0xe0, 0x05, /// 0x1550 + 0x40, 0x35, 0xf7, 0x81, 0x00, 0x28, 0x0f, 0xda, 0xff, 0xf7, 0x2c, 0xfb, + 0x02, 0x20, 0xf2, 0x4a, /// 0x1560 + 0x28, 0x70, 0x5a, 0x21, 0x11, 0x70, 0xf0, 0x48, 0x10, 0x23, 0x40, 0x30, + 0x03, 0x70, 0x11, 0x70, /// 0x1570 + 0x07, 0x72, 0x80, 0x21, 0x01, 0x70, 0x54, 0xe0, 0xec, 0x48, 0x21, 0x04, + 0x04, 0xd5, 0x01, 0x8d, /// 0x1580 + 0x01, 0x22, 0x52, 0x02, 0x11, 0x43, 0x01, 0x85, 0xe1, 0x06, 0x04, 0xd5, + 0x01, 0x8d, 0xff, 0x22, /// 0x1590 + 0x01, 0x32, 0x11, 0x43, 0x01, 0x85, 0xe1, 0x07, 0x08, 0x22, 0x00, 0x29, + 0x02, 0xd0, 0x69, 0x78, /// 0x15a0 + 0x11, 0x43, 0x69, 0x70, 0xa1, 0x05, 0x15, 0xd5, 0xde, 0x49, 0x20, 0x39, + 0x8b, 0x79, 0x1b, 0x06, /// 0x15b0 + 0x06, 0xd5, 0x8f, 0x71, 0xcf, 0x71, 0x01, 0x8d, 0x01, 0x22, 0x11, 0x43, + 0x01, 0x85, 0x09, 0xe0, /// 0x15c0 + 0xda, 0x48, 0x0b, 0x7b, 0x00, 0x8d, 0x00, 0x2b, 0x0e, 0xd0, 0x20, 0x23, + 0x18, 0x43, 0xd7, 0x4b, /// 0x15d0 + 0x18, 0x85, 0xca, 0x71, 0xa0, 0x06, 0x01, 0xd5, 0xff, 0xf7, 0xe5, 0xf9, + 0x60, 0x06, 0x0b, 0xd5, /// 0x15e0 + 0x30, 0x7b, 0x5a, 0x28, 0x02, 0xd0, 0x07, 0xe0, 0x10, 0x23, 0xef, 0xe7, + 0x70, 0x7b, 0x40, 0x21, /// 0x15f0 + 0x08, 0x43, 0x70, 0x73, 0xce, 0x48, 0x80, 0x47, 0x20, 0x07, 0x01, 0xd5, + 0xff, 0xf7, 0x92, 0xff, /// 0x1600 + 0xa0, 0x07, 0x01, 0xd5, 0x00, 0xf0, 0xb0, 0xfd, 0x20, 0x06, 0x03, 0xd5, + 0xa8, 0x78, 0x01, 0x21, /// 0x1610 + 0x08, 0x43, 0xa8, 0x70, 0x60, 0x07, 0x03, 0xd5, 0xa8, 0x78, 0x20, 0x21, + 0x08, 0x43, 0xa8, 0x70, /// 0x1620 + 0x37, 0x73, 0x00, 0x20, 0xf8, 0xbd, 0xbe, 0x48, 0x10, 0xb5, 0x80, 0x38, + 0x01, 0x68, 0x80, 0x30, /// 0x1630 + 0x82, 0x6d, 0x43, 0x6e, 0x8a, 0x1a, 0x9a, 0x42, 0x0c, 0xdb, 0x81, 0x65, + 0x83, 0x21, 0x89, 0x00, /// 0x1640 + 0x81, 0x85, 0xb8, 0x48, 0x20, 0x38, 0xc1, 0x7e, 0xb5, 0x48, 0x20, 0x30, + 0x81, 0x73, 0x01, 0x20, /// 0x1650 + 0xff, 0xf7, 0x47, 0xfa, 0x10, 0xbd, 0xb3, 0x48, 0x10, 0xb5, 0x10, 0x22, + 0xb5, 0x49, 0x50, 0x30, /// 0x1660 + 0xff, 0xf7, 0x77, 0xf9, 0xaf, 0x48, 0x10, 0x22, 0xb3, 0x49, 0x28, 0x30, + 0xff, 0xf7, 0x71, 0xf9, /// 0x1670 + 0xac, 0x48, 0x19, 0x21, 0x20, 0x38, 0x02, 0x46, 0x81, 0x77, 0x40, 0x32, + 0xd1, 0x70, 0x00, 0x21, /// 0x1680 + 0xc1, 0x77, 0xa9, 0x49, 0x80, 0x20, 0x08, 0x82, 0x10, 0xbd, 0x10, 0xb5, + 0xff, 0xf7, 0xe3, 0xff, /// 0x1690 + 0xa4, 0x49, 0xf7, 0x22, 0x48, 0x7b, 0x10, 0x40, 0x48, 0x73, 0x08, 0x46, + 0xa7, 0x4a, 0x40, 0x30, /// 0x16a0 + 0xc2, 0x60, 0x82, 0x60, 0x9e, 0x48, 0xa6, 0x4a, 0x80, 0x30, 0x42, 0x81, + 0xff, 0x38, 0x01, 0x38, /// 0x16b0 + 0x02, 0x68, 0x80, 0x30, 0x02, 0x66, 0xc2, 0x65, 0x43, 0x6e, 0xd2, 0x1a, + 0x82, 0x65, 0x0f, 0x20, /// 0x16c0 + 0x88, 0x72, 0x98, 0x48, 0x03, 0x21, 0x20, 0x30, 0x81, 0x70, 0x95, 0x48, + 0x05, 0x21, 0x40, 0x38, /// 0x16d0 + 0x81, 0x72, 0x10, 0xbd, 0x70, 0xb5, 0x9b, 0x48, 0x01, 0x88, 0x07, 0x22, + 0x12, 0x02, 0x91, 0x43, /// 0x16e0 + 0x01, 0x80, 0x90, 0x48, 0x08, 0x22, 0x41, 0x7b, 0x04, 0x46, 0x11, 0x43, + 0x41, 0x73, 0x0f, 0x21, /// 0x16f0 + 0x81, 0x72, 0x90, 0x49, 0x00, 0x25, 0x20, 0x34, 0xa5, 0x70, 0x10, 0x22, + 0x10, 0x31, 0x50, 0x30, /// 0x1700 + 0xff, 0xf7, 0x27, 0xf9, 0x8c, 0x49, 0x20, 0x46, 0x10, 0x22, 0x10, 0x31, + 0x08, 0x30, 0xff, 0xf7, /// 0x1710 + 0x20, 0xf9, 0x20, 0x46, 0x8c, 0x49, 0x20, 0x30, 0x01, 0x82, 0xff, 0x21, + 0x82, 0x4a, 0x71, 0x31, /// 0x1720 + 0x11, 0x82, 0x01, 0x46, 0x55, 0x22, 0x60, 0x39, 0x8a, 0x77, 0xe2, 0x70, + 0xcd, 0x77, 0x87, 0x49, /// 0x1730 + 0xc1, 0x60, 0x82, 0x49, 0x81, 0x60, 0x7a, 0x48, 0x80, 0x30, 0x81, 0x66, + 0x04, 0x21, 0xc0, 0x38, /// 0x1740 + 0x81, 0x72, 0x70, 0xbd, 0x10, 0xb5, 0x76, 0x48, 0x81, 0x49, 0xc1, 0x62, + 0x41, 0x21, 0x49, 0x02, /// 0x1750 + 0x01, 0x86, 0x80, 0x21, 0x20, 0x30, 0x81, 0x74, 0x05, 0x20, 0xff, 0xf7, + 0xc2, 0xf9, 0x10, 0xbd, /// 0x1760 + 0x10, 0xb5, 0x6f, 0x48, 0x7b, 0x49, 0xc1, 0x62, 0x6e, 0x21, 0x01, 0x86, + 0x7a, 0x49, 0x20, 0x30, /// 0x1770 + 0xca, 0x7b, 0x82, 0x74, 0x0a, 0x7c, 0xc2, 0x74, 0x49, 0x7c, 0x01, 0x75, + 0x07, 0x20, 0xff, 0xf7, /// 0x1780 + 0xb0, 0xf9, 0x10, 0xbd, 0x10, 0xb5, 0x67, 0x49, 0x08, 0x88, 0xc0, 0x08, + 0xff, 0x28, 0x00, 0xd9, /// 0x1790 + 0xff, 0x20, 0xc8, 0x72, 0xff, 0x22, 0x62, 0x49, 0x0d, 0x32, 0x8a, 0x85, + 0x20, 0x31, 0x88, 0x73, /// 0x17a0 + 0x01, 0x20, 0xff, 0xf7, 0x9e, 0xf9, 0x10, 0xbd, 0xf8, 0xb5, 0x5e, 0x4d, + 0x5f, 0x4c, 0x40, 0x35, /// 0x17b0 + 0x68, 0x78, 0x26, 0x46, 0x27, 0x46, 0xc1, 0x06, 0x40, 0x36, 0xc0, 0x37, + 0x00, 0x29, 0x0a, 0xda, /// 0x17c0 + 0xef, 0x21, 0x08, 0x40, 0x68, 0x70, 0xa1, 0x8e, 0x01, 0x20, 0xc0, 0x02, + 0x01, 0x43, 0xa1, 0x86, /// 0x17d0 + 0xfe, 0xf7, 0xdf, 0xff, 0x10, 0xe0, 0x39, 0x79, 0x0a, 0x07, 0x06, 0xd5, + 0x32, 0x7e, 0x1e, 0x2a, /// 0x17e0 + 0x03, 0xd0, 0x20, 0x21, 0x08, 0x43, 0x68, 0x70, 0x06, 0xe0, 0x48, 0x06, + 0x04, 0xd5, 0xbf, 0x20, /// 0x17f0 + 0x01, 0x40, 0x80, 0x20, 0x01, 0x43, 0x39, 0x71, 0x38, 0x79, 0x81, 0x07, + 0x02, 0xd5, 0x31, 0x7e, /// 0x1800 + 0x3f, 0x29, 0x16, 0xd0, 0x69, 0x78, 0x49, 0x06, 0x02, 0xd5, 0x31, 0x7e, + 0x4f, 0x29, 0x13, 0xd0, /// 0x1810 + 0x00, 0x07, 0x09, 0xd5, 0x30, 0x7e, 0x1e, 0x28, 0x06, 0xd0, 0xa0, 0x8e, + 0x10, 0x21, 0x08, 0x43, /// 0x1820 + 0xa0, 0x86, 0x08, 0x46, 0xfe, 0xf7, 0xb5, 0xff, 0xa8, 0x78, 0xbf, 0x21, + 0x08, 0x40, 0xa8, 0x70, /// 0x1830 + 0xf8, 0xbd, 0x01, 0xf0, 0x52, 0xfc, 0xf7, 0xe7, 0x3a, 0x48, 0x19, 0x30, + 0x01, 0xf0, 0x28, 0xfc, /// 0x1840 + 0xf2, 0xe7, 0x10, 0xb5, 0x45, 0x49, 0x0d, 0x20, 0x08, 0x72, 0xff, 0xf7, + 0x2f, 0xf8, 0x37, 0x48, /// 0x1850 + 0x00, 0x21, 0x01, 0x81, 0x33, 0x49, 0x42, 0x4a, 0x49, 0x7b, 0x82, 0x81, + 0x0b, 0x07, 0x7d, 0x21, /// 0x1860 + 0x01, 0x82, 0x96, 0x21, 0xc1, 0x81, 0x2a, 0x21, 0xc1, 0x74, 0x81, 0x7c, + 0x20, 0x22, 0x11, 0x43, /// 0x1870 + 0x81, 0x74, 0x10, 0xbd, 0x10, 0xb5, 0x39, 0x48, 0x00, 0x7e, 0x80, 0x07, + 0x11, 0xd5, 0x01, 0x20, /// 0x1880 + 0x80, 0x03, 0xfe, 0xf7, 0x86, 0xff, 0xff, 0xf7, 0x95, 0xf9, 0x26, 0x48, + 0x02, 0x21, 0x40, 0x30, /// 0x1890 + 0x01, 0x70, 0x25, 0x49, 0x5a, 0x20, 0x08, 0x70, 0x23, 0x49, 0x80, 0x20, + 0x40, 0x31, 0x08, 0x70, /// 0x18a0 + 0xfe, 0xe7, 0x10, 0xbd, 0xfe, 0xb5, 0xff, 0xf7, 0xe5, 0xff, 0x2e, 0x48, + 0x01, 0x90, 0x00, 0x7d, /// 0x18b0 + 0x00, 0x28, 0x12, 0xd0, 0x40, 0x1e, 0x00, 0x06, 0x01, 0x99, 0x00, 0x0e, + 0x08, 0x75, 0x0c, 0xd1, /// 0x18c0 + 0x26, 0x48, 0x20, 0x30, 0x01, 0x78, 0x20, 0x22, 0x11, 0x43, 0x01, 0x70, + 0x17, 0x48, 0x10, 0x22, /// 0x18d0 + 0x81, 0x7c, 0x11, 0x43, 0x81, 0x74, 0xff, 0xf7, 0xb4, 0xff, 0x12, 0x4e, + 0x40, 0x36, 0xb0, 0x78, /// 0x18e0 + 0x40, 0x06, 0x01, 0xd5, 0xff, 0xf7, 0x60, 0xff, 0x0e, 0x48, 0x20, 0x38, + 0x81, 0x7f, 0x40, 0x30, /// 0x18f0 + 0x4b, 0x29, 0x01, 0xd9, 0x01, 0x21, 0x04, 0xe0, 0x23, 0x29, 0x01, 0xd9, + 0x00, 0x21, 0x00, 0xe0, /// 0x1900 + 0x03, 0x21, 0x81, 0x70, 0x17, 0x48, 0x06, 0x4d, 0x40, 0x38, 0x00, 0x90, + 0x40, 0x78, 0x40, 0x35, /// 0x1910 + 0x00, 0x28, 0x2d, 0xd1, 0x28, 0x7a, 0x00, 0x28, 0x2a, 0xd1, 0x28, 0x46, + 0x3c, 0x38, 0x23, 0xe0, /// 0x1920 + 0xb0, 0x02, 0x00, 0x20, 0x40, 0x00, 0x00, 0x20, 0x00, 0x30, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x20, /// 0x1930 + 0x11, 0x06, 0x00, 0x20, 0x6c, 0x1b, 0x00, 0x00, 0x44, 0x31, 0x00, 0x00, + 0x04, 0x0a, 0x0a, 0x00, /// 0x1940 + 0xdc, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x40, 0x85, 0x09, 0x00, 0x00, + 0x31, 0x14, 0x14, 0x00, /// 0x1950 + 0x0c, 0x51, 0x0a, 0x00, 0x0c, 0x71, 0x12, 0x00, 0x20, 0x47, 0x00, 0x00, + 0x20, 0x6c, 0x00, 0x40, /// 0x1960 + 0x88, 0x13, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x20, 0xfe, 0xf7, 0x84, 0xfd, + 0xfe, 0xf7, 0x47, 0xfe, /// 0x1970 + 0x72, 0x78, 0x73, 0x4f, 0xd0, 0x06, 0x00, 0x28, 0x11, 0xda, 0xbb, 0x89, + 0x39, 0x46, 0x58, 0x1c, /// 0x1980 + 0xb8, 0x81, 0xc0, 0x39, 0x48, 0x8c, 0x83, 0x42, 0x09, 0xd9, 0xef, 0x20, + 0x02, 0x40, 0x72, 0x70, /// 0x1990 + 0x8a, 0x8e, 0x01, 0x20, 0x80, 0x02, 0x02, 0x43, 0x8a, 0x86, 0xfe, 0xf7, + 0xfa, 0xfe, 0x30, 0x78, /// 0x19a0 + 0xc0, 0x06, 0x23, 0xd5, 0x66, 0x48, 0xc0, 0x38, 0x81, 0x7c, 0x02, 0x91, + 0x89, 0x06, 0x1b, 0xd5, /// 0x19b0 + 0x40, 0x89, 0x64, 0x49, 0x48, 0x43, 0x64, 0x49, 0xff, 0xf7, 0x58, 0xfd, + 0x60, 0x4c, 0x12, 0x30, /// 0x19c0 + 0x80, 0x3c, 0xe1, 0x78, 0x06, 0x29, 0x15, 0xd0, 0x22, 0x46, 0x40, 0x3a, + 0x13, 0x6b, 0x18, 0x18, /// 0x19d0 + 0x49, 0x1c, 0x10, 0x63, 0xe1, 0x70, 0x5a, 0x48, 0xc0, 0x38, 0x01, 0x8a, + 0xc0, 0x89, 0xfe, 0xf7, /// 0x19e0 + 0x78, 0xff, 0x30, 0x78, 0xc0, 0x06, 0x01, 0xd5, 0x01, 0xf0, 0xe9, 0xfa, + 0x28, 0x7a, 0x00, 0x28, /// 0x19f0 + 0x42, 0xd1, 0x1c, 0xe0, 0x52, 0x49, 0xc0, 0x39, 0x09, 0x6b, 0x08, 0x18, + 0x07, 0x21, 0xff, 0xf7, /// 0x1a00 + 0x35, 0xfd, 0x4f, 0x49, 0x80, 0xb2, 0xc0, 0x39, 0x08, 0x81, 0x4d, 0x4a, + 0x00, 0x21, 0xe1, 0x70, /// 0x1a10 + 0xc0, 0x3a, 0x11, 0x63, 0x02, 0x99, 0xc9, 0x07, 0xdd, 0xd1, 0x91, 0x89, + 0x43, 0x1a, 0x00, 0xd5, /// 0x1a20 + 0x5b, 0x42, 0xd2, 0x7c, 0x93, 0x42, 0xd6, 0xdd, 0xfe, 0xf7, 0x60, 0xff, + 0xd3, 0xe7, 0x47, 0x48, /// 0x1a30 + 0xe9, 0x7a, 0x04, 0x46, 0xff, 0x34, 0x41, 0x34, 0x20, 0x46, 0xc0, 0x30, + 0x02, 0x90, 0x00, 0x29, /// 0x1a40 + 0x1b, 0xd0, 0x49, 0x1e, 0xe9, 0x72, 0xa0, 0x7a, 0x03, 0x28, 0x76, 0xd3, + 0x72, 0xb6, 0x40, 0x48, /// 0x1a50 + 0xfe, 0xf7, 0x1d, 0xfb, 0x62, 0xb6, 0x28, 0x7b, 0xe9, 0x7a, 0x40, 0x1e, + 0x81, 0x42, 0x6c, 0xd1, /// 0x1a60 + 0x02, 0x99, 0x00, 0x20, 0x08, 0x82, 0x88, 0x81, 0x68, 0x7b, 0x80, 0x06, + 0x65, 0xd4, 0x39, 0x48, /// 0x1a70 + 0x01, 0x88, 0x82, 0x14, 0x91, 0x43, 0x01, 0x80, 0x5f, 0xe0, 0x00, 0x20, + 0x68, 0x74, 0xa0, 0x7a, /// 0x1a80 + 0x03, 0x00, 0xff, 0xf7, 0x1d, 0xfd, 0x09, 0x06, 0x15, 0x1a, 0x26, 0x3f, + 0x42, 0x45, 0x55, 0x58, /// 0x1a90 + 0x5a, 0x00, 0x31, 0x48, 0x00, 0x68, 0x1d, 0x28, 0x4f, 0xd9, 0x08, 0x20, + 0x28, 0x73, 0x2e, 0x48, /// 0x1aa0 + 0x32, 0x21, 0x80, 0x30, 0x41, 0x66, 0x01, 0x20, 0xa0, 0x72, 0xff, 0xf7, + 0x6b, 0xfe, 0x44, 0xe0, /// 0x1ab0 + 0xff, 0xf7, 0x56, 0xfe, 0x02, 0x20, 0xa0, 0x72, 0x3f, 0xe0, 0x34, 0x20, + 0xf0, 0x70, 0x1e, 0x20, /// 0x1ac0 + 0x28, 0x73, 0xff, 0xf7, 0x3f, 0xfe, 0x03, 0x20, 0xa0, 0x72, 0x24, 0x49, + 0x01, 0x20, 0xc8, 0x77, /// 0x1ad0 + 0x33, 0xe0, 0x00, 0x98, 0x00, 0x78, 0xc0, 0x07, 0x02, 0xd0, 0xff, 0xf7, + 0xfb, 0xfd, 0x01, 0xe0, /// 0x1ae0 + 0xff, 0xf7, 0xd3, 0xfd, 0x16, 0x49, 0xff, 0x20, 0xf5, 0x30, 0xc0, 0x39, + 0x48, 0x84, 0x00, 0x20, /// 0x1af0 + 0xb0, 0x64, 0xff, 0x22, 0x78, 0x71, 0x60, 0x32, 0xfa, 0x81, 0x01, 0x9a, + 0x10, 0x75, 0x18, 0x48, /// 0x1b00 + 0x08, 0x87, 0x1a, 0xe0, 0x01, 0xf0, 0x62, 0xf9, 0x17, 0xe0, 0x00, 0xf0, + 0xcb, 0xff, 0x14, 0xe0, /// 0x1b10 + 0x00, 0x98, 0x00, 0x78, 0xc0, 0x07, 0x01, 0xd0, 0x07, 0x20, 0x00, 0xe0, + 0x05, 0x20, 0xa0, 0x72, /// 0x1b20 + 0x0e, 0x49, 0x00, 0x20, 0x40, 0x31, 0xc8, 0x71, 0x02, 0x98, 0xb1, 0x68, + 0x81, 0x66, 0x04, 0xe0, /// 0x1b30 + 0x00, 0xf0, 0x59, 0xfb, 0x01, 0xe0, 0xff, 0xf7, 0x76, 0xfd, 0x00, 0x20, + 0xfe, 0xbd, 0x00, 0x00, /// 0x1b40 + 0xc0, 0x00, 0x00, 0x20, 0x34, 0x08, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, + 0x30, 0x01, 0x00, 0x20, /// 0x1b50 + 0x5f, 0x1f, 0x00, 0x00, 0x20, 0x38, 0x00, 0x40, 0x30, 0x02, 0x00, 0x20, + 0x50, 0x03, 0x00, 0x20, /// 0x1b60 + 0xd8, 0xbf, 0x00, 0x00, 0x32, 0x31, 0x3f, 0x03, 0x32, 0x31, 0x3f, 0x14, + 0xf3, 0x04, 0x19, 0x0c, /// 0x1b70 + 0xea, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x08, 0x32, 0x04, /// 0x1b80 + 0x75, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x28, 0x01, 0xd2, /// 0x1b90 + 0x01, 0x20, 0x70, 0x47, 0x80, 0x28, 0x03, 0xd2, 0x20, 0x38, 0x00, 0x11, + 0x80, 0x1c, 0x70, 0x47, /// 0x1ba0 + 0xe0, 0x28, 0x03, 0xd2, 0x80, 0x38, 0xc0, 0x10, 0x08, 0x30, 0x70, 0x47, + 0xe0, 0x38, 0x80, 0x10, /// 0x1bb0 + 0x14, 0x30, 0x70, 0x47, 0x41, 0x07, 0x89, 0x0f, 0x03, 0x29, 0x0b, 0xd1, + 0x01, 0x07, 0x03, 0xd5, /// 0x1bc0 + 0x80, 0x09, 0x02, 0x28, 0x04, 0xd0, 0x05, 0xe0, 0x00, 0x09, 0x03, 0xd0, + 0x0c, 0x28, 0x01, 0xd8, /// 0x1bd0 + 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x1e, 0x28, 0x08, 0xd0, + 0xc1, 0x43, 0x09, 0x07, /// 0x1be0 + 0x07, 0xd1, 0x01, 0x09, 0x06, 0x29, 0x04, 0xd2, 0x00, 0x06, 0x00, 0x0f, + 0x01, 0xd0, 0x01, 0x20, /// 0x1bf0 + 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x10, 0xb5, 0xf9, 0x48, 0xf7, 0x22, + 0xc1, 0x79, 0x11, 0x40, /// 0x1c00 + 0xc1, 0x71, 0xf7, 0x49, 0x00, 0x20, 0x20, 0x39, 0x08, 0x85, 0x80, 0x20, + 0xfe, 0xf7, 0xc1, 0xfd, /// 0x1c10 + 0x10, 0xbd, 0xf8, 0xb5, 0xf3, 0x4a, 0x10, 0x7d, 0xff, 0xf7, 0xde, 0xff, + 0xf2, 0x49, 0x11, 0x24, /// 0x1c20 + 0x64, 0x01, 0x0f, 0x19, 0x85, 0x23, 0x09, 0x24, 0x9b, 0x00, 0xa4, 0x01, + 0xcb, 0x18, 0x0e, 0x19, /// 0x1c30 + 0x00, 0x28, 0x18, 0xd0, 0xf0, 0x79, 0x40, 0x1c, 0xc0, 0xb2, 0xf0, 0x71, + 0x06, 0x28, 0x01, 0xd9, /// 0x1c40 + 0x06, 0x20, 0xf0, 0x71, 0xc2, 0xb2, 0xe6, 0x48, 0x19, 0x46, 0x38, 0x30, + 0xfe, 0xf7, 0x88, 0xfe, /// 0x1c50 + 0xe3, 0x48, 0x40, 0x22, 0x60, 0x30, 0x81, 0x78, 0x11, 0x43, 0x81, 0x70, + 0xf8, 0x7f, 0xef, 0x21, /// 0x1c60 + 0x08, 0x40, 0xf8, 0x77, 0xf8, 0xbd, 0xde, 0x4c, 0x10, 0x7d, 0x20, 0x3c, + 0x25, 0x46, 0x20, 0x35, /// 0x1c70 + 0x15, 0x28, 0x17, 0xd0, 0xff, 0xf7, 0x9e, 0xff, 0x01, 0x1e, 0xdc, 0x48, + 0x57, 0xd0, 0x11, 0x7d, /// 0x1c80 + 0xea, 0x79, 0xc9, 0x07, 0xd2, 0x07, 0xc9, 0x0f, 0xd2, 0x0f, 0x91, 0x42, + 0x4a, 0xd1, 0xf1, 0x79, /// 0x1c90 + 0xeb, 0x7b, 0x8c, 0x46, 0xaa, 0x7b, 0x59, 0x18, 0x91, 0x42, 0x22, 0xd9, + 0xe9, 0x73, 0x20, 0x8d, /// 0x1ca0 + 0x02, 0x21, 0x41, 0xe0, 0x50, 0x7d, 0x01, 0x06, 0x14, 0xd5, 0xe9, 0x79, + 0x8a, 0x06, 0x92, 0x0f, /// 0x1cb0 + 0x02, 0xd0, 0x20, 0x8d, 0x04, 0x21, 0x37, 0xe0, 0x22, 0x8d, 0x08, 0x23, + 0x40, 0x06, 0x1a, 0x43, /// 0x1cc0 + 0x40, 0x0e, 0x22, 0x85, 0x40, 0x1c, 0xa8, 0x73, 0x00, 0x20, 0xe8, 0x73, + 0x48, 0x08, 0x40, 0x00, /// 0x1cd0 + 0xe8, 0x71, 0xf8, 0xbd, 0x03, 0x28, 0x01, 0xd1, 0xff, 0xf7, 0x8d, 0xff, + 0x20, 0x8d, 0x08, 0x21, /// 0x1ce0 + 0x22, 0xe0, 0xc0, 0x49, 0x18, 0x18, 0x62, 0x46, 0x15, 0x31, 0xfe, 0xf7, + 0x39, 0xfe, 0xe8, 0x7b, /// 0x1cf0 + 0xf1, 0x79, 0x01, 0x22, 0x40, 0x18, 0xc1, 0xb2, 0xe9, 0x73, 0xe8, 0x79, + 0x40, 0x23, 0x50, 0x40, /// 0x1d00 + 0xe8, 0x71, 0x22, 0x8d, 0x1a, 0x43, 0x22, 0x85, 0xb6, 0x4a, 0x32, 0x23, + 0x80, 0x3a, 0x53, 0x66, /// 0x1d10 + 0x05, 0x22, 0x3a, 0x77, 0xaa, 0x7b, 0x91, 0x42, 0xdb, 0xd1, 0x10, 0x21, + 0x08, 0x43, 0xe8, 0x71, /// 0x1d20 + 0x08, 0x46, 0x18, 0xe0, 0x20, 0x8d, 0x40, 0x21, 0x08, 0x43, 0x20, 0x85, + 0xf8, 0xbd, 0xe9, 0x79, /// 0x1d30 + 0x89, 0x06, 0x89, 0x0f, 0xbd, 0xd1, 0x21, 0x8d, 0x08, 0x22, 0x11, 0x43, + 0x21, 0x85, 0xf1, 0x79, /// 0x1d40 + 0x49, 0x1c, 0xca, 0xb2, 0xaa, 0x73, 0x19, 0x46, 0xfe, 0xf7, 0x0a, 0xfe, + 0xe8, 0x79, 0x20, 0x21, /// 0x1d50 + 0x08, 0x43, 0xe8, 0x71, 0x08, 0x46, 0xfe, 0xf7, 0x1c, 0xfd, 0xf8, 0xbd, + 0xf8, 0xb5, 0xa0, 0x4c, /// 0x1d60 + 0x61, 0x7b, 0x22, 0x7b, 0x26, 0x46, 0x20, 0x3e, 0xe0, 0x79, 0x91, 0x42, + 0x07, 0xd3, 0x32, 0x8d, /// 0x1d70 + 0x80, 0x21, 0x8a, 0x43, 0xf7, 0x21, 0x32, 0x85, 0x08, 0x40, 0xe0, 0x71, + 0xf8, 0xbd, 0x52, 0x1a, /// 0x1d80 + 0xd5, 0xb2, 0x08, 0x2d, 0x00, 0xd9, 0x08, 0x25, 0x2a, 0x07, 0x13, 0x0e, + 0x82, 0x07, 0x01, 0xd5, /// 0x1d90 + 0x07, 0x22, 0x00, 0xe0, 0x06, 0x22, 0x1a, 0x43, 0x02, 0x23, 0x58, 0x40, + 0xe0, 0x71, 0x91, 0x4f, /// 0x1da0 + 0x91, 0x48, 0x20, 0x37, 0x09, 0x18, 0x3a, 0x72, 0x38, 0x46, 0x2a, 0x46, + 0x09, 0x30, 0xfe, 0xf7, /// 0x1db0 + 0xd7, 0xfd, 0x60, 0x7b, 0x80, 0x21, 0x40, 0x19, 0x60, 0x73, 0x30, 0x8d, + 0x08, 0x43, 0x30, 0x85, /// 0x1dc0 + 0x38, 0x46, 0x32, 0x21, 0xa0, 0x38, 0x41, 0x66, 0x05, 0x20, 0x38, 0x77, + 0xf8, 0xbd, 0xfe, 0xb5, /// 0x1dd0 + 0x07, 0x46, 0x84, 0x48, 0x20, 0x30, 0x00, 0x90, 0xc0, 0x7f, 0x00, 0x28, + 0x06, 0xd1, 0x00, 0x2f, /// 0x1de0 + 0x01, 0xd0, 0x02, 0x20, 0x00, 0xe0, 0x08, 0x20, 0x00, 0x99, 0xc8, 0x77, + 0x00, 0x98, 0x7e, 0x4b, /// 0x1df0 + 0xc1, 0x7f, 0xf8, 0x01, 0x86, 0x46, 0x7a, 0x48, 0xde, 0x1d, 0xff, 0x36, + 0x20, 0x30, 0xfa, 0x36, /// 0x1e00 + 0x00, 0x89, 0x34, 0x8a, 0x01, 0x94, 0x09, 0x24, 0xa4, 0x01, 0x1c, 0x19, + 0x33, 0x7d, 0x8a, 0x07, /// 0x1e10 + 0xa5, 0x79, 0x9c, 0x46, 0x00, 0x2a, 0x4b, 0xd0, 0x62, 0x46, 0x52, 0x08, + 0x73, 0x46, 0x1a, 0x43, /// 0x1e20 + 0xd2, 0xb2, 0x32, 0x75, 0x00, 0x2d, 0x0a, 0xd0, 0x07, 0x2d, 0x10, 0xd3, + 0xff, 0x2a, 0x11, 0xd0, /// 0x1e30 + 0x00, 0x2a, 0x38, 0xd0, 0x55, 0x2a, 0x38, 0xd0, 0xaa, 0x2a, 0x36, 0xd0, + 0x83, 0xe0, 0x48, 0x21, /// 0x1e40 + 0x48, 0x43, 0x6b, 0x49, 0xff, 0xf7, 0x12, 0xfb, 0x01, 0x99, 0x40, 0x18, + 0x70, 0x82, 0x6d, 0x1c, /// 0x1e50 + 0xa5, 0x71, 0x82, 0xe0, 0x88, 0x07, 0x02, 0xd5, 0xff, 0xf7, 0x80, 0xff, + 0x73, 0xe0, 0x60, 0x4d, /// 0x1e60 + 0x20, 0x3d, 0x6a, 0x8d, 0x00, 0x2a, 0x1c, 0xd0, 0xd0, 0x07, 0x02, 0xd0, + 0xff, 0xf7, 0xc3, 0xfe, /// 0x1e70 + 0x11, 0xe0, 0x5b, 0x48, 0x93, 0x06, 0xc1, 0x79, 0x00, 0x2b, 0x07, 0xda, + 0x00, 0x22, 0x42, 0x73, /// 0x1e80 + 0xfd, 0x22, 0x11, 0x40, 0xc1, 0x71, 0xff, 0xf7, 0x69, 0xff, 0x04, 0xe0, + 0xd2, 0x06, 0x02, 0xd5, /// 0x1e90 + 0xf7, 0x22, 0x11, 0x40, 0xc1, 0x71, 0x28, 0x8d, 0x69, 0x8d, 0x88, 0x43, + 0x28, 0x85, 0x00, 0x20, /// 0x1ea0 + 0x68, 0x85, 0x01, 0x20, 0x02, 0xe0, 0x02, 0x20, 0x00, 0xe0, 0x04, 0x20, + 0x20, 0x70, 0x4a, 0xe0, /// 0x1eb0 + 0xc9, 0x06, 0x49, 0x0f, 0x47, 0xd0, 0x4b, 0x4a, 0x40, 0x32, 0xd1, 0x79, + 0x52, 0x79, 0x00, 0x2d, /// 0x1ec0 + 0x13, 0xd0, 0x48, 0x48, 0x14, 0x30, 0x09, 0x2d, 0x25, 0xd0, 0x0a, 0x2d, + 0x3d, 0xd3, 0x00, 0x2f, /// 0x1ed0 + 0x39, 0xd0, 0x00, 0x23, 0xa3, 0x71, 0x00, 0x2a, 0x25, 0xd0, 0x8a, 0x42, + 0x27, 0xd9, 0x89, 0x1c, /// 0x1ee0 + 0xfe, 0xf7, 0x93, 0xfd, 0x00, 0x28, 0x26, 0xd0, 0x2d, 0xe0, 0x00, 0x2f, + 0x2b, 0xd1, 0x01, 0x23, /// 0x1ef0 + 0xa3, 0x71, 0x00, 0x2a, 0x0c, 0xd0, 0x8a, 0x1a, 0x58, 0x21, 0x92, 0x1c, + 0x4a, 0x43, 0x08, 0x32, /// 0x1f00 + 0x50, 0x43, 0x3b, 0x49, 0xff, 0xf7, 0xb2, 0xfa, 0x01, 0x99, 0x40, 0x18, + 0x70, 0x82, 0x24, 0xe0, /// 0x1f10 + 0x60, 0x21, 0x48, 0x43, 0xf5, 0xe7, 0x0a, 0x21, 0xa1, 0x71, 0x10, 0x5c, + 0xfe, 0xf7, 0x7e, 0xfd, /// 0x1f20 + 0xb8, 0x42, 0x10, 0xd0, 0x19, 0xe0, 0x60, 0x46, 0xff, 0xf7, 0x30, 0xfe, + 0xe0, 0x71, 0x60, 0x79, /// 0x1f30 + 0x40, 0x1c, 0x60, 0x71, 0x11, 0xe0, 0x00, 0x98, 0xc0, 0x7f, 0x40, 0x07, + 0x01, 0xd5, 0x08, 0x20, /// 0x1f40 + 0xb4, 0xe7, 0xff, 0xf7, 0x66, 0xfe, 0x01, 0x20, 0xfe, 0xbd, 0x11, 0x5c, + 0x73, 0x46, 0x49, 0x08, /// 0x1f50 + 0x19, 0x43, 0x11, 0x54, 0xa0, 0x79, 0x40, 0x1c, 0xa0, 0x71, 0x00, 0x20, + 0xfe, 0xbd, 0xfe, 0xb5, /// 0x1f60 + 0x20, 0x4c, 0x24, 0x48, 0xa1, 0x89, 0x26, 0x46, 0x00, 0x27, 0x40, 0x3e, + 0x81, 0x42, 0x09, 0xd1, /// 0x1f70 + 0x60, 0x8a, 0x41, 0x1e, 0x61, 0x82, 0x03, 0xd3, 0x30, 0x7b, 0x40, 0x1e, + 0xf0, 0x72, 0xed, 0xe0, /// 0x1f80 + 0xf7, 0x72, 0xeb, 0xe0, 0x16, 0x48, 0x22, 0x8a, 0x20, 0x38, 0x01, 0x46, + 0x15, 0x4d, 0x40, 0x31, /// 0x1f90 + 0x80, 0x30, 0x40, 0x35, 0x01, 0x91, 0x00, 0x90, 0x00, 0x2a, 0x06, 0xd1, + 0x2f, 0x70, 0x6f, 0x71, /// 0x1fa0 + 0xaf, 0x71, 0x0f, 0x20, 0x60, 0x82, 0xfe, 0xf7, 0x70, 0xfc, 0x9b, 0xe0, + 0x41, 0x00, 0x0e, 0x4a, /// 0x1fb0 + 0x40, 0x1c, 0x89, 0x18, 0xff, 0x31, 0xc1, 0x31, 0x00, 0x07, 0x09, 0x8d, + 0x00, 0x0f, 0x60, 0x72, /// 0x1fc0 + 0xa0, 0x89, 0x40, 0x1c, 0x80, 0xb2, 0xa0, 0x81, 0x03, 0x28, 0x2f, 0xd8, + 0x01, 0x28, 0x13, 0xd0, /// 0x1fd0 + 0xe2, 0x89, 0x51, 0x18, 0x89, 0xb2, 0xe1, 0x81, 0x03, 0x28, 0x12, 0xd1, + 0x12, 0xe0, 0x00, 0x00, /// 0x1fe0 + 0x20, 0x00, 0x00, 0x20, 0x30, 0x03, 0x00, 0x20, 0x30, 0x01, 0x00, 0x20, + 0xb0, 0x01, 0x00, 0x20, /// 0x1ff0 + 0x70, 0x17, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xe7, 0x81, 0xef, 0x70, + 0xaf, 0x70, 0xaf, 0x72, /// 0x2000 + 0xef, 0x72, 0x6f, 0xe0, 0x49, 0x1c, 0x48, 0x08, 0xe0, 0x81, 0x01, 0x99, + 0x08, 0x81, 0x00, 0x99, /// 0x2010 + 0x09, 0x78, 0xc9, 0x07, 0x01, 0xd1, 0xfe, 0xf7, 0xe1, 0xf9, 0xe1, 0x89, + 0x50, 0x4a, 0x48, 0x08, /// 0x2020 + 0x80, 0x18, 0xff, 0xf7, 0x23, 0xfa, 0x01, 0x99, 0xc8, 0x83, 0x5b, 0xe0, + 0x00, 0x98, 0xc2, 0x7a, /// 0x2030 + 0x06, 0x20, 0x93, 0x07, 0x9b, 0x0f, 0x98, 0x40, 0x80, 0x1e, 0x52, 0x07, + 0xe2, 0x89, 0x03, 0xd5, /// 0x2040 + 0x10, 0x18, 0x88, 0x42, 0x03, 0xd3, 0x20, 0xe0, 0x10, 0x1a, 0x88, 0x42, + 0x1d, 0xd9, 0xe8, 0x78, /// 0x2050 + 0x40, 0x1c, 0xc0, 0xb2, 0xe8, 0x70, 0x0a, 0x28, 0x53, 0xd8, 0xa8, 0x7a, + 0x00, 0x28, 0x12, 0xd0, /// 0x2060 + 0xa8, 0x78, 0x05, 0x28, 0x01, 0xd9, 0x00, 0x20, 0x05, 0xe0, 0x02, 0x28, + 0x0b, 0xd9, 0xe8, 0x7a, /// 0x2070 + 0x00, 0x28, 0x06, 0xd0, 0x01, 0x20, 0xff, 0xf7, 0xaa, 0xfe, 0x00, 0x28, + 0x41, 0xd1, 0xef, 0x72, /// 0x2080 + 0x01, 0xe0, 0x01, 0x20, 0xe8, 0x72, 0xaf, 0x70, 0x2c, 0xe0, 0xa8, 0x78, + 0x40, 0x1c, 0xc0, 0xb2, /// 0x2090 + 0xa8, 0x70, 0xa9, 0x7a, 0x00, 0x29, 0x0c, 0xd0, 0xe9, 0x7a, 0x00, 0x29, + 0x03, 0xd0, 0x05, 0x28, /// 0x20a0 + 0x0c, 0xd9, 0x01, 0x20, 0x02, 0xe0, 0x0a, 0x28, 0x08, 0xd9, 0x00, 0x20, + 0xff, 0xf7, 0x8f, 0xfe, /// 0x20b0 + 0x27, 0xe0, 0xe8, 0x78, 0x02, 0x28, 0x01, 0xd9, 0x01, 0x20, 0xa8, 0x72, + 0xe8, 0x78, 0x05, 0x28, /// 0x20c0 + 0x01, 0xd9, 0x00, 0x20, 0x05, 0xe0, 0x02, 0x28, 0x0b, 0xd9, 0xe8, 0x7a, + 0x00, 0x28, 0x06, 0xd0, /// 0x20d0 + 0x01, 0x20, 0xff, 0xf7, 0x7c, 0xfe, 0x00, 0x28, 0x13, 0xd1, 0xef, 0x72, + 0x01, 0xe0, 0x01, 0x20, /// 0x20e0 + 0xe8, 0x72, 0xef, 0x70, 0x21, 0x7a, 0x60, 0x7a, 0x81, 0x42, 0x00, 0xd0, + 0x5e, 0xe7, 0x30, 0x7b, /// 0x20f0 + 0x40, 0x1e, 0xf0, 0x72, 0x20, 0x8a, 0x40, 0x1c, 0x80, 0xb2, 0x20, 0x82, + 0x61, 0x8a, 0x88, 0x42, /// 0x2100 + 0x2c, 0xd9, 0xfe, 0xf7, 0x54, 0xfb, 0x00, 0x20, 0xc0, 0x43, 0xa0, 0x81, + 0x15, 0x48, 0xc7, 0x77, /// 0x2110 + 0x70, 0x7c, 0x00, 0x28, 0x01, 0xd0, 0x16, 0x20, 0x00, 0xe0, 0x05, 0x20, + 0x70, 0x74, 0x28, 0x78, /// 0x2120 + 0x00, 0x28, 0x01, 0xd0, 0x70, 0x7c, 0x10, 0xe0, 0x60, 0x8a, 0x0f, 0x28, + 0x04, 0xd9, 0x21, 0x8a, /// 0x2130 + 0x40, 0x1a, 0x71, 0x7c, 0x40, 0x18, 0x08, 0xe0, 0x20, 0x8a, 0x31, 0x7b, + 0x02, 0x1d, 0x8a, 0x42, /// 0x2140 + 0x02, 0xd2, 0xc0, 0xb2, 0x08, 0x1a, 0x00, 0xe0, 0x04, 0x20, 0x60, 0x82, + 0x20, 0x8a, 0x61, 0x8a, /// 0x2150 + 0x42, 0x18, 0x31, 0x7b, 0x8a, 0x42, 0x01, 0xd2, 0x08, 0x1a, 0x60, 0x82, + 0x00, 0x20, 0xfe, 0xbd, /// 0x2160 + 0x00, 0xdc, 0x05, 0x00, 0x50, 0x03, 0x00, 0x20, 0x10, 0xb5, 0xfe, 0x48, + 0x41, 0x7b, 0x0a, 0x07, /// 0x2170 + 0x03, 0xd5, 0xf7, 0x22, 0x11, 0x40, 0x41, 0x73, 0x10, 0xbd, 0x08, 0x22, + 0x11, 0x43, 0x41, 0x73, /// 0x2180 + 0xfe, 0xf7, 0x18, 0xfd, 0x10, 0xbd, 0xf7, 0x49, 0x00, 0x20, 0xf7, 0x4a, + 0x40, 0x31, 0x89, 0x6e, /// 0x2190 + 0x92, 0x68, 0x06, 0xe0, 0x0b, 0x46, 0x53, 0x40, 0x1b, 0x06, 0x00, 0xd0, + 0x40, 0x1c, 0x09, 0x0a, /// 0x21a0 + 0x12, 0x0a, 0x0b, 0x46, 0x13, 0x43, 0xf5, 0xd1, 0x70, 0x47, 0xee, 0x4a, + 0x10, 0xb5, 0xef, 0x4b, /// 0x21b0 + 0x40, 0x3a, 0x93, 0x85, 0x20, 0x32, 0x90, 0x73, 0xd1, 0x73, 0x11, 0x46, + 0x01, 0x20, 0x80, 0x31, /// 0x21c0 + 0xc8, 0x77, 0x02, 0x20, 0xfe, 0xf7, 0x8d, 0xfc, 0x10, 0xbd, 0xe6, 0x49, + 0x10, 0xb5, 0xe8, 0x4a, /// 0x21d0 + 0x40, 0x39, 0x8a, 0x85, 0x20, 0x31, 0x88, 0x73, 0x04, 0x20, 0x80, 0x31, + 0xc8, 0x77, 0x01, 0x20, /// 0x21e0 + 0xfe, 0xf7, 0x7f, 0xfc, 0x10, 0xbd, 0xf8, 0xb5, 0x09, 0x21, 0xe2, 0x4b, + 0xdd, 0x4c, 0x89, 0x01, /// 0x21f0 + 0x5d, 0x18, 0xa0, 0x34, 0xff, 0x33, 0xe0, 0x79, 0xff, 0x33, 0x02, 0x26, + 0xda, 0x4a, 0x02, 0x33, /// 0x2200 + 0x00, 0x28, 0x02, 0xd0, 0x01, 0x28, 0x0b, 0xd0, 0x3e, 0xe0, 0xd0, 0x79, + 0xc0, 0x07, 0x05, 0xd0, /// 0x2210 + 0x31, 0x20, 0xff, 0xf7, 0xda, 0xff, 0x01, 0x20, 0xe0, 0x71, 0xf8, 0xbd, + 0xe6, 0x71, 0x0c, 0xe0, /// 0x2220 + 0x28, 0x78, 0x00, 0x07, 0xfa, 0xd5, 0x18, 0x7d, 0x31, 0x28, 0xf7, 0xd1, + 0x58, 0x7d, 0x10, 0x71, /// 0x2230 + 0x98, 0x7d, 0x50, 0x71, 0xd8, 0x7d, 0x90, 0x71, 0xf0, 0xe7, 0xe7, 0x79, + 0x78, 0x08, 0xf9, 0x07, /// 0x2240 + 0x7f, 0x1c, 0xff, 0xb2, 0xe7, 0x71, 0xbc, 0x46, 0xc7, 0x4f, 0x80, 0x3f, + 0x00, 0x29, 0x0c, 0xd0, /// 0x2250 + 0x29, 0x78, 0xc9, 0x07, 0x18, 0xd0, 0x39, 0x18, 0xc6, 0x4f, 0x80, 0x31, + 0x38, 0x18, 0x13, 0x27, /// 0x2260 + 0x7f, 0x01, 0x09, 0x7b, 0xc0, 0x19, 0x01, 0x72, 0x0e, 0xe0, 0x3f, 0x18, + 0x80, 0x37, 0x39, 0x7b, /// 0x2270 + 0x3f, 0x7a, 0xb9, 0x42, 0x05, 0xd0, 0xc2, 0x07, 0x00, 0xd1, 0x04, 0x20, + 0xff, 0xf7, 0x95, 0xff, /// 0x2280 + 0xf8, 0xbd, 0x60, 0x46, 0x40, 0x1c, 0xe0, 0x71, 0xe0, 0x79, 0x08, 0x28, + 0xd5, 0xd3, 0x41, 0x1c, /// 0x2290 + 0xe1, 0x71, 0x08, 0x28, 0x06, 0xd0, 0x28, 0x78, 0xc0, 0x07, 0x08, 0xd0, + 0x98, 0x6e, 0x90, 0x60, /// 0x22a0 + 0xd6, 0x71, 0x06, 0xe0, 0xff, 0xf7, 0x6f, 0xff, 0xc1, 0xb2, 0x00, 0x20, + 0xe6, 0xe7, 0x04, 0x20, /// 0x22b0 + 0xd0, 0x71, 0xac, 0x48, 0x05, 0x21, 0x80, 0x38, 0x81, 0x72, 0xf8, 0xbd, + 0xa9, 0x48, 0x10, 0xb5, /// 0x22c0 + 0xad, 0x49, 0x40, 0x38, 0xc1, 0x62, 0xa7, 0x49, 0x01, 0x20, 0x60, 0x31, + 0xc8, 0x77, 0xfe, 0xf7, /// 0x22d0 + 0x08, 0xfc, 0x10, 0xbd, 0xa3, 0x48, 0x10, 0xb5, 0xa8, 0x49, 0x40, 0x38, + 0x81, 0x85, 0xa2, 0x48, /// 0x22e0 + 0x60, 0x38, 0x81, 0x7e, 0x9f, 0x48, 0x20, 0x38, 0x81, 0x73, 0x01, 0x20, + 0xfe, 0xf7, 0xf9, 0xfb, /// 0x22f0 + 0x10, 0xbd, 0x9c, 0x48, 0x10, 0xb5, 0x60, 0x30, 0x00, 0x7a, 0xff, 0xf7, + 0x47, 0xfc, 0x99, 0x49, /// 0x2300 + 0xc4, 0xb2, 0x68, 0x31, 0x08, 0x46, 0x62, 0x1c, 0x7b, 0x38, 0xfe, 0xf7, + 0x29, 0xfb, 0x95, 0x48, /// 0x2310 + 0x0c, 0x21, 0x20, 0x38, 0x01, 0x73, 0x20, 0x46, 0xfe, 0xf7, 0xe3, 0xfb, + 0x10, 0xbd, 0x91, 0x49, /// 0x2320 + 0x10, 0xb5, 0x0c, 0x22, 0x20, 0x39, 0x0a, 0x73, 0x15, 0x22, 0x4a, 0x73, + 0x88, 0x73, 0x01, 0x20, /// 0x2330 + 0xfe, 0xf7, 0xd7, 0xfb, 0x10, 0xbd, 0x10, 0xb5, 0x8e, 0x48, 0x00, 0x78, + 0xff, 0xf7, 0x26, 0xfc, /// 0x2340 + 0x04, 0x46, 0x42, 0x1c, 0x87, 0x48, 0x8b, 0x49, 0x13, 0x38, 0xfe, 0xf7, + 0x09, 0xfb, 0x85, 0x48, /// 0x2350 + 0x0c, 0x21, 0x20, 0x38, 0x01, 0x73, 0x20, 0x46, 0xfe, 0xf7, 0xc3, 0xfb, + 0x10, 0xbd, 0xf0, 0xb5, /// 0x2360 + 0x81, 0x48, 0x01, 0x78, 0x49, 0x06, 0x01, 0xd5, 0x00, 0x20, 0xf0, 0xbd, + 0x01, 0x8a, 0x7e, 0x48, /// 0x2370 + 0x40, 0x38, 0x00, 0x88, 0x0b, 0x1a, 0x02, 0xd5, 0x01, 0x25, 0x59, 0x42, + 0x01, 0xe0, 0x00, 0x25, /// 0x2380 + 0x19, 0x46, 0x78, 0x48, 0x04, 0x26, 0xa0, 0x30, 0x42, 0x7c, 0x94, 0x08, + 0x34, 0x1b, 0x4c, 0x43, /// 0x2390 + 0x61, 0x09, 0x05, 0xd0, 0x00, 0x2d, 0x01, 0xd0, 0x00, 0x24, 0x02, 0xe0, + 0x02, 0x24, 0x00, 0xe0, /// 0x23a0 + 0x01, 0x24, 0x10, 0x26, 0x86, 0x57, 0x02, 0x27, 0x7e, 0x40, 0x20, 0x27, + 0xa6, 0x42, 0x05, 0xd1, /// 0x23b0 + 0x0f, 0x2a, 0x01, 0xd2, 0x52, 0x1c, 0x0e, 0xe0, 0x87, 0x74, 0x0e, 0xe0, + 0x86, 0x7c, 0x00, 0x2e, /// 0x23c0 + 0x0b, 0xd0, 0x76, 0x1e, 0x36, 0x06, 0x36, 0x0e, 0x86, 0x74, 0x06, 0xd1, + 0x00, 0x2a, 0x04, 0xd0, /// 0x23d0 + 0xfc, 0x26, 0x52, 0x1e, 0x32, 0x40, 0x42, 0x74, 0xee, 0xe7, 0x04, 0x74, + 0x00, 0x24, 0x00, 0x29, /// 0x23e0 + 0x0b, 0xd0, 0xc4, 0x73, 0x84, 0x73, 0x08, 0x22, 0x02, 0x73, 0x7f, 0x29, + 0x00, 0xd9, 0x7f, 0x21, /// 0x23f0 + 0x00, 0x2d, 0x00, 0xd0, 0x49, 0x42, 0x48, 0xb2, 0xf0, 0xbd, 0x82, 0x7b, + 0xd2, 0x18, 0x56, 0xb2, /// 0x2400 + 0x86, 0x73, 0xc2, 0x7b, 0x52, 0x1c, 0xd3, 0xb2, 0xc3, 0x73, 0x9a, 0x07, + 0xf0, 0xd1, 0x02, 0x7b, /// 0x2410 + 0x96, 0x42, 0x02, 0xdd, 0x01, 0x21, 0x00, 0x25, 0x04, 0xe0, 0x57, 0x42, + 0xbe, 0x42, 0x07, 0xda, /// 0x2420 + 0x01, 0x21, 0x0d, 0x46, 0x0c, 0x2b, 0x01, 0xd3, 0x52, 0x1c, 0x02, 0x73, + 0x84, 0x73, 0xdc, 0xe7, /// 0x2430 + 0xc4, 0x73, 0x43, 0x7b, 0x5b, 0x1c, 0xdb, 0xb2, 0x43, 0x73, 0x20, 0x2b, + 0xf6, 0xd9, 0x44, 0x73, /// 0x2440 + 0x04, 0x2a, 0xf3, 0xd9, 0x52, 0x1e, 0xf0, 0xe7, 0xfe, 0xb5, 0x47, 0x48, + 0x4c, 0x49, 0x80, 0x38, /// 0x2450 + 0x80, 0x8f, 0x45, 0x4e, 0x48, 0x43, 0x00, 0x0c, 0x40, 0x3e, 0xb0, 0x87, + 0x30, 0x88, 0x41, 0x43, /// 0x2460 + 0x09, 0x0c, 0xf1, 0x87, 0x47, 0x49, 0x88, 0x42, 0x05, 0xd2, 0x47, 0x48, + 0x01, 0x8b, 0x1f, 0x22, /// 0x2470 + 0x12, 0x02, 0x91, 0x43, 0x01, 0x83, 0x3b, 0x4f, 0x3e, 0x4d, 0x78, 0x7b, + 0x3a, 0x4c, 0x41, 0x07, /// 0x2480 + 0xe8, 0x1d, 0xf9, 0x30, 0x80, 0x3c, 0x01, 0x90, 0x20, 0x46, 0x80, 0x30, + 0xff, 0x35, 0xa0, 0x34, /// 0x2490 + 0x81, 0x35, 0x00, 0x90, 0x00, 0x29, 0x4e, 0xda, 0x70, 0x8f, 0xfe, 0xf7, + 0x75, 0xf8, 0xb0, 0x80, /// 0x24a0 + 0x00, 0x99, 0x09, 0x78, 0xc9, 0x07, 0x2b, 0xd1, 0xfe, 0xf7, 0x1a, 0xfc, + 0xb8, 0x7b, 0xfe, 0xf7, /// 0x24b0 + 0x14, 0xf8, 0xb9, 0x7b, 0x35, 0x4a, 0x04, 0x29, 0x02, 0xd2, 0x01, 0x20, + 0x90, 0x80, 0x03, 0xe0, /// 0x24c0 + 0x03, 0x20, 0x90, 0x80, 0x0a, 0x29, 0x01, 0xd2, 0x00, 0x20, 0x08, 0xe0, + 0x0f, 0x29, 0x01, 0xd2, /// 0x24d0 + 0x01, 0x20, 0x04, 0xe0, 0x14, 0x29, 0x01, 0xd2, 0x02, 0x20, 0x00, 0xe0, + 0x03, 0x20, 0x2b, 0x4a, /// 0x24e0 + 0x12, 0x88, 0xf0, 0x23, 0x9a, 0x43, 0x80, 0x01, 0x02, 0x43, 0x28, 0x48, + 0x02, 0x80, 0x07, 0x29, /// 0x24f0 + 0x01, 0xd9, 0x16, 0x21, 0x00, 0xe0, 0x06, 0x21, 0x24, 0x48, 0x81, 0x81, + 0xfe, 0xf7, 0xc0, 0xfb, /// 0x2500 + 0xff, 0xf7, 0x2d, 0xff, 0x18, 0x49, 0x40, 0x31, 0x0a, 0x79, 0x94, 0x46, + 0x92, 0x07, 0x6b, 0xd1, /// 0x2510 + 0x8b, 0x79, 0x5a, 0x1c, 0x8a, 0x71, 0x03, 0x2b, 0x66, 0xd9, 0x72, 0x7b, + 0x12, 0x07, 0x63, 0xd4, /// 0x2520 + 0x62, 0x46, 0x06, 0x23, 0x1a, 0x43, 0x0a, 0x71, 0x01, 0x9a, 0x13, 0x68, + 0x00, 0x9a, 0x93, 0x64, /// 0x2530 + 0x00, 0x22, 0x4a, 0x71, 0x58, 0xe0, 0xff, 0xf7, 0x12, 0xff, 0x79, 0x7b, + 0x0a, 0x07, 0x53, 0xd4, /// 0x2540 + 0x00, 0x9a, 0x13, 0x8a, 0x0d, 0x4a, 0xaa, 0x32, 0x93, 0x42, 0x28, 0xd8, + 0x32, 0x88, 0x9a, 0x42, /// 0x2550 + 0x06, 0xd8, 0x01, 0x9a, 0x13, 0x68, 0x2a, 0x6e, 0x9a, 0x1a, 0x0d, 0x4b, + 0x9a, 0x42, 0x1c, 0xdb, /// 0x2560 + 0x22, 0x7a, 0x17, 0xe0, 0xf0, 0x02, 0x00, 0x20, 0x80, 0x00, 0x00, 0x20, + 0x0c, 0x20, 0x00, 0x00, /// 0x2570 + 0x0c, 0x07, 0x00, 0x00, 0x30, 0x01, 0x00, 0x20, 0x0c, 0x09, 0x00, 0x00, + 0x0c, 0x05, 0x00, 0x00, /// 0x2580 + 0x80, 0x20, 0x05, 0x00, 0x83, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x40, + 0x00, 0x34, 0x00, 0x40, /// 0x2590 + 0x88, 0x13, 0x00, 0x00, 0x10, 0x23, 0x1a, 0x43, 0x11, 0xe0, 0x37, 0x20, + 0x10, 0xe0, 0x22, 0x7a, /// 0x25a0 + 0x94, 0x46, 0x93, 0x07, 0x06, 0xd5, 0x01, 0x9b, 0x2a, 0x6e, 0x1b, 0x68, + 0x9b, 0x1a, 0xfe, 0x4a, /// 0x25b0 + 0x93, 0x42, 0x19, 0xdb, 0x62, 0x46, 0x10, 0x23, 0x1a, 0x43, 0x52, 0x08, + 0x52, 0x00, 0x22, 0x72, /// 0x25c0 + 0x22, 0x7a, 0x93, 0x07, 0x10, 0xd4, 0xd3, 0x06, 0x0e, 0xd5, 0x10, 0x07, + 0x02, 0xd5, 0xf8, 0x48, /// 0x25d0 + 0xf6, 0x4a, 0x42, 0x81, 0x07, 0x20, 0x01, 0x43, 0x79, 0x73, 0x32, 0x20, + 0x68, 0x66, 0x01, 0x98, /// 0x25e0 + 0x00, 0x68, 0x28, 0x38, 0xa8, 0x65, 0xfe, 0xbd, 0xf1, 0x49, 0x42, 0x1d, + 0x20, 0x31, 0x0a, 0x2a, /// 0x25f0 + 0x02, 0xd9, 0x7a, 0x7b, 0x12, 0x07, 0x0a, 0xd5, 0x00, 0x22, 0x8a, 0x77, + 0x0a, 0x7f, 0x00, 0x2a, /// 0x2600 + 0x02, 0xd0, 0x52, 0x1e, 0x0a, 0x77, 0x09, 0xe0, 0x96, 0x21, 0x69, 0x66, + 0x06, 0xe0, 0x32, 0x22, /// 0x2610 + 0x6a, 0x66, 0x8a, 0x7f, 0xff, 0x2a, 0x01, 0xd0, 0x52, 0x1c, 0x8a, 0x77, + 0x21, 0x7a, 0x0a, 0x07, /// 0x2620 + 0x11, 0xd5, 0x82, 0x1d, 0x0c, 0x2a, 0x04, 0xd8, 0x8a, 0x07, 0x09, 0xd5, + 0x49, 0x08, 0x49, 0x00, /// 0x2630 + 0x08, 0xe0, 0xdf, 0x4a, 0x80, 0x32, 0x52, 0x7d, 0x03, 0x2a, 0x04, 0xd9, + 0x8a, 0x07, 0x02, 0xd4, /// 0x2640 + 0xfb, 0x22, 0x11, 0x40, 0x21, 0x72, 0xb1, 0x88, 0x32, 0x29, 0x15, 0xd2, + 0x1e, 0x28, 0x03, 0xdd, /// 0x2650 + 0x00, 0x99, 0x49, 0x8c, 0x27, 0x29, 0x04, 0xd0, 0x00, 0x99, 0x49, 0x8c, + 0x28, 0x29, 0x02, 0xd0, /// 0x2660 + 0x0a, 0xe0, 0x1e, 0x20, 0x08, 0xe0, 0x09, 0x21, 0xc9, 0x43, 0x0a, 0x28, + 0x01, 0xdd, 0x0a, 0x20, /// 0x2670 + 0x02, 0xe0, 0x88, 0x42, 0x00, 0xda, 0x08, 0x46, 0xc3, 0x21, 0x89, 0x00, + 0xa9, 0x85, 0xcc, 0x49, /// 0x2680 + 0x60, 0x39, 0x88, 0x73, 0x00, 0x28, 0x01, 0xd0, 0x01, 0x20, 0x78, 0x74, + 0x01, 0x20, 0xfe, 0xf7, /// 0x2690 + 0x28, 0xfa, 0xc8, 0x48, 0x01, 0x8c, 0x49, 0x1c, 0x01, 0x84, 0xfe, 0xbd, + 0xc4, 0x48, 0x10, 0xb5, /// 0x26a0 + 0x0c, 0x21, 0x60, 0x38, 0x01, 0x73, 0x38, 0x21, 0x41, 0x73, 0x0a, 0x21, + 0x81, 0x73, 0xc1, 0x49, /// 0x26b0 + 0x40, 0x31, 0x09, 0x8f, 0xc1, 0x73, 0x09, 0x0a, 0x01, 0x74, 0xbd, 0x49, + 0x10, 0x20, 0x20, 0x31, /// 0x26c0 + 0xc8, 0x77, 0x03, 0x20, 0xfe, 0xf7, 0x0d, 0xfa, 0x10, 0xbd, 0xb9, 0x48, + 0x10, 0xb5, 0x0c, 0x21, /// 0x26d0 + 0x60, 0x38, 0x01, 0x73, 0x38, 0x21, 0x41, 0x73, 0x3b, 0x21, 0x81, 0x73, + 0x02, 0x21, 0xc1, 0x73, /// 0x26e0 + 0xbb, 0x21, 0x01, 0x74, 0xb2, 0x49, 0x10, 0x20, 0x20, 0x31, 0xc8, 0x77, + 0x03, 0x20, 0xfe, 0xf7, /// 0x26f0 + 0xf8, 0xf9, 0x10, 0xbd, 0xae, 0x4a, 0x10, 0xb5, 0x0c, 0x23, 0x60, 0x3a, + 0x13, 0x73, 0xa4, 0x23, /// 0x2700 + 0x53, 0x73, 0x90, 0x73, 0xaa, 0x48, 0x08, 0x22, 0x51, 0x38, 0xfe, 0xf7, + 0x29, 0xf9, 0xa8, 0x49, /// 0x2710 + 0x10, 0x20, 0x20, 0x31, 0xc8, 0x77, 0x0c, 0x20, 0xfe, 0xf7, 0xe3, 0xf9, + 0x10, 0xbd, 0x10, 0xb5, /// 0x2720 + 0xa5, 0xa1, 0x03, 0xc9, 0xa2, 0xb0, 0x01, 0x91, 0xa2, 0x49, 0x00, 0x90, + 0x14, 0x31, 0x08, 0x22, /// 0x2730 + 0x0c, 0x46, 0x1c, 0xa8, 0xfe, 0xf7, 0x14, 0xf9, 0x08, 0x22, 0x69, 0x46, + 0x1e, 0xa8, 0xfe, 0xf7, /// 0x2740 + 0x0f, 0xf9, 0x02, 0xa8, 0xfe, 0xf7, 0xe6, 0xfc, 0x10, 0x22, 0x1c, 0xa9, + 0x02, 0xa8, 0xfe, 0xf7, /// 0x2750 + 0x27, 0xfe, 0x98, 0x49, 0x02, 0xa8, 0xb0, 0x31, 0xfe, 0xf7, 0xf4, 0xfd, + 0x21, 0x46, 0x08, 0x20, /// 0x2760 + 0xff, 0xf7, 0xc8, 0xff, 0x22, 0xb0, 0x10, 0xbd, 0x92, 0x48, 0x10, 0xb5, + 0x40, 0x30, 0x00, 0x7c, /// 0x2770 + 0xff, 0xf7, 0x0c, 0xfa, 0x04, 0x46, 0x42, 0x1c, 0x8e, 0x49, 0x8d, 0x48, + 0x50, 0x31, 0x53, 0x38, /// 0x2780 + 0xfe, 0xf7, 0xee, 0xf8, 0x8a, 0x48, 0x0c, 0x21, 0x60, 0x38, 0x01, 0x73, + 0x88, 0x49, 0x10, 0x20, /// 0x2790 + 0x20, 0x31, 0xc8, 0x77, 0x20, 0x46, 0xfe, 0xf7, 0xa4, 0xf9, 0x10, 0xbd, + 0xfe, 0xb5, 0x85, 0x4d, /// 0x27a0 + 0x80, 0x35, 0x28, 0x7e, 0x2e, 0x46, 0x40, 0x1e, 0xc2, 0xb2, 0x20, 0x36, + 0x2a, 0x76, 0x00, 0x2a, /// 0x27b0 + 0x1a, 0xd0, 0x80, 0x49, 0x9c, 0x20, 0x40, 0x5a, 0x40, 0x31, 0x00, 0x91, + 0x08, 0x2a, 0x42, 0xd3, /// 0x27c0 + 0x91, 0x07, 0x10, 0xd1, 0x00, 0x99, 0x6b, 0x8b, 0x09, 0x88, 0x59, 0x18, + 0x89, 0xb2, 0x69, 0x83, /// 0x27d0 + 0x00, 0x9b, 0x5b, 0x8f, 0xc0, 0x18, 0x80, 0xb2, 0xa8, 0x83, 0x08, 0x2a, + 0x03, 0xd1, 0x09, 0x09, /// 0x27e0 + 0x69, 0x83, 0x00, 0x09, 0xa8, 0x83, 0xfe, 0xbd, 0x71, 0x48, 0xfd, 0x21, + 0x40, 0x30, 0x02, 0x78, /// 0x27f0 + 0x70, 0x48, 0xd3, 0x07, 0xa0, 0x30, 0x00, 0x7a, 0x01, 0x40, 0x00, 0x2b, + 0x16, 0xd0, 0x02, 0x07, /// 0x2800 + 0xf1, 0xd5, 0xc2, 0x07, 0x01, 0xd0, 0x40, 0x21, 0x0d, 0xe0, 0x82, 0x07, + 0x01, 0xd5, 0x31, 0x72, /// 0x2810 + 0xfe, 0xbd, 0x41, 0x07, 0x06, 0xd4, 0xf7, 0x21, 0x08, 0x40, 0x30, 0x72, + 0x64, 0x48, 0x68, 0x49, /// 0x2820 + 0x41, 0x81, 0xfe, 0xbd, 0x80, 0x21, 0x08, 0x43, 0x30, 0x72, 0xfe, 0xbd, + 0x92, 0x07, 0xfc, 0xd5, /// 0x2830 + 0x02, 0x07, 0xfa, 0xd5, 0xc2, 0x07, 0xf8, 0xd1, 0x82, 0x07, 0xf6, 0xd5, + 0x40, 0x06, 0xf4, 0xd5, /// 0x2840 + 0xbf, 0x20, 0x01, 0x40, 0xe3, 0xe7, 0x06, 0x2a, 0xef, 0xd8, 0xfd, 0xf7, + 0x9d, 0xfe, 0x04, 0x46, /// 0x2850 + 0x68, 0x8b, 0x0b, 0x21, 0x09, 0x07, 0x40, 0x18, 0xfe, 0xf7, 0xca, 0xfa, + 0x05, 0x20, 0x40, 0x07, /// 0x2860 + 0x20, 0x43, 0xfe, 0xf7, 0xc5, 0xfa, 0x53, 0x48, 0x81, 0x8f, 0x0d, 0x20, + 0x00, 0x07, 0x08, 0x18, /// 0x2870 + 0xfe, 0xf7, 0xbe, 0xfa, 0x00, 0x98, 0x0f, 0x21, 0x00, 0x89, 0x09, 0x07, + 0x40, 0x18, 0xfe, 0xf7, /// 0x2880 + 0xb7, 0xfa, 0x50, 0x48, 0x00, 0x88, 0x00, 0x0b, 0xc1, 0x07, 0x05, 0xd0, + 0x40, 0x07, 0x80, 0x0f, /// 0x2890 + 0x0a, 0x21, 0x40, 0x1c, 0x48, 0x43, 0x04, 0x19, 0x68, 0x8b, 0x15, 0x21, + 0x61, 0x43, 0x48, 0x43, /// 0x28a0 + 0x07, 0x0b, 0x00, 0x20, 0x68, 0x83, 0xa8, 0x83, 0x07, 0x21, 0x38, 0x46, + 0x49, 0x07, 0x08, 0x43, /// 0x28b0 + 0xfe, 0xf7, 0x9e, 0xfa, 0x44, 0x48, 0x80, 0x8b, 0xc0, 0x07, 0x0a, 0xd0, + 0x43, 0x48, 0x81, 0x88, /// 0x28c0 + 0x89, 0x07, 0x89, 0x0f, 0x01, 0x29, 0x06, 0xd0, 0x41, 0x49, 0x8c, 0x42, + 0x05, 0xd9, 0x05, 0x20, /// 0x28d0 + 0x07, 0xe0, 0x07, 0x20, 0x05, 0xe0, 0x00, 0x20, 0x03, 0xe0, 0x00, 0x88, + 0x00, 0x06, 0x80, 0x0f, /// 0x28e0 + 0x40, 0x1c, 0x68, 0x76, 0x00, 0x06, 0xc1, 0x0d, 0x32, 0x48, 0x09, 0x18, + 0x60, 0x31, 0x0a, 0x7a, /// 0x28f0 + 0x7a, 0x43, 0xd3, 0x09, 0x09, 0x22, 0x8a, 0x56, 0x0a, 0x21, 0x4a, 0x43, + 0xd4, 0x18, 0x00, 0xd5, /// 0x2900 + 0x00, 0x24, 0x34, 0x4f, 0x84, 0x84, 0x3b, 0x46, 0xff, 0x33, 0x2a, 0x7a, + 0x03, 0x21, 0x81, 0x33, /// 0x2910 + 0xff, 0x37, 0x89, 0x07, 0xa1, 0x37, 0x01, 0x93, 0x31, 0x2a, 0x0b, 0xd0, + 0x00, 0x22, 0x2a, 0x76, /// 0x2920 + 0x27, 0x4a, 0x80, 0x8f, 0x87, 0x3a, 0x90, 0x42, 0x66, 0xd8, 0x2b, 0x48, + 0x84, 0x42, 0x68, 0xd9, /// 0x2930 + 0x04, 0x46, 0x66, 0xe0, 0x1e, 0x4a, 0x01, 0x20, 0x28, 0x76, 0x20, 0x32, + 0xd0, 0x77, 0x30, 0x7a, /// 0x2940 + 0x02, 0x07, 0x0a, 0xd5, 0x80, 0x07, 0x01, 0xd5, 0x01, 0x26, 0x18, 0xe0, + 0x18, 0x4a, 0x02, 0x26, /// 0x2950 + 0x80, 0x32, 0x50, 0x7d, 0x40, 0x1c, 0x50, 0x75, 0x11, 0xe0, 0x16, 0x4a, + 0x00, 0x26, 0xc0, 0x32, /// 0x2960 + 0x10, 0x79, 0x83, 0x07, 0x0b, 0xd1, 0x00, 0x9b, 0x5b, 0x7b, 0x1b, 0x07, + 0x07, 0xd5, 0x06, 0x23, /// 0x2970 + 0x18, 0x43, 0x10, 0x71, 0x19, 0x48, 0x00, 0x68, 0xa8, 0x64, 0x00, 0x20, + 0x50, 0x71, 0x28, 0x78, /// 0x2980 + 0x00, 0x06, 0x00, 0xd5, 0x64, 0x08, 0x20, 0x46, 0x08, 0x43, 0xfe, 0xf7, + 0x31, 0xfa, 0xa9, 0x7a, /// 0x2990 + 0x7d, 0x20, 0xc0, 0x00, 0x41, 0x43, 0x20, 0x04, 0xfe, 0xf7, 0x68, 0xfd, + 0x10, 0x49, 0x88, 0x42, /// 0x29a0 + 0x00, 0xd9, 0x08, 0x46, 0x0f, 0x4a, 0x1f, 0xe0, 0x88, 0x13, 0x00, 0x00, + 0x6c, 0x07, 0x00, 0x00, /// 0x29b0 + 0x30, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0xf9, 0x6e, 0xd4, 0xc1, + 0xe3, 0x2a, 0xb7, 0x58, /// 0x29c0 + 0xdc, 0x05, 0x00, 0x00, 0x20, 0x38, 0x00, 0x40, 0x00, 0x30, 0x00, 0x40, + 0x00, 0x34, 0x00, 0x40, /// 0x29d0 + 0x52, 0x03, 0x00, 0x00, 0x30, 0x01, 0x00, 0x20, 0xe8, 0x26, 0x00, 0x00, + 0x30, 0x02, 0x00, 0x20, /// 0x29e0 + 0xff, 0xff, 0x00, 0x00, 0x0c, 0x31, 0x00, 0x00, 0x01, 0x99, 0x8a, 0x85, + 0xbe, 0x73, 0x01, 0x0a, /// 0x29f0 + 0xf9, 0x73, 0x38, 0x74, 0x03, 0x20, 0x11, 0xe0, 0xfe, 0x48, 0x84, 0x42, + 0x00, 0xd9, 0x04, 0x46, /// 0x2a00 + 0x64, 0x08, 0x20, 0x46, 0x08, 0x43, 0xfe, 0xf7, 0xf3, 0xf9, 0xe0, 0x01, + 0xfa, 0x49, 0xfe, 0xf7, /// 0x2a10 + 0x2d, 0xfd, 0x01, 0x99, 0xf9, 0x4a, 0x8a, 0x85, 0xb8, 0x73, 0x01, 0x20, + 0xfe, 0xf7, 0x61, 0xf8, /// 0x2a20 + 0xfe, 0xbd, 0x10, 0xb5, 0xf6, 0x48, 0x01, 0x22, 0x41, 0x7b, 0x49, 0x1e, + 0xc9, 0xb2, 0x41, 0x73, /// 0x2a30 + 0x8b, 0x07, 0xf4, 0x48, 0x00, 0x2b, 0x03, 0xda, 0x81, 0x8b, 0x11, 0x43, + 0x81, 0x83, 0x10, 0xbd, /// 0x2a40 + 0xcb, 0x07, 0xf1, 0x49, 0x0c, 0xd0, 0x03, 0x8b, 0x8b, 0x43, 0x09, 0x21, + 0x09, 0x02, 0x59, 0x18, /// 0x2a50 + 0x01, 0x83, 0xee, 0x48, 0x82, 0x80, 0x01, 0x88, 0x30, 0x22, 0x91, 0x43, + 0x01, 0x80, 0x10, 0xbd, /// 0x2a60 + 0x02, 0x8b, 0x8a, 0x43, 0x1b, 0x21, 0x09, 0x02, 0x51, 0x18, 0x01, 0x83, + 0xe8, 0x48, 0x40, 0x7b, /// 0x2a70 + 0x00, 0x07, 0x04, 0xd4, 0xe7, 0x48, 0x01, 0x78, 0x04, 0x22, 0x11, 0x43, + 0x01, 0x70, 0xe0, 0x49, /// 0x2a80 + 0x0a, 0x20, 0xc0, 0x31, 0x08, 0x75, 0xe2, 0x48, 0x10, 0x22, 0x40, 0x30, + 0x01, 0x78, 0x11, 0x43, /// 0x2a90 + 0x01, 0x70, 0x80, 0x38, 0x81, 0x8e, 0x40, 0x22, 0x11, 0x43, 0x81, 0x86, + 0x10, 0x46, 0xfd, 0xf7, /// 0x2aa0 + 0x78, 0xfe, 0x10, 0xbd, 0xf0, 0xb5, 0xd6, 0x48, 0x8b, 0xb0, 0x40, 0x7b, + 0x80, 0x07, 0x03, 0xd0, /// 0x2ab0 + 0xff, 0xf7, 0xb7, 0xff, 0x0b, 0xb0, 0xf0, 0xbd, 0xd5, 0x4f, 0xd1, 0x49, + 0x80, 0x37, 0x38, 0x79, /// 0x2ac0 + 0xc0, 0x39, 0x3c, 0x46, 0x82, 0x07, 0x40, 0x3c, 0x06, 0x91, 0x00, 0x2a, + 0x1a, 0xda, 0x09, 0x68, /// 0x2ad0 + 0xa2, 0x6c, 0x89, 0x1a, 0xff, 0x22, 0x2d, 0x32, 0x91, 0x42, 0x13, 0xd9, + 0x79, 0x79, 0x03, 0x29, /// 0x2ae0 + 0x01, 0xd2, 0x04, 0x21, 0x0c, 0xe0, 0xca, 0x49, 0x01, 0x20, 0x40, 0x39, + 0x8a, 0x8e, 0x00, 0x03, /// 0x2af0 + 0x02, 0x43, 0x8a, 0x86, 0xfd, 0xf7, 0x4d, 0xfe, 0x38, 0x79, 0xfd, 0x21, + 0x08, 0x40, 0x01, 0x21, /// 0x2b00 + 0x08, 0x43, 0x38, 0x71, 0x60, 0x78, 0x41, 0x06, 0x13, 0xd5, 0x06, 0x99, + 0xa2, 0x6c, 0x09, 0x68, /// 0x2b10 + 0x89, 0x1a, 0xff, 0x22, 0xf5, 0x32, 0x91, 0x42, 0x0b, 0xd9, 0xbf, 0x21, + 0x08, 0x40, 0xbc, 0x49, /// 0x2b20 + 0x60, 0x70, 0x40, 0x39, 0x8a, 0x8e, 0xff, 0x20, 0x01, 0x30, 0x02, 0x43, + 0x8a, 0x86, 0xfd, 0xf7, /// 0x2b30 + 0x30, 0xfe, 0x20, 0x7e, 0x00, 0x28, 0x02, 0xd0, 0xff, 0xf7, 0x30, 0xfe, + 0xba, 0xe7, 0x06, 0x98, /// 0x2b40 + 0xaf, 0x4d, 0x00, 0x68, 0x40, 0x3d, 0x00, 0x90, 0xe9, 0x6d, 0x0a, 0x22, + 0x41, 0x1a, 0x28, 0x46, /// 0x2b50 + 0x80, 0x30, 0x08, 0x90, 0x82, 0x5e, 0x00, 0x98, 0x91, 0x42, 0x03, 0xdb, + 0xe8, 0x65, 0x48, 0x20, /// 0x2b60 + 0x20, 0x76, 0xe9, 0xe7, 0xa9, 0x6d, 0xa6, 0x4e, 0x41, 0x1a, 0xa9, 0x48, + 0x6a, 0x6e, 0x20, 0x38, /// 0x2b70 + 0x60, 0x36, 0x05, 0x90, 0x91, 0x42, 0x7d, 0xdb, 0x00, 0x98, 0xa8, 0x65, + 0x60, 0x78, 0x01, 0x07, /// 0x2b80 + 0x0b, 0xd5, 0xf7, 0x21, 0x08, 0x40, 0x32, 0x21, 0x69, 0x66, 0x10, 0x21, + 0x08, 0x43, 0x60, 0x70, /// 0x2b90 + 0x00, 0x20, 0xb8, 0x81, 0xff, 0xf7, 0xe8, 0xfd, 0x8c, 0xe7, 0x39, 0x79, + 0x0a, 0x07, 0x0f, 0xd5, /// 0x2ba0 + 0xa2, 0x78, 0x93, 0x06, 0x0c, 0xd5, 0xdf, 0x21, 0x0a, 0x40, 0xa2, 0x70, + 0x32, 0x21, 0x69, 0x66, /// 0x2bb0 + 0x40, 0x21, 0x08, 0x43, 0x60, 0x70, 0x00, 0x98, 0xa0, 0x64, 0xff, 0xf7, + 0xb0, 0xfd, 0x79, 0xe7, /// 0x2bc0 + 0x82, 0x06, 0x08, 0xd5, 0xdf, 0x21, 0x08, 0x40, 0x60, 0x70, 0x32, 0x20, + 0x68, 0x66, 0xff, 0x20, /// 0x2bd0 + 0xfe, 0xf7, 0x22, 0xfc, 0x6e, 0xe7, 0x48, 0x07, 0x0d, 0xd5, 0xfb, 0x20, + 0x01, 0x40, 0x39, 0x71, /// 0x2be0 + 0x32, 0x20, 0x68, 0x66, 0xff, 0xf7, 0x71, 0xfd, 0x06, 0x98, 0x00, 0x68, + 0xa0, 0x64, 0x78, 0x79, /// 0x2bf0 + 0x40, 0x1c, 0x78, 0x71, 0x5e, 0xe7, 0x08, 0x07, 0x23, 0xd5, 0xa7, 0x78, + 0xf8, 0x07, 0x20, 0xd0, /// 0x2c00 + 0x83, 0x48, 0x09, 0x90, 0x00, 0x8f, 0x64, 0x21, 0xfe, 0xf7, 0x30, 0xfc, + 0x05, 0x99, 0x89, 0x7f, /// 0x2c10 + 0x08, 0x1a, 0x79, 0x08, 0x49, 0x00, 0x23, 0x30, 0xa1, 0x70, 0x00, 0x28, + 0x00, 0xdc, 0x40, 0x42, /// 0x2c20 + 0x14, 0x28, 0x2d, 0xdb, 0x32, 0x20, 0x68, 0x66, 0x09, 0x98, 0x02, 0x88, + 0x74, 0x48, 0xc0, 0x30, /// 0x2c30 + 0xc2, 0x80, 0x02, 0x22, 0x11, 0x43, 0xa1, 0x70, 0x00, 0x99, 0x81, 0x60, + 0xff, 0xf7, 0x2e, 0xfd, /// 0x2c40 + 0x38, 0xe7, 0x73, 0x48, 0x40, 0x38, 0x00, 0x8d, 0x00, 0x28, 0x0a, 0xd0, + 0x70, 0x7f, 0x07, 0x28, /// 0x2c50 + 0x07, 0xd2, 0xb0, 0x7f, 0x0a, 0x28, 0x18, 0xd2, 0xff, 0xf7, 0x81, 0xfb, + 0xc0, 0x1d, 0x0e, 0x28, /// 0x2c60 + 0x0e, 0xd9, 0x00, 0x20, 0x70, 0x77, 0x30, 0x7f, 0x00, 0x28, 0x01, 0xd0, + 0x40, 0x1e, 0x30, 0x77, /// 0x2c70 + 0x06, 0x98, 0x00, 0xe0, 0x04, 0xe0, 0x00, 0x68, 0xa8, 0x65, 0xff, 0xf7, + 0xe5, 0xfb, 0x19, 0xe7, /// 0x2c80 + 0x63, 0x48, 0x40, 0x38, 0x00, 0x8d, 0x00, 0x28, 0x86, 0xd0, 0x70, 0x7f, + 0x60, 0x49, 0x40, 0x1c, /// 0x2c90 + 0x70, 0x77, 0x40, 0x39, 0x08, 0x8d, 0x80, 0x22, 0x83, 0x06, 0x00, 0x2b, + 0x39, 0xd0, 0xc3, 0x07, /// 0x2ca0 + 0x04, 0xd0, 0x01, 0x20, 0x48, 0x85, 0xf0, 0x77, 0x03, 0x20, 0x4a, 0xe0, + 0x83, 0x07, 0x05, 0xd5, /// 0x2cb0 + 0x02, 0x20, 0x48, 0x85, 0x01, 0x20, 0xf0, 0x77, 0x05, 0x20, 0x42, 0xe0, + 0x43, 0x07, 0x04, 0xd5, /// 0x2cc0 + 0x04, 0x22, 0x90, 0x43, 0x08, 0x85, 0x02, 0x20, 0x3b, 0xe0, 0x03, 0x07, + 0x04, 0xd5, 0x08, 0x22, /// 0x2cd0 + 0x90, 0x43, 0x08, 0x85, 0x01, 0x20, 0x34, 0xe0, 0xc3, 0x06, 0x0e, 0xd5, + 0x05, 0x9a, 0x92, 0x79, /// 0x2ce0 + 0x52, 0x06, 0x04, 0xd5, 0x10, 0x20, 0x48, 0x85, 0x01, 0x20, 0xf0, 0x77, + 0x02, 0xe0, 0x10, 0x22, /// 0x2cf0 + 0x90, 0x43, 0x08, 0x85, 0xff, 0xf7, 0x1f, 0xfb, 0xdc, 0xe6, 0x83, 0x06, + 0x09, 0xd5, 0x20, 0x20, /// 0x2d00 + 0x48, 0x85, 0x01, 0x20, 0xf0, 0x77, 0x05, 0x98, 0x00, 0x7b, 0x40, 0x1e, + 0x10, 0x43, 0xc0, 0xb2, /// 0x2d10 + 0x17, 0xe0, 0xc0, 0x22, 0x02, 0x40, 0x20, 0xd0, 0xc0, 0x2a, 0x06, 0xd1, + 0x05, 0x9a, 0xd2, 0x79, /// 0x2d20 + 0x52, 0x07, 0x01, 0xd5, 0x40, 0x22, 0x00, 0xe0, 0x80, 0x22, 0x52, 0x06, + 0x0c, 0xd5, 0x40, 0x22, /// 0x2d30 + 0x90, 0x43, 0x08, 0x85, 0x05, 0x98, 0xfb, 0x21, 0xc0, 0x79, 0x08, 0x40, + 0x05, 0x99, 0xc8, 0x71, /// 0x2d40 + 0x06, 0x20, 0xff, 0xf7, 0xec, 0xfa, 0xb5, 0xe6, 0x05, 0x98, 0x04, 0x21, + 0xc0, 0x79, 0x08, 0x43, /// 0x2d50 + 0x05, 0x99, 0xc8, 0x71, 0xff, 0xf7, 0xcd, 0xfa, 0xac, 0xe6, 0xc2, 0x05, + 0x06, 0xd5, 0xff, 0x22, /// 0x2d60 + 0x01, 0x32, 0x90, 0x43, 0x08, 0x85, 0xff, 0xf7, 0xb5, 0xfa, 0xa3, 0xe6, + 0x82, 0x05, 0x86, 0xd5, /// 0x2d70 + 0x06, 0x9a, 0xab, 0x6d, 0x12, 0x68, 0xd3, 0x1a, 0x64, 0x2b, 0xbd, 0xda, + 0xeb, 0x6d, 0x0a, 0x24, /// 0x2d80 + 0x9b, 0x1a, 0x08, 0x9a, 0x14, 0x5f, 0x1a, 0x19, 0xff, 0x23, 0x5f, 0x33, + 0x9a, 0x42, 0xb3, 0xdd, /// 0x2d90 + 0x01, 0x22, 0x52, 0x02, 0x90, 0x43, 0x08, 0x85, 0x19, 0x48, 0x06, 0x21, + 0x80, 0x38, 0x81, 0x72, /// 0x2da0 + 0xff, 0xf7, 0x8c, 0xfa, 0x86, 0xe6, 0x16, 0x48, 0x10, 0xb5, 0x1b, 0x49, + 0x40, 0x38, 0xc1, 0x62, /// 0x2db0 + 0x17, 0x48, 0x40, 0x30, 0xc1, 0x78, 0x12, 0x48, 0x20, 0x38, 0xc1, 0x73, + 0x10, 0x49, 0x01, 0x20, /// 0x2dc0 + 0x60, 0x31, 0xc8, 0x77, 0x02, 0x20, 0xfd, 0xf7, 0x8c, 0xfe, 0x10, 0xbd, + 0xf0, 0xb5, 0x09, 0x22, /// 0x2dd0 + 0x12, 0x49, 0x92, 0x01, 0x0a, 0x4c, 0x8a, 0x18, 0x15, 0x78, 0x20, 0x7c, + 0x13, 0x22, 0x52, 0x01, /// 0x2de0 + 0xc3, 0x07, 0x8a, 0x18, 0x87, 0xb0, 0x00, 0x2b, 0x25, 0xd0, 0x00, 0x2d, + 0x23, 0xd1, 0xd1, 0x79, /// 0x2df0 + 0x49, 0x1c, 0x15, 0xe0, 0xd0, 0x4d, 0x00, 0x00, 0x88, 0x13, 0x00, 0x00, + 0x0c, 0x04, 0x00, 0x00, /// 0x2e00 + 0xf0, 0x02, 0x00, 0x20, 0x00, 0x30, 0x00, 0x40, 0x00, 0x1f, 0x00, 0x00, + 0x00, 0x34, 0x00, 0x40, /// 0x2e10 + 0x40, 0x00, 0x00, 0x20, 0x40, 0x6c, 0x00, 0x40, 0x0c, 0x22, 0x00, 0x00, + 0x30, 0x01, 0x00, 0x20, /// 0x2e20 + 0xc9, 0xb2, 0xd1, 0x71, 0x03, 0x29, 0x02, 0xd2, 0x40, 0x1e, 0x20, 0x74, + 0x03, 0xe0, 0x40, 0x1c, /// 0x2e30 + 0x20, 0x74, 0x00, 0x20, 0xd0, 0x71, 0xbd, 0x4e, 0x27, 0x7c, 0x30, 0x7d, + 0x05, 0x90, 0x70, 0x7d, /// 0x2e40 + 0x01, 0x90, 0xbb, 0x48, 0x01, 0x46, 0xa0, 0x31, 0x80, 0x30, 0x00, 0x91, + 0xc1, 0x7b, 0x04, 0x91, /// 0x2e50 + 0x81, 0x7b, 0x02, 0x91, 0x41, 0x7b, 0x03, 0x7b, 0x03, 0x93, 0x3b, 0x00, + 0xfe, 0xf7, 0x30, 0xfb, /// 0x2e60 + 0x11, 0x0a, 0x0d, 0x13, 0x15, 0x1f, 0x23, 0x36, 0x3e, 0x43, 0x4a, 0x60, + 0x68, 0x6d, 0x78, 0x7d, /// 0x2e70 + 0x82, 0xa8, 0xaa, 0x00, 0xff, 0xf7, 0x97, 0xff, 0x9c, 0xe0, 0xa8, 0x07, + 0x00, 0xd5, 0xfe, 0xe7, /// 0x2e80 + 0x00, 0x20, 0xd0, 0x71, 0x96, 0xe0, 0x30, 0x20, 0x0a, 0xe0, 0x05, 0x99, + 0x30, 0x29, 0xf7, 0xd1, /// 0x2e90 + 0x00, 0x99, 0x01, 0x9b, 0x4b, 0x72, 0xf1, 0x8a, 0x49, 0xba, 0x41, 0x84, + 0xf0, 0xe7, 0x31, 0x20, /// 0x2ea0 + 0xff, 0xf7, 0x93, 0xf9, 0x86, 0xe0, 0x05, 0x9b, 0x31, 0x2b, 0xe9, 0xd1, + 0x01, 0x9d, 0x05, 0x71, /// 0x2eb0 + 0xb3, 0x7d, 0x43, 0x71, 0xf6, 0x7d, 0x86, 0x71, 0x8d, 0x42, 0x02, 0xd2, + 0x8b, 0x42, 0x00, 0xd2, /// 0x2ec0 + 0x43, 0x73, 0x02, 0x99, 0x8b, 0x42, 0xdb, 0xd2, 0x83, 0x73, 0xd9, 0xe7, + 0x00, 0x7a, 0x03, 0x99, /// 0x2ed0 + 0x81, 0x42, 0x01, 0xd0, 0x02, 0x20, 0x35, 0xe0, 0x07, 0x20, 0x37, 0xe0, + 0xe8, 0x07, 0xcf, 0xd0, /// 0x2ee0 + 0x03, 0x98, 0x10, 0x72, 0xcc, 0xe7, 0x40, 0x7a, 0x81, 0x42, 0x01, 0xd0, + 0x01, 0x20, 0x29, 0xe0, /// 0x2ef0 + 0x09, 0x20, 0x2b, 0xe0, 0x8e, 0x4b, 0xed, 0x07, 0x80, 0x33, 0x1b, 0x79, + 0x00, 0x2d, 0x09, 0xd0, /// 0x2f00 + 0x51, 0x72, 0x8b, 0x42, 0x00, 0xd2, 0x01, 0x71, 0x41, 0x8c, 0x27, 0x29, + 0xb8, 0xd1, 0x04, 0x21, /// 0x2f10 + 0x01, 0x71, 0xb5, 0xe7, 0x99, 0x42, 0xb3, 0xd9, 0x43, 0x73, 0x08, 0x20, + 0x20, 0x74, 0xaf, 0xe7, /// 0x2f20 + 0x80, 0x7a, 0x02, 0x99, 0x81, 0x42, 0x01, 0xd0, 0x04, 0x20, 0x0b, 0xe0, + 0x0b, 0x20, 0x0d, 0xe0, /// 0x2f30 + 0xe8, 0x07, 0xa5, 0xd0, 0x02, 0x98, 0x90, 0x72, 0xa2, 0xe7, 0xc0, 0x7a, + 0x04, 0x99, 0x81, 0x42, /// 0x2f40 + 0x03, 0xd0, 0x03, 0x20, 0xff, 0xf7, 0x31, 0xf9, 0x34, 0xe0, 0x0d, 0x20, + 0x20, 0x74, 0x31, 0xe0, /// 0x2f50 + 0xe8, 0x07, 0x95, 0xd0, 0x04, 0x98, 0xd0, 0x72, 0x92, 0xe7, 0xff, 0xf7, + 0x14, 0xf9, 0xc1, 0xb2, /// 0x2f60 + 0x00, 0x20, 0xef, 0xe7, 0xe9, 0x07, 0x1c, 0xd0, 0xb1, 0x6e, 0x81, 0x60, + 0xff, 0x20, 0xc3, 0x30, /// 0x2f70 + 0x70, 0x81, 0x70, 0x48, 0x01, 0x68, 0x80, 0x30, 0x0a, 0x46, 0xff, 0x3a, + 0x2d, 0x3a, 0xc2, 0x65, /// 0x2f80 + 0x01, 0x66, 0x42, 0x6e, 0x89, 0x1a, 0x81, 0x65, 0x6a, 0x49, 0x05, 0x20, + 0x40, 0x31, 0x88, 0x72, /// 0x2f90 + 0x00, 0x98, 0x0f, 0x21, 0x01, 0x72, 0x68, 0x48, 0x01, 0x78, 0x04, 0x22, + 0x11, 0x43, 0x01, 0x70, /// 0x2fa0 + 0x08, 0xe0, 0xa9, 0x07, 0x06, 0xd5, 0x80, 0x68, 0xb0, 0x66, 0x00, 0x20, + 0xd0, 0x71, 0x03, 0xe0, /// 0x2fb0 + 0xfe, 0xf7, 0x6b, 0xfb, 0x20, 0x7c, 0x40, 0x1c, 0x20, 0x74, 0x07, 0xb0, + 0xf0, 0xbd, 0xf8, 0xb5, /// 0x2fc0 + 0x5b, 0x4c, 0x80, 0x34, 0xa2, 0x78, 0x90, 0x07, 0x60, 0xd5, 0x58, 0x4d, + 0x20, 0x46, 0x40, 0x38, /// 0x2fd0 + 0x80, 0x35, 0x01, 0x88, 0xeb, 0x88, 0xc9, 0x1a, 0x00, 0x29, 0x00, 0xdc, + 0x49, 0x42, 0x54, 0x4b, /// 0x2fe0 + 0x53, 0x4f, 0xc0, 0x33, 0xdb, 0x89, 0xbe, 0x8e, 0x99, 0x42, 0x31, 0xdd, + 0xfd, 0x21, 0x0a, 0x40, /// 0x2ff0 + 0xa2, 0x70, 0x00, 0x8f, 0x64, 0x21, 0x00, 0x90, 0xfe, 0xf7, 0x38, 0xfa, + 0x3d, 0x46, 0x20, 0x35, /// 0x3000 + 0x23, 0x38, 0x29, 0x46, 0xa8, 0x77, 0x40, 0x31, 0xc8, 0x70, 0xaf, 0x21, + 0x00, 0x98, 0x09, 0x01, /// 0x3010 + 0x40, 0x1a, 0x19, 0x21, 0xfe, 0xf7, 0x40, 0xfa, 0x48, 0x49, 0x08, 0x82, + 0x08, 0x20, 0x06, 0x43, /// 0x3020 + 0xbe, 0x86, 0xfd, 0xf7, 0xb6, 0xfb, 0xa9, 0x7f, 0x28, 0x46, 0x80, 0x30, + 0x73, 0x29, 0x02, 0xd1, /// 0x3030 + 0xe9, 0x7f, 0x00, 0x29, 0x06, 0xd0, 0x21, 0x78, 0x49, 0x06, 0x49, 0x0e, + 0x21, 0x70, 0x48, 0x21, /// 0x3040 + 0xc1, 0x72, 0x23, 0xe0, 0x21, 0x78, 0x80, 0x22, 0x11, 0x43, 0x21, 0x70, + 0x30, 0x21, 0xf7, 0xe7, /// 0x3050 + 0x38, 0x49, 0x3b, 0x4b, 0x0a, 0x68, 0xa9, 0x68, 0x51, 0x1a, 0x99, 0x42, + 0x16, 0xdd, 0x69, 0x79, /// 0x3060 + 0x02, 0x29, 0x07, 0xd2, 0xc3, 0x89, 0x80, 0x24, 0x23, 0x43, 0xc3, 0x81, + 0x49, 0x1c, 0xaa, 0x60, /// 0x3070 + 0x69, 0x71, 0x0b, 0xe0, 0x01, 0x20, 0xc0, 0x03, 0x06, 0x43, 0xbe, 0x86, + 0xfd, 0xf7, 0x89, 0xfb, /// 0x3080 + 0xa0, 0x78, 0xfd, 0x21, 0x08, 0x40, 0xa0, 0x70, 0x00, 0x20, 0x68, 0x71, + 0x00, 0x20, 0xf8, 0xbd, /// 0x3090 + 0x70, 0xb5, 0x27, 0x49, 0x9f, 0x23, 0x80, 0x31, 0x4a, 0x78, 0x1a, 0x40, + 0x4a, 0x70, 0x0b, 0x46, /// 0x30a0 + 0x20, 0x33, 0x1c, 0x7c, 0x05, 0x78, 0x80, 0x39, 0x8a, 0x8e, 0xac, 0x42, + 0x0e, 0xd1, 0x5c, 0x7c, /// 0x30b0 + 0x45, 0x78, 0xac, 0x42, 0x0a, 0xd1, 0x9c, 0x7c, 0x85, 0x78, 0xac, 0x42, + 0x06, 0xd1, 0xdb, 0x7c, /// 0x30c0 + 0xc0, 0x78, 0x83, 0x42, 0x02, 0xd1, 0x01, 0x20, 0x40, 0x02, 0x01, 0xe0, + 0xff, 0x20, 0x01, 0x30, /// 0x30d0 + 0x02, 0x43, 0x8a, 0x86, 0xfd, 0xf7, 0x5d, 0xfb, 0x70, 0xbd, 0x70, 0xb5, + 0x14, 0x48, 0xdf, 0x22, /// 0x30e0 + 0x80, 0x30, 0x41, 0x78, 0x04, 0x46, 0x11, 0x40, 0x41, 0x70, 0x40, 0x3c, + 0x60, 0x7e, 0x3b, 0x28, /// 0x30f0 + 0x15, 0xd1, 0x23, 0x46, 0x80, 0x33, 0x18, 0x79, 0xfd, 0x21, 0x08, 0x40, + 0x01, 0x21, 0x08, 0x43, /// 0x3100 + 0x18, 0x71, 0x0b, 0x49, 0xa5, 0x7e, 0x8a, 0x8e, 0x02, 0x2d, 0x02, 0xd1, + 0xe4, 0x7e, 0xbb, 0x2c, /// 0x3110 + 0x06, 0xd0, 0x01, 0x20, 0x00, 0x03, 0x02, 0x43, 0x8a, 0x86, 0xfd, 0xf7, + 0x3a, 0xfb, 0x70, 0xbd, /// 0x3120 + 0x08, 0x24, 0x20, 0x43, 0x18, 0x71, 0xa0, 0x02, 0xf5, 0xe7, 0x00, 0x00, + 0x30, 0x03, 0x00, 0x20, /// 0x3130 + 0x00, 0x00, 0x00, 0x20, 0x30, 0x02, 0x00, 0x20, 0x40, 0x6c, 0x00, 0x40, + 0x00, 0x30, 0x00, 0x40, /// 0x3140 + 0xdc, 0x05, 0x00, 0x00, 0x94, 0x28, 0x94, 0x1f, 0x94, 0x15, 0x94, 0x15, + 0x94, 0x0f, 0x94, 0x14, /// 0x3150 + 0x14, 0x14, 0x00, 0x00, 0x93, 0x3e, 0x85, 0x4d, 0x89, 0x43, 0x86, 0x55, + 0x86, 0x5c, 0x86, 0x60, /// 0x3160 + 0x14, 0x00, 0x01, 0x50, 0x01, 0x00, 0x01, 0x00, 0x4e, 0x6f, 0x76, 0x20, + 0x32, 0x31, 0x20, 0x32, /// 0x3170 + 0x30, 0x31, 0x38, 0x00, 0x31, 0x34, 0x3a, 0x33, 0x39, 0x3a, 0x35, 0x36, +}; + +unsigned char idt_firmware_sram[] = { + 0x0c, 0x0b, 0x00, 0x20, 0x30, 0x11, 0x00, 0x20, + 0x08, 0x1d, 0x00, 0x00, 0xac, 0x29, 0x00, 0x00, /// 0x4010 + 0x09, 0x09, 0x00, 0x20, 0x97, 0x1a, 0x00, 0x00, + 0xa3, 0x1e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /// 0x4020 + 0x20, 0x92, 0x02, 0x00, 0x87, 0x01, 0x01, 0x02, + 0xf3, 0x04, 0x1e, 0x12, 0xd4, 0x01, 0x09, 0x00, /// 0x4030 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x13, + 0x78, 0x05, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, /// 0x4040 + 0x23, 0x01, 0x9a, 0x02, 0x90, 0x01, 0xe8, 0x03, + 0x4c, 0x1d, 0x08, 0xff, 0x00, 0x00, 0x00, 0x00, /// 0x4050 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /// 0x4060 + 0x70, 0xb5, 0x72, 0xb6, 0x23, 0x48, 0x22, 0x49, + 0x41, 0x60, 0x23, 0x49, 0x23, 0x4c, 0x81, 0x67, /// 0x4070 + 0x23, 0x4d, 0x62, 0xb6, 0x60, 0x68, 0x21, 0x46, + 0xe8, 0x61, 0x10, 0x22, 0x08, 0x31, 0x21, 0x48, /// 0x4080 + 0x00, 0xf0, 0xea, 0xf9, 0x20, 0x49, 0x08, 0x78, + 0x00, 0x28, 0x00, 0xd1, 0x1f, 0x49, 0x1c, 0x48, /// 0x4090 + 0x10, 0x22, 0x68, 0x30, 0x00, 0xf0, 0xe6, 0xf9, + 0xa0, 0x78, 0xe8, 0x70, 0x58, 0x20, 0x28, 0x87, /// 0x40a0 + 0x20, 0x8b, 0x64, 0x21, 0x00, 0xf0, 0xe4, 0xf9, + 0x15, 0x49, 0x40, 0x1e, 0x40, 0x31, 0x88, 0x72, /// 0x40b0 + 0x13, 0x48, 0xa1, 0x7e, 0x60, 0x30, 0x81, 0x70, + 0x15, 0x49, 0x20, 0x20, 0x08, 0x81, 0x60, 0x22, /// 0x40c0 + 0x8a, 0x83, 0x13, 0x49, 0x20, 0x31, 0x8a, 0x89, + 0x02, 0x43, 0x8a, 0x81, 0xe0, 0x8a, 0x64, 0x21, /// 0x40d0 + 0x00, 0xf0, 0xce, 0xf9, 0x0a, 0x49, 0x21, 0x38, + 0x20, 0x31, 0x88, 0x77, 0xe0, 0x8a, 0xaf, 0x21, /// 0x40e0 + 0x09, 0x01, 0x40, 0x1a, 0x19, 0x21, 0x00, 0xf0, + 0xc9, 0xf9, 0x0a, 0x49, 0x08, 0x82, 0x70, 0xbd, /// 0x40f0 + 0x09, 0x09, 0x00, 0x20, 0x00, 0x01, 0x00, 0x20, + 0x0d, 0x0b, 0x00, 0x20, 0x20, 0x06, 0x00, 0x20, /// 0x4100 + 0x00, 0x00, 0x00, 0x20, 0xb0, 0x00, 0x00, 0x20, + 0x60, 0x3e, 0x00, 0x00, 0x20, 0x11, 0x00, 0x20, /// 0x4110 + 0x00, 0x6c, 0x00, 0x40, 0x00, 0x30, 0x00, 0x40, + 0x10, 0xb5, 0xc1, 0x48, 0x0c, 0x21, 0x01, 0x73, /// 0x4120 + 0x38, 0x21, 0x41, 0x73, 0x0a, 0x21, 0x81, 0x73, + 0xbe, 0x49, 0x09, 0x8f, 0xc1, 0x73, 0x09, 0x0a, /// 0x4130 + 0x01, 0x74, 0x03, 0x20, 0x00, 0xf0, 0xa8, 0xf9, + 0x10, 0xbd, 0xf8, 0xb5, 0xb8, 0x49, 0x20, 0x31, /// 0x4140 + 0x48, 0x7b, 0xc2, 0x06, 0x0e, 0xd5, 0xef, 0x22, + 0x10, 0x40, 0x48, 0x73, 0xb5, 0x48, 0x80, 0x22, /// 0x4150 + 0x40, 0x38, 0x81, 0x8e, 0x11, 0x43, 0x81, 0x86, + 0xb3, 0x48, 0x81, 0x89, 0x04, 0x22, 0x11, 0x43, /// 0x4160 + 0x81, 0x81, 0xf8, 0xbd, 0x43, 0x07, 0xfb, 0x22, + 0x00, 0x2b, 0x0b, 0xda, 0x10, 0x40, 0x10, 0x22, /// 0x4170 + 0x10, 0x43, 0x48, 0x73, 0xad, 0x48, 0x01, 0x21, + 0x81, 0x80, 0x01, 0x88, 0x30, 0x22, 0x91, 0x43, /// 0x4180 + 0x01, 0x80, 0xf8, 0xbd, 0xaa, 0x48, 0x01, 0x7e, + 0x00, 0x29, 0x02, 0xd0, 0x00, 0xf0, 0x52, 0xfb, /// 0x4190 + 0xf8, 0xbd, 0xa3, 0x49, 0xa2, 0x4c, 0x80, 0x39, + 0x0d, 0x68, 0xe1, 0x6b, 0xa5, 0x4b, 0x69, 0x1a, /// 0x41a0 + 0x99, 0x42, 0x03, 0xdb, 0x48, 0x21, 0xe5, 0x63, + 0x01, 0x76, 0xef, 0xe7, 0xa0, 0x6b, 0x21, 0x6c, /// 0x41b0 + 0x28, 0x1a, 0x88, 0x42, 0xec, 0xdb, 0x9e, 0x48, + 0xa5, 0x63, 0x20, 0x38, 0x41, 0x78, 0x4b, 0x07, /// 0x41c0 + 0x06, 0xd5, 0x11, 0x40, 0x41, 0x70, 0x32, 0x20, + 0x20, 0x64, 0x00, 0xf0, 0x63, 0xf9, 0xf8, 0xbd, /// 0x41d0 + 0x0a, 0x07, 0x07, 0xd5, 0xf7, 0x22, 0x11, 0x40, + 0x41, 0x70, 0x32, 0x20, 0x20, 0x64, 0x00, 0xf0, /// 0x41e0 + 0x5f, 0xf9, 0xf8, 0xbd, 0x86, 0x78, 0x31, 0x07, + 0x89, 0x0f, 0x02, 0xd0, 0x00, 0xf0, 0xcf, 0xfa, /// 0x41f0 + 0xf8, 0xbd, 0x8b, 0x4f, 0xf0, 0x07, 0x80, 0x37, + 0x00, 0x28, 0x22, 0xd0, 0x89, 0x48, 0x00, 0x90, /// 0x4200 + 0x00, 0x8f, 0x64, 0x21, 0x00, 0xf0, 0x34, 0xf9, + 0x86, 0x49, 0x72, 0x08, 0x20, 0x39, 0x89, 0x7f, /// 0x4210 + 0x52, 0x00, 0x08, 0x1a, 0x86, 0x49, 0x23, 0x30, + 0x20, 0x39, 0x8a, 0x70, 0x00, 0x28, 0x00, 0xdc, /// 0x4220 + 0x40, 0x42, 0x14, 0x28, 0xe4, 0xdb, 0x32, 0x20, + 0x20, 0x64, 0x00, 0x98, 0x03, 0x88, 0x7c, 0x48, /// 0x4230 + 0xc0, 0x30, 0x83, 0x80, 0x02, 0x20, 0x02, 0x43, + 0x8a, 0x70, 0x3d, 0x64, 0xff, 0xf7, 0x6c, 0xff, /// 0x4240 + 0xf8, 0xbd, 0x00, 0xf0, 0xba, 0xf9, 0x78, 0x7f, + 0x00, 0x28, 0xf9, 0xd0, 0x40, 0x1e, 0x78, 0x77, /// 0x4250 + 0xf8, 0xbd, 0x10, 0xb5, 0x75, 0x48, 0x00, 0x21, + 0x80, 0x88, 0x00, 0x07, 0x00, 0xd5, 0x02, 0x21, /// 0x4260 + 0x75, 0x48, 0x80, 0x8b, 0xc0, 0x04, 0x01, 0xd5, + 0x01, 0x20, 0x01, 0x43, 0x73, 0x48, 0x80, 0x89, /// 0x4270 + 0xc0, 0x06, 0x01, 0xd5, 0x04, 0x20, 0x01, 0x43, + 0x6a, 0x4b, 0x40, 0x3b, 0x9a, 0x8e, 0x50, 0x07, /// 0x4280 + 0x40, 0x0f, 0x48, 0x40, 0x05, 0xd0, 0xd2, 0x08, + 0xd2, 0x00, 0x0a, 0x43, 0x9a, 0x86, 0x00, 0xf0, /// 0x4290 + 0x0d, 0xf9, 0x10, 0xbd, 0x70, 0xb5, 0x66, 0x4a, + 0x20, 0x3a, 0x93, 0x78, 0x98, 0x07, 0x31, 0xd5, /// 0x42a0 + 0x5f, 0x4c, 0x60, 0x49, 0xc0, 0x34, 0x08, 0x88, + 0xa5, 0x88, 0x40, 0x1b, 0x00, 0x28, 0x00, 0xdc, /// 0x42b0 + 0x40, 0x42, 0x63, 0x4d, 0xa8, 0x42, 0x16, 0xdd, + 0xfd, 0x20, 0x03, 0x40, 0x93, 0x70, 0x0d, 0x8f, /// 0x42c0 + 0x64, 0x21, 0x28, 0x46, 0x00, 0xf0, 0xd4, 0xf8, + 0x56, 0x49, 0x23, 0x38, 0x20, 0x39, 0x88, 0x77, /// 0x42d0 + 0xaf, 0x20, 0x00, 0x01, 0x28, 0x1a, 0x19, 0x21, + 0x00, 0xf0, 0xd0, 0xf8, 0x56, 0x49, 0x08, 0x82, /// 0x42e0 + 0x00, 0x20, 0xa0, 0x71, 0x0e, 0xe0, 0x4e, 0x48, + 0x52, 0x4c, 0x80, 0x38, 0x02, 0x68, 0xff, 0x30, /// 0x42f0 + 0x01, 0x30, 0x03, 0x6c, 0xd3, 0x1a, 0xa3, 0x42, + 0x04, 0xdd, 0x8b, 0x7b, 0x80, 0x24, 0x23, 0x43, /// 0x4300 + 0x8b, 0x73, 0x02, 0x64, 0x00, 0x20, 0x70, 0xbd, + 0xf8, 0xb5, 0x45, 0x48, 0x4d, 0x49, 0x80, 0x38, /// 0x4310 + 0x80, 0x6f, 0x00, 0x26, 0x88, 0x42, 0x14, 0xd1, + 0x41, 0x4a, 0xa0, 0x32, 0x50, 0x79, 0x00, 0x28, /// 0x4320 + 0x14, 0xd0, 0x40, 0x49, 0x20, 0x39, 0x88, 0x79, + 0x43, 0x1c, 0x8b, 0x71, 0x0a, 0x28, 0x08, 0xd9, /// 0x4330 + 0x45, 0x48, 0x01, 0x23, 0x03, 0x80, 0x03, 0x23, + 0x03, 0x80, 0x41, 0x23, 0x03, 0x83, 0x56, 0x71, /// 0x4340 + 0x8e, 0x71, 0x38, 0x4f, 0xb8, 0x7b, 0x00, 0x28, + 0x07, 0xd1, 0x03, 0xe0, 0x3f, 0x48, 0x00, 0xf0, /// 0x4350 + 0xb3, 0xf8, 0xf6, 0xe7, 0x38, 0x7b, 0x00, 0x28, + 0x02, 0xd0, 0x3d, 0x48, 0x00, 0xf0, 0xb2, 0xf8, /// 0x4360 + 0x30, 0x48, 0x40, 0x38, 0x80, 0x8e, 0x00, 0x06, + 0x01, 0xd5, 0xff, 0xf7, 0x93, 0xff, 0xff, 0xf7, /// 0x4370 + 0x70, 0xff, 0x2b, 0x4d, 0x20, 0x35, 0x28, 0x7a, + 0x00, 0x28, 0x4e, 0xd1, 0xe8, 0x7a, 0x2c, 0x46, /// 0x4380 + 0x60, 0x3c, 0x00, 0x28, 0x11, 0xd0, 0x40, 0x1e, + 0xe8, 0x72, 0xa0, 0x7a, 0x05, 0x28, 0x44, 0xd1, /// 0x4390 + 0x30, 0x48, 0x00, 0xf0, 0x97, 0xf8, 0x28, 0x7b, + 0xe9, 0x7a, 0x40, 0x1e, 0x81, 0x42, 0x3c, 0xd1, /// 0x43a0 + 0x20, 0x46, 0x80, 0x30, 0x06, 0x86, 0x86, 0x85, + 0x37, 0xe0, 0xa0, 0x7a, 0x1c, 0x4e, 0x03, 0x00, /// 0x43b0 + 0x00, 0xf0, 0x8e, 0xf8, 0x07, 0x05, 0x16, 0x1a, + 0x1e, 0x22, 0x2e, 0x31, 0x33, 0x00, 0x18, 0x48, /// 0x43c0 + 0x79, 0x7b, 0x80, 0x38, 0x00, 0x68, 0xc9, 0x06, + 0x01, 0xd5, 0x1d, 0x21, 0x00, 0xe0, 0x03, 0x21, /// 0x43d0 + 0x88, 0x42, 0x22, 0xd9, 0x08, 0x20, 0x28, 0x73, + 0x32, 0x20, 0x30, 0x64, 0x01, 0x20, 0x15, 0xe0, /// 0x43e0 + 0x00, 0xf0, 0x7c, 0xf8, 0x02, 0x20, 0x11, 0xe0, + 0x00, 0xf0, 0x7e, 0xf8, 0x03, 0x20, 0x0d, 0xe0, /// 0x43f0 + 0x00, 0xf0, 0x80, 0xf8, 0x04, 0x20, 0x09, 0xe0, + 0xff, 0xf7, 0x32, 0xfe, 0x08, 0x48, 0x80, 0x38, /// 0x4400 + 0x00, 0x68, 0xf0, 0x63, 0xb0, 0x63, 0x1e, 0x20, + 0x28, 0x73, 0x05, 0x20, 0xa0, 0x72, 0x04, 0xe0, /// 0x4410 + 0xff, 0xf7, 0x93, 0xfe, 0x01, 0xe0, 0x00, 0xf0, + 0x73, 0xf8, 0x00, 0x20, 0xf8, 0xbd, 0x00, 0x00, /// 0x4420 + 0x80, 0x01, 0x00, 0x20, 0x40, 0x00, 0x00, 0x20, + 0x20, 0x6c, 0x00, 0x40, 0x00, 0x34, 0x00, 0x40, /// 0x4430 + 0xa0, 0x00, 0x00, 0x20, 0xdc, 0x05, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x40, 0x20, 0x48, 0x00, 0x40, /// 0x4440 + 0x49, 0x02, 0x00, 0x00, 0x0d, 0x0b, 0x00, 0x20, + 0x00, 0x44, 0x00, 0x40, 0x18, 0x11, 0x00, 0x20, /// 0x4450 + 0x7d, 0x0f, 0x00, 0x20, 0x27, 0x0f, 0x00, 0x00, + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, /// 0x4460 + 0x7f, 0x05, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, + 0x01, 0x90, 0x01, 0xbd, 0x71, 0x05, 0x00, 0x00, /// 0x4470 + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, + 0xe9, 0x15, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, /// 0x4480 + 0x01, 0x90, 0x01, 0xbd, 0x15, 0x16, 0x00, 0x00, + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, /// 0x4490 + 0x2f, 0x07, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, + 0x01, 0x90, 0x01, 0xbd, 0x2b, 0x12, 0x00, 0x00, /// 0x44a0 + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, + 0xfd, 0x11, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, /// 0x44b0 + 0x01, 0x90, 0x01, 0xbd, 0xd5, 0x05, 0x00, 0x00, + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, /// 0x44c0 + 0xf5, 0x03, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, + 0x01, 0x90, 0x01, 0xbd, 0xb1, 0x00, 0x00, 0x00, /// 0x44d0 + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, + 0x3d, 0x16, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, /// 0x44e0 + 0x01, 0x90, 0x01, 0xbd, 0x81, 0x12, 0x00, 0x00, + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, /// 0x44f0 + 0x5d, 0x12, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, + 0x01, 0x90, 0x01, 0xbd, 0x45, 0x12, 0x00, 0x00, /// 0x4500 + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, + 0x6d, 0x11, 0x00, 0x00, 0xf8, 0xb5, 0x02, 0x22, /// 0x4510 + 0x03, 0x21, 0x00, 0x20, 0x00, 0xf0, 0x94, 0xfa, + 0x03, 0x21, 0x00, 0xf0, 0x97, 0xfa, 0x05, 0x46, /// 0x4520 + 0xfe, 0x49, 0x00, 0xf0, 0x99, 0xfa, 0xfe, 0x4e, + 0xfc, 0x49, 0x30, 0x80, 0x28, 0x39, 0x88, 0x69, /// 0x4530 + 0x0c, 0x46, 0x42, 0x00, 0x48, 0x69, 0x20, 0x34, + 0xc3, 0x0f, 0x1a, 0x43, 0x8a, 0x61, 0xea, 0x07, /// 0x4540 + 0x40, 0x00, 0xd2, 0x0f, 0x10, 0x43, 0x48, 0x61, + 0xa1, 0x7e, 0xf6, 0x4f, 0x49, 0x00, 0xc9, 0x19, /// 0x4550 + 0xff, 0x31, 0x01, 0x31, 0x0d, 0x85, 0x01, 0x22, + 0x03, 0x21, 0x02, 0x20, 0x00, 0xf0, 0x70, 0xfa, /// 0x4560 + 0x45, 0x08, 0x21, 0x46, 0x14, 0x31, 0x28, 0x46, + 0x00, 0xf0, 0x76, 0xfa, 0x70, 0x87, 0xa0, 0x7e, /// 0x4570 + 0x03, 0x22, 0x40, 0x00, 0xc0, 0x19, 0xff, 0x30, + 0x01, 0x30, 0x85, 0x86, 0x11, 0x46, 0x01, 0x20, /// 0x4580 + 0x00, 0xf0, 0x5e, 0xfa, 0x03, 0x21, 0x00, 0xf0, + 0x61, 0xfa, 0x21, 0x46, 0x05, 0x46, 0x0e, 0x31, /// 0x4590 + 0x00, 0xf0, 0x62, 0xfa, 0x31, 0x46, 0x40, 0x39, + 0x88, 0x87, 0xa1, 0x7e, 0x49, 0x00, 0xc9, 0x19, /// 0x45a0 + 0xff, 0x31, 0x01, 0x31, 0xcd, 0x85, 0xa0, 0x7e, + 0x02, 0x28, 0x01, 0xd3, 0x00, 0x20, 0x00, 0xe0, /// 0x45b0 + 0x40, 0x1c, 0xa0, 0x76, 0x00, 0x20, 0x60, 0x71, + 0xf8, 0xbd, 0xf8, 0xb5, 0xd8, 0x4f, 0xda, 0x48, /// 0x45c0 + 0x39, 0x88, 0x81, 0x42, 0x05, 0xd2, 0xd9, 0x48, + 0x02, 0x8b, 0x1f, 0x23, 0x1b, 0x02, 0x9a, 0x43, /// 0x45d0 + 0x02, 0x83, 0xd2, 0x4e, 0x88, 0x3e, 0x72, 0x7b, + 0x35, 0x46, 0xd0, 0x07, 0x20, 0x3d, 0x00, 0x28, /// 0x45e0 + 0x60, 0xd0, 0x78, 0x8f, 0x00, 0xf0, 0x3e, 0xfa, + 0xc0, 0x1c, 0xd1, 0x49, 0xb8, 0x80, 0x09, 0x78, /// 0x45f0 + 0xc9, 0x07, 0x59, 0xd1, 0x00, 0xf0, 0x3c, 0xfa, + 0xcd, 0x48, 0xce, 0x4c, 0x40, 0x30, 0x80, 0x8f, /// 0x4600 + 0x6b, 0x38, 0x0b, 0x28, 0xb0, 0x7b, 0x32, 0xd3, + 0xcb, 0x49, 0xc9, 0x7e, 0x49, 0x09, 0x88, 0x42, /// 0x4610 + 0x04, 0xd2, 0xa2, 0x88, 0x92, 0x07, 0x01, 0xd5, + 0x01, 0x20, 0x05, 0xe0, 0x88, 0x42, 0x05, 0xd3, /// 0x4620 + 0xa1, 0x88, 0x89, 0x07, 0x02, 0xd4, 0x03, 0x20, + 0xa0, 0x80, 0x38, 0xe0, 0x00, 0xf0, 0x26, 0xfa, /// 0x4630 + 0xb1, 0x7b, 0x0a, 0x29, 0x01, 0xd2, 0x00, 0x20, + 0x08, 0xe0, 0x0f, 0x29, 0x01, 0xd2, 0x01, 0x20, /// 0x4640 + 0x04, 0xe0, 0x14, 0x29, 0x01, 0xd2, 0x02, 0x20, + 0x00, 0xe0, 0x03, 0x20, 0x22, 0x88, 0xf0, 0x23, /// 0x4650 + 0x9a, 0x43, 0x80, 0x01, 0x02, 0x43, 0x22, 0x80, + 0x02, 0x29, 0x01, 0xd9, 0x10, 0x20, 0x00, 0xe0, /// 0x4660 + 0x00, 0x20, 0xa0, 0x81, 0x38, 0x89, 0x00, 0xf0, + 0x0f, 0xfa, 0x20, 0x82, 0x17, 0xe0, 0x09, 0x28, /// 0x4670 + 0x01, 0xd2, 0x01, 0x21, 0x00, 0xe0, 0x03, 0x21, + 0xa1, 0x80, 0x21, 0x88, 0xf0, 0x22, 0x91, 0x43, /// 0x4680 + 0x12, 0x28, 0x01, 0xd2, 0x00, 0x22, 0x00, 0xe0, + 0xc0, 0x22, 0x11, 0x43, 0x21, 0x80, 0x02, 0x28, /// 0x4690 + 0x01, 0xd9, 0x10, 0x21, 0x00, 0xe0, 0x00, 0x21, + 0xa1, 0x81, 0x00, 0xf0, 0xef, 0xf9, 0x00, 0xf0, /// 0x46a0 + 0xf9, 0xf9, 0x01, 0xe0, 0x10, 0x07, 0x05, 0xd5, + 0x00, 0xf0, 0xfa, 0xf9, 0x41, 0x1d, 0x0a, 0x29, /// 0x46b0 + 0x23, 0xd8, 0x25, 0xe0, 0x9e, 0x4b, 0x37, 0x20, + 0x1c, 0x8e, 0x9a, 0x4b, 0xa1, 0x42, 0x1b, 0x68, /// 0x46c0 + 0x05, 0xd8, 0xe9, 0x6b, 0x7d, 0x24, 0x59, 0x1a, + 0xe4, 0x00, 0xa1, 0x42, 0x15, 0xdb, 0x94, 0x48, /// 0x46d0 + 0x9a, 0x49, 0x40, 0x38, 0x80, 0x8f, 0x88, 0x42, + 0x04, 0xd9, 0x94, 0x48, 0x81, 0x8a, 0x04, 0x15, /// 0x46e0 + 0x21, 0x43, 0x81, 0x82, 0x91, 0x48, 0x81, 0x8b, + 0x01, 0x24, 0x21, 0x43, 0x81, 0x83, 0x05, 0x20, /// 0x46f0 + 0x02, 0x43, 0x72, 0x73, 0x28, 0x3b, 0xab, 0x63, + 0xf8, 0xbd, 0x32, 0x21, 0x29, 0x64, 0x0f, 0xe0, /// 0x4700 + 0x71, 0x7b, 0x96, 0x22, 0xcb, 0x07, 0x00, 0x2b, + 0x07, 0xd0, 0x84, 0x4b, 0x28, 0x3b, 0x59, 0x7f, /// 0x4710 + 0x00, 0x29, 0x04, 0xd0, 0x49, 0x1e, 0x59, 0x77, + 0x02, 0xe0, 0x09, 0x07, 0x00, 0xd5, 0x2a, 0x64, /// 0x4720 + 0x83, 0x49, 0x81, 0x4b, 0x09, 0x8e, 0x3a, 0x3b, + 0xcb, 0x18, 0x7c, 0x49, 0x3a, 0x88, 0x08, 0x39, /// 0x4730 + 0x9a, 0x42, 0x19, 0xd9, 0x0a, 0x79, 0x0a, 0x2a, + 0x03, 0xd3, 0x7a, 0x48, 0x00, 0x68, 0xe8, 0x63, /// 0x4740 + 0xf8, 0xbd, 0x52, 0x1c, 0x0a, 0x71, 0xc3, 0x21, + 0x89, 0x00, 0xa9, 0x81, 0xa8, 0x73, 0x00, 0x28, /// 0x4750 + 0x01, 0xd0, 0x01, 0x20, 0x70, 0x74, 0x01, 0x20, + 0x00, 0xf0, 0xa8, 0xf9, 0x78, 0x48, 0x81, 0x89, /// 0x4760 + 0x80, 0x22, 0x51, 0x40, 0x81, 0x81, 0xf8, 0xbd, + 0x00, 0x22, 0xeb, 0xe7, 0x6d, 0x4a, 0x10, 0xb5, /// 0x4770 + 0x0c, 0x23, 0x80, 0x32, 0x13, 0x73, 0xa4, 0x23, + 0x53, 0x73, 0x90, 0x73, 0x69, 0x48, 0x08, 0x22, /// 0x4780 + 0x8f, 0x30, 0x00, 0xf0, 0x99, 0xf9, 0x0c, 0x20, + 0x00, 0xf0, 0x90, 0xf9, 0x10, 0xbd, 0x70, 0xb5, /// 0x4790 + 0x64, 0x48, 0x67, 0x4c, 0x00, 0x68, 0x21, 0x6f, + 0x6a, 0x4a, 0x41, 0x1a, 0x8a, 0xb0, 0x91, 0x42, /// 0x47a0 + 0x3e, 0xd9, 0xa1, 0x78, 0x68, 0x4e, 0x09, 0x07, + 0x15, 0xd5, 0x25, 0x46, 0x40, 0x35, 0xea, 0x8f, /// 0x47b0 + 0x51, 0x1c, 0xe9, 0x87, 0x03, 0x2a, 0x10, 0xd9, + 0x59, 0x48, 0x08, 0x22, 0x40, 0x38, 0x81, 0x8e, /// 0x47c0 + 0x11, 0x43, 0x81, 0x86, 0x10, 0x46, 0x00, 0xf0, + 0x7d, 0xf9, 0xa0, 0x78, 0xf7, 0x21, 0x08, 0x40, /// 0x47d0 + 0xa0, 0x70, 0x00, 0x20, 0xe8, 0x87, 0x0a, 0xb0, + 0x70, 0xbd, 0x5c, 0xa3, 0x0e, 0xcb, 0x01, 0xad, /// 0x47e0 + 0x0e, 0xc5, 0x4e, 0x49, 0x20, 0x67, 0x14, 0x39, + 0x08, 0x22, 0x0c, 0x46, 0x04, 0xa8, 0x00, 0xf0, /// 0x47f0 + 0x63, 0xf9, 0x08, 0x22, 0x01, 0xa9, 0x06, 0xa8, + 0x00, 0xf0, 0x5e, 0xf9, 0x30, 0x46, 0x00, 0xf0, /// 0x4800 + 0x67, 0xf9, 0x10, 0x22, 0x04, 0xa9, 0x30, 0x46, + 0x00, 0xf0, 0x68, 0xf9, 0x48, 0x49, 0x30, 0x46, /// 0x4810 + 0x0c, 0x31, 0x00, 0xf0, 0x69, 0xf9, 0x21, 0x46, + 0x08, 0x20, 0xff, 0xf7, 0xa7, 0xff, 0xda, 0xe7, /// 0x4820 + 0xff, 0xf7, 0xcb, 0xfe, 0x3d, 0x49, 0x28, 0x39, + 0x48, 0x7f, 0x00, 0x28, 0xd3, 0xd0, 0x40, 0x1e, /// 0x4830 + 0x48, 0x77, 0xd0, 0xe7, 0xf8, 0xb5, 0x3e, 0x4d, + 0x3d, 0x4c, 0x20, 0x35, 0x28, 0x7e, 0x38, 0x4b, /// 0x4840 + 0x40, 0x1e, 0xc2, 0xb2, 0x2a, 0x76, 0xa0, 0x8f, + 0x19, 0x88, 0x08, 0x2a, 0x10, 0xd3, 0x95, 0x07, /// 0x4850 + 0x0d, 0xd1, 0x65, 0x8f, 0x69, 0x18, 0x89, 0xb2, + 0x61, 0x87, 0x5b, 0x8f, 0xc0, 0x18, 0x80, 0xb2, /// 0x4860 + 0xa0, 0x87, 0x08, 0x2a, 0x03, 0xd1, 0x09, 0x09, + 0x61, 0x87, 0x00, 0x09, 0xa0, 0x87, 0xf8, 0xbd, /// 0x4870 + 0x06, 0x2a, 0xfc, 0xd8, 0x00, 0xf0, 0xf6, 0xf8, + 0x37, 0x49, 0x09, 0x88, 0x28, 0x4a, 0xc9, 0x05, /// 0x4880 + 0x20, 0x32, 0x00, 0x29, 0x01, 0xda, 0x11, 0x7d, + 0x08, 0x18, 0x2a, 0x49, 0x0b, 0x8a, 0x1b, 0x04, /// 0x4890 + 0x02, 0xd5, 0x15, 0x23, 0xd3, 0x56, 0x18, 0x18, + 0x62, 0x8f, 0x15, 0x23, 0x43, 0x43, 0x5a, 0x43, /// 0x48a0 + 0x8b, 0x88, 0x12, 0x0b, 0x00, 0x26, 0x01, 0x2b, + 0x05, 0xd0, 0x55, 0x23, 0xdb, 0x00, 0x98, 0x42, /// 0x48b0 + 0x03, 0xd9, 0x05, 0x20, 0x05, 0xe0, 0x6e, 0x76, + 0x04, 0xe0, 0x08, 0x88, 0x00, 0x06, 0x80, 0x0f, /// 0x48c0 + 0x40, 0x1c, 0x68, 0x76, 0x68, 0x7e, 0x41, 0x00, + 0x15, 0x48, 0x40, 0x38, 0x09, 0x18, 0x60, 0x31, /// 0x48d0 + 0x08, 0x7a, 0x50, 0x43, 0xc2, 0x09, 0x09, 0x20, + 0x08, 0x56, 0x0a, 0x21, 0x48, 0x43, 0x1f, 0x49, /// 0x48e0 + 0x80, 0x18, 0x01, 0xd5, 0x00, 0x20, 0x06, 0xe0, + 0x88, 0x42, 0x04, 0xd9, 0x1b, 0x4a, 0x52, 0x42, /// 0x48f0 + 0x82, 0x18, 0xd2, 0x08, 0x10, 0x18, 0x0e, 0x4a, + 0x40, 0x32, 0x92, 0x8f, 0x6b, 0x3a, 0x0a, 0x2a, /// 0x4900 + 0x01, 0xd8, 0x17, 0x4a, 0x80, 0x18, 0x17, 0x4a, + 0x90, 0x42, 0x00, 0xd9, 0x10, 0x46, 0x0b, 0x4a, /// 0x4910 + 0x04, 0x4f, 0x3d, 0x32, 0x80, 0x37, 0xba, 0x81, + 0xc0, 0x01, 0x25, 0xe0, 0x28, 0x02, 0x00, 0x20, /// 0x4920 + 0x40, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x20, + 0x83, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x40, /// 0x4930 + 0x80, 0x00, 0x00, 0x20, 0x00, 0x34, 0x00, 0x40, + 0x20, 0x06, 0x00, 0x20, 0xcf, 0x03, 0x00, 0x00, /// 0x4940 + 0x20, 0x6c, 0x00, 0x40, 0x70, 0x17, 0x00, 0x00, + 0x40, 0x03, 0x00, 0x20, 0x58, 0x69, 0x61, 0x6f, /// 0x4950 + 0x6d, 0x69, 0x52, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x38, 0x00, 0x40, 0x88, 0x13, 0x00, 0x00, /// 0x4960 + 0xdc, 0x05, 0x00, 0x00, 0xe8, 0x26, 0x00, 0x00, + 0x00, 0xf0, 0x70, 0xf8, 0xb8, 0x73, 0x66, 0x87, /// 0x4970 + 0xa6, 0x87, 0x2e, 0x76, 0x01, 0x20, 0x00, 0xf0, + 0x99, 0xf8, 0xf8, 0xbd, 0xf8, 0xb5, 0x2b, 0x4c, /// 0x4980 + 0xa0, 0x7b, 0x80, 0x06, 0x01, 0xd5, 0x00, 0xf0, + 0xb5, 0xf8, 0xa0, 0x7b, 0x40, 0x06, 0x0a, 0xd5, /// 0x4990 + 0xe0, 0x7b, 0x5a, 0x28, 0x07, 0xd1, 0x60, 0x7b, + 0xef, 0x21, 0x08, 0x40, 0x40, 0x21, 0x08, 0x43, /// 0x49a0 + 0x60, 0x73, 0x23, 0x48, 0x80, 0x47, 0xa0, 0x7b, + 0x04, 0x27, 0xc1, 0x06, 0x21, 0x4d, 0x00, 0x29, /// 0x49b0 + 0x02, 0xda, 0x69, 0x78, 0x39, 0x43, 0x69, 0x70, + 0x00, 0x07, 0x04, 0xd5, 0x1b, 0x48, 0x20, 0x38, /// 0x49c0 + 0xc0, 0x7e, 0x00, 0xf0, 0x9d, 0xf8, 0xa0, 0x7b, + 0x08, 0x26, 0x80, 0x07, 0x00, 0x28, 0x15, 0xda, /// 0x49d0 + 0x19, 0x49, 0x48, 0x7b, 0x02, 0x07, 0x03, 0xd5, + 0xf7, 0x22, 0x10, 0x40, 0x48, 0x73, 0x0d, 0xe0, /// 0x49e0 + 0x30, 0x43, 0x48, 0x73, 0x00, 0xf0, 0x92, 0xf8, + 0x10, 0x48, 0x80, 0x22, 0x40, 0x38, 0x81, 0x8e, /// 0x49f0 + 0x91, 0x43, 0x81, 0x86, 0x11, 0x48, 0x81, 0x89, + 0xb9, 0x43, 0x81, 0x81, 0xa0, 0x7b, 0xc1, 0x07, /// 0x4a00 + 0x02, 0xd0, 0x69, 0x78, 0x31, 0x43, 0x69, 0x70, + 0x00, 0x06, 0x03, 0xd5, 0xa8, 0x78, 0x01, 0x21, /// 0x4a10 + 0x08, 0x43, 0xa8, 0x70, 0x20, 0x7b, 0xc0, 0x07, + 0x02, 0xd0, 0xa8, 0x78, 0x30, 0x43, 0xa8, 0x70, /// 0x4a20 + 0x00, 0x20, 0xe0, 0x73, 0x20, 0x73, 0xa0, 0x73, + 0xf8, 0xbd, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, /// 0x4a30 + 0x61, 0x06, 0x00, 0x20, 0x80, 0x00, 0x00, 0x20, + 0xa0, 0x01, 0x00, 0x20, 0x20, 0x6c, 0x00, 0x40, /// 0x4a40 + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, + 0xcb, 0x03, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, /// 0x4a50 + 0x01, 0x90, 0x01, 0xbd, 0xe9, 0x15, 0x00, 0x00, + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, /// 0x4a60 + 0x49, 0x04, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, + 0x01, 0x90, 0x01, 0xbd, 0x9d, 0x04, 0x00, 0x00, /// 0x4a70 + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, + 0x7d, 0x08, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, /// 0x4a80 + 0x01, 0x90, 0x01, 0xbd, 0x6b, 0x04, 0x00, 0x00, + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, /// 0x4a90 + 0xbf, 0x11, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, + 0x01, 0x90, 0x01, 0xbd, 0x39, 0x08, 0x00, 0x00, /// 0x4aa0 + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, + 0x97, 0x11, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, /// 0x4ab0 + 0x01, 0x90, 0x01, 0xbd, 0x2f, 0x07, 0x00, 0x00, + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, /// 0x4ac0 + 0x7f, 0x05, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, + 0x01, 0x90, 0x01, 0xbd, 0xd5, 0x05, 0x00, 0x00, /// 0x4ad0 + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, + 0xe5, 0x12, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, /// 0x4ae0 + 0x01, 0x90, 0x01, 0xbd, 0x71, 0x15, 0x00, 0x00, + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, /// 0x4af0 + 0x15, 0x15, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, + 0x01, 0x90, 0x01, 0xbd, 0xef, 0x05, 0x00, 0x00, /// 0x4b00 + 0x03, 0xb4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xbd, + 0xa3, 0x12, 0x00, 0x00, 0x03, 0xb4, 0x01, 0x48, /// 0x4b10 + 0x01, 0x90, 0x01, 0xbd, 0x05, 0x0f, 0x00, 0x00, + 0x32, 0x33, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, /// 0x4b20 + 0xf0, 0x14, 0xac, 0x28, 0xac, 0x28, 0xac, 0x28, + 0xbe, 0x28, 0xb9, 0x28, 0x14, 0x14, 0x00, 0x00, +}; +#endif + +extern uint32_t get_hw_version_major(void); + +#endif diff --git a/drivers/power/supply/renesas/idtp9418.c b/drivers/power/supply/renesas/idtp9418.c new file mode 100644 index 000000000000..34834c24a32a --- /dev/null +++ b/drivers/power/supply/renesas/idtp9418.c @@ -0,0 +1,5971 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/*add for sdm845 request*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* add for get hw country */ +#include + +static struct idtp9220_device_info *g_di; +#ifdef CONFIG_FACTORY_BUILD +#define REVERSE_TEST_READY_CHECK_DELAY_MS 12000 +#define REVERSE_DPING_CHECK_DELAY_MS 15000 +#else +#define REVERSE_TEST_READY_CHECK_DELAY_MS 8000 +#define REVERSE_DPING_CHECK_DELAY_MS 10000 +#endif +#define REVERSE_CHG_CHECK_DELAY_MS 10000 +#define BPP_QC_7W_CURRENT 700000 +#define BPP_DEFAULT_CURRENT 800000 +#define EPP_DEFAULT_SWITCH_CURRENT 1800000 +#define EPP_DEFAULT_BYPASS_CURRENT 800000 +#define DEFAULT_40V_PSNS_CURRENT 100000 +#define CURRENT_CHANGE_2_TO_1 30000 +#define DC_LOAD_CURRENT 2000000 +#define DC_FUL_CURRENT 50000 +#define SCREEN_OFF_FUL_CURRENT 250000 +#define DC_LOW_CURRENT 350000 +#define DC_SDP_CURRENT 500000 +#define DC_DCP_CURRENT 500000 +#define DC_PD_CURRENT 800000 +#define DC_MI_CURRENT_20W 2100000 +#define DC_MI_CURRENT_30W 3100000 +#define WIRELESS_BY_USBIN_MI_CURRENT 2000000 +#define DC_MI_STEP1_CURRENT 1200000 +#define DC_QC3_CURRENT 500000 +#define DC_EPP_QC3_CURRENT 900000 +#define DC_QC2_CURRENT 1000000 +#define DC_BPP_CURRENT 850000 +#define DC_BPP_AUTH_FAIL_CURRENT 850000 +#define DC_PAN_CURRENT_UA 1200000 +#define ICL_EXCHANGE_CURRENT 600000 +#define ICL_EXCHANGE_COUNT 10 /*5 = 2min */ + +#define ICL_CP_2SBATT_40W_MA 1000000 +#define ICL_CP_2SBATT_30W_MA 1000000 +#define ICL_CP_2SBATT_20W_MA 1000000 + +#define ICL_TAPER_2SBATT_40W_MA 2000000 +#define ICL_TAPER_2SBATT_30W_MA 1800000 +#define ICL_TAPER_2SBATT_20W_MA 1200000 + +#define EXCHANGE_9V 0x0 +#define EXCHANGE_5V 0x1 +#define EXCHANGE_15V 0x0 +#define EXCHANGE_10V 0x1 +#define LIMIT_EPP_IOUT 500 +#define LIMIT_BPP_IOUT 500 +#define LIMIT_SOC 95 +#define TAPER_SOC 86 +#define EPP_TAPER_SOC 95 +#define FULL_SOC 100 +#define TAPER_VOL 4350000 +#define TAPER_CUR -500000 +#define HIGH_THERMAL_LEVEL_THR 12 +#define OCP_PROTECTION_VOTER "OCP_PROTECTION_VOTER" +#define VOICE_LIMIT_FCC_VOTER "VOICE_LIMIT_FCC_VOTER" +#define VOICE_LIMIT_FCC_1A_VOTER "VOICE_LIMIT_FCC_1A_VOTER" +#define IDTP_WAKE_VOTER "IDTP_WAKE_VOTER" +#define IDTP_DOWNLAOD_WAKE_VOTER "IDTP_DOWNLAOD_WAKE_VOTER" + +#define MAX_PMIC_ICL_UA 1500000 +#define EPP_PLUS_VOL 15 +#define BPP_PLUS_VOL 9 +#define EPP_BASE_VOL 12 +#define FULL_VOL 7 +#define CP_CLOSE_VOUT_MV 14200 +#define PAN_BBC_MAX_ICL_MA 1300000 + +//add for soc 100 retry +#define SOC_100_RETRY 6 + +#define MAC_LEN 6 + +struct idtp9220_access_func { + int (*read)(struct idtp9220_device_info *di, u16 reg, u8 *val); + int (*write)(struct idtp9220_device_info *di, u16 reg, u8 val); + int (*read_buf)(struct idtp9220_device_info *di, u16 reg, u8 *buf, + u32 size); + int (*write_buf)(struct idtp9220_device_info *di, u16 reg, u8 *buf, + u32 size); + int (*mask_write)(struct idtp9220_device_info *di, u16 reg, u8 mask, + u8 val); +}; + +struct idtp9220_dt_props { + unsigned int irq_gpio; + unsigned int hall3_gpio; + unsigned int hall4_gpio; + unsigned int wpc_det_gpio; + unsigned int reverse_gpio; + unsigned int rx_ovp_ctl_gpio; + unsigned int reverse_boost_enable_gpio; + bool wireless_by_usbin; + bool only_idt_on_cmi; + bool is_urd_device; +}; + +struct idtp9220_device_info { + int chip_enable; + char *name; + struct device *dev; + struct idtp9220_access_func bus; + struct regmap *regmap; + struct idtp9220_dt_props dt_props; + int irq; + int hall3_irq; + int hall4_irq; + int wpc_irq; + struct delayed_work irq_work; + struct delayed_work hall3_irq_work; + struct delayed_work hall4_irq_work; + struct delayed_work wpc_det_work; + struct pinctrl *idt_pinctrl; + struct pinctrl_state *idt_gpio_active; + struct pinctrl_state *idt_gpio_suspend; + struct power_supply *usb_psy; + struct power_supply *dc_psy; + struct power_supply *batt_psy; + struct power_supply *idtp_psy; + struct power_supply *wireless_psy; + struct power_supply *ln_psy; + struct power_supply *pc_port_psy; + struct mutex read_lock; + struct mutex write_lock; + struct mutex sysfs_op_lock; + struct mutex reverse_op_lock; + struct delayed_work chg_monitor_work; + struct delayed_work chg_detect_work; + struct delayed_work bpp_connect_load_work; + struct delayed_work epp_connect_load_work; + struct delayed_work cmd_check_work; + struct delayed_work vout_regulator_work; + struct delayed_work load_fod_param_work; + struct delayed_work rx_vout_work; + struct delayed_work dc_check_work; + struct delayed_work initial_tx_work; + struct delayed_work bpp_e5_tx_work; + struct delayed_work pan_tx_work; + struct delayed_work voice_tx_work; + struct delayed_work qc2_f1_tx_work; + struct delayed_work qc3_epp_work; + struct delayed_work oob_set_cep_work; + struct delayed_work oob_set_ept_work; + struct delayed_work rx_ready_check_work; + struct delayed_work rx_vout_cp_close_work; + struct delayed_work keep_awake_work; + struct delayed_work oob_clean_work; + struct delayed_work reverse_chg_work; + struct votable *icl_votable; + struct mutex wpc_det_lock; + struct votable *ocp_disable_votable; + bool wait_for_reverse_test; + /* +reverse work +*/ + struct delayed_work reverse_ept_type_work; + struct delayed_work reverse_chg_state_work; + struct delayed_work reverse_dping_state_work; + struct delayed_work reverse_test_state_work; + struct delayed_work reverse_sent_state_work; + struct alarm reverse_dping_alarm; + struct alarm reverse_chg_alarm; + struct alarm reverse_test_ready_alarm; + +//end +#ifdef IDTP9220_SRAM_UPDATE + struct delayed_work sram_update_work; +#endif + + /* +Factory Test Work +*/ + struct delayed_work get_vout_work; + struct delayed_work get_iout_work; + struct delayed_work fw_download_work; + struct delayed_work idt_first_boot; + + /* + #ifdef CONFIG_DRM + struct notifier_block wireless_fb_notif; + struct mutex screen_lock; + bool screen_icl_status; + #endif + */ + bool screen_on; + int tx_charger_type; + int status; + int count_5v; + int count_9v; + int exchange; + int dcin_present; + int epp; + int power_off_mode; + int power_max; + u8 header; + u8 cmd; + int is_compatible_hwid; + int last_vin; + int is_car_tx; + int is_ble_tx; + int is_zm_mobil_tx; + int is_zm_20w_tx; + int is_voice_box_tx; + int is_pan_tx; + int last_icl; + int power_good_flag; + int vout_on; + + /*idt9220 charging info */ + int vout; + int iout; + int f; + int vrect; + int ss; + int is_epp_qc3; + /* bpp e5_tx info */ + int last_bpp_icl; + int last_bpp_vout; + /* qc2+f1_tx info */ + int is_f1_tx; + int bpp_vout_rise; + int last_qc2_vout; + int last_qc2_icl; + /* qc3_epp+f1_tx info */ + int last_qc3_vout; + int last_qc3_icl; + bool fw_update; + int adapter_voltage; + bool first_rise_flag; + bool enable_ext5v; + bool vswitch_ok; + u8 mac_data[6]; + u8 pen_mac_data[6]; + int rpp_val; + int cep_val; + int is_reverse_mode; + int is_reverse_chg; + int is_boost_mode; + int fw_version; + int bpp_icl; + int chip_ok; + int otg_insert; + bool disable_cp; + struct votable *fcc_votable; + bool bpp_break; + bool cp_regulator_done; + int gpio_enable_val; + int reverse_pen_soc; + int reverse_vout; + int reverse_iout; + int hall3_online; + int hall4_online; +}; + +void idtp922x_request_adapter(struct idtp9220_device_info *di); +static void idtp9220_set_charging_param(struct idtp9220_device_info *di); +int program_fw(struct idtp9220_device_info *di, u16 destAddr, u8 *src, + u32 size); +static int program_crc_verify(struct idtp9220_device_info *di); +static int program_bootloader(struct idtp9220_device_info *di); +static int idtp9220_set_rpp(struct idtp9220_device_info *di); +static int idtp9220_set_cep(struct idtp9220_device_info *di); +static int idtp9220_set_ept(struct idtp9220_device_info *di); +static u8 oob_check_sum(u8 *buf, u32 size); +static int idtp9220_set_reverse_enable(struct idtp9220_device_info *di, + int enable); +static void idt_get_reverse_soc(struct idtp9220_device_info *di); + +/*static int idt_signal_strength = 0; + module_param_named(ss, idt_signal_strength, int, 0600); + */ + +static int idt_signal_range = 2; +static int idt_first_flag; +static int pen_soc_count = 0; + +module_param_named(signal_range, idt_signal_range, int, 0644); + +/* +#ifdef CONFIG_DRM +static int wireless_fb_notifier_cb(struct notifier_block *self, +unsigned long event, void *data); +#endif + */ + +static int idtp9220_get_property_names(struct idtp9220_device_info *di) +{ + di->batt_psy = power_supply_get_by_name("battery"); + if (!di->batt_psy) { + dev_err(di->dev, "[idt] no batt_psy,return\n"); + return -EINVAL; + } + di->dc_psy = power_supply_get_by_name("dc"); + if (!di->dc_psy) { + dev_err(di->dev, "[idt] no dc_psy,return\n"); + return -EINVAL; + } + di->usb_psy = power_supply_get_by_name("usb"); + if (!di->usb_psy) { + dev_err(di->dev, "[idt] no usb_psy,return\n"); + return -EINVAL; + } + di->wireless_psy = power_supply_get_by_name("wireless"); + if (!di->wireless_psy) { + dev_err(di->dev, "[idt] no wireless_psy,return\n"); + return -EINVAL; + } + di->pc_port_psy = power_supply_get_by_name("pc_port"); + if (!di->pc_port_psy) { + dev_err(di->dev, "[idt] no pc_port_psy,return\n"); + return -EINVAL; + } + return 0; +} + +int idtp9220_read(struct idtp9220_device_info *di, u16 reg, u8 *val) +{ + unsigned int temp; + int rc; + + mutex_lock(&di->read_lock); + rc = regmap_read(di->regmap, reg, &temp); + if (rc >= 0) + *val = (u8)temp; + + mutex_unlock(&di->read_lock); + return rc; +} + +int idtp9220_write(struct idtp9220_device_info *di, u16 reg, u8 val) +{ + int rc = 0; + + mutex_lock(&di->write_lock); + rc = regmap_write(di->regmap, reg, val); + if (rc < 0) + dev_err(di->dev, "[idt] idtp9220 write error: %d\n", rc); + + mutex_unlock(&di->write_lock); + return rc; +} + +int idtp9220_masked_write(struct idtp9220_device_info *di, u16 reg, u8 mask, + u8 val) +{ + int rc = 0; + + mutex_lock(&di->write_lock); + + rc = regmap_update_bits(di->regmap, reg, mask, val); + if (rc < 0) + dev_err(di->dev, "[idt] idtp9220 write mask error: %d\n", rc); + + mutex_unlock(&di->write_lock); + return rc; +} + +int idtp9220_read_buffer(struct idtp9220_device_info *di, u16 reg, u8 *buf, + u32 size) +{ + int rc = 0; + + while (size--) { + rc = di->bus.read(di, reg++, buf++); + if (rc < 0) { + dev_err(di->dev, "[idt] read buf error: %d\n", rc); + return rc; + } + } + + return rc; +} + +int idtp9220_write_buffer(struct idtp9220_device_info *di, u16 reg, u8 *buf, + u32 size) +{ + int rc = 0; + + while (size--) { + rc = di->bus.write(di, reg++, *buf++); + if (rc < 0) { + dev_err(di->dev, "[idt] write error: %d\n", rc); + return rc; + } + } + + return rc; +} + +u32 ExtractPacketSize(u8 hdr) +{ + if (hdr < 0x20) + return 1; + if (hdr < 0x80) + return (2 + ((hdr - 0x20) >> 4)); + if (hdr < 0xe0) + return (8 + ((hdr - 0x80) >> 3)); + return (20 + ((hdr - 0xe0) >> 2)); +} + +void idtp922x_clrInt(struct idtp9220_device_info *di, u8 *buf, u32 size) +{ + di->bus.write_buf(di, REG_SYS_INT_CLR, buf, size); + di->bus.write(di, REG_SSCMND, CLRINT); +} + +void reverse_clrInt(struct idtp9220_device_info *di, u8 *buf, u32 size) +{ + di->bus.write_buf(di, REG_SYS_INT_CLR, buf, size); + di->bus.write(di, REG_TX_CMD, TX_FOD_EN | TX_CLRINT); +} + +void idtp922x_enable_ext5v(struct idtp9220_device_info *di) +{ + dev_info(di->dev, "enable external 5v\n"); + di->bus.write(di, REG_EXTERNAL_5V, BIT(0)); +} + +void idtp922x_sendPkt(struct idtp9220_device_info *di, ProPkt_Type *pkt) +{ + u32 size = ExtractPacketSize(pkt->header) + 1; + di->bus.write_buf(di, REG_PROPPKT, (u8 *)pkt, + size); // write data into proprietary packet buffer + di->bus.write(di, REG_SSCMND, SENDPROPP); // send proprietary packet + + dev_info(di->dev, "pkt header: 0x%x and cmd: 0x%x\n", pkt->header, + pkt->cmd); + di->header = pkt->header; + di->cmd = pkt->cmd; +} + +void idtp922x_receivePkt(struct idtp9220_device_info *di, u8 *buf) +{ + u8 header; + int rc; + u32 size; + + di->bus.read(di, REG_BCHEADER, &header); + size = ExtractPacketSize(header) + 1; + rc = di->bus.read_buf(di, REG_BCDATA, buf, size); + if (rc < 0) + dev_err(di->dev, "[idt] read Tx data error: %d\n", rc); +} + +void idtp922x_receivePkt2(struct idtp9220_device_info *di, u8 *buf) +{ + int rc; + + rc = di->bus.read_buf(di, REG_PROPPKT, buf, 2); + if (rc < 0) + dev_err(di->dev, "[idt] read Tx data error: %d\n", rc); +} + +void idtp922x_set_adap_vol(struct idtp9220_device_info *di, u16 mv) +{ + dev_info(di->dev, "set adapter vol to %d\n", mv); + di->bus.write(di, REG_FC_VOLTAGE_L, mv & 0xff); + di->bus.write(di, REG_FC_VOLTAGE_H, (mv >> 8) & 0xff); + di->bus.write(di, REG_SSCMND, VSWITCH); +} + +void idtp922x_set_pmi_icl(struct idtp9220_device_info *di, int mA) +{ + union power_supply_propval val = { + 0, + }; + int rc; + if (!di->power_good_flag && val.intval) + return; + + rc = idtp9220_get_property_names(di); + val.intval = mA; + if (di->dt_props.wireless_by_usbin) { + if (di->usb_psy) + power_supply_set_property(di->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, + &val); + } else { + /* set bbc icl only */ + if (di->dc_psy) + power_supply_set_property(di->dc_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, + &val); + } + dev_info(di->dev, "[%s] set wls icl %d\n", __func__, val.intval); +} + +/* Adapter Type */ +/* Adapter_list = {0x00:'ADAPTER_UNKNOWN', */ +/* 0x01:'SDP 500mA', */ +/* 0x02:'CDP 1.1A', */ +/* 0x03:'DCP 1.5A', */ +/* 0x05:'QC2.0', */ +/* 0x06:'QC3.0', */ +/* 0x07:'PD',} */ +void idtp922x_request_adapter(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY18; + pkt.cmd = BC_ADAPTER_TYPE; + + idtp922x_sendPkt(di, &pkt); +} + +void idtp922x_request_uuid(struct idtp9220_device_info *di, int is_epp) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY18; + if (is_epp) + pkt.cmd = BC_TX_HWID; + else + pkt.cmd = BC_TX_COMPATIBLE_HWID; + idtp922x_sendPkt(di, &pkt); +} + +void idtp922x_get_tx_vin(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY18; + pkt.cmd = BC_READ_Vin; + + idtp922x_sendPkt(di, &pkt); +} + +void idtp922x_retry_cmd(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + pkt.header = di->header; + pkt.cmd = di->cmd; + + idtp922x_sendPkt(di, &pkt); +} + +static int idtp9220_get_vout_regulator(struct idtp9220_device_info *di) +{ + u8 vout_l, vout_h; + u16 vout; + + if (!di) + return 0; + + di->bus.read(di, REG_REGULATOR_L, &vout_l); + di->bus.read(di, REG_REGULATOR_H, &vout_h); + vout = vout_l | ((vout_h & 0xff) << 8); + dev_info(di->dev, "vout regulator get vol: %d\n", vout); + + return vout; +} + +/* + void idtp9220_set_toggle_mode(struct idtp9220_device_info *di) + { + ProPkt_Type pkt; + pkt.header = PROPRIETARY18; + pkt.cmd = BC_TX_TOGGLE; + idtp922x_sendPkt(di, &pkt); + } + */ +void idtp9220_retry_id_auth(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY38; + pkt.cmd = BC_RX_ID_AUTH; + + pkt.data[0] = 0x02; + pkt.data[1] = 0xbb; + + idtp922x_sendPkt(di, &pkt); +} + +static int idtp9220_set_vout_regulator(struct idtp9220_device_info *di, int mv) +{ + u8 vout_l, vout_h; + u16 vout; + + if (!di) + return 0; + vout_l = mv & 0xff; + vout_h = mv >> 8; + + dev_info(di->dev, "vout regulator vout_l: 0x%x and vout_h: 0x%x\n", + vout_l, vout_h); + di->bus.write(di, REG_REGULATOR_L, vout_l); + di->bus.write(di, REG_REGULATOR_H, vout_h); + + vout = vout_l | ((vout_h & 0xff) << 8); + dev_info(di->dev, "vout regulator set vol: %d\n", vout); + + return vout; +} + +#if 0 +static int idtp9220_get_vbuck(struct idtp9220_device_info *di) +{ + u8 vbuck_l, vbuck_h; + u16 vbuck_ret; + + if (!di) + return 0; + + di->bus.read(di, 0x08, &vbuck_l); + di->bus.read(di, 0x09, &vbuck_h); + vbuck_ret = vbuck_l | (vbuck_h << 8); + + return vbuck_ret; +} + +static void idtp9220_dump_regs(struct idtp9220_device_info *di) +{ + u8 VOut_l; + u8 VOut_h; + u8 VOutSet; + u8 VrectAdc; + u8 IOut_l; + u8 IOut_h; + u8 VrectTarget; + + di->bus.read(di, REG_ADC_VOUT_L, &VOut_l); + di->bus.read(di, REG_ADC_VOUT_H, &VOut_h); + di->bus.read(di, REG_VOUT_SET, &VOutSet); + di->bus.read(di, REG_ADC_VRECT, &VrectAdc); + di->bus.read(di, REG_RX_LOUT_L, &IOut_l); + di->bus.read(di, REG_RX_LOUT_H, &IOut_h); + di->bus.read(di, REG_VRECT_TAEGET, &VrectTarget); + + dev_info(di->dev, + "vout_l:%d, vout_h:%d, vout_set:%d, Vrect_adc:%d , iout_l:%d, iout_h:%d, Vrect_target:%d", + VOut_l, VOut_h, VOutSet, VrectAdc, IOut_l, IOut_h, + VrectTarget); +} +#endif + +static int idtp9220_get_vout(struct idtp9220_device_info *di) +{ + u8 vout_l, vout_h; + + if (!di) + return 0; + + di->bus.read(di, REG_ADC_VOUT_L, &vout_l); + di->bus.read(di, REG_ADC_VOUT_H, &vout_h); + di->vout = vout_l | ((vout_h & 0xf) << 8); + di->vout = di->vout * 10 * 21 * 1000 / 40950 + + ADJUST_METE_MV; //vout = val/4095*10*2.1 + dev_info(di->dev, "%s: vout is %d\n", __func__, di->vout); + return di->vout; +} + +static void idtp9220_set_vout(struct idtp9220_device_info *di, int mv) +{ + u16 val; + u8 vout_l, vout_h; + if (!di) + return; + if (!di->power_good_flag) + return; + val = (mv - 2800) * 10 / 84; + vout_l = val & 0xff; + vout_h = val >> 8; + di->bus.write(di, REG_VOUT_SET, vout_l); + di->bus.write(di, REG_VRECT_ADJ, vout_h); + dev_info(di->dev, "[idtp9220]: set vout voltage: %d %d\n", mv, val); +} + +static void idt_set_reverse_fod(struct idtp9220_device_info *di, int mw) +{ + u8 mw_l, mw_h; + if (!di) + return; + mw_l = mw & 0xff; + mw_h = mw >> 8; + di->bus.write(di, REG_FOD_LOW, mw_l); + di->bus.write(di, REG_FOD_HIGH, mw_h); + dev_info(di->dev, "set reverse fod: %d\n", mw); +} + +/* delete because idt9415 can't set rx reset +static void idtp9220_set_reset(struct idtp9220_device_info *di) +{ + if(!di) + return; + di->bus.write(di, REG_RX_RESET, 0x01); + dev_info(di->dev, "[idtp9220]: set RX reset\n"); +} +*/ + +extern char *saved_command_line; + +static int get_cmdline(struct idtp9220_device_info *di) +{ + if (strnstr(saved_command_line, + "androidboot.mode=", strlen(saved_command_line))) { + di->power_off_mode = 1; + dev_info(di->dev, "[idtp9220]: enter power off charging app\n"); + } else { + di->power_off_mode = 0; + dev_info(di->dev, "[idtp9220]: enter normal boot mode\n"); + } + return 1; +} + +#if 0 +static int get_board_version(void) +{ + char boot[5] = { '\0' }; + char *match = (char *)strnstr(saved_command_line, + "androidboot.hwlevel=", + strlen(saved_command_line)); + if (match) { + memcpy(boot, (match + strlen("androidboot.hwlevel=")), + sizeof(boot) - 1); + printk("%s: hwlevel is %s\n", __func__, boot); + if (!strncmp(boot, "P1.2", strlen("P1.2"))) + return 0; + else if (!strncmp(boot, "P1.6", strlen("P1.6"))) + return 0; + } + return 1; +} +#endif +static int idtp9220_get_tx_id(struct idtp9220_device_info *di) +{ + if (di->tx_charger_type == ADAPTER_XIAOMI_PD_40W && di->is_zm_mobil_tx) + return 1; + else + return 0; +} + +static int idtp9220_get_iout(struct idtp9220_device_info *di) +{ + u8 cout_l, cout_h; + + if (!di) + return 0; + + di->bus.read(di, REG_RX_LOUT_L, &cout_l); + di->bus.read(di, REG_RX_LOUT_H, &cout_h); + di->iout = cout_l | (cout_h << 8); + + return di->iout; +} + +static int idtp9220_get_power_profile(struct idtp9220_device_info *di) +{ + u8 mode; + int ret; + + di->bus.read(di, REG_WPC_MODE, &mode); + ret = mode & BIT(3); + dev_info(di->dev, "tx is epp ? ret is 0x%x\n", mode); + + return ret; +} + +static int idtp9220_get_freq(struct idtp9220_device_info *di) +{ + u8 data_list[2]; + + di->bus.read_buf(di, REG_FREQ_ADDR, data_list, 2); + di->f = 64 * HSCLK / (data_list[0] | (data_list[1] << 8)) / 10; + + return di->f; +} + +static int idtp9220_get_vrect(struct idtp9220_device_info *di) +{ + u8 data_list[2]; + + if (!di->power_good_flag) + return 0; + di->bus.read_buf(di, REG_ADC_VRECT, data_list, 2); + di->vrect = data_list[0] | ((data_list[1] & 0xf) << 8); + di->vrect = + di->vrect * 125 * 21 * 100 / 40950; //vrect = val/4095*12.5*2.1 + + return di->vrect; +} + +static int idtp9220_get_power_max(struct idtp9220_device_info *di) +{ + int power_max; + u8 val; + + di->bus.read(di, REG_POWER_MAX, &val); + power_max = (val / 2) * 1000; + dev_info(di->dev, "rx power max is %dmW\n", power_max); + + return power_max; +} + +/* + static int idtp9220_get_signal_strength(struct idtp9220_device_info *di) + { + u8 ss; + + di->bus.read(di, REG_SIGNAL_STRENGTH, &ss); + if(ss >= 95) + idt_signal_range = 1; + else + idt_signal_range = 0; + + dev_info(di->dev, "[idt] signal strength: %d\n", ss); + di->ss = idt_signal_range; + + return ss; + } + */ + +static void idtp9220_send_device_auth(struct idtp9220_device_info *di) +{ + di->bus.write(di, REG_SSCMND, SEND_DEVICE_AUTH); +} + +/*Factory Function*/ + +void idtp922x_sent_vout(struct idtp9220_device_info *di, u8 data_l, u8 data_h) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY38; + pkt.cmd = BC_READ_VOUT; + pkt.data[0] = data_l; + pkt.data[1] = data_h; + idtp922x_sendPkt(di, &pkt); +} + +void idtp922x_sent_iout(struct idtp9220_device_info *di, u8 data_l, u8 data_h) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY38; + pkt.cmd = BC_READ_IOUT; + pkt.data[0] = data_l; + pkt.data[1] = data_h; + idtp922x_sendPkt(di, &pkt); +} + +void idtp922x_request_low_addr(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY18; + pkt.cmd = CMD_GET_BLEMAC_2_0; + + idtp922x_sendPkt(di, &pkt); +} + +void idtp922x_request_high_addr(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY18; + pkt.cmd = CMD_GET_BLEMAC_5_3; + + idtp922x_sendPkt(di, &pkt); +} + +static void idtp9220_test_vout_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, get_vout_work.work); + int vol = 0; + u8 vout_l, vout_h; + + vol = idtp9220_get_vout(di); + dev_info(di->dev, "[Factory test] RX VOUT %d mV \n", vol); + vout_h = vol >> 8; + vout_l = vol & 0xff; + idtp922x_sent_vout(di, vout_l, vout_h); +} + +static void idtp9220_test_iout_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, get_iout_work.work); + int curr = 0; + u8 cout_l, cout_h; + + curr = idtp9220_get_iout(di); + dev_info(di->dev, " [Factory test] RX IOUT %d mA \n", curr); + cout_h = curr >> 8; + cout_l = curr & 0xff; + idtp922x_sent_iout(di, cout_l, cout_h); +} + +void idtp922x_sent_tx_mac(struct idtp9220_device_info *di) +{ + int64_t ble_mac = 0; + union power_supply_propval val = { + 0, + }; + memcpy(&ble_mac, di->mac_data, MAC_LEN); + val.int64val = ble_mac; + if (di->wireless_psy) + power_supply_set_property(di->wireless_psy, + POWER_SUPPLY_PROP_TX_MAC, &val); + else + dev_err(di->dev, "BLE mac addr get error:\n"); +} + +void idtp922x_sent_pen_mac(struct idtp9220_device_info *di) +{ + int64_t ble_mac = 0; + union power_supply_propval val = { + 0, + }; + memcpy(&ble_mac, di->pen_mac_data, MAC_LEN); + val.int64val = ble_mac; + if (di->wireless_psy) + power_supply_set_property(di->wireless_psy, + POWER_SUPPLY_PROP_PEN_MAC, &val); + else + dev_err(di->dev, "pen ble mac addr get error:\n"); +} + +void idtp922x_sent_chip_version(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + u8 chip_id_l, chip_id_h; + + di->bus.read(di, REG_CHIP_ID_L, &chip_id_l); + di->bus.read(di, REG_CHIP_ID_H, &chip_id_h); + + dev_info(di->dev, "Chip_ID: %02x%02x\n", chip_id_h, chip_id_l); + + pkt.header = PROPRIETARY38; + pkt.cmd = BC_RX_CHIP_VERSION; + pkt.data[0] = chip_id_h; + pkt.data[1] = chip_id_l; + idtp922x_sendPkt(di, &pkt); +} + +void idtp922x_sent_fw_version(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + u8 fw_app_ver[4]; + + di->bus.read_buf(di, REG_EPRFWVER_ADDR, fw_app_ver, 4); + + dev_info(di->dev, "RX FW version %x.%x.%x.%x\n", fw_app_ver[3], + fw_app_ver[2], fw_app_ver[1], fw_app_ver[0]); + + pkt.header = PROPRIETARY58; + pkt.cmd = BC_RX_FW_VERSION; + pkt.data[0] = fw_app_ver[3]; + pkt.data[1] = fw_app_ver[2]; + pkt.data[2] = fw_app_ver[1]; + pkt.data[3] = fw_app_ver[0]; + idtp922x_sendPkt(di, &pkt); +} + +void idtp922x_sent_reverse_cnf(struct idtp9220_device_info *di) +{ + ProPkt_Type pkt; + pkt.header = PROPRIETARY18; + pkt.cmd = CMD_FACOTRY_REVERSE; + idtp922x_sendPkt(di, &pkt); +} +/*Factory end*/ + +/******************************************************* + * SET GPIO STATE TO SMB FOR IGNORE DC_POWER_ON IRQ* + *******************************************************/ +/* define for reverse state of wireless charging */ +#define REVERSE_GPIO_STATE_UNSET 0 +#define REVERSE_GPIO_STATE_START 1 +#define REVERSE_GPIO_STATE_END 2 +static int idtp9220_set_reverse_gpio_state(struct idtp9220_device_info *di, + int enable) +{ + union power_supply_propval reverse_val = { + 0, + }; + + if (!di->wireless_psy) + di->wireless_psy = power_supply_get_by_name("wireless"); + + if (di->wireless_psy) { + dev_dbg(di->dev, "set_reverse_gpio_state\n", + reverse_val.intval); + if (enable) { + reverse_val.intval = REVERSE_GPIO_STATE_START; + } else { + reverse_val.intval = REVERSE_GPIO_STATE_END; + } + + power_supply_set_property(di->wireless_psy, + POWER_SUPPLY_PROP_REVERSE_GPIO_STATE, + &reverse_val); + + } else { + dev_err(di->dev, "no wireless_psy,return\n"); + return -EINVAL; + } + return 0; +} +static int +idtp9229_set_reverse_boost_enable_gpio(struct idtp9220_device_info *di, + int enable) +{ + int ret; + if (gpio_is_valid(di->dt_props.reverse_boost_enable_gpio)) { + ret = gpio_request(di->dt_props.reverse_boost_enable_gpio, + "reverse-boost-enable-gpio"); + if (ret) { + dev_err(di->dev, + "%s: unable to reverse_boost_enable_gpio [%d]\n", + __func__, + di->dt_props.reverse_boost_enable_gpio); + } + + ret = gpio_direction_output( + di->dt_props.reverse_boost_enable_gpio, !!enable); + if (ret) { + dev_err(di->dev, + "%s: cannot set direction for reverse_boost_enable_gpio gpio [%d]\n", + __func__, + di->dt_props.reverse_boost_enable_gpio); + } + gpio_free(di->dt_props.reverse_boost_enable_gpio); + } else + dev_err(di->dev, + "%s: unable to set reverse_boost_enable_gpio\n"); + + return ret; +} + +static int idtp9220_set_reverse_gpio(struct idtp9220_device_info *di, + int enable) +{ + int ret; + union power_supply_propval val = { + 0, + }; + if (!di->wireless_psy) + di->wireless_psy = power_supply_get_by_name("wireless"); + + if (!di->wireless_psy) { + dev_err(di->dev, "no wireless_psy,return\n"); + return -EINVAL; + } + + val.intval = !!enable; + + if (gpio_is_valid(di->dt_props.reverse_gpio)) { + if (enable) { + idtp9220_set_reverse_gpio_state(di, enable); + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_SW_DISABLE_DC_EN, &val); + idtp9229_set_reverse_boost_enable_gpio(di, enable); + } + ret = gpio_request(di->dt_props.reverse_gpio, + "reverse-enable-gpio"); + if (ret) { + dev_err(di->dev, + "%s: unable to request reverse gpio [%d]\n", + __func__, di->dt_props.reverse_gpio); + } + + ret = gpio_direction_output(di->dt_props.reverse_gpio, + !!enable); + if (ret) { + dev_err(di->dev, + "%s: cannot set direction for reverse enable gpio [%d]\n", + __func__, di->dt_props.reverse_gpio); + } + gpio_free(di->dt_props.reverse_gpio); + if (!enable) { + idtp9229_set_reverse_boost_enable_gpio(di, enable); + idtp9220_set_reverse_gpio_state(di, enable); + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_SW_DISABLE_DC_EN, &val); + } + + } else + dev_err(di->dev, "%s: unable to set tx_on\n"); + + di->wireless_psy = power_supply_get_by_name("wireless"); + if (!di->wireless_psy) + dev_err(di->dev, "[idt] no wireless_psy,return\n"); + else + power_supply_changed(di->wireless_psy); + return ret; +} + +static ssize_t chip_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 chip_id_l, chip_id_h, chip_rev, cust_id, status, vset; + u8 fw_otp_ver[4], fw_app_ver[4]; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + if (!di->fw_update) { + di->fw_update = true; + idtp9220_set_reverse_gpio(di, true); + msleep(100); + di->bus.read(di, REG_STATUS_L, &status); + di->bus.read(di, REG_VOUT_SET, &vset); + + di->bus.read(di, REG_CHIP_ID_L, &chip_id_l); + di->bus.read(di, REG_CHIP_ID_H, &chip_id_h); + di->bus.read(di, REG_CHIP_REV, &chip_rev); + chip_rev = chip_rev >> 4; + di->bus.read(di, REG_CTM_ID, &cust_id); + di->bus.read_buf(di, REG_OTPFWVER_ADDR, fw_otp_ver, 4); + di->bus.read_buf(di, REG_EPRFWVER_ADDR, fw_app_ver, 4); + + /* add crc verify to ensure fw version is right, + * if crc failed, return app ver to 0xFE + */ + if (!program_crc_verify(di)) { + idtp9220_set_reverse_gpio(di, false); + dev_err(di->dev, "crc verify failed, fw: %x\n", + fw_app_ver[0]); + fw_app_ver[0] = 0xFE; + di->fw_update = false; + return snprintf( + buf, PAGE_SIZE, + "chip_id_l:%02x\nchip_id_h:%02x\nchip_rev:%02x\ncust_id:%02x status:%02x vset:%02x\n otp_ver:%x.%x.%x.%x\n app_ver:%x.%x.%x.%x\n", + chip_id_l, chip_id_h, chip_rev, cust_id, status, + vset, fw_otp_ver[0], fw_otp_ver[1], + fw_otp_ver[2], fw_otp_ver[3], fw_app_ver[0], + fw_app_ver[1], fw_app_ver[2], fw_app_ver[3]); + } else { + dev_info(di->dev, "crc verify success.\n"); + } + + idtp9220_set_reverse_gpio(di, false); + di->fw_update = false; + return snprintf( + buf, PAGE_SIZE, + "chip_id_l:%02x\nchip_id_h:%02x\nchip_rev:%02x\ncust_id:%02x status:%02x vset:%02x\n otp_ver:%x.%x.%x.%x\n app_ver:%x.%x.%x.%x\n", + chip_id_l, chip_id_h, chip_rev, cust_id, status, vset, + fw_otp_ver[0], fw_otp_ver[1], fw_otp_ver[2], + fw_otp_ver[3], fw_app_ver[0], fw_app_ver[1], + fw_app_ver[2], fw_app_ver[3]); + } else { + return snprintf(buf, PAGE_SIZE, + "fw update is ongoing ,can not get version\n"); + } +} + +/* voltage limit attrs */ +static ssize_t chip_vout_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + int vout; + + vout = idtp9220_get_vout(di); + return snprintf(buf, PAGE_SIZE, "%d\n", vout); +} + +static ssize_t chip_vout_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + int index; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + index = (int)simple_strtoul(buf, NULL, 16); + /* + if ((index < VOUT_VAL_3500_MV) || (index > VOUT_VAL_5000_MV)) { + dev_err(di->dev, "Store Val %s is invalid!\n", buf); + return count; + } + */ + + idtp9220_set_vout(di, index); + + return count; +} + +static ssize_t vout_regulator_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + int vout; + + vout = idtp9220_get_vout_regulator(di); + + return snprintf(buf, PAGE_SIZE, "Vout ADC Value: %dMV\n", vout); +} + +#define VOUT_MIN_4900_MV 4900 +#define VOUT_MAX_10000_MV 10000 +static ssize_t vout_regulator_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int vout; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + vout = (int)simple_strtoul(buf, NULL, 10); + if ((vout <= VOUT_MIN_4900_MV) || (vout > VOUT_MAX_10000_MV)) { + dev_err(di->dev, "Store Val %s : %ld is invalid!\n", buf, vout); + return count; + } + idtp9220_set_vout_regulator(di, vout); + + return count; +} + +/* current attrs */ +static ssize_t chip_iout_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + int cout; + + cout = idtp9220_get_iout(di); + + return snprintf(buf, PAGE_SIZE, "%d\n", cout); +} + +static ssize_t chip_iout_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + int index; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + index = (int)simple_strtoul(buf, NULL, 10); + + if ((index < CURR_VAL_100_MA) || (index > CURR_VAL_1300_MA)) { + dev_err(di->dev, "Store Val %s is invalid", buf); + return count; + } + + di->bus.write(di, REG_ILIM_SET, index); + + return count; +} + +static ssize_t chip_freq_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + int f; + + f = idtp9220_get_freq(di); + + return snprintf(buf, sizeof(buf), "Output Current: %dkHz\n", f); +} + +static void idtp9220_charging_info(struct idtp9220_device_info *di) +{ + if (!di) + return; + + idtp9220_get_vout(di); + idtp9220_get_iout(di); + idtp9220_get_freq(di); + idtp9220_get_vrect(di); + + dev_info(di->dev, + "%s:Vout:%dmV,Iout:%dmA,Freq:%dKHz,Vrect:%dmV,SS:%d\n", + __func__, di->vout, di->iout, di->f, di->vrect, di->ss); +} + +static int idtp9220_reverse_charge_enable(struct idtp9220_device_info *di) +{ + u8 mode = 0; + int ret = 0, i = 0; + int fod_set = REVERSE_FOD; + + if (!di->fw_update) { + di->bus.read(di, REG_WPC_MODE, &mode); + dev_info(di->dev, "wpc mode(0x004D): 0x%x\n", mode); + ret = mode & BIT(0); + if (ret) { + dev_info(di->dev, + "rx mode, can not enable reverse charge\n"); + di->is_reverse_mode = 0; + di->is_reverse_chg = 1; + idtp9220_set_reverse_enable(di, false); + schedule_delayed_work(&di->reverse_sent_state_work, 0); + return 0; + } + } + + if (!di->fw_update) { + /* set reverse fod to REVERSE_FOD */ + idt_set_reverse_fod(di, fod_set); + for (i = 0; i < 3; i++) { + di->bus.write(di, REG_TX_CMD, TX_EN | TX_FOD_EN); + msleep(50); + di->bus.read(di, REG_TX_DATA, &mode); + dev_info(di->dev, "tx data(0078): 0x%x\n", mode); + if (mode & BIT(0)) { + di->is_reverse_mode = 1; + dev_info(di->dev, "start reverse charging\n"); + break; + } else { + dev_err(di->dev, + "idt set reverse charge failed, retry: %d\n", + i); + } + } + + if (i < 3) { + dev_info(di->dev, "reverse charging start success\n"); + return 1; + } else { + dev_info(di->dev, "reverse charging failed start\n"); + idtp9220_set_reverse_enable(di, false); + return 0; + } + } else { + return 0; + } +} + +static int idtp9220_set_reverse_enable(struct idtp9220_device_info *di, + int enable) +{ + int ret = 0; + union power_supply_propval wk_val = { + 0, + }; + + di->wireless_psy = power_supply_get_by_name("wireless"); + if (!di->wireless_psy) { + dev_err(di->dev, "[idt] no wireless_psy,return\n"); + if (!enable) { + di->is_reverse_mode = 0; + cancel_delayed_work(&di->reverse_chg_state_work); + cancel_delayed_work(&di->reverse_dping_state_work); + cancel_delayed_work(&di->reverse_ept_type_work); + idtp9220_set_reverse_gpio(di, false); + } + goto out; + } + + if (di->fw_update) { + goto out; + } + idtp9220_set_reverse_gpio(di, enable); + + if (enable) { + di->is_boost_mode = 1; + ret = idtp9220_reverse_charge_enable(di); + if (ret) { + if (di->wireless_psy) { + wk_val.intval = 1; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, + &wk_val); + } + alarm_start_relative( + &di->reverse_dping_alarm, + ms_to_ktime(REVERSE_DPING_CHECK_DELAY_MS)); + } + } else { + di->is_boost_mode = 0; + dev_info(di->dev, "disable reverse charging for wireless\n"); + if (di->wireless_psy) { + wk_val.intval = 0; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, &wk_val); + } + di->is_reverse_mode = 0; + di->reverse_pen_soc = 255; + cancel_delayed_work(&di->reverse_chg_state_work); + cancel_delayed_work(&di->reverse_dping_state_work); + cancel_delayed_work(&di->reverse_ept_type_work); + cancel_delayed_work(&di->reverse_chg_work); + + ret = alarm_cancel(&di->reverse_dping_alarm); + if (ret < 0) + dev_err(di->dev, + "Couldn't cancel reverse_dping_alarm\n"); + + ret = alarm_cancel(&di->reverse_chg_alarm); + if (ret < 0) + dev_err(di->dev, "Couldn't cancel reverse_chg_alarm\n"); + pm_relax(di->dev); + } +out: + return ret; +} + +/* reverse enable attrs */ +static ssize_t reverse_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + if (gpio_is_valid(di->dt_props.reverse_gpio)) + ret = gpio_get_value(di->dt_props.reverse_gpio); + else { + dev_err(di->dev, "%s: reverse gpio not provided\n", __func__); + ret = -1; + } + + dev_info(di->dev, "reverse enable gpio: %d\n", ret); + + return snprintf(buf, sizeof(buf), "reverse enable: %d\n", ret); +} + +static ssize_t reverse_gpio_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret, enable; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + ret = (int)simple_strtoul(buf, NULL, 10); + enable = !!ret; + + idtp9220_set_reverse_gpio(di, enable); + + return count; +} + +/*ovp cntl*/ +static ssize_t ovp_gpio_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + if (gpio_is_valid(di->dt_props.rx_ovp_ctl_gpio)) + ret = gpio_get_value(di->dt_props.rx_ovp_ctl_gpio); + else { + dev_err(di->dev, "%s: ovp cntl gpio not provided\n", __func__); + ret = -1; + } + + dev_info(di->dev, "ovp enable gpio: %d\n", ret); + + return scnprintf(buf, PAGE_SIZE, "ovp enable: %d\n", ret); +} + +static ssize_t ovp_gpio_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret, enable; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + ret = (int)simple_strtoul(buf, NULL, 10); + enable = !!ret; + + if (gpio_is_valid(di->dt_props.rx_ovp_ctl_gpio)) { + ret = gpio_request(di->dt_props.rx_ovp_ctl_gpio, + "ovp-enable-gpio"); + if (ret) { + dev_err(di->dev, + "%s: unable to request ovp_en_gpio [%d]\n", + __func__, di->dt_props.rx_ovp_ctl_gpio); + } + + ret = gpio_direction_output(di->dt_props.rx_ovp_ctl_gpio, + enable); + if (ret) { + dev_err(di->dev, + "%s: cannot set direction for ovp_en_gpio [%d]\n", + __func__, di->dt_props.rx_ovp_ctl_gpio); + } + gpio_free(di->dt_props.rx_ovp_ctl_gpio); + } else + dev_err(di->dev, "%s: unable to get ovp_en_gpio\n"); + + return count; +} + +static ssize_t reverse_gpio_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + if (gpio_is_valid(di->dt_props.reverse_gpio)) + ret = gpio_get_value(di->dt_props.reverse_gpio); + else { + dev_err(di->dev, "%s: reverse gpio not provided\n", __func__); + ret = -1; + } + + dev_info(di->dev, "reverse enable gpio: %d\n", ret); + + return scnprintf(buf, PAGE_SIZE, "reverse enable: %d\n", ret); +} + +static ssize_t reverse_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret, enable; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + ret = (int)simple_strtoul(buf, NULL, 10); + enable = !!ret; + di->is_reverse_chg = 0; + schedule_delayed_work(&di->reverse_sent_state_work, 0); + idtp9220_set_reverse_enable(di, enable); + return count; +} + +/* chip enable attrs */ +static ssize_t chip_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0; + + return snprintf(buf, PAGE_SIZE, "Chip enable: %d\n", !ret); + + /* + if (gpio_is_valid(di->dt_props.enable_gpio)) + ret = gpio_get_value(di->dt_props.enable_gpio); + else { + dev_err(di->dev, "%s: sleep gpio not provided\n", __func__); + ret = -1; + } + + dev_info(di->dev, "chip enable gpio: %d\n", ret); + + return snprintf(buf, PAGE_SIZE, "Chip enable: %d\n", !ret); +*/ +} + +static ssize_t chip_die_temp_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + u8 buff[2] = { 0 }; + int die_temp = 0; + ret = di->bus.read_buf(di, REG_RX_DIE_TEMP, buff, 2); + if (!ret) { + die_temp = buff[0] | ((buff[1] & 0x0f) << 8); + die_temp = (die_temp - 1350) * 83 / 444 - 273; + } + return snprintf(buf, PAGE_SIZE, "%d\n", die_temp); +} + +static enum alarmtimer_restart reverse_chg_alarm_cb(struct alarm *alarm, + ktime_t now) +{ + struct idtp9220_device_info *di = container_of( + alarm, struct idtp9220_device_info, reverse_chg_alarm); + + dev_info(di->dev, " Reverse Chg Alarm Triggered %lld\n", + ktime_to_ms(now)); + + /* Atomic context, cannot use voter */ + pm_stay_awake(di->dev); + + schedule_delayed_work(&di->reverse_chg_state_work, 0); + + return ALARMTIMER_NORESTART; +} + +static enum alarmtimer_restart reverse_dping_alarm_cb(struct alarm *alarm, + ktime_t now) +{ + struct idtp9220_device_info *di = container_of( + alarm, struct idtp9220_device_info, reverse_dping_alarm); + + dev_info(di->dev, "Reverse Dping Alarm Triggered %lld\n", + ktime_to_ms(now)); + + /* Atomic context, cannot use voter */ + pm_stay_awake(di->dev); + schedule_delayed_work(&di->reverse_dping_state_work, 0); + + return ALARMTIMER_NORESTART; +} + +static enum alarmtimer_restart reverse_test_ready_alarm_cb(struct alarm *alarm, + ktime_t now) +{ + struct idtp9220_device_info *di = container_of( + alarm, struct idtp9220_device_info, reverse_test_ready_alarm); + + dev_info( + di->dev, + "[ factory reverse test ] reverse_rest_ready_alarm Triggered\n"); + + /* Atomic context, cannot use voter */ + pm_stay_awake(di->dev); + schedule_delayed_work(&di->reverse_test_state_work, 0); + di->wait_for_reverse_test = false; + + return ALARMTIMER_NORESTART; +} + +static int idtp9220_set_present(struct idtp9220_device_info *di, int enable) +{ + int ret = 0; + + dev_info(di->dev, "[idtp] dc plug %s\n", enable ? "in" : "out"); + if (enable) { + di->dcin_present = true; + di->ss = 1; + } else { + schedule_delayed_work(&di->oob_set_ept_work, + msecs_to_jiffies(10)); + di->status = NORMAL_MODE; + di->count_9v = 0; + di->count_5v = 0; + di->exchange = 0; + di->dcin_present = false; + idt_signal_range = 2; + di->ss = 2; + di->epp = 0; + di->last_vin = 0; + di->last_icl = 0; + di->is_car_tx = 0; + di->is_voice_box_tx = 0; + di->is_zm_20w_tx = 0; + di->is_pan_tx = 0; + di->is_ble_tx = 0; + di->vout_on = 0; + di->is_zm_mobil_tx = 0; + di->power_off_mode = 0; + di->is_epp_qc3 = 0; + di->bpp_vout_rise = 0; + di->is_f1_tx = 0; + di->last_bpp_vout = 0; + di->last_bpp_icl = 0; + di->last_qc2_vout = 0; + di->last_qc2_icl = 0; + di->last_qc3_vout = 0; + di->last_qc3_icl = 0; + di->fw_update = false; + di->tx_charger_type = ADAPTER_NONE; + di->adapter_voltage = 0; + di->first_rise_flag = false; + di->enable_ext5v = false; + di->vswitch_ok = false; + di->bpp_icl = 0; + di->otg_insert = 0; + di->disable_cp = false; + di->bpp_break = false; + di->cp_regulator_done = false; + cancel_delayed_work(&di->rx_vout_work); + cancel_delayed_work(&di->chg_monitor_work); + cancel_delayed_work(&di->cmd_check_work); + cancel_delayed_work(&di->oob_set_cep_work); + cancel_delayed_work(&di->rx_vout_cp_close_work); + /* clear OOB messages */ + schedule_delayed_work(&di->oob_clean_work, + msecs_to_jiffies(100)); + } + + return ret; +} + +static int idtp9220_set_enable_mode(struct idtp9220_device_info *di, int enable) +{ + int ret = 0; + + return ret; + /* + printk("idtp9220_set_enable_mode: enable:%d\n", enable); + if (gpio_is_valid(di->dt_props.enable_gpio)) { + ret = gpio_request(di->dt_props.enable_gpio, "idt-enable-gpio"); + if (ret) { + dev_err(di->dev, + "%s: unable to request idt enable gpio [%d]\n", + __func__, di->dt_props.enable_gpio); + } + + ret = gpio_direction_output(di->dt_props.enable_gpio, !enable); + if (ret) { + dev_err(di->dev, + "%s: cannot set direction for idt enable gpio [%d]\n", + __func__, di->dt_props.enable_gpio); + } + di->gpio_enable_val = gpio_get_value(di->dt_props.enable_gpio); + pr_info("idtp9415 enable gpio val is :%d\n", di->gpio_enable_val); + gpio_free(di->dt_props.enable_gpio); + } +*/ +} + +static ssize_t chip_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + int ret, enable; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + ret = (int)simple_strtoul(buf, NULL, 10); + enable = !!ret; + + idtp9220_set_enable_mode(di, enable); + + return count; +} + +/*print the result of fw program*/ +static ssize_t chip_fw_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret = 0; + int fw_ret = 0; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + if (di->fw_update) { + dev_err(&client->dev, + "[idtp9415] [%s] Firmware Update is on going!\n", + __func__); + return snprintf(buf, PAGE_SIZE, + "Firmware Update is on going!\n"); + } + pm_stay_awake(di->dev); + di->fw_update = true; + + idtp9220_set_reverse_gpio(di, true); + msleep(100); + + if (!program_fw(di, 0x0000, idt_firmware, sizeof(idt_firmware))) { + dev_err(&client->dev, "program fw failed.\n"); + fw_ret = 0; + } else { + dev_err(&client->dev, "program fw sucess.\n"); + di->fw_version = FW_VERSION; + fw_ret = 1; + } + idtp9220_set_reverse_gpio(di, false); + msleep(100); + + idtp9220_set_reverse_gpio(di, true); + msleep(100); + + /* start crc verify */ + if (!program_crc_verify(di)) { + dev_err(&client->dev, "crc verify failed.\n"); + ret = 0; + } else { + dev_err(&client->dev, "crc verify success.\n"); + ret = 1; + } + + idtp9220_set_reverse_gpio(di, false); + di->fw_update = false; + pm_relax(di->dev); + if (ret && fw_ret) + return snprintf(buf, PAGE_SIZE, "Firmware Update:Success\n"); + else + return snprintf(buf, PAGE_SIZE, "Firmware Update:Failed\n"); +} + +static DEVICE_ATTR(chip_enable, S_IWUSR | S_IRUGO, chip_enable_show, + chip_enable_store); +static DEVICE_ATTR(reverse_enable, S_IWUSR | S_IRUGO, reverse_enable_show, + reverse_enable_store); +static DEVICE_ATTR(chip_version, S_IRUGO, chip_version_show, NULL); +static DEVICE_ATTR(chip_vout, S_IWUSR | S_IRUGO, chip_vout_show, + chip_vout_store); +static DEVICE_ATTR(chip_iout, S_IWUSR | S_IRUGO, chip_iout_show, + chip_iout_store); +static DEVICE_ATTR(chip_freq, S_IRUGO, chip_freq_show, NULL); +static DEVICE_ATTR(vout_regulator, S_IWUSR | S_IRUGO, vout_regulator_show, + vout_regulator_store); +static DEVICE_ATTR(chip_fw, S_IWUSR | S_IRUGO, chip_fw_show, NULL); +static DEVICE_ATTR(reverse_set_gpio, S_IWUSR | S_IRUGO, reverse_gpio_show, + reverse_gpio_store); +static DEVICE_ATTR(ovp_set_gpio, S_IWUSR | S_IRUGO, ovp_gpio_show, + ovp_gpio_store); +static DEVICE_ATTR(chip_die_temp, S_IWUSR | S_IRUGO, chip_die_temp_show, NULL); + +static struct attribute *sysfs_attrs[] = { + &dev_attr_chip_version.attr, &dev_attr_chip_vout.attr, + &dev_attr_chip_iout.attr, &dev_attr_chip_freq.attr, + &dev_attr_chip_enable.attr, &dev_attr_reverse_enable.attr, + &dev_attr_vout_regulator.attr, &dev_attr_chip_fw.attr, + &dev_attr_reverse_set_gpio.attr, &dev_attr_ovp_set_gpio.attr, + &dev_attr_chip_die_temp.attr, NULL, +}; + +static const struct attribute_group sysfs_group_attrs = { + .attrs = sysfs_attrs, +}; + +#if 1 +static int program_bootloader(struct idtp9220_device_info *di) +{ + int i, rc = 0; + int len; + + len = sizeof(bootloader_data); + + for (i = 0; i < len; i++) { + rc = di->bus.write(di, 0x0800 + i, bootloader_data[i]); + if (rc) + return rc; + } + + return 0; +} + +static int program_crc_verify(struct idtp9220_device_info *di) +{ + u8 val; + int retry_cnt = 0; + + /* unlock system clock */ + if (di->bus.write(di, 0x3000, 0x5a)) + return false; + /* configure clocks and timing */ + if (di->bus.write(di, 0x3004, 0x00)) + return false; + if (di->bus.write(di, 0x3008, 0x09)) + return false; + if (di->bus.write(di, 0x300C, 0x05)) + return false; + if (di->bus.write(di, 0x300D, 0x1D)) + return false; + if (di->bus.write(di, 0x304C, 0x00)) + return false; + if (di->bus.write(di, 0x304D, 0x00)) + return false; + /* pause the processor and enable MTP */ + if (di->bus.write(di, 0x3040, 0x11)) + return false; + mdelay(10); + /* halt the mpu */ + if (di->bus.write(di, 0x3040, 0x10)) + return false; + mdelay(10); + + /* load the mtp downloader program */ + if (program_bootloader(di)) + return false; + + /* init the program structure and remap RAM */ + if (di->bus.write(di, 0x0400, 0x00)) + return false; + if (di->bus.write(di, 0x3048, 0xD0)) + return false; + /* reset mpu and run mtp downloader program, ignoreNAK */ + di->bus.write(di, 0x3040, 0x80); + mdelay(100); + + /* configure MTP crc check utility */ + /* step1 load start address */ + if (di->bus.write(di, 0x402, 0x00)) + return false; + if (di->bus.write(di, 0x403, 0x00)) + return false; + /* step2 load mtp data size 0x6000 */ + if (di->bus.write(di, 0x404, 0x00)) + return false; + if (di->bus.write(di, 0x405, 0x60)) + return false; + /* step3 write crc valuve */ + if (di->bus.write(di, 0x406, CRC_VERIFY_LOW)) + return false; + if (di->bus.write(di, 0x407, CRC_VERIFY_HIGH)) + return false; + /* start crc check */ + if (di->bus.write(di, 0x400, 0x11)) { + dev_err(di->dev, "on OTP buffer CRC validation error\n"); + return false; + } + + do { + mdelay(100); + di->bus.read(di, 0x400, &val); + if ((val & 1) != 0) + dev_info(di->dev, "Programming crc check val:%02x\n", + val); + if (retry_cnt++ > 50) + break; + } while ((val & 1) != 0); //check if crc program finishes "OK" + + if (retry_cnt > 50) { + dev_err(di->dev, "Programming CRC finished failed retry:%d\n", + retry_cnt); + return false; + } else { + di->bus.read(di, 0x401, &val); + if (val != 2) { + dev_err(di->dev, "crc check failed status:%d\n", val); + return false; + } else { + dev_info(di->dev, "crc check success!\n"); + return true; + } + } +} + +int program_fw(struct idtp9220_device_info *di, u16 destAddr, u8 *src, u32 size) +{ + int i, j; + u8 data = 0; + //u8 data_array[512]; + + // === Step-1 === + // Transfer 9220 boot loader code "OTPBootloader" to 9220 SRAM + // - Setup 9220 registers before transferring the boot loader code + // - Transfer the boot loader code to 9220 SRAM + // - Reset 9220 => 9220 M0 runs the boot loader + // + di->bus.read(di, 0x5870, &data); + printk(KERN_EMERG "0x5870 %s:%d :%02x\n", __func__, __LINE__, data); + di->bus.read(di, 0x5874, &data); + printk(KERN_EMERG "0x5874 %s:%d :%02x\n", __func__, __LINE__, data); + // configure the system + if (di->bus.write(di, 0x3000, 0x5a)) + return false; + if (di->bus.write(di, 0x3004, 0x00)) + return false; + if (di->bus.write(di, 0x3008, 0x09)) + return false; + if (di->bus.write(di, 0x300C, 0x05)) + return false; + if (di->bus.write(di, 0x300D, 0x1D)) + return false; + if (di->bus.write(di, 0x3040, 0x11)) + return false; + if (di->bus.write(di, 0x3040, 0x10)) + return false; + if (program_bootloader(di)) + return false; + + di->bus.write(di, 0x0400, 0x00); + if (di->bus.write(di, 0x3048, 0xD0)) + return false; + + /* ignoreNAK */ + di->bus.write(di, 0x3040, 0x80); + mdelay(100); + printk(KERN_EMERG "%s:%d\n", __func__, __LINE__); + +#if 0 + for (i = 0; i < 512; i++) { + di->bus.read(di, 0x1c00 + i, data_array[i]); + if (data_array[i] != bootloader_data[i]) { + printk(KERN_EMERG + "MAXUEYUE bootloader check err data[%d]:%02x != boot[%d]:%02x.\n", + i, data_array[i], i, bootloader_data[i]); + return 1; + } + printk(KERN_EMERG "%02x ", data_array[i]); + if (i + 1 % 16 == 0) + printk(KERN_EMERG "\n"); + } +#endif + // + // === Step-2 === + // Program OTP image data to 9220 OTP memory + // + for (i = destAddr; i < destAddr + size; + i += 128) { // program pages of 128 bytes + // + // Build a packet + // + char sBuf[136]; // 136=8+128 --- 8-byte header plus 128-byte data + u16 StartAddr = (u16)i; + u16 CheckSum = StartAddr; + u16 CodeLength = 128; + int retry_cnt = 0; + + memset(sBuf, 0, 136); + + //(1) Copy the 128 bytes of the OTP image data to the packet data buffer + // Array.Copy(srcData, i + srcOffs, sBuf, 8, 128);// Copy 128 bytes from srcData (starting at i+srcOffs) + memcpy(sBuf + 8, src, + 128); // Copy 128 bytes from srcData (starting at i+srcOffs) + src += 128; + // to sBuf (starting at 8) + //srcData --- source array + //i + srcOffs --- start index in source array + //sBuf --- destination array + //8 --- start index in destination array + //128 --- elements to copy + + /* + //(2) Calculate the packet checksum of the 128-byte data, StartAddr, and CodeLength + for (j = 127; j >= 0; j--) { // find the 1st non zero value byte from the end of the sBuf[] buffer + if (sBuf[j + 8] != 0) + break; + else + CodeLength--; + } + if (CodeLength == 0) + continue; // skip programming if nothing to program + */ + + for (j = 127; j >= 0; j--) + CheckSum += sBuf[j + 8]; // add the nonzero values + CheckSum += CodeLength; // finish calculation of the check sum + + //(3) Fill up StartAddr, CodeLength, CheckSum of the current packet. + memcpy(sBuf + 2, &StartAddr, 2); + memcpy(sBuf + 4, &CodeLength, 2); + memcpy(sBuf + 6, &CheckSum, 2); + + // + // Send the current packet to 9220 SRAM via I2C + // + + // read status is guaranteed to be != 1 at this point + for (j = 0; j < CodeLength + 8; j++) { + if (di->bus.write(di, 0x400 + j, sBuf[j])) { + printk("on writing to OTP buffer error"); + return false; + } + } + + // + // Write 1 to the Status in the SRAM. This informs the 9220 to start programming the new packet + // from SRAM to OTP memory + // + if (di->bus.write(di, 0x400, 1)) { + printk("on OTP buffer validation error"); + return false; + } + + // + // Wait for 9220 bootloader to complete programming the current packet image data from SRAM to the OTP. + // The boot loader will update the Status in the SRAM as follows: + // Status: + // "0" - reset value (from AP) + // "1" - buffer validated / busy (from AP) + // "2" - finish "OK" (from the boot loader) + // "4" - programming error (from the boot loader) + // "8" - wrong check sum (from the boot loader) + // "16"- programming not possible (try to write "0" to bit location already programmed to "1") + // (from the boot loader) + + // DateTime startT = DateTime.Now; + do { + mdelay(100); + di->bus.read(di, 0x400, sBuf); + if (sBuf[0] == 1) { + printk("Programming OTP buffer status sBuf:%02x i:%d\n", + sBuf[0], i); + } + if (retry_cnt++ > 5) + break; + } while (sBuf[0] == 1); //check if OTP programming finishes "OK" + + if (retry_cnt > 5) { + printk("Programming OTP buffer retry failed :%d\n", + retry_cnt); + return false; + } else { + di->bus.read(di, 0x401, sBuf); + if (sBuf[0] != 2) { + printk("buffer write to OTP returned status:%d :%s\n", + sBuf[0], "X4"); + return false; + } else { + printk("Program OTP 0x%04x\n", i); + } + } + + /* + if (sBuf[0] != 2) { // not OK + printk("buffer write to OTP returned status:%d :%s\n" , sBuf[0], "X4"); + return false; + } else { + printk("Program OTP 0x%04x\n", i); + } + */ + } + + // === Step-3 === + // Restore system (Need to reset or power cycle 9220 to run the OTP code) + // + if (di->bus.write(di, 0x3000, 0x5a)) + return false; // write key + if (di->bus.write(di, 0x3048, 0x00)) + return false; // remove code remapping + //if (!di->bus.write(0x3040, 0x80)) return false; // reset M0 + return true; +} +#endif + +static int idtp9220_parse_dt(struct idtp9220_device_info *di) +{ + struct device_node *node = di->dev->of_node; + + if (!node) { + dev_err(di->dev, "device tree node missing\n"); + return -EINVAL; + } + + di->dt_props.irq_gpio = of_get_named_gpio(node, "idt,irq", 0); + if ((!gpio_is_valid(di->dt_props.irq_gpio))) + return -EINVAL; + + di->dt_props.hall3_gpio = of_get_named_gpio(node, "hall,int3", 0); + if ((!gpio_is_valid(di->dt_props.hall3_gpio))) + return -EINVAL; + + di->dt_props.hall4_gpio = of_get_named_gpio(node, "hall,int4", 0); + if ((!gpio_is_valid(di->dt_props.hall4_gpio))) + return -EINVAL; + + di->dt_props.reverse_gpio = + of_get_named_gpio(node, "idt,reverse-enable", 0); + if ((!gpio_is_valid(di->dt_props.reverse_gpio))) + return -EINVAL; + + di->dt_props.wpc_det_gpio = of_get_named_gpio(node, "idt,wpc-det", 0); + if ((!gpio_is_valid(di->dt_props.wpc_det_gpio))) + return -EINVAL; + /* + di->dt_props.enable_gpio = of_get_named_gpio(node, "idt,rx-sleep", 0); + if ((!gpio_is_valid(di->dt_props.enable_gpio))) { + dev_err(di->dev, "get enable_gpio fault\n"); + return -EINVAL; + } +*/ + di->dt_props.reverse_boost_enable_gpio = + of_get_named_gpio(node, "idt,reverse-booset-enable", 0); + if ((!gpio_is_valid(di->dt_props.reverse_boost_enable_gpio))) { + dev_err(di->dev, "get reverse_boost_enable_gpio fault\n"); + return -EINVAL; + } + + di->dt_props.wireless_by_usbin = + of_property_read_bool(node, "mi,wireless-by-usbin"); + + di->dt_props.only_idt_on_cmi = + of_property_read_bool(node, "mi,only-idt-on-cmi"); + + di->dt_props.is_urd_device = + of_property_read_bool(node, "mi,urd-device"); + + return 0; +} + +static int idtp9220_gpio_init(struct idtp9220_device_info *di) +{ + int ret = 0; + int irqn = 0; + int wpc_irq = 0; + + di->idt_pinctrl = devm_pinctrl_get(di->dev); + if (IS_ERR_OR_NULL(di->idt_pinctrl)) { + dev_err(di->dev, "No pinctrl config specified\n"); + ret = PTR_ERR(di->dev); + return ret; + } + di->idt_gpio_active = + pinctrl_lookup_state(di->idt_pinctrl, "idt_active"); + if (IS_ERR_OR_NULL(di->idt_gpio_active)) { + dev_err(di->dev, "No active config specified\n"); + ret = PTR_ERR(di->idt_gpio_active); + return ret; + } + di->idt_gpio_suspend = + pinctrl_lookup_state(di->idt_pinctrl, "idt_suspend"); + if (IS_ERR_OR_NULL(di->idt_gpio_suspend)) { + dev_err(di->dev, "No suspend config specified\n"); + ret = PTR_ERR(di->idt_gpio_suspend); + return ret; + } + + ret = pinctrl_select_state(di->idt_pinctrl, di->idt_gpio_active); + if (ret < 0) { + dev_err(di->dev, "fail to select pinctrl active rc=%d\n", ret); + return ret; + } + + if (gpio_is_valid(di->dt_props.irq_gpio)) { + irqn = gpio_to_irq(di->dt_props.irq_gpio); + if (irqn < 0) { + ret = irqn; + goto err_irq_gpio; + } + di->irq = irqn; + } else { + dev_err(di->dev, "%s: irq gpio not provided\n", __func__); + goto err_irq_gpio; + } + + if (gpio_is_valid(di->dt_props.hall3_gpio)) { + irqn = gpio_to_irq(di->dt_props.hall3_gpio); + if (irqn < 0) { + ret = irqn; + goto err_irq_gpio; + } + di->hall3_irq = irqn; + } else { + dev_err(di->dev, "%s:hall3 irq gpio not provided\n", __func__); + goto err_hall3_irq_gpio; + } + + if (gpio_is_valid(di->dt_props.hall4_gpio)) { + irqn = gpio_to_irq(di->dt_props.hall4_gpio); + if (irqn < 0) { + ret = irqn; + goto err_irq_gpio; + } + di->hall4_irq = irqn; + } else { + dev_err(di->dev, "%s:hall4 irq gpio not provided\n", __func__); + goto err_hall4_irq_gpio; + } + + if (gpio_is_valid(di->dt_props.wpc_det_gpio)) { + wpc_irq = gpio_to_irq(di->dt_props.wpc_det_gpio); + if (wpc_irq < 0) { + ret = wpc_irq; + goto err_wpc_irq; + } + di->wpc_irq = wpc_irq; + } else { + dev_err(di->dev, "%s: wpc irq gpio not provided\n", __func__); + goto err_wpc_irq; + } + + if (ret) + goto err_wpc_irq; + +err_wpc_irq: + gpio_free(di->dt_props.wpc_det_gpio); +err_hall4_irq_gpio: + gpio_free(di->dt_props.hall4_gpio); +err_hall3_irq_gpio: + gpio_free(di->dt_props.hall3_gpio); +err_irq_gpio: + gpio_free(di->dt_props.irq_gpio); + return ret; +} + +static bool need_irq_cleared(struct idtp9220_device_info *di) +{ + u8 int_buf[4]; + u32 int_val; + int rc = -1; + + rc = di->bus.read_buf(di, REG_SYS_INT, int_buf, 4); + if (rc < 0) { + dev_err(di->dev, "%s: read int state error\n", __func__); + return true; + } + int_val = int_buf[0] | (int_buf[1] << 8) | (int_buf[2] << 16) | + (int_buf[3] << 24); + if (int_val != 0) { + dev_info(di->dev, "irq not clear right: 0x%08x\n", int_val); + return true; + } + + if (gpio_is_valid(di->dt_props.irq_gpio)) + rc = gpio_get_value(di->dt_props.irq_gpio); + else { + dev_err(di->dev, "%s: irq gpio not provided\n", __func__); + rc = -1; + } + if (!rc) { + dev_info(di->dev, "irq low, need clear int: %d\n", rc); + return true; + } + return false; +} + +static bool reverse_need_irq_cleared(struct idtp9220_device_info *di, u32 val) +{ + u8 int_buf[4]; + u32 int_val; + int rc = -1; + + rc = di->bus.read_buf(di, REG_SYS_INT, int_buf, 4); + if (rc < 0) { + dev_err(di->dev, "%s: read int state error\n", __func__); + return false; + } + int_val = int_buf[0] | (int_buf[1] << 8) | (int_buf[2] << 16) | + (int_buf[3] << 24); + if (int_val && (int_val == val)) { + dev_info(di->dev, "irq clear wrong, retry: 0x%08x\n", int_val); + return true; + } + + return false; +} + +#define VBUCK_QC_VOL 7000 +#define VBUCK_FULL_VOL 7000 +#define VBUCK_DEFAULT_VOL 5500 +#define ADAPTER_DEFAULT_VOL 6000 +#define ADAPTER_BPP_QC_VOL 10000 +#define ADAPTER_BPP_QC2_VOL 6500 +#define ADAPTER_EPP_QC3_VOL 11000 +#define ADAPTER_BPP_LIMIT_VOL 6500 +#define ADAPTER_VOUT_LIMIT_VOL 7000 +#define BPP_VOL_THRESHOLD 8000 +#define ADAPTER_BPP_VOL 5000 +#define ADAPTER_EPP_MI_VOL 15000 +#define EPP_VOL_THRESHOLD 12000 +#define EPP_VOL_LIM_THRESHOLD 13000 +#define BPP_VOL_LIM_THRESHOLD 10500 +#define CHARGING_PERIOD_S 10 +#define TAPER_CURR_Limit 950000 + +static void idtp9220_monitor_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, chg_monitor_work.work); + + idtp9220_charging_info(di); + + idtp9220_set_charging_param(di); + + schedule_delayed_work(&di->chg_monitor_work, CHARGING_PERIOD_S * HZ); +} + +static void idtp9220_rx_vout_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, rx_vout_work.work); + + idtp9220_set_charging_param(di); +} + +static void idtp9220_dc_check_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, dc_check_work.work); + + if (di->vout_on) { + di->ss = 1; + dev_info(di->dev, "dcin present, quit dc check work\n"); + return; + } else { + di->ss = 0; + dev_info(di->dev, "dcin no present, continue dc check work\n"); + schedule_delayed_work(&di->dc_check_work, + msecs_to_jiffies(2500)); + } +} + +static void idtp9220_chg_detect_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, chg_detect_work.work); + + union power_supply_propval val = { + 0, + }; + union power_supply_propval pc_val = { + 0, + }; + int rc; + bool valid_typec_mode = false; + + dev_info(di->dev, "[idt] enter %s\n", __func__); + + rc = idtp9220_get_property_names(di); + if (rc < 0) + return; + /*set idtp9220 into sleep mode when usbin */ + power_supply_get_property(di->usb_psy, POWER_SUPPLY_PROP_TYPEC_MODE, + &val); + power_supply_get_property(di->pc_port_psy, POWER_SUPPLY_PROP_ONLINE, + &pc_val); + if (val.intval >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT && + val.intval <= POWER_SUPPLY_TYPEC_SOURCE_HIGH) + valid_typec_mode = true; + + if (valid_typec_mode || pc_val.intval) { + dev_info(di->dev, + "typec_mode: %d or pc online: %d,set chip disable\n", + val.intval, pc_val.intval); + //idtp9220_set_enable_mode(di, false); + //schedule_delayed_work(&di->fw_download_work, 1 * HZ); + return; + } + + /* reset rx for bootup charging */ + idtp9220_set_enable_mode(di, false); + msleep(10); + idtp9220_set_enable_mode(di, true); +} + +static void idtp9220_bpp_connect_load_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, bpp_connect_load_work.work); + dev_info(di->dev, "[idt] %s: \n", __func__); + idtp922x_set_pmi_icl(di, BPP_DEFAULT_CURRENT / 3); + if (di->bpp_break || !di->power_good_flag) + return; + msleep(300); + idtp922x_set_pmi_icl(di, (BPP_DEFAULT_CURRENT / 3) * 2); + if (di->bpp_break || !di->power_good_flag) + return; + msleep(300); + idtp922x_set_pmi_icl(di, BPP_DEFAULT_CURRENT); +} + +static void idtp9220_epp_connect_load_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, epp_connect_load_work.work); + int dc_load_curr = 0; + + if (di->power_max < 10000) { + dc_load_curr = (di->power_max - 1000) / 11 * 1000; + + } else { + dc_load_curr = EPP_DEFAULT_BYPASS_CURRENT; + } + + idtp922x_set_pmi_icl(di, dc_load_curr); +} + +static void idtp9220_cmd_check_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, cmd_check_work.work); + + dev_info(di->dev, "[idt] %s: \n", __func__); + idtp922x_get_tx_vin(di); + if (di->power_off_mode) { + schedule_delayed_work(&di->load_fod_param_work, + msecs_to_jiffies(500)); + schedule_delayed_work(&di->vout_regulator_work, + msecs_to_jiffies(10)); + } +} + +static void idtp9220_initial_tx_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, initial_tx_work.work); + int ret = 0; + u8 buf[2] = { 0 }; + u16 int_val = 0; + + ret = idtp9220_get_power_profile(di); + if (ret) { + ret = di->bus.read_buf(di, REG_TX_TYPE, buf, 2); + if (ret < 0) + dev_err(di->dev, "read tx type error: %d\n", ret); + else { + int_val = buf[0] | (buf[1] << 8); + dev_info(di->dev, "tx type: 0x%04x\n", int_val); + } + } + + /* check dc present to judge device skewing */ + if (int_val == 0x0059) { + dev_info(di->dev, "mophie tx, start check dc with 8s\n"); + schedule_delayed_work(&di->dc_check_work, + msecs_to_jiffies(8000)); + } else + schedule_delayed_work(&di->dc_check_work, + msecs_to_jiffies(2500)); +} + +static int idt_get_effective_fcc(struct idtp9220_device_info *di) +{ + int effective_fcc_val = 0; + + if (!di->fcc_votable) + di->fcc_votable = find_votable("FCC"); + + if (!di->fcc_votable) + return -EINVAL; + + effective_fcc_val = get_effective_result(di->fcc_votable); + effective_fcc_val = effective_fcc_val / 1000; + dev_info(di->dev, "effective_fcc: %d\n", effective_fcc_val); + return effective_fcc_val; +} + +#define VOICE_THERMAL_FCC_HOT_MA 500 +#define VOICE_THERMAL_FCC_WARM_MA 1300 +#define VOICE_TEMP_HOT_UP_LIMIT 402 +#define VOICE_TEMP_HOT_DOWN_LIMIT 400 +#define VOICE_TEMP_WARM_UP_LIMIT 375 +#define VOICE_TEMP_WARM_DOWN_LIMIT 367 +#define VOICE_MAX_ICL_UA 1500000 +static void idt_voice_tx_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, voice_tx_work.work); + + int soc = 0, batt_sts = 0, dc_level = 0, batt_temp = 0; + int adapter_vol = ADAPTER_EPP_MI_VOL; + int icl_curr = VOICE_MAX_ICL_UA; + int effective_fcc = 0; + bool vout_change = false; + union power_supply_propval val = { + 0, + }; + union power_supply_propval wk_val = { + 0, + }; + int vout = 0; + di->bpp_break = 1; + if (di->batt_psy) { + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_STATUS, &val); + batt_sts = val.intval; + + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &val); + soc = val.intval; + + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_DC_THERMAL_LEVELS, + &val); + dc_level = val.intval; + + power_supply_get_property(di->batt_psy, POWER_SUPPLY_PROP_TEMP, + &val); + batt_temp = val.intval; + } + + dev_info(di->dev, "soc:%d, dc_level:%d, bat_status:%d, batt_temp: %d\n", + soc, dc_level, batt_sts, batt_temp); + + switch (di->status) { + case NORMAL_MODE: + if (soc >= EPP_TAPER_SOC) + di->status = TAPER_MODE; + break; + case TAPER_MODE: + dev_info(di->dev, "[voice]taper mode set Vin 11V\n"); + if (soc == FULL_SOC && batt_sts == POWER_SUPPLY_STATUS_FULL) + di->status = FULL_MODE; + else if (soc < 95) + di->status = NORMAL_MODE; + break; + case FULL_MODE: + dev_info(di->dev, "[voice]charge full set Vin 11V\n"); + adapter_vol = EPP_VOL_THRESHOLD; + icl_curr = SCREEN_OFF_FUL_CURRENT; + + if (batt_sts == POWER_SUPPLY_STATUS_CHARGING) { + dev_info(di->dev, + "[voice]full mode -> recharge mode\n"); + di->status = RECHG_MODE; + icl_curr = DC_LOW_CURRENT; + } + break; + case RECHG_MODE: + if (batt_sts == POWER_SUPPLY_STATUS_FULL) { + dev_info(di->dev, + "[voice]recharge mode -> full mode\n"); + di->status = FULL_MODE; + icl_curr = SCREEN_OFF_FUL_CURRENT; + adapter_vol = EPP_VOL_THRESHOLD; + if (di->wireless_psy) { + wk_val.intval = 0; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, + &wk_val); + } + break; + } + + dev_info(di->dev, "[voice]recharge mode set icl to 350mA\n"); + adapter_vol = EPP_VOL_THRESHOLD; + icl_curr = DC_LOW_CURRENT; + + if (di->wireless_psy) { + wk_val.intval = 1; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, &wk_val); + } + break; + default: + break; + } + effective_fcc = idt_get_effective_fcc(di); + /* + if (batt_temp >= VOICE_TEMP_HOT_UP_LIMIT) { + dev_info(di->dev, "[voice]Tbat limit fcc 1A\n"); + effective_fcc = idt_get_effective_fcc(di); + if (di->fcc_votable) { + effective_fcc = VOICE_THERMAL_FCC_HOT_MA; + vote(di->fcc_votable, VOICE_LIMIT_FCC_1A_VOTER, + true, effective_fcc * 1000); + } + } else if (batt_temp < VOICE_TEMP_HOT_DOWN_LIMIT) { + if (di->fcc_votable) + vote(di->fcc_votable, VOICE_LIMIT_FCC_1A_VOTER, + false, 0); + } + + if (batt_temp >= VOICE_TEMP_WARM_UP_LIMIT) { + dev_info(di->dev, "[voice]Tbat limit fcc 3.2A\n"); + effective_fcc = idt_get_effective_fcc(di); + if (di->fcc_votable) { + effective_fcc = VOICE_THERMAL_FCC_WARM_MA; + vote(di->fcc_votable, VOICE_LIMIT_FCC_VOTER, + true, effective_fcc * 1000); + } + } else if (batt_temp < VOICE_TEMP_WARM_DOWN_LIMIT) { + if (di->fcc_votable) + vote(di->fcc_votable, VOICE_LIMIT_FCC_VOTER, + false, 0); + } +*/ + if (dc_level) { + di->disable_cp = true; + /* disable cp charger */ + if (di->wireless_psy) { + val.intval = 0; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, &val); + } + dev_info(di->dev, "[voice]Disable cp, dc_level:%d\n", dc_level); + } + + if (di->cp_regulator_done) + adapter_vol = EPP_VOL_THRESHOLD; + + if (!di->enable_ext5v) { + di->enable_ext5v = true; + idtp922x_enable_ext5v(di); + } + + if (adapter_vol > 0 && adapter_vol != di->last_vin) { + if ((adapter_vol == ADAPTER_EPP_MI_VOL) && + !di->first_rise_flag) { + di->disable_cp = false; + di->first_rise_flag = true; + idtp922x_set_adap_vol(di, adapter_vol); + di->vswitch_ok = false; + msleep(110); + } else if ((adapter_vol == ADAPTER_EPP_MI_VOL) && + di->first_rise_flag) { + di->disable_cp = false; + idtp9220_set_vout(di, adapter_vol); + msleep(110); + schedule_delayed_work(&di->load_fod_param_work, + msecs_to_jiffies(500)); + schedule_delayed_work(&di->vout_regulator_work, + msecs_to_jiffies(400)); + } else if (adapter_vol == EPP_VOL_THRESHOLD) { + vout = idtp9220_get_vout(di); + while (vout > EPP_VOL_THRESHOLD) { + vout = vout - 1000; + idtp9220_set_vout(di, vout); + msleep(200); + } + idtp9220_set_vout(di, EPP_VOL_THRESHOLD); + schedule_delayed_work(&di->load_fod_param_work, + msecs_to_jiffies(500)); + } + vout_change = true; + di->last_vin = adapter_vol; + } + + if ((icl_curr > 0 && icl_curr != di->last_icl) || vout_change) { + di->last_icl = icl_curr; + idtp922x_set_pmi_icl(di, icl_curr); + msleep(100); + } + + dev_info( + di->dev, + "di->status:0x%x,adapter_vol=%d,icl_curr=%d,last_vin=%d,last_icl=%d, bq_dis:%d\n", + di->status, adapter_vol, icl_curr, di->last_vin, di->last_icl, + di->disable_cp); + + return; +} + +#define PAN_BBC_ICL_MA 1300000 +static void idt_pan_tx_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, pan_tx_work.work); + + int soc = 0, batt_sts = 0, dc_level = 0; + int adapter_vol = ADAPTER_EPP_MI_VOL; + int icl_curr = DC_PAN_CURRENT_UA; + bool vout_change = false; + union power_supply_propval val = { + 0, + }; + union power_supply_propval wk_val = { + 0, + }; + int vout = 0; + di->bpp_break = 1; + if (di->batt_psy) { + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_STATUS, &val); + batt_sts = val.intval; + + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &val); + soc = val.intval; + + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_DC_THERMAL_LEVELS, + &val); + dc_level = val.intval; + } + + dev_info(di->dev, "soc:%d, dc_level:%d, bat_status:%d\n", soc, dc_level, + batt_sts); + + switch (di->status) { + case NORMAL_MODE: + if (soc >= FULL_SOC) + di->status = TAPER_MODE; + break; + case TAPER_MODE: + if (soc == FULL_SOC && batt_sts == POWER_SUPPLY_STATUS_FULL) + di->status = FULL_MODE; + else if (soc < FULL_SOC - 1) + di->status = NORMAL_MODE; + break; + case FULL_MODE: + dev_info(di->dev, "[pan]charge full set Vin 12V\n"); + adapter_vol = EPP_VOL_THRESHOLD; + icl_curr = SCREEN_OFF_FUL_CURRENT; + + if (batt_sts == POWER_SUPPLY_STATUS_CHARGING) { + dev_info(di->dev, "[pan]full mode -> recharge mode\n"); + di->status = RECHG_MODE; + icl_curr = DC_LOW_CURRENT; + } + break; + case RECHG_MODE: + if (batt_sts == POWER_SUPPLY_STATUS_FULL) { + dev_info(di->dev, "recharge mode -> full mode\n"); + di->status = FULL_MODE; + icl_curr = SCREEN_OFF_FUL_CURRENT; + adapter_vol = EPP_VOL_THRESHOLD; + if (di->wireless_psy) { + wk_val.intval = 0; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, + &wk_val); + } + break; + } + + dev_info(di->dev, "recharge mode set icl to 350mA\n"); + adapter_vol = EPP_VOL_THRESHOLD; + icl_curr = DC_LOW_CURRENT; + + if (di->wireless_psy) { + wk_val.intval = 1; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, &wk_val); + } + break; + default: + break; + } + + if (dc_level) { + dev_info(di->dev, "Disable bq, dc_level:%d\n", dc_level); + di->disable_cp = true; + if (di->wireless_psy) { + val.intval = 0; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, &val); + } + + if (di->cp_regulator_done) { + adapter_vol = EPP_VOL_THRESHOLD; + icl_curr = PAN_BBC_MAX_ICL_MA; + } + } + + if (!di->enable_ext5v) { + di->enable_ext5v = true; + idtp922x_enable_ext5v(di); + } + + if (adapter_vol > 0 && adapter_vol != di->last_vin) { + if ((adapter_vol == ADAPTER_EPP_MI_VOL) && + !di->first_rise_flag) { + di->disable_cp = false; + di->first_rise_flag = true; + idtp922x_set_adap_vol(di, adapter_vol); + di->vswitch_ok = false; + msleep(110); + } else if ((adapter_vol == ADAPTER_EPP_MI_VOL) && + di->first_rise_flag) { + di->disable_cp = false; + idtp9220_set_vout(di, adapter_vol); + msleep(110); + schedule_delayed_work(&di->load_fod_param_work, + msecs_to_jiffies(500)); + schedule_delayed_work(&di->vout_regulator_work, + msecs_to_jiffies(400)); + } else if (adapter_vol == EPP_VOL_THRESHOLD) { + vout = idtp9220_get_vout(di); + while (vout > EPP_VOL_THRESHOLD) { + vout = vout - 1000; + idtp9220_set_vout(di, vout); + msleep(200); + } + idtp9220_set_vout(di, EPP_VOL_THRESHOLD); + schedule_delayed_work(&di->load_fod_param_work, + msecs_to_jiffies(500)); + } + vout_change = true; + di->last_vin = adapter_vol; + } + + if ((icl_curr > 0 && icl_curr != di->last_icl) || vout_change) { + di->last_icl = icl_curr; + idtp922x_set_pmi_icl(di, icl_curr); + msleep(100); + } + + dev_info( + di->dev, + "di->status:0x%x,adapter_vol=%d,icl_curr=%d,last_vin=%d,last_icl=%d, bq_dis:%d\n", + di->status, adapter_vol, icl_curr, di->last_vin, di->last_icl, + di->disable_cp); + + return; +} + +static void idtp9220_bpp_e5_tx_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, bpp_e5_tx_work.work); + int icl_curr = BPP_QC_7W_CURRENT, adapter_vol = ADAPTER_BPP_QC_VOL; + int soc = 0, batt_sts = 0, health = 0; + int icl_setted = 0; + union power_supply_propval val = { + 0, + }; + union power_supply_propval wk_val = { + 0, + }; + + if (di->batt_psy) { + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_STATUS, &val); + batt_sts = val.intval; + + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &val); + soc = val.intval; + + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_HEALTH, &val); + health = val.intval; + } + + if (di->tx_charger_type == ADAPTER_QC2) + icl_curr = 750000; + + if (di->iout < LIMIT_BPP_IOUT && di->exchange == EXCHANGE_9V) { + di->count_5v++; + di->count_9v = 0; + } else if (di->iout > LIMIT_BPP_IOUT && di->exchange == EXCHANGE_5V) { + di->count_9v++; + di->count_5v = 0; + } else { + di->count_5v = 0; + di->count_9v = 0; + } + /* + * 9V-->5V check 6 times + * 5V-->9v check 3 times + */ + if (di->count_5v > ICL_EXCHANGE_COUNT || + (di->exchange == EXCHANGE_5V && + di->count_9v <= ICL_EXCHANGE_COUNT - 3)) { + dev_info(di->dev, "iout less than 400mA ,set vout to 5.5v\n"); + adapter_vol = ADAPTER_DEFAULT_VOL; + icl_curr = DC_BPP_CURRENT; + di->exchange = EXCHANGE_5V; + } else if (di->count_9v > (ICL_EXCHANGE_COUNT - 3)) + di->exchange = EXCHANGE_9V; + + if (soc > 90) + icl_curr = DC_BPP_CURRENT; + + switch (di->status) { + case NORMAL_MODE: + if (soc >= EPP_TAPER_SOC) { + di->status = TAPER_MODE; + adapter_vol = ADAPTER_DEFAULT_VOL; + icl_curr = min(DC_SDP_CURRENT, icl_curr); + } + break; + case TAPER_MODE: + dev_info(di->dev, "[bpp] taper mode set vout to 5.5v\n"); + adapter_vol = ADAPTER_DEFAULT_VOL; + icl_curr = min(DC_SDP_CURRENT, icl_curr); + + if (soc == FULL_SOC && batt_sts == POWER_SUPPLY_STATUS_FULL) + di->status = FULL_MODE; + else if (soc < EPP_TAPER_SOC - 1) + di->status = NORMAL_MODE; + break; + case FULL_MODE: + dev_info(di->dev, "[bpp] charge full set vout to 5.5v\n"); + adapter_vol = ADAPTER_DEFAULT_VOL; + icl_curr = SCREEN_OFF_FUL_CURRENT; + + if (batt_sts == POWER_SUPPLY_STATUS_CHARGING) { + di->status = RECHG_MODE; + icl_curr = DC_LOW_CURRENT; + } + break; + case RECHG_MODE: + dev_info(di->dev, "[bpp] recharge mode set icl to 360mA\n"); + adapter_vol = ADAPTER_DEFAULT_VOL; + icl_curr = DC_LOW_CURRENT; + + if (soc < EPP_TAPER_SOC - 1) + di->status = NORMAL_MODE; + else if (batt_sts == POWER_SUPPLY_STATUS_FULL) + di->status = FULL_MODE; + + if (di->wireless_psy) { + wk_val.intval = 1; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, &wk_val); + } + break; + default: + break; + } + + switch (health) { + case POWER_SUPPLY_HEALTH_GOOD: + break; + case POWER_SUPPLY_HEALTH_COOL: + break; + case POWER_SUPPLY_HEALTH_WARM: + adapter_vol = ADAPTER_DEFAULT_VOL; + icl_curr = min(DC_SDP_CURRENT, icl_curr); + break; + case POWER_SUPPLY_HEALTH_OVERVOLTAGE: + adapter_vol = ADAPTER_DEFAULT_VOL; + icl_curr = min(SCREEN_OFF_FUL_CURRENT, icl_curr); + break; + case POWER_SUPPLY_HEALTH_COLD: + case POWER_SUPPLY_HEALTH_HOT: + adapter_vol = ADAPTER_DEFAULT_VOL; + icl_curr = SCREEN_OFF_FUL_CURRENT; + break; + default: + break; + } + + if (adapter_vol != di->last_bpp_vout) { + dev_info(di->dev, "bpp_10w, set new vout: %d, last_vout: %d\n", + adapter_vol, di->last_bpp_vout); + if (adapter_vol > BPP_VOL_THRESHOLD) { + idtp922x_set_adap_vol(di, adapter_vol); + idtp922x_enable_ext5v(di); + msleep(400); + } else { + idtp922x_set_pmi_icl(di, 100000); + msleep(100); + idtp922x_set_adap_vol(di, adapter_vol); + msleep(2000); + idtp922x_set_pmi_icl(di, DC_SDP_CURRENT); + msleep(100); + icl_setted = 1; + } + di->last_bpp_vout = adapter_vol; + } + + if ((icl_curr != di->last_bpp_icl) || (icl_setted)) { + dev_info(di->dev, "bpp_10w, set new icl: %d, last_icl: %d\n", + icl_curr, di->last_bpp_icl); + di->last_bpp_icl = icl_curr; + di->bpp_break = true; + cancel_delayed_work_sync(&di->bpp_connect_load_work); + if ((adapter_vol == ADAPTER_BPP_QC_VOL) && + (!di->bpp_vout_rise)) { + dev_info(di->dev, + "bpp_10w, vout lower than 8v, set 500mA\n"); + icl_curr = min(DC_SDP_CURRENT, icl_curr); + } + idtp922x_set_pmi_icl(di, icl_curr); + } +} + +static void idtp9220_qc2_f1_tx_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, qc2_f1_tx_work.work); + int soc = 0, batt_sts = 0; + int vout = ADAPTER_BPP_QC2_VOL; + int dc_icl = DC_QC2_CURRENT; + union power_supply_propval val = { + 0, + }; + + if (di->batt_psy) { + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_STATUS, &val); + batt_sts = val.intval; + + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &val); + soc = val.intval; + } + + if (soc >= 95) + dc_icl = DC_DCP_CURRENT; + if (soc == 100) + dc_icl = DC_LOW_CURRENT; + + if (soc == FULL_SOC && batt_sts == POWER_SUPPLY_STATUS_FULL) { + dev_info(di->dev, + "qc2+f1_tx, full mode set vout to 8V,icl to 250mA\n"); + dc_icl = SCREEN_OFF_FUL_CURRENT; + } + + if (vout != di->last_qc2_vout) { + dev_info(di->dev, + "qc2+f1_tx, set new vout: %d, last_vout: %d\n", vout, + di->last_qc2_vout); + di->last_qc2_vout = vout; + idtp9220_set_vout(di, vout); + msleep(200); + if (vout == ADAPTER_BPP_QC_VOL) + idtp922x_enable_ext5v(di); + } + + if (dc_icl != di->last_qc2_icl) { + dev_info(di->dev, "qc2+f1_tx, set new icl: %d, last_icl: %d\n", + dc_icl, di->last_qc2_icl); + di->last_qc2_icl = dc_icl; + idtp922x_set_pmi_icl(di, dc_icl); + } +} + +static void idtp9220_qc3_epp_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, qc3_epp_work.work); + int soc = 0, batt_sts = 0; + int adapter_vol = ADAPTER_EPP_QC3_VOL; + int dc_icl = DC_EPP_QC3_CURRENT; + union power_supply_propval val = { + 0, + }; + + if (di->batt_psy) { + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_STATUS, &val); + batt_sts = val.intval; + + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &val); + soc = val.intval; + } + + if (soc >= 97) + dc_icl = DC_BPP_CURRENT; + + if (soc == 100) + dc_icl = DC_SDP_CURRENT; + + if (soc == FULL_SOC && batt_sts == POWER_SUPPLY_STATUS_FULL) + dc_icl = SCREEN_OFF_FUL_CURRENT; + + if (adapter_vol != di->last_qc3_vout) { + dev_info(di->dev, "qc3 epp, set new vout: %d, last_vout: %d\n", + adapter_vol, di->last_qc3_vout); + di->last_qc3_vout = adapter_vol; + idtp9220_set_vout(di, adapter_vol); + msleep(200); + if (adapter_vol == ADAPTER_EPP_QC3_VOL) + idtp922x_enable_ext5v(di); + } + + if (dc_icl != di->last_qc3_icl) { + dev_info(di->dev, "qc3_epp, set new icl: %d, last_icl: %d\n", + dc_icl, di->last_qc3_icl); + di->last_qc3_icl = dc_icl; + idtp922x_set_pmi_icl(di, dc_icl); + msleep(100); + } +} + +static void idtp9220_vout_regulator_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, vout_regulator_work.work); + + union power_supply_propval val = { + 0, + }; + int ret; + int vinc = 0; + int soc = 0; + int dc_level = 0; + int need_cp = true; + printk("idtp9220_vout_regulator_work\n"); + + if (di->batt_psy) { + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &val); + soc = val.intval; + + power_supply_get_property(di->batt_psy, + POWER_SUPPLY_PROP_DC_THERMAL_LEVELS, + &val); + dc_level = val.intval; + } + + if (di) + idtp9220_get_vout(di); + else + return; + + if (di->epp) + vinc = (di->vout > EPP_VOL_THRESHOLD) ? 1 : 0; + else + vinc = (di->vout > BPP_VOL_THRESHOLD) ? 1 : 0; + + if (vinc && !di->epp) { + di->bpp_vout_rise = 1; + goto out; + } else if (!vinc && !di->epp) { + di->bpp_vout_rise = 0; + goto out; + } + /* for pan and voice tx, do not open cp while thermal high */ + if ((di->is_pan_tx || di->is_voice_box_tx) && dc_level) { + need_cp = false; + } + + if (di->epp && vinc && soc < TAPER_SOC - 1 && need_cp) { + dev_info(di->dev, "%s: open charge pump by wireless\n", + __func__); + ret = idtp9220_get_property_names(di); + if (di->wireless_psy) { + val.intval = 1; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, &val); + } else { + dev_err(di->dev, "[idt] no wireless psy\n"); + } + } else { + dev_info(di->dev, "%s: close charge pump by wireless\n", + __func__); + if (di->wireless_psy) { + val.intval = 0; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, &val); + } + // set vout to 14.2v + msleep(200); + idtp9220_set_vout(di, CP_CLOSE_VOUT_MV); + } + +out: + dev_info(di->dev, "%s: epp=%d vout= %d\n", __func__, di->epp, di->vout); + return; +} + +static int fod_over_write(struct idtp9220_device_info *di, int mode) +{ + int ret = 0; + + switch (mode) { + case EPP_PLUS_VOL: + if (di->is_zm_20w_tx) { + di->bus.write(di, 0x68, 0x98); + di->bus.write(di, 0x69, 0x46); + di->bus.write(di, 0x6A, 0x98); + di->bus.write(di, 0x6B, 0x46); + di->bus.write(di, 0x6C, 0x87); + di->bus.write(di, 0x6D, 0x69); + di->bus.write(di, 0x6E, 0x87); + di->bus.write(di, 0x6F, 0x69); + di->bus.write(di, 0x70, 0x95); + di->bus.write(di, 0x71, 0x1b); + di->bus.write(di, 0x72, 0x87); + di->bus.write(di, 0x73, 0x7D); + } else if (!di->is_f1_tx) { + di->bus.write(di, 0x68, 0x98); + di->bus.write(di, 0x69, 0x46); + di->bus.write(di, 0x6A, 0x98); + di->bus.write(di, 0x6B, 0x46); + di->bus.write(di, 0x6C, 0x87); + di->bus.write(di, 0x6D, 0x69); + di->bus.write(di, 0x6E, 0x87); + di->bus.write(di, 0x6F, 0x69); + di->bus.write(di, 0x70, 0x89); + di->bus.write(di, 0x71, 0x1b); + di->bus.write(di, 0x72, 0x87); + di->bus.write(di, 0x73, 0x7D); + } else { + di->bus.write(di, 0x68, 0x82); + di->bus.write(di, 0x69, 0x78); + di->bus.write(di, 0x6A, 0x82); + di->bus.write(di, 0x6B, 0x78); + di->bus.write(di, 0x6C, 0x80); + di->bus.write(di, 0x6D, 0x7d); + di->bus.write(di, 0x6E, 0x80); + di->bus.write(di, 0x6F, 0x7d); + di->bus.write(di, 0x70, 0x89); + di->bus.write(di, 0x71, 0x43); + di->bus.write(di, 0x72, 0x88); + di->bus.write(di, 0x73, 0x7f); + } + ret = 1; + break; + case EPP_BASE_VOL: + di->bus.write(di, 0x68, 0x93); + di->bus.write(di, 0x69, 0x44); + di->bus.write(di, 0x6A, 0x93); + di->bus.write(di, 0x6B, 0x44); + di->bus.write(di, 0x6C, 0x96); + di->bus.write(di, 0x6D, 0x17); + di->bus.write(di, 0x6E, 0x96); + di->bus.write(di, 0x6F, 0x17); + di->bus.write(di, 0x70, 0x95); + di->bus.write(di, 0x71, 0x16); + di->bus.write(di, 0x72, 0x91); + di->bus.write(di, 0x73, 0x39); + /* + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + */ + ret = 1; + break; + case BPP_PLUS_VOL: + di->bus.write(di, 0x68, 0x9C); + di->bus.write(di, 0x69, 0x29); + di->bus.write(di, 0x6A, 0x57); + di->bus.write(di, 0x6B, 0x7B); + di->bus.write(di, 0x6C, 0x57); + di->bus.write(di, 0x6D, 0x7B); + di->bus.write(di, 0x6E, 0x96); + di->bus.write(di, 0x6F, 0x00); + di->bus.write(di, 0x70, 0x93); + di->bus.write(di, 0x71, 0x0A); + di->bus.write(di, 0x72, 0x93); + di->bus.write(di, 0x73, 0x0A); + /* + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + */ + ret = 1; + break; + case FULL_VOL: + di->bus.write(di, 0x68, 0x9C); + di->bus.write(di, 0x69, 0x29); + di->bus.write(di, 0x6A, 0x57); + di->bus.write(di, 0x6B, 0x7B); + di->bus.write(di, 0x6C, 0x57); + di->bus.write(di, 0x6D, 0x7B); + di->bus.write(di, 0x6E, 0x9E); + di->bus.write(di, 0x6F, 0x08); + di->bus.write(di, 0x70, 0x9D); + di->bus.write(di, 0x71, 0x05); + di->bus.write(di, 0x72, 0x96); + di->bus.write(di, 0x73, 0x28); + /* + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + di->bus.write(di, 0xFF, 0x7F); + */ + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +static int fod_param_verity(struct idtp9220_device_info *di, int mode) +{ + u8 data_l = 0, data_h = 0; + int ret = 0; + + di->bus.read(di, 0x72, &data_l); + di->bus.read(di, 0x73, &data_h); + + switch (mode) { + case EPP_PLUS_VOL: + if (data_l == 0x97 && data_h == 0xD1) + ret = 1; + else + ret = 0; + break; + case EPP_BASE_VOL: + if (data_l == 0x91 && data_h == 0x39) + ret = 1; + else + ret = 0; + break; + case BPP_PLUS_VOL: + if (data_l == 0x93 && data_h == 0x14) + ret = 1; + else + ret = 0; + break; + case FULL_VOL: + if (data_l == 0x96 && data_h == 0x28) + ret = 1; + else + ret = 0; + break; + default: + ret = 0; + break; + } + + return ret; +} + +static void reverse_chg_sent_state_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = + container_of(work, struct idtp9220_device_info, + reverse_sent_state_work.work); + union power_supply_propval val = { + 0, + }; + + if (di->wireless_psy) { + if (di->is_reverse_chg == 4) + idt_get_reverse_soc(di); + val.intval = di->is_reverse_chg; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_REVERSE_PEN_CHG_STATE, &val); + power_supply_changed(di->wireless_psy); + dev_info(di->dev, "uevent: %d for reverse charging state\n", + di->is_reverse_chg); + } else + dev_err(di->dev, "get wls property error\n"); +} + +static void reverse_chg_state_set_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, reverse_chg_state_work.work); + + dev_info(di->dev, "no rx found and disable reverse charging\n"); + + mutex_lock(&di->reverse_op_lock); + idtp9220_set_reverse_enable(di, false); + di->is_reverse_mode = 0; + di->is_reverse_chg = 1; + mutex_unlock(&di->reverse_op_lock); + schedule_delayed_work(&di->reverse_sent_state_work, 0); + + return; +} + +static void reverse_dping_state_set_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = + container_of(work, struct idtp9220_device_info, + reverse_dping_state_work.work); + + dev_info(di->dev, "tx mode fault and disable reverse charging\n"); + + mutex_lock(&di->reverse_op_lock); + idtp9220_set_reverse_enable(di, false); + di->is_reverse_mode = 0; + di->is_reverse_chg = 2; + mutex_unlock(&di->reverse_op_lock); + schedule_delayed_work(&di->reverse_sent_state_work, 0); + + return; +} +static void reverse_test_state_set_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = + container_of(work, struct idtp9220_device_info, + reverse_test_state_work.work); + + dev_info( + di->dev, + "[ factory reverse test ]tx mode fault and disable reverse charging\n"); + + mutex_lock(&di->reverse_op_lock); + idtp9220_set_reverse_enable(di, false); + di->is_reverse_mode = 0; + di->is_reverse_chg = 2; + mutex_unlock(&di->reverse_op_lock); + schedule_delayed_work(&di->reverse_sent_state_work, 0); + pm_relax(di->dev); + return; +} + +static void reverse_ept_type_get_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, reverse_ept_type_work.work); + int rc; + u8 buf[2] = { 0 }; + u16 ept_val = 0; + + rc = di->bus.read_buf(di, REG_EPT_TYPE, buf, 2); + if (rc < 0) + dev_err(di->dev, "read tx ept type error: %d\n", rc); + else { + ept_val = buf[0] | (buf[1] << 8); + dev_info(di->dev, "tx ept type: 0x%04x\n", ept_val); + if (ept_val) { + if ((ept_val & EPT_FOD) || (ept_val & EPT_CMD) || + (ept_val & EPT_OCP) || (ept_val & EPT_OVP) || + (ept_val & EPT_LVP) || (ept_val & EPT_OTP) || + (ept_val & EPT_POCP)) { + dev_info( + di->dev, + "TX mode in ept and disable reverse charging\n"); + idtp9220_set_reverse_enable(di, false); + di->is_reverse_mode = 0; + di->is_reverse_chg = 2; + schedule_delayed_work( + &di->reverse_sent_state_work, 0); + } else if (ept_val & EPT_CEP_TIMEOUT) { + dev_info(di->dev, "recheck ping state\n"); + di->is_reverse_chg = 5; + schedule_delayed_work( + &di->reverse_sent_state_work, 0); + } + } + } + + return; +} + +static void idtp9220_load_fod_param_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, load_fod_param_work.work); + int fod_param = 0; + int ret = 0, val = 0; + + if (!di->vout) + idtp9220_get_vout(di); + + if (di->vout > EPP_VOL_LIM_THRESHOLD) + fod_param = EPP_PLUS_VOL; + else if (di->vout > BPP_VOL_LIM_THRESHOLD && + di->vout < EPP_VOL_LIM_THRESHOLD) + fod_param = EPP_BASE_VOL; + else if (di->vout > BPP_VOL_THRESHOLD && + di->vout < BPP_VOL_LIM_THRESHOLD) + fod_param = BPP_PLUS_VOL; + else if (di->vout > 0 && di->vout < BPP_VOL_THRESHOLD) + fod_param = FULL_VOL; + + val = fod_over_write(di, fod_param); + msleep(50); + if (val) { + ret = fod_param_verity(di, fod_param); + if (!ret) + fod_over_write(di, fod_param); + } else + fod_over_write(di, fod_param); + + dev_info(di->dev, "[idt] %d mV fod load %s\n", di->vout, + (ret ? "success" : "fail")); + return; +} + +static int idtp9220_get_charging_current(struct idtp9220_device_info *di) +{ + switch (di->tx_charger_type) { + case ADAPTER_XIAOMI_QC3: + case ADAPTER_XIAOMI_PD: + case ADAPTER_ZIMI_CAR_POWER: + return ICL_CP_2SBATT_20W_MA; + case ADAPTER_XIAOMI_PD_40W: + case ADAPTER_VOICE_BOX: + return ICL_CP_2SBATT_30W_MA; + case ADAPTER_XIAOMI_PD_45W: + case ADAPTER_XIAOMI_PD_60W: + return ICL_CP_2SBATT_40W_MA; + default: + break; + } + return DC_QC3_CURRENT; +} +static int idtp9220_get_taper_charging_current(struct idtp9220_device_info *di) +{ + switch (di->tx_charger_type) { + case ADAPTER_XIAOMI_QC3: + case ADAPTER_XIAOMI_PD: + case ADAPTER_ZIMI_CAR_POWER: + return ICL_TAPER_2SBATT_20W_MA; + case ADAPTER_XIAOMI_PD_40W: + case ADAPTER_VOICE_BOX: + return ICL_TAPER_2SBATT_30W_MA; + case ADAPTER_XIAOMI_PD_45W: + case ADAPTER_XIAOMI_PD_60W: + return ICL_TAPER_2SBATT_40W_MA; + default: + break; + } + return DC_QC3_CURRENT; +} + +static void idtp9220_set_charging_param(struct idtp9220_device_info *di) +{ + int soc = 0, health = 0, batt_sts = 0; + int adapter_vol = 0, icl_curr = 0; + int cur_now = 0, vol_now = 0, vin_inc = 0; + bool vout_change = false; + union power_supply_propval val = { + 0, + }; + union power_supply_propval wk_val = { + 0, + }; + int vout = 0; + + switch (di->tx_charger_type) { + case ADAPTER_QC2: + adapter_vol = ADAPTER_BPP_QC2_VOL; //6.5V + di->bpp_break = 1; + icl_curr = DC_QC2_CURRENT; //1A + break; + case ADAPTER_QC3: + if (!di->epp) { + adapter_vol = ADAPTER_BPP_QC_VOL; + icl_curr = DC_QC3_CURRENT; //1A + } else { + di->is_epp_qc3 = 1; + adapter_vol = ADAPTER_EPP_QC3_VOL; //11V + icl_curr = DC_EPP_QC3_CURRENT; + } + break; + case ADAPTER_PD: + if (di->epp) { + adapter_vol = ADAPTER_EPP_QC3_VOL; + icl_curr = DC_EPP_QC3_CURRENT; + } else { + adapter_vol = ADAPTER_DEFAULT_VOL; //6V + icl_curr = DC_PD_CURRENT; //800mA + } + break; + case ADAPTER_AUTH_FAILED: + if (di->epp) { + adapter_vol = ADAPTER_EPP_QC3_VOL; + if (di->power_max < 10000) { + icl_curr = ((di->power_max - 1000) / 11) * 1000; + } else { + icl_curr = EPP_DEFAULT_BYPASS_CURRENT; + } + } else { + adapter_vol = ADAPTER_DEFAULT_VOL; //6V + icl_curr = di->bpp_icl; + } + break; + case ADAPTER_DCP: + case ADAPTER_CDP: + adapter_vol = ADAPTER_DEFAULT_VOL; //6V + if (di->is_compatible_hwid) + icl_curr = DC_BPP_AUTH_FAIL_CURRENT; //860mA + else + icl_curr = DC_BPP_AUTH_FAIL_CURRENT; + break; + case ADAPTER_SDP: + adapter_vol = ADAPTER_DEFAULT_VOL; + icl_curr = 500000; + break; + case ADAPTER_XIAOMI_QC3: + case ADAPTER_XIAOMI_PD: + case ADAPTER_ZIMI_CAR_POWER: + case ADAPTER_XIAOMI_PD_40W: + case ADAPTER_VOICE_BOX: + case ADAPTER_XIAOMI_PD_45W: + case ADAPTER_XIAOMI_PD_60W: + if (di->epp) { + adapter_vol = ADAPTER_EPP_MI_VOL; + icl_curr = idtp9220_get_charging_current(di); + } else { + adapter_vol = ADAPTER_BPP_QC_VOL; + icl_curr = DC_QC3_CURRENT; + } + break; + default: + icl_curr = 0; + break; + } + + power_supply_get_property(di->batt_psy, POWER_SUPPLY_PROP_STATUS, &val); + batt_sts = val.intval; + + power_supply_get_property(di->batt_psy, POWER_SUPPLY_PROP_CAPACITY, + &val); + soc = val.intval; + + power_supply_get_property(di->batt_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, + &val); + vol_now = val.intval; + + power_supply_get_property(di->batt_psy, POWER_SUPPLY_PROP_CURRENT_NOW, + &val); + cur_now = val.intval; + + power_supply_get_property(di->batt_psy, POWER_SUPPLY_PROP_HEALTH, &val); + health = val.intval; + + idtp9220_get_iout(di); + + if ((batt_sts == POWER_SUPPLY_STATUS_DISCHARGING) && di->dcin_present && + di->power_good_flag) { + dev_info(di->dev, + "discharge when dc and pwr present, reset chip\n"); + return; + } + dev_info( + di->dev, + "[idtp] soc:%d,vol_now:%d,cur_now:%d,health:%d, bat_status:%d\n", + soc, vol_now, cur_now, health, batt_sts); + + /* adapter:qc2/qc3; tx:e5/d5x_10W; + * vout/psns is setted in delayed work + */ + if (adapter_vol == ADAPTER_BPP_QC_VOL && di->is_compatible_hwid) { + schedule_delayed_work(&di->bpp_e5_tx_work, msecs_to_jiffies(0)); + goto out; + } + + /* adapter:qc2; tx:F1_27W; + * vout/psns is setted in delayed work + */ + if (di->tx_charger_type == ADAPTER_QC2 && di->is_f1_tx) { + schedule_delayed_work(&di->qc2_f1_tx_work, msecs_to_jiffies(0)); + goto out; + } + + /* adapter:qc3_epp; tx:F1_27W; + * vout/psns is setted in delayed work + */ + if (di->is_epp_qc3) { + schedule_delayed_work(&di->qc3_epp_work, msecs_to_jiffies(0)); + goto out; + } + + if ((adapter_vol == ADAPTER_EPP_QC3_VOL) && (di->epp)) { + dev_info(di->dev, "standard epp logic\n"); + + if (adapter_vol > 0 && adapter_vol != di->last_vin) { + idtp922x_set_adap_vol(di, adapter_vol); + di->last_vin = adapter_vol; + msleep(200); + } + + if ((icl_curr > 0) && (icl_curr != di->last_icl)) { + idtp922x_set_pmi_icl(di, icl_curr); + di->last_icl = icl_curr; + msleep(100); + } + + goto out; + } + + if ((adapter_vol == ADAPTER_DEFAULT_VOL) && (!di->epp)) { + dev_info(di->dev, "standard bpp logic\n"); + + if (adapter_vol > 0 && adapter_vol != di->last_vin) { + idtp922x_set_adap_vol(di, adapter_vol); + di->last_vin = adapter_vol; + msleep(200); + } + + if ((icl_curr > 0) && (icl_curr != di->last_icl)) { + idtp922x_set_pmi_icl(di, icl_curr); + di->last_icl = icl_curr; + msleep(100); + } + + goto out; + } + + if (adapter_vol == ADAPTER_EPP_MI_VOL && di->is_pan_tx) { + schedule_delayed_work(&di->pan_tx_work, msecs_to_jiffies(0)); + goto out; + } + if (adapter_vol == ADAPTER_EPP_MI_VOL && di->is_voice_box_tx) { + dev_info(di->dev, "voice box logic\n"); + schedule_delayed_work(&di->voice_tx_work, msecs_to_jiffies(0)); + goto out; + } + /* MI adapter, change vout only after vswitch success */ + if (adapter_vol == ADAPTER_EPP_MI_VOL && di->vswitch_ok) { + switch (di->status) { + case NORMAL_MODE: + if (soc >= EPP_TAPER_SOC) { + if (di->wireless_psy) { + power_supply_get_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, + &val); + if (!val.intval) { + icl_curr = + idtp9220_get_taper_charging_current( + di); + } + } else { + icl_curr = + idtp9220_get_taper_charging_current( + di); + } + /* close cp, avoid battery OV */ + if (di->wireless_psy) { + val.intval = 0; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, + &val); + } + icl_curr = min(icl_curr, MAX_PMIC_ICL_UA); + } + if (soc >= FULL_SOC) { + di->status = TAPER_MODE; + } + break; + case TAPER_MODE: + if (soc == FULL_SOC && + batt_sts == POWER_SUPPLY_STATUS_FULL) + di->status = FULL_MODE; + else if (soc < FULL_SOC - 1) + di->status = NORMAL_MODE; + break; + case FULL_MODE: + dev_info(di->dev, "charge full set Vin 12V\n"); + adapter_vol = EPP_VOL_THRESHOLD; + icl_curr = SCREEN_OFF_FUL_CURRENT; + + if (batt_sts == POWER_SUPPLY_STATUS_CHARGING) { + dev_info(di->dev, + "full mode -> recharge mode\n"); + di->status = RECHG_MODE; + icl_curr = DC_LOW_CURRENT; + } + break; + case RECHG_MODE: + if (batt_sts == POWER_SUPPLY_STATUS_FULL) { + dev_info(di->dev, + "recharge mode -> full mode\n"); + di->status = FULL_MODE; + icl_curr = SCREEN_OFF_FUL_CURRENT; + adapter_vol = EPP_VOL_THRESHOLD; + if (di->wireless_psy) { + wk_val.intval = 0; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, + &wk_val); + } + break; + } + + dev_info(di->dev, "recharge mode set icl to 350mA\n"); + adapter_vol = EPP_VOL_THRESHOLD; + icl_curr = DC_LOW_CURRENT; + + if (di->wireless_psy) { + wk_val.intval = 1; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, + &wk_val); + } + break; + default: + break; + } + } + + if (!di->enable_ext5v) { + di->enable_ext5v = true; + idtp922x_enable_ext5v(di); + } + if (!di->power_good_flag) + return; + dev_info(di->dev, "%s: ready to set_vin vol\n", __func__); + if (adapter_vol > 0 && adapter_vol != di->last_vin) { + if ((adapter_vol == ADAPTER_EPP_MI_VOL) && + !di->first_rise_flag) { + di->first_rise_flag = true; + idtp922x_set_adap_vol(di, adapter_vol); + di->vswitch_ok = false; + vin_inc = 1; + msleep(110); + dev_info(di->dev, "%s:set adapter_vol %d\n", __func__, + adapter_vol); + } else if ((adapter_vol == ADAPTER_EPP_MI_VOL) && + di->first_rise_flag) { + idtp9220_set_vout(di, adapter_vol); + msleep(110); + schedule_delayed_work(&di->load_fod_param_work, + msecs_to_jiffies(500)); + schedule_delayed_work(&di->vout_regulator_work, + msecs_to_jiffies(400)); + dev_info(di->dev, "%s:set vout_vol %d\n", __func__, + adapter_vol); + } else if (adapter_vol == EPP_VOL_THRESHOLD) { + vout = idtp9220_get_vout(di); + while (vout > EPP_VOL_THRESHOLD) { + vout = vout - 1000; + idtp9220_set_vout(di, vout); + msleep(200); + } + idtp9220_set_vout(di, EPP_VOL_THRESHOLD); + schedule_delayed_work(&di->load_fod_param_work, + msecs_to_jiffies(500)); + } + vout_change = true; + di->last_vin = adapter_vol; + } + + if ((icl_curr > 0 && icl_curr != di->last_icl) || vout_change) { + di->last_icl = icl_curr; + idtp922x_set_pmi_icl(di, icl_curr); + msleep(100); + } + + dev_info( + di->dev, + "di->status:0x%x,adapter_vol=%d,icl_curr=%d,last_vin=%d,last_icl=%d\n", + di->status, adapter_vol, icl_curr, di->last_vin, di->last_icl); + + if (!di->vswitch_ok && vin_inc) { + di->adapter_voltage = adapter_vol; + schedule_delayed_work(&di->cmd_check_work, + msecs_to_jiffies(8000)); + } +out: + return; +} + +static void idtp9220_wpc_det_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, wpc_det_work.work); + union power_supply_propval val = { + 0, + }; + int ret = 0; + + ret = idtp9220_get_property_names(di); + if (ret < 0) { + dev_err(di->dev, "get property error: %d\n", ret); + return; + } + /* if power good is low return */ + if (!di->power_good_flag) + return; + + pm_stay_awake(di->dev); + + dev_info(di->dev, "power_good low, wireless detached\n"); + cancel_delayed_work(&di->dc_check_work); + di->power_good_flag = 0; + val.intval = 0; + di->ss = 2; + di->bpp_break = true; + cancel_delayed_work(&di->oob_set_cep_work); + cancel_delayed_work_sync(&di->chg_monitor_work); + cancel_delayed_work_sync(&di->epp_connect_load_work); + cancel_delayed_work_sync(&di->rx_vout_cp_close_work); + cancel_delayed_work_sync(&di->rx_vout_work); + vote(di->fcc_votable, VOICE_LIMIT_FCC_VOTER, false, 0); + vote(di->fcc_votable, VOICE_LIMIT_FCC_1A_VOTER, false, 0); + idtp9220_set_present(di, val.intval); + if (!di->icl_votable) + di->icl_votable = find_votable("dc_icl_votable"); + + if (di->icl_votable) + vote(di->icl_votable, OCP_PROTECTION_VOTER, false, 0); + + idtp922x_set_pmi_icl(di, 0); + + power_supply_set_property(di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN, + &val); + + if (di->wait_for_reverse_test) { + msleep(2000); + idtp9220_set_reverse_enable(di, true); + dev_err(di->dev, + "[ factory reverse test ] wait for factory reverse charging test, power good low\n"); + alarm_start_relative( + &di->reverse_test_ready_alarm, + ms_to_ktime(REVERSE_TEST_READY_CHECK_DELAY_MS)); + } + schedule_delayed_work(&di->keep_awake_work, msecs_to_jiffies(5000)); + return; +} + +static void idtp9220_fw_download_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, fw_download_work.work); + + u8 fw_app_ver[4] = { 0 }; + union power_supply_propval val = { + 0, + }; + bool crc_ok = false; + int rc = 0; + + dev_info(di->dev, "[idt] enter %s\n", __func__); + + if (di->fw_update) { + dev_info(di->dev, "[idtp9415] [%s] FW Update is on going!\n", + __func__); + return; + } + + power_supply_get_property(di->dc_psy, POWER_SUPPLY_PROP_ONLINE, &val); + + if (!val.intval) { + pm_stay_awake(di->dev); + di->fw_update = true; + idtp9220_set_reverse_gpio(di, true); + msleep(100); + rc = di->bus.read_buf(di, REG_EPRFWVER_ADDR, fw_app_ver, 4); + dev_info(di->dev, "%s: RX_FW version %x.%x.%x.%x\n", __func__, + fw_app_ver[3], fw_app_ver[2], fw_app_ver[1], + fw_app_ver[0]); + + if (!rc) + di->chip_ok = 1; + else + di->chip_ok = 0; + + di->fw_version = fw_app_ver[0]; + if (!program_crc_verify(di)) { + dev_err(di->dev, "update crc verify failed.\n"); + crc_ok = false; + } else { + dev_info(di->dev, "update crc verify success.\n"); + crc_ok = true; + } + + idtp9220_set_reverse_gpio(di, false); + msleep(30); + + if ((fw_app_ver[3] == 0x2 && fw_app_ver[2] == 0x6 && + fw_app_ver[1] == 0x1 && fw_app_ver[0] >= FW_VERSION) && + (crc_ok)) { + dev_info(di->dev, "FW: 0x%x, crc: %d so skip upgrade\n", + fw_app_ver[0], crc_ok); + } else { +#ifndef CONFIG_FACTORY_BUILD + idtp9220_set_reverse_gpio(di, true); + msleep(100); + + dev_info(di->dev, "%s: FW download start\n", __func__); + if (!program_fw(di, 0x0000, idt_firmware, + sizeof(idt_firmware))) { + dev_err(di->dev, "program fw failed.\n"); + } else { + dev_info( + di->dev, + "[idt] %s: program fw %ld bytes done\n", + __func__, sizeof(idt_firmware)); + di->fw_version = FW_VERSION; + } + + idtp9220_set_reverse_gpio(di, false); + msleep(100); + /* start crc verify */ + idtp9220_set_reverse_gpio(di, true); + msleep(100); + + if (!program_crc_verify(di)) + dev_err(di->dev, "crc verify failed.\n"); + else + dev_info(di->dev, "crc verify success.\n"); + idtp9220_set_reverse_gpio(di, false); +#else + dev_info(di->dev, "%s: factory build, don't update\n", + __func__); +#endif + } + di->fw_update = false; + pm_relax(di->dev); + } else + dev_info(di->dev, + "%s: Skip FW download due to wireless charging\n", + __func__); +} + +static void idtp9220_rx_vout_cp_close_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, rx_vout_cp_close_work.work); + int vout = 0; + vout = idtp9220_get_vout(di); + while (vout > CP_CLOSE_VOUT_MV) { + vout = vout - 1000; + if (!di->power_good_flag) + return; + idtp9220_set_vout(di, vout); + msleep(300); + } + if (!di->power_good_flag) + return; + idtp9220_set_vout(di, CP_CLOSE_VOUT_MV); + + if (di->power_good_flag) + di->cp_regulator_done = true; +} +static void idtp9220_keep_awake_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, keep_awake_work.work); + pm_relax(di->dev); +} +static int idtp_get_effective_icl_val(struct idtp9220_device_info *di) +{ + int effective_icl_val = 0; + + if (!di->icl_votable) + di->icl_votable = find_votable("DC_ICL"); + + if (!di->icl_votable) + return -EINVAL; + + effective_icl_val = get_effective_result_locked(di->icl_votable); + pr_info("effective_icl_val: %d\n", effective_icl_val); + return effective_icl_val; +} + +static int idtp_set_effective_icl_val(struct idtp9220_device_info *di, int icl) +{ + int effective_icl_val = 0; + + if (!di->icl_votable) + di->icl_votable = find_votable("DC_ICL"); + + if (!di->icl_votable) + return -EINVAL; + + vote(di->icl_votable, OCP_PROTECTION_VOTER, true, icl); + pr_info("effective_icl_val: %d\n", effective_icl_val); + return 0; +} + +#ifndef CONFIG_FACTORY_BUILD +#define NEW_MAX_POWER_CMD 0x28 +#define RENEGOTIATION_CMD 0x80 +static void idtp9220_renegociation(struct idtp9220_device_info *di) +{ + if (di->tx_charger_type == ADAPTER_XIAOMI_PD_45W || + di->tx_charger_type == ADAPTER_XIAOMI_PD_60W) { + di->bus.write(di, REG_MAX_POWER, NEW_MAX_POWER_CMD); + di->bus.write(di, REG_RX_RESET, RENEGOTIATION_CMD); + } +} +#endif +static void idtp9220_start_to_load(struct idtp9220_device_info *di) +{ + union power_supply_propval val = { + 0, + }; + schedule_delayed_work(&di->rx_vout_work, msecs_to_jiffies(100)); + schedule_delayed_work(&di->chg_monitor_work, msecs_to_jiffies(1000)); + if (di->tx_charger_type == ADAPTER_XIAOMI_PD_40W || + di->tx_charger_type == ADAPTER_XIAOMI_PD_45W || + di->tx_charger_type == ADAPTER_XIAOMI_PD_60W) { + if (di->wireless_psy) { + val.intval = di->tx_charger_type; + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_QUICK_CHARGE_TYPE, &val); + } + msleep(100); + if (di->usb_psy) + power_supply_changed(di->usb_psy); + } + + if (di->wireless_psy) + power_supply_changed(di->wireless_psy); +} + +static void idtp9220_idt_first_boot(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, idt_first_boot.work); + idt_first_flag = true; + if (di->idtp_psy) + power_supply_changed(di->idtp_psy); +} + +static int idt_trx_get_ble_mac(struct idtp9220_device_info *di) +{ + int rc = 0, i = 0; + u8 mac_buf[MAC_LEN] = { 0 }; + + rc = di->bus.read_buf(di, REG_MAC_ADDR, mac_buf, MAC_LEN); + if (rc < 0) { + dev_err(di->dev, "trx read mac addr error: %d\n", rc); + return rc; + } + + dev_info(di->dev, "mac addr of pen: 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n", + mac_buf[0], mac_buf[1], mac_buf[2], mac_buf[3], mac_buf[4], + mac_buf[5]); + + for (i = 0; i < MAC_LEN; i++) + di->pen_mac_data[i] = mac_buf[i]; + + idtp922x_sent_pen_mac(di); + + return rc; +} + +static void idtp9220_hall3_irq_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, hall3_irq_work.work); + if (di->hall3_online) + idtp9220_set_reverse_enable(di, true); + else if (!di->hall4_online) { + idtp9220_set_reverse_enable(di, false); + di->is_reverse_mode = 0; + di->is_reverse_chg = 2; + schedule_delayed_work(&di->reverse_sent_state_work, 0); + } else { + dev_info( + di->dev, + "[hall3] hall4 online, don't disable reverse charge\n"); + } + + return; +} + +static void idtp9220_hall4_irq_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, hall4_irq_work.work); + + if (di->hall4_online) + idtp9220_set_reverse_enable(di, true); + else if (!di->hall3_online) { + idtp9220_set_reverse_enable(di, false); + di->is_reverse_mode = 0; + di->is_reverse_chg = 2; + schedule_delayed_work(&di->reverse_sent_state_work, 0); + } else { + dev_info( + di->dev, + "[hall4] hall3 online, don't disable reverse charge\n"); + } + + return; +} + +#define OCP_LOWER_ICL_SETP_UA 500000; +static void idtp9220_irq_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = + container_of(work, struct idtp9220_device_info, irq_work.work); + union power_supply_propval val = { + 0, + }; + u8 int_buf[4] = { 0 }; + u32 int_val = 0; + int rc = 0; + u8 recive_data[5] = { 0 }; + static int retry; + static int retry_id; + static int retry_count; +#ifndef CONFIG_FACTORY_BUILD + static int renego_retry_count; +#endif + int tx_vin = 0; + int irq_level; + int i; + u8 clr_buf[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; + int lower_icl = 0; + if (gpio_is_valid(di->dt_props.irq_gpio)) + irq_level = gpio_get_value(di->dt_props.irq_gpio); + else { + dev_err(di->dev, "%s: irq gpio not provided\n", __func__); + irq_level = -1; + pm_relax(di->dev); + return; + } + if (irq_level) { + dev_info(di->dev, "irq is high level, ignore%d\n", irq_level); + pm_relax(di->dev); + return; + } + + rc = di->bus.read_buf(di, REG_SYS_INT, int_buf, 4); + if (rc < 0) { + dev_err(di->dev, "[idt]read int state error: %d\n", rc); + goto out; + } + + if (di->is_reverse_mode || di->is_boost_mode) { + reverse_clrInt(di, int_buf, 4); + int_val = int_buf[0] | (int_buf[1] << 8) | (int_buf[2] << 16) | + (int_buf[3] << 24); + dev_info(di->dev, "[idt] TRX int: 0x%08x\n", int_val); + /* add for confirm if irq is cleared start */ + msleep(5); + if (reverse_need_irq_cleared(di, int_val)) { + reverse_clrInt(di, clr_buf, 4); + msleep(5); + } + /* add for confirm if irq is cleared end */ + if (int_val & INT_EPT_TYPE) { + schedule_delayed_work(&di->reverse_ept_type_work, 0); + goto reverse_out; + } + + if (int_val & INT_GET_DPING) { + dev_info( + di->dev, + "[idt] TRX get dping and disable reverse charging \n"); + idtp9220_set_reverse_enable(di, false); + di->is_reverse_mode = 0; + di->is_reverse_chg = 2; + schedule_delayed_work(&di->reverse_sent_state_work, 0); + goto reverse_out; + } + + if (int_val & INT_START_DPING) { + alarm_start_relative( + &di->reverse_chg_alarm, + ms_to_ktime(REVERSE_CHG_CHECK_DELAY_MS)); + rc = alarm_cancel(&di->reverse_dping_alarm); + if (rc < 0) + dev_err(di->dev, + "Couldn't cancel reverse_dping_alarm\n"); + pm_relax(di->dev); + } + if (int_val & INT_GET_CFG) { + //cancel_delayed_work(&di->reverse_chg_state_work); + dev_info(di->dev, "TRX get cfg, cancel 80s alarm\n"); + rc = alarm_cancel(&di->reverse_chg_alarm); + if (rc < 0) + dev_err(di->dev, + "Couldn't cancel reverse_dping_alarm\n"); + pm_stay_awake(di->dev); + schedule_delayed_work(&di->reverse_sent_state_work, 0); + di->bus.write(di, REG_TX_CMD, TX_EN); + msleep(50); + //start reverse chg infor work + cancel_delayed_work_sync(&di->reverse_chg_work); + msleep(10); + schedule_delayed_work(&di->reverse_chg_work, 0); + /* set reverse charging state to started */ + if (di->is_reverse_mode || di->is_boost_mode) { + di->is_reverse_chg = 4; + schedule_delayed_work( + &di->reverse_sent_state_work, 100); + } + } + if (int_val & INT_GET_SS) { + dev_info(di->dev, "TRX get ss\n"); + } + if (int_val & INT_GET_ID) { + dev_info(di->dev, "TRX get id\n"); + } + if (int_val & INT_INIT_TX) { + dev_info(di->dev, "[idt] TRX reset done\n"); + } + if (int_val & INT_GET_BLE_ADDR) { + dev_info(di->dev, "[idt] TRX get ble mac\n"); + idt_trx_get_ble_mac(di); + } + if (int_val & INT_GET_PPP) { + idtp922x_receivePkt2(di, recive_data); + dev_err(di->dev, + "[ factory reverse test ] receive dates: 0x%02x, 0x%02x\n", + recive_data[0], recive_data[1]); + if (recive_data[0] == 0x18 && recive_data[1] == 0x31) { + // done + dev_err(di->dev, + "[ factory reverse test ] receiver reverse test done\n"); + idtp9220_set_reverse_enable(di, false); + di->wait_for_reverse_test = false; + } else if (recive_data[0] == 0x18 && + recive_data[1] == 0x3D) { + //ready + dev_err(di->dev, + "[ factory reverse test ] receiver reverse test ready, cancel timer\n"); + alarm_cancel(&di->reverse_test_ready_alarm); + } + } +reverse_out: + goto out; + } + int_val = int_buf[0] | (int_buf[1] << 8) | (int_buf[2] << 16) | + (int_buf[3] << 24); + dev_info(di->dev, "[idt] int: 0x%08x\n", int_val); + + if (int_val & INT_MODE_CHANGE || int_val & INT_VOUT_OFF) { + if (di->power_good_flag) { + cancel_delayed_work_sync(&di->rx_ready_check_work); + schedule_delayed_work(&di->wpc_det_work, + msecs_to_jiffies(0)); + } + + idtp922x_clrInt(di, int_buf, 4); + msleep(5); + if (need_irq_cleared(di)) { + idtp922x_clrInt(di, clr_buf, 4); + msleep(5); + } + goto out; + } + + if (int_val & INT_OV_CURR) { + lower_icl = + idtp_get_effective_icl_val(di) - OCP_LOWER_ICL_SETP_UA; + + if (lower_icl > 0) + idtp_set_effective_icl_val(di, lower_icl); + + /* wait for icl works */ + msleep(1000); + idtp922x_clrInt(di, int_buf, 4); + msleep(5); + if (need_irq_cleared(di)) { + idtp922x_clrInt(di, clr_buf, 4); + msleep(5); + } + goto out; + } + + /* clear int and enable irq immediately when read int register */ + idtp922x_clrInt(di, int_buf, 4); + msleep(5); + if (need_irq_cleared(di)) { + idtp922x_clrInt(di, clr_buf, 4); + msleep(5); + } + + if (int_val & INT_RXREADY) { + cancel_delayed_work_sync(&di->rx_ready_check_work); + if (di->power_good_flag) { + schedule_delayed_work(&di->wpc_det_work, + msecs_to_jiffies(0)); + } + schedule_delayed_work(&di->initial_tx_work, + msecs_to_jiffies(100)); + di->power_good_flag = 1; + val.intval = 1; + if (!di->wireless_psy) + di->wireless_psy = power_supply_get_by_name("wireless"); + if (di->wireless_psy) + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN, &val); + schedule_delayed_work(&di->rx_ready_check_work, + msecs_to_jiffies(100)); + } + if (int_val & INT_VOUT_ON) { + if (!di->power_good_flag) { + cancel_delayed_work_sync(&di->rx_ready_check_work); + if (di->power_good_flag) { + schedule_delayed_work(&di->wpc_det_work, + msecs_to_jiffies(0)); + } + schedule_delayed_work(&di->initial_tx_work, + msecs_to_jiffies(100)); + di->power_good_flag = 1; + val.intval = 1; + if (!di->wireless_psy) + di->wireless_psy = + power_supply_get_by_name("wireless"); + if (di->wireless_psy) + power_supply_set_property( + di->wireless_psy, + POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN, + &val); + schedule_delayed_work(&di->rx_ready_check_work, + msecs_to_jiffies(100)); + } + di->vout_on = true; + di->epp = idtp9220_get_power_profile(di); + if (di->epp) { + di->power_max = idtp9220_get_power_max(di); + schedule_delayed_work(&di->epp_connect_load_work, + msecs_to_jiffies(200)); + } else + schedule_delayed_work(&di->bpp_connect_load_work, + msecs_to_jiffies(200)); + if (int_val & INT_IDAUTH_SUCESS) + idtp9220_send_device_auth(di); + goto out; + } + + if (int_val & INT_VSWITCH_SUCESS) { + di->vswitch_ok = true; + schedule_delayed_work(&di->load_fod_param_work, + msecs_to_jiffies(500)); + schedule_delayed_work(&di->vout_regulator_work, + msecs_to_jiffies(50)); + cancel_delayed_work(&di->cmd_check_work); + if (di->is_ble_tx) + idtp922x_request_low_addr(di); + goto out; + } + + if (int_val & INT_IDAUTH_SUCESS) { + idtp9220_send_device_auth(di); + //idtp922x_request_adapter(di); + goto out; + } + + if (int_val & INT_AUTH_SUCESS) { + idtp922x_request_uuid(di, di->epp); + goto out; + } + /* + idtp9220_get_signal_strength(di); + di->tx_charger_type = ADAPTER_QC3; + schedule_delayed_work(&di->chg_monitor_work, + msecs_to_jiffies(0)); + goto out; + */ + + if ((int_val & INT_IDAUTH_FAIL) || (int_val & INT_AUTH_FAIL) || + int_val == 0) { + if (((int_val & INT_AUTH_FAIL) || (int_val == 0)) && + (retry < 5)) { + idtp9220_send_device_auth(di); + retry++; + dev_info(di->dev, "[idtp] dev auth failed retry %d\n", + retry); + goto out; + } else if ((int_val & INT_IDAUTH_FAIL) && retry_id < 5) { + idtp9220_retry_id_auth(di); + retry_id++; + dev_info(di->dev, "[idtp] id auth failed retry %d\n", + retry); + goto out; + } else { + retry = 0; + retry_id = 0; + } + di->tx_charger_type = ADAPTER_AUTH_FAILED; + dev_info(di->dev, "[idtp] auth failed tx charger type set %d\n", + di->tx_charger_type); + + schedule_delayed_work(&di->rx_vout_work, msecs_to_jiffies(0)); + schedule_delayed_work(&di->chg_monitor_work, + msecs_to_jiffies(0)); + goto out; + } else + retry = 0; + /* + if (int_val & INT_IDAUTH_FAIL) { + idtp922x_request_adapter(di); + goto out; + } + */ + + if (int_val & INT_SEND_TIMEOUT) { + if (retry_count < 3) { + dev_info(di->dev, "timeout retry %d\n", retry_count); + idtp922x_retry_cmd(di); + retry_count++; + goto out; + } else { + dev_err(di->dev, "%s: retry failed\n", __func__); + if (!di->tx_charger_type) + di->tx_charger_type = ADAPTER_AUTH_FAILED; + schedule_delayed_work(&di->rx_vout_work, + msecs_to_jiffies(0)); + schedule_delayed_work(&di->chg_monitor_work, + msecs_to_jiffies(0)); + retry_count = 0; + goto out; + } + } else { + retry_count = 0; + } +#ifndef CONFIG_FACTORY_BUILD + if (int_val & RENEG_SUCCESS) { + if (di->tx_charger_type == ADAPTER_XIAOMI_PD_45W || + di->tx_charger_type == ADAPTER_XIAOMI_PD_60W) { + dev_err(di->dev, + "%s: max power renegociation success\n", + __func__); + idtp9220_start_to_load(di); + renego_retry_count = 0; + } + } + + if (int_val & RENEG_FAIL) { + if (di->tx_charger_type == ADAPTER_XIAOMI_PD_45W || + di->tx_charger_type == ADAPTER_XIAOMI_PD_60W) { + if (renego_retry_count < 3) { + idtp9220_renegociation(di); + dev_err(di->dev, "%s: retry renegociation\n", + __func__); + renego_retry_count++; + } else { + dev_err(di->dev, + "%s: retry limit exceed, set adapter type to 40W\n", + __func__); + di->tx_charger_type = ADAPTER_XIAOMI_PD_40W; + idtp9220_start_to_load(di); + renego_retry_count = 0; + } + } + } +#endif + + if (int_val & INT_TX_DATA_RECV) { + idtp922x_receivePkt(di, recive_data); + dev_info(di->dev, "[idt] cmd: %x\n", recive_data[0]); + + switch (recive_data[0]) { + case BC_TX_HWID: + dev_info( + di->dev, + "[idt] TX chip_vendor:0x%x, module:0x%x, hw:0x%x and power:0x%x\n", + recive_data[4], recive_data[2], recive_data[3], + recive_data[1]); + if (recive_data[4] == 0x07 && recive_data[2] == 0x1 && + recive_data[3] == 0x4 && + ((recive_data[1] == 0x9) || + (recive_data[1] == 0x1))) { + di->is_ble_tx = 1; + } else if (recive_data[4] == 0x01 && + recive_data[2] == 0x2 && + recive_data[3] == 0x8 && + recive_data[1] == 0x6) { + di->is_car_tx = 1; + } else if (recive_data[4] == 0x07 && + recive_data[2] == 0x8 && + recive_data[3] == 0x6 && + recive_data[1] == 0x9) { + di->is_voice_box_tx = 1; + di->is_ble_tx = 1; + } else if (recive_data[4] == 0x06 && + recive_data[2] == 0x1 && + recive_data[3] == 0x5 && + recive_data[1] == 0x9) { + di->is_pan_tx = 1; + } else if (recive_data[4] == 0x0B && + recive_data[2] == 0x1 && + recive_data[3] == 0x1 && + recive_data[1] == 0x9) { + di->is_ble_tx = 1; + } else if (recive_data[4] == 0x01 && + recive_data[2] == 0x1 && + recive_data[3] == 0x1 && + recive_data[1] == 0x6) { + di->is_f1_tx = 1; + } else if (recive_data[4] == 0x01 && + recive_data[2] == 0x3 && + recive_data[3] == 0x8 && + recive_data[1] == 0x7) { + di->is_zm_mobil_tx = 1; + } else if (recive_data[4] == 0x08 && + recive_data[2] == 0x8 && + recive_data[3] == 0x1 && + recive_data[1] == 0x9) { + di->is_zm_20w_tx = 1; + } +#ifdef CONFIG_FACTORY_BUILD + di->is_ble_tx = 0; +#endif + idtp922x_request_adapter(di); + break; + case BC_TX_COMPATIBLE_HWID: + dev_info(di->dev, "[idt] TX hwid: 0x%x 0x%x\n", + recive_data[1], recive_data[2]); + if (recive_data[1] == 0x12 && recive_data[2]) + di->is_compatible_hwid = 1; + if (recive_data[1] == 0x16 && recive_data[2] == 0x11) + di->is_f1_tx = 1; + idtp922x_request_adapter(di); + break; + case BC_ADAPTER_TYPE: + dev_info(di->dev, "[idt]adapter type: %d\n", + recive_data[1]); + + if (di->is_car_tx && + (recive_data[1] == ADAPTER_XIAOMI_QC3)) + di->tx_charger_type = ADAPTER_ZIMI_CAR_POWER; + else if (di->is_voice_box_tx) + di->tx_charger_type = ADAPTER_VOICE_BOX; + else + di->tx_charger_type = recive_data[1]; + + if (di->tx_charger_type == ADAPTER_XIAOMI_PD_40W && + di->is_zm_mobil_tx) { + //di->tx_charger_type = ADAPTER_VOICE_BOX; + di->is_voice_box_tx = 1; + } + /* + if(!di->epp && (di->tx_charger_type == ADAPTER_QC3 || + di->tx_charger_type == ADAPTER_QC2)) { + idtp922x_set_adap_vol(di, ADAPTER_BPP_VOL); + dev_info(di->dev, "[idt]bpp mode set 5v first\n"); + } + */ +#ifdef CONFIG_FACTORY_BUILD + idtp9220_start_to_load(di); +#else + if (di->tx_charger_type == ADAPTER_XIAOMI_PD_45W || + di->tx_charger_type == ADAPTER_XIAOMI_PD_60W) { + renego_retry_count = 0; + idtp9220_renegociation(di); + } else { + idtp9220_start_to_load(di); + } +#endif + break; + case BC_READ_Vin: + tx_vin = recive_data[1] | (recive_data[2] << 8); + if (!di->power_off_mode) { + if (di->epp) + idtp9220_set_vout(di, + di->adapter_voltage); + else + idtp9220_set_vout(di, + ADAPTER_BPP_QC_VOL); + } + dev_info(di->dev, "[idt] tx vin : %d\n", tx_vin); + break; + case BC_READ_VOUT: + schedule_delayed_work(&di->get_vout_work, + msecs_to_jiffies(0)); + break; + case BC_READ_IOUT: + schedule_delayed_work(&di->get_iout_work, + msecs_to_jiffies(0)); + break; + case BC_RX_CHIP_VERSION: + dev_info(di->dev, "[idt]Detect RX Chip version\n"); + idtp922x_sent_chip_version(di); + break; + case BC_RX_FW_VERSION: + dev_info(di->dev, "[idt]Detect RX FW version\n"); + idtp922x_sent_fw_version(di); + break; + case BC_RX_ID_AUTH: + dev_info(di->dev, + "[idt] ID Auth retry success: 0x%x, 0x%x\n", + recive_data[1], recive_data[2]); + idtp9220_send_device_auth(di); + break; + case CMD_GET_BLEMAC_2_0: + dev_info( + di->dev, + "[idt] get mac low 3 bytes: 0x%x, 0x%x, 0x%x\n", + recive_data[1], recive_data[2], recive_data[3]); + for (i = 0; i < 3; i++) { + di->mac_data[i] = recive_data[i + 1]; + } + idtp922x_request_high_addr(di); + break; + case CMD_GET_BLEMAC_5_3: + dev_info( + di->dev, + "[idt] get mac high 3 bytes: 0x%x, 0x%x, 0x%x\n", + recive_data[1], recive_data[2], recive_data[3]); + for (i = 0; i < 3; i++) { + di->mac_data[i + 3] = recive_data[i + 1]; + } + idtp922x_sent_tx_mac(di); + break; + case CMD_FACOTRY_REVERSE: + dev_info( + di->dev, + "[ factory reverse test ] send factory reverse cnf\n"); + idtp922x_sent_reverse_cnf(di); + di->wait_for_reverse_test = true; + break; + default: + dev_info(di->dev, "[idt] unsupport cmd: %x\n", + recive_data[0]); + break; + } + } + if (int_val & INT_RPP_READ) + rc = idtp9220_set_rpp(di); + +out: + pm_relax(di->dev); + return; +} + +static irqreturn_t idtp9220_wpc_det_irq_handler(int irq, void *dev_id) +{ + //struct idtp9220_device_info *di = dev_id; + + //pm_stay_awake(di->dev); + printk("idtp9220_wpc_det_irq_handler\n"); + //schedule_delayed_work(&di->wpc_det_work, msecs_to_jiffies(0)); + + return IRQ_HANDLED; +} + +static int idtp9220_ocp_disable_vote_cb(struct votable *votable, void *data, + int disable, const char *client) +{ + struct idtp9220_device_info *di = (struct idtp9220_device_info *)data; + di->bus.write(di, REG_OCP_CONFIG, !disable); + dev_err(di->dev, "idtp9220_ocp_disable_vote_cb enable:%d\n", !disable); + return 0; +} + +static irqreturn_t idtp9220_irq_handler(int irq, void *dev_id) +{ + struct idtp9220_device_info *di = dev_id; + pm_stay_awake(di->dev); + printk("idtp9220_irq_handler\n"); + schedule_delayed_work(&di->irq_work, msecs_to_jiffies(10)); + return IRQ_HANDLED; +} + +static irqreturn_t idtp9220_hall3_irq_handler(int irq, void *dev_id) +{ + struct idtp9220_device_info *di = dev_id; + + if (gpio_is_valid(di->dt_props.hall3_gpio)) { + if (gpio_get_value(di->dt_props.hall3_gpio)) { + dev_info(di->dev, + "idtp9220_hall3_irq_handler: pen detach\n"); + di->hall3_online = 0; + if (di->hall4_online) { + dev_info( + di->dev, + "idtp9220_hall3_irq_handler: hall4 online, return\n"); + return IRQ_HANDLED; + } + schedule_delayed_work(&di->hall3_irq_work, + msecs_to_jiffies(0)); + return IRQ_HANDLED; + } else { + dev_info(di->dev, + "idtp9220_hall3_irq_handler: pen attach\n"); + di->hall3_online = 1; + } + } + + if (di->hall4_online) { + dev_info(di->dev, + "[hall3] reverse charging already running, return\n"); + return IRQ_HANDLED; + } else + schedule_delayed_work(&di->hall3_irq_work, + msecs_to_jiffies(10)); + + return IRQ_HANDLED; +} + +static irqreturn_t idtp9220_hall4_irq_handler(int irq, void *dev_id) +{ + struct idtp9220_device_info *di = dev_id; + + if (gpio_is_valid(di->dt_props.hall4_gpio)) { + if (gpio_get_value(di->dt_props.hall4_gpio)) { + dev_info(di->dev, + "idtp9220_hall4_irq_handler: pen detach\n"); + di->hall4_online = 0; + if (di->hall3_online) { + dev_info( + di->dev, + "idtp9220_hall4_irq_handler: hall3 online, return\n"); + return IRQ_HANDLED; + } + schedule_delayed_work(&di->hall4_irq_work, + msecs_to_jiffies(0)); + return IRQ_HANDLED; + } else { + dev_info(di->dev, + "idtp9220_hall4_irq_handler: pen attach\n"); + di->hall4_online = 1; + } + } + + if (di->hall3_online) { + dev_info(di->dev, + "[hall4] reverse charging already running, return\n"); + return IRQ_HANDLED; + } else + schedule_delayed_work(&di->hall4_irq_work, + msecs_to_jiffies(10)); + + return IRQ_HANDLED; +} + +static int idtp9220_irq_request(struct idtp9220_device_info *di) +{ + int ret = 0; + + if (!di->irq) { + dev_err(di->dev, "%s: irq is wrong\n", __func__); + return -EINVAL; + } + + ret = request_irq(di->irq, idtp9220_irq_handler, IRQF_TRIGGER_FALLING, + di->name, di); + if (ret) { + dev_err(di->dev, "%s: request_irq failed\n", __func__); + return ret; + } + + ret = enable_irq_wake(di->irq); + if (ret) { + dev_err(di->dev, "%s: enable_irq_wake failed\n", __func__); + return ret; + } + + if (!di->hall3_irq) { + dev_err(di->dev, "%s: hall3 irq is wrong\n", __func__); + return -EINVAL; + } + + ret = request_irq(di->hall3_irq, idtp9220_hall3_irq_handler, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "hall3_irq", di); + if (ret) { + dev_err(di->dev, "%s: request hall3 irq failed\n", __func__); + return ret; + } + + ret = enable_irq_wake(di->hall3_irq); + if (ret) { + dev_err(di->dev, "%s: enable hall3 irq wake failed\n", + __func__); + return ret; + } + + if (!di->hall4_irq) { + dev_err(di->dev, "%s: hall4 irq is wrong\n", __func__); + return -EINVAL; + } + + ret = request_irq(di->hall4_irq, idtp9220_hall4_irq_handler, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "hall4_irq", di); + if (ret) { + dev_err(di->dev, "%s: request hall4 irq failed\n", __func__); + return ret; + } + + ret = enable_irq_wake(di->hall4_irq); + if (ret) { + dev_err(di->dev, "%s: enable hall4 irq wake failed\n", + __func__); + return ret; + } + + if (!di->wpc_irq) { + dev_err(di->dev, "%s: wpc irq is wrong\n", __func__); + return -EINVAL; + } + + ret = request_irq(di->wpc_irq, idtp9220_wpc_det_irq_handler, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "wpc_det", + di); + if (ret) { + dev_err(di->dev, "%s: wpc request_irq failed\n", __func__); + return ret; + } + + ret = enable_irq_wake(di->wpc_irq); + if (ret) { + dev_err(di->dev, "%s: enable_irq_wake failed\n", __func__); + return ret; + } + + return 0; +} + +static struct regmap_config i2c_idtp9220_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .max_register = 0xFFFF, +}; + +/* + static int idtp9220_get_version(struct idtp9220_device_info *di) + { + int id_val = 0; + u8 chip_id[2] = {0}; + + di->bus.read_buf(di, REG_CHIP_ID_L, chip_id, 2); + id_val = (chip_id[1] << 8) | chip_id[0]; + + return id_val; + } + */ + +static u8 oob_check_sum(u8 *buf, u32 size) +{ + u8 chksum = 0; + while (size--) { + chksum ^= *buf++; + } + + return chksum; +} + +static int idtp9220_set_ept(struct idtp9220_device_info *di) +{ + union power_supply_propval val = { + 0, + }; + int ept = 0; + u8 ept_raw = 0x0b; + u8 header[2] = { 0 }; + u8 chksum[4] = { 0 }; + int rc = 0; + + header[1] = 0x02; //add the ept header + + chksum[0] = header[1]; + chksum[1] = ept_raw; + header[0] = oob_check_sum(chksum, 2); + ept = header[0] | ept_raw << 8 | (header[1] << 16); + val.int64val = ept; + + if (di->wireless_psy) { + mutex_lock(&di->sysfs_op_lock); + power_supply_set_property(di->wireless_psy, + POWER_SUPPLY_PROP_RX_CEP, &val); + mutex_unlock(&di->sysfs_op_lock); + } else { + dev_err(di->dev, "BLE EPT set error:\n"); + rc = -EINVAL; + } + + dev_info(di->dev, "Header: 0x%x, ept_raw: 0x%x, checksum: 0x%x\n", + header[1], ept_raw, header[0]); + + return rc; +} + +static int idtp9220_set_rpp(struct idtp9220_device_info *di) +{ + int64_t rpp = 0; + int64_t header_ul = 0; + u8 rpp_raw[2] = { 0 }; + u8 header[2] = { 0 }; + u8 chksum[4] = { 0 }; + union power_supply_propval val = { + 0, + }; + int rc = 0; + + header[1] = 0x31; //add the rpp header + di->bus.read_buf(di, REG_RPP, rpp_raw, 2); + + chksum[0] = header[1]; + chksum[1] = rpp_raw[0]; + chksum[2] = rpp_raw[1]; + header[0] = oob_check_sum(chksum, 3); + + dev_info(di->dev, + "header: 0x%x, RPP_raw: 0x%x, 0x%x, checksum: 0x%x\n", + header[1], rpp_raw[1], rpp_raw[0], header[0]); + rpp = header[0] | (rpp_raw[0] << 8) | (rpp_raw[1] << 16); + header_ul = header[1]; + header_ul <<= 32; + header_ul |= rpp; + val.int64val = header_ul; + + if (di->wireless_psy) { + mutex_lock(&di->sysfs_op_lock); + power_supply_set_property(di->wireless_psy, + POWER_SUPPLY_PROP_RX_CR, &val); + mutex_unlock(&di->sysfs_op_lock); + } else { + dev_err(di->dev, "BLE RPP set error:\n"); + rc = -EINVAL; + } + return rc; +} + +static int idtp9220_set_cep(struct idtp9220_device_info *di) +{ + int cep = 0; + u8 cep_raw = 0; + u8 header[2] = { 0 }; + u8 chksum[4] = { 0 }; + union power_supply_propval val = { + 0, + }; + int rc = 0; + + header[1] = 0x03; //add the rpp header + di->bus.read(di, REG_CEP, &cep_raw); + + chksum[0] = header[1]; + chksum[1] = cep_raw; + header[0] = oob_check_sum(chksum, 2); + + dev_info(di->dev, "Header: 0x%x, CEP_raw: 0x%x, checksum: 0x%x\n", + header[1], cep_raw, header[0]); + cep = header[0] | cep_raw << 8 | (header[1] << 16); + val.int64val = cep; + if (di->wireless_psy) { + mutex_lock(&di->sysfs_op_lock); + power_supply_set_property(di->wireless_psy, + POWER_SUPPLY_PROP_RX_CEP, &val); + mutex_unlock(&di->sysfs_op_lock); + } else { + dev_err(di->dev, "BLE CEP set error:\n"); + rc = -EINVAL; + } + return rc; +} + +static void idtp_oob_set_cep_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, oob_set_cep_work.work); + int rc; + u8 ble_ok; + + di->bus.read(di, REG_BLE_FLAG, &ble_ok); + if (ble_ok & BIT(0)) + rc = idtp9220_set_cep(di); + + schedule_delayed_work(&di->oob_set_cep_work, 1 * HZ); + return; +} + +static void idt_get_reverse_vout(struct idtp9220_device_info *di) +{ + u8 vout_l, vout_h; + int vout = 0; + + if (!di) + return; + + di->bus.read(di, REG_REVERSE_VIN_LOW, &vout_l); + di->bus.read(di, REG_REVERSE_VIN_HIGH, &vout_h); + vout = vout_l | (vout_h << 8); + dev_info(di->dev, "[reverse] vout is %d\n", vout); + di->reverse_vout = vout; + return; +} + +static void idt_get_reverse_soc(struct idtp9220_device_info *di) +{ + u8 soc = 0; + + if (!di) + return; + + di->bus.read(di, REG_CHG_STATUS, &soc); + if ((soc < 0) || (soc > 0x64)) { + if (soc == 0xFF) { + dev_info(di->dev, "[reverse] soc is default 0xFF\n"); + di->reverse_pen_soc = 0xFF; + } else { + dev_info(di->dev, "[reverse] soc illegal: %d\n", soc); + return; + } + } + + dev_info(di->dev, "[reverse] soc is %d\n", soc); + di->reverse_pen_soc = soc; + + if ((di->reverse_pen_soc == 100) && (pen_soc_count < SOC_100_RETRY)) { + dev_info(di->dev, "[reverse] soc is 100 count: %d\n", + pen_soc_count); + pen_soc_count++; + } else { + pen_soc_count = 0; + } + + if (pen_soc_count == SOC_100_RETRY) { + dev_info( + di->dev, + "[reverse] soc is 100 exceed 6 times, disable reverse chg!\n"); + idtp9220_set_reverse_enable(di, false); + di->is_reverse_mode = 0; + di->is_reverse_chg = 2; + pen_soc_count = 0; + schedule_delayed_work(&di->reverse_sent_state_work, 0); + } + + return; +} + +static void idt_get_reverse_iin(struct idtp9220_device_info *di) +{ + u8 iin_l, iin_h; + int iin = 0; + + if (!di) + return; + + di->bus.read(di, REG_REVERSE_IIN_LOW, &iin_l); + di->bus.read(di, REG_REVERSE_IIN_HIGH, &iin_h); + iin = iin_l | (iin_h << 8); + dev_info(di->dev, "[reverse] iin is %d\n", iin); + di->reverse_iout = iin; + return; +} + +static void idt_get_reverse_temp(struct idtp9220_device_info *di) +{ + u8 temp = 0; + + if (!di) + return; + + di->bus.read(di, REG_REVERSE_TEMP, &temp); + dev_info(di->dev, "[reverse] temp is %d\n", temp); + return; +} + +static void idt_reverse_chg_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, reverse_chg_work.work); + + if (di->is_reverse_mode || di->is_boost_mode) { + idt_get_reverse_vout(di); + idt_get_reverse_iin(di); + idt_get_reverse_temp(di); + idt_get_reverse_soc(di); + } else { + dev_info(di->dev, "reverse chg closed, return\n"); + di->reverse_pen_soc = 255; + di->reverse_vout = 0; + di->reverse_iout = 0; + return; + } + + if (di->reverse_pen_soc == 255) + schedule_delayed_work(&di->reverse_chg_work, 100); + else + schedule_delayed_work(&di->reverse_chg_work, 10 * HZ); + return; +} + +static void idtp_oob_set_ept_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, oob_set_ept_work.work); + + idtp9220_set_ept(di); + + return; +} + +static void idtp_oob_clean_work(struct work_struct *work) +{ + union power_supply_propval val = { + 0, + }; + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, oob_clean_work.work); + memset(di->mac_data, 0x0, sizeof(di->mac_data)); + idtp922x_sent_tx_mac(di); + if (di->wireless_psy) { + power_supply_set_property(di->wireless_psy, + POWER_SUPPLY_PROP_RX_CR, &val); + power_supply_set_property(di->wireless_psy, + POWER_SUPPLY_PROP_RX_CEP, &val); + } + return; +} + +#define WPC_MODE_BPP 0x1 +#define WPC_MODE_EPP 0x9 + +static void idtp_rx_ready_check_work(struct work_struct *work) +{ + int rx_dead = 0; + u8 mode; + u8 buffer[2] = { 0, 0 }; + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, rx_ready_check_work.work); + rx_dead = di->bus.read(di, REG_WPC_MODE, &mode); + di->bus.read_buf(di, 0x2c, buffer, 2); + if (rx_dead) { + msleep(10); + rx_dead = di->bus.read(di, REG_WPC_MODE, &mode); + di->bus.read_buf(di, 0x2c, buffer, 2); + } + dev_info(di->dev, "rx status: %d mod:0x%x 2C_RISTER 0x%x 0x%x\n", + rx_dead, mode, buffer[0], buffer[1]); + if (rx_dead || (mode != WPC_MODE_BPP && mode != WPC_MODE_EPP)) { + dev_err(di->dev, "rx not respond, power good low\n"); + if (di->power_good_flag) { + schedule_delayed_work(&di->wpc_det_work, + msecs_to_jiffies(0)); + } + } else { + schedule_delayed_work(&di->rx_ready_check_work, + msecs_to_jiffies(500)); + } + return; +} +static int idtp9220_get_temperature(struct idtp9220_device_info *di, u8 *temp) +{ + int rc = 0; + rc = di->bus.read(di, REG_TEMPTER, temp); + return rc; +} + +static void idtp9220_power_off(struct idtp9220_device_info *di) +{ + dev_err(di->dev, "bbc or smb report power off, PG:%d\n", + di->power_good_flag); + if (di->power_good_flag && di->vout_on) { + schedule_delayed_work(&di->wpc_det_work, msecs_to_jiffies(0)); + } +} + +int idtp_op_ble_flag(int en) +{ + int rc; + if (!g_di) + return -EINVAL; + + dev_info(g_di->dev, "set ble flag: %d\n", en); + + if (en) { + rc = g_di->bus.mask_write(g_di, REG_BLE_FLAG, BIT(0), BIT(0)); + schedule_delayed_work(&g_di->oob_set_cep_work, 0); + } else { + rc = g_di->bus.mask_write(g_di, REG_BLE_FLAG, BIT(0), 0); + cancel_delayed_work_sync(&g_di->oob_set_cep_work); + } + + return rc; +} + +static int rx_set_otg_state(struct idtp9220_device_info *di, int plugin) +{ + u8 mode; + di->otg_insert = plugin; + dev_info(di->dev, "[otg]set otg state: %d\n", plugin); + + if (!plugin || !di->is_reverse_mode) + return 0; + + di->bus.read(di, REG_WROK_MODE, &mode); + if (mode & BIT(2)) { + dev_info(di->dev, "[otg]already 148K: 0x%x\n", mode); + return 0; + } else { + di->bus.write(di, REG_TX_CMD, TX_TOGGLE); + msleep(10); + di->bus.read(di, REG_WROK_MODE, &mode); + dev_info(di->dev, "[otg]007B: 0x%x\n", mode); + if (mode & BIT(2)) + dev_info(di->dev, "[otg]set 148K success: 0x%x\n", + mode); + else + dev_info(di->dev, "[otg]set 148K error: 0x%x\n", mode); + } + + return 0; +} + +static enum power_supply_property idtp9220_props[] = { + POWER_SUPPLY_PROP_PIN_ENABLED, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_WIRELESS_VERSION, + POWER_SUPPLY_PROP_WIRELESS_FW_VERSION, + POWER_SUPPLY_PROP_SIGNAL_STRENGTH, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_VRECT, + POWER_SUPPLY_PROP_RX_IOUT, + POWER_SUPPLY_PROP_WIRELESS_TX_ID, + POWER_SUPPLY_PROP_TX_ADAPTER, + POWER_SUPPLY_PROP_REVERSE_CHG_MODE, + POWER_SUPPLY_PROP_CHIP_OK, + POWER_SUPPLY_PROP_DIV_2_MODE, + POWER_SUPPLY_PROP_OTG_STATE, + POWER_SUPPLY_PROP_REVERSE_CHG_HALL3, + POWER_SUPPLY_PROP_REVERSE_CHG_HALL4, + POWER_SUPPLY_PROP_REVERSE_PEN_SOC, + POWER_SUPPLY_PROP_REVERSE_VOUT, + POWER_SUPPLY_PROP_REVERSE_IOUT, +}; + +static int idtp9220_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct idtp9220_device_info *di = power_supply_get_drvdata(psy); + u8 temp = 0; + int rc = 0; + switch (psp) { + case POWER_SUPPLY_PROP_PIN_ENABLED: + val->intval = di->gpio_enable_val; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = di->dcin_present; + break; + case POWER_SUPPLY_PROP_WIRELESS_VERSION: + val->intval = di->epp; + break; + case POWER_SUPPLY_PROP_WIRELESS_FW_VERSION: + val->intval = di->fw_version; + break; + case POWER_SUPPLY_PROP_SIGNAL_STRENGTH: + val->intval = di->ss; + break; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + if (!di->power_good_flag) { + val->intval = 0; + break; + } + val->intval = idtp9220_get_vout(di); + break; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_VRECT: + if (!di->power_good_flag) { + val->intval = 0; + break; + } + val->intval = idtp9220_get_vrect(di); + break; + case POWER_SUPPLY_PROP_RX_IOUT: + if (!di->power_good_flag) { + val->intval = 0; + break; + } + val->intval = idtp9220_get_iout(di); + break; + case POWER_SUPPLY_PROP_WIRELESS_TX_ID: + val->intval = idtp9220_get_tx_id(di); + break; + case POWER_SUPPLY_PROP_TX_ADAPTER: + val->intval = di->tx_charger_type; + break; + case POWER_SUPPLY_PROP_REVERSE_CHG_MODE: + val->intval = gpio_get_value(di->dt_props.reverse_gpio); + break; + case POWER_SUPPLY_PROP_CHIP_OK: + val->intval = di->chip_ok; + break; + case POWER_SUPPLY_PROP_REVERSE_CHG_HALL3: + if (gpio_is_valid(di->dt_props.hall3_gpio)) { + val->intval = gpio_get_value(di->dt_props.hall3_gpio); + dev_info(di->dev, "hall3 gpio:%d\n", val->intval); + } else { + val->intval = -1; + dev_err(di->dev, "hall3 gpio is not provided\n"); + } + break; + case POWER_SUPPLY_PROP_REVERSE_CHG_HALL4: + if (gpio_is_valid(di->dt_props.hall4_gpio)) { + val->intval = gpio_get_value(di->dt_props.hall4_gpio); + dev_info(di->dev, "hall4 gpio:%d\n", val->intval); + } else { + val->intval = -1; + dev_err(di->dev, "hall4 gpio is not provided\n"); + } + break; + case POWER_SUPPLY_PROP_REVERSE_PEN_SOC: + if (di->is_reverse_mode || di->is_boost_mode) + val->intval = di->reverse_pen_soc; + else + val->intval = 50; + break; + case POWER_SUPPLY_PROP_REVERSE_VOUT: + if (di->is_reverse_mode || di->is_boost_mode) + val->intval = di->reverse_vout; + else + val->intval = 0; + break; + case POWER_SUPPLY_PROP_REVERSE_IOUT: + if (di->is_reverse_mode || di->is_boost_mode) + val->intval = di->reverse_iout; + else + val->intval = 0; + break; + case POWER_SUPPLY_PROP_OTG_STATE: + if (!di->power_good_flag) { + val->intval = 0; + break; + } + rc = idtp9220_get_temperature(di, &temp); + if (!rc) + val->intval = temp; + else + val->intval = 0; + default: + return -EINVAL; + } + return 0; +} + +#define RX_VOUT_MAX_MV 20000 +#define RX_VOUT_MIN_MV 12000 +#define RX_VOUT_OFFSET_MV 100 + +static int idtp9220_set_prop(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + struct idtp9220_device_info *di = power_supply_get_drvdata(psy); + int rc = 0; + + int data; + + switch (psp) { + case POWER_SUPPLY_PROP_PIN_ENABLED: + rc = idtp9220_set_enable_mode(di, val->intval); + break; + case POWER_SUPPLY_PROP_PRESENT: + rc = idtp9220_set_present(di, val->intval); + break; + case POWER_SUPPLY_PROP_SIGNAL_STRENGTH: + di->ss = val->intval; + if (di->idtp_psy) + power_supply_changed(di->idtp_psy); + break; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + data = val->intval / 1000; + + if (data > RX_VOUT_MAX_MV) + data = RX_VOUT_MAX_MV; + else if (data < RX_VOUT_MIN_MV) + data = RX_VOUT_MIN_MV + RX_VOUT_OFFSET_MV; + + if (di->power_good_flag) { + if (data == CP_CLOSE_VOUT_MV) + schedule_delayed_work( + &di->rx_vout_cp_close_work, 0); + else + idtp9220_set_vout(di, data); + } + break; + case POWER_SUPPLY_PROP_REVERSE_CHG_MODE: + if (di->fw_update) { + dev_info(di->dev, "fw update going, break\n"); + break; + } + + if (di->hall3_online || di->hall4_online) { + if (di->is_reverse_mode || di->is_boost_mode) { + dev_info(di->dev, + "reverse charge running, return\n"); + break; + } + } else { + dev_info(di->dev, + "pen detach, don't open reverse charge\n"); + break; + } + + di->is_reverse_chg = 0; + schedule_delayed_work(&di->reverse_sent_state_work, 0); + if (!di->power_good_flag) { + idtp9220_set_reverse_enable(di, val->intval); + } else { + di->is_reverse_chg = 3; + schedule_delayed_work(&di->reverse_sent_state_work, 0); + } + break; + case POWER_SUPPLY_PROP_OTG_STATE: + rx_set_otg_state(di, val->intval); + break; + case POWER_SUPPLY_PROP_DIV_2_MODE: + idtp9220_power_off(di); + break; + default: + return -EINVAL; + } + + return rc; +} + +static int idtp9220_prop_is_writeable(struct power_supply *psy, + enum power_supply_property psp) +{ + int rc; + + switch (psp) { + case POWER_SUPPLY_PROP_PIN_ENABLED: + case POWER_SUPPLY_PROP_PRESENT: + case POWER_SUPPLY_PROP_SIGNAL_STRENGTH: + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + case POWER_SUPPLY_PROP_REVERSE_CHG_MODE: + return 1; + default: + rc = 0; + break; + } + + return rc; +} + +static const struct power_supply_desc idtp_psy_desc = { + .name = "idt", + .type = POWER_SUPPLY_TYPE_WIRELESS, + .properties = idtp9220_props, + .num_properties = ARRAY_SIZE(idtp9220_props), + .get_property = idtp9220_get_prop, + .set_property = idtp9220_set_prop, + .property_is_writeable = idtp9220_prop_is_writeable, +}; + +#ifdef IDTP9220_SRAM_UPDATE +static void idtp9220_sram_update_work(struct work_struct *work) +{ + struct idtp9220_device_info *di = container_of( + work, struct idtp9220_device_info, sram_update_work.work); + u8 data; + int size = sizeof(idt_firmware_sram); + u8 buffer[size]; + int i = 0; + + di->bus.read(di, 0x4D, &data); + dev_info(di->dev, "[idtp] %s: 0x4D data:%x, (data & BIT(4)):%lu\n", + __func__, data, (data & BIT(4))); + if (!(data & BIT(4))) + return; + + di->bus.write_buf(di, 0x0600, idt_firmware_sram, size); + di->bus.read_buf(di, 0x0600, buffer, size); + + while (size--) { + if (idt_firmware_sram[i] == buffer[i]) { + printk("buffer[%d]:0x%x", i, buffer[i]); + } else { + printk("[idt] sram data is not right\n"); + return; + } + i++; + } + + di->bus.write(di, 0x4F, 0x5A); + + di->bus.write(di, 0x4E, BIT(6)); + + mdelay(1000); + di->bus.read(di, 0x4D, &data); + dev_info(di->dev, "[idtp] %s: 0x4D data:%x\n", __func__, data); +} +#endif + +/* +#ifdef CONFIG_DRM +static int wireless_fb_notifier_cb(struct notifier_block *self, +unsigned long event, void *data) +{ + +struct drm_notify_data *evdata = data; +int *blank; + +struct idtp9220_device_info *di = +container_of(self, struct idtp9220_device_info, wireless_fb_notif); + +mutex_lock(&di->screen_lock); +if (evdata && evdata->data && di) { +if (event == DRM_EARLY_EVENT_BLANK) { +blank = evdata->data; +if (*blank == DRM_BLANK_UNBLANK) { +di->screen_on = true; +pr_info("%s: screen_on\n", __func__); +if(di->status & FULL_MODE) +idtp922x_set_pmi_icl(di, DC_FUL_CURRENT); +} else if (*blank == DRM_BLANK_POWERDOWN) { +di->screen_on = false; +pr_info("%s: screen_off\n", __func__); +if(di->status & FULL_MODE) +idtp922x_set_pmi_icl(di, SCREEN_OFF_FUL_CURRENT); +} +} +} else { +pr_err("%s: Couldn't get DRM event\n", __func__); +mutex_unlock(&di->screen_lock); +return 0; +} +mutex_unlock(&di->screen_lock); +return 0; +} +#endif + */ + +static int idtp9220_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0; + int hall3_val = 1, hall4_val = 1; + struct idtp9220_device_info *di; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct power_supply_config idtp_cfg = {}; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) { + dev_err(&client->dev, "i2c check functionality failed!\n"); + return -EIO; + } + + di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL); + if (!di) { + dev_err(&client->dev, + "i2c allocated device info data failed!\n"); + return -ENOMEM; + } + + di->name = IDT_DRIVER_NAME; + di->dev = &client->dev; + di->chip_enable = 1; + di->ss = 2; + di->fw_update = false; + di->fw_version = 0; + di->status = NORMAL_MODE; + // set reverse pen soc to default + di->reverse_pen_soc = 255; + di->regmap = devm_regmap_init_i2c(client, &i2c_idtp9220_regmap_config); + if (!di->regmap) + return -ENODEV; + di->bus.read = idtp9220_read; + di->bus.write = idtp9220_write; + di->bus.read_buf = idtp9220_read_buffer; + di->bus.write_buf = idtp9220_write_buffer; + di->bus.mask_write = idtp9220_masked_write; + INIT_DELAYED_WORK(&di->irq_work, idtp9220_irq_work); + INIT_DELAYED_WORK(&di->hall3_irq_work, idtp9220_hall3_irq_work); + INIT_DELAYED_WORK(&di->hall4_irq_work, idtp9220_hall4_irq_work); + INIT_DELAYED_WORK(&di->wpc_det_work, idtp9220_wpc_det_work); + mutex_init(&di->read_lock); + mutex_init(&di->write_lock); + mutex_init(&di->wpc_det_lock); + /* + #ifdef CONFIG_DRM + mutex_init(&di->screen_lock); + #endif + */ + device_init_wakeup(&client->dev, true); + i2c_set_clientdata(client, di); + g_di = di; + + ret = idtp9220_parse_dt(di); + if (ret < 0) { + dev_err(di->dev, "%s: parse dt error [%d]\n", __func__, ret); + goto cleanup; + } + + ret = idtp9220_gpio_init(di); + if (ret < 0) { + dev_err(di->dev, "%s: gpio init error [%d]\n", __func__, ret); + goto cleanup; + } + + ret = idtp9220_irq_request(di); + if (ret < 0) { + dev_err(di->dev, "%s: request irq error [%d]\n", __func__, ret); + goto cleanup; + } + + /* + * this func write config to otp when init, due to the config will be + * write to otp in factory, so delete it. + * + + if (!program_fw(di, 0x0000, idt_firmware, sizeof(idt_firmware))) { + dev_err(&client->dev, "program fw failed.\n"); + //goto cleanup; + } + */ + + if (sysfs_create_group(&client->dev.kobj, &sysfs_group_attrs)) { + dev_err(&client->dev, "create sysfs attrs failed!\n"); + ret = -EIO; + goto cleanup; + } + idtp_cfg.drv_data = di; + di->idtp_psy = + power_supply_register(di->dev, &idtp_psy_desc, &idtp_cfg); + + INIT_DELAYED_WORK(&di->chg_monitor_work, idtp9220_monitor_work); + INIT_DELAYED_WORK(&di->chg_detect_work, idtp9220_chg_detect_work); + INIT_DELAYED_WORK(&di->bpp_connect_load_work, + idtp9220_bpp_connect_load_work); + INIT_DELAYED_WORK(&di->epp_connect_load_work, + idtp9220_epp_connect_load_work); + INIT_DELAYED_WORK(&di->cmd_check_work, idtp9220_cmd_check_work); + INIT_DELAYED_WORK(&di->vout_regulator_work, + idtp9220_vout_regulator_work); + INIT_DELAYED_WORK(&di->load_fod_param_work, + idtp9220_load_fod_param_work); + INIT_DELAYED_WORK(&di->rx_vout_work, idtp9220_rx_vout_work); + INIT_DELAYED_WORK(&di->dc_check_work, idtp9220_dc_check_work); + INIT_DELAYED_WORK(&di->initial_tx_work, idtp9220_initial_tx_work); + INIT_DELAYED_WORK(&di->bpp_e5_tx_work, idtp9220_bpp_e5_tx_work); + INIT_DELAYED_WORK(&di->pan_tx_work, idt_pan_tx_work); + INIT_DELAYED_WORK(&di->voice_tx_work, idt_voice_tx_work); + INIT_DELAYED_WORK(&di->qc2_f1_tx_work, idtp9220_qc2_f1_tx_work); + INIT_DELAYED_WORK(&di->qc3_epp_work, idtp9220_qc3_epp_work); + INIT_DELAYED_WORK(&di->oob_set_cep_work, idtp_oob_set_cep_work); + INIT_DELAYED_WORK(&di->oob_set_ept_work, idtp_oob_set_ept_work); + INIT_DELAYED_WORK(&di->rx_ready_check_work, idtp_rx_ready_check_work); + INIT_DELAYED_WORK(&di->oob_clean_work, idtp_oob_clean_work); + + INIT_DELAYED_WORK(&di->reverse_ept_type_work, + reverse_ept_type_get_work); + INIT_DELAYED_WORK(&di->reverse_chg_state_work, + reverse_chg_state_set_work); + INIT_DELAYED_WORK(&di->reverse_dping_state_work, + reverse_dping_state_set_work); + INIT_DELAYED_WORK(&di->reverse_test_state_work, + reverse_test_state_set_work); + INIT_DELAYED_WORK(&di->reverse_sent_state_work, + reverse_chg_sent_state_work); + + INIT_DELAYED_WORK(&di->get_vout_work, idtp9220_test_vout_work); + INIT_DELAYED_WORK(&di->get_iout_work, idtp9220_test_iout_work); + INIT_DELAYED_WORK(&di->fw_download_work, idtp9220_fw_download_work); + INIT_DELAYED_WORK(&di->idt_first_boot, idtp9220_idt_first_boot); + INIT_DELAYED_WORK(&di->rx_vout_cp_close_work, + idtp9220_rx_vout_cp_close_work); + INIT_DELAYED_WORK(&di->keep_awake_work, idtp9220_keep_awake_work); + INIT_DELAYED_WORK(&di->reverse_chg_work, idt_reverse_chg_work); + mutex_init(&di->sysfs_op_lock); + mutex_init(&di->reverse_op_lock); + + di->ocp_disable_votable = + create_votable("IDTP_OCP_DISABLE", VOTE_SET_ANY, + idtp9220_ocp_disable_vote_cb, di); + if (IS_ERR_OR_NULL(di->ocp_disable_votable)) { + PTR_ERR_OR_ZERO(di->ocp_disable_votable); + dev_err(di->dev, "Failed to initialize ocp_disable_votable\n"); + return -ENODEV; + } + //ret = idtp9220_get_property_names(di); + /* + #ifdef CONFIG_DRM + if (&di->wireless_fb_notif) { + di->wireless_fb_notif.notifier_call = wireless_fb_notifier_cb; + rc = drm_register_client(&di->wireless_fb_notif); + if (rc < 0) { + dev_err(di->dev, + "Couldn't register notifier rc=%d\n", rc); + return rc; + } + //INIT_DELAYED_WORK(&di->screen_on_work, wireless_screen_on_work); + } else + dev_err(di->dev, "Unsupported fb notifier \n"); + #endif + */ + + if (alarmtimer_get_rtcdev()) { + alarm_init(&di->reverse_dping_alarm, ALARM_BOOTTIME, + reverse_dping_alarm_cb); + } else { + dev_err(di->dev, "Failed to initialize reverse dping alarm\n"); + return -ENODEV; + } + + if (alarmtimer_get_rtcdev()) { + alarm_init(&di->reverse_chg_alarm, ALARM_BOOTTIME, + reverse_chg_alarm_cb); + } else { + dev_err(di->dev, "Failed to initialize reverse chg alarm\n"); + return -ENODEV; + } + if (alarmtimer_get_rtcdev()) { + alarm_init(&di->reverse_test_ready_alarm, ALARM_BOOTTIME, + reverse_test_ready_alarm_cb); + } else { + dev_err(di->dev, + "Failed to initialize reverse_test_ready_alarm alarm\n"); + return -ENODEV; + } + + if (gpio_is_valid(di->dt_props.hall3_gpio)) { + hall3_val = gpio_get_value(di->dt_props.hall3_gpio); + if (!hall3_val) { + dev_info(di->dev, "pen online, start reverse charge\n"); + schedule_delayed_work(&di->hall3_irq_work, + msecs_to_jiffies(5000)); + } + } else + dev_err(di->dev, "%s: hall3 gpio not provided\n", __func__); + + if (gpio_is_valid(di->dt_props.hall4_gpio)) { + hall4_val = gpio_get_value(di->dt_props.hall4_gpio); + if (!hall4_val) { + dev_info(di->dev, "pen online, start reverse charge\n"); + schedule_delayed_work(&di->hall4_irq_work, + msecs_to_jiffies(5000)); + } + } else + dev_err(di->dev, "%s: hall4 gpio not provided\n", __func__); + + dev_info(di->dev, "[idt] success probe idtp922x driver\n"); + get_cmdline(di); + if (!di->power_off_mode) +#ifdef CONFIG_FACTORY_BUILD + schedule_delayed_work(&di->chg_detect_work, 3 * HZ); +#else + schedule_delayed_work(&di->chg_detect_work, 8 * HZ); +#endif + else { + dev_info(di->dev, "off-chg mode, reset chip\n"); + idtp9220_set_enable_mode(di, false); + msleep(10); + idtp9220_set_enable_mode(di, true); + } + + if (!idt_first_flag) + schedule_delayed_work(&di->idt_first_boot, + msecs_to_jiffies(30000)); +#ifdef IDTP9220_SRAM_UPDATE + INIT_DELAYED_WORK(&di->sram_update_work, idtp9220_sram_update_work); + schedule_delayed_work(&di->sram_update_work, 10 * HZ); +#endif + return 0; + +cleanup: + free_irq(di->irq, di); + cancel_delayed_work_sync(&di->irq_work); + cancel_delayed_work_sync(&di->hall3_irq_work); + cancel_delayed_work_sync(&di->hall4_irq_work); + i2c_set_clientdata(client, NULL); + + return ret; +} + +static int idtp9220_remove(struct i2c_client *client) +{ + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + gpio_free(di->dt_props.reverse_gpio); + gpio_free(di->dt_props.reverse_boost_enable_gpio); + cancel_delayed_work_sync(&di->irq_work); + cancel_delayed_work_sync(&di->hall3_irq_work); + cancel_delayed_work_sync(&di->hall4_irq_work); + i2c_set_clientdata(client, NULL); + + return 0; +} + +static void idtp9220_shutdown(struct i2c_client *client) +{ + struct idtp9220_device_info *di = i2c_get_clientdata(client); + + if (di->power_good_flag) { + msleep(30); + idtp9220_set_enable_mode(di, false); + msleep(10); + idtp9220_set_enable_mode(di, true); + } +} + +static const struct i2c_device_id idtp9220_id[] = { + { IDT_DRIVER_NAME, 0 }, + {}, +}; + +static const struct of_device_id idt_match_table[] = { { .compatible = + "idt,p9418" }, + {} }; + +MODULE_DEVICE_TABLE(i2c, idtp9220_id); + +static struct i2c_driver idtp9220_driver = { + .driver = { + .name = IDT_DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = idt_match_table, + }, + .probe = idtp9220_probe, + .remove = idtp9220_remove, + .shutdown = idtp9220_shutdown, + .id_table = idtp9220_id, +}; + +static int __init idt_init(void) +{ + int ret; + + ret = i2c_add_driver(&idtp9220_driver); + if (ret) + printk(KERN_ERR "idt i2c driver init failed!\n"); + + return ret; +} + +static void __exit idt_exit(void) +{ + i2c_del_driver(&idtp9220_driver); +} + +module_init(idt_init); +module_exit(idt_exit); + +MODULE_AUTHOR("bsp@xiaomi.com"); +MODULE_DESCRIPTION("IDTP9220 Wireless Power Charger Monitor driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/power/supply/renesas/idtp9418.h b/drivers/power/supply/renesas/idtp9418.h new file mode 100644 index 000000000000..93de90033cee --- /dev/null +++ b/drivers/power/supply/renesas/idtp9418.h @@ -0,0 +1,507 @@ +/** + * @file idtp9220.h + * @author + * @date Sun Nov 22 11:49:55 2015 + * + * @brief + * + * + */ +#ifndef __IDTP9220_H__ +#define __IDTP9220_H__ + +#include +#include +#include +#include "idtp9418_fw.h" +#define IDT_DRIVER_NAME "idtp9418" +#define IDT_I2C_ADDR 0x3b + +#define HSCLK 60000 + +#define ADJUST_METE_MV 35 +#define IDTP9220_DELAY 2000 +#define CHARGING_FULL 100 +#define CHARGING_NEED 95 + +/* status low regiter bits define */ +#define STATUS_VOUT_ON (1 << 7) +#define STATUS_VOUT_OFF (1 << 6) +#define STATUS_TX_DATA_RECV (1 << 4) +#define STATUS_OV_TEMP (1 << 2) +#define STATUS_OV_VOL (1 << 1) +#define STATUS_OV_CURR (1 << 0) + +#define OVER_EVENT_OCCUR (STATUS_OV_TEMP | STATUS_OV_VOL | STATUS_OV_CURR) +#define TOGGLE_LDO_ON_OFF (1 << 1) + +/* interrupt register bits define */ +#define INT_RXREADY (1 << 22) +#define INT_POWER_LOSS (1 << 21) +#define INT_OVERCURRENT_HIGH (1 << 20) +#define RENEG_FAIL (1 << 19) +#define RENEG_SUCCESS (1 << 18) +#define INT_RPP_READ (1 << 17) +#define INT_EXT5V_FAIL (1 << 16) +#define INT_VSWITCH_FAIL (1 << 15) +#define INT_SLEEPMODE (1 << 14) +#define INT_IDAUTH_SUCESS (1 << 13) +#define INT_IDAUTH_FAIL (1 << 12) +#define INT_SEND_SUCESS (1 << 11) +#define INT_SEND_TIMEOUT (1 << 10) +#define INT_AUTH_SUCESS (1 << 9) +#define INT_AUTH_FAIL (1 << 8) +#define INT_VOUT_OFF (1 << 7) +#define INT_VOUT_ON (1 << 6) +#define INT_MODE_CHANGE (1 << 5) +#define INT_TX_DATA_RECV (1 << 4) +#define INT_VSWITCH_SUCESS (1 << 3) +#define INT_OV_TEMP (1 << 2) +#define INT_OV_VOL (1 << 1) +#define INT_OV_CURR (1 << 0) + +/*TRX int bits define*/ +#define INT_GET_BLE_ADDR (1 << 8) +#define INT_INIT_TX (1 << 7) +#define INT_GET_DPING (1 << 6) +#define INT_GET_PPP (1 << 5) +#define INT_GET_CFG (1 << 4) +#define INT_GET_ID (1 << 3) +#define INT_GET_SS (1 << 2) +#define INT_START_DPING (1 << 1) +#define INT_EPT_TYPE (1 << 0) + +#define TX_TOGGLE BIT(6) // toggle work mode(148K or 190K) +#define TX_FOD_EN BIT(5) // enable FOD +#define TX_WD BIT(4) // enable WD +#define TX_SEND_FSK BIT(3) // SEND_FSK +#define TX_DIS BIT(2) // disable tx +#define TX_CLRINT BIT(1) // clr int +#define TX_EN BIT(0) // enable tx mode + +/* used registers define */ +#define REG_CHIP_ID_L 0x0000 +#define REG_CHIP_ID_H 0x0001 +#define REG_CHIP_REV 0x0002 +#define REG_CTM_ID 0x0003 +#define REG_OTPFWVER_ADDR 0x0004 // OTP firmware version +#define REG_EPRFWVER_ADDR 0x001c // EEPROM firmware version +#define REG_SYS_INT_CLR 0x0028 // int clear +#define REG_SYS_INT 0x0030 // interrupt +#define REG_STATUS_L 0x0034 +#define REG_STATUS_H 0x0035 +#define REG_INTR_L 0x0036 +#define REG_INTR_H 0x0037 +#define REG_INTR_EN_L 0x0038 +#define REG_INTR_EN_H 0x0039 +#define REG_CHG_STATUS 0x003A +#define REG_ADC_VOUT_L 0x003C +#define REG_ADC_VOUT_H 0x003D +#define REG_VOUT_SET 0x003E +#define REG_VRECT_ADJ 0x003F +#define REG_ADC_VRECT 0x0040 +#define REG_RX_LOUT_L 0x0044 +#define REG_RX_LOUT_H 0x0045 +#define REG_RX_DIE_TEMP 0x0046 +#define REG_FREQ_ADDR \ + 0x0048 // Operating Frequency, Fop(KHz) = 64 * 6000 /value * 256) +#define REG_ILIM_SET 0x004A +#define REG_SIGNAL_STRENGTH 0x004B +#define REG_WPC_MODE 0x004D +#define REG_SSCMND 0x004e // Command Register, COM (0x4E) +#define REG_RX_RESET 0x004F +#define REG_PROPPKT \ + 0x0050 // Proprietary Packet Header Register, PPP_Header (0x50) +#define REG_PPPDATA \ + 0x0051 // PPP Data Value Register(0X51, 0x52, 0x53, 0x54, 0x55) +#define REG_SSINTCLR 0x0056 // Interrupt Clear Registers, INT_Clear_L (0x56) +#define REG_BCHEADER 0x0058 // Back Channel Packet Register (0x58) +#define REG_BCDATA \ + 0x0059 // Back Channel Packet Register (0x59, 0x5A, 0x5B, 0x5C) +#define REG_FC_VOLTAGE_L 0x0078 // Fast Charging Voltage Register +#define REG_FC_VOLTAGE_H 0x0079 +#define REG_REGULATOR_L 0x000C +#define REG_REGULATOR_H 0x000d +#define REG_POWER_MAX 0x0084 //Get the TX power on EPP mode. +#define REG_TX_TYPE 0x00A2 //Get the TX type. +#define REG_BLE_FLAG 0x00A4 //Get the rx ble flag. +#define REG_CEP 0x00A5 //Get the CEP. +#define REG_RPP 0x00A6 //Get the RPP. +#define REG_MAX_POWER 0x008E +#define REG_OCP_CONFIG 0x00F1 +#define REG_TEMPTER 0x00F2 + +/*add for reverse charge*/ +#define REG_EPT_TYPE 0x0074 +#define REG_TX_CMD 0x0076 +#define REG_TX_DATA 0x0078 +#define REG_WROK_MODE 0x007B +#define REG_VRECT_TAEGET 0x0090 +#define REG_FOD_LOW 0x0092 +#define REG_FOD_HIGH 0x0093 +#define REG_MAC_ADDR 0x00be + +#define REG_REVERSE_IIN_LOW 0x006e +#define REG_REVERSE_IIN_HIGH 0x006f +#define REG_REVERSE_VIN_LOW 0x0070 +#define REG_REVERSE_VIN_HIGH 0x0071 +#define REG_REVERSE_TEMP 0x007a + +#define EPT_POCP BIT(15) +#define EPT_OTP BIT(14) +#define EPT_FOD BIT(13) +#define EPT_LVP BIT(12) +#define EPT_OVP BIT(11) +#define EPT_OCP BIT(10) +#define EPT_RPP_TIMEOUT BIT(9) +#define EPT_CEP_TIMEOUT BIT(8) +#define EPT_CMD BIT(0) + +#define REG_EXTERNAL_5V 0x00dc //external 5v enable + +// RX -> TX +#define PROPRIETARY18 0x18 +#define PROPRIETARY28 0x28 +#define PROPRIETARY38 0x38 +#define PROPRIETARY48 0x48 +#define PROPRIETARY58 0x58 + +// bitmap for customer command +#define BC_NONE 0x00 +#define BC_SET_FREQ 0x03 +#define BC_GET_FREQ 0x04 +#define BC_READ_FW_VER 0x05 +#define BC_READ_Iin 0x06 +#define BC_READ_Vin 0x07 +#define BC_SET_Vin 0x0a + +#define BC_ADAPTER_TYPE 0x0b +#define BC_RESET 0x0c +#define BC_READ_I2C 0x0d +#define BC_WRITE_I2C 0x0e +#define BC_VI2C_INIT 0x10 +#define BC_RX_ID_AUTH 0x3b +#define BC_TX_COMPATIBLE_HWID 0x3f +#define BC_TX_HWID 0x4c +#define BC_TX_TOGGLE 0xc4 +#define CMD_GET_BLEMAC_2_0 0xb6 +#define CMD_GET_BLEMAC_5_3 0xb7 +#define CMD_FACOTRY_REVERSE 0x30 + +//Factory test command +#define BC_READ_IOUT 0x12 +#define BC_READ_VOUT 0x13 +#define BC_RX_CHIP_VERSION 0x23 +#define BC_RX_FW_VERSION 0x24 +#define BC_START_CHARGE 0x30 +#define BC_SET_AP_OVERLOAD 0x31 +#define BC_ENABLE_FAST_CHARGE 0x32 + +/* Adapter_list = {0x00:'ADAPTER_UNKNOWN', */ +/* 0x01:'SDP 500mA', */ +/* 0x02:'CDP 1.1A', */ +/* 0x03:'DCP 1.5A', */ +/* 0x05:'QC2.0', */ +/* 0x06:'QC3.0', */ +/* 0x07:'PD',} */ +//define adapter type +#define ADAPTER_NONE 0x00 +#define ADAPTER_SDP 0x01 +#define ADAPTER_CDP 0x02 +#define ADAPTER_DCP 0x03 +#define ADAPTER_QC2 0x05 +#define ADAPTER_QC3 0x06 +#define ADAPTER_PD 0x07 +#define ADAPTER_AUTH_FAILED 0x08 +#define ADAPTER_XIAOMI_QC3 0x09 +#define ADAPTER_XIAOMI_PD 0x0a +#define ADAPTER_ZIMI_CAR_POWER 0x0b +#define ADAPTER_XIAOMI_PD_40W 0x0c +#define ADAPTER_VOICE_BOX 0x0d +#define ADAPTER_XIAOMI_PD_45W 0x0e +#define ADAPTER_XIAOMI_PD_60W 0x0f + +#define NORMAL_MODE 0x1 +#define TAPER_MODE 0x2 +#define FULL_MODE 0x3 +#define RECHG_MODE 0x4 + +//fw version to update +#define FW_VERSION 0x1 + +//add for crc verify +#define CRC_VERIFY_LOW 0xB5 +#define CRC_VERIFY_HIGH 0xA9 + +//add for reverse fod +#define REVERSE_FOD 500 + +/*CLRPOWERGOOD BIT(10), upper byte is 0x8*/ +#define CLRPOWERGOOD 0x04 +// bitmap for status flags +// 1: indicates a pending interrupt for LDO Vout state change – from OFF to ON +#define VOUTCHANGED BIT(7) // Stat_Vout_ON +// 1: indicates a pending interrupt for TX Data Received. (Change from “No Received Data†state to “Data Received†state) +#define TXDATARCVD BIT(4) // TX Data Received + +// bitmap for SSCmnd register 0x4e +#define VSWITCH BIT(7) +// If AP sets this bit to "1" then IDTP9220 M0 clears the interrupt corresponding to the bit(s) which has a value of “1†+#define CLRINT BIT(5) // Clear Interrupt +// If AP sets this bit to "1" then IDTP9220 M0 toggles LDO output once (from on to off, or from off to on), and then sets this bit to “0†+#define LDOTGL BIT(1) // Toggle LDO On/OFF +// If AP sets this bit to “1†then IDTP9220 M0 sends the Proprietary Packet +#define SENDPROPP BIT(0) // SEND RX Data + +#define SEND_DEVICE_AUTH BIT(2) + +enum VOUT_SET_VAL { + VOUT_VAL_3500_MV = 0, + VOUT_VAL_3600_MV, + VOUT_VAL_3700_MV, + VOUT_VAL_3800_MV, + VOUT_VAL_3900_MV, + VOUT_VAL_4000_MV, + VOUT_VAL_4100_MV, + VOUT_VAL_4200_MV, + VOUT_VAL_4300_MV, + VOUT_VAL_4400_MV, + VOUT_VAL_4500_MV, + VOUT_VAL_4600_MV, + VOUT_VAL_4700_MV, + VOUT_VAL_4800_MV, + VOUT_VAL_4900_MV, + VOUT_VAL_5000_MV, + VOUT_VAL_5100_MV, + VOUT_VAL_5200_MV, + VOUT_VAL_5300_MV, + VOUT_VAL_5400_MV, + VOUT_VAL_5500_MV, + VOUT_VAL_5600_MV, + VOUT_VAL_5700_MV, + VOUT_VAL_5800_MV, + VOUT_VAL_5900_MV, + VOUT_VAL_6000_MV, + VOUT_VAL_6100_MV, + VOUT_VAL_6200_MV, + VOUT_VAL_6300_MV, + VOUT_VAL_6400_MV, + VOUT_VAL_6500_MV, + VOUT_VAL_6600_MV, + VOUT_VAL_6700_MV, + VOUT_VAL_6800_MV, + VOUT_VAL_6900_MV, + VOUT_VAL_7000_MV, + VOUT_VAL_7100_MV, + VOUT_VAL_7200_MV, + VOUT_VAL_7300_MV, + VOUT_VAL_7400_MV, + VOUT_VAL_7500_MV, + VOUT_VAL_7600_MV, + VOUT_VAL_7700_MV, + VOUT_VAL_7800_MV, + VOUT_VAL_7900_MV, + VOUT_VAL_8000_MV, +}; + +enum IMIL_SET_VAL { + CURR_VAL_100_MA = 0, + CURR_VAL_200_MA, + CURR_VAL_300_MA, + CURR_VAL_400_MA, + CURR_VAL_500_MA, + CURR_VAL_600_MA, + CURR_VAL_700_MA, + CURR_VAL_800_MA, + CURR_VAL_900_MA, + CURR_VAL_1000_MA, + CURR_VAL_1100_MA, + CURR_VAL_1200_MA, + CURR_VAL_1300_MA, +}; + +struct vol_curr_table { + int index; + char *val; +}; +/* +struct idtp9220_platform_data { + enum VOUT_SET_VAL vout_val_default; + enum IMIL_SET_VAL curr_val_default; + unsigned long gpio_en; +}; +*/ +typedef struct { // write to structure at SRAM address 0x0400 + u16 status; // Read/Write by both 9220 and 9220 host + u16 startAddr; // OTP image address of the current packet + u16 codeLength; // The size of the OTP image data in the current packet + u16 dataChksum; // Checksum of the current packet + u8 dataBuf[128]; // OTP image data of the current packet +} idtp9220_packet_t; + +// proprietary packet type +typedef struct { + u8 header; // The header consists of a single byte that indicates the Packet type. + u8 cmd; // Back channel command + u8 data[4]; // Send data buffer +} ProPkt_Type; + +#if 1 +static char bootloader_data[] = { + 0x00, 0x02, 0x00, 0x20, 0x99, 0x00, 0x00, 0x00, 0x9D, 0x00, 0x00, 0x00, + 0x9F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x02, 0xF8, 0x00, 0xF0, 0x30, 0xF8, + 0x0C, 0xA0, 0x30, 0xC8, 0x08, 0x38, 0x24, 0x18, 0x2D, 0x18, 0xA2, 0x46, + 0x67, 0x1E, 0xAB, 0x46, 0x54, 0x46, 0x5D, 0x46, 0xAC, 0x42, 0x01, 0xD1, + 0x00, 0xF0, 0x22, 0xF8, 0x7E, 0x46, 0x0F, 0x3E, 0x0F, 0xCC, 0xB6, 0x46, + 0x01, 0x26, 0x33, 0x42, 0x00, 0xD0, 0xFB, 0x1A, 0xA2, 0x46, 0xAB, 0x46, + 0x33, 0x43, 0x18, 0x47, 0xA8, 0x06, 0x00, 0x00, 0xB8, 0x06, 0x00, 0x00, + 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x10, 0x3A, 0x01, 0xD3, + 0x78, 0xC1, 0xFB, 0xD8, 0x52, 0x07, 0x00, 0xD3, 0x30, 0xC1, 0x00, 0xD5, + 0x0B, 0x60, 0x70, 0x47, 0x1F, 0xB5, 0x1F, 0xBD, 0x10, 0xB5, 0x10, 0xBD, + 0x00, 0xF0, 0x09, 0xFB, 0x11, 0x46, 0xFF, 0xF7, 0xF7, 0xFF, 0x00, 0xF0, + 0x45, 0xFA, 0x00, 0xF0, 0x21, 0xFB, 0x03, 0xB4, 0xFF, 0xF7, 0xF2, 0xFF, + 0x03, 0xBC, 0x00, 0xF0, 0x27, 0xFB, 0x00, 0x00, 0x05, 0x48, 0x00, 0x47, + 0xFE, 0xE7, 0xFE, 0xE7, 0xFE, 0xE7, 0x00, 0x00, 0x03, 0x48, 0x04, 0x49, + 0x02, 0x4A, 0x04, 0x4B, 0x70, 0x47, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x20, 0x60, 0x01, 0x00, 0x20, 0x60, 0x00, 0x00, 0x20, + 0xFE, 0xB5, 0x04, 0x46, 0x00, 0x20, 0x02, 0x90, 0x10, 0x20, 0x20, 0x40, + 0x00, 0x28, 0x64, 0xD0, 0x01, 0x20, 0xFA, 0x4E, 0x30, 0x80, 0x80, 0x1E, + 0x30, 0x81, 0x01, 0x46, 0xF8, 0x4E, 0x31, 0x83, 0x08, 0x0C, 0x70, 0x83, + 0x00, 0x22, 0x44, 0xE0, 0xF6, 0x48, 0x40, 0x88, 0x80, 0x18, 0x83, 0xB2, + 0x01, 0x93, 0xD8, 0x13, 0x00, 0x28, 0x03, 0xD1, 0x01, 0x20, 0xC0, 0x03, + 0x18, 0x43, 0x01, 0x90, 0xEF, 0x48, 0xC2, 0x81, 0x03, 0x80, 0xEE, 0x4E, + 0x01, 0x98, 0x70, 0x80, 0x01, 0x98, 0x05, 0x78, 0xEA, 0x48, 0x85, 0x80, + 0x30, 0x46, 0x85, 0x80, 0x30, 0x20, 0x20, 0x40, 0x10, 0x28, 0x07, 0xD1, + 0x00, 0xBF, 0xE6, 0x48, 0x00, 0x88, 0x40, 0x06, 0xC0, 0x0F, 0x00, 0x28, + 0xF9, 0xD1, 0x1E, 0xE0, 0x00, 0x20, 0x00, 0x90, 0x18, 0xE0, 0xC8, 0x0F, + 0x07, 0x27, 0x00, 0x9E, 0xBE, 0x1B, 0x2F, 0x46, 0x37, 0x41, 0xFE, 0x07, + 0xF6, 0x0F, 0x70, 0x40, 0x00, 0x28, 0x01, 0xD0, 0xDE, 0x48, 0x00, 0xE0, + 0x00, 0x20, 0x4E, 0x00, 0x70, 0x40, 0x01, 0x46, 0xD9, 0x4E, 0x31, 0x83, + 0x08, 0x0C, 0x70, 0x83, 0x00, 0x98, 0x40, 0x1C, 0xC0, 0xB2, 0x00, 0x90, + 0x00, 0x98, 0x07, 0x28, 0xE3, 0xDD, 0x50, 0x1C, 0x82, 0xB2, 0xD4, 0x48, + 0x80, 0x88, 0x90, 0x42, 0xB6, 0xDC, 0x30, 0x20, 0x20, 0x40, 0x10, 0x28, + 0x13, 0xD1, 0xCE, 0x48, 0x00, 0x89, 0xCE, 0x4E, 0x70, 0x82, 0xCC, 0x48, + 0x00, 0x89, 0xCD, 0x4E, 0xF6, 0x88, 0xB0, 0x42, 0x02, 0xD1, 0x00, 0x20, + 0x02, 0x90, 0x2F, 0xE0, 0x01, 0x20, 0x02, 0x90, 0xC6, 0x48, 0x00, 0x89, + 0xC7, 0x4E, 0xF0, 0x80, 0x28, 0xE0, 0x88, 0xB2, 0xC5, 0x4E, 0xF6, 0x88, + 0xB0, 0x42, 0x01, 0xD1, 0x01, 0x20, 0x00, 0xE0, 0x00, 0x20, 0x0E, 0x02, + 0x36, 0x0E, 0xC1, 0x4F, 0x3F, 0x7A, 0xBE, 0x42, 0x01, 0xD1, 0x01, 0x26, + 0x00, 0xE0, 0x00, 0x26, 0x30, 0x40, 0x0E, 0x0E, 0xBC, 0x4F, 0x7F, 0x7A, + 0xBE, 0x42, 0x01, 0xD1, 0x01, 0x26, 0x00, 0xE0, 0x00, 0x26, 0x30, 0x40, + 0x00, 0x28, 0x02, 0xD0, 0x00, 0x20, 0x02, 0x90, 0x08, 0xE0, 0x01, 0x20, + 0x02, 0x90, 0xB5, 0x4E, 0xF1, 0x80, 0x08, 0x02, 0x00, 0x0E, 0x30, 0x72, + 0x08, 0x0E, 0x70, 0x72, 0x02, 0x98, 0xFE, 0xBD, 0x10, 0xB5, 0x02, 0x46, + 0xAE, 0x4B, 0x1B, 0x8A, 0x04, 0x24, 0x23, 0x43, 0xAC, 0x4C, 0x23, 0x82, + 0x63, 0x14, 0xAE, 0x4C, 0xA3, 0x81, 0x93, 0x00, 0x19, 0x60, 0xAD, 0x4B, + 0x1B, 0x88, 0xA4, 0x14, 0x23, 0x40, 0x18, 0x46, 0xA6, 0x4B, 0x1B, 0x8A, + 0x04, 0x24, 0xA3, 0x43, 0xA4, 0x4C, 0x23, 0x82, 0xA8, 0x4B, 0xA6, 0x4C, + 0xA3, 0x81, 0x10, 0xBD, 0x10, 0xB5, 0x02, 0x46, 0xA0, 0x4B, 0x1B, 0x8A, + 0x02, 0x24, 0x23, 0x43, 0x9E, 0x4C, 0x23, 0x82, 0x63, 0x14, 0xA0, 0x4C, + 0xA3, 0x81, 0x11, 0x70, 0x9F, 0x4B, 0x1B, 0x88, 0xA4, 0x14, 0x23, 0x40, + 0x18, 0x46, 0x99, 0x4B, 0x1B, 0x8A, 0x02, 0x24, 0xA3, 0x43, 0x97, 0x4C, + 0x23, 0x82, 0x9B, 0x4B, 0x98, 0x4C, 0xA3, 0x81, 0x10, 0xBD, 0xF1, 0xB5, + 0x88, 0xB0, 0x08, 0x9D, 0x00, 0x20, 0x00, 0x90, 0x91, 0x48, 0x00, 0x8A, + 0x08, 0x21, 0x88, 0x43, 0x8F, 0x49, 0x08, 0x82, 0x8F, 0x48, 0x00, 0x88, + 0x00, 0x07, 0x00, 0x0F, 0x03, 0x90, 0x8D, 0x48, 0x40, 0x88, 0x02, 0x90, + 0x8B, 0x48, 0x80, 0x88, 0x01, 0x90, 0x01, 0x99, 0x02, 0x98, 0x40, 0x18, + 0x40, 0x1E, 0x80, 0xB2, 0x05, 0x90, 0x05, 0x98, 0xC0, 0x13, 0x00, 0x28, + 0x04, 0xD1, 0x01, 0x21, 0xC9, 0x03, 0x05, 0x98, 0x08, 0x43, 0x05, 0x90, + 0x02, 0x98, 0x07, 0x90, 0x01, 0x99, 0x07, 0x98, 0x40, 0x18, 0x80, 0xB2, + 0x07, 0x90, 0x00, 0x27, 0x08, 0xE0, 0x7E, 0x48, 0x08, 0x30, 0xC1, 0x5D, + 0x07, 0x98, 0x08, 0x18, 0x80, 0xB2, 0x07, 0x90, 0x78, 0x1C, 0x87, 0xB2, + 0x01, 0x98, 0x87, 0x42, 0xF3, 0xDB, 0x77, 0x49, 0x07, 0x98, 0x48, 0x82, + 0x76, 0x48, 0xC1, 0x88, 0x07, 0x98, 0x81, 0x42, 0x73, 0xD1, 0x03, 0x98, + 0x01, 0x28, 0x01, 0xD1, 0x00, 0x20, 0x0C, 0xE0, 0x03, 0x98, 0x03, 0x28, + 0x01, 0xD1, 0x04, 0x20, 0x07, 0xE0, 0x03, 0x98, 0x05, 0x28, 0x01, 0xD1, + 0x24, 0x20, 0x02, 0xE0, 0x6F, 0x48, 0x20, 0x30, 0x00, 0x89, 0x6E, 0x49, + 0x20, 0x31, 0x08, 0x81, 0x00, 0x27, 0xBE, 0xE0, 0x02, 0x98, 0xC0, 0x19, + 0x80, 0xB2, 0x06, 0x90, 0x30, 0x0A, 0x66, 0x49, 0x08, 0x31, 0xC9, 0x5D, + 0x09, 0x06, 0x08, 0x43, 0x06, 0x46, 0x06, 0x9C, 0x61, 0x48, 0xC7, 0x81, + 0x60, 0x49, 0x06, 0x98, 0x08, 0x80, 0x30, 0x0C, 0xC8, 0x80, 0x8E, 0x80, + 0x06, 0x98, 0xC0, 0x13, 0x00, 0x28, 0x03, 0xD1, 0x89, 0x13, 0x06, 0x98, + 0x08, 0x43, 0x04, 0x46, 0x04, 0x98, 0x00, 0x0A, 0x21, 0x78, 0x09, 0x06, + 0x08, 0x43, 0x04, 0x90, 0x56, 0x48, 0x44, 0x80, 0x04, 0x98, 0x00, 0x0C, + 0x54, 0x49, 0x48, 0x81, 0x04, 0x98, 0x08, 0x81, 0x03, 0x98, 0x01, 0x28, + 0x02, 0xD0, 0x03, 0x98, 0x03, 0x28, 0x16, 0xD1, 0x04, 0x98, 0x00, 0x0E, + 0x31, 0x0E, 0x88, 0x42, 0x0D, 0xD0, 0x31, 0x0E, 0x20, 0x46, 0xFF, 0xF7, + 0x53, 0xFF, 0x00, 0x28, 0x08, 0xD1, 0x20, 0x78, 0x04, 0x90, 0x31, 0x0E, + 0x04, 0x98, 0x81, 0x42, 0x79, 0xD0, 0x68, 0x1C, 0x85, 0xB2, 0x76, 0xE0, + 0x68, 0x1C, 0x85, 0xB2, 0x73, 0xE0, 0x03, 0x98, 0x05, 0x28, 0x70, 0xD1, + 0xA0, 0x07, 0x80, 0x0F, 0x00, 0x28, 0x07, 0xD1, 0x01, 0x20, 0x00, 0x90, + 0x3F, 0x48, 0x00, 0x8A, 0x08, 0x21, 0x08, 0x43, 0x3D, 0x49, 0x08, 0x82, + 0x42, 0x49, 0x05, 0x98, 0x08, 0x40, 0xA0, 0x42, 0x02, 0xD1, 0x01, 0x20, + 0x01, 0xE0, 0x65, 0xE0, 0x00, 0x20, 0x05, 0x99, 0x89, 0x07, 0x89, 0x0F, + 0x03, 0x29, 0x01, 0xD0, 0x01, 0x21, 0x00, 0xE0, 0x00, 0x21, 0x08, 0x40, + 0x00, 0x28, 0x07, 0xD0, 0x00, 0x20, 0x00, 0x90, 0x31, 0x48, 0x00, 0x8A, + 0x08, 0x21, 0x88, 0x43, 0x2F, 0x49, 0x08, 0x82, 0x00, 0x98, 0x00, 0x28, + 0x20, 0xD1, 0x31, 0x48, 0x20, 0x30, 0x00, 0x89, 0x20, 0x21, 0x88, 0x43, + 0x2E, 0x49, 0x20, 0x31, 0x08, 0x81, 0x08, 0x46, 0x00, 0x89, 0x04, 0x21, + 0x08, 0x43, 0x2B, 0x49, 0x20, 0x31, 0x08, 0x81, 0x31, 0x0E, 0x20, 0x46, + 0xFF, 0xF7, 0x04, 0xFF, 0x00, 0x28, 0x08, 0xD1, 0x20, 0x78, 0x04, 0x90, + 0x31, 0x0E, 0x04, 0x98, 0x81, 0x42, 0x2A, 0xD0, 0x68, 0x1C, 0x85, 0xB2, + 0x27, 0xE0, 0x68, 0x1C, 0x85, 0xB2, 0x24, 0xE0, 0xA0, 0x07, 0x80, 0x0F, + 0x03, 0x28, 0x20, 0xD1, 0x1E, 0x48, 0x20, 0x30, 0x00, 0x89, 0x20, 0x21, + 0x08, 0x43, 0x1C, 0x49, 0x20, 0x31, 0x08, 0x81, 0x08, 0x46, 0x00, 0x89, + 0x04, 0x21, 0x08, 0x43, 0x18, 0x49, 0x20, 0x31, 0x08, 0x81, 0xA0, 0x10, + 0x31, 0x46, 0xFF, 0xF7, 0xC3, 0xFE, 0x00, 0x28, 0x09, 0xD1, 0xA0, 0x10, + 0x80, 0x00, 0x00, 0x68, 0x04, 0x90, 0x04, 0x98, 0xB0, 0x42, 0x04, 0xD0, + 0x28, 0x1D, 0x85, 0xB2, 0x01, 0xE0, 0x28, 0x1D, 0x85, 0xB2, 0x0A, 0x48, + 0x85, 0x81, 0x78, 0x1C, 0x87, 0xB2, 0x01, 0x98, 0x87, 0x42, 0x00, 0xDA, + 0x3C, 0xE7, 0x06, 0xE0, 0x06, 0x48, 0x80, 0x88, 0x40, 0x19, 0x85, 0xB2, + 0x01, 0x20, 0xC0, 0x03, 0x05, 0x43, 0x28, 0x46, 0x09, 0xB0, 0xF0, 0xBD, + 0x00, 0x70, 0x00, 0x40, 0x00, 0x05, 0x00, 0x20, 0x00, 0x04, 0x00, 0x20, + 0xB7, 0x1D, 0xC1, 0x04, 0x40, 0x30, 0x00, 0x40, 0x00, 0x5C, 0x00, 0x40, + 0xFF, 0x1F, 0x00, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0x0C, 0xB5, 0x00, 0x21, + 0x01, 0x91, 0x10, 0xE0, 0x00, 0x21, 0x00, 0x91, 0x04, 0xE0, 0x69, 0x46, + 0x09, 0x88, 0x49, 0x1C, 0x8A, 0xB2, 0x00, 0x92, 0x69, 0x46, 0x09, 0x88, + 0x02, 0x29, 0xF6, 0xDB, 0x69, 0x46, 0x89, 0x88, 0x49, 0x1C, 0x8A, 0xB2, + 0x01, 0x92, 0x69, 0x46, 0x89, 0x88, 0x81, 0x42, 0xEA, 0xDB, 0x0C, 0xBD, + 0x5A, 0x20, 0x53, 0x49, 0x08, 0x80, 0x05, 0x20, 0x88, 0x80, 0x04, 0x20, + 0x08, 0x81, 0x51, 0x48, 0x88, 0x81, 0x50, 0x20, 0xFF, 0xF7, 0xDA, 0xFF, + 0x4F, 0x48, 0x4D, 0x49, 0x88, 0x82, 0x4F, 0x48, 0x08, 0x82, 0x18, 0x20, + 0x88, 0x83, 0x08, 0x46, 0x00, 0x8B, 0x17, 0x21, 0x49, 0x02, 0x08, 0x43, + 0x47, 0x49, 0x08, 0x83, 0x08, 0x46, 0x00, 0x8B, 0x2E, 0x21, 0x08, 0x43, + 0x44, 0x49, 0x08, 0x83, 0x05, 0x20, 0xFF, 0xF7, 0xC3, 0xFF, 0x42, 0x48, + 0x80, 0x8B, 0x01, 0x21, 0x08, 0x43, 0x40, 0x49, 0x88, 0x83, 0x32, 0x20, + 0x42, 0x49, 0x08, 0x80, 0x94, 0x20, 0x42, 0x49, 0x08, 0x80, 0x15, 0x20, + 0x08, 0x80, 0x08, 0x46, 0x80, 0x8A, 0x60, 0x21, 0x88, 0x43, 0x3E, 0x49, + 0x88, 0x82, 0x00, 0x20, 0x3D, 0x49, 0x08, 0x80, 0x3D, 0x49, 0x08, 0x80, + 0x48, 0x80, 0x00, 0x24, 0x00, 0x27, 0x01, 0x25, 0x00, 0x26, 0x06, 0xE0, + 0x00, 0x20, 0x71, 0x00, 0x39, 0x4A, 0x89, 0x18, 0x08, 0x80, 0x70, 0x1C, + 0x86, 0xB2, 0x10, 0x2E, 0xF6, 0xDB, 0x5A, 0xE0, 0x34, 0x48, 0x00, 0x88, + 0xC0, 0x07, 0xC0, 0x0F, 0x00, 0x28, 0x54, 0xD0, 0x31, 0x48, 0x00, 0x88, + 0xC0, 0xB2, 0x30, 0x49, 0x08, 0x80, 0x5A, 0x20, 0x30, 0x49, 0x08, 0x82, + 0x00, 0x20, 0x26, 0x49, 0x60, 0x31, 0x08, 0x80, 0x2B, 0x48, 0x00, 0x88, + 0x11, 0x21, 0x08, 0x40, 0x01, 0x28, 0x27, 0xD1, 0x01, 0x25, 0x28, 0x48, + 0x00, 0x88, 0xC0, 0xB2, 0x29, 0x02, 0x08, 0x43, 0x25, 0x49, 0x08, 0x80, + 0x25, 0x48, 0x00, 0x8A, 0x01, 0x21, 0x08, 0x43, 0x23, 0x49, 0x08, 0x82, + 0x00, 0x20, 0xFF, 0xF7, 0x3A, 0xFE, 0x04, 0x46, 0x20, 0x48, 0x00, 0x8A, + 0xA8, 0x43, 0x1F, 0x49, 0x08, 0x82, 0x60, 0x04, 0x40, 0x0C, 0xC0, 0x19, + 0x87, 0xB2, 0x88, 0x13, 0x20, 0x40, 0x00, 0x28, 0x01, 0xD0, 0x08, 0x20, + 0x04, 0xE0, 0x00, 0x2C, 0x01, 0xD0, 0x04, 0x20, 0x00, 0xE0, 0x02, 0x20, + 0x05, 0x46, 0x11, 0xE0, 0x01, 0x25, 0x14, 0x48, 0x00, 0x88, 0xC0, 0xB2, + 0x29, 0x02, 0x08, 0x43, 0x11, 0x49, 0x08, 0x80, 0x08, 0x88, 0xFF, 0xF7, + 0x41, 0xFD, 0x04, 0x46, 0x00, 0x2C, 0x01, 0xD0, 0x08, 0x20, 0x00, 0xE0, + 0x02, 0x20, 0x05, 0x46, 0x0B, 0x48, 0x47, 0x80, 0x00, 0x88, 0xFE, 0x21, + 0x08, 0x40, 0x29, 0x02, 0x08, 0x43, 0x08, 0x49, 0x08, 0x80, 0xA3, 0xE7, + 0x00, 0x30, 0x00, 0x40, 0x01, 0x04, 0x00, 0x00, 0x0A, 0x20, 0x00, 0x00, + 0xFF, 0x07, 0x00, 0x00, 0x40, 0x54, 0x00, 0x40, 0x00, 0x58, 0x00, 0x40, + 0x40, 0x6C, 0x00, 0x40, 0x00, 0x04, 0x00, 0x20, 0x00, 0x05, 0x00, 0x20, + 0x40, 0x5C, 0x00, 0x40, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47, 0x75, 0x46, + 0x00, 0xF0, 0x24, 0xF8, 0xAE, 0x46, 0x05, 0x00, 0x69, 0x46, 0x53, 0x46, + 0xC0, 0x08, 0xC0, 0x00, 0x85, 0x46, 0x18, 0xB0, 0x20, 0xB5, 0xFF, 0xF7, + 0xFD, 0xFC, 0x60, 0xBC, 0x00, 0x27, 0x49, 0x08, 0xB6, 0x46, 0x00, 0x26, + 0xC0, 0xC5, 0xC0, 0xC5, 0xC0, 0xC5, 0xC0, 0xC5, 0xC0, 0xC5, 0xC0, 0xC5, + 0xC0, 0xC5, 0xC0, 0xC5, 0x40, 0x3D, 0x49, 0x00, 0x8D, 0x46, 0x70, 0x47, + 0x10, 0xB5, 0x04, 0x46, 0xC0, 0x46, 0xC0, 0x46, 0x20, 0x46, 0xFF, 0xF7, + 0xD8, 0xFC, 0x10, 0xBD, 0x00, 0x48, 0x70, 0x47, 0x00, 0x00, 0x00, 0x20, + 0x01, 0x49, 0x18, 0x20, 0xAB, 0xBE, 0xFE, 0xE7, 0x26, 0x00, 0x02, 0x00, + 0x70, 0x47, 0x00, 0x00, 0x04, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x60, 0x01, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00 +}; + +#endif + +extern uint32_t get_hw_version_major(void); + +#endif diff --git a/drivers/power/supply/renesas/idtp9418_fw.h b/drivers/power/supply/renesas/idtp9418_fw.h new file mode 100644 index 000000000000..a0c68039ec8b --- /dev/null +++ b/drivers/power/supply/renesas/idtp9418_fw.h @@ -0,0 +1,3083 @@ +/** +* @file./release/P9418_xiaomi_v2.8.0.c.h +* @author +* @date2021-07-3 +* @customerXiaomi +* @brief +* +*/ + +unsigned char idt_firmware[] = { + 0x00, 0x08, 0x00, 0x20, 0xff, 0x03, 0x00, 0x00, + 0x71, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, /// 0x10 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /// 0x20 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, /// 0x30 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /// 0x40 + 0x5d, 0x13, 0x00, 0x00, 0x63, 0x13, 0x00, 0x00, + 0x69, 0x13, 0x00, 0x00, 0x6f, 0x13, 0x00, 0x00, /// 0x50 + 0x75, 0x13, 0x00, 0x00, 0x7b, 0x13, 0x00, 0x00, + 0x81, 0x13, 0x00, 0x00, 0x87, 0x13, 0x00, 0x00, /// 0x60 + 0x8d, 0x13, 0x00, 0x00, 0x93, 0x13, 0x00, 0x00, + 0x99, 0x13, 0x00, 0x00, 0x9f, 0x13, 0x00, 0x00, /// 0x70 + 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, + 0xfe, 0xe7, 0x00, 0x20, 0x00, 0x68, 0x80, 0xf3, /// 0x80 + 0x08, 0x88, 0x70, 0x47, 0xf3, 0x48, 0x00, 0x21, + 0x01, 0x73, 0x41, 0x73, 0x70, 0x47, 0x10, 0xb5, /// 0x90 + 0xf0, 0x4b, 0x1a, 0x7b, 0x5c, 0x7b, 0x51, 0x1c, + 0x09, 0x07, 0x09, 0x0f, 0x8c, 0x42, 0x01, 0xd1, /// 0xa0 + 0x01, 0x20, 0x10, 0xbd, 0xec, 0x4c, 0x92, 0x00, + 0x12, 0x19, 0xff, 0x32, 0x01, 0x32, 0xd0, 0x60, /// 0xb0 + 0x19, 0x73, 0x00, 0x20, 0x10, 0xbd, 0xe8, 0x4e, + 0x34, 0x46, 0xff, 0x34, 0x41, 0x34, 0x21, 0x7b, /// 0xc0 + 0x60, 0x7b, 0x81, 0x42, 0x01, 0xd1, 0x30, 0xbf, + 0xf9, 0xe7, 0x81, 0x00, 0x89, 0x19, 0xff, 0x31, /// 0xd0 + 0x01, 0x31, 0xcd, 0x68, 0x00, 0x2d, 0x0c, 0xd0, + 0x40, 0x1c, 0x00, 0x07, 0x00, 0x0f, 0x60, 0x73, /// 0xe0 + 0xa8, 0x47, 0x00, 0x28, 0xeb, 0xd0, 0x72, 0xb6, + 0x28, 0x46, 0xff, 0xf7, 0xd0, 0xff, 0x62, 0xb6, /// 0xf0 + 0xe5, 0xe7, 0xff, 0xf7, 0xc7, 0xff, 0xe2, 0xe7, + 0x08, 0xb5, 0xd9, 0x49, 0xd7, 0x48, 0x08, 0x60, /// 0x100 + 0xff, 0xf7, 0xbb, 0xff, 0xd7, 0x4f, 0x5a, 0x20, + 0x38, 0x70, 0x00, 0x24, 0x3c, 0x71, 0x09, 0x20, /// 0x110 + 0x38, 0x72, 0xd5, 0x48, 0xb8, 0x81, 0xd4, 0x48, + 0xfb, 0x38, 0xb8, 0x82, 0xd3, 0x48, 0x38, 0x83, /// 0x120 + 0xb8, 0x8a, 0x79, 0x14, 0x08, 0x43, 0xb8, 0x82, + 0x01, 0x25, 0x3d, 0x82, 0x4d, 0x20, 0x00, 0x01, /// 0x130 + 0xb8, 0x83, 0x14, 0x20, 0x00, 0xf0, 0x78, 0xfc, + 0xb8, 0x8b, 0x08, 0x26, 0x30, 0x43, 0xb8, 0x83, /// 0x140 + 0x14, 0x20, 0x00, 0xf0, 0x71, 0xfc, 0xb8, 0x8b, + 0x28, 0x43, 0xb8, 0x83, 0x14, 0x20, 0x00, 0xf0, /// 0x150 + 0x6b, 0xfc, 0xb8, 0x8b, 0xa8, 0x43, 0xb8, 0x83, + 0x14, 0x20, 0x00, 0xf0, 0x65, 0xfc, 0xb8, 0x8b, /// 0x160 + 0xb0, 0x43, 0xb8, 0x83, 0xbf, 0x49, 0x02, 0x20, + 0x20, 0x31, 0x08, 0x76, 0xc0, 0x48, 0x84, 0x80, /// 0x170 + 0xbf, 0x49, 0xc0, 0x48, 0x08, 0x80, 0x80, 0x20, + 0x88, 0x81, 0xbf, 0x49, 0x94, 0x20, 0x08, 0x70, /// 0x180 + 0x15, 0x20, 0x08, 0x70, 0xbc, 0x48, 0x20, 0x30, + 0x00, 0x7c, 0x02, 0x21, 0x08, 0x43, 0xba, 0x49, /// 0x190 + 0x20, 0x31, 0x08, 0x74, 0xb8, 0x48, 0x04, 0x70, + 0x39, 0x20, 0xb5, 0x49, 0x00, 0x02, 0x08, 0x82, /// 0x1a0 + 0xb6, 0x48, 0x05, 0x80, 0xb5, 0x49, 0x81, 0x20, + 0x08, 0x80, 0xac, 0x49, 0xb3, 0x48, 0x20, 0x31, /// 0x1b0 + 0x20, 0x30, 0x01, 0x80, 0xb2, 0x48, 0xb1, 0x49, + 0x80, 0x78, 0x28, 0x43, 0x20, 0x31, 0x08, 0x71, /// 0x1c0 + 0xb0, 0x48, 0x85, 0x83, 0x09, 0x88, 0xc2, 0x13, + 0x11, 0x43, 0xac, 0x4a, 0x20, 0x32, 0x11, 0x80, /// 0x1d0 + 0x03, 0x27, 0x57, 0x71, 0xac, 0x49, 0x0d, 0x74, + 0x8e, 0x82, 0xa2, 0x49, 0x40, 0x31, 0x09, 0x8a, /// 0x1e0 + 0x02, 0x15, 0x11, 0x43, 0x9f, 0x4a, 0x40, 0x32, + 0x11, 0x82, 0xa6, 0x4a, 0x40, 0x21, 0x40, 0x3a, /// 0x1f0 + 0x11, 0x72, 0x11, 0x73, 0x11, 0x74, 0x20, 0x21, + 0x11, 0x76, 0xa2, 0x4a, 0x20, 0x3a, 0x11, 0x70, /// 0x200 + 0x80, 0x21, 0x11, 0x71, 0xa1, 0x4a, 0xa5, 0x21, + 0x11, 0x80, 0x11, 0x89, 0x82, 0x15, 0x11, 0x43, /// 0x210 + 0x9e, 0x4a, 0x11, 0x81, 0x14, 0x80, 0x04, 0x83, + 0x9a, 0x49, 0x20, 0x20, 0x20, 0x39, 0x08, 0x72, /// 0x220 + 0x9b, 0x48, 0x6a, 0x21, 0x01, 0x77, 0x9b, 0x48, + 0x81, 0xb2, 0x9b, 0x48, 0x00, 0xf0, 0x72, 0xfc, /// 0x230 + 0x30, 0x22, 0x9a, 0x49, 0x9a, 0x48, 0x00, 0xf0, + 0x5d, 0xfc, 0x91, 0x49, 0x86, 0x48, 0x10, 0x22, /// 0x240 + 0x50, 0x39, 0x48, 0x30, 0x00, 0xf0, 0x5d, 0xfc, + 0x8d, 0x49, 0x83, 0x48, 0x10, 0x22, 0x30, 0x31, /// 0x250 + 0x58, 0x30, 0x00, 0xf0, 0x56, 0xfc, 0x93, 0x48, + 0x1f, 0x21, 0x00, 0x90, 0x81, 0x72, 0x06, 0x46, /// 0x260 + 0xc7, 0x73, 0x20, 0x36, 0x4b, 0x20, 0x34, 0x77, + 0x00, 0x01, 0x00, 0xf0, 0xdd, 0xfb, 0x8e, 0x48, /// 0x270 + 0x05, 0x70, 0x8d, 0x49, 0x81, 0x20, 0x08, 0x70, + 0x3b, 0x20, 0x08, 0x71, 0x3f, 0x20, 0x08, 0x81, /// 0x280 + 0x21, 0x20, 0x08, 0x70, 0x00, 0xf0, 0x55, 0xfc, + 0x00, 0xf0, 0x23, 0xfc, 0x87, 0x49, 0x06, 0x20, /// 0x290 + 0x08, 0x60, 0x73, 0x49, 0x80, 0x39, 0x08, 0x60, + 0x85, 0x48, 0x05, 0x80, 0x07, 0x80, 0x41, 0x21, /// 0x2a0 + 0x01, 0x76, 0x84, 0x48, 0x00, 0xf0, 0x69, 0xf9, + 0x83, 0x48, 0x04, 0x71, 0x83, 0x48, 0x44, 0x73, /// 0x2b0 + 0x00, 0xf0, 0xb5, 0xff, 0x37, 0x46, 0x80, 0x3f, + 0x78, 0x73, 0x00, 0xf0, 0xaf, 0xfb, 0x7e, 0x48, /// 0x2c0 + 0x01, 0x7a, 0x89, 0x07, 0xfc, 0xd5, 0x7c, 0x49, + 0x00, 0x24, 0x20, 0x31, 0x0c, 0x70, 0x02, 0x21, /// 0x2d0 + 0x01, 0x72, 0x60, 0x49, 0x10, 0x22, 0x58, 0x31, + 0x88, 0x18, 0x00, 0xf0, 0x0b, 0xfc, 0x0f, 0x22, /// 0x2e0 + 0x01, 0x21, 0x00, 0x20, 0x00, 0xf0, 0x31, 0xf9, + 0x40, 0x03, 0x01, 0x0c, 0x6d, 0x48, 0x5a, 0x4d, /// 0x2f0 + 0x20, 0x38, 0x81, 0x85, 0x96, 0x20, 0x68, 0x86, + 0x51, 0x21, 0xa9, 0x86, 0x30, 0x82, 0x71, 0x82, /// 0x300 + 0x05, 0xf0, 0x78, 0xfa, 0x00, 0xf0, 0x95, 0xfb, + 0x5b, 0x49, 0x60, 0x31, 0x0a, 0x7d, 0x65, 0x48, /// 0x310 + 0xa0, 0x38, 0x02, 0x70, 0x0a, 0x7c, 0x42, 0x70, + 0x09, 0x7e, 0x81, 0x70, 0x02, 0x21, 0xc1, 0x70, /// 0x320 + 0xff, 0x21, 0x02, 0x31, 0x41, 0x60, 0x66, 0x49, + 0xc1, 0x61, 0x04, 0x72, 0x12, 0x21, 0xb9, 0x72, /// 0x330 + 0x01, 0x46, 0x01, 0x22, 0x60, 0x31, 0x8a, 0x70, + 0x28, 0x23, 0x80, 0x31, 0x4b, 0x76, 0xbc, 0x70, /// 0x340 + 0x74, 0x83, 0x4a, 0x74, 0x5f, 0x21, 0x69, 0x76, + 0x05, 0x21, 0xa9, 0x76, 0x6c, 0x21, 0xe9, 0x76, /// 0x350 + 0x5c, 0x49, 0xec, 0x61, 0x29, 0x62, 0x29, 0x46, + 0x5b, 0x4a, 0x40, 0x31, 0x0a, 0x80, 0x80, 0x78, /// 0x360 + 0x05, 0x28, 0x47, 0x48, 0x04, 0xd3, 0x81, 0x78, + 0x44, 0x48, 0x20, 0x30, 0x01, 0x71, 0x05, 0xe0, /// 0x370 + 0x80, 0x78, 0x01, 0x21, 0x08, 0x43, 0x41, 0x49, + 0x20, 0x31, 0x08, 0x71, 0x00, 0xf0, 0x6e, 0xff, /// 0x380 + 0x00, 0x99, 0x3f, 0x4d, 0x88, 0x73, 0xa8, 0x8b, + 0x50, 0x4e, 0xb0, 0x42, 0x01, 0xd0, 0x00, 0xf0, /// 0x390 + 0x75, 0xff, 0x68, 0x8b, 0xb0, 0x42, 0x01, 0xd0, + 0x00, 0xf0, 0x81, 0xff, 0x00, 0xf0, 0x91, 0xff, /// 0x3a0 + 0x2e, 0x49, 0x46, 0x48, 0xf5, 0x31, 0x40, 0x30, + 0x01, 0x85, 0x01, 0x46, 0x20, 0x31, 0x2b, 0x4a, /// 0x3b0 + 0x0c, 0x73, 0x9c, 0x3a, 0x42, 0x85, 0x2b, 0x20, + 0x48, 0x73, 0x45, 0x48, 0x01, 0x21, 0x01, 0x80, /// 0x3c0 + 0x33, 0x48, 0x01, 0x70, 0x81, 0x21, 0x01, 0x70, + 0x0d, 0x21, 0x01, 0x70, 0x30, 0x4a, 0x95, 0x21, /// 0x3d0 + 0x20, 0x32, 0x11, 0x80, 0xff, 0x21, 0x81, 0x82, + 0x03, 0x21, 0x09, 0x02, 0x01, 0x82, 0x04, 0x71, /// 0x3e0 + 0x32, 0x49, 0x61, 0x20, 0x08, 0x60, 0x1e, 0x49, + 0x80, 0x39, 0x08, 0x60, 0x2d, 0x48, 0x39, 0x49, /// 0x3f0 + 0xa0, 0x38, 0x41, 0x63, 0x2a, 0x49, 0x38, 0x48, + 0x48, 0x60, 0xff, 0xf7, 0x5c, 0xfe, 0x08, 0x20, /// 0x400 + 0x00, 0xf0, 0x12, 0xfb, 0x17, 0x48, 0x40, 0x30, + 0x01, 0x78, 0x49, 0x06, 0xfc, 0xd4, 0xff, 0xf7, /// 0x410 + 0x73, 0xfe, 0x10, 0x48, 0x10, 0xb5, 0x40, 0x38, + 0x41, 0x68, 0x22, 0x4c, 0x49, 0x1c, 0x20, 0x3c, /// 0x420 + 0x41, 0x60, 0x21, 0x78, 0x89, 0x07, 0x04, 0xd4, + 0x72, 0xb6, 0x80, 0x68, 0xff, 0xf7, 0x2f, 0xfe, /// 0x430 + 0x62, 0xb6, 0x20, 0x78, 0x00, 0x07, 0x03, 0xd5, + 0x07, 0x48, 0xc1, 0x69, 0x49, 0x1c, 0xc1, 0x61, /// 0x440 + 0x72, 0xb6, 0x04, 0x48, 0x40, 0x30, 0x00, 0x68, + 0xff, 0xf7, 0x21, 0xfe, 0x62, 0xb6, 0x00, 0x20, /// 0x450 + 0x10, 0xbd, 0x00, 0x00, 0x70, 0x02, 0x00, 0x20, + 0x30, 0x01, 0x00, 0x20, 0xff, 0x0f, 0x00, 0x00, /// 0x460 + 0x80, 0xe1, 0x00, 0xe0, 0x00, 0x30, 0x00, 0x40, + 0x05, 0x1d, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, /// 0x470 + 0x00, 0x34, 0x00, 0x40, 0xf9, 0x09, 0x00, 0x00, + 0x00, 0x58, 0x00, 0x40, 0x00, 0x38, 0x00, 0x40, /// 0x480 + 0x60, 0x67, 0x00, 0x00, 0x40, 0x6c, 0x00, 0x40, + 0x60, 0x40, 0x00, 0x40, 0x00, 0x74, 0x00, 0x40, /// 0x490 + 0x00, 0x64, 0x00, 0x40, 0x0c, 0x05, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x20, 0x40, 0x1a, 0x00, 0x00, /// 0x4a0 + 0x00, 0x01, 0x00, 0x20, 0xa0, 0x00, 0x00, 0x20, + 0x00, 0x3c, 0x00, 0x40, 0x80, 0xe2, 0x00, 0xe0, /// 0x4b0 + 0x00, 0x44, 0x00, 0x40, 0x38, 0x1a, 0x00, 0x00, + 0x00, 0x60, 0x00, 0x40, 0x70, 0x03, 0x00, 0x20, /// 0x4c0 + 0x0c, 0x00, 0x08, 0x02, 0x20, 0xbf, 0x02, 0x00, + 0xe4, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, /// 0x4d0 + 0x00, 0x48, 0x00, 0x40, 0x07, 0x40, 0x70, 0x00, + 0x53, 0x15, 0x00, 0x00, 0x70, 0xb5, 0xfe, 0x49, /// 0x4e0 + 0x8a, 0x88, 0xd2, 0x43, 0x92, 0x07, 0x07, 0xd0, + 0xfc, 0x4a, 0xfd, 0x4b, 0xd2, 0x8f, 0x9a, 0x42, /// 0x4f0 + 0x02, 0xd3, 0x40, 0x09, 0x00, 0x23, 0x03, 0xe0, + 0x82, 0x00, 0x80, 0x18, 0xc0, 0x09, 0x01, 0x23, /// 0x500 + 0x3c, 0x28, 0x01, 0xd2, 0x3c, 0x20, 0x02, 0xe0, + 0xff, 0x28, 0x00, 0xd9, 0xff, 0x20, 0x0a, 0x8a, /// 0x510 + 0xf4, 0x4c, 0x12, 0x0a, 0xc0, 0x1e, 0x82, 0x42, + 0x15, 0xd0, 0x00, 0x2b, 0x02, 0xd1, 0x25, 0x7b, /// 0x520 + 0x01, 0x2d, 0x03, 0xd0, 0x55, 0x1d, 0xa8, 0x42, + 0x00, 0xd9, 0x28, 0x46, 0x0a, 0x8a, 0x40, 0x25, /// 0x530 + 0x2a, 0x43, 0x0a, 0x82, 0x0a, 0x8a, 0x4f, 0x26, + 0x32, 0x40, 0x00, 0x02, 0x02, 0x43, 0x0a, 0x82, /// 0x540 + 0x08, 0x8a, 0xa8, 0x43, 0x08, 0x82, 0x23, 0x73, + 0x70, 0xbd, 0x70, 0xb5, 0x00, 0x23, 0x12, 0x07, /// 0x550 + 0x12, 0x0f, 0xe5, 0x4d, 0x0b, 0xe0, 0x44, 0x00, + 0x64, 0x19, 0xff, 0x34, 0x81, 0x34, 0x24, 0x8d, /// 0x560 + 0x26, 0x0b, 0x96, 0x42, 0x07, 0xd1, 0x24, 0x05, + 0x24, 0x0d, 0xe3, 0x18, 0x40, 0x18, 0x08, 0x28, /// 0x570 + 0xf1, 0xd3, 0x18, 0x46, 0x70, 0xbd, 0xdd, 0x48, + 0x70, 0xbd, 0x10, 0xb5, 0xdc, 0x4a, 0x00, 0x21, /// 0x580 + 0x11, 0x70, 0xd8, 0x4b, 0x01, 0x21, 0x40, 0x3b, + 0x59, 0x73, 0xda, 0x49, 0x03, 0x88, 0x8b, 0x80, /// 0x590 + 0x43, 0x88, 0x0b, 0x81, 0x83, 0x88, 0x8b, 0x81, + 0xc0, 0x88, 0x08, 0x82, 0xb4, 0x20, 0x10, 0x70, /// 0x5a0 + 0xd0, 0x48, 0xe8, 0x38, 0x10, 0x81, 0x07, 0x20, + 0x90, 0x80, 0xd1, 0x48, 0x02, 0x22, 0x20, 0x38, /// 0x5b0 + 0x02, 0x72, 0x03, 0x79, 0x72, 0xb6, 0x13, 0x43, + 0x03, 0x71, 0x62, 0xb6, 0x11, 0x20, 0x08, 0x80, /// 0x5c0 + 0x10, 0xbd, 0x01, 0x88, 0x42, 0x88, 0x51, 0x18, + 0x82, 0x88, 0xc0, 0x88, 0x51, 0x18, 0x40, 0x18, /// 0x5d0 + 0xc9, 0x49, 0x00, 0x22, 0x8a, 0x5e, 0x80, 0x10, + 0x80, 0x1a, 0x00, 0xd5, 0x00, 0x20, 0x70, 0x47, /// 0x5e0 + 0x01, 0x88, 0x42, 0x88, 0x51, 0x18, 0x82, 0x88, + 0xc0, 0x88, 0x51, 0x18, 0x40, 0x18, 0x80, 0x10, /// 0x5f0 + 0x00, 0xd5, 0x00, 0x20, 0x70, 0x47, 0xf8, 0xb5, + 0x09, 0x22, 0x04, 0x21, 0x00, 0x20, 0xff, 0xf7, /// 0x600 + 0xa4, 0xff, 0xb8, 0x4e, 0xb8, 0x4d, 0x20, 0x3e, + 0xb1, 0x7c, 0x09, 0x27, 0x49, 0x00, 0xc0, 0x03, /// 0x610 + 0x49, 0x19, 0xbf, 0x01, 0x00, 0x0c, 0xc9, 0x19, + 0x08, 0x83, 0x00, 0x22, 0x04, 0x21, 0x01, 0x20, /// 0x620 + 0xff, 0xf7, 0x93, 0xff, 0xb1, 0x7c, 0xc0, 0x03, + 0x49, 0x00, 0x49, 0x19, 0x00, 0x0c, 0xc9, 0x19, /// 0x630 + 0x08, 0x85, 0x02, 0x22, 0x08, 0x21, 0x03, 0x20, + 0xff, 0xf7, 0x87, 0xff, 0xb1, 0x7c, 0x03, 0x22, /// 0x640 + 0x49, 0x00, 0x49, 0x19, 0xc9, 0x19, 0x08, 0x84, + 0x04, 0x21, 0x02, 0x20, 0xff, 0xf7, 0x7d, 0xff, /// 0x650 + 0xb1, 0x7c, 0x05, 0x22, 0x49, 0x00, 0xc0, 0x03, + 0x49, 0x19, 0xd2, 0x01, 0x00, 0x0c, 0x89, 0x18, /// 0x660 + 0x9e, 0x4c, 0x88, 0x82, 0xa0, 0x69, 0x41, 0x00, + 0x60, 0x69, 0xc2, 0x0f, 0x11, 0x43, 0xa1, 0x61, /// 0x670 + 0x41, 0x00, 0xb0, 0x7c, 0x42, 0x00, 0x52, 0x19, + 0xd2, 0x19, 0x12, 0x7e, 0x40, 0x1c, 0xd2, 0x07, /// 0x680 + 0xd2, 0x0f, 0x11, 0x43, 0x80, 0x07, 0x80, 0x0f, + 0x61, 0x61, 0xb0, 0x74, 0x30, 0x46, 0x08, 0x38, /// 0x690 + 0xff, 0xf7, 0x97, 0xff, 0x25, 0x46, 0x98, 0x49, + 0x80, 0xb2, 0x40, 0x35, 0x28, 0x80, 0x40, 0x31, /// 0x6a0 + 0x49, 0x8b, 0x92, 0x4f, 0xb9, 0x42, 0x0a, 0xd0, + 0x94, 0x49, 0x0a, 0x68, 0x49, 0x68, 0x50, 0x43, /// 0x6b0 + 0x40, 0x18, 0x00, 0x13, 0x00, 0xb2, 0x00, 0x28, + 0x00, 0xda, 0x00, 0x20, 0x28, 0x80, 0xa0, 0x78, /// 0x6c0 + 0x05, 0x28, 0x06, 0xd3, 0x28, 0x88, 0x3b, 0x21, + 0x48, 0x43, 0x32, 0x21, 0x01, 0xf0, 0x7c, 0xf9, /// 0x6d0 + 0x28, 0x80, 0x84, 0x48, 0x18, 0x38, 0xff, 0xf7, + 0x83, 0xff, 0x80, 0xb2, 0x4b, 0x21, 0xc9, 0x00, /// 0x6e0 + 0x68, 0x87, 0x88, 0x42, 0x04, 0xd9, 0x7f, 0x48, + 0x14, 0x30, 0xff, 0xf7, 0x79, 0xff, 0x68, 0x87, /// 0x6f0 + 0x81, 0x48, 0x40, 0x30, 0x80, 0x8b, 0xb8, 0x42, + 0x30, 0x46, 0x27, 0xd0, 0xff, 0xf7, 0x70, 0xff, /// 0x700 + 0x80, 0xb2, 0x78, 0x49, 0xa0, 0x87, 0x0a, 0x6a, + 0x49, 0x6a, 0x50, 0x43, 0x40, 0x18, 0x00, 0x13, /// 0x710 + 0x00, 0xb2, 0x00, 0x28, 0x00, 0xda, 0x00, 0x20, + 0x73, 0x4d, 0xa0, 0x87, 0xa4, 0x8f, 0x68, 0x6a, /// 0x720 + 0x2f, 0x46, 0x00, 0x19, 0x20, 0x37, 0x68, 0x62, + 0x79, 0x7a, 0x49, 0x1c, 0xc9, 0xb2, 0x79, 0x72, /// 0x730 + 0x3e, 0x7a, 0xb1, 0x42, 0x06, 0xd1, 0x31, 0x46, + 0x01, 0xf0, 0x46, 0xf9, 0x68, 0x85, 0x00, 0x20, /// 0x740 + 0x78, 0x72, 0x68, 0x62, 0xe8, 0x6a, 0x00, 0x28, + 0x03, 0xd0, 0x05, 0xe0, 0xff, 0xf7, 0x39, 0xff, /// 0x750 + 0xe2, 0xe7, 0x20, 0x46, 0x70, 0x43, 0xe8, 0x62, + 0x07, 0x46, 0x31, 0x46, 0x01, 0xf0, 0x34, 0xf9, /// 0x760 + 0x38, 0x1a, 0x00, 0x19, 0x31, 0x46, 0xe8, 0x62, + 0x01, 0xf0, 0x2e, 0xf9, 0x28, 0x86, 0xff, 0x22, /// 0x770 + 0x01, 0x21, 0x25, 0x32, 0x49, 0x03, 0x62, 0x48, + 0x94, 0x42, 0x02, 0xd9, 0x82, 0x8b, 0xd2, 0x07, /// 0x780 + 0x04, 0xd0, 0x82, 0x8a, 0x8a, 0x43, 0x82, 0x82, + 0x00, 0x20, 0xf8, 0xbd, 0x82, 0x8a, 0x0a, 0x43, /// 0x790 + 0xf9, 0xe7, 0x30, 0xb5, 0x52, 0x4c, 0x5b, 0x49, + 0x5c, 0x34, 0x5b, 0x4a, 0x03, 0x46, 0xa0, 0x42, /// 0x7a0 + 0x31, 0xdb, 0x4f, 0x4c, 0x9c, 0x34, 0xa0, 0x42, + 0x0c, 0xda, 0x58, 0x48, 0x2d, 0x25, 0x18, 0x18, /// 0x7b0 + 0x04, 0x46, 0x68, 0x43, 0xc5, 0x17, 0xad, 0x0e, + 0x28, 0x18, 0x80, 0x11, 0x41, 0x18, 0x20, 0x46, /// 0x7c0 + 0x53, 0x4c, 0x16, 0xe0, 0x53, 0x4c, 0x3f, 0x21, + 0x89, 0x01, 0x53, 0x4a, 0xa0, 0x42, 0x1a, 0xdb, /// 0x7d0 + 0x50, 0x4c, 0x40, 0x34, 0xa3, 0x42, 0x13, 0xda, + 0x4e, 0x48, 0xa3, 0x25, 0x40, 0x42, 0x18, 0x18, /// 0x7e0 + 0x04, 0x46, 0x68, 0x43, 0xc5, 0x17, 0xad, 0x0e, + 0x28, 0x18, 0x80, 0x11, 0x41, 0x18, 0x20, 0x46, /// 0x7f0 + 0x4a, 0x4c, 0x60, 0x43, 0xc4, 0x17, 0xa4, 0x0e, + 0x20, 0x18, 0x80, 0x11, 0x82, 0x18, 0x02, 0xe0, /// 0x800 + 0x40, 0x49, 0x47, 0x4a, 0xd0, 0x31, 0x4b, 0x43, + 0x98, 0x1a, 0x00, 0x13, 0x00, 0xb2, 0x00, 0x28, /// 0x810 + 0x00, 0xda, 0x00, 0x20, 0x30, 0xbd, 0xff, 0x22, + 0x10, 0xb5, 0xe1, 0x32, 0x31, 0x49, 0x90, 0x42, /// 0x820 + 0x03, 0xd8, 0x06, 0x23, 0x8a, 0x88, 0xcb, 0x5e, + 0x07, 0xe0, 0xf7, 0x22, 0x92, 0x00, 0x90, 0x42, /// 0x830 + 0x00, 0xd9, 0x32, 0x49, 0x0a, 0x23, 0x0a, 0x89, + 0xcb, 0x5e, 0x50, 0x43, 0x80, 0x0a, 0xc0, 0x18, /// 0x840 + 0x40, 0x01, 0x19, 0x21, 0x01, 0xf0, 0xc0, 0xf8, + 0x00, 0xb2, 0x00, 0x28, 0x00, 0xda, 0x00, 0x20, /// 0x850 + 0x10, 0xbd, 0x10, 0xb5, 0xff, 0xf7, 0xdf, 0xff, + 0xff, 0xf7, 0x9b, 0xff, 0x10, 0xbd, 0xf8, 0xb5, /// 0x860 + 0x04, 0x22, 0x08, 0x21, 0x07, 0x20, 0xff, 0xf7, + 0x70, 0xfe, 0x20, 0x4e, 0x81, 0xb2, 0xb1, 0x42, /// 0x870 + 0x7e, 0xd0, 0x1a, 0x48, 0x40, 0x30, 0xc2, 0x88, + 0x13, 0x01, 0x9a, 0x1a, 0x51, 0x18, 0x09, 0x03, /// 0x880 + 0x09, 0x0c, 0xc1, 0x80, 0x09, 0x22, 0x04, 0x21, + 0x00, 0x20, 0xff, 0xf7, 0x5e, 0xfe, 0x80, 0xb2, /// 0x890 + 0xb0, 0x42, 0x6d, 0xd0, 0x11, 0x4c, 0x0e, 0x21, + 0xa0, 0x34, 0x61, 0x56, 0x40, 0x08, 0x40, 0x18, /// 0x8a0 + 0x27, 0x46, 0x80, 0xb2, 0x20, 0x37, 0x14, 0x4a, + 0x38, 0x84, 0x00, 0x21, 0x51, 0x5e, 0x88, 0x42, /// 0x8b0 + 0x01, 0xdb, 0x40, 0x1a, 0x00, 0xe0, 0x00, 0x20, + 0x80, 0xb2, 0x08, 0x4d, 0x38, 0x84, 0xa9, 0x78, /// 0x8c0 + 0x05, 0x29, 0x05, 0xd3, 0x3b, 0x21, 0x48, 0x43, + 0x32, 0x21, 0x01, 0xf0, 0x7d, 0xf8, 0x38, 0x84, /// 0x8d0 + 0x00, 0x22, 0x04, 0x21, 0x01, 0x20, 0x25, 0xe0, + 0x00, 0x34, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, /// 0x8e0 + 0xa6, 0x02, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x20, + 0x30, 0x01, 0x00, 0x20, 0xff, 0xff, 0x00, 0x00, /// 0x8f0 + 0x20, 0x60, 0x00, 0x40, 0x00, 0x44, 0x00, 0x40, + 0x20, 0x67, 0x00, 0x00, 0x00, 0x05, 0x00, 0x20, /// 0x900 + 0x00, 0x30, 0x00, 0x40, 0x93, 0x0f, 0x00, 0x00, + 0xcb, 0x4f, 0x00, 0x00, 0xfe, 0xfc, 0xff, 0xff, /// 0x910 + 0x57, 0xf4, 0xff, 0xff, 0x7a, 0x08, 0x00, 0x00, + 0x22, 0x44, 0x00, 0x00, 0xe3, 0x7a, 0x05, 0x00, /// 0x920 + 0x05, 0xbf, 0x05, 0x00, 0xff, 0xf7, 0x11, 0xfe, + 0x80, 0xb2, 0xb0, 0x42, 0x3f, 0xd0, 0x4b, 0x21, /// 0x930 + 0x40, 0x08, 0xc9, 0x00, 0x88, 0x42, 0x08, 0xd9, + 0x03, 0x22, 0x04, 0x21, 0x02, 0x20, 0xff, 0xf7, /// 0x940 + 0x04, 0xfe, 0x80, 0xb2, 0xb0, 0x42, 0x32, 0xd0, + 0x40, 0x08, 0xff, 0xf7, 0x82, 0xff, 0xfd, 0x49, /// 0x950 + 0xfc, 0x4b, 0xc9, 0x8d, 0x01, 0x22, 0xc0, 0x3b, + 0x56, 0x00, 0xf6, 0x18, 0xc0, 0x36, 0xf6, 0x8d, /// 0x960 + 0x8e, 0x42, 0x00, 0xd9, 0x31, 0x46, 0x52, 0x1c, + 0xd2, 0xb2, 0x04, 0x2a, 0xf4, 0xd3, 0x00, 0xe0, /// 0x970 + 0x1d, 0xe0, 0xf4, 0x4a, 0x20, 0x32, 0x96, 0x7d, + 0x76, 0x00, 0xf3, 0x18, 0xc0, 0x33, 0xd8, 0x85, /// 0x980 + 0x93, 0x7d, 0x5b, 0x1c, 0x9b, 0x07, 0x9b, 0x0f, + 0x93, 0x75, 0x7d, 0x23, 0xdb, 0x00, 0xee, 0x4a, /// 0x990 + 0x98, 0x42, 0x0d, 0xd9, 0x93, 0x88, 0xdb, 0x43, + 0x9b, 0x07, 0x09, 0xd0, 0x03, 0x20, 0x90, 0x80, /// 0x9a0 + 0x10, 0x88, 0xf8, 0x21, 0x88, 0x43, 0x38, 0x21, + 0xc0, 0x30, 0x08, 0x43, 0x10, 0x80, 0xf8, 0xbd, /// 0x9b0 + 0xe6, 0x4b, 0x1b, 0x78, 0xdb, 0x06, 0xfa, 0xd5, + 0x93, 0x88, 0x00, 0x2b, 0xf7, 0xd0, 0x03, 0x46, /// 0x9c0 + 0xc8, 0x33, 0x99, 0x42, 0x01, 0xd9, 0x64, 0x28, + 0x05, 0xd3, 0x6b, 0x7a, 0x0a, 0x25, 0x6b, 0x43, /// 0x9d0 + 0x18, 0x18, 0x88, 0x42, 0xeb, 0xd2, 0x00, 0x20, + 0x90, 0x80, 0x08, 0x21, 0xdc, 0x48, 0xe1, 0x73, /// 0x9e0 + 0x41, 0x71, 0x01, 0x88, 0x82, 0x14, 0x11, 0x43, + 0x01, 0x80, 0xd6, 0x48, 0x32, 0x21, 0xc0, 0x30, /// 0x9f0 + 0x01, 0x67, 0x01, 0x46, 0x80, 0x39, 0x49, 0x68, + 0x42, 0x6e, 0x8a, 0x1a, 0x1e, 0x2a, 0xd6, 0xd3, /// 0xa00 + 0x1e, 0x39, 0x41, 0x66, 0xf8, 0xbd, 0xd3, 0x48, + 0x01, 0x78, 0x42, 0x22, 0x11, 0x43, 0x01, 0x70, /// 0xa10 + 0xd1, 0x49, 0xc0, 0x14, 0x08, 0x60, 0xd1, 0x49, + 0x08, 0x60, 0x70, 0x47, 0xd0, 0x48, 0x81, 0x21, /// 0xa20 + 0x01, 0x80, 0x00, 0x21, 0x01, 0x80, 0x70, 0x47, + 0x00, 0xe0, 0x00, 0xbf, 0x40, 0x1e, 0xfc, 0xd2, /// 0xa30 + 0x70, 0x47, 0x10, 0xb5, 0xc4, 0x4c, 0x00, 0x23, + 0xa3, 0x80, 0xc3, 0x48, 0x40, 0x30, 0x03, 0x74, /// 0xa40 + 0xc8, 0x48, 0x20, 0x80, 0xc9, 0x4a, 0xc8, 0x48, + 0x10, 0x82, 0x90, 0x8a, 0x51, 0x14, 0x08, 0x43, /// 0xa50 + 0x90, 0x82, 0xd8, 0x20, 0x90, 0x83, 0x64, 0x20, + 0xff, 0xf7, 0xe6, 0xff, 0xd0, 0x20, 0x90, 0x83, /// 0xa60 + 0x39, 0x20, 0x00, 0x02, 0x20, 0x82, 0xc2, 0x48, + 0x10, 0x83, 0xb9, 0x49, 0x81, 0x20, 0x20, 0x39, /// 0xa70 + 0x08, 0x80, 0xb6, 0x49, 0x1f, 0x20, 0x20, 0x31, + 0x88, 0x72, 0xb5, 0x48, 0xbd, 0x49, 0x01, 0x80, /// 0xa80 + 0xbd, 0x49, 0x01, 0x22, 0x89, 0x78, 0x11, 0x43, + 0x01, 0x71, 0xb2, 0x49, 0x09, 0x20, 0x08, 0x70, /// 0xa90 + 0xae, 0x48, 0x40, 0x30, 0x01, 0x7f, 0x91, 0x43, + 0xb8, 0x4a, 0x01, 0x77, 0x10, 0x78, 0x40, 0x08, /// 0xaa0 + 0x40, 0x00, 0x10, 0x70, 0xff, 0xf7, 0xba, 0xff, + 0xa6, 0x48, 0xb5, 0x49, 0x40, 0x30, 0x81, 0x60, /// 0xab0 + 0x11, 0x78, 0xfb, 0x24, 0x21, 0x40, 0x11, 0x70, + 0x41, 0x68, 0x80, 0x30, 0xc1, 0x66, 0xa3, 0x48, /// 0xac0 + 0x40, 0x22, 0x40, 0x38, 0x43, 0x73, 0x40, 0x38, + 0xc1, 0x6a, 0x91, 0x43, 0xc1, 0x62, 0x00, 0x20, /// 0xad0 + 0x10, 0xbd, 0xac, 0x48, 0x00, 0x21, 0x01, 0x75, + 0x41, 0x75, 0xa1, 0x48, 0x01, 0x21, 0x01, 0x80, /// 0xae0 + 0x01, 0x15, 0x81, 0x80, 0x0f, 0x21, 0x01, 0x80, + 0x02, 0x22, 0x02, 0x81, 0x01, 0x83, 0x04, 0x21, /// 0xaf0 + 0x81, 0x82, 0x70, 0x47, 0x82, 0x18, 0x01, 0xe0, + 0x08, 0xc9, 0x08, 0xc0, 0x90, 0x42, 0xfb, 0xd3, /// 0xb00 + 0x70, 0x47, 0x82, 0x18, 0x03, 0xe0, 0x0b, 0x78, + 0x03, 0x70, 0x40, 0x1c, 0x49, 0x1c, 0x90, 0x42, /// 0xb10 + 0xf9, 0xd3, 0x70, 0x47, 0x41, 0x18, 0x00, 0x22, + 0x00, 0xe0, 0x04, 0xc0, 0x88, 0x42, 0xfc, 0xd3, /// 0xb20 + 0x70, 0x47, 0x41, 0x18, 0x00, 0x22, 0x01, 0xe0, + 0x02, 0x70, 0x40, 0x1c, 0x88, 0x42, 0xfb, 0xd3, /// 0xb30 + 0x70, 0x47, 0x95, 0x48, 0x01, 0x21, 0x01, 0x70, + 0x93, 0x4a, 0x05, 0x21, 0x40, 0x32, 0x11, 0x80, /// 0xb40 + 0x00, 0x22, 0x02, 0x74, 0x90, 0x49, 0x20, 0x31, + 0x0a, 0x74, 0x90, 0x4a, 0x8a, 0x81, 0x13, 0x22, /// 0xb50 + 0x0a, 0x70, 0x07, 0x21, 0x01, 0x72, 0x70, 0x47, + 0x7c, 0x49, 0x80, 0x39, 0x0a, 0x6b, 0x02, 0x43, /// 0xb60 + 0x48, 0x6b, 0x10, 0x40, 0x08, 0x63, 0x05, 0xd0, + 0x84, 0x48, 0x20, 0x38, 0x01, 0x7f, 0xfb, 0x22, /// 0xb70 + 0x11, 0x40, 0x01, 0x77, 0x70, 0x47, 0x75, 0x48, + 0x80, 0x38, 0x82, 0x6a, 0xc1, 0x6a, 0x91, 0x43, /// 0xb80 + 0xc1, 0x62, 0x01, 0x6b, 0x91, 0x43, 0x00, 0x22, + 0x82, 0x62, 0x01, 0x63, 0x00, 0x29, 0x05, 0xd1, /// 0xb90 + 0x7a, 0x48, 0x20, 0x38, 0x01, 0x7f, 0x04, 0x22, + 0x11, 0x43, 0x01, 0x77, 0x70, 0x47, 0x6b, 0x49, /// 0xba0 + 0x10, 0xb5, 0x80, 0x39, 0xc9, 0x8f, 0x7a, 0x4a, + 0x91, 0x42, 0x01, 0xd9, 0x07, 0x21, 0x00, 0xe0, /// 0xbb0 + 0x00, 0x21, 0x6e, 0x4a, 0x13, 0x15, 0x94, 0x8b, + 0x02, 0x28, 0x01, 0xd8, 0x1c, 0x43, 0x00, 0xe0, /// 0xbc0 + 0x9c, 0x43, 0x94, 0x83, 0x61, 0x4c, 0x20, 0x34, + 0x01, 0x28, 0x01, 0xd9, 0x00, 0x20, 0x06, 0xe0, /// 0xbd0 + 0x01, 0x28, 0x10, 0xd0, 0x1c, 0x20, 0x40, 0x1a, + 0x07, 0x21, 0x00, 0xf0, 0x0b, 0xff, 0xe0, 0x73, /// 0xbe0 + 0xc1, 0xb2, 0x5b, 0x48, 0x41, 0x71, 0x42, 0x79, + 0x81, 0x14, 0x00, 0x2a, 0x02, 0x88, 0x04, 0xd0, /// 0xbf0 + 0x0a, 0x43, 0x02, 0x80, 0x10, 0xbd, 0x0e, 0x20, + 0xed, 0xe7, 0x8a, 0x43, 0xf9, 0xe7, 0x10, 0xb5, /// 0xc00 + 0x00, 0x20, 0xff, 0xf7, 0xcc, 0xff, 0x59, 0x4a, + 0x90, 0x8a, 0x51, 0x14, 0x08, 0x43, 0x90, 0x82, /// 0xc10 + 0x10, 0x8a, 0x01, 0x21, 0x08, 0x43, 0x10, 0x82, + 0xd8, 0x20, 0x90, 0x83, 0x64, 0x20, 0xff, 0xf7, /// 0xc20 + 0x03, 0xff, 0xd0, 0x20, 0x90, 0x83, 0x39, 0x20, + 0x47, 0x49, 0x00, 0x02, 0x08, 0x82, 0x00, 0x20, /// 0xc30 + 0x88, 0x80, 0x0a, 0x88, 0xc0, 0x23, 0x9a, 0x43, + 0x0a, 0x80, 0x52, 0x49, 0xfb, 0x23, 0x40, 0x39, /// 0xc40 + 0x4a, 0x7e, 0xef, 0x24, 0x1a, 0x40, 0x4a, 0x76, + 0x40, 0x4a, 0x80, 0x3a, 0x11, 0x46, 0x90, 0x87, /// 0xc50 + 0x40, 0x31, 0x88, 0x87, 0x88, 0x80, 0x3d, 0x48, + 0x01, 0x78, 0x21, 0x40, 0x01, 0x70, 0x39, 0x48, /// 0xc60 + 0xc0, 0x38, 0x00, 0x7d, 0x01, 0x28, 0x0a, 0xd0, + 0x44, 0x48, 0x01, 0x78, 0x19, 0x40, 0x01, 0x70, /// 0xc70 + 0xd0, 0x6a, 0x80, 0x21, 0x08, 0x43, 0xd0, 0x62, + 0x08, 0x46, 0xff, 0xf7, 0x6d, 0xff, 0x10, 0xbd, /// 0xc80 + 0xf8, 0xb5, 0x31, 0x48, 0x00, 0x24, 0x80, 0x88, + 0x3e, 0x49, 0x02, 0x07, 0x40, 0x39, 0xc8, 0x7e, /// 0xc90 + 0x00, 0x2a, 0x06, 0xda, 0xc2, 0x07, 0x02, 0xd1, + 0x01, 0x22, 0x10, 0x43, 0xc8, 0x76, 0x02, 0x24, /// 0xca0 + 0x0b, 0xe0, 0xc2, 0x07, 0x09, 0xd0, 0x2a, 0x4a, + 0x20, 0x3a, 0x13, 0x8b, 0x05, 0x25, 0x2d, 0x02, /// 0xcb0 + 0x2b, 0x43, 0x13, 0x83, 0x40, 0x08, 0x40, 0x00, + 0xc8, 0x76, 0x24, 0x4d, 0x4b, 0x21, 0x40, 0x3d, /// 0xcc0 + 0xe8, 0x88, 0x48, 0x43, 0x7d, 0x21, 0xc9, 0x00, + 0x00, 0xf0, 0x7e, 0xfe, 0xae, 0x28, 0x01, 0xd4, /// 0xcd0 + 0xae, 0x38, 0x00, 0xe0, 0x00, 0x20, 0x1d, 0x49, + 0x1c, 0x4e, 0x60, 0x31, 0x00, 0x91, 0x88, 0x74, /// 0xce0 + 0x18, 0x49, 0x80, 0x3e, 0xc0, 0x39, 0x37, 0x46, + 0x49, 0x7e, 0x20, 0x37, 0x80, 0x36, 0x81, 0x42, /// 0xcf0 + 0x17, 0xd2, 0x14, 0x4a, 0xc0, 0x3a, 0xd2, 0x69, + 0x00, 0x2a, 0x01, 0xd1, 0x04, 0x22, 0x14, 0x43, /// 0xd00 + 0x32, 0x78, 0x08, 0x23, 0x1a, 0x43, 0x32, 0x70, + 0x0e, 0x4a, 0xc0, 0x3a, 0xd3, 0x7e, 0x83, 0x42, /// 0xd10 + 0x07, 0xd2, 0x00, 0x23, 0xd3, 0x61, 0x03, 0x22, + 0xfa, 0x76, 0xea, 0x89, 0x08, 0x23, 0x1a, 0x43, /// 0xd20 + 0xea, 0x81, 0x08, 0x4a, 0xc0, 0x3a, 0x92, 0x7e, + 0x89, 0x1a, 0x81, 0x42, 0x30, 0x78, 0x31, 0xd9, /// 0xd30 + 0x01, 0x07, 0x02, 0xd5, 0xf7, 0x21, 0x08, 0x40, + 0x30, 0x70, 0x02, 0x49, 0x00, 0x20, 0xc0, 0x39, /// 0xd40 + 0xc8, 0x61, 0x36, 0xe0, 0xf0, 0x01, 0x00, 0x20, + 0x00, 0x34, 0x00, 0x40, 0x80, 0x00, 0x00, 0x20, /// 0xd50 + 0x20, 0x38, 0x00, 0x40, 0x00, 0x3c, 0x00, 0x40, + 0x80, 0xe2, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe0, /// 0xd60 + 0x00, 0x4c, 0x00, 0x40, 0x01, 0x0a, 0x00, 0x00, + 0xff, 0x07, 0x00, 0x00, 0x00, 0x30, 0x00, 0x40, /// 0xd70 + 0x05, 0x3f, 0x00, 0x00, 0x1f, 0xb0, 0x00, 0x00, + 0x60, 0x67, 0x00, 0x00, 0x40, 0x6c, 0x00, 0x40, /// 0xd80 + 0x05, 0x53, 0x00, 0x00, 0x30, 0x03, 0x00, 0x20, + 0x00, 0x54, 0x00, 0x40, 0xe7, 0x03, 0x00, 0x00, /// 0xd90 + 0xf9, 0x04, 0x00, 0x00, 0x00, 0x07, 0x0c, 0xd5, + 0xfe, 0x48, 0x02, 0x6a, 0xc1, 0x69, 0x91, 0x42, /// 0xda0 + 0x07, 0xd3, 0x00, 0x21, 0xc1, 0x61, 0x03, 0x20, + 0xf8, 0x76, 0xe8, 0x89, 0x08, 0x21, 0x08, 0x43, /// 0xdb0 + 0xe8, 0x81, 0xf9, 0x48, 0x80, 0x89, 0x80, 0x06, + 0x0d, 0xd5, 0xf6, 0x48, 0xc0, 0x69, 0x00, 0x28, /// 0xdc0 + 0x07, 0xd1, 0x04, 0x20, 0x04, 0x43, 0x03, 0x20, + 0xf8, 0x76, 0xe8, 0x89, 0x08, 0x21, 0x08, 0x43, /// 0xdd0 + 0xe8, 0x81, 0xff, 0xf7, 0x14, 0xff, 0xf1, 0x48, + 0x80, 0x8b, 0xc1, 0x04, 0x00, 0x29, 0xf0, 0x48, /// 0xde0 + 0xf0, 0x49, 0x41, 0x56, 0x06, 0xda, 0x19, 0x29, + 0x02, 0xdd, 0x01, 0x20, 0x04, 0x43, 0x0b, 0xe0, /// 0xdf0 + 0x49, 0x1c, 0x03, 0xe0, 0x19, 0x22, 0xd1, 0x42, + 0x06, 0xdb, 0x49, 0x1e, 0x01, 0x74, 0xea, 0x48, /// 0xe00 + 0x80, 0x8d, 0xc0, 0x07, 0xc0, 0x0f, 0x04, 0x43, + 0xe2, 0x48, 0xc0, 0x30, 0xc1, 0x8d, 0x02, 0x8e, /// 0xe10 + 0x83, 0x8e, 0x89, 0x18, 0x42, 0x8e, 0xd2, 0x18, + 0x89, 0x18, 0xde, 0x4a, 0x89, 0x08, 0xd1, 0x60, /// 0xe20 + 0x00, 0x9a, 0x52, 0x7c, 0x00, 0x2a, 0x33, 0xd0, + 0x02, 0x46, 0x80, 0x3a, 0x13, 0x88, 0xa0, 0x32, /// 0xe30 + 0x94, 0x46, 0x8b, 0x42, 0x29, 0xd2, 0x60, 0x32, + 0xc8, 0x33, 0x8b, 0x42, 0x14, 0xd8, 0x81, 0x7f, /// 0xe40 + 0x49, 0x1c, 0xc9, 0xb2, 0x81, 0x77, 0x05, 0x29, + 0x22, 0xd3, 0x91, 0x7b, 0x0a, 0x29, 0x1f, 0xd0, /// 0xe50 + 0x00, 0x21, 0x81, 0x77, 0x01, 0x20, 0x00, 0x05, + 0x04, 0x43, 0x05, 0x20, 0xf8, 0x76, 0xe8, 0x89, /// 0xe60 + 0x08, 0x21, 0x08, 0x43, 0xe8, 0x81, 0x13, 0xe0, + 0x00, 0x21, 0x81, 0x77, 0x60, 0x46, 0x40, 0x7e, /// 0xe70 + 0x63, 0x46, 0x40, 0x1c, 0xc0, 0xb2, 0x58, 0x76, + 0x05, 0x28, 0x09, 0xd3, 0x90, 0x7b, 0x0a, 0x28, /// 0xe80 + 0x06, 0xd0, 0x01, 0x20, 0x59, 0x76, 0x04, 0x43, + 0x02, 0xe0, 0x00, 0x21, 0x51, 0x76, 0x81, 0x77, /// 0xe90 + 0xc6, 0x49, 0x70, 0x6f, 0x88, 0x42, 0x1a, 0xdd, + 0xa9, 0x88, 0x7d, 0x20, 0xc0, 0x00, 0x81, 0x42, /// 0xea0 + 0x15, 0xd9, 0x00, 0x98, 0x00, 0x99, 0x00, 0x7e, + 0x40, 0x1c, 0xc0, 0xb2, 0x08, 0x76, 0x28, 0x28, /// 0xeb0 + 0x10, 0xd3, 0x01, 0x21, 0x49, 0x05, 0x0c, 0x43, + 0x05, 0x21, 0xf9, 0x76, 0xe9, 0x89, 0x08, 0x22, /// 0xec0 + 0x11, 0x43, 0xe9, 0x81, 0x64, 0x28, 0x05, 0xd3, + 0xff, 0xf7, 0x99, 0xfe, 0x02, 0xe0, 0x00, 0x99, /// 0xed0 + 0x00, 0x20, 0x08, 0x76, 0xb4, 0x4a, 0xb6, 0x4b, + 0xd0, 0x6a, 0x01, 0x46, 0x18, 0x40, 0x60, 0x40, /// 0xee0 + 0x05, 0xd0, 0xdb, 0x43, 0x19, 0x40, 0x21, 0x43, + 0xd1, 0x62, 0xff, 0xf7, 0x35, 0xfe, 0xf8, 0xbd, /// 0xef0 + 0x02, 0x46, 0x00, 0x20, 0x02, 0xe0, 0x13, 0x78, + 0x58, 0x40, 0x52, 0x1c, 0x49, 0x1e, 0xfa, 0xd2, /// 0xf00 + 0x70, 0x47, 0x08, 0x22, 0x01, 0x21, 0x01, 0xe0, + 0x09, 0x18, 0x40, 0x08, 0x52, 0x1e, 0xfb, 0xd2, /// 0xf10 + 0xc8, 0x07, 0xc0, 0x0f, 0x70, 0x47, 0xf8, 0xb5, + 0x9e, 0x4c, 0x00, 0x27, 0x20, 0x46, 0xff, 0x30, /// 0xf20 + 0xa1, 0x30, 0x84, 0x46, 0x18, 0x30, 0x05, 0x46, + 0x28, 0x35, 0xff, 0x34, 0x3e, 0x46, 0xc1, 0x34, /// 0xf30 + 0x00, 0x90, 0x60, 0x7d, 0x00, 0x28, 0x0f, 0xd1, + 0x60, 0x46, 0xa1, 0x7d, 0x00, 0x7e, 0x81, 0x42, /// 0xf40 + 0x06, 0xd2, 0x01, 0x20, 0xb8, 0x40, 0x49, 0x1c, + 0x06, 0x43, 0xa1, 0x75, 0xbf, 0x1c, 0x3a, 0xe0, /// 0xf50 + 0x00, 0x20, 0xa0, 0x75, 0x01, 0x20, 0x60, 0x75, + 0xc1, 0xb2, 0x20, 0x7d, 0x81, 0x42, 0x1e, 0xd2, /// 0xf60 + 0xa0, 0x7d, 0x00, 0x28, 0x1f, 0xd0, 0x09, 0x28, + 0x06, 0xd2, 0x00, 0x9a, 0x40, 0x1e, 0x89, 0x5c, /// 0xf70 + 0xc1, 0x40, 0xc8, 0x07, 0xc0, 0x0f, 0x16, 0xe0, + 0x09, 0x28, 0x05, 0xd0, 0xff, 0x22, 0x01, 0x20, /// 0xf80 + 0xa2, 0x75, 0x49, 0x1c, 0x61, 0x75, 0x0e, 0xe0, + 0x00, 0x98, 0x08, 0x5c, 0xff, 0xf7, 0xb9, 0xff, /// 0xf90 + 0x61, 0x46, 0x09, 0x7e, 0x00, 0x29, 0x06, 0xd1, + 0x01, 0x21, 0x48, 0x40, 0x03, 0xe0, 0x68, 0x78, /// 0xfa0 + 0x01, 0x21, 0x48, 0x40, 0xa9, 0x70, 0x69, 0x78, + 0x01, 0x22, 0x51, 0x40, 0x48, 0x40, 0x68, 0x70, /// 0xfb0 + 0x40, 0x00, 0x08, 0x43, 0xb8, 0x40, 0x06, 0x43, + 0xa0, 0x7d, 0xbf, 0x1c, 0x40, 0x1c, 0xa0, 0x75, /// 0xfc0 + 0xa8, 0x78, 0x01, 0x28, 0x01, 0xd0, 0x10, 0x2f, + 0xb3, 0xd3, 0x7f, 0x1e, 0x2f, 0x70, 0xe6, 0x83, /// 0xfd0 + 0xf8, 0xbd, 0xf0, 0xb5, 0x04, 0x46, 0x41, 0x1c, + 0x71, 0x48, 0xa7, 0x38, 0xff, 0xf7, 0x88, 0xff, /// 0xfe0 + 0x6c, 0x49, 0x6f, 0x4d, 0x09, 0x19, 0xff, 0x31, + 0xa0, 0x3d, 0xa1, 0x31, 0x88, 0x76, 0xe4, 0x1c, /// 0xff0 + 0x2c, 0x75, 0x28, 0x7e, 0xe8, 0x75, 0x00, 0x20, + 0x68, 0x75, 0x2e, 0x46, 0xa8, 0x75, 0x20, 0x36, /// 0x1000 + 0x70, 0x70, 0x02, 0x27, 0xb7, 0x70, 0xff, 0xf7, + 0x86, 0xff, 0xa9, 0x7e, 0x69, 0x48, 0x00, 0x29, /// 0x1010 + 0x08, 0xd1, 0x65, 0x49, 0xa0, 0x31, 0xc9, 0x7b, + 0xc9, 0x1d, 0x41, 0x71, 0x01, 0x88, 0x82, 0x14, /// 0x1020 + 0x11, 0x43, 0x01, 0x80, 0x64, 0x49, 0x0a, 0x8a, + 0x0c, 0x23, 0x1a, 0x43, 0x0a, 0x82, 0x5e, 0x4a, /// 0x1030 + 0x62, 0x4b, 0xd2, 0x8f, 0x00, 0x21, 0x9a, 0x42, + 0x01, 0xd2, 0xc0, 0x22, 0x00, 0xe0, 0x30, 0x22, /// 0x1040 + 0xd3, 0x06, 0x01, 0xd5, 0xff, 0x21, 0x01, 0x31, + 0x93, 0x06, 0x02, 0xd5, 0x01, 0x23, 0x5b, 0x02, /// 0x1050 + 0x19, 0x43, 0x03, 0x88, 0x03, 0x24, 0x24, 0x02, + 0xa3, 0x43, 0x0b, 0x43, 0x01, 0x21, 0xc9, 0x03, /// 0x1060 + 0x0b, 0x43, 0x03, 0x80, 0x53, 0x4c, 0x56, 0x48, + 0x20, 0x3c, 0xa0, 0x80, 0x27, 0x81, 0x00, 0x20, /// 0x1070 + 0xc0, 0x43, 0xa0, 0x81, 0x00, 0x20, 0x51, 0x06, + 0x00, 0xd5, 0x08, 0x20, 0x11, 0x06, 0x01, 0xd5, /// 0x1080 + 0x40, 0x21, 0x08, 0x43, 0x25, 0x21, 0x08, 0x43, + 0x20, 0x80, 0x47, 0x48, 0x40, 0x30, 0x80, 0x78, /// 0x1090 + 0x01, 0x28, 0xe8, 0x8b, 0x00, 0xd1, 0xc0, 0x43, + 0x20, 0x82, 0x30, 0x78, 0x20, 0x75, 0xff, 0xf7, /// 0x10a0 + 0x3a, 0xff, 0xff, 0x20, 0x00, 0x02, 0xa0, 0x81, + 0xf0, 0xbd, 0x3c, 0x4a, 0x10, 0x8b, 0x45, 0x4b, /// 0x10b0 + 0x80, 0x04, 0x81, 0x0e, 0x3c, 0x48, 0x40, 0x30, + 0x80, 0x7a, 0x40, 0x1c, 0x58, 0x43, 0x00, 0x0a, /// 0x10c0 + 0x40, 0x1e, 0x3f, 0x28, 0x00, 0xdd, 0x3f, 0x20, + 0x81, 0x42, 0x00, 0xd2, 0x48, 0x1c, 0x11, 0x8b, /// 0x10d0 + 0x3f, 0x23, 0x1b, 0x02, 0x99, 0x43, 0x00, 0x02, + 0x01, 0x43, 0x11, 0x83, 0x36, 0x49, 0x08, 0x88, /// 0x10e0 + 0x07, 0x22, 0x12, 0x02, 0x90, 0x43, 0x30, 0x4a, + 0x60, 0x32, 0x92, 0x78, 0x52, 0x07, 0x52, 0x0d, /// 0x10f0 + 0x10, 0x43, 0x08, 0x80, 0x2c, 0x48, 0xa0, 0x30, + 0x81, 0x7a, 0x1f, 0x29, 0x01, 0xd9, 0x1f, 0x21, /// 0x1100 + 0x81, 0x72, 0x2c, 0x48, 0xc9, 0xb2, 0x02, 0x88, + 0x52, 0x09, 0x52, 0x01, 0xc3, 0x13, 0x1a, 0x43, /// 0x1110 + 0x11, 0x43, 0x01, 0x80, 0x70, 0x47, 0xf8, 0xb5, + 0x21, 0x49, 0x05, 0x46, 0x40, 0x09, 0xa0, 0x39, /// 0x1120 + 0x00, 0x28, 0x0a, 0xd0, 0x20, 0x28, 0x01, 0xdb, + 0x1f, 0x20, 0x06, 0xe0, 0x8a, 0x7e, 0x82, 0x42, /// 0x1130 + 0x01, 0xda, 0x40, 0x1e, 0x01, 0xe0, 0x82, 0x42, + 0x00, 0xdd, 0x88, 0x76, 0x1a, 0x48, 0x15, 0x21, /// 0x1140 + 0xc0, 0x8f, 0x06, 0x46, 0x48, 0x43, 0x19, 0x21, + 0x00, 0xf0, 0x3e, 0xfc, 0x04, 0x46, 0x1b, 0x48, /// 0x1150 + 0xff, 0x34, 0x19, 0x34, 0x56, 0x30, 0x84, 0x42, + 0x00, 0xd9, 0x64, 0x1c, 0x7d, 0x20, 0x00, 0x01, /// 0x1160 + 0x84, 0x42, 0x00, 0xd9, 0x04, 0x46, 0x67, 0x20, + 0x00, 0x02, 0x0e, 0x21, 0x41, 0x56, 0x70, 0x18, /// 0x1170 + 0x15, 0x49, 0x88, 0x42, 0x00, 0xd9, 0x08, 0x46, + 0x01, 0x21, 0x08, 0x43, 0x07, 0x49, 0x08, 0x82, /// 0x1180 + 0x65, 0x43, 0x28, 0x46, 0x11, 0x49, 0x00, 0xf0, + 0x1f, 0xfc, 0x07, 0x4d, 0x80, 0x35, 0xa9, 0x7c, /// 0x1190 + 0x08, 0x1a, 0x1d, 0xe0, 0x30, 0x01, 0x00, 0x20, + 0x20, 0x48, 0x00, 0x40, 0x00, 0x30, 0x00, 0x40, /// 0x11a0 + 0x90, 0x03, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0xc4, 0x09, 0x00, 0x00, /// 0x11b0 + 0x07, 0x00, 0x30, 0x00, 0x20, 0x38, 0x00, 0x40, + 0x00, 0x34, 0x00, 0x40, 0xbe, 0x04, 0x00, 0x00, /// 0x11c0 + 0xdb, 0x05, 0x00, 0x00, 0x55, 0x03, 0x00, 0x00, + 0xff, 0x07, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, /// 0x11d0 + 0x53, 0x49, 0x77, 0x39, 0x8e, 0x42, 0x06, 0xd8, + 0x00, 0x28, 0x04, 0xdb, 0xe9, 0x7c, 0x40, 0x43, /// 0x11e0 + 0x41, 0x43, 0x48, 0x11, 0x00, 0xe0, 0x00, 0x20, + 0xe9, 0x8a, 0x0f, 0x18, 0xa8, 0x8a, 0xb8, 0x42, /// 0x11f0 + 0x00, 0xd2, 0x07, 0x46, 0x4a, 0x48, 0x3b, 0x30, + 0x86, 0x42, 0x00, 0xd9, 0x0d, 0x27, 0x49, 0x49, /// 0x1200 + 0x60, 0x03, 0x40, 0x18, 0x49, 0x00, 0x00, 0xf0, + 0xdf, 0xfb, 0x1e, 0x21, 0x69, 0x56, 0xc0, 0x19, /// 0x1210 + 0x08, 0x18, 0x45, 0x49, 0x88, 0x42, 0x00, 0xd9, + 0x08, 0x46, 0x28, 0x82, 0xf8, 0xbd, 0x10, 0xb5, /// 0x1220 + 0x42, 0x48, 0x43, 0x49, 0x43, 0x4a, 0x13, 0x78, + 0x5b, 0x06, 0x02, 0xd4, 0x03, 0x68, 0x05, 0x2b, /// 0x1230 + 0x01, 0xd3, 0x00, 0x20, 0x10, 0xbd, 0x0b, 0x78, + 0x05, 0x2b, 0xf4, 0xd9, 0x3c, 0x48, 0x54, 0x38, /// 0x1240 + 0x01, 0x8f, 0x42, 0x8f, 0x51, 0x18, 0x82, 0x8f, + 0xc0, 0x8f, 0x51, 0x18, 0x41, 0x18, 0x3a, 0x48, /// 0x1250 + 0x00, 0xf0, 0xba, 0xfb, 0x39, 0x49, 0x08, 0x84, + 0x01, 0x20, 0x10, 0xbd, 0x37, 0x48, 0x40, 0x38, /// 0x1260 + 0x80, 0x78, 0x05, 0x28, 0x01, 0xd3, 0x36, 0x49, + 0x01, 0xe0, 0x35, 0x49, 0x83, 0x31, 0x35, 0x48, /// 0x1270 + 0x02, 0x89, 0x89, 0x1a, 0x00, 0x22, 0x82, 0x5e, + 0x88, 0x18, 0x70, 0x47, 0x31, 0x48, 0x10, 0xb5, /// 0x1280 + 0x40, 0x30, 0xc4, 0x8b, 0x80, 0x8b, 0x21, 0x1a, + 0x2f, 0x48, 0x00, 0xf0, 0x9d, 0xfb, 0x28, 0x49, /// 0x1290 + 0x2e, 0x4a, 0x6c, 0x31, 0x08, 0x62, 0x60, 0x43, + 0x10, 0x1a, 0x48, 0x62, 0x10, 0xbd, 0x29, 0x48, /// 0x12a0 + 0x10, 0xb5, 0x40, 0x30, 0x44, 0x8b, 0x27, 0x48, + 0x00, 0x89, 0x21, 0x1a, 0x9d, 0x20, 0xc0, 0x03, /// 0x12b0 + 0x00, 0xf0, 0x8a, 0xfb, 0x26, 0x49, 0x27, 0x4a, + 0x08, 0x60, 0x60, 0x43, 0x10, 0x1a, 0x48, 0x60, /// 0x12c0 + 0x10, 0xbd, 0xf8, 0xb5, 0x24, 0x48, 0x00, 0x8b, + 0xcf, 0x26, 0xf6, 0x01, 0x37, 0x8b, 0x19, 0x20, /// 0x12d0 + 0x39, 0x46, 0x80, 0x03, 0x00, 0xf0, 0x78, 0xfb, + 0x15, 0x4c, 0x6c, 0x34, 0xa0, 0x80, 0x00, 0x20, /// 0x12e0 + 0xe0, 0x80, 0x75, 0x8b, 0x19, 0x20, 0xe9, 0x1b, + 0x80, 0x03, 0x00, 0xf0, 0x83, 0xfb, 0x80, 0xb2, /// 0x12f0 + 0x20, 0x81, 0x68, 0x43, 0x19, 0x21, 0x80, 0x12, + 0x49, 0x01, 0x08, 0x1a, 0x60, 0x81, 0xb4, 0x8b, /// 0x1300 + 0x7d, 0x20, 0x61, 0x1b, 0x00, 0x03, 0x00, 0xf0, + 0x75, 0xfb, 0x11, 0x49, 0x80, 0xb2, 0x08, 0x81, /// 0x1310 + 0x03, 0x4a, 0x60, 0x43, 0x80, 0x12, 0x56, 0x32, + 0x10, 0x1a, 0x48, 0x81, 0xf8, 0xbd, 0x00, 0x00, /// 0x1320 + 0xbe, 0x04, 0x00, 0x00, 0x41, 0x0a, 0x00, 0x00, + 0xff, 0x0f, 0x00, 0x00, 0x34, 0x02, 0x00, 0x20, /// 0x1330 + 0x44, 0x03, 0x00, 0x20, 0x00, 0x3c, 0x00, 0x40, + 0x00, 0x70, 0x17, 0x00, 0x40, 0x00, 0x00, 0x20, /// 0x1340 + 0xd7, 0x02, 0x00, 0x00, 0x20, 0x67, 0x00, 0x00, + 0x00, 0xe0, 0x79, 0x00, 0x00, 0xd0, 0xb6, 0x00, /// 0x1350 + 0x00, 0x05, 0x00, 0x20, 0x00, 0xf0, 0x7b, 0x00, + 0x00, 0x30, 0x00, 0x40, 0xb5, 0x48, 0x00, 0x68, /// 0x1360 + 0x00, 0x47, 0xb4, 0x48, 0x40, 0x68, 0x00, 0x47, + 0xb2, 0x48, 0x80, 0x68, 0x00, 0x47, 0xb1, 0x48, /// 0x1370 + 0xc0, 0x68, 0x00, 0x47, 0xaf, 0x48, 0x00, 0x69, + 0x00, 0x47, 0xae, 0x48, 0x40, 0x69, 0x00, 0x47, /// 0x1380 + 0xac, 0x48, 0x80, 0x69, 0x00, 0x47, 0xab, 0x48, + 0xc0, 0x69, 0x00, 0x47, 0xa9, 0x48, 0x00, 0x6a, /// 0x1390 + 0x00, 0x47, 0xa8, 0x48, 0x40, 0x6a, 0x00, 0x47, + 0xa6, 0x48, 0x80, 0x6a, 0x00, 0x47, 0xa5, 0x48, /// 0x13a0 + 0xc0, 0x6a, 0x00, 0x47, 0xf8, 0xb5, 0xa4, 0x48, + 0x02, 0x7a, 0x01, 0x79, 0x0a, 0x40, 0x02, 0x72, /// 0x13b0 + 0xd1, 0x07, 0x19, 0xd0, 0x01, 0x79, 0x49, 0x08, + 0x49, 0x00, 0x01, 0x71, 0x00, 0x21, 0x01, 0x74, /// 0x13c0 + 0x01, 0x70, 0x9e, 0x4c, 0x65, 0x7e, 0x9e, 0x49, + 0x02, 0x23, 0x05, 0x2d, 0x09, 0xd0, 0x0e, 0x79, /// 0x13d0 + 0x04, 0x25, 0x2e, 0x43, 0x0e, 0x71, 0x0e, 0x8a, + 0xc1, 0x27, 0xbf, 0x00, 0xbe, 0x43, 0x0e, 0x82, /// 0x13e0 + 0x65, 0x76, 0x0c, 0x79, 0x1c, 0x43, 0x0c, 0x71, + 0x91, 0x07, 0x10, 0xd5, 0x01, 0x79, 0xfd, 0x22, /// 0x13f0 + 0x11, 0x40, 0x01, 0x71, 0x90, 0x48, 0x00, 0x24, + 0x20, 0x30, 0x04, 0x70, 0x8f, 0x49, 0x10, 0x22, /// 0x1400 + 0x38, 0x31, 0x88, 0x18, 0xff, 0xf7, 0x76, 0xfb, + 0x8c, 0x48, 0xe0, 0x30, 0x44, 0x73, 0xf8, 0xbd, /// 0x1410 + 0xf8, 0xb5, 0x8b, 0x4c, 0xa0, 0x8a, 0x21, 0x8a, + 0x08, 0x40, 0xff, 0x21, 0xa1, 0x82, 0xc6, 0x21, /// 0x1420 + 0x06, 0x46, 0xff, 0x22, 0x0e, 0x40, 0x87, 0x4d, + 0x71, 0x32, 0x11, 0x1d, 0x52, 0x59, 0x49, 0x5b, /// 0x1430 + 0xff, 0x35, 0x02, 0x23, 0x61, 0x35, 0x00, 0x2e, + 0x25, 0xd0, 0xc4, 0x26, 0x30, 0x40, 0x00, 0x26, /// 0x1440 + 0x00, 0x28, 0x08, 0xd0, 0x20, 0x79, 0x18, 0x43, + 0x20, 0x71, 0x20, 0x20, 0xff, 0xf7, 0xec, 0xfa, /// 0x1450 + 0x06, 0x20, 0x68, 0x76, 0x07, 0xe0, 0x68, 0x7e, + 0x04, 0x28, 0x03, 0xd1, 0x20, 0x7b, 0x51, 0x18, /// 0x1460 + 0x20, 0x39, 0xc8, 0x77, 0x6e, 0x76, 0x0d, 0x20, + 0x20, 0x70, 0x03, 0x20, 0x00, 0x02, 0x20, 0x82, /// 0x1470 + 0x6a, 0x20, 0x20, 0x77, 0x26, 0x71, 0x70, 0x48, + 0x06, 0x70, 0x06, 0x74, 0x01, 0x79, 0x49, 0x08, /// 0x1480 + 0x49, 0x00, 0x01, 0x71, 0xf8, 0xbd, 0x6d, 0x4e, + 0xc7, 0x07, 0x20, 0x3e, 0xf6, 0x8e, 0x00, 0x2f, /// 0x1490 + 0x03, 0xd0, 0x30, 0x0a, 0x20, 0x73, 0x6b, 0x76, + 0xf8, 0xbd, 0xc0, 0x06, 0xfc, 0xd5, 0x68, 0x7e, /// 0x14a0 + 0x02, 0x28, 0x12, 0xd0, 0x21, 0x20, 0x20, 0x71, + 0xff, 0x20, 0xc3, 0x30, 0x20, 0x82, 0x62, 0x48, /// 0x14b0 + 0x40, 0x23, 0x03, 0x70, 0x90, 0x23, 0x03, 0x74, + 0x02, 0x83, 0x89, 0x1e, 0x81, 0x82, 0x01, 0x21, /// 0x14c0 + 0x01, 0x72, 0x02, 0x79, 0x0a, 0x43, 0x02, 0x71, + 0xf8, 0xbd, 0x26, 0x73, 0x03, 0x20, 0x68, 0x76, /// 0x14d0 + 0xf8, 0xbd, 0x5d, 0x49, 0x81, 0x20, 0x08, 0x80, + 0x70, 0x47, 0x70, 0xb5, 0x5a, 0x48, 0x02, 0x8b, /// 0x14e0 + 0x02, 0x83, 0x91, 0x06, 0x8c, 0x0f, 0x55, 0x49, + 0x01, 0x23, 0x60, 0x31, 0x00, 0x2c, 0x1f, 0xd0, /// 0x14f0 + 0x0a, 0x46, 0x20, 0x32, 0x95, 0x78, 0x00, 0x24, + 0x00, 0x2d, 0x11, 0xd0, 0x53, 0x49, 0x8b, 0x78, /// 0x1500 + 0x11, 0x46, 0x20, 0x39, 0xc9, 0x8b, 0x01, 0x2b, + 0x00, 0xd1, 0xc9, 0x43, 0x01, 0x82, 0x11, 0x78, /// 0x1510 + 0x01, 0x75, 0x01, 0x2d, 0x02, 0xd0, 0xff, 0xf7, + 0xfe, 0xfc, 0x70, 0xbd, 0x94, 0x70, 0x70, 0xbd, /// 0x1520 + 0x03, 0x80, 0x4b, 0x48, 0x0c, 0x75, 0x01, 0x8a, + 0x0c, 0x22, 0x91, 0x43, 0x01, 0x82, 0x70, 0xbd, /// 0x1530 + 0x05, 0x20, 0x00, 0x03, 0x02, 0x42, 0xfa, 0xd0, + 0xc8, 0x7e, 0x18, 0x43, 0xc8, 0x76, 0x70, 0xbd, /// 0x1540 + 0x3e, 0x48, 0x60, 0x38, 0x41, 0x68, 0x49, 0x1c, + 0x41, 0x60, 0x42, 0x49, 0x07, 0x20, 0x08, 0x72, /// 0x1550 + 0x70, 0x47, 0x10, 0xb5, 0x3f, 0x4c, 0x20, 0x7a, + 0x80, 0x07, 0x02, 0xd5, 0x3e, 0x48, 0xfe, 0xf7, /// 0x1560 + 0x96, 0xfd, 0x07, 0x20, 0x20, 0x72, 0x10, 0xbd, + 0x10, 0xb5, 0x3c, 0x49, 0x8b, 0x89, 0x33, 0x48, /// 0x1570 + 0x34, 0x4c, 0xa0, 0x30, 0x02, 0x7d, 0x52, 0x00, + 0x12, 0x19, 0xff, 0x32, 0xc1, 0x32, 0x93, 0x86, /// 0x1580 + 0x02, 0x7d, 0x52, 0x1c, 0x12, 0x07, 0x12, 0x0f, + 0x02, 0x75, 0x0f, 0x20, 0x08, 0x83, 0x10, 0xbd, /// 0x1590 + 0x33, 0x49, 0x0f, 0x20, 0x08, 0x83, 0x70, 0x47, + 0x2d, 0x48, 0x10, 0xb5, 0x40, 0x30, 0x81, 0x88, /// 0x15a0 + 0x09, 0x07, 0x0c, 0xd5, 0x81, 0x88, 0x08, 0x22, + 0x11, 0x43, 0x81, 0x80, 0x28, 0x48, 0x81, 0x88, /// 0x15b0 + 0x89, 0x07, 0x04, 0xd5, 0x2b, 0x4a, 0x02, 0x21, + 0xd1, 0x77, 0x01, 0x21, 0x81, 0x80, 0x1f, 0x48, /// 0x15c0 + 0x20, 0x30, 0x40, 0x68, 0x00, 0x28, 0x00, 0xd0, + 0x80, 0x47, 0x27, 0x49, 0x0f, 0x20, 0x08, 0x76, /// 0x15d0 + 0x10, 0xbd, 0x10, 0xb5, 0x25, 0x48, 0x01, 0x78, + 0x49, 0x06, 0x22, 0xd5, 0x41, 0x21, 0x01, 0x70, /// 0x15e0 + 0x1a, 0x48, 0x20, 0x21, 0x40, 0x38, 0x42, 0x6b, + 0x0a, 0x43, 0x42, 0x63, 0xc2, 0x6a, 0x0a, 0x43, /// 0x15f0 + 0xc2, 0x62, 0x08, 0x46, 0xff, 0xf7, 0xb0, 0xfa, + 0x14, 0x48, 0x00, 0x21, 0x41, 0x73, 0x1d, 0x4c, /// 0x1600 + 0x1b, 0x48, 0x20, 0x82, 0xa0, 0x8a, 0x61, 0x14, + 0x08, 0x43, 0xa0, 0x82, 0xa0, 0x8b, 0x40, 0x08, /// 0x1610 + 0x40, 0x00, 0xa0, 0x83, 0x64, 0x20, 0xff, 0xf7, + 0x07, 0xfa, 0xa0, 0x8b, 0x08, 0x21, 0x88, 0x43, /// 0x1620 + 0xa0, 0x83, 0x14, 0x48, 0x40, 0x30, 0x01, 0x79, + 0xc9, 0x07, 0x01, 0xd0, 0x10, 0x21, 0x01, 0x71, /// 0x1630 + 0x10, 0xbd, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, + 0x00, 0x60, 0x00, 0x40, 0x90, 0x02, 0x00, 0x20, /// 0x1640 + 0x00, 0x64, 0x00, 0x40, 0x30, 0x01, 0x00, 0x20, + 0x00, 0x38, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, /// 0x1650 + 0x00, 0x34, 0x00, 0x40, 0x00, 0x54, 0x00, 0x40, + 0x13, 0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x40, /// 0x1660 + 0x00, 0x50, 0x00, 0x40, 0x90, 0x03, 0x00, 0x20, + 0x00, 0x40, 0x00, 0x40, 0x00, 0x3c, 0x00, 0x40, /// 0x1670 + 0xff, 0x07, 0x00, 0x00, 0x00, 0x30, 0x00, 0x40, + 0x00, 0x21, 0x41, 0x61, 0x81, 0x61, 0xbb, 0x4a, /// 0x1680 + 0x02, 0x60, 0xc1, 0x61, 0xba, 0x4a, 0x42, 0x60, + 0xb8, 0x4a, 0xd2, 0x43, 0x82, 0x60, 0xb8, 0x4a, /// 0x1690 + 0xd2, 0x43, 0xc2, 0x60, 0xb7, 0x4a, 0x01, 0x66, + 0x02, 0x61, 0x41, 0x66, 0x70, 0x47, 0xf0, 0xb5, /// 0x16a0 + 0xb5, 0x4b, 0x84, 0x46, 0x0f, 0xcb, 0xd9, 0xb0, + 0x6c, 0x46, 0x0f, 0xc4, 0x00, 0x23, 0x09, 0xa8, /// 0x16b0 + 0x9a, 0x00, 0x61, 0x46, 0x54, 0x18, 0x20, 0x34, + 0x21, 0x78, 0x5b, 0x1c, 0x09, 0x06, 0x81, 0x50, /// 0x16c0 + 0x65, 0x78, 0x2d, 0x04, 0x29, 0x43, 0x81, 0x50, + 0xa5, 0x78, 0x2d, 0x02, 0x29, 0x43, 0x81, 0x50, /// 0x16d0 + 0xe4, 0x78, 0x21, 0x43, 0x81, 0x50, 0x10, 0x2b, + 0xea, 0xdb, 0x10, 0x21, 0x8c, 0x00, 0x22, 0x18, /// 0x16e0 + 0x80, 0x3a, 0x15, 0x6e, 0x53, 0x6f, 0x6b, 0x40, + 0x95, 0x6c, 0x12, 0x6c, 0x55, 0x40, 0x6b, 0x40, /// 0x16f0 + 0x1f, 0x22, 0xd3, 0x41, 0x49, 0x1c, 0x03, 0x51, + 0x50, 0x29, 0xef, 0xdb, 0x61, 0x46, 0x0a, 0x68, /// 0x1700 + 0x08, 0x92, 0x49, 0x68, 0x63, 0x46, 0x07, 0x91, + 0x9b, 0x68, 0x64, 0x46, 0x06, 0x93, 0xe4, 0x68, /// 0x1710 + 0x65, 0x46, 0x05, 0x94, 0x2d, 0x69, 0x00, 0x26, + 0xb6, 0x46, 0x04, 0x95, 0x70, 0x46, 0x86, 0x00, /// 0x1720 + 0x09, 0xa8, 0x87, 0x59, 0x1b, 0x20, 0x16, 0x46, + 0xc6, 0x41, 0xb8, 0x19, 0x0e, 0x46, 0x27, 0x46, /// 0x1730 + 0x1e, 0x40, 0x8f, 0x43, 0x3e, 0x43, 0x75, 0x19, + 0x45, 0x19, 0x00, 0x98, 0x28, 0x18, 0x25, 0x46, /// 0x1740 + 0x1c, 0x46, 0x0b, 0x46, 0x02, 0x21, 0xcb, 0x41, + 0x11, 0x46, 0x02, 0x46, 0x70, 0x46, 0x40, 0x1c, /// 0x1750 + 0x86, 0x46, 0x14, 0x28, 0xe2, 0xdb, 0x14, 0x20, + 0x86, 0x46, 0x86, 0x00, 0x09, 0xa8, 0x87, 0x59, /// 0x1760 + 0x1b, 0x20, 0x16, 0x46, 0xc6, 0x41, 0xb8, 0x19, + 0x0e, 0x46, 0x5e, 0x40, 0x66, 0x40, 0x75, 0x19, /// 0x1770 + 0x45, 0x19, 0x01, 0x98, 0x28, 0x18, 0x25, 0x46, + 0x1c, 0x46, 0x0b, 0x46, 0x02, 0x21, 0xcb, 0x41, /// 0x1780 + 0x11, 0x46, 0x02, 0x46, 0x70, 0x46, 0x40, 0x1c, + 0x86, 0x46, 0x28, 0x28, 0xe5, 0xdb, 0x28, 0x20, /// 0x1790 + 0x86, 0x46, 0x86, 0x00, 0x09, 0xa8, 0x87, 0x59, + 0x1b, 0x20, 0x16, 0x46, 0xc6, 0x41, 0xbf, 0x19, /// 0x17a0 + 0x1e, 0x46, 0x26, 0x43, 0x18, 0x46, 0x0e, 0x40, + 0x20, 0x40, 0x06, 0x43, 0x70, 0x19, 0x3d, 0x18, /// 0x17b0 + 0x02, 0x98, 0x28, 0x18, 0x25, 0x46, 0x1c, 0x46, + 0x02, 0x23, 0xd9, 0x41, 0x0b, 0x46, 0x11, 0x46, /// 0x17c0 + 0x02, 0x46, 0x70, 0x46, 0x40, 0x1c, 0x86, 0x46, + 0x3c, 0x28, 0xe2, 0xdb, 0x3c, 0x20, 0x86, 0x46, /// 0x17d0 + 0x86, 0x00, 0x09, 0xa8, 0x87, 0x59, 0x1b, 0x20, + 0x16, 0x46, 0xc6, 0x41, 0xb8, 0x19, 0x0e, 0x46, /// 0x17e0 + 0x5e, 0x40, 0x66, 0x40, 0x75, 0x19, 0x45, 0x19, + 0x03, 0x98, 0x28, 0x18, 0x25, 0x46, 0x1c, 0x46, /// 0x17f0 + 0x02, 0x23, 0xd9, 0x41, 0x0b, 0x46, 0x11, 0x46, + 0x02, 0x46, 0x70, 0x46, 0x40, 0x1c, 0x86, 0x46, /// 0x1800 + 0x50, 0x28, 0xe5, 0xdb, 0x08, 0x98, 0x82, 0x18, + 0x60, 0x46, 0x02, 0x60, 0x07, 0x98, 0x41, 0x18, /// 0x1810 + 0x60, 0x46, 0x41, 0x60, 0x06, 0x98, 0xc1, 0x18, + 0x60, 0x46, 0x81, 0x60, 0x05, 0x98, 0x01, 0x19, /// 0x1820 + 0x60, 0x46, 0xc1, 0x60, 0x04, 0x98, 0x41, 0x19, + 0x60, 0x46, 0x01, 0x61, 0x00, 0x21, 0xc1, 0x61, /// 0x1830 + 0x59, 0xb0, 0xf0, 0xbd, 0x70, 0xb5, 0x04, 0x46, + 0xc0, 0x69, 0x25, 0x46, 0x41, 0x1c, 0x80, 0x22, /// 0x1840 + 0x20, 0x35, 0x00, 0x26, 0xe1, 0x61, 0x37, 0x28, + 0x42, 0x55, 0x03, 0xdc, 0x13, 0xe0, 0x41, 0x1c, /// 0x1850 + 0xe1, 0x61, 0x46, 0x55, 0xe0, 0x69, 0x40, 0x28, + 0xf9, 0xdb, 0x20, 0x46, 0xff, 0xf7, 0x1f, 0xff, /// 0x1860 + 0x02, 0xe0, 0x41, 0x1c, 0xe1, 0x61, 0x46, 0x55, + 0xe0, 0x69, 0x38, 0x28, 0xf9, 0xdb, 0x05, 0xe0, /// 0x1870 + 0x41, 0x1c, 0xe1, 0x61, 0x46, 0x55, 0xe0, 0x69, + 0x38, 0x28, 0xf9, 0xdb, 0xa1, 0x69, 0x20, 0x46, /// 0x1880 + 0x0a, 0x0e, 0x40, 0x30, 0x02, 0x76, 0x0a, 0x0c, + 0x42, 0x76, 0x0a, 0x0a, 0x82, 0x76, 0xc1, 0x76, /// 0x1890 + 0x61, 0x69, 0x0a, 0x0e, 0x02, 0x77, 0x0a, 0x0c, + 0x42, 0x77, 0x0a, 0x0a, 0x82, 0x77, 0xc1, 0x77, /// 0x18a0 + 0x20, 0x46, 0xff, 0xf7, 0xfc, 0xfe, 0x70, 0xbd, + 0x30, 0xb5, 0x0d, 0x46, 0x04, 0x00, 0x08, 0xd0, /// 0x18b0 + 0x00, 0x2d, 0x06, 0xd0, 0x60, 0x6e, 0x00, 0x28, + 0x04, 0xd1, 0x20, 0x6e, 0x00, 0x28, 0x02, 0xd0, /// 0x18c0 + 0x10, 0xe0, 0x01, 0x20, 0x30, 0xbd, 0x20, 0x46, + 0xff, 0xf7, 0xb4, 0xff, 0x00, 0x20, 0x01, 0x46, /// 0x18d0 + 0x22, 0x18, 0x20, 0x32, 0x40, 0x1c, 0x11, 0x70, + 0x40, 0x28, 0xf9, 0xdb, 0x61, 0x61, 0x01, 0x20, /// 0x18e0 + 0xa1, 0x61, 0x20, 0x66, 0x00, 0x20, 0x03, 0x22, + 0x81, 0x08, 0x83, 0x07, 0x89, 0x00, 0x9b, 0x0f, /// 0x18f0 + 0x61, 0x58, 0xd3, 0x1a, 0xdb, 0x00, 0xd9, 0x40, + 0x29, 0x54, 0x40, 0x1c, 0x14, 0x28, 0xf3, 0xdb, /// 0x1900 + 0x00, 0x20, 0x30, 0xbd, 0xf0, 0xb5, 0x15, 0x00, + 0x0e, 0x46, 0x04, 0x46, 0x15, 0xd0, 0x00, 0x2c, /// 0x1910 + 0x07, 0xd0, 0x00, 0x2e, 0x05, 0xd0, 0x20, 0x6e, + 0x00, 0x28, 0x04, 0xd0, 0x03, 0x20, 0x60, 0x66, /// 0x1920 + 0xf0, 0xbd, 0x01, 0x20, 0xf0, 0xbd, 0x60, 0x6e, + 0x00, 0x28, 0xfb, 0xd1, 0x27, 0x46, 0x20, 0x37, /// 0x1930 + 0x6d, 0x1e, 0x02, 0xd3, 0x60, 0x6e, 0x00, 0x28, + 0x01, 0xd0, 0x00, 0x20, 0xf0, 0xbd, 0xe0, 0x69, /// 0x1940 + 0x31, 0x78, 0x42, 0x1c, 0xe2, 0x61, 0xc1, 0x55, + 0x60, 0x69, 0x08, 0x30, 0x60, 0x61, 0x05, 0xd1, /// 0x1950 + 0xa0, 0x69, 0x40, 0x1c, 0xa0, 0x61, 0x01, 0xd1, + 0x01, 0x20, 0x60, 0x66, 0xe0, 0x69, 0x40, 0x28, /// 0x1960 + 0x02, 0xd1, 0x20, 0x46, 0xff, 0xf7, 0x9b, 0xfe, + 0x76, 0x1c, 0xe1, 0xe7, 0x01, 0x23, 0x45, 0x67, /// 0x1970 + 0x89, 0xab, 0xcd, 0xef, 0xf0, 0xe1, 0xd2, 0xc3, + 0x70, 0x1a, 0x00, 0x00, 0x10, 0xb5, 0x06, 0x49, /// 0x1980 + 0x0c, 0x22, 0x0a, 0x76, 0x19, 0x22, 0x4a, 0x76, + 0x88, 0x76, 0x10, 0x20, 0xa0, 0x31, 0xc8, 0x72, /// 0x1990 + 0x01, 0x20, 0xff, 0xf7, 0x1e, 0xfb, 0x10, 0xbd, + 0xd0, 0x02, 0x00, 0x20, 0x10, 0xb5, 0x07, 0x48, /// 0x19a0 + 0x05, 0x49, 0x81, 0x60, 0x06, 0x49, 0x80, 0x30, + 0x01, 0x60, 0x08, 0x22, 0x05, 0x49, 0x10, 0x30, /// 0x19b0 + 0xff, 0xf7, 0xa0, 0xf8, 0x10, 0xbd, 0x00, 0x00, + 0x47, 0x1e, 0x00, 0x00, 0x30, 0x02, 0x00, 0x20, /// 0x19c0 + 0xad, 0x1a, 0x00, 0x00, 0xc4, 0x22, 0x00, 0x00, + 0x30, 0xb5, 0x0b, 0x46, 0x01, 0x46, 0x00, 0x20, /// 0x19d0 + 0x20, 0x22, 0x01, 0x24, 0x09, 0xe0, 0x0d, 0x46, + 0xd5, 0x40, 0x9d, 0x42, 0x05, 0xd3, 0x1d, 0x46, /// 0x19e0 + 0x95, 0x40, 0x49, 0x1b, 0x25, 0x46, 0x95, 0x40, + 0x40, 0x19, 0x15, 0x46, 0x52, 0x1e, 0x00, 0x2d, /// 0x19f0 + 0xf1, 0xdc, 0x30, 0xbd, 0x70, 0xb5, 0x00, 0x24, + 0x25, 0x46, 0x00, 0x28, 0x01, 0xda, 0x01, 0x24, /// 0x1a00 + 0x40, 0x42, 0x00, 0x29, 0x01, 0xda, 0x01, 0x25, + 0x49, 0x42, 0xff, 0xf7, 0xdd, 0xff, 0xac, 0x42, /// 0x1a10 + 0x00, 0xd0, 0x40, 0x42, 0x00, 0x2c, 0x00, 0xd0, + 0x49, 0x42, 0x70, 0xbd, 0x30, 0xb4, 0x74, 0x46, /// 0x1a20 + 0x64, 0x1e, 0x25, 0x78, 0x64, 0x1c, 0xab, 0x42, + 0x00, 0xd2, 0x1d, 0x46, 0x63, 0x5d, 0x5b, 0x00, /// 0x1a30 + 0xe3, 0x18, 0x30, 0xbc, 0x18, 0x47, 0x00, 0x00, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, /// 0x1a40 + 0xa5, 0x13, 0x00, 0x00, 0x41, 0x15, 0x00, 0x00, + 0x69, 0x15, 0x00, 0x00, 0x91, 0x15, 0x00, 0x00, /// 0x1a50 + 0x79, 0x00, 0x00, 0x00, 0x11, 0x14, 0x00, 0x00, + 0xd3, 0x14, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, /// 0x1a60 + 0x79, 0x00, 0x00, 0x00, 0x99, 0x15, 0x00, 0x00, + 0x79, 0x00, 0x00, 0x00, 0xd3, 0x15, 0x00, 0x00, /// 0x1a70 + 0x99, 0x79, 0x82, 0x5a, 0xa1, 0xeb, 0xd9, 0x6e, + 0xdc, 0xbc, 0x1b, 0x8f, 0xd6, 0xc1, 0x62, 0xca, /// 0x1a80 + 0xfe, 0x48, 0x32, 0x21, 0x01, 0x67, 0x01, 0x46, + 0x0a, 0x22, 0x40, 0x39, 0x8a, 0x73, 0x40, 0x39, /// 0x1a90 + 0x49, 0x68, 0x32, 0x39, 0x41, 0x66, 0xfa, 0x48, + 0x01, 0x7f, 0x49, 0x08, 0x49, 0x00, 0x01, 0x77, /// 0x1aa0 + 0xf8, 0x48, 0x01, 0x78, 0x49, 0x08, 0x49, 0x00, + 0x01, 0x70, 0x70, 0x47, 0xf8, 0xb5, 0xff, 0xf7, /// 0x1ab0 + 0xe7, 0xf8, 0xf3, 0x4e, 0x80, 0x3e, 0xf4, 0x89, + 0x00, 0x2c, 0x50, 0xd0, 0x00, 0x27, 0x35, 0x46, /// 0x1ac0 + 0xe0, 0x05, 0x40, 0x35, 0xf7, 0x81, 0x00, 0x28, + 0x15, 0xda, 0xff, 0xf7, 0x98, 0xf8, 0x02, 0x20, /// 0x1ad0 + 0x28, 0x70, 0xeb, 0x48, 0x01, 0x7f, 0x49, 0x08, + 0x49, 0x00, 0x01, 0x77, 0xe9, 0x48, 0x01, 0x78, /// 0x1ae0 + 0x49, 0x08, 0x49, 0x00, 0x01, 0x70, 0xe8, 0x49, + 0x5a, 0x20, 0x08, 0x70, 0xe6, 0x49, 0x10, 0x20, /// 0x1af0 + 0x40, 0x31, 0x08, 0x70, 0x33, 0xe0, 0xe5, 0x48, + 0x21, 0x04, 0x04, 0xd5, 0x01, 0x8f, 0x01, 0x22, /// 0x1b00 + 0x52, 0x02, 0x11, 0x43, 0x01, 0x87, 0xe1, 0x06, + 0x04, 0xd5, 0x01, 0x8f, 0xff, 0x22, 0x01, 0x32, /// 0x1b10 + 0x11, 0x43, 0x01, 0x87, 0xe0, 0x07, 0x03, 0xd0, + 0x68, 0x78, 0x08, 0x21, 0x08, 0x43, 0x68, 0x70, /// 0x1b20 + 0xa0, 0x06, 0x07, 0xd5, 0xda, 0x48, 0x01, 0x7d, + 0x01, 0x29, 0x01, 0xd1, 0x04, 0x21, 0x01, 0x75, /// 0x1b30 + 0xff, 0xf7, 0x21, 0xf8, 0x20, 0x07, 0x01, 0xd5, + 0xff, 0xf7, 0xa2, 0xff, 0xa0, 0x07, 0x01, 0xd5, /// 0x1b40 + 0x00, 0xf0, 0xde, 0xfe, 0x20, 0x06, 0x03, 0xd5, + 0xa8, 0x78, 0x01, 0x21, 0x08, 0x43, 0xa8, 0x70, /// 0x1b50 + 0x60, 0x07, 0x03, 0xd5, 0xa8, 0x78, 0x20, 0x21, + 0x08, 0x43, 0xa8, 0x70, 0x37, 0x73, 0x00, 0x20, /// 0x1b60 + 0xf8, 0xbd, 0xc6, 0x48, 0x10, 0xb5, 0x80, 0x38, + 0x41, 0x68, 0x80, 0x30, 0x42, 0x6e, 0x03, 0x6f, /// 0x1b70 + 0x8a, 0x1a, 0x9a, 0x42, 0x0c, 0xdb, 0x41, 0x66, + 0x83, 0x21, 0x89, 0x00, 0x01, 0x87, 0xc3, 0x48, /// 0x1b80 + 0x20, 0x30, 0xc1, 0x7e, 0xbd, 0x48, 0x20, 0x30, + 0x81, 0x76, 0x01, 0x20, 0xff, 0xf7, 0x21, 0xfa, /// 0x1b90 + 0x10, 0xbd, 0xbb, 0x48, 0x10, 0xb5, 0x10, 0x22, + 0xbe, 0x49, 0x30, 0x38, 0xfe, 0xf7, 0xaa, 0xff, /// 0x1ba0 + 0xb7, 0x48, 0x10, 0x22, 0xbc, 0x49, 0x58, 0x38, + 0xfe, 0xf7, 0xa4, 0xff, 0xff, 0x20, 0xb7, 0x49, /// 0x1bb0 + 0x7d, 0x30, 0xc8, 0x87, 0xb2, 0x48, 0x7c, 0x21, + 0x60, 0x38, 0xc1, 0x70, 0xff, 0x20, 0xb2, 0x49, /// 0x1bc0 + 0x7e, 0x30, 0x08, 0x82, 0x10, 0xbd, 0x10, 0xb5, + 0xff, 0xf7, 0xe3, 0xff, 0xaf, 0x4c, 0xf7, 0x21, /// 0x1bd0 + 0x40, 0x34, 0x60, 0x7b, 0x08, 0x40, 0x60, 0x73, + 0xac, 0x49, 0x01, 0x20, 0xca, 0x6a, 0x80, 0x05, /// 0x1be0 + 0x02, 0x43, 0xca, 0x62, 0xfe, 0xf7, 0xb8, 0xff, + 0x20, 0x46, 0xac, 0x49, 0x40, 0x30, 0xc1, 0x60, /// 0x1bf0 + 0x81, 0x60, 0xa2, 0x48, 0xaa, 0x49, 0x80, 0x30, + 0xc1, 0x82, 0xff, 0x38, 0x01, 0x38, 0x41, 0x68, /// 0x1c00 + 0x80, 0x30, 0xc1, 0x66, 0x81, 0x66, 0x02, 0x6f, + 0x89, 0x1a, 0x41, 0x66, 0x12, 0x20, 0xa0, 0x72, /// 0x1c10 + 0x20, 0x46, 0x03, 0x21, 0x20, 0x30, 0x81, 0x70, + 0x9d, 0x49, 0x04, 0x20, 0x08, 0x75, 0x97, 0x48, /// 0x1c20 + 0x07, 0x21, 0x40, 0x38, 0x81, 0x73, 0x10, 0xbd, + 0x70, 0xb5, 0x9e, 0x48, 0x01, 0x88, 0x07, 0x22, /// 0x1c30 + 0x12, 0x02, 0x91, 0x43, 0x01, 0x80, 0x95, 0x4c, + 0x08, 0x21, 0x40, 0x34, 0x60, 0x7b, 0x93, 0x4d, /// 0x1c40 + 0x08, 0x43, 0x60, 0x73, 0x01, 0x20, 0xe9, 0x6a, + 0x80, 0x05, 0x01, 0x43, 0xe9, 0x62, 0xfe, 0xf7, /// 0x1c50 + 0x83, 0xff, 0x12, 0x20, 0xa0, 0x72, 0x20, 0x34, + 0x8e, 0x49, 0x00, 0x26, 0x20, 0x46, 0xa6, 0x70, /// 0x1c60 + 0x10, 0x22, 0x10, 0x31, 0x30, 0x30, 0xfe, 0xf7, + 0x45, 0xff, 0x8b, 0x49, 0x20, 0x46, 0x10, 0x22, /// 0x1c70 + 0x10, 0x31, 0x08, 0x30, 0xfe, 0xf7, 0x3e, 0xff, + 0x20, 0x46, 0x8b, 0x49, 0x20, 0x30, 0x01, 0x82, /// 0x1c80 + 0x81, 0x4a, 0x8a, 0x49, 0x11, 0x82, 0xe9, 0x87, + 0x47, 0x21, 0xe1, 0x70, 0x88, 0x49, 0xc1, 0x60, /// 0x1c90 + 0x82, 0x49, 0x81, 0x60, 0x79, 0x48, 0x80, 0x30, + 0x41, 0x67, 0x7d, 0x48, 0x05, 0x21, 0x06, 0x75, /// 0x1ca0 + 0xff, 0x30, 0x41, 0x30, 0x81, 0x73, 0x70, 0xbd, + 0x10, 0xb5, 0x74, 0x48, 0x81, 0x49, 0x81, 0x63, /// 0x1cb0 + 0x41, 0x21, 0x49, 0x02, 0x81, 0x87, 0x80, 0x21, + 0x20, 0x30, 0x81, 0x77, 0x05, 0x20, 0xff, 0xf7, /// 0x1cc0 + 0x88, 0xf9, 0x10, 0xbd, 0x10, 0xb5, 0x6d, 0x48, + 0x7b, 0x49, 0x81, 0x63, 0x6e, 0x21, 0x81, 0x87, /// 0x1cd0 + 0x7a, 0x49, 0x20, 0x30, 0xca, 0x7b, 0x82, 0x77, + 0x0a, 0x7c, 0xc2, 0x77, 0x49, 0x7c, 0x20, 0x30, /// 0x1ce0 + 0x01, 0x70, 0x07, 0x20, 0xff, 0xf7, 0x75, 0xf9, + 0x10, 0xbd, 0x68, 0x49, 0x10, 0xb5, 0x40, 0x31, /// 0x1cf0 + 0x08, 0x88, 0xc0, 0x08, 0xff, 0x28, 0x00, 0xd9, + 0xff, 0x20, 0xc8, 0x72, 0xff, 0x22, 0x5f, 0x49, /// 0x1d00 + 0x0d, 0x32, 0x0a, 0x87, 0x20, 0x31, 0x88, 0x76, + 0x01, 0x20, 0xff, 0xf7, 0x62, 0xf9, 0x10, 0xbd, /// 0x1d10 + 0xf8, 0xb5, 0x5b, 0x4d, 0x5d, 0x4c, 0x40, 0x3d, + 0x68, 0x78, 0x26, 0x46, 0x27, 0x46, 0xc1, 0x06, /// 0x1d20 + 0x40, 0x36, 0xc0, 0x37, 0x00, 0x29, 0x0a, 0xda, + 0xef, 0x21, 0x08, 0x40, 0x68, 0x70, 0x01, 0x20, /// 0x1d30 + 0xe1, 0x6a, 0xc0, 0x02, 0x01, 0x43, 0xe1, 0x62, + 0xfe, 0xf7, 0x0e, 0xff, 0x10, 0xe0, 0x39, 0x79, /// 0x1d40 + 0x0a, 0x07, 0x06, 0xd5, 0x32, 0x7e, 0x1e, 0x2a, + 0x03, 0xd0, 0x20, 0x21, 0x08, 0x43, 0x68, 0x70, /// 0x1d50 + 0x06, 0xe0, 0x48, 0x06, 0x04, 0xd5, 0xbf, 0x20, + 0x01, 0x40, 0x80, 0x20, 0x01, 0x43, 0x39, 0x71, /// 0x1d60 + 0x38, 0x79, 0x81, 0x07, 0x02, 0xd5, 0x31, 0x7e, + 0x3f, 0x29, 0x16, 0xd0, 0x69, 0x78, 0x49, 0x06, /// 0x1d70 + 0x02, 0xd5, 0x31, 0x7e, 0x4f, 0x29, 0x13, 0xd0, + 0x00, 0x07, 0x09, 0xd5, 0x30, 0x7e, 0x1e, 0x28, /// 0x1d80 + 0x06, 0xd0, 0xe0, 0x6a, 0x10, 0x21, 0x08, 0x43, + 0xe0, 0x62, 0x08, 0x46, 0xfe, 0xf7, 0xe4, 0xfe, /// 0x1d90 + 0xa8, 0x78, 0xbf, 0x21, 0x08, 0x40, 0xa8, 0x70, + 0xf8, 0xbd, 0x01, 0xf0, 0xc8, 0xfe, 0xf7, 0xe7, /// 0x1da0 + 0x3a, 0x48, 0x59, 0x30, 0x01, 0xf0, 0x9f, 0xfe, + 0xf2, 0xe7, 0x10, 0xb5, 0x38, 0x48, 0x44, 0x49, /// 0x1db0 + 0xc4, 0x68, 0x36, 0x48, 0x3c, 0x4a, 0x40, 0x30, + 0x00, 0x88, 0x96, 0x32, 0x48, 0x43, 0x33, 0x49, /// 0x1dc0 + 0x89, 0x8f, 0x51, 0x43, 0x40, 0x1a, 0x64, 0x21, + 0xff, 0xf7, 0x14, 0xfe, 0x60, 0x43, 0xc1, 0x17, /// 0x1dd0 + 0x09, 0x0d, 0x08, 0x18, 0x2a, 0x49, 0x00, 0x13, + 0x40, 0x39, 0x48, 0x67, 0x10, 0xbd, 0x70, 0xb5, /// 0x1de0 + 0x28, 0x48, 0x20, 0x38, 0x00, 0x7d, 0x00, 0x07, + 0x22, 0xd5, 0x28, 0x4d, 0x20, 0x35, 0xe8, 0x7e, /// 0x1df0 + 0x0b, 0x28, 0x1d, 0xd0, 0x22, 0x4c, 0x20, 0x7f, + 0x40, 0x08, 0x40, 0x00, 0x20, 0x77, 0x21, 0x48, /// 0x1e00 + 0x01, 0x78, 0x49, 0x08, 0x49, 0x00, 0x01, 0x70, + 0x20, 0x49, 0x00, 0x14, 0xca, 0x6a, 0x02, 0x43, /// 0x1e10 + 0xca, 0x62, 0xfe, 0xf7, 0xa1, 0xfe, 0x61, 0x8b, + 0x20, 0x46, 0x40, 0x38, 0x00, 0x29, 0x08, 0xd0, /// 0x1e20 + 0x01, 0x78, 0xfd, 0x22, 0x11, 0x40, 0x01, 0x70, + 0x0b, 0x20, 0xe8, 0x76, 0xff, 0xf7, 0x28, 0xfe, /// 0x1e30 + 0x70, 0xbd, 0x02, 0x21, 0x01, 0x70, 0x14, 0x49, + 0x5a, 0x20, 0x08, 0x70, 0x12, 0x49, 0x10, 0x20, /// 0x1e40 + 0x40, 0x31, 0x08, 0x70, 0xfe, 0xe7, 0xf0, 0xb5, + 0x85, 0xb0, 0xff, 0xf7, 0xc8, 0xff, 0xff, 0xf7, /// 0x1e50 + 0xac, 0xff, 0x0f, 0x4e, 0x0a, 0x4f, 0x34, 0x46, + 0xe0, 0x1d, 0x31, 0x7d, 0xf9, 0x30, 0x60, 0x3f, /// 0x1e60 + 0x01, 0x90, 0x3d, 0x46, 0x80, 0x30, 0xff, 0x34, + 0x20, 0x35, 0xc1, 0x34, 0x04, 0x90, 0x01, 0x29, /// 0x1e70 + 0x4e, 0xd1, 0x01, 0x98, 0x31, 0x69, 0x40, 0x68, + 0x41, 0x1a, 0x23, 0xe0, 0xb0, 0x02, 0x00, 0x20, /// 0x1e80 + 0xc0, 0x00, 0x00, 0x20, 0x40, 0x6c, 0x00, 0x40, + 0x00, 0x30, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, /// 0x1e90 + 0x30, 0x01, 0x00, 0x20, 0xcc, 0x22, 0x00, 0x00, + 0xa4, 0x3b, 0x00, 0x00, 0x04, 0x0a, 0x0a, 0x00, /// 0x1ea0 + 0xdc, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x40, + 0x9e, 0x07, 0x00, 0x00, 0x47, 0x04, 0x00, 0x00, /// 0x1eb0 + 0x31, 0x14, 0x14, 0x04, 0x0c, 0x51, 0x0a, 0x00, + 0x0c, 0x71, 0x12, 0x00, 0x20, 0x67, 0x00, 0x00, /// 0x1ec0 + 0x41, 0x0a, 0x00, 0x00, 0xf2, 0x48, 0x81, 0x42, + 0x66, 0xd9, 0xf0, 0x68, 0x50, 0x28, 0x12, 0xd2, /// 0x1ed0 + 0x70, 0x7d, 0x40, 0x1c, 0xc0, 0xb2, 0x70, 0x75, + 0x05, 0x28, 0x0e, 0xd1, 0x60, 0x7e, 0x08, 0x21, /// 0x1ee0 + 0x08, 0x43, 0x60, 0x76, 0xfe, 0xf7, 0x8b, 0xfe, + 0xea, 0x48, 0x28, 0x82, 0x02, 0x20, 0x30, 0x75, /// 0x1ef0 + 0x01, 0x98, 0x40, 0x68, 0x30, 0x61, 0x00, 0x20, + 0x70, 0x75, 0x01, 0x98, 0x31, 0x69, 0x40, 0x68, /// 0x1f00 + 0x40, 0x1a, 0xe3, 0x49, 0x08, 0x31, 0x88, 0x42, + 0x02, 0xd9, 0x04, 0x20, 0x30, 0x75, 0x43, 0xe0, /// 0x1f10 + 0x30, 0x7d, 0x02, 0x28, 0x02, 0xd0, 0x03, 0x28, + 0x1e, 0xd0, 0x3d, 0xe0, 0x01, 0x98, 0x31, 0x69, /// 0x1f20 + 0x40, 0x68, 0x7d, 0x22, 0x41, 0x1a, 0x12, 0x01, + 0x91, 0x42, 0x35, 0xd9, 0xff, 0x22, 0xda, 0x49, /// 0x1f30 + 0x7d, 0x32, 0xca, 0x87, 0x7c, 0x21, 0xf9, 0x70, + 0xd8, 0x49, 0x52, 0x1c, 0x0a, 0x82, 0x61, 0x7e, /// 0x1f40 + 0x07, 0x22, 0x11, 0x43, 0x61, 0x76, 0x04, 0x9a, + 0x32, 0x21, 0x11, 0x67, 0x01, 0x46, 0x28, 0x39, /// 0x1f50 + 0x51, 0x66, 0x03, 0x21, 0x31, 0x75, 0x30, 0x61, + 0x01, 0x98, 0x31, 0x69, 0x40, 0x68, 0x47, 0x23, /// 0x1f60 + 0x42, 0x1a, 0xcb, 0x48, 0xce, 0x49, 0x82, 0x42, + 0x24, 0xd2, 0xff, 0x22, 0xf0, 0x68, 0x91, 0x32, /// 0x1f70 + 0x90, 0x42, 0x0f, 0xd9, 0x70, 0x7d, 0x40, 0x1c, + 0xc0, 0xb2, 0x70, 0x75, 0x05, 0x28, 0x0b, 0xd1, /// 0x1f80 + 0x04, 0x20, 0x30, 0x75, 0x00, 0x20, 0x70, 0x75, + 0x29, 0x82, 0xc3, 0x49, 0xc5, 0x48, 0xc8, 0x87, /// 0x1f90 + 0xfb, 0x70, 0x01, 0xe0, 0x00, 0x20, 0x70, 0x75, + 0xbf, 0x49, 0x28, 0x8c, 0xc2, 0x4a, 0xa0, 0x31, /// 0x1fa0 + 0x00, 0x91, 0x90, 0x42, 0x11, 0xd0, 0x00, 0x28, + 0x0f, 0xd0, 0x40, 0x1e, 0x10, 0x40, 0x28, 0x84, /// 0x1fb0 + 0x03, 0xd0, 0x0a, 0xe0, 0x04, 0x20, 0x30, 0x75, + 0xe6, 0xe7, 0x08, 0x79, 0x41, 0x08, 0x00, 0x98, /// 0x1fc0 + 0x49, 0x00, 0x01, 0x71, 0x00, 0x20, 0xc0, 0x43, + 0x28, 0x84, 0x00, 0x98, 0x05, 0x26, 0x00, 0x79, /// 0x1fd0 + 0x01, 0x46, 0x31, 0x40, 0x04, 0x29, 0x03, 0xd1, + 0xfb, 0x21, 0x08, 0x40, 0x00, 0x99, 0x08, 0x71, /// 0x1fe0 + 0xa8, 0x78, 0x40, 0x06, 0x01, 0xd5, 0xff, 0xf7, + 0x93, 0xfe, 0xab, 0x48, 0xad, 0x49, 0xc0, 0x8f, /// 0x1ff0 + 0x88, 0x42, 0x07, 0xd9, 0xa8, 0x48, 0x80, 0x78, + 0x05, 0x28, 0x01, 0xd3, 0x06, 0x20, 0x08, 0xe0, /// 0x2000 + 0xbe, 0x70, 0x07, 0xe0, 0xff, 0x21, 0xf5, 0x31, + 0x88, 0x42, 0x01, 0xd9, 0x01, 0x20, 0x00, 0xe0, /// 0x2010 + 0x03, 0x20, 0xb8, 0x70, 0xa5, 0x48, 0x03, 0x90, + 0x40, 0x7b, 0x00, 0x28, 0x0a, 0xd1, 0xa3, 0x48, /// 0x2020 + 0xb0, 0x38, 0xfe, 0xf7, 0xaa, 0xfa, 0x20, 0x7d, + 0x00, 0x28, 0x01, 0xd1, 0xfe, 0xf7, 0xe3, 0xfa, /// 0x2030 + 0xfe, 0xf7, 0x15, 0xfc, 0x98, 0x4f, 0x98, 0x49, + 0xc0, 0x37, 0x9a, 0x4b, 0x38, 0x7f, 0xc9, 0x8f, /// 0x2040 + 0x77, 0x33, 0x02, 0x46, 0x99, 0x42, 0x03, 0xd3, + 0x3b, 0x8c, 0x92, 0x49, 0x8b, 0x42, 0x01, 0xd2, /// 0x2050 + 0x40, 0x08, 0x40, 0x00, 0x96, 0x49, 0x38, 0x77, + 0xc3, 0x07, 0x0b, 0x78, 0x02, 0xd0, 0x01, 0x26, /// 0x2060 + 0x33, 0x43, 0x06, 0xe0, 0xdb, 0x07, 0x01, 0xd0, + 0xc2, 0x43, 0xd2, 0xb2, 0x0b, 0x78, 0x5b, 0x08, /// 0x2070 + 0x5b, 0x00, 0x0b, 0x70, 0x90, 0x42, 0x07, 0xd0, + 0x87, 0x49, 0x01, 0x20, 0xca, 0x6a, 0x00, 0x04, /// 0x2080 + 0x02, 0x43, 0xca, 0x62, 0xfe, 0xf7, 0x68, 0xfd, + 0x6a, 0x78, 0xd0, 0x06, 0x10, 0xd5, 0xb8, 0x89, /// 0x2090 + 0x41, 0x1c, 0xb9, 0x81, 0x80, 0x49, 0x4b, 0x8c, + 0x98, 0x42, 0x09, 0xd9, 0xef, 0x20, 0x02, 0x40, /// 0x20a0 + 0x6a, 0x70, 0x01, 0x20, 0xca, 0x6a, 0x80, 0x02, + 0x02, 0x43, 0xca, 0x62, 0xfe, 0xf7, 0x54, 0xfd, /// 0x20b0 + 0x28, 0x78, 0xc0, 0x06, 0x01, 0xd5, 0x01, 0xf0, + 0xb5, 0xfc, 0x20, 0x7d, 0x00, 0x28, 0x27, 0xd1, /// 0x20c0 + 0x7c, 0x49, 0xe0, 0x7d, 0x0e, 0x46, 0xff, 0x36, + 0x41, 0x36, 0x31, 0x46, 0xc0, 0x31, 0x02, 0x91, /// 0x20d0 + 0x00, 0x28, 0x20, 0xd0, 0x40, 0x1e, 0xe0, 0x75, + 0xb0, 0x7b, 0x04, 0x28, 0x18, 0xd3, 0x72, 0xb6, /// 0x20e0 + 0x75, 0x48, 0xfd, 0xf7, 0xd4, 0xff, 0x62, 0xb6, + 0x20, 0x7e, 0xe1, 0x7d, 0x40, 0x1e, 0x81, 0x42, /// 0x20f0 + 0x0e, 0xd1, 0x02, 0x99, 0x00, 0x20, 0x88, 0x83, + 0x08, 0x83, 0x00, 0x98, 0xc1, 0x7b, 0x6f, 0x48, /// 0x2100 + 0x41, 0x71, 0x42, 0x79, 0x81, 0x14, 0x00, 0x2a, + 0x02, 0x88, 0x02, 0xd0, 0x0a, 0x43, 0x02, 0x80, /// 0x2110 + 0xb2, 0xe0, 0x8a, 0x43, 0xfb, 0xe7, 0x00, 0x20, + 0x60, 0x77, 0xb0, 0x7b, 0x03, 0x00, 0xff, 0xf7, /// 0x2120 + 0x7d, 0xfc, 0x0b, 0x07, 0xab, 0x4e, 0x53, 0x5f, + 0x85, 0xab, 0x88, 0x8b, 0x9b, 0x9e, 0xab, 0x00, /// 0x2130 + 0x59, 0x48, 0xff, 0x21, 0x80, 0x8f, 0x01, 0x27, + 0x25, 0x31, 0x7f, 0x03, 0x88, 0x42, 0x21, 0xd9, /// 0x2140 + 0x56, 0x4d, 0x01, 0x20, 0x28, 0x82, 0xa8, 0x8a, + 0x38, 0x43, 0xa8, 0x82, 0x14, 0x20, 0xfe, 0xf7, /// 0x2150 + 0x6b, 0xfc, 0xa8, 0x8b, 0x08, 0x27, 0x38, 0x43, + 0xa8, 0x83, 0x14, 0x20, 0xfe, 0xf7, 0x64, 0xfc, /// 0x2160 + 0xa8, 0x8b, 0x01, 0x21, 0x08, 0x43, 0xa8, 0x83, + 0x14, 0x20, 0xfe, 0xf7, 0x5d, 0xfc, 0xa8, 0x8b, /// 0x2170 + 0x40, 0x08, 0x40, 0x00, 0xa8, 0x83, 0x14, 0x20, + 0xfe, 0xf7, 0x56, 0xfc, 0xa8, 0x8b, 0xb8, 0x43, /// 0x2180 + 0xa8, 0x83, 0x0e, 0xe0, 0x45, 0x4d, 0xa8, 0x8b, + 0x40, 0x08, 0x40, 0x00, 0xa8, 0x83, 0x64, 0x20, /// 0x2190 + 0xfe, 0xf7, 0x4a, 0xfc, 0xa9, 0x8b, 0x08, 0x20, + 0x81, 0x43, 0xa9, 0x83, 0xa8, 0x8a, 0xb8, 0x43, /// 0x21a0 + 0xa8, 0x82, 0x01, 0x98, 0x40, 0x68, 0x1d, 0x28, + 0x66, 0xd9, 0x08, 0x20, 0x20, 0x76, 0x04, 0x99, /// 0x21b0 + 0x32, 0x20, 0x08, 0x67, 0x02, 0x20, 0xb0, 0x73, + 0xff, 0xf7, 0x97, 0xfd, 0x5c, 0xe0, 0xff, 0xf7, /// 0x21c0 + 0x81, 0xfd, 0x03, 0x20, 0xb0, 0x73, 0x57, 0xe0, + 0x31, 0x20, 0xe8, 0x70, 0x1e, 0x20, 0x20, 0x76, /// 0x21d0 + 0xff, 0xf7, 0x6a, 0xfd, 0x04, 0x20, 0xb0, 0x73, + 0x03, 0x99, 0x01, 0x20, 0xc8, 0x72, 0x4b, 0xe0, /// 0x21e0 + 0x03, 0x98, 0x00, 0x7b, 0xc0, 0x07, 0x02, 0xd0, + 0xff, 0xf7, 0x1e, 0xfd, 0x01, 0xe0, 0xff, 0xf7, /// 0x21f0 + 0xea, 0xfc, 0xff, 0x20, 0x28, 0x49, 0xf5, 0x30, + 0x48, 0x84, 0x00, 0x20, 0xa8, 0x64, 0x78, 0x71, /// 0x2200 + 0xc8, 0x22, 0xfa, 0x81, 0x01, 0x22, 0x7a, 0x77, + 0xff, 0x22, 0x4a, 0x72, 0x29, 0x4a, 0x80, 0x23, /// 0x2210 + 0x20, 0x32, 0x13, 0x72, 0x42, 0x1e, 0x2a, 0x84, + 0x00, 0x9a, 0x10, 0x71, 0x23, 0x4a, 0x40, 0x32, /// 0x2220 + 0x10, 0x77, 0x27, 0x4a, 0x48, 0x6b, 0x10, 0x43, + 0x48, 0x63, 0x25, 0xe0, 0x01, 0xf0, 0x04, 0xfb, /// 0x2230 + 0x22, 0xe0, 0x01, 0xf0, 0x41, 0xf9, 0x1f, 0xe0, + 0x03, 0x98, 0x00, 0x7b, 0xc0, 0x07, 0x01, 0xd0, /// 0x2240 + 0x09, 0x20, 0x00, 0xe0, 0x07, 0x20, 0xb0, 0x73, + 0x18, 0x49, 0x00, 0x20, 0x20, 0x31, 0xc8, 0x74, /// 0x2250 + 0x02, 0x98, 0xa9, 0x68, 0x41, 0x67, 0x0f, 0xe0, + 0x00, 0xf0, 0x91, 0xfb, 0x0c, 0xe0, 0x0e, 0x48, /// 0x2260 + 0x20, 0x30, 0xc1, 0x7e, 0x13, 0x48, 0xe0, 0x30, + 0x0b, 0x29, 0x08, 0xd0, 0x03, 0x29, 0x06, 0xd0, /// 0x2270 + 0x00, 0x21, 0xc1, 0x75, 0xff, 0xf7, 0x75, 0xfc, + 0x00, 0x20, 0x05, 0xb0, 0xf0, 0xbd, 0xc1, 0x7d, /// 0x2280 + 0x49, 0x1c, 0xc9, 0xb2, 0xc1, 0x75, 0x03, 0x29, + 0xf4, 0xd9, 0x04, 0x21, 0xc1, 0x75, 0xf3, 0xe7, /// 0x2290 + 0x98, 0x3a, 0x00, 0x00, 0x7c, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x30, 0x00, 0x40, /// 0x22a0 + 0x9e, 0x07, 0x00, 0x00, 0x47, 0x04, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x70, 0x03, 0x00, 0x20, /// 0x22b0 + 0x40, 0x6c, 0x00, 0x40, 0x30, 0x01, 0x00, 0x20, + 0xc7, 0x26, 0x00, 0x00, 0x20, 0x38, 0x00, 0x40, /// 0x22c0 + 0xd8, 0xbf, 0x0f, 0x00, 0x69, 0x60, 0x63, 0x02, + 0x69, 0x60, 0x63, 0x24, 0xf6, 0x03, 0x19, 0x02, /// 0x22d0 + 0xbb, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x75, 0x06, 0x32, 0x04, /// 0x22e0 + 0x5d, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x28, 0x01, 0xd2, /// 0x22f0 + 0x01, 0x20, 0x70, 0x47, 0x80, 0x28, 0x03, 0xd2, + 0x20, 0x38, 0x00, 0x11, 0x80, 0x1c, 0x70, 0x47, /// 0x2300 + 0xe0, 0x28, 0x03, 0xd2, 0x80, 0x38, 0xc0, 0x10, + 0x08, 0x30, 0x70, 0x47, 0xe0, 0x38, 0x80, 0x10, /// 0x2310 + 0x14, 0x30, 0x70, 0x47, 0x41, 0x07, 0x89, 0x0f, + 0x03, 0x29, 0x0b, 0xd1, 0x01, 0x07, 0x03, 0xd5, /// 0x2320 + 0x80, 0x09, 0x02, 0x28, 0x04, 0xd0, 0x05, 0xe0, + 0x00, 0x09, 0x03, 0xd0, 0x0c, 0x28, 0x01, 0xd8, /// 0x2330 + 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, + 0x1e, 0x28, 0x08, 0xd0, 0xc1, 0x43, 0x09, 0x07, /// 0x2340 + 0x07, 0xd1, 0x01, 0x09, 0x06, 0x29, 0x04, 0xd2, + 0x00, 0x06, 0x00, 0x0f, 0x01, 0xd0, 0x01, 0x20, /// 0x2350 + 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x10, 0xb5, + 0xfc, 0x48, 0xf7, 0x22, 0xc1, 0x79, 0x11, 0x40, /// 0x2360 + 0xc1, 0x71, 0xfa, 0x49, 0x00, 0x20, 0x20, 0x39, + 0x08, 0x87, 0x80, 0x20, 0xfe, 0xf7, 0xf4, 0xfb, /// 0x2370 + 0x10, 0xbd, 0xf8, 0xb5, 0xf6, 0x4b, 0x18, 0x78, + 0xff, 0xf7, 0xde, 0xff, 0xf4, 0x4f, 0x20, 0x37, /// 0x2380 + 0x00, 0x28, 0x18, 0xd0, 0xf8, 0x7c, 0x40, 0x1c, + 0xc0, 0xb2, 0xf8, 0x74, 0x06, 0x28, 0x01, 0xd9, /// 0x2390 + 0x06, 0x20, 0xf8, 0x74, 0xc2, 0xb2, 0xed, 0x48, + 0x19, 0x46, 0x38, 0x30, 0xfe, 0xf7, 0xb1, 0xfb, /// 0x23a0 + 0xea, 0x48, 0x40, 0x22, 0x60, 0x30, 0x81, 0x78, + 0x11, 0x43, 0x81, 0x70, 0xf8, 0x7a, 0xef, 0x21, /// 0x23b0 + 0x08, 0x40, 0xf8, 0x72, 0xf8, 0xbd, 0xe5, 0x4c, + 0x18, 0x78, 0x20, 0x3c, 0x26, 0x46, 0x25, 0x46, /// 0x23c0 + 0x04, 0x22, 0x20, 0x36, 0xc0, 0x35, 0x15, 0x28, + 0x18, 0xd0, 0xff, 0xf7, 0xa3, 0xff, 0x01, 0x00, /// 0x23d0 + 0xe0, 0x48, 0x57, 0xd0, 0x19, 0x78, 0xf2, 0x79, + 0xc9, 0x07, 0xd2, 0x07, 0xc9, 0x0f, 0xd2, 0x0f, /// 0x23e0 + 0x91, 0x42, 0x4c, 0xd1, 0xf9, 0x7c, 0x6b, 0x7e, + 0x8c, 0x46, 0x2a, 0x7e, 0x59, 0x18, 0x91, 0x42, /// 0x23f0 + 0x24, 0xd9, 0x69, 0x76, 0x20, 0x8f, 0x02, 0x21, + 0x08, 0x43, 0x08, 0xe0, 0x58, 0x78, 0x01, 0x06, /// 0x2400 + 0x15, 0xd5, 0xf1, 0x79, 0x8b, 0x06, 0x9b, 0x0f, + 0x03, 0xd0, 0x20, 0x8f, 0x10, 0x43, 0x20, 0x87, /// 0x2410 + 0xf8, 0xbd, 0x22, 0x8f, 0x08, 0x23, 0x40, 0x06, + 0x1a, 0x43, 0x40, 0x0e, 0x22, 0x87, 0x40, 0x1c, /// 0x2420 + 0x28, 0x76, 0x00, 0x20, 0x68, 0x76, 0x48, 0x08, + 0x40, 0x00, 0xf0, 0x71, 0xf8, 0xbd, 0x03, 0x28, /// 0x2430 + 0x01, 0xd1, 0xff, 0xf7, 0x90, 0xff, 0x20, 0x8f, + 0x08, 0x21, 0xdd, 0xe7, 0xc4, 0x49, 0x18, 0x18, /// 0x2440 + 0x62, 0x46, 0x49, 0x1c, 0xfe, 0xf7, 0x5d, 0xfb, + 0x68, 0x7e, 0xf9, 0x7c, 0x01, 0x22, 0x40, 0x18, /// 0x2450 + 0xc1, 0xb2, 0x69, 0x76, 0xf0, 0x79, 0x40, 0x23, + 0x50, 0x40, 0xf0, 0x71, 0x22, 0x8f, 0x1a, 0x43, /// 0x2460 + 0x22, 0x87, 0xbb, 0x4a, 0x32, 0x23, 0xa0, 0x3a, + 0x13, 0x67, 0x05, 0x22, 0x3a, 0x72, 0x2a, 0x7e, /// 0x2470 + 0x91, 0x42, 0xdb, 0xd1, 0x10, 0x21, 0x08, 0x43, + 0xf0, 0x71, 0x08, 0x46, 0x16, 0xe0, 0x20, 0x8f, /// 0x2480 + 0x40, 0x21, 0xb9, 0xe7, 0xf1, 0x79, 0x89, 0x06, + 0x89, 0x0f, 0xbe, 0xd1, 0x21, 0x8f, 0x08, 0x22, /// 0x2490 + 0x11, 0x43, 0x21, 0x87, 0xf9, 0x7c, 0x49, 0x1c, + 0xca, 0xb2, 0x2a, 0x76, 0x19, 0x46, 0xfe, 0xf7, /// 0x24a0 + 0x30, 0xfb, 0xf0, 0x79, 0x20, 0x21, 0x08, 0x43, + 0xf0, 0x71, 0x08, 0x46, 0xfe, 0xf7, 0x54, 0xfb, /// 0x24b0 + 0xf8, 0xbd, 0xf8, 0xb5, 0xa5, 0x4e, 0xa0, 0x36, + 0x34, 0x46, 0xc0, 0x3c, 0x23, 0x46, 0xf2, 0x7d, /// 0x24c0 + 0xb1, 0x7d, 0x20, 0x33, 0xd8, 0x79, 0x8a, 0x42, + 0x07, 0xd3, 0x22, 0x8f, 0x80, 0x21, 0x8a, 0x43, /// 0x24d0 + 0xf7, 0x21, 0x22, 0x87, 0x08, 0x40, 0xd8, 0x71, + 0xf8, 0xbd, 0x89, 0x1a, 0xcd, 0xb2, 0x08, 0x2d, /// 0x24e0 + 0x00, 0xd9, 0x08, 0x25, 0x29, 0x07, 0x0f, 0x0e, + 0x81, 0x07, 0x01, 0xd5, 0x07, 0x21, 0x00, 0xe0, /// 0x24f0 + 0x06, 0x21, 0x39, 0x43, 0x02, 0x27, 0x78, 0x40, + 0xd8, 0x71, 0x95, 0x48, 0x01, 0x75, 0xff, 0x38, /// 0x2500 + 0xd9, 0x38, 0x11, 0x18, 0xff, 0x30, 0x2a, 0x46, + 0xee, 0x30, 0xfe, 0xf7, 0xfa, 0xfa, 0xf0, 0x7d, /// 0x2510 + 0x80, 0x21, 0x40, 0x19, 0xf0, 0x75, 0x20, 0x8f, + 0x08, 0x43, 0x20, 0x87, 0x8c, 0x48, 0x32, 0x21, /// 0x2520 + 0xa0, 0x38, 0x01, 0x67, 0x8a, 0x49, 0x05, 0x20, + 0x20, 0x31, 0x08, 0x72, 0xf8, 0xbd, 0xfe, 0xb5, /// 0x2530 + 0x87, 0x4c, 0x06, 0x46, 0x20, 0x34, 0xe0, 0x7a, + 0x00, 0x28, 0x05, 0xd1, 0x00, 0x2e, 0x01, 0xd0, /// 0x2540 + 0x02, 0x20, 0x00, 0xe0, 0x08, 0x20, 0xe0, 0x72, + 0xc0, 0xb2, 0x84, 0x46, 0x82, 0x07, 0x81, 0x49, /// 0x2550 + 0xf0, 0x01, 0x01, 0x90, 0x7e, 0x39, 0x7d, 0x48, + 0xcf, 0x1d, 0xff, 0x37, 0x20, 0x30, 0xfa, 0x37, /// 0x2560 + 0x00, 0x89, 0xbb, 0x8b, 0x00, 0x93, 0x09, 0x23, + 0x9b, 0x01, 0xcb, 0x18, 0x9d, 0x7c, 0x11, 0x23, /// 0x2570 + 0x5b, 0x01, 0xcb, 0x18, 0x19, 0x78, 0x00, 0x2a, + 0x8e, 0x46, 0x4e, 0xd0, 0x71, 0x46, 0x01, 0x9a, /// 0x2580 + 0x49, 0x08, 0x11, 0x43, 0xc9, 0xb2, 0x19, 0x70, + 0x00, 0x2d, 0x0a, 0xd0, 0x07, 0x2d, 0x10, 0xd3, /// 0x2590 + 0xff, 0x29, 0x11, 0xd0, 0x00, 0x29, 0x3b, 0xd0, + 0x55, 0x29, 0x3b, 0xd0, 0xaa, 0x29, 0x39, 0xd0, /// 0x25a0 + 0x85, 0xe0, 0x48, 0x21, 0x48, 0x43, 0x6c, 0x49, + 0xff, 0xf7, 0x0e, 0xfa, 0x00, 0x99, 0x40, 0x18, /// 0x25b0 + 0xf8, 0x83, 0x6d, 0x1c, 0xa5, 0x74, 0x84, 0xe0, + 0x60, 0x46, 0x80, 0x07, 0x02, 0xd5, 0xff, 0xf7, /// 0x25c0 + 0x78, 0xff, 0x74, 0xe0, 0x61, 0x4d, 0xa0, 0x35, + 0xa9, 0x8a, 0x00, 0x29, 0x1e, 0xd0, 0xc8, 0x07, /// 0x25d0 + 0x02, 0xd0, 0xff, 0xf7, 0xc0, 0xfe, 0x11, 0xe0, + 0x5c, 0x4a, 0x8b, 0x06, 0xd0, 0x79, 0x00, 0x2b, /// 0x25e0 + 0x07, 0xda, 0x00, 0x21, 0xe9, 0x75, 0xfd, 0x21, + 0x08, 0x40, 0xd0, 0x71, 0xff, 0xf7, 0x61, 0xff, /// 0x25f0 + 0x04, 0xe0, 0xc9, 0x06, 0x02, 0xd5, 0xf7, 0x21, + 0x08, 0x40, 0xd0, 0x71, 0x53, 0x48, 0xaa, 0x8a, /// 0x2600 + 0x20, 0x38, 0x01, 0x8f, 0x91, 0x43, 0x01, 0x87, + 0x00, 0x20, 0xa8, 0x82, 0x01, 0x20, 0x02, 0xe0, /// 0x2610 + 0x02, 0x20, 0x00, 0xe0, 0x04, 0x20, 0x20, 0x73, + 0x49, 0xe0, 0x61, 0x46, 0xc9, 0x06, 0x49, 0x0f, /// 0x2620 + 0x45, 0xd0, 0x4b, 0x4a, 0x20, 0x32, 0xd1, 0x7c, + 0x52, 0x7c, 0x00, 0x2d, 0x12, 0xd0, 0x09, 0x2d, /// 0x2630 + 0x26, 0xd0, 0x0a, 0x2d, 0x3d, 0xd3, 0x00, 0x2e, + 0x39, 0xd0, 0x00, 0x20, 0xa0, 0x74, 0x00, 0x2a, /// 0x2640 + 0x26, 0xd0, 0x8a, 0x42, 0x28, 0xd9, 0x18, 0x46, + 0x89, 0x1c, 0xfe, 0xf7, 0x51, 0xfc, 0x00, 0x28, /// 0x2650 + 0x26, 0xd0, 0x2c, 0xe0, 0x00, 0x2e, 0x2a, 0xd1, + 0x01, 0x23, 0xa3, 0x74, 0x00, 0x2a, 0x0c, 0xd0, /// 0x2660 + 0x8a, 0x1a, 0x58, 0x21, 0x92, 0x1c, 0x4a, 0x43, + 0x08, 0x32, 0x50, 0x43, 0x3a, 0x49, 0xff, 0xf7, /// 0x2670 + 0xab, 0xf9, 0x00, 0x99, 0x40, 0x18, 0xf8, 0x83, + 0x23, 0xe0, 0x60, 0x21, 0x48, 0x43, 0xf5, 0xe7, /// 0x2680 + 0x0a, 0x20, 0xa0, 0x74, 0xd0, 0x5c, 0xfe, 0xf7, + 0x3c, 0xfc, 0xb0, 0x42, 0x0f, 0xd0, 0x18, 0xe0, /// 0x2690 + 0x70, 0x46, 0xff, 0xf7, 0x2b, 0xfe, 0xe0, 0x74, + 0x60, 0x7c, 0x40, 0x1c, 0x60, 0x74, 0x10, 0xe0, /// 0x26a0 + 0xe0, 0x7a, 0x40, 0x07, 0x01, 0xd5, 0x08, 0x20, + 0xb5, 0xe7, 0xff, 0xf7, 0x62, 0xfe, 0x01, 0x20, /// 0x26b0 + 0xfe, 0xbd, 0xd0, 0x5c, 0x01, 0x99, 0x40, 0x08, + 0x08, 0x43, 0xd0, 0x54, 0xa0, 0x7c, 0x40, 0x1c, /// 0x26c0 + 0xa0, 0x74, 0x00, 0x20, 0xfe, 0xbd, 0xfe, 0xb5, + 0x21, 0x4c, 0x24, 0x48, 0x20, 0x3c, 0x21, 0x8b, /// 0x26d0 + 0x26, 0x46, 0x00, 0x27, 0x40, 0x3e, 0x81, 0x42, + 0x09, 0xd1, 0xe0, 0x8b, 0x41, 0x1e, 0xe1, 0x83, /// 0x26e0 + 0x03, 0xd3, 0x30, 0x7e, 0x40, 0x1e, 0xf0, 0x75, + 0x00, 0xe1, 0xf7, 0x75, 0xfe, 0xe0, 0x17, 0x48, /// 0x26f0 + 0xa1, 0x8b, 0x20, 0x38, 0x02, 0x46, 0x16, 0x4d, + 0x40, 0x32, 0x80, 0x30, 0x20, 0x35, 0x01, 0x92, /// 0x2700 + 0x00, 0x90, 0x00, 0x29, 0x06, 0xd1, 0x2f, 0x73, + 0x6f, 0x74, 0xaf, 0x74, 0x0f, 0x20, 0xe0, 0x83, /// 0x2710 + 0xfe, 0xf7, 0xdf, 0xf9, 0xaf, 0xe0, 0x41, 0x00, + 0x0e, 0x4a, 0x40, 0x1c, 0x7e, 0x3a, 0x89, 0x18, /// 0x2720 + 0xff, 0x31, 0xc1, 0x31, 0x00, 0x07, 0x89, 0x8e, + 0x00, 0x0f, 0x60, 0x75, 0x20, 0x8b, 0x40, 0x1c, /// 0x2730 + 0x80, 0xb2, 0x20, 0x83, 0x03, 0x28, 0x42, 0xd8, + 0x01, 0x28, 0x11, 0xd0, 0x62, 0x8b, 0x51, 0x18, /// 0x2740 + 0x89, 0xb2, 0x61, 0x83, 0x03, 0x28, 0x10, 0xd1, + 0x10, 0xe0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, /// 0x2750 + 0x50, 0x03, 0x00, 0x20, 0xae, 0x01, 0x00, 0x20, + 0x70, 0x17, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, /// 0x2760 + 0x67, 0x83, 0xef, 0x73, 0xaf, 0x73, 0xaf, 0x75, + 0xef, 0x75, 0x84, 0xe0, 0x49, 0x1c, 0x48, 0x08, /// 0x2770 + 0x60, 0x83, 0x01, 0x99, 0x08, 0x81, 0x00, 0x99, + 0x09, 0x78, 0xc9, 0x07, 0x16, 0xd1, 0x5c, 0x49, /// 0x2780 + 0x5c, 0x4a, 0xc9, 0x8f, 0x91, 0x42, 0x02, 0xd2, + 0xfd, 0xf7, 0xa8, 0xfe, 0x0e, 0xe0, 0x5a, 0x48, /// 0x2790 + 0x02, 0x8a, 0x40, 0x21, 0x0a, 0x43, 0x02, 0x82, + 0x02, 0x8a, 0x4f, 0x23, 0x1a, 0x40, 0x39, 0x23, /// 0x27a0 + 0x1b, 0x02, 0xd2, 0x18, 0x02, 0x82, 0x02, 0x8a, + 0x8a, 0x43, 0x02, 0x82, 0x61, 0x8b, 0x53, 0x4a, /// 0x27b0 + 0x48, 0x08, 0x80, 0x18, 0xff, 0xf7, 0x08, 0xf9, + 0x01, 0x99, 0xc8, 0x83, 0x5b, 0xe0, 0x00, 0x98, /// 0x27c0 + 0xc2, 0x7a, 0x06, 0x20, 0x93, 0x07, 0x9b, 0x0f, + 0x98, 0x40, 0x80, 0x1e, 0x52, 0x07, 0x62, 0x8b, /// 0x27d0 + 0x03, 0xd5, 0x10, 0x18, 0x88, 0x42, 0x03, 0xd3, + 0x20, 0xe0, 0x10, 0x1a, 0x88, 0x42, 0x1d, 0xd9, /// 0x27e0 + 0xe8, 0x7b, 0x40, 0x1c, 0xc0, 0xb2, 0xe8, 0x73, + 0x0a, 0x28, 0x53, 0xd8, 0xa8, 0x7d, 0x00, 0x28, /// 0x27f0 + 0x12, 0xd0, 0xa8, 0x7b, 0x05, 0x28, 0x01, 0xd9, + 0x00, 0x20, 0x05, 0xe0, 0x02, 0x28, 0x0b, 0xd9, /// 0x2800 + 0xe8, 0x7d, 0x00, 0x28, 0x06, 0xd0, 0x01, 0x20, + 0xff, 0xf7, 0x91, 0xfe, 0x00, 0x28, 0x41, 0xd1, /// 0x2810 + 0xef, 0x75, 0x01, 0xe0, 0x01, 0x20, 0xe8, 0x75, + 0xaf, 0x73, 0x2c, 0xe0, 0xa8, 0x7b, 0x40, 0x1c, /// 0x2820 + 0xc0, 0xb2, 0xa8, 0x73, 0xa9, 0x7d, 0x00, 0x29, + 0x0c, 0xd0, 0xe9, 0x7d, 0x00, 0x29, 0x03, 0xd0, /// 0x2830 + 0x05, 0x28, 0x0c, 0xd9, 0x01, 0x20, 0x02, 0xe0, + 0x0a, 0x28, 0x08, 0xd9, 0x00, 0x20, 0xff, 0xf7, /// 0x2840 + 0x76, 0xfe, 0x27, 0xe0, 0xe8, 0x7b, 0x02, 0x28, + 0x01, 0xd9, 0x01, 0x20, 0xa8, 0x75, 0xe8, 0x7b, /// 0x2850 + 0x05, 0x28, 0x01, 0xd9, 0x00, 0x20, 0x05, 0xe0, + 0x02, 0x28, 0x0b, 0xd9, 0xe8, 0x7d, 0x00, 0x28, /// 0x2860 + 0x06, 0xd0, 0x01, 0x20, 0xff, 0xf7, 0x63, 0xfe, + 0x00, 0x28, 0x13, 0xd1, 0xef, 0x75, 0x01, 0xe0, /// 0x2870 + 0x01, 0x20, 0xe8, 0x75, 0xef, 0x73, 0x21, 0x7d, + 0x60, 0x7d, 0x81, 0x42, 0x00, 0xd0, 0x4a, 0xe7, /// 0x2880 + 0x30, 0x7e, 0x40, 0x1e, 0xf0, 0x75, 0xa0, 0x8b, + 0x40, 0x1c, 0x80, 0xb2, 0xa0, 0x83, 0xe1, 0x8b, /// 0x2890 + 0x88, 0x42, 0x2b, 0xd9, 0xfe, 0xf7, 0xc2, 0xf8, + 0x00, 0x20, 0xc0, 0x43, 0x20, 0x83, 0xef, 0x72, /// 0x28a0 + 0x70, 0x7f, 0x00, 0x28, 0x01, 0xd0, 0x16, 0x20, + 0x00, 0xe0, 0x05, 0x20, 0x70, 0x77, 0x28, 0x7b, /// 0x28b0 + 0x00, 0x28, 0x01, 0xd0, 0x70, 0x7f, 0x10, 0xe0, + 0xe0, 0x8b, 0x0f, 0x28, 0x04, 0xd9, 0xa1, 0x8b, /// 0x28c0 + 0x40, 0x1a, 0x71, 0x7f, 0x40, 0x18, 0x08, 0xe0, + 0xa0, 0x8b, 0x31, 0x7e, 0x02, 0x1d, 0x8a, 0x42, /// 0x28d0 + 0x02, 0xd2, 0xc0, 0xb2, 0x08, 0x1a, 0x00, 0xe0, + 0x04, 0x20, 0xe0, 0x83, 0xa0, 0x8b, 0xe1, 0x8b, /// 0x28e0 + 0x42, 0x18, 0x31, 0x7e, 0x8a, 0x42, 0x01, 0xd2, + 0x08, 0x1a, 0xe0, 0x83, 0x00, 0x20, 0xfe, 0xbd, /// 0x28f0 + 0x00, 0x00, 0x00, 0x20, 0xbe, 0x04, 0x00, 0x00, + 0x00, 0x34, 0x00, 0x40, 0x00, 0xdc, 0x05, 0x00, /// 0x2900 + 0x10, 0xb5, 0xfe, 0x48, 0x41, 0x7e, 0x0a, 0x07, + 0x03, 0xd5, 0xf7, 0x22, 0x11, 0x40, 0x41, 0x76, /// 0x2910 + 0x10, 0xbd, 0x08, 0x22, 0x11, 0x43, 0x41, 0x76, + 0xfe, 0xf7, 0x71, 0xf9, 0x10, 0xbd, 0xf7, 0x49, /// 0x2920 + 0x00, 0x20, 0xf7, 0x4a, 0x40, 0x31, 0x49, 0x6f, + 0x92, 0x68, 0x06, 0xe0, 0x0b, 0x46, 0x53, 0x40, /// 0x2930 + 0x1b, 0x06, 0x00, 0xd0, 0x40, 0x1c, 0x09, 0x0a, + 0x12, 0x0a, 0x0b, 0x46, 0x13, 0x43, 0xf5, 0xd1, /// 0x2940 + 0x70, 0x47, 0xee, 0x4a, 0x10, 0xb5, 0xef, 0x4b, + 0x40, 0x3a, 0x13, 0x87, 0x20, 0x32, 0x90, 0x76, /// 0x2950 + 0xd1, 0x76, 0x11, 0x46, 0x01, 0x20, 0xa0, 0x31, + 0xc8, 0x72, 0x02, 0x20, 0xfe, 0xf7, 0x39, 0xfb, /// 0x2960 + 0x10, 0xbd, 0xe6, 0x49, 0x10, 0xb5, 0xe8, 0x4a, + 0x40, 0x39, 0x0a, 0x87, 0x20, 0x31, 0x88, 0x76, /// 0x2970 + 0x04, 0x20, 0xa0, 0x31, 0xc8, 0x72, 0x01, 0x20, + 0xfe, 0xf7, 0x2b, 0xfb, 0x10, 0xbd, 0xf8, 0xb5, /// 0x2980 + 0xde, 0x4c, 0xdf, 0x4a, 0xa0, 0x34, 0x80, 0x3a, + 0xe0, 0x7c, 0x25, 0x46, 0x13, 0x46, 0x02, 0x26, /// 0x2990 + 0x20, 0x3d, 0x80, 0x33, 0x00, 0x28, 0x02, 0xd0, + 0x01, 0x28, 0x0b, 0xd0, 0x3e, 0xe0, 0xd8, 0x79, /// 0x29a0 + 0xc0, 0x07, 0x05, 0xd0, 0x31, 0x20, 0xff, 0xf7, + 0xdc, 0xff, 0x01, 0x20, 0xe0, 0x74, 0xf8, 0xbd, /// 0x29b0 + 0xe6, 0x74, 0x0e, 0xe0, 0x28, 0x7b, 0x00, 0x07, + 0xfa, 0xd5, 0xd0, 0x48, 0x60, 0x30, 0x01, 0x78, /// 0x29c0 + 0x31, 0x29, 0xf5, 0xd1, 0x41, 0x78, 0x19, 0x71, + 0x81, 0x78, 0x59, 0x71, 0xc0, 0x78, 0x98, 0x71, /// 0x29d0 + 0xee, 0xe7, 0xe7, 0x7c, 0x78, 0x08, 0xf9, 0x07, + 0x7f, 0x1c, 0xff, 0xb2, 0xe7, 0x74, 0xbc, 0x46, /// 0x29e0 + 0x00, 0x29, 0x0c, 0xd0, 0x29, 0x7b, 0xc9, 0x07, + 0x18, 0xd0, 0x11, 0x18, 0xc7, 0x4f, 0x80, 0x31, /// 0x29f0 + 0x38, 0x18, 0x13, 0x27, 0x7f, 0x01, 0x09, 0x7b, + 0xc0, 0x19, 0x01, 0x75, 0x0e, 0xe0, 0x17, 0x18, /// 0x2a00 + 0x80, 0x37, 0x39, 0x7b, 0x3f, 0x7a, 0xb9, 0x42, + 0x05, 0xd0, 0xc2, 0x07, 0x00, 0xd1, 0x04, 0x20, /// 0x2a10 + 0xff, 0xf7, 0x97, 0xff, 0xf8, 0xbd, 0x60, 0x46, + 0x40, 0x1c, 0xe0, 0x74, 0xe0, 0x7c, 0x08, 0x28, /// 0x2a20 + 0xd7, 0xd3, 0x41, 0x1c, 0xe1, 0x74, 0x08, 0x28, + 0x0c, 0xd0, 0xb9, 0x49, 0x28, 0x7b, 0xc9, 0x6a, /// 0x2a30 + 0xc0, 0x07, 0x0c, 0xd0, 0xb1, 0x48, 0x40, 0x30, + 0x40, 0x6f, 0x98, 0x60, 0x01, 0x20, 0xde, 0x71, /// 0x2a40 + 0x80, 0x04, 0x07, 0xe0, 0xff, 0xf7, 0x6b, 0xff, + 0xc1, 0xb2, 0x00, 0x20, 0xe0, 0xe7, 0x04, 0x20, /// 0x2a50 + 0xd8, 0x71, 0x40, 0x04, 0x01, 0x43, 0xd1, 0x62, + 0xfe, 0xf7, 0x7e, 0xf8, 0xa7, 0x48, 0x07, 0x21, /// 0x2a60 + 0x80, 0x38, 0x81, 0x73, 0xf8, 0xbd, 0xa5, 0x48, + 0x10, 0xb5, 0xaa, 0x49, 0x40, 0x38, 0x81, 0x63, /// 0x2a70 + 0xa2, 0x49, 0x01, 0x20, 0x80, 0x31, 0xc8, 0x72, + 0xfe, 0xf7, 0xab, 0xfa, 0x10, 0xbd, 0x9f, 0x48, /// 0x2a80 + 0x10, 0xb5, 0xa5, 0x49, 0x40, 0x38, 0x01, 0x87, + 0xa1, 0x48, 0x20, 0x30, 0x81, 0x7e, 0x9b, 0x48, /// 0x2a90 + 0x20, 0x38, 0x81, 0x76, 0x01, 0x20, 0xfe, 0xf7, + 0x9c, 0xfa, 0x10, 0xbd, 0x97, 0x48, 0x10, 0xb5, /// 0x2aa0 + 0x60, 0x30, 0x00, 0x7d, 0xff, 0xf7, 0x22, 0xfc, + 0x94, 0x49, 0xc4, 0xb2, 0x74, 0x31, 0x08, 0x46, /// 0x2ab0 + 0x62, 0x1c, 0x7b, 0x38, 0xfe, 0xf7, 0x25, 0xf8, + 0x90, 0x48, 0x0c, 0x21, 0x20, 0x38, 0x01, 0x76, /// 0x2ac0 + 0x20, 0x46, 0xfe, 0xf7, 0x86, 0xfa, 0x10, 0xbd, + 0x8c, 0x49, 0x10, 0xb5, 0x0c, 0x22, 0x20, 0x39, /// 0x2ad0 + 0x0a, 0x76, 0x15, 0x22, 0x4a, 0x76, 0x88, 0x76, + 0x01, 0x20, 0xfe, 0xf7, 0x7a, 0xfa, 0x10, 0xbd, /// 0x2ae0 + 0x8a, 0x48, 0x10, 0xb5, 0x40, 0x30, 0x00, 0x7a, + 0xff, 0xf7, 0x00, 0xfc, 0x04, 0x46, 0x42, 0x1c, /// 0x2af0 + 0x86, 0x49, 0x82, 0x48, 0x48, 0x31, 0xc0, 0x1f, + 0xfe, 0xf7, 0x03, 0xf8, 0x7f, 0x48, 0x0c, 0x21, /// 0x2b00 + 0x20, 0x38, 0x01, 0x76, 0x20, 0x46, 0xfe, 0xf7, + 0x64, 0xfa, 0x10, 0xbd, 0xf0, 0xb5, 0x7c, 0x48, /// 0x2b10 + 0x01, 0x78, 0x49, 0x06, 0x01, 0xd5, 0x00, 0x20, + 0xf0, 0xbd, 0x01, 0x8a, 0x78, 0x48, 0x40, 0x38, /// 0x2b20 + 0x00, 0x88, 0x0b, 0x1a, 0x02, 0xd5, 0x01, 0x25, + 0x59, 0x42, 0x01, 0xe0, 0x00, 0x25, 0x19, 0x46, /// 0x2b30 + 0x72, 0x48, 0x04, 0x26, 0xa0, 0x30, 0x42, 0x7f, + 0x94, 0x08, 0x34, 0x1b, 0x4c, 0x43, 0x61, 0x09, /// 0x2b40 + 0x05, 0xd0, 0x00, 0x2d, 0x01, 0xd0, 0x00, 0x24, + 0x02, 0xe0, 0x02, 0x24, 0x00, 0xe0, 0x01, 0x24, /// 0x2b50 + 0x1c, 0x26, 0x86, 0x57, 0x02, 0x27, 0x7e, 0x40, + 0x20, 0x27, 0xa6, 0x42, 0x05, 0xd1, 0x0f, 0x2a, /// 0x2b60 + 0x01, 0xd2, 0x52, 0x1c, 0x0e, 0xe0, 0x87, 0x77, + 0x0e, 0xe0, 0x86, 0x7f, 0x00, 0x2e, 0x0b, 0xd0, /// 0x2b70 + 0x76, 0x1e, 0x36, 0x06, 0x36, 0x0e, 0x86, 0x77, + 0x06, 0xd1, 0x00, 0x2a, 0x04, 0xd0, 0xfc, 0x26, /// 0x2b80 + 0x52, 0x1e, 0x32, 0x40, 0x42, 0x77, 0xee, 0xe7, + 0x04, 0x77, 0x00, 0x24, 0x00, 0x29, 0x0b, 0xd0, /// 0x2b90 + 0xc4, 0x76, 0x84, 0x76, 0x08, 0x22, 0x02, 0x76, + 0x7f, 0x29, 0x00, 0xd9, 0x7f, 0x21, 0x00, 0x2d, /// 0x2ba0 + 0x00, 0xd0, 0x49, 0x42, 0x48, 0xb2, 0xf0, 0xbd, + 0x82, 0x7e, 0xd2, 0x18, 0x56, 0xb2, 0x86, 0x76, /// 0x2bb0 + 0xc2, 0x7e, 0x52, 0x1c, 0xd3, 0xb2, 0xc3, 0x76, + 0x9a, 0x07, 0xf0, 0xd1, 0x02, 0x7e, 0x96, 0x42, /// 0x2bc0 + 0x02, 0xdd, 0x01, 0x21, 0x00, 0x25, 0x04, 0xe0, + 0x57, 0x42, 0xbe, 0x42, 0x07, 0xda, 0x01, 0x21, /// 0x2bd0 + 0x0d, 0x46, 0x0c, 0x2b, 0x01, 0xd3, 0x52, 0x1c, + 0x02, 0x76, 0x84, 0x76, 0xdc, 0xe7, 0xc4, 0x76, /// 0x2be0 + 0x43, 0x7e, 0x5b, 0x1c, 0xdb, 0xb2, 0x43, 0x76, + 0x20, 0x2b, 0xf6, 0xd9, 0x44, 0x76, 0x04, 0x2a, /// 0x2bf0 + 0xf3, 0xd9, 0x52, 0x1e, 0xf0, 0xe7, 0xf0, 0xb5, + 0x45, 0x48, 0x48, 0x49, 0x80, 0x8f, 0x40, 0x4f, /// 0x2c00 + 0x48, 0x43, 0x8d, 0xb0, 0x00, 0x0c, 0x40, 0x3f, + 0xb8, 0x87, 0x38, 0x88, 0x44, 0x49, 0x41, 0x43, /// 0x2c10 + 0x09, 0x0c, 0xf9, 0x87, 0x43, 0x49, 0x88, 0x42, + 0x05, 0xd2, 0x43, 0x48, 0x01, 0x8b, 0x3f, 0x22, /// 0x2c20 + 0x12, 0x02, 0x91, 0x43, 0x01, 0x83, 0x35, 0x48, + 0x08, 0x90, 0x40, 0x7e, 0x37, 0x4d, 0x41, 0x07, /// 0x2c30 + 0xe8, 0x1d, 0x37, 0x4e, 0xff, 0x30, 0xfa, 0x30, + 0x09, 0x90, 0x30, 0x46, 0x80, 0x30, 0x07, 0x90, /// 0x2c40 + 0xe8, 0x1d, 0x34, 0x46, 0xf9, 0x30, 0xff, 0x35, + 0xa0, 0x34, 0x81, 0x35, 0xc0, 0x36, 0x0a, 0x90, /// 0x2c50 + 0x00, 0x29, 0x6d, 0xda, 0x78, 0x8f, 0xfd, 0xf7, + 0xfc, 0xfd, 0x00, 0x90, 0xb8, 0x80, 0x07, 0x98, /// 0x2c60 + 0x00, 0x78, 0xc0, 0x07, 0x7e, 0xd1, 0x2a, 0x48, + 0xc1, 0x8f, 0x2b, 0x48, 0x4e, 0x38, 0x81, 0x42, /// 0x2c70 + 0x03, 0xd2, 0x38, 0x89, 0xfd, 0xf7, 0x32, 0xfc, + 0x0e, 0xe0, 0x2c, 0x48, 0x02, 0x8a, 0x40, 0x21, /// 0x2c80 + 0x0a, 0x43, 0x02, 0x82, 0x02, 0x8a, 0x4f, 0x23, + 0x1a, 0x40, 0x39, 0x23, 0x1b, 0x02, 0xd2, 0x18, /// 0x2c90 + 0x02, 0x82, 0x02, 0x8a, 0x8a, 0x43, 0x02, 0x82, + 0x1c, 0x48, 0x00, 0x7d, 0x03, 0x28, 0x02, 0xd0, /// 0x2ca0 + 0x00, 0x98, 0xfe, 0xf7, 0x38, 0xfa, 0x1a, 0x48, + 0xc1, 0x8f, 0xff, 0x20, 0xf5, 0x30, 0x81, 0x42, /// 0x2cb0 + 0x04, 0xd2, 0xff, 0x22, 0x01, 0x32, 0xff, 0x20, + 0x21, 0x30, 0x03, 0xe0, 0xff, 0x22, 0x61, 0x32, /// 0x2cc0 + 0xff, 0x20, 0x81, 0x30, 0x84, 0x46, 0xb8, 0x88, + 0x40, 0x28, 0x0b, 0xd2, 0x17, 0x4b, 0x9b, 0x88, /// 0x2cd0 + 0x00, 0x2b, 0x07, 0xd0, 0xff, 0x23, 0xf5, 0x33, + 0x99, 0x42, 0x03, 0xd3, 0x0e, 0x4b, 0x4e, 0x3b, /// 0x2ce0 + 0x99, 0x42, 0x09, 0xd3, 0x60, 0x28, 0x24, 0xd2, + 0x10, 0x4b, 0x9b, 0x88, 0x00, 0x2b, 0x2b, 0xd0, /// 0x2cf0 + 0x09, 0x4b, 0x4e, 0x3b, 0x99, 0x42, 0x27, 0xd3, + 0x00, 0x20, 0x40, 0xe0, 0xf0, 0x02, 0x00, 0x20, /// 0x2d00 + 0x80, 0x00, 0x00, 0x20, 0x0c, 0x20, 0x00, 0x00, + 0x0c, 0x07, 0x00, 0x00, 0x30, 0x01, 0x00, 0x20, /// 0x2d10 + 0x00, 0x00, 0x00, 0x20, 0x0c, 0x09, 0x00, 0x00, + 0x0c, 0x05, 0x00, 0x00, 0x80, 0x20, 0x05, 0x00, /// 0x2d20 + 0xa0, 0x68, 0x06, 0x00, 0x02, 0x02, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x40, 0x00, 0x34, 0x00, 0x40, /// 0x2d30 + 0x6c, 0xe0, 0x60, 0x28, 0x08, 0xd9, 0x90, 0x42, + 0x06, 0xd2, 0xfe, 0x4b, 0x9b, 0x88, 0x01, 0x2b, /// 0x2d40 + 0x02, 0xd0, 0xfd, 0x4b, 0x99, 0x42, 0x27, 0xd3, + 0x80, 0x28, 0x08, 0xd9, 0x90, 0x42, 0x06, 0xd2, /// 0x2d50 + 0xf8, 0x4b, 0x9b, 0x88, 0x01, 0x2b, 0x02, 0xd0, + 0xf7, 0x4b, 0x99, 0x42, 0x1c, 0xd2, 0x60, 0x45, /// 0x2d60 + 0x12, 0xd9, 0x00, 0xe0, 0x3b, 0xe0, 0xf3, 0x49, + 0x8b, 0x88, 0x03, 0x2b, 0x0c, 0xd0, 0xf3, 0x4a, /// 0x2d70 + 0xd0, 0x7f, 0x00, 0x28, 0x05, 0xd0, 0xd0, 0x7f, + 0x40, 0x1e, 0xd0, 0x77, 0x2d, 0xe0, 0xed, 0x49, /// 0x2d80 + 0x00, 0xe0, 0x03, 0x20, 0x88, 0x80, 0x28, 0xe0, + 0xea, 0x49, 0x89, 0x88, 0x00, 0x29, 0x05, 0xd1, /// 0x2d90 + 0x90, 0x42, 0x03, 0xd3, 0x60, 0x45, 0x01, 0xd8, + 0x01, 0x20, 0xf0, 0xe7, 0x08, 0x98, 0x80, 0x7e, /// 0x2da0 + 0xfd, 0xf7, 0xfd, 0xfe, 0x08, 0x98, 0x80, 0x7e, + 0x0a, 0x28, 0x01, 0xd2, 0x01, 0x20, 0x06, 0xe0, /// 0x2db0 + 0x0f, 0x28, 0x01, 0xd3, 0x14, 0x28, 0x01, 0xd2, + 0x02, 0x20, 0x00, 0xe0, 0x03, 0x20, 0xdd, 0x49, /// 0x2dc0 + 0x0a, 0x88, 0xf8, 0x23, 0x9a, 0x43, 0x83, 0x01, + 0xc0, 0x00, 0x1a, 0x43, 0x20, 0x30, 0x02, 0x43, /// 0x2dd0 + 0x0a, 0x80, 0x88, 0x89, 0x06, 0x22, 0x10, 0x43, + 0x88, 0x81, 0xfe, 0xf7, 0x66, 0xf9, 0xff, 0xf7, /// 0x2de0 + 0x95, 0xfe, 0x31, 0x79, 0x8a, 0x07, 0x5f, 0xd1, + 0xb2, 0x79, 0x53, 0x1c, 0xb3, 0x71, 0x03, 0x2a, /// 0x2df0 + 0x5a, 0xd9, 0x7a, 0x7b, 0x12, 0x07, 0x57, 0xd4, + 0x06, 0x22, 0x11, 0x43, 0x31, 0x71, 0x0a, 0x99, /// 0x2e00 + 0x4a, 0x68, 0x07, 0x99, 0x8a, 0x64, 0x00, 0x21, + 0x71, 0x71, 0x4d, 0xe0, 0xff, 0xf7, 0x7e, 0xfe, /// 0x2e10 + 0x08, 0x99, 0x49, 0x7e, 0x8c, 0x46, 0x09, 0x07, + 0x46, 0xd4, 0x07, 0x99, 0xc6, 0x4a, 0x09, 0x8a, /// 0x2e20 + 0x2c, 0x3a, 0x91, 0x42, 0x10, 0xd8, 0x3a, 0x88, + 0x8a, 0x42, 0x07, 0xd8, 0x0a, 0x99, 0xea, 0x6e, /// 0x2e30 + 0x49, 0x68, 0x89, 0x1a, 0x7d, 0x22, 0x12, 0x01, + 0x91, 0x42, 0x03, 0xdb, 0x21, 0x7a, 0x10, 0x22, /// 0x2e40 + 0x11, 0x43, 0x0f, 0xe0, 0x37, 0x20, 0x0e, 0xe0, + 0x21, 0x7a, 0x8a, 0x07, 0x06, 0xd5, 0x0a, 0x9a, /// 0x2e50 + 0xeb, 0x6e, 0x52, 0x68, 0xd2, 0x1a, 0xba, 0x4b, + 0x9a, 0x42, 0x04, 0xdb, 0x10, 0x22, 0x11, 0x43, /// 0x2e60 + 0x49, 0x08, 0x49, 0x00, 0x21, 0x72, 0x71, 0x8b, + 0x00, 0x29, 0x06, 0xd1, 0x79, 0x7b, 0x09, 0x07, /// 0x2e70 + 0x03, 0xd5, 0x04, 0x21, 0xb3, 0x4a, 0xe1, 0x73, + 0x51, 0x71, 0x21, 0x7a, 0x8a, 0x07, 0x13, 0xd4, /// 0x2e80 + 0xca, 0x06, 0x11, 0xd5, 0x08, 0x07, 0x02, 0xd5, + 0x09, 0x98, 0xaf, 0x49, 0xc1, 0x82, 0x60, 0x46, /// 0x2e90 + 0x07, 0x21, 0x08, 0x43, 0x08, 0x99, 0x48, 0x76, + 0x32, 0x20, 0x28, 0x67, 0x0a, 0x98, 0x40, 0x68, /// 0x2ea0 + 0x28, 0x38, 0x68, 0x66, 0x0d, 0xb0, 0xf0, 0xbd, + 0xa4, 0x4a, 0x41, 0x1d, 0x20, 0x3a, 0x94, 0x46, /// 0x2eb0 + 0x0a, 0x29, 0x03, 0xd9, 0x08, 0x99, 0x49, 0x7e, + 0x09, 0x07, 0x0b, 0xd5, 0x00, 0x21, 0x91, 0x72, /// 0x2ec0 + 0x11, 0x7a, 0x00, 0x29, 0x03, 0xd0, 0x62, 0x46, + 0x49, 0x1e, 0x11, 0x72, 0x0a, 0xe0, 0x96, 0x21, /// 0x2ed0 + 0x29, 0x67, 0x07, 0xe0, 0x32, 0x21, 0x29, 0x67, + 0x91, 0x7a, 0xff, 0x29, 0x02, 0xd0, 0x62, 0x46, /// 0x2ee0 + 0x49, 0x1c, 0x91, 0x72, 0x0a, 0x99, 0x99, 0x4a, + 0x49, 0x68, 0x03, 0x91, 0x91, 0x42, 0x04, 0xd2, /// 0x2ef0 + 0x29, 0x6f, 0x96, 0x29, 0x01, 0xd1, 0x64, 0x21, + 0x29, 0x67, 0x21, 0x7a, 0x8f, 0x4a, 0x8e, 0x46, /// 0x2f00 + 0x09, 0x07, 0x20, 0x32, 0x00, 0x29, 0x13, 0xda, + 0x81, 0x1d, 0x0c, 0x29, 0x06, 0xd8, 0x71, 0x46, /// 0x2f10 + 0x89, 0x07, 0x09, 0xd5, 0x71, 0x46, 0x49, 0x08, + 0x49, 0x00, 0x08, 0xe0, 0x51, 0x7f, 0x03, 0x29, /// 0x2f20 + 0x06, 0xd9, 0x71, 0x46, 0x89, 0x07, 0x06, 0xd4, + 0x71, 0x46, 0xfb, 0x23, 0x19, 0x40, 0x21, 0x72, /// 0x2f30 + 0x21, 0x7a, 0x89, 0x07, 0x1a, 0xd5, 0x06, 0x28, + 0x18, 0xdd, 0x91, 0x7f, 0x09, 0x29, 0x06, 0xd9, /// 0x2f40 + 0xe5, 0x22, 0x83, 0x49, 0x92, 0x00, 0xca, 0x87, + 0x7f, 0x4a, 0xb8, 0x3a, 0x07, 0xe0, 0x06, 0x29, /// 0x2f50 + 0x07, 0xd1, 0x3d, 0x22, 0x7e, 0x49, 0x12, 0x01, + 0xca, 0x87, 0x7b, 0x4a, 0x6a, 0x3a, 0x07, 0x99, /// 0x2f60 + 0x0a, 0x82, 0x7b, 0x49, 0x7a, 0x4a, 0xc9, 0x8f, + 0x60, 0x32, 0xd1, 0x70, 0x03, 0x99, 0xaa, 0x6e, /// 0x2f70 + 0x8b, 0x1a, 0x09, 0x9a, 0x16, 0x21, 0x51, 0x5e, + 0xb4, 0x39, 0x8b, 0x42, 0x01, 0xdb, 0x01, 0x28, /// 0x2f80 + 0x01, 0xd0, 0x41, 0x1c, 0x00, 0xd1, 0x00, 0x20, + 0x07, 0x99, 0x3a, 0x88, 0x09, 0x8a, 0xff, 0x31, /// 0x2f90 + 0xd5, 0x31, 0x8a, 0x42, 0x1b, 0xd9, 0x61, 0x46, + 0x09, 0x7d, 0x0a, 0x29, 0x02, 0xd3, 0x03, 0x98, /// 0x2fa0 + 0xa8, 0x66, 0x7f, 0xe7, 0x62, 0x46, 0x49, 0x1c, + 0x11, 0x75, 0x60, 0x71, 0x00, 0x28, 0x05, 0xd0, /// 0x2fb0 + 0x08, 0x9a, 0x01, 0x21, 0x51, 0x77, 0x01, 0x1d, + 0x08, 0x29, 0x1d, 0xd8, 0x21, 0x79, 0x02, 0x22, /// 0x2fc0 + 0x11, 0x43, 0x21, 0x71, 0xca, 0x07, 0x05, 0xd0, + 0x04, 0x22, 0x11, 0x43, 0x04, 0xe0, 0x00, 0x21, /// 0x2fd0 + 0x62, 0x46, 0xe9, 0xe7, 0xfb, 0x22, 0x11, 0x40, + 0x21, 0x71, 0x49, 0x07, 0xe1, 0xd4, 0xc3, 0x21, /// 0x2fe0 + 0x89, 0x00, 0x29, 0x87, 0x55, 0x49, 0xc0, 0x39, + 0x88, 0x76, 0x01, 0x20, 0xfd, 0xf7, 0xf1, 0xff, /// 0x2ff0 + 0x70, 0x8b, 0x40, 0x1c, 0x70, 0x83, 0x55, 0xe7, + 0x21, 0x79, 0xfd, 0x22, 0x11, 0x40, 0x21, 0x71, /// 0x3000 + 0x4a, 0x07, 0xe7, 0xd4, 0xeb, 0xe7, 0x4d, 0x48, + 0x10, 0xb5, 0x0c, 0x21, 0xc0, 0x38, 0x01, 0x76, /// 0x3010 + 0x38, 0x21, 0x41, 0x76, 0x0a, 0x21, 0x81, 0x76, + 0x4d, 0x49, 0x40, 0x31, 0x09, 0x8f, 0xc1, 0x76, /// 0x3020 + 0x09, 0x0a, 0x01, 0x77, 0x45, 0x49, 0x10, 0x20, + 0x20, 0x39, 0xc8, 0x72, 0x03, 0x20, 0xfd, 0xf7, /// 0x3030 + 0xd0, 0xff, 0x10, 0xbd, 0x41, 0x48, 0x10, 0xb5, + 0x0c, 0x21, 0xc0, 0x38, 0x01, 0x76, 0x38, 0x21, /// 0x3040 + 0x41, 0x76, 0x3b, 0x21, 0x81, 0x76, 0x02, 0x21, + 0xc1, 0x76, 0xbb, 0x21, 0x01, 0x77, 0x3b, 0x49, /// 0x3050 + 0x10, 0x20, 0x20, 0x39, 0xc8, 0x72, 0x03, 0x20, + 0xfd, 0xf7, 0xbb, 0xff, 0x10, 0xbd, 0x37, 0x4a, /// 0x3060 + 0x10, 0xb5, 0x0c, 0x23, 0xc0, 0x3a, 0x13, 0x76, + 0xa4, 0x23, 0x53, 0x76, 0x90, 0x76, 0x33, 0x48, /// 0x3070 + 0x08, 0x22, 0xa5, 0x38, 0xfd, 0xf7, 0x45, 0xfd, + 0x30, 0x49, 0x10, 0x20, 0x20, 0x39, 0xc8, 0x72, /// 0x3080 + 0x0c, 0x20, 0xfd, 0xf7, 0xa6, 0xff, 0x10, 0xbd, + 0x10, 0xb5, 0x32, 0xa2, 0x07, 0xca, 0xa2, 0xb0, /// 0x3090 + 0x6b, 0x46, 0x07, 0xc3, 0x2e, 0x49, 0x08, 0x22, + 0x14, 0x31, 0x0c, 0x46, 0x1d, 0xa8, 0xfd, 0xf7, /// 0x30a0 + 0x30, 0xfd, 0x08, 0x22, 0x69, 0x46, 0x1f, 0xa8, + 0xfd, 0xf7, 0x2b, 0xfd, 0x03, 0xa8, 0xfe, 0xf7, /// 0x30b0 + 0xe3, 0xfa, 0x10, 0x22, 0x1d, 0xa9, 0x03, 0xa8, + 0xfe, 0xf7, 0x24, 0xfc, 0x24, 0x49, 0x03, 0xa8, /// 0x30c0 + 0xb0, 0x31, 0xfe, 0xf7, 0xf1, 0xfb, 0x21, 0x46, + 0x08, 0x20, 0xff, 0xf7, 0xc8, 0xff, 0x22, 0xb0, /// 0x30d0 + 0x10, 0xbd, 0x1f, 0x48, 0x10, 0xb5, 0x40, 0x30, + 0x00, 0x7c, 0xff, 0xf7, 0x07, 0xf9, 0x04, 0x46, /// 0x30e0 + 0x42, 0x1c, 0x1b, 0x49, 0x15, 0x48, 0x50, 0x31, + 0xa7, 0x38, 0xfd, 0xf7, 0x0a, 0xfd, 0x13, 0x48, /// 0x30f0 + 0x0c, 0x21, 0xc0, 0x38, 0x01, 0x76, 0x11, 0x49, + 0x10, 0x20, 0x20, 0x39, 0xc8, 0x72, 0x20, 0x46, /// 0x3100 + 0xfd, 0xf7, 0x67, 0xff, 0x10, 0xbd, 0xfe, 0xb5, + 0x11, 0x4c, 0x80, 0x34, 0x20, 0x7e, 0x25, 0x46, /// 0x3110 + 0x40, 0x1e, 0xc2, 0xb2, 0x09, 0x48, 0x22, 0x76, + 0x20, 0x38, 0x20, 0x35, 0x02, 0x90, 0x00, 0x2a, /// 0x3120 + 0x31, 0xd0, 0x0b, 0x49, 0x9c, 0x20, 0x40, 0x5a, + 0x40, 0x31, 0x00, 0x91, 0x08, 0x2a, 0x56, 0xd3, /// 0x3130 + 0x91, 0x07, 0x15, 0xe0, 0x00, 0x34, 0x00, 0x40, + 0xbe, 0x04, 0x00, 0x00, 0x90, 0x03, 0x00, 0x20, /// 0x3140 + 0x88, 0x13, 0x00, 0x00, 0x20, 0x38, 0x00, 0x40, + 0x6c, 0x07, 0x00, 0x00, 0x58, 0x1b, 0x00, 0x00, /// 0x3150 + 0x00, 0x00, 0x00, 0x20, 0x58, 0x69, 0x61, 0x6f, + 0x6d, 0x69, 0x52, 0x78, 0x00, 0x00, 0x00, 0x00, /// 0x3160 + 0x10, 0xd1, 0x00, 0x99, 0x63, 0x8b, 0x09, 0x88, + 0x59, 0x18, 0x89, 0xb2, 0x61, 0x83, 0x00, 0x9b, /// 0x3170 + 0x5b, 0x8f, 0xc0, 0x18, 0x80, 0xb2, 0xa0, 0x83, + 0x08, 0x2a, 0x03, 0xd1, 0x09, 0x09, 0x61, 0x83, /// 0x3180 + 0x00, 0x09, 0xa0, 0x83, 0xfe, 0xbd, 0x02, 0x7b, + 0xfa, 0x48, 0xfd, 0x21, 0x00, 0x7a, 0xd3, 0x07, /// 0x3190 + 0x01, 0x40, 0x00, 0x2b, 0x16, 0xd0, 0x02, 0x07, + 0xf4, 0xd5, 0xc2, 0x07, 0x01, 0xd0, 0x40, 0x21, /// 0x31a0 + 0x0d, 0xe0, 0x82, 0x07, 0x01, 0xd5, 0x29, 0x72, + 0xfe, 0xbd, 0x41, 0x07, 0x06, 0xd4, 0xf7, 0x21, /// 0x31b0 + 0x08, 0x40, 0x28, 0x72, 0xf1, 0x48, 0xf0, 0x49, + 0xc1, 0x82, 0xfe, 0xbd, 0x80, 0x21, 0x08, 0x43, /// 0x31c0 + 0x28, 0x72, 0xfe, 0xbd, 0x92, 0x07, 0xfc, 0xd5, + 0x02, 0x07, 0xfa, 0xd5, 0xc2, 0x07, 0xf8, 0xd1, /// 0x31d0 + 0x82, 0x07, 0xf6, 0xd5, 0x40, 0x06, 0xf4, 0xd5, + 0xbf, 0x20, 0x01, 0x40, 0xe3, 0xe7, 0x06, 0x2a, /// 0x31e0 + 0xef, 0xd8, 0xfd, 0xf7, 0x36, 0xfb, 0x06, 0x46, + 0x20, 0x78, 0xe4, 0x4f, 0xc0, 0x06, 0x40, 0x3f, /// 0x31f0 + 0x00, 0x28, 0x14, 0xda, 0x00, 0x98, 0x40, 0x8f, + 0xfd, 0xf7, 0x2b, 0xfb, 0x40, 0x09, 0x0a, 0xd0, /// 0x3200 + 0x20, 0x28, 0x01, 0xd3, 0x1f, 0x20, 0x06, 0xe0, + 0xb9, 0x7e, 0x81, 0x42, 0x01, 0xd2, 0x40, 0x1e, /// 0x3210 + 0x01, 0xe0, 0x81, 0x42, 0x00, 0xd9, 0xb8, 0x76, + 0xb8, 0x7e, 0xfd, 0xf7, 0xc0, 0xfc, 0xd8, 0x48, /// 0x3220 + 0x01, 0x88, 0xc9, 0x04, 0x0b, 0xd5, 0x40, 0x79, + 0x21, 0x78, 0xc0, 0x06, 0xc0, 0x0e, 0xc9, 0x06, /// 0x3230 + 0x03, 0xd5, 0xc1, 0x00, 0x08, 0x1a, 0x86, 0x19, + 0x01, 0xe0, 0xc1, 0x00, 0x0e, 0x1a, 0xcd, 0x49, /// 0x3240 + 0x60, 0x8b, 0x20, 0x31, 0x48, 0x85, 0x8e, 0x85, + 0x69, 0x22, 0x56, 0x43, 0x70, 0x43, 0x80, 0x0b, /// 0x3250 + 0xc8, 0x85, 0x00, 0x22, 0x62, 0x83, 0xa2, 0x83, + 0xca, 0x4a, 0x92, 0x8b, 0xd2, 0x07, 0x06, 0xd0, /// 0x3260 + 0xc9, 0x4a, 0x93, 0x88, 0xdb, 0x43, 0x9b, 0x07, + 0x03, 0xd0, 0x00, 0x22, 0x0a, 0xe0, 0x07, 0x22, /// 0x3270 + 0x08, 0xe0, 0xbb, 0x7e, 0x1a, 0x2b, 0x01, 0xd3, + 0x05, 0x22, 0x03, 0xe0, 0x12, 0x88, 0x12, 0x06, /// 0x3280 + 0x92, 0x0f, 0x52, 0x1c, 0xbb, 0x4f, 0xd6, 0xb2, + 0x62, 0x76, 0x73, 0x00, 0xa0, 0x3f, 0xda, 0x19, /// 0x3290 + 0x60, 0x32, 0x13, 0x7a, 0x43, 0x43, 0xdb, 0x09, + 0x07, 0x2e, 0x21, 0xd0, 0x09, 0x20, 0x10, 0x56, /// 0x32a0 + 0x0a, 0x22, 0x50, 0x43, 0xc0, 0x18, 0x00, 0xd5, + 0x00, 0x20, 0xb8, 0x4e, 0xb1, 0x4a, 0x33, 0x46, /// 0x32b0 + 0xa0, 0x3a, 0x90, 0x84, 0xff, 0x33, 0x22, 0x7a, + 0x81, 0x33, 0xff, 0x36, 0xa1, 0x36, 0x01, 0x93, /// 0x32c0 + 0x31, 0x2a, 0x11, 0xd0, 0x00, 0x21, 0x21, 0x76, + 0xaa, 0x49, 0xab, 0x4a, 0xa0, 0x39, 0x89, 0x8f, /// 0x32d0 + 0x87, 0x3a, 0x91, 0x42, 0x5d, 0xd8, 0xae, 0x49, + 0x88, 0x42, 0x5f, 0xd9, 0x08, 0x46, 0x5d, 0xe0, /// 0x32e0 + 0xa4, 0x48, 0x32, 0x38, 0x40, 0x7a, 0xdb, 0xe7, + 0x01, 0x22, 0x22, 0x76, 0x02, 0x9b, 0xda, 0x72, /// 0x32f0 + 0x2a, 0x7a, 0x13, 0x07, 0x10, 0xd5, 0xa1, 0x49, + 0x92, 0x07, 0x80, 0x31, 0x00, 0x2a, 0x05, 0xda, /// 0x3300 + 0x01, 0x22, 0x02, 0x92, 0x8a, 0x7f, 0x52, 0x1c, + 0x8a, 0x77, 0x16, 0xe0, 0x02, 0x22, 0x02, 0x92, /// 0x3310 + 0x4a, 0x7f, 0x52, 0x1c, 0x4a, 0x77, 0x10, 0xe0, + 0x00, 0x22, 0x02, 0x92, 0x0a, 0x79, 0x93, 0x07, /// 0x3320 + 0x0b, 0xd1, 0x00, 0x9b, 0x5b, 0x7b, 0x1b, 0x07, + 0x07, 0xd5, 0x06, 0x23, 0x1a, 0x43, 0x0a, 0x71, /// 0x3330 + 0x98, 0x4a, 0x52, 0x68, 0xa2, 0x64, 0x00, 0x22, + 0x4a, 0x71, 0x21, 0x78, 0x09, 0x06, 0x00, 0xd5, /// 0x3340 + 0x40, 0x08, 0xa1, 0x7a, 0x7d, 0x22, 0xd2, 0x00, + 0x51, 0x43, 0x00, 0x04, 0xfe, 0xf7, 0x3c, 0xfb, /// 0x3350 + 0x91, 0x49, 0x07, 0x46, 0x88, 0x42, 0x00, 0xd9, + 0x0f, 0x46, 0xe7, 0x84, 0x28, 0x79, 0xc0, 0x07, /// 0x3360 + 0x09, 0xd0, 0x84, 0x48, 0x01, 0x21, 0xa0, 0x38, + 0xc2, 0x6a, 0x49, 0x04, 0x0a, 0x43, 0xc2, 0x62, /// 0x3370 + 0x08, 0x46, 0xfd, 0xf7, 0xf1, 0xfb, 0x28, 0x79, + 0x40, 0x07, 0x00, 0xd5, 0x21, 0xe7, 0x01, 0x98, /// 0x3380 + 0x86, 0x49, 0x01, 0x87, 0x02, 0x98, 0xb0, 0x76, + 0x38, 0x0a, 0xf0, 0x76, 0x37, 0x77, 0x03, 0x20, /// 0x3390 + 0x0d, 0xe0, 0x83, 0x49, 0x88, 0x42, 0x00, 0xd9, + 0x08, 0x46, 0x40, 0x08, 0xc0, 0x01, 0x81, 0x49, /// 0x33a0 + 0xfe, 0xf7, 0x12, 0xfb, 0x01, 0x99, 0x80, 0x4a, + 0x0a, 0x87, 0xb0, 0x76, 0x01, 0x20, 0xfd, 0xf7, /// 0x33b0 + 0x10, 0xfe, 0xfe, 0xbd, 0xf8, 0xb5, 0x6f, 0x4a, + 0x7c, 0x49, 0x60, 0x3a, 0x10, 0x88, 0x48, 0x43, /// 0x33c0 + 0x7b, 0x49, 0x88, 0x42, 0x31, 0xd8, 0x6d, 0x4b, + 0x6e, 0x4c, 0x40, 0x3b, 0x59, 0x7e, 0xc8, 0x43, /// 0x33d0 + 0x85, 0x07, 0x78, 0x48, 0x11, 0xd1, 0x86, 0x8f, + 0xff, 0x27, 0x25, 0x37, 0x65, 0x14, 0xbe, 0x42, /// 0x33e0 + 0x08, 0xd9, 0xa1, 0x8a, 0x29, 0x43, 0xa1, 0x82, + 0x41, 0x6b, 0x80, 0x22, 0x11, 0x43, 0x41, 0x63, /// 0x33f0 + 0x10, 0x46, 0x5e, 0xe0, 0xa6, 0x8a, 0xae, 0x43, + 0xa6, 0x82, 0x49, 0x1e, 0xc9, 0xb2, 0x59, 0x76, /// 0x3400 + 0x8b, 0x07, 0x01, 0x25, 0x00, 0x2b, 0x11, 0xda, + 0x20, 0x8a, 0xd0, 0x84, 0x80, 0xb2, 0xcb, 0x28, /// 0x3410 + 0x01, 0xd9, 0xcb, 0x20, 0x20, 0x82, 0xa0, 0x8b, + 0x08, 0x21, 0x08, 0x43, 0xa0, 0x83, 0x64, 0x20, /// 0x3420 + 0xfd, 0xf7, 0x02, 0xfb, 0xa0, 0x8b, 0x28, 0x43, + 0xa0, 0x83, 0xf8, 0xbd, 0x61, 0x4b, 0xcf, 0x07, /// 0x3430 + 0x40, 0x33, 0xdb, 0x8c, 0x3f, 0x26, 0x01, 0x21, + 0x36, 0x02, 0x19, 0x43, 0x00, 0x2f, 0x12, 0xd0, /// 0x3440 + 0x5d, 0x4a, 0x93, 0x42, 0x00, 0xd9, 0x11, 0x46, + 0x21, 0x82, 0x21, 0x8b, 0x0f, 0x22, 0xb1, 0x43, /// 0x3450 + 0x12, 0x02, 0x89, 0x18, 0x21, 0x83, 0xc0, 0x8f, + 0xff, 0x21, 0xf5, 0x31, 0x88, 0x42, 0xe4, 0xd2, /// 0x3460 + 0x49, 0x48, 0x85, 0x80, 0xf8, 0xbd, 0x21, 0x82, + 0x21, 0x8b, 0x31, 0x43, 0x21, 0x83, 0xa1, 0x8b, /// 0x3470 + 0x01, 0x23, 0x5b, 0x02, 0x19, 0x43, 0xa1, 0x83, + 0x51, 0x7b, 0x0a, 0x07, 0x43, 0x49, 0x06, 0xd4, /// 0x3480 + 0x4e, 0x4a, 0x14, 0x78, 0x04, 0x23, 0x1c, 0x43, + 0x14, 0x70, 0x0b, 0x75, 0x06, 0xe0, 0x0a, 0x7d, /// 0x3490 + 0x00, 0x2a, 0x03, 0xd1, 0x3f, 0x4a, 0x52, 0x68, + 0x0a, 0x61, 0x0d, 0x75, 0x35, 0x49, 0x10, 0x23, /// 0x34a0 + 0x20, 0x39, 0x0a, 0x78, 0x1a, 0x43, 0x0a, 0x70, + 0xc1, 0x6a, 0x40, 0x22, 0x11, 0x43, 0xc1, 0x62, /// 0x34b0 + 0x10, 0x46, 0xfd, 0xf7, 0x51, 0xfb, 0xf8, 0xbd, + 0xf0, 0xb5, 0x30, 0x48, 0x8b, 0xb0, 0x40, 0x38, /// 0x34c0 + 0x40, 0x7e, 0x80, 0x07, 0x03, 0xd0, 0xff, 0xf7, + 0x75, 0xff, 0x0b, 0xb0, 0xf0, 0xbd, 0x29, 0x4c, /// 0x34d0 + 0x30, 0x49, 0x20, 0x34, 0x20, 0x79, 0x26, 0x46, + 0x82, 0x07, 0x40, 0x3e, 0x05, 0x91, 0x00, 0x2a, /// 0x34e0 + 0x19, 0xda, 0x49, 0x68, 0xb2, 0x6c, 0x89, 0x1a, + 0xff, 0x22, 0x2d, 0x32, 0x91, 0x42, 0x12, 0xd9, /// 0x34f0 + 0x61, 0x79, 0x03, 0x29, 0x01, 0xd2, 0x04, 0x21, + 0x0b, 0xe0, 0x2e, 0x49, 0x01, 0x20, 0xca, 0x6a, /// 0x3500 + 0x00, 0x03, 0x02, 0x43, 0xca, 0x62, 0xfd, 0xf7, + 0x27, 0xfb, 0x20, 0x79, 0xfd, 0x21, 0x08, 0x40, /// 0x3510 + 0x01, 0x21, 0x08, 0x43, 0x20, 0x71, 0x70, 0x78, + 0x41, 0x06, 0x12, 0xd5, 0x05, 0x99, 0xb2, 0x6c, /// 0x3520 + 0x49, 0x68, 0x89, 0x1a, 0xff, 0x22, 0xf5, 0x32, + 0x91, 0x42, 0x0a, 0xd9, 0xbf, 0x21, 0x08, 0x40, /// 0x3530 + 0x70, 0x70, 0x20, 0x49, 0xff, 0x20, 0xca, 0x6a, + 0x01, 0x30, 0x02, 0x43, 0xca, 0x62, 0xfd, 0xf7, /// 0x3540 + 0x0b, 0xfb, 0x30, 0x7e, 0x00, 0x28, 0x02, 0xd0, + 0xff, 0xf7, 0xdd, 0xfd, 0xbd, 0xe7, 0x05, 0x98, /// 0x3550 + 0x0a, 0x4d, 0x40, 0x68, 0x80, 0x3d, 0x00, 0x90, + 0xa9, 0x6e, 0x16, 0x22, 0x41, 0x1a, 0x07, 0x48, /// 0x3560 + 0x08, 0x90, 0x82, 0x5e, 0x00, 0x98, 0x91, 0x42, + 0x2a, 0xdb, 0xa8, 0x66, 0x48, 0x20, 0x30, 0x76, /// 0x3570 + 0xea, 0xe7, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x20, + 0xdc, 0x05, 0x00, 0x00, 0x30, 0x03, 0x00, 0x20, /// 0x3580 + 0x20, 0x38, 0x00, 0x40, 0x00, 0x30, 0x00, 0x40, + 0x00, 0x34, 0x00, 0x40, 0x30, 0x01, 0x00, 0x20, /// 0x3590 + 0xe8, 0x26, 0x00, 0x00, 0x30, 0x02, 0x00, 0x20, + 0xff, 0xff, 0x00, 0x00, 0x0c, 0x31, 0x00, 0x00, /// 0x35a0 + 0xd0, 0x4d, 0x00, 0x00, 0x88, 0x13, 0x00, 0x00, + 0x0c, 0x04, 0x00, 0x00, 0x41, 0x0a, 0x00, 0x00, /// 0x35b0 + 0xff, 0x8f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x20, + 0xe3, 0x02, 0x00, 0x00, 0x40, 0x6c, 0x00, 0x40, /// 0x35c0 + 0x69, 0x6e, 0x42, 0x1a, 0x29, 0x6f, 0xf7, 0x48, + 0x04, 0x90, 0x8a, 0x42, 0x72, 0xdb, 0x00, 0x98, /// 0x35d0 + 0x68, 0x66, 0x70, 0x78, 0x01, 0x07, 0x0b, 0xd5, + 0xf7, 0x21, 0x08, 0x40, 0x32, 0x21, 0x29, 0x67, /// 0x35e0 + 0x10, 0x21, 0x08, 0x43, 0x70, 0x70, 0x00, 0x20, + 0xa0, 0x81, 0xff, 0xf7, 0x72, 0xfd, 0x6c, 0xe7, /// 0x35f0 + 0x23, 0x79, 0xdf, 0x22, 0x19, 0x07, 0x00, 0x29, + 0x0e, 0xda, 0xb1, 0x78, 0x8f, 0x06, 0x0b, 0xd5, /// 0x3600 + 0x11, 0x40, 0xb1, 0x70, 0x32, 0x21, 0x29, 0x67, + 0x40, 0x21, 0x08, 0x43, 0x70, 0x70, 0x00, 0x98, /// 0x3610 + 0xb0, 0x64, 0xff, 0xf7, 0x39, 0xfd, 0x58, 0xe7, + 0x81, 0x06, 0x07, 0xd5, 0x10, 0x40, 0x70, 0x70, /// 0x3620 + 0x32, 0x20, 0x28, 0x67, 0xff, 0x20, 0xfe, 0xf7, + 0xa9, 0xf9, 0x4e, 0xe7, 0x58, 0x07, 0x0d, 0xd5, /// 0x3630 + 0xfb, 0x20, 0x03, 0x40, 0x23, 0x71, 0x32, 0x20, + 0x28, 0x67, 0xff, 0xf7, 0xfb, 0xfc, 0x05, 0x98, /// 0x3640 + 0x40, 0x68, 0xb0, 0x64, 0x60, 0x79, 0x40, 0x1c, + 0x60, 0x71, 0x3e, 0xe7, 0x18, 0x07, 0x32, 0xd5, /// 0x3650 + 0xb0, 0x78, 0x07, 0x90, 0xc0, 0x07, 0x2e, 0xd0, + 0xd3, 0x48, 0x15, 0x21, 0xc0, 0x8f, 0x48, 0x43, /// 0x3660 + 0xfa, 0x21, 0xfe, 0xf7, 0xb1, 0xf9, 0x07, 0x46, + 0xcf, 0x48, 0x64, 0x21, 0x40, 0x30, 0x09, 0x90, /// 0x3670 + 0x00, 0x8f, 0xfe, 0xf7, 0xa9, 0xf9, 0x07, 0x99, + 0x38, 0x1a, 0x49, 0x08, 0x49, 0x00, 0x1c, 0x30, /// 0x3680 + 0xb1, 0x70, 0x00, 0x28, 0x00, 0xdc, 0x40, 0x42, + 0x14, 0x28, 0x33, 0xdb, 0x32, 0x20, 0x28, 0x67, /// 0x3690 + 0x09, 0x98, 0x02, 0x88, 0xc3, 0x48, 0x40, 0x30, + 0xc2, 0x81, 0x02, 0x22, 0x11, 0x43, 0xb1, 0x70, /// 0x36a0 + 0x00, 0x99, 0x01, 0x61, 0xc0, 0x48, 0xa0, 0x30, + 0x00, 0x79, 0x40, 0x07, 0x9f, 0xd4, 0xff, 0xf7, /// 0x36b0 + 0xaa, 0xfc, 0x0a, 0xe7, 0x1e, 0xe0, 0xbc, 0x48, + 0x00, 0x8f, 0x00, 0x28, 0x0c, 0xd0, 0x04, 0x98, /// 0x36c0 + 0x40, 0x7a, 0x07, 0x28, 0x08, 0xd2, 0x04, 0x98, + 0x80, 0x7a, 0x0a, 0x28, 0x16, 0xd2, 0xff, 0xf7, /// 0x36d0 + 0x1d, 0xfa, 0xc0, 0x1d, 0x0e, 0x28, 0x0d, 0xd9, + 0x04, 0x99, 0x00, 0x20, 0x48, 0x72, 0x08, 0x7a, /// 0x36e0 + 0x00, 0x28, 0x01, 0xd0, 0x40, 0x1e, 0x08, 0x72, + 0x05, 0x98, 0x40, 0x68, 0x68, 0x66, 0xff, 0xf7, /// 0x36f0 + 0x82, 0xfa, 0xea, 0xe6, 0xac, 0x48, 0x00, 0x8f, + 0x00, 0x28, 0x8c, 0xd0, 0x04, 0x98, 0x04, 0x99, /// 0x3700 + 0x40, 0x7a, 0x08, 0x23, 0x40, 0x1c, 0x48, 0x72, + 0xa7, 0x49, 0x80, 0x26, 0x08, 0x8f, 0x0a, 0x46, /// 0x3710 + 0x87, 0x06, 0x20, 0x32, 0x00, 0x2f, 0x3a, 0xd0, + 0xc7, 0x07, 0x05, 0xd0, 0x01, 0x20, 0xa0, 0x82, /// 0x3720 + 0x04, 0x99, 0xc8, 0x72, 0x03, 0x20, 0x47, 0xe0, + 0x87, 0x07, 0x06, 0xd5, 0x02, 0x20, 0xa0, 0x82, /// 0x3730 + 0x04, 0x99, 0x01, 0x20, 0xc8, 0x72, 0x05, 0x20, + 0x3e, 0xe0, 0x47, 0x07, 0x04, 0xd5, 0x04, 0x22, /// 0x3740 + 0x90, 0x43, 0x08, 0x87, 0x02, 0x20, 0x37, 0xe0, + 0x07, 0x07, 0x03, 0xd5, 0x98, 0x43, 0x08, 0x87, /// 0x3750 + 0x01, 0x20, 0x31, 0xe0, 0xc7, 0x06, 0x0e, 0xd5, + 0x92, 0x79, 0x52, 0x06, 0x05, 0xd5, 0x10, 0x20, /// 0x3760 + 0xa0, 0x82, 0x04, 0x99, 0x01, 0x20, 0xc8, 0x72, + 0x02, 0xe0, 0x10, 0x22, 0x90, 0x43, 0x08, 0x87, /// 0x3770 + 0xff, 0xf7, 0xb6, 0xf9, 0xa9, 0xe6, 0x87, 0x06, + 0x09, 0xd5, 0x20, 0x20, 0xa0, 0x82, 0x04, 0x99, /// 0x3780 + 0x01, 0x20, 0xc8, 0x72, 0xa0, 0x7d, 0x40, 0x1e, + 0x30, 0x43, 0xc0, 0xb2, 0x14, 0xe0, 0xc0, 0x24, /// 0x3790 + 0x04, 0x40, 0x1b, 0xd0, 0xc0, 0x2c, 0x05, 0xd1, + 0xd3, 0x79, 0x5b, 0x07, 0x01, 0xd5, 0x40, 0x24, /// 0x37a0 + 0x00, 0xe0, 0x80, 0x24, 0x63, 0x06, 0x0a, 0xd5, + 0x40, 0x23, 0x98, 0x43, 0x08, 0x87, 0xd0, 0x79, /// 0x37b0 + 0xfb, 0x21, 0x08, 0x40, 0xd0, 0x71, 0x06, 0x20, + 0xff, 0xf7, 0x86, 0xf9, 0x85, 0xe6, 0xd0, 0x79, /// 0x37c0 + 0x04, 0x21, 0x08, 0x43, 0xd0, 0x71, 0xff, 0xf7, + 0x69, 0xf9, 0x7e, 0xe6, 0xc2, 0x05, 0x06, 0xd5, /// 0x37d0 + 0xff, 0x22, 0x01, 0x32, 0x90, 0x43, 0x08, 0x87, + 0xff, 0xf7, 0x51, 0xf9, 0x75, 0xe6, 0x82, 0x05, /// 0x37e0 + 0x87, 0xd5, 0x05, 0x9a, 0x6c, 0x6e, 0x52, 0x68, + 0x14, 0x1b, 0x64, 0x2c, 0xc2, 0xda, 0xac, 0x6e, /// 0x37f0 + 0x16, 0x25, 0xa4, 0x1a, 0x08, 0x9a, 0x55, 0x5f, + 0x62, 0x19, 0xff, 0x24, 0x5f, 0x34, 0xa2, 0x42, /// 0x3800 + 0xb8, 0xdd, 0x01, 0x22, 0x52, 0x02, 0x90, 0x43, + 0x08, 0x87, 0x68, 0x48, 0x83, 0x73, 0xff, 0xf7, /// 0x3810 + 0x2a, 0xf9, 0x5a, 0xe6, 0x65, 0x48, 0x10, 0xb5, + 0x65, 0x49, 0x40, 0x30, 0x81, 0x63, 0x62, 0x48, /// 0x3820 + 0x80, 0x30, 0xc1, 0x78, 0x61, 0x48, 0x60, 0x30, + 0xc1, 0x76, 0x5e, 0x49, 0x01, 0x20, 0xc8, 0x72, /// 0x3830 + 0x02, 0x20, 0xfd, 0xf7, 0xce, 0xfb, 0x10, 0xbd, + 0xf0, 0xb5, 0x09, 0x22, 0x5d, 0x49, 0x59, 0x4c, /// 0x3840 + 0x92, 0x01, 0x8a, 0x18, 0x80, 0x3c, 0x15, 0x7b, + 0x20, 0x7f, 0x13, 0x22, 0x52, 0x01, 0xc3, 0x07, /// 0x3850 + 0x8a, 0x18, 0x8d, 0xb0, 0x00, 0x2b, 0x0e, 0xd0, + 0x00, 0x2d, 0x0c, 0xd1, 0xd1, 0x7c, 0x49, 0x1c, /// 0x3860 + 0xc9, 0xb2, 0xd1, 0x74, 0x03, 0x29, 0x02, 0xd2, + 0x40, 0x1e, 0x20, 0x77, 0x03, 0xe0, 0x40, 0x1c, /// 0x3870 + 0x20, 0x77, 0x00, 0x20, 0xd0, 0x74, 0x11, 0x20, + 0x4e, 0x4e, 0x40, 0x01, 0x30, 0x18, 0x27, 0x7f, /// 0x3880 + 0x09, 0x90, 0x00, 0x78, 0x0c, 0x90, 0x09, 0x98, + 0xff, 0x36, 0x40, 0x78, 0x06, 0x90, 0x46, 0x48, /// 0x3890 + 0xff, 0x36, 0x01, 0x46, 0xa0, 0x31, 0x80, 0x30, + 0x07, 0x91, 0xc1, 0x7b, 0x03, 0x91, 0x81, 0x7b, /// 0x38a0 + 0x04, 0x91, 0x41, 0x7b, 0x03, 0x7b, 0x05, 0x93, + 0x02, 0x36, 0x3b, 0x00, 0xfe, 0xf7, 0xb6, 0xf8, /// 0x38b0 + 0x11, 0x0a, 0x0d, 0x13, 0x15, 0x1f, 0x23, 0x38, + 0x40, 0x45, 0x4c, 0x62, 0x6a, 0x6f, 0x84, 0x89, /// 0x38c0 + 0x8e, 0xb3, 0xb5, 0x00, 0xff, 0xf7, 0xa6, 0xff, + 0xa7, 0xe0, 0xa8, 0x07, 0x00, 0xd5, 0xfe, 0xe7, /// 0x38d0 + 0x00, 0x20, 0xd0, 0x74, 0xa1, 0xe0, 0x30, 0x20, + 0x0a, 0xe0, 0x0c, 0x99, 0x30, 0x29, 0xf7, 0xd1, /// 0x38e0 + 0x07, 0x9b, 0x06, 0x99, 0x59, 0x72, 0x71, 0x8c, + 0x49, 0xba, 0x41, 0x84, 0xf0, 0xe7, 0x31, 0x20, /// 0x38f0 + 0xff, 0xf7, 0x37, 0xf8, 0x91, 0xe0, 0x0c, 0x9b, + 0x31, 0x2b, 0xe9, 0xd1, 0x06, 0x9d, 0x05, 0x71, /// 0x3900 + 0x09, 0x9b, 0x8d, 0x42, 0x9b, 0x78, 0x43, 0x71, + 0x09, 0x9e, 0xf6, 0x78, 0x86, 0x71, 0x02, 0xd2, /// 0x3910 + 0x8b, 0x42, 0x00, 0xd2, 0x43, 0x73, 0x04, 0x99, + 0x8b, 0x42, 0xd9, 0xd2, 0x83, 0x73, 0xd7, 0xe7, /// 0x3920 + 0x00, 0x7a, 0x05, 0x99, 0x81, 0x42, 0x01, 0xd0, + 0x02, 0x20, 0x35, 0xe0, 0x07, 0x20, 0x37, 0xe0, /// 0x3930 + 0xe8, 0x07, 0xcd, 0xd0, 0x05, 0x98, 0x10, 0x75, + 0xca, 0xe7, 0x40, 0x7a, 0x81, 0x42, 0x01, 0xd0, /// 0x3940 + 0x01, 0x20, 0x29, 0xe0, 0x09, 0x20, 0x2b, 0xe0, + 0x17, 0x4b, 0xed, 0x07, 0x80, 0x33, 0x1b, 0x79, /// 0x3950 + 0x00, 0x2d, 0x09, 0xd0, 0x51, 0x75, 0x8b, 0x42, + 0x00, 0xd2, 0x01, 0x71, 0x41, 0x8c, 0x27, 0x29, /// 0x3960 + 0xb6, 0xd1, 0x04, 0x21, 0x01, 0x71, 0xb3, 0xe7, + 0x99, 0x42, 0xb1, 0xd9, 0x43, 0x73, 0x08, 0x20, /// 0x3970 + 0x20, 0x77, 0xad, 0xe7, 0x80, 0x7a, 0x04, 0x99, + 0x81, 0x42, 0x01, 0xd0, 0x04, 0x20, 0x0b, 0xe0, /// 0x3980 + 0x0b, 0x20, 0x0d, 0xe0, 0xe8, 0x07, 0xa3, 0xd0, + 0x04, 0x98, 0x90, 0x75, 0xa0, 0xe7, 0xc0, 0x7a, /// 0x3990 + 0x03, 0x99, 0x81, 0x42, 0x03, 0xd0, 0x03, 0x20, + 0xfe, 0xf7, 0xd3, 0xff, 0x3d, 0xe0, 0x0d, 0x20, /// 0x39a0 + 0x20, 0x77, 0x3a, 0xe0, 0x70, 0x03, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x20, 0x70, 0x02, 0x00, 0x20, /// 0x39b0 + 0x0c, 0x22, 0x00, 0x00, 0x30, 0x01, 0x00, 0x20, + 0xe8, 0x07, 0x89, 0xd0, 0x03, 0x98, 0xd0, 0x75, /// 0x39c0 + 0x86, 0xe7, 0xfe, 0xf7, 0xac, 0xff, 0xc1, 0xb2, + 0x00, 0x20, 0xe5, 0xe7, 0xe9, 0x07, 0x1b, 0xd0, /// 0x39d0 + 0x71, 0x6f, 0x81, 0x60, 0xff, 0x20, 0xb7, 0x30, + 0xf0, 0x82, 0x6c, 0x48, 0x41, 0x68, 0x80, 0x30, /// 0x39e0 + 0x0a, 0x46, 0xcd, 0x3a, 0x82, 0x66, 0xc1, 0x66, + 0x02, 0x6f, 0x89, 0x1a, 0x41, 0x66, 0x67, 0x49, /// 0x39f0 + 0x07, 0x20, 0x40, 0x31, 0x88, 0x73, 0x07, 0x99, + 0x0f, 0x20, 0x08, 0x72, 0x64, 0x48, 0x01, 0x78, /// 0x3a00 + 0x04, 0x22, 0x11, 0x43, 0x01, 0x70, 0x08, 0xe0, + 0xa9, 0x07, 0x06, 0xd5, 0x80, 0x68, 0x70, 0x67, /// 0x3a10 + 0x00, 0x20, 0xd0, 0x74, 0x03, 0xe0, 0xfe, 0xf7, + 0xd6, 0xf8, 0x20, 0x7f, 0x40, 0x1c, 0x20, 0x77, /// 0x3a20 + 0x0d, 0xb0, 0xf0, 0xbd, 0xf8, 0xb5, 0x5b, 0x4c, + 0xa0, 0x78, 0x84, 0x46, 0x80, 0x07, 0x58, 0xd5, /// 0x3a30 + 0x20, 0x46, 0x59, 0x4e, 0x40, 0x38, 0x01, 0x88, + 0xf2, 0x89, 0x89, 0x1a, 0x00, 0x29, 0x00, 0xdc, /// 0x3a40 + 0x49, 0x42, 0x54, 0x4a, 0x40, 0x32, 0x15, 0x46, + 0xd3, 0x89, 0xc0, 0x3d, 0xef, 0x6a, 0x99, 0x42, /// 0x3a50 + 0x25, 0xdd, 0x61, 0x46, 0xfd, 0x22, 0x11, 0x40, + 0xa1, 0x70, 0x01, 0x8f, 0xaf, 0x20, 0x00, 0x01, /// 0x3a60 + 0x08, 0x1a, 0x0a, 0x21, 0x48, 0x43, 0x54, 0x21, + 0xfd, 0xf7, 0xc4, 0xff, 0x29, 0x46, 0xe8, 0x87, /// 0x3a70 + 0x60, 0x31, 0xc8, 0x70, 0x01, 0x21, 0x08, 0x43, + 0x48, 0x49, 0x08, 0x82, 0x08, 0x20, 0x07, 0x43, /// 0x3a80 + 0xef, 0x62, 0xfd, 0xf7, 0x69, 0xf8, 0xe9, 0x8f, + 0x45, 0x48, 0x81, 0x42, 0x20, 0x78, 0x02, 0xd1, /// 0x3a90 + 0x80, 0x21, 0x08, 0x43, 0x01, 0xe0, 0x40, 0x06, + 0x40, 0x0e, 0x20, 0x70, 0x21, 0xe0, 0x3b, 0x49, /// 0x3aa0 + 0x4b, 0x68, 0x31, 0x69, 0x9c, 0x46, 0x59, 0x1a, + 0x3d, 0x4b, 0x30, 0x33, 0x99, 0x42, 0x18, 0xdd, /// 0x3ab0 + 0x71, 0x7b, 0x52, 0x7f, 0x91, 0x42, 0x08, 0xd2, + 0xc2, 0x89, 0x80, 0x23, 0x1a, 0x43, 0xc2, 0x81, /// 0x3ac0 + 0x60, 0x46, 0x49, 0x1c, 0x30, 0x61, 0x71, 0x73, + 0x0b, 0xe0, 0x01, 0x20, 0xc0, 0x03, 0x07, 0x43, /// 0x3ad0 + 0xef, 0x62, 0xfd, 0xf7, 0x41, 0xf8, 0xa0, 0x78, + 0xfd, 0x21, 0x08, 0x40, 0xa0, 0x70, 0x00, 0x20, /// 0x3ae0 + 0x70, 0x73, 0x00, 0x20, 0xf8, 0xbd, 0x70, 0xb5, + 0x2a, 0x49, 0x9f, 0x23, 0x4a, 0x78, 0x1a, 0x40, /// 0x3af0 + 0x4a, 0x70, 0x0b, 0x46, 0x20, 0x33, 0x1c, 0x7c, + 0x05, 0x78, 0x80, 0x39, 0xca, 0x6a, 0xac, 0x42, /// 0x3b00 + 0x0e, 0xd1, 0x5c, 0x7c, 0x45, 0x78, 0xac, 0x42, + 0x0a, 0xd1, 0x9c, 0x7c, 0x85, 0x78, 0xac, 0x42, /// 0x3b10 + 0x06, 0xd1, 0xdb, 0x7c, 0xc0, 0x78, 0x83, 0x42, + 0x02, 0xd1, 0x01, 0x20, 0x40, 0x02, 0x01, 0xe0, /// 0x3b20 + 0xff, 0x20, 0x01, 0x30, 0x02, 0x43, 0xca, 0x62, + 0xfd, 0xf7, 0x16, 0xf8, 0x70, 0xbd, 0x70, 0xb5, /// 0x3b30 + 0x18, 0x4c, 0xdf, 0x21, 0x60, 0x78, 0x23, 0x46, + 0x08, 0x40, 0x60, 0x70, 0x40, 0x3b, 0x58, 0x7e, /// 0x3b40 + 0x3b, 0x28, 0x16, 0xd1, 0x1d, 0x46, 0x80, 0x35, + 0x28, 0x79, 0xfd, 0x21, 0x08, 0x40, 0x01, 0x21, /// 0x3b50 + 0x08, 0x43, 0x28, 0x71, 0x19, 0x46, 0x9e, 0x7e, + 0x40, 0x39, 0xca, 0x6a, 0x02, 0x2e, 0x02, 0xd1, /// 0x3b60 + 0xdb, 0x7e, 0xbb, 0x2b, 0x06, 0xd0, 0x01, 0x20, + 0x00, 0x03, 0x02, 0x43, 0xca, 0x62, 0xfc, 0xf7, /// 0x3b70 + 0xf3, 0xff, 0x70, 0xbd, 0x08, 0x23, 0x18, 0x43, + 0x28, 0x71, 0x98, 0x02, 0x02, 0x43, 0xca, 0x62, /// 0x3b80 + 0xfc, 0xf7, 0xea, 0xff, 0x09, 0x20, 0xe0, 0x82, + 0x70, 0xbd, 0x00, 0x00, 0x30, 0x02, 0x00, 0x20, /// 0x3b90 + 0x40, 0x6c, 0x00, 0x40, 0x80, 0x00, 0x00, 0x20, + 0xb0, 0x03, 0x00, 0x20, 0x00, 0x30, 0x00, 0x40, /// 0x3ba0 + 0xac, 0x05, 0x00, 0x00, 0x9a, 0x34, 0x9a, 0x34, + 0x8c, 0x26, 0x8c, 0x26, 0x9b, 0xef, 0x9b, 0xef, /// 0x3bb0 + 0x14, 0x14, 0x00, 0x00, 0x8b, 0x74, 0x8b, 0x74, + 0x8c, 0x4c, 0x8c, 0x4c, 0x8c, 0x48, 0x8c, 0x48, /// 0x3bc0 + 0x14, 0x00, 0x80, 0x45, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /// 0x3bd0 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb5, 0x72, 0xb6, /// 0x3be0 + 0x72, 0x48, 0x89, 0xb0, 0x70, 0x49, 0x81, 0x60, + 0x71, 0x49, 0xc1, 0x67, 0x71, 0x49, 0x80, 0x30, /// 0x3bf0 + 0x01, 0x60, 0x71, 0x49, 0x74, 0x4f, 0x41, 0x60, + 0x71, 0x49, 0x70, 0x48, 0x3d, 0x46, 0x88, 0x61, /// 0x3c00 + 0x80, 0x35, 0x70, 0x4e, 0x71, 0x48, 0xfe, 0x61, + 0x28, 0x82, 0x04, 0x20, 0x2c, 0x46, 0x38, 0x84, /// 0x3c10 + 0x40, 0x3c, 0x60, 0x73, 0x62, 0xb6, 0x65, 0x48, + 0xb9, 0x78, 0x20, 0x38, 0x05, 0x29, 0x01, 0xd3, /// 0x3c20 + 0x02, 0x21, 0x00, 0xe0, 0x06, 0x21, 0x01, 0x76, + 0x01, 0xf0, 0xa7, 0xfa, 0x01, 0xf0, 0x98, 0xfa, /// 0x3c30 + 0x67, 0x48, 0xc3, 0x21, 0x00, 0x60, 0x40, 0x60, + 0x63, 0x48, 0x29, 0x22, 0x41, 0x63, 0x62, 0x49, /// 0x3c40 + 0x00, 0x20, 0xc8, 0x62, 0x63, 0x49, 0xff, 0x27, + 0x4e, 0x60, 0x5f, 0x49, 0xf5, 0x37, 0xce, 0x61, /// 0x3c50 + 0xff, 0x21, 0x9d, 0x31, 0xa1, 0x84, 0xe1, 0x84, + 0x21, 0x85, 0x5b, 0x49, 0xaf, 0x23, 0x60, 0x31, /// 0x3c60 + 0x07, 0x91, 0x4a, 0x76, 0x67, 0x85, 0x5c, 0x49, + 0xa1, 0x85, 0xf9, 0x00, 0x21, 0x84, 0x07, 0x99, /// 0x3c70 + 0x02, 0x22, 0x0a, 0x76, 0xa0, 0x87, 0xb9, 0x00, + 0xe1, 0x87, 0x55, 0x49, 0x08, 0x22, 0x78, 0x39, /// 0x3c80 + 0x0a, 0x71, 0xff, 0x22, 0x4a, 0x71, 0x49, 0x49, + 0xe0, 0x86, 0x9b, 0x00, 0xc0, 0x39, 0xff, 0x26, /// 0x3c90 + 0x4b, 0x80, 0x91, 0x36, 0x6e, 0x82, 0xae, 0x82, + 0x18, 0x26, 0xae, 0x76, 0xee, 0x76, 0x19, 0x26, /// 0x3ca0 + 0x76, 0x01, 0xee, 0x82, 0x05, 0x26, 0xae, 0x77, + 0x47, 0x4e, 0x73, 0x81, 0x33, 0x46, 0x9f, 0x81, /// 0x3cb0 + 0x37, 0x46, 0x11, 0x23, 0xe0, 0x37, 0xbb, 0x77, + 0x4c, 0x23, 0xfb, 0x77, 0x01, 0x26, 0xfe, 0x71, /// 0x3cc0 + 0x3e, 0x46, 0xc0, 0x3e, 0xb2, 0x76, 0x0a, 0x46, + 0x0a, 0x26, 0x40, 0x3a, 0x96, 0x70, 0x3e, 0x46, /// 0x3cd0 + 0x52, 0x8e, 0x20, 0x3e, 0x32, 0x82, 0x0a, 0x46, + 0x40, 0x3a, 0x92, 0x8e, 0x72, 0x82, 0x0a, 0x46, /// 0x3ce0 + 0x20, 0x3a, 0xd3, 0x77, 0x08, 0x71, 0x01, 0x23, + 0x4b, 0x71, 0xcb, 0x80, 0x09, 0x21, 0x91, 0x75, /// 0x3cf0 + 0x02, 0x21, 0x20, 0x3a, 0x11, 0x87, 0x39, 0x49, + 0x8f, 0x22, 0x4a, 0x87, 0x7b, 0x72, 0xe0, 0x85, /// 0x3d00 + 0x37, 0x49, 0x2a, 0x48, 0x0a, 0x8a, 0x37, 0x4b, + 0x40, 0x38, 0x06, 0x90, 0x9a, 0x42, 0x23, 0xd0, /// 0x3d10 + 0x08, 0x46, 0x0e, 0x21, 0x41, 0x5e, 0x08, 0x03, + 0x33, 0x49, 0xfd, 0xf7, 0x6b, 0xfe, 0x06, 0x99, /// 0x3d20 + 0x80, 0xb2, 0x48, 0x83, 0x00, 0x90, 0x2e, 0x48, + 0x10, 0x21, 0x41, 0x5e, 0x08, 0x03, 0x2e, 0x49, /// 0x3d30 + 0xfd, 0xf7, 0x60, 0xfe, 0x81, 0xb2, 0x06, 0x98, + 0x81, 0x83, 0x00, 0x98, 0x09, 0x1a, 0x7d, 0x20, /// 0x3d40 + 0x40, 0x03, 0xfd, 0xf7, 0x57, 0xfe, 0x01, 0xb2, + 0x71, 0x87, 0x00, 0x98, 0x41, 0x43, 0xc8, 0x12, /// 0x3d50 + 0xff, 0x21, 0x2d, 0x31, 0x08, 0x1a, 0x04, 0xe0, + 0x01, 0x20, 0xc0, 0x02, 0x70, 0x87, 0xe1, 0x20, /// 0x3d60 + 0x80, 0x00, 0x1b, 0x49, 0xb0, 0x87, 0x78, 0x39, + 0x08, 0x7b, 0xf7, 0x22, 0x40, 0x08, 0x40, 0x00, /// 0x3d70 + 0x10, 0x40, 0x08, 0x73, 0x00, 0x20, 0x08, 0x72, + 0x48, 0x73, 0x88, 0x73, 0x01, 0x22, 0xca, 0x76, /// 0x3d80 + 0x20, 0x73, 0xe0, 0x81, 0x28, 0x70, 0x07, 0x99, + 0xef, 0x22, 0xc9, 0x7e, 0x0e, 0x4c, 0x11, 0x40, /// 0x3d90 + 0x07, 0x9a, 0xd1, 0x76, 0x06, 0x99, 0x08, 0x83, + 0xf8, 0x74, 0x80, 0x20, 0xfc, 0xf7, 0xdc, 0xfe, /// 0x3da0 + 0x20, 0x6b, 0xe0, 0x62, 0x09, 0xb0, 0xf0, 0xbd, + 0x05, 0x53, 0x00, 0x00, 0x30, 0x02, 0x00, 0x20, /// 0x3db0 + 0x55, 0x4f, 0x00, 0x00, 0x25, 0x52, 0x00, 0x00, + 0x21, 0x40, 0x00, 0x00, 0xd5, 0x54, 0x00, 0x00, /// 0x3dc0 + 0x00, 0x01, 0x00, 0x20, 0x0c, 0x00, 0x08, 0x02, + 0x00, 0x00, 0x00, 0x20, 0xdc, 0x05, 0x00, 0x00, /// 0x3dd0 + 0xe8, 0x04, 0x00, 0x20, 0x40, 0x04, 0x00, 0x20, + 0xf8, 0x2a, 0x00, 0x00, 0x30, 0x01, 0x00, 0x20, /// 0x3de0 + 0x60, 0x67, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x34, 0x08, 0x00, 0x00, 0x70, 0xb5, 0x03, 0x46, /// 0x3df0 + 0xfe, 0x4a, 0x00, 0x20, 0x14, 0x24, 0x44, 0x43, + 0xa4, 0x18, 0x50, 0x34, 0x25, 0x78, 0x00, 0x2d, /// 0x3e00 + 0x03, 0xd0, 0x40, 0x1c, 0x02, 0x28, 0xf5, 0xdb, + 0x70, 0xbd, 0x0a, 0x46, 0x19, 0x46, 0x20, 0x46, /// 0x3e10 + 0xfc, 0xf7, 0x77, 0xfe, 0xf5, 0x48, 0x0c, 0x34, + 0xc1, 0x6f, 0xc4, 0x67, 0x78, 0x30, 0x03, 0xc4, /// 0x3e20 + 0x08, 0x3c, 0x0c, 0x60, 0x70, 0xbd, 0xf8, 0xb5, + 0x15, 0x46, 0x2c, 0x22, 0x50, 0x43, 0xf0, 0x4a, /// 0x3e30 + 0x87, 0x18, 0x14, 0x20, 0x41, 0x43, 0x7c, 0x18, + 0x20, 0x7a, 0x0a, 0x28, 0x6e, 0xd2, 0x20, 0x7a, /// 0x3e40 + 0x00, 0x28, 0x09, 0xd1, 0x28, 0x46, 0xfe, 0xf7, + 0x51, 0xfa, 0x80, 0x1c, 0xc0, 0xb2, 0x00, 0x2d, /// 0x3e50 + 0x64, 0xd0, 0x0c, 0x28, 0x62, 0xd8, 0xa0, 0x72, + 0x20, 0x7a, 0x21, 0x18, 0x40, 0x1c, 0x20, 0x72, /// 0x3e60 + 0x8d, 0x73, 0x60, 0x7a, 0x68, 0x40, 0x60, 0x72, + 0x20, 0x7a, 0xa1, 0x7a, 0xe1, 0x4e, 0x88, 0x42, /// 0x3e70 + 0x52, 0xd1, 0x60, 0x7a, 0x00, 0x28, 0x0f, 0xd0, + 0xdc, 0x4d, 0x2a, 0x7a, 0x0c, 0x2a, 0x4b, 0xd2, /// 0x3e80 + 0xdd, 0x48, 0xa3, 0x7b, 0x01, 0x46, 0x40, 0x31, + 0x01, 0x2b, 0x11, 0xd0, 0x08, 0x27, 0x71, 0x2b, /// 0x3e90 + 0x1e, 0xd0, 0x51, 0x2b, 0x2c, 0xd0, 0x3f, 0xe0, + 0xa1, 0x7a, 0x20, 0x46, 0x0e, 0x30, 0xff, 0xf7, /// 0x3ea0 + 0xa5, 0xff, 0x00, 0x20, 0x20, 0x72, 0xb8, 0x78, + 0xfb, 0x21, 0x08, 0x40, 0xb8, 0x70, 0x33, 0xe0, /// 0x3eb0 + 0x01, 0x2a, 0x31, 0xd1, 0x0a, 0x74, 0xc1, 0x6a, + 0x4a, 0x07, 0x05, 0xd4, 0x04, 0x22, 0x11, 0x43, /// 0x3ec0 + 0xc1, 0x62, 0x10, 0x46, 0xfc, 0xf7, 0x48, 0xfe, + 0x70, 0x68, 0x28, 0x60, 0x02, 0x20, 0x22, 0xe0, /// 0x3ed0 + 0x02, 0x2a, 0x21, 0xd1, 0x71, 0x22, 0x0a, 0x74, + 0xc1, 0x6a, 0x0a, 0x07, 0x04, 0xd4, 0x39, 0x43, /// 0x3ee0 + 0xc1, 0x62, 0x08, 0x20, 0xfc, 0xf7, 0x38, 0xfe, + 0x70, 0x68, 0x28, 0x60, 0x03, 0x20, 0x12, 0xe0, /// 0x3ef0 + 0x03, 0x2a, 0x11, 0xd1, 0x51, 0x22, 0x0a, 0x74, + 0xc1, 0x6a, 0xca, 0x06, 0x05, 0xd4, 0x10, 0x22, /// 0x3f00 + 0x11, 0x43, 0xc1, 0x62, 0x10, 0x46, 0xfc, 0xf7, + 0x27, 0xfe, 0xbb, 0x48, 0x60, 0x30, 0x07, 0x76, /// 0x3f10 + 0x70, 0x68, 0x28, 0x60, 0x0c, 0x20, 0x28, 0x72, + 0x70, 0x68, 0x60, 0x60, 0xf8, 0xbd, 0xf1, 0xb5, /// 0x3f20 + 0xb6, 0x4d, 0x82, 0xb0, 0x28, 0x7b, 0x02, 0x99, + 0x86, 0x07, 0x2c, 0x22, 0xb6, 0x0f, 0xb0, 0x48, /// 0x3f30 + 0x51, 0x43, 0x01, 0x2e, 0x46, 0xd0, 0x00, 0x22, + 0x42, 0x52, 0x43, 0x5a, 0x02, 0x9a, 0x2c, 0x24, /// 0x3f40 + 0x62, 0x43, 0xab, 0x4c, 0x14, 0x19, 0x09, 0x2b, + 0x02, 0xd3, 0xa2, 0x78, 0x52, 0x07, 0x05, 0xd5, /// 0x3f50 + 0x40, 0x5a, 0x0b, 0x28, 0x0a, 0xd3, 0xa0, 0x78, + 0x40, 0x07, 0x07, 0xd5, 0xa0, 0x78, 0xfb, 0x21, /// 0x3f60 + 0x08, 0x40, 0xa0, 0x70, 0xa0, 0x78, 0x01, 0x21, + 0x08, 0x43, 0xa0, 0x70, 0xa0, 0x78, 0xc0, 0x07, /// 0x3f70 + 0x34, 0xd0, 0x01, 0x2e, 0x32, 0xd9, 0xa0, 0x78, + 0x40, 0x08, 0x40, 0x00, 0xa0, 0x70, 0xa0, 0x78, /// 0x3f80 + 0x04, 0x21, 0x08, 0x43, 0xa0, 0x70, 0xa0, 0x78, + 0x02, 0x2e, 0x1e, 0xd0, 0xfd, 0x21, 0x08, 0x40, /// 0x3f90 + 0xa0, 0x70, 0x20, 0x1d, 0x28, 0x21, 0xfc, 0xf7, + 0xc4, 0xfd, 0x20, 0x46, 0x18, 0x30, 0x28, 0x21, /// 0x3fa0 + 0xfc, 0xf7, 0xbf, 0xfd, 0x03, 0x2e, 0x13, 0xd0, + 0x01, 0x20, 0x40, 0x02, 0xa0, 0x81, 0x11, 0x20, /// 0x3fb0 + 0x40, 0x02, 0x20, 0x84, 0x8d, 0x48, 0x01, 0x7a, + 0x0c, 0x29, 0x02, 0xd1, 0x8d, 0x49, 0x49, 0x68, /// 0x3fc0 + 0x01, 0x60, 0xfe, 0xbd, 0x42, 0x5a, 0x52, 0x1c, + 0xb6, 0xe7, 0x02, 0x21, 0x08, 0x43, 0xdf, 0xe7, /// 0x3fd0 + 0x03, 0x20, 0x00, 0x02, 0xa0, 0x81, 0x23, 0x20, + 0x00, 0x02, 0xea, 0xe7, 0xa0, 0x78, 0x40, 0x07, /// 0x3fe0 + 0xef, 0xd5, 0xa0, 0x78, 0x80, 0x07, 0x01, 0xd5, + 0x02, 0x20, 0x00, 0xe0, 0x01, 0x20, 0x00, 0x26, /// 0x3ff0 + 0x00, 0x90, 0x14, 0x20, 0x70, 0x43, 0x27, 0x18, + 0xb8, 0x89, 0xa8, 0x83, 0xa9, 0x8b, 0x09, 0x20, /// 0x4000 + 0x00, 0x03, 0x88, 0x43, 0x05, 0xd1, 0xa8, 0x8b, + 0xf1, 0xb2, 0xc2, 0xb2, 0x02, 0x98, 0xff, 0xf7, /// 0x4010 + 0x0a, 0xff, 0xa8, 0x8b, 0xb8, 0x81, 0x00, 0x98, + 0x76, 0x1c, 0x86, 0x42, 0xe9, 0xdb, 0xfe, 0xbd, /// 0x4020 + 0xf8, 0xb5, 0x76, 0x48, 0x40, 0x38, 0x06, 0x7f, + 0xff, 0x21, 0x01, 0x76, 0x00, 0x24, 0x01, 0x27, /// 0x4030 + 0x3d, 0x46, 0xa5, 0x40, 0x35, 0x42, 0x02, 0xd0, + 0xe0, 0xb2, 0xff, 0xf7, 0x70, 0xff, 0x64, 0x1c, /// 0x4040 + 0x02, 0x2c, 0xf5, 0xdb, 0x00, 0x20, 0xf8, 0xbd, + 0x01, 0x21, 0x6c, 0x48, 0xc9, 0x03, 0x40, 0x38, /// 0x4050 + 0x01, 0x80, 0x6a, 0x49, 0x0c, 0x22, 0x20, 0x31, + 0x8a, 0x82, 0x69, 0x4b, 0xa5, 0x22, 0x1a, 0x80, /// 0x4060 + 0x00, 0x22, 0x9a, 0x82, 0x01, 0x23, 0x0b, 0x74, + 0x10, 0x21, 0x01, 0x80, 0x08, 0x21, 0x01, 0x71, /// 0x4070 + 0x8d, 0x21, 0x01, 0x72, 0x60, 0x21, 0x01, 0x73, + 0x60, 0x49, 0x20, 0x39, 0x0a, 0x71, 0x61, 0x4a, /// 0x4080 + 0x8a, 0x83, 0x61, 0x4a, 0x0a, 0x82, 0x61, 0x4a, + 0x8a, 0x82, 0x61, 0x4a, 0x0a, 0x83, 0x61, 0x4a, /// 0x4090 + 0x0a, 0x81, 0x8a, 0x81, 0x60, 0x4a, 0x41, 0x15, + 0x11, 0x60, 0x60, 0x4a, 0x11, 0x60, 0x03, 0x21, /// 0x40a0 + 0x01, 0x82, 0xff, 0x21, 0x01, 0x76, 0x70, 0x47, + 0xff, 0x21, 0x10, 0xb5, 0x90, 0x31, 0x88, 0x42, /// 0x40b0 + 0x06, 0xd9, 0x64, 0x21, 0xfd, 0xf7, 0x88, 0xfc, + 0x0a, 0x21, 0x48, 0x43, 0x80, 0x1c, 0x00, 0xe0, /// 0x40c0 + 0x20, 0x20, 0xc1, 0xb2, 0x08, 0x02, 0x08, 0x43, + 0x4c, 0x49, 0x20, 0x39, 0x08, 0x81, 0x88, 0x81, /// 0x40d0 + 0x10, 0xbd, 0x49, 0x49, 0x10, 0xb5, 0x00, 0x22, + 0x80, 0x31, 0x4a, 0x76, 0x43, 0x49, 0x88, 0x71, /// 0x40e0 + 0x8a, 0x76, 0x02, 0x20, 0x08, 0x72, 0x43, 0x48, + 0x04, 0x22, 0x40, 0x68, 0x08, 0x60, 0x42, 0x48, /// 0x40f0 + 0xc1, 0x6a, 0x11, 0x43, 0xc1, 0x62, 0x10, 0x46, + 0xfc, 0xf7, 0x2e, 0xfd, 0x10, 0xbd, 0x01, 0x46, /// 0x4100 + 0x3a, 0x48, 0x10, 0xb5, 0x07, 0x22, 0x1c, 0x30, + 0xfc, 0xf7, 0xfb, 0xfc, 0x44, 0x49, 0xfb, 0x20, /// 0x4110 + 0x08, 0x80, 0x36, 0x48, 0x0c, 0x21, 0x01, 0x72, + 0x36, 0x49, 0x10, 0x22, 0x49, 0x68, 0x01, 0x60, /// 0x4120 + 0x35, 0x48, 0x08, 0x21, 0x60, 0x30, 0x01, 0x76, + 0x60, 0x38, 0xc1, 0x6a, 0x11, 0x43, 0xc1, 0x62, /// 0x4130 + 0x10, 0x46, 0xfc, 0xf7, 0x11, 0xfd, 0x10, 0xbd, + 0x01, 0x46, 0x2c, 0x48, 0x10, 0xb5, 0x07, 0x22, /// 0x4140 + 0x21, 0x30, 0xfc, 0xf7, 0xde, 0xfc, 0x29, 0x48, + 0x03, 0x21, 0x01, 0x72, 0x29, 0x49, 0x08, 0x22, /// 0x4150 + 0x49, 0x68, 0x01, 0x60, 0x28, 0x48, 0xc1, 0x6a, + 0x11, 0x43, 0xc1, 0x62, 0x10, 0x46, 0xfc, 0xf7, /// 0x4160 + 0xfb, 0xfc, 0x10, 0xbd, 0x21, 0x48, 0x03, 0x21, + 0x01, 0x72, 0x22, 0x49, 0x49, 0x68, 0x01, 0x60, /// 0x4170 + 0x70, 0x47, 0x10, 0xb5, 0x08, 0x28, 0x17, 0xd8, + 0x1f, 0x48, 0x80, 0x30, 0x41, 0x7e, 0x49, 0x1c, /// 0x4180 + 0xc9, 0xb2, 0x41, 0x76, 0x80, 0x38, 0x02, 0x8c, + 0x91, 0x42, 0x0d, 0xd3, 0x01, 0x46, 0x40, 0x31, /// 0x4190 + 0x8b, 0x8e, 0x01, 0x22, 0x13, 0x43, 0x8b, 0x86, + 0xc1, 0x6a, 0x11, 0x43, 0xc1, 0x62, 0x10, 0x46, /// 0x41a0 + 0xfc, 0xf7, 0xda, 0xfc, 0x00, 0xf0, 0x54, 0xfb, + 0x10, 0xbd, 0xf8, 0xb5, 0x07, 0x46, 0xc5, 0x09, /// 0x41b0 + 0x01, 0xd0, 0xf8, 0x43, 0x40, 0x1c, 0xc4, 0xb2, + 0x19, 0x48, 0x01, 0x88, 0x09, 0x06, 0xc9, 0x0e, /// 0x41c0 + 0x1f, 0x29, 0x01, 0xd0, 0xfb, 0x21, 0x01, 0x80, + 0x0b, 0x4e, 0xff, 0x20, 0x40, 0x36, 0x71, 0x8c, /// 0x41d0 + 0x9d, 0x30, 0x81, 0x42, 0x03, 0xd0, 0x05, 0x49, + 0x49, 0x79, 0x00, 0xf0, 0x98, 0xfb, 0x05, 0x48, /// 0x41e0 + 0x05, 0x49, 0xe0, 0x38, 0xc7, 0x75, 0x80, 0x31, + 0x48, 0x7e, 0x1b, 0xe0, 0x70, 0x04, 0x00, 0x20, /// 0x41f0 + 0xe0, 0x03, 0x00, 0x20, 0x30, 0x02, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x20, 0x40, 0x40, 0x00, 0x40, /// 0x4200 + 0x00, 0x74, 0x00, 0x40, 0x2c, 0x10, 0x00, 0x00, + 0x1d, 0x26, 0x00, 0x00, 0x15, 0x1d, 0x00, 0x00, /// 0x4210 + 0x0e, 0x15, 0x00, 0x00, 0x2a, 0x2a, 0x00, 0x00, + 0x80, 0xe2, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe0, /// 0x4220 + 0x00, 0x34, 0x00, 0x40, 0x00, 0x22, 0x00, 0x28, + 0x19, 0xd0, 0x08, 0x7e, 0x40, 0x1c, 0xc0, 0xb2, /// 0x4230 + 0x08, 0x76, 0x14, 0x28, 0x00, 0xd9, 0x4a, 0x76, + 0xfe, 0x48, 0xf7, 0x27, 0xc2, 0x80, 0xfe, 0x48, /// 0x4240 + 0x03, 0x7b, 0x3b, 0x40, 0x03, 0x73, 0xfd, 0x4b, + 0x00, 0x2c, 0x5b, 0x68, 0x03, 0x60, 0x08, 0xd0, /// 0x4250 + 0x04, 0x2c, 0x0a, 0xd2, 0x00, 0x2d, 0x06, 0xd0, + 0x00, 0x23, 0xdb, 0x43, 0x0f, 0xe0, 0x0a, 0x76, /// 0x4260 + 0xea, 0xe7, 0x42, 0x72, 0x2a, 0xe0, 0x01, 0x23, + 0x09, 0xe0, 0x73, 0x8c, 0xb7, 0x8c, 0xbb, 0x42, /// 0x4270 + 0x07, 0xd1, 0x00, 0x2d, 0x02, 0xd0, 0xa3, 0x08, + 0x5b, 0x42, 0x00, 0xe0, 0x63, 0x08, 0x43, 0x72, /// 0x4280 + 0x1c, 0xe0, 0xf6, 0x8c, 0xf3, 0x1a, 0x1b, 0x12, + 0x5b, 0x1c, 0x9b, 0xb2, 0x10, 0x2c, 0x00, 0xd9, /// 0x4290 + 0x10, 0x24, 0x00, 0x2d, 0x02, 0xd0, 0x66, 0x08, + 0x34, 0x19, 0xe4, 0xb2, 0x46, 0x79, 0xff, 0x2e, /// 0x42a0 + 0x05, 0xd0, 0xe4, 0x4e, 0x40, 0x36, 0x36, 0x79, + 0xf4, 0x40, 0x64, 0x1c, 0xe4, 0xb2, 0x00, 0x2d, /// 0x42b0 + 0x02, 0xd0, 0x5c, 0x43, 0x64, 0x42, 0x00, 0xe0, + 0x5c, 0x43, 0x44, 0x72, 0x09, 0x24, 0x04, 0x57, /// 0x42c0 + 0xdf, 0x4b, 0x00, 0x2c, 0x02, 0xdd, 0xdc, 0x7e, + 0x64, 0x07, 0x02, 0xd4, 0xdb, 0x7e, 0xdb, 0x06, /// 0x42d0 + 0x00, 0xd4, 0x42, 0x72, 0x48, 0x7f, 0x10, 0x28, + 0x00, 0xd2, 0x40, 0x1c, 0x48, 0x77, 0xf8, 0xbd, /// 0x42e0 + 0xf0, 0xb5, 0xd7, 0x4d, 0xd4, 0x4e, 0x20, 0x3d, + 0x2c, 0x46, 0x40, 0x34, 0x28, 0x8e, 0x31, 0x8a, /// 0x42f0 + 0x85, 0xb0, 0x62, 0x8a, 0x01, 0x92, 0xa2, 0x7e, + 0x03, 0x92, 0xe2, 0x8a, 0x00, 0x92, 0xa2, 0x7f, /// 0x4300 + 0x02, 0x92, 0x48, 0x43, 0x05, 0xd0, 0x7d, 0x21, + 0xc9, 0x00, 0xfd, 0xf7, 0x73, 0xfb, 0x07, 0x46, /// 0x4310 + 0x00, 0xe0, 0x00, 0x27, 0x31, 0x7f, 0xf0, 0x79, + 0x89, 0x06, 0x89, 0x0e, 0x7d, 0x22, 0x51, 0x43, /// 0x4320 + 0x48, 0x43, 0x46, 0x09, 0x00, 0x98, 0x87, 0x42, + 0x06, 0xd9, 0x03, 0x99, 0x38, 0x1a, 0x48, 0x43, /// 0x4330 + 0x64, 0x21, 0xfd, 0xf7, 0x49, 0xfb, 0x00, 0xe0, + 0x00, 0x20, 0xc1, 0x49, 0x38, 0x1a, 0x82, 0x1b, /// 0x4340 + 0x60, 0x39, 0x08, 0x46, 0xe0, 0x30, 0x0a, 0x61, + 0x80, 0x7f, 0x64, 0x23, 0x58, 0x43, 0xb0, 0x42, /// 0x4350 + 0x07, 0xd8, 0x01, 0x98, 0x82, 0x42, 0x06, 0xdc, + 0xba, 0x48, 0x86, 0x42, 0x03, 0xd2, 0x00, 0x20, /// 0x4360 + 0xe0, 0x77, 0x05, 0xb0, 0xf0, 0xbd, 0xe0, 0x7f, + 0x40, 0x1c, 0xc0, 0xb2, 0xe0, 0x77, 0x01, 0x9b, /// 0x4370 + 0x9b, 0x00, 0x93, 0x42, 0x01, 0xda, 0x40, 0x1c, + 0xe0, 0x77, 0xc2, 0xb2, 0x02, 0x98, 0x82, 0x42, /// 0x4380 + 0xef, 0xd3, 0x00, 0x20, 0xe0, 0x77, 0xa8, 0x8e, + 0x01, 0x22, 0x52, 0x03, 0x10, 0x43, 0xa8, 0x86, /// 0x4390 + 0xc8, 0x6a, 0x01, 0x22, 0x10, 0x43, 0xc8, 0x62, + 0x10, 0x46, 0xfc, 0xf7, 0xdd, 0xfb, 0x00, 0xf0, /// 0x43a0 + 0x57, 0xfa, 0xde, 0xe7, 0x70, 0xb5, 0xa4, 0x4d, + 0xa5, 0x4c, 0xe8, 0x71, 0x20, 0x34, 0x21, 0x7f, /// 0x43b0 + 0x08, 0x30, 0x81, 0x42, 0x01, 0xd9, 0x00, 0x20, + 0x60, 0x77, 0xa1, 0x48, 0x20, 0x38, 0xc0, 0x8e, /// 0x43c0 + 0x80, 0x06, 0x09, 0xd5, 0x60, 0x7f, 0x06, 0x28, + 0x06, 0xd9, 0x9b, 0x48, 0x20, 0x30, 0x40, 0x78, /// 0x43d0 + 0x00, 0x07, 0x01, 0xd0, 0xff, 0xf7, 0x84, 0xff, + 0xe8, 0x79, 0x20, 0x77, 0x70, 0xbd, 0x98, 0x49, /// 0x43e0 + 0x40, 0x39, 0x88, 0x76, 0x64, 0x28, 0x01, 0xd9, + 0x64, 0x20, 0x88, 0x76, 0x70, 0x47, 0x41, 0x1f, /// 0x43f0 + 0xc8, 0x29, 0x01, 0xd8, 0x90, 0x49, 0xc8, 0x72, + 0x70, 0x47, 0x10, 0xb5, 0x42, 0x78, 0x1e, 0x23, /// 0x4400 + 0x4a, 0x70, 0x36, 0x2a, 0x09, 0xd0, 0x37, 0x2a, + 0x06, 0xd1, 0x0b, 0x70, 0x81, 0x1c, 0x8c, 0x48, /// 0x4410 + 0x04, 0x22, 0x48, 0x38, 0xfc, 0xf7, 0x75, 0xfb, + 0x10, 0xbd, 0x0b, 0x70, 0x81, 0x1c, 0x88, 0x48, /// 0x4420 + 0x04, 0x22, 0x4c, 0x38, 0xf6, 0xe7, 0x70, 0xb5, + 0x42, 0x78, 0x1e, 0x25, 0x0c, 0x46, 0x4a, 0x70, /// 0x4430 + 0xc1, 0x2a, 0x16, 0xd0, 0xc3, 0x2a, 0x18, 0xd0, + 0x81, 0x49, 0x60, 0x31, 0xb6, 0x2a, 0x1c, 0xd0, /// 0x4440 + 0xb7, 0x2a, 0x19, 0xd1, 0x82, 0x78, 0x4a, 0x70, + 0xc2, 0x78, 0x8a, 0x70, 0x00, 0x79, 0xc8, 0x70, /// 0x4450 + 0xc0, 0x39, 0xff, 0x20, 0xca, 0x6a, 0x01, 0x30, + 0x02, 0x43, 0xca, 0x62, 0xfc, 0xf7, 0x7c, 0xfb, /// 0x4460 + 0x09, 0xe0, 0x01, 0x22, 0x41, 0x88, 0x92, 0x07, + 0x02, 0xe0, 0x41, 0x88, 0x01, 0x22, 0x52, 0x07, /// 0x4470 + 0x89, 0x18, 0x00, 0x79, 0x08, 0x70, 0x25, 0x70, + 0x70, 0xbd, 0x71, 0x4a, 0x83, 0x78, 0x40, 0x32, /// 0x4480 + 0x93, 0x77, 0xc3, 0x78, 0xd3, 0x77, 0xf4, 0xe7, + 0xf8, 0xb5, 0x0d, 0x46, 0x6c, 0x4c, 0x41, 0x78, /// 0x4490 + 0x6d, 0x4a, 0x1e, 0x27, 0x20, 0x3c, 0x69, 0x70, + 0xc8, 0x29, 0x1c, 0xd0, 0xff, 0x26, 0xc6, 0x29, /// 0x44a0 + 0x1f, 0xd0, 0xc7, 0x29, 0x2c, 0xd0, 0x2f, 0x22, + 0xc0, 0x29, 0x38, 0xd0, 0xc2, 0x29, 0x3a, 0xd0, /// 0x44b0 + 0x3d, 0x29, 0x0f, 0xd1, 0x81, 0x78, 0x22, 0x29, + 0x0c, 0xd1, 0xc0, 0x78, 0x07, 0x28, 0x09, 0xd1, /// 0x44c0 + 0x5f, 0x48, 0x2f, 0x70, 0xc1, 0x7e, 0x10, 0x22, + 0x11, 0x43, 0xc1, 0x76, 0xa0, 0x8e, 0x08, 0x21, /// 0x44d0 + 0x88, 0x43, 0xa0, 0x86, 0xf8, 0xbd, 0x41, 0x88, + 0x10, 0x46, 0xfd, 0xf7, 0x75, 0xfa, 0x20, 0x85, /// 0x44e0 + 0x0c, 0xe0, 0x41, 0x88, 0x10, 0x46, 0xfd, 0xf7, + 0x6f, 0xfa, 0x53, 0x4a, 0xe0, 0x84, 0x56, 0x71, /// 0x44f0 + 0x62, 0x8c, 0x31, 0x46, 0x82, 0x42, 0x0e, 0xd8, + 0x10, 0x46, 0x0c, 0xe0, 0x2f, 0x70, 0xf8, 0xbd, /// 0x4500 + 0x41, 0x88, 0x10, 0x46, 0xfd, 0xf7, 0x60, 0xfa, + 0x4b, 0x4a, 0xa0, 0x84, 0x56, 0x71, 0x62, 0x8c, /// 0x4510 + 0x31, 0x46, 0x82, 0x42, 0xf0, 0xd2, 0x60, 0x84, + 0x00, 0xf0, 0xf9, 0xf9, 0xee, 0xe7, 0x01, 0x21, /// 0x4520 + 0x40, 0x88, 0x89, 0x07, 0x02, 0xe0, 0x40, 0x88, + 0x01, 0x21, 0x49, 0x07, 0x40, 0x18, 0x2a, 0x70, /// 0x4530 + 0x00, 0x78, 0xa8, 0x70, 0xf8, 0xbd, 0x70, 0xb5, + 0x0c, 0x46, 0x41, 0x4a, 0x41, 0x78, 0x3e, 0x4b, /// 0x4540 + 0x20, 0x3a, 0x1e, 0x25, 0x61, 0x70, 0xc5, 0x29, + 0x09, 0xd0, 0xcd, 0x29, 0x06, 0xd1, 0x80, 0x78, /// 0x4550 + 0x18, 0x71, 0x59, 0x79, 0x50, 0x8c, 0x00, 0xf0, + 0xda, 0xf9, 0x25, 0x70, 0x70, 0xbd, 0x81, 0x78, /// 0x4560 + 0x59, 0x71, 0xf7, 0xe7, 0x70, 0xb5, 0x0c, 0x46, + 0x41, 0x78, 0x61, 0x70, 0x05, 0x29, 0x23, 0xd0, /// 0x4570 + 0x2f, 0x26, 0x31, 0x4b, 0xc9, 0x29, 0x2e, 0xd0, + 0x31, 0x4a, 0x33, 0x48, 0x20, 0x3a, 0x3f, 0x25, /// 0x4580 + 0xca, 0x29, 0x2b, 0xd0, 0xcb, 0x29, 0x2b, 0xd0, + 0xcc, 0x29, 0x31, 0xd0, 0x04, 0x29, 0x31, 0xd0, /// 0x4590 + 0x06, 0x29, 0x31, 0xd0, 0x07, 0x29, 0x31, 0xd0, + 0xce, 0x29, 0x31, 0xd0, 0xc4, 0x29, 0x0a, 0xd1, /// 0x45a0 + 0x18, 0x7b, 0x41, 0x08, 0x49, 0x00, 0xc0, 0x07, + 0xc2, 0x17, 0x01, 0x20, 0x90, 0x43, 0x01, 0x43, /// 0x45b0 + 0x19, 0x73, 0x1e, 0x20, 0x20, 0x70, 0x70, 0xbd, + 0x5f, 0x20, 0x20, 0x70, 0x23, 0x48, 0x01, 0x79, /// 0x45c0 + 0xa1, 0x70, 0x81, 0x88, 0x09, 0x0a, 0xe1, 0x70, + 0x41, 0x68, 0x09, 0x0c, 0x21, 0x71, 0x40, 0x68, /// 0x45d0 + 0x00, 0x0e, 0x60, 0x71, 0x70, 0xbd, 0x26, 0x70, + 0x58, 0x79, 0x13, 0xe0, 0xd1, 0x8c, 0x00, 0xe0, /// 0x45e0 + 0x91, 0x8c, 0xfd, 0xf7, 0xf1, 0xf9, 0x25, 0x70, + 0xa0, 0x70, 0x00, 0x0a, 0xe0, 0x70, 0x70, 0xbd, /// 0x45f0 + 0x11, 0x8d, 0xf6, 0xe7, 0x51, 0x8c, 0xf4, 0xe7, + 0xd0, 0x8d, 0xf4, 0xe7, 0x10, 0x8e, 0xf2, 0xe7, /// 0x4600 + 0x26, 0x70, 0x18, 0x79, 0xa0, 0x70, 0x70, 0xbd, + 0x3e, 0xb5, 0x04, 0x46, 0x00, 0x78, 0xfd, 0xf7, /// 0x4610 + 0x6d, 0xfe, 0x0b, 0x48, 0x06, 0x22, 0x21, 0x46, + 0x10, 0x38, 0xfc, 0xf7, 0x72, 0xfa, 0x00, 0x20, /// 0x4620 + 0x69, 0x46, 0x08, 0x70, 0x20, 0x78, 0x38, 0x28, + 0x2d, 0xd0, 0x16, 0xdc, 0x18, 0x28, 0x26, 0xd0, /// 0x4630 + 0x28, 0x28, 0x0d, 0xe0, 0x30, 0x01, 0x00, 0x20, + 0x70, 0x04, 0x00, 0x20, 0x30, 0x02, 0x00, 0x20, /// 0x4640 + 0x60, 0x00, 0x00, 0x20, 0x28, 0x23, 0x00, 0x00, + 0x60, 0xea, 0x00, 0x00, 0x40, 0x04, 0x00, 0x20, /// 0x4650 + 0x32, 0xd1, 0x20, 0x46, 0xff, 0xf7, 0x6f, 0xff, + 0x06, 0xe0, 0x48, 0x28, 0x17, 0xd0, 0x58, 0x28, /// 0x4660 + 0x2a, 0xd1, 0x20, 0x46, 0xff, 0xf7, 0xc9, 0xfe, + 0x68, 0x46, 0x00, 0x78, 0x00, 0x28, 0x23, 0xd0, /// 0x4670 + 0xfd, 0xf7, 0x3c, 0xfe, 0x69, 0x46, 0x09, 0x78, + 0x1e, 0x29, 0x0c, 0xd0, 0x0e, 0xe0, 0x20, 0x46, /// 0x4680 + 0xff, 0xf7, 0x70, 0xff, 0xf0, 0xe7, 0x20, 0x46, + 0xff, 0xf7, 0xfe, 0xfe, 0xec, 0xe7, 0x20, 0x46, /// 0x4690 + 0xff, 0xf7, 0xc9, 0xfe, 0xe8, 0xe7, 0xff, 0x21, + 0x6a, 0x46, 0x51, 0x70, 0x42, 0x1c, 0x69, 0x46, /// 0x46a0 + 0x52, 0x48, 0xfc, 0xf7, 0x2e, 0xfa, 0x51, 0x48, + 0x08, 0x22, 0x18, 0x38, 0xc1, 0x8e, 0x11, 0x43, /// 0x46b0 + 0xc1, 0x86, 0x03, 0x21, 0xa0, 0x30, 0xc1, 0x74, + 0x3e, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0x4c, 0x48, /// 0x46c0 + 0x4a, 0x4b, 0x00, 0x7a, 0x08, 0x3b, 0x21, 0x78, + 0x0c, 0x28, 0x2e, 0xd0, 0x01, 0x29, 0x0b, 0xd0, /// 0x46d0 + 0x51, 0x29, 0x14, 0xd0, 0x71, 0x29, 0x1d, 0xd0, + 0x81, 0x29, 0x04, 0xd1, 0x71, 0x28, 0x02, 0xd1, /// 0x46e0 + 0x60, 0x1c, 0xff, 0xf7, 0x3f, 0xfd, 0x10, 0xbd, + 0x01, 0x28, 0xfc, 0xd1, 0x06, 0x22, 0x21, 0x46, /// 0x46f0 + 0x18, 0x46, 0xfc, 0xf7, 0x06, 0xfa, 0x60, 0x78, + 0xff, 0xf7, 0xeb, 0xfc, 0x10, 0xbd, 0x03, 0x28, /// 0x4700 + 0xfc, 0xd1, 0x06, 0x22, 0x21, 0x46, 0x18, 0x46, + 0xfc, 0xf7, 0xfb, 0xf9, 0x60, 0x1c, 0xff, 0xf7, /// 0x4710 + 0xf6, 0xfc, 0x10, 0xbd, 0x02, 0x28, 0xfc, 0xd1, + 0x06, 0x22, 0x21, 0x46, 0x18, 0x46, 0xfc, 0xf7, /// 0x4720 + 0xf0, 0xf9, 0x60, 0x1c, 0xff, 0xf7, 0x08, 0xfd, + 0x10, 0xbd, 0x05, 0x29, 0x26, 0xd0, 0x08, 0xdc, /// 0x4730 + 0x01, 0x29, 0xf9, 0xd0, 0x02, 0x29, 0x10, 0xd0, + 0x03, 0x29, 0x17, 0xd0, 0x04, 0x29, 0x08, 0xd1, /// 0x4740 + 0x18, 0xe0, 0x06, 0x29, 0x1e, 0xd0, 0x51, 0x29, + 0xee, 0xd0, 0x71, 0x29, 0xec, 0xd0, 0x81, 0x29, /// 0x4750 + 0xea, 0xd0, 0x20, 0x46, 0xff, 0xf7, 0x58, 0xff, + 0x10, 0xbd, 0x06, 0x22, 0x21, 0x46, 0x18, 0x46, /// 0x4760 + 0xfc, 0xf7, 0xcf, 0xf9, 0x60, 0x78, 0xff, 0xf7, + 0x04, 0xfd, 0x10, 0xbd, 0x60, 0x78, 0xff, 0xf7, /// 0x4770 + 0x1c, 0xfd, 0x10, 0xbd, 0x60, 0x78, 0xff, 0xf7, + 0x15, 0xfe, 0x10, 0xbd, 0x60, 0x78, 0xff, 0xf7, /// 0x4780 + 0x2e, 0xfe, 0x10, 0xbd, 0x60, 0x78, 0xff, 0xf7, + 0x32, 0xfe, 0x10, 0xbd, 0xf8, 0xb5, 0x18, 0x48, /// 0x4790 + 0x17, 0x4e, 0x80, 0x6f, 0x00, 0x27, 0x78, 0x36, + 0x04, 0x68, 0x10, 0xe0, 0x05, 0x46, 0x06, 0xc8, /// 0x47a0 + 0x4a, 0x60, 0x08, 0x38, 0x11, 0x60, 0x07, 0x60, + 0x0c, 0x3d, 0x47, 0x60, 0x28, 0x46, 0xff, 0xf7, /// 0x47b0 + 0x84, 0xff, 0x0a, 0x21, 0x28, 0x46, 0xfc, 0xf7, + 0xb4, 0xf9, 0x20, 0x46, 0x24, 0x68, 0xb0, 0x42, /// 0x47c0 + 0xec, 0xd1, 0xf8, 0xbd, 0x10, 0xb5, 0x0b, 0x4c, + 0x20, 0x7a, 0xc0, 0x07, 0x0c, 0xd0, 0x20, 0x7b, /// 0x47d0 + 0xfd, 0xf7, 0x8c, 0xfd, 0x40, 0x1c, 0xc1, 0xb2, + 0x20, 0x46, 0x0c, 0x30, 0xff, 0xf7, 0x06, 0xfb, /// 0x47e0 + 0x20, 0x7a, 0x40, 0x08, 0x40, 0x00, 0x20, 0x72, + 0x10, 0xbd, 0x00, 0x00, 0x58, 0x00, 0x00, 0x20, /// 0x47f0 + 0x70, 0x04, 0x00, 0x20, 0x40, 0x04, 0x00, 0x20, + 0x01, 0x21, 0xb3, 0x48, 0xc9, 0x03, 0x01, 0x80, /// 0x4800 + 0xb2, 0x49, 0x09, 0x7e, 0xc9, 0x00, 0x49, 0x1c, + 0x01, 0x80, 0x03, 0x21, 0x81, 0x80, 0x01, 0x88, /// 0x4810 + 0x02, 0x22, 0x11, 0x43, 0x01, 0x80, 0x70, 0x47, + 0xac, 0x48, 0x00, 0x7e, 0xc1, 0x00, 0xaa, 0x48, /// 0x4820 + 0x49, 0x1c, 0x01, 0x80, 0x01, 0x88, 0x02, 0x22, + 0x11, 0x43, 0x01, 0x80, 0x70, 0x47, 0x01, 0x20, /// 0x4830 + 0xa5, 0x49, 0xc0, 0x03, 0x08, 0x80, 0xa6, 0x49, + 0x00, 0x20, 0x08, 0x76, 0xa5, 0x4a, 0xd0, 0x21, /// 0x4840 + 0x91, 0x83, 0xa5, 0x49, 0x08, 0x72, 0xa2, 0x48, + 0x04, 0x21, 0x20, 0x38, 0x41, 0x73, 0x70, 0x47, /// 0x4850 + 0xf8, 0xb5, 0x9d, 0x48, 0x00, 0x25, 0x05, 0x83, + 0x9d, 0x4e, 0x9f, 0x4c, 0x01, 0x20, 0x25, 0x72, /// 0x4860 + 0x30, 0x76, 0x31, 0x46, 0xa5, 0x76, 0x80, 0x31, + 0xc8, 0x71, 0xff, 0x20, 0xc0, 0x39, 0x88, 0x76, /// 0x4870 + 0xf1, 0x7e, 0xef, 0x22, 0x11, 0x40, 0xf1, 0x76, + 0x94, 0x49, 0x94, 0x4f, 0x20, 0x39, 0x0d, 0x83, /// 0x4880 + 0x60, 0x71, 0x30, 0x46, 0x20, 0x30, 0xc5, 0x77, + 0x08, 0x46, 0x40, 0x30, 0x40, 0x68, 0x20, 0x60, /// 0x4890 + 0x20, 0x7b, 0xf7, 0x21, 0x08, 0x40, 0x20, 0x73, + 0xe0, 0x3f, 0x32, 0x46, 0x78, 0x8e, 0x60, 0x32, /// 0x48a0 + 0x10, 0x82, 0xb9, 0x8e, 0x51, 0x82, 0x00, 0xf0, + 0xbc, 0xff, 0xe0, 0x7e, 0x40, 0x1c, 0xc0, 0xb2, /// 0x48b0 + 0xe0, 0x76, 0x03, 0x28, 0x00, 0xd3, 0xe5, 0x76, + 0x83, 0x48, 0x01, 0x88, 0x02, 0x22, 0x91, 0x43, /// 0x48c0 + 0x01, 0x80, 0x83, 0x48, 0x85, 0x49, 0x20, 0x38, + 0x80, 0x8e, 0x08, 0x42, 0x0b, 0xd1, 0x01, 0x05, /// 0x48d0 + 0x09, 0xd4, 0xc1, 0x04, 0x07, 0xd4, 0x41, 0x04, + 0x05, 0xd4, 0x01, 0x04, 0x03, 0xd4, 0xc1, 0x06, /// 0x48e0 + 0x01, 0xd4, 0x80, 0x04, 0x04, 0xd5, 0x30, 0x7e, + 0x00, 0x28, 0x01, 0xd0, 0xff, 0xf7, 0x9f, 0xff, /// 0x48f0 + 0x0a, 0x20, 0xb8, 0x70, 0x00, 0x20, 0x7a, 0x4a, + 0xfb, 0x23, 0x2c, 0x21, 0x41, 0x43, 0x89, 0x18, /// 0x4900 + 0x8c, 0x78, 0x1c, 0x40, 0x8c, 0x70, 0x40, 0x1c, + 0x02, 0x28, 0xf6, 0xdb, 0xf8, 0xbd, 0xfe, 0xb5, /// 0x4910 + 0x6f, 0x4f, 0x04, 0x46, 0x80, 0x37, 0xf8, 0x79, + 0x65, 0x08, 0x01, 0x28, 0x0d, 0xd0, 0xff, 0x20, /// 0x4920 + 0x40, 0x1a, 0x68, 0x43, 0x00, 0x0a, 0x01, 0x90, + 0x60, 0x1e, 0x39, 0x7a, 0x80, 0xb2, 0x00, 0x90, /// 0x4930 + 0xa0, 0x1c, 0x86, 0xb2, 0x01, 0x29, 0x15, 0xd0, + 0x2a, 0xe0, 0x28, 0x46, 0x48, 0x43, 0x02, 0x0a, /// 0x4940 + 0x61, 0x48, 0x01, 0x21, 0x20, 0x30, 0x81, 0x81, + 0x05, 0x82, 0x69, 0x1c, 0x81, 0x82, 0x04, 0x83, /// 0x4950 + 0x5d, 0x4b, 0xa1, 0x1a, 0x99, 0x83, 0xaa, 0x1a, + 0x02, 0x80, 0x52, 0x1c, 0x82, 0x80, 0x49, 0x1e, /// 0x4960 + 0x01, 0x81, 0x24, 0xe0, 0x58, 0x48, 0x01, 0x21, + 0x20, 0x30, 0x81, 0x81, 0x05, 0x82, 0x85, 0x82, /// 0x4970 + 0x00, 0x9a, 0x02, 0x83, 0x81, 0x80, 0x06, 0x81, + 0x53, 0x49, 0x89, 0x8b, 0x49, 0x1d, 0x01, 0x80, /// 0x4980 + 0x55, 0x49, 0x09, 0x79, 0xff, 0x31, 0x01, 0x31, + 0x81, 0x83, 0x14, 0x20, 0xfc, 0xf7, 0x4c, 0xf8, /// 0x4990 + 0x4d, 0x48, 0x01, 0x21, 0x20, 0x30, 0x81, 0x81, + 0x01, 0x9a, 0xaa, 0x1a, 0x02, 0x82, 0x82, 0x82, /// 0x49a0 + 0x00, 0x9a, 0x02, 0x83, 0x48, 0x4a, 0x96, 0x83, + 0x06, 0x80, 0x81, 0x80, 0x06, 0x81, 0xf8, 0x79, /// 0x49b0 + 0x38, 0x72, 0x0f, 0x20, 0x00, 0x03, 0x44, 0x49, + 0x20, 0x43, 0x08, 0x83, 0x46, 0x48, 0x42, 0x49, /// 0x49c0 + 0x00, 0x79, 0x20, 0x31, 0xff, 0x30, 0x01, 0x30, + 0x88, 0x83, 0x41, 0x48, 0x20, 0x38, 0x44, 0x84, /// 0x49d0 + 0xfe, 0xbd, 0x3f, 0x4a, 0x10, 0xb5, 0x20, 0x3a, + 0x91, 0x8c, 0x51, 0x84, 0x00, 0x28, 0x02, 0xd0, /// 0x49e0 + 0x01, 0x28, 0x03, 0xd0, 0x04, 0xe0, 0x01, 0x23, + 0x9b, 0x03, 0x01, 0xe0, 0x01, 0x23, 0xdb, 0x03, /// 0x49f0 + 0x35, 0x48, 0x00, 0x22, 0x20, 0x30, 0x82, 0x81, + 0x01, 0x82, 0x82, 0x80, 0x01, 0x81, 0x82, 0x82, /// 0x4a00 + 0x01, 0x83, 0x31, 0x4c, 0xa2, 0x83, 0x01, 0x80, + 0x19, 0x43, 0x21, 0x83, 0x32, 0x49, 0x09, 0x79, /// 0x4a10 + 0xff, 0x31, 0x01, 0x31, 0x81, 0x83, 0x10, 0xbd, + 0x32, 0x48, 0x01, 0x21, 0x01, 0x80, 0x05, 0x22, /// 0x4a20 + 0x02, 0x80, 0x82, 0x80, 0x01, 0x81, 0x08, 0x22, + 0x82, 0x81, 0xff, 0x22, 0x02, 0x82, 0x2e, 0x4a, /// 0x4a30 + 0x11, 0x70, 0x04, 0x23, 0x13, 0x71, 0x07, 0x22, + 0x02, 0x80, 0x2a, 0x4a, 0x00, 0x23, 0x20, 0x32, /// 0x4a40 + 0x13, 0x80, 0x2a, 0x4b, 0x13, 0x80, 0x01, 0x75, + 0x70, 0x47, 0x30, 0xb4, 0x22, 0x4a, 0x20, 0x4b, /// 0x4a50 + 0x14, 0x7b, 0x20, 0x3b, 0x11, 0x46, 0xe5, 0x07, + 0x58, 0x8c, 0x49, 0x79, 0x00, 0x2d, 0x05, 0xd0, /// 0x4a60 + 0x63, 0x07, 0x2f, 0xd5, 0xfb, 0x23, 0x1c, 0x40, + 0x14, 0x73, 0x29, 0xe0, 0x09, 0x24, 0x14, 0x57, /// 0x4a70 + 0x00, 0x2c, 0x27, 0xd0, 0x10, 0xdd, 0xff, 0x29, + 0x02, 0xd0, 0x09, 0xd2, 0x49, 0x1c, 0x08, 0xe0, /// 0x4a80 + 0xd9, 0x8c, 0x88, 0x42, 0x01, 0xd2, 0x40, 0x1c, + 0x00, 0xe0, 0x08, 0x46, 0x58, 0x84, 0x01, 0xe0, /// 0x4a90 + 0xff, 0x21, 0x51, 0x71, 0x64, 0x1e, 0x10, 0xe0, + 0x9d, 0x8c, 0xa8, 0x42, 0x06, 0xd1, 0x14, 0x29, /// 0x4aa0 + 0x01, 0xd9, 0x49, 0x1e, 0x00, 0xe0, 0x14, 0x21, + 0x51, 0x71, 0x05, 0xe0, 0xa8, 0x42, 0x01, 0xd9, /// 0x4ab0 + 0x40, 0x1e, 0x00, 0xe0, 0x28, 0x46, 0x58, 0x84, + 0x64, 0x1c, 0x54, 0x72, 0x51, 0x79, 0x58, 0x8c, /// 0x4ac0 + 0x30, 0xbc, 0x24, 0xe7, 0x30, 0xbc, 0x70, 0x47, + 0x00, 0x34, 0x00, 0x40, 0x10, 0x02, 0x00, 0x20, /// 0x4ad0 + 0x60, 0x00, 0x00, 0x20, 0x00, 0x30, 0x00, 0x40, + 0x70, 0x04, 0x00, 0x20, 0x01, 0x04, 0x00, 0x00, /// 0x4ae0 + 0xe0, 0x03, 0x00, 0x20, 0x00, 0x38, 0x00, 0x40, + 0x00, 0x3c, 0x00, 0x40, 0x08, 0x80, 0x00, 0x00, /// 0x4af0 + 0x70, 0xb5, 0xfe, 0x48, 0x00, 0x24, 0x01, 0x7a, + 0x01, 0x29, 0x20, 0xd1, 0xfc, 0x4a, 0x2e, 0x23, /// 0x4b00 + 0x11, 0x46, 0x40, 0x39, 0xd3, 0x5e, 0x4d, 0x89, + 0xab, 0x42, 0x03, 0xdc, 0x03, 0x8a, 0x8d, 0x89, /// 0x4b10 + 0xab, 0x42, 0x14, 0xd9, 0x03, 0x7e, 0x5d, 0x1c, + 0x05, 0x76, 0x03, 0x2b, 0x0e, 0xd3, 0x04, 0x76, /// 0x4b20 + 0x90, 0x8e, 0x01, 0x23, 0xdb, 0x03, 0x18, 0x43, + 0x90, 0x86, 0xc8, 0x6a, 0x01, 0x22, 0x10, 0x43, /// 0x4b30 + 0xc8, 0x62, 0x10, 0x46, 0xfc, 0xf7, 0x10, 0xf8, + 0xff, 0xf7, 0x8a, 0xfe, 0x70, 0xbd, 0x04, 0x76, /// 0x4b40 + 0x70, 0xbd, 0xf8, 0xb5, 0xea, 0x4c, 0x05, 0x21, + 0xa0, 0x8e, 0x89, 0x02, 0x08, 0x42, 0x7d, 0xd1, /// 0x4b50 + 0x01, 0x05, 0x7b, 0xd4, 0x81, 0x04, 0x79, 0xd4, + 0xc1, 0x07, 0x77, 0xd1, 0x41, 0x04, 0x75, 0xd4, /// 0x4b60 + 0xc1, 0x06, 0x73, 0xd4, 0x00, 0x04, 0x71, 0xd4, + 0xe0, 0x4e, 0x20, 0x46, 0x31, 0x7a, 0xa0, 0x30, /// 0x4b70 + 0x00, 0x90, 0x01, 0x29, 0x14, 0xd8, 0xb0, 0x7e, + 0x00, 0x28, 0x11, 0xd0, 0x06, 0x28, 0x0f, 0xd8, /// 0x4b80 + 0x23, 0x21, 0x00, 0x9a, 0x41, 0x43, 0xd2, 0x7f, + 0x40, 0x1c, 0x89, 0x18, 0xb0, 0x76, 0xff, 0x29, /// 0x4b90 + 0x02, 0xd3, 0xff, 0x21, 0x00, 0x20, 0xb0, 0x76, + 0xc9, 0xb2, 0x20, 0x8d, 0xff, 0xf7, 0xb7, 0xfe, /// 0x4ba0 + 0xd2, 0x48, 0xd3, 0x4e, 0x00, 0x7a, 0xd3, 0x4f, + 0x20, 0x36, 0x03, 0x28, 0x06, 0xd0, 0x06, 0xdc, /// 0x4bb0 + 0x00, 0x28, 0x25, 0xd0, 0x01, 0x28, 0x7a, 0xd0, + 0x02, 0x28, 0x69, 0xd1, 0x8e, 0xe0, 0x0b, 0x28, /// 0x4bc0 + 0x76, 0xd0, 0x0c, 0x28, 0x64, 0xd1, 0xf0, 0x7e, + 0xc1, 0x06, 0xca, 0x48, 0x40, 0x38, 0x00, 0x29, /// 0x4bd0 + 0x6f, 0xdb, 0x01, 0x8b, 0x49, 0x1c, 0x89, 0xb2, + 0x01, 0x83, 0xc7, 0x48, 0x81, 0x42, 0x0e, 0xd3, /// 0x4be0 + 0xa0, 0x8e, 0x08, 0x21, 0x08, 0x43, 0xa0, 0x86, + 0xc1, 0x48, 0x01, 0x22, 0x40, 0x38, 0xc1, 0x6a, /// 0x4bf0 + 0x11, 0x43, 0xc1, 0x62, 0x10, 0x46, 0xfb, 0xf7, + 0xaf, 0xff, 0xff, 0xf7, 0x29, 0xfe, 0x78, 0xe0, /// 0x4c00 + 0xbc, 0x48, 0xbe, 0x49, 0x20, 0x38, 0x00, 0x7e, + 0xc0, 0x00, 0xc0, 0x1c, 0x08, 0x80, 0xb7, 0x4d, /// 0x4c10 + 0xbb, 0x49, 0xe8, 0x7e, 0x00, 0x02, 0x00, 0x1d, + 0x88, 0x82, 0x78, 0x68, 0x29, 0x68, 0x0a, 0x23, /// 0x4c20 + 0x42, 0x1a, 0x71, 0x7e, 0x59, 0x43, 0x8a, 0x42, + 0x32, 0xd9, 0xb6, 0x49, 0x0a, 0x8d, 0xb0, 0x49, /// 0x4c30 + 0x40, 0x31, 0x0a, 0x82, 0x31, 0x7e, 0xc9, 0x07, + 0x41, 0xd0, 0x20, 0x8e, 0xb2, 0x49, 0x40, 0x18, /// 0x4c40 + 0xb2, 0x49, 0x88, 0x42, 0x25, 0xd2, 0xaa, 0x4e, + 0x40, 0x3e, 0x00, 0xe0, 0x20, 0xe0, 0xb0, 0x8e, /// 0x4c50 + 0x40, 0x07, 0x04, 0xd4, 0x02, 0x20, 0xfb, 0xf7, + 0x7f, 0xff, 0x30, 0x6b, 0xf0, 0x62, 0xff, 0x21, /// 0x4c60 + 0x70, 0x6b, 0x3d, 0x31, 0x08, 0x43, 0x70, 0x63, + 0xa8, 0x7e, 0x40, 0x1c, 0xa8, 0x76, 0x00, 0x98, /// 0x4c70 + 0xc1, 0x7f, 0x20, 0x8d, 0xff, 0xf7, 0x4b, 0xfe, + 0xa0, 0x48, 0x01, 0x88, 0x02, 0x22, 0x11, 0x43, /// 0x4c80 + 0x01, 0x80, 0x29, 0x7b, 0xc9, 0x07, 0x15, 0xd0, + 0x0c, 0x21, 0x29, 0x72, 0xfb, 0x21, 0x01, 0x80, /// 0x4c90 + 0xf8, 0xbd, 0xa0, 0x8e, 0x10, 0x21, 0x08, 0x43, + 0xa0, 0x86, 0x95, 0x48, 0x01, 0x22, 0x40, 0x38, /// 0x4ca0 + 0xc1, 0x6a, 0x11, 0x43, 0xc1, 0x62, 0x10, 0x46, + 0xfb, 0xf7, 0x56, 0xff, 0xf8, 0xbd, 0x08, 0xe0, /// 0x4cb0 + 0x14, 0xe0, 0x1c, 0xe0, 0x78, 0x68, 0x28, 0x60, + 0x01, 0x20, 0x28, 0x72, 0xf6, 0xe7, 0x28, 0x60, /// 0x4cc0 + 0xf4, 0xe7, 0x8a, 0x48, 0x79, 0x68, 0x00, 0x68, + 0x08, 0x1a, 0x5a, 0x28, 0xee, 0xd9, 0xa0, 0x8e, /// 0x4cd0 + 0x8f, 0x49, 0x08, 0x40, 0xa0, 0x86, 0xff, 0xf7, + 0x0b, 0xff, 0x05, 0xe0, 0x83, 0x48, 0x79, 0x68, /// 0x4ce0 + 0x00, 0x68, 0x08, 0x1a, 0xaa, 0x28, 0xe1, 0xd9, + 0xff, 0xf7, 0xb2, 0xfd, 0xde, 0xe7, 0x00, 0x21, /// 0x4cf0 + 0x01, 0x83, 0x00, 0x98, 0x40, 0x7a, 0x00, 0x28, + 0x45, 0xd0, 0x7c, 0x48, 0x79, 0x68, 0x00, 0x68, /// 0x4d00 + 0x08, 0x1a, 0xff, 0x21, 0x91, 0x31, 0x88, 0x42, + 0x07, 0xd9, 0xf2, 0x7e, 0x08, 0x23, 0x1a, 0x43, /// 0x4d10 + 0xf2, 0x76, 0xfc, 0xf7, 0x59, 0xfe, 0xc5, 0xb2, + 0x02, 0xe0, 0x7e, 0x49, 0x00, 0x20, 0x08, 0x71, /// 0x4d20 + 0xf0, 0x7e, 0x01, 0x07, 0x2f, 0xd5, 0xf7, 0x21, + 0x08, 0x40, 0xf0, 0x76, 0x03, 0x2d, 0x00, 0xd3, /// 0x4d30 + 0x00, 0x25, 0x78, 0x48, 0x01, 0x79, 0xa9, 0x42, + 0x0b, 0xd0, 0x71, 0x49, 0x05, 0x71, 0x88, 0x8a, /// 0x4d40 + 0x40, 0x05, 0x40, 0x0f, 0x40, 0x1c, 0x04, 0x28, + 0x00, 0xd9, 0x00, 0x20, 0x00, 0x02, 0x00, 0x1d, /// 0x4d50 + 0x88, 0x82, 0x02, 0x2d, 0x17, 0xd3, 0x65, 0x48, + 0x01, 0x7b, 0x0a, 0x07, 0x02, 0xd5, 0x42, 0x7e, /// 0x4d60 + 0x1e, 0x2a, 0x10, 0xd9, 0x08, 0x22, 0x11, 0x43, + 0x01, 0x73, 0x00, 0x21, 0x41, 0x76, 0x41, 0x79, /// 0x4d70 + 0x4a, 0x1d, 0xff, 0x2a, 0x01, 0xd2, 0x49, 0x1d, + 0x00, 0xe0, 0xff, 0x21, 0xc9, 0xb2, 0x41, 0x71, /// 0x4d80 + 0x60, 0x8c, 0xff, 0xf7, 0xc4, 0xfd, 0x59, 0x48, + 0x01, 0x7b, 0xc9, 0x07, 0x19, 0xd1, 0x79, 0x68, /// 0x4d90 + 0x00, 0x68, 0x09, 0x1a, 0x58, 0x48, 0x81, 0x42, + 0x13, 0xd9, 0x55, 0x48, 0xff, 0x22, 0x40, 0x38, /// 0x4da0 + 0x41, 0x6b, 0x3d, 0x32, 0x91, 0x43, 0x41, 0x63, + 0xa1, 0x8e, 0xff, 0x22, 0x01, 0x32, 0x11, 0x43, /// 0x4db0 + 0xa1, 0x86, 0xc1, 0x6a, 0x01, 0x22, 0x11, 0x43, + 0xc1, 0x62, 0x10, 0x46, 0xfb, 0xf7, 0xcc, 0xfe, /// 0x4dc0 + 0x92, 0xe7, 0xe0, 0x8e, 0xc0, 0x06, 0x12, 0xd5, + 0xa0, 0x8f, 0x41, 0x1c, 0xa1, 0x87, 0xe1, 0x8f, /// 0x4dd0 + 0x88, 0x42, 0x8b, 0xd9, 0xa0, 0x8e, 0x80, 0x21, + 0x08, 0x43, 0xa0, 0x86, 0xff, 0xf7, 0x27, 0xfd, /// 0x4de0 + 0x00, 0x20, 0xa0, 0x87, 0xe0, 0x8e, 0x10, 0x21, + 0x88, 0x43, 0xe0, 0x86, 0x5e, 0xe7, 0x00, 0x20, /// 0x4df0 + 0xa0, 0x87, 0x5b, 0xe7, 0x10, 0xb5, 0x48, 0x48, + 0x80, 0x89, 0x80, 0x06, 0x80, 0x0f, 0x12, 0xd0, /// 0x4e00 + 0x3b, 0x49, 0x88, 0x8e, 0x42, 0x04, 0x0e, 0xd4, + 0x01, 0x22, 0x92, 0x03, 0x10, 0x43, 0x88, 0x86, /// 0x4e10 + 0x08, 0x46, 0x40, 0x38, 0xc1, 0x6a, 0x01, 0x22, + 0x11, 0x43, 0xc1, 0x62, 0x10, 0x46, 0xfb, 0xf7, /// 0x4e20 + 0x9b, 0xfe, 0xff, 0xf7, 0x15, 0xfd, 0x10, 0xbd, + 0xf8, 0xb5, 0x31, 0x4c, 0x01, 0x27, 0x20, 0x8e, /// 0x4e30 + 0x21, 0x8c, 0x25, 0x46, 0x40, 0x3d, 0x2d, 0x4e, + 0x88, 0x42, 0x13, 0xd2, 0xa1, 0x8e, 0xc8, 0x04, /// 0x4e40 + 0x12, 0xd4, 0x72, 0x7b, 0x50, 0x1c, 0x70, 0x73, + 0x28, 0x2a, 0x0d, 0xd9, 0x38, 0x03, 0x01, 0x43, /// 0x4e50 + 0xa1, 0x86, 0xe8, 0x6a, 0x38, 0x43, 0xe8, 0x62, + 0x01, 0x20, 0xfb, 0xf7, 0x7d, 0xfe, 0xff, 0xf7, /// 0x4e60 + 0xf7, 0xfc, 0x01, 0xe0, 0x00, 0x20, 0x70, 0x73, + 0x62, 0x8e, 0xa0, 0x8d, 0x01, 0x21, 0xc9, 0x02, /// 0x4e70 + 0x82, 0x42, 0x0d, 0xd9, 0xa0, 0x8e, 0x02, 0x05, + 0x12, 0xd4, 0x08, 0x43, 0xa0, 0x86, 0xe8, 0x6a, /// 0x4e80 + 0x38, 0x43, 0xe8, 0x62, 0x01, 0x20, 0xfb, 0xf7, + 0x67, 0xfe, 0xff, 0xf7, 0xe1, 0xfc, 0x07, 0xe0, /// 0x4e90 + 0x19, 0x4b, 0x5b, 0x42, 0xc0, 0x18, 0x82, 0x42, + 0x02, 0xda, 0xa0, 0x8e, 0x88, 0x43, 0xa0, 0x86, /// 0x4ea0 + 0x30, 0x8a, 0x61, 0x8d, 0x88, 0x42, 0x06, 0xd8, + 0x1a, 0x48, 0x2e, 0x21, 0x40, 0x30, 0x61, 0x5e, /// 0x4eb0 + 0x40, 0x88, 0x81, 0x42, 0x0e, 0xdd, 0xa0, 0x8e, + 0x41, 0x05, 0x0b, 0xd4, 0x01, 0x21, 0x89, 0x02, /// 0x4ec0 + 0x08, 0x43, 0xa0, 0x86, 0xe8, 0x6a, 0x38, 0x43, + 0xe8, 0x62, 0x01, 0x20, 0xfb, 0xf7, 0x44, 0xfe, /// 0x4ed0 + 0xff, 0xf7, 0xbe, 0xfc, 0x61, 0x8d, 0x06, 0x48, + 0x33, 0x8a, 0x0a, 0x46, 0xc8, 0x3a, 0x20, 0x30, /// 0x4ee0 + 0x93, 0x42, 0x1f, 0xdd, 0xc2, 0x7e, 0x54, 0x07, + 0x1c, 0xd4, 0x17, 0xe0, 0x70, 0x04, 0x00, 0x20, /// 0x4ef0 + 0x40, 0x00, 0x00, 0x20, 0x30, 0x02, 0x00, 0x20, + 0xdc, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x40, /// 0x4f00 + 0x60, 0x40, 0x00, 0x40, 0x70, 0x03, 0x00, 0x20, + 0x8f, 0xe8, 0xff, 0xff, 0xcf, 0x07, 0x00, 0x00, /// 0x4f10 + 0xfe, 0xc3, 0xff, 0xff, 0x30, 0x01, 0x00, 0x20, + 0x20, 0x48, 0x00, 0x40, 0x04, 0x21, 0x0a, 0x43, /// 0x4f20 + 0xc2, 0x76, 0xc3, 0xe6, 0xff, 0x39, 0x2d, 0x39, + 0x8b, 0x42, 0xfa, 0xda, 0xc1, 0x7e, 0x4a, 0x07, /// 0x4f30 + 0xf7, 0xd5, 0xfb, 0x22, 0x11, 0x40, 0xc1, 0x76, + 0xb8, 0xe6, 0xfe, 0x49, 0x3a, 0x22, 0x8a, 0x5e, /// 0x4f40 + 0x89, 0x8f, 0x42, 0x43, 0xd0, 0x0a, 0x40, 0x18, + 0x00, 0xb2, 0x00, 0x28, 0x00, 0xda, 0x00, 0x20, /// 0x4f50 + 0x80, 0xb2, 0x70, 0x47, 0xf8, 0xb5, 0xf7, 0x4e, + 0x02, 0x21, 0x60, 0x3e, 0xf0, 0x7e, 0x09, 0x22, /// 0x4f60 + 0x08, 0x43, 0xf0, 0x76, 0x04, 0x21, 0x00, 0x20, + 0xfb, 0xf7, 0xef, 0xfa, 0xf2, 0x49, 0x88, 0x42, /// 0x4f70 + 0x7e, 0xd0, 0x09, 0x22, 0x04, 0x21, 0x00, 0x20, + 0xfb, 0xf7, 0xe7, 0xfa, 0xef, 0x4d, 0x40, 0x08, /// 0x4f80 + 0xa9, 0x7c, 0x2c, 0x46, 0x4a, 0x00, 0xee, 0x49, + 0x20, 0x3c, 0x52, 0x18, 0x09, 0x21, 0x89, 0x01, /// 0x4f90 + 0x51, 0x18, 0x08, 0x83, 0x20, 0x8b, 0x61, 0x8b, + 0xe2, 0x8b, 0x40, 0x18, 0xa1, 0x8b, 0x89, 0x18, /// 0x4fa0 + 0x40, 0x18, 0x81, 0x08, 0xe7, 0x48, 0x00, 0x88, + 0x08, 0x1a, 0x00, 0xb2, 0x00, 0x28, 0x00, 0xda, /// 0x4fb0 + 0x00, 0x20, 0x80, 0x01, 0x0a, 0x21, 0xfc, 0xf7, + 0x1d, 0xfd, 0xde, 0x49, 0xdd, 0x4f, 0xc0, 0x39, /// 0x4fc0 + 0x89, 0x78, 0x80, 0x3f, 0x80, 0xb2, 0x05, 0x29, + 0x04, 0xd3, 0x3b, 0x21, 0x48, 0x43, 0x32, 0x21, /// 0x4fd0 + 0xfc, 0xf7, 0xfa, 0xfc, 0x78, 0x86, 0x03, 0x22, + 0x04, 0x21, 0x01, 0x20, 0xfb, 0xf7, 0xb5, 0xfa, /// 0x4fe0 + 0xd5, 0x49, 0x88, 0x42, 0x44, 0xd0, 0x03, 0x22, + 0x04, 0x21, 0x01, 0x20, 0xfb, 0xf7, 0xad, 0xfa, /// 0x4ff0 + 0xc0, 0x03, 0x01, 0x0c, 0xa8, 0x7c, 0x42, 0x00, + 0xd1, 0x48, 0x12, 0x18, 0x09, 0x20, 0x80, 0x01, /// 0x5000 + 0x10, 0x18, 0x01, 0x85, 0xcd, 0x48, 0x08, 0x30, + 0xfb, 0xf7, 0xdb, 0xfa, 0x00, 0xb2, 0x00, 0x28, /// 0x5010 + 0x00, 0xda, 0x00, 0x20, 0xff, 0xf7, 0x91, 0xff, + 0x00, 0xb2, 0xcb, 0x4a, 0xf8, 0x85, 0xd1, 0x7b, /// 0x5020 + 0x49, 0x1c, 0xc9, 0xb2, 0xd1, 0x73, 0x05, 0x29, + 0x12, 0xd3, 0x00, 0x21, 0xd1, 0x73, 0x91, 0x8a, /// 0x5030 + 0x08, 0x18, 0x80, 0xb2, 0x90, 0x82, 0x91, 0x7c, + 0x49, 0x1c, 0xc9, 0xb2, 0x91, 0x74, 0x0f, 0x29, /// 0x5040 + 0x06, 0xd3, 0xfc, 0xf7, 0xc1, 0xfc, 0xc0, 0x49, + 0x08, 0x82, 0x00, 0x20, 0x88, 0x74, 0x88, 0x82, /// 0x5050 + 0x02, 0x22, 0x08, 0x21, 0x03, 0x20, 0xfb, 0xf7, + 0x78, 0xfa, 0xb7, 0x49, 0x88, 0x42, 0x43, 0xd0, /// 0x5060 + 0x02, 0x22, 0x08, 0x21, 0x03, 0x20, 0xfb, 0xf7, + 0x70, 0xfa, 0xa9, 0x7c, 0x4a, 0x00, 0x00, 0xe0, /// 0x5070 + 0x3a, 0xe0, 0xb3, 0x49, 0x52, 0x18, 0x09, 0x21, + 0x89, 0x01, 0x51, 0x18, 0x08, 0x84, 0x20, 0x8c, /// 0x5080 + 0x61, 0x8c, 0xe2, 0x8c, 0x40, 0x18, 0xa1, 0x8c, + 0x89, 0x18, 0x40, 0x18, 0x81, 0x08, 0xad, 0x48, /// 0x5090 + 0x00, 0x88, 0x08, 0x1a, 0x00, 0xb2, 0x00, 0x28, + 0x00, 0xda, 0x00, 0x20, 0x29, 0x21, 0x48, 0x43, /// 0x50a0 + 0xc1, 0x17, 0x49, 0x0f, 0x08, 0x18, 0x40, 0x03, + 0x00, 0x0c, 0x38, 0x86, 0x04, 0x22, 0x08, 0x21, /// 0x50b0 + 0x07, 0x20, 0xfb, 0xf7, 0x4a, 0xfa, 0xa0, 0x49, + 0x88, 0x42, 0x15, 0xd0, 0x04, 0x22, 0x08, 0x21, /// 0x50c0 + 0x07, 0x20, 0xfb, 0xf7, 0x42, 0xfa, 0xa1, 0x49, + 0x88, 0x42, 0x00, 0xd2, 0x08, 0x46, 0x4b, 0x21, /// 0x50d0 + 0x48, 0x43, 0x7d, 0x21, 0xc9, 0x00, 0xfc, 0xf7, + 0x77, 0xfc, 0xae, 0x38, 0xb0, 0x76, 0xa8, 0x7c, /// 0x50e0 + 0x03, 0x28, 0x03, 0xd3, 0x00, 0x20, 0x02, 0xe0, + 0x00, 0x20, 0xdf, 0xe5, 0x40, 0x1c, 0xa8, 0x74, /// 0x50f0 + 0xff, 0xf7, 0x9a, 0xfe, 0xff, 0xf7, 0x7e, 0xfe, + 0xf6, 0xe7, 0x90, 0x49, 0x10, 0xb5, 0x01, 0x20, /// 0x5100 + 0x20, 0x39, 0x48, 0x73, 0x92, 0x49, 0x00, 0x20, + 0x08, 0x70, 0x92, 0x48, 0x69, 0x22, 0x02, 0x71, /// 0x5110 + 0x63, 0x24, 0x44, 0x71, 0x02, 0x72, 0x02, 0x23, + 0x43, 0x72, 0x02, 0x73, 0x44, 0x73, 0x02, 0x74, /// 0x5120 + 0x24, 0x22, 0x42, 0x74, 0xb4, 0x22, 0x0a, 0x70, + 0x84, 0x4a, 0xc8, 0x3a, 0x0a, 0x81, 0x07, 0x22, /// 0x5130 + 0x8a, 0x80, 0x87, 0x49, 0x20, 0x39, 0x0b, 0x72, + 0x0a, 0x79, 0x72, 0xb6, 0x1a, 0x43, 0x0a, 0x71, /// 0x5140 + 0x84, 0x49, 0x62, 0xb6, 0x20, 0x31, 0x0a, 0x7a, + 0xfb, 0x23, 0x1a, 0x40, 0x0a, 0x72, 0x01, 0x88, /// 0x5150 + 0x10, 0x22, 0x11, 0x43, 0x01, 0x80, 0x10, 0xbd, + 0x7f, 0x49, 0x03, 0x20, 0x08, 0x80, 0x70, 0x47, /// 0x5160 + 0x7d, 0x49, 0x5a, 0x20, 0x20, 0x39, 0x08, 0x70, + 0x7b, 0x49, 0x08, 0x80, 0x71, 0x48, 0x60, 0x38, /// 0x5170 + 0xc1, 0x7e, 0x49, 0x08, 0x49, 0x00, 0xc1, 0x76, + 0x70, 0x47, 0x77, 0x48, 0x10, 0xb5, 0x5a, 0x21, /// 0x5180 + 0x20, 0x38, 0x01, 0x70, 0x81, 0x8a, 0x42, 0x14, + 0x11, 0x43, 0x81, 0x82, 0x71, 0x49, 0x0a, 0x88, /// 0x5190 + 0x83, 0x14, 0x1a, 0x43, 0x0a, 0x80, 0x71, 0x49, + 0x01, 0x82, 0x71, 0x49, 0x01, 0x83, 0x09, 0x21, /// 0x51a0 + 0x01, 0x72, 0x70, 0x49, 0x81, 0x81, 0x70, 0x48, + 0x01, 0x21, 0x01, 0x80, 0xff, 0x22, 0x82, 0x80, /// 0x51b0 + 0x05, 0x22, 0x02, 0x81, 0x60, 0x4a, 0x82, 0x81, + 0x07, 0x23, 0x03, 0x80, 0x6a, 0x4b, 0x6b, 0x4c, /// 0x51c0 + 0x20, 0x33, 0x1c, 0x80, 0x5f, 0x4c, 0x40, 0x34, + 0xa4, 0x78, 0x0c, 0x43, 0x1c, 0x71, 0x02, 0x82, /// 0x51d0 + 0x00, 0x22, 0x02, 0x75, 0x66, 0x48, 0x01, 0x81, + 0x59, 0x48, 0xe0, 0x30, 0x00, 0x7e, 0xc2, 0x00, /// 0x51e0 + 0x63, 0x48, 0x40, 0x38, 0xd2, 0x1c, 0x02, 0x80, + 0x81, 0x80, 0x30, 0x21, 0x81, 0x81, 0x10, 0xbd, /// 0x51f0 + 0x10, 0xb5, 0xff, 0xf7, 0x01, 0xfb, 0xff, 0xf7, + 0x0f, 0xfc, 0xfe, 0xf7, 0x25, 0xff, 0x00, 0x20, /// 0x5200 + 0x10, 0xbd, 0x55, 0x49, 0x5a, 0x20, 0x20, 0x39, + 0x08, 0x70, 0x53, 0x48, 0xc8, 0x21, 0x81, 0x80, /// 0x5210 + 0x04, 0x21, 0x01, 0x73, 0x01, 0x21, 0x01, 0x80, + 0x46, 0x48, 0x60, 0x38, 0xc2, 0x7e, 0x0a, 0x43, /// 0x5220 + 0xc2, 0x76, 0x70, 0x47, 0xf8, 0xb5, 0x43, 0x4c, + 0x80, 0x3c, 0xe0, 0x8e, 0x81, 0x07, 0x04, 0xd5, /// 0x5230 + 0x02, 0x21, 0x88, 0x43, 0xe0, 0x86, 0xfb, 0xf7, + 0x9e, 0xfc, 0xe0, 0x8e, 0x08, 0x26, 0xc1, 0x07, /// 0x5240 + 0x00, 0x29, 0x1f, 0xd0, 0x40, 0x08, 0x3b, 0x4b, + 0x40, 0x00, 0xe0, 0x86, 0x60, 0x3b, 0x18, 0x7e, /// 0x5250 + 0x02, 0x28, 0x1e, 0xd1, 0xff, 0xf7, 0xd5, 0xff, + 0x01, 0x20, 0x3f, 0x4d, 0x18, 0x76, 0x20, 0x3d, /// 0x5260 + 0xa8, 0x8b, 0x30, 0x43, 0xa8, 0x83, 0x64, 0x20, + 0xfb, 0xf7, 0xde, 0xfb, 0xa8, 0x8b, 0x11, 0x21, /// 0x5270 + 0x08, 0x43, 0xa8, 0x83, 0xa8, 0x8b, 0x69, 0x15, + 0x08, 0x43, 0xa8, 0x83, 0x3d, 0x48, 0xfa, 0xf7, /// 0x5280 + 0x06, 0xff, 0x06, 0xe0, 0x41, 0x07, 0x04, 0xd5, + 0x04, 0x21, 0x88, 0x43, 0xe0, 0x86, 0xff, 0xf7, /// 0x5290 + 0xce, 0xfa, 0x28, 0x49, 0x20, 0x31, 0xc8, 0x7c, + 0x00, 0x28, 0x02, 0xd0, 0x40, 0x1e, 0xc8, 0x74, /// 0x52a0 + 0x25, 0xe0, 0xe0, 0x8e, 0x00, 0x07, 0x22, 0xd5, + 0x20, 0x7e, 0xfd, 0xf7, 0x1f, 0xf8, 0x05, 0x46, /// 0x52b0 + 0x0a, 0x28, 0x19, 0xd2, 0x1f, 0x48, 0x69, 0x1c, + 0x68, 0x38, 0x07, 0x46, 0xfb, 0xf7, 0x18, 0xfe, /// 0x52c0 + 0x1c, 0x49, 0xc0, 0x39, 0x49, 0x19, 0x40, 0x31, + 0x48, 0x76, 0xa8, 0x1c, 0x82, 0xb2, 0x1e, 0x48, /// 0x52d0 + 0x39, 0x46, 0x2c, 0x30, 0x07, 0x46, 0x00, 0xf0, + 0x90, 0xf9, 0x16, 0x20, 0x45, 0x43, 0x2e, 0x35, /// 0x52e0 + 0xa9, 0xb2, 0x38, 0x46, 0x00, 0xf0, 0x71, 0xf9, + 0xe0, 0x8e, 0xb0, 0x43, 0xe0, 0x86, 0xe0, 0x8e, /// 0x52f0 + 0x41, 0x06, 0x05, 0xd5, 0x40, 0x21, 0x88, 0x43, + 0xe0, 0x86, 0xff, 0x20, 0x95, 0x30, 0x20, 0x85, /// 0x5300 + 0x00, 0x20, 0xd3, 0xe4, 0xf8, 0xb5, 0x10, 0x48, + 0x01, 0x7b, 0x88, 0x07, 0x05, 0xd4, 0x0e, 0x48, /// 0x5310 + 0x02, 0x22, 0x11, 0x43, 0x01, 0x73, 0xfe, 0xf7, + 0x61, 0xfc, 0x06, 0x4f, 0x08, 0x4c, 0x60, 0x3f, /// 0x5320 + 0x38, 0x7e, 0x3e, 0x46, 0xc1, 0x07, 0x00, 0x25, + 0x20, 0x3e, 0x00, 0x29, 0x26, 0xd0, 0x06, 0x49, /// 0x5330 + 0x09, 0x7a, 0x21, 0xe0, 0xc0, 0x00, 0x00, 0x20, + 0xff, 0xff, 0x00, 0x00, 0x90, 0x03, 0x00, 0x20, /// 0x5340 + 0x30, 0x01, 0x00, 0x20, 0x20, 0x67, 0x00, 0x00, + 0x70, 0x04, 0x00, 0x20, 0x5a, 0x0a, 0x00, 0x00, /// 0x5350 + 0x20, 0x60, 0x00, 0x40, 0x00, 0x44, 0x00, 0x40, + 0x20, 0x30, 0x00, 0x40, 0xff, 0x07, 0x00, 0x00, /// 0x5360 + 0x7f, 0x3f, 0x00, 0x00, 0x05, 0x1d, 0x00, 0x00, + 0x00, 0x38, 0x00, 0x40, 0x08, 0x80, 0x00, 0x00, /// 0x5370 + 0x40, 0x34, 0x00, 0x40, 0xf1, 0x51, 0x00, 0x00, + 0x00, 0x29, 0x25, 0xd1, 0x00, 0x07, 0x23, 0xd4, /// 0x5380 + 0xa0, 0x78, 0x00, 0x28, 0x02, 0xd0, 0x40, 0x1e, + 0xa0, 0x70, 0x1e, 0xe0, 0x49, 0x48, 0x01, 0x78, /// 0x5390 + 0x09, 0x07, 0x19, 0xd5, 0x01, 0x78, 0x08, 0x22, + 0x11, 0x43, 0x01, 0x70, 0xe0, 0x78, 0x40, 0x1c, /// 0x53a0 + 0xc0, 0xb2, 0xe0, 0x70, 0x0a, 0x28, 0x10, 0xd3, + 0xe5, 0x70, 0xb0, 0x8e, 0x11, 0x03, 0x08, 0x43, /// 0x53b0 + 0xb0, 0x86, 0x40, 0x20, 0xfb, 0xf7, 0xd0, 0xfb, + 0x3f, 0x48, 0x40, 0x22, 0xc1, 0x6a, 0x11, 0x43, /// 0x53c0 + 0xc1, 0x62, 0xff, 0xf7, 0x45, 0xfa, 0x00, 0xe0, + 0xe5, 0x70, 0xf8, 0x7e, 0xc1, 0x07, 0x07, 0xd0, /// 0x53d0 + 0x81, 0x07, 0x05, 0xd5, 0x39, 0x4a, 0x03, 0x21, + 0x11, 0x80, 0xfd, 0x21, 0x08, 0x40, 0xf8, 0x76, /// 0x53e0 + 0x37, 0x48, 0x01, 0x7a, 0x0c, 0x29, 0x07, 0xd0, + 0x45, 0x76, 0xe5, 0x80, 0x65, 0x71, 0x35, 0x48, /// 0x53f0 + 0x40, 0x7b, 0x00, 0x28, 0x3d, 0xd0, 0x40, 0xe0, + 0x01, 0x7b, 0x09, 0x07, 0x03, 0xd5, 0x41, 0x7e, /// 0x5400 + 0x49, 0x1c, 0x41, 0x76, 0x00, 0xe0, 0x45, 0x76, + 0xe0, 0x88, 0x4b, 0x21, 0x40, 0x1c, 0x80, 0xb2, /// 0x5410 + 0xc9, 0x01, 0xe0, 0x80, 0x88, 0x42, 0x17, 0xd2, + 0x19, 0x21, 0x89, 0x01, 0xfc, 0xf7, 0xd4, 0xfa, /// 0x5420 + 0xc0, 0xb2, 0x05, 0x28, 0x00, 0xd9, 0x00, 0x20, + 0x61, 0x79, 0x81, 0x42, 0xdf, 0xd0, 0x26, 0x49, /// 0x5430 + 0x60, 0x71, 0x88, 0x8a, 0x40, 0x05, 0x40, 0x0f, + 0x40, 0x1c, 0x04, 0x28, 0x00, 0xd9, 0x00, 0x20, /// 0x5440 + 0x00, 0x02, 0x00, 0x1d, 0x88, 0x82, 0xd2, 0xe7, + 0x1b, 0x48, 0xff, 0x22, 0x41, 0x6b, 0x3d, 0x32, /// 0x5450 + 0x91, 0x43, 0x41, 0x63, 0xb1, 0x8e, 0xff, 0x22, + 0x01, 0x32, 0x11, 0x43, 0xb1, 0x86, 0xc1, 0x6a, /// 0x5460 + 0x01, 0x22, 0x11, 0x43, 0xc1, 0x62, 0x10, 0x46, + 0xfb, 0xf7, 0x76, 0xfb, 0xff, 0xf7, 0xf0, 0xf9, /// 0x5470 + 0xbd, 0xe7, 0xff, 0xf7, 0x42, 0xfe, 0xff, 0xf7, + 0x6d, 0xfd, 0x14, 0x48, 0x00, 0x7f, 0x41, 0x07, /// 0x5480 + 0x13, 0x48, 0x00, 0x29, 0x0d, 0xdb, 0xc1, 0x7f, + 0x49, 0x1c, 0xc9, 0xb2, 0xc1, 0x77, 0x64, 0x29, /// 0x5490 + 0x08, 0xd3, 0xc5, 0x77, 0x08, 0x48, 0x02, 0x21, + 0x05, 0x63, 0xf0, 0x8e, 0x08, 0x43, 0xf0, 0x86, /// 0x54a0 + 0x00, 0xe0, 0xc5, 0x77, 0xff, 0xf7, 0x72, 0xf9, + 0xff, 0xf7, 0x4b, 0xfb, 0x00, 0xf0, 0xc6, 0xf9, /// 0x54b0 + 0x00, 0x20, 0x03, 0xe4, 0x00, 0x3c, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x20, 0x20, 0x30, 0x00, 0x40, /// 0x54c0 + 0x70, 0x04, 0x00, 0x20, 0x70, 0x03, 0x00, 0x20, + 0x60, 0x40, 0x00, 0x40, 0x20, 0x6c, 0x00, 0x40, /// 0x54d0 + 0xf0, 0x01, 0x00, 0x20, 0xc2, 0x48, 0x01, 0x8b, + 0x89, 0x06, 0x02, 0xd5, 0xc1, 0x49, 0x01, 0x22, /// 0x54e0 + 0x0a, 0x72, 0x30, 0x21, 0x01, 0x83, 0x70, 0x47, + 0x70, 0xb5, 0xbf, 0x48, 0xbf, 0x4d, 0x41, 0x8c, /// 0x54f0 + 0x28, 0x46, 0xfc, 0xf7, 0x69, 0xfa, 0xba, 0x4a, + 0x81, 0x21, 0x11, 0x80, 0x01, 0x24, 0x14, 0x80, /// 0x5500 + 0x35, 0x21, 0x11, 0x80, 0x07, 0x21, 0x91, 0x80, + 0x14, 0x81, 0x80, 0x21, 0x91, 0x81, 0xb8, 0x4a, /// 0x5510 + 0xf9, 0x21, 0x11, 0x80, 0x03, 0x21, 0x91, 0x80, + 0xff, 0x21, 0x11, 0x80, 0xc1, 0x1c, 0x28, 0x46, /// 0x5520 + 0xfc, 0xf7, 0x52, 0xfa, 0xb2, 0x49, 0x40, 0x31, + 0x08, 0x80, 0xb1, 0x48, 0x20, 0x30, 0x03, 0x8b, /// 0x5530 + 0xac, 0x4a, 0x20, 0x32, 0x13, 0x81, 0x03, 0x89, + 0x53, 0x81, 0x03, 0x8a, 0x93, 0x81, 0x03, 0x88, /// 0x5540 + 0xd3, 0x81, 0x03, 0x8b, 0x0a, 0x88, 0x52, 0x1e, + 0x93, 0x42, 0x02, 0xdd, 0x0a, 0x88, 0x52, 0x1e, /// 0x5550 + 0x02, 0x83, 0x03, 0x88, 0x0a, 0x88, 0x52, 0x1e, + 0x93, 0x42, 0x02, 0xdd, 0x0a, 0x88, 0x52, 0x1e, /// 0x5560 + 0x02, 0x80, 0x03, 0x8a, 0x0a, 0x88, 0x52, 0x1e, + 0x93, 0x42, 0x02, 0xdd, 0x0a, 0x88, 0x52, 0x1e, /// 0x5570 + 0x02, 0x82, 0x03, 0x89, 0x0a, 0x88, 0x52, 0x1e, + 0x93, 0x42, 0x02, 0xdd, 0x0a, 0x88, 0x52, 0x1e, /// 0x5580 + 0x02, 0x81, 0x30, 0x20, 0x88, 0x80, 0x0c, 0x81, + 0x70, 0xbd, 0x96, 0x48, 0x98, 0x49, 0x20, 0x30, /// 0x5590 + 0x02, 0x89, 0x20, 0x31, 0x0a, 0x83, 0x42, 0x89, + 0x0a, 0x81, 0x82, 0x89, 0x0a, 0x82, 0xc0, 0x89, /// 0x55a0 + 0x08, 0x80, 0x8f, 0x48, 0x01, 0x21, 0x01, 0x80, + 0x03, 0x21, 0x01, 0x80, 0x90, 0x49, 0xfb, 0x20, /// 0x55b0 + 0x08, 0x80, 0x70, 0x47, 0x8b, 0x4b, 0x00, 0x22, + 0x1a, 0x72, 0x89, 0x4a, 0x10, 0x82, 0x49, 0x1e, /// 0x55c0 + 0x11, 0x75, 0x18, 0x7a, 0x00, 0x28, 0xfc, 0xd0, + 0x70, 0x47, 0x70, 0xb5, 0x0c, 0x46, 0x05, 0x46, /// 0x55d0 + 0xff, 0xf7, 0x8a, 0xff, 0x08, 0xe0, 0x28, 0x88, + 0x10, 0x2c, 0x0a, 0xd9, 0x10, 0x21, 0xad, 0x1c, /// 0x55e0 + 0xff, 0xf7, 0xe8, 0xff, 0x10, 0x3c, 0xa4, 0xb2, + 0x00, 0x2c, 0xf4, 0xd1, 0xff, 0xf7, 0xcd, 0xff, /// 0x55f0 + 0x70, 0xbd, 0x21, 0x46, 0xff, 0xf7, 0xde, 0xff, + 0xf8, 0xe7, 0xf0, 0xb5, 0x00, 0x23, 0x02, 0x27, /// 0x5600 + 0x1c, 0x46, 0x9e, 0x46, 0x1d, 0x46, 0x8b, 0x54, + 0x05, 0xe0, 0x0e, 0x5d, 0xed, 0xb2, 0x75, 0x40, /// 0x5610 + 0x64, 0x1c, 0x8d, 0x54, 0xe4, 0xb2, 0x94, 0x42, + 0xf7, 0xd3, 0x52, 0x1c, 0x92, 0xb2, 0x94, 0x46, /// 0x5620 + 0x00, 0x22, 0x70, 0x4d, 0x14, 0x46, 0x20, 0x3d, + 0x56, 0x00, 0x76, 0x19, 0x52, 0x1c, 0xd2, 0xb2, /// 0x5630 + 0xb4, 0x85, 0x1c, 0x2a, 0xf8, 0xd3, 0x73, 0xe0, + 0x00, 0x2b, 0x01, 0xd0, 0x00, 0x23, 0x05, 0xe0, /// 0x5640 + 0x02, 0x78, 0x03, 0x23, 0xbb, 0x40, 0x1a, 0x43, + 0x02, 0x70, 0x01, 0x23, 0xbf, 0x1c, 0xfa, 0xb2, /// 0x5650 + 0x08, 0x2a, 0x01, 0xd1, 0x00, 0x22, 0x40, 0x1c, + 0x00, 0x24, 0x0d, 0x78, 0xe5, 0x40, 0xef, 0x07, /// 0x5660 + 0xff, 0x0f, 0x12, 0xd0, 0x00, 0x2b, 0x06, 0xd0, + 0x03, 0x78, 0x02, 0x25, 0x95, 0x40, 0x2b, 0x43, /// 0x5670 + 0x03, 0x70, 0x01, 0x23, 0x04, 0xe0, 0x05, 0x78, + 0x01, 0x26, 0x96, 0x40, 0x35, 0x43, 0x05, 0x70, /// 0x5680 + 0x75, 0x46, 0xed, 0x19, 0xed, 0xb2, 0xae, 0x46, + 0x09, 0xe0, 0x00, 0x2b, 0x01, 0xd0, 0x00, 0x23, /// 0x5690 + 0x05, 0xe0, 0x03, 0x78, 0x03, 0x25, 0x95, 0x40, + 0x2b, 0x43, 0x03, 0x70, 0x01, 0x23, 0x92, 0x1c, /// 0x56a0 + 0xd2, 0xb2, 0x08, 0x2a, 0x01, 0xd1, 0x00, 0x22, + 0x40, 0x1c, 0x64, 0x1c, 0xe4, 0xb2, 0x08, 0x2c, /// 0x56b0 + 0xd3, 0xd3, 0x74, 0x46, 0xe4, 0x07, 0x0d, 0xd0, + 0x00, 0x2b, 0x05, 0xd0, 0x03, 0x78, 0x02, 0x24, /// 0x56c0 + 0x94, 0x40, 0x23, 0x43, 0x03, 0x70, 0x0e, 0xe0, + 0x04, 0x78, 0x01, 0x25, 0x95, 0x40, 0x2c, 0x43, /// 0x56d0 + 0x04, 0x70, 0x09, 0xe0, 0x00, 0x2b, 0x01, 0xd0, + 0x00, 0x23, 0x05, 0xe0, 0x04, 0x78, 0x03, 0x23, /// 0x56e0 + 0x93, 0x40, 0x1c, 0x43, 0x04, 0x70, 0x01, 0x23, + 0x92, 0x1c, 0xd2, 0xb2, 0x08, 0x2a, 0x01, 0xd1, /// 0x56f0 + 0x00, 0x22, 0x40, 0x1c, 0x04, 0x78, 0x00, 0x2b, + 0x05, 0xd0, 0x02, 0x23, 0x93, 0x40, 0x1c, 0x43, /// 0x5700 + 0x04, 0x70, 0x01, 0x23, 0x03, 0xe0, 0x01, 0x25, + 0x95, 0x40, 0x2c, 0x43, 0x04, 0x70, 0x92, 0x1c, /// 0x5710 + 0xd7, 0xb2, 0x08, 0x2f, 0x01, 0xd1, 0x00, 0x27, + 0x40, 0x1c, 0x00, 0x22, 0x96, 0x46, 0x49, 0x1c, /// 0x5720 + 0x62, 0x46, 0x54, 0x1e, 0xa4, 0xb2, 0xa4, 0x46, + 0x00, 0x2a, 0x85, 0xd1, 0x00, 0x2b, 0x04, 0xd1, /// 0x5730 + 0x02, 0x78, 0x01, 0x21, 0xb9, 0x40, 0x0a, 0x43, + 0x02, 0x70, 0xf0, 0xbd, 0xf0, 0xb5, 0x00, 0x24, /// 0x5740 + 0x23, 0x46, 0x25, 0x46, 0x26, 0x46, 0x8c, 0x54, + 0x05, 0xe0, 0x4f, 0x5d, 0xf6, 0xb2, 0x7e, 0x40, /// 0x5750 + 0x6d, 0x1c, 0x8e, 0x54, 0xed, 0xb2, 0x95, 0x42, + 0xf7, 0xd3, 0x52, 0x1c, 0x92, 0xb2, 0x94, 0x46, /// 0x5760 + 0x00, 0x22, 0x20, 0x4e, 0x15, 0x46, 0x20, 0x3e, + 0x57, 0x00, 0xbf, 0x19, 0x52, 0x1c, 0xd2, 0xb2, /// 0x5770 + 0xbd, 0x85, 0x1c, 0x2a, 0xf8, 0xd3, 0x25, 0xe0, + 0x00, 0x22, 0x0d, 0x78, 0xd5, 0x40, 0xed, 0x07, /// 0x5780 + 0xed, 0x0f, 0x0a, 0xd0, 0x00, 0x2c, 0x02, 0xd0, + 0x04, 0x78, 0x02, 0x25, 0x0b, 0xe0, 0x05, 0x78, /// 0x5790 + 0x01, 0x26, 0x9e, 0x40, 0x35, 0x43, 0x05, 0x70, + 0x09, 0xe0, 0x00, 0x2c, 0x01, 0xd0, 0x00, 0x24, /// 0x57a0 + 0x05, 0xe0, 0x04, 0x78, 0x03, 0x25, 0x9d, 0x40, + 0x2c, 0x43, 0x04, 0x70, 0x01, 0x24, 0x9b, 0x1c, /// 0x57b0 + 0xdb, 0xb2, 0x08, 0x2b, 0x01, 0xd1, 0x00, 0x23, + 0x40, 0x1c, 0x52, 0x1c, 0xd2, 0xb2, 0x08, 0x2a, /// 0x57c0 + 0xdb, 0xd3, 0x49, 0x1c, 0x62, 0x46, 0x55, 0x1e, + 0xad, 0xb2, 0xac, 0x46, 0x00, 0x2a, 0xd3, 0xd1, /// 0x57d0 + 0x00, 0x2c, 0x04, 0xd1, 0x02, 0x78, 0x01, 0x21, + 0x99, 0x40, 0x0a, 0x43, 0x02, 0x70, 0xf0, 0xbd, /// 0x57e0 + 0x00, 0x38, 0x00, 0x40, 0x90, 0x04, 0x00, 0x20, + 0x40, 0x00, 0x00, 0x20, 0x60, 0xea, 0x00, 0x00, /// 0x57f0 + 0x00, 0x34, 0x00, 0x40, 0x65, 0x49, 0x0d, 0x20, + 0x08, 0x76, 0x65, 0x48, 0x01, 0x21, 0x01, 0x80, /// 0x5800 + 0x02, 0x15, 0x82, 0x80, 0x2b, 0x22, 0x02, 0x80, + 0x01, 0x81, 0x62, 0x49, 0x60, 0x4a, 0x0b, 0x8a, /// 0x5810 + 0x20, 0x32, 0x13, 0x80, 0x49, 0x8a, 0x91, 0x80, + 0x0f, 0x21, 0x01, 0x83, 0x08, 0x21, 0x81, 0x82, /// 0x5820 + 0x70, 0x47, 0x00, 0x28, 0x09, 0xd0, 0x00, 0x29, + 0x07, 0xd0, 0x81, 0x42, 0x01, 0xd9, 0x41, 0x1e, /// 0x5830 + 0x89, 0xb2, 0x57, 0x4a, 0x20, 0x32, 0x10, 0x80, + 0x91, 0x80, 0x70, 0x47, 0xf8, 0xb5, 0x56, 0x4b, /// 0x5840 + 0x54, 0x4c, 0x18, 0x7b, 0x61, 0x8a, 0xc2, 0x07, + 0x00, 0x2a, 0x05, 0xd0, 0x42, 0x07, 0x7d, 0xd5, /// 0x5850 + 0xfb, 0x22, 0x10, 0x40, 0x18, 0x73, 0x94, 0xe0, + 0x09, 0x22, 0x9a, 0x56, 0x00, 0x2a, 0x78, 0xd0, /// 0x5860 + 0x4d, 0x4d, 0x09, 0x20, 0x28, 0x56, 0x40, 0x42, + 0x00, 0x2a, 0x01, 0xdd, 0x15, 0x46, 0x00, 0xe0, /// 0x5870 + 0x05, 0x46, 0x4a, 0x4e, 0x00, 0x96, 0xb6, 0x7d, + 0xb5, 0x42, 0x01, 0xdd, 0x30, 0x46, 0x02, 0xe0, /// 0x5880 + 0x00, 0x2a, 0x00, 0xdd, 0x10, 0x46, 0x80, 0xb2, + 0x86, 0x46, 0x44, 0x48, 0x41, 0x4d, 0x20, 0x30, /// 0x5890 + 0xc6, 0x88, 0x40, 0x79, 0x80, 0x3d, 0x84, 0x46, + 0x3f, 0x48, 0x6f, 0x8c, 0x43, 0x79, 0x00, 0x2a, /// 0x58a0 + 0x2d, 0xdd, 0xff, 0x2b, 0x0c, 0xd2, 0x61, 0x46, + 0x59, 0x18, 0xff, 0x29, 0x00, 0xd3, 0xff, 0x21, /// 0x58b0 + 0x41, 0x71, 0x61, 0x46, 0x51, 0x1a, 0x00, 0x29, + 0x00, 0xdc, 0x00, 0x21, 0x41, 0x72, 0x2f, 0xe0, /// 0x58c0 + 0x36, 0x4b, 0x70, 0x46, 0x20, 0x3b, 0x1b, 0x8f, + 0x08, 0x1a, 0x98, 0x42, 0x07, 0xdd, 0x60, 0x82, /// 0x58d0 + 0x70, 0x46, 0x31, 0x49, 0x10, 0x1a, 0x00, 0x28, + 0x30, 0xdc, 0x00, 0x20, 0x2e, 0xe0, 0x99, 0x42, /// 0x58e0 + 0x0b, 0xd1, 0xe9, 0x8c, 0xb8, 0x19, 0x88, 0x42, + 0x00, 0xd3, 0x08, 0x46, 0x68, 0x84, 0x2a, 0x49, /// 0x58f0 + 0x90, 0x1b, 0x00, 0x28, 0x3c, 0xdd, 0x48, 0x72, + 0x12, 0xe0, 0x63, 0x82, 0x3b, 0xe0, 0xa8, 0x8c, /// 0x5900 + 0x87, 0x42, 0x0f, 0xd9, 0xb9, 0x1b, 0x81, 0x42, + 0x00, 0xdd, 0x08, 0x46, 0x80, 0xb2, 0x22, 0x4f, /// 0x5910 + 0x68, 0x84, 0x91, 0x19, 0x00, 0xd4, 0x00, 0x21, + 0x79, 0x72, 0x19, 0x46, 0xfe, 0xf7, 0xf7, 0xff, /// 0x5920 + 0x02, 0x20, 0x0d, 0xe0, 0x1d, 0x4e, 0x70, 0x46, + 0x20, 0x3e, 0x76, 0x8f, 0x08, 0x18, 0xb0, 0x42, /// 0x5930 + 0x10, 0xd2, 0x60, 0x82, 0x18, 0x49, 0x70, 0x46, + 0x10, 0x18, 0xce, 0xd5, 0x48, 0x72, 0x01, 0x20, /// 0x5940 + 0x81, 0x07, 0x1b, 0xd5, 0x14, 0x48, 0x41, 0x79, + 0x68, 0x8c, 0x00, 0xe0, 0x01, 0xe0, 0xfe, 0xf7, /// 0x5950 + 0xde, 0xff, 0xf8, 0xbd, 0xb1, 0x42, 0x0d, 0xd1, + 0x60, 0x46, 0x1b, 0x1a, 0x00, 0x98, 0x0e, 0x49, /// 0x5960 + 0xc0, 0x7f, 0x83, 0x42, 0x00, 0xdd, 0x18, 0x46, + 0x48, 0x71, 0x60, 0x46, 0x10, 0x18, 0xc2, 0xd4, /// 0x5970 + 0x00, 0x20, 0xc0, 0xe7, 0x66, 0x82, 0x00, 0x20, + 0x07, 0x49, 0xdf, 0xe7, 0xc0, 0x07, 0xe8, 0xd0, /// 0x5980 + 0x61, 0x8a, 0x20, 0x8a, 0xff, 0xf7, 0x4d, 0xff, + 0xf8, 0xbd, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x40, /// 0x5990 + 0x00, 0x50, 0x00, 0x40, 0xc0, 0x00, 0x00, 0x20, + 0x70, 0x04, 0x00, 0x20, 0x50, 0x01, 0x00, 0x20, /// 0x59a0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x59b0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x59c0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x59d0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x59e0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x59f0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5a00 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5a10 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5a20 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5a30 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5a40 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5a50 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5a60 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5a70 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5a80 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5a90 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5aa0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5ab0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5ac0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5ad0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5ae0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5af0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5b00 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5b10 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5b20 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5b30 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5b40 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5b50 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5b60 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5b70 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5b80 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5b90 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5ba0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5bb0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5bc0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5bd0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5be0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5bf0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5c00 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5c10 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5c20 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5c30 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5c40 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5c50 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5c60 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5c70 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5c80 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5c90 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5ca0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5cb0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5cc0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5cd0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5ce0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5cf0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5d00 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5d10 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5d20 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5d30 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5d40 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5d50 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5d60 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5d70 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5d80 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5d90 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5da0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5db0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5dc0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5dd0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5de0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5df0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5e00 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5e10 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5e20 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5e30 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5e40 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5e50 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5e60 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5e70 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5e80 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5e90 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5ea0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5eb0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5ec0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5ed0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5ee0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5ef0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5f00 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5f10 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5f20 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5f30 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5f40 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5f50 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5f60 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5f70 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5f80 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5f90 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5fa0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5fb0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5fc0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5fd0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5fe0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /// 0x5ff0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; \ No newline at end of file diff --git a/drivers/power/supply/ti/Kconfig b/drivers/power/supply/ti/Kconfig new file mode 100644 index 000000000000..775441e0e570 --- /dev/null +++ b/drivers/power/supply/ti/Kconfig @@ -0,0 +1,24 @@ +menu "TI Technologies, Inc. Charger support" + +config FUEL_GAUGE_BQ27Z561 + tristate "TI bq27z561 battery gauge driver" + help + Say Y to enable support for TI bq27z561 fuel gauge driver + +config BQ2597X_CHARGE_PUMP + tristate "BQ2597X power supply framework based driver" + depends on I2C + help + Say Y to include support for BQ2597X Charge Pump driver based on + power supply framework. + BQ2597X is a div2 charge pump capable of delivering 8A charge current + with very high efficiency. + +config CHARGER_LN8000 + tristate "LionSemi LN8000 Battery Charger" + depends on I2C + select REGMAP_I2C + help + Say Y to enable support for the LN8000 charger + +endmenu diff --git a/drivers/power/supply/ti/Makefile b/drivers/power/supply/ti/Makefile new file mode 100644 index 000000000000..04ee88c8ba3e --- /dev/null +++ b/drivers/power/supply/ti/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_FUEL_GAUGE_BQ27Z561) += bq27z561_fg.o +obj-$(CONFIG_BQ2597X_CHARGE_PUMP) += bq2597x_charger.o pd_policy_manager.o cp_qc30.o +obj-$(CONFIG_CHARGER_LN8000) += ln8000_charger.o pd_policy_manager.o cp_qc30.o diff --git a/drivers/power/supply/ti/bq25970_reg.h b/drivers/power/supply/ti/bq25970_reg.h new file mode 100644 index 000000000000..71cedf04b552 --- /dev/null +++ b/drivers/power/supply/ti/bq25970_reg.h @@ -0,0 +1,791 @@ + +#ifndef __BQ2597X_HEADER__ +#define __BQ2597X_HEADER__ + +/* Register 00h */ +#define BQ2597X_REG_00 0x00 +#define BQ2597X_BAT_OVP_DIS_MASK 0x80 +#define BQ2597X_BAT_OVP_DIS_SHIFT 7 +#define BQ2597X_BAT_OVP_ENABLE 0 +#define BQ2597X_BAT_OVP_DISABLE 1 + +#define BQ2597X_BAT_OVP_MASK 0x3F +#define BQ2597X_BAT_OVP_SHIFT 0 +#define BQ2597X_BAT_OVP_BASE 3475 +#define BQ2597X_BAT_OVP_LSB 25 + +/* Register 01h */ +#define BQ2597X_REG_01 0x01 +#define BQ2597X_BAT_OVP_ALM_DIS_MASK 0x80 +#define BQ2597X_BAT_OVP_ALM_DIS_SHIFT 7 +#define BQ2597X_BAT_OVP_ALM_ENABLE 0 +#define BQ2597X_BAT_OVP_ALM_DISABLE 1 + +#define BQ2597X_BAT_OVP_ALM_MASK 0x3F +#define BQ2597X_BAT_OVP_ALM_SHIFT 0 +#define BQ2597X_BAT_OVP_ALM_BASE 3500 +#define BQ2597X_BAT_OVP_ALM_LSB 25 + +/* Register 02h */ +#define BQ2597X_REG_02 0x02 +#define BQ2597X_BAT_OCP_DIS_MASK 0x80 +#define BQ2597X_BAT_OCP_DIS_SHIFT 7 +#define BQ2597X_BAT_OCP_ENABLE 0 +#define BQ2597X_BAT_OCP_DISABLE 1 + +#define BQ2597X_BAT_OCP_MASK 0x7F +#define BQ2597X_BAT_OCP_SHIFT 0 +#define BQ2597X_BAT_OCP_BASE 2000 +#define BQ2597X_BAT_OCP_LSB 100 + +/* Register 03h */ +#define BQ2597X_REG_03 0x03 +#define BQ2597X_BAT_OCP_ALM_DIS_MASK 0x80 +#define BQ2597X_BAT_OCP_ALM_DIS_SHIFT 7 +#define BQ2597X_BAT_OCP_ALM_ENABLE 0 +#define BQ2597X_BAT_OCP_ALM_DISABLE 1 + +#define BQ2597X_BAT_OCP_ALM_MASK 0x7F +#define BQ2597X_BAT_OCP_ALM_SHIFT 0 +#define BQ2597X_BAT_OCP_ALM_BASE 2000 +#define BQ2597X_BAT_OCP_ALM_LSB 100 + +/* Register 04h */ +#define BQ2597X_REG_04 0x04 +#define BQ2597X_BAT_UCP_ALM_DIS_MASK 0x80 +#define BQ2597X_BAT_UCP_ALM_DIS_SHIFT 7 +#define BQ2597X_BAT_UCP_ALM_ENABLE 0 +#define BQ2597X_BAT_UCP_ALM_DISABLE 1 + +#define BQ2597X_BAT_UCP_ALM_MASK 0x7F +#define BQ2597X_BAT_UCP_ALM_SHIFT 0 +#define BQ2597X_BAT_UCP_ALM_BASE 0 +#define BQ2597X_BAT_UCP_ALM_LSB 50 + +/* Register 05h */ +#define BQ2597X_REG_05 0x05 +#define BQ2597X_AC_OVP_STAT_MASK 0x80 +#define BQ2597X_AC_OVP_STAT_SHIFT 7 + +#define BQ2597X_AC_OVP_FLAG_MASK 0x40 +#define BQ2597X_AC_OVP_FLAG_SHIFT 6 + +#define BQ2597X_AC_OVP_MASK_MASK 0x20 +#define BQ2597X_AC_OVP_MASK_SHIFT 5 + +#define BQ2597X_VDROP_THRESHOLD_SET_MASK 0x10 +#define BQ2597X_VDROP_THRESHOLD_SET_SHIFT 4 +#define BQ2597X_VDROP_THRESHOLD_300MV 0 +#define BQ2597X_VDROP_THRESHOLD_400MV 1 + +#define BQ2597X_VDROP_DEGLITCH_SET_MASK 0x08 +#define BQ2597X_VDROP_DEGLITCH_SET_SHIFT 3 +#define BQ2597X_VDROP_DEGLITCH_8US 0 +#define BQ2597X_VDROP_DEGLITCH_5MS 1 + +#define BQ2597X_AC_OVP_MASK 0x07 +#define BQ2597X_AC_OVP_SHIFT 0 +#define BQ2597X_AC_OVP_BASE 11 +#define BQ2597X_AC_OVP_LSB 1 +#define BQ2597X_AC_OVP_6P5V 65 + +/* Register 06h */ +#define BQ2597X_REG_06 0x06 +#define BQ2597X_VBUS_PD_EN_MASK 0x80 +#define BQ2597X_VBUS_PD_EN_SHIFT 7 +#define BQ2597X_VBUS_PD_ENABLE 1 +#define BQ2597X_VBUS_PD_DISABLE 0 + +#define BQ2597X_BUS_OVP_MASK 0x7F +#define BQ2597X_BUS_OVP_SHIFT 0 +#define BQ2597X_BUS_OVP_BASE 5950 +#define BQ2597X_BUS_OVP_LSB 50 + +/* Register 07h */ +#define BQ2597X_REG_07 0x07 +#define BQ2597X_BUS_OVP_ALM_DIS_MASK 0x80 +#define BQ2597X_BUS_OVP_ALM_DIS_SHIFT 7 +#define BQ2597X_BUS_OVP_ALM_ENABLE 0 +#define BQ2597X_BUS_OVP_ALM_DISABLE 1 + +#define BQ2597X_BUS_OVP_ALM_MASK 0x7F +#define BQ2597X_BUS_OVP_ALM_SHIFT 0 +#define BQ2597X_BUS_OVP_ALM_BASE 6000 +#define BQ2597X_BUS_OVP_ALM_LSB 50 + +/* Register 08h */ +#define BQ2597X_REG_08 0x08 +#define BQ2597X_BUS_OCP_DIS_MASK 0x80 +#define BQ2597X_BUS_OCP_DIS_SHIFT 7 +#define BQ2597X_BUS_OCP_ENABLE 0 +#define BQ2597X_BUS_OCP_DISABLE 1 + +#define BQ2597X_IBUS_UCP_RISE_FLAG_MASK 0x40 +#define BQ2597X_IBUS_UCP_RISE_FLAG_SHIFT 6 + +#define BQ2597X_IBUS_UCP_RISE_MASK_MASK 0x20 +#define BQ2597X_IBUS_UCP_RISE_MASK_SHIFT 5 +#define BQ2597X_IBUS_UCP_RISE_MASK_ENABLE 1 +#define BQ2597X_IBUS_UCP_RISE_MASK_DISABLE 0 + +#define BQ2597X_IBUS_UCP_FALL_FLAG_MASK 0x10 +#define BQ2597X_IBUS_UCP_FALL_FLAG_SHIFT 4 + +#define BQ2597X_BUS_OCP_MASK 0x0F +#define BQ2597X_BUS_OCP_SHIFT 0 +#define BQ2597X_BUS_OCP_BASE 1000 +#define BQ2597X_BUS_OCP_LSB 250 + +/* Register 09h */ +#define BQ2597X_REG_09 0x09 +#define BQ2597X_BUS_OCP_ALM_DIS_MASK 0x80 +#define BQ2597X_BUS_OCP_ALM_DIS_SHIFT 7 +#define BQ2597X_BUS_OCP_ALM_ENABLE 0 +#define BQ2597X_BUS_OCP_ALM_DISABLE 1 + +#define BQ2597X_BUS_OCP_ALM_MASK 0x7F +#define BQ2597X_BUS_OCP_ALM_SHIFT 0 +#define BQ2597X_BUS_OCP_ALM_BASE 0 +#define BQ2597X_BUS_OCP_ALM_LSB 50 + +/* Register 0Ah */ +#define BQ2597X_REG_0A 0x0A +#define BQ2597X_TSHUT_FLAG_MASK 0x80 +#define BQ2597X_TSHUT_FLAG_SHIFT 7 +#define VBUS_ERROR_LOW_MASK BIT(5) +#define VBUS_ERROR_HIGH_MASK BIT(4) + +#define BQ2597X_TSHUT_STAT_MASK 0x40 +#define BQ2597X_TSHUT_STAT_SHIFT 6 + +#define BQ2597X_VBUS_ERRORLO_STAT_MASK 0x20 +#define BQ2597X_VBUS_ERRORLO_STAT_SHIFT 5 + +#define BQ2597X_VBUS_ERRORHI_STAT_MASK 0x10 +#define BQ2597X_VBUS_ERRORHI_STAT_SHIFT 4 + +#define BQ2597X_SS_TIMEOUT_FLAG_MASK 0x08 +#define BQ2597X_SS_TIMEOUT_FLAG_SHIFT 3 + +#define BQ2597X_CONV_SWITCHING_STAT_MASK 0x04 +#define BQ2597X_CONV_SWITCHING_STAT_SHIFT 2 + +#define BQ2597X_CONV_OCP_FLAG_MASK 0x02 +#define BQ2597X_CONV_OCP_FLAG_SHIFT 1 + +#define BQ2597X_PIN_DIAG_FALL_FLAG_MASK 0x01 +#define BQ2597X_PIN_DIAG_FALL_FLAG_SHIFT 0 + +/* Register 0Bh */ +#define BQ2597X_REG_0B 0x0B +#define BQ2597X_REG_RST_MASK 0x80 +#define BQ2597X_REG_RST_SHIFT 7 +#define BQ2597X_REG_RST_ENABLE 1 +#define BQ2597X_REG_RST_DISABLE 0 + +#define BQ2597X_FSW_SET_MASK 0x70 +#define BQ2597X_FSW_SET_SHIFT 4 +#define BQ2597X_FSW_SET_187P5KHZ 0 +#define BQ2597X_FSW_SET_250KHZ 1 +#define BQ2597X_FSW_SET_300KHZ 2 +#define BQ2597X_FSW_SET_375KHZ 3 +#define BQ2597X_FSW_SET_500KHZ 4 +#define BQ2597X_FSW_SET_750KHZ 5 + +#define BQ2597X_WD_TIMEOUT_FLAG_MASK 0x08 +#define BQ2597X_WD_TIMEOUT_SHIFT 3 + +#define BQ2597X_WATCHDOG_DIS_MASK 0x04 +#define BQ2597X_WATCHDOG_DIS_SHIFT 2 +#define BQ2597X_WATCHDOG_ENABLE 0 +#define BQ2597X_WATCHDOG_DISABLE 1 + +#define BQ2597X_WATCHDOG_MASK 0x03 +#define BQ2597X_WATCHDOG_SHIFT 0 +#define BQ2597X_WATCHDOG_0P5S 0 +#define BQ2597X_WATCHDOG_1S 1 +#define BQ2597X_WATCHDOG_5S 2 +#define BQ2597X_WATCHDOG_30S 3 + +/* Register 0Ch */ +#define BQ2597X_REG_0C 0x0C +#define BQ2597X_CHG_EN_MASK 0x80 +#define BQ2597X_CHG_EN_SHIFT 7 +#define BQ2597X_CHG_ENABLE 1 +#define BQ2597X_CHG_DISABLE 0 + +#define BQ2597X_MS_MASK 0x60 +#define BQ2597X_MS_SHIFT 5 +#define BQ2597X_MS_STANDALONE 0 +#define BQ2597X_MS_SLAVE 1 +#define BQ2597X_MS_MASTER 2 + +#define BQ2597X_FREQ_SHIFT_MASK 0x18 +#define BQ2597X_FREQ_SHIFT_SHIFT 3 +#define BQ2597X_FREQ_SHIFT_NORMINAL 0 +#define BQ2597X_FREQ_SHIFT_POSITIVE10 1 +#define BQ2597X_FREQ_SHIFT_NEGATIVE10 2 +#define BQ2597X_FREQ_SHIFT_SPREAD_SPECTRUM 3 + +#define BQ2597X_TSBUS_DIS_MASK 0x04 +#define BQ2597X_TSBUS_DIS_SHIFT 2 +#define BQ2597X_TSBUS_ENABLE 0 +#define BQ2597X_TSBUS_DISABLE 1 + +#define BQ2597X_TSBAT_DIS_MASK 0x02 +#define BQ2597X_TSBAT_DIS_SHIFT 1 +#define BQ2597X_TSBAT_ENABLE 0 +#define BQ2597X_TSBAT_DISABLE 1 + +#define BQ2597X_TDIE_DIS_MASK 0x01 +#define BQ2597X_TDIE_DIS_SHIFT 0 +#define BQ2597X_TDIE_ENABLE 0 +#define BQ2597X_TDIE_DISABLE 1 + +/* Register 0Dh */ +#define BQ2597X_REG_0D 0x0D +#define BQ2597X_BAT_OVP_ALM_STAT_MASK 0x80 +#define BQ2597X_BAT_OVP_ALM_STAT_SHIFT 7 + +#define BQ2597X_BAT_OCP_ALM_STAT_MASK 0x40 +#define BQ2597X_BAT_OCP_ALM_STAT_SHIFT 6 + +#define BQ2597X_BUS_OVP_ALM_STAT_MASK 0x20 +#define BQ2597X_BUS_OVP_ALM_STAT_SHIFT 5 + +#define BQ2597X_BUS_OCP_ALM_STAT_MASK 0x10 +#define BQ2597X_BUS_OCP_ALM_STAT_SHIFT 4 + +#define BQ2597X_BAT_UCP_ALM_STAT_MASK 0x08 +#define BQ2597X_BAT_UCP_ALM_STAT_SHIFT 3 + +#define BQ2597X_ADAPTER_INSERT_STAT_MASK 0x04 +#define BQ2597X_ADAPTER_INSERT_STAT_SHIFT 2 + +#define BQ2597X_VBAT_INSERT_STAT_MASK 0x02 +#define BQ2597X_VBAT_INSERT_STAT_SHIFT 1 + +#define BQ2597X_ADC_DONE_STAT_MASK 0x01 +#define BQ2597X_ADC_DONE_STAT_SHIFT 0 +#define BQ2597X_ADC_DONE_STAT_COMPLETE 1 +#define BQ2597X_ADC_DONE_STAT_NOTCOMPLETE 0 + +/* Register 0Eh */ +#define BQ2597X_REG_0E 0x0E +#define BQ2597X_BAT_OVP_ALM_FLAG_MASK 0x80 +#define BQ2597X_BAT_OVP_ALM_FLAG_SHIFT 7 + +#define BQ2597X_BAT_OCP_ALM_FLAG_MASK 0x40 +#define BQ2597X_BAT_OCP_ALM_FLAG_SHIFT 6 + +#define BQ2597X_BUS_OVP_ALM_FLAG_MASK 0x20 +#define BQ2597X_BUS_OVP_ALM_FLAG_SHIFT 5 + +#define BQ2597X_BUS_OCP_ALM_FLAG_MASK 0x10 +#define BQ2597X_BUS_OCP_ALM_FLAG_SHIFT 4 + +#define BQ2597X_BAT_UCP_ALM_FLAG_MASK 0x08 +#define BQ2597X_BAT_UCP_ALM_FLAG_SHIFT 3 + +#define BQ2597X_ADAPTER_INSERT_FLAG_MASK 0x04 +#define BQ2597X_ADAPTER_INSERT_FLAG_SHIFT 2 + +#define BQ2597X_VBAT_INSERT_FLAG_MASK 0x02 +#define BQ2597X_VBAT_INSERT_FLAG_SHIFT 1 + +#define BQ2597X_ADC_DONE_FLAG_MASK 0x01 +#define BQ2597X_ADC_DONE_FLAG_SHIFT 0 +#define BQ2597X_ADC_DONE_FLAG_COMPLETE 1 +#define BQ2597X_ADC_DONE_FLAG_NOTCOMPLETE 0 + +/* Register 0Fh */ +#define BQ2597X_REG_0F 0x0F +#define BQ2597X_BAT_OVP_ALM_MASK_MASK 0x80 +#define BQ2597X_BAT_OVP_ALM_MASK_SHIFT 7 +#define BQ2597X_BAT_OVP_ALM_MASK_ENABLE 1 +#define BQ2597X_BAT_OVP_ALM_MASK_DISABLE 0 + +#define BQ2597X_BAT_OCP_ALM_MASK_MASK 0x40 +#define BQ2597X_BAT_OCP_ALM_MASK_SHIFT 6 +#define BQ2597X_BAT_OCP_ALM_MASK_ENABLE 1 +#define BQ2597X_BAT_OCP_ALM_MASK_DISABLE 0 + +#define BQ2597X_BUS_OVP_ALM_MASK_MASK 0x20 +#define BQ2597X_BUS_OVP_ALM_MASK_SHIFT 5 +#define BQ2597X_BUS_OVP_ALM_MASK_ENABLE 1 +#define BQ2597X_BUS_OVP_ALM_MASK_DISABLE 0 + +#define BQ2597X_BUS_OCP_ALM_MASK_MASK 0x10 +#define BQ2597X_BUS_OCP_ALM_MASK_SHIFT 4 +#define BQ2597X_BUS_OCP_ALM_MASK_ENABLE 1 +#define BQ2597X_BUS_OCP_ALM_MASK_DISABLE 0 + +#define BQ2597X_BAT_UCP_ALM_MASK_MASK 0x08 +#define BQ2597X_BAT_UCP_ALM_MASK_SHIFT 3 +#define BQ2597X_BAT_UCP_ALM_MASK_ENABLE 1 +#define BQ2597X_BAT_UCP_ALM_MASK_DISABLE 0 + +#define BQ2597X_ADAPTER_INSERT_MASK_MASK 0x04 +#define BQ2597X_ADAPTER_INSERT_MASK_SHIFT 2 +#define BQ2597X_ADAPTER_INSERT_MASK_ENABLE 1 +#define BQ2597X_ADAPTER_INSERT_MASK_DISABLE 0 + +#define BQ2597X_VBAT_INSERT_MASK_MASK 0x02 +#define BQ2597X_VBAT_INSERT_MASK_SHIFT 1 +#define BQ2597X_VBAT_INSERT_MASK_ENABLE 1 +#define BQ2597X_VBAT_INSERT_MASK_DISABLE 0 + +#define BQ2597X_ADC_DONE_MASK_MASK 0x01 +#define BQ2597X_ADC_DONE_MASK_SHIFT 0 +#define BQ2597X_ADC_DONE_MASK_ENABLE 1 +#define BQ2597X_ADC_DONE_MASK_DISABLE 0 + +/* Register 10h */ +#define BQ2597X_REG_10 0x10 +#define BQ2597X_BAT_OVP_FLT_STAT_MASK 0x80 +#define BQ2597X_BAT_OVP_FLT_STAT_SHIFT 7 + +#define BQ2597X_BAT_OCP_FLT_STAT_MASK 0x40 +#define BQ2597X_BAT_OCP_FLT_STAT_SHIFT 6 + +#define BQ2597X_BUS_OVP_FLT_STAT_MASK 0x20 +#define BQ2597X_BUS_OVP_FLT_STAT_SHIFT 5 + +#define BQ2597X_BUS_OCP_FLT_STAT_MASK 0x10 +#define BQ2597X_BUS_OCP_FLT_STAT_SHIFT 4 + +#define BQ2597X_TSBUS_TSBAT_ALM_STAT_MASK 0x08 +#define BQ2597X_TSBUS_TSBAT_ALM_STAT_SHIFT 3 + +#define BQ2597X_TSBAT_FLT_STAT_MASK 0x04 +#define BQ2597X_TSBAT_FLT_STAT_SHIFT 2 + +#define BQ2597X_TSBUS_FLT_STAT_MASK 0x02 +#define BQ2597X_TSBUS_FLT_STAT_SHIFT 1 + +#define BQ2597X_TDIE_ALM_STAT_MASK 0x01 +#define BQ2597X_TDIE_ALM_STAT_SHIFT 0 + +/* Register 11h */ +#define BQ2597X_REG_11 0x11 +#define BQ2597X_BAT_OVP_FLT_FLAG_MASK 0x80 +#define BQ2597X_BAT_OVP_FLT_FLAG_SHIFT 7 + +#define BQ2597X_BAT_OCP_FLT_FLAG_MASK 0x40 +#define BQ2597X_BAT_OCP_FLT_FLAG_SHIFT 6 + +#define BQ2597X_BUS_OVP_FLT_FLAG_MASK 0x20 +#define BQ2597X_BUS_OVP_FLT_FLAG_SHIFT 5 + +#define BQ2597X_BUS_OCP_FLT_FLAG_MASK 0x10 +#define BQ2597X_BUS_OCP_FLT_FLAG_SHIFT 4 + +#define BQ2597X_TSBUS_TSBAT_ALM_FLAG_MASK 0x08 +#define BQ2597X_TSBUS_TSBAT_ALM_FLAG_SHIFT 3 + +#define BQ2597X_TSBAT_FLT_FLAG_MASK 0x04 +#define BQ2597X_TSBAT_FLT_FLAG_SHIFT 2 + +#define BQ2597X_TSBUS_FLT_FLAG_MASK 0x02 +#define BQ2597X_TSBUS_FLT_FLAG_SHIFT 1 + +#define BQ2597X_TDIE_ALM_FLAG_MASK 0x01 +#define BQ2597X_TDIE_ALM_FLAG_SHIFT 0 + +/* Register 12h */ +#define BQ2597X_REG_12 0x12 +#define BQ2597X_BAT_OVP_FLT_MASK_MASK 0x80 +#define BQ2597X_BAT_OVP_FLT_MASK_SHIFT 7 +#define BQ2597X_BAT_OVP_FLT_MASK_ENABLE 1 +#define BQ2597X_BAT_OVP_FLT_MASK_DISABLE 0 + +#define BQ2597X_BAT_OCP_FLT_MASK_MASK 0x40 +#define BQ2597X_BAT_OCP_FLT_MASK_SHIFT 6 +#define BQ2597X_BAT_OCP_FLT_MASK_ENABLE 1 +#define BQ2597X_BAT_OCP_FLT_MASK_DISABLE 0 + +#define BQ2597X_BUS_OVP_FLT_MASK_MASK 0x20 +#define BQ2597X_BUS_OVP_FLT_MASK_SHIFT 5 +#define BQ2597X_BUS_OVP_FLT_MASK_ENABLE 1 +#define BQ2597X_BUS_OVP_FLT_MASK_DISABLE 0 + +#define BQ2597X_BUS_OCP_FLT_MASK_MASK 0x10 +#define BQ2597X_BUS_OCP_FLT_MASK_SHIFT 4 +#define BQ2597X_BUS_OCP_FLT_MASK_ENABLE 1 +#define BQ2597X_BUS_OCP_FLT_MASK_DISABLE 0 + +#define BQ2597X_TSBUS_TSBAT_ALM_MASK_MASK 0x08 +#define BQ2597X_TSBUS_TSBAT_ALM_MASK_SHIFT 3 +#define BQ2597X_TSBUS_TSBAT_ALM_MASK_ENABLE 1 +#define BQ2597X_TSBUS_TSBAT_ALM_MASK_DISABLE 0 + +#define BQ2597X_TSBAT_FLT_MASK_MASK 0x04 +#define BQ2597X_TSBAT_FLT_MASK_SHIFT 2 +#define BQ2597X_TSBAT_FLT_MASK_ENABLE 1 +#define BQ2597X_TSBAT_FLT_MASK_DISABLE 0 + +#define BQ2597X_TSBUS_FLT_MASK_MASK 0x02 +#define BQ2597X_TSBUS_FLT_MASK_SHIFT 1 +#define BQ2597X_TSBUS_FLT_MASK_ENABLE 1 +#define BQ2597X_TSBUS_FLT_MASK_DISABLE 0 + +#define BQ2597X_TDIE_ALM_MASK_MASK 0x01 +#define BQ2597X_TDIE_ALM_MASK_SHIFT 0 +#define BQ2597X_TDIE_ALM_MASK_ENABLE 1 +#define BQ2597X_TDIE_ALM_MASK_DISABLE 0 + +/* Register 13h */ +#define BQ2597X_REG_13 0x13 +#define BQ2597X_DEV_ID_MASK 0x0F +#define BQ2597X_DEV_ID_SHIFT 0 + +/* Register 14h */ +#define BQ2597X_REG_14 0x14 +#define BQ2597X_ADC_EN_MASK 0x80 +#define BQ2597X_ADC_EN_SHIFT 7 +#define BQ2597X_ADC_ENABLE 1 +#define BQ2597X_ADC_DISABLE 0 + +#define BQ2597X_ADC_RATE_MASK 0x40 +#define BQ2597X_ADC_RATE_SHIFT 6 +#define BQ2597X_ADC_RATE_CONTINOUS 0 +#define BQ2597X_ADC_RATE_ONESHOT 1 + +#define BQ2597X_ADC_AVG_MASK 0x20 +#define BQ2597X_ADC_AVG_SHIFT 5 +#define BQ2597X_ADC_AVG_DISABLE 0 +#define BQ2597X_ADC_AVG_ENABLE 1 + +#define BQ2597X_ADC_AVG_INIT_MASK 0x10 +#define BQ2597X_ADC_AVG_INIT_SHIFT 4 +#define BQ2597X_ADC_AVG_INIT_EXIST_REG_VAL 0 +#define BQ2597X_ADC_AVG_INIT_NEW_CONVERSION 1 + +#define BQ2597X_ADC_SAMPLE_MASK 0x0C +#define BQ2597X_ADC_SAMPLE_SHIFT 2 +#define BQ2597X_ADC_SAMPLE_15BITS 0 +#define BQ2597X_ADC_SAMPLE_14BITS 1 +#define BQ2597X_ADC_SAMPLE_13BITS 2 +#define BQ2597X_ADC_SAMPLE_12BITS 3 + +#define BQ2597X_IBUS_ADC_DIS_MASK 0x01 +#define BQ2597X_IBUS_ADC_DIS_SHIFT 0 +#define BQ2597X_IBUS_ADC_ENABLE 0 +#define BQ2597X_IBUS_ADC_DISABLE 1 + +/* Register 15h */ +#define BQ2597X_REG_15 0x15 +#define BQ2597X_VBUS_ADC_DIS_MASK 0x80 +#define BQ2597X_VBUS_ADC_DIS_SHIFT 7 +#define BQ2597X_VBUS_ADC_ENABLE 0 +#define BQ2597X_VBUS_ADC_DISABLE 1 + +#define BQ2597X_VAC_ADC_DIS_MASK 0x40 +#define BQ2597X_VAC_ADC_DIS_SHIFT 6 +#define BQ2597X_VAC_ADC_ENABLE 0 +#define BQ2597X_VAC_ADC_DISABLE 1 + +#define BQ2597X_VOUT_ADC_DIS_MASK 0x20 +#define BQ2597X_VOUT_ADC_DIS_SHIFT 5 +#define BQ2597X_VOUT_ADC_ENABLE 0 +#define BQ2597X_VOUT_ADC_DISABLE 1 + +#define BQ2597X_VBAT_ADC_DIS_MASK 0x10 +#define BQ2597X_VBAT_ADC_DIS_SHIFT 4 +#define BQ2597X_VBAT_ADC_ENABLE 0 +#define BQ2597X_VBAT_ADC_DISABLE 1 + +#define BQ2597X_IBAT_ADC_DIS_MASK 0x08 +#define BQ2597X_IBAT_ADC_DIS_SHIFT 3 +#define BQ2597X_IBAT_ADC_ENABLE 0 +#define BQ2597X_IBAT_ADC_DISABLE 1 + +#define BQ2597X_TSBUS_ADC_DIS_MASK 0x04 +#define BQ2597X_TSBUS_ADC_DIS_SHIFT 2 +#define BQ2597X_TSBUS_ADC_ENABLE 0 +#define BQ2597X_TSBUS_ADC_DISABLE 1 + +#define BQ2597X_TSBAT_ADC_DIS_MASK 0x02 +#define BQ2597X_TSBAT_ADC_DIS_SHIFT 1 +#define BQ2597X_TSBAT_ADC_ENABLE 0 +#define BQ2597X_TSBAT_ADC_DISABLE 1 + +#define BQ2597X_TDIE_ADC_DIS_MASK 0x01 +#define BQ2597X_TDIE_ADC_DIS_SHIFT 0 +#define BQ2597X_TDIE_ADC_ENABLE 0 +#define BQ2597X_TDIE_ADC_DISABLE 1 + +/* Register 16h */ +#define BQ2597X_REG_16 0x16 +#define BQ2597X_IBUS_POL_MASK 0x80 +#define BQ2597X_IBUS_POL_SHIFT 7 +#define BQ2597X_IBUS_POL_POSITIVE 0 +#define BQ2597X_IBUS_POL_NAGETIVE 1 + +#define BQ2597X_IBUS_ADC1_MASK 0x7F +#define BQ2597X_IBUS_ADC1_SHIFT 0 +#define BQ2597X_IBUS_ADC1_BASE 0 +#define BQ2597X_IBUS_ADC1_LSB 256 + +/* Register 17h */ +#define BQ2597X_REG_17 0x17 +#define BQ2597X_IBUS_ADC0_MASK 0xFF +#define BQ2597X_IBUS_ADC0_SHIFT 0 +#define BQ2597X_IBUS_ADC0_BASE 0 +#define BQ2597X_IBUS_ADC0_LSB 1 + +/* Register 18h */ +#define BQ2597X_REG_18 0x18 +#define BQ2597X_VBUS_POL_MASK 0x80 +#define BQ2597X_VBUS_POL_SHIFT 7 +#define BQ2597X_VBUS_POL_POSITIVE 0 +#define BQ2597X_VBUS_POL_NEGATIVE 1 + +#define BQ2597X_VBUS_ADC1_MASK 0x7F +#define BQ2597X_VBUS_ADC1_SHIFT 0 +#define BQ2597X_VBUS_ADC1_BASE 0 +#define BQ2597X_VBUS_ADC1_LSB 256 + +/* Register 19h */ +#define BQ2597X_REG_19 0x19 +#define BQ2597X_VBUS_ADC0_MASK 0xFF +#define BQ2597X_VBUS_ADC0_SHIFT 0 +#define BQ2597X_VBUS_ADC0_BASE 0 +#define BQ2597X_VBUS_ADC0_LSB 1 + +/* Register 1Ah */ +#define BQ2597X_REG_1A 0x1A +#define BQ2597X_VAC_POL_MASK 0x80 +#define BQ2597X_VAC_POL_SHIFT 7 +#define BQ2597X_VAC_POL_POSITIVE 0 +#define BQ2597X_VAC_POL_NEGATIVE 1 + +#define BQ2597X_VAC_ADC1_MASK 0x7F +#define BQ2597X_VAC_ADC1_SHIFT 0 +#define BQ2597X_VAC_ADC1_BASE 0 +#define BQ2597X_VAC_ADC1_LSB 256 + +/* Register 1Bh */ +#define BQ2597X_REG_1B 0x1B +#define BQ2597X_VAC_ADC0_MASK 0xFF +#define BQ2597X_VAC_ADC0_SHIFT 0 +#define BQ2597X_VAC_ADC0_BASE 0 +#define BQ2597X_VAC_ADC0_LSB 1 + +/* Register 1Ch */ +#define BQ2597X_REG_1C 0x1C +#define BQ2597X_VOUT_POL_MASK 0x80 +#define BQ2597X_VOUT_POL_SHIFT 7 +#define BQ2597X_VOUT_POL_POSITIVE 0 +#define BQ2597X_VOUT_POL_NEGATIVE 1 + +#define BQ2597X_VOUT_ADC1_MASK 0x7F +#define BQ2597X_VOUT_ADC1_SHIFT 0 +#define BQ2597X_VOUT_ADC1_BASE 0 +#define BQ2597X_VOUT_ADC1_LSB 256 + +/* Register 1Dh */ +#define BQ2597X_REG_1D 0x1D +#define BQ2597X_VOUT_ADC0_MASK 0xFF +#define BQ2597X_VOUT_ADC0_SHIFT 0 +#define BQ2597X_VOUT_ADC0_BASE 0 +#define BQ2597X_VOUT_ADC0_LSB 1 + +/* Register 1Eh */ +#define BQ2597X_REG_1E 0x1E +#define BQ2597X_VBAT_POL_MASK 0x80 +#define BQ2597X_VBAT_POL_SHIFT 7 +#define BQ2597X_VBAT_POL_POSITIVE 0 +#define BQ2597X_VBAT_POL_NEGATIVE 1 + +#define BQ2597X_VBAT_ADC1_MASK 0x7F +#define BQ2597X_VBAT_ADC1_SHIFT 0 +#define BQ2597X_VBAT_ADC1_BASE 0 +#define BQ2597X_VBAT_ADC1_LSB 256 + +/* Register 1Fh */ +#define BQ2597X_REG_1F 0x1F +#define BQ2597X_VBAT_ADC0_MASK 0xFF +#define BQ2597X_VBAT_ADC0_SHIFT 0 +#define BQ2597X_VBAT_ADC0_BASE 0 +#define BQ2597X_VBAT_ADC0_LSB 1 + +/* Register 20h */ +#define BQ2597X_REG_20 0x20 +#define BQ2597X_IBAT_POL_MASK 0x80 +#define BQ2597X_IBAT_POL_SHIFT 7 +#define BQ2597X_IBAT_POL_POSITIVE 0 +#define BQ2597X_IBAT_POL_NEGATIVE 1 + +#define BQ2597X_IBAT_ADC1_MASK 0x7F +#define BQ2597X_IBAT_ADC1_SHIFT 0 +#define BQ2597X_IBAT_ADC1_BASE 0 +#define BQ2597X_IBAT_ADC1_LSB 256 + +/* Register 21h */ +#define BQ2597X_REG_21 0x21 +#define BQ2597X_IBAT_ADC0_MASK 0xFF +#define BQ2597X_IBAT_ADC0_SHIFT 0 +#define BQ2597X_IBAT_ADC0_BASE 0 +#define BQ2597X_IBAT_ADC0_LSB 1 + +/* Register 22h */ +#define BQ2597X_REG_22 0x22 +#define BQ2597X_TSBUS_POL_MASK 0x80 +#define BQ2597X_TSBUS_POL_SHIFT 7 +#define BQ2597X_TSBUS_POL_POSITIVE 0 +#define BQ2597X_TSBUS_POL_NEGATIVE 1 + +#define BQ2597X_TSBUS_ADC1_MASK 0x7F +#define BQ2597X_TSBUS_ADC1_SHIFT 0 +#define BQ2597X_TSBUS_ADC1_BASE 0 +#define BQ2597X_TSBUS_ADC1_LSB 25 + +/* Register 23h */ +#define BQ2597X_REG_23 0x23 +#define BQ2597X_TSBUS_ADC0_MASK 0xFF +#define BQ2597X_TSBUS_ADC0_SHIFT 0 +#define BQ2597X_TSBUS_ADC0_BASE 0 +#define BQ2597X_TSBUS_ADC0_LSB 0.09766 + +/* Register 24h */ +#define BQ2597X_REG_24 0x24 +#define BQ2597X_TSBAT_POL_MASK 0x80 +#define BQ2597X_TSBAT_POL_SHIFT 7 +#define BQ2597X_TSBAT_POL_POSITIVE 0 +#define BQ2597X_TSBAT_POL_NEGATIVE 1 + +#define BQ2597X_TSBAT_ADC1_MASK 0x7F +#define BQ2597X_TSBAT_ADC1_SHIFT 0 +#define BQ2597X_TSBAT_ADC1_BASE 0 +#define BQ2597X_TSBAT_ADC1_LSB 25 + +/* Register 25h */ +#define BQ2597X_REG_25 0x25 +#define BQ2597X_TSBAT_ADC0_MASK 0xFF +#define BQ2597X_TSBAT_ADC0_SHIFT 0 +#define BQ2597X_TSBAT_ADC0_BASE 0 +#define BQ2597X_TSBAT_ADC0_LSB 0.09766 + +/* Register 26h */ +#define BQ2597X_REG_26 0x26 +#define BQ2597X_TDIE_POL_MASK 0x80 +#define BQ2597X_TDIE_POL_SHIFT 7 +#define BQ2597X_TDIE_POL_POSITIVE 0 +#define BQ2597X_TDIE_POL_NEGATIVE 1 + +#define BQ2597X_TDIE_ADC1_MASK 0x7F +#define BQ2597X_TDIE_ADC1_SHIFT 0 +#define BQ2597X_TDIE_ADC1_BASE 0 +#define BQ2597X_TDIE_ADC1_LSB 128 + +/* Register 27h */ +#define BQ2597X_REG_27 0x27 +#define BQ2597X_TDIE_ADC0_MASK 0xFF +#define BQ2597X_TDIE_ADC0_SHIFT 0 +#define BQ2597X_TDIE_ADC0_BASE 0 +#define BQ2597X_TDIE_ADC0_LSB 0.5 + +/* Register 28h */ +#define BQ2597X_REG_28 0x28 +#define BQ2597X_TSBUS_FLT1_MASK 0xFF +#define BQ2597X_TSBUS_FLT1_SHIFT 0 +#define BQ2597X_TSBUS_FLT1_BASE 0 +#define BQ2597X_TSBUS_FLT1_LSB 0.19531 + +/* Register 29h */ +#define BQ2597X_REG_29 0x29 +#define BQ2597X_TSBAT_FLT0_MASK 0xFF +#define BQ2597X_TSBAT_FLT0_SHIFT 0 +#define BQ2597X_TSBAT_FLT0_BASE 0 +#define BQ2597X_TSBAT_FLT0_LSB 0.19531 + +/* Register 2Ah */ +#define BQ2597X_REG_2A 0x2A +#define BQ2597X_TDIE_ALM_MASK 0xFF +#define BQ2597X_TDIE_ALM_SHIFT 0 +#define BQ2597X_TDIE_ALM_BASE 30 + +#define BQ2597X_TDIE_ALM_LSB \ + 2 /*careful + multiply is used for calc*/ + +/* Register 2Bh */ +#define BQ2597X_REG_2B 0x2B +#define BQ2597X_SS_TIMEOUT_SET_MASK 0xE0 +#define BQ2597X_SS_TIMEOUT_SET_SHIFT 5 +#define BQ2597X_SS_TIMEOUT_DISABLE 0 +#define BQ2597X_SS_TIMEOUT_12P5MS 1 +#define BQ2597X_SS_TIMEOUT_25MS 2 +#define BQ2597X_SS_TIMEOUT_50MS 3 +#define BQ2597X_SS_TIMEOUT_100MS 4 +#define BQ2597X_SS_TIMEOUT_400MS 5 +#define BQ2597X_SS_TIMEOUT_1500MS 6 +#define BQ2597X_SS_TIMEOUT_100000MS 7 + +#define BQ2597X_EN_REGULATION_MASK 0x10 +#define BQ2597X_EN_REGULATION_SHIFT 4 +#define BQ2597X_EN_REGULATION_ENABLE 1 +#define BQ2597X_EN_REGULATION_DISABLE 0 + +#define BQ2597X_VOUT_OVP_DIS_MASK 0x08 +#define BQ2597X_VOUT_OVP_DIS_SHIFT 3 +#define BQ2597X_VOUT_OVP_ENABLE 1 +#define BQ2597X_VOUT_OVP_DISABLE 0 + +#define BQ2597X_IBUS_UCP_RISE_TH_MASK 0x04 +#define BQ2597X_IBUS_UCP_RISE_TH_SHIFT 2 +#define BQ2597X_IBUS_UCP_RISE_300MA 0 +#define BQ2597X_IBUS_UCP_RISE_500MA 1 + +#define BQ2597X_SET_IBAT_SNS_RES_MASK 0x02 +#define BQ2597X_SET_IBAT_SNS_RES_SHIFT 1 +#define BQ2597X_SET_IBAT_SNS_RES_2MHM 0 +#define BQ2597X_SET_IBAT_SNS_RES_5MHM 1 + +#define BQ2597X_VAC_PD_EN_MASK 0x01 +#define BQ2597X_VAC_PD_EN_SHIFT 0 +#define BQ2597X_VAC_PD_ENABLE 1 +#define BQ2597X_VAC_PD_DISABLE 0 + +/* Register 2Ch */ +#define BQ2597X_REG_2C 0x2C +#define BQ2597X_IBAT_REG_MASK 0xC0 +#define BQ2597X_IBAT_REG_SHIFT 6 +#define BQ2597X_IBAT_REG_200MA 0 +#define BQ2597X_IBAT_REG_300MA 1 +#define BQ2597X_IBAT_REG_400MA 2 +#define BQ2597X_IBAT_REG_500MA 3 +#define BQ2597X_VBAT_REG_MASK 0x30 +#define BQ2597X_VBAT_REG_SHIFT 4 +#define BQ2597X_VBAT_REG_50MV 0 +#define BQ2597X_VBAT_REG_100MV 1 +#define BQ2597X_VBAT_REG_150MV 2 +#define BQ2597X_VBAT_REG_200MV 3 + +#define BQ2597X_VBAT_REG_ACTIVE_STAT_MASK 0x08 +#define BQ2597X_IBAT_REG_ACTIVE_STAT_MASK 0x04 +#define BQ2597X_VDROP_OVP_ACTIVE_STAT_MASK 0x02 +#define BQ2597X_VOUT_OVP_ACTIVE_STAT_MASK 0x01 + +#define BQ2597X_REG_2D 0x2D +#define BQ2597X_VBAT_REG_ACTIVE_FLAG_MASK 0x80 +#define BQ2597X_IBAT_REG_ACTIVE_FLAG_MASK 0x40 +#define BQ2597X_VDROP_OVP_FLAG_MASK 0x20 +#define BQ2597X_VOUT_OVP_FLAG_MASK 0x10 +#define BQ2597X_VBAT_REG_ACTIVE_MASK_MASK 0x08 +#define BQ2597X_IBAT_REG_ACTIVE_MASK_MASK 0x04 +#define BQ2597X_VDROP_OVP_MASK_MASK 0x02 +#define BQ2597X_VOUT_OVP_MASK_MASK 0x01 + +#define BQ2597X_REG_2E 0x2E +#define BQ2597X_VBUS_ERR_LOW_DG_MASK 0x10 +#define BQ2597X_VBUS_ERR_LOW_DG_SHIFT 4 +#define BQ2597X_VBUS_ERR_LOW_DG_10US 0 +#define BQ2597X_VBUS_ERR_LOW_DG_10MS 1 +#define BQ2597X_IBUS_LOW_DG_MASK 0x08 +#define BQ2597X_IBUS_LOW_DG_SHIFT 3 +#define BQ2597X_IBUS_LOW_DG_10US 0 +#define BQ2597X_IBUS_LOW_DG_5MS 1 + +#endif diff --git a/drivers/power/supply/ti/bq2597x_charger.c b/drivers/power/supply/ti/bq2597x_charger.c new file mode 100644 index 000000000000..304916983cab --- /dev/null +++ b/drivers/power/supply/ti/bq2597x_charger.c @@ -0,0 +1,2462 @@ +/* + * BQ2570x battery charging driver + * + * Copyright (C) 2017 Texas Instruments * + * Copyright (C) 2021 XiaoMi, Inc. + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#define pr_fmt(fmt) "[bq2597x] %s: " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bq25970_reg.h" +/*#include "bq2597x.h"*/ + +enum { + VBUS_ERROR_NONE, + VBUS_ERROR_LOW, + VBUS_ERROR_HIGH, +}; + +enum { + ADC_IBUS, + ADC_VBUS, + ADC_VAC, + ADC_VOUT, + ADC_VBAT, + ADC_IBAT, + ADC_TBUS, + ADC_TBAT, + ADC_TDIE, + ADC_MAX_NUM, +}; + +#define BQ25970_ROLE_STDALONE 0 +#define BQ25970_ROLE_SLAVE 1 +#define BQ25970_ROLE_MASTER 2 + +enum { + BQ25970_STDALONE, + BQ25970_SLAVE, + BQ25970_MASTER, +}; + +static int bq2597x_mode_data[] = { + [BQ25970_STDALONE] = BQ25970_STDALONE, + [BQ25970_MASTER] = BQ25970_ROLE_MASTER, + [BQ25970_SLAVE] = BQ25970_ROLE_SLAVE, +}; + +#define BAT_OVP_ALARM BIT(7) +#define BAT_OCP_ALARM BIT(6) +#define BUS_OVP_ALARM BIT(5) +#define BUS_OCP_ALARM BIT(4) +#define BAT_UCP_ALARM BIT(3) +#define VBUS_INSERT BIT(2) +#define VBAT_INSERT BIT(1) +#define ADC_DONE BIT(0) + +#define BAT_OVP_FAULT BIT(7) +#define BAT_OCP_FAULT BIT(6) +#define BUS_OVP_FAULT BIT(5) +#define BUS_OCP_FAULT BIT(4) +#define TBUS_TBAT_ALARM BIT(3) +#define TS_BAT_FAULT BIT(2) +#define TS_BUS_FAULT BIT(1) +#define TS_DIE_FAULT BIT(0) + +/*below used for comm with other module*/ +#define BAT_OVP_FAULT_SHIFT 0 +#define BAT_OCP_FAULT_SHIFT 1 +#define BUS_OVP_FAULT_SHIFT 2 +#define BUS_OCP_FAULT_SHIFT 3 +#define BAT_THERM_FAULT_SHIFT 4 +#define BUS_THERM_FAULT_SHIFT 5 +#define DIE_THERM_FAULT_SHIFT 6 + +#define BAT_OVP_FAULT_MASK (1 << BAT_OVP_FAULT_SHIFT) +#define BAT_OCP_FAULT_MASK (1 << BAT_OCP_FAULT_SHIFT) +#define BUS_OVP_FAULT_MASK (1 << BUS_OVP_FAULT_SHIFT) +#define BUS_OCP_FAULT_MASK (1 << BUS_OCP_FAULT_SHIFT) +#define BAT_THERM_FAULT_MASK (1 << BAT_THERM_FAULT_SHIFT) +#define BUS_THERM_FAULT_MASK (1 << BUS_THERM_FAULT_SHIFT) +#define DIE_THERM_FAULT_MASK (1 << DIE_THERM_FAULT_SHIFT) + +#define BAT_OVP_ALARM_SHIFT 0 +#define BAT_OCP_ALARM_SHIFT 1 +#define BUS_OVP_ALARM_SHIFT 2 +#define BUS_OCP_ALARM_SHIFT 3 +#define BAT_THERM_ALARM_SHIFT 4 +#define BUS_THERM_ALARM_SHIFT 5 +#define DIE_THERM_ALARM_SHIFT 6 +#define BAT_UCP_ALARM_SHIFT 7 + +#define BAT_OVP_ALARM_MASK (1 << BAT_OVP_ALARM_SHIFT) +#define BAT_OCP_ALARM_MASK (1 << BAT_OCP_ALARM_SHIFT) +#define BUS_OVP_ALARM_MASK (1 << BUS_OVP_ALARM_SHIFT) +#define BUS_OCP_ALARM_MASK (1 << BUS_OCP_ALARM_SHIFT) +#define BAT_THERM_ALARM_MASK (1 << BAT_THERM_ALARM_SHIFT) +#define BUS_THERM_ALARM_MASK (1 << BUS_THERM_ALARM_SHIFT) +#define DIE_THERM_ALARM_MASK (1 << DIE_THERM_ALARM_SHIFT) +#define BAT_UCP_ALARM_MASK (1 << BAT_UCP_ALARM_SHIFT) + +#define VBAT_REG_STATUS_SHIFT 0 +#define IBAT_REG_STATUS_SHIFT 1 + +#define VBAT_REG_STATUS_MASK (1 << VBAT_REG_STATUS_SHIFT) +#define IBAT_REG_STATUS_MASK (1 << VBAT_REG_STATUS_SHIFT) + +#define bq_err(fmt, ...) \ + do { \ + if (bq->mode == BQ25970_ROLE_MASTER) \ + printk(KERN_ERR "[bq2597x-MASTER]:%s:" fmt, __func__, \ + ##__VA_ARGS__); \ + else if (bq->mode == BQ25970_ROLE_SLAVE) \ + printk(KERN_ERR "[bq2597x-SLAVE]:%s:" fmt, __func__, \ + ##__VA_ARGS__); \ + else \ + printk(KERN_ERR "[bq2597x-STANDALONE]:%s:" fmt, \ + __func__, ##__VA_ARGS__); \ + } while (0); + +#define bq_info(fmt, ...) \ + do { \ + if (bq->mode == BQ25970_ROLE_MASTER) \ + printk(KERN_INFO "[bq2597x-MASTER]:%s:" fmt, __func__, \ + ##__VA_ARGS__); \ + else if (bq->mode == BQ25970_ROLE_SLAVE) \ + printk(KERN_INFO "[bq2597x-SLAVE]:%s:" fmt, __func__, \ + ##__VA_ARGS__); \ + else \ + printk(KERN_INFO "[bq2597x-STANDALONE]:%s:" fmt, \ + __func__, ##__VA_ARGS__); \ + } while (0); + +#define bq_dbg(fmt, ...) \ + do { \ + if (bq->mode == BQ25970_ROLE_MASTER) \ + printk(KERN_DEBUG "[bq2597x-MASTER]:%s:" fmt, \ + __func__, ##__VA_ARGS__); \ + else if (bq->mode == BQ25970_ROLE_SLAVE) \ + printk(KERN_DEBUG "[bq2597x-SLAVE]:%s:" fmt, __func__, \ + ##__VA_ARGS__); \ + else \ + printk(KERN_DEBUG "[bq2597x-STANDALONE]:%s:" fmt, \ + __func__, ##__VA_ARGS__); \ + } while (0); + +enum hvdcp3_type { + HVDCP3_NONE = 0, + HVDCP3_CLASSA_18W, + HVDCP3_CLASSB_27W, + HVDCP3P5_CLASSA_18W, + HVDCP3P5_CLASSB_27W, +}; + +#define BUS_OVP_FOR_QC 10000 +#define BUS_OVP_ALARM_FOR_QC 9500 +#define BUS_OCP_FOR_QC_CLASS_A 3250 +#define BUS_OCP_ALARM_FOR_QC_CLASS_A 2000 +#define BUS_OCP_FOR_QC_CLASS_B 3750 +#define BUS_OCP_ALARM_FOR_QC_CLASS_B 2800 +#define BUS_OCP_FOR_QC3P5_CLASS_A 3000 +#define BUS_OCP_ALARM_FOR_QC3P5_CLASS_A 2500 +#define BUS_OCP_FOR_QC3P5_CLASS_B 3500 +#define BUS_OCP_ALARM_FOR_QC3P5_CLASS_B 3200 + +/*end*/ + +struct bq2597x_cfg { + bool bat_ovp_disable; + bool bat_ocp_disable; + bool bat_ovp_alm_disable; + bool bat_ocp_alm_disable; + + int bat_ovp_th; + int bat_ovp_alm_th; + int bat_ocp_th; + int bat_ocp_alm_th; + + bool bus_ovp_alm_disable; + bool bus_ocp_disable; + bool bus_ocp_alm_disable; + + int bus_ovp_th; + int bus_ovp_alm_th; + int bus_ocp_th; + int bus_ocp_alm_th; + + bool bat_ucp_alm_disable; + + int bat_ucp_alm_th; + int ac_ovp_th; + + bool bat_therm_disable; + bool bus_therm_disable; + bool die_therm_disable; + + int bat_therm_th; /*in %*/ + int bus_therm_th; /*in %*/ + int die_therm_th; /*in degC*/ + + int sense_r_mohm; +}; + +struct bq2597x { + struct device *dev; + struct i2c_client *client; + + int part_no; + int revision; + + int mode; + + struct mutex data_lock; + struct mutex i2c_rw_lock; + struct mutex charging_disable_lock; + struct mutex irq_complete; + + bool irq_waiting; + bool irq_disabled; + bool resume_completed; + + bool batt_present; + bool vbus_present; + + bool usb_present; + bool charge_enabled; /* Register bit status */ + + /* ADC reading */ + int vbat_volt; + int vbus_volt; + int vout_volt; + int vac_volt; + + int ibat_curr; + int ibus_curr; + + int bat_temp; + int bus_temp; + int die_temp; + + /* alarm/fault status */ + bool bat_ovp_fault; + bool bat_ocp_fault; + bool bus_ovp_fault; + bool bus_ocp_fault; + + bool bat_ovp_alarm; + bool bat_ocp_alarm; + bool bus_ovp_alarm; + bool bus_ocp_alarm; + + bool bat_ucp_alarm; + + bool bat_therm_alarm; + bool bus_therm_alarm; + bool die_therm_alarm; + + bool bat_therm_fault; + bool bus_therm_fault; + bool die_therm_fault; + + bool therm_shutdown_flag; + bool therm_shutdown_stat; + + bool vbat_reg; + bool ibat_reg; + + int prev_alarm; + int prev_fault; + + int chg_ma; + int chg_mv; + + int charge_state; + + struct bq2597x_cfg *cfg; + + int skip_writes; + int skip_reads; + + struct bq2597x_platform_data *platform_data; + + struct delayed_work monitor_work; + + struct dentry *debug_root; + + struct power_supply_desc psy_desc; + struct power_supply_config psy_cfg; + struct power_supply *fc2_psy; +}; + +static int bq_debug_flag; +module_param_named(bq_debug_flag, bq_debug_flag, int, 0600); + +/************************************************************************/ +static int __bq2597x_read_byte(struct bq2597x *bq, u8 reg, u8 *data) +{ + s32 ret; + + ret = i2c_smbus_read_byte_data(bq->client, reg); + if (ret < 0) { + bq_err("i2c read fail: can't read from reg 0x%02X\n", reg); + return ret; + } + + *data = (u8)ret; + + return 0; +} + +static int __bq2597x_write_byte(struct bq2597x *bq, int reg, u8 val) +{ + s32 ret; + + ret = i2c_smbus_write_byte_data(bq->client, reg, val); + if (ret < 0) { + bq_err("i2c write fail: can't write 0x%02X to reg 0x%02X: %d\n", + val, reg, ret); + return ret; + } + return 0; +} + +static int __bq2597x_read_word(struct bq2597x *bq, u8 reg, u16 *data) +{ + s32 ret; + + ret = i2c_smbus_read_word_data(bq->client, reg); + if (ret < 0) { + bq_err("i2c read fail: can't read from reg 0x%02X\n", reg); + return ret; + } + + *data = (u16)ret; + + return 0; +} + +static int bq2597x_read_byte(struct bq2597x *bq, u8 reg, u8 *data) +{ + int ret; + + if (bq->skip_reads) { + *data = 0; + return 0; + } + + mutex_lock(&bq->i2c_rw_lock); + ret = __bq2597x_read_byte(bq, reg, data); + mutex_unlock(&bq->i2c_rw_lock); + + return ret; +} + +static int bq2597x_write_byte(struct bq2597x *bq, u8 reg, u8 data) +{ + int ret; + + if (bq->skip_writes) + return 0; + + mutex_lock(&bq->i2c_rw_lock); + ret = __bq2597x_write_byte(bq, reg, data); + mutex_unlock(&bq->i2c_rw_lock); + + return ret; +} + +static int bq2597x_read_word(struct bq2597x *bq, u8 reg, u16 *data) +{ + int ret; + + if (bq->skip_reads) { + *data = 0; + return 0; + } + + mutex_lock(&bq->i2c_rw_lock); + ret = __bq2597x_read_word(bq, reg, data); + mutex_unlock(&bq->i2c_rw_lock); + + return ret; +} + +static int bq2597x_update_bits(struct bq2597x *bq, u8 reg, u8 mask, u8 data) +{ + int ret; + u8 tmp; + + if (bq->skip_reads || bq->skip_writes) + return 0; + + mutex_lock(&bq->i2c_rw_lock); + ret = __bq2597x_read_byte(bq, reg, &tmp); + if (ret) { + bq_err("Failed: reg=%02X, ret=%d\n", reg, ret); + goto out; + } + + tmp &= ~mask; + tmp |= data & mask; + + ret = __bq2597x_write_byte(bq, reg, tmp); + if (ret) + bq_err("Failed: reg=%02X, ret=%d\n", reg, ret); + +out: + mutex_unlock(&bq->i2c_rw_lock); + return ret; +} + +/*********************************************************************/ + +static int bq2597x_enable_charge(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_CHG_ENABLE; + else + val = BQ2597X_CHG_DISABLE; + + val <<= BQ2597X_CHG_EN_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_0C, BQ2597X_CHG_EN_MASK, val); + + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_charge); + +static int bq2597x_check_charge_enabled(struct bq2597x *bq, bool *enabled) +{ + int ret; + u8 val; + + ret = bq2597x_read_byte(bq, BQ2597X_REG_0C, &val); + if (!ret) + *enabled = !!(val & BQ2597X_CHG_EN_MASK); + return ret; +} + +static int bq2597x_enable_wdt(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_WATCHDOG_ENABLE; + else + val = BQ2597X_WATCHDOG_DISABLE; + + val <<= BQ2597X_WATCHDOG_DIS_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_0B, BQ2597X_WATCHDOG_DIS_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_wdt); + +static int bq2597x_set_wdt(struct bq2597x *bq, int ms) +{ + int ret; + u8 val; + + if (ms == 500) + val = BQ2597X_WATCHDOG_0P5S; + else if (ms == 1000) + val = BQ2597X_WATCHDOG_1S; + else if (ms == 5000) + val = BQ2597X_WATCHDOG_5S; + else if (ms == 30000) + val = BQ2597X_WATCHDOG_30S; + else + val = BQ2597X_WATCHDOG_30S; + + val <<= BQ2597X_WATCHDOG_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_0B, BQ2597X_WATCHDOG_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_wdt); + +static int bq2597x_enable_batovp(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_BAT_OVP_ENABLE; + else + val = BQ2597X_BAT_OVP_DISABLE; + + val <<= BQ2597X_BAT_OVP_DIS_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_00, BQ2597X_BAT_OVP_DIS_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_batovp); + +static int bq2597x_set_batovp_th(struct bq2597x *bq, int threshold) +{ + int ret; + u8 val; + + if (threshold < BQ2597X_BAT_OVP_BASE) + threshold = BQ2597X_BAT_OVP_BASE; + + val = (threshold - BQ2597X_BAT_OVP_BASE) / BQ2597X_BAT_OVP_LSB; + + val <<= BQ2597X_BAT_OVP_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_00, BQ2597X_BAT_OVP_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_batovp_th); + +static int bq2597x_enable_batovp_alarm(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_BAT_OVP_ALM_ENABLE; + else + val = BQ2597X_BAT_OVP_ALM_DISABLE; + + val <<= BQ2597X_BAT_OVP_ALM_DIS_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_01, + BQ2597X_BAT_OVP_ALM_DIS_MASK, val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_batovp_alarm); + +static int bq2597x_set_batovp_alarm_th(struct bq2597x *bq, int threshold) +{ + int ret; + u8 val; + + if (threshold < BQ2597X_BAT_OVP_ALM_BASE) + threshold = BQ2597X_BAT_OVP_ALM_BASE; + + val = (threshold - BQ2597X_BAT_OVP_ALM_BASE) / BQ2597X_BAT_OVP_ALM_LSB; + + val <<= BQ2597X_BAT_OVP_ALM_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_01, BQ2597X_BAT_OVP_ALM_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_batovp_alarm_th); + +static int bq2597x_enable_batocp(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_BAT_OCP_ENABLE; + else + val = BQ2597X_BAT_OCP_DISABLE; + + val <<= BQ2597X_BAT_OCP_DIS_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_02, BQ2597X_BAT_OCP_DIS_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_batocp); + +static int bq2597x_set_batocp_th(struct bq2597x *bq, int threshold) +{ + int ret; + u8 val; + + if (threshold < BQ2597X_BAT_OCP_BASE) + threshold = BQ2597X_BAT_OCP_BASE; + + val = (threshold - BQ2597X_BAT_OCP_BASE) / BQ2597X_BAT_OCP_LSB; + + val <<= BQ2597X_BAT_OCP_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_02, BQ2597X_BAT_OCP_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_batocp_th); + +static int bq2597x_enable_batocp_alarm(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_BAT_OCP_ALM_ENABLE; + else + val = BQ2597X_BAT_OCP_ALM_DISABLE; + + val <<= BQ2597X_BAT_OCP_ALM_DIS_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_03, + BQ2597X_BAT_OCP_ALM_DIS_MASK, val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_batocp_alarm); + +static int bq2597x_set_batocp_alarm_th(struct bq2597x *bq, int threshold) +{ + int ret; + u8 val; + + if (threshold < BQ2597X_BAT_OCP_ALM_BASE) + threshold = BQ2597X_BAT_OCP_ALM_BASE; + + val = (threshold - BQ2597X_BAT_OCP_ALM_BASE) / BQ2597X_BAT_OCP_ALM_LSB; + + val <<= BQ2597X_BAT_OCP_ALM_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_03, BQ2597X_BAT_OCP_ALM_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_batocp_alarm_th); + +static int bq2597x_set_busovp_th(struct bq2597x *bq, int threshold) +{ + int ret; + u8 val; + + if (threshold < BQ2597X_BUS_OVP_BASE) + threshold = BQ2597X_BUS_OVP_BASE; + + val = (threshold - BQ2597X_BUS_OVP_BASE) / BQ2597X_BUS_OVP_LSB; + + val <<= BQ2597X_BUS_OVP_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_06, BQ2597X_BUS_OVP_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_busovp_th); + +static int bq2597x_enable_busovp_alarm(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_BUS_OVP_ALM_ENABLE; + else + val = BQ2597X_BUS_OVP_ALM_DISABLE; + + val <<= BQ2597X_BUS_OVP_ALM_DIS_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_07, + BQ2597X_BUS_OVP_ALM_DIS_MASK, val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_busovp_alarm); + +static int bq2597x_set_busovp_alarm_th(struct bq2597x *bq, int threshold) +{ + int ret; + u8 val; + + if (threshold < BQ2597X_BUS_OVP_ALM_BASE) + threshold = BQ2597X_BUS_OVP_ALM_BASE; + + val = (threshold - BQ2597X_BUS_OVP_ALM_BASE) / BQ2597X_BUS_OVP_ALM_LSB; + + val <<= BQ2597X_BUS_OVP_ALM_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_07, BQ2597X_BUS_OVP_ALM_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_busovp_alarm_th); + +static int bq2597x_enable_busocp(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_BUS_OCP_ENABLE; + else + val = BQ2597X_BUS_OCP_DISABLE; + + val <<= BQ2597X_BUS_OCP_DIS_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_08, BQ2597X_BUS_OCP_DIS_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_busocp); + +static int bq2597x_set_busocp_th(struct bq2597x *bq, int threshold) +{ + int ret; + u8 val; + + if (threshold < BQ2597X_BUS_OCP_BASE) + threshold = BQ2597X_BUS_OCP_BASE; + + val = (threshold - BQ2597X_BUS_OCP_BASE) / BQ2597X_BUS_OCP_LSB; + + val <<= BQ2597X_BUS_OCP_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_08, BQ2597X_BUS_OCP_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_busocp_th); + +static int bq2597x_enable_busocp_alarm(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_BUS_OCP_ALM_ENABLE; + else + val = BQ2597X_BUS_OCP_ALM_DISABLE; + + val <<= BQ2597X_BUS_OCP_ALM_DIS_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_09, + BQ2597X_BUS_OCP_ALM_DIS_MASK, val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_busocp_alarm); + +static int bq2597x_set_busocp_alarm_th(struct bq2597x *bq, int threshold) +{ + int ret; + u8 val; + + if (threshold < BQ2597X_BUS_OCP_ALM_BASE) + threshold = BQ2597X_BUS_OCP_ALM_BASE; + + val = (threshold - BQ2597X_BUS_OCP_ALM_BASE) / BQ2597X_BUS_OCP_ALM_LSB; + + val <<= BQ2597X_BUS_OCP_ALM_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_09, BQ2597X_BUS_OCP_ALM_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_busocp_alarm_th); + +static int bq2597x_enable_batucp_alarm(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_BAT_UCP_ALM_ENABLE; + else + val = BQ2597X_BAT_UCP_ALM_DISABLE; + + val <<= BQ2597X_BAT_UCP_ALM_DIS_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_04, + BQ2597X_BAT_UCP_ALM_DIS_MASK, val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_batucp_alarm); + +static int bq2597x_set_batucp_alarm_th(struct bq2597x *bq, int threshold) +{ + int ret; + u8 val; + + if (threshold < BQ2597X_BAT_UCP_ALM_BASE) + threshold = BQ2597X_BAT_UCP_ALM_BASE; + + val = (threshold - BQ2597X_BAT_UCP_ALM_BASE) / BQ2597X_BAT_UCP_ALM_LSB; + + val <<= BQ2597X_BAT_UCP_ALM_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_04, BQ2597X_BAT_UCP_ALM_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_batucp_alarm_th); + +static int bq2597x_set_acovp_th(struct bq2597x *bq, int threshold) +{ + int ret; + u8 val; + + if (threshold < BQ2597X_AC_OVP_BASE) + threshold = BQ2597X_AC_OVP_BASE; + + if (threshold == BQ2597X_AC_OVP_6P5V) + val = 0x07; + else + val = (threshold - BQ2597X_AC_OVP_BASE) / BQ2597X_AC_OVP_LSB; + + val <<= BQ2597X_AC_OVP_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_05, BQ2597X_AC_OVP_MASK, val); + + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_acovp_th); + +static int bq2597x_set_vdrop_th(struct bq2597x *bq, int threshold) +{ + int ret; + u8 val; + + if (threshold == 300) + val = BQ2597X_VDROP_THRESHOLD_300MV; + else + val = BQ2597X_VDROP_THRESHOLD_400MV; + + val <<= BQ2597X_VDROP_THRESHOLD_SET_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_05, + BQ2597X_VDROP_THRESHOLD_SET_MASK, val); + + return ret; +} + +static int bq2597x_set_vdrop_deglitch(struct bq2597x *bq, int us) +{ + int ret; + u8 val; + + if (us == 8) + val = BQ2597X_VDROP_DEGLITCH_8US; + else + val = BQ2597X_VDROP_DEGLITCH_5MS; + + val <<= BQ2597X_VDROP_DEGLITCH_SET_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_05, + BQ2597X_VDROP_DEGLITCH_SET_MASK, val); + return ret; +} + +static int bq2597x_enable_bat_therm(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_TSBAT_ENABLE; + else + val = BQ2597X_TSBAT_DISABLE; + + val <<= BQ2597X_TSBAT_DIS_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_0C, BQ2597X_TSBAT_DIS_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_bat_therm); + +/* + * the input threshold is the raw value that would write to register directly. + */ +static int bq2597x_set_bat_therm_th(struct bq2597x *bq, u8 threshold) +{ + int ret; + + ret = bq2597x_write_byte(bq, BQ2597X_REG_29, threshold); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_bat_therm_th); + +static int bq2597x_enable_bus_therm(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_TSBUS_ENABLE; + else + val = BQ2597X_TSBUS_DISABLE; + + val <<= BQ2597X_TSBUS_DIS_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_0C, BQ2597X_TSBUS_DIS_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_bus_therm); + +/* + * the input threshold is the raw value that would write to register directly. + */ +static int bq2597x_set_bus_therm_th(struct bq2597x *bq, u8 threshold) +{ + int ret; + + ret = bq2597x_write_byte(bq, BQ2597X_REG_28, threshold); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_bus_therm_th); + +static int bq2597x_enable_die_therm(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_TDIE_ENABLE; + else + val = BQ2597X_TDIE_DISABLE; + + val <<= BQ2597X_TDIE_DIS_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_0C, BQ2597X_TDIE_DIS_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_die_therm); + +/* + * please be noted that the unit here is degC + */ +static int bq2597x_set_die_therm_th(struct bq2597x *bq, u8 threshold) +{ + int ret; + u8 val; + + /*BE careful, LSB is here is 1/LSB, so we use multiply here*/ + val = (threshold - BQ2597X_TDIE_ALM_BASE) * BQ2597X_TDIE_ALM_LSB; + val <<= BQ2597X_TDIE_ALM_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_2A, BQ2597X_TDIE_ALM_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_die_therm_th); + +static int bq2597x_enable_adc(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_ADC_ENABLE; + else + val = BQ2597X_ADC_DISABLE; + + val <<= BQ2597X_ADC_EN_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_14, BQ2597X_ADC_EN_MASK, val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_enable_adc); + +static int bq2597x_set_adc_average(struct bq2597x *bq, bool avg) +{ + int ret; + u8 val; + + if (avg) + val = BQ2597X_ADC_AVG_ENABLE; + else + val = BQ2597X_ADC_AVG_DISABLE; + + val <<= BQ2597X_ADC_AVG_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_14, BQ2597X_ADC_AVG_MASK, + val); + return 0; +} +EXPORT_SYMBOL_GPL(bq2597x_set_adc_average); + +static int bq2597x_set_adc_scanrate(struct bq2597x *bq, bool oneshot) +{ + int ret; + u8 val; + + if (oneshot) + val = BQ2597X_ADC_RATE_ONESHOT; + else + val = BQ2597X_ADC_RATE_CONTINOUS; + + val <<= BQ2597X_ADC_RATE_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_14, BQ2597X_ADC_EN_MASK, val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_adc_scanrate); + +static int bq2597x_set_adc_bits(struct bq2597x *bq, int bits) +{ + int ret; + u8 val; + + if (bits > 15) + bits = 15; + if (bits < 12) + bits = 12; + val = 15 - bits; + + val <<= BQ2597X_ADC_SAMPLE_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_14, BQ2597X_ADC_SAMPLE_MASK, + val); + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_adc_bits); + +#define ADC_REG_BASE 0x16 +static int bq2597x_get_adc_data(struct bq2597x *bq, int channel, int *result) +{ + int ret; + u16 val; + s16 t; + + if (channel > ADC_MAX_NUM) + return -EINVAL; + + ret = bq2597x_read_word(bq, ADC_REG_BASE + (channel << 1), &val); + if (ret < 0) + return ret; + t = val & 0xFF; + t <<= 8; + t |= (val >> 8) & 0xFF; + *result = t; + + return 0; +} +EXPORT_SYMBOL_GPL(bq2597x_get_adc_data); + +static int bq2597x_set_adc_scan(struct bq2597x *bq, int channel, bool enable) +{ + int ret; + u8 reg; + u8 mask; + u8 shift; + u8 val; + + if (channel > ADC_MAX_NUM) + return -EINVAL; + + if (channel == ADC_IBUS) { + reg = BQ2597X_REG_14; + shift = BQ2597X_IBUS_ADC_DIS_SHIFT; + mask = BQ2597X_IBUS_ADC_DIS_MASK; + } else { + reg = BQ2597X_REG_15; + shift = 8 - channel; + mask = 1 << shift; + } + + if (enable) + val = 0 << shift; + else + val = 1 << shift; + + ret = bq2597x_update_bits(bq, reg, mask, val); + + return ret; +} + +static int bq2597x_set_alarm_int_mask(struct bq2597x *bq, u8 mask) +{ + int ret; + u8 val; + + ret = bq2597x_read_byte(bq, BQ2597X_REG_0F, &val); + if (ret) + return ret; + + val |= mask; + + ret = bq2597x_write_byte(bq, BQ2597X_REG_0F, val); + + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_alarm_int_mask); + +static int bq2597x_clear_alarm_int_mask(struct bq2597x *bq, u8 mask) +{ + int ret; + u8 val; + + ret = bq2597x_read_byte(bq, BQ2597X_REG_0F, &val); + if (ret) + return ret; + + val &= ~mask; + + ret = bq2597x_write_byte(bq, BQ2597X_REG_0F, val); + + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_clear_alarm_int_mask); + +static int bq2597x_set_fault_int_mask(struct bq2597x *bq, u8 mask) +{ + int ret; + u8 val; + + ret = bq2597x_read_byte(bq, BQ2597X_REG_12, &val); + if (ret) + return ret; + + val |= mask; + + ret = bq2597x_write_byte(bq, BQ2597X_REG_12, val); + + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_set_fault_int_mask); + +static int bq2597x_clear_fault_int_mask(struct bq2597x *bq, u8 mask) +{ + int ret; + u8 val; + + ret = bq2597x_read_byte(bq, BQ2597X_REG_12, &val); + if (ret) + return ret; + + val &= ~mask; + + ret = bq2597x_write_byte(bq, BQ2597X_REG_12, val); + + return ret; +} +EXPORT_SYMBOL_GPL(bq2597x_clear_fault_int_mask); + +static int bq2597x_set_sense_resistor(struct bq2597x *bq, int r_mohm) +{ + int ret; + u8 val; + + if (r_mohm == 2) + val = BQ2597X_SET_IBAT_SNS_RES_2MHM; + else if (r_mohm == 5) + val = BQ2597X_SET_IBAT_SNS_RES_5MHM; + else + return -EINVAL; + + val <<= BQ2597X_SET_IBAT_SNS_RES_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_2B, + BQ2597X_SET_IBAT_SNS_RES_MASK, val); + return ret; +} + +static int bq2597x_set_ibus_ucp_thr(struct bq2597x *bq, int ibus_ucp_thr) +{ + int ret; + u8 val; + + if (ibus_ucp_thr == 300) + val = BQ2597X_IBUS_UCP_RISE_300MA; + else if (ibus_ucp_thr == 500) + val = BQ2597X_IBUS_UCP_RISE_500MA; + else + return -EINVAL; + + val <<= BQ2597X_IBUS_UCP_RISE_TH_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_2B, + BQ2597X_IBUS_UCP_RISE_TH_MASK, val); + return ret; +} + +static int bq2597x_enable_regulation(struct bq2597x *bq, bool enable) +{ + int ret; + u8 val; + + if (enable) + val = BQ2597X_EN_REGULATION_ENABLE; + else + val = BQ2597X_EN_REGULATION_DISABLE; + + val <<= BQ2597X_EN_REGULATION_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_2B, + BQ2597X_EN_REGULATION_MASK, val); + + return ret; +} + +static int bq2597x_set_ss_timeout(struct bq2597x *bq, int timeout) +{ + int ret; + u8 val; + + switch (timeout) { + case 0: + val = BQ2597X_SS_TIMEOUT_DISABLE; + break; + case 12: + val = BQ2597X_SS_TIMEOUT_12P5MS; + break; + case 25: + val = BQ2597X_SS_TIMEOUT_25MS; + break; + case 50: + val = BQ2597X_SS_TIMEOUT_50MS; + break; + case 100: + val = BQ2597X_SS_TIMEOUT_100MS; + break; + case 400: + val = BQ2597X_SS_TIMEOUT_400MS; + break; + case 1500: + val = BQ2597X_SS_TIMEOUT_1500MS; + break; + case 100000: + val = BQ2597X_SS_TIMEOUT_100000MS; + break; + default: + val = BQ2597X_SS_TIMEOUT_DISABLE; + break; + } + + val <<= BQ2597X_SS_TIMEOUT_SET_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_2B, + BQ2597X_SS_TIMEOUT_SET_MASK, val); + + return ret; +} + +static int bq2597x_set_ibat_reg_th(struct bq2597x *bq, int th_ma) +{ + int ret; + u8 val; + + if (th_ma == 200) + val = BQ2597X_IBAT_REG_200MA; + else if (th_ma == 300) + val = BQ2597X_IBAT_REG_300MA; + else if (th_ma == 400) + val = BQ2597X_IBAT_REG_400MA; + else if (th_ma == 500) + val = BQ2597X_IBAT_REG_500MA; + else + val = BQ2597X_IBAT_REG_500MA; + + val <<= BQ2597X_IBAT_REG_SHIFT; + ret = bq2597x_update_bits(bq, BQ2597X_REG_2C, BQ2597X_IBAT_REG_MASK, + val); + + return ret; +} + +static int bq2597x_set_vbat_reg_th(struct bq2597x *bq, int th_mv) +{ + int ret; + u8 val; + + if (th_mv == 50) + val = BQ2597X_VBAT_REG_50MV; + else if (th_mv == 100) + val = BQ2597X_VBAT_REG_100MV; + else if (th_mv == 150) + val = BQ2597X_VBAT_REG_150MV; + else + val = BQ2597X_VBAT_REG_200MV; + + val <<= BQ2597X_VBAT_REG_SHIFT; + + ret = bq2597x_update_bits(bq, BQ2597X_REG_2C, BQ2597X_VBAT_REG_MASK, + val); + + return ret; +} + +static int bq2597x_check_reg_status(struct bq2597x *bq) +{ + int ret; + u8 val; + + ret = bq2597x_read_byte(bq, BQ2597X_REG_2C, &val); + if (!ret) { + bq->vbat_reg = !!(val & BQ2597X_VBAT_REG_ACTIVE_STAT_MASK); + bq->ibat_reg = !!(val & BQ2597X_IBAT_REG_ACTIVE_STAT_MASK); + } + + return ret; +} + +static int bq2597x_get_work_mode(struct bq2597x *bq, int *mode) +{ + int ret; + u8 val; + + ret = bq2597x_read_byte(bq, BQ2597X_REG_0C, &val); + + if (ret) { + bq_err("Failed to read operation mode register\n"); + return ret; + } + + val = (val & BQ2597X_MS_MASK) >> BQ2597X_MS_SHIFT; + if (val == BQ2597X_MS_MASTER) + *mode = BQ25970_ROLE_MASTER; + else if (val == BQ2597X_MS_SLAVE) + *mode = BQ25970_ROLE_SLAVE; + else + *mode = BQ25970_ROLE_STDALONE; + + bq_info("work mode:%s\n", + *mode == BQ25970_ROLE_STDALONE ? + "Standalone" : + (*mode == BQ25970_ROLE_SLAVE ? "Slave" : "Master")); + return ret; +} + +static int bq2597x_detect_device(struct bq2597x *bq) +{ + int ret; + u8 data; + + ret = bq2597x_read_byte(bq, BQ2597X_REG_13, &data); + if (ret == 0) { + bq->part_no = (data & BQ2597X_DEV_ID_MASK); + bq->part_no >>= BQ2597X_DEV_ID_SHIFT; + } + + return ret; +} + +static void bq2597x_dump_reg(struct bq2597x *bq); +#define RUNNING_PERIOD_S (60 * 1000) + +static void bq2597x_monitor_work(struct work_struct *work) +{ + struct bq2597x *bq = + container_of(work, struct bq2597x, monitor_work.work); + bq2597x_dump_reg(bq); + schedule_delayed_work(&bq->monitor_work, + msecs_to_jiffies(RUNNING_PERIOD_S)); +} + +static int bq2597x_parse_dt(struct bq2597x *bq, struct device *dev) +{ + int ret; + struct device_node *np = dev->of_node; + + bq->cfg = devm_kzalloc(dev, sizeof(struct bq2597x_cfg), GFP_KERNEL); + + if (!bq->cfg) + return -ENOMEM; + + bq->cfg->bat_ovp_disable = + of_property_read_bool(np, "ti,bq2597x,bat-ovp-disable"); + bq->cfg->bat_ocp_disable = + of_property_read_bool(np, "ti,bq2597x,bat-ocp-disable"); + bq->cfg->bat_ovp_alm_disable = + of_property_read_bool(np, "ti,bq2597x,bat-ovp-alarm-disable"); + bq->cfg->bat_ocp_alm_disable = + of_property_read_bool(np, "ti,bq2597x,bat-ocp-alarm-disable"); + bq->cfg->bus_ocp_disable = + of_property_read_bool(np, "ti,bq2597x,bus-ocp-disable"); + bq->cfg->bus_ovp_alm_disable = + of_property_read_bool(np, "ti,bq2597x,bus-ovp-alarm-disable"); + bq->cfg->bus_ocp_alm_disable = + of_property_read_bool(np, "ti,bq2597x,bus-ocp-alarm-disable"); + bq->cfg->bat_ucp_alm_disable = + of_property_read_bool(np, "ti,bq2597x,bat-ucp-alarm-disable"); + bq->cfg->bat_therm_disable = + of_property_read_bool(np, "ti,bq2597x,bat-therm-disable"); + bq->cfg->bus_therm_disable = + of_property_read_bool(np, "ti,bq2597x,bus-therm-disable"); + bq->cfg->die_therm_disable = + of_property_read_bool(np, "ti,bq2597x,die-therm-disable"); + + ret = of_property_read_u32(np, "ti,bq2597x,bat-ovp-threshold", + &bq->cfg->bat_ovp_th); + if (ret) { + bq_err("failed to read bat-ovp-threshold\n"); + return ret; + } + ret = of_property_read_u32(np, "ti,bq2597x,bat-ovp-alarm-threshold", + &bq->cfg->bat_ovp_alm_th); + if (ret) { + bq_err("failed to read bat-ovp-alarm-threshold\n"); + return ret; + } + /*ret = of_property_read_u32(np, "ti,bq2597x,bat-ocp-threshold", + &bq->cfg->bat_ocp_th); + if (ret) { + bq_err("failed to read bat-ocp-threshold\n"); + return ret; + } + ret = of_property_read_u32(np, "ti,bq2597x,bat-ocp-alarm-threshold", + &bq->cfg->bat_ocp_alm_th); + if (ret) { + bq_err("failed to read bat-ocp-alarm-threshold\n"); + return ret; + }*/ + ret = of_property_read_u32(np, "ti,bq2597x,bus-ovp-threshold", + &bq->cfg->bus_ovp_th); + if (ret) { + bq_err("failed to read bus-ovp-threshold\n"); + return ret; + } + ret = of_property_read_u32(np, "ti,bq2597x,bus-ovp-alarm-threshold", + &bq->cfg->bus_ovp_alm_th); + if (ret) { + bq_err("failed to read bus-ovp-alarm-threshold\n"); + return ret; + } + ret = of_property_read_u32(np, "ti,bq2597x,bus-ocp-threshold", + &bq->cfg->bus_ocp_th); + if (ret) { + bq_err("failed to read bus-ocp-threshold\n"); + return ret; + } + ret = of_property_read_u32(np, "ti,bq2597x,bus-ocp-alarm-threshold", + &bq->cfg->bus_ocp_alm_th); + if (ret) { + bq_err("failed to read bus-ocp-alarm-threshold\n"); + return ret; + } + /*ret = of_property_read_u32(np, "ti,bq2597x,bat-ucp-alarm-threshold", + &bq->cfg->bat_ucp_alm_th); + if (ret) { + bq_err("failed to read bat-ucp-alarm-threshold\n"); + return ret; + }*/ + ret = of_property_read_u32(np, "ti,bq2597x,bat-therm-threshold", + &bq->cfg->bat_therm_th); + if (ret) { + bq_err("failed to read bat-therm-threshold\n"); + return ret; + } + ret = of_property_read_u32(np, "ti,bq2597x,bus-therm-threshold", + &bq->cfg->bus_therm_th); + if (ret) { + bq_err("failed to read bus-therm-threshold\n"); + return ret; + } + ret = of_property_read_u32(np, "ti,bq2597x,die-therm-threshold", + &bq->cfg->die_therm_th); + if (ret) { + bq_err("failed to read die-therm-threshold\n"); + return ret; + } + + ret = of_property_read_u32(np, "ti,bq2597x,ac-ovp-threshold", + &bq->cfg->ac_ovp_th); + if (ret) { + bq_err("failed to read ac-ovp-threshold\n"); + return ret; + } + + /*ret = of_property_read_u32(np, "ti,bq2597x,sense-resistor-mohm", + &bq->cfg->sense_r_mohm); + if (ret) { + bq_err("failed to read sense-resistor-mohm\n"); + return ret; + }*/ + + return 0; +} + +static int bq2597x_init_protection(struct bq2597x *bq) +{ + int ret; + + ret = bq2597x_enable_batovp(bq, !bq->cfg->bat_ovp_disable); + bq_info("%s bat ovp %s\n", + bq->cfg->bat_ovp_disable ? "disable" : "enable", + !ret ? "successfullly" : "failed"); + + ret = bq2597x_enable_batocp(bq, !bq->cfg->bat_ocp_disable); + bq_info("%s bat ocp %s\n", + bq->cfg->bat_ocp_disable ? "disable" : "enable", + !ret ? "successfullly" : "failed"); + + ret = bq2597x_enable_batovp_alarm(bq, !bq->cfg->bat_ovp_alm_disable); + bq_info("%s bat ovp alarm %s\n", + bq->cfg->bat_ovp_alm_disable ? "disable" : "enable", + !ret ? "successfullly" : "failed"); + + ret = bq2597x_enable_batocp_alarm(bq, !bq->cfg->bat_ocp_alm_disable); + bq_info("%s bat ocp alarm %s\n", + bq->cfg->bat_ocp_alm_disable ? "disable" : "enable", + !ret ? "successfullly" : "failed"); + + ret = bq2597x_enable_batucp_alarm(bq, !bq->cfg->bat_ucp_alm_disable); + bq_info("%s bat ocp alarm %s\n", + bq->cfg->bat_ucp_alm_disable ? "disable" : "enable", + !ret ? "successfullly" : "failed"); + + ret = bq2597x_enable_busovp_alarm(bq, !bq->cfg->bus_ovp_alm_disable); + bq_info("%s bus ovp alarm %s\n", + bq->cfg->bus_ovp_alm_disable ? "disable" : "enable", + !ret ? "successfullly" : "failed"); + + ret = bq2597x_enable_busocp(bq, !bq->cfg->bus_ocp_disable); + bq_info("%s bus ocp %s\n", + bq->cfg->bus_ocp_disable ? "disable" : "enable", + !ret ? "successfullly" : "failed"); + + ret = bq2597x_enable_busocp_alarm(bq, !bq->cfg->bus_ocp_alm_disable); + bq_info("%s bus ocp alarm %s\n", + bq->cfg->bus_ocp_alm_disable ? "disable" : "enable", + !ret ? "successfullly" : "failed"); + + ret = bq2597x_enable_bat_therm(bq, !bq->cfg->bat_therm_disable); + bq_info("%s bat therm %s\n", + bq->cfg->bat_therm_disable ? "disable" : "enable", + !ret ? "successfullly" : "failed"); + + ret = bq2597x_enable_bus_therm(bq, !bq->cfg->bus_therm_disable); + bq_info("%s bus therm %s\n", + bq->cfg->bus_therm_disable ? "disable" : "enable", + !ret ? "successfullly" : "failed"); + + ret = bq2597x_enable_die_therm(bq, !bq->cfg->die_therm_disable); + bq_info("%s die therm %s\n", + bq->cfg->die_therm_disable ? "disable" : "enable", + !ret ? "successfullly" : "failed"); + + ret = bq2597x_set_batovp_th(bq, bq->cfg->bat_ovp_th); + bq_info("set bat ovp th %d %s\n", bq->cfg->bat_ovp_th, + !ret ? "successfully" : "failed"); + + ret = bq2597x_set_batovp_alarm_th(bq, bq->cfg->bat_ovp_alm_th); + bq_info("set bat ovp alarm threshold %d %s\n", bq->cfg->bat_ovp_alm_th, + !ret ? "successfully" : "failed"); + + ret = bq2597x_set_batocp_th(bq, bq->cfg->bat_ocp_th); + bq_info("set bat ocp threshold %d %s\n", bq->cfg->bat_ocp_th, + !ret ? "successfully" : "failed"); + + ret = bq2597x_set_batocp_alarm_th(bq, bq->cfg->bat_ocp_alm_th); + bq_info("set bat ocp alarm threshold %d %s\n", bq->cfg->bat_ocp_alm_th, + !ret ? "successfully" : "failed"); + + ret = bq2597x_set_busovp_th(bq, bq->cfg->bus_ovp_th); + bq_info("set bus ovp threshold %d %s\n", bq->cfg->bus_ovp_th, + !ret ? "successfully" : "failed"); + + ret = bq2597x_set_busovp_alarm_th(bq, bq->cfg->bus_ovp_alm_th); + bq_info("set bus ovp alarm threshold %d %s\n", bq->cfg->bus_ovp_alm_th, + !ret ? "successfully" : "failed"); + + ret = bq2597x_set_busocp_th(bq, bq->cfg->bus_ocp_th); + bq_info("set bus ocp threshold %d %s\n", bq->cfg->bus_ocp_th, + !ret ? "successfully" : "failed"); + + ret = bq2597x_set_busocp_alarm_th(bq, bq->cfg->bus_ocp_alm_th); + bq_info("set bus ocp alarm th %d %s\n", bq->cfg->bus_ocp_alm_th, + !ret ? "successfully" : "failed"); + + ret = bq2597x_set_batucp_alarm_th(bq, bq->cfg->bat_ucp_alm_th); + bq_info("set bat ucp threshold %d %s\n", bq->cfg->bat_ucp_alm_th, + !ret ? "successfully" : "failed"); + + ret = bq2597x_set_bat_therm_th(bq, bq->cfg->bat_therm_th); + bq_info("set die therm threshold %d %s\n", bq->cfg->bat_therm_th, + !ret ? "successfully" : "failed"); + ret = bq2597x_set_bus_therm_th(bq, bq->cfg->bus_therm_th); + bq_info("set bus therm threshold %d %s\n", bq->cfg->bus_therm_th, + !ret ? "successfully" : "failed"); + ret = bq2597x_set_die_therm_th(bq, bq->cfg->die_therm_th); + bq_info("set die therm threshold %d %s\n", bq->cfg->die_therm_th, + !ret ? "successfully" : "failed"); + + ret = bq2597x_set_acovp_th(bq, bq->cfg->ac_ovp_th); + bq_info("set ac ovp threshold %d %s\n", bq->cfg->ac_ovp_th, + !ret ? "successfully" : "failed"); + + return 0; +} + +static int bq2597x_set_bus_protection(struct bq2597x *bq, int hvdcp3_type) +{ + /* just return now, to do later */ + //return 0; + + pr_err("hvdcp3_type: %d\n", hvdcp3_type); + if (hvdcp3_type == HVDCP3_CLASSA_18W) { + bq2597x_set_busovp_th(bq, BUS_OVP_FOR_QC); + bq2597x_set_busovp_alarm_th(bq, BUS_OVP_ALARM_FOR_QC); + bq2597x_set_busocp_th(bq, BUS_OCP_FOR_QC_CLASS_A); + bq2597x_set_busocp_alarm_th(bq, BUS_OCP_ALARM_FOR_QC_CLASS_A); + } else if (hvdcp3_type == HVDCP3_CLASSB_27W) { + bq2597x_set_busovp_th(bq, BUS_OVP_FOR_QC); + bq2597x_set_busovp_alarm_th(bq, BUS_OVP_ALARM_FOR_QC); + bq2597x_set_busocp_th(bq, BUS_OCP_FOR_QC_CLASS_B); + bq2597x_set_busocp_alarm_th(bq, BUS_OCP_ALARM_FOR_QC_CLASS_B); + } else if (hvdcp3_type == HVDCP3P5_CLASSA_18W) { + bq2597x_set_busovp_th(bq, BUS_OVP_FOR_QC); + bq2597x_set_busovp_alarm_th(bq, BUS_OVP_ALARM_FOR_QC); + bq2597x_set_busocp_th(bq, BUS_OCP_FOR_QC3P5_CLASS_A); + bq2597x_set_busocp_alarm_th(bq, + BUS_OCP_ALARM_FOR_QC3P5_CLASS_A); + } else if (hvdcp3_type == HVDCP3P5_CLASSB_27W) { + bq2597x_set_busovp_th(bq, BUS_OVP_FOR_QC); + bq2597x_set_busovp_alarm_th(bq, BUS_OVP_ALARM_FOR_QC); + bq2597x_set_busocp_th(bq, BUS_OCP_FOR_QC3P5_CLASS_B); + bq2597x_set_busocp_alarm_th(bq, + BUS_OCP_ALARM_FOR_QC3P5_CLASS_B); + } else { + bq2597x_set_busovp_th(bq, bq->cfg->bus_ovp_th); + bq2597x_set_busovp_alarm_th(bq, bq->cfg->bus_ovp_alm_th); + bq2597x_set_busocp_th(bq, bq->cfg->bus_ocp_th); + bq2597x_set_busocp_alarm_th(bq, bq->cfg->bus_ocp_alm_th); + } + return 0; +} + +static int bq2597x_init_adc(struct bq2597x *bq) +{ + bq2597x_set_adc_scanrate(bq, false); + bq2597x_set_adc_bits(bq, 13); + bq2597x_set_adc_average(bq, true); + bq2597x_set_adc_scan(bq, ADC_IBUS, true); + bq2597x_set_adc_scan(bq, ADC_VBUS, true); + bq2597x_set_adc_scan(bq, ADC_VOUT, false); + bq2597x_set_adc_scan(bq, ADC_VBAT, true); + bq2597x_set_adc_scan(bq, ADC_IBAT, false); + bq2597x_set_adc_scan(bq, ADC_TBUS, false); + bq2597x_set_adc_scan(bq, ADC_TBAT, false); + bq2597x_set_adc_scan(bq, ADC_TDIE, false); + bq2597x_set_adc_scan(bq, ADC_VAC, true); + + bq2597x_enable_adc(bq, true); + + return 0; +} + +static int bq2597x_init_int_src(struct bq2597x *bq) +{ + int ret; + /*TODO:be careful ts bus and ts bat alarm bit mask is in + * fault mask register, so you need call + * bq2597x_set_fault_int_mask for tsbus and tsbat alarm + */ + ret = bq2597x_set_alarm_int_mask( + bq, ADC_DONE | BAT_OCP_ALARM | BAT_UCP_ALARM | BAT_OVP_ALARM); + if (ret) { + bq_err("failed to set alarm mask:%d\n", ret); + return ret; + } + //#if 0 + ret = bq2597x_set_fault_int_mask( + bq, TS_BUS_FAULT | TS_DIE_FAULT | TS_BAT_FAULT | BAT_OCP_FAULT); + if (ret) { + bq_err("failed to set fault mask:%d\n", ret); + return ret; + } + //#endif + return ret; +} + +static int bq2597x_init_regulation(struct bq2597x *bq) +{ + bq2597x_set_ibat_reg_th(bq, 200); + bq2597x_set_vbat_reg_th(bq, 50); + + bq2597x_set_vdrop_deglitch(bq, 5000); + bq2597x_set_vdrop_th(bq, 400); + + bq2597x_enable_regulation(bq, true); + + return 0; +} + +static int bq2597x_init_device(struct bq2597x *bq) +{ + bq2597x_enable_wdt(bq, false); + + bq2597x_set_ss_timeout(bq, 100000); + bq2597x_set_ibus_ucp_thr(bq, 300); + bq2597x_set_sense_resistor(bq, bq->cfg->sense_r_mohm); + + bq2597x_init_protection(bq); + bq2597x_init_adc(bq); + bq2597x_init_int_src(bq); + + bq2597x_init_regulation(bq); + + return 0; +} + +static int bq2597x_set_present(struct bq2597x *bq, bool present) +{ + bq->usb_present = present; + + if (present) + bq2597x_init_device(bq); + return 0; +} + +static ssize_t bq2597x_show_registers(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct bq2597x *bq = dev_get_drvdata(dev); + u8 addr; + u8 val; + u8 tmpbuf[300]; + int len; + int idx = 0; + int ret; + + idx = snprintf(buf, PAGE_SIZE, "%s:\n", "bq25970"); + for (addr = 0x0; addr <= 0x2A; addr++) { + ret = bq2597x_read_byte(bq, addr, &val); + if (ret == 0) { + len = snprintf(tmpbuf, PAGE_SIZE - idx, + "Reg[%.2X] = 0x%.2x\n", addr, val); + memcpy(&buf[idx], tmpbuf, len); + idx += len; + } + } + + return idx; +} + +static ssize_t bq2597x_store_register(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct bq2597x *bq = dev_get_drvdata(dev); + int ret; + unsigned int reg; + unsigned int val; + + ret = sscanf(buf, "%x %x", ®, &val); + if (ret == 2 && reg <= 0x2A) + bq2597x_write_byte(bq, (unsigned char)reg, (unsigned char)val); + + return count; +} + +static DEVICE_ATTR(registers, 0660, bq2597x_show_registers, + bq2597x_store_register); + +static struct attribute *bq2597x_attributes[] = { + &dev_attr_registers.attr, + NULL, +}; + +static const struct attribute_group bq2597x_attr_group = { + .attrs = bq2597x_attributes, +}; + +static enum power_supply_property bq2597x_charger_props[] = { + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_CHARGING_ENABLED, + POWER_SUPPLY_PROP_STATUS, + + POWER_SUPPLY_PROP_TI_BATTERY_PRESENT, + POWER_SUPPLY_PROP_TI_VBUS_PRESENT, + POWER_SUPPLY_PROP_TI_BATTERY_VOLTAGE, + POWER_SUPPLY_PROP_TI_BATTERY_CURRENT, + POWER_SUPPLY_PROP_TI_BATTERY_TEMPERATURE, + POWER_SUPPLY_PROP_TI_BUS_VOLTAGE, + POWER_SUPPLY_PROP_TI_BUS_CURRENT, + POWER_SUPPLY_PROP_TI_BUS_TEMPERATURE, + POWER_SUPPLY_PROP_TI_DIE_TEMPERATURE, + POWER_SUPPLY_PROP_TI_ALARM_STATUS, + POWER_SUPPLY_PROP_TI_FAULT_STATUS, + POWER_SUPPLY_PROP_TI_REG_STATUS, + POWER_SUPPLY_PROP_TI_SET_BUS_PROTECTION_FOR_QC3, + POWER_SUPPLY_PROP_MODEL_NAME, +}; + +static void bq2597x_check_alarm_status(struct bq2597x *bq); +static void bq2597x_check_fault_status(struct bq2597x *bq); +static int bq2597x_check_vbus_error_status(struct bq2597x *bq); + +static int bq2597x_charger_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct bq2597x *bq = power_supply_get_drvdata(psy); + int result; + int ret; + u8 reg_val; + + switch (psp) { + case POWER_SUPPLY_PROP_CHARGING_ENABLED: + bq2597x_check_charge_enabled(bq, &bq->charge_enabled); + val->intval = bq->charge_enabled; + break; + case POWER_SUPPLY_PROP_STATUS: + val->intval = 0; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = bq->usb_present; + break; + case POWER_SUPPLY_PROP_TI_BATTERY_PRESENT: + ret = bq2597x_read_byte(bq, BQ2597X_REG_0D, ®_val); + if (!ret) + bq->batt_present = !!(reg_val & VBAT_INSERT); + val->intval = bq->batt_present; + break; + case POWER_SUPPLY_PROP_TI_VBUS_PRESENT: + ret = bq2597x_read_byte(bq, BQ2597X_REG_0D, ®_val); + if (!ret) + bq->vbus_present = !!(reg_val & VBUS_INSERT); + val->intval = bq->vbus_present; + break; + case POWER_SUPPLY_PROP_TI_BATTERY_VOLTAGE: + ret = bq2597x_get_adc_data(bq, ADC_VBAT, &result); + if (!ret) + bq->vbat_volt = result; + + val->intval = bq->vbat_volt; + break; + case POWER_SUPPLY_PROP_TI_BATTERY_CURRENT: + ret = bq2597x_get_adc_data(bq, ADC_IBAT, &result); + if (!ret) + bq->ibat_curr = result; + + val->intval = bq->ibat_curr; + break; + case POWER_SUPPLY_PROP_TI_BATTERY_TEMPERATURE: + ret = bq2597x_get_adc_data(bq, ADC_TBAT, &result); + if (!ret) + bq->bat_temp = result; + + val->intval = bq->bat_temp; + break; + case POWER_SUPPLY_PROP_TI_BUS_VOLTAGE: + ret = bq2597x_get_adc_data(bq, ADC_VBUS, &result); + if (!ret) + bq->vbus_volt = result; + + val->intval = bq->vbus_volt; + break; + case POWER_SUPPLY_PROP_TI_BUS_CURRENT: + ret = bq2597x_get_adc_data(bq, ADC_IBUS, &result); + if (!ret) + bq->ibus_curr = result; + + val->intval = bq->ibus_curr; + break; + case POWER_SUPPLY_PROP_TI_BUS_TEMPERATURE: + ret = bq2597x_get_adc_data(bq, ADC_TBUS, &result); + if (!ret) + bq->bus_temp = result; + + val->intval = bq->bus_temp; + break; + case POWER_SUPPLY_PROP_TI_DIE_TEMPERATURE: + ret = bq2597x_get_adc_data(bq, ADC_TDIE, &result); + if (!ret) + bq->die_temp = result; + + val->intval = bq->die_temp; + break; + case POWER_SUPPLY_PROP_TI_ALARM_STATUS: + + bq2597x_check_alarm_status(bq); + + val->intval = ((bq->bat_ovp_alarm << BAT_OVP_ALARM_SHIFT) | + (bq->bat_ocp_alarm << BAT_OCP_ALARM_SHIFT) | + (bq->bat_ucp_alarm << BAT_UCP_ALARM_SHIFT) | + (bq->bus_ovp_alarm << BUS_OVP_ALARM_SHIFT) | + (bq->bus_ocp_alarm << BUS_OCP_ALARM_SHIFT) | + (bq->bat_therm_alarm << BAT_THERM_ALARM_SHIFT) | + (bq->bus_therm_alarm << BUS_THERM_ALARM_SHIFT) | + (bq->die_therm_alarm << DIE_THERM_ALARM_SHIFT)); + break; + + case POWER_SUPPLY_PROP_TI_FAULT_STATUS: + bq2597x_check_fault_status(bq); + + val->intval = ((bq->bat_ovp_fault << BAT_OVP_FAULT_SHIFT) | + (bq->bat_ocp_fault << BAT_OCP_FAULT_SHIFT) | + (bq->bus_ovp_fault << BUS_OVP_FAULT_SHIFT) | + (bq->bus_ocp_fault << BUS_OCP_FAULT_SHIFT) | + (bq->bat_therm_fault << BAT_THERM_FAULT_SHIFT) | + (bq->bus_therm_fault << BUS_THERM_FAULT_SHIFT) | + (bq->die_therm_fault << DIE_THERM_FAULT_SHIFT)); + break; + + case POWER_SUPPLY_PROP_TI_REG_STATUS: + bq2597x_check_reg_status(bq); + val->intval = (bq->vbat_reg << VBAT_REG_STATUS_SHIFT) | + (bq->ibat_reg << IBAT_REG_STATUS_SHIFT); + break; + case POWER_SUPPLY_PROP_TI_SET_BUS_PROTECTION_FOR_QC3: + val->intval = 0; + break; + case POWER_SUPPLY_PROP_MODEL_NAME: + ret = bq2597x_get_work_mode(bq, &bq->mode); + if (ret) { + val->strval = "unknown"; + } else { + if (bq->mode == BQ25970_ROLE_MASTER) + val->strval = "bq2597x-master"; + else if (bq->mode == BQ25970_ROLE_SLAVE) + val->strval = "bq2597x-slave"; + else + val->strval = "bq2597x-standalone"; + } + break; + case POWER_SUPPLY_PROP_TI_BUS_ERROR_STATUS: + val->intval = bq2597x_check_vbus_error_status(bq); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int bq2597x_charger_set_property(struct power_supply *psy, + enum power_supply_property prop, + const union power_supply_propval *val) +{ + struct bq2597x *bq = power_supply_get_drvdata(psy); + + switch (prop) { + case POWER_SUPPLY_PROP_CHARGING_ENABLED: + bq2597x_enable_charge(bq, val->intval); + bq2597x_check_charge_enabled(bq, &bq->charge_enabled); + bq_info("POWER_SUPPLY_PROP_CHARGING_ENABLED: %s\n", + val->intval ? "enable" : "disable"); + break; + case POWER_SUPPLY_PROP_PRESENT: + bq2597x_set_present(bq, !!val->intval); + break; + case POWER_SUPPLY_PROP_TI_SET_BUS_PROTECTION_FOR_QC3: + bq2597x_set_bus_protection(bq, val->intval); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int bq2597x_check_vbus_error_status(struct bq2597x *bq) +{ + int ret; + u8 stat = 0; + + ret = bq2597x_read_byte(bq, BQ2597X_REG_0A, &stat); + if (!ret) { + bq_info("BQ2597X_REG_0A:0x%02x\n", stat); + if (stat & VBUS_ERROR_LOW_MASK) + return VBUS_ERROR_LOW; + else if (stat & VBUS_ERROR_HIGH_MASK) + return VBUS_ERROR_HIGH; + } + + return VBUS_ERROR_NONE; +} + +static int bq2597x_charger_is_writeable(struct power_supply *psy, + enum power_supply_property prop) +{ + int ret; + + switch (prop) { + case POWER_SUPPLY_PROP_CHARGING_ENABLED: + case POWER_SUPPLY_PROP_TI_SET_BUS_PROTECTION_FOR_QC3: + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +static int bq2597x_psy_register(struct bq2597x *bq) +{ + int ret; + + bq->psy_cfg.drv_data = bq; + bq->psy_cfg.of_node = bq->dev->of_node; + + if (bq->mode == BQ25970_ROLE_MASTER) + bq->psy_desc.name = "bq2597x-master"; + else if (bq->mode == BQ25970_ROLE_SLAVE) + bq->psy_desc.name = "bq2597x-slave"; + else + bq->psy_desc.name = "bq2597x-standalone"; + + bq->psy_desc.type = POWER_SUPPLY_TYPE_MAINS; + bq->psy_desc.properties = bq2597x_charger_props; + bq->psy_desc.num_properties = ARRAY_SIZE(bq2597x_charger_props); + bq->psy_desc.get_property = bq2597x_charger_get_property; + bq->psy_desc.set_property = bq2597x_charger_set_property; + bq->psy_desc.property_is_writeable = bq2597x_charger_is_writeable; + + bq->fc2_psy = devm_power_supply_register(bq->dev, &bq->psy_desc, + &bq->psy_cfg); + if (IS_ERR(bq->fc2_psy)) { + bq_err("failed to register fc2_psy:%d\n", ret); + return PTR_ERR(bq->fc2_psy); + } + + bq_info("%s power supply register successfully\n", bq->psy_desc.name); + + return 0; +} + +static void bq2597x_dump_reg(struct bq2597x *bq) +{ + int ret; + u8 val; + u8 addr; + if (bq_debug_flag) { + for (addr = 0x00; addr <= 0x2B; addr++) { + ret = bq2597x_read_byte(bq, addr, &val); + if (!ret) + bq_err("Reg[%02X] = 0x%02X\n", addr, val); + } + } +} +EXPORT_SYMBOL_GPL(bq2597x_dump_reg); + +static void bq2597x_check_alarm_status(struct bq2597x *bq) +{ + int ret; + u8 flag = 0; + u8 stat = 0; + + mutex_lock(&bq->data_lock); + + ret = bq2597x_read_byte(bq, BQ2597X_REG_08, &flag); + if (!ret && (flag & BQ2597X_IBUS_UCP_FALL_FLAG_MASK)) + bq_info("UCP_FLAG =0x%02X\n", + !!(flag & BQ2597X_IBUS_UCP_FALL_FLAG_MASK)); + + ret = bq2597x_read_byte(bq, BQ2597X_REG_2D, &flag); + if (!ret && (flag & BQ2597X_VDROP_OVP_FLAG_MASK)) + bq_info("VDROP_OVP_FLAG =0x%02X\n", + !!(flag & BQ2597X_VDROP_OVP_FLAG_MASK)); + + /*read to clear alarm flag*/ + ret = bq2597x_read_byte(bq, BQ2597X_REG_0E, &flag); + if (!ret && flag) + bq_info("INT_FLAG =0x%02X\n", flag); + + ret = bq2597x_read_byte(bq, BQ2597X_REG_0D, &stat); + if (!ret && stat != bq->prev_alarm) { + bq_info("INT_STAT = 0X%02x\n", stat); + bq->prev_alarm = stat; + bq->bat_ovp_alarm = !!(stat & BAT_OVP_ALARM); + bq->bat_ocp_alarm = !!(stat & BAT_OCP_ALARM); + bq->bus_ovp_alarm = !!(stat & BUS_OVP_ALARM); + bq->bus_ocp_alarm = !!(stat & BUS_OCP_ALARM); + bq->batt_present = !!(stat & VBAT_INSERT); + bq->vbus_present = !!(stat & VBUS_INSERT); + bq->bat_ucp_alarm = !!(stat & BAT_UCP_ALARM); + } + + ret = bq2597x_read_byte(bq, BQ2597X_REG_08, &stat); + if (!ret && (stat & 0x50)) + bq_err("Reg[08]BUS_UCPOVP = 0x%02X\n", stat); + + ret = bq2597x_read_byte(bq, BQ2597X_REG_0A, &stat); + if (!ret && (stat & 0x02)) + bq_err("Reg[0A]CONV_OCP = 0x%02X\n", stat); + + mutex_unlock(&bq->data_lock); +} + +static void bq2597x_check_fault_status(struct bq2597x *bq) +{ + int ret; + u8 flag = 0; + u8 stat = 0; + bool changed = false; + + mutex_lock(&bq->data_lock); + + ret = bq2597x_read_byte(bq, BQ2597X_REG_10, &stat); + if (!ret && stat) + bq_err("FAULT_STAT = 0x%02X\n", stat); + + ret = bq2597x_read_byte(bq, BQ2597X_REG_11, &flag); + if (!ret && flag) + bq_err("FAULT_FLAG = 0x%02X\n", flag); + + if (!ret && flag != bq->prev_fault) { + changed = true; + bq->prev_fault = flag; + bq->bat_ovp_fault = !!(flag & BAT_OVP_FAULT); + bq->bat_ocp_fault = !!(flag & BAT_OCP_FAULT); + bq->bus_ovp_fault = !!(flag & BUS_OVP_FAULT); + bq->bus_ocp_fault = !!(flag & BUS_OCP_FAULT); + bq->bat_therm_fault = !!(flag & TS_BAT_FAULT); + bq->bus_therm_fault = !!(flag & TS_BUS_FAULT); + + bq->bat_therm_alarm = !!(flag & TBUS_TBAT_ALARM); + bq->bus_therm_alarm = !!(flag & TBUS_TBAT_ALARM); + } + + mutex_unlock(&bq->data_lock); +} + +static void bq2597x_charger_info(struct bq2597x *bq) +{ + int vbat, vbus, ibus; + + bq2597x_get_adc_data(bq, ADC_VBAT, &vbat); + bq2597x_get_adc_data(bq, ADC_VBUS, &vbus); + bq2597x_get_adc_data(bq, ADC_IBUS, &ibus); + bq_info("charger info: vbat(%d), vbus(%d), ibus(%d)\n", vbat, vbus, + ibus); +} + +/* + * interrupt does nothing, just info event chagne, other module could get info + * through power supply interface + */ +static irqreturn_t bq2597x_charger_interrupt(int irq, void *dev_id) +{ + struct bq2597x *bq = dev_id; + + bq_info("INT OCCURED\n"); + mutex_lock(&bq->irq_complete); + bq->irq_waiting = true; + if (!bq->resume_completed) { + dev_dbg(bq->dev, "IRQ triggered before device-resume\n"); + if (!bq->irq_disabled) { + disable_irq_nosync(irq); + bq->irq_disabled = true; + } + mutex_unlock(&bq->irq_complete); + return IRQ_HANDLED; + } + bq->irq_waiting = false; + + /* TODO */ + bq2597x_check_alarm_status(bq); + bq2597x_check_fault_status(bq); + + bq2597x_charger_info(bq); + bq2597x_dump_reg(bq); + mutex_unlock(&bq->irq_complete); + power_supply_changed(bq->fc2_psy); + + return IRQ_HANDLED; +} + +static void determine_initial_status(struct bq2597x *bq) +{ + if (bq->client->irq) + bq2597x_charger_interrupt(bq->client->irq, bq); +} + +static int show_registers(struct seq_file *m, void *data) +{ + struct bq2597x *bq = m->private; + u8 addr; + int ret; + u8 val; + + for (addr = 0x0; addr <= 0x2B; addr++) { + ret = bq2597x_read_byte(bq, addr, &val); + if (!ret) + seq_printf(m, "Reg[%02X] = 0x%02X\n", addr, val); + } + return 0; +} + +static int reg_debugfs_open(struct inode *inode, struct file *file) +{ + struct bq2597x *bq = inode->i_private; + + return single_open(file, show_registers, bq); +} + +static const struct file_operations reg_debugfs_ops = { + .owner = THIS_MODULE, + .open = reg_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void create_debugfs_entry(struct bq2597x *bq) +{ + if (bq->mode == BQ25970_ROLE_MASTER) + bq->debug_root = debugfs_create_dir("bq2597x-master", NULL); + else if (bq->mode == BQ25970_ROLE_SLAVE) + bq->debug_root = debugfs_create_dir("bq2597x-slave", NULL); + else + bq->debug_root = debugfs_create_dir("bq2597x-standalone", NULL); + + if (!bq->debug_root) + bq_err("Failed to create debug dir\n"); + + if (bq->debug_root) { + debugfs_create_file("registers", S_IFREG | S_IRUGO, + bq->debug_root, bq, ®_debugfs_ops); + + debugfs_create_x32("skip_reads", S_IFREG | S_IWUSR | S_IRUGO, + bq->debug_root, &(bq->skip_reads)); + debugfs_create_x32("skip_writes", S_IFREG | S_IWUSR | S_IRUGO, + bq->debug_root, &(bq->skip_writes)); + } +} + +static struct of_device_id bq2597x_charger_match_table[] = { + { + .compatible = "ti,bq2597x-standalone", + .data = &bq2597x_mode_data[BQ25970_STDALONE], + }, + { + .compatible = "ti,bq2597x-master", + .data = &bq2597x_mode_data[BQ25970_MASTER], + }, + + { + .compatible = "ti,bq2597x-slave", + .data = &bq2597x_mode_data[BQ25970_SLAVE], + }, + {}, +}; +//MODULE_DEVICE_TABLE(of, bq2597x_charger_match_table); + +static int bq2597x_charger_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct bq2597x *bq; + const struct of_device_id *match; + struct device_node *node = client->dev.of_node; + int ret; + + bq = devm_kzalloc(&client->dev, sizeof(struct bq2597x), GFP_KERNEL); + if (!bq) + return -ENOMEM; + + bq->dev = &client->dev; + + bq->client = client; + i2c_set_clientdata(client, bq); + + mutex_init(&bq->i2c_rw_lock); + mutex_init(&bq->data_lock); + mutex_init(&bq->charging_disable_lock); + mutex_init(&bq->irq_complete); + + bq->resume_completed = true; + bq->irq_waiting = false; + + ret = bq2597x_detect_device(bq); + if (ret) { + bq_err("No bq2597x device found!\n"); + return -ENODEV; + } + + match = of_match_node(bq2597x_charger_match_table, node); + if (match == NULL) { + bq_err("device tree match not found!\n"); + return -ENODEV; + } + + bq2597x_get_work_mode(bq, &bq->mode); + + if (bq->mode != *(int *)match->data) { + bq_err("device operation mode mismatch with dts configuration\n"); + return -EINVAL; + } + + ret = bq2597x_parse_dt(bq, &client->dev); + if (ret) + return -EIO; + + ret = bq2597x_init_device(bq); + if (ret) { + bq_err("Failed to init device\n"); + return ret; + } + + ret = bq2597x_psy_register(bq); + if (ret) + return ret; + + if (client->irq) { + ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, + bq2597x_charger_interrupt, + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + "bq2597x charger irq", bq); + if (ret < 0) { + bq_err("request irq for irq=%d failed, ret =%d\n", + client->irq, ret); + goto err_1; + } + enable_irq_wake(client->irq); + } + + INIT_DELAYED_WORK(&bq->monitor_work, bq2597x_monitor_work); + device_init_wakeup(bq->dev, 1); + create_debugfs_entry(bq); + + ret = sysfs_create_group(&bq->dev->kobj, &bq2597x_attr_group); + if (ret) { + bq_err("failed to register sysfs. err: %d\n", ret); + goto err_1; + } + + determine_initial_status(bq); + /* schedule_delayed_work(&bq->monitor_work, 60 * HZ); */ + bq_info("bq2597x probe successfully, Part Num:%d\n!", bq->part_no); + + return 0; + +err_1: + power_supply_unregister(bq->fc2_psy); + return ret; +} + +static inline bool is_device_suspended(struct bq2597x *bq) +{ + return !bq->resume_completed; +} + +static int bq2597x_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq2597x *bq = i2c_get_clientdata(client); + + mutex_lock(&bq->irq_complete); + bq->resume_completed = false; + mutex_unlock(&bq->irq_complete); + bq2597x_enable_adc(bq, false); + cancel_delayed_work_sync(&bq->monitor_work); + bq_err("Suspend successfully!"); + + return 0; +} + +static int bq2597x_suspend_noirq(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq2597x *bq = i2c_get_clientdata(client); + + if (bq->irq_waiting) { + pr_err_ratelimited( + "Aborting suspend, an interrupt was detected while suspending\n"); + return -EBUSY; + } + return 0; +} + +static int bq2597x_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq2597x *bq = i2c_get_clientdata(client); + + mutex_lock(&bq->irq_complete); + bq->resume_completed = true; + if (bq->irq_waiting) { + bq->irq_disabled = false; + enable_irq(client->irq); + mutex_unlock(&bq->irq_complete); + bq2597x_charger_interrupt(client->irq, bq); + } else { + mutex_unlock(&bq->irq_complete); + } + + bq2597x_enable_adc(bq, true); + power_supply_changed(bq->fc2_psy); + bq_err("Resume successfully!"); + + return 0; +} +static int bq2597x_charger_remove(struct i2c_client *client) +{ + struct bq2597x *bq = i2c_get_clientdata(client); + + bq2597x_enable_adc(bq, false); + + power_supply_unregister(bq->fc2_psy); + + mutex_destroy(&bq->charging_disable_lock); + mutex_destroy(&bq->data_lock); + mutex_destroy(&bq->i2c_rw_lock); + mutex_destroy(&bq->irq_complete); + + debugfs_remove_recursive(bq->debug_root); + + sysfs_remove_group(&bq->dev->kobj, &bq2597x_attr_group); + + return 0; +} + +static void bq2597x_charger_shutdown(struct i2c_client *client) +{ + struct bq2597x *bq = i2c_get_clientdata(client); + + bq2597x_enable_adc(bq, false); +} + +static const struct dev_pm_ops bq2597x_pm_ops = { + .resume = bq2597x_resume, + .suspend_noirq = bq2597x_suspend_noirq, + .suspend = bq2597x_suspend, +}; + +static const struct i2c_device_id bq2597x_charger_id[] = { + { "bq2597x-standalone", BQ25970_ROLE_STDALONE }, + { "bq2597x-master", BQ25970_ROLE_MASTER }, + { "bq2597x-slave", BQ25970_ROLE_SLAVE }, + {}, +}; + +static struct i2c_driver bq2597x_charger_driver = { + .driver = { + .name = "bq2597x-charger", + .owner = THIS_MODULE, + .of_match_table = bq2597x_charger_match_table, + .pm = &bq2597x_pm_ops, + }, + .id_table = bq2597x_charger_id, + + .probe = bq2597x_charger_probe, + .remove = bq2597x_charger_remove, + .shutdown = bq2597x_charger_shutdown, +}; + +module_i2c_driver(bq2597x_charger_driver); + +MODULE_DESCRIPTION("TI BQ2597x Charger Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Texas Instruments"); diff --git a/drivers/power/supply/ti/bq27z561_fg.c b/drivers/power/supply/ti/bq27z561_fg.c new file mode 100644 index 000000000000..f713af276273 --- /dev/null +++ b/drivers/power/supply/ti/bq27z561_fg.c @@ -0,0 +1,2134 @@ +/* + * bq27z561 fuel gauge driver + * + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#define pr_fmt(fmt) "[bq27z561] %s: " fmt, __func__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum print_reason { + PR_INTERRUPT = BIT(0), + PR_REGISTER = BIT(1), + PR_OEM = BIT(2), + PR_DEBUG = BIT(3), +}; + +static int debug_mask = PR_OEM; +module_param_named(debug_mask, debug_mask, int, 0600); + +#define INVALID_REG_ADDR 0xFF + +#define FG_FLAGS_FD BIT(4) +#define FG_FLAGS_FC BIT(5) +#define FG_FLAGS_DSG BIT(6) +#define FG_FLAGS_RCA BIT(9) +#define FG_FLAGS_FASTCHAGE BIT(5) + +#define BATTERY_DIGEST_LEN 32 + +#define DEFUALT_FULL_DESIGN 100000 + +#define BQ_REPORT_FULL_SOC 9800 +#define BQ_CHARGE_FULL_SOC 9750 +#define BQ_RECHARGE_SOC 9900 + +#define PD_CHG_UPDATE_DELAY_US 20 /*20 sec*/ + +enum bq_fg_reg_idx { + BQ_FG_REG_CTRL = 0, + BQ_FG_REG_TEMP, /* Battery Temperature */ + BQ_FG_REG_VOLT, /* Battery Voltage */ + BQ_FG_REG_CN, /* Current Now */ + BQ_FG_REG_AI, /* Average Current */ + BQ_FG_REG_BATT_STATUS, /* BatteryStatus */ + BQ_FG_REG_TTE, /* Time to Empty */ + BQ_FG_REG_TTF, /* Time to Full */ + BQ_FG_REG_FCC, /* Full Charge Capacity */ + BQ_FG_REG_RM, /* Remaining Capacity */ + BQ_FG_REG_CC, /* Cycle Count */ + BQ_FG_REG_SOC, /* Relative State of Charge */ + BQ_FG_REG_SOH, /* State of Health */ + BQ_FG_REG_CHG_VOL, /* Charging Voltage*/ + BQ_FG_REG_CHG_CUR, /* Charging Current*/ + BQ_FG_REG_DC, /* Design Capacity */ + BQ_FG_REG_ALT_MAC, /* AltManufactureAccess*/ + BQ_FG_REG_MAC_DATA, /* MACData*/ + BQ_FG_REG_MAC_CHKSUM, /* MACChecksum */ + BQ_FG_REG_MAC_DATA_LEN, /* MACDataLen */ + NUM_REGS, +}; + +static u8 bq27z561_regs[NUM_REGS] = { + 0x00, /* CONTROL */ + 0x06, /* TEMP */ + 0x08, /* VOLT */ + 0x0C, /* CURRENT NOW */ + 0x14, /* AVG CURRENT */ + 0x0A, /* FLAGS */ + 0x16, /* Time to empty */ + 0x18, /* Time to full */ + 0x12, /* Full charge capacity */ + 0x10, /* Remaining Capacity */ + 0x2A, /* CycleCount */ + 0x2C, /* State of Charge */ + 0x2E, /* State of Health */ + 0x30, /* Charging Voltage*/ + 0x32, /* Charging Current*/ + 0x3C, /* Design Capacity */ + 0x3E, /* AltManufacturerAccess*/ + 0x40, /* MACData*/ + 0x60, /* MACChecksum */ + 0x61, /* MACDataLen */ +}; + +enum bq_fg_mac_cmd { + FG_MAC_CMD_CTRL_STATUS = 0x0000, + FG_MAC_CMD_DEV_TYPE = 0x0001, + FG_MAC_CMD_FW_VER = 0x0002, + FG_MAC_CMD_HW_VER = 0x0003, + FG_MAC_CMD_IF_SIG = 0x0004, + FG_MAC_CMD_CHEM_ID = 0x0006, + FG_MAC_CMD_GAUGING = 0x0021, + FG_MAC_CMD_SEAL = 0x0030, + FG_MAC_CMD_FASTCHARGE_EN = 0x003E, + FG_MAC_CMD_FASTCHARGE_DIS = 0x003F, + FG_MAC_CMD_DEV_RESET = 0x0041, + FG_MAC_CMD_MANU_NAME = 0x004C, + FG_MAC_CMD_CHARGING_STATUS = 0x0055, + FG_MAC_CMD_ITSTATUS1 = 0x0073, + FG_MAC_CMD_QMAX = 0x0075, + FG_MAC_CMD_RA_TABLE = 0x40C0, +}; + +enum { + SEAL_STATE_RSVED, + SEAL_STATE_UNSEALED, + SEAL_STATE_SEALED, + SEAL_STATE_FA, +}; + +enum bq_fg_device { + BQ27Z561, +}; + +static const unsigned char *device2str[] = { + "bq27z561", +}; + +struct cold_thermal { + int index; + int temp_l; + int temp_h; + int curr_th; +}; + +struct bq_fg_chip { + struct device *dev; + struct i2c_client *client; + struct regmap *regmap; + + struct mutex i2c_rw_lock; + struct mutex data_lock; + + int fw_ver; + int df_ver; + + u8 chip; + u8 regs[NUM_REGS]; + + /* status tracking */ + + bool batt_fc; + bool batt_fd; /* full depleted */ + + bool batt_dsg; + bool batt_rca; /* remaining capacity alarm */ + + int seal_state; /* 0 - Full Access, 1 - Unsealed, 2 - Sealed */ + int batt_tte; + int batt_soc; + int batt_fcc; /* Full charge capacity */ + int batt_rm; /* Remaining capacity */ + int batt_dc; /* Design Capacity */ + int batt_volt; + int batt_temp; + int batt_curr; + int batt_resistance; + int batt_cyclecnt; /* cycle count */ + int batt_st; + + /* debug */ + int skip_reads; + int skip_writes; + + int fake_soc; + int fake_temp; + int fake_volt; + + struct delayed_work monitor_work; + struct power_supply *fg_psy; + struct power_supply *usb_psy; + struct power_supply *batt_psy; + struct power_supply_desc fg_psy_d; + struct timeval suspend_time; + + u8 digest[BATTERY_DIGEST_LEN]; + bool verify_digest_success; + int constant_charge_current_max; + + bool charge_done; + bool charge_full; + int health; + int batt_recharge_vol; + + /* workaround for debug or other purpose */ + bool ignore_digest_for_debug; + bool old_hw; + + int *dec_rate_seq; + int dec_rate_len; + + struct cold_thermal *cold_thermal_seq; + int cold_thermal_len; + bool update_now; + bool fast_mode; +}; + +#define bq_dbg(reason, fmt, ...) \ + do { \ + if (debug_mask & (reason)) \ + pr_info(fmt, ##__VA_ARGS__); \ + else \ + pr_debug(fmt, ##__VA_ARGS__); \ + } while (0) + +static int bq_battery_soc_smooth_tracking(struct bq_fg_chip *chip, int raw_soc, + int soc, int temp, int curr); +static int fg_get_raw_soc(struct bq_fg_chip *bq); +static int fg_read_current(struct bq_fg_chip *bq, int *curr); +static int fg_read_temperature(struct bq_fg_chip *bq); +static int calc_delta_time(struct timeval *time_stamp, int *delta_time); +/* +static int __fg_read_byte(struct i2c_client *client, u8 reg, u8 *val) +{ + s32 ret; + + ret = i2c_smbus_read_byte_data(client, reg); + if (ret < 0) { + bq_dbg(PR_OEM, "i2c read byte fail: can't read from reg 0x%02X\n", reg); + return ret; + } + + *val = (u8)ret; + + return 0; +} +*/ + +static int __fg_write_byte(struct i2c_client *client, u8 reg, u8 val) +{ + s32 ret; + + ret = i2c_smbus_write_byte_data(client, reg, val); + if (ret < 0) { + bq_dbg(PR_REGISTER, + "i2c write byte fail: can't write 0x%02X to reg 0x%02X\n", + val, reg); + return ret; + } + + return 0; +} + +static int __fg_read_word(struct i2c_client *client, u8 reg, u16 *val) +{ + s32 ret; + + ret = i2c_smbus_read_word_data(client, reg); + if (ret < 0) { + bq_dbg(PR_REGISTER, + "i2c read word fail: can't read from reg 0x%02X\n", reg); + return ret; + } + + *val = (u16)ret; + + return 0; +} + +static int __fg_read_block(struct i2c_client *client, u8 reg, u8 *buf, u8 len) +{ + int ret; + int i; + + for (i = 0; i < len; i++) { + ret = i2c_smbus_read_byte_data(client, reg + i); + if (ret < 0) { + bq_dbg(PR_REGISTER, "i2c read reg 0x%02X faild\n", + reg + i); + return ret; + } + buf[i] = ret; + } + + return ret; +} + +static int __fg_write_block(struct i2c_client *client, u8 reg, u8 *buf, u8 len) +{ + int ret; + int i = 0; + + for (i = 0; i < len; i++) { + ret = i2c_smbus_write_byte_data(client, reg + i, buf[i]); + if (ret < 0) { + bq_dbg(PR_REGISTER, "i2c read reg 0x%02X faild\n", + reg + i); + return ret; + } + } + + return ret; +} + +/* +static int fg_read_byte(struct bq_fg_chip *bq, u8 reg, u8 *val) +{ + int ret; + + if (bq->skip_reads) { + *val = 0; + return 0; + } + + mutex_lock(&bq->i2c_rw_lock); + ret = __fg_read_byte(bq->client, reg, val); + mutex_unlock(&bq->i2c_rw_lock); + + return ret; +} +*/ + +static int fg_write_byte(struct bq_fg_chip *bq, u8 reg, u8 val) +{ + int ret; + + if (bq->skip_writes) + return 0; + + mutex_lock(&bq->i2c_rw_lock); + ret = __fg_write_byte(bq->client, reg, val); + mutex_unlock(&bq->i2c_rw_lock); + + return ret; +} + +static int fg_read_word(struct bq_fg_chip *bq, u8 reg, u16 *val) +{ + int ret; + + if (bq->skip_reads) { + *val = 0; + return 0; + } + + mutex_lock(&bq->i2c_rw_lock); + ret = __fg_read_word(bq->client, reg, val); + mutex_unlock(&bq->i2c_rw_lock); + + return ret; +} + +static int fg_read_block(struct bq_fg_chip *bq, u8 reg, u8 *buf, u8 len) +{ + int ret; + + if (bq->skip_reads) + return 0; + mutex_lock(&bq->i2c_rw_lock); + ret = __fg_read_block(bq->client, reg, buf, len); + mutex_unlock(&bq->i2c_rw_lock); + + return ret; +} + +static int fg_write_block(struct bq_fg_chip *bq, u8 reg, u8 *data, u8 len) +{ + int ret; + + if (bq->skip_writes) + return 0; + + mutex_lock(&bq->i2c_rw_lock); + ret = __fg_write_block(bq->client, reg, data, len); + mutex_unlock(&bq->i2c_rw_lock); + + return ret; +} + +static u8 checksum(u8 *data, u8 len) +{ + u8 i; + u16 sum = 0; + + for (i = 0; i < len; i++) { + sum += data[i]; + } + + sum &= 0xFF; + + return 0xFF - sum; +} + +static void fg_print_buf(const char *msg, u8 *buf, u8 len) +{ + int i; + int idx = 0; + int num; + u8 strbuf[128]; + + bq_dbg(PR_REGISTER, "%s buf: ", msg); + for (i = 0; i < len; i++) { + num = sprintf(&strbuf[idx], "%02X ", buf[i]); + idx += num; + } + bq_dbg(PR_REGISTER, "%s\n", strbuf); +} + +#if 0 +#define TIMEOUT_INIT_COMPLETED 100 +static int fg_check_init_completed(struct bq_fg_chip *bq) +{ + int ret; + int i = 0; + u16 status; + + while (i++ < TIMEOUT_INIT_COMPLETED) { + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_BATT_STATUS], &status); + if (ret >= 0 && (status & 0x0080)) + return 0; + msleep(100); + } + bq_dbg(PR_OEM, "wait for FG INITCOMP timeout\n"); + return ret; +} +#endif + +#if 0 +static int fg_get_seal_state(struct bq_fg_chip *bq) +{ + int ret; + u16 status; + + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_CTRL], &status); + if (ret < 0) { + bq_dbg(PR_OEM, "Failed to read control status, ret = %d\n", ret); + return ret; + } + status &= 0x6000; + status >>= 13; + + if (status == 1) + bq->seal_state = SEAL_STATE_FA; + else if (status == 2) + bq->seal_state = SEAL_STATE_UNSEALED; + else if (status == 3) + bq->seal_state = SEAL_STATE_SEALED; + + return 0; +} + +static int fg_unseal_send_key(struct bq_fg_chip *bq, int key) +{ + int ret; + + ret = fg_write_word(bq, bq->regs[BQ_FG_REG_ALT_MAC], key & 0xFFFF); + + if (ret < 0) { + bq_dbg(PR_OEM, "unable to write unseal key step 1, ret = %d\n", ret); + return ret; + } + + msleep(5); + + ret = fg_write_word(bq, bq->regs[BQ_FG_REG_ALT_MAC], (key >> 16) & 0xFFFF); + if (ret < 0) { + bq_dbg(PR_OEM, "unable to write unseal key step 2, ret = %d\n", ret); + return ret; + } + + msleep(100); + + return 0; +} + +#define FG_DEFAULT_UNSEAL_KEY 0x80008000 +static int fg_unseal(struct bq_fg_chip *bq) +{ + int ret; + int retry = 0; + + ret = fg_unseal_send_key(bq, FG_DEFAULT_UNSEAL_KEY); + if (!ret) { + while (retry++ < 100) { + ret = fg_get_seal_state(bq); + if (bq->seal_state == SEAL_STATE_UNSEALED || + bq->seal_state == SEAL_STATE_FA) { + bq_dbg(PR_OEM, "FG is unsealed"); + return 0; + } + } + } + + return -EPERM; +} + +#define FG_DEFAULT_UNSEAL_FA_KEY 0x36724614 +static int fg_unseal_full_access(struct bq_fg_chip *bq) +{ + int ret; + int retry = 0; + + ret = fg_unseal_send_key(bq, FG_DEFAULT_UNSEAL_FA_KEY); + if (!ret) { + while (retry++ < 100) { + fg_get_seal_state(bq); + if (bq->seal_state == SEAL_STATE_FA) { + bq_dbg(PR_OEM, "FG is in full access."); + return 0; + } + msleep(200); + } + } + + return -EPERM; +} + + +static int fg_seal(struct bq_fg_chip *bq) +{ + int ret; + int retry = 0; + + ret = fg_write_word(bq, bq->regs[BQ_FG_REG_ALT_MAC], FG_MAC_CMD_SEAL); + + if (ret < 0) { + bq_dbg(PR_OEM, "Failed to send seal command\n"); + return ret; + } + + while (retry++ < 100) { + fg_get_seal_state(bq); + if (bq->seal_state == SEAL_STATE_SEALED) { + bq_dbg(PR_OEM, "FG is sealed successfully"); + return 0; + } + msleep(200); + } + + return -EPERM; +} +#endif + +static int fg_mac_read_block(struct bq_fg_chip *bq, u16 cmd, u8 *buf, u8 len) +{ + int ret; + u8 cksum_calc, cksum; + u8 t_buf[40]; + u8 t_len; + int i; + + t_buf[0] = (u8)cmd; + t_buf[1] = (u8)(cmd >> 8); + ret = fg_write_block(bq, bq->regs[BQ_FG_REG_ALT_MAC], t_buf, 2); + if (ret < 0) + return ret; + + msleep(4); + + ret = fg_read_block(bq, bq->regs[BQ_FG_REG_ALT_MAC], t_buf, 36); + if (ret < 0) + return ret; + + fg_print_buf("mac_read_block", t_buf, 36); + + cksum = t_buf[34]; + t_len = t_buf[35]; + + cksum_calc = checksum(t_buf, t_len - 2); + if (cksum_calc != cksum) + return 1; + + for (i = 0; i < len; i++) + buf[i] = t_buf[i + 2]; + + return 0; +} + +static int fg_sha256_auth(struct bq_fg_chip *bq, u8 *rand_num, int length) +{ + int ret; + u8 cksum_calc; + u8 t_buf[2]; + + /* + 1. The host writes 0x00 to 0x3E. + 2. The host writes 0x00 to 0x3F + */ + t_buf[0] = 0x00; + t_buf[1] = 0x00; + ret = fg_write_block(bq, bq->regs[BQ_FG_REG_ALT_MAC], t_buf, 2); + if (ret < 0) + return ret; + /* + 3. Write the random challenge should be written in a 32-byte block to address 0x40-0x5F + */ + msleep(2); + + ret = fg_write_block(bq, bq->regs[BQ_FG_REG_MAC_DATA], rand_num, + length); + if (ret < 0) + return ret; + + /*4. Write the checksum (2’s complement sum of (1), (2), and (3)) to address 0x60.*/ + cksum_calc = checksum(rand_num, length); + ret = fg_write_byte(bq, bq->regs[BQ_FG_REG_MAC_CHKSUM], cksum_calc); + if (ret < 0) + return ret; + + /*5. Write the length 0x24 to address 0x61.*/ + ret = fg_write_byte(bq, bq->regs[BQ_FG_REG_MAC_DATA_LEN], 0x24); + if (ret < 0) + return ret; + + msleep(300); + + ret = fg_read_block(bq, bq->regs[BQ_FG_REG_MAC_DATA], bq->digest, + length); + if (ret < 0) + return ret; + + return 0; +} + +static int fg_mac_write_block(struct bq_fg_chip *bq, u16 cmd, u8 *data, u8 len) +{ + int ret; + u8 cksum; + u8 t_buf[40]; + int i; + + if (len > 32) + return -EPERM; + + t_buf[0] = (u8)cmd; + t_buf[1] = (u8)(cmd >> 8); + for (i = 0; i < len; i++) + t_buf[i + 2] = data[i]; + + cksum = checksum(data, len + 2); + /*write command/addr, data*/ + ret = fg_write_block(bq, bq->regs[BQ_FG_REG_ALT_MAC], t_buf, len + 2); + if (ret < 0) + return ret; + t_buf[0] = cksum; + t_buf[1] = len + 4; /*buf length, cmd, CRC and len byte itself*/ + /*write checksum and length*/ + ret = fg_write_block(bq, bq->regs[BQ_FG_REG_MAC_CHKSUM], t_buf, 2); + + return ret; +} +/* +static int fg_get_fastcharge_mode(struct bq_fg_chip *bq) +{ + u8 data[3]; + int ret; + + ret = fg_mac_read_block(bq, FG_MAC_CMD_CHARGING_STATUS, data, 3); + if (ret < 0) { + bq_dbg(PR_OEM, "could not write fastcharge = %d\n", ret); + return ret; + } + + return (data[2] & FG_FLAGS_FASTCHAGE) >> 5; +} +*/ + +static int fg_set_fastcharge_mode(struct bq_fg_chip *bq, bool enable) +{ + u8 data[2]; + int ret; + + data[0] = enable; + + bq_dbg(PR_OEM, "set fastcharge mode: enable: %d\n", enable); + if (enable) { + ret = fg_mac_write_block(bq, FG_MAC_CMD_FASTCHARGE_EN, data, 2); + if (ret < 0) { + bq_dbg(PR_OEM, "could not write fastcharge = %d\n", + ret); + return ret; + } + } else { + ret = fg_mac_write_block(bq, FG_MAC_CMD_FASTCHARGE_DIS, data, + 2); + if (ret < 0) { + bq_dbg(PR_OEM, "could not write fastcharge = %d\n", + ret); + return ret; + } + } + bq->fast_mode = enable; + + return ret; +} + +static int fg_read_status(struct bq_fg_chip *bq) +{ + int ret; + u16 flags; + + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_BATT_STATUS], &flags); + if (ret < 0) + return ret; + + bq->batt_fc = !!(flags & FG_FLAGS_FC); + bq->batt_fd = !!(flags & FG_FLAGS_FD); + bq->batt_rca = !!(flags & FG_FLAGS_RCA); + bq->batt_dsg = !!(flags & FG_FLAGS_DSG); + + return 0; +} + +#define TERMINATION 0 +#define TERMINATION_BYTE 6 +#define TERMINATION_BASE 30 +#define TERMINATION_STEP 5 + +#define RECHARGE_VOL 1 +#define RECHARGE_VOL_BYTE 7 +#define RECHARGE_VOL_BASE 4200 +#define RECHARGE_VOL_STEP 5 + +#define FFC_TERMINATION 2 +#define FFC_TERMINATION_BYTE 8 +#define FFC_TERMINATION_BASE 400 +#define FFC_TERMINATION_STEP 20 + +#define MANU_DATA_LEN 3 + +struct manu_data { + int byte; + int base; + int step; + int data; +}; + +struct manu_data manu_info[MANU_DATA_LEN] = { + { TERMINATION_BYTE, TERMINATION_BASE, TERMINATION_STEP }, + { RECHARGE_VOL_BYTE, RECHARGE_VOL_BASE, RECHARGE_VOL_STEP }, + { FFC_TERMINATION_BYTE, FFC_TERMINATION_BASE, FFC_TERMINATION_STEP }, +}; + +static int fg_get_manu_info(unsigned char val, int base, int step) +{ + int index = 0; + int data = 0; + + bq_dbg(PR_OEM, "val:%d, '0':%d, 'A':%d, 'a':%d\n", val, '0', 'A', 'a'); + if (val > '0' && val < '9') + index = val - '0'; + if (val > 'A' && val < 'Z') + index = val - 'A' + 10; + if (val > 'a' && val < 'z') + index = val - 'a' + 36; + + data = base + index * step; + + return data; +} + +static int fg_get_manufacture_data(struct bq_fg_chip *bq) +{ + u8 t_buf[40]; + int ret; + int i; + int byte, base, step; + + ret = fg_mac_read_block(bq, FG_MAC_CMD_MANU_NAME, t_buf, 32); + if (ret < 0) { + bq_dbg(PR_OEM, "failed to get MANE NAME\n"); + if (bq->ignore_digest_for_debug) + bq->old_hw = true; + } + + if (strncmp(t_buf, "MI", 2) != 0) { + bq_dbg(PR_OEM, "maybe not mi battery data\n"); + return 0; + } + + for (i = 0; i < MANU_DATA_LEN; i++) { + byte = manu_info[i].byte; + base = manu_info[i].base; + step = manu_info[i].step; + manu_info[i].data = fg_get_manu_info(t_buf[byte], base, step); + } + + return 0; +} + +static int fg_read_rsoc(struct bq_fg_chip *bq) +{ + static int last_soc; + int soc, ret; + + if (bq->fake_soc > 0) + return bq->fake_soc; + + ret = regmap_read(bq->regmap, bq->regs[BQ_FG_REG_SOC], &soc); + if (ret < 0) { + bq_dbg(PR_OEM, "could not read RSOC, ret = %d\n", ret); + if (!last_soc) + last_soc = 50; + return last_soc; + } + + last_soc = soc; + + return soc; +} + +#define FG_REPORT_FULL_SOC 9600 +#define FG_OPTIMIZ_FULL_TIME 40 + +static int fg_read_system_soc(struct bq_fg_chip *bq) +{ + int soc, curr, temp, raw_soc; + + soc = fg_read_rsoc(bq); + raw_soc = fg_get_raw_soc(bq); + + fg_read_current(bq, &curr); + temp = fg_read_temperature(bq); + + soc = bq_battery_soc_smooth_tracking(bq, raw_soc, soc, temp, curr); + + return soc; +} + +static int fg_read_temperature(struct bq_fg_chip *bq) +{ + int ret; + u16 temp = 0; + static int last_temp; + + if (bq->fake_temp > 0) + return bq->fake_temp; + + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_TEMP], &temp); + if (ret < 0) { + bq_dbg(PR_OEM, "could not read temperature, ret = %d\n", ret); + if (!last_temp) + last_temp = 250; + return last_temp; + } + last_temp = temp - 2730; + + return temp - 2730; +} + +static int fg_read_volt(struct bq_fg_chip *bq) +{ + int ret; + u16 volt = 0; + + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_VOLT], &volt); + if (ret < 0) { + bq_dbg(PR_OEM, "could not read voltage, ret = %d\n", ret); + return 3700; + } + + return volt; +} + +static int fg_read_avg_current(struct bq_fg_chip *bq, int *curr) +{ + int ret; + s16 avg_curr = 0; + + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_AI], (u16 *)&avg_curr); + if (ret < 0) { + bq_dbg(PR_OEM, "could not read current, ret = %d\n", ret); + return ret; + } + *curr = -1 * avg_curr; + + return ret; +} + +static int fg_read_current(struct bq_fg_chip *bq, int *curr) +{ + int ret; + s16 avg_curr = 0; + + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_CN], (u16 *)&avg_curr); + if (ret < 0) { + bq_dbg(PR_OEM, "could not read current, ret = %d\n", ret); + return ret; + } + *curr = -1 * avg_curr; + + return ret; +} + +static int fg_read_fcc(struct bq_fg_chip *bq) +{ + int ret; + u16 fcc; + + if (bq->regs[BQ_FG_REG_FCC] == INVALID_REG_ADDR) { + bq_dbg(PR_OEM, "FCC command not supported!\n"); + return 0; + } + + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_FCC], &fcc); + + if (ret < 0) + bq_dbg(PR_OEM, "could not read FCC, ret=%d\n", ret); + + return fcc; +} + +static int fg_read_rm(struct bq_fg_chip *bq) +{ + int ret; + u16 rm; + + if (bq->regs[BQ_FG_REG_RM] == INVALID_REG_ADDR) { + bq_dbg(PR_OEM, "RemainingCapacity command not supported!\n"); + return 0; + } + + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_RM], &rm); + + if (ret < 0) { + bq_dbg(PR_OEM, "could not read DC, ret=%d\n", ret); + return ret; + } + + return rm; +} + +static int fg_read_soh(struct bq_fg_chip *bq) +{ + int ret; + u16 soh; + + if (bq->regs[BQ_FG_REG_SOH] == INVALID_REG_ADDR) { + bq_dbg(PR_OEM, "SOH command not supported!\n"); + return 0; + } + + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_SOH], &soh); + if (ret < 0) { + bq_dbg(PR_OEM, "could not read DC, ret=%d\n", ret); + return ret; + } + + return soh; +} + +static int fg_get_charge_counter(struct bq_fg_chip *bq, int *value) +{ + if (!bq) + return 0; + + *value = fg_read_rm(bq) * 1000; + + return 0; +} + +static int fg_read_cyclecount(struct bq_fg_chip *bq) +{ + int ret; + u16 cc; + + if (bq->regs[BQ_FG_REG_CC] == INVALID_REG_ADDR) { + bq_dbg(PR_OEM, "Cycle Count not supported!\n"); + return -EPERM; + } + + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_CC], &cc); + + if (ret < 0) { + bq_dbg(PR_OEM, "could not read Cycle Count, ret=%d\n", ret); + return ret; + } + + return cc; +} + +static int fg_read_tte(struct bq_fg_chip *bq) +{ + int ret; + u16 tte; + + if (bq->regs[BQ_FG_REG_TTE] == INVALID_REG_ADDR) { + bq_dbg(PR_OEM, "Time To Empty not supported!\n"); + return -EPERM; + } + + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_TTE], &tte); + + if (ret < 0) { + bq_dbg(PR_OEM, "could not read Time To Empty, ret=%d\n", ret); + return ret; + } + + if (ret == 0xFFFF) + return -ENODATA; + + return tte; +} + +static int fg_read_charging_current(struct bq_fg_chip *bq) +{ + int ret; + u16 cc; + + if (bq->regs[BQ_FG_REG_CHG_CUR] == INVALID_REG_ADDR) { + bq_dbg(PR_OEM, " not supported!\n"); + return -EPERM; + } + + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_CHG_CUR], &cc); + + if (ret < 0) { + bq_dbg(PR_OEM, "could not read Time To Empty, ret=%d\n", ret); + return ret; + } + + if (ret == 0xFFFF) + return -ENODATA; + + return cc; +} + +static int fg_read_charging_voltage(struct bq_fg_chip *bq) +{ + int ret; + u16 cv; + + if (bq->regs[BQ_FG_REG_CHG_VOL] == INVALID_REG_ADDR) { + bq_dbg(PR_OEM, " not supported!\n"); + return -EPERM; + } + + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_CHG_VOL], &cv); + + if (ret < 0) { + bq_dbg(PR_OEM, "could not read Time To Empty, ret=%d\n", ret); + return ret; + } + + if (ret == 0xFFFF) + return -ENODATA; + + return cv; +} + +static int fg_get_batt_status(struct bq_fg_chip *bq) +{ + fg_read_status(bq); + + if (bq->batt_fc) + return POWER_SUPPLY_STATUS_FULL; + else if (bq->batt_dsg) + return POWER_SUPPLY_STATUS_DISCHARGING; + else if (bq->batt_curr > 0) + return POWER_SUPPLY_STATUS_CHARGING; + else + return POWER_SUPPLY_STATUS_NOT_CHARGING; +} + +static int fg_get_batt_capacity_level(struct bq_fg_chip *bq) +{ + if (bq->batt_fc) + return POWER_SUPPLY_CAPACITY_LEVEL_FULL; + else if (bq->batt_rca) + return POWER_SUPPLY_CAPACITY_LEVEL_LOW; + else if (bq->batt_fd) + return POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; + else + return POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; +} + +static int fg_get_soc_decimal_rate(struct bq_fg_chip *bq) +{ + int soc, i; + + if (bq->dec_rate_len <= 0) + return 0; + + soc = fg_read_rsoc(bq); + + for (i = 0; i < bq->dec_rate_len; i += 2) { + if (soc < bq->dec_rate_seq[i]) { + return bq->dec_rate_seq[i - 1]; + } + } + + return bq->dec_rate_seq[bq->dec_rate_len - 1]; +} + +static int fg_get_soc_decimal(struct bq_fg_chip *bq) +{ + int rsoc, raw_soc; + + if (!bq) + return 0; + + rsoc = fg_read_rsoc(bq); + raw_soc = fg_get_raw_soc(bq); + + if (bq->batt_soc > rsoc) + return 0; + + return raw_soc % 100; +} + +static int fg_get_cold_thermal_level(struct bq_fg_chip *bq) +{ + union power_supply_propval pval = { + 0, + }; + int curr, i, rc, temp, volt, status; + + if (!bq) + return -EINVAL; + + if (!bq->cold_thermal_len) + return 0; + + if (!bq->batt_psy) { + bq->batt_psy = power_supply_get_by_name("battery"); + if (!bq->batt_psy) { + return 0; + } + } + + rc = power_supply_get_property(bq->batt_psy, POWER_SUPPLY_PROP_STATUS, + &pval); + if (rc < 0) { + bq_dbg(PR_OEM, "failed get batt staus\n"); + return -EINVAL; + } + status = pval.intval; + + rc = power_supply_get_property(bq->batt_psy, POWER_SUPPLY_PROP_TEMP, + &pval); + if (rc < 0) { + bq_dbg(PR_OEM, "failed get batt temp\n"); + return -EINVAL; + } + temp = pval.intval; + + rc = power_supply_get_property(bq->batt_psy, + POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); + if (rc < 0) { + bq_dbg(PR_OEM, "failed get batt temp\n"); + return -EINVAL; + } + volt = pval.intval; + + if (status == POWER_SUPPLY_STATUS_CHARGING || temp > 100 || + volt > 3500000) + return 0; + + fg_read_avg_current(bq, &curr); + + for (i = 0; i < bq->cold_thermal_len; i++) { + if (temp > bq->cold_thermal_seq[i].temp_l && + temp <= bq->cold_thermal_seq[i].temp_h && + curr > bq->cold_thermal_seq[i].curr_th) { + bq_dbg(PR_OEM, + "cold thermal trigger status:%d, temp:%d, volt:%d\n", + status, temp, volt); + bq_dbg(PR_OEM, + "curr:%d, bq->cold_thermal_seq[i].index:%d\n", + curr, bq->cold_thermal_seq[i].index); + return bq->cold_thermal_seq[i].index; + } + } + + return 0; +} + +static enum power_supply_property fg_props[] = { + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CAPACITY_LEVEL, + POWER_SUPPLY_PROP_SOC_DECIMAL, + POWER_SUPPLY_PROP_SOC_DECIMAL_RATE, + POWER_SUPPLY_PROP_COLD_THERMAL_LEVEL, + POWER_SUPPLY_PROP_TEMP, + /*POWER_SUPPLY_PROP_HEALTH,*/ /*implement it in battery power_supply*/ + POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CYCLE_COUNT, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_RESISTANCE_ID, + POWER_SUPPLY_PROP_UPDATE_NOW, + POWER_SUPPLY_PROP_CURRENT_MAX, + POWER_SUPPLY_PROP_VOLTAGE_MAX, + POWER_SUPPLY_PROP_AUTHENTIC, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, + POWER_SUPPLY_PROP_RESISTANCE, + POWER_SUPPLY_PROP_FASTCHARGE_MODE, + POWER_SUPPLY_PROP_CHARGE_COUNTER, + POWER_SUPPLY_PROP_TERMINATION_CURRENT, + POWER_SUPPLY_PROP_FFC_TERMINATION_CURRENT, + POWER_SUPPLY_PROP_RECHARGE_VBAT, + POWER_SUPPLY_PROP_MODEL_NAME, +}; + +static int fg_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct bq_fg_chip *bq = power_supply_get_drvdata(psy); + int ret; + u16 flags; + + switch (psp) { + case POWER_SUPPLY_PROP_MODEL_NAME: + if (bq->old_hw) { + val->strval = "unknown"; + break; + } + ret = fg_read_word(bq, bq->regs[BQ_FG_REG_BATT_STATUS], &flags); + if (ret < 0) + val->strval = "unknown"; + else + val->strval = "bq27z561"; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + if (bq->fake_volt != -EINVAL) { + val->intval = bq->fake_volt; + break; + } + if (bq->old_hw) { + val->intval = 3700 * 1000; + break; + } + ret = fg_read_volt(bq); + if (ret >= 0) + bq->batt_volt = ret; + val->intval = bq->batt_volt * 1000; + + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = 1; + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + if (bq->old_hw) { + val->intval = -500; + break; + } + fg_read_current(bq, &bq->batt_curr); + val->intval = bq->batt_curr * 1000; + break; + + case POWER_SUPPLY_PROP_CAPACITY: + if (bq->old_hw) { + val->intval = 50; + break; + } + val->intval = fg_read_system_soc(bq); + bq->batt_soc = val->intval; + break; + case POWER_SUPPLY_PROP_CAPACITY_LEVEL: + val->intval = fg_get_batt_capacity_level(bq); + break; + case POWER_SUPPLY_PROP_SOC_DECIMAL: + val->intval = fg_get_soc_decimal(bq); + break; + case POWER_SUPPLY_PROP_SOC_DECIMAL_RATE: + val->intval = fg_get_soc_decimal_rate(bq); + break; + case POWER_SUPPLY_PROP_COLD_THERMAL_LEVEL: + val->intval = fg_get_cold_thermal_level(bq); + break; + case POWER_SUPPLY_PROP_TEMP: + if (bq->fake_temp != -EINVAL) { + val->intval = bq->fake_temp; + break; + } + if (bq->old_hw) { + val->intval = 250; + break; + } + val->intval = bq->batt_temp; + break; + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: + if (bq->old_hw) { + val->intval = bq->batt_tte; + break; + } + ret = fg_read_tte(bq); + if (ret >= 0) + bq->batt_tte = ret; + + val->intval = bq->batt_tte; + break; + + case POWER_SUPPLY_PROP_CHARGE_FULL: + if (bq->old_hw) { + val->intval = 4050000; + break; + } + ret = fg_read_fcc(bq); + if (ret > 0) + bq->batt_fcc = ret; + val->intval = bq->batt_fcc * 1000; + break; + + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + val->intval = bq->batt_dc; + break; + + case POWER_SUPPLY_PROP_CYCLE_COUNT: + if (bq->old_hw) { + val->intval = 1; + break; + } + ret = fg_read_cyclecount(bq); + if (ret >= 0) + bq->batt_cyclecnt = ret; + val->intval = bq->batt_cyclecnt; + break; + + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO; + break; + case POWER_SUPPLY_PROP_RESISTANCE: + val->intval = bq->batt_resistance; + break; + case POWER_SUPPLY_PROP_RESISTANCE_ID: + val->intval = 100000; + break; + case POWER_SUPPLY_PROP_UPDATE_NOW: + val->intval = 0; + break; + case POWER_SUPPLY_PROP_CURRENT_MAX: + if (bq->old_hw) { + val->intval = 8000000; + break; + } + val->intval = fg_read_charging_current(bq); + if (bq->verify_digest_success == false && + !bq->ignore_digest_for_debug) { + val->intval = min(val->intval, 2000); + } + val->intval *= 1000; + break; + case POWER_SUPPLY_PROP_VOLTAGE_MAX: + if (bq->old_hw) { + val->intval = 4450000; + break; + } + val->intval = fg_read_charging_voltage(bq); + val->intval *= 1000; + break; + case POWER_SUPPLY_PROP_AUTHENTIC: + val->intval = bq->verify_digest_success; + break; + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: + if (bq->constant_charge_current_max != 0) + val->intval = bq->constant_charge_current_max; + else + val->intval = fg_read_charging_current(bq); + break; + case POWER_SUPPLY_PROP_FASTCHARGE_MODE: + if (bq->old_hw) { + val->intval = 0; + break; + } + val->intval = bq->fast_mode; + break; + case POWER_SUPPLY_PROP_CHARGE_COUNTER: + if (bq->old_hw) { + val->intval = 4050000; + break; + } + ret = fg_get_charge_counter(bq, &val->intval); + break; + case POWER_SUPPLY_PROP_TERMINATION_CURRENT: + val->intval = manu_info[TERMINATION].data; + break; + case POWER_SUPPLY_PROP_FFC_TERMINATION_CURRENT: + val->intval = manu_info[FFC_TERMINATION].data; + break; + case POWER_SUPPLY_PROP_RECHARGE_VBAT: + if (bq->batt_recharge_vol > 0) + val->intval = bq->batt_recharge_vol; + else + val->intval = manu_info[RECHARGE_VOL].data; + break; + default: + return -EINVAL; + } + return 0; +} + +static int fg_set_property(struct power_supply *psy, + enum power_supply_property prop, + const union power_supply_propval *val) +{ + struct bq_fg_chip *bq = power_supply_get_drvdata(psy); + + switch (prop) { + case POWER_SUPPLY_PROP_TEMP: + bq->fake_temp = val->intval; + break; + case POWER_SUPPLY_PROP_CAPACITY: + bq->fake_soc = val->intval; + power_supply_changed(bq->fg_psy); + break; + case POWER_SUPPLY_PROP_UPDATE_NOW: + break; + case POWER_SUPPLY_PROP_AUTHENTIC: + bq->verify_digest_success = !!val->intval; + break; + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: + bq->constant_charge_current_max = val->intval; + break; + case POWER_SUPPLY_PROP_FASTCHARGE_MODE: + fg_set_fastcharge_mode(bq, !!val->intval); + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + bq->fake_volt = val->intval; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int fg_prop_is_writeable(struct power_supply *psy, + enum power_supply_property prop) +{ + int ret; + + switch (prop) { + case POWER_SUPPLY_PROP_TEMP: + case POWER_SUPPLY_PROP_CAPACITY: + case POWER_SUPPLY_PROP_UPDATE_NOW: + case POWER_SUPPLY_PROP_AUTHENTIC: + case POWER_SUPPLY_PROP_FASTCHARGE_MODE: + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +static int fg_psy_register(struct bq_fg_chip *bq) +{ + struct power_supply_config fg_psy_cfg = {}; + + bq->fg_psy_d.name = "bms"; + bq->fg_psy_d.type = POWER_SUPPLY_TYPE_BMS; + bq->fg_psy_d.properties = fg_props; + bq->fg_psy_d.num_properties = ARRAY_SIZE(fg_props); + bq->fg_psy_d.get_property = fg_get_property; + bq->fg_psy_d.set_property = fg_set_property; + bq->fg_psy_d.property_is_writeable = fg_prop_is_writeable; + + fg_psy_cfg.drv_data = bq; + fg_psy_cfg.num_supplicants = 0; + bq->fg_psy = + devm_power_supply_register(bq->dev, &bq->fg_psy_d, &fg_psy_cfg); + if (IS_ERR(bq->fg_psy)) { + bq_dbg(PR_OEM, "Failed to register fg_psy"); + return PTR_ERR(bq->fg_psy); + } + + return 0; +} + +static void fg_psy_unregister(struct bq_fg_chip *bq) +{ + power_supply_unregister(bq->fg_psy); +} + +static const u8 fg_dump_regs[] = { + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x16, 0x18, 0x1A, + 0x1C, 0x1E, 0x20, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x66, 0x68, 0x6C, 0x6E, +}; + +static ssize_t fg_attr_show_Ra_table(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + u8 t_buf[40]; + u8 temp_buf[40]; + int ret; + int i, idx, len; + + ret = fg_mac_read_block(bq, FG_MAC_CMD_RA_TABLE, t_buf, 32); + if (ret < 0) + return 0; + + idx = 0; + len = sprintf(temp_buf, "Ra Flag:0x%02X\n", t_buf[0] << 8 | t_buf[1]); + memcpy(&buf[idx], temp_buf, len); + idx += len; + len = sprintf(temp_buf, "RaTable:\n"); + memcpy(&buf[idx], temp_buf, len); + idx += len; + for (i = 1; i < 16; i++) { + len = sprintf(temp_buf, "%d ", + t_buf[i * 2] << 8 | t_buf[i * 2 + 1]); + memcpy(&buf[idx], temp_buf, len); + idx += len; + } + + return idx; +} + +static ssize_t fg_attr_show_Qmax(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + int ret; + u8 t_buf[64]; + int len; + + memset(t_buf, 0, 64); + + ret = fg_mac_read_block(bq, FG_MAC_CMD_QMAX, t_buf, 2); + if (ret < 0) + return 0; + + len = snprintf(buf, sizeof(t_buf), "%d\n", (t_buf[1] << 8) | t_buf[0]); + + return len; +} + +static ssize_t fg_attr_show_fcc_soh(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + int ret; + u8 t_buf[64]; + int len; + + memset(t_buf, 0, 64); + + ret = fg_mac_read_block(bq, 0x0077, t_buf, 2); + if (ret < 0) + return 0; + + len = snprintf(buf, sizeof(t_buf), "%d\n", (t_buf[1] << 8) | t_buf[0]); + + return len; +} + +static ssize_t fg_attr_show_rm(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + int rm, len; + + rm = fg_read_rm(bq); + len = snprintf(buf, 1024, "%d\n", rm); + + return len; +} + +static ssize_t fg_attr_show_fcc(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + int fcc, len; + + fcc = fg_read_fcc(bq); + len = snprintf(buf, 1024, "%d\n", fcc); + + return len; +} + +static ssize_t fg_attr_show_soh(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + int soh, len; + + soh = fg_read_soh(bq); + len = snprintf(buf, 1024, "%d\n", soh); + + return len; +} + +static ssize_t verify_digest_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + u8 digest_buf[4]; + int i; + int len; + + for (i = 0; i < BATTERY_DIGEST_LEN; i++) { + memset(digest_buf, 0, sizeof(digest_buf)); + snprintf(digest_buf, sizeof(digest_buf) - 1, "%02x", + bq->digest[i]); + strlcat(buf, digest_buf, BATTERY_DIGEST_LEN * 2 + 1); + } + len = strlen(buf); + buf[len] = '\0'; + + return strlen(buf) + 1; +} + +int StringToHex(char *str, unsigned char *out, unsigned int *outlen) +{ + char *p = str; + char high = 0, low = 0; + int tmplen = strlen(p), cnt = 0; + tmplen = strlen(p); + while (cnt < (tmplen / 2)) { + high = ((*p > '9') && ((*p <= 'F') || (*p <= 'f'))) ? + *p - 48 - 7 : + *p - 48; + low = (*(++p) > '9' && ((*p <= 'F') || (*p <= 'f'))) ? + *(p)-48 - 7 : + *(p)-48; + out[cnt] = ((high & 0x0f) << 4 | (low & 0x0f)); + p++; + cnt++; + } + if (tmplen % 2 != 0) + out[cnt] = ((*p > '9') && ((*p <= 'F') || (*p <= 'f'))) ? + *p - 48 - 7 : + *p - 48; + + if (outlen != NULL) + *outlen = tmplen / 2 + tmplen % 2; + + return tmplen / 2 + tmplen % 2; +} + +ssize_t verify_digest_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + int i; + u8 random[32] = { 0 }; + char kbuf[70] = { 0 }; + + memset(kbuf, 0, sizeof(kbuf)); + strncpy(kbuf, buf, count - 1); + + StringToHex(kbuf, random, &i); + fg_sha256_auth(bq, random, BATTERY_DIGEST_LEN); + + return count; +} + +static ssize_t fg_attr_show_TRemQ(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + int ret; + u8 t_buf[64]; + int len; + + memset(t_buf, 0, 64); + + ret = fg_mac_read_block(bq, FG_MAC_CMD_ITSTATUS1, t_buf, 36); + if (ret < 0) + return 0; + + len = snprintf(buf, sizeof(t_buf), "%d\n", (t_buf[1] << 8) | t_buf[0]); + + return len; +} + +static ssize_t fg_attr_show_TFullChgQ(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + int ret; + u8 t_buf[64]; + int len; + + memset(t_buf, 0, 64); + + ret = fg_mac_read_block(bq, FG_MAC_CMD_ITSTATUS1, t_buf, 36); + if (ret < 0) + return 0; + + len = snprintf(buf, sizeof(t_buf), "%d\n", (t_buf[9] << 8) | t_buf[8]); + + return len; +} + +static ssize_t fg_attr_show_TSim(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + int ret; + u8 t_buf[64]; + int len; + + memset(t_buf, 0, 64); + + ret = fg_mac_read_block(bq, FG_MAC_CMD_ITSTATUS1, t_buf, 36); + if (ret < 0) + return 0; + + len = snprintf(buf, sizeof(t_buf), "%d\n", + (t_buf[13] << 8) | t_buf[12]); + + return len; +} + +static ssize_t fg_attr_show_TAmbient(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + int ret; + u8 t_buf[64]; + int len; + + memset(t_buf, 0, 64); + + ret = fg_mac_read_block(bq, FG_MAC_CMD_ITSTATUS1, t_buf, 36); + if (ret < 0) + return 0; + + len = snprintf(buf, sizeof(t_buf), "%d\n", + (t_buf[15] << 8) | t_buf[14]); + + return len; +} + +static DEVICE_ATTR(verify_digest, 0660, verify_digest_show, + verify_digest_store); +static DEVICE_ATTR(RaTable, S_IRUGO, fg_attr_show_Ra_table, NULL); +static DEVICE_ATTR(Qmax, S_IRUGO, fg_attr_show_Qmax, NULL); +static DEVICE_ATTR(fcc_soh, S_IRUGO, fg_attr_show_fcc_soh, NULL); +static DEVICE_ATTR(rm, S_IRUGO, fg_attr_show_rm, NULL); +static DEVICE_ATTR(fcc, S_IRUGO, fg_attr_show_fcc, NULL); +static DEVICE_ATTR(soh, S_IRUGO, fg_attr_show_soh, NULL); +static DEVICE_ATTR(TRemQ, S_IRUGO, fg_attr_show_TRemQ, NULL); +static DEVICE_ATTR(TFullChgQ, S_IRUGO, fg_attr_show_TFullChgQ, NULL); +static DEVICE_ATTR(TSim, S_IRUGO, fg_attr_show_TSim, NULL); +static DEVICE_ATTR(TAmbient, S_IRUGO, fg_attr_show_TAmbient, NULL); + +static struct attribute *fg_attributes[] = { + &dev_attr_RaTable.attr, &dev_attr_Qmax.attr, + &dev_attr_fcc_soh.attr, &dev_attr_rm.attr, + &dev_attr_fcc.attr, &dev_attr_soh.attr, + &dev_attr_verify_digest.attr, &dev_attr_TRemQ.attr, + &dev_attr_TFullChgQ.attr, &dev_attr_TSim.attr, + &dev_attr_TAmbient.attr, NULL, +}; + +static const struct attribute_group fg_attr_group = { + .attrs = fg_attributes, +}; + +static int fg_dump_registers(struct bq_fg_chip *bq) +{ + int i; + int ret; + u16 val; + + for (i = 0; i < ARRAY_SIZE(fg_dump_regs); i++) { + ret = fg_read_word(bq, fg_dump_regs[i], &val); + if (!ret) + bq_dbg(PR_REGISTER, "Reg[%02X] = 0x%04X\n", + fg_dump_regs[i], val); + } + + return ret; +} + +static void fg_update_status(struct bq_fg_chip *bq) +{ + static int last_st, last_soc, last_temp; + int rm, fcc; + + mutex_lock(&bq->data_lock); + + bq->batt_soc = fg_read_system_soc(bq); + bq->batt_volt = fg_read_volt(bq); + fg_read_current(bq, &bq->batt_curr); + bq->batt_temp = fg_read_temperature(bq); + bq->batt_st = fg_get_batt_status(bq); + rm = fg_read_rm(bq); + fcc = fg_read_fcc(bq); + + mutex_unlock(&bq->data_lock); + + bq_dbg(PR_OEM, "SOC:%d,Volt:%d,Cur:%d,Temp:%d,RM:%d,FC:%d,FAST:%d", + bq->batt_soc, bq->batt_volt, bq->batt_curr, bq->batt_temp, rm, + fcc, bq->fast_mode); + + if ((last_soc != bq->batt_soc) || (last_temp != bq->batt_temp) || + (last_st != bq->batt_st)) { + if (bq->fg_psy) + power_supply_changed(bq->fg_psy); + } + + last_soc = bq->batt_soc; + last_temp = bq->batt_temp; + last_st = bq->batt_st; +} + +static int fg_get_raw_soc(struct bq_fg_chip *bq) +{ + int rm, fcc; + int raw_soc; + + rm = fg_read_rm(bq); + fcc = fg_read_fcc(bq); + + raw_soc = rm * 10000 / fcc; + + return raw_soc; +} + +static int calc_delta_time(struct timeval *time_start, int *delta_time) +{ + struct timeval time_now; + + *delta_time = 0; + + do_gettimeofday(&time_now); + *delta_time = (time_now.tv_sec - time_start->tv_sec); + if (*delta_time < 0) + *delta_time = 0; + + return 0; +} + +#define BATT_HIGH_AVG_CURRENT 1000000 +#define NORMAL_TEMP_CHARGING_DELTA 10 +#define NORMAL_DISTEMP_CHARGING_DELTA 60 +#define LOW_TEMP_CHARGING_DELTA 10 +#define LOW_TEMP_DISCHARGING_DELTA 20 +#define BATT_TEMP_LOW_THRED 150 +#define FFC_SMOOTH_LEN 4 +#define FG_RAW_SOC_FULL 10000 + +struct ffc_smooth { + int curr_lim; + int time; +}; + +struct ffc_smooth ffc_dischg_smooth[FFC_SMOOTH_LEN] = { + { 0, 300 }, + { 300, 150 }, + { 600, 72 }, + { 1000, 50 }, +}; + +static int bq_battery_soc_smooth_tracking(struct bq_fg_chip *bq, int raw_soc, + int batt_soc, int batt_temp, + int batt_ma) +{ + return batt_soc; +} + +static void fg_monitor_workfunc(struct work_struct *work) +{ + struct bq_fg_chip *bq = + container_of(work, struct bq_fg_chip, monitor_work.work); + int rc; + + if (!bq->old_hw) { + rc = fg_dump_registers(bq); + /*if (rc < 0) + return;*/ + fg_update_status(bq); + } + + schedule_delayed_work(&bq->monitor_work, 10 * HZ); +} +static int bq_parse_dt(struct bq_fg_chip *bq) +{ + struct device_node *node = bq->dev->of_node; + int ret, size; + + ret = of_property_read_u32(node, "bq,charge-full-design", &bq->batt_dc); + if (ret < 0) { + bq_dbg(PR_OEM, "failed to get bq,charge-full-designe\n"); + bq->batt_dc = DEFUALT_FULL_DESIGN; + return ret; + } + + ret = of_property_read_u32(node, "bq,recharge-voltage", + &bq->batt_recharge_vol); + if (ret < 0) { + bq_dbg(PR_OEM, "failed to get bq,recharge-voltage\n"); + bq->batt_recharge_vol = -EINVAL; + return ret; + } + + bq->ignore_digest_for_debug = + of_property_read_bool(node, "bq,ignore-digest-debug"); + + size = 0; + of_get_property(node, "bq,soc_decimal_rate", &size); + if (size) { + bq->dec_rate_seq = devm_kzalloc(bq->dev, size, GFP_KERNEL); + if (bq->dec_rate_seq) { + bq->dec_rate_len = (size / sizeof(*bq->dec_rate_seq)); + if (bq->dec_rate_len % 2) { + bq_dbg(PR_OEM, + "invalid soc decimal rate seq\n"); + return -EINVAL; + } + of_property_read_u32_array(node, "bq,soc_decimal_rate", + bq->dec_rate_seq, + bq->dec_rate_len); + } else { + bq_dbg(PR_OEM, + "error allocating memory for dec_rate_seq\n"); + } + } + + size = 0; + of_get_property(node, "bq,cold_thermal_seq", &size); + if (size) { + bq->cold_thermal_seq = devm_kzalloc(bq->dev, size, GFP_KERNEL); + if (bq->cold_thermal_seq) { + bq->cold_thermal_len = (size / sizeof(int)); + if (bq->cold_thermal_len % 4) { + bq_dbg(PR_OEM, "invalid cold thermal seq\n"); + return -EINVAL; + } + of_property_read_u32_array(node, "bq,cold_thermal_seq", + (int *)bq->cold_thermal_seq, + bq->cold_thermal_len); + bq->cold_thermal_len = bq->cold_thermal_len / 4; + } else { + bq_dbg(PR_OEM, + "error allocating memory for cold thermal seq\n"); + } + } + + return 0; +} + +static struct regmap_config i2c_bq27z561_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0xFFFF, +}; + +static int bq_fg_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + struct bq_fg_chip *bq; + u8 *regs; + + bq = devm_kzalloc(&client->dev, sizeof(*bq), GFP_DMA); + + if (!bq) + return -ENOMEM; + + bq->dev = &client->dev; + bq->client = client; + bq->chip = id->driver_data; + + bq->batt_soc = -ENODATA; + bq->batt_fcc = -ENODATA; + bq->batt_rm = -ENODATA; + bq->batt_dc = -ENODATA; + bq->batt_volt = -ENODATA; + bq->batt_temp = -ENODATA; + bq->batt_curr = -ENODATA; + bq->batt_cyclecnt = -ENODATA; + bq->batt_tte = -ENODATA; + + bq->fake_soc = -EINVAL; + bq->fake_temp = -EINVAL; + bq->fake_volt = -EINVAL; + + if (bq->chip == BQ27Z561) { + regs = bq27z561_regs; + } else { + bq_dbg(PR_OEM, "unexpected fuel gauge: %d\n", bq->chip); + regs = bq27z561_regs; + } + memcpy(bq->regs, regs, NUM_REGS); + + i2c_set_clientdata(client, bq); + + bq_parse_dt(bq); + + bq->regmap = devm_regmap_init_i2c(client, &i2c_bq27z561_regmap_config); + if (!bq->regmap) + return -ENODEV; + + fg_get_manufacture_data(bq); + fg_set_fastcharge_mode(bq, false); + + mutex_init(&bq->i2c_rw_lock); + mutex_init(&bq->data_lock); + device_init_wakeup(bq->dev, 1); + + fg_psy_register(bq); + fg_update_status(bq); + + ret = sysfs_create_group(&bq->dev->kobj, &fg_attr_group); + if (ret) + bq_dbg(PR_OEM, "Failed to register sysfs, err:%d\n", ret); + + INIT_DELAYED_WORK(&bq->monitor_work, fg_monitor_workfunc); + schedule_delayed_work(&bq->monitor_work, 10 * HZ); + + bq_dbg(PR_OEM, "bq fuel gauge probe successfully, %s\n", + device2str[bq->chip]); + + return 0; +} + +static int bq_fg_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + + do_gettimeofday(&bq->suspend_time); + + cancel_delayed_work(&bq->monitor_work); + + return 0; +} +#define BQ_RESUME_UPDATE_TIME 600 + +static int bq_fg_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bq_fg_chip *bq = i2c_get_clientdata(client); + int delta_time; + + calc_delta_time(&bq->suspend_time, &delta_time); + + if (delta_time > BQ_RESUME_UPDATE_TIME) { + bq_dbg(PR_OEM, "suspend more than %d, update soc now\n", + BQ_RESUME_UPDATE_TIME); + bq->update_now = true; + } + + schedule_delayed_work(&bq->monitor_work, HZ); + + return 0; +} + +static int bq_fg_remove(struct i2c_client *client) +{ + struct bq_fg_chip *bq = i2c_get_clientdata(client); + + fg_psy_unregister(bq); + + mutex_destroy(&bq->data_lock); + mutex_destroy(&bq->i2c_rw_lock); + + sysfs_remove_group(&bq->dev->kobj, &fg_attr_group); + + return 0; +} + +static void bq_fg_shutdown(struct i2c_client *client) +{ + bq_dbg(PR_OEM, "bq fuel gauge driver shutdown!\n"); +} + +static struct of_device_id bq_fg_match_table[] = { + { + .compatible = "ti,bq27z561", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, bq_fg_match_table); + +static const struct i2c_device_id bq_fg_id[] = { + { "bq27z561", BQ27Z561 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, bq_fg_id); + +static const struct dev_pm_ops bq_fg_pm_ops = { + .resume = bq_fg_resume, + .suspend = bq_fg_suspend, +}; + +static struct i2c_driver bq_fg_driver = { + .driver = { + .name = "bq_fg", + .owner = THIS_MODULE, + .of_match_table = bq_fg_match_table, + .pm = &bq_fg_pm_ops, + }, + .id_table = bq_fg_id, + + .probe = bq_fg_probe, + .remove = bq_fg_remove, + .shutdown = bq_fg_shutdown, + +}; + +module_i2c_driver(bq_fg_driver); + +MODULE_DESCRIPTION("TI BQ27Z561 Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Texas Instruments"); diff --git a/drivers/power/supply/ti/cp_qc30.c b/drivers/power/supply/ti/cp_qc30.c new file mode 100644 index 000000000000..47b23ede9bf8 --- /dev/null +++ b/drivers/power/supply/ti/cp_qc30.c @@ -0,0 +1,1527 @@ +/* + * State machine for qc3 when it works on cp + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define pr_fmt(fmt) "[FC2-PM]: %s: " fmt, __func__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cp_qc30.h" + +#ifdef pr_debug +#undef pr_debug +#define pr_debug pr_err +#endif +#ifdef pr_info +#undef pr_info +#define pr_info pr_err +#endif + +#define BATT_MAX_CHG_VOLT 4400 +#define BATT_FAST_CHG_CURR 5400 +#define BUS_OVP_THRESHOLD 12000 +#define BUS_OVP_ALARM_THRESHOLD 9500 + +#define BUS_VOLT_INIT_UP 200 + +#define BAT_VOLT_LOOP_LMT BATT_MAX_CHG_VOLT +#define BAT_CURR_LOOP_LMT BATT_FAST_CHG_CURR +#define BUS_VOLT_LOOP_LMT BUS_OVP_THRESHOLD + +#define VOLT_UP true +#define VOLT_DOWN false + +#define ADC_ERR 1 +#define CP_ENABLE_FAIL 2 +#define TAPER_DONE 1 + +#ifdef CONFIG_CHARGER_LN8000 +#define VBUS_COMP 250 +#else +#define VBUS_COMP 150 +#endif + +enum { + VBUS_ERROR_NONE, + VBUS_ERROR_LOW, + VBUS_ERROR_HIGH, +}; + +static struct sys_config sys_config = { + .bat_volt_lp_lmt = BAT_VOLT_LOOP_LMT, + .ffc_bat_volt_lmt = BAT_VOLT_LOOP_LMT, + .bat_curr_lp_lmt = BAT_CURR_LOOP_LMT /* + 1000*/, + .bus_volt_lp_lmt = BUS_VOLT_LOOP_LMT, + .bus_curr_lp_lmt = BAT_CURR_LOOP_LMT >> 1, + + .ibus_minus_deviation_val = HVDCP3_IBUS_MINUS_DEV_VAL, + .ibus_plus_deviation_val = HVDCP3_IBUS_PLUS_DEV_VAL, + .ibat_minus_deviation_val = HVDCP3_IBAT_MINUS_DEV_VAL, + .ibat_plus_deviation_val = HVDCP3_IBAT_PLUS_DEV_VAL, + + .fc2_taper_current = 2200, + .flash2_policy.down_steps = -1, + .flash2_policy.volt_hysteresis = 50, + + .min_vbat_start_flash2 = 3500, + .cp_sec_enable = false, + .qc3p5_supported = false, +}; + +struct cp_qc30_data { + struct device *dev; + int bat_volt_max; + int ffc_bat_volt_max; + int bat_curr_max; + int bus_volt_max; + int bus_curr_max; + bool cp_sec_enable; + bool qc3p5_supported; + + /* notifiers */ + struct notifier_block nb; +}; + +static pm_t pm_state; + +static int fc2_taper_timer; +static int ibus_lmt_change_timer; + +static struct power_supply *cp_get_sw_psy(void) +{ + if (!pm_state.sw_psy) + pm_state.sw_psy = power_supply_get_by_name("battery"); + + return pm_state.sw_psy; +} + +static struct power_supply *cp_get_usb_psy(void) +{ + if (!pm_state.usb_psy) + pm_state.usb_psy = power_supply_get_by_name("usb"); + + return pm_state.usb_psy; +} + +static struct power_supply *cp_get_bms_psy(void) +{ + if (!pm_state.bms_psy) + pm_state.bms_psy = power_supply_get_by_name("bms"); + + return pm_state.bms_psy; +} + +static int cp_get_effective_fcc_val(pm_t pm_state) +{ + int effective_fcc_val = 0; + + if (!pm_state.fcc_votable) + pm_state.fcc_votable = find_votable("FCC"); + + if (!pm_state.fcc_votable) + return -EINVAL; + + effective_fcc_val = get_effective_result(pm_state.fcc_votable); + effective_fcc_val = effective_fcc_val / 1000; + pr_info("effective_fcc_val: %d\n", effective_fcc_val); + return effective_fcc_val; +} + +static struct power_supply *cp_get_fc_psy(void) +{ + if (!pm_state.fc_psy) { + if (sys_config.cp_sec_enable) + pm_state.fc_psy = + power_supply_get_by_name("bq2597x-master"); + else + pm_state.fc_psy = + power_supply_get_by_name("bq2597x-standalone"); + } + + return pm_state.fc_psy; +} + +static void cp_update_bms_ibat(void) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_bms_psy(); + if (!psy) + return; + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_CURRENT_NOW, + &val); + if (!ret) + pm_state.ibat_now = -(val.intval / 1000); +} + +static int qc3_get_bms_fastcharge_mode(void) +{ + union power_supply_propval pval = { + 0, + }; + int rc; + + cp_get_bms_psy(); + + if (!pm_state.bms_psy) + return 0; + + rc = power_supply_get_property( + pm_state.bms_psy, POWER_SUPPLY_PROP_FASTCHARGE_MODE, &pval); + if (rc < 0) { + pr_info("Couldn't get fastcharge mode:%d\n", rc); + return 0; + } + + pm_state.bms_fastcharge_mode = pval.intval; + + return pval.intval; +} + +/* get thermal level from battery power supply property */ +static int qc3_get_batt_current_thermal_level(int *level) +{ + int ret, rc; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_sw_psy(); + if (!psy) + return 0; + + ret = power_supply_get_property( + psy, POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &val); + + if (rc < 0) { + pr_info("Couldn't get themal level:%d\n", rc); + return rc; + } + + pr_err("val.intval: %d\n", val.intval); + + *level = val.intval; + return rc; +} + +/* determine whether to disable cp according to jeita status */ +static bool qc3_disable_cp_by_jeita_status(void) +{ + int batt_temp = 0, bq_input_suspend = 0; + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_sw_psy(); + if (!psy) + return false; + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_BQ_INPUT_SUSPEND, + &val); + if (!ret) + bq_input_suspend = !!val.intval; + + psy = cp_get_bms_psy(); + if (!psy) + return false; + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TEMP, &val); + + if (ret < 0) { + pr_info("Couldn't get batt temp prop:%d\n", ret); + return false; + } + + batt_temp = val.intval; + pr_err("batt_temp: %d\n", batt_temp); + + if (bq_input_suspend) { + return true; + } else { + if (batt_temp >= JEITA_WARM_THR && !pm_state.jeita_triggered) { + pm_state.jeita_triggered = true; + return true; + } else if (batt_temp <= JEITA_COOL_NOT_ALLOW_CP_THR && + !pm_state.jeita_triggered) { + pm_state.jeita_triggered = true; + return true; + } else if ((batt_temp <= (JEITA_WARM_THR - JEITA_HYSTERESIS)) && + (batt_temp >= + (JEITA_COOL_NOT_ALLOW_CP_THR + JEITA_HYSTERESIS)) && + pm_state.jeita_triggered) { + pm_state.jeita_triggered = false; + return false; + } else { + return pm_state.jeita_triggered; + } + } +} + +static int qc3_check_slowly_charging_enabled(void) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_sw_psy(); + if (!psy) + return false; + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_SLOWLY_CHARGING, + &val); + if (!ret) + pm_state.slowly_charging = !!val.intval; + + return ret; +} + +static void cp_get_batt_capacity(void) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_sw_psy(); + if (!psy) + return; + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_CAPACITY, &val); + if (!ret) + pm_state.capacity = val.intval; + pr_info("capacity %d\n", pm_state.capacity); +} + +static void cp_update_fc_status(void) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_fc_psy(); + if (!psy) + return; + + ret = power_supply_get_property( + psy, POWER_SUPPLY_PROP_TI_BATTERY_VOLTAGE, &val); + if (!ret) + pm_state.bq2597x.vbat_volt = val.intval; + + /*ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TI_BATTERY_CURRENT, &val); + if (!ret) + pm_state.bq2597x.ibat_curr = val.intval; */ + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TI_BUS_VOLTAGE, + &val); + if (!ret) + pm_state.bq2597x.vbus_volt = val.intval; + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TI_BUS_CURRENT, + &val); + if (!ret) + pm_state.bq2597x.ibus_curr = val.intval; + + ret = power_supply_get_property( + psy, POWER_SUPPLY_PROP_TI_BUS_TEMPERATURE, &val); + if (!ret) + pm_state.bq2597x.bus_temp = val.intval; + + ret = power_supply_get_property( + psy, POWER_SUPPLY_PROP_TI_BATTERY_TEMPERATURE, &val); + if (!ret) + pm_state.bq2597x.bat_temp = val.intval; + + ret = power_supply_get_property( + psy, POWER_SUPPLY_PROP_TI_DIE_TEMPERATURE, &val); + if (!ret) + pm_state.bq2597x.die_temp = val.intval; + + ret = power_supply_get_property( + psy, POWER_SUPPLY_PROP_TI_BATTERY_PRESENT, &val); + if (!ret) + pm_state.bq2597x.batt_pres = val.intval; + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TI_VBUS_PRESENT, + &val); + if (!ret) + pm_state.bq2597x.vbus_pres = val.intval; + + ret = power_supply_get_property( + psy, POWER_SUPPLY_PROP_TI_BUS_ERROR_STATUS, &val); + if (!ret) + pm_state.bq2597x.bus_error_status = val.intval; + + if (pm_state.bq2597x.vbus_pres == 1) { + cp_update_bms_ibat(); + pm_state.bq2597x.ibat_curr = pm_state.ibat_now; + } + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_CHARGING_ENABLED, + &val); + if (!ret) + pm_state.bq2597x.charge_enabled = val.intval; + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TI_ALARM_STATUS, + &val); + if (!ret) { + pm_state.bq2597x.bat_ovp_alarm = + !!(val.intval & BAT_OVP_ALARM_MASK); + pm_state.bq2597x.bat_ocp_alarm = + !!(val.intval & BAT_OCP_ALARM_MASK); + pm_state.bq2597x.bus_ovp_alarm = + !!(val.intval & BUS_OVP_ALARM_MASK); + pm_state.bq2597x.bus_ocp_alarm = + !!(val.intval & BUS_OCP_ALARM_MASK); + pm_state.bq2597x.bat_ucp_alarm = + !!(val.intval & BAT_UCP_ALARM_MASK); + pm_state.bq2597x.bat_therm_alarm = + !!(val.intval & BAT_THERM_ALARM_MASK); + pm_state.bq2597x.bus_therm_alarm = + !!(val.intval & BUS_THERM_ALARM_MASK); + pm_state.bq2597x.die_therm_alarm = + !!(val.intval & DIE_THERM_ALARM_MASK); + } + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TI_FAULT_STATUS, + &val); + if (!ret) { + pm_state.bq2597x.bat_ovp_fault = + !!(val.intval & BAT_OVP_FAULT_MASK); + pm_state.bq2597x.bat_ocp_fault = + !!(val.intval & BAT_OCP_FAULT_MASK); + pm_state.bq2597x.bus_ovp_fault = + !!(val.intval & BUS_OVP_FAULT_MASK); + pm_state.bq2597x.bus_ocp_fault = + !!(val.intval & BUS_OCP_FAULT_MASK); + pm_state.bq2597x.bat_therm_fault = + !!(val.intval & BAT_THERM_FAULT_MASK); + pm_state.bq2597x.bus_therm_fault = + !!(val.intval & BUS_THERM_FAULT_MASK); + pm_state.bq2597x.die_therm_fault = + !!(val.intval & DIE_THERM_FAULT_MASK); + } + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TI_REG_STATUS, + &val); + if (!ret) { + pm_state.bq2597x.vbat_reg = + !!(val.intval & VBAT_REG_STATUS_MASK); + pm_state.bq2597x.ibat_reg = + !!(val.intval & IBAT_REG_STATUS_MASK); + } +} + +static int cp_enable_fc(bool enable) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_fc_psy(); + if (!psy) + return -ENODEV; + + val.intval = enable; + ret = power_supply_set_property(psy, POWER_SUPPLY_PROP_CHARGING_ENABLED, + &val); + + return ret; +} + +static int cp_set_qc_bus_protections(int hvdcp3_type) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_fc_psy(); + if (!psy) + return -ENODEV; + + val.intval = hvdcp3_type; + ret = power_supply_set_property( + psy, POWER_SUPPLY_PROP_TI_SET_BUS_PROTECTION_FOR_QC3, &val); + + return ret; +} + +static int cp_enable_sw(bool enable) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_sw_psy(); + if (!psy) + return -ENODEV; + + val.intval = enable; + ret = power_supply_set_property( + psy, POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED, &val); + + return ret; +} + +static int cp_limit_sw(bool enable) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_sw_psy(); + if (!psy) + return -ENODEV; + + val.intval = enable; + ret = power_supply_set_property( + psy, POWER_SUPPLY_PROP_BATTERY_CHARGING_LIMITED, &val); + + return ret; +} + +static int cp_check_fc_enabled(void) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_fc_psy(); + if (!psy) + return -ENODEV; + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_CHARGING_ENABLED, + &val); + if (!ret) + pm_state.bq2597x.charge_enabled = !!val.intval; + + pr_info("pm_state.bq2597x.charge_enabled: %d\n", + pm_state.bq2597x.charge_enabled); + return ret; +} + +static int cp_check_sw_enabled(void) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_sw_psy(); + if (!psy) + return -ENODEV; + + ret = power_supply_get_property( + psy, POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED, &val); + if (!ret) + pm_state.sw_chager.charge_enabled = !!val.intval; + + pr_info("pm_state.sw_chager.charge_enabled: %d\n", + pm_state.sw_chager.charge_enabled); + return ret; +} + +static int cp_check_sw_limited(void) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_sw_psy(); + if (!psy) + return -ENODEV; + + ret = power_supply_get_property( + psy, POWER_SUPPLY_PROP_BATTERY_CHARGING_LIMITED, &val); + if (!ret) + pm_state.sw_chager.charge_limited = !!val.intval; + + pr_info("pm_state.sw_chager.charge_limited: %d\n", + pm_state.sw_chager.charge_limited); + return ret; +} + +static void cp_update_sw_status(void) +{ + cp_check_sw_enabled(); + cp_check_sw_limited(); +} + +static int cp_tune_vbus_volt(bool up) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_sw_psy(); + if (!psy) + return -ENODEV; + + if (up) + val.intval = POWER_SUPPLY_DP_DM_DP_PULSE; + else + val.intval = POWER_SUPPLY_DP_DM_DM_PULSE; + + ret = power_supply_set_property(psy, POWER_SUPPLY_PROP_DP_DM_BQ, &val); + + pr_info("tune adapter voltage %s %s\n", up ? "up" : "down", + ret ? "fail" : "successfully"); + + return ret; +} + +static int cp_get_qc_pulse_cnt(void) +{ + int ret = 0, cnt = 0; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_sw_psy(); + if (!psy) + return -ENODEV; + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_DP_DM_BQ, &val); + if (!ret) + cnt = val.intval; + + pr_info("pulse_cnt:%d\n", cnt); + return cnt; +} + +static int cp_reset_vbus_volt(void) +{ + int ret; + int qc3p5_reset_vbus_retry = 0; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + if (pm_state.usb_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) { + cp_update_fc_status(); + pr_err("vbat=%d,vbus=%d\n", pm_state.bq2597x.vbat_volt, + pm_state.bq2597x.vbus_volt); + while (pm_state.bq2597x.vbus_volt > 6550) { + cp_tune_vbus_volt(VOLT_DOWN); + cp_update_fc_status(); + qc3p5_reset_vbus_retry++; + usleep_range(10000, 10010); + pr_err("qc3p5_reset_vbus_retry=%d,vbus=%d\n", + qc3p5_reset_vbus_retry, + pm_state.bq2597x.vbus_volt); + if (qc3p5_reset_vbus_retry > 300) { + pr_err("Failed to reset qc3.5 adapter volt to 6.55v or less\n"); + break; + } + } + } else { + psy = cp_get_sw_psy(); + if (!psy) + return -ENODEV; + + val.intval = POWER_SUPPLY_DP_DM_FORCE_5V; + + ret = power_supply_set_property(psy, POWER_SUPPLY_PROP_DP_DM_BQ, + &val); + + pr_err("reset vbus volt %s\n", ret ? "fail" : "successfully"); + } + + return ret; +} + +static int cp_get_usb_type(void) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_usb_psy(); + if (!psy) + return -ENODEV; + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_REAL_TYPE, &val); + if (!ret) + pm_state.usb_type = val.intval; + + return ret; +} + +static int cp_get_usb_present(void) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_usb_psy(); + if (!psy) + return -ENODEV; + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_PRESENT, &val); + if (!ret) + pm_state.usb_present = val.intval; + + return ret; +} + +static int cp_get_qc_hvdcp3_type(void) +{ + int ret; + struct power_supply *psy; + union power_supply_propval val = { + 0, + }; + + psy = cp_get_usb_psy(); + if (!psy) + return -ENODEV; + + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_HVDCP3_TYPE, + &val); + if (!ret) + pm_state.hvdcp3_type = val.intval; + pr_info("hvdcp3 type %s\n", pm_state.hvdcp3_type); + return ret; +} + +#define TAPER_TIMEOUT 10 +#define IBUS_CHANGE_TIMEOUT 5 +static int cp_flash2_charge(unsigned int port) +{ + static int ibus_limit, ibat_limit; + int thermal_level = 0; + uint16_t effective_fcc_val = cp_get_effective_fcc_val(pm_state); + uint16_t effective_ibus_val = effective_fcc_val / 2; + if (ibus_limit == 0) + ibus_limit = pm_state.ibus_lmt_curr; + ibus_limit = min(effective_ibus_val, pm_state.ibus_lmt_curr); + + qc3_get_bms_fastcharge_mode(); + if (pm_state.bms_fastcharge_mode) + sys_config.bat_volt_lp_lmt = sys_config.ffc_bat_volt_lmt; + pr_info("bat_volt_lp_lmt = %d\n", sys_config.bat_volt_lp_lmt); + pr_info("ibus_limit: %d\n", ibus_limit); + + pr_info("vbus=%d, ibus=%d, vbat=%d, ibat=%d, ibus_target_val=%d\n", + pm_state.bq2597x.vbus_volt, pm_state.bq2597x.ibus_curr, + pm_state.bq2597x.vbat_volt, pm_state.bq2597x.ibat_curr, + effective_ibus_val); + qc3_get_batt_current_thermal_level(&thermal_level); + qc3_check_slowly_charging_enabled(); + + pm_state.is_temp_out_fc2_range = qc3_disable_cp_by_jeita_status(); + pr_info("is_temp_out_fc2_range:%d\n", pm_state.is_temp_out_fc2_range); + + pr_info("bq2597x bat_ovp_fault: %d,bat_ocp_fault =%d,bus_ovp_fault=%d,bus_ocp_fault=%d,bat_ucp_alarm=%d,vbat_reg=%d\n", + pm_state.bq2597x.bat_ovp_fault, pm_state.bq2597x.bat_ocp_fault, + pm_state.bq2597x.bus_ovp_fault, pm_state.bq2597x.bus_ocp_fault, + pm_state.bq2597x.bat_ucp_alarm, pm_state.bq2597x.vbat_reg); + ibat_limit = min(effective_fcc_val, sys_config.bat_curr_lp_lmt); + if (!pm_state.batt_cell_volt_triggered) { + cp_get_batt_capacity(); + if (pm_state.usb_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) { + if (pm_state.bq2597x.vbat_volt >= 4250 || + pm_state.capacity > 40) { + sys_config.ibus_minus_deviation_val = + HVDCP3P5_IBUS_MINUS_DEV_VAL; + sys_config.ibus_plus_deviation_val = + HVDCP3P5_IBUS_PLUS_DEV_VAL; + sys_config.ibat_minus_deviation_val = + HVDCP3P5_IBAT_MINUS_DEV_VAL + 100; + sys_config.ibat_plus_deviation_val = + HVDCP3P5_IBAT_PLUS_DEV_VAL - 50; + pm_state.batt_cell_volt_triggered = true; + pr_info("for qc3.5, cell_vbat > 4250mv or soc > 40%, modify bq adjust params\n"); + } + } else if (pm_state.usb_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) { + if (pm_state.bq2597x.vbat_volt >= 4200 || + pm_state.capacity > 29) { + sys_config.ibus_minus_deviation_val = + HVDCP3_IBUS_MINUS_DEV_VAL; + sys_config.ibus_plus_deviation_val = + HVDCP3_IBUS_PLUS_DEV_VAL; + sys_config.ibat_minus_deviation_val = + HVDCP3_IBAT_MINUS_DEV_VAL + 450; + sys_config.ibat_plus_deviation_val = + HVDCP3_IBAT_PLUS_DEV_VAL - 450; + pm_state.batt_cell_volt_triggered = true; + pr_info("for qc3.0, cell_vbat > 4200mv or soc > 29%, modify bq adjust params\n"); + } + } + } + + pr_info("target: t_vbus=%d, t_ibus=%d(m:%d, p:%d), t_vbat=%d, t_ibat=%d(m:%d, p:%d)\n", + 9500, ibus_limit, sys_config.ibus_minus_deviation_val, + sys_config.ibus_plus_deviation_val, sys_config.bat_volt_lp_lmt, + ibat_limit, sys_config.ibat_minus_deviation_val, + sys_config.ibat_plus_deviation_val); + + if (pm_state.bq2597x.vbus_volt < 10000 && + pm_state.bq2597x.ibus_curr < ibus_limit && + !pm_state.bq2597x.bus_ocp_alarm && + !pm_state.bq2597x.bus_ovp_alarm && + pm_state.bq2597x.vbat_volt < sys_config.bat_volt_lp_lmt - 50 && + pm_state.bq2597x.ibat_curr < sys_config.bat_curr_lp_lmt && + pm_state.usb_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) + + cp_tune_vbus_volt(VOLT_UP); + + if (pm_state.bq2597x.vbus_volt <= 9500 && + pm_state.bq2597x.ibus_curr < + ibus_limit - sys_config.ibus_minus_deviation_val && + !pm_state.bq2597x.bus_ocp_alarm && + !pm_state.bq2597x.bus_ovp_alarm && + pm_state.bq2597x.vbat_volt < sys_config.bat_volt_lp_lmt - 50 && + pm_state.bq2597x.ibat_curr < + ibat_limit - sys_config.ibat_minus_deviation_val) { + cp_tune_vbus_volt(VOLT_UP); + } + + if (pm_state.bq2597x.bus_ocp_alarm || pm_state.bq2597x.bus_ovp_alarm || + pm_state.bq2597x.vbat_reg || + pm_state.bq2597x.vbat_volt > sys_config.bat_volt_lp_lmt || + pm_state.bq2597x.ibat_curr > + ibat_limit + sys_config.ibat_plus_deviation_val || + pm_state.bq2597x.ibus_curr > + ibus_limit + sys_config.ibus_plus_deviation_val) { + cp_tune_vbus_volt(VOLT_DOWN); + } + + cp_check_fc_enabled(); + + /* battery overheat, stop charge */ + if (pm_state.bq2597x.bat_therm_fault) + return -ADC_ERR; + else if (pm_state.bq2597x.bus_ocp_fault || + pm_state.bq2597x.bat_ovp_fault || + pm_state.bq2597x.bus_ovp_fault) + return -ADC_ERR; + else if (!pm_state.bq2597x.charge_enabled) + return -CP_ENABLE_FAIL; + else if (thermal_level >= MAX_THERMAL_LEVEL || + pm_state.is_temp_out_fc2_range) { + pr_info("thermal level too high or batt temp is out of fc2 range\n"); + return CP_ENABLE_FAIL; + } else if (pm_state.slowly_charging) { + pr_info("slowly charging feature is enabled!\n"); + return CP_ENABLE_FAIL; + } + if (pm_state.bq2597x.vbat_volt > sys_config.bat_volt_lp_lmt - 100 && + pm_state.bq2597x.ibat_curr < sys_config.fc2_taper_current) { + if (fc2_taper_timer++ > TAPER_TIMEOUT) { + fc2_taper_timer = 0; + return TAPER_DONE; + } + } else { + fc2_taper_timer = 0; + } + + return 0; +} + +const unsigned char *pm_state_str[] = { + "CP_STATE_ENTRY", + "CP_STATE_DISCONNECT", + "CP_STATE_SW_ENTRY", + "CP_STATE_SW_ENTRY_2", + // "CP_STATE_SW_ENTRY_3", + "CP_STATE_SW_LOOP", + "CP_STATE_FLASH2_ENTRY", + "CP_STATE_FLASH2_ENTRY_1", + // "CP_STATE_FLASH2_ENTRY_2", + "CP_STATE_FLASH2_ENTRY_3", + // "CP_STATE_FLASH2_GET_PPS_STATUS", + "CP_STATE_FLASH2_TUNE", + "CP_STATE_FLASH2_DELAY", + "CP_STATE_STOP_CHARGE", +}; + +static void cp_move_state(pm_sm_state_t state) +{ +#if 1 + pr_debug("pm_state change:%s -> %s\n", pm_state_str[pm_state.state], + pm_state_str[state]); + pm_state.state_log[pm_state.log_idx] = pm_state.state; + pm_state.log_idx++; + pm_state.log_idx %= PM_STATE_LOG_MAX; +#endif + pm_state.state = state; +} + +void cp_statemachine(unsigned int port) +{ + int ret; + static int tune_vbus_retry, tune_vbus_count, retry_enable_bq_count; + int thermal_level = 0; + static bool recovery; + + if (!pm_state.bq2597x.vbus_pres) { + pm_state.state = CP_STATE_DISCONNECT; + recovery = true; + pr_info("vbus disconnected\n"); + } else if (pm_state.state == CP_STATE_DISCONNECT) { + pr_info("vbus connected\n"); + recovery = true; + pm_state.jeita_triggered = false; + pm_state.is_temp_out_fc2_range = false; + cp_move_state(CP_STATE_ENTRY); + } + + switch (pm_state.state) { + case CP_STATE_DISCONNECT: + if (pm_state.bq2597x.charge_enabled) { + cp_enable_fc(false); + cp_check_fc_enabled(); + } + + if (!pm_state.sw_chager.charge_enabled || + pm_state.sw_chager.charge_limited) { + cp_reset_vbus_volt(); + cp_enable_sw(true); + cp_update_sw_status(); + } + + tune_vbus_count = 0; + retry_enable_bq_count = 0; + pm_state.usb_type = 0; + pm_state.sw_fc2_init_fail = false; + pm_state.sw_near_cv = false; + sys_config.bat_curr_lp_lmt = HVDCP3_CLASS_A_BAT_CURRENT_MA; + sys_config.bus_curr_lp_lmt = HVDCP3_CLASS_A_BUS_CURRENT_MA; + pm_state.ibus_lmt_curr = HVDCP3_CLASS_A_BUS_CURRENT_MA; + sys_config.ibus_minus_deviation_val = HVDCP3_IBUS_MINUS_DEV_VAL; + sys_config.ibus_plus_deviation_val = HVDCP3_IBUS_PLUS_DEV_VAL; + sys_config.ibat_minus_deviation_val = HVDCP3_IBAT_MINUS_DEV_VAL; + sys_config.ibat_plus_deviation_val = HVDCP3_IBAT_PLUS_DEV_VAL; + pm_state.batt_cell_volt_triggered = false; + cp_set_qc_bus_protections(HVDCP3_NONE); + break; + + case CP_STATE_ENTRY: + cp_get_usb_type(); + cp_get_batt_capacity(); + qc3_get_batt_current_thermal_level(&thermal_level); + qc3_check_slowly_charging_enabled(); + pm_state.is_temp_out_fc2_range = + qc3_disable_cp_by_jeita_status(); + pr_info("is_temp_out_fc2_range:%d\n", + pm_state.is_temp_out_fc2_range); + + if (pm_state.usb_type == POWER_SUPPLY_TYPE_USB_HVDCP_3 || + pm_state.usb_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) { + pr_info("vbus_volt:%d\n", pm_state.bq2597x.vbus_volt); + cp_reset_vbus_volt(); + msleep(100); + if (thermal_level >= MAX_THERMAL_LEVEL || + pm_state.slowly_charging || + pm_state.is_temp_out_fc2_range) { + cp_move_state(CP_STATE_SW_ENTRY); + pr_info("thermal too high or batt temp out of range or slowly charging, waiting...\n"); + } else if (pm_state.bq2597x.vbat_volt < + sys_config.min_vbat_start_flash2) { + cp_move_state(CP_STATE_SW_ENTRY); + } else if (pm_state.bq2597x.vbat_volt > + sys_config.bat_volt_lp_lmt - 100 || + pm_state.capacity >= HIGH_CAPACITY_TRH) { + pm_state.sw_near_cv = true; + cp_move_state(CP_STATE_SW_ENTRY); + } else { + cp_move_state(CP_STATE_FLASH2_ENTRY); + } + } + break; + + case CP_STATE_SW_ENTRY: + cp_reset_vbus_volt(); + if (pm_state.bq2597x.charge_enabled) { + cp_enable_fc(false); + cp_check_fc_enabled(); + } + + if (!pm_state.bq2597x.charge_enabled) + cp_move_state(CP_STATE_SW_ENTRY_2); + break; + + case CP_STATE_SW_ENTRY_2: + pr_info("enable sw charger and check enable\n"); + cp_enable_sw(true); + cp_update_sw_status(); + if (pm_state.sw_chager.charge_enabled) + cp_move_state(CP_STATE_SW_LOOP); + break; + + case CP_STATE_SW_LOOP: + qc3_get_batt_current_thermal_level(&thermal_level); + if (retry_enable_bq_count >= 5) { + pr_info("retry_enable_bq_count=%d\n", + retry_enable_bq_count); + break; + } + + pm_state.is_temp_out_fc2_range = + qc3_disable_cp_by_jeita_status(); + qc3_check_slowly_charging_enabled(); + if (thermal_level < MAX_THERMAL_LEVEL && + !pm_state.slowly_charging && + !pm_state.is_temp_out_fc2_range && recovery) { + if (tune_vbus_count >= 2) { + pr_info("unsupport qc3, use sw charging\n"); + break; + } + tune_vbus_count++; + pr_info("thermal or batt temp recovery...\n"); + recovery = false; + } else { + pr_info("thermal(%d) too high or batt temp out of range\n", + thermal_level); + } + cp_get_batt_capacity(); + if (pm_state.bq2597x.vbat_volt > + sys_config.bat_volt_lp_lmt - 100 || + pm_state.capacity >= HIGH_CAPACITY_TRH) { + pm_state.sw_near_cv = true; + } else { + pr_info("capacity(%d) too high or vbat_volt(%d) too low.\n", + pm_state.capacity, pm_state.bq2597x.vbat_volt); + } + if (!pm_state.sw_near_cv && !recovery) { + if (pm_state.bq2597x.vbat_volt > + sys_config.min_vbat_start_flash2) { + pr_info("battery volt: %d is ok, proceeding to flash charging...\n", + pm_state.bq2597x.vbat_volt); + cp_move_state(CP_STATE_FLASH2_ENTRY); + } + } + break; + + case CP_STATE_FLASH2_ENTRY: + if (!pm_state.sw_chager.charge_limited) { + cp_limit_sw(true); + cp_update_sw_status(); + } + + if (pm_state.sw_chager.charge_limited) { + cp_move_state(CP_STATE_FLASH2_ENTRY_1); + tune_vbus_retry = 0; + } + + cp_get_qc_hvdcp3_type(); + if (pm_state.hvdcp3_type == HVDCP3_CLASSB_27W) { + sys_config.bat_curr_lp_lmt = + HVDCP3_CLASS_B_BAT_CURRENT_MA; + sys_config.bus_curr_lp_lmt = + HVDCP3_CLASS_B_BUS_CURRENT_MA; + pm_state.ibus_lmt_curr = sys_config.bus_curr_lp_lmt; + cp_set_qc_bus_protections(HVDCP3_CLASSB_27W); + } else if (pm_state.hvdcp3_type == HVDCP3_CLASSA_18W) { + sys_config.bat_curr_lp_lmt = + HVDCP3_CLASS_A_BAT_CURRENT_MA; + sys_config.bus_curr_lp_lmt = + HVDCP3_CLASS_A_BUS_CURRENT_MA; + pm_state.ibus_lmt_curr = sys_config.bus_curr_lp_lmt; + cp_set_qc_bus_protections(HVDCP3_CLASSA_18W); + } else if (pm_state.hvdcp3_type == + HVDCP3P5_CLASSB_27W) { // QC3.5 27W + sys_config.ibus_minus_deviation_val = + HVDCP3P5_IBUS_MINUS_DEV_VAL; + sys_config.ibus_plus_deviation_val = + HVDCP3P5_IBUS_PLUS_DEV_VAL; + sys_config.ibat_minus_deviation_val = + HVDCP3P5_IBAT_MINUS_DEV_VAL; + sys_config.ibat_plus_deviation_val = + HVDCP3P5_IBAT_PLUS_DEV_VAL; + sys_config.bat_curr_lp_lmt = + HVDCP3P5_CLASS_B_BAT_CURRENT_MA; + sys_config.bus_curr_lp_lmt = + HVDCP3P5_CLASS_B_BUS_CURRENT_MA; + pm_state.ibus_lmt_curr = sys_config.bus_curr_lp_lmt; + cp_set_qc_bus_protections(HVDCP3P5_CLASSB_27W); + } else if (pm_state.hvdcp3_type == + HVDCP3P5_CLASSA_18W) { // QC3.5 18W + sys_config.ibus_minus_deviation_val = + HVDCP3P5_IBUS_MINUS_DEV_VAL; + sys_config.ibus_plus_deviation_val = + HVDCP3P5_IBUS_PLUS_DEV_VAL; + sys_config.ibat_minus_deviation_val = + HVDCP3P5_IBAT_MINUS_DEV_VAL; + sys_config.ibat_plus_deviation_val = + HVDCP3P5_IBAT_PLUS_DEV_VAL; + sys_config.bat_curr_lp_lmt = + HVDCP3P5_CLASS_A_BAT_CURRENT_MA; + sys_config.bus_curr_lp_lmt = + HVDCP3P5_CLASS_A_BUS_CURRENT_MA; + pm_state.ibus_lmt_curr = sys_config.bus_curr_lp_lmt; + cp_set_qc_bus_protections(HVDCP3P5_CLASSA_18W); + } else { + cp_set_qc_bus_protections(HVDCP3_NONE); + } + break; + + case CP_STATE_FLASH2_ENTRY_1: + cp_update_fc_status(); + if (sys_config.qc3p5_supported) { + if (pm_state.bq2597x.bus_error_status == + VBUS_ERROR_LOW || + pm_state.bq2597x.vbus_volt < + (pm_state.bq2597x.vbat_volt * 2 + + VBUS_COMP)) { + tune_vbus_retry = cp_get_qc_pulse_cnt(); + tune_vbus_retry++; + cp_tune_vbus_volt(VOLT_UP); + pr_info("vbus:%d, retry_times:%d, tuning...\n", + pm_state.bq2597x.vbus_volt, + tune_vbus_retry); + } else { + pr_err("vbus:%d, tuned above expected voltage, retry_times:%d\n", + pm_state.bq2597x.vbus_volt, + tune_vbus_retry); + cp_move_state(CP_STATE_FLASH2_ENTRY_3); + break; + } + if ((pm_state.usb_type == + POWER_SUPPLY_TYPE_USB_HVDCP_3 && + tune_vbus_retry > MAX_PLUSE_COUNT_ALLOWED) || + (pm_state.usb_type == + POWER_SUPPLY_TYPE_USB_HVDCP_3P5 && + tune_vbus_retry > + MAX_HVDCP3P5_PLUSE_COUNT_ALLOWED)) { + pr_err("Failed to tune adapter volt into valid range, charge with switching charger\n"); + pm_state.sw_fc2_init_fail = true; + cp_move_state(CP_STATE_SW_ENTRY); + } + break; + + } else { + if (pm_state.bq2597x.vbus_volt < + (pm_state.bq2597x.vbat_volt * 2 + BUS_VOLT_INIT_UP - + 50)) { + tune_vbus_retry++; + cp_tune_vbus_volt(VOLT_UP); + } else { + pr_err("voltage tuned above expected voltage, retry %d times\n", + tune_vbus_retry); + cp_move_state(CP_STATE_FLASH2_ENTRY_3); + break; + } + + if (tune_vbus_retry > 23) { + pr_err("Failed to tune adapter volt into valid range, charge with switching charger\n"); + pm_state.sw_fc2_init_fail = true; + cp_move_state(CP_STATE_SW_ENTRY); + } + break; + } + + case CP_STATE_FLASH2_ENTRY_3: + if (sys_config.qc3p5_supported) { + if (pm_state.bq2597x.bus_error_status == + VBUS_ERROR_HIGH || + pm_state.bq2597x.vbus_volt > + (pm_state.bq2597x.vbat_volt * 2 + + BUS_VOLT_INIT_UP + 200)) { + pr_err("vbus=%d, too high to open cp switcher, decrease it.\n", + pm_state.bq2597x.vbus_volt); + cp_tune_vbus_volt(VOLT_DOWN); + } else if (pm_state.bq2597x.bus_error_status == + VBUS_ERROR_LOW) { + pr_err("vbus=%d, too low to open cp switcher, increase it.\n", + pm_state.bq2597x.vbus_volt); + cp_tune_vbus_volt(VOLT_UP); + } else { + pr_err("vbat volt is ok, enable flash charging\n"); + if (!pm_state.bq2597x.charge_enabled) { + cp_enable_fc(true); + cp_check_fc_enabled(); + if (pm_state.bq2597x.charge_enabled) { + if (retry_enable_bq_count > 0) + retry_enable_bq_count = + 0; + cp_move_state( + CP_STATE_FLASH2_TUNE); + cp_enable_sw(false); + cp_update_sw_status(); + } else { + retry_enable_bq_count++; + if (retry_enable_bq_count < 5) + cp_move_state( + CP_STATE_FLASH2_ENTRY_3); + else + cp_move_state( + CP_STATE_SW_ENTRY); + } + } + ibus_lmt_change_timer = 0; + fc2_taper_timer = 0; + } + break; + } else { + if (pm_state.bq2597x.vbus_volt > + (pm_state.bq2597x.vbat_volt * 2 + BUS_VOLT_INIT_UP + + 200)) { + pr_err("vbat volt is too high, wait it down\n"); + /* voltage is too high, wait for voltage down, keep charge disabled to discharge */ + } else { + pr_err("vbat volt is ok, enable flash charging\n"); + if (!pm_state.bq2597x.charge_enabled) { + cp_enable_fc(true); + cp_check_fc_enabled(); + if (pm_state.bq2597x.charge_enabled) { + if (retry_enable_bq_count > 0) + retry_enable_bq_count = + 0; + cp_move_state( + CP_STATE_FLASH2_TUNE); + cp_enable_sw(false); + cp_update_sw_status(); + } else { + retry_enable_bq_count++; + if (retry_enable_bq_count < 5) + cp_move_state( + CP_STATE_FLASH2_ENTRY_3); + else + cp_move_state( + CP_STATE_SW_ENTRY); + } + } + ibus_lmt_change_timer = 0; + fc2_taper_timer = 0; + } + break; + } + + case CP_STATE_FLASH2_TUNE: + ret = cp_flash2_charge(port); + if (ret == -ADC_ERR) { + pr_err("Move to stop charging:%d\n", ret); + cp_move_state(CP_STATE_STOP_CHARGE); + break; + } else if (ret == -CP_ENABLE_FAIL || ret == TAPER_DONE) { + pr_err("Move to switch charging:%d\n", ret); + cp_move_state(CP_STATE_SW_ENTRY); + break; + } else if (ret == CP_ENABLE_FAIL) { + tune_vbus_count = 0; + pr_err("Move to switch charging, will try to recover to flash charging:%d\n", + ret); + recovery = true; + cp_move_state(CP_STATE_SW_ENTRY); + } else { // normal tune adapter output + cp_move_state(CP_STATE_FLASH2_DELAY); + } + break; + + case CP_STATE_FLASH2_DELAY: + cp_move_state(CP_STATE_FLASH2_TUNE); + break; + + case CP_STATE_STOP_CHARGE: + pr_err("Stop charging\n"); + if (pm_state.bq2597x.charge_enabled) { + cp_enable_fc(false); + cp_check_fc_enabled(); + } + if (pm_state.sw_chager.charge_enabled) { + cp_enable_sw(false); + cp_update_sw_status(); + } + break; + + default: + pr_err("No state defined! Move to stop charging\n"); + cp_move_state(CP_STATE_STOP_CHARGE); + break; + } +} + +static void cp_workfunc(struct work_struct *work) +{ + cp_get_usb_type(); + + cp_update_sw_status(); + cp_update_fc_status(); + + cp_statemachine(0); + + cp_get_usb_present(); + pr_info("pm_state.usb_present: %d\n", pm_state.usb_present); + /* check whether usb is present */ + if (pm_state.usb_present == 0) { + cp_set_qc_bus_protections(HVDCP3_NONE); +#ifdef CONFIG_CHARGER_LN8000 + pm_state.state = CP_STATE_DISCONNECT; +#endif + return; + } + + if (pm_state.usb_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) { + schedule_delayed_work(&pm_state.qc3_pm_work, HZ); + } else if (pm_state.usb_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) { + schedule_delayed_work(&pm_state.qc3_pm_work, + msecs_to_jiffies(PM_WORK_TIME_100MS)); + } +} + +static int cp_qc30_notifier_call(struct notifier_block *nb, unsigned long ev, + void *v) +{ + struct power_supply *psy = v; + static bool usb_hvdcp3_on; + if (ev != PSY_EVENT_PROP_CHANGED) + return NOTIFY_OK; + + if (strcmp(psy->desc->name, "usb") == 0) { + cp_get_usb_type(); + if (pm_state.usb_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) { + if (!usb_hvdcp3_on) { + schedule_delayed_work(&pm_state.qc3_pm_work, + 3 * HZ); + usb_hvdcp3_on = true; + } else { + schedule_delayed_work(&pm_state.qc3_pm_work, + msecs_to_jiffies(300)); + } + } else if (sys_config.qc3p5_supported && + pm_state.usb_type == + POWER_SUPPLY_TYPE_USB_HVDCP_3P5) { + if (!usb_hvdcp3_on) { + schedule_delayed_work(&pm_state.qc3_pm_work, + HZ); + usb_hvdcp3_on = true; + } else { + schedule_delayed_work(&pm_state.qc3_pm_work, + msecs_to_jiffies(100)); + } + } else if (pm_state.usb_type == POWER_SUPPLY_TYPE_UNKNOWN && + usb_hvdcp3_on == true) { + cancel_delayed_work(&pm_state.qc3_pm_work); + schedule_delayed_work(&pm_state.qc3_pm_work, 0); + pr_info("pm_state.usb_type: %d\n", pm_state.usb_type); + usb_hvdcp3_on = false; + } + } + + return NOTIFY_OK; +} + +static int cp_qc30_register_notifier(struct cp_qc30_data *chip) +{ + int rc; + + chip->nb.notifier_call = cp_qc30_notifier_call; + rc = power_supply_reg_notifier(&chip->nb); + if (rc < 0) { + pr_err("Couldn't register psy notifier rc = %d\n", rc); + return rc; + } + + return 0; +} + +static int cp_qc30_parse_dt(struct cp_qc30_data *chip) +{ + struct device_node *node = chip->dev->of_node; + int rc = 0; + + if (!node) { + pr_err("device tree node missing\n"); + return -EINVAL; + } + + rc = of_property_read_u32(node, "mi,qc3-bat-volt-max", + &chip->bat_volt_max); + if (rc < 0) + pr_err("qc3-bat-volt-max property missing, use default val\n"); + else + sys_config.bat_volt_lp_lmt = chip->bat_volt_max; + + rc = of_property_read_u32(node, "mi,qc3-ffc-bat-volt-max", + &chip->ffc_bat_volt_max); + if (rc < 0) + pr_err("qc3-ffc-bat-volt-max property missing, use default\n"); + else + sys_config.ffc_bat_volt_lmt = chip->ffc_bat_volt_max; + + rc = of_property_read_u32(node, "mi,qc3-bat-curr-max", + &chip->bat_curr_max); + if (rc < 0) + pr_err("qc3-bat-curr-max property missing, use default val\n"); + else + sys_config.bat_curr_lp_lmt = chip->bat_curr_max; + + rc = of_property_read_u32(node, "mi,qc3-bus-volt-max", + &chip->bus_volt_max); + if (rc < 0) + pr_err("qc3-bus-volt-max property missing, use default val\n"); + else + sys_config.bus_volt_lp_lmt = chip->bus_volt_max; + + rc = of_property_read_u32(node, "mi,qc3-bus-curr-max", + &chip->bus_curr_max); + if (rc < 0) + pr_err("qc3-bus-curr-max property missing, use default val\n"); + else + sys_config.bus_curr_lp_lmt = chip->bus_curr_max; + + chip->qc3p5_supported = + of_property_read_bool(node, "mi,support-qc3p5-without-smb"); + sys_config.qc3p5_supported = chip->qc3p5_supported; + + chip->cp_sec_enable = of_property_read_bool(node, "mi,cp-sec-enable"); + + sys_config.cp_sec_enable = chip->cp_sec_enable; + + return rc; +} + +static int cp_qc30_probe(struct platform_device *pdev) +{ + int ret = 0; + struct device *dev = &pdev->dev; + struct cp_qc30_data *chip; + + pr_info("%s enter\n", __func__); + + chip = devm_kzalloc(dev, sizeof(struct cp_qc30_data), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->dev = dev; + ret = cp_qc30_parse_dt(chip); + if (ret < 0) { + pr_err("Couldn't parse device tree rc=%d\n", ret); + return ret; + } + + platform_set_drvdata(pdev, chip); + + pm_state.state = CP_STATE_DISCONNECT; + pm_state.usb_type = POWER_SUPPLY_TYPE_UNKNOWN; + pm_state.ibus_lmt_curr = sys_config.bus_curr_lp_lmt; + + INIT_DELAYED_WORK(&pm_state.qc3_pm_work, cp_workfunc); + + cp_qc30_register_notifier(chip); + + pr_info("charge pump qc3 probe\n"); + + return ret; +} + +static int cp_qc30_remove(struct platform_device *pdev) +{ + cancel_delayed_work(&pm_state.qc3_pm_work); + return 0; +} + +static const struct of_device_id cp_qc30_of_match[] = { + { + .compatible = "xiaomi,cp-qc30", + }, + {}, +}; + +static struct platform_driver cp_qc30_driver = { + .driver = { + .name = "cp-qc30", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(cp_qc30_of_match), + }, + .probe = cp_qc30_probe, + .remove = cp_qc30_remove, +}; + +static int __init cp_qc30_init(void) +{ + return platform_driver_register(&cp_qc30_driver); +} + +late_initcall(cp_qc30_init); + +static void __exit cp_qc30_exit(void) +{ + return platform_driver_unregister(&cp_qc30_driver); +} +module_exit(cp_qc30_exit); + +MODULE_AUTHOR("Fei Jiang"); +MODULE_DESCRIPTION("Xiaomi cp qc30"); +MODULE_LICENSE("GPL"); diff --git a/drivers/power/supply/ti/cp_qc30.h b/drivers/power/supply/ti/cp_qc30.h new file mode 100644 index 000000000000..660c1f6e76dc --- /dev/null +++ b/drivers/power/supply/ti/cp_qc30.h @@ -0,0 +1,251 @@ +/* + * cp_qc30.h + * + */ + +#ifndef SRC_PDLIB_USB_PD_POLICY_MANAGER_H_ +#define SRC_PDLIB_USB_PD_POLICY_MANAGER_H_ +#include +#include +#include + +typedef enum { + CP_STATE_ENTRY, + CP_STATE_DISCONNECT, + CP_STATE_SW_ENTRY, + CP_STATE_SW_ENTRY_2, + // CP_STATE_SW_ENTRY_3, + CP_STATE_SW_LOOP, + CP_STATE_FLASH2_ENTRY, + CP_STATE_FLASH2_ENTRY_1, + // CP_STATE_FLASH2_ENTRY_2, + CP_STATE_FLASH2_ENTRY_3, + // CP_STATE_FLASH2_GET_PPS_STATUS, + CP_STATE_FLASH2_TUNE, + CP_STATE_FLASH2_DELAY, + CP_STATE_STOP_CHARGE, +} pm_sm_state_t; + +#define BAT_OVP_FAULT_SHIFT 0 +#define BAT_OCP_FAULT_SHIFT 1 +#define BUS_OVP_FAULT_SHIFT 2 +#define BUS_OCP_FAULT_SHIFT 3 +#define BAT_THERM_FAULT_SHIFT 4 +#define BUS_THERM_FAULT_SHIFT 5 +#define DIE_THERM_FAULT_SHIFT 6 + +#define BAT_OVP_FAULT_MASK (1 << BAT_OVP_FAULT_SHIFT) +#define BAT_OCP_FAULT_MASK (1 << BAT_OCP_FAULT_SHIFT) +#define BUS_OVP_FAULT_MASK (1 << BUS_OVP_FAULT_SHIFT) +#define BUS_OCP_FAULT_MASK (1 << BUS_OCP_FAULT_SHIFT) +#define BAT_THERM_FAULT_MASK (1 << BAT_THERM_FAULT_SHIFT) +#define BUS_THERM_FAULT_MASK (1 << BUS_THERM_FAULT_SHIFT) +#define DIE_THERM_FAULT_MASK (1 << DIE_THERM_FAULT_SHIFT) + +#define BAT_OVP_ALARM_SHIFT 0 +#define BAT_OCP_ALARM_SHIFT 1 +#define BUS_OVP_ALARM_SHIFT 2 +#define BUS_OCP_ALARM_SHIFT 3 +#define BAT_THERM_ALARM_SHIFT 4 +#define BUS_THERM_ALARM_SHIFT 5 +#define DIE_THERM_ALARM_SHIFT 6 +#define BAT_UCP_ALARM_SHIFT 7 + +#define BAT_OVP_ALARM_MASK (1 << BAT_OVP_ALARM_SHIFT) +#define BAT_OCP_ALARM_MASK (1 << BAT_OCP_ALARM_SHIFT) +#define BUS_OVP_ALARM_MASK (1 << BUS_OVP_ALARM_SHIFT) +#define BUS_OCP_ALARM_MASK (1 << BUS_OCP_ALARM_SHIFT) +#define BAT_THERM_ALARM_MASK (1 << BAT_THERM_ALARM_SHIFT) +#define BUS_THERM_ALARM_MASK (1 << BUS_THERM_ALARM_SHIFT) +#define DIE_THERM_ALARM_MASK (1 << DIE_THERM_ALARM_SHIFT) +#define BAT_UCP_ALARM_MASK (1 << BAT_UCP_ALARM_SHIFT) + +#define VBAT_REG_STATUS_SHIFT 0 +#define IBAT_REG_STATUS_SHIFT 1 + +#define VBAT_REG_STATUS_MASK (1 << VBAT_REG_STATUS_SHIFT) +#define IBAT_REG_STATUS_MASK (1 << VBAT_REG_STATUS_SHIFT) + +enum hvdcp3_type { + HVDCP3_NONE = 0, + HVDCP3_CLASSA_18W, + HVDCP3_CLASSB_27W, + HVDCP3P5_CLASSA_18W, + HVDCP3P5_CLASSB_27W, +}; + +#define HVDCP3_CLASS_B_BAT_CURRENT_MA 5400 +#define HVDCP3_CLASS_B_BUS_CURRENT_MA 2700 +#define HVDCP3_CLASS_A_BAT_CURRENT_MA 3600 +#define HVDCP3_CLASS_A_BUS_CURRENT_MA 2100 +#define MAX_PLUSE_COUNT_ALLOWED 23 +#define HVDCP3_IBUS_MINUS_DEV_VAL 550 +#define HVDCP3_IBUS_PLUS_DEV_VAL 200 +#define HVDCP3_IBAT_MINUS_DEV_VAL 600 +#define HVDCP3_IBAT_PLUS_DEV_VAL 500 + +/* QC3.5 */ +#define HVDCP3P5_CLASS_B_BAT_CURRENT_MA 5400 +#define HVDCP3P5_CLASS_B_BUS_CURRENT_MA 2700 +#define HVDCP3P5_CLASS_A_BAT_CURRENT_MA 4200 +#define HVDCP3P5_CLASS_A_BUS_CURRENT_MA 2100 +#define MAX_HVDCP3P5_PLUSE_COUNT_ALLOWED 300 +#define HVDCP3P5_IBUS_MINUS_DEV_VAL 200 +#define HVDCP3P5_IBUS_PLUS_DEV_VAL 150 +#define HVDCP3P5_IBAT_MINUS_DEV_VAL 300 +#define HVDCP3P5_IBAT_PLUS_DEV_VAL 200 + +#define MAX_THERMAL_LEVEL 13 +/* jeita related */ +#define JEITA_WARM_THR 450 +#define JEITA_COOL_NOT_ALLOW_CP_THR 100 +/* + * add hysteresis for warm threshold to avoid flash + * charge and normal charge switch frequently at + * the warm threshold + */ +#define JEITA_HYSTERESIS 20 + +#define HIGH_CAPACITY_TRH 90 +#define PM_WORK_TIME_100MS 100 + +struct flash2_policy { + int down_steps; + uint16_t volt_hysteresis; +}; + +#if 0 +struct bq2597x_cfg { + uint16_t bat_ovp_th; + uint16_t bat_ocp_th; + uint16_t bus_ovp_th; + uint16_t bus_ocp_th; + + + uint16_t bat_ucp_alarm_th; + + uint16_t bat_ovp_alarm_th; + uint16_t bat_ocp_alarm_th; + uint16_t bus_ovp_alarm_th; + uint16_t bus_ocp_alarm_th; + + uint16_t ac_ovp_th; + uint16_t ts_bus_fault_th; + uint16_t ts_bat_fault_th; + uint16_t ts_die_fault_th; + + /* software protection threshold*/ + int32_t sw_bat_ovp_th; + int32_t sw_bat_ocp_th; + int32_t sw_bus_ovp_th; + int32_t sw_bus_ocp_th; + int32_t sw_bat_ucp_th; + int32_t taper_current; +}; +#endif + +struct bq2597x { + bool charge_enabled; + + bool batt_pres; + bool vbus_pres; + + /* alarm/fault status */ + bool bat_ovp_fault; + bool bat_ocp_fault; + bool bus_ovp_fault; + bool bus_ocp_fault; + + bool bat_ovp_alarm; + bool bat_ocp_alarm; + bool bus_ovp_alarm; + bool bus_ocp_alarm; + + bool bat_ucp_alarm; + + bool bat_therm_alarm; + bool bus_therm_alarm; + bool die_therm_alarm; + + bool bat_therm_fault; + bool bus_therm_fault; + bool die_therm_fault; + + bool therm_shutdown_flag; + bool therm_shutdown_stat; + + bool vbat_reg; + bool ibat_reg; + + int vout_volt; + int vbat_volt; + int vbus_volt; + int ibat_curr; + int ibus_curr; + + int bat_temp; + int bus_temp; + int die_temp; + int bus_error_status; +}; + +struct sw_charger { + bool charge_enabled; + bool charge_limited; +}; + +#define PM_STATE_LOG_MAX 32 +typedef struct { + bool sw_is_charging; + bool flash2_is_charging; + bool sw_near_cv; + bool sw_fc2_init_fail; + bool bms_fastcharge_mode; + + uint16_t ibus_lmt_curr; + pm_sm_state_t state; //state machine + pm_sm_state_t state_log[PM_STATE_LOG_MAX]; + uint8_t log_idx; + + int usb_type; + int hvdcp3_type; + int usb_present; + int ibat_now; + int capacity; + struct bq2597x bq2597x; + struct sw_charger sw_chager; + struct votable *fcc_votable; + + struct power_supply *fc_psy; + struct power_supply *sw_psy; + struct power_supply *usb_psy; + struct power_supply *bms_psy; + /* jeita or thermal related */ + bool jeita_triggered; + bool batt_cell_volt_triggered; + bool is_temp_out_fc2_range; + bool slowly_charging; + + struct delayed_work qc3_pm_work; +} pm_t; + +struct sys_config { + uint16_t bat_volt_lp_lmt; /*bat volt loop limit*/ + uint16_t ffc_bat_volt_lmt; + uint16_t bat_curr_lp_lmt; + uint16_t bus_volt_lp_lmt; + uint16_t bus_curr_lp_lmt; + uint16_t ibus_plus_deviation_val; + uint16_t ibus_minus_deviation_val; + uint16_t ibat_plus_deviation_val; + uint16_t ibat_minus_deviation_val; + int32_t fc2_taper_current; + + struct flash2_policy flash2_policy; + + uint16_t min_vbat_start_flash2; + bool cp_sec_enable; + bool qc3p5_supported; +}; + +#endif /* SRC_PDLIB_USB_PD_POLICY_MANAGER_H_ */ diff --git a/drivers/power/supply/ti/ln8000_charger.c b/drivers/power/supply/ti/ln8000_charger.c new file mode 100644 index 000000000000..7ecf5e0626f0 --- /dev/null +++ b/drivers/power/supply/ti/ln8000_charger.c @@ -0,0 +1,1826 @@ +/* + * ln8000-charger.c - Charger driver for LIONSEMI LN8000 + * + * Copyright (C) 2021 Lion Semiconductor Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include "ln8000_charger.h" +#include "cp_qc30.h" + +#define ln_err(fmt, ...) \ + do { \ + if (info->dev_role == LN_PRIMARY) \ + printk(KERN_ERR "ln8000@pri: %s: " fmt, __func__, \ + ##__VA_ARGS__); \ + else \ + printk(KERN_ERR "ln8000@sec: %s: " fmt, __func__, \ + ##__VA_ARGS__); \ + } while (0); + +#define ln_info(fmt, ...) \ + do { \ + if (info->dev_role == LN_PRIMARY) \ + printk(KERN_INFO "ln8000@pri: %s: " fmt, __func__, \ + ##__VA_ARGS__); \ + else \ + printk(KERN_INFO "ln8000@sec: %s: " fmt, __func__, \ + ##__VA_ARGS__); \ + } while (0); + +#define ln_dbg(fmt, ...) \ + do { \ + if (info->dev_role == LN_PRIMARY) \ + printk(KERN_DEBUG "ln8000@pri: %s: " fmt, __func__, \ + ##__VA_ARGS__); \ + else \ + printk(KERN_DEBUG "ln8000@sec: %s: " fmt, __func__, \ + ##__VA_ARGS__); \ + } while (0); + +#define LN8000_REG_PRINT(reg_addr, val) \ + do { \ + ln_info(" --> [%-20s] 0x%02X : 0x%02X\n", #reg_addr, \ + LN8000_REG_##reg_addr, (val) & 0xFF); \ + } while (0); + +#define LN8000_PARSE_PROP(ret, pdata, field, prop, default_prop) \ + do { \ + if (ret) { \ + ln_info("%s = %d (set to default)\n", #field, \ + default_prop); \ + pdata->field = default_prop; \ + } else { \ + ln_info("%s = %d\n", #field, prop); \ + pdata->field = prop; \ + } \ + } while (0); + +#define LN8000_BIT_CHECK(val, idx, desc) \ + if (val & (1 << idx)) \ + ln_info("-> %s\n", desc) +#define LN8000_IS_PRIMARY(info) (info->dev_role == LN_PRIMARY) +#define LN8000_ROLE(info) (LN8000_IS_PRIMARY(info) ? "prim" : "sec ") +#define LN8000_USE_GPIO(pdata) \ + ((pdata != NULL) && (!IS_ERR_OR_NULL(pdata->irq_gpio))) +#define LN8000_STATUS(val, mask) ((val & mask) ? true : false) + +/** + * I2C control functions : when occurred I2C tranfer fault, we + * will retry to it. (default count:3) + */ +#define I2C_RETRY_CNT 3 +static int ln8000_read_reg(struct ln8000_info *info, u8 addr, void *data) +{ + int i, ret = 0; + + mutex_lock(&info->i2c_lock); + for (i = 0; i < I2C_RETRY_CNT; ++i) { + ret = regmap_read(info->regmap, addr, data); + if (IS_ERR_VALUE((unsigned long)ret)) { + ln_info("failed-read, reg(0x%02X), ret(%d)\n", addr, + ret); + } else { + break; + } + } + mutex_unlock(&info->i2c_lock); + return ret; +} + +static int ln8000_bulk_read_reg(struct ln8000_info *info, u8 addr, void *data, + int count) +{ + int i, ret = 0; + + mutex_lock(&info->i2c_lock); + for (i = 0; i < I2C_RETRY_CNT; ++i) { + ret = regmap_bulk_read(info->regmap, addr, data, count); + if (IS_ERR_VALUE((unsigned long)ret)) { + ln_info("failed-bulk-read, reg(0x%02X, %d bytes), ret(%d)\n", + addr, count, ret); + } else { + break; + } + } + mutex_unlock(&info->i2c_lock); + return ret; +} + +static int ln8000_write_reg(struct ln8000_info *info, u8 addr, u8 data) +{ + int i, ret = 0; + + mutex_lock(&info->i2c_lock); + for (i = 0; i < I2C_RETRY_CNT; ++i) { + ret = regmap_write(info->regmap, addr, data); + if (IS_ERR_VALUE((unsigned long)ret)) { + ln_info("failed-write, reg(0x%02X), ret(%d)\n", addr, + ret); + } else { + break; + } + } + mutex_unlock(&info->i2c_lock); + return ret; +} + +static int ln8000_update_reg(struct ln8000_info *info, u8 addr, u8 mask, + u8 data) +{ + int i, ret = 0; + + mutex_lock(&info->i2c_lock); + for (i = 0; i < I2C_RETRY_CNT; ++i) { + ret = regmap_update_bits(info->regmap, addr, mask, data); + if (IS_ERR_VALUE((unsigned long)ret)) { + ln_info("failed-update, reg(0x%02X), ret(%d)\n", addr, + ret); + } else { + break; + } + } + mutex_unlock(&info->i2c_lock); + return ret; +} + +/** + * Register control functions + */ +#if 0 +static int ln8000_set_sw_freq(struct ln8000_info *info, unsigned int cfg) +{ + return ln8000_update_reg(info, LN8000_REG_SYS_CTRL, 0xF << 4, cfg << 4); +} +#endif + +static int ln8000_set_vac_ovp(struct ln8000_info *info, unsigned int ovp_th) +{ + u8 cfg; + + if (ovp_th <= 6500000) { + cfg = LN8000_VAC_OVP_6P5V; + } else if (ovp_th <= 11000000) { + cfg = LN8000_VAC_OVP_11V; + } else if (ovp_th <= 12000000) { + cfg = LN8000_VAC_OVP_12V; + } else { + cfg = LN8000_VAC_OVP_13V; + } + + return ln8000_update_reg(info, LN8000_REG_GLITCH_CTRL, 0x3 << 2, + cfg << 2); +} + +/* battery float voltage */ +static int ln8000_set_vbat_float(struct ln8000_info *info, unsigned int cfg) +{ + u8 val; + + if (cfg < LN8000_VBAT_FLOAT_MIN) + val = 0x00; + else if (cfg > LN8000_VBAT_FLOAT_MAX) + val = 0xFF; + else + val = (cfg - LN8000_VBAT_FLOAT_MIN) / LN8000_VBAT_FLOAT_LSB; + + return ln8000_write_reg(info, LN8000_REG_V_FLOAT_CTRL, val); +} + +static int ln8000_set_iin_limit(struct ln8000_info *info, unsigned int cfg) +{ + u8 val = cfg / LN8000_IIN_CFG_LSB; + + ln_info("iin_limit=%dmV(iin_ctrl=0x%x)\n", cfg / 1000, val); + + return ln8000_update_reg(info, LN8000_REG_IIN_CTRL, 0x7F, val); +} + +static int ln8000_set_ntc_alarm(struct ln8000_info *info, unsigned int cfg) +{ + int ret; + + /* update lower bits */ + ret = ln8000_write_reg(info, LN8000_REG_NTC_CTRL, (cfg & 0xFF)); + if (ret < 0) + return ret; + + /* update upper bits */ + ret = ln8000_update_reg(info, LN8000_REG_ADC_CTRL, 0x3, (cfg >> 8)); + return ret; +} + +/* battery voltage OV protection */ +static int ln8000_enable_vbat_ovp(struct ln8000_info *info, bool enable) +{ + u8 val; + + val = (enable) ? 0 : 1; //disable + val <<= LN8000_BIT_DISABLE_VBAT_OV; + + return ln8000_update_reg(info, LN8000_REG_FAULT_CTRL, + BIT(LN8000_BIT_DISABLE_VBAT_OV), val); +} + +static int ln8000_enable_vbat_regulation(struct ln8000_info *info, bool enable) +{ + return ln8000_update_reg(info, LN8000_REG_REGULATION_CTRL, + 0x1 << LN8000_BIT_DISABLE_VFLOAT_LOOP, + !(enable) << LN8000_BIT_DISABLE_VFLOAT_LOOP); +} + +static int ln8000_enable_vbat_loop_int(struct ln8000_info *info, bool enable) +{ + return ln8000_update_reg(info, LN8000_REG_REGULATION_CTRL, + 0x1 << LN8000_BIT_ENABLE_VFLOAT_LOOP_INT, + enable << LN8000_BIT_ENABLE_VFLOAT_LOOP_INT); +} + +/* input current OC protection */ +static int ln8000_enable_iin_ocp(struct ln8000_info *info, bool enable) +{ + return ln8000_update_reg(info, LN8000_REG_FAULT_CTRL, + 0x1 << LN8000_BIT_DISABLE_IIN_OCP, + !(enable) << LN8000_BIT_DISABLE_IIN_OCP); +} + +static int ln8000_enable_iin_regulation(struct ln8000_info *info, bool enable) +{ + return ln8000_update_reg(info, LN8000_REG_REGULATION_CTRL, + 0x1 << LN8000_BIT_DISABLE_IIN_LOOP, + !(enable) << LN8000_BIT_DISABLE_IIN_LOOP); +} + +static int ln8000_enable_iin_loop_int(struct ln8000_info *info, bool enable) +{ + return ln8000_update_reg(info, LN8000_REG_REGULATION_CTRL, + 0x1 << LN8000_BIT_ENABLE_IIN_LOOP_INT, + enable << LN8000_BIT_ENABLE_IIN_LOOP_INT); +} + +static int ln8000_enable_vac_ov(struct ln8000_info *info, bool enable) +{ + return ln8000_update_reg(info, LN8000_REG_FAULT_CTRL, + 0x1 << LN8000_BIT_DISABLE_VAC_OV, + !(enable) << LN8000_BIT_DISABLE_VAC_OV); +} + +static int ln8000_enable_tdie_prot(struct ln8000_info *info, bool enable) +{ + return ln8000_update_reg(info, LN8000_REG_REGULATION_CTRL, + 0x1 << LN8000_BIT_TEMP_MAX_EN, + enable << LN8000_BIT_TEMP_MAX_EN); +} + +static int ln8000_enable_tdie_regulation(struct ln8000_info *info, bool enable) +{ + return ln8000_update_reg(info, LN8000_REG_REGULATION_CTRL, + 0x1 << LN8000_BIT_TEMP_REG_EN, + enable << LN8000_BIT_TEMP_REG_EN); +} + +/* ADC channel enable */ +static int ln8000_set_adc_ch(struct ln8000_info *info, unsigned int ch, + bool enable) +{ + u8 mask; + u8 val; + int ret; + + if ((ch > LN8000_ADC_CH_ALL) || (ch < 1)) + return -EINVAL; + + if (ch == LN8000_ADC_CH_ALL) { + // update all channels + val = (enable) ? 0x3E : 0x00; + ret = ln8000_write_reg(info, LN8000_REG_ADC_CFG, val); + } else { + // update selected channel + mask = 1 << (ch - 1); + val = (enable) ? 1 : 0; + val <<= (ch - 1); + ret = ln8000_update_reg(info, LN8000_REG_ADC_CFG, mask, val); + } + + return ret; +} + +/* BUS temperature monitoring (protection+alarm) */ +static int ln8000_enable_tbus_monitor(struct ln8000_info *info, bool enable) +{ + int ret; + + /* enable BUS monitoring */ + ret = ln8000_update_reg(info, LN8000_REG_RECOVERY_CTRL, 0x1 << 1, + enable << 1); + if (ret < 0) + return ret; + + /* enable BUS ADC channel */ + if (enable) { + ret = ln8000_set_adc_ch(info, LN8000_ADC_CH_TSBUS, true); + } + return ret; +} + +/* BAT temperature monitoring (protection+alarm) */ +static int ln8000_enable_tbat_monitor(struct ln8000_info *info, bool enable) +{ + int ret; + + /* enable BAT monitoring */ + ret = ln8000_update_reg(info, LN8000_REG_RECOVERY_CTRL, 0x1 << 0, + enable << 0); + if (ret < 0) + return ret; + + /* enable BAT ADC channel */ + if (enable) { + ret = ln8000_set_adc_ch(info, LN8000_ADC_CH_TSBAT, true); + } + return ret; +} + +/* watchdog timer */ +static int ln8000_enable_wdt(struct ln8000_info *info, bool enable) +{ + return ln8000_update_reg(info, LN8000_REG_TIMER_CTRL, 0x1 << 7, + enable << 7); +} + +#if 0 +static int ln8000_set_wdt(struct ln8000_info *info, unsigned int cfg) +{ + if (cfg >= LN8000_WATCHDOG_MAX) { + cfg = LN8000_WATCHDOG_40SEC; + } + + return ln8000_update_reg(info, LN8000_REG_TIMER_CTRL, 0x3 << 5, cfg << 5); +} +#endif + +/* unplug / reverse-current detection */ +static int ln8000_enable_rcp(struct ln8000_info *info, bool enable) +{ + info->rcp_en = enable; + + return ln8000_update_reg(info, LN8000_REG_SYS_CTRL, + BIT(LN8000_BIT_REV_IIN_DET), + enable << LN8000_BIT_REV_IIN_DET); +} + +/* auto-recovery */ +static int ln8000_enable_auto_recovery(struct ln8000_info *info, bool enable) +{ + return ln8000_update_reg(info, LN8000_REG_RECOVERY_CTRL, 0xF << 4, + ((0xF << 4) * enable)); +} + +static int ln8000_set_adc_mode(struct ln8000_info *info, unsigned int cfg) +{ + return ln8000_update_reg(info, LN8000_REG_ADC_CTRL, 0x7 << 5, cfg << 5); +} + +static int ln8000_set_adc_hib_delay(struct ln8000_info *info, unsigned int cfg) +{ + return ln8000_update_reg(info, LN8000_REG_ADC_CTRL, 0x3 << 3, cfg << 3); +} + +/* check if device has been initialized (by SW) */ +#if defined(LN8000_DUAL_CONFIG) +static bool ln8000_is_sw_init(struct ln8000_info *info) +{ + u32 val; + + ln8000_read_reg(info, LN8000_REG_CHARGE_CTRL, &val); + + return (val >> 7); +} +#endif + +/* grab programmed battery float voltage (uV) */ +static int ln8000_get_vbat_float(struct ln8000_info *info) +{ + int ret, val; + + ret = ln8000_read_reg(info, LN8000_REG_V_FLOAT_CTRL, &val); + if (ret < 0) + return ret; + + return ((val & 0xFF) * LN8000_VBAT_FLOAT_LSB + + LN8000_VBAT_FLOAT_MIN); //uV +} + +/* grab programmed input current limit (uA) */ +static int ln8000_get_iin_limit(struct ln8000_info *info) +{ + int ret, val; + int iin; + + ret = ln8000_read_reg(info, LN8000_REG_IIN_CTRL, &val); + if (ret < 0) + return ret; + + iin = ((val & 0x7F) * LN8000_IIN_CFG_LSB); + + if (iin < LN8000_IIN_CFG_MIN) { + iin = LN8000_IIN_CFG_MIN; + } + + return iin; +} + +/* enable/disable STANDBY */ +static inline void ln8000_sw_standby(struct ln8000_info *info, bool standby) +{ + u8 val = (standby) ? BIT(LN8000_BIT_STANDBY_EN) : 0x00; + ln8000_update_reg(info, LN8000_REG_SYS_CTRL, BIT(LN8000_BIT_STANDBY_EN), + val); +} + +/* Convert Raw ADC Code */ +static void ln8000_convert_adc_code(struct ln8000_info *info, unsigned int ch, + u8 *sts, int *result) +{ + int adc_raw; // raw ADC value + int adc_final; // final (converted) ADC value + + switch (ch) { + case LN8000_ADC_CH_VOUT: + adc_raw = ((sts[1] & 0xFF) << 2) | ((sts[0] & 0xC0) >> 6); + adc_final = adc_raw * LN8000_ADC_VOUT_STEP; //uV + break; + case LN8000_ADC_CH_VIN: + adc_raw = ((sts[1] & 0x3F) << 4) | ((sts[0] & 0xF0) >> 4); + adc_final = adc_raw * LN8000_ADC_VIN_STEP; //uV + break; + case LN8000_ADC_CH_VBAT: + adc_raw = ((sts[1] & 0x03) << 8) | (sts[0] & 0xFF); + adc_final = adc_raw * LN8000_ADC_VBAT_STEP; //uV + break; + case LN8000_ADC_CH_VAC: + adc_raw = (((sts[1] & 0x0F) << 6) | ((sts[0] & 0xFC) >> 2)) + + LN8000_ADC_VAC_OS; + adc_final = adc_raw * LN8000_ADC_VAC_STEP; //uV + break; + case LN8000_ADC_CH_IIN: + adc_raw = ((sts[1] & 0x03) << 8) | (sts[0] & 0xFF); + adc_final = adc_raw * LN8000_ADC_IIN_STEP; //uA + break; + case LN8000_ADC_CH_DIETEMP: + adc_raw = ((sts[1] & 0x0F) << 6) | ((sts[0] & 0xFC) >> 2); + adc_final = (935 - adc_raw) * LN8000_ADC_DIETEMP_STEP / + LN8000_ADC_DIETEMP_DENOM; //dC + if (adc_final > LN8000_ADC_DIETEMP_MAX) + adc_final = LN8000_ADC_DIETEMP_MAX; + else if (adc_final < LN8000_ADC_DIETEMP_MIN) + adc_final = LN8000_ADC_DIETEMP_MIN; + break; + case LN8000_ADC_CH_TSBAT: + adc_raw = ((sts[1] & 0x3F) << 4) | ((sts[0] & 0xF0) >> 4); + adc_final = adc_raw * LN8000_ADC_NTCV_STEP; //(NTC) uV + break; + case LN8000_ADC_CH_TSBUS: + adc_raw = ((sts[1] & 0xFF) << 2) | ((sts[0] & 0xC0) >> 6); + adc_final = adc_raw * LN8000_ADC_NTCV_STEP; //(NTC) uV + break; + default: + adc_raw = -EINVAL; + adc_final = -EINVAL; + break; + } + + *result = adc_final; + return; +} + +static void ln8000_print_regmap(struct ln8000_info *info) +{ + const u8 print_reg_num = + (LN8000_REG_CHARGE_CTRL - LN8000_REG_INT1_MSK) + 1; + u32 regs[64] = { + 0x0, + }; + char temp_buf[128] = { + 0, + }; + int i, ret; + + for (i = 0; i < print_reg_num; ++i) { + ret = ln8000_read_reg(info, LN8000_REG_INT1_MSK + i, ®s[i]); + if (IS_ERR_VALUE((unsigned long)ret)) { + ln_err("fail to read reg for print_regmap[%d]\n", i); + regs[i] = 0xFF; + } + sprintf(temp_buf + strlen(temp_buf), "0x%02X[0x%02X],", + LN8000_REG_INT1_MSK + i, regs[i]); + if (((i + 1) % 10 == 0) || ((i + 1) == print_reg_num)) { + ln_info("%s\n", temp_buf); + memset(temp_buf, 0x0, sizeof(temp_buf)); + } + } +} + +/** + * LN8000 device driver control routines + */ +static int ln8000_check_status(struct ln8000_info *info) +{ + u8 val[4]; + + if (ln8000_bulk_read_reg(info, LN8000_REG_SYS_STS, val, 4) < 0) { + return -EINVAL; + } + + mutex_lock(&info->data_lock); + + info->vbat_regulated = + LN8000_STATUS(val[0], LN8000_MASK_VFLOAT_LOOP_STS); + info->iin_regulated = LN8000_STATUS(val[0], LN8000_MASK_IIN_LOOP_STS); + info->pwr_status = + val[0] & + (LN8000_MASK_BYPASS_ENABLED | LN8000_MASK_SWITCHING_ENABLED | + LN8000_MASK_STANDBY_STS | LN8000_MASK_SHUTDOWN_STS); + info->tdie_fault = LN8000_STATUS(val[1], LN8000_MASK_TEMP_MAX_STS); + info->tdie_alarm = + LN8000_STATUS(val[1], LN8000_MASK_TEMP_REGULATION_STS); + if (!info->pdata->tbat_mon_disable || !info->pdata->tbus_mon_disable) { + info->tbus_tbat_fault = LN8000_STATUS( + val[1], LN8000_MASK_NTC_SHUTDOWN_STS); //tbus or tbat + info->tbus_tbat_alarm = LN8000_STATUS( + val[1], LN8000_MASK_NTC_ALARM_STS); //tbus or tbat + } + info->iin_rc = LN8000_STATUS(val[1], LN8000_MASK_REV_IIN_STS); + + info->wdt_fault = LN8000_STATUS(val[2], LN8000_MASK_WATCHDOG_TIMER_STS); + info->vbat_ov = LN8000_STATUS(val[2], LN8000_MASK_VBAT_OV_STS); + info->vac_unplug = LN8000_STATUS(val[2], LN8000_MASK_VAC_UNPLUG_STS); + info->vac_ov = LN8000_STATUS(val[2], LN8000_MASK_VAC_OV_STS); + info->vbus_ov = LN8000_STATUS(val[2], LN8000_MASK_VIN_OV_STS); + info->volt_qual = !(LN8000_STATUS(val[2], 0x7F)); + if (info->volt_qual == 1 && info->chg_en == 1) { + info->volt_qual = !(LN8000_STATUS(val[3], 1 << 5)); + if (info->volt_qual == 0) { + ln_info("volt_fault_detected (volt_qual=%d)\n", + info->volt_qual); + /* clear latched status */ + ln8000_update_reg(info, LN8000_REG_TIMER_CTRL, 0x1 << 2, + 0x1 << 2); + ln8000_update_reg(info, LN8000_REG_TIMER_CTRL, 0x1 << 2, + 0x0 << 2); + } + } + info->iin_oc = LN8000_STATUS(val[3], LN8000_MASK_IIN_OC_DETECTED); + + mutex_unlock(&info->data_lock); + + return 0; +} + +static void ln8000_irq_sleep(struct ln8000_info *info, int suspend) +{ + if (info->client->irq <= 0) + return; + + if (suspend) { + ln_info("disable/suspend IRQ\n"); + disable_irq(info->client->irq); + } else { + ln_info("enable/resume IRQ\n"); + enable_irq(info->client->irq); + } +} + +#if 0 +static void ln8000_soft_reset(struct ln8000_info *info) +{ + ln8000_write_reg(info, LN8000_REG_LION_CTRL, 0xC6); + + ln8000_irq_sleep(info, 1); + + ln_info("(%s) Trigger soft-reset\n", LN8000_ROLE(info)); + ln8000_update_reg(info, LN8000_REG_BC_OP_2, 0x1 << 0, 0x1 << 0); + msleep(5 * 2); /* ln8000 min wait time 5ms (after POR) */ + + ln8000_irq_sleep(info, 0); +} +#endif + +static void ln8000_update_opmode(struct ln8000_info *info) +{ + unsigned int op_mode; + u32 val; + + /* chack mode status */ + ln8000_read_reg(info, LN8000_REG_SYS_STS, &val); + + if (val & LN8000_MASK_SHUTDOWN_STS) { + op_mode = LN8000_OPMODE_STANDBY; + } else if (val & LN8000_MASK_STANDBY_STS) { + op_mode = LN8000_OPMODE_STANDBY; + } else if (val & LN8000_MASK_SWITCHING_ENABLED) { + op_mode = LN8000_OPMODE_SWITCHING; + } else if (val & LN8000_MASK_BYPASS_ENABLED) { + op_mode = LN8000_OPMODE_BYPASS; + } else { + op_mode = LN8000_OPMODE_UNKNOWN; + } + + if (op_mode != info->op_mode) { + /* IC already has been entered standby_mode, need to trigger standbt_en bit */ + if (op_mode == LN8000_OPMODE_STANDBY) { + ln8000_update_reg(info, LN8000_REG_SYS_CTRL, + 1 << LN8000_BIT_STANDBY_EN, + 1 << LN8000_BIT_STANDBY_EN); + ln_info("forced trigger standby_en\n"); + info->chg_en = 0; + } + ln_info("op_mode has been changed [%d]->[%d] (sys_st=0x%x)\n", + info->op_mode, op_mode, val); + info->op_mode = op_mode; + } + + return; +} + +static int ln8000_change_opmode(struct ln8000_info *info, + unsigned int target_mode) +{ + int ret = 0; + u8 val, msk = (0x1 << LN8000_BIT_STANDBY_EN | + 0x1 << LN8000_BIT_EN_1TO1); + + switch (target_mode) { + case LN8000_OPMODE_STANDBY: + val = (1 << LN8000_BIT_STANDBY_EN); + break; + case LN8000_OPMODE_BYPASS: + val = (0 << LN8000_BIT_STANDBY_EN) | (1 << LN8000_BIT_EN_1TO1); + break; + case LN8000_OPMODE_SWITCHING: + val = (0 << LN8000_BIT_STANDBY_EN) | (0 << LN8000_BIT_EN_1TO1); + break; + default: + ln_err("invalid index (target_mode=%d)\n", target_mode); + return -EINVAL; + } + ret = ln8000_update_reg(info, LN8000_REG_SYS_CTRL, msk, val); + if (IS_ERR_VALUE((unsigned long)ret)) { + return -EINVAL; + } + ln_info("changed opmode [%d] -> [%d]\n", info->op_mode, target_mode); + info->op_mode = target_mode; + + return 0; +} + +static int ln8000_init_device(struct ln8000_info *info) +{ + unsigned int vbat_float; + + /* config default charging paramter by dt */ + vbat_float = info->pdata->bat_ovp_th * 100 / + 102; /* ovp thershold = v_float x 1.02 */ + vbat_float = (vbat_float / 1000) * 1000; + ln_info("bat_ovp_th=%d, vbat_float=%d\n", info->pdata->bat_ovp_th, + vbat_float); + ln8000_set_vbat_float(info, vbat_float); + info->vbat_ovp_alarm_th = info->pdata->bat_ovp_alarm_th; + ln8000_set_vac_ovp(info, info->pdata->bus_ovp_th); + info->vin_ovp_alarm_th = info->pdata->bus_ovp_alarm_th; + ln8000_set_iin_limit(info, info->pdata->bus_ocp_th - 700000); + info->iin_ocp_alarm_th = info->pdata->bus_ocp_alarm_th; + ln8000_set_ntc_alarm(info, info->pdata->ntc_alarm_cfg); + + ln8000_update_reg(info, LN8000_REG_REGULATION_CTRL, 0x3 << 2, + LN8000_NTC_SHUTDOWN_CFG); + ln8000_enable_auto_recovery(info, 0); + + /* config charging protection */ + ln8000_enable_vbat_ovp(info, !info->pdata->vbat_ovp_disable); + ln8000_enable_vbat_regulation(info, !info->pdata->vbat_reg_disable); + ln8000_enable_vbat_loop_int(info, !info->pdata->vbat_reg_disable); + ln8000_enable_iin_ocp(info, !info->pdata->iin_ocp_disable); + ln8000_enable_iin_regulation(info, !info->pdata->iin_reg_disable); + ln8000_enable_iin_loop_int(info, !info->pdata->iin_reg_disable); + ln8000_enable_tdie_regulation(info, !info->pdata->tdie_reg_disable); + ln8000_enable_tdie_prot(info, !info->pdata->tdie_prot_disable); + ln8000_enable_rcp(info, 0); + ln8000_change_opmode(info, LN8000_OPMODE_STANDBY); + ln8000_enable_vac_ov(info, 1); + + /* wdt : disable, adc : shutdown mode */ + ln8000_enable_wdt(info, false); + ln8000_set_adc_mode(info, ADC_SHUTDOWN_MODE); //disable before updating + ln8000_set_adc_hib_delay(info, ADC_HIBERNATE_4S); + ln8000_set_adc_ch(info, LN8000_ADC_CH_ALL, true); + ln8000_enable_tbus_monitor( + info, !info->pdata->tbus_mon_disable); //+enables ADC ch + ln8000_enable_tbat_monitor( + info, !info->pdata->tbat_mon_disable); //+enables ADC ch + ln8000_set_adc_mode(info, ADC_AUTO_HIB_MODE); + + /* mark sw initialized (used CHARGE_CTRL bit:7) */ + ln8000_update_reg(info, LN8000_REG_CHARGE_CTRL, 0x1 << 7, 0x1 << 7); + ln8000_write_reg(info, LN8000_REG_THRESHOLD_CTRL, 0x0E); + + ln8000_print_regmap(info); + + ln_info(" done.\n"); + + return 0; +} + +/** + * Support power_supply platform for charger block. + * propertis are compatible by Xiaomi platform + */ +static int ln8000_get_adc_data(struct ln8000_info *info, unsigned int ch, + int *result) +{ + int ret; + u8 sts[2]; + + /* pause adc update */ + ret = ln8000_update_reg(info, LN8000_REG_TIMER_CTRL, 0x1 << 1, + 0x1 << 1); + if (ret < 0) { + ln_err("fail to update bit PAUSE_ADC_UPDATE:1 (ret=%d)\n", ret); + return ret; + } + + switch (ch) { + case LN8000_ADC_CH_VOUT: + ret = ln8000_bulk_read_reg(info, LN8000_REG_ADC04_STS, sts, 2); + break; + case LN8000_ADC_CH_VIN: + ret = ln8000_bulk_read_reg(info, LN8000_REG_ADC03_STS, sts, 2); + break; + case LN8000_ADC_CH_VBAT: + ret = ln8000_bulk_read_reg(info, LN8000_REG_ADC06_STS, sts, 2); + break; + case LN8000_ADC_CH_VAC: + ret = ln8000_bulk_read_reg(info, LN8000_REG_ADC02_STS, sts, 2); + break; + case LN8000_ADC_CH_IIN: + ret = ln8000_bulk_read_reg(info, LN8000_REG_ADC01_STS, sts, 2); + break; + case LN8000_ADC_CH_DIETEMP: + ret = ln8000_bulk_read_reg(info, LN8000_REG_ADC07_STS, sts, 2); + break; + case LN8000_ADC_CH_TSBAT: + ret = ln8000_bulk_read_reg(info, LN8000_REG_ADC08_STS, sts, 2); + break; + case LN8000_ADC_CH_TSBUS: + ret = ln8000_bulk_read_reg(info, LN8000_REG_ADC09_STS, sts, 2); + break; + default: + ln_err("invalid ch(%d)\n", ch); + ret = -EINVAL; + break; + } + + /* resume adc update */ + ln8000_update_reg(info, LN8000_REG_TIMER_CTRL, 0x1 << 1, 0x0 << 1); + + if (IS_ERR_VALUE((unsigned long)ret) == false) { + ln8000_convert_adc_code(info, ch, sts, result); + } + + return ret; +} + +static int psy_chg_get_charging_enabled(struct ln8000_info *info) +{ + int enabled = 0; /* disabled */ + + if (info->chg_en) { + ln8000_update_opmode(info); + if (info->op_mode >= LN8000_OPMODE_BYPASS) { + enabled = 1; + } + } + + return enabled; +} + +static int psy_chg_get_ti_alarm_status(struct ln8000_info *info) +{ + int alarm; + unsigned int v_offset; + bool bus_ovp, bus_ocp, bat_ovp; + u8 val[4]; + + ln8000_check_status(info); + ln8000_get_adc_data(info, LN8000_ADC_CH_VIN, &info->vbus_uV); + ln8000_get_adc_data(info, LN8000_ADC_CH_IIN, &info->iin_uA); + ln8000_get_adc_data(info, LN8000_ADC_CH_VBAT, &info->vbat_uV); + + bus_ovp = (info->vbus_uV > info->vin_ovp_alarm_th) ? 1 : 0; + bus_ocp = (info->iin_uA > info->iin_ocp_alarm_th) ? 1 : 0; + bat_ovp = (info->vbat_uV > info->vbat_ovp_alarm_th) ? 1 : 0; + + /* BAT alarm status not support (ovp/ocp/ucp) */ + alarm = ((bus_ovp << BUS_OVP_ALARM_SHIFT) | + (bus_ocp << BUS_OCP_ALARM_SHIFT) | + (bat_ovp << BAT_OVP_ALARM_SHIFT) | + (info->tbus_tbat_alarm << BAT_THERM_ALARM_SHIFT) | + (info->tbus_tbat_alarm << BUS_THERM_ALARM_SHIFT) | + (info->tdie_alarm << DIE_THERM_ALARM_SHIFT)); + + v_offset = info->vbus_uV - (info->vbat_uV * 2); + /* after charging-enabled, When the input current rises above rcp_th(over 200mA), it activates rcp. */ + if (info->chg_en && !(info->rcp_en)) { + if (info->iin_uA > 200000 && v_offset > 300000) { + ln8000_enable_rcp(info, 1); + ln_info("enabled rcp\n"); + } + } + /* If an unplug event occurs when vbus voltage lower then vin_start_up_th, switch to standby mode. */ + if (info->chg_en && !(info->rcp_en)) { + if (v_offset < 100000) { + ln8000_change_opmode(info, LN8000_OPMODE_STANDBY); + ln_info("forced change standby_mode for prevent reverse current\n"); + info->chg_en = 0; + } + } + + ln8000_bulk_read_reg(info, LN8000_REG_SYS_STS, val, 4); + ln_info("adc_vin=%d(th=%d), adc_iin=%d(th=%d), adc_vbat=%d(th=%d), v_offset=%d\n", + info->vbus_uV / 1000, info->vin_ovp_alarm_th / 1000, + info->iin_uA / 1000, info->iin_ocp_alarm_th / 1000, + info->vbat_uV / 1000, info->vbat_ovp_alarm_th / 1000, + v_offset / 1000); + ln_info("st:0x%x:0x%x:0x%x:0x%x alarm=0x%x\n", val[0], val[1], val[2], + val[3], alarm); + + return alarm; +} + +static int psy_chg_get_ti_fault_status(struct ln8000_info *info) +{ + int fault; + + ln8000_check_status(info); + + /* BAT ocp fault status not suppport */ + fault = ((info->vbat_ov << BAT_OVP_FAULT_SHIFT) | + (info->vbus_ov << BUS_OVP_FAULT_SHIFT) | + (info->iin_oc << BUS_OCP_FAULT_SHIFT) | + (info->tbus_tbat_fault << BAT_THERM_FAULT_SHIFT) | + (info->tbus_tbat_fault << BUS_THERM_FAULT_SHIFT) | + (info->tdie_fault << DIE_THERM_FAULT_SHIFT)); + + if (info->volt_qual == 0) { + fault |= ((1 << BAT_OVP_FAULT_SHIFT) | + (1 << BUS_OVP_FAULT_SHIFT)); + } + + if (fault) { + ln_info("fault=0x%x\n", fault); + } + + return fault; +} + +static int ln8000_charger_get_property(struct power_supply *psy, + enum power_supply_property prop, + union power_supply_propval *val) +{ + struct ln8000_info *info = power_supply_get_drvdata(psy); + + switch (prop) { + case POWER_SUPPLY_PROP_CHARGING_ENABLED: + val->intval = psy_chg_get_charging_enabled(info); + break; + case POWER_SUPPLY_PROP_STATUS: + val->intval = 0; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = info->usb_present; + break; + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: + val->intval = ln8000_get_vbat_float(info); + break; + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + val->intval = ln8000_get_iin_limit(info); + break; + case POWER_SUPPLY_PROP_TI_BATTERY_PRESENT: + ln8000_get_adc_data(info, LN8000_ADC_CH_VBAT, &info->vbat_uV); + if (info->vbat_uV > LN8000_ADC_VBAT_MIN) { + val->intval = 1; /* detected battery */ + } else { + val->intval = 0; /* non-detected battery */ + } + break; + case POWER_SUPPLY_PROP_TI_VBUS_PRESENT: + ln8000_check_status(info); + val->intval = !(info->vac_unplug); + break; + case POWER_SUPPLY_PROP_TI_BATTERY_VOLTAGE: + ln8000_get_adc_data(info, LN8000_ADC_CH_VBAT, &info->vbat_uV); + val->intval = info->vbat_uV / 1000; + break; + case POWER_SUPPLY_PROP_TI_BATTERY_CURRENT: /* ln8000 not support IBAT_ADC */ + ln8000_get_adc_data(info, LN8000_ADC_CH_IIN, &info->iin_uA); + val->intval = + (info->iin_uA * 2) / 1000; /* return to IBUS_ADC x 2 */ + break; + case POWER_SUPPLY_PROP_TI_BATTERY_TEMPERATURE: + if (info->pdata->tbat_mon_disable) { + val->intval = 0; + } else { + ln8000_get_adc_data(info, LN8000_ADC_CH_TSBAT, + &info->tbat_uV); + val->intval = info->tbat_uV; + ln_info("ti_battery_temperature: adc_tbat=%d\n", + val->intval); + } + break; + case POWER_SUPPLY_PROP_TI_BUS_VOLTAGE: + ln8000_get_adc_data(info, LN8000_ADC_CH_VIN, &info->vbus_uV); + val->intval = info->vbus_uV / 1000; + break; + case POWER_SUPPLY_PROP_TI_BUS_CURRENT: + ln8000_get_adc_data(info, LN8000_ADC_CH_IIN, &info->iin_uA); + val->intval = info->iin_uA / 1000; + break; + case POWER_SUPPLY_PROP_TI_BUS_TEMPERATURE: + if (info->pdata->tbus_mon_disable) { + val->intval = 0; + } else { + ln8000_get_adc_data(info, LN8000_ADC_CH_TSBUS, + &info->tbus_uV); + val->intval = info->tbus_uV; + ln_info("ti_bus_temperature: adc_tbus=%d\n", + val->intval); + } + break; + case POWER_SUPPLY_PROP_TI_DIE_TEMPERATURE: + ln8000_get_adc_data(info, LN8000_ADC_CH_DIETEMP, + &info->tdie_dC); + val->intval = info->tdie_dC; + ln_info("ti_die_temperature: adc_tdie=%d\n", val->intval); + break; + case POWER_SUPPLY_PROP_TI_ALARM_STATUS: + val->intval = psy_chg_get_ti_alarm_status(info); + break; + case POWER_SUPPLY_PROP_TI_FAULT_STATUS: + val->intval = psy_chg_get_ti_fault_status(info); + break; + case POWER_SUPPLY_PROP_TI_REG_STATUS: + ln8000_check_status(info); + val->intval = + ((info->vbat_regulated << VBAT_REG_STATUS_SHIFT) | + /* ln8000 not support ibat_reg, we are can be ibus_reg */ + (info->iin_regulated << IBAT_REG_STATUS_SHIFT)); + if (val->intval) { + ln_info("ti_reg_status: intavl=0x%x\n", val->intval); + } + break; + case POWER_SUPPLY_PROP_MODEL_NAME: + val->strval = "ln8000"; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int psy_chg_set_charging_enable(struct ln8000_info *info, int val) +{ + int op_mode; + + if (val) { + ln_info("start charging\n"); + op_mode = LN8000_OPMODE_SWITCHING; + } else { + ln_info("stop charging\n"); + op_mode = LN8000_OPMODE_STANDBY; + } + + /* when the start-up to charging, we need to disabled rcp. */ + ln8000_enable_rcp(info, 0); + + ln8000_change_opmode(info, op_mode); + msleep(10); + ln8000_update_opmode(info); + + ln8000_print_regmap(info); + info->chg_en = val; + + ln_info("op_mode=%d\n", info->op_mode); + + return 0; +} + +static int psy_chg_set_present(struct ln8000_info *info, int val) +{ + bool usb_present = (bool)val; + + if (usb_present != info->usb_present) { + ln_info("changed usb_present [%d] -> [%d]\n", info->usb_present, + usb_present); + if (usb_present) { + ln8000_init_device(info); + } + info->usb_present = usb_present; + } + + return 0; +} + +static int psy_chg_set_bus_protection_for_qc3(struct ln8000_info *info, + int hvdcp3_type) +{ + ln_info("hvdcp3_type: %d\n", hvdcp3_type); + + if (hvdcp3_type == HVDCP3_CLASSA_18W) { + ln8000_set_vac_ovp(info, BUS_OVP_FOR_QC); + info->vin_ovp_alarm_th = BUS_OVP_ALARM_FOR_QC; + ln8000_set_iin_limit(info, BUS_OCP_FOR_QC_CLASS_A - 700000); + info->iin_ocp_alarm_th = BUS_OCP_ALARM_FOR_QC_CLASS_A; + } else if (hvdcp3_type == HVDCP3_CLASSB_27W) { + ln8000_set_vac_ovp(info, BUS_OVP_FOR_QC); + info->vin_ovp_alarm_th = BUS_OVP_ALARM_FOR_QC; + ln8000_set_iin_limit(info, BUS_OCP_FOR_QC_CLASS_B - 700000); + info->iin_ocp_alarm_th = BUS_OCP_ALARM_FOR_QC_CLASS_B; + } else if (hvdcp3_type == HVDCP3P5_CLASSA_18W) { + ln8000_set_vac_ovp(info, BUS_OVP_FOR_QC); + info->vin_ovp_alarm_th = BUS_OVP_ALARM_FOR_QC; + ln8000_set_iin_limit(info, BUS_OCP_FOR_QC3P5_CLASS_A - 700000); + info->iin_ocp_alarm_th = BUS_OCP_ALARM_FOR_QC3P5_CLASS_A; + } else if (hvdcp3_type == HVDCP3P5_CLASSB_27W) { + ln8000_set_vac_ovp(info, BUS_OVP_FOR_QC); + info->vin_ovp_alarm_th = BUS_OVP_ALARM_FOR_QC; + ln8000_set_iin_limit(info, BUS_OCP_FOR_QC3P5_CLASS_B - 700000); + info->iin_ocp_alarm_th = BUS_OCP_ALARM_FOR_QC3P5_CLASS_B; + } else { + ln8000_set_vac_ovp(info, info->pdata->bus_ovp_th); + info->vin_ovp_alarm_th = info->pdata->bus_ovp_alarm_th; + ln8000_set_iin_limit(info, info->pdata->bus_ocp_th - 700000); + info->iin_ocp_alarm_th = info->pdata->bus_ocp_alarm_th; + } + + ln8000_print_regmap(info); + + return 0; +} + +static int ln8000_charger_set_property(struct power_supply *psy, + enum power_supply_property prop, + const union power_supply_propval *val) +{ + struct ln8000_info *info = power_supply_get_drvdata(psy); + int ret = 0; + + switch (prop) { + case POWER_SUPPLY_PROP_CHARGING_ENABLED: + ret = psy_chg_set_charging_enable(info, val->intval); + break; + case POWER_SUPPLY_PROP_PRESENT: + ret = psy_chg_set_present(info, val->intval); + break; + case POWER_SUPPLY_PROP_TI_SET_BUS_PROTECTION_FOR_QC3: + ret = psy_chg_set_bus_protection_for_qc3(info, val->intval); + break; + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: + ret = ln8000_set_vbat_float(info, val->intval); + break; + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + ret = ln8000_set_iin_limit(info, val->intval); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int ln8000_charger_is_writeable(struct power_supply *psy, + enum power_supply_property prop) +{ + int ret; + + switch (prop) { + case POWER_SUPPLY_PROP_PRESENT: + case POWER_SUPPLY_PROP_CHARGING_ENABLED: + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + case POWER_SUPPLY_PROP_TI_SET_BUS_PROTECTION_FOR_QC3: + ret = 1; + break; + default: + ret = 0; + break; + } + + return ret; +} + +static enum power_supply_property ln8000_charger_props[] = { + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_CHARGING_ENABLED, + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, + /* support TI extended propertis */ + POWER_SUPPLY_PROP_TI_BATTERY_PRESENT, + POWER_SUPPLY_PROP_TI_VBUS_PRESENT, + POWER_SUPPLY_PROP_TI_BATTERY_VOLTAGE, + POWER_SUPPLY_PROP_TI_BATTERY_CURRENT, + POWER_SUPPLY_PROP_TI_BATTERY_TEMPERATURE, + POWER_SUPPLY_PROP_TI_BUS_VOLTAGE, + POWER_SUPPLY_PROP_TI_BUS_CURRENT, + POWER_SUPPLY_PROP_TI_BUS_TEMPERATURE, + POWER_SUPPLY_PROP_TI_DIE_TEMPERATURE, + POWER_SUPPLY_PROP_TI_ALARM_STATUS, + POWER_SUPPLY_PROP_TI_FAULT_STATUS, + POWER_SUPPLY_PROP_TI_REG_STATUS, + POWER_SUPPLY_PROP_TI_SET_BUS_PROTECTION_FOR_QC3, + POWER_SUPPLY_PROP_MODEL_NAME, +}; + +static int read_reg(void *data, u64 *val) +{ + struct ln8000_info *info = data; + int ret; + unsigned int temp; + + ret = regmap_read(info->regmap, info->debug_address, &temp); + if (ret) { + ln_err("Unable to read reg(0x%02X), ret=%d\n", + info->debug_address, ret); + return -EAGAIN; + } + *val = temp; + return 0; +} + +static int write_reg(void *data, u64 val) +{ + struct ln8000_info *info = data; + int ret; + u8 temp = (u8)val; + + ret = regmap_write(info->regmap, info->debug_address, temp); + if (ret) { + ln_err("Unable to write reg(0x%02X), data(0x%02X), ret=%d\n", + info->debug_address, temp, ret); + return -EAGAIN; + } + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(register_debug_ops, read_reg, write_reg, "0x%02llX\n"); + +static int ln8000_create_debugfs_entries(struct ln8000_info *info) +{ + struct dentry *ent; + + info->debug_root = debugfs_create_dir( + (LN8000_IS_PRIMARY(info) ? "ln8000" : "ln8000-secondary"), + NULL); + if (!info->debug_root) { + ln_err("unable to create debug dir\n"); + return -ENOENT; + } else { + ent = debugfs_create_x32("address", S_IFREG | S_IWUSR | S_IRUGO, + info->debug_root, + &(info->debug_address)); + if (!ent) { + ln_err("unable to create address debug file\n"); + return -ENOENT; + } + ent = debugfs_create_file("data", S_IFREG | S_IWUSR | S_IRUGO, + info->debug_root, info, + ®ister_debug_ops); + if (!ent) { + ln_err("unable to create data debug file\n"); + return -ENOENT; + } + } + + return 0; +} + +/** + * Support IRQ interface + */ +static int ln8000_read_int_value(struct ln8000_info *info, u32 *reg_val) +{ + int ret; + + /* pause INT updates */ + ln8000_update_reg(info, LN8000_REG_TIMER_CTRL, 0x1, 0x1); + mdelay(1); + + ret = ln8000_read_reg(info, LN8000_REG_INT1, reg_val); + + /* resume INT updates */ + ln8000_update_reg(info, LN8000_REG_TIMER_CTRL, 0x1, 0x0); + + return ret; +} + +static void vac_ov_control_work(struct work_struct *work) +{ + struct ln8000_info *info = + container_of(work, struct ln8000_info, vac_ov_work.work); + int i, cnt, ta_detached, delay = 50; + u32 sys_st; + bool enable_vac_ov = 1; + + ta_detached = 0; + cnt = 5000 / delay; + for (i = 0; i < cnt; ++i) { + ln8000_get_adc_data(info, LN8000_ADC_CH_VIN, &info->vbus_uV); + ln8000_read_reg(info, LN8000_REG_SYS_STS, &sys_st); + + if (enable_vac_ov) { + /* Check ADC_VIN during the 5sec, if vin higher then 10V, disable to vac_ov */ + if (info->vbus_uV > 10000000) { + enable_vac_ov = 0; + ln8000_enable_vac_ov(info, enable_vac_ov); + ln_info("vac_ov=disable, vin=%dmV, i=%d, cnt=%d, delay=%d\n", + info->vbus_uV / 1000, i, cnt, delay); + } + } else { + /* After disabled vac_ov, if ADC_VIN lower then 7V goto the terminate work */ + if (info->vbus_uV < 7000000) { + enable_vac_ov = 1; + ln_info("vac_ov=enable, vin=%dmV, i=%d, cnt=%d, delay=%d\n", + info->vbus_uV / 1000, i, cnt, delay); + goto teminate_work; + } + } + /* If judged 3 times by TA disconnected, goto the terminate work */ + if (sys_st == 0x1) { /* it's means entered shutdown mode */ + ta_detached += 1; + ln_info("sys_st=0x%x, ta_detached=%d\n", sys_st, + ta_detached); + if (ta_detached > 2) { + goto teminate_work; + } + } + + msleep(delay); + } + +teminate_work: + ln8000_enable_vac_ov(info, 1); + info->vac_ov_work_on = 0; +} + +static void check_vac_ov_work(struct ln8000_info *info) +{ + u32 sys_st, fault1_st; + + ln8000_read_reg(info, LN8000_REG_SYS_STS, &sys_st); + ln8000_read_reg(info, LN8000_REG_FAULT1_STS, &fault1_st); + + if (sys_st == 0x02 && fault1_st == 0x00) { /* connected valid VBUS */ + if (info->vac_ov_work_on == 0) { /* vac_ov_work not worked */ + schedule_delayed_work(&info->vac_ov_work, + msecs_to_jiffies(0)); + info->vac_ov_work_on = 1; + ln_info("schedule_work : vac_ov_work\n"); + } + } +} + +static irqreturn_t ln8000_interrupt_handler(int irq, void *data) +{ + struct ln8000_info *info = data; + u32 int_reg, int_msk; + u8 masked_int; + int ret; + ln_err("ln8000_interrupt_handler enter!\n"); + ret = ln8000_read_int_value(info, &int_reg); + if (IS_ERR_VALUE((unsigned long)ret)) { + ln_err("fail to read INT reg (ret=%d)\n", ret); + return IRQ_NONE; + } + ln8000_read_reg(info, LN8000_REG_INT1_MSK, &int_msk); + masked_int = int_reg & ~int_msk; + + ln_info("int_reg=0x%x, int_msk=0x%x, masked_int=0x%x\n", int_reg, + int_msk, masked_int); + + ln8000_print_regmap(info); + LN8000_BIT_CHECK(masked_int, 7, "(INT) FAULT_INT"); + LN8000_BIT_CHECK(masked_int, 6, "(INT) NTC_PROT_INT"); + LN8000_BIT_CHECK(masked_int, 5, "(INT) CHARGE_PHASE_INT"); + LN8000_BIT_CHECK(masked_int, 4, "(INT) MODE_INT"); + LN8000_BIT_CHECK(masked_int, 3, "(INT) REV_CURR_INT"); + LN8000_BIT_CHECK(masked_int, 2, "(INT) TEMP_INT"); + LN8000_BIT_CHECK(masked_int, 1, "(INT) ADC_DONE_INT"); + LN8000_BIT_CHECK(masked_int, 0, "(INT) TIMER_INT"); + ln8000_check_status(info); + + if (masked_int & LN8000_MASK_FAULT_INT) { /* FAULT_INT */ + if (info->volt_qual) { + ln_info("connected to power_supplier\n"); + } else { + ln_info("FAULT_INT has occurred\n"); + } + } + if (masked_int & LN8000_MASK_NTC_PROT_INT) { /* NTC_PROT_INT */ + ln_info("NTC_PROT_INT has occurred(ntc_fault=%d, ntc_alarm=%d)\n", + info->tbus_tbat_fault, info->tbus_tbat_alarm); + } + if (masked_int & LN8000_MASK_CHARGE_PHASE_INT) { /* CHARGE_PHASE_INT */ + if (info->vbat_regulated) { + ln_info("CHARGE_PHASE_INT: VFLOAT regulated\n"); + } else if (info->iin_regulated) { + ln_info("CHARGE_PHASE_INT: IIN regulated\n"); + } + } + if (masked_int & LN8000_MASK_MODE_INT) { /* MODE_INT */ + switch (info->pwr_status) { + case LN8000_MASK_BYPASS_ENABLED: + ln_info("MODE_INT: device in BYPASS mode\n"); + break; + case LN8000_MASK_SWITCHING_ENABLED: + ln_info("MODE_INT: device in SWITCHING mode\n"); + break; + case LN8000_MASK_STANDBY_STS: + ln_info("MODE_INT: device in STANDBY mode\n"); + break; + case LN8000_MASK_SHUTDOWN_STS: + ln_info("MODE_INT: device in SHUTDOWN mode\n"); + break; + default: + ln_info("MODE_INT: device in unknown mode\n"); + break; + } + } + if (masked_int & LN8000_MASK_TEMP_INT) { /* TEMP_INT */ + ln_info("TEMP_INT has occurred(tdie_fault=%d, tdie_alarm=%d)\n", + info->tdie_fault, info->tdie_alarm); + } + if (masked_int & LN8000_MASK_TIMER_INT) { /* TIMER_INT */ + ln_info("Watchdog timer has expired(wdt_fault=%d)\n", + info->wdt_fault); + } + + check_vac_ov_work(info); + + return IRQ_HANDLED; +} + +static int ln8000_irq_init(struct ln8000_info *info) +{ + const struct ln8000_platform_data *pdata = info->pdata; + int ret; + u8 mask; + u32 int_reg; + + if (LN8000_IS_PRIMARY(info)) { + if (info->pdata->irq_gpio) { + info->client->irq = gpiod_to_irq(pdata->irq_gpio); + if (info->client->irq < 0) { + ln_err("fail to get irq from gpio(irq_gpio=%p)\n", + pdata->irq_gpio) info->client->irq = 0; + return -EINVAL; + } + ln_info("mapped GPIO to irq (%d)\n", info->client->irq); + } + } else { + /* grab IRQ from primary device */ + ln_info("mapped shared GPIO to (primary dev) irq (%d)\n", + info->client->irq); + } + /* interrupt mask setting */ + mask = LN8000_MASK_ADC_DONE_INT | LN8000_MASK_TIMER_INT | + LN8000_MASK_MODE_INT | LN8000_MASK_REV_CURR_INT; + if (info->pdata->tdie_prot_disable && info->pdata->tdie_reg_disable) + mask |= LN8000_MASK_TEMP_INT; + if (info->pdata->iin_reg_disable && info->pdata->vbat_reg_disable) + mask |= LN8000_MASK_CHARGE_PHASE_INT; + if (info->pdata->tbat_mon_disable && info->pdata->tbus_mon_disable) + mask |= LN8000_MASK_NTC_PROT_INT; + ln8000_write_reg(info, LN8000_REG_INT1_MSK, mask); + /* read clear int_reg */ + ret = ln8000_read_int_value(info, &int_reg); + if (IS_ERR_VALUE((unsigned long)ret)) { + ln_err("fail to read INT reg (ret=%d)\n", ret); + return IRQ_NONE; + } + ln_info("int1_msk=0x%x\n", mask); + + return 0; +} + +static void determine_initial_status(struct ln8000_info *info) +{ + if (info->client->irq) + ln8000_interrupt_handler(info->client->irq, info); +} + +static const struct of_device_id ln8000_dt_match[] = { + { .compatible = "lionsemi,ln8000", .data = (void *)LN_PRIMARY }, + { .compatible = "lionsemi,ln8000-secondary", + .data = (void *)LN_SECONDARY }, + {}, +}; +MODULE_DEVICE_TABLE(of, ln8000_dt_match); + +static const struct i2c_device_id ln8000_id[] = { { "ln8000", LN_PRIMARY }, + { "ln8000-secondary", + LN_SECONDARY }, + {} }; + +static const struct regmap_config ln8000_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = LN8000_REG_MAX, +}; + +static int ln8000_get_dev_role(struct i2c_client *client) +{ + const struct of_device_id *of_id; + + of_id = of_match_device(of_match_ptr(ln8000_dt_match), &client->dev); + if (of_id == NULL) { + dev_err(&client->dev, "%s: fail to matched of_device_id\n", + __func__); + return -EINVAL; + } + + dev_info(&client->dev, "%s: matched to %s\n", __func__, + of_id->compatible); + + return (int)of_id->data; +} + +static int ln8000_parse_dt(struct ln8000_info *info) +{ + struct device *dev = info->dev; + struct ln8000_platform_data *pdata = info->pdata; + struct device_node *np = dev->of_node; + u32 prop; + int ret; + + if (np == NULL) + return -EINVAL; + + /* first we try to used client->irq */ + if (info->client->irq == 0) { + /* sencond we try to used irq_index info */ + ret = of_property_read_u32(np, "ln8000_charger,irq_index", + &prop); + if (ret < 0) { + ln_err("can't get irq_index(ret=%d)\n", ret); + prop = 0; + } + info->client->irq = prop; + } + ln_info("info->client->irq=%d\n", info->client->irq); + + if (!info->client->irq) { + pdata->irq_gpio = gpiod_get(dev, "irqb", GPIOD_IN); + if (LN8000_USE_GPIO(pdata)) { + ln_info("[gpio] found valid GPIO/IRQ descriptor\n"); + } else { + ln_info("[gpio] unspecified or invalid GPIO descriptor\n"); + pdata->irq_gpio = 0; + } + } + + /* device configuration */ + ret = of_property_read_u32(np, "ln8000_charger,bat-ovp-threshold", + &prop); + LN8000_PARSE_PROP(ret, pdata, bat_ovp_th, (prop * 1000 /*uV*/), + LN8000_BAT_OVP_DEFAULT); + ret = of_property_read_u32(np, "ln8000_charger,bat-ovp-alarm-threshold", + &prop); + LN8000_PARSE_PROP(ret, pdata, bat_ovp_alarm_th, (prop * 1000 /*uV*/), + 0); + ret = of_property_read_u32(np, "ln8000_charger,bus-ovp-threshold", + &prop); + LN8000_PARSE_PROP(ret, pdata, bus_ovp_th, (prop * 1000 /*uV*/), + LN8000_BUS_OVP_DEFAULT); + ret = of_property_read_u32(np, "ln8000_charger,bus-ovp-alarm-threshold", + &prop); + LN8000_PARSE_PROP(ret, pdata, bus_ovp_alarm_th, (prop * 1000 /*uA*/), + 0); + ret = of_property_read_u32(np, "ln8000_charger,bus-ocp-threshold", + &prop); + LN8000_PARSE_PROP(ret, pdata, bus_ocp_th, (prop * 1000 /*uA*/), + LN8000_BUS_OCP_DEFAULT); + ret = of_property_read_u32(np, "ln8000_charger,bus-ocp-alarm-threshold", + &prop); + LN8000_PARSE_PROP(ret, pdata, bus_ocp_alarm_th, (prop * 1000 /*uA*/), + 0); + ret = of_property_read_u32(np, "ln8000_charger,ntc-alarm-cfg", &prop); + LN8000_PARSE_PROP(ret, pdata, ntc_alarm_cfg, prop, + LN8000_NTC_ALARM_CFG_DEFAULT); + + /* protection/alarm disable (defaults to enable) */ + pdata->vbat_ovp_disable = + of_property_read_bool(np, "ln8000_charger,vbat-ovp-disable"); + pdata->vbat_reg_disable = + of_property_read_bool(np, "ln8000_charger,vbat-reg-disable"); + pdata->iin_ocp_disable = + of_property_read_bool(np, "ln8000_charger,iin-ocp-disable"); + pdata->iin_reg_disable = + of_property_read_bool(np, "ln8000_charger,iin-reg-disable"); + pdata->tbus_mon_disable = + of_property_read_bool(np, "ln8000_charger,tbus-mon-disable"); + pdata->tbat_mon_disable = + of_property_read_bool(np, "ln8000_charger,tbat-mon-disable"); + pdata->tdie_prot_disable = + of_property_read_bool(np, "ln8000_charger,tdie-prot-disable"); + pdata->tdie_reg_disable = + of_property_read_bool(np, "ln8000_charger,tdie-reg-disable"); + pdata->revcurr_prot_disable = of_property_read_bool( + np, "ln8000_charger,revcurr-prot-disable"); + +#ifdef LN8000_DUAL_CONFIG + /* override device tree */ + if (info->dev_role == LN_PRIMARY) { + ln_info("disable TS_BAT monitor for primary device on dual-mode\n"); + pdata->tbat_mon_disable = true; + } else { + ln_info("disable VBAT_OVP and TS_BAT for secondary device on dual-mode\n"); + pdata->vbat_ovp_disable = true; + pdata->tbat_mon_disable = true; + } +#endif + ln_info("vbat_ovp_disable = %d\n", pdata->vbat_ovp_disable); + ln_info("vbat_reg_disable = %d\n", pdata->vbat_reg_disable); + ln_info("iin_ocp_disable = %d\n", pdata->iin_ocp_disable); + ln_info("iin_reg_disable = %d\n", pdata->iin_reg_disable); + ln_info("tbus_mon_disable = %d\n", pdata->tbus_mon_disable); + ln_info("tbat_mon_disable = %d\n", pdata->tbat_mon_disable); + ln_info("tdie_prot_disable = %d\n", pdata->tdie_prot_disable); + ln_info("tdie_reg_disable = %d\n", pdata->tdie_reg_disable); + ln_info("revcurr_prot_disable = %d\n", pdata->revcurr_prot_disable); + + return 0; +} + +static int ln8000_psy_register(struct ln8000_info *info) +{ + info->psy_cfg.drv_data = info; + info->psy_cfg.of_node = info->client->dev.of_node; + info->psy_desc.name = "bq2597x-standalone"; + info->psy_desc.type = POWER_SUPPLY_TYPE_MAINS; + info->psy_desc.properties = ln8000_charger_props; + info->psy_desc.num_properties = ARRAY_SIZE(ln8000_charger_props); + info->psy_desc.get_property = ln8000_charger_get_property; + info->psy_desc.set_property = ln8000_charger_set_property; + info->psy_desc.property_is_writeable = ln8000_charger_is_writeable; + info->psy_chg = devm_power_supply_register( + &info->client->dev, &info->psy_desc, &info->psy_cfg); + if (IS_ERR(info->psy_chg)) { + ln_err("(%s) failed to register power supply\n", + LN8000_ROLE(info)); + return PTR_ERR(info->psy_chg); + } + + ln_info("(%s) successfully registered power supply\n", + LN8000_ROLE(info)); + + return 0; +} + +static int ln8000_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ln8000_info *info; + int ret = 0; + + /* detect device on connected i2c bus */ + ret = i2c_smbus_read_byte_data(client, LN8000_REG_DEVICE_ID); + if (IS_ERR_VALUE((unsigned long)ret)) { + dev_err(&client->dev, + "fail to detect ln8000 on i2c_bus(addr=0x%x)\n", + client->addr); + return -ENODEV; + } + dev_info(&client->dev, "device id=0x%x\n", ret); + + info = devm_kzalloc(&client->dev, sizeof(struct ln8000_info), + GFP_KERNEL); + if (info == NULL) { + dev_err(&client->dev, + "%s: fail to alloc devm for ln8000_info\n", __func__); + return -ENOMEM; + } + info->dev_role = ln8000_get_dev_role(client); + if (IS_ERR_VALUE((unsigned long)info->dev_role)) { + kfree(info); + return -EINVAL; + } + + info->pdata = devm_kzalloc( + &client->dev, sizeof(struct ln8000_platform_data), GFP_KERNEL); + if (info->pdata == NULL) { + ln_err("fail to alloc devm for ln8000_platform_data\n"); + kfree(info); + return -ENOMEM; + } + info->dev = &client->dev; + info->client = client; + ret = ln8000_parse_dt(info); + if (IS_ERR_VALUE((unsigned long)ret)) { + ln_err("fail to parsed dt\n"); + goto err_devmem; + } + + info->regmap = devm_regmap_init_i2c(client, &ln8000_regmap_config); + if (IS_ERR(info->regmap)) { + ln_err("fail to initialize regmap\n"); + ret = PTR_ERR(info->regmap); + goto err_devmem; + } + + mutex_init(&info->data_lock); + mutex_init(&info->i2c_lock); + mutex_init(&info->irq_lock); + i2c_set_clientdata(client, info); + + ln8000_init_device(info); + + ret = ln8000_psy_register(info); + if (ret) { + goto err_cleanup; + } + + ret = ln8000_irq_init(info); + if (ret < 0) { + goto err_psy; + } + + if (client->irq) { + ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, + ln8000_interrupt_handler, + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + "ln8000-charger-irq", info); + if (ret < 0) { + ln_err("request irq for irq=%d failed, ret =%d\n", + client->irq, ret); + goto err_wakeup; + } + enable_irq_wake(client->irq); + INIT_DELAYED_WORK(&info->vac_ov_work, vac_ov_control_work); + } else { + ln_info("don't support isr(irq=%d)\n", info->client->irq); + } + + device_init_wakeup(info->dev, 1); + + ret = ln8000_create_debugfs_entries(info); + if (IS_ERR_VALUE((unsigned long)ret)) { + goto err_wakeup; + } + + determine_initial_status(info); + + return 0; + +err_wakeup: + if (LN8000_IS_PRIMARY(info) && client->irq) { + free_irq(client->irq, info); + if (info->pdata->irq_gpio) { + gpiod_put(info->pdata->irq_gpio); + } + } +err_psy: + power_supply_unregister(info->psy_chg); + +err_cleanup: + i2c_set_clientdata(client, NULL); + mutex_destroy(&info->data_lock); + mutex_destroy(&info->i2c_lock); + mutex_destroy(&info->irq_lock); +err_devmem: + kfree(info->pdata); + kfree(info); + + return ret; +} + +static int ln8000_remove(struct i2c_client *client) +{ + struct ln8000_info *info = i2c_get_clientdata(client); + + ln8000_change_opmode(info, LN8000_OPMODE_STANDBY); + + debugfs_remove_recursive(info->debug_root); + + if (LN8000_IS_PRIMARY(info) && client->irq) { + free_irq(client->irq, info); + if (info->pdata->irq_gpio) { + gpiod_put(info->pdata->irq_gpio); + } + } + + power_supply_unregister(info->psy_chg); + i2c_set_clientdata(info->client, NULL); + + mutex_destroy(&info->data_lock); + mutex_destroy(&info->i2c_lock); + mutex_destroy(&info->irq_lock); + + kfree(info->pdata); + kfree(info); + + return 0; +} + +static void ln8000_shutdown(struct i2c_client *client) +{ + struct ln8000_info *info = i2c_get_clientdata(client); + + ln8000_change_opmode(info, LN8000_OPMODE_STANDBY); +} + +#if defined(CONFIG_PM) +static int ln8000_suspend(struct device *dev) +{ + struct ln8000_info *info = dev_get_drvdata(dev); + + if (device_may_wakeup(dev) && info->client->irq) + enable_irq_wake(info->client->irq); + + ln8000_irq_sleep(info, 1); + + return 0; +} + +static int ln8000_resume(struct device *dev) +{ + struct ln8000_info *info = dev_get_drvdata(dev); + + if (device_may_wakeup(dev) && info->client->irq) + disable_irq_wake(info->client->irq); + + ln8000_irq_sleep(info, 0); + + return 0; +} + +static const struct dev_pm_ops ln8000_pm_ops = { + .suspend = ln8000_suspend, + .resume = ln8000_resume, +}; +#endif + +static struct i2c_driver ln8000_driver = { + .driver = { + .name = "ln8000_charger", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(ln8000_dt_match), +#if defined(CONFIG_PM) + .pm = &ln8000_pm_ops, +#endif + }, + .probe = ln8000_probe, + .remove = ln8000_remove, + .shutdown = ln8000_shutdown, + .id_table = ln8000_id, +}; +module_i2c_driver(ln8000_driver); + +MODULE_AUTHOR("sungdae choi"); +MODULE_DESCRIPTION("LIONSEMI LN8000 charger driver"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("0.3.0"); diff --git a/drivers/power/supply/ti/ln8000_charger.h b/drivers/power/supply/ti/ln8000_charger.h new file mode 100644 index 000000000000..41a7d859bf49 --- /dev/null +++ b/drivers/power/supply/ti/ln8000_charger.h @@ -0,0 +1,344 @@ +/* + * ln8000-charger.h - Charger driver for LIONSEMI LN8000 + * + * Copyright (C) 2021 Lion Semiconductor Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * 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 __LN8000_CHARGER_H__ +#define __LN8000_CHARGER_H__ + +//#define LN8000_DUAL_CONFIG /* uncomment to enable DUAL chip operation */ +//#define LN8000_DEBUG_SUPPORT + +/** + * ln8000 device descripion definition + */ +#define ASSIGNED_BITS(_end, _start) ((BIT(_end) - BIT(_start)) + BIT(_end)) + +/* register map description */ +enum ln8000_int1_desc { + LN8000_MASK_FAULT_INT = BIT(7), + LN8000_MASK_NTC_PROT_INT = BIT(6), + LN8000_MASK_CHARGE_PHASE_INT = BIT(5), + LN8000_MASK_MODE_INT = BIT(4), + LN8000_MASK_REV_CURR_INT = BIT(3), + LN8000_MASK_TEMP_INT = BIT(2), + LN8000_MASK_ADC_DONE_INT = BIT(1), + LN8000_MASK_TIMER_INT = BIT(0), +}; + +enum ln8000_sys_sts_desc { + LN8000_MASK_IIN_LOOP_STS = BIT(7), + LN8000_MASK_VFLOAT_LOOP_STS = BIT(6), + LN8000_MASK_BYPASS_ENABLED = BIT(3), + LN8000_MASK_SWITCHING_ENABLED = BIT(2), + LN8000_MASK_STANDBY_STS = BIT(1), + LN8000_MASK_SHUTDOWN_STS = BIT(0), +}; + +enum ln8000_safety_sts_desc { + LN8000_MASK_TEMP_MAX_STS = BIT(6), + LN8000_MASK_TEMP_REGULATION_STS = BIT(5), + LN8000_MASK_NTC_ALARM_STS = BIT(4), + LN8000_MASK_NTC_SHUTDOWN_STS = BIT(3), + LN8000_MASK_REV_IIN_STS = BIT(2), +}; + +enum ln8000_fault1_sts_desc { + LN8000_MASK_WATCHDOG_TIMER_STS = BIT(7), + LN8000_MASK_VBAT_OV_STS = BIT(6), + LN8000_MASK_VAC_UNPLUG_STS = BIT(4), + LN8000_MASK_VAC_OV_STS = BIT(3), + LN8000_MASK_VIN_OV_STS = BIT(1), + LN8000_MASK_VFAULTS = ASSIGNED_BITS(6, 0), +}; + +enum ln8000_fault2_sts_desc { + LN8000_MASK_IIN_OC_DETECTED = BIT(7), +}; + +enum ln8000_ldo_sts_desc { + LN8000_MASK_VBAT_MIN_OK_STS = BIT(7), + LN8000_MASK_CHARGE_TERM_STS = BIT(5), + LN8000_MASK_RECHARGE_STS = BIT(4), +}; + +enum ln8000_regulation_ctrl_desc { + LN8000_BIT_ENABLE_VFLOAT_LOOP_INT = 7, + LN8000_BIT_ENABLE_IIN_LOOP_INT = 6, + LN8000_BIT_DISABLE_VFLOAT_LOOP = 5, + LN8000_BIT_DISABLE_IIN_LOOP = 4, + LN8000_BIT_TEMP_MAX_EN = 2, + LN8000_BIT_TEMP_REG_EN = 1, +}; + +enum ln8000_sys_ctrl_desc { + LN8000_BIT_STANDBY_EN = 3, + LN8000_BIT_REV_IIN_DET = 2, + LN8000_BIT_EN_1TO1 = 0, +}; + +enum ln8000_fault_ctrl_desc { + LN8000_BIT_DISABLE_IIN_OCP = 6, + LN8000_BIT_DISABLE_VBAT_OV = 5, + LN8000_BIT_DISABLE_VAC_OV = 4, + LN8000_BIT_DISABLE_VAC_UV = 3, + LN8000_BIT_DISABLE_VIN_OV = 2, +}; + +enum ln8000_bc_op1_desc { + LN8000_BIT_DUAL_FUNCTION_EN = 2, + LN8000_BIT_DUAL_CFG = 1, + LN8000_BIT_DUAL_LOCKOUT_EN = 0, +}; + +enum ln8000_reg_addr { + LN8000_REG_DEVICE_ID = 0x00, + LN8000_REG_INT1 = 0x01, + LN8000_REG_INT1_MSK = 0x02, + LN8000_REG_SYS_STS = 0x03, + LN8000_REG_SAFETY_STS = 0x04, + LN8000_REG_FAULT1_STS = 0x05, + LN8000_REG_FAULT2_STS = 0x06, + LN8000_REG_CURR1_STS = 0x07, + LN8000_REG_LDO_STS = 0x08, + LN8000_REG_ADC01_STS = 0x09, + LN8000_REG_ADC02_STS = 0x0A, + LN8000_REG_ADC03_STS = 0x0B, + LN8000_REG_ADC04_STS = 0x0C, + LN8000_REG_ADC05_STS = 0x0D, + LN8000_REG_ADC06_STS = 0x0E, + LN8000_REG_ADC07_STS = 0x0F, + LN8000_REG_ADC08_STS = 0x10, + LN8000_REG_ADC09_STS = 0x11, + LN8000_REG_ADC10_STS = 0x12, + LN8000_REG_IIN_CTRL = 0x1B, + LN8000_REG_REGULATION_CTRL = 0x1C, + LN8000_REG_PWR_CTRL = 0x1D, + LN8000_REG_SYS_CTRL = 0x1E, + LN8000_REG_LDO_CTRL = 0x1F, + LN8000_REG_GLITCH_CTRL = 0x20, + LN8000_REG_FAULT_CTRL = 0x21, + LN8000_REG_NTC_CTRL = 0x22, + LN8000_REG_ADC_CTRL = 0x23, + LN8000_REG_ADC_CFG = 0x24, + LN8000_REG_RECOVERY_CTRL = 0x25, + LN8000_REG_TIMER_CTRL = 0x26, + LN8000_REG_THRESHOLD_CTRL = 0x27, + LN8000_REG_V_FLOAT_CTRL = 0x28, + LN8000_REG_CHARGE_CTRL = 0x29, + LN8000_REG_LION_CTRL = 0x30, + LN8000_REG_BC_OP_1 = 0x41, + LN8000_REG_BC_OP_2 = 0x42, + LN8000_REG_BC_STS_A = 0x49, + LN8000_REG_BC_STS_B = 0x4A, + LN8000_REG_BC_STS_C = 0x4B, + LN8000_REG_BC_STS_D = 0x4C, + LN8000_REG_BC_STS_E = 0x4D, + LN8000_REG_MAX, +}; + +/* device feature configuration desc */ +#define LN8000_DEVICE_ID 0x42 + +enum ln8000_role { + LN_PRIMARY = 0x0, + LN_SECONDARY = 0x1, +}; + +enum ln8000_opmode_ { + LN8000_OPMODE_UNKNOWN = 0x0, + LN8000_OPMODE_STANDBY = 0x1, + LN8000_OPMODE_BYPASS = 0x2, + LN8000_OPMODE_SWITCHING = 0x3, +}; + +enum ln8000_vac_ov_cfg_desc { + LN8000_VAC_OVP_6P5V = 0x0, + LN8000_VAC_OVP_11V = 0x1, + LN8000_VAC_OVP_12V = 0x2, + LN8000_VAC_OVP_13V = 0x3, +}; + +enum ln8000_watchdpg_cfg_desc { + LN8000_WATCHDOG_5SEC = 0x0, + LN8000_WATCHDOG_10SEC = 0x1, + LN8000_WATCHDOG_20SEC = 0x2, + LN8000_WATCHDOG_40SEC = 0x3, + LN8000_WATCHDOG_MAX +}; + +enum ln8000_adc_channel_index { + LN8000_ADC_CH_VOUT = 1, + LN8000_ADC_CH_VIN, + LN8000_ADC_CH_VBAT, + LN8000_ADC_CH_VAC, + LN8000_ADC_CH_IIN, + LN8000_ADC_CH_DIETEMP, + LN8000_ADC_CH_TSBAT, + LN8000_ADC_CH_TSBUS, + LN8000_ADC_CH_ALL +}; + +enum ln8000_adc_mode_desc { /* used FORCE_ADC_MODE + ADC_SHUTDOWN_CFG */ + ADC_AUTO_HIB_MODE = 0x0, + ADC_AUTO_SHD_MODE = 0x1, + ADC_SHUTDOWN_MODE = 0x2, + ADC_HIBERNATE_MODE = 0x4, + ADC_NORMAL_MODE = 0x6, +}; + +enum ln8000_adc_hibernate_delay_desc { + ADC_HIBERNATE_500MS = 0x0, + ADC_HIBERNATE_1S = 0x1, + ADC_HIBERNATE_2S = 0x2, + ADC_HIBERNATE_4S = 0x3, +}; + +/* electrical numeric calculation unit description */ +#define LN8000_VBAT_FLOAT_MIN 3725000 /* unit = uV */ +#define LN8000_VBAT_FLOAT_MAX 5000000 +#define LN8000_VBAT_FLOAT_LSB 5000 +#define LN8000_ADC_VOUT_STEP 5000 /* 5mV= 5000uV LSB (0V ~ 5.115V) */ +#define LN8000_ADC_VIN_STEP 16000 /* 16mV=16000uV LSB (0V ~ 16.386V) */ +#define LN8000_ADC_VBAT_STEP 5000 /* 5mV= 5000uV LSB (0V ~ 5.115V) */ +#define LN8000_ADC_VBAT_MIN 1000000 /* 1V */ +#define LN8000_ADC_VAC_STEP 16000 /* 16mV=16000uV LSB (0V ~ 16.386V) */ +#define LN8000_ADC_VAC_OS 5 +#define LN8000_ADC_IIN_STEP 4890 /* 4.89mA=4890uA LSB (0A ~ 5A) */ +#define LN8000_ADC_DIETEMP_STEP \ + 4350 /* 0.435C LSB = 4350dC/1000 (-25C ~ 160C) */ +#define LN8000_ADC_DIETEMP_DENOM 1000 /* 1000 */ +#define LN8000_ADC_DIETEMP_MIN (-250) /* -25C = -250dC */ +#define LN8000_ADC_DIETEMP_MAX 1600 /* 160C = 1600dC */ +#define LN8000_ADC_NTCV_STEP 2933 /* 2.933mV=2933uV LSB (0V ~ 3V) */ +#define LN8000_IIN_CFG_MIN 500000 /* 500mA=500,000uA */ +#define LN8000_IIN_CFG_LSB 50000 /* 50mA=50,000uA */ + +/* device default values */ +#define LN8000_BAT_OVP_DEFAULT 4440000 +#define LN8000_BUS_OVP_DEFAULT 9500000 +#define LN8000_BUS_OCP_DEFAULT 2000000 + +#define LN8000_NTC_ALARM_CFG_DEFAULT 226 /* NTC alarm threshold (~40C) */ +#define LN8000_NTC_SHUTDOWN_CFG 2 /* NTC shutdown config (-16LSB ~ 4.3C) */ +#define LN8000_DEFAULT_FSW_CFG 8 /* 8=440kHz, switching freq */ +#define LN8000_IIN_CFG_DEFAULT 2000000 /* 2A=2,000,000uA, input current limit */ + +/* bus protection values for QC */ +#define BUS_OVP_FOR_QC \ + 13000000 /* ln8000 didn't used 10V, (support tot 6.5V, 11V, 12V, 13V) */ +#define BUS_OVP_ALARM_FOR_QC 9500000 +#define BUS_OCP_FOR_QC_CLASS_A 3250000 +#define BUS_OCP_ALARM_FOR_QC_CLASS_A 2000000 +#define BUS_OCP_FOR_QC_CLASS_B 3750000 +#define BUS_OCP_ALARM_FOR_QC_CLASS_B 2800000 +#define BUS_OCP_FOR_QC3P5_CLASS_A 3000000 +#define BUS_OCP_ALARM_FOR_QC3P5_CLASS_A 2500000 +#define BUS_OCP_FOR_QC3P5_CLASS_B 3500000 +#define BUS_OCP_ALARM_FOR_QC3P5_CLASS_B 3200000 + +/** + * driver instance structure definition + */ +struct ln8000_platform_data { + struct gpio_desc + *irq_gpio; /* GPIO pin for (generic/power-on) interrupt */ + + /* feature configuration */ + unsigned int bat_ovp_th; /* battery ovp threshold (mV) */ + unsigned int bat_ovp_alarm_th; /* battery ovp alarm threshold (mV) */ + unsigned int bus_ovp_th; /* IIN ovp threshold (mV) */ + unsigned int bus_ovp_alarm_th; /* IIN ovp alarm threshold (mV) */ + unsigned int bus_ocp_th; /* IIN ocp threshold (mA) */ + unsigned int bus_ocp_alarm_th; /* IIN ocp alarm threshold */ + unsigned int + ntc_alarm_cfg; /* input/battery NTC voltage threshold code: 0~1023 */ + + /* protection enable/disable */ + bool vbat_ovp_disable; /* disable battery voltage OVP */ + bool vbat_reg_disable; /* disable battery voltage (float) regulation */ + bool iin_ocp_disable; /* disable input current OCP */ + bool iin_reg_disable; /* disable input current regulation */ + bool tbus_mon_disable; /* disable BUS temperature monitor (prot/alarm) */ + bool tbat_mon_disable; /* disable BAT temperature monitor (prot/alarm) */ + bool tdie_prot_disable; /* disable die temperature protection */ + bool tdie_reg_disable; /* disable die temperature regulation */ + bool revcurr_prot_disable; /* disable reverse current protection */ +}; + +struct ln8000_info { + struct device *dev; + struct i2c_client *client; + struct ln8000_platform_data *pdata; + struct power_supply *psy_chg; + + struct mutex data_lock; + struct mutex i2c_lock; + struct mutex irq_lock; + struct regmap *regmap; + struct power_supply_config psy_cfg; + struct power_supply_desc psy_desc; + + unsigned int op_mode; /* target operation mode */ + unsigned int pwr_status; /* current device status */ + unsigned int dev_role; /* device role */ + + /* system/device status */ + bool vbat_regulated; /* vbat loop is active (+ OV alarm) */ + bool iin_regulated; /* iin loop is active (+ OC alarm) */ + bool tdie_fault; /* die temperature fault */ + bool tbus_tbat_fault; /* BUS/BAT temperature fault */ + bool tdie_alarm; /* die temperature alarm (regulated) */ + bool tbus_tbat_alarm; /* BUS/BAT temperature alarm */ + bool wdt_fault; /* watchdog timer expiration */ + bool vbat_ov; /* vbat OV fault */ + bool vac_ov; /* vac OV fault */ + bool vbus_ov; /* vbus OV fault */ + bool iin_oc; /* iin OC fault */ + bool vac_unplug; /* vac unplugged */ + bool iin_rc; /* iin reverse current detected */ + bool volt_qual; /* all voltages are qualified */ + bool usb_present; /* usb plugged (present) */ + bool chg_en; /* charging enavbled */ + bool rcp_en; /* reverse current protection enabled */ + int vbat_ovp_alarm_th; /* vbat ovp alarm threshold */ + int vin_ovp_alarm_th; /* vin ovp alarm threshold */ + int iin_ocp_alarm_th; /* iin ocp alarm threshold */ + + /* ADC readings */ + int tbat_uV; /* BAT temperature (NTC, uV) */ + int tbus_uV; /* BUS temperature (NTC, uV) */ + int tdie_dC; /* die temperature (deci-Celsius) */ + int vbat_uV; /* battery voltage (uV) */ + int vbus_uV; /* input voltage (uV) */ + int iin_uA; /* input current (uV) */ + + /* VAC_OV control for QC3 */ + struct delayed_work vac_ov_work; + bool vac_ov_work_on; + +#ifdef LN8000_ROLE_MASTER + bool ibat_term; /* battery current below termination threshold */ + bool vbat_rechg; /* battery voltage below recharge threshold */ + bool vbat_min; /* battery voltage above min. threshold */ +#endif + + /* debugfs */ + struct dentry *debug_root; + u32 debug_address; +}; + +#endif /* __LN8000_CHARGER_H__ */ diff --git a/drivers/power/supply/ti/pd_policy_manager.c b/drivers/power/supply/ti/pd_policy_manager.c new file mode 100644 index 000000000000..d65e013f8ffd --- /dev/null +++ b/drivers/power/supply/ti/pd_policy_manager.c @@ -0,0 +1,1589 @@ + +#define pr_fmt(fmt) "[USBPD-PM]: %s: " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pd_policy_manager.h" + +#ifdef pr_debug +#undef pr_debug +#define pr_debug pr_err +#endif + +#ifdef pr_info +#undef pr_info +#define pr_info pr_err +#endif + +#define PD_SRC_PDO_TYPE_FIXED 0 +#define PD_SRC_PDO_TYPE_BATTERY 1 +#define PD_SRC_PDO_TYPE_VARIABLE 2 +#define PD_SRC_PDO_TYPE_AUGMENTED 3 + +#define BATT_MAX_CHG_VOLT 4450 +#define BATT_FAST_CHG_CURR 6000 +#define BUS_OVP_THRESHOLD 12000 +#define BUS_OVP_ALARM_THRESHOLD 9500 +#define APDO_MAX_VOLT 11000 + +#define BUS_VOLT_INIT_UP 400 + +#define BAT_VOLT_LOOP_LMT BATT_MAX_CHG_VOLT +#define BAT_CURR_LOOP_LMT BATT_FAST_CHG_CURR +#define BUS_VOLT_LOOP_LMT BUS_OVP_THRESHOLD + +#define PM_WORK_RUN_NORMAL_INTERVAL 500 +#define PM_WORK_RUN_QUICK_INTERVAL 200 +#define PM_WORK_RUN_CRITICAL_INTERVAL 100 + +enum { + PM_ALGO_RET_OK, + PM_ALGO_RET_THERM_FAULT, + PM_ALGO_RET_OTHER_FAULT, + PM_ALGO_RET_CHG_DISABLED, + PM_ALGO_RET_TAPER_DONE, + PM_ALGO_RET_SLOWLY_CHARGING, +}; + +static struct pdpm_config pm_config = { + .bat_volt_lp_lmt = BAT_VOLT_LOOP_LMT, + .bat_curr_lp_lmt = BAT_CURR_LOOP_LMT + 1000, + .bus_volt_lp_lmt = BUS_VOLT_LOOP_LMT, + .bus_curr_lp_lmt = BAT_CURR_LOOP_LMT >> 1, + .bus_curr_compensate = 0, + + .fc2_taper_current = 2300, + .fc2_steps = 1, + + .min_adapter_volt_required = 10000, + .min_adapter_curr_required = 2000, + + .min_vbat_for_cp = 3500, + + .cp_sec_enable = false, + .fc2_disable_sw = true, +}; + +static struct usbpd_pm *__pdpm; + +static int fc2_taper_timer; +static int cool_overcharge_timer; +static int ibus_lmt_change_timer; + +static void usbpd_check_usb_psy(struct usbpd_pm *pdpm) +{ + if (!pdpm->usb_psy) { + pdpm->usb_psy = power_supply_get_by_name("usb"); + if (!pdpm->usb_psy) + pr_err("usb psy not found!\n"); + } +} + +static void usbpd_check_batt_psy(struct usbpd_pm *pdpm) +{ + if (!pdpm->sw_psy) { + pdpm->sw_psy = power_supply_get_by_name("battery"); + if (!pdpm->sw_psy) + pr_err("batt psy not found!\n"); + } +} + +static void usbpd_check_bms_psy(struct usbpd_pm *pdpm) +{ + if (!pdpm->bms_psy) { + pdpm->bms_psy = power_supply_get_by_name("bms"); + if (!pdpm->bms_psy) + pr_err("bms psy not found!\n"); + } +} + +/* get thermal level from battery power supply property */ +static int pd_get_batt_current_thermal_level(struct usbpd_pm *pdpm, int *level) +{ + union power_supply_propval pval = { + 0, + }; + int rc = 0; + + usbpd_check_batt_psy(pdpm); + + if (!pdpm->sw_psy) + return -ENODEV; + + rc = power_supply_get_property( + pdpm->sw_psy, POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &pval); + if (rc < 0) { + pr_info("Couldn't get fastcharge mode:%d\n", rc); + return rc; + } + + pr_debug("pval.intval: %d\n", pval.intval); + + *level = pval.intval; + return rc; +} + +static int pd_get_batt_capacity(struct usbpd_pm *pdpm, int *capacity) +{ + union power_supply_propval pval = { + 0, + }; + int rc = 0; + + usbpd_check_batt_psy(pdpm); + + if (!pdpm->sw_psy) + return -ENODEV; + + rc = power_supply_get_property(pdpm->sw_psy, POWER_SUPPLY_PROP_CAPACITY, + &pval); + if (rc < 0) { + pr_info("Couldn't get fastcharge mode:%d\n", rc); + return rc; + } + + pr_err("pval.intval: %d\n", pval.intval); + *capacity = pval.intval; + return rc; +} + +/* determine whether to disable cp according to jeita status */ +static bool pd_disable_cp_by_jeita_status(struct usbpd_pm *pdpm) +{ + union power_supply_propval pval = { + 0, + }; + int batt_temp = 0, bq_input_suspend = 0; + int rc; + + usbpd_check_batt_psy(pdpm); + + if (!pdpm->sw_psy) + return -ENODEV; + + rc = power_supply_get_property( + pdpm->sw_psy, POWER_SUPPLY_PROP_BQ_INPUT_SUSPEND, &pval); + + if (!rc) + bq_input_suspend = !!pval.intval; + + if (!pdpm->bms_psy) + return false; + + rc = power_supply_get_property(pdpm->bms_psy, POWER_SUPPLY_PROP_TEMP, + &pval); + if (rc < 0) { + pr_info("Couldn't get batt temp prop:%d\n", rc); + return false; + } + + batt_temp = pval.intval; + pr_debug("batt_temp: %d\n", batt_temp); + if (bq_input_suspend) { + return true; + } else { + if (batt_temp >= JEITA_WARM_THR && !pdpm->jeita_triggered) { + pdpm->jeita_triggered = true; + return true; + } else if (batt_temp <= JEITA_COOL_NOT_ALLOW_CP_THR) { + pdpm->jeita_triggered = true; + return true; + } else if ((batt_temp <= (JEITA_WARM_THR - JEITA_HYSTERESIS)) && + (batt_temp >= + (JEITA_COOL_NOT_ALLOW_CP_THR + JEITA_HYSTERESIS)) && + pdpm->jeita_triggered) { + pdpm->jeita_triggered = false; + return false; + } else { + return pdpm->jeita_triggered; + } + } +} + +static bool is_cool_charge(struct usbpd_pm *pdpm) +{ + union power_supply_propval pval = { + 0, + }; + int batt_temp = 0; + int rc; + + if (!pdpm->bms_psy) + return false; + + rc = power_supply_get_property(pdpm->bms_psy, POWER_SUPPLY_PROP_TEMP, + &pval); + if (rc < 0) { + pr_info("Couldn't get batt temp prop:%d\n", rc); + return false; + } + batt_temp = pval.intval; + + pr_debug("batt_temp: %d\n", batt_temp); + if (batt_temp < 150) + return true; + return false; +} + +/* get bq27z561 fastcharge mode to enable or disabled */ +static bool pd_get_bms_digest_verified(struct usbpd_pm *pdpm) +{ + union power_supply_propval pval = { + 0, + }; + int rc; + + return true; /*for temp debug*/ + + if (!pdpm->bms_psy) + return false; + + rc = power_supply_get_property(pdpm->bms_psy, + POWER_SUPPLY_PROP_AUTHENTIC, &pval); + if (rc < 0) { + pr_info("Couldn't get fastcharge mode:%d\n", rc); + return false; + } + + pr_err("battery verify is: %d\n", pval.intval); + + if (pval.intval == 1) + return true; + else + return false; +} + +/* get pd pps charger verified result */ +#if 0 +static bool pd_get_pps_charger_verified(struct usbpd_pm *pdpm) +{ + union power_supply_propval pval = {0,}; + int rc; + + if (!pdpm->usb_psy) + return false; + + rc = power_supply_get_property(pdpm->usb_psy, + POWER_SUPPLY_PROP_PD_AUTHENTICATION, &pval); + if (rc < 0) { + pr_info("Couldn't get pd_authentication result:%d\n", rc); + return false; + } + + pr_err("pval.intval: %d\n", pval.intval); + + if (pval.intval == 1) + return true; + else + return false; +} +#endif + +/* get bq27z561 fastcharge mode to enable or disabled */ +/* +static int pd_get_bms_charge_current_max(struct usbpd_pm *pdpm, int *fcc_ua) +{ + union power_supply_propval pval = {0,}; + int rc = 0; + + if (!pdpm->bms_psy) + return rc; + + rc = power_supply_get_property(pdpm->bms_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &pval); + if (rc < 0) { + pr_info("Couldn't get current max:%d\n", rc); + return rc; + } + + *fcc_ua = pval.intval; + return rc; + +} +*/ +/* +static int usbpd_set_new_fcc_voter(struct usbpd_pm *pdpm) +{ + int rc = 0; + int fcc_ua = 0; + + rc = pd_get_bms_charge_current_max(pdpm, &fcc_ua); + + if (rc < 0) + return rc; + + if (!pdpm->fcc_votable) + pdpm->fcc_votable = find_votable("FCC"); + + if (!pdpm->fcc_votable) + return -EINVAL; + + if (pdpm->fcc_votable) + vote(pdpm->fcc_votable, STEP_BMS_CHG_VOTER, true, fcc_ua); + + return rc; +} +*/ + +static void usbpd_check_cp_psy(struct usbpd_pm *pdpm) +{ + if (!pdpm->cp_psy) { + if (pm_config.cp_sec_enable) + pdpm->cp_psy = + power_supply_get_by_name("bq2597x-master"); + else + pdpm->cp_psy = + power_supply_get_by_name("bq2597x-standalone"); + if (!pdpm->cp_psy) { + pdpm->cp_psy = power_supply_get_by_name("ln8000"); + if (!pdpm->cp_psy) + pr_err("cp_psy not found\n"); + } + } +} + +static void usbpd_check_cp_sec_psy(struct usbpd_pm *pdpm) +{ + if (!pdpm->cp_sec_psy) { + pdpm->cp_sec_psy = power_supply_get_by_name("bq2597x-slave"); + if (!pdpm->cp_sec_psy) + pr_err("cp_sec_psy not found\n"); + } +} + +static int usbpd_get_effective_fcc_val(struct usbpd_pm *pdpm) +{ + int effective_fcc_val = 0; + + if (!pdpm->fcc_votable) + pdpm->fcc_votable = find_votable("FCC"); + + if (!pdpm->fcc_votable) + return -EINVAL; + + effective_fcc_val = get_effective_result(pdpm->fcc_votable); + effective_fcc_val = effective_fcc_val / 1000; + pr_info("effective_fcc_val: %d\n", effective_fcc_val); + return effective_fcc_val; +} + +static void usbpd_pm_update_cp_status(struct usbpd_pm *pdpm) +{ + int ret; + union power_supply_propval val = { + 0, + }; + + usbpd_check_cp_psy(pdpm); + + if (!pdpm->cp_psy) + return; + + ret = power_supply_get_property( + pdpm->cp_psy, POWER_SUPPLY_PROP_TI_BATTERY_VOLTAGE, &val); + if (!ret) + pdpm->cp.vbat_volt = val.intval; + + ret = power_supply_get_property(pdpm->cp_psy, + POWER_SUPPLY_PROP_TI_BUS_VOLTAGE, &val); + if (!ret) + pdpm->cp.vbus_volt = val.intval; + + ret = power_supply_get_property(pdpm->cp_psy, + POWER_SUPPLY_PROP_TI_BUS_CURRENT, &val); + if (!ret) + pdpm->cp.ibus_curr = val.intval; + + ret = power_supply_get_property( + pdpm->cp_psy, POWER_SUPPLY_PROP_TI_BUS_TEMPERATURE, &val); + if (!ret) + pdpm->cp.bus_temp = val.intval; + + ret = power_supply_get_property( + pdpm->cp_psy, POWER_SUPPLY_PROP_TI_BATTERY_TEMPERATURE, &val); + if (!ret) + pdpm->cp.bat_temp = val.intval; + + ret = power_supply_get_property( + pdpm->cp_psy, POWER_SUPPLY_PROP_TI_DIE_TEMPERATURE, &val); + if (!ret) + pdpm->cp.die_temp = val.intval; + + ret = power_supply_get_property( + pdpm->cp_psy, POWER_SUPPLY_PROP_TI_BATTERY_PRESENT, &val); + if (!ret) + pdpm->cp.batt_pres = val.intval; + + ret = power_supply_get_property( + pdpm->cp_psy, POWER_SUPPLY_PROP_TI_VBUS_PRESENT, &val); + if (!ret) + pdpm->cp.vbus_pres = val.intval; + + usbpd_check_bms_psy(pdpm); + if (pdpm->bms_psy) { + ret = power_supply_get_property( + pdpm->bms_psy, POWER_SUPPLY_PROP_CURRENT_NOW, &val); + if (!ret) { + if (pdpm->cp.vbus_pres) + pdpm->cp.ibat_curr = -(val.intval / 1000); + } + ret = power_supply_get_property( + pdpm->bms_psy, POWER_SUPPLY_PROP_FASTCHARGE_MODE, &val); + if (!ret) { + if (val.intval) + pm_config.bat_volt_lp_lmt = + pdpm->ffc_bat_volt_max; + } + } + + ret = power_supply_get_property( + pdpm->cp_psy, POWER_SUPPLY_PROP_CHARGING_ENABLED, &val); + if (!ret) + pdpm->cp.charge_enabled = val.intval; + + ret = power_supply_get_property( + pdpm->cp_psy, POWER_SUPPLY_PROP_TI_ALARM_STATUS, &val); + if (!ret) { + pdpm->cp.bat_ovp_alarm = !!(val.intval & BAT_OVP_ALARM_MASK); + pdpm->cp.bat_ocp_alarm = !!(val.intval & BAT_OCP_ALARM_MASK); + pdpm->cp.bus_ovp_alarm = !!(val.intval & BUS_OVP_ALARM_MASK); + pdpm->cp.bus_ocp_alarm = !!(val.intval & BUS_OCP_ALARM_MASK); + pdpm->cp.bat_ucp_alarm = !!(val.intval & BAT_UCP_ALARM_MASK); + pdpm->cp.bat_therm_alarm = + !!(val.intval & BAT_THERM_ALARM_MASK); + pdpm->cp.bus_therm_alarm = + !!(val.intval & BUS_THERM_ALARM_MASK); + pdpm->cp.die_therm_alarm = + !!(val.intval & DIE_THERM_ALARM_MASK); + } + + ret = power_supply_get_property( + pdpm->cp_psy, POWER_SUPPLY_PROP_TI_FAULT_STATUS, &val); + if (!ret) { + pdpm->cp.bat_ovp_fault = !!(val.intval & BAT_OVP_FAULT_MASK); + pdpm->cp.bat_ocp_fault = !!(val.intval & BAT_OCP_FAULT_MASK); + pdpm->cp.bus_ovp_fault = !!(val.intval & BUS_OVP_FAULT_MASK); + pdpm->cp.bus_ocp_fault = !!(val.intval & BUS_OCP_FAULT_MASK); + pdpm->cp.bat_therm_fault = + !!(val.intval & BAT_THERM_FAULT_MASK); + pdpm->cp.bus_therm_fault = + !!(val.intval & BUS_THERM_FAULT_MASK); + pdpm->cp.die_therm_fault = + !!(val.intval & DIE_THERM_FAULT_MASK); + } + + ret = power_supply_get_property(pdpm->cp_psy, + POWER_SUPPLY_PROP_TI_REG_STATUS, &val); + if (!ret) { + pdpm->cp.vbat_reg = !!(val.intval & VBAT_REG_STATUS_MASK); + pdpm->cp.ibat_reg = !!(val.intval & IBAT_REG_STATUS_MASK); + } +} + +static void usbpd_pm_update_cp_sec_status(struct usbpd_pm *pdpm) +{ + int ret; + union power_supply_propval val = { + 0, + }; + + if (!pm_config.cp_sec_enable) + return; + + usbpd_check_cp_sec_psy(pdpm); + + if (!pdpm->cp_sec_psy) + return; + + ret = power_supply_get_property(pdpm->cp_sec_psy, + POWER_SUPPLY_PROP_TI_BUS_CURRENT, &val); + if (!ret) + pdpm->cp_sec.ibus_curr = val.intval; + + ret = power_supply_get_property( + pdpm->cp_sec_psy, POWER_SUPPLY_PROP_CHARGING_ENABLED, &val); + if (!ret) + pdpm->cp_sec.charge_enabled = val.intval; +} + +static int usbpd_pm_enable_cp(struct usbpd_pm *pdpm, bool enable) +{ + int ret; + union power_supply_propval val = { + 0, + }; + + usbpd_check_cp_psy(pdpm); + + if (!pdpm->cp_psy) + return -ENODEV; + + val.intval = enable; + ret = power_supply_set_property( + pdpm->cp_psy, POWER_SUPPLY_PROP_CHARGING_ENABLED, &val); + + return ret; +} + +static int usbpd_pm_enable_cp_sec(struct usbpd_pm *pdpm, bool enable) +{ + int ret; + union power_supply_propval val = { + 0, + }; + + usbpd_check_cp_sec_psy(pdpm); + + if (!pdpm->cp_sec_psy) + return -ENODEV; + + val.intval = enable; + ret = power_supply_set_property( + pdpm->cp_sec_psy, POWER_SUPPLY_PROP_CHARGING_ENABLED, &val); + + return ret; +} + +static int usbpd_pm_check_cp_enabled(struct usbpd_pm *pdpm) +{ + int ret; + union power_supply_propval val = { + 0, + }; + + usbpd_check_cp_psy(pdpm); + + if (!pdpm->cp_psy) + return -ENODEV; + + ret = power_supply_get_property( + pdpm->cp_psy, POWER_SUPPLY_PROP_CHARGING_ENABLED, &val); + if (!ret) + pdpm->cp.charge_enabled = !!val.intval; + + pr_info("pdpm->cp.charge_enabled:%d\n", pdpm->cp.charge_enabled); + + return ret; +} + +static int usbpd_pm_check_cp_sec_enabled(struct usbpd_pm *pdpm) +{ + int ret; + union power_supply_propval val = { + 0, + }; + + usbpd_check_cp_sec_psy(pdpm); + + if (!pdpm->cp_sec_psy) + return -ENODEV; + + ret = power_supply_get_property( + pdpm->cp_sec_psy, POWER_SUPPLY_PROP_CHARGING_ENABLED, &val); + if (!ret) + pdpm->cp_sec.charge_enabled = !!val.intval; + pr_info("pdpm->cp_sec.charge_enabled:%d\n", + pdpm->cp_sec.charge_enabled); + return ret; +} + +static int usbpd_pm_enable_sw(struct usbpd_pm *pdpm, bool enable) +{ + int ret; + union power_supply_propval val = { + 0, + }; + + if (!pdpm->sw_psy) { + pdpm->sw_psy = power_supply_get_by_name("battery"); + if (!pdpm->sw_psy) { + return -ENODEV; + } + } + + val.intval = enable; + ret = power_supply_set_property( + pdpm->sw_psy, POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED, &val); + + return ret; +} + +static int usbpd_pm_check_slowly_charging_enabled(struct usbpd_pm *pdpm) +{ + int ret; + union power_supply_propval val = { + 0, + }; + + if (!pdpm->sw_psy) { + pdpm->sw_psy = power_supply_get_by_name("battery"); + if (!pdpm->sw_psy) { + return -ENODEV; + } + } + + ret = power_supply_get_property( + pdpm->sw_psy, POWER_SUPPLY_PROP_SLOWLY_CHARGING, &val); + if (!ret) + pdpm->sw.slowly_charging = !!val.intval; + + return ret; +} + +static int usbpd_pm_limit_sw(struct usbpd_pm *pdpm, bool enable) +{ + int ret; + union power_supply_propval val = { + 0, + }; + + if (!pdpm->sw_psy) { + pdpm->sw_psy = power_supply_get_by_name("battery"); + if (!pdpm->sw_psy) { + return -ENODEV; + } + } + + val.intval = enable; + ret = power_supply_set_property( + pdpm->sw_psy, POWER_SUPPLY_PROP_BATTERY_CHARGING_LIMITED, &val); + + return ret; +} + +static int usbpd_pm_check_sw_limited(struct usbpd_pm *pdpm) +{ + int ret; + union power_supply_propval val = { + 0, + }; + + if (!pdpm->sw_psy) { + pdpm->sw_psy = power_supply_get_by_name("battery"); + if (!pdpm->sw_psy) { + return -ENODEV; + } + } + + ret = power_supply_get_property( + pdpm->sw_psy, POWER_SUPPLY_PROP_BATTERY_CHARGING_LIMITED, &val); + if (!ret) + pdpm->sw.charge_limited = !!val.intval; + + return ret; +} + +static int usbpd_pm_check_sw_enabled(struct usbpd_pm *pdpm) +{ + int ret; + union power_supply_propval val = { + 0, + }; + + if (!pdpm->sw_psy) { + pdpm->sw_psy = power_supply_get_by_name("battery"); + if (!pdpm->sw_psy) { + return -ENODEV; + } + } + + ret = power_supply_get_property( + pdpm->sw_psy, POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED, &val); + if (!ret) + pdpm->sw.charge_enabled = !!val.intval; + + return ret; +} + +static void usbpd_pm_update_sw_status(struct usbpd_pm *pdpm) +{ + usbpd_pm_check_sw_enabled(pdpm); + usbpd_pm_check_sw_limited(pdpm); +} + +static void usbpd_pm_evaluate_src_caps(struct usbpd_pm *pdpm) +{ + int ret; + int i; + union power_supply_propval pval = { + 0, + }; + + if (!pdpm->pd) { + pdpm->pd = smb_get_usbpd(); + if (!pdpm->pd) { + pr_err("couldn't get usbpd device\n"); + return; + } + } + + ret = usbpd_fetch_pdo(pdpm->pd, pdpm->pdo); + if (ret) { + pr_err("Failed to fetch pdo info\n"); + return; + } + + pdpm->apdo_max_volt = pm_config.min_adapter_volt_required; + pdpm->apdo_max_curr = pm_config.min_adapter_curr_required; + + for (i = 0; i < PDO_MAX_NUM; i++) { + if (pdpm->pdo[i].type == PD_SRC_PDO_TYPE_AUGMENTED && + pdpm->pdo[i].pps && pdpm->pdo[i].pos) { + if (pdpm->pdo[i].max_volt_mv >= pdpm->apdo_max_volt && + pdpm->pdo[i].curr_ma >= pdpm->apdo_max_curr && + pdpm->pdo[i].max_volt_mv <= APDO_MAX_VOLT) { + pdpm->apdo_max_volt = pdpm->pdo[i].max_volt_mv; + pdpm->apdo_max_curr = pdpm->pdo[i].curr_ma; + pdpm->apdo_selected_pdo = pdpm->pdo[i].pos; + pdpm->pps_supported = true; + } + } + } + + if (pdpm->pps_supported) { + pr_info("PPS supported, preferred APDO pos:%d, max volt:%d, current:%d\n", + pdpm->apdo_selected_pdo, pdpm->apdo_max_volt, + pdpm->apdo_max_curr); + if (pdpm->apdo_max_curr <= LOW_POWER_PPS_CURR_THR) + pdpm->apdo_max_curr = XIAOMI_LOW_POWER_PPS_CURR_MAX; + pval.intval = (pdpm->apdo_max_volt / 1000) * + (pdpm->apdo_max_curr / 1000); + power_supply_set_property(pdpm->usb_psy, + POWER_SUPPLY_PROP_APDO_MAX, &pval); + } else { + pr_info("Not qualified PPS adapter\n"); + } +} + +static void usbpd_update_pps_status(struct usbpd_pm *pdpm) +{ + int ret; + u32 status; + + /* we will use it later, to do */ + return; + + ret = usbpd_get_pps_status(pdpm->pd, &status); + + if (!ret) { + pr_info("get_pps_status: status_db :0x%x\n", status); + /*TODO: check byte order to insure data integrity*/ + pdpm->adapter_voltage = (status & 0xFFFF) * 20; + pdpm->adapter_current = ((status >> 16) & 0xFF) * 50; + pdpm->adapter_ptf = ((status >> 24) & 0x06) >> 1; + pdpm->adapter_omf = !!((status >> 24) & 0x08); + pr_info("adapter_volt:%d, adapter_current:%d\n", + pdpm->adapter_voltage, pdpm->adapter_current); + pr_info("pdpm->adapter_ptf:%d, pdpm->adapter_omf:%d\n", + pdpm->adapter_ptf, pdpm->adapter_omf); + } +} + +#define TAPER_TIMEOUT (25000 / PM_WORK_RUN_NORMAL_INTERVAL) +#define IBUS_CHANGE_TIMEOUT (2500 / PM_WORK_RUN_NORMAL_INTERVAL) +static int usbpd_pm_fc2_charge_algo(struct usbpd_pm *pdpm) +{ + int steps; + int sw_ctrl_steps = 0; + int hw_ctrl_steps = 0; + int step_vbat = 0; + int step_ibus = 0; + int step_ibat = 0; + int step_bat_reg = 0; + int ibus_total = 0; + int effective_fcc_val = 0; + int effective_fcc_taper = 0; + int thermal_level = 0; + static int curr_fcc_limit, curr_ibus_limit; + + static int ibus_limit; + + //usbpd_set_new_fcc_voter(pdpm); + + effective_fcc_val = usbpd_get_effective_fcc_val(pdpm); + + if (effective_fcc_val > 0) { + curr_fcc_limit = + min(pm_config.bat_curr_lp_lmt, effective_fcc_val); + curr_ibus_limit = curr_fcc_limit >> 1; + /* + * bq25970 alone compensate 100mA, bq25970 master ans slave compensate 300mA, + * for target curr_ibus_limit for bq adc accurancy is below standard and power suuply system current + */ + curr_ibus_limit += pm_config.bus_curr_compensate; + /* curr_ibus_limit should compare with apdo_max_curr here*/ + curr_ibus_limit = min(curr_ibus_limit, pdpm->apdo_max_curr); + pr_debug("curr_ibus_limit:%d\n", curr_ibus_limit); + } + + ibus_limit = curr_ibus_limit; + /* reduce bus current in cv loop */ + if (pdpm->cp.vbat_volt > pm_config.bat_volt_lp_lmt - BQ_TAPER_HYS_MV) { + if (ibus_lmt_change_timer++ > IBUS_CHANGE_TIMEOUT) { + ibus_lmt_change_timer = 0; + ibus_limit = curr_ibus_limit - 100; + effective_fcc_taper = usbpd_get_effective_fcc_val(pdpm); + effective_fcc_taper -= BQ_TAPER_DECREASE_STEP_MA; + pr_err("bq set taper fcc to: %d mA\n", + effective_fcc_taper); + if (pdpm->fcc_votable) + vote(pdpm->fcc_votable, BQ_TAPER_FCC_VOTER, + true, effective_fcc_taper * 1000); + } + } else if (pdpm->cp.vbat_volt < pm_config.bat_volt_lp_lmt - 250) { + ibus_limit = curr_ibus_limit + 100; + ibus_lmt_change_timer = 0; + } else { + ibus_lmt_change_timer = 0; + } + pr_info("ibus_limit:%d\n", ibus_limit); + + /* battery voltage loop*/ + if (pdpm->cp.vbat_volt > pm_config.bat_volt_lp_lmt) + step_vbat = -pm_config.fc2_steps; + else if (pdpm->cp.vbat_volt < pm_config.bat_volt_lp_lmt - 10) + step_vbat = pm_config.fc2_steps; + ; + + /* battery charge current loop*/ + if (pdpm->cp.ibat_curr < curr_fcc_limit) + step_ibat = pm_config.fc2_steps; + else if (pdpm->cp.ibat_curr > curr_fcc_limit + 50) + step_ibat = -pm_config.fc2_steps; + + /* bus current loop*/ + ibus_total = pdpm->cp.ibus_curr; + + if (pm_config.cp_sec_enable) + ibus_total += pdpm->cp_sec.ibus_curr; + + pr_info("ibus_total_ma: %d\n", ibus_total); + pr_info("vbus_mv: %d\n", pdpm->cp.vbus_volt); + pr_info("vbat_mv: %d\n", pdpm->cp.vbat_volt); + pr_info("ibat_ma: %d\n", pdpm->cp.ibat_curr); + + if (ibus_total < ibus_limit - 50) + step_ibus = pm_config.fc2_steps; + else if (ibus_total > ibus_limit) + step_ibus = -pm_config.fc2_steps; + pr_info("step_ibus:%d\n", step_ibus); + + pr_info("pdpm->cp.vbat_reg:%d, pdpm->cp.ibat_reg:%d\n", + pdpm->cp.vbat_reg, pdpm->cp.ibat_reg); + /* hardware regulation loop*/ + if (pdpm->cp.vbat_reg) /*|| pdpm->cp.ibat_reg*/ + step_bat_reg = 3 * (-pm_config.fc2_steps); + else + step_bat_reg = pm_config.fc2_steps; + + pr_info("step_bat_reg:%d\n", step_bat_reg); + sw_ctrl_steps = min(min(step_vbat, step_ibus), step_ibat); + sw_ctrl_steps = min(sw_ctrl_steps, step_bat_reg); + + pr_info("sw_ctrl_steps:%d\n", sw_ctrl_steps); + /* hardware alarm loop */ + if (pdpm->cp.bus_ocp_alarm || pdpm->cp.bus_ovp_alarm) + hw_ctrl_steps = -pm_config.fc2_steps; + else + hw_ctrl_steps = pm_config.fc2_steps; + pr_info("hw_ctrl_steps:%d\n", hw_ctrl_steps); + /* check if cp disabled due to other reason*/ + usbpd_pm_check_cp_enabled(pdpm); + + if (pm_config.cp_sec_enable) + usbpd_pm_check_cp_sec_enabled(pdpm); + + pd_get_batt_current_thermal_level(pdpm, &thermal_level); + + pdpm->is_temp_out_fc2_range = pd_disable_cp_by_jeita_status(pdpm); + pr_debug("is_temp_out_fc2_range:%d\n", pdpm->is_temp_out_fc2_range); + + /*check if slowly charging feature is enabled*/ + usbpd_pm_check_slowly_charging_enabled(pdpm); + + if (pdpm->cp.bat_therm_fault) { /* battery overheat, stop charge*/ + pr_info("bat_therm_fault:%d\n", pdpm->cp.bat_therm_fault); + return PM_ALGO_RET_THERM_FAULT; + } else if (thermal_level >= MAX_THERMAL_LEVEL || + pdpm->is_temp_out_fc2_range) { + pr_info("is_temp_out_fc2_range:%d,thermal_level:%d\n", + pdpm->is_temp_out_fc2_range, thermal_level); + pr_info("thermal level too high or batt temp is out of fc2 range\n"); + return PM_ALGO_RET_CHG_DISABLED; + } else if (pdpm->cp.bat_ocp_fault || pdpm->cp.bus_ocp_fault || + pdpm->cp.bat_ovp_fault || pdpm->cp.bus_ovp_fault) { + pr_info("bat_ocp_fault:%d, bus_ocp_fault:%d, bat_ovp_fault:%d, bus_ovp_fault:%d\n", + pdpm->cp.bat_ocp_fault, pdpm->cp.bus_ocp_fault, + pdpm->cp.bat_ovp_fault, pdpm->cp.bus_ovp_fault); + return PM_ALGO_RET_OTHER_FAULT; /* go to switch, and try to ramp up*/ + } else if (!pdpm->cp.charge_enabled || + (pm_config.cp_sec_enable && !pdpm->cp_sec.charge_enabled)) { + pr_info("cp.charge_enabled:%d, cp_sec.charge_enabled:%d\n", + pdpm->cp.charge_enabled, pdpm->cp_sec.charge_enabled); + return PM_ALGO_RET_CHG_DISABLED; + } else if (pdpm->sw.slowly_charging) { + pr_info("slowly charging enabled[%d]\n", + pdpm->sw.slowly_charging); + return PM_ALGO_RET_SLOWLY_CHARGING; + } + + /*check overcharge when it is cool*/ + if (pdpm->cp.vbat_volt > pm_config.bat_volt_lp_lmt && + is_cool_charge(pdpm)) { + if (cool_overcharge_timer++ > TAPER_TIMEOUT) { + pr_info("cool overcharge\n"); + cool_overcharge_timer = 0; + return PM_ALGO_RET_TAPER_DONE; + } + } else { + cool_overcharge_timer = 0; + } + /* charge pump taper charge */ + if (pdpm->cp.vbat_volt > pm_config.bat_volt_lp_lmt - TAPER_VOL_HYS && + pdpm->cp.ibat_curr < pm_config.fc2_taper_current) { + if (fc2_taper_timer++ > TAPER_TIMEOUT) { + pr_info("charge pump taper charging done\n"); + fc2_taper_timer = 0; + return PM_ALGO_RET_TAPER_DONE; + } + } else { + fc2_taper_timer = 0; + } + + /*TODO: customer can add hook here to check system level + * thermal mitigation*/ + + steps = min(sw_ctrl_steps, hw_ctrl_steps); + pr_info("steps: %d, sw_ctrl_steps:%d, hw_ctrl_steps:%d\n", steps, + sw_ctrl_steps, hw_ctrl_steps); + pdpm->request_voltage += steps * STEP_MV; + + pdpm->request_current = min(pdpm->apdo_max_curr, curr_ibus_limit); + + pr_info("steps: %d, pdpm->request_voltage: %d\n", steps, + pdpm->request_voltage); + + if (pdpm->apdo_max_volt == PPS_VOL_MAX) + pdpm->apdo_max_volt = pdpm->apdo_max_volt - PPS_VOL_HYS; + + if (pdpm->request_voltage > pdpm->apdo_max_volt) + pdpm->request_voltage = pdpm->apdo_max_volt; + + /*if (pdpm->adapter_voltage > 0 + && pdpm->request_voltage > pdpm->adapter_voltage + 500) + pdpm->request_voltage = pdpm->adapter_voltage + 500; */ + + return PM_ALGO_RET_OK; +} + +static const unsigned char *pm_str[] = { + "PD_PM_STATE_ENTRY", "PD_PM_STATE_FC2_ENTRY", + "PD_PM_STATE_FC2_ENTRY_1", "PD_PM_STATE_FC2_ENTRY_2", + "PD_PM_STATE_FC2_ENTRY_3", "PD_PM_STATE_FC2_TUNE", + "PD_PM_STATE_FC2_EXIT", +}; + +static void usbpd_pm_move_state(struct usbpd_pm *pdpm, enum pm_state state) +{ +#if 1 + pr_info("state change:%s -> %s\n", pm_str[pdpm->state], pm_str[state]); +#endif + pdpm->state = state; +} + +static int usbpd_pm_sm(struct usbpd_pm *pdpm) +{ + int ret; + int rc = 0; + static int tune_vbus_retry; + static bool stop_sw; + static bool recover; + int effective_fcc_val = 0; + int thermal_level = 0, capacity; + static int curr_fcc_lmt, curr_ibus_lmt, retry_count; + + switch (pdpm->state) { + case PD_PM_STATE_ENTRY: + stop_sw = false; + recover = false; + + usbpd_pm_check_slowly_charging_enabled(pdpm); + pd_get_batt_current_thermal_level(pdpm, &thermal_level); + pdpm->is_temp_out_fc2_range = + pd_disable_cp_by_jeita_status(pdpm); + pr_info("is_temp_out_fc2_range:%d\n", + pdpm->is_temp_out_fc2_range); + pd_get_batt_capacity(pdpm, &capacity); + effective_fcc_val = usbpd_get_effective_fcc_val(pdpm); + + if (effective_fcc_val > 0) { + curr_fcc_lmt = min(pm_config.bat_curr_lp_lmt, + effective_fcc_val); + curr_ibus_lmt = curr_fcc_lmt >> 1; + pr_info("curr_ibus_lmt:%d\n", curr_ibus_lmt); + } + + if (pdpm->cp.vbat_volt < pm_config.min_vbat_for_cp) { + pr_info("batt_volt %d, waiting...\n", + pdpm->cp.vbat_volt); + } else if ((pdpm->cp.vbat_volt > + pm_config.bat_volt_lp_lmt - 50) || + (capacity >= 95)) { + pr_info("batt_volt %d is too high for cp,\ + charging with switch charger\n", + pdpm->cp.vbat_volt); + usbpd_pm_move_state(pdpm, PD_PM_STATE_FC2_EXIT); + if (pm_config.bat_volt_lp_lmt < BAT_VOLT_LOOP_LMT) + recover = true; + } else if (!pd_get_bms_digest_verified(pdpm)) { + pr_info("bms digest is not verified, waiting...\n"); + } else if (thermal_level >= MAX_THERMAL_LEVEL || + pdpm->is_temp_out_fc2_range) { + pr_info("thermal too high or batt temp is out of fc2 range, waiting...\n"); + } else if (pdpm->sw.slowly_charging) { + pr_info("slowly charging feature is on, waiting...\n"); + } else { + pr_info("batt_volt-%d is ok, start flash charging\n", + pdpm->cp.vbat_volt); + usbpd_pm_move_state(pdpm, PD_PM_STATE_FC2_ENTRY); + } + break; + + case PD_PM_STATE_FC2_ENTRY: + if (pm_config.fc2_disable_sw) { + if (!pdpm->sw.charge_limited) { + usbpd_pm_limit_sw(pdpm, true); + usbpd_pm_update_sw_status(pdpm); + } + usbpd_pm_move_state(pdpm, PD_PM_STATE_FC2_ENTRY_1); + } else { + usbpd_pm_move_state(pdpm, PD_PM_STATE_FC2_ENTRY_1); + } + retry_count = 0; + break; + + case PD_PM_STATE_FC2_ENTRY_1: + pdpm->request_voltage = + pdpm->cp.vbat_volt * 2 + BUS_VOLT_INIT_UP; + pdpm->request_current = min(pdpm->apdo_max_curr, curr_ibus_lmt); + + usbpd_select_pdo(pdpm->pd, pdpm->apdo_selected_pdo, + pdpm->request_voltage * 1000, + pdpm->request_current * 1000); + pr_debug("request_voltage:%d, request_current:%d\n", + pdpm->request_voltage, pdpm->request_current); + + usbpd_pm_move_state(pdpm, PD_PM_STATE_FC2_ENTRY_2); + + tune_vbus_retry = 0; + break; + + case PD_PM_STATE_FC2_ENTRY_2: + pr_info("tune adapter volt %d , vbatt %d\n", pdpm->cp.vbus_volt, + pdpm->cp.vbat_volt); + if (pdpm->cp.vbus_volt < + (pdpm->cp.vbat_volt * 2 + BUS_VOLT_INIT_UP - 50)) { + tune_vbus_retry++; + pdpm->request_voltage += STEP_MV; + usbpd_select_pdo(pdpm->pd, pdpm->apdo_selected_pdo, + pdpm->request_voltage * 1000, + pdpm->request_current * 1000); + } else if (pdpm->cp.vbus_volt > + (pdpm->cp.vbat_volt * 2 + BUS_VOLT_INIT_UP + 200)) { + tune_vbus_retry++; + pdpm->request_voltage -= STEP_MV; + usbpd_select_pdo(pdpm->pd, pdpm->apdo_selected_pdo, + pdpm->request_voltage * 1000, + pdpm->request_current * 1000); + } else { + pr_info("adapter volt tune ok, retry %d times\n", + tune_vbus_retry); + usbpd_pm_move_state(pdpm, PD_PM_STATE_FC2_ENTRY_3); + break; + } + + if (tune_vbus_retry > 60) { + if (retry_count < 1) { + usbpd_pm_move_state(pdpm, + PD_PM_STATE_FC2_ENTRY_1); + retry_count++; + pr_info("Failed to tune adapter volt into valid range, retry again\n"); + } else { + pr_info("Failed to tune adapter volt into valid range, charge with switching charger\n"); + usbpd_pm_move_state(pdpm, PD_PM_STATE_FC2_EXIT); + } + } + break; + + case PD_PM_STATE_FC2_ENTRY_3: + + if (pm_config.cp_sec_enable && !pdpm->cp_sec.charge_enabled) { + usbpd_pm_enable_cp_sec(pdpm, true); + msleep(30); + usbpd_pm_check_cp_sec_enabled(pdpm); + } + + if (!pdpm->cp.charge_enabled) { + usbpd_pm_enable_cp(pdpm, true); + msleep(30); + usbpd_pm_check_cp_enabled(pdpm); + } + + if (pdpm->cp.charge_enabled) { + if (pm_config.fc2_disable_sw) { + if (pdpm->sw.charge_enabled) { + usbpd_pm_enable_sw(pdpm, false); + usbpd_pm_update_sw_status(pdpm); + } + } + if ((pm_config.cp_sec_enable && + pdpm->cp_sec.charge_enabled) || + !pm_config.cp_sec_enable) { + usbpd_pm_move_state(pdpm, PD_PM_STATE_FC2_TUNE); + ibus_lmt_change_timer = 0; + fc2_taper_timer = 0; + } + } + break; + + case PD_PM_STATE_FC2_TUNE: +#if 0 + if (pdpm->cp.vbat_volt < pm_config.min_vbat_for_cp - 400) { + usbpd_pm_move_state(PD_PM_STATE_SW_ENTRY); + break; + } +#endif + usbpd_update_pps_status(pdpm); + + ret = usbpd_pm_fc2_charge_algo(pdpm); + if (ret == PM_ALGO_RET_THERM_FAULT) { + pr_info("Move to stop charging:%d\n", ret); + stop_sw = true; + usbpd_pm_move_state(pdpm, PD_PM_STATE_FC2_EXIT); + break; + } else if (ret == PM_ALGO_RET_OTHER_FAULT || + ret == PM_ALGO_RET_TAPER_DONE) { + pr_info("Move to switch charging:%d\n", ret); + usbpd_pm_move_state(pdpm, PD_PM_STATE_FC2_EXIT); + break; + } else if (ret == PM_ALGO_RET_CHG_DISABLED) { + pr_info("Move to switch charging, will try to recover flash charging:%d\n", + ret); + recover = true; + usbpd_pm_move_state(pdpm, PD_PM_STATE_FC2_EXIT); + break; + } else if (ret == PM_ALGO_RET_SLOWLY_CHARGING) { + recover = true; + pr_info("Slow Charging Feature is running %d\n", ret); + usbpd_pm_move_state(pdpm, PD_PM_STATE_FC2_EXIT); + } else { + usbpd_select_pdo(pdpm->pd, pdpm->apdo_selected_pdo, + pdpm->request_voltage * 1000, + pdpm->request_current * 1000); + pr_info("request_voltage:%d, request_current:%d\n", + pdpm->request_voltage, pdpm->request_current); + } + /*stop second charge pump if either of ibus is lower than 400ma during CV*/ + if (pm_config.cp_sec_enable && pdpm->cp_sec.charge_enabled && + pdpm->cp.vbat_volt > + pm_config.bat_volt_lp_lmt - TAPER_WITH_IBUS_HYS && + (pdpm->cp.ibus_curr < TAPER_IBUS_THR || + pdpm->cp_sec.ibus_curr < TAPER_IBUS_THR)) { + pr_info("second cp is disabled due to ibus < 450mA\n"); + usbpd_pm_enable_cp_sec(pdpm, false); + usbpd_pm_check_cp_sec_enabled(pdpm); + } + break; + + case PD_PM_STATE_FC2_EXIT: + /* select default 5V*/ + usbpd_select_pdo(pdpm->pd, 1, 0, 0); + if (pdpm->fcc_votable) + vote(pdpm->fcc_votable, BQ_TAPER_FCC_VOTER, false, 0); + + if (!stop_sw && + (!pdpm->sw.charge_enabled || pdpm->sw.charge_limited)) { + usbpd_pm_enable_sw(pdpm, true); + } + if (stop_sw && + (pdpm->sw.charge_enabled || pdpm->sw.charge_limited)) + usbpd_pm_enable_sw(pdpm, false); + usbpd_pm_update_sw_status(pdpm); + + if (pdpm->cp.charge_enabled) { + usbpd_pm_enable_cp(pdpm, false); + usbpd_pm_check_cp_enabled(pdpm); + } + + if (pm_config.cp_sec_enable && pdpm->cp_sec.charge_enabled) { + usbpd_pm_enable_cp_sec(pdpm, false); + usbpd_pm_check_cp_sec_enabled(pdpm); + } + + if (recover) + usbpd_pm_move_state(pdpm, PD_PM_STATE_ENTRY); + else + rc = 1; + + break; + default: + usbpd_pm_move_state(pdpm, PD_PM_STATE_ENTRY); + break; + } + + return rc; +} + +static void usbpd_pm_workfunc(struct work_struct *work) +{ + struct usbpd_pm *pdpm = + container_of(work, struct usbpd_pm, pm_work.work); + int internal = PM_WORK_RUN_NORMAL_INTERVAL; + + usbpd_pm_update_sw_status(pdpm); + usbpd_pm_update_cp_status(pdpm); + usbpd_pm_update_cp_sec_status(pdpm); + + pr_info("%s:pd_bat_volt_lp_lmt=%d, vbatt_now=%d\n", __func__, + pm_config.bat_volt_lp_lmt, pdpm->cp.vbat_volt); + + if (!usbpd_pm_sm(pdpm) && pdpm->pd_active) { + if (pdpm->state == PD_PM_STATE_FC2_ENTRY_2) + internal = PM_WORK_RUN_QUICK_INTERVAL; + else + internal = PM_WORK_RUN_NORMAL_INTERVAL; + + schedule_delayed_work(&pdpm->pm_work, + msecs_to_jiffies(internal)); + } +} + +static void usbpd_pm_disconnect(struct usbpd_pm *pdpm) +{ + union power_supply_propval pval = { + 0, + }; + + cancel_delayed_work_sync(&pdpm->pm_work); + + if (pdpm->fcc_votable) + vote(pdpm->fcc_votable, BQ_TAPER_FCC_VOTER, false, 0); + pdpm->pps_supported = false; + pdpm->jeita_triggered = false; + pdpm->is_temp_out_fc2_range = false; + pdpm->apdo_selected_pdo = 0; + memset(&pdpm->pdo, 0, sizeof(pdpm->pdo)); + pm_config.bat_curr_lp_lmt = pdpm->bat_curr_max; + if (!pdpm->sw.charge_enabled || pdpm->sw.charge_limited) { + usbpd_pm_enable_sw(pdpm, true); + usbpd_pm_check_sw_enabled(pdpm); + } + + pval.intval = 0; + power_supply_set_property(pdpm->usb_psy, POWER_SUPPLY_PROP_APDO_MAX, + &pval); + + usbpd_pm_enable_cp(pdpm, false); + + usbpd_pm_move_state(pdpm, PD_PM_STATE_ENTRY); +} + +static void usbpd_pd_contact(struct usbpd_pm *pdpm, bool connected) +{ + pdpm->pd_active = connected; + + pr_info("pd_active = %d\n", connected); + + if (connected) { + usbpd_pm_evaluate_src_caps(pdpm); + if (pdpm->pps_supported) + schedule_delayed_work(&pdpm->pm_work, 0); + } else { + usbpd_pm_disconnect(pdpm); + } +} + +static void usbpd_pps_non_verified_contact(struct usbpd_pm *pdpm, + bool connected) +{ + pdpm->pd_active = connected; + + pr_info("pd_active = %d\n", connected); + + if (connected) { + usbpd_pm_evaluate_src_caps(pdpm); + if (pdpm->pps_supported) + schedule_delayed_work(&pdpm->pm_work, 5 * HZ); + } else { + usbpd_pm_disconnect(pdpm); + } +} + +static void cp_psy_change_work(struct work_struct *work) +{ + struct usbpd_pm *pdpm = + container_of(work, struct usbpd_pm, cp_psy_change_work); +#if 0 + union power_supply_propval val = {0,}; + bool ac_pres = pdpm->cp.vbus_pres; + int ret; + + if (!pdpm->cp_psy) + return; + + ret = power_supply_get_property(pdpm->cp_psy, POWER_SUPPLY_PROP_TI_VBUS_PRESENT, &val); + if (!ret) + pdpm->cp.vbus_pres = val.intval; + + if (!ac_pres && pdpm->cp.vbus_pres) + schedule_delayed_work(&pdpm->pm_work, 0); +#endif + pdpm->psy_change_running = false; +} + +static void usb_psy_change_work(struct work_struct *work) +{ + struct usbpd_pm *pdpm = + container_of(work, struct usbpd_pm, usb_psy_change_work); + union power_supply_propval val = { + 0, + }; + union power_supply_propval pd_auth_val = { + 0, + }; + int ret = 0; + + ret = power_supply_get_property( + pdpm->usb_psy, POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &val); + if (ret) { + pr_err("Failed to read typec power role\n"); + goto out; + } + + if (val.intval != POWER_SUPPLY_TYPEC_PR_SINK && + val.intval != POWER_SUPPLY_TYPEC_PR_DUAL) + goto out; + + ret = power_supply_get_property(pdpm->usb_psy, + POWER_SUPPLY_PROP_PD_ACTIVE, &val); + if (ret) { + pr_err("Failed to get usb pd active state\n"); + goto out; + } + + ret = power_supply_get_property(pdpm->usb_psy, + POWER_SUPPLY_PROP_PD_AUTHENTICATION, + &pd_auth_val); + if (ret) { + pr_err("Failed to read typec power role\n"); + goto out; + } + + if (!pdpm->pd_active && (pd_auth_val.intval == 1) && + (val.intval == POWER_SUPPLY_PD_PPS_ACTIVE)) + usbpd_pd_contact(pdpm, true); + else if (!pdpm->pd_active && (val.intval == POWER_SUPPLY_PD_PPS_ACTIVE)) + usbpd_pps_non_verified_contact(pdpm, true); + else if (pdpm->pd_active && !val.intval) + usbpd_pd_contact(pdpm, false); +out: + pdpm->psy_change_running = false; +} + +static int usbpd_psy_notifier_cb(struct notifier_block *nb, unsigned long event, + void *data) +{ + struct usbpd_pm *pdpm = container_of(nb, struct usbpd_pm, nb); + struct power_supply *psy = data; + unsigned long flags; + + if (event != PSY_EVENT_PROP_CHANGED) + return NOTIFY_OK; + + usbpd_check_cp_psy(pdpm); + usbpd_check_usb_psy(pdpm); + + if (!pdpm->cp_psy || !pdpm->usb_psy) + return NOTIFY_OK; + + if (psy == pdpm->cp_psy || psy == pdpm->usb_psy) { + spin_lock_irqsave(&pdpm->psy_change_lock, flags); + if (!pdpm->psy_change_running) { + pdpm->psy_change_running = true; + if (psy == pdpm->cp_psy) + schedule_work(&pdpm->cp_psy_change_work); + else + schedule_work(&pdpm->usb_psy_change_work); + } + spin_unlock_irqrestore(&pdpm->psy_change_lock, flags); + } + + return NOTIFY_OK; +} + +static int pd_policy_parse_dt(struct usbpd_pm *pdpm) +{ + struct device_node *node = pdpm->dev->of_node; + int rc = 0; + + if (!node) { + pr_err("device tree node missing\n"); + return -EINVAL; + } + + rc = of_property_read_u32(node, "mi,pd-bat-volt-max", + &pdpm->bat_volt_max); + if (rc < 0) + pr_err("pd-bat-volt-max property missing, use default val\n"); + else + pm_config.bat_volt_lp_lmt = pdpm->bat_volt_max; + pr_info("pm_config.bat_volt_lp_lmt:%d\n", pm_config.bat_volt_lp_lmt); + + rc = of_property_read_u32(node, "mi,pd-bat-curr-max", + &pdpm->bat_curr_max); + if (rc < 0) + pr_err("pd-bat-curr-max property missing, use default val\n"); + else + pm_config.bat_curr_lp_lmt = pdpm->bat_curr_max; + pr_info("pm_config.bat_curr_lp_lmt:%d\n", pm_config.bat_curr_lp_lmt); + + rc = of_property_read_u32(node, "mi,pd-bus-volt-max", + &pdpm->bus_volt_max); + if (rc < 0) + pr_err("pd-bus-volt-max property missing, use default val\n"); + else + pm_config.bus_volt_lp_lmt = pdpm->bus_volt_max; + pr_info("pm_config.bus_volt_lp_lmt:%d\n", pm_config.bus_volt_lp_lmt); + + rc = of_property_read_u32(node, "mi,pd-bus-curr-max", + &pdpm->bus_curr_max); + if (rc < 0) + pr_err("pd-bus-curr-max property missing, use default val\n"); + else + pm_config.bus_curr_lp_lmt = pdpm->bus_curr_max; + pr_info("pm_config.bus_curr_lp_lmt:%d\n", pm_config.bus_curr_lp_lmt); + + rc = of_property_read_u32(node, "mi,pd-bus-curr-compensate", + &pdpm->bus_curr_compensate); + if (rc < 0) + pr_err("pd-bus-curr-compensate property missing, use default val\n"); + else + pm_config.bus_curr_compensate = pdpm->bus_curr_compensate; + pr_info("pm_config.bus_curr_compensate:%d\n", + pm_config.bus_curr_compensate); + + pdpm->cp_sec_enable = of_property_read_bool(node, "mi,cp-sec-enable"); + pm_config.cp_sec_enable = pdpm->cp_sec_enable; + + rc = of_property_read_u32(node, "mi,pd-ffc-bat-volt-max", + &pdpm->ffc_bat_volt_max); + pr_info("pdpm->ffc_bat_volt_max:%d\n", pdpm->ffc_bat_volt_max); + + return rc; +} + +static int usbpd_pm_probe(struct platform_device *pdev) +{ + int ret = 0; + struct device *dev = &pdev->dev; + struct usbpd_pm *pdpm; + + pr_info("%s enter\n", __func__); + + pdpm = kzalloc(sizeof(struct usbpd_pm), GFP_KERNEL); + if (!pdpm) + return -ENOMEM; + + __pdpm = pdpm; + + pdpm->dev = dev; + + ret = pd_policy_parse_dt(pdpm); + if (ret < 0) { + pr_err("Couldn't parse device tree rc=%d\n", ret); + return ret; + } + + platform_set_drvdata(pdev, pdpm); + + spin_lock_init(&pdpm->psy_change_lock); + + usbpd_check_cp_psy(pdpm); + usbpd_check_cp_sec_psy(pdpm); + usbpd_check_usb_psy(pdpm); + + INIT_WORK(&pdpm->cp_psy_change_work, cp_psy_change_work); + INIT_WORK(&pdpm->usb_psy_change_work, usb_psy_change_work); + INIT_DELAYED_WORK(&pdpm->pm_work, usbpd_pm_workfunc); + + pdpm->nb.notifier_call = usbpd_psy_notifier_cb; + power_supply_reg_notifier(&pdpm->nb); + + return ret; +} + +static int usbpd_pm_remove(struct platform_device *pdev) +{ + power_supply_unreg_notifier(&__pdpm->nb); + cancel_delayed_work(&__pdpm->pm_work); + cancel_work(&__pdpm->cp_psy_change_work); + cancel_work(&__pdpm->usb_psy_change_work); + + return 0; +} + +static const struct of_device_id usbpd_pm_of_match[] = { + { + .compatible = "xiaomi,usbpd-pm", + }, + {}, +}; + +static struct platform_driver usbpd_pm_driver = { + .driver = { + .name = "usbpd-pm", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(usbpd_pm_of_match), + }, + .probe = usbpd_pm_probe, + .remove = usbpd_pm_remove, +}; + +static int __init usbpd_pm_init(void) +{ + return platform_driver_register(&usbpd_pm_driver); +} + +late_initcall(usbpd_pm_init); + +static void __exit usbpd_pm_exit(void) +{ + return platform_driver_unregister(&usbpd_pm_driver); +} +module_exit(usbpd_pm_exit); + +MODULE_AUTHOR("Fei Jiang"); +MODULE_DESCRIPTION("Xiaomi usb pd statemachine for bq"); +MODULE_LICENSE("GPL"); diff --git a/drivers/power/supply/ti/pd_policy_manager.h b/drivers/power/supply/ti/pd_policy_manager.h new file mode 100644 index 000000000000..465e0b66db14 --- /dev/null +++ b/drivers/power/supply/ti/pd_policy_manager.h @@ -0,0 +1,237 @@ +/* + * usb_pd_policy_manager.h + * + * Created on: Mar 27, 2017 + * Author: a0220433 + */ + +#ifndef SRC_PDLIB_USB_PD_POLICY_MANAGER_H_ +#define SRC_PDLIB_USB_PD_POLICY_MANAGER_H_ +#include +#include +#include +#include +#include +#include +#include + +enum pm_state { + PD_PM_STATE_ENTRY, + PD_PM_STATE_FC2_ENTRY, + PD_PM_STATE_FC2_ENTRY_1, + PD_PM_STATE_FC2_ENTRY_2, + PD_PM_STATE_FC2_ENTRY_3, + PD_PM_STATE_FC2_TUNE, + PD_PM_STATE_FC2_EXIT, +}; + +#define BAT_OVP_FAULT_SHIFT 0 +#define BAT_OCP_FAULT_SHIFT 1 +#define BUS_OVP_FAULT_SHIFT 2 +#define BUS_OCP_FAULT_SHIFT 3 +#define BAT_THERM_FAULT_SHIFT 4 +#define BUS_THERM_FAULT_SHIFT 5 +#define DIE_THERM_FAULT_SHIFT 6 + +#define BAT_OVP_FAULT_MASK (1 << BAT_OVP_FAULT_SHIFT) +#define BAT_OCP_FAULT_MASK (1 << BAT_OCP_FAULT_SHIFT) +#define BUS_OVP_FAULT_MASK (1 << BUS_OVP_FAULT_SHIFT) +#define BUS_OCP_FAULT_MASK (1 << BUS_OCP_FAULT_SHIFT) +#define BAT_THERM_FAULT_MASK (1 << BAT_THERM_FAULT_SHIFT) +#define BUS_THERM_FAULT_MASK (1 << BUS_THERM_FAULT_SHIFT) +#define DIE_THERM_FAULT_MASK (1 << DIE_THERM_FAULT_SHIFT) + +#define BAT_OVP_ALARM_SHIFT 0 +#define BAT_OCP_ALARM_SHIFT 1 +#define BUS_OVP_ALARM_SHIFT 2 +#define BUS_OCP_ALARM_SHIFT 3 +#define BAT_THERM_ALARM_SHIFT 4 +#define BUS_THERM_ALARM_SHIFT 5 +#define DIE_THERM_ALARM_SHIFT 6 +#define BAT_UCP_ALARM_SHIFT 7 + +#define BAT_OVP_ALARM_MASK (1 << BAT_OVP_ALARM_SHIFT) +#define BAT_OCP_ALARM_MASK (1 << BAT_OCP_ALARM_SHIFT) +#define BUS_OVP_ALARM_MASK (1 << BUS_OVP_ALARM_SHIFT) +#define BUS_OCP_ALARM_MASK (1 << BUS_OCP_ALARM_SHIFT) +#define BAT_THERM_ALARM_MASK (1 << BAT_THERM_ALARM_SHIFT) +#define BUS_THERM_ALARM_MASK (1 << BUS_THERM_ALARM_SHIFT) +#define DIE_THERM_ALARM_MASK (1 << DIE_THERM_ALARM_SHIFT) +#define BAT_UCP_ALARM_MASK (1 << BAT_UCP_ALARM_SHIFT) + +#define VBAT_REG_STATUS_SHIFT 0 +#define IBAT_REG_STATUS_SHIFT 1 + +#define VBAT_REG_STATUS_MASK (1 << VBAT_REG_STATUS_SHIFT) +#define IBAT_REG_STATUS_MASK (1 << VBAT_REG_STATUS_SHIFT) + +/* voters for usbpd */ +#define STEP_BMS_CHG_VOTER "STEP_BMS_CHG_VOTER" +#define BQ_TAPER_FCC_VOTER "BQ_TAPER_FCC_VOTER" + +/* defined for non_verified pps charger maxium fcc */ +#define NON_VERIFIED_PPS_FCC_MAX 3000 +#define MAX_THERMAL_LEVEL 13 +/* jeita related */ +#define JEITA_WARM_THR 450 +#define JEITA_COOL_NOT_ALLOW_CP_THR 100 +#define PDO_MAX_NUM 7 +/* + * add hysteresis for warm threshold to avoid flash + * charge and normal charge switch frequently at + * the warm threshold + */ +#define JEITA_HYSTERESIS 20 +/* product related */ +#define LOW_POWER_PPS_CURR_THR 2000 +#define XIAOMI_LOW_POWER_PPS_CURR_MAX 1500 +#define XIAOMI_LOW_POWER_PPS_CURR_MAX 1500 +#define PPS_VOL_MAX 11000 +#define PPS_VOL_HYS 1000 + +#define STEP_MV 20 +#define TAPER_VOL_HYS 80 +#define TAPER_WITH_IBUS_HYS 60 +#define TAPER_IBUS_THR 450 +#define BQ_TAPER_HYS_MV 10 +#define BQ_TAPER_DECREASE_STEP_MA 200 +struct sw_device { + bool charge_enabled; + bool charge_limited; + bool slowly_charging; +}; + +struct usbpd_pdo { + bool pps; + int type; + int max_volt_mv; + int min_volt_mv; + int curr_ma; + int pos; +}; + +struct cp_device { + bool charge_enabled; + + bool batt_pres; + bool vbus_pres; + + /* alarm/fault status */ + bool bat_ovp_fault; + bool bat_ocp_fault; + bool bus_ovp_fault; + bool bus_ocp_fault; + + bool bat_ovp_alarm; + bool bat_ocp_alarm; + bool bus_ovp_alarm; + bool bus_ocp_alarm; + + bool bat_ucp_alarm; + + bool bat_therm_alarm; + bool bus_therm_alarm; + bool die_therm_alarm; + + bool bat_therm_fault; + bool bus_therm_fault; + bool die_therm_fault; + + bool therm_shutdown_flag; + bool therm_shutdown_stat; + + bool vbat_reg; + bool ibat_reg; + + int vout_volt; + int vbat_volt; + int vbus_volt; + int ibat_curr; + int ibus_curr; + + int bat_temp; + int bus_temp; + int die_temp; +}; + +#define PM_STATE_LOG_MAX 32 +struct usbpd_pm { + struct device *dev; + + enum pm_state state; + + struct cp_device cp; + struct cp_device cp_sec; + + struct sw_device sw; + + bool pd_active; + bool pps_supported; + + int request_voltage; + int request_current; + + struct usbpd *pd; + struct usbpd_pdo pdo[7]; + + int apdo_max_volt; + int apdo_max_curr; + int apdo_selected_pdo; + + int adapter_voltage; + int adapter_current; + int adapter_ptf; + bool adapter_omf; + struct delayed_work pm_work; + + struct notifier_block nb; + + bool psy_change_running; + struct work_struct cp_psy_change_work; + struct work_struct usb_psy_change_work; + spinlock_t psy_change_lock; + + struct votable *fcc_votable; + struct power_supply *cp_psy; + struct power_supply *cp_sec_psy; + struct power_supply *sw_psy; + struct power_supply *usb_psy; + struct power_supply *bms_psy; + + /* dtsi properties */ + int bat_volt_max; + int ffc_bat_volt_max; + int bat_curr_max; + int bus_volt_max; + int bus_curr_max; + int bus_curr_compensate; + bool cp_sec_enable; + /* jeita or thermal related */ + bool jeita_triggered; + bool is_temp_out_fc2_range; +}; + +struct pdpm_config { + int bat_volt_lp_lmt; /*bat volt loop limit*/ + int bat_curr_lp_lmt; + int bus_volt_lp_lmt; + int bus_curr_lp_lmt; + int bus_curr_compensate; + + int fc2_taper_current; + int fc2_steps; + + int min_adapter_volt_required; + int min_adapter_curr_required; + int min_vbat_for_cp; + + bool cp_sec_enable; + bool fc2_disable_sw; /* disable switching charger during flash charge*/ +}; + +extern int usbpd_get_pps_status(struct usbpd *pd, u32 *status); +extern int usbpd_fetch_pdo(struct usbpd *pd, struct usbpd_pdo *pdos); +extern int usbpd_select_pdo(struct usbpd *pd, int pdo, int uv, int ua); +extern struct usbpd *smb_get_usbpd(void); + +#endif /* SRC_PDLIB_USB_PD_POLICY_MANAGER_H_ */ diff --git a/include/linux/power/ln8282.h b/include/linux/power/ln8282.h new file mode 100644 index 000000000000..39dd30b8d1f0 --- /dev/null +++ b/include/linux/power/ln8282.h @@ -0,0 +1,40 @@ +/* + * LIONSEMI LN8282 voltage regulator driver + * + * 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 _LN8282_REGULATOR_H_ +#define _LN8282_REGULATOR_H_ + +enum { + LN8282_OPMODE_UNKNOWN = -1, + LN8282_OPMODE_STANDBY = 0, + LN8282_OPMODE_BYPASS = 1, + LN8282_OPMODE_SWITCHING = 2, + LN8282_OPMODE_SWITCHING_ALT = 3, +}; + +struct ln8282_info; + +void ln8282_use_ext_5V(struct ln8282_info *info, unsigned int enable); +void ln8282_set_infet(struct ln8282_info *info, unsigned int enable); +void ln8282_set_powerpath(struct ln8282_info *info, bool forward_path); +bool ln8282_change_opmode(struct ln8282_info *info, unsigned int target_mode); +int ln8282_hw_init(struct ln8282_info *info); +/*add for other module run*/ +/* +void ln8282_set_powerpath_ext(bool forward_path); +bool ln8282_change_opmode_ext(unsigned int target_mode); +unsigned int ln8282_get_opmode_ext(void); +*/ + +#endif From 982e22f12d3df2a529d55ce25bcda0882a2b1137 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Thu, 8 Jul 2021 15:19:41 +0200 Subject: [PATCH 084/226] drivers: power: supply: maxim: Extract S_secret from vayu stock kernel `cat /sys/devices/platform/soc/soc:maxim_ds28e16/ds_S_secret` Change-Id: I1d33a55e38b197aec5a36b2253eaece33996afbb Signed-off-by: firebird11 --- drivers/power/supply/maxim/ds28e16.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/power/supply/maxim/ds28e16.c b/drivers/power/supply/maxim/ds28e16.c index 2947b5b361c8..c3df48f55b4d 100644 --- a/drivers/power/supply/maxim/ds28e16.c +++ b/drivers/power/supply/maxim/ds28e16.c @@ -55,10 +55,10 @@ unsigned char session_seed[32] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA }; -unsigned char S_secret[32] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, - 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, - 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, - 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA }; +unsigned char S_secret[32] = { 0x0C, 0x99, 0x2B, 0xD3, 0x95, 0xDB, 0xA0, 0xB4, + 0xEF, 0x07, 0xB3, 0xD8, 0x75, 0xF3, 0xC7, 0xAE, + 0xDA, 0xC4, 0x41, 0x2F, 0x48, 0x93, 0xB5, 0xD9, + 0xE1, 0xE5, 0x4B, 0x20, 0x9B, 0xF3, 0x77, 0x39 }; unsigned char challenge[32] = { 0x00 }; int auth_ANON = 1; int auth_BDCONST = 1; @@ -633,9 +633,9 @@ int DS28E16_cmd_device_disable(int op, unsigned char *password) /// 'Compute and Read Page Authentication' command /// /// @param[in] anon - boolean parameter -/// @param[in] pg - Page number 2,计数å™? 0,page0; 1,page1; +/// @param[in] pg - Page number 2,计数�? 0,page0; 1,page1; /// @param[in] challenge -/// @param[out] hmac 返回的计算结æž?2个字èŠ?/// +/// @param[out] hmac 返回的计算结�?2个字�?/// /// @return /// DS_TRUE - command successful @n /// DS_FALSE - command failed From 115340ebd4d89eec627e9a06d4757ec3cb2b2895 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Tue, 12 Jul 2022 23:51:13 +0200 Subject: [PATCH 085/226] drivers: power: supply: qcom: rx1619: Extract firmware from crux stock kernel Change-Id: Ib3aa8c7a853d04180c1f101d09f6ab30031155fe Signed-off-by: firebird11 --- drivers/power/supply/nuvolta/rx1619.h | 4888 ++++++++++++------------- 1 file changed, 2444 insertions(+), 2444 deletions(-) diff --git a/drivers/power/supply/nuvolta/rx1619.h b/drivers/power/supply/nuvolta/rx1619.h index 8791019582fe..c076f24135ee 100644 --- a/drivers/power/supply/nuvolta/rx1619.h +++ b/drivers/power/supply/nuvolta/rx1619.h @@ -1,6 +1,6 @@ u8 chip_default_data[2] = { 0x47, 0x10 }; -//J2 fw version 0x15 +// Extracted from stock kernel - crux V13.0.1.0.RFXCNXM u8 fw_data_boot[1016] = { 0xff, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, @@ -86,725 +86,478 @@ u8 fw_data_boot[1016] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xb1, 0xaa, 0xe9, 0xe6, 0xdf, 0xb5, 0xcd, 0xea + 0xb1, 0xaa, 0xe9, 0xe6, 0xbd, 0xb0, 0xab, 0xb0 }; u8 fw_data_tx[13304] = { - 0xff, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, - 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, - 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, 0x93, 0xb2, 0xff, 0xff, - 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, - 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, 0x9b, 0xb2, 0xff, 0xff, - 0x9b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, - 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, - 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, - 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, - 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, - 0x8b, 0xb2, 0xff, 0xff, 0x8b, 0xb2, 0xff, 0xff, 0x63, 0x8b, 0xff, 0xff, - 0xff, 0x8a, 0xff, 0xff, 0x4f, 0x8b, 0xff, 0xff, 0x2b, 0x8b, 0xff, 0xff, - 0x23, 0x8b, 0xff, 0xff, 0xeb, 0x8a, 0xff, 0xff, 0xe3, 0x8a, 0xff, 0xff, - 0x1b, 0x8b, 0xff, 0xff, 0x13, 0x8b, 0xff, 0xff, 0xcb, 0x8a, 0xff, 0xff, - 0x9f, 0x8a, 0xff, 0xff, 0x97, 0x8a, 0xff, 0xff, 0x8f, 0x8a, 0xff, 0xff, - 0x3b, 0x8b, 0xff, 0xff, 0x33, 0x8b, 0xff, 0xff, 0x87, 0x8a, 0xff, 0xff, - 0x7f, 0x8a, 0xff, 0xff, 0x77, 0x8a, 0xff, 0xff, 0x5b, 0x8a, 0xff, 0xff, - 0x53, 0x8a, 0xff, 0xff, 0x4b, 0x8a, 0xff, 0xff, 0x43, 0x8a, 0xff, 0xff, - 0x3b, 0x8a, 0xff, 0xff, 0x33, 0x8a, 0xff, 0xff, 0x2b, 0x8a, 0xff, 0xff, - 0x23, 0x8a, 0xff, 0xff, 0x23, 0x8a, 0xff, 0xff, 0x23, 0x8a, 0xff, 0xff, - 0x23, 0x8a, 0xff, 0xff, 0x23, 0x8a, 0xff, 0xff, 0x23, 0x8a, 0xff, 0xff, - 0x23, 0x8a, 0xff, 0xff, 0x8e, 0xef, 0xfc, 0x3f, 0xdf, 0x9b, 0xae, 0xef, + 0x4f, 0xb1, 0xff, 0xff, 0xeb, 0xb0, 0xff, 0xff, 0xeb, 0xb0, 0xff, 0xff, + 0xeb, 0xb0, 0xff, 0xff, 0xeb, 0xb0, 0xff, 0xff, 0xeb, 0xb0, 0xff, 0xff, + 0xeb, 0xb0, 0xff, 0xff, 0xeb, 0xb0, 0xff, 0xff, 0xe3, 0xb0, 0xff, 0xff, + 0xeb, 0xb0, 0xff, 0xff, 0xeb, 0xb0, 0xff, 0xff, 0xeb, 0xb0, 0xff, 0xff, + 0xeb, 0xb0, 0xff, 0xff, 0xeb, 0xb0, 0xff, 0xff, 0xeb, 0xb0, 0xff, 0xff, + 0xeb, 0xb0, 0xff, 0xff, 0xdb, 0xb0, 0xff, 0xff, 0xdb, 0xb0, 0xff, 0xff, + 0xdb, 0xb0, 0xff, 0xff, 0xdb, 0xb0, 0xff, 0xff, 0xdb, 0xb0, 0xff, 0xff, + 0xdb, 0xb0, 0xff, 0xff, 0xdb, 0xb0, 0xff, 0xff, 0xdb, 0xb0, 0xff, 0xff, + 0xdb, 0xb0, 0xff, 0xff, 0xdb, 0xb0, 0xff, 0xff, 0xdb, 0xb0, 0xff, 0xff, + 0xdb, 0xb0, 0xff, 0xff, 0xdb, 0xb0, 0xff, 0xff, 0xdb, 0xb0, 0xff, 0xff, + 0xdb, 0xb0, 0xff, 0xff, 0xdb, 0xb0, 0xff, 0xff, 0xcf, 0x96, 0xff, 0xff, + 0x6b, 0x96, 0xff, 0xff, 0xbb, 0x96, 0xff, 0xff, 0x97, 0x96, 0xff, 0xff, + 0x8f, 0x96, 0xff, 0xff, 0x57, 0x96, 0xff, 0xff, 0x4f, 0x96, 0xff, 0xff, + 0x87, 0x96, 0xff, 0xff, 0x7f, 0x96, 0xff, 0xff, 0x2f, 0x96, 0xff, 0xff, + 0xff, 0x95, 0xff, 0xff, 0xf7, 0x95, 0xff, 0xff, 0xef, 0x95, 0xff, 0xff, + 0xa7, 0x96, 0xff, 0xff, 0x9f, 0x96, 0xff, 0xff, 0xe7, 0x95, 0xff, 0xff, + 0xdf, 0x95, 0xff, 0xff, 0xd7, 0x95, 0xff, 0xff, 0xbb, 0x95, 0xff, 0xff, + 0xb3, 0x95, 0xff, 0xff, 0xab, 0x95, 0xff, 0xff, 0xa3, 0x95, 0xff, 0xff, + 0x9b, 0x95, 0xff, 0xff, 0x93, 0x95, 0xff, 0xff, 0x8b, 0x95, 0xff, 0xff, + 0x83, 0x95, 0xff, 0xff, 0x83, 0x95, 0xff, 0xff, 0x83, 0x95, 0xff, 0xff, + 0x83, 0x95, 0xff, 0xff, 0x83, 0x95, 0xff, 0xff, 0x83, 0x95, 0xff, 0xff, + 0x83, 0x95, 0xff, 0xff, 0x2f, 0xeb, 0xff, 0x8b, 0xff, 0x1f, 0x29, 0xef, + 0x6f, 0xeb, 0xff, 0xff, 0x2e, 0xeb, 0xfc, 0x92, 0xff, 0x7f, 0xbf, 0xc7, + 0xf8, 0xf3, 0xff, 0xdb, 0x00, 0x1c, 0x0b, 0x00, 0xff, 0x7b, 0xbf, 0xc7, + 0x04, 0xf4, 0x6e, 0xeb, 0x2b, 0xeb, 0xd7, 0xeb, 0xff, 0x47, 0x3a, 0x8a, + 0x77, 0x8b, 0xbd, 0x47, 0x33, 0x8b, 0x9e, 0x47, 0xff, 0xcd, 0xfc, 0xe4, + 0xac, 0x5c, 0x20, 0xc7, 0xfb, 0xf3, 0xff, 0xca, 0x5e, 0xa2, 0xfd, 0xfb, + 0x5f, 0x67, 0xff, 0xc9, 0x71, 0x1b, 0xe1, 0xff, 0x20, 0x8a, 0xff, 0xd3, + 0xe8, 0x93, 0xa0, 0x93, 0xff, 0x1f, 0x25, 0xee, 0x8b, 0xed, 0xf3, 0xa7, + 0x9f, 0x7f, 0x9f, 0x5b, 0xff, 0xd9, 0x67, 0x8a, 0xe8, 0x93, 0xa0, 0x93, + 0xff, 0x1f, 0x55, 0xee, 0xbc, 0x92, 0xbf, 0xc7, 0x10, 0xf4, 0x6c, 0x93, + 0x9e, 0x67, 0xbf, 0xc4, 0xec, 0xf3, 0x27, 0x9b, 0xee, 0xf7, 0x26, 0xa4, + 0x67, 0x8a, 0xbf, 0xc1, 0xf2, 0xf3, 0xff, 0xd1, 0x67, 0x8a, 0x9c, 0xa3, + 0x86, 0xa4, 0xdd, 0x67, 0xff, 0xd3, 0xdf, 0x5b, 0x2d, 0x9b, 0x02, 0xf4, + 0x39, 0x3b, 0x7b, 0xdb, 0x6f, 0xa5, 0x9f, 0x67, 0x20, 0xc4, 0xfb, 0xf3, + 0xff, 0xd3, 0xd2, 0xcc, 0x9f, 0x5b, 0xec, 0x93, 0x00, 0x1c, 0x4f, 0x00, + 0xf7, 0xeb, 0x6b, 0xeb, 0xdb, 0xeb, 0x9c, 0x47, 0xbd, 0x47, 0xde, 0x47, + 0xff, 0x47, 0x2b, 0xeb, 0xde, 0xeb, 0x79, 0x67, 0xff, 0x7b, 0xbf, 0xc7, + 0x99, 0xf3, 0xf8, 0xe1, 0xff, 0xca, 0xdf, 0xcd, 0xbf, 0x47, 0xda, 0xc8, + 0x3d, 0x9a, 0xfb, 0xf3, 0x00, 0x1c, 0x6b, 0x00, 0xa7, 0xfb, 0xff, 0xdb, + 0x9f, 0x7b, 0xcf, 0xcd, 0x71, 0x9b, 0xfc, 0xf7, 0xff, 0xdb, 0xbf, 0x47, + 0xff, 0x7b, 0x9f, 0x1b, 0xd0, 0xef, 0x33, 0x8b, 0xf6, 0xc4, 0xf1, 0xf7, + 0xf6, 0xcd, 0x9c, 0xba, 0x5c, 0x3b, 0xda, 0xf7, 0x5f, 0xa2, 0xd0, 0xd2, + 0xff, 0xdb, 0xff, 0x7b, 0x9f, 0x1b, 0xd0, 0xef, 0x33, 0x8b, 0x37, 0x9b, + 0x0a, 0xf4, 0x9f, 0x1b, 0x9d, 0xef, 0x73, 0x8b, 0xea, 0xc5, 0xc8, 0xf7, + 0x34, 0x93, 0xbb, 0xee, 0x9d, 0x3b, 0xbc, 0xf7, 0x9f, 0x6c, 0xf3, 0x87, + 0xfc, 0xd9, 0x90, 0xa1, 0xff, 0x6c, 0x2b, 0x8b, 0xf5, 0xce, 0xbf, 0x67, + 0x00, 0x1c, 0x87, 0x00, 0xd5, 0xfb, 0xfc, 0xd9, 0x90, 0xa1, 0xff, 0x6c, + 0x2b, 0x8b, 0xf7, 0xce, 0xbf, 0x67, 0x00, 0x1c, 0x90, 0x00, 0xde, 0xfb, + 0xfc, 0xd9, 0x90, 0xa1, 0xff, 0x6c, 0x2b, 0x8b, 0xf5, 0xce, 0xbf, 0x67, + 0x00, 0x1c, 0x99, 0x00, 0xe7, 0xfb, 0xfc, 0xd9, 0x90, 0xa1, 0xff, 0x6c, + 0x2b, 0x8b, 0xef, 0xce, 0xbf, 0x67, 0x00, 0x1c, 0xa2, 0x00, 0xf0, 0xfb, + 0xfc, 0xd9, 0x90, 0xa1, 0xff, 0x7c, 0x00, 0x1c, 0xba, 0x00, 0xf6, 0xfb, + 0xfc, 0xd9, 0x90, 0xa1, 0xff, 0x6c, 0x00, 0x1c, 0xba, 0x00, 0xfc, 0xfb, + 0x00, 0x1c, 0xc3, 0x00, 0xff, 0xdb, 0xff, 0x7b, 0xbf, 0xc7, 0x5e, 0xf4, + 0xfe, 0xeb, 0x11, 0x26, 0xfb, 0xdf, 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, + 0x7f, 0x67, 0xf6, 0xeb, 0xc3, 0x87, 0xff, 0xff, 0x2f, 0x8e, 0xff, 0xff, + 0x87, 0x8e, 0xff, 0xff, 0x8e, 0xef, 0xfc, 0x3f, 0xdf, 0x9b, 0xae, 0xef, 0xfd, 0x3f, 0xde, 0x9b, 0xcf, 0xef, 0x78, 0x90, 0x0f, 0xef, 0x2e, 0xef, 0x4e, 0xef, 0x63, 0x9a, 0xf8, 0xf7, 0x7f, 0x6a, 0x7f, 0x48, 0xfc, 0xda, 0xfc, 0xd8, 0x63, 0x9a, 0x04, 0xf0, 0x91, 0xef, 0xb1, 0xef, 0x71, 0x9f, 0xbd, 0xb5, 0xbf, 0xc5, 0xf8, 0xf3, 0xff, 0xce, 0xdf, 0x4c, 0xfc, 0xdc, - 0xff, 0xd5, 0xbf, 0xc5, 0x03, 0xf4, 0xff, 0x1f, 0x0a, 0xe9, 0xff, 0xfb, + 0xff, 0xd5, 0xbf, 0xc5, 0x03, 0xf4, 0xff, 0x1f, 0x60, 0xef, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0x7f, 0xff, 0xb3, 0xff, 0xff, 0x07, 0xfd, 0xff, 0xdf, - 0xff, 0xff, 0xff, 0xdf, 0xfb, 0xff, 0xff, 0xdf, 0x47, 0x82, 0xff, 0xff, - 0xfb, 0xff, 0xff, 0xdf, 0x7f, 0xfe, 0xff, 0xdf, 0xff, 0x1f, 0xa7, 0xec, - 0xff, 0x3f, 0xdf, 0xbf, 0xff, 0x1f, 0x89, 0xec, 0xff, 0x3f, 0xdf, 0xbf, - 0xff, 0x1f, 0xd1, 0xec, 0xff, 0x3f, 0xdf, 0xbf, 0xbf, 0xc6, 0xfc, 0xf7, - 0xff, 0x3f, 0xdf, 0xd3, 0xbf, 0xc7, 0xfd, 0xf7, 0xc3, 0x87, 0x3d, 0xeb, - 0xbc, 0x92, 0xba, 0x92, 0x1f, 0x38, 0x7f, 0xd7, 0xfc, 0xf3, 0xfd, 0x93, - 0xff, 0xdf, 0x1e, 0x38, 0x7f, 0xd7, 0xfc, 0xf3, 0xb9, 0x93, 0xff, 0xde, - 0xfe, 0xcd, 0x3c, 0x93, 0xfc, 0x3b, 0xbb, 0x83, 0x6f, 0x8f, 0xef, 0x8f, - 0x38, 0x93, 0xfc, 0x3b, 0xbb, 0x83, 0xff, 0xdb, 0x3c, 0x93, 0x2e, 0x8f, - 0xed, 0x92, 0xdf, 0xdb, 0x6f, 0x8f, 0xef, 0x8f, 0xbf, 0xc5, 0xf6, 0xf3, - 0xff, 0x3b, 0xdf, 0xb3, 0x32, 0x9f, 0xb3, 0x9b, 0xfd, 0xf3, 0x39, 0x9f, - 0x76, 0x9f, 0x06, 0xf0, 0xf4, 0x93, 0xb0, 0x93, 0xfa, 0x3b, 0xda, 0xb3, - 0xfa, 0xf3, 0xfd, 0x93, 0xff, 0xdf, 0xb9, 0x93, 0xff, 0xde, 0x7d, 0xeb, - 0xbf, 0xc6, 0xfc, 0xf7, 0xff, 0x3f, 0xdf, 0xd3, 0xbf, 0xc7, 0xfd, 0xf7, - 0xc3, 0x87, 0x3e, 0xeb, 0xfe, 0xcd, 0x3c, 0x93, 0xfc, 0x3b, 0xbb, 0x83, - 0x6f, 0x8f, 0xef, 0x8f, 0x38, 0x93, 0xfc, 0x3b, 0xbb, 0x83, 0xff, 0xdb, - 0x3c, 0x93, 0x2e, 0x8f, 0xed, 0x92, 0xdf, 0xdb, 0x6f, 0x8f, 0xef, 0x8f, - 0xbf, 0xc5, 0xf6, 0xf3, 0xff, 0x3b, 0xdf, 0xb3, 0x32, 0x9f, 0xb3, 0x9b, - 0xfd, 0xf3, 0x39, 0x9f, 0x76, 0x9f, 0x06, 0xf0, 0xf4, 0x93, 0xb0, 0x93, - 0x7e, 0xeb, 0xff, 0xff, 0xbf, 0xc6, 0xfc, 0xf7, 0xff, 0x3f, 0xdf, 0xd3, - 0xbf, 0xc7, 0xfd, 0xf7, 0xc3, 0x87, 0x7c, 0x93, 0xfd, 0x3b, 0xbc, 0x83, - 0xfe, 0xcd, 0x73, 0x8f, 0xf3, 0x8f, 0xff, 0xcc, 0xff, 0x3b, 0xdf, 0xb3, - 0x32, 0x9f, 0xb3, 0x9b, 0xfd, 0xf3, 0x39, 0x9f, 0x76, 0x9f, 0x06, 0xf0, - 0xf0, 0x93, 0xc3, 0x87, 0x2e, 0xeb, 0x61, 0xce, 0xc8, 0xbe, 0xfc, 0x92, - 0xff, 0x1f, 0x9d, 0xfe, 0x1f, 0x38, 0x7f, 0xd7, 0xfa, 0xf3, 0xec, 0x93, - 0xff, 0x1f, 0x59, 0xfe, 0x6e, 0xeb, 0x61, 0xce, 0xc8, 0xbe, 0xec, 0x93, - 0xff, 0x1f, 0x31, 0xff, 0xff, 0x1f, 0x61, 0xfe, 0x7f, 0xcc, 0x87, 0xbc, - 0xf3, 0xa7, 0x6e, 0xeb, 0x3b, 0xeb, 0xde, 0xeb, 0x7f, 0x6f, 0xfe, 0xca, - 0xeb, 0x9a, 0xba, 0xf7, 0x9f, 0x6e, 0x2b, 0x9b, 0x7b, 0xf7, 0xbb, 0xc3, - 0x69, 0xf3, 0xbb, 0xc4, 0x7f, 0xf3, 0xbd, 0xc4, 0xa5, 0xf3, 0xbd, 0xc3, - 0x83, 0xf3, 0x9c, 0x6f, 0x7d, 0x6f, 0x1d, 0x6e, 0x9f, 0x47, 0x82, 0xa3, - 0x1c, 0x38, 0x7f, 0xd7, 0x5c, 0x6e, 0x70, 0x92, 0x92, 0xf7, 0xc0, 0xc1, - 0xcf, 0xf3, 0xdf, 0xc4, 0x8e, 0xf7, 0xfe, 0xcc, 0x27, 0x8f, 0xff, 0xd4, - 0x3a, 0x3b, 0xb8, 0xbf, 0xb3, 0x96, 0xbf, 0xc2, 0xff, 0x3b, 0xfa, 0xfa, - 0xa3, 0x92, 0x9e, 0x6f, 0xde, 0x6e, 0xb1, 0x9b, 0xd8, 0xf3, 0xbf, 0xc4, - 0xb6, 0xf3, 0x3f, 0x67, 0x46, 0xa2, 0x1a, 0x38, 0x7f, 0xd7, 0xb6, 0xf7, - 0xff, 0xc9, 0x3e, 0x4d, 0x7d, 0x4d, 0x5c, 0x4d, 0x9c, 0xa2, 0xe7, 0xee, - 0x3f, 0x9b, 0xf6, 0xf3, 0x9d, 0x6d, 0x5e, 0xba, 0xdc, 0xa2, 0xbf, 0x9b, - 0xff, 0xd4, 0x03, 0xf4, 0x5c, 0x4d, 0x9d, 0x4d, 0xfc, 0xcc, 0x1a, 0x38, - 0x7f, 0xd7, 0x9f, 0x4d, 0xea, 0xf7, 0xf4, 0x93, 0xfe, 0xeb, 0x7b, 0xeb, - 0xe2, 0x9a, 0xc9, 0xf3, 0x9e, 0x6f, 0xde, 0x6e, 0xb1, 0x9b, 0xff, 0xca, - 0x24, 0xf4, 0x3f, 0x67, 0x47, 0xa2, 0x9e, 0x4d, 0x1a, 0x38, 0x7f, 0xd7, - 0xfc, 0xcc, 0x7d, 0x4d, 0x5c, 0x4d, 0x9f, 0x4d, 0x12, 0xf0, 0x9a, 0x1b, - 0xfe, 0xdf, 0x5e, 0xb2, 0xb3, 0x92, 0x9d, 0x6d, 0xff, 0xdc, 0xf4, 0x93, - 0x5c, 0x4d, 0x9d, 0x4d, 0xfe, 0xeb, 0x7b, 0xeb, 0xbd, 0xc3, 0x1e, 0xf4, - 0x9f, 0x4d, 0x3e, 0x6f, 0x3e, 0x4d, 0x9d, 0x6f, 0x9d, 0x4d, 0x3c, 0x6f, - 0x3c, 0x4d, 0x9e, 0x6f, 0xde, 0x6e, 0x3b, 0x97, 0x9e, 0x4d, 0xf4, 0x93, - 0x2b, 0xf8, 0x9f, 0x67, 0x4a, 0xa4, 0x1a, 0x38, 0x7f, 0xd7, 0x46, 0xf0, - 0xfe, 0xcc, 0x9e, 0x4d, 0xff, 0xcc, 0x4a, 0xa4, 0x7d, 0x4d, 0x5c, 0x4d, - 0x49, 0xf8, 0xff, 0xcc, 0xe0, 0x92, 0x9f, 0x47, 0x5c, 0xf8, 0xff, 0xc9, - 0x32, 0xa1, 0xc0, 0xc1, 0x3d, 0xf0, 0x6d, 0xf8, 0xf8, 0x93, 0xfe, 0xeb, - 0x7b, 0xeb, 0xbf, 0xc4, 0x66, 0xf0, 0x9f, 0x67, 0x3c, 0x3b, 0xb8, 0xbf, - 0xfe, 0xcc, 0x27, 0x8f, 0x67, 0xa3, 0xff, 0xd4, 0x3f, 0x67, 0x27, 0x97, - 0xbf, 0xc4, 0xff, 0x3b, 0xfc, 0xfa, 0x23, 0x93, 0x9f, 0x47, 0x75, 0xf8, - 0xbb, 0xc4, 0x56, 0xf4, 0xbe, 0x6f, 0x9e, 0x6e, 0x35, 0x9b, 0x5a, 0xf0, - 0xfd, 0xef, 0x5c, 0xf8, 0x01, 0x00, 0x00, 0xc0, 0xef, 0x83, 0xff, 0xff, - 0x2c, 0xeb, 0xd1, 0xeb, 0x3c, 0x93, 0xf3, 0xe1, 0xf2, 0xe7, 0xf7, 0xe2, - 0x9f, 0x4f, 0xfb, 0xe3, 0xdf, 0x49, 0xa8, 0x93, 0xff, 0x1f, 0x8b, 0xfe, - 0xe4, 0x93, 0xac, 0x93, 0xff, 0x1f, 0x8f, 0xfe, 0x44, 0x93, 0xac, 0x93, - 0xe8, 0x93, 0x00, 0x1c, 0xbe, 0x00, 0xff, 0x1f, 0xf8, 0xfe, 0xf1, 0xeb, - 0x6c, 0xeb, 0xff, 0xff, 0x2c, 0xeb, 0xd1, 0xeb, 0x3c, 0x93, 0xf3, 0xe1, - 0xf2, 0xe7, 0xf7, 0xe2, 0xfb, 0xe3, 0x9f, 0x4f, 0xdf, 0x49, 0xa8, 0x93, - 0xff, 0x1f, 0xa5, 0xfe, 0xe4, 0x93, 0xac, 0x93, 0xff, 0x1f, 0xa9, 0xfe, - 0x9e, 0x6b, 0x9c, 0x1b, 0xfe, 0xbf, 0x44, 0x93, 0xac, 0x93, 0xe8, 0x93, - 0x9e, 0x4b, 0x00, 0x1c, 0xdc, 0x00, 0xff, 0x1f, 0x16, 0xff, 0xf1, 0xeb, - 0x6c, 0xeb, 0xff, 0xff, 0x2b, 0xeb, 0xd5, 0xeb, 0x3c, 0x93, 0xf7, 0xe1, - 0xf6, 0xe7, 0xfb, 0xe3, 0x9f, 0x4f, 0xdf, 0x49, 0xac, 0x93, 0xff, 0x1f, - 0xc2, 0xfe, 0x84, 0x93, 0xe4, 0x93, 0xff, 0x1f, 0xc6, 0xfe, 0x9f, 0x6b, - 0xfe, 0xce, 0x3b, 0x9b, 0x84, 0x92, 0xc4, 0xf7, 0xbf, 0x67, 0x7b, 0x9b, - 0xb5, 0xf7, 0xde, 0x6b, 0xfe, 0x67, 0xbe, 0x93, 0xbb, 0xc4, 0xde, 0x4b, - 0xc8, 0xf3, 0xbd, 0xc4, 0xca, 0xf3, 0xbb, 0xc5, 0xbd, 0xf3, 0xbd, 0xc5, - 0xd5, 0xf3, 0xbd, 0x6b, 0x9d, 0x67, 0xb2, 0xa5, 0xdc, 0x67, 0x9c, 0x6b, - 0xb3, 0x9b, 0xbd, 0x4b, 0xe1, 0xf3, 0x7f, 0xcd, 0xe0, 0xcf, 0xa8, 0xbd, - 0xff, 0xca, 0xb3, 0x9b, 0xba, 0x3b, 0xd8, 0xdb, 0x3a, 0xa4, 0xfd, 0xf7, - 0x70, 0x92, 0xb3, 0x9b, 0xfd, 0xf3, 0xa0, 0x92, 0xff, 0xd7, 0xbf, 0xc7, - 0xbe, 0xb5, 0x9e, 0xb9, 0x0c, 0xf4, 0xba, 0x1b, 0x80, 0xdf, 0xbf, 0xce, - 0xb5, 0x9b, 0xe9, 0xf3, 0x5c, 0x4b, 0xec, 0x93, 0xff, 0x1f, 0x5f, 0xff, - 0xf5, 0xeb, 0x6b, 0xeb, 0xff, 0xd5, 0x9e, 0xbc, 0xbd, 0x4b, 0x1f, 0xf8, - 0xfb, 0xcc, 0x9f, 0x4b, 0xec, 0x93, 0xff, 0x1f, 0x6a, 0xff, 0xf5, 0xeb, - 0x6b, 0xeb, 0x71, 0x9b, 0x05, 0xf4, 0xf5, 0xef, 0x11, 0xf8, 0x1a, 0x3b, - 0x7f, 0xd7, 0x16, 0xf4, 0xbf, 0xc4, 0x18, 0xf0, 0x57, 0xa2, 0x5a, 0x1b, - 0x80, 0xcf, 0x1c, 0xf8, 0xc4, 0x93, 0x1c, 0xf8, 0xff, 0xcc, 0x9c, 0x4b, - 0x9d, 0x4b, 0xec, 0x93, 0x21, 0xf8, 0xff, 0xff, 0xef, 0x83, 0xff, 0xff, - 0x2c, 0xeb, 0xd5, 0xeb, 0x3c, 0x93, 0xf7, 0xe1, 0xf6, 0xe7, 0xfb, 0xe3, - 0x9f, 0x4f, 0xdf, 0x49, 0xac, 0x93, 0xff, 0x1f, 0x2c, 0xff, 0xe4, 0x93, - 0x84, 0x93, 0xff, 0x1f, 0x30, 0xff, 0xbf, 0x6b, 0xfe, 0xcc, 0x73, 0x9b, - 0x84, 0x92, 0xf5, 0xf7, 0xbf, 0x67, 0x73, 0x9b, 0xf8, 0xf7, 0xec, 0x93, - 0x84, 0x93, 0xff, 0x1f, 0x00, 0xff, 0xf5, 0xeb, 0x6c, 0xeb, 0xff, 0xcf, - 0xff, 0xd7, 0x03, 0xf8, 0x2f, 0xeb, 0xdb, 0xeb, 0xfc, 0xce, 0xa0, 0xb7, - 0xbf, 0xc7, 0x04, 0x93, 0xdf, 0x47, 0xbe, 0x47, 0xf7, 0xf7, 0xfd, 0xcd, - 0xbf, 0x47, 0xc4, 0x93, 0xff, 0x1f, 0xb1, 0xff, 0xfb, 0xeb, 0x6f, 0xeb, - 0xe1, 0xce, 0xbf, 0xc5, 0xdd, 0x47, 0xf8, 0xf3, 0x7f, 0xcd, 0xa7, 0xbd, - 0x7d, 0x9b, 0xf0, 0xf3, 0xff, 0xcd, 0xfe, 0xa5, 0xff, 0x3b, 0xbd, 0x83, - 0xff, 0xd5, 0xdf, 0xc5, 0xfc, 0x4c, 0x13, 0xf4, 0xe1, 0xce, 0xf7, 0x8f, - 0xb6, 0xa6, 0xfc, 0x4c, 0xbd, 0x4c, 0x19, 0xf8, 0x30, 0xcf, 0xe7, 0xbf, - 0x19, 0xf8, 0xff, 0xff, 0x2e, 0xeb, 0xda, 0xeb, 0x3c, 0x93, 0xfb, 0xe7, - 0x9f, 0x4f, 0x84, 0x93, 0xff, 0x1f, 0x73, 0xff, 0x9f, 0x67, 0xbd, 0xc4, - 0xc4, 0x92, 0xe1, 0xf3, 0xfe, 0xcd, 0x37, 0x9b, 0xe4, 0xf7, 0xbb, 0xc4, - 0xf8, 0xf3, 0x9d, 0x67, 0x1c, 0x38, 0x7f, 0xd7, 0xea, 0xf7, 0xc1, 0xc4, - 0xf7, 0xf7, 0x9e, 0x6b, 0xbf, 0xc4, 0xec, 0xf7, 0x3f, 0x38, 0xdf, 0xaf, - 0xfa, 0xeb, 0x6e, 0xeb, 0xe1, 0xcf, 0x92, 0xa7, 0xfc, 0x67, 0xf2, 0x8f, - 0x9e, 0x67, 0xbf, 0xc4, 0x07, 0xf0, 0xff, 0xcc, 0xfe, 0xa4, 0xfa, 0xeb, - 0x6e, 0xeb, 0xff, 0xcf, 0xfa, 0xeb, 0x6e, 0xeb, 0x7f, 0xcf, 0xe7, 0xbf, - 0xfa, 0xeb, 0x6e, 0xeb, 0x3e, 0xeb, 0xbf, 0x6f, 0xfe, 0xc5, 0x9c, 0x6f, - 0xde, 0x6f, 0xcb, 0xf3, 0xbb, 0xc5, 0xd1, 0xf3, 0xbd, 0xc5, 0xe1, 0xf3, - 0xbf, 0xc4, 0xe3, 0xf3, 0xbd, 0x6f, 0xff, 0xcf, 0x82, 0xd7, 0xf6, 0x9b, - 0xd0, 0xf7, 0x80, 0xcf, 0x7e, 0x9b, 0xdd, 0xf7, 0xfc, 0x1b, 0x80, 0xdf, - 0xbf, 0xcb, 0xfd, 0x9a, 0x81, 0xdd, 0xeb, 0xf3, 0xc1, 0xdc, 0x1c, 0x38, - 0x7f, 0xd7, 0xea, 0xf7, 0x9d, 0xbc, 0xbd, 0x1b, 0x00, 0xdf, 0xa8, 0xbd, - 0x96, 0xb4, 0x37, 0x93, 0xe0, 0xbe, 0xf3, 0x93, 0x7e, 0xeb, 0xff, 0xcd, - 0xff, 0xcc, 0x37, 0x93, 0xe0, 0xbe, 0xf3, 0x93, 0x7e, 0xeb, 0x1c, 0x3b, - 0x7f, 0xd7, 0x13, 0xf0, 0x9f, 0xa4, 0x15, 0xf8, 0x9e, 0xb4, 0xff, 0xdd, - 0x15, 0xf8, 0x00, 0xcd, 0xa8, 0xbd, 0xff, 0xcc, 0x0e, 0xf8, 0x4b, 0xc4, - 0x96, 0xbc, 0x00, 0xcd, 0x96, 0xb4, 0xa8, 0xbd, 0x14, 0xf8, 0xf6, 0xa7, - 0xc6, 0xc7, 0xe2, 0xf3, 0xfe, 0xcb, 0xfc, 0x3b, 0xbd, 0xbf, 0xfb, 0x3b, - 0xdf, 0xbf, 0xff, 0xd7, 0x3f, 0x97, 0xbf, 0xc4, 0xff, 0x3b, 0xfc, 0xfa, - 0x73, 0x93, 0x9d, 0x1b, 0x80, 0xdf, 0xbf, 0xcf, 0xf1, 0x9b, 0xf1, 0xf7, - 0x1d, 0x3b, 0x7f, 0xd7, 0xfd, 0xf3, 0xb3, 0xa5, 0x5f, 0x38, 0xdf, 0xaf, - 0x7f, 0x9b, 0x9d, 0xbd, 0x7c, 0x9b, 0x96, 0xb4, 0xa8, 0xbd, 0x33, 0xf8, - 0xff, 0xcd, 0xc1, 0xdd, 0x09, 0xf8, 0xff, 0xff, 0x3e, 0xeb, 0x9f, 0x6f, - 0xe8, 0xb4, 0xff, 0x1b, 0x00, 0xdf, 0xb6, 0xbc, 0x60, 0xb4, 0xbf, 0xc7, - 0xb6, 0xb5, 0x7e, 0x4e, 0xea, 0xf7, 0xbf, 0xc5, 0xe1, 0xf3, 0xff, 0xcc, - 0x82, 0xd4, 0xfc, 0xcf, 0x9d, 0x4e, 0xff, 0xcc, 0xff, 0x4e, 0xb8, 0xbd, - 0x81, 0xd4, 0x5f, 0x38, 0xdf, 0xaf, 0xbe, 0xbd, 0x7f, 0x9b, 0xf0, 0x92, - 0xff, 0xd4, 0x03, 0xf4, 0x7d, 0x4e, 0xbc, 0x4e, 0x7e, 0xeb, 0x00, 0xcb, - 0xfd, 0x9a, 0xf3, 0xf3, 0xb8, 0xbd, 0x81, 0xd7, 0xfc, 0xcc, 0x41, 0xc5, - 0xfd, 0x4e, 0x9f, 0x4e, 0xbc, 0x4e, 0x7e, 0xeb, 0xfd, 0xcf, 0xff, 0x4e, - 0x7e, 0xeb, 0xbf, 0xc5, 0xf5, 0xf3, 0x7f, 0xcf, 0xf2, 0xbf, 0x3f, 0x97, - 0xbf, 0xc4, 0xff, 0x3b, 0xfc, 0xfa, 0x9f, 0x4e, 0xbc, 0x4e, 0x7e, 0xeb, - 0xfb, 0xcc, 0x9f, 0x4e, 0x7e, 0xeb, 0xff, 0xff, 0x3e, 0xeb, 0x9f, 0x6f, - 0xfe, 0xcb, 0x2f, 0x9b, 0xed, 0xf7, 0xbf, 0x6e, 0x6f, 0x9b, 0xf0, 0xf7, - 0xbb, 0xc4, 0xd2, 0xf3, 0xbb, 0xc5, 0xf0, 0xf3, 0xbd, 0xc4, 0xf4, 0xf3, - 0xbd, 0xc5, 0xee, 0xf3, 0x9e, 0x6f, 0xbe, 0x6e, 0x71, 0x9b, 0xed, 0xf3, - 0xbf, 0xc4, 0xf7, 0xf7, 0xfe, 0xcf, 0x7e, 0xeb, 0xbd, 0xc5, 0xe4, 0xf3, - 0x9e, 0x6e, 0xbf, 0xc4, 0x05, 0xf4, 0xff, 0xcf, 0xff, 0xd7, 0x7e, 0xeb, - 0x9e, 0x6f, 0xbf, 0xc4, 0x04, 0xf4, 0xfe, 0xcf, 0x0c, 0xf8, 0x7d, 0x6f, - 0xbd, 0x6e, 0xf6, 0x9a, 0x13, 0xf4, 0x6e, 0x9b, 0xf8, 0xf7, 0xfc, 0x6f, - 0xbc, 0x6e, 0xf7, 0x9b, 0x19, 0xf0, 0x7f, 0x9b, 0xfb, 0xf7, 0xbf, 0xc4, - 0x14, 0xf0, 0x1c, 0xf8, 0xff, 0xcf, 0x7e, 0xeb, 0xbb, 0xc5, 0x16, 0xf4, - 0xbe, 0x6e, 0x9e, 0x6f, 0xf2, 0xa5, 0x7e, 0xeb, 0x2f, 0xeb, 0xff, 0x8b, - 0xff, 0x1f, 0xfb, 0xec, 0x6f, 0xeb, 0xff, 0xff, 0x2e, 0xeb, 0xfc, 0x92, - 0xff, 0x7f, 0xbf, 0xc7, 0xf8, 0xf3, 0xff, 0xdb, 0x00, 0x1c, 0x0b, 0x00, - 0xff, 0x7b, 0xbf, 0xc7, 0x04, 0xf4, 0x6e, 0xeb, 0x2b, 0xeb, 0xd7, 0xeb, - 0xff, 0x47, 0x3a, 0x8a, 0x77, 0x8b, 0xbd, 0x47, 0x33, 0x8b, 0x9e, 0x47, - 0xff, 0xcd, 0xfc, 0xe4, 0xac, 0x5c, 0x20, 0xc7, 0xfb, 0xf3, 0xff, 0xca, - 0x5e, 0xa2, 0xfd, 0xfb, 0x5f, 0x67, 0xff, 0xc9, 0x71, 0x1b, 0xe1, 0xff, - 0x20, 0x8a, 0xff, 0xd3, 0xe8, 0x93, 0xa0, 0x93, 0x00, 0x1c, 0xfb, 0x02, - 0x88, 0xef, 0xf3, 0xa7, 0x9f, 0x7f, 0x9f, 0x5b, 0xff, 0xd9, 0x67, 0x8a, - 0xe8, 0x93, 0xa0, 0x93, 0x00, 0x1c, 0x2b, 0x03, 0xbc, 0x92, 0xbf, 0xc7, - 0x10, 0xf4, 0x6c, 0x93, 0x9e, 0x67, 0xbf, 0xc4, 0xec, 0xf3, 0x27, 0x9b, - 0xee, 0xf7, 0x26, 0xa4, 0x67, 0x8a, 0xbf, 0xc1, 0xf2, 0xf3, 0xff, 0xd1, - 0x67, 0x8a, 0x9c, 0xa3, 0x86, 0xa4, 0xdd, 0x67, 0xff, 0xd3, 0xdf, 0x5b, - 0x2d, 0x9b, 0x02, 0xf4, 0x39, 0x3b, 0x7b, 0xdb, 0x6f, 0xa5, 0x9f, 0x67, - 0x20, 0xc4, 0xfb, 0xf3, 0xff, 0xd3, 0xd2, 0xcc, 0x9f, 0x5b, 0xec, 0x93, - 0x00, 0x1c, 0x4f, 0x00, 0xf7, 0xeb, 0x6b, 0xeb, 0x37, 0x84, 0xff, 0xff, - 0xdb, 0xeb, 0x9c, 0x47, 0xbd, 0x47, 0xde, 0x47, 0xff, 0x47, 0x2b, 0xeb, - 0xde, 0xeb, 0x79, 0x67, 0xff, 0x7b, 0xbf, 0xc7, 0x99, 0xf3, 0xf8, 0xe1, - 0xff, 0xca, 0xdf, 0xcd, 0xbf, 0x47, 0xda, 0xc8, 0x3d, 0x9a, 0xfb, 0xf3, - 0x00, 0x1c, 0x6d, 0x00, 0xa7, 0xfb, 0xff, 0xdb, 0x9f, 0x7b, 0xcf, 0xcd, - 0x71, 0x9b, 0xfc, 0xf7, 0xff, 0xdb, 0xbf, 0x47, 0xff, 0x7b, 0x9f, 0x1b, - 0xd0, 0xef, 0x33, 0x8b, 0xf6, 0xc4, 0xf1, 0xf7, 0xf6, 0xcd, 0x9c, 0xba, - 0x5c, 0x3b, 0xda, 0xf7, 0x5f, 0xa2, 0xd0, 0xd2, 0xff, 0xdb, 0xff, 0x7b, - 0x9f, 0x1b, 0xd0, 0xef, 0x33, 0x8b, 0x37, 0x9b, 0x0a, 0xf4, 0x9f, 0x1b, - 0x9d, 0xef, 0x73, 0x8b, 0xea, 0xc5, 0xc8, 0xf7, 0x34, 0x93, 0xbc, 0xee, - 0x9d, 0x3b, 0xbc, 0xf7, 0x9f, 0x6c, 0xf3, 0x87, 0xfc, 0xd9, 0x90, 0xa1, - 0xff, 0x6c, 0x2b, 0x8b, 0xf5, 0xce, 0xbf, 0x67, 0x00, 0x1c, 0x89, 0x00, - 0xd5, 0xfb, 0xfc, 0xd9, 0x90, 0xa1, 0xff, 0x6c, 0x2b, 0x8b, 0xf7, 0xce, - 0xbf, 0x67, 0x00, 0x1c, 0x92, 0x00, 0xde, 0xfb, 0xfc, 0xd9, 0x90, 0xa1, - 0xff, 0x6c, 0x2b, 0x8b, 0xf5, 0xce, 0xbf, 0x67, 0x00, 0x1c, 0x9b, 0x00, - 0xe7, 0xfb, 0xfc, 0xd9, 0x90, 0xa1, 0xff, 0x6c, 0x2b, 0x8b, 0xef, 0xce, - 0xbf, 0x67, 0x00, 0x1c, 0xa4, 0x00, 0xf0, 0xfb, 0xfc, 0xd9, 0x90, 0xa1, - 0xff, 0x7c, 0x00, 0x1c, 0xbc, 0x00, 0xf6, 0xfb, 0xfc, 0xd9, 0x90, 0xa1, - 0xff, 0x6c, 0x00, 0x1c, 0xbc, 0x00, 0xfc, 0xfb, 0x00, 0x1c, 0xc5, 0x00, - 0xff, 0xdb, 0xff, 0x7b, 0xbf, 0xc7, 0x5e, 0xf4, 0xfe, 0xeb, 0x11, 0x26, - 0xfb, 0xdf, 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, 0x7f, 0x67, 0xf6, 0xeb, - 0xc3, 0x87, 0xff, 0xff, 0x8f, 0x84, 0xff, 0xff, 0x8e, 0xef, 0xad, 0xef, + 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xdf, 0x7b, 0x8c, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xdf, 0x8f, 0xfe, 0xff, 0xdf, 0xff, 0x1f, 0x25, 0xf3, + 0xff, 0x3f, 0xdf, 0xbf, 0xff, 0x1f, 0x0f, 0xf3, 0xff, 0x3f, 0xdf, 0xbf, + 0xff, 0x1f, 0x4f, 0xf3, 0xff, 0x3f, 0xdf, 0xbf, 0x8e, 0xef, 0xad, 0xef, 0x9f, 0x4d, 0xad, 0xef, 0xbc, 0x23, 0xff, 0xde, 0xae, 0xef, 0xbc, 0x23, 0xfe, 0xde, 0xae, 0xef, 0xbc, 0x23, 0xfd, 0xde, 0xaf, 0xef, 0xbc, 0x23, 0xfc, 0xde, 0xaf, 0xef, 0xbc, 0x23, 0xfb, 0xde, 0xb0, 0xef, 0xbc, 0x23, 0xfa, 0xde, 0xb0, 0xef, 0xbc, 0x23, 0xf9, 0xde, 0xb1, 0xef, 0xbc, 0x23, 0xf8, 0xde, 0xff, 0xcd, 0xbc, 0x23, 0xfe, 0xdc, 0xbc, 0x23, 0x3f, 0xdf, - 0xc3, 0x87, 0xff, 0xff, 0xff, 0x1f, 0xff, 0x1f, 0x83, 0xfe, 0xff, 0xdf, + 0xc3, 0x87, 0xff, 0xff, 0xff, 0x1f, 0xff, 0x1f, 0x93, 0xfe, 0xff, 0xdf, 0xfc, 0xfd, 0xfe, 0xff, 0xf8, 0xf9, 0xfa, 0xfb, 0xf4, 0xf5, 0xf6, 0xf7, 0xf0, 0xf1, 0xf2, 0xf3, 0xec, 0xed, 0xee, 0xef, 0xe8, 0xe9, 0xea, 0xeb, - 0xe4, 0xe5, 0xe6, 0xe7, 0xe0, 0xe1, 0xe2, 0xe3, 0x7f, 0x3e, 0xdf, 0x8b, - 0xc3, 0x87, 0xff, 0xff, 0x9b, 0xef, 0x9f, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, - 0xdf, 0xbf, 0xfc, 0x23, 0xbf, 0xdf, 0xc3, 0x87, 0x83, 0xfe, 0xff, 0xdf, - 0x9b, 0xef, 0x9f, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, 0xfc, 0x23, - 0x9f, 0xdf, 0xc3, 0x87, 0x83, 0xfe, 0xff, 0xdf, 0x3e, 0xeb, 0x20, 0xc7, - 0xe9, 0xf7, 0x9f, 0x1b, 0xfc, 0xdf, 0x9c, 0xbc, 0xb5, 0xef, 0xbf, 0x6d, - 0xfd, 0xaf, 0xff, 0x8b, 0x00, 0xdf, 0xfd, 0x3b, 0xbf, 0xf7, 0x7f, 0x6f, - 0x00, 0xcd, 0x73, 0x8f, 0xbb, 0x3b, 0xbd, 0xdf, 0xbf, 0x4f, 0xbf, 0x6f, - 0xfa, 0xdc, 0xb3, 0x8f, 0xb7, 0x93, 0xdf, 0x4f, 0x7e, 0xeb, 0xff, 0xff, - 0x83, 0xfe, 0xff, 0xdf, 0x2e, 0xeb, 0x80, 0xef, 0xfc, 0xcd, 0xbf, 0x3b, - 0xde, 0xdf, 0xfb, 0x7c, 0x7f, 0xc7, 0x7e, 0xc7, 0xfb, 0x93, 0x5c, 0xc7, - 0xfb, 0x5c, 0xde, 0x6c, 0xe5, 0xef, 0xbf, 0x97, 0xde, 0x4c, 0xe5, 0xef, - 0xbf, 0x97, 0xdb, 0x5c, 0x7b, 0x97, 0x77, 0x8b, 0xbf, 0xc5, 0xf7, 0xf7, - 0xee, 0xcf, 0xff, 0x1f, 0x4e, 0xf0, 0xfe, 0xcf, 0xff, 0x1f, 0x51, 0xf0, - 0xf8, 0xfb, 0xee, 0xcf, 0xff, 0x1f, 0x5b, 0xf0, 0xfe, 0xcf, 0xff, 0x1f, - 0x5e, 0xf0, 0xff, 0xcf, 0xff, 0xce, 0xff, 0xcd, 0xff, 0x1f, 0x3f, 0xf2, - 0xff, 0xcf, 0xff, 0x1f, 0x56, 0xf2, 0xff, 0x1f, 0xa4, 0xee, 0xff, 0xcf, - 0xff, 0x1f, 0x3f, 0xef, 0x75, 0xef, 0xec, 0x93, 0x46, 0xce, 0xde, 0xbe, - 0xfe, 0xcd, 0xff, 0x1f, 0x9e, 0xee, 0x9d, 0x6b, 0x9e, 0x4b, 0x9f, 0x6b, - 0x56, 0xc4, 0x9f, 0x4b, 0x6e, 0xeb, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, - 0xf0, 0xff, 0x01, 0x00, 0xf4, 0xff, 0x01, 0x00, 0xff, 0xdf, 0xff, 0xbf, - 0x2b, 0xeb, 0xdb, 0xeb, 0xbf, 0x8a, 0x82, 0xed, 0xbf, 0x7c, 0x00, 0xcc, - 0x35, 0x9b, 0xe4, 0xf7, 0x65, 0xed, 0xff, 0xcc, 0x9f, 0x5b, 0xff, 0xce, - 0xdd, 0x4b, 0xdc, 0x4b, 0xdb, 0x4b, 0xda, 0x4b, 0x05, 0xcc, 0x9e, 0xbc, - 0x9c, 0x53, 0xff, 0x1f, 0x70, 0xef, 0xfd, 0x53, 0xff, 0xcc, 0x9e, 0x5b, - 0xff, 0x1f, 0x5d, 0xee, 0xbe, 0xc7, 0xfb, 0xf7, 0xff, 0xcd, 0xbd, 0x5b, - 0xfb, 0xfb, 0xff, 0xcd, 0x91, 0xed, 0xbd, 0x5c, 0xa9, 0x8a, 0x72, 0xed, - 0x5d, 0x4b, 0x9b, 0x6b, 0x93, 0xa2, 0x9e, 0x47, 0x9b, 0x4b, 0x1c, 0x6b, - 0x02, 0xa2, 0x1a, 0x4b, 0x5c, 0x4b, 0xfa, 0xba, 0x98, 0xba, 0xf3, 0xa7, - 0xff, 0x3b, 0xbf, 0xf7, 0x05, 0xce, 0xdd, 0xbe, 0x00, 0x1c, 0xeb, 0x04, - 0x7c, 0x92, 0x1f, 0x47, 0xfc, 0xed, 0xa4, 0x93, 0x68, 0x93, 0x9e, 0x67, - 0x00, 0x1c, 0x67, 0x01, 0xff, 0xcc, 0xff, 0xd4, 0xbd, 0x6b, 0x35, 0x9b, - 0xfd, 0xf7, 0x70, 0x92, 0xff, 0x1f, 0x89, 0xee, 0xbf, 0xc7, 0xf3, 0xf3, - 0x24, 0x93, 0xff, 0xcd, 0xe7, 0xd5, 0x66, 0x9b, 0xfd, 0xf3, 0x34, 0x93, - 0xb0, 0x92, 0xc6, 0xc4, 0xf2, 0xf7, 0xe6, 0xca, 0xf4, 0xfb, 0x24, 0x93, - 0xff, 0xcd, 0xe2, 0xd5, 0x66, 0x9b, 0xfd, 0xf3, 0x34, 0x93, 0xb0, 0x92, - 0xc1, 0xc4, 0xfd, 0xf7, 0xe1, 0xca, 0xff, 0x1f, 0xba, 0xef, 0x70, 0xee, - 0xfd, 0x53, 0xff, 0x1f, 0x04, 0xf0, 0xfc, 0x53, 0x9e, 0x7b, 0xbf, 0xc4, - 0x0d, 0xf7, 0xff, 0x1f, 0xac, 0xee, 0xbe, 0xc7, 0xf6, 0xf3, 0xff, 0x1f, - 0xb0, 0xee, 0xbd, 0xc7, 0xf6, 0xf3, 0x7d, 0xcd, 0xbc, 0x47, 0x4b, 0xcf, - 0xf7, 0xfb, 0x8c, 0xcc, 0x9c, 0x47, 0x6c, 0xcf, 0xfb, 0xfb, 0x8c, 0xce, - 0xdc, 0x47, 0x6c, 0xcf, 0x6a, 0x8b, 0xbd, 0x47, 0x9f, 0xee, 0x7d, 0x74, - 0x77, 0xa3, 0xee, 0x8a, 0x7d, 0x54, 0x2c, 0x8a, 0x00, 0x1c, 0x3d, 0x03, - 0xbc, 0x93, 0x81, 0xef, 0xff, 0x6c, 0x00, 0x1c, 0xcc, 0x03, 0x82, 0xef, - 0xdf, 0x6c, 0x00, 0x1c, 0x08, 0x04, 0x00, 0x1c, 0xce, 0x04, 0x7c, 0x92, - 0x3e, 0x8b, 0x9e, 0x47, 0x22, 0x9b, 0xdb, 0xf3, 0x8b, 0xef, 0x9d, 0x7c, - 0xbe, 0xc4, 0xfb, 0xf7, 0xfe, 0xcd, 0x8d, 0xef, 0xbe, 0x5c, 0x8e, 0xef, - 0x3d, 0x54, 0xff, 0x1f, 0xe2, 0xee, 0xbe, 0xc7, 0xc6, 0xf6, 0x91, 0xef, - 0x9d, 0x7c, 0xbf, 0xc4, 0xca, 0xf6, 0x20, 0xc2, 0xcc, 0xf2, 0xb4, 0xef, - 0x9c, 0x75, 0xdd, 0x67, 0x9b, 0xa4, 0x32, 0x8b, 0x9c, 0x55, 0x30, 0x8b, - 0xfd, 0x15, 0xd4, 0xfe, 0x36, 0x9b, 0xd7, 0xf6, 0x69, 0xcc, 0x9e, 0xbc, - 0xbb, 0xef, 0x9c, 0x55, 0xdc, 0xfa, 0x9c, 0xef, 0x9d, 0x7c, 0xbf, 0xc4, - 0xe3, 0xf7, 0xf6, 0xfb, 0xef, 0xff, 0xff, 0xdf, 0xd7, 0x83, 0xff, 0xff, - 0xdf, 0x83, 0xff, 0xff, 0xdb, 0x83, 0xff, 0xff, 0xfc, 0x67, 0x00, 0x1c, - 0x80, 0x03, 0xbc, 0x93, 0x83, 0xed, 0xff, 0x6c, 0x00, 0x1c, 0x0f, 0x04, - 0x84, 0xed, 0xdf, 0x6c, 0x00, 0x1c, 0x4b, 0x04, 0x00, 0x1c, 0x11, 0x05, - 0xfe, 0x8b, 0x3e, 0x9a, 0xe0, 0xf7, 0xfb, 0xfa, 0xbe, 0xc4, 0xfd, 0xf6, - 0xec, 0x8a, 0x6c, 0xcc, 0x9d, 0xbc, 0xf2, 0x9a, 0xf6, 0xf3, 0xff, 0x1f, - 0x22, 0xef, 0xbf, 0xc7, 0xf0, 0xf3, 0x8d, 0xed, 0x9d, 0x7c, 0xbe, 0xc4, - 0x0a, 0xf7, 0x8f, 0xed, 0x9d, 0x74, 0x30, 0x8b, 0xbe, 0x67, 0x36, 0x9b, - 0x10, 0xf3, 0xff, 0x1f, 0x30, 0xef, 0xbe, 0xc7, 0x14, 0xf7, 0x94, 0xed, - 0x9d, 0x7c, 0xbf, 0xc4, 0xa5, 0xf7, 0xff, 0x1f, 0x38, 0xef, 0xbe, 0xc7, - 0xd5, 0xf7, 0x98, 0xed, 0x9c, 0x74, 0xb0, 0x8b, 0xfd, 0x15, 0x0c, 0xfe, - 0xb6, 0x9b, 0xdc, 0xf7, 0xdf, 0xc2, 0xde, 0xf7, 0xdd, 0x67, 0x9b, 0xa4, - 0x32, 0x8b, 0xbe, 0xed, 0x9c, 0x55, 0x70, 0x8b, 0x05, 0xcc, 0x9e, 0xbc, - 0x72, 0x9b, 0xfa, 0xf3, 0x05, 0xcc, 0x9e, 0xbc, 0xa3, 0xee, 0x9c, 0x55, - 0x64, 0xee, 0xdd, 0x7b, 0xbe, 0x7b, 0x9d, 0x73, 0x30, 0x8b, 0xfc, 0x73, - 0xfc, 0x8b, 0xff, 0x47, 0xe7, 0xee, 0x00, 0x1c, 0x42, 0x02, 0xfd, 0x73, - 0xdc, 0x73, 0xbd, 0x7b, 0xfe, 0xcc, 0xff, 0x1f, 0x60, 0xf0, 0x24, 0xfb, - 0xff, 0x1f, 0x65, 0xef, 0xbe, 0xc7, 0x49, 0xf3, 0x8d, 0xee, 0xbc, 0x1b, - 0xf4, 0xff, 0xfe, 0xce, 0xdd, 0x5d, 0x3d, 0x55, 0x8d, 0x74, 0xa5, 0xcd, - 0x71, 0x9b, 0xf8, 0xf7, 0x94, 0xee, 0x69, 0xcd, 0xbc, 0x54, 0xfe, 0xcd, - 0xbe, 0x5c, 0x59, 0xfb, 0x91, 0xcd, 0x71, 0x9b, 0xf8, 0xf7, 0x98, 0xee, - 0x05, 0xcd, 0xbc, 0x54, 0xfe, 0xcd, 0xbe, 0x5c, 0x62, 0xfb, 0x05, 0xcc, - 0x9e, 0xbc, 0xbc, 0xee, 0x9c, 0x55, 0xff, 0x1f, 0x86, 0xef, 0xbe, 0xc7, - 0x6a, 0xf7, 0xbf, 0xee, 0xfe, 0xcc, 0x9e, 0x5d, 0x69, 0xcc, 0x9e, 0xbc, - 0x9c, 0x55, 0x71, 0xfb, 0xff, 0x1f, 0x91, 0xef, 0xbe, 0xc7, 0xfb, 0xf7, - 0x85, 0xef, 0x3d, 0x54, 0x78, 0xfb, 0x6c, 0xcc, 0x9d, 0xbc, 0xa7, 0xef, - 0x9d, 0x55, 0x7d, 0xfb, 0xbe, 0xc4, 0x7f, 0xf7, 0xff, 0x1f, 0x9f, 0xef, - 0xbd, 0xc7, 0xf7, 0xf7, 0x8a, 0xef, 0xad, 0x74, 0x91, 0xcc, 0x35, 0x9b, - 0xf9, 0xf7, 0x19, 0xcb, 0xf9, 0xfb, 0x05, 0xcb, 0x7e, 0xbb, 0xfc, 0xfb, - 0x69, 0xcb, 0x7e, 0xbb, 0x90, 0xef, 0xbc, 0x1b, 0xf4, 0xff, 0xdc, 0x75, - 0x5b, 0xa2, 0xaa, 0x8a, 0x5c, 0x55, 0xad, 0x74, 0x91, 0xcc, 0x35, 0x9b, - 0xcd, 0xf7, 0xff, 0x1f, 0xba, 0xef, 0xbd, 0xc7, 0xe3, 0xf7, 0x99, 0xef, - 0x9c, 0x74, 0xb0, 0x8b, 0x9c, 0xcd, 0xb6, 0x9b, 0xef, 0xf7, 0xf4, 0xfb, - 0xdf, 0x83, 0xff, 0xff, 0xdb, 0x83, 0xff, 0xff, 0xef, 0xff, 0xff, 0xdf, - 0xb7, 0x83, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, 0x9b, 0xcd, 0x86, 0xee, - 0xbc, 0x54, 0xb3, 0xfb, 0x30, 0x8b, 0x2e, 0x9b, 0xb6, 0xf3, 0x89, 0xee, - 0x7c, 0x54, 0xb9, 0xfb, 0x8b, 0xee, 0x9c, 0x74, 0xb0, 0x8b, 0x06, 0xcd, - 0xb6, 0x9b, 0xfa, 0xf7, 0x05, 0xcd, 0x8e, 0xee, 0xbc, 0x54, 0xc3, 0xfb, - 0x30, 0x8b, 0x2e, 0x9b, 0xc6, 0xf3, 0x91, 0xee, 0x7c, 0x54, 0xff, 0xcd, - 0xbe, 0x5c, 0xcb, 0xfb, 0x68, 0x8b, 0x9c, 0xcc, 0x72, 0x9b, 0xdb, 0xf7, - 0x96, 0xee, 0x9d, 0x7c, 0xbe, 0xc4, 0xe7, 0xf7, 0x58, 0xee, 0xec, 0x93, - 0x00, 0x1c, 0x6b, 0x04, 0xbc, 0x93, 0x99, 0xee, 0xff, 0x6c, 0x00, 0x1c, - 0xfa, 0x04, 0x9a, 0xee, 0xdf, 0x6c, 0x00, 0x1c, 0x36, 0x05, 0x00, 0x1c, - 0xfc, 0x05, 0xfd, 0x52, 0x05, 0xcc, 0x9e, 0xbc, 0x9c, 0x52, 0xff, 0xcc, - 0x9d, 0x5a, 0x9e, 0x5a, 0xea, 0xfb, 0xff, 0x1f, 0x0a, 0xf0, 0xbf, 0xc7, - 0xee, 0xf7, 0x9b, 0xcd, 0x86, 0xef, 0xbc, 0x54, 0xf2, 0xfb, 0xa8, 0x8a, - 0xae, 0x9a, 0xf5, 0xf3, 0x89, 0xef, 0x7c, 0x54, 0xff, 0x1f, 0x17, 0xf0, - 0xbf, 0xc7, 0xfb, 0xf7, 0xff, 0xcd, 0x8c, 0xef, 0xbe, 0x5c, 0x6a, 0xef, - 0xfb, 0x1b, 0xf4, 0xff, 0xdd, 0x7f, 0xbe, 0x7f, 0x9d, 0x77, 0x30, 0x8b, - 0xfc, 0x77, 0xfc, 0x8b, 0xff, 0x47, 0xee, 0xef, 0x00, 0x1c, 0x0f, 0x03, - 0xad, 0x73, 0xa5, 0xcc, 0x35, 0x9b, 0xf5, 0xf7, 0x96, 0xef, 0x9c, 0x74, - 0x64, 0xd4, 0x32, 0x8b, 0xf3, 0xc4, 0xfb, 0xf7, 0x4b, 0xcd, 0x99, 0xef, - 0xbc, 0x54, 0x9a, 0xef, 0xfd, 0x74, 0xdc, 0x74, 0xbd, 0x7c, 0xfe, 0xcc, - 0xff, 0x1f, 0x3b, 0xf1, 0xfb, 0xeb, 0x6b, 0xeb, 0xef, 0xff, 0xff, 0xdf, - 0xdf, 0x83, 0xff, 0xff, 0xdb, 0x83, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, - 0xb7, 0x83, 0xff, 0xff, 0x2c, 0xeb, 0xff, 0x8b, 0xbb, 0x8b, 0xbb, 0xc7, - 0xe3, 0xf7, 0x71, 0xee, 0x9d, 0x6b, 0x97, 0xbc, 0x97, 0xb4, 0x45, 0xc4, - 0x9d, 0x4b, 0x3d, 0x6b, 0xff, 0x1f, 0x57, 0xf0, 0xbc, 0x92, 0xff, 0x1f, - 0x4e, 0xf0, 0x5a, 0x1b, 0xf0, 0xdf, 0x97, 0xee, 0x73, 0x96, 0xa7, 0x92, - 0x9f, 0x1b, 0x0f, 0xdf, 0x8f, 0xbc, 0xb3, 0x92, 0x5d, 0x4b, 0xff, 0x1f, - 0x26, 0xf4, 0xff, 0x1f, 0x28, 0xf4, 0xbf, 0xfb, 0xba, 0xc7, 0xec, 0xf7, - 0x80, 0xef, 0xbd, 0x6c, 0x20, 0xef, 0x67, 0x97, 0xcf, 0xbe, 0xb7, 0x93, - 0xdd, 0x4c, 0xbd, 0x6c, 0xb7, 0xbd, 0xb7, 0xb5, 0x47, 0xc5, 0x45, 0xc5, - 0xbd, 0x4c, 0xff, 0x1f, 0x3a, 0xf4, 0xff, 0x1f, 0x3c, 0xf4, 0xd3, 0xfb, - 0x47, 0xef, 0x7a, 0x1b, 0xd8, 0xff, 0xde, 0x5b, 0xff, 0x5b, 0x8b, 0xef, - 0xbd, 0x6c, 0x2b, 0xef, 0x67, 0x97, 0xcf, 0xbe, 0xb7, 0x93, 0xdd, 0x4c, - 0xbd, 0x6c, 0xb7, 0xbd, 0xb7, 0xb5, 0xe7, 0xbf, 0xf7, 0x93, 0xfd, 0x4c, - 0xff, 0x1f, 0x51, 0xf4, 0xfe, 0xcc, 0x9a, 0x23, 0xd5, 0xff, 0x9f, 0x7b, + 0xe4, 0xe5, 0xe6, 0xe7, 0xe0, 0xe1, 0xe2, 0xe3, 0x9e, 0xee, 0x9f, 0x6c, + 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, 0xfc, 0x23, 0x7f, 0xdf, 0xc3, 0x87, + 0x7f, 0x3e, 0xdf, 0x8b, 0xc3, 0x87, 0xff, 0xff, 0x7f, 0x3f, 0xdf, 0x8f, + 0xc3, 0x87, 0xff, 0xff, 0x86, 0xef, 0x9f, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, + 0xdf, 0xbf, 0xfc, 0x23, 0xbf, 0xdf, 0xc3, 0x87, 0x8a, 0xef, 0x9f, 0x6c, + 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, 0xfc, 0x23, 0x9f, 0xdf, 0xc3, 0x87, + 0x8e, 0xef, 0x9f, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, 0xfc, 0x23, + 0x5f, 0xdf, 0xc3, 0x87, 0x3e, 0xeb, 0x20, 0xc7, 0xe9, 0xf7, 0x9f, 0x1b, + 0xfc, 0xdf, 0x9c, 0xbc, 0xb5, 0xef, 0xbf, 0x6d, 0xfd, 0xaf, 0xff, 0x8b, + 0x00, 0xdf, 0xfd, 0x3b, 0xbf, 0xf7, 0x7f, 0x6f, 0x00, 0xcd, 0x73, 0x8f, + 0xbb, 0x3b, 0xbd, 0xdf, 0xbf, 0x4f, 0xbf, 0x6f, 0xfa, 0xdc, 0xb3, 0x8f, + 0xb7, 0x93, 0xdf, 0x4f, 0x7e, 0xeb, 0xff, 0xff, 0x93, 0xfe, 0xff, 0xdf, + 0x2e, 0xeb, 0x80, 0xef, 0xfc, 0xcd, 0xbf, 0x3b, 0xde, 0xdf, 0xfb, 0x7c, + 0x7f, 0xc7, 0x7e, 0xc7, 0xfb, 0x93, 0x5c, 0xc7, 0xfb, 0x5c, 0xde, 0x6c, + 0xe5, 0xef, 0xbf, 0x97, 0xde, 0x4c, 0xe5, 0xef, 0xbf, 0x97, 0xdb, 0x5c, + 0x7b, 0x97, 0x77, 0x8b, 0xbf, 0xc5, 0xf7, 0xf7, 0xee, 0xcf, 0xff, 0x1f, + 0xde, 0xf2, 0xfe, 0xcf, 0xff, 0x1f, 0xe1, 0xf2, 0xf8, 0xfb, 0xee, 0xcf, + 0xff, 0x1f, 0xeb, 0xf2, 0xfe, 0xcf, 0xff, 0x1f, 0xee, 0xf2, 0xff, 0xcf, + 0xff, 0xce, 0xff, 0xcd, 0xff, 0x1f, 0xf7, 0xf4, 0xff, 0xcf, 0xff, 0x1f, + 0x0a, 0xf5, 0xff, 0x1f, 0x34, 0xf1, 0xff, 0xcf, 0xff, 0x1f, 0xe7, 0xf1, + 0x75, 0xef, 0xec, 0x93, 0x46, 0xce, 0xde, 0xbe, 0xfe, 0xcd, 0xff, 0x1f, + 0x1a, 0xf1, 0x9d, 0x6b, 0x9e, 0x4b, 0x9f, 0x6b, 0x56, 0xc4, 0x9f, 0x4b, + 0x6e, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xf0, 0xff, 0x01, 0x00, + 0xf4, 0xff, 0x01, 0x00, 0xff, 0xdf, 0xff, 0xbf, 0x2c, 0xeb, 0xff, 0x8b, + 0xbb, 0x8b, 0x5e, 0xec, 0x7a, 0x1b, 0xf4, 0xff, 0xde, 0x5b, 0xff, 0x5b, + 0x80, 0xed, 0xbd, 0x6c, 0x20, 0xed, 0x67, 0x97, 0xcf, 0xbe, 0xb7, 0x93, + 0xdd, 0x4c, 0xbd, 0x6c, 0xb7, 0xbd, 0xb7, 0xb5, 0xe7, 0xbf, 0xf7, 0x93, + 0xfd, 0x4c, 0xff, 0x1f, 0xbe, 0xf4, 0xfe, 0xcc, 0x91, 0x5a, 0x9f, 0x7b, 0xfe, 0xc4, 0xed, 0xf7, 0xfe, 0xcf, 0x7f, 0xce, 0xd9, 0xbe, 0xff, 0x1f, - 0xe2, 0xf7, 0x95, 0xef, 0x9f, 0x7c, 0xbf, 0xc4, 0xf6, 0xf7, 0xff, 0x1f, - 0x1c, 0xf1, 0x97, 0xef, 0xbf, 0x6c, 0x76, 0xc5, 0xbf, 0x4c, 0xbd, 0x6c, - 0x9e, 0x6c, 0x6c, 0xeb, 0xff, 0x6f, 0xff, 0xbf, 0x00, 0x00, 0xff, 0x00, - 0xfb, 0xff, 0xff, 0xdf, 0xd3, 0xff, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xbf, - 0xbc, 0xc7, 0xf3, 0xf7, 0x90, 0xef, 0x9f, 0x74, 0xbd, 0xbc, 0xd8, 0xbc, - 0xb6, 0xa6, 0x93, 0xa5, 0x9c, 0x3b, 0xbc, 0xf7, 0xf7, 0xac, 0xfe, 0x8b, - 0xed, 0xfb, 0xbe, 0xc7, 0xf0, 0xf7, 0x96, 0xef, 0x9e, 0x74, 0xbb, 0xbc, - 0x9d, 0x3b, 0xbc, 0xf7, 0x9c, 0x3b, 0xbc, 0xf7, 0xfb, 0xbc, 0x92, 0xa7, - 0xfb, 0xbc, 0xf2, 0xa7, 0xf5, 0xaf, 0xfe, 0x8b, 0xfd, 0xfb, 0xff, 0xcf, - 0xc3, 0x87, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xdf, 0xb8, 0xef, 0xde, 0x75, + 0x64, 0xf8, 0x8a, 0xed, 0x9f, 0x7c, 0xbf, 0xc4, 0xf6, 0xf7, 0xff, 0x1f, + 0x74, 0xf1, 0x8c, 0xed, 0xbf, 0x6c, 0x76, 0xc5, 0xbf, 0x4c, 0xbd, 0x6c, + 0x9e, 0x6c, 0x6c, 0xeb, 0xbc, 0xc7, 0xf3, 0xf7, 0x90, 0xed, 0x9f, 0x74, + 0xbd, 0xbc, 0xd8, 0xbc, 0xb6, 0xa6, 0x93, 0xa5, 0x9c, 0x3b, 0xbc, 0xf7, + 0xf7, 0xac, 0xfe, 0x8b, 0xed, 0xfb, 0xbe, 0xc7, 0xf0, 0xf7, 0x96, 0xed, + 0x9e, 0x74, 0xbb, 0xbc, 0x9d, 0x3b, 0xbc, 0xf7, 0x9c, 0x3b, 0xbc, 0xf7, + 0xfb, 0xbc, 0x92, 0xa7, 0xfb, 0xbc, 0xf2, 0xa7, 0xf5, 0xaf, 0xfe, 0x8b, + 0xfd, 0xfb, 0xff, 0xcf, 0xc3, 0x87, 0xff, 0xff, 0xbf, 0xed, 0xde, 0x75, 0x9f, 0x75, 0x3b, 0x83, 0xbc, 0xbc, 0xf9, 0xbc, 0xf6, 0xa7, 0xf2, 0xa7, 0xfb, 0xbf, 0xf3, 0xa7, 0xfd, 0xbf, 0x92, 0xa7, 0xef, 0xac, 0xc3, 0x87, - 0xcf, 0xff, 0xff, 0xdf, 0x2b, 0xeb, 0xdd, 0xeb, 0xbe, 0x8a, 0xff, 0x1f, - 0xde, 0xf0, 0x3e, 0xc2, 0x36, 0xf3, 0x98, 0xec, 0x9c, 0x6c, 0x37, 0xc4, - 0xba, 0xf3, 0x93, 0xbf, 0xf1, 0xbf, 0xff, 0xa4, 0xff, 0x3b, 0xbf, 0xf7, - 0xfe, 0x15, 0x3b, 0xf6, 0x00, 0x1c, 0x6b, 0x07, 0x3e, 0x8a, 0x7e, 0xec, - 0x9f, 0x73, 0x3d, 0xb4, 0x86, 0xa4, 0x72, 0x8a, 0x3f, 0x53, 0xff, 0x1f, - 0xa6, 0xf5, 0xfd, 0xb7, 0x3f, 0xa1, 0x66, 0x8a, 0x3f, 0x53, 0x83, 0xed, - 0xbd, 0x6c, 0xbd, 0x1b, 0x00, 0xcf, 0x3d, 0xb1, 0x67, 0x8a, 0x67, 0x93, - 0xbd, 0x4c, 0xff, 0x1f, 0x10, 0xf1, 0xbe, 0xc7, 0xed, 0xf7, 0xbf, 0x73, - 0x37, 0xcc, 0x9e, 0xbc, 0x73, 0x9b, 0xf9, 0xf7, 0xff, 0xcf, 0xfd, 0xce, - 0x00, 0x1c, 0xcf, 0x00, 0xe6, 0xfb, 0x63, 0x9b, 0xe8, 0xf7, 0xfc, 0xcf, - 0xff, 0xce, 0x00, 0x1c, 0xd6, 0x00, 0xed, 0xfb, 0x93, 0xed, 0x9f, 0x74, - 0xb8, 0x1b, 0xb0, 0xff, 0x36, 0x9b, 0xf9, 0xf3, 0xff, 0xcf, 0xfd, 0xce, - 0x00, 0x1c, 0xe1, 0x00, 0xf8, 0xfb, 0x23, 0x9b, 0xfa, 0xf7, 0xfc, 0xcf, - 0xff, 0xce, 0x00, 0x1c, 0xe8, 0x00, 0x99, 0xed, 0x9b, 0x7c, 0x9c, 0x1b, - 0xfb, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0x89, 0xf7, 0xff, 0x1f, 0x25, 0xf1, - 0xfc, 0x92, 0x9e, 0xed, 0x9c, 0x27, 0xcf, 0xff, 0xbe, 0xc4, 0xb8, 0xf7, - 0xbf, 0xc7, 0xba, 0xf3, 0xff, 0xcf, 0xff, 0x1f, 0xc4, 0xf5, 0x23, 0xee, - 0x99, 0xbf, 0xb7, 0xbf, 0x92, 0xa5, 0x9e, 0xa4, 0xbc, 0xbc, 0x97, 0xa4, - 0x9d, 0xbc, 0x9e, 0xa4, 0x97, 0xb4, 0x86, 0x51, 0xfe, 0xcf, 0xff, 0x1f, - 0xd2, 0xf5, 0x9b, 0xbf, 0xfc, 0x3b, 0xbc, 0xf7, 0x9c, 0x3b, 0xbc, 0xf7, - 0xbb, 0xbc, 0x92, 0xa5, 0xbb, 0xbc, 0x92, 0xa5, 0x95, 0xac, 0x32, 0x8b, - 0x85, 0x51, 0xa6, 0x71, 0x96, 0xa4, 0xbc, 0xbb, 0x7d, 0x3b, 0xdb, 0xf7, - 0xf2, 0x9a, 0xe2, 0xf3, 0x99, 0x27, 0xc9, 0xff, 0xff, 0xdc, 0x33, 0x8b, - 0x99, 0x23, 0xc9, 0xff, 0xfc, 0xcd, 0x37, 0x9b, 0xe7, 0xf7, 0xbe, 0x69, - 0xd8, 0xee, 0x7b, 0x97, 0xbe, 0x49, 0xd8, 0xee, 0x7b, 0x97, 0xbb, 0x59, - 0xff, 0x1f, 0xf5, 0xf1, 0x80, 0xef, 0xbd, 0x6c, 0xdb, 0xee, 0x7b, 0x97, - 0xbd, 0x4c, 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, 0x38, 0x01, 0xfa, 0xfb, - 0xff, 0xcd, 0x82, 0xef, 0xbc, 0x23, 0xc9, 0xff, 0x66, 0xef, 0x9e, 0x73, - 0x3d, 0xb4, 0x86, 0xa4, 0x72, 0x8a, 0x3e, 0x53, 0xfe, 0xcf, 0xff, 0x1f, - 0x0e, 0xf6, 0xfd, 0xb7, 0x3f, 0xa1, 0x66, 0x8a, 0x3e, 0x53, 0x8b, 0xef, - 0xdd, 0x6c, 0xa7, 0xef, 0xb7, 0x97, 0xbd, 0xb1, 0x77, 0x8b, 0xb7, 0xbd, - 0x7b, 0x93, 0xbd, 0x4c, 0xfc, 0x15, 0x0a, 0xfe, 0x73, 0x9a, 0xf9, 0xf7, - 0xff, 0xcf, 0xfe, 0xce, 0x00, 0x1c, 0x5b, 0x01, 0xf6, 0xfb, 0xfc, 0x15, - 0x94, 0xfe, 0x73, 0x9a, 0xfa, 0xf3, 0xff, 0xcf, 0xfc, 0xce, 0x00, 0x1c, - 0x64, 0x01, 0xff, 0x1f, 0x3e, 0xf6, 0x5a, 0x1b, 0xfd, 0xbf, 0x31, 0xc2, - 0x99, 0xf3, 0xba, 0xef, 0xff, 0xcc, 0xee, 0xfb, 0xff, 0x5f, 0xff, 0xbf, - 0xcf, 0xff, 0xff, 0xdf, 0xff, 0x6f, 0xff, 0xbf, 0xfb, 0xff, 0xff, 0xdf, - 0xf0, 0xff, 0x01, 0x00, 0xf4, 0xff, 0x01, 0x00, 0x00, 0x00, 0xf0, 0x00, - 0x00, 0xff, 0x00, 0x00, 0xff, 0xd4, 0x93, 0x5d, 0xfd, 0x27, 0xc8, 0xff, - 0x7f, 0xce, 0xd8, 0xbe, 0xff, 0x1f, 0x77, 0xf9, 0x7c, 0x92, 0xbe, 0x6f, - 0x9f, 0x7d, 0xbe, 0xc4, 0xe3, 0xf3, 0xbf, 0xc4, 0xf9, 0xf3, 0xbd, 0xc4, - 0xdf, 0xf3, 0xbc, 0xc4, 0xc5, 0xf7, 0xcf, 0xfb, 0x92, 0xec, 0xbf, 0x6c, - 0x76, 0xc5, 0xbf, 0x4c, 0xbd, 0x6c, 0x9e, 0x6c, 0x94, 0xec, 0xbb, 0x7c, - 0x7d, 0xc5, 0xbb, 0x5c, 0x95, 0xec, 0xbd, 0x6c, 0xd5, 0xec, 0x7b, 0x97, - 0xbd, 0x4c, 0x95, 0xec, 0xff, 0xcd, 0xbf, 0x4c, 0xbe, 0x4c, 0xda, 0xfb, - 0xbe, 0x75, 0x9b, 0xec, 0xad, 0x54, 0xfd, 0xcf, 0xff, 0xce, 0x00, 0x1c, - 0xac, 0x01, 0xe2, 0xfb, 0xff, 0xcd, 0x9f, 0xec, 0xad, 0x54, 0xff, 0x1f, - 0x78, 0xf2, 0x7d, 0xec, 0xff, 0x1f, 0x0f, 0xf2, 0xff, 0xd3, 0xbf, 0xc3, - 0x03, 0xf4, 0xfe, 0xcf, 0x00, 0x1c, 0x07, 0x04, 0xfe, 0xcf, 0xff, 0xce, - 0x00, 0x1c, 0xbf, 0x01, 0xf5, 0xfb, 0xff, 0xcd, 0x89, 0xed, 0xad, 0x54, - 0xff, 0x1f, 0x8b, 0xf2, 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, 0xc9, 0x01, - 0xe4, 0x93, 0xff, 0x1f, 0xce, 0xf9, 0x7f, 0xcc, 0x98, 0xbc, 0xb2, 0x92, - 0x33, 0xc2, 0x8a, 0xf3, 0xfc, 0xcf, 0x00, 0x1c, 0x6a, 0x01, 0xfc, 0x92, - 0x93, 0xed, 0xfc, 0x27, 0xc8, 0xff, 0x7f, 0xce, 0xda, 0xbe, 0xff, 0x1f, - 0xce, 0xf9, 0x9e, 0x6f, 0x3f, 0x7c, 0xff, 0x1f, 0xe2, 0xf9, 0xf3, 0xed, - 0xac, 0x93, 0x00, 0x1c, 0x16, 0x05, 0xff, 0x1f, 0x26, 0xf2, 0x9b, 0xbf, - 0xfc, 0x3b, 0xbf, 0xf7, 0xff, 0x3b, 0xbf, 0xf7, 0xee, 0x9b, 0xec, 0xf3, - 0xff, 0x1f, 0x2f, 0xf2, 0x9b, 0xbf, 0xfc, 0x3b, 0xbf, 0xf7, 0xff, 0x3b, - 0xbf, 0xf7, 0xec, 0xd7, 0xfe, 0x9a, 0xfa, 0xf3, 0x25, 0x8b, 0xdf, 0xc4, - 0xfd, 0xf7, 0xfd, 0xc9, 0xe5, 0x8b, 0x00, 0x1c, 0x04, 0x04, 0xbb, 0xfb, - 0xff, 0x1f, 0x41, 0xf2, 0x9b, 0xbf, 0xfc, 0x3b, 0xbf, 0xf7, 0xff, 0x3b, - 0xbf, 0xf7, 0x74, 0xdf, 0xee, 0x9b, 0xf9, 0xf7, 0xff, 0xcf, 0xf8, 0xd7, - 0x00, 0x1c, 0x13, 0x04, 0xca, 0xfb, 0xff, 0x1f, 0x50, 0xf2, 0x9d, 0xa7, - 0xbb, 0xbc, 0x9d, 0x3b, 0xbc, 0xf7, 0x9c, 0x3b, 0xbc, 0xf7, 0x2e, 0x9b, - 0xf9, 0xf7, 0xff, 0xcf, 0xfc, 0xd7, 0x00, 0x1c, 0x22, 0x04, 0xd9, 0xfb, - 0xff, 0x1f, 0x5f, 0xf2, 0x9b, 0xbf, 0xfc, 0x3b, 0xbc, 0xf7, 0x9c, 0x3b, - 0xbc, 0xf7, 0xce, 0xdc, 0x2e, 0x9b, 0xf9, 0xf7, 0xff, 0xcf, 0xfe, 0xd7, - 0x00, 0x1c, 0x31, 0x04, 0xe8, 0xfb, 0xff, 0x1f, 0x6e, 0xf2, 0x9b, 0xbf, - 0xfc, 0x3b, 0xbc, 0xf7, 0x9c, 0x3b, 0xbc, 0xf7, 0x2e, 0x9b, 0xf1, 0xf7, - 0x67, 0x8a, 0x65, 0x8b, 0xff, 0xcc, 0xff, 0xd4, 0x36, 0x9b, 0xfa, 0xf3, - 0xf4, 0x93, 0x00, 0x1c, 0x44, 0x04, 0xfb, 0xfb, 0xff, 0xcf, 0x00, 0x1c, - 0x48, 0x04, 0x7f, 0xce, 0xda, 0xbe, 0xba, 0x92, 0x34, 0xc2, 0x94, 0xf3, - 0x8c, 0xef, 0xfc, 0x27, 0xc8, 0xff, 0x7f, 0xce, 0xdb, 0xbe, 0xff, 0x1f, - 0x40, 0xfa, 0xfe, 0x47, 0x9e, 0x6f, 0x9f, 0x7c, 0xbd, 0xbc, 0xd8, 0xbc, - 0xb6, 0xa6, 0x93, 0xa5, 0x9c, 0x3b, 0xbc, 0xf7, 0x1b, 0xac, 0x00, 0x1c, - 0xce, 0x01, 0x7c, 0x92, 0xfc, 0xcf, 0x00, 0x1c, 0xf4, 0x01, 0xfc, 0x92, - 0xff, 0x1f, 0x9b, 0xf2, 0x9c, 0xbf, 0xfc, 0x3b, 0xdf, 0xf7, 0x03, 0xa7, - 0x9d, 0xbb, 0xbb, 0xbb, 0x92, 0xa5, 0x8e, 0xa4, 0xef, 0xfb, 0xff, 0xff, - 0xff, 0xdf, 0xff, 0xbf, 0xfb, 0xff, 0xff, 0xdf, 0xff, 0x5f, 0xff, 0xbf, - 0x00, 0x00, 0xf0, 0x00, 0xff, 0x8f, 0xff, 0xbf, 0xbf, 0xf2, 0xfc, 0xff, - 0x93, 0x83, 0xff, 0xff, 0xbc, 0xbc, 0x92, 0xa5, 0x99, 0xac, 0x13, 0xa0, - 0x82, 0xa1, 0x9f, 0x47, 0xf9, 0xee, 0xa0, 0x93, 0x64, 0x93, 0x2c, 0x93, - 0x00, 0x1c, 0xb7, 0x05, 0x63, 0x9a, 0xe5, 0xf7, 0x22, 0xa1, 0x66, 0x8a, - 0x05, 0xcc, 0x9b, 0xbc, 0x73, 0x9a, 0xe6, 0xf3, 0xfc, 0x15, 0x23, 0xfa, - 0x73, 0x9a, 0xf4, 0xf7, 0xa1, 0xef, 0x9d, 0x27, 0xc7, 0xff, 0xff, 0xdc, - 0x33, 0x8b, 0x9d, 0x23, 0xc7, 0xff, 0xfd, 0xc4, 0xec, 0xf3, 0xf4, 0xfb, - 0xff, 0xcd, 0x86, 0xef, 0xbc, 0x23, 0xc7, 0xff, 0xf2, 0xfb, 0xff, 0xcd, - 0x89, 0xef, 0xbc, 0x23, 0xc7, 0xff, 0xf7, 0xfb, 0xff, 0xcf, 0x00, 0x1c, - 0xf4, 0x04, 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, 0xac, 0x02, 0xfe, 0x67, - 0xff, 0x1f, 0xb1, 0xfa, 0x5a, 0x1b, 0xff, 0xb7, 0x3d, 0xc2, 0xf5, 0xf3, - 0xfe, 0xcf, 0x00, 0x1c, 0x02, 0x05, 0xfe, 0xcf, 0xff, 0xce, 0x00, 0x1c, - 0xba, 0x02, 0x5a, 0x1b, 0xfb, 0xbf, 0x3f, 0xc2, 0xf5, 0xf3, 0xff, 0x1f, - 0x1a, 0xf3, 0x98, 0xef, 0x9c, 0x27, 0xd5, 0xff, 0xbf, 0xc4, 0xfc, 0xf3, - 0xff, 0x1f, 0xd3, 0xf6, 0xff, 0xcf, 0xfd, 0xeb, 0x6b, 0xeb, 0xff, 0xff, - 0x87, 0x83, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, 0x2e, 0xeb, 0xff, 0x1f, - 0x50, 0xf5, 0xff, 0x1f, 0xa0, 0xf7, 0xff, 0x1f, 0x92, 0xf6, 0xff, 0x1f, - 0x74, 0xf3, 0xff, 0x1f, 0x1a, 0xf5, 0xff, 0x1f, 0x4c, 0xf3, 0xff, 0x1f, - 0x88, 0xf7, 0x7f, 0xcb, 0x68, 0xbb, 0xec, 0x93, 0x46, 0xce, 0xdd, 0xbe, - 0xfe, 0xcd, 0xff, 0x1f, 0x9c, 0xf3, 0x9d, 0x6b, 0x9e, 0x4b, 0x9f, 0x6b, - 0x56, 0xc4, 0x9f, 0x4b, 0x6e, 0xeb, 0xff, 0xff, 0x2e, 0xeb, 0xe9, 0xef, - 0xff, 0x1f, 0xcd, 0xf9, 0x6a, 0xef, 0xfb, 0x23, 0xc8, 0xff, 0xff, 0x1f, - 0xc0, 0xf4, 0xbc, 0x93, 0xec, 0xef, 0x00, 0x1c, 0x2c, 0x06, 0xff, 0xcc, - 0x9b, 0x23, 0xc6, 0xff, 0x9b, 0x23, 0xd5, 0xff, 0xfe, 0xcf, 0xff, 0x1f, - 0xca, 0xf7, 0xe8, 0x53, 0xfb, 0x27, 0xc8, 0xff, 0xfe, 0xce, 0x05, 0xcd, - 0xbe, 0xbd, 0xfe, 0xcc, 0xff, 0x1f, 0x6b, 0xfb, 0xfb, 0x27, 0xc8, 0xff, - 0xfd, 0xce, 0xf8, 0xcd, 0xfe, 0xcc, 0xff, 0x1f, 0x72, 0xfb, 0xfb, 0x27, - 0xc8, 0xff, 0xfb, 0xce, 0xff, 0x1f, 0xa9, 0xfa, 0x6e, 0xeb, 0xff, 0xff, - 0xcf, 0xa3, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, 0x67, 0x83, 0xff, 0xff, - 0x2c, 0xeb, 0x9d, 0xec, 0x9b, 0x7c, 0x9c, 0x1b, 0xfb, 0xdf, 0x33, 0x8b, - 0xbf, 0xc4, 0x2c, 0xf3, 0xa1, 0xed, 0xde, 0x6d, 0x90, 0xbe, 0x8c, 0xb4, - 0xff, 0xdc, 0x8c, 0xbc, 0x90, 0xb4, 0xe3, 0xed, 0xbf, 0x97, 0x3b, 0x93, - 0x9e, 0x4d, 0xc4, 0xed, 0xdc, 0x3b, 0xdd, 0xdf, 0xdf, 0xcc, 0x35, 0x9b, - 0xf2, 0xf7, 0x86, 0xed, 0xbc, 0x6c, 0x57, 0xc5, 0xbc, 0x4c, 0xbd, 0x6c, - 0x0f, 0xca, 0x4f, 0xba, 0x6b, 0x93, 0xbd, 0x4c, 0xff, 0x1f, 0x1b, 0xf8, - 0xcf, 0xfa, 0x5f, 0xcc, 0x9b, 0xbc, 0x35, 0x9b, 0xb7, 0xf7, 0xff, 0x1f, - 0x10, 0xf4, 0x8f, 0xed, 0xbd, 0x6c, 0xef, 0xed, 0x7f, 0x97, 0xbd, 0x4c, - 0x95, 0xed, 0x5b, 0x7c, 0x9a, 0x1b, 0xfc, 0xdf, 0xbf, 0xc4, 0xce, 0xf7, - 0x78, 0xed, 0x3d, 0x6b, 0xf7, 0xb9, 0xf7, 0xb7, 0xdc, 0x73, 0xc8, 0xbe, - 0xc7, 0xb6, 0x00, 0x1c, 0x1c, 0x0a, 0xf7, 0xbf, 0xf7, 0xb7, 0x27, 0xb1, - 0x27, 0xb9, 0x7f, 0x92, 0x3d, 0x4b, 0x5a, 0x1b, 0xf7, 0xdf, 0xab, 0x8a, - 0xbf, 0xc2, 0xfc, 0xf3, 0xfe, 0x53, 0xed, 0xfb, 0x83, 0xee, 0x9e, 0x74, - 0xfb, 0xd4, 0x3e, 0x9b, 0xf2, 0xf3, 0x85, 0xee, 0xbb, 0x7c, 0x7f, 0xc5, - 0x7e, 0xc5, 0x5f, 0xc5, 0xbb, 0x5c, 0xee, 0xcf, 0xff, 0x1f, 0x03, 0xf6, - 0xfe, 0xcf, 0xff, 0x1f, 0x06, 0xf6, 0x8b, 0xee, 0xbd, 0x6c, 0xa7, 0xb5, + 0x2b, 0xeb, 0xde, 0xeb, 0xfe, 0x8a, 0x3e, 0xc3, 0x7a, 0xf3, 0x87, 0xee, + 0x9c, 0x6c, 0x37, 0xc4, 0xc2, 0xf3, 0x0f, 0xee, 0x58, 0x1b, 0xf0, 0xff, + 0x9f, 0x72, 0x3d, 0xb4, 0x26, 0xa4, 0x66, 0x8a, 0x3f, 0x52, 0xff, 0x1f, + 0x02, 0xf6, 0xfd, 0xb7, 0x3f, 0xa1, 0x66, 0x8a, 0x3f, 0x52, 0x95, 0xee, + 0xbd, 0x6c, 0xbd, 0x1b, 0x00, 0xcf, 0xdd, 0xb1, 0xbb, 0x8b, 0x7b, 0x93, + 0xbd, 0x4c, 0x8b, 0x78, 0xbf, 0xc4, 0xec, 0xf3, 0xfc, 0x15, 0x3c, 0xfe, + 0x73, 0x9a, 0xf9, 0xf7, 0xff, 0xcf, 0xfd, 0xce, 0x00, 0x1c, 0x83, 0x00, + 0xe4, 0xfb, 0x5b, 0xcc, 0x9e, 0xbc, 0x73, 0x9a, 0xe8, 0xf7, 0xfc, 0xcf, + 0xff, 0xce, 0x00, 0x1c, 0x8c, 0x00, 0xed, 0xfb, 0xfc, 0x15, 0x3c, 0xfe, + 0x73, 0x9a, 0xf9, 0xf7, 0xff, 0xcf, 0xfd, 0xce, 0x00, 0x1c, 0x95, 0x00, + 0xf6, 0xfb, 0x32, 0xcc, 0x9e, 0xbc, 0x73, 0x9a, 0xfa, 0xf7, 0xfc, 0xcf, + 0xff, 0xce, 0x00, 0x1c, 0x9e, 0x00, 0x8d, 0xef, 0x9b, 0x7c, 0x9c, 0x1b, + 0xfb, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0xc5, 0xf7, 0x4c, 0xef, 0x9e, 0x72, + 0x3d, 0xb4, 0x26, 0xa4, 0x66, 0x8a, 0x3e, 0x52, 0xfe, 0xcf, 0xff, 0x1f, + 0x24, 0xf6, 0xfd, 0xb7, 0x3f, 0xa1, 0x66, 0x8a, 0x3e, 0x52, 0x96, 0xef, + 0xdd, 0x6c, 0xb1, 0xef, 0xb7, 0x97, 0xbd, 0xb1, 0x77, 0x8b, 0xb7, 0xbd, + 0x7b, 0x93, 0xbd, 0x4c, 0xfc, 0x15, 0x0a, 0xfe, 0x73, 0x9a, 0xe7, 0xf7, + 0xed, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x6f, 0xff, 0xbf, + 0x00, 0x00, 0xff, 0x00, 0xf3, 0xff, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xbf, + 0xef, 0xff, 0xff, 0xdf, 0xff, 0x5f, 0xff, 0xbf, 0x00, 0xff, 0x00, 0x00, + 0xff, 0xcf, 0xfe, 0xce, 0x00, 0x1c, 0xd5, 0x00, 0xf6, 0xfb, 0xfc, 0x15, + 0x66, 0xfe, 0x73, 0x9a, 0xfa, 0xf3, 0xff, 0xcf, 0xfc, 0xce, 0x00, 0x1c, + 0xde, 0x00, 0xff, 0x1f, 0x64, 0xf6, 0x7b, 0x1b, 0xfd, 0xbf, 0x31, 0xc3, + 0xad, 0xf3, 0xbe, 0xec, 0xff, 0xcc, 0xff, 0xd4, 0x87, 0x5d, 0xfd, 0x27, + 0xcf, 0xff, 0x7f, 0xce, 0xd8, 0xbe, 0xff, 0x1f, 0x98, 0xf9, 0xbc, 0x92, + 0xbe, 0x6f, 0x9f, 0x7d, 0xbe, 0xc4, 0xe3, 0xf3, 0xbf, 0xc4, 0xf9, 0xf3, + 0xbd, 0xc4, 0xda, 0xf3, 0xbc, 0xc4, 0xc8, 0xf7, 0xd2, 0xfb, 0x88, 0xed, + 0xbf, 0x6c, 0x76, 0xc5, 0xbf, 0x4c, 0xbd, 0x6c, 0x9e, 0x6c, 0x8c, 0xed, + 0xbb, 0x7c, 0x7d, 0xc5, 0xbb, 0x5c, 0x8c, 0xed, 0xbd, 0x6c, 0xcc, 0xed, + 0x7b, 0x97, 0xbd, 0x4c, 0x8d, 0xed, 0xff, 0xcd, 0xbf, 0x4c, 0xbe, 0x4c, + 0xdd, 0xfb, 0xde, 0x75, 0xef, 0xed, 0x00, 0x1c, 0x8e, 0x02, 0x9e, 0x6a, + 0xbe, 0x74, 0x96, 0xed, 0xa6, 0x54, 0xfd, 0xcf, 0xff, 0xce, 0x00, 0x1c, + 0x1a, 0x01, 0xea, 0xfb, 0xff, 0xcd, 0x9a, 0xed, 0xa6, 0x54, 0xfe, 0xcf, + 0x00, 0x1c, 0x67, 0x01, 0xfe, 0xcf, 0xff, 0xce, 0x00, 0x1c, 0x25, 0x01, + 0xf5, 0xfb, 0xff, 0xcd, 0x80, 0xee, 0xa6, 0x54, 0xff, 0x1f, 0x7b, 0xf2, + 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, 0x2f, 0x01, 0xe8, 0x93, 0xff, 0x1f, + 0xea, 0xf9, 0x7f, 0xcc, 0x98, 0xbc, 0xf2, 0x92, 0x33, 0xc3, 0x10, 0xf3, + 0xfc, 0xcf, 0x00, 0x1c, 0x0c, 0x01, 0x7c, 0x92, 0x4a, 0xee, 0xfa, 0x27, + 0xcf, 0xff, 0x7f, 0xce, 0xda, 0xbe, 0xff, 0x1f, 0xec, 0xf9, 0x9e, 0x6f, + 0x1f, 0x7c, 0xff, 0x1f, 0xfe, 0xf9, 0xe9, 0xee, 0xa4, 0x93, 0x00, 0x1c, + 0xc6, 0x02, 0x8b, 0x7a, 0xbf, 0xc4, 0xf9, 0xf3, 0xfc, 0x15, 0xe0, 0xfc, + 0x73, 0x9a, 0xf9, 0xf7, 0x2e, 0xfb, 0xfc, 0x15, 0x18, 0xfc, 0x73, 0x9a, + 0x32, 0xf3, 0xa1, 0x8a, 0x91, 0xee, 0xbf, 0x7c, 0x00, 0xcc, 0x35, 0x9b, + 0xee, 0xf7, 0x33, 0xee, 0xff, 0xcc, 0x9f, 0x59, 0xff, 0xc8, 0x1d, 0x49, + 0x1c, 0x49, 0x1b, 0x49, 0x1a, 0x49, 0x05, 0xcc, 0x9e, 0xbc, 0x9c, 0x51, + 0xff, 0x1f, 0x6d, 0xf3, 0xfd, 0x51, 0x1e, 0x59, 0x1d, 0x59, 0x9b, 0xee, + 0x5d, 0x4c, 0xbb, 0x6c, 0xb7, 0xa2, 0xbb, 0x4c, 0xbc, 0x6c, 0xb6, 0xa2, + 0xba, 0x4c, 0x5c, 0x4c, 0xfa, 0xba, 0x58, 0xba, 0xeb, 0xa7, 0xff, 0x3b, + 0xbf, 0xf7, 0x05, 0xce, 0xdd, 0xbe, 0xff, 0x1f, 0xae, 0xf1, 0x3c, 0x93, + 0xff, 0xcd, 0xe2, 0xd5, 0x7e, 0x9b, 0xfd, 0xf3, 0x34, 0x93, 0x70, 0x92, + 0xc1, 0xc4, 0xfd, 0xf7, 0xe1, 0xc9, 0xff, 0x1f, 0x8e, 0xf3, 0x4a, 0xef, + 0xfd, 0x52, 0xff, 0x1f, 0xbc, 0xf3, 0xfc, 0x52, 0x9e, 0x7a, 0xbf, 0xc4, + 0xad, 0xf7, 0xbd, 0x72, 0x37, 0xa1, 0x66, 0x8a, 0x3d, 0x52, 0x64, 0x8b, + 0xfc, 0x15, 0xd4, 0xfd, 0x72, 0x9b, 0xe3, 0xf7, 0x9d, 0x7a, 0xbe, 0xc4, + 0xfc, 0xf7, 0xfe, 0xcd, 0xbe, 0x5a, 0x74, 0xcc, 0x9d, 0xbc, 0xb6, 0xef, + 0x9d, 0x55, 0xee, 0xfb, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xbf, + 0xff, 0x5f, 0xff, 0xbf, 0x00, 0x00, 0xf0, 0x00, 0xff, 0x8f, 0xff, 0xbf, + 0xe7, 0x8d, 0xff, 0xff, 0xd3, 0x8d, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xdf, + 0x99, 0xfb, 0x85, 0xed, 0x9d, 0x7c, 0xbf, 0xc4, 0xf8, 0xf7, 0x64, 0x8a, + 0x9c, 0x1b, 0xff, 0xfc, 0x72, 0x9a, 0xf5, 0xf7, 0xa3, 0xfb, 0xbe, 0xc4, + 0xa5, 0xf7, 0x64, 0x8a, 0x6c, 0xcc, 0x9d, 0xbc, 0x72, 0x9a, 0xe7, 0xf7, + 0xab, 0xfb, 0x8d, 0xed, 0xfe, 0xcd, 0xa5, 0x5c, 0xa6, 0x74, 0xa5, 0xcc, + 0x35, 0x9b, 0xf8, 0xf7, 0x92, 0xed, 0x37, 0xcd, 0xbc, 0x54, 0xfe, 0xcd, + 0xbe, 0x5c, 0xfa, 0xfb, 0x05, 0xcc, 0x9e, 0xbc, 0xb6, 0xed, 0x9c, 0x55, + 0x74, 0xcc, 0x9d, 0xbc, 0xb8, 0xed, 0x9d, 0x55, 0xc1, 0xfb, 0x6c, 0xcc, + 0x9d, 0xbc, 0xba, 0xed, 0x9d, 0x55, 0xc6, 0xfb, 0xbe, 0xc4, 0xc8, 0xf7, + 0xe7, 0xa7, 0xfe, 0x8b, 0x9d, 0xed, 0xf0, 0x54, 0xa6, 0x74, 0x91, 0xcc, + 0x35, 0x9b, 0xea, 0xf7, 0x7c, 0x8b, 0x06, 0xcc, 0x72, 0x9b, 0xfa, 0xf7, + 0x05, 0xcd, 0x83, 0xee, 0xbc, 0x54, 0xd8, 0xfb, 0xfc, 0x8b, 0x05, 0xcc, + 0x9e, 0xbc, 0xf2, 0x9b, 0xdd, 0xf3, 0xa7, 0xee, 0x05, 0xcc, 0x9e, 0xbc, + 0x9c, 0x55, 0xff, 0xcc, 0x9e, 0x5d, 0xe4, 0xfb, 0x7c, 0x8b, 0x9c, 0xcc, + 0x72, 0x9b, 0xf3, 0xf7, 0x8d, 0xee, 0x74, 0xcd, 0xbd, 0xbd, 0xbd, 0x54, + 0x05, 0xcd, 0xbe, 0xbd, 0xbc, 0x54, 0xff, 0xcd, 0xbd, 0x5c, 0xbe, 0x5c, + 0xf3, 0xfb, 0xfc, 0x8b, 0x05, 0xcc, 0x9e, 0xbc, 0xf2, 0x9b, 0xf8, 0xf3, + 0xb5, 0xee, 0x05, 0xcc, 0x9e, 0xbc, 0x9c, 0x55, 0xff, 0xcc, 0x9e, 0x5d, + 0x98, 0xee, 0xfd, 0x74, 0xdc, 0x74, 0xbd, 0x7c, 0xfe, 0xcc, 0xff, 0x1f, + 0x08, 0xf4, 0x7f, 0xce, 0xda, 0xbe, 0xfa, 0x92, 0x34, 0xc3, 0xa5, 0xf3, + 0x9d, 0xee, 0xfc, 0x27, 0xcf, 0xff, 0x7f, 0xce, 0xdb, 0xbe, 0xff, 0x1f, + 0xd8, 0xfa, 0x3c, 0x92, 0x9e, 0x6f, 0x9f, 0x7c, 0xbd, 0xbc, 0x38, 0xbc, + 0x36, 0xa1, 0x93, 0xa1, 0x9c, 0x3b, 0xbc, 0xf7, 0x3b, 0xac, 0x00, 0x1c, + 0xec, 0x01, 0xbc, 0x92, 0xfc, 0xcf, 0x00, 0x1c, 0x10, 0x02, 0x3c, 0x93, + 0xbd, 0xbf, 0xdb, 0xbf, 0xb6, 0xa6, 0xbe, 0xa5, 0xdc, 0xbd, 0xb6, 0xa6, + 0xb9, 0xad, 0x27, 0xa5, 0xa6, 0xa2, 0xbf, 0x47, 0xed, 0xef, 0xa4, 0x93, + 0x68, 0x93, 0x00, 0x1c, 0xca, 0x03, 0xa7, 0x9a, 0xdf, 0xf7, 0x46, 0xa2, + 0xaa, 0x8a, 0xfc, 0x15, 0x47, 0xf4, 0xb3, 0x9a, 0xe0, 0xf3, 0xfc, 0x15, + 0x23, 0xfa, 0xb3, 0x9a, 0xf4, 0xf7, 0xb6, 0xef, 0x9d, 0x27, 0xcb, 0xff, + 0xff, 0xdc, 0x33, 0x8b, 0x9d, 0x23, 0xcb, 0xff, 0xfd, 0xc4, 0xe6, 0xf3, + 0xee, 0xfb, 0xff, 0xcd, 0x9c, 0xef, 0xbc, 0x23, 0xcb, 0xff, 0xec, 0xfb, + 0xe7, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xdf, 0xc7, 0x8d, 0xff, 0xff, + 0xff, 0xcd, 0x92, 0xec, 0xbc, 0x23, 0xcb, 0xff, 0xf7, 0xfb, 0xff, 0xcf, + 0x00, 0x1c, 0xbd, 0x02, 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, 0x7b, 0x02, + 0xe0, 0x93, 0xff, 0x1f, 0x36, 0xfb, 0x7b, 0x1b, 0xff, 0xb7, 0x3d, 0xc3, + 0xf5, 0xf3, 0xfe, 0xcf, 0x00, 0x1c, 0xcb, 0x02, 0xfe, 0xcf, 0xff, 0xce, + 0x00, 0x1c, 0x89, 0x02, 0x7b, 0x1b, 0xfb, 0xbf, 0x3f, 0xc3, 0xf0, 0xf3, + 0xff, 0x1f, 0xed, 0xf2, 0x82, 0xed, 0x91, 0x7c, 0xbf, 0xc4, 0xf6, 0xf3, + 0xff, 0x1f, 0x3f, 0xf7, 0x84, 0xed, 0xdf, 0x7c, 0xbe, 0x7c, 0xe4, 0xed, + 0x00, 0x1c, 0x17, 0x04, 0xff, 0xcf, 0xfe, 0xeb, 0x6b, 0xeb, 0xff, 0xff, + 0x2e, 0xeb, 0xff, 0x1f, 0xaa, 0xf5, 0xff, 0x1f, 0x1e, 0xf8, 0xff, 0x1f, + 0xe2, 0xf6, 0xff, 0x1f, 0xba, 0xf3, 0xff, 0x1f, 0x66, 0xf5, 0xff, 0x1f, + 0x20, 0xf3, 0xff, 0x1f, 0x04, 0xf8, 0x7f, 0xcb, 0x68, 0xbb, 0xec, 0x93, + 0x46, 0xce, 0xdd, 0xbe, 0xfe, 0xcd, 0xff, 0x1f, 0xe2, 0xf3, 0x9d, 0x6b, + 0x9e, 0x4b, 0x9f, 0x6b, 0x56, 0xc4, 0x9f, 0x4b, 0x6e, 0xeb, 0xff, 0xff, + 0x2e, 0xeb, 0xf6, 0xed, 0xff, 0x1f, 0x47, 0xfa, 0xbc, 0x93, 0x9b, 0xed, + 0xfc, 0x23, 0xcf, 0xff, 0x00, 0xcc, 0x3d, 0x9b, 0xfb, 0xf3, 0xfa, 0xed, + 0x00, 0x1c, 0x47, 0x04, 0xff, 0x1f, 0x13, 0xf5, 0xbc, 0x93, 0xfc, 0xed, + 0x00, 0x1c, 0x4d, 0x04, 0x63, 0xee, 0xff, 0xcc, 0x8b, 0x5b, 0x91, 0x5b, + 0xfe, 0xcf, 0xff, 0x1f, 0x4e, 0xf8, 0xf6, 0x53, 0xfb, 0x27, 0xcf, 0xff, + 0xfe, 0xce, 0x05, 0xcd, 0xbe, 0xbd, 0xfe, 0xcc, 0xff, 0x1f, 0x13, 0xfc, + 0xfb, 0x27, 0xcf, 0xff, 0xfd, 0xce, 0xf8, 0xcd, 0xfe, 0xcc, 0xff, 0x1f, + 0x1a, 0xfc, 0xfb, 0x27, 0xcf, 0xff, 0xfb, 0xce, 0xff, 0x1f, 0x33, 0xfb, + 0x6e, 0xeb, 0xff, 0xff, 0x2c, 0xeb, 0x92, 0xee, 0x9b, 0x7c, 0x9c, 0x1b, + 0xfb, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0x26, 0xf3, 0xb6, 0xee, 0xde, 0x6d, + 0x90, 0xbe, 0x8c, 0xb4, 0xff, 0xdc, 0x8c, 0xbc, 0x90, 0xb4, 0xf3, 0xee, + 0xbf, 0x97, 0x3b, 0x93, 0x9e, 0x4d, 0xd4, 0xee, 0xdc, 0x3b, 0xdd, 0xdf, + 0xdf, 0xcc, 0x35, 0x9b, 0xf2, 0xf7, 0x96, 0xee, 0xbc, 0x6c, 0x57, 0xc5, + 0xbc, 0x4c, 0xbd, 0x6c, 0x0f, 0xca, 0x4f, 0xba, 0x6b, 0x93, 0xbd, 0x4c, + 0xff, 0x1f, 0x97, 0xf8, 0xf9, 0xfa, 0x5f, 0xcc, 0x9b, 0xbc, 0x35, 0x9b, + 0xa1, 0xf7, 0xff, 0x1f, 0x6a, 0xf4, 0x9f, 0xee, 0xbd, 0x6c, 0xff, 0xee, + 0x7f, 0x97, 0xbd, 0x4c, 0x8a, 0xef, 0x5b, 0x7c, 0x9a, 0x1b, 0xfc, 0xdf, + 0xbf, 0xc4, 0xb8, 0xf7, 0x6d, 0xef, 0x3d, 0x6b, 0xf7, 0xb9, 0xf7, 0xb7, + 0xdc, 0x73, 0xc8, 0xbe, 0xc7, 0xb6, 0xff, 0x1f, 0x5e, 0xf3, 0xf7, 0xbf, + 0xf7, 0xb7, 0x27, 0xb1, 0x27, 0xb9, 0x7f, 0x92, 0x3d, 0x4b, 0x5a, 0x1b, + 0xf7, 0xdf, 0xab, 0x8a, 0xbf, 0xc2, 0xfc, 0xf3, 0xfe, 0x53, 0xd7, 0xfb, + 0x98, 0xef, 0x9e, 0x74, 0xfb, 0xd4, 0x3e, 0x9b, 0xdc, 0xf3, 0x9a, 0xef, + 0xbb, 0x7c, 0x7f, 0xc5, 0x7e, 0xc5, 0x5f, 0xc5, 0xbb, 0x5c, 0xee, 0xcf, + 0xe9, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xf3, 0xff, 0xff, 0xdf, + 0xa7, 0x8d, 0xff, 0xff, 0x9b, 0xae, 0xff, 0xff, 0x8f, 0x8d, 0xff, 0xff, + 0x77, 0x8d, 0xff, 0xff, 0xf0, 0xff, 0x01, 0x00, 0x0f, 0x00, 0xfe, 0xff, + 0xff, 0x5f, 0xff, 0xbf, 0x00, 0x00, 0xf0, 0x00, 0xff, 0x1f, 0x73, 0xf6, + 0xfe, 0xcf, 0xff, 0x1f, 0x76, 0xf6, 0x82, 0xed, 0xbd, 0x6c, 0xa7, 0xb5, 0xa7, 0xbd, 0xbd, 0x4c, 0xbc, 0x74, 0xbd, 0x1b, 0x01, 0xce, 0xbc, 0x54, - 0x90, 0xee, 0xbb, 0x7c, 0x7d, 0xc5, 0x7c, 0xc5, 0xbb, 0x5c, 0xbe, 0x6c, - 0xd2, 0xee, 0x7b, 0x97, 0xbe, 0x4c, 0x1a, 0xfb, 0xff, 0x1f, 0x71, 0xf8, - 0xfc, 0x92, 0xff, 0x1f, 0x3e, 0xf5, 0x92, 0xee, 0x9f, 0x74, 0xba, 0xdc, - 0xf2, 0x9a, 0xdd, 0xf3, 0x9a, 0xee, 0xbe, 0x6c, 0x5a, 0xee, 0x6b, 0x97, - 0xbe, 0x4c, 0xf6, 0xee, 0x7f, 0x97, 0xbb, 0x5c, 0xff, 0x1f, 0x69, 0xf4, - 0x9c, 0xee, 0xbd, 0x6c, 0xdc, 0xee, 0x7b, 0x97, 0xbd, 0x4c, 0x9c, 0xee, - 0x9f, 0x74, 0x88, 0xdc, 0xf2, 0x9a, 0xf6, 0xf7, 0xa4, 0xef, 0x9f, 0x7d, - 0xff, 0xdc, 0x33, 0x8b, 0x9f, 0x5d, 0xfd, 0xcd, 0x37, 0x9b, 0x40, 0xf7, - 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, 0xb9, 0x03, 0x45, 0xfb, 0x8a, 0xef, + 0x87, 0xed, 0xbb, 0x7c, 0x7d, 0xc5, 0x7c, 0xc5, 0xbb, 0x5c, 0xbe, 0x6c, + 0xc9, 0xed, 0x7b, 0x97, 0xbe, 0x4c, 0x5a, 0xfb, 0xff, 0x1f, 0x01, 0xf9, + 0xfc, 0x92, 0xff, 0x1f, 0xa8, 0xf5, 0x8c, 0xed, 0x9f, 0x74, 0xc4, 0xdc, + 0xf2, 0x9a, 0xdd, 0xf3, 0x91, 0xed, 0xbe, 0x6c, 0x51, 0xed, 0x6b, 0x97, + 0xbe, 0x4c, 0xf0, 0xed, 0x7f, 0x97, 0xbb, 0x5c, 0xff, 0x1f, 0xd9, 0xf4, + 0x92, 0xed, 0xbd, 0x6c, 0xd2, 0xed, 0x7b, 0x97, 0xbd, 0x4c, 0x96, 0xed, + 0x9f, 0x74, 0x88, 0xdc, 0xf2, 0x9a, 0xf6, 0xf7, 0xbb, 0xed, 0x9f, 0x7d, + 0xff, 0xdc, 0x33, 0x8b, 0x9f, 0x5d, 0xfd, 0xcd, 0x37, 0x9b, 0x80, 0xf7, + 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, 0x9f, 0x03, 0x85, 0xfb, 0x81, 0xee, 0xbe, 0x6c, 0xb0, 0xbd, 0xac, 0xb5, 0xaf, 0xcc, 0x72, 0x9b, 0xfb, 0xf3, - 0xff, 0xcd, 0x8e, 0xef, 0xbf, 0x5c, 0xfc, 0x15, 0x0c, 0xfe, 0xf3, 0x9b, - 0xf9, 0xf3, 0xce, 0xdf, 0xfe, 0x8b, 0xff, 0x1f, 0x90, 0xf5, 0x58, 0xfb, - 0x94, 0xef, 0x9b, 0x7c, 0x9c, 0x1b, 0xfc, 0xdf, 0xbf, 0xc4, 0x5e, 0xf7, - 0x97, 0xef, 0xbc, 0x74, 0xc8, 0xbd, 0xc7, 0xb6, 0xff, 0xde, 0xbb, 0x8b, + 0xff, 0xcd, 0x85, 0xee, 0xbf, 0x5c, 0xfc, 0x15, 0x0c, 0xfe, 0xf3, 0x9b, + 0xf9, 0xf3, 0xce, 0xdf, 0xfe, 0x8b, 0xff, 0x1f, 0xf4, 0xf5, 0x98, 0xfb, + 0x8b, 0xee, 0x9b, 0x7c, 0x9c, 0x1b, 0xfc, 0xdf, 0xbf, 0xc4, 0x9e, 0xf7, + 0x8e, 0xee, 0xbc, 0x74, 0xc8, 0xbd, 0xc7, 0xb6, 0xff, 0xde, 0xbb, 0x8b, 0xde, 0xbe, 0xbd, 0x1b, 0x01, 0xce, 0x7b, 0x93, 0xbc, 0x54, 0xbd, 0x6c, - 0xd7, 0xbd, 0xd7, 0xb6, 0xef, 0xfb, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, - 0xf0, 0xff, 0x01, 0x00, 0x0f, 0x00, 0xfe, 0xff, 0xff, 0x5f, 0xff, 0xbf, - 0x00, 0x00, 0xf0, 0x00, 0x8b, 0xfe, 0xff, 0xdf, 0xf4, 0xff, 0x01, 0x00, - 0x7b, 0xa3, 0x77, 0xbb, 0x77, 0xb3, 0xa7, 0xb5, 0xa7, 0xbd, 0x6f, 0x93, - 0xbd, 0x4c, 0x84, 0xfb, 0xc1, 0xee, 0xfe, 0x6e, 0x90, 0xbf, 0x8c, 0xb4, - 0xff, 0xdc, 0x8c, 0xbc, 0x8c, 0xb4, 0x7b, 0xbc, 0x44, 0xee, 0x5f, 0x3b, - 0xdd, 0xdf, 0x6f, 0x93, 0xbe, 0x4e, 0xe5, 0xee, 0x7f, 0x97, 0xaf, 0xc5, - 0xf3, 0xf7, 0xa6, 0xee, 0xff, 0xce, 0xdf, 0x4d, 0xdf, 0x6d, 0xdf, 0x4d, - 0xdf, 0x6d, 0x5d, 0xc6, 0xdf, 0x4d, 0xdf, 0x6d, 0x5c, 0xc6, 0xdf, 0x4d, - 0xaf, 0xee, 0xbb, 0x7d, 0xbd, 0x1b, 0xf7, 0xdf, 0x77, 0x8b, 0xbf, 0xc5, - 0xfa, 0xf3, 0x9c, 0xcd, 0x36, 0x9b, 0xf9, 0xf7, 0xb6, 0xfb, 0xfd, 0x15, - 0x30, 0xf8, 0x36, 0x9b, 0xba, 0xf3, 0x96, 0xee, 0xff, 0xcd, 0xbc, 0x23, - 0xcf, 0xff, 0xbb, 0x7c, 0x5d, 0xc5, 0xbb, 0x5c, 0xbe, 0x6c, 0x59, 0xee, - 0x6b, 0x97, 0xbe, 0x4c, 0x99, 0xee, 0xff, 0xcf, 0xff, 0x4c, 0xff, 0x1f, - 0x80, 0xf4, 0xbe, 0xc7, 0xfa, 0xf3, 0xff, 0x1f, 0x84, 0xf4, 0xbd, 0xc7, - 0xe8, 0xf7, 0x81, 0xef, 0x9b, 0x7c, 0x9c, 0x1b, 0xfc, 0xdf, 0xbf, 0xc4, - 0xf6, 0xf7, 0x55, 0xcf, 0xfd, 0xbf, 0xcd, 0xce, 0xff, 0xcd, 0xfe, 0xcc, - 0xff, 0x1f, 0x91, 0xf5, 0xe1, 0xfb, 0x55, 0xcf, 0xfd, 0xbf, 0xcd, 0xce, - 0xff, 0xcd, 0xfe, 0xcc, 0xff, 0x1f, 0x99, 0xf5, 0xe9, 0xfb, 0x8c, 0xef, - 0x9b, 0x7c, 0x9c, 0x1b, 0xfc, 0xdf, 0xbf, 0xc4, 0xf6, 0xf7, 0x74, 0xcf, - 0xfd, 0xbf, 0xcd, 0xce, 0xff, 0xcd, 0xfe, 0xcc, 0xff, 0x1f, 0xa7, 0xf5, - 0xf7, 0xfb, 0xff, 0x15, 0x7a, 0xfd, 0xcd, 0xce, 0xff, 0xcd, 0xfe, 0xcc, - 0xff, 0x1f, 0xaf, 0xf5, 0xff, 0x1f, 0xf3, 0xf8, 0xf3, 0xfb, 0xdb, 0xc4, - 0xf9, 0xf7, 0xfe, 0xcd, 0x9a, 0xef, 0xbc, 0x23, 0xcf, 0xff, 0xfa, 0xfb, - 0xff, 0xcd, 0x9c, 0xef, 0xbc, 0x23, 0xcf, 0xff, 0x6c, 0xeb, 0xff, 0xff, - 0xfb, 0xff, 0xff, 0xdf, 0xf0, 0xff, 0x01, 0x00, 0x0f, 0x00, 0xfe, 0xff, - 0xff, 0x8f, 0xff, 0xbf, 0x2d, 0xeb, 0x9c, 0xee, 0xbc, 0x6c, 0x77, 0x8b, - 0x55, 0xcc, 0x35, 0x9b, 0xf9, 0xf7, 0xff, 0xcd, 0x9f, 0xee, 0xbc, 0x23, - 0xd5, 0xff, 0xc5, 0xfb, 0x82, 0xef, 0xbc, 0x6c, 0x77, 0x8b, 0xaa, 0xcc, - 0x35, 0x9b, 0xcb, 0xf7, 0x85, 0xef, 0x9f, 0x6c, 0x33, 0x8b, 0xae, 0xc4, - 0xf7, 0xf3, 0xad, 0xc4, 0xf4, 0xf3, 0xbf, 0xc4, 0xd4, 0xf7, 0xff, 0x1f, - 0x60, 0xf5, 0xd7, 0xfb, 0xff, 0xcd, 0x8a, 0xef, 0xbc, 0x23, 0xc6, 0xff, - 0xdc, 0xfb, 0xfe, 0xcd, 0x8d, 0xef, 0xbc, 0x23, 0xc6, 0xff, 0xff, 0x1f, - 0xf2, 0xf4, 0xbf, 0xc7, 0xe4, 0xf7, 0xff, 0xcd, 0x91, 0xef, 0xad, 0x54, - 0xfe, 0xcf, 0xff, 0x1f, 0x00, 0xf5, 0xfa, 0xcf, 0xff, 0x1f, 0xf7, 0xf4, - 0xff, 0x1f, 0x79, 0xf5, 0x55, 0xef, 0xff, 0xcb, 0xff, 0xd3, 0xff, 0x1f, - 0x12, 0xf5, 0xff, 0xd2, 0xe9, 0x9a, 0x03, 0xf4, 0xfe, 0xcf, 0x00, 0x1c, - 0x0a, 0x07, 0xfe, 0xcf, 0xf7, 0xce, 0x00, 0x1c, 0xc2, 0x04, 0x6d, 0xeb, - 0xff, 0x6f, 0xff, 0xbf, 0xfb, 0xff, 0xff, 0xdf, 0xc0, 0xf2, 0xfc, 0xff, + 0xd7, 0xbd, 0xd7, 0xb6, 0x7b, 0xa3, 0x77, 0xbb, 0x77, 0xb3, 0xa7, 0xb5, + 0xa7, 0xbd, 0x6f, 0x93, 0xbd, 0x4c, 0xb4, 0xfb, 0xb9, 0xee, 0xde, 0x6d, + 0xf0, 0xbe, 0xec, 0xb7, 0xff, 0xdf, 0xec, 0xbf, 0xec, 0xb7, 0x7b, 0xbf, + 0x5c, 0xee, 0x5e, 0x3b, 0xdc, 0xdf, 0x2f, 0x93, 0x9e, 0x4d, 0xd9, 0xee, + 0x3b, 0x97, 0xaf, 0xc4, 0xf3, 0xf7, 0x9a, 0xee, 0xff, 0xcd, 0xbf, 0x4c, + 0xbf, 0x6c, 0xbf, 0x4c, 0xbf, 0x6c, 0x5d, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, + 0x5c, 0xc5, 0xbf, 0x4c, 0x87, 0xef, 0x9b, 0x7c, 0x9c, 0x1b, 0xf7, 0xdf, + 0x33, 0x8b, 0xbf, 0xc4, 0xfa, 0xf3, 0x9c, 0xcc, 0xf2, 0x9b, 0xf9, 0xf7, + 0xdb, 0xfb, 0xfc, 0x15, 0x30, 0xf8, 0xf2, 0x9b, 0xdf, 0xf3, 0x8e, 0xef, + 0xbb, 0x7c, 0x5d, 0xc5, 0xbb, 0x5c, 0xbe, 0x6c, 0x50, 0xef, 0x6b, 0x97, + 0xbe, 0x4c, 0x8b, 0xef, 0xff, 0xcf, 0xff, 0x4c, 0xbd, 0x1b, 0xfc, 0xdf, + 0xbf, 0xc5, 0xf7, 0xf7, 0x74, 0xcf, 0xfd, 0xbf, 0xcd, 0xce, 0xfe, 0xcc, + 0xff, 0x1f, 0xf5, 0xf5, 0xf7, 0xfb, 0xff, 0x15, 0x7a, 0xfd, 0xcd, 0xce, + 0xff, 0xcd, 0xfe, 0xcc, 0xff, 0x1f, 0xfd, 0xf5, 0xff, 0x1f, 0x51, 0xf9, + 0x6c, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xf0, 0xff, 0x01, 0x00, + 0x97, 0xfe, 0xff, 0xdf, 0xf4, 0xff, 0x01, 0x00, 0xff, 0x5f, 0xff, 0xbf, + 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0xfe, 0xff, 0xff, 0x8f, 0xff, 0xbf, + 0x2f, 0xeb, 0x8c, 0xef, 0xbc, 0x6c, 0x77, 0x8b, 0x55, 0xcc, 0x35, 0x9b, + 0xfa, 0xf7, 0xff, 0xcd, 0x8f, 0xef, 0xb1, 0x5c, 0xe5, 0xfb, 0x91, 0xef, + 0xbc, 0x6c, 0x77, 0x8b, 0xaa, 0xcc, 0x35, 0x9b, 0xeb, 0xf7, 0x94, 0xef, + 0x9f, 0x6c, 0x33, 0x8b, 0xae, 0xc4, 0xf7, 0xf3, 0xad, 0xc4, 0xf5, 0xf3, + 0xbf, 0xc4, 0xf4, 0xf7, 0xff, 0x1f, 0x97, 0xf5, 0xf7, 0xfb, 0xff, 0xcd, + 0x9a, 0xef, 0xab, 0x5c, 0xfb, 0xfb, 0xfe, 0xcd, 0x9c, 0xef, 0xab, 0x5c, + 0x6f, 0xeb, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xdf, 0x2e, 0xeb, 0xff, 0x8a, 0x94, 0xef, 0x7f, 0x5c, 0xf7, 0xcf, 0xff, 0x1f, - 0xea, 0xfc, 0xbf, 0xc7, 0xf5, 0xf3, 0x7f, 0xcc, 0x98, 0xbc, 0x9e, 0x57, - 0xfd, 0xcc, 0x9f, 0x5f, 0x9a, 0xef, 0x9e, 0x4f, 0xff, 0x1f, 0xd9, 0xfb, - 0xfb, 0xef, 0xac, 0x93, 0x00, 0x1c, 0x11, 0x08, 0x6e, 0xeb, 0xff, 0xff, - 0xbf, 0xff, 0xff, 0xdf, 0x53, 0x83, 0xff, 0xff, 0x2b, 0xeb, 0xdc, 0xeb, - 0xbe, 0x8a, 0x32, 0xc2, 0xf2, 0xf3, 0x63, 0xed, 0x31, 0xa3, 0xe5, 0xa3, - 0xff, 0x1f, 0x19, 0xfd, 0xff, 0xcc, 0x9f, 0x59, 0xfe, 0xcc, 0x9e, 0x5b, - 0x7f, 0xcf, 0xf9, 0xbf, 0xbe, 0x92, 0x28, 0x8b, 0x20, 0xc4, 0x07, 0xf3, - 0x8b, 0xed, 0xf7, 0x7c, 0x7f, 0xce, 0xd7, 0xbe, 0xff, 0x1f, 0xf1, 0xfc, - 0xfd, 0x47, 0xde, 0x6f, 0xde, 0x47, 0xb9, 0xa6, 0xbf, 0x47, 0x7e, 0x7e, - 0xf0, 0xed, 0x00, 0x1c, 0x3a, 0x08, 0xbf, 0xc3, 0xf3, 0xf3, 0x3f, 0x67, - 0x12, 0xed, 0xdf, 0x79, 0xff, 0xd9, 0xe0, 0x93, 0x00, 0x1c, 0x43, 0x08, - 0xff, 0xd3, 0xef, 0x8a, 0xbf, 0xc3, 0x07, 0xf4, 0x96, 0xed, 0xff, 0xcd, - 0xbf, 0x5c, 0xbc, 0x7c, 0x00, 0xcc, 0x35, 0x9b, 0xec, 0xf7, 0x7c, 0xed, - 0x9b, 0x1b, 0xf4, 0xff, 0xbf, 0x7c, 0xbd, 0x1b, 0x03, 0xdf, 0xbd, 0x1b, - 0xe3, 0xcf, 0xbd, 0x1b, 0xe3, 0xdf, 0xbf, 0x5c, 0xf7, 0x7b, 0xfe, 0xce, - 0x69, 0xcd, 0xfe, 0xcc, 0xff, 0x1f, 0x8d, 0xfd, 0xf8, 0x5b, 0x9e, 0x67, - 0x7e, 0x7c, 0xbe, 0xc3, 0xed, 0xf3, 0xfe, 0xd3, 0xef, 0x8a, 0xdf, 0x67, - 0xfd, 0xa6, 0xef, 0xa7, 0x38, 0x93, 0xff, 0xcd, 0xdf, 0x7c, 0x7a, 0x93, - 0xff, 0xdc, 0xf1, 0x9b, 0x03, 0xf4, 0xff, 0xdb, 0x9f, 0x67, 0x8f, 0xa4, + 0x2a, 0xfd, 0xbf, 0xc7, 0xf5, 0xf3, 0x7f, 0xcc, 0x98, 0xbc, 0x9e, 0x57, + 0xfd, 0xcc, 0x9f, 0x5f, 0x9a, 0xef, 0x9e, 0x4f, 0xff, 0x1f, 0x17, 0xfc, + 0xfb, 0xef, 0xac, 0x93, 0x00, 0x1c, 0xe7, 0x05, 0x6e, 0xeb, 0xff, 0xff, + 0xc7, 0xff, 0xff, 0xdf, 0x63, 0x8d, 0xff, 0xff, 0x2b, 0xeb, 0xdc, 0xeb, + 0xfe, 0x8a, 0x32, 0xc3, 0xf2, 0xf3, 0x44, 0xed, 0x31, 0xa2, 0xe5, 0xa2, + 0xff, 0x1f, 0x57, 0xfd, 0xff, 0xcc, 0x9f, 0x59, 0xfe, 0xcc, 0x9e, 0x5a, + 0x7f, 0xcf, 0xf9, 0xbf, 0xfe, 0x92, 0x2c, 0x8b, 0x20, 0xc4, 0x07, 0xf3, + 0x8c, 0xed, 0xf7, 0x7c, 0x7f, 0xce, 0xd7, 0xbe, 0xff, 0x1f, 0x35, 0xfd, + 0xfd, 0x47, 0xde, 0x6f, 0xde, 0x47, 0xb9, 0xa6, 0xbf, 0x47, 0x5e, 0x7e, + 0xf1, 0xed, 0x00, 0x1c, 0x10, 0x06, 0xbf, 0xc2, 0xf3, 0xf3, 0x3f, 0x67, + 0x13, 0xed, 0xdf, 0x79, 0xff, 0xd9, 0xe0, 0x93, 0x00, 0x1c, 0x19, 0x06, + 0xff, 0xd2, 0xab, 0x8a, 0xbf, 0xc2, 0x07, 0xf4, 0x97, 0xed, 0xff, 0xcd, + 0xbf, 0x5c, 0xbc, 0x7c, 0x00, 0xcc, 0x35, 0x9b, 0xec, 0xf7, 0x5d, 0xed, + 0x9a, 0x1b, 0xf4, 0xff, 0xbf, 0x7c, 0xbd, 0x1b, 0x03, 0xdf, 0xbd, 0x1b, + 0xe3, 0xcf, 0xbd, 0x1b, 0xe3, 0xdf, 0xbf, 0x5c, 0xf7, 0x7a, 0xfe, 0xce, + 0x69, 0xcd, 0xfe, 0xcc, 0xff, 0x1f, 0xeb, 0xfd, 0xf8, 0x5a, 0x9e, 0x67, + 0x5e, 0x7c, 0xbe, 0xc2, 0xed, 0xf3, 0xfe, 0xd2, 0xab, 0x8a, 0xdf, 0x67, + 0xfd, 0xa6, 0xeb, 0xa7, 0x38, 0x93, 0xff, 0xcd, 0xdf, 0x7c, 0x7a, 0x93, + 0xff, 0xdc, 0xf1, 0x9b, 0x03, 0xf4, 0xff, 0xda, 0x9f, 0x67, 0x8b, 0xa4, 0x9f, 0x47, 0xfd, 0xfb, 0xff, 0xcd, 0xff, 0x67, 0x9f, 0x7f, 0x71, 0x9b, - 0xea, 0xf3, 0xee, 0xee, 0x00, 0x1c, 0x7d, 0x08, 0xb1, 0xee, 0x9e, 0x7d, + 0xe9, 0xf3, 0xef, 0xee, 0x00, 0x1c, 0x53, 0x06, 0xb2, 0xee, 0x9e, 0x7d, 0xff, 0xdc, 0x33, 0x8b, 0x9e, 0x5d, 0xf5, 0xcd, 0x37, 0x9b, 0x67, 0xf7, - 0xff, 0xcd, 0x95, 0xee, 0xbe, 0x5c, 0xff, 0x1f, 0x7c, 0xf9, 0xf5, 0xee, - 0x00, 0x1c, 0x8d, 0x08, 0x70, 0xfb, 0xff, 0xcd, 0x9a, 0xee, 0xbe, 0x5c, - 0xde, 0x67, 0x9f, 0x7e, 0xbc, 0xc4, 0xa9, 0xf3, 0xfc, 0xc4, 0xf9, 0xf7, - 0xbe, 0xc4, 0xe0, 0xf3, 0xbd, 0xc4, 0x7d, 0xf7, 0xf5, 0xfb, 0xae, 0xcd, - 0x71, 0x9b, 0xcd, 0xf3, 0x8e, 0xcd, 0x71, 0x9b, 0xde, 0xf3, 0xbb, 0xc4, - 0x86, 0xf7, 0xa4, 0xfb, 0xfe, 0xcd, 0x88, 0xef, 0xbe, 0x5c, 0xbe, 0x67, - 0x9c, 0x7d, 0xb4, 0xc4, 0xfa, 0xf7, 0xfd, 0xcf, 0x00, 0x1c, 0xb1, 0x00, - 0xfb, 0xfb, 0xfc, 0xcf, 0x00, 0x1c, 0xb5, 0x00, 0xe9, 0xef, 0xff, 0x1f, - 0xae, 0xfd, 0x99, 0xfb, 0x91, 0xef, 0x9e, 0x7c, 0xbe, 0xc4, 0xa3, 0xf7, - 0xfd, 0xcd, 0x93, 0xef, 0xbe, 0x5c, 0xff, 0xcf, 0x00, 0x1c, 0xc3, 0x00, - 0xa4, 0xfb, 0x96, 0xef, 0x9e, 0x7c, 0xbd, 0xc4, 0xae, 0xf7, 0x98, 0xef, - 0xfc, 0xcd, 0xbe, 0x5c, 0xfe, 0x67, 0xdb, 0x7f, 0xd7, 0xbe, 0xba, 0x7f, - 0x7b, 0x93, 0xbe, 0x54, 0xb2, 0xfb, 0x9d, 0xef, 0x9e, 0x7c, 0xf0, 0xfb, - 0xbf, 0xff, 0xff, 0xdf, 0x3f, 0x83, 0xff, 0xff, 0x3b, 0x83, 0xff, 0xff, - 0xbb, 0xff, 0xff, 0xdf, 0x33, 0x83, 0xff, 0xff, 0x23, 0x83, 0xff, 0xff, - 0xb8, 0xff, 0xff, 0xdf, 0xbc, 0xc4, 0xcb, 0xf7, 0xfb, 0xcd, 0x97, 0xec, - 0xbe, 0x5c, 0xfe, 0xcf, 0x00, 0x1c, 0xeb, 0x00, 0xcc, 0xfb, 0x9a, 0xec, - 0x9e, 0x7c, 0xbb, 0xc4, 0xd6, 0xf7, 0xf7, 0xcf, 0xff, 0x1f, 0xd9, 0xfd, + 0xff, 0xcd, 0x96, 0xee, 0xbe, 0x5c, 0xff, 0x1f, 0xa4, 0xf9, 0xbc, 0x93, + 0xf7, 0xee, 0x00, 0x1c, 0x64, 0x06, 0x71, 0xfb, 0xff, 0xcd, 0x9b, 0xee, + 0xbe, 0x5c, 0xde, 0x67, 0x9f, 0x7e, 0xbc, 0xc4, 0xaa, 0xf3, 0xfc, 0xc4, + 0xf9, 0xf7, 0xbe, 0xc4, 0xe0, 0xf3, 0xbd, 0xc4, 0x7e, 0xf7, 0xf5, 0xfb, + 0xae, 0xcd, 0x71, 0x9b, 0xbf, 0xf3, 0x8e, 0xcd, 0x71, 0x9b, 0xde, 0xf3, + 0xbb, 0xc4, 0x87, 0xf7, 0xa5, 0xfb, 0xfe, 0xcd, 0x8a, 0xef, 0xbe, 0x5c, + 0xbe, 0x67, 0x9c, 0x7d, 0xb4, 0xc4, 0xfa, 0xf7, 0xfd, 0xcf, 0x00, 0x1c, + 0xb2, 0x00, 0xfb, 0xfb, 0xfc, 0xcf, 0x00, 0x1c, 0xb6, 0x00, 0xea, 0xef, + 0xff, 0x1f, 0xed, 0xfd, 0x9a, 0xfb, 0x92, 0xef, 0x9e, 0x7c, 0xbe, 0xc4, + 0xa4, 0xf7, 0xfd, 0xcd, 0x95, 0xef, 0xbe, 0x5c, 0xff, 0xcf, 0x00, 0x1c, + 0xc4, 0x00, 0xa5, 0xfb, 0x98, 0xef, 0x9e, 0x7c, 0xbd, 0xc4, 0xaf, 0xf7, + 0x9a, 0xef, 0xfc, 0xcd, 0xbe, 0x5c, 0xfe, 0x67, 0xdb, 0x7f, 0xd7, 0xbe, + 0xba, 0x7f, 0x7b, 0x93, 0xbe, 0x54, 0xb3, 0xfb, 0xc7, 0xff, 0xff, 0xdf, + 0x4f, 0x8d, 0xff, 0xff, 0x4b, 0x8d, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xdf, + 0x43, 0x8d, 0xff, 0xff, 0x33, 0x8d, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xdf, + 0x98, 0xec, 0x9e, 0x7c, 0xbc, 0xc4, 0xcb, 0xf7, 0xfb, 0xcd, 0x9a, 0xec, + 0xbe, 0x5c, 0xfe, 0xcf, 0x00, 0x1c, 0xeb, 0x00, 0xcc, 0xfb, 0x9d, 0xec, + 0x9e, 0x7c, 0xbb, 0xc4, 0xd6, 0xf7, 0xf7, 0xcf, 0xff, 0x1f, 0x19, 0xfe, 0xdd, 0x67, 0xbf, 0xc6, 0xd6, 0xf3, 0x7f, 0xcc, 0x9a, 0xbc, 0x9e, 0x57, 0xfd, 0xcc, 0x9f, 0x5f, 0xbe, 0x67, 0x95, 0xa5, 0x9e, 0x4f, 0xff, 0x1f, - 0xca, 0xfc, 0xe1, 0xfb, 0x85, 0xed, 0x9e, 0x7c, 0xbb, 0xc4, 0xeb, 0xf7, - 0xff, 0xcd, 0x86, 0xed, 0xbd, 0x5c, 0xf7, 0xcf, 0xff, 0x1f, 0xf1, 0xfd, + 0x08, 0xfd, 0xe1, 0xfb, 0x88, 0xed, 0x9e, 0x7c, 0xbb, 0xc4, 0xeb, 0xf7, + 0xff, 0xcd, 0x89, 0xed, 0xbd, 0x5c, 0xf7, 0xcf, 0xff, 0x1f, 0x31, 0xfe, 0xbf, 0xc7, 0xed, 0xf3, 0x7f, 0xcc, 0x9b, 0xbc, 0x9e, 0x57, 0xfd, 0xcc, - 0x9f, 0x5f, 0xde, 0x67, 0x95, 0xa6, 0x9e, 0x4f, 0xff, 0x1f, 0xe1, 0xfc, - 0xf8, 0xfb, 0xfe, 0xcd, 0x91, 0xed, 0xbe, 0x5c, 0xfd, 0xcf, 0x00, 0x1c, - 0x1e, 0x01, 0xfd, 0x67, 0xff, 0x1f, 0xef, 0xfd, 0x7f, 0xcd, 0xb7, 0xbd, - 0xb6, 0x92, 0x3f, 0xc2, 0xa4, 0xf2, 0xb6, 0xed, 0x9f, 0x7d, 0xff, 0xdc, - 0x33, 0x8b, 0x9f, 0x5d, 0xf2, 0xc4, 0xc6, 0xf6, 0xb9, 0xed, 0x9d, 0x3b, - 0xbc, 0xf7, 0x9f, 0x6c, 0xf3, 0x87, 0x9a, 0xed, 0x9f, 0x7c, 0x9c, 0x1b, - 0xe3, 0xdf, 0xa3, 0xc4, 0xfc, 0xf3, 0xab, 0xc4, 0xf8, 0xf7, 0x9e, 0xed, - 0xbf, 0x7c, 0xbd, 0x1b, 0xe3, 0xcf, 0xbf, 0x5c, 0xf3, 0xfb, 0xa1, 0xee, + 0x9f, 0x5f, 0xde, 0x67, 0x95, 0xa6, 0x9e, 0x4f, 0xff, 0x1f, 0x1f, 0xfd, + 0xf8, 0xfb, 0xfe, 0xcd, 0x94, 0xed, 0xbe, 0x5c, 0xfd, 0xcf, 0x00, 0x1c, + 0x1e, 0x01, 0xfd, 0x67, 0xff, 0x1f, 0x31, 0xfe, 0x7f, 0xcd, 0xb7, 0xbd, + 0xf6, 0x92, 0x3f, 0xc3, 0xf5, 0xf2, 0xb9, 0xed, 0x9f, 0x7d, 0xff, 0xdc, + 0x33, 0x8b, 0x9f, 0x5d, 0xf2, 0xc4, 0x17, 0xf7, 0xbc, 0xed, 0x9d, 0x3b, + 0xbc, 0xf7, 0x9f, 0x6c, 0xf3, 0x87, 0x9d, 0xed, 0x9f, 0x7c, 0x9c, 0x1b, + 0xe3, 0xdf, 0xa3, 0xc4, 0xfc, 0xf3, 0xab, 0xc4, 0xf8, 0xf7, 0x81, 0xee, + 0xbf, 0x7c, 0xbd, 0x1b, 0xe3, 0xcf, 0xbf, 0x5c, 0xf3, 0xfb, 0xa4, 0xee, 0x9f, 0x7d, 0xdd, 0xb4, 0xff, 0xde, 0xde, 0x1b, 0xf8, 0xdf, 0xdd, 0xbe, - 0x9c, 0x1b, 0xe3, 0xcf, 0x3b, 0x93, 0x9f, 0x5d, 0x87, 0xee, 0x9f, 0x7c, - 0xfc, 0x1b, 0xfc, 0xdf, 0xdd, 0xb4, 0xde, 0x1b, 0xf8, 0xdf, 0x9a, 0xb4, - 0xbc, 0x1b, 0xf8, 0xdf, 0xff, 0x1f, 0x89, 0xfa, 0xec, 0xee, 0x00, 0x1c, - 0x58, 0x09, 0xf4, 0xfa, 0x8f, 0xee, 0x9f, 0x7c, 0x9c, 0x1b, 0xe3, 0xdf, - 0xbf, 0xc4, 0xf6, 0xf7, 0x92, 0xee, 0xbf, 0x7c, 0xbd, 0x1b, 0xe3, 0xcf, + 0x9c, 0x1b, 0xe3, 0xcf, 0x3b, 0x93, 0x9f, 0x5d, 0x8a, 0xee, 0xbf, 0x7c, + 0xfd, 0x1b, 0xfc, 0xdf, 0xdd, 0xb5, 0xde, 0x1b, 0xf8, 0xdf, 0xba, 0xb5, + 0xbd, 0x1b, 0xf8, 0xdf, 0xff, 0x1f, 0xc7, 0xfa, 0xef, 0xee, 0x00, 0x1c, + 0x2e, 0x07, 0x45, 0xfb, 0x92, 0xee, 0x9f, 0x7c, 0x9c, 0x1b, 0xe3, 0xdf, + 0xbf, 0xc4, 0xf6, 0xf7, 0x95, 0xee, 0xbf, 0x7c, 0xbd, 0x1b, 0xe3, 0xcf, 0xbd, 0x13, 0xe7, 0xff, 0xbf, 0x5c, 0xe5, 0xfb, 0xbb, 0xc4, 0xf8, 0xf7, - 0x97, 0xee, 0xbf, 0x7c, 0xbd, 0x13, 0xe3, 0xff, 0xbf, 0x5c, 0xed, 0xfb, - 0x9a, 0xee, 0x9f, 0x7c, 0x9d, 0xb4, 0x9c, 0x1b, 0xf8, 0xdf, 0xda, 0xc4, - 0xf4, 0xf3, 0xbd, 0xee, 0xfe, 0xd4, 0xdc, 0x1b, 0xf8, 0xdf, 0xdd, 0xbe, - 0x9f, 0x7d, 0x9c, 0x1b, 0xe3, 0xcf, 0x3b, 0x93, 0x9f, 0x5d, 0x82, 0xef, - 0x9f, 0x7c, 0xfc, 0x1b, 0xfc, 0xdf, 0xdd, 0xb4, 0xde, 0x1b, 0xf8, 0xdf, - 0x9a, 0xb4, 0xbc, 0x1b, 0xf8, 0xdf, 0xff, 0x1f, 0xc0, 0xfa, 0xe6, 0xef, - 0x00, 0x1c, 0x8f, 0x09, 0x2b, 0xfb, 0x6a, 0xef, 0x9f, 0x7b, 0x9c, 0x1b, - 0xe3, 0xcf, 0x9c, 0x1b, 0xe0, 0xdf, 0x9f, 0x5b, 0xff, 0x1f, 0xcb, 0xf7, - 0xfe, 0x53, 0xff, 0x1f, 0x14, 0xf8, 0xfd, 0x53, 0xff, 0x1f, 0xb9, 0xf6, - 0xbe, 0xc7, 0xfb, 0xf3, 0x7d, 0xcd, 0x4b, 0xcf, 0xfc, 0xfb, 0x8c, 0xcd, - 0x6c, 0xcf, 0x95, 0xef, 0x9e, 0x7c, 0xbf, 0xc4, 0xdb, 0xf3, 0x00, 0x1c, - 0x3c, 0x0b, 0xbc, 0x93, 0x96, 0xef, 0xff, 0x6c, 0x00, 0x1c, 0xcb, 0x0b, - 0xef, 0xfb, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xdf, 0xbb, 0xff, 0xff, 0xdf, - 0x27, 0x84, 0xff, 0xff, 0xb3, 0xff, 0xff, 0xdf, 0x1b, 0x83, 0xff, 0xff, - 0x13, 0x83, 0xff, 0xff, 0xdf, 0x83, 0xff, 0xff, 0x9a, 0xec, 0xdf, 0x6c, - 0x00, 0x1c, 0x17, 0x0c, 0x00, 0x1c, 0xdd, 0x0c, 0x9c, 0xec, 0xbe, 0x74, - 0x3e, 0x8b, 0x73, 0x9b, 0xea, 0xf7, 0x4a, 0xfb, 0xf4, 0x93, 0x00, 0x1c, - 0x60, 0x0b, 0xbc, 0x93, 0x80, 0xed, 0xff, 0x6c, 0x00, 0x1c, 0xef, 0x0b, - 0x84, 0xed, 0xdf, 0x6c, 0x00, 0x1c, 0x2b, 0x0c, 0x00, 0x1c, 0xf1, 0x0c, - 0x86, 0xed, 0xbe, 0x74, 0x3e, 0x8b, 0x37, 0x9b, 0x5d, 0xf7, 0x88, 0xed, - 0xfe, 0xcd, 0xbe, 0x5c, 0x9d, 0x74, 0x24, 0xcd, 0x37, 0x9b, 0xf7, 0xf3, - 0xea, 0xdc, 0xf2, 0x8b, 0x8d, 0xed, 0xfd, 0x54, 0xff, 0x1f, 0x7f, 0xf8, - 0xfa, 0xfb, 0x8f, 0xed, 0xbe, 0x74, 0xea, 0xdd, 0xbe, 0x54, 0xef, 0xed, - 0x00, 0x1c, 0xf5, 0x09, 0x73, 0xed, 0x9f, 0x7b, 0xfc, 0x1b, 0xfc, 0xdf, - 0xdd, 0xb4, 0xde, 0x1b, 0xf8, 0xdf, 0x9a, 0xb4, 0xbc, 0x1b, 0xf8, 0xdf, - 0xff, 0x1f, 0x35, 0xfb, 0xfe, 0x73, 0xff, 0x1f, 0x76, 0xf8, 0xa0, 0xfb, - 0xff, 0x1f, 0x43, 0xfb, 0xff, 0x1b, 0xf8, 0xdf, 0xbd, 0xed, 0x9a, 0xbf, - 0xdf, 0x7d, 0xde, 0x1b, 0xe0, 0xdf, 0xb3, 0x93, 0x38, 0x93, 0xdf, 0x5d, - 0x9c, 0x1b, 0xe0, 0xcf, 0x33, 0x8b, 0xbf, 0xc4, 0xed, 0xf7, 0xbd, 0xa7, - 0xbd, 0x1b, 0xf8, 0xdf, 0xc5, 0xee, 0x9a, 0xbd, 0xff, 0x7e, 0xff, 0x1b, - 0xe0, 0xdf, 0x3f, 0x93, 0x9f, 0x5e, 0xfc, 0x1b, 0xfc, 0xdf, 0x9d, 0xb4, - 0xdc, 0x1b, 0xf8, 0xdf, 0xff, 0x1f, 0x5b, 0xfb, 0xe9, 0xee, 0x00, 0x1c, - 0x2a, 0x0a, 0xc6, 0xfb, 0x8e, 0xee, 0x9f, 0x7c, 0x9c, 0x1b, 0xe0, 0xcf, - 0x73, 0x8b, 0xdf, 0xcc, 0x35, 0x9b, 0xef, 0xf7, 0xb2, 0xee, 0x9f, 0x7d, - 0x9c, 0x1b, 0xe0, 0xdf, 0x9c, 0x13, 0x9f, 0xff, 0x9f, 0x5d, 0xfc, 0x1b, - 0xfc, 0xdf, 0x9d, 0xb4, 0xdc, 0x1b, 0xf8, 0xdf, 0xfc, 0xcd, 0xff, 0x1f, - 0x76, 0xfb, 0xf5, 0xee, 0x00, 0x1c, 0x45, 0x0a, 0xe1, 0xfb, 0xff, 0x1f, - 0x3a, 0xfb, 0xf7, 0xee, 0x00, 0x1c, 0x4b, 0x0a, 0xe7, 0xfb, 0x78, 0xee, - 0x91, 0xa3, 0xff, 0xcd, 0xbf, 0x5c, 0xe5, 0xa3, 0xff, 0x1f, 0x4b, 0xff, - 0xfe, 0xcc, 0x9e, 0x5b, 0xff, 0x1f, 0xeb, 0xf7, 0x7d, 0xee, 0xff, 0x1f, - 0x82, 0xf7, 0xff, 0xd3, 0xbf, 0xc3, 0x03, 0xf4, 0xfd, 0xcf, 0x00, 0x1c, - 0x62, 0x02, 0xe0, 0xef, 0x00, 0x1c, 0x63, 0x0a, 0xff, 0x1f, 0xbf, 0xfb, - 0xa2, 0xef, 0x9d, 0x7d, 0xff, 0xdc, 0x33, 0x8b, 0x9d, 0x5d, 0x5f, 0xcd, - 0x37, 0x9b, 0xef, 0xf7, 0xe9, 0xef, 0xfe, 0xcc, 0x9e, 0x5f, 0x91, 0xa7, - 0xff, 0xcd, 0xbd, 0x5c, 0xf9, 0xdf, 0xff, 0x1f, 0x6e, 0xff, 0xfd, 0xcf, - 0x00, 0x1c, 0x7b, 0x02, 0xeb, 0xef, 0x00, 0x1c, 0x7c, 0x0a, 0x5a, 0x1b, - 0xfe, 0xbf, 0xe8, 0x93, 0xfc, 0xeb, 0x6b, 0xeb, 0x99, 0xef, 0xff, 0xcd, - 0xbe, 0x5c, 0xbe, 0x74, 0xea, 0xd5, 0xbe, 0x54, 0xf1, 0xef, 0x00, 0x1c, - 0x8a, 0x0a, 0x94, 0xf8, 0xdb, 0x83, 0xff, 0xff, 0xb3, 0xff, 0xff, 0xdf, - 0xdf, 0x83, 0xff, 0xff, 0x0b, 0x83, 0xff, 0xff, 0xff, 0x82, 0xff, 0xff, - 0xf3, 0x82, 0xff, 0xff, 0xe7, 0x82, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xdf, - 0x5f, 0x79, 0xfe, 0xff, 0xd3, 0x82, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xdf, - 0xbb, 0x82, 0xff, 0xff, 0xab, 0x82, 0xff, 0xff, 0x2f, 0xeb, 0xf3, 0xef, - 0xff, 0x1f, 0x53, 0xfe, 0x94, 0xef, 0xf7, 0x5c, 0xbc, 0x1b, 0xf4, 0xff, + 0x9a, 0xee, 0xbf, 0x7c, 0xbd, 0x13, 0xe3, 0xff, 0xbf, 0x5c, 0xed, 0xfb, + 0x9d, 0xee, 0x9f, 0x7c, 0x9d, 0xb4, 0x9c, 0x1b, 0xf8, 0xdf, 0xda, 0xc4, + 0xf4, 0xf3, 0xa0, 0xef, 0xfe, 0xd4, 0xdc, 0x1b, 0xf8, 0xdf, 0xdd, 0xbe, + 0x9f, 0x7d, 0x9c, 0x1b, 0xe3, 0xcf, 0x3b, 0x93, 0x9f, 0x5d, 0x85, 0xef, + 0xbf, 0x7c, 0xfd, 0x1b, 0xfc, 0xdf, 0xdd, 0xb5, 0xde, 0x1b, 0xf8, 0xdf, + 0xba, 0xb5, 0xbd, 0x1b, 0xf8, 0xdf, 0xff, 0x1f, 0xfe, 0xfa, 0xe9, 0xef, + 0x00, 0x1c, 0x65, 0x07, 0x7c, 0xfb, 0x4d, 0xef, 0x9f, 0x7a, 0x9c, 0x1b, + 0xe3, 0xcf, 0x9c, 0x1b, 0xe0, 0xdf, 0x9f, 0x5a, 0xff, 0x1f, 0xf7, 0xf7, + 0xd4, 0xdf, 0xfe, 0x52, 0xbf, 0x7a, 0xfd, 0x1b, 0xfc, 0xdf, 0xdd, 0xb5, + 0xde, 0x1b, 0xf8, 0xdf, 0xba, 0xb5, 0xbd, 0x1b, 0xf8, 0xdf, 0xff, 0x1f, + 0x18, 0xfb, 0xfe, 0x72, 0xff, 0x1f, 0x2d, 0xf8, 0xf7, 0xef, 0x00, 0x1c, + 0x82, 0x07, 0x99, 0xfb, 0xc7, 0xff, 0xff, 0xdf, 0xc3, 0xff, 0xff, 0xdf, + 0x1f, 0x8e, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xdf, 0x2b, 0x8d, 0xff, 0xff, + 0x23, 0x8d, 0xff, 0xff, 0x1b, 0x8d, 0xff, 0xff, 0xff, 0x1f, 0x35, 0xfb, + 0xff, 0x1b, 0xf8, 0xdf, 0xb4, 0xed, 0x9a, 0xbf, 0xdf, 0x7d, 0xde, 0x1b, + 0xe0, 0xdf, 0xb3, 0x93, 0x38, 0x93, 0xdf, 0x5d, 0x9c, 0x1b, 0xe0, 0xcf, + 0x33, 0x8b, 0xbf, 0xc4, 0xed, 0xf7, 0xbd, 0xa7, 0xbd, 0x1b, 0xf8, 0xdf, + 0xdc, 0xed, 0x9a, 0xbd, 0xff, 0x7e, 0xff, 0x1b, 0xe0, 0xdf, 0x3f, 0x93, + 0x9f, 0x5e, 0xfc, 0x1b, 0xfc, 0xdf, 0x9d, 0xb4, 0xdc, 0x1b, 0xf8, 0xdf, + 0xff, 0x1f, 0x4f, 0xfb, 0xe2, 0xee, 0x00, 0x1c, 0xb6, 0x07, 0xcd, 0xfb, + 0x85, 0xee, 0x9f, 0x7c, 0x9c, 0x1b, 0xe0, 0xcf, 0x33, 0x8b, 0xdf, 0xcd, + 0x71, 0x9b, 0xef, 0xf7, 0xa9, 0xee, 0x9f, 0x7d, 0x9c, 0x1b, 0xe0, 0xdf, + 0x9c, 0x13, 0x9f, 0xff, 0x9f, 0x5d, 0xfc, 0x1b, 0xfc, 0xdf, 0x9d, 0xb4, + 0xdc, 0x1b, 0xf8, 0xdf, 0xfc, 0xcd, 0xff, 0x1f, 0x6a, 0xfb, 0xee, 0xee, + 0x00, 0x1c, 0xd1, 0x07, 0xe8, 0xfb, 0xff, 0x1f, 0x18, 0xfb, 0xbc, 0x93, + 0xf1, 0xee, 0x00, 0x1c, 0xd8, 0x07, 0xef, 0xfb, 0x52, 0xee, 0x91, 0xa2, + 0xff, 0xcd, 0xbf, 0x5c, 0xe5, 0xa2, 0xff, 0x1f, 0x40, 0xff, 0xfe, 0xcc, + 0x9e, 0x5a, 0xfd, 0xcf, 0x00, 0x1c, 0x11, 0x02, 0xf7, 0xee, 0x00, 0x1c, + 0xe8, 0x07, 0xff, 0x1f, 0xa6, 0xfb, 0xb8, 0xee, 0x9d, 0x7d, 0xff, 0xdc, + 0x33, 0x8b, 0x9d, 0x5d, 0x5f, 0xcd, 0x37, 0x9b, 0xef, 0xf7, 0xfe, 0xee, + 0xfe, 0xcc, 0x9e, 0x5f, 0x91, 0xa7, 0xff, 0xcd, 0xbd, 0x5c, 0xf9, 0xdf, + 0xff, 0x1f, 0x5b, 0xff, 0xfd, 0xcf, 0x00, 0x1c, 0x2a, 0x02, 0xe1, 0xef, + 0x00, 0x1c, 0x01, 0x08, 0x7b, 0x1b, 0xfe, 0xbf, 0xec, 0x93, 0xfc, 0xeb, + 0x6b, 0xeb, 0xff, 0xff, 0x2f, 0xeb, 0xe5, 0xef, 0xff, 0x1f, 0x15, 0xfe, + 0xbc, 0x93, 0x8b, 0xef, 0xf7, 0x5c, 0x00, 0xcc, 0x3d, 0x9b, 0xfb, 0xf3, + 0xe9, 0xef, 0x00, 0x1c, 0x14, 0x08, 0x8f, 0xef, 0xbc, 0x1b, 0xf4, 0xff, 0xdf, 0x7d, 0xde, 0x1b, 0x03, 0xdf, 0xde, 0x1b, 0xe3, 0xcf, 0xde, 0x1b, 0xe3, 0xdf, 0xdf, 0x5d, 0xfa, 0xcd, 0xbf, 0x5c, 0xfe, 0xcd, 0xbe, 0x5c, - 0xff, 0xcd, 0xff, 0xd5, 0xb8, 0x5c, 0x6f, 0xeb, 0x37, 0x9b, 0xff, 0xff, - 0xbf, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xf7, 0x7c, 0xc3, 0x87, 0xff, 0xff, - 0xbf, 0xff, 0xff, 0xdf, 0x9c, 0xef, 0xbf, 0x6c, 0xff, 0xdd, 0xbf, 0x4c, - 0xc3, 0x87, 0xff, 0xff, 0xab, 0xff, 0xff, 0xdf, 0x3b, 0xeb, 0x3f, 0x8a, - 0xba, 0x8b, 0x76, 0x8b, 0xe9, 0xef, 0x7e, 0x7f, 0x00, 0xcf, 0xed, 0x9b, - 0xed, 0xf3, 0x6a, 0xef, 0xfe, 0xcf, 0x00, 0xc9, 0x5f, 0x7b, 0x69, 0x9a, - 0xf7, 0xf3, 0xff, 0xdf, 0xff, 0x8b, 0xf8, 0xdb, 0xb7, 0xc7, 0x06, 0xf4, - 0x00, 0xcf, 0xe5, 0xfb, 0x00, 0xcb, 0xfd, 0x9a, 0xfc, 0xf7, 0xe9, 0xfb, - 0xff, 0xcf, 0xbc, 0x92, 0x7c, 0xbf, 0x35, 0xef, 0x6f, 0xa1, 0x1e, 0x5b, - 0xde, 0x53, 0xbd, 0x53, 0xbe, 0xc4, 0xfd, 0xf3, 0xff, 0xcd, 0x97, 0xef, - 0x71, 0xa4, 0xdc, 0xba, 0xdb, 0xa3, 0xbc, 0x56, 0xbc, 0x27, 0xbb, 0xff, - 0xbf, 0x5e, 0xfc, 0x23, 0xbb, 0xff, 0x7b, 0xeb, 0xa7, 0xff, 0xff, 0xdf, - 0x9e, 0xff, 0xff, 0xdf, 0xab, 0xff, 0xff, 0xdf, 0x9f, 0x7f, 0x00, 0xcd, - 0x71, 0x9b, 0xf6, 0xf3, 0x9c, 0xbc, 0xba, 0xef, 0x93, 0xa5, 0xff, 0xcd, - 0xbe, 0x54, 0xff, 0xcc, 0xff, 0xd4, 0x9f, 0x5f, 0xc3, 0x87, 0xff, 0xff, - 0xa7, 0xff, 0xff, 0xdf, 0xff, 0x8b, 0xef, 0xc7, 0xed, 0xf7, 0x95, 0xef, - 0x9f, 0x7c, 0xbf, 0xc4, 0xf3, 0xf3, 0x97, 0xef, 0xfd, 0x6c, 0xde, 0x6f, - 0xdd, 0x4c, 0xbe, 0x6f, 0xdf, 0x6f, 0xdf, 0x4d, 0xbf, 0x7c, 0xff, 0xd5, - 0xbf, 0x5c, 0xfb, 0xfb, 0xff, 0xcf, 0xfd, 0xfb, 0xff, 0xcf, 0xc3, 0x87, - 0x63, 0xff, 0xff, 0xdf, 0x98, 0xef, 0xbe, 0x6c, 0xbe, 0x6d, 0xbe, 0x4f, + 0xff, 0xcd, 0xff, 0xd5, 0xb8, 0x5c, 0x6f, 0xeb, 0x99, 0xef, 0xf7, 0x7c, + 0xc3, 0x87, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xdf, 0x0f, 0x8d, 0xff, 0xff, + 0x03, 0x8d, 0xff, 0xff, 0xf7, 0x8c, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xdf, + 0xeb, 0x8c, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xdf, 0xd3, 0x8c, 0xff, 0xff, + 0x6b, 0xa6, 0xff, 0xff, 0xc3, 0x8c, 0xff, 0xff, 0x9c, 0xef, 0xbf, 0x6c, + 0xff, 0xdd, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0xb7, 0xff, 0xff, 0xdf, + 0x3b, 0xeb, 0x3f, 0x8a, 0xba, 0x8b, 0x76, 0x8b, 0xe5, 0xed, 0x7e, 0x7f, + 0x00, 0xcf, 0xed, 0x9b, 0xed, 0xf3, 0x66, 0xed, 0xfe, 0xcf, 0x00, 0xc9, + 0x5f, 0x7b, 0x69, 0x9a, 0xf7, 0xf3, 0xff, 0xdf, 0xff, 0x8b, 0xf8, 0xdb, + 0xb7, 0xc7, 0x06, 0xf4, 0x00, 0xcf, 0xe5, 0xfb, 0x00, 0xcb, 0xfd, 0x9a, + 0xfc, 0xf7, 0xe9, 0xfb, 0xff, 0xcf, 0xbc, 0x92, 0x7c, 0xbf, 0x31, 0xed, + 0x6f, 0xa1, 0x1e, 0x5b, 0xde, 0x53, 0xbd, 0x53, 0xbe, 0xc4, 0xfd, 0xf3, + 0xff, 0xcd, 0x93, 0xed, 0x71, 0xa4, 0xdc, 0xba, 0xdb, 0xa3, 0xbc, 0x56, + 0xbc, 0x27, 0xbb, 0xff, 0xbf, 0x5e, 0xfc, 0x23, 0xbb, 0xff, 0x7b, 0xeb, + 0x3c, 0xeb, 0xff, 0x8b, 0xba, 0x8a, 0x9a, 0xed, 0x9c, 0x27, 0xbb, 0xff, + 0x00, 0xcd, 0x71, 0x9b, 0xe3, 0xf3, 0xbf, 0xed, 0x00, 0xc9, 0xf0, 0x92, + 0xdc, 0xbc, 0xdb, 0xa5, 0xde, 0x76, 0xb9, 0x9a, 0xf9, 0xf7, 0xdc, 0xbc, + 0xdb, 0xa5, 0xde, 0x7e, 0xf9, 0x9b, 0xf8, 0xf3, 0x7c, 0xbb, 0x6f, 0xa5, + 0x9f, 0x7b, 0x71, 0x9a, 0x0e, 0xf4, 0xf6, 0xfb, 0x00, 0xcd, 0x71, 0x9b, + 0xf9, 0xf3, 0x9c, 0xbc, 0xab, 0xee, 0x93, 0xa5, 0xff, 0xcd, 0xbe, 0x54, + 0x7c, 0xeb, 0xff, 0xff, 0x9f, 0x7f, 0x00, 0xcd, 0x71, 0x9b, 0xf6, 0xf3, + 0x9c, 0xbc, 0xb0, 0xee, 0x93, 0xa5, 0xff, 0xcd, 0xbe, 0x54, 0xff, 0xcc, + 0xff, 0xd4, 0x9f, 0x5f, 0xc3, 0x87, 0xff, 0xff, 0xff, 0x8b, 0xef, 0xc7, + 0xed, 0xf7, 0x93, 0xee, 0x9f, 0x7c, 0xbf, 0xc4, 0xf3, 0xf3, 0x95, 0xee, + 0xfd, 0x6c, 0xde, 0x6f, 0xdd, 0x4c, 0xbe, 0x6f, 0xdf, 0x6f, 0xdf, 0x4d, + 0xbf, 0x7c, 0xff, 0xd5, 0xbf, 0x5c, 0xfb, 0xfb, 0xff, 0xcf, 0xfd, 0xfb, + 0xff, 0xcf, 0xc3, 0x87, 0x9d, 0xee, 0xbe, 0x6c, 0xbe, 0x6d, 0xbe, 0x4f, 0xbe, 0x6c, 0xbf, 0x4f, 0xbe, 0x6c, 0xfe, 0x4d, 0xfe, 0x4c, 0xbf, 0x7c, - 0xff, 0xdd, 0xbf, 0x5c, 0xc3, 0x87, 0xff, 0xff, 0x63, 0xff, 0xff, 0xdf, - 0x3c, 0xeb, 0xbf, 0x8a, 0xba, 0x8b, 0xb3, 0xef, 0xff, 0xcc, 0x70, 0x92, - 0xff, 0x6d, 0x7f, 0x7f, 0xad, 0x9a, 0xf5, 0xf7, 0x7e, 0x77, 0xad, 0x9b, - 0xf8, 0xf7, 0x98, 0xef, 0x3c, 0x3b, 0xb9, 0xf7, 0xff, 0xcc, 0x9f, 0x49, - 0xf9, 0xfb, 0xff, 0xdc, 0xfc, 0xdd, 0xba, 0xc4, 0x10, 0xf4, 0xff, 0xcf, - 0x7c, 0xeb, 0xff, 0xff, 0x57, 0xff, 0xff, 0xdf, 0x3c, 0xeb, 0xa1, 0xef, - 0x9d, 0x1b, 0xb8, 0xff, 0xd1, 0xa4, 0xde, 0x4c, 0xdd, 0x4c, 0xff, 0xce, - 0xdf, 0x5c, 0x9d, 0x1b, 0x98, 0xff, 0xbc, 0x1b, 0xc0, 0xff, 0x73, 0x9b, - 0xe9, 0xf7, 0x87, 0xef, 0x5c, 0x1b, 0xc0, 0xff, 0xff, 0xce, 0xe8, 0xef, - 0xef, 0xcb, 0x9f, 0x4c, 0x9e, 0x4c, 0xbe, 0x6f, 0x3e, 0x6d, 0x3e, 0x4c, - 0xbf, 0x4c, 0x9e, 0x4d, 0x9e, 0x4f, 0xff, 0xde, 0xbb, 0x8b, 0x8f, 0xa4, - 0xb1, 0x9a, 0x0b, 0xf4, 0x90, 0xef, 0xdf, 0x5c, 0x73, 0xef, 0xff, 0xcc, - 0xff, 0xd4, 0x9b, 0x23, 0xbb, 0xff, 0x8d, 0xa3, 0xbb, 0xdb, 0xff, 0xcf, - 0xff, 0xd7, 0xff, 0xce, 0xff, 0x5c, 0xad, 0xa4, 0xdf, 0x55, 0xf8, 0xdc, - 0xf1, 0x9a, 0x04, 0xf4, 0x98, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xbe, 0x4c, - 0xbd, 0x4c, 0xbc, 0x4c, 0xbb, 0x4c, 0x7c, 0xeb, 0xab, 0xff, 0xff, 0xdf, - 0x43, 0xff, 0xff, 0xdf, 0x63, 0xff, 0xff, 0xdf, 0x57, 0xff, 0xff, 0xdf, - 0xff, 0x8b, 0xba, 0x8b, 0xfb, 0xc7, 0xf8, 0xf7, 0x9b, 0xef, 0xfc, 0x3b, - 0xdf, 0xf7, 0x9f, 0x77, 0xb3, 0x93, 0xdf, 0x57, 0xc3, 0x87, 0xff, 0xff, - 0x03, 0xff, 0xff, 0xdf, 0x2b, 0xeb, 0xdd, 0xeb, 0x81, 0xee, 0x5c, 0x27, + 0xff, 0xdd, 0xbf, 0x5c, 0xc3, 0x87, 0xff, 0xff, 0x3c, 0xeb, 0xbf, 0x8a, + 0xba, 0x8b, 0xa4, 0xef, 0xff, 0xcc, 0x70, 0x92, 0xff, 0x6d, 0x7f, 0x7f, + 0xad, 0x9a, 0xf5, 0xf7, 0x7e, 0x77, 0xad, 0x9b, 0xf8, 0xf7, 0x89, 0xef, + 0x3c, 0x3b, 0xb9, 0xf7, 0xff, 0xcc, 0x9f, 0x49, 0xf9, 0xfb, 0xff, 0xdc, + 0xfc, 0xdd, 0xba, 0xc4, 0x10, 0xf4, 0xff, 0xcf, 0x7c, 0xeb, 0xff, 0xff, + 0x3c, 0xeb, 0xb2, 0xef, 0x9d, 0x1b, 0xb8, 0xff, 0xd1, 0xa4, 0xde, 0x4c, + 0xdd, 0x4c, 0xff, 0xce, 0xdf, 0x5c, 0x9d, 0x1b, 0x98, 0xff, 0xbc, 0x1b, + 0xc0, 0xff, 0x73, 0x9b, 0xdc, 0xf7, 0x96, 0xef, 0x5c, 0x1b, 0xc0, 0xff, + 0xff, 0xce, 0xfa, 0xef, 0xef, 0xcb, 0xf2, 0xfb, 0xb3, 0xff, 0xff, 0xdf, + 0xaa, 0xff, 0xff, 0xdf, 0xb7, 0xff, 0xff, 0xdf, 0x6f, 0xff, 0xff, 0xdf, + 0x63, 0xff, 0xff, 0xdf, 0x4f, 0xff, 0xff, 0xdf, 0x9f, 0x4c, 0x9e, 0x4c, + 0xbe, 0x6f, 0x3e, 0x6d, 0x3e, 0x4c, 0xbf, 0x4c, 0x9e, 0x4d, 0x9e, 0x4f, + 0xff, 0xde, 0xbb, 0x8b, 0x8f, 0xa4, 0xb1, 0x9a, 0x0b, 0xf4, 0x8a, 0xed, + 0xdf, 0x5c, 0x6a, 0xed, 0xff, 0xcc, 0xff, 0xd4, 0x9b, 0x23, 0xbb, 0xff, + 0x8d, 0xa3, 0xbb, 0xdb, 0xff, 0xcf, 0xff, 0xd7, 0xff, 0xce, 0xff, 0x5c, + 0xad, 0xa4, 0xdf, 0x55, 0xf8, 0xdc, 0xf1, 0x9a, 0x04, 0xf4, 0x91, 0xed, + 0xff, 0xcd, 0xbf, 0x4c, 0xbe, 0x4c, 0xbd, 0x4c, 0xbc, 0x4c, 0xbb, 0x4c, + 0x7c, 0xeb, 0xff, 0xff, 0xff, 0x8b, 0xba, 0x8b, 0xfb, 0xc7, 0xf8, 0xf7, + 0x97, 0xed, 0xfc, 0x3b, 0xdf, 0xf7, 0x9f, 0x77, 0xb3, 0x93, 0xdf, 0x57, + 0xc3, 0x87, 0xff, 0xff, 0x2b, 0xeb, 0xdd, 0xeb, 0x9e, 0xed, 0x5c, 0x27, 0xbb, 0xff, 0xbf, 0x6c, 0xdc, 0x27, 0xd2, 0xdf, 0xda, 0xa5, 0xdf, 0x47, 0xbc, 0x23, 0xd2, 0xdf, 0xbf, 0xc6, 0xb4, 0xf3, 0x00, 0xcc, 0x29, 0x9b, - 0xb7, 0xf3, 0x00, 0xc8, 0xc9, 0xee, 0x71, 0xa6, 0xfc, 0xfb, 0x28, 0x92, + 0xb7, 0xf3, 0x00, 0xc8, 0xc6, 0xee, 0x71, 0xa6, 0xfc, 0xfb, 0x28, 0x92, 0xb0, 0x92, 0x68, 0x92, 0x9c, 0xba, 0x93, 0xa3, 0x9d, 0x74, 0xbf, 0x67, 0x37, 0x9b, 0xf8, 0xf7, 0xbc, 0xba, 0xb7, 0xa3, 0xbe, 0x75, 0xbf, 0xc5, 0xea, 0xf3, 0xd5, 0xfb, 0x9c, 0xba, 0x93, 0xa3, 0xde, 0x74, 0xbf, 0xc6, 0xf0, 0xf3, 0x9c, 0xba, 0x93, 0xa3, 0x9e, 0x47, 0xfe, 0x7c, 0x00, 0x1c, - 0x3a, 0x00, 0xde, 0x67, 0x9c, 0x76, 0xbf, 0xc4, 0xfa, 0xf3, 0xbc, 0xba, + 0x38, 0x00, 0xde, 0x67, 0x9c, 0x76, 0xbf, 0xc4, 0xfa, 0xf3, 0xbc, 0xba, 0xb7, 0xa3, 0x9d, 0x55, 0xe3, 0xfb, 0x00, 0xcd, 0x61, 0x9b, 0xf7, 0xf7, - 0x9c, 0xb9, 0x93, 0xa3, 0x9f, 0x7c, 0xde, 0xee, 0x9e, 0x23, 0xbb, 0xff, + 0x9c, 0xb9, 0x93, 0xa3, 0x9f, 0x7c, 0xdb, 0xee, 0x9e, 0x23, 0xbb, 0xff, 0xf8, 0xfb, 0x1c, 0xb8, 0x03, 0xa3, 0x9c, 0xb9, 0x93, 0xa3, 0x9f, 0x7c, 0x9f, 0x58, 0x9c, 0xb9, 0x93, 0xa3, 0xff, 0xcd, 0xff, 0xd5, 0xbe, 0x5c, 0xf9, 0xfb, 0xbc, 0xba, 0xb7, 0xa3, 0xdf, 0x67, 0x9a, 0xa4, 0x9d, 0x55, 0x3c, 0xb9, 0x27, 0xa3, 0x9f, 0x79, 0x00, 0xcd, 0x71, 0x9b, 0x41, 0xf4, - 0xab, 0xef, 0xff, 0xcc, 0xdf, 0x75, 0xbf, 0xc6, 0xf8, 0xf7, 0xff, 0xdc, + 0xa7, 0xef, 0xff, 0xcc, 0xdf, 0x75, 0xbf, 0xc6, 0xf8, 0xf7, 0xff, 0xdc, 0x33, 0x8b, 0xfe, 0xdd, 0xba, 0xc4, 0x06, 0xf4, 0xe6, 0xfb, 0xfb, 0xc4, - 0xe8, 0xf7, 0x52, 0xef, 0x7a, 0x1b, 0x58, 0xff, 0x9b, 0x3b, 0xdb, 0xf7, + 0xe8, 0xf7, 0x4f, 0xef, 0x7a, 0x1b, 0x58, 0xff, 0x9b, 0x3b, 0xdb, 0xf7, 0xff, 0x73, 0xff, 0xcd, 0xbf, 0x53, 0x9a, 0x23, 0x47, 0xff, 0x9a, 0x3b, 0xbc, 0xf7, 0x9c, 0x27, 0xd0, 0xdf, 0x32, 0x84, 0xff, 0xcc, 0xff, 0xd4, 0x9a, 0x23, 0x47, 0xff, 0x9f, 0x73, 0xf3, 0x93, 0xff, 0x53, 0xfd, 0xeb, - 0x6b, 0xeb, 0xff, 0xff, 0xab, 0xff, 0xff, 0xdf, 0x03, 0xff, 0xff, 0xdf, - 0x2f, 0xeb, 0x00, 0x1c, 0x82, 0x00, 0x01, 0xf8, 0x2e, 0xeb, 0x90, 0xef, - 0x9f, 0x6c, 0xbf, 0xc4, 0xf6, 0xf3, 0xb1, 0xef, 0xff, 0xcc, 0xff, 0xdc, - 0xf0, 0x92, 0xdf, 0x6d, 0xbf, 0xc6, 0xf1, 0xf7, 0xfd, 0xfb, 0xff, 0xcb, - 0x97, 0xef, 0x7c, 0x3b, 0xbb, 0xf7, 0xff, 0x4b, 0x9f, 0x7f, 0xde, 0x77, - 0xf0, 0x93, 0x00, 0x1c, 0xa8, 0x00, 0xfe, 0xcf, 0xfa, 0xfb, 0xfc, 0xdd, - 0xbb, 0xc4, 0x13, 0xf4, 0xff, 0xcf, 0x6e, 0xeb, 0x57, 0xff, 0xff, 0xdf, - 0x53, 0xff, 0xff, 0xdf, 0x3d, 0xeb, 0xbc, 0x92, 0x91, 0xef, 0x9f, 0x6c, - 0xbf, 0xc4, 0xf5, 0xf3, 0xb2, 0xef, 0xff, 0xcc, 0xfe, 0xcf, 0xff, 0xdc, + 0x6b, 0xeb, 0xff, 0xff, 0x2f, 0xeb, 0x00, 0x1c, 0x7e, 0x00, 0x01, 0xf8, + 0x6f, 0xff, 0xff, 0xdf, 0xb7, 0xff, 0xff, 0xdf, 0x63, 0xff, 0xff, 0xdf, + 0x0f, 0xff, 0xff, 0xdf, 0x2e, 0xeb, 0x9b, 0xee, 0x9f, 0x6c, 0xbf, 0xc4, + 0xf6, 0xf3, 0xbc, 0xee, 0xff, 0xcc, 0xff, 0xdc, 0xf0, 0x92, 0xdf, 0x6d, + 0xbf, 0xc6, 0xf1, 0xf7, 0xfd, 0xfb, 0xff, 0xcb, 0x82, 0xef, 0x7c, 0x3b, + 0xbb, 0xf7, 0xff, 0x4b, 0x9f, 0x7f, 0xde, 0x77, 0xf0, 0x93, 0x00, 0x1c, + 0xaa, 0x00, 0xfe, 0xcf, 0xfa, 0xfb, 0xfc, 0xdd, 0xbb, 0xc4, 0x13, 0xf4, + 0xff, 0xcf, 0x6e, 0xeb, 0xff, 0x8b, 0xba, 0x8b, 0xfb, 0xc7, 0xf7, 0xf7, + 0x8a, 0xef, 0xfc, 0x3b, 0xdf, 0xf7, 0x9f, 0x77, 0xdc, 0x3b, 0xbe, 0xdf, + 0xdf, 0x57, 0xc3, 0x87, 0x3d, 0xeb, 0xbc, 0x92, 0x8e, 0xef, 0x9f, 0x6c, + 0xbf, 0xc4, 0xf5, 0xf3, 0xaf, 0xef, 0xff, 0xcc, 0xfe, 0xcf, 0xff, 0xdc, 0xf0, 0x92, 0xdf, 0x6d, 0xbf, 0xc6, 0xf6, 0xf7, 0xfc, 0xfb, 0xff, 0xcb, - 0xff, 0xcf, 0x98, 0xef, 0x7c, 0x3b, 0xbb, 0xf7, 0x5f, 0x4b, 0xf8, 0xfb, + 0xff, 0xcf, 0x95, 0xef, 0x7c, 0x3b, 0xbb, 0xf7, 0x5f, 0x4b, 0xf8, 0xfb, 0xdd, 0xa7, 0xfb, 0x8b, 0xfc, 0xdd, 0xba, 0xc7, 0x10, 0xf4, 0x00, 0xcf, - 0x7d, 0xeb, 0xff, 0xff, 0xef, 0xfe, 0xff, 0xdf, 0xeb, 0xfe, 0xff, 0xdf, + 0x7d, 0xeb, 0xff, 0xff, 0x63, 0xff, 0xff, 0xdf, 0x5f, 0xff, 0xff, 0xdf, + 0x0f, 0xff, 0xff, 0xdf, 0xfb, 0xfe, 0xff, 0xdf, 0xf7, 0xfe, 0xff, 0xdf, 0x2b, 0xeb, 0xd8, 0xeb, 0xfe, 0x8b, 0xff, 0x47, 0x32, 0xc7, 0xef, 0xf3, 0xa5, 0xed, 0xff, 0xcc, 0x9f, 0x5d, 0xfc, 0xdd, 0x93, 0x5d, 0x92, 0x5d, 0x9f, 0x5d, 0x9c, 0x5d, 0x9b, 0x5d, 0x9d, 0x5d, 0x9e, 0x5d, 0x7f, 0xce, @@ -831,326 +584,471 @@ u8 fw_data_tx[13304] = { 0xf6, 0xf7, 0xdc, 0x67, 0xbc, 0xa6, 0x77, 0x8b, 0xbc, 0x47, 0xbf, 0xc5, 0xe9, 0xf7, 0xfc, 0xcb, 0xeb, 0xfb, 0xcb, 0xef, 0xb1, 0xa6, 0x93, 0x5d, 0xff, 0xcc, 0x9d, 0x5d, 0x5d, 0x67, 0x52, 0x4e, 0xfc, 0x67, 0xff, 0x5d, - 0x9c, 0x5d, 0x9b, 0x5d, 0x9e, 0x5d, 0xf7, 0xcf, 0x00, 0x1c, 0xff, 0x01, + 0x9c, 0x5d, 0x9b, 0x5d, 0x9e, 0x5d, 0xf7, 0xcf, 0x00, 0x1c, 0x0f, 0x02, 0xfc, 0x92, 0xbf, 0xc7, 0xdb, 0xf7, 0xd2, 0xfb, 0xdd, 0x67, 0xff, 0xde, 0xdd, 0x47, 0xff, 0xcf, 0xf7, 0xfb, 0xfe, 0xcf, 0xf9, 0xfb, 0xff, 0xcd, 0xbb, 0x47, 0xbe, 0x47, 0xff, 0xcf, 0xff, 0xcb, 0x25, 0x9b, 0x86, 0xf4, 0xdc, 0xef, 0xb1, 0xa6, 0x93, 0x5d, 0x7e, 0x5d, 0xf9, 0xfb, 0xff, 0xff, - 0xdb, 0xfe, 0xff, 0xdf, 0xd7, 0xfe, 0xff, 0xdf, 0xfd, 0x5d, 0x9e, 0x67, + 0xe7, 0xfe, 0xff, 0xdf, 0xe3, 0xfe, 0xff, 0xdf, 0xfd, 0x5d, 0x9e, 0x67, 0x9c, 0x5d, 0x5b, 0x67, 0x5b, 0x5d, 0xfd, 0x67, 0xf2, 0x4e, 0xdc, 0x67, - 0xdf, 0x5d, 0xf4, 0xfb, 0x96, 0xef, 0x9e, 0x57, 0x00, 0x1c, 0x7d, 0x02, - 0xff, 0x5b, 0xb7, 0xef, 0xbe, 0x4b, 0xec, 0x93, 0x00, 0x1c, 0x13, 0x01, + 0xdf, 0x5d, 0xf4, 0xfb, 0x96, 0xef, 0x9e, 0x57, 0x00, 0x1c, 0xbd, 0x02, + 0xff, 0x5b, 0xb7, 0xef, 0xbe, 0x4b, 0xec, 0x93, 0x00, 0x1c, 0x21, 0x01, 0x9f, 0x67, 0x9c, 0x1b, 0xfe, 0xbf, 0x9f, 0x47, 0xff, 0x67, 0xf8, 0xeb, - 0x6b, 0xeb, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xa3, 0xfe, 0xff, 0xdf, - 0x2e, 0xeb, 0x73, 0xef, 0x9b, 0x1b, 0xc8, 0xff, 0x9c, 0x4b, 0xf4, 0xef, - 0x00, 0x1c, 0x05, 0x01, 0xbc, 0x93, 0xfb, 0x23, 0xb7, 0xff, 0x00, 0xcc, - 0x3d, 0x9b, 0xfb, 0xf3, 0xf8, 0xef, 0x00, 0x1c, 0x64, 0x0d, 0xf8, 0xef, - 0x46, 0xce, 0xdd, 0xbe, 0xff, 0xcd, 0xff, 0x1f, 0xee, 0xfa, 0x6e, 0xeb, - 0xdb, 0xfe, 0xff, 0xdf, 0x7b, 0x92, 0xff, 0xff, 0x9f, 0x82, 0xff, 0xff, - 0xff, 0xef, 0xff, 0xbf, 0x96, 0xef, 0xbf, 0x6c, 0x76, 0xc5, 0xbf, 0x4c, - 0xbd, 0x6c, 0x9e, 0x6c, 0xb8, 0xef, 0xff, 0xcc, 0x9f, 0x5d, 0xfc, 0xdd, - 0x93, 0x5d, 0x92, 0x5d, 0x9f, 0x5d, 0x9c, 0x5d, 0x9b, 0x5d, 0x9d, 0x5d, - 0x9e, 0x5d, 0xc3, 0x87, 0xff, 0xef, 0xff, 0xbf, 0xdb, 0xfe, 0xff, 0xdf, - 0x2e, 0xeb, 0x8a, 0xed, 0xbf, 0x6c, 0x76, 0xc5, 0xbf, 0x4c, 0xdd, 0x6c, + 0x6b, 0xeb, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xaf, 0xfe, 0xff, 0xdf, + 0x2e, 0xeb, 0x67, 0xed, 0x9b, 0x1b, 0xc8, 0xff, 0x9c, 0x4b, 0xe8, 0xed, + 0x00, 0x1c, 0x0b, 0x01, 0xbc, 0x93, 0xfb, 0x23, 0xb7, 0xff, 0x00, 0xcc, + 0x3d, 0x9b, 0xfb, 0xf3, 0xec, 0xed, 0x00, 0x1c, 0x0a, 0x0b, 0xec, 0xed, + 0x46, 0xce, 0xdd, 0xbe, 0xff, 0xcd, 0xff, 0x1f, 0xc0, 0xfa, 0x6e, 0xeb, + 0x90, 0xed, 0xbf, 0x6c, 0x76, 0xc5, 0xbf, 0x4c, 0xbd, 0x6c, 0x9e, 0x6c, + 0xb6, 0xed, 0xff, 0xcc, 0x9f, 0x5d, 0xfc, 0xdd, 0x93, 0x5d, 0x92, 0x5d, + 0x9f, 0x5d, 0x9c, 0x5d, 0x9b, 0x5d, 0x9d, 0x5d, 0x9e, 0x5d, 0xc3, 0x87, + 0x2e, 0xeb, 0x99, 0xed, 0xbf, 0x6c, 0x76, 0xc5, 0xbf, 0x4c, 0xdd, 0x6c, 0xbe, 0x6c, 0xb6, 0xa6, 0xdd, 0x6c, 0xde, 0x4c, 0xdf, 0x6c, 0x56, 0xc6, - 0xdf, 0x4c, 0xb6, 0xcc, 0x73, 0x9b, 0xf2, 0xf3, 0xb1, 0xed, 0xff, 0xcc, + 0xdf, 0x4c, 0xb6, 0xcc, 0x73, 0x9b, 0xf2, 0xf3, 0xa4, 0xee, 0xff, 0xcc, 0x9f, 0x5d, 0xfc, 0xdd, 0x93, 0x5d, 0x92, 0x5d, 0x9f, 0x5d, 0x9c, 0x5d, - 0x9b, 0x5d, 0x9d, 0x5d, 0x9e, 0x5d, 0x72, 0xfb, 0x75, 0xcc, 0x9e, 0xbc, + 0x9b, 0x5d, 0x9d, 0x5d, 0x9e, 0x5d, 0x66, 0xfb, 0x75, 0xcc, 0x9e, 0xbc, 0x73, 0x9b, 0xee, 0xf7, 0xfc, 0x15, 0xb0, 0xfd, 0x73, 0x9b, 0xf0, 0xf7, - 0xbb, 0xed, 0xff, 0xcc, 0x9f, 0x5d, 0xfc, 0xdd, 0x93, 0x5d, 0x92, 0x5d, - 0x9f, 0x5d, 0x9c, 0x5d, 0x9b, 0x5d, 0x9d, 0x5d, 0x9e, 0x5d, 0x86, 0xfb, - 0xfe, 0xcc, 0xfd, 0xfb, 0xff, 0xcc, 0xa1, 0xee, 0xbe, 0x7d, 0xbf, 0xc5, - 0xde, 0xf7, 0xbf, 0xc4, 0xf3, 0xf3, 0xa4, 0xee, 0x9b, 0x7d, 0xff, 0xdc, - 0x33, 0x8b, 0x9b, 0x5d, 0xeb, 0xcd, 0x37, 0x9b, 0x97, 0xf7, 0x88, 0xee, - 0xbb, 0x5c, 0x9a, 0xfb, 0x8a, 0xee, 0xbb, 0x7c, 0xfa, 0xcc, 0x73, 0x9b, - 0xf4, 0xf7, 0x8d, 0xee, 0xb1, 0xa4, 0xdd, 0x6d, 0xfe, 0xde, 0xd2, 0x4c, + 0xae, 0xee, 0xff, 0xcc, 0x9f, 0x5d, 0xfc, 0xdd, 0x93, 0x5d, 0x92, 0x5d, + 0x9f, 0x5d, 0x9c, 0x5d, 0x9b, 0x5d, 0x9d, 0x5d, 0x9e, 0x5d, 0x7a, 0xfb, + 0xfe, 0xcc, 0xfd, 0xfb, 0xff, 0xcc, 0xb1, 0xee, 0xbe, 0x7d, 0xbf, 0xc5, + 0xde, 0xf7, 0xbf, 0xc4, 0xf3, 0xf3, 0xb4, 0xee, 0x9b, 0x7d, 0xff, 0xdc, + 0x33, 0x8b, 0x9b, 0x5d, 0xeb, 0xcd, 0x37, 0x9b, 0x8b, 0xf7, 0x98, 0xee, + 0xbb, 0x5c, 0x8e, 0xfb, 0x9a, 0xee, 0xbb, 0x7c, 0xfa, 0xcc, 0x73, 0x9b, + 0xf4, 0xf7, 0x80, 0xef, 0xb1, 0xa4, 0xdd, 0x6d, 0xfe, 0xde, 0xd2, 0x4c, 0xfe, 0xce, 0xdd, 0x5d, 0xde, 0x5d, 0xff, 0xcd, 0xbf, 0x5c, 0xff, 0xcd, - 0x92, 0xee, 0xbb, 0x5c, 0xad, 0xfb, 0xb4, 0xee, 0xbf, 0x7d, 0xbf, 0xc5, - 0xf5, 0xf7, 0xbf, 0xc4, 0xfa, 0xf7, 0x97, 0xee, 0xbf, 0x5c, 0xff, 0xcc, - 0xc0, 0xfb, 0xb9, 0xee, 0x9f, 0x5d, 0xba, 0xfb, 0xbe, 0xc5, 0xf0, 0xf7, - 0xbc, 0xa4, 0xbf, 0xc5, 0xfa, 0xf7, 0x9d, 0xee, 0xbf, 0x5c, 0xfe, 0xcc, - 0xcc, 0xfb, 0xbf, 0xc4, 0xc5, 0xf7, 0xff, 0xcd, 0x81, 0xef, 0xbf, 0x5c, - 0xfe, 0xcc, 0xd3, 0xfb, 0xbd, 0xc5, 0xcc, 0xf7, 0xbf, 0xc4, 0xea, 0xf7, - 0x85, 0xef, 0xff, 0xcd, 0xbf, 0x5c, 0xfc, 0xdc, 0xd2, 0x7c, 0xf3, 0xcf, + 0x82, 0xef, 0xbb, 0x5c, 0xa1, 0xfb, 0xa7, 0xef, 0xbf, 0x7d, 0xbf, 0xc5, + 0xf5, 0xf7, 0xbf, 0xc4, 0xfa, 0xf7, 0x8a, 0xef, 0xbf, 0x5c, 0xff, 0xcc, + 0xb4, 0xfb, 0xac, 0xef, 0x9f, 0x5d, 0xae, 0xfb, 0xbe, 0xc5, 0xf0, 0xf7, + 0xbc, 0xa4, 0xbf, 0xc5, 0xfa, 0xf7, 0x90, 0xef, 0xbf, 0x5c, 0xfe, 0xcc, + 0xc0, 0xfb, 0xbf, 0xc4, 0xb9, 0xf7, 0xff, 0xcd, 0x94, 0xef, 0xbf, 0x5c, + 0xfe, 0xcc, 0xc7, 0xfb, 0xbd, 0xc5, 0xc0, 0xf7, 0xbf, 0xc4, 0xde, 0xf7, + 0x98, 0xef, 0xff, 0xcd, 0xbf, 0x5c, 0xfc, 0xdc, 0xd2, 0x7c, 0xf3, 0xcf, 0x7b, 0xa4, 0x7f, 0xa3, 0xbd, 0x5b, 0xff, 0xde, 0xde, 0x1b, 0xe0, 0xdf, + 0xf3, 0xfb, 0xff, 0xff, 0xe7, 0xfe, 0xff, 0xdf, 0x0f, 0x9e, 0xff, 0xff, + 0xab, 0x8c, 0xff, 0xff, 0xff, 0xef, 0xff, 0xbf, 0xe3, 0xfe, 0xff, 0xdf, 0x7b, 0xa4, 0xff, 0xa3, 0xbd, 0x5f, 0xbd, 0xa6, 0xbd, 0x1b, 0xe0, 0xdf, - 0xb2, 0x5c, 0xf2, 0xfb, 0xbe, 0xc4, 0xf9, 0xf7, 0xff, 0xcd, 0x90, 0xef, - 0xbf, 0x5c, 0xfe, 0xcc, 0xf2, 0xfb, 0xfe, 0xcd, 0x93, 0xef, 0xbf, 0x5c, - 0xff, 0xcc, 0xf7, 0xfb, 0x95, 0xef, 0xfc, 0x27, 0xb7, 0xff, 0xfe, 0xce, - 0x00, 0x1c, 0x87, 0x02, 0xf5, 0xfb, 0xb7, 0xef, 0xd2, 0x7d, 0xfb, 0xa5, + 0xb2, 0x5c, 0xf2, 0xfb, 0xbe, 0xc4, 0xf9, 0xf7, 0xff, 0xcd, 0x91, 0xef, + 0xbf, 0x5c, 0xfe, 0xcc, 0xf2, 0xfb, 0xfe, 0xcd, 0x94, 0xef, 0xbf, 0x5c, + 0xff, 0xcc, 0xf7, 0xfb, 0x96, 0xef, 0xfc, 0x27, 0xb7, 0xff, 0xfe, 0xce, + 0x00, 0x1c, 0x97, 0x02, 0xf5, 0xfb, 0xb8, 0xef, 0xd2, 0x7d, 0xfb, 0xa5, 0x91, 0x5f, 0x9d, 0xa6, 0x9c, 0x1b, 0xe0, 0xdf, 0x92, 0x5d, 0x0e, 0xf8, - 0x6e, 0xeb, 0xff, 0xff, 0xff, 0xef, 0xff, 0xbf, 0xdb, 0xfe, 0xff, 0xdf, - 0xd7, 0xfe, 0xff, 0xdf, 0x9d, 0xef, 0xff, 0x54, 0xc3, 0x87, 0xff, 0xff, - 0x91, 0xfe, 0xff, 0xdf, 0x99, 0xef, 0xfb, 0x6c, 0xff, 0x1b, 0x00, 0xdc, - 0xd8, 0xdf, 0x9a, 0xef, 0x9f, 0x74, 0xf3, 0x9b, 0xfc, 0xf7, 0xf2, 0xa7, - 0xfe, 0x8b, 0xc3, 0x87, 0xff, 0x7f, 0xff, 0xbf, 0x91, 0xfe, 0xff, 0xdf, - 0x9c, 0xef, 0xfb, 0x6c, 0xff, 0x1b, 0x00, 0xdc, 0xc3, 0x87, 0xff, 0xff, - 0xff, 0x7f, 0xff, 0xbf, 0x9a, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xfc, 0x93, - 0xfc, 0x93, 0xbd, 0x1b, 0x34, 0xf8, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, - 0xff, 0x7f, 0xff, 0xbf, 0x2f, 0xeb, 0x00, 0x1c, 0x0c, 0x00, 0x6f, 0xeb, - 0xff, 0x8b, 0x92, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xfc, 0x93, 0xfc, 0x93, - 0xfc, 0x93, 0xfd, 0xbf, 0xbf, 0x13, 0x7f, 0xf8, 0xbf, 0x4c, 0xfc, 0x93, - 0xb0, 0x93, 0xfe, 0xcd, 0x9f, 0x6e, 0x71, 0x97, 0x01, 0xf0, 0x99, 0xef, - 0xf3, 0xa7, 0xff, 0x6f, 0xff, 0x1b, 0x00, 0xdc, 0x9d, 0xef, 0xff, 0xcd, - 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0x7f, 0xff, 0xbf, 0xfb, 0x7f, 0xff, 0xbf, - 0x91, 0xef, 0xbc, 0x6c, 0x50, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, 0x79, 0xc5, - 0x78, 0xc5, 0xbc, 0x4c, 0xdc, 0x6c, 0xcc, 0xb6, 0xcc, 0xbe, 0xbc, 0x6c, - 0xb2, 0xbd, 0xb2, 0xb5, 0x7b, 0x93, 0xbc, 0x4c, 0xbc, 0x6c, 0x53, 0xc5, - 0xbc, 0x4c, 0xbc, 0x6c, 0x72, 0xc5, 0x71, 0xc5, 0x52, 0xc5, 0xbc, 0x4c, - 0xbf, 0x6c, 0x7e, 0xc5, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, - 0x97, 0xef, 0xbc, 0x6c, 0x70, 0xc5, 0xbc, 0x4c, 0xfc, 0x93, 0xfc, 0x93, - 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, - 0xbc, 0x6c, 0x50, 0xc5, 0xbc, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, - 0x9a, 0xef, 0xbf, 0x1b, 0xfc, 0xdf, 0xb9, 0xbd, 0xfc, 0x6c, 0x79, 0xc7, - 0x78, 0xc7, 0xf7, 0x93, 0xfc, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, - 0x9c, 0xef, 0xfc, 0x6c, 0xe6, 0xb7, 0xff, 0x1b, 0xfc, 0xdf, 0xc3, 0x87, - 0xff, 0x5f, 0xff, 0xbf, 0x3d, 0xeb, 0xff, 0x8b, 0xbb, 0x8b, 0x77, 0x8b, - 0x81, 0xef, 0x5c, 0x6c, 0x4c, 0xb2, 0x5a, 0x1b, 0x00, 0xd8, 0x4c, 0xba, - 0x7c, 0x6c, 0x72, 0xbb, 0x72, 0xb3, 0xeb, 0x92, 0x7c, 0x4c, 0x5c, 0x6c, - 0x4c, 0xb2, 0x74, 0xbf, 0xeb, 0x92, 0x6c, 0xbb, 0xfc, 0x6c, 0xf2, 0xbf, - 0xf2, 0xb7, 0xef, 0x93, 0xfc, 0x4c, 0x7c, 0x6c, 0xdf, 0x15, 0x07, 0x38, - 0xff, 0x96, 0xfc, 0x6c, 0xf2, 0xbf, 0xf2, 0xb7, 0xef, 0x93, 0xfc, 0x4c, - 0x7c, 0x6c, 0x6c, 0xb3, 0xf7, 0xbe, 0xef, 0x93, 0xec, 0xbf, 0xdc, 0x6c, - 0xd2, 0xbe, 0xd2, 0xb6, 0xbf, 0x93, 0xdc, 0x4c, 0xfc, 0x6c, 0xde, 0x15, - 0x07, 0x06, 0xfb, 0x97, 0xdc, 0x6c, 0xd2, 0xbe, 0xd2, 0xb6, 0xbf, 0x93, - 0xdc, 0x4c, 0xfc, 0x6c, 0xec, 0xb7, 0xd9, 0xbd, 0xbf, 0x93, 0xcc, 0xbe, - 0xbc, 0x6c, 0xb2, 0xbd, 0xb2, 0xb5, 0x7b, 0x93, 0xbc, 0x4c, 0x7d, 0xeb, - 0xff, 0x5f, 0xff, 0xbf, 0x94, 0xef, 0x9c, 0x6c, 0x9c, 0x1b, 0x3f, 0xdf, - 0xbf, 0xc4, 0xf6, 0xf7, 0x97, 0xef, 0xbc, 0x6c, 0x79, 0xc5, 0x78, 0xc5, - 0x59, 0xc5, 0xbc, 0x4c, 0xfe, 0xcf, 0xf8, 0xfb, 0x9b, 0xef, 0xbc, 0x6c, - 0x79, 0xc5, 0x78, 0xc5, 0xbc, 0x4c, 0xff, 0xcf, 0xc3, 0x87, 0xff, 0xff, - 0xff, 0x5f, 0xff, 0xbf, 0x98, 0xef, 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, + 0x6e, 0xeb, 0xff, 0xff, 0xe7, 0xfe, 0xff, 0xdf, 0xe3, 0xfe, 0xff, 0xdf, + 0x9d, 0xef, 0xff, 0x54, 0xc3, 0x87, 0xff, 0xff, 0x9d, 0xfe, 0xff, 0xdf, + 0x82, 0xef, 0xfb, 0x6c, 0xff, 0x1b, 0x00, 0xdc, 0xd8, 0xdf, 0x83, 0xef, + 0x9f, 0x74, 0xf3, 0x9b, 0xfc, 0xf7, 0xf2, 0xa7, 0xfe, 0x8b, 0xc3, 0x87, + 0x88, 0xef, 0xfb, 0x6c, 0xff, 0x1b, 0x00, 0xdc, 0xc3, 0x87, 0xff, 0xff, + 0x8b, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xfc, 0x93, 0xfc, 0x93, 0xbd, 0x1b, + 0x34, 0xf8, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0x2f, 0xeb, 0x00, 0x1c, + 0x0a, 0x00, 0x6f, 0xeb, 0xff, 0x8b, 0x92, 0xef, 0xff, 0xcd, 0xbf, 0x4c, + 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfd, 0xbf, 0xbf, 0x13, 0x7f, 0xf8, + 0xbf, 0x4c, 0xfc, 0x93, 0xb0, 0x93, 0xfe, 0xcd, 0x9f, 0x6e, 0x71, 0x97, + 0x01, 0xf0, 0x98, 0xef, 0xf3, 0xa7, 0xff, 0x6f, 0xff, 0x1b, 0x00, 0xdc, + 0x9d, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0x7f, 0xff, 0xbf, + 0x9d, 0xfe, 0xff, 0xdf, 0xfb, 0x7f, 0xff, 0xbf, 0x91, 0xef, 0xbc, 0x6c, + 0x50, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, 0x79, 0xc5, 0x78, 0xc5, 0xbc, 0x4c, + 0xdc, 0x6c, 0xcc, 0xb6, 0xcc, 0xbe, 0xbc, 0x6c, 0xb2, 0xbd, 0xb2, 0xb5, + 0x7b, 0x93, 0xbc, 0x4c, 0xbc, 0x6c, 0x53, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, + 0x72, 0xc5, 0x71, 0xc5, 0x52, 0xc5, 0xbc, 0x4c, 0xbf, 0x6c, 0x7e, 0xc5, + 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, 0x91, 0xed, 0xbc, 0x6c, + 0x70, 0xc5, 0xbc, 0x4c, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, + 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xbc, 0x6c, 0x50, 0xc5, + 0xbc, 0x4c, 0xc3, 0x87, 0x99, 0xed, 0xbf, 0x1b, 0xfc, 0xdf, 0xb9, 0xbd, + 0xfc, 0x6c, 0x79, 0xc7, 0x78, 0xc7, 0xf7, 0x93, 0xfc, 0x4c, 0xc3, 0x87, + 0x9e, 0xed, 0xfc, 0x6c, 0xe6, 0xb7, 0xff, 0x1b, 0xfc, 0xdf, 0xc3, 0x87, + 0x3d, 0xeb, 0xff, 0x8b, 0xbb, 0x8b, 0x77, 0x8b, 0x83, 0xee, 0x5c, 0x6c, + 0x4c, 0xb2, 0x5a, 0x1b, 0x00, 0xd8, 0x4c, 0xba, 0x7c, 0x6c, 0x72, 0xbb, + 0x72, 0xb3, 0xeb, 0x92, 0x7c, 0x4c, 0x5c, 0x6c, 0x4c, 0xb2, 0x74, 0xbf, + 0xeb, 0x92, 0x6c, 0xbb, 0xfc, 0x6c, 0xf2, 0xbf, 0xf2, 0xb7, 0xef, 0x93, + 0xfc, 0x4c, 0x7c, 0x6c, 0xdf, 0x15, 0x07, 0x38, 0xff, 0x96, 0xfc, 0x6c, + 0xf2, 0xbf, 0xf2, 0xb7, 0xef, 0x93, 0xfc, 0x4c, 0x7c, 0x6c, 0x6c, 0xb3, + 0xf7, 0xbe, 0xef, 0x93, 0xec, 0xbf, 0xdc, 0x6c, 0xd2, 0xbe, 0xd2, 0xb6, + 0xbf, 0x93, 0xdc, 0x4c, 0xfc, 0x6c, 0xde, 0x15, 0x07, 0x06, 0xfb, 0x97, + 0xdc, 0x6c, 0xd2, 0xbe, 0xd2, 0xb6, 0xbf, 0x93, 0xdc, 0x4c, 0xfc, 0x6c, + 0xec, 0xb7, 0xd9, 0xbd, 0xbf, 0x93, 0xcc, 0xbe, 0xbc, 0x6c, 0xb2, 0xbd, + 0xb2, 0xb5, 0x7b, 0x93, 0xbc, 0x4c, 0x7d, 0xeb, 0xbf, 0x8b, 0x81, 0xef, + 0xfc, 0x6c, 0xec, 0xb7, 0xff, 0x1b, 0x00, 0xd8, 0xec, 0xbf, 0xbc, 0x6c, + 0xb2, 0xbd, 0xb2, 0xb5, 0x7f, 0x93, 0xbc, 0x4c, 0xbc, 0x6c, 0xac, 0xb5, + 0xd4, 0xbe, 0xb7, 0x93, 0xcc, 0xbe, 0xbc, 0x6c, 0xb2, 0xbd, 0xb2, 0xb5, + 0x7b, 0x93, 0xbc, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0x8d, 0xef, 0x9c, 0x6c, + 0x9c, 0x1b, 0x3f, 0xdf, 0xbf, 0xc4, 0xf6, 0xf7, 0x90, 0xef, 0xbc, 0x6c, + 0x79, 0xc5, 0x78, 0xc5, 0x59, 0xc5, 0xbc, 0x4c, 0xfe, 0xcf, 0xf8, 0xfb, + 0x94, 0xef, 0xbc, 0x6c, 0x79, 0xc5, 0x78, 0xc5, 0xbc, 0x4c, 0xff, 0xcf, + 0xc3, 0x87, 0xff, 0xff, 0x98, 0xef, 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xbf, 0x6c, 0x7e, 0xc5, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, 0xff, 0x8b, 0x9a, 0xef, 0xbe, 0x6c, 0xfe, 0xce, 0xfe, 0x3b, 0xdf, 0xbf, 0xf7, 0x93, 0xfe, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xbf, - 0xff, 0x8b, 0xba, 0xef, 0xde, 0x6d, 0xff, 0xcc, 0xfe, 0xd4, 0x3c, 0x8f, - 0x3b, 0x97, 0x9e, 0x4d, 0xc3, 0x87, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xbf, - 0xff, 0x8b, 0x95, 0xef, 0x9e, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, - 0x3d, 0x97, 0xf8, 0xf3, 0x99, 0xef, 0xbe, 0x6c, 0xfd, 0x3b, 0xbf, 0xdf, - 0xfe, 0x4c, 0xfa, 0xfb, 0x9c, 0xef, 0xbe, 0x6c, 0xf7, 0x93, 0xfe, 0x4c, - 0xc3, 0x87, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xbf, 0xff, 0x8b, 0x97, 0xef, - 0xbd, 0x6c, 0xfe, 0xce, 0xfe, 0x3b, 0xdf, 0xbf, 0x7f, 0x93, 0xbd, 0x4c, - 0xbf, 0x6c, 0xfd, 0x93, 0x7f, 0x97, 0xbf, 0x4c, 0xbc, 0x6c, 0xf7, 0x97, - 0xfc, 0x4c, 0xc3, 0x87, 0xff, 0xaf, 0xff, 0xbf, 0x2f, 0xeb, 0x8c, 0xef, - 0xdc, 0x6c, 0xde, 0xb6, 0xde, 0x1b, 0xe0, 0xdf, 0x5f, 0xc6, 0xde, 0xbe, - 0xbc, 0x6c, 0xbd, 0x1b, 0xc1, 0xcf, 0x7b, 0x93, 0xbc, 0x4c, 0xff, 0xcf, - 0x00, 0x1c, 0x1f, 0x00, 0xff, 0xcf, 0x00, 0x1c, 0x50, 0x00, 0xfe, 0xcf, - 0x00, 0x1c, 0x25, 0x00, 0xfe, 0xcf, 0x00, 0x1c, 0x56, 0x00, 0xfa, 0xcf, - 0x00, 0x1c, 0x2b, 0x00, 0xfc, 0xcf, 0x00, 0x1c, 0x2e, 0x00, 0xfc, 0xcf, - 0x00, 0x1c, 0x53, 0x00, 0xfb, 0xcf, 0x00, 0x1c, 0x34, 0x00, 0x6f, 0xeb, - 0xff, 0x5f, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, 0x93, 0xef, 0xb2, 0xef, + 0xff, 0x8b, 0xa3, 0xee, 0xde, 0x6d, 0xff, 0xcc, 0xfe, 0xd4, 0x3c, 0x8f, + 0x3b, 0x97, 0x9e, 0x4d, 0xc3, 0x87, 0xff, 0xff, 0xff, 0x8b, 0x88, 0xee, + 0x9e, 0x6c, 0xfc, 0x3b, 0xbf, 0xbf, 0xff, 0x1b, 0xfe, 0xdf, 0xc3, 0x87, + 0xff, 0x8b, 0x8c, 0xee, 0x9e, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, + 0x3d, 0x97, 0xf8, 0xf3, 0x90, 0xee, 0xbe, 0x6c, 0xfd, 0x3b, 0xbf, 0xdf, + 0xfe, 0x4c, 0xfa, 0xfb, 0x93, 0xee, 0xbe, 0x6c, 0xf7, 0x93, 0xfe, 0x4c, + 0xc3, 0x87, 0xff, 0xff, 0xff, 0x8b, 0x96, 0xee, 0xbc, 0x6c, 0xfe, 0xce, + 0xfe, 0x3b, 0xdf, 0xbf, 0x7f, 0x93, 0xbc, 0x4c, 0xba, 0x6c, 0xf7, 0x93, + 0xfa, 0x4c, 0xc3, 0x87, 0xff, 0x8b, 0x9c, 0xee, 0xbc, 0x6c, 0xfe, 0xce, + 0xfe, 0x3b, 0xdf, 0xbf, 0x7f, 0x93, 0xbc, 0x4c, 0xba, 0x6c, 0x7f, 0x93, + 0xba, 0x4c, 0xb8, 0x6c, 0xf7, 0x93, 0xf8, 0x4c, 0xc3, 0x87, 0xff, 0xff, + 0xff, 0x8b, 0x84, 0xef, 0xbd, 0x6c, 0xfe, 0xce, 0xfe, 0x3b, 0xdf, 0xbf, + 0x7f, 0x93, 0xbd, 0x4c, 0xbf, 0x6c, 0xfd, 0x93, 0x7f, 0x97, 0xbf, 0x4c, + 0xbc, 0x6c, 0xf7, 0x97, 0xfc, 0x4c, 0xc3, 0x87, 0x2f, 0xeb, 0xff, 0xcf, + 0x00, 0x1c, 0x11, 0x00, 0xff, 0xcf, 0x00, 0x1c, 0x62, 0x00, 0xfe, 0xcf, + 0x00, 0x1c, 0x17, 0x00, 0xfe, 0xcf, 0x00, 0x1c, 0x68, 0x00, 0xfa, 0xcf, + 0x00, 0x1c, 0x1d, 0x00, 0xfc, 0xcf, 0x00, 0x1c, 0x20, 0x00, 0xfc, 0xcf, + 0x00, 0x1c, 0x65, 0x00, 0xfb, 0xcf, 0x00, 0x1c, 0x26, 0x00, 0x6f, 0xeb, + 0xff, 0x8b, 0x99, 0xef, 0x9f, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, + 0xf3, 0x97, 0xbf, 0xc7, 0xff, 0x3b, 0xff, 0xfa, 0xc3, 0x87, 0xff, 0xff, + 0xff, 0xaf, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, 0x93, 0xef, 0xb2, 0xef, 0xbf, 0x4c, 0x92, 0xef, 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0x5f, 0xc5, 0xbd, 0x4c, 0xfd, 0xcd, 0xbf, 0x4c, 0xb6, 0xef, 0xfd, 0xce, 0xad, 0xcc, 0x9e, 0x4d, 0x9f, 0x6d, 0xb1, 0x97, 0x01, 0xf0, 0x9f, 0x6d, 0x7e, 0xc4, 0x9f, 0x4d, 0x07, 0xf8, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xbf, 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xcf, 0xff, 0xbf, - 0x9f, 0xeb, 0x9d, 0xeb, 0x93, 0xef, 0xb2, 0xef, 0xbf, 0x4c, 0x92, 0xef, + 0x9f, 0xeb, 0x9d, 0xeb, 0x92, 0xfc, 0xb3, 0xfc, 0xbf, 0x4c, 0x93, 0xfc, 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0x5f, 0xc5, 0xbd, 0x4c, - 0xfd, 0xcd, 0xbf, 0x4c, 0xb6, 0xef, 0xfd, 0xce, 0xb4, 0xcc, 0x9e, 0x4d, + 0xfd, 0xcd, 0xbf, 0x4c, 0xaf, 0xfc, 0xfd, 0xce, 0xb4, 0xcc, 0x9e, 0x4d, 0x9f, 0x6d, 0xb1, 0x97, 0x01, 0xf0, 0x9f, 0x6d, 0x7e, 0xc4, 0x9f, 0x4d, - 0x07, 0xf8, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xbf, 0xae, 0x1a, 0x33, 0xe5, - 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xcf, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, - 0x93, 0xef, 0xb2, 0xef, 0xbf, 0x4c, 0x92, 0xef, 0xbd, 0x6c, 0x5e, 0xc5, - 0xbd, 0x4c, 0xbd, 0x6c, 0x5f, 0xc5, 0xbd, 0x4c, 0xfd, 0xcd, 0xbf, 0x4c, - 0xb6, 0xef, 0xfd, 0xce, 0xba, 0xcc, 0x9e, 0x4d, 0x9f, 0x6d, 0xb1, 0x97, - 0x01, 0xf0, 0x9f, 0x6d, 0x7e, 0xc4, 0x9f, 0x4d, 0x07, 0xf8, 0xff, 0xff, - 0xff, 0xbb, 0xff, 0xbf, 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, - 0xff, 0xcf, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, - 0x3c, 0x05, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, - 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, 0xbc, 0x09, 0x11, 0x26, - 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, - 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x07, 0xf8, 0xff, 0xff, 0x9f, 0xeb, 0x9d, 0xeb, 0x85, 0xfc, 0xa6, 0xfc, + 0xbf, 0x4c, 0x86, 0xfc, 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, + 0x5f, 0xc5, 0xbd, 0x4c, 0xfd, 0xcd, 0xbf, 0x4c, 0xa2, 0xfc, 0xfd, 0xce, + 0xba, 0xcc, 0x9e, 0x4d, 0x9f, 0x6d, 0xb1, 0x97, 0x01, 0xf0, 0x9f, 0x6d, + 0x7e, 0xc4, 0x9f, 0x4d, 0x07, 0xf8, 0xff, 0xff, 0x9f, 0xeb, 0x9d, 0xeb, + 0x2f, 0xeb, 0x00, 0x1c, 0x7e, 0x05, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, + 0x5c, 0x09, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, - 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, 0x7c, 0x08, 0x11, 0x26, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, + 0x3e, 0x08, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, 0xde, 0x02, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, - 0x2f, 0xeb, 0x00, 0x1c, 0xc2, 0x02, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, - 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, - 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, - 0x16, 0x0d, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, - 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x96, 0xef, 0x9f, 0x6c, 0x3b, 0xc4, - 0xfa, 0xf7, 0x98, 0xef, 0x9f, 0x6c, 0x3f, 0xc4, 0xfa, 0xf3, 0xff, 0xcf, - 0xfd, 0xce, 0x00, 0x1c, 0x2a, 0x0d, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, - 0x9c, 0xeb, 0x9e, 0xeb, 0xff, 0x5f, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0xe3, 0xed, + 0x00, 0x1c, 0x01, 0x0e, 0xff, 0xcf, 0xfa, 0xce, 0x00, 0x1c, 0x89, 0x0c, + 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xff, 0xff, + 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x8a, 0xed, 0x9f, 0x6c, 0x3b, 0xc4, + 0xfa, 0xf7, 0x8c, 0xed, 0x9f, 0x6c, 0x3f, 0xc4, 0xf7, 0xf3, 0xed, 0xed, + 0x00, 0x1c, 0x19, 0x0e, 0xff, 0xcf, 0xfd, 0xce, 0x00, 0x1c, 0xa1, 0x0c, + 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xff, 0xff, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0xff, 0xcf, + 0x00, 0x1c, 0x3d, 0x01, 0x00, 0x1c, 0x19, 0x03, 0x11, 0x26, 0xff, 0xdf, + 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xff, 0xff, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, - 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0xff, 0xcf, 0x00, 0x1c, 0x2f, 0x01, - 0x00, 0x1c, 0xf3, 0x02, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, - 0x9e, 0xeb, 0xff, 0xff, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, - 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x2f, 0xeb, 0xff, 0x8b, - 0x00, 0x1c, 0xf3, 0x0f, 0x6f, 0xeb, 0xff, 0xff, 0x2f, 0xeb, 0xff, 0x8b, - 0x00, 0x1c, 0xef, 0x0f, 0x6f, 0xeb, 0xff, 0xff, 0x2f, 0xeb, 0x00, 0x1c, - 0x38, 0x10, 0x00, 0x1c, 0x04, 0x10, 0x83, 0xef, 0xb8, 0x6c, 0x5f, 0xc5, - 0xb8, 0x4c, 0xf9, 0xcf, 0x00, 0x1c, 0x07, 0x10, 0xf9, 0xcf, 0xff, 0xce, - 0x00, 0x1c, 0xf7, 0x0f, 0xf6, 0xcf, 0x00, 0x1c, 0x0e, 0x10, 0xf6, 0xcf, - 0xff, 0xce, 0x00, 0x1c, 0xfe, 0x0f, 0xf7, 0xcf, 0x00, 0x1c, 0x15, 0x10, - 0xf7, 0xcf, 0xff, 0xce, 0x00, 0x1c, 0x05, 0x10, 0xee, 0xcf, 0x00, 0x1c, - 0x1c, 0x10, 0xee, 0xcf, 0xff, 0xce, 0x00, 0x1c, 0x0c, 0x10, 0xfe, 0xcf, - 0x00, 0x1c, 0x23, 0x10, 0xfe, 0xcf, 0xff, 0xce, 0x00, 0x1c, 0x13, 0x10, - 0xfd, 0xcf, 0x00, 0x1c, 0x2a, 0x10, 0xfd, 0xcf, 0xfc, 0xce, 0x00, 0x1c, - 0x1a, 0x10, 0xff, 0xcf, 0x00, 0x1c, 0x31, 0x10, 0xff, 0xcf, 0xfd, 0xce, - 0x00, 0x1c, 0x21, 0x10, 0x6f, 0xeb, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xbf, - 0x2e, 0xeb, 0x89, 0xee, 0xbb, 0x6c, 0x7f, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, - 0x7c, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, 0x7b, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, - 0x7a, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, 0x58, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, - 0x79, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, 0xb3, 0xbd, 0xb3, 0xb5, 0xde, 0x15, - 0x4f, 0xdc, 0x7b, 0x93, 0xbb, 0x4c, 0xbb, 0x6c, 0xd6, 0xee, 0x7b, 0x97, - 0xd6, 0xee, 0x7b, 0x93, 0xbb, 0x4c, 0xbc, 0x6c, 0x4d, 0xc5, 0xbc, 0x4c, - 0xbc, 0x6c, 0x50, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, 0x4f, 0xc5, 0x4e, 0xc5, - 0xbc, 0x4c, 0xbc, 0x6c, 0x5f, 0xc5, 0xbc, 0x4c, 0xbe, 0x6c, 0x50, 0xc5, - 0xbe, 0x4c, 0xbd, 0x6c, 0x45, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0x43, 0xc5, - 0xbd, 0x4c, 0xff, 0xcc, 0xff, 0xdc, 0xaf, 0xc4, 0x01, 0xf4, 0xff, 0xcc, - 0xff, 0xd4, 0xa4, 0xef, 0x9f, 0x5d, 0x88, 0xef, 0xbd, 0x6c, 0x0f, 0xce, - 0xcf, 0xbe, 0x7b, 0x93, 0xbd, 0x4c, 0xbc, 0x6c, 0x57, 0xc5, 0xbc, 0x4c, - 0x00, 0x1c, 0xdf, 0x02, 0xff, 0xcc, 0xfd, 0x15, 0xfe, 0xfb, 0xff, 0xdc, - 0x71, 0x9b, 0x01, 0xf4, 0x6e, 0xef, 0xff, 0xcc, 0xff, 0xd4, 0x9e, 0x53, - 0x00, 0x1c, 0xf3, 0x02, 0xfd, 0x53, 0x00, 0x1c, 0x0c, 0x03, 0x95, 0xef, - 0xbc, 0x6c, 0x77, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, 0x7f, 0xc5, 0xbc, 0x4c, - 0xbd, 0x6c, 0x65, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0xd7, 0xef, 0x7b, 0x97, - 0xbd, 0x4c, 0xbb, 0x6c, 0x78, 0xc5, 0xbb, 0x4c, 0x6e, 0xeb, 0xff, 0xff, - 0xff, 0x5f, 0xff, 0xbf, 0x00, 0xff, 0x0f, 0x00, 0xff, 0xe2, 0xfe, 0xff, - 0x8f, 0xfe, 0xff, 0xdf, 0x00, 0x00, 0xf0, 0x00, 0x9d, 0xef, 0xfd, 0x74, - 0xc3, 0x87, 0xff, 0xff, 0x8f, 0xfe, 0xff, 0xdf, 0xfe, 0x8b, 0x95, 0xef, - 0xbb, 0x6c, 0xab, 0xb5, 0xd6, 0xef, 0xfe, 0x56, 0xd9, 0xbd, 0xb7, 0xa6, - 0xf7, 0x83, 0xef, 0xaf, 0xff, 0x1b, 0x00, 0xd0, 0xf7, 0xbf, 0xbb, 0x6c, - 0xda, 0xef, 0x7b, 0x97, 0x7f, 0x93, 0xbb, 0x4c, 0xc3, 0x87, 0xff, 0xff, - 0xff, 0x5f, 0xff, 0xbf, 0x8f, 0xfe, 0xff, 0xdf, 0x00, 0xff, 0x0f, 0x00, - 0x9d, 0xef, 0xfe, 0x74, 0xc3, 0x87, 0xff, 0xff, 0x8f, 0xfe, 0xff, 0xdf, - 0x2e, 0xeb, 0xfe, 0x8a, 0xff, 0x1f, 0xa9, 0xfe, 0xbe, 0xc7, 0xf2, 0xf7, - 0xfc, 0x15, 0x58, 0xfd, 0xf3, 0x9a, 0xea, 0xf7, 0x6c, 0x93, 0x41, 0xdc, - 0xf3, 0x9a, 0xfc, 0xf7, 0xfd, 0x15, 0x99, 0xfc, 0x76, 0x8b, 0xed, 0xfb, - 0xfc, 0x15, 0xd4, 0xfd, 0xf3, 0x9a, 0xf3, 0xf7, 0x6c, 0x93, 0x2a, 0xdc, - 0xf3, 0x9a, 0xfc, 0xf7, 0xfd, 0x15, 0xfe, 0xfc, 0x76, 0x8b, 0xf9, 0xfb, - 0x55, 0xcd, 0xbd, 0xbd, 0xfc, 0xfb, 0x74, 0xcd, 0xbd, 0xbd, 0x93, 0xef, - 0xeb, 0xbd, 0xdb, 0x6c, 0xd3, 0xbe, 0xd3, 0xb6, 0xbf, 0x93, 0xdb, 0x4c, - 0xd6, 0xef, 0xde, 0x76, 0xf9, 0xbe, 0xdb, 0xa7, 0xb7, 0x83, 0xcf, 0xae, - 0xde, 0x1b, 0x00, 0xd0, 0xd7, 0xbe, 0xbb, 0x6c, 0xfa, 0xef, 0x7f, 0x97, - 0x7b, 0x93, 0xbb, 0x4c, 0x6e, 0xeb, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xbf, - 0x8f, 0xfe, 0xff, 0xdf, 0x00, 0xff, 0x0f, 0x00, 0x9d, 0xef, 0xfb, 0x6c, - 0xeb, 0xb7, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, 0xbf, 0xc7, 0xf6, 0xf7, - 0x97, 0xef, 0xbb, 0x6c, 0x7a, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, 0x7f, 0xc5, - 0xbb, 0x4c, 0xf7, 0xfb, 0x9b, 0xef, 0xbb, 0x6c, 0x5a, 0xc5, 0xbb, 0x4c, - 0xbb, 0x6c, 0x7f, 0xc5, 0xbb, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, - 0x2b, 0xeb, 0xde, 0xeb, 0xbf, 0x47, 0x30, 0x92, 0x7e, 0x8a, 0xba, 0x8a, - 0xff, 0x1f, 0x07, 0xff, 0xbe, 0xc7, 0xf2, 0xf7, 0xfc, 0x15, 0x58, 0xfd, - 0x73, 0x9a, 0xea, 0xf7, 0xe4, 0x92, 0x41, 0xdc, 0x73, 0x9a, 0xfc, 0xf7, - 0xfb, 0x15, 0x99, 0xfc, 0xee, 0x8a, 0xed, 0xfb, 0xfc, 0x15, 0xd4, 0xfd, - 0x73, 0x9a, 0xf3, 0xf7, 0xe4, 0x92, 0x2a, 0xdc, 0x73, 0x9a, 0xfc, 0xf7, - 0xfb, 0x15, 0xfe, 0xfc, 0xee, 0x8a, 0xf9, 0xfb, 0x55, 0xcb, 0x7d, 0xbb, - 0xfc, 0xfb, 0x74, 0xcb, 0x7d, 0xbb, 0x93, 0xee, 0x5e, 0x54, 0x93, 0xee, - 0x9d, 0x6c, 0x25, 0xc4, 0xd6, 0xf7, 0xbf, 0xc0, 0xd8, 0xf3, 0xfe, 0xcf, - 0x00, 0x1c, 0x43, 0x00, 0x98, 0xee, 0xcb, 0xbb, 0xbb, 0x6c, 0xb3, 0xbd, + 0x2f, 0xeb, 0xff, 0x8b, 0x00, 0x1c, 0x67, 0x0d, 0x6f, 0xeb, 0xff, 0xff, + 0x2f, 0xeb, 0xff, 0x8b, 0x00, 0x1c, 0x65, 0x0d, 0x6f, 0xeb, 0xff, 0xff, + 0x2f, 0xeb, 0x00, 0x1c, 0xb8, 0x0d, 0x00, 0x1c, 0x7c, 0x0d, 0x9c, 0xee, + 0xb8, 0x6c, 0x5f, 0xc5, 0xb8, 0x4c, 0xf9, 0xcf, 0x00, 0x1c, 0x7b, 0x0d, + 0xf9, 0xcf, 0xff, 0xce, 0x00, 0x1c, 0x67, 0x0d, 0xf6, 0xcf, 0x00, 0x1c, + 0x82, 0x0d, 0xf6, 0xcf, 0xff, 0xce, 0x00, 0x1c, 0x6e, 0x0d, 0xf7, 0xcf, + 0x00, 0x1c, 0x89, 0x0d, 0xf7, 0xcf, 0xff, 0xce, 0x00, 0x1c, 0x75, 0x0d, + 0xee, 0xcf, 0x00, 0x1c, 0x90, 0x0d, 0xee, 0xcf, 0xff, 0xce, 0x00, 0x1c, + 0x7c, 0x0d, 0xfe, 0xcf, 0x00, 0x1c, 0x97, 0x0d, 0xfe, 0xcf, 0xff, 0xce, + 0x00, 0x1c, 0x83, 0x0d, 0xfd, 0xcf, 0x00, 0x1c, 0x9e, 0x0d, 0xfd, 0xcf, + 0xfc, 0xce, 0x00, 0x1c, 0x8a, 0x0d, 0xff, 0xcf, 0x00, 0x1c, 0xa5, 0x0d, + 0xff, 0xcf, 0xfd, 0xce, 0x00, 0x1c, 0x91, 0x0d, 0x6f, 0xeb, 0xff, 0xff, + 0xff, 0xbb, 0xff, 0xbf, 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, + 0xff, 0xcf, 0xff, 0xbf, 0x93, 0x8c, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xbf, + 0x87, 0x8c, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xbf, 0x2e, 0xeb, 0x89, 0xee, + 0xbb, 0x6c, 0x7f, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, 0x7c, 0xc5, 0xbb, 0x4c, + 0xbb, 0x6c, 0x7b, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, 0x7a, 0xc5, 0xbb, 0x4c, + 0xbb, 0x6c, 0x58, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, 0x79, 0xc5, 0xbb, 0x4c, + 0xbb, 0x6c, 0xb3, 0xbd, 0xb3, 0xb5, 0xde, 0x15, 0x4f, 0xdc, 0x7b, 0x93, + 0xbb, 0x4c, 0xbb, 0x6c, 0xd6, 0xee, 0x7b, 0x97, 0xd6, 0xee, 0x7b, 0x93, + 0xbb, 0x4c, 0xbc, 0x6c, 0x4d, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, 0x50, 0xc5, + 0xbc, 0x4c, 0xbc, 0x6c, 0x4f, 0xc5, 0x4e, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, + 0x5f, 0xc5, 0xbc, 0x4c, 0xbe, 0x6c, 0x50, 0xc5, 0xbe, 0x4c, 0xbd, 0x6c, + 0x45, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0x43, 0xc5, 0xbd, 0x4c, 0xff, 0xcc, + 0xff, 0xdc, 0xaf, 0xc4, 0x01, 0xf4, 0xff, 0xcc, 0xff, 0xd4, 0xa4, 0xef, + 0x9f, 0x5d, 0x88, 0xef, 0xbd, 0x6c, 0x0f, 0xce, 0xcf, 0xbe, 0x7b, 0x93, + 0xbd, 0x4c, 0xbc, 0x6c, 0x57, 0xc5, 0xbc, 0x4c, 0x00, 0x1c, 0x0f, 0x03, + 0xff, 0xcc, 0xfd, 0x15, 0xfe, 0xfb, 0xff, 0xdc, 0x71, 0x9b, 0x01, 0xf4, + 0x6e, 0xef, 0xff, 0xcc, 0xff, 0xd4, 0x9e, 0x53, 0x00, 0x1c, 0x21, 0x03, + 0xfd, 0x53, 0x00, 0x1c, 0x36, 0x03, 0x95, 0xef, 0xbc, 0x6c, 0x77, 0xc5, + 0xbc, 0x4c, 0xbc, 0x6c, 0x7f, 0xc5, 0xbc, 0x4c, 0xbd, 0x6c, 0x65, 0xc5, + 0xbd, 0x4c, 0xbd, 0x6c, 0xd7, 0xef, 0x7b, 0x97, 0xbd, 0x4c, 0xbb, 0x6c, + 0x78, 0xc5, 0xbb, 0x4c, 0x6e, 0xeb, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xbf, + 0x00, 0xff, 0x0f, 0x00, 0xff, 0xe2, 0xfe, 0xff, 0x9b, 0xfe, 0xff, 0xdf, + 0x00, 0x00, 0xf0, 0x00, 0x81, 0xed, 0xfd, 0x74, 0xc3, 0x87, 0xff, 0xff, + 0xfe, 0x8b, 0x82, 0xed, 0xbb, 0x6c, 0xab, 0xb5, 0xc5, 0xed, 0xfe, 0x56, + 0xd9, 0xbd, 0xb7, 0xa6, 0xf7, 0x83, 0xef, 0xaf, 0xff, 0x1b, 0x00, 0xd0, + 0xf7, 0xbf, 0xbb, 0x6c, 0xc8, 0xed, 0x7b, 0x97, 0x7f, 0x93, 0xbb, 0x4c, + 0xc3, 0x87, 0xff, 0xff, 0x8d, 0xed, 0xfe, 0x74, 0xc3, 0x87, 0xff, 0xff, + 0xfe, 0x8b, 0xfc, 0x15, 0xd4, 0xfd, 0xf3, 0x9b, 0xf6, 0xf7, 0x7c, 0x93, + 0x2a, 0xdc, 0xf3, 0x9b, 0xfc, 0xf7, 0xfd, 0x15, 0xfe, 0xfc, 0x76, 0x8b, + 0xfc, 0xfb, 0x74, 0xcd, 0xbd, 0xbd, 0x95, 0xed, 0xeb, 0xbd, 0xdb, 0x6c, + 0xd3, 0xbe, 0xd3, 0xb6, 0xbf, 0x93, 0xdb, 0x4c, 0xda, 0xed, 0xde, 0x76, + 0xf9, 0xbe, 0xdb, 0xa7, 0xb7, 0x83, 0xcf, 0xae, 0xde, 0x1b, 0x00, 0xd0, + 0xd7, 0xbe, 0xbb, 0x6c, 0xfd, 0xed, 0x7f, 0x97, 0x7b, 0x93, 0xbb, 0x4c, + 0xc3, 0x87, 0xff, 0xff, 0x81, 0xee, 0xfb, 0x6c, 0xeb, 0xb7, 0xc3, 0x87, + 0xbf, 0xc7, 0xf6, 0xf7, 0x84, 0xee, 0xbb, 0x6c, 0x7a, 0xc5, 0xbb, 0x4c, + 0xbb, 0x6c, 0x7f, 0xc5, 0xbb, 0x4c, 0xf7, 0xfb, 0x88, 0xee, 0xbb, 0x6c, + 0x5a, 0xc5, 0xbb, 0x4c, 0xbb, 0x6c, 0x7f, 0xc5, 0xbb, 0x4c, 0xc3, 0x87, + 0x8c, 0xee, 0x9b, 0x6c, 0x9c, 0x1b, 0xdf, 0xdf, 0xbf, 0xc4, 0xff, 0x3b, + 0xff, 0xfa, 0xc3, 0x87, 0x2b, 0xeb, 0x34, 0x92, 0x70, 0x92, 0xfe, 0x8b, + 0xba, 0x8a, 0xfc, 0x15, 0xd4, 0xfd, 0xf3, 0x9b, 0xf6, 0xf7, 0xfc, 0x92, + 0x2a, 0xdc, 0xf3, 0x9b, 0xfc, 0xf7, 0xfb, 0x15, 0xfe, 0xfc, 0xee, 0x8a, + 0xfc, 0xfb, 0x74, 0xcb, 0x7d, 0xbb, 0x9a, 0xee, 0x5e, 0x54, 0x9a, 0xee, + 0x9d, 0x6c, 0x25, 0xc4, 0xd6, 0xf7, 0xbf, 0xc1, 0xd8, 0xf3, 0xfe, 0xcf, + 0x00, 0x1c, 0x35, 0x00, 0x9f, 0xee, 0xcb, 0xbb, 0xbb, 0x6c, 0xb3, 0xbd, 0xb3, 0xb5, 0x7b, 0x93, 0xbb, 0x4c, 0x7b, 0x3b, 0xbd, 0xf7, 0xd9, 0xbd, - 0xdb, 0xa5, 0xcf, 0xb6, 0xd7, 0xbe, 0xbb, 0x6c, 0xfe, 0xee, 0x7f, 0x97, + 0xdb, 0xa5, 0xcf, 0xb6, 0xd7, 0xbe, 0xbb, 0x6c, 0xe5, 0xef, 0x7f, 0x97, 0x7b, 0x93, 0xbb, 0x4c, 0xbb, 0x6c, 0x58, 0xc5, 0xbb, 0x4c, 0xbc, 0x6c, 0x5f, 0xc5, 0xbc, 0x4c, 0xbd, 0x6c, 0x45, 0xc5, 0xbd, 0x4c, 0xff, 0xcc, - 0xff, 0xdc, 0xbb, 0xc4, 0x01, 0xf4, 0xff, 0xcc, 0xff, 0xd4, 0xa9, 0xef, - 0x9f, 0x5d, 0x89, 0xef, 0xcb, 0xbb, 0xbb, 0x6c, 0xb3, 0xbd, 0xb3, 0xb5, + 0xff, 0xdc, 0xbb, 0xc4, 0x01, 0xf4, 0xff, 0xcc, 0xff, 0xd4, 0xb0, 0xef, + 0x9f, 0x5d, 0x90, 0xef, 0xcb, 0xbb, 0xbb, 0x6c, 0xb3, 0xbd, 0xb3, 0xb5, 0x7b, 0x93, 0xbb, 0x4c, 0xb9, 0xba, 0x4b, 0xa5, 0xeb, 0x82, 0x6f, 0xab, - 0x7b, 0x1b, 0x00, 0xd0, 0x77, 0xbb, 0xbb, 0x6c, 0xd0, 0xef, 0x7b, 0x97, - 0x6f, 0x93, 0xbb, 0x4c, 0xbe, 0xc0, 0x7c, 0x9b, 0xf8, 0xbd, 0xdb, 0x6c, - 0x78, 0xc6, 0xbf, 0x93, 0xdb, 0x4c, 0xdc, 0x6c, 0x7f, 0xc6, 0xb7, 0x93, - 0xdc, 0x4c, 0xa5, 0xbd, 0xdd, 0x6c, 0x65, 0xc6, 0x7b, 0x93, 0xbd, 0x4c, - 0xff, 0x67, 0x00, 0x1c, 0x8c, 0x00, 0xfe, 0xeb, 0x6b, 0xeb, 0xff, 0xff, - 0x8f, 0xfe, 0xff, 0xdf, 0xff, 0x5f, 0xff, 0xbf, 0x00, 0xff, 0x0f, 0x00, - 0x98, 0xef, 0xbc, 0x6c, 0x7f, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, 0x77, 0xc5, - 0xbc, 0x4c, 0xbd, 0x6c, 0x65, 0xc5, 0xbd, 0x4c, 0xbb, 0x6c, 0x78, 0xc5, - 0xbb, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, 0xde, 0x4f, 0xdd, 0x4f, - 0x9f, 0x6f, 0x9c, 0x1b, 0xe0, 0xcf, 0x5e, 0xc4, 0x9f, 0x4f, 0x9f, 0x6f, - 0x78, 0xc4, 0x77, 0xc4, 0x9f, 0x4f, 0x9f, 0x6f, 0x59, 0xc4, 0x9f, 0x4f, - 0xbe, 0xc5, 0x7c, 0x9b, 0xba, 0xbd, 0x9f, 0x6f, 0x7a, 0xc4, 0x37, 0x93, - 0x9f, 0x4f, 0x9f, 0x6f, 0x76, 0xc4, 0x9f, 0x4f, 0xc3, 0x87, 0xff, 0xff, - 0x97, 0xef, 0xb7, 0x6c, 0x5f, 0xc5, 0xb7, 0x4c, 0x98, 0xef, 0xbf, 0x6c, - 0x59, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x5b, 0xc5, 0xbf, 0x4c, 0x01, 0xcd, - 0xb9, 0x4c, 0x00, 0xcd, 0xb8, 0x4c, 0xc3, 0x87, 0xff, 0xaf, 0xff, 0xbf, - 0xff, 0xcf, 0xff, 0xbf, 0x3e, 0xeb, 0xff, 0x8b, 0x95, 0xef, 0xfe, 0x4c, - 0xff, 0xcc, 0xf6, 0xef, 0xfd, 0xce, 0xfb, 0x15, 0xae, 0x3c, 0xfb, 0xfb, - 0xff, 0xdc, 0xf1, 0x9a, 0xfb, 0xf3, 0xbf, 0x6f, 0xb5, 0x97, 0x04, 0xf0, - 0x9c, 0xef, 0xbf, 0x6c, 0x7e, 0xc5, 0xbf, 0x4c, 0x7e, 0xeb, 0xff, 0xff, - 0xff, 0xcf, 0xff, 0xbf, 0x98, 0xef, 0xb7, 0xef, 0xbf, 0x4c, 0x97, 0xef, - 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0x5f, 0xc5, 0xbd, 0x4c, - 0xba, 0xef, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xbf, - 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, 0x3f, 0x04, 0xc6, 0xff, - 0x9d, 0xef, 0xbc, 0xef, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xbf, 0xff, 0xbf, - 0x3f, 0x04, 0xc6, 0xff, 0x9d, 0xef, 0xff, 0x5c, 0xc3, 0x87, 0xff, 0xff, - 0x89, 0xfe, 0xff, 0xdf, 0x9d, 0xef, 0xff, 0x7c, 0xc3, 0x87, 0xff, 0xff, - 0x89, 0xfe, 0xff, 0xdf, 0x9d, 0xef, 0xff, 0x5c, 0xc3, 0x87, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xff, 0x7c, 0xc3, 0x87, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xfe, 0x7c, 0xc3, 0x87, 0xff, 0xff, - 0x89, 0xfe, 0xff, 0xdf, 0x9d, 0xef, 0xfd, 0x7c, 0xc3, 0x87, 0xff, 0xff, - 0x89, 0xfe, 0xff, 0xdf, 0x2c, 0xeb, 0x9f, 0xee, 0xbf, 0x6c, 0xdf, 0x6c, - 0x7f, 0x6c, 0x5f, 0x6c, 0x3e, 0x6c, 0x37, 0x8b, 0xac, 0xc4, 0xd7, 0xf7, - 0xfe, 0x3b, 0x7e, 0x8f, 0xfd, 0xc6, 0xe0, 0xf7, 0xfb, 0x3b, 0xbb, 0x8f, - 0xe7, 0xc3, 0xe4, 0xf7, 0xbf, 0xc7, 0xec, 0xf3, 0x67, 0x8a, 0x88, 0xef, - 0xdf, 0x5c, 0x47, 0xb2, 0x5e, 0x5c, 0xbf, 0xc1, 0xfb, 0xf7, 0xeb, 0xcd, - 0xbd, 0x5c, 0xf6, 0xfb, 0xfd, 0xc1, 0xfa, 0xf7, 0xff, 0xcd, 0x8e, 0xef, - 0xbd, 0x5c, 0xfc, 0xfb, 0x90, 0xef, 0x3d, 0x5c, 0x90, 0xef, 0x7f, 0x5c, - 0xfb, 0xcf, 0x00, 0x1c, 0xfa, 0x0f, 0xec, 0xfb, 0xfa, 0xcf, 0xfe, 0xce, - 0x00, 0x1c, 0xff, 0x0f, 0xf1, 0xfb, 0xfe, 0xcd, 0x97, 0xef, 0xbf, 0x5c, - 0xfa, 0xcd, 0x97, 0xef, 0xbf, 0x5c, 0xbf, 0xc7, 0xf9, 0xf3, 0x9a, 0xef, - 0xff, 0xcd, 0xbe, 0x5c, 0xeb, 0xcd, 0xbd, 0x5c, 0x6c, 0xeb, 0xff, 0xff, - 0xff, 0x6f, 0xff, 0xbf, 0x89, 0xfe, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xdf, - 0x2f, 0xeb, 0xde, 0xeb, 0x00, 0x1c, 0x47, 0x0d, 0x00, 0x1c, 0xf1, 0x07, - 0xfe, 0xcf, 0x00, 0x1c, 0x4c, 0x00, 0xf4, 0xef, 0xdf, 0x7f, 0x94, 0xef, - 0xbf, 0x7c, 0x9e, 0x7f, 0xfd, 0x7f, 0xff, 0x47, 0xf6, 0xef, 0x00, 0x1c, - 0x5a, 0x13, 0x00, 0x1c, 0x06, 0x06, 0x00, 0x1c, 0xb6, 0x08, 0x00, 0x1c, - 0x3e, 0x0d, 0x00, 0x1c, 0x32, 0x07, 0xff, 0xcf, 0xfe, 0xeb, 0x6f, 0xeb, - 0x89, 0xfe, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xdf, 0x87, 0x82, 0xff, 0xff, - 0xaf, 0xaa, 0xff, 0xff, 0xf7, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, - 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, - 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, - 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, - 0xe5, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, - 0x97, 0xaa, 0xff, 0xff, 0xa3, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, - 0xd3, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, 0x97, 0xaa, 0xff, 0xff, - 0xc1, 0xaa, 0xff, 0xff, 0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8, - 0xc7, 0xc6, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0x9f, 0x96, 0xff, 0xff, - 0x9f, 0x96, 0xff, 0xff, 0x05, 0x99, 0xff, 0xff, 0x9f, 0x96, 0xff, 0xff, - 0xb3, 0x98, 0xff, 0xff, 0x5b, 0x97, 0xff, 0xff, 0x9f, 0x96, 0xff, 0xff, - 0x0f, 0x97, 0xff, 0xff, 0x9f, 0x96, 0xff, 0xff, 0xd9, 0x96, 0xff, 0xff, - 0x9f, 0x96, 0xff, 0xff, 0x45, 0x98, 0xff, 0xff, 0x9f, 0x96, 0xff, 0xff, - 0xcd, 0x96, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0x3c, 0xb8, - 0xff, 0xff, 0xff, 0xc0, 0xd3, 0xdf, 0x8f, 0x96, 0x9b, 0xc5, 0xdf, 0xda, - 0x9b, 0xd7, 0x9a, 0x8d, 0x8d, 0xc5, 0xdf, 0xda, 0x9b, 0xd3, 0xdf, 0x96, - 0xc5, 0xda, 0x9b, 0xd3, 0xdf, 0x9b, 0xc5, 0xda, 0x9b, 0xd6, 0xff, 0xff, - 0xdf, 0x9a, 0x92, 0xc5, 0xda, 0x9b, 0xd3, 0xdf, 0x9c, 0x92, 0xc5, 0xdf, - 0xda, 0x9b, 0xd3, 0xdf, 0x99, 0x8d, 0x9a, 0x8e, 0xc5, 0xda, 0x9b, 0xd3, - 0xdf, 0x9b, 0x8a, 0x8b, 0x86, 0xdf, 0xda, 0x9b, 0xff, 0xff, 0xff, 0xff, - 0xdf, 0x96, 0xc5, 0xdf, 0xda, 0x9b, 0xdf, 0x92, 0xbe, 0xff, 0xff, 0xff, - 0xf2, 0xf5, 0xdf, 0x8d, 0x87, 0xc5, 0xda, 0x9b, 0xd3, 0xdf, 0x8b, 0x87, - 0xc5, 0xda, 0x9b, 0xd3, 0xdf, 0x96, 0xc5, 0xda, 0x9b, 0xd3, 0xdf, 0x93, - 0x90, 0x8c, 0x8c, 0xc5, 0xda, 0x9b, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x9c, - 0x9e, 0x93, 0x96, 0xdf, 0x8d, 0x9a, 0x8c, 0xdf, 0x96, 0x8c, 0xdf, 0xda, - 0x9b, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x91, 0x88, 0x94, 0xdf, 0x8c, - 0x8b, 0x9e, 0x8b, 0x9a, 0xdf, 0x8b, 0x90, 0xdf, 0xda, 0x9b, 0xff, 0xff, - 0xf2, 0xf5, 0xff, 0xff, 0xdf, 0xda, 0xcf, 0xcd, 0x87, 0xff, 0xff, 0xff, - 0xdf, 0x9c, 0x97, 0x94, 0x8c, 0x8a, 0x92, 0xdf, 0x9a, 0x8d, 0x8d, 0xd1, - 0xd1, 0xd1, 0xff, 0xff, 0xdf, 0x9b, 0x92, 0xd2, 0xc1, 0xda, 0x9b, 0xff, - 0xf2, 0xf5, 0xdf, 0x97, 0x86, 0x8c, 0xd4, 0xff, 0xf2, 0xf5, 0xdf, 0x97, - 0x86, 0x8c, 0xd2, 0xff, 0xf2, 0xf5, 0xdf, 0x99, 0x8d, 0x9a, 0x8e, 0xd4, - 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x8f, 0x90, 0x93, 0x9a, 0xd4, - 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x8f, 0x90, 0x93, 0x9a, 0xd2, - 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x9b, 0x92, 0xdf, 0x9c, 0x97, - 0x9e, 0x91, 0x98, 0x9a, 0x9b, 0xd1, 0xdf, 0xda, 0x9b, 0xff, 0xff, 0xff, - 0xf2, 0xf5, 0xdf, 0x8f, 0x9e, 0x9c, 0x94, 0x9a, 0x8b, 0xdf, 0x8b, 0x96, - 0x92, 0x9a, 0x90, 0x8a, 0x8b, 0xd1, 0xd1, 0xd1, 0xff, 0xff, 0xff, 0xff, - 0xf2, 0xf5, 0xdf, 0x8d, 0x8f, 0x8f, 0xdf, 0x8b, 0x96, 0x92, 0x9a, 0x90, - 0x8a, 0x8b, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x99, 0x8d, 0x9a, 0x8e, 0xd2, - 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x8f, 0x97, 0x86, 0xdf, 0x8b, - 0x9e, 0x8c, 0x94, 0xdf, 0x96, 0x9b, 0xdf, 0x96, 0x8c, 0xdf, 0xda, 0x9b, - 0xff, 0xff, 0xff, 0xff, 0x8b, 0x87, 0xa0, 0x92, 0x90, 0x9b, 0x9a, 0xc2, - 0xdf, 0xda, 0x9b, 0xd3, 0xdf, 0x96, 0x96, 0x91, 0xa0, 0x92, 0x9e, 0x87, - 0xc2, 0xdf, 0xda, 0x9b, 0xd3, 0xdf, 0x99, 0x90, 0x9b, 0xa0, 0x90, 0x99, - 0x99, 0x8c, 0x9a, 0x8b, 0xc2, 0xdf, 0xda, 0x9b, 0xd3, 0xdf, 0x8f, 0x96, - 0x91, 0x98, 0xa0, 0x90, 0x99, 0x99, 0x8c, 0x9a, 0x8b, 0xc2, 0xdf, 0xda, - 0x9b, 0xdf, 0xf2, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xff, 0xff, + 0x7b, 0x1b, 0x00, 0xd0, 0x77, 0xbb, 0xbb, 0x6c, 0xd7, 0xef, 0x7b, 0x97, + 0x6f, 0x93, 0xbb, 0x4c, 0xbe, 0xc1, 0x7c, 0x9b, 0xf8, 0xbd, 0xdb, 0x6c, + 0x78, 0xc6, 0xbf, 0x93, 0xdb, 0x4c, 0xf8, 0xfb, 0x9b, 0xfe, 0xff, 0xdf, + 0xff, 0x5f, 0xff, 0xbf, 0x00, 0xff, 0x0f, 0x00, 0xdc, 0x6c, 0x7f, 0xc6, + 0xb7, 0x93, 0xdc, 0x4c, 0xa5, 0xbd, 0xdd, 0x6c, 0x65, 0xc6, 0x7b, 0x93, + 0xbd, 0x4c, 0xe0, 0x93, 0x00, 0x1c, 0x85, 0x00, 0x6b, 0xeb, 0xff, 0xff, + 0x3e, 0xeb, 0xfe, 0x8b, 0x7a, 0x8b, 0x9d, 0xee, 0x6b, 0xbf, 0xdb, 0x6c, + 0xd3, 0xbe, 0xd3, 0xb6, 0xaf, 0x93, 0xdb, 0x4c, 0xd9, 0xbf, 0xdf, 0xa6, + 0xb7, 0x83, 0xcf, 0xae, 0xde, 0x1b, 0x00, 0xd0, 0xd7, 0xbe, 0xbb, 0x6c, + 0xe4, 0xef, 0x7f, 0x97, 0x7b, 0x93, 0xbb, 0x4c, 0xbc, 0x6c, 0x5f, 0xc5, + 0xbc, 0x4c, 0x7e, 0xeb, 0x89, 0xef, 0xbb, 0x6c, 0x58, 0xc5, 0xbb, 0x4c, + 0xbc, 0x6c, 0x5f, 0xc5, 0xbc, 0x4c, 0xbd, 0x6c, 0x45, 0xc5, 0xbd, 0x4c, + 0xc3, 0x87, 0xff, 0xff, 0x8f, 0xef, 0xbc, 0x6c, 0x7f, 0xc5, 0xbc, 0x4c, + 0xbc, 0x6c, 0x77, 0xc5, 0xbc, 0x4c, 0xbd, 0x6c, 0x65, 0xc5, 0xbd, 0x4c, + 0xbb, 0x6c, 0x78, 0xc5, 0xbb, 0x4c, 0xc3, 0x87, 0xbe, 0xc7, 0x96, 0xef, + 0x7c, 0x9b, 0xf8, 0xbd, 0xdb, 0x6c, 0x78, 0xc6, 0xbf, 0x93, 0xdb, 0x4c, + 0xdc, 0x6c, 0x7f, 0xc6, 0xb7, 0x93, 0xdc, 0x4c, 0xa5, 0xbd, 0xdd, 0x6c, + 0x65, 0xc6, 0x7b, 0x93, 0xbd, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, + 0x00, 0xff, 0x0f, 0x00, 0xde, 0x4f, 0xdd, 0x4f, 0x9f, 0x6f, 0x9c, 0x1b, + 0xe0, 0xcf, 0x5e, 0xc4, 0x9f, 0x4f, 0x9f, 0x6f, 0x78, 0xc4, 0x77, 0xc4, + 0x9f, 0x4f, 0x9f, 0x6f, 0x59, 0xc4, 0x9f, 0x4f, 0xbe, 0xc5, 0x7c, 0x9b, + 0xba, 0xbd, 0x9f, 0x6f, 0x7a, 0xc4, 0x37, 0x93, 0x9f, 0x4f, 0x9f, 0x6f, + 0x76, 0xc4, 0x9f, 0x4f, 0xc3, 0x87, 0xff, 0xff, 0x97, 0xef, 0xb7, 0x6c, + 0x5f, 0xc5, 0xb7, 0x4c, 0x98, 0xef, 0xbf, 0x6c, 0x59, 0xc5, 0xbf, 0x4c, + 0xbf, 0x6c, 0x5b, 0xc5, 0xbf, 0x4c, 0x01, 0xcd, 0xb9, 0x4c, 0x00, 0xcd, + 0xb8, 0x4c, 0xc3, 0x87, 0xff, 0xaf, 0xff, 0xbf, 0xff, 0xcf, 0xff, 0xbf, + 0x3e, 0xeb, 0xff, 0x8b, 0x9c, 0xed, 0xfe, 0x4c, 0xff, 0xcc, 0xfd, 0xed, + 0xfd, 0xce, 0xfb, 0x15, 0xae, 0x3c, 0xfb, 0xfb, 0xff, 0xdc, 0xf1, 0x9a, + 0xfb, 0xf3, 0xbf, 0x6f, 0xb5, 0x97, 0x04, 0xf0, 0x83, 0xee, 0xbf, 0x6c, + 0x7e, 0xc5, 0xbf, 0x4c, 0x7e, 0xeb, 0xff, 0xff, 0x2d, 0xeb, 0xde, 0xeb, + 0xfc, 0x92, 0xff, 0x1f, 0xd4, 0xfe, 0xff, 0x8b, 0x91, 0x1b, 0xfd, 0xff, + 0xff, 0x5c, 0xbf, 0x7c, 0x77, 0x8b, 0xdc, 0xa5, 0xbb, 0x8b, 0xdf, 0x5c, + 0xbf, 0xc5, 0xf2, 0xf3, 0xb0, 0x92, 0xff, 0x7b, 0xff, 0xdb, 0x00, 0x1c, + 0x28, 0x00, 0x9f, 0x7a, 0x33, 0x8b, 0xbc, 0xa4, 0x77, 0x8b, 0xbf, 0x5a, + 0xbf, 0xc4, 0x09, 0xf4, 0xfe, 0xeb, 0x6d, 0xeb, 0x2d, 0xeb, 0xde, 0xeb, + 0xbf, 0x8a, 0xbb, 0xb2, 0x91, 0x1b, 0xfd, 0xff, 0xbf, 0x5c, 0x9f, 0x7c, + 0x33, 0x8b, 0xf6, 0xc4, 0xf8, 0xf7, 0x91, 0x1b, 0xfd, 0xff, 0x9f, 0x7c, + 0xd0, 0xdc, 0x33, 0x8b, 0xf9, 0xfb, 0x91, 0x1b, 0xfd, 0xff, 0x9f, 0x7c, + 0xc9, 0xdc, 0x33, 0x8b, 0x71, 0x1b, 0xfd, 0xff, 0x9f, 0x5b, 0xff, 0x7b, + 0xff, 0x8b, 0x00, 0x1c, 0x4e, 0x00, 0x5a, 0x1b, 0xf0, 0xdf, 0x5f, 0x5b, + 0x9f, 0x7b, 0x33, 0x8b, 0xf6, 0xc4, 0xf8, 0xf7, 0x91, 0x1b, 0xfd, 0xff, + 0xbf, 0x7c, 0xd0, 0xdd, 0x77, 0x8b, 0xf9, 0xfb, 0x91, 0x1b, 0xfd, 0xff, + 0xbf, 0x7c, 0xc9, 0xdd, 0x77, 0x8b, 0x91, 0x1b, 0xfd, 0xff, 0xbf, 0x5c, + 0xff, 0x7c, 0xff, 0x8b, 0x00, 0x1c, 0x67, 0x00, 0xfe, 0xeb, 0x6d, 0xeb, + 0x2e, 0xeb, 0xfe, 0x8a, 0xf7, 0xb3, 0x00, 0x1c, 0x3a, 0x00, 0xef, 0x8b, + 0x00, 0x1c, 0x3d, 0x00, 0x6e, 0xeb, 0xff, 0xff, 0x2e, 0xeb, 0xfc, 0x92, + 0xe7, 0xb7, 0x00, 0x1c, 0x44, 0x00, 0xfb, 0x3b, 0xbf, 0x8f, 0x00, 0x1c, + 0x48, 0x00, 0xfb, 0x3b, 0x7f, 0x8f, 0x00, 0x1c, 0x4c, 0x00, 0xef, 0x8b, + 0x00, 0x1c, 0x4f, 0x00, 0x6e, 0xeb, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xbf, + 0x98, 0xef, 0xb7, 0xef, 0xbf, 0x4c, 0x97, 0xef, 0xbd, 0x6c, 0x5e, 0xc5, + 0xbd, 0x4c, 0xbd, 0x6c, 0x5f, 0xc5, 0xbd, 0x4c, 0xba, 0xef, 0xbf, 0x4c, + 0xc3, 0x87, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xbf, 0xae, 0x1a, 0x33, 0xe5, + 0xff, 0xbf, 0xff, 0xbf, 0x3f, 0x04, 0xc6, 0xff, 0x94, 0xef, 0xb3, 0xef, + 0xbf, 0x4c, 0xc3, 0x87, 0x96, 0xef, 0xff, 0xcd, 0xbd, 0x4c, 0xc3, 0x87, + 0x96, 0xef, 0xb5, 0xef, 0xbf, 0x4c, 0x99, 0xef, 0xbd, 0x6c, 0x5e, 0xc5, + 0xbd, 0x4c, 0xbd, 0x6c, 0x5f, 0xc5, 0xbd, 0x4c, 0xfd, 0xcd, 0xbf, 0x4c, + 0xff, 0xfb, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xbf, 0x3f, 0x04, 0xc6, 0xff, + 0xff, 0xbb, 0xff, 0xbf, 0xae, 0x1a, 0x33, 0xe5, 0x2f, 0xeb, 0x00, 0x1c, + 0x1e, 0x0d, 0x00, 0x1c, 0x52, 0x08, 0x00, 0x1c, 0x44, 0x06, 0x00, 0x1c, + 0x38, 0x09, 0x00, 0x1c, 0x08, 0x0d, 0x00, 0x1c, 0x86, 0x07, 0xff, 0xcf, + 0x6f, 0xeb, 0xff, 0xff, 0xbf, 0xc6, 0xfc, 0xf7, 0xff, 0x3f, 0xdf, 0xd3, + 0xbf, 0xc7, 0xfd, 0xf7, 0xc3, 0x87, 0x3d, 0xeb, 0xbc, 0x92, 0xba, 0x92, + 0x1f, 0x38, 0x7f, 0xd7, 0xfc, 0xf3, 0xfd, 0x93, 0xff, 0xdf, 0x1e, 0x38, + 0x7f, 0xd7, 0xfc, 0xf3, 0xb9, 0x93, 0xff, 0xde, 0xfe, 0xcd, 0x3c, 0x93, + 0xfc, 0x3b, 0xbb, 0x83, 0x6f, 0x8f, 0xef, 0x8f, 0x38, 0x93, 0xfc, 0x3b, + 0xbb, 0x83, 0xff, 0xdb, 0x3c, 0x93, 0x2e, 0x8f, 0xed, 0x92, 0xdf, 0xdb, + 0x6f, 0x8f, 0xef, 0x8f, 0xbf, 0xc5, 0xf6, 0xf3, 0xff, 0x3b, 0xdf, 0xb3, + 0x32, 0x9f, 0xb3, 0x9b, 0xfd, 0xf3, 0x39, 0x9f, 0x76, 0x9f, 0x06, 0xf0, + 0xf4, 0x93, 0xb0, 0x93, 0xfa, 0x3b, 0xda, 0xb3, 0xfa, 0xf3, 0xfd, 0x93, + 0xff, 0xdf, 0xb9, 0x93, 0xff, 0xde, 0x7d, 0xeb, 0xbf, 0xc6, 0xfc, 0xf7, + 0xff, 0x3f, 0xdf, 0xd3, 0xbf, 0xc7, 0xfd, 0xf7, 0xc3, 0x87, 0x3e, 0xeb, + 0xfe, 0xcd, 0x3c, 0x93, 0xfc, 0x3b, 0xbb, 0x83, 0x6f, 0x8f, 0xef, 0x8f, + 0x38, 0x93, 0xfc, 0x3b, 0xbb, 0x83, 0xff, 0xdb, 0x3c, 0x93, 0x2e, 0x8f, + 0xed, 0x92, 0xdf, 0xdb, 0x6f, 0x8f, 0xef, 0x8f, 0xbf, 0xc5, 0xf6, 0xf3, + 0xff, 0x3b, 0xdf, 0xb3, 0x32, 0x9f, 0xb3, 0x9b, 0xfd, 0xf3, 0x39, 0x9f, + 0x76, 0x9f, 0x06, 0xf0, 0xf4, 0x93, 0xb0, 0x93, 0x7e, 0xeb, 0xff, 0xff, + 0xbf, 0xc6, 0xfc, 0xf7, 0xff, 0x3f, 0xdf, 0xd3, 0xbf, 0xc7, 0xfd, 0xf7, + 0xc3, 0x87, 0x7c, 0x93, 0xfd, 0x3b, 0xbc, 0x83, 0xfe, 0xcd, 0x73, 0x8f, + 0xf3, 0x8f, 0xff, 0xcc, 0xff, 0x3b, 0xdf, 0xb3, 0x32, 0x9f, 0xb3, 0x9b, + 0xfd, 0xf3, 0x39, 0x9f, 0x76, 0x9f, 0x06, 0xf0, 0xf0, 0x93, 0xc3, 0x87, + 0xbc, 0x93, 0xff, 0x1b, 0xfc, 0xdf, 0xbf, 0xc7, 0xf7, 0xf3, 0xff, 0xcf, + 0xbf, 0x7e, 0xbf, 0xc5, 0xe9, 0xf3, 0xff, 0xde, 0xff, 0xdf, 0x04, 0xf8, + 0xbf, 0x6e, 0xf4, 0x97, 0xfb, 0xf3, 0xfc, 0xde, 0xfc, 0xdf, 0x04, 0xf8, + 0xfd, 0x3b, 0xfc, 0x8e, 0xf5, 0xf3, 0xff, 0xdf, 0xfd, 0x3b, 0x7c, 0x8f, + 0xf9, 0xf3, 0xff, 0xdf, 0xfd, 0x3b, 0xbc, 0x8f, 0xfd, 0xf3, 0xff, 0xdf, + 0xc3, 0x87, 0xff, 0xff, 0x8f, 0xb1, 0xff, 0xff, 0xd7, 0xb1, 0xff, 0xff, + 0x77, 0xb1, 0xff, 0xff, 0x77, 0xb1, 0xff, 0xff, 0x77, 0xb1, 0xff, 0xff, + 0x77, 0xb1, 0xff, 0xff, 0x77, 0xb1, 0xff, 0xff, 0x77, 0xb1, 0xff, 0xff, + 0x77, 0xb1, 0xff, 0xff, 0x77, 0xb1, 0xff, 0xff, 0x77, 0xb1, 0xff, 0xff, + 0x77, 0xb1, 0xff, 0xff, 0xc5, 0xb1, 0xff, 0xff, 0x77, 0xb1, 0xff, 0xff, + 0x77, 0xb1, 0xff, 0xff, 0x77, 0xb1, 0xff, 0xff, 0x83, 0xb1, 0xff, 0xff, + 0x77, 0xb1, 0xff, 0xff, 0xb3, 0xb1, 0xff, 0xff, 0x77, 0xb1, 0xff, 0xff, + 0x77, 0xb1, 0xff, 0xff, 0xa1, 0xb1, 0xff, 0xff, 0xcf, 0xce, 0xcd, 0xcc, + 0xcb, 0xca, 0xc9, 0xc8, 0xc7, 0xc6, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, + 0x75, 0xa2, 0xff, 0xff, 0x75, 0xa2, 0xff, 0xff, 0x39, 0xa4, 0xff, 0xff, + 0x75, 0xa2, 0xff, 0xff, 0xe7, 0xa3, 0xff, 0xff, 0x79, 0xa3, 0xff, 0xff, + 0x75, 0xa2, 0xff, 0xff, 0x23, 0xa3, 0xff, 0xff, 0x75, 0xa2, 0xff, 0xff, + 0xd7, 0xa2, 0xff, 0xff, 0x75, 0xa2, 0xff, 0xff, 0xa1, 0xa2, 0xff, 0xff, + 0x75, 0xa2, 0xff, 0xff, 0x93, 0xa2, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x8d, + 0x87, 0xdf, 0x96, 0x9b, 0xd2, 0xc1, 0xcf, 0x87, 0xda, 0xcf, 0xcb, 0x87, + 0xff, 0xff, 0xff, 0xff, 0xdf, 0x96, 0xc5, 0xdf, 0xda, 0x9b, 0xdf, 0x92, + 0xbe, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x8d, 0x87, 0xc5, 0xda, 0x9b, + 0xd3, 0xdf, 0x8b, 0x87, 0xc5, 0xda, 0x9b, 0xd3, 0xdf, 0x96, 0xc5, 0xda, + 0x9b, 0xd3, 0xdf, 0x93, 0x90, 0x8c, 0x8c, 0xc5, 0xda, 0x9b, 0xff, 0xff, + 0xf2, 0xf5, 0xdf, 0x8c, 0x8b, 0x9e, 0x8b, 0x9a, 0xc5, 0xda, 0x9b, 0xd3, + 0xdf, 0x8d, 0x9a, 0x9e, 0x8c, 0x90, 0x91, 0xc5, 0xdf, 0xda, 0x9b, 0xff, + 0xf2, 0xf5, 0xdf, 0x97, 0x9e, 0x93, 0xdf, 0x8b, 0x9e, 0x8c, 0x94, 0xdf, + 0x96, 0x9b, 0xdf, 0x96, 0x8c, 0xdf, 0xda, 0x9b, 0xff, 0xff, 0xff, 0xff, + 0xf2, 0xf5, 0xdf, 0x9c, 0x9e, 0x93, 0x96, 0xdf, 0x8d, 0x9a, 0x8c, 0xdf, + 0x96, 0x8c, 0xdf, 0xda, 0x9b, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x91, + 0x88, 0x94, 0xdf, 0x8c, 0x8b, 0x9e, 0x8b, 0x9a, 0xdf, 0x8b, 0x90, 0xdf, + 0xda, 0x9b, 0xff, 0xff, 0xf2, 0xf5, 0xff, 0xff, 0xdf, 0xda, 0xcf, 0xcd, + 0x87, 0xff, 0xff, 0xff, 0xdf, 0x9c, 0x97, 0x94, 0x8c, 0x8a, 0x92, 0xdf, + 0x9a, 0x8d, 0x8d, 0xd1, 0xd1, 0xd1, 0xff, 0xff, 0xdf, 0x9b, 0x92, 0xd2, + 0xc1, 0xda, 0x9b, 0xff, 0xf2, 0xf5, 0xdf, 0x97, 0x86, 0x8c, 0xd4, 0xff, + 0xf2, 0xf5, 0xdf, 0x97, 0x86, 0x8c, 0xd2, 0xff, 0xf2, 0xf5, 0xdf, 0x99, + 0x8d, 0x9a, 0x8e, 0xd4, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x8f, + 0x90, 0x93, 0x9a, 0xd4, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x8f, + 0x90, 0x93, 0x9a, 0xd2, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x9b, + 0x92, 0xc5, 0xdf, 0xda, 0x9b, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x8f, + 0x9e, 0x9c, 0x94, 0x9a, 0x8b, 0xdf, 0x8b, 0x96, 0x92, 0x9a, 0x90, 0x8a, + 0x8b, 0xd1, 0xd1, 0xd1, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf5, 0xdf, 0x8d, + 0x8f, 0x8f, 0xdf, 0x8b, 0x96, 0x92, 0x9a, 0x90, 0x8a, 0x8b, 0xff, 0xff, + 0xf2, 0xf5, 0xdf, 0x91, 0x88, 0x94, 0xdf, 0x8b, 0x9e, 0x8c, 0x94, 0xdf, + 0x96, 0x9b, 0xdf, 0x96, 0x8c, 0xdf, 0xda, 0x9b, 0xff, 0xff, 0xff, 0xff, + 0xf2, 0xf5, 0xdf, 0x8f, 0x97, 0x86, 0xdf, 0x8b, 0x9e, 0x8c, 0x94, 0xdf, + 0x96, 0x9b, 0xdf, 0x96, 0x8c, 0xdf, 0xda, 0x9b, 0xff, 0xff, 0xff, 0xff, + 0xf2, 0xf5, 0xdf, 0x98, 0x9a, 0x8b, 0xdf, 0x9e, 0x9c, 0xff, 0xff, 0xff, + 0xf2, 0xf5, 0xdf, 0x96, 0x8d, 0x8e, 0xd2, 0xc1, 0x90, 0x9c, 0x8f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -1198,1534 +1096,1635 @@ u8 fw_data_tx[13304] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xb1, 0xaa, 0xe9, 0xe6, 0xdf, 0xb5, 0xcd, 0xea + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xb1, 0xaa, 0xe9, 0xe6, 0xab, 0xa7, 0xd2, 0xb0 }; -u8 fw_data_rx[18424] = { - 0xff, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, - 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, - 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, - 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, - 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, - 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, - 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, - 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, - 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, - 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, - 0x97, 0xfa, 0xff, 0xff, 0x97, 0xfa, 0xff, 0xff, 0xff, 0xb9, 0xff, 0xff, - 0x67, 0xc1, 0xff, 0xff, 0x8b, 0xb9, 0xff, 0xff, 0x7b, 0xb9, 0xff, 0xff, - 0x73, 0xb9, 0xff, 0xff, 0xf3, 0xc6, 0xff, 0xff, 0x67, 0xc0, 0xff, 0xff, - 0x6b, 0xb9, 0xff, 0xff, 0x63, 0xb9, 0xff, 0xff, 0x4f, 0xb9, 0xff, 0xff, - 0x3b, 0xb9, 0xff, 0xff, 0x33, 0xb9, 0xff, 0xff, 0x2b, 0xb9, 0xff, 0xff, - 0xeb, 0xc6, 0xff, 0xff, 0x83, 0xb9, 0xff, 0xff, 0x23, 0xb9, 0xff, 0xff, - 0x1b, 0xb9, 0xff, 0xff, 0x13, 0xb9, 0xff, 0xff, 0x0b, 0xb9, 0xff, 0xff, - 0x03, 0xb9, 0xff, 0xff, 0xef, 0xb8, 0xff, 0xff, 0xe7, 0xb8, 0xff, 0xff, - 0xdf, 0xb8, 0xff, 0xff, 0xd7, 0xb8, 0xff, 0xff, 0xcf, 0xb8, 0xff, 0xff, - 0xc7, 0xb8, 0xff, 0xff, 0xc7, 0xb8, 0xff, 0xff, 0xc7, 0xb8, 0xff, 0xff, - 0xc7, 0xb8, 0xff, 0xff, 0xc7, 0xb8, 0xff, 0xff, 0xc7, 0xb8, 0xff, 0xff, - 0xc7, 0xb8, 0xff, 0xff, 0x8d, 0xef, 0xfc, 0x3f, 0xdf, 0x9b, 0xad, 0xef, - 0xfd, 0x3f, 0xde, 0x9b, 0xce, 0xef, 0x78, 0x90, 0x0e, 0xef, 0x2d, 0xef, - 0x4d, 0xef, 0x63, 0x9a, 0xf8, 0xf7, 0x7f, 0x6a, 0x7f, 0x48, 0xfc, 0xda, - 0xfc, 0xd8, 0x63, 0x9a, 0x04, 0xf0, 0x90, 0xef, 0xb0, 0xef, 0x71, 0x9f, - 0xbd, 0xb5, 0xbf, 0xc5, 0xf8, 0xf3, 0xff, 0xce, 0xdf, 0x4c, 0xfc, 0xdc, - 0xff, 0xd5, 0xbf, 0xc5, 0x03, 0xf4, 0xff, 0x1f, 0xe6, 0xff, 0xff, 0x1f, - 0x5a, 0xe7, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0x7f, 0xff, 0xfb, 0xff, 0xff, - 0x07, 0xfd, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xdf, 0xd7, 0xff, 0xff, 0xdf, - 0xaf, 0xb4, 0xff, 0xff, 0xd7, 0xff, 0xff, 0xdf, 0x3f, 0xfe, 0xff, 0xdf, - 0xff, 0x1f, 0xd5, 0xdf, 0xff, 0x3f, 0xdf, 0xbf, 0x2b, 0xeb, 0xcc, 0xe9, - 0x8d, 0xed, 0xff, 0xce, 0xda, 0x4c, 0xd9, 0x4c, 0x5f, 0xcd, 0xbe, 0xbd, - 0xfc, 0xe7, 0xff, 0x1f, 0x00, 0xff, 0xdf, 0xca, 0x72, 0xed, 0xfe, 0xc9, - 0xff, 0xcf, 0xff, 0x1f, 0x3a, 0xe7, 0xe7, 0x97, 0xff, 0x8b, 0x9a, 0x6b, - 0x9f, 0x3b, 0xdf, 0xf7, 0xfa, 0x4b, 0xff, 0xcf, 0xff, 0x1f, 0x43, 0xe7, - 0xe7, 0x97, 0xff, 0x8b, 0x99, 0x6b, 0x9f, 0x3b, 0xdf, 0xf7, 0xf9, 0x4b, - 0xff, 0xd2, 0xab, 0x8a, 0xbf, 0xc2, 0x14, 0xf4, 0xfc, 0xe4, 0xbe, 0xed, - 0x3a, 0x6d, 0x3f, 0x4c, 0xb9, 0x6d, 0xbe, 0x4c, 0x00, 0xee, 0x1d, 0x4c, - 0xc0, 0xee, 0xdc, 0x4c, 0x7f, 0xcd, 0xa7, 0xbd, 0xbb, 0x4c, 0x7f, 0xc9, - 0x30, 0x4c, 0xf0, 0x92, 0xfc, 0x1b, 0x00, 0xff, 0xd7, 0x6c, 0xb2, 0x6c, - 0x7a, 0x93, 0xdd, 0x6c, 0x7a, 0x93, 0xdf, 0x6c, 0x7a, 0x93, 0xdd, 0x3b, - 0xfd, 0xb6, 0xaf, 0x4c, 0xfc, 0xdc, 0xf1, 0x9b, 0x0b, 0xf4, 0x0a, 0xee, - 0xca, 0xee, 0xe9, 0xee, 0xa9, 0xee, 0x48, 0xee, 0xff, 0xcc, 0x1f, 0x47, - 0xec, 0xc4, 0xf5, 0xf7, 0xbe, 0x3b, 0xb8, 0xdf, 0xbf, 0x3b, 0xd9, 0xdf, - 0x27, 0x92, 0x1e, 0x47, 0x2d, 0xee, 0x3d, 0x47, 0xd8, 0xfb, 0xd8, 0xc8, - 0x23, 0x9b, 0xf7, 0xf3, 0xbf, 0x3b, 0xb9, 0xdb, 0x7a, 0x92, 0x3e, 0x47, - 0x31, 0xee, 0x3d, 0x47, 0xe2, 0xfb, 0xc4, 0xc8, 0x23, 0x9b, 0xf2, 0xf3, - 0xfe, 0x3b, 0xd9, 0xdb, 0x77, 0x96, 0x3e, 0x47, 0xfe, 0x3b, 0xd9, 0xdf, - 0x1e, 0x67, 0x27, 0x92, 0x1e, 0x47, 0x37, 0xee, 0x3d, 0x47, 0xf1, 0xfb, - 0xb0, 0xc9, 0x27, 0x9b, 0xf7, 0xf3, 0xbf, 0x3b, 0xb9, 0xdb, 0x7a, 0x92, - 0x3e, 0x47, 0x1b, 0xee, 0x1d, 0x47, 0xfb, 0xfb, 0xff, 0xc9, 0x3d, 0x47, - 0x3e, 0x47, 0x3f, 0x6b, 0x1f, 0x67, 0x07, 0xa0, 0x5a, 0x3b, 0xf9, 0xb6, - 0x27, 0xa0, 0x1e, 0x67, 0x23, 0xa1, 0x1d, 0x67, 0x23, 0xa1, 0xff, 0xdc, - 0x33, 0x8b, 0xfc, 0xdb, 0xaf, 0xc8, 0x31, 0x9a, 0xf6, 0xf3, 0x3d, 0x38, - 0xf8, 0xb6, 0x68, 0x93, 0xdf, 0x47, 0xbc, 0x93, 0xe0, 0x93, 0xa4, 0x92, - 0x47, 0xf8, 0x95, 0xef, 0xbf, 0x6c, 0x37, 0xa1, 0x3f, 0x4c, 0xbe, 0x6c, - 0xb7, 0xa2, 0xbe, 0x4c, 0xbd, 0x6c, 0x57, 0xa2, 0x5d, 0x4c, 0xbc, 0x6c, - 0xf7, 0xa7, 0xfc, 0x4c, 0xbb, 0x6c, 0xd7, 0xa6, 0xdb, 0x4c, 0xec, 0xe9, - 0x6b, 0xeb, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xdf, 0x3e, 0x2b, 0x91, 0x06, - 0xa7, 0x48, 0xd5, 0x1c, 0x0f, 0x1e, 0x2d, 0x3c, 0x89, 0xab, 0xcd, 0xef, - 0x01, 0x23, 0x45, 0x67, 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, - 0x66, 0x86, 0x7d, 0xa5, 0x5e, 0x14, 0x26, 0x91, 0x23, 0x43, 0xe4, 0x70, - 0x29, 0x3e, 0x9d, 0x35, 0x97, 0xef, 0xbf, 0x6c, 0xbf, 0x4f, 0xbe, 0x6c, - 0xbe, 0x4f, 0xbd, 0x6c, 0xbd, 0x4f, 0xbc, 0x6c, 0xbc, 0x4f, 0xbb, 0x6c, - 0xbb, 0x4f, 0xba, 0x6c, 0xba, 0x4f, 0x99, 0x6c, 0x99, 0x4f, 0xc3, 0x87, - 0xf3, 0xff, 0xff, 0xdf, 0xbf, 0xc6, 0xfc, 0xf7, 0xff, 0x3f, 0xdf, 0xd3, - 0xbf, 0xc7, 0xfd, 0xf7, 0xc3, 0x87, 0x3d, 0xeb, 0xbc, 0x92, 0xba, 0x92, - 0x1f, 0x38, 0x7f, 0xd7, 0xfc, 0xf3, 0xfd, 0x93, 0xff, 0xdf, 0x1e, 0x38, - 0x7f, 0xd7, 0xfc, 0xf3, 0xb9, 0x93, 0xff, 0xde, 0xfe, 0xcd, 0x3c, 0x93, - 0xfc, 0x3b, 0xbb, 0x83, 0x6f, 0x8f, 0xef, 0x8f, 0x38, 0x93, 0xfc, 0x3b, - 0xbb, 0x83, 0xff, 0xdb, 0x3c, 0x93, 0x2e, 0x8f, 0xed, 0x92, 0xdf, 0xdb, - 0x6f, 0x8f, 0xef, 0x8f, 0xbf, 0xc5, 0xf6, 0xf3, 0xff, 0x3b, 0xdf, 0xb3, - 0x32, 0x9f, 0xb3, 0x9b, 0xfd, 0xf3, 0x39, 0x9f, 0x76, 0x9f, 0x06, 0xf0, - 0xf4, 0x93, 0xb0, 0x93, 0xfa, 0x3b, 0xda, 0xb3, 0xfa, 0xf3, 0xfd, 0x93, - 0xff, 0xdf, 0xb9, 0x93, 0xff, 0xde, 0x7d, 0xeb, 0xbf, 0xc5, 0xda, 0xf3, - 0xbc, 0x90, 0x7f, 0x1a, 0xfc, 0xdf, 0xb3, 0x14, 0xff, 0xff, 0xdf, 0xf3, - 0xd2, 0x23, 0xff, 0xff, 0xff, 0xd5, 0xbf, 0xc5, 0xe5, 0xf3, 0x52, 0x1a, - 0xff, 0xff, 0x72, 0x1a, 0xfc, 0xdf, 0xb3, 0x14, 0xff, 0xff, 0xeb, 0xf3, - 0xd2, 0x23, 0xff, 0xff, 0xff, 0xd5, 0xbf, 0xc5, 0xf1, 0xf3, 0x52, 0x1a, - 0xff, 0xff, 0x72, 0x1a, 0xfc, 0xdf, 0xb3, 0x14, 0xff, 0xff, 0xf7, 0xf3, - 0xd2, 0x23, 0xff, 0xff, 0xff, 0xd5, 0x52, 0x1a, 0xff, 0xff, 0xfd, 0xfb, - 0xc3, 0x87, 0x97, 0xbe, 0xb3, 0x93, 0x8f, 0xbe, 0xb3, 0x93, 0xd0, 0xc5, - 0xf1, 0xf7, 0xd2, 0x23, 0xff, 0xdf, 0xd2, 0x23, 0xfe, 0xdf, 0xd2, 0x23, - 0xfd, 0xdf, 0xd2, 0x23, 0xfc, 0xdf, 0xf0, 0xd5, 0x52, 0x1a, 0xf0, 0xff, - 0xd0, 0xc5, 0x0b, 0xf0, 0xdc, 0xc5, 0xf7, 0xf7, 0xfc, 0xd5, 0xd2, 0x23, - 0xff, 0xdf, 0x52, 0x1a, 0xfc, 0xff, 0xdc, 0xc5, 0x05, 0xf0, 0xbf, 0xc5, - 0x1d, 0xf0, 0xff, 0xd5, 0xd2, 0x23, 0xff, 0xff, 0xbf, 0xc5, 0x22, 0xf0, - 0xff, 0xd5, 0xd2, 0x23, 0xfe, 0xff, 0xbf, 0xc5, 0x27, 0xf0, 0xd2, 0x23, - 0xfd, 0xff, 0xc3, 0x87, 0x3d, 0xeb, 0x77, 0x8b, 0xbf, 0xc5, 0xf3, 0xf3, +u8 fw_data_rx[18426] = { + 0x0b, 0xfa, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, + 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, + 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, + 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, + 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, + 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, + 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, + 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, + 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, + 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, + 0xa3, 0xf9, 0xff, 0xff, 0xa3, 0xf9, 0xff, 0xff, 0xfb, 0xbe, 0xff, 0xff, + 0x57, 0xc6, 0xff, 0xff, 0x8b, 0xcb, 0xff, 0xff, 0x8b, 0xbe, 0xff, 0xff, + 0x83, 0xbe, 0xff, 0xff, 0x93, 0xcb, 0xff, 0xff, 0x7f, 0xc5, 0xff, 0xff, + 0x7b, 0xbe, 0xff, 0xff, 0x73, 0xbe, 0xff, 0xff, 0x5f, 0xbe, 0xff, 0xff, + 0x4b, 0xbe, 0xff, 0xff, 0x43, 0xbe, 0xff, 0xff, 0x3b, 0xbe, 0xff, 0xff, + 0x9b, 0xbe, 0xff, 0xff, 0x93, 0xbe, 0xff, 0xff, 0x33, 0xbe, 0xff, 0xff, + 0x2b, 0xbe, 0xff, 0xff, 0x23, 0xbe, 0xff, 0xff, 0x1b, 0xbe, 0xff, 0xff, + 0x13, 0xbe, 0xff, 0xff, 0xff, 0xbd, 0xff, 0xff, 0xf7, 0xbd, 0xff, 0xff, + 0xef, 0xbd, 0xff, 0xff, 0xe7, 0xbd, 0xff, 0xff, 0xdf, 0xbd, 0xff, 0xff, + 0xd7, 0xbd, 0xff, 0xff, 0xd7, 0xbd, 0xff, 0xff, 0xd7, 0xbd, 0xff, 0xff, + 0xd7, 0xbd, 0xff, 0xff, 0xd7, 0xbd, 0xff, 0xff, 0xd7, 0xbd, 0xff, 0xff, + 0xd7, 0xbd, 0xff, 0xff, 0x3d, 0xeb, 0x77, 0x8b, 0xbf, 0xc5, 0xf3, 0xf3, 0x5c, 0xa5, 0xab, 0x8a, 0xff, 0xda, 0xff, 0xcc, 0xb3, 0xa6, 0x73, 0xa7, - 0xff, 0xdc, 0x7f, 0x7b, 0xb1, 0x9a, 0x7f, 0x5d, 0x05, 0xf4, 0x7d, 0xeb, - 0xb7, 0xef, 0x9d, 0x1b, 0xf4, 0xff, 0xdc, 0x1b, 0xf0, 0xff, 0xf1, 0xa5, - 0x9e, 0x4f, 0xff, 0x4c, 0xfe, 0x4e, 0x9f, 0x4e, 0xde, 0x4c, 0xfd, 0xcc, - 0xde, 0x4d, 0x9f, 0x5d, 0xc3, 0x87, 0xff, 0xff, 0xd7, 0xff, 0xff, 0xdf, - 0xff, 0x8b, 0xef, 0xc7, 0xf0, 0xf7, 0x96, 0xef, 0xbf, 0x7c, 0xbf, 0xc5, - 0xf4, 0xf3, 0xfd, 0x6c, 0xde, 0x6f, 0xdd, 0x4c, 0xbe, 0x6f, 0xdf, 0x6f, - 0xdf, 0x4d, 0xbf, 0x7c, 0xff, 0xd5, 0xbf, 0x5c, 0xc3, 0x87, 0xff, 0xcf, - 0xc3, 0x87, 0xff, 0xff, 0xd7, 0xff, 0xff, 0xdf, 0x93, 0xef, 0xbc, 0x1b, - 0xf4, 0xff, 0x7f, 0x9b, 0xed, 0xf3, 0xbc, 0x1b, 0xd4, 0xff, 0xf7, 0x9b, - 0xf1, 0xf3, 0xff, 0xcd, 0xbf, 0x5f, 0xbe, 0x5f, 0xbe, 0x6c, 0xbf, 0x4f, - 0xde, 0x6d, 0xbe, 0x6c, 0xde, 0x4f, 0xfe, 0x4d, 0xbf, 0x7c, 0xff, 0xdd, - 0xfe, 0x4c, 0xbf, 0x5c, 0xc3, 0x87, 0xff, 0xff, 0xd7, 0xff, 0xff, 0xdf, - 0x77, 0x8b, 0xbf, 0xc5, 0xbb, 0x8b, 0xf6, 0xf3, 0xff, 0xd5, 0x9d, 0xa7, - 0x77, 0x8b, 0x97, 0xa4, 0xdf, 0x5f, 0xff, 0xdf, 0x3d, 0x9b, 0x02, 0xf4, - 0xc3, 0x87, 0xff, 0xff, 0x9f, 0x6f, 0x73, 0x9b, 0xfa, 0xf3, 0x3b, 0x9b, - 0xfd, 0xf7, 0xdf, 0x4f, 0xc3, 0x87, 0xbf, 0x4f, 0xc3, 0x87, 0xff, 0xff, - 0xff, 0xcd, 0x9d, 0xef, 0xbf, 0x5c, 0xc3, 0x87, 0xab, 0xff, 0xff, 0xdf, - 0x2e, 0xeb, 0xfc, 0x92, 0xff, 0x1f, 0xc7, 0xea, 0xbf, 0xc7, 0xeb, 0xf7, - 0x9f, 0x73, 0xbd, 0xc4, 0xe1, 0xf3, 0xb9, 0xc4, 0xdf, 0xf3, 0xbe, 0xc4, - 0xfd, 0xf3, 0x6e, 0xeb, 0xba, 0xee, 0xdf, 0x7d, 0x9a, 0xee, 0xfc, 0xbe, - 0xff, 0xa4, 0xfe, 0x7f, 0xbf, 0xc7, 0xdd, 0xf3, 0xff, 0x1f, 0x6b, 0xf4, - 0x6e, 0xeb, 0x9f, 0xee, 0x9f, 0x7c, 0xbf, 0xee, 0x9c, 0xbc, 0x93, 0xa5, - 0xff, 0x7c, 0xde, 0x6c, 0xf7, 0xcd, 0xff, 0x1f, 0xe6, 0xf5, 0x9f, 0x73, - 0xbd, 0xc4, 0x1b, 0xf4, 0xff, 0xcf, 0xff, 0x1f, 0x0a, 0xeb, 0x6e, 0xeb, - 0x88, 0xef, 0x9f, 0x7c, 0x9c, 0xbc, 0xa8, 0xef, 0x93, 0xa5, 0x9f, 0x7c, - 0xbd, 0xc4, 0x7e, 0x6b, 0xef, 0xf3, 0xec, 0x93, 0x00, 0x1c, 0x6b, 0x00, - 0x6e, 0xeb, 0xff, 0xde, 0xbb, 0x8b, 0xdf, 0x5d, 0xdc, 0xbe, 0x9b, 0xa4, - 0xff, 0x7c, 0xde, 0x6c, 0xf7, 0xcd, 0xff, 0x1f, 0x04, 0xf6, 0x6e, 0xeb, - 0x9e, 0x7b, 0xbf, 0xc4, 0xfb, 0xf7, 0x9f, 0x7b, 0xbe, 0xc4, 0xf7, 0xf3, - 0xfc, 0xcf, 0xff, 0x1f, 0xda, 0xe5, 0xfb, 0xcf, 0xff, 0x1f, 0x2f, 0xeb, - 0x1a, 0xf8, 0xbc, 0x7b, 0x00, 0xcc, 0x35, 0x9b, 0x09, 0xf4, 0xfc, 0xcf, - 0xff, 0x1f, 0x37, 0xeb, 0x22, 0xf8, 0xff, 0xff, 0xab, 0xff, 0xff, 0xdf, - 0x1f, 0xb7, 0xff, 0xff, 0x98, 0xef, 0xff, 0xcd, 0xbf, 0x5c, 0xbe, 0x5c, - 0xff, 0xcd, 0xbe, 0x54, 0x9a, 0xef, 0xdf, 0xcd, 0xbf, 0x5c, 0xfe, 0xcd, - 0xbe, 0x5c, 0xeb, 0xcd, 0xbd, 0x5c, 0xc3, 0x87, 0xa9, 0xff, 0xff, 0xdf, - 0xff, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xfe, 0x74, 0xc3, 0x87, 0xff, 0xff, - 0xa9, 0xff, 0xff, 0xdf, 0x2c, 0xeb, 0xfc, 0x92, 0xff, 0x1f, 0x3b, 0xeb, - 0xbf, 0xc7, 0xed, 0xf7, 0x9f, 0x73, 0xbd, 0xc4, 0xe5, 0xf3, 0xb9, 0xc4, - 0xe3, 0xf3, 0xbe, 0xc4, 0xfd, 0xf3, 0x6c, 0xeb, 0x87, 0xed, 0x9f, 0x7c, - 0xa7, 0xed, 0x9c, 0xbc, 0x93, 0xa5, 0xfe, 0x7c, 0xff, 0x1f, 0xdd, 0xf4, - 0x6c, 0xeb, 0x8b, 0xed, 0xff, 0xcd, 0xbf, 0x5c, 0xfc, 0xcf, 0xcb, 0xed, - 0xfb, 0xcd, 0xff, 0x1f, 0x56, 0xf6, 0x9f, 0x73, 0xbd, 0xc4, 0x17, 0xf4, - 0xff, 0xcf, 0xff, 0x1f, 0x7a, 0xeb, 0x6c, 0xeb, 0x7e, 0x6b, 0x9e, 0x7b, - 0xbf, 0xc4, 0xe8, 0xf3, 0xfd, 0xc4, 0xee, 0xf7, 0x96, 0xed, 0xbe, 0x7c, - 0xff, 0xdd, 0x77, 0x8b, 0xbc, 0xc5, 0xbe, 0x5c, 0xb1, 0xf3, 0x9f, 0x7c, - 0x9c, 0xbc, 0xb9, 0xed, 0x93, 0xa5, 0xff, 0x7c, 0xde, 0x6c, 0xfb, 0xcd, - 0xff, 0x1f, 0x73, 0xf6, 0xec, 0x93, 0x00, 0x1c, 0xe8, 0x00, 0x6c, 0xeb, - 0x40, 0xee, 0x9e, 0x5a, 0x9f, 0x7b, 0xbe, 0xc4, 0xb9, 0xa3, 0xdf, 0xf3, - 0x9f, 0x7a, 0xbc, 0xbc, 0x23, 0xee, 0xb7, 0xa1, 0xbf, 0x7d, 0xff, 0xdc, - 0x33, 0x8b, 0xba, 0xc5, 0x9f, 0x5a, 0xf6, 0xf3, 0x9c, 0xbc, 0x33, 0xa1, - 0xff, 0x79, 0xde, 0x69, 0xfb, 0xcd, 0xff, 0x1f, 0x8e, 0xf6, 0x1a, 0xf8, - 0x95, 0xa3, 0xbd, 0x7c, 0xb7, 0xbd, 0x9c, 0x7c, 0x37, 0x93, 0x9e, 0x52, - 0xef, 0xcf, 0xd9, 0xa2, 0xff, 0xcd, 0xff, 0x1f, 0xe2, 0xf4, 0x9f, 0x7a, - 0x13, 0xf8, 0x9e, 0x7d, 0xfe, 0xdc, 0x33, 0x8b, 0xfe, 0xc4, 0xdf, 0xf3, - 0xbf, 0x7a, 0x94, 0xee, 0xdc, 0xbd, 0xdb, 0xa4, 0xff, 0x7e, 0x24, 0xa7, - 0x67, 0x8a, 0xfe, 0xc1, 0xd2, 0xf3, 0xff, 0xdd, 0x77, 0x8b, 0xbf, 0x5a, - 0xbc, 0xbd, 0x97, 0xa4, 0xde, 0x6c, 0xbf, 0xc6, 0xce, 0xf3, 0xff, 0x7c, - 0xfb, 0xcd, 0xff, 0x1f, 0xb6, 0xf6, 0x42, 0xf8, 0xbf, 0x7c, 0xff, 0xdd, - 0x77, 0x8b, 0xff, 0xce, 0xbf, 0x5c, 0xde, 0x5c, 0xbc, 0xbd, 0x82, 0xef, - 0x51, 0xf8, 0x9f, 0x7a, 0x24, 0xef, 0xbc, 0xbc, 0xb7, 0xa1, 0xbf, 0x7d, - 0xb8, 0xc5, 0xdb, 0xf3, 0xbc, 0xc5, 0xd7, 0xf3, 0xff, 0xdc, 0x33, 0x8b, - 0x9f, 0x5a, 0x9c, 0xbc, 0x33, 0xa1, 0xde, 0x69, 0xbf, 0xc6, 0xed, 0xf3, - 0xff, 0x79, 0xfb, 0xcd, 0xff, 0x1f, 0xd5, 0xf6, 0x61, 0xf8, 0x8c, 0xef, - 0xbd, 0x7c, 0xf5, 0xca, 0x6b, 0x9b, 0xf3, 0xf7, 0xfe, 0xd5, 0xbd, 0x5c, - 0xde, 0x6e, 0xfb, 0xcd, 0xff, 0x1f, 0xe1, 0xf6, 0x6d, 0xf8, 0xfb, 0xcf, - 0xff, 0x1f, 0x03, 0xec, 0x71, 0xf8, 0xf9, 0xcf, 0xff, 0x1f, 0xb1, 0xec, - 0x75, 0xf8, 0xb6, 0xef, 0xfb, 0xce, 0xde, 0x5d, 0xeb, 0xce, 0xdd, 0x5d, - 0x25, 0xf8, 0xfc, 0xcf, 0xff, 0x1f, 0xbf, 0xe6, 0x9f, 0x7a, 0x2a, 0xf8, - 0xa9, 0xff, 0xff, 0xdf, 0xf3, 0xb6, 0xff, 0xff, 0xf7, 0xb6, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xfd, 0x7c, 0xfe, 0xb7, 0xc3, 0x87, - 0xff, 0xff, 0xff, 0xdf, 0xc3, 0x87, 0xff, 0xff, 0x2e, 0xeb, 0xfc, 0x92, - 0xff, 0x1f, 0x09, 0xec, 0xbf, 0xc7, 0xf0, 0xf7, 0x9f, 0x73, 0xbe, 0xc4, - 0xf7, 0xf3, 0xbd, 0xc4, 0xfd, 0xf3, 0x6e, 0xeb, 0xff, 0xcf, 0xff, 0x1f, - 0x32, 0xec, 0x6e, 0xeb, 0xfd, 0xcf, 0xff, 0x1f, 0x36, 0xec, 0x6e, 0xeb, - 0xff, 0xcf, 0xff, 0xce, 0xf7, 0xcd, 0xff, 0x1f, 0x1e, 0xf7, 0x12, 0xf8, - 0x2f, 0xeb, 0xfe, 0xcf, 0xff, 0x1f, 0x41, 0xec, 0xfd, 0xef, 0xff, 0x1f, - 0x8a, 0xeb, 0x6f, 0xeb, 0xa5, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0xfe, 0xce, - 0xbc, 0xef, 0xfb, 0xef, 0xff, 0x1f, 0xc7, 0xeb, 0x6f, 0xeb, 0xff, 0xff, - 0x43, 0xf4, 0xff, 0xff, 0xa5, 0xff, 0xff, 0xdf, 0x2e, 0xeb, 0xfc, 0x92, - 0xff, 0x1f, 0x39, 0xec, 0xbe, 0xc7, 0xe4, 0xf3, 0x9f, 0x73, 0xbe, 0xc4, - 0xfd, 0xf3, 0x6e, 0xeb, 0xff, 0x1f, 0xfd, 0xfb, 0xbf, 0xc7, 0xf1, 0xf7, - 0xf5, 0xcf, 0xff, 0xce, 0xf0, 0xcd, 0xff, 0x1f, 0x48, 0xf7, 0x8b, 0xef, - 0xbe, 0x7c, 0xff, 0xdd, 0xbe, 0x5c, 0xfc, 0xcf, 0xff, 0x1f, 0x1d, 0xf5, - 0x6e, 0xeb, 0xff, 0x1f, 0x0c, 0xed, 0xb4, 0xc7, 0x0f, 0xf4, 0x0b, 0xf8, - 0xff, 0x1f, 0x65, 0xec, 0xba, 0xc7, 0xef, 0xf3, 0xf2, 0xcf, 0xff, 0xce, - 0xf0, 0xcd, 0xff, 0x1f, 0x5e, 0xf7, 0xff, 0xcd, 0x97, 0xef, 0xbe, 0x5c, - 0xff, 0x1f, 0x1f, 0xfc, 0xbf, 0xc7, 0x28, 0xf0, 0xff, 0x1f, 0x0d, 0xea, - 0x2b, 0xf8, 0x9b, 0xef, 0xff, 0x7c, 0xfd, 0xce, 0xff, 0xcd, 0xff, 0x1f, - 0xaa, 0xeb, 0x32, 0xf8, 0xa5, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0x8e, 0xee, + 0x7f, 0x7b, 0x7f, 0x5d, 0xff, 0xdc, 0xb1, 0x9a, 0x05, 0xf4, 0x7d, 0xeb, + 0x3c, 0xeb, 0xb2, 0xee, 0x9d, 0x1b, 0xc0, 0xff, 0xd1, 0xa4, 0xde, 0x4c, + 0xdd, 0x4c, 0xff, 0xce, 0xdf, 0x5c, 0x37, 0x9b, 0xe9, 0xf7, 0x34, 0x93, + 0x5d, 0x1b, 0xc0, 0xff, 0xff, 0xce, 0xf8, 0xee, 0xef, 0xcb, 0x9f, 0x4c, + 0x9e, 0x4c, 0xbe, 0x6f, 0x3e, 0x6d, 0x3e, 0x4c, 0xbf, 0x4c, 0x9e, 0x4d, + 0x9e, 0x4f, 0xff, 0xde, 0xbb, 0x8b, 0x8f, 0xa4, 0xb1, 0x9a, 0x0b, 0xf4, + 0x80, 0xef, 0xdf, 0x5c, 0x7c, 0xeb, 0xff, 0xff, 0xff, 0x8b, 0xef, 0xc7, + 0xed, 0xf7, 0x83, 0xef, 0x9f, 0x7c, 0xbf, 0xc4, 0xf3, 0xf3, 0x85, 0xef, + 0xfd, 0x6c, 0xde, 0x6f, 0xdd, 0x4c, 0xbe, 0x6f, 0xdf, 0x6f, 0xdf, 0x4d, + 0xbf, 0x7c, 0xff, 0xd5, 0xbf, 0x5c, 0xfb, 0xfb, 0xff, 0xcf, 0xfd, 0xfb, + 0xff, 0xcf, 0xc3, 0x87, 0xff, 0xcc, 0x9f, 0x5f, 0xbd, 0xa7, 0x9f, 0x5d, + 0xb9, 0xa7, 0x9f, 0x5d, 0x9e, 0x5d, 0x90, 0xef, 0xbe, 0x6c, 0xbe, 0x6d, + 0xbe, 0x4f, 0xbe, 0x6c, 0xbf, 0x4f, 0xbe, 0x6c, 0xfe, 0x4d, 0xfe, 0x4c, + 0xbf, 0x7c, 0xff, 0xdd, 0xbf, 0x5c, 0xc3, 0x87, 0xbb, 0x8b, 0x77, 0x8b, + 0xbf, 0xc5, 0xf5, 0xf3, 0x3c, 0x93, 0xff, 0xdf, 0xff, 0xd5, 0x77, 0x8b, + 0xf7, 0xa7, 0xdf, 0x5c, 0xff, 0xdc, 0xf1, 0x9b, 0x02, 0xf4, 0xc3, 0x87, + 0xdf, 0xff, 0xff, 0xdf, 0x9f, 0xff, 0xff, 0xdf, 0xc3, 0x87, 0xff, 0xff, + 0x9f, 0x6f, 0x73, 0x9b, 0xfc, 0xf7, 0xbf, 0x4f, 0xfb, 0xfb, 0x3b, 0x9b, + 0xfd, 0xf7, 0xdf, 0x4f, 0xc3, 0x87, 0xff, 0xff, 0x8d, 0xef, 0xfc, 0x3f, + 0xdf, 0x9b, 0xad, 0xef, 0xfd, 0x3f, 0xde, 0x9b, 0xce, 0xef, 0x78, 0x90, + 0x0e, 0xef, 0x2d, 0xef, 0x4d, 0xef, 0x63, 0x9a, 0xf8, 0xf7, 0x7f, 0x6a, + 0x7f, 0x48, 0xfc, 0xda, 0xfc, 0xd8, 0x63, 0x9a, 0x04, 0xf0, 0x90, 0xef, + 0xb0, 0xef, 0x71, 0x9f, 0xbd, 0xb5, 0xbf, 0xc5, 0xf8, 0xf3, 0xff, 0xce, + 0xdf, 0x4c, 0xfc, 0xdc, 0xff, 0xd5, 0xbf, 0xc5, 0x03, 0xf4, 0xff, 0x1f, + 0xa2, 0xe0, 0xff, 0x1f, 0x3e, 0xea, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0x7f, + 0xff, 0xfb, 0xff, 0xff, 0x07, 0xfd, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xdf, + 0xdf, 0xff, 0xff, 0xdf, 0x8f, 0xb5, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xdf, + 0x2b, 0xfe, 0xff, 0xdf, 0xff, 0x1f, 0xcd, 0xe2, 0xff, 0x3f, 0xdf, 0xbf, + 0xff, 0xcd, 0x9d, 0xef, 0xbf, 0x5c, 0xc3, 0x87, 0x93, 0xff, 0xff, 0xdf, + 0x2e, 0xeb, 0xfc, 0x92, 0xff, 0x1f, 0xfd, 0xeb, 0xbf, 0xc7, 0xf4, 0xf3, + 0x98, 0xee, 0x9f, 0x7c, 0x9c, 0xbc, 0xb8, 0xee, 0x93, 0xa5, 0xff, 0x7c, + 0xde, 0x6c, 0xf7, 0xcd, 0xff, 0x1f, 0xb1, 0xf6, 0x9f, 0x73, 0xbd, 0xc4, + 0xc1, 0xf3, 0xb9, 0xc4, 0xe4, 0xf3, 0xbe, 0xc4, 0xc2, 0xf7, 0x80, 0xef, + 0x9f, 0x7c, 0xbc, 0xbc, 0xc1, 0xef, 0xb7, 0xa6, 0xfe, 0x7d, 0xbf, 0xc7, + 0xfb, 0xf3, 0xff, 0x1f, 0x70, 0xf5, 0xcd, 0xfb, 0xff, 0xdc, 0x33, 0x8b, + 0xa7, 0xef, 0x9f, 0x5d, 0x9c, 0xbc, 0xa7, 0xef, 0x93, 0xa5, 0xff, 0x7c, + 0xde, 0x6c, 0xf7, 0xcd, 0xff, 0x1f, 0xcf, 0xf6, 0xda, 0xfb, 0x7e, 0x6b, + 0x8d, 0xef, 0x9f, 0x7c, 0x9c, 0xbc, 0xad, 0xef, 0x93, 0xa5, 0x9f, 0x7c, + 0xbd, 0xc4, 0xea, 0xf7, 0x9e, 0x7b, 0xbf, 0xc4, 0xf3, 0xf7, 0x9f, 0x7b, + 0xbe, 0xc4, 0xf6, 0xf7, 0xbc, 0x7b, 0x00, 0xcc, 0x35, 0x9b, 0xfa, 0xf7, + 0xfc, 0xcf, 0xff, 0x1f, 0x56, 0xec, 0xf8, 0xfb, 0xfc, 0xcf, 0xff, 0x1f, + 0x24, 0xe7, 0xfb, 0xcf, 0xff, 0x1f, 0x5d, 0xec, 0xec, 0x93, 0x00, 0x1c, + 0xbc, 0x00, 0xfb, 0xfb, 0xff, 0xcf, 0xff, 0x1f, 0x64, 0xec, 0x6e, 0xeb, + 0x93, 0xff, 0xff, 0xdf, 0x1f, 0xb8, 0xff, 0xff, 0x98, 0xef, 0xff, 0xcd, + 0xbf, 0x5c, 0xbe, 0x5c, 0xff, 0xcd, 0xbe, 0x54, 0x9a, 0xef, 0xdf, 0xcd, + 0xbf, 0x5c, 0xfe, 0xcd, 0xbe, 0x5c, 0xeb, 0xcd, 0xbd, 0x5c, 0xc3, 0x87, + 0x91, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xdf, 0x83, 0xed, 0xfe, 0x74, + 0xc3, 0x87, 0xff, 0xff, 0x2d, 0xeb, 0xfc, 0x92, 0xff, 0x1f, 0x6b, 0xec, + 0xbf, 0xc7, 0xf6, 0xf3, 0xff, 0xcd, 0x88, 0xed, 0xbf, 0x5c, 0xfc, 0xcf, + 0xc9, 0xed, 0xfb, 0xcd, 0xff, 0x1f, 0x1d, 0xf7, 0x9f, 0x73, 0xbd, 0xc4, + 0x2f, 0xf3, 0xb9, 0xc4, 0xf3, 0xf3, 0xbe, 0xc4, 0x30, 0xf7, 0x8f, 0xed, + 0x9f, 0x7c, 0x9c, 0xbc, 0xaf, 0xed, 0x93, 0xa5, 0xfe, 0x7c, 0xff, 0x1f, + 0xda, 0xf5, 0x39, 0xfb, 0x7e, 0x6b, 0x9e, 0x7b, 0xbf, 0xc4, 0xfb, 0xf3, + 0xfd, 0xc4, 0x46, 0xf7, 0x73, 0xfb, 0xff, 0xcd, 0x98, 0xed, 0xbe, 0x5c, + 0xf9, 0xa3, 0x9f, 0x7b, 0xbe, 0xc4, 0x9b, 0xf7, 0x9e, 0x7f, 0xfe, 0xdc, + 0x33, 0x8b, 0xfe, 0xc4, 0xd4, 0xf7, 0x9d, 0xed, 0x9f, 0x7c, 0x9c, 0xbc, + 0xbd, 0xed, 0x93, 0xa5, 0x9f, 0x7c, 0xb8, 0xc4, 0xf8, 0xf7, 0x9e, 0xed, + 0xfb, 0xcd, 0xbe, 0x5c, 0xeb, 0xcd, 0xbd, 0x5c, 0xf9, 0xfb, 0xbc, 0xc4, + 0xfb, 0xf7, 0xfc, 0xcf, 0xff, 0x1f, 0x8d, 0xe7, 0xa7, 0xee, 0x9f, 0x7d, + 0xff, 0xdc, 0x33, 0x8b, 0x9f, 0x5d, 0xdc, 0xbc, 0xa6, 0xee, 0xb7, 0xa6, + 0xdf, 0x6d, 0xbf, 0xc6, 0xf6, 0xf3, 0x9c, 0xbc, 0xab, 0xee, 0x93, 0xa5, + 0xff, 0x7c, 0xfb, 0xcd, 0xff, 0x1f, 0x65, 0xf7, 0x79, 0xfb, 0xfb, 0xcf, + 0xff, 0x1f, 0xd9, 0xec, 0x7d, 0xfb, 0x92, 0xee, 0x9f, 0x7c, 0xbc, 0xbc, + 0xd2, 0xee, 0xb7, 0xa6, 0xff, 0x7d, 0xa4, 0xa7, 0x77, 0x8b, 0xfe, 0xc5, + 0xea, 0xf7, 0xb4, 0xee, 0xbd, 0x7d, 0xf5, 0xce, 0x7b, 0x9b, 0xf3, 0xf7, + 0xfe, 0xd5, 0xd7, 0xee, 0xbd, 0x5e, 0x9c, 0xbc, 0xb8, 0xee, 0x97, 0xa4, + 0xdf, 0x6c, 0xfb, 0xcd, 0xff, 0x1f, 0x83, 0xf7, 0x97, 0xfb, 0xf9, 0xcf, + 0xff, 0x1f, 0x9b, 0xed, 0x9b, 0xfb, 0xff, 0xdc, 0x33, 0x8b, 0xa2, 0xef, + 0x9f, 0x5d, 0xdc, 0xbc, 0xa0, 0xef, 0xb7, 0xa6, 0xdf, 0x6d, 0xbf, 0xc6, + 0xf6, 0xf3, 0x9c, 0xbc, 0xa5, 0xef, 0x93, 0xa5, 0xff, 0x7c, 0xfb, 0xcd, + 0xff, 0x1f, 0x99, 0xf7, 0xad, 0xfb, 0xfb, 0xcf, 0xff, 0x1f, 0x0d, 0xed, + 0xb1, 0xfb, 0x8c, 0xef, 0xbf, 0x7c, 0xdc, 0xbd, 0x4c, 0xef, 0xdb, 0xa2, + 0xdf, 0x7e, 0xff, 0xdd, 0xbf, 0x5c, 0xba, 0xc6, 0xf2, 0xf7, 0xff, 0xdf, + 0xb0, 0x93, 0xbd, 0x7f, 0xb7, 0xbd, 0x9c, 0x7f, 0x37, 0x93, 0x9e, 0x56, + 0xfe, 0xde, 0xef, 0xcf, 0xff, 0xcd, 0xff, 0x1f, 0x1e, 0xf6, 0x97, 0xef, + 0x9f, 0x7c, 0x9c, 0xbc, 0xb7, 0xef, 0x93, 0xa5, 0xff, 0x7c, 0xde, 0x6c, + 0xfb, 0xcd, 0xff, 0x1f, 0xbe, 0xf7, 0xd2, 0xfb, 0xbd, 0xef, 0x9e, 0x7d, + 0xff, 0xdc, 0xf4, 0xfb, 0x91, 0xff, 0xff, 0xdf, 0xf7, 0xb7, 0xff, 0xff, + 0xf3, 0xb7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xef, 0xb7, 0xff, 0xff, + 0x33, 0x8b, 0x9e, 0x5d, 0xbc, 0xc4, 0xee, 0xf7, 0x34, 0x93, 0xbf, 0x7d, + 0xff, 0xdd, 0x77, 0x8b, 0xbf, 0x5c, 0xff, 0xce, 0xde, 0x5c, 0xbc, 0xbd, + 0x90, 0xef, 0x97, 0xa4, 0xff, 0x7c, 0xde, 0x6c, 0xfb, 0xcd, 0xff, 0x1f, + 0xe0, 0xf7, 0xf4, 0xfb, 0x93, 0xef, 0x9f, 0x7c, 0x9c, 0xbc, 0xb5, 0xef, + 0x93, 0xa5, 0xff, 0x7c, 0xde, 0x6c, 0xfb, 0xcd, 0xff, 0x1f, 0xeb, 0xf7, + 0xec, 0x93, 0x00, 0x1c, 0xba, 0x01, 0xfb, 0xfb, 0xff, 0xcf, 0xff, 0x1f, + 0x62, 0xed, 0x6d, 0xeb, 0x9b, 0xef, 0xfd, 0x7c, 0xfe, 0xb7, 0xc3, 0x87, + 0xf3, 0xb7, 0xff, 0xff, 0x91, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xdf, + 0xc3, 0x87, 0xff, 0xff, 0x2e, 0xeb, 0xfc, 0x92, 0xff, 0x1f, 0x5b, 0xed, + 0xbf, 0xc7, 0xf9, 0xf3, 0xff, 0xcf, 0xff, 0xce, 0xf7, 0xcd, 0xff, 0x1f, + 0x0a, 0xf8, 0x9f, 0x73, 0xbe, 0xc4, 0xfb, 0xf3, 0xbd, 0xc4, 0xf6, 0xf7, + 0xfa, 0xfb, 0xfd, 0xcf, 0xff, 0x1f, 0x83, 0xed, 0xfb, 0xfb, 0xff, 0xcf, + 0xff, 0x1f, 0x87, 0xed, 0x6e, 0xeb, 0xff, 0xff, 0x2f, 0xeb, 0xfe, 0xcf, + 0xff, 0x1f, 0x8d, 0xed, 0xfd, 0xef, 0xff, 0x1f, 0xce, 0xec, 0x6f, 0xeb, + 0x8d, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0xeb, 0xef, 0xfe, 0xce, 0xab, 0xef, + 0xff, 0x1f, 0x19, 0xed, 0x6f, 0xeb, 0xff, 0xff, 0x2e, 0xeb, 0xfc, 0x92, + 0xff, 0x1f, 0x87, 0xed, 0xbe, 0xc7, 0xee, 0xf7, 0xff, 0x1f, 0x95, 0xed, + 0xba, 0xc7, 0xf7, 0xf7, 0x94, 0xef, 0xff, 0x7c, 0xfd, 0xce, 0xff, 0xcd, + 0xff, 0x1f, 0xc3, 0xec, 0xf9, 0xfb, 0xf5, 0xcf, 0xff, 0xce, 0xf7, 0xcd, + 0xff, 0x1f, 0x41, 0xf8, 0x9f, 0x73, 0xbe, 0xc4, 0xf9, 0xf7, 0xf5, 0xcf, + 0xff, 0xce, 0xf7, 0xcd, 0xff, 0x1f, 0x49, 0xf8, 0x6e, 0xeb, 0xff, 0xff, + 0x8d, 0xff, 0xff, 0xdf, 0x9f, 0xf6, 0xff, 0xff, 0x2f, 0xeb, 0x95, 0xee, 0xbb, 0x7c, 0xdd, 0xa5, 0xde, 0x1b, 0xe0, 0xdf, 0xbd, 0x1b, 0xe0, 0xcf, - 0x7b, 0x93, 0xbb, 0x5c, 0xbc, 0x7c, 0xbd, 0xb5, 0xbd, 0x1b, 0xe0, 0xdf, - 0xb6, 0x9b, 0xdd, 0xf3, 0xff, 0x6c, 0xbe, 0x7c, 0xf2, 0xb7, 0xff, 0x1b, - 0xe0, 0xdf, 0xbd, 0x1b, 0xe0, 0xcf, 0x7f, 0x93, 0xbe, 0x5c, 0xbd, 0x1b, - 0xe0, 0xdf, 0xf2, 0xd5, 0x77, 0x8b, 0xfd, 0xc5, 0xff, 0x3b, 0xfe, 0xfa, - 0xbd, 0x74, 0xff, 0xde, 0xd8, 0xbe, 0x78, 0xc5, 0x77, 0xc5, 0x7b, 0x93, - 0xbd, 0x54, 0xbd, 0x1b, 0xe0, 0xcf, 0xbb, 0x5c, 0xbe, 0x74, 0xa9, 0xbd, - 0xa7, 0xb5, 0xff, 0xce, 0xff, 0x1f, 0xa1, 0xf7, 0x6f, 0xeb, 0x7a, 0x9b, - 0xe4, 0xf7, 0xa1, 0xa4, 0xde, 0x7c, 0xde, 0x1b, 0xe0, 0xcf, 0xde, 0x13, - 0xf2, 0xff, 0xde, 0x5c, 0xbf, 0x7d, 0xbd, 0x1b, 0xf9, 0xdf, 0xbf, 0xc5, - 0xf8, 0x93, 0xe5, 0xf3, 0xf2, 0xcf, 0xbd, 0x74, 0x78, 0xc5, 0x77, 0xc5, - 0x57, 0xc5, 0xbd, 0x54, 0xbe, 0x74, 0xa9, 0xbd, 0xa7, 0xb5, 0xff, 0xce, - 0xff, 0x1f, 0xbd, 0xf7, 0x6f, 0xeb, 0xa1, 0xa4, 0xde, 0x7d, 0x3f, 0xc6, - 0x1b, 0xf4, 0xbe, 0x7c, 0xbd, 0x1b, 0xe0, 0xcf, 0xbd, 0x13, 0xf4, 0xff, - 0xbe, 0x5c, 0xf4, 0xcf, 0x16, 0xf8, 0xff, 0x1b, 0xe0, 0xcf, 0xff, 0x13, - 0xf4, 0xff, 0xbc, 0xef, 0xfe, 0x5d, 0xf4, 0xcf, 0x1e, 0xf8, 0xff, 0xff, - 0xa3, 0xff, 0xff, 0xdf, 0x2d, 0xeb, 0xfc, 0x92, 0xff, 0xcf, 0xff, 0x1f, - 0x10, 0xf0, 0x91, 0xef, 0xdf, 0x73, 0xbe, 0x74, 0x5e, 0x1b, 0x00, 0xdc, - 0xbd, 0x1b, 0x00, 0xcc, 0x6b, 0x93, 0xbe, 0x54, 0xbe, 0x73, 0x7f, 0x9b, - 0xf7, 0xf3, 0xdf, 0x7c, 0x5c, 0xc6, 0xdf, 0x5c, 0xf4, 0x93, 0xff, 0x1f, - 0x06, 0xf8, 0x6d, 0xeb, 0xf8, 0x93, 0xff, 0x1f, 0xb8, 0xea, 0xbe, 0x73, - 0xf4, 0x93, 0xff, 0x1f, 0x0e, 0xf8, 0x6d, 0xeb, 0x9b, 0xff, 0xff, 0xdf, - 0x2e, 0xeb, 0x79, 0xed, 0xa1, 0xa3, 0xdf, 0x7d, 0x9e, 0x1b, 0xf9, 0xdf, - 0xbf, 0xc4, 0xa8, 0xf3, 0xbd, 0xc4, 0xd4, 0xf3, 0xbb, 0xc4, 0xfd, 0xf3, - 0x6e, 0xeb, 0x8f, 0x7b, 0xbc, 0x1b, 0xfc, 0xdf, 0xbe, 0xc5, 0x04, 0xf0, - 0x7f, 0xc4, 0x7e, 0xc4, 0x5f, 0xc4, 0x8f, 0x5b, 0x9e, 0x73, 0x9c, 0x1b, - 0x03, 0xcc, 0x9c, 0x13, 0x73, 0xff, 0x9e, 0x53, 0x97, 0xb4, 0x9c, 0x1b, - 0x83, 0xcf, 0x9c, 0x13, 0xeb, 0xff, 0x9c, 0x5b, 0x9e, 0x7b, 0x9c, 0x1b, - 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5b, 0x9f, 0x6b, 0xac, 0xee, - 0x37, 0x97, 0x52, 0xc4, 0x4e, 0xc4, 0x9f, 0x4b, 0x9d, 0x73, 0x78, 0xc4, - 0x77, 0xc4, 0x57, 0xc4, 0x9d, 0x53, 0x6e, 0xeb, 0x91, 0xee, 0x9e, 0x6c, - 0x3f, 0xc4, 0x2a, 0xf0, 0x7e, 0xc6, 0x7d, 0xc6, 0xff, 0xcc, 0x5d, 0xc6, - 0x91, 0x5b, 0xff, 0x15, 0x60, 0xfe, 0xdf, 0x5d, 0xff, 0x1f, 0x53, 0xf8, - 0xff, 0xcd, 0xfc, 0xcf, 0xff, 0xce, 0xff, 0x1f, 0x86, 0xf6, 0x9e, 0x73, + 0x7b, 0x93, 0xbb, 0x5c, 0x9c, 0x7c, 0x9d, 0xb4, 0x9c, 0x1b, 0xe0, 0xdf, + 0xb2, 0x9b, 0xe2, 0xf3, 0x9d, 0xee, 0xbf, 0x6c, 0xb2, 0xb5, 0xbd, 0x1b, + 0xe0, 0xdf, 0xde, 0x7c, 0xde, 0x1b, 0xe0, 0xcf, 0x7b, 0x93, 0xbe, 0x5c, + 0xbd, 0x1b, 0xe0, 0xdf, 0xf2, 0xd5, 0x77, 0x8b, 0xfd, 0xc5, 0xff, 0x3b, + 0xfe, 0xfa, 0xff, 0xde, 0xd8, 0xbe, 0xbd, 0x74, 0x78, 0xc5, 0x77, 0xc5, + 0x7b, 0x93, 0xbd, 0x54, 0xbd, 0x1b, 0xe0, 0xcf, 0xbb, 0x5c, 0xe2, 0xfb, + 0xff, 0xd4, 0xb2, 0x9b, 0xfa, 0xf7, 0x8b, 0xef, 0x9e, 0x7c, 0x3f, 0xc4, + 0xf6, 0xf3, 0x8e, 0xef, 0xbe, 0x7c, 0xbd, 0x1b, 0xe0, 0xcf, 0xbd, 0x13, + 0xf2, 0xff, 0xbe, 0x5c, 0xf7, 0xfb, 0x92, 0xef, 0xbe, 0x7c, 0xbd, 0x1b, + 0xe0, 0xcf, 0xbd, 0x13, 0xf4, 0xff, 0xbe, 0x5c, 0x96, 0xef, 0xbd, 0x74, + 0x78, 0xc5, 0x77, 0xc5, 0x57, 0xc5, 0xbd, 0x54, 0x99, 0xef, 0xfe, 0x7c, + 0xff, 0x1b, 0xe0, 0xdf, 0xbe, 0x74, 0xa9, 0xbd, 0xa7, 0xb5, 0xff, 0xce, + 0xff, 0x1f, 0xa1, 0xf8, 0x6f, 0xeb, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xdf, + 0x83, 0xff, 0xff, 0xdf, 0x2e, 0xeb, 0xfc, 0x92, 0xff, 0xcf, 0xff, 0x1f, + 0x0a, 0xf1, 0x96, 0xec, 0xdf, 0x73, 0xde, 0x1b, 0x00, 0xdc, 0xbe, 0x74, + 0xbd, 0x1b, 0x00, 0xcc, 0x7b, 0x93, 0xbe, 0x54, 0x9e, 0x73, 0x3f, 0x9b, + 0xfa, 0xf7, 0xff, 0x73, 0xff, 0x1f, 0x19, 0xec, 0xfa, 0xfb, 0x9e, 0xec, + 0xbf, 0x7c, 0x5c, 0xc5, 0xbf, 0x5c, 0xfe, 0x73, 0xff, 0x1f, 0xd7, 0xf8, + 0x6e, 0xeb, 0xff, 0xff, 0x2e, 0xeb, 0x83, 0xed, 0x9f, 0x7c, 0x9c, 0x1b, + 0xf9, 0xdf, 0xbf, 0xc4, 0xd0, 0xf7, 0x65, 0xed, 0x81, 0xa3, 0xbe, 0x7c, + 0x7f, 0xc5, 0xbe, 0x5c, 0xbf, 0x7c, 0xff, 0xce, 0xc9, 0xd6, 0x7b, 0x97, + 0x5e, 0xc5, 0xbf, 0x5c, 0xff, 0x15, 0x2e, 0xfe, 0xff, 0x1f, 0xef, 0xf8, + 0x9e, 0x73, 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, 0x37, 0xff, 0x9e, 0x53, + 0x97, 0xb4, 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0x9b, 0xff, 0x9c, 0x5b, + 0x9e, 0x7b, 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5b, + 0x9f, 0x6b, 0xb5, 0xed, 0x37, 0x97, 0x0f, 0xce, 0xd6, 0xbe, 0x3b, 0x93, + 0x9f, 0x4b, 0x9d, 0x73, 0x78, 0xc4, 0x77, 0xc4, 0x58, 0xc4, 0x9d, 0x53, + 0xa0, 0xfb, 0xbd, 0xc4, 0xcd, 0xf7, 0x9b, 0xed, 0x9e, 0x6c, 0x3f, 0xc4, + 0xa6, 0xf3, 0x7f, 0xed, 0x81, 0xa3, 0xbf, 0x7c, 0x7e, 0xc5, 0x7d, 0xc5, + 0x5d, 0xc5, 0xbf, 0x5c, 0xff, 0x15, 0x60, 0xfe, 0xff, 0x1f, 0x1f, 0xf9, + 0xfc, 0xcf, 0xff, 0xce, 0xff, 0xcd, 0xff, 0x1f, 0x7a, 0xf7, 0x9e, 0x73, 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, 0x73, 0xff, 0x9e, 0x53, 0x97, 0xb4, 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0xc7, 0xff, 0x9c, 0x5b, 0x9e, 0x7b, 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5b, 0x9f, 0x6b, - 0xa5, 0xef, 0x37, 0x97, 0x4e, 0xc4, 0x2f, 0xf8, 0x9e, 0x7d, 0x7f, 0xc4, - 0x9e, 0x5d, 0xff, 0xcc, 0xc9, 0xd4, 0xb3, 0x97, 0x5e, 0xc6, 0x1c, 0xcf, - 0xdf, 0x5d, 0xfe, 0xbf, 0xff, 0x1f, 0x7b, 0xf8, 0x9e, 0x73, 0x9c, 0x1b, - 0x03, 0xcc, 0x9c, 0x13, 0x3b, 0xff, 0x9e, 0x53, 0x97, 0xb4, 0x9c, 0x1b, - 0x83, 0xcf, 0x9c, 0x13, 0x9b, 0xff, 0x9c, 0x5b, 0x9e, 0x7b, 0x9c, 0x1b, - 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5b, 0x9f, 0x6b, 0xb6, 0xef, - 0x37, 0x97, 0x0f, 0xcd, 0xb6, 0xbd, 0x37, 0x93, 0x9f, 0x4b, 0x9d, 0x73, - 0x78, 0xc4, 0x77, 0xc4, 0x58, 0xc4, 0x9d, 0x53, 0x9c, 0x1b, 0xe0, 0xcf, - 0x9b, 0x5b, 0x6e, 0xeb, 0xa3, 0xff, 0xff, 0xdf, 0x00, 0xe0, 0x03, 0x00, - 0xff, 0x5f, 0xff, 0xbf, 0x2e, 0xeb, 0xde, 0xeb, 0x6c, 0xef, 0x9e, 0x7b, - 0x9c, 0x1b, 0xf9, 0xdf, 0xbf, 0xc4, 0xf9, 0xf3, 0xee, 0xef, 0xff, 0x1f, - 0xf8, 0xec, 0xfe, 0xeb, 0x6e, 0xeb, 0xff, 0xcf, 0xff, 0x1f, 0x3f, 0xf3, - 0xff, 0xcd, 0x9e, 0x7b, 0xf8, 0xd5, 0x37, 0x97, 0x5d, 0xc4, 0x9e, 0x5b, - 0x9f, 0x7b, 0x3f, 0xc4, 0x0f, 0xf4, 0xfc, 0x15, 0xb2, 0xfe, 0xc4, 0x93, + 0xb0, 0xee, 0x37, 0x97, 0x4e, 0xc4, 0x9f, 0x4b, 0x9d, 0x73, 0x78, 0xc4, + 0x77, 0xc4, 0x57, 0xc4, 0x9d, 0x53, 0xd3, 0xfb, 0xbb, 0xc4, 0xd5, 0xf7, + 0x97, 0xee, 0x8f, 0x7c, 0x9c, 0x1b, 0xfc, 0xdf, 0xbe, 0xc4, 0xdb, 0xf3, + 0x9a, 0xee, 0xaf, 0x7c, 0x7f, 0xc5, 0x7e, 0xc5, 0x5f, 0xc5, 0xaf, 0x5c, + 0xbe, 0x74, 0xbd, 0x1b, 0x03, 0xcc, 0xbd, 0x13, 0x73, 0xff, 0xbe, 0x54, + 0xb7, 0xb5, 0xbd, 0x1b, 0x83, 0xcf, 0xbd, 0x13, 0xeb, 0xff, 0xbc, 0x5c, + 0xbe, 0x7c, 0xbd, 0x1b, 0xe0, 0xcf, 0xbd, 0x13, 0xf4, 0xff, 0xbe, 0x5c, + 0xbf, 0x6c, 0xc5, 0xef, 0x7b, 0x97, 0x52, 0xc5, 0x4e, 0xc5, 0xbf, 0x4c, + 0xbd, 0x74, 0x78, 0xc5, 0x77, 0xc5, 0x57, 0xc5, 0xbd, 0x54, 0x6e, 0xeb, + 0x2f, 0xeb, 0xde, 0xeb, 0x8e, 0xef, 0x9e, 0x7c, 0x9c, 0x1b, 0xf9, 0xdf, + 0xbf, 0xc4, 0xe7, 0xf7, 0xff, 0xcf, 0xff, 0x1f, 0xa0, 0xf4, 0x92, 0xef, + 0xbe, 0x7c, 0xff, 0xce, 0xf8, 0xd6, 0x7b, 0x97, 0x5d, 0xc5, 0xbe, 0x5c, + 0x9f, 0x7c, 0x3f, 0xc4, 0xf4, 0xf7, 0xc4, 0x93, 0xfc, 0x15, 0xb2, 0xfe, 0x91, 0x23, 0xff, 0xef, 0x07, 0xcc, 0x91, 0x23, 0xfe, 0xef, 0x00, 0x1c, - 0xd4, 0x00, 0xfb, 0xef, 0xff, 0x1f, 0x13, 0xed, 0xfe, 0xeb, 0x6e, 0xeb, - 0x9b, 0xff, 0xff, 0xdf, 0x92, 0xff, 0xff, 0xdf, 0x2b, 0xeb, 0xdb, 0xeb, - 0x7a, 0xec, 0x9a, 0x6b, 0xbe, 0xc4, 0xbc, 0x92, 0xe4, 0xf2, 0x9f, 0x7a, - 0x9b, 0xb4, 0xfd, 0xdc, 0x9c, 0x1b, 0xfc, 0xdf, 0xfe, 0xc4, 0x56, 0xf3, - 0xff, 0x1f, 0x3b, 0xe9, 0xbf, 0xc7, 0xfc, 0xf3, 0xfb, 0xeb, 0x6b, 0xeb, - 0xff, 0x1f, 0x01, 0xf1, 0x7c, 0x92, 0xff, 0x1f, 0xd4, 0xf8, 0xbe, 0x7a, - 0xbd, 0x1b, 0xf9, 0xdf, 0xbf, 0xc5, 0x3c, 0x93, 0xbf, 0xf7, 0x07, 0xed, - 0xbd, 0x70, 0xa9, 0xbd, 0xa9, 0xb5, 0x76, 0x9a, 0xc5, 0xf3, 0xff, 0x47, - 0xff, 0x1f, 0x67, 0xf3, 0xf7, 0xcd, 0xf7, 0x9b, 0x9f, 0x67, 0x81, 0xf6, - 0x72, 0xcf, 0xfd, 0xbf, 0xff, 0x1f, 0xff, 0xf8, 0x3f, 0xcf, 0xfd, 0xbf, - 0xff, 0x1f, 0xb1, 0xeb, 0x9f, 0x67, 0xff, 0xcd, 0xac, 0x53, 0xff, 0xcf, - 0xbe, 0x7a, 0xf8, 0xd7, 0x7f, 0x97, 0x5e, 0xc5, 0xbe, 0x5a, 0xbe, 0x73, - 0xbd, 0x1b, 0x03, 0xcc, 0xbd, 0x13, 0x37, 0xff, 0xbe, 0x53, 0xb7, 0xb5, - 0xbd, 0x1b, 0x83, 0xcf, 0xbd, 0x13, 0xc7, 0xff, 0xbc, 0x5b, 0xbe, 0x7b, - 0xbd, 0x1b, 0xe0, 0xcf, 0xbd, 0x13, 0xf4, 0xff, 0xbe, 0x5b, 0xbf, 0x78, - 0x3f, 0xc5, 0x65, 0xf6, 0xf3, 0xce, 0xbf, 0x6b, 0xe1, 0xee, 0xd2, 0xbe, - 0x7f, 0x97, 0x7b, 0x93, 0xbf, 0x4b, 0xbd, 0x73, 0x78, 0xc5, 0x77, 0xc5, - 0x57, 0xc5, 0xbd, 0x53, 0xdf, 0x7a, 0xbb, 0xb6, 0xbd, 0x1b, 0xfc, 0xdf, - 0xbe, 0xc5, 0x0e, 0xf3, 0xbd, 0xc5, 0x8e, 0xf3, 0xbf, 0xc5, 0x54, 0xf4, - 0xed, 0xd4, 0x73, 0x9a, 0xca, 0xf6, 0x9f, 0x7a, 0x7b, 0xc4, 0x7a, 0xc4, - 0x5b, 0xc4, 0x9f, 0x5a, 0x3f, 0xc4, 0x36, 0xf6, 0xbb, 0x7b, 0xbd, 0x1b, - 0xe0, 0xdf, 0xdd, 0xc5, 0xa9, 0xf2, 0x7b, 0xc4, 0x7a, 0xc4, 0x9f, 0x5a, - 0xff, 0xcd, 0xbb, 0x23, 0xdb, 0xff, 0xbf, 0x7a, 0x98, 0xee, 0x3f, 0xc5, - 0x9d, 0xf6, 0xcc, 0x74, 0x66, 0xcd, 0xb7, 0x9b, 0xd0, 0xf7, 0xbe, 0x74, + 0xce, 0x00, 0xf8, 0xef, 0xff, 0x1f, 0x29, 0xee, 0xfe, 0xeb, 0x6f, 0xeb, + 0x83, 0xff, 0xff, 0xdf, 0x8b, 0xff, 0xff, 0xdf, 0x00, 0xe0, 0x03, 0x00, + 0xff, 0x5f, 0xff, 0xbf, 0x7a, 0xff, 0xff, 0xdf, 0x2c, 0xeb, 0xdc, 0xeb, + 0xfc, 0x92, 0xff, 0x1f, 0x5c, 0xea, 0xbf, 0xc7, 0x52, 0xf6, 0xff, 0x1f, + 0xee, 0xf1, 0xbc, 0x92, 0xff, 0x1f, 0x97, 0xf9, 0x7c, 0x92, 0x9e, 0x7b, + 0x9c, 0x1b, 0xf9, 0xdf, 0xbf, 0xc4, 0xa5, 0xf7, 0x80, 0xed, 0x9d, 0x74, + 0x89, 0xbc, 0x89, 0xb4, 0xb2, 0x9a, 0xab, 0xf3, 0xff, 0x1f, 0xc1, 0xf4, + 0xf7, 0xcc, 0xf3, 0x9b, 0xf5, 0xf7, 0x72, 0xcf, 0xfd, 0xbf, 0xff, 0x1f, + 0xbc, 0xf9, 0x3f, 0xcf, 0xfd, 0xbf, 0xff, 0x1f, 0x0a, 0xed, 0xe6, 0xfb, + 0x9e, 0x7b, 0x59, 0xc4, 0x9e, 0x5b, 0xfe, 0xcf, 0xff, 0x1f, 0xef, 0xf4, + 0x9f, 0x7b, 0x3f, 0xc4, 0xfa, 0xf3, 0xfc, 0xcf, 0xff, 0x1f, 0x43, 0xfa, + 0xf3, 0xfb, 0xfe, 0xe7, 0xfc, 0x15, 0xb2, 0xfe, 0x9f, 0x57, 0x07, 0xcc, + 0x9e, 0x57, 0x00, 0x1c, 0x18, 0x01, 0xfe, 0xcf, 0xff, 0x1f, 0x4f, 0xfa, + 0x95, 0xed, 0xff, 0xcd, 0xb6, 0x54, 0xbe, 0x7b, 0xff, 0xcf, 0xf8, 0xd7, + 0x7f, 0x97, 0x5e, 0xc5, 0xbe, 0x5b, 0xbe, 0x74, 0xbd, 0x1b, 0x03, 0xcc, + 0xbd, 0x13, 0x37, 0xff, 0xbe, 0x54, 0xb7, 0xb5, 0xbd, 0x1b, 0x83, 0xcf, + 0xbd, 0x13, 0xc7, 0xff, 0xbc, 0x5c, 0xbe, 0x7c, 0xbd, 0x1b, 0xe0, 0xcf, + 0xbd, 0x13, 0xf4, 0xff, 0xbe, 0x5c, 0x97, 0x7c, 0x3f, 0xc4, 0xfc, 0xf7, + 0xf3, 0xce, 0xfd, 0xfb, 0xef, 0xce, 0x85, 0xee, 0xd2, 0xbe, 0xbf, 0x6c, + 0xe6, 0xee, 0x7f, 0x97, 0x7b, 0x93, 0xbf, 0x4c, 0xbd, 0x74, 0x78, 0xc5, + 0x77, 0xc5, 0x57, 0xc5, 0xbd, 0x54, 0x9f, 0x7b, 0x9b, 0xb4, 0x9c, 0x1b, + 0xfc, 0xdf, 0xbe, 0xc4, 0x99, 0xf3, 0xbd, 0xc4, 0x56, 0xf3, 0xbf, 0xc4, + 0xc0, 0xf6, 0xed, 0xd1, 0xa7, 0x9a, 0xf6, 0xf3, 0xb2, 0xee, 0x96, 0x75, + 0xff, 0xdc, 0x32, 0x8b, 0x96, 0x55, 0x00, 0xcd, 0x37, 0x9b, 0xcb, 0xf6, + 0x9f, 0x7b, 0x7b, 0xc4, 0x7a, 0xc4, 0x5b, 0xc4, 0x9f, 0x5b, 0x3f, 0xc4, + 0xf8, 0xf3, 0xff, 0x15, 0xcc, 0xfd, 0x84, 0xce, 0xff, 0x1f, 0x5d, 0xed, + 0xf9, 0xfb, 0xff, 0x15, 0xb2, 0xfe, 0x84, 0xce, 0xff, 0x1f, 0x63, 0xed, + 0x9f, 0xee, 0xb6, 0x74, 0x00, 0xcc, 0x73, 0x9b, 0xc9, 0xf7, 0x9f, 0x7b, + 0x3f, 0xc4, 0xf9, 0xf3, 0xff, 0x15, 0x60, 0xfe, 0xff, 0x1f, 0x39, 0xfa, + 0xe0, 0xfb, 0x85, 0xef, 0xbe, 0x74, 0xbd, 0x1b, 0x03, 0xcc, 0xbd, 0x13, + 0x73, 0xff, 0xbe, 0x54, 0xb7, 0xb5, 0xbd, 0x1b, 0x83, 0xcf, 0xbd, 0x13, + 0xeb, 0xff, 0xbc, 0x5c, 0xbe, 0x7c, 0xbd, 0x1b, 0xe0, 0xcf, 0xbd, 0x13, + 0xf4, 0xff, 0xbe, 0x5c, 0xbf, 0x6c, 0xce, 0xef, 0x7b, 0x97, 0x52, 0xc5, + 0x4e, 0xc5, 0xbf, 0x4c, 0xbd, 0x74, 0x78, 0xc5, 0x77, 0xc5, 0x57, 0xc5, + 0xbd, 0x54, 0xd1, 0x1b, 0xf5, 0xff, 0x9f, 0x7b, 0x9c, 0x1b, 0xfe, 0xdf, + 0x9f, 0x5e, 0xfe, 0xcf, 0xff, 0xcd, 0xff, 0x1f, 0xb8, 0xf8, 0x9f, 0x7b, + 0x7b, 0xc4, 0x7a, 0xc4, 0x5a, 0xc4, 0x9f, 0x5b, 0xff, 0xcd, 0x9c, 0xef, + 0xb6, 0x54, 0x1b, 0xfb, 0x83, 0xff, 0xff, 0xdf, 0x8b, 0xff, 0xff, 0xdf, + 0x00, 0xe0, 0x03, 0x00, 0x9f, 0x7b, 0x3f, 0xc4, 0xf4, 0xf7, 0xfe, 0xcf, + 0xff, 0x1f, 0xc1, 0xf2, 0xfc, 0x15, 0xee, 0xfe, 0xf3, 0x9b, 0xf4, 0xf3, + 0x9f, 0x7b, 0x3f, 0xc4, 0x2e, 0xf3, 0xfe, 0xcf, 0xff, 0x1f, 0xcb, 0xf2, + 0x32, 0xcc, 0x9e, 0xbc, 0xf3, 0x9b, 0x35, 0xf7, 0xd1, 0x1b, 0xf5, 0xff, + 0x9f, 0x7b, 0x9c, 0x1b, 0xfe, 0xdf, 0x9f, 0x5e, 0xfe, 0xcf, 0xff, 0xcd, + 0xff, 0x1f, 0xe5, 0xf8, 0x9f, 0x7b, 0x3f, 0xc4, 0xe0, 0xf7, 0x9f, 0xec, + 0xbe, 0x74, 0xbd, 0x1b, 0x03, 0xcc, 0xbd, 0x13, 0x73, 0xff, 0xbe, 0x54, + 0xb7, 0xb5, 0xbd, 0x1b, 0x83, 0xcf, 0xbd, 0x13, 0xeb, 0xff, 0xbc, 0x5c, + 0xbe, 0x7c, 0xbd, 0x1b, 0xe0, 0xcf, 0xbd, 0x13, 0xf4, 0xff, 0xbe, 0x5c, + 0xbf, 0x6c, 0xe8, 0xed, 0x7f, 0x97, 0x52, 0xc5, 0x4e, 0xc5, 0xbf, 0x4c, + 0xbd, 0x74, 0x78, 0xc5, 0x77, 0xc5, 0x57, 0xc5, 0xbd, 0x54, 0x9f, 0x7b, + 0x7b, 0xc4, 0x7a, 0xc4, 0x5a, 0xc4, 0x9f, 0x5b, 0x66, 0xfb, 0xff, 0x1f, + 0x34, 0xed, 0x9e, 0x7b, 0x9c, 0xb4, 0x9c, 0x1b, 0xf8, 0xdf, 0xf2, 0x9b, + 0xf9, 0xf3, 0xff, 0xd7, 0xff, 0x8b, 0xff, 0x1f, 0x82, 0xed, 0xf8, 0xfb, + 0x3e, 0x9b, 0xfa, 0xf3, 0xff, 0xdf, 0xff, 0x8b, 0xff, 0x1f, 0x89, 0xed, + 0xfc, 0xcf, 0xff, 0x1f, 0x16, 0xf3, 0x7a, 0xcc, 0x9e, 0xbc, 0xf3, 0x9b, + 0xf4, 0xf7, 0x9f, 0x7b, 0x9c, 0x1b, 0xfe, 0xdf, 0xbf, 0xc4, 0xff, 0x3b, + 0xfc, 0xfa, 0xf4, 0xcf, 0xf2, 0xa7, 0xff, 0x1f, 0xf6, 0xf0, 0x81, 0xee, + 0x9c, 0x7c, 0x9c, 0x1b, 0xfb, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0xee, 0xf3, + 0x20, 0xcc, 0x9e, 0xbc, 0xb3, 0x9a, 0xf2, 0xf3, 0x87, 0xee, 0xbc, 0x7c, + 0x7d, 0xc5, 0xbc, 0x5c, 0xfa, 0xcf, 0xff, 0xce, 0xff, 0x1f, 0x4f, 0xeb, + 0xff, 0x15, 0xcc, 0xfd, 0xff, 0x1f, 0x3b, 0xee, 0x9f, 0x7b, 0x9c, 0x1b, + 0xf7, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0xe7, 0xf3, 0xff, 0x1f, 0x2d, 0xf5, + 0xf1, 0x23, 0xff, 0xef, 0xef, 0xb7, 0xf1, 0x23, 0xfe, 0xef, 0x9f, 0x67, + 0xfe, 0xe5, 0x9f, 0x4d, 0x8f, 0xb4, 0xf9, 0xdc, 0xb3, 0x9a, 0xf5, 0xf3, + 0x97, 0xee, 0xfe, 0x74, 0xe9, 0xbf, 0xe9, 0xb7, 0xff, 0x1f, 0x55, 0xee, + 0x9f, 0x7b, 0x7c, 0xc4, 0x9f, 0x5b, 0x9e, 0x7b, 0xbc, 0x1b, 0xb9, 0xdf, + 0xbd, 0xc5, 0xd3, 0xf7, 0x78, 0xcc, 0x9d, 0xbc, 0xb3, 0x9a, 0xf2, 0xf7, + 0x9e, 0x7b, 0xff, 0xce, 0xc0, 0xd6, 0x3b, 0x93, 0x9e, 0x5b, 0xff, 0xcd, + 0x85, 0xef, 0xb6, 0x54, 0xfc, 0xcf, 0xff, 0x1f, 0x98, 0xfb, 0xd3, 0xfb, + 0xa8, 0xef, 0x96, 0x75, 0xff, 0xdc, 0x32, 0x8b, 0x96, 0x55, 0xca, 0xcd, + 0x37, 0x9b, 0xdb, 0xf7, 0xfe, 0xe7, 0xfc, 0x15, 0xcc, 0xfd, 0x9f, 0x57, + 0xfc, 0x15, 0x60, 0xfe, 0x9e, 0x57, 0x9e, 0x7b, 0x59, 0xc4, 0x9e, 0x5b, + 0xff, 0xcd, 0x91, 0xef, 0xb6, 0x54, 0x00, 0x1c, 0x7c, 0x02, 0xff, 0xcf, + 0xff, 0x1f, 0x65, 0xf6, 0xee, 0xfb, 0x9c, 0x1b, 0x80, 0xcf, 0xbf, 0xc4, + 0xf2, 0xf3, 0x5a, 0x1b, 0xd0, 0xed, 0xaa, 0x8a, 0xef, 0xc2, 0xf7, 0xf7, + 0x9e, 0x7b, 0x9c, 0x1b, 0x80, 0xdf, 0x9e, 0x5b, 0xfe, 0xcf, 0xff, 0x1f, + 0x76, 0xf6, 0xfc, 0xeb, 0x6c, 0xeb, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xdf, + 0x00, 0xe0, 0x03, 0x00, 0x83, 0xff, 0xff, 0xdf, 0x2d, 0xeb, 0x58, 0xec, + 0xe8, 0x93, 0xff, 0xce, 0xf7, 0xcd, 0x00, 0x1c, 0x02, 0x05, 0x61, 0xa2, + 0xec, 0x93, 0xff, 0xce, 0xf9, 0xcd, 0x00, 0x1c, 0x08, 0x05, 0x9f, 0x7b, + 0xff, 0xcd, 0x8f, 0xd5, 0x37, 0x97, 0x9f, 0x5b, 0x9e, 0x7b, 0x9c, 0x13, + 0xf9, 0xff, 0x9c, 0x1b, 0xc7, 0xcf, 0x5b, 0xc4, 0x9e, 0x5b, 0x8f, 0x7a, + 0x97, 0xdd, 0x37, 0x97, 0x5e, 0xc4, 0x8f, 0x5a, 0xf0, 0xcc, 0x8e, 0x5a, + 0xff, 0xcc, 0x96, 0x52, 0x6d, 0xeb, 0xff, 0xff, 0x2c, 0xeb, 0xd7, 0xeb, + 0xbc, 0x92, 0xff, 0x1f, 0xc4, 0xf0, 0xbe, 0xc7, 0x83, 0xf7, 0xff, 0x1f, + 0xd2, 0xf0, 0xbc, 0xc7, 0xc5, 0xf7, 0x8e, 0xed, 0xbf, 0x7c, 0xbd, 0x13, + 0xce, 0xff, 0xbf, 0x5c, 0x00, 0x1c, 0x6b, 0x04, 0x87, 0xcc, 0x3d, 0x9b, + 0xfb, 0xf3, 0xaf, 0xcc, 0x3d, 0x9b, 0xf9, 0xf7, 0x32, 0xcf, 0xfe, 0xbf, + 0xff, 0x1f, 0x97, 0xfb, 0xfa, 0xfb, 0x97, 0xed, 0xbe, 0x7c, 0x5f, 0xc5, + 0xbe, 0x5c, 0xfd, 0xcf, 0xff, 0x1f, 0x15, 0xfc, 0x9c, 0xed, 0xbe, 0x74, 0xbd, 0x1b, 0x03, 0xcc, 0xbd, 0x13, 0x73, 0xff, 0xbe, 0x54, 0xb7, 0xb5, - 0xbd, 0x1b, 0x83, 0xcf, 0xbd, 0x13, 0xeb, 0xff, 0xbc, 0x5c, 0xbe, 0x7c, + 0xbd, 0x1b, 0x83, 0xcf, 0xbd, 0x13, 0xf3, 0xff, 0xbc, 0x5c, 0xbe, 0x7c, 0xbd, 0x1b, 0xe0, 0xcf, 0xbd, 0x13, 0xf4, 0xff, 0xbe, 0x5c, 0xbf, 0x6c, - 0xc3, 0xef, 0x7b, 0x97, 0x52, 0xc5, 0x4e, 0xc5, 0xbf, 0x4c, 0xbd, 0x74, - 0x78, 0xc5, 0x77, 0xc5, 0x57, 0xc5, 0xbd, 0x54, 0x9f, 0x7a, 0x9c, 0x1b, - 0xfe, 0xdf, 0xd1, 0x1b, 0xf1, 0xff, 0xfe, 0xcd, 0x9f, 0x5e, 0xba, 0x4b, - 0xfe, 0xcf, 0xff, 0xcd, 0xff, 0x1f, 0xab, 0xf7, 0x9f, 0x7a, 0x7b, 0xc4, - 0x7a, 0xc4, 0x5a, 0xc4, 0x9f, 0x5a, 0xff, 0xcc, 0x8c, 0x53, 0xa2, 0xf8, - 0x91, 0xef, 0x9d, 0x6c, 0x3d, 0xc4, 0xaa, 0xf4, 0x9b, 0x27, 0xdb, 0xff, - 0xbd, 0xa4, 0xbb, 0x23, 0xdb, 0xff, 0xfa, 0xcd, 0x37, 0x9b, 0xb2, 0xf4, - 0x96, 0xef, 0xff, 0xce, 0xdd, 0x4c, 0xfd, 0xcf, 0xff, 0x1f, 0x25, 0xe9, - 0xfd, 0xcf, 0xff, 0x1f, 0x4c, 0xe9, 0xbc, 0xf8, 0xa3, 0xff, 0xff, 0xdf, - 0x9b, 0xff, 0xff, 0xdf, 0x00, 0xe0, 0x03, 0x00, 0xff, 0xaf, 0xff, 0xbf, - 0xff, 0xcf, 0xff, 0xbf, 0xff, 0x1f, 0xe1, 0xeb, 0x9e, 0x7a, 0x9c, 0xb4, - 0x9c, 0x1b, 0xf8, 0xdf, 0xf2, 0x9b, 0xe4, 0xf6, 0x3e, 0x9b, 0x25, 0xf7, - 0xfc, 0xcf, 0xff, 0x1f, 0xce, 0xf1, 0x7a, 0xcc, 0x9e, 0xbc, 0xf3, 0x9b, - 0xf4, 0xf7, 0x9f, 0x7a, 0x9c, 0x1b, 0xfe, 0xdf, 0xbf, 0xc4, 0xff, 0x3b, - 0xfc, 0xfa, 0xf4, 0xcf, 0xf2, 0xa7, 0xff, 0x1f, 0x9c, 0xef, 0x18, 0xec, - 0x9c, 0x78, 0xbc, 0x1b, 0xfb, 0xdf, 0x77, 0x8b, 0xbf, 0xc5, 0x66, 0xf7, - 0x9f, 0x7a, 0x9c, 0x1b, 0xf7, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0xff, 0xf6, - 0xbe, 0x7a, 0x37, 0x8b, 0xdc, 0x1b, 0xb9, 0xdf, 0xbd, 0xc6, 0xef, 0xf2, - 0x9c, 0x1b, 0x80, 0xcf, 0xbf, 0xc4, 0xf3, 0xf3, 0x39, 0x1b, 0xd0, 0xed, - 0x66, 0x8a, 0xef, 0xc1, 0xf8, 0xf7, 0xbd, 0x1b, 0x80, 0xdf, 0xbe, 0x5a, - 0xfe, 0xcf, 0xff, 0x1f, 0x6e, 0xf4, 0x8b, 0x73, 0xff, 0xdc, 0x32, 0x8b, - 0x9c, 0xcd, 0x37, 0x9b, 0x8b, 0x53, 0x06, 0xf5, 0xff, 0xcd, 0x8c, 0xed, - 0xab, 0x54, 0xfb, 0xcf, 0xff, 0x1f, 0xa3, 0xf7, 0x0d, 0xf9, 0xfc, 0xcf, - 0xff, 0x1f, 0x0f, 0xf2, 0x93, 0x73, 0xb3, 0xa7, 0x92, 0x73, 0xff, 0xdc, - 0x32, 0x8b, 0x76, 0x8b, 0xfe, 0x15, 0x82, 0xfb, 0xbe, 0xb5, 0x3b, 0x9b, - 0xb3, 0x53, 0x92, 0x53, 0xf9, 0xf7, 0xff, 0xcc, 0x92, 0x53, 0xc4, 0xcc, - 0x73, 0x9b, 0x70, 0xf7, 0x98, 0x6b, 0xbe, 0xc4, 0xbb, 0xed, 0x66, 0xf3, - 0x97, 0x6b, 0xbe, 0xc4, 0xbd, 0xed, 0x35, 0xf5, 0xd2, 0x75, 0x9c, 0x1b, - 0xe2, 0xfc, 0xb3, 0x9b, 0x3a, 0xf5, 0xff, 0xcf, 0xff, 0xcc, 0xfa, 0x4d, - 0xf7, 0x4d, 0x92, 0x55, 0x9f, 0x7a, 0x3f, 0xc4, 0xf8, 0xf2, 0xff, 0x1b, - 0x61, 0xfe, 0xff, 0x1f, 0x1e, 0xfa, 0xff, 0x15, 0xcc, 0xfd, 0xff, 0x1f, - 0xd0, 0xec, 0x4b, 0xf9, 0x3f, 0xc6, 0x67, 0xf3, 0xfe, 0xcf, 0xff, 0x1f, - 0x44, 0xf2, 0x32, 0xcc, 0x9e, 0xbc, 0xf3, 0x9b, 0x49, 0xf5, 0x9f, 0x7a, - 0xd1, 0x1b, 0xf1, 0xff, 0x9c, 0x1b, 0xfe, 0xdf, 0x9f, 0x5e, 0xfe, 0xcf, - 0xfe, 0xcc, 0xff, 0xcd, 0x9a, 0x4b, 0xff, 0x1f, 0x66, 0xf8, 0x9f, 0x7a, - 0x34, 0xee, 0x3f, 0xc4, 0xe1, 0xf7, 0x9e, 0x71, 0x9c, 0x1b, 0x03, 0xcc, - 0x9c, 0x13, 0x73, 0xff, 0x9e, 0x51, 0x97, 0xb4, 0x9c, 0x1b, 0x83, 0xcf, - 0x9c, 0x13, 0xeb, 0xff, 0x9c, 0x59, 0x9e, 0x79, 0x9c, 0x1b, 0xe0, 0xcf, - 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x59, 0x9f, 0x69, 0xfe, 0xee, 0x3f, 0x97, - 0x52, 0xc4, 0x4e, 0xc4, 0x9f, 0x49, 0x9d, 0x71, 0x78, 0xc4, 0x77, 0xc4, - 0x57, 0xc4, 0x9d, 0x51, 0x9f, 0x7a, 0x7b, 0xc4, 0x7a, 0xc4, 0x5a, 0xc4, - 0x9f, 0x5a, 0x7c, 0xf9, 0x20, 0xcd, 0xbe, 0xbd, 0x77, 0x9a, 0x9a, 0xf0, - 0x7d, 0xc4, 0xfa, 0xcf, 0xff, 0xce, 0x9c, 0x58, 0xff, 0x1f, 0x53, 0xea, - 0xff, 0x15, 0xcc, 0xfd, 0xff, 0x1f, 0x1b, 0xed, 0xa5, 0xf8, 0x3f, 0xc6, - 0x6e, 0xf7, 0x8c, 0x73, 0xff, 0xdc, 0x32, 0x8b, 0x66, 0xcd, 0x37, 0x9b, - 0x8c, 0x53, 0x3b, 0xf1, 0x95, 0xf9, 0xbe, 0x7a, 0x59, 0xc5, 0xbe, 0x5a, - 0xfe, 0xcf, 0x9f, 0x47, 0xff, 0x1f, 0x0b, 0xf5, 0xbf, 0x7a, 0x9f, 0x67, - 0x3f, 0xc5, 0x70, 0xf3, 0xfc, 0xcf, 0xff, 0x1f, 0xf0, 0xfa, 0x9f, 0x67, - 0x82, 0xf9, 0xff, 0xdf, 0xff, 0x8b, 0xff, 0x1f, 0xd4, 0xec, 0xdc, 0xf8, - 0x9b, 0xff, 0xff, 0xdf, 0xa3, 0xff, 0xff, 0xdf, 0x00, 0xe0, 0x03, 0x00, - 0xfe, 0xcf, 0xf8, 0x4b, 0x0d, 0xcf, 0xff, 0x1f, 0x98, 0xfa, 0xff, 0x1f, - 0x26, 0xed, 0x94, 0xf8, 0xff, 0x15, 0xb2, 0xfe, 0x84, 0xce, 0xff, 0x1f, - 0x44, 0xed, 0x56, 0xf9, 0xd2, 0x75, 0x6a, 0xcc, 0xb3, 0x9b, 0x9a, 0xf4, - 0xff, 0xcc, 0xff, 0xce, 0x92, 0x55, 0xfe, 0xcc, 0xd8, 0x4d, 0x97, 0x4d, - 0xff, 0x15, 0xcc, 0xfe, 0x84, 0xce, 0xff, 0x1f, 0x54, 0xed, 0xa6, 0xf8, - 0xac, 0x74, 0x00, 0xcc, 0x73, 0x9b, 0x31, 0xf5, 0xff, 0x15, 0x60, 0xfe, - 0xff, 0x1f, 0xb9, 0xfa, 0x47, 0xf9, 0xef, 0xce, 0x98, 0xf9, 0xfe, 0xcf, - 0xff, 0x1f, 0xdb, 0xf2, 0xfc, 0x15, 0xee, 0xfe, 0xf3, 0x9b, 0x95, 0xf0, - 0x9f, 0x7a, 0x3f, 0xc4, 0xe3, 0xf1, 0xa0, 0xf8, 0xff, 0xd7, 0xff, 0x8b, - 0xff, 0x1f, 0x13, 0xed, 0x1b, 0xf9, 0xff, 0x1f, 0x12, 0xf5, 0xfe, 0xe4, - 0xff, 0x54, 0xef, 0xb7, 0xfe, 0x54, 0x9f, 0x6c, 0xfd, 0xe5, 0x9f, 0x4d, - 0x8f, 0xb4, 0xf9, 0xdc, 0x73, 0x9a, 0x0a, 0xf1, 0xfe, 0x70, 0xe9, 0xbf, - 0xe9, 0xb7, 0xff, 0x1f, 0x8c, 0xed, 0x9f, 0x7a, 0x7c, 0xc4, 0x9f, 0x5a, - 0x13, 0xf9, 0x78, 0xcc, 0x9d, 0xbc, 0x73, 0x9a, 0xbb, 0xf3, 0x8c, 0x73, - 0xff, 0xdc, 0x32, 0x8b, 0xca, 0xcd, 0x37, 0x9b, 0x8c, 0x53, 0x09, 0xf5, - 0xfd, 0xe7, 0xfc, 0x15, 0xcc, 0xfd, 0x9f, 0x57, 0xfc, 0x15, 0x60, 0xfe, - 0x9e, 0x57, 0x9e, 0x7a, 0x59, 0xc4, 0x9e, 0x5a, 0xff, 0xcd, 0x81, 0xef, - 0xac, 0x54, 0x00, 0x1c, 0x0a, 0x03, 0xff, 0xcf, 0xff, 0x1f, 0x8b, 0xf5, - 0x1c, 0xf9, 0x8c, 0x73, 0xff, 0xdc, 0x32, 0x8b, 0x00, 0xcd, 0x37, 0x9b, - 0x8c, 0x53, 0xcb, 0xf1, 0xff, 0x17, 0x25, 0x02, 0xff, 0x15, 0xcc, 0xfd, - 0x84, 0xce, 0xff, 0x1f, 0xb2, 0xed, 0xfe, 0xcc, 0x91, 0x5b, 0xc6, 0xf9, - 0xfd, 0xe7, 0xfd, 0x15, 0xb2, 0xfe, 0xbf, 0x57, 0x07, 0xcd, 0xbe, 0x57, - 0x9f, 0x47, 0x00, 0x1c, 0x28, 0x03, 0xfe, 0xcf, 0xff, 0x1f, 0x87, 0xfb, - 0x9f, 0x67, 0xff, 0x17, 0x19, 0x02, 0x07, 0xcf, 0xff, 0x1f, 0x23, 0xfb, - 0xff, 0x15, 0xb2, 0xfe, 0xff, 0x1f, 0xd5, 0xed, 0xff, 0x17, 0x50, 0x02, - 0xff, 0xce, 0xc0, 0xd6, 0x7b, 0x93, 0xbe, 0x5a, 0xff, 0xcc, 0xfc, 0xcf, - 0x8c, 0x53, 0xff, 0x1f, 0x9c, 0xfb, 0x4f, 0xf9, 0xa3, 0xff, 0xff, 0xdf, - 0x2d, 0xeb, 0x6d, 0xef, 0x41, 0xa3, 0xec, 0x93, 0xff, 0xce, 0xf7, 0xcd, - 0x00, 0x1c, 0x7b, 0x05, 0xf9, 0xcd, 0xe8, 0x93, 0xff, 0xce, 0x00, 0x1c, - 0x80, 0x05, 0xff, 0xcd, 0x9f, 0x7a, 0x8f, 0xd5, 0x37, 0x97, 0x9f, 0x5a, - 0x9e, 0x7a, 0x9c, 0x13, 0xf9, 0xff, 0x9c, 0x1b, 0xc7, 0xcf, 0x5b, 0xc4, - 0x9e, 0x5a, 0x8f, 0x7b, 0x97, 0xdd, 0x37, 0x97, 0x5e, 0xc4, 0x8f, 0x5b, - 0xf0, 0xcc, 0x8e, 0x5b, 0xff, 0xcc, 0x8c, 0x53, 0x6d, 0xeb, 0xff, 0xff, - 0xa3, 0xff, 0xff, 0xdf, 0x9c, 0xef, 0xff, 0x7c, 0xfd, 0x93, 0xff, 0x1b, - 0xfe, 0xdf, 0xc3, 0x87, 0x9b, 0xff, 0xff, 0xdf, 0x2b, 0xeb, 0xd6, 0xeb, - 0xfc, 0x92, 0xff, 0x1f, 0x4e, 0xf0, 0xbe, 0xc7, 0x39, 0xf3, 0x9f, 0x73, - 0xf9, 0xc4, 0xdc, 0xf7, 0xb6, 0xec, 0x9d, 0x3b, 0xbc, 0xf7, 0x9f, 0x6c, - 0xf3, 0x87, 0x57, 0xec, 0x97, 0x7a, 0x9c, 0x1b, 0x80, 0xcf, 0x33, 0x8b, - 0xbf, 0xc4, 0x9f, 0x17, 0xcb, 0xfd, 0x6f, 0x7a, 0x7b, 0x1b, 0xfb, 0xdf, - 0xef, 0x8a, 0xbf, 0xc3, 0xf8, 0xf7, 0x9e, 0x7a, 0x9c, 0x1b, 0xe0, 0xdf, - 0xd2, 0xc4, 0x9f, 0x17, 0xd2, 0xfd, 0xfd, 0x72, 0xf8, 0xb7, 0xff, 0x1b, - 0xfc, 0xdf, 0xff, 0x1f, 0x02, 0xfa, 0xfe, 0xcc, 0x9a, 0x23, 0xd4, 0xff, - 0xf6, 0xeb, 0x6b, 0xeb, 0x7e, 0x6b, 0x9e, 0x7b, 0xbf, 0xc4, 0x12, 0xf7, - 0xbf, 0x7b, 0xbe, 0xc5, 0x39, 0xa3, 0xbf, 0x17, 0x9b, 0xfd, 0xbd, 0xc5, - 0xb8, 0xf2, 0x4c, 0xed, 0xec, 0x93, 0x00, 0x1c, 0xf8, 0x05, 0x00, 0x1c, - 0x14, 0x04, 0xff, 0xcc, 0x8b, 0x52, 0xf6, 0xeb, 0x6b, 0xeb, 0x9e, 0x6b, - 0xbd, 0x7c, 0xbd, 0x1b, 0xf0, 0xdf, 0xbd, 0xc5, 0xd5, 0xf2, 0xfd, 0x74, - 0xe9, 0xbf, 0xe9, 0xb7, 0xff, 0x1f, 0xb1, 0xfb, 0x9e, 0x6b, 0x9d, 0x7c, - 0x9c, 0x1b, 0xf0, 0xdf, 0xbc, 0xc4, 0x26, 0xf4, 0x99, 0xed, 0xbf, 0x7c, - 0xbe, 0xc5, 0x2a, 0xf4, 0xff, 0xcd, 0xbf, 0x5c, 0xfb, 0xed, 0x00, 0x1c, - 0xce, 0x03, 0xf6, 0xeb, 0x6b, 0xeb, 0x9e, 0x6b, 0xff, 0x7c, 0x7d, 0xed, - 0x9f, 0x7b, 0xff, 0x1b, 0xfe, 0xdf, 0xb9, 0xbf, 0x79, 0xc4, 0x37, 0x93, - 0x9f, 0x5b, 0xff, 0x1f, 0x40, 0xee, 0x9f, 0x7b, 0x9c, 0x1b, 0xbf, 0xdf, - 0x33, 0x8b, 0xbf, 0xc4, 0x06, 0xf7, 0xff, 0xcf, 0xff, 0x1f, 0xf3, 0xf3, - 0xfc, 0x15, 0xd0, 0xfd, 0xf3, 0x9b, 0xfd, 0xf2, 0x45, 0xcc, 0x9e, 0xbc, - 0xf3, 0x9b, 0x24, 0xf6, 0x9e, 0x7b, 0x9c, 0x1b, 0xc7, 0xcf, 0x5b, 0xc4, - 0x9e, 0x5b, 0xfe, 0xcf, 0xfe, 0xce, 0xff, 0x1f, 0xd2, 0xeb, 0x58, 0xf8, - 0xfe, 0x6b, 0xbf, 0x77, 0xfc, 0x15, 0xcc, 0xfe, 0x73, 0x9b, 0x2f, 0xf0, - 0x93, 0xee, 0x9f, 0x7c, 0x3f, 0xc4, 0x33, 0xf4, 0x94, 0xee, 0xfe, 0xcd, - 0xbf, 0x4c, 0x00, 0x1c, 0x06, 0x04, 0x37, 0xf8, 0xff, 0xcf, 0xff, 0x1f, - 0x18, 0xf4, 0xfc, 0x15, 0x16, 0xfd, 0xf3, 0x9b, 0x7c, 0x92, 0x58, 0xf2, - 0x5f, 0xee, 0x9e, 0x72, 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, 0x37, 0xff, - 0x9e, 0x52, 0x97, 0xb4, 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0xeb, 0xff, - 0x9c, 0x5a, 0x9e, 0x7a, 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, - 0x9e, 0x5a, 0x9e, 0x6b, 0xbf, 0x7c, 0xbd, 0x1b, 0xe0, 0xdf, 0x9f, 0x6a, - 0xc6, 0xef, 0xb2, 0xbd, 0x3b, 0x97, 0x37, 0x93, 0x9f, 0x4a, 0x9d, 0x72, - 0x78, 0xc4, 0x77, 0xc4, 0x57, 0xc4, 0x9d, 0x52, 0x9e, 0x6b, 0x9f, 0x7c, - 0xab, 0xc4, 0xad, 0xf2, 0xa6, 0xc4, 0x98, 0xf4, 0x9c, 0x7a, 0x9c, 0x1b, - 0x83, 0xcf, 0x5c, 0xc4, 0x9c, 0x5a, 0x9e, 0xf8, 0xff, 0x1f, 0x25, 0xf1, - 0xbc, 0xc7, 0x14, 0xf3, 0x58, 0xef, 0x21, 0xa2, 0xff, 0xce, 0x9f, 0x79, - 0xce, 0xd6, 0x3b, 0x97, 0x9f, 0x59, 0xff, 0xcf, 0xff, 0x1f, 0xa7, 0xfc, - 0x07, 0xcf, 0xf0, 0xfb, 0xa3, 0xb6, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xdf, - 0x3b, 0xff, 0xff, 0xdf, 0x4b, 0xfe, 0xff, 0xdf, 0x9b, 0xff, 0xff, 0xdf, - 0x47, 0xfe, 0xff, 0xdf, 0x00, 0xe0, 0x03, 0x00, 0xff, 0x1f, 0x4f, 0xfc, - 0x9e, 0x72, 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, 0x73, 0xff, 0x9e, 0x52, - 0x97, 0xb4, 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0xc7, 0xff, 0x9c, 0x5a, - 0x9e, 0x7a, 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5a, - 0x9f, 0x6a, 0xb4, 0xec, 0x37, 0x97, 0x50, 0xc4, 0x4f, 0xc4, 0x9f, 0x4a, - 0x9d, 0x72, 0x78, 0xc4, 0x77, 0xc4, 0x57, 0xc4, 0x9d, 0x52, 0xf4, 0xcf, - 0xff, 0xce, 0xf7, 0xcd, 0x5a, 0xec, 0xff, 0x1f, 0x58, 0xfc, 0xfa, 0x1b, - 0xd6, 0xff, 0xff, 0xce, 0xbc, 0xec, 0xff, 0x1f, 0xf6, 0xf0, 0xbf, 0xc7, - 0x0e, 0xf5, 0xfa, 0x27, 0xd5, 0xff, 0xf2, 0xce, 0xa1, 0xa2, 0xff, 0x1f, - 0xa2, 0xf0, 0x15, 0xf9, 0x9f, 0x7b, 0xbe, 0xc4, 0xbf, 0xf2, 0x44, 0xed, - 0x9e, 0x7a, 0xbc, 0x1b, 0xe0, 0xdf, 0xd2, 0xc5, 0xeb, 0xf4, 0xab, 0xc5, - 0x61, 0xf2, 0x9f, 0x7a, 0xff, 0xdc, 0x33, 0x8b, 0xfd, 0xce, 0x3b, 0x9b, - 0x9f, 0x5a, 0xf4, 0xf4, 0xab, 0xc5, 0x48, 0xf2, 0xa6, 0xc5, 0x4a, 0xf2, - 0xae, 0xc5, 0xbf, 0x17, 0xea, 0xfd, 0xf0, 0xcf, 0xff, 0xce, 0xff, 0xcd, - 0xff, 0x1f, 0xcd, 0xfa, 0x30, 0xed, 0x9e, 0x79, 0x7f, 0xc4, 0x9e, 0x59, - 0x9e, 0x72, 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, 0x37, 0xff, 0x9e, 0x52, - 0x97, 0xb4, 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0xc7, 0xff, 0x9c, 0x5a, - 0x9e, 0x7a, 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5a, - 0x9f, 0x79, 0x3f, 0xc4, 0x96, 0xf6, 0xf3, 0xcd, 0x9f, 0x6a, 0xc0, 0xee, - 0xb2, 0xbd, 0x3b, 0x97, 0x37, 0x93, 0x9f, 0x4a, 0x9d, 0x72, 0x78, 0xc4, - 0x77, 0xc4, 0x57, 0xc4, 0x9d, 0x52, 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, - 0xf4, 0xff, 0x9b, 0x5a, 0xff, 0xcc, 0x9f, 0x5a, 0x2d, 0xf9, 0x9e, 0x7b, - 0x9c, 0x1b, 0xc7, 0xcf, 0x9e, 0x5b, 0xfe, 0xcf, 0xff, 0xce, 0xff, 0x1f, - 0xbe, 0xec, 0x44, 0xf9, 0x8b, 0xee, 0xff, 0xce, 0xbf, 0x7c, 0x80, 0xd6, - 0x7b, 0x93, 0xbf, 0x5c, 0x4b, 0xf9, 0x9e, 0x7b, 0x9c, 0x1b, 0xc7, 0xcf, - 0x5c, 0xc4, 0x9e, 0x5b, 0xfc, 0xf8, 0x53, 0xee, 0x9f, 0x5a, 0x15, 0xa3, - 0xbf, 0x78, 0xc0, 0xce, 0xb5, 0x9b, 0x7a, 0xf2, 0x7b, 0x9b, 0x9a, 0xf2, - 0xa0, 0xc5, 0x4e, 0xf2, 0xd0, 0xcc, 0x35, 0x9b, 0x74, 0xf2, 0xbe, 0x7a, - 0xbd, 0x1b, 0xe0, 0xdf, 0xab, 0xc5, 0xf9, 0xf3, 0xf0, 0xcf, 0xff, 0xce, - 0xff, 0xcd, 0xff, 0x1f, 0x28, 0xfb, 0x3d, 0xee, 0x9e, 0x72, 0x9c, 0x1b, - 0x03, 0xcc, 0x9c, 0x13, 0x37, 0xff, 0x9e, 0x52, 0x97, 0xb4, 0x9c, 0x1b, - 0x83, 0xcf, 0x9c, 0x13, 0xc7, 0xff, 0x9c, 0x5a, 0x9e, 0x7a, 0x9c, 0x1b, - 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5a, 0x9f, 0x79, 0x3f, 0xc4, - 0xc1, 0xf2, 0xef, 0xcd, 0x9f, 0x6a, 0xcc, 0xef, 0xb2, 0xbd, 0x3b, 0x97, - 0x37, 0x93, 0x9f, 0x4a, 0x9d, 0x72, 0x78, 0xc4, 0x77, 0xc4, 0x57, 0xc4, - 0x9d, 0x52, 0x7e, 0xf9, 0x51, 0xef, 0x21, 0xa2, 0x9f, 0x79, 0x9c, 0x13, - 0xce, 0xff, 0x9f, 0x59, 0xfd, 0xcf, 0xff, 0x1f, 0x90, 0xfd, 0x9e, 0x72, - 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, 0x73, 0xff, 0x9e, 0x52, 0x97, 0xb4, - 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0xf3, 0xff, 0x9c, 0x5a, 0x9e, 0x7a, - 0x9c, 0x1b, 0xe0, 0xcf, 0xf5, 0xfb, 0xff, 0xff, 0x00, 0xe0, 0x03, 0x00, - 0xa3, 0xff, 0xff, 0xdf, 0x17, 0xf1, 0xff, 0xff, 0x9b, 0xff, 0xff, 0xdf, - 0x9c, 0x13, 0xf4, 0xff, 0x9e, 0x5a, 0x9f, 0x6a, 0xcf, 0xec, 0x1f, 0xcd, - 0x3b, 0x97, 0xb6, 0xbd, 0x37, 0x93, 0x9f, 0x4a, 0x9d, 0x72, 0x78, 0xc4, - 0x77, 0xc4, 0x58, 0xc4, 0x9d, 0x52, 0xbe, 0x79, 0x7f, 0xc5, 0x9c, 0x1b, - 0xe0, 0xcf, 0xbe, 0x59, 0x5d, 0xc4, 0xff, 0x15, 0x40, 0xfe, 0x9b, 0x5a, - 0xff, 0x1f, 0x59, 0xfd, 0x9e, 0x72, 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, - 0x73, 0xff, 0x9e, 0x52, 0x97, 0xb4, 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, - 0xe7, 0xff, 0x9c, 0x5a, 0x9e, 0x7a, 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, - 0xf4, 0xff, 0x9e, 0x5a, 0x9f, 0x6a, 0xc3, 0xed, 0x1f, 0xcd, 0x3b, 0x97, - 0xb6, 0xbd, 0x37, 0x93, 0x9f, 0x4a, 0x9d, 0x72, 0x78, 0xc4, 0x77, 0xc4, - 0x58, 0xc4, 0x9d, 0x52, 0x0a, 0xf9, 0xee, 0x7a, 0xb0, 0xc7, 0x63, 0xf3, - 0xfe, 0x15, 0x47, 0xf4, 0xff, 0xcd, 0xff, 0x1f, 0xa2, 0xf1, 0xcc, 0xed, - 0x81, 0xa6, 0xfe, 0x7c, 0x5f, 0xc7, 0xdf, 0x3b, 0xdd, 0xd7, 0x7d, 0xc5, - 0xbe, 0x5c, 0xdb, 0xd9, 0xbd, 0x74, 0x39, 0x1b, 0x00, 0xdc, 0xbd, 0x1b, - 0x00, 0xcc, 0x67, 0x93, 0xbd, 0x54, 0xbf, 0x7c, 0x3f, 0xc5, 0x9f, 0x17, - 0x02, 0x02, 0xff, 0xcd, 0xf8, 0xd5, 0xf7, 0x97, 0xfe, 0x5c, 0x9c, 0x7e, - 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0xd7, 0xff, 0x9c, 0x5e, 0xff, 0x15, - 0x4c, 0xfe, 0xff, 0x1f, 0x50, 0xf0, 0x32, 0xcf, 0xff, 0x1f, 0xa5, 0xfd, - 0xff, 0x17, 0x15, 0x02, 0xfe, 0xcf, 0xff, 0x1f, 0x36, 0xf8, 0xff, 0x17, - 0x1a, 0x02, 0xff, 0xcf, 0xff, 0x1f, 0xb3, 0xf2, 0xff, 0x17, 0x1f, 0x02, - 0x00, 0x1c, 0x25, 0x06, 0xfd, 0xcc, 0x6b, 0x52, 0x9a, 0x23, 0xd4, 0xff, - 0xff, 0x17, 0x27, 0x02, 0x45, 0xcc, 0xf3, 0x9b, 0xab, 0xf7, 0x9e, 0x7b, - 0x9c, 0x1b, 0xc7, 0xcf, 0x9c, 0x13, 0xe7, 0xff, 0x9e, 0x5b, 0xdd, 0xf9, - 0x4e, 0xee, 0x9e, 0x7a, 0x9c, 0x1b, 0xe0, 0xdf, 0xd0, 0xc4, 0xf7, 0xf3, - 0x9f, 0x7a, 0xff, 0xdc, 0x33, 0x8b, 0xfb, 0xcd, 0x37, 0x9b, 0x9f, 0x5a, - 0x26, 0xf3, 0x8f, 0x7a, 0x9c, 0x1b, 0xfb, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, - 0x37, 0xee, 0x9f, 0x17, 0x38, 0x02, 0x9e, 0x79, 0x9c, 0x1b, 0xe0, 0xdf, - 0xb0, 0xc4, 0x1e, 0xf3, 0xaf, 0xc4, 0x9f, 0x17, 0x40, 0x02, 0xff, 0xcf, - 0xff, 0x1f, 0xff, 0xf5, 0xfc, 0x15, 0x40, 0xfe, 0xf3, 0x9b, 0x9f, 0x17, - 0x48, 0x02, 0x81, 0xa1, 0xbc, 0x7c, 0xdd, 0x1b, 0xfb, 0xdf, 0xbf, 0xc6, - 0x9f, 0x17, 0x4f, 0x02, 0x5d, 0xc5, 0xdf, 0x59, 0xfa, 0xcf, 0xbc, 0x5c, - 0xfe, 0xce, 0xff, 0x1f, 0xe0, 0xed, 0xff, 0x15, 0x65, 0xfd, 0xff, 0x1f, - 0xa8, 0xf0, 0xff, 0x17, 0x5c, 0x02, 0xbe, 0x79, 0xfe, 0xdd, 0x77, 0x8b, - 0xfe, 0xc5, 0x48, 0xf3, 0x4d, 0xef, 0xbf, 0x7a, 0xff, 0xdd, 0x77, 0x8b, - 0xfb, 0xce, 0x7b, 0x9b, 0xbf, 0x5a, 0x9f, 0x17, 0x6a, 0x02, 0x9f, 0x5a, - 0x00, 0x1c, 0xf9, 0x05, 0xff, 0x17, 0x6f, 0x02, 0x9e, 0x7b, 0x9c, 0x1b, - 0xc7, 0xcf, 0x5a, 0xc4, 0x9e, 0x5b, 0xff, 0x17, 0x2f, 0x02, 0xfa, 0x1b, - 0xef, 0xff, 0xfe, 0xce, 0xb8, 0xef, 0xff, 0x1f, 0x9a, 0xf2, 0xbf, 0xc7, - 0x9c, 0xf4, 0xee, 0x7a, 0xa3, 0xf8, 0xef, 0xcd, 0x67, 0xf9, 0xff, 0xff, - 0x00, 0xe0, 0x03, 0x00, 0xa3, 0xff, 0xff, 0xdf, 0x6f, 0xf1, 0xff, 0xff, - 0xc1, 0xa2, 0xfe, 0x7e, 0xff, 0x1b, 0xf9, 0xdf, 0xbd, 0xc7, 0xa1, 0xf5, - 0xff, 0xcd, 0xbf, 0x5a, 0xbe, 0x72, 0xbd, 0x1b, 0x03, 0xcc, 0xbd, 0x13, - 0x37, 0xff, 0xbe, 0x52, 0xb7, 0xb5, 0xbd, 0x1b, 0x83, 0xcf, 0x9c, 0x1b, - 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, 0xbd, 0x13, 0xc7, 0xff, 0xbc, 0x5a, - 0x9e, 0x5a, 0x9f, 0x7e, 0x3f, 0xc4, 0x78, 0xf3, 0xef, 0xcc, 0xbf, 0x6a, - 0xdd, 0xec, 0x92, 0xbc, 0x7b, 0x97, 0x34, 0xf9, 0x3e, 0xec, 0xa8, 0xf9, - 0xf3, 0xcd, 0x3c, 0xf9, 0xb0, 0xce, 0xb5, 0x9b, 0xc6, 0xf3, 0xa0, 0xcc, - 0x35, 0x9b, 0x63, 0xf5, 0xbe, 0x78, 0xb3, 0xcc, 0x35, 0x9b, 0x67, 0xf5, - 0xbd, 0x78, 0x9c, 0x78, 0x8f, 0xbc, 0xa7, 0xbd, 0x73, 0x93, 0x9a, 0x78, - 0x73, 0x93, 0x9b, 0x78, 0x97, 0xbc, 0x73, 0x93, 0x89, 0xed, 0x35, 0x9b, - 0x51, 0xf3, 0xd9, 0xa0, 0xf2, 0xcf, 0xfb, 0xcd, 0xff, 0x1f, 0x99, 0xfc, - 0x2e, 0xed, 0x70, 0xf9, 0x9e, 0x78, 0xc4, 0xce, 0xb1, 0x9b, 0x9c, 0xf3, - 0x71, 0x9b, 0x81, 0xf5, 0xcd, 0xa3, 0xf2, 0xcf, 0xfd, 0xcd, 0xff, 0x1f, - 0xa6, 0xfc, 0x21, 0xa2, 0x7d, 0xf9, 0x9e, 0x78, 0xb4, 0xc4, 0x8b, 0xf5, - 0x9d, 0x78, 0xd1, 0x1b, 0xde, 0xff, 0x9f, 0x5e, 0x21, 0xa2, 0xf9, 0xcf, - 0xff, 0xcd, 0xff, 0x1f, 0xb4, 0xfc, 0x9e, 0x79, 0x7f, 0xc4, 0x9e, 0x59, - 0x8d, 0xf9, 0xbe, 0x7a, 0xbd, 0x1b, 0xe0, 0xdf, 0xad, 0xc5, 0xa0, 0xf3, - 0x9e, 0x78, 0x49, 0xce, 0xb1, 0x9b, 0xab, 0xf3, 0x48, 0xce, 0xb1, 0x9b, - 0xa1, 0xf5, 0xcd, 0xa3, 0xf5, 0xcf, 0xfc, 0xcd, 0xff, 0x1f, 0xc9, 0xfc, - 0x21, 0xa2, 0xa0, 0xf9, 0xbe, 0x78, 0x00, 0xcc, 0x35, 0x9b, 0xaf, 0xf1, - 0xbf, 0x79, 0xf7, 0xcf, 0xa0, 0x93, 0xff, 0x1f, 0xd4, 0xfc, 0x21, 0xa2, - 0xab, 0xf9, 0xff, 0xcc, 0x9f, 0x5a, 0x00, 0x1c, 0x98, 0x06, 0xdb, 0xf8, - 0xd1, 0x1b, 0xde, 0xff, 0xc4, 0xcc, 0x9f, 0x5e, 0xfe, 0xcd, 0xf0, 0xcf, - 0xff, 0x1f, 0xe3, 0xfc, 0xff, 0x17, 0x15, 0x02, 0x52, 0xee, 0x9f, 0x5a, - 0x00, 0x1c, 0xa7, 0x06, 0xff, 0x17, 0x1d, 0x03, 0xfc, 0xcf, 0xff, 0x1f, - 0xdc, 0xf6, 0x66, 0xcc, 0x9e, 0xbc, 0xf3, 0x9b, 0xf5, 0xf3, 0xff, 0xce, - 0xff, 0xcd, 0xfc, 0xcf, 0xff, 0x1f, 0xf7, 0xfc, 0xff, 0x17, 0x2b, 0x03, - 0xf3, 0xcc, 0x85, 0xf8, 0xff, 0x15, 0x60, 0xfe, 0xff, 0x1f, 0xd1, 0xfe, - 0xff, 0x17, 0x33, 0x03, 0xbd, 0x78, 0x9c, 0x78, 0xb7, 0xbd, 0x37, 0x93, - 0xd1, 0x1b, 0xde, 0xff, 0x9f, 0x56, 0xfb, 0xcf, 0xff, 0xcd, 0x21, 0xa2, - 0xff, 0x1f, 0x0d, 0xfd, 0x9f, 0x79, 0x3f, 0xc4, 0xe5, 0xf5, 0x9e, 0x79, - 0x5f, 0xc4, 0x9e, 0x59, 0xe9, 0xf9, 0xcd, 0xa3, 0xf6, 0xcf, 0xfc, 0xcd, - 0xff, 0x1f, 0x19, 0xfd, 0x21, 0xa2, 0xf0, 0xf9, 0x11, 0x1b, 0xde, 0xff, - 0x9f, 0x58, 0xfe, 0xe4, 0xf0, 0x93, 0x9f, 0x47, 0x00, 0x1c, 0x21, 0x0a, - 0xdd, 0x79, 0xbc, 0x79, 0xaf, 0xbd, 0xc7, 0xbe, 0xb7, 0x93, 0xba, 0x79, - 0xb7, 0x93, 0xbb, 0x79, 0xb7, 0xbd, 0x9f, 0x67, 0x7b, 0x93, 0x9f, 0x6c, - 0x35, 0x9b, 0xe5, 0xf3, 0xfa, 0xcf, 0xa0, 0x93, 0xff, 0xcd, 0xff, 0x1f, - 0x36, 0xfd, 0x3c, 0xef, 0xff, 0x17, 0x0d, 0x02, 0x00, 0xe0, 0x03, 0x00, - 0x9b, 0xff, 0xff, 0xdf, 0xfe, 0xfe, 0xfe, 0xf9, 0xa3, 0xff, 0xff, 0xdf, - 0x00, 0x1c, 0xc7, 0x08, 0x6f, 0xcc, 0x99, 0xbc, 0x3d, 0x9b, 0xb1, 0xf4, - 0xff, 0x1f, 0x31, 0xff, 0xb4, 0xf8, 0xfe, 0xcc, 0x9f, 0x58, 0x8f, 0x7a, - 0x5d, 0xc4, 0x8f, 0x5a, 0x1d, 0xf8, 0xff, 0xff, 0x2c, 0xeb, 0xde, 0xeb, - 0xff, 0x1f, 0xf7, 0xf6, 0xff, 0x47, 0x4e, 0xee, 0xff, 0xcf, 0xff, 0x1f, - 0x48, 0xf7, 0x9f, 0x7a, 0xfe, 0xc4, 0xc4, 0x92, 0xb3, 0xf3, 0xbd, 0xc4, - 0xc8, 0xf3, 0xbc, 0xc4, 0xce, 0xf3, 0xfc, 0xcf, 0xff, 0x1f, 0x53, 0xf7, - 0xb8, 0xbf, 0x9d, 0xbf, 0x92, 0xa5, 0xff, 0xa4, 0xff, 0x3b, 0xbf, 0xf7, - 0x9d, 0xbf, 0x95, 0xac, 0x9c, 0x3b, 0xde, 0x7b, 0x97, 0xb4, 0xba, 0xee, - 0x9c, 0x1b, 0x01, 0xde, 0x93, 0xa5, 0xbf, 0x7c, 0x9e, 0x7c, 0x7b, 0x83, - 0xdc, 0xbc, 0x9e, 0x3b, 0xdc, 0xf7, 0xdf, 0x6b, 0x9b, 0xa4, 0xaf, 0xb5, - 0x97, 0xa4, 0x9f, 0x4b, 0x9f, 0x7a, 0x21, 0xef, 0x9c, 0xbc, 0x93, 0xa1, - 0xdf, 0x74, 0xc4, 0x93, 0xde, 0xbe, 0xff, 0xcd, 0x00, 0x1c, 0x8b, 0x09, - 0x9f, 0x7a, 0x9c, 0xbc, 0x33, 0xa1, 0xff, 0x6b, 0x9e, 0x69, 0xf3, 0x83, - 0xf0, 0xb7, 0xfe, 0xeb, 0x6c, 0xeb, 0x7d, 0xcd, 0xbd, 0xbd, 0xf7, 0x9b, - 0x32, 0xf0, 0xdf, 0x6b, 0xb5, 0xb6, 0x77, 0x8b, 0xf0, 0xcf, 0x7f, 0x9b, - 0xe9, 0xf3, 0xee, 0xef, 0xbf, 0x3b, 0xdd, 0xf7, 0xfe, 0x7d, 0xbf, 0x7d, - 0x3c, 0xbf, 0xb7, 0x83, 0xf9, 0x3b, 0xdf, 0xf7, 0xd8, 0xb6, 0xfb, 0xa7, - 0xff, 0x4b, 0x27, 0xf8, 0xdf, 0x67, 0xb5, 0xb6, 0x77, 0x8b, 0xf6, 0xcf, - 0x7f, 0x9b, 0xfa, 0xf3, 0xf7, 0xef, 0x12, 0xf8, 0xf0, 0xcd, 0x15, 0xf8, - 0xf6, 0xcd, 0xf9, 0xef, 0x17, 0xf8, 0xff, 0xff, 0x77, 0xff, 0xff, 0xdf, - 0xfb, 0xff, 0xff, 0xdf, 0x53, 0xb6, 0xff, 0xff, 0x73, 0xb6, 0xff, 0xff, - 0x87, 0xb6, 0xff, 0xff, 0x9d, 0xef, 0xff, 0x5c, 0xc3, 0x87, 0xff, 0xff, - 0x77, 0xff, 0xff, 0xdf, 0xc3, 0x87, 0xff, 0xff, 0xff, 0x8b, 0xfc, 0xc7, - 0xbb, 0x8b, 0x77, 0x8b, 0xf9, 0xf7, 0x9b, 0xef, 0xfc, 0x3b, 0xdf, 0xf7, - 0xdf, 0x5f, 0xbe, 0x5f, 0xc3, 0x87, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, - 0x2f, 0xeb, 0x9f, 0x7f, 0xe0, 0xcd, 0x37, 0x9b, 0xe8, 0xf7, 0x81, 0xcd, - 0x37, 0x9b, 0xf3, 0xf7, 0x21, 0xcd, 0x37, 0x9b, 0xea, 0xf7, 0xdc, 0x1b, - 0x20, 0xef, 0xdd, 0xae, 0xe1, 0xde, 0xbb, 0x8b, 0xff, 0x1f, 0x0f, 0xf0, - 0x6f, 0xeb, 0xdc, 0x1b, 0xe0, 0xef, 0xdb, 0xae, 0xfd, 0xde, 0xbb, 0x8b, - 0xff, 0x1f, 0x17, 0xf0, 0x6f, 0xeb, 0xfd, 0xce, 0xff, 0x1f, 0x1b, 0xf0, - 0x6f, 0xeb, 0xdc, 0x1b, 0x80, 0xef, 0xdc, 0xae, 0xf7, 0xde, 0xbb, 0x8b, - 0xff, 0x1f, 0x23, 0xf0, 0x6f, 0xeb, 0xff, 0xff, 0x2f, 0xeb, 0xff, 0x1f, - 0x3c, 0xec, 0xff, 0x1f, 0x48, 0xf0, 0xff, 0x1f, 0xd2, 0xf2, 0xff, 0x1f, - 0xdc, 0xea, 0xff, 0x1f, 0x60, 0xef, 0xff, 0x1f, 0x28, 0xea, 0xff, 0x1f, - 0x20, 0xf3, 0xff, 0x1f, 0x2a, 0xea, 0x6f, 0xeb, 0x2f, 0xeb, 0xff, 0x1f, - 0x4a, 0xea, 0x6f, 0xeb, 0xfe, 0xcd, 0x9d, 0xef, 0xbf, 0x5c, 0xc3, 0x87, - 0x75, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0xf9, 0xef, 0xff, 0xcc, 0x9e, 0x57, - 0x9f, 0x5f, 0xfe, 0xce, 0xbb, 0xef, 0xfc, 0xdf, 0xff, 0x1f, 0x75, 0xf4, - 0x6f, 0xeb, 0xff, 0xff, 0x75, 0xff, 0xff, 0xdf, 0x63, 0xe3, 0xff, 0xff, - 0x9d, 0xef, 0xfe, 0x54, 0xc3, 0x87, 0xff, 0xff, 0x75, 0xff, 0xff, 0xdf, - 0xfe, 0x8b, 0xbf, 0xc7, 0x9a, 0xef, 0xfb, 0xf7, 0xbf, 0xcd, 0xba, 0x5c, - 0xc3, 0x87, 0xff, 0xcd, 0x80, 0xd5, 0xba, 0x5c, 0xc3, 0x87, 0xff, 0xff, - 0x75, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xfe, 0x74, 0xc3, 0x87, 0xff, 0xff, - 0x75, 0xff, 0xff, 0xdf, 0x2b, 0xeb, 0xd6, 0xeb, 0xbf, 0xc6, 0x38, 0x93, - 0x7f, 0x8a, 0xf6, 0x8a, 0xf6, 0xf3, 0xa7, 0xed, 0xfb, 0x7d, 0xac, 0x93, - 0x70, 0x93, 0xff, 0x1f, 0x46, 0xf4, 0xf6, 0xeb, 0x6b, 0xeb, 0xef, 0xcf, - 0x00, 0x1c, 0x97, 0x0a, 0xbc, 0x92, 0xff, 0xcf, 0xff, 0x1f, 0x49, 0xf8, - 0xe3, 0xc1, 0xbc, 0x93, 0xe7, 0xf7, 0x8f, 0xed, 0x3c, 0x3b, 0xbc, 0xf7, - 0x9f, 0x6c, 0xf3, 0x87, 0xfe, 0xcc, 0x9f, 0x5a, 0xbe, 0x8b, 0xfc, 0x15, - 0xd9, 0xfd, 0xb3, 0x9b, 0xfd, 0xf7, 0xb0, 0x93, 0x9a, 0xbe, 0x9b, 0xa4, - 0xb9, 0xbc, 0x97, 0xa4, 0x9e, 0x3b, 0xde, 0xf7, 0x9c, 0xbe, 0x9a, 0xa4, - 0x8f, 0xac, 0x9e, 0x5a, 0x3c, 0xed, 0xfb, 0x79, 0xac, 0x93, 0x68, 0x93, - 0xff, 0x1f, 0x6f, 0xf4, 0xf6, 0xeb, 0x6b, 0xeb, 0xe7, 0xcc, 0x9f, 0x5a, - 0xff, 0x1f, 0xb7, 0xfe, 0x9f, 0x7f, 0xb3, 0xcd, 0x71, 0x9b, 0xdc, 0xf3, - 0xc0, 0xce, 0xb1, 0x9b, 0xdf, 0xf3, 0xbe, 0x5a, 0x26, 0xee, 0x13, 0xf8, - 0xe7, 0xcc, 0x9f, 0x5a, 0xff, 0xcc, 0xb7, 0xd4, 0x9e, 0x5a, 0x29, 0xee, - 0x1a, 0xf8, 0xe7, 0xcc, 0x9f, 0x5a, 0xff, 0xcc, 0xb6, 0xd4, 0x9e, 0x5a, - 0x2d, 0xee, 0x21, 0xf8, 0xff, 0x1f, 0xd1, 0xfe, 0x9f, 0x7f, 0xd7, 0xcd, - 0x71, 0x9b, 0x9f, 0x5a, 0x5c, 0xf3, 0x37, 0x9b, 0x69, 0xf3, 0xe8, 0xd4, - 0xfe, 0xcd, 0x37, 0x9b, 0x2f, 0xf0, 0x9e, 0x7f, 0x9e, 0x5a, 0x32, 0xf8, - 0xc7, 0xcc, 0x9f, 0x5a, 0xf5, 0xcc, 0x9e, 0x5a, 0xff, 0x1f, 0xe5, 0xfe, - 0x9f, 0x7f, 0xbf, 0xc4, 0x6a, 0xf3, 0xff, 0xdf, 0x9d, 0x5a, 0x9f, 0x7f, - 0x9c, 0x5a, 0x3c, 0xee, 0x40, 0xf8, 0xfe, 0xe1, 0xe4, 0x93, 0x00, 0x1c, - 0xba, 0x0b, 0xff, 0xce, 0xa4, 0xd6, 0xba, 0x69, 0x99, 0x69, 0xdf, 0x5a, - 0xf7, 0xce, 0xde, 0x5a, 0xc7, 0xb5, 0xdd, 0x5a, 0xcf, 0xb5, 0xdc, 0x5a, - 0xba, 0x5a, 0xd7, 0xb5, 0xa7, 0xb4, 0xb9, 0x5a, 0xaf, 0xb4, 0xb8, 0x5a, - 0x96, 0x5a, 0xb7, 0xb4, 0xff, 0xcc, 0xdb, 0x5a, 0xb7, 0x5a, 0x95, 0x5a, - 0x94, 0x5a, 0x93, 0x5a, 0x2c, 0xef, 0x5f, 0xf8, 0xc7, 0xcc, 0x9f, 0x5a, - 0xc4, 0xcc, 0x9e, 0x5a, 0xfd, 0xcc, 0x9d, 0x5a, 0xff, 0xcc, 0xbb, 0xd4, - 0x9c, 0x5a, 0x31, 0xef, 0x6a, 0xf8, 0x00, 0x1c, 0x90, 0x01, 0xf7, 0xe6, - 0xf2, 0xc1, 0xff, 0x4e, 0x97, 0xf7, 0xfb, 0xcc, 0x9f, 0x5a, 0x9f, 0x6e, - 0x9e, 0x5a, 0x37, 0xef, 0xff, 0xcd, 0xf3, 0xcf, 0xff, 0x1f, 0xf1, 0xfe, - 0x7a, 0xf8, 0xfc, 0xcc, 0xb2, 0xc1, 0x9f, 0x5a, 0x1d, 0xa2, 0x90, 0xf3, - 0xfe, 0xcf, 0x3d, 0xef, 0xdf, 0x47, 0xfa, 0xfb, 0x75, 0xff, 0xff, 0xdf, - 0x33, 0xb6, 0xff, 0xff, 0xff, 0x1f, 0xef, 0xf8, 0xdf, 0x67, 0xfe, 0x71, - 0xfa, 0xa7, 0xf8, 0xbf, 0x00, 0x1c, 0xf3, 0x0b, 0xff, 0xcd, 0x81, 0xd5, - 0x7e, 0x9b, 0xfd, 0xf3, 0xf4, 0x93, 0x80, 0xcd, 0xf6, 0x9b, 0x3c, 0x93, - 0xfd, 0xf3, 0x80, 0xcc, 0xaf, 0xed, 0xbf, 0x7d, 0xbf, 0xc5, 0xf6, 0xf3, - 0xdb, 0xc4, 0x8f, 0xf3, 0xff, 0xcd, 0xfc, 0xd5, 0x72, 0x9b, 0xfc, 0xf3, - 0xff, 0xcc, 0xfb, 0xd4, 0x9f, 0x47, 0xff, 0x1f, 0x72, 0xfb, 0xbe, 0xc7, - 0x9f, 0x67, 0xb3, 0xf3, 0x99, 0x59, 0x33, 0x8b, 0x9f, 0x58, 0xaf, 0xf8, - 0xfd, 0xcc, 0x9f, 0x5a, 0xff, 0x1f, 0x9d, 0xf6, 0xfe, 0x5a, 0xff, 0xcf, - 0xff, 0x1f, 0x87, 0xf1, 0x3d, 0xed, 0xb9, 0xf8, 0xe7, 0xcc, 0x9f, 0x5a, - 0xf4, 0xcc, 0x9e, 0x5a, 0x20, 0xee, 0xbf, 0xf8, 0xb7, 0xcd, 0x71, 0x9b, - 0xcd, 0xf3, 0xa7, 0xcd, 0x71, 0x9b, 0xd2, 0xf3, 0xc7, 0xcd, 0x71, 0x9b, - 0xc9, 0xf4, 0x9c, 0x7f, 0x9c, 0x5a, 0x9d, 0x7f, 0x9d, 0x5a, 0x9e, 0x7f, - 0x9d, 0xf8, 0xff, 0xcc, 0x98, 0xd4, 0x9f, 0x5f, 0xc5, 0xcd, 0xff, 0xdf, - 0xbf, 0x5f, 0x9c, 0x1b, 0x67, 0xdf, 0x9a, 0xf8, 0xce, 0xcc, 0xb1, 0xc1, - 0x9f, 0x5a, 0xbf, 0xf3, 0xb0, 0xc1, 0xcb, 0xf3, 0xff, 0xcc, 0x9e, 0x5a, - 0x31, 0xee, 0x99, 0x79, 0x31, 0x8b, 0xde, 0xc4, 0xca, 0xf7, 0x9f, 0x6e, - 0x9c, 0x1b, 0x71, 0xfd, 0x9f, 0x4e, 0x97, 0xb4, 0x9d, 0x5a, 0x9f, 0x6e, - 0x9c, 0x5a, 0x76, 0xf8, 0xff, 0xcc, 0x38, 0xee, 0x9f, 0x58, 0xf1, 0xf8, - 0x9a, 0x7f, 0x9a, 0x5a, 0x9b, 0x7f, 0x9b, 0x5a, 0x2c, 0xf8, 0xbf, 0x79, - 0xbf, 0xc5, 0xf8, 0xf3, 0xbe, 0xc4, 0xc5, 0xf3, 0xff, 0xcd, 0xff, 0xd5, - 0x71, 0x9b, 0xcc, 0xf3, 0xbf, 0xc4, 0x54, 0xf4, 0xba, 0x79, 0xbf, 0xc5, - 0x57, 0xf0, 0xb5, 0x8b, 0x20, 0xc6, 0xcf, 0xf7, 0x39, 0xc5, 0xfc, 0xf3, - 0xff, 0xcc, 0xff, 0xd4, 0xff, 0xcd, 0xba, 0x59, 0x61, 0xf8, 0xfa, 0xcc, - 0x69, 0xf8, 0xfd, 0xcc, 0x9e, 0x5a, 0x9f, 0x6e, 0x9c, 0x1b, 0x0c, 0xee, - 0x9f, 0x4e, 0x2c, 0xef, 0x2e, 0xf8, 0x9f, 0x6e, 0x30, 0xf8, 0xfe, 0xcc, - 0x9e, 0x5a, 0xdf, 0x47, 0x00, 0x1c, 0x1b, 0x0b, 0x3f, 0x8b, 0x87, 0xcd, - 0x71, 0x9b, 0xdf, 0x67, 0xf6, 0xf3, 0xaf, 0xcd, 0x71, 0x9b, 0xf9, 0xf3, - 0xfc, 0x15, 0x47, 0xf4, 0x9f, 0x4e, 0x36, 0xef, 0x42, 0xf8, 0xfc, 0x15, - 0xa1, 0xf5, 0x9f, 0x4e, 0x39, 0xef, 0x47, 0xf8, 0xff, 0xcc, 0xfe, 0xd4, - 0x87, 0xf8, 0xfd, 0xcc, 0x89, 0xf8, 0xfe, 0xcc, 0x2b, 0xf8, 0xff, 0xff, - 0x95, 0xff, 0xff, 0xdf, 0x75, 0xff, 0xff, 0xdf, 0x2e, 0xeb, 0xff, 0x8a, - 0xf0, 0xcf, 0x00, 0x1c, 0xfa, 0x0b, 0xbf, 0xc7, 0xbc, 0x93, 0xfb, 0xf3, - 0xec, 0x93, 0xff, 0x1f, 0x9e, 0xed, 0x6e, 0xeb, 0x9d, 0xef, 0xf9, 0x7c, - 0xc3, 0x87, 0xff, 0xff, 0x75, 0xff, 0xff, 0xdf, 0xfe, 0xef, 0xc3, 0x87, - 0x6a, 0xff, 0xff, 0xdf, 0x2d, 0xeb, 0x8a, 0xef, 0xb8, 0x6c, 0x6a, 0xef, - 0x5f, 0xc5, 0xb8, 0x4c, 0xff, 0xca, 0xfb, 0x1b, 0xf4, 0xff, 0xff, 0xce, - 0xf3, 0xcd, 0x58, 0x5b, 0x57, 0x5b, 0x00, 0x1c, 0xea, 0x0b, 0x9b, 0x1b, - 0xe8, 0xff, 0xb0, 0xef, 0xbe, 0x4c, 0xfc, 0xcd, 0xbd, 0x5c, 0x5f, 0x5c, - 0x5e, 0x5c, 0x98, 0x7b, 0x5f, 0xc4, 0xfb, 0x1b, 0xdc, 0xff, 0xff, 0xce, - 0xb5, 0xef, 0x98, 0x5b, 0xff, 0x1f, 0x3b, 0xf6, 0xbf, 0xc7, 0xfd, 0xf3, - 0x6d, 0xeb, 0xfb, 0x27, 0xdb, 0xff, 0xea, 0xce, 0xa5, 0xa3, 0xff, 0x1f, - 0xe8, 0xf5, 0x6d, 0xeb, 0xff, 0x6f, 0xff, 0xbf, 0x6b, 0xff, 0xff, 0xdf, - 0x4b, 0xff, 0xff, 0xdf, 0x67, 0xdc, 0xff, 0xff, 0x2e, 0xeb, 0xff, 0x8a, - 0xb3, 0xc3, 0x77, 0x8b, 0xe5, 0xf3, 0xeb, 0xc3, 0xec, 0xf3, 0x89, 0xee, - 0xbe, 0x7c, 0x77, 0x8b, 0xdd, 0x7c, 0xff, 0xdd, 0x7b, 0x97, 0xdf, 0x7c, - 0xbb, 0x8b, 0xb5, 0x9b, 0xa1, 0xf3, 0xde, 0x7c, 0xfe, 0x6c, 0xbb, 0x8b, - 0xdb, 0xa7, 0x7f, 0x5e, 0xfe, 0xcf, 0xbe, 0x5c, 0x6e, 0xeb, 0x91, 0xee, - 0x7c, 0x3b, 0xbc, 0xf7, 0x9f, 0x6c, 0xf3, 0x87, 0x93, 0xee, 0x8f, 0xa4, - 0xbf, 0x7c, 0x3a, 0xc5, 0xfb, 0xf3, 0xbf, 0x6e, 0xbb, 0x54, 0x1d, 0xf8, - 0xff, 0xcf, 0x6e, 0xeb, 0xbf, 0xc5, 0x21, 0xf0, 0xbf, 0x7e, 0x98, 0xee, - 0xb9, 0x5c, 0x25, 0xf8, 0xbf, 0x76, 0x9a, 0xee, 0xba, 0x54, 0x29, 0xf8, - 0xbf, 0xc5, 0x2b, 0xf0, 0xbf, 0x7e, 0x9d, 0xee, 0xba, 0x5c, 0x2f, 0xf8, - 0xfa, 0xcc, 0x73, 0x9b, 0xf8, 0xf7, 0xfa, 0xcd, 0xf8, 0x93, 0xc2, 0xef, - 0x00, 0x1c, 0x9f, 0x0c, 0x38, 0xf8, 0xbf, 0xc5, 0x3a, 0xf0, 0x06, 0xf8, - 0xbf, 0x7e, 0x85, 0xef, 0xbf, 0xc5, 0xff, 0x3b, 0xfe, 0xfa, 0xbf, 0x7c, - 0xde, 0xbe, 0x7e, 0xc5, 0x7b, 0x93, 0xbf, 0x5c, 0x46, 0xf8, 0xbf, 0x7e, - 0x8b, 0xef, 0xbd, 0x5c, 0x4a, 0xf8, 0xbf, 0x7e, 0x8d, 0xef, 0xbf, 0xc5, - 0xbf, 0x7c, 0xff, 0x3b, 0xfe, 0xfa, 0x7f, 0xc5, 0x7b, 0x93, 0xbf, 0x5c, - 0x54, 0xf8, 0xbf, 0x76, 0x92, 0xef, 0xb7, 0xb5, 0xbc, 0x5c, 0xbf, 0x76, - 0xbb, 0x5c, 0x5b, 0xf8, 0x95, 0xef, 0xdf, 0x7e, 0xbf, 0x7c, 0xde, 0x1b, - 0xfe, 0xdf, 0xdd, 0xbe, 0x7d, 0xc5, 0x7b, 0x93, 0xbf, 0x5c, 0x65, 0xf8, - 0xfe, 0xcf, 0x6e, 0xeb, 0x9b, 0xef, 0x4d, 0xf8, 0x53, 0xff, 0xff, 0xdf, - 0xbf, 0xb5, 0xff, 0xff, 0x6b, 0xff, 0xff, 0xdf, 0x5f, 0xff, 0xff, 0xdf, - 0x2f, 0xeb, 0xde, 0xeb, 0xd1, 0x1b, 0xfd, 0xff, 0xff, 0x5e, 0xfe, 0xcd, - 0xeb, 0xcf, 0x00, 0x1c, 0x80, 0x00, 0xfe, 0xeb, 0x6f, 0xeb, 0xff, 0xff, - 0x2c, 0xeb, 0x9c, 0xec, 0x7f, 0x6c, 0xef, 0x8a, 0x9b, 0x1b, 0x7f, 0xbf, - 0xef, 0xc4, 0xda, 0xf7, 0xbf, 0xec, 0x9d, 0x3b, 0xbc, 0xf7, 0x9f, 0x6c, - 0xf3, 0x87, 0xa2, 0xed, 0xde, 0x6d, 0x81, 0xed, 0xcf, 0xb6, 0xd9, 0x5c, - 0xde, 0x6d, 0xd7, 0xb6, 0xda, 0x5c, 0xde, 0x6d, 0xdb, 0x5c, 0xbf, 0x6d, - 0xa7, 0xb5, 0xbc, 0x5c, 0xa9, 0xed, 0xbf, 0x6d, 0xaf, 0xb5, 0xbd, 0x5c, - 0xab, 0xed, 0xbf, 0x6d, 0xb7, 0xb5, 0xbe, 0x5c, 0xfa, 0xcd, 0xab, 0x54, - 0xac, 0xed, 0xb4, 0x4c, 0xbb, 0x1b, 0x8c, 0xef, 0xbf, 0x5c, 0xed, 0xed, - 0xff, 0x1f, 0x5b, 0xf7, 0x4e, 0xed, 0x7a, 0x5a, 0x6c, 0xeb, 0x93, 0xed, - 0xdf, 0x6c, 0xbe, 0x6c, 0x87, 0xb6, 0x97, 0xbc, 0x77, 0x8b, 0x73, 0x93, - 0xfe, 0x15, 0x1e, 0xfd, 0x93, 0xed, 0x7b, 0x9b, 0xbe, 0x54, 0x9a, 0xf3, - 0xff, 0xce, 0xba, 0xed, 0xff, 0x6d, 0x5f, 0x6d, 0xff, 0x3b, 0x7d, 0x8f, - 0xfa, 0x3b, 0xba, 0x8f, 0xb7, 0xbd, 0xb7, 0x92, 0x5f, 0x54, 0xfc, 0x15, - 0x09, 0xfc, 0xb3, 0x9a, 0x9d, 0xf7, 0xbc, 0xed, 0x9f, 0x55, 0xff, 0x1f, - 0x4c, 0xf8, 0xbf, 0xc7, 0x7c, 0x92, 0x98, 0xf7, 0x43, 0xee, 0xfb, 0xcc, - 0xa1, 0xee, 0x8b, 0x52, 0xb4, 0x4a, 0xfa, 0x1b, 0xd8, 0xff, 0xff, 0x1f, - 0x8a, 0xf7, 0x3a, 0x23, 0xcf, 0xff, 0xfe, 0xcf, 0x00, 0x1c, 0x69, 0x00, - 0xf4, 0xda, 0x33, 0xf8, 0xf9, 0xcf, 0xff, 0x1f, 0x68, 0xf8, 0x4a, 0xee, - 0x38, 0xf8, 0x8f, 0xee, 0xff, 0x6c, 0xf7, 0xb7, 0xdf, 0x6c, 0xff, 0xd7, - 0xbf, 0x6c, 0xff, 0x8b, 0xfe, 0x3b, 0xbe, 0x8f, 0xa7, 0xb5, 0x00, 0x1c, - 0x2a, 0x03, 0xfd, 0xcf, 0xff, 0xce, 0xff, 0xcd, 0x00, 0x1c, 0xfb, 0x00, - 0x54, 0xee, 0x4b, 0xf8, 0xfe, 0xcf, 0xff, 0xce, 0xff, 0xcd, 0x00, 0x1c, - 0x02, 0x01, 0x57, 0xee, 0x52, 0xf8, 0x9c, 0xee, 0x9f, 0x6c, 0xfc, 0x3b, - 0x7c, 0x8f, 0xbf, 0xc4, 0xe2, 0xf3, 0x5b, 0xee, 0x9f, 0x7a, 0xbc, 0xb4, - 0xbd, 0x1b, 0xf9, 0xdf, 0x5f, 0xc5, 0xbc, 0xbd, 0x9c, 0x1b, 0xc7, 0xcf, - 0x37, 0x93, 0x9f, 0x5a, 0x64, 0xf8, 0xf4, 0xcf, 0xff, 0xce, 0xff, 0xcd, - 0x00, 0x1c, 0x1b, 0x01, 0x44, 0xef, 0x6b, 0xf8, 0x87, 0xef, 0x7c, 0xf8, - 0x88, 0xef, 0x82, 0xf8, 0x89, 0xef, 0x7c, 0xf8, 0xde, 0x54, 0xfe, 0xce, - 0x64, 0xf8, 0x49, 0xef, 0x9f, 0x7a, 0xbc, 0x1b, 0xef, 0xdf, 0x9c, 0x1b, - 0xc7, 0xcf, 0x37, 0x93, 0x9f, 0x5a, 0x7d, 0xf8, 0xbf, 0xc6, 0x5f, 0xf4, - 0xff, 0x1f, 0x37, 0xf5, 0xbf, 0x9a, 0xef, 0xf3, 0xeb, 0x9b, 0x65, 0xf4, - 0xff, 0xcf, 0x00, 0x1c, 0x06, 0x03, 0x69, 0xf8, 0x56, 0xef, 0xfe, 0xcc, - 0x9a, 0x23, 0xcf, 0xff, 0xfd, 0xcf, 0x00, 0x1c, 0xc8, 0x00, 0xf4, 0xda, - 0x92, 0xf8, 0xfe, 0xcf, 0x00, 0x1c, 0x13, 0x03, 0x76, 0xf8, 0xff, 0xff, - 0xff, 0x6f, 0xff, 0xbf, 0x6b, 0xb5, 0xff, 0xff, 0x6b, 0xff, 0xff, 0xdf, - 0x43, 0xff, 0xff, 0xdf, 0x5f, 0xff, 0xff, 0xdf, 0x4b, 0xfe, 0xff, 0xdf, - 0x2b, 0xeb, 0x9f, 0x7f, 0xbc, 0x92, 0x3f, 0xc4, 0x6a, 0xf7, 0x7a, 0xec, - 0x3a, 0xec, 0x3d, 0xc4, 0xf7, 0xf3, 0x97, 0x79, 0xff, 0xdc, 0x33, 0x8b, - 0xf5, 0xcd, 0x37, 0x9b, 0x97, 0x59, 0x4b, 0xf3, 0x5e, 0xec, 0x9c, 0x6a, - 0xb9, 0x27, 0xce, 0xff, 0x33, 0x8b, 0x35, 0x9b, 0xf9, 0xf3, 0xbc, 0x6a, - 0x77, 0x8b, 0xaa, 0xcc, 0x35, 0x9b, 0x3c, 0xf3, 0x00, 0x1c, 0xaf, 0x01, - 0xbf, 0x8a, 0x91, 0xa2, 0x33, 0x8b, 0xf7, 0xc4, 0xa8, 0xf7, 0xbf, 0x7b, - 0x9c, 0xb5, 0x9c, 0x1b, 0xfa, 0xdf, 0x5e, 0xc4, 0xdc, 0xbc, 0xbd, 0x1b, - 0xc7, 0xcf, 0x7b, 0x93, 0xb4, 0x93, 0xbf, 0x5b, 0x3f, 0xc4, 0xa2, 0xf7, - 0xbe, 0x7b, 0xbd, 0x1b, 0xf8, 0xdf, 0x35, 0x9b, 0xe7, 0xf3, 0x9c, 0x1b, - 0xfb, 0xdf, 0xbf, 0xc4, 0xaf, 0xf7, 0xff, 0xcf, 0xff, 0x1f, 0xe9, 0xf3, - 0x9f, 0x7b, 0x9c, 0xb4, 0x9c, 0x1b, 0xf8, 0xdf, 0x3f, 0xc4, 0xf4, 0xf3, - 0xf4, 0xcf, 0xff, 0xce, 0xff, 0xcd, 0x00, 0x1c, 0x9c, 0x01, 0x9b, 0xed, - 0x9f, 0x7c, 0x9c, 0xb4, 0x9c, 0x1b, 0xf8, 0xdf, 0xbe, 0x7b, 0xbd, 0x1b, - 0xf8, 0xcf, 0x37, 0x93, 0x9e, 0x5b, 0x7e, 0xed, 0x9d, 0x6b, 0x9c, 0x1b, - 0x00, 0xcf, 0xb3, 0x92, 0x5d, 0x4b, 0x80, 0xee, 0x5d, 0x6b, 0xfe, 0xcf, - 0xb3, 0x96, 0xff, 0x1f, 0xa0, 0xfb, 0x9d, 0xb7, 0xff, 0xdc, 0x33, 0x8b, - 0x97, 0xbc, 0xb3, 0x92, 0x5d, 0x4b, 0xc5, 0xee, 0x5d, 0x6b, 0xff, 0xcf, - 0xbb, 0x96, 0xff, 0x1f, 0xac, 0xfb, 0x9d, 0xb7, 0x33, 0x8b, 0x8f, 0xbc, - 0xb3, 0x92, 0x5d, 0x4b, 0xfc, 0xcf, 0x5d, 0x6b, 0xff, 0x1f, 0xb5, 0xfb, - 0x57, 0xba, 0xfd, 0xb7, 0x57, 0xb2, 0xe7, 0xbf, 0xbf, 0x92, 0x5d, 0x4b, - 0x6b, 0xeb, 0x9a, 0x1b, 0xf6, 0xff, 0x33, 0x8b, 0xeb, 0xc4, 0xe8, 0xf3, - 0xbf, 0x7b, 0x9c, 0xb5, 0x9c, 0x1b, 0xfe, 0xdf, 0xdc, 0xbc, 0xbd, 0x1b, - 0xc7, 0xcf, 0x7b, 0x93, 0xbf, 0x5b, 0x56, 0xf8, 0xfe, 0xcf, 0xff, 0x1f, - 0x38, 0xf4, 0x4e, 0xf8, 0x5d, 0xc4, 0xbc, 0xbc, 0xde, 0x1b, 0xc7, 0xcf, - 0xb7, 0x93, 0xa0, 0xef, 0xdf, 0x5d, 0x62, 0xf8, 0x9f, 0x7b, 0x9c, 0xb4, - 0x9c, 0x1b, 0xf8, 0xdf, 0x67, 0xf8, 0x9c, 0x1b, 0x04, 0xdf, 0x9f, 0x5f, - 0xa1, 0xef, 0xff, 0x7d, 0xde, 0x7d, 0xff, 0x8b, 0xbb, 0x8b, 0xbd, 0x9b, - 0x9c, 0xf0, 0xdf, 0x7d, 0xbb, 0x8b, 0x9e, 0x6d, 0x9b, 0xa4, 0xff, 0xde, - 0xbb, 0x8b, 0x9f, 0x7c, 0xdf, 0x5d, 0xdf, 0x7d, 0xfd, 0x7d, 0xbf, 0x97, - 0xdf, 0x5d, 0xad, 0xef, 0xd3, 0x6d, 0xde, 0x1b, 0x00, 0xcf, 0xb3, 0x93, - 0xeb, 0xc4, 0xd3, 0x4d, 0xec, 0xf3, 0x73, 0xef, 0x33, 0xef, 0xff, 0xcc, - 0x97, 0x59, 0xff, 0x1f, 0x10, 0xf6, 0x9f, 0x7a, 0x5d, 0xc4, 0x9c, 0x1b, - 0x01, 0xdf, 0x9f, 0x5a, 0xba, 0xf8, 0xff, 0xcd, 0x99, 0xef, 0xb7, 0x5c, - 0xff, 0x1f, 0x1b, 0xf6, 0xb7, 0xf8, 0xb6, 0xef, 0x9d, 0x3b, 0xbc, 0xf7, - 0xef, 0xfb, 0xff, 0xff, 0x5f, 0xff, 0xff, 0xdf, 0x6b, 0xff, 0xff, 0xdf, - 0xff, 0x6f, 0xff, 0xbf, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x53, 0xff, 0xff, 0xdf, 0x27, 0xb5, 0xff, 0xff, 0x9f, 0x6c, 0xf3, 0x87, - 0x00, 0x1c, 0xaf, 0x01, 0xbc, 0x6a, 0x80, 0xed, 0xbc, 0x23, 0xce, 0xff, - 0xc7, 0xf8, 0x21, 0xed, 0xb2, 0x69, 0x81, 0xed, 0x61, 0xed, 0x73, 0x97, - 0x99, 0x7b, 0xd7, 0xbc, 0x7b, 0x93, 0xb2, 0x49, 0xb1, 0x69, 0xbd, 0x1b, - 0x00, 0xcf, 0xbe, 0xc4, 0xb1, 0x49, 0xe1, 0xf2, 0xbc, 0xc4, 0xc9, 0xf2, - 0xbb, 0xc4, 0xee, 0xf2, 0x2c, 0xed, 0x3f, 0xf8, 0x8c, 0xed, 0xd2, 0x6c, - 0xac, 0xed, 0x6b, 0xed, 0xb7, 0x97, 0xba, 0x73, 0xf7, 0xb5, 0xf7, 0xbf, - 0xbf, 0x93, 0xd2, 0x4c, 0xd2, 0x6c, 0xde, 0x1b, 0x00, 0xcf, 0x77, 0x8b, - 0x7b, 0x93, 0xb2, 0x4c, 0x35, 0xed, 0x51, 0xf8, 0x95, 0xed, 0xd4, 0xed, - 0xb2, 0x6c, 0x74, 0xed, 0x7b, 0x97, 0xda, 0x7b, 0xd7, 0xbe, 0x7b, 0x93, - 0xb2, 0x4c, 0xb2, 0x6c, 0xbd, 0x1b, 0x00, 0xcf, 0xb2, 0x4c, 0x3c, 0xed, - 0x60, 0xf8, 0x9c, 0xed, 0xb2, 0x6c, 0x3e, 0xed, 0xdd, 0xed, 0x7b, 0x97, - 0xdf, 0x79, 0xd7, 0xbe, 0x7b, 0x93, 0xb2, 0x4c, 0xb2, 0x6c, 0xde, 0x79, - 0xbd, 0x1b, 0x00, 0xcf, 0x7b, 0x93, 0xb2, 0x4c, 0xb1, 0x6c, 0xc3, 0xee, - 0x7b, 0x97, 0xdd, 0x79, 0xd7, 0xbe, 0x7b, 0x93, 0xb1, 0x4c, 0xb1, 0x6c, - 0xdc, 0x79, 0xbd, 0x1b, 0x00, 0xcf, 0x7b, 0x93, 0xb1, 0x4c, 0x79, 0x1b, - 0xf4, 0xff, 0x7f, 0xf8, 0x8c, 0xee, 0xd2, 0x6c, 0x6b, 0xee, 0xac, 0xee, - 0xb7, 0x97, 0xbb, 0x73, 0xf7, 0xb5, 0xf7, 0xbf, 0xbf, 0x93, 0xd2, 0x4c, - 0xd2, 0x6c, 0xde, 0x1b, 0x00, 0xcf, 0x77, 0x8b, 0x7b, 0x93, 0xb2, 0x4c, - 0xd1, 0x6c, 0xb3, 0xee, 0xb7, 0x97, 0xb8, 0x7b, 0xf7, 0xbd, 0xbf, 0x93, - 0xff, 0xdd, 0xb8, 0x5b, 0x39, 0xee, 0xd1, 0x4c, 0x9a, 0xf8, 0x99, 0xee, - 0xb2, 0x6c, 0xd9, 0xee, 0x79, 0xee, 0x7b, 0x97, 0xdf, 0x7b, 0xda, 0xbe, - 0xde, 0x1b, 0xff, 0xd8, 0x7b, 0x93, 0xb2, 0x4c, 0x20, 0xef, 0xa7, 0xf8, - 0x80, 0xef, 0xb2, 0x6c, 0x22, 0xef, 0xc0, 0xef, 0x7b, 0x97, 0xdf, 0x79, - 0xd7, 0xbe, 0x7b, 0x93, 0xb2, 0x4c, 0xb2, 0x6c, 0xde, 0x79, 0xbd, 0x1b, - 0x00, 0xcf, 0x7b, 0x93, 0xb2, 0x4c, 0xb1, 0x6c, 0xc7, 0xef, 0x7b, 0x97, - 0xdd, 0x79, 0xd7, 0xbe, 0x7b, 0x93, 0xb1, 0x4c, 0x79, 0x1b, 0xf4, 0xff, - 0xc0, 0xf8, 0x8c, 0xef, 0xb3, 0x6c, 0x2e, 0xef, 0xdf, 0x79, 0xbd, 0x1b, - 0x00, 0xcf, 0x7b, 0x93, 0xb3, 0x4c, 0xb2, 0x6c, 0xd0, 0xef, 0x7b, 0x97, - 0xde, 0x79, 0xd7, 0xbe, 0x7b, 0x93, 0xb2, 0x4c, 0xb2, 0x6c, 0xdd, 0x79, - 0xbd, 0x1b, 0x00, 0xcf, 0x7b, 0x93, 0xb2, 0x4c, 0xb1, 0x6c, 0xd6, 0xef, - 0x7b, 0x97, 0xdc, 0x79, 0xd7, 0xbe, 0x7b, 0x93, 0xb1, 0x4c, 0xb1, 0x6c, - 0xdb, 0x79, 0xbd, 0x1b, 0x00, 0xcf, 0x7b, 0x93, 0xb1, 0x4c, 0xf6, 0xfb, - 0x6b, 0xff, 0xff, 0xdf, 0xff, 0x6f, 0xff, 0xbf, 0x00, 0xff, 0x00, 0x00, - 0x5f, 0xff, 0xff, 0xdf, 0x79, 0x1b, 0xf4, 0xff, 0xee, 0xf8, 0x95, 0xed, - 0xd5, 0xed, 0xb2, 0x6c, 0x75, 0xed, 0x7b, 0x97, 0xdf, 0x7b, 0xd8, 0xbe, - 0xde, 0x1b, 0xff, 0xde, 0x9e, 0xf8, 0x9a, 0xed, 0xda, 0xed, 0xb2, 0x6c, - 0x7a, 0xed, 0x7b, 0x97, 0xdd, 0x7b, 0xd7, 0xbe, 0xa6, 0xf8, 0x9e, 0xed, - 0xde, 0xed, 0xb2, 0x6c, 0x7e, 0xed, 0x7b, 0x97, 0xdf, 0x7b, 0xde, 0x1b, - 0xfe, 0xdf, 0xd7, 0xbe, 0xb0, 0xf8, 0x83, 0xee, 0xb2, 0x6c, 0xc3, 0xee, - 0x63, 0xee, 0x7b, 0x97, 0xdc, 0x7b, 0xd7, 0xbe, 0x7b, 0x93, 0xb2, 0x4c, - 0xb2, 0x6c, 0xdb, 0x7b, 0xbd, 0x1b, 0x00, 0xcf, 0x7b, 0x93, 0xb2, 0x4c, - 0x28, 0xee, 0x1b, 0xf9, 0x6c, 0xee, 0x8b, 0xee, 0x32, 0x6b, 0x73, 0x96, - 0x00, 0x1c, 0xe9, 0x0d, 0x97, 0xbf, 0x73, 0x92, 0x32, 0x4b, 0x27, 0xf9, - 0x6f, 0xee, 0x9f, 0x7b, 0x9d, 0xb4, 0x9c, 0x1b, 0xfe, 0xdf, 0xbe, 0xc4, - 0x7c, 0x9a, 0x00, 0x1c, 0xf6, 0x0d, 0x95, 0xee, 0xb2, 0x6c, 0x38, 0xb9, - 0xd6, 0xee, 0x7b, 0x97, 0xf9, 0x3b, 0xde, 0xdb, 0xbb, 0x8b, 0xd7, 0xbe, - 0x7b, 0x93, 0xb2, 0x4c, 0xb2, 0x6c, 0xbd, 0x1b, 0x00, 0xcf, 0xbd, 0x13, - 0xe9, 0xff, 0xb2, 0x4c, 0xb1, 0x6c, 0xdd, 0xee, 0x7b, 0x97, 0xbd, 0x13, - 0xff, 0xe6, 0xb1, 0x4c, 0xb1, 0x6c, 0xbd, 0x1b, 0x00, 0xcf, 0xbd, 0x13, - 0xea, 0xff, 0xb1, 0x4c, 0x21, 0xef, 0x4d, 0xf9, 0x92, 0x69, 0xa1, 0xef, - 0xbf, 0x7d, 0x9c, 0x1b, 0x00, 0xcf, 0x37, 0x93, 0x92, 0x49, 0x25, 0xef, - 0x56, 0xf9, 0x92, 0x69, 0xbc, 0x1b, 0x00, 0xcf, 0x86, 0xef, 0x9e, 0x74, - 0xd7, 0xb4, 0x7b, 0x93, 0xb2, 0x49, 0xb1, 0x69, 0xcd, 0xef, 0x33, 0x8b, - 0x7b, 0x97, 0x97, 0xbc, 0x37, 0x93, 0x91, 0x49, 0x11, 0x69, 0x00, 0x1c, - 0x36, 0x05, 0x9d, 0xb7, 0x18, 0x1b, 0x00, 0xcf, 0x33, 0x8b, 0x33, 0x92, - 0x11, 0x49, 0x32, 0xef, 0x70, 0xf9, 0x12, 0x69, 0x18, 0x1b, 0x00, 0xcf, - 0xff, 0x1f, 0xf7, 0xfa, 0x3f, 0x92, 0x12, 0x49, 0x91, 0x69, 0xb9, 0xef, - 0x37, 0x97, 0xb5, 0xef, 0xbf, 0x7d, 0xb7, 0xbd, 0x37, 0x93, 0x91, 0x49, - 0x3b, 0xef, 0x81, 0xf9, 0xff, 0x6f, 0xff, 0xbf, 0x00, 0xff, 0x00, 0x00, - 0x5f, 0xff, 0xff, 0xdf, 0x6b, 0xff, 0xff, 0xdf, 0x78, 0xff, 0xff, 0xdf, - 0x4b, 0xfe, 0xff, 0xdf, 0x0f, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0xde, 0xeb, - 0xd1, 0x1b, 0xfd, 0xff, 0xff, 0x5e, 0xff, 0xcd, 0xf8, 0xcf, 0x00, 0x1c, - 0xa8, 0x03, 0xfe, 0xeb, 0x6f, 0xeb, 0xff, 0xff, 0x98, 0xef, 0xdd, 0x7c, - 0xf7, 0xcd, 0xb7, 0x9b, 0xf7, 0xf7, 0x9f, 0x7c, 0x9c, 0x1b, 0xfd, 0xdf, - 0xbf, 0xc4, 0xff, 0x3b, 0xff, 0xfa, 0xc3, 0x87, 0xff, 0xcf, 0xc3, 0x87, - 0x5f, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xfd, 0x7c, 0xc3, 0x87, 0xff, 0xff, - 0x5f, 0xff, 0xff, 0xdf, 0x2e, 0xeb, 0x6f, 0xef, 0xbc, 0x6b, 0x77, 0x8b, - 0x55, 0xcc, 0x35, 0x9b, 0xee, 0xf3, 0xbc, 0x6b, 0x77, 0x8b, 0xaa, 0xcc, - 0x35, 0x9b, 0xfd, 0xf3, 0x6e, 0xeb, 0x00, 0x1c, 0x4a, 0x03, 0xbc, 0x6b, - 0x96, 0xef, 0xbc, 0x23, 0xce, 0xff, 0x96, 0xef, 0xff, 0xcd, 0xbf, 0x4c, - 0x6e, 0xeb, 0x99, 0xef, 0xb8, 0x7c, 0x5f, 0xc5, 0xb8, 0x5c, 0x9a, 0xef, - 0xff, 0xcd, 0xbf, 0x4c, 0x6e, 0xeb, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xbf, - 0x6b, 0xff, 0xff, 0xdf, 0x8f, 0xff, 0xff, 0xdf, 0xde, 0xeb, 0x9a, 0xef, - 0x9f, 0x6c, 0xf2, 0x8b, 0x8f, 0xb4, 0x8f, 0xbc, 0xf3, 0x93, 0xfe, 0xeb, - 0xc3, 0x87, 0xff, 0xff, 0x4b, 0xfe, 0xff, 0xdf, 0x2c, 0xeb, 0x80, 0xed, - 0xe0, 0xed, 0xff, 0x4c, 0xff, 0x1f, 0x27, 0xf6, 0xbf, 0xc7, 0xa7, 0xf7, - 0x82, 0xed, 0x9e, 0x6c, 0x3f, 0xc4, 0x67, 0xf7, 0x63, 0xed, 0xff, 0xcf, - 0xff, 0x1f, 0xeb, 0xf8, 0xb4, 0x73, 0xf5, 0x9b, 0xbc, 0x92, 0x86, 0xed, - 0xfa, 0xf2, 0xff, 0xcd, 0xb3, 0x54, 0x9f, 0x6b, 0x89, 0xbc, 0x89, 0xb4, - 0xbd, 0xac, 0x96, 0xa4, 0x54, 0x53, 0x5d, 0xb2, 0x4b, 0xa4, 0x9f, 0x73, - 0x5a, 0x1b, 0x00, 0xdc, 0x9c, 0x1b, 0x00, 0xcc, 0x2b, 0x93, 0x9f, 0x53, - 0xfc, 0x15, 0x8c, 0xfe, 0xb3, 0x9a, 0x31, 0xed, 0x99, 0xf3, 0x91, 0xed, - 0x9e, 0x6c, 0x3b, 0xc4, 0x1b, 0xf7, 0x20, 0xcc, 0x9e, 0xbc, 0xb3, 0x9a, - 0xe8, 0xf6, 0x9f, 0x6b, 0x53, 0xbc, 0x49, 0xb2, 0xbd, 0xaa, 0x56, 0xa2, - 0x5a, 0x1b, 0x00, 0xdc, 0xf8, 0xed, 0xb5, 0xba, 0x3f, 0x97, 0x37, 0x93, - 0xfe, 0xcf, 0x9f, 0x4b, 0xff, 0x1f, 0x1d, 0xf9, 0xfd, 0xb7, 0x5f, 0xa2, - 0x5a, 0x1b, 0x00, 0xdc, 0x9f, 0x6b, 0xde, 0xed, 0xb5, 0xba, 0x3b, 0x97, - 0x37, 0x93, 0x9f, 0x4b, 0xfc, 0x15, 0xde, 0xfd, 0xb3, 0x9a, 0xb2, 0xf3, - 0x86, 0xee, 0xbf, 0x6c, 0x43, 0xee, 0x6b, 0x97, 0x55, 0xc5, 0xbf, 0x4c, - 0xff, 0xcc, 0x85, 0x5b, 0xff, 0x1f, 0x41, 0xf9, 0xff, 0x1f, 0x0f, 0xfb, - 0xfc, 0xc7, 0xeb, 0xf3, 0x6c, 0xeb, 0xac, 0xee, 0x85, 0x7d, 0xff, 0xdc, - 0x33, 0x8b, 0x85, 0x5d, 0x69, 0xcd, 0x37, 0x9b, 0x0b, 0xf4, 0xfb, 0xcf, - 0xff, 0x1f, 0xdd, 0xfb, 0xfc, 0xcd, 0x8e, 0xee, 0xbf, 0x5c, 0xff, 0x1f, - 0x22, 0xfb, 0xfc, 0xc7, 0x11, 0xf4, 0xff, 0xcf, 0xff, 0x1f, 0x4f, 0xf9, - 0xfc, 0x15, 0xd0, 0xfd, 0xf3, 0x9b, 0x18, 0xf4, 0x9a, 0xee, 0xbe, 0x6c, - 0xa9, 0xb5, 0xfc, 0x15, 0x00, 0xfd, 0x73, 0x9b, 0xfa, 0xf3, 0x97, 0xee, - 0x9f, 0x7c, 0xbf, 0xc4, 0xf6, 0xf2, 0xfd, 0xcf, 0xff, 0x1f, 0x9f, 0xf8, - 0xfa, 0xcf, 0xff, 0x1f, 0x96, 0xf8, 0xfb, 0xcf, 0xff, 0x1f, 0xe7, 0xfd, - 0xfb, 0xcd, 0x9f, 0xee, 0xbf, 0x5c, 0x6c, 0xeb, 0xfc, 0x15, 0xd0, 0xfd, - 0xb3, 0x9a, 0x88, 0xf3, 0x0d, 0xcc, 0x9e, 0xbc, 0xb3, 0x9a, 0x67, 0xf4, - 0xfe, 0xcf, 0xff, 0x1f, 0xb4, 0xf8, 0x67, 0xf8, 0x8c, 0xef, 0xbf, 0x6c, - 0xe9, 0xef, 0x7f, 0x97, 0x53, 0xc5, 0xbf, 0x4c, 0x4b, 0xf8, 0x6e, 0xef, - 0xff, 0x1f, 0x9f, 0xf9, 0x9f, 0x6b, 0x9d, 0xbc, 0x89, 0xb4, 0xbd, 0xac, - 0x96, 0xa4, 0xfd, 0xb7, 0xbf, 0xa4, 0xbd, 0x1b, 0x00, 0xdc, 0x9e, 0x73, - 0xfd, 0x1b, 0x00, 0xdc, 0x50, 0xef, 0xdb, 0xbf, 0x2b, 0x97, 0x3b, 0x93, - 0x7f, 0xce, 0xde, 0xbe, 0x7b, 0x9b, 0x9e, 0x53, 0x34, 0x93, 0xc3, 0xf7, - 0xe9, 0xfb, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xbf, 0x04, 0x00, 0xdd, 0xff, - 0xff, 0x5f, 0xff, 0xbf, 0x37, 0xff, 0xff, 0xdf, 0xff, 0xaf, 0xff, 0xbf, - 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xdf, - 0x6f, 0xfe, 0xff, 0xdf, 0xf0, 0x3f, 0x00, 0x00, 0x9a, 0x73, 0xdb, 0xb4, - 0xde, 0x1b, 0xe0, 0xdf, 0x5d, 0xa6, 0x5a, 0x1b, 0xe0, 0xdf, 0x5b, 0xba, - 0x9c, 0x1b, 0x0f, 0xce, 0x2b, 0x93, 0xd6, 0xc6, 0xb0, 0x92, 0x9a, 0x53, - 0x78, 0xf3, 0x9d, 0x6b, 0xd3, 0xbc, 0xd3, 0xb6, 0xdb, 0xa5, 0xd3, 0xbe, - 0x8b, 0xb4, 0xd3, 0xb6, 0x8b, 0xbc, 0x3b, 0x93, 0x9d, 0x4b, 0x9e, 0x6b, - 0xd3, 0xbc, 0xc9, 0xb6, 0xb6, 0x9b, 0x3e, 0xf3, 0xc8, 0xed, 0xf5, 0xbf, - 0x3b, 0x97, 0x3f, 0x93, 0x9e, 0x4b, 0x9d, 0xbc, 0x89, 0xb4, 0xca, 0xed, - 0xbd, 0x76, 0xbf, 0xc5, 0xc9, 0xf3, 0x73, 0x9b, 0x97, 0xf3, 0xf6, 0xa4, - 0xfe, 0x8b, 0xf3, 0xc7, 0xcf, 0xf7, 0x5e, 0x76, 0x29, 0x9b, 0xf0, 0xed, - 0xdc, 0xf3, 0x9e, 0x57, 0xfe, 0xcc, 0x9f, 0x5f, 0x34, 0x93, 0xd7, 0xfb, - 0xff, 0x1f, 0xbf, 0xfb, 0xbb, 0xc7, 0x7b, 0xf3, 0x5f, 0x69, 0x49, 0xba, - 0x49, 0xb2, 0x7c, 0xf8, 0xfb, 0xcf, 0xff, 0x1f, 0x82, 0xf6, 0x5f, 0x69, - 0x49, 0xba, 0x49, 0xb2, 0x83, 0xf8, 0xb3, 0x74, 0xff, 0xdd, 0x76, 0x8b, - 0xb3, 0x54, 0x9b, 0xcc, 0x73, 0x9b, 0x07, 0xf5, 0xfb, 0xcf, 0xff, 0x1f, - 0x96, 0xfc, 0xfd, 0xcd, 0x80, 0xee, 0xbf, 0x5c, 0x0e, 0xf9, 0x5f, 0x7f, - 0xff, 0xda, 0xab, 0x8a, 0x5f, 0x5f, 0xec, 0xcf, 0xbf, 0x9a, 0x6f, 0xf7, - 0x35, 0x9b, 0xfd, 0xf3, 0x9d, 0x56, 0xd7, 0xcd, 0x37, 0x9b, 0xe5, 0xf3, - 0x8c, 0x7b, 0xff, 0xdc, 0x33, 0x8b, 0xf5, 0xcd, 0xff, 0xcf, 0x37, 0x9b, - 0xca, 0xee, 0xed, 0x5b, 0x8c, 0x5b, 0xf6, 0xf7, 0x8b, 0x7e, 0xbe, 0xc4, - 0xac, 0x5e, 0xfa, 0xf7, 0xeb, 0x5e, 0xed, 0xee, 0xff, 0x1f, 0xe5, 0xfb, - 0xff, 0xcc, 0x8d, 0x5b, 0x3a, 0xf9, 0xfc, 0xcf, 0xff, 0x1f, 0x65, 0xf9, - 0x18, 0xf9, 0xff, 0xce, 0xcc, 0x5b, 0x84, 0xce, 0x3b, 0x9b, 0xb5, 0xee, - 0x0b, 0xf4, 0x8d, 0x7d, 0xff, 0xdc, 0x33, 0x8b, 0xf5, 0xce, 0x3b, 0x9b, - 0x8d, 0x5d, 0x4b, 0xf5, 0x8b, 0x7d, 0xbf, 0xc4, 0xcd, 0x5d, 0x4f, 0xf5, - 0xfe, 0xcc, 0x8b, 0x5d, 0xfc, 0xee, 0xff, 0x1f, 0x02, 0xfc, 0x55, 0xf9, - 0xf2, 0xa5, 0xfe, 0x8b, 0x66, 0xf8, 0xbd, 0x6b, 0x9d, 0x73, 0xb3, 0xbd, - 0x89, 0xbc, 0xb3, 0xb5, 0x89, 0xb4, 0x92, 0xa5, 0xbe, 0x6b, 0x93, 0xbc, - 0xb3, 0xbd, 0xa9, 0xb5, 0x93, 0xb4, 0x96, 0xa4, 0x8c, 0xbc, 0xbc, 0x73, - 0x89, 0xb4, 0xe6, 0xef, 0xdb, 0xbc, 0x7f, 0x97, 0x5a, 0x1b, 0x0f, 0xce, - 0x7b, 0x93, 0x5a, 0x53, 0xbc, 0x53, 0xbd, 0x6b, 0xab, 0xb5, 0xab, 0xbd, - 0xbd, 0x4b, 0xcb, 0xef, 0xbe, 0x6b, 0x7b, 0x93, 0xbe, 0x4b, 0xbd, 0x1b, - 0x00, 0xcc, 0xbd, 0x53, 0x92, 0xf8, 0x3f, 0xcf, 0xfd, 0xbf, 0x84, 0xce, - 0xff, 0x1f, 0xf9, 0xf9, 0x0c, 0xf9, 0x91, 0xef, 0x9e, 0x6c, 0x3b, 0xc4, - 0x85, 0xf4, 0x92, 0xef, 0x9f, 0x7c, 0xbf, 0xc4, 0x89, 0xf4, 0xfb, 0xcf, - 0xff, 0x1f, 0x13, 0xf7, 0x8d, 0xf8, 0xff, 0xff, 0x00, 0xfc, 0x0f, 0x00, - 0x2b, 0xff, 0xff, 0xdf, 0x0f, 0xff, 0xff, 0xdf, 0x37, 0xff, 0xff, 0xdf, - 0xd3, 0xb4, 0xff, 0xff, 0xf0, 0x3f, 0x00, 0x00, 0xff, 0x03, 0xf0, 0xff, - 0xff, 0xaf, 0xff, 0xbf, 0x6f, 0xfe, 0xff, 0xdf, 0x9d, 0x73, 0xc9, 0xbc, - 0xc9, 0xb6, 0x7a, 0x9b, 0xfa, 0xf3, 0x9c, 0x1b, 0x00, 0xcc, 0xf3, 0x93, - 0xfd, 0x53, 0x9c, 0x73, 0x8d, 0xbc, 0x89, 0xb4, 0xc4, 0xf8, 0x34, 0x93, - 0x8c, 0xf8, 0xff, 0xff, 0x2e, 0xeb, 0x77, 0xee, 0xff, 0xcc, 0xbb, 0x1b, - 0xf4, 0xff, 0x8c, 0x5b, 0x8d, 0x5b, 0x8b, 0x5b, 0xff, 0xcc, 0x9d, 0x55, - 0x9e, 0x55, 0x9f, 0x5d, 0x93, 0x53, 0x85, 0x5b, 0x9a, 0x73, 0x9c, 0x1b, - 0x0f, 0xce, 0x9a, 0x53, 0x9d, 0x6b, 0x8b, 0xb4, 0x8b, 0xbc, 0x9d, 0x4b, - 0x9d, 0x73, 0x9c, 0x1b, 0x00, 0xcc, 0x9d, 0x53, 0x9e, 0x6b, 0xa3, 0xef, - 0x37, 0x93, 0x9e, 0x4b, 0xff, 0x1f, 0xd9, 0xfa, 0x9f, 0x1b, 0x00, 0xdc, - 0xa6, 0xef, 0xfe, 0x73, 0xf7, 0x97, 0x9b, 0xbc, 0xf3, 0x93, 0xfe, 0x53, - 0xff, 0xcf, 0xff, 0x1f, 0xc6, 0xfa, 0x9f, 0x73, 0xff, 0x1b, 0x00, 0xdc, - 0x9c, 0x1b, 0x00, 0xcc, 0x3f, 0x93, 0xfe, 0xcf, 0x9f, 0x53, 0xff, 0x1f, - 0xd0, 0xfa, 0x9f, 0x1b, 0x00, 0xdc, 0xaf, 0xef, 0xff, 0x6b, 0x95, 0xbc, - 0xf7, 0x97, 0xf3, 0x93, 0xff, 0x4b, 0xff, 0x1f, 0xe6, 0xfa, 0xfb, 0x1b, - 0xe5, 0xff, 0xff, 0xce, 0xb4, 0xef, 0xff, 0x1f, 0x48, 0xfc, 0xbf, 0xc7, - 0xf9, 0xf7, 0xe4, 0x7b, 0xfc, 0xce, 0xff, 0xcd, 0xff, 0x1f, 0xf3, 0xfb, - 0x98, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0x6e, 0xeb, 0x37, 0xff, 0xff, 0xdf, - 0xff, 0x03, 0xf0, 0xff, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, - 0x2b, 0xd7, 0xff, 0xff, 0x47, 0xfe, 0xff, 0xdf, 0xff, 0x8b, 0xbf, 0xc7, - 0xf4, 0xf7, 0x8e, 0xef, 0xbf, 0x74, 0xbd, 0x1b, 0x00, 0xdc, 0xbf, 0xc5, - 0xec, 0xf3, 0xff, 0x6c, 0xe9, 0xbf, 0xe9, 0xb7, 0xc3, 0x87, 0xbe, 0xc7, - 0xf9, 0xf3, 0xbc, 0xc7, 0xf2, 0xf3, 0xff, 0x15, 0x00, 0xfc, 0xc3, 0x87, - 0x97, 0xef, 0xff, 0x6c, 0xb7, 0xef, 0xbf, 0x3b, 0xdc, 0xdf, 0xbf, 0xc4, - 0xf9, 0xf7, 0xfe, 0xcf, 0xc3, 0x87, 0x99, 0xef, 0xfd, 0x74, 0xc3, 0x87, - 0xf3, 0xbf, 0xe9, 0xb7, 0xc3, 0x87, 0xff, 0xff, 0x37, 0xff, 0xff, 0xdf, - 0xff, 0x03, 0xf0, 0xff, 0x2b, 0xff, 0xff, 0xdf, 0x3e, 0xeb, 0x8f, 0xef, + 0xe4, 0xee, 0x7f, 0x97, 0x1f, 0xce, 0xd6, 0xbe, 0x7b, 0x93, 0xbf, 0x4c, + 0xbd, 0x74, 0x78, 0xc5, 0x77, 0xc5, 0x58, 0xc5, 0xbd, 0x54, 0xd4, 0xfb, + 0x6c, 0xee, 0x81, 0xa3, 0xbf, 0x7c, 0xff, 0xcf, 0xce, 0xd7, 0x7f, 0x97, + 0xbf, 0x5c, 0xff, 0xcf, 0xff, 0x1f, 0x3f, 0xfc, 0x07, 0xcf, 0xff, 0x1f, + 0xcc, 0xfb, 0x9e, 0x73, 0x9c, 0x1b, 0x03, 0xcc, 0x9c, 0x13, 0x73, 0xff, + 0x9e, 0x53, 0x97, 0xb4, 0x9c, 0x1b, 0x83, 0xcf, 0x9c, 0x13, 0xc7, 0xff, + 0x9c, 0x5b, 0x9e, 0x7b, 0x9c, 0x1b, 0xe0, 0xcf, 0x9c, 0x13, 0xf4, 0xff, + 0x9e, 0x5b, 0x9f, 0x6b, 0xda, 0xee, 0x3b, 0x97, 0x50, 0xc4, 0x4f, 0xc4, + 0x9f, 0x4b, 0x9d, 0x73, 0x78, 0xc4, 0x77, 0xc4, 0x57, 0xc4, 0x9d, 0x53, + 0xf2, 0xcf, 0xff, 0xce, 0xf7, 0xcd, 0xff, 0x1f, 0xda, 0xfb, 0xe0, 0xef, + 0xff, 0xce, 0xa0, 0xef, 0xff, 0x1f, 0xcf, 0xf0, 0xbf, 0xc7, 0xf7, 0xf7, + 0xa7, 0xef, 0xeb, 0x7d, 0xf8, 0xdd, 0xf2, 0xce, 0xff, 0x1f, 0x6f, 0xf0, + 0xfd, 0xfb, 0xff, 0xfb, 0x9f, 0x72, 0xff, 0xd4, 0x72, 0x8b, 0xfa, 0xc5, + 0x9f, 0x17, 0xfa, 0xfc, 0x34, 0x93, 0xa9, 0xef, 0x9d, 0x3b, 0xbc, 0xf7, + 0x9f, 0x6c, 0xf3, 0x87, 0x3e, 0x6a, 0x9e, 0x79, 0xbf, 0xc4, 0xf7, 0xf6, + 0x59, 0xa1, 0x9f, 0x79, 0xbe, 0xc4, 0xd8, 0xf7, 0x9e, 0x7a, 0xfe, 0xdc, + 0x33, 0x8b, 0xfe, 0xc4, 0xf8, 0xf7, 0xff, 0xcd, 0x98, 0xef, 0xbf, 0x5c, + 0x00, 0x1c, 0x3f, 0x03, 0x23, 0xfa, 0xba, 0xef, 0x9f, 0x7d, 0xff, 0xdc, + 0x33, 0x8b, 0x9f, 0x5d, 0xfb, 0xcd, 0x37, 0x9b, 0x2b, 0xf6, 0xf2, 0xfb, + 0x8b, 0xff, 0xff, 0xdf, 0x83, 0xff, 0xff, 0xdf, 0x00, 0xe0, 0x03, 0x00, + 0x77, 0xff, 0xff, 0xdf, 0xc3, 0xf3, 0xff, 0xff, 0xa3, 0xb7, 0xff, 0xff, + 0xff, 0xcd, 0x9d, 0xec, 0xbf, 0x5c, 0x00, 0x1c, 0x5a, 0x03, 0x3e, 0xfa, + 0xbd, 0xc4, 0x40, 0xf6, 0xff, 0xcd, 0x81, 0xed, 0xbf, 0x5c, 0x7d, 0xa2, + 0x9f, 0x7b, 0xc0, 0xcd, 0x71, 0x9b, 0xd5, 0xf3, 0x37, 0x9b, 0xf8, 0xf3, + 0xa0, 0xc4, 0xf3, 0xf3, 0xd0, 0xcd, 0x71, 0x9b, 0x60, 0xf7, 0xed, 0xfb, + 0xb0, 0xcd, 0x71, 0x9b, 0xbf, 0xf3, 0xa0, 0xcd, 0x71, 0x9b, 0x67, 0xf7, + 0x86, 0xfb, 0xbe, 0x7b, 0x00, 0xcc, 0x35, 0x9b, 0x6c, 0xf3, 0xbf, 0x7a, + 0xf7, 0xcf, 0xac, 0x93, 0xff, 0x1f, 0xaf, 0xfa, 0x72, 0xfb, 0x9e, 0x7b, + 0xb4, 0xc4, 0x75, 0xf7, 0xd1, 0x1b, 0xe2, 0xff, 0x9d, 0x7b, 0x9f, 0x5e, + 0xf9, 0xcf, 0xff, 0xcd, 0xff, 0x1f, 0xbb, 0xfa, 0x96, 0xed, 0xbe, 0x7c, + 0x7f, 0xc5, 0xbe, 0x5c, 0x82, 0xfb, 0x9e, 0x7b, 0xc4, 0xcd, 0x71, 0x9b, + 0xea, 0xf7, 0xd1, 0x1b, 0xe2, 0xff, 0xbd, 0x7b, 0xb7, 0xbd, 0x9c, 0x7b, + 0x37, 0x93, 0x9f, 0x56, 0xfb, 0xcf, 0xff, 0xcd, 0xff, 0x1f, 0xcf, 0xfa, + 0x80, 0xee, 0x9f, 0x7c, 0x3f, 0xc4, 0x95, 0xf7, 0x82, 0xee, 0xbe, 0x7c, + 0x5f, 0xc5, 0xbe, 0x5c, 0x9a, 0xfb, 0xc0, 0xcd, 0x71, 0x9b, 0x9d, 0xf7, + 0xd9, 0xa3, 0xf2, 0xcf, 0xfd, 0xcd, 0xff, 0x1f, 0xe0, 0xfa, 0xa3, 0xfb, + 0x8a, 0xee, 0x9e, 0x7c, 0x9c, 0x1b, 0xe0, 0xdf, 0xad, 0xc4, 0xda, 0xf7, + 0xff, 0xcd, 0x91, 0x1b, 0xe2, 0xff, 0xbf, 0x5c, 0xc4, 0x92, 0xc4, 0x93, + 0xff, 0x1f, 0xe5, 0xe5, 0xbd, 0x7a, 0xa7, 0xbd, 0x9c, 0x7a, 0x8f, 0xbc, + 0x73, 0x93, 0x9a, 0x7a, 0x73, 0x93, 0x9b, 0x7a, 0x97, 0xbc, 0x37, 0x93, + 0xbf, 0x67, 0x35, 0x9b, 0xf6, 0xf7, 0xfe, 0xcd, 0x91, 0x1b, 0xe2, 0xff, + 0xbf, 0x5c, 0x99, 0xee, 0xaf, 0x7c, 0x5d, 0xc5, 0xaf, 0x5c, 0xfa, 0xcf, + 0xd1, 0x1b, 0xe2, 0xff, 0xff, 0xcd, 0xff, 0x1f, 0x0a, 0xfb, 0xcd, 0xfb, + 0x9e, 0x7b, 0x49, 0xcd, 0x71, 0x9b, 0xf8, 0xf7, 0xd9, 0xa3, 0xf6, 0xcf, + 0xfc, 0xcd, 0xff, 0x1f, 0x14, 0xfb, 0xd7, 0xfb, 0x48, 0xcd, 0x71, 0x9b, + 0xda, 0xf7, 0xd9, 0xa3, 0xf5, 0xcf, 0xfc, 0xcd, 0xff, 0x1f, 0x1d, 0xfb, + 0xe0, 0xfb, 0xbe, 0x7b, 0xb3, 0xcc, 0x35, 0x9b, 0xe4, 0xf7, 0xbd, 0x7b, + 0xa7, 0xbd, 0x9c, 0x7b, 0x8f, 0xbc, 0x73, 0x93, 0x9a, 0x7b, 0x73, 0x93, + 0x9b, 0x7b, 0x97, 0xbc, 0x73, 0x93, 0x8d, 0xef, 0x35, 0x9b, 0xf6, 0xf7, + 0x00, 0x1c, 0xb9, 0x05, 0x6f, 0xcc, 0x99, 0xbc, 0x3d, 0x9b, 0xfc, 0xf7, + 0xff, 0x1f, 0xf1, 0xfc, 0xd9, 0xa3, 0xf2, 0xcf, 0xfb, 0xcd, 0xff, 0x1f, + 0x3c, 0xfb, 0x97, 0xef, 0xbe, 0x74, 0xbd, 0x1b, 0x03, 0xcc, 0xbd, 0x13, + 0x37, 0xff, 0xbe, 0x54, 0xb7, 0xb5, 0xbd, 0x1b, 0x83, 0xcf, 0xbd, 0x13, + 0xc7, 0xff, 0xbc, 0x5c, 0xf7, 0xfb, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xdf, + 0x83, 0xff, 0xff, 0xdf, 0xfe, 0xfe, 0xfe, 0xf9, 0xbe, 0x7c, 0xbd, 0x1b, + 0xe0, 0xcf, 0xbd, 0x13, 0xf4, 0xff, 0xbe, 0x5c, 0x97, 0x7c, 0x3f, 0xc4, + 0xfc, 0xf7, 0xf3, 0xcd, 0xfd, 0xfb, 0xef, 0xcd, 0x99, 0xec, 0xb2, 0xbd, + 0xdf, 0x6c, 0xf9, 0xec, 0xbf, 0x97, 0x7b, 0x93, 0xbf, 0x4c, 0xbd, 0x74, + 0x78, 0xc5, 0x77, 0xc5, 0x57, 0xc5, 0xbd, 0x54, 0x1b, 0xfb, 0x9f, 0x79, + 0xbe, 0xc4, 0xac, 0xf7, 0x81, 0xed, 0x9e, 0x7c, 0x9c, 0x1b, 0xe0, 0xdf, + 0xd0, 0xc4, 0xf1, 0xf3, 0xa4, 0xed, 0x9f, 0x7d, 0xff, 0xdc, 0x33, 0x8b, + 0x9f, 0x5d, 0xfb, 0xcd, 0x37, 0x9b, 0xf9, 0xf7, 0xff, 0xcd, 0x88, 0xed, + 0xbf, 0x5c, 0x00, 0x1c, 0x4e, 0x04, 0x8a, 0xed, 0x8f, 0x7c, 0x9c, 0x1b, + 0xfb, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0x38, 0xf7, 0x8e, 0xed, 0x9e, 0x7c, + 0x9c, 0x1b, 0xe0, 0xdf, 0xb0, 0xc4, 0xec, 0xf7, 0xfc, 0xcf, 0xff, 0x1f, + 0x84, 0xf5, 0x66, 0xcc, 0x9e, 0xbc, 0xf3, 0x9b, 0xf8, 0xf3, 0xfc, 0xcf, + 0xff, 0xce, 0xff, 0xcd, 0xff, 0x1f, 0x99, 0xfb, 0x4b, 0xfb, 0xff, 0x15, + 0x60, 0xfe, 0xff, 0x1f, 0x48, 0xfd, 0x50, 0xfb, 0xaf, 0xc4, 0x52, 0xf7, + 0xff, 0xcf, 0xff, 0x1f, 0x98, 0xf5, 0xfc, 0x15, 0x40, 0xfe, 0xf3, 0x9b, + 0x59, 0xf7, 0x9c, 0xed, 0x9c, 0x7c, 0x9c, 0x1b, 0xfb, 0xdf, 0x33, 0x8b, + 0xbf, 0xc4, 0x60, 0xf7, 0x82, 0xee, 0xff, 0xcd, 0xbf, 0x5c, 0xf8, 0xdc, + 0xbc, 0x7c, 0x5d, 0xc5, 0xbc, 0x5c, 0xfa, 0xcf, 0xfe, 0xce, 0xff, 0x1f, + 0xc6, 0xed, 0xff, 0x15, 0x65, 0xfd, 0xff, 0x1f, 0xb2, 0xf0, 0x70, 0xfb, + 0x8a, 0xee, 0x9e, 0x7c, 0x9c, 0x1b, 0xe0, 0xdf, 0xd2, 0xc4, 0x76, 0xf7, + 0x8d, 0xee, 0x9e, 0x7c, 0x9c, 0x1b, 0xe0, 0xdf, 0xab, 0xc4, 0xd0, 0xf7, + 0xae, 0xee, 0xbe, 0x7d, 0xbd, 0x1b, 0xf9, 0xdf, 0xbd, 0xc5, 0xd6, 0xf7, + 0x93, 0xee, 0xff, 0xcd, 0xbf, 0x5c, 0xbe, 0x74, 0xbd, 0x1b, 0x03, 0xcc, + 0xbd, 0x13, 0x37, 0xff, 0xbe, 0x54, 0xb7, 0xb5, 0xbd, 0x1b, 0x83, 0xcf, + 0xbd, 0x13, 0xc7, 0xff, 0xbc, 0x5c, 0xbe, 0x7c, 0xbd, 0x1b, 0xe0, 0xcf, + 0xbd, 0x13, 0xf4, 0xff, 0xbe, 0x5c, 0x97, 0x7c, 0x3f, 0xc4, 0xfc, 0xf7, + 0xf3, 0xcd, 0xfd, 0xfb, 0xef, 0xcd, 0x80, 0xef, 0xb2, 0xbd, 0xdf, 0x6c, + 0xe1, 0xef, 0xbf, 0x97, 0x7b, 0x93, 0xbf, 0x4c, 0xbd, 0x74, 0x78, 0xc5, + 0x77, 0xc5, 0x57, 0xc5, 0xbd, 0x54, 0xaa, 0xfb, 0xc7, 0xef, 0xbf, 0x7e, + 0xff, 0xdd, 0x77, 0x8b, 0xbf, 0x5e, 0xfd, 0xce, 0x7b, 0x9b, 0xb2, 0xf7, + 0xab, 0xc4, 0xe8, 0xf3, 0xa6, 0xc4, 0xea, 0xf3, 0xae, 0xc4, 0xf5, 0xf7, + 0xd1, 0x1b, 0xe2, 0xff, 0xc4, 0xcc, 0x9f, 0x5e, 0xf0, 0xcf, 0xfe, 0xcd, + 0xff, 0x1f, 0x0f, 0xfc, 0xf9, 0xfb, 0xf0, 0xcf, 0xff, 0xce, 0xff, 0xcd, + 0xff, 0x1f, 0x15, 0xfc, 0x93, 0xef, 0xbe, 0x7c, 0x7f, 0xc5, 0xbe, 0x5c, + 0x97, 0xef, 0xbe, 0x74, 0xbd, 0x1b, 0x03, 0xcc, 0xbd, 0x13, 0x37, 0xff, + 0xbe, 0x54, 0xb7, 0xb5, 0xbd, 0x1b, 0x83, 0xcf, 0xbd, 0x13, 0xc7, 0xff, + 0xbc, 0x5c, 0xbe, 0x7c, 0xf7, 0xfb, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xdf, + 0x00, 0xe0, 0x03, 0x00, 0x83, 0xff, 0xff, 0xdf, 0xbd, 0x1b, 0xe0, 0xcf, + 0xbd, 0x13, 0xf4, 0xff, 0xbe, 0x5c, 0x97, 0x7c, 0x3f, 0xc4, 0xfc, 0xf7, + 0xf3, 0xcd, 0xfd, 0xfb, 0xef, 0xcd, 0x93, 0xec, 0xb2, 0xbd, 0xdf, 0x6c, + 0xf4, 0xec, 0xbf, 0x97, 0x7b, 0x93, 0xbf, 0x4c, 0xbd, 0x74, 0x78, 0xc5, + 0x77, 0xc5, 0x57, 0xc5, 0xbd, 0x54, 0xbd, 0x1b, 0xe0, 0xcf, 0xbd, 0x13, + 0xf4, 0xff, 0xbb, 0x5c, 0xff, 0xcd, 0xbf, 0x5c, 0xe4, 0x93, 0x00, 0x1c, + 0xb2, 0x07, 0x00, 0x1c, 0x96, 0x05, 0xf5, 0xfa, 0x9e, 0xec, 0x9f, 0x7c, + 0x9c, 0x1b, 0x80, 0xcf, 0x33, 0x8b, 0xbf, 0xc4, 0xfa, 0xf3, 0xff, 0xcf, + 0xff, 0x1f, 0x63, 0xf3, 0x00, 0xfb, 0x85, 0xed, 0x8f, 0x7c, 0x9c, 0x1b, + 0xfb, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0xf8, 0xf7, 0x89, 0xed, 0x9e, 0x7c, + 0x9c, 0x1b, 0xe0, 0xdf, 0xd2, 0xc4, 0xf6, 0xf7, 0x8c, 0xed, 0xfd, 0x74, + 0xf8, 0xb7, 0xff, 0x1b, 0xfc, 0xdf, 0xff, 0x1f, 0xb6, 0xfc, 0x15, 0xfb, + 0x00, 0x1c, 0xb9, 0x05, 0x18, 0xfb, 0x9e, 0x6a, 0xff, 0x7c, 0xff, 0x1b, + 0xfe, 0xdf, 0x71, 0xed, 0x99, 0xbf, 0xbf, 0x7b, 0x79, 0xc5, 0x37, 0x93, + 0x9f, 0x5b, 0xff, 0x1f, 0x20, 0xf1, 0x9f, 0x7b, 0x9c, 0x1b, 0xbf, 0xdf, + 0x33, 0x8b, 0xbf, 0xc4, 0xf5, 0xf3, 0xbe, 0x7b, 0xbd, 0x1b, 0xc7, 0xcf, + 0xbe, 0x5b, 0xfe, 0xcf, 0xff, 0xce, 0xff, 0x1f, 0x9c, 0xee, 0x33, 0xfb, + 0xff, 0xcf, 0xff, 0x1f, 0x88, 0xf6, 0xfc, 0x15, 0xd0, 0xfd, 0xf3, 0x9b, + 0xf7, 0xf7, 0x80, 0xee, 0xbe, 0x7c, 0xbd, 0x1b, 0xc7, 0xcf, 0x5c, 0xc5, + 0xbe, 0x5c, 0xe2, 0xfb, 0x45, 0xcc, 0x9e, 0xbc, 0xf3, 0x9b, 0xf7, 0xf7, + 0x86, 0xee, 0xbe, 0x7c, 0xbd, 0x1b, 0xc7, 0xcf, 0x5b, 0xc5, 0xbe, 0x5c, + 0xed, 0xfb, 0x45, 0xcc, 0xf3, 0x9b, 0xf6, 0xf7, 0x8b, 0xee, 0xbe, 0x7c, + 0xbd, 0x1b, 0xc7, 0xcf, 0xbd, 0x13, 0xe7, 0xff, 0xbe, 0x5c, 0xf8, 0xfb, + 0x8f, 0xee, 0xbe, 0x7c, 0xbd, 0x1b, 0xc7, 0xcf, 0x5a, 0xc5, 0xbe, 0x5c, + 0xfe, 0xcf, 0xfe, 0xce, 0xff, 0x1f, 0xcb, 0xee, 0x62, 0xfb, 0xfe, 0x6a, + 0x00, 0x1c, 0xaf, 0x05, 0x66, 0xfb, 0xff, 0xcf, 0xff, 0x1f, 0xbb, 0xf6, + 0xfc, 0x92, 0xfc, 0x15, 0x16, 0xfd, 0xf3, 0x9b, 0xfa, 0xf7, 0xfe, 0xcf, + 0xff, 0x1f, 0xa1, 0xf9, 0x72, 0xfb, 0x9e, 0xee, 0xbe, 0x74, 0xbd, 0x1b, + 0x03, 0xcc, 0xbd, 0x13, 0x37, 0xff, 0xbe, 0x54, 0xb7, 0xb5, 0xbd, 0x1b, + 0x83, 0xcf, 0xbd, 0x13, 0xeb, 0xff, 0xbc, 0x5c, 0xbe, 0x7c, 0xbd, 0x1b, + 0xe0, 0xcf, 0xbd, 0x13, 0xf4, 0xff, 0xbe, 0x5c, 0xbe, 0x6a, 0xbf, 0x7d, + 0xbd, 0x1b, 0xe0, 0xdf, 0xb2, 0xbd, 0xdf, 0x6c, 0xea, 0xef, 0xbf, 0x97, + 0x7b, 0x93, 0xbf, 0x4c, 0xbd, 0x74, 0x78, 0xc5, 0x77, 0xc5, 0x57, 0xc5, + 0xbd, 0x54, 0x9e, 0x6a, 0x9f, 0x7c, 0xab, 0xc4, 0xb3, 0xf7, 0x91, 0xef, + 0xee, 0x7c, 0xb0, 0xc7, 0xf8, 0xf3, 0xfe, 0x15, 0x47, 0xf4, 0xff, 0xcd, + 0xff, 0x1f, 0x1d, 0xf3, 0xe3, 0xfb, 0xf3, 0xef, 0xfe, 0xce, 0xb3, 0xef, + 0xff, 0x1f, 0x8b, 0xf3, 0xbf, 0xc7, 0xf6, 0xf7, 0x9a, 0xef, 0xee, 0x7c, + 0xfe, 0x15, 0x47, 0xf4, 0xff, 0xcd, 0xff, 0x1f, 0x2c, 0xf3, 0xf2, 0xfb, + 0xff, 0xfb, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xdf, 0x00, 0xe0, 0x03, 0x00, + 0x83, 0xff, 0xff, 0xdf, 0x7a, 0xff, 0xff, 0xdf, 0x1f, 0xf4, 0xff, 0xff, + 0x9d, 0xee, 0xde, 0x7c, 0xfe, 0xcd, 0xb7, 0x93, 0x7e, 0xc6, 0x7d, 0xc6, + 0xde, 0x5c, 0xfb, 0x1b, 0xdb, 0xff, 0xff, 0x1b, 0x00, 0xdc, 0xdd, 0x74, + 0xde, 0x1b, 0x00, 0xcc, 0xbf, 0x93, 0xdd, 0x54, 0x9f, 0x7c, 0x71, 0x97, + 0xd0, 0xf7, 0x85, 0xef, 0xa1, 0xa4, 0xde, 0x7d, 0x7f, 0xc6, 0xde, 0x5d, + 0xbc, 0x7c, 0xbd, 0x1b, 0x83, 0xcf, 0xbd, 0x13, 0xd7, 0xff, 0xbc, 0x5c, + 0xff, 0x15, 0x4c, 0xfe, 0xff, 0x1f, 0x31, 0xf2, 0x32, 0xcf, 0xff, 0x1f, + 0xea, 0xfe, 0xe3, 0xfb, 0xa6, 0xc4, 0xe5, 0xf7, 0x90, 0xef, 0xbc, 0x7c, + 0xbd, 0x1b, 0x83, 0xcf, 0x5c, 0xc5, 0xbc, 0x5c, 0xec, 0xfb, 0x9e, 0x6a, + 0xbd, 0x7c, 0xbd, 0x1b, 0xf0, 0xdf, 0xbd, 0xc5, 0xf7, 0xf7, 0x97, 0xef, + 0xbf, 0x7c, 0xff, 0xce, 0x80, 0xd6, 0x7b, 0x93, 0xbf, 0x5c, 0xf9, 0xfb, + 0xfd, 0x74, 0xff, 0x1b, 0x00, 0xdc, 0xff, 0x1f, 0x06, 0xff, 0xf7, 0xeb, + 0x6c, 0xeb, 0xff, 0xff, 0x83, 0xff, 0xff, 0xdf, 0x8b, 0xff, 0xff, 0xdf, + 0x2c, 0xeb, 0xde, 0xeb, 0xff, 0x1f, 0x13, 0xf7, 0xff, 0x47, 0xff, 0xcf, + 0xff, 0x1f, 0x5f, 0xf7, 0x8b, 0xee, 0x9f, 0x7c, 0xfe, 0xc4, 0xe9, 0xf7, + 0xbf, 0x67, 0x95, 0xb5, 0xf3, 0x8b, 0xf6, 0xce, 0xfb, 0x9b, 0xfd, 0xf7, + 0xf6, 0xcc, 0x33, 0x8b, 0xd0, 0xee, 0x9e, 0x3b, 0xdc, 0xf7, 0xde, 0x7c, + 0xfc, 0xbe, 0xdf, 0x3b, 0xde, 0xf7, 0x9f, 0x7c, 0x73, 0x83, 0xb8, 0xb5, + 0xd7, 0xa6, 0xdf, 0x47, 0xc4, 0xfb, 0xbd, 0xc4, 0xf8, 0xf3, 0xbc, 0xc4, + 0xe5, 0xf7, 0x7d, 0xcc, 0x9d, 0xbc, 0xf3, 0x9b, 0xe9, 0xf3, 0xbf, 0x67, + 0x95, 0xb5, 0xf3, 0x8b, 0xf0, 0xce, 0xfb, 0x9b, 0xfd, 0xf7, 0xf0, 0xcc, + 0x33, 0x8b, 0xdd, 0xee, 0x9e, 0x3b, 0xdc, 0xf7, 0xde, 0x7c, 0xfc, 0xbe, + 0xdf, 0x3b, 0xde, 0xf7, 0x9f, 0x7c, 0x73, 0x83, 0xb8, 0xb5, 0xd7, 0xa6, + 0xdf, 0x47, 0xe1, 0xfb, 0xfc, 0xcf, 0xff, 0x1f, 0x98, 0xf7, 0x9d, 0xbf, + 0xb8, 0xbf, 0x92, 0xa5, 0xff, 0xa4, 0xff, 0x3b, 0xbf, 0xf7, 0x9d, 0xbf, + 0x95, 0xac, 0x9c, 0x3b, 0xde, 0x7b, 0x97, 0xb4, 0x9c, 0x1b, 0x01, 0xde, + 0xab, 0xef, 0x93, 0xa5, 0xbf, 0x7c, 0xb7, 0x83, 0x9e, 0x7c, 0xfc, 0xbc, + 0x9f, 0x3b, 0xdc, 0xf7, 0xff, 0x67, 0x9f, 0xa4, 0xcf, 0xb6, 0x9b, 0xa4, + 0x9f, 0x47, 0x44, 0x92, 0x51, 0xef, 0x75, 0xef, 0x9f, 0x7b, 0x9c, 0xbc, + 0x93, 0xa2, 0xdf, 0x74, 0xde, 0xbe, 0xc4, 0x93, 0xff, 0xcd, 0x00, 0x1c, + 0x04, 0x09, 0x9f, 0x7b, 0x9c, 0xbc, 0x53, 0xa2, 0xff, 0x67, 0x9e, 0x6a, + 0xf3, 0x83, 0xf0, 0xb7, 0xfe, 0xeb, 0x6c, 0xeb, 0x73, 0xff, 0xff, 0xdf, + 0x8b, 0xb7, 0xff, 0xff, 0x77, 0xb7, 0xff, 0xff, 0x6f, 0xff, 0xff, 0xdf, + 0x57, 0xb7, 0xff, 0xff, 0x8c, 0xef, 0xff, 0x5c, 0xc3, 0x87, 0xff, 0xff, + 0xce, 0xef, 0x91, 0xa6, 0xae, 0xef, 0xff, 0x7d, 0xff, 0x5c, 0xfe, 0x7d, + 0xfe, 0x5c, 0xfd, 0x7d, 0xfd, 0x5c, 0xfc, 0x7d, 0xfc, 0x5c, 0xfb, 0x7d, + 0xfb, 0x5c, 0xfa, 0x7d, 0xfa, 0x5c, 0xf9, 0x7d, 0xf9, 0x5c, 0xb8, 0x7d, + 0xb8, 0x5c, 0xff, 0xcc, 0x9f, 0x5e, 0xc3, 0x87, 0xff, 0x8b, 0xbb, 0x8b, + 0x77, 0x8b, 0xfc, 0xc7, 0xf9, 0xf7, 0x99, 0xef, 0xfc, 0x3b, 0xdf, 0xf7, + 0xdf, 0x5f, 0xbe, 0x5f, 0xc3, 0x87, 0xff, 0xff, 0x73, 0xff, 0xff, 0xdf, + 0x2f, 0xb4, 0xff, 0xff, 0x6f, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0x9f, 0x7f, + 0xe0, 0xcd, 0x37, 0x9b, 0xe6, 0xf7, 0x81, 0xcd, 0x37, 0x9b, 0xf8, 0xf3, + 0xdc, 0x1b, 0xe0, 0xef, 0xdb, 0xae, 0xfc, 0xde, 0xbb, 0x8b, 0xee, 0xfb, + 0x21, 0xcd, 0x37, 0x9b, 0xf8, 0xf3, 0xdc, 0x1b, 0x80, 0xef, 0xdc, 0xae, + 0xf6, 0xde, 0xbb, 0x8b, 0xf7, 0xfb, 0xdc, 0x1b, 0x20, 0xef, 0xdd, 0xae, + 0xe0, 0xde, 0xbb, 0x8b, 0xfd, 0xfb, 0xfc, 0xce, 0xff, 0xd6, 0xbb, 0x8b, + 0xff, 0x1f, 0x8b, 0xf0, 0x6f, 0xeb, 0xff, 0xff, 0x2f, 0xeb, 0xff, 0x1f, + 0xa6, 0xec, 0xff, 0x1f, 0xaa, 0xf0, 0xff, 0x1f, 0x94, 0xf2, 0xff, 0x1f, + 0x48, 0xeb, 0xff, 0x1f, 0xac, 0xef, 0xff, 0x1f, 0x6e, 0xea, 0xff, 0x1f, + 0x52, 0xf3, 0xff, 0x1f, 0x0e, 0xea, 0x6f, 0xeb, 0x2f, 0xeb, 0xff, 0x1f, + 0x90, 0xea, 0x6f, 0xeb, 0xfe, 0xcd, 0x8c, 0xed, 0xbf, 0x5c, 0xc3, 0x87, + 0x2f, 0xeb, 0xee, 0xed, 0xff, 0xcc, 0x9e, 0x57, 0x9f, 0x5f, 0xfc, 0xdf, + 0xfe, 0xce, 0xb0, 0xed, 0xff, 0x1f, 0xd7, 0xf4, 0x6f, 0xeb, 0xff, 0xff, + 0x94, 0xed, 0xfe, 0x54, 0xc3, 0x87, 0xff, 0xff, 0xfe, 0x8b, 0xbf, 0xc7, + 0xf9, 0xf3, 0xff, 0xcc, 0x80, 0xd4, 0xb8, 0xed, 0x9a, 0x5d, 0xfb, 0xfb, + 0xbf, 0xcd, 0x9a, 0xed, 0xba, 0x5c, 0xc3, 0x87, 0x9c, 0xed, 0xfe, 0x74, + 0xc3, 0x87, 0xff, 0xff, 0x2b, 0xeb, 0xd6, 0xeb, 0x38, 0x93, 0xbf, 0x8a, + 0xf6, 0x8a, 0xbf, 0xc6, 0xc1, 0xf6, 0xef, 0xcf, 0x00, 0x1c, 0xe9, 0x09, + 0x7c, 0x92, 0xff, 0xcf, 0xff, 0x1f, 0x69, 0xf8, 0x3c, 0x92, 0xe3, 0xc2, + 0xd2, 0xf6, 0x84, 0xee, 0x5c, 0x3b, 0xbc, 0xf7, 0x9f, 0x6c, 0xf3, 0x87, + 0xfe, 0xcc, 0x9f, 0x59, 0x7e, 0x8b, 0xfc, 0x15, 0xd9, 0xfd, 0x73, 0x9b, + 0xfc, 0xf7, 0xf8, 0x15, 0xd9, 0xfd, 0x22, 0x8b, 0xba, 0xbc, 0xb3, 0xa5, + 0xd9, 0xbd, 0xbb, 0xa5, 0xbc, 0x3b, 0xdc, 0xf7, 0xbc, 0xbc, 0x92, 0xa5, + 0x8f, 0xac, 0x9e, 0x59, 0xec, 0xfa, 0xfd, 0xcc, 0x9f, 0x59, 0xff, 0x1f, + 0x34, 0xf6, 0xfe, 0x59, 0xff, 0xcf, 0xff, 0x1f, 0x26, 0xf1, 0xf5, 0xfa, + 0xfc, 0xcc, 0x9f, 0x59, 0xbd, 0xa1, 0xbf, 0x47, 0xb2, 0xc2, 0xc4, 0xf3, + 0xfe, 0xcf, 0xff, 0x1f, 0x98, 0xf8, 0x9c, 0xee, 0xfe, 0x74, 0xe2, 0xa7, + 0xf8, 0xbf, 0xa0, 0x93, 0xff, 0x1f, 0x8f, 0xe9, 0x3c, 0x93, 0xff, 0xcd, + 0x81, 0xd5, 0x7e, 0x9b, 0xfd, 0xf3, 0x34, 0x93, 0xb0, 0x92, 0x80, 0xcd, + 0x36, 0x9b, 0xfd, 0xf3, 0x80, 0xca, 0xff, 0x1f, 0x7e, 0xfb, 0xbe, 0xc7, + 0xe1, 0xf7, 0x87, 0xef, 0x9f, 0x7c, 0xbf, 0xc4, 0xf8, 0xf3, 0xbe, 0xc2, + 0x0c, 0xf3, 0xff, 0xcc, 0xff, 0xd4, 0x29, 0x9b, 0x0e, 0xf3, 0xbf, 0xc2, + 0xed, 0xf7, 0x8d, 0xef, 0x9a, 0x7c, 0xbf, 0xc4, 0xf1, 0xf3, 0x71, 0x8b, + 0x20, 0xc5, 0xfb, 0xf7, 0x39, 0xc4, 0xfb, 0xf7, 0xfa, 0xfb, 0xfe, 0xca, + 0xfc, 0xfb, 0xff, 0xca, 0xff, 0xd2, 0xff, 0xcd, 0x95, 0xef, 0xba, 0x5c, + 0x96, 0xef, 0x59, 0x5c, 0xab, 0x8a, 0xfd, 0xfb, 0xff, 0xca, 0x9f, 0x67, + 0x5f, 0x5c, 0x39, 0xfb, 0xc7, 0xcc, 0x9f, 0x59, 0xc4, 0xcc, 0x9e, 0x59, + 0xfd, 0xcc, 0x9d, 0x59, 0xff, 0xcc, 0xbb, 0xd4, 0x9c, 0x59, 0x43, 0xfb, + 0x67, 0xff, 0xff, 0xdf, 0x93, 0xe7, 0xff, 0xff, 0x37, 0xb7, 0xff, 0xff, + 0xfe, 0xe2, 0xe8, 0x93, 0xff, 0x1f, 0xe9, 0xe9, 0xba, 0x6a, 0x99, 0x6a, + 0xff, 0xce, 0xa4, 0xd6, 0xdf, 0x59, 0xf7, 0xce, 0xde, 0x59, 0xc7, 0xb5, + 0xdd, 0x59, 0xcf, 0xb5, 0xdc, 0x59, 0xd7, 0xb5, 0xdb, 0x59, 0xba, 0x59, + 0xa7, 0xb4, 0xb9, 0x59, 0xaf, 0xb4, 0xb8, 0x59, 0xb7, 0xb4, 0xb7, 0x59, + 0x96, 0x59, 0xff, 0xcc, 0x95, 0x59, 0x94, 0x59, 0x93, 0x59, 0x67, 0xfb, + 0xe7, 0xcc, 0x9f, 0x59, 0xf4, 0xcc, 0x9e, 0x59, 0x6c, 0xfb, 0xc7, 0xcc, + 0x9f, 0x59, 0xf5, 0xcc, 0x9e, 0x59, 0xff, 0x1f, 0x48, 0xff, 0x9f, 0x7f, + 0xbf, 0xc4, 0xfa, 0xf7, 0x98, 0xd4, 0x9f, 0x5f, 0xc5, 0xcc, 0x9e, 0x5f, + 0x9f, 0x7f, 0x9d, 0x59, 0x9e, 0x7f, 0x9c, 0x59, 0x7e, 0xfb, 0xe7, 0xcc, + 0x9f, 0x59, 0xff, 0xcc, 0xb6, 0xd4, 0x9e, 0x59, 0x84, 0xfb, 0xe7, 0xcc, + 0x9f, 0x59, 0xff, 0xcc, 0xb7, 0xd4, 0x9e, 0x59, 0x8a, 0xfb, 0xe7, 0xcc, + 0x9f, 0x59, 0xff, 0x1f, 0x64, 0xff, 0x9f, 0x7f, 0xb3, 0xcd, 0x71, 0x9b, + 0xfb, 0xf3, 0xc0, 0xcd, 0x71, 0x9b, 0xfc, 0xf7, 0x9e, 0x59, 0x97, 0xfb, + 0xb3, 0xcc, 0x9e, 0x59, 0x9a, 0xfb, 0xff, 0x1f, 0x72, 0xff, 0x9f, 0x7f, + 0x9f, 0x59, 0xd7, 0xcd, 0x71, 0x9b, 0xe7, 0xf3, 0x37, 0x9b, 0xf9, 0xf3, + 0xe8, 0xd4, 0xfe, 0xcd, 0x37, 0x9b, 0xa7, 0xf3, 0xec, 0xfb, 0xb7, 0xcd, + 0x71, 0x9b, 0xf5, 0xf3, 0xa7, 0xcd, 0x71, 0x9b, 0xfa, 0xf3, 0xc7, 0xcd, + 0x71, 0x9b, 0xb1, 0xf7, 0xfa, 0xfb, 0x9a, 0x7f, 0x9a, 0x59, 0x9b, 0x7f, + 0x9b, 0x59, 0x9c, 0x7f, 0x9c, 0x59, 0x9d, 0x7f, 0x9d, 0x59, 0x9e, 0x7f, + 0x9e, 0x59, 0xbd, 0xfb, 0x00, 0x1c, 0xff, 0x01, 0xf7, 0xe4, 0xff, 0x4c, + 0xf2, 0xc2, 0xf8, 0xf7, 0xfb, 0xcc, 0x9f, 0x59, 0xf7, 0xe4, 0x9f, 0x6c, + 0x9e, 0x59, 0xce, 0xfb, 0xce, 0xcc, 0x9f, 0x59, 0xb1, 0xc2, 0xe9, 0xf7, + 0xfe, 0xcc, 0x9e, 0x59, 0x00, 0x1c, 0xff, 0x09, 0x3f, 0x8b, 0x87, 0xcd, + 0x71, 0x9b, 0xfb, 0xf3, 0xaf, 0xcd, 0x71, 0x9b, 0xf9, 0xf7, 0xf7, 0xe4, + 0xfd, 0x15, 0xa1, 0xf5, 0xbf, 0x4c, 0xe8, 0xfb, 0xf7, 0xe4, 0xfd, 0x15, + 0xad, 0xf7, 0xbf, 0x4c, 0xed, 0xfb, 0xb0, 0xc2, 0xfb, 0xf7, 0xfd, 0xcc, + 0x9e, 0x59, 0xf2, 0xfb, 0xff, 0xcc, 0x9e, 0x59, 0x81, 0xef, 0x99, 0x7c, + 0x31, 0x8b, 0xde, 0xc4, 0xf9, 0xf7, 0xf7, 0xe4, 0xbf, 0x6c, 0xbd, 0x1b, + 0x71, 0xfd, 0xbf, 0x4c, 0xf7, 0xe4, 0xbf, 0x6c, 0xb7, 0xb5, 0xbd, 0x59, + 0x9f, 0x6c, 0x9c, 0x59, 0xf3, 0xcf, 0xf7, 0xe6, 0xff, 0xcd, 0xff, 0x1f, + 0xa4, 0xff, 0x8b, 0xef, 0xfb, 0x7c, 0xac, 0x93, 0x64, 0x93, 0xff, 0x1f, + 0xc8, 0xf5, 0xf2, 0xfb, 0xaf, 0xef, 0xfb, 0x7d, 0xac, 0x93, 0x70, 0x93, + 0xff, 0x1f, 0xcf, 0xf5, 0xf9, 0xfb, 0xfd, 0xca, 0xdb, 0xf8, 0xff, 0xca, + 0xfe, 0xd2, 0xde, 0xf8, 0xf6, 0xeb, 0x6b, 0xeb, 0x2e, 0xeb, 0xff, 0x8a, + 0xf0, 0xcf, 0x00, 0x1c, 0x36, 0x0b, 0xbc, 0x93, 0xbf, 0xc7, 0xfb, 0xf3, + 0xec, 0x93, 0xff, 0x1f, 0xde, 0xed, 0x6e, 0xeb, 0xc3, 0x87, 0xff, 0xff, + 0x9d, 0xef, 0xf9, 0x7c, 0xc3, 0x87, 0xff, 0xff, 0x67, 0xff, 0xff, 0xdf, + 0xfe, 0xef, 0xc3, 0x87, 0x5e, 0xff, 0xff, 0xdf, 0x2d, 0xeb, 0x81, 0xed, + 0xb8, 0x6c, 0x5f, 0xc5, 0xb8, 0x4c, 0x62, 0xed, 0xff, 0xca, 0x58, 0x5b, + 0x57, 0x5b, 0xfb, 0x1b, 0xf4, 0xff, 0xff, 0xce, 0xf3, 0xcd, 0x00, 0x1c, + 0x2e, 0x0b, 0x9b, 0x1b, 0xe8, 0xff, 0xbb, 0x1b, 0xe0, 0xff, 0xbe, 0x4c, + 0xfc, 0xcd, 0xbd, 0x5c, 0x5f, 0x5c, 0x5e, 0x5c, 0x98, 0x7b, 0x5f, 0xc4, + 0x98, 0x5b, 0xfb, 0x1b, 0xdc, 0xff, 0xff, 0xce, 0xae, 0xed, 0xff, 0x1f, + 0x78, 0xf6, 0xbf, 0xc7, 0xf6, 0xf7, 0x6c, 0x93, 0xfb, 0x27, 0xdb, 0xff, + 0xf9, 0xdd, 0xea, 0xce, 0xff, 0x1f, 0x19, 0xf6, 0x6d, 0xeb, 0xff, 0xfb, + 0x2e, 0xeb, 0xff, 0x8a, 0x77, 0x8b, 0xb3, 0xc3, 0xf9, 0xf7, 0x96, 0xed, + 0x9f, 0x7c, 0x3a, 0xc4, 0xd2, 0xf7, 0xa0, 0xfb, 0xef, 0xc3, 0xb5, 0xf7, + 0x99, 0xed, 0x7c, 0x3b, 0xbc, 0xf7, 0x9f, 0x6c, 0xf3, 0x87, 0xbf, 0x76, + 0x9d, 0xed, 0xba, 0x54, 0xbe, 0xfb, 0x9e, 0xed, 0xbf, 0x76, 0xb7, 0xb5, + 0xbc, 0x5c, 0xbf, 0x76, 0xbb, 0x5c, 0xc5, 0xfb, 0x82, 0xee, 0xbf, 0x7e, + 0xbf, 0xc5, 0xff, 0x3b, 0xfe, 0xfa, 0xbf, 0x7c, 0x7f, 0xc5, 0x7b, 0x93, + 0xbf, 0x5c, 0xcf, 0xfb, 0xbf, 0x7e, 0x87, 0xee, 0xbd, 0x5c, 0xd3, 0xfb, + 0x89, 0xee, 0xbf, 0x7e, 0xbf, 0xc5, 0xff, 0x3b, 0xfe, 0xfa, 0xde, 0xbe, + 0xbf, 0x7c, 0x7e, 0xc5, 0x7b, 0x93, 0xbf, 0x5c, 0xde, 0xfb, 0xbf, 0x6e, + 0x8f, 0xee, 0xbb, 0x54, 0xe2, 0xfb, 0xbf, 0xc5, 0xe4, 0xf3, 0xbf, 0x7e, + 0x92, 0xee, 0xba, 0x5c, 0xe8, 0xfb, 0x93, 0xee, 0xdf, 0x7e, 0xde, 0x1b, + 0xfe, 0xdf, 0xdd, 0xbe, 0xbf, 0x7c, 0x7d, 0xc5, 0x7b, 0x93, 0xbf, 0x5c, + 0xf2, 0xfb, 0x34, 0x93, 0xfa, 0xcf, 0x7f, 0x9b, 0xfd, 0xf7, 0xfa, 0xcc, + 0x73, 0x8b, 0xbf, 0xc5, 0xfa, 0xf3, 0xf8, 0x93, 0xdf, 0xee, 0x00, 0x1c, + 0xfc, 0x0b, 0x9c, 0xee, 0xbe, 0x7c, 0x77, 0x8b, 0xff, 0xdd, 0xdd, 0x7c, + 0x7b, 0x97, 0x9f, 0x7c, 0x33, 0x8b, 0x35, 0x9b, 0xf3, 0xf3, 0x81, 0xef, + 0xde, 0x7c, 0xbb, 0x8b, 0xfe, 0x6c, 0xdb, 0xa7, 0x7f, 0x5e, 0xbe, 0x5c, + 0xfe, 0xcf, 0xfb, 0xfb, 0xff, 0xcf, 0xfd, 0xfb, 0xfe, 0xcf, 0x6e, 0xeb, + 0x2c, 0xeb, 0xfc, 0x92, 0x9f, 0x7f, 0x3f, 0xc4, 0xae, 0xf2, 0x7d, 0xc4, + 0x9f, 0x5f, 0x8b, 0xef, 0xbf, 0x7c, 0x77, 0x8b, 0x9e, 0x7c, 0x33, 0x8b, + 0x35, 0x9b, 0xb7, 0xf2, 0x8f, 0xef, 0xdf, 0x7c, 0xbb, 0x8b, 0xbe, 0x6c, + 0xbb, 0xa5, 0xbf, 0x7d, 0xff, 0xde, 0xbb, 0x8b, 0xdf, 0x5c, 0xdf, 0x7c, + 0xfd, 0x7c, 0xbf, 0x97, 0xdf, 0x5c, 0x9a, 0xef, 0xd3, 0x6c, 0xde, 0x1b, + 0x00, 0xcf, 0xb7, 0x93, 0xd3, 0x4c, 0xef, 0xc5, 0xf1, 0xfb, 0xff, 0xff, + 0xff, 0x6f, 0xff, 0xbf, 0x5f, 0xff, 0xff, 0xdf, 0xd3, 0xe2, 0xff, 0xff, + 0x53, 0xff, 0xff, 0xdf, 0xc3, 0xb6, 0xff, 0xff, 0x47, 0xff, 0xff, 0xdf, + 0xe3, 0xf6, 0x9d, 0xec, 0xbc, 0x3b, 0xbd, 0xf7, 0x9f, 0x6d, 0xf3, 0x87, + 0x9f, 0xec, 0xd2, 0x6c, 0xbf, 0xec, 0xb7, 0x97, 0xbf, 0xec, 0xfa, 0x75, + 0xf7, 0xb7, 0xf7, 0xbf, 0xbf, 0x93, 0xd2, 0x4c, 0xd2, 0x6c, 0xde, 0x1b, + 0x00, 0xcf, 0xb5, 0x7d, 0x7b, 0x93, 0xb2, 0x4c, 0xf9, 0xfa, 0x47, 0xed, + 0x32, 0x6a, 0x87, 0xed, 0x73, 0x96, 0x00, 0x1c, 0x56, 0x0a, 0x97, 0xbf, + 0x73, 0x92, 0x32, 0x4a, 0x03, 0xfb, 0x8c, 0xed, 0xd2, 0x6c, 0xac, 0xed, + 0xb7, 0x97, 0xac, 0xed, 0xfc, 0x7d, 0xf7, 0xbf, 0xbf, 0x93, 0xd2, 0x4c, + 0xd2, 0x6c, 0xde, 0x1b, 0x00, 0xcf, 0xbb, 0x7d, 0x7b, 0x93, 0xb2, 0x4c, + 0x13, 0xfb, 0x94, 0xed, 0xb2, 0x6c, 0xd4, 0xed, 0x7b, 0x97, 0xd4, 0xed, + 0xdd, 0x7e, 0xd7, 0xbe, 0x7b, 0x93, 0xb2, 0x4c, 0xb2, 0x6c, 0xbd, 0x1b, + 0x00, 0xcf, 0xb2, 0x4c, 0x21, 0xfb, 0x9b, 0xed, 0xb2, 0x6c, 0xdb, 0xed, + 0x7b, 0x97, 0xdb, 0xed, 0xdf, 0x7e, 0xde, 0x1b, 0xfe, 0xdf, 0xd7, 0xbe, + 0x7b, 0x93, 0xb2, 0x4c, 0xb2, 0x6c, 0xbd, 0x1b, 0x00, 0xcf, 0xb2, 0x4c, + 0x31, 0xfb, 0x83, 0xee, 0xb2, 0x6c, 0xc3, 0xee, 0x7b, 0x97, 0xc3, 0xee, + 0xdf, 0x7e, 0xd8, 0xbe, 0xde, 0x1b, 0xff, 0xde, 0x7b, 0x93, 0xb2, 0x4c, + 0xb2, 0x6c, 0xbd, 0x1b, 0x00, 0xcf, 0xb2, 0x4c, 0x41, 0xfb, 0x89, 0xee, + 0x9f, 0x7c, 0x82, 0xbc, 0x80, 0xb4, 0xdf, 0xc4, 0xbc, 0x9a, 0x58, 0xba, + 0x00, 0x1c, 0xa1, 0x0a, 0x90, 0xee, 0xd2, 0x6c, 0xb0, 0xee, 0xb7, 0x97, + 0xeb, 0x93, 0xff, 0x8b, 0xf7, 0xbf, 0xbf, 0x93, 0xd2, 0x4c, 0xd2, 0x6c, + 0xde, 0x1b, 0x00, 0xcf, 0xde, 0x13, 0xe9, 0xff, 0xd2, 0x4c, 0xd1, 0x6c, + 0x7b, 0x97, 0xbd, 0x13, 0xff, 0xe6, 0xb1, 0x4c, 0xb1, 0x6c, 0xbd, 0x1b, + 0x00, 0xcf, 0xbd, 0x13, 0xb0, 0xff, 0xb1, 0x4c, 0x65, 0xfb, 0x9d, 0xee, + 0xf2, 0x6c, 0xdd, 0xee, 0xfb, 0x97, 0xbc, 0xee, 0x5f, 0x7d, 0x57, 0xba, + 0xeb, 0x93, 0xf2, 0x4c, 0xf2, 0x6c, 0xff, 0x1b, 0x00, 0xcf, 0x5e, 0x7d, + 0xeb, 0x93, 0xf2, 0x4c, 0xf1, 0x6c, 0xbf, 0x97, 0xbd, 0x7d, 0xb7, 0xbd, + 0x7b, 0x93, 0xb1, 0x4c, 0x7b, 0xfb, 0x88, 0xef, 0xf2, 0x6c, 0xc8, 0xef, + 0xfb, 0x97, 0xa7, 0xef, 0x5f, 0x7d, 0x57, 0xba, 0xeb, 0x93, 0xf2, 0x4c, + 0xf2, 0x6c, 0xff, 0x1b, 0x00, 0xcf, 0x5e, 0x7d, 0xeb, 0x93, 0xf2, 0x4c, + 0xf1, 0x6c, 0xbf, 0x97, 0xfd, 0x7d, 0xf7, 0xbf, 0xbf, 0x93, 0xd1, 0x4c, + 0xd1, 0x6c, 0xde, 0x1b, 0x00, 0xcf, 0xbc, 0x7d, 0x7b, 0x93, 0xb1, 0x4c, + 0x97, 0xfb, 0x96, 0xef, 0xb3, 0x6c, 0xdd, 0x1b, 0x00, 0xcf, 0xb5, 0xef, + 0xff, 0x7d, 0xbf, 0x93, 0xd3, 0x4c, 0xf2, 0x6c, 0xda, 0xef, 0xfb, 0x97, + 0x5e, 0x7d, 0x57, 0xba, 0xf3, 0xfb, 0xff, 0xff, 0x7f, 0xb6, 0xff, 0xff, + 0xff, 0x6f, 0xff, 0xbf, 0x00, 0xff, 0x00, 0x00, 0x53, 0xff, 0xff, 0xdf, + 0x5f, 0xff, 0xff, 0xdf, 0xeb, 0x93, 0xf2, 0x4c, 0xf2, 0x6c, 0xff, 0x1b, + 0x00, 0xcf, 0x5d, 0x7d, 0xeb, 0x93, 0xf2, 0x4c, 0xf1, 0x6c, 0xbf, 0x97, + 0xfc, 0x7d, 0xf7, 0xbf, 0xbf, 0x93, 0xd1, 0x4c, 0xd1, 0x6c, 0xde, 0x1b, + 0x00, 0xcf, 0xbb, 0x7d, 0x7b, 0x93, 0xb1, 0x4c, 0xc5, 0xfb, 0x9d, 0xec, + 0xb2, 0x6c, 0xdd, 0xec, 0x7b, 0x97, 0xdd, 0xec, 0xdf, 0x7e, 0xda, 0xbe, + 0xde, 0x1b, 0xff, 0xd8, 0x7b, 0x93, 0xb2, 0x4c, 0xd1, 0xfb, 0x83, 0xed, + 0xf2, 0x6c, 0xc3, 0xed, 0xfb, 0x97, 0xa3, 0xed, 0x5b, 0x75, 0x57, 0xb2, + 0x57, 0xba, 0xeb, 0x93, 0xf2, 0x4c, 0xf2, 0x6c, 0xff, 0x1b, 0x00, 0xcf, + 0x57, 0x7d, 0xeb, 0x93, 0xf2, 0x4c, 0xf1, 0x6c, 0xfb, 0x97, 0xd9, 0x7d, + 0x57, 0xbe, 0xeb, 0x93, 0xff, 0xde, 0xd9, 0x5d, 0xf1, 0x4c, 0xea, 0xfb, + 0x90, 0xed, 0xd2, 0x6c, 0xb0, 0xed, 0xb7, 0x97, 0xf0, 0xed, 0xfa, 0x7f, + 0xf7, 0xbf, 0xbf, 0x93, 0xd2, 0x4c, 0xd2, 0x6c, 0xde, 0x1b, 0x00, 0xcf, + 0xd2, 0x4c, 0xd1, 0x6c, 0x7b, 0x97, 0xb1, 0x4c, 0xb1, 0x6c, 0xbd, 0x1b, + 0x00, 0xcf, 0xb1, 0x4c, 0xff, 0xcd, 0x97, 0xed, 0xb7, 0x5c, 0xff, 0x1f, + 0xc4, 0xf5, 0x9f, 0x7b, 0x5d, 0xc4, 0x7f, 0xc4, 0x9f, 0x5b, 0x9f, 0x7b, + 0x3d, 0xc4, 0xf1, 0xf3, 0xbd, 0xed, 0x97, 0x7d, 0xff, 0xdc, 0x33, 0x8b, + 0x97, 0x5d, 0xf5, 0xcd, 0x37, 0x9b, 0xf9, 0xf7, 0xff, 0xcd, 0x81, 0xee, + 0xb7, 0x5c, 0xff, 0x1f, 0xd8, 0xf5, 0x86, 0xee, 0x9c, 0x6c, 0xa4, 0xee, + 0xbd, 0x27, 0xda, 0xff, 0x33, 0x8b, 0x35, 0x9b, 0x34, 0xf3, 0x8a, 0xee, + 0xbc, 0x6c, 0x77, 0x8b, 0xaa, 0xcc, 0x35, 0x9b, 0x3a, 0xf7, 0x8d, 0xee, + 0x7f, 0x6c, 0xef, 0x8a, 0x9b, 0x1b, 0x80, 0xef, 0x73, 0x8b, 0xef, 0xc5, + 0x48, 0xf7, 0x34, 0x93, 0xae, 0xee, 0x9d, 0x3b, 0xbc, 0xf7, 0x9f, 0x6c, + 0xf3, 0x87, 0xff, 0x1f, 0x90, 0xf9, 0xbf, 0xc7, 0x52, 0xf7, 0x96, 0xee, + 0xdf, 0x6c, 0xbe, 0x6c, 0x87, 0xb6, 0x97, 0xbc, 0x77, 0x8b, 0x37, 0x93, + 0xb5, 0xee, 0x9e, 0x55, 0xfd, 0x15, 0x1e, 0xfd, 0x37, 0x9b, 0xfa, 0xf7, + 0x98, 0xee, 0xbe, 0x54, 0xfe, 0xcd, 0xfd, 0xfb, 0xff, 0xcd, 0x9f, 0xee, + 0xdf, 0x6c, 0x5f, 0x6c, 0xfe, 0x3b, 0x7c, 0x8f, 0x97, 0xbc, 0xfa, 0x3b, + 0xba, 0x8f, 0xb3, 0x92, 0x9f, 0xee, 0x5f, 0x54, 0xfc, 0x15, 0x09, 0xfc, + 0xb3, 0x9a, 0xf9, 0xf7, 0xfd, 0x15, 0x09, 0xfc, 0x83, 0xef, 0xbf, 0x54, + 0xef, 0xfb, 0xbf, 0xc5, 0xf1, 0xf7, 0xff, 0x1f, 0x38, 0xf6, 0xbf, 0x9a, + 0xfa, 0xf7, 0xfe, 0xcf, 0x00, 0x1c, 0xc3, 0x03, 0xf9, 0xfb, 0xeb, 0x9b, + 0xfb, 0xf7, 0xff, 0xcf, 0x00, 0x1c, 0xc9, 0x03, 0x8e, 0xef, 0xfb, 0xcd, + 0xa9, 0x54, 0xbc, 0x1b, 0xd8, 0xff, 0xb3, 0x4c, 0xfc, 0x1b, 0xd4, 0xff, + 0xff, 0x1f, 0x11, 0xf9, 0x92, 0xfb, 0x96, 0xef, 0xff, 0x6c, 0xdf, 0x6c, + 0xbf, 0x6c, 0xf7, 0xb7, 0xff, 0xd7, 0xff, 0x8b, 0xfe, 0x3b, 0xbe, 0x8f, + 0xa7, 0xb5, 0x00, 0x1c, 0x40, 0x04, 0xfd, 0xcf, 0xff, 0xce, 0xff, 0xcd, + 0xf1, 0xfb, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xbf, 0x00, 0xff, 0x00, 0x00, + 0x53, 0xff, 0xff, 0xdf, 0x5f, 0xff, 0xff, 0xdf, 0x3b, 0xb6, 0xff, 0xff, + 0x37, 0xff, 0xff, 0xdf, 0x00, 0x1c, 0x4d, 0x02, 0xb2, 0xfb, 0x97, 0xec, + 0x9f, 0x6c, 0xfc, 0x3b, 0x7c, 0x8f, 0xbf, 0xc4, 0xf2, 0xf3, 0xb9, 0xec, + 0x9f, 0x7d, 0xdc, 0xb4, 0xde, 0x1b, 0xf9, 0xdf, 0x5f, 0xc6, 0xdc, 0xbe, + 0x9c, 0x1b, 0xc7, 0xcf, 0x3b, 0x93, 0x9f, 0x5d, 0xc4, 0xfb, 0xbf, 0xec, + 0x9f, 0x7d, 0xdc, 0x1b, 0xef, 0xdf, 0x9c, 0x1b, 0xc7, 0xcf, 0x3b, 0x93, + 0x9f, 0x5d, 0xcd, 0xfb, 0xfe, 0xcf, 0xff, 0xce, 0xff, 0xcd, 0x00, 0x1c, + 0x6e, 0x02, 0xd3, 0xfb, 0xf4, 0xcf, 0xff, 0xce, 0xff, 0xcd, 0x00, 0x1c, + 0x74, 0x02, 0xd9, 0xfb, 0xf9, 0xcf, 0xff, 0x1f, 0x22, 0xfa, 0xdd, 0xfb, + 0xad, 0xed, 0xde, 0x6d, 0x8c, 0xed, 0xcf, 0xb6, 0xd9, 0x5c, 0xde, 0x6d, + 0xd7, 0xb6, 0xda, 0x5c, 0xde, 0x6d, 0xdb, 0x5c, 0xbf, 0x6d, 0xa7, 0xb5, + 0xbc, 0x5c, 0x93, 0xed, 0xbf, 0x6c, 0xaf, 0xb5, 0x93, 0xed, 0xbd, 0x5c, + 0x96, 0xed, 0xbf, 0x6c, 0xb7, 0xb5, 0x95, 0xed, 0xbe, 0x5c, 0xf6, 0xed, + 0xfa, 0xcc, 0x89, 0x57, 0xf3, 0x4f, 0x9b, 0x1b, 0x8c, 0xef, 0x9f, 0x5f, + 0xd4, 0xdf, 0xff, 0x1f, 0x7e, 0xf9, 0x9b, 0xed, 0x6e, 0x5c, 0xbe, 0xed, + 0xbc, 0x6d, 0xbc, 0x23, 0xda, 0xff, 0x00, 0x1c, 0xd8, 0x02, 0xbf, 0x8a, + 0x91, 0xa2, 0x33, 0x8b, 0xf7, 0xc4, 0xe4, 0xf7, 0xc3, 0xee, 0x9f, 0x7e, + 0xbc, 0xb4, 0xbd, 0x1b, 0xfa, 0xdf, 0x5e, 0xc5, 0xfd, 0x1b, 0xf8, 0xdf, + 0xfc, 0xbf, 0x9c, 0x1b, 0xc7, 0xcf, 0x3f, 0x93, 0x9f, 0x5e, 0x3f, 0xc5, + 0xe5, 0xf3, 0x38, 0x93, 0x5d, 0xc5, 0xbd, 0x1b, 0xf8, 0xdf, 0xbc, 0xbd, + 0xdf, 0x7e, 0xde, 0x1b, 0xc7, 0xcf, 0xb7, 0x93, 0xdf, 0x5c, 0xf0, 0xfb, + 0xba, 0x1b, 0xf6, 0xff, 0x77, 0x8b, 0xeb, 0xcc, 0x73, 0x9b, 0xf6, 0xf7, + 0xb3, 0xee, 0x9f, 0x7d, 0xdc, 0x1b, 0xf7, 0xdf, 0x9c, 0x1b, 0xc7, 0xcf, + 0x3b, 0x93, 0x9f, 0x5d, 0x97, 0xee, 0xbf, 0x7c, 0xbc, 0xb5, 0xbd, 0x1b, + 0xf8, 0xdf, 0x9e, 0x7c, 0x9c, 0x1b, 0xf8, 0xdf, 0x71, 0x9b, 0xea, 0xf3, + 0xbd, 0x1b, 0xfb, 0xdf, 0xbf, 0xc5, 0xfa, 0xf3, 0xfe, 0xcf, 0xff, 0x1f, + 0x6c, 0xf5, 0xfb, 0xfb, 0xff, 0xcf, 0xff, 0x1f, 0x70, 0xf5, 0x81, 0xef, + 0x9f, 0x7c, 0x3c, 0xc4, 0xf9, 0xf3, 0xf4, 0xcf, 0xff, 0xce, 0xff, 0xcd, + 0x00, 0x1c, 0xed, 0x02, 0x86, 0xef, 0xdf, 0x7c, 0xdc, 0xb6, 0xde, 0x1b, + 0xf8, 0xdf, 0xbe, 0x7c, 0xbd, 0x1b, 0xf8, 0xcf, 0x7b, 0x93, 0xbe, 0x5c, + 0x6c, 0xef, 0x9d, 0x6b, 0x9c, 0x1b, 0x00, 0xcf, 0xb3, 0x92, 0x5d, 0x4b, + 0x5d, 0x6b, 0xac, 0xef, 0xb7, 0x96, 0xfe, 0xcf, 0xff, 0x1f, 0xf7, 0xfc, + 0x9d, 0xb7, 0xff, 0xdc, 0x33, 0x8b, 0x97, 0xbc, 0xb3, 0x92, 0x5d, 0x4b, + 0x5d, 0x6b, 0x91, 0xef, 0xb3, 0x96, 0xff, 0xcf, 0xff, 0x1f, 0x03, 0xfd, + 0x9d, 0xb7, 0x33, 0x8b, 0x8f, 0xbc, 0xb3, 0x92, 0x5d, 0x4b, 0x5d, 0x6b, + 0x57, 0xba, 0x57, 0xb2, 0xfc, 0xcf, 0xff, 0x1f, 0x0e, 0xfd, 0xfd, 0xb7, + 0xf3, 0xfb, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xbf, 0x53, 0xff, 0xff, 0xdf, + 0x5f, 0xff, 0xff, 0xdf, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xe7, 0xbf, 0xbf, 0x92, 0x5d, 0x4b, 0x6c, 0xeb, 0x2f, 0xeb, 0xde, 0xeb, + 0xd1, 0x1b, 0xfd, 0xff, 0xff, 0x5e, 0xf8, 0xcf, 0xff, 0xcd, 0x00, 0x1c, + 0x34, 0x03, 0xfe, 0xeb, 0x6f, 0xeb, 0xff, 0xff, 0x9b, 0xec, 0xbd, 0x7c, + 0xf7, 0xcc, 0x73, 0x9b, 0xf5, 0xf7, 0x9d, 0xec, 0x9f, 0x7c, 0x9c, 0x1b, + 0xfd, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0xff, 0x3b, 0xff, 0xfa, 0xfd, 0xfb, + 0xff, 0xcf, 0xc3, 0x87, 0x83, 0xed, 0xfd, 0x7c, 0xc3, 0x87, 0xff, 0xff, + 0x2d, 0xeb, 0x84, 0xed, 0xbc, 0x6c, 0x77, 0x8b, 0x55, 0xcc, 0x35, 0x9b, + 0xf9, 0xf7, 0x86, 0xed, 0xb8, 0x7c, 0x5f, 0xc5, 0xb8, 0x5c, 0x37, 0xfb, + 0x8a, 0xed, 0xbc, 0x6c, 0x77, 0x8b, 0xaa, 0xcc, 0x35, 0x9b, 0x3d, 0xf7, + 0x8d, 0xed, 0x7f, 0x6c, 0xef, 0x8a, 0x9b, 0x1b, 0x80, 0xef, 0x73, 0x8b, + 0xef, 0xc5, 0x4b, 0xf7, 0x34, 0x93, 0xaf, 0xed, 0x9d, 0x3b, 0xbc, 0xf7, + 0x9f, 0x6c, 0xf3, 0x87, 0xff, 0x1f, 0x11, 0xfb, 0xbf, 0xc7, 0x55, 0xf7, + 0x96, 0xed, 0xdf, 0x6c, 0xbe, 0x6c, 0x87, 0xb6, 0x97, 0xbc, 0x77, 0x8b, + 0x37, 0x93, 0xb6, 0xed, 0x9e, 0x55, 0xfd, 0x15, 0x1e, 0xfd, 0x37, 0x9b, + 0xfa, 0xf7, 0x99, 0xed, 0xbe, 0x54, 0xfe, 0xcd, 0xfd, 0xfb, 0xff, 0xcd, + 0x9f, 0xed, 0xdf, 0x6c, 0x5f, 0x6c, 0xfe, 0x3b, 0x7c, 0x8f, 0x97, 0xbc, + 0xfa, 0x3b, 0xba, 0x8f, 0xb3, 0x92, 0x80, 0xee, 0x5f, 0x54, 0xfc, 0x15, + 0x09, 0xfc, 0xb3, 0x9a, 0xf9, 0xf7, 0xfd, 0x15, 0x09, 0xfc, 0x84, 0xee, + 0xbf, 0x54, 0xef, 0xfb, 0xbf, 0xc5, 0xf1, 0xf7, 0xff, 0x1f, 0xb9, 0xf7, + 0xbf, 0x9a, 0xfa, 0xf7, 0xfe, 0xcf, 0x00, 0x1c, 0x44, 0x05, 0xf9, 0xfb, + 0xeb, 0x9b, 0xfb, 0xf7, 0xff, 0xcf, 0x00, 0x1c, 0x4a, 0x05, 0x8f, 0xee, + 0xfb, 0xcd, 0xa9, 0x54, 0xbc, 0x1b, 0xd8, 0xff, 0xb3, 0x4c, 0xfc, 0x1b, + 0xd4, 0xff, 0xff, 0x1f, 0x92, 0xfa, 0x95, 0xfb, 0x96, 0xee, 0xff, 0x6c, + 0xdf, 0x6c, 0xbf, 0x6c, 0xf7, 0xb7, 0xff, 0xd7, 0xff, 0x8b, 0xfe, 0x3b, + 0xbe, 0x8f, 0xa7, 0xb5, 0x00, 0x1c, 0xc1, 0x05, 0xfd, 0xcf, 0xff, 0xce, + 0xff, 0xcd, 0x00, 0x1c, 0xc0, 0x03, 0xa7, 0xfb, 0x9f, 0xee, 0x9f, 0x6c, + 0xfc, 0x3b, 0x7c, 0x8f, 0xbf, 0xc4, 0xf2, 0xf3, 0xa3, 0xef, 0x9f, 0x7d, + 0xdc, 0xb4, 0xde, 0x1b, 0xf9, 0xdf, 0x5f, 0xc6, 0xdc, 0xbe, 0x9c, 0x1b, + 0xc7, 0xcf, 0x3b, 0x93, 0x9f, 0x5d, 0xb9, 0xfb, 0xa9, 0xef, 0x9f, 0x7d, + 0xdc, 0x1b, 0xef, 0xdf, 0x9c, 0x1b, 0xc7, 0xcf, 0x3b, 0x93, 0x9f, 0x5d, + 0xc2, 0xfb, 0xfe, 0xcf, 0xff, 0xce, 0xff, 0xcd, 0x00, 0x1c, 0xe1, 0x03, + 0xc8, 0xfb, 0xf4, 0xcf, 0xff, 0xce, 0xff, 0xcd, 0x00, 0x1c, 0xe7, 0x03, + 0xce, 0xfb, 0xf9, 0xcf, 0xff, 0x1f, 0x95, 0xfb, 0xd2, 0xfb, 0xb4, 0xef, + 0xde, 0x6d, 0x94, 0xef, 0xcf, 0xb6, 0xd9, 0x5c, 0xde, 0x6d, 0xd7, 0xb6, + 0xda, 0x5c, 0xde, 0x6d, 0xdb, 0x5c, 0xbf, 0x6d, 0xa7, 0xb5, 0xbc, 0x5c, + 0x9b, 0xef, 0xbf, 0x6c, 0xaf, 0xb5, 0x9b, 0xef, 0xbd, 0x5c, 0xf4, 0xfb, + 0x53, 0xff, 0xff, 0xdf, 0xff, 0x6f, 0xff, 0xbf, 0x5f, 0xff, 0xff, 0xdf, + 0xf7, 0xb5, 0xff, 0xff, 0x37, 0xff, 0xff, 0xdf, 0x8f, 0xef, 0xbf, 0x6c, + 0xb7, 0xb5, 0x8f, 0xef, 0xbe, 0x5c, 0xf0, 0xef, 0xfa, 0xcc, 0x89, 0x57, + 0xf3, 0x4f, 0x9b, 0x1b, 0x8c, 0xef, 0x9f, 0x5f, 0xd4, 0xdf, 0xff, 0x1f, + 0xfc, 0xfa, 0x95, 0xef, 0x6e, 0x5c, 0xb7, 0xef, 0xbc, 0x6d, 0xbc, 0x23, + 0xda, 0xff, 0x6d, 0xeb, 0xde, 0xeb, 0x98, 0xef, 0x9f, 0x6c, 0xf2, 0x8b, + 0x8f, 0xb4, 0x8f, 0xbc, 0xf3, 0x93, 0xfe, 0xeb, 0xc3, 0x87, 0xff, 0xff, + 0xff, 0x6f, 0xff, 0xbf, 0x5f, 0xff, 0xff, 0xdf, 0x37, 0xff, 0xff, 0xdf, + 0x2c, 0xeb, 0x84, 0xed, 0xe4, 0xed, 0xff, 0x4c, 0xff, 0x1f, 0x9b, 0xf6, + 0xbf, 0xc7, 0x93, 0xf6, 0x86, 0xed, 0x9e, 0x6c, 0x3f, 0xc4, 0x1b, 0xf3, + 0xff, 0x1f, 0x6f, 0xf9, 0xa8, 0xed, 0xdf, 0x6d, 0xdd, 0xbe, 0xc9, 0xb6, + 0x9d, 0xae, 0xd2, 0xa6, 0xfd, 0xb7, 0x9f, 0xa6, 0x9c, 0x1b, 0x00, 0xdc, + 0xfb, 0xbc, 0xde, 0x75, 0x6d, 0xed, 0xaf, 0x97, 0xbf, 0x93, 0xde, 0x55, + 0xb0, 0x93, 0x7f, 0xcd, 0xbe, 0xbd, 0x37, 0x9b, 0xa1, 0xf7, 0xf2, 0xed, + 0xba, 0x77, 0xdb, 0xb5, 0xde, 0x1b, 0xe0, 0xdf, 0x7d, 0xa6, 0x7b, 0x1b, + 0xe0, 0xdf, 0x7b, 0xbb, 0xbd, 0x1b, 0x0f, 0xce, 0x6f, 0x93, 0xba, 0x57, + 0xd6, 0xc6, 0xd9, 0xf3, 0x7c, 0x93, 0xdd, 0x6f, 0xf3, 0xbe, 0xf3, 0xb7, + 0xff, 0xa4, 0xf3, 0xbf, 0xf3, 0xb7, 0xcb, 0xb6, 0xcb, 0xbe, 0xbf, 0x93, + 0xdd, 0x4d, 0xbe, 0x6d, 0xb3, 0xbd, 0xa9, 0xb5, 0x72, 0x9b, 0xf6, 0xf3, + 0xa2, 0xee, 0x95, 0xbc, 0xde, 0x6d, 0xe1, 0xee, 0xbf, 0x97, 0x3b, 0x93, + 0x9e, 0x4d, 0xcc, 0xfb, 0xa6, 0xee, 0xbd, 0x75, 0xa9, 0xbd, 0xa9, 0xb5, + 0x36, 0x9b, 0xd2, 0xf3, 0xa9, 0xee, 0xdd, 0x75, 0xde, 0x1b, 0x00, 0xcc, + 0x3b, 0x93, 0x9d, 0x55, 0xd9, 0xfb, 0x8c, 0xee, 0xdd, 0x6c, 0xd3, 0xbe, + 0xd3, 0xb6, 0xbd, 0x74, 0xa9, 0xbd, 0xa9, 0xb5, 0xb6, 0xa6, 0xb3, 0xbd, + 0xb3, 0xb5, 0xde, 0x6c, 0xd3, 0xbe, 0xc9, 0xb6, 0xda, 0xa5, 0xcc, 0xbe, + 0xc9, 0xb6, 0xdb, 0xbe, 0xbc, 0x74, 0x74, 0xee, 0x6f, 0x97, 0x7b, 0x93, + 0xbc, 0x54, 0xba, 0x74, 0xbd, 0x1b, 0x0f, 0xce, 0xba, 0x54, 0xbd, 0x6c, + 0xab, 0xb5, 0xab, 0xbd, 0xbd, 0x4c, 0xbe, 0x6c, 0xf9, 0xee, 0x7f, 0x93, + 0xbe, 0x4c, 0xbd, 0x1b, 0x00, 0xcc, 0xbd, 0x54, 0x9f, 0xee, 0xdc, 0x74, + 0xcd, 0xbe, 0xc9, 0xb6, 0x9d, 0xee, 0x9d, 0x74, 0xbf, 0xc4, 0xe2, 0xf3, + 0x3b, 0x9b, 0xfb, 0xf7, 0xba, 0xa4, 0x76, 0x8b, 0xfc, 0xfb, 0xb2, 0xa6, + 0x76, 0x8b, 0xf3, 0xc5, 0xeb, 0xf7, 0xa3, 0xef, 0xbe, 0x75, 0xb5, 0x9b, + 0xf9, 0xf3, 0x85, 0xef, 0xde, 0x54, 0xfe, 0xcd, 0xbf, 0x5c, 0xf2, 0xfb, + 0x68, 0xef, 0xff, 0x7b, 0xff, 0xdf, 0xff, 0x8b, 0xff, 0x5b, 0xec, 0xcb, + 0xef, 0x9b, 0xfa, 0xf7, 0x71, 0x9b, 0xfc, 0xf3, 0x8d, 0xef, 0xdd, 0x54, + 0x8e, 0xef, 0x7d, 0x74, 0xae, 0xcc, 0xf3, 0x9a, 0xd6, 0xf3, 0x94, 0xef, + 0xff, 0xcd, 0xad, 0x5c, 0xac, 0x7c, 0xff, 0xdd, 0x77, 0x8b, 0xac, 0x5c, + 0xf5, 0xcc, 0x73, 0x9b, 0xdd, 0xf7, 0x99, 0xef, 0xf5, 0xcd, 0xac, 0x5c, + 0x8b, 0x7c, 0xee, 0xfb, 0xff, 0xbf, 0xff, 0xbf, 0x04, 0x00, 0xdd, 0xff, + 0xff, 0x5f, 0xff, 0xbf, 0x2b, 0xff, 0xff, 0xdf, 0xf0, 0x3f, 0x00, 0x00, + 0x00, 0xfc, 0x0f, 0x00, 0xff, 0x03, 0xf0, 0xff, 0x1f, 0xff, 0xff, 0xdf, + 0xbe, 0xc4, 0xf4, 0xf7, 0xff, 0xcd, 0x83, 0xed, 0xab, 0x5c, 0xe3, 0xed, + 0xff, 0x1f, 0xe1, 0xfb, 0xfb, 0xfb, 0xff, 0xcd, 0x87, 0xed, 0xac, 0x5c, + 0x99, 0xcc, 0xf3, 0x9a, 0xe7, 0xf7, 0x89, 0xed, 0xff, 0xcd, 0xac, 0x5c, + 0xad, 0x7c, 0xff, 0xdd, 0x77, 0x8b, 0xad, 0x5c, 0xf5, 0xcc, 0x73, 0x9b, + 0xee, 0xf7, 0x8e, 0xed, 0xf5, 0xcd, 0xad, 0x5c, 0x8b, 0x7c, 0xbf, 0xc4, + 0xf4, 0xf7, 0xfe, 0xcd, 0x92, 0xed, 0xab, 0x5c, 0xf2, 0xed, 0xff, 0x1f, + 0xfe, 0xfb, 0xfb, 0xfb, 0xff, 0xcd, 0x95, 0xed, 0xad, 0x5c, 0xff, 0xcf, + 0xff, 0x1f, 0x33, 0xfa, 0xfc, 0x92, 0x98, 0xed, 0x94, 0x74, 0xf1, 0x9b, + 0xf2, 0xf7, 0xba, 0xed, 0x87, 0x7d, 0xff, 0xdc, 0x33, 0x8b, 0x87, 0x5d, + 0x9b, 0xcd, 0x37, 0x9b, 0xf7, 0xf7, 0xfb, 0xcf, 0xff, 0x1f, 0xdb, 0xfc, + 0xfb, 0xfb, 0xff, 0xcd, 0x81, 0xee, 0xa7, 0x5c, 0x82, 0xee, 0x74, 0x54, + 0xbf, 0x6c, 0xa9, 0xbd, 0xa9, 0xb5, 0xdd, 0xad, 0xba, 0xa5, 0x7d, 0xb3, + 0x6f, 0xa5, 0x7b, 0x1b, 0x00, 0xdc, 0xbf, 0x74, 0xbd, 0x1b, 0x00, 0xcc, + 0x6f, 0x93, 0xbf, 0x54, 0xfc, 0x15, 0x8c, 0xfe, 0xf3, 0x9a, 0xf6, 0xf3, + 0x8a, 0xee, 0x9e, 0x6c, 0x3b, 0xc4, 0xec, 0xf3, 0xfb, 0xcf, 0xff, 0x1f, + 0x0e, 0xf7, 0xf0, 0xfb, 0xfc, 0x15, 0xd0, 0xfd, 0xf3, 0x9a, 0xf4, 0xf7, + 0xff, 0x1f, 0x4b, 0xfc, 0xbb, 0xc7, 0xf8, 0xf7, 0x92, 0xee, 0x9e, 0x6c, + 0x3b, 0xc4, 0xfc, 0xf7, 0xff, 0x1f, 0x2f, 0xf7, 0x97, 0xee, 0xbf, 0x6c, + 0xa9, 0xbd, 0xa9, 0xb5, 0x0d, 0xcc, 0x9e, 0xbc, 0x73, 0x9b, 0xfa, 0xf7, + 0xfe, 0xcf, 0xff, 0x1f, 0xee, 0xf9, 0xf7, 0xfb, 0x20, 0xcc, 0x9e, 0xbc, + 0x73, 0x9b, 0xfb, 0xf3, 0xfc, 0xcf, 0xff, 0x1f, 0xf6, 0xf9, 0x60, 0xef, + 0x9f, 0x6b, 0x53, 0xbc, 0x49, 0xb2, 0xbd, 0xaa, 0x56, 0xa2, 0x5a, 0x1b, + 0x00, 0xdc, 0xb5, 0xba, 0x22, 0xef, 0x27, 0x97, 0x37, 0x93, 0x9f, 0x4b, + 0xfe, 0xcf, 0xff, 0x1f, 0x94, 0xfa, 0xfd, 0xb7, 0x5f, 0xa2, 0x5a, 0x1b, + 0x00, 0xdc, 0x95, 0xba, 0xbf, 0x6b, 0x77, 0x96, 0x73, 0x92, 0x3f, 0x4b, + 0xfc, 0x15, 0xde, 0xfd, 0xb3, 0x9a, 0xf7, 0xf3, 0x8b, 0xef, 0xbf, 0x6c, + 0xcb, 0xef, 0x7b, 0x97, 0x55, 0xc5, 0xbf, 0x4c, 0xf8, 0xfb, 0x8e, 0xef, + 0xbf, 0x6c, 0x6e, 0xef, 0x6f, 0x97, 0x53, 0xc5, 0xbf, 0x4c, 0xff, 0xcd, + 0x96, 0xef, 0xa6, 0x5c, 0xff, 0x1f, 0xc1, 0xfa, 0xf3, 0xfb, 0xb8, 0xef, + 0x86, 0x7d, 0xff, 0xdc, 0x33, 0x8b, 0x86, 0x5d, 0x69, 0xcd, 0x37, 0x9b, + 0xfb, 0xf7, 0xfb, 0xcf, 0xff, 0x1f, 0x57, 0xfd, 0x6c, 0xeb, 0xff, 0xff, + 0x2b, 0xff, 0xff, 0xdf, 0xb3, 0xb5, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xbf, + 0x00, 0xfc, 0x0f, 0x00, 0xff, 0x5f, 0xff, 0xbf, 0x00, 0x1c, 0x00, 0x00, + 0x2e, 0xeb, 0x7e, 0xec, 0xff, 0xcc, 0x8c, 0x5b, 0x8d, 0x5b, 0x8b, 0x5b, + 0x87, 0x5b, 0x86, 0x5b, 0x9b, 0x1b, 0xf4, 0xff, 0xff, 0xcd, 0xbd, 0x54, + 0xbe, 0x54, 0xbf, 0x5c, 0x9a, 0x73, 0x9c, 0x1b, 0x0f, 0xce, 0x9a, 0x53, + 0x9d, 0x6b, 0x8b, 0xb4, 0x8b, 0xbc, 0x9d, 0x4b, 0x9d, 0x73, 0x9c, 0x1b, + 0x00, 0xcc, 0x9d, 0x53, 0x9e, 0x6b, 0xca, 0xed, 0x3b, 0x93, 0x9e, 0x4b, + 0xff, 0x1f, 0x0d, 0xfb, 0x9f, 0x1b, 0x00, 0xdc, 0x9b, 0xbc, 0xbe, 0x73, + 0xce, 0xed, 0x7b, 0x97, 0x37, 0x93, 0x9e, 0x53, 0xff, 0xcf, 0xff, 0x1f, + 0xf8, 0xfa, 0xbf, 0x1b, 0x00, 0xdc, 0x9f, 0x73, 0x9c, 0x1b, 0x00, 0xcc, + 0x37, 0x93, 0x9f, 0x53, 0xfe, 0xcf, 0xff, 0x1f, 0x02, 0xfb, 0x9f, 0x1b, + 0x00, 0xdc, 0x95, 0xbc, 0xbf, 0x6b, 0xd7, 0xed, 0x7b, 0x97, 0x37, 0x93, + 0x9f, 0x4b, 0xff, 0x1f, 0x1a, 0xfb, 0xfb, 0x1b, 0xe6, 0xff, 0xff, 0xce, + 0xbb, 0xed, 0xff, 0x1f, 0x86, 0xfc, 0xbf, 0xc7, 0xf8, 0xf7, 0xe5, 0x7b, + 0xfc, 0xce, 0xff, 0xcd, 0xff, 0x1f, 0x25, 0xfc, 0x6e, 0xeb, 0xff, 0xfb, + 0xff, 0x8b, 0xbf, 0xc7, 0xf3, 0xf7, 0x86, 0xee, 0x9f, 0x74, 0x9c, 0x1b, + 0x00, 0xdc, 0xbf, 0xc4, 0xe7, 0xf3, 0x89, 0xee, 0xff, 0x6c, 0xe9, 0xbf, + 0xe9, 0xb7, 0xe6, 0xfb, 0xbe, 0xc7, 0xf3, 0xf7, 0x8d, 0xee, 0x9f, 0x6c, + 0xad, 0xee, 0x37, 0x97, 0xbf, 0xc4, 0xf2, 0xf3, 0x90, 0xee, 0xff, 0x6c, + 0xf3, 0xbf, 0xe9, 0xb7, 0xf3, 0xfb, 0xbc, 0xc7, 0xf7, 0xf7, 0x8e, 0xee, + 0xfd, 0x74, 0xf8, 0xfb, 0xfe, 0xcf, 0xfa, 0xfb, 0xfe, 0xcf, 0xfc, 0xfb, + 0xff, 0x15, 0x00, 0xfc, 0xc3, 0x87, 0xff, 0xff, 0x3e, 0xeb, 0x99, 0xee, 0xd7, 0x74, 0x9f, 0x6c, 0xa9, 0xbc, 0xa9, 0xb5, 0x7b, 0x83, 0x7a, 0xbd, - 0xf7, 0xbd, 0xff, 0xa3, 0x93, 0xbc, 0xb6, 0xa7, 0x89, 0xb4, 0x3b, 0x83, - 0xfb, 0xbd, 0xb6, 0xa7, 0xdc, 0xbc, 0xf9, 0xbc, 0xda, 0xa7, 0xd2, 0xa6, - 0xdb, 0xbe, 0xd3, 0xa6, 0xdd, 0xbe, 0x92, 0xa6, 0xaf, 0xad, 0x8f, 0xac, - 0x37, 0x9b, 0xfc, 0xf3, 0xf2, 0xa5, 0x7e, 0xeb, 0xff, 0xcf, 0x7e, 0xeb, - 0x37, 0xff, 0xff, 0xdf, 0x3e, 0xeb, 0x85, 0xef, 0x9d, 0x6c, 0x2c, 0xc4, - 0xdb, 0xf7, 0x86, 0xef, 0xbf, 0x6c, 0xa9, 0xbd, 0xa9, 0xb5, 0xff, 0xce, - 0x8a, 0xef, 0x0f, 0xcb, 0xfd, 0x6c, 0x6f, 0xbb, 0xef, 0x97, 0xbf, 0xc7, - 0xf1, 0xf3, 0x9d, 0x6c, 0x8b, 0xb4, 0x9c, 0x1b, 0xf0, 0xdf, 0xfc, 0xbc, - 0x9f, 0x3b, 0xdc, 0xf7, 0xfd, 0xbc, 0x9a, 0xbc, 0x9e, 0xa4, 0x37, 0x83, - 0x95, 0xac, 0xd3, 0xa6, 0x92, 0xef, 0x9d, 0x74, 0xf9, 0xbc, 0x9f, 0x3b, - 0xbf, 0xf7, 0xf2, 0xa7, 0xf7, 0x83, 0xf5, 0xaf, 0xff, 0xa6, 0x7e, 0xeb, - 0x98, 0xef, 0xbf, 0x6c, 0xa9, 0xbd, 0xa9, 0xb5, 0xbd, 0x3b, 0xdc, 0x7b, - 0xdb, 0xbc, 0x9e, 0x3b, 0xbe, 0xf7, 0xd2, 0xa6, 0xd1, 0xae, 0x28, 0xf8, - 0xff, 0x5f, 0xff, 0xbf, 0x37, 0xff, 0xff, 0xdf, 0x2b, 0xff, 0xff, 0xdf, - 0x2d, 0xeb, 0x6c, 0xee, 0xbf, 0x8a, 0x9f, 0x73, 0x5c, 0x3b, 0x7d, 0xbf, - 0xfe, 0xce, 0x3f, 0xc5, 0xed, 0xf7, 0xbf, 0xc2, 0xee, 0xf3, 0xbe, 0xc2, - 0xdc, 0xf3, 0xbd, 0x7b, 0xbd, 0x1b, 0xf0, 0xcf, 0x5e, 0x3b, 0xda, 0xbf, - 0x5e, 0xc5, 0x2b, 0x93, 0xd7, 0x5b, 0xbd, 0x5b, 0x9f, 0x53, 0xf6, 0xee, - 0xff, 0x1f, 0x5b, 0xfd, 0x6d, 0xeb, 0xfb, 0xcf, 0xff, 0xce, 0xff, 0x1f, - 0x70, 0xf8, 0x9d, 0x7b, 0x9c, 0x1b, 0xf0, 0xcf, 0x9c, 0x13, 0xfc, 0xff, - 0x9d, 0x5b, 0xbe, 0x73, 0x9d, 0x73, 0xad, 0xbd, 0xa9, 0xb5, 0x9c, 0x1b, - 0x00, 0xcc, 0x37, 0x93, 0x9d, 0x53, 0x57, 0x5b, 0x16, 0xf8, 0xfe, 0xce, - 0xfb, 0xcf, 0x57, 0x5b, 0xff, 0x1f, 0x85, 0xf8, 0x9d, 0x7b, 0x9c, 0x1b, - 0xf0, 0xcf, 0x5f, 0xc4, 0x9d, 0x5b, 0x00, 0x1c, 0x8e, 0x08, 0xbf, 0x1b, - 0x00, 0xdc, 0x9e, 0x73, 0xc9, 0xef, 0xbb, 0xbd, 0x3b, 0x97, 0x37, 0x93, - 0x9e, 0x53, 0x00, 0x1c, 0x98, 0x08, 0xfc, 0x15, 0x40, 0xfe, 0xf3, 0x9b, - 0xf4, 0xf7, 0x9d, 0x73, 0x9c, 0x1b, 0x00, 0xcc, 0x9c, 0x13, 0x40, 0xfe, - 0x9d, 0x53, 0x9f, 0x73, 0x5e, 0xc4, 0x9f, 0x53, 0x3a, 0xf8, 0xbe, 0x73, - 0x9d, 0x73, 0xad, 0xbd, 0xa9, 0xb5, 0x9c, 0x1b, 0x00, 0xcc, 0x37, 0x93, - 0x9d, 0x53, 0x00, 0x1c, 0x66, 0x0d, 0xbf, 0xc7, 0x0e, 0xf0, 0x9d, 0x73, - 0x9c, 0x1b, 0x00, 0xcc, 0x9c, 0x13, 0x8b, 0xfe, 0x9d, 0x53, 0x15, 0xf8, - 0x1b, 0xff, 0xff, 0xdf, 0xcb, 0xb4, 0xff, 0xff, 0xf0, 0x3f, 0x00, 0x00, - 0x2c, 0xeb, 0x7c, 0x92, 0xff, 0xcf, 0x00, 0x1c, 0xf4, 0x00, 0xfc, 0x15, - 0xb9, 0xfc, 0xf3, 0x9b, 0xbc, 0x92, 0x75, 0xf3, 0x00, 0x1c, 0xd1, 0x00, - 0xfc, 0x15, 0x3b, 0xf6, 0xf3, 0x9b, 0x8d, 0xf3, 0xfc, 0x15, 0x23, 0xfa, - 0xf3, 0x9b, 0xcb, 0xf3, 0x6d, 0xed, 0xff, 0xcc, 0x98, 0x53, 0x9a, 0x53, - 0x9f, 0x71, 0x3e, 0xc4, 0xf8, 0xf3, 0x9d, 0x73, 0x89, 0xbc, 0x89, 0xb4, - 0xdb, 0xdc, 0x2b, 0x9b, 0x7a, 0xf3, 0x92, 0xed, 0xbe, 0x6c, 0x3f, 0xc5, - 0xa5, 0xf3, 0x9d, 0x6c, 0x2c, 0xc4, 0xa8, 0xf3, 0x97, 0x73, 0xff, 0xdc, - 0x32, 0x8b, 0xfd, 0x15, 0x6a, 0xfa, 0x37, 0x9b, 0x97, 0x53, 0x8f, 0xf3, - 0xfe, 0xcf, 0x00, 0x1c, 0x22, 0x01, 0x9f, 0x73, 0xbc, 0x92, 0x35, 0xc4, - 0xd9, 0xf3, 0xfd, 0x15, 0x66, 0xfe, 0xf7, 0x9b, 0xdd, 0xf3, 0xfb, 0xcf, - 0x00, 0x1c, 0xa7, 0x00, 0xf7, 0xcc, 0x93, 0x5b, 0x82, 0xee, 0x9e, 0x6c, - 0x3f, 0xc4, 0xdd, 0xf7, 0xff, 0xcc, 0x8d, 0x5b, 0x6c, 0xeb, 0x66, 0xee, - 0xff, 0xcc, 0xb8, 0x73, 0x9a, 0x53, 0xff, 0xdd, 0x70, 0xcc, 0x76, 0x8b, - 0x9e, 0xbc, 0x73, 0x9b, 0xb8, 0x53, 0x38, 0xf4, 0xff, 0x15, 0x09, 0xfc, - 0xff, 0x1f, 0xd7, 0xfb, 0xfb, 0xcf, 0x00, 0x1c, 0xc2, 0x00, 0xf8, 0xcc, - 0x93, 0x5b, 0x42, 0xf8, 0x34, 0xc4, 0x1c, 0xf0, 0x61, 0xcc, 0xb3, 0x9a, - 0x24, 0xf4, 0x92, 0xee, 0x9e, 0x6c, 0x3f, 0xc4, 0x1f, 0xf0, 0xfc, 0xcf, - 0x00, 0x1c, 0x57, 0x01, 0xfc, 0x15, 0x51, 0xfc, 0xf3, 0x9b, 0xcf, 0xf7, - 0x8d, 0x7b, 0xff, 0xdc, 0x33, 0x8b, 0xb9, 0xcd, 0x37, 0x9b, 0x8d, 0x5b, - 0x2b, 0xf4, 0x77, 0xcc, 0xb3, 0x9a, 0xfa, 0xf3, 0x9d, 0xee, 0xbe, 0x6c, - 0x7f, 0xc5, 0xbe, 0x4c, 0xfd, 0xcf, 0x00, 0x1c, 0xe6, 0x00, 0x6c, 0xeb, - 0xff, 0xcc, 0x97, 0x53, 0x4f, 0xf8, 0x63, 0xef, 0xff, 0x15, 0x09, 0xfc, - 0xff, 0x1f, 0x07, 0xfc, 0x9a, 0x73, 0xff, 0xdc, 0x32, 0x8b, 0xf1, 0xcd, - 0x37, 0x9b, 0x9a, 0x53, 0x73, 0xf4, 0xfb, 0xcf, 0x00, 0x1c, 0xf9, 0x00, - 0xf9, 0xcc, 0x93, 0x5b, 0x79, 0xf8, 0x8b, 0xef, 0xbd, 0x6c, 0x4c, 0xc5, - 0xbd, 0x4c, 0xfe, 0xcf, 0x00, 0x1c, 0x03, 0x01, 0x8f, 0xf8, 0x77, 0xcc, - 0xb3, 0x9a, 0x58, 0xf0, 0x31, 0xf8, 0x92, 0xef, 0xb7, 0x54, 0xf8, 0xcf, - 0x00, 0x1c, 0x0d, 0x01, 0x73, 0xf8, 0xff, 0xcd, 0x96, 0xef, 0xb7, 0x54, - 0xff, 0x1f, 0x01, 0xfc, 0x97, 0xef, 0xbd, 0x6c, 0x6c, 0xc5, 0xbd, 0x4c, - 0xbd, 0x6c, 0x56, 0xc5, 0xbd, 0x4c, 0xff, 0xcf, 0x00, 0x1c, 0x1d, 0x01, - 0x9f, 0x71, 0x7e, 0xc4, 0x9f, 0x51, 0x95, 0xf8, 0x1b, 0xff, 0xff, 0xdf, - 0xff, 0x5f, 0xff, 0xbf, 0x2e, 0xeb, 0x82, 0xef, 0xb9, 0x6c, 0x3a, 0xc5, - 0xfb, 0xf7, 0xb9, 0x6c, 0x34, 0xc5, 0xe2, 0xf3, 0x86, 0xef, 0xbd, 0x6c, - 0x4c, 0xc5, 0xbd, 0x4c, 0xfe, 0xcf, 0x00, 0x1c, 0x34, 0x01, 0xff, 0xcf, - 0xff, 0x1f, 0x03, 0xf9, 0xbf, 0xc7, 0xf1, 0xf3, 0x6b, 0xef, 0x8c, 0x7b, - 0xff, 0xdc, 0x33, 0x8b, 0xf4, 0xcd, 0x37, 0x9b, 0x8c, 0x5b, 0xfa, 0xf7, - 0x8e, 0xef, 0x9f, 0x7c, 0xbf, 0xc4, 0xf0, 0xf3, 0x6e, 0xeb, 0x91, 0xef, - 0xec, 0x5c, 0x6e, 0xeb, 0xb9, 0x6c, 0x3c, 0xc5, 0x1d, 0xf4, 0xb9, 0x6c, - 0x3d, 0xc5, 0x20, 0xf4, 0x99, 0x6c, 0x35, 0xc4, 0x1c, 0xf0, 0x24, 0xf8, - 0xfb, 0xcf, 0x8c, 0x5b, 0x00, 0x1c, 0x57, 0x01, 0xfa, 0xcc, 0xfb, 0xcf, - 0xfe, 0xce, 0x93, 0x5b, 0xff, 0x1f, 0xb1, 0xf9, 0x6e, 0xeb, 0xff, 0xff, - 0xff, 0x5f, 0xff, 0xbf, 0x1b, 0xff, 0xff, 0xdf, 0x6f, 0xfe, 0xff, 0xdf, - 0x2e, 0xeb, 0x6d, 0xef, 0xbd, 0x7b, 0xbd, 0x1b, 0xf0, 0xcf, 0xbd, 0x5b, - 0xbe, 0x73, 0xcf, 0xef, 0x7b, 0x97, 0xbe, 0x53, 0xbd, 0x73, 0xbd, 0x1b, - 0x00, 0xcc, 0xff, 0xcc, 0xbd, 0x53, 0xfb, 0x1b, 0xec, 0xff, 0xff, 0xce, - 0xb4, 0xef, 0x97, 0x53, 0x9a, 0x53, 0x98, 0x53, 0x97, 0x5b, 0x9f, 0x53, - 0xff, 0x1f, 0x67, 0xfe, 0xbf, 0xc7, 0xfd, 0xf3, 0x6e, 0xeb, 0xeb, 0x7b, - 0xf8, 0xce, 0x6c, 0x93, 0xff, 0x1f, 0x13, 0xfe, 0x6e, 0xeb, 0xff, 0xff, - 0x1b, 0xff, 0xff, 0xdf, 0xf0, 0x3f, 0x00, 0x00, 0x0f, 0xd1, 0xff, 0xff, - 0x2f, 0xeb, 0x8e, 0xef, 0xb9, 0x6c, 0x3b, 0xc5, 0xfb, 0xf7, 0xb9, 0x6c, - 0x3f, 0xc5, 0xfa, 0xf3, 0xfd, 0xcf, 0x00, 0x1c, 0x9a, 0x01, 0x6f, 0xeb, - 0xbd, 0x6c, 0x4c, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0xd5, 0xef, 0x7b, 0x97, - 0x4b, 0xc5, 0x49, 0xc5, 0xbd, 0x4c, 0x96, 0xef, 0xbf, 0x74, 0x5e, 0xc5, - 0xbf, 0x54, 0xfb, 0xcf, 0xfe, 0xce, 0xff, 0x1f, 0x00, 0xfa, 0xf9, 0xcf, - 0x00, 0x1c, 0xaf, 0x01, 0x6f, 0xeb, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xbf, - 0x00, 0x00, 0xf0, 0x00, 0x1b, 0xff, 0xff, 0xdf, 0x9a, 0xef, 0xfe, 0xcd, - 0xff, 0x8b, 0xfd, 0x3b, 0xdf, 0xbf, 0xbf, 0x74, 0xf7, 0x93, 0xff, 0x54, - 0xc3, 0x87, 0xff, 0xff, 0x1b, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0xff, 0xcf, - 0xff, 0x1f, 0x93, 0xf9, 0xbe, 0xc7, 0xfd, 0xf3, 0x6f, 0xeb, 0x94, 0xef, - 0xff, 0x5c, 0xfb, 0xcf, 0xff, 0x1f, 0xe1, 0xf9, 0x96, 0xef, 0xbd, 0x6c, - 0x4c, 0xc5, 0xbd, 0x4c, 0xfb, 0xcf, 0x00, 0x1c, 0xd6, 0x01, 0xf5, 0xcd, - 0x99, 0xef, 0xb3, 0x5c, 0xfb, 0xcf, 0xfe, 0xce, 0xff, 0x1f, 0x31, 0xfa, - 0x6f, 0xeb, 0xff, 0xff, 0x6f, 0xfe, 0xff, 0xdf, 0xff, 0x5f, 0xff, 0xbf, - 0x1b, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0xff, 0x8b, 0x00, 0x1c, 0xe9, 0x01, - 0x6f, 0xeb, 0xff, 0xff, 0x9c, 0xef, 0x97, 0x7c, 0xbf, 0xc4, 0xff, 0x3b, - 0xff, 0xfa, 0xc3, 0x87, 0x1b, 0xff, 0xff, 0xdf, 0x95, 0xef, 0x9f, 0x74, - 0x3e, 0xc4, 0xf4, 0xf7, 0x3d, 0xc4, 0xf8, 0xf7, 0x3a, 0xc4, 0xf4, 0xf7, - 0x3b, 0xc4, 0xf8, 0xf3, 0xf4, 0xcf, 0xc3, 0x87, 0xfa, 0xcf, 0xc3, 0x87, - 0xfb, 0xcf, 0xc3, 0x87, 0xff, 0xcf, 0xc3, 0x87, 0xf5, 0xcf, 0xc3, 0x87, - 0x1b, 0xff, 0xff, 0xdf, 0x2f, 0xeb, 0x8e, 0xef, 0xbf, 0x7c, 0xdd, 0x1b, - 0xf0, 0xcf, 0x5f, 0xc6, 0xf0, 0xcd, 0xb7, 0x97, 0xdf, 0x5c, 0xde, 0x7c, - 0xde, 0x1b, 0xf0, 0xcf, 0x7b, 0x97, 0xdc, 0x1b, 0xf4, 0xff, 0xbe, 0x5c, - 0xdd, 0x4c, 0xff, 0xcd, 0xf8, 0xce, 0xbb, 0x5c, 0xbe, 0x54, 0xd9, 0x5c, - 0xba, 0x5c, 0x00, 0x1c, 0x46, 0x13, 0x00, 0x1c, 0x6e, 0x13, 0x00, 0x1c, - 0xb6, 0x14, 0x00, 0x1c, 0x56, 0x14, 0x00, 0x1c, 0x5c, 0x0f, 0x6f, 0xeb, - 0x03, 0xff, 0xff, 0xdf, 0x98, 0xef, 0xdf, 0x7c, 0xf0, 0xcd, 0xb7, 0x97, - 0xde, 0x13, 0xaf, 0xff, 0xdf, 0x5c, 0xde, 0x7c, 0xde, 0x1b, 0xf0, 0xcf, - 0x7b, 0x97, 0xbe, 0x5c, 0xc3, 0x87, 0xff, 0xff, 0x03, 0xff, 0xff, 0xdf, - 0x2c, 0xeb, 0xde, 0xeb, 0xff, 0xcd, 0x79, 0xee, 0xdb, 0x7b, 0xbf, 0x47, - 0xba, 0x7b, 0xbb, 0x8b, 0x77, 0x8b, 0x79, 0x9b, 0xc8, 0xf3, 0x7f, 0x3f, - 0xdf, 0x8f, 0xbb, 0x7b, 0x77, 0x8b, 0xdd, 0x6b, 0xbe, 0x3b, 0xbe, 0xf7, - 0xff, 0xdd, 0x77, 0x8b, 0x5f, 0x6e, 0xbb, 0x5b, 0x9b, 0x7b, 0xb9, 0x7b, - 0x37, 0x97, 0x9b, 0x5b, 0x5f, 0x47, 0x7f, 0x3f, 0xdf, 0x8b, 0xff, 0xcc, - 0xbf, 0x72, 0xfe, 0xd4, 0x34, 0x8f, 0xbe, 0x73, 0x37, 0x97, 0x9e, 0x53, - 0x9e, 0x7b, 0xa9, 0xef, 0x9c, 0x1b, 0xf0, 0xdf, 0x9d, 0x3b, 0xbc, 0xf7, - 0x9f, 0x6c, 0xe8, 0x93, 0x32, 0x84, 0x9e, 0x7b, 0xbc, 0x1b, 0xf0, 0xdf, - 0xdf, 0x7b, 0xfb, 0xbd, 0xde, 0x1b, 0xf0, 0xdf, 0xbf, 0x93, 0xf8, 0x93, - 0xdf, 0x5b, 0xdb, 0xb4, 0xde, 0x1b, 0xf0, 0xdf, 0xb5, 0x9b, 0x35, 0xef, - 0xfc, 0xf3, 0xbf, 0xc2, 0xfa, 0xf3, 0xfe, 0xeb, 0x6c, 0xeb, 0xff, 0xca, - 0x1d, 0xf8, 0x9c, 0x1b, 0xf0, 0xcf, 0xff, 0x1b, 0xf0, 0xcf, 0xb3, 0x93, - 0x5f, 0xc7, 0xde, 0x59, 0xff, 0x59, 0xfe, 0xeb, 0x6c, 0xeb, 0xff, 0xff, - 0x03, 0xff, 0xff, 0xdf, 0xc3, 0xb4, 0xff, 0xff, 0x98, 0xef, 0xbf, 0x7c, - 0xff, 0x8b, 0xbd, 0x1b, 0xf0, 0xcf, 0xbf, 0x5c, 0xbb, 0xbf, 0xfe, 0x7c, - 0xff, 0x1b, 0xf0, 0xdf, 0xf7, 0x93, 0xfe, 0x5c, 0xc3, 0x87, 0xff, 0xff, - 0x03, 0xff, 0xff, 0xdf, 0x9d, 0xef, 0xff, 0x7c, 0xfb, 0xb7, 0xc3, 0x87, - 0x03, 0xff, 0xff, 0xdf, 0x9c, 0xef, 0xfe, 0x7c, 0xff, 0x1b, 0xf0, 0xdf, - 0xc3, 0x87, 0xff, 0xff, 0x03, 0xff, 0xff, 0xdf, 0x9a, 0xef, 0xbf, 0x7c, - 0x9e, 0x7c, 0xbb, 0xb5, 0x9c, 0x1b, 0xf0, 0xdf, 0x35, 0x9b, 0xff, 0x3b, - 0xff, 0xfa, 0xc3, 0x87, 0x03, 0xff, 0xff, 0xdf, 0x3e, 0xeb, 0x8e, 0xef, - 0xbf, 0x7c, 0xbd, 0x1b, 0xf0, 0xdf, 0xbf, 0xc5, 0xe4, 0xf3, 0xde, 0x74, - 0xbf, 0x77, 0xbe, 0x3b, 0x7d, 0xbf, 0x3f, 0xc5, 0xea, 0xf7, 0xba, 0x7c, - 0x77, 0x8b, 0xd9, 0x7c, 0xff, 0xdd, 0x7b, 0x97, 0xdb, 0x7c, 0xbb, 0x8b, - 0xb5, 0x9b, 0xf3, 0xf3, 0x7f, 0x3f, 0xdf, 0x8f, 0x7a, 0x7c, 0xdd, 0x6c, - 0xef, 0x8a, 0x7e, 0x3b, 0xbe, 0xf7, 0xff, 0x4e, 0xba, 0x5c, 0x7f, 0x3f, - 0xdf, 0x8b, 0x7e, 0xeb, 0x03, 0xff, 0xff, 0xdf, 0x9c, 0xef, 0xbf, 0x6c, - 0xff, 0xdd, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0xd7, 0xfe, 0xff, 0xdf, - 0xf0, 0xcd, 0x88, 0xef, 0xbb, 0x5c, 0xf8, 0xdc, 0xff, 0x7c, 0x7f, 0xc7, - 0xd3, 0x7c, 0xf7, 0x97, 0x5b, 0xc7, 0x7f, 0xc6, 0xb7, 0x97, 0xff, 0x5c, - 0xe7, 0x7c, 0x5a, 0xc6, 0x7f, 0xc7, 0xf7, 0x97, 0xd3, 0x5c, 0xdc, 0x27, - 0xdb, 0xff, 0xff, 0x13, 0xcf, 0xff, 0x7f, 0xc6, 0xb7, 0x97, 0xe7, 0x5c, - 0xfc, 0x27, 0xcf, 0xff, 0x7f, 0xc7, 0x59, 0xc6, 0x7f, 0x97, 0xdc, 0x23, - 0xdb, 0xff, 0xff, 0xcf, 0xdc, 0x27, 0xc3, 0xff, 0xbd, 0x13, 0xaf, 0xff, - 0x7f, 0xc6, 0xf0, 0xd7, 0xbc, 0x23, 0xcf, 0xff, 0xfe, 0x3b, 0xdd, 0xdb, - 0xbc, 0x23, 0xc3, 0xff, 0xc3, 0x87, 0xff, 0xff, 0xd7, 0xfe, 0xff, 0xdf, - 0x3c, 0xeb, 0xbf, 0xc7, 0xfc, 0xf3, 0xfe, 0xc6, 0xfc, 0xf3, 0xfe, 0xcf, - 0x7c, 0xeb, 0xbf, 0xc5, 0x02, 0xf0, 0x8a, 0xef, 0x7b, 0x7c, 0x3b, 0x1b, - 0xf0, 0xcf, 0x67, 0x8a, 0x0f, 0xca, 0xa5, 0x9a, 0xdf, 0xf3, 0x7b, 0xb3, - 0x7b, 0x1b, 0xf0, 0xdf, 0xaf, 0x8a, 0x7f, 0x5f, 0x7d, 0xba, 0x5b, 0xba, - 0x4e, 0xa2, 0xe1, 0xa4, 0xeb, 0xa7, 0x5f, 0x7f, 0x7b, 0x7c, 0x5b, 0xb2, - 0x5b, 0xba, 0x7b, 0x1b, 0xf0, 0xdf, 0xeb, 0x92, 0x7b, 0x5c, 0x9f, 0x7f, - 0xff, 0xcb, 0xf1, 0xd3, 0x5f, 0xc4, 0xde, 0x1b, 0xfc, 0xdf, 0x2f, 0x97, - 0xde, 0xbe, 0xb3, 0x93, 0xdf, 0x5f, 0xbe, 0x4f, 0xff, 0xcf, 0x7c, 0xeb, - 0xfd, 0xcf, 0x7c, 0xeb, 0xd7, 0xfe, 0xff, 0xdf, 0x3d, 0xeb, 0x9f, 0x7f, - 0xb0, 0xc4, 0xe2, 0xf3, 0xdd, 0xbc, 0xae, 0xef, 0x9b, 0xbc, 0x61, 0xa5, - 0xda, 0xa4, 0xdb, 0xa3, 0x7f, 0x7e, 0x3c, 0xc3, 0xe9, 0xf7, 0xfb, 0x3b, - 0xda, 0xd7, 0x5f, 0x5e, 0x5b, 0x7d, 0x5b, 0xb2, 0x5b, 0xba, 0x7b, 0x1b, - 0xf1, 0xdf, 0xeb, 0x92, 0x7f, 0x5e, 0xdb, 0x7d, 0xde, 0x1b, 0xf0, 0xdf, - 0x3b, 0x93, 0x9b, 0x5d, 0xf0, 0xcc, 0x9f, 0x5f, 0xff, 0xcf, 0x7d, 0xeb, - 0xfe, 0xcf, 0x7d, 0xeb, 0x7c, 0xc3, 0x7f, 0x5e, 0xff, 0xcf, 0x7d, 0xeb, - 0xd7, 0xfe, 0xff, 0xdf, 0x3c, 0xeb, 0xff, 0x8b, 0x66, 0xef, 0x9d, 0xbf, - 0x3b, 0xbf, 0x41, 0xa3, 0x92, 0xa1, 0x93, 0xa2, 0x5f, 0x7c, 0x3f, 0xc2, - 0xfc, 0xf7, 0xfe, 0xcf, 0x7c, 0xeb, 0x3c, 0xc2, 0xdc, 0xf7, 0x5e, 0x74, - 0xde, 0x1b, 0x00, 0xd0, 0x3b, 0xbe, 0x5a, 0x1b, 0xf0, 0xdf, 0xa7, 0x92, - 0x5e, 0x54, 0x5f, 0x6c, 0x30, 0xef, 0xa7, 0x96, 0xd7, 0xbe, 0xab, 0x93, - 0xdf, 0x4c, 0x5c, 0xc6, 0xdf, 0x5c, 0xbd, 0x4c, 0xbb, 0x7b, 0xbd, 0x1b, - 0xf0, 0xdf, 0xbb, 0xbd, 0xde, 0x1b, 0xf0, 0xdf, 0xb7, 0x93, 0xdf, 0x5c, - 0x9b, 0x7b, 0x9c, 0x1b, 0xf0, 0xcf, 0xff, 0x1b, 0xf0, 0xdf, 0xf3, 0x93, - 0xfb, 0x5b, 0xff, 0xcf, 0x7c, 0xeb, 0xfc, 0xcf, 0x7c, 0xeb, 0xff, 0xff, - 0xd7, 0xfe, 0xff, 0xdf, 0x00, 0xff, 0x0f, 0x00, 0x2b, 0xeb, 0xde, 0xeb, - 0x9c, 0xed, 0xbf, 0x6c, 0x2b, 0x6c, 0x26, 0xa5, 0x66, 0x8a, 0xbf, 0xc1, - 0xab, 0x4c, 0xc7, 0xf3, 0x5b, 0x7c, 0x5a, 0x1b, 0xf0, 0xdf, 0xb0, 0xc2, - 0xcc, 0xf3, 0xf0, 0xcf, 0x3f, 0x47, 0xef, 0xfb, 0x1f, 0x7b, 0x3e, 0xb0, - 0x39, 0x1b, 0xfc, 0xdf, 0xbf, 0xc1, 0xc8, 0xf3, 0xbe, 0xc1, 0xbd, 0xf3, - 0x1b, 0xb0, 0x18, 0x1b, 0xf0, 0xdf, 0xb0, 0xc0, 0xdc, 0xf3, 0xe8, 0x93, - 0xa0, 0x92, 0xbd, 0xba, 0xdb, 0xba, 0x8b, 0xee, 0x76, 0xa6, 0x73, 0xa3, - 0x9f, 0x6b, 0x33, 0xbc, 0x2b, 0xb1, 0x1f, 0x67, 0x62, 0x9a, 0x18, 0xf0, - 0x1f, 0x7b, 0x3c, 0xc0, 0xea, 0xf7, 0xb0, 0xc7, 0xbb, 0xf3, 0x9d, 0xbf, - 0xfb, 0xbf, 0xf2, 0xa7, 0xb4, 0xee, 0xf7, 0xa7, 0x9f, 0x7f, 0x18, 0x1b, - 0x0f, 0xdf, 0x9c, 0x1b, 0xf0, 0xdf, 0x33, 0x92, 0x1f, 0x5f, 0x1f, 0x7b, - 0x1b, 0xb0, 0xb0, 0xc0, 0x20, 0xf4, 0xfe, 0xeb, 0x6b, 0xeb, 0x1f, 0x67, - 0x22, 0xa1, 0x39, 0x1b, 0x00, 0xd0, 0xfc, 0xee, 0x37, 0xb9, 0x3f, 0x97, - 0x3c, 0x3b, 0xd8, 0xdb, 0x1f, 0x4b, 0x32, 0xf8, 0xbe, 0x73, 0xe0, 0xef, - 0xbb, 0xb5, 0xb7, 0xbd, 0x3f, 0x97, 0x37, 0x93, 0x9f, 0x4b, 0xfd, 0x6b, - 0x9e, 0x6b, 0x32, 0x84, 0x1f, 0x7b, 0x1b, 0xb0, 0x3c, 0xf8, 0x7c, 0xc0, - 0xb0, 0xc7, 0x1f, 0x5b, 0xdf, 0xf3, 0x9d, 0xbf, 0xfb, 0xbf, 0xf2, 0xa7, - 0x8b, 0xef, 0xf3, 0xa7, 0x9f, 0x7f, 0x18, 0x1b, 0x0f, 0xdf, 0x9c, 0x1b, - 0xf0, 0xdf, 0x33, 0x92, 0x1f, 0x5f, 0x1f, 0x7b, 0x1b, 0xb0, 0xb6, 0xa6, - 0xf1, 0xef, 0xbf, 0xa5, 0xfd, 0x6d, 0x9e, 0x6d, 0x32, 0x84, 0x55, 0xf8, - 0xd5, 0xef, 0x9b, 0x7e, 0x1b, 0xb0, 0x18, 0x1b, 0xf0, 0xdf, 0x9c, 0x1b, - 0xf0, 0xcf, 0x23, 0x93, 0x9b, 0x5e, 0x5f, 0xf8, 0xfa, 0xef, 0x9b, 0x7f, - 0x1b, 0xb0, 0x18, 0x1b, 0xf0, 0xdf, 0x9c, 0x1b, 0xf0, 0xcf, 0x23, 0x93, - 0x9b, 0x5f, 0x19, 0xf8, 0xd7, 0xfe, 0xff, 0xdf, 0xcf, 0xfe, 0xff, 0xdf, - 0x00, 0xff, 0x0f, 0x00, 0x2f, 0xeb, 0x00, 0x1c, 0xd0, 0x0c, 0x00, 0x1c, - 0x26, 0x17, 0x00, 0x1c, 0x56, 0x01, 0x00, 0x1c, 0xba, 0x0c, 0x00, 0x1c, - 0xda, 0x02, 0x00, 0x1c, 0x26, 0x05, 0x00, 0x1c, 0x10, 0x0b, 0x00, 0x1c, - 0x16, 0x0d, 0x00, 0x1c, 0x3e, 0x02, 0x00, 0x1c, 0x1c, 0x02, 0x00, 0x1c, - 0xd2, 0x0c, 0x00, 0x1c, 0xa4, 0x00, 0x00, 0x1c, 0x12, 0x02, 0x03, 0xf8, - 0x9a, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xfc, 0x93, 0xfc, 0x93, 0xbd, 0x1b, - 0x34, 0xf8, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xbf, + 0xf7, 0xbd, 0xff, 0xa3, 0xb6, 0xa7, 0xfb, 0xbd, 0xb6, 0xa7, 0xaf, 0xad, + 0x93, 0xbc, 0x89, 0xb4, 0x3b, 0x83, 0xdc, 0xbc, 0xf9, 0xbc, 0xda, 0xa7, + 0xd2, 0xa6, 0xdb, 0xbe, 0xd3, 0xa6, 0xdd, 0xbe, 0x92, 0xa6, 0x8f, 0xac, + 0x37, 0x9b, 0xfc, 0xf3, 0xf2, 0xa5, 0xfd, 0xfb, 0xff, 0xcf, 0x7e, 0xeb, + 0x83, 0xef, 0x9d, 0x6c, 0x2c, 0xc4, 0xf3, 0xf3, 0x8b, 0xef, 0x9f, 0x6c, + 0x89, 0xbc, 0x89, 0xb4, 0x33, 0x83, 0xbb, 0xbc, 0x9d, 0x3b, 0xbd, 0xf7, + 0xb2, 0xa5, 0xb1, 0xad, 0xfd, 0xfb, 0xff, 0xcd, 0x8b, 0xef, 0x9d, 0x6c, + 0x0f, 0xce, 0xcf, 0xbe, 0x3b, 0x97, 0xbf, 0xc4, 0xed, 0xf3, 0x8e, 0xef, + 0x9d, 0x6c, 0x8c, 0xb4, 0xd6, 0xef, 0xdf, 0x6e, 0xc9, 0xbe, 0xc9, 0xb6, + 0xfd, 0xbe, 0xda, 0xbe, 0xde, 0xa6, 0x9c, 0x1b, 0xe1, 0xdf, 0x9c, 0x3b, + 0xbc, 0xf7, 0x3b, 0x83, 0x95, 0xac, 0xb3, 0xa5, 0xdd, 0xef, 0x9f, 0x6e, + 0x89, 0xbc, 0xf0, 0xfb, 0x2b, 0xff, 0xff, 0xdf, 0xff, 0x03, 0xf0, 0xff, + 0xf0, 0x3f, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x47, 0xdb, 0xff, 0xff, + 0x1f, 0xff, 0xff, 0xdf, 0xff, 0x5f, 0xff, 0xbf, 0x89, 0xb4, 0xd7, 0x76, + 0x3b, 0x83, 0xf9, 0xbc, 0x9f, 0x3b, 0xbf, 0xf7, 0xf2, 0xa7, 0xf5, 0xaf, + 0xff, 0xa5, 0xc3, 0x87, 0x9d, 0xef, 0xeb, 0x7c, 0xc3, 0x87, 0xff, 0xff, + 0x2b, 0xff, 0xff, 0xdf, 0x2c, 0xeb, 0xff, 0x8a, 0x8c, 0xee, 0x9f, 0x74, + 0x7c, 0x3b, 0x7d, 0xbf, 0x3f, 0xc5, 0x9f, 0xf7, 0xbf, 0xc3, 0xfb, 0xf3, + 0xbe, 0xc3, 0xb3, 0xf7, 0xe8, 0xfb, 0xfb, 0xcf, 0xff, 0xce, 0xff, 0x1f, + 0xb8, 0xf8, 0x93, 0xee, 0xbd, 0x7c, 0xbd, 0x1b, 0xf0, 0xcf, 0xbd, 0x13, + 0xfc, 0xff, 0xbd, 0x5c, 0xde, 0x74, 0xcd, 0xbe, 0xc9, 0xb6, 0xbd, 0x74, + 0xbd, 0x1b, 0x00, 0xcc, 0x7b, 0x93, 0xbd, 0x54, 0xff, 0xcd, 0xb7, 0x5c, + 0xbd, 0xfb, 0x5c, 0xee, 0xfe, 0xc9, 0x37, 0x5a, 0xfb, 0xcf, 0xfe, 0xce, + 0xff, 0x1f, 0xd1, 0xf8, 0x9d, 0x7a, 0x9c, 0x1b, 0xf0, 0xcf, 0x73, 0x92, + 0x3d, 0x5a, 0x00, 0x1c, 0x66, 0x08, 0xbf, 0x1b, 0x00, 0xdc, 0xbb, 0xbd, + 0x9e, 0x72, 0xc4, 0xef, 0x3b, 0x97, 0x37, 0x93, 0x9e, 0x52, 0x00, 0x1c, + 0x70, 0x08, 0xfc, 0x15, 0x40, 0xfe, 0xf3, 0x9b, 0xf7, 0xf7, 0xbd, 0x72, + 0xbd, 0x1b, 0x00, 0xcc, 0xbd, 0x13, 0x40, 0xfe, 0xbd, 0x52, 0xf5, 0xfb, + 0x8e, 0xef, 0xde, 0x74, 0xcd, 0xbe, 0xc9, 0xb6, 0xbd, 0x74, 0xbd, 0x1b, + 0x00, 0xcc, 0x7b, 0x93, 0xbd, 0x54, 0x92, 0xef, 0xfe, 0xcd, 0x7d, 0x3b, + 0xdb, 0xbf, 0xbf, 0x74, 0xf7, 0x92, 0x7f, 0x54, 0xf1, 0xfb, 0xb6, 0xef, + 0xfe, 0xce, 0xd7, 0x5d, 0xdd, 0x7d, 0xde, 0x1b, 0xf0, 0xcf, 0x5e, 0xc6, + 0xdd, 0x5d, 0xfe, 0xce, 0x7e, 0x3b, 0xdb, 0xbf, 0x2f, 0x93, 0x9f, 0x55, + 0xfb, 0xef, 0xff, 0x1f, 0xe6, 0xfd, 0x6c, 0xeb, 0x0f, 0xff, 0xff, 0xdf, + 0xf0, 0x3f, 0x00, 0x00, 0xab, 0xb5, 0xff, 0xff, 0x2d, 0xeb, 0xbc, 0x92, + 0xff, 0xcf, 0x00, 0x1c, 0x02, 0x01, 0xfc, 0x92, 0xfc, 0x15, 0xb9, 0xfc, + 0xf3, 0x9b, 0xf7, 0xf7, 0x82, 0xed, 0xbd, 0x6c, 0x4c, 0xc5, 0xbd, 0x4c, + 0xfe, 0xcf, 0x00, 0x1c, 0x7c, 0x00, 0xff, 0x1f, 0x10, 0xfe, 0xff, 0xd7, + 0xff, 0x8b, 0xfd, 0xc7, 0xf2, 0xf7, 0xfc, 0x15, 0xd0, 0xfd, 0xf3, 0x9a, + 0xf6, 0xf7, 0x3f, 0xcf, 0xfd, 0xbf, 0x84, 0xce, 0xff, 0x1f, 0x09, 0xfc, + 0xfb, 0xcf, 0x00, 0x1c, 0x8e, 0x00, 0x00, 0x1c, 0xfa, 0x00, 0xfc, 0x15, + 0x3b, 0xf6, 0xf3, 0x9b, 0xee, 0xf7, 0xff, 0x15, 0x09, 0xfc, 0xff, 0x1f, + 0x2a, 0xfc, 0xb2, 0xed, 0x9a, 0x75, 0xff, 0xdc, 0x32, 0x8b, 0x9a, 0x55, + 0xf1, 0xcd, 0x37, 0x9b, 0xdf, 0xf7, 0xfb, 0xcf, 0x00, 0x1c, 0xa3, 0x00, + 0xe3, 0xfb, 0xfc, 0x15, 0x23, 0xfa, 0xf3, 0x9b, 0xeb, 0xf7, 0x9a, 0xed, + 0xff, 0xcd, 0xba, 0x54, 0xb9, 0x74, 0xff, 0xdd, 0x76, 0x8b, 0xb9, 0x54, + 0x70, 0xcc, 0x9e, 0xbc, 0x73, 0x9b, 0xf2, 0xf7, 0xff, 0x15, 0x09, 0xfc, + 0xff, 0x1f, 0x49, 0xfc, 0xfb, 0xcf, 0x00, 0x1c, 0xba, 0x00, 0xfa, 0xfb, + 0x84, 0xee, 0xff, 0xcd, 0xb9, 0x54, 0xba, 0x54, 0x9f, 0x72, 0x3e, 0xc4, + 0xe5, 0xf3, 0x87, 0xee, 0x9d, 0x74, 0x89, 0xbc, 0x89, 0xb4, 0xdb, 0xdc, + 0x2f, 0x9b, 0xec, 0xf7, 0xff, 0xcd, 0x8b, 0xee, 0xb8, 0x54, 0xff, 0x1f, + 0x18, 0xfc, 0x8e, 0xee, 0xbd, 0x6c, 0x6c, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, + 0x56, 0xc5, 0xbd, 0x4c, 0xff, 0xcf, 0x00, 0x1c, 0xd8, 0x00, 0x9f, 0x72, + 0x7e, 0xc4, 0x9f, 0x52, 0x95, 0xee, 0x9e, 0x6c, 0x3f, 0xc4, 0xeb, 0xf3, + 0x97, 0xee, 0x9d, 0x6c, 0x2c, 0xc4, 0xef, 0xf3, 0xb8, 0xee, 0x98, 0x75, + 0xff, 0xdc, 0x32, 0x8b, 0x98, 0x55, 0xfd, 0x15, 0x6a, 0xfa, 0x37, 0x9b, + 0xf5, 0xf7, 0x9c, 0xee, 0xb8, 0x54, 0xf8, 0xcf, 0x00, 0x1c, 0xf1, 0x00, + 0xfb, 0xfb, 0xff, 0xcd, 0x80, 0xef, 0xb8, 0x54, 0xfe, 0xcf, 0x00, 0x1c, + 0x8a, 0x01, 0xfc, 0x92, 0x83, 0xef, 0x9f, 0x74, 0x35, 0xc4, 0xfa, 0xf3, + 0xfd, 0x15, 0x66, 0xfe, 0xf7, 0x9b, 0xf9, 0xf7, 0x34, 0xc4, 0xf8, 0xf3, + 0x33, 0xcc, 0xf3, 0x9a, 0xfb, 0xf3, 0xfb, 0xcf, 0x00, 0x1c, 0x09, 0x01, + 0x8c, 0xef, 0x9e, 0x6c, 0x3f, 0xc4, 0xe1, 0xf3, 0xfc, 0xcf, 0x00, 0x1c, + 0xa2, 0x01, 0xfc, 0x15, 0x51, 0xfc, 0xf3, 0x9b, 0xfb, 0xf3, 0x77, 0xcc, + 0xf3, 0x9a, 0xeb, 0xf3, 0xb2, 0xef, 0x8f, 0x7d, 0xff, 0xdc, 0x33, 0x8b, + 0x8f, 0x5d, 0xb9, 0xcd, 0x37, 0x9b, 0xf0, 0xf7, 0x77, 0xcc, 0xf3, 0x9a, + 0xfa, 0xf3, 0x98, 0xef, 0xbe, 0x6c, 0x7f, 0xc5, 0xbe, 0x4c, 0xfd, 0xcf, + 0x00, 0x1c, 0x29, 0x01, 0xfb, 0xfb, 0xff, 0xcd, 0x9c, 0xef, 0xaf, 0x5c, + 0x6d, 0xeb, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xbf, 0x0f, 0xff, 0xff, 0xdf, + 0x2f, 0xeb, 0x8e, 0xed, 0x99, 0x6c, 0x3a, 0xc4, 0xee, 0xf7, 0x90, 0xed, + 0x99, 0x6c, 0x34, 0xc4, 0xf2, 0xf7, 0x92, 0xed, 0x99, 0x6c, 0x3c, 0xc4, + 0xf6, 0xf7, 0x94, 0xed, 0x99, 0x6c, 0x3d, 0xc4, 0xfa, 0xf7, 0x96, 0xed, + 0x99, 0x6c, 0x35, 0xc4, 0xf7, 0xf3, 0x98, 0xed, 0xbd, 0x6c, 0x4c, 0xc5, + 0xbd, 0x4c, 0xfe, 0xcf, 0x00, 0x1c, 0x4f, 0x01, 0x6f, 0xeb, 0xff, 0xff, + 0x2f, 0xeb, 0x9c, 0xed, 0xff, 0xcd, 0xb8, 0x54, 0xba, 0x54, 0xb9, 0x54, + 0xb7, 0x5c, 0xdd, 0x7c, 0xde, 0x1b, 0xf0, 0xcf, 0xdd, 0x5c, 0xde, 0x74, + 0xe1, 0xee, 0xbf, 0x97, 0xde, 0x54, 0xdd, 0x74, 0xde, 0x1b, 0x00, 0xcc, + 0xdd, 0x54, 0xbf, 0x54, 0xfc, 0x1b, 0xef, 0xff, 0xff, 0xce, 0xa5, 0xee, + 0xff, 0x1f, 0x8f, 0xfe, 0xbf, 0xc7, 0xf8, 0xf7, 0xaa, 0xee, 0xee, 0x7d, + 0xf8, 0xce, 0xff, 0x1f, 0x2e, 0xfe, 0x6f, 0xeb, 0xff, 0xfb, 0xff, 0xff, + 0x2f, 0xeb, 0x8f, 0xee, 0x99, 0x6c, 0x3b, 0xc4, 0xfa, 0xf7, 0x91, 0xee, + 0x99, 0x6c, 0x3f, 0xc4, 0xfa, 0xf3, 0xfd, 0xcf, 0x00, 0x1c, 0x81, 0x01, + 0xe9, 0xfb, 0x95, 0xee, 0xbd, 0x6c, 0x4c, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, + 0xd4, 0xee, 0x7b, 0x97, 0x4b, 0xc5, 0x49, 0xc5, 0xbd, 0x4c, 0x99, 0xee, + 0xbf, 0x74, 0x5e, 0xc5, 0xbf, 0x54, 0xfb, 0xcf, 0xfe, 0xce, 0xff, 0x1f, + 0x3e, 0xfa, 0xf9, 0xcf, 0x00, 0x1c, 0x97, 0x01, 0x6f, 0xeb, 0xff, 0xff, + 0xff, 0x8b, 0x80, 0xef, 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, 0xbf, 0x74, + 0xf7, 0x93, 0xff, 0x54, 0xc3, 0x87, 0xff, 0xff, 0x2f, 0xeb, 0xff, 0xcf, + 0xff, 0x1f, 0xc3, 0xf9, 0xbe, 0xc7, 0xf3, 0xf7, 0x89, 0xef, 0xbd, 0x6c, + 0x4c, 0xc5, 0xbd, 0x4c, 0xfb, 0xcf, 0x00, 0x1c, 0xb0, 0x01, 0xfb, 0xcf, + 0xfe, 0xce, 0xff, 0x1f, 0x5e, 0xfa, 0x6f, 0xeb, 0x2f, 0xeb, 0xff, 0x8b, + 0x00, 0x1c, 0xb9, 0x01, 0x6f, 0xeb, 0xff, 0xff, 0x91, 0xef, 0x97, 0x7c, + 0xbf, 0xc4, 0xff, 0x3b, 0xff, 0xfa, 0xc3, 0x87, 0x94, 0xef, 0x9f, 0x74, + 0x3e, 0xc4, 0xf6, 0xf7, 0x3d, 0xc4, 0xf6, 0xf7, 0x3a, 0xc4, 0xf6, 0xf7, + 0x3b, 0xc4, 0xf6, 0xf7, 0xff, 0xcf, 0xf7, 0xfb, 0xfb, 0xcf, 0xf9, 0xfb, + 0xfa, 0xcf, 0xfb, 0xfb, 0xf5, 0xcf, 0xfd, 0xfb, 0xf4, 0xcf, 0xc3, 0x87, + 0xff, 0x5f, 0xff, 0xbf, 0x0f, 0xff, 0xff, 0xdf, 0xf0, 0x3f, 0x00, 0x00, + 0x93, 0xd5, 0xff, 0xff, 0x00, 0x00, 0xf0, 0x00, 0x2f, 0xeb, 0x8e, 0xef, + 0xbf, 0x7c, 0xdd, 0x1b, 0xf0, 0xcf, 0x5f, 0xc6, 0xf0, 0xcd, 0xb7, 0x97, + 0xdf, 0x5c, 0xde, 0x7c, 0xde, 0x1b, 0xf0, 0xcf, 0x7b, 0x97, 0xbe, 0x5c, + 0xff, 0xcd, 0xbe, 0x54, 0xdc, 0x1b, 0xf4, 0xff, 0xdd, 0x4c, 0xf8, 0xce, + 0xd9, 0x5c, 0xbb, 0x5c, 0xba, 0x5c, 0x00, 0x1c, 0x06, 0x12, 0x00, 0x1c, + 0x2e, 0x12, 0x00, 0x1c, 0x92, 0x13, 0x00, 0x1c, 0x36, 0x13, 0x00, 0x1c, + 0xee, 0x0e, 0x6f, 0xeb, 0xfb, 0xfe, 0xff, 0xdf, 0x92, 0xed, 0xdf, 0x7c, + 0xf0, 0xcd, 0xb7, 0x97, 0xde, 0x13, 0xaf, 0xff, 0xdf, 0x5c, 0xde, 0x7c, + 0xde, 0x1b, 0xf0, 0xcf, 0x7b, 0x97, 0xbe, 0x5c, 0xc3, 0x87, 0xff, 0xff, + 0x2d, 0xeb, 0xde, 0xeb, 0xff, 0xcd, 0xbf, 0x47, 0x9b, 0xed, 0xbb, 0x7c, + 0x77, 0x8b, 0x9a, 0x7c, 0x33, 0x8b, 0x35, 0x9b, 0xe8, 0xf3, 0x9e, 0xed, + 0xdb, 0x7c, 0xbb, 0x8b, 0xbd, 0x6c, 0xdd, 0x3b, 0xbd, 0xf7, 0xbf, 0x6d, + 0xbf, 0x47, 0xff, 0xde, 0xbb, 0x8b, 0xdb, 0x5c, 0xdb, 0x7c, 0xf9, 0x7c, + 0xbf, 0x97, 0xdb, 0x5c, 0xdf, 0x75, 0xff, 0xcd, 0xfe, 0xd5, 0x78, 0x8f, + 0xde, 0x74, 0x7b, 0x97, 0xbe, 0x54, 0x5f, 0x67, 0x6a, 0xee, 0x9e, 0x7b, + 0x9c, 0x1b, 0xf0, 0xdf, 0xab, 0xee, 0x9d, 0x3b, 0xbc, 0xf7, 0x9f, 0x6c, + 0xe8, 0x93, 0x32, 0x84, 0xbe, 0x7b, 0x9d, 0x1b, 0xf0, 0xdf, 0xfb, 0xbc, + 0xdf, 0x7b, 0xde, 0x1b, 0xf0, 0xdf, 0xbf, 0x93, 0xdf, 0x5b, 0xbb, 0xb5, + 0xbd, 0x1b, 0xf0, 0xdf, 0x71, 0x9b, 0xf2, 0xf3, 0xbf, 0xc2, 0xf4, 0xf7, + 0xde, 0x7b, 0xde, 0x1b, 0xf0, 0xcf, 0x7b, 0x93, 0xbe, 0x5b, 0xbf, 0x7b, + 0xbd, 0x1b, 0xf0, 0xcf, 0x5f, 0xc5, 0xbf, 0x5b, 0xfe, 0xeb, 0x6d, 0xeb, + 0xff, 0x8b, 0x9d, 0xee, 0xbf, 0x7c, 0xbd, 0x1b, 0xf0, 0xcf, 0xbf, 0x5c, + 0xbb, 0xbf, 0xfe, 0x7c, 0xff, 0x1b, 0xf0, 0xdf, 0xf7, 0x93, 0xfe, 0x5c, + 0xc3, 0x87, 0xff, 0xff, 0x84, 0xef, 0xff, 0x7c, 0xfb, 0xb7, 0xc3, 0x87, + 0x86, 0xef, 0xfe, 0x7c, 0xff, 0x1b, 0xf0, 0xdf, 0xc3, 0x87, 0xff, 0xff, + 0x89, 0xef, 0xbf, 0x7c, 0x9e, 0x7c, 0xbb, 0xb5, 0x9c, 0x1b, 0xf0, 0xdf, + 0x35, 0x9b, 0xff, 0x3b, 0xff, 0xfa, 0xc3, 0x87, 0x3e, 0xeb, 0x8e, 0xef, + 0x9f, 0x7c, 0x9c, 0x1b, 0xf0, 0xdf, 0xbf, 0xc4, 0xe5, 0xf3, 0x91, 0xef, + 0xbe, 0x74, 0x9f, 0x77, 0x9d, 0x3b, 0x7c, 0xbf, 0x3f, 0xc4, 0xec, 0xf7, + 0x95, 0xef, 0xba, 0x7c, 0x77, 0x8b, 0xff, 0xdd, 0xd9, 0x7c, 0x7b, 0x97, + 0x9b, 0x7c, 0x33, 0x8b, 0x35, 0x9b, 0xf6, 0xf3, 0x9a, 0xef, 0x7a, 0x7c, + 0xef, 0x8a, 0xdd, 0x6c, 0x7e, 0x3b, 0xbe, 0xf7, 0xff, 0x4e, 0xba, 0x5c, + 0x7e, 0xeb, 0xff, 0xff, 0xfb, 0xfe, 0xff, 0xdf, 0xa3, 0xb5, 0xff, 0xff, + 0x9c, 0xef, 0xbf, 0x6c, 0xff, 0xdd, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, + 0xcf, 0xfe, 0xff, 0xdf, 0x9f, 0xec, 0xf0, 0xcd, 0xbb, 0x5c, 0xf8, 0xdc, + 0xff, 0x7c, 0x7f, 0xc7, 0xcf, 0x7c, 0x7f, 0xc6, 0xf7, 0x97, 0x5b, 0xc7, + 0xff, 0x5c, 0xfc, 0x27, 0xdf, 0xff, 0x7f, 0xc7, 0xb7, 0x97, 0x5a, 0xc6, + 0xcf, 0x5c, 0xdc, 0x27, 0xcf, 0xff, 0x7f, 0xc6, 0xf7, 0x97, 0xff, 0x13, + 0xcf, 0xff, 0xfc, 0x23, 0xdf, 0xff, 0xfc, 0x27, 0xbf, 0xff, 0x7f, 0xc7, + 0xb7, 0x97, 0x59, 0xc6, 0xdc, 0x23, 0xcf, 0xff, 0xdc, 0x27, 0xaf, 0xff, + 0x7f, 0xc6, 0x7f, 0x97, 0xbd, 0x13, 0xaf, 0xff, 0xbc, 0x23, 0xbf, 0xff, + 0xff, 0xcf, 0xf0, 0xd7, 0xfe, 0x3b, 0xdd, 0xdb, 0xbc, 0x23, 0xaf, 0xff, + 0xc3, 0x87, 0xff, 0xff, 0x3d, 0xeb, 0xbf, 0xc7, 0xd5, 0xf3, 0xfe, 0xc6, + 0xd5, 0xf7, 0xbf, 0xc5, 0xd5, 0xf3, 0x9a, 0xed, 0x9b, 0x7c, 0x9c, 0x1b, + 0xf0, 0xcf, 0x33, 0x8b, 0x0f, 0xcb, 0xf1, 0x9a, 0xdb, 0xf3, 0x7e, 0xed, + 0x5b, 0x7b, 0x5b, 0xb2, 0x2b, 0x8b, 0x5f, 0x5f, 0xe1, 0xa3, 0x9b, 0xbc, + 0x93, 0xa7, 0x5f, 0x7c, 0x5b, 0xb2, 0x5b, 0xba, 0xfb, 0x7b, 0xff, 0x1b, + 0xf0, 0xdf, 0xeb, 0x93, 0xfb, 0x5b, 0xff, 0x7c, 0x5f, 0xc7, 0xde, 0x1b, + 0xfc, 0xdf, 0xde, 0xbe, 0xff, 0xcb, 0xf1, 0xd3, 0xef, 0x97, 0xbf, 0x93, + 0xdf, 0x5c, 0xbd, 0x4c, 0xff, 0xcf, 0xf7, 0xfb, 0xfe, 0xcf, 0xf9, 0xfb, + 0xfe, 0xcf, 0xfb, 0xfb, 0xfe, 0xcf, 0xfd, 0xfb, 0xfd, 0xcf, 0x7d, 0xeb, + 0x9f, 0x7f, 0xb0, 0xc4, 0xf6, 0xf3, 0x9b, 0xbc, 0xb2, 0xee, 0x93, 0xa5, + 0xbf, 0x7c, 0x7c, 0xc5, 0xbf, 0x5c, 0xff, 0xcf, 0xfd, 0xfb, 0xfe, 0xcf, + 0xc3, 0x87, 0xff, 0xff, 0x2c, 0xeb, 0x9f, 0x7f, 0xb0, 0xc4, 0xdf, 0xf3, + 0xbb, 0xbc, 0xd9, 0xee, 0xb7, 0xa6, 0xbf, 0x7d, 0x3c, 0xc5, 0xfb, 0xf3, + 0x00, 0x1c, 0x17, 0x00, 0xe7, 0xfb, 0xbe, 0xee, 0x61, 0xa5, 0xdb, 0xbc, + 0x7b, 0xa3, 0x5f, 0x7b, 0x7f, 0xc2, 0x5f, 0x5b, 0x3b, 0x7d, 0x3b, 0xb1, + 0x3b, 0xb9, 0xf0, 0xce, 0xbb, 0x96, 0xa7, 0x92, 0x5f, 0x5b, 0x9b, 0xbc, + 0x7b, 0x7d, 0xfb, 0x96, 0x2f, 0x93, 0x9b, 0x5d, 0xdf, 0x5f, 0xff, 0xcf, + 0xfd, 0xfb, 0xfe, 0xcf, 0x6c, 0xeb, 0xff, 0xff, 0x3c, 0xeb, 0xff, 0x8b, + 0x9b, 0xbf, 0x6b, 0xef, 0x93, 0xa3, 0x9f, 0x7c, 0x3f, 0xc4, 0xcc, 0xf3, + 0x9b, 0xbf, 0x93, 0xa3, 0x9f, 0x7c, 0x3c, 0xc4, 0xcf, 0xf7, 0x71, 0xef, + 0x41, 0xa3, 0x9b, 0xbf, 0x93, 0xa2, 0x51, 0xa4, 0xcc, 0xbe, 0xcc, 0xb6, + 0x3f, 0x72, 0x32, 0xb1, 0x32, 0xb9, 0x7b, 0x92, 0x3f, 0x52, 0xd7, 0xbe, + 0x5f, 0x6c, 0x36, 0xef, 0xa7, 0x96, 0xab, 0x93, 0xdf, 0x4c, 0xbc, 0x4c, + 0xdf, 0x7c, 0x5c, 0xc6, 0xdf, 0x5c, 0x5b, 0x7b, 0x5a, 0x1b, 0xf0, 0xdf, + 0x5b, 0xba, 0xf8, 0xfb, 0xcf, 0xfe, 0xff, 0xdf, 0xc7, 0xfe, 0xff, 0xdf, + 0x00, 0xff, 0x1f, 0x00, 0xf0, 0xcd, 0xb7, 0x97, 0xab, 0x93, 0xdf, 0x5c, + 0xf7, 0x97, 0x9b, 0x7b, 0x9c, 0x1b, 0xf0, 0xcf, 0xf3, 0x93, 0xfb, 0x5b, + 0xff, 0xcf, 0xfb, 0xfb, 0xfe, 0xcf, 0xfd, 0xfb, 0xfc, 0xcf, 0x7c, 0xeb, + 0x2b, 0xeb, 0x98, 0xed, 0xbf, 0x6c, 0x05, 0x6c, 0x02, 0xa5, 0x22, 0x8a, + 0xa5, 0x4c, 0xbf, 0xc0, 0x7b, 0xf3, 0x7b, 0x7c, 0x7b, 0x1b, 0xf0, 0xdf, + 0xb0, 0xc3, 0x80, 0xf3, 0xf0, 0xcd, 0x41, 0xa4, 0xfc, 0xfb, 0x6c, 0x93, + 0xe4, 0x92, 0x6c, 0x92, 0x9b, 0xbb, 0x93, 0xa2, 0x9f, 0x6c, 0x94, 0xbc, + 0x8c, 0xb4, 0x22, 0x9b, 0xbe, 0xf7, 0x9b, 0xbb, 0x93, 0xa2, 0x9f, 0x7c, + 0x9e, 0xb4, 0x9c, 0x1b, 0xfc, 0xdf, 0xbf, 0xc4, 0xf0, 0xf7, 0x9b, 0xbb, + 0x93, 0xa2, 0xdd, 0x74, 0xcc, 0xbe, 0xd4, 0xb6, 0xbf, 0x6c, 0xeb, 0xee, + 0x7f, 0x97, 0x7b, 0x93, 0xbf, 0x4c, 0xfc, 0x6c, 0x9d, 0x6c, 0x32, 0x84, + 0xa9, 0xfb, 0xbe, 0xc4, 0xab, 0xf7, 0x9b, 0xbb, 0x93, 0xa2, 0xdf, 0x7c, + 0x7c, 0xc6, 0xdf, 0x5c, 0xb0, 0xc5, 0xf1, 0xf7, 0x9b, 0xbb, 0x93, 0xa2, + 0xbf, 0x7c, 0xbb, 0xb5, 0xbd, 0x1b, 0xf0, 0xdf, 0xd8, 0xee, 0x9b, 0x7e, + 0x9c, 0x1b, 0xf0, 0xcf, 0x37, 0x93, 0x9b, 0x5e, 0xf2, 0xfb, 0xbb, 0xbd, + 0xb7, 0xa2, 0x9b, 0xbb, 0x93, 0xa2, 0xdf, 0x7c, 0xdb, 0xb6, 0xdb, 0xbe, + 0x9f, 0x7d, 0x9c, 0x1b, 0xf0, 0xdf, 0x3b, 0x93, 0x9f, 0x5d, 0x3b, 0xb9, + 0x87, 0xa2, 0x3f, 0x7c, 0x3b, 0xb1, 0xfc, 0x6c, 0x9d, 0x6c, 0x32, 0x84, + 0xcf, 0xfb, 0xdb, 0xbb, 0xdb, 0xa2, 0xdf, 0x7e, 0x3c, 0xc6, 0xe2, 0xf7, + 0xb0, 0xc5, 0xf1, 0xf7, 0x9b, 0xbb, 0x93, 0xa2, 0xbf, 0x7c, 0xbb, 0xb5, + 0xbd, 0x1b, 0xf0, 0xdf, 0xec, 0xef, 0x9b, 0x7f, 0x9c, 0x1b, 0xf0, 0xcf, + 0x37, 0x93, 0x9b, 0x5f, 0xe7, 0xfb, 0xbb, 0xbd, 0xb7, 0xa2, 0x9b, 0xbb, + 0x93, 0xa2, 0xdf, 0x7c, 0xdb, 0xb6, 0xdb, 0xbe, 0x9f, 0x7d, 0x9c, 0x1b, + 0xf0, 0xdf, 0x3b, 0x93, 0x9f, 0x5d, 0xf4, 0xfb, 0xbb, 0xbb, 0xb7, 0xa2, + 0xc2, 0xa4, 0xcc, 0xbe, 0xd4, 0xb6, 0x9f, 0x6d, 0xf8, 0xef, 0x3f, 0x97, + 0x3b, 0x93, 0x9f, 0x4d, 0x3b, 0xb9, 0x27, 0xa2, 0x3f, 0x79, 0x3b, 0xb1, + 0xb0, 0xc1, 0x79, 0xf4, 0x6b, 0xeb, 0xff, 0xff, 0xcf, 0xfe, 0xff, 0xdf, + 0x00, 0xff, 0x1f, 0x00, 0x2f, 0xeb, 0x00, 0x1c, 0x82, 0x0c, 0x00, 0x1c, + 0x4e, 0x16, 0x00, 0x1c, 0x6c, 0x01, 0x00, 0x1c, 0x6e, 0x0c, 0x00, 0x1c, + 0xc8, 0x02, 0x00, 0x1c, 0xfe, 0x04, 0x00, 0x1c, 0xea, 0x0a, 0x00, 0x1c, + 0xdc, 0x0c, 0x00, 0x1c, 0x42, 0x02, 0x00, 0x1c, 0x20, 0x02, 0x00, 0x1c, + 0x84, 0x0c, 0x00, 0x1c, 0xa8, 0x00, 0x00, 0x1c, 0x18, 0x02, 0x03, 0xf8, 0x97, 0xef, 0xfb, 0x6c, 0xff, 0x1b, 0x00, 0xdc, 0xd6, 0xcc, 0xf3, 0x9b, - 0xf7, 0xf7, 0xd7, 0xd7, 0xfe, 0x8b, 0x0a, 0xdc, 0xf3, 0x9b, 0xfc, 0xf7, - 0xfc, 0xd7, 0xfe, 0x8b, 0xc3, 0x87, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xbf, - 0x9a, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xfc, 0x93, 0xfc, 0x93, 0xbd, 0x1b, - 0x34, 0xf8, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xbf, - 0xb3, 0xef, 0xff, 0xcc, 0x9f, 0x4d, 0xff, 0x8b, 0xfc, 0x93, 0xfc, 0x93, - 0xfc, 0x93, 0xfd, 0xbf, 0x9f, 0x13, 0x7f, 0xf8, 0x9f, 0x4d, 0xfc, 0x93, - 0x9f, 0x6d, 0x3f, 0xc4, 0x01, 0xf0, 0xb9, 0xef, 0xf7, 0xa7, 0xff, 0x6f, - 0x9c, 0xef, 0xff, 0xcd, 0xff, 0x1b, 0x00, 0xdc, 0xbf, 0x4c, 0xc3, 0x87, - 0xff, 0x7f, 0xff, 0xbf, 0xfb, 0x7f, 0xff, 0xbf, 0x9d, 0xee, 0xff, 0xce, - 0xdd, 0x4c, 0xbc, 0x6c, 0x53, 0xc5, 0xbc, 0x4c, 0xbc, 0x6c, 0x72, 0xc5, - 0x71, 0xc5, 0x51, 0xc5, 0xbc, 0x4c, 0xbf, 0x6c, 0x77, 0xc5, 0x76, 0xc5, - 0x57, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0xc4, 0xef, 0x7b, 0x97, 0xbf, 0x4c, - 0xc2, 0xcd, 0xb7, 0x5c, 0xbd, 0x6c, 0xc6, 0xef, 0x7b, 0x97, 0x50, 0xc5, - 0xbd, 0x4c, 0xbd, 0x6c, 0x56, 0xc5, 0xbd, 0x4c, 0xbf, 0x6c, 0x7e, 0xc5, - 0xbf, 0x4c, 0xbd, 0x6c, 0x4c, 0xc5, 0xbd, 0x4c, 0xdc, 0x6c, 0xde, 0xb6, - 0xde, 0x1b, 0xe0, 0xdf, 0xbc, 0x6c, 0x5d, 0xc6, 0xde, 0xbe, 0xbd, 0x1b, - 0xc1, 0xcf, 0x7b, 0x93, 0xbc, 0x4c, 0xdc, 0x6c, 0xde, 0xb6, 0xde, 0x1b, - 0xe0, 0xdf, 0xbc, 0x6c, 0x5e, 0xc6, 0xde, 0xbe, 0xbd, 0x1b, 0xc1, 0xcf, - 0x7b, 0x93, 0xbc, 0x4c, 0xbd, 0x6c, 0xd7, 0xef, 0x7b, 0x97, 0x4a, 0xc5, - 0xbd, 0x4c, 0xbf, 0x6c, 0xbd, 0x13, 0xcf, 0xff, 0xbf, 0x4c, 0xc3, 0x87, - 0xff, 0x5f, 0xff, 0xbf, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0x00, 0x9b, 0xef, 0xa9, 0xbf, 0xfe, 0x6c, 0xf5, 0xbf, + 0xfc, 0xf7, 0xd7, 0xd7, 0xfe, 0x8b, 0xfc, 0x15, 0xe0, 0xfe, 0xf3, 0x9b, + 0xfc, 0xf7, 0xfc, 0xd7, 0xfe, 0x8b, 0xc3, 0x87, 0xff, 0x7f, 0xff, 0xbf, + 0x8b, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xfc, 0x93, 0xfc, 0x93, 0xbd, 0x1b, + 0x34, 0xf8, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0x2f, 0xeb, 0x00, 0x1c, + 0x0a, 0x00, 0x6f, 0xeb, 0xff, 0x8b, 0x92, 0xef, 0xff, 0xcd, 0xbf, 0x4c, + 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfd, 0xbf, 0xbf, 0x13, 0x7f, 0xf8, + 0xbf, 0x4c, 0xfc, 0x93, 0xb0, 0x93, 0xfe, 0xcd, 0x9f, 0x6e, 0x71, 0x97, + 0x01, 0xf0, 0x99, 0xef, 0xf3, 0xa7, 0xff, 0x6f, 0xff, 0x1b, 0x00, 0xdc, + 0x9d, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0x7f, 0xff, 0xbf, + 0xfb, 0x7f, 0xff, 0xbf, 0x9b, 0xef, 0xa9, 0xbf, 0xfe, 0x6c, 0xf5, 0xbf, 0xf5, 0xb7, 0xf7, 0x93, 0xfe, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, - 0x95, 0xef, 0xbe, 0x6c, 0xb5, 0xbd, 0xb5, 0xb5, 0xe9, 0xbf, 0xf7, 0x93, - 0xfe, 0x4c, 0xbe, 0x1b, 0x80, 0xdf, 0xf8, 0xef, 0xde, 0x6c, 0xb7, 0xbd, - 0xbf, 0x97, 0xb7, 0x93, 0xde, 0x4c, 0xbe, 0x6c, 0x5f, 0xc5, 0xbe, 0x4c, - 0xc3, 0x87, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xbf, 0x00, 0x7f, 0x00, 0x00, - 0x9c, 0xef, 0xbe, 0x6c, 0x7f, 0xc5, 0xbe, 0x4c, 0xc3, 0x87, 0xff, 0xff, - 0xff, 0x5f, 0xff, 0xbf, 0x98, 0xef, 0xff, 0xcd, 0xb7, 0x5c, 0xdd, 0x6c, - 0xb9, 0xef, 0xb7, 0x97, 0xdd, 0x4c, 0xfe, 0xce, 0xd7, 0x5c, 0xdd, 0x6c, - 0x7b, 0x97, 0x50, 0xc5, 0xbd, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, - 0x00, 0xf0, 0x00, 0x00, 0xff, 0x8b, 0xbf, 0xc7, 0xf6, 0xf7, 0x93, 0xef, + 0x82, 0xed, 0xbf, 0x1b, 0x80, 0xdf, 0xb7, 0xbd, 0xfe, 0x6c, 0xc3, 0xed, + 0xfb, 0x97, 0xf7, 0x93, 0xfe, 0x4c, 0xc3, 0x87, 0x87, 0xed, 0xe9, 0xbf, + 0xbe, 0x6c, 0xb5, 0xbd, 0xb5, 0xb5, 0xf7, 0x93, 0xfe, 0x4c, 0xbe, 0x1b, + 0x80, 0xdf, 0xb7, 0xbd, 0xde, 0x6c, 0xeb, 0xed, 0xbf, 0x97, 0xb7, 0x93, + 0xde, 0x4c, 0xbe, 0x6c, 0x5f, 0xc5, 0xbe, 0x4c, 0xc3, 0x87, 0xff, 0xff, + 0x91, 0xed, 0xbe, 0x6c, 0x7f, 0xc5, 0xbe, 0x4c, 0xc3, 0x87, 0xff, 0xff, + 0x94, 0xed, 0xfe, 0x6c, 0xff, 0x1b, 0xfe, 0xdf, 0xc3, 0x87, 0xff, 0xff, + 0xff, 0x8b, 0xbf, 0xc7, 0xf6, 0xf3, 0x98, 0xed, 0xbf, 0x6c, 0x5c, 0xc5, + 0xbf, 0x4c, 0xbf, 0x6c, 0x5d, 0xc5, 0xbf, 0x4c, 0xf7, 0xfb, 0x9c, 0xed, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x7d, 0xc5, 0xbf, 0x4c, - 0xc3, 0x87, 0x97, 0xef, 0xbf, 0x6c, 0x5c, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, - 0x5d, 0xc5, 0xbf, 0x4c, 0xbd, 0x6c, 0xda, 0xef, 0x7b, 0x97, 0xbd, 0x4c, - 0xbd, 0x6c, 0x6c, 0xc5, 0xbd, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, - 0x00, 0x00, 0xf0, 0x00, 0x9a, 0xef, 0xbf, 0x1b, 0xfc, 0xdf, 0xff, 0x6c, - 0xbb, 0xbd, 0x7b, 0xc7, 0x7a, 0xc7, 0xf7, 0x93, 0xff, 0x4c, 0xc3, 0x87, - 0xff, 0x5f, 0xff, 0xbf, 0x9a, 0xef, 0xbf, 0x1b, 0xf0, 0xdf, 0xda, 0xef, - 0xfd, 0x6c, 0xab, 0xbd, 0xfb, 0x97, 0xf7, 0x93, 0xfd, 0x4c, 0xc3, 0x87, - 0xff, 0x5f, 0xff, 0xbf, 0x00, 0x00, 0xf0, 0x00, 0x9c, 0xef, 0xfd, 0x6c, - 0xeb, 0xb7, 0xff, 0x1b, 0xf0, 0xdf, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, - 0x9d, 0xef, 0xfe, 0x6c, 0xe9, 0xb7, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, - 0x98, 0xef, 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, 0xfc, 0x93, 0xfc, 0x93, - 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xbf, 0x6c, 0x7e, 0xc5, - 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, - 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x2d, 0xeb, 0x7c, 0xec, - 0x9f, 0x7b, 0x3b, 0xc4, 0x96, 0xf7, 0xbe, 0x7b, 0xff, 0xdd, 0x77, 0x8b, - 0x80, 0xed, 0xbe, 0x5b, 0x3f, 0xc5, 0xea, 0xf3, 0x3f, 0xcd, 0xb6, 0xbd, - 0xde, 0x6c, 0xbe, 0x3b, 0xdf, 0xdf, 0x7f, 0xcd, 0xb6, 0xbd, 0x7d, 0x9b, - 0x5f, 0xf3, 0xba, 0x7c, 0xb7, 0x8b, 0x3f, 0xc6, 0xa6, 0xf7, 0x11, 0x26, - 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, - 0xab, 0xed, 0xf1, 0xce, 0xdf, 0x5d, 0xbf, 0x7c, 0x39, 0xc5, 0xe9, 0xf7, - 0xda, 0x7c, 0xbe, 0x1b, 0xbf, 0xdf, 0xbf, 0xc5, 0x7c, 0x9b, 0xb9, 0xbd, - 0x79, 0xc6, 0x7b, 0x93, 0xba, 0x5c, 0xbd, 0x1b, 0xbf, 0xdf, 0x77, 0x8b, - 0xbf, 0xc5, 0x3d, 0xf7, 0x94, 0xed, 0xbf, 0x6c, 0x7d, 0xc5, 0xbf, 0x4c, - 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, 0xff, 0xcd, 0xbe, 0x5b, 0x3f, 0xcd, - 0xb6, 0xbd, 0xde, 0x6b, 0xbe, 0x3b, 0xdf, 0xdf, 0x7f, 0xcd, 0xb7, 0xbd, - 0x7d, 0x9b, 0x9e, 0xed, 0x48, 0xf3, 0xbb, 0x7c, 0xfd, 0x1b, 0xe0, 0xcf, - 0xbf, 0x8a, 0xbf, 0xc2, 0xb9, 0xf7, 0xff, 0xde, 0xde, 0x1b, 0xe0, 0xdf, - 0xdf, 0x3b, 0xdd, 0xdb, 0xd0, 0xc6, 0xb4, 0x92, 0xbb, 0x5c, 0x43, 0xf7, - 0x5a, 0x1b, 0xe0, 0xcf, 0x5b, 0x5c, 0xf3, 0x5c, 0x9a, 0x7b, 0x9c, 0x1b, - 0x01, 0xdf, 0x9c, 0x1b, 0xe1, 0xcf, 0x5a, 0xc4, 0x9a, 0x5b, 0x9b, 0x7b, - 0x9c, 0x1b, 0xe0, 0xdf, 0x59, 0xc4, 0x9b, 0x5b, 0x11, 0x26, 0xfd, 0xdf, - 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xf8, 0xcf, - 0x00, 0x1c, 0x9f, 0x00, 0x6a, 0xf8, 0xf3, 0xee, 0xf2, 0xcb, 0x7f, 0x5f, - 0xff, 0x7c, 0x39, 0xc7, 0x5c, 0xf4, 0xde, 0x1b, 0xbf, 0xdf, 0xbf, 0xc6, - 0xbc, 0x9b, 0xd9, 0xbe, 0x79, 0xc5, 0x7b, 0x93, 0xba, 0x5c, 0xbd, 0x1b, - 0xbf, 0xdf, 0x77, 0x8b, 0xbf, 0xc5, 0x1d, 0xf7, 0x9c, 0xee, 0xbf, 0x6c, - 0x7d, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, 0x11, 0x26, - 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, - 0xfa, 0xb6, 0xff, 0x1b, 0xf8, 0xdf, 0xbd, 0xc7, 0x7a, 0xf3, 0xdd, 0xc7, - 0x8f, 0xf7, 0xbc, 0xc7, 0x48, 0xf3, 0xbb, 0xc7, 0x82, 0xf4, 0xbd, 0x1b, - 0xe0, 0xdf, 0x5a, 0xc5, 0xbb, 0x5c, 0xb2, 0x7c, 0xda, 0x7c, 0x77, 0x8b, - 0x5f, 0xc6, 0xbf, 0xc5, 0xda, 0x5c, 0x2d, 0xf7, 0xbe, 0x6c, 0x70, 0xc5, - 0x6f, 0xc5, 0x50, 0xc5, 0xbe, 0x4c, 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, - 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xf3, 0xcf, 0xb5, 0xef, - 0xff, 0x5d, 0xb4, 0xef, 0xff, 0x6d, 0x76, 0xc7, 0xff, 0x4d, 0xff, 0x6d, - 0x79, 0xc7, 0xff, 0x4d, 0xfd, 0x6d, 0xbe, 0x6d, 0xff, 0xcf, 0xba, 0xef, - 0xff, 0x4d, 0x70, 0xc6, 0x6f, 0xc6, 0xf6, 0xfb, 0x83, 0xfe, 0xff, 0xdf, - 0x78, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0xbf, 0xff, 0x4f, 0xff, 0xbf, - 0xbf, 0x7c, 0xde, 0x4c, 0xbd, 0x1b, 0x01, 0xdf, 0xbf, 0x5c, 0xb9, 0x7c, - 0xdd, 0x1b, 0xfd, 0xdf, 0xbb, 0x8b, 0xbf, 0xc6, 0xf8, 0xf3, 0xdf, 0x7c, - 0xbb, 0x8b, 0x59, 0xc6, 0x7e, 0xc5, 0xdf, 0x5c, 0xb9, 0x5c, 0x7f, 0xcc, - 0xfd, 0x6b, 0x89, 0xbc, 0xf2, 0x9b, 0xf5, 0xf7, 0xff, 0x1f, 0x03, 0xfb, - 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, - 0x9e, 0xeb, 0x00, 0x1c, 0x2e, 0x19, 0x90, 0xed, 0xff, 0xce, 0xdd, 0x4c, - 0xff, 0x1f, 0x11, 0xfb, 0x0d, 0xf8, 0x92, 0xed, 0xbf, 0x6c, 0x5d, 0xc5, - 0xbf, 0x4c, 0xbf, 0x6c, 0x7e, 0xc5, 0xbf, 0x4c, 0xc0, 0xf8, 0x70, 0xc6, - 0x6f, 0xc6, 0x4f, 0xc6, 0xde, 0x4c, 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, - 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xbe, 0xc7, 0xae, 0xf0, - 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, - 0x9e, 0xeb, 0xba, 0x7c, 0x5f, 0xc5, 0xba, 0x5c, 0x11, 0x26, 0xfd, 0xdf, - 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xb2, 0x7c, - 0xb2, 0x7c, 0x77, 0x8b, 0xbf, 0xc5, 0xa7, 0xf3, 0x9b, 0x6c, 0xdf, 0x7c, - 0x9e, 0x6b, 0x96, 0xb4, 0x9c, 0x1b, 0xf0, 0xdf, 0xb1, 0x8f, 0xac, 0xee, - 0x3f, 0xc6, 0xb5, 0xf3, 0xda, 0x7d, 0x5f, 0xc6, 0xfe, 0x1b, 0xdf, 0xdf, - 0xbf, 0xc7, 0xfc, 0x9b, 0xfa, 0xbf, 0x7a, 0xc6, 0xbf, 0x93, 0xda, 0x5d, - 0xff, 0xdc, 0x9c, 0x1b, 0xf0, 0xdf, 0xda, 0x7b, 0xde, 0x1b, 0xe1, 0xcf, - 0xbe, 0xbc, 0x7b, 0x93, 0xb7, 0xc4, 0xf7, 0xee, 0xb4, 0x93, 0xba, 0x5b, - 0x26, 0xf5, 0x9b, 0x7f, 0x9c, 0x1b, 0xe0, 0xdf, 0xde, 0x1b, 0xe1, 0xcf, - 0x9c, 0x13, 0x9f, 0xff, 0xda, 0x5f, 0x9b, 0x5f, 0x11, 0x26, 0xfd, 0xdf, - 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xfa, 0x7c, - 0xd2, 0xb6, 0x7f, 0xc7, 0xde, 0x1b, 0xfe, 0xdf, 0xbf, 0x93, 0xff, 0xcf, - 0xbd, 0x1b, 0xe0, 0xdf, 0x80, 0xd7, 0x7f, 0x93, 0xda, 0x5c, 0xbb, 0x5c, - 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, 0xfc, 0xeb, 0x9c, 0xeb, - 0x9e, 0xeb, 0x8a, 0xef, 0xbf, 0x6c, 0x5d, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, - 0x7e, 0xc5, 0xbf, 0x4c, 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, - 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xda, 0x7d, 0x7f, 0xc6, 0xda, 0x5d, - 0x41, 0xf8, 0xd3, 0x7c, 0x55, 0xf8, 0xbb, 0x6c, 0xff, 0x7d, 0xff, 0xdd, - 0xbb, 0x4c, 0xb2, 0x7c, 0xd3, 0x7c, 0xff, 0xd5, 0xbe, 0x93, 0x77, 0x8b, - 0xd3, 0x5c, 0xb2, 0x5c, 0x11, 0x26, 0xfd, 0xdf, 0x5e, 0x67, 0x7f, 0x67, - 0xfc, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xff, 0xff, 0x83, 0xfe, 0xff, 0xdf, - 0xff, 0x9f, 0xff, 0xbf, 0xff, 0x8b, 0xbf, 0xc7, 0xf5, 0xf7, 0x97, 0xef, - 0xb9, 0x7c, 0x7e, 0xc5, 0xb9, 0x5c, 0xbf, 0x7c, 0xbd, 0x1b, 0x40, 0xdf, - 0xbf, 0x5c, 0xc3, 0x87, 0x9c, 0xef, 0xb9, 0x7c, 0x5e, 0xc5, 0xb9, 0x5c, - 0xc3, 0x87, 0xff, 0xff, 0x83, 0xfe, 0xff, 0xdf, 0x2e, 0xeb, 0xff, 0xcc, - 0x77, 0xef, 0xb6, 0xef, 0x9f, 0x4d, 0xf1, 0xa3, 0xff, 0xce, 0xfb, 0xcd, - 0x9f, 0x5b, 0x9b, 0x4b, 0x92, 0x5b, 0x00, 0x1c, 0xd6, 0x19, 0x9f, 0x7b, - 0x33, 0x8b, 0x5e, 0xc4, 0x9f, 0x5b, 0x6e, 0xeb, 0x83, 0xfe, 0xff, 0xdf, - 0xff, 0x9f, 0xff, 0xbf, 0x9c, 0xef, 0xff, 0x7c, 0xff, 0x1b, 0xfe, 0xdf, - 0xc3, 0x87, 0xff, 0xff, 0x83, 0xfe, 0xff, 0xdf, 0x2e, 0xeb, 0x70, 0xee, - 0xff, 0xcc, 0xbb, 0x8b, 0x93, 0x5b, 0x9e, 0x5b, 0x9a, 0x7b, 0xd2, 0x5b, - 0x7f, 0xc4, 0x79, 0xc4, 0x9a, 0x5b, 0x9f, 0x7b, 0x33, 0x8b, 0x5f, 0xc4, - 0xbb, 0x7b, 0x9f, 0x5b, 0xbd, 0x1b, 0xe0, 0xdf, 0x9f, 0x7b, 0xfb, 0x4b, - 0xfd, 0x4b, 0xbb, 0x5b, 0x3e, 0xc4, 0xf4, 0xf3, 0x9f, 0x7b, 0x3b, 0xc4, - 0xcc, 0xf7, 0xfa, 0xcf, 0x00, 0x1c, 0x0f, 0x02, 0x9e, 0xee, 0xbd, 0x6c, - 0x4c, 0xc5, 0xbd, 0x4c, 0x9f, 0x7b, 0x3a, 0xc4, 0xd2, 0xf7, 0x80, 0xef, - 0xbf, 0x6c, 0x5c, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x58, 0xc5, 0xbf, 0x4c, - 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, 0x84, 0xef, 0x9f, 0x6c, 0xbe, 0xc4, - 0xd8, 0xf3, 0xf4, 0xcd, 0x86, 0xef, 0xbf, 0x5c, 0x86, 0xef, 0xbf, 0x6c, - 0xbd, 0x1b, 0xe0, 0xcf, 0x5e, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x78, 0xc5, - 0x77, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, - 0x59, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x5a, 0xc5, 0xbf, 0x4c, 0x46, 0xcd, - 0xbe, 0x4c, 0xbd, 0x4c, 0x6e, 0xeb, 0xf8, 0xcf, 0x00, 0x1c, 0x41, 0x02, - 0x31, 0xf8, 0xf0, 0xcf, 0x00, 0x1c, 0x45, 0x02, 0x99, 0xef, 0xbd, 0x6c, - 0x4c, 0xc5, 0xbd, 0x4c, 0x32, 0xf8, 0xfd, 0xcf, 0x00, 0x1c, 0x59, 0x02, - 0x28, 0xf8, 0xff, 0xff, 0x83, 0xfe, 0xff, 0xdf, 0xff, 0x5f, 0xff, 0xbf, - 0xff, 0x9f, 0xff, 0xbf, 0x47, 0xfe, 0xff, 0xdf, 0x78, 0xff, 0xff, 0xdf, - 0xff, 0x4f, 0xff, 0xbf, 0xbf, 0xc6, 0xff, 0x8b, 0xf4, 0xf7, 0xb5, 0xef, - 0xff, 0xcc, 0xdf, 0x7d, 0xfe, 0xd4, 0xbb, 0x8b, 0xfc, 0x3b, 0xff, 0xbe, - 0xfb, 0x97, 0xff, 0x5d, 0xc3, 0x87, 0xba, 0xef, 0xfe, 0xcc, 0xdf, 0x7d, - 0xfc, 0x3b, 0xdf, 0xbf, 0xfb, 0x93, 0xff, 0x8b, 0xff, 0x5d, 0xc3, 0x87, - 0x83, 0xfe, 0xff, 0xdf, 0x2f, 0xeb, 0x91, 0xef, 0xbf, 0x7c, 0x3b, 0xc5, - 0xfa, 0xf7, 0xb2, 0xef, 0xdd, 0x6d, 0x6c, 0xc6, 0xdd, 0x4d, 0x9f, 0x7c, - 0x3e, 0xc4, 0xf2, 0xf3, 0x97, 0xef, 0x9f, 0x7c, 0x3b, 0xc4, 0xfa, 0xf3, - 0xf8, 0xcf, 0x00, 0x1c, 0x86, 0x02, 0x6f, 0xeb, 0xfa, 0xcf, 0x00, 0x1c, - 0x8a, 0x02, 0x6f, 0xeb, 0xff, 0xcf, 0x00, 0x1c, 0x8e, 0x02, 0x6f, 0xeb, - 0x83, 0xfe, 0xff, 0xdf, 0xff, 0x5f, 0xff, 0xbf, 0x9b, 0xef, 0xfe, 0xce, - 0xbe, 0x6c, 0xfe, 0x3b, 0xdf, 0xbf, 0xf7, 0x93, 0xfe, 0x4c, 0xc3, 0x87, - 0xff, 0xaf, 0xff, 0xbf, 0xff, 0xcc, 0xbb, 0xef, 0xfe, 0xd4, 0xde, 0x6d, - 0x3c, 0x8f, 0x3b, 0x97, 0x9e, 0x4d, 0xc3, 0x87, 0xff, 0xaf, 0xff, 0xbf, - 0x98, 0xef, 0xfe, 0xce, 0xbc, 0x6c, 0xfe, 0x3b, 0xdf, 0xbf, 0x7f, 0x93, + 0xc3, 0x87, 0xff, 0xff, 0x81, 0xee, 0xff, 0xcd, 0xb7, 0x5c, 0xdd, 0x6c, + 0xa1, 0xee, 0xb7, 0x97, 0xdd, 0x4c, 0xfe, 0xce, 0xd7, 0x5c, 0xdd, 0x6c, + 0x7b, 0x97, 0x50, 0xc5, 0xbd, 0x4c, 0xc3, 0x87, 0xff, 0x8b, 0xbf, 0xc7, + 0xef, 0xf3, 0x89, 0xee, 0xbf, 0x6c, 0x5c, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, + 0x5d, 0xc5, 0xbf, 0x4c, 0xbd, 0x6c, 0xca, 0xee, 0x7b, 0x97, 0xbd, 0x4c, + 0xbd, 0x6c, 0x6c, 0xc5, 0xbd, 0x4c, 0xf7, 0xfb, 0x91, 0xee, 0xbf, 0x6c, + 0x7c, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x7d, 0xc5, 0xbf, 0x4c, 0xc3, 0x87, + 0x95, 0xee, 0xbf, 0x1b, 0xfc, 0xdf, 0xbb, 0xbd, 0xff, 0x6c, 0x7b, 0xc7, + 0x7a, 0xc7, 0xf7, 0x93, 0xff, 0x4c, 0xc3, 0x87, 0x7f, 0x8b, 0xf8, 0xcc, + 0x73, 0x9b, 0xfd, 0xf7, 0xf8, 0xcf, 0x9c, 0xee, 0xff, 0x1b, 0xf8, 0xdf, + 0xf5, 0xbf, 0xbf, 0x6c, 0xdb, 0xee, 0x7b, 0x97, 0xf7, 0x93, 0xff, 0x4c, + 0xc3, 0x87, 0xff, 0xff, 0x82, 0xef, 0xbf, 0x1b, 0xf0, 0xdf, 0xab, 0xbd, + 0xfd, 0x6c, 0xc1, 0xef, 0xfb, 0x97, 0xf7, 0x93, 0xfd, 0x4c, 0xc3, 0x87, + 0x2f, 0xeb, 0x87, 0xef, 0xff, 0xce, 0xdd, 0x4c, 0xbf, 0x6c, 0x77, 0xc5, + 0x76, 0xc5, 0x57, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0xc8, 0xef, 0x7b, 0x97, + 0xbf, 0x4c, 0xc2, 0xcd, 0xb7, 0x5c, 0xbd, 0x6c, 0xcd, 0xef, 0x7b, 0x97, + 0x50, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0x56, 0xc5, 0xbd, 0x4c, 0xbf, 0x6c, + 0x7e, 0xc5, 0xbf, 0x4c, 0xbd, 0x6c, 0x4c, 0xc5, 0xbd, 0x4c, 0xdc, 0x6c, + 0xde, 0xb6, 0xde, 0x1b, 0xe0, 0xdf, 0x5d, 0xc6, 0xde, 0xbe, 0xbc, 0x6c, + 0xbd, 0x1b, 0xc1, 0xcf, 0x7b, 0x93, 0xbc, 0x4c, 0xfd, 0xcf, 0x00, 0x1c, + 0x32, 0x00, 0xfc, 0xcf, 0x00, 0x1c, 0x4f, 0x00, 0x6f, 0xeb, 0xff, 0xff, + 0xff, 0x5f, 0xff, 0xbf, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x8a, 0xef, 0xfd, 0x6c, + 0xeb, 0xb7, 0xff, 0x1b, 0xf0, 0xdf, 0xc3, 0x87, 0x8d, 0xef, 0xfe, 0x6c, + 0xe9, 0xb7, 0xc3, 0x87, 0x8f, 0xef, 0x99, 0x6c, 0x2f, 0xc4, 0xf2, 0xf7, + 0x90, 0xef, 0xaf, 0xef, 0xbf, 0x4c, 0x8f, 0xef, 0xbd, 0x6c, 0x5e, 0xc5, + 0xbd, 0x4c, 0xbd, 0x6c, 0x5f, 0xc5, 0xbd, 0x4c, 0xfd, 0xcd, 0xbf, 0x4c, + 0xc3, 0x87, 0xff, 0xff, 0x98, 0xef, 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, + 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x93, + 0xbf, 0x6c, 0x7e, 0xc5, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0x5f, 0xff, 0xbf, + 0xff, 0xbb, 0xff, 0xbf, 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, + 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, + 0x2f, 0xeb, 0x83, 0xed, 0x9f, 0x7c, 0x3b, 0xc4, 0xfb, 0xf3, 0xf8, 0xcf, + 0x00, 0x1c, 0x81, 0x00, 0xa7, 0xed, 0x9e, 0x7d, 0xff, 0xdc, 0x33, 0x8b, + 0x9e, 0x5d, 0x3f, 0xc4, 0x9f, 0xf3, 0xbe, 0x6d, 0x3f, 0xce, 0xd6, 0xbe, + 0x7b, 0x97, 0x7f, 0xcc, 0x96, 0xbc, 0x35, 0x9b, 0xcd, 0xf7, 0x8d, 0xed, + 0xbf, 0x6c, 0x76, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x79, 0xc5, 0xbf, 0x4c, + 0xbd, 0x6c, 0x9e, 0x6c, 0x91, 0xed, 0xff, 0xcd, 0xbf, 0x4c, 0x94, 0xed, + 0xbe, 0x6c, 0x70, 0xc5, 0x6f, 0xc5, 0xbe, 0x4c, 0xbf, 0x7c, 0xbd, 0x1b, + 0x01, 0xdf, 0xbf, 0x5c, 0x99, 0x7c, 0x9c, 0x1b, 0xfd, 0xdf, 0x33, 0x8b, + 0xbf, 0xc4, 0xf6, 0xf3, 0x9c, 0xed, 0xbf, 0x7c, 0x77, 0x8b, 0x59, 0xc5, + 0xbf, 0x5c, 0xb9, 0x7c, 0x7e, 0xc5, 0xb9, 0x5c, 0x80, 0xee, 0xfd, 0x6c, + 0x7f, 0xcc, 0x89, 0xbc, 0xf2, 0x9b, 0xf9, 0xf3, 0x00, 0x1c, 0xb3, 0x17, + 0x84, 0xee, 0xff, 0xce, 0xdd, 0x4c, 0xff, 0x1f, 0x9c, 0xfa, 0xe9, 0xfa, + 0x87, 0xee, 0x9a, 0x7c, 0x3f, 0xc4, 0xed, 0xf2, 0xa9, 0xee, 0xbf, 0x7d, + 0x39, 0xc5, 0xf1, 0xf6, 0xcb, 0xee, 0xbf, 0xcd, 0x37, 0x97, 0xbf, 0xc4, + 0xfc, 0x9b, 0xf9, 0xbf, 0x9a, 0x7e, 0x79, 0xc4, 0x3f, 0x93, 0x9a, 0x5e, + 0x37, 0x97, 0x33, 0x8b, 0xbf, 0xc4, 0xf6, 0xf3, 0x90, 0xee, 0xbf, 0x6c, + 0x5d, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x7e, 0xc5, 0xbf, 0x4c, 0x07, 0xfb, + 0x94, 0xee, 0xbf, 0x6c, 0x7d, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x5e, 0xc5, + 0xbf, 0x4c, 0x0f, 0xfb, 0x9a, 0xee, 0x9f, 0x7c, 0x39, 0xc4, 0xdf, 0xf7, + 0xdc, 0xee, 0xbf, 0xcc, 0xfa, 0x7e, 0x9f, 0x3b, 0xdd, 0xdf, 0x77, 0x8b, + 0xbf, 0xc5, 0x7c, 0x9b, 0xb9, 0xbd, 0x79, 0xc7, 0x7f, 0x93, 0xba, 0x5e, + 0x37, 0x97, 0x33, 0x8b, 0xbf, 0xc4, 0xf6, 0xf3, 0x82, 0xef, 0xbf, 0x6c, + 0x5d, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x7e, 0xc5, 0xbf, 0x4c, 0xf7, 0xfb, + 0x86, 0xef, 0xbf, 0x6c, 0x7d, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x5e, 0xc5, + 0xbf, 0x4c, 0x8b, 0xef, 0xff, 0xcd, 0xbe, 0x5c, 0xbe, 0x6c, 0x3f, 0xcc, + 0x96, 0xbc, 0x73, 0x97, 0x7f, 0xcc, 0x97, 0xbc, 0x35, 0x9b, 0xf7, 0xf7, + 0x91, 0xef, 0xbe, 0x6c, 0x70, 0xc5, 0x6f, 0xc5, 0x4f, 0xc5, 0xbe, 0x4c, + 0x44, 0xfb, 0x94, 0xef, 0x9b, 0x7c, 0x9c, 0x1b, 0xe0, 0xcf, 0x33, 0x8b, + 0xbf, 0xc4, 0xdc, 0xf7, 0x98, 0xef, 0xbe, 0x6c, 0xff, 0xdd, 0xbd, 0x1b, + 0xe0, 0xdf, 0xdb, 0x7c, 0xde, 0x1b, 0xe0, 0xcf, 0xb7, 0x93, 0xdb, 0x5c, + 0xd0, 0xc5, 0xf2, 0xf3, 0xf7, 0xfb, 0xff, 0xff, 0x63, 0xfe, 0xff, 0xdf, + 0xff, 0xdf, 0xff, 0xbf, 0xff, 0x9f, 0xff, 0xbf, 0xba, 0x7c, 0x5f, 0xc5, + 0xba, 0x5c, 0x63, 0xfb, 0x86, 0xed, 0xbb, 0x7c, 0xbd, 0x1b, 0xe0, 0xcf, + 0xbd, 0x1b, 0xe0, 0xdf, 0x5a, 0xc5, 0xbb, 0x5c, 0xff, 0xcd, 0xb3, 0x5c, + 0x8b, 0xed, 0x9e, 0x6c, 0x9a, 0xb4, 0x9c, 0x1b, 0xf8, 0xdf, 0xbd, 0xc4, + 0xe6, 0xf3, 0xdd, 0xc4, 0xfb, 0xf3, 0xbe, 0xc4, 0x78, 0xf7, 0xf9, 0xfb, + 0xbc, 0xc4, 0xac, 0xf3, 0xbb, 0xc4, 0x7d, 0xf7, 0x9e, 0xfb, 0x93, 0xed, + 0xba, 0x7c, 0xbd, 0x1b, 0x01, 0xdf, 0xbd, 0x1b, 0xe1, 0xcf, 0x5a, 0xc5, + 0xba, 0x5c, 0xbb, 0x7c, 0xbd, 0x1b, 0xe0, 0xdf, 0x59, 0xc5, 0xbb, 0x5c, + 0x8c, 0xfb, 0x9a, 0xed, 0xb2, 0x7c, 0x92, 0x7c, 0x33, 0x8b, 0xbf, 0xc4, + 0xfa, 0xf3, 0x9d, 0xed, 0x9b, 0x6c, 0xdf, 0x7c, 0xfc, 0xfb, 0x9f, 0xed, + 0xd3, 0x7c, 0xa0, 0xee, 0x9e, 0x6d, 0x96, 0xb4, 0x9c, 0x1b, 0xf0, 0xdf, + 0x9e, 0x3b, 0x7c, 0xbf, 0x3f, 0xc4, 0xef, 0xf3, 0x34, 0x93, 0xba, 0x7d, + 0xfe, 0xce, 0x7b, 0x93, 0xfd, 0x1b, 0xdf, 0xdf, 0xff, 0x8b, 0xbf, 0xc7, + 0xfc, 0x9b, 0xbf, 0x97, 0xda, 0xbe, 0x7a, 0xc5, 0x7b, 0x93, 0xba, 0x5c, + 0xfa, 0xfb, 0x8c, 0xee, 0xba, 0x7c, 0x7f, 0xc5, 0xba, 0x5c, 0x8e, 0xee, + 0xbe, 0x6c, 0xb6, 0xb5, 0xff, 0xdd, 0xbd, 0x1b, 0xf0, 0xdf, 0xfe, 0xbd, + 0xda, 0x7c, 0xde, 0x1b, 0xe1, 0xcf, 0xbf, 0x93, 0xda, 0x5c, 0xb7, 0xc5, + 0xc2, 0xf7, 0xba, 0x7c, 0xbd, 0x1b, 0xe1, 0xcf, 0xba, 0x5c, 0xbb, 0x7c, + 0xbd, 0x1b, 0xe0, 0xdf, 0xbd, 0x13, 0x9f, 0xff, 0xbb, 0x5c, 0xcd, 0xfb, + 0x9b, 0xee, 0xde, 0x6c, 0xd2, 0xb6, 0xde, 0x1b, 0xfe, 0xdf, 0xba, 0x7c, + 0x7f, 0xc5, 0x7b, 0x93, 0xba, 0x5c, 0xbb, 0x7c, 0xbd, 0x1b, 0xe0, 0xdf, + 0xff, 0xce, 0x80, 0xd6, 0x7b, 0x93, 0xbb, 0x5c, 0xde, 0xfb, 0x83, 0xef, + 0xba, 0x7c, 0x5f, 0xc5, 0xba, 0x5c, 0xbb, 0x7c, 0xbd, 0x1b, 0xe0, 0xdf, + 0x5a, 0xc5, 0xbb, 0x5c, 0x92, 0x7c, 0x33, 0x8b, 0xbf, 0xc4, 0xf1, 0xf3, + 0x8a, 0xef, 0xbb, 0x6c, 0xff, 0x7d, 0xd3, 0x7c, 0xbe, 0x93, 0xd3, 0x5c, + 0xff, 0xdd, 0xbb, 0x4c, 0xb2, 0x7c, 0xff, 0xd5, 0x77, 0x8b, 0xb2, 0x5c, + 0xf8, 0xfb, 0x90, 0xef, 0xbe, 0x6c, 0x70, 0xc5, 0x6f, 0xc5, 0x50, 0xc5, + 0xbe, 0x4c, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, + 0xff, 0x8b, 0xbf, 0xc7, 0xf9, 0xf3, 0x97, 0xef, 0xb9, 0x7c, 0x5e, 0xc5, + 0xb9, 0x5c, 0xf6, 0xfb, 0x9a, 0xef, 0xb9, 0x7c, 0x7e, 0xc5, 0xb9, 0x5c, + 0xbf, 0x7c, 0xbd, 0x1b, 0x40, 0xdf, 0xbf, 0x5c, 0xc3, 0x87, 0xff, 0xff, + 0x63, 0xfe, 0xff, 0xdf, 0x2e, 0xeb, 0xff, 0xcc, 0xb0, 0xed, 0x9f, 0x4d, + 0x70, 0xed, 0x9f, 0x5b, 0x9b, 0x4b, 0x92, 0x5b, 0xf1, 0xa3, 0xff, 0xce, + 0xfb, 0xcd, 0x00, 0x1c, 0xe0, 0x18, 0x9f, 0x7b, 0x33, 0x8b, 0x5e, 0xc4, + 0x9f, 0x5b, 0x6e, 0xeb, 0x97, 0xed, 0xff, 0x7c, 0xff, 0x1b, 0xfe, 0xdf, + 0xc3, 0x87, 0xff, 0xff, 0x2f, 0xeb, 0xbb, 0x8b, 0x9b, 0xed, 0xfb, 0x4c, + 0xfd, 0x4c, 0xd2, 0x5c, 0xff, 0xcd, 0xb3, 0x5c, 0xbe, 0x5c, 0xba, 0x7c, + 0xdb, 0x7c, 0xde, 0x1b, 0xe0, 0xdf, 0xdb, 0x5c, 0x7f, 0xc5, 0x79, 0xc5, + 0xba, 0x5c, 0xbf, 0x7c, 0x77, 0x8b, 0x5f, 0xc5, 0xbf, 0x5c, 0x9f, 0x7c, + 0x3e, 0xc4, 0xef, 0xf3, 0x86, 0xee, 0x9f, 0x7c, 0x3b, 0xc4, 0xfa, 0xf3, + 0xf8, 0xcf, 0x00, 0x1c, 0x26, 0x02, 0xfb, 0xfb, 0xfa, 0xcf, 0x00, 0x1c, + 0x2a, 0x02, 0x8a, 0xee, 0xbd, 0x6c, 0x4c, 0xc5, 0xbd, 0x4c, 0x8d, 0xee, + 0x9f, 0x7c, 0x3a, 0xc4, 0xf7, 0xf3, 0xf0, 0xcf, 0x00, 0x1c, 0x35, 0x02, + 0x90, 0xee, 0xbd, 0x6c, 0x4c, 0xc5, 0xbd, 0x4c, 0x94, 0xee, 0xbf, 0x6c, + 0x5c, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x58, 0xc5, 0xbf, 0x4c, 0xdf, 0x6c, + 0xfd, 0xcd, 0xb7, 0x93, 0xdf, 0x4c, 0x96, 0xee, 0xdf, 0x6c, 0xde, 0x1b, + 0xe0, 0xcf, 0x7b, 0x93, 0xbf, 0x4c, 0xbf, 0x6c, 0x78, 0xc5, 0x77, 0xc5, + 0xbf, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x59, 0xc5, + 0xbf, 0x4c, 0xbf, 0x6c, 0x5a, 0xc5, 0xbf, 0x4c, 0x46, 0xcd, 0xbe, 0x4c, + 0xbd, 0x4c, 0x6f, 0xeb, 0xff, 0x8b, 0xbf, 0xc6, 0xf5, 0xf3, 0xa5, 0xef, + 0xdf, 0x7d, 0xfe, 0xcc, 0xfc, 0x3b, 0xdf, 0xbf, 0xfb, 0x93, 0xff, 0x8b, + 0xff, 0x5d, 0xf5, 0xfb, 0xaa, 0xef, 0xdf, 0x7d, 0xbb, 0x8b, 0xff, 0xcc, + 0xfe, 0xd4, 0xfc, 0x3b, 0xff, 0xbe, 0xfb, 0x97, 0xff, 0x5d, 0xc3, 0x87, + 0x2f, 0xeb, 0x8f, 0xef, 0x9f, 0x7c, 0x3b, 0xc4, 0xfa, 0xf7, 0x90, 0xef, + 0xbd, 0x6c, 0x6c, 0xc5, 0xbd, 0x4c, 0x93, 0xef, 0x9f, 0x7c, 0x3e, 0xc4, + 0xf2, 0xf3, 0x95, 0xef, 0x9f, 0x7c, 0x3b, 0xc4, 0xfa, 0xf3, 0xf8, 0xcf, + 0x00, 0x1c, 0x85, 0x02, 0xf7, 0xfb, 0xfa, 0xcf, 0x00, 0x1c, 0x89, 0x02, + 0xfb, 0xfb, 0xff, 0xcf, 0x00, 0x1c, 0x8d, 0x02, 0x6f, 0xeb, 0xff, 0xff, + 0xff, 0x9f, 0xff, 0xbf, 0x63, 0xfe, 0xff, 0xdf, 0xff, 0x5f, 0xff, 0xbf, + 0xff, 0xdf, 0xff, 0xbf, 0x9b, 0xef, 0xbe, 0x6c, 0xfe, 0xce, 0xfe, 0x3b, + 0xdf, 0xbf, 0xf7, 0x93, 0xfe, 0x4c, 0xc3, 0x87, 0xff, 0xaf, 0xff, 0xbf, + 0x88, 0xee, 0x9e, 0x6c, 0xfc, 0x3b, 0xbf, 0xbf, 0xff, 0x1b, 0xfe, 0xdf, + 0xc3, 0x87, 0xff, 0xff, 0xac, 0xee, 0xde, 0x6d, 0xff, 0xcc, 0xfe, 0xd4, + 0x3c, 0x8f, 0x3b, 0x97, 0x9e, 0x4d, 0xc3, 0x87, 0x2f, 0xeb, 0x90, 0xee, + 0x9e, 0x6c, 0xfe, 0xcd, 0x7f, 0x8f, 0x35, 0x97, 0xfb, 0xf3, 0x00, 0x1c, + 0x0e, 0x00, 0xfc, 0xfb, 0x00, 0x1c, 0x23, 0x00, 0x6f, 0xeb, 0xff, 0xff, + 0x97, 0xee, 0xbc, 0x6c, 0xfe, 0xce, 0xfe, 0x3b, 0xdf, 0xbf, 0x7f, 0x93, 0xbc, 0x4c, 0xb8, 0x6c, 0x7f, 0x93, 0xb8, 0x4c, 0xba, 0x6c, 0xf7, 0x93, - 0xfa, 0x4c, 0xc3, 0x87, 0xff, 0xaf, 0xff, 0xbf, 0x9b, 0xef, 0xfe, 0xce, - 0xbd, 0x6c, 0xfe, 0x3b, 0xdf, 0xbf, 0xf7, 0x93, 0xfd, 0x4c, 0xc3, 0x87, - 0xff, 0xaf, 0xff, 0xbf, 0x2e, 0xeb, 0x70, 0xef, 0x9d, 0x6b, 0x5e, 0xc4, - 0x9d, 0x4b, 0x9e, 0x6b, 0x5e, 0xc4, 0x9e, 0x4b, 0x9d, 0x6b, 0x5c, 0xc4, - 0x9d, 0x4b, 0x9e, 0x6b, 0x7c, 0xc4, 0x9e, 0x4b, 0x9d, 0x6b, 0x5b, 0xc4, - 0x9d, 0x4b, 0x9e, 0x6b, 0x7b, 0xc4, 0x9e, 0x4b, 0xff, 0xcf, 0x00, 0x1c, - 0x2e, 0x00, 0xff, 0xcd, 0x9b, 0xef, 0xbf, 0x5c, 0x9f, 0x6b, 0x3f, 0xc4, - 0x01, 0xf4, 0x6e, 0xeb, 0xff, 0xaf, 0xff, 0xbf, 0x6f, 0xfe, 0xff, 0xdf, - 0xfe, 0xcd, 0x9a, 0xef, 0x9f, 0x6c, 0xfd, 0x3b, 0xdf, 0xbf, 0xf3, 0x97, - 0xbf, 0xc7, 0xff, 0x3b, 0xff, 0xfa, 0xc3, 0x87, 0xff, 0xaf, 0xff, 0xbf, - 0x9f, 0xeb, 0x9d, 0xeb, 0x2e, 0xeb, 0x66, 0xee, 0x9f, 0x7b, 0xbf, 0xc4, - 0xdc, 0xf7, 0x9e, 0x7b, 0xff, 0xdc, 0x33, 0x8b, 0xfd, 0xcd, 0x37, 0x9b, - 0x9e, 0x5b, 0xc4, 0xf3, 0xfd, 0xcc, 0xff, 0xcf, 0x9f, 0x5b, 0xfd, 0x4b, - 0xfe, 0xcc, 0xed, 0xee, 0x9d, 0x53, 0x00, 0x1c, 0x98, 0x05, 0xfc, 0xcd, - 0x8f, 0xee, 0xbf, 0x5c, 0x00, 0x1c, 0x95, 0x00, 0x90, 0xee, 0xff, 0xcd, - 0xbf, 0x4c, 0x90, 0xee, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0x11, 0x26, - 0xfe, 0xdf, 0x7f, 0x67, 0xfd, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x3f, 0xcf, - 0xbb, 0x6b, 0x3f, 0xcc, 0xf6, 0xbf, 0x96, 0xbc, 0xfd, 0x3b, 0xde, 0xdf, - 0x39, 0x9b, 0xdb, 0xf3, 0x9b, 0xee, 0xff, 0xcd, 0xbf, 0x4c, 0x9b, 0xee, - 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0x9d, 0x6b, 0xfd, 0xcd, 0xbe, 0x5c, - 0xf1, 0xa3, 0x00, 0x1c, 0xc0, 0x05, 0xfa, 0xcd, 0x83, 0xef, 0xbf, 0x5c, - 0x11, 0x26, 0xfe, 0xdf, 0x7f, 0x67, 0xfd, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, - 0xfc, 0xcf, 0x00, 0x1c, 0x9a, 0x00, 0xfb, 0xcf, 0x00, 0x1c, 0x9d, 0x00, - 0xfb, 0xcf, 0x00, 0x1c, 0xa6, 0x06, 0xfe, 0xcd, 0x89, 0xef, 0xbf, 0x5c, - 0x45, 0xf8, 0x8b, 0xef, 0xdf, 0x6c, 0x70, 0xc5, 0x6f, 0xc5, 0x5c, 0xc6, - 0xdf, 0x4c, 0xbb, 0x4b, 0x90, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xbf, 0x6c, - 0xbd, 0x13, 0x9d, 0xff, 0xff, 0x15, 0x77, 0x6f, 0xbf, 0x4c, 0xfe, 0x4c, - 0xfd, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, 0xbf, 0x4c, 0xfb, 0xcd, 0x98, 0xef, - 0xbf, 0x5c, 0x11, 0x26, 0xfe, 0xdf, 0x7f, 0x67, 0xfd, 0xeb, 0x9c, 0xeb, - 0x9e, 0xeb, 0xff, 0xff, 0x6b, 0xfe, 0xff, 0xdf, 0x67, 0xfe, 0xff, 0xdf, - 0x78, 0xff, 0xff, 0xdf, 0xff, 0xef, 0xff, 0xbf, 0xff, 0x8f, 0xff, 0xbf, - 0x0f, 0xff, 0xff, 0xdf, 0x9f, 0xeb, 0x9d, 0xeb, 0x2b, 0xeb, 0x7e, 0xec, - 0x9f, 0x7b, 0xbf, 0xc4, 0xd4, 0xf3, 0x3f, 0xcc, 0x96, 0xbc, 0xdb, 0x6b, - 0x9e, 0x3b, 0xdd, 0xdf, 0x7f, 0xcc, 0x96, 0xbc, 0x35, 0x9b, 0x86, 0xf3, - 0xbf, 0xc5, 0xf1, 0xf3, 0x7f, 0xcc, 0x97, 0xbc, 0x35, 0x9b, 0xc4, 0xf3, - 0x11, 0x26, 0xfb, 0xdf, 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, 0x7f, 0x67, - 0xfa, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x8b, 0xed, 0x9e, 0x6c, 0x8d, 0xbc, - 0x70, 0xc6, 0x6f, 0xc6, 0x8d, 0xb4, 0x50, 0xc6, 0x95, 0x53, 0xdb, 0x4b, - 0x11, 0x26, 0xfb, 0xdf, 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, 0x7f, 0x67, - 0xfa, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xb3, 0xed, 0xff, 0xce, 0xdf, 0x4d, - 0xb6, 0xed, 0xdf, 0x6d, 0x7c, 0xc6, 0xdf, 0x4d, 0x9e, 0x5b, 0xfd, 0xcc, - 0x9f, 0x5b, 0xff, 0xcd, 0xfe, 0xcc, 0xf1, 0xa3, 0x9d, 0x53, 0xbd, 0x4b, - 0x00, 0x1c, 0x43, 0x06, 0xf9, 0xcd, 0x9b, 0xed, 0xbf, 0x5c, 0x00, 0x1c, - 0x40, 0x01, 0x11, 0x26, 0xfb, 0xdf, 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, - 0x7f, 0x67, 0xfa, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x84, 0xee, 0xde, 0x6c, - 0xcd, 0xbe, 0xb5, 0x73, 0xcd, 0xb6, 0x76, 0x8b, 0xb7, 0x9b, 0xd7, 0xf7, - 0xbe, 0x6c, 0xad, 0xbd, 0x95, 0x73, 0xad, 0xb5, 0x32, 0x8b, 0x92, 0xa5, - 0xdb, 0xc4, 0x3c, 0x9b, 0xbf, 0xc4, 0x4a, 0xf0, 0x9b, 0x6b, 0x70, 0xc4, - 0x6f, 0xc4, 0x4f, 0xc4, 0x9b, 0x4b, 0xff, 0xcd, 0x8f, 0xee, 0xbf, 0x4c, - 0xbf, 0x4c, 0xbf, 0x6c, 0xbd, 0x13, 0x9d, 0xff, 0xfe, 0x15, 0x8b, 0xf1, - 0xbf, 0x4c, 0xde, 0x4c, 0xdd, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, 0xbf, 0x4c, - 0x11, 0x26, 0xfb, 0xdf, 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, 0x7f, 0x67, - 0xfa, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xb5, 0x73, 0x9e, 0x6c, 0x8d, 0xbc, - 0x76, 0x8b, 0x8d, 0xb4, 0x92, 0xa5, 0xdb, 0xc4, 0x3c, 0x9b, 0x26, 0xf8, - 0x9f, 0xee, 0xfe, 0x15, 0x8b, 0xf1, 0xde, 0x4c, 0x82, 0xef, 0xde, 0x6c, - 0xcd, 0xbe, 0xb5, 0x73, 0xcd, 0xb6, 0x76, 0x8b, 0xb7, 0x9b, 0xa9, 0xf3, - 0xb5, 0x73, 0x9e, 0x6c, 0x8d, 0xbc, 0x8d, 0xb4, 0xb2, 0xa5, 0x77, 0x8b, - 0xfb, 0xcc, 0x73, 0x9b, 0xab, 0xf7, 0x93, 0x7b, 0x5f, 0xc4, 0x93, 0x5b, - 0xfe, 0xcc, 0xb3, 0x7b, 0xde, 0xb5, 0xde, 0x1b, 0xfe, 0xdf, 0x39, 0x9b, - 0x50, 0xef, 0xa9, 0xf3, 0xff, 0xcc, 0xbc, 0xb5, 0x89, 0x5a, 0xbd, 0x1b, - 0xf0, 0xdf, 0x93, 0x7b, 0xdc, 0x1b, 0xfb, 0xdf, 0xbb, 0x8b, 0xbf, 0xc6, - 0x56, 0xef, 0xbd, 0xf7, 0xde, 0xc5, 0x26, 0xf7, 0xda, 0xc5, 0xa2, 0xf3, - 0x5d, 0xc4, 0xaf, 0x7a, 0x93, 0x5a, 0xbd, 0x1b, 0xfc, 0xdf, 0x93, 0x7b, - 0x9c, 0x1b, 0x87, 0xcf, 0x93, 0x5b, 0x9c, 0x1b, 0xfe, 0xdf, 0xf6, 0xfb, - 0x6b, 0xfe, 0xff, 0xdf, 0xff, 0x8f, 0xff, 0xbf, 0xff, 0xef, 0xff, 0xbf, - 0x78, 0xff, 0xff, 0xdf, 0xd3, 0x7b, 0x9e, 0xbc, 0x7e, 0xc6, 0x3b, 0x93, - 0x93, 0x5b, 0xde, 0xc5, 0xbb, 0xf0, 0xcf, 0x7b, 0x9e, 0x1b, 0xf3, 0xdf, - 0xbb, 0xc4, 0xfe, 0xec, 0xa9, 0xf3, 0xb7, 0xc4, 0x86, 0xf3, 0x8f, 0x7b, - 0x7f, 0xc4, 0x7e, 0xc4, 0x5e, 0xc4, 0x8f, 0x5b, 0x11, 0x26, 0xfb, 0xdf, - 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, 0x7f, 0x67, 0xfa, 0xeb, 0x9c, 0xeb, - 0x9e, 0xeb, 0xbe, 0x6c, 0xad, 0xbd, 0xad, 0xb5, 0x95, 0x73, 0xb2, 0xa5, - 0x77, 0x8b, 0x54, 0xf8, 0x93, 0x7b, 0x7f, 0xc4, 0x93, 0x5b, 0xff, 0xcc, - 0x52, 0xf8, 0xde, 0xc5, 0x71, 0xf7, 0xda, 0xc5, 0xdd, 0xf7, 0xaf, 0x7a, - 0xbd, 0x1b, 0xfc, 0xdf, 0x3e, 0xf8, 0xfc, 0xb5, 0xff, 0xdf, 0xc9, 0x7a, - 0xff, 0x1b, 0xf0, 0xdf, 0x3c, 0xbf, 0xff, 0xde, 0xbd, 0x1b, 0x87, 0xcf, - 0x67, 0x93, 0xbb, 0x8b, 0xdf, 0xc9, 0xa7, 0x9b, 0xc9, 0x5a, 0x34, 0x92, - 0xb3, 0x5a, 0x9f, 0xf3, 0xd3, 0xc7, 0xeb, 0xf3, 0xaf, 0x7a, 0xbd, 0x1b, - 0xfc, 0xdf, 0x46, 0xf8, 0x8f, 0x7a, 0x7f, 0xc4, 0x7e, 0xc4, 0x8f, 0x5a, - 0xff, 0xcd, 0x5b, 0xf8, 0xaf, 0x7a, 0x7f, 0xc5, 0x7e, 0xc5, 0x5f, 0xc5, - 0x7d, 0xc4, 0xaf, 0x5a, 0x93, 0x5a, 0xfe, 0xcd, 0x64, 0xf8, 0x9d, 0x1b, - 0xfb, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0xa8, 0xf7, 0x98, 0x1b, 0x87, 0xcf, - 0x59, 0xc4, 0x93, 0x5a, 0xf7, 0xcd, 0x7f, 0xf8, 0x99, 0x6f, 0xbf, 0x7c, - 0x77, 0x8b, 0xde, 0x1b, 0xfc, 0xdf, 0xbe, 0xb5, 0xbe, 0xc6, 0xbf, 0x5c, - 0x7a, 0xf3, 0xaf, 0x7b, 0x9b, 0xb5, 0xff, 0xdc, 0x9c, 0x1b, 0xf0, 0xdf, - 0xdb, 0xbc, 0xbd, 0x1b, 0xf0, 0xdf, 0x7b, 0x93, 0xb7, 0xc4, 0xf3, 0xee, - 0xaf, 0x5b, 0x67, 0xf4, 0x94, 0xee, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, - 0xff, 0xcd, 0x95, 0xee, 0xbf, 0x4c, 0x9d, 0x6f, 0xbe, 0x5c, 0xfe, 0xcd, - 0xbd, 0x5c, 0xfc, 0xdf, 0x00, 0x1c, 0x53, 0x07, 0x76, 0xf8, 0x8e, 0x7f, - 0x5c, 0x1b, 0x83, 0xdf, 0xbf, 0xc2, 0x94, 0xf3, 0x5c, 0x1b, 0xfc, 0xdf, - 0xbd, 0xc2, 0x8b, 0xf3, 0xbc, 0xc2, 0x66, 0xf3, 0xbe, 0xc2, 0x87, 0xf3, - 0xde, 0x1b, 0xfc, 0xdf, 0xbf, 0xc6, 0xbd, 0xf7, 0x7f, 0xc4, 0x7e, 0xc4, - 0x5f, 0xc4, 0x8e, 0x5f, 0x93, 0x7f, 0x9c, 0x1b, 0x80, 0xdf, 0x93, 0x5f, - 0x90, 0xf8, 0x88, 0xef, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0x89, 0xef, - 0xff, 0xcd, 0xbf, 0x4c, 0x9d, 0x6a, 0xfd, 0xcd, 0xbe, 0x5c, 0xf1, 0xa2, - 0x00, 0x1c, 0x7b, 0x07, 0xaf, 0x7a, 0xbd, 0x1b, 0xfc, 0xdf, 0xab, 0xf8, - 0x98, 0x1b, 0x87, 0xcf, 0x5a, 0xc4, 0x93, 0x5a, 0xfb, 0xcd, 0xd5, 0xf8, - 0x94, 0xef, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0x95, 0xef, 0xff, 0xcd, - 0xbf, 0x4c, 0x9d, 0x6a, 0xfe, 0xcd, 0x16, 0xf8, 0x99, 0xef, 0xbf, 0x6c, - 0x7c, 0xc5, 0xbf, 0x4c, 0x9a, 0xef, 0xdf, 0x4c, 0x9d, 0x6a, 0xfe, 0xcd, - 0x1f, 0xf8, 0xff, 0xff, 0x6b, 0xfe, 0xff, 0xdf, 0xff, 0x8f, 0xff, 0xbf, - 0xff, 0xef, 0xff, 0xbf, 0xb9, 0x6c, 0xbf, 0x7d, 0x83, 0x7c, 0x77, 0x8b, - 0x33, 0x8b, 0x35, 0x9b, 0x84, 0xf3, 0x9e, 0xec, 0xbf, 0x6c, 0x7c, 0xc5, - 0xbf, 0x4c, 0xff, 0xce, 0x80, 0xed, 0xdf, 0x4c, 0x9d, 0x6b, 0xfe, 0xcd, - 0xbe, 0x5c, 0xe1, 0xed, 0x00, 0x1c, 0xb3, 0x07, 0x11, 0x26, 0xfb, 0xdf, - 0x1c, 0x67, 0x3d, 0x67, 0x5e, 0x67, 0x7f, 0x67, 0xfa, 0xeb, 0x9c, 0xeb, - 0x9e, 0xeb, 0xff, 0xce, 0xbf, 0x7c, 0x80, 0xd6, 0x7b, 0x93, 0x77, 0x8b, - 0xbf, 0x5c, 0x89, 0xf8, 0x8d, 0xed, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, - 0x8e, 0xed, 0xff, 0xcd, 0xbf, 0x4c, 0x9d, 0x6f, 0x5e, 0x5c, 0xfc, 0xdf, - 0x00, 0x1c, 0xcf, 0x07, 0xf2, 0xf8, 0xd3, 0x7f, 0xd8, 0xb6, 0x79, 0x9b, - 0x2c, 0xf4, 0x9c, 0x13, 0xfc, 0xff, 0x8e, 0x5f, 0xfa, 0xf8, 0x99, 0x6f, - 0xbf, 0x7c, 0x77, 0x8b, 0xde, 0x1b, 0xfc, 0xdf, 0xbe, 0xb5, 0xbe, 0xc6, - 0xbf, 0x5c, 0x98, 0xf3, 0xef, 0x7b, 0xdb, 0xb7, 0xff, 0xde, 0xde, 0x1b, - 0xf0, 0xdf, 0xbb, 0xbe, 0xff, 0x1b, 0xf0, 0xdf, 0x7f, 0x93, 0xb7, 0xc6, - 0x9e, 0xed, 0xaf, 0x5b, 0x10, 0xf5, 0xbd, 0x1b, 0xf0, 0xdf, 0xaf, 0x5c, - 0xae, 0x7c, 0x7f, 0xc5, 0x7e, 0xc5, 0x5e, 0xc5, 0xae, 0x5c, 0x19, 0xf9, - 0xde, 0x1b, 0xfc, 0xdf, 0xbe, 0xc6, 0x53, 0xf4, 0x8d, 0x7f, 0xbc, 0x1b, - 0xfd, 0xdf, 0x77, 0x8b, 0xbf, 0xc5, 0xe5, 0xf7, 0x5e, 0xc4, 0x8d, 0x5f, - 0x99, 0x6f, 0x9f, 0x7c, 0x33, 0x8b, 0xe0, 0xcd, 0x37, 0x9b, 0xaf, 0xf7, - 0x81, 0xcd, 0x37, 0x9b, 0xb0, 0xf3, 0xe0, 0xd4, 0x9b, 0xac, 0xfc, 0xdc, - 0x33, 0x8b, 0xae, 0x7b, 0x9c, 0x1b, 0xe0, 0xdf, 0xdd, 0xbc, 0xbd, 0x1b, - 0x83, 0xcf, 0x7b, 0x93, 0xae, 0x5b, 0xbd, 0x6b, 0x9d, 0x5d, 0xae, 0x7b, - 0xbd, 0x1b, 0x83, 0xdf, 0xbb, 0xc5, 0x97, 0xee, 0x7f, 0xf0, 0x99, 0x6b, - 0xbf, 0x7c, 0xc3, 0x7b, 0xff, 0xdc, 0x7a, 0x93, 0x99, 0x4b, 0x8e, 0x7b, - 0x77, 0x8b, 0x7f, 0xc4, 0x7e, 0xc4, 0xa3, 0x5b, 0x70, 0x93, 0x9d, 0xb4, - 0xe1, 0xdc, 0x9c, 0x1b, 0xe0, 0xdf, 0x9d, 0xbc, 0xbd, 0x1b, 0x83, 0xcf, - 0x37, 0x93, 0x8e, 0x5b, 0x9c, 0x1b, 0x83, 0xdf, 0xbf, 0xc4, 0xe4, 0xef, - 0x5c, 0xf5, 0xa8, 0xef, 0xdf, 0x6d, 0x7c, 0xc6, 0xdf, 0x4d, 0xa9, 0xef, - 0xff, 0xce, 0xdf, 0x4d, 0xbd, 0x6f, 0x9e, 0x5d, 0xfc, 0xdf, 0x00, 0x1c, - 0x46, 0x08, 0x69, 0xf9, 0xff, 0xce, 0xbf, 0x7c, 0x80, 0xd6, 0x7b, 0x93, - 0x77, 0x8b, 0xbf, 0x5c, 0x93, 0x7f, 0xb8, 0xb4, 0xbd, 0x1b, 0xfe, 0xdf, - 0x75, 0x93, 0xb8, 0xbd, 0x9c, 0x1b, 0x80, 0xdf, 0x37, 0x93, 0x93, 0x5f, - 0x75, 0xf8, 0xfc, 0xcc, 0x48, 0xf8, 0x21, 0xcd, 0x37, 0x9b, 0xf9, 0xf3, - 0x80, 0xd4, 0x9c, 0xac, 0xf6, 0xdc, 0x33, 0x8b, 0x50, 0xf8, 0x20, 0xd4, - 0x9d, 0xac, 0xe0, 0xdc, 0x33, 0x8b, 0x55, 0xf8, 0xff, 0x8f, 0xff, 0xbf, - 0xff, 0xef, 0xff, 0xbf, 0x67, 0xfe, 0xff, 0xdf, 0x6b, 0xfe, 0xff, 0xdf, - 0xe8, 0xef, 0xff, 0xcc, 0x9f, 0x4f, 0x9f, 0x6f, 0x9c, 0x13, 0xfc, 0xff, - 0x9f, 0x4f, 0x9f, 0x6f, 0x5d, 0xc4, 0x9f, 0x4f, 0x9b, 0xce, 0x9e, 0x6f, - 0x3b, 0x9b, 0xae, 0xef, 0x02, 0xf4, 0x9f, 0x6d, 0x7c, 0xc4, 0x9f, 0x4d, - 0x90, 0xef, 0xff, 0xcd, 0xbe, 0x5c, 0xa2, 0x5c, 0xff, 0xcd, 0xb5, 0x54, - 0xb3, 0x7c, 0xbd, 0x1b, 0x87, 0xdf, 0xbd, 0x1b, 0x87, 0xcf, 0xb3, 0x5c, - 0xae, 0x7c, 0xbd, 0x1b, 0x03, 0xdf, 0xbd, 0x1b, 0x83, 0xcf, 0xae, 0x5c, - 0xff, 0xcd, 0xaf, 0x5c, 0xbb, 0x6c, 0x70, 0xc5, 0x6f, 0xc5, 0xbb, 0x4c, - 0xaf, 0xb5, 0x7e, 0xc5, 0xad, 0x5c, 0xc3, 0x87, 0xff, 0x8f, 0xff, 0xbf, - 0x6b, 0xfe, 0xff, 0xdf, 0x2f, 0xeb, 0xad, 0xef, 0xff, 0xcc, 0x9f, 0x5d, - 0xff, 0xce, 0x8e, 0xef, 0xdf, 0x4c, 0xdf, 0x6c, 0xdf, 0x4c, 0xdf, 0x6c, + 0xfa, 0x4c, 0xc3, 0x87, 0x9e, 0xee, 0xbc, 0x6c, 0xfe, 0xce, 0xfe, 0x3b, + 0xdf, 0xbf, 0xf7, 0x93, 0xfc, 0x4c, 0xc3, 0x87, 0x82, 0xef, 0xdf, 0x6c, + 0xff, 0xcd, 0xfe, 0xd5, 0x7c, 0x8f, 0xb7, 0x97, 0xdf, 0x4c, 0xdc, 0x6c, + 0x7b, 0x97, 0xbc, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0x88, 0xef, 0xbd, 0x6c, + 0xfe, 0xce, 0xfe, 0x3b, 0xdf, 0xbf, 0xf7, 0x93, 0xfd, 0x4c, 0xc3, 0x87, + 0x8c, 0xef, 0x9f, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, 0xf3, 0x97, + 0xbf, 0xc7, 0xff, 0x3b, 0xff, 0xfa, 0xc3, 0x87, 0x2f, 0xeb, 0xfe, 0xcf, + 0x00, 0x1c, 0x13, 0x00, 0xfe, 0xcf, 0x00, 0x1c, 0x60, 0x00, 0xfc, 0xcf, + 0x00, 0x1c, 0x19, 0x00, 0xfc, 0xcf, 0x00, 0x1c, 0x54, 0x00, 0xfb, 0xcf, + 0x00, 0x1c, 0x1f, 0x00, 0xfb, 0xcf, 0x00, 0x1c, 0x5a, 0x00, 0xff, 0xcf, + 0x00, 0x1c, 0x47, 0x00, 0xff, 0xcf, 0x00, 0x1c, 0x20, 0x00, 0xbf, 0xc7, + 0x03, 0xf4, 0x6f, 0xeb, 0xff, 0xaf, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, + 0x2f, 0xeb, 0x8d, 0xee, 0x9f, 0x7c, 0xbf, 0xc4, 0xd9, 0xf7, 0xaf, 0xee, + 0x9e, 0x7d, 0xff, 0xdc, 0x33, 0x8b, 0x9e, 0x5d, 0xfd, 0xcd, 0x37, 0x9b, + 0xf5, 0xf7, 0xfc, 0xcf, 0x00, 0x1c, 0x77, 0x00, 0xfb, 0xcf, 0x00, 0x1c, + 0x7a, 0x00, 0xfb, 0xcf, 0x00, 0x1c, 0x69, 0x06, 0xf8, 0xee, 0xfd, 0xcc, + 0x9f, 0x5f, 0xfe, 0xcc, 0x9d, 0x57, 0xff, 0xcd, 0xbd, 0x4f, 0xfc, 0xdf, + 0x00, 0x1c, 0xad, 0x05, 0x00, 0x1c, 0xc1, 0x00, 0x9d, 0xee, 0xff, 0xcd, + 0xbf, 0x4c, 0x9d, 0xee, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0xca, 0xfb, + 0x82, 0xef, 0xbb, 0x6c, 0x3f, 0xcc, 0x96, 0xbc, 0x73, 0x97, 0x35, 0x9b, + 0xdf, 0xf7, 0x83, 0xef, 0xbf, 0x6c, 0x5c, 0xc5, 0xbf, 0x4c, 0x87, 0xef, + 0xbb, 0x6c, 0x70, 0xc5, 0x6f, 0xc5, 0xbb, 0x4c, 0x89, 0xef, 0xff, 0xcd, + 0xbf, 0x4c, 0xbf, 0x6c, 0x5a, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0xbf, 0x4c, + 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x59, 0xc5, 0xbf, 0x4c, + 0xfd, 0x15, 0x77, 0x6f, 0xbe, 0x4c, 0xbd, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, + 0xbf, 0x4c, 0xf0, 0xfb, 0x94, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0x94, 0xef, + 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0xf8, 0xef, 0x9d, 0x6f, 0xfd, 0xcd, + 0xbe, 0x5c, 0xfc, 0xdf, 0x00, 0x1c, 0xeb, 0x05, 0x11, 0x26, 0xff, 0xdf, + 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xff, 0xff, 0x4f, 0xfe, 0xff, 0xdf, + 0xff, 0xef, 0xff, 0xbf, 0xff, 0x8f, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, + 0x2e, 0xeb, 0x82, 0xed, 0x9f, 0x7c, 0xbf, 0xc4, 0xe7, 0xf7, 0x83, 0xed, + 0xff, 0xce, 0xdf, 0x4c, 0x84, 0xed, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, + 0xe8, 0xed, 0xff, 0xcc, 0x9e, 0x5f, 0xfd, 0xcc, 0x9f, 0x5f, 0xfe, 0xcc, + 0x9d, 0x57, 0xff, 0xcd, 0xbd, 0x4f, 0xfc, 0xdf, 0x00, 0x1c, 0x11, 0x06, + 0x00, 0x1c, 0x25, 0x01, 0xff, 0x17, 0xad, 0xfd, 0x90, 0xed, 0xbb, 0x6c, + 0x3f, 0xcc, 0x96, 0xbc, 0x73, 0x97, 0x7f, 0xcc, 0x96, 0xbc, 0x35, 0x9b, + 0x0d, 0xf6, 0x93, 0xed, 0xfe, 0x15, 0x8b, 0xf1, 0xde, 0x4c, 0x94, 0xed, + 0xbe, 0x6c, 0xad, 0xbd, 0xad, 0xb5, 0x98, 0xed, 0x95, 0x74, 0x32, 0x8b, + 0x73, 0x9b, 0xf5, 0xf7, 0x99, 0xed, 0xbe, 0x6c, 0xad, 0xbd, 0xad, 0xb5, + 0x9d, 0xed, 0x95, 0x74, 0xb2, 0xa5, 0x77, 0x8b, 0xf6, 0xfb, 0x9f, 0xed, + 0xb5, 0x74, 0x9e, 0xed, 0x9e, 0x6c, 0x8d, 0xbc, 0x8d, 0xb4, 0xb2, 0xa5, + 0x77, 0x8b, 0xfb, 0xcc, 0x73, 0x9b, 0xf9, 0xf7, 0x85, 0xee, 0xb3, 0x7c, + 0x5f, 0xc5, 0xb3, 0x5c, 0xfa, 0xfb, 0x87, 0xee, 0xb3, 0x7c, 0x7f, 0xc5, + 0xb3, 0x5c, 0x89, 0xee, 0x93, 0x7c, 0xbe, 0xb4, 0x9c, 0x1b, 0xfe, 0xdf, + 0xbd, 0x1b, 0xfe, 0xdf, 0x71, 0x9b, 0xc6, 0xf7, 0x8e, 0xee, 0xc9, 0x7c, + 0xff, 0xde, 0xbb, 0x8b, 0xc9, 0x5c, 0xb3, 0x7c, 0xfc, 0xb5, 0xff, 0xdf, + 0xff, 0x1b, 0xf0, 0xdf, 0x7c, 0xbf, 0xbd, 0x1b, 0x87, 0xcf, 0x6f, 0x93, + 0xb3, 0x5c, 0xdf, 0xcc, 0xb3, 0x9b, 0xef, 0xf7, 0x95, 0xee, 0xbf, 0x6c, + 0x7c, 0xc5, 0xbf, 0x4c, 0x98, 0xee, 0xff, 0xcd, 0xbf, 0x4c, 0x9a, 0xee, + 0xbd, 0x6c, 0xfd, 0xce, 0xde, 0x5d, 0xf1, 0xa4, 0x00, 0x1c, 0x71, 0x06, + 0x85, 0xfb, 0xd3, 0xc7, 0x8f, 0xf7, 0x9f, 0xee, 0x93, 0x7c, 0x9c, 0x1b, + 0xfb, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0xf7, 0xf7, 0x83, 0xef, 0xb3, 0x7c, + 0xbd, 0x1b, 0x87, 0xcf, 0x59, 0xc5, 0xb3, 0x5c, 0xf4, 0xfb, 0x86, 0xef, + 0xb3, 0x7c, 0xbd, 0x1b, 0x87, 0xcf, 0x5a, 0xc5, 0xb3, 0x5c, 0xfb, 0xfb, + 0xff, 0xcd, 0x8a, 0xef, 0xa9, 0x5c, 0x8b, 0xef, 0x93, 0x7c, 0x9c, 0x1b, + 0xfb, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0xd4, 0xf7, 0x8f, 0xef, 0x93, 0x7c, + 0x9c, 0xb4, 0x9c, 0x1b, 0xf0, 0xdf, 0xde, 0xc4, 0xef, 0xf3, 0x90, 0xef, + 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0x93, 0xef, 0xff, 0xce, 0xdf, 0x4c, + 0x96, 0xef, 0xbd, 0x6c, 0xfe, 0xce, 0xde, 0x5d, 0xf1, 0xa4, 0x00, 0x1c, + 0xa8, 0x06, 0xbc, 0xfb, 0xda, 0xc4, 0xf9, 0xf3, 0x9b, 0xef, 0xb3, 0x7c, + 0x5d, 0xc5, 0xb3, 0x5c, 0xd0, 0xfb, 0x9d, 0xef, 0xaf, 0x7c, 0xf8, 0xfb, + 0x4f, 0xfe, 0xff, 0xdf, 0xff, 0xef, 0xff, 0xbf, 0xff, 0x8f, 0xff, 0xbf, + 0x7f, 0xc5, 0x7e, 0xc5, 0xaf, 0x5c, 0xdd, 0xfb, 0x9e, 0xec, 0x93, 0x7c, + 0x9c, 0xb4, 0x9c, 0x1b, 0xf0, 0xdf, 0xde, 0xc4, 0xef, 0xf3, 0x80, 0xed, + 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0x81, 0xed, 0xff, 0xcd, 0xbf, 0x4c, + 0x85, 0xed, 0xbd, 0x6c, 0xfe, 0xce, 0xde, 0x5d, 0xf1, 0xa4, 0x00, 0x1c, + 0xd2, 0x06, 0xe6, 0xfb, 0xda, 0xc4, 0xf5, 0xf3, 0x8a, 0xed, 0xaf, 0x7c, + 0x7f, 0xc5, 0x7e, 0xc5, 0x5f, 0xc5, 0xaf, 0x5c, 0xb3, 0x7c, 0x7d, 0xc5, + 0xb3, 0x5c, 0x8e, 0xed, 0xb3, 0x7c, 0xbd, 0x1b, 0x87, 0xcf, 0xb3, 0x5c, + 0x91, 0xed, 0xb3, 0x7c, 0xdd, 0x1b, 0xfe, 0xdf, 0xde, 0xbe, 0x7e, 0xc5, + 0x7b, 0x93, 0xb3, 0x5c, 0x95, 0xed, 0x8f, 0x7c, 0x9c, 0x1b, 0xfc, 0xdf, + 0xde, 0xc4, 0x8a, 0xf2, 0xb8, 0xed, 0xcf, 0x7d, 0xbe, 0x1b, 0xf3, 0xdf, + 0xbb, 0xc5, 0xd0, 0xf7, 0x9b, 0xed, 0x99, 0x6c, 0xbf, 0x7c, 0x77, 0x8b, + 0xbe, 0xb5, 0xbf, 0x5c, 0xde, 0x1b, 0xfc, 0xdf, 0xbe, 0xc6, 0xf8, 0xf7, + 0xbf, 0x7c, 0xff, 0xce, 0x80, 0xd6, 0x7b, 0x93, 0x77, 0x8b, 0xbf, 0x5c, + 0xa3, 0xee, 0xcf, 0x7d, 0x9b, 0xb6, 0xff, 0xdc, 0x9c, 0x1b, 0xf0, 0xdf, + 0xfb, 0xbc, 0xde, 0x1b, 0xf0, 0xdf, 0xbf, 0x93, 0xcf, 0x5d, 0xb7, 0xc4, + 0x19, 0xf7, 0x88, 0xee, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0x89, 0xee, + 0xff, 0xcd, 0xbf, 0x4c, 0x8d, 0xee, 0xbd, 0x6c, 0xff, 0xce, 0xde, 0x5d, + 0xfe, 0xce, 0xdd, 0x5d, 0xf1, 0xa4, 0x00, 0x1c, 0x24, 0x07, 0x2a, 0xfb, + 0xb7, 0xc5, 0x2c, 0xf7, 0xb3, 0xee, 0xae, 0x7d, 0xbd, 0x1b, 0x83, 0xdf, + 0xbf, 0xc5, 0x40, 0xf3, 0xb6, 0xee, 0xae, 0x7d, 0xbd, 0x1b, 0xfc, 0xdf, + 0xbe, 0xc5, 0xe5, 0xf3, 0xde, 0xc5, 0xfb, 0xf3, 0xbf, 0xc5, 0xf8, 0xf3, + 0x3d, 0xfb, 0xbd, 0xc5, 0xb3, 0xf3, 0xbc, 0xc5, 0x41, 0xf7, 0xab, 0xfb, + 0xde, 0x1b, 0xfc, 0xdf, 0xbf, 0xc6, 0x3f, 0xf7, 0x80, 0xef, 0xae, 0x7c, + 0x7f, 0xc5, 0x7e, 0xc5, 0x5f, 0xc5, 0xae, 0x5c, 0xb3, 0x7c, 0xbd, 0x1b, + 0x80, 0xdf, 0xb3, 0x5c, 0x51, 0xfb, 0x85, 0xef, 0x99, 0x6c, 0xbf, 0x7c, + 0x77, 0x8b, 0xbe, 0xb5, 0xbf, 0x5c, 0xde, 0x1b, 0xfc, 0xdf, 0xbe, 0xc6, + 0xed, 0xf7, 0xbf, 0x7c, 0xff, 0xce, 0x80, 0xd6, 0x7b, 0x93, 0x77, 0x8b, + 0xbf, 0x5c, 0x8d, 0xef, 0xb3, 0x7c, 0xd8, 0xb5, 0xde, 0x1b, 0xfe, 0xdf, + 0xb9, 0x93, 0xd8, 0xbe, 0xbd, 0x1b, 0x80, 0xdf, 0x7b, 0x93, 0xb3, 0x5c, + 0xb3, 0xef, 0xcf, 0x7d, 0x9b, 0xb6, 0xff, 0xdc, 0x9c, 0x1b, 0xf0, 0xdf, + 0xfb, 0xbc, 0xde, 0x1b, 0xf0, 0xdf, 0xbf, 0x93, 0xcf, 0x5d, 0xb7, 0xc4, + 0x79, 0xf7, 0x34, 0x93, 0xaf, 0x7d, 0xbd, 0x1b, 0xf0, 0xdf, 0xaf, 0x5c, + 0xae, 0x7c, 0x7f, 0xc5, 0x7e, 0xc5, 0x5e, 0xc5, 0xae, 0x5c, 0x84, 0xfb, + 0x4f, 0xfe, 0xff, 0xdf, 0xff, 0x8f, 0xff, 0xbf, 0xff, 0xef, 0xff, 0xbf, + 0xa1, 0xed, 0xb3, 0x7d, 0xb8, 0xb5, 0x71, 0x9b, 0x88, 0xf7, 0x83, 0xed, + 0xae, 0x7c, 0xbd, 0x13, 0xfc, 0xff, 0xae, 0x5c, 0x95, 0xfb, 0xde, 0x1b, + 0xfc, 0xdf, 0xbe, 0xc6, 0x92, 0xf7, 0x88, 0xed, 0x8d, 0x7c, 0x9c, 0x1b, + 0xfd, 0xdf, 0x33, 0x8b, 0xbf, 0xc4, 0xd3, 0xf7, 0x8c, 0xed, 0xad, 0x7c, + 0x5e, 0xc5, 0xad, 0x5c, 0x99, 0x6c, 0x9f, 0x7c, 0x33, 0x8b, 0xe0, 0xcd, + 0x37, 0x9b, 0xe9, 0xf7, 0x81, 0xcd, 0x37, 0x9b, 0xf9, 0xf3, 0xe0, 0xd4, + 0x9b, 0xac, 0xfc, 0xdc, 0x33, 0x8b, 0xf0, 0xfb, 0x21, 0xcd, 0x37, 0x9b, + 0xf9, 0xf3, 0x80, 0xd4, 0x9c, 0xac, 0xf6, 0xdc, 0x33, 0x8b, 0xf8, 0xfb, + 0x20, 0xd4, 0x9d, 0xac, 0xe0, 0xdc, 0x33, 0x8b, 0xfd, 0xfb, 0xfc, 0xcc, + 0xdc, 0x1b, 0xe0, 0xdf, 0xbd, 0xed, 0xfd, 0xbe, 0x8e, 0x7d, 0x9c, 0x1b, + 0x83, 0xcf, 0x3f, 0x93, 0x8e, 0x5d, 0x9d, 0x6d, 0xdd, 0x5c, 0x81, 0xee, + 0x8e, 0x7c, 0x9c, 0x1b, 0x83, 0xdf, 0xbb, 0xc4, 0xf6, 0xf7, 0x84, 0xee, + 0xb9, 0x6c, 0xbf, 0x7d, 0x77, 0x8b, 0x83, 0x7c, 0x33, 0x8b, 0x35, 0x9b, + 0xd2, 0xf7, 0x88, 0xee, 0xb9, 0x6c, 0xdf, 0x7d, 0xe3, 0x7c, 0xbe, 0x93, + 0xbb, 0x8b, 0xc3, 0x5c, 0xff, 0xdd, 0xb9, 0x4c, 0xce, 0x7c, 0x7f, 0xc6, + 0x7e, 0xc6, 0x78, 0x93, 0xdd, 0xb6, 0xe1, 0xde, 0xde, 0x1b, 0xe0, 0xdf, + 0xdd, 0xbe, 0xbd, 0x1b, 0x83, 0xcf, 0x7b, 0x93, 0xae, 0x5c, 0xf0, 0xfb, + 0x93, 0xee, 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0x94, 0xee, 0xff, 0xcd, + 0xbf, 0x4c, 0x97, 0xee, 0xbd, 0x6c, 0xff, 0xce, 0xde, 0x5d, 0xf1, 0xa4, + 0x00, 0x1c, 0xf9, 0x07, 0x9b, 0xee, 0xaf, 0x7c, 0x7f, 0xc5, 0x7e, 0xc5, + 0x5e, 0xc5, 0xaf, 0x5c, 0x99, 0xfb, 0x9d, 0xee, 0xbf, 0x6c, 0x7c, 0xc5, + 0xbf, 0x4c, 0x9e, 0xee, 0xff, 0xce, 0xdf, 0x4c, 0x82, 0xef, 0xbd, 0x6c, + 0xfe, 0xce, 0xde, 0x5d, 0xf1, 0xa4, 0x00, 0x1c, 0x0e, 0x08, 0xa8, 0xfb, + 0xbf, 0xc5, 0xf2, 0xf7, 0x86, 0xef, 0xbe, 0x6c, 0xad, 0xbd, 0xad, 0xb5, + 0x89, 0xef, 0xb5, 0x54, 0xbb, 0x6c, 0x70, 0xc5, 0x6f, 0xc5, 0x50, 0xc5, + 0xbb, 0x4c, 0xb6, 0xfb, 0x7f, 0xcc, 0x97, 0xbc, 0x35, 0x9b, 0xba, 0xf7, + 0x8e, 0xef, 0xbe, 0x6c, 0xad, 0xbd, 0xad, 0xb5, 0x91, 0xef, 0x95, 0x74, + 0x32, 0x8b, 0x73, 0x9b, 0xf3, 0xf7, 0x92, 0xef, 0xbe, 0x6c, 0xad, 0xbd, + 0xad, 0xb5, 0x95, 0xef, 0x95, 0x74, 0x32, 0x8b, 0x92, 0xa5, 0xdb, 0xc4, + 0x3c, 0x9b, 0xec, 0xfb, 0x99, 0xef, 0xb5, 0x74, 0x76, 0x8b, 0x99, 0xef, + 0x9e, 0x6c, 0x8d, 0xbc, 0x8d, 0xb4, 0x92, 0xa5, 0xdb, 0xc4, 0x3c, 0x9b, + 0xf7, 0xfb, 0xff, 0xff, 0x4f, 0xfe, 0xff, 0xdf, 0xff, 0x8f, 0xff, 0xbf, + 0xff, 0xef, 0xff, 0xbf, 0xbf, 0xc4, 0xe2, 0xf3, 0x81, 0xed, 0xbb, 0x6c, + 0x70, 0xc5, 0x6f, 0xc5, 0x4f, 0xc5, 0xbb, 0x4c, 0x83, 0xed, 0xff, 0xcd, + 0xbf, 0x4c, 0xbf, 0x4c, 0xbf, 0x6c, 0x5a, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, + 0xbf, 0x4c, 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x59, 0xc5, + 0xbf, 0x4c, 0xfd, 0x15, 0x8b, 0xf1, 0xbe, 0x4c, 0xbd, 0x4c, 0xbf, 0x6c, + 0x56, 0xc5, 0xbf, 0x4c, 0x11, 0x26, 0xfe, 0xdf, 0x7f, 0x67, 0xfd, 0xeb, + 0x9c, 0xeb, 0x9e, 0xeb, 0x90, 0xed, 0xff, 0xcd, 0xbf, 0x4c, 0xbf, 0x6c, + 0xbd, 0x13, 0xfc, 0xff, 0xbf, 0x4c, 0xbf, 0x6c, 0x5d, 0xc5, 0xbf, 0x4c, + 0xb0, 0x93, 0x9b, 0xcd, 0x9e, 0x6e, 0x37, 0x9b, 0x01, 0xf4, 0x97, 0xed, + 0xbf, 0x6c, 0x7c, 0xc5, 0xbf, 0x4c, 0x9b, 0xed, 0xff, 0xcd, 0xbe, 0x5c, + 0xa2, 0x5c, 0xff, 0xcd, 0xb5, 0x54, 0xb3, 0x7c, 0xbd, 0x1b, 0x87, 0xdf, + 0xbd, 0x1b, 0x87, 0xcf, 0xb3, 0x5c, 0xae, 0x7c, 0xbd, 0x1b, 0x03, 0xdf, + 0xbd, 0x1b, 0x83, 0xcf, 0xae, 0x5c, 0xff, 0xcd, 0xaf, 0x5c, 0xbb, 0x6c, + 0x70, 0xc5, 0x6f, 0xc5, 0xbb, 0x4c, 0xaf, 0xb5, 0x7e, 0xc5, 0xad, 0x5c, + 0xc3, 0x87, 0xff, 0xff, 0x2f, 0xeb, 0xaa, 0xee, 0xff, 0xcc, 0x9f, 0x5d, + 0x8a, 0xee, 0xff, 0xce, 0xdf, 0x4c, 0xdf, 0x6c, 0xdf, 0x4c, 0xdf, 0x6c, 0x5d, 0xc6, 0xdf, 0x4c, 0x9e, 0x7d, 0xbf, 0xc4, 0xfb, 0xf3, 0xf0, 0xcf, - 0x00, 0x1c, 0x21, 0x06, 0x95, 0xef, 0xbf, 0x6c, 0x5c, 0xc5, 0xbf, 0x4c, - 0x96, 0xef, 0xff, 0xcd, 0xbf, 0x4c, 0xbf, 0x6c, 0xbd, 0x13, 0x9d, 0xff, - 0x46, 0xce, 0xbf, 0x4c, 0xde, 0x4c, 0xdd, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, - 0xbf, 0x4c, 0x6f, 0xeb, 0x6b, 0xfe, 0xff, 0xdf, 0xff, 0x8f, 0xff, 0xbf, - 0xff, 0xef, 0xff, 0xbf, 0x9e, 0xee, 0xff, 0x8b, 0xf9, 0xcd, 0xbd, 0x54, - 0xdd, 0x4c, 0xff, 0x5e, 0xfd, 0xde, 0xd9, 0x4c, 0xb3, 0x7c, 0xfd, 0xce, - 0x7b, 0x93, 0xbd, 0x1b, 0x87, 0xcf, 0x7d, 0xc5, 0xb3, 0x5c, 0xae, 0x7c, - 0xbd, 0x1b, 0x03, 0xdf, 0xff, 0x1b, 0xfc, 0xdf, 0xfd, 0xbf, 0xbd, 0x1b, - 0x83, 0xcf, 0xbf, 0x93, 0x5d, 0xc5, 0xcf, 0x5c, 0xae, 0x5c, 0xbb, 0x6c, - 0x50, 0xc5, 0x4f, 0xc5, 0xbb, 0x4c, 0xaf, 0xb5, 0x7e, 0xc5, 0xad, 0x5c, - 0xff, 0xce, 0xae, 0xef, 0xdf, 0x4d, 0xff, 0x6d, 0xff, 0x13, 0xfc, 0xff, - 0xff, 0x4d, 0xff, 0x6d, 0x5d, 0xc7, 0xff, 0x4d, 0xff, 0x6d, 0x7c, 0xc7, - 0xff, 0x4d, 0xfe, 0xcd, 0xc3, 0x5c, 0xbf, 0x5c, 0xc9, 0x5c, 0x95, 0xef, - 0xdf, 0x4c, 0xbf, 0x6c, 0xbd, 0x13, 0x9d, 0xff, 0xbf, 0x4c, 0xfd, 0x15, - 0xa9, 0xfb, 0xbe, 0x4c, 0xbd, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, 0xbf, 0x4c, - 0xc3, 0x87, 0xff, 0xff, 0x6b, 0xfe, 0xff, 0xdf, 0xff, 0x8f, 0xff, 0xbf, - 0xff, 0xef, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, 0x93, 0xef, 0xb2, 0xef, - 0xbf, 0x4c, 0x92, 0xef, 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, - 0x5f, 0xc5, 0xbd, 0x4c, 0xfd, 0xcd, 0xbf, 0x4c, 0xd6, 0xef, 0xba, 0xcc, - 0x9e, 0x4e, 0x9f, 0x6e, 0xb8, 0xef, 0x3e, 0xc4, 0x02, 0xf0, 0x9f, 0x6d, - 0x7e, 0xc4, 0x9f, 0x4d, 0x08, 0xf8, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xbf, - 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xcf, 0xff, 0xbf, - 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x88, 0xef, 0x99, 0x6c, 0x2f, 0xc4, - 0xf2, 0xf3, 0xff, 0xcd, 0x8a, 0xef, 0xbf, 0x5c, 0x00, 0x1c, 0xd5, 0x0a, - 0x00, 0x1c, 0x1f, 0x09, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, - 0x9e, 0xeb, 0xff, 0xcf, 0x00, 0x1c, 0x8d, 0x0c, 0xfc, 0x15, 0xd1, 0xfd, - 0xf3, 0x9b, 0x11, 0xf0, 0xb3, 0xef, 0x9f, 0x7d, 0xff, 0xdc, 0x33, 0x8b, - 0x9f, 0x5d, 0xfc, 0xcd, 0x37, 0x9b, 0x16, 0xf4, 0x96, 0xef, 0xb5, 0xef, - 0xbf, 0x4c, 0x95, 0xef, 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, - 0x5f, 0xc5, 0xbd, 0x4c, 0xfd, 0xcd, 0xbf, 0x4c, 0x23, 0xf8, 0xff, 0xff, - 0xff, 0x5f, 0xff, 0xbf, 0x4d, 0xfe, 0xff, 0xdf, 0xff, 0xbb, 0xff, 0xbf, - 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, + 0x00, 0x1c, 0x33, 0x06, 0x91, 0xee, 0xbf, 0x6c, 0x5c, 0xc5, 0xbf, 0x4c, + 0x94, 0xee, 0xff, 0xcd, 0xbf, 0x4c, 0xbf, 0x6c, 0x5a, 0xc5, 0xbf, 0x4c, + 0xbf, 0x6c, 0xbf, 0x4c, 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, + 0x59, 0xc5, 0xbf, 0x4c, 0x46, 0xce, 0xde, 0x4c, 0xdd, 0x4c, 0xbf, 0x6c, + 0x56, 0xc5, 0xbf, 0x4c, 0x6f, 0xeb, 0xff, 0xff, 0xff, 0x8b, 0x80, 0xef, + 0xf9, 0xcd, 0xbd, 0x54, 0xdd, 0x4c, 0xff, 0x5e, 0xfd, 0xde, 0xd9, 0x4c, + 0xb3, 0x7c, 0xfd, 0xce, 0x7b, 0x93, 0xbd, 0x1b, 0x87, 0xcf, 0x7d, 0xc5, + 0xb3, 0x5c, 0xae, 0x7c, 0xbd, 0x1b, 0x03, 0xdf, 0xff, 0x1b, 0xfc, 0xdf, + 0xfd, 0xbf, 0xbf, 0x93, 0xcf, 0x5c, 0xbd, 0x1b, 0x83, 0xcf, 0x5d, 0xc5, + 0xae, 0x5c, 0xbb, 0x6c, 0x50, 0xc5, 0x4f, 0xc5, 0xbb, 0x4c, 0xaf, 0xb5, + 0x7e, 0xc5, 0xad, 0x5c, 0xaf, 0xef, 0xff, 0xce, 0xdf, 0x4d, 0xff, 0x6d, + 0xff, 0x13, 0xfc, 0xff, 0xff, 0x4d, 0xff, 0x6d, 0x5d, 0xc7, 0xff, 0x4d, + 0xff, 0x6d, 0x7c, 0xc7, 0xff, 0x4d, 0xc3, 0x5c, 0xc9, 0x5c, 0xfe, 0xcd, + 0xbf, 0x5c, 0x98, 0xef, 0xdf, 0x4c, 0xbf, 0x6c, 0x5a, 0xc5, 0xbf, 0x4c, + 0xbf, 0x6c, 0xbf, 0x4c, 0xbf, 0x6c, 0x5e, 0xc5, 0xbf, 0x4c, 0xf8, 0xfb, + 0x4f, 0xfe, 0xff, 0xdf, 0xff, 0xef, 0xff, 0xbf, 0xff, 0x8f, 0xff, 0xbf, + 0xbf, 0x6c, 0x59, 0xc5, 0xbf, 0x4c, 0xfd, 0x15, 0xa9, 0xfb, 0xbe, 0x4c, + 0xbd, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, + 0x9f, 0xeb, 0x9d, 0xeb, 0x93, 0xef, 0xb2, 0xef, 0xbf, 0x4c, 0x92, 0xef, + 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0x5f, 0xc5, 0xbd, 0x4c, + 0xfd, 0xcd, 0xbf, 0x4c, 0xb6, 0xef, 0xfd, 0xce, 0xba, 0xcc, 0x9e, 0x4d, + 0x9f, 0x6d, 0xb1, 0x97, 0x01, 0xf0, 0x9f, 0x6d, 0x7e, 0xc4, 0x9f, 0x4d, + 0x07, 0xf8, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xbf, 0xae, 0x1a, 0x33, 0xe5, + 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xcf, 0xff, 0xbf, 0x9f, 0xeb, 0x9d, 0xeb, + 0x2f, 0xeb, 0x95, 0xec, 0x99, 0x6c, 0x2f, 0xc4, 0xe2, 0xf7, 0xff, 0xcf, + 0x00, 0x1c, 0x53, 0x0c, 0xfc, 0x15, 0xd1, 0xfd, 0xf3, 0x9b, 0xe9, 0xf3, + 0xba, 0xec, 0x9f, 0x7d, 0xff, 0xdc, 0x33, 0x8b, 0x9f, 0x5d, 0xfc, 0xcd, + 0x37, 0x9b, 0xee, 0xf7, 0x9d, 0xec, 0xbc, 0xec, 0xbf, 0x4c, 0x9c, 0xec, + 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0x5f, 0xc5, 0xbd, 0x4c, + 0xfd, 0xcd, 0xbf, 0x4c, 0xfb, 0xfb, 0xff, 0xcd, 0x85, 0xed, 0xbf, 0x5c, + 0x00, 0x1c, 0xa9, 0x0a, 0x00, 0x1c, 0x3d, 0x09, 0x11, 0x26, 0xff, 0xdf, + 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0xff, 0xff, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, - 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, 0x18, 0x0f, 0x11, 0x26, + 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, 0x50, 0x0f, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, - 0x2f, 0xeb, 0x00, 0x1c, 0xbc, 0x0a, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, + 0x2f, 0xeb, 0x00, 0x1c, 0x92, 0x0a, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, - 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, 0xae, 0x0a, 0x11, 0x26, + 0x9f, 0xeb, 0x9d, 0xeb, 0x2f, 0xeb, 0x00, 0x1c, 0x8a, 0x0a, 0x11, 0x26, 0xff, 0xdf, 0xfe, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x9f, 0xeb, 0x9d, 0xeb, 0x9c, 0xeb, 0x9e, 0xeb, 0x2f, 0xeb, 0xff, 0x1f, - 0xc2, 0xff, 0xff, 0x1f, 0x8e, 0xff, 0xf6, 0xcf, 0xff, 0x1f, 0x8d, 0xff, - 0xff, 0xce, 0xf6, 0xcf, 0xff, 0x1f, 0x87, 0xff, 0xf5, 0xcf, 0xff, 0x1f, - 0x94, 0xff, 0xff, 0xce, 0xf5, 0xcf, 0xff, 0x1f, 0x8e, 0xff, 0xec, 0xcf, - 0xff, 0x1f, 0x9b, 0xff, 0xfe, 0xce, 0xec, 0xcf, 0xff, 0x1f, 0x95, 0xff, - 0xf2, 0xcf, 0xff, 0x1f, 0xa2, 0xff, 0xfe, 0xce, 0xf2, 0xcf, 0xff, 0x1f, - 0x9c, 0xff, 0xfe, 0xcf, 0xff, 0x1f, 0xa9, 0xff, 0xfe, 0xce, 0xfe, 0xcf, - 0xff, 0x1f, 0xa3, 0xff, 0xf9, 0xcf, 0xff, 0x1f, 0xb0, 0xff, 0xfd, 0xce, - 0xf9, 0xcf, 0xff, 0x1f, 0xaa, 0xff, 0xf7, 0xcf, 0xff, 0x1f, 0xb7, 0xff, - 0xfc, 0xce, 0xf7, 0xcf, 0xff, 0x1f, 0xb1, 0xff, 0xff, 0xcf, 0xff, 0x1f, - 0xbe, 0xff, 0xff, 0xcf, 0xfc, 0xce, 0xff, 0x1f, 0xb8, 0xff, 0x6f, 0xeb, + 0xb6, 0xff, 0xff, 0x1f, 0x7a, 0xff, 0xf6, 0xcf, 0xff, 0x1f, 0x75, 0xff, + 0xf6, 0xcf, 0xff, 0xce, 0xff, 0x1f, 0x61, 0xff, 0xf5, 0xcf, 0xff, 0x1f, + 0x7c, 0xff, 0xf5, 0xcf, 0xff, 0xce, 0xff, 0x1f, 0x68, 0xff, 0xec, 0xcf, + 0xff, 0x1f, 0x83, 0xff, 0xec, 0xcf, 0xfe, 0xce, 0xff, 0x1f, 0x6f, 0xff, + 0xfd, 0xcf, 0xff, 0x1f, 0x8a, 0xff, 0xfd, 0xcf, 0xfe, 0xce, 0xff, 0x1f, + 0x76, 0xff, 0xfe, 0xcf, 0xff, 0x1f, 0x91, 0xff, 0xfe, 0xcf, 0xfe, 0xce, + 0xff, 0x1f, 0x7d, 0xff, 0xf9, 0xcf, 0xff, 0x1f, 0x98, 0xff, 0xf9, 0xcf, + 0xfd, 0xce, 0xff, 0x1f, 0x84, 0xff, 0xf7, 0xcf, 0xff, 0x1f, 0x9f, 0xff, + 0xf7, 0xcf, 0xfc, 0xce, 0xff, 0x1f, 0x8b, 0xff, 0xff, 0xcf, 0xff, 0x1f, + 0xa6, 0xff, 0xff, 0xcf, 0xfc, 0xce, 0xff, 0x1f, 0x92, 0xff, 0x6f, 0xeb, + 0xc3, 0x87, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xbf, 0x31, 0xfe, 0xff, 0xdf, + 0xff, 0xbb, 0xff, 0xbf, 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, 0x8e, 0xef, 0xad, 0xef, 0x9f, 0x4d, 0xad, 0xef, 0xbc, 0x23, 0xff, 0xde, 0xae, 0xef, 0xbc, 0x23, 0xfe, 0xde, 0xae, 0xef, 0xbc, 0x23, 0xfd, 0xde, 0xaf, 0xef, 0xbc, 0x23, 0xfc, 0xde, 0xaf, 0xef, 0xbc, 0x23, 0xfb, 0xde, 0xb0, 0xef, 0xbc, 0x23, 0xfa, 0xde, 0xb0, 0xef, 0xbc, 0x23, 0xf9, 0xde, 0xb1, 0xef, 0xbc, 0x23, 0xf8, 0xde, 0xff, 0xcd, 0xbc, 0x23, 0xfe, 0xdc, 0xbc, 0x23, 0x3f, 0xdf, 0xc3, 0x87, 0xff, 0xff, 0xff, 0x1f, 0xff, 0x1f, - 0x43, 0xfe, 0xff, 0xdf, 0xfc, 0xfd, 0xfe, 0xff, 0xf8, 0xf9, 0xfa, 0xfb, + 0x2f, 0xfe, 0xff, 0xdf, 0xfc, 0xfd, 0xfe, 0xff, 0xf8, 0xf9, 0xfa, 0xfb, 0xf4, 0xf5, 0xf6, 0xf7, 0xf0, 0xf1, 0xf2, 0xf3, 0xec, 0xed, 0xee, 0xef, 0xe8, 0xe9, 0xea, 0xeb, 0xe4, 0xe5, 0xe6, 0xe7, 0xe0, 0xe1, 0xe2, 0xe3, - 0x7f, 0x3e, 0xdf, 0x8b, 0xc3, 0x87, 0xff, 0xff, 0x9b, 0xef, 0xfe, 0xcd, - 0x9f, 0x6c, 0xfd, 0x3b, 0xdf, 0xbf, 0xfc, 0x23, 0xbf, 0xdf, 0xc3, 0x87, - 0x43, 0xfe, 0xff, 0xdf, 0x3e, 0xeb, 0x20, 0xc7, 0xe9, 0xf7, 0x9f, 0x1b, - 0xfc, 0xdf, 0xfd, 0xaf, 0xb5, 0xef, 0xff, 0x8b, 0xbf, 0x6d, 0x00, 0xdf, - 0xfd, 0x3b, 0xbf, 0xf7, 0x9c, 0xbc, 0x00, 0xcd, 0x7f, 0x6f, 0x73, 0x8f, - 0xbb, 0x3b, 0xbd, 0xdf, 0xbf, 0x4f, 0xfa, 0xdc, 0xbf, 0x6f, 0xb3, 0x8f, - 0xb7, 0x93, 0xdf, 0x4f, 0x7e, 0xeb, 0xff, 0xff, 0x43, 0xfe, 0xff, 0xdf, - 0x7f, 0xcc, 0x88, 0xbc, 0xbf, 0x6c, 0xbd, 0x1b, 0xe0, 0xcf, 0x5e, 0xc5, - 0xbf, 0x4c, 0xbf, 0x6c, 0x78, 0xc5, 0x77, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, - 0x56, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x59, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, - 0x5a, 0xc5, 0xbf, 0x4c, 0x46, 0xcd, 0xbd, 0xbd, 0xbe, 0x4c, 0xbd, 0x4c, - 0xc3, 0x87, 0xff, 0xff, 0xc3, 0x87, 0xff, 0xff, 0x98, 0xef, 0xb7, 0xef, - 0xbf, 0x4c, 0x97, 0xef, 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, - 0x5f, 0xc5, 0xbd, 0x4c, 0xba, 0xef, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, - 0xff, 0xbb, 0xff, 0xbf, 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, - 0x00, 0x00, 0xf9, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x07, 0xb7, 0xff, 0xff, - 0xfd, 0xfe, 0xff, 0xff, 0xff, 0xb6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x8e, 0xed, 0xff, 0x91, 0xff, 0xff, 0x9b, 0x54, - 0xae, 0xf5, 0xff, 0xff, 0xbc, 0x2f, 0xff, 0xff, 0xdd, 0xff, 0xcf, 0xff, - 0xfc, 0xfe, 0xff, 0xff, 0xf7, 0xb6, 0xff, 0xff, 0xfb, 0xfe, 0xff, 0xff, - 0xb3, 0xb6, 0xff, 0xff, 0xfa, 0xfd, 0xff, 0xff, 0xaf, 0xb6, 0xff, 0xff, - 0xf9, 0xfd, 0xff, 0xff, 0xab, 0xb6, 0xff, 0xff, 0xf8, 0xfe, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xdf, 0xf7, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, - 0xf6, 0xfe, 0xff, 0xff, 0xa7, 0xb6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xdf, 0xfd, 0xce, 0xff, 0xf8, 0xcf, 0xff, 0xff, - 0xf8, 0xce, 0xff, 0xff, 0xdf, 0xff, 0xfc, 0xff, 0x97, 0xeb, 0xff, 0xff, - 0xd1, 0xeb, 0xff, 0xff, 0x69, 0xeb, 0xff, 0xff, 0x31, 0xeb, 0xff, 0xff, - 0xe3, 0xea, 0xff, 0xff, 0xc3, 0xea, 0xff, 0xff, 0x93, 0xeb, 0xff, 0xff, - 0x7f, 0xf5, 0x59, 0xf5, 0x59, 0xf5, 0x59, 0xd7, 0x79, 0xd7, 0x79, 0xd7, - 0x79, 0xd7, 0x79, 0xd7, 0x79, 0xcd, 0x79, 0xc3, 0x59, 0xd7, 0x59, 0xd7, - 0x67, 0xc3, 0x67, 0xd7, 0x72, 0xd7, 0x72, 0xd7, 0x72, 0xc3, 0x72, 0xe1, - 0x72, 0xe1, 0x72, 0xe1, 0x72, 0xe1, 0x72, 0xeb, 0x72, 0xeb, 0x72, 0xeb, - 0x72, 0xeb, 0xff, 0xff, 0x77, 0xec, 0xff, 0xff, 0xb8, 0xfc, 0xff, 0xff, - 0xef, 0xd8, 0xff, 0xff, 0x5b, 0xfe, 0xff, 0xff, 0xef, 0xd8, 0xff, 0xff, - 0x91, 0x5c, 0xfe, 0xff, 0xdf, 0xb1, 0xff, 0xff, 0x48, 0x2e, 0xff, 0xff, - 0x4b, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, - 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, - 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, - 0x27, 0xe2, 0xff, 0xff, 0xc3, 0xe0, 0xff, 0xff, 0x2d, 0xe1, 0xff, 0xff, - 0x4d, 0xe1, 0xff, 0xff, 0x2d, 0xe1, 0xff, 0xff, 0x4d, 0xe1, 0xff, 0xff, - 0x4d, 0xe1, 0xff, 0xff, 0x4d, 0xe1, 0xff, 0xff, 0x63, 0xe1, 0xff, 0xff, - 0xa1, 0xe1, 0xff, 0xff, 0xaf, 0xe0, 0xff, 0xff, 0xbf, 0xe1, 0xff, 0xff, - 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, 0x27, 0xe2, 0xff, 0xff, - 0x27, 0xe2, 0xff, 0xff, 0xdf, 0xe1, 0xff, 0xff, 0xed, 0xe1, 0xff, 0xff, - 0xfb, 0xe1, 0xff, 0xff, 0x17, 0xe2, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, - 0x4f, 0xde, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, - 0x5d, 0xde, 0xff, 0xff, 0x71, 0xde, 0xff, 0xff, 0x79, 0xde, 0xff, 0xff, - 0x8f, 0xde, 0xff, 0xff, 0xa7, 0xde, 0xff, 0xff, 0xa7, 0xde, 0xff, 0xff, - 0xa7, 0xde, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, 0x37, 0xde, 0xff, 0xff, - 0xa7, 0xde, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, 0xb3, 0xde, 0xff, 0xff, - 0xbb, 0xde, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, 0x09, 0xdf, 0xff, 0xff, - 0x09, 0xdf, 0xff, 0xff, 0xc7, 0xde, 0xff, 0xff, 0xad, 0xdd, 0xff, 0xff, - 0xb3, 0xdd, 0xff, 0xff, 0xb3, 0xdd, 0xff, 0xff, 0xb3, 0xdd, 0xff, 0xff, - 0x47, 0xdd, 0xff, 0xff, 0x3d, 0xdd, 0xff, 0xff, 0xcf, 0xdc, 0xff, 0xff, - 0xcf, 0xdc, 0xff, 0xff, 0xd3, 0xdc, 0xff, 0xff, 0x17, 0xdd, 0xff, 0xff, - 0xb3, 0xdd, 0xff, 0xff, 0x09, 0xdd, 0xff, 0xff, 0xe5, 0xdc, 0xff, 0xff, - 0xf1, 0xdd, 0xff, 0xff, 0xcf, 0xdc, 0xff, 0xff, 0xcf, 0xdc, 0xff, 0xff, - 0xd7, 0xdc, 0xff, 0xff, 0xf9, 0xda, 0xff, 0xff, 0xa7, 0xd8, 0xff, 0xff, - 0xf9, 0xda, 0xff, 0xff, 0xbb, 0xd8, 0xff, 0xff, 0xdd, 0xd8, 0xff, 0xff, - 0xf1, 0xd8, 0xff, 0xff, 0x01, 0xd9, 0xff, 0xff, 0x15, 0xd9, 0xff, 0xff, - 0x71, 0xd9, 0xff, 0xff, 0xa3, 0xd9, 0xff, 0xff, 0xa3, 0xd9, 0xff, 0xff, - 0xbd, 0xd9, 0xff, 0xff, 0xf3, 0xd9, 0xff, 0xff, 0x31, 0xda, 0xff, 0xff, - 0xf9, 0xda, 0xff, 0xff, 0x4f, 0xda, 0xff, 0xff, 0x73, 0xda, 0xff, 0xff, - 0xf9, 0xda, 0xff, 0xff, 0xf9, 0xda, 0xff, 0xff, 0xf9, 0xda, 0xff, 0xff, - 0x9d, 0xda, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x23, 0xff, 0xff, 0xdf, - 0xfd, 0xff, 0xff, 0xff, 0x1b, 0xff, 0xff, 0xdf, 0x17, 0xf4, 0xff, 0xff, - 0x77, 0xf4, 0xff, 0xff, 0xfb, 0xf6, 0xff, 0xff, 0x13, 0xf6, 0xff, 0xff, - 0xef, 0xeb, 0xff, 0xff, 0xdf, 0xfe, 0xeb, 0xff, 0xbb, 0x9b, 0xbb, 0x87, - 0xc5, 0x98, 0xc8, 0x98, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x0f, 0x1e, 0x2d, 0x3c, + 0x9e, 0xee, 0x9f, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, 0xfc, 0x23, + 0x7f, 0xdf, 0xc3, 0x87, 0x7f, 0x3e, 0xdf, 0x8b, 0xc3, 0x87, 0xff, 0xff, + 0x7f, 0x3f, 0xdf, 0x8f, 0xc3, 0x87, 0xff, 0xff, 0x86, 0xef, 0x9f, 0x6c, + 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, 0xfc, 0x23, 0xbf, 0xdf, 0xc3, 0x87, + 0x8a, 0xef, 0x9f, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, 0xdf, 0xbf, 0xfc, 0x23, + 0x9f, 0xdf, 0xc3, 0x87, 0x8e, 0xef, 0x9f, 0x6c, 0xfe, 0xcd, 0xfd, 0x3b, + 0xdf, 0xbf, 0xfc, 0x23, 0x5f, 0xdf, 0xc3, 0x87, 0x3e, 0xeb, 0x20, 0xc7, + 0xe9, 0xf7, 0x9f, 0x1b, 0xfc, 0xdf, 0x9c, 0xbc, 0xb5, 0xef, 0xbf, 0x6d, + 0xfd, 0xaf, 0xff, 0x8b, 0x00, 0xdf, 0xfd, 0x3b, 0xbf, 0xf7, 0x7f, 0x6f, + 0x00, 0xcd, 0x73, 0x8f, 0xbb, 0x3b, 0xbd, 0xdf, 0xbf, 0x4f, 0xbf, 0x6f, + 0xfa, 0xdc, 0xb3, 0x8f, 0xb7, 0x93, 0xdf, 0x4f, 0x7e, 0xeb, 0xff, 0xff, + 0x2f, 0xfe, 0xff, 0xdf, 0x7f, 0xcc, 0x88, 0xbc, 0xbf, 0x6c, 0xbd, 0x1b, + 0xe0, 0xcf, 0x5e, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x78, 0xc5, 0x77, 0xc5, + 0xbf, 0x4c, 0xbf, 0x6c, 0x56, 0xc5, 0xbf, 0x4c, 0xbf, 0x6c, 0x59, 0xc5, + 0xbf, 0x4c, 0xbf, 0x6c, 0x5a, 0xc5, 0xbf, 0x4c, 0x46, 0xcd, 0xbd, 0xbd, + 0xbe, 0x4c, 0xbd, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0xc3, 0x87, 0xff, 0xff, + 0xc3, 0x87, 0xff, 0xff, 0x2f, 0xeb, 0xde, 0xeb, 0xff, 0x1f, 0x2b, 0xfe, + 0xff, 0x8b, 0x91, 0x1b, 0xfd, 0xff, 0xff, 0x5c, 0x70, 0x93, 0x9f, 0x7d, + 0x33, 0x8b, 0xdc, 0xa4, 0xbb, 0x8b, 0xdf, 0x5d, 0xbf, 0xc4, 0x05, 0xf4, + 0xfe, 0xeb, 0x6f, 0xeb, 0xde, 0xeb, 0xff, 0x8b, 0xbb, 0xb7, 0x91, 0x1b, + 0xfd, 0xff, 0xbf, 0x5c, 0x9f, 0x7c, 0x33, 0x8b, 0xf6, 0xc4, 0xf8, 0xf7, + 0x91, 0x1b, 0xfd, 0xff, 0xbf, 0x7c, 0xd0, 0xdd, 0x77, 0x8b, 0xf9, 0xfb, + 0x91, 0x1b, 0xfd, 0xff, 0xbf, 0x7c, 0xc9, 0xdd, 0x77, 0x8b, 0x91, 0x1b, + 0xfd, 0xff, 0xbf, 0x5c, 0xbf, 0x7c, 0xff, 0x1b, 0xf0, 0xdf, 0xff, 0x5c, + 0x9f, 0x7c, 0x33, 0x8b, 0xf6, 0xc4, 0xf8, 0xf7, 0x91, 0x1b, 0xfd, 0xff, + 0xbf, 0x7c, 0xd0, 0xdd, 0x77, 0x8b, 0xf9, 0xfb, 0x91, 0x1b, 0xfd, 0xff, + 0xbf, 0x7c, 0xc9, 0xdd, 0x77, 0x8b, 0x91, 0x1b, 0xfd, 0xff, 0xbf, 0x5c, + 0x9f, 0x7c, 0xfe, 0xeb, 0xc3, 0x87, 0xff, 0xff, 0x2e, 0xeb, 0xfe, 0x8a, + 0xf7, 0xb3, 0x00, 0x1c, 0x34, 0x00, 0xef, 0x8b, 0x00, 0x1c, 0x37, 0x00, + 0x6e, 0xeb, 0xff, 0xff, 0x2e, 0xeb, 0xfc, 0x92, 0xe7, 0xb7, 0x00, 0x1c, + 0x3e, 0x00, 0xfb, 0x3b, 0xbf, 0x8f, 0x00, 0x1c, 0x42, 0x00, 0xfb, 0x3b, + 0x7f, 0x8f, 0x00, 0x1c, 0x46, 0x00, 0xef, 0x8b, 0x00, 0x1c, 0x49, 0x00, + 0x6e, 0xeb, 0xff, 0xff, 0x98, 0xef, 0xb7, 0xef, 0xbf, 0x4c, 0x97, 0xef, + 0xbd, 0x6c, 0x5e, 0xc5, 0xbd, 0x4c, 0xbd, 0x6c, 0x5f, 0xc5, 0xbd, 0x4c, + 0xba, 0xef, 0xbf, 0x4c, 0xc3, 0x87, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xbf, + 0xae, 0x1a, 0x33, 0xe5, 0xff, 0xbf, 0xff, 0xbf, 0x00, 0x00, 0xf9, 0xff, + 0x9d, 0xef, 0xff, 0xcd, 0xbd, 0x4c, 0xc3, 0x87, 0xff, 0xbf, 0xff, 0xbf, + 0x2b, 0xeb, 0xcc, 0xe9, 0x8d, 0xed, 0xff, 0xce, 0xda, 0x4c, 0xd9, 0x4c, + 0x5f, 0xcd, 0xbe, 0xbd, 0xfc, 0xe7, 0xff, 0x1f, 0x00, 0xff, 0xdf, 0xca, + 0x72, 0xed, 0xfe, 0xc9, 0xff, 0xcf, 0x00, 0x1c, 0x6c, 0x09, 0xe7, 0x97, + 0xff, 0x8b, 0x9a, 0x6b, 0x9f, 0x3b, 0xdf, 0xf7, 0xfa, 0x4b, 0xff, 0xcf, + 0x00, 0x1c, 0x75, 0x09, 0xe7, 0x97, 0xff, 0x8b, 0x99, 0x6b, 0x9f, 0x3b, + 0xdf, 0xf7, 0xf9, 0x4b, 0xff, 0xd2, 0xab, 0x8a, 0xbf, 0xc2, 0x14, 0xf4, + 0xfc, 0xe4, 0xbe, 0xed, 0x3a, 0x6d, 0x3f, 0x4c, 0xb9, 0x6d, 0xbe, 0x4c, + 0x00, 0xee, 0x1d, 0x4c, 0xc0, 0xee, 0xdc, 0x4c, 0x7f, 0xcd, 0xa7, 0xbd, + 0xbb, 0x4c, 0x7f, 0xc9, 0x30, 0x4c, 0xf0, 0x92, 0xfc, 0x1b, 0x00, 0xff, + 0xd7, 0x6c, 0xb2, 0x6c, 0x7a, 0x93, 0xdd, 0x6c, 0x7a, 0x93, 0xdf, 0x6c, + 0x7a, 0x93, 0xdd, 0x3b, 0xfd, 0xb6, 0xaf, 0x4c, 0xfc, 0xdc, 0xf1, 0x9b, + 0x0b, 0xf4, 0x0a, 0xee, 0xca, 0xee, 0xe9, 0xee, 0xa9, 0xee, 0x48, 0xee, + 0xff, 0xcc, 0x1f, 0x47, 0xec, 0xc4, 0xf5, 0xf7, 0xbe, 0x3b, 0xb8, 0xdf, + 0xbf, 0x3b, 0xd9, 0xdf, 0x27, 0x92, 0x1e, 0x47, 0x2d, 0xee, 0x3d, 0x47, + 0xd8, 0xfb, 0xd8, 0xc8, 0x23, 0x9b, 0xf7, 0xf3, 0xbf, 0x3b, 0xb9, 0xdb, + 0x7a, 0x92, 0x3e, 0x47, 0x31, 0xee, 0x3d, 0x47, 0xe2, 0xfb, 0xc4, 0xc8, + 0x23, 0x9b, 0xf2, 0xf3, 0xfe, 0x3b, 0xd9, 0xdb, 0x77, 0x96, 0x3e, 0x47, + 0xfe, 0x3b, 0xd9, 0xdf, 0x1e, 0x67, 0x27, 0x92, 0x1e, 0x47, 0x37, 0xee, + 0x3d, 0x47, 0xf1, 0xfb, 0xb0, 0xc9, 0x27, 0x9b, 0xf7, 0xf3, 0xbf, 0x3b, + 0xb9, 0xdb, 0x7a, 0x92, 0x3e, 0x47, 0x1b, 0xee, 0x1d, 0x47, 0xfb, 0xfb, + 0xff, 0xc9, 0x3d, 0x47, 0x3e, 0x47, 0x3f, 0x6b, 0x1f, 0x67, 0x07, 0xa0, + 0x5a, 0x3b, 0xf9, 0xb6, 0x27, 0xa0, 0x1e, 0x67, 0x23, 0xa1, 0x1d, 0x67, + 0x23, 0xa1, 0xff, 0xdc, 0x33, 0x8b, 0xfc, 0xdb, 0xaf, 0xc8, 0x31, 0x9a, + 0xf6, 0xf3, 0x3d, 0x38, 0xf8, 0xb6, 0x68, 0x93, 0xdf, 0x47, 0xbc, 0x93, + 0xe0, 0x93, 0xa4, 0x92, 0x47, 0xf8, 0x95, 0xef, 0xbf, 0x6c, 0x37, 0xa1, + 0x3f, 0x4c, 0xbe, 0x6c, 0xb7, 0xa2, 0xbe, 0x4c, 0xbd, 0x6c, 0x57, 0xa2, + 0x5d, 0x4c, 0xbc, 0x6c, 0xf7, 0xa7, 0xfc, 0x4c, 0xbb, 0x6c, 0xd7, 0xa6, + 0xdb, 0x4c, 0xec, 0xe9, 0x6b, 0xeb, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xdf, + 0x3e, 0x2b, 0x91, 0x06, 0xa7, 0x48, 0xd5, 0x1c, 0x0f, 0x1e, 0x2d, 0x3c, + 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x76, 0x54, 0x32, 0x10, + 0xfe, 0xdc, 0xba, 0x98, 0x66, 0x86, 0x7d, 0xa5, 0x5e, 0x14, 0x26, 0x91, + 0x23, 0x43, 0xe4, 0x70, 0x29, 0x3e, 0x9d, 0x35, 0x97, 0xef, 0xbf, 0x6c, + 0xbf, 0x4f, 0xbe, 0x6c, 0xbe, 0x4f, 0xbd, 0x6c, 0xbd, 0x4f, 0xbc, 0x6c, + 0xbc, 0x4f, 0xbb, 0x6c, 0xbb, 0x4f, 0xba, 0x6c, 0xba, 0x4f, 0x99, 0x6c, + 0x99, 0x4f, 0xc3, 0x87, 0xfb, 0xff, 0xff, 0xdf, 0xbf, 0xc6, 0xfc, 0xf7, + 0xff, 0x3f, 0xdf, 0xd3, 0xbf, 0xc7, 0xfd, 0xf7, 0xc3, 0x87, 0x3d, 0xeb, + 0xbc, 0x92, 0xba, 0x92, 0x1f, 0x38, 0x7f, 0xd7, 0xfc, 0xf3, 0xfd, 0x93, + 0xff, 0xdf, 0x1e, 0x38, 0x7f, 0xd7, 0xfc, 0xf3, 0xb9, 0x93, 0xff, 0xde, + 0xfe, 0xcd, 0x3c, 0x93, 0xfc, 0x3b, 0xbb, 0x83, 0x6f, 0x8f, 0xef, 0x8f, + 0x38, 0x93, 0xfc, 0x3b, 0xbb, 0x83, 0xff, 0xdb, 0x3c, 0x93, 0x2e, 0x8f, + 0xed, 0x92, 0xdf, 0xdb, 0x6f, 0x8f, 0xef, 0x8f, 0xbf, 0xc5, 0xf6, 0xf3, + 0xff, 0x3b, 0xdf, 0xb3, 0x32, 0x9f, 0xb3, 0x9b, 0xfd, 0xf3, 0x39, 0x9f, + 0x76, 0x9f, 0x06, 0xf0, 0xf4, 0x93, 0xb0, 0x93, 0xfa, 0x3b, 0xda, 0xb3, + 0xfa, 0xf3, 0xfd, 0x93, 0xff, 0xdf, 0xb9, 0x93, 0xff, 0xde, 0x7d, 0xeb, + 0xbf, 0xc5, 0xda, 0xf3, 0xbc, 0x90, 0x7f, 0x1a, 0xfc, 0xdf, 0xb3, 0x14, + 0xff, 0xff, 0xdf, 0xf3, 0xd2, 0x23, 0xff, 0xff, 0xff, 0xd5, 0xbf, 0xc5, + 0xe5, 0xf3, 0x52, 0x1a, 0xff, 0xff, 0x72, 0x1a, 0xfc, 0xdf, 0xb3, 0x14, + 0xff, 0xff, 0xeb, 0xf3, 0xd2, 0x23, 0xff, 0xff, 0xff, 0xd5, 0xbf, 0xc5, + 0xf1, 0xf3, 0x52, 0x1a, 0xff, 0xff, 0x72, 0x1a, 0xfc, 0xdf, 0xb3, 0x14, + 0xff, 0xff, 0xf7, 0xf3, 0xd2, 0x23, 0xff, 0xff, 0xff, 0xd5, 0x52, 0x1a, + 0xff, 0xff, 0xfd, 0xfb, 0xc3, 0x87, 0x97, 0xbe, 0xb3, 0x93, 0x8f, 0xbe, + 0xb3, 0x93, 0xd0, 0xc5, 0xf1, 0xf7, 0xd2, 0x23, 0xff, 0xdf, 0xd2, 0x23, + 0xfe, 0xdf, 0xd2, 0x23, 0xfd, 0xdf, 0xd2, 0x23, 0xfc, 0xdf, 0xf0, 0xd5, + 0x52, 0x1a, 0xf0, 0xff, 0xd0, 0xc5, 0x0b, 0xf0, 0xdc, 0xc5, 0xf7, 0xf7, + 0xfc, 0xd5, 0xd2, 0x23, 0xff, 0xdf, 0x52, 0x1a, 0xfc, 0xff, 0xdc, 0xc5, + 0x05, 0xf0, 0xbf, 0xc5, 0x1d, 0xf0, 0xff, 0xd5, 0xd2, 0x23, 0xff, 0xff, + 0xbf, 0xc5, 0x22, 0xf0, 0xff, 0xd5, 0xd2, 0x23, 0xfe, 0xff, 0xbf, 0xc5, + 0x27, 0xf0, 0xd2, 0x23, 0xfd, 0xff, 0xc3, 0x87, 0xbc, 0x93, 0xff, 0x1b, + 0xfc, 0xdf, 0xbf, 0xc7, 0xf7, 0xf3, 0xff, 0xcf, 0xbf, 0x7e, 0xbf, 0xc5, + 0xe9, 0xf3, 0xff, 0xde, 0xff, 0xdf, 0x04, 0xf8, 0xbf, 0x6e, 0xf4, 0x97, + 0xfb, 0xf3, 0xfc, 0xde, 0xfc, 0xdf, 0x04, 0xf8, 0xfd, 0x3b, 0xfc, 0x8e, + 0xf5, 0xf3, 0xff, 0xdf, 0xfd, 0x3b, 0x7c, 0x8f, 0xf9, 0xf3, 0xff, 0xdf, + 0xfd, 0x3b, 0xbc, 0x8f, 0xfd, 0xf3, 0xff, 0xdf, 0xc3, 0x87, 0xff, 0xff, + 0xfe, 0xff, 0xff, 0xff, 0x07, 0xb8, 0xff, 0xff, 0xfd, 0xfe, 0xff, 0xff, + 0xff, 0xb7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x8e, 0xed, 0xff, 0x91, 0xff, 0xff, 0x9b, 0x54, 0xae, 0xf5, 0xff, 0xff, + 0xbc, 0x2f, 0xff, 0xff, 0xdd, 0xff, 0xc5, 0xff, 0xfc, 0xfe, 0xff, 0xff, + 0xf7, 0xb7, 0xff, 0xff, 0xfb, 0xfe, 0xff, 0xff, 0xb3, 0xb7, 0xff, 0xff, + 0xfa, 0xfd, 0xff, 0xff, 0xaf, 0xb7, 0xff, 0xff, 0xf9, 0xfd, 0xff, 0xff, + 0xab, 0xb7, 0xff, 0xff, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, + 0xf7, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xf6, 0xfe, 0xff, 0xff, + 0xa7, 0xb7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xdf, 0xfd, 0xce, 0xff, 0xf8, 0xcf, 0xff, 0xff, 0xf8, 0xce, 0xff, 0xff, + 0xdf, 0xff, 0xfc, 0xff, 0xff, 0xea, 0xff, 0xff, 0x11, 0xe9, 0xff, 0xff, + 0xb9, 0xea, 0xff, 0xff, 0x25, 0xea, 0xff, 0xff, 0x1d, 0xea, 0xff, 0xff, + 0xe7, 0xee, 0xff, 0xff, 0x7f, 0xeb, 0x59, 0xeb, 0x3f, 0xcd, 0x59, 0xf5, + 0x72, 0xf5, 0x72, 0xeb, 0x72, 0xe1, 0x72, 0xd7, 0x72, 0xcd, 0x72, 0xc3, + 0x59, 0xd7, 0x59, 0xd7, 0x67, 0xaf, 0x67, 0xd7, 0x72, 0xeb, 0x72, 0xf5, + 0x72, 0xff, 0x72, 0xff, 0x72, 0xf5, 0x72, 0xeb, 0x72, 0xeb, 0x72, 0xeb, + 0x72, 0xeb, 0x72, 0xeb, 0x72, 0xeb, 0xff, 0xff, 0x77, 0xec, 0xff, 0xff, + 0xb8, 0xfc, 0xff, 0xff, 0xef, 0xd8, 0xff, 0xff, 0x5b, 0xfe, 0xff, 0xff, + 0xef, 0xd8, 0xff, 0xff, 0x91, 0x5c, 0xfe, 0xff, 0xdf, 0xb1, 0xff, 0xff, + 0x48, 0x2e, 0xff, 0xff, 0xab, 0xe6, 0xff, 0xff, 0x5d, 0xe4, 0xff, 0xff, + 0x5d, 0xe4, 0xff, 0xff, 0x5d, 0xe4, 0xff, 0xff, 0x5d, 0xe4, 0xff, 0xff, + 0x5d, 0xe4, 0xff, 0xff, 0x5d, 0xe4, 0xff, 0xff, 0x5d, 0xe4, 0xff, 0xff, + 0x5d, 0xe4, 0xff, 0xff, 0x5d, 0xe4, 0xff, 0xff, 0x81, 0xe6, 0xff, 0xff, + 0x6f, 0xe6, 0xff, 0xff, 0xdf, 0xe4, 0xff, 0xff, 0x6f, 0xe6, 0xff, 0xff, + 0xdf, 0xe4, 0xff, 0xff, 0xdf, 0xe4, 0xff, 0xff, 0xdf, 0xe4, 0xff, 0xff, + 0xe7, 0xe5, 0xff, 0xff, 0xc7, 0xe5, 0xff, 0xff, 0x8b, 0xe5, 0xff, 0xff, + 0x81, 0xe5, 0xff, 0xff, 0x5d, 0xe4, 0xff, 0xff, 0x5d, 0xe4, 0xff, 0xff, + 0x5d, 0xe4, 0xff, 0xff, 0x5d, 0xe4, 0xff, 0xff, 0x25, 0xe5, 0xff, 0xff, + 0x5d, 0xe5, 0xff, 0xff, 0x51, 0xe5, 0xff, 0xff, 0x45, 0xe5, 0xff, 0xff, + 0x01, 0xe3, 0xff, 0xff, 0x2d, 0xe3, 0xff, 0xff, 0x01, 0xe3, 0xff, 0xff, + 0x01, 0xe3, 0xff, 0xff, 0x81, 0xe3, 0xff, 0xff, 0x73, 0xe3, 0xff, 0xff, + 0x5f, 0xe3, 0xff, 0xff, 0x57, 0xe3, 0xff, 0xff, 0x19, 0xe3, 0xff, 0xff, + 0x19, 0xe3, 0xff, 0xff, 0x19, 0xe3, 0xff, 0xff, 0x01, 0xe3, 0xff, 0xff, + 0x41, 0xe3, 0xff, 0xff, 0x19, 0xe3, 0xff, 0xff, 0x01, 0xe3, 0xff, 0xff, + 0x39, 0xe3, 0xff, 0xff, 0x89, 0xe3, 0xff, 0xff, 0x3b, 0xe0, 0xff, 0xff, + 0xb5, 0xe1, 0xff, 0xff, 0x3b, 0xe0, 0xff, 0xff, 0x45, 0xe2, 0xff, 0xff, + 0x31, 0xe2, 0xff, 0xff, 0xf5, 0xe1, 0xff, 0xff, 0x11, 0xe2, 0xff, 0xff, + 0xd5, 0xe1, 0xff, 0xff, 0x09, 0xe1, 0xff, 0xff, 0x6d, 0xe1, 0xff, 0xff, + 0x6d, 0xe1, 0xff, 0xff, 0xad, 0xe0, 0xff, 0xff, 0x95, 0xe0, 0xff, 0xff, + 0x41, 0xe1, 0xff, 0xff, 0x3b, 0xe0, 0xff, 0xff, 0x63, 0xe0, 0xff, 0xff, + 0x67, 0xe2, 0xff, 0xff, 0xd1, 0xdf, 0xff, 0xff, 0x71, 0xde, 0xff, 0xff, + 0x71, 0xde, 0xff, 0xff, 0x71, 0xde, 0xff, 0xff, 0xbb, 0xde, 0xff, 0xff, + 0x49, 0xdf, 0xff, 0xff, 0x85, 0xde, 0xff, 0xff, 0x85, 0xde, 0xff, 0xff, + 0x99, 0xde, 0xff, 0xff, 0xd3, 0xde, 0xff, 0xff, 0x71, 0xde, 0xff, 0xff, + 0x09, 0xdf, 0xff, 0xff, 0xc7, 0xde, 0xff, 0xff, 0xb3, 0xde, 0xff, 0xff, + 0x85, 0xde, 0xff, 0xff, 0x85, 0xde, 0xff, 0xff, 0x8f, 0xde, 0xff, 0xff, + 0xcf, 0xdc, 0xff, 0xff, 0x75, 0xdb, 0xff, 0xff, 0x75, 0xdb, 0xff, 0xff, + 0x75, 0xdb, 0xff, 0xff, 0xd5, 0xdb, 0xff, 0xff, 0x47, 0xdc, 0xff, 0xff, + 0x89, 0xdb, 0xff, 0xff, 0x89, 0xdb, 0xff, 0xff, 0xb3, 0xdb, 0xff, 0xff, + 0xed, 0xdb, 0xff, 0xff, 0x75, 0xdb, 0xff, 0xff, 0x23, 0xdc, 0xff, 0xff, + 0xe1, 0xdb, 0xff, 0xff, 0xcd, 0xdb, 0xff, 0xff, 0x89, 0xdb, 0xff, 0xff, + 0x89, 0xdb, 0xff, 0xff, 0x93, 0xdb, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, + 0x17, 0xff, 0xff, 0xdf, 0xfd, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xdf, + 0x7b, 0xf6, 0xff, 0xff, 0xd3, 0xf6, 0xff, 0xff, 0x8f, 0xf9, 0xff, 0xff, + 0xb3, 0xf8, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0xdf, 0xfe, 0xeb, 0xff, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, + 0x89, 0xab, 0xcd, 0xef, 0x0f, 0x1e, 0x2d, 0x3c, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -2735,7 +2734,8 @@ u8 fw_data_rx[18424] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xbb, 0xe1, 0xbb, 0xc8, 0xc5, 0xb9, 0xc8, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb1, 0xaa, 0xe9, 0xe6, - 0xdf, 0xb5, 0xcd, 0xea + 0xad, 0xa7, 0xd2, 0xb0, 0x00, 0x00 }; From 992549aa49b1769a630a0af4b9e3e05e803cb6d4 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Tue, 6 Jul 2021 02:47:50 +0200 Subject: [PATCH 086/226] drivers: power: supply: Import Xiaomi changes * From cepheus-q-oss + vayu-r-oss + nabu-r-oss Change-Id: Ib40c0b88fcbcc6df3215dd37ada30cf642758b1e Signed-off-by: firebird11 --- drivers/power/supply/power_supply_core.c | 4 + drivers/power/supply/power_supply_leds.c | 2 + drivers/power/supply/power_supply_sysfs.c | 257 ++ drivers/power/supply/qcom/battery.c | 27 + drivers/power/supply/qcom/fg-alg.c | 23 + drivers/power/supply/qcom/fg-alg.h | 3 + drivers/power/supply/qcom/fg-core.h | 97 + drivers/power/supply/qcom/fg-util.c | 18 + drivers/power/supply/qcom/qpnp-fg-gen4.c | 1541 +++++++ drivers/power/supply/qcom/qpnp-qg.c | 8 + drivers/power/supply/qcom/qpnp-smb5.c | 2285 +++++++++- drivers/power/supply/qcom/smb1390-charger.c | 128 + drivers/power/supply/qcom/smb5-lib.c | 4377 ++++++++++++++++++- drivers/power/supply/qcom/smb5-lib.h | 626 +++ drivers/power/supply/qcom/smb5-reg.h | 46 + drivers/power/supply/qcom/step-chg-jeita.c | 458 ++ drivers/power/supply/qcom/step-chg-jeita.h | 27 + include/linux/power_supply.h | 166 + 18 files changed, 9719 insertions(+), 374 deletions(-) diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index cf7ec189a71b..eec3174898a9 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -358,7 +358,11 @@ static int __power_supply_is_system_supplied(struct device *dev, void *data) return 0; (*count)++; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if ((psy->desc->type != POWER_SUPPLY_TYPE_BATTERY) && (psy->desc->type != POWER_SUPPLY_TYPE_BMS)) +#else if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY) +#endif if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &ret)) return ret.intval; diff --git a/drivers/power/supply/power_supply_leds.c b/drivers/power/supply/power_supply_leds.c index 9188b7ccdd4c..7585ec444272 100644 --- a/drivers/power/supply/power_supply_leds.c +++ b/drivers/power/supply/power_supply_leds.c @@ -114,6 +114,7 @@ static void power_supply_remove_bat_triggers(struct power_supply *psy) static void power_supply_update_gen_leds(struct power_supply *psy) { +#ifndef CONFIG_MACH_XIAOMI_SM8150 union power_supply_propval online; if (power_supply_get_property(psy, POWER_SUPPLY_PROP_ONLINE, &online)) @@ -125,6 +126,7 @@ static void power_supply_update_gen_leds(struct power_supply *psy) led_trigger_event(psy->online_trig, LED_FULL); else led_trigger_event(psy->online_trig, LED_OFF); +#endif } static int power_supply_create_gen_triggers(struct power_supply *psy) diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index 58d89585bb90..7680bc49495b 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -47,6 +47,12 @@ static const char * const power_supply_type_text[] = { "USB_HVDCP", "USB_HVDCP_3", "USB_HVDCP_3P5", "Wireless", "USB_FLOAT", "BMS", "Parallel", "Main", "Wipower", "USB_C_UFP", "USB_C_DFP", "Charge_Pump", +#ifdef CONFIG_MACH_XIAOMI_SM8150 + "ZIMI_CAR_POWER", +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + "Batt_Verify", +#endif +#endif }; static const char * const power_supply_status_text[] = { @@ -162,8 +168,69 @@ static ssize_t power_supply_show_property(struct device *dev, else if (off >= POWER_SUPPLY_PROP_MODEL_NAME) return sprintf(buf, "%s\n", value.strval); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + else if ((off == POWER_SUPPLY_PROP_ROMID) || (off == POWER_SUPPLY_PROP_DS_STATUS)) + return scnprintf(buf, PAGE_SIZE, "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + value.arrayval[0], value.arrayval[1], value.arrayval[2], value.arrayval[3], + value.arrayval[4], value.arrayval[5], value.arrayval[6], value.arrayval[7]); + else if ((off == POWER_SUPPLY_PROP_PAGE0_DATA) || + (off == POWER_SUPPLY_PROP_PAGE1_DATA) || + (off == POWER_SUPPLY_PROP_PAGEDATA)) + return scnprintf(buf, PAGE_SIZE, "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", + value.arrayval[0], value.arrayval[1], value.arrayval[2], value.arrayval[3], + value.arrayval[4], value.arrayval[5], value.arrayval[6], value.arrayval[7], + value.arrayval[8], value.arrayval[9], value.arrayval[10], value.arrayval[11], + value.arrayval[12], value.arrayval[13], value.arrayval[14], value.arrayval[15]); + else if (off == POWER_SUPPLY_PROP_VERIFY_MODEL_NAME) + return sprintf(buf, "%s\n", value.strval); +#endif if (off == POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT) return sprintf(buf, "%lld\n", value.int64val); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + else if (off == POWER_SUPPLY_PROP_WIRELESS_VERSION) + return scnprintf(buf, PAGE_SIZE, "0x%x\n", + value.intval); + else if (off == POWER_SUPPLY_PROP_WIRELESS_WAKELOCK) + return scnprintf(buf, PAGE_SIZE, "%d\n", + value.intval); + else if (off == POWER_SUPPLY_PROP_SIGNAL_STRENGTH) + return scnprintf(buf, PAGE_SIZE, "%d\n", + value.intval); + else if (off == POWER_SUPPLY_PROP_WIRELESS_CP_EN) + return scnprintf(buf, PAGE_SIZE, "%d\n", + value.intval); + else if (off == POWER_SUPPLY_PROP_TYPE_RECHECK) + return scnprintf(buf, PAGE_SIZE, "0x%x\n", + value.intval); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + else if (off == POWER_SUPPLY_PROP_TX_MAC) + return scnprintf(buf, PAGE_SIZE, "%llx\n", + value.int64val); +#ifdef CONFIG_MACH_XIAOMI_NABU + else if (off == POWER_SUPPLY_PROP_PEN_MAC) + return scnprintf(buf, PAGE_SIZE, "%llx\n", + value.int64val); + else if (off == POWER_SUPPLY_PROP_REVERSE_PEN_SOC) + return scnprintf(buf, PAGE_SIZE, "%d\n", + value.intval); + else if (off == POWER_SUPPLY_PROP_REVERSE_CHG_STATE) + return scnprintf(buf, PAGE_SIZE, "%d\n", + value.intval); + else if (off == POWER_SUPPLY_PROP_REVERSE_PEN_CHG_STATE) + return scnprintf(buf, PAGE_SIZE, "%d\n", + value.intval); +#endif + else if (off == POWER_SUPPLY_PROP_RX_CR) + return scnprintf(buf, PAGE_SIZE, "%llx\n", + value.int64val); + else if (off == POWER_SUPPLY_PROP_RX_CEP) + return scnprintf(buf, PAGE_SIZE, "%llx\n", + value.int64val); + else if (off == POWER_SUPPLY_PROP_BT_STATE) + return scnprintf(buf, PAGE_SIZE, "%x\n", + value.intval); +#endif +#endif else return sprintf(buf, "%d\n", value.intval); } @@ -175,6 +242,10 @@ static ssize_t power_supply_store_property(struct device *dev, struct power_supply *psy = dev_get_drvdata(dev); const ptrdiff_t off = attr - power_supply_attrs; union power_supply_propval value; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + long val; + int64_t num_long; +#endif /* maybe it is a enum property? */ switch (off) { @@ -196,6 +267,46 @@ static ssize_t power_supply_store_property(struct device *dev, case POWER_SUPPLY_PROP_SCOPE: ret = sysfs_match_string(power_supply_scope_text, buf); break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_BT_STATE: + case POWER_SUPPLY_PROP_RX_CR: + ret = kstrtol(buf, 16, &val); + if (ret < 0) + return ret; + ret = val; + break; + case POWER_SUPPLY_PROP_RX_CEP: + ret = kstrtol(buf, 16, &val); + if (ret < 0) + return ret; + ret = val; + break; + case POWER_SUPPLY_PROP_TX_MAC: + ret = kstrtoll(buf, 16, &num_long); + if (ret < 0) + return ret; + value.int64val = num_long; + ret = power_supply_set_property(psy, off, &value); + if (ret < 0) + return ret; + else + return count; + break; +#ifdef CONFIG_MACH_XIAOMI_NABU + case POWER_SUPPLY_PROP_PEN_MAC: + ret = kstrtoll(buf, 16, &num_long); + if (ret < 0) + return ret; + value.int64val = num_long; + ret = power_supply_set_property(psy, off, &value); + if (ret < 0) + return ret; + else + return count; + + break; +#endif +#endif default: ret = -EINVAL; } @@ -255,6 +366,10 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(charge_now), POWER_SUPPLY_ATTR(charge_avg), POWER_SUPPLY_ATTR(charge_counter), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_ATTR(termination_current), + POWER_SUPPLY_ATTR(ffc_termination_current), +#endif POWER_SUPPLY_ATTR(constant_charge_current), POWER_SUPPLY_ATTR(constant_charge_current_max), POWER_SUPPLY_ATTR(constant_charge_voltage), @@ -272,6 +387,14 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(capacity_alert_min), POWER_SUPPLY_ATTR(capacity_alert_max), POWER_SUPPLY_ATTR(capacity_level), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_ATTR(shutdown_delay), + POWER_SUPPLY_ATTR(shutdown_delay_en), + POWER_SUPPLY_ATTR(raw_capacity), + POWER_SUPPLY_ATTR(soc_decimal), + POWER_SUPPLY_ATTR(soc_decimal_rate), + POWER_SUPPLY_ATTR(cold_thermal_level), +#endif POWER_SUPPLY_ATTR(temp), POWER_SUPPLY_ATTR(temp_max), POWER_SUPPLY_ATTR(temp_min), @@ -295,6 +418,10 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(charge_enabled), POWER_SUPPLY_ATTR(set_ship_mode), POWER_SUPPLY_ATTR(real_type), +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_ATTR(hvdcp3_type), + POWER_SUPPLY_ATTR(quick_charge_type), +#endif POWER_SUPPLY_ATTR(charge_now_raw), POWER_SUPPLY_ATTR(charge_now_error), POWER_SUPPLY_ATTR(capacity_raw), @@ -305,6 +432,10 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(pin_enabled), POWER_SUPPLY_ATTR(input_suspend), POWER_SUPPLY_ATTR(input_voltage_regulation), +#ifdef CONFIG_MACH_XIAOMI_NABU + POWER_SUPPLY_ATTR(input_voltage_vrect), + POWER_SUPPLY_ATTR(rx_iout), +#endif POWER_SUPPLY_ATTR(input_current_max), POWER_SUPPLY_ATTR(input_current_trim), POWER_SUPPLY_ATTR(input_current_settled), @@ -333,6 +464,9 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(flash_trigger), POWER_SUPPLY_ATTR(force_tlim), POWER_SUPPLY_ATTR(dp_dm), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_ATTR(dp_dm_bq), +#endif POWER_SUPPLY_ATTR(input_current_limited), POWER_SUPPLY_ATTR(input_current_now), POWER_SUPPLY_ATTR(charge_qnovo_enable), @@ -349,8 +483,17 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(typec_src_rp), POWER_SUPPLY_ATTR(pd_allowed), POWER_SUPPLY_ATTR(pd_active), +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_ATTR(pd_authentication), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_ATTR(pd_remove_compensation), +#endif +#endif POWER_SUPPLY_ATTR(pd_in_hard_reset), POWER_SUPPLY_ATTR(pd_current_max), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_ATTR(apdo_max), +#endif POWER_SUPPLY_ATTR(pd_usb_suspend_supported), POWER_SUPPLY_ATTR(charger_temp), POWER_SUPPLY_ATTR(charger_temp_max), @@ -363,6 +506,10 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(parallel_mode), POWER_SUPPLY_ATTR(die_health), POWER_SUPPLY_ATTR(connector_health), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_ATTR(connector_temp), + POWER_SUPPLY_ATTR(vbus_disable), +#endif POWER_SUPPLY_ATTR(ctm_current_max), POWER_SUPPLY_ATTR(hw_current_max), POWER_SUPPLY_ATTR(pr_swap), @@ -372,15 +519,75 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(pd_voltage_max), POWER_SUPPLY_ATTR(pd_voltage_min), POWER_SUPPLY_ATTR(sdp_current_max), +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_ATTR(dc_thermal_levels), +#endif POWER_SUPPLY_ATTR(connector_type), POWER_SUPPLY_ATTR(parallel_batfet_mode), POWER_SUPPLY_ATTR(parallel_fcc_max), +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_ATTR(wireless_version), +#ifdef CONFIG_MACH_XIAOMI_NABU + POWER_SUPPLY_ATTR(wireless_fw_version), +#endif + POWER_SUPPLY_ATTR(signal_strength), + POWER_SUPPLY_ATTR(wireless_cp_en), + POWER_SUPPLY_ATTR(wireless_power_good_en), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_ATTR(sw_disabel_dc_en), +#endif + POWER_SUPPLY_ATTR(wireless_wakelock), +#ifdef CONFIG_MACH_XIAOMI_NABU + POWER_SUPPLY_ATTR(wireless_tx_id), +#endif + POWER_SUPPLY_ATTR(tx_adapter), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_ATTR(tx_mac), + POWER_SUPPLY_ATTR(rx_cr), + POWER_SUPPLY_ATTR(rx_cep), + POWER_SUPPLY_ATTR(bt_state), +#endif +#ifdef CONFIG_MACH_XIAOMI_NABU + POWER_SUPPLY_ATTR(pen_mac), +#endif +#endif POWER_SUPPLY_ATTR(min_icl), POWER_SUPPLY_ATTR(moisture_detected), POWER_SUPPLY_ATTR(batt_profile_version), POWER_SUPPLY_ATTR(batt_full_current), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_ATTR(battery_charging_limited), + POWER_SUPPLY_ATTR(slowly_charging), + POWER_SUPPLY_ATTR(bq_input_suspend), +#endif POWER_SUPPLY_ATTR(recharge_soc), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_ATTR(recharge_vbat), + POWER_SUPPLY_ATTR(sys_termination_current), + POWER_SUPPLY_ATTR(ffc_sys_termination_current), + POWER_SUPPLY_ATTR(vbatt_full_vol), + POWER_SUPPLY_ATTR(fcc_vbatt_full_vol), + POWER_SUPPLY_ATTR(ki_coeff_current), + /* battery verify properties */ + POWER_SUPPLY_ATTR(romid), + POWER_SUPPLY_ATTR(ds_status), + POWER_SUPPLY_ATTR(pagenumber), + POWER_SUPPLY_ATTR(pagedata), + POWER_SUPPLY_ATTR(authen_result), + POWER_SUPPLY_ATTR(session_seed), + POWER_SUPPLY_ATTR(s_secret), + POWER_SUPPLY_ATTR(challenge), + POWER_SUPPLY_ATTR(auth_anon), + POWER_SUPPLY_ATTR(auth_bdconst), + POWER_SUPPLY_ATTR(page0_data), + POWER_SUPPLY_ATTR(page1_data), + POWER_SUPPLY_ATTR(verify_model_name), + POWER_SUPPLY_ATTR(maxim_batt_cycle_count), +#endif POWER_SUPPLY_ATTR(hvdcp_opti_allowed), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_ATTR(fastcharge_mode), +#endif POWER_SUPPLY_ATTR(smb_en_mode), POWER_SUPPLY_ATTR(smb_en_reason), POWER_SUPPLY_ATTR(esr_actual), @@ -390,6 +597,11 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(force_recharge), POWER_SUPPLY_ATTR(fcc_stepper_enable), POWER_SUPPLY_ATTR(toggle_stat), +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_ATTR(type_recheck), + POWER_SUPPLY_ATTR(liquid_detection), + POWER_SUPPLY_ATTR(dynamic_fv_enabled), +#endif POWER_SUPPLY_ATTR(main_fcc_max), POWER_SUPPLY_ATTR(fg_reset), POWER_SUPPLY_ATTR(qc_opti_disable), @@ -397,6 +609,9 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(batt_age_level), POWER_SUPPLY_ATTR(voltage_vph), POWER_SUPPLY_ATTR(chip_version), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_ATTR(chip_ok), +#endif POWER_SUPPLY_ATTR(therm_icl_limit), POWER_SUPPLY_ATTR(dc_reset), POWER_SUPPLY_ATTR(scale_mode_en), @@ -421,8 +636,50 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(cp_toggle_switcher), POWER_SUPPLY_ATTR(cp_irq_status), POWER_SUPPLY_ATTR(cp_ilim), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_ATTR(step_index), + /* Bq charge pump properties */ + POWER_SUPPLY_ATTR(ti_battery_present), + POWER_SUPPLY_ATTR(ti_vbus_present), + POWER_SUPPLY_ATTR(ti_battery_voltage), + POWER_SUPPLY_ATTR(ti_battery_current), + POWER_SUPPLY_ATTR(ti_battery_temperature), + POWER_SUPPLY_ATTR(ti_bus_voltage), + POWER_SUPPLY_ATTR(ti_bus_current), + POWER_SUPPLY_ATTR(ti_bus_temperature), + POWER_SUPPLY_ATTR(ti_die_temperature), + POWER_SUPPLY_ATTR(ti_alarm_status), + POWER_SUPPLY_ATTR(ti_fault_status), + POWER_SUPPLY_ATTR(ti_reg_status), + POWER_SUPPLY_ATTR(ti_set_bus_protection_for_qc3), + POWER_SUPPLY_ATTR(ti_bus_error_status), + POWER_SUPPLY_ATTR(ti_charge_mode), + POWER_SUPPLY_ATTR(ti_bypass_mode_enable), +#endif POWER_SUPPLY_ATTR(irq_status), POWER_SUPPLY_ATTR(parallel_output_mode), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* DIV 2 properties */ + POWER_SUPPLY_ATTR(div_2_mode), + POWER_SUPPLY_ATTR(reverse_chg_mode), + POWER_SUPPLY_ATTR(reverse_chg_state), +#ifdef CONFIG_MACH_XIAOMI_NABU + POWER_SUPPLY_ATTR(reverse_pen_chg_state), + POWER_SUPPLY_ATTR(reverse_gpio_state), +#endif + POWER_SUPPLY_ATTR(reset_div_2_mode), +#ifdef CONFIG_MACH_XIAOMI_NABU + POWER_SUPPLY_ATTR(aicl_enable), + POWER_SUPPLY_ATTR(otg_state), + POWER_SUPPLY_ATTR(reverse_chg_hall3), + POWER_SUPPLY_ATTR(reverse_chg_hall4), + POWER_SUPPLY_ATTR(reverse_pen_soc), + POWER_SUPPLY_ATTR(reverse_vout), + POWER_SUPPLY_ATTR(reverse_iout), +#endif + POWER_SUPPLY_ATTR(rx_op_ble), + POWER_SUPPLY_ATTR(op_ble), +#endif /* Local extensions of type int64_t */ POWER_SUPPLY_ATTR(charge_counter_ext), /* Properties of type `const char *' */ diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c index 0c6a11b6961a..327357ecc34e 100644 --- a/drivers/power/supply/qcom/battery.c +++ b/drivers/power/supply/qcom/battery.c @@ -1348,6 +1348,33 @@ static int usb_icl_vote_callback(struct votable *votable, void *data, == POWER_SUPPLY_PL_USBMID_USBMID) cp_configure_ilim(chip, ICL_CHANGE_VOTER, icl_ua); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (!chip->usb_psy) + chip->usb_psy = power_supply_get_by_name("usb"); + if (!chip->usb_psy) { + pr_err("Couldn't get usb psy\n"); + return -ENODEV; + } + + rc = power_supply_get_property(chip->usb_psy, + POWER_SUPPLY_PROP_SMB_EN_REASON, &pval); + if (rc < 0) { + pr_err("Couldn't get cp reason rc=%d\n", rc); + return rc; + } + + if (chip->cp_ilim_votable) { + if (pval.intval != POWER_SUPPLY_CP_WIRELESS) + vote(chip->cp_ilim_votable, ICL_CHANGE_VOTER, true, icl_ua); + else + vote(chip->cp_ilim_votable, ICL_CHANGE_VOTER, false, 0); + } + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + cp_configure_ilim(chip, ICL_CHANGE_VOTER, icl_ua); +#endif +#endif + return 0; } diff --git a/drivers/power/supply/qcom/fg-alg.c b/drivers/power/supply/qcom/fg-alg.c index c27f1d481cf3..f9283c86982d 100644 --- a/drivers/power/supply/qcom/fg-alg.c +++ b/drivers/power/supply/qcom/fg-alg.c @@ -277,6 +277,29 @@ int get_cycle_counts(struct cycle_counter *counter, const char **buf) return 0; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +/** + * set_cycle_count - + * @counter: Cycle counter object + * @value: The cycle count value to be set + * + * Get average cycle count for all buckets + * + */ +int set_cycle_count(struct cycle_counter *counter, u16 count) +{ + int rc, id; + + for (id = 0; id < BUCKET_COUNT; id++) { + rc = counter->store_count(counter->data, &count, id, 2); + if (rc < 0) + pr_err("failed to clear cycle counter rc=%d\n", rc); + } + + return 0; +} +#endif + /** * cycle_count_init - * @counter: Cycle counter object diff --git a/drivers/power/supply/qcom/fg-alg.h b/drivers/power/supply/qcom/fg-alg.h index 0bf466cce465..4a84d76dba1e 100644 --- a/drivers/power/supply/qcom/fg-alg.h +++ b/drivers/power/supply/qcom/fg-alg.h @@ -157,6 +157,9 @@ void cycle_count_update(struct cycle_counter *counter, int batt_soc, int charge_status, bool charge_done, bool input_present); int get_cycle_count(struct cycle_counter *counter, int *count); int get_cycle_counts(struct cycle_counter *counter, const char **buf); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int set_cycle_count(struct cycle_counter *counter, u16 count); +#endif int cycle_count_init(struct cycle_counter *counter); void cap_learning_abort(struct cap_learning *cl); void cap_learning_update(struct cap_learning *cl, int batt_temp, diff --git a/drivers/power/supply/qcom/fg-core.h b/drivers/power/supply/qcom/fg-core.h index 267cdaf3b926..23d8256484e6 100644 --- a/drivers/power/supply/qcom/fg-core.h +++ b/drivers/power/supply/qcom/fg-core.h @@ -92,12 +92,26 @@ #define FULL_CAPACITY 100 #define FULL_SOC_RAW 255 +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define FULL_SOC_REPORT_THR 250 +#endif #define DEBUG_BATT_SOC 67 #define BATT_MISS_SOC 50 #define ESR_SOH_SOC 50 #define EMPTY_SOC 0 +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define VBAT_RESTART_FG_EMPTY_UV 3700000 +#define TEMP_THR_RESTART_FG 150 +#define RESTART_FG_START_WORK_MS 1000 +#define RESTART_FG_WORK_MS 2000 +#define EMPTY_REPORT_SOC 1 + +#define VBAT_CRITICAL_LOW_THR 2800 +#define EMPTY_DEBOUNCE_TIME_COUNT_MAX 5 +#endif + enum prof_load_status { PROFILE_MISSING, PROFILE_LOADED, @@ -332,12 +346,23 @@ struct fg_batt_props { char *batt_profile; int float_volt_uv; int vbatt_full_mv; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int ffc_vbatt_full_mv; +#endif int fastchg_curr_ma; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int nom_cap_uah; +#endif int *therm_coeffs; int therm_ctr_offset; int therm_pull_up_kohms; int *rslow_normal_coeffs; int *rslow_low_coeffs; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int ffc_term_curr_ma; + int ffc_low_temp_term_curr_ma; + int ffc_high_temp_term_curr_ma; +#endif }; struct fg_cyc_ctr_data { @@ -421,6 +446,24 @@ static const struct fg_pt fg_tsmc_osc_table[] = { { 90, 444992 }, }; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define BATT_MA_AVG_SAMPLES 8 +struct batt_params { + bool update_now; + int batt_raw_soc; + int batt_soc; + int samples_num; + int samples_index; + int batt_ma_avg_samples[BATT_MA_AVG_SAMPLES]; + int batt_ma_avg; + int batt_ma_prev; + int batt_ma; + int batt_mv; + int batt_temp; + struct timespec last_soc_change_time; +}; +#endif + struct fg_memif { struct fg_dma_address *addr_map; int num_partitions; @@ -428,6 +471,15 @@ struct fg_memif { u8 num_bytes_per_word; }; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +struct cold_thermal { + int index; + int temp_l; + int temp_h; + int curr_th; +}; +#endif + struct fg_dev { struct thermal_zone_device *tz_dev; struct device *dev; @@ -440,6 +492,12 @@ struct fg_dev { struct power_supply *dc_psy; struct power_supply *parallel_psy; struct power_supply *pc_port_psy; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + struct power_supply *max_verify_psy; +#endif +#ifdef CONFIG_MACH_XIAOMI_NABU + struct power_supply *max_verify_slave_psy; +#endif struct fg_irq_info *irqs; struct votable *awake_votable; struct votable *delta_bsoc_irq_en_votable; @@ -463,6 +521,9 @@ struct fg_dev { u32 mem_if_base; u32 rradc_base; u32 wa_flags; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int cycle_count; +#endif u32 esr_wakeup_ms; u32 awake_status; int batt_id_ohms; @@ -480,6 +541,10 @@ struct fg_dev { int last_recharge_volt_mv; int delta_temp_irq_count; enum esr_filter_status esr_flt_sts; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int vbatt_full_volt_uv; + int vbat_critical_low_count; +#endif bool profile_available; enum prof_load_status profile_load_status; bool battery_missing; @@ -490,19 +555,51 @@ struct fg_dev { bool use_ima_single_mode; bool usb_present; bool twm_state; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool report_full; +#endif bool use_dma; bool qnovo_enable; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool empty_restart_fg; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + bool profile_already_find; + bool input_present; + bool batt_temp_low; + bool shutdown_delay; + /* cold thermal related */ + struct cold_thermal *cold_thermal_seq; + int cold_thermal_len; + int curr_cold_thermal_level; +#else + bool input_present; +#endif +#endif enum fg_version version; bool suspended; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + struct batt_params param; + struct delayed_work soc_monitor_work; +#endif struct completion soc_update; struct completion soc_ready; struct delayed_work profile_load_work; struct work_struct status_change_work; struct work_struct esr_sw_work; struct delayed_work sram_dump_work; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int fake_authentic; + int fake_chip_ok; + int maxim_cycle_count; + int batt_fake_temp; +#endif struct work_struct esr_filter_work; struct alarm esr_filter_alarm; ktime_t last_delta_temp_time; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct delayed_work empty_restart_fg_work; + struct delayed_work soc_work; +#endif }; /* Debugfs data structures are below */ diff --git a/drivers/power/supply/qcom/fg-util.c b/drivers/power/supply/qcom/fg-util.c index c1b66cc1f400..7397089a4a68 100644 --- a/drivers/power/supply/qcom/fg-util.c +++ b/drivers/power/supply/qcom/fg-util.c @@ -407,6 +407,7 @@ void fg_notify_charger(struct fg_dev *fg) } } +#ifndef CONFIG_MACH_XIAOMI_SM8150 if (fg->bp.fastchg_curr_ma > 0) { prop.intval = fg->bp.fastchg_curr_ma * 1000; rc = power_supply_set_property(fg->batt_psy, @@ -418,6 +419,7 @@ void fg_notify_charger(struct fg_dev *fg) return; } } +#endif } bool batt_psy_initialized(struct fg_dev *fg) @@ -867,6 +869,10 @@ int fg_restart(struct fg_dev *fg, int wait_time_ms) goto out; } out: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (fg->empty_restart_fg) + fg->empty_restart_fg = false; +#endif fg->fg_restarting = false; return rc; } @@ -916,10 +922,22 @@ int fg_get_msoc(struct fg_dev *fg, int *msoc) * of the values 1-254 will be scaled to 1-99. DIV_ROUND_UP will not * be suitable here as it rounds up any value higher than 252 to 100. */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if ((*msoc >= FULL_SOC_REPORT_THR - 2) + && (*msoc < FULL_SOC_RAW) && fg->report_full) { + *msoc = DIV_ROUND_CLOSEST(*msoc * FULL_CAPACITY, FULL_SOC_RAW) + 1; + if (*msoc >= FULL_CAPACITY) + *msoc = FULL_CAPACITY; + } else +#endif if (*msoc == FULL_SOC_RAW) *msoc = 100; else if (*msoc == 0) *msoc = 0; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + else if (*msoc >= FULL_SOC_REPORT_THR - 4 && *msoc <= FULL_SOC_REPORT_THR - 3 && fg->report_full) + *msoc = DIV_ROUND_CLOSEST(*msoc * FULL_CAPACITY, FULL_SOC_RAW); +#endif else *msoc = DIV_ROUND_CLOSEST((*msoc - 1) * (FULL_CAPACITY - 2), FULL_SOC_RAW - 2) + 1; diff --git a/drivers/power/supply/qcom/qpnp-fg-gen4.c b/drivers/power/supply/qcom/qpnp-fg-gen4.c index 892071fa67cc..642d1644be13 100644 --- a/drivers/power/supply/qcom/qpnp-fg-gen4.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen4.c @@ -23,6 +23,9 @@ #include #include #include +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#include +#endif #include "fg-core.h" #include "fg-reg.h" #include "fg-alg.h" @@ -209,6 +212,9 @@ #define FIRST_LOG_CURRENT_v2_WORD 471 #define FIRST_LOG_CURRENT_v2_OFFSET 0 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define DEFAULT_FFC_TERM_CURRENT 1500 +#endif static struct fg_irq_info fg_irqs[FG_GEN4_IRQ_MAX]; /* DT parameters for FG device */ @@ -222,11 +228,19 @@ struct fg_dt_props { bool esr_calib_dischg; bool soc_hi_res; bool soc_scale_mode; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + bool shutdown_delay_enable; + int *dec_rate_seq; + int dec_rate_len; +#endif int cutoff_volt_mv; int empty_volt_mv; int sys_min_volt_mv; int cutoff_curr_ma; int sys_term_curr_ma; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int ffc_sys_term_curr_ma; +#endif int delta_soc_thr; int vbatt_scale_thr_mv; int scale_timer_ms; @@ -254,6 +268,10 @@ struct fg_dt_props { int ki_coeff_hi_chg; int ki_coeff_lo_med_chg_thr_ma; int ki_coeff_med_hi_chg_thr_ma; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int ffc_ki_coeff_lo_med_chg_thr_ma; + int ffc_ki_coeff_med_hi_chg_thr_ma; +#endif int ki_coeff_cutoff_gain; int ki_coeff_full_soc_dischg[2]; int ki_coeff_soc[KI_COEFF_SOC_LEVELS]; @@ -280,10 +298,37 @@ struct fg_gen4_chip { struct votable *parallel_current_en_votable; struct votable *mem_attn_irq_en_votable; struct work_struct esr_calib_work; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct work_struct vbat_sync_work; +#endif struct work_struct soc_scale_work; struct alarm esr_fast_cal_timer; struct alarm soc_scale_alarm_timer; struct delayed_work pl_enable_work; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + struct delayed_work battery_authentic_work; + int battery_authentic_result; +#ifdef CONFIG_MACH_XIAOMI_NABU + int battery_authentic_slave_result; + int battery_chip_ok; + int battery_chip_slave_ok; +#endif + struct delayed_work ds_romid_work; + unsigned char ds_romid[8]; +#ifdef CONFIG_MACH_XIAOMI_NABU + unsigned char ds_slave_romid[8]; +#endif + struct delayed_work ds_status_work; + unsigned char ds_status[8]; +#ifdef CONFIG_MACH_XIAOMI_NABU + unsigned char ds_slave_status[8]; +#endif + struct delayed_work ds_page0_work; + unsigned char ds_page0[16]; +#ifdef CONFIG_MACH_XIAOMI_NABU + unsigned char ds_slave_page0[16]; +#endif +#endif struct work_struct pl_current_en_work; struct completion mem_attn; struct mutex soc_scale_lock; @@ -324,6 +369,10 @@ struct fg_gen4_chip { bool vbatt_low; bool soc_scale_mode; bool chg_term_good; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + bool fastcharge_mode_enabled; + bool cold_thermal_support; +#endif }; struct bias_config { @@ -337,6 +386,11 @@ module_param_named( debug_mask, fg_gen4_debug_mask, int, 0600 ); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static bool is_batt_vendor_sunwoda; +static bool is_batt_vendor_nvt; +#endif + static bool fg_profile_dump; module_param_named( profile_dump, fg_profile_dump, bool, 0600 @@ -740,6 +794,13 @@ static int fg_gen4_get_battery_temp(struct fg_dev *fg, int *val) int rc = 0; u16 buf; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (fg->batt_fake_temp != -EINVAL) { + *val = fg->batt_fake_temp; + pr_err("use fake batt temp =%d\n", fg->batt_fake_temp); + return 0; + } +#endif rc = fg_sram_read(fg, BATT_TEMP_WORD, BATT_TEMP_OFFSET, (u8 *)&buf, 2, FG_IMA_DEFAULT); if (rc < 0) { @@ -917,6 +978,20 @@ static int fg_gen4_get_prop_capacity(struct fg_dev *fg, int *val) return 0; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = fg_get_msoc(fg, &msoc); + if (rc < 0) + return rc; + + if (fg->empty_restart_fg && (msoc == 0)) + msoc = EMPTY_REPORT_SOC; + + if (chip->dt.linearize_soc && fg->delta_soc > 0) + *val = fg->maint_soc; + else + *val = msoc; +#endif + if (chip->soc_scale_mode) { mutex_lock(&chip->soc_scale_lock); *val = chip->soc_scale_msoc; @@ -968,6 +1043,48 @@ static int fg_gen4_get_prop_capacity_raw(struct fg_gen4_chip *chip, int *val) return 0; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static int fg_gen4_get_prop_soc_decimal_rate(struct fg_gen4_chip *chip, int *val) +{ + struct fg_dev *fg = &chip->fg; + int i, soc, rc = 0; + + rc = fg_gen4_get_prop_capacity(fg, &soc); + if (rc < 0) { + pr_err("Failed to get battery capacity, rc=%d\n", rc); + return 0; + } + + for (i = 0; i < chip->dt.dec_rate_len; i += 2) { + if (soc < chip->dt.dec_rate_seq[i]) { + *val = chip->dt.dec_rate_seq[i - 1]; + return 0; + } + } + + *val = chip->dt.dec_rate_seq[chip->dt.dec_rate_len - 1]; + + return 0; +} + +static int fg_gen4_get_prop_soc_decimal(struct fg_gen4_chip *chip, int *val) +{ + int rc; + int soc_decimal, soc_decimal_rate; + + union power_supply_propval pval = {0,}; + + rc = fg_gen4_get_prop_capacity_raw(chip, &pval.intval); + soc_decimal = pval.intval % 100; + rc = fg_gen4_get_prop_soc_decimal_rate(chip, &soc_decimal_rate); + if (soc_decimal + soc_decimal_rate >= 100) + soc_decimal -= soc_decimal_rate; + + *val = soc_decimal; + return rc; +} +#endif + static inline void get_esr_meas_current(int curr_ma, u8 *val) { switch (curr_ma) { @@ -1684,6 +1801,10 @@ static int fg_gen4_rapid_soc_config(struct fg_gen4_chip *chip, bool en) return 0; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int retry_batt_profile; +#define BATT_PROFILE_RETRY_COUNT_MAX 5 +#endif static int fg_gen4_get_batt_profile(struct fg_dev *fg) { struct fg_gen4_chip *chip = container_of(fg, struct fg_gen4_chip, fg); @@ -1703,8 +1824,72 @@ static int fg_gen4_get_batt_profile(struct fg_dev *fg) fg->batt_id_ohms / 1000, chip->batt_age_level, &avail_age_level); else +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + { + profile_node = ERR_PTR(-ENXIO); + /* if cmdline battery profile vendor is passed to fg driver, use cmdline result */ + if (is_batt_vendor_sunwoda && !fg->profile_already_find) { + pr_err("is_batt_vendor_sunwoda is %d\n", is_batt_vendor_sunwoda); + fg->profile_already_find = true; +#ifdef CONFIG_MACH_XIAOMI_NABU + profile_node = of_batterydata_get_best_profile(batt_node, // comment for git + fg->batt_id_ohms / 1000, "K82_sunwoda_8720mah"); +#else + profile_node = of_batterydata_get_best_profile(batt_node, // comment for git + fg->batt_id_ohms / 1000, "J20S_sunwoda_5160mah"); +#endif + } else if (is_batt_vendor_nvt && !fg->profile_already_find) { + pr_err("is_batt_vendor_nvt is %d\n", is_batt_vendor_nvt); + fg->profile_already_find = true; + profile_node = of_batterydata_get_best_profile(batt_node, // comment for git + fg->batt_id_ohms / 1000, "J20S_nvt_5160mah"); + } else { + pr_err("cmdline of batt profile is not defined, read page0 to reload file\n"); + } + // the battery is xiaomi's batt; FC code, custom id + if ((chip->ds_romid[0] == 0x9F) && ((chip->ds_romid[5] & 0xF0) == 0xF0) + && (chip->ds_romid[6] == 04) && !fg->profile_already_find) { + if ((chip->ds_page0[0] == 'S') || (chip->ds_page0[0] == 'X')) { +#ifdef CONFIG_MACH_XIAOMI_NABU + profile_node = of_batterydata_get_best_profile(batt_node, // comment for git + fg->batt_id_ohms / 1000, "K82_sunwoda_8720mah"); +#else + profile_node = of_batterydata_get_best_profile(batt_node, // comment for git + fg->batt_id_ohms / 1000, "J20S_sunwoda_5160mah"); +#endif + } else if ((chip->ds_page0[0] == 'N') || (chip->ds_page0[0] == 'A')) { + profile_node = of_batterydata_get_best_profile(batt_node, // comment for git + fg->batt_id_ohms / 1000, "J20S_nvt_5160mah"); + } else { + retry_batt_profile++; + } + } else if (!fg->profile_already_find) { + retry_batt_profile++; + } + + if (retry_batt_profile < BATT_PROFILE_RETRY_COUNT_MAX + && !fg->profile_already_find) { + if (profile_node == ERR_PTR(-ENXIO)) { + pr_warn("verifty battery fail. recheck after, retry:%d\n", + retry_batt_profile); + schedule_delayed_work(&fg->profile_load_work, 500); + } + } else if (!fg->profile_already_find) { +#ifdef CONFIG_MACH_XIAOMI_NABU + pr_warn("verifty battery fail. use default profile K82_sunwoda_8720mah\n"); + profile_node = of_batterydata_get_best_profile(batt_node, // comment for git + fg->batt_id_ohms / 1000, "K82_sunwoda_8720mah"); +#else + pr_warn("verifty battery fail. use default profile J20S_nvt_5160mah\n"); + profile_node = of_batterydata_get_best_profile(batt_node, // comment for git + fg->batt_id_ohms / 1000, "J20S_nvt_5160mah"); +#endif + } + } +#else profile_node = of_batterydata_get_best_profile(batt_node, fg->batt_id_ohms / 1000, NULL); +#endif if (IS_ERR(profile_node)) return PTR_ERR(profile_node); @@ -1763,6 +1948,22 @@ static int fg_gen4_get_batt_profile(struct fg_dev *fg) fg->bp.fastchg_curr_ma = -EINVAL; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + rc = of_property_read_u32(profile_node, "qcom,ffc-low-temp-term-current-ma", + &fg->bp.ffc_low_temp_term_curr_ma); + if (rc < 0) { + pr_err("battery system current unavailable, rc:%d\n", rc); + fg->bp.ffc_low_temp_term_curr_ma = -DEFAULT_FFC_TERM_CURRENT; + } + + rc = of_property_read_u32(profile_node, "qcom,ffc-high-temp-term-current-ma", + &fg->bp.ffc_high_temp_term_curr_ma); + if (rc < 0) { + pr_err("battery system current unavailable, rc:%d\n", rc); + fg->bp.ffc_high_temp_term_curr_ma = -DEFAULT_FFC_TERM_CURRENT; + } +#endif + rc = of_property_read_u32(profile_node, "qcom,fg-cc-cv-threshold-mv", &fg->bp.vbatt_full_mv); if (rc < 0) { @@ -1770,6 +1971,24 @@ static int fg_gen4_get_batt_profile(struct fg_dev *fg) fg->bp.vbatt_full_mv = -EINVAL; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + rc = of_property_read_u32(profile_node, "qcom,fg-ffc-cc-cv-threshold-mv", + &fg->bp.ffc_vbatt_full_mv); + if (rc < 0) { + pr_err("battery ffc cc_cv threshold unavailable, rc:%d\n", rc); + fg->bp.ffc_vbatt_full_mv = -EINVAL; + } +#endif + + rc = of_property_read_u32(profile_node, "qcom,nom-batt-capacity-mah", + &fg->bp.nom_cap_uah); + if (rc < 0) { + pr_err("battery nominal capacity unavailable, rc:%d\n", rc); + fg->bp.nom_cap_uah = -EINVAL; + } +#endif + if (of_find_property(profile_node, "qcom,therm-coefficients", &len)) { len /= sizeof(u32); if (len == BATT_THERM_NUM_COEFFS) { @@ -2738,6 +2957,10 @@ static int fg_gen4_adjust_recharge_soc(struct fg_gen4_chip *chip) if (is_input_present(fg)) { if (fg->charge_done) { if (!fg->recharge_soc_adjusted) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (fg->health == POWER_SUPPLY_HEALTH_GOOD) + return 0; +#endif /* Get raw monotonic SOC for calculation */ rc = fg_get_msoc(fg, &msoc); if (rc < 0) { @@ -3407,6 +3630,9 @@ static irqreturn_t fg_vbatt_low_irq_handler(int irq, void *data) int rc, vbatt_mv, msoc_raw; s64 time_us; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + schedule_work(&chip->vbat_sync_work); +#endif rc = fg_get_battery_voltage(fg, &vbatt_mv); if (rc < 0) return IRQ_HANDLED; @@ -3435,6 +3661,20 @@ static irqreturn_t fg_vbatt_low_irq_handler(int irq, void *data) if (vbatt_mv < chip->dt.cutoff_volt_mv) { if (chip->dt.rapid_soc_dec_en) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* + * Set vbat_low debounce window to avoid shutdown in low temperature and high + * current scene, we set the counter to maxium 5, if fg_vbatt_low_irq trigger + * exceed 5 times, decrease soc to 0% very rapidly. + */ + fg->vbat_critical_low_count++; + if (fg->vbat_critical_low_count < EMPTY_DEBOUNCE_TIME_COUNT_MAX + && vbatt_mv > VBAT_CRITICAL_LOW_THR) { + if (batt_psy_initialized(fg)) + power_supply_changed(fg->batt_psy); + return IRQ_HANDLED; + } +#endif /* * Set this flag so that slope limiter coefficient * cannot be configured during rapid SOC decrease. @@ -3582,6 +3822,32 @@ static irqreturn_t fg_delta_bsoc_irq_handler(int irq, void *data) } #define CENTI_FULL_SOC 10000 + +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static bool fg_is_input_suspend(struct fg_dev *fg) +{ + int rc = 0; + union power_supply_propval prop = {0, }; + int input_suspend = 0; + + if (fg->batt_psy) { + rc = power_supply_get_property(fg->batt_psy, + POWER_SUPPLY_PROP_INPUT_SUSPEND, + &prop); + if (rc < 0) { + pr_err("Error in getting input suspend property, rc=%d\n", rc); + return false; + } + input_suspend = prop.intval; + } + + if (input_suspend == 1) + return true; + else + return false; +} +#endif + static irqreturn_t fg_delta_msoc_irq_handler(int irq, void *data) { struct fg_dev *fg = data; @@ -3589,6 +3855,9 @@ static irqreturn_t fg_delta_msoc_irq_handler(int irq, void *data) int rc, batt_soc, batt_temp, msoc_raw; bool input_present = is_input_present(fg); u32 batt_soc_cp; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool input_suspend = false; +#endif rc = fg_get_msoc_raw(fg, &msoc_raw); if (!rc) @@ -3597,12 +3866,20 @@ static irqreturn_t fg_delta_msoc_irq_handler(int irq, void *data) get_batt_psy_props(fg); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + input_suspend = fg_is_input_suspend(fg); +#endif + rc = fg_get_sram_prop(fg, FG_SRAM_BATT_SOC, &batt_soc); if (rc < 0) pr_err("Failed to read battery soc rc: %d\n", rc); else cycle_count_update(chip->counter, (u32)batt_soc >> 24, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + fg->charge_status, fg->charge_done, (input_present & (!input_suspend))); +#else fg->charge_status, fg->charge_done, input_present); +#endif rc = fg_gen4_get_battery_temp(fg, &batt_temp); if (rc < 0) { @@ -4037,6 +4314,11 @@ static void pl_current_en_work(struct work_struct *work) return; vote(chip->parallel_current_en_votable, FG_PARALLEL_EN_VOTER, en, 0); + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* qcom patch to fix pm8150b ADC EOC bit not set issue */ + vote(chip->mem_attn_irq_en_votable, MEM_ATTN_IRQ_VOTER, false, 0); +#endif } static void pl_enable_work(struct work_struct *work) @@ -4053,6 +4335,166 @@ static void pl_enable_work(struct work_struct *work) vote(fg->awake_votable, ESR_FCC_VOTER, false, 0); } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static void vbat_sync_work(struct work_struct *work) +{ + pr_err("sys_sync:vbat_sync_work\n"); + sys_sync(); +} + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static int battery_authentic_period_ms = 1000; +#define BATTERY_AUTHENTIC_COUNT_MAX 5 +int retry_battery_authentic_result; +static void battery_authentic_work(struct work_struct *work) +{ + int rc; + //int count = 0; + union power_supply_propval pval = {0,}; + + struct fg_gen4_chip *chip = container_of(work, + struct fg_gen4_chip, + battery_authentic_work.work); + struct fg_dev *fg = &chip->fg; + + rc = power_supply_get_property(fg->fg_psy, + POWER_SUPPLY_PROP_AUTHENTIC, &pval); + if (pval.intval != true) { + retry_battery_authentic_result++; + if (retry_battery_authentic_result < BATTERY_AUTHENTIC_COUNT_MAX) { + pr_err("battery authentic work begin to restart.\n"); + schedule_delayed_work(&chip->battery_authentic_work, + msecs_to_jiffies(battery_authentic_period_ms)); + } + + if (retry_battery_authentic_result == BATTERY_AUTHENTIC_COUNT_MAX) { + pr_err("FG: authentic prop is %d\n", pval.intval); + } + } else { + pr_err("FG: authentic prop is %d\n", pval.intval); + schedule_delayed_work(&chip->ds_romid_work, + msecs_to_jiffies(0)); + schedule_delayed_work(&chip->ds_status_work, + msecs_to_jiffies(500)); + schedule_delayed_work(&chip->ds_page0_work, + msecs_to_jiffies(1000)); + } +} + +static int ds_romid_period_ms = 1000; +int retry_ds_romid; +#define DS_ROMID_COUNT_MAX 5 +static void ds_romid_work(struct work_struct *work) +{ + int rc; + //int count = 0; + union power_supply_propval pval = {0,}; + + struct fg_gen4_chip *chip = container_of(work, + struct fg_gen4_chip, + ds_romid_work.work); + struct fg_dev *fg = &chip->fg; + + rc = power_supply_get_property(fg->fg_psy, + POWER_SUPPLY_PROP_ROMID, &pval); + if (rc < 0) { + retry_ds_romid++; + if (retry_ds_romid < DS_ROMID_COUNT_MAX) { + pr_err("battery authentic work begin to restart.\n"); + schedule_delayed_work(&chip->ds_romid_work, + msecs_to_jiffies(ds_romid_period_ms)); + } + + if (retry_ds_romid == DS_ROMID_COUNT_MAX) { + pr_err("FG: romid prop is %02x %02x %02x %02x %02x %02x %02x %02x\n", + pval.arrayval[0], pval.arrayval[1], pval.arrayval[2], pval.arrayval[3], + pval.arrayval[4], pval.arrayval[5], pval.arrayval[6], pval.arrayval[7]); + } + } else { + pr_err("FG: romid prop is %02x %02x %02x %02x %02x %02x %02x %02x\n", + pval.arrayval[0], pval.arrayval[1], pval.arrayval[2], pval.arrayval[3], + pval.arrayval[4], pval.arrayval[5], pval.arrayval[6], pval.arrayval[7]); + } +} + +static int ds_status_period_ms = 1000; +#define DS_STATUS_COUNT_MAX 5 +int retry_ds_status; +static void ds_status_work(struct work_struct *work) +{ + int rc; + //int count = 0; + union power_supply_propval pval = {0,}; + + struct fg_gen4_chip *chip = container_of(work, + struct fg_gen4_chip, + ds_status_work.work); + struct fg_dev *fg = &chip->fg; + + rc = power_supply_get_property(fg->fg_psy, + POWER_SUPPLY_PROP_DS_STATUS, &pval); + if (rc < 0) { + retry_ds_status++; + if (retry_ds_status < DS_STATUS_COUNT_MAX) { + pr_err("battery authentic work begin to restart.\n"); + schedule_delayed_work(&chip->ds_status_work, + msecs_to_jiffies(ds_status_period_ms)); + } + + if (retry_ds_status == DS_STATUS_COUNT_MAX) { + pr_err("FG: ds_status prop is %02x %02x %02x %02x %02x %02x %02x %02x\n", + pval.arrayval[0], pval.arrayval[1], pval.arrayval[2], pval.arrayval[3], + pval.arrayval[4], pval.arrayval[5], pval.arrayval[6], pval.arrayval[7]); + } + } else { + pr_err("FG: ds_status prop is %02x %02x %02x %02x %02x %02x %02x %02x\n", + pval.arrayval[0], pval.arrayval[1], pval.arrayval[2], pval.arrayval[3], + pval.arrayval[4], pval.arrayval[5], pval.arrayval[6], pval.arrayval[7]); + } +} + +static int ds_page0_period_ms = 1000; +#define DS_PAGE0_COUNT_MAX 5 +int retry_ds_page0; +static void ds_page0_work(struct work_struct *work) +{ + int rc; + //int count = 0; + union power_supply_propval pval = {0,}; + + struct fg_gen4_chip *chip = container_of(work, + struct fg_gen4_chip, + ds_page0_work.work); + struct fg_dev *fg = &chip->fg; + + rc = power_supply_get_property(fg->fg_psy, + POWER_SUPPLY_PROP_PAGE0_DATA, &pval); + if (rc < 0) { + retry_ds_page0++; + if (retry_ds_page0 < DS_PAGE0_COUNT_MAX) { + pr_err("battery authentic work begin to restart.\n"); + schedule_delayed_work(&chip->ds_page0_work, + msecs_to_jiffies(ds_page0_period_ms)); + } + + if (retry_ds_page0 == DS_PAGE0_COUNT_MAX) { + pr_err("FG: ds_page0 prop is %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + pval.arrayval[0], pval.arrayval[1], pval.arrayval[2], pval.arrayval[3], + pval.arrayval[4], pval.arrayval[5], pval.arrayval[6], pval.arrayval[7], + pval.arrayval[8], pval.arrayval[9], pval.arrayval[10], pval.arrayval[11], + pval.arrayval[12], pval.arrayval[13], pval.arrayval[14], pval.arrayval[15]); + } + } else { + pr_err("FG: ds_page0 prop is %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + pval.arrayval[0], pval.arrayval[1], pval.arrayval[2], pval.arrayval[3], + pval.arrayval[4], pval.arrayval[5], pval.arrayval[6], pval.arrayval[7], + pval.arrayval[8], pval.arrayval[9], pval.arrayval[10], pval.arrayval[11], + pval.arrayval[12], pval.arrayval[13], pval.arrayval[14], pval.arrayval[15]); + } +} +#endif +#endif + static void status_change_work(struct work_struct *work) { struct fg_dev *fg = container_of(work, @@ -4061,6 +4503,10 @@ static void status_change_work(struct work_struct *work) int rc, batt_soc, batt_temp; bool input_present, qnovo_en; u32 batt_soc_cp; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int msoc_raw; + bool input_suspend = false; +#endif if (fg->battery_missing) { pm_relax(fg->dev); @@ -4085,6 +4531,18 @@ static void status_change_work(struct work_struct *work) get_batt_psy_props(fg); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (fg->charge_done && !fg->report_full) { + fg->report_full = true; + } else if (!fg->charge_done && fg->report_full) { + rc = fg_get_msoc_raw(fg, &msoc_raw); + if (rc < 0) + pr_err("Error in getting msoc, rc=%d\n", rc); + if (msoc_raw < FULL_SOC_REPORT_THR - 4) + fg->report_full = false; + } +#endif + rc = fg_get_sram_prop(fg, FG_SRAM_BATT_SOC, &batt_soc); if (rc < 0) { pr_err("Failed to read battery soc rc: %d\n", rc); @@ -4098,9 +4556,17 @@ static void status_change_work(struct work_struct *work) } input_present = is_input_present(fg); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + fg->input_present = input_present; + input_suspend = fg_is_input_suspend(fg); +#endif qnovo_en = is_qnovo_en(fg); cycle_count_update(chip->counter, (u32)batt_soc >> 24, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + fg->charge_status, fg->charge_done, (input_present & (!input_suspend))); +#else fg->charge_status, fg->charge_done, input_present); +#endif batt_soc_cp = div64_u64((u64)(u32)batt_soc * CENTI_FULL_SOC, BATT_SOC_32BIT); @@ -4148,6 +4614,69 @@ static void status_change_work(struct work_struct *work) pm_relax(fg->dev); } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define NORMAL_VOLTAGE_UV_THR 3700000 +static int fg_get_cold_thermal_level(struct fg_dev *fg) +{ + union power_supply_propval pval = {0, }; + int curr_ua, i, rc, temp, volt, status; + + if (!fg) + return -EINVAL; + + if (!fg->cold_thermal_len) + return 1; + + if (!fg->batt_psy) { + fg->batt_psy = power_supply_get_by_name("battery"); + if (!fg->batt_psy) { + return 1; + } + } + + rc = power_supply_get_property(fg->batt_psy, + POWER_SUPPLY_PROP_STATUS, &pval); + if (rc < 0) { + pr_err("failed get batt staus\n"); + return -EINVAL; + } + status = pval.intval; + + rc = fg_get_battery_voltage(fg, &volt); + if (rc < 0) + pr_err("failed to get voltage, rc=%d\n", rc); + + rc = fg_gen4_get_battery_temp(fg, &temp); + if (rc < 0) + pr_err("Error in getting batt_temp, rc=%d\n", rc); + + if (status == POWER_SUPPLY_STATUS_CHARGING || + !fg->batt_temp_low || volt > NORMAL_VOLTAGE_UV_THR) + return 1; + + rc = fg_get_battery_current(fg, &curr_ua); + if (rc < 0) + pr_err("failded to get battery current, rc=%d\n", rc); + + pr_err("volt: %d, temp: %d, curr_ua: %d\n", + volt, temp, curr_ua); + + for (i = 0; i < fg->cold_thermal_len; i++) { + if (temp > fg->cold_thermal_seq[i].temp_l && + temp <= fg->cold_thermal_seq[i].temp_h && + curr_ua > fg->cold_thermal_seq[i].curr_th) { + pr_err("cold thermal trigger status:%d, temp:%d, volt:%d\n", + status, temp, volt); + pr_err("curr_ua:%d, fg->cold_thermal_seq[i].index:%d\n", curr_ua, + fg->cold_thermal_seq[i].index); + return (fg->cold_thermal_seq[i].index + 1); + } + } + + return 1; +} +#endif + static void sram_dump_work(struct work_struct *work) { struct fg_dev *fg = container_of(work, struct fg_dev, @@ -4321,7 +4850,121 @@ static struct kernel_param_ops fg_esr_cal_ops = { module_param_cb(esr_fast_cal_en, &fg_esr_cal_ops, &fg_esr_fast_cal_en, 0644); /* All power supply functions here */ +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static int fg_gen4_set_vbatt_full_vol(struct fg_dev *fg, bool enable_ffc) +{ + int rc; + int volt; + if (enable_ffc) + volt = fg->bp.ffc_vbatt_full_mv; + else + volt = fg->bp.vbatt_full_mv; + if (volt < 0) + return rc; + rc = fg_set_constant_chg_voltage(fg, volt * 1000); + if (rc < 0) { + pr_err("Error in constant chg vol rc=%d\n", rc); + return rc; + } + fg->bp.float_volt_uv = volt * 1000 + 10000; + fg_dbg(fg, FG_STATUS, "set cc-cv volt:%d float_volt_uv:%d\n", volt, fg->bp.float_volt_uv); + return rc; +} +static int fg_gen4_set_sys_termi_curr(struct fg_dev *fg, bool enable_ffc) +{ + struct fg_gen4_chip *chip = container_of(fg, struct fg_gen4_chip, fg); + u8 buf[4]; + int rc; + int curr; + if (enable_ffc) + curr = chip->dt.ffc_sys_term_curr_ma; + else + curr = chip->dt.sys_term_curr_ma; + if (chip->dt.ffc_sys_term_curr_ma == -EINVAL) + return 0; + fg_encode(fg->sp, FG_SRAM_SYS_TERM_CURR, curr, buf); + rc = fg_sram_write(fg, fg->sp[FG_SRAM_SYS_TERM_CURR].addr_word, + fg->sp[FG_SRAM_SYS_TERM_CURR].addr_byte, buf, + fg->sp[FG_SRAM_SYS_TERM_CURR].len, FG_IMA_DEFAULT); + if (rc < 0) { + pr_err("Error in writing sys_term_curr, rc=%d\n", rc); + return rc; + } + fg_dbg(fg, FG_STATUS, "set sys termi curr:%d\n", curr); + return rc; +} +static int fg_gen4_set_ki_coeff_curr(struct fg_dev *fg, bool enable_ffc) +{ + struct fg_gen4_chip *chip = container_of(fg, struct fg_gen4_chip, fg); + u8 val; + int rc; + int lo_med_curr, med_hi_curr; + if (enable_ffc) { + lo_med_curr = chip->dt.ffc_ki_coeff_lo_med_chg_thr_ma; + med_hi_curr = chip->dt.ffc_ki_coeff_med_hi_chg_thr_ma; + } else { + lo_med_curr = chip->dt.ki_coeff_lo_med_chg_thr_ma; + med_hi_curr = chip->dt.ki_coeff_med_hi_chg_thr_ma; + } + pr_err("enable_ffc:%d, low_med_curr:%d, med_hi_curr:%d\n", enable_ffc, lo_med_curr, med_hi_curr); + if (lo_med_curr == -EINVAL || med_hi_curr == -EINVAL) + return 0; + fg_encode(fg->sp, FG_SRAM_KI_COEFF_LO_MED_CHG_THR, + lo_med_curr, &val); + rc = fg_sram_write(fg, + fg->sp[FG_SRAM_KI_COEFF_LO_MED_CHG_THR].addr_word, + fg->sp[FG_SRAM_KI_COEFF_LO_MED_CHG_THR].addr_byte, + &val, fg->sp[FG_SRAM_KI_COEFF_LO_MED_CHG_THR].len, + FG_IMA_DEFAULT); + if (rc < 0) { + pr_err("Error in writing ki_coeff_lo_med_chg_thr_ma, rc=%d\n", + rc); + return rc; + } + fg_encode(fg->sp, FG_SRAM_KI_COEFF_MED_HI_CHG_THR, + med_hi_curr, &val); + rc = fg_sram_write(fg, + fg->sp[FG_SRAM_KI_COEFF_MED_HI_CHG_THR].addr_word, + fg->sp[FG_SRAM_KI_COEFF_MED_HI_CHG_THR].addr_byte, &val, + fg->sp[FG_SRAM_KI_COEFF_MED_HI_CHG_THR].len, + FG_IMA_DEFAULT); + if (rc < 0) { + pr_err("Error in writing ki_coeff_med_hi_chg_thr_ma, rc=%d\n", + rc); + return rc; + } + pr_err("==test lo_med_curr:%d, med_hi_curr:%d\n", lo_med_curr, med_hi_curr); + return rc; +} +static int fg_get_ffc_iterm_for_chg(struct fg_dev *fg) +{ + int rc = 0, batt_temp = 0, ffc_chg_iterm = 0; + rc = fg_gen4_get_battery_temp(fg, &batt_temp); + if (rc < 0){ + pr_err("Failed to get battery-temp, rc = %d\n", rc); + return -DEFAULT_FFC_TERM_CURRENT; + } + if (batt_temp < 350) + ffc_chg_iterm = fg->bp.ffc_low_temp_term_curr_ma; + else + ffc_chg_iterm = fg->bp.ffc_high_temp_term_curr_ma; +#ifdef CONFIG_MACH_XIAOMI_NABU + if (ffc_chg_iterm == 0) { + if (batt_temp < 350) + ffc_chg_iterm = -1278; + else + ffc_chg_iterm = -1363; + } +#endif + + return ffc_chg_iterm; +} +#endif + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define SHUTDOWN_DELAY_VOL 3300 +#endif static int fg_psy_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *pval) @@ -4330,10 +4973,187 @@ static int fg_psy_get_property(struct power_supply *psy, struct fg_dev *fg = &chip->fg; int rc = 0, val; int64_t temp; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int vbatt_uv; + static bool shutdown_delay_cancel; + static bool last_shutdown_delay; +#endif + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + union power_supply_propval b_val = {0,}; + + if (fg->max_verify_psy == NULL) { + fg->max_verify_psy = power_supply_get_by_name("batt_verify"); + if (fg->max_verify_psy == NULL) { + pr_err("max_verify_psy is NULL\n"); + } + } + +#ifdef CONFIG_MACH_XIAOMI_NABU + if (fg->max_verify_slave_psy == NULL) { + fg->max_verify_slave_psy = power_supply_get_by_name("batt_verify_slave"); + if (fg->max_verify_slave_psy == NULL) { + pr_err("max_verify_slave_psy is NULL\n"); + } + } +#endif +#endif switch (psp) { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_AUTHENTIC: + if (fg->fake_authentic != -EINVAL) { + pval->intval = fg->fake_authentic; + break; + } + + if (fg->max_verify_psy == NULL) + return -ENODATA; +#ifdef CONFIG_MACH_XIAOMI_NABU + if (fg->max_verify_slave_psy == NULL) + return -ENODATA; +#endif + + rc = power_supply_get_property(fg->max_verify_psy, + POWER_SUPPLY_PROP_AUTHEN_RESULT, &b_val); + chip->battery_authentic_result = b_val.intval; +#ifdef CONFIG_MACH_XIAOMI_NABU + rc = power_supply_get_property(fg->max_verify_slave_psy, + POWER_SUPPLY_PROP_AUTHEN_RESULT, &b_val); + chip->battery_authentic_slave_result = b_val.intval; +#endif + if (chip->battery_authentic_result == 1 +#ifdef CONFIG_MACH_XIAOMI_NABU + && chip->battery_authentic_slave_result == 1 +#endif + ) { + pval->intval = 1; + } else { + pval->intval = 0; + } + break; + case POWER_SUPPLY_PROP_ROMID: + if (fg->max_verify_psy == NULL) + return -ENODATA; +#ifdef CONFIG_MACH_XIAOMI_NABU + if (fg->max_verify_slave_psy == NULL) + return -ENODATA; +#endif + + rc = power_supply_get_property(fg->max_verify_psy, + POWER_SUPPLY_PROP_ROMID, &b_val); + memcpy(pval->arrayval, b_val.arrayval, 8); + memcpy(chip->ds_romid, b_val.arrayval, 8); + +#ifdef CONFIG_MACH_XIAOMI_NABU + rc = power_supply_get_property(fg->max_verify_slave_psy, + POWER_SUPPLY_PROP_ROMID, &b_val); + memcpy(chip->ds_slave_romid, b_val.arrayval, 8); +#endif + + break; + case POWER_SUPPLY_PROP_CHIP_OK: + if (fg->fake_chip_ok != -EINVAL) { + pval->intval = fg->fake_chip_ok; + break; + } + if (fg->max_verify_psy == NULL) + return -ENODATA; +#ifdef CONFIG_MACH_XIAOMI_NABU + if (fg->max_verify_slave_psy == NULL) + return -ENODATA; +#endif + + rc = power_supply_get_property(fg->max_verify_psy, + POWER_SUPPLY_PROP_CHIP_OK, &b_val); +#ifdef CONFIG_MACH_XIAOMI_NABU + chip->battery_chip_ok = b_val.intval; +#endif + pval->intval = b_val.intval; +#ifdef CONFIG_MACH_XIAOMI_NABU + rc = power_supply_get_property(fg->max_verify_slave_psy, + POWER_SUPPLY_PROP_CHIP_OK, &b_val); + chip->battery_chip_slave_ok = b_val.intval; + if (chip->battery_chip_ok == 1 && chip->battery_chip_slave_ok == 1) { + pval->intval = 1; + } else { + pval->intval = 0; + } +#endif + break; + case POWER_SUPPLY_PROP_DS_STATUS: + if (fg->max_verify_psy == NULL) + return -ENODATA; +#ifdef CONFIG_MACH_XIAOMI_NABU + if (fg->max_verify_slave_psy == NULL) + return -ENODATA; +#endif + + rc = power_supply_get_property(fg->max_verify_psy, + POWER_SUPPLY_PROP_DS_STATUS, &b_val); + memcpy(pval->arrayval, b_val.arrayval, 8); + memcpy(chip->ds_status, b_val.arrayval, 8); +#ifdef CONFIG_MACH_XIAOMI_NABU + rc = power_supply_get_property(fg->max_verify_slave_psy, + POWER_SUPPLY_PROP_DS_STATUS, &b_val); + memcpy(chip->ds_slave_status, b_val.arrayval, 8); +#endif + break; + case POWER_SUPPLY_PROP_PAGE0_DATA: + if (fg->max_verify_psy == NULL) + return -ENODATA; +#ifdef CONFIG_MACH_XIAOMI_NABU + if (fg->max_verify_slave_psy == NULL) + return -ENODATA; +#endif + + rc = power_supply_get_property(fg->max_verify_psy, + POWER_SUPPLY_PROP_PAGE0_DATA, &b_val); + memcpy(pval->arrayval, b_val.arrayval, 16); + memcpy(chip->ds_page0, b_val.arrayval, 16); +#ifdef CONFIG_MACH_XIAOMI_NABU + rc = power_supply_get_property(fg->max_verify_slave_psy, + POWER_SUPPLY_PROP_PAGE0_DATA, &b_val); + memcpy(chip->ds_slave_page0, b_val.arrayval, 16); +#endif + break; +#endif case POWER_SUPPLY_PROP_CAPACITY: rc = fg_gen4_get_prop_capacity(fg, &pval->intval); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + //Using smooth battery capacity. + if (fg->param.batt_soc >= 0 && !chip->rapid_soc_dec_en) + pval->intval = fg->param.batt_soc; + //shutdown delay feature + if (chip->dt.shutdown_delay_enable) { + if (pval->intval == 0) { + rc = fg_get_battery_voltage(fg, &vbatt_uv); + if (vbatt_uv/1000 > SHUTDOWN_DELAY_VOL + && fg->charge_status != POWER_SUPPLY_STATUS_CHARGING) { + fg->shutdown_delay = true; + pval->intval = 1; + } else if (fg->charge_status == POWER_SUPPLY_STATUS_CHARGING + && fg->shutdown_delay) { + fg->shutdown_delay = false; + shutdown_delay_cancel = true; + pval->intval = 1; + } else { + fg->shutdown_delay = false; + if (shutdown_delay_cancel) + pval->intval = 1; + } + } else { + fg->shutdown_delay = false; + shutdown_delay_cancel = false; + } + + if (last_shutdown_delay != fg->shutdown_delay) { + last_shutdown_delay = fg->shutdown_delay; + if (fg->fg_psy) + power_supply_changed(fg->fg_psy); + } + } +#endif break; case POWER_SUPPLY_PROP_REAL_CAPACITY: rc = fg_gen4_get_prop_real_capacity(fg, &pval->intval); @@ -4341,6 +5161,17 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CAPACITY_RAW: rc = fg_gen4_get_prop_capacity_raw(chip, &pval->intval); break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_SHUTDOWN_DELAY: + pval->intval = fg->shutdown_delay; + break; + case POWER_SUPPLY_PROP_SOC_DECIMAL: + rc = fg_gen4_get_prop_soc_decimal(chip, &pval->intval); + break; + case POWER_SUPPLY_PROP_SOC_DECIMAL_RATE: + rc = fg_gen4_get_prop_soc_decimal_rate(chip, &pval->intval); + break; +#endif case POWER_SUPPLY_PROP_CC_SOC: rc = fg_get_sram_prop(&chip->fg, FG_SRAM_CC_SOC, &val); if (rc < 0) { @@ -4401,9 +5232,17 @@ static int fg_psy_get_property(struct power_supply *psy, pval->intval = (int)temp; break; case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (-EINVAL != fg->bp.nom_cap_uah) { + pval->intval = fg->bp.nom_cap_uah * 1000; + } else { +#endif rc = fg_gen4_get_nominal_capacity(chip, &temp); if (!rc) pval->intval = (int)temp; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + } +#endif break; case POWER_SUPPLY_PROP_CHARGE_COUNTER: rc = fg_gen4_get_charge_counter(chip, &pval->intval); @@ -4457,6 +5296,15 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CC_STEP_SEL: pval->intval = chip->ttf->cc_step.sel; break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_COLD_THERMAL_LEVEL: + if(chip->cold_thermal_support) { + pval->intval = fg_get_cold_thermal_level(fg); + if (pval->intval < fg->curr_cold_thermal_level) + pval->intval = fg->curr_cold_thermal_level; + } + break; +#endif case POWER_SUPPLY_PROP_BATT_AGE_LEVEL: pval->intval = chip->batt_age_level; break; @@ -4472,6 +5320,29 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CALIBRATE: pval->intval = chip->calib_level; break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_FASTCHARGE_MODE: + pval->intval = chip->fastcharge_mode_enabled; + break; + case POWER_SUPPLY_PROP_FFC_TERMINATION_CURRENT: + pval->intval = fg_get_ffc_iterm_for_chg(fg); + break; + case POWER_SUPPLY_PROP_SYS_TERMINATION_CURRENT: + pval->intval = chip->dt.sys_term_curr_ma; + break; + case POWER_SUPPLY_PROP_FFC_SYS_TERMINATION_CURRENT: + pval->intval = chip->dt.ffc_sys_term_curr_ma; + break; + case POWER_SUPPLY_PROP_VBATT_FULL_VOL: + pval->intval = fg->bp.vbatt_full_mv; + break; + case POWER_SUPPLY_PROP_FFC_VBATT_FULL_VOL: + pval->intval = fg->bp.ffc_vbatt_full_mv; + break; + case POWER_SUPPLY_PROP_KI_COEFF_CURRENT: + pval->intval = chip->dt.ffc_ki_coeff_med_hi_chg_thr_ma; + break; +#endif default: pr_err("unsupported property %d\n", psp); rc = -EINVAL; @@ -4540,6 +5411,12 @@ static int fg_psy_set_property(struct power_supply *psy, if (chip->sp) soh_profile_update(chip->sp, chip->soh); break; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_CYCLE_COUNT: + rc = set_cycle_count(chip->counter, pval->intval); + pr_info("Cycle count is modified to %d by userspace\n", pval->intval); + break; +#endif case POWER_SUPPLY_PROP_CLEAR_SOH: if (chip->first_profile_load && !pval->intval) { fg_dbg(fg, FG_STATUS, "Clearing first profile load bit\n"); @@ -4563,9 +5440,53 @@ static int fg_psy_set_property(struct power_supply *psy, chip->batt_age_level = pval->intval; schedule_delayed_work(&fg->profile_load_work, 0); break; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: + if (fg->vbatt_full_volt_uv != pval->intval) + rc = fg_set_constant_chg_voltage(fg, pval->intval); + fg->vbatt_full_volt_uv = pval->intval; + break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_COLD_THERMAL_LEVEL: + if (chip->cold_thermal_support) { + fg->curr_cold_thermal_level = pval->intval; + if (fg->curr_cold_thermal_level > 3) + fg->curr_cold_thermal_level = 3; + else if (fg->curr_cold_thermal_level < 1) + fg->curr_cold_thermal_level = 1; + } + break; +#endif +#endif case POWER_SUPPLY_PROP_CALIBRATE: rc = fg_gen4_set_calibrate_level(chip, pval->intval); break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_FASTCHARGE_MODE: + chip->fastcharge_mode_enabled = pval->intval; + break; + case POWER_SUPPLY_PROP_SYS_TERMINATION_CURRENT: + rc = fg_gen4_set_sys_termi_curr(fg, pval->intval); + break; + case POWER_SUPPLY_PROP_VBATT_FULL_VOL: + rc = fg_gen4_set_vbatt_full_vol(fg, pval->intval); + break; + case POWER_SUPPLY_PROP_KI_COEFF_CURRENT: + rc = fg_gen4_set_ki_coeff_curr(fg, pval->intval); + break; + case POWER_SUPPLY_PROP_SHUTDOWN_DELAY_ENABLE: + chip->dt.shutdown_delay_enable = pval->intval; + break; + case POWER_SUPPLY_PROP_AUTHENTIC: + fg->fake_authentic = !!pval->intval; + break; + case POWER_SUPPLY_PROP_CHIP_OK: + fg->fake_chip_ok = !!pval->intval; + break; + case POWER_SUPPLY_PROP_TEMP: + fg->batt_fake_temp = pval->intval; + break; +#endif default: break; } @@ -4583,9 +5504,27 @@ static int fg_property_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_ESR_ACTUAL: case POWER_SUPPLY_PROP_ESR_NOMINAL: case POWER_SUPPLY_PROP_SOH: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_CYCLE_COUNT: +#endif case POWER_SUPPLY_PROP_CLEAR_SOH: case POWER_SUPPLY_PROP_BATT_AGE_LEVEL: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_COLD_THERMAL_LEVEL: +#endif +#endif case POWER_SUPPLY_PROP_CALIBRATE: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_FASTCHARGE_MODE: + case POWER_SUPPLY_PROP_SYS_TERMINATION_CURRENT: + case POWER_SUPPLY_PROP_VBATT_FULL_VOL: + case POWER_SUPPLY_PROP_KI_COEFF_CURRENT: + case POWER_SUPPLY_PROP_AUTHENTIC: + case POWER_SUPPLY_PROP_CHIP_OK: + case POWER_SUPPLY_PROP_TEMP: +#endif return 1; default: break; @@ -4595,8 +5534,20 @@ static int fg_property_is_writeable(struct power_supply *psy, } static enum power_supply_property fg_psy_props[] = { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_AUTHENTIC, + POWER_SUPPLY_PROP_ROMID, + POWER_SUPPLY_PROP_DS_STATUS, + POWER_SUPPLY_PROP_PAGE0_DATA, + POWER_SUPPLY_PROP_CHIP_OK, +#endif POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_REAL_CAPACITY, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_SHUTDOWN_DELAY, + POWER_SUPPLY_PROP_SOC_DECIMAL, + POWER_SUPPLY_PROP_SOC_DECIMAL_RATE, +#endif POWER_SUPPLY_PROP_CAPACITY_RAW, POWER_SUPPLY_PROP_CC_SOC, POWER_SUPPLY_PROP_TEMP, @@ -4617,6 +5568,9 @@ static enum power_supply_property fg_psy_props[] = { POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_CHARGE_COUNTER_SHADOW, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_PROP_CYCLE_COUNT, +#endif POWER_SUPPLY_PROP_CYCLE_COUNTS, POWER_SUPPLY_PROP_SOC_REPORTING_READY, POWER_SUPPLY_PROP_CLEAR_SOH, @@ -4628,11 +5582,23 @@ static enum power_supply_property fg_psy_props[] = { POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, POWER_SUPPLY_PROP_CC_STEP, POWER_SUPPLY_PROP_CC_STEP_SEL, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_COLD_THERMAL_LEVEL, +#endif POWER_SUPPLY_PROP_BATT_AGE_LEVEL, POWER_SUPPLY_PROP_POWER_NOW, POWER_SUPPLY_PROP_POWER_AVG, POWER_SUPPLY_PROP_SCALE_MODE_EN, POWER_SUPPLY_PROP_CALIBRATE, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_FASTCHARGE_MODE, + POWER_SUPPLY_PROP_FFC_TERMINATION_CURRENT, + POWER_SUPPLY_PROP_SYS_TERMINATION_CURRENT, + POWER_SUPPLY_PROP_FFC_SYS_TERMINATION_CURRENT, + POWER_SUPPLY_PROP_VBATT_FULL_VOL, + POWER_SUPPLY_PROP_FFC_VBATT_FULL_VOL, + POWER_SUPPLY_PROP_KI_COEFF_CURRENT, +#endif }; static const struct power_supply_desc fg_psy_desc = { @@ -4739,7 +5705,9 @@ static int fg_parallel_current_en_cb(struct votable *votable, void *data, struct fg_dev *fg = data; struct fg_gen4_chip *chip = container_of(fg, struct fg_gen4_chip, fg); int rc; +#if !defined(CONFIG_MACH_XIAOMI_VAYU) && !defined(CONFIG_MACH_XIAOMI_NABU) u8 val, mask; +#endif vote(chip->mem_attn_irq_en_votable, MEM_ATTN_IRQ_VOTER, true, 0); @@ -4748,6 +5716,7 @@ static int fg_parallel_current_en_cb(struct votable *votable, void *data, if (rc < 0) return rc; +#if !defined(CONFIG_MACH_XIAOMI_VAYU) && !defined(CONFIG_MACH_XIAOMI_NABU) val = enable ? SMB_MEASURE_EN_BIT : 0; mask = SMB_MEASURE_EN_BIT; rc = fg_masked_write(fg, BATT_INFO_FG_CNV_CHAR_CFG(fg), mask, val); @@ -4757,6 +5726,7 @@ static int fg_parallel_current_en_cb(struct votable *votable, void *data, vote(chip->mem_attn_irq_en_votable, MEM_ATTN_IRQ_VOTER, false, 0); fg_dbg(fg, FG_STATUS, "Parallel current summing: %d\n", enable); +#endif return rc; } @@ -5433,6 +6403,16 @@ static int fg_parse_ki_coefficients(struct fg_dev *fg) of_property_read_u32(node, "qcom,ki-coeff-chg-med-hi-thresh-ma", &chip->dt.ki_coeff_med_hi_chg_thr_ma); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chip->dt.ffc_ki_coeff_lo_med_chg_thr_ma = -EINVAL; + of_property_read_u32(node, "qcom,ffc-ki-coeff-chg-low-med-thresh-ma", + &chip->dt.ffc_ki_coeff_lo_med_chg_thr_ma); + + chip->dt.ffc_ki_coeff_med_hi_chg_thr_ma = -EINVAL; + of_property_read_u32(node, "qcom,ffc-ki-coeff-chg-med-hi-thresh-ma", + &chip->dt.ffc_ki_coeff_med_hi_chg_thr_ma); +#endif + chip->dt.ki_coeff_lo_med_dchg_thr_ma = 50; of_property_read_u32(node, "qcom,ki-coeff-dischg-low-med-thresh-ma", &chip->dt.ki_coeff_lo_med_dchg_thr_ma); @@ -5605,6 +6585,9 @@ static int fg_gen4_parse_nvmem_dt(struct fg_gen4_chip *chip) #define DEFAULT_EMPTY_VOLT_MV 2812 #define DEFAULT_SYS_MIN_VOLT_MV 2800 #define DEFAULT_SYS_TERM_CURR_MA -125 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define DEFAULT_FFC_SYS_TERM_CURR_MA -1125 +#endif #define DEFAULT_CUTOFF_CURR_MA 200 #define DEFAULT_DELTA_SOC_THR 5 /* 0.5 % */ #define DEFAULT_CL_START_SOC 15 @@ -5616,7 +6599,11 @@ static int fg_gen4_parse_nvmem_dt(struct fg_gen4_chip *chip) #define DEFAULT_CL_MAX_LIM_DECIPERC 0 #define DEFAULT_CL_DELTA_BATT_SOC 10 #define BTEMP_DELTA_LOW 0 +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define BTEMP_DELTA_HIGH 10 +#else #define BTEMP_DELTA_HIGH 3 +#endif #define DEFAULT_ESR_PULSE_THRESH_MA 47 #define DEFAULT_ESR_MEAS_CURR_MA 120 #define DEFAULT_SCALE_VBATT_THR_MV 3400 @@ -5628,6 +6615,9 @@ static int fg_gen4_parse_dt(struct fg_gen4_chip *chip) u32 base, temp; u8 subtype; int rc; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int size; +#endif if (!node) { dev_err(fg->dev, "device tree node missing\n"); @@ -5750,6 +6740,14 @@ static int fg_gen4_parse_dt(struct fg_gen4_chip *chip) else chip->dt.sys_term_curr_ma = temp; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + rc = of_property_read_u32(node, "qcom,fg-ffc-sys-term-current", &temp); + if (rc < 0) + chip->dt.ffc_sys_term_curr_ma = DEFAULT_FFC_SYS_TERM_CURR_MA; + else + chip->dt.ffc_sys_term_curr_ma = temp; +#endif + rc = of_property_read_u32(node, "qcom,fg-delta-soc-thr", &temp); if (rc < 0) chip->dt.delta_soc_thr = DEFAULT_DELTA_SOC_THR; @@ -5762,6 +6760,29 @@ static int fg_gen4_parse_dt(struct fg_gen4_chip *chip) return -EINVAL; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + size = 0; + of_get_property(node, "qcom,soc_decimal_rate", &size); + if (size) { + chip->dt.dec_rate_seq = devm_kzalloc(fg->dev, + size, GFP_KERNEL); + if (chip->dt.dec_rate_seq) { + chip->dt.dec_rate_len = + (size / sizeof(*chip->dt.dec_rate_seq)); + if (chip->dt.dec_rate_len % 2) { + pr_err("invalid soc decimal rate seq\n"); + return -EINVAL; + } + of_property_read_u32_array(node, + "qcom,soc_decimal_rate", + chip->dt.dec_rate_seq, + chip->dt.dec_rate_len); + } else { + pr_err("error allocating memory for dec_rate_seq\n"); + } + } +#endif + chip->dt.esr_timer_chg_fast[TIMER_RETRY] = -EINVAL; chip->dt.esr_timer_chg_fast[TIMER_MAX] = -EINVAL; rc = fg_parse_dt_property_u32_array(node, "qcom,fg-esr-timer-chg-fast", @@ -5795,6 +6816,11 @@ static int fg_gen4_parse_dt(struct fg_gen4_chip *chip) chip->dt.force_load_profile = of_property_read_bool(node, "qcom,fg-force-load-profile"); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chip->dt.shutdown_delay_enable = of_property_read_bool(node, + "qcom,shutdown-delay-enable"); +#endif + rc = of_property_read_u32(node, "qcom,cl-start-capacity", &temp); if (rc < 0) chip->cl->dt.max_start_soc = DEFAULT_CL_START_SOC; @@ -5947,9 +6973,350 @@ static int fg_gen4_parse_dt(struct fg_gen4_chip *chip) chip->dt.sys_min_volt_mv = DEFAULT_SYS_MIN_VOLT_MV; of_property_read_u32(node, "qcom,fg-sys-min-voltage", &chip->dt.sys_min_volt_mv); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chip->cold_thermal_support = of_property_read_bool(node, + "qcom,cold-thermal-support"); + + size = 0; + of_get_property(node, "mi,cold_thermal_seq", &size); + if (size) { + fg->cold_thermal_seq = devm_kzalloc(fg->dev, + size, GFP_KERNEL); + if (fg->cold_thermal_seq) { + fg->cold_thermal_len = + (size / sizeof(int)); + if (fg->cold_thermal_len % 4) { + pr_err("invalid cold thermal seq\n"); + return -EINVAL; + } + of_property_read_u32_array(node, + "mi,cold_thermal_seq", + (int *)fg->cold_thermal_seq, + fg->cold_thermal_len); + fg->cold_thermal_len = fg->cold_thermal_len / 4; + } else { + pr_err("error allocating memory for cold thermal seq\n"); + } + } +#endif + return 0; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define SOC_WORK_MS 20000 +static void soc_work_fn(struct work_struct *work) +{ + struct fg_dev *fg = container_of(work, + struct fg_dev, soc_work.work); + struct fg_gen4_chip *chip = container_of(fg, + struct fg_gen4_chip, fg); + int msoc = 0, soc = 0, curr_ua = 0, volt_uv = 0, temp = 0; + int esr_uohms = 0; + int cycle_count; + int rc; + static int prev_soc = -EINVAL; + + rc = fg_gen4_get_prop_capacity(fg, &soc); + if (rc < 0) + pr_err("Error in getting capacity, rc=%d\n", rc); + + rc = fg_get_msoc_raw(fg, &msoc); + if (rc < 0) + pr_err("Error in getting msoc, rc=%d\n", rc); + + rc = fg_get_battery_resistance(fg, &esr_uohms); + if (rc < 0) + pr_err("Error in getting esr_uohms, rc=%d\n", rc); + + fg_get_battery_current(fg, &curr_ua); + if (rc < 0) + pr_err("failed to get current, rc=%d\n", rc); + + rc = fg_get_battery_voltage(fg, &volt_uv); + if (rc < 0) + pr_err("failed to get voltage, rc=%d\n", rc); + + rc = fg_gen4_get_battery_temp(fg, &temp); + if (rc < 0) + pr_err("Error in getting batt_temp, rc=%d\n", rc); + + rc = get_cycle_count(chip->counter, &cycle_count); + if (rc < 0) + pr_err("failed to get cycle count, rc=%d\n", rc); + + pr_info("adjust_soc: s %d r %d i %d v %d t %d cc %d m 0x%02x\n", + soc, + esr_uohms, + curr_ua/1000, + volt_uv/1000, + temp, + cycle_count, + msoc); + + if (temp < 450 && fg->last_batt_temp >= 450) { + /* follow the way that fg_notifier_cb use wake lock */ + pm_stay_awake(fg->dev); + schedule_work(&fg->status_change_work); + } + + fg->last_batt_temp = temp; + + /* if soc changes, report power supply changed uevent */ + if (soc != prev_soc) { + if (fg->batt_psy) + power_supply_changed(fg->batt_psy); + prev_soc = soc; + } + + schedule_delayed_work( + &fg->soc_work, + msecs_to_jiffies(SOC_WORK_MS)); +} + +static void empty_restart_fg_work(struct work_struct *work) +{ + struct fg_dev *fg = container_of(work, struct fg_dev, + empty_restart_fg_work.work); + union power_supply_propval prop = {0, }; + int usb_present = 0; + int rc; + + if (usb_psy_initialized(fg)) { + rc = power_supply_get_property(fg->usb_psy, + POWER_SUPPLY_PROP_PRESENT, &prop); + if (rc < 0) { + pr_err("Couldn't read usb present prop rc=%d\n", rc); + return; + } + usb_present = prop.intval; + } + + /* only when usb is absent, restart fg */ + if (!usb_present) { + if (fg->profile_load_status == PROFILE_LOADED) { + pr_info("soc empty after cold to warm, need to restart fg\n"); + fg->empty_restart_fg = true; + rc = fg_restart(fg, SOC_READY_WAIT_TIME_MS); + if (rc < 0) { + pr_err("Error in restarting FG, rc=%d\n", rc); + fg->empty_restart_fg = false; + return; + } + pr_info("FG restart done\n"); + if (batt_psy_initialized(fg)) + power_supply_changed(fg->batt_psy); + } else { + schedule_delayed_work( + &fg->empty_restart_fg_work, + msecs_to_jiffies(RESTART_FG_WORK_MS)); + } + } +} + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static int calculate_delta_time(struct timespec *time_stamp, int *delta_time_s) +{ + struct timespec now_time; + + /* default to delta time = 0 if anything fails */ + *delta_time_s = 0; + + get_monotonic_boottime(&now_time); + *delta_time_s = (now_time.tv_sec - time_stamp->tv_sec); + + /* remember this time */ + *time_stamp = now_time; + return 0; // git +} // git + +static int calculate_average_current(struct fg_gen4_chip *chip) +{ + struct fg_dev *fg = &chip->fg; + int i; + int iavg_ma = fg->param.batt_ma; + + /* only continue if ibat has changed */ + if (fg->param.batt_ma == fg->param.batt_ma_prev) + goto unchanged; + else + fg->param.batt_ma_prev = fg->param.batt_ma; + + fg->param.batt_ma_avg_samples[fg->param.samples_index] = iavg_ma; + fg->param.samples_index = (fg->param.samples_index + 1) % BATT_MA_AVG_SAMPLES; + fg->param.samples_num++; + + if (fg->param.samples_num >= BATT_MA_AVG_SAMPLES) + fg->param.samples_num = BATT_MA_AVG_SAMPLES; + + if (fg->param.samples_num) { + iavg_ma = 0; + /* maintain a AVG_SAMPLES sample average of ibat */ + for (i = 0; i < fg->param.samples_num; i++) { + pr_debug("iavg_samples_ma[%d] = %d\n", i, fg->param.batt_ma_avg_samples[i]); + iavg_ma += fg->param.batt_ma_avg_samples[i]; + } + fg->param.batt_ma_avg = DIV_ROUND_CLOSEST(iavg_ma, fg->param.samples_num); + } + +unchanged: + pr_info("current_now_ma=%d averaged_iavg_ma=%d\n", + fg->param.batt_ma, fg->param.batt_ma_avg); + return fg->param.batt_ma_avg; +} + +static void fg_battery_soc_smooth_tracking(struct fg_gen4_chip *chip) +{ + struct fg_dev *fg = &chip->fg; + int delta_time = 0; + int soc_changed; + int last_batt_soc = fg->param.batt_soc; + int time_since_last_change_sec; + + struct timespec last_change_time = fg->param.last_soc_change_time; + + calculate_delta_time(&last_change_time, &time_since_last_change_sec); + + if (fg->param.batt_temp > 150) { + /* Battery in normal temperture */ + if (fg->param.batt_ma < 0 || + (abs(fg->param.batt_raw_soc - fg->param.batt_soc) > 2)) + delta_time = time_since_last_change_sec / 20; + else + delta_time = time_since_last_change_sec / 60; + } else { + /* Battery in low temperture */ + calculate_average_current(chip); + /* Calculated average current > 1000mA */ + if ((fg->param.batt_ma_avg > 1000000) || + (abs(fg->param.batt_raw_soc - fg->param.batt_soc) > 2)) + /* Heavy loading current, ignore battery soc limit*/ + delta_time = time_since_last_change_sec / 10; + else + delta_time = time_since_last_change_sec / 20; + } + + if (delta_time < 0) + delta_time = 0; + + soc_changed = min(1, delta_time); + + if (last_batt_soc >= 0) { + if (last_batt_soc != 100 + && fg->param.batt_raw_soc >= 95 + && fg->charge_status == POWER_SUPPLY_STATUS_FULL) + // Unlikely status + last_batt_soc = fg->param.update_now ? + 100 : last_batt_soc + soc_changed; + else if (last_batt_soc < fg->param.batt_raw_soc && + fg->param.batt_ma < 0) + /* Battery in charging status + * update the soc when resuming device + */ + last_batt_soc = fg->param.update_now ? + fg->param.batt_raw_soc : last_batt_soc + soc_changed; + else if (last_batt_soc > fg->param.batt_raw_soc +#ifdef CONFIG_MACH_XIAOMI_NABU + && fg->charge_status != POWER_SUPPLY_STATUS_FULL +#endif + && fg->param.batt_ma > 0) + /* Battery in discharging status + * update the soc when resuming device + */ + last_batt_soc = fg->param.update_now ? + fg->param.batt_raw_soc : last_batt_soc - soc_changed; + + fg->param.update_now = false; + } else { + last_batt_soc = fg->param.batt_raw_soc; + } + + if (fg->param.batt_soc != last_batt_soc) { + fg->param.batt_soc = last_batt_soc; + fg->param.last_soc_change_time = last_change_time; + if (batt_psy_initialized(fg)) + power_supply_changed(fg->batt_psy); + } + + pr_info("soc:%d, last_soc:%d, raw_soc:%d, soc_changed:%d.\n", + fg->param.batt_soc, last_batt_soc, + fg->param.batt_raw_soc, soc_changed); +} + +static int fg_dynamic_set_cutoff_voltage(struct fg_dev *fg, + int cut_off_mv) +{ + int rc; + u8 buf[4]; + + pr_err("set dynamic cutoff voltage to: %d\n", cut_off_mv); + + fg_encode(fg->sp, FG_SRAM_CUTOFF_VOLT, cut_off_mv, buf); + rc = fg_sram_write(fg, fg->sp[FG_SRAM_CUTOFF_VOLT].addr_word, + fg->sp[FG_SRAM_CUTOFF_VOLT].addr_byte, buf, + fg->sp[FG_SRAM_CUTOFF_VOLT].len, FG_IMA_DEFAULT); + if (rc < 0) { + pr_err("Error in writing cutoff_volt, rc=%d\n", rc); + return rc; + } + + return rc; +} + +#define LOW_DISCHARGE_TEMP_TRH 150 +#define LOW_DISCHARGE_TEMP_HYS 20 +#define LOW_TEMP_CUTOFF_VOL_MV 3200 +#define MONITOR_SOC_WAIT_MS 1000 +#define MONITOR_SOC_WAIT_PER_MS 10000 +static void soc_monitor_work(struct work_struct *work) +{ + int rc; + struct fg_dev *fg = container_of(work, + struct fg_dev, + soc_monitor_work.work); + struct fg_gen4_chip *chip = container_of(fg, struct fg_gen4_chip, fg); + + // Update battery information + rc = fg_get_battery_current(fg, &fg->param.batt_ma); + if (rc < 0) + pr_err("failded to get battery current, rc=%d\n", rc); + + rc = fg_gen4_get_prop_capacity(fg, &fg->param.batt_raw_soc); + if (rc < 0) + pr_err("failed to get battery capacity, rc=%d\n", rc); + + rc = fg_gen4_get_battery_temp(fg, &fg->param.batt_temp); + if (rc < 0) + pr_err("failed to get battery temperature, rc=%d\n", rc); + + if (fg->soc_reporting_ready) + fg_battery_soc_smooth_tracking(chip); + + pr_info("soc:%d, raw_soc:%d, c:%d, s:%d\n", + fg->param.batt_soc, fg->param.batt_raw_soc, + fg->param.batt_ma, fg->charge_status); + + if (chip->cold_thermal_support) { + if (!fg->batt_temp_low + && fg->param.batt_temp <= LOW_DISCHARGE_TEMP_TRH) { + rc = fg_dynamic_set_cutoff_voltage(fg, LOW_TEMP_CUTOFF_VOL_MV); + if (rc < 0) + pr_err("fg_dynamic_set_cutoff_voltage set failed\n"); + fg->batt_temp_low = true; + } else if (fg->batt_temp_low && (fg->param.batt_temp + > LOW_DISCHARGE_TEMP_TRH + LOW_DISCHARGE_TEMP_HYS)) { + fg_dynamic_set_cutoff_voltage(fg, chip->dt.cutoff_volt_mv); + fg->batt_temp_low = false; + } + } + + schedule_delayed_work(&fg->soc_monitor_work, + msecs_to_jiffies(MONITOR_SOC_WAIT_PER_MS)); +} +#endif +#endif + static void fg_gen4_cleanup(struct fg_gen4_chip *chip) { struct fg_dev *fg = &chip->fg; @@ -5961,7 +7328,13 @@ static void fg_gen4_cleanup(struct fg_gen4_chip *chip) fg_gen4_exit_soc_scale(chip); cancel_delayed_work_sync(&fg->profile_load_work); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + cancel_delayed_work_sync(&fg->empty_restart_fg_work); +#endif cancel_delayed_work_sync(&fg->sram_dump_work); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + cancel_delayed_work_sync(&fg->soc_work); +#endif cancel_work_sync(&chip->pl_current_en_work); power_supply_unreg_notifier(&fg->nb); @@ -6013,6 +7386,37 @@ static void fg_gen4_post_init(struct fg_gen4_chip *chip) fg_dbg(fg, FG_STATUS, "Disabled wakeable irqs for debug board\n"); } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define IBAT_OLD_WORD 317 +#define IBAT_OLD_OFFSET 0 +#define BATT_CURRENT_NUMR 488281 +#define BATT_CURRENT_DENR 1000 +int fg_get_batt_isense(struct fg_dev *fg, int *val) +{ + int rc; + u8 buf[2]; + int64_t temp = 0; + + rc = fg_sram_read(fg, IBAT_OLD_WORD, IBAT_OLD_OFFSET, buf, 2, + FG_IMA_DEFAULT); + if (rc < 0) { + pr_err("Error in reading %04x[%d] rc=%d\n", IBAT_OLD_WORD, + IBAT_OLD_OFFSET, rc); + return rc; + } + + temp = buf[0] | buf[1] << 8; + + /* Sign bit is bit 15 */ + temp = sign_extend32(temp, 15); + *val = div_s64((s64)temp * BATT_CURRENT_NUMR, BATT_CURRENT_DENR); + pr_info("read batt isense: %d[%d]%d\n", + (*val)/10, *val, (*val)/1000); + + return 0; +} +#endif + static int fg_gen4_probe(struct platform_device *pdev) { struct fg_gen4_chip *chip; @@ -6034,7 +7438,42 @@ static int fg_gen4_probe(struct platform_device *pdev) chip->ki_coeff_full_soc[0] = -EINVAL; chip->ki_coeff_full_soc[1] = -EINVAL; chip->esr_soh_cycle_count = -EINVAL; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + fg->vbat_critical_low_count = 0; + fg->vbatt_full_volt_uv = 0; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + fg->curr_cold_thermal_level = 1; +#endif +#endif chip->calib_level = -EINVAL; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + fg->fake_authentic = -EINVAL; + fg->fake_chip_ok = -EINVAL; + fg->batt_fake_temp = -EINVAL; + chip->battery_authentic_result = -EINVAL; +#ifdef CONFIG_MACH_XIAOMI_NABU + chip->battery_authentic_slave_result = -EINVAL; + chip->battery_chip_ok = -EINVAL; + chip->battery_chip_slave_ok = -EINVAL; +#endif + memset(chip->ds_romid, 0, 8); +#ifdef CONFIG_MACH_XIAOMI_NABU + memset(chip->ds_slave_romid, 0, 8); +#endif + memset(chip->ds_status, 0, 8); +#ifdef CONFIG_MACH_XIAOMI_NABU + memset(chip->ds_slave_status, 0, 8); +#endif + memset(chip->ds_page0, 0, 16); +#ifdef CONFIG_MACH_XIAOMI_NABU + memset(chip->ds_slave_page0, 0, 16); +#endif + retry_batt_profile = 0; + retry_battery_authentic_result = 0; + retry_ds_romid = 0; + retry_ds_status = 0; + retry_ds_page0 = 0; +#endif fg->regmap = dev_get_regmap(fg->dev->parent, NULL); if (!fg->regmap) { dev_err(fg->dev, "Parent regmap is unavailable\n"); @@ -6051,11 +7490,25 @@ static int fg_gen4_probe(struct platform_device *pdev) init_completion(&chip->mem_attn); INIT_WORK(&fg->status_change_work, status_change_work); INIT_WORK(&chip->esr_calib_work, esr_calib_work); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + INIT_WORK(&chip->vbat_sync_work, vbat_sync_work); +#endif INIT_WORK(&chip->soc_scale_work, soc_scale_work); INIT_DELAYED_WORK(&fg->profile_load_work, profile_load_work); INIT_DELAYED_WORK(&fg->sram_dump_work, sram_dump_work); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + INIT_DELAYED_WORK(&fg->soc_work, soc_work_fn); + INIT_DELAYED_WORK(&fg->empty_restart_fg_work, empty_restart_fg_work); +#endif INIT_DELAYED_WORK(&chip->pl_enable_work, pl_enable_work); INIT_WORK(&chip->pl_current_en_work, pl_current_en_work); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + INIT_DELAYED_WORK(&fg->soc_monitor_work, soc_monitor_work); + INIT_DELAYED_WORK(&chip->battery_authentic_work, battery_authentic_work); + INIT_DELAYED_WORK(&chip->ds_romid_work, ds_romid_work); + INIT_DELAYED_WORK(&chip->ds_status_work, ds_status_work); + INIT_DELAYED_WORK(&chip->ds_page0_work, ds_page0_work); +#endif fg->awake_votable = create_votable("FG_WS", VOTE_SET_ANY, fg_awake_cb, fg); @@ -6153,6 +7606,12 @@ static int fg_gen4_probe(struct platform_device *pdev) goto exit; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + fg->max_verify_psy = power_supply_get_by_name("batt_verify"); +#endif +#ifdef CONFIG_MACH_XIAOMI_NABU + fg->max_verify_slave_psy = power_supply_get_by_name("batt_verify_slave"); +#endif /* Register the power supply */ fg_psy_cfg.drv_data = fg; fg_psy_cfg.of_node = NULL; @@ -6166,6 +7625,16 @@ static int fg_gen4_probe(struct platform_device *pdev) goto exit; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chip->battery_authentic_result != true +#ifdef CONFIG_MACH_XIAOMI_NABU + || chip->battery_authentic_slave_result != true +#endif + ) { + schedule_delayed_work(&chip->battery_authentic_work, + msecs_to_jiffies(0)); + } +#endif fg->nb.notifier_call = fg_notifier_cb; rc = power_supply_reg_notifier(&fg->nb); if (rc < 0) { @@ -6227,6 +7696,27 @@ static int fg_gen4_probe(struct platform_device *pdev) fg_gen4_post_init(chip); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + schedule_delayed_work(&fg->soc_work, 0); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + fg->param.batt_soc = -EINVAL; + schedule_delayed_work(&fg->soc_monitor_work, + msecs_to_jiffies(MONITOR_SOC_WAIT_MS)); +#endif + + /* + * if vbat is above 3.7V and msoc is 0% and battery temperature is + * above 15 degree, we restart fg to do new first soc calculate to + * improve user experience when device is shutdown in cold then + * try to power on in normal temperature room. + */ + if ((volt_uv >= VBAT_RESTART_FG_EMPTY_UV) + && (msoc == 0) && (batt_temp >= TEMP_THR_RESTART_FG)) + schedule_delayed_work(&fg->empty_restart_fg_work, + msecs_to_jiffies(RESTART_FG_START_WORK_MS)); +#endif + pr_debug("FG GEN4 driver probed successfully\n"); return 0; exit: @@ -6247,6 +7737,9 @@ static void fg_gen4_shutdown(struct platform_device *pdev) struct fg_gen4_chip *chip = dev_get_drvdata(&pdev->dev); struct fg_dev *fg = &chip->fg; int rc, bsoc; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int msoc; +#endif fg_unregister_interrupts(fg, chip, FG_GEN4_IRQ_MAX); @@ -6260,13 +7753,25 @@ static void fg_gen4_shutdown(struct platform_device *pdev) rc); } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = fg_gen4_get_prop_capacity(fg, &msoc); + if (rc < 0) { + pr_err("Error in getting capacity, rc=%d\n", rc); + return; + } +#endif + rc = fg_get_sram_prop(fg, FG_SRAM_BATT_SOC, &bsoc); if (rc < 0) { pr_err("Error in getting BATT_SOC, rc=%d\n", rc); return; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (fg->charge_full || (msoc == 100)) { +#else if (fg->charge_full) { +#endif /* We need 2 most significant bytes here */ bsoc = (u32)bsoc >> 16; @@ -6290,6 +7795,9 @@ static int fg_gen4_suspend(struct device *dev) struct fg_gen4_chip *chip = dev_get_drvdata(dev); struct fg_dev *fg = &chip->fg; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + cancel_delayed_work_sync(&fg->soc_work); +#endif cancel_delayed_work_sync(&chip->ttf->ttf_work); if (fg_sram_dump) cancel_delayed_work_sync(&fg->sram_dump_work); @@ -6300,11 +7808,29 @@ static int fg_gen4_resume(struct device *dev) { struct fg_gen4_chip *chip = dev_get_drvdata(dev); struct fg_dev *fg = &chip->fg; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int val = 0; +#endif + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (!fg->input_present) + fg_get_batt_isense(fg, &val); + + schedule_delayed_work( + &fg->soc_work, msecs_to_jiffies(SOC_WORK_MS)); +#endif schedule_delayed_work(&chip->ttf->ttf_work, 0); if (fg_sram_dump) schedule_delayed_work(&fg->sram_dump_work, msecs_to_jiffies(fg_sram_dump_period_ms)); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + fg->param.update_now = true; + schedule_delayed_work(&fg->soc_monitor_work, + msecs_to_jiffies(MONITOR_SOC_WAIT_MS)); +#endif + return 0; } @@ -6330,6 +7856,21 @@ static struct platform_driver fg_gen4_driver = { .shutdown = fg_gen4_shutdown, }; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static int __init early_parse_batt_profile_vendor_id(char *p) +{ + if (p) { + if (!strcmp(p, "0A")) + is_batt_vendor_sunwoda = true; + else if (!strcmp(p, "0B")) + is_batt_vendor_nvt = true; + } + + return 0; +} +early_param("androidboot.profile_vendor_id", early_parse_batt_profile_vendor_id); +#endif + module_platform_driver(fg_gen4_driver); MODULE_DESCRIPTION("QPNP Fuel gauge GEN4 driver"); diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c index 5651c8c0ccf9..7672839bb7d1 100644 --- a/drivers/power/supply/qcom/qpnp-qg.c +++ b/drivers/power/supply/qcom/qpnp-qg.c @@ -4558,6 +4558,14 @@ static int qpnp_qg_probe(struct platform_device *pdev) return rc; } +#ifdef CONFIG_MACH_XIAOMI_VAYU + rc = qg_sanitize_sdam(chip); + if (rc < 0) { + pr_err("Failed to sanitize SDAM, rc=%d\n", rc); + return rc; + } +#endif + rc = qg_soc_init(chip); if (rc < 0) { pr_err("Failed to initialize SOC scaling init rc=%d\n", rc); diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c index 199c1f375882..9f7e1b81c73d 100644 --- a/drivers/power/supply/qcom/qpnp-smb5.c +++ b/drivers/power/supply/qcom/qpnp-smb5.c @@ -76,6 +76,15 @@ static struct smb_params smb5_pmi632_params = { .max_u = 1000000, .step_u = 250000, }, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + .dc_icl = { + .name = "DC input current limit", + .reg = DCDC_CFG_REF_MAX_PSNS_REG, + .min_u = 0, + .max_u = 1500000, + .step_u = 50000, + }, +#endif .jeita_cc_comp_hot = { .name = "jeita fcc reduction", .reg = JEITA_CCCOMP_CFG_HOT_REG, @@ -156,15 +165,24 @@ static struct smb_params smb5_pm8150b_params = { .name = "usb otg current limit", .reg = DCDC_OTG_CURRENT_LIMIT_CFG_REG, .min_u = 500000, +#ifdef CONFIG_MACH_XIAOMI_NABU + .max_u = 2000000, +#else .max_u = 3000000, +#endif .step_u = 500000, }, .dc_icl = { .name = "DC input current limit", .reg = DCDC_CFG_REF_MAX_PSNS_REG, .min_u = 0, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + .max_u = 1200000, + .step_u = 40000, +#else .max_u = DCIN_ICL_MAX_UA, .step_u = 50000, +#endif }, .jeita_cc_comp_hot = { .name = "jeita fcc reduction", @@ -210,6 +228,9 @@ static struct smb_params smb5_pm8150b_params = { struct smb_dt_props { int usb_icl_ua; +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + int dc_icl_ua; +#endif struct device_node *revid_dev_node; enum float_options float_option; int chg_inhibit_thr_mv; @@ -222,6 +243,9 @@ struct smb_dt_props { int auto_recharge_vbat_mv; int wd_bark_time; int wd_snarl_time_cfg; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int batt_unverify_fcc_ua; +#endif int batt_profile_fcc_ua; int batt_profile_fv_uv; int term_current_src; @@ -236,6 +260,10 @@ struct smb5 { struct smb_dt_props dt; }; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static struct smb_charger *__smbchg; +#endif + static int __debug_mask; module_param_named( debug_mask, __debug_mask, int, 0600 @@ -251,6 +279,13 @@ module_param_named( weak_chg_icl_ua, __weak_chg_icl_ua, int, 0600 ); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static bool disable_thermal = false; +module_param_named( + disable_thermal, disable_thermal, bool, 0600 +); +#endif + enum { BAT_THERM = 0, MISC_THERM, @@ -258,6 +293,62 @@ enum { SMB_THERM, }; +#ifdef CONFIG_MACH_XIAOMI_NABU +static BLOCKING_NOTIFIER_HEAD(pen_charge_state_notifier_list); + +int pen_charge_state_notifier_register_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&pen_charge_state_notifier_list, nb); +} +EXPORT_SYMBOL(pen_charge_state_notifier_register_client); + +int pen_charge_state_notifier_unregister_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&pen_charge_state_notifier_list, nb); +} +EXPORT_SYMBOL(pen_charge_state_notifier_unregister_client); + +int pen_charge_state_notifier_call_chain(unsigned long val, void *v) +{ + return blocking_notifier_call_chain(&pen_charge_state_notifier_list, val, v); +} +EXPORT_SYMBOL(pen_charge_state_notifier_call_chain); +#endif + +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) +static int smb5_get_prop_input_voltage_regulation(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc; +/* + if (!chg->idtp_psy) { + chg->idtp_psy = power_supply_get_by_name("idt"); + if (!chg->idtp_psy) + return -EINVAL; + } +*/ + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) + chg->wls_chip_psy = chg->idtp_psy; + else { + chg->wip_psy = power_supply_get_by_name("rx1618"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + if (chg->wls_chip_psy) + rc = power_supply_get_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, val); + + val->intval = 1000*val->intval;//IDT in mV + + return rc; +} +#endif + static const struct clamp_config clamp_levels[] = { { {0x11C6, 0x11F9, 0x13F1}, {0x60, 0x2E, 0x90} }, { {0x11C6, 0x11F9, 0x13F1}, {0x60, 0x2B, 0x9C} }, @@ -387,21 +478,102 @@ static int smb5_configure_internal_pull(struct smb_charger *chg, int type, return rc; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static int read_step_chg_range_data_from_node(struct device_node *node, + const char *prop_str, struct six_pin_step_data *ranges) +{ + int rc = 0, length, per_tuple_length, tuples; + + if (!node || !prop_str || !ranges) { + pr_err("Invalid parameters passed\n"); + return -EINVAL; + } + + rc = of_property_count_elems_of_size(node, prop_str, sizeof(u32)); + if (rc < 0) { + pr_err("Count %s failed, rc=%d\n", prop_str, rc); + return rc; + } + + length = rc; + per_tuple_length = sizeof(struct six_pin_step_data) / sizeof(u32); + if (length % per_tuple_length) { + pr_err("%s length (%d) should be multiple of %d\n", + prop_str, length, per_tuple_length); + return -EINVAL; + } + tuples = length / per_tuple_length; + + if (tuples > MAX_STEP_ENTRIES) { + pr_err("too many entries(%d), only %d allowed\n", + tuples, MAX_STEP_ENTRIES); + return -EINVAL; + } + + rc = of_property_read_u32_array(node, prop_str, + (u32 *)ranges, length); + if (rc) { + pr_err("Read %s failed, rc=%d\n", prop_str, rc); + return rc; + } + + return rc; +} + +static int smb5_charge_step_charge_init(struct smb_charger *chg, + struct device_node *node) +{ + int rc = 0; + + rc = read_step_chg_range_data_from_node(node, + "mi,six-pin-step-chg-params", + chg->six_pin_step_cfg); + if (rc < 0) { + pr_debug("Read mi,six-pin-step-chg-params failed charger node, rc=%d\n", + rc); + chg->six_pin_step_charge_enable = false; + } + + return rc; +} +#endif + +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) +int smblib_change_psns_to_curr(struct smb_charger *chg, int uv) +{ + uv = uv * PSNS_CURRENT_SAMPLE_RATE / PSNS_CURRENT_SAMPLE_RESIS; + + return uv; +} +#endif + #define MICRO_1P5A 1500000 #define MICRO_P1A 100000 #define MICRO_1PA 1000000 #define MICRO_3PA 3000000 +#ifdef CONFIG_MACH_XIAOMI_NABU +#define MICRO_1P8A_FOR_DCP 2000000 +#elif defined(CONFIG_MACH_XIAOMI_SM8150) +#define MICRO_1P8A_FOR_DCP 1800000 +#endif #define MICRO_4PA 4000000 #define OTG_DEFAULT_DEGLITCH_TIME_MS 50 #define DEFAULT_WD_BARK_TIME 64 #define DEFAULT_WD_SNARL_TIME_8S 0x07 #define DEFAULT_FCC_STEP_SIZE_UA 100000 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define DEFAULT_FCC_STEP_UPDATE_DELAY_MS 100 +#else #define DEFAULT_FCC_STEP_UPDATE_DELAY_MS 1000 +#endif static int smb5_parse_dt(struct smb5 *chip) { struct smb_charger *chg = &chip->chg; struct device_node *node = chg->dev->of_node; int rc, byte_len, tmp; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int i; +#endif if (!node) { pr_err("device tree node missing\n"); @@ -427,11 +599,59 @@ static int smb5_parse_dt(struct smb5 *chip) chg->sw_jeita_enabled = of_property_read_bool(node, "qcom,sw-jeita-enable"); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->pps_fcc_therm_work_disabled = of_property_read_bool(node, + "mi,pps-thermal-setting-disable"); + + chg->use_bq_pump = of_property_read_bool(node, + "mi,use-bq-pump"); +#endif + chg->pd_not_supported = chg->pd_not_supported || of_property_read_bool(node, "qcom,usb-pd-disable"); chg->lpd_disabled = chg->lpd_disabled || of_property_read_bool(node, "qcom,lpd-disable"); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->lpd_enabled = of_property_read_bool(node, + "qcom,lpd-enable"); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->six_pin_step_charge_enable = of_property_read_bool(node, + "mi,six-pin-step-chg"); +#endif + + chg->dynamic_fv_enabled = of_property_read_bool(node, + "qcom,dynamic-fv-enable"); + + chg->qc_class_ab = of_property_read_bool(node, + "qcom,distinguish-qc-class-ab"); + + chg->support_wireless = of_property_read_bool(node, + "qcom,support-wireless"); + +#ifdef CONFIG_MACH_XIAOMI_NABU + chg->qc3p5_supported = of_property_read_bool(node, + "mi,support-qc3p5-without-smb"); +#endif + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->support_ffc = of_property_read_bool(node, + "mi,support-ffc"); + + rc = of_property_read_u32(node, "mi,ffc-low-tbat", &chg->ffc_low_tbat); + if (rc < 0) { + pr_info("use default ffc_low_tbat\n"); + chg->ffc_low_tbat = DEFAULT_FFC_LOW_TBAT; + } + + rc = of_property_read_u32(node, "mi,ffc-high-tbat", &chg->ffc_high_tbat); + if (rc < 0) { + pr_info("use default ffc_high_tbat\n"); + chg->ffc_high_tbat = DEFAULT_FFC_HIGH_TBAT; + } +#endif +#endif rc = of_property_read_u32(node, "qcom,wd-bark-time-secs", &chip->dt.wd_bark_time); @@ -451,6 +671,15 @@ static int smb5_parse_dt(struct smb5 *chip) if (rc < 0) chip->dt.batt_profile_fcc_ua = -EINVAL; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->batt_profile_fcc_ua = chip->dt.batt_profile_fcc_ua; + + rc = of_property_read_u32(node, + "mi,fcc-batt-unverify-ua", &chip->dt.batt_unverify_fcc_ua); + if (rc < 0) + chip->dt.batt_unverify_fcc_ua = -EINVAL; +#endif + rc = of_property_read_u32(node, "qcom,fv-max-uv", &chip->dt.batt_profile_fv_uv); if (rc < 0) @@ -461,6 +690,13 @@ static int smb5_parse_dt(struct smb5 *chip) if (rc < 0) chip->dt.usb_icl_ua = -EINVAL; +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + rc = of_property_read_u32(node, + "qcom,dc-icl-ua", &chip->dt.dc_icl_ua); + if (rc < 0) + chip->dt.dc_icl_ua = -EINVAL; +#endif + rc = of_property_read_u32(node, "qcom,otg-cl-ua", &chg->otg_cl_ua); if (rc < 0) @@ -476,22 +712,27 @@ static int smb5_parse_dt(struct smb5 *chip) rc = of_property_read_u32(node, "qcom,chg-term-current-ma", &chip->dt.term_current_thresh_hi_ma); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->chg_term_current_thresh_hi_from_dts = chip->dt.term_current_thresh_hi_ma; +#endif + if (chip->dt.term_current_src == ITERM_SRC_ADC) rc = of_property_read_u32(node, "qcom,chg-term-base-current-ma", &chip->dt.term_current_thresh_lo_ma); - if (of_find_property(node, "qcom,thermal-mitigation", &byte_len)) { - chg->thermal_mitigation = devm_kzalloc(chg->dev, byte_len, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (of_find_property(node, "qcom,lpd_hwversion", &byte_len)) { + chg->lpd_hwversion = devm_kzalloc(chg->dev, byte_len, GFP_KERNEL); - if (chg->thermal_mitigation == NULL) + if (chg->lpd_hwversion == NULL) return -ENOMEM; - chg->thermal_levels = byte_len / sizeof(u32); + chg->lpd_levels = byte_len / sizeof(u32); rc = of_property_read_u32_array(node, - "qcom,thermal-mitigation", - chg->thermal_mitigation, - chg->thermal_levels); + "qcom,lpd_hwversion", + chg->lpd_hwversion, + byte_len / sizeof(u32)); if (rc < 0) { dev_err(chg->dev, "Couldn't read threm limits rc = %d\n", rc); @@ -499,101 +740,392 @@ static int smb5_parse_dt(struct smb5 *chip) } } - rc = of_property_read_u32(node, "qcom,charger-temp-max", - &chg->charger_temp_max); - if (rc < 0) - chg->charger_temp_max = -EINVAL; + if (of_find_property(node, "qcom,thermal-mitigation-dcp", &byte_len)) { + chg->thermal_mitigation_dcp = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); - rc = of_property_read_u32(node, "qcom,smb-temp-max", - &chg->smb_temp_max); - if (rc < 0) - chg->smb_temp_max = -EINVAL; + if (chg->thermal_mitigation_dcp == NULL) + return -ENOMEM; - rc = of_property_read_u32(node, "qcom,float-option", - &chip->dt.float_option); - if (!rc && (chip->dt.float_option < 0 || chip->dt.float_option > 4)) { - pr_err("qcom,float-option is out of range [0, 4]\n"); - return -EINVAL; + chg->thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-mitigation-dcp", + chg->thermal_mitigation_dcp, + chg->thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } } - chip->dt.hvdcp_disable = of_property_read_bool(node, - "qcom,hvdcp-disable"); - chg->hvdcp_disable = chip->dt.hvdcp_disable; +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + if (of_find_property(node, "qcom,thermal-mitigation-dc", &byte_len)) { + chg->thermal_mitigation_dc = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); - chip->dt.hvdcp_autonomous = of_property_read_bool(node, - "qcom,hvdcp-autonomous-enable"); + if (chg->thermal_mitigation_dc == NULL) + return -ENOMEM; - rc = of_property_read_u32(node, "qcom,chg-inhibit-threshold-mv", - &chip->dt.chg_inhibit_thr_mv); - if (!rc && (chip->dt.chg_inhibit_thr_mv < 0 || - chip->dt.chg_inhibit_thr_mv > 300)) { - pr_err("qcom,chg-inhibit-threshold-mv is incorrect\n"); - return -EINVAL; + chg->dc_thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-mitigation-dc", + chg->thermal_mitigation_dc, + chg->dc_thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } } - chip->dt.auto_recharge_soc = -EINVAL; - rc = of_property_read_u32(node, "qcom,auto-recharge-soc", - &chip->dt.auto_recharge_soc); - if (!rc && (chip->dt.auto_recharge_soc < 0 || - chip->dt.auto_recharge_soc > 100)) { - pr_err("qcom,auto-recharge-soc is incorrect\n"); - return -EINVAL; - } - chg->auto_recharge_soc = chip->dt.auto_recharge_soc; + if (of_find_property(node, "qcom,thermal-mitigation-epp", &byte_len)) { + chg->thermal_mitigation_epp = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); - chip->dt.auto_recharge_vbat_mv = -EINVAL; - rc = of_property_read_u32(node, "qcom,auto-recharge-vbat-mv", - &chip->dt.auto_recharge_vbat_mv); - if (!rc && (chip->dt.auto_recharge_vbat_mv < 0)) { - pr_err("qcom,auto-recharge-vbat-mv is incorrect\n"); - return -EINVAL; + if (chg->thermal_mitigation_epp == NULL) + return -ENOMEM; + + chg->dc_thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-mitigation-epp", + chg->thermal_mitigation_epp, + chg->dc_thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } } - chg->dcp_icl_ua = chip->dt.usb_icl_ua; + if (of_find_property(node, "qcom,thermal-mitigation-bpp-qc3", &byte_len)) { + chg->thermal_mitigation_bpp_qc3 = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); - chg->suspend_input_on_debug_batt = of_property_read_bool(node, - "qcom,suspend-input-on-debug-batt"); + if (chg->thermal_mitigation_bpp_qc3 == NULL) + return -ENOMEM; - chg->fake_chg_status_on_debug_batt = of_property_read_bool(node, - "qcom,fake-chg-status-on-debug-batt"); + chg->dc_thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-mitigation-bpp-qc3", + chg->thermal_mitigation_bpp_qc3, + chg->dc_thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } + } - rc = of_property_read_u32(node, "qcom,otg-deglitch-time-ms", - &chg->otg_delay_ms); - if (rc < 0) - chg->otg_delay_ms = OTG_DEFAULT_DEGLITCH_TIME_MS; + if (of_find_property(node, "qcom,thermal-mitigation-bpp-qc2", &byte_len)) { + chg->thermal_mitigation_bpp_qc2 = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); - chg->fcc_stepper_enable = of_property_read_bool(node, - "qcom,fcc-stepping-enable"); + if (chg->thermal_mitigation_bpp_qc2 == NULL) + return -ENOMEM; - chg->uusb_moisture_protection_enabled = - chg->uusb_moisture_protection_enabled && - of_property_read_bool(node, - "qcom,uusb-moisture-protection-enable"); + chg->dc_thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-mitigation-bpp-qc2", + chg->thermal_mitigation_bpp_qc2, + chg->dc_thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } + } - chg->hw_die_temp_mitigation = of_property_read_bool(node, - "qcom,hw-die-temp-mitigation"); + if (of_find_property(node, "qcom,thermal-mitigation-bpp", &byte_len)) { + chg->thermal_mitigation_bpp = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); - chg->hw_connector_mitigation = of_property_read_bool(node, - "qcom,hw-connector-mitigation"); + if (chg->thermal_mitigation_bpp == NULL) + return -ENOMEM; - chg->hw_skin_temp_mitigation = of_property_read_bool(node, - "qcom,hw-skin-temp-mitigation"); + chg->dc_thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-mitigation-bpp", + chg->thermal_mitigation_bpp, + chg->dc_thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } + } +#endif - chg->en_skin_therm_mitigation = of_property_read_bool(node, - "qcom,en-skin-therm-mitigation"); + if (of_find_property(node, "qcom,thermal-mitigation-qc2", &byte_len)) { + chg->thermal_mitigation_qc2 = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); - chg->connector_pull_up = -EINVAL; - of_property_read_u32(node, "qcom,connector-internal-pull-kohm", - &chg->connector_pull_up); + if (chg->thermal_mitigation_qc2 == NULL) + return -ENOMEM; - chg->smb_pull_up = -EINVAL; - of_property_read_u32(node, "qcom,smb-internal-pull-kohm", - &chg->smb_pull_up); + chg->thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-mitigation-qc2", + chg->thermal_mitigation_qc2, + chg->thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } + } - chip->dt.adc_based_aicl = of_property_read_bool(node, - "qcom,adc-based-aicl"); + if (of_find_property(node, "qcom,thermal-mitigation-pd-base", &byte_len)) { + chg->thermal_mitigation_pd_base = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); + + if (chg->thermal_mitigation_pd_base == NULL) + return -ENOMEM; + + chg->thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-mitigation-pd-base", + chg->thermal_mitigation_pd_base, + chg->thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } + } + + if (of_find_property(node, "qcom,thermal-fcc-qc3-normal", &byte_len)) { + chg->thermal_fcc_qc3_normal = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); + + if (chg->thermal_fcc_qc3_normal == NULL) + return -ENOMEM; + + chg->thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-fcc-qc3-normal", + chg->thermal_fcc_qc3_normal, + chg->thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } + } + + if (of_find_property(node, "qcom,thermal-fcc-qc3-cp", &byte_len)) { + chg->thermal_fcc_qc3_cp = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); + + if (chg->thermal_fcc_qc3_cp == NULL) + return -ENOMEM; + + chg->thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-fcc-qc3-cp", + chg->thermal_fcc_qc3_cp, + chg->thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } + } + + if (of_find_property(node, "qcom,thermal-fcc-qc3-classb-cp", &byte_len)) { + chg->thermal_fcc_qc3_classb_cp = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); + + if (chg->thermal_fcc_qc3_classb_cp == NULL) + return -ENOMEM; + + chg->thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-fcc-qc3-classb-cp", + chg->thermal_fcc_qc3_classb_cp, + chg->thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } + } + + if (of_find_property(node, "qcom,thermal-fcc-pps-cp", &byte_len)) { + chg->thermal_fcc_pps_cp = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); + + if (chg->thermal_fcc_pps_cp == NULL) + return -ENOMEM; + + chg->thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-fcc-pps-cp", + chg->thermal_fcc_pps_cp, + chg->thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } + } + + if (of_find_property(node, "qcom,thermal-mitigation-icl", &byte_len)) { + chg->thermal_mitigation_icl = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); + + if (chg->thermal_mitigation_icl == NULL) + return -ENOMEM; + + chg->thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-mitigation-icl", + chg->thermal_mitigation_icl, + chg->thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } + } +#else + if (of_find_property(node, "qcom,thermal-mitigation", &byte_len)) { + chg->thermal_mitigation = devm_kzalloc(chg->dev, byte_len, + GFP_KERNEL); + + if (chg->thermal_mitigation == NULL) + return -ENOMEM; + + chg->thermal_levels = byte_len / sizeof(u32); + rc = of_property_read_u32_array(node, + "qcom,thermal-mitigation", + chg->thermal_mitigation, + chg->thermal_levels); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't read threm limits rc = %d\n", rc); + return rc; + } + } +#endif + + rc = of_property_read_u32(node, "qcom,charger-temp-max", + &chg->charger_temp_max); + if (rc < 0) + chg->charger_temp_max = -EINVAL; + + rc = of_property_read_u32(node, "qcom,smb-temp-max", + &chg->smb_temp_max); + if (rc < 0) + chg->smb_temp_max = -EINVAL; + + rc = of_property_read_u32(node, "qcom,float-option", + &chip->dt.float_option); + if (!rc && (chip->dt.float_option < 0 || chip->dt.float_option > 4)) { + pr_err("qcom,float-option is out of range [0, 4]\n"); + return -EINVAL; + } + + chip->dt.hvdcp_disable = of_property_read_bool(node, + "qcom,hvdcp-disable"); + chg->hvdcp_disable = chip->dt.hvdcp_disable; + + chip->dt.hvdcp_autonomous = of_property_read_bool(node, + "qcom,hvdcp-autonomous-enable"); + + rc = of_property_read_u32(node, "qcom,chg-inhibit-threshold-mv", + &chip->dt.chg_inhibit_thr_mv); + if (!rc && (chip->dt.chg_inhibit_thr_mv < 0 || + chip->dt.chg_inhibit_thr_mv > 300)) { + pr_err("qcom,chg-inhibit-threshold-mv is incorrect\n"); + return -EINVAL; + } + + chip->dt.auto_recharge_soc = -EINVAL; + rc = of_property_read_u32(node, "qcom,auto-recharge-soc", + &chip->dt.auto_recharge_soc); + if (!rc && (chip->dt.auto_recharge_soc < 0 || + chip->dt.auto_recharge_soc > 100)) { + pr_err("qcom,auto-recharge-soc is incorrect\n"); + return -EINVAL; + } + chg->auto_recharge_soc = chip->dt.auto_recharge_soc; + + chip->dt.auto_recharge_vbat_mv = -EINVAL; + rc = of_property_read_u32(node, "qcom,auto-recharge-vbat-mv", + &chip->dt.auto_recharge_vbat_mv); + if (!rc && (chip->dt.auto_recharge_vbat_mv < 0)) { + pr_err("qcom,auto-recharge-vbat-mv is incorrect\n"); + return -EINVAL; + } + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->dcp_icl_ua = MICRO_1P8A_FOR_DCP; +#else + chg->dcp_icl_ua = chip->dt.usb_icl_ua; +#endif + + chg->suspend_input_on_debug_batt = of_property_read_bool(node, + "qcom,suspend-input-on-debug-batt"); + + chg->fake_chg_status_on_debug_batt = of_property_read_bool(node, + "qcom,fake-chg-status-on-debug-batt"); + + rc = of_property_read_u32(node, "qcom,otg-deglitch-time-ms", + &chg->otg_delay_ms); + if (rc < 0) + chg->otg_delay_ms = OTG_DEFAULT_DEGLITCH_TIME_MS; + + chg->fcc_stepper_enable = of_property_read_bool(node, + "qcom,fcc-stepping-enable"); + + chg->uusb_moisture_protection_enabled = + chg->uusb_moisture_protection_enabled && + of_property_read_bool(node, + "qcom,uusb-moisture-protection-enable"); + + chg->hw_die_temp_mitigation = of_property_read_bool(node, + "qcom,hw-die-temp-mitigation"); + + chg->hw_connector_mitigation = of_property_read_bool(node, + "qcom,hw-connector-mitigation"); + + chg->hw_skin_temp_mitigation = of_property_read_bool(node, + "qcom,hw-skin-temp-mitigation"); + + chg->en_skin_therm_mitigation = of_property_read_bool(node, + "qcom,en-skin-therm-mitigation"); + + chg->connector_pull_up = -EINVAL; + of_property_read_u32(node, "qcom,connector-internal-pull-kohm", + &chg->connector_pull_up); + + chg->smb_pull_up = -EINVAL; + of_property_read_u32(node, "qcom,smb-internal-pull-kohm", + &chg->smb_pull_up); + + chip->dt.adc_based_aicl = of_property_read_bool(node, + "qcom,adc-based-aicl"); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->six_pin_step_charge_enable) { + rc = smb5_charge_step_charge_init(chg, node); + if (!rc) { + for (i = 0; i < MAX_STEP_ENTRIES; i++) + pr_err("six-pin-step-chg-cfg: %duV, %duA\n", + chg->six_pin_step_cfg[i].vfloat_step_uv, + chg->six_pin_step_cfg[i].fcc_step_ua); + } + } +#endif /* Extract ADC channels */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = smblib_get_iio_channel(chg, "usb_in_voltage", + &chg->iio.usbin_v_chan); + if (rc < 0) + return rc; +#endif + rc = smblib_get_iio_channel(chg, "mid_voltage", &chg->iio.mid_chan); if (rc < 0) return rc; @@ -637,6 +1169,16 @@ static int smb5_parse_dt(struct smb5 *chip) if (rc < 0) return rc; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = smblib_get_iio_channel(chg, "hw_version_gpio5", &chg->iio.hw_version_gpio5); + if (rc < 0) + return rc; + + rc = smblib_get_iio_channel(chg, "project_gpio6", &chg->iio.project_gpio6); + if (rc < 0) + return rc; +#endif + chip->dt.disable_suspend_on_collapse = of_property_read_bool(node, "qcom,disable-suspend-on-collapse"); @@ -808,6 +1350,98 @@ static int smb5_set_prop_comp_clamp_level(struct smb_charger *chg, return rc; } +#ifdef CONFIG_MACH_XIAOMI_NABU +int smblib_set_prop_tx_mac(struct smb_charger *chg, + const union power_supply_propval *val) +{ + int rc = 0; + chg->tx_bt_mac = val->int64val; + if (!chg->wls_psy) { + chg->wls_psy = power_supply_get_by_name("wireless"); + if (!chg->wls_psy) + return -ENODEV; + } + power_supply_changed(chg->wls_psy); + return rc; +} + +int smblib_set_prop_rx_cr(struct smb_charger *chg, + const union power_supply_propval *val) +{ + int rc = 0; + if (!chg->wls_psy) { + chg->wls_psy = power_supply_get_by_name("wireless"); + if (!chg->wls_psy) { + return -ENODEV; + } + } + if (!val->int64val) + return rc; + chg->oob_rpp_msg_cnt %= 9; + chg->oob_rpp_msg_cnt++; + chg->rpp = (val->int64val | chg->oob_rpp_msg_cnt << 48); + power_supply_changed(chg->wls_psy); + return rc; +} + +int smblib_set_prop_rx_cep(struct smb_charger *chg, + const union power_supply_propval *val) +{ + int rc = 0; + if (!chg->wls_psy) { + chg->wls_psy = power_supply_get_by_name("wireless"); + if (!chg->wls_psy) { + return -ENODEV; + } + } + if (!val->int64val) + return rc; + chg->oob_cep_msg_cnt %= 9; + chg->oob_cep_msg_cnt++; + chg->cep = (val->int64val | chg->oob_cep_msg_cnt << 48); + power_supply_changed(chg->wls_psy); + return rc; +} +#define BLE_CONNECT 1 +#define BLE_DISCONNECT 2 +#define BLE_CONNECTING 3 + +extern int idtp_op_ble_flag(int en); +extern int rx_op_ble_flag(int en); +int smblib_set_prop_bt_state(struct smb_charger *chg, + const union power_supply_propval *val) +{ + int bt_state = -2; + + bt_state = val->intval; + +#if defined(CONFIG_IDT_P9415) || defined(CONFIG_RX1619) + switch (bt_state) { + case BLE_CONNECT: + if (chg->idtp_psy) + idtp_op_ble_flag(1); + else + rx_op_ble_flag(1); + chg->tx_bt_mac = 0; + break; + case BLE_DISCONNECT: + if (chg->idtp_psy) + idtp_op_ble_flag(0); + else + rx_op_ble_flag(0); + chg->tx_bt_mac = 0; + break; + case BLE_CONNECTING: + chg->tx_bt_mac = 0; + break; + default: + break; + } +#endif + return 0; +} +#endif + /************************ * USB PSY REGISTRATION * ************************/ @@ -823,6 +1457,13 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION, POWER_SUPPLY_PROP_LOW_POWER, POWER_SUPPLY_PROP_PD_ACTIVE, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_PROP_PD_AUTHENTICATION, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_FASTCHARGE_MODE, + POWER_SUPPLY_PROP_PD_REMOVE_COMPENSATION, +#endif +#endif POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, POWER_SUPPLY_PROP_INPUT_CURRENT_NOW, POWER_SUPPLY_PROP_BOOST_CURRENT, @@ -830,6 +1471,11 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_CTM_CURRENT_MAX, POWER_SUPPLY_PROP_HW_CURRENT_MAX, POWER_SUPPLY_PROP_REAL_TYPE, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_PROP_HVDCP3_TYPE, + POWER_SUPPLY_PROP_QUICK_CHARGE_TYPE, + POWER_SUPPLY_PROP_PR_SWAP, +#endif POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, POWER_SUPPLY_PROP_CONNECTOR_TYPE, @@ -839,6 +1485,9 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT, POWER_SUPPLY_PROP_SMB_EN_MODE, POWER_SUPPLY_PROP_SMB_EN_REASON, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_PROP_TYPE_RECHECK, +#endif POWER_SUPPLY_PROP_ADAPTER_CC_MODE, POWER_SUPPLY_PROP_SCOPE, POWER_SUPPLY_PROP_MOISTURE_DETECTED, @@ -849,6 +1498,9 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_SKIN_HEALTH, POWER_SUPPLY_PROP_APSD_RERUN, POWER_SUPPLY_PROP_APSD_TIMEOUT, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_APDO_MAX, +#endif }; static int smb5_usb_get_prop(struct power_supply *psy, @@ -866,6 +1518,13 @@ static int smb5_usb_get_prop(struct power_supply *psy, rc = smblib_get_prop_usb_present(chg, val); break; case POWER_SUPPLY_PROP_ONLINE: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (chg->report_usb_absent) { + val->intval = 0; + break; + } +#endif + rc = smblib_get_prop_usb_online(chg, val); if (!val->intval) break; @@ -913,6 +1572,55 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_REAL_TYPE: val->intval = chg->real_charger_type; break; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_HVDCP3_TYPE: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3 + && chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3P5) { + val->intval = HVDCP3_NONE; /* 0: none hvdcp3 insert */ + } else { + if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) { + if (chg->qc3p5_power_limit_w == 18) + val->intval = HVDCP3P5_CLASSA_18W; + else if (chg->qc3p5_power_limit_w == 27) + val->intval = HVDCP3P5_CLASSB_27W; + else + val->intval = HVDCP3_NONE; + } else { // QC3 + if (chg->qc_class_ab) { + if (chg->is_qc_class_a) + val->intval = HVDCP3_CLASSA_18W; /* 18W hvdcp3 insert */ + else if (chg->is_qc_class_b) + val->intval = HVDCP3_CLASSB_27W; /* 27W hvdcp3 insert */ + else + val->intval = HVDCP3_NONE; + } else {/* for F10 */ + if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) + val->intval = HVDCP3_CLASSA_18W; /* 18W hvdcp3 insert */ + else + val->intval = HVDCP3_NONE; + } + } + } +#else + if (chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3) + val->intval = HVDCP3_NONE; /* 0: none hvdcp3 insert */ + else { + if (chg->is_qc_class_a) + val->intval = HVDCP3_CLASSA_18W; /* 18W hvdcp3 insert */ + else if (chg->is_qc_class_b) + val->intval = HVDCP3_CLASSB_27W; /* 27W hvdcp3 insert */ + else + val->intval = HVDCP3_NONE; + } +#endif + break; +#endif +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_QUICK_CHARGE_TYPE: + val->intval = smblib_get_quick_charge_type(chg); + break; +#endif case POWER_SUPPLY_PROP_TYPEC_MODE: if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) val->intval = POWER_SUPPLY_TYPEC_NONE; @@ -943,6 +1651,19 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_PD_ACTIVE: val->intval = chg->pd_active; break; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_PD_AUTHENTICATION: + val->intval = chg->pd_verifed; + break; +#endif +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_FASTCHARGE_MODE: + val->intval = smblib_get_fastcharge_mode(chg); + break; + case POWER_SUPPLY_PROP_PD_REMOVE_COMPENSATION: + val->intval = chg->remove_comp; + break; +#endif case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED: rc = smblib_get_prop_input_current_settled(chg, val); break; @@ -1006,6 +1727,11 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_SMB_EN_REASON: val->intval = chg->cp_reason; break; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_TYPE_RECHECK: + rc = smblib_get_prop_type_recheck(chg, val); + break; +#endif case POWER_SUPPLY_PROP_MOISTURE_DETECTED: val->intval = chg->moisture_present; break; @@ -1038,6 +1764,11 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_APSD_TIMEOUT: val->intval = chg->apsd_ext_timeout; break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_APDO_MAX: + val->intval = chg->apdo_max; + break; +#endif default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; @@ -1074,6 +1805,31 @@ static int smb5_usb_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_PD_ACTIVE: rc = smblib_set_prop_pd_active(chg, val); break; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_PD_AUTHENTICATION: + chg->pd_verifed = val->intval; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /*if set pd authentication auto set fastcharge mode*/ + /*do not break here*/ +#else + rc = vote(chg->usb_icl_votable, PD_VERIFED_VOTER, + !chg->pd_verifed, PD_UNVERIFED_CURRENT); + break; +#endif +#endif +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_FASTCHARGE_MODE: + power_supply_changed(chg->usb_psy); + if (chg->support_ffc) { + rc = smblib_set_fastcharge_mode(chg, val->intval); + } + schedule_delayed_work(&chg->report_soc_decimal_work, + msecs_to_jiffies(REPORT_SOC_DECIMAL_MS)); + break; + case POWER_SUPPLY_PROP_PD_REMOVE_COMPENSATION: + chg->remove_comp = val->intval; + break; +#endif case POWER_SUPPLY_PROP_PD_IN_HARD_RESET: rc = smblib_set_prop_pd_in_hard_reset(chg, val); break; @@ -1121,6 +1877,10 @@ static int smb5_usb_set_prop(struct power_supply *psy, else rc = -EINVAL; break; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_TYPE_RECHECK: + rc = smblib_set_prop_type_recheck(chg, val); +#endif case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT: smblib_set_prop_usb_voltage_max_limit(chg, val); break; @@ -1132,6 +1892,11 @@ static int smb5_usb_set_prop(struct power_supply *psy, chg->apsd_ext_timeout = false; smblib_rerun_apsd(chg); break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_APDO_MAX: + chg->apdo_max = val->intval; + break; +#endif default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; @@ -1150,7 +1915,17 @@ static int smb5_usb_prop_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_THERM_ICL_LIMIT: case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT: case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_PD_AUTHENTICATION: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_FASTCHARGE_MODE: + case POWER_SUPPLY_PROP_PD_REMOVE_COMPENSATION: +#endif +#endif case POWER_SUPPLY_PROP_APSD_RERUN: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_APDO_MAX: +#endif return 1; default: break; @@ -1174,10 +1949,17 @@ static int smb5_init_usb_psy(struct smb5 *chip) struct power_supply_config usb_cfg = {}; struct smb_charger *chg = &chip->chg; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->usb_psy_desc = usb_psy_desc; +#endif usb_cfg.drv_data = chip; usb_cfg.of_node = chg->dev->of_node; chg->usb_psy = devm_power_supply_register(chg->dev, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + &chg->usb_psy_desc, +#else &usb_psy_desc, +#endif &usb_cfg); if (IS_ERR(chg->usb_psy)) { pr_err("Couldn't register USB power supply\n"); @@ -1210,6 +1992,13 @@ static int smb5_usb_port_get_prop(struct power_supply *psy, val->intval = POWER_SUPPLY_TYPE_USB; break; case POWER_SUPPLY_PROP_ONLINE: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (chg->report_usb_absent) { + val->intval = 0; + break; + } +#endif + rc = smblib_get_prop_usb_online(chg, val); if (!val->intval) break; @@ -1396,6 +2185,9 @@ static int smb5_usb_main_set_prop(struct power_supply *psy, union power_supply_propval pval = {0, }; enum power_supply_type real_chg_type = chg->real_charger_type; int rc = 0, offset_ua = 0; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int parallel_output_mode = 0; +#endif switch (psp) { case POWER_SUPPLY_PROP_VOLTAGE_MAX: @@ -1407,8 +2199,33 @@ static int smb5_usb_main_set_prop(struct power_supply *psy, if (rc < 0) offset_ua = 0; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->six_pin_step_charge_enable) { + rc = smblib_get_prop_from_bms(chg, POWER_SUPPLY_PROP_TEMP, &pval); + /* if temp out of soft jeita normal zone, do not add fast charge current offset */ + if (pval.intval >= CP_WARM_THRESHOLD - SOFT_JEITA_HYSTERESIS || pval.intval <= CP_COOL_THRESHOLD + SOFT_JEITA_HYSTERESIS + || chg->index_vfloat == MAX_STEP_ENTRIES - 1) + + rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval); + else + rc = smblib_set_charge_param(chg, &chg->param.fcc,val->intval + offset_ua); + } else { + if (chg->cp_psy) { + rc = power_supply_get_property(chg->cp_psy, + POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, &pval); + if (rc >= 0) + parallel_output_mode = pval.intval; + } + /* only parallel output mode is output to vbat need add offset */ + if (parallel_output_mode == POWER_SUPPLY_PL_OUTPUT_VBAT) + rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval + offset_ua); + else + rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval); + } +#else rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval + offset_ua); +#endif break; case POWER_SUPPLY_PROP_CURRENT_MAX: rc = smblib_set_icl_current(chg, val->intval); @@ -1505,130 +2322,944 @@ static int smb5_usb_main_prop_is_writeable(struct power_supply *psy, return rc; } -static const struct power_supply_desc usb_main_psy_desc = { - .name = "main", - .type = POWER_SUPPLY_TYPE_MAIN, - .properties = smb5_usb_main_props, - .num_properties = ARRAY_SIZE(smb5_usb_main_props), - .get_property = smb5_usb_main_get_prop, - .set_property = smb5_usb_main_set_prop, - .property_is_writeable = smb5_usb_main_prop_is_writeable, -}; - -static int smb5_init_usb_main_psy(struct smb5 *chip) +static const struct power_supply_desc usb_main_psy_desc = { + .name = "main", + .type = POWER_SUPPLY_TYPE_MAIN, + .properties = smb5_usb_main_props, + .num_properties = ARRAY_SIZE(smb5_usb_main_props), + .get_property = smb5_usb_main_get_prop, + .set_property = smb5_usb_main_set_prop, + .property_is_writeable = smb5_usb_main_prop_is_writeable, +}; + +static int smb5_init_usb_main_psy(struct smb5 *chip) +{ + struct power_supply_config usb_main_cfg = {}; + struct smb_charger *chg = &chip->chg; + + usb_main_cfg.drv_data = chip; + usb_main_cfg.of_node = chg->dev->of_node; + chg->usb_main_psy = devm_power_supply_register(chg->dev, + &usb_main_psy_desc, + &usb_main_cfg); + if (IS_ERR(chg->usb_main_psy)) { + pr_err("Couldn't register USB main power supply\n"); + return PTR_ERR(chg->usb_main_psy); + } + + return 0; +} + +/************************* + * DC PSY REGISTRATION * + *************************/ + +static enum power_supply_property smb5_dc_props[] = { + POWER_SUPPLY_PROP_INPUT_SUSPEND, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_MAX, + POWER_SUPPLY_PROP_VOLTAGE_MAX, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, + POWER_SUPPLY_PROP_REAL_TYPE, + POWER_SUPPLY_PROP_DC_RESET, +}; + +static int smb5_dc_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct smb5 *chip = power_supply_get_drvdata(psy); + struct smb_charger *chg = &chip->chg; + int rc = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_INPUT_SUSPEND: + val->intval = get_effective_result(chg->dc_suspend_votable); + break; + case POWER_SUPPLY_PROP_PRESENT: + rc = smblib_get_prop_dc_present(chg, val); + break; + case POWER_SUPPLY_PROP_ONLINE: + rc = smblib_get_prop_dc_online(chg, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + rc = smblib_get_prop_dc_voltage_now(chg, val); + break; + case POWER_SUPPLY_PROP_CURRENT_MAX: + rc = smblib_get_prop_dc_current_max(chg, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_MAX: + rc = smblib_get_prop_dc_voltage_max(chg, val); + break; +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + smb5_get_prop_input_voltage_regulation(chg, val); + break; + case POWER_SUPPLY_PROP_REAL_TYPE: + val->intval = POWER_SUPPLY_TYPE_WIPOWER; + break; + case POWER_SUPPLY_PROP_DC_RESET: + val->intval = 0; + break; +#endif +#ifndef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + rc = smblib_get_prop_voltage_wls_output(chg, val); + break; +#endif + default: + return -EINVAL; + } + if (rc < 0) { + pr_debug("Couldn't get prop %d rc = %d\n", psp, rc); + return -ENODATA; + } + return 0; +} + +static int smb5_dc_set_prop(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + struct smb5 *chip = power_supply_get_drvdata(psy); + struct smb_charger *chg = &chip->chg; + int rc = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_INPUT_SUSPEND: + rc = vote(chg->dc_suspend_votable, WBC_VOTER, + (bool)val->intval, 0); + break; + case POWER_SUPPLY_PROP_CURRENT_MAX: + rc = smblib_set_prop_dc_current_max(chg, val); + break; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + rc = smblib_set_prop_voltage_wls_output(chg, val); + break; + case POWER_SUPPLY_PROP_DC_RESET: + rc = smblib_set_prop_dc_reset(chg); + break; + default: + return -EINVAL; + } + + return rc; +} + +static int smb5_dc_prop_is_writeable(struct power_supply *psy, + enum power_supply_property psp) +{ + switch (psp) { + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_INPUT_SUSPEND: + case POWER_SUPPLY_PROP_CURRENT_MAX: +#endif + return 1; + default: + break; + } + + return 0; +} + +static const struct power_supply_desc dc_psy_desc = { + .name = "dc", + .type = POWER_SUPPLY_TYPE_WIRELESS, + .properties = smb5_dc_props, + .num_properties = ARRAY_SIZE(smb5_dc_props), + .get_property = smb5_dc_get_prop, + .set_property = smb5_dc_set_prop, + .property_is_writeable = smb5_dc_prop_is_writeable, +}; + +static int smb5_init_dc_psy(struct smb5 *chip) +{ + struct power_supply_config dc_cfg = {}; + struct smb_charger *chg = &chip->chg; + + dc_cfg.drv_data = chip; + dc_cfg.of_node = chg->dev->of_node; + chg->dc_psy = devm_power_supply_register(chg->dev, + &dc_psy_desc, + &dc_cfg); + if (IS_ERR(chg->dc_psy)) { + pr_err("Couldn't register USB power supply\n"); + return PTR_ERR(chg->dc_psy); + } + + return 0; +} + +#ifdef CONFIG_MACH_XIAOMI_NABU +static int smb5_get_prop_input_voltage_regulation(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc; + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) { + chg->wls_chip_psy = chg->idtp_psy; + } else { + chg->wip_psy = power_supply_get_by_name("rx1619"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + //msleep(200); + if (chg->wls_chip_psy) + rc = power_supply_get_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, val); + + val->intval = 1000*val->intval;//IDT in mV + + return rc; +} + +static int smb5_get_prop_input_voltage_vrect(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc; + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) { + chg->wls_chip_psy = chg->idtp_psy; + } else { + chg->wip_psy = power_supply_get_by_name("rx1619"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + //msleep(200); + + if (chg->wls_chip_psy) + rc = power_supply_get_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_VRECT, val); + + val->intval = 1000*val->intval;//IDT in mV + + return rc; +} + +static int smb5_get_prop_rx_iout(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc; + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) { + chg->wls_chip_psy = chg->idtp_psy; + } else { + chg->wip_psy = power_supply_get_by_name("rx1619"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + //msleep(100); + if (chg->wls_chip_psy) + rc = power_supply_get_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_RX_IOUT, val); + + val->intval = 1000*val->intval;//IDT in mV + + return rc; +} + +static int smb5_get_prop_wireless_signal(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc; + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) { + chg->wls_chip_psy = chg->idtp_psy; + } else { + chg->wip_psy = power_supply_get_by_name("rx1619"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + if (chg->wls_chip_psy) + rc = power_supply_get_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_SIGNAL_STRENGTH, val); + + return rc; +} + +static int smb5_set_prop_input_voltage_regulation(struct smb_charger *chg, + const union power_supply_propval *val) +{ + int rc; + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) { + chg->wls_chip_psy = chg->idtp_psy; + } else { + chg->wip_psy = power_supply_get_by_name("rx1619"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + if (chg->wls_chip_psy) + rc = power_supply_set_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, val); + + return rc; +} + +static int smb5_get_prop_wirless_type(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc = 0; + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) + chg->wls_chip_psy = chg->idtp_psy; + else { + chg->wip_psy = power_supply_get_by_name("rx1619"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + if (chg->wls_chip_psy) + rc = power_supply_get_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_TX_ADAPTER, val); + + return rc; +} + +static int smb5_get_prop_reverse_pen_soc(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc = 0; + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) + chg->wls_chip_psy = chg->idtp_psy; + else { + chg->wip_psy = power_supply_get_by_name("rx1619"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + if (chg->wls_chip_psy) + rc = power_supply_get_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_REVERSE_PEN_SOC, val); + + return rc; +} + +/*set mode of DIV 2*/ +static int smb5_set_prop_div2_mode(struct smb_charger *chg, + const union power_supply_propval *val) +{ + int rc; + + dev_info(chg->dev, "%s: set mode is = %d\n", + __func__, val->intval); + + chg->ln_psy = power_supply_get_by_name("lionsemi"); + //chg->halo_psy = power_supply_get_by_name("halo"); + if (chg->ln_psy) + chg->cp_chip_psy = chg->ln_psy; + /*else if (chg->halo_psy) + chg->cp_chip_psy = chg->halo_psy;*/ + else + return -EINVAL; + + if (chg->cp_chip_psy) + rc = power_supply_set_property(chg->cp_chip_psy, + POWER_SUPPLY_PROP_DIV_2_MODE, val); + + return rc; +} + +static int smb5_get_prop_div2_mode(struct smb_charger *chg, + union power_supply_propval *val) +{ + dev_info(chg->dev, "%s: get div2 mode\n", __func__); + + chg->ln_psy = power_supply_get_by_name("lionsemi"); + //chg->halo_psy = power_supply_get_by_name("halo"); + + if (chg->ln_psy) + chg->cp_chip_psy = chg->ln_psy; + /*else if (chg->halo_psy) + chg->cp_chip_psy = chg->halo_psy;*/ + else + return -EINVAL; + + if (chg->cp_chip_psy) { + power_supply_get_property(chg->cp_chip_psy, + POWER_SUPPLY_PROP_DIV_2_MODE, val); + dev_info(chg->dev, "%s: get mode is = %d\n", + __func__, val->intval); + } + + return 1; +} +static int smb5_set_prop_reverse_chg_mode(struct smb_charger *chg, + const union power_supply_propval *val) +{ + int rc; + + dev_info(chg->dev, "%s: set mode is = %d\n", + __func__, val->intval); + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) { + chg->wls_chip_psy = chg->idtp_psy; + } else { + chg->wip_psy = power_supply_get_by_name("rx1619"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + if (chg->wls_chip_psy) + rc = power_supply_set_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_REVERSE_CHG_MODE, val); + + return rc; +} + +static int smb5_set_prop_otg_mode(struct smb_charger *chg, + const union power_supply_propval *val) +{ + int rc; + + dev_info(chg->dev, "%s: set mode is = %d\n", + __func__, val->intval); + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) { + chg->wls_chip_psy = chg->idtp_psy; + } else { + chg->wip_psy = power_supply_get_by_name("rx1619"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + if (chg->wls_chip_psy) + rc = power_supply_set_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_OTG_STATE, val); + + return rc; +} + +static int smb5_get_prop_reverse_chg_mode(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc; + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) { + chg->wls_chip_psy = chg->idtp_psy; + } else { + chg->wip_psy = power_supply_get_by_name("rx1619"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + if (chg->wls_chip_psy) { + rc = power_supply_get_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_REVERSE_CHG_MODE, val); + dev_info(chg->dev, "%s: get mode is = %d\n", + __func__, val->intval); + } + + return rc; +} + +static int smb5_get_prop_wirless_chip_ok(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc; + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) { + chg->wls_chip_psy = chg->idtp_psy; + } else { + chg->wip_psy = power_supply_get_by_name("rx1619"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + if (chg->wls_chip_psy) { + rc = power_supply_get_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_CHIP_OK, val); + dev_info(chg->dev, "%s: get chip status is = %d\n", + __func__, val->intval); + } + + return rc; +} + +int smblib_enable_aicl(struct smb_charger *chg, int enable) +{ + int rc = 0; + u8 mask = 0; + u8 val = 0; + + mask = USBIN_AICL_EN_BIT; + val = enable?USBIN_AICL_EN_BIT:0; + + rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG, + mask, val); + if (rc < 0) { + dev_err(chg->dev, "Couldn't config AICL enable rc=%d\n", rc); + return rc; + } + return 0; + +} + +/************************* + * WIRELESS PSY REGISTRATION * + *************************/ + +static enum power_supply_property smb5_wireless_props[] = { + POWER_SUPPLY_PROP_WIRELESS_VERSION, + POWER_SUPPLY_PROP_SIGNAL_STRENGTH, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_VRECT, + POWER_SUPPLY_PROP_RX_IOUT, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, + POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN, + POWER_SUPPLY_PROP_SW_DISABLE_DC_EN, + POWER_SUPPLY_PROP_TX_ADAPTER, + POWER_SUPPLY_PROP_TX_MAC, + POWER_SUPPLY_PROP_PEN_MAC, + POWER_SUPPLY_PROP_REVERSE_PEN_SOC, + POWER_SUPPLY_PROP_BT_STATE, + POWER_SUPPLY_PROP_RX_CR, + POWER_SUPPLY_PROP_RX_CEP, + POWER_SUPPLY_PROP_DC_RESET, + POWER_SUPPLY_PROP_DIV_2_MODE, + POWER_SUPPLY_PROP_REVERSE_CHG_MODE, + POWER_SUPPLY_PROP_REVERSE_PEN_CHG_STATE, + POWER_SUPPLY_PROP_REVERSE_GPIO_STATE, + POWER_SUPPLY_PROP_AICL_ENABLE, + POWER_SUPPLY_PROP_OTG_STATE, + POWER_SUPPLY_PROP_WIRELESS_FW_VERSION, + POWER_SUPPLY_PROP_CHIP_OK, +}; + +static int smb5_wireless_set_prop(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + struct smb5 *chip = power_supply_get_drvdata(psy); + struct smb_charger *chg = &chip->chg; + int rc = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_WIRELESS_VERSION: + dev_info(chg->dev, "set version=%d\n", val->intval); + break; + case POWER_SUPPLY_PROP_WIRELESS_WAKELOCK: + rc = smblib_set_prop_wireless_wakelock(chg, val); + break; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + smb5_set_prop_input_voltage_regulation(chg, val); + break; + case POWER_SUPPLY_PROP_WIRELESS_CP_EN: + smblib_set_wirless_cp_enable(chg, val); + break; + case POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN: + smblib_set_wirless_power_good_enable(chg, val); + break; + case POWER_SUPPLY_PROP_SW_DISABLE_DC_EN: + smblib_set_sw_disable_dc_en(chg, val); + break; + case POWER_SUPPLY_PROP_DC_RESET: + rc = smblib_set_prop_dc_reset(chg); + break; + case POWER_SUPPLY_PROP_DIV_2_MODE: + rc = smb5_set_prop_div2_mode(chg, val); + break; + case POWER_SUPPLY_PROP_TX_MAC: + smblib_set_prop_tx_mac(chg, val); + break; + case POWER_SUPPLY_PROP_PEN_MAC: + smblib_set_prop_pen_mac(chg, val); + break; + case POWER_SUPPLY_PROP_RX_CR: + smblib_set_prop_rx_cr(chg, val); + break; + case POWER_SUPPLY_PROP_RX_CEP: + smblib_set_prop_rx_cep(chg, val); + break; + case POWER_SUPPLY_PROP_BT_STATE: + smblib_set_prop_bt_state(chg, val); + break; + case POWER_SUPPLY_PROP_REVERSE_CHG_MODE: + rc = smb5_set_prop_reverse_chg_mode(chg, val); + break; + case POWER_SUPPLY_PROP_REVERSE_PEN_CHG_STATE: + chg->reverse_chg_state = val->intval; + pen_charge_state_notifier_call_chain(chg->reverse_chg_state == 4, NULL); + break; + case POWER_SUPPLY_PROP_AICL_ENABLE: + rc = smblib_enable_aicl(chg, val->intval); + break; + case POWER_SUPPLY_PROP_REVERSE_GPIO_STATE: + chg->reverse_gpio_state = val->intval; + break; + case POWER_SUPPLY_PROP_OTG_STATE: + rc = smb5_set_prop_otg_mode(chg, val); + break; + default: + return -EINVAL; + } + + return rc; +} + +static int smb5_wireless_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct smb5 *chip = power_supply_get_drvdata(psy); + struct smb_charger *chg = &chip->chg; + int rc = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_WIRELESS_VERSION: + rc = smblib_get_prop_wireless_version(chg, val); + break; + case POWER_SUPPLY_PROP_WIRELESS_FW_VERSION: + rc = smblib_get_prop_wireless_fw_version(chg, val); + break; + case POWER_SUPPLY_PROP_SIGNAL_STRENGTH: + smb5_get_prop_wireless_signal(chg, val); + break; + case POWER_SUPPLY_PROP_WIRELESS_WAKELOCK: + val->intval = 1; + break; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + smb5_get_prop_input_voltage_regulation(chg, val); + break; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_VRECT: + smb5_get_prop_input_voltage_vrect(chg, val); + break; + case POWER_SUPPLY_PROP_RX_IOUT: + smb5_get_prop_rx_iout(chg, val); + break; + case POWER_SUPPLY_PROP_WIRELESS_CP_EN: + if (chg->wireless_bq) + val->intval = chg->en_bq_flag; + else + val->intval = chg->flag_dc_present; + break; + case POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN: + val->intval = chg->power_good_en; + break; + case POWER_SUPPLY_PROP_TX_ADAPTER: + smb5_get_prop_wirless_type(chg, val); + break; + case POWER_SUPPLY_PROP_REVERSE_PEN_SOC: + smb5_get_prop_reverse_pen_soc(chg, val); + break; + case POWER_SUPPLY_PROP_DC_RESET: + val->intval = 0; + break; + case POWER_SUPPLY_PROP_DIV_2_MODE: + smb5_get_prop_div2_mode(chg, val); + break; + case POWER_SUPPLY_PROP_TX_MAC: + val->int64val = chg->tx_bt_mac; + break; + case POWER_SUPPLY_PROP_PEN_MAC: + val->int64val = chg->pen_bt_mac; + break; + case POWER_SUPPLY_PROP_RX_CR: + val->int64val = chg->rpp; + break; + case POWER_SUPPLY_PROP_RX_CEP: + val->int64val = chg->cep; + break; + case POWER_SUPPLY_PROP_BT_STATE: + val->intval = 0; + break; + case POWER_SUPPLY_PROP_SW_DISABLE_DC_EN: + val->intval = 0; + break; + case POWER_SUPPLY_PROP_REVERSE_CHG_MODE: + smb5_get_prop_reverse_chg_mode(chg, val); + break; + case POWER_SUPPLY_PROP_REVERSE_PEN_CHG_STATE: + val->intval = chg->reverse_chg_state; + break; + case POWER_SUPPLY_PROP_REVERSE_GPIO_STATE: + val->intval = chg->reverse_gpio_state; + break; + case POWER_SUPPLY_PROP_AICL_ENABLE: + val->intval = 0; + break; + case POWER_SUPPLY_PROP_CHIP_OK: + smb5_get_prop_wirless_chip_ok(chg, val); + break; + case POWER_SUPPLY_PROP_OTG_STATE: + val->intval = 0; + break; + + default: + return -EINVAL; + } + if (rc < 0) { + pr_debug("Couldn't get prop %d rc = %d\n", psp, rc); + return -ENODATA; + } + return 0; +} + +static int smb5_wireless_prop_is_writeable(struct power_supply *psy, + enum power_supply_property psp) +{ + switch (psp) { + case POWER_SUPPLY_PROP_WIRELESS_VERSION: + case POWER_SUPPLY_PROP_WIRELESS_WAKELOCK: + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + case POWER_SUPPLY_PROP_WIRELESS_CP_EN: + case POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN: + case POWER_SUPPLY_PROP_SW_DISABLE_DC_EN: + case POWER_SUPPLY_PROP_RX_CR: + case POWER_SUPPLY_PROP_RX_CEP: + case POWER_SUPPLY_PROP_TX_MAC: + case POWER_SUPPLY_PROP_PEN_MAC: + case POWER_SUPPLY_PROP_BT_STATE: + case POWER_SUPPLY_PROP_DIV_2_MODE: + case POWER_SUPPLY_PROP_REVERSE_CHG_MODE: + case POWER_SUPPLY_PROP_REVERSE_PEN_CHG_STATE: + case POWER_SUPPLY_PROP_CURRENT_MAX: + return 1; + default: + break; + } + + return 0; +} + +static const struct power_supply_desc wireless_psy_desc = { + .name = "wireless", + .type = POWER_SUPPLY_TYPE_WIRELESS, + .properties = smb5_wireless_props, + .num_properties = ARRAY_SIZE(smb5_wireless_props), + .get_property = smb5_wireless_get_prop, + .set_property = smb5_wireless_set_prop, + .property_is_writeable = smb5_wireless_prop_is_writeable, +}; + +static int smb5_init_wireless_psy(struct smb5 *chip) +{ + struct power_supply_config wireless_cfg = {}; + struct smb_charger *chg = &chip->chg; + + wireless_cfg.drv_data = chip; + wireless_cfg.of_node = chg->dev->of_node; + chg->wireless_psy = power_supply_register(chg->dev, + &wireless_psy_desc, + &wireless_cfg); + if (IS_ERR(chg->wireless_psy)) { + pr_err("Couldn't register wireless power supply\n"); + return PTR_ERR(chg->wireless_psy); + } + + return 0; +} +#endif + +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) +static int smb5_get_prop_wireless_signal(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc; + +/* + if (!chg->idtp_psy) { + chg->idtp_psy = power_supply_get_by_name("idt"); + if (!chg->idtp_psy) + return -EINVAL; + } +*/ + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) + chg->wls_chip_psy = chg->idtp_psy; + else { + chg->wip_psy = power_supply_get_by_name("rx1618"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + if (chg->wls_chip_psy) + rc = power_supply_get_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_SIGNAL_STRENGTH, val); + + return rc; +} + +static int smb5_set_prop_input_voltage_regulation(struct smb_charger *chg, + const union power_supply_propval *val) { - struct power_supply_config usb_main_cfg = {}; - struct smb_charger *chg = &chip->chg; + int rc; - usb_main_cfg.drv_data = chip; - usb_main_cfg.of_node = chg->dev->of_node; - chg->usb_main_psy = devm_power_supply_register(chg->dev, - &usb_main_psy_desc, - &usb_main_cfg); - if (IS_ERR(chg->usb_main_psy)) { - pr_err("Couldn't register USB main power supply\n"); - return PTR_ERR(chg->usb_main_psy); +/* + if (!chg->idtp_psy) { + chg->idtp_psy = power_supply_get_by_name("idt"); + if (!chg->idtp_psy) + return -EINVAL; + } +*/ + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) + chg->wls_chip_psy = chg->idtp_psy; + else { + chg->wip_psy = power_supply_get_by_name("rx1618"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; } - return 0; + if (chg->wls_chip_psy) + rc = power_supply_set_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, val); + + return rc; +} + +static int smb5_get_prop_wirless_type(struct smb_charger *chg, + union power_supply_propval *val) +{ + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) + power_supply_get_property(chg->idtp_psy, + POWER_SUPPLY_PROP_TX_ADAPTER, val); + + return 1; } /************************* - * DC PSY REGISTRATION * + * WIRELESS PSY REGISTRATION * *************************/ -static enum power_supply_property smb5_dc_props[] = { - POWER_SUPPLY_PROP_INPUT_SUSPEND, - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_ONLINE, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CURRENT_MAX, - POWER_SUPPLY_PROP_VOLTAGE_MAX, +static enum power_supply_property smb5_wireless_props[] = { + POWER_SUPPLY_PROP_WIRELESS_VERSION, + POWER_SUPPLY_PROP_SIGNAL_STRENGTH, + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, - POWER_SUPPLY_PROP_REAL_TYPE, - POWER_SUPPLY_PROP_DC_RESET, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, + POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN, + POWER_SUPPLY_PROP_TX_ADAPTER, }; -static int smb5_dc_get_prop(struct power_supply *psy, +static int smb5_wireless_set_prop(struct power_supply *psy, enum power_supply_property psp, - union power_supply_propval *val) + const union power_supply_propval *val) { struct smb5 *chip = power_supply_get_drvdata(psy); struct smb_charger *chg = &chip->chg; int rc = 0; switch (psp) { - case POWER_SUPPLY_PROP_INPUT_SUSPEND: - val->intval = get_effective_result(chg->dc_suspend_votable); - break; - case POWER_SUPPLY_PROP_PRESENT: - rc = smblib_get_prop_dc_present(chg, val); - break; - case POWER_SUPPLY_PROP_ONLINE: - rc = smblib_get_prop_dc_online(chg, val); - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - rc = smblib_get_prop_dc_voltage_now(chg, val); - break; - case POWER_SUPPLY_PROP_CURRENT_MAX: - rc = smblib_get_prop_dc_current_max(chg, val); + case POWER_SUPPLY_PROP_WIRELESS_VERSION: + dev_info(chg->dev, "set version=%d\n", val->intval); break; - case POWER_SUPPLY_PROP_VOLTAGE_MAX: - rc = smblib_get_prop_dc_voltage_max(chg, val); + case POWER_SUPPLY_PROP_WIRELESS_WAKELOCK: + rc = smblib_set_prop_wireless_wakelock(chg, val); break; - case POWER_SUPPLY_PROP_REAL_TYPE: - val->intval = POWER_SUPPLY_TYPE_WIPOWER; + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + smb5_set_prop_input_voltage_regulation(chg, val); break; - case POWER_SUPPLY_PROP_DC_RESET: - val->intval = 0; + case POWER_SUPPLY_PROP_WIRELESS_CP_EN: + smblib_set_wirless_cp_enable(chg, val); break; - case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: - rc = smblib_get_prop_voltage_wls_output(chg, val); + case POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN: + smblib_set_wirless_power_good_enable(chg, val); break; default: return -EINVAL; } - if (rc < 0) { - pr_debug("Couldn't get prop %d rc = %d\n", psp, rc); - return -ENODATA; - } - return 0; + + return rc; } -static int smb5_dc_set_prop(struct power_supply *psy, +static int smb5_wireless_get_prop(struct power_supply *psy, enum power_supply_property psp, - const union power_supply_propval *val) + union power_supply_propval *val) { struct smb5 *chip = power_supply_get_drvdata(psy); struct smb_charger *chg = &chip->chg; int rc = 0; switch (psp) { - case POWER_SUPPLY_PROP_INPUT_SUSPEND: - rc = vote(chg->dc_suspend_votable, WBC_VOTER, - (bool)val->intval, 0); + case POWER_SUPPLY_PROP_WIRELESS_VERSION: + rc = smblib_get_prop_wireless_version(chg, val); break; - case POWER_SUPPLY_PROP_CURRENT_MAX: - rc = smblib_set_prop_dc_current_max(chg, val); + case POWER_SUPPLY_PROP_SIGNAL_STRENGTH: + smb5_get_prop_wireless_signal(chg, val); + break; + case POWER_SUPPLY_PROP_WIRELESS_WAKELOCK: + val->intval = 1; break; case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: - rc = smblib_set_prop_voltage_wls_output(chg, val); + smb5_get_prop_input_voltage_regulation(chg, val); break; - case POWER_SUPPLY_PROP_DC_RESET: - rc = smblib_set_prop_dc_reset(chg); + case POWER_SUPPLY_PROP_WIRELESS_CP_EN: + val->intval = chg->flag_dc_present; + break; + case POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN: + val->intval = chg->power_good_en; + break; + case POWER_SUPPLY_PROP_TX_ADAPTER: + smb5_get_prop_wirless_type(chg, val); break; default: return -EINVAL; } - - return rc; + if (rc < 0) { + pr_debug("Couldn't get prop %d rc = %d\n", psp, rc); + return -ENODATA; + } + return 0; } -static int smb5_dc_prop_is_writeable(struct power_supply *psy, +static int smb5_wireless_prop_is_writeable(struct power_supply *psy, enum power_supply_property psp) { switch (psp) { + case POWER_SUPPLY_PROP_WIRELESS_VERSION: + case POWER_SUPPLY_PROP_WIRELESS_WAKELOCK: case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + case POWER_SUPPLY_PROP_WIRELESS_CP_EN: + case POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN: return 1; default: break; @@ -1637,39 +3268,44 @@ static int smb5_dc_prop_is_writeable(struct power_supply *psy, return 0; } -static const struct power_supply_desc dc_psy_desc = { - .name = "dc", +static const struct power_supply_desc wireless_psy_desc = { + .name = "wireless", .type = POWER_SUPPLY_TYPE_WIRELESS, - .properties = smb5_dc_props, - .num_properties = ARRAY_SIZE(smb5_dc_props), - .get_property = smb5_dc_get_prop, - .set_property = smb5_dc_set_prop, - .property_is_writeable = smb5_dc_prop_is_writeable, + .properties = smb5_wireless_props, + .num_properties = ARRAY_SIZE(smb5_wireless_props), + .get_property = smb5_wireless_get_prop, + .set_property = smb5_wireless_set_prop, + .property_is_writeable = smb5_wireless_prop_is_writeable, }; -static int smb5_init_dc_psy(struct smb5 *chip) +static int smb5_init_wireless_psy(struct smb5 *chip) { - struct power_supply_config dc_cfg = {}; + struct power_supply_config wireless_cfg = {}; struct smb_charger *chg = &chip->chg; - dc_cfg.drv_data = chip; - dc_cfg.of_node = chg->dev->of_node; - chg->dc_psy = devm_power_supply_register(chg->dev, - &dc_psy_desc, - &dc_cfg); - if (IS_ERR(chg->dc_psy)) { - pr_err("Couldn't register USB power supply\n"); - return PTR_ERR(chg->dc_psy); + wireless_cfg.drv_data = chip; + wireless_cfg.of_node = chg->dev->of_node; + chg->wireless_psy = power_supply_register(chg->dev, + &wireless_psy_desc, + &wireless_cfg); + if (IS_ERR(chg->wireless_psy)) { + pr_err("Couldn't register wireless power supply\n"); + return PTR_ERR(chg->wireless_psy); } return 0; } +#endif /************************* * BATT PSY REGISTRATION * *************************/ static enum power_supply_property smb5_batt_props[] = { POWER_SUPPLY_PROP_INPUT_SUSPEND, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_PROP_LIQUID_DETECTION, + POWER_SUPPLY_PROP_DYNAMIC_FV_ENABLED, +#endif POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_PRESENT, @@ -1704,9 +3340,18 @@ static enum power_supply_property smb5_batt_props[] = { POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_FORCE_RECHARGE, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_CAPACITY_LEVEL, +#endif POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE, POWER_SUPPLY_PROP_CHARGING_ENABLED, +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED, +#endif + POWER_SUPPLY_PROP_DC_THERMAL_LEVELS, +#endif }; #define DEBUG_ACCESSORY_TEMP_DECIDEGC 250 @@ -1733,6 +3378,11 @@ static int smb5_batt_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CHARGE_TYPE: rc = smblib_get_prop_batt_charge_type(chg, val); break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_CAPACITY_LEVEL: + rc = smblib_get_prop_batt_capacity_level(chg, val); + break; +#endif case POWER_SUPPLY_PROP_CAPACITY: rc = smblib_get_prop_batt_capacity(chg, val); break; @@ -1742,6 +3392,11 @@ static int smb5_batt_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX: rc = smblib_get_prop_system_temp_level_max(chg, val); break; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_DC_THERMAL_LEVELS: + rc = smblib_get_prop_dc_temp_level(chg, val); + break; +#endif case POWER_SUPPLY_PROP_CHARGER_TEMP: rc = smblib_get_prop_charger_temp(chg, val); break; @@ -1775,8 +3430,10 @@ static int smb5_batt_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CURRENT_NOW: rc = smblib_get_prop_from_bms(chg, POWER_SUPPLY_PROP_CURRENT_NOW, val); +#ifndef CONFIG_MACH_XIAOMI_SM8150 if (!rc) val->intval *= (-1); +#endif break; case POWER_SUPPLY_PROP_CURRENT_QNOVO: val->intval = get_client_vote_locked(chg->fcc_votable, @@ -1800,7 +3457,11 @@ static int smb5_batt_get_prop(struct power_supply *psy, POWER_SUPPLY_PROP_TEMP, val); break; case POWER_SUPPLY_PROP_TECHNOLOGY: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO; +#else val->intval = POWER_SUPPLY_TECHNOLOGY_LION; +#endif break; case POWER_SUPPLY_PROP_CHARGE_DONE: rc = smblib_get_prop_batt_charge_done(chg, val); @@ -1822,6 +3483,11 @@ static int smb5_batt_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_DP_DM: val->intval = chg->pulse_cnt; break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_DP_DM_BQ: + val->intval = chg->pulse_cnt; + break; +#endif case POWER_SUPPLY_PROP_RERUN_AICL: val->intval = 0; break; @@ -1857,6 +3523,31 @@ static int smb5_batt_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE: val->intval = chg->fcc_stepper_enable; break; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_LIQUID_DETECTION: + if (chg->support_liquid == true) + rc = smblib_get_prop_liquid_status(chg, val); + else + val->intval = 0; + break; + case POWER_SUPPLY_PROP_DYNAMIC_FV_ENABLED: + val->intval = chg->dynamic_fv_enabled; + break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED: + rc = smblib_get_prop_battery_charging_enabled(chg, val); + break; + case POWER_SUPPLY_PROP_BATTERY_CHARGING_LIMITED: + rc = smblib_get_prop_battery_charging_limited(chg, val); + break; + case POWER_SUPPLY_PROP_SLOWLY_CHARGING: + rc = smblib_get_prop_battery_slowly_charging(chg, val); + break; + case POWER_SUPPLY_PROP_BQ_INPUT_SUSPEND: + rc = smblib_get_prop_battery_bq_input_suspend(chg, val); + break; +#endif +#endif default: pr_err("batt power supply prop %d not supported\n", psp); return -EINVAL; @@ -1876,6 +3567,9 @@ static int smb5_batt_set_prop(struct power_supply *psy, { int rc = 0; struct smb_charger *chg = power_supply_get_drvdata(psy); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + union power_supply_propval pval = {0,}; +#endif switch (prop) { case POWER_SUPPLY_PROP_STATUS: @@ -1885,8 +3579,20 @@ static int smb5_batt_set_prop(struct power_supply *psy, rc = smblib_set_prop_input_suspend(chg, val); break; case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (disable_thermal) { + smblib_set_prop_system_temp_level(chg, &pval); + break; + } +#endif rc = smblib_set_prop_system_temp_level(chg, val); break; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_DC_THERMAL_LEVELS: + if (chg->support_wireless) + rc = smblib_set_prop_dc_temp_level(chg, val); + break; +#endif case POWER_SUPPLY_PROP_CAPACITY: rc = smblib_set_prop_batt_capacity(chg, val); break; @@ -1908,6 +3614,11 @@ static int smb5_batt_set_prop(struct power_supply *psy, chg->batt_profile_fcc_ua = val->intval; vote(chg->fcc_votable, BATT_PROFILE_VOTER, true, val->intval); break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: + smb5_config_iterm(chg, val->intval, 50); + break; +#endif case POWER_SUPPLY_PROP_CURRENT_QNOVO: vote(chg->pl_disable_votable, PL_QNOVO_VOTER, val->intval != -EINVAL && val->intval < 2000000, 0); @@ -1939,6 +3650,12 @@ static int smb5_batt_set_prop(struct power_supply *psy, if (!chg->flash_active) rc = smblib_dp_dm(chg, val->intval); break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_DP_DM_BQ: + if (chg->use_bq_pump) + rc = smblib_dp_dm_bq(chg, val->intval); + break; +#endif case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: rc = smblib_set_prop_input_current_limited(chg, val); break; @@ -1958,9 +3675,53 @@ static int smb5_batt_set_prop(struct power_supply *psy, vote(chg->chg_disable_votable, FORCE_RECHARGE_VOTER, false, 0); break; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_LIQUID_DETECTION: + chg->lpd_status = val->intval; + power_supply_changed(chg->batt_psy); + break; + case POWER_SUPPLY_PROP_DYNAMIC_FV_ENABLED: + chg->dynamic_fv_enabled = !!val->intval; + break; +#endif case POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE: chg->fcc_stepper_enable = val->intval; break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED: + if (chg->use_bq_pump) { + if (val->intval == 0) + vote(chg->usb_icl_votable, MAIN_CHG_VOTER, + true, MAIN_CHARGER_STOP_ICL); + else + vote(chg->usb_icl_votable, MAIN_CHG_VOTER, + false, 0); + rerun_election(chg->usb_icl_votable); + } + break; + case POWER_SUPPLY_PROP_BATTERY_CHARGING_LIMITED: + if (chg->use_bq_pump) { + if (val->intval == 0) { + vote(chg->usb_icl_votable, MAIN_CHG_VOTER, + false, MAIN_CHARGER_ICL); + } else { + if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) + vote(chg->usb_icl_votable, MAIN_CHG_VOTER, + true, QC3_CHARGER_ICL); + else if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) + vote(chg->usb_icl_votable, MAIN_CHG_VOTER, + true, QC3P5_CHARGER_ICL); + else + vote(chg->usb_icl_votable, MAIN_CHG_VOTER, + true, MAIN_CHARGER_ICL); + } + rerun_election(chg->usb_icl_votable); + } + break; + case POWER_SUPPLY_PROP_SLOWLY_CHARGING: + rc = smblib_set_prop_battery_slowly_charging(chg, val); + break; +#endif default: rc = -EINVAL; } @@ -1979,10 +3740,23 @@ static int smb5_batt_prop_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_CAPACITY: case POWER_SUPPLY_PROP_PARALLEL_DISABLE: case POWER_SUPPLY_PROP_DP_DM: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_DP_DM_BQ: +#endif case POWER_SUPPLY_PROP_RERUN_AICL: case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED: case POWER_SUPPLY_PROP_DIE_HEALTH: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case POWER_SUPPLY_PROP_DC_THERMAL_LEVELS: + case POWER_SUPPLY_PROP_LIQUID_DETECTION: + case POWER_SUPPLY_PROP_DYNAMIC_FV_ENABLED: +#endif +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED: + case POWER_SUPPLY_PROP_BATTERY_CHARGING_LIMITED: + case POWER_SUPPLY_PROP_SLOWLY_CHARGING: +#endif return 1; default: break; @@ -2530,10 +4304,23 @@ static int smb5_configure_iterm_thresholds_adc(struct smb5 *chip) max_limit_ma); raw_hi_thresh = sign_extend32(raw_hi_thresh, 15); buf = (u8 *)&raw_hi_thresh; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = smblib_write(chg, CHGR_ADC_ITERM_UP_THD_MSB_REG, + buf[1]); + if (rc < 0) { + dev_err(chg->dev, "Couldn't set term MSB rc=%d\n", + rc); + return rc; + } + + rc = smblib_write(chg, CHGR_ADC_ITERM_UP_THD_LSB_REG, + buf[0]); +#else raw_hi_thresh = buf[1] | (buf[0] << 8); rc = smblib_batch_write(chg, CHGR_ADC_ITERM_UP_THD_MSB_REG, (u8 *)&raw_hi_thresh, 2); +#endif if (rc < 0) { dev_err(chg->dev, "Couldn't configure ITERM threshold HIGH rc=%d\n", rc); @@ -2678,6 +4465,9 @@ static int smb5_init_hw(struct smb5 *chip) if (chip->dt.batt_profile_fv_uv < 0) smblib_get_charge_param(chg, &chg->param.fv, &chg->batt_profile_fv_uv); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->batt_profile_fv_uv = chip->dt.batt_profile_fv_uv; +#endif smblib_get_charge_param(chg, &chg->param.usb_icl, &chg->default_icl_ua); @@ -2688,6 +4478,14 @@ static int smb5_init_hw(struct smb5 *chip) &chg->default_aicl_cont_threshold_mv); chg->aicl_cont_threshold_mv = chg->default_aicl_cont_threshold_mv; +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + if (chip->dt.dc_icl_ua < 0) { + smblib_get_charge_param(chg, &chg->param.dc_icl, + &chip->dt.dc_icl_ua); + chip->dt.dc_icl_ua = smblib_change_psns_to_curr(chg, chip->dt.dc_icl_ua); + } +#endif + if (chg->charger_temp_max == -EINVAL) { rc = smblib_get_thermal_threshold(chg, DIE_REG_H_THRESHOLD_MSB_REG, @@ -2819,12 +4617,25 @@ static int smb5_init_hw(struct smb5 *chip) chip->dt.batt_profile_fcc_ua > 0, chip->dt.batt_profile_fcc_ua); vote(chg->fv_votable, HW_LIMIT_VOTER, chip->dt.batt_profile_fv_uv > 0, chip->dt.batt_profile_fv_uv); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + vote(chg->fcc_votable, BATT_VERIFY_VOTER, + chip->dt.batt_unverify_fcc_ua > 0, chip->dt.batt_unverify_fcc_ua); + vote(chg->fv_votable, BATT_PROFILE_VOTER, + chg->batt_profile_fv_uv > 0, chg->batt_profile_fv_uv); + + /* if support ffc, default vfloat set to 4.4V, only fast charge need override to 4.45V */ + if (chg->support_ffc) + vote(chg->fv_votable, NON_FFC_VFLOAT_VOTER, + true, NON_FFC_VFLOAT_UV); +#endif vote(chg->fcc_votable, BATT_PROFILE_VOTER, chg->batt_profile_fcc_ua > 0, chg->batt_profile_fcc_ua); +#if !defined(CONFIG_MACH_XIAOMI_VAYU) && !defined(CONFIG_MACH_XIAOMI_NABU) vote(chg->fv_votable, BATT_PROFILE_VOTER, chg->batt_profile_fv_uv > 0, chg->batt_profile_fv_uv); +#endif /* Some h/w limit maximum supported ICL */ vote(chg->usb_icl_votable, HW_LIMIT_VOTER, @@ -2835,6 +4646,23 @@ static int smb5_init_hw(struct smb5 *chip) if (rc < 0) return rc; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + /* set dc icl by default voter */ + vote(chg->dc_icl_votable, + DCIN_ADAPTER_VOTER, true, chip->dt.dc_icl_ua); +#endif + + /* Disable DC Input missing poller function */ + rc = smblib_masked_write(chg, DCIN_LOAD_CFG_REG, + INPUT_MISS_POLL_EN_BIT, 0); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't disable DC Input missing poller rc=%d\n", rc); + return rc; + } +#endif + /* * AICL configuration: enable aicl and aicl rerun and based on DT * configuration enable/disable ADB based AICL and Suspend on collapse. @@ -2878,6 +4706,14 @@ static int smb5_init_hw(struct smb5 *chip) return rc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = smblib_masked_write(chg, DCIN_BASE + 0x65 , BIT(5), 0); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't configure IMP rc=%d\n", rc); + } +#endif + /* enable the charging path */ rc = vote(chg->chg_disable_votable, DEFAULT_VOTER, false, 0); if (rc < 0) { @@ -2914,6 +4750,9 @@ static int smb5_init_hw(struct smb5 *chip) rc = smblib_masked_write(chg, WD_CFG_REG, WATCHDOG_TRIGGER_AFP_EN_BIT | WDOG_TIMER_EN_ON_PLUGIN_BIT | +#ifdef CONFIG_MACH_XIAOMI_SM8150 + WDOG_TIMER_EN_BIT | +#endif BARK_WDOG_INT_EN_BIT, val); if (rc < 0) { pr_err("Couldn't configue WD config rc=%d\n", rc); @@ -2948,7 +4787,11 @@ static int smb5_init_hw(struct smb5 *chip) chg->float_cfg = val; /* Update float charger setting and set DCD timeout 300ms */ rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + FLOAT_OPTIONS_MASK, val); +#else FLOAT_OPTIONS_MASK | DCD_TIMEOUT_SEL_BIT, val); +#endif if (rc < 0) { dev_err(chg->dev, "Couldn't change float charger setting rc=%d\n", rc); @@ -2989,8 +4832,13 @@ static int smb5_init_hw(struct smb5 *chip) return rc; } +#ifndef CONFIG_MACH_XIAOMI_NABU rc = smblib_write(chg, CHGR_FAST_CHARGE_SAFETY_TIMER_CFG_REG, FAST_CHARGE_SAFETY_TIMER_768_MIN); +#else + rc = smblib_write(chg, CHGR_FAST_CHARGE_SAFETY_TIMER_CFG_REG, + FAST_CHARGE_SAFETY_TIMER_1536_MIN); +#endif if (rc < 0) { dev_err(chg->dev, "Couldn't set CHGR_FAST_CHARGE_SAFETY_TIMER_CFG_REG rc=%d\n", rc); @@ -3083,6 +4931,15 @@ static int smb5_init_hw(struct smb5 *chip) } } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = smblib_masked_write(chg, TYPE_C_DEBUG_ACC_SNK_CFG, 0x1F, 0x07); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure TYPE_C_DEBUG_ACC_SNK_CFG rc=%d\n", + rc); + return rc; + } +#endif + if (chg->smb_pull_up != -EINVAL) { rc = smb5_configure_internal_pull(chg, SMB_THERM, get_valid_pullup(chg->smb_pull_up)); @@ -3142,10 +4999,22 @@ static int smb5_determine_initial_status(struct smb5 *chip) } chg->early_usb_attach = val.intval; +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + rc = smblib_get_prop_dc_present(chg, &val); + if (rc < 0) { + pr_err("Couldn't get usb present rc=%d\n", rc); + return rc; + } + chg->early_dc_attach = val.intval; +#endif + if (chg->bms_psy) smblib_suspend_on_debug_battery(chg); usb_plugin_irq_handler(0, &irq_data); +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + dc_plugin_irq_handler(0, &irq_data); +#endif typec_attach_detach_irq_handler(0, &irq_data); typec_state_change_irq_handler(0, &irq_data); usb_source_change_irq_handler(0, &irq_data); @@ -3226,7 +5095,9 @@ static struct smb_irq_info smb5_irqs[] = { [BAT_TEMP_IRQ] = { .name = "bat-temp", .handler = batt_temp_changed_irq_handler, +#ifndef CONFIG_MACH_XIAOMI_SM8150 .wake = true, +#endif }, [ALL_CHNL_CONV_DONE_IRQ] = { .name = "all-chnl-conv-done", @@ -3296,7 +5167,11 @@ static struct smb_irq_info smb5_irqs[] = { }, [DCIN_UV_IRQ] = { .name = "dcin-uv", +#ifdef CONFIG_MACH_XIAOMI_SM8150 + .handler = dcin_uv_handler, +#else .handler = dcin_uv_irq_handler, +#endif .wake = true, }, [DCIN_OV_IRQ] = { @@ -3323,7 +5198,9 @@ static struct smb_irq_info smb5_irqs[] = { [TYPEC_OR_RID_DETECTION_CHANGE_IRQ] = { .name = "typec-or-rid-detect-change", .handler = typec_or_rid_detection_change_irq_handler, +#ifndef CONFIG_MACH_XIAOMI_SM8150 .wake = true, +#endif }, [TYPEC_VPD_DETECT_IRQ] = { .name = "typec-vpd-detect", @@ -3356,7 +5233,11 @@ static struct smb_irq_info smb5_irqs[] = { [WDOG_SNARL_IRQ] = { .name = "wdog-snarl", .handler = wdog_snarl_irq_handler, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + .wake = false, +#else .wake = true, +#endif }, [WDOG_BARK_IRQ] = { .name = "wdog-bark", @@ -3501,6 +5382,18 @@ static int smb5_request_interrupts(struct smb5 *chip) } } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /*enable batt_temp irq when plugin usb poweron charging*/ +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->irq_info[BAT_TEMP_IRQ].irq && (chg->early_usb_attach || chg->early_dc_attach)) { +#else + if (chg->irq_info[BAT_TEMP_IRQ].irq && (chg->early_usb_attach)) { +#endif + enable_irq_wake(chg->irq_info[BAT_TEMP_IRQ].irq); + chg->batt_temp_irq_enabled = true; + } +#endif + vote(chg->limited_irq_disable_votable, CHARGER_TYPE_VOTER, true, 0); vote(chg->hdc_irq_disable_votable, CHARGER_TYPE_VOTER, true, 0); @@ -3642,6 +5535,14 @@ static int smb5_show_charger_status(struct smb5 *chip) return rc; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +struct usbpd *smb_get_usbpd(void) +{ + return __smbchg->pd; +} +EXPORT_SYMBOL(smb_get_usbpd); +#endif + static int smb5_probe(struct platform_device *pdev) { struct smb5 *chip; @@ -3658,11 +5559,21 @@ static int smb5_probe(struct platform_device *pdev) chg->pd_disabled = &__pd_disabled; chg->weak_chg_icl_ua = &__weak_chg_icl_ua; chg->mode = PARALLEL_MASTER; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->apdo_max = 0; +#endif chg->irq_info = smb5_irqs; chg->die_health = -EINVAL; chg->connector_health = -EINVAL; chg->otg_present = false; chg->main_fcc_max = -EINVAL; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + chg->fake_dc_on = false; +#endif + chg->support_liquid = false; + chg->init_once = false; +#endif mutex_init(&chg->adc_lock); chg->regmap = dev_get_regmap(chg->dev->parent, NULL); @@ -3684,12 +5595,22 @@ static int smb5_probe(struct platform_device *pdev) return rc; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump) + __smbchg = chg; +#endif + if (alarmtimer_get_rtcdev()) alarm_init(&chg->lpd_recheck_timer, ALARM_REALTIME, smblib_lpd_recheck_timer); else return -EPROBE_DEFER; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* wakeup init should be done at the beginning of smb5_probe */ + device_init_wakeup(chg->dev, true); +#endif + rc = smblib_init(chg); if (rc < 0) { pr_err("Smblib_init failed rc=%d\n", rc); @@ -3812,12 +5733,30 @@ static int smb5_probe(struct platform_device *pdev) goto cleanup; } +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + rc = smb5_init_wireless_psy(chip); + if (rc < 0) { + pr_err("Couldn't initialize wireless psy rc=%d\n", rc); + goto cleanup; + } +#endif + rc = smb5_request_interrupts(chip); if (rc < 0) { pr_err("Couldn't request interrupts rc=%d\n", rc); goto cleanup; } +#ifdef CONFIG_MACH_XIAOMI_NABU + if (chg->support_wireless) { + rc = smb5_init_wireless_psy(chip); + if (rc < 0) { + pr_err("Couldn't initialize wireless psy rc=%d\n", rc); + goto cleanup; + } + } +#endif + rc = smb5_post_init(chip); if (rc < 0) { pr_err("Failed in post init rc=%d\n", rc); @@ -3832,12 +5771,17 @@ static int smb5_probe(struct platform_device *pdev) goto free_irq; } +#ifndef CONFIG_MACH_XIAOMI_SM8150 device_init_wakeup(chg->dev, true); +#endif if (chg->dcin_uusb_over_gpio_en && gpio_is_valid(chg->micro_usb_gpio)) smb_micro_usb_irq_handler(chg->micro_usb_irq, chg); pr_info("QPNP SMB5 probed successfully\n"); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + smblib_support_liquid_feature(chg); +#endif return rc; @@ -3878,6 +5822,11 @@ static void smb5_shutdown(struct platform_device *pdev) smblib_masked_write(chg, TYPE_C_MODE_CFG_REG, TYPEC_POWER_ROLE_CMD_MASK, EN_SNK_ONLY_BIT); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /*fix PD bug.Set 0x1360 = 0x0c when shutdown*/ + smblib_write(chg, USBIN_ADAPTER_ALLOW_CFG_REG, USBIN_ADAPTER_ALLOW_5V_TO_12V); +#endif + /* force enable and rerun APSD */ smblib_apsd_enable(chg, true); smblib_hvdcp_exit_config(chg); diff --git a/drivers/power/supply/qcom/smb1390-charger.c b/drivers/power/supply/qcom/smb1390-charger.c index f8fd9dbcdd63..ffd0ba084261 100644 --- a/drivers/power/supply/qcom/smb1390-charger.c +++ b/drivers/power/supply/qcom/smb1390-charger.c @@ -87,6 +87,9 @@ #define ILIM_VOTER "ILIM_VOTER" #define FCC_VOTER "FCC_VOTER" #define ICL_VOTER "ICL_VOTER" +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define ICL_CHANGE_VOTER "ICL_CHANGE_VOTER" +#endif #define TAPER_END_VOTER "TAPER_END_VOTER" #define WIRELESS_VOTER "WIRELESS_VOTER" #define SRC_VOTER "SRC_VOTER" @@ -139,6 +142,9 @@ struct smb1390 { int irqs[NUM_IRQS]; bool status_change_running; bool taper_work_running; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool taper_early_trigger; +#endif struct smb1390_iio iio; int irq_status; int taper_entry_fv; @@ -343,6 +349,22 @@ static ssize_t stat2_show(struct class *c, struct class_attribute *attr, } static CLASS_ATTR_RO(stat2); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static ssize_t model_name_show(struct class *c, struct class_attribute *attr, + char *buf) +{ + struct smb1390 *chip = container_of(c, struct smb1390, cp_class); + int rc, val; + + rc = smb1390_read(chip, CORE_STATUS1_REG, &val); + if (rc < 0) + return snprintf(buf, PAGE_SIZE, "%s\n", "unknown"); + else + return snprintf(buf, PAGE_SIZE, "%s\n", "smb1390"); +} +static CLASS_ATTR_RO(model_name); +#endif + static ssize_t enable_show(struct class *c, struct class_attribute *attr, char *buf) { @@ -469,6 +491,9 @@ static struct attribute *cp_class_attrs[] = { &class_attr_toggle_switcher.attr, &class_attr_die_temp.attr, &class_attr_isns.attr, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + &class_attr_model_name.attr, +#endif NULL, }; ATTRIBUTE_GROUPS(cp_class); @@ -519,7 +544,11 @@ static int smb1390_ilim_vote_cb(struct votable *votable, void *data, } /* ILIM less than 1A is not accurate; disable charging */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (ilim_uA < 900000) { +#else if (ilim_uA < 1000000) { +#endif pr_debug("ILIM %duA is too low to allow charging\n", ilim_uA); vote(chip->disable_votable, ILIM_VOTER, true, 0); } else { @@ -575,12 +604,20 @@ static int smb1390_notifier_cb(struct notifier_block *nb, return NOTIFY_OK; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define TAPER_CAPACITY_THR 55 +#define TAPER_CAPCITY_DELTA 1 +#define BATT_COOL_THR 220 +#endif static void smb1390_status_change_work(struct work_struct *work) { struct smb1390 *chip = container_of(work, struct smb1390, status_change_work); union power_supply_propval pval = {0, }; int max_fcc_ma, rc; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int capacity, batt_temp, charge_type; +#endif if (!is_psy_voter_available(chip)) goto out; @@ -612,6 +649,9 @@ static void smb1390_status_change_work(struct work_struct *work) */ if (pval.intval == POWER_SUPPLY_CP_WIRELESS) { vote(chip->ilim_votable, ICL_VOTER, false, 0); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + vote(chip->ilim_votable, ICL_CHANGE_VOTER, false, 0); +#endif rc = power_supply_get_property(chip->dc_psy, POWER_SUPPLY_PROP_CURRENT_MAX, &pval); if (rc < 0) @@ -650,6 +690,57 @@ static void smb1390_status_change_work(struct work_struct *work) if (get_effective_result(chip->disable_votable)) goto out; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &pval); + if (rc < 0) { + pr_err("Couldn't get batt capacity rc=%d\n", rc); + goto out; + } + capacity = pval.intval; + + rc = power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_TEMP, &pval); + if (rc < 0) { + pr_err("Couldn't get batt temp rc=%d\n", rc); + goto out; + } + batt_temp = pval.intval; + + rc = power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_CHARGE_TYPE, &pval); + if (rc < 0) { + pr_err("Couldn't get charge type rc=%d\n", rc); + goto out; + } + charge_type = pval.intval; + + pr_info("capacity:%d, batt_temp:%d, charge_type:%d\n", + capacity, batt_temp, charge_type); + + /* + * if taper happens too early due to battery esr is high caused by + * battery temperature is cool, vbat is easy to reach to near to vfloat, + * we will reset CP_VOTER here if early taper happens and battery + * temp recover to normal(above 22 degree by test) and charge type + * is FAST and battery capacity is below 55% to recover 1.5C charging + */ + if ((capacity < TAPER_CAPACITY_THR) + && (batt_temp >= BATT_COOL_THR) + && (charge_type == POWER_SUPPLY_CHARGE_TYPE_FAST) + && chip->taper_early_trigger) { + if (is_client_vote_enabled(chip->fcc_votable, + CP_VOTER)) { + /* reset cp_voter here */ + vote(chip->fcc_votable, CP_VOTER, false, 0); + /* input current is always half the charge current */ + vote(chip->ilim_votable, FCC_VOTER, true, + get_effective_result(chip->fcc_votable) / 2); + chip->taper_early_trigger = false; + } + } +#endif + rc = power_supply_get_property(chip->batt_psy, POWER_SUPPLY_PROP_CHARGE_TYPE, &pval); if (rc < 0) { @@ -673,6 +764,9 @@ static void smb1390_status_change_work(struct work_struct *work) BATT_PROFILE_VOTER); vote(chip->fcc_votable, CP_VOTER, max_fcc_ma > 0 ? true : false, max_fcc_ma); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chip->taper_early_trigger = false; +#endif vote(chip->disable_votable, SOC_LEVEL_VOTER, true, 0); } @@ -686,12 +780,34 @@ static void smb1390_taper_work(struct work_struct *work) struct smb1390 *chip = container_of(work, struct smb1390, taper_work); union power_supply_propval pval = {0, }; int rc, fcc_uA; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int capacity; +#endif if (!is_psy_voter_available(chip)) goto out; chip->taper_entry_fv = get_effective_result(chip->fv_votable); while (true) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &pval); + if (rc < 0) { + pr_err("Couldn't get batt capacity rc=%d\n", rc); + goto out; + } + capacity = pval.intval; + /* + * if capacity is lower than 55% - 1%(delta) and taper charge comes + * we think it is a early taper, normaly due to battery temperature is low + * such as 10 to 22 degree, battery esr is high and high current charging + * (charge pump is working during 10 to 22 degree, not working below 10) + */ + if ((capacity < (TAPER_CAPACITY_THR - TAPER_CAPCITY_DELTA)) + && !chip->taper_early_trigger) + chip->taper_early_trigger = true; +#endif + rc = power_supply_get_property(chip->batt_psy, POWER_SUPPLY_PROP_CHARGE_TYPE, &pval); if (rc < 0) { @@ -795,6 +911,9 @@ static void smb1390_destroy_votables(struct smb1390 *chip) static int smb1390_init_hw(struct smb1390 *chip) { int rc; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int val; +#endif /* * charge pump is initially disabled; this indirectly votes to allow @@ -820,6 +939,15 @@ static int smb1390_init_hw(struct smb1390 *chip) if (rc < 0) return rc; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = smb1390_read(chip, 0x1032, &val); + + rc = smb1390_masked_write(chip, 0x1032, 0x0F, 0x07); + rc = smb1390_read(chip, 0x1032, &val); + + if (rc < 0) + return rc; +#endif return 0; } diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c index bea84df021e6..2df71494216e 100644 --- a/drivers/power/supply/qcom/smb5-lib.c +++ b/drivers/power/supply/qcom/smb5-lib.c @@ -50,8 +50,21 @@ || typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH) \ && (!chg->typec_legacy || chg->typec_legacy_use_rp_icl)) +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static bool off_charge_flag; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static bool first_boot_flag; +#endif + +bool smblib_rsbux_low(struct smb_charger *chg, int r_thr); +static int smblib_get_prop_typec_mode(struct smb_charger *chg); +#endif + static void update_sw_icl_max(struct smb_charger *chg, int pst); static int smblib_get_prop_typec_mode(struct smb_charger *chg); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static int smblib_get_prop_dfp_mode(struct smb_charger *chg); +#endif int smblib_read(struct smb_charger *chg, u16 addr, u8 *val) { @@ -109,6 +122,25 @@ int smblib_get_iio_channel(struct smb_charger *chg, const char *propname, return rc; } +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) +static void smblib_wireless_set_enable(struct smb_charger *chg, int enable) +{ + int rc = 0; + union power_supply_propval val = {0, }; + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) + { + val.intval = enable; + rc = power_supply_set_property(chg->idtp_psy, POWER_SUPPLY_PROP_PIN_ENABLED, &val); + if (rc < 0) { + smblib_err(chg, "Could not set charger control limit =%d\n", rc); + return; + } + } +} +#endif + #define DIV_FACTOR_MICRO_V_I 1 #define DIV_FACTOR_MILI_V_I 1000 #define DIV_FACTOR_DECIDEGC 100 @@ -491,6 +523,9 @@ enum { FLOAT, HVDCP2, HVDCP3, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + HVDCP3P5, +#endif MAX_TYPES }; @@ -535,6 +570,12 @@ static const struct apsd_result smblib_apsd_results[] = { .bit = DCP_CHARGER_BIT | QC_3P0_BIT, .pst = POWER_SUPPLY_TYPE_USB_HVDCP_3, }, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + [HVDCP3P5] = { + .name = "HVDCP3P5", + .pst = POWER_SUPPLY_TYPE_USB_HVDCP_3P5, + }, +#endif }; static const struct apsd_result *smblib_get_apsd_result(struct smb_charger *chg) @@ -567,9 +608,24 @@ static const struct apsd_result *smblib_get_apsd_result(struct smb_charger *chg) } if (apsd_stat & QC_CHARGER_BIT) { +#ifdef CONFIG_MACH_XIAOMI_NABU + if (chg->qc3p5_supported) { + if (result == &smblib_apsd_results[HVDCP3] + && chg->qc3p5_authenticated) { + result = &smblib_apsd_results[HVDCP3P5]; + } else if ((result != &smblib_apsd_results[HVDCP3P5]) + && (result != &smblib_apsd_results[HVDCP3])) { + /* If not QC3 or QC3.5, return QC2 */ + result = &smblib_apsd_results[HVDCP2]; + } + } else { +#endif /* since its a qc_charger, either return HVDCP3 or HVDCP2 */ if (result != &smblib_apsd_results[HVDCP3]) result = &smblib_apsd_results[HVDCP2]; +#ifdef CONFIG_MACH_XIAOMI_NABU + } +#endif } return result; @@ -761,6 +817,253 @@ int smblib_set_dc_suspend(struct smb_charger *chg, bool suspend) return rc; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smblib_get_fastcharge_mode(struct smb_charger *chg) +{ + union power_supply_propval pval = {0,}; + int rc = 0; + + if (!chg->bms_psy) + return 0; + + rc = power_supply_get_property(chg->bms_psy, + POWER_SUPPLY_PROP_FASTCHARGE_MODE, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't read fastcharge mode:%d\n", rc); + return rc; + } + + return pval.intval; +} + +static int smb5_config_sys_iterm(struct smb_charger *chg, bool ffc_enable) +{ + union power_supply_propval pval = {0,}; + int rc; + + pval.intval = ffc_enable; + + rc = power_supply_set_property(chg->bms_psy, + POWER_SUPPLY_PROP_SYS_TERMINATION_CURRENT, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't set ffc termination current:%d\n", rc); + return rc; + } + rc = power_supply_set_property(chg->bms_psy, + POWER_SUPPLY_PROP_VBATT_FULL_VOL, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't set ffc vabtt full:%d\n", rc); + return rc; + } + + rc = power_supply_set_property(chg->bms_psy, + POWER_SUPPLY_PROP_KI_COEFF_CURRENT, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't set ffc ki_coefet:%d\n", rc); + return rc; + } + return rc; +} + +int smb5_config_iterm(struct smb_charger *chg, int hi_thresh, int low_thresh) +{ + s16 raw_hi_thresh, raw_lo_thresh; + u8 *buf; + int rc = 0; + + rc = smblib_masked_write(chg, CHGR_ADC_TERM_CFG_REG, + TERM_BASED_ON_SYNC_CONV_OR_SAMPLE_CNT, + TERM_BASED_ON_SAMPLE_CNT); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure ADC_ITERM_CFG rc=%d\n", + rc); + return rc; + } + + /* + * Conversion: + * raw (A) = (scaled_mA * ADC_CHG_TERM_MASK) / (10 * 1000) + * Note: raw needs to be converted to big-endian format. + */ + + if (hi_thresh) { + raw_hi_thresh = ((hi_thresh * ADC_CHG_ITERM_MASK) / 10000); + raw_hi_thresh = sign_extend32(raw_hi_thresh, 15); + buf = (u8 *)&raw_hi_thresh; + rc = smblib_write(chg, CHGR_ADC_ITERM_UP_THD_MSB_REG, + buf[1]); + if (rc < 0) { + dev_err(chg->dev, "Couldn't set term MSB rc=%d\n", + rc); + return rc; + } + rc = smblib_write(chg, CHGR_ADC_ITERM_UP_THD_LSB_REG, + buf[0]); + if (rc < 0) { + dev_err(chg->dev, "Couldn't set term LSB rc=%d\n", + rc); + return rc; + } + } + + if (low_thresh) { + raw_lo_thresh = ((low_thresh * ADC_CHG_ITERM_MASK) / 10000); + raw_lo_thresh = sign_extend32(raw_lo_thresh, 15); + buf = (u8 *)&raw_lo_thresh; + raw_lo_thresh = buf[1] | (buf[0] << 8); + + rc = smblib_batch_write(chg, CHGR_ADC_ITERM_LO_THD_MSB_REG, + (u8 *)&raw_lo_thresh, 2); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure ITERM threshold LOW rc=%d\n", + rc); + return rc; + } + } + + return 0; +} + +#ifdef CONFIG_MACH_XIAOMI_NABU +static int set_ln8000_fv(struct smb_charger *chg) { + int rc; + union power_supply_propval val; + if (!chg->cp_psy) { + chg->cp_psy = power_supply_get_by_name("bq2597x-standalone"); + if (!chg->cp_psy){ + chg->cp_psy = power_supply_get_by_name("ln8000"); + if (!chg->cp_psy){ + pr_err("cp_psy not found\n"); + return 0; + } + } + } + + rc = power_supply_get_property(chg->cp_psy, + POWER_SUPPLY_PROP_MODEL_NAME, &val); + if (rc < 0) { + pr_err("Error in getting charge IC name, rc=%d\n", rc); + return 0; + } + + if (strcmp(val.strval, "ln8000") == 0) { + vote(chg->fv_votable, BATT_LN8000_VOTER, true, 4470000); + } + return 0; +} +#endif + +int smblib_set_fastcharge_mode(struct smb_charger *chg, bool enable) +{ + union power_supply_propval pval = {0,}; + int rc = 0; + int termi = -220, batt_temp; + + if (!chg->bms_psy) + return 0; + + rc = power_supply_get_property(chg->bms_psy, + POWER_SUPPLY_PROP_AUTHENTIC, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get battery authentic:%d\n", rc); + return rc; + } + if (!pval.intval) + enable = false; + + /*if soc > 95 do not set fastcharge flag*/ + rc = power_supply_get_property(chg->bms_psy, + POWER_SUPPLY_PROP_CAPACITY, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get bms capacity:%d\n", rc); + return rc; + } + if (enable && pval.intval >= 95) { + smblib_dbg(chg, PR_MISC, "soc:%d is more than 95" + "do not setfastcharge mode\n", pval.intval); + enable = false; + } + /*if temp > 450 or temp < 150 do not set fastcharge flag*/ + rc = power_supply_get_property(chg->bms_psy, + POWER_SUPPLY_PROP_TEMP, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get bms capacity:%d\n", rc); + goto set_term; + } + batt_temp = pval.intval; + if (enable && (pval.intval >= chg->ffc_high_tbat || pval.intval <= chg->ffc_low_tbat)) { + pr_info("tbat out of range, don't enable ffc\n"); + enable = false; + } + + pval.intval = enable; + rc = power_supply_set_property(chg->bms_psy, + POWER_SUPPLY_PROP_FASTCHARGE_MODE, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't write fastcharge mode:%d\n", rc); + goto set_term; + } + + if (enable) { + /* ffc need clear non_fcc_vfloat_voter first */ + vote(chg->fv_votable, NON_FFC_VFLOAT_VOTER, false, 0); +#ifdef CONFIG_MACH_XIAOMI_NABU + set_ln8000_fv(chg); +#endif + rc = power_supply_get_property(chg->bms_psy, + POWER_SUPPLY_PROP_FFC_TERMINATION_CURRENT, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't ffc termination current:%d\n", rc); + goto set_term; + } + termi = pval.intval; + + } else { + /* when disable fast charge mode, need set vfloat back to 4.4V */ + vote(chg->fv_votable, NON_FFC_VFLOAT_VOTER, + true, NON_FFC_VFLOAT_UV); + termi = chg->chg_term_current_thresh_hi_from_dts; + } + smb5_config_sys_iterm(chg, enable); +set_term: + smb5_config_iterm(chg, termi, 50); + + rc = vote(chg->fcc_votable, PD_VERIFED_VOTER, + !enable, PD_UNVERIFED_CURRENT); + + rc = vote(chg->fv_votable, PD_VERIFED_VOTER, + !enable, PD_UNVERIFED_VOLTAGE); + + pr_info("fastcharge mode:%d termi:%d\n", enable, termi); + + return 0; +} + +static void smblib_check_batt_authentic(struct smb_charger *chg) +{ + int rc = 0; + int authen_result = -1; + union power_supply_propval pval = {0,}; + if (chg->batt_verify_psy && chg->bms_psy) { + rc = power_supply_get_property(chg->bms_psy, + POWER_SUPPLY_PROP_AUTHENTIC, &pval); + if (!rc) + authen_result = pval.intval; + pr_err("authen_result: %d\n", authen_result); + if (!authen_result) { + pval.intval = 1; + rc = power_supply_set_property(chg->batt_verify_psy, + POWER_SUPPLY_PROP_AUTHENTIC, &pval); + if (rc) + pr_err("set batt_verify authentic prop failed: %d\n", + rc); + } + /* notify smblib_notifier_call to reset BATT_VERIFY_VOTER fcc voter */ + power_supply_changed(chg->bms_psy); + } +} +#endif + static int smblib_usb_pd_adapter_allowance_override(struct smb_charger *chg, u8 allowed_voltage) { @@ -780,6 +1083,40 @@ static int smblib_usb_pd_adapter_allowance_override(struct smb_charger *chg, return rc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static int smblib_set_adapter_allowance(struct smb_charger *chg, + u8 allowed_voltage) +{ + int rc = 0; + + /* PMI632 only support max. 9V */ + if (chg->chg_param.smb_version == PMI632_SUBTYPE) { + switch (allowed_voltage) { + case USBIN_ADAPTER_ALLOW_12V: + case USBIN_ADAPTER_ALLOW_9V_TO_12V: + allowed_voltage = USBIN_ADAPTER_ALLOW_9V; + break; + case USBIN_ADAPTER_ALLOW_5V_OR_12V: + case USBIN_ADAPTER_ALLOW_5V_OR_9V_TO_12V: + allowed_voltage = USBIN_ADAPTER_ALLOW_5V_OR_9V; + break; + case USBIN_ADAPTER_ALLOW_5V_TO_12V: + allowed_voltage = USBIN_ADAPTER_ALLOW_5V_TO_9V; + break; + } + } + + rc = smblib_write(chg, USBIN_ADAPTER_ALLOW_CFG_REG, allowed_voltage); + if (rc < 0) { + smblib_err(chg, "Couldn't write 0x%02x to USBIN_ADAPTER_ALLOW_CFG rc=%d\n", + allowed_voltage, rc); + return rc; + } + + return rc; +} +#endif + #define MICRO_5V 5000000 #define MICRO_9V 9000000 #define MICRO_12V 12000000 @@ -1083,6 +1420,9 @@ static const struct apsd_result *smblib_update_usb_type(struct smb_charger *chg) /* if PD is active, APSD is disabled so won't have a valid result */ if (chg->pd_active) { chg->real_charger_type = POWER_SUPPLY_TYPE_USB_PD; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_PD; +#endif } else if (chg->qc3p5_detected) { chg->real_charger_type = POWER_SUPPLY_TYPE_USB_HVDCP_3P5; } else { @@ -1090,9 +1430,23 @@ static const struct apsd_result *smblib_update_usb_type(struct smb_charger *chg) * Update real charger type only if its not FLOAT * detected as as SDP */ +#ifndef CONFIG_MACH_XIAOMI_NABU if (!(apsd_result->pst == POWER_SUPPLY_TYPE_USB_FLOAT && chg->real_charger_type == POWER_SUPPLY_TYPE_USB)) +#else + if (!(apsd_result->pst == POWER_SUPPLY_TYPE_USB_FLOAT && + chg->real_charger_type == POWER_SUPPLY_TYPE_USB) && + (!chg->qc3p5_supported || chg->qc3p5_auth_complete || + apsd_result->pst != POWER_SUPPLY_TYPE_USB_HVDCP_3)) +#endif +#ifdef CONFIG_MACH_XIAOMI_SM8150 + { +#endif chg->real_charger_type = apsd_result->pst; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->usb_psy_desc.type = apsd_result->pst; + } +#endif } smblib_dbg(chg, PR_MISC, "APSD=%s PD=%d QC3P5=%d\n", @@ -1110,7 +1464,15 @@ static int smblib_notifier_call(struct notifier_block *nb, if (!chg->bms_psy) chg->bms_psy = psy; if (ev == PSY_EVENT_PROP_CHANGED) +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + { + if (!chg->batt_verified) + schedule_delayed_work(&chg->batt_verify_update_work, 0); +#endif schedule_work(&chg->bms_update_work); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + } // git don't pick this bracket +#endif } if (chg->jeita_configured == JEITA_CFG_NONE) @@ -1238,6 +1600,9 @@ static void smblib_uusb_removal(struct smb_charger *chg) del_timer_sync(&chg->apsd_timer); chg->apsd_ext_timeout = false; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->report_usb_absent = false; +#endif /* write back the default FLOAT charger configuration */ rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG, @@ -1309,6 +1674,9 @@ int smblib_rerun_apsd_if_required(struct smb_charger *chg) { union power_supply_propval val; int rc; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + const struct apsd_result *apsd_result; +#endif rc = smblib_get_prop_usb_present(chg, &val); if (rc < 0) { @@ -1316,15 +1684,40 @@ int smblib_rerun_apsd_if_required(struct smb_charger *chg) return rc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (!val.intval || chg->fake_usb_insertion) +#else if (!val.intval) +#endif return 0; +#ifndef CONFIG_MACH_XIAOMI_SM8150 rc = smblib_request_dpdm(chg, true); if (rc < 0) smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc); +#endif chg->uusb_apsd_rerun_done = true; + +#ifndef CONFIG_MACH_XIAOMI_SM8150 smblib_rerun_apsd(chg); +#else + if (!off_charge_flag) { + rc = smblib_request_dpdm(chg, true); + if (rc < 0) + smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc); + smblib_rerun_apsd(chg); + } else { + apsd_result = smblib_update_usb_type(chg); + /* if apsd result is SDP and off-charge mode, no need rerun apsd */ + if (!(apsd_result->bit & SDP_CHARGER_BIT)) { + rc = smblib_request_dpdm(chg, true); + if (rc < 0) + smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc); + smblib_rerun_apsd(chg); + } + } +#endif return 0; } @@ -1421,6 +1814,9 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) if (!chg->dcin_uusb_over_gpio_en) { /* configure current */ if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB +#ifdef CONFIG_MACH_XIAOMI_SM8150 + && (icl_ua <= USBIN_500MA) +#endif && (chg->typec_legacy || chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->connector_type == @@ -1438,7 +1834,11 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) * or below for better accuracy; in case of error, * proceed to use USB high-current mode. */ +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + if (icl_ua < USBIN_100MA) { +#else if (icl_ua <= USBIN_500MA) { +#endif rc = set_sdp_current(chg, icl_ua); if (rc >= 0) goto unsuspend; @@ -1697,6 +2097,46 @@ static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data, return smblib_set_dc_suspend(chg, (bool)suspend); } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static int smblib_dc_icl_vote_callback(struct votable *votable, void *data, + int icl_ua, const char *client) +{ + struct smb_charger *chg = data; + int rc = 0; + bool suspend; + int Vpsns; + + if (icl_ua < 0) { + smblib_dbg(chg, PR_MISC, "No Voter hence suspending\n"); + icl_ua = 0; + } + + suspend = (icl_ua <= USBIN_25MA); + if (suspend) + goto suspend; + + Vpsns = (icl_ua/PSNS_CURRENT_SAMPLE_RATE) * PSNS_CURRENT_SAMPLE_RESIS; + if (chg->dc_temp_level == 13 || chg->dc_temp_level == 9) + Vpsns += PSNS_COMP_UV_FOR_HIGH_THERMAL; + + rc = smblib_set_charge_param(chg, &chg->param.dc_icl, Vpsns); + if (rc < 0) { + smblib_err(chg, "Couldn't set DC input current limit rc=%d\n", + rc); + return rc; + } + +suspend: + rc = vote(chg->dc_suspend_votable, USER_VOTER, suspend, 0); + if (rc < 0) { + smblib_err(chg, "Couldn't vote to %s DC rc=%d\n", + suspend ? "suspend" : "resume", rc); + return rc; + } + return rc; +} +#endif + static int smblib_awake_vote_callback(struct votable *votable, void *data, int awake, const char *client) { @@ -1932,6 +2372,33 @@ int smblib_vbus_regulator_is_enabled(struct regulator_dev *rdev) return (cmd & OTG_EN_BIT) ? 1 : 0; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static int smblib_get_batt_voltage_now(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc; + + rc = smblib_get_prop_from_bms(chg, + POWER_SUPPLY_PROP_VOLTAGE_NOW, val); + + return rc; +} + +static void smblib_get_start_vbat_before_step_charge(struct smb_charger *chg) +{ + int rc; + union power_supply_propval pval = {0, }; + + rc = smblib_get_batt_voltage_now(chg, &pval); + if (!rc) + chg->start_step_vbat = pval.intval; + else + pr_err("could not get vbat vol from bms\n"); + + pr_err("chg->start_step_vbat: %d\n", chg->start_step_vbat); +} +#endif + /******************** * BATT PSY GETTERS * ********************/ @@ -1941,7 +2408,11 @@ int smblib_get_prop_input_suspend(struct smb_charger *chg, { val->intval = (get_client_vote(chg->usb_icl_votable, USER_VOTER) == 0) +#ifdef CONFIG_MACH_XIAOMI_SM8150 + || get_client_vote(chg->dc_suspend_votable, USER_VOTER); +#else && get_client_vote(chg->dc_suspend_votable, USER_VOTER); +#endif return 0; } @@ -1963,51 +2434,242 @@ int smblib_get_prop_batt_present(struct smb_charger *chg, return rc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int smblib_get_prop_batt_voltage_now(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc; + if (!chg->bms_psy) + return -EINVAL; + + rc = power_supply_get_property(chg->bms_psy, + POWER_SUPPLY_PROP_VOLTAGE_NOW, val); + return rc; +} + +static void smblib_check_usb_status(struct smb_charger *chg) +{ + int rc; + int usb_present = 0, vbat_uv = 0; + union power_supply_propval pval = {0,}; + + rc = smblib_get_prop_usb_present(chg, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get usb present rc = %d\n", rc); + return; + } + usb_present = pval.intval; + + if (!usb_present) + return; + + rc = smblib_get_prop_batt_voltage_now(chg, &pval); + if (rc < 0) { + pr_err("Couldn't get vbat rc=%d\n", rc); + return; + } + vbat_uv = pval.intval; + + /* + * if battery soc is 0%, vbat is below 3400mV and usb is present in + * normal mode(not power-off charging mode), set online to + * false to notify system to power off. + */ + if ((usb_present == 1) && (!off_charge_flag) + && (vbat_uv <= CUTOFF_VOL_THR)) { + chg->report_usb_absent = true; + power_supply_changed(chg->batt_psy); + } +} +#endif + int smblib_get_prop_batt_capacity(struct smb_charger *chg, union power_supply_propval *val) { int rc = -EINVAL; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->fake_capacity >= 0 && chg->fake_capacity <= 100) { +#else if (chg->fake_capacity >= 0) { +#endif val->intval = chg->fake_capacity; return 0; } rc = smblib_get_prop_from_bms(chg, POWER_SUPPLY_PROP_CAPACITY, val); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (val->intval == 0) + smblib_check_usb_status(chg); +#endif + return rc; } -static bool is_charging_paused(struct smb_charger *chg) +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smblib_get_prop_batt_capacity_level(struct smb_charger *chg, + union power_supply_propval *val) { - int rc; - u8 val; + int rc,cap; + union power_supply_propval capacity = {0, }; - rc = smblib_read(chg, CHARGING_PAUSE_CMD_REG, &val); - if (rc < 0) { - smblib_err(chg, "Couldn't read CHARGING_PAUSE_CMD rc=%d\n", rc); - return false; - } + rc = smblib_get_prop_batt_capacity(chg, &capacity); - return val & CHARGING_PAUSE_CMD_BIT; + cap = capacity.intval; + if (cap <= 0) + val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; + if (cap > 0 && cap <= 20) + val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW; + if (cap > 20 && cap <= 80) + val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; + if (cap > 80 && cap <= 99) + val->intval = POWER_SUPPLY_CAPACITY_LEVEL_HIGH; + if (cap >= 100) + val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL; + return rc; // git } -int smblib_get_prop_batt_status(struct smb_charger *chg, - union power_supply_propval *val) +static bool smblib_is_jeita_warm_charging(struct smb_charger *chg) { union power_supply_propval pval = {0, }; bool usb_online, dc_online; - u8 stat; - int rc, suspend = 0; + int rc; - if (chg->fake_chg_status_on_debug_batt) { - rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_DEBUG_BATTERY, &pval); - if (rc < 0) { - pr_err_ratelimited("Couldn't get debug battery prop rc=%d\n", - rc); - } else if (pval.intval == 1) { - val->intval = POWER_SUPPLY_STATUS_UNKNOWN; + rc = smblib_get_prop_usb_online(chg, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get usb online property rc=%d\n", + rc); + return rc; // git + } // git + usb_online = (bool)pval.intval; + + rc = smblib_get_prop_dc_online(chg, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get dc online property rc=%d\n", + rc); + return rc; // git + } // git + dc_online = (bool)pval.intval; + + if (!usb_online && !dc_online) + return false; + + rc = smblib_get_prop_batt_health(chg, &pval); + if (rc < 0) + smblib_err(chg, "Couldn't get batt health rc=%d\n", rc); + + /* show charging when jeita warm if real charging status is not charging */ + if (POWER_SUPPLY_HEALTH_WARM == pval.intval) + return true; + else + return false; +} +#endif + +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) +static bool smblib_wireless_to_usb_charging(struct smb_charger *chg, + bool usb_online, bool dc_online) +{ + if ((usb_online || chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH) + && chg->fake_dc_on) { + /* insert usb when wireless charging, set status + * to charge and charger type to DCP + * insert pd charger when wireless charging, power good irq will + * trigger very qucickly difference with other charger type. + */ + if (!chg->pd_active) { + chg->real_charger_type = POWER_SUPPLY_TYPE_USB_DCP; + chg->usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_DCP; + } + return true; + } else if (smblib_get_prop_dfp_mode(chg) != POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER + && smblib_get_prop_dfp_mode(chg) != POWER_SUPPLY_TYPEC_NONE + && chg->power_good_en) { + smblib_dbg(chg, PR_WLS, "otg mode, set charging when pwr on\n"); + return true; + } + else + return false; +} + +static bool smblib_is_jeita_warm_charging(struct smb_charger *chg) +{ + union power_supply_propval pval = {0, }; + bool usb_online, dc_online; + int rc; + + rc = smblib_get_prop_usb_online(chg, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get usb online property rc=%d\n", + rc); + return rc; + } + usb_online = (bool)pval.intval; + + rc = smblib_get_prop_dc_online(chg, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get dc online property rc=%d\n", + rc); + return rc; + } + dc_online = (bool)pval.intval; + + if (!usb_online && !dc_online) + return false; + + rc = smblib_get_prop_batt_health(chg, &pval); + if (rc < 0) + smblib_err(chg, "Couldn't get batt health rc=%d\n", rc); + + if (POWER_SUPPLY_HEALTH_WARM == pval.intval) + return true; + else + return false; +} +#endif + +static bool is_charging_paused(struct smb_charger *chg) +{ + int rc; + u8 val; + + rc = smblib_read(chg, CHARGING_PAUSE_CMD_REG, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't read CHARGING_PAUSE_CMD rc=%d\n", rc); + return false; + } + + return val & CHARGING_PAUSE_CMD_BIT; +} + +int smblib_get_prop_batt_status(struct smb_charger *chg, + union power_supply_propval *val) +{ + union power_supply_propval pval = {0, }; + bool usb_online, dc_online; + u8 stat; + int rc, suspend = 0; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + union power_supply_propval batt_capa = {0, }; +#endif + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump && (get_client_vote_locked(chg->usb_icl_votable, + MAIN_CHG_VOTER) == MAIN_CHARGER_STOP_ICL)) { + val->intval = POWER_SUPPLY_STATUS_CHARGING; + return 0; + } +#endif + + if (chg->fake_chg_status_on_debug_batt) { + rc = smblib_get_prop_from_bms(chg, + POWER_SUPPLY_PROP_DEBUG_BATTERY, &pval); + if (rc < 0) { + pr_err_ratelimited("Couldn't get debug battery prop rc=%d\n", + rc); + } else if (pval.intval == 1) { + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; return 0; } } @@ -2062,6 +2724,7 @@ int smblib_get_prop_batt_status(struct smb_charger *chg, stat = stat & BATTERY_CHARGER_STATUS_MASK; if (!usb_online && !dc_online) { +#ifndef CONFIG_MACH_XIAOMI_SM8150 switch (stat) { case TERMINATE_CHARGE: case INHIBIT_CHARGE: @@ -2071,9 +2734,47 @@ int smblib_get_prop_batt_status(struct smb_charger *chg, val->intval = POWER_SUPPLY_STATUS_DISCHARGING; break; } +#else + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; +#endif return rc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = smblib_get_prop_batt_health(chg, &pval); + if (rc < 0) + smblib_err(chg, "Couldn't get batt health rc=%d\n", rc); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + rc = smblib_get_prop_from_bms(chg, + POWER_SUPPLY_PROP_CAPACITY, &batt_capa); + if (rc < 0) + smblib_err(chg, "Couldn't read SOC value, rc=%d\n", rc); +#endif + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (get_client_vote_locked(chg->usb_icl_votable, JEITA_VOTER) == 0) { +#else + if ((get_client_vote_locked(chg->usb_icl_votable, JEITA_VOTER) == 0) || + (get_client_vote_locked(chg->dc_suspend_votable, JEITA_VOTER) == 1)) { +#endif + /* show charging when JEITA_VOTER 0mA is vote to improve user experience */ + if (pval.intval != POWER_SUPPLY_HEALTH_OVERHEAT + && pval.intval != POWER_SUPPLY_HEALTH_COLD) { + val->intval = POWER_SUPPLY_STATUS_CHARGING; + return 0; + } + } + +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + if (pval.intval == POWER_SUPPLY_HEALTH_OVERHEAT || + pval.intval == POWER_SUPPLY_HEALTH_COLD) { + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; + return 0; + } +#endif +#endif + switch (stat) { case TRICKLE_CHARGE: case PRE_CHARGE: @@ -2083,17 +2784,67 @@ int smblib_get_prop_batt_status(struct smb_charger *chg, break; case TERMINATE_CHARGE: case INHIBIT_CHARGE: +#ifndef CONFIG_MACH_XIAOMI_SM8150 val->intval = POWER_SUPPLY_STATUS_FULL; +#else + if (POWER_SUPPLY_HEALTH_WARM == pval.intval +#ifdef CONFIG_MACH_XIAOMI_VAYU + || batt_capa.intval <= 98 +#endif + || POWER_SUPPLY_HEALTH_OVERHEAT == pval.intval) + val->intval = POWER_SUPPLY_STATUS_CHARGING; + else { + val->intval = POWER_SUPPLY_STATUS_FULL; +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + chg->last_batt_stat = val->intval; +#endif + } +#endif break; case DISABLE_CHARGE: case PAUSE_CHARGE: +#ifndef CONFIG_MACH_XIAOMI_SM8150 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; +#else + /* + * As from jeita status change, there is very short time not charging, + * to improve user experience, we report charging at this moment. + */ + if (smblib_is_jeita_warm_charging(chg) +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + || smblib_wireless_to_usb_charging(chg, usb_online, dc_online) +#endif + ) + val->intval = POWER_SUPPLY_STATUS_CHARGING; + else + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; +#endif break; default: val->intval = POWER_SUPPLY_STATUS_UNKNOWN; break; } +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + if (!usb_online && chg->typec_mode != POWER_SUPPLY_TYPEC_SOURCE_HIGH + && dc_online && chg->fake_dc_on) { + /* + * fix insert wireless charger the logo will show twice. + * Also include wireless swith to pd charger, "wireless charger stop" issue. + */ + if (val->intval == POWER_SUPPLY_STATUS_CHARGING) + chg->fake_dc_on = 0; + else if (chg->last_batt_stat == POWER_SUPPLY_STATUS_FULL && + val->intval != POWER_SUPPLY_STATUS_CHARGING) { + val->intval = POWER_SUPPLY_STATUS_FULL; + chg->last_batt_stat = val->intval; + } + else if (val->intval != POWER_SUPPLY_STATUS_FULL) + val->intval = POWER_SUPPLY_STATUS_CHARGING; + return 0; + } +#endif + if (is_charging_paused(chg)) { val->intval = POWER_SUPPLY_STATUS_CHARGING; return 0; @@ -2109,15 +2860,29 @@ int smblib_get_prop_batt_status(struct smb_charger *chg, return 0; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + rc = smblib_get_prop_batt_health(chg, &pval); + if (rc < 0) + smblib_err(chg, "Couldn't get batt health rc=%d\n", rc); +#endif + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (val->intval != POWER_SUPPLY_STATUS_CHARGING || pval.intval == POWER_SUPPLY_HEALTH_WARM) +#else if (val->intval != POWER_SUPPLY_STATUS_CHARGING) +#endif return 0; if (!usb_online && dc_online && chg->fake_batt_status == POWER_SUPPLY_STATUS_FULL) { val->intval = POWER_SUPPLY_STATUS_FULL; +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + chg->last_batt_stat = val->intval; +#endif return 0; } +#ifndef CONFIG_MACH_XIAOMI_SM8150 rc = smblib_read(chg, BATTERY_CHARGER_STATUS_5_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read BATTERY_CHARGER_STATUS_2 rc=%d\n", @@ -2130,6 +2895,7 @@ int smblib_get_prop_batt_status(struct smb_charger *chg, if (!stat) val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; +#endif return 0; } @@ -2165,6 +2931,24 @@ int smblib_get_prop_batt_charge_type(struct smb_charger *chg, return rc; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static bool is_bq25970_available(struct smb_charger *chg) +{ + if (!chg->cp_psy) + chg->cp_psy = power_supply_get_by_name("bq2597x-standalone"); + +#ifdef CONFIG_MACH_XIAOMI_NABU + if (!chg->cp_psy) + chg->cp_psy = power_supply_get_by_name("ln8000"); +#endif + + if (!chg->cp_psy) + return false; + + return true; +} +#endif + int smblib_get_prop_batt_health(struct smb_charger *chg, union power_supply_propval *val) { @@ -2172,6 +2956,9 @@ int smblib_get_prop_batt_health(struct smb_charger *chg, int rc; int effective_fv_uv; u8 stat; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int over_voltage_thr_uv; +#endif rc = smblib_read(chg, BATTERY_CHARGER_STATUS_2_REG, &stat); if (rc < 0) { @@ -2183,6 +2970,13 @@ int smblib_get_prop_batt_health(struct smb_charger *chg, stat); if (stat & CHARGER_ERROR_STATUS_BAT_OV_BIT) { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump && is_bq25970_available(chg)) { + rc = power_supply_get_property(chg->cp_psy, + POWER_SUPPLY_PROP_TI_BATTERY_VOLTAGE, &pval); + pval.intval = pval.intval * 1000; + } else +#endif rc = smblib_get_prop_from_bms(chg, POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); if (!rc) { @@ -2190,8 +2984,30 @@ int smblib_get_prop_batt_health(struct smb_charger *chg, * If Vbatt is within 40mV above Vfloat, then don't * treat it as overvoltage. */ +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + effective_fv_uv = get_effective_result_locked(chg->fv_votable); + /* + * as six pin battery vbat is much higher than cell voltage + * we should add more buffer to over voltage threshold + * to report over voltage health + */ + if (chg->six_pin_step_charge_enable) { + if (effective_fv_uv == WARM_VFLOAT_UV) + over_voltage_thr_uv = effective_fv_uv + 80000; + else + over_voltage_thr_uv = chg->batt_profile_fv_uv + 50000; + } else { + over_voltage_thr_uv = effective_fv_uv + 40000; + } + if (pval.intval >= over_voltage_thr_uv) { +#else +#ifdef CONFIG_MACH_XIAOMI_SM8150 + effective_fv_uv = get_effective_result_locked(chg->fv_votable); +#else effective_fv_uv = get_effective_result(chg->fv_votable); +#endif if (pval.intval >= effective_fv_uv + 40000) { +#endif val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; smblib_err(chg, "battery over-voltage vbat_fg = %duV, fv = %duV\n", pval.intval, effective_fv_uv); @@ -2235,6 +3051,15 @@ int smblib_get_prop_system_temp_level_max(struct smb_charger *chg, return 0; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int smblib_get_prop_dc_temp_level(struct smb_charger *chg, + union power_supply_propval *val) +{ + val->intval = chg->dc_temp_level; + return 0; +} +#endif + int smblib_get_prop_input_current_limited(struct smb_charger *chg, union power_supply_propval *val) { @@ -2301,11 +3126,33 @@ int smblib_get_prop_batt_iterm(struct smb_charger *chg, return rc; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static int smblib_set_wdog_bark_timer(struct smb_charger *chg, + int wdog_timer) +{ + u8 val = 0; + int rc; + + val = (ilog2(wdog_timer / 16) << BARK_WDOG_TIMEOUT_SHIFT) + & BARK_WDOG_TIMEOUT_MASK; + rc = smblib_masked_write(chg, SNARL_BARK_BITE_WD_CFG_REG, + BARK_WDOG_TIMEOUT_MASK, val); + if (rc < 0) { + pr_err("Couldn't configue WD config rc=%d\n", rc); + return rc; + } + return rc; +} +#endif + int smblib_get_prop_batt_charge_done(struct smb_charger *chg, union power_supply_propval *val) { int rc; u8 stat; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + union power_supply_propval pval = {0, }; +#endif rc = smblib_read(chg, BATTERY_CHARGER_STATUS_1_REG, &stat); if (rc < 0) { @@ -2316,9 +3163,153 @@ int smblib_get_prop_batt_charge_done(struct smb_charger *chg, stat = stat & BATTERY_CHARGER_STATUS_MASK; val->intval = (stat == TERMINATE_CHARGE); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + rc = smblib_get_prop_batt_capacity(chg, &pval); + if (rc < 0) + smblib_err(chg, "Couldn't get batt capacity rc=%d\n", rc); + + /* if charge is done, clear CHG_AWAKE_VOTER */ + if (val->intval == 1 && pval.intval >= 95) { + /* when charge done, set bark timer to 128s to decrease wakeups */ + smblib_set_wdog_bark_timer(chg, BARK_TIMER_LONG); + /*disable FFC when charge done*/ + if (chg->support_ffc) { + if (smblib_get_fastcharge_mode(chg) == 1) + rc = smblib_set_fastcharge_mode(chg, false); + } + vote(chg->awake_votable, CHG_AWAKE_VOTER, false, 0); + } +#elif defined(CONFIG_MACH_XIAOMI_SM8150) + if (val->intval == 1) { + vote(chg->awake_votable, CHG_AWAKE_VOTER, false, 0); + vote(chg->awake_votable, DC_AWAKE_VOTER, false, 0); + } +#endif + + return 0; +} + +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int smblib_get_prop_liquid_status(struct smb_charger *chg, + union power_supply_propval *val) +{ + /* + * as qcom liquid detection have a bug that when connect a A to C + * to Type-C port, but A port of cable plug is float, liquid detection + * will be triggered, it is same with real liquid detection action + * so we do not report lpd_status true to UI side, we will check later. + */ + val->intval = 0; + + if (chg->lpd_status) { + val->intval = 1; + pr_info("liquid status is true\n"); + } else { + val->intval = 0; + pr_info("liquid status is false\n"); + } + return 0; +} + +#define HW_ER_RATIO 2 +#define RF_ADC 1875 + +bool smblib_support_liquid_feature(struct smb_charger *chg) +{ + int hw_version; + int rc, i, data; + int error_value = RF_ADC*HW_ER_RATIO/100; + + if (chg->lpd_enabled == true) { + if (chg->init_once == false) { + rc = smblib_read_iio_channel(chg, chg->iio.hw_version_gpio5, + DIV_FACTOR_MILI_V_I, &hw_version); + if (rc < 0) { + smblib_err(chg, "Couldn't read hw_version_gpio5, rc = %d\n", rc); + return rc; + } else { + smblib_err(chg, "hw_version_gpio5 ADC = %d\n", hw_version); + } + + chg->init_once = true; + + for (i = 0; i < chg->lpd_levels; i++) { + data = (chg->lpd_hwversion[i] * 100) / (100000 + chg->lpd_hwversion[i]); + if (abs(RF_ADC * data / 100 - hw_version) < error_value) { + chg->support_liquid = true; + break; + } + } + } + } + + smblib_err(chg, "support_liquid is %d\n", chg->support_liquid); + return chg->support_liquid; +} + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smblib_get_prop_battery_charging_enabled(struct smb_charger *chg, + union power_supply_propval *val) +{ + val->intval = !(get_client_vote(chg->usb_icl_votable, MAIN_CHG_VOTER) + == MAIN_CHARGER_STOP_ICL); + return 0; +} + +int smblib_get_prop_battery_charging_limited(struct smb_charger *chg, + union power_supply_propval *val) +{ + if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) + val->intval = (get_client_vote(chg->usb_icl_votable, MAIN_CHG_VOTER) + == QC3_CHARGER_ICL); + else if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) + val->intval = (get_client_vote(chg->usb_icl_votable, MAIN_CHG_VOTER) + == QC3P5_CHARGER_ICL); + else + val->intval = (get_client_vote(chg->usb_icl_votable, MAIN_CHG_VOTER) + == MAIN_CHARGER_ICL); + return 0; +} + +int smblib_get_prop_battery_slowly_charging(struct smb_charger *chg, + union power_supply_propval *val) +{ + val->intval = chg->slowly_charging; + return 0; +} + +int smblib_set_prop_battery_slowly_charging(struct smb_charger *chg, + const union power_supply_propval *val) +{ + if (val->intval ^ chg->slowly_charging) { + if (val->intval) { + vote(chg->fcc_votable, SLOWLY_CHARGING_VOTER, + true, SLOWLY_CHARGING_CURRENT); + } else { + + vote(chg->fcc_votable, SLOWLY_CHARGING_VOTER, false, 0); + } + chg->slowly_charging = (bool)val->intval; + rerun_election(chg->fcc_votable); + pr_info("slowly charging enabled[%d]\n", val->intval); + } + + return 0; +} + +int smblib_get_prop_battery_bq_input_suspend(struct smb_charger *chg, + union power_supply_propval *val) +{ + val->intval = chg->bq_input_suspend; return 0; } +#define HW_ER_RATIO 2 +#define RF_ADC 1875 +#endif +#endif + /*********************** * BATTERY PSY SETTERS * ***********************/ @@ -2343,6 +3334,11 @@ int smblib_set_prop_input_suspend(struct smb_charger *chg, return rc; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump) + chg->bq_input_suspend = !!(val->intval); +#endif + power_supply_changed(chg->batt_psy); return rc; } @@ -2350,8 +3346,23 @@ int smblib_set_prop_input_suspend(struct smb_charger *chg, int smblib_set_prop_batt_capacity(struct smb_charger *chg, const union power_supply_propval *val) { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + union power_supply_propval shutdown_delay_en = {0, }; + /* only enable write reasonable soc value */ + if (val->intval < 0) + chg->fake_capacity = 0; + else if (val->intval > 100) + chg->fake_capacity = 100; + else +#endif chg->fake_capacity = val->intval; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + power_supply_set_property(chg->bms_psy, + POWER_SUPPLY_PROP_SHUTDOWN_DELAY_ENABLE, + &shutdown_delay_en); +#endif + power_supply_changed(chg->batt_psy); return 0; @@ -2371,35 +3382,447 @@ int smblib_set_prop_batt_status(struct smb_charger *chg, return 0; } -int smblib_set_prop_system_temp_level(struct smb_charger *chg, - const union power_supply_propval *val) +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#ifdef CONFIG_MACH_XIAOMI_NABU +int smblib_get_prop_wireless_version(struct smb_charger *chg, + union power_supply_propval *val) { - if (val->intval < 0) - return -EINVAL; - - if (chg->thermal_levels <= 0) - return -EINVAL; - - if (val->intval > chg->thermal_levels) - return -EINVAL; - - chg->system_temp_level = val->intval; - - if (chg->system_temp_level == chg->thermal_levels) - return vote(chg->chg_disable_votable, - THERMAL_DAEMON_VOTER, true, 0); + int rc; - vote(chg->chg_disable_votable, THERMAL_DAEMON_VOTER, false, 0); - if (chg->system_temp_level == 0) - return vote(chg->fcc_votable, THERMAL_DAEMON_VOTER, false, 0); + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) { + chg->wls_chip_psy = chg->idtp_psy; + } else { + chg->wip_psy = power_supply_get_by_name("rx1619"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } - vote(chg->fcc_votable, THERMAL_DAEMON_VOTER, true, - chg->thermal_mitigation[chg->system_temp_level]); - return 0; + if (chg->wls_chip_psy) + rc = power_supply_get_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_WIRELESS_VERSION, val); + return rc; } -int smblib_set_prop_input_current_limited(struct smb_charger *chg, - const union power_supply_propval *val) +int smblib_get_prop_wireless_fw_version(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc; + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) { + chg->wls_chip_psy = chg->idtp_psy; + } else { + chg->wip_psy = power_supply_get_by_name("rx1619"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + if (chg->wls_chip_psy) + rc = power_supply_get_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_WIRELESS_FW_VERSION, val); + return rc; +} +#endif + +#define ADAPTER_NONE 0x00 +#define ADAPTER_SDP 0x01 +#define ADAPTER_CDP 0x02 +#define ADAPTER_DCP 0x03 +#define ADAPTER_QC2 0x05 +#define ADAPTER_QC3 0x06 +#define ADAPTER_PD 0x07 +#define ADAPTER_AUTH_FAILED 0x08 +#define ADAPTER_XIAOMI_QC3 0x09 +#define ADAPTER_XIAOMI_PD 0x0a +#define ADAPTER_ZIMI_CAR_POWER 0x0b +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define ADAPTER_XIAOMI_PD_40W 0x0c +#define ADAPTER_VOICE_BOX 0x0d +#define ADAPTER_XIAOMI_PD_50W 0x0e +#endif + +static int smblib_dc_therm_charging(struct smb_charger *chg, + int temp_level) +{ + int thermal_icl_ua = 0; + int rc; + union power_supply_propval pval = {0, }; + union power_supply_propval val = {0, }; + + if (!chg->wls_psy) { + chg->wls_psy = power_supply_get_by_name("wireless"); + if (!chg->wls_psy) + return -ENODEV; + } + rc = power_supply_get_property(chg->wls_psy, + POWER_SUPPLY_PROP_TX_ADAPTER, + &pval); + + rc = power_supply_get_property(chg->wls_psy, + POWER_SUPPLY_PROP_WIRELESS_VERSION, + &val); + switch (pval.intval) { + case ADAPTER_XIAOMI_QC3: + case ADAPTER_ZIMI_CAR_POWER: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case ADAPTER_XIAOMI_PD_40W: + case ADAPTER_XIAOMI_PD_50W: + case ADAPTER_VOICE_BOX: +#endif + thermal_icl_ua = chg->thermal_mitigation_dc[temp_level]; + break; + case ADAPTER_QC2: + thermal_icl_ua = chg->thermal_mitigation_bpp_qc2[temp_level]; + break; + case ADAPTER_QC3: + if (val.intval == 1)/*is epp*/ + thermal_icl_ua = chg->thermal_mitigation_epp[temp_level]; + else + thermal_icl_ua = chg->thermal_mitigation_bpp_qc3[temp_level]; + break; + case ADAPTER_XIAOMI_PD: + case ADAPTER_PD: + if (val.intval == 1)/*is epp*/ + thermal_icl_ua = chg->thermal_mitigation_epp[temp_level]; + else + thermal_icl_ua = chg->thermal_mitigation_bpp[temp_level]; + break; + case ADAPTER_AUTH_FAILED: + if (val.intval == 1)/*is epp*/ + thermal_icl_ua = chg->thermal_mitigation_epp[temp_level]; + else + thermal_icl_ua = chg->thermal_mitigation_bpp[temp_level]; + break; + case ADAPTER_CDP: + case ADAPTER_DCP: + thermal_icl_ua = chg->thermal_mitigation_bpp[temp_level]; + break; + default: + thermal_icl_ua = chg->thermal_mitigation_bpp[temp_level]; + break; + } + vote(chg->dc_icl_votable, THERMAL_DAEMON_VOTER, true, thermal_icl_ua); + + return rc; +} + +int smblib_set_prop_dc_temp_level(struct smb_charger *chg, + const union power_supply_propval *val) +{ + union power_supply_propval dc_present; + union power_supply_propval batt_temp; + int rc; + + rc = smblib_get_prop_dc_present(chg, &dc_present); + if (rc < 0) { + pr_err("Couldn't get dc present rc=%d\n", rc); + return -EINVAL; + } + + rc = smblib_get_prop_from_bms(chg, + POWER_SUPPLY_PROP_TEMP, &batt_temp); + if (rc < 0) { + pr_err("Couldn't get batt temp rc=%d\n", rc); + return -EINVAL; + } + + if (val->intval < 0) + return -EINVAL; + if (chg->dc_thermal_levels <= 0) + return -EINVAL; + if (val->intval > chg->dc_thermal_levels) + return -EINVAL; + chg->dc_temp_level = val->intval; + + if (chg->dc_temp_level == chg->dc_thermal_levels) + return vote(chg->chg_disable_votable, + THERMAL_DAEMON_VOTER, true, 0); + + vote(chg->chg_disable_votable, THERMAL_DAEMON_VOTER, false, 0); + if (chg->dc_temp_level == 0) + return vote(chg->dc_icl_votable, THERMAL_DAEMON_VOTER, false, 0); + + smblib_dc_therm_charging(chg, val->intval); + + return 0; +} + +static int smblib_therm_charging(struct smb_charger *chg) +{ + int thermal_icl_ua = 0; + int thermal_fcc_ua = 0; + int rc; + + if (chg->system_temp_level >= MAX_TEMP_LEVEL) + return 0; + + switch (chg->real_charger_type) { + case POWER_SUPPLY_TYPE_USB_HVDCP: + thermal_icl_ua = chg->thermal_mitigation_qc2[chg->system_temp_level]; + break; + case POWER_SUPPLY_TYPE_USB_HVDCP_3: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump) { + thermal_fcc_ua = + chg->thermal_fcc_qc3_cp[chg->system_temp_level]; + } else { +#endif + if (chg->cp_reason == POWER_SUPPLY_CP_HVDCP3) { + if (chg->is_qc_class_a) + thermal_fcc_ua = + chg->thermal_fcc_qc3_cp[chg->system_temp_level]; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + else if (chg->temp_27W_enable) + thermal_fcc_ua = + chg->thermal_fcc_qc3_classb_cp[chg->system_temp_level]; +#endif + else + thermal_fcc_ua = +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->thermal_fcc_qc3_cp[chg->system_temp_level]; +#else + chg->thermal_fcc_qc3_classb_cp[chg->system_temp_level]; +#endif + } else { + thermal_fcc_ua = + chg->thermal_fcc_qc3_normal[chg->system_temp_level]; + } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + } +#endif + break; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case POWER_SUPPLY_TYPE_USB_HVDCP_3P5: + thermal_fcc_ua = + chg->thermal_fcc_qc3_cp[chg->system_temp_level]; + break; +#endif + case POWER_SUPPLY_TYPE_USB_PD: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump) { + if (chg->pps_thermal_level < 0) + chg->pps_thermal_level = chg->system_temp_level; + pr_err("chg->pps_thermal_level=%d,chg->system_temp_level=%d\n", chg->pps_thermal_level, chg->system_temp_level); + thermal_fcc_ua = + chg->thermal_fcc_pps_cp[chg->pps_thermal_level]; + } else { +#endif + if (chg->cp_reason == POWER_SUPPLY_CP_PPS) { + thermal_fcc_ua = + chg->thermal_fcc_pps_cp[chg->system_temp_level]; + } else { + if (chg->voltage_min_uv >= PD_MICRO_5V + && chg->voltage_min_uv < PD_MICRO_5P9V) + thermal_icl_ua = + chg->thermal_mitigation_pd_base[chg->system_temp_level]; + else if (chg->voltage_min_uv >= PD_MICRO_5P9V + && chg->voltage_min_uv < PD_MICRO_6P5V) + thermal_icl_ua = + chg->thermal_mitigation_pd_base[chg->system_temp_level] + * PD_6P5V_PERCENT / 100; + else if (chg->voltage_min_uv >= PD_MICRO_6P5V + && chg->voltage_min_uv < PD_MICRO_7P5V) + thermal_icl_ua = + chg->thermal_mitigation_pd_base[chg->system_temp_level] + * PD_7P5V_PERCENT / 100; + else if (chg->voltage_min_uv >= PD_MICRO_7P5V + && chg->voltage_min_uv <= PD_MICRO_8P5V) + thermal_icl_ua = + chg->thermal_mitigation_pd_base[chg->system_temp_level] + * PD_8P5V_PERCENT / 100; + else if (chg->voltage_min_uv >= PD_MICRO_8P5V) + thermal_icl_ua = + chg->thermal_mitigation_pd_base[chg->system_temp_level] + * PD_9V_PERCENT / 100; + else + thermal_icl_ua = + chg->thermal_mitigation_pd_base[chg->system_temp_level]; + } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + } +#endif + break; + case POWER_SUPPLY_TYPE_USB_DCP: + default: + thermal_icl_ua = chg->thermal_mitigation_dcp[chg->system_temp_level]; + break; + } + + if (chg->system_temp_level == 0) { + /* if therm_lvl_sel is 0, clear thermal voter */ + rc = vote(chg->usb_icl_votable, THERMAL_DAEMON_VOTER, false, 0); + if (rc < 0) + pr_err("Couldn't disable USB thermal ICL vote rc=%d\n", + rc); + rc = vote(chg->fcc_votable, THERMAL_DAEMON_VOTER, false, 0); + if (rc < 0) + pr_err("Couldn't disable USB thermal ICL vote rc=%d\n", + rc); + } else { + pr_info("thermal_icl_ua is %d, chg->system_temp_level: %d\n", + thermal_icl_ua, chg->system_temp_level); + pr_info("thermal_fcc_ua is %d\n", thermal_fcc_ua); + + if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + || chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5 + || ((chg->cp_reason == POWER_SUPPLY_CP_PPS || chg->use_bq_pump) +#else + || (chg->cp_reason == POWER_SUPPLY_CP_PPS +#endif + && chg->real_charger_type == POWER_SUPPLY_TYPE_USB_PD)) { + /* if use qc3 or pps charge with cp, also limit icl when high level */ + if (chg->system_temp_level >= ICL_LIMIT_LEVEL_THR) + thermal_icl_ua = + chg->thermal_mitigation_icl[chg->system_temp_level]; + if (chg->system_temp_level >= ICL_LIMIT_LEVEL_THR) { + rc = vote(chg->usb_icl_votable, THERMAL_DAEMON_VOTER, + true, thermal_icl_ua); + if (rc < 0) + pr_err("Couldn't enable USB thermal ICL vote rc=%d\n", + rc); + } else { + /* + * if use qc3 or pps charge with cp, reset it when level decrease + * below level threshold(such as level 9) + */ + rc = vote(chg->usb_icl_votable, THERMAL_DAEMON_VOTER, + false, 0); + if (rc < 0) + pr_err("Couldn't disable USB thermal ICL vote rc=%d\n", + rc); + } + } else { + if (thermal_icl_ua > 0) { + rc = vote(chg->usb_icl_votable, THERMAL_DAEMON_VOTER, true, + thermal_icl_ua); + if (rc < 0) + pr_err("Couldn't enable USB thermal ICL vote rc=%d\n", + rc); + } + } + if (thermal_fcc_ua > 0) { + rc = vote(chg->fcc_votable, THERMAL_DAEMON_VOTER, true, + thermal_fcc_ua); + if (rc < 0) + pr_err("Couldn't enable USB thermal ICL vote rc=%d\n", + rc); + } + } + + return rc; +} + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static void smblib_thermal_setting_work(struct work_struct *work) +{ + struct smb_charger *chg = container_of(work, struct smb_charger, + thermal_setting_work.work); + + if (chg->pps_thermal_level > chg->system_temp_level) { + if (chg->pps_thermal_level - chg->system_temp_level >= 2) + chg->pps_thermal_level -= 2; + else + chg->pps_thermal_level -= 1; + } else if (chg->pps_thermal_level < chg->system_temp_level) { + if (chg->system_temp_level - chg->pps_thermal_level >= 2) + chg->pps_thermal_level += 2; + else + chg->pps_thermal_level += 1; + } + + smblib_therm_charging(chg); + + if (chg->pps_thermal_level != chg->system_temp_level) + schedule_delayed_work(&chg->thermal_setting_work, 3 * HZ); +} +#endif +#endif + +int smblib_set_prop_system_temp_level(struct smb_charger *chg, + const union power_supply_propval *val) +{ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int rc; + union power_supply_propval batt_temp = {0, }; +#endif + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = smblib_get_prop_from_bms(chg, + POWER_SUPPLY_PROP_TEMP, &batt_temp); + if (rc < 0) { + pr_err("Couldn't get batt temp rc=%d\n", rc); + return -EINVAL; + } +#endif + + if (val->intval < 0) + return -EINVAL; + + if (chg->thermal_levels <= 0) + return -EINVAL; + + if (val->intval > chg->thermal_levels) + return -EINVAL; + + chg->system_temp_level = val->intval; + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (!chg->use_bq_pump) { + if (chg->system_temp_level >= (chg->thermal_levels - 1)) { + if (!chg->cp_disable_votable) + chg->cp_disable_votable = find_votable("CP_DISABLE"); + if (chg->cp_disable_votable) + vote(chg->cp_disable_votable, THERMAL_DAEMON_VOTER, true, 0); + + return vote(chg->chg_disable_votable, + THERMAL_DAEMON_VOTER, true, 0); + } + } +#elif defined(CONFIG_MACH_XIAOMI_SM8150) + if (chg->system_temp_level >= (chg->thermal_levels - 1)) + return vote(chg->chg_disable_votable, + THERMAL_DAEMON_VOTER, true, 0); +#else + if (chg->system_temp_level == chg->thermal_levels) + return vote(chg->chg_disable_votable, + THERMAL_DAEMON_VOTER, true, 0); +#endif + + vote(chg->chg_disable_votable, THERMAL_DAEMON_VOTER, false, 0); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (!chg->use_bq_pump && chg->cp_disable_votable) + vote(chg->cp_disable_votable, THERMAL_DAEMON_VOTER, false, 0); + + if (chg->use_bq_pump + && chg->real_charger_type == POWER_SUPPLY_TYPE_USB_PD) { + if (chg->pps_fcc_therm_work_disabled) { + chg->pps_thermal_level = chg->system_temp_level; + smblib_therm_charging(chg); + } else + schedule_delayed_work(&chg->thermal_setting_work, 3 * HZ); + } else + smblib_therm_charging(chg); +#elif defined(CONFIG_MACH_XIAOMI_SM8150) + smblib_therm_charging(chg); +#else + if (chg->system_temp_level == 0) + return vote(chg->fcc_votable, THERMAL_DAEMON_VOTER, false, 0); + + vote(chg->fcc_votable, THERMAL_DAEMON_VOTER, true, + chg->thermal_mitigation[chg->system_temp_level]); +#endif + + return 0; +} + +int smblib_set_prop_input_current_limited(struct smb_charger *chg, + const union power_supply_propval *val) { chg->fake_input_current_limited = val->intval; return 0; @@ -2411,6 +3834,15 @@ int smblib_set_prop_rechg_soc_thresh(struct smb_charger *chg, int rc; u8 new_thr = DIV_ROUND_CLOSEST(val->intval * 255, 100); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* + * As DIV_ROUND_CLOSEST cal cause new_thr to 252, we add 1 more to + * improve recharging UI soc still to 100% to improve user experience. + */ + if (val->intval == RECHARGE_SOC_THR) + new_thr += 1; +#endif + rc = smblib_write(chg, CHARGE_RCHG_SOC_THRESHOLD_CFG_REG, new_thr); if (rc < 0) { @@ -2547,6 +3979,13 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg) u8 stat; if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (chg->qc2_unsupported) { + smblib_hvdcp_set_fsw(chg, QC_5V_BIT); + power_supply_changed(chg->usb_main_psy); + return; + } +#endif rc = smblib_read(chg, QC_CHANGE_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, @@ -2574,8 +4013,30 @@ int smblib_dp_dm(struct smb_charger *chg, int val) union power_supply_propval pval; u8 stat; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump) { + pr_info("dp_dm is controled by our self\n"); + return rc; + } +#endif + + /* if raise_vbus work is running, ignore dp_dm pulses */ + if (chg->raise_vbus_to_detect) + return rc; +#endif + switch (val) { case POWER_SUPPLY_DP_DM_DP_PULSE: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* + * if hvdcp_opti wrongly send more than 30 dp pulse(11V) to smb5, + * ignore them to allow maxium vbus as 11V, as charge pump do not + * need the vin more than 11V, and protect the device. + */ + if (chg->pulse_cnt > MAX_PLUSE_COUNT_ALLOWED) + return rc; +#endif /* * Pre-emptively increment pulse count to enable the setting * of FSW prior to increasing voltage. @@ -2599,6 +4060,21 @@ int smblib_dp_dm(struct smb_charger *chg, int val) smblib_dbg(chg, PR_PARALLEL, "DP_DM_DP_PULSE rc=%d cnt=%d\n", rc, chg->pulse_cnt); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* + * if use class_a qc, and slave ic is charge pump, should limit + * maxium icl to 1.9A, as VBUS will raise to about 9V to 9.8V, + * so we set icl to 1.9A when vbus raise above 7.4V + */ + if (chg->is_qc_class_a && chg->sec_cp_present) { + if (chg->pulse_cnt >= HIGH_NUM_PULSE_THR + && !chg->high_vbus_detected) { + vote(chg->usb_icl_votable, QC_A_CP_ICL_MAX_VOTER, true, + HVDCP_CLASS_A_FOR_CP_UA); + chg->high_vbus_detected = true; + } + } +#endif break; case POWER_SUPPLY_DP_DM_DM_PULSE: rc = smblib_dm_pulse(chg); @@ -2606,6 +4082,20 @@ int smblib_dp_dm(struct smb_charger *chg, int val) chg->pulse_cnt--; smblib_dbg(chg, PR_PARALLEL, "DP_DM_DM_PULSE rc=%d cnt=%d\n", rc, chg->pulse_cnt); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* + * if use class_a qc, and slave ic is charge pump, should restore + * icl to 2.4A when charge pump is not working for class_a qc + */ + if (chg->is_qc_class_a && chg->sec_cp_present) { + if (chg->pulse_cnt < HIGH_NUM_PULSE_THR + && chg->high_vbus_detected) { + vote(chg->usb_icl_votable, QC_A_CP_ICL_MAX_VOTER, false, + 0); + chg->high_vbus_detected = false; + } + } +#endif break; case POWER_SUPPLY_DP_DM_ICL_DOWN: target_icl_ua = get_effective_result(chg->usb_icl_votable); @@ -2639,10 +4129,21 @@ int smblib_dp_dm(struct smb_charger *chg, int val) break; case POWER_SUPPLY_DP_DM_FORCE_5V: rc = smblib_force_vbus_voltage(chg, FORCE_5V_BIT); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->pulse_cnt = 0; +#endif if (rc < 0) pr_err("Failed to force 5V\n"); break; case POWER_SUPPLY_DP_DM_FORCE_9V: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* we use our own qc2 method to raise to 9V, so just return here */ + return 0; + + if (chg->qc2_unsupported) + return 0; +#endif + if (chg->qc2_unsupported_voltage == QC2_NON_COMPLIANT_9V) { smblib_err(chg, "Couldn't set 9V: unsupported\n"); return -EINVAL; @@ -2666,8 +4167,20 @@ int smblib_dp_dm(struct smb_charger *chg, int val) rc = smblib_force_vbus_voltage(chg, FORCE_9V_BIT); if (rc < 0) pr_err("Failed to force 9V\n"); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, + HVDCP2_CURRENT_UA); +#endif break; case POWER_SUPPLY_DP_DM_FORCE_12V: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* we use our own qc2 method to raise to 9V, so just return here */ + return 0; + + if (chg->qc2_unsupported) + return 0; +#endif + if (chg->qc2_unsupported_voltage == QC2_NON_COMPLIANT_12V) { smblib_err(chg, "Couldn't set 12V: unsupported\n"); return -EINVAL; @@ -2691,6 +4204,10 @@ int smblib_dp_dm(struct smb_charger *chg, int val) rc = smblib_force_vbus_voltage(chg, FORCE_12V_BIT); if (rc < 0) pr_err("Failed to force 12V\n"); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, + HVDCP2_CURRENT_UA); +#endif break; case POWER_SUPPLY_DP_DM_CONFIRMED_HVDCP3P5: chg->qc3p5_detected = true; @@ -2704,65 +4221,231 @@ int smblib_dp_dm(struct smb_charger *chg, int val) return rc; } -int smblib_disable_hw_jeita(struct smb_charger *chg, bool disable) -{ - int rc; - u8 mask; - - /* - * Disable h/w base JEITA compensation if s/w JEITA is enabled - */ - mask = JEITA_EN_COLD_SL_FCV_BIT - | JEITA_EN_HOT_SL_FCV_BIT - | JEITA_EN_HOT_SL_CCC_BIT - | JEITA_EN_COLD_SL_CCC_BIT, - rc = smblib_masked_write(chg, JEITA_EN_CFG_REG, mask, - disable ? 0 : mask); - if (rc < 0) { - dev_err(chg->dev, "Couldn't configure s/w jeita rc=%d\n", - rc); - return rc; - } - - return 0; -} - -static int smblib_set_sw_thermal_regulation(struct smb_charger *chg, - bool enable) +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smblib_dp_dm_bq(struct smb_charger *chg, int val) { int rc = 0; +#ifdef CONFIG_MACH_XIAOMI_NABU + int qc3p5_dp_cnt = 0; +#endif - if (!(chg->wa_flags & SW_THERM_REGULATION_WA)) + /* if raise_vbus work is running, ignore dp_dm pulses */ + if (chg->raise_vbus_to_detect) return rc; - if (enable) { + switch (val) { + case POWER_SUPPLY_DP_DM_DP_PULSE: /* - * Configure min time to quickly address thermal - * condition. + * if hvdcp_opti wrongly send more than 30 dp pulse(11V) to smb5, + * ignore them to allow maxium vbus as 11V, as charge pump do not + * need the vin more than 11V, and protect the device. */ - rc = smblib_masked_write(chg, SNARL_BARK_BITE_WD_CFG_REG, - SNARL_WDOG_TIMEOUT_MASK, SNARL_WDOG_TMOUT_62P5MS); - if (rc < 0) { - smblib_err(chg, "Couldn't configure snarl wdog tmout, rc=%d\n", - rc); + if (chg->pulse_cnt > MAX_PLUSE_COUNT_ALLOWED +#ifdef CONFIG_MACH_XIAOMI_NABU + && chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3 +#endif + ) { return rc; +#ifdef CONFIG_MACH_XIAOMI_NABU + } else if (chg->qc3p5_supported + && chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) { + if (chg->pulse_cnt > MAX_QC3P5_PLUSE_COUNT_ALLOWED) + return rc; + else if (chg->pulse_cnt >= QC3P5_DP_RAPIDLY_TUNE_ALLOWED) + chg->qc3p5_dp_tune_rapidly = false; + else + chg->qc3p5_dp_tune_rapidly = true; +#endif } /* - * Schedule SW_THERM_REGULATION_WORK directly if USB input - * is suspended due to SW thermal regulation WA since WDOG - * IRQ won't trigger with input suspended. + * Pre-emptively increment pulse count to enable the setting + * of FSW prior to increasing voltage. */ - if (is_client_vote_enabled(chg->usb_icl_votable, - SW_THERM_REGULATION_VOTER)) { - vote(chg->awake_votable, SW_THERM_REGULATION_VOTER, - true, 0); - schedule_delayed_work(&chg->thermal_regulation_work, 0); - } - } else { - cancel_delayed_work_sync(&chg->thermal_regulation_work); - vote(chg->awake_votable, SW_THERM_REGULATION_VOTER, false, 0); - } +#ifdef CONFIG_MACH_XIAOMI_NABU + if (chg->qc3p5_dp_tune_rapidly) + chg->pulse_cnt += QC3P5_DP_RAPIDLY_TUNE_PULSE; + else + chg->pulse_cnt++; +#else + chg->pulse_cnt++; +#endif + + rc = smblib_hvdcp3_set_fsw(chg); + if (rc < 0) + smblib_err(chg, "Couldn't set QC3.0 Fsw rc=%d\n", rc); + +#ifdef CONFIG_MACH_XIAOMI_NABU + if (chg->qc3p5_dp_tune_rapidly) { + for (qc3p5_dp_cnt = 1; qc3p5_dp_cnt <= QC3P5_DP_RAPIDLY_TUNE_PULSE; qc3p5_dp_cnt++) { + rc = smblib_dp_pulse(chg); + if (rc < 0) { + smblib_err(chg, "Couldn't increase pulse count rc=%d\n", rc); + chg->pulse_cnt--; + } + smblib_dbg(chg, PR_PARALLEL, "DP_DM_DP_PULSE rapidly rc=%d cnt=%d\n", + rc, chg->pulse_cnt - QC3P5_DP_RAPIDLY_TUNE_PULSE + qc3p5_dp_cnt); + usleep_range(8000, 8010); // delay 8ms + } + } else { +#endif + rc = smblib_dp_pulse(chg); + if (rc < 0) { + smblib_err(chg, "Couldn't increase pulse count rc=%d\n", + rc); + /* + * Increment pulse count failed; + * reset to former value. + */ + chg->pulse_cnt--; + } +#ifdef CONFIG_MACH_XIAOMI_NABU + } +#endif + + smblib_dbg(chg, PR_PARALLEL, "DP_DM_DP_PULSE rc=%d cnt=%d\n", + rc, chg->pulse_cnt); + /* + * if use class_a qc, and slave ic is charge pump, should limit + * maxium icl to 1.9A, as VBUS will raise to about 9V to 9.8V, + * so we set icl to 1.9A when vbus raise above 7.4V + */ + if (chg->is_qc_class_a && chg->sec_cp_present) { + if (chg->pulse_cnt >= HIGH_NUM_PULSE_THR + && !chg->high_vbus_detected) { + vote(chg->usb_icl_votable, QC_A_CP_ICL_MAX_VOTER, true, + HVDCP_CLASS_A_FOR_CP_UA); + chg->high_vbus_detected = true; + } + } + break; + + case POWER_SUPPLY_DP_DM_DM_PULSE: + rc = smblib_dm_pulse(chg); + if (!rc && chg->pulse_cnt) + chg->pulse_cnt--; + smblib_dbg(chg, PR_PARALLEL, "DP_DM_DM_PULSE rc=%d cnt=%d\n", + rc, chg->pulse_cnt); + /* + * if use class_a qc, and slave ic is charge pump, should restore + * icl to 2.4A when charge pump is not working for class_a qc + */ + if (chg->is_qc_class_a && chg->use_bq_pump) { + if (chg->pulse_cnt < HIGH_NUM_PULSE_THR + && chg->high_vbus_detected) { + vote(chg->usb_icl_votable, QC_A_CP_ICL_MAX_VOTER, false, + 0); + chg->high_vbus_detected = false; + } + } + break; + + case POWER_SUPPLY_DP_DM_FORCE_5V: + rc = smblib_force_vbus_voltage(chg, FORCE_5V_BIT); + chg->pulse_cnt = 0; + if (rc < 0) + pr_err("Failed to force 5V\n"); + break; + + default: + break; + } + + return rc; +} +#endif + +int smblib_disable_hw_jeita(struct smb_charger *chg, bool disable) +{ + int rc; + u8 mask; + + /* + * Disable h/w base JEITA compensation if s/w JEITA is enabled + */ + mask = JEITA_EN_COLD_SL_FCV_BIT + | JEITA_EN_HOT_SL_FCV_BIT + | JEITA_EN_HOT_SL_CCC_BIT + | JEITA_EN_COLD_SL_CCC_BIT, + rc = smblib_masked_write(chg, JEITA_EN_CFG_REG, mask, + disable ? 0 : mask); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure s/w jeita rc=%d\n", + rc); + return rc; + } + + return 0; +} + +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) +int smblib_get_prop_wireless_version(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc; + +/* + if (!chg->idtp_psy) { + chg->idtp_psy = power_supply_get_by_name("idt"); + if (!chg->idtp_psy) + return -EINVAL; + } +*/ + + chg->idtp_psy = power_supply_get_by_name("idt"); + if (chg->idtp_psy) + chg->wls_chip_psy = chg->idtp_psy; + else { + chg->wip_psy = power_supply_get_by_name("rx1618"); + if (chg->wip_psy) + chg->wls_chip_psy = chg->wip_psy; + else + return -EINVAL; + } + + if (chg->wls_chip_psy) + rc = power_supply_get_property(chg->wls_chip_psy, + POWER_SUPPLY_PROP_WIRELESS_VERSION, val); + return rc; +} +#endif + +static int smblib_set_sw_thermal_regulation(struct smb_charger *chg, + bool enable) +{ + int rc = 0; + + if (!(chg->wa_flags & SW_THERM_REGULATION_WA)) + return rc; + + if (enable) { + /* + * Configure min time to quickly address thermal + * condition. + */ + rc = smblib_masked_write(chg, SNARL_BARK_BITE_WD_CFG_REG, + SNARL_WDOG_TIMEOUT_MASK, SNARL_WDOG_TMOUT_62P5MS); + if (rc < 0) { + smblib_err(chg, "Couldn't configure snarl wdog tmout, rc=%d\n", + rc); + return rc; + } + + /* + * Schedule SW_THERM_REGULATION_WORK directly if USB input + * is suspended due to SW thermal regulation WA since WDOG + * IRQ won't trigger with input suspended. + */ + if (is_client_vote_enabled(chg->usb_icl_votable, + SW_THERM_REGULATION_VOTER)) { + vote(chg->awake_votable, SW_THERM_REGULATION_VOTER, + true, 0); + schedule_delayed_work(&chg->thermal_regulation_work, 0); + } + } else { + cancel_delayed_work_sync(&chg->thermal_regulation_work); + vote(chg->awake_votable, SW_THERM_REGULATION_VOTER, false, 0); + } smblib_dbg(chg, PR_MISC, "WDOG SNARL INT %s\n", enable ? "Enabled" : "Disabled"); @@ -2852,6 +4535,23 @@ static int smblib_update_thermal_readings(struct smb_charger *chg) #define THERM_REG_RECHECK_DELAY_1S 1000 /* 1 sec */ #define THERM_REG_RECHECK_DELAY_8S 8000 /* 8 sec */ + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static void smblib_report_soc_decimal_work(struct work_struct *work) +{ + struct smb_charger *chg = container_of(work, struct smb_charger, + report_soc_decimal_work.work); + int quick_charge_type; + + quick_charge_type = smblib_get_quick_charge_type(chg); + + if (QUICK_CHARGE_TURBE == quick_charge_type) { + pr_info("report bms uevent when enter turbe charge!\n "); + power_supply_changed(chg->bms_psy); + } +} +#endif + static int smblib_process_thermal_readings(struct smb_charger *chg) { int rc = 0, wdog_timeout = SNARL_WDOG_TMOUT_8S; @@ -2955,6 +4655,10 @@ static int smblib_process_thermal_readings(struct smb_charger *chg) */ if (chg->thermal_status == TEMP_SHUT_DOWN_SMB) goto exit; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump) + chg->bq_input_suspend = !!suspend_input; +#endif /* Suspend input if SHDN threshold reached */ vote(chg->dc_suspend_votable, SW_THERM_REGULATION_VOTER, @@ -3037,6 +4741,10 @@ int smblib_get_prop_dc_online(struct smb_charger *chg, { int rc = 0; u8 stat; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int dc_present; + union power_supply_propval pval = {0, }; +#endif if (chg->chg_param.smb_version == PMI632_SUBTYPE) { val->intval = 0; @@ -3048,20 +4756,48 @@ int smblib_get_prop_dc_online(struct smb_charger *chg, return rc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (is_client_vote_enabled_locked(chg->dc_suspend_votable, +#else if (is_client_vote_enabled(chg->dc_suspend_votable, +#endif CHG_TERMINATION_VOTER)) { rc = smblib_get_prop_dc_present(chg, val); return rc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = smblib_get_prop_dc_present(chg, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get usb present rc = %d\n", rc); + return rc; + } + + dc_present = pval.intval; + + + if (dc_present && + get_client_vote_locked(chg->dc_suspend_votable, JEITA_VOTER) == 1) { + val->intval = true; + return rc; + } + + if (chg->fake_dc_on) { + val->intval = true; + return rc; + } +#endif + rc = smblib_read(chg, POWER_PATH_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read POWER_PATH_STATUS rc=%d\n", rc); return rc; } +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) smblib_dbg(chg, PR_REGISTER, "POWER_PATH_STATUS = 0x%02x\n", stat); +#endif val->intval = (stat & USE_DCIN_BIT) && (stat & VALID_INPUT_POWER_SOURCE_STS_BIT); @@ -3069,10 +4805,31 @@ int smblib_get_prop_dc_online(struct smb_charger *chg, return rc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int smblib_set_prop_wireless_wakelock(struct smb_charger *chg, + const union power_supply_propval *val) +{ + if (val->intval) { + vote(chg->awake_votable, DC_AWAKE_VOTER, true, 0); + //schedule_delayed_work(&chg->dc_input_current_work, + // msecs_to_jiffies(100)); //need enable + } else { + vote(chg->awake_votable, DC_AWAKE_VOTER, false, 0); + //cancel_delayed_work_sync(&chg->dc_input_current_work); + } + return 0; +} +#endif + int smblib_get_prop_dc_current_max(struct smb_charger *chg, union power_supply_propval *val) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + val->intval = get_effective_result_locked(chg->dc_icl_votable); + return 0; +#else return smblib_get_charge_param(chg, &chg->param.dc_icl, &val->intval); +#endif } int smblib_get_prop_dc_voltage_max(struct smb_charger *chg, @@ -3112,7 +4869,14 @@ int smblib_get_prop_dc_voltage_now(struct smb_charger *chg, int smblib_set_prop_dc_current_max(struct smb_charger *chg, const union power_supply_propval *val) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int rc; + + rc = vote(chg->dc_icl_votable, DCIN_ADAPTER_VOTER, true, val->intval); + return rc; +#else return smblib_set_charge_param(chg, &chg->param.dc_icl, val->intval); +#endif } #define DCIN_AICL_RERUN_DELAY_MS 5000 @@ -3120,6 +4884,9 @@ int smblib_set_prop_voltage_wls_output(struct smb_charger *chg, const union power_supply_propval *val) { int rc; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + union power_supply_propval pval = {0, }; +#endif if (!chg->wls_psy) { chg->wls_psy = power_supply_get_by_name("wireless"); @@ -3127,6 +4894,35 @@ int smblib_set_prop_voltage_wls_output(struct smb_charger *chg, return -ENODEV; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = power_supply_get_property(chg->wls_psy, + POWER_SUPPLY_PROP_TX_ADAPTER, + &pval); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (pval.intval == 9 || pval.intval == 11 || pval.intval == 12 || pval.intval == 13 || pval.intval == 14) { +#else + if (pval.intval == 9 || pval.intval == 11 || pval.intval == 12) { +#endif + if (val->intval >= 9200000 && val->intval < 9500000) + vote(chg->dc_icl_votable, DCIN_LIMIT_VOTER, true, 2000000); + else if (val->intval > 9500000) + vote(chg->dc_icl_votable, DCIN_LIMIT_VOTER, true, 1800000); + else + vote(chg->dc_icl_votable, DCIN_LIMIT_VOTER, false, 0); + } else if (pval.intval == 6) { + if (val->intval > 9000000 && val->intval <= 9500000) + vote(chg->dc_icl_votable, DCIN_LIMIT_VOTER, true, 1100000); + else if (val->intval > 9500000) + vote(chg->dc_icl_votable, DCIN_LIMIT_VOTER, true, 1000000); + else + vote(chg->dc_icl_votable, DCIN_LIMIT_VOTER, false, 0); + } else { + smblib_dbg(chg, PR_WLS, "WLS chg type error %d\n", pval.intval); + return rc; + } +#endif + rc = power_supply_set_property(chg->wls_psy, POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, val); @@ -3202,6 +4998,23 @@ int smblib_set_prop_dc_reset(struct smb_charger *chg) return rc; } +#ifdef CONFIG_MACH_XIAOMI_NABU +void smblib_set_prop_pen_mac(struct smb_charger *chg, + const union power_supply_propval *val) +{ + smblib_dbg(chg, PR_WLS, "pen mac raw %llx\n", val->int64val); + chg->pen_bt_mac = val->int64val; + if (!chg->wls_psy) { + chg->wls_psy = power_supply_get_by_name("wireless"); + if (!chg->wls_psy) { + smblib_err(chg, "no wireless power supply, return\n"); + return; + } + } + power_supply_changed(chg->wls_psy); +} +#endif + /******************* * USB PSY GETTERS * *******************/ @@ -3227,18 +5040,77 @@ int smblib_get_prop_usb_online(struct smb_charger *chg, { int rc = 0; u8 stat; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int usb_present; + union power_supply_propval pval = {0, }; +#endif if (get_client_vote_locked(chg->usb_icl_votable, USER_VOTER) == 0) { val->intval = false; return rc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (get_client_vote_locked(chg->usb_icl_votable, JEITA_VOTER) == 0) { + /* show online when JEITA_VOTER 0mA is vote to improve user experience */ + val->intval = true; + return rc; + } +#endif + if (is_client_vote_enabled_locked(chg->usb_icl_votable, CHG_TERMINATION_VOTER)) { rc = smblib_get_prop_usb_present(chg, val); return rc; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump) { + rc = smblib_get_prop_usb_present(chg, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get usb present rc = %d\n", rc); + return rc; + } + + usb_present = pval.intval; + + if (usb_present && chg->use_bq_pump + && (get_client_vote_locked(chg->usb_icl_votable, + MAIN_CHG_VOTER) == MAIN_CHARGER_STOP_ICL)) { + val->intval = true; + return rc; + } + } +#elif defined(CONFIG_MACH_XIAOMI_SM8150) + rc = smblib_get_prop_usb_present(chg, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get usb present rc = %d\n", rc); + return rc; + } + + usb_present = pval.intval; + + if (usb_present && chg->typec_mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) { + val->intval = true; + return rc; + } + + if (usb_present && + get_client_vote_locked(chg->usb_icl_votable, JEITA_VOTER) == 0) { + val->intval = true; + return rc; + } + + if (usb_present && chg->power_good_en) { + /* show online when insert usb in wireless charging */ + if (chg->typec_mode == POWER_SUPPLY_TYPEC_SINK) + val->intval = false; + else + val->intval = true; + return rc; + } +#endif + rc = smblib_read(chg, POWER_PATH_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read POWER_PATH_STATUS rc=%d\n", @@ -3467,6 +5339,52 @@ int smblib_get_prop_vph_voltage_now(struct smb_charger *chg, return 0; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +/* + * we use usb in adc for distinguish qc_a and qc_b, so remain this func + * for this purpose + */ +int smblib_get_usb_in_voltage_now(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc, ret = 0; + + /* set 12V OV to 14.6V */ + /* if (chg->smb_version == PM8150B_SUBTYPE) { + rc = smblib_masked_write(chg, USB_ENG_SSUPPLY_USB2_REG, + ENG_SSUPPLY_12V_OV_OPT_BIT, + ENG_SSUPPLY_12V_OV_OPT_BIT); + if (rc < 0) { + smblib_err(chg, "Couldn't set USB_ENG_SSUPPLY_USB2_REG rc=%d\n", + rc); + return -ENODATA; + } + } */ + + if (chg->iio.usbin_v_chan) { + rc = iio_read_channel_processed(chg->iio.usbin_v_chan, + &val->intval); + if (rc < 0) + ret = -ENODATA; + } else { + ret = -ENODATA; + } + + /* restore 12V OV to 13.2V */ + /* if (chg->smb_version == PM8150B_SUBTYPE) { + rc = smblib_masked_write(chg, USB_ENG_SSUPPLY_USB2_REG, + ENG_SSUPPLY_12V_OV_OPT_BIT, 0); + if (rc < 0) { + smblib_err(chg, "Couldn't restore USB_ENG_SSUPPLY_USB2_REG rc=%d\n", + rc); + ret = -ENODATA; + } + } */ + + return ret; +} +#endif + bool smblib_rsbux_low(struct smb_charger *chg, int r_thr) { int r_sbu1, r_sbu2; @@ -3600,6 +5518,10 @@ static int smblib_get_prop_ufp_mode(struct smb_charger *chg) { int rc; u8 stat; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + union power_supply_propval val = {0, }; + int usb_present = 0; +#endif rc = smblib_read(chg, TYPE_C_SNK_STATUS_REG, &stat); if (rc < 0) { @@ -3620,11 +5542,37 @@ static int smblib_get_prop_ufp_mode(struct smb_charger *chg) case SNK_DAM_500MA_BIT: case SNK_DAM_1500MA_BIT: case SNK_DAM_3000MA_BIT: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + return POWER_SUPPLY_TYPEC_SOURCE_DEFAULT; +#else return POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY; +#endif default: break; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* workaround for scp cable or similar A TO C cables */ + rc = smblib_read(chg, TYPE_C_SNK_DEBUG_ACC_STATUS_REG, &stat); + if (rc < 0) { + smblib_err(chg, "Couldn't read TYPE_C_STATUS_1 rc=%d\n", rc); + return POWER_SUPPLY_TYPEC_NONE; // git + } // git + + rc = smblib_get_prop_usb_present(chg, &val); + if (rc < 0) + smblib_err(chg, "Couldn't get usb present rc = %d\n", rc); + else + usb_present = val.intval; + + if (chg->snk_debug_acc_detected && usb_present) { + return POWER_SUPPLY_TYPEC_SOURCE_DEFAULT; + } + if (stat & SNK_DEBUG_ACC_RPSTD_PRSTD_BIT && usb_present) { + chg->snk_debug_acc_detected = true; + return POWER_SUPPLY_TYPEC_SOURCE_DEFAULT; + } +#endif return POWER_SUPPLY_TYPEC_NONE; } @@ -3642,7 +5590,9 @@ static int smblib_get_prop_dfp_mode(struct smb_charger *chg) rc); return POWER_SUPPLY_TYPEC_NONE; } +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) smblib_dbg(chg, PR_REGISTER, "TYPE_C_SRC_STATUS_REG = 0x%02x\n", stat); +#endif switch (stat & DETECTED_SNK_TYPE_MASK) { case AUDIO_ACCESS_RA_RA_BIT: @@ -4024,6 +5974,10 @@ static int smblib_get_typec_connector_temp_status(struct smb_charger *chg) return POWER_SUPPLY_HEALTH_COOL; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define HVDCP_START_CURRENT_UA 1000000 +#endif + int smblib_get_skin_temp_status(struct smb_charger *chg) { int rc; @@ -4077,6 +6031,7 @@ int smblib_get_prop_connector_health(struct smb_charger *chg) return POWER_SUPPLY_HEALTH_COOL; } +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) static int get_rp_based_dcp_current(struct smb_charger *chg, int typec_mode) { int rp_ua; @@ -4094,6 +6049,7 @@ static int get_rp_based_dcp_current(struct smb_charger *chg, int typec_mode) return rp_ua; } +#endif /******************* * USB PSY SETTERS * @@ -4116,14 +6072,40 @@ int smblib_set_prop_pd_current_max(struct smb_charger *chg, return rc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define FLOAT_CHARGER_UA 1000000 +#define SUSPEND_CURRENT_UA 2000 +#endif static int smblib_handle_usb_current(struct smb_charger *chg, int usb_current) { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int rc = 0, typec_mode; +#else int rc = 0, rp_ua, typec_mode; +#endif union power_supply_propval val = {0, }; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool is_float = false; +#endif + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_FLOAT + && (usb_current == SUSPEND_CURRENT_UA)) + is_float = true; + + if ((usb_current > 0 && usb_current < USBIN_500MA) + || (usb_current == USBIN_900MA)) + usb_current = USBIN_500MA; +#endif if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_FLOAT) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (usb_current == -ETIMEDOUT || is_float) { +#else if (usb_current == -ETIMEDOUT) { +#endif +#ifndef CONFIG_MACH_XIAOMI_SM8150 if ((chg->float_cfg & FLOAT_OPTIONS_MASK) == FORCE_FLOAT_SDP_CFG_BIT) { /* @@ -4138,6 +6120,7 @@ static int smblib_handle_usb_current(struct smb_charger *chg, rc); return rc; } +#endif if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) { @@ -4146,10 +6129,20 @@ static int smblib_handle_usb_current(struct smb_charger *chg, * based of Rp. */ typec_mode = smblib_get_prop_typec_mode(chg); +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) rp_ua = get_rp_based_dcp_current(chg, typec_mode); +#endif +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + if (rp_ua == DCP_CURRENT_UA) + rp_ua = FLOAT_CHARGER_UA; +#endif rc = vote(chg->usb_icl_votable, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + SW_ICL_MAX_VOTER, true, FLOAT_CHARGER_UA); +#else SW_ICL_MAX_VOTER, true, rp_ua); +#endif if (rc < 0) return rc; } else { @@ -4165,6 +6158,9 @@ static int smblib_handle_usb_current(struct smb_charger *chg, * real_charger_type */ chg->real_charger_type = POWER_SUPPLY_TYPE_USB; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->usb_psy_desc.type = POWER_SUPPLY_TYPE_USB; +#endif rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, true, usb_current); if (rc < 0) @@ -4220,7 +6216,11 @@ int smblib_set_prop_sdp_current_max(struct smb_charger *chg, } /* handle the request only when USB is present */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (pval.intval && (val->intval != 0)) +#else if (pval.intval) +#endif rc = smblib_handle_usb_current(chg, val->intval); } else if (chg->system_suspend_supported) { if (val->intval <= USBIN_25MA) @@ -4233,7 +6233,35 @@ int smblib_set_prop_sdp_current_max(struct smb_charger *chg, return rc; } -int smblib_set_prop_boost_current(struct smb_charger *chg, +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int smblib_get_prop_type_recheck(struct smb_charger *chg, + union power_supply_propval *val) +{ + int status = 0; + + if (chg->recheck_charger) + status |= BIT(0) << 8; + + status |= chg->precheck_charger_type << 4; + status |= chg->real_charger_type; + + val->intval = status; + + return 0; +} + +int smblib_set_prop_type_recheck(struct smb_charger *chg, + const union power_supply_propval *val) +{ + if (val->intval == 0) { + cancel_delayed_work_sync(&chg->charger_type_recheck); + chg->recheck_charger = false; + } + return 0; +} +#endif + +int smblib_set_prop_boost_current(struct smb_charger *chg, const union power_supply_propval *val) { int rc = 0; @@ -4478,6 +6506,16 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, smblib_apsd_enable(chg, !chg->pd_active); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (!chg->pd && chg->use_bq_pump) { + chg->pd = devm_usbpd_get_by_phandle(chg->dev, + "qcom,usbpd-phandle"); + if (IS_ERR_OR_NULL(chg->pd)) + pr_err("Failed to get pd handle %ld\n", + PTR_ERR(chg->pd)); + } +#endif + update_sw_icl_max(chg, apsd->pst); if (chg->pd_active) { @@ -4495,6 +6533,19 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0); vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, false, 0); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /*set the icl to PD_UNVERIFED_CURRENT when pd is not verifed*/ + if (!chg->pd_verifed) { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + rc = vote(chg->fcc_votable, PD_VERIFED_VOTER, true, PD_UNVERIFED_CURRENT); +#else + rc = vote(chg->usb_icl_votable, PD_VERIFED_VOTER, true, PD_UNVERIFED_CURRENT); +#endif + if (rc < 0) + smblib_err(chg, "Couldn't unvote PD_VERIFED_VOTER, rc=%d\n", rc); + } +#endif + /* * For PPS, Charge Pump is preferred over parallel charger if * present. @@ -4507,7 +6558,21 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, if (rc < 0) dev_err(chg->dev, "Couldn't enable secondary charger rc=%d\n", rc); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + else + chg->cp_reason = POWER_SUPPLY_CP_PPS; +#endif + } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->pd_active == POWER_SUPPLY_PD_PPS_ACTIVE + && chg->six_pin_step_charge_enable) { + /* start six pin battery step charge monitor work */ + schedule_delayed_work(&chg->six_pin_batt_step_chg_work, + msecs_to_jiffies(STEP_CHG_DELAYED_START_MS)); } + + smblib_therm_charging(chg); +#endif } else { vote(chg->usb_icl_votable, PD_VOTER, false, 0); vote(chg->limited_irq_disable_votable, CHARGER_TYPE_VOTER, @@ -4534,7 +6599,18 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, smblib_usb_pd_adapter_allowance_override(chg, !!chg->pd_active ? FORCE_5V : FORCE_NULL); + +#if !(defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU))) smblib_update_usb_type(chg); +#else + if (!chg->fake_usb_insertion) + smblib_update_usb_type(chg); +#endif + +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + smblib_therm_charging(chg); +#endif + power_supply_changed(chg->usb_psy); return rc; } @@ -4626,6 +6702,11 @@ static int smblib_soft_jeita_arb_wa(struct smb_charger *chg) int rc = 0; bool soft_jeita; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* we still use old soft jeita method */ + return 0; +#endif + rc = smblib_get_prop_batt_health(chg, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get battery health rc=%d\n", rc); @@ -4766,12 +6847,34 @@ int smblib_get_charge_current(struct smb_charger *chg, typec_source_rd = smblib_get_prop_ufp_mode(chg); +#ifdef CONFIG_MACH_XIAOMI_NABU + /* QC 3.5 adapter */ + if (chg->qc3p5_supported && + (apsd_result->pst == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) && + (chg->qc3p5_power_limit_w == 40)) { + *total_current_ua = HVDCP3P5_40W_CURRENT_UA; + return 0; + } +#endif + /* QC 2.0/3.0 adapter */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (apsd_result->bit & QC_3P0_BIT) { +#else if (apsd_result->bit & (QC_3P0_BIT | QC_2P0_BIT)) { +#endif *total_current_ua = HVDCP_CURRENT_UA; return 0; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* QC 2.0 adapter */ + if (apsd_result->bit & QC_2P0_BIT) { + *total_current_ua = HVDCP2_CURRENT_UA; + return 0; + } +#endif + if (non_compliant && !chg->typec_legacy_use_rp_icl) { switch (apsd_result->bit) { case CDP_CHARGER_BIT: @@ -4952,6 +7055,35 @@ static void smblib_eval_chg_termination(struct smb_charger *chg, u8 batt_status) } } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +irqreturn_t dcin_uv_handler(int irq, void *data) +{ + struct smb_irq_data *irq_data = data; + struct smb_charger *chg = irq_data->parent_data; + + int rc; + u8 stat; + + rc = smblib_read(chg, POWER_PATH_STATUS_REG, &stat); + if (rc < 0) { + smblib_err(chg, "Couldn't read POWER_PATH_STATUS rc=%d\n", + rc); + return IRQ_HANDLED; + } + + if ((stat & POWER_PATH_MASK) == 0x2) { /*power by battery*/ + chg->fake_dc_on = 1; /*use for delay 1.8s*/ + chg->fake_dc_flag = 1; + schedule_delayed_work(&chg->dc_plug_out_delay_work, + msecs_to_jiffies(1800)); + vote(chg->awake_votable, DC_UV_AWAKE_VOTER, true, 0); + } + smblib_dbg(chg, PR_WLS, "Delay dc plug out and power path 0x%x\n", stat); + + return IRQ_HANDLED; +} +#endif + irqreturn_t chg_state_change_irq_handler(int irq, void *data) { struct smb_irq_data *irq_data = data; @@ -4995,6 +7127,12 @@ irqreturn_t batt_temp_changed_irq_handler(int irq, void *data) return IRQ_HANDLED; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* we still use old soft jeita method */ + rerun_election(chg->fcc_votable); + power_supply_changed(chg->batt_psy); +#endif + return IRQ_HANDLED; } @@ -5092,6 +7230,9 @@ irqreturn_t usbin_uv_irq_handler(int irq, void *data) /* Workaround for non-QC2.0-compliant chargers follows */ if (!chg->qc2_unsupported_voltage && +#ifdef CONFIG_MACH_XIAOMI_SM8150 + !chg->qc2_unsupported && +#endif apsd->pst == POWER_SUPPLY_TYPE_USB_HVDCP) { rc = smblib_read(chg, QC_CHANGE_STATUS_REG, &stat); if (rc < 0) @@ -5137,6 +7278,22 @@ irqreturn_t usbin_uv_irq_handler(int irq, void *data) rc); smblib_rerun_apsd(chg); + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + pr_info("qc2_unsupported charger detected\n"); + rc = smblib_force_vbus_voltage(chg, FORCE_5V_BIT); + if (rc < 0) + pr_err("Failed to force 5V\n"); + rc = smblib_set_adapter_allowance(chg, USBIN_ADAPTER_ALLOW_5V);; + if (rc < 0) + pr_err("Failed to set adapter allowance to 5V\n"); + rc = smblib_set_opt_switcher_freq(chg, chg->chg_freq.freq_5V); + if (rc < 0) + pr_err("Failed to set chg_freq.freq_5V\n"); + vote(chg->usb_icl_votable, QC2_UNSUPPORTED_VOTER, true, + QC2_UNSUPPORTED_UA); + chg->qc2_unsupported = true; +#endif } return IRQ_HANDLED; @@ -5196,6 +7353,243 @@ irqreturn_t icl_change_irq_handler(int irq, void *data) return IRQ_HANDLED; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static void smblib_cc_un_compliant_charge_work(struct work_struct *work) +{ + union power_supply_propval val = {0, }; + int rc, usb_present = 0; + + struct smb_charger *chg = container_of(work, struct smb_charger, + cc_un_compliant_charge_work.work); + + rc = smblib_get_prop_usb_present(chg, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't get usb present rc = %d\n", rc); + return; + } + + usb_present = val.intval; + + /* + * workaround for typec audio/charger connector charge issue + * when firstly insert earphone then insert charger, it will trigger usbin_plugin irq, + * but not trigger typec_attach_detach irq. so need force set charger type and ICL here. + */ + if (usb_present && chg->typec_mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) { + chg->real_charger_type = POWER_SUPPLY_TYPE_USB_FLOAT; + chg->usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_FLOAT; + if ((strcmp(get_effective_client(chg->usb_icl_votable), "OTG_VOTER") == 0) && + (get_effective_result(chg->usb_icl_votable) == 0)) + vote(chg->usb_icl_votable, OTG_VOTER, false, 0); + + if (get_client_vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER) != 500000) + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, 500000); + } + + /* + * if CC pin of C to A cable is not connected to the receptacle + * or CC pin is bad or short to VBUS or C to C cable CC line is float, + * disable APSD CC trigger since pm8150b CC protection voltage + * threshold is very high (22V), our wire charging maxium charging + * vbus is below 13.2V. + */ + if (usb_present + && (chg->typec_mode == POWER_SUPPLY_TYPEC_NONE || + chg->typec_mode == POWER_SUPPLY_TYPEC_NON_COMPLIANT || + chg->snk_debug_acc_detected == true) + && (chg->cc_un_compliant_detected == false)) { + chg->cc_un_compliant_detected = true; + //smblib_apsd_enable(chg, true); + smblib_hvdcp_detect_enable(chg, true); + smblib_rerun_apsd_if_required(chg); + } +} + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static void smb_check_init_boot(struct work_struct *work) +{ + struct smb_charger *chg = container_of(work, struct smb_charger, + check_init_boot.work); + first_boot_flag = true; + if (chg->usb_psy) + power_supply_changed(chg->usb_psy); +} + +#ifdef CONFIG_MACH_XIAOMI_NABU +static int fv_over_limit_times; +#define OVER_FV_MAX_TIMES 10 +static void smblib_check_vbat_work(struct work_struct *work) +{ + int rc; + int effective_fv_uv; + union power_supply_propval val; + + struct smb_charger *chg = container_of(work, struct smb_charger, + check_vbat_work.work); + if (!chg->cp_psy) { + chg->cp_psy = power_supply_get_by_name("bq2597x-standalone"); + if (!chg->cp_psy){ + chg->cp_psy = power_supply_get_by_name("ln8000"); + if (!chg->cp_psy){ + pr_err("cp_psy not found\n"); + return; + } + } + } + + rc = power_supply_get_property(chg->cp_psy, + POWER_SUPPLY_PROP_MODEL_NAME, &val); + if (rc < 0) { + pr_err("Error in getting charge IC name, rc=%d\n", rc); + return; + } + + if (strcmp(val.strval, "bq2597x-standalone") == 0) { + rc = power_supply_get_property(chg->cp_psy, + POWER_SUPPLY_PROP_TI_BATTERY_VOLTAGE, &val); + pr_err("getting ti battery voltage = %d\n", val.intval); + if (rc < 0) { + pr_err("Error in getting ti battery voltage, rc=%d\n", rc); + return; + } + if (val.intval > 4800) { + if (fv_over_limit_times++ > OVER_FV_MAX_TIMES) { + fv_over_limit_times = 0; + effective_fv_uv = get_effective_result_locked(chg->fv_votable); + vote(chg->fv_votable, BATT_BQ2597X_VOTER, true, effective_fv_uv - 10000); + } + } + } + schedule_delayed_work(&chg->check_vbat_work, msecs_to_jiffies(200)); + +} +#endif + +#define REDUCED_CURRENT 500000 +static int smblib_get_effective_fcc_val(struct smb_charger *chg) +{ + int effective_fcc_val = 0; + + effective_fcc_val = get_effective_result(chg->fcc_votable); + return effective_fcc_val; +} + +static int check_reduce_fcc_condition(struct smb_charger *chg) +{ + union power_supply_propval val = {0, }; + int rc, ibat = 0; + int effective_fcc = 0; + + if (!chg->cp_psy) { + chg->cp_psy = power_supply_get_by_name("bq2597x-standalone"); + } + +#ifdef CONFIG_MACH_XIAOMI_NABU + if (!chg->cp_psy){ + chg->cp_psy = power_supply_get_by_name("ln8000"); + } +#endif + + if (!chg->cp_psy) { + pr_err("cp_psy not found\n"); + return 0; + } + + rc = power_supply_get_property(chg->cp_psy, + POWER_SUPPLY_PROP_CHARGING_ENABLED, &val); + if (rc < 0) { + pr_err("Error in getting cp charge enable, rc=%d\n", rc); + return 0; + } + chg->cp_charge_enabled = !!val.intval; + + rc = power_supply_get_property(chg->batt_psy, POWER_SUPPLY_PROP_STATUS, + &val); + if (rc < 0) { + pr_err("Error in getting charging status, rc=%d\n", rc); + return 0; + } + chg->charge_status = val.intval; + + rc = power_supply_get_property(chg->batt_psy, + POWER_SUPPLY_PROP_CHARGE_TYPE, &val); + if (rc < 0) { + pr_err("Error in getting charge type, rc=%d\n", rc); + return 0; + } + chg->charge_type = val.intval; + + rc = power_supply_get_property(chg->batt_psy, POWER_SUPPLY_PROP_HEALTH, + &val); + if (rc < 0) { + pr_err("Error in getting charging status, rc=%d\n", rc); + return 0; + } + chg->batt_health = val.intval; + + pr_info("cp_charge_enabled(%d), charge_status(%d), charge_type(%d), batt_health(%d)\n", + chg->cp_charge_enabled, chg->charge_status, chg->charge_type, chg->batt_health); + + /* should add battery health later */ + if (!chg->cp_charge_enabled || + (chg->charge_status != POWER_SUPPLY_STATUS_CHARGING) || + (chg->charge_type != POWER_SUPPLY_CHARGE_TYPE_FAST) || + (chg->batt_health != POWER_SUPPLY_HEALTH_GOOD)) + return 0; + + rc = smblib_get_prop_from_bms(chg, + POWER_SUPPLY_PROP_CURRENT_NOW, &val); + if (rc < 0) + return 0; + + ibat = val.intval/1000; + if (ibat > -450) { + pr_info("Skip CHG ESR, Fails IBAT ibat(%d)\n", ibat); + return 0; + } + + effective_fcc = smblib_get_effective_fcc_val(chg); + if (effective_fcc < 0) + return 0; + + return effective_fcc; +} + +/* In order to calculate battery esr */ +static void reduce_fcc_work(struct work_struct *work) +{ + struct smb_charger *chg = container_of(work, struct smb_charger, + reduce_fcc_work.work); + int effective_fcc; + int esr_work_time = ESR_WORK_TIME_180S; + bool reduce_fcc = false; + + effective_fcc = check_reduce_fcc_condition(chg); + if (effective_fcc > 0) { + if (chg->esr_work_status == ESR_CHECK_FCC_NOLIMIT) { + effective_fcc -= REDUCED_CURRENT; + chg->esr_work_status = ESR_CHECK_FCC_LIMITED; + reduce_fcc = true; + esr_work_time = ESR_WORK_TIME_2S; + } else { + chg->esr_work_status = ESR_CHECK_FCC_NOLIMIT; + reduce_fcc = false; + esr_work_time = ESR_WORK_TIME_180S; + } + } else { + chg->esr_work_status = ESR_CHECK_FCC_NOLIMIT; + reduce_fcc = false; + esr_work_time = ESR_WORK_TIME_180S; + pr_info("calculate esr condition not satisfy.\n"); + } + + vote(chg->fcc_votable, ESR_WORK_VOTER, reduce_fcc, effective_fcc); + schedule_delayed_work(&chg->reduce_fcc_work, + msecs_to_jiffies(esr_work_time)); +} +#endif +#endif + static void smblib_micro_usb_plugin(struct smb_charger *chg, bool vbus_rising) { if (!vbus_rising) { @@ -5205,6 +7599,9 @@ static void smblib_micro_usb_plugin(struct smb_charger *chg, bool vbus_rising) } } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static void typec_src_removal(struct smb_charger *chg); +#endif void smblib_usb_plugin_hard_reset_locked(struct smb_charger *chg) { int rc; @@ -5222,9 +7619,17 @@ void smblib_usb_plugin_hard_reset_locked(struct smb_charger *chg) vbus_rising = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT); if (vbus_rising) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* hold chg_awake wakeup source when charger is present */ + vote(chg->awake_votable, CHG_AWAKE_VOTER, true, 0); +#endif /* Remove FCC_STEPPER 1.5A init vote to allow FCC ramp up */ if (chg->fcc_stepper_enable) vote(chg->fcc_votable, FCC_STEPPER_VOTER, false, 0); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->six_pin_step_charge_enable) + smblib_get_start_vbat_before_step_charge(chg); +#endif } else { if (chg->wa_flags & BOOST_BACK_WA) { data = chg->irq_info[SWITCHER_POWER_OK_IRQ].irq_data; @@ -5239,6 +7644,28 @@ void smblib_usb_plugin_hard_reset_locked(struct smb_charger *chg) } } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + cancel_delayed_work_sync(&chg->charger_type_recheck); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->hvdcp_recheck_status = false; +#endif + chg->recheck_charger = false; + chg->precheck_charger_type = POWER_SUPPLY_TYPE_UNKNOWN; + if (chg->cc_un_compliant_detected) { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* disable apsd if cc_un_compliant detected after plug out */ + //smblib_apsd_enable(chg, false); + typec_src_removal(chg); +#else + smblib_hvdcp_detect_enable(chg, false); +#endif + chg->cc_un_compliant_detected = false; + } + + /* clear chg_awake wakeup source when charger is absent */ + vote(chg->awake_votable, CHG_AWAKE_VOTER, false, 0); +#endif + /* Force 1500mA FCC on USB removal if fcc stepper is enabled */ if (chg->fcc_stepper_enable) vote(chg->fcc_votable, FCC_STEPPER_VOTER, @@ -5265,131 +7692,614 @@ void smblib_usb_plugin_locked(struct smb_charger *chg) return; } - vbus_rising = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT); - smblib_set_opt_switcher_freq(chg, vbus_rising ? chg->chg_freq.freq_5V : - chg->chg_freq.freq_removal); + vbus_rising = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT); + smblib_set_opt_switcher_freq(chg, vbus_rising ? chg->chg_freq.freq_5V : + chg->chg_freq.freq_removal); + + if (vbus_rising) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* when vbus present, enable batt_temp irq wakeup */ +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->irq_info[BAT_TEMP_IRQ].irq && !chg->batt_temp_irq_enabled) { + enable_irq_wake(chg->irq_info[BAT_TEMP_IRQ].irq); + chg->batt_temp_irq_enabled = true; + } +#endif + if (smblib_get_prop_dfp_mode(chg) != POWER_SUPPLY_TYPEC_NONE + && smblib_get_prop_dfp_mode(chg) + != POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) { + chg->fake_usb_insertion = true; + return; + } + + /* hold a wakeup source when charger is present */ + vote(chg->awake_votable, CHG_AWAKE_VOTER, true, 0); +#endif + cancel_delayed_work_sync(&chg->pr_swap_detach_work); + vote(chg->awake_votable, DETACH_DETECT_VOTER, false, 0); + rc = smblib_request_dpdm(chg, true); + if (rc < 0) + smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + smblib_check_batt_authentic(chg); +#endif + + /* Enable SW Thermal regulation */ + rc = smblib_set_sw_thermal_regulation(chg, true); + if (rc < 0) + smblib_err(chg, "Couldn't start SW thermal regulation WA, rc=%d\n", + rc); + + /* Remove FCC_STEPPER 1.5A init vote to allow FCC ramp up */ + if (chg->fcc_stepper_enable) + vote(chg->fcc_votable, FCC_STEPPER_VOTER, false, 0); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->six_pin_step_charge_enable) + smblib_get_start_vbat_before_step_charge(chg); +#endif + + /* Schedule work to enable parallel charger */ + vote(chg->awake_votable, PL_DELAY_VOTER, true, 0); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (!first_boot_flag) + schedule_delayed_work(&chg->check_init_boot, msecs_to_jiffies(18000)); +#endif + schedule_delayed_work(&chg->pl_enable_work, + msecs_to_jiffies(PL_DELAY_MS)); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + schedule_delayed_work(&chg->charger_type_recheck, + msecs_to_jiffies(CHARGER_RECHECK_DELAY_MS)); + schedule_delayed_work(&chg->cc_un_compliant_charge_work, + msecs_to_jiffies(CC_UN_COMPLIANT_START_DELAY_MS)); +#ifdef CONFIG_MACH_XIAOMI_NABU + schedule_delayed_work(&chg->check_vbat_work, msecs_to_jiffies(200)); +#endif +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump) + schedule_delayed_work(&chg->reduce_fcc_work, + msecs_to_jiffies(ESR_WORK_TIME_180S)); +#endif +#endif + } else { +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* when vbus absent, disable batt_temp irq wakeup */ + if (chg->irq_info[BAT_TEMP_IRQ].irq && chg->batt_temp_irq_enabled) { + disable_irq_wake(chg->irq_info[BAT_TEMP_IRQ].irq); + chg->batt_temp_irq_enabled = false; + } +#endif + + if (chg->fake_usb_insertion) { + chg->fake_usb_insertion = false; + return; + } + + cancel_delayed_work_sync(&chg->charger_type_recheck); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump) { + cancel_delayed_work_sync(&chg->reduce_fcc_work); + vote(chg->fcc_votable, ESR_WORK_VOTER, false, 0); + } +#endif +#endif + + /* Disable SW Thermal Regulation */ + rc = smblib_set_sw_thermal_regulation(chg, false); + if (rc < 0) + smblib_err(chg, "Couldn't stop SW thermal regulation WA, rc=%d\n", + rc); + + if (chg->wa_flags & BOOST_BACK_WA) { + data = chg->irq_info[SWITCHER_POWER_OK_IRQ].irq_data; + if (data) { + wdata = &data->storm_data; + update_storm_count(wdata, + WEAK_CHG_STORM_COUNT); + vote(chg->usb_icl_votable, BOOST_BACK_VOTER, + false, 0); + vote(chg->usb_icl_votable, WEAK_CHARGER_VOTER, + false, 0); + } + } + + /* Force 1500mA FCC on removal if fcc stepper is enabled */ + if (chg->fcc_stepper_enable) + vote(chg->fcc_votable, FCC_STEPPER_VOTER, + true, 1500000); + + if (chg->wa_flags & WEAK_ADAPTER_WA) { + chg->aicl_5v_threshold_mv = + chg->default_aicl_5v_threshold_mv; + chg->aicl_cont_threshold_mv = + chg->default_aicl_cont_threshold_mv; + + smblib_set_charge_param(chg, + &chg->param.aicl_5v_threshold, + chg->aicl_5v_threshold_mv); + smblib_set_charge_param(chg, + &chg->param.aicl_cont_threshold, + chg->aicl_cont_threshold_mv); + chg->aicl_max_reached = false; + + if (chg->chg_param.smb_version == PMI632_SUBTYPE) + schgm_flash_torch_priority(chg, + TORCH_BUCK_MODE); + + data = chg->irq_info[USBIN_UV_IRQ].irq_data; + if (data) { + wdata = &data->storm_data; + reset_storm_count(wdata); + } + vote(chg->usb_icl_votable, AICL_THRESHOLD_VOTER, + false, 0); + } + + rc = smblib_request_dpdm(chg, false); + if (rc < 0) + smblib_err(chg, "Couldn't disable DPDM rc=%d\n", rc); + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (chg->cc_un_compliant_detected) { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* disable apsd if cc_un_compliant detected after plug out */ + //smblib_apsd_enable(chg, false); + typec_src_removal(chg); +#else + smblib_hvdcp_detect_enable(chg, false); +#endif + chg->cc_un_compliant_detected = false; + } + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->hvdcp_recheck_status = false; +#endif + chg->recheck_charger = false; + chg->precheck_charger_type = POWER_SUPPLY_TYPE_UNKNOWN; + /* clear chg_awake wakeup source when charger is absent */ + vote(chg->awake_votable, CHG_AWAKE_VOTER, false, 0); +#endif + smblib_update_usb_type(chg); + } + + if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + smblib_micro_usb_plugin(chg, vbus_rising); + + vote(chg->temp_change_irq_disable_votable, DEFAULT_VOTER, + !vbus_rising, 0); + + power_supply_changed(chg->usb_psy); + if (chg->dual_role) + dual_role_instance_changed(chg->dual_role); + smblib_dbg(chg, PR_INTERRUPT, "IRQ: usbin-plugin %s\n", + vbus_rising ? "attached" : "detached"); +} + +irqreturn_t usb_plugin_irq_handler(int irq, void *data) +{ + struct smb_irq_data *irq_data = data; + struct smb_charger *chg = irq_data->parent_data; + + if (chg->pd_hard_reset) + smblib_usb_plugin_hard_reset_locked(chg); + else + smblib_usb_plugin_locked(chg); + + return IRQ_HANDLED; +} + +static void smblib_handle_slow_plugin_timeout(struct smb_charger *chg, + bool rising) +{ + smblib_dbg(chg, PR_INTERRUPT, "IRQ: slow-plugin-timeout %s\n", + rising ? "rising" : "falling"); +} + +static void smblib_handle_sdp_enumeration_done(struct smb_charger *chg, + bool rising) +{ + smblib_dbg(chg, PR_INTERRUPT, "IRQ: sdp-enumeration-done %s\n", + rising ? "rising" : "falling"); +} + +#ifdef CONFIG_MACH_XIAOMI_NABU +static bool qc3p5_vbus_timeout_check(struct smb_charger *chg, + int timeout_ms, int vbus_lo_bound, + int vbus_hi_bound, int *vbus_uv) +{ + union power_supply_propval pval; + ktime_t start_kt, delta_kt; + int rc = 0; + + rc = power_supply_get_property(chg->usb_psy, + POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get VBUS voltage rc=%d\n", rc); + return false; + } + + start_kt = ktime_get_boottime(); + delta_kt = ktime_sub(ktime_get_boottime(), start_kt); + while (((pval.intval <= vbus_lo_bound) || (pval.intval >= vbus_hi_bound)) + && (ktime_to_ms(delta_kt) < timeout_ms)) { + rc = power_supply_get_property(chg->usb_psy, + POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get VBUS voltage rc=%d\n", rc); + return false; + } + delta_kt = ktime_sub(ktime_get_boottime(), start_kt); + } + + if ((pval.intval <= vbus_lo_bound) + || (pval.intval >= vbus_hi_bound) + || (ktime_to_ms(delta_kt) > timeout_ms)) { + smblib_err(chg, "QC3.5: VBUS failed to settle\n"); + return false; + } + + *vbus_uv = (int)pval.intval; + smblib_err(chg, "QC3.5: VBUS successfully settled\n"); + + return true; +} + +#define QC3P5_T_TA_DETECTION_TIMEOUT_PMIC_MS 200 +#define QC3P5_T_TA_CAP_TIMEOUT_PMIC_MS 250 +#define VBUS_5P5_V_UV 5500000 +#define VBUS_6P4_V_UV 6400000 +#define VBUS_6P65_V_UV 6650000 +#define VBUS_7P35_V_UV 7350000 +#define VBUS_7P6_V_UV 7600000 +#define VBUS_8P4_V_UV 8400000 +/*Use 8.55V and 9.8V to account for +10% and -5% spec on 9V for QC2/3 */ +#define VBUS_8P55_V_UV 8550000 +#define VBUS_9P8_V_UV 9800000 + +static int qc3p5_authenticate(struct smb_charger *chg) +{ + int i, vbus_uv, rc = 0; + + chg->qc3p5_authenticated = false; + chg->qc3p5_authentication_started = true; + chg->qc3p5_power_limit_w = 18;//Default to lowest power limit of 18W + + /* Set ICL to 500mA during QC3.5 Authentication */ + vote(chg->usb_icl_votable, QC3P5_VOTER, true, USBIN_500MA); + + /* + * * Fall back to QC3.0 Mode if VBUS doesn't settle between + * * 5.5V and 6.4V in 200ms + * */ + if (!qc3p5_vbus_timeout_check(chg, QC3P5_T_TA_DETECTION_TIMEOUT_PMIC_MS, + VBUS_5P5_V_UV, VBUS_6P4_V_UV, &vbus_uv)) { + smblib_err(chg, "VBUS doesn't reach 6V vbus=%d\n", vbus_uv); + return -ENODEV; + } + + smblib_err(chg, "QC3P5 AUTH: After QC3.0 Auth VBUS = %d\n", vbus_uv); + + /* Issue +-+-+- to request SRC CAP */ + for (i = 0; i < 3; i++) { + rc = smblib_dp_pulse(chg); + if (rc < 0) { + smblib_err(chg, "Couldn't issue D+ pulse rc=%d\n", rc); + return rc; + } + usleep_range(5000, 5010); + + rc = smblib_dm_pulse(chg); + if (rc < 0) { + smblib_err(chg, "Couldn't issue D- pulse rc=%d\n", rc); + return rc; + } + usleep_range(5000, 5010); + } + + /* Return to QC3.0 Mode if VBUS doesn't reach 7V in 200ms 50ms buffer */ + if (!qc3p5_vbus_timeout_check(chg, QC3P5_T_TA_CAP_TIMEOUT_PMIC_MS, + VBUS_6P65_V_UV, VBUS_9P8_V_UV, &vbus_uv)) { + smblib_err(chg, "VBUS doesn't reach 7V vbus=%d\n", vbus_uv); + return -ENODEV; + } + smblib_err(chg, "QC3P5 AUTH: SRC_CAP receieved\n"); + + /* Issue ++-- to confirm transition to QC3.5 */ + rc = smblib_dp_pulse(chg); + if (rc < 0) { + smblib_err(chg, "Couldn't issue D+ pulse rc=%d\n", rc); + return rc; + } + usleep_range(5000, 5010); + + rc = smblib_dp_pulse(chg); + if (rc < 0) { + smblib_err(chg, "Couldn't issue D+ pulse rc=%d\n", rc); + return rc; + } + usleep_range(5000, 5010); + + rc = smblib_dm_pulse(chg); + if (rc < 0) { + smblib_err(chg, "Couldn't issue D- pulse rc=%d\n", rc); + return rc; + } + usleep_range(5000, 5010); + + rc = smblib_dm_pulse(chg); + if (rc < 0) { + smblib_err(chg, "Couldn't issue D- pulse rc=%d\n", rc); + return rc; + } + + /* SRC CAP 7V for 18W */ + if ((vbus_uv >= VBUS_6P65_V_UV) && (vbus_uv <= VBUS_7P35_V_UV)) { + chg->qc3p5_power_limit_w = 18; + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, QC3P5_CHARGER_ICL); + /* SRC CAP 8V for 27W */ + } else if ((vbus_uv >= VBUS_7P6_V_UV) && (vbus_uv <= VBUS_8P4_V_UV)) { + chg->qc3p5_power_limit_w = 27; + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, QC3P5_CHARGER_ICL); + /* SRC CAP 9V for 40W */ + } else if ((vbus_uv >= VBUS_8P55_V_UV) && (vbus_uv <= VBUS_9P8_V_UV)) { + chg->qc3p5_power_limit_w = 40; + // QC3.5 40W adapter's icl limited to 4A + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, HVDCP3P5_40W_CURRENT_UA); + } else { + smblib_err(chg, "not supported SRC CAP, vbus=%d\n", vbus_uv); + return -ENODEV; + } + + chg->qc3p5_authenticated = true; + vote(chg->fcc_votable, FCC_MAX_QC3P5_VOTER, true, HVDCP3P5_40W_CURRENT_UA); + + if (chg->support_ffc && !smblib_get_fastcharge_mode(chg)) + smblib_set_fastcharge_mode(chg, true); + + smblib_err(chg, "QC3P5 AUTH: QC3.5 Authenticated\n"); + smblib_err(chg, "QC3P5 AUTH: Power Limit = %d\n", + chg->qc3p5_power_limit_w); + + return rc; +} +#endif + +#define APSD_EXTENDED_TIMEOUT_MS 400 +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static int smblib_hvdcp3_raise_fsw(struct smb_charger *chg, int pulse_count) +{ + if (pulse_count < QC3_PULSES_FOR_6V) + smblib_set_opt_switcher_freq(chg, + chg->chg_freq.freq_5V); + else if (pulse_count < QC3_PULSES_FOR_9V) + smblib_set_opt_switcher_freq(chg, + chg->chg_freq.freq_6V_8V); + else if (pulse_count < QC3_PULSES_FOR_12V) + smblib_set_opt_switcher_freq(chg, + chg->chg_freq.freq_9V); + else + smblib_set_opt_switcher_freq(chg, + chg->chg_freq.freq_12V); + return 0; +} +#endif + +static void smblib_raise_qc3_vbus_work(struct work_struct *work) +{ + union power_supply_propval val = {0, }; + int i, usb_present = 0, vbus_now = 0; + int vol_qc_ab_thr = 0; + int rc; + struct smb_charger *chg = container_of(work, struct smb_charger, + raise_qc3_vbus_work.work); + + rc = smblib_get_prop_usb_present(chg, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't get usb present rc = %d\n", rc); + return; + } + + usb_present = val.intval; + if (usb_present) { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->pd_hard_reset) { + if (chg->detect_low_power_qc3_charger) + chg->detect_low_power_qc3_charger = false; + if (chg->use_bq_pump) + vote(chg->usb_icl_votable, HVDCP3_START_ICL_VOTER, false, 0); + pr_info("pd hard reset, no need to raise vbus now\n"); + return; + } +#endif + + chg->raise_vbus_to_detect = true; + for (i = 0; i < MAX_PULSE; i++) { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + smblib_hvdcp3_raise_fsw(chg, i); +#endif + rc = smblib_dp_pulse(chg); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + msleep(40); +#else + msleep(30); +#endif + } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + msleep(200); +#else + msleep(100); +#endif + rc = smblib_get_prop_usb_present(chg, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't get usb present rc = %d\n", rc); + return; + } - if (vbus_rising) { - cancel_delayed_work_sync(&chg->pr_swap_detach_work); - vote(chg->awake_votable, DETACH_DETECT_VOTER, false, 0); - rc = smblib_request_dpdm(chg, true); + usb_present = val.intval; + pr_info("usb_present is %d\n", usb_present); + if (!usb_present) { + chg->raise_vbus_to_detect = false; + rc = smblib_force_vbus_voltage(chg, FORCE_5V_BIT); + if (rc < 0) + pr_err("Failed to force 5V\n"); + return; + } + + rc = smblib_get_usb_in_voltage_now(chg, &val); if (rc < 0) - smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc); + pr_err("Couldn't get usb voltage rc=%d\n", rc); + vbus_now = val.intval; + pr_info("vbus_now is %d\n", vbus_now); - /* Enable SW Thermal regulation */ - rc = smblib_set_sw_thermal_regulation(chg, true); + if (chg->snk_debug_acc_detected && usb_present) + vol_qc_ab_thr = VOL_THR_FOR_QC_CLASS_AB + + COMP_FOR_LOW_RESISTANCE_CABLE; + else + vol_qc_ab_thr = VOL_THR_FOR_QC_CLASS_AB; + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (vbus_now <= vol_qc_ab_thr + || chg->batt_profile_fcc_ua <= QC_CLASS_A_CURRENT_UA) { +#else + if (vbus_now <= vol_qc_ab_thr) { +#endif + pr_info("qc_class_a charger is detected, batt_profile_fcc=%d\n", chg->batt_profile_fcc_ua); + chg->is_qc_class_a = true; + vote(chg->fcc_votable, + CLASSA_QC_FCC_VOTER, true, QC_CLASS_A_CURRENT_UA); + } else { + pr_info("qc_class_b charger is detected\n"); + chg->is_qc_class_b = true; + if (chg->usb_psy) + power_supply_changed(chg->usb_psy); + } + rc = smblib_force_vbus_voltage(chg, FORCE_5V_BIT); if (rc < 0) - smblib_err(chg, "Couldn't start SW thermal regulation WA, rc=%d\n", - rc); + pr_err("Failed to force 5V\n"); - /* Remove FCC_STEPPER 1.5A init vote to allow FCC ramp up */ - if (chg->fcc_stepper_enable) - vote(chg->fcc_votable, FCC_STEPPER_VOTER, false, 0); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + msleep(100); - /* Schedule work to enable parallel charger */ - vote(chg->awake_votable, PL_DELAY_VOTER, true, 0); - schedule_delayed_work(&chg->pl_enable_work, - msecs_to_jiffies(PL_DELAY_MS)); - } else { - /* Disable SW Thermal Regulation */ - rc = smblib_set_sw_thermal_regulation(chg, false); - if (rc < 0) - smblib_err(chg, "Couldn't stop SW thermal regulation WA, rc=%d\n", - rc); + rc = smblib_dp_pulse(chg); +#endif - if (chg->wa_flags & BOOST_BACK_WA) { - data = chg->irq_info[SWITCHER_POWER_OK_IRQ].irq_data; - if (data) { - wdata = &data->storm_data; - update_storm_count(wdata, - WEAK_CHG_STORM_COUNT); - vote(chg->usb_icl_votable, BOOST_BACK_VOTER, - false, 0); - vote(chg->usb_icl_votable, WEAK_CHARGER_VOTER, - false, 0); + if (chg->is_qc_class_a) { + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, + HVDCP_CLASS_A_MAX_UA); + } else { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, + HVDCP_CLASS_B_CURRENT_UA); + if (chg->support_ffc) { + if (!smblib_get_fastcharge_mode(chg)) + smblib_set_fastcharge_mode(chg, true); } +#else + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, + HVDCP_CURRENT_UA); +#endif } - /* Force 1500mA FCC on removal if fcc stepper is enabled */ - if (chg->fcc_stepper_enable) - vote(chg->fcc_votable, FCC_STEPPER_VOTER, - true, 1500000); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump) + vote(chg->usb_icl_votable, HVDCP3_START_ICL_VOTER, false, 0); - if (chg->wa_flags & WEAK_ADAPTER_WA) { - chg->aicl_5v_threshold_mv = - chg->default_aicl_5v_threshold_mv; - chg->aicl_cont_threshold_mv = - chg->default_aicl_cont_threshold_mv; + if (!chg->use_bq_pump) { +#endif + /* select charge pump as second charger */ + rc = smblib_select_sec_charger(chg, POWER_SUPPLY_CHARGER_SEC_CP, + POWER_SUPPLY_CP_HVDCP3, false); + if (rc < 0) + dev_err(chg->dev, + "Couldn't enable secondary chargers rc=%d\n", rc); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + } +#endif + +#ifdef CONFIG_THERMAL + if (chg->cp_reason == POWER_SUPPLY_CP_HVDCP3) + smblib_therm_charging(chg); +#endif + chg->raise_vbus_to_detect = false; + } +} + +struct quick_charge adapter_cap[] = { + { POWER_SUPPLY_TYPE_USB, QUICK_CHARGE_NORMAL }, + { POWER_SUPPLY_TYPE_USB_DCP, QUICK_CHARGE_NORMAL }, + { POWER_SUPPLY_TYPE_USB_CDP, QUICK_CHARGE_NORMAL }, + { POWER_SUPPLY_TYPE_USB_ACA, QUICK_CHARGE_NORMAL }, + { POWER_SUPPLY_TYPE_USB_FLOAT, QUICK_CHARGE_NORMAL }, + { POWER_SUPPLY_TYPE_USB_PD, QUICK_CHARGE_FAST }, + { POWER_SUPPLY_TYPE_USB_HVDCP, QUICK_CHARGE_FAST }, + { POWER_SUPPLY_TYPE_USB_HVDCP_3, QUICK_CHARGE_FAST }, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + { POWER_SUPPLY_TYPE_USB_HVDCP_3P5, QUICK_CHARGE_FLASH }, +#endif + { POWER_SUPPLY_TYPE_WIRELESS, QUICK_CHARGE_FAST }, + {0, 0}, +}; - smblib_set_charge_param(chg, - &chg->param.aicl_5v_threshold, - chg->aicl_5v_threshold_mv); - smblib_set_charge_param(chg, - &chg->param.aicl_cont_threshold, - chg->aicl_cont_threshold_mv); - chg->aicl_max_reached = false; +int smblib_get_quick_charge_type(struct smb_charger *chg) +{ + int i = 0, rc; + union power_supply_propval pval = {0, }; - if (chg->chg_param.smb_version == PMI632_SUBTYPE) - schgm_flash_torch_priority(chg, - TORCH_BUCK_MODE); + if (!chg) { + dev_err(chg->dev, "get quick charge type faied\n"); + return -EINVAL; + } - data = chg->irq_info[USBIN_UV_IRQ].irq_data; - if (data) { - wdata = &data->storm_data; - reset_storm_count(wdata); - } - vote(chg->usb_icl_votable, AICL_THRESHOLD_VOTER, - false, 0); - } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + rc = smblib_get_prop_batt_health(chg, &pval); + if (rc < 0) + smblib_err(chg, "Couldn't get batt health rc=%d\n", rc); - rc = smblib_request_dpdm(chg, false); - if (rc < 0) - smblib_err(chg, "Couldn't disable DPDM rc=%d\n", rc); + if ((pval.intval == POWER_SUPPLY_HEALTH_COLD) + || (pval.intval == POWER_SUPPLY_HEALTH_OVERHEAT)) + return 0; - smblib_update_usb_type(chg); + /* davinic do not need to report this type */ + if ((chg->real_charger_type == POWER_SUPPLY_TYPE_USB_PD) + && chg->pd_verifed && chg->qc_class_ab) { + return QUICK_CHARGE_TURBE; } - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) - smblib_micro_usb_plugin(chg, vbus_rising); - - vote(chg->temp_change_irq_disable_votable, DEFAULT_VOTER, - !vbus_rising, 0); + if (chg->is_qc_class_b || chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) + return QUICK_CHARGE_FLASH; - power_supply_changed(chg->usb_psy); - if (chg->dual_role) - dual_role_instance_changed(chg->dual_role); - smblib_dbg(chg, PR_INTERRUPT, "IRQ: usbin-plugin %s\n", - vbus_rising ? "attached" : "detached"); -} + if ((chg->real_charger_type == POWER_SUPPLY_TYPE_USB_DCP) && chg->hvdcp_recheck_status) + return QUICK_CHARGE_FAST; +#else + rc = smblib_get_prop_batt_status(chg, &pval); + if (rc < 0) + return -EINVAL; -irqreturn_t usb_plugin_irq_handler(int irq, void *data) -{ - struct smb_irq_data *irq_data = data; - struct smb_charger *chg = irq_data->parent_data; + if (pval.intval == POWER_SUPPLY_STATUS_DISCHARGING) + return 0; - if (chg->pd_hard_reset) - smblib_usb_plugin_hard_reset_locked(chg); - else - smblib_usb_plugin_locked(chg); + if ((chg->real_charger_type == POWER_SUPPLY_TYPE_USB_PD) && chg->pd_verifed) { + return QUICK_CHARGE_FLASH; + } - return IRQ_HANDLED; -} + if (chg->is_qc_class_b) + return QUICK_CHARGE_FLASH; +#endif -static void smblib_handle_slow_plugin_timeout(struct smb_charger *chg, - bool rising) -{ - smblib_dbg(chg, PR_INTERRUPT, "IRQ: slow-plugin-timeout %s\n", - rising ? "rising" : "falling"); -} + while (adapter_cap[i].adap_type != 0) { + if (chg->real_charger_type == adapter_cap[i].adap_type) { + return adapter_cap[i].adap_cap; + } + i++; + } -static void smblib_handle_sdp_enumeration_done(struct smb_charger *chg, - bool rising) -{ - smblib_dbg(chg, PR_INTERRUPT, "IRQ: sdp-enumeration-done %s\n", - rising ? "rising" : "falling"); + return 0; } +#endif -#define APSD_EXTENDED_TIMEOUT_MS 400 /* triggers when HVDCP 3.0 authentication has finished */ static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg, bool rising) @@ -5400,12 +8310,98 @@ static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg, if (!rising) return; +#ifdef CONFIG_MACH_XIAOMI_NABU + if (chg->qc3p5_supported) { + /* Run QC3P5 Authentication */ + if (!chg->qc3p5_authentication_started) { + rc = qc3p5_authenticate(chg); + if (rc < 0) { + chg->qc3p5_authenticated = false; + dev_err(chg->dev, "QC3.5 Authentication Failed, rc=%d\n", rc); + } + chg->qc3p5_auth_complete = true; + /* Release 500mA QC3.5 Authentication vote */ + vote(chg->usb_icl_votable, QC3P5_VOTER, false, 0); + } + smblib_update_usb_type(chg); + } +#endif + if (chg->mode == PARALLEL_MASTER) vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, true, 0); /* the APSD done handler will set the USB supply type */ apsd_result = smblib_get_apsd_result(chg); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* for QC3, switch to CP if present */ + if ((apsd_result->bit & QC_3P0_BIT) + && (chg->sec_cp_present || chg->use_bq_pump)) { + if (!chg->qc_class_ab) { + rc = smblib_select_sec_charger(chg, POWER_SUPPLY_CHARGER_SEC_CP, + POWER_SUPPLY_CP_HVDCP3, false); + if (rc < 0) + dev_err(chg->dev, + "Couldn't enable secondary chargers rc=%d\n", rc); + } else { + if (!chg->detect_low_power_qc3_charger && + (!chg->qc3p5_supported || !chg->qc3p5_authenticated)) { + if (!chg->use_bq_pump) + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, + HVDCP_START_CURRENT_UA); + else { + vote(chg->usb_icl_votable, HVDCP3_START_ICL_VOTER, true, + HVDCP_START_CURRENT_UA_FOR_BQ); + } + schedule_delayed_work(&chg->raise_qc3_vbus_work, 0); + chg->detect_low_power_qc3_charger = true; + } + } + /* start six pin battery step charge monitor work */ + if (chg->six_pin_step_charge_enable) { + if (!chg->already_start_step_charge_work) { + schedule_delayed_work(&chg->six_pin_batt_step_chg_work, + msecs_to_jiffies(STEP_CHG_DELAYED_START_MS)); + chg->already_start_step_charge_work = true; + } + } + } else if ((apsd_result->bit & QC_2P0_BIT) + && (!chg->qc2_unsupported)) { + pr_info("force 9V for QC2 charger\n"); + rc = smblib_force_vbus_voltage(chg, FORCE_9V_BIT); + if (rc < 0) + pr_err("Failed to force 9V\n"); + + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, + HVDCP2_CURRENT_UA); + } +#elif defined(CONFIG_MACH_XIAOMI_SM8150) + /* for QC3, switch to CP if present */ + if ((apsd_result->bit & QC_3P0_BIT) && chg->sec_cp_present) { + if (!chg->qc_class_ab) { + rc = smblib_select_sec_charger(chg, POWER_SUPPLY_CHARGER_SEC_CP, + POWER_SUPPLY_CP_HVDCP3, false); + if (rc < 0) + dev_err(chg->dev, + "Couldn't enable secondary chargers rc=%d\n", rc); + } else { + if (!chg->detect_low_power_qc3_charger) { + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, + HVDCP_START_CURRENT_UA); + schedule_delayed_work(&chg->raise_qc3_vbus_work, 0); + chg->detect_low_power_qc3_charger = true; + } + } + } else if (apsd_result->bit & QC_2P0_BIT + && !chg->qc2_unsupported) { + pr_info("force 9V for QC2 charger\n"); + rc = smblib_force_vbus_voltage(chg, FORCE_9V_BIT); + if (rc < 0) + pr_err("Failed to force 9V\n"); + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, + HVDCP2_CURRENT_UA); + } +#else if (apsd_result->bit & QC_3P0_BIT) { /* for QC3, switch to CP if present */ if (chg->sec_cp_present) { @@ -5430,6 +8426,7 @@ static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg, + jiffies); } } +#endif smblib_dbg(chg, PR_INTERRUPT, "IRQ: hvdcp-3p0-auth-done rising; %s detected\n", apsd_result->name); @@ -5446,8 +8443,40 @@ static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg, CHARGER_TYPE_VOTER, false, 0); vote(chg->hdc_irq_disable_votable, CHARGER_TYPE_VOTER, false, 0); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (!chg->raise_vbus_to_detect + && chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3P5) { + if (chg->is_qc_class_a) { + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, // git + HVDCP_CLASS_A_MAX_UA); + } else if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP) { + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, // git + HVDCP2_CURRENT_UA); + } else { + if (chg->six_pin_step_charge_enable || chg->use_bq_pump) + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, // git + HVDCP_CLASS_B_CURRENT_UA); + else + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, // git + HVDCP_CLASS_A_FOR_CP_UA); + } + } +#elif defined(CONFIG_MACH_XIAOMI_SM8150) + if (!chg->raise_vbus_to_detect) { + if (chg->is_qc_class_a) + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, // git + HVDCP_CLASS_A_MAX_UA); + else if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP) + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, // git + HVDCP2_CURRENT_UA); + else + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, // git + HVDCP_CURRENT_UA); + } +#else vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, HVDCP_CURRENT_UA); +#endif } else { /* A plain DCP, enforce DCP ICL if specified */ vote(chg->usb_icl_votable, DCP_VOTER, @@ -5469,8 +8498,12 @@ static void smblib_handle_hvdcp_detect_done(struct smb_charger *chg, static void update_sw_icl_max(struct smb_charger *chg, int pst) { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + union power_supply_propval val = {0, }; +#else int typec_mode; int rp_ua; +#endif /* while PD is active it should have complete ICL control */ if (chg->pd_active) @@ -5485,9 +8518,13 @@ static void update_sw_icl_max(struct smb_charger *chg, int pst) * HVDCP 2/3, handled separately */ if (pst == POWER_SUPPLY_TYPE_USB_HVDCP +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + || pst == POWER_SUPPLY_TYPE_USB_HVDCP_3P5 +#endif || pst == POWER_SUPPLY_TYPE_USB_HVDCP_3) return; +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) /* TypeC rp med or high, use rp value */ typec_mode = smblib_get_prop_typec_mode(chg); if (typec_rp_med_high(chg, typec_mode)) { @@ -5495,10 +8532,14 @@ static void update_sw_icl_max(struct smb_charger *chg, int pst) vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, rp_ua); return; } +#endif /* rp-std or legacy, USB BC 1.2 */ switch (pst) { case POWER_SUPPLY_TYPE_USB: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + smblib_get_prop_usb_present(chg, &val); +#endif /* * USB_PSY will vote to increase the current to 500/900mA once * enumeration is done. @@ -5517,21 +8558,56 @@ static void update_sw_icl_max(struct smb_charger *chg, int pst) DCP_CURRENT_UA); else /* if flash is active force 500mA */ +#if !defined(CONFIG_MACH_XIAOMI_SM8150) || defined(CONFIG_MACH_XIAOMI_VAYU) vote(chg->usb_icl_votable, USB_PSY_VOTER, true, is_flash_active(chg) ? SDP_CURRENT_UA : SDP_100_MA); +#elif defined(CONFIG_MACH_XIAOMI_NABU) + vote(chg->usb_icl_votable, USB_PSY_VOTER, true, SDP_CURRENT_UA); +#else + vote(chg->usb_icl_votable, USB_PSY_VOTER, true, + is_flash_active(chg) ? + SDP_CURRENT_UA : USBIN_500MA); +#endif +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, false, 0); +#endif } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + else if ((chg->typec_mode == POWER_SUPPLY_TYPEC_NONE) && (val.intval == true)) + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, SDP_CURRENT_UA); + else +#endif vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, false, 0); break; case POWER_SUPPLY_TYPE_USB_CDP: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (is_client_vote_enabled(chg->usb_icl_votable, + USB_PSY_VOTER)) + vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0); +#endif vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, CDP_CURRENT_UA); break; case POWER_SUPPLY_TYPE_USB_DCP: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, DCP_CURRENT_UA); +#else +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + if (is_client_vote_enabled(chg->usb_icl_votable, + USB_PSY_VOTER)) + vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0); +#endif rp_ua = get_rp_based_dcp_current(chg, typec_mode); vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, rp_ua); +#endif break; case POWER_SUPPLY_TYPE_USB_FLOAT: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (is_client_vote_enabled(chg->usb_icl_votable, + USB_PSY_VOTER)) + vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0); +#endif /* * If DC_IN or uUSB is detected then vote * for DCP current. @@ -5547,8 +8623,16 @@ static void update_sw_icl_max(struct smb_charger *chg, int pst) * enumerate to check if this is a SDP and * appropriately set the current. */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (!chg->recheck_charger) +#endif vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, SDP_100_MA); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + else + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, + true, FLOAT_CHARGER_UA); +#endif break; case POWER_SUPPLY_TYPE_UNKNOWN: default: @@ -5558,6 +8642,20 @@ static void update_sw_icl_max(struct smb_charger *chg, int pst) } } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static void determine_thermal_current(struct smb_charger *chg) +{ + if (chg->system_temp_level > 0 + && chg->system_temp_level < (chg->thermal_levels - 1)) { + /* + * consider thermal limit only when it is active and not at + * the highest level + */ + smblib_therm_charging(chg); + } +} +#endif + static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising) { const struct apsd_result *apsd_result; @@ -5581,14 +8679,35 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising) smblib_notify_device_mode(chg, true); } } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* if floated charger is detected, and audio accessory set icl to 500 */ + if (chg->typec_mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, 500000); +#endif break; case OCP_CHARGER_BIT: case DCP_CHARGER_BIT: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (chg->typec_mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER){ + chg->real_charger_type = POWER_SUPPLY_TYPE_USB_FLOAT; + chg->usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_FLOAT; + if ((strcmp(get_effective_client(chg->usb_icl_votable), "OTG_VOTER") == 0) && + (get_effective_result(chg->usb_icl_votable) == 0)) + vote(chg->usb_icl_votable, OTG_VOTER, false, 0); + + if (get_client_vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER) != 500000) + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, 500000); + } +#endif break; default: break; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + determine_thermal_current(chg); +#endif + smblib_dbg(chg, PR_INTERRUPT, "IRQ: apsd-done rising; %s detected\n", apsd_result->name); } @@ -5599,6 +8718,10 @@ irqreturn_t usb_source_change_irq_handler(int irq, void *data) struct smb_charger *chg = irq_data->parent_data; int rc = 0; u8 stat; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (chg->fake_usb_insertion) + return IRQ_HANDLED; +#endif /* PD session is ongoing, ignore BC1.2 and QC detection */ if (chg->pd_active) @@ -5690,6 +8813,12 @@ enum alarmtimer_restart smblib_lpd_recheck_timer(struct alarm *alarm, chg->lpd_stage = LPD_STAGE_NONE; chg->lpd_reason = LPD_NONE; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (chg->support_liquid == true) { + schedule_work(&chg->lpd_disable_chg_work); + } +#endif + return ALARMTIMER_NORESTART; } @@ -5723,6 +8852,15 @@ static bool smblib_src_lpd(struct smb_charger *chg) break; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->typec_mode = smblib_get_prop_typec_mode(chg); + if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) + && (chg->support_liquid == true)) { + lpd_flag = false; + return lpd_flag; + } +#endif + if (lpd_flag) { chg->lpd_stage = LPD_STAGE_COMMIT; pval.intval = POWER_SUPPLY_TYPEC_PR_SINK; @@ -5731,6 +8869,19 @@ static bool smblib_src_lpd(struct smb_charger *chg) smblib_err(chg, "Couldn't write 0x%02x to TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n", pval.intval, rc); chg->lpd_reason = LPD_MOISTURE_DETECTED; + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->lpd_status = true; + + if (chg->support_liquid == true) { + vote(chg->usb_icl_votable, LIQUID_DETECTION_VOTER, true, 0); + if (chg->batt_psy) + power_supply_changed(chg->batt_psy); + } + alarm_start_relative(&chg->lpd_recheck_timer, + ms_to_ktime(15000)); +#endif + chg->moisture_present = true; alarm_start_relative(&chg->lpd_recheck_timer, ms_to_ktime(60000)); @@ -5757,7 +8908,36 @@ static void typec_src_fault_condition_cfg(struct smb_charger *chg, bool src) static void typec_sink_insertion(struct smb_charger *chg) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int rc = 0; + int usb_present = 0; + int typec_mode; + union power_supply_propval pval = {0, }; +#else int rc; +#endif + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = smblib_get_prop_usb_present(chg, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get usb present rc = %d\n", rc); + return; + } + + usb_present = pval.intval; + + typec_mode = smblib_get_prop_typec_mode(chg); + if (usb_present && typec_mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) { + chg->real_charger_type = POWER_SUPPLY_TYPE_USB_FLOAT; + chg->usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_FLOAT; + if (get_client_vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER) != 500000) + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, 500000); + vote(chg->usb_icl_votable, OTG_VOTER, false, 0); + power_supply_changed(chg->batt_psy); + } else { + vote(chg->usb_icl_votable, OTG_VOTER, true, 0); + } +#endif typec_src_fault_condition_cfg(chg, true); rc = smblib_set_charge_param(chg, &chg->param.freq_switcher, @@ -5813,6 +8993,9 @@ static void typec_sink_removal(struct smb_charger *chg) { int rc; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + vote(chg->usb_icl_votable, OTG_VOTER, false, 0); +#endif typec_src_fault_condition_cfg(chg, false); rc = smblib_set_charge_param(chg, &chg->param.freq_switcher, chg->chg_freq.freq_removal); @@ -5842,7 +9025,20 @@ static void typec_src_removal(struct smb_charger *chg) dev_err(chg->dev, "Couldn't disable secondary charger rc=%d\n", rc); +#ifdef CONFIG_MACH_XIAOMI_NABU + /* Reset QC3.5 Flag and power limit*/ + chg->qc3p5_authenticated = false; + chg->qc3p5_auth_complete = false; + chg->qc3p5_authentication_started = false; + chg->qc3p5_dp_tune_rapidly = false; + chg->qc3p5_power_limit_w = 18; +#endif + chg->qc3p5_detected = false; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->snk_debug_acc_detected = false; +#endif + typec_src_fault_condition_cfg(chg, false); smblib_hvdcp_detect_enable(chg, false); smblib_update_usb_type(chg); @@ -5859,6 +9055,15 @@ static void typec_src_removal(struct smb_charger *chg) } cancel_delayed_work_sync(&chg->pl_enable_work); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + cancel_delayed_work_sync(&chg->raise_qc3_vbus_work); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + cancel_delayed_work_sync(&chg->check_init_boot); +#endif +#endif +#ifdef CONFIG_MACH_XIAOMI_NABU + cancel_delayed_work_sync(&chg->check_vbat_work); +#endif /* reset input current limit voters */ vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, @@ -5867,10 +9072,16 @@ static void typec_src_removal(struct smb_charger *chg) vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0); vote(chg->usb_icl_votable, DCP_VOTER, false, 0); vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + vote(chg->usb_icl_votable, OTG_VOTER, false, 0); +#endif vote(chg->usb_icl_votable, CTM_VOTER, false, 0); vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, false, 0); vote(chg->usb_icl_votable, CHG_TERMINATION_VOTER, false, 0); vote(chg->usb_icl_votable, THERMAL_THROTTLE_VOTER, false, 0); +#ifdef CONFIG_MACH_XIAOMI_NABU + vote(chg->usb_icl_votable, QC3P5_VOTER, false, 0); +#endif /* reset usb irq voters */ vote(chg->limited_irq_disable_votable, CHARGER_TYPE_VOTER, @@ -5884,6 +9095,28 @@ static void typec_src_removal(struct smb_charger *chg) vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, false, 0); vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0); vote(chg->awake_votable, PL_DELAY_VOTER, false, 0); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* reset our own voters */ + /* clear chg_awake wakeup source when typec removal */ + vote(chg->awake_votable, CHG_AWAKE_VOTER, false, 0); + vote(chg->fcc_votable, CLASSA_QC_FCC_VOTER, false, 0); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + vote(chg->fcc_votable, PD_REMOVE_COMP_VOTER, false, 0); + vote(chg->fcc_votable, PD_VERIFED_VOTER, true, PD_UNVERIFED_CURRENT); +#endif + vote(chg->usb_icl_votable, QC_A_CP_ICL_MAX_VOTER, false, 0); + vote(chg->usb_icl_votable, QC2_UNSUPPORTED_VOTER, false, 0); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump) { + vote(chg->usb_icl_votable, HVDCP3_START_ICL_VOTER, false, 0); + vote(chg->usb_icl_votable, MAIN_CHG_VOTER, false, 0); + vote(chg->fcc_votable, SLOWLY_CHARGING_VOTER, false, 0); + } +#endif +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + vote(chg->usb_icl_votable, PD_VERIFED_VOTER, false, 0); +#endif +#endif /* Remove SW thermal regulation WA votes */ vote(chg->usb_icl_votable, SW_THERM_REGULATION_VOTER, false, 0); @@ -5905,8 +9138,26 @@ static void typec_src_removal(struct smb_charger *chg) chg->usbin_forced_max_uv = 0; chg->chg_param.forced_main_fcc = 0; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->six_pin_step_charge_enable) { + chg->init_start_vbat_checked = false; + chg->already_start_step_charge_work = false; + chg->trigger_taper_count = 0; + chg->index_vfloat = 0; + vote(chg->fv_votable, SIX_PIN_VFLOAT_VOTER, false, 0); + vote(chg->fcc_votable, SIX_PIN_VFLOAT_VOTER, false, 0); + cancel_delayed_work_sync(&chg->six_pin_batt_step_chg_work); + } +#endif +#ifdef CONFIG_MACH_XIAOMI_NABU + vote(chg->fv_votable, BATT_BQ2597X_VOTER, false, 0); +#endif + /* Reset CC mode votes */ vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0); +#ifdef CONFIG_MACH_XIAOMI_NABU + vote(chg->fcc_votable, FCC_MAX_QC3P5_VOTER, false, 0); +#endif chg->adapter_cc_mode = 0; chg->thermal_overheat = 0; vote_override(chg->fcc_votable, CC_MODE_VOTER, false, 0); @@ -5920,6 +9171,13 @@ static void typec_src_removal(struct smb_charger *chg) if (rc < 0) smblib_err(chg, "Couldn't write float charger options rc=%d\n", rc); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->qc_class_ab) { + rc = smblib_force_vbus_voltage(chg, FORCE_5V_BIT); + if (rc < 0) + pr_err("Failed to force 5V\n"); + } +#endif if (!chg->pr_swap_in_progress) { rc = smblib_usb_pd_adapter_allowance_override(chg, FORCE_NULL); @@ -5958,10 +9216,51 @@ static void typec_src_removal(struct smb_charger *chg) if (chg->use_extcon) smblib_notify_device_mode(chg, false); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->support_ffc) { + if (smblib_get_fastcharge_mode(chg) == 1) + smblib_set_fastcharge_mode(chg, false); + /* if support ffc, default vfloat set back to 4.4V when typec removal */ + vote(chg->fv_votable, NON_FFC_VFLOAT_VOTER, + true, NON_FFC_VFLOAT_UV); + } + + /* when src removal, set bark timer back to default 16s */ + smblib_set_wdog_bark_timer(chg, BARK_TIMER_NORMAL); +#endif + chg->typec_legacy = false; del_timer_sync(&chg->apsd_timer); chg->apsd_ext_timeout = false; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->detect_low_power_qc3_charger = false; + chg->raise_vbus_to_detect = false; + chg->is_qc_class_a = false; + chg->is_qc_class_b = false; + chg->high_vbus_detected = false; + chg->qc2_unsupported = false; + chg->cc_un_compliant_detected = false; + chg->recheck_charger = false; + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->slowly_charging = false; + chg->pps_thermal_level = -EINVAL; +#endif +#ifdef CONFIG_MACH_XIAOMI_NABU + fv_over_limit_times = 0; +#endif + pr_err("%s:", __func__); + if (chg->pd_verifed) { + chg->pd_verifed = false; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->support_ffc) { + if (smblib_get_fastcharge_mode(chg) == true) + smblib_set_fastcharge_mode(chg, false); + } +#endif + } +#endif } static void typec_mode_unattached(struct smb_charger *chg) @@ -6144,6 +9443,11 @@ irqreturn_t typec_attach_detach_irq_handler(int irq, void *data) if (attached) { smblib_lpd_clear_ra_open_work(chg); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (chg->lpd_status) + chg->lpd_status = false; +#endif + rc = smblib_read(chg, TYPE_C_MISC_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read TYPE_C_MISC_STATUS_REG rc=%d\n", @@ -6163,6 +9467,9 @@ irqreturn_t typec_attach_detach_irq_handler(int irq, void *data) } else { chg->sink_src_mode = SINK_MODE; typec_src_insertion(chg); +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + smblib_wireless_set_enable(chg, false); +#endif } if (chg->typec_role_swap_failed) { @@ -6180,6 +9487,9 @@ irqreturn_t typec_attach_detach_irq_handler(int irq, void *data) case SINK_MODE: case AUDIO_ACCESS_MODE: typec_src_removal(chg); +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + smblib_wireless_set_enable(chg, true); +#endif break; case UNATTACHED_MODE: default: @@ -6205,24 +9515,90 @@ irqreturn_t typec_attach_detach_irq_handler(int irq, void *data) } } - if (chg->lpd_stage == LPD_STAGE_FLOAT_CANCEL) - schedule_delayed_work(&chg->lpd_detach_work, - msecs_to_jiffies(1000)); - } + if (chg->lpd_stage == LPD_STAGE_FLOAT_CANCEL) + schedule_delayed_work(&chg->lpd_detach_work, + msecs_to_jiffies(1000)); + } + + rc = smblib_masked_write(chg, USB_CMD_PULLDOWN_REG, + EN_PULLDOWN_USB_IN_BIT, + attached ? 0 : EN_PULLDOWN_USB_IN_BIT); + if (rc < 0) + smblib_err(chg, "Couldn't configure pulldown on USB_IN rc=%d\n", + rc); + + power_supply_changed(chg->usb_psy); + if (chg->dual_role) + dual_role_instance_changed(chg->dual_role); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_MACH_XIAOMI_NABU +/*add for wireless reverse charge to disable dc*/ +int smblib_set_sw_disable_dc_en(struct smb_charger *chg, + const union power_supply_propval *val) +{ + int rc = 0; + + if (val->intval) { + /* step1: enter dc suspend */ + rc = vote(chg->dc_suspend_votable, SW_DISABLE_DC_VOTER, + true, 0); + + /* step2: force dcin_en low */ + rc = smblib_masked_write(chg, DCIN_CMD_IL_REG, + DCIN_EN_OVERRIDE_BIT | DCIN_EN_BIT, + DCIN_EN_OVERRIDE_BIT); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure dc_en override rc=%d\n", rc); + return rc; + } + + /* step3: enable pull-down on dcin_pon and mid_chg */ + rc = smblib_masked_write(chg, DCIN_CMD_PULLDOWN_REG, + DCIN_PULLDOWN_EN_BIT | DCIN_MID_PULLDOWN_BIT, + DCIN_PULLDOWN_EN_BIT | DCIN_MID_PULLDOWN_BIT); + if (rc < 0) { + dev_err(chg->dev, "Couldn't enable dcin_pulldown rc=%d\n", rc); + return rc; + } + /* wait 10ms to pull mid_chg lower than Vsys+Vrevi */ + msleep(10); + + /* step4: exit dc suspend */ + rc = vote(chg->dc_suspend_votable, SW_DISABLE_DC_VOTER, + false, 0); + } else { + /* step1: enter dc suspend */ + rc = vote(chg->dc_suspend_votable, SW_DISABLE_DC_VOTER, + true, 0); - rc = smblib_masked_write(chg, USB_CMD_PULLDOWN_REG, - EN_PULLDOWN_USB_IN_BIT, - attached ? 0 : EN_PULLDOWN_USB_IN_BIT); - if (rc < 0) - smblib_err(chg, "Couldn't configure pulldown on USB_IN rc=%d\n", - rc); + /* step2: force dcin_en low */ + rc = smblib_masked_write(chg, DCIN_CMD_IL_REG, + DCIN_EN_OVERRIDE_BIT, 0); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure dc_en override rc=%d\n", rc); + return rc; + } - power_supply_changed(chg->usb_psy); - if (chg->dual_role) - dual_role_instance_changed(chg->dual_role); + /* step3: enable pull-down on dcin_pon and mid_chg */ + rc = smblib_masked_write(chg, DCIN_CMD_PULLDOWN_REG, + DCIN_PULLDOWN_EN_BIT | DCIN_MID_PULLDOWN_BIT, 0); + if (rc < 0) { + dev_err(chg->dev, "Couldn't disable dcin_pulldown rc=%d\n", rc); + return rc; + } + /* wait 10ms to pull mid_chg lower than Vsys+Vrevi */ + msleep(10); + /* step4: exit dc suspend */ + rc = vote(chg->dc_suspend_votable, SW_DISABLE_DC_VOTER, + false, 0); + } - return IRQ_HANDLED; + return 0; } +#endif static void dcin_aicl(struct smb_charger *chg) { @@ -6369,14 +9745,160 @@ irqreturn_t dcin_uv_irq_handler(int irq, void *data) return IRQ_HANDLED; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static int smblib_get_wireless_output_vol(struct smb_charger *chg) +{ + + int rc,wireless_vout = 0; + + rc = iio_read_channel_processed(chg->iio.vph_v_chan, + &wireless_vout); + if (rc < 0) { + smblib_err(chg, "Couldn't get vph vol rc = %d\n", + rc); + return -ENODATA; + } + wireless_vout *= 2; + wireless_vout /= 100000; + wireless_vout *= 100000; + + return wireless_vout; + +} + +int smblib_set_wirless_cp_enable(struct smb_charger *chg, + const union power_supply_propval *val) +{ + union power_supply_propval pval; + int wireless_vout = 0; + int rc; + + wireless_vout = smblib_get_wireless_output_vol(chg); + if (wireless_vout < 0) { + dev_err(chg->dev, "Couldn't get vph_pwr wireless_vout=%d\n", + wireless_vout); + return -ENODATA; + } + + if (chg->flag_dc_present && val->intval) { + pval.intval = wireless_vout; + rc = smblib_set_prop_voltage_wls_output(chg, &pval); + if (rc < 0) + dev_err(chg->dev, "Couldn't set dc voltage to 2*vph rc=%d\n", + rc); + + rc = smblib_select_sec_charger(chg, POWER_SUPPLY_CHARGER_SEC_CP, + POWER_SUPPLY_CP_WIRELESS, false); + if (rc < 0) + dev_err(chg->dev, + "Couldn't enable secondary chargers rc=%d\n", rc); + } else + smblib_dbg(chg, PR_WLS, "dcin_not present or usbin_present\n"); + + return 0; +} + +int smblib_set_wirless_power_good_enable(struct smb_charger *chg, + const union power_supply_propval *val) +{ + int rc = 0; + + chg->power_good_en = val->intval; + if (chg->power_good_en) { + chg->fake_dc_on = 1; + chg->fake_dc_flag = 0; + chg->last_batt_stat = 0; + cancel_delayed_work(&chg->dc_plug_out_delay_work); + vote(chg->awake_votable, DC_UV_AWAKE_VOTER, false, 0); + + } + else { + if (!chg->fake_dc_flag) + chg->fake_dc_on = 0; + /* step1: enter dc suspend */ + rc = vote(chg->dc_suspend_votable, OTG_VOTER, + true, 0); + + /* step2: force dcin_en low */ + rc = smblib_masked_write(chg, DCIN_CMD_IL_REG, + DCIN_EN_OVERRIDE_BIT | DCIN_EN_BIT, + DCIN_EN_OVERRIDE_BIT); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure dc_en override rc=%d\n", rc); + return rc; + } + + /* step3: enable pull-down on dcin_pon and mid_chg */ + rc = smblib_masked_write(chg, DCIN_CMD_PULLDOWN_REG, + DCIN_PULLDOWN_EN_BIT | DCIN_MID_PULLDOWN_BIT, + DCIN_PULLDOWN_EN_BIT | DCIN_MID_PULLDOWN_BIT); + if (rc < 0) { + dev_err(chg->dev, "Couldn't enable dcin_pulldown rc=%d\n", rc); + return rc; + } + /* wait 10ms to pull mid_chg lower than Vsys+Vrevi */ + msleep(10); + + /* step4: disable pull-down on dcin_pon and mid_chg */ + rc = smblib_masked_write(chg, DCIN_CMD_PULLDOWN_REG, + DCIN_PULLDOWN_EN_BIT | DCIN_MID_PULLDOWN_BIT, + 0); + if (rc < 0) { + dev_err(chg->dev, "Couldn't disable dcin_pulldown rc=%d\n", rc); + return rc; + } + + /* step5: remove dcin_en low */ + rc = smblib_masked_write(chg, DCIN_CMD_IL_REG, + DCIN_EN_OVERRIDE_BIT | DCIN_EN_BIT, + 0); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure dc_en override rc=%d\n", rc); + return rc; + } + + /* step6: exit dc suspend */ + rc = vote(chg->dc_suspend_votable, OTG_VOTER, + false, 0); + } + power_supply_changed(chg->dc_psy); + power_supply_changed(chg->batt_psy); + if (chg->wls_psy) + power_supply_changed(chg->wls_psy); + + return 0; +} + +static void smblib_dc_plug_out_work(struct work_struct *work) +{ + struct smb_charger *chg = container_of(work, struct smb_charger, + dc_plug_out_delay_work.work); + + chg->fake_dc_on = 0; /*use for delay 1.8s*/ + chg->fake_dc_flag = 0; + chg->last_batt_stat = 0; + power_supply_changed(chg->dc_psy); + smblib_dbg(chg, PR_WLS, "Delay timeout and clear dc fake value\n"); + vote(chg->awake_votable, DC_UV_AWAKE_VOTER, false, 0); +} +#endif + irqreturn_t dc_plugin_irq_handler(int irq, void *data) { struct smb_irq_data *irq_data = data; struct smb_charger *chg = irq_data->parent_data; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + union power_supply_propval pval = {0, }; +#else union power_supply_propval pval; +#endif int input_present; bool dcin_present, vbus_present; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int rc; +#else int rc, wireless_vout = 0; +#endif int sec_charger; rc = smblib_get_prop_vph_voltage_now(chg, &pval); @@ -6384,15 +9906,33 @@ irqreturn_t dc_plugin_irq_handler(int irq, void *data) return IRQ_HANDLED; /* 2*VPH, with a granularity of 100mV */ +#ifndef CONFIG_MACH_XIAOMI_SM8150 wireless_vout = ((pval.intval * 2) / 100000) * 100000; +#endif rc = smblib_is_input_present(chg, &input_present); if (rc < 0) return IRQ_HANDLED; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->idtp_psy = power_supply_get_by_name("idt"); + if (!chg->idtp_psy) + dev_err(chg->dev, "Could not get idtp psy\n"); +#endif + dcin_present = input_present & INPUT_PRESENT_DC; vbus_present = input_present & INPUT_PRESENT_USB; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* when dcin present and in otg mode, set vbus present to 0*/ + if (smblib_get_prop_dfp_mode(chg) != POWER_SUPPLY_TYPEC_NONE + && smblib_get_prop_dfp_mode(chg) + != POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER + && dcin_present) + vbus_present = 0; +#endif + +#ifndef CONFIG_MACH_XIAOMI_SM8150 if (dcin_present && !vbus_present) { cancel_work_sync(&chg->dcin_aicl_work); @@ -6448,9 +9988,123 @@ irqreturn_t dc_plugin_irq_handler(int irq, void *data) chg->last_wls_vout = 0; } +#elif defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (dcin_present) { + if (!vbus_present && chg->sec_cp_present) { + chg->flag_dc_present = 1; + vote(chg->awake_votable, DC_AWAKE_VOTER, true, 0); + if (chg->idtp_psy) { + pval.intval = true; + power_supply_set_property(chg->idtp_psy, + POWER_SUPPLY_PROP_PRESENT, &pval); + } + /* when dc_in plug in, enable batt_temp irq wakeup */ + if (chg->irq_info[BAT_TEMP_IRQ].irq && !chg->batt_temp_irq_enabled) { + enable_irq_wake(chg->irq_info[BAT_TEMP_IRQ].irq); + chg->batt_temp_irq_enabled = true; + } + } + + schedule_work(&chg->dcin_aicl_work); + } else { + /* when dc_in plug out, disable batt_temp irq wakeup */ + if (chg->irq_info[BAT_TEMP_IRQ].irq && chg->batt_temp_irq_enabled) { + disable_irq_wake(chg->irq_info[BAT_TEMP_IRQ].irq); + chg->batt_temp_irq_enabled = false; + } + /* when dc plug out, set bark timer back to default 16s */ + smblib_set_wdog_bark_timer(chg, BARK_TIMER_NORMAL); + vote(chg->awake_votable, DC_AWAKE_VOTER, false, 0); + vote(chg->dc_icl_votable, DCIN_ADAPTER_VOTER, true, 100000); + chg->flag_dc_present = 0; + chg->cp_reason = POWER_SUPPLY_CP_NONE; + sec_charger = chg->sec_pl_present ? + POWER_SUPPLY_CHARGER_SEC_PL : + POWER_SUPPLY_CHARGER_SEC_NONE; + rc = smblib_select_sec_charger(chg, sec_charger, + POWER_SUPPLY_CP_NONE, false); + + if (rc < 0) + dev_err(chg->dev, + "Couldn't disable secondary charger rc=%d\n", + rc); + + if (chg->idtp_psy) { + pval.intval = false; + power_supply_set_property(chg->idtp_psy, + POWER_SUPPLY_PROP_PRESENT, &pval); + } + + if (chg->cp_reason == POWER_SUPPLY_CP_WIRELESS) { + sec_charger = chg->sec_pl_present ? + POWER_SUPPLY_CHARGER_SEC_PL : + POWER_SUPPLY_CHARGER_SEC_NONE; + rc = smblib_select_sec_charger(chg, sec_charger, + POWER_SUPPLY_CP_NONE, false); + if (rc < 0) + dev_err(chg->dev, "Couldn't disable secondary charger rc=%d\n", + rc); + } + + vote(chg->dc_suspend_votable, CHG_TERMINATION_VOTER, false, 0); + + chg->last_wls_vout = 0; + } +#else + if (dcin_present) { + if (!vbus_present && chg->sec_cp_present) { + chg->flag_dc_present = 1; + vote(chg->awake_votable, DC_AWAKE_VOTER, true, 0); + if (chg->idtp_psy) { + pval.intval = true; + power_supply_set_property(chg->idtp_psy, + POWER_SUPPLY_PROP_PRESENT, &pval); + } + } + } else { + vote(chg->awake_votable, DC_AWAKE_VOTER, false, 0); + vote(chg->dc_icl_votable, DCIN_ADAPTER_VOTER, true, 100000); + chg->flag_dc_present = 0; + chg->cp_reason = POWER_SUPPLY_CP_NONE; + sec_charger = chg->sec_pl_present ? + POWER_SUPPLY_CHARGER_SEC_PL : + POWER_SUPPLY_CHARGER_SEC_NONE; + rc = smblib_select_sec_charger(chg, sec_charger, + POWER_SUPPLY_CP_NONE, false); + + if (rc < 0) + dev_err(chg->dev, + "Couldn't disable secondary charger rc=%d\n", + rc); + + if (chg->idtp_psy) { + pval.intval = false; + power_supply_set_property(chg->idtp_psy, + POWER_SUPPLY_PROP_PRESENT, &pval); + } + + if (chg->cp_reason == POWER_SUPPLY_CP_WIRELESS) { + sec_charger = chg->sec_pl_present ? + POWER_SUPPLY_CHARGER_SEC_PL : + POWER_SUPPLY_CHARGER_SEC_NONE; + rc = smblib_select_sec_charger(chg, sec_charger, + POWER_SUPPLY_CP_NONE, false); + if (rc < 0) + dev_err(chg->dev, "Couldn't disable secondary charger rc=%d\n", + rc); + } + + vote(chg->dc_suspend_votable, CHG_TERMINATION_VOTER, false, 0); + } +#endif power_supply_changed(chg->dc_psy); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (chg->wls_psy) + power_supply_changed(chg->wls_psy); +#endif + smblib_dbg(chg, (PR_WLS | PR_INTERRUPT), "dcin_present= %d, usbin_present= %d, cp_reason = %d\n", dcin_present, vbus_present, chg->cp_reason); @@ -6574,6 +10228,11 @@ irqreturn_t wdog_bark_irq_handler(int irq, void *data) if (rc < 0) smblib_err(chg, "Couldn't pet the dog rc=%d\n", rc); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (chg->step_chg_enabled || chg->sw_jeita_enabled) + power_supply_changed(chg->batt_psy); +#endif + return IRQ_HANDLED; } @@ -6618,6 +10277,102 @@ static void smblib_usbov_dbc_work(struct work_struct *work) vote(chg->awake_votable, USBOV_DBC_VOTER, false, 0); } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static int smblib_get_step_vfloat_index(struct smb_charger *chg, + int val) +{ + int i; + + /* select correct index by compare start_vbat and range vfloat threshold */ + for (i = 0; i <= ARRAY_SIZE(chg->six_pin_step_cfg) - 1; i++) { + if (val < (chg->six_pin_step_cfg[i].vfloat_step_uv - VBAT_FOR_STEP_HYS_UV)) + break; + } + + if (i >= ARRAY_SIZE(chg->six_pin_step_cfg) - 1) + return ARRAY_SIZE(chg->six_pin_step_cfg) - 1; + + return i; +} + +static void smblib_six_pin_batt_step_chg_work(struct work_struct *work) +{ + struct smb_charger *chg = container_of(work, struct smb_charger, + six_pin_batt_step_chg_work.work); + + int rc = 0; + int input_present; + int main_charge_type; + int interval_ms = STEP_CHG_DELAYED_MONITOR_MS; + union power_supply_propval pval = {0, }; + + rc = smblib_is_input_present(chg, &input_present); + if (rc < 0) + return; + + pr_err("input_present: %d\n", input_present); + if (input_present == INPUT_NOT_PRESENT) { + if (is_client_vote_enabled(chg->fv_votable, + SIX_PIN_VFLOAT_VOTER)) + vote(chg->fv_votable, SIX_PIN_VFLOAT_VOTER, false, 0); + if (is_client_vote_enabled(chg->fcc_votable, + SIX_PIN_VFLOAT_VOTER)) + vote(chg->fcc_votable, SIX_PIN_VFLOAT_VOTER, false, 0); + return; + } + + if (chg->start_step_vbat >= VBAT_FOR_STEP_MIN_UV) { + pr_err("start step vbat is too high, no need do step charge\n"); + return; + } + + /* set init start vfloat according to chg->start_step_vbat */ + if (!chg->init_start_vbat_checked) { + chg->index_vfloat = + smblib_get_step_vfloat_index(chg, chg->start_step_vbat); + vote(chg->fv_votable, SIX_PIN_VFLOAT_VOTER, + true, chg->six_pin_step_cfg[chg->index_vfloat].vfloat_step_uv); + vote(chg->fcc_votable, SIX_PIN_VFLOAT_VOTER, + true, chg->six_pin_step_cfg[chg->index_vfloat].fcc_step_ua); + chg->init_start_vbat_checked = true; + } + + rc = smblib_get_prop_batt_charge_type(chg, &pval); + if (rc < 0) { + pr_err("Couldn't get batt charge type rc=%d\n", rc); + return; + } + main_charge_type = pval.intval; + pr_err("main_charge_type: %d\n", main_charge_type); + + if (main_charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER) + chg->trigger_taper_count++; + else + chg->trigger_taper_count = 0; + + if (chg->trigger_taper_count >= MAX_COUNT_OF_IBAT_STEP) { + chg->index_vfloat++; + chg->trigger_taper_count = 0; + if (chg->index_vfloat < MAX_STEP_ENTRIES) { + vote(chg->fcc_votable, SIX_PIN_VFLOAT_VOTER, + true, chg->six_pin_step_cfg[chg->index_vfloat].fcc_step_ua); + vote(chg->fv_votable, SIX_PIN_VFLOAT_VOTER, + true, chg->six_pin_step_cfg[chg->index_vfloat].vfloat_step_uv); + } + if (chg->index_vfloat >= MAX_STEP_ENTRIES) + chg->index_vfloat = MAX_STEP_ENTRIES - 1; + } + + if (main_charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER) + interval_ms = STEP_CHG_DELAYED_QUICK_MONITOR_MS; + else + interval_ms = STEP_CHG_DELAYED_MONITOR_MS; + + schedule_delayed_work(&chg->six_pin_batt_step_chg_work, + msecs_to_jiffies(interval_ms)); +} +#endif + #define USB_OV_DBC_PERIOD_MS 1000 irqreturn_t usbin_ov_irq_handler(int irq, void *data) { @@ -7352,6 +11107,12 @@ static void jeita_update_work(struct work_struct *work) chg->jeita_soft_thlds[1] + SOFT_JEITA_HYSTERESIS_OFFSET; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* we still use old soft jeita method */ + chg->jeita_configured = JEITA_CFG_COMPLETE; + return; +#endif + chg->jeita_soft_fcc[0] = chg->jeita_soft_fcc[1] = -EINVAL; chg->jeita_soft_fv[0] = chg->jeita_soft_fv[1] = -EINVAL; max_fcc_ma = max_fv_uv = -EINVAL; @@ -7438,6 +11199,15 @@ static void smblib_lpd_ra_open_work(struct work_struct *work) if (!(stat & TYPEC_WATER_DETECTION_STATUS_BIT) || (stat & TYPEC_TCCDEBOUNCE_DONE_STATUS_BIT)) { chg->lpd_stage = LPD_STAGE_NONE; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->lpd_status = false; + + if (chg->support_liquid == true) { + vote(chg->usb_icl_votable, LIQUID_DETECTION_VOTER, false, 0); + if (chg->batt_psy) + power_supply_changed(chg->batt_psy); + } +#endif goto out; } @@ -7466,8 +11236,18 @@ static void smblib_lpd_ra_open_work(struct work_struct *work) } chg->lpd_reason = LPD_MOISTURE_DETECTED; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->lpd_status = true; +#endif chg->moisture_present = true; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (chg->support_liquid == true) { + vote(chg->usb_icl_votable, LIQUID_DETECTION_VOTER, true, 0); + if (chg->batt_psy) + power_supply_changed(chg->batt_psy); + } +#endif } else { /* Floating cable, disable water detection irq temporarily */ rc = smblib_masked_write(chg, TYPE_C_INTERRUPT_EN_CFG_2_REG, @@ -7491,11 +11271,27 @@ static void smblib_lpd_ra_open_work(struct work_struct *work) } /* recheck in 60 seconds */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + alarm_start_relative(&chg->lpd_recheck_timer, ms_to_ktime(15000)); +#else alarm_start_relative(&chg->lpd_recheck_timer, ms_to_ktime(60000)); +#endif out: vote(chg->awake_votable, LPD_VOTER, false, 0); } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static void smblib_lpd_disable_chg_work(struct work_struct *work) +{ + struct smb_charger *chg = container_of(work, struct smb_charger, + lpd_disable_chg_work); + + vote(chg->usb_icl_votable, LIQUID_DETECTION_VOTER, false, 0); + if (chg->batt_psy) + power_supply_changed(chg->batt_psy); +} +#endif + static void smblib_lpd_detach_work(struct work_struct *work) { struct smb_charger *chg = container_of(work, struct smb_charger, @@ -7505,6 +11301,55 @@ static void smblib_lpd_detach_work(struct work_struct *work) chg->lpd_stage = LPD_STAGE_NONE; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static void smblib_charger_type_recheck(struct work_struct *work) +{ + struct smb_charger *chg = container_of(work, struct smb_charger, + charger_type_recheck.work); + int recheck_time = TYPE_RECHECK_TIME_5S; + static int last_charger_type, check_count; + int rc; + smblib_update_usb_type(chg); + + if (last_charger_type != chg->real_charger_type) + check_count--; + last_charger_type = chg->real_charger_type; + + if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3 || +#ifdef CONFIG_MACH_XIAOMI_NABU + chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5 || +#endif + chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP || + chg->pd_active || (check_count >= TYPE_RECHECK_COUNT) || + ((chg->real_charger_type == POWER_SUPPLY_TYPE_USB_FLOAT) && + (chg->typec_mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER))) { + check_count = 0; + return; + } + + if (smblib_get_prop_dfp_mode(chg) != POWER_SUPPLY_TYPEC_NONE) + goto check_next; + + if (!chg->recheck_charger) + chg->precheck_charger_type = chg->real_charger_type; + chg->recheck_charger = true; + + if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_FLOAT) { + rc = smblib_request_dpdm(chg, false); + if (rc < 0) + smblib_err(chg, "Couldn't disable DPDM rc=%d\n", rc); + + msleep(500); + } + smblib_rerun_apsd_if_required(chg); + +check_next: + check_count++; + schedule_delayed_work(&chg->charger_type_recheck, + msecs_to_jiffies(recheck_time)); +} +#endif + static char *dr_mode_text[] = { "ufp", "dfp", "none" }; @@ -7600,6 +11445,39 @@ static void smblib_dual_role_check_work(struct work_struct *work) vote(chg->awake_votable, DR_SWAP_VOTER, false, 0); } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static void smblib_batt_verify_update_work(struct work_struct *work) +{ + struct smb_charger *chg = container_of(work, struct smb_charger, + batt_verify_update_work.work); + int rc; + union power_supply_propval pval = {0,}; + static int count; + + rc = power_supply_get_property(chg->bms_psy, + POWER_SUPPLY_PROP_AUTHENTIC, &pval); + if (rc < 0) { + pr_err("Couldn't get batt verify status rc=%d\n", rc); + } + chg->batt_verified = pval.intval; + pr_err("batt_verified =%d\n", chg->batt_verified); + if (chg->batt_verified) { + vote(chg->fcc_votable, BATT_VERIFY_VOTER, false, 0); + count = 0; + return; + } + if (count < 3) { + count ++; + pr_err("battery verify failed, we will recheck it!\n"); + schedule_delayed_work(&chg->batt_verify_update_work, + msecs_to_jiffies(3000)); + } else { + count = 0; + } + +} +#endif + static int smblib_create_votables(struct smb_charger *chg) { int rc = 0; @@ -7668,6 +11546,16 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->dc_icl_votable = create_votable("DC_ICL", VOTE_MIN, + smblib_dc_icl_vote_callback, + chg); + if (IS_ERR(chg->dc_icl_votable)) { + rc = PTR_ERR(chg->dc_icl_votable); + return rc; + } +#endif + chg->awake_votable = create_votable("AWAKE", VOTE_SET_ANY, smblib_awake_vote_callback, chg); @@ -7777,6 +11665,9 @@ int smblib_init(struct smb_charger *chg) INIT_WORK(&chg->pl_update_work, pl_update_work); INIT_WORK(&chg->jeita_update_work, jeita_update_work); INIT_WORK(&chg->dcin_aicl_work, dcin_aicl_work); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + INIT_WORK(&chg->lpd_disable_chg_work, smblib_lpd_disable_chg_work); +#endif INIT_DELAYED_WORK(&chg->clear_hdc_work, clear_hdc_work); INIT_DELAYED_WORK(&chg->icl_change_work, smblib_icl_change_work); INIT_DELAYED_WORK(&chg->pl_enable_work, smblib_pl_enable_work); @@ -7784,13 +11675,38 @@ int smblib_init(struct smb_charger *chg) INIT_DELAYED_WORK(&chg->bb_removal_work, smblib_bb_removal_work); INIT_DELAYED_WORK(&chg->lpd_ra_open_work, smblib_lpd_ra_open_work); INIT_DELAYED_WORK(&chg->lpd_detach_work, smblib_lpd_detach_work); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + INIT_DELAYED_WORK(&chg->batt_verify_update_work, smblib_batt_verify_update_work); +#endif + INIT_DELAYED_WORK(&chg->raise_qc3_vbus_work, smblib_raise_qc3_vbus_work); + INIT_DELAYED_WORK(&chg->charger_type_recheck, smblib_charger_type_recheck); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + INIT_DELAYED_WORK(&chg->six_pin_batt_step_chg_work, + smblib_six_pin_batt_step_chg_work); +#endif + INIT_DELAYED_WORK(&chg->cc_un_compliant_charge_work, + smblib_cc_un_compliant_charge_work); +#endif INIT_DELAYED_WORK(&chg->thermal_regulation_work, smblib_thermal_regulation_work); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + INIT_DELAYED_WORK(&chg->dc_plug_out_delay_work, smblib_dc_plug_out_work); +#endif INIT_DELAYED_WORK(&chg->usbov_dbc_work, smblib_usbov_dbc_work); INIT_DELAYED_WORK(&chg->role_reversal_check, smblib_dual_role_check_work); INIT_DELAYED_WORK(&chg->pr_swap_detach_work, smblib_pr_swap_detach_work); +#ifdef CONFIG_MACH_XIAOMI_NABU + INIT_DELAYED_WORK(&chg->check_vbat_work, smblib_check_vbat_work); +#endif +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chg->use_bq_pump) { + INIT_DELAYED_WORK(&chg->reduce_fcc_work, reduce_fcc_work); + INIT_DELAYED_WORK(&chg->thermal_setting_work, smblib_thermal_setting_work); + } +#endif INIT_DELAYED_WORK(&chg->pr_lock_clear_work, smblib_pr_lock_clear_work); if (chg->dcin_uusb_over_gpio_en) @@ -7799,6 +11715,10 @@ int smblib_init(struct smb_charger *chg) setup_timer(&chg->apsd_timer, apsd_timer_cb, (unsigned long)chg); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + INIT_DELAYED_WORK(&chg->report_soc_decimal_work, smblib_report_soc_decimal_work); + INIT_DELAYED_WORK(&chg->check_init_boot, smb_check_init_boot); +#endif if (chg->wa_flags & CHG_TERMINATION_WA) { INIT_WORK(&chg->chg_termination_work, smblib_chg_termination_work); @@ -7825,6 +11745,10 @@ int smblib_init(struct smb_charger *chg) } } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->pps_thermal_level = -EINVAL; +#endif + if (alarmtimer_get_rtcdev()) { alarm_init(&chg->dcin_aicl_alarm, ALARM_REALTIME, dcin_aicl_alarm_cb); @@ -7841,7 +11765,14 @@ int smblib_init(struct smb_charger *chg) chg->sec_chg_selected = POWER_SUPPLY_CHARGER_SEC_NONE; chg->cp_reason = POWER_SUPPLY_CP_NONE; chg->thermal_status = TEMP_BELOW_RANGE; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chg->batt_temp_irq_enabled = false; +#endif chg->dr_mode = DUAL_ROLE_PROP_MODE_NONE; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->esr_work_status = ESR_CHECK_FCC_NOLIMIT; + chg->hvdcp_recheck_status = false; +#endif chg->typec_irq_en = true; switch (chg->mode) { @@ -7870,6 +11801,9 @@ int smblib_init(struct smb_charger *chg) chg->bms_psy = power_supply_get_by_name("bms"); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chg->batt_verify_psy = power_supply_get_by_name("batt_verify"); +#endif if (chg->sec_pl_present) { chg->pl.psy = power_supply_get_by_name("parallel"); if (chg->pl.psy) { @@ -7947,10 +11881,28 @@ int smblib_deinit(struct smb_charger *chg) cancel_delayed_work_sync(&chg->bb_removal_work); cancel_delayed_work_sync(&chg->lpd_ra_open_work); cancel_delayed_work_sync(&chg->lpd_detach_work); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + cancel_delayed_work_sync(&chg->batt_verify_update_work); +#endif + cancel_delayed_work_sync(&chg->raise_qc3_vbus_work); + cancel_delayed_work_sync(&chg->charger_type_recheck); + cancel_delayed_work_sync(&chg->cc_un_compliant_charge_work); +#endif cancel_delayed_work_sync(&chg->thermal_regulation_work); cancel_delayed_work_sync(&chg->usbov_dbc_work); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + cancel_delayed_work_sync(&chg->six_pin_batt_step_chg_work); +#endif cancel_delayed_work_sync(&chg->role_reversal_check); cancel_delayed_work_sync(&chg->pr_swap_detach_work); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + cancel_delayed_work_sync(&chg->report_soc_decimal_work); + cancel_delayed_work_sync(&chg->check_init_boot); +#endif +#ifdef CONFIG_MACH_XIAOMI_NABU + cancel_delayed_work_sync(&chg->check_vbat_work); +#endif power_supply_unreg_notifier(&chg->nb); smblib_destroy_votables(chg); qcom_step_chg_deinit(); @@ -7967,3 +11919,16 @@ int smblib_deinit(struct smb_charger *chg) return 0; } + +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static int __init early_parse_off_charge_flag(char *p) +{ + if (p) { + if (!strcmp(p, "charger")) + off_charge_flag = true; + } + + return 0; +} +early_param("androidboot.mode", early_parse_off_charge_flag); +#endif diff --git a/drivers/power/supply/qcom/smb5-lib.h b/drivers/power/supply/qcom/smb5-lib.h index 72eb66100c27..07b19e0e8098 100644 --- a/drivers/power/supply/qcom/smb5-lib.h +++ b/drivers/power/supply/qcom/smb5-lib.h @@ -26,6 +26,12 @@ #include #include "storm-watch.h" #include "battery.h" +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#include +#include +#include +#include +#endif enum print_reason { PR_INTERRUPT = BIT(0), @@ -40,6 +46,9 @@ enum print_reason { #define USER_VOTER "USER_VOTER" #define PD_VOTER "PD_VOTER" #define DCP_VOTER "DCP_VOTER" +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define CP_VOTER "CP_VOTER" +#endif #define QC_VOTER "QC_VOTER" #define USB_PSY_VOTER "USB_PSY_VOTER" #define PL_TAPER_WORK_RUNNING_VOTER "PL_TAPER_WORK_RUNNING_VOTER" @@ -59,6 +68,12 @@ enum print_reason { #define SW_ICL_MAX_VOTER "SW_ICL_MAX_VOTER" #define PL_QNOVO_VOTER "PL_QNOVO_VOTER" #define QNOVO_VOTER "QNOVO_VOTER" +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define OTG_VOTER "OTG_VOTER" +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define SW_DISABLE_DC_VOTER "SW_DISABLE_DC_VOTER" +#endif +#endif #define BATT_PROFILE_VOTER "BATT_PROFILE_VOTER" #define OTG_DELAY_VOTER "OTG_DELAY_VOTER" #define USBIN_I_VOTER "USBIN_I_VOTER" @@ -66,12 +81,37 @@ enum print_reason { #define PL_FCC_LOW_VOTER "PL_FCC_LOW_VOTER" #define WBC_VOTER "WBC_VOTER" #define HW_LIMIT_VOTER "HW_LIMIT_VOTER" +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define CHG_AWAKE_VOTER "CHG_AWAKE_VOTER" +#define DCIN_ADAPTER_VOTER "DCIN_ADAPTER_VOTER" +#define DCIN_LIMIT_VOTER "DCIN_LIMIT_VOTER" +#endif #define PL_SMB_EN_VOTER "PL_SMB_EN_VOTER" #define FORCE_RECHARGE_VOTER "FORCE_RECHARGE_VOTER" #define LPD_VOTER "LPD_VOTER" +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define DC_AWAKE_VOTER "DC_AWAKE_VOTER" +#define DC_UV_AWAKE_VOTER "DC_UV_AWAKE_VOTER" +#define CLASSA_QC_FCC_VOTER "CLASSA_QC_FCC_VOTER" +#define QC_A_CP_ICL_MAX_VOTER "QC_A_CP_ICL_MAX_VOTER" +#define JEITA_VOTER "JEITA_VOTER" +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define UNSTANDARD_QC2_VOTER "UNSTANDARD_QC2_VOTER" +#endif +#endif #define FCC_STEPPER_VOTER "FCC_STEPPER_VOTER" #define SW_THERM_REGULATION_VOTER "SW_THERM_REGULATION_VOTER" +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define SW_CONN_THERM_VOTER "SW_CONN_THERM_VOTER" +#endif +#define LIQUID_DETECTION_VOTER "LIQUID_DETECTION_VOTER" +#define QC2_UNSUPPORTED_VOTER "QC2_UNSUPPORTED_VOTER" +#endif #define JEITA_ARB_VOTER "JEITA_ARB_VOTER" +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define AFTER_FFC_VOTER "AFTER_FFC_VOTER" +#endif #define MOISTURE_VOTER "MOISTURE_VOTER" #define HVDCP2_ICL_VOTER "HVDCP2_ICL_VOTER" #define AICL_THRESHOLD_VOTER "AICL_THRESHOLD_VOTER" @@ -90,9 +130,109 @@ enum print_reason { #define OVERHEAT_LIMIT_VOTER "OVERHEAT_LIMIT_VOTER" #define GPIO_DCIN_VOTER "GPIO_DCIN_VOTER" +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define FCC_VOTER "FCC_VOTER" +#define ICL_CHANGE_VOTER "ICL_CHANGE_VOTER" +#endif +#define PD_VERIFED_VOTER "PD_VERIFED_VOTER" +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define PD_REMOVE_COMP_VOTER "PD_REMOVE_COMP_VOTER" +#define STEP_BMS_CHG_VOTER "STEP_BMS_CHG_VOTER" +#define STEP_CHG_VOTER "STEP_CHG_VOTER" +#define LOW_ILIM_VOTER "LOW_ILIM_VOTER" +/* used for bq charge pump solution */ +#define MAIN_CHG_VOTER "MAIN_CHG_VOTER" +#define HVDCP3_START_ICL_VOTER "HVDCP3_START_ICL_VOTER" +#define MAIN_CHG_SUSPEND_VOTER "MAIN_CHG_SUSPEND_VOTER" +#ifdef CONFIG_MACH_XIAOMI_NABU +/* use for QC3P5 */ +#define QC3P5_VOTER "QC3P5_VOTER" +#define FCC_MAX_QC3P5_VOTER "FCC_MAX_QC3P5_VOTER" +/* use for Ln8000 */ +#define BATT_LN8000_VOTER "BATT_LN8000_VOTER" +#define BATT_BQ2597X_VOTER "BATT_BQ2597X_VOTER" +#endif + +#define WLS_FCC_VOTER "WLS_FCC_VOTER" +#endif +#endif + #define BOOST_BACK_STORM_COUNT 3 #define WEAK_CHG_STORM_COUNT 8 +#ifdef CONFIG_MACH_XIAOMI_NABU +#define MAX_QC3P5_PLUSE_COUNT_ALLOWED 230 +#define QC3P5_DP_RAPIDLY_TUNE_ALLOWED 120 +#define QC3P5_DP_RAPIDLY_TUNE_PULSE 10 +#endif + +#ifdef CONFIG_MACH_XIAOMI_SM8150 +/* defined for distinguish qc class_a and class_b */ +#define VOL_THR_FOR_QC_CLASS_AB 12300000 +#define COMP_FOR_LOW_RESISTANCE_CABLE 100000 +#define QC_CLASS_A_CURRENT_UA 3600000 +#define HVDCP_CLASS_A_MAX_UA 2500000 +#define HVDCP_CLASS_A_FOR_CP_UA 2000000 +#define MAX_PULSE 38 +#define MAX_PLUSE_COUNT_ALLOWED 30 +#define HIGH_NUM_PULSE_THR 12 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define PD_UNVERIFED_CURRENT 4800000 +#else +#define PD_UNVERIFED_CURRENT 3000000 +#endif +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define PD_UNVERIFED_VOLTAGE 4450000 +#define PD_REMOVE_COMP_CURRENT 7000000 +#endif + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +/* QC2.0 voltage UV threshold 7.8V */ +#define QC2_HVDCP_VOL_UV_THR 7800000 +#define CHECK_VBUS_WORK_DELAY_MS 200 +#define UNSTANDARD_HVDCP2_UA 1800000 + +#define BAT_TEMP_COLD 0 +#define BAT_TEMP_COOL 150 +#define BAT_TEMP_HOT 450 +#define BAT_TEMP_TOO_HOT 580 + +#define TEMP_COOL_RECHARGE_VBAT 4300 + +/*early attached report power supply changed*/ +#define EARLY_ATTACH_DELAY_MS 20000 +#endif + +/* thermal micros */ +#define MAX_TEMP_LEVEL 16 +/* percent of ICL compared to base 5V for different PD voltage_min voltage */ +#define PD_6P5V_PERCENT 85 +#define PD_7P5V_PERCENT 75 +#define PD_8P5V_PERCENT 70 +#define PD_9V_PERCENT 65 +#define PD_MICRO_5V 5000000 +#define PD_MICRO_5P9V 5900000 +#define PD_MICRO_6P5V 6500000 +#define PD_MICRO_7P5V 7500000 +#define PD_MICRO_8P5V 8500000 +#define PD_MICRO_9V 9000000 +#define ICL_LIMIT_LEVEL_THR 8 + +/* defined for qc2_unsupported */ +#define QC2_UNSUPPORTED_UA 1800000 +/* defined for HVDCP2 */ +#define HVDCP2_CURRENT_UA 1500000 + +/* defined for charger type recheck */ +#define CHARGER_RECHECK_DELAY_MS 30000 +#define TYPE_RECHECK_TIME_5S 5000 +#define TYPE_RECHECK_COUNT 3 + +/* defined for un_compliant Type-C cable */ +#define CC_UN_COMPLIANT_START_DELAY_MS 700 +#endif + #define VBAT_TO_VRAW_ADC(v) div_u64((u64)v * 1000000UL, 194637UL) #define ITERM_LIMITS_PMI632_MA 5000 @@ -102,14 +242,125 @@ enum print_reason { #define SDP_100_MA 100000 #define SDP_CURRENT_UA 500000 #define CDP_CURRENT_UA 1500000 +#ifdef CONFIG_MACH_XIAOMI_NABU +#define DCP_CURRENT_UA 2000000 +#elif defined(CONFIG_MACH_XIAOMI_SM8150) +#define DCP_CURRENT_UA 1600000 +#else #define DCP_CURRENT_UA 1500000 +#endif +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define HVDCP_CURRENT_UA 2800000 +#else #define HVDCP_CURRENT_UA 3000000 +#endif +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define HVDCP_CLASS_B_CURRENT_UA 3100000 +#define HVDCP_START_CURRENT_UA_FOR_BQ 500000 +#endif #define TYPEC_DEFAULT_CURRENT_UA 900000 #define TYPEC_MEDIUM_CURRENT_UA 1500000 #define TYPEC_HIGH_CURRENT_UA 3000000 #define DCIN_ICL_MIN_UA 100000 #define DCIN_ICL_MAX_UA 1500000 #define DCIN_ICL_STEP_UA 100000 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define SLOWLY_CHARGING_CURRENT 1000000 +#define ADC_CHG_TERM_MASK 32767 +#endif +#ifdef CONFIG_MACH_XIAOMI_NABU +#define HVDCP3P5_40W_CURRENT_UA 4500000 +#endif + +#ifdef CONFIG_MACH_XIAOMI_SM8150 +/*DCIN ICL*/ +#define PSNS_CURRENT_SAMPLE_RATE 1053 +#define PSNS_CURRENT_SAMPLE_RESIS 392 +#define PSNS_COMP_UV_FOR_HIGH_THERMAL 40000 + +/* cutoff voltage threshold */ +#define CUTOFF_VOL_THR 3400000 + +#define RECHARGE_SOC_THR 99 + + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define ESR_WORK_VOTER "ESR_WORK_VOTER" +#define SLOWLY_CHARGING_VOTER "SLOWLY_CHARGING_VOTER" +#define BATT_VERIFY_VOTER "BATT_VERIFY_VOTER" + +/* six pin new battery step charge micros */ +#define MAX_STEP_ENTRIES 3 +#define MAX_COUNT_OF_IBAT_STEP 2 + +#define STEP_CHG_DELAYED_MONITOR_MS 15000 +#define STEP_CHG_DELAYED_QUICK_MONITOR_MS 5000 +#define STEP_CHG_DELAYED_START_MS 100 +#define VBAT_FOR_STEP_MIN_UV 4300000 +#define VBAT_FOR_STEP_HYS_UV 20000 + +#define MAIN_ICL_MIN 100000 +#define SIX_PIN_VFLOAT_VOTER "SIX_PIN_VFLOAT_VOTER" +#define WARM_VFLOAT_UV 4100000 + +#define NON_FFC_VFLOAT_VOTER "NON_FFC_VFLOAT_VOTER" +#define NON_FFC_VFLOAT_UV 4450000 + +#define CP_COOL_THRESHOLD 150 +#define CP_WARM_THRESHOLD 450 +#define SOFT_JEITA_HYSTERESIS 5 + +/* used for bq charge pump solution */ +#define MAIN_CHARGER_ICL 2000000 +#define QC3_CHARGER_ICL 500000 +#ifdef CONFIG_MACH_XIAOMI_NABU +#define QC3P5_CHARGER_ICL 2000000 +#else +#define QC3P5_CHARGER_ICL 200000 +#endif + +#define MAIN_CHARGER_STOP_ICL 50000 +#define ESR_WORK_TIME_2S 2000 +#define ESR_WORK_TIME_180S 180000 + +/* six pin battery data struct */ +struct six_pin_step_data { + u32 vfloat_step_uv; + u32 fcc_step_ua; +}; + +#define DEFAULT_FFC_LOW_TBAT 150 +#define DEFAULT_FFC_HIGH_TBAT 450 + +enum esr_work_status { + ESR_CHECK_FCC_NOLIMIT, + ESR_CHECK_FCC_LIMITED, +}; + +#define REPORT_SOC_DECIMAL_MS 100 + +/* cutoff voltage threshold */ +#define CUTOFF_VOL_THR 3400000 +#define CUTOFF_VOL_HYS 50000 + +/* wdog bark timer */ +#define BARK_TIMER_LONG 128 +#define BARK_TIMER_NORMAL 16 + +/* for override ffc terminate current */ +#define OVERRIDE_FFC_TERM_CURRENT 820 +#endif + +enum hvdcp3_type { + HVDCP3_NONE = 0, + HVDCP3_CLASSA_18W, + HVDCP3_CLASSB_27W, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + HVDCP3P5_CLASSA_18W, + HVDCP3P5_CLASSB_27W, +#endif +}; +#endif #define ROLE_REVERSAL_DELAY_MS 2000 @@ -249,6 +500,21 @@ enum comp_clamp_levels { MAX_CLAMP_LEVEL, }; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +enum quick_charge_type { + QUICK_CHARGE_NORMAL = 0, + QUICK_CHARGE_FAST, + QUICK_CHARGE_FLASH, + QUICK_CHARGE_TURBE, + QUICK_CHARGE_MAX, +}; + +struct quick_charge { + enum power_supply_type adap_type; + enum quick_charge_type adap_cap; +}; +#endif + struct clamp_config { u16 reg[3]; u16 val[3]; @@ -304,6 +570,10 @@ enum icl_override_mode { SW_OVERRIDE_USB51_MODE, /* ICL other than USB51 */ SW_OVERRIDE_HC_MODE, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* ICL in cc float mode */ + SW_OVERRIDE_NO_CC_MODE, +#endif }; /* EXTCON_USB and EXTCON_USB_HOST are mutually exclusive */ @@ -379,6 +649,10 @@ struct smb_iio { struct iio_channel *die_temp_chan; struct iio_channel *skin_temp_chan; struct iio_channel *smb_temp_chan; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct iio_channel *hw_version_gpio5; + struct iio_channel *project_gpio6; +#endif }; struct smb_charger { @@ -395,6 +669,14 @@ struct smb_charger { int otg_delay_ms; int *weak_chg_icl_ua; bool pd_not_supported; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool init_once; + bool support_liquid; + bool dynamic_fv_enabled; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + bool batt_verified; +#endif +#endif /* locks */ struct mutex smb_lock; @@ -411,11 +693,29 @@ struct smb_charger { struct power_supply *usb_psy; struct power_supply *dc_psy; struct power_supply *bms_psy; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct power_supply_desc usb_psy_desc; +#endif struct power_supply *usb_main_psy; struct power_supply *usb_port_psy; struct power_supply *wls_psy; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct power_supply *idtp_psy; + struct power_supply *wip_psy; + struct power_supply *wireless_psy; + struct power_supply *wls_chip_psy; +#endif struct power_supply *cp_psy; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + struct power_supply *ln_psy; + struct power_supply *halo_psy; + struct power_supply *cp_chip_psy; + struct power_supply *batt_verify_psy; +#endif enum power_supply_type real_charger_type; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + enum power_supply_type wireless_charger_type; +#endif /* dual role class */ struct dual_role_phy_instance *dual_role; @@ -441,6 +741,9 @@ struct smb_charger { struct votable *fcc_main_votable; struct votable *fv_votable; struct votable *usb_icl_votable; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct votable *dc_icl_votable; +#endif struct votable *awake_votable; struct votable *pl_disable_votable; struct votable *chg_disable_votable; @@ -450,6 +753,9 @@ struct smb_charger { struct votable *icl_irq_disable_votable; struct votable *limited_irq_disable_votable; struct votable *hdc_irq_disable_votable; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + struct votable *cp_ilim_votable; +#endif struct votable *temp_change_irq_disable_votable; /* work */ @@ -459,21 +765,56 @@ struct smb_charger { struct work_struct moisture_protection_work; struct work_struct chg_termination_work; struct work_struct dcin_aicl_work; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct work_struct lpd_disable_chg_work; +#endif struct delayed_work ps_change_timeout_work; struct delayed_work clear_hdc_work; struct delayed_work icl_change_work; struct delayed_work pl_enable_work; struct delayed_work uusb_otg_work; struct delayed_work bb_removal_work; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + struct delayed_work batt_verify_update_work; +#endif + struct delayed_work raise_qc3_vbus_work; +#endif struct delayed_work lpd_ra_open_work; struct delayed_work lpd_detach_work; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct delayed_work charger_type_recheck; + struct delayed_work cc_un_compliant_charge_work; +#endif struct delayed_work thermal_regulation_work; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + struct delayed_work conn_therm_work; + struct delayed_work after_ffc_chg_dis_work; + struct delayed_work after_ffc_chg_en_work; +#endif + struct delayed_work dc_plug_out_delay_work; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + struct delayed_work report_soc_decimal_work; +#endif +#endif struct delayed_work usbov_dbc_work; struct delayed_work role_reversal_check; struct delayed_work pr_swap_detach_work; struct delayed_work pr_lock_clear_work; struct delayed_work micro_usb_switch_work; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + struct delayed_work check_vbus_work; + struct delayed_work check_init_boot; + struct delayed_work early_attach; + struct delayed_work six_pin_batt_step_chg_work; + struct delayed_work reduce_fcc_work; + struct delayed_work thermal_setting_work; +#endif +#ifdef CONFIG_MACH_XIAOMI_NABU + struct delayed_work check_vbat_work; +#endif struct alarm lpd_recheck_timer; struct alarm moisture_protection_alarm; struct alarm chg_termination_alarm; @@ -487,15 +828,30 @@ struct smb_charger { bool sec_cp_present; int sec_chg_selected; int cp_reason; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int cp_mode; + int cp_fcc; + int cp_main_fcc; +#endif /* pd */ int voltage_min_uv; int voltage_max_uv; int pd_active; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int apdo_max; +#endif + int pd_verifed; +#endif bool pd_hard_reset; bool pr_lock_in_progress; bool pr_swap_in_progress; bool early_usb_attach; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool early_dc_attach; + bool batt_temp_irq_enabled; +#endif bool ok_to_pd; bool typec_legacy; bool typec_irq_en; @@ -505,14 +861,49 @@ struct smb_charger { bool system_suspend_supported; int boost_threshold_ua; int system_temp_level; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int pps_thermal_level; +#endif int thermal_levels; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int lpd_levels; + int dc_temp_level; + int dc_thermal_levels; + int *thermal_mitigation_dcp; + int *thermal_mitigation_qc2; + int *thermal_mitigation_pd_base; + int *thermal_mitigation_icl; + int *thermal_fcc_qc3_normal; + int *thermal_fcc_qc3_cp; + int *thermal_fcc_qc3_classb_cp; + int *thermal_fcc_pps_cp; + int *thermal_mitigation_dc; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int *thermal_mitigation_voice; +#endif + int *lpd_hwversion; + int *thermal_mitigation_epp; + int *thermal_mitigation_bpp_qc3; + int *thermal_mitigation_bpp_qc2; + int *thermal_mitigation_bpp; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int *thermal_mitigation_dc_20W; +#endif +#else int *thermal_mitigation; +#endif int dcp_icl_ua; int fake_capacity; int fake_batt_status; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int fake_conn_temp; +#endif bool step_chg_enabled; bool sw_jeita_enabled; bool typec_legacy_use_rp_icl; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool lpd_enabled; +#endif bool is_hdc; bool chg_done; int connector_type; @@ -534,6 +925,9 @@ struct smb_charger { bool hvdcp_disable; int hw_max_icl_ua; int auto_recharge_soc; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int auto_recharge_vbat; +#endif enum sink_src_mode sink_src_mode; enum power_supply_typec_power_role power_role; enum jeita_cfg_stat jeita_configured; @@ -543,13 +937,22 @@ struct smb_charger { enum lpd_stage lpd_stage; bool lpd_disabled; enum lpd_reason lpd_reason; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool lpd_status; +#endif bool fcc_stepper_enable; int die_temp; int smb_temp; int skin_temp; int connector_temp; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + u64 entry_time; +#endif int thermal_status; int main_fcc_max; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool report_usb_absent; +#endif u32 jeita_soft_thlds[2]; u32 jeita_soft_hys_thlds[2]; int jeita_soft_fcc[2]; @@ -580,6 +983,22 @@ struct smb_charger { bool dpdm_enabled; bool apsd_ext_timeout; bool qc3p5_detected; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int vbus_disable; +#ifdef CONFIG_MACH_XIAOMI_NABU + bool en_bq_flag; +#endif + int64_t rpp; + int64_t cep; + int64_t tx_bt_mac; +#ifdef CONFIG_MACH_XIAOMI_NABU + int64_t pen_bt_mac; +#endif + int reverse_chg_state; +#endif +#ifdef CONFIG_MACH_XIAOMI_NABU + int reverse_gpio_state; +#endif /* workaround flag */ u32 wa_flags; @@ -587,6 +1006,14 @@ struct smb_charger { int qc2_max_pulses; enum qc2_non_comp_voltage qc2_unsupported_voltage; bool dbc_usbov; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool fake_usb_insertion; + bool qc2_unsupported; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + bool check_vbus_once; + bool unstandard_hvdcp; +#endif +#endif /* extcon for VBUS / ID notification to USB for uUSB */ struct extcon_dev *extcon; @@ -600,6 +1027,15 @@ struct smb_charger { int die_health; int connector_health; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* raise qc3 vbus flag */ + bool qc_class_ab; + bool is_qc_class_a; + bool is_qc_class_b; + bool raise_vbus_to_detect; + bool detect_low_power_qc3_charger; + bool high_vbus_detected; +#endif /* flash */ u32 flash_derating_soc; @@ -623,6 +1059,89 @@ struct smb_charger { int micro_usb_pre_state; bool dcin_uusb_over_gpio_en; bool aicl_disable; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int wireless_vout; +#endif + int flag_dc_present; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int flag_cp_en; +#endif + int power_good_en; + int fake_dc_on; + int fake_dc_flag; + int last_batt_stat; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int last_vout_set; +#endif + /* charger type recheck */ + int recheck_charger; + int precheck_charger_type; + /* workarounds */ + bool cc_un_compliant_detected; + bool snk_debug_acc_detected; + bool support_wireless; +#ifdef CONFIG_MACH_XIAOMI_NABU + bool wireless_bq; +#endif +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + bool support_conn_therm; + bool ext_fg; + int conn_detect_count; + int vbus_disable_gpio; + int remove_comp; + u64 last_ffc_remove_time; +#endif +#endif + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* used for bq charge pump solution */ + struct usbpd *pd; + bool use_bq_pump; + + /* reduce fcc for esr cal*/ + int esr_work_status; + bool cp_charge_enabled; + int charge_type; + int charge_status; + int batt_health; + + bool override_ffc_term_current; + /* for 27W charge*/ + bool temp_27W_enable; + + /* used for 6pin new battery step charge */ + bool six_pin_step_charge_enable; + bool init_start_vbat_checked; + struct six_pin_step_data six_pin_step_cfg[MAX_STEP_ENTRIES]; + u32 start_step_vbat; + int trigger_taper_count; + int index_vfloat; + + /* fast full charge related */ + int chg_term_current_thresh_hi_from_dts; + bool support_ffc; + int ffc_low_tbat; + int ffc_high_tbat; + bool slowly_charging; + bool already_start_step_charge_work; + bool bq_input_suspend; + + bool hvdcp_recheck_status; + + /* QC3P5 related */ + bool qc3p5_supported; + bool qc3p5_auth_complete; + bool qc3p5_authenticated; + bool qc3p5_authentication_started; + bool qc3p5_dp_tune_rapidly; + int qc3p5_power_limit_w; + + bool pps_fcc_therm_work_disabled; + int wls_cp_vin; + int64_t oob_rpp_msg_cnt; + int64_t oob_cep_msg_cnt; +#endif }; int smblib_read(struct smb_charger *chg, u16 addr, u8 *val); @@ -641,6 +1160,10 @@ int smblib_set_charge_param(struct smb_charger *chg, int smblib_set_usb_suspend(struct smb_charger *chg, bool suspend); int smblib_set_dc_suspend(struct smb_charger *chg, bool suspend); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int smblib_change_psns_to_curr(struct smb_charger *chg, int uv); +#endif + int smblib_mapping_soc_from_field_value(struct smb_chg_param *param, int val_u, u8 *val_raw); int smblib_mapping_cc_delta_to_field_value(struct smb_chg_param *param, @@ -662,6 +1185,9 @@ int smblib_vconn_regulator_disable(struct regulator_dev *rdev); int smblib_vconn_regulator_is_enabled(struct regulator_dev *rdev); irqreturn_t default_irq_handler(int irq, void *data); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +irqreturn_t dcin_uv_handler(int irq, void *data); +#endif irqreturn_t smb_en_irq_handler(int irq, void *data); irqreturn_t chg_state_change_irq_handler(int irq, void *data); irqreturn_t batt_temp_changed_irq_handler(int irq, void *data); @@ -689,6 +1215,10 @@ int smblib_get_prop_batt_present(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_batt_capacity(struct smb_charger *chg, union power_supply_propval *val); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smblib_get_prop_batt_capacity_level(struct smb_charger *chg, + union power_supply_propval *val); +#endif int smblib_get_prop_batt_status(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_batt_charge_type(struct smb_charger *chg, @@ -701,6 +1231,10 @@ int smblib_get_prop_system_temp_level(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_system_temp_level_max(struct smb_charger *chg, union power_supply_propval *val); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int smblib_get_prop_dc_temp_level(struct smb_charger *chg, + union power_supply_propval *val); +#endif int smblib_get_prop_input_current_limited(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_batt_iterm(struct smb_charger *chg, @@ -713,6 +1247,10 @@ int smblib_set_prop_batt_status(struct smb_charger *chg, const union power_supply_propval *val); int smblib_set_prop_system_temp_level(struct smb_charger *chg, const union power_supply_propval *val); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int smblib_set_prop_dc_temp_level(struct smb_charger *chg, + const union power_supply_propval *val); +#endif int smblib_set_prop_input_current_limited(struct smb_charger *chg, const union power_supply_propval *val); @@ -732,6 +1270,10 @@ int smblib_get_prop_voltage_wls_output(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_voltage_wls_output(struct smb_charger *chg, const union power_supply_propval *val); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int smblib_get_prop_wireless_version(struct smb_charger *chg, + union power_supply_propval *val); +#endif int smblib_set_prop_dc_reset(struct smb_charger *chg); int smblib_get_prop_usb_present(struct smb_charger *chg, union power_supply_propval *val); @@ -774,6 +1316,13 @@ int smblib_get_prop_input_current_max(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_thermal_overheat(struct smb_charger *chg, int therm_overheat); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smblib_get_prop_vph_voltage_now(struct smb_charger *chg, + union power_supply_propval *val); +int smblib_get_prop_connector_temp(struct smb_charger *chg); +int smblib_set_vbus_disable(struct smb_charger *chg, + bool disable); +#endif int smblib_get_skin_temp_status(struct smb_charger *chg); int smblib_get_prop_vph_voltage_now(struct smb_charger *chg, union power_supply_propval *val); @@ -797,6 +1346,10 @@ int smblib_set_prop_ship_mode(struct smb_charger *chg, const union power_supply_propval *val); int smblib_set_prop_rechg_soc_thresh(struct smb_charger *chg, const union power_supply_propval *val); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smblib_set_prop_rechg_vbat_thresh(struct smb_charger *chg, + const union power_supply_propval *val); +#endif void smblib_suspend_on_debug_battery(struct smb_charger *chg); int smblib_rerun_apsd_if_required(struct smb_charger *chg); void smblib_rerun_apsd(struct smb_charger *chg); @@ -804,11 +1357,21 @@ int smblib_get_prop_fcc_delta(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_thermal_threshold(struct smb_charger *chg, u16 addr, int *val); int smblib_dp_dm(struct smb_charger *chg, int val); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smblib_dp_dm_bq(struct smb_charger *chg, int val); +#endif int smblib_disable_hw_jeita(struct smb_charger *chg, bool disable); int smblib_run_aicl(struct smb_charger *chg, int type); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smblib_rerun_aicl(struct smb_charger *chg); +#endif int smblib_set_icl_current(struct smb_charger *chg, int icl_ua); int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua); int smblib_get_charge_current(struct smb_charger *chg, int *total_current_ua); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smblib_get_charge_current_limit(struct smb_charger *chg, + int *total_current_ua); +#endif int smblib_get_prop_pr_swap_in_progress(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg, @@ -825,6 +1388,49 @@ int smblib_configure_hvdcp_apsd(struct smb_charger *chg, bool enable); int smblib_icl_override(struct smb_charger *chg, enum icl_override_mode mode); enum alarmtimer_restart smblib_lpd_recheck_timer(struct alarm *alarm, ktime_t time); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int smblib_set_prop_wireless_wakelock(struct smb_charger *chg, + const union power_supply_propval *val); + +int smblib_set_prop_type_recheck(struct smb_charger *chg, + const union power_supply_propval *val); +int smblib_get_prop_type_recheck(struct smb_charger *chg, + union power_supply_propval *val); +int smblib_get_quick_charge_type(struct smb_charger *chg); +int smblib_set_wirless_cp_enable(struct smb_charger *chg, + const union power_supply_propval *val); +int smblib_set_wirless_power_good_enable(struct smb_charger *chg, + const union power_supply_propval *val); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smblib_set_fastcharge_mode(struct smb_charger *chg, bool enable); +int smblib_get_fastcharge_mode(struct smb_charger *chg); +int smblib_set_sw_disable_dc_en(struct smb_charger *chg, + const union power_supply_propval *val); +#endif +int smblib_get_prop_liquid_status(struct smb_charger *chg, + union power_supply_propval *val); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smblib_set_prop_tx_mac(struct smb_charger *chg, + const union power_supply_propval *val); +#ifdef CONFIG_MACH_XIAOMI_NABU +void smblib_set_prop_pen_mac(struct smb_charger *chg, + const union power_supply_propval *val); +#endif +int smblib_set_prop_rx_cr(struct smb_charger *chg, + const union power_supply_propval *val); +int smblib_set_prop_rx_cep(struct smb_charger *chg, + const union power_supply_propval *val); +int smblib_set_prop_bt_state(struct smb_charger *chg, + const union power_supply_propval *val); +#endif + +bool smblib_support_liquid_feature(struct smb_charger *chg); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smblib_set_prop_battery_charging_enabled(struct smb_charger *chg, + const union power_supply_propval *val); +#endif +#endif int smblib_toggle_smb_en(struct smb_charger *chg, int toggle); void smblib_hvdcp_detect_enable(struct smb_charger *chg, bool enable); void smblib_hvdcp_exit_config(struct smb_charger *chg); @@ -832,8 +1438,28 @@ void smblib_apsd_enable(struct smb_charger *chg, bool enable); int smblib_force_vbus_voltage(struct smb_charger *chg, u8 val); int smblib_get_irq_status(struct smb_charger *chg, union power_supply_propval *val); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int smb5_config_iterm(struct smb_charger *chg, int hi_thresh, int low_thresh); +int smblib_get_prop_battery_charging_enabled(struct smb_charger *chg, + union power_supply_propval *val); +int smblib_get_prop_battery_charging_limited(struct smb_charger *chg, + union power_supply_propval *val); +int smblib_get_prop_battery_slowly_charging(struct smb_charger *chg, + union power_supply_propval *val); +int smblib_set_prop_battery_slowly_charging(struct smb_charger *chg, + const union power_supply_propval *val); +int smblib_get_prop_battery_bq_input_suspend(struct smb_charger *chg, + union power_supply_propval *val); +#endif int smblib_get_qc3_main_icl_offset(struct smb_charger *chg, int *offset_ua); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +struct usbpd *smb_get_usbpd(void); +#endif int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg); +#ifdef CONFIG_MACH_XIAOMI_NABU +int smblib_get_prop_wireless_fw_version(struct smb_charger *chg, + union power_supply_propval *val); +#endif #endif /* __SMB5_CHARGER_H */ diff --git a/drivers/power/supply/qcom/smb5-reg.h b/drivers/power/supply/qcom/smb5-reg.h index 444841d67c82..214441ab03cc 100644 --- a/drivers/power/supply/qcom/smb5-reg.h +++ b/drivers/power/supply/qcom/smb5-reg.h @@ -281,6 +281,21 @@ enum { HVDCP_PULSE_COUNT_MAX_QC2_INVALID = 0xC0 }; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define USBIN_ADAPTER_ALLOW_CFG_REG (USBIN_BASE + 0x60) +enum { + USBIN_ADAPTER_ALLOW_5V = 0, + USBIN_ADAPTER_ALLOW_9V = 2, + USBIN_ADAPTER_ALLOW_5V_OR_9V = 3, + USBIN_ADAPTER_ALLOW_12V = 4, + USBIN_ADAPTER_ALLOW_5V_OR_12V = 5, + USBIN_ADAPTER_ALLOW_9V_TO_12V = 6, + USBIN_ADAPTER_ALLOW_5V_OR_9V_TO_12V = 7, + USBIN_ADAPTER_ALLOW_5V_TO_9V = 8, + USBIN_ADAPTER_ALLOW_5V_TO_12V = 12, +}; +#endif + #define USBIN_OPTIONS_1_CFG_REG (USBIN_BASE + 0x62) #define HVDCP_AUTH_ALG_EN_CFG_BIT BIT(6) #define HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT BIT(5) @@ -317,6 +332,11 @@ enum { #define USBIN_5V_AICL_THRESHOLD_REG (USBIN_BASE + 0x81) #define USBIN_CONT_AICL_THRESHOLD_REG (USBIN_BASE + 0x84) + +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define APSD_START_ON_CC_BIT BIT(7) +#endif + /******************************** * DCIN Peripheral Registers * ********************************/ @@ -327,8 +347,17 @@ enum { #define DCIN_CMD_IL_REG (DCIN_BASE + 0x40) #define DCIN_SUSPEND_BIT BIT(0) #define DCIN_EN_OVERRIDE_BIT BIT(1) +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define DCIN_EN_BIT BIT(2) +#endif #define DCIN_EN_MASK GENMASK(2, 1) +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define DCIN_CMD_PULLDOWN_REG (DCIN_BASE + 0x45) +#define DCIN_PULLDOWN_EN_BIT BIT(0) +#define DCIN_MID_PULLDOWN_BIT BIT(1) +#endif + #define DCIN_CMD_PON_REG (DCIN_BASE + 0x45) #define DCIN_PON_BIT BIT(0) #define MID_CHG_BIT BIT(1) @@ -349,6 +378,11 @@ enum { #define SNK_RP_3P0_BIT BIT(1) #define SNK_RP_SHORT_BIT BIT(0) +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define TYPE_C_SNK_DEBUG_ACC_STATUS_REG (TYPEC_BASE + 0x07) +#define SNK_DEBUG_ACC_RPSTD_PRSTD_BIT BIT(0) +#endif + #define TYPE_C_SRC_STATUS_REG (TYPEC_BASE + 0x08) #define DETECTED_SNK_TYPE_MASK GENMASK(4, 0) #define SRC_HIGH_BATT_BIT BIT(5) @@ -400,6 +434,12 @@ enum { #define TYPEC_CCOUT_VALUE_BIT BIT(1) #define TYPEC_CCOUT_SRC_BIT BIT(0) +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define TYPE_C_DEBUG_ACC_SNK_CFG (TYPEC_BASE + 0x4A) +#define TYPEC_DEBUG_ACC_SNK_SEL_ICL BIT(2) +#define TYPEC_DEBUG_ACC_SNK_DIS_AICL BIT(3) +#endif + #define DEBUG_ACCESS_SRC_CFG_REG (TYPEC_BASE + 0x4C) #define EN_UNORIENTED_DEBUG_ACCESS_SRC_BIT BIT(0) @@ -457,6 +497,9 @@ enum { #define EN_MICRO_USB_WATER_PROTECTION_BIT BIT(4) #define MICRO_USB_DETECTION_ON_TIME_CFG_MASK GENMASK(3, 2) #define MICRO_USB_DETECTION_PERIOD_CFG_MASK GENMASK(1, 0) +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define TYPEC_MICRO_USB_MODE_REG (TYPEC_BASE + 0x73) +#endif #define PMI632_TYPEC_MICRO_USB_MODE_REG (TYPEC_BASE + 0x73) #define MICRO_USB_MODE_ONLY_BIT BIT(0) @@ -515,6 +558,9 @@ enum { #define WATCHDOG_TRIGGER_AFP_EN_BIT BIT(7) #define BARK_WDOG_INT_EN_BIT BIT(6) #define WDOG_TIMER_EN_ON_PLUGIN_BIT BIT(1) +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define WDOG_TIMER_EN_BIT BIT(0) +#endif #define SNARL_BARK_BITE_WD_CFG_REG (MISC_BASE + 0x53) #define BITE_WDOG_DISABLE_CHARGING_CFG_BIT BIT(7) diff --git a/drivers/power/supply/qcom/step-chg-jeita.c b/drivers/power/supply/qcom/step-chg-jeita.c index 72191eca56bb..43aa26996511 100644 --- a/drivers/power/supply/qcom/step-chg-jeita.c +++ b/drivers/power/supply/qcom/step-chg-jeita.c @@ -22,6 +22,9 @@ #define STEP_CHG_VOTER "STEP_CHG_VOTER" #define JEITA_VOTER "JEITA_VOTER" +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define DYNAMIC_FV_VOTER "DYNAMIC_FV_VOTER" +#endif #define is_between(left, right, value) \ (((left) >= (right) && (left) >= (value) \ @@ -44,38 +47,70 @@ struct jeita_fv_cfg { struct range_data fv_cfg[MAX_STEP_CHG_ENTRIES]; }; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +struct dynamic_fv_cfg { + char *prop_name; + struct range_data fv_cfg[MAX_STEP_CHG_ENTRIES]; +}; +#endif + struct step_chg_info { struct device *dev; ktime_t step_last_update_time; ktime_t jeita_last_update_time; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + ktime_t dynamic_fv_last_update_time; +#endif bool step_chg_enable; bool sw_jeita_enable; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool dynamic_fv_enable; +#endif bool jeita_arb_en; bool config_is_read; bool step_chg_cfg_valid; bool sw_jeita_cfg_valid; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool dynamic_fv_cfg_valid; +#endif bool soc_based_step_chg; bool ocv_based_step_chg; bool vbat_avg_based_step_chg; bool batt_missing; bool taper_fcc; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + bool six_pin_battery; + bool use_bq_pump; +#endif int jeita_fcc_index; int jeita_fv_index; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int dynamic_fv_index; +#endif int step_index; int get_config_retry_count; struct step_chg_cfg *step_chg_config; struct jeita_fcc_cfg *jeita_fcc_config; struct jeita_fv_cfg *jeita_fv_config; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct dynamic_fv_cfg *dynamic_fv_config; +#endif struct votable *fcc_votable; struct votable *fv_votable; struct votable *usb_icl_votable; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct votable *dc_suspend_votable; +#endif struct wakeup_source *step_chg_ws; struct power_supply *batt_psy; struct power_supply *bms_psy; struct power_supply *usb_psy; struct power_supply *dc_psy; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + struct power_supply *bq_psy; +#endif struct delayed_work status_change_work; struct delayed_work get_config_work; struct notifier_block nb; @@ -123,6 +158,24 @@ static bool is_usb_available(struct step_chg_info *chip) return true; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static bool is_bq25970_available(struct step_chg_info *chip) +{ + if (!chip->bq_psy) + chip->bq_psy = power_supply_get_by_name("bq2597x-standalone"); + +#ifdef CONFIG_MACH_XIAOMI_NABU + if (!chip->bq_psy) + chip->bq_psy = power_supply_get_by_name("ln8000"); +#endif + + if (!chip->bq_psy) + return false; + + return true; +} +#endif + static bool is_input_present(struct step_chg_info *chip) { int rc = 0, input_present = 0; @@ -262,8 +315,13 @@ static int get_step_chg_jeita_setting_from_profile(struct step_chg_info *chip) if (batt_id_ohms < 0) return -EBUSY; +#ifndef CONFIG_MACH_XIAOMI_NABU profile_node = of_batterydata_get_best_profile(batt_node, batt_id_ohms / 1000, NULL); +#else + profile_node = of_batterydata_get_best_profile(batt_node, + batt_id_ohms / 1000, "K82_sunwoda_8720mah"); +#endif if (IS_ERR(profile_node)) return PTR_ERR(profile_node); @@ -360,6 +418,26 @@ static int get_step_chg_jeita_setting_from_profile(struct step_chg_info *chip) chip->sw_jeita_cfg_valid = false; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chip->dynamic_fv_cfg_valid = true; + rc = read_range_data_from_node(profile_node, + "qcom,dynamic-fv-ranges", + chip->dynamic_fv_config->fv_cfg, + BATT_HOT_DECIDEGREE_MAX, max_fv_uv); + if (rc < 0) { + pr_debug("Read qcom,dynamic-fv-ranges failed from battery profile, rc=%d\n", + rc); + chip->dynamic_fv_cfg_valid = false; + } + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chip->six_pin_battery = + of_property_read_bool(profile_node, "mi,six-pin-battery"); + chip->use_bq_pump = + of_property_read_bool(profile_node, "qcom,use-bq-pump"); +#endif +#endif + return rc; } @@ -417,6 +495,16 @@ static int get_val(struct range_data *range, int hysteresis, int current_index, *new_index = -EINVAL; +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + /* + * As battery temperature may be below 0, range.xxx is a unsigned int, but battery + * temperature is a signed int, so cannot compare them when battery temp is below 0, + * we treat it as 0 degree when the parameter threshold(battery temp) is below 0. + */ + if (threshold < 0) + threshold = 0; +#endif + /* * If the threshold is lesser than the minimum allowed range, * return -ENODATA. @@ -456,6 +544,16 @@ static int get_val(struct range_data *range, int hysteresis, int current_index, *val = range[*new_index].value; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (threshold < range[0].low_threshold) { + *new_index = 0; + *val = range[*new_index].value; + } else if (threshold > range[MAX_STEP_CHG_ENTRIES - 1].low_threshold) { + *new_index = MAX_STEP_CHG_ENTRIES - 1; + *val = range[*new_index].value; + } +#endif + /* * If we don't have a current_index return this * newfound value. There is no hysterisis from out of range @@ -538,10 +636,32 @@ static int handle_step_chg_config(struct step_chg_info *chip) union power_supply_propval pval = {0, }; int rc = 0, fcc_ua = 0, current_index; u64 elapsed_us; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int update_now = 0; + static int usb_present; +#endif + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (!is_usb_available(chip)) + return 0; + rc = power_supply_get_property(chip->usb_psy, + POWER_SUPPLY_PROP_PRESENT, &pval); + if (rc < 0) { + pr_err("Get battery present status failed, rc=%d\n", rc); + return rc; + } + if (pval.intval && pval.intval != usb_present) + update_now = true; + usb_present = pval.intval; +#endif elapsed_us = ktime_us_delta(ktime_get(), chip->step_last_update_time); /* skip processing, event too early */ +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (elapsed_us < STEP_CHG_HYSTERISIS_DELAY_US && !update_now) +#else if (elapsed_us < STEP_CHG_HYSTERISIS_DELAY_US) +#endif return 0; rc = power_supply_get_property(chip->batt_psy, @@ -557,12 +677,24 @@ static int handle_step_chg_config(struct step_chg_info *chip) goto update_time; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (chip->use_bq_pump) { + if (is_bq25970_available(chip)) { + rc = power_supply_get_property(chip->bq_psy, + POWER_SUPPLY_PROP_TI_BATTERY_VOLTAGE, &pval); + pval.intval = pval.intval * 1000; + } + } else { +#endif if (chip->step_chg_config->param.use_bms) rc = power_supply_get_property(chip->bms_psy, chip->step_chg_config->param.psy_prop, &pval); else rc = power_supply_get_property(chip->batt_psy, chip->step_chg_config->param.psy_prop, &pval); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + } +#endif if (rc < 0) { pr_err("Couldn't read %s property rc=%d\n", @@ -614,12 +746,111 @@ static int handle_step_chg_config(struct step_chg_info *chip) return 0; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static int handle_dynamic_fv(struct step_chg_info *chip) +{ + union power_supply_propval pval = {0, }; + int rc = 0, fv_uv, cycle_count; + u64 elapsed_us; + int batt_vol = 0; + + rc = power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_DYNAMIC_FV_ENABLED, &pval); + if (rc < 0) + chip->dynamic_fv_enable = 0; + else + chip->dynamic_fv_enable = pval.intval; + + if (!chip->dynamic_fv_enable || !chip->dynamic_fv_cfg_valid) { + /*need recovery some setting*/ + if (chip->fv_votable) + vote(chip->fv_votable, DYNAMIC_FV_VOTER, false, 0); + return 0; + } + + elapsed_us = ktime_us_delta(ktime_get(), chip->dynamic_fv_last_update_time); + /* skip processing, event too early */ + if (elapsed_us < STEP_CHG_HYSTERISIS_DELAY_US) + return 0; + + rc = power_supply_get_property(chip->bms_psy, + POWER_SUPPLY_PROP_CYCLE_COUNT, &pval); + if (rc < 0) { + pr_err("Couldn't read %s property rc=%d\n", + chip->dynamic_fv_config->prop_name, rc); + return rc; + } + cycle_count = pval.intval; + + rc = get_val(chip->dynamic_fv_config->fv_cfg, + 0, + chip->dynamic_fv_index, + cycle_count, + &chip->dynamic_fv_index, + &fv_uv); + if (rc < 0) { + /* remove the vote if no step-based fv is found */ + if (chip->fv_votable) + vote(chip->fv_votable, DYNAMIC_FV_VOTER, false, 0); + goto update_time; + } + + power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); + batt_vol = pval.intval; + if (batt_vol >= fv_uv) { + goto update_time; + } + + chip->fv_votable = find_votable("FV"); + if (!chip->fv_votable) + goto update_time; + + vote(chip->fv_votable, DYNAMIC_FV_VOTER, true, fv_uv); + + /*set battery full voltage to FLOAT VOLTAGE - 10mV*/ + pval.intval = fv_uv - 10000; + rc = power_supply_set_property(chip->bms_psy, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, &pval); + if (rc < 0) { + pr_err("Couldn't set CONSTANT VOLTAGE property rc=%d\n", rc); + return rc; + } + + pr_debug("%s:cycle_count:%d,Batt_full:%d,fv:%d,\n", + __func__, cycle_count, pval.intval, fv_uv); + +update_time: + chip->dynamic_fv_last_update_time = ktime_get(); + return 0; +} +#endif + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define JEITA_SUSPEND_HYST_UV 130000 +#elif defined(CONFIG_MACH_XIAOMI_SM8150) +#define JEITA_SUSPEND_HYST_UV 70000 +#else #define JEITA_SUSPEND_HYST_UV 50000 +#endif +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define JEITA_SIX_PIN_BATT_HYST_UV 100000 +#define WARM_VFLOAT_UV 4100000 +#endif static int handle_jeita(struct step_chg_info *chip) { union power_supply_propval pval = {0, }; int rc = 0, fcc_ua = 0, fv_uv = 0; u64 elapsed_us; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int update_now = 0; + int curr_vfloat_uv, curr_vbat_uv; + int temp, pd_authen_result = 0; + static bool fast_mode_dis, usb_present; + int batt_soc = 0, batt_temp = 0; + static bool ffc_temp_is_high; + bool set_term_curr_flag = false; +#endif rc = power_supply_get_property(chip->batt_psy, POWER_SUPPLY_PROP_SW_JEITA_ENABLED, &pval); @@ -635,12 +866,35 @@ static int handle_jeita(struct step_chg_info *chip) vote(chip->fv_votable, JEITA_VOTER, false, 0); if (chip->usb_icl_votable) vote(chip->usb_icl_votable, JEITA_VOTER, false, 0); +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + if (chip->dc_suspend_votable) + vote(chip->dc_suspend_votable, JEITA_VOTER, 0, 0); +#endif + return 0; + } + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (!is_usb_available(chip)) return 0; + + rc = power_supply_get_property(chip->usb_psy, + POWER_SUPPLY_PROP_PRESENT, &pval); + if (rc < 0) { + pr_err("Get battery present status failed, rc=%d\n", rc); + return rc; } + if (pval.intval && pval.intval != usb_present) + update_now = true; + usb_present = pval.intval; +#endif elapsed_us = ktime_us_delta(ktime_get(), chip->jeita_last_update_time); /* skip processing, event too early */ +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (elapsed_us < STEP_CHG_HYSTERISIS_DELAY_US && !update_now) +#else if (elapsed_us < STEP_CHG_HYSTERISIS_DELAY_US) +#endif return 0; if (chip->jeita_fcc_config->param.use_bms) @@ -656,6 +910,9 @@ static int handle_jeita(struct step_chg_info *chip) return rc; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + temp = pval.intval; +#endif rc = get_val(chip->jeita_fcc_config->fcc_cfg, chip->jeita_fcc_config->param.hysteresis, chip->jeita_fcc_index, @@ -671,6 +928,11 @@ static int handle_jeita(struct step_chg_info *chip) /* changing FCC is a must */ return -EINVAL; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (rc == -ENODATA) + vote(chip->fcc_votable, JEITA_VOTER, true, fcc_ua); + else +#endif vote(chip->fcc_votable, JEITA_VOTER, fcc_ua ? true : false, fcc_ua); rc = get_val(chip->jeita_fv_config->fv_cfg, @@ -682,6 +944,51 @@ static int handle_jeita(struct step_chg_info *chip) if (rc < 0) fv_uv = 0; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + batt_temp = pval.intval; + rc = power_supply_get_property(chip->bms_psy, + POWER_SUPPLY_PROP_CAPACITY, &pval); + if (rc < 0) { + pr_err("Couldn't read batt_soc fail rc=%d\n", rc); + return rc; + } + batt_soc = pval.intval; + pr_info("%s:batt_soc=%d\n", __func__, batt_soc); + rc = power_supply_get_property(chip->bms_psy, + POWER_SUPPLY_PROP_FASTCHARGE_MODE, &pval); + pr_err("%s:fastcharge_mode=%d\n", __func__, pval.intval); + if (rc < 0) { + pr_err("Couldn't read fastcharge mode fail rc=%d\n", rc); + return rc; + } + if (pval.intval) { + if (batt_soc < 95) { + if (!ffc_temp_is_high && batt_temp > FFC_CHG_TERM_TEMP_THRESHOLD +10) { + ffc_temp_is_high = true; + set_term_curr_flag = true; + } else if (ffc_temp_is_high && batt_temp < FFC_CHG_TERM_TEMP_THRESHOLD-10) { + ffc_temp_is_high = false; + set_term_curr_flag = true; + } + if (set_term_curr_flag) { + rc = power_supply_get_property(chip->bms_psy, + POWER_SUPPLY_PROP_FFC_TERMINATION_CURRENT, &pval); + if (rc < 0) { + pr_err("Couldn't read ffc_term_curr fail rc=%d\n", rc); + return rc; + } + rc = power_supply_set_property(chip->batt_psy, + POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, &pval); + if (rc < 0) { + pr_err("Set charge_term_curr failed, rc=%d\n", rc); + return rc; + } + } + } + } + pval.intval = batt_temp; +#endif + chip->fv_votable = find_votable("FV"); if (!chip->fv_votable) goto update_time; @@ -692,6 +999,62 @@ static int handle_jeita(struct step_chg_info *chip) if (!chip->usb_icl_votable) goto set_jeita_fv; +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + if (!chip->dc_suspend_votable) + chip->dc_suspend_votable = find_votable("DC_SUSPEND"); + + if (!chip->dc_suspend_votable) + goto set_jeita_fv; +#endif + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* set and clear fast charge mode when soft jeita trigger and clear */ + if (chip->six_pin_battery) { + rc = power_supply_get_property(chip->usb_psy, + POWER_SUPPLY_PROP_PD_AUTHENTICATION, &pval); + if (rc < 0) + pr_err("Get fastcharge mode status failed, rc=%d\n", rc); + pd_authen_result = pval.intval; + + rc = power_supply_get_property(chip->usb_psy, + POWER_SUPPLY_PROP_HVDCP3_TYPE, &pval); + if (rc < 0) + pr_err("get hvdcp3_type failed, rc=%d\n", rc); + + if ((pval.intval == HVDCP3_CLASS_B_27W) +#ifdef CONFIG_MACH_XIAOMI_NABU + || (pval.intval == HVDCP3P5_CLASS_A_18W) + || (pval.intval == HVDCP3P5_CLASS_B_27W) +#endif + || (pd_authen_result == 1)) { + if ((temp >= BATT_WARM_THRESHOLD || temp <= BATT_COOL_THRESHOLD) + && !fast_mode_dis) { + pval.intval = false; + rc = power_supply_set_property(chip->usb_psy, + POWER_SUPPLY_PROP_FASTCHARGE_MODE, &pval); + if (rc < 0) { + pr_err("Set fastcharge mode failed, rc=%d\n", rc); + return rc; + } + fast_mode_dis = true; + } else if ((temp < BATT_WARM_THRESHOLD - chip->jeita_fv_config->param.hysteresis) + && (temp > BATT_COOL_THRESHOLD + chip->jeita_fv_config->param.hysteresis) + && fast_mode_dis) { + pval.intval = true; + rc = power_supply_set_property(chip->usb_psy, + POWER_SUPPLY_PROP_FASTCHARGE_MODE, &pval); + if (rc < 0) { + pr_err("Set fastcharge mode failed, rc=%d\n", rc); + return rc; + } + fast_mode_dis = false; + } + } else { + fast_mode_dis = false; + } + } +#endif + /* * If JEITA float voltage is same as max-vfloat of battery then * skip any further VBAT specific checks. @@ -700,6 +1063,9 @@ static int handle_jeita(struct step_chg_info *chip) POWER_SUPPLY_PROP_VOLTAGE_MAX, &pval); if (rc || (pval.intval == fv_uv)) { vote(chip->usb_icl_votable, JEITA_VOTER, false, 0); +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + vote(chip->dc_suspend_votable, JEITA_VOTER, 0, 0); +#endif goto set_jeita_fv; } @@ -707,13 +1073,66 @@ static int handle_jeita(struct step_chg_info *chip) * Suspend USB input path if battery voltage is above * JEITA VFLOAT threshold. */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (fv_uv > 0) { +#else if (chip->jeita_arb_en && fv_uv > 0) { +#endif rc = power_supply_get_property(chip->batt_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (rc < 0) { + pr_err("Get battery voltage failed, rc = %d\n", rc); + goto set_jeita_fv; + } + curr_vbat_uv = pval.intval; + + if (!chip->six_pin_battery) { + if ((curr_vbat_uv > fv_uv) && (temp >= BATT_WARM_THRESHOLD)) + vote(chip->usb_icl_votable, JEITA_VOTER, true, 0); + else if (curr_vbat_uv < (fv_uv - JEITA_SUSPEND_HYST_UV)) + vote(chip->usb_icl_votable, JEITA_VOTER, false, 0); + } else { + curr_vfloat_uv = get_effective_result(chip->fv_votable); + + rc = power_supply_get_property(chip->batt_psy, + POWER_SUPPLY_PROP_CHARGE_TYPE, &pval); + if (rc < 0) { + pr_err("Get charge type failed, rc = %d\n", rc); + goto set_jeita_fv; + } + + if (curr_vfloat_uv != WARM_VFLOAT_UV) { + if (curr_vbat_uv > fv_uv + JEITA_SIX_PIN_BATT_HYST_UV) { + if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER && fv_uv == WARM_VFLOAT_UV) + vote(chip->usb_icl_votable, JEITA_VOTER, true, 0); + } else if (curr_vbat_uv < (fv_uv - JEITA_SUSPEND_HYST_UV)) { + vote(chip->usb_icl_votable, JEITA_VOTER, false, 0); + } + } else { + pr_info("curr_vbat_uv = %duV,FCC =%duA,FV = %duV\n",curr_vbat_uv, fcc_ua, fv_uv); + if (curr_vbat_uv > fv_uv + JEITA_SIX_PIN_BATT_HYST_UV) { + if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER && fv_uv == WARM_VFLOAT_UV) + vote(chip->usb_icl_votable, JEITA_VOTER, true, 0); + } else if (curr_vbat_uv < (fv_uv - JEITA_SUSPEND_HYST_UV)) { + vote(chip->usb_icl_votable, JEITA_VOTER, false, 0); + } + } + } +#elif defined(CONFIG_MACH_XIAOMI_SM8150) + if (!rc && (pval.intval > fv_uv)) { + vote(chip->usb_icl_votable, JEITA_VOTER, true, 0); + vote(chip->dc_suspend_votable, JEITA_VOTER, 1, 0); + } else if (pval.intval < (fv_uv - JEITA_SUSPEND_HYST_UV)) { + vote(chip->usb_icl_votable, JEITA_VOTER, false, 0); + vote(chip->dc_suspend_votable, JEITA_VOTER, 0, 0); + } +#else if (!rc && (pval.intval > fv_uv)) vote(chip->usb_icl_votable, JEITA_VOTER, true, 0); else if (pval.intval < (fv_uv - JEITA_SUSPEND_HYST_UV)) vote(chip->usb_icl_votable, JEITA_VOTER, false, 0); +#endif } set_jeita_fv: @@ -744,6 +1163,9 @@ static int handle_battery_insertion(struct step_chg_info *chip) if (chip->batt_missing) { chip->step_chg_cfg_valid = false; chip->sw_jeita_cfg_valid = false; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chip->dynamic_fv_cfg_valid = false; +#endif chip->get_config_retry_count = 0; } else { /* @@ -765,7 +1187,11 @@ static void status_change_work(struct work_struct *work) int rc = 0; union power_supply_propval prop = {0, }; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (!is_batt_available(chip) || !is_bms_available(chip) || !is_usb_available(chip)) +#else if (!is_batt_available(chip) || !is_bms_available(chip)) +#endif goto exit_work; handle_battery_insertion(chip); @@ -775,6 +1201,12 @@ static void status_change_work(struct work_struct *work) if (rc < 0) pr_err("Couldn't handle sw jeita rc = %d\n", rc); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + rc = handle_dynamic_fv(chip); + if (rc < 0) + pr_err("Couldn't handle sw dynamic fv rc = %d\n", rc); +#endif + rc = handle_step_chg_config(chip); if (rc < 0) pr_err("Couldn't handle step rc = %d\n", rc); @@ -860,6 +1292,9 @@ int qcom_step_chg_init(struct device *dev, chip->step_index = -EINVAL; chip->jeita_fcc_index = -EINVAL; chip->jeita_fv_index = -EINVAL; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chip->dynamic_fv_index = -EINVAL; +#endif chip->step_chg_config = devm_kzalloc(dev, sizeof(struct step_chg_cfg), GFP_KERNEL); @@ -868,22 +1303,45 @@ int qcom_step_chg_init(struct device *dev, chip->step_chg_config->param.psy_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW; chip->step_chg_config->param.prop_name = "VBATT"; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + chip->step_chg_config->param.hysteresis = 10000; +#else chip->step_chg_config->param.hysteresis = 100000; +#endif chip->jeita_fcc_config = devm_kzalloc(dev, sizeof(struct jeita_fcc_cfg), GFP_KERNEL); chip->jeita_fv_config = devm_kzalloc(dev, sizeof(struct jeita_fv_cfg), GFP_KERNEL); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chip->dynamic_fv_config = devm_kzalloc(dev, + sizeof(struct dynamic_fv_cfg), GFP_KERNEL); +#endif +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (!chip->jeita_fcc_config || !chip->jeita_fv_config || !chip->dynamic_fv_config) +#else if (!chip->jeita_fcc_config || !chip->jeita_fv_config) +#endif return -ENOMEM; chip->jeita_fcc_config->param.psy_prop = POWER_SUPPLY_PROP_TEMP; chip->jeita_fcc_config->param.prop_name = "BATT_TEMP"; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chip->jeita_fcc_config->param.hysteresis = 5; +#else chip->jeita_fcc_config->param.hysteresis = 10; +#endif chip->jeita_fv_config->param.psy_prop = POWER_SUPPLY_PROP_TEMP; chip->jeita_fv_config->param.prop_name = "BATT_TEMP"; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chip->jeita_fv_config->param.hysteresis = 5; +#else chip->jeita_fv_config->param.hysteresis = 10; +#endif +#ifdef CONFIG_MACH_XIAOMI_SM8150 + chip->dynamic_fv_config->prop_name = "BATT_CYCLE_COUNT"; +#endif INIT_DELAYED_WORK(&chip->status_change_work, status_change_work); INIT_DELAYED_WORK(&chip->get_config_work, get_config_work); diff --git a/drivers/power/supply/qcom/step-chg-jeita.h b/drivers/power/supply/qcom/step-chg-jeita.h index 26e74ed484e9..3016100a76a5 100644 --- a/drivers/power/supply/qcom/step-chg-jeita.h +++ b/drivers/power/supply/qcom/step-chg-jeita.h @@ -13,7 +13,31 @@ #ifndef __STEP_CHG_H__ #define __STEP_CHG_H__ +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define MAX_STEP_CHG_ENTRIES 6 +#elif defined(CONFIG_MACH_XIAOMI_SM8150) +#define MAX_STEP_CHG_ENTRIES 5 +#else #define MAX_STEP_CHG_ENTRIES 8 +#endif + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define BATT_CP_COOL_THRESHOLD 100 +#define BATT_CP_WARM_THRESHOLD 450 + +#define BATT_COOL_THRESHOLD 150 +#define BATT_WARM_THRESHOLD 450 +#define FFC_CHG_TERM_TEMP_THRESHOLD 350 +enum hvdcp3_class_type { + HVDCP3_CLASS_NONE = 0, + HVDCP3_CLASS_A_18W, + HVDCP3_CLASS_B_27W, +#ifdef CONFIG_MACH_XIAOMI_NABU + HVDCP3P5_CLASS_A_18W, + HVDCP3P5_CLASS_B_27W, +#endif +}; +#endif struct step_chg_jeita_param { u32 psy_prop; @@ -34,4 +58,7 @@ void qcom_step_chg_deinit(void); int read_range_data_from_node(struct device_node *node, const char *prop_str, struct range_data *ranges, int max_threshold, u32 max_value); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int qcom_step_chg_get_step_index(void); +#endif #endif /* __STEP_CHG_H__ */ diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index b8c434c34c8c..578f91092c05 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -117,6 +117,16 @@ enum { POWER_SUPPLY_PL_USBMID_USBMID, }; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +enum { + POWER_SUPPLY_CP_UNKNOWN, + POWER_SUPPLY_CP_MID, + POWER_SUPPLY_CP_MID_EXT, + POWER_SUPPLY_CP_USBIN, + POWER_SUPPLY_CP_USBIN_EXT, +}; +#endif + enum { POWER_SUPPLY_CHARGER_SEC_NONE = 0, POWER_SUPPLY_CHARGER_SEC_CP, @@ -127,7 +137,9 @@ enum { enum { POWER_SUPPLY_CP_NONE = 0, POWER_SUPPLY_CP_HVDCP3, +#ifndef CONFIG_MACH_XIAOMI_VAYU POWER_SUPPLY_CP_HVDCP3P5, +#endif POWER_SUPPLY_CP_PPS, POWER_SUPPLY_CP_WIRELESS, }; @@ -192,6 +204,10 @@ enum power_supply_property { POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_CHARGE_AVG, POWER_SUPPLY_PROP_CHARGE_COUNTER, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_TERMINATION_CURRENT, + POWER_SUPPLY_PROP_FFC_TERMINATION_CURRENT, +#endif POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, @@ -209,6 +225,14 @@ enum power_supply_property { POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN, /* in percents! */ POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX, /* in percents! */ POWER_SUPPLY_PROP_CAPACITY_LEVEL, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_SHUTDOWN_DELAY, + POWER_SUPPLY_PROP_SHUTDOWN_DELAY_ENABLE, + POWER_SUPPLY_PROP_RAW_CAPACITY, + POWER_SUPPLY_PROP_SOC_DECIMAL, + POWER_SUPPLY_PROP_SOC_DECIMAL_RATE, + POWER_SUPPLY_PROP_COLD_THERMAL_LEVEL, +#endif POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_TEMP_MAX, POWER_SUPPLY_PROP_TEMP_MIN, @@ -232,6 +256,10 @@ enum power_supply_property { POWER_SUPPLY_PROP_CHARGE_ENABLED, POWER_SUPPLY_PROP_SET_SHIP_MODE, POWER_SUPPLY_PROP_REAL_TYPE, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_PROP_HVDCP3_TYPE, + POWER_SUPPLY_PROP_QUICK_CHARGE_TYPE, +#endif POWER_SUPPLY_PROP_CHARGE_NOW_RAW, POWER_SUPPLY_PROP_CHARGE_NOW_ERROR, POWER_SUPPLY_PROP_CAPACITY_RAW, @@ -242,6 +270,10 @@ enum power_supply_property { POWER_SUPPLY_PROP_PIN_ENABLED, POWER_SUPPLY_PROP_INPUT_SUSPEND, POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, +#ifdef CONFIG_MACH_XIAOMI_NABU + POWER_SUPPLY_PROP_INPUT_VOLTAGE_VRECT, + POWER_SUPPLY_PROP_RX_IOUT, +#endif POWER_SUPPLY_PROP_INPUT_CURRENT_MAX, POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM, POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, @@ -270,6 +302,9 @@ enum power_supply_property { POWER_SUPPLY_PROP_FLASH_TRIGGER, POWER_SUPPLY_PROP_FORCE_TLIM, POWER_SUPPLY_PROP_DP_DM, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_DP_DM_BQ, +#endif POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED, POWER_SUPPLY_PROP_INPUT_CURRENT_NOW, POWER_SUPPLY_PROP_CHARGE_QNOVO_ENABLE, @@ -286,8 +321,17 @@ enum power_supply_property { POWER_SUPPLY_PROP_TYPEC_SRC_RP, POWER_SUPPLY_PROP_PD_ALLOWED, POWER_SUPPLY_PROP_PD_ACTIVE, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_PROP_PD_AUTHENTICATION, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_PD_REMOVE_COMPENSATION, +#endif +#endif POWER_SUPPLY_PROP_PD_IN_HARD_RESET, POWER_SUPPLY_PROP_PD_CURRENT_MAX, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_APDO_MAX, +#endif POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED, POWER_SUPPLY_PROP_CHARGER_TEMP, POWER_SUPPLY_PROP_CHARGER_TEMP_MAX, @@ -300,6 +344,10 @@ enum power_supply_property { POWER_SUPPLY_PROP_PARALLEL_MODE, POWER_SUPPLY_PROP_DIE_HEALTH, POWER_SUPPLY_PROP_CONNECTOR_HEALTH, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_CONNECTOR_TEMP, + POWER_SUPPLY_PROP_VBUS_DISABLE, +#endif POWER_SUPPLY_PROP_CTM_CURRENT_MAX, POWER_SUPPLY_PROP_HW_CURRENT_MAX, POWER_SUPPLY_PROP_PR_SWAP, @@ -309,15 +357,75 @@ enum power_supply_property { POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, POWER_SUPPLY_PROP_SDP_CURRENT_MAX, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_PROP_DC_THERMAL_LEVELS, +#endif POWER_SUPPLY_PROP_CONNECTOR_TYPE, POWER_SUPPLY_PROP_PARALLEL_BATFET_MODE, POWER_SUPPLY_PROP_PARALLEL_FCC_MAX, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_PROP_WIRELESS_VERSION, +#ifdef CONFIG_MACH_XIAOMI_NABU + POWER_SUPPLY_PROP_WIRELESS_FW_VERSION, +#endif + POWER_SUPPLY_PROP_SIGNAL_STRENGTH, + POWER_SUPPLY_PROP_WIRELESS_CP_EN, + POWER_SUPPLY_PROP_WIRELESS_POWER_GOOD_EN, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_SW_DISABLE_DC_EN, +#endif + POWER_SUPPLY_PROP_WIRELESS_WAKELOCK, +#ifdef CONFIG_MACH_XIAOMI_NABU + POWER_SUPPLY_PROP_WIRELESS_TX_ID, +#endif + POWER_SUPPLY_PROP_TX_ADAPTER, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_TX_MAC, + POWER_SUPPLY_PROP_RX_CR, + POWER_SUPPLY_PROP_RX_CEP, + POWER_SUPPLY_PROP_BT_STATE, +#endif +#ifdef CONFIG_MACH_XIAOMI_NABU + POWER_SUPPLY_PROP_PEN_MAC, +#endif +#endif POWER_SUPPLY_PROP_MIN_ICL, POWER_SUPPLY_PROP_MOISTURE_DETECTED, POWER_SUPPLY_PROP_BATT_PROFILE_VERSION, POWER_SUPPLY_PROP_BATT_FULL_CURRENT, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_BATTERY_CHARGING_LIMITED, + POWER_SUPPLY_PROP_SLOWLY_CHARGING, + POWER_SUPPLY_PROP_BQ_INPUT_SUSPEND, +#endif POWER_SUPPLY_PROP_RECHARGE_SOC, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_RECHARGE_VBAT, + POWER_SUPPLY_PROP_SYS_TERMINATION_CURRENT, + POWER_SUPPLY_PROP_FFC_SYS_TERMINATION_CURRENT, + POWER_SUPPLY_PROP_VBATT_FULL_VOL, + POWER_SUPPLY_PROP_FFC_VBATT_FULL_VOL, + POWER_SUPPLY_PROP_KI_COEFF_CURRENT, + /* battery verify properties */ + POWER_SUPPLY_PROP_ROMID, + POWER_SUPPLY_PROP_DS_STATUS, + POWER_SUPPLY_PROP_PAGENUMBER, + POWER_SUPPLY_PROP_PAGEDATA, + POWER_SUPPLY_PROP_AUTHEN_RESULT, + POWER_SUPPLY_PROP_SESSION_SEED, + POWER_SUPPLY_PROP_S_SECRET, + POWER_SUPPLY_PROP_CHALLENGE, + POWER_SUPPLY_PROP_AUTH_ANON, + POWER_SUPPLY_PROP_AUTH_BDCONST, + POWER_SUPPLY_PROP_PAGE0_DATA, + POWER_SUPPLY_PROP_PAGE1_DATA, + POWER_SUPPLY_PROP_VERIFY_MODEL_NAME, + POWER_SUPPLY_PROP_MAXIM_BATT_CYCLE_COUNT, +#endif POWER_SUPPLY_PROP_HVDCP_OPTI_ALLOWED, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_FASTCHARGE_MODE, +#endif POWER_SUPPLY_PROP_SMB_EN_MODE, POWER_SUPPLY_PROP_SMB_EN_REASON, POWER_SUPPLY_PROP_ESR_ACTUAL, @@ -327,6 +435,11 @@ enum power_supply_property { POWER_SUPPLY_PROP_FORCE_RECHARGE, POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE, POWER_SUPPLY_PROP_TOGGLE_STAT, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_PROP_TYPE_RECHECK, + POWER_SUPPLY_PROP_LIQUID_DETECTION, + POWER_SUPPLY_PROP_DYNAMIC_FV_ENABLED, +#endif POWER_SUPPLY_PROP_MAIN_FCC_MAX, POWER_SUPPLY_PROP_FG_RESET, POWER_SUPPLY_PROP_QC_OPTI_DISABLE, @@ -334,6 +447,9 @@ enum power_supply_property { POWER_SUPPLY_PROP_BATT_AGE_LEVEL, POWER_SUPPLY_PROP_VOLTAGE_VPH, POWER_SUPPLY_PROP_CHIP_VERSION, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_CHIP_OK, +#endif POWER_SUPPLY_PROP_THERM_ICL_LIMIT, POWER_SUPPLY_PROP_DC_RESET, POWER_SUPPLY_PROP_SCALE_MODE_EN, @@ -358,8 +474,49 @@ enum power_supply_property { POWER_SUPPLY_PROP_CP_TOGGLE_SWITCHER, POWER_SUPPLY_PROP_CP_IRQ_STATUS, POWER_SUPPLY_PROP_CP_ILIM, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_PROP_STEP_INDEX, + POWER_SUPPLY_PROP_TI_BATTERY_PRESENT, + POWER_SUPPLY_PROP_TI_VBUS_PRESENT, + POWER_SUPPLY_PROP_TI_BATTERY_VOLTAGE, + POWER_SUPPLY_PROP_TI_BATTERY_CURRENT, + POWER_SUPPLY_PROP_TI_BATTERY_TEMPERATURE, + POWER_SUPPLY_PROP_TI_BUS_VOLTAGE, + POWER_SUPPLY_PROP_TI_BUS_CURRENT, + POWER_SUPPLY_PROP_TI_BUS_TEMPERATURE, + POWER_SUPPLY_PROP_TI_DIE_TEMPERATURE, + POWER_SUPPLY_PROP_TI_ALARM_STATUS, + POWER_SUPPLY_PROP_TI_FAULT_STATUS, + POWER_SUPPLY_PROP_TI_REG_STATUS, + POWER_SUPPLY_PROP_TI_SET_BUS_PROTECTION_FOR_QC3, + POWER_SUPPLY_PROP_TI_BUS_ERROR_STATUS, + POWER_SUPPLY_PROP_TI_CHARGE_MODE, + POWER_SUPPLY_PROP_TI_BYPASS_MODE_ENABLED, +#endif POWER_SUPPLY_PROP_IRQ_STATUS, POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* DIV 2 properties */ + POWER_SUPPLY_PROP_DIV_2_MODE, + POWER_SUPPLY_PROP_REVERSE_CHG_MODE, + POWER_SUPPLY_PROP_REVERSE_CHG_STATE, +#ifdef CONFIG_MACH_XIAOMI_NABU + POWER_SUPPLY_PROP_REVERSE_PEN_CHG_STATE, + POWER_SUPPLY_PROP_REVERSE_GPIO_STATE, +#endif + POWER_SUPPLY_PROP_RESET_DIV_2_MODE, +#ifdef CONFIG_MACH_XIAOMI_NABU + POWER_SUPPLY_PROP_AICL_ENABLE, + POWER_SUPPLY_PROP_OTG_STATE, + POWER_SUPPLY_PROP_REVERSE_CHG_HALL3, + POWER_SUPPLY_PROP_REVERSE_CHG_HALL4, + POWER_SUPPLY_PROP_REVERSE_PEN_SOC, + POWER_SUPPLY_PROP_REVERSE_VOUT, + POWER_SUPPLY_PROP_REVERSE_IOUT, +#endif + POWER_SUPPLY_PROP_RX_OP_BLE, + POWER_SUPPLY_PROP_OP_BLE, +#endif /* Local extensions of type int64_t */ POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT, /* Properties of type `const char *' */ @@ -395,6 +552,12 @@ enum power_supply_type { POWER_SUPPLY_TYPE_UFP, /* Type-C UFP */ POWER_SUPPLY_TYPE_DFP, /* Type-C DFP */ POWER_SUPPLY_TYPE_CHARGE_PUMP, /* Charge Pump */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + POWER_SUPPLY_TYPE_ZIMI_CAR_POWER, /* Zimi Car chargr */ +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + POWER_SUPPLY_TYPE_BATT_VERIFY, /* battery verify */ +#endif +#endif }; /* Indicates USB Type-C CC connection status */ @@ -436,6 +599,9 @@ union power_supply_propval { int intval; const char *strval; int64_t int64val; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + unsigned char arrayval[50]; +#endif }; struct device_node; From e6e0eaa57a153a6dd3a69520fbedaba5567a6219 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:32:27 +0200 Subject: [PATCH 087/226] drivers: regulator: Import Xiaomi changes Change-Id: Icbe3bfb4f35f9c7d0c7b04eeb2bbf0c53d31e4cd Signed-off-by: firebird11 --- drivers/regulator/qpnp-lcdb-regulator.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/regulator/qpnp-lcdb-regulator.c b/drivers/regulator/qpnp-lcdb-regulator.c index 396ed5415eea..a4c130279bd1 100644 --- a/drivers/regulator/qpnp-lcdb-regulator.c +++ b/drivers/regulator/qpnp-lcdb-regulator.c @@ -1283,6 +1283,19 @@ static int qpnp_lcdb_get_voltage(struct qpnp_lcdb *lcdb, return rc; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if ((val & 0x80) && (type == NCP))//NCP follow 0x71 LDO + { + offset = LCDB_LDO_OUTPUT_VOLTAGE_REG; + + rc = qpnp_lcdb_read(lcdb, lcdb->base + offset, &val, 1); + if (rc < 0) { + pr_err("Failed to read NCP volatge rc=%d\n", rc); + return rc; + } + } +#endif + val &= SET_OUTPUT_VOLTAGE_MASK; if (val < VOLTAGE_STEP_50MV_OFFSET) { *voltage_mv = VOLTAGE_MIN_STEP_100_MV + From c002beae8684e49df84076e43394ca49e1c72f4a Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:33:47 +0200 Subject: [PATCH 088/226] drivers: scsi: ufs: Import Xiaomi changes Change-Id: If39fe42fd22910e9ef55c0effa4a4a9b27cd6fed Signed-off-by: firebird11 --- drivers/scsi/ufs/ufs-qcom.c | 8 ++++++++ drivers/scsi/ufs/ufs_quirks.h | 3 +++ drivers/scsi/ufs/ufshcd.c | 25 +++++++++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 69ae57be7a5d..442694bd20d6 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -1268,9 +1268,17 @@ static void ufs_qcom_dev_ref_clk_ctrl(struct ufs_qcom_host *host, bool enable) if (enable) { if (host->hba->dev_info.quirks & UFS_DEVICE_QUIRK_WAIT_AFTER_REF_CLK_UNGATE) +#ifdef CONFIG_MACH_XIAOMI_SM8150 + usleep_range(960, 970); +#else usleep_range(50, 60); +#endif else +#ifdef CONFIG_MACH_XIAOMI_SM8150 + usleep_range(200, 210); +#else udelay(1); +#endif } host->is_dev_ref_clk_enabled = enable; diff --git a/drivers/scsi/ufs/ufs_quirks.h b/drivers/scsi/ufs/ufs_quirks.h index 07731d172fe6..98051585ef33 100644 --- a/drivers/scsi/ufs/ufs_quirks.h +++ b/drivers/scsi/ufs/ufs_quirks.h @@ -26,6 +26,9 @@ #define UFS_VENDOR_SAMSUNG 0x1CE #define UFS_VENDOR_SKHYNIX 0x1AD #define UFS_VENDOR_WDC 0x145 +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define UFS_VENDOR_SANDISK 0x0145 +#endif /** * ufs_dev_fix - ufs device quirk info diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 994ee23ccd7f..7bfac837b605 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -213,6 +213,10 @@ static void ufshcd_update_uic_error_cnt(struct ufs_hba *hba, u32 reg, int type) /* UIC command timeout, unit: ms */ #define UIC_CMD_TIMEOUT 500 +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define UIC_PWR_CTRL_TIMEOUT 3000 +#endif + /* NOP OUT retries waiting for NOP IN response */ #define NOP_OUT_RETRIES 10 /* Timeout after 30 msecs if NOP OUT hangs without response */ @@ -221,7 +225,11 @@ static void ufshcd_update_uic_error_cnt(struct ufs_hba *hba, u32 reg, int type) /* Query request retries */ #define QUERY_REQ_RETRIES 3 /* Query request timeout */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define QUERY_REQ_TIMEOUT 3000 /* 3.0 seconds */ +#else #define QUERY_REQ_TIMEOUT 1500 /* 1.5 seconds */ +#endif /* Task management command timeout */ #define TM_CMD_TIMEOUT 100 /* msecs */ @@ -428,6 +436,10 @@ static struct ufs_dev_fix ufs_fixups[] = { UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME), UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL, UFS_DEVICE_QUIRK_WAIT_AFTER_REF_CLK_UNGATE), +#ifdef CONFIG_MACH_XIAOMI_SM8150 + UFS_FIX(UFS_VENDOR_SANDISK, UFS_ANY_MODEL, + UFS_DEVICE_QUIRK_WAIT_AFTER_REF_CLK_UNGATE), +#endif UFS_FIX(UFS_VENDOR_SKHYNIX, "hB8aL1", UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH), UFS_FIX(UFS_VENDOR_SKHYNIX, "hC8aL1", @@ -442,6 +454,10 @@ static struct ufs_dev_fix ufs_fixups[] = { UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH), UFS_FIX(UFS_VENDOR_SKHYNIX, "hC8HL1", UFS_DEVICE_QUIRK_HS_G1_TO_HS_G3_SWITCH), +#ifdef CONFIG_MACH_XIAOMI_SM8150 + UFS_FIX(UFS_VENDOR_SANDISK, UFS_ANY_MODEL, + UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE), +#endif END_FIX }; @@ -5132,8 +5148,13 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) } more_wait: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (!wait_for_completion_timeout(hba->uic_async_done, + msecs_to_jiffies(UIC_PWR_CTRL_TIMEOUT))) { +#else if (!wait_for_completion_timeout(hba->uic_async_done, msecs_to_jiffies(UIC_CMD_TIMEOUT))) { +#endif u32 intr_status = 0; s64 ts_since_last_intr; @@ -5644,7 +5665,11 @@ static int ufshcd_complete_dev_init(struct ufs_hba *hba) * Some vendor devices are taking longer time to complete its internal * initialization, so set fDeviceInit flag poll time to 5 secs */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + timeout = ktime_add_ms(ktime_get(), 8000); +#else timeout = ktime_add_ms(ktime_get(), 5000); +#endif /* poll for max. 5sec for fDeviceInit flag to clear */ while (1) { From 27a15c78bd11315170099f69bc5ce9dfef6dbd6e Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:36:43 +0200 Subject: [PATCH 089/226] drivers: sensors: Import Xiaomi changes Change-Id: I22bcac45b0f804931f9bf32a89e2fbd2e010f9c0 Signed-off-by: firebird11 --- drivers/sensors/sensors_ssc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/sensors/sensors_ssc.c b/drivers/sensors/sensors_ssc.c index dfdbd8e8df69..619b0bbdba16 100644 --- a/drivers/sensors/sensors_ssc.c +++ b/drivers/sensors/sensors_ssc.c @@ -123,6 +123,14 @@ static void slpi_load_fw(struct work_struct *slpi_ldr_work) fail: dev_err(&pdev->dev, "%s: SLPI image loading failed\n", __func__); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + priv->pil_h = subsystem_get_with_fwname("slpi", "slpi"); + if (IS_ERR(priv->pil_h)) { + dev_err(&pdev->dev, "%s: SLPI image re-loading failed\n", __func__); + } else { + dev_info(&pdev->dev, "%s: SLPI image is loaded\n", __func__); + } +#endif } static void slpi_loader_do(struct platform_device *pdev) From f86956688b35ed8c1083ac2d4287509764c6afc4 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:39:17 +0200 Subject: [PATCH 090/226] drivers: soc: qcom: Import Xiaomi changes Change-Id: Ic0c898b3ad242541751029d70958786d401ec054 Signed-off-by: firebird11 --- drivers/soc/qcom/fsa4480-i2c.c | 4 + drivers/soc/qcom/microdump_collector.c | 131 +++++++++++++++++++++++++ drivers/soc/qcom/socinfo.c | 87 ++++++++++++++++ drivers/soc/qcom/watchdog_v2.c | 4 + include/soc/qcom/socinfo.h | 37 +++++++ 5 files changed, 263 insertions(+) diff --git a/drivers/soc/qcom/fsa4480-i2c.c b/drivers/soc/qcom/fsa4480-i2c.c index cddb520ac4cf..1ff3d7c0d9fd 100644 --- a/drivers/soc/qcom/fsa4480-i2c.c +++ b/drivers/soc/qcom/fsa4480-i2c.c @@ -319,7 +319,11 @@ int fsa4480_switch_event(struct device_node *node, else switch_control = 0x7; fsa4480_usbc_update_settings(fsa_priv, switch_control, 0x9F); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + return 1; +#else break; +#endif case FSA_USBC_ORIENTATION_CC1: fsa4480_usbc_update_settings(fsa_priv, 0x18, 0xF8); return fsa4480_validate_display_port_settings(fsa_priv); diff --git a/drivers/soc/qcom/microdump_collector.c b/drivers/soc/qcom/microdump_collector.c index d55f3d177cdc..a4506ac2908d 100644 --- a/drivers/soc/qcom/microdump_collector.c +++ b/drivers/soc/qcom/microdump_collector.c @@ -8,7 +8,15 @@ #include #include #include +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#include +#include +#include +#endif +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define MAX_SSR_REASON_LEN 130U +#endif #define SMEM_SSR_REASON_MSS0 421 #define SMEM_SSR_DATA_MSS0 611 #define SMEM_MODEM 1 @@ -19,6 +27,82 @@ * user space. */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define STR_NV_SIGNATURE_DESTROYED "CRITICAL_DATA_CHECK_FAILED" + +static struct kobject *checknv_kobj; +static struct kset *checknv_kset; + +static const struct sysfs_ops checknv_sysfs_ops = { +}; + +static void kobj_release(struct kobject *kobj) +{ + kfree(kobj); +} + +static struct kobj_type checknv_ktype = { + .sysfs_ops = &checknv_sysfs_ops, + .release = kobj_release, +}; + +static void checknv_kobj_clean(struct work_struct *work) +{ + kobject_uevent(checknv_kobj, KOBJ_REMOVE); + kobject_put(checknv_kobj); + kset_unregister(checknv_kset); +} + +static void checknv_kobj_create(struct work_struct *work) +{ + int ret; + + if (checknv_kset != NULL) { + pr_err("checknv_kset is not NULL, should clean up."); + kobject_uevent(checknv_kobj, KOBJ_REMOVE); + kobject_put(checknv_kobj); + } + + checknv_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); + if (!checknv_kobj) { + pr_err("kobject alloc failed."); + return; + } + + if (checknv_kset == NULL) { + checknv_kset = kset_create_and_add("checknv_errimei", NULL, NULL); + if (!checknv_kset) { + pr_err("kset creation failed."); + goto free_kobj; + } + } + + checknv_kobj->kset = checknv_kset; + + ret = kobject_init_and_add(checknv_kobj, &checknv_ktype, NULL, "%s", "errimei"); + if (ret) { + pr_err("%s: Error in creation kobject", __func__); + goto del_kobj; + } + + kobject_uevent(checknv_kobj, KOBJ_ADD); + return; + +del_kobj: + kobject_put(checknv_kobj); + kset_unregister(checknv_kset); + +free_kobj: + kfree(checknv_kobj); +} + +static DECLARE_DELAYED_WORK(create_kobj_work, checknv_kobj_create); +static DECLARE_WORK(clean_kobj_work, checknv_kobj_clean); + +static char last_modem_sfr_reason[MAX_SSR_REASON_LEN] = "none"; +static struct proc_dir_entry *last_modem_sfr_entry; +#endif + struct microdump_data { struct ramdump_device *microdump_dev; void *microdump_modem_notify_handler; @@ -65,6 +149,18 @@ static int microdump_modem_notifier_nb(struct notifier_block *nb, segment[1].v_address = crash_data; segment[1].size = size_data; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + strlcpy(last_modem_sfr_reason, crash_reason, MAX_SSR_REASON_LEN); + pr_err("modem subsystem failure reason: %s.\n", last_modem_sfr_reason); + + // If the NV protected file (critical_info) is destroyed, restart to recovery to inform user + if (strnstr(last_modem_sfr_reason, STR_NV_SIGNATURE_DESTROYED, strlen(last_modem_sfr_reason))) { + pr_err("errimei_dev: the NV has been destroyed, should restart to recovery\n"); + schedule_delayed_work(&create_kobj_work, msecs_to_jiffies(1*1000)); + goto out; + } +#endif + ret = do_ramdump(drv->microdump_dev, segment, 2); if (ret) pr_info("%s: do_ramdump() failed\n", __func__); @@ -99,6 +195,27 @@ static void microdump_modem_ssr_unregister_notifier(struct microdump_data *drv) drv->microdump_modem_notify_handler = NULL; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static int last_modem_sfr_proc_show(struct seq_file *m, void *v) +{ + seq_printf(m, "%s\n", last_modem_sfr_reason); + return 0; +} + +static int last_modem_sfr_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, last_modem_sfr_proc_show, NULL); +} + +static const struct file_operations last_modem_sfr_file_ops = { + .owner = THIS_MODULE, + .open = last_modem_sfr_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + /* * microdump_init() - Registers kernel module for microdump collector * @@ -111,6 +228,13 @@ static int __init microdump_init(void) { int ret = -ENOMEM; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + last_modem_sfr_entry = proc_create("last_mcrash", S_IFREG | S_IRUGO, NULL, &last_modem_sfr_file_ops); + if (!last_modem_sfr_entry) { + printk(KERN_ERR "pil: cannot create proc entry last_mcrash\n"); + } +#endif + drv = kzalloc(sizeof(struct microdump_data), GFP_KERNEL); if (!drv) goto out; @@ -140,6 +264,13 @@ static int __init microdump_init(void) static void __exit microdump_exit(void) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + schedule_work(&clean_kobj_work); + if (last_modem_sfr_entry) { + remove_proc_entry("last_mcrash", NULL); + last_modem_sfr_entry = NULL; + } +#endif microdump_modem_ssr_unregister_notifier(drv); destroy_ramdump_device(drv->microdump_dev); kfree(drv); diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 9e749e559937..69217e749b9d 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -71,6 +71,14 @@ enum { HW_PLATFORM_HDK = 31, HW_PLATFORM_IOT = 32, HW_PLATFORM_IDP = 34, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + HW_PLATFORM_F1 = 37, + HW_PLATFORM_E5G = 39, + HW_PLATFORM_F11 = 40, + HW_PLATFORM_F1X = 43, + HW_PLATFORM_J20S = 47, + HW_PLATFORM_K82 = 48, +#endif HW_PLATFORM_INVALID }; @@ -96,6 +104,15 @@ const char *hw_platform[] = { [HW_PLATFORM_HDK] = "HDK", [HW_PLATFORM_IOT] = "IOT", [HW_PLATFORM_IDP] = "IDP" +#ifdef CONFIG_MACH_XIAOMI_SM8150 + , + [HW_PLATFORM_F1] = "CEPHEUS", + [HW_PLATFORM_E5G] = "ANDROMEDA", + [HW_PLATFORM_F11] = "RAPHAEL", + [HW_PLATFORM_F1X] = "CRUX", + [HW_PLATFORM_J20S] = "VAYU", + [HW_PLATFORM_K82] = "NABU", +#endif }; enum { @@ -1815,6 +1832,76 @@ static void socinfo_select_format(void) } } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +const char *product_name_get(void) +{ + char *product_name = NULL; + size_t size; + uint32_t hw_type; + + hw_type = socinfo_get_platform_type(); + + product_name = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_ID_VENDOR1, &size); + if (IS_ERR_OR_NULL(product_name)) { + pr_warn("Can't find SMEM_ID_VENDOR1; falling back on dummy values.\n"); + return hw_platform[hw_type]; + } + + return product_name; +} + +EXPORT_SYMBOL(product_name_get); + +uint32_t get_hw_country_version(void) +{ + uint32_t version = socinfo_get_platform_version(); + return (version & HW_COUNTRY_VERSION_MASK) >> HW_COUNTRY_VERSION_SHIFT; +} + +EXPORT_SYMBOL(get_hw_country_version); + +uint32_t get_hw_version_platform(void) +{ + uint32_t hw_type = socinfo_get_platform_type(); + if (hw_type == HW_PLATFORM_F1) + return HARDWARE_PLATFORM_CEPHEUS; + else if (hw_type == HW_PLATFORM_E5G) + return HARDWARE_PLATFORM_ANDROMEDA; + else if (hw_type == HW_PLATFORM_F11) + return HARDWARE_PLATFORM_RAPHAEL; + else if (hw_type == HW_PLATFORM_F1X) + return HARDWARE_PLATFORM_CRUX; + else if (hw_type == HW_PLATFORM_J20S) + return HARDWARE_PLATFORM_VAYU; + else if (hw_type == HW_PLATFORM_K82) + return HARDWARE_PLATFORM_NABU; + else + return HARDWARE_PLATFORM_UNKNOWN; +} +EXPORT_SYMBOL(get_hw_version_platform); + +uint32_t get_hw_version_major(void) +{ + uint32_t version = socinfo_get_platform_version(); + return (version & HW_MAJOR_VERSION_MASK) >> HW_MAJOR_VERSION_SHIFT; +} +EXPORT_SYMBOL(get_hw_version_major); + +uint32_t get_hw_version_minor(void) +{ + uint32_t version = socinfo_get_platform_version(); + return (version & HW_MINOR_VERSION_MASK) >> HW_MINOR_VERSION_SHIFT; +} +EXPORT_SYMBOL(get_hw_version_minor); + +uint32_t get_hw_version_build(void) +{ + uint32_t version = socinfo_get_platform_version(); + return (version & HW_BUILD_VERSION_MASK) >> HW_BUILD_VERSION_SHIFT; +} +EXPORT_SYMBOL(get_hw_version_build); +#endif + int __init socinfo_init(void) { static bool socinfo_init_done; diff --git a/drivers/soc/qcom/watchdog_v2.c b/drivers/soc/qcom/watchdog_v2.c index e4eaa8b8e77e..4518d1e1ab5f 100644 --- a/drivers/soc/qcom/watchdog_v2.c +++ b/drivers/soc/qcom/watchdog_v2.c @@ -746,7 +746,11 @@ static void init_watchdog_data(struct msm_watchdog_data *wdog_dd) configure_bark_dump(wdog_dd); timeout = (wdog_dd->bark_time * WDT_HZ)/1000; __raw_writel(timeout, wdog_dd->base + WDT0_BARK_TIME); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + __raw_writel(timeout + 10*WDT_HZ, wdog_dd->base + WDT0_BITE_TIME); +#else __raw_writel(timeout + 3*WDT_HZ, wdog_dd->base + WDT0_BITE_TIME); +#endif wdog_dd->panic_blk.notifier_call = panic_wdog_handler; atomic_notifier_chain_register(&panic_notifier_list, diff --git a/include/soc/qcom/socinfo.h b/include/soc/qcom/socinfo.h index b9e3927081d3..ad076636242c 100644 --- a/include/soc/qcom/socinfo.h +++ b/include/soc/qcom/socinfo.h @@ -178,6 +178,9 @@ #define SMEM_IMAGE_VERSION_TABLE 469 #define SMEM_HW_SW_BUILD_ID 137 +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define SMEM_ID_VENDOR1 135 +#endif enum msm_cpu { MSM_CPU_UNKNOWN = 0, MSM_CPU_8960, @@ -246,6 +249,32 @@ enum pmic_model { PMIC_MODEL_UNKNOWN = 0xFFFFFFFF }; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define HARDWARE_PLATFORM_UNKNOWN 0 +#define HARDWARE_PLATFORM_CEPHEUS 1 +#define HARDWARE_PLATFORM_ANDROMEDA 3 +#define HARDWARE_PLATFORM_RAPHAEL 4 +#define HARDWARE_PLATFORM_VAYU 6 +#define HARDWARE_PLATFORM_CRUX 7 +#define HARDWARE_PLATFORM_NABU 8 + +#define HW_MAJOR_VERSION_SHIFT 16 +#define HW_MAJOR_VERSION_MASK 0xFFFF0000 +#define HW_MINOR_VERSION_SHIFT 0 +#define HW_MINOR_VERSION_MASK 0x0000FFFF +#define HW_COUNTRY_VERSION_MASK 0xFFF00000 +#define HW_COUNTRY_VERSION_SHIFT 20 +#define HW_BUILD_VERSION_MASK 0x000F0000 +#define HW_BUILD_VERSION_SHIFT 16 + +typedef enum { + CountryCN = 0, + CountryGlobal = 1, + CountryIndia = 2, + INVALID, +} CountryType; +#endif + enum msm_cpu socinfo_get_msm_cpu(void); uint32_t socinfo_get_id(void); uint32_t socinfo_get_version(void); @@ -258,6 +287,14 @@ uint32_t socinfo_get_platform_version(void); uint32_t socinfo_get_serial_number(void); enum pmic_model socinfo_get_pmic_model(void); uint32_t socinfo_get_pmic_die_revision(void); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +uint32_t get_hw_version_platform(void); +uint32_t get_hw_country_version(void); +uint32_t get_hw_version_major(void); +uint32_t get_hw_version_minor(void); +uint32_t get_hw_version_build(void); +const char *product_name_get(void); +#endif int __init socinfo_init(void) __must_check; #endif From 11b59db7ce5b417e6fd5d66fcb9c9fd18cfcaf7b Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:39:49 +0200 Subject: [PATCH 091/226] drivers: spi: Import Xiaomi changes Change-Id: Ic55a5b60361e6b9b5e4dd6d3b0adf4bf1780aeeb Signed-off-by: firebird11 --- drivers/spi/spi-geni-qcom.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c index 25ac91e53fbd..4f470d580303 100644 --- a/drivers/spi/spi-geni-qcom.c +++ b/drivers/spi/spi-geni-qcom.c @@ -29,7 +29,11 @@ #include #define SPI_NUM_CHIPSELECT (4) +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define SPI_XFER_TIMEOUT_MS (1500) +#else #define SPI_XFER_TIMEOUT_MS (250) +#endif #define SPI_AUTO_SUSPEND_DELAY (250) /* SPI SE specific registers */ #define SE_SPI_CPHA (0x224) From 9ed94fb2ec71c69780136ed9cc71cf51d78d5784 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:43:31 +0200 Subject: [PATCH 092/226] drivers: thermal: Import Xiaomi changes Change-Id: I990d079bb5611fa83cdeb467a11f14e72a4cd80f Signed-off-by: firebird11 --- drivers/thermal/cpu_cooling.c | 56 ++++++++ drivers/thermal/thermal_core.c | 229 +++++++++++++++++++++++++++++++++ include/linux/cpu_cooling.h | 4 + 3 files changed, 289 insertions(+) diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 786a9e2c4e4d..b31416a556c8 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -300,7 +300,11 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb, unsigned long clipped_freq = ULONG_MAX, floor_freq = 0; struct cpufreq_cooling_device *cpufreq_cdev; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (event != CPUFREQ_THERMAL) +#else if (event != CPUFREQ_INCOMPATIBLE) +#endif return NOTIFY_DONE; mutex_lock(&cooling_list_lock); @@ -331,13 +335,45 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb, * Similarly, if policy minimum set by the user is less than * the floor_frequency, then adjust the policy->min. */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + cpufreq_verify_within_limits(policy, floor_freq, clipped_freq); +#else if (policy->max > clipped_freq || policy->min < floor_freq) cpufreq_verify_within_limits(policy, floor_freq, clipped_freq); +#endif mutex_unlock(&cooling_list_lock); return NOTIFY_OK; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +void cpu_limits_set_level(unsigned int cpu, unsigned int max_freq) +{ + struct cpufreq_cooling_device *cpufreq_cdev; + struct thermal_cooling_device *cdev; + unsigned int cdev_cpu; + unsigned int level; + + list_for_each_entry(cpufreq_cdev, &cpufreq_cdev_list, node) { + sscanf(cpufreq_cdev->cdev->type, "thermal-cpufreq-%d", &cdev_cpu); + if (cdev_cpu == cpu) { + for (level = 0; level < cpufreq_cdev->max_level; level++) { + int target_freq = cpufreq_cdev->freq_table[level].frequency; + if (max_freq >= target_freq) { + cdev = cpufreq_cdev->cdev; + if (cdev) + cdev->ops->set_cur_state(cdev, level); + + break; + } + } + + break; + } + } +} +#endif + /** * update_freq_table() - Update the freq table with power numbers * @cpufreq_cdev: the cpufreq cooling device in which to update the table @@ -674,7 +710,11 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, /* Request state should be less than max_level */ if (WARN_ON(state > cpufreq_cdev->max_level)) +#ifdef CONFIG_MACH_XIAOMI_SM8150 + state = cpufreq_cdev->max_level; +#else return -EINVAL; +#endif /* Check if the old cooling action is same as new cooling action */ if (cpufreq_cdev->cpufreq_state == state) @@ -720,6 +760,11 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, cpufreq_cdev->cpufreq_state = state; cpufreq_cdev->clipped_freq = clip_freq; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + get_online_cpus(); + cpufreq_update_policy(cpu); + put_online_cpus(); +#else /* Check if the device has a platform mitigation function that * can handle the CPU freq mitigation, if not, notify cpufreq * framework. @@ -731,6 +776,7 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, } else { cpufreq_update_policy(cpu); } +#endif return 0; } @@ -1087,7 +1133,11 @@ __cpufreq_cooling_register(struct device_node *np, list_add(&cpufreq_cdev->node, &cpufreq_cdev_list); mutex_unlock(&cooling_list_lock); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (first) +#else if (first && !cpufreq_cdev->plat_ops) +#endif cpufreq_register_notifier(&thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER); if (!cpuhp_registered) { @@ -1280,10 +1330,16 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) if (last) { unregister_pm_notifier(&cpufreq_cooling_pm_nb); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + cpufreq_unregister_notifier( + &thermal_cpufreq_notifier_block, + CPUFREQ_POLICY_NOTIFIER); +#else if (!cpufreq_cdev->plat_ops) cpufreq_unregister_notifier( &thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER); +#endif } thermal_cooling_device_unregister(cpufreq_cdev->cdev); diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 6df9a1c24217..9d769e1c4e39 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -25,6 +25,13 @@ #include #include #include +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#include + +#ifdef CONFIG_DRM +#include +#endif +#endif #define CREATE_TRACE_POINTS #include @@ -38,6 +45,10 @@ MODULE_LICENSE("GPL v2"); #define THERMAL_MAX_ACTIVE 16 +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define CPU_LIMITS_PARAM_NUM 2 +#endif + static DEFINE_IDA(thermal_tz_ida); static DEFINE_IDA(thermal_cdev_ida); @@ -56,6 +67,21 @@ static struct thermal_governor *def_governor; static struct workqueue_struct *thermal_passive_wq; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#ifdef CONFIG_DRM +struct screen_monitor { + struct notifier_block thermal_notifier; + int screen_state; /* 1: on; 0:off */ +}; + +struct screen_monitor sm; +#endif + +static atomic_t switch_mode = ATOMIC_INIT(-1); +static atomic_t temp_state = ATOMIC_INIT(0); +static char boost_buf[128]; +#endif + /* * Governor section: set of functions to handle thermal governors * @@ -944,6 +970,10 @@ static struct class thermal_class = { .dev_release = thermal_release, }; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static struct device thermal_message_dev; +#endif + static inline void print_bind_err_msg(struct thermal_zone_device *tz, struct thermal_cooling_device *cdev, int ret) @@ -1624,6 +1654,185 @@ static struct notifier_block thermal_pm_nb = { .notifier_call = thermal_pm_notify, }; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#ifdef CONFIG_DRM +static ssize_t +thermal_screen_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", sm.screen_state); +} + +static DEVICE_ATTR(screen_state, 0644, + thermal_screen_state_show, NULL); +#endif + +static ssize_t +thermal_sconfig_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&switch_mode)); +} + +static ssize_t +thermal_sconfig_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + int val = -1; + + val = simple_strtol(buf, NULL, 10); + + atomic_set(&switch_mode, val); + + return len; +} + +static DEVICE_ATTR(sconfig, 0664, + thermal_sconfig_show, thermal_sconfig_store); + +static ssize_t +thermal_boost_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, boost_buf); +} + +static ssize_t +thermal_boost_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + int ret; + ret = snprintf(boost_buf, PAGE_SIZE, buf); + return len; +} + +static DEVICE_ATTR(boost, 0644, + thermal_boost_show, thermal_boost_store); + +static ssize_t +thermal_temp_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&temp_state)); +} + +static ssize_t +thermal_temp_state_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + int val = -1; + + val = simple_strtol(buf, NULL, 10); + + atomic_set(&temp_state, val); + + return len; +} + +static DEVICE_ATTR(temp_state, 0664, + thermal_temp_state_show, thermal_temp_state_store); + +static ssize_t +cpu_limits_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return 0; +} + +static ssize_t +cpu_limits_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + unsigned int cpu; + unsigned int max; + + if (sscanf(buf, "cpu%u %u", &cpu, &max) != CPU_LIMITS_PARAM_NUM) { + pr_err("input param error, can not prase param\n"); + return -EINVAL; + } + + cpu_limits_set_level(cpu, max); + + return len; +} + +static DEVICE_ATTR(cpu_limits, 0664, + cpu_limits_show, cpu_limits_store); + +static int create_thermal_message_node(void) +{ + int ret = 0; + + thermal_message_dev.class = &thermal_class; + + dev_set_name(&thermal_message_dev, "thermal_message"); + ret = device_register(&thermal_message_dev); + if (!ret) { +#ifdef CONFIG_DRM + ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_screen_state.attr); + if (ret < 0) + pr_warn("Thermal: create batt message node failed\n"); +#endif + ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_sconfig.attr); + if (ret < 0) + pr_warn("Thermal: create sconfig node failed\n"); + + ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_boost.attr); + if (ret < 0) + pr_warn("Thermal: create boost node failed\n"); + + ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_temp_state.attr); + if (ret < 0) + pr_warn("Thermal: create temp state node failed\n"); + + ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_cpu_limits.attr); + if (ret < 0) + pr_warn("Thermal: create cpu limits node failed\n"); + } + + return ret; +} + +static void destroy_thermal_message_node(void) +{ + sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_cpu_limits.attr); + sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_temp_state.attr); + sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_boost.attr); + sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_sconfig.attr); +#ifdef CONFIG_DRM + sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_screen_state.attr); +#endif + device_unregister(&thermal_message_dev); +} + +#ifdef CONFIG_DRM +static int screen_state_for_thermal_callback(struct notifier_block *nb, unsigned long val, void *data) +{ + struct msm_drm_notifier *evdata = data; + unsigned int blank; + + if (val != MSM_DRM_EVENT_BLANK || !evdata || !evdata->data) + return 0; + + blank = *(int *)(evdata->data); + switch (blank) { + case MSM_DRM_BLANK_POWERDOWN: + sm.screen_state = 0; + break; + case MSM_DRM_BLANK_UNBLANK: + sm.screen_state = 1; + break; + default: + break; + } + + sysfs_notify(&thermal_message_dev.kobj, NULL, "screen_state"); + + return NOTIFY_OK; +} +#endif +#endif + static int __init thermal_init(void) { int result; @@ -1655,6 +1864,20 @@ static int __init thermal_init(void) pr_warn("Thermal: Can not register suspend notifier, return %d\n", result); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + result = create_thermal_message_node(); + if (result) + pr_warn("Thermal: create thermal message node failed, return %d\n", + result); + +#ifdef CONFIG_DRM + sm.thermal_notifier.notifier_call = screen_state_for_thermal_callback; + if (msm_drm_register_client(&sm.thermal_notifier) < 0) { + pr_warn("Thermal: register screen state callback failed\n"); + } +#endif +#endif + return 0; exit_zone_parse: @@ -1674,6 +1897,12 @@ static int __init thermal_init(void) static void thermal_exit(void) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#ifdef CONFIG_DRM + msm_drm_unregister_client(&sm.thermal_notifier); +#endif + destroy_thermal_message_node(); +#endif unregister_pm_notifier(&thermal_pm_nb); of_thermal_destroy_zones(); destroy_workqueue(thermal_passive_wq); diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index f85fa59e6009..8ed9c87e81b7 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h @@ -54,6 +54,10 @@ struct thermal_cooling_device * cpufreq_platform_cooling_register(const struct cpumask *clip_cpus, struct cpu_cooling_ops *ops); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +void cpu_limits_set_level(unsigned int cpu, unsigned int max_freq); +#endif + /** * of_cpufreq_cooling_register - create cpufreq cooling device based on DT. * @np: a valid struct device_node to the cooling device device tree node. From b640c4a9e55bacd42428cd01925601e20466c9bd Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:44:13 +0200 Subject: [PATCH 093/226] drivers: Import Trusty TEE driver Change-Id: I48972b00e02dccc1382dfa329103417141410b35 Signed-off-by: firebird11 --- drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/trusty/Kconfig | 68 + drivers/trusty/Makefile | 17 + drivers/trusty/trusty-fiq-arm.c | 42 + drivers/trusty/trusty-fiq-arm64-glue.S | 60 + drivers/trusty/trusty-fiq-arm64.c | 173 ++ drivers/trusty/trusty-fiq.c | 88 + drivers/trusty/trusty-fiq.h | 17 + drivers/trusty/trusty-hee-irqs.c | 100 + drivers/trusty/trusty-ipc.c | 2438 ++++++++++++++++++++++++ drivers/trusty/trusty-irq.c | 598 ++++++ drivers/trusty/trusty-link-shbuf.c | 691 +++++++ drivers/trusty/trusty-link-shbuf.h | 58 + drivers/trusty/trusty-log.c | 275 +++ drivers/trusty/trusty-log.h | 17 + drivers/trusty/trusty-mem.c | 158 ++ drivers/trusty/trusty-shm.c | 209 ++ drivers/trusty/trusty-virq.c | 242 +++ drivers/trusty/trusty-virq.h | 55 + drivers/trusty/trusty-virtio.c | 761 ++++++++ drivers/trusty/trusty.c | 662 +++++++ include/linux/trusty/hvcall.h | 130 ++ include/linux/trusty/sm_err.h | 49 + include/linux/trusty/smcall.h | 136 ++ include/linux/trusty/trusty.h | 91 + include/linux/trusty/trusty_ipc.h | 89 + include/linux/trusty/trusty_shm.h | 26 + include/uapi/linux/virtio_ids.h | 1 + 29 files changed, 7254 insertions(+) create mode 100644 drivers/trusty/Kconfig create mode 100644 drivers/trusty/Makefile create mode 100644 drivers/trusty/trusty-fiq-arm.c create mode 100644 drivers/trusty/trusty-fiq-arm64-glue.S create mode 100644 drivers/trusty/trusty-fiq-arm64.c create mode 100644 drivers/trusty/trusty-fiq.c create mode 100644 drivers/trusty/trusty-fiq.h create mode 100644 drivers/trusty/trusty-hee-irqs.c create mode 100644 drivers/trusty/trusty-ipc.c create mode 100644 drivers/trusty/trusty-irq.c create mode 100644 drivers/trusty/trusty-link-shbuf.c create mode 100644 drivers/trusty/trusty-link-shbuf.h create mode 100644 drivers/trusty/trusty-log.c create mode 100644 drivers/trusty/trusty-log.h create mode 100644 drivers/trusty/trusty-mem.c create mode 100644 drivers/trusty/trusty-shm.c create mode 100644 drivers/trusty/trusty-virq.c create mode 100644 drivers/trusty/trusty-virq.h create mode 100644 drivers/trusty/trusty-virtio.c create mode 100644 drivers/trusty/trusty.c create mode 100644 include/linux/trusty/hvcall.h create mode 100644 include/linux/trusty/sm_err.h create mode 100644 include/linux/trusty/smcall.h create mode 100644 include/linux/trusty/trusty.h create mode 100644 include/linux/trusty/trusty_ipc.h create mode 100644 include/linux/trusty/trusty_shm.h diff --git a/drivers/Kconfig b/drivers/Kconfig index cfd0d22ebcca..673f6a1f6ac4 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -227,4 +227,6 @@ source "drivers/esoc/Kconfig" source "drivers/halls/Kconfig" +source "drivers/trusty/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 2f8e36eb37d5..ca8275dd8884 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -189,6 +189,7 @@ obj-$(CONFIG_MULTIPLEXER) += mux/ obj-$(CONFIG_SENSORS_SSC) += sensors/ obj-$(CONFIG_ESOC) += esoc/ obj-$(CONFIG_HALLS) += halls/ +obj-$(CONFIG_TRUSTY) += trusty/ # GNSS driver obj-$(CONFIG_GNSS_SIRF) += gnsssirf/ obj-$(CONFIG_GNSS) += gnss/ diff --git a/drivers/trusty/Kconfig b/drivers/trusty/Kconfig new file mode 100644 index 000000000000..32639a803d9f --- /dev/null +++ b/drivers/trusty/Kconfig @@ -0,0 +1,68 @@ +# +# Trusty +# + +menu "Trusty" + +config TRUSTY + tristate "Trusty" + default n + help + Trusty is a secure Operating System (OS) that provides a + Trusted Execution Environment (TEE) for Android. + Trusty is compatible with ARM and Intel processors. + Say N if unsure. + +config TRUSTY_VIRQ_SIMULATION + tristate "Trusty Virq Simulation" + default n + help + This module adds support for simulations of communications based + on virq with Trusty Services. + + It'll be called trusty-ipc, trusty-virtio. + Say N if unsure. + +config TRUSTY_FIQ + tristate + depends on TRUSTY + default n + +config TRUSTY_FIQ_ARM + tristate + depends on TRUSTY + depends on ARM + select FIQ_GLUE + select TRUSTY_FIQ + default n + +config TRUSTY_FIQ_ARM64 + tristate + depends on TRUSTY + depends on ARM64 + select FIQ_GLUE + select TRUSTY_FIQ + default n + +config TRUSTY_LOG + tristate + depends on TRUSTY + default y + +config TRUSTY_VIRTIO + tristate "Trusty virtio support" + depends on TRUSTY + select VIRTIO + default y + +config TRUSTY_VIRTIO_IPC + tristate "Trusty Virtio IPC driver" + depends on TRUSTY_VIRTIO + default y + help + This module adds support for communications with Trusty Services + + If you choose to build a module, it'll be called trusty-ipc. + Say N if unsure. + +endmenu diff --git a/drivers/trusty/Makefile b/drivers/trusty/Makefile new file mode 100644 index 000000000000..dd903e6fd525 --- /dev/null +++ b/drivers/trusty/Makefile @@ -0,0 +1,17 @@ +# +# Makefile for trusty components +# + +obj-$(CONFIG_TRUSTY) += trusty.o +obj-$(CONFIG_TRUSTY) += trusty-shm.o +obj-$(CONFIG_TRUSTY) += trusty-irq.o +obj-$(CONFIG_TRUSTY_FIQ) += trusty-fiq.o +obj-$(CONFIG_TRUSTY_FIQ_ARM) += trusty-fiq-arm.o +obj-$(CONFIG_TRUSTY_FIQ_ARM64) += trusty-fiq-arm64.o trusty-fiq-arm64-glue.o +obj-$(CONFIG_TRUSTY_LOG) += trusty-log.o +obj-$(CONFIG_TRUSTY) += trusty-mem.o +obj-$(CONFIG_TRUSTY_VIRTIO) += trusty-virtio.o +obj-$(CONFIG_TRUSTY_VIRTIO_IPC) += trusty-ipc.o +# OKL-HYP +obj-$(CONFIG_TRUSTY) += trusty-link-shbuf.o +obj-$(CONFIG_TRUSTY_VIRQ_SIMULATION) += trusty-hee-irqs.o diff --git a/drivers/trusty/trusty-fiq-arm.c b/drivers/trusty/trusty-fiq-arm.c new file mode 100644 index 000000000000..91ed5276e5f4 --- /dev/null +++ b/drivers/trusty/trusty-fiq-arm.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Google, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include + +#include "trusty-fiq.h" + +#define _STRINGIFY(x) #x +#define STRINGIFY(x) _STRINGIFY(x) + +static void __naked trusty_fiq_return(void) +{ + asm volatile(".arch_extension sec\n" + "mov r12, r0\n" + "ldr r0, =" STRINGIFY(SMC_FC_FIQ_EXIT) "\n" + "smc #0"); +} + +int trusty_fiq_arch_probe(struct platform_device *pdev) +{ + return fiq_glue_set_return_handler(trusty_fiq_return); +} + +void trusty_fiq_arch_remove(struct platform_device *pdev) +{ + fiq_glue_clear_return_handler(trusty_fiq_return); +} diff --git a/drivers/trusty/trusty-fiq-arm64-glue.S b/drivers/trusty/trusty-fiq-arm64-glue.S new file mode 100644 index 000000000000..b02fe617a545 --- /dev/null +++ b/drivers/trusty/trusty-fiq-arm64-glue.S @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2013 Google, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include + +.macro push reg1,reg2,remregs:vararg + .ifnb \remregs + push \remregs + .endif + stp \reg1, \reg2, [sp, #-16]! +.endm + +.macro pop reg1,reg2,remregs:vararg + ldp \reg1, \reg2, [sp], #16 + .ifnb \remregs + pop \remregs + .endif +.endm + +ENTRY(trusty_fiq_glue_arm64) + sub sp, sp, #S_FRAME_SIZE - S_LR + push x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, \ + x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, \ + x26, x27, x28, x29 + ldr x0, =SMC_FC64_GET_FIQ_REGS + smc #0 + stp x0, x1, [sp, #S_PC] /* original pc, cpsr */ + tst x1, PSR_MODE_MASK + csel x2, x2, x3, eq /* sp el0, sp el1 */ + stp x30, x2, [sp, #S_LR] /* lr, original sp */ + mov x0, sp + mov x1, x3 + bl trusty_fiq_handler + pop x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, \ + x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, \ + x26, x27, x28, x29 + ldr x30, [sp], #S_FRAME_SIZE - S_LR /* load LR and restore SP */ + ldr x0, =SMC_FC_FIQ_EXIT + smc #0 + b . /* should not get here */ + +ENTRY(trusty_fiq_cpu_resume) + ldr x0, =SMC_FC_FIQ_RESUME + smc #0 + ret diff --git a/drivers/trusty/trusty-fiq-arm64.c b/drivers/trusty/trusty-fiq-arm64.c new file mode 100644 index 000000000000..bdd4c8e5d32d --- /dev/null +++ b/drivers/trusty/trusty-fiq-arm64.c @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2013 Google, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include + +#include + +#include "trusty-fiq.h" + +extern void trusty_fiq_glue_arm64(void); + +static struct device *trusty_dev; +static DEFINE_PER_CPU(void *, fiq_stack); +static struct fiq_glue_handler *fiq_handlers; +static DEFINE_MUTEX(fiq_glue_lock); + +void trusty_fiq_handler(struct pt_regs *regs, void *svc_sp) +{ + struct fiq_glue_handler *handler; + + for (handler = READ_ONCE(fiq_handlers); handler; + handler = READ_ONCE(handler->next)) { + /* Barrier paired with smp_wmb in fiq_glue_register_handler */ + smp_read_barrier_depends(); + handler->fiq(handler, regs, svc_sp); + } +} + +static void smp_nop_call(void *info) +{ + /* If this call is reached, the fiq handler is not currently running */ +} + +static void fiq_glue_clear_handler(void) +{ + int cpu; + int ret; + void *stack; + + for_each_possible_cpu(cpu) { + stack = per_cpu(fiq_stack, cpu); + if (!stack) + continue; + + ret = trusty_fast_call64(trusty_dev, SMC_FC64_SET_FIQ_HANDLER, + cpu, 0, 0); + if (ret) { + pr_err("%s: SMC_FC_SET_FIQ_HANDLER(%d, 0, 0) failed 0x%x, skip free stack\n", + __func__, cpu, ret); + continue; + } + + per_cpu(fiq_stack, cpu) = NULL; + smp_call_function_single(cpu, smp_nop_call, NULL, true); + free_pages((unsigned long)stack, THREAD_SIZE_ORDER); + } +} + +static int fiq_glue_set_handler(void) +{ + int ret; + int cpu; + void *stack; + unsigned long irqflags; + + for_each_possible_cpu(cpu) { + stack = (void *)__get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER); + if (WARN_ON(!stack)) { + ret = -ENOMEM; + goto err_alloc_fiq_stack; + } + per_cpu(fiq_stack, cpu) = stack; + stack += THREAD_START_SP; + + local_irq_save(irqflags); + ret = trusty_fast_call64(trusty_dev, SMC_FC64_SET_FIQ_HANDLER, + cpu, (uintptr_t)trusty_fiq_glue_arm64, + (uintptr_t)stack); + local_irq_restore(irqflags); + if (ret) { + pr_err("%s: SMC_FC_SET_FIQ_HANDLER(%d, %p, %p) failed 0x%x\n", + __func__, cpu, trusty_fiq_glue_arm64, stack, + ret); + ret = -EINVAL; + goto err_set_fiq_handler; + } + } + return 0; + +err_alloc_fiq_stack: +err_set_fiq_handler: + fiq_glue_clear_handler(); + return ret; +} + +int fiq_glue_register_handler(struct fiq_glue_handler *handler) +{ + int ret; + + if (!handler || !handler->fiq) { + ret = -EINVAL; + goto err_bad_arg; + } + + mutex_lock(&fiq_glue_lock); + + if (!trusty_dev) { + ret = -ENODEV; + goto err_no_trusty; + } + + handler->next = fiq_handlers; + /* + * Write barrier paired with smp_read_barrier_depends in + * trusty_fiq_handler. Make sure next pointer is updated before + * fiq_handlers so trusty_fiq_handler does not see an uninitialized + * value and terminate early or crash. + */ + smp_wmb(); + fiq_handlers = handler; + + smp_call_function(smp_nop_call, NULL, true); + + if (!handler->next) { + ret = fiq_glue_set_handler(); + if (ret) + goto err_set_fiq_handler; + } + + mutex_unlock(&fiq_glue_lock); + return 0; + +err_set_fiq_handler: + fiq_handlers = handler->next; +err_no_trusty: + mutex_unlock(&fiq_glue_lock); +err_bad_arg: + pr_err("%s: failed, %d\n", __func__, ret); + return ret; +} + +int trusty_fiq_arch_probe(struct platform_device *pdev) +{ + mutex_lock(&fiq_glue_lock); + trusty_dev = pdev->dev.parent; + mutex_unlock(&fiq_glue_lock); + + return 0; +} + +void trusty_fiq_arch_remove(struct platform_device *pdev) +{ + mutex_lock(&fiq_glue_lock); + fiq_glue_clear_handler(); + trusty_dev = NULL; + mutex_unlock(&fiq_glue_lock); +} diff --git a/drivers/trusty/trusty-fiq.c b/drivers/trusty/trusty-fiq.c new file mode 100644 index 000000000000..bb937bf33ce3 --- /dev/null +++ b/drivers/trusty/trusty-fiq.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2013 Google, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include + +#include "trusty-fiq.h" + +static int trusty_fiq_remove_child(struct device *dev, void *data) +{ + platform_device_unregister(to_platform_device(dev)); + return 0; +} + +static int trusty_fiq_probe(struct platform_device *pdev) +{ + int ret; + + ret = trusty_fiq_arch_probe(pdev); + if (ret) + goto err_set_fiq_return; + + ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to add children: %d\n", ret); + goto err_add_children; + } + + return 0; + +err_add_children: + device_for_each_child(&pdev->dev, NULL, trusty_fiq_remove_child); + trusty_fiq_arch_remove(pdev); +err_set_fiq_return: + return ret; +} + +static int trusty_fiq_remove(struct platform_device *pdev) +{ + device_for_each_child(&pdev->dev, NULL, trusty_fiq_remove_child); + trusty_fiq_arch_remove(pdev); + return 0; +} + +static const struct of_device_id trusty_fiq_of_match[] = { + { + .compatible = "android,trusty-fiq-v1", + }, + {}, +}; + +static struct platform_driver trusty_fiq_driver = { + .probe = trusty_fiq_probe, + .remove = trusty_fiq_remove, + .driver = { + .name = "trusty-fiq", + .owner = THIS_MODULE, + .of_match_table = trusty_fiq_of_match, + }, +}; + +static int __init trusty_fiq_driver_init(void) +{ + return platform_driver_register(&trusty_fiq_driver); +} + +static void __exit trusty_fiq_driver_exit(void) +{ + platform_driver_unregister(&trusty_fiq_driver); +} + +subsys_initcall(trusty_fiq_driver_init); +module_exit(trusty_fiq_driver_exit); diff --git a/drivers/trusty/trusty-fiq.h b/drivers/trusty/trusty-fiq.h new file mode 100644 index 000000000000..ebc17e2351df --- /dev/null +++ b/drivers/trusty/trusty-fiq.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2014 Google, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +int trusty_fiq_arch_probe(struct platform_device *pdev); +void trusty_fiq_arch_remove(struct platform_device *pdev); diff --git a/drivers/trusty/trusty-hee-irqs.c b/drivers/trusty/trusty-hee-irqs.c new file mode 100644 index 000000000000..057c8f7755fe --- /dev/null +++ b/drivers/trusty/trusty-hee-irqs.c @@ -0,0 +1,100 @@ +/* + * Copyright 2018 GoldenRiver Technologies Co., Ltd. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* should not reach here */ +static irqreturn_t irq_handler(int irq, void *data) +{ + WARN_ON(true); + return IRQ_HANDLED; +} + +static int hee_irq_probe(struct platform_device *pdev) +{ + int ret; + u32 irq, cpu; + ulong hwirq; + void __iomem *gicd_base; + struct irq_desc *desc; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "platform_get_irq err %d\n", ret); + return -EINVAL; + } + + desc = irq_to_desc(irq); + if (!desc) { + dev_err(&pdev->dev, "irq_desc(%d) null\n", irq); + return -EINVAL; + } + hwirq = desc->irq_data.hwirq; + + ret = devm_request_irq(&pdev->dev, irq, irq_handler, + IRQF_TRIGGER_RISING, "hee_irq", NULL); + if (ret < 0) { + dev_err(&pdev->dev, "request_irq irq %d err %d\n", irq, ret); + return ret; + } + + gicd_base = ioremap_nocache(0x08000000, 1024 * 1024); + + for_each_possible_cpu(cpu) { + if (cpumask_test_cpu(cpu, cpu_online_mask)) + continue; + + /* Aff1/2/3 is 0 in Virt. :-) */ + gic_write_irouter(cpu, gicd_base + GICD_IROUTER + hwirq * 8); + break; + } + + iounmap(gicd_base); + + dev_dbg(&pdev->dev, "irq %d hwirq %lu configured.\n", irq, + desc->irq_data.hwirq); + + return 0; +} + +static const struct of_device_id hee_irq_of_match[] = { + { + .compatible = "nbl,hee-irq", + }, + {}, +}; + +static struct platform_driver hee_irq_driver = { + .probe = hee_irq_probe, + .driver = { + .name = "trusty-hee-irq", + .owner = THIS_MODULE, + .of_match_table = hee_irq_of_match, + }, +}; + +static int __init hee_irq_driver_init(void) +{ + return platform_driver_register(&hee_irq_driver); +} + +arch_initcall(hee_irq_driver_init); diff --git a/drivers/trusty/trusty-ipc.c b/drivers/trusty/trusty-ipc.c new file mode 100644 index 000000000000..32fd1b051366 --- /dev/null +++ b/drivers/trusty/trusty-ipc.c @@ -0,0 +1,2438 @@ +/* + * Copyright 2018 GoldenRiver Technologies Co., Ltd. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * Copyright (C) 2015 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 10, 0) +#include +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) +#include +#endif +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "trusty-link-shbuf.h" + +#define MAX_DEVICES 4 + +#define REPLY_TIMEOUT 5000 +#define TXBUF_TIMEOUT 15000 + +#define MAX_SRV_NAME_LEN 256 +#define MAX_DEV_NAME_LEN 32 + +#define DEFAULT_MSG_BUF_SIZE PAGE_SIZE +#define DEFAULT_MSG_BUF_ALIGN PAGE_SIZE + +#define TIPC_CTRL_ADDR 53 +#define TIPC_ANY_ADDR 0xFFFFFFFF + +#define TIPC_MIN_LOCAL_ADDR 1024 +#define TIPC_MAX_LOCAL_ADDR 0x7FFFFFFF + +#define MAX_MEMREF_NUM 8 +#define MEMREF_ALIGN 8 +#define TIPC_MIN_MEMREF_ID 2048 +#define TIPC_MAX_MEMREF_ID 10000 +#define MAX_MREF_SIZE (2 * 1024 * 1024) + +#define TIPC_IOC_MAGIC 'r' +#define TIPC_IOC_CONNECT _IOW(TIPC_IOC_MAGIC, 0x80, char *) + +#define TIPC_MEMREF_PERM_RO (0x0U << 0) +#define TIPC_MEMREF_PERM_RW (0x1U << 0) + +struct tipc_shmem { + __u32 flags; + __u32 size[3]; + __u64 base[3]; +}; + +struct tipc_send_msg_req { + __u64 msgiov; + __u64 shmemv; + __u32 msgiov_cnt; + __u32 shmemv_cnt; +}; + +#define TIPC_IOC_SEND_MSG _IOW(TIPC_IOC_MAGIC, 0x81, struct tipc_send_msg_req) + +#if defined(CONFIG_COMPAT) +#define TIPC_IOC_CONNECT_COMPAT _IOW(TIPC_IOC_MAGIC, 0x80, compat_uptr_t) + +#endif + +struct tipc_virtio_dev; + +struct tipc_dev_config { + u32 msg_buf_max_size; + u32 msg_buf_alignment; + char dev_name[MAX_DEV_NAME_LEN]; +} __packed; + +struct tipc_msg_hdr { + u32 src; + u32 dst; + u32 reserved; + u16 len; + u16 flags; + u8 data[0]; +} __packed; + +struct tipc_msg_mref_hdr { + u32 id; + u32 flags; + u32 size; + u32 pg_inf_cnt; + struct ns_mem_page_info pg_inf[]; +} __packed; + +enum tipc_ctrl_msg_types { + TIPC_CTRL_MSGTYPE_GO_ONLINE = 1, + TIPC_CTRL_MSGTYPE_GO_OFFLINE, + TIPC_CTRL_MSGTYPE_CONN_REQ, + TIPC_CTRL_MSGTYPE_CONN_RSP, + TIPC_CTRL_MSGTYPE_DISC_REQ, + TIPC_CTRL_MSGTYPE_MREF_RELEASE_REQ, +}; + +struct tipc_ctrl_msg { + u32 type; + u32 body_len; + u8 body[0]; +} __packed; + +struct tipc_conn_req_body { + char name[MAX_SRV_NAME_LEN]; +} __packed; + +struct tipc_conn_rsp_body { + u32 target; + u32 status; + u32 remote; + u32 max_msg_size; + u32 max_msg_cnt; +} __packed; + +struct tipc_disc_req_body { + u32 target; +} __packed; + +struct tipc_mref_release_req_body { + u32 id; +} __packed; + +struct tipc_cdev_node { + struct cdev cdev; + struct device *dev; + unsigned int minor; +}; + +enum tipc_device_state { + VDS_OFFLINE = 0, + VDS_ONLINE, + VDS_DEAD, +}; + +struct tipc_virtio_dev { + struct kref refcount; + struct mutex lock; /* protects access to this device */ + struct virtio_device *vdev; + struct virtqueue *rxvq; + struct virtqueue *txvq; + uint msg_buf_cnt; + uint msg_buf_max_cnt; + size_t msg_buf_sz; + uint free_msg_buf_cnt; + struct list_head free_buf_list; + struct list_head stashed_buf_list; + wait_queue_head_t sendq; + struct idr addr_idr; + struct idr mref_idr; + struct mutex mref_lock; /* protects access to mref_idr */ + enum tipc_device_state state; + struct tipc_cdev_node cdev_node; + char cdev_name[MAX_DEV_NAME_LEN]; +}; + +enum tipc_chan_state { + TIPC_DISCONNECTED = 0, + TIPC_CONNECTING, + TIPC_CONNECTED, + TIPC_STALE, +}; + +struct tipc_chan { + struct mutex lock; /* protects channel state */ + struct kref refcount; + enum tipc_chan_state state; + struct tipc_virtio_dev *vds; + const struct tipc_chan_ops *ops; + void *ops_arg; + struct list_head mref_list; + wait_queue_head_t mrefq; + u32 remote; + u32 local; + u32 max_msg_size; + u32 max_msg_cnt; + char srv_name[MAX_SRV_NAME_LEN]; +}; + +struct tipc_memref { + struct tipc_chan *chan; + struct list_head node; + unsigned int pg_num; + unsigned int pg_pinned; + struct page *pages[]; +}; + +static struct class *tipc_class; +static unsigned int tipc_major; + +struct virtio_device *default_vdev; + +static DEFINE_IDR(tipc_devices); +static DEFINE_MUTEX(tipc_devices_lock); + +static int _tipc_send_msg(struct tipc_chan *chan, struct iov_iter *msg_iter, + struct tipc_shmem *shmv, uint shmv_cnt, bool user, + long timeout, bool intr); + +static int _match_any(int id, void *p, void *data) +{ + return id; +} + +static int _match_data(int id, void *p, void *data) +{ + return (p == data); +} + +static void *_alloc_shareable_mem(size_t sz, phys_addr_t *ppa, gfp_t gfp) +{ + return trusty_shm_alloc(sz, gfp); +} + +static void _free_shareable_mem(size_t sz, void *va, phys_addr_t pa) +{ + trusty_shm_free(va, sz); +} + +static struct tipc_msg_buf *_alloc_msg_buf(size_t sz) +{ + struct tipc_msg_buf *mb; + + /* allocate tracking structure */ + mb = kzalloc(sizeof(struct tipc_msg_buf), GFP_KERNEL); + if (!mb) + return NULL; + + /* allocate buffer that can be shared with secure world */ + mb->buf_va = _alloc_shareable_mem(sz, &mb->buf_pa, GFP_KERNEL); + if (!mb->buf_va) + goto err_alloc; + + mb->buf_sz = sz; + + return mb; + +err_alloc: + kfree(mb); + return NULL; +} + +static void _free_msg_buf(struct tipc_msg_buf *mb) +{ + _free_shareable_mem(mb->buf_sz, mb->buf_va, mb->buf_pa); + kfree(mb); +} + +static void _free_msg_buf_list(struct list_head *list) +{ + struct tipc_msg_buf *mb = NULL; + + mb = list_first_entry_or_null(list, struct tipc_msg_buf, node); + while (mb) { + list_del(&mb->node); + _free_msg_buf(mb); + mb = list_first_entry_or_null(list, struct tipc_msg_buf, node); + } +} + +static inline void mb_reset(struct tipc_msg_buf *mb) +{ + mb->wpos = 0; + mb->rpos = 0; +} + +static inline void mb_reset_read(struct tipc_msg_buf *mb) +{ + mb->rpos = 0; +} + +static inline void mb_align_read(struct tipc_msg_buf *mb, uint align) +{ + (void)mb_get_data(mb, ALIGN(mb->rpos, align) - mb->rpos); +} + +static inline void mb_align_write(struct tipc_msg_buf *mb, uint align) +{ + size_t cb = ALIGN(mb->wpos, align) - mb->wpos; + + memset(mb_put_data(mb, cb), 0, cb); +} + +static void _free_vds(struct kref *kref) +{ + struct tipc_virtio_dev *vds = + container_of(kref, struct tipc_virtio_dev, refcount); + kfree(vds); +} + +static void _free_chan(struct kref *kref) +{ + struct tipc_chan *ch = container_of(kref, struct tipc_chan, refcount); + + if (ch->ops && ch->ops->handle_release) + ch->ops->handle_release(ch->ops_arg); + + kref_put(&ch->vds->refcount, _free_vds); + kfree(ch); +} + +static struct tipc_msg_buf *vds_alloc_msg_buf(struct tipc_virtio_dev *vds) +{ + return _alloc_msg_buf(vds->msg_buf_sz); +} + +static void vds_free_msg_buf(struct tipc_virtio_dev *vds, + struct tipc_msg_buf *mb) +{ + _free_msg_buf(mb); +} + +static bool _put_txbuf_locked(struct tipc_virtio_dev *vds, + struct tipc_msg_buf *mb) +{ + if (mb->buf_sz > vds->msg_buf_sz) { + _free_msg_buf(mb); + + if (list_empty(&vds->stashed_buf_list)) { + vds->msg_buf_cnt--; + return true; + } + + /* take buf out of stashed list and put it on free list */ + mb = list_first_entry(&vds->stashed_buf_list, + struct tipc_msg_buf, node); + list_del(&mb->node); + } + list_add_tail(&mb->node, &vds->free_buf_list); + return vds->free_msg_buf_cnt++ == 0; +} + +static struct tipc_msg_buf *_get_txbuf_locked(struct tipc_virtio_dev *vds, + size_t sz) +{ + struct tipc_msg_buf *mb; + + if (vds->state != VDS_ONLINE) + return ERR_PTR(-ENODEV); + + if (sz < vds->msg_buf_sz) + sz = vds->msg_buf_sz; + + if (vds->free_msg_buf_cnt) { + /* peek head of free list */ + mb = list_first_entry(&vds->free_buf_list, struct tipc_msg_buf, + node); + + if (sz > vds->msg_buf_sz) { + struct tipc_msg_buf *newmb; + + /* allocate new one */ + newmb = _alloc_msg_buf(sz); + if (!newmb) + return ERR_PTR(-ENOMEM); + + /* remove from free list and put it on shashed list */ + list_del(&mb->node); + list_add_tail(&mb->node, &vds->stashed_buf_list); + + /* return a new one to caller */ + mb = newmb; + } else { + /* take it out of free list */ + list_del(&mb->node); + } + vds->free_msg_buf_cnt--; + } else { + if (vds->msg_buf_cnt >= vds->msg_buf_max_cnt) + return ERR_PTR(-EAGAIN); + + /* try to allocate it */ + mb = _alloc_msg_buf(sz); + if (!mb) + return ERR_PTR(-ENOMEM); + + vds->msg_buf_cnt++; + } + return mb; +} + +static struct tipc_msg_buf *_vds_get_txbuf(struct tipc_virtio_dev *vds, + size_t sz) +{ + struct tipc_msg_buf *mb; + + mutex_lock(&vds->lock); + mb = _get_txbuf_locked(vds, sz); + mutex_unlock(&vds->lock); + + return mb; +} + +static void vds_put_txbuf_locked(struct tipc_virtio_dev *vds, + struct tipc_msg_buf *mb) +{ + if (_put_txbuf_locked(vds, mb)) + wake_up(&vds->sendq); +} + +static void vds_put_txbuf(struct tipc_virtio_dev *vds, struct tipc_msg_buf *mb) +{ + mutex_lock(&vds->lock); + vds_put_txbuf_locked(vds, mb); + mutex_unlock(&vds->lock); +} + +static struct tipc_msg_buf *vds_get_txbuf(struct tipc_virtio_dev *vds, + size_t sz, long timeout, bool intr) +{ + struct tipc_msg_buf *mb; + unsigned int mode = intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; + + mb = _vds_get_txbuf(vds, sz); + + if ((PTR_ERR(mb) == -EAGAIN) && timeout) { + DEFINE_WAIT_FUNC(wait, woken_wake_function); + + timeout = msecs_to_jiffies(timeout); + add_wait_queue(&vds->sendq, &wait); + for (;;) { + timeout = wait_woken(&wait, mode, timeout); + if (!timeout) { + mb = ERR_PTR(-ETIMEDOUT); + break; + } + + if (intr) { + if (signal_pending(current)) { + mb = ERR_PTR(-ERESTARTSYS); + break; + } + } + + mb = _vds_get_txbuf(vds, sz); + if (PTR_ERR(mb) != -EAGAIN) + break; + } + remove_wait_queue(&vds->sendq, &wait); + } + + if (IS_ERR(mb)) + return mb; + + BUG_ON(!mb); + + /* reset and reserve space for message header */ + mb_reset(mb); + mb_put_data(mb, sizeof(struct tipc_msg_hdr)); + + return mb; +} + +static int vds_queue_txbuf(struct tipc_virtio_dev *vds, struct tipc_msg_buf *mb) +{ + int err; + struct scatterlist sg; + bool need_notify = false; + + mutex_lock(&vds->lock); + if (vds->state == VDS_ONLINE) { + sg_init_one(&sg, mb->buf_va, mb->wpos); + err = virtqueue_add_outbuf(vds->txvq, &sg, 1, mb, GFP_KERNEL); + need_notify = virtqueue_kick_prepare(vds->txvq); + } else { + err = -ENODEV; + } + mutex_unlock(&vds->lock); + + if (need_notify) + virtqueue_notify(vds->txvq); + + return err; +} + +static int vds_add_channel(struct tipc_virtio_dev *vds, struct tipc_chan *chan) +{ + int ret; + + mutex_lock(&vds->lock); + if (vds->state == VDS_ONLINE) { + ret = idr_alloc_cyclic(&vds->addr_idr, chan, + TIPC_MIN_LOCAL_ADDR, TIPC_MAX_LOCAL_ADDR, + GFP_KERNEL); + if (ret > 0) { + chan->local = ret; + kref_get(&chan->refcount); + ret = 0; + } + } else { + ret = -EINVAL; + } + mutex_unlock(&vds->lock); + + return ret; +} + +static void vds_del_channel(struct tipc_virtio_dev *vds, struct tipc_chan *chan) +{ + mutex_lock(&vds->lock); + if (chan->local) { + idr_remove(&vds->addr_idr, chan->local); + chan->local = 0; + chan->remote = 0; + kref_put(&chan->refcount, _free_chan); + } + mutex_unlock(&vds->lock); +} + +static struct tipc_chan *vds_lookup_channel(struct tipc_virtio_dev *vds, + u32 addr) +{ + int id; + struct tipc_chan *chan = NULL; + + mutex_lock(&vds->lock); + if (addr == TIPC_ANY_ADDR) { + id = idr_for_each(&vds->addr_idr, _match_any, NULL); + if (id > 0) + chan = idr_find(&vds->addr_idr, id); + } else { + chan = idr_find(&vds->addr_idr, addr); + } + if (chan) + kref_get(&chan->refcount); + mutex_unlock(&vds->lock); + + return chan; +} + +static struct tipc_chan *vds_create_channel(struct tipc_virtio_dev *vds, + const struct tipc_chan_ops *ops, + void *ops_arg) +{ + int ret; + struct tipc_chan *chan = NULL; + + if (!vds) + return ERR_PTR(-ENOENT); + + if (!ops) + return ERR_PTR(-EINVAL); + + chan = kzalloc(sizeof(*chan), GFP_KERNEL); + if (!chan) + return ERR_PTR(-ENOMEM); + + kref_get(&vds->refcount); + chan->vds = vds; + chan->ops = ops; + chan->ops_arg = ops_arg; + mutex_init(&chan->lock); + kref_init(&chan->refcount); + chan->state = TIPC_DISCONNECTED; + INIT_LIST_HEAD(&chan->mref_list); + init_waitqueue_head(&chan->mrefq); + + ret = vds_add_channel(vds, chan); + if (ret) { + kfree(chan); + kref_put(&vds->refcount, _free_vds); + return ERR_PTR(ret); + } + + return chan; +} + +static void fill_msg_hdr(struct tipc_msg_buf *mb, u32 src, u32 dst) +{ + struct tipc_msg_hdr *hdr = mb_get_data(mb, sizeof(*hdr)); + + hdr->src = src; + hdr->dst = dst; + hdr->len = mb_avail_data(mb); + hdr->flags = 0; + hdr->reserved = 0; +} + +/*****************************************************************************/ + +static int memref_preflight_check(struct tipc_shmem *shm) +{ + unsigned int i; + + if (!shm) + return -EINVAL; + + for (i = 0; i < 3; i++) { + /* size has to be page aligned */ + if (shm->size[i] & (PAGE_SIZE - 1)) + return -EINVAL; + + /* base address also has not be page aligned */ + if ((uintptr_t)shm->base[i] & (PAGE_SIZE - 1)) + return -EINVAL; + } + return 0; +} + +static int memrefv_preflight_check(struct tipc_shmem *shmv, uint shmv_cnt) +{ + int ret; + unsigned int i; + + if (shmv_cnt > MAX_MEMREF_NUM) + return -EINVAL; + + for (i = 0; i < shmv_cnt; i++) { + ret = memref_preflight_check(&shmv[i]); + if (ret < 0) + return ret; + } + return 0; +} + +static unsigned int memref_count_pages(struct tipc_shmem *shm) +{ + unsigned int i; + unsigned int pg_cnt = 0; + + for (i = 0; i < 3; i++) + pg_cnt += shm->size[i] / PAGE_SIZE; + return pg_cnt; +} + +static void memref_release_pages(struct tipc_memref *mref, bool dirty) +{ + unsigned int i; + + /* if pages are pinned, unpin them */ + for (i = 0; i < mref->pg_pinned; i++) { + if (dirty) + set_page_dirty(mref->pages[i]); + put_page(mref->pages[i]); + } + mref->pg_pinned = 0; +} + +static void vds_memref_release_locked(struct tipc_virtio_dev *vds, u32 id) +{ + struct tipc_memref *mref = idr_find(&vds->mref_idr, id); + + if (WARN_ON(!mref)) { + pr_err("%s: memref (id=%u) is not found\n", __func__, id); + return; + } + + pr_debug("%s: id=%u %u\n", __func__, id, mref->pg_pinned); + + /* remove id */ + idr_remove(&mref->chan->vds->mref_idr, id); + + /* dec refs */ + list_del(&mref->node); + if (list_empty(&mref->chan->mref_list)) + wake_up_all(&mref->chan->mrefq); + + kref_put(&mref->chan->refcount, _free_chan); + mref->chan = NULL; + + memref_release_pages(mref, true); + kfree(mref); +} + +static void vds_memref_release(struct tipc_virtio_dev *vds, const u32 *ids, + uint ids_num) +{ + uint i; + mutex_lock(&vds->mref_lock); + for (i = 0; i < ids_num; i++) + vds_memref_release_locked(vds, ids[i]); + mutex_unlock(&vds->mref_lock); +} + +static int build_user_page_info(struct ns_mem_page_info *ns, + struct vm_area_struct *vmas[], + struct page *pages[], unsigned long pg_num) +{ + int ret; + unsigned long i; + + for (i = 0; i < pg_num; i++, ns++) { + struct vm_area_struct *vma = vmas[i]; + + ret = trusty_encode_page_info(ns, pages[i], vma->vm_page_prot, + !!(vma->vm_flags & VM_WRITE)); + if (ret < 0) + return ret; + } + return 0; +} + +static int build_kern_page_info(struct ns_mem_page_info *ns, + struct vm_area_struct *vma, + struct page *pages[], unsigned long pg_num) +{ + int ret; + unsigned long i; + + for (i = 0; i < pg_num; i++, ns++) { + ret = trusty_encode_page_info(ns, pages[i], vma->vm_page_prot, + !!(vma->vm_flags & VM_WRITE)); + if (ret < 0) + return ret; + } + return 0; +} + +static int append_kernel_memref(struct tipc_msg_mref_hdr *hdr, + struct tipc_memref *mref, + struct tipc_shmem *shm) +{ + long ret; + unsigned int i; + unsigned int pg_num; + unsigned long pg_start; + unsigned long pfn; + struct vm_area_struct *vma; + + /* sanity check */ + if (WARN_ON(shm->size[0] || shm->base[0]) || + WARN_ON(shm->size[2] || shm->base[2])) + return -EINVAL; + + /* in shm case, we're interested in region 1 */ + pg_num = shm->size[1] / PAGE_SIZE; + pg_start = (unsigned long)shm->base[1]; + + if (WARN_ON(!pg_num || !pg_start)) + return -EINVAL; + + down_read(¤t->mm->mmap_sem); + + vma = find_extend_vma(current->mm, pg_start); + + if (WARN_ON(!vma)) { + ret = -EINVAL; + goto err_out; + } + + /* TODO: check pg_num * PAGE_SIZE is within vm_area */ + /* TODO: follow pte for all pages, not only the first one. */ + /* obtain physical frame number */ + follow_pfn(vma, pg_start, &pfn); + if (WARN_ON(!pfn)) { + ret = -EINVAL; + goto err_out; + } + + /* fill pages of memref */ + for (i = 0; i < pg_num; i++, pfn++) { + mref->pages[i] = pfn_to_page(pfn); + if (WARN_ON(!mref->pages[i])) { + ret = -EINVAL; + goto err_out; + } + } + + hdr->id = 0; /* will be filled later */ + hdr->flags = shm->flags & TIPC_MEMREF_PERM_RW; + hdr->size = shm->size[1]; + hdr->pg_inf_cnt = shm->size[1] / PAGE_SIZE; + ret = build_kern_page_info(hdr->pg_inf, vma, mref->pages, pg_num); + +err_out: + up_read(¤t->mm->mmap_sem); + return ret; +} + +static int append_user_memref(struct tipc_msg_mref_hdr *hdr, + struct tipc_memref *mref, struct tipc_shmem *shm) +{ + long ret; + unsigned int gup_flags; + unsigned int i; + unsigned int pg_num; + unsigned long pg_start; + struct vm_area_struct **vmas; + + vmas = kcalloc(mref->pg_num, sizeof(*vmas), GFP_KERNEL); + if (!vmas) + return -ENOMEM; + + gup_flags = (shm->flags & TIPC_MEMREF_PERM_RW) ? FOLL_WRITE : 0; + + down_read(¤t->mm->mmap_sem); + + /* for all 3 regions */ + for (i = 0; i < 3; i++) { + pg_num = shm->size[i] / PAGE_SIZE; + pg_start = (unsigned long)shm->base[i]; + + if (!pg_start || !pg_num) + continue; + + ret = get_user_pages(pg_start, pg_num, gup_flags, + mref->pages + mref->pg_pinned, + vmas + mref->pg_pinned); + if (ret < 0) + goto err_pinned; + + mref->pg_pinned += (unsigned int)ret; + + if ((unsigned int)ret != pg_num) { + /* partially succeeded */ + ret = -EINVAL; + goto err_bad_cnt; + } + } + + hdr->id = 0; /* will be filled later */ + hdr->flags = shm->flags & TIPC_MEMREF_PERM_RW; + hdr->size = mref->pg_pinned * PAGE_SIZE; + hdr->pg_inf_cnt = mref->pg_pinned; + ret = build_user_page_info(hdr->pg_inf, vmas, mref->pages, + mref->pg_pinned); + +err_bad_cnt: +err_pinned: + if (ret < 0) + memref_release_pages(mref, false); + up_read(¤t->mm->mmap_sem); + kfree(vmas); + return ret; +} + +static int append_memrefs(struct tipc_chan *chan, struct tipc_msg_buf *mb, + u32 *mr_ids, struct tipc_shmem *shmv, uint shmv_cnt, + bool user) +{ + uint i; + int ret; + size_t sz; + unsigned int pg_num; + struct tipc_memref *mref; + struct tipc_msg_mref_hdr *hdr; + struct tipc_virtio_dev *vds = chan->vds; + + /* align output buffer */ + mb_align_write(mb, MEMREF_ALIGN); + + /* for each memrefs */ + mutex_lock(&chan->vds->mref_lock); + for (i = 0; i < shmv_cnt; i++) { + /* create memref tracking obj */ + pg_num = memref_count_pages(&shmv[i]); + if (!pg_num) { + ret = -EINVAL; + goto err_create; + } + + mref = kzalloc(sizeof(*mref) + pg_num * sizeof(struct page *), + GFP_KERNEL); + if (!mref) { + ret = -ENOMEM; + goto err_create; + } + mref->pg_num = pg_num; + + /* reserve space for memref object */ + sz = sizeof(struct tipc_msg_mref_hdr) + + sizeof(struct ns_mem_page_info) * pg_num; + hdr = mb_put_data(mb, sz); + + if (user) + ret = append_user_memref(hdr, mref, &shmv[i]); + else + ret = append_kernel_memref(hdr, mref, &shmv[i]); + if (ret) + goto err_append; + + /* create memref id */ + ret = idr_alloc(&vds->mref_idr, mref, TIPC_MIN_MEMREF_ID, + TIPC_MAX_MEMREF_ID, GFP_KERNEL); + + if (ret < 0) + goto err_idr_alloc; + + hdr->id = ret; + mr_ids[i] = ret; + + /* attach memref to chan object */ + kref_get(&chan->refcount); + mref->chan = chan; + list_add_tail(&mref->node, &chan->mref_list); + } + mutex_unlock(&chan->vds->mref_lock); + + return 0; + +err_idr_alloc: +err_append: + memref_release_pages(mref, false); + kfree(mref); +err_create: + while (i--) + vds_memref_release_locked(vds, mr_ids[i]); + mutex_unlock(&chan->vds->mref_lock); + return ret; +} + +/*****************************************************************************/ + +struct tipc_chan *tipc_create_channel(struct device *dev, + const struct tipc_chan_ops *ops, + void *ops_arg) +{ + struct virtio_device *vd; + struct tipc_chan *chan; + struct tipc_virtio_dev *vds; + + mutex_lock(&tipc_devices_lock); + if (dev) { + vd = container_of(dev, struct virtio_device, dev); + } else { + vd = default_vdev; + if (!vd) { + mutex_unlock(&tipc_devices_lock); + return ERR_PTR(-ENOENT); + } + } + vds = vd->priv; + kref_get(&vds->refcount); + mutex_unlock(&tipc_devices_lock); + + chan = vds_create_channel(vds, ops, ops_arg); + kref_put(&vds->refcount, _free_vds); + return chan; +} +EXPORT_SYMBOL(tipc_create_channel); + +struct tipc_msg_buf *tipc_chan_get_rxbuf(struct tipc_chan *chan) +{ + return vds_alloc_msg_buf(chan->vds); +} +EXPORT_SYMBOL(tipc_chan_get_rxbuf); + +void tipc_chan_put_rxbuf(struct tipc_chan *chan, struct tipc_msg_buf *mb) +{ + vds_free_msg_buf(chan->vds, mb); +} +EXPORT_SYMBOL(tipc_chan_put_rxbuf); + +struct tipc_msg_buf *tipc_chan_get_txbuf_timeout(struct tipc_chan *chan, + long timeout) +{ + struct tipc_virtio_dev *vds = chan->vds; + + return vds_get_txbuf(vds, vds->msg_buf_sz, timeout, true); +} +EXPORT_SYMBOL(tipc_chan_get_txbuf_timeout); + +void tipc_chan_put_txbuf(struct tipc_chan *chan, struct tipc_msg_buf *mb) +{ + vds_put_txbuf(chan->vds, mb); +} +EXPORT_SYMBOL(tipc_chan_put_txbuf); + +static int _tipc_chan_queue_msg(struct tipc_chan *chan, struct tipc_msg_buf *mb, + struct tipc_shmem *shmv, uint shmv_cnt, + bool user) +{ + int err; + u32 mr_ids[MAX_MEMREF_NUM]; + + mutex_lock(&chan->lock); + switch (chan->state) { + case TIPC_CONNECTED: + fill_msg_hdr(mb, chan->local, chan->remote); + + /* append memrefs if any */ + if (shmv_cnt) { + err = append_memrefs(chan, mb, mr_ids, shmv, shmv_cnt, + user); + if (err < 0) { + pr_err("%s: failed to append memrefs (%d)\n", + __func__, err); + break; + } + } + + /* queue message */ + err = vds_queue_txbuf(chan->vds, mb); + if (err) { + /* this should never happen */ + pr_err("%s: failed to queue tx buffer (%d)\n", __func__, + err); + vds_memref_release(chan->vds, mr_ids, shmv_cnt); + } + break; + case TIPC_DISCONNECTED: + case TIPC_CONNECTING: + err = -ENOTCONN; + break; + case TIPC_STALE: + err = -ESHUTDOWN; + break; + default: + err = -EBADFD; + pr_err("%s: unexpected channel state %d\n", __func__, + chan->state); + } + mutex_unlock(&chan->lock); + return err; +} + +int tipc_chan_queue_msg(struct tipc_chan *chan, struct tipc_msg_buf *mb) +{ + return _tipc_chan_queue_msg(chan, mb, NULL, 0, false); +} +EXPORT_SYMBOL(tipc_chan_queue_msg); + +int tipc_chan_connect(struct tipc_chan *chan, const char *name) +{ + int err; + struct tipc_ctrl_msg *msg; + struct tipc_conn_req_body *body; + struct tipc_msg_buf *txbuf; + + txbuf = tipc_chan_get_txbuf_timeout(chan, TXBUF_TIMEOUT); + if (IS_ERR(txbuf)) + return PTR_ERR(txbuf); + + /* reserve space for connection request control message */ + msg = mb_put_data(txbuf, sizeof(*msg) + sizeof(*body)); + body = (struct tipc_conn_req_body *)msg->body; + + /* fill message */ + msg->type = TIPC_CTRL_MSGTYPE_CONN_REQ; + msg->body_len = sizeof(*body); + + strlcpy(body->name, name, sizeof(body->name)); + body->name[sizeof(body->name) - 1] = '\0'; + + mutex_lock(&chan->lock); + switch (chan->state) { + case TIPC_DISCONNECTED: + /* save service name we are connecting to */ + strlcpy(chan->srv_name, body->name, sizeof(chan->srv_name)); + + fill_msg_hdr(txbuf, chan->local, TIPC_CTRL_ADDR); + err = vds_queue_txbuf(chan->vds, txbuf); + if (err) { + /* this should never happen */ + pr_err("%s: failed to queue tx buffer (%d)\n", __func__, + err); + } else { + chan->state = TIPC_CONNECTING; + txbuf = NULL; /* prevents discarding buffer */ + } + break; + case TIPC_CONNECTED: + case TIPC_CONNECTING: + /* check if we are trying to connect to the same service */ + if (strcmp(chan->srv_name, body->name) == 0) + err = 0; + else if (chan->state == TIPC_CONNECTING) + err = -EALREADY; /* in progress */ + else + err = -EISCONN; /* already connected */ + break; + + case TIPC_STALE: + err = -ESHUTDOWN; + break; + default: + err = -EBADFD; + pr_err("%s: unexpected channel state %d\n", __func__, + chan->state); + break; + } + mutex_unlock(&chan->lock); + + if (txbuf) + tipc_chan_put_txbuf(chan, txbuf); /* discard it */ + + return err; +} +EXPORT_SYMBOL(tipc_chan_connect); + +static void wait_for_memrefs(struct tipc_chan *chan) +{ + DEFINE_WAIT_FUNC(wait, woken_wake_function); + + if (list_empty(&chan->mref_list)) + return; + + add_wait_queue(&chan->mrefq, &wait); + do { + wait_woken(&wait, TASK_UNINTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); + } while (!list_empty(&chan->mref_list)); + remove_wait_queue(&chan->mrefq, &wait); +} + +int tipc_chan_shutdown(struct tipc_chan *chan) +{ + int err; + struct tipc_ctrl_msg *msg; + struct tipc_disc_req_body *body; + struct tipc_msg_buf *txbuf = NULL; + + /* get tx buffer */ + txbuf = vds_get_txbuf(chan->vds, chan->vds->msg_buf_sz, TXBUF_TIMEOUT, + false); + if (IS_ERR(txbuf)) + return PTR_ERR(txbuf); + + mutex_lock(&chan->lock); + if (chan->state == TIPC_CONNECTED || chan->state == TIPC_CONNECTING) { + /* reserve space for disconnect request control message */ + msg = mb_put_data(txbuf, sizeof(*msg) + sizeof(*body)); + body = (struct tipc_disc_req_body *)msg->body; + + msg->type = TIPC_CTRL_MSGTYPE_DISC_REQ; + msg->body_len = sizeof(*body); + body->target = chan->remote; + + fill_msg_hdr(txbuf, chan->local, TIPC_CTRL_ADDR); + err = vds_queue_txbuf(chan->vds, txbuf); + if (err) { + /* this should never happen */ + pr_err("%s: failed to queue tx buffer (%d)\n", __func__, + err); + } + } else { + err = -ENOTCONN; + } + chan->state = TIPC_STALE; + mutex_unlock(&chan->lock); + + /* wait for all outstanding memref to be released by remote side */ + wait_for_memrefs(chan); + + if (err) { + /* release buffer */ + tipc_chan_put_txbuf(chan, txbuf); + } + + return err; +} +EXPORT_SYMBOL(tipc_chan_shutdown); + +void tipc_chan_destroy(struct tipc_chan *chan) +{ + vds_del_channel(chan->vds, chan); + kref_put(&chan->refcount, _free_chan); +} +EXPORT_SYMBOL(tipc_chan_destroy); + +/***************************************************************************/ +struct mref_shm { + unsigned long vm_start; + uintptr_t vaddr; + phys_addr_t paddr; + size_t size; + struct list_head node; +}; + +struct tipc_dn_chan { + int state; + struct mutex lock; /* protects rx_msg_queue list and channel state */ + struct tipc_chan *chan; + wait_queue_head_t readq; + struct completion reply_comp; + struct list_head rx_msg_queue; + struct list_head mref_shm_list; /* used in static shm allocation */ +}; + +static int dn_wait_for_reply(struct tipc_dn_chan *dn, int timeout) +{ + int ret; + + ret = wait_for_completion_interruptible_timeout( + &dn->reply_comp, msecs_to_jiffies(timeout)); + if (ret < 0) + return ret; + + mutex_lock(&dn->lock); + if (!ret) { + /* no reply from remote */ + dn->state = TIPC_STALE; + ret = -ETIMEDOUT; + } else { + /* got reply */ + if (dn->state == TIPC_CONNECTED) + ret = 0; + else if (dn->state == TIPC_DISCONNECTED) + if (!list_empty(&dn->rx_msg_queue)) + ret = 0; + else + ret = -ENOTCONN; + else + ret = -EIO; + } + mutex_unlock(&dn->lock); + + return ret; +} + +struct tipc_msg_buf *dn_handle_msg(void *data, struct tipc_msg_buf *rxbuf) +{ + struct tipc_dn_chan *dn = data; + struct tipc_msg_buf *newbuf = rxbuf; + + mutex_lock(&dn->lock); + if (dn->state == TIPC_CONNECTED) { + /* get new buffer */ + newbuf = tipc_chan_get_rxbuf(dn->chan); + if (newbuf) { + /* queue an old buffer and return a new one */ + list_add_tail(&rxbuf->node, &dn->rx_msg_queue); + wake_up_interruptible(&dn->readq); + } else { + /* + * return an old buffer effectively discarding + * incoming message + */ + pr_err("%s: discard incoming message\n", __func__); + newbuf = rxbuf; + } + } + mutex_unlock(&dn->lock); + + return newbuf; +} + +static void dn_connected(struct tipc_dn_chan *dn) +{ + mutex_lock(&dn->lock); + dn->state = TIPC_CONNECTED; + + /* complete all pending */ + complete(&dn->reply_comp); + + mutex_unlock(&dn->lock); +} + +static void dn_disconnected(struct tipc_dn_chan *dn) +{ + mutex_lock(&dn->lock); + dn->state = TIPC_DISCONNECTED; + + /* complete all pending */ + complete(&dn->reply_comp); + + /* wakeup all readers */ + wake_up_interruptible_all(&dn->readq); + + mutex_unlock(&dn->lock); +} + +static void dn_shutdown(struct tipc_dn_chan *dn) +{ + mutex_lock(&dn->lock); + + /* set state to STALE */ + dn->state = TIPC_STALE; + + /* complete all pending */ + complete(&dn->reply_comp); + + /* wakeup all readers */ + wake_up_interruptible_all(&dn->readq); + + mutex_unlock(&dn->lock); +} + +static void dn_handle_event(void *data, int event) +{ + struct tipc_dn_chan *dn = data; + + switch (event) { + case TIPC_CHANNEL_SHUTDOWN: + dn_shutdown(dn); + break; + + case TIPC_CHANNEL_DISCONNECTED: + dn_disconnected(dn); + break; + + case TIPC_CHANNEL_CONNECTED: + dn_connected(dn); + break; + + default: + pr_err("%s: unhandled event %d\n", __func__, event); + break; + } +} + +static void dn_handle_release(void *data) +{ + kfree(data); +} + +static struct tipc_chan_ops _dn_ops = { + .handle_msg = dn_handle_msg, + .handle_event = dn_handle_event, + .handle_release = dn_handle_release, +}; + +#define cdev_to_cdn(c) container_of((c), struct tipc_cdev_node, cdev) +#define cdn_to_vds(cdn) container_of((cdn), struct tipc_virtio_dev, cdev_node) + +static struct tipc_virtio_dev *_dn_lookup_vds(struct tipc_cdev_node *cdn) +{ + int ret; + struct tipc_virtio_dev *vds = NULL; + + mutex_lock(&tipc_devices_lock); + ret = idr_for_each(&tipc_devices, _match_data, cdn); + if (ret) { + vds = cdn_to_vds(cdn); + kref_get(&vds->refcount); + } + mutex_unlock(&tipc_devices_lock); + return vds; +} + +static int tipc_open(struct inode *inode, struct file *filp) +{ + int ret; + struct tipc_virtio_dev *vds; + struct tipc_dn_chan *dn; + struct tipc_cdev_node *cdn = cdev_to_cdn(inode->i_cdev); + + vds = _dn_lookup_vds(cdn); + if (!vds) { + ret = -ENOENT; + goto err_vds_lookup; + } + + dn = kzalloc(sizeof(*dn), GFP_KERNEL); + if (!dn) { + ret = -ENOMEM; + goto err_alloc_chan; + } + + mutex_init(&dn->lock); + init_waitqueue_head(&dn->readq); + init_completion(&dn->reply_comp); + INIT_LIST_HEAD(&dn->rx_msg_queue); + INIT_LIST_HEAD(&dn->mref_shm_list); + + dn->state = TIPC_DISCONNECTED; + + dn->chan = vds_create_channel(vds, &_dn_ops, dn); + if (IS_ERR(dn->chan)) { + ret = PTR_ERR(dn->chan); + goto err_create_chan; + } + + filp->private_data = dn; + kref_put(&vds->refcount, _free_vds); + return 0; + +err_create_chan: + kfree(dn); +err_alloc_chan: + kref_put(&vds->refcount, _free_vds); +err_vds_lookup: + return ret; +} + +static int dn_connect_ioctl(struct tipc_dn_chan *dn, char __user *usr_name) +{ + int err; + char name[MAX_SRV_NAME_LEN]; + + /* copy in service name from user space */ + err = strncpy_from_user(name, usr_name, sizeof(name)); + if (err < 0) { + pr_err("%s: copy_from_user (%p) failed (%d)\n", __func__, + usr_name, err); + return err; + } + name[sizeof(name) - 1] = '\0'; + + /* send connect request */ + err = tipc_chan_connect(dn->chan, name); + if (err) + return err; + + /* and wait for reply */ + return dn_wait_for_reply(dn, REPLY_TIMEOUT); +} + +#if !defined(CONFIG_COMPAT) +static int compat_import_iovec(int type, + const struct compat_iovec __user *uvector, + unsigned int nr_segs, unsigned int fast_segs, + struct iovec **iov, struct iov_iter *i) +{ + return -EINVAL; +} +#endif + +static long tipc_send_msg_ioctl(struct file *filp, unsigned long arg, + bool compat) +{ + ssize_t ret; + struct iov_iter msg_iter; + struct iovec iovstack[12]; + struct tipc_send_msg_req req; + struct tipc_shmem shmems[MAX_MEMREF_NUM]; + struct tipc_dn_chan *dn = filp->private_data; + struct iovec *iov = iovstack; + long timeout = (filp->f_flags & O_NONBLOCK) ? 0 : TXBUF_TIMEOUT; + bool mref_malloc = true; /* mref from malloc or mmap */ + struct mref_shm *mshm; + + /* copy in request */ + if (copy_from_user(&req, (const void __user *)arg, sizeof(req))) + return -EFAULT; + + if (req.shmemv_cnt > MAX_MEMREF_NUM) { + pr_err("%s: too many memrefs %u\n", __func__, req.shmemv_cnt); + return -EINVAL; + } + + /* import message iovecs */ + if (compat) + ret = compat_import_iovec(READ, (void *)(uintptr_t)req.msgiov, + req.msgiov_cnt, ARRAY_SIZE(iovstack), + &iov, &msg_iter); + else + ret = import_iovec(READ, (void *)(uintptr_t)req.msgiov, + req.msgiov_cnt, ARRAY_SIZE(iovstack), &iov, + &msg_iter); + if (ret < 0) + return ret; + + if (req.shmemv_cnt) { + /* import memref descriptors */ + if (copy_from_user(shmems, (const void __user *)req.shmemv, + req.shmemv_cnt * sizeof(shmems[0]))) { + ret = -EFAULT; + goto err_bad_descrs; + } + + /* + * NOTE(GRT): Since all of mref buffers either comes from + * malloc or mmap, check all buffers is not necessary. + * More, buffers from mref_mmap is always page-aligned, + * so we can skip the aux case, i.e., base[0] and base[2]. + */ + mutex_lock(&dn->lock); + list_for_each_entry(mshm, &dn->mref_shm_list, node) { + if (mshm->vm_start == shmems[0].base[1]) { + mref_malloc = false; + break; + } + } + mutex_unlock(&dn->lock); + } + + ret = _tipc_send_msg(dn->chan, &msg_iter, shmems, req.shmemv_cnt, + mref_malloc, timeout, true); + +err_bad_descrs: + kfree(iov); + return ret; +} + +static long tipc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long ret; + struct tipc_dn_chan *dn = filp->private_data; + + if (_IOC_TYPE(cmd) != TIPC_IOC_MAGIC) + return -EINVAL; + + switch (cmd) { + case TIPC_IOC_CONNECT: + ret = dn_connect_ioctl(dn, (char __user *)arg); + break; + case TIPC_IOC_SEND_MSG: + ret = tipc_send_msg_ioctl(filp, arg, false); + break; + default: + pr_warn("%s: Unhandled ioctl cmd: 0x%x\n", __func__, cmd); + ret = -EINVAL; + } + return ret; +} + +#if defined(CONFIG_COMPAT) + +static long tipc_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + int ret; + struct tipc_dn_chan *dn = filp->private_data; + void __user *user_req = compat_ptr(arg); + + if (_IOC_TYPE(cmd) != TIPC_IOC_MAGIC) + return -EINVAL; + + switch (cmd) { + case TIPC_IOC_CONNECT_COMPAT: + ret = dn_connect_ioctl(dn, user_req); + break; + case TIPC_IOC_SEND_MSG: + ret = tipc_send_msg_ioctl(filp, arg, true); + break; + default: + pr_warn("%s: Unhandled ioctl cmd: 0x%x\n", __func__, cmd); + ret = -EINVAL; + } + return ret; +} +#endif + +static inline bool _got_rx(struct tipc_dn_chan *dn) +{ + if (dn->state != TIPC_CONNECTED) + return true; + + if (!list_empty(&dn->rx_msg_queue)) + return true; + + return false; +} + +static ssize_t tipc_read_iter(struct kiocb *iocb, struct iov_iter *iter) +{ + ssize_t ret; + size_t len; + struct tipc_msg_buf *mb; + struct file *filp = iocb->ki_filp; + struct tipc_dn_chan *dn = filp->private_data; + + mutex_lock(&dn->lock); + + while (list_empty(&dn->rx_msg_queue)) { + if (dn->state != TIPC_CONNECTED) { + if (dn->state == TIPC_CONNECTING) + ret = -ENOTCONN; + else if (dn->state == TIPC_DISCONNECTED) + ret = -ENOTCONN; + else if (dn->state == TIPC_STALE) + ret = -ESHUTDOWN; + else + ret = -EBADFD; + goto out; + } + + mutex_unlock(&dn->lock); + + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; + + if (wait_event_interruptible(dn->readq, _got_rx(dn))) + return -ERESTARTSYS; + + mutex_lock(&dn->lock); + } + + mb = list_first_entry(&dn->rx_msg_queue, struct tipc_msg_buf, node); + + len = mb_avail_data(mb); + if (len > iov_iter_count(iter)) { + ret = -EMSGSIZE; + goto out; + } + + if (copy_to_iter(mb_get_data(mb, len), len, iter) != len) { + ret = -EFAULT; + goto out; + } + + ret = len; + list_del(&mb->node); + tipc_chan_put_rxbuf(dn->chan, mb); + +out: + mutex_unlock(&dn->lock); + return ret; +} + +static size_t aux_data_len(struct tipc_shmem *shmv, uint shmv_cnt) +{ + uint i; + size_t len; + unsigned int pg_num; + + len = shmv_cnt * sizeof(struct tipc_msg_mref_hdr); + for (i = 0; i < shmv_cnt; i++) { + pg_num = memref_count_pages(&shmv[i]); + len += pg_num * sizeof(struct ns_mem_page_info); + } + return len; +} + +static int _tipc_send_msg(struct tipc_chan *chan, struct iov_iter *msg_iter, + struct tipc_shmem *shmv, uint shmv_cnt, bool user, + long timeout, bool intr) +{ + int ret; + size_t len; + struct tipc_msg_buf *txbuf; + size_t aux_len = 0; + + /* pre flight check message length */ + len = iov_iter_count(msg_iter); + if (len > (chan->vds->msg_buf_sz - sizeof(struct tipc_msg_hdr))) + return -EMSGSIZE; + + if (shmv_cnt) { + /* do memref parameters check */ + ret = memrefv_preflight_check(shmv, shmv_cnt); + if (ret < 0) + return ret; + + /* calculate aux data size and add alignment */ + aux_len = + aux_data_len(shmv, shmv_cnt) + ALIGN(len, MEMREF_ALIGN); + } + + /* get or allocate tx buffer */ + txbuf = vds_get_txbuf(chan->vds, + sizeof(struct tipc_msg_hdr) + len + aux_len, + timeout, intr); + if (IS_ERR(txbuf)) + return PTR_ERR(txbuf); + + /* copy in message data */ + if (copy_from_iter(mb_put_data(txbuf, len), len, msg_iter) != len) { + ret = -EFAULT; + goto err_out; + } + + /* queue message */ + ret = _tipc_chan_queue_msg(chan, txbuf, shmv, shmv_cnt, user); + if (ret) + goto err_out; + + return len; + +err_out: + tipc_chan_put_txbuf(chan, txbuf); + return ret; +} + +static ssize_t tipc_write_iter(struct kiocb *iocb, struct iov_iter *iter) +{ + struct file *filp = iocb->ki_filp; + struct tipc_dn_chan *dn = filp->private_data; + long timeout = (filp->f_flags & O_NONBLOCK) ? 0 : TXBUF_TIMEOUT; + + return _tipc_send_msg(dn->chan, iter, NULL, 0, true, timeout, true); +} + +static unsigned int tipc_poll(struct file *filp, poll_table *wait) +{ + unsigned int mask = 0; + struct tipc_dn_chan *dn = filp->private_data; + + mutex_lock(&dn->lock); + + poll_wait(filp, &dn->readq, wait); + + /* Writes always succeed for now */ + mask |= POLLOUT | POLLWRNORM; + + if (!list_empty(&dn->rx_msg_queue)) + mask |= POLLIN | POLLRDNORM; + + if (dn->state != TIPC_CONNECTED) + mask |= POLLERR; + + mutex_unlock(&dn->lock); + return mask; +} + +void tipc_mref_vma_close(struct vm_area_struct *vma) +{ + struct mref_shm *mshm, *mshmtmp; + struct tipc_dn_chan *dn = vma->vm_private_data; + bool found = false; + + mutex_lock(&dn->lock); + + list_for_each_entry_safe(mshm, mshmtmp, &dn->mref_shm_list, node) { + if (mshm->vm_start == vma->vm_start) { + pr_info("%s: uva %lx sz %zx fl %lx kva %lx kpa %llx\n", + __func__, mshm->vm_start, mshm->size, + vma->vm_flags, mshm->vaddr, mshm->paddr); + _free_shareable_mem(mshm->size, (void *)mshm->vaddr, + mshm->paddr); + list_del(&mshm->node); + kfree(mshm); + found = true; + break; + } + } + + WARN_ON(unlikely(!found)); + + mutex_unlock(&dn->lock); +} + +static struct vm_operations_struct mref_vma_ops = { + .close = tipc_mref_vma_close, +}; + +static int tipc_mref_mmap(struct file *filp, struct vm_area_struct *vma) +{ + ulong offset, flags, pfn; + void *vaddr; + phys_addr_t paddr; + struct tipc_dn_chan *dn = filp->private_data; + size_t size; + pgprot_t prot; + struct mref_shm *mshm; + + if (!trusty_get_link_shbuf_device(0)) + return -ENODEV; + + flags = vma->vm_flags; + + if (WARN_ON((flags & VM_EXEC) && !(filp->f_mode & FMODE_EXEC))) + return -EINVAL; + + /* Check the mmap request is within bounds. */ + size = vma->vm_end - vma->vm_start; + if (WARN_ON(!PAGE_ALIGNED(size))) + return -EINVAL; + if (size > MAX_MREF_SIZE) + return -ENOMEM; + + offset = vma->vm_pgoff << PAGE_SHIFT; + if (WARN_ON(offset != 0)) + return -EINVAL; + + vaddr = _alloc_shareable_mem(size, NULL, GFP_KERNEL | __GFP_ZERO); + if (WARN_ON(!vaddr)) + return -ENOMEM; + paddr = trusty_shm_virt_to_phys(vaddr); + + mshm = kzalloc(sizeof(struct mref_shm), GFP_KERNEL); + if (WARN_ON(!mshm)) + return -ENOMEM; + + mshm->vm_start = vma->vm_start; + mshm->vaddr = (uintptr_t)vaddr; + mshm->paddr = paddr; + mshm->size = size; + list_add_tail(&mshm->node, &dn->mref_shm_list); + + pfn = (paddr + offset) >> PAGE_SHIFT; + prot = vm_get_page_prot(flags); + + vma->vm_ops = &mref_vma_ops; + vma->vm_private_data = dn; + + pr_info("%s: uva %lx sz %zx fl %lx kva %lx kpa %llx\n", __func__, + mshm->vm_start, mshm->size, vma->vm_flags, mshm->vaddr, + mshm->paddr); + + return remap_pfn_range(vma, vma->vm_start, pfn, size, prot); +} + +static int tipc_release(struct inode *inode, struct file *filp) +{ + struct tipc_dn_chan *dn = filp->private_data; + + dn_shutdown(dn); + + /* free all pending buffers */ + _free_msg_buf_list(&dn->rx_msg_queue); + + /* shutdown channel */ + tipc_chan_shutdown(dn->chan); + + /* and destroy it */ + tipc_chan_destroy(dn->chan); + + return 0; +} + +static const struct file_operations tipc_fops = { + .open = tipc_open, + .release = tipc_release, + .unlocked_ioctl = tipc_ioctl, +#if defined(CONFIG_COMPAT) + .compat_ioctl = tipc_compat_ioctl, +#endif + .read_iter = tipc_read_iter, + .write_iter = tipc_write_iter, + .poll = tipc_poll, + .mmap = tipc_mref_mmap, + .owner = THIS_MODULE, +}; + +/*****************************************************************************/ + +static void chan_trigger_event(struct tipc_chan *chan, int event) +{ + if (!event) + return; + + chan->ops->handle_event(chan->ops_arg, event); +} + +static void _cleanup_vq(struct virtqueue *vq) +{ + struct tipc_msg_buf *mb; + + while ((mb = virtqueue_detach_unused_buf(vq)) != NULL) + _free_msg_buf(mb); +} + +static int _create_cdev_node(struct device *parent, struct tipc_cdev_node *cdn, + const char *name) +{ + int ret; + dev_t devt; + + if (!name) { + dev_dbg(parent, "%s: cdev name has to be provided\n", __func__); + return -EINVAL; + } + + /* allocate minor */ + ret = idr_alloc(&tipc_devices, cdn, 0, MAX_DEVICES - 1, GFP_KERNEL); + if (ret < 0) { + dev_dbg(parent, "%s: failed (%d) to get id\n", __func__, ret); + return ret; + } + + cdn->minor = ret; + cdev_init(&cdn->cdev, &tipc_fops); + cdn->cdev.owner = THIS_MODULE; + + /* Add character device */ + devt = MKDEV(tipc_major, cdn->minor); + ret = cdev_add(&cdn->cdev, devt, 1); + if (ret) { + dev_dbg(parent, "%s: cdev_add failed (%d)\n", __func__, ret); + goto err_add_cdev; + } + + /* Create a device node */ + cdn->dev = device_create(tipc_class, parent, devt, NULL, + "trusty-ipc-%s", name); + if (IS_ERR(cdn->dev)) { + ret = PTR_ERR(cdn->dev); + dev_dbg(parent, "%s: device_create failed: %d\n", __func__, + ret); + goto err_device_create; + } + + return 0; + +err_device_create: + cdn->dev = NULL; + cdev_del(&cdn->cdev); +err_add_cdev: + idr_remove(&tipc_devices, cdn->minor); + return ret; +} + +static void create_cdev_node(struct tipc_virtio_dev *vds, + struct tipc_cdev_node *cdn) +{ + int err; + + mutex_lock(&tipc_devices_lock); + + if (!default_vdev) { + kref_get(&vds->refcount); + default_vdev = vds->vdev; + } + + if (vds->cdev_name[0] && !cdn->dev) { + kref_get(&vds->refcount); + err = _create_cdev_node(&vds->vdev->dev, cdn, vds->cdev_name); + if (err) { + dev_err(&vds->vdev->dev, + "failed (%d) to create cdev node\n", err); + kref_put(&vds->refcount, _free_vds); + } + } + mutex_unlock(&tipc_devices_lock); +} + +static void destroy_cdev_node(struct tipc_virtio_dev *vds, + struct tipc_cdev_node *cdn) +{ + mutex_lock(&tipc_devices_lock); + if (cdn->dev) { + device_destroy(tipc_class, MKDEV(tipc_major, cdn->minor)); + cdev_del(&cdn->cdev); + idr_remove(&tipc_devices, cdn->minor); + cdn->dev = NULL; + kref_put(&vds->refcount, _free_vds); + } + + if (default_vdev == vds->vdev) { + default_vdev = NULL; + kref_put(&vds->refcount, _free_vds); + } + + mutex_unlock(&tipc_devices_lock); +} + +static void _go_online(struct tipc_virtio_dev *vds) +{ + mutex_lock(&vds->lock); + if (vds->state == VDS_OFFLINE) + vds->state = VDS_ONLINE; + mutex_unlock(&vds->lock); + + create_cdev_node(vds, &vds->cdev_node); + + dev_info(&vds->vdev->dev, "is online\n"); +} + +static void _go_offline(struct tipc_virtio_dev *vds) +{ + struct tipc_chan *chan; + + /* change state to OFFLINE */ + mutex_lock(&vds->lock); + if (vds->state != VDS_ONLINE) { + mutex_unlock(&vds->lock); + return; + } + vds->state = VDS_OFFLINE; + mutex_unlock(&vds->lock); + + /* wakeup all waiters */ + wake_up_all(&vds->sendq); + + /* shutdown all channels */ + while ((chan = vds_lookup_channel(vds, TIPC_ANY_ADDR))) { + mutex_lock(&chan->lock); + chan->state = TIPC_STALE; + chan->remote = 0; + chan_trigger_event(chan, TIPC_CHANNEL_SHUTDOWN); + mutex_unlock(&chan->lock); + kref_put(&chan->refcount, _free_chan); + } + + /* shutdown device node */ + destroy_cdev_node(vds, &vds->cdev_node); + + dev_info(&vds->vdev->dev, "is offline\n"); +} + +static void _handle_conn_rsp(struct tipc_virtio_dev *vds, + struct tipc_conn_rsp_body *rsp, size_t len) +{ + struct tipc_chan *chan; + + if (sizeof(*rsp) != len) { + dev_err(&vds->vdev->dev, "%s: Invalid response length %zd\n", + __func__, len); + return; + } + + dev_dbg(&vds->vdev->dev, + "%s: connection response: for addr 0x%x: " + "status %d remote addr 0x%x\n", + __func__, rsp->target, rsp->status, rsp->remote); + + /* Lookup channel */ + chan = vds_lookup_channel(vds, rsp->target); + if (chan) { + mutex_lock(&chan->lock); + if (chan->state == TIPC_CONNECTING) { + if (!rsp->status) { + chan->state = TIPC_CONNECTED; + chan->remote = rsp->remote; + chan->max_msg_cnt = rsp->max_msg_cnt; + chan->max_msg_size = rsp->max_msg_size; + chan_trigger_event(chan, + TIPC_CHANNEL_CONNECTED); + } else { + chan->state = TIPC_DISCONNECTED; + chan->remote = 0; + chan_trigger_event(chan, + TIPC_CHANNEL_DISCONNECTED); + } + } + mutex_unlock(&chan->lock); + kref_put(&chan->refcount, _free_chan); + } +} + +static void _handle_disc_req(struct tipc_virtio_dev *vds, + struct tipc_disc_req_body *req, size_t len) +{ + struct tipc_chan *chan; + + if (sizeof(*req) != len) { + dev_err(&vds->vdev->dev, "%s: Invalid request length %zd\n", + __func__, len); + return; + } + + dev_dbg(&vds->vdev->dev, "%s: disconnect request: for addr 0x%x\n", + __func__, req->target); + + chan = vds_lookup_channel(vds, req->target); + if (chan) { + mutex_lock(&chan->lock); + if (chan->state == TIPC_CONNECTED || + chan->state == TIPC_CONNECTING) { + chan->state = TIPC_DISCONNECTED; + chan->remote = 0; + chan_trigger_event(chan, TIPC_CHANNEL_DISCONNECTED); + } + mutex_unlock(&chan->lock); + kref_put(&chan->refcount, _free_chan); + } +} + +static void _handle_mref_release_req(struct tipc_virtio_dev *vds, + struct tipc_mref_release_req_body *req, + size_t len) +{ + while (len >= sizeof(*req)) { + if (req->id) { + /* release memref with specified id */ + vds_memref_release(vds, &req->id, 1); + } + req++; + len -= sizeof(*req); + } + WARN_ON(len); +} + +static void _handle_ctrl_msg(struct tipc_virtio_dev *vds, void *data, int len, + u32 src) +{ + struct tipc_ctrl_msg *msg = data; + + if ((len < sizeof(*msg)) || (sizeof(*msg) + msg->body_len != len)) { + dev_err(&vds->vdev->dev, + "%s: Invalid message length ( %d vs. %d)\n", __func__, + (int)(sizeof(*msg) + msg->body_len), len); + return; + } + + dev_dbg(&vds->vdev->dev, + "%s: Incoming ctrl message: src 0x%x type %d len %d\n", + __func__, src, msg->type, msg->body_len); + + switch (msg->type) { + case TIPC_CTRL_MSGTYPE_GO_ONLINE: + _go_online(vds); + break; + + case TIPC_CTRL_MSGTYPE_GO_OFFLINE: + _go_offline(vds); + break; + + case TIPC_CTRL_MSGTYPE_CONN_RSP: + _handle_conn_rsp(vds, (struct tipc_conn_rsp_body *)msg->body, + msg->body_len); + break; + + case TIPC_CTRL_MSGTYPE_DISC_REQ: + _handle_disc_req(vds, (struct tipc_disc_req_body *)msg->body, + msg->body_len); + break; + + case TIPC_CTRL_MSGTYPE_MREF_RELEASE_REQ: { + struct tipc_mref_release_req_body *req = + (struct tipc_mref_release_req_body *)msg->body; + _handle_mref_release_req(vds, req, msg->body_len); + } break; + + default: + dev_warn(&vds->vdev->dev, "%s: Unexpected message type: %d\n", + __func__, msg->type); + } +} + +static int _handle_rxbuf(struct tipc_virtio_dev *vds, + struct tipc_msg_buf *rxbuf, size_t rxlen) +{ + int err; + struct scatterlist sg; + struct tipc_msg_hdr *msg; + struct device *dev = &vds->vdev->dev; + + /* message sanity check */ + if (rxlen > rxbuf->buf_sz) { + dev_warn(dev, "inbound msg is too big: %zd\n", rxlen); + goto drop_it; + } + + if (rxlen < sizeof(*msg)) { + dev_warn(dev, "inbound msg is too short: %zd\n", rxlen); + goto drop_it; + } + + /* reset buffer and put data */ + mb_reset(rxbuf); + mb_put_data(rxbuf, rxlen); + + /* get message header */ + msg = mb_get_data(rxbuf, sizeof(*msg)); + if (mb_avail_data(rxbuf) != msg->len) { + dev_warn(dev, "inbound msg length mismatch: (%d vs. %d)\n", + (uint)mb_avail_data(rxbuf), (uint)msg->len); + goto drop_it; + } + + dev_dbg(dev, "From: %d, To: %d, Len: %d, Flags: 0x%x, Reserved: %d\n", + msg->src, msg->dst, msg->len, msg->flags, msg->reserved); + + /* message directed to control endpoint is a special case */ + if (msg->dst == TIPC_CTRL_ADDR) { + _handle_ctrl_msg(vds, msg->data, msg->len, msg->src); + } else { + struct tipc_chan *chan = NULL; + /* Lookup channel */ + chan = vds_lookup_channel(vds, msg->dst); + if (chan) { + /* handle it */ + rxbuf = chan->ops->handle_msg(chan->ops_arg, rxbuf); + BUG_ON(!rxbuf); + kref_put(&chan->refcount, _free_chan); + } + } + +drop_it: + /* add the buffer back to the virtqueue */ + sg_init_one(&sg, rxbuf->buf_va, rxbuf->buf_sz); + err = virtqueue_add_inbuf(vds->rxvq, &sg, 1, rxbuf, GFP_KERNEL); + if (err < 0) { + dev_err(dev, "failed to add a virtqueue buffer: %d\n", err); + return err; + } + + return 0; +} + +static void _rxvq_cb(struct virtqueue *rxvq) +{ + unsigned int len; + struct tipc_msg_buf *mb; + unsigned int msg_cnt = 0; + struct tipc_virtio_dev *vds = rxvq->vdev->priv; + + while ((mb = virtqueue_get_buf(rxvq, &len)) != NULL) { + if (_handle_rxbuf(vds, mb, len)) + break; + msg_cnt++; + } + + /* tell the other size that we added rx buffers */ + if (msg_cnt) + virtqueue_kick(rxvq); +} + +static void _discard_ctrl_msg(struct tipc_virtio_dev *vds, + struct tipc_msg_buf *mb) +{ + /* nothing to do for control messages */ +} + +static void _discard_chan_msg(struct tipc_virtio_dev *vds, + struct tipc_msg_hdr *msg, struct tipc_msg_buf *mb) +{ + struct tipc_msg_mref_hdr *mhdr; + + /* skip message data */ + (void)mb_get_data(mb, msg->len); + + /* check if we have memrefs attached */ + if (!mb_avail_data(mb)) + return; /* no more data */ + + /* align for proper boundary */ + mb_align_read(mb, MEMREF_ALIGN); + + /* discard all memrefs */ + while (mb_avail_data(mb)) { + /* get memref */ + mhdr = mb_get_data(mb, sizeof(*mhdr)); + + /* release mref_by id */ + vds_memref_release(vds, &mhdr->id, 1); + + /* skip to next memref hdr */ + (void)mb_get_data(mb, + mhdr->pg_inf_cnt * sizeof(mhdr->pg_inf[0])); + } +} + +static void _txvq_cb(struct virtqueue *txvq) +{ + unsigned int len; + struct tipc_msg_buf *mb; + bool need_wakeup = false; + struct tipc_virtio_dev *vds = txvq->vdev->priv; + + dev_dbg(&txvq->vdev->dev, "%s\n", __func__); + + /* detach all buffers */ + mutex_lock(&vds->lock); + while ((mb = virtqueue_get_buf(txvq, &len)) != NULL) { + if ((int)len < 0) { + struct tipc_msg_hdr *msg; + + mb_reset_read(mb); + msg = mb_get_data(mb, sizeof(*msg)); + if (msg->dst == TIPC_CTRL_ADDR) + _discard_ctrl_msg(vds, mb); + else + _discard_chan_msg(vds, msg, mb); + } + need_wakeup |= _put_txbuf_locked(vds, mb); + } + mutex_unlock(&vds->lock); + + if (need_wakeup) { + /* wake up potential senders waiting for a tx buffer */ + wake_up_all(&vds->sendq); + } +} + +static int tipc_virtio_probe(struct virtio_device *vdev) +{ + int err, i; + struct tipc_virtio_dev *vds; + struct tipc_dev_config config; + struct virtqueue *vqs[2]; + vq_callback_t *vq_cbs[] = { _rxvq_cb, _txvq_cb }; + const char *vq_names[] = { "rx", "tx" }; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + bool *ctx = NULL; +#endif + + dev_dbg(&vdev->dev, "%s:\n", __func__); + + vds = kzalloc(sizeof(*vds), GFP_KERNEL); + if (!vds) + return -ENOMEM; + + vds->vdev = vdev; + + mutex_init(&vds->lock); + kref_init(&vds->refcount); + init_waitqueue_head(&vds->sendq); + INIT_LIST_HEAD(&vds->free_buf_list); + INIT_LIST_HEAD(&vds->stashed_buf_list); + idr_init(&vds->addr_idr); + idr_init(&vds->mref_idr); + mutex_init(&vds->mref_lock); + + /* set default max message size and alignment */ + memset(&config, 0, sizeof(config)); + config.msg_buf_max_size = DEFAULT_MSG_BUF_SIZE; + config.msg_buf_alignment = DEFAULT_MSG_BUF_ALIGN; + + /* get configuration if present */ + vdev->config->get(vdev, 0, &config, sizeof(config)); + + /* copy dev name */ + strlcpy(vds->cdev_name, config.dev_name, sizeof(vds->cdev_name)); + vds->cdev_name[sizeof(vds->cdev_name) - 1] = '\0'; + + /* find tx virtqueues (rx and tx and in this order) */ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 10, 0) + err = vdev->config->find_vqs(vdev, 2, vqs, vq_cbs, vq_names); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + err = vdev->config->find_vqs(vdev, 2, vqs, vq_cbs, vq_names, ctx, NULL); +#endif + if (err) + goto err_find_vqs; + + vds->rxvq = vqs[0]; + vds->txvq = vqs[1]; + + /* save max buffer size and count */ + vds->msg_buf_sz = config.msg_buf_max_size; + vds->msg_buf_max_cnt = virtqueue_get_vring_size(vds->txvq); + + /* set up the receive buffers */ + for (i = 0; i < virtqueue_get_vring_size(vds->rxvq); i++) { + struct scatterlist sg; + struct tipc_msg_buf *rxbuf; + + rxbuf = _alloc_msg_buf(vds->msg_buf_sz); + if (!rxbuf) { + dev_err(&vdev->dev, "failed to allocate rx buffer\n"); + err = -ENOMEM; + goto err_free_rx_buffers; + } + + sg_init_one(&sg, rxbuf->buf_va, rxbuf->buf_sz); + err = virtqueue_add_inbuf(vds->rxvq, &sg, 1, rxbuf, GFP_KERNEL); + WARN_ON(err); /* sanity check; this can't really happen */ + } + + vdev->priv = vds; + vds->state = VDS_OFFLINE; + + dev_dbg(&vdev->dev, "%s: done\n", __func__); + return 0; + +err_free_rx_buffers: + _cleanup_vq(vds->rxvq); +err_find_vqs: + kref_put(&vds->refcount, _free_vds); + return err; +} + +static void tipc_virtio_remove(struct virtio_device *vdev) +{ + struct tipc_virtio_dev *vds = vdev->priv; + + _go_offline(vds); + + mutex_lock(&vds->lock); + vds->state = VDS_DEAD; + vds->vdev = NULL; + mutex_unlock(&vds->lock); + + vdev->config->reset(vdev); + + idr_destroy(&vds->mref_idr); + idr_destroy(&vds->addr_idr); + + _cleanup_vq(vds->rxvq); + _cleanup_vq(vds->txvq); + _free_msg_buf_list(&vds->free_buf_list); + _free_msg_buf_list(&vds->stashed_buf_list); + + vdev->config->del_vqs(vds->vdev); + + kref_put(&vds->refcount, _free_vds); +} + +static struct virtio_device_id tipc_virtio_id_table[] = { + { VIRTIO_ID_TRUSTY_IPC, VIRTIO_DEV_ANY_ID }, + { 0 }, +}; + +static unsigned int features[] = { + 0, +}; + +static struct virtio_driver virtio_tipc_driver = { + .feature_table = features, + .feature_table_size = ARRAY_SIZE(features), + .driver.name = KBUILD_MODNAME, + .driver.owner = THIS_MODULE, + .id_table = tipc_virtio_id_table, + .probe = tipc_virtio_probe, + .remove = tipc_virtio_remove, +}; + +static int __init tipc_init(void) +{ + int ret; + dev_t dev; + + ret = alloc_chrdev_region(&dev, 0, MAX_DEVICES, KBUILD_MODNAME); + if (ret) { + pr_err("%s: alloc_chrdev_region failed: %d\n", __func__, ret); + return ret; + } + + tipc_major = MAJOR(dev); + tipc_class = class_create(THIS_MODULE, KBUILD_MODNAME); + if (IS_ERR(tipc_class)) { + ret = PTR_ERR(tipc_class); + pr_err("%s: class_create failed: %d\n", __func__, ret); + goto err_class_create; + } + + ret = register_virtio_driver(&virtio_tipc_driver); + if (ret) { + pr_err("failed to register virtio driver: %d\n", ret); + goto err_register_virtio_drv; + } + + return 0; + +err_register_virtio_drv: + class_destroy(tipc_class); + +err_class_create: + unregister_chrdev_region(dev, MAX_DEVICES); + return ret; +} + +static void __exit tipc_exit(void) +{ + unregister_virtio_driver(&virtio_tipc_driver); + class_destroy(tipc_class); + unregister_chrdev_region(MKDEV(tipc_major, 0), MAX_DEVICES); +} + +/* We need to init this early */ +subsys_initcall(tipc_init); +module_exit(tipc_exit); + +MODULE_DEVICE_TABLE(tipc, tipc_virtio_id_table); +MODULE_DESCRIPTION("Trusty IPC driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/trusty/trusty-irq.c b/drivers/trusty/trusty-irq.c new file mode 100644 index 000000000000..3de7ac28b9ee --- /dev/null +++ b/drivers/trusty/trusty-irq.c @@ -0,0 +1,598 @@ +/* + * Copyright (C) 2013 Google, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct trusty_irq { + struct trusty_irq_state *is; + struct hlist_node node; + unsigned int irq; + bool percpu; + bool enable; + struct trusty_irq __percpu *percpu_ptr; +}; + +struct trusty_irq_irqset { + struct hlist_head pending; + struct hlist_head inactive; +}; + +struct trusty_irq_state { + struct device *dev; + struct device *trusty_dev; + struct trusty_irq_irqset normal_irqs; + spinlock_t normal_irqs_lock; + struct trusty_irq_irqset __percpu *percpu_irqs; + struct notifier_block trusty_call_notifier; + struct hlist_node cpuhp_node; +}; + +static int trusty_irq_cpuhp_slot = -1; + +static void trusty_irq_enable_pending_irqs(struct trusty_irq_state *is, + struct trusty_irq_irqset *irqset, + bool percpu) +{ + struct hlist_node *n; + struct trusty_irq *trusty_irq; + + hlist_for_each_entry_safe(trusty_irq, n, &irqset->pending, node) { + dev_dbg(is->dev, + "%s: enable pending irq %d, percpu %d, cpu %d\n", + __func__, trusty_irq->irq, percpu, smp_processor_id()); + if (percpu) + enable_percpu_irq(trusty_irq->irq, 0); + else + enable_irq(trusty_irq->irq); + hlist_del(&trusty_irq->node); + hlist_add_head(&trusty_irq->node, &irqset->inactive); + } +} + +static void trusty_irq_enable_irqset(struct trusty_irq_state *is, + struct trusty_irq_irqset *irqset) +{ + struct trusty_irq *trusty_irq; + + hlist_for_each_entry(trusty_irq, &irqset->inactive, node) { + if (trusty_irq->enable) { + dev_warn(is->dev, + "%s: percpu irq %d already enabled, cpu %d\n", + __func__, trusty_irq->irq, smp_processor_id()); + continue; + } + dev_dbg(is->dev, "%s: enable percpu irq %d, cpu %d\n", __func__, + trusty_irq->irq, smp_processor_id()); + enable_percpu_irq(trusty_irq->irq, 0); + trusty_irq->enable = true; + } +} + +static void trusty_irq_disable_irqset(struct trusty_irq_state *is, + struct trusty_irq_irqset *irqset) +{ + struct hlist_node *n; + struct trusty_irq *trusty_irq; + + hlist_for_each_entry(trusty_irq, &irqset->inactive, node) { + if (!trusty_irq->enable) { + dev_warn(is->dev, + "irq %d already disabled, percpu %d, cpu %d\n", + trusty_irq->irq, trusty_irq->percpu, + smp_processor_id()); + continue; + } + dev_dbg(is->dev, "%s: disable irq %d, percpu %d, cpu %d\n", + __func__, trusty_irq->irq, trusty_irq->percpu, + smp_processor_id()); + trusty_irq->enable = false; + if (trusty_irq->percpu) + disable_percpu_irq(trusty_irq->irq); + else + disable_irq_nosync(trusty_irq->irq); + } + hlist_for_each_entry_safe(trusty_irq, n, &irqset->pending, node) { + if (!trusty_irq->enable) { + dev_warn( + is->dev, + "pending irq %d already disabled, percpu %d, cpu %d\n", + trusty_irq->irq, trusty_irq->percpu, + smp_processor_id()); + } + dev_dbg(is->dev, + "%s: disable pending irq %d, percpu %d, cpu %d\n", + __func__, trusty_irq->irq, trusty_irq->percpu, + smp_processor_id()); + trusty_irq->enable = false; + hlist_del(&trusty_irq->node); + hlist_add_head(&trusty_irq->node, &irqset->inactive); + } +} + +static int trusty_irq_call_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct trusty_irq_state *is; + + BUG_ON(!irqs_disabled()); + + if (action != TRUSTY_CALL_PREPARE) + return NOTIFY_DONE; + + is = container_of(nb, struct trusty_irq_state, trusty_call_notifier); + + spin_lock(&is->normal_irqs_lock); + trusty_irq_enable_pending_irqs(is, &is->normal_irqs, false); + spin_unlock(&is->normal_irqs_lock); + trusty_irq_enable_pending_irqs(is, this_cpu_ptr(is->percpu_irqs), true); + + return NOTIFY_OK; +} + +irqreturn_t trusty_irq_handler(int irq, void *data) +{ + struct trusty_irq *trusty_irq = data; + struct trusty_irq_state *is = trusty_irq->is; + struct trusty_irq_irqset *irqset; + + dev_dbg(is->dev, "%s: irq %d, percpu %d, cpu %d, enable %d\n", __func__, + irq, trusty_irq->irq, smp_processor_id(), trusty_irq->enable); + + if (trusty_irq->percpu) { + disable_percpu_irq(irq); + irqset = this_cpu_ptr(is->percpu_irqs); + } else { + disable_irq_nosync(irq); + irqset = &is->normal_irqs; + } + + spin_lock(&is->normal_irqs_lock); + if (trusty_irq->enable) { + hlist_del(&trusty_irq->node); + hlist_add_head(&trusty_irq->node, &irqset->pending); + } + spin_unlock(&is->normal_irqs_lock); + + trusty_enqueue_nop(is->trusty_dev, NULL); + + dev_dbg(is->dev, "%s: irq %d done\n", __func__, irq); + + return IRQ_HANDLED; +} + +static int trusty_irq_cpu_up(unsigned int cpu, struct hlist_node *node) +{ + unsigned long irq_flags; + struct trusty_irq_state *is; + + is = container_of(node, struct trusty_irq_state, cpuhp_node); + + dev_dbg(is->dev, "%s: cpu %d\n", __func__, cpu); + + local_irq_save(irq_flags); + trusty_irq_enable_irqset(is, this_cpu_ptr(is->percpu_irqs)); + local_irq_restore(irq_flags); + + return 0; +} + +static int trusty_irq_cpu_down(unsigned int cpu, struct hlist_node *node) +{ + unsigned long irq_flags; + struct trusty_irq_state *is; + + is = container_of(node, struct trusty_irq_state, cpuhp_node); + + dev_dbg(is->dev, "%s: cpu %d\n", __func__, cpu); + + local_irq_save(irq_flags); + trusty_irq_disable_irqset(is, this_cpu_ptr(is->percpu_irqs)); + local_irq_restore(irq_flags); + + return 0; +} + +static int trusty_irq_create_irq_mapping(struct trusty_irq_state *is, int irq) +{ + int ret; + int index; + u32 irq_pos; + u32 templ_idx; + u32 range_base; + u32 range_end; + struct of_phandle_args oirq; + + /* check if "interrupt-ranges" property is present */ + if (!of_find_property(is->dev->of_node, "interrupt-ranges", NULL)) { + /* fallback to old behavior to be backward compatible with + * systems that do not need IRQ domains. + */ + return irq; + } + + /* find irq range */ + for (index = 0;; index += 3) { + ret = of_property_read_u32_index(is->dev->of_node, + "interrupt-ranges", index, + &range_base); + if (ret) + return ret; + + ret = of_property_read_u32_index(is->dev->of_node, + "interrupt-ranges", index + 1, + &range_end); + if (ret) + return ret; + + if (irq >= range_base && irq <= range_end) + break; + } + + /* read the rest of range entry: template index and irq_pos */ + ret = of_property_read_u32_index(is->dev->of_node, "interrupt-ranges", + index + 2, &templ_idx); + if (ret) + return ret; + + /* read irq template */ + ret = of_parse_phandle_with_args(is->dev->of_node, + "interrupt-templates", + "#interrupt-cells", templ_idx, &oirq); + if (ret) + return ret; + + WARN_ON(!oirq.np); + WARN_ON(!oirq.args_count); + + /* + * An IRQ template is a non empty array of u32 values describing group + * of interrupts having common properties. The u32 entry with index + * zero contains the position of irq_id in interrupt specifier array + * followed by data representing interrupt specifier array with irq id + * field omitted, so to convert irq template to interrupt specifier + * array we have to move down one slot the first irq_pos entries and + * replace the resulting gap with real irq id. + */ + irq_pos = oirq.args[0]; + + if (irq_pos >= oirq.args_count) { + dev_err(is->dev, "irq pos is out of range: %d\n", irq_pos); + return -EINVAL; + } + + for (index = 1; index <= irq_pos; index++) + oirq.args[index - 1] = oirq.args[index]; + + oirq.args[irq_pos] = irq - range_base; + + ret = irq_create_of_mapping(&oirq); + + return (!ret) ? -EINVAL : ret; +} + +static int trusty_irq_init_normal_irq(struct trusty_irq_state *is, int tirq) +{ + int ret; + int irq; + unsigned long irq_flags; + struct trusty_irq *trusty_irq; + + dev_dbg(is->dev, "%s: irq %d\n", __func__, tirq); + + irq = trusty_irq_create_irq_mapping(is, tirq); + if (irq < 0) { + dev_err(is->dev, "trusty_irq_create_irq_mapping failed (%d)\n", + irq); + return irq; + } + + trusty_irq = kzalloc(sizeof(*trusty_irq), GFP_KERNEL); + if (!trusty_irq) + return -ENOMEM; + + trusty_irq->is = is; + trusty_irq->irq = irq; + trusty_irq->enable = true; + + spin_lock_irqsave(&is->normal_irqs_lock, irq_flags); + hlist_add_head(&trusty_irq->node, &is->normal_irqs.inactive); + spin_unlock_irqrestore(&is->normal_irqs_lock, irq_flags); + + ret = request_irq(irq, trusty_irq_handler, IRQF_NO_THREAD, "trusty", + trusty_irq); + if (ret) { + dev_err(is->dev, "request_irq failed %d\n", ret); + goto err_request_irq; + } + return 0; + +err_request_irq: + spin_lock_irqsave(&is->normal_irqs_lock, irq_flags); + hlist_del(&trusty_irq->node); + spin_unlock_irqrestore(&is->normal_irqs_lock, irq_flags); + kfree(trusty_irq); + return ret; +} + +static int trusty_irq_init_per_cpu_irq(struct trusty_irq_state *is, int tirq) +{ + int ret; + int irq; + unsigned int cpu; + struct trusty_irq __percpu *trusty_irq_handler_data; + + dev_dbg(is->dev, "%s: irq %d\n", __func__, tirq); + + irq = trusty_irq_create_irq_mapping(is, tirq); + if (irq <= 0) { + dev_err(is->dev, "trusty_irq_create_irq_mapping failed (%d)\n", + irq); + return irq; + } + + trusty_irq_handler_data = alloc_percpu(struct trusty_irq); + if (!trusty_irq_handler_data) + return -ENOMEM; + + for_each_possible_cpu(cpu) { + struct trusty_irq *trusty_irq; + struct trusty_irq_irqset *irqset; + + trusty_irq = per_cpu_ptr(trusty_irq_handler_data, cpu); + irqset = per_cpu_ptr(is->percpu_irqs, cpu); + + trusty_irq->is = is; + hlist_add_head(&trusty_irq->node, &irqset->inactive); + trusty_irq->irq = irq; + trusty_irq->percpu = true; + trusty_irq->percpu_ptr = trusty_irq_handler_data; + } + + ret = request_percpu_irq(irq, trusty_irq_handler, "trusty", + trusty_irq_handler_data); + if (ret) { + dev_err(is->dev, "request_percpu_irq failed %d\n", ret); + goto err_request_percpu_irq; + } + + return 0; + +err_request_percpu_irq: + for_each_possible_cpu(cpu) { + struct trusty_irq *trusty_irq; + + trusty_irq = per_cpu_ptr(trusty_irq_handler_data, cpu); + hlist_del(&trusty_irq->node); + } + + free_percpu(trusty_irq_handler_data); + return ret; +} + +static int trusty_smc_get_next_irq(struct trusty_irq_state *is, + unsigned long min_irq, bool per_cpu) +{ + return trusty_fast_call32(is->trusty_dev, SMC_FC_GET_NEXT_IRQ, min_irq, + per_cpu, 0); +} + +static int trusty_irq_init_one(struct trusty_irq_state *is, int irq, + bool per_cpu) +{ + int ret; + + irq = trusty_smc_get_next_irq(is, irq, per_cpu); + if (irq < 0) + return irq; + + if (per_cpu) + ret = trusty_irq_init_per_cpu_irq(is, irq); + else + ret = trusty_irq_init_normal_irq(is, irq); + + if (ret) { + dev_warn(is->dev, + "failed to initialize irq %d, irq will be ignored\n", + irq); + } + + return irq + 1; +} + +static void trusty_irq_free_irqs(struct trusty_irq_state *is) +{ + struct trusty_irq *irq; + struct hlist_node *n; + unsigned int cpu; + + hlist_for_each_entry_safe(irq, n, &is->normal_irqs.inactive, node) { + dev_dbg(is->dev, "%s: irq %d\n", __func__, irq->irq); + free_irq(irq->irq, irq); + hlist_del(&irq->node); + kfree(irq); + } + hlist_for_each_entry_safe( + irq, n, &this_cpu_ptr(is->percpu_irqs)->inactive, node) { + struct trusty_irq __percpu *trusty_irq_handler_data; + + dev_dbg(is->dev, "%s: percpu irq %d\n", __func__, irq->irq); + trusty_irq_handler_data = irq->percpu_ptr; + free_percpu_irq(irq->irq, trusty_irq_handler_data); + for_each_possible_cpu(cpu) { + struct trusty_irq *irq_tmp; + + irq_tmp = per_cpu_ptr(trusty_irq_handler_data, cpu); + hlist_del(&irq_tmp->node); + } + free_percpu(trusty_irq_handler_data); + } +} + +static int trusty_irq_probe(struct platform_device *pdev) +{ + int ret; + int irq; + unsigned long irq_flags; + struct trusty_irq_state *is; + + dev_dbg(&pdev->dev, "%s\n", __func__); + + is = kzalloc(sizeof(*is), GFP_KERNEL); + if (!is) { + ret = -ENOMEM; + goto err_alloc_is; + } + + is->dev = &pdev->dev; + is->trusty_dev = is->dev->parent; + spin_lock_init(&is->normal_irqs_lock); + is->percpu_irqs = alloc_percpu(struct trusty_irq_irqset); + if (!is->percpu_irqs) { + ret = -ENOMEM; + goto err_alloc_pending_percpu_irqs; + } + + platform_set_drvdata(pdev, is); + + is->trusty_call_notifier.notifier_call = trusty_irq_call_notify; + ret = trusty_call_notifier_register(is->trusty_dev, + &is->trusty_call_notifier); + if (ret) { + dev_err(&pdev->dev, + "failed to register trusty call notifier\n"); + goto err_trusty_call_notifier_register; + } + + for (irq = 0; irq >= 0;) + irq = trusty_irq_init_one(is, irq, true); + for (irq = 0; irq >= 0;) + irq = trusty_irq_init_one(is, irq, false); + + ret = cpuhp_state_add_instance(trusty_irq_cpuhp_slot, &is->cpuhp_node); + if (ret < 0) { + dev_err(&pdev->dev, "cpuhp_state_add_instance failed %d\n", + ret); + goto err_add_cpuhp_instance; + } + + return 0; + +err_add_cpuhp_instance: + spin_lock_irqsave(&is->normal_irqs_lock, irq_flags); + trusty_irq_disable_irqset(is, &is->normal_irqs); + spin_unlock_irqrestore(&is->normal_irqs_lock, irq_flags); + trusty_irq_free_irqs(is); + trusty_call_notifier_unregister(is->trusty_dev, + &is->trusty_call_notifier); +err_trusty_call_notifier_register: + free_percpu(is->percpu_irqs); +err_alloc_pending_percpu_irqs: + kfree(is); +err_alloc_is: + return ret; +} + +static int trusty_irq_remove(struct platform_device *pdev) +{ + int ret; + unsigned long irq_flags; + struct trusty_irq_state *is = platform_get_drvdata(pdev); + + dev_dbg(&pdev->dev, "%s\n", __func__); + + ret = cpuhp_state_remove_instance(trusty_irq_cpuhp_slot, + &is->cpuhp_node); + if (WARN_ON(ret)) + return ret; + + spin_lock_irqsave(&is->normal_irqs_lock, irq_flags); + trusty_irq_disable_irqset(is, &is->normal_irqs); + spin_unlock_irqrestore(&is->normal_irqs_lock, irq_flags); + + trusty_irq_free_irqs(is); + + trusty_call_notifier_unregister(is->trusty_dev, + &is->trusty_call_notifier); + free_percpu(is->percpu_irqs); + kfree(is); + + return 0; +} + +static const struct of_device_id trusty_test_of_match[] = { + { + .compatible = "android,trusty-irq-v1", + }, + {}, +}; + +static struct platform_driver trusty_irq_driver = { + .probe = trusty_irq_probe, + .remove = trusty_irq_remove, + .driver = { + .name = "trusty-irq", + .owner = THIS_MODULE, + .of_match_table = trusty_test_of_match, + }, +}; + +static int __init trusty_irq_driver_init(void) +{ + int ret; + + /* allocate dynamic cpuhp state slot */ + ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, + "trusty-irq:cpu:online", + trusty_irq_cpu_up, trusty_irq_cpu_down); + if (ret < 0) + return ret; + trusty_irq_cpuhp_slot = ret; + + /* Register platform driver */ + ret = platform_driver_register(&trusty_irq_driver); + if (ret < 0) + goto err_driver_register; + + return ret; + +err_driver_register: + /* undo cpuhp slot allocation */ + cpuhp_remove_multi_state(trusty_irq_cpuhp_slot); + trusty_irq_cpuhp_slot = -1; + + return ret; +} + +static void __exit trusty_irq_driver_exit(void) +{ + platform_driver_unregister(&trusty_irq_driver); + cpuhp_remove_multi_state(trusty_irq_cpuhp_slot); + trusty_irq_cpuhp_slot = -1; +} + +module_init(trusty_irq_driver_init); +module_exit(trusty_irq_driver_exit); diff --git a/drivers/trusty/trusty-link-shbuf.c b/drivers/trusty/trusty-link-shbuf.c new file mode 100644 index 000000000000..bbfa8e8bab27 --- /dev/null +++ b/drivers/trusty/trusty-link-shbuf.c @@ -0,0 +1,691 @@ +/* + * Copyright 2018 GoldenRiver Technologies Co., Ltd. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "trusty-link-shbuf.h" + +#define MAX_LINK_SHBUF_DEV 4 +#define ENABLE_SHBUF_RAMCONSOLE (1) + +#if ENABLE_SHBUF_RAMCONSOLE +#define RAMCONSOLE_SIZE (64ul * 1024ul) // 64KB +#define RAMCONSOLE_OFFSET (sizeof(uint64_t)) // 64B +#endif + +static struct link_shbuf_data *link_shbuf_dev[MAX_LINK_SHBUF_DEV]; +static u32 link_shbuf_dev_num; +struct link_shbuf_data *gpriv; + +u32 trusty_virtio_devid = 0, trusty_virtio_vqid = 0; + +/* Sentinel values for indicating missing communication channels */ +#define NO_OUTGOING_IRQ (0) +#define NO_INCOMING_IRQ (-1) + +static bool link_shbuf_data_invariant(const struct link_shbuf_data *priv) +{ + if (!priv) + return false; + + if (!priv->base || (uintptr_t)priv->base % PAGE_SIZE != 0) + return false; + + if (resource_size(&priv->buffer) == 0) + return false; + + return true; +} + +struct link_shbuf_data *trusty_get_link_shbuf_device(u32 lsdidx) +{ + if (lsdidx >= MAX_LINK_SHBUF_DEV) + return NULL; + + return link_shbuf_dev[lsdidx]; +} + +s32 trusty_link_shbuf_recv(u32 lsdidx, ulong *out) +{ + ulong payload; + int ret; + struct link_shbuf_data *dev = trusty_get_link_shbuf_device(lsdidx); + + if (!dev) { + dev_err(dev->dev, "lsdidx %u invalid (should be < %u)\n", + lsdidx, link_shbuf_dev_num); + return -EINVAL; + } + + do { + ret = wait_event_interruptible_timeout(dev->virq_wq, + dev->virq_pending, + msecs_to_jiffies(30000)); + if (ret < 0) { + dev_err(dev->dev, + "wait failed ret %d virq_pending %u\n", ret, + dev->virq_pending); + return ret; + } else if (ret == 0) { + dev_err(dev->dev, + "wait timeout ret %d virq_pending %u\n", ret, + dev->virq_pending); + return -ETIMEDOUT; + } + } while (!xchg(&dev->virq_pending, 0)); + + /* Ensure all PEs see the latest payload. */ + smp_rmb(); + payload = atomic64_xchg(&dev->virq_payload, 0); + + if (out) + *out = payload; + + dev_dbg(dev->dev, "%s: virq %d hwirq %d payload 0x%lx\n", __func__, + dev->virq, dev->hwirq, payload); + + return 0; +} + +s32 trusty_link_shbuf_send(u32 lsdidx, ulong payload) +{ + okl4_error_t err; + struct link_shbuf_data *dev = trusty_get_link_shbuf_device(lsdidx); + + if (!dev) { + dev_err(dev->dev, "lsdidx %u invalid (should be < %u)\n", + lsdidx, link_shbuf_dev_num); + return -EINVAL; + } + + err = _okl4_sys_vinterrupt_raise(dev->virqline, payload); + if (err != OKL4_OK) { + dev_err(dev->dev, + "failed to raise virq %u err %u payload 0x%lx\n", + dev->virqline, err, payload); + return -EIO; + } + + dev_dbg(dev->dev, "%s: virqline %d payload 0x%lx\n", __func__, + dev->virqline, payload); + + return 0; +} + +static int shbuf_virq_show(struct seq_file *m, void *v) +{ + ulong out; + + trusty_link_shbuf_recv(0, &out); + seq_printf(m, "%lx\n", out); + return 0; +} + +ssize_t shbuf_virq_write(struct file *filp, const char __user *ubuf, + size_t size, loff_t *off) +{ + char kbuf[32]; + ulong payload; + + if (!size) + return 0; + if (!access_ok(VERIFY_READ, ubuf, size)) + return -EFAULT; + + if (size > sizeof(kbuf) - 1) + size = sizeof(kbuf) - 1; + + if (copy_from_user(kbuf, ubuf, size)) + return -EFAULT; + + kbuf[size] = '\0'; + + if (kstrtoul(kbuf, 0, &payload) == 0) { + dev_info(gpriv->dev, "shbuf_send payload 0x%lx\n", payload); + trusty_link_shbuf_send(0, payload); + } + + return size; +} + +static int shbuf_virq_open(struct inode *inode, struct file *filp) +{ + return single_open(filp, shbuf_virq_show, NULL); +} + +static const struct file_operations shbuf_virq_fops = { + .open = shbuf_virq_open, + .read = seq_read, + .write = shbuf_virq_write, + .release = single_release, +}; + +static int shbuf_buffer_show(struct seq_file *m, void *v) +{ + struct link_shbuf_data *priv = m->private; +#if ENABLE_SHBUF_RAMCONSOLE + char *ramconsole_beg = NULL; + char *ramconsole_cur = NULL; + char *ramconsole_end = NULL; + + ramconsole_beg = priv->base; + ramconsole_cur = priv->base; + ramconsole_end = priv->base + RAMCONSOLE_SIZE; + + for (; ramconsole_cur < ramconsole_end; + ramconsole_cur += sizeof(uint64_t)) { + seq_printf(m, + "%08lx: %02x %02x %02x %02x %02x %02x %02x %02x\n", + ramconsole_cur - ramconsole_beg, + readb_relaxed(ramconsole_cur + 0), + readb_relaxed(ramconsole_cur + 1), + readb_relaxed(ramconsole_cur + 2), + readb_relaxed(ramconsole_cur + 3), + readb_relaxed(ramconsole_cur + 4), + readb_relaxed(ramconsole_cur + 5), + readb_relaxed(ramconsole_cur + 6), + readb_relaxed(ramconsole_cur + 7)); + } +#endif + + seq_printf(m, "%llx\n", readq_relaxed(priv->base)); + return 0; +} + +ssize_t shbuf_buffer_write(struct file *filp, const char __user *ubuf, + size_t size, loff_t *off) +{ + ulong offset; + void *ptr; + char kbuf[32]; + struct link_shbuf_data *priv = + ((struct seq_file *)filp->private_data)->private; + const uint64_t pattern = 0x11223344deadbeefULL; + + if (!size) + return 0; + if (!access_ok(VERIFY_READ, ubuf, size)) + return -EFAULT; + + if (size > sizeof(kbuf) - 1) + size = sizeof(kbuf) - 1; + + if (copy_from_user(kbuf, ubuf, size)) + return -EFAULT; + + kbuf[size] = '\0'; + + if (kstrtoul(kbuf, 0, &offset) == 0) { + if (offset > (RAMCONSOLE_SIZE - sizeof(uint64_t))) + offset = RAMCONSOLE_SIZE - sizeof(uint64_t); + ptr = (void *)((uintptr_t)priv->base + offset); + writeq_relaxed(pattern, ptr); + dev_info(gpriv->dev, "addr %p w:%llx r:%llx\n", ptr, pattern, + readq_relaxed(ptr)); + } + + return size; +} + +static int shbuf_buffer_open(struct inode *inode, struct file *filp) +{ + return single_open(filp, shbuf_buffer_show, inode->i_private); +} + +static const struct file_operations shbuf_buffer_fops = { + .open = shbuf_buffer_open, + .read = seq_read, + .write = shbuf_buffer_write, + .release = single_release, +}; + +s32 trusty_link_shbuf_smc(u32 lsdidx, ulong r0, ulong r1, ulong r2, ulong r3) +{ + unsigned long ret = 0; + struct link_shbuf_data *dev = trusty_get_link_shbuf_device(lsdidx); + + trusty_link_shbuf_send(lsdidx, r0); + trusty_link_shbuf_recv(lsdidx, NULL); + trusty_link_shbuf_send(lsdidx, r1); + trusty_link_shbuf_recv(lsdidx, NULL); + trusty_link_shbuf_send(lsdidx, r2); + trusty_link_shbuf_recv(lsdidx, NULL); + trusty_link_shbuf_send(lsdidx, r3); + trusty_link_shbuf_recv(lsdidx, &ret); + + dev_dbg(dev->dev, "%s: 0x%lx 0x%lx 0x%lx 0x%lx done (0x%lx)\n", + __func__, r0, r1, r2, r3, ret); + + return ret; +} + +/* + * Interrupt handler. + * + * This function will be called when our link partner uses the ioctl on their + * shared memory device to send an outgoing interrupt. + */ +static irqreturn_t link_shbuf_irq_handler(int irq, void *data) +{ + u64 payload, old, new; + struct _okl4_sys_interrupt_get_payload_return _payload; + + /* Retrieve a pointer to our private data. */ + struct link_shbuf_data *priv = data; + + if (WARN_ON(!link_shbuf_data_invariant(priv))) + return IRQ_NONE; + + /* + * We should only ever be handling a single interrupt, and only if there + * was an incoming interrupt in the configuration. + */ + if (WARN_ON(priv->virq < 0 || priv->virq != irq)) + return IRQ_NONE; + + _payload = _okl4_sys_interrupt_get_payload(priv->hwirq); + payload = (u64)_payload.payload; + + dev_dbg(priv->dev, "irq %d payload %llx\n", irq, payload); + + if (payload == TRUSTY_PROBE_DEFER) { + trusty_probe_late(); + } else if ((payload >> 32) == SMC_NC_VDEV_KICK_VQ) { + trusty_virtio_devid = (u32)((payload & 0xFFFF0000) >> 16); + trusty_virtio_vqid = (u32)(payload & 0x0000FFFF); + trusty_notifier_call(); + } else { + /* + * At this point, it is possible the pending flag is already + * set. It is up to the user to synchronise their transmission + * and acknowledgement of interrupts. + */ + + /* atomic64_or which is not universally available. */ + do { + old = atomic64_read(&priv->virq_payload); + new = old | payload; + } while (atomic64_cmpxchg(&priv->virq_payload, old, new) != + old); + + priv->virq_pending = true; + /* Ensure all PEs see the latest payload/pending. */ + smp_wmb(); + wake_up_interruptible(&priv->virq_wq); + } + + return IRQ_HANDLED; +} + +static int link_shbuf_dev_compare(const void *lhs, const void *rhs) +{ + const struct link_shbuf_data *l = lhs; + const struct link_shbuf_data *r = rhs; + + return l->hwirq - r->hwirq; +} + +/* + * Discover and add a new shared-buffer link. + * + * In the following function, we are expecting to parse device tree entries + * looking like the following: + * + * hypervisor { + * ... + * interrupt-line@1d { + * compatible = "okl,microvisor-interrupt-line", + * "okl,microvisor-capability"; + * phandle = <0x7>; + * reg = <0x1d>; + * label = "foo_virqline"; + * }; + * ; + * + * foo@41003000 { + * compatible = "okl,microvisor-link-shbuf", + * "okl,microvisor-shared-memory"; + * phandle = <0xd>; + * reg = <0x0 0x41003000 0x2000>; + * label = "foo"; + * okl,rwx = <0x6>; + * okl,interrupt-line = <0x7>; + * interrupts = <0x0 0x4 0x1>; + * interrupt-parent = <0x1>; + * }; + */ +static int trusty_link_shbuf_probe(struct platform_device *pdev) +{ + int ret, i; + struct device_node *node; + struct link_shbuf_data *priv; + const char *name; + u32 permissions; + struct dentry *debugfs_root; + + node = pdev->dev.of_node; + + if (!node) + return -ENODEV; + + ret = of_property_read_string(node, "label", &name); + if (ret < 0) { + dev_err(&pdev->dev, "failed to read label\n"); + return -ENODEV; + } + + if (strncmp(name, "mlvm_shm", strlen("mlvm_shm"))) { + dev_info(&pdev->dev, "label mismatch, expect %s was %s\n", + "mlvm_shm", name); + return -ENODEV; + } + + if (link_shbuf_dev_num >= MAX_LINK_SHBUF_DEV) { + dev_err(&pdev->dev, + "link-shbuf devices > MAX_LINK_SHBUF_DEV\n"); + return -ENOMEM; + } + + if (!gpriv) + gpriv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + priv = gpriv; + if (!priv) + return -ENOMEM; + + priv->dev = &pdev->dev; + + init_waitqueue_head(&priv->virq_wq); + priv->virq_pending = false; + + /* Retrieve information about the shared memory region. */ + ret = of_address_to_resource(node, 0, &priv->buffer); + if (ret < 0) { + dev_err(&pdev->dev, "failed to get buffer address\n"); + goto err_free_irq; + } + + /* + * We expect the Elfweaver to have validated that we have a non-NULL, + * page-aligned region. + */ + if (WARN_ON(priv->buffer.start == 0) || + WARN_ON(resource_size(&priv->buffer) % PAGE_SIZE != 0)) + goto err_free_irq; + + if (!devm_request_mem_region(&pdev->dev, priv->buffer.start, + resource_size(&priv->buffer), + dev_name(&pdev->dev))) { + ret = -EINVAL; + dev_err(&pdev->dev, + "failed to request_mem_region start %llx size %llx\n", + priv->buffer.start, resource_size(&priv->buffer)); + goto err_free_irq; + } + + priv->base = devm_memremap(&pdev->dev, priv->buffer.start, + resource_size(&priv->buffer), MEMREMAP_WB); + if (!priv->base) { + dev_err(&pdev->dev, + "failed to memremap, start %llx size %llx\n", + priv->buffer.start, resource_size(&priv->buffer)); + goto err_release_region; + } + +#if ENABLE_SHBUF_RAMCONSOLE + priv->ramconsole_size = RAMCONSOLE_SIZE; +#endif + + dev_info(&pdev->dev, + "shbuf pa %llx size %llx memremap_va 0x%lx rc_sz %zx\n", + priv->buffer.start, resource_size(&priv->buffer), + (uintptr_t)priv->base, priv->ramconsole_size); + + /* Read the permissions of the shared memory region. */ + ret = of_property_read_u32(node, "okl,rwx", &permissions); + if (ret < 0) { + dev_err(&pdev->dev, + "failed to read shared memory permissions\n"); + goto err_unmap_dev; + } + + if (permissions & ~(0007)) { + ret = -EINVAL; + dev_err(&pdev->dev, "invalid shared memory permissions %u\n", + permissions); + goto err_unmap_dev; + } + + priv->permissions = ((permissions & 0004) ? FMODE_READ : 0) | + ((permissions & 0002) ? FMODE_WRITE : 0) | + ((permissions & 0001) ? FMODE_EXEC : 0); + if (WARN_ON(priv->permissions == 0)) { + ret = -EINVAL; + dev_err(&pdev->dev, "shared memory permissions is 0\n"); + goto err_unmap_dev; + } + + debugfs_root = debugfs_create_dir(dev_name(&pdev->dev), NULL); + if (!IS_ERR_OR_NULL(debugfs_root)) { + debugfs_create_file("shbuf_virq", 0600, debugfs_root, NULL, + &shbuf_virq_fops); + debugfs_create_file("shbuf_buffer", 0600, debugfs_root, priv, + &shbuf_buffer_fops); + } else { + dev_err(&pdev->dev, "debugfs_create_dir '%s' failed ret %ld\n", + dev_name(&pdev->dev), PTR_ERR(debugfs_root)); + } + + dev_set_drvdata(&pdev->dev, priv); + + link_shbuf_dev[link_shbuf_dev_num++] = priv; + sort(link_shbuf_dev, link_shbuf_dev_num, sizeof(u64), + &link_shbuf_dev_compare, NULL); + + dev_info(&pdev->dev, "current %d link-shbuf devices registered.\n", + link_shbuf_dev_num); + + for (i = 0; i < link_shbuf_dev_num; i++) { + dev_info( + &pdev->dev, + " link_shbuf_dev[%d] virq %d hwirq %d virqline %d base 0x%lx remap_pa 0x%llx\n", + i, link_shbuf_dev[i]->virq, link_shbuf_dev[i]->hwirq, + link_shbuf_dev[i]->virqline, + (uintptr_t)link_shbuf_dev[i]->base, + page_to_phys(virt_to_page(link_shbuf_dev[i]->base))); + } + + return 0; + +err_unmap_dev: + dev_info(&pdev->dev, "%s: devm_memunmap %lx\n", __func__, + (uintptr_t)priv->base); + devm_memunmap(&pdev->dev, priv->base); +err_release_region: + devm_release_mem_region(&pdev->dev, priv->buffer.start, + resource_size(&priv->buffer)); +err_free_irq: + if (priv->virq != NO_INCOMING_IRQ) + devm_free_irq(&pdev->dev, priv->virq, priv); + devm_kfree(&pdev->dev, priv); + return ret; +} + +static int trusty_link_shbuf_remove(struct platform_device *pdev) +{ + struct link_shbuf_data *priv; + + priv = dev_get_drvdata(&pdev->dev); + WARN_ON(!link_shbuf_data_invariant(priv)); + + /* + * None of the following is strictly required, as these are all managed + * resources, but we clean it up anyway for clarity. + */ + + dev_info(&pdev->dev, "%s: devm_memunmap %lx\n", __func__, + (uintptr_t)priv->base); + + devm_memunmap(&pdev->dev, priv->base); + + devm_release_mem_region(&pdev->dev, priv->buffer.start, + resource_size(&priv->buffer)); + + if (priv->virq != NO_INCOMING_IRQ) + devm_free_irq(&pdev->dev, priv->virq, priv); + + devm_kfree(&pdev->dev, priv); + + return 0; +} + +static const struct of_device_id trusty_link_shbuf_match[] = { + { + .compatible = "okl,microvisor-shared-memory", + }, + {}, +}; + +static struct platform_driver trusty_link_shbuf_driver = { + .driver = { + .name = "trusty-link-shbuf", + .owner = THIS_MODULE, + .of_match_table = trusty_link_shbuf_match, + }, + .probe = trusty_link_shbuf_probe, + .remove = trusty_link_shbuf_remove, +}; + +/* Maximum number of minor device numbers */ +enum { + MAX_MINOR = 1 << MINORBITS, +}; + +static int __init trusty_link_shbuf_init(void) +{ + return platform_driver_register(&trusty_link_shbuf_driver); +} + +static void __exit trusty_link_shbuf_exit(void) +{ + platform_driver_unregister(&trusty_link_shbuf_driver); +} + +arch_initcall(trusty_link_shbuf_init); +module_exit(trusty_link_shbuf_exit); + +static int fifo_vipc_probe(struct platform_device *pdev) +{ + int ret; + struct device_node *node; + struct link_shbuf_data *priv; + const char *name; + struct irq_desc *desc; + + node = pdev->dev.of_node; + + if (!node) + return -ENODEV; + + ret = of_property_read_string(node, "label", &name); + if (ret < 0) { + dev_err(&pdev->dev, "failed to read label\n"); + return -ENODEV; + } + + priv = gpriv; + if (!priv) + return -ENOMEM; + + ret = of_property_read_u32(node, "reg", &priv->virqline); + if (ret < 0 || priv->virqline == OKL4_KCAP_INVALID) { + dev_err(&pdev->dev, + "failed to get \"reg\" of interrupt-line\n"); + return -ENODEV; + } + + /* Retrieve the incoming vIRQ number. Again, this is configurable and we + * anticipate that it may not exist. + */ + priv->virq = platform_get_irq(pdev, 0); + if (priv->virq < 0) { + dev_err(&pdev->dev, "failed to get platform irq\n"); + return -EINVAL; + } + + desc = irq_to_desc(priv->virq); + if (!desc) { + dev_err(&pdev->dev, "failed to get irq_desc\n"); + return -EINVAL; + } + priv->hwirq = desc->irq_data.hwirq; + + /* If we have a valid incoming vIRQ, register to handle it. */ + ret = devm_request_irq(&pdev->dev, priv->virq, link_shbuf_irq_handler, + 0, dev_name(&pdev->dev), priv); + if (ret < 0) { + dev_err(&pdev->dev, "failed to request_irq\n"); + return -EINVAL; + } + + dev_info(&pdev->dev, "%s: virq %d hwirq %d virqline %d\n", __func__, + priv->virq, priv->hwirq, priv->virqline); + +#if ENABLE_SHBUF_RAMCONSOLE + WARN_ON(!priv->base); + /* Notify HEE we're ready for virq communication */ + writeq_relaxed(TRUSTY_PROBE_DEFER, priv->base); + dev_info(&pdev->dev, "%s: TRUSTY_PROBE_DEFER %llx\n", __func__, + readq_relaxed(priv->base)); +#endif + return 0; +} + +static const struct of_device_id fifo_vipc_match[] = { + { + .compatible = "qcom,ipcr-fifo-xprt", + }, + {}, +}; + +static struct platform_driver fifo_vipc_driver = { + .driver = { + .name = "trusty-ipcr-fifo-xprt", + .owner = THIS_MODULE, + .of_match_table = fifo_vipc_match, + }, + .probe = fifo_vipc_probe, +}; + +static int __init fifo_vipc_init(void) +{ + return platform_driver_register(&fifo_vipc_driver); +} + +module_init(fifo_vipc_init); diff --git a/drivers/trusty/trusty-link-shbuf.h b/drivers/trusty/trusty-link-shbuf.h new file mode 100644 index 000000000000..8ffc20206bea --- /dev/null +++ b/drivers/trusty/trusty-link-shbuf.h @@ -0,0 +1,58 @@ +/* + * Copyright 2018 GoldenRiver Technologies Co., Ltd. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 _TRUSTY_LINK_SHBUF_H_ +#define _TRUSTY_LINK_SHBUF_H_ + +#include +#include + +/* Private data for this driver */ +struct link_shbuf_data { + /* Outgoing vIRQ */ + u32 virqline; + + /* Incoming vIRQ */ + int virq; + int hwirq; + atomic64_t virq_payload; + bool virq_pending; + wait_queue_head_t virq_wq; + + /* Shared memory region */ + void *base; + fmode_t permissions; + struct resource buffer; + size_t ramconsole_size; + + struct device *dev; +#ifdef CONFIG_TRUSTY_VIRQ_SIMULATION + void __iomem *gicd_base; +#endif +}; + +#ifdef CONFIG_TRUSTY_VIRQ_SIMULATION +/* Enabled only in QEMU environment. */ +extern int gic_set_affinity_possible(struct irq_data *d, + const struct cpumask *mask_val, + bool force); +#endif + +s32 trusty_link_shbuf_recv(u32 lsdidx, ulong *out); +s32 trusty_link_shbuf_send(u32 lsdidx, ulong payload); +s32 trusty_link_shbuf_smc(u32 lsdidx, ulong r0, ulong r1, ulong r2, ulong r3); +struct link_shbuf_data *trusty_get_link_shbuf_device(u32 lsdidx); + +#endif /* _TRUSTY_LINK_SHBUF_H_ */ diff --git a/drivers/trusty/trusty-log.c b/drivers/trusty/trusty-log.c new file mode 100644 index 000000000000..aef4718cdcb1 --- /dev/null +++ b/drivers/trusty/trusty-log.c @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2015 Google, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "trusty-log.h" + +#define TRUSTY_LOG_SIZE (PAGE_SIZE * 2) +#define TRUSTY_LINE_BUFFER_SIZE 256 + +struct trusty_log_state { + struct device *dev; + struct device *trusty_dev; + + /* + * This lock is here to ensure only one consumer will read + * from the log ring buffer at a time. + */ + spinlock_t lock; + struct log_rb *log; + uint32_t get; + + struct page *log_pages; + + struct notifier_block call_notifier; + struct notifier_block panic_notifier; + char line_buffer[TRUSTY_LINE_BUFFER_SIZE]; +}; + +static int log_read_line(struct trusty_log_state *s, int put, int get) +{ + struct log_rb *log = s->log; + int i; + char c = '\0'; + size_t max_to_read = + min((size_t)(put - get), sizeof(s->line_buffer) - 1); + size_t mask = log->sz - 1; + + for (i = 0; i < max_to_read && c != '\n';) + s->line_buffer[i++] = c = log->data[get++ & mask]; + s->line_buffer[i] = '\0'; + + return i; +} + +static void trusty_dump_logs(struct trusty_log_state *s) +{ + struct log_rb *log = s->log; + uint32_t get, put, alloc; + int read_chars; + + BUG_ON(!is_power_of_2(log->sz)); + + /* + * For this ring buffer, at any given point, alloc >= put >= get. + * The producer side of the buffer is not locked, so the put and alloc + * pointers must be read in a defined order (put before alloc) so + * that the above condition is maintained. A read barrier is needed + * to make sure the hardware and compiler keep the reads ordered. + */ + get = s->get; + while ((put = log->put) != get) { + /* Make sure that the read of put occurs before the read of log data */ + rmb(); + + /* Read a line from the log */ + read_chars = log_read_line(s, put, get); + + /* Force the loads from log_read_line to complete. */ + rmb(); + alloc = log->alloc; + + /* + * Discard the line that was just read if the data could + * have been corrupted by the producer. + */ + if (alloc - get > log->sz) { + pr_err("trusty: log overflow."); + get = alloc - log->sz; + continue; + } + pr_info("trusty: %s", s->line_buffer); + get += read_chars; + } + s->get = get; +} + +static int trusty_log_call_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct trusty_log_state *s; + unsigned long flags; + + if (action != TRUSTY_CALL_RETURNED) + return NOTIFY_DONE; + + s = container_of(nb, struct trusty_log_state, call_notifier); + spin_lock_irqsave(&s->lock, flags); + trusty_dump_logs(s); + spin_unlock_irqrestore(&s->lock, flags); + return NOTIFY_OK; +} + +static int trusty_log_panic_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct trusty_log_state *s; + + /* + * Don't grab the spin lock to hold up the panic notifier, even + * though this is racy. + */ + s = container_of(nb, struct trusty_log_state, panic_notifier); + pr_info("trusty-log panic notifier - trusty version %s", + trusty_version_str_get(s->trusty_dev)); + trusty_dump_logs(s); + return NOTIFY_OK; +} + +static bool trusty_supports_logging(struct device *device) +{ + int result; + + result = trusty_std_call32(device, SMC_SC_SHARED_LOG_VERSION, + TRUSTY_LOG_API_VERSION, 0, 0); + if (result == SM_ERR_UNDEFINED_SMC) { + pr_info("trusty-log not supported on secure side.\n"); + return false; + } else if (result < 0) { + pr_err("trusty std call (SMC_SC_SHARED_LOG_VERSION) failed: %d\n", + result); + return false; + } + + if (result == TRUSTY_LOG_API_VERSION) { + return true; + } else { + pr_info("trusty-log unsupported api version: %d, supported: %d\n", + result, TRUSTY_LOG_API_VERSION); + return false; + } +} + +static int trusty_log_probe(struct platform_device *pdev) +{ + struct trusty_log_state *s; + int result; + phys_addr_t pa; + + dev_dbg(&pdev->dev, "%s\n", __func__); + if (!trusty_supports_logging(pdev->dev.parent)) { + return -ENXIO; + } + + s = kzalloc(sizeof(*s), GFP_KERNEL); + if (!s) { + result = -ENOMEM; + goto error_alloc_state; + } + + spin_lock_init(&s->lock); + s->dev = &pdev->dev; + s->trusty_dev = s->dev->parent; + s->get = 0; + + s->log = trusty_shm_alloc(TRUSTY_LOG_SIZE, GFP_KERNEL | __GFP_ZERO); + if (!s->log) { + result = -ENOMEM; + goto error_alloc_log; + } + s->log_pages = virt_to_page(s->log); + + pa = trusty_shm_virt_to_phys(s->log); + result = trusty_std_call32(s->trusty_dev, SMC_SC_SHARED_LOG_ADD, + (u32)(pa), (u32)(pa >> 32), TRUSTY_LOG_SIZE); + if (result < 0) { + pr_err("trusty std call (SMC_SC_SHARED_LOG_ADD) failed: %d %pa\n", + result, &pa); + goto error_std_call; + } + + s->call_notifier.notifier_call = trusty_log_call_notify; + result = + trusty_call_notifier_register(s->trusty_dev, &s->call_notifier); + if (result < 0) { + dev_err(&pdev->dev, + "failed to register trusty call notifier\n"); + goto error_call_notifier; + } + + s->panic_notifier.notifier_call = trusty_log_panic_notify; + result = atomic_notifier_chain_register(&panic_notifier_list, + &s->panic_notifier); + if (result < 0) { + dev_err(&pdev->dev, "failed to register panic notifier\n"); + goto error_panic_notifier; + } + platform_set_drvdata(pdev, s); + + return 0; + +error_panic_notifier: + trusty_call_notifier_unregister(s->trusty_dev, &s->call_notifier); +error_call_notifier: + trusty_std_call32(s->trusty_dev, SMC_SC_SHARED_LOG_RM, (u32)pa, + (u32)(pa >> 32), 0); +error_std_call: + trusty_shm_free(s->log, TRUSTY_LOG_SIZE); +error_alloc_log: + kfree(s); +error_alloc_state: + return result; +} + +static int trusty_log_remove(struct platform_device *pdev) +{ + int result; + struct trusty_log_state *s = platform_get_drvdata(pdev); + phys_addr_t pa = page_to_phys(s->log_pages); + + dev_dbg(&pdev->dev, "%s\n", __func__); + + atomic_notifier_chain_unregister(&panic_notifier_list, + &s->panic_notifier); + trusty_call_notifier_unregister(s->trusty_dev, &s->call_notifier); + + result = trusty_std_call32(s->trusty_dev, SMC_SC_SHARED_LOG_RM, (u32)pa, + (u32)(pa >> 32), 0); + if (result) { + pr_err("trusty std call (SMC_SC_SHARED_LOG_RM) failed: %d\n", + result); + } + trusty_shm_free(s->log, TRUSTY_LOG_SIZE); + kfree(s); + + return 0; +} + +static const struct of_device_id trusty_test_of_match[] = { + { + .compatible = "android,trusty-log-v1", + }, + {}, +}; + +static struct platform_driver trusty_log_driver = { + .probe = trusty_log_probe, + .remove = trusty_log_remove, + .driver = { + .name = "trusty-log", + .owner = THIS_MODULE, + .of_match_table = trusty_test_of_match, + }, +}; + +module_platform_driver(trusty_log_driver); diff --git a/drivers/trusty/trusty-log.h b/drivers/trusty/trusty-log.h new file mode 100644 index 000000000000..bcb1ad32028e --- /dev/null +++ b/drivers/trusty/trusty-log.h @@ -0,0 +1,17 @@ +#ifndef _TRUSTY_LOG_H_ +#define _TRUSTY_LOG_H_ + +/* + * Ring buffer that supports one secure producer thread and one + * linux side consumer thread. + */ +struct log_rb { + volatile uint32_t alloc; + volatile uint32_t put; + uint32_t sz; + volatile char data[0]; +} __packed; + +#define TRUSTY_LOG_API_VERSION 1 + +#endif diff --git a/drivers/trusty/trusty-mem.c b/drivers/trusty/trusty-mem.c new file mode 100644 index 000000000000..5653888d4877 --- /dev/null +++ b/drivers/trusty/trusty-mem.c @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2015-2018 Google, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include + +#if defined(CONFIG_ARM64) +static int encode_page_inf(struct ns_mem_page_info *inf, uint64_t pte, + pgprot_t pgprot, bool writable) +{ + uint64_t mair; + uint attr_index = (pgprot_val(pgprot) & PTE_ATTRINDX_MASK) >> 2; + + asm("mrs %0, mair_el1\n" : "=&r"(mair)); + mair = (mair >> (attr_index * 8)) & 0xff; + + /* add other attributes */ + pte |= pgprot_val(pgprot); + + /* reset RDONLY flag if needed */ + if (writable) + pte &= ~PTE_RDONLY; + + inf->attr = (pte & 0x0000FFFFFFFFFFFFull) | (mair << 48); + return 0; +} +#elif defined(CONFIG_ARM_LPAE) +static int encode_page_inf(struct ns_mem_page_info *inf, uint64_t pte, + pgprot_t pgprot, bool writable) +{ + u32 mair; + uint attr_index = ((pgprot_val(pgprot) & L_PTE_MT_MASK) >> 2); + + if (attr_index >= 4) { + attr_index -= 4; + asm volatile("mrc p15, 0, %0, c10, c2, 1\n" : "=&r"(mair)); + } else { + asm volatile("mrc p15, 0, %0, c10, c2, 0\n" : "=&r"(mair)); + } + mair = (mair >> (attr_index * 8)) & 0xff; + + /* add other attributes */ + pte |= pgprot_val(pgprot); + + /* reset RDONLY flag if needed */ + if (writable) + pte &= ~(1 << 7); + + inf->attr = (pte & 0x0000FFFFFFFFFFFFull) | ((uint64_t)mair << 48); + return 0; +} +#elif defined(CONFIG_ARM) +static int encode_page_inf(struct ns_mem_page_info *inf, uint64_t pte, + pgprot_t pgprot, bool writable) +{ + u32 mair; + + /* check memory type */ + switch (pgprot_val(pgprot) & L_PTE_MT_MASK) { + case L_PTE_MT_WRITEALLOC: + /* Normal: write back write allocate */ + mair = 0xFF; + break; + + case L_PTE_MT_BUFFERABLE: + /* Normal: non-cacheble */ + mair = 0x44; + break; + + case L_PTE_MT_WRITEBACK: + /* Normal: writeback, read allocate */ + mair = 0xEE; + break; + + case L_PTE_MT_WRITETHROUGH: + /* Normal: write through */ + mair = 0xAA; + break; + + case L_PTE_MT_UNCACHED: + /* strongly ordered */ + mair = 0x00; + break; + + case L_PTE_MT_DEV_SHARED: + case L_PTE_MT_DEV_NONSHARED: + /* device */ + mair = 0x04; + break; + + default: + return -EINVAL; + } + + /* add other attributes */ + if (pgprot_val(pgprot) & L_PTE_USER) + pte |= (1 << 6); + if (!writable && pgprot_val(pgprot) & L_PTE_RDONLY) + pte |= (1 << 7); + if (pgprot_val(pgprot) & L_PTE_SHARED) + pte |= (3 << 8); /* inner sharable */ + + inf->attr = (pte & 0x0000FFFFFFFFFFFFull) | ((uint64_t)mair << 48); + return 0; +} +#else +static int encode_page_inf(struct ns_mem_page_info *inf, uint64_t pte, + pgprot_t pgprot, bool writable) +{ + return -EINVAL; +} +#endif + +int trusty_encode_page_info(struct ns_mem_page_info *inf, struct page *page, + pgprot_t pgprot, bool writable) +{ + if (!inf || !page) + return -EINVAL; + + return encode_page_inf(inf, (uint64_t)page_to_phys(page), pgprot, + writable); +} + +int trusty_call32_mem_buf(struct device *dev, u32 smcnr, struct page *page, + u32 size, pgprot_t pgprot, bool writable) +{ + int ret; + struct ns_mem_page_info pg_inf; + + if (!dev || !page) + return -EINVAL; + + ret = trusty_encode_page_info(&pg_inf, page, pgprot, writable); + if (ret) + return ret; + + if (SMC_IS_FASTCALL(smcnr)) { + return trusty_fast_call32(dev, smcnr, (u32)pg_inf.attr, + (u32)(pg_inf.attr >> 32), size); + } else { + return trusty_std_call32(dev, smcnr, (u32)pg_inf.attr, + (u32)(pg_inf.attr >> 32), size); + } +} diff --git a/drivers/trusty/trusty-shm.c b/drivers/trusty/trusty-shm.c new file mode 100644 index 000000000000..595de5c56e7e --- /dev/null +++ b/drivers/trusty/trusty-shm.c @@ -0,0 +1,209 @@ +/* + * Copyright 2018 GoldenRiver Technologies Co., Ltd. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include "trusty-link-shbuf.h" + +static struct gen_pool *gpool; +static struct device *gdev; /* trusty dev */ + +struct trusty_shm_ops { + void *(*alloc)(size_t size, gfp_t gfp_mask); /* alloc_pages_exact */ + void (*free)(void *vaddr, size_t size); /* free_pages_exact */ + /* arch/arm64/include/asm/memory.h */ + void *(*phys_to_virt)(phys_addr_t x); + phys_addr_t (*virt_to_phys)(const volatile void *x); +}; + +static void *default_shm_alloc(size_t sz, gfp_t gfp) +{ + return alloc_pages_exact(sz, gfp); +} + +static void default_shm_free(void *va, size_t sz) +{ + free_pages_exact(va, sz); +} + +static void *gpool_shm_alloc(size_t size, gfp_t gfp) +{ + unsigned long vaddr; + + BUG_ON(!gpool); + BUG_ON(!size); + + vaddr = gen_pool_alloc(gpool, size); + if (!vaddr) { + dev_err(gdev, + "%s: alloc shm failed, request 0x%zx avail 0x%zx\n", + __func__, size, gen_pool_avail(gpool)); + return NULL; + } + + if (gfp & __GFP_ZERO) + memset((void *)vaddr, 0, size); + + /* WARN if other gfp set ? */ + + dev_dbg(gdev, "%s: 0x%zx alloced, avail 0x%zx\n", __func__, size, + gen_pool_avail(gpool)); + + return (void *)vaddr; +} + +static void gpool_shm_free(void *vaddr, size_t size) +{ + BUG_ON(!gpool); + BUG_ON(!vaddr); + BUG_ON(!size); + + gen_pool_free(gpool, (uintptr_t)vaddr, size); + + dev_dbg(gdev, "%s: 0x%zx freed, avail 0x%zx\n", __func__, size, + gen_pool_avail(gpool)); +} + +static void *gpool_shm_phys_to_virt(phys_addr_t paddr) +{ + struct gen_pool_chunk *chunk; + size_t chunk_size = 0; + unsigned long vaddr = 0; + + BUG_ON(!gpool); + + rcu_read_lock(); + list_for_each_entry_rcu(chunk, &gpool->chunks, next_chunk) { + chunk_size = chunk->end_addr - chunk->start_addr + 1; + /* check addr is within chunk boundary */ + if (paddr >= chunk->phys_addr && + paddr <= (chunk->phys_addr + chunk_size)) { + vaddr = chunk->start_addr + (paddr - chunk->phys_addr); + break; + } + } + rcu_read_unlock(); + + return (void *)vaddr; +} + +static phys_addr_t gpool_shm_virt_to_phys(const volatile void *vaddr) +{ + BUG_ON(!gpool); + + return gen_pool_virt_to_phys(gpool, (uintptr_t)vaddr); +} + +static struct trusty_shm_ops shm_ops = { + .alloc = default_shm_alloc, + .free = default_shm_free, + .virt_to_phys = virt_to_phys, + .phys_to_virt = phys_to_virt, +}; + +void *trusty_shm_alloc(size_t size, gfp_t gfp) +{ + return shm_ops.alloc(size, gfp); +} + +void trusty_shm_free(void *vaddr, size_t size) +{ + shm_ops.free(vaddr, size); +} + +void *trusty_shm_phys_to_virt(unsigned long paddr) +{ + return shm_ops.phys_to_virt(paddr); +} + +phys_addr_t trusty_shm_virt_to_phys(void *vaddr) +{ + return shm_ops.virt_to_phys(vaddr); +} + +int trusty_shm_init_pool(struct device *dev) +{ + int rc; + unsigned long shm_pa = 0; + unsigned long shm_va = 0; + unsigned long shm_size = 0; + unsigned long shm_ioremap_pa = 0; /* for hee pa fixup */ + struct link_shbuf_data *shbuf_dev = NULL; + + gdev = dev; + shbuf_dev = trusty_get_link_shbuf_device(0); + + if (shbuf_dev) { + shm_pa = shbuf_dev->buffer.start + shbuf_dev->ramconsole_size; + shm_size = resource_size(&shbuf_dev->buffer) - + shbuf_dev->ramconsole_size; + shm_va = + (uintptr_t)shbuf_dev->base + shbuf_dev->ramconsole_size; + shm_ioremap_pa = page_to_phys(virt_to_page(shm_va)); + + dev_info(dev, "%s: pa %lx size %lx va %lx remap_pa %lx\n", + __func__, shm_pa, shm_size, shm_va, shm_ioremap_pa); + + gpool = gen_pool_create(3 /* 8 bytes aligned */, -1); + if (!gpool) { + dev_err(dev, "%s: gen_pool_create failed\n", __func__); + goto err_pool_create; + } + + gen_pool_set_algo(gpool, gen_pool_best_fit, NULL); + rc = gen_pool_add_virt(gpool, shm_va, shm_pa, shm_size, -1); + if (rc < 0) { + dev_err(dev, "%s: gen_pool_add_virt failed (%d)\n", + __func__, rc); + gen_pool_destroy(gpool); + goto err_pool_add_virt; + } + + shm_ops.alloc = gpool_shm_alloc; + shm_ops.free = gpool_shm_free; + shm_ops.virt_to_phys = gpool_shm_virt_to_phys; + shm_ops.phys_to_virt = gpool_shm_phys_to_virt; + /* + * ioremap va is not in kernel linear map, so we need + * to pass the offset between linear and non-linear + * mapping to hee for fixing up. + */ + trusty_fast_call32(dev, SMC_FC_IOREMAP_PA_INFO, + (u32)shm_ioremap_pa, + (u32)(shm_ioremap_pa >> 32), (u32)shm_size); + + dev_info(dev, "shm available, use shm alloc/free\n"); + return 0; + } + + /* fallback to alloc_pages_exact / free_pages_exact */ +err_pool_add_virt: + if (gpool) { + gen_pool_destroy(gpool); + gpool = NULL; + } +err_pool_create: + dev_info(dev, "shm not available, fallback to default alloc/free\n"); + return 0; +} + +void trusty_shm_destroy_pool(struct device *dev) +{ + if (gpool) + gen_pool_destroy(gpool); +} diff --git a/drivers/trusty/trusty-virq.c b/drivers/trusty/trusty-virq.c new file mode 100644 index 000000000000..9696fb1bc2f1 --- /dev/null +++ b/drivers/trusty/trusty-virq.c @@ -0,0 +1,242 @@ +/* + * Copyright 2018 GoldenRiver Technologies Co., Ltd. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "trusty-virq.h" + +#define MAX_VIRQ_DEV 4 +#define LESS (-1) +#define EQUAL (0) +#define GREATER (1) + +static struct virq_device *virqdev[MAX_VIRQ_DEV]; +static u32 virqdev_num; + +static irqreturn_t virq_handler(int irq, void *data) +{ + struct virq_device *dev = data; + ulong payload = okl4_get_virq_payload(irq); + + dev->virq.payload |= payload; + + /* Ensure all PEs see the latest payload. */ + smp_wmb(); + dev->virq.raised = true; + + wake_up_interruptible(&dev->virq.wq); + return IRQ_HANDLED; +} + +struct virq_device *trusty_get_virq_device(u32 virqidx) +{ + if (virqidx >= MAX_VIRQ_DEV) + return NULL; + + return virqdev[virqidx]; +} + +s32 trusty_virq_recv(u32 virqidx, ulong *out) +{ + ulong payload; + int ret; + struct virq_device *dev = trusty_get_virq_device(virqidx); + + if (!dev) + return -EINVAL; + + do { + ret = wait_event_interruptible(dev->virq.wq, dev->virq.raised); + if (ret < 0) + return ret; + } while (!xchg(&dev->virq.raised, 0)); + + /* Ensure all PEs see the latest payload. */ + smp_rmb(); + payload = xchg(&dev->virq.payload, 0); + + if (out) + *out = payload; + + dev_dbg(dev->dev, "%s: irq %d hwirq %d payload 0x%lx\n", __func__, + dev->virq.irqno, dev->virq.hwirq, payload); + + return 0; +} + +s32 trusty_virq_send(u32 virqidx, ulong payload) +{ + okl4_error_t err; + struct virq_device *dev = trusty_get_virq_device(virqidx); + + if (!dev) { + dev_err(dev->dev, "virqidx %u invalid, virqdev_num = %u\n", + virqidx, virqdev_num); + return -EINVAL; + } + + err = _okl4_sys_vinterrupt_raise(dev->source.kcap, payload); + if (err != OKL4_OK) { + dev_err(dev->dev, + "failed to raise virq %u err %u payload 0x%lx\n", + dev->source.kcap, err, payload); + return -EIO; + } + + dev_dbg(dev->dev, "%s: irq %d hwirq %d payload 0x%lx\n", __func__, + dev->virq.irqno, dev->virq.hwirq, payload); + + return 0; +} + +s32 trusty_virq_smc(u32 virqidx, ulong r0, ulong r1, ulong r2, ulong r3) +{ + unsigned long ret = 0; + struct virq_device *dev = trusty_get_virq_device(virqidx); + + trusty_virq_send(virqidx, r0); + trusty_virq_recv(virqidx, NULL); + trusty_virq_send(virqidx, r1); + trusty_virq_recv(virqidx, NULL); + trusty_virq_send(virqidx, r2); + trusty_virq_recv(virqidx, NULL); + trusty_virq_send(virqidx, r3); + trusty_virq_recv(virqidx, &ret); + + dev_dbg(dev->dev, "%s(%u): 0x%lx 0x%lx 0x%lx 0x%lx done (0x%lx)\n", + __func__, virqidx, r0, r1, r2, r3, ret); + + return ret; +} + +static int virqdev_compare(const void *lhs, const void *rhs) +{ + const struct virq_device *l = lhs; + const struct virq_device *r = rhs; + + if (l->virq.hwirq < r->virq.hwirq) + return LESS; + if (l->virq.hwirq > r->virq.hwirq) + return GREATER; + return EQUAL; +} + +static int trusty_virq_probe(struct platform_device *pdev) +{ + int ret, i; + struct device_node *node = pdev->dev.of_node; + struct virq_device *vdev = NULL; + struct irq_desc *desc; + + if (!node) { + dev_err(&pdev->dev, "of_node required\n"); + return -ENODEV; + } + + if (virqdev_num >= MAX_VIRQ_DEV) { + dev_err(&pdev->dev, "virq devices > MAX_VIRQ_DEV\n"); + return -ENOMEM; + } + + vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); + if (!vdev) + return -ENOMEM; + + vdev->dev = &pdev->dev; + vdev->virq.raised = false; + vdev->virq.payload = 0; + init_waitqueue_head(&vdev->virq.wq); + + if (!of_device_is_compatible(node, "okl,microvisor-interrupt-line")) { + ret = -EINVAL; + goto err_virq_register; + } + of_property_read_u32(node, "reg", &vdev->source.kcap); + + vdev->virq.irqno = platform_get_irq(pdev, 0); + if (vdev->virq.irqno < 0) { + ret = -EINVAL; + goto err_virq_register; + } + + ret = devm_request_irq(&pdev->dev, vdev->virq.irqno, virq_handler, 0, + "virq", vdev); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to request_irq: %d\n", ret); + goto err_virq_register; + } + + desc = irq_to_desc(vdev->virq.irqno); + if (desc) + vdev->virq.hwirq = desc->irq_data.hwirq; + + virqdev[virqdev_num++] = vdev; + sort(virqdev, virqdev_num, sizeof(u64), &virqdev_compare, NULL); + + dev_info(&pdev->dev, "current %d virq devices registered.\n", + virqdev_num); + + for (i = 0; i < virqdev_num; i++) { + dev_info(&pdev->dev, + " virqdev[%d] irqno %d hwirq %d kcap %d\n", i, + virqdev[i]->virq.irqno, virqdev[i]->virq.hwirq, + virqdev[i]->source.kcap); + } + + return 0; + +err_virq_register: + kfree(vdev); + return ret; +} + +static const struct of_device_id trusty_virq_of_match[] = { + { + .compatible = "okl,user-virq", + }, + {}, +}; + +static struct platform_driver trusty_virq_driver = { + .probe = trusty_virq_probe, + .driver = { + .name = "trusty-virq", + .owner = THIS_MODULE, + .of_match_table = trusty_virq_of_match, + }, +}; + +static int __init trusty_virq_init(void) +{ + return platform_driver_register(&trusty_virq_driver); +} + +static void __exit trusty_virq_exit(void) +{ + platform_driver_unregister(&trusty_virq_driver); +} + +arch_initcall(trusty_virq_init); +module_exit(trusty_virq_exit); diff --git a/drivers/trusty/trusty-virq.h b/drivers/trusty/trusty-virq.h new file mode 100644 index 000000000000..9db067e38bb5 --- /dev/null +++ b/drivers/trusty/trusty-virq.h @@ -0,0 +1,55 @@ +/* + * Copyright 2018 GoldenRiver Technologies Co., Ltd. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 _TRUSTY_VIRQ_H_ +#define _TRUSTY_VIRQ_H_ + +#include +#include + +struct virq_data { + wait_queue_head_t wq; + int irqno; + int hwirq; + bool raised; + unsigned long payload; +}; + +struct source_data { + okl4_kcap_t kcap; +}; + +struct virq_device { + struct device *dev; + struct virq_data virq; /* notify from hee */ + struct source_data source; /* notify to hee */ +#ifdef CONFIG_TRUSTY_VIRQ_SIMULATION + void __iomem *gicd_base; +#endif +}; + +#ifdef CONFIG_TRUSTY_VIRQ_SIMULATION +/* Enabled only in QEMU environment. */ +extern int gic_set_affinity_possible(struct irq_data *d, + const struct cpumask *mask_val, + bool force); +#endif + +s32 trusty_virq_recv(u32 virqidx, ulong *out); +s32 trusty_virq_send(u32 virqidx, ulong payload); +s32 trusty_virq_smc(u32 virqidx, ulong r0, ulong r1, ulong r2, ulong r3); +struct virq_device *trusty_get_virq_device(u32 virqidx); + +#endif /* _TRUSTY_VIRQ_H_ */ diff --git a/drivers/trusty/trusty-virtio.c b/drivers/trusty/trusty-virtio.c new file mode 100644 index 000000000000..a47b076256b4 --- /dev/null +++ b/drivers/trusty/trusty-virtio.c @@ -0,0 +1,761 @@ +/* + * Trusty Virtio driver + * + * Copyright 2018 GoldenRiver Technologies Co., Ltd. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * Copyright (C) 2015 Google, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "trusty-link-shbuf.h" + +#define RSC_DESCR_VER 1 + +struct trusty_vdev; + +struct trusty_ctx { + struct device *dev; + void *shared_va; + size_t shared_sz; + struct work_struct check_vqs; + struct work_struct kick_vqs; + struct notifier_block call_notifier; + struct list_head vdev_list; + struct mutex mlock; /* protects vdev_list */ + struct workqueue_struct *kick_wq; + struct workqueue_struct *check_wq; +}; + +struct trusty_vring { + void *vaddr; + phys_addr_t paddr; + size_t size; + uint align; + uint elem_num; + u32 notifyid; + atomic_t needs_kick; + struct fw_rsc_vdev_vring *vr_descr; + struct virtqueue *vq; + struct trusty_vdev *tvdev; + struct trusty_nop kick_nop; +}; + +struct trusty_vdev { + struct list_head node; + struct virtio_device vdev; + struct trusty_ctx *tctx; + u32 notifyid; + uint config_len; + void *config; + struct fw_rsc_vdev *vdev_descr; + uint vring_num; + struct trusty_vring vrings[0]; +}; + +#define vdev_to_tvdev(vd) container_of((vd), struct trusty_vdev, vdev) + +static void check_all_vqs(struct work_struct *work) +{ + uint i; + struct trusty_ctx *tctx = + container_of(work, struct trusty_ctx, check_vqs); + struct trusty_vdev *tvdev; + + list_for_each_entry(tvdev, &tctx->vdev_list, node) { + for (i = 0; i < tvdev->vring_num; i++) + vring_interrupt(0, tvdev->vrings[i].vq); + } +} + +static int trusty_call_notify(struct notifier_block *nb, unsigned long action, + void *data) +{ + struct trusty_ctx *tctx; + + if (action != TRUSTY_CALL_RETURNED) + return NOTIFY_DONE; + + tctx = container_of(nb, struct trusty_ctx, call_notifier); + queue_work(tctx->check_wq, &tctx->check_vqs); + + return NOTIFY_OK; +} + +static void kick_vq(struct trusty_ctx *tctx, struct trusty_vdev *tvdev, + struct trusty_vring *tvr) +{ + int ret; + + dev_dbg(tctx->dev, "%s: vdev_id=%d: vq_id=%d\n", __func__, + tvdev->notifyid, tvr->notifyid); + + ret = trusty_std_call32(tctx->dev->parent, SMC_SC_VDEV_KICK_VQ, + tvdev->notifyid, tvr->notifyid, 0); + if (ret) { + dev_err(tctx->dev, "vq notify (%d, %d) returned %d\n", + tvdev->notifyid, tvr->notifyid, ret); + } +} + +static void kick_vqs(struct work_struct *work) +{ + uint i; + struct trusty_vdev *tvdev; + struct trusty_ctx *tctx = + container_of(work, struct trusty_ctx, kick_vqs); + mutex_lock(&tctx->mlock); + list_for_each_entry(tvdev, &tctx->vdev_list, node) { + for (i = 0; i < tvdev->vring_num; i++) { + struct trusty_vring *tvr = &tvdev->vrings[i]; + if (atomic_xchg(&tvr->needs_kick, 0)) + kick_vq(tctx, tvdev, tvr); + } + } + mutex_unlock(&tctx->mlock); +} + +static bool trusty_virtio_notify(struct virtqueue *vq) +{ + struct trusty_vring *tvr = vq->priv; + struct trusty_vdev *tvdev = tvr->tvdev; + struct trusty_ctx *tctx = tvdev->tctx; + u32 api_ver = trusty_get_api_version(tctx->dev->parent); + ulong smc_nr = SMC_NC_VDEV_KICK_VQ; + ulong payload = (smc_nr << 32) | (tvdev->notifyid << 16) | + (u16)tvr->notifyid; + + if (api_ver < TRUSTY_API_VERSION_SMP_NOP) { + atomic_set(&tvr->needs_kick, 1); + queue_work(tctx->kick_wq, &tctx->kick_vqs); + } else { + if (trusty_get_link_shbuf_device(0)) + trusty_link_shbuf_send(0, payload); + else + trusty_enqueue_nop(tctx->dev->parent, &tvr->kick_nop); + } + + return true; +} + +static int trusty_load_device_descr(struct trusty_ctx *tctx, void *va, + size_t sz) +{ + int ret; + + dev_dbg(tctx->dev, "%s: %zu bytes @ %p\n", __func__, sz, va); + + ret = trusty_call32_mem_buf(tctx->dev->parent, SMC_SC_VIRTIO_GET_DESCR, + virt_to_page(va), sz, PAGE_KERNEL, true); + if (ret < 0) { + dev_err(tctx->dev, "%s: virtio get descr returned (%d)\n", + __func__, ret); + return -ENODEV; + } + return ret; +} + +static void trusty_virtio_stop(struct trusty_ctx *tctx, void *va, size_t sz) +{ + int ret; + + dev_dbg(tctx->dev, "%s: %zu bytes @ %p\n", __func__, sz, va); + + ret = trusty_call32_mem_buf(tctx->dev->parent, SMC_SC_VIRTIO_STOP, + virt_to_page(va), sz, PAGE_KERNEL, false); + if (ret) { + dev_err(tctx->dev, "%s: virtio done returned (%d)\n", __func__, + ret); + return; + } +} + +static int trusty_virtio_start(struct trusty_ctx *tctx, void *va, size_t sz) +{ + int ret; + + dev_dbg(tctx->dev, "%s: %zu bytes @ %p\n", __func__, sz, va); + + ret = trusty_call32_mem_buf(tctx->dev->parent, SMC_SC_VIRTIO_START, + virt_to_page(va), sz, PAGE_KERNEL, false); + if (ret) { + dev_err(tctx->dev, "%s: virtio start returned (%d)\n", __func__, + ret); + return -ENODEV; + } + return 0; +} + +static void trusty_virtio_reset(struct virtio_device *vdev) +{ + struct trusty_vdev *tvdev = vdev_to_tvdev(vdev); + struct trusty_ctx *tctx = tvdev->tctx; + + dev_dbg(&vdev->dev, "reset vdev_id=%d\n", tvdev->notifyid); + trusty_std_call32(tctx->dev->parent, SMC_SC_VDEV_RESET, tvdev->notifyid, + 0, 0); +} + +static u64 trusty_virtio_get_features(struct virtio_device *vdev) +{ + struct trusty_vdev *tvdev = vdev_to_tvdev(vdev); + return tvdev->vdev_descr->dfeatures; +} + +static int trusty_virtio_finalize_features(struct virtio_device *vdev) +{ + struct trusty_vdev *tvdev = vdev_to_tvdev(vdev); + + /* Make sure we don't have any features > 32 bits! */ + BUG_ON((u32)vdev->features != vdev->features); + + tvdev->vdev_descr->gfeatures = vdev->features; + return 0; +} + +static void trusty_virtio_get_config(struct virtio_device *vdev, + unsigned offset, void *buf, unsigned len) +{ + struct trusty_vdev *tvdev = vdev_to_tvdev(vdev); + + dev_dbg(&vdev->dev, "%s: %d bytes @ offset %d\n", __func__, len, + offset); + + if (tvdev->config) { + if (offset + len <= tvdev->config_len) + memcpy(buf, tvdev->config + offset, len); + } +} + +static void trusty_virtio_set_config(struct virtio_device *vdev, + unsigned offset, const void *buf, + unsigned len) +{ + dev_dbg(&vdev->dev, "%s\n", __func__); +} + +static u8 trusty_virtio_get_status(struct virtio_device *vdev) +{ + struct trusty_vdev *tvdev = vdev_to_tvdev(vdev); + return tvdev->vdev_descr->status; +} + +static void trusty_virtio_set_status(struct virtio_device *vdev, u8 status) +{ + struct trusty_vdev *tvdev = vdev_to_tvdev(vdev); + tvdev->vdev_descr->status = status; +} + +static void _del_vqs(struct virtio_device *vdev) +{ + uint i; + struct trusty_vdev *tvdev = vdev_to_tvdev(vdev); + struct trusty_vring *tvr = &tvdev->vrings[0]; + + for (i = 0; i < tvdev->vring_num; i++, tvr++) { + /* dequeue kick_nop */ + trusty_dequeue_nop(tvdev->tctx->dev->parent, &tvr->kick_nop); + + /* delete vq */ + if (tvr->vq) { + vring_del_virtqueue(tvr->vq); + tvr->vq = NULL; + } + /* delete vring */ + if (tvr->vaddr) { + trusty_shm_free(tvr->vaddr, tvr->size); + tvr->vaddr = NULL; + } + } +} + +static void trusty_virtio_del_vqs(struct virtio_device *vdev) +{ + dev_dbg(&vdev->dev, "%s\n", __func__); + _del_vqs(vdev); +} + +static struct virtqueue *_find_vq(struct virtio_device *vdev, unsigned id, + void (*callback)(struct virtqueue *vq), + const char *name +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + , + bool ctx +#endif +) +{ + struct trusty_vring *tvr; + struct trusty_vdev *tvdev = vdev_to_tvdev(vdev); + phys_addr_t pa; + + if (!name) + return ERR_PTR(-EINVAL); + + if (id >= tvdev->vring_num) + return ERR_PTR(-EINVAL); + + tvr = &tvdev->vrings[id]; + + /* actual size of vring (in bytes) */ + tvr->size = PAGE_ALIGN(vring_size(tvr->elem_num, tvr->align)); + + /* allocate memory for the vring. */ + tvr->vaddr = trusty_shm_alloc(tvr->size, GFP_KERNEL | __GFP_ZERO); + if (!tvr->vaddr) { + dev_err(&vdev->dev, "vring alloc failed\n"); + return ERR_PTR(-ENOMEM); + } + + pa = trusty_shm_virt_to_phys(tvr->vaddr); + /* save vring address to shared structure */ + tvr->vr_descr->da = (u32)pa; + /* da field is only 32 bit wide. Use previously unused 'reserved' field + * to store top 32 bits of 64-bit address + */ + tvr->vr_descr->pa = (u32)(pa >> 32); + + dev_info(&vdev->dev, "vring%d: va(pa) %p(%llx) qsz %d notifyid %d\n", + id, tvr->vaddr, (u64)tvr->paddr, tvr->elem_num, tvr->notifyid); + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 10, 0) + tvr->vq = vring_new_virtqueue(id, tvr->elem_num, tvr->align, vdev, true, + tvr->vaddr, trusty_virtio_notify, + callback, name); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + tvr->vq = vring_new_virtqueue(id, tvr->elem_num, tvr->align, vdev, true, + ctx, tvr->vaddr, trusty_virtio_notify, + callback, name); +#endif + if (!tvr->vq) { + dev_err(&vdev->dev, "vring_new_virtqueue %s failed\n", name); + goto err_new_virtqueue; + } + + tvr->vq->priv = tvr; + + return tvr->vq; + +err_new_virtqueue: + trusty_shm_free(tvr->vaddr, tvr->size); + tvr->vaddr = NULL; + return ERR_PTR(-ENOMEM); +} + +static int trusty_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, + struct virtqueue *vqs[], + vq_callback_t *callbacks[], + const char *const names[] +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + , + const bool *ctx, struct irq_affinity *desc +#endif +) +{ + uint i; + int ret; + + for (i = 0; i < nvqs; i++) { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 10, 0) + vqs[i] = _find_vq(vdev, i, callbacks[i], names[i]); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + vqs[i] = _find_vq(vdev, i, callbacks[i], names[i], + ctx ? ctx[i] : false); +#endif + if (IS_ERR(vqs[i])) { + ret = PTR_ERR(vqs[i]); + _del_vqs(vdev); + return ret; + } + } + return 0; +} + +static const char *trusty_virtio_bus_name(struct virtio_device *vdev) +{ + return "trusty-virtio"; +} + +/* The ops structure which hooks everything together. */ +static const struct virtio_config_ops trusty_virtio_config_ops = { + .get_features = trusty_virtio_get_features, + .finalize_features = trusty_virtio_finalize_features, + .get = trusty_virtio_get_config, + .set = trusty_virtio_set_config, + .get_status = trusty_virtio_get_status, + .set_status = trusty_virtio_set_status, + .reset = trusty_virtio_reset, + .find_vqs = trusty_virtio_find_vqs, + .del_vqs = trusty_virtio_del_vqs, + .bus_name = trusty_virtio_bus_name, +}; + +static int trusty_virtio_add_device(struct trusty_ctx *tctx, + struct fw_rsc_vdev *vdev_descr, + struct fw_rsc_vdev_vring *vr_descr, + void *config) +{ + int i, ret; + struct trusty_vdev *tvdev; + + tvdev = kzalloc(sizeof(struct trusty_vdev) + + vdev_descr->num_of_vrings * + sizeof(struct trusty_vring), + GFP_KERNEL); + if (!tvdev) { + dev_err(tctx->dev, "Failed to allocate VDEV\n"); + return -ENOMEM; + } + + /* setup vdev */ + tvdev->tctx = tctx; + tvdev->vdev.dev.parent = tctx->dev; + tvdev->vdev.id.device = vdev_descr->id; + tvdev->vdev.config = &trusty_virtio_config_ops; + tvdev->vdev_descr = vdev_descr; + tvdev->notifyid = vdev_descr->notifyid; + + /* setup config */ + tvdev->config = config; + tvdev->config_len = vdev_descr->config_len; + + /* setup vrings and vdev resource */ + tvdev->vring_num = vdev_descr->num_of_vrings; + + for (i = 0; i < tvdev->vring_num; i++, vr_descr++) { + struct trusty_vring *tvr = &tvdev->vrings[i]; + tvr->tvdev = tvdev; + tvr->vr_descr = vr_descr; + tvr->align = vr_descr->align; + tvr->elem_num = vr_descr->num; + tvr->notifyid = vr_descr->notifyid; + trusty_nop_init(&tvr->kick_nop, SMC_NC_VDEV_KICK_VQ, + tvdev->notifyid, tvr->notifyid); + } + + /* register device */ + ret = register_virtio_device(&tvdev->vdev); + if (ret) { + dev_err(tctx->dev, + "Failed (%d) to register device dev type %u\n", ret, + vdev_descr->id); + goto err_register; + } + + /* add it to tracking list */ + list_add_tail(&tvdev->node, &tctx->vdev_list); + + return 0; + +err_register: + kfree(tvdev); + return ret; +} + +static int trusty_parse_device_descr(struct trusty_ctx *tctx, void *descr_va, + size_t descr_sz) +{ + u32 i; + struct resource_table *descr = descr_va; + + if (descr_sz < sizeof(*descr)) { + dev_err(tctx->dev, "descr table is too small (0x%x)\n", + (int)descr_sz); + return -ENODEV; + } + + if (descr->ver != RSC_DESCR_VER) { + dev_err(tctx->dev, "unexpected descr ver (0x%x)\n", + (int)descr->ver); + return -ENODEV; + } + + if (descr_sz < (sizeof(*descr) + descr->num * sizeof(u32))) { + dev_err(tctx->dev, "descr table is too small (0x%x)\n", + (int)descr->ver); + return -ENODEV; + } + + for (i = 0; i < descr->num; i++) { + struct fw_rsc_hdr *hdr; + struct fw_rsc_vdev *vd; + struct fw_rsc_vdev_vring *vr; + void *cfg; + size_t vd_sz; + + u32 offset = descr->offset[i]; + + if (offset >= descr_sz) { + dev_err(tctx->dev, "offset is out of bounds (%u)\n", + (uint)offset); + return -ENODEV; + } + + /* check space for rsc header */ + if ((descr_sz - offset) < sizeof(struct fw_rsc_hdr)) { + dev_err(tctx->dev, "no space for rsc header (%u)\n", + (uint)offset); + return -ENODEV; + } + hdr = (struct fw_rsc_hdr *)((u8 *)descr + offset); + offset += sizeof(struct fw_rsc_hdr); + + /* check type */ + if (hdr->type != RSC_VDEV) { + dev_err(tctx->dev, "unsupported rsc type (%u)\n", + (uint)hdr->type); + continue; + } + + /* got vdev: check space for vdev */ + if ((descr_sz - offset) < sizeof(struct fw_rsc_vdev)) { + dev_err(tctx->dev, "no space for vdev descr (%u)\n", + (uint)offset); + return -ENODEV; + } + vd = (struct fw_rsc_vdev *)((u8 *)descr + offset); + + /* check space for vrings and config area */ + vd_sz = sizeof(struct fw_rsc_vdev) + + vd->num_of_vrings * sizeof(struct fw_rsc_vdev_vring) + + vd->config_len; + + if ((descr_sz - offset) < vd_sz) { + dev_err(tctx->dev, "no space for vdev (%u)\n", + (uint)offset); + return -ENODEV; + } + vr = (struct fw_rsc_vdev_vring *)vd->vring; + cfg = (void *)(vr + vd->num_of_vrings); + + trusty_virtio_add_device(tctx, vd, vr, cfg); + } + + return 0; +} + +static void _remove_devices_locked(struct trusty_ctx *tctx) +{ + struct trusty_vdev *tvdev, *next; + + list_for_each_entry_safe(tvdev, next, &tctx->vdev_list, node) { + list_del(&tvdev->node); + unregister_virtio_device(&tvdev->vdev); + kfree(tvdev); + } +} + +static void trusty_virtio_remove_devices(struct trusty_ctx *tctx) +{ + mutex_lock(&tctx->mlock); + _remove_devices_locked(tctx); + mutex_unlock(&tctx->mlock); +} + +static int trusty_virtio_add_devices(struct trusty_ctx *tctx) +{ + int ret; + void *descr_va; + size_t descr_sz; + size_t descr_buf_sz; + + /* allocate buffer to load device descriptor into */ + descr_buf_sz = PAGE_SIZE; + descr_va = trusty_shm_alloc(descr_buf_sz, GFP_KERNEL | __GFP_ZERO); + if (!descr_va) { + dev_err(tctx->dev, "Failed to allocate shared area\n"); + return -ENOMEM; + } + + /* load device descriptors */ + ret = trusty_load_device_descr(tctx, descr_va, descr_buf_sz); + if (ret < 0) { + dev_err(tctx->dev, "failed (%d) to load device descr\n", ret); + goto err_load_descr; + } + + descr_sz = (size_t)ret; + + mutex_lock(&tctx->mlock); + + /* parse device descriptor and add virtio devices */ + ret = trusty_parse_device_descr(tctx, descr_va, descr_sz); + if (ret) { + dev_err(tctx->dev, "failed (%d) to parse device descr\n", ret); + goto err_parse_descr; + } + + /* register call notifier */ + ret = trusty_call_notifier_register(tctx->dev->parent, + &tctx->call_notifier); + if (ret) { + dev_err(tctx->dev, "%s: failed (%d) to register notifier\n", + __func__, ret); + goto err_register_notifier; + } + + /* start virtio */ + ret = trusty_virtio_start(tctx, descr_va, descr_sz); + if (ret) { + dev_err(tctx->dev, "failed (%d) to start virtio\n", ret); + goto err_start_virtio; + } + + /* attach shared area */ + tctx->shared_va = descr_va; + tctx->shared_sz = descr_buf_sz; + + mutex_unlock(&tctx->mlock); + + return 0; + +err_start_virtio: + trusty_call_notifier_unregister(tctx->dev->parent, + &tctx->call_notifier); + cancel_work_sync(&tctx->check_vqs); +err_register_notifier: +err_parse_descr: + _remove_devices_locked(tctx); + mutex_unlock(&tctx->mlock); + cancel_work_sync(&tctx->kick_vqs); + trusty_virtio_stop(tctx, descr_va, descr_sz); +err_load_descr: + trusty_shm_free(descr_va, descr_buf_sz); + return ret; +} + +static int trusty_virtio_probe(struct platform_device *pdev) +{ + int ret; + struct trusty_ctx *tctx; + + dev_info(&pdev->dev, "initializing\n"); + + tctx = kzalloc(sizeof(*tctx), GFP_KERNEL); + if (!tctx) { + dev_err(&pdev->dev, "Failed to allocate context\n"); + return -ENOMEM; + } + + tctx->dev = &pdev->dev; + tctx->call_notifier.notifier_call = trusty_call_notify; + mutex_init(&tctx->mlock); + INIT_LIST_HEAD(&tctx->vdev_list); + INIT_WORK(&tctx->check_vqs, check_all_vqs); + INIT_WORK(&tctx->kick_vqs, kick_vqs); + platform_set_drvdata(pdev, tctx); + + tctx->check_wq = alloc_workqueue("trusty-check-wq", WQ_UNBOUND, 0); + if (!tctx->check_wq) { + ret = -ENODEV; + dev_err(&pdev->dev, "Failed create trusty-check-wq\n"); + goto err_create_check_wq; + } + + tctx->kick_wq = alloc_workqueue("trusty-kick-wq", + WQ_UNBOUND | WQ_CPU_INTENSIVE, 0); + if (!tctx->kick_wq) { + ret = -ENODEV; + dev_err(&pdev->dev, "Failed create trusty-kick-wq\n"); + goto err_create_kick_wq; + } + + ret = trusty_virtio_add_devices(tctx); + if (ret) { + dev_err(&pdev->dev, "Failed to add virtio devices\n"); + goto err_add_devices; + } + + dev_info(&pdev->dev, "initializing done\n"); + return 0; + +err_add_devices: + destroy_workqueue(tctx->kick_wq); +err_create_kick_wq: + destroy_workqueue(tctx->check_wq); +err_create_check_wq: + kfree(tctx); + return ret; +} + +static int trusty_virtio_remove(struct platform_device *pdev) +{ + struct trusty_ctx *tctx = platform_get_drvdata(pdev); + + dev_err(&pdev->dev, "removing\n"); + + /* unregister call notifier and wait until workqueue is done */ + trusty_call_notifier_unregister(tctx->dev->parent, + &tctx->call_notifier); + cancel_work_sync(&tctx->check_vqs); + + /* remove virtio devices */ + trusty_virtio_remove_devices(tctx); + cancel_work_sync(&tctx->kick_vqs); + + /* destroy workqueues */ + destroy_workqueue(tctx->kick_wq); + destroy_workqueue(tctx->check_wq); + + /* notify remote that shared area goes away */ + trusty_virtio_stop(tctx, tctx->shared_va, tctx->shared_sz); + + /* free shared area */ + trusty_shm_free(tctx->shared_va, tctx->shared_sz); + + /* free context */ + kfree(tctx); + return 0; +} + +static const struct of_device_id trusty_of_match[] = { + { + .compatible = "android,trusty-virtio-v1", + }, +}; + +MODULE_DEVICE_TABLE(of, trusty_of_match); + +static struct platform_driver trusty_virtio_driver = { + .probe = trusty_virtio_probe, + .remove = trusty_virtio_remove, + .driver = { + .name = "trusty-virtio", + .owner = THIS_MODULE, + .of_match_table = trusty_of_match, + }, +}; + +module_platform_driver(trusty_virtio_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Trusty virtio driver"); diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c new file mode 100644 index 000000000000..c690df2f263c --- /dev/null +++ b/drivers/trusty/trusty.c @@ -0,0 +1,662 @@ +/* + * Copyright 2018 GoldenRiver Technologies Co., Ltd. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * Copyright (C) 2013 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "trusty-link-shbuf.h" +#include "trusty-virq.h" + +struct trusty_state; + +struct trusty_work { + struct trusty_state *ts; + struct work_struct work; +}; + +struct trusty_state { + struct mutex smc_lock; + struct atomic_notifier_head notifier; + struct completion cpu_idle_completion; + char *version_str; + u32 api_version; + struct device *dev; + struct workqueue_struct *nop_wq; + struct trusty_work __percpu *nop_works; + struct list_head nop_queue; + spinlock_t nop_lock; /* protects nop_queue */ +}; + +struct trusty_state *tstate; + +#ifdef CONFIG_ARM64 +#define SMC_ARG0 "x0" +#define SMC_ARG1 "x1" +#define SMC_ARG2 "x2" +#define SMC_ARG3 "x3" +#define SMC_ARCH_EXTENSION "" +#define SMC_REGISTERS_TRASHED \ + "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", \ + "x15", "x16", "x17" +#else +#define SMC_ARG0 "r0" +#define SMC_ARG1 "r1" +#define SMC_ARG2 "r2" +#define SMC_ARG3 "r3" +#define SMC_ARCH_EXTENSION ".arch_extension sec\n" +#define SMC_REGISTERS_TRASHED "ip" +#endif + +static inline ulong smc(ulong r0, ulong r1, ulong r2, ulong r3) +{ + register ulong _r0 asm(SMC_ARG0) = r0; + register ulong _r1 asm(SMC_ARG1) = r1; + register ulong _r2 asm(SMC_ARG2) = r2; + register ulong _r3 asm(SMC_ARG3) = r3; + + asm volatile(__asmeq("%0", SMC_ARG0) __asmeq("%1", SMC_ARG1) __asmeq( + "%2", SMC_ARG2) __asmeq("%3", SMC_ARG3) + __asmeq("%4", SMC_ARG0) __asmeq("%5", SMC_ARG1) + __asmeq("%6", SMC_ARG2) + __asmeq("%7", SMC_ARG3) + SMC_ARCH_EXTENSION + "smc #0" /* switch to secure world */ + : "=r"(_r0), "=r"(_r1), "=r"(_r2), "=r"(_r3) + : "r"(_r0), "r"(_r1), "r"(_r2), "r"(_r3) + : SMC_REGISTERS_TRASHED); + return _r0; +} + +s32 trusty_fast_call32(struct device *dev, u32 smcnr, u32 a0, u32 a1, u32 a2) +{ + struct trusty_state *s = platform_get_drvdata(to_platform_device(dev)); + + BUG_ON(!s); + BUG_ON(!SMC_IS_FASTCALL(smcnr)); + BUG_ON(SMC_IS_SMC64(smcnr)); + + if (trusty_get_link_shbuf_device(0)) + return trusty_link_shbuf_smc(0, smcnr, a0, a1, a2); + + return smc(smcnr, a0, a1, a2); +} +EXPORT_SYMBOL(trusty_fast_call32); + +#ifdef CONFIG_64BIT +s64 trusty_fast_call64(struct device *dev, u64 smcnr, u64 a0, u64 a1, u64 a2) +{ + struct trusty_state *s = platform_get_drvdata(to_platform_device(dev)); + + BUG_ON(!s); + BUG_ON(!SMC_IS_FASTCALL(smcnr)); + BUG_ON(!SMC_IS_SMC64(smcnr)); + + return smc(smcnr, a0, a1, a2); +} +#endif + +static ulong trusty_std_call_inner(struct device *dev, ulong smcnr, ulong a0, + ulong a1, ulong a2) +{ + ulong ret; + int retry = 5; + + dev_dbg(dev, "%s(0x%lx 0x%lx 0x%lx 0x%lx)\n", __func__, smcnr, a0, a1, + a2); + while (true) { + ret = smc(smcnr, a0, a1, a2); + while ((s32)ret == SM_ERR_FIQ_INTERRUPTED) + ret = smc(SMC_SC_RESTART_FIQ, 0, 0, 0); + if ((int)ret != SM_ERR_BUSY || !retry) + break; + + dev_dbg(dev, + "%s(0x%lx 0x%lx 0x%lx 0x%lx) returned busy, retry\n", + __func__, smcnr, a0, a1, a2); + retry--; + } + + return ret; +} + +static ulong trusty_std_call_helper(struct device *dev, ulong smcnr, ulong a0, + ulong a1, ulong a2) +{ + ulong ret; + int sleep_time = 1; + struct trusty_state *s = platform_get_drvdata(to_platform_device(dev)); + + while (true) { + local_irq_disable(); + atomic_notifier_call_chain(&s->notifier, TRUSTY_CALL_PREPARE, + NULL); + ret = trusty_std_call_inner(dev, smcnr, a0, a1, a2); + atomic_notifier_call_chain(&s->notifier, TRUSTY_CALL_RETURNED, + NULL); + local_irq_enable(); + + if ((int)ret != SM_ERR_BUSY) + break; + + if (sleep_time == 256) + dev_warn(dev, + "%s(0x%lx 0x%lx 0x%lx 0x%lx) returned busy\n", + __func__, smcnr, a0, a1, a2); + dev_dbg(dev, + "%s(0x%lx 0x%lx 0x%lx 0x%lx) returned busy, wait %d ms\n", + __func__, smcnr, a0, a1, a2, sleep_time); + + msleep(sleep_time); + if (sleep_time < 1000) + sleep_time <<= 1; + + dev_dbg(dev, "%s(0x%lx 0x%lx 0x%lx 0x%lx) retry\n", __func__, + smcnr, a0, a1, a2); + } + + if (sleep_time > 256) + dev_warn(dev, "%s(0x%lx 0x%lx 0x%lx 0x%lx) busy cleared\n", + __func__, smcnr, a0, a1, a2); + + return ret; +} + +static void trusty_std_call_cpu_idle(struct trusty_state *s) +{ + int ret; + + ret = wait_for_completion_timeout(&s->cpu_idle_completion, HZ * 10); + if (!ret) { + pr_warn("%s: timed out waiting for cpu idle to clear, retry anyway\n", + __func__); + } +} + +s32 trusty_std_call32(struct device *dev, u32 smcnr, u32 a0, u32 a1, u32 a2) +{ + int ret; + struct trusty_state *s = platform_get_drvdata(to_platform_device(dev)); + + BUG_ON(SMC_IS_FASTCALL(smcnr)); + BUG_ON(SMC_IS_SMC64(smcnr)); + + if (trusty_get_link_shbuf_device(0)) { + ret = trusty_link_shbuf_smc(0, smcnr, a0, a1, a2); + atomic_notifier_call_chain(&s->notifier, TRUSTY_CALL_RETURNED, + NULL); + return ret; + } + + if (smcnr != SMC_SC_NOP) { + mutex_lock(&s->smc_lock); + reinit_completion(&s->cpu_idle_completion); + } + + dev_dbg(dev, "%s(0x%x 0x%x 0x%x 0x%x) started\n", __func__, smcnr, a0, + a1, a2); + + ret = trusty_std_call_helper(dev, smcnr, a0, a1, a2); + while (ret == SM_ERR_INTERRUPTED || ret == SM_ERR_CPU_IDLE) { + dev_dbg(dev, "%s(0x%x 0x%x 0x%x 0x%x) interrupted\n", __func__, + smcnr, a0, a1, a2); + if (ret == SM_ERR_CPU_IDLE) + trusty_std_call_cpu_idle(s); + ret = trusty_std_call_helper(dev, SMC_SC_RESTART_LAST, 0, 0, 0); + } + dev_dbg(dev, "%s(0x%x 0x%x 0x%x 0x%x) returned 0x%x\n", __func__, smcnr, + a0, a1, a2, ret); + + WARN_ONCE(ret == SM_ERR_PANIC, "trusty crashed"); + + if (smcnr == SMC_SC_NOP) + complete(&s->cpu_idle_completion); + else + mutex_unlock(&s->smc_lock); + + return ret; +} +EXPORT_SYMBOL(trusty_std_call32); + +int trusty_call_notifier_register(struct device *dev, struct notifier_block *n) +{ + struct trusty_state *s = platform_get_drvdata(to_platform_device(dev)); + + return atomic_notifier_chain_register(&s->notifier, n); +} +EXPORT_SYMBOL(trusty_call_notifier_register); + +int trusty_call_notifier_unregister(struct device *dev, + struct notifier_block *n) +{ + struct trusty_state *s = platform_get_drvdata(to_platform_device(dev)); + + return atomic_notifier_chain_unregister(&s->notifier, n); +} +EXPORT_SYMBOL(trusty_call_notifier_unregister); + +static int trusty_remove_child(struct device *dev, void *data) +{ + platform_device_unregister(to_platform_device(dev)); + return 0; +} + +ssize_t trusty_version_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct trusty_state *s = platform_get_drvdata(to_platform_device(dev)); + + return scnprintf(buf, PAGE_SIZE, "%s\n", s->version_str); +} + +DEVICE_ATTR(trusty_version, S_IRUSR, trusty_version_show, NULL); + +const char *trusty_version_str_get(struct device *dev) +{ + struct trusty_state *s = platform_get_drvdata(to_platform_device(dev)); + + return s->version_str; +} +EXPORT_SYMBOL(trusty_version_str_get); + +static void trusty_init_version(struct trusty_state *s, struct device *dev) +{ + int ret; + int i; + int version_str_len; + + ret = trusty_fast_call32(dev, SMC_FC_GET_VERSION_STR, -1, 0, 0); + if (ret <= 0) + goto err_get_size; + + version_str_len = ret; + + s->version_str = kmalloc(version_str_len + 1, GFP_KERNEL); + for (i = 0; i < version_str_len; i++) { + ret = trusty_fast_call32(dev, SMC_FC_GET_VERSION_STR, i, 0, 0); + if (ret < 0) + goto err_get_char; + s->version_str[i] = ret; + } + s->version_str[i] = '\0'; + + dev_info(dev, "trusty version: %s\n", s->version_str); + + ret = device_create_file(dev, &dev_attr_trusty_version); + if (ret) + goto err_create_file; + return; + +err_create_file: +err_get_char: + kfree(s->version_str); + s->version_str = NULL; +err_get_size: + dev_err(dev, "failed to get version: %d\n", ret); +} + +u32 trusty_get_api_version(struct device *dev) +{ + struct trusty_state *s = platform_get_drvdata(to_platform_device(dev)); + + return s->api_version; +} +EXPORT_SYMBOL(trusty_get_api_version); + +static int trusty_init_api_version(struct trusty_state *s, struct device *dev) +{ + u32 api_version; + api_version = trusty_fast_call32(dev, SMC_FC_API_VERSION, + TRUSTY_API_VERSION_CURRENT, 0, 0); + if (api_version == SM_ERR_UNDEFINED_SMC) + api_version = 0; + + if (api_version > TRUSTY_API_VERSION_CURRENT) { + dev_err(dev, "unsupported api version %u > %u\n", api_version, + TRUSTY_API_VERSION_CURRENT); + return -EINVAL; + } + + dev_info(dev, "selected api version: %u (requested %u)\n", api_version, + TRUSTY_API_VERSION_CURRENT); + s->api_version = api_version; + + return 0; +} + +static bool dequeue_nop(struct trusty_state *s, u32 *args) +{ + unsigned long flags; + struct trusty_nop *nop = NULL; + + spin_lock_irqsave(&s->nop_lock, flags); + if (!list_empty(&s->nop_queue)) { + nop = list_first_entry(&s->nop_queue, struct trusty_nop, node); + list_del_init(&nop->node); + args[0] = nop->args[0]; + args[1] = nop->args[1]; + args[2] = nop->args[2]; + } else { + args[0] = 0; + args[1] = 0; + args[2] = 0; + } + spin_unlock_irqrestore(&s->nop_lock, flags); + return nop; +} + +static void locked_nop_work_func(struct work_struct *work) +{ + int ret; + struct trusty_work *tw = container_of(work, struct trusty_work, work); + struct trusty_state *s = tw->ts; + + dev_dbg(s->dev, "%s\n", __func__); + + ret = trusty_std_call32(s->dev, SMC_SC_LOCKED_NOP, 0, 0, 0); + if (ret != 0) + dev_err(s->dev, "%s: SMC_SC_LOCKED_NOP failed %d", __func__, + ret); + + dev_dbg(s->dev, "%s: done\n", __func__); +} + +static void nop_work_func(struct work_struct *work) +{ + int ret; + bool next; + u32 args[3]; + struct trusty_work *tw = container_of(work, struct trusty_work, work); + struct trusty_state *s = tw->ts; + + dev_dbg(s->dev, "%s:\n", __func__); + + dequeue_nop(s, args); + do { + dev_dbg(s->dev, "%s: %x %x %x\n", __func__, args[0], args[1], + args[2]); + + ret = trusty_std_call32(s->dev, SMC_SC_NOP, args[0], args[1], + args[2]); + + next = dequeue_nop(s, args); + + if (ret == SM_ERR_NOP_INTERRUPTED) + next = true; + else if (ret != SM_ERR_NOP_DONE) + dev_err(s->dev, "%s: SMC_SC_NOP failed %d", __func__, + ret); + } while (next); + + dev_dbg(s->dev, "%s: done\n", __func__); +} + +void trusty_enqueue_nop(struct device *dev, struct trusty_nop *nop) +{ + unsigned long flags; + struct trusty_work *tw; + struct trusty_state *s = platform_get_drvdata(to_platform_device(dev)); + + preempt_disable(); + tw = this_cpu_ptr(s->nop_works); + if (nop) { + WARN_ON(s->api_version < TRUSTY_API_VERSION_SMP_NOP); + + spin_lock_irqsave(&s->nop_lock, flags); + if (list_empty(&nop->node)) + list_add_tail(&nop->node, &s->nop_queue); + spin_unlock_irqrestore(&s->nop_lock, flags); + } + queue_work(s->nop_wq, &tw->work); + preempt_enable(); +} +EXPORT_SYMBOL(trusty_enqueue_nop); + +void trusty_dequeue_nop(struct device *dev, struct trusty_nop *nop) +{ + unsigned long flags; + struct trusty_state *s = platform_get_drvdata(to_platform_device(dev)); + + if (WARN_ON(!nop)) + return; + + spin_lock_irqsave(&s->nop_lock, flags); + if (!list_empty(&nop->node)) + list_del_init(&nop->node); + spin_unlock_irqrestore(&s->nop_lock, flags); +} +EXPORT_SYMBOL(trusty_dequeue_nop); + +static struct platform_device *gpdev; +static struct workqueue_struct *late_init_wq; +static struct work_struct late_init_work; +static struct workqueue_struct *notif_call_wq; +static struct work_struct notif_call_work; + +void trusty_probe_late(void) +{ + queue_work(late_init_wq, &late_init_work); +} + +void trusty_notifier_call(void) +{ + queue_work(notif_call_wq, ¬if_call_work); +} + +static void notif_call_work_func(struct work_struct *work) +{ + atomic_notifier_call_chain(&tstate->notifier, TRUSTY_CALL_RETURNED, + NULL); +} + +static void late_init_work_func(struct work_struct *work) +{ + int ret; + unsigned int cpu; + work_func_t work_func; + struct trusty_state *s; + struct platform_device *pdev = gpdev; + + s = kzalloc(sizeof(*s), GFP_KERNEL); + if (!s) { + ret = -ENOMEM; + goto err_allocate_state; + } + + s->dev = &pdev->dev; + spin_lock_init(&s->nop_lock); + INIT_LIST_HEAD(&s->nop_queue); + mutex_init(&s->smc_lock); + ATOMIC_INIT_NOTIFIER_HEAD(&s->notifier); + init_completion(&s->cpu_idle_completion); + platform_set_drvdata(pdev, s); + + if (trusty_get_link_shbuf_device(0)) + dev_info(&pdev->dev, "using shbuf smc ...\n"); + else + dev_info(&pdev->dev, "using default smc ...\n"); + + trusty_init_version(s, &pdev->dev); + + ret = trusty_init_api_version(s, &pdev->dev); + if (ret < 0) + goto err_api_version; + + ret = trusty_shm_init_pool(&pdev->dev); + if (ret < 0) + goto err_shm_init_pool; + + s->nop_wq = alloc_workqueue("trusty-nop-wq", WQ_CPU_INTENSIVE, 0); + if (!s->nop_wq) { + ret = -ENODEV; + dev_err(&pdev->dev, "Failed create trusty-nop-wq\n"); + goto err_create_nop_wq; + } + + s->nop_works = alloc_percpu(struct trusty_work); + if (!s->nop_works) { + ret = -ENOMEM; + dev_err(&pdev->dev, "Failed to allocate works\n"); + goto err_alloc_works; + } + + if (s->api_version < TRUSTY_API_VERSION_SMP) + work_func = locked_nop_work_func; + else + work_func = nop_work_func; + + for_each_possible_cpu(cpu) { + struct trusty_work *tw = per_cpu_ptr(s->nop_works, cpu); + + tw->ts = s; + INIT_WORK(&tw->work, work_func); + } + + tstate = s; + + ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to add children: %d\n", ret); + goto err_add_children; + } + + dev_info(&pdev->dev, "%s: done\n", __func__); + + return; + +err_add_children: + for_each_possible_cpu(cpu) { + struct trusty_work *tw = per_cpu_ptr(s->nop_works, cpu); + + flush_work(&tw->work); + } + free_percpu(s->nop_works); +err_alloc_works: + destroy_workqueue(s->nop_wq); +err_create_nop_wq: + trusty_shm_destroy_pool(&pdev->dev); +err_shm_init_pool: +err_api_version: + if (s->version_str) { + device_remove_file(&pdev->dev, &dev_attr_trusty_version); + kfree(s->version_str); + } + device_for_each_child(&pdev->dev, NULL, trusty_remove_child); + mutex_destroy(&s->smc_lock); + kfree(s); +err_allocate_state: + return; +} + +static int trusty_probe_early(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + + if (!node) { + dev_err(&pdev->dev, "of_node required\n"); + return -EINVAL; + } + + gpdev = pdev; + + late_init_wq = alloc_workqueue("trusty-late-init-wq", WQ_UNBOUND, 0); + if (!late_init_wq) { + dev_err(&pdev->dev, "Failed create trusty-late-init-wq\n"); + return -ENODEV; + } + INIT_WORK(&late_init_work, late_init_work_func); + + notif_call_wq = alloc_workqueue("trusty-notif-call-wq", WQ_UNBOUND, 0); + if (!notif_call_wq) { + destroy_workqueue(late_init_wq); + dev_err(&pdev->dev, "Failed create trusty-notif-call-wq\n"); + return -ENODEV; + } + INIT_WORK(¬if_call_work, notif_call_work_func); + + dev_info(&pdev->dev, "%s: done\n", __func__); + + if (!trusty_get_link_shbuf_device(0)) + late_init_work_func(&late_init_work); + + return 0; +} + +static int trusty_remove(struct platform_device *pdev) +{ + unsigned int cpu; + struct trusty_state *s = platform_get_drvdata(pdev); + + device_for_each_child(&pdev->dev, NULL, trusty_remove_child); + + for_each_possible_cpu(cpu) { + struct trusty_work *tw = per_cpu_ptr(s->nop_works, cpu); + + flush_work(&tw->work); + } + free_percpu(s->nop_works); + destroy_workqueue(s->nop_wq); + + trusty_shm_destroy_pool(&pdev->dev); + + mutex_destroy(&s->smc_lock); + if (s->version_str) { + device_remove_file(&pdev->dev, &dev_attr_trusty_version); + kfree(s->version_str); + } + kfree(s); + return 0; +} + +static const struct of_device_id trusty_of_match[] = { + { + .compatible = "android,trusty-smc-v1", + }, + {}, +}; + +static struct platform_driver trusty_driver = { + .probe = trusty_probe_early, + .remove = trusty_remove, + .driver = { + .name = "trusty", + .owner = THIS_MODULE, + .of_match_table = trusty_of_match, + }, +}; + +static int __init trusty_driver_init(void) +{ + return platform_driver_register(&trusty_driver); +} + +static void __exit trusty_driver_exit(void) +{ + platform_driver_unregister(&trusty_driver); +} + +subsys_initcall(trusty_driver_init); +module_exit(trusty_driver_exit); diff --git a/include/linux/trusty/hvcall.h b/include/linux/trusty/hvcall.h new file mode 100644 index 000000000000..91576f02e31e --- /dev/null +++ b/include/linux/trusty/hvcall.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2018 GoldenRiver Technology Co., Ltd. All rights reserved + * Copyright (C) 2021 XiaoMi, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Copyright (c) 2013-2014 Google Inc. All rights reserved + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __HV_CALL_H__ +#define __HV_CALL_H__ + +/* To prevent redefined with smcall.h */ +#ifndef SMC_NUM_ENTITIES +#define SMC_NUM_ENTITIES 64 +#define SMC_NUM_ARGS 4 +#define SMC_NUM_PARAMS (SMC_NUM_ARGS - 1) + +#define SMC_IS_FASTCALL(smc_nr) ((smc_nr) & 0x80000000) +#define SMC_IS_SMC64(smc_nr) ((smc_nr) & 0x40000000) +#define SMC_ENTITY(smc_nr) (((smc_nr) & 0x3F000000) >> 24) +#define SMC_FUNCTION(smc_nr) ((smc_nr) & 0x0000FFFF) + +#define SMC_NR(_entity, _fn, _fastcall, _smc64) \ + ((((_fastcall) & 0x1) << 31) | (((_smc64) & 0x1) << 30) | \ + (((_entity) & 0x3F) << 24) | ((_fn) & 0xFFFF)) + +#define SMC_FASTCALL_NR(entity, fn) SMC_NR((entity), (fn), 1, 0) +#define SMC_STDCALL_NR(entity, fn) SMC_NR((entity), (fn), 0, 0) +#define SMC_FASTCALL64_NR(entity, fn) SMC_NR((entity), (fn), 1, 1) +#define SMC_STDCALL64_NR(entity, fn) SMC_NR((entity), (fn), 0, 1) +#endif /* end of SMC_NUM_ENTITIES */ + +#define SMC_ENTITY_VM 52 /* VMM SMC Calls */ +#define SMC_ENTITY_PLAT 53 /* PLATFORM SMC Calls */ + +/****************************************************/ +/********** VMM Specific SMC Calls ******************/ +/****************************************************/ +#define SMC_FC_VM_INIT_DONE SMC_FASTCALL_NR(SMC_ENTITY_VM, 100) +#define SMC_FC_VM_STDCALL_SWITCH SMC_FASTCALL_NR(SMC_ENTITY_VM, 101) +#define SMC_FC_CPU_HOTPLUG_ON SMC_FASTCALL_NR(SMC_ENTITY_VM, 110) +#define SMC_FC_CPU_HOTPLUG_OFF SMC_FASTCALL_NR(SMC_ENTITY_VM, 111) +#define SMC_FC_KERNEL_SUSPEND_OFF SMC_FASTCALL_NR(SMC_ENTITY_VM, 112) +#define SMC_FC_KERNEL_SUSPEND_ON SMC_FASTCALL_NR(SMC_ENTITY_VM, 113) +#define SMC_FC_VM_TEST_ADD SMC_FASTCALL_NR(SMC_ENTITY_VM, 200) +#define SMC_FC_VM_TEST_MULTIPLY SMC_FASTCALL_NR(SMC_ENTITY_VM, 201) + +#define SMC_SC_VM_SMC_RETURN SMC_STDCALL_NR(SMC_ENTITY_VM, 100) +#define SMC_SC_VM_STDCALL_DONE SMC_STDCALL_NR(SMC_ENTITY_VM, 101) +#define SMC_SC_VM_SHARED_LOG_VERSION SMC_STDCALL_NR(SMC_ENTITY_VM, 110) +#define SMC_SC_VM_SHARED_LOG_ADD SMC_STDCALL_NR(SMC_ENTITY_VM, 111) +#define SMC_SC_VM_SHARED_LOG_RM SMC_STDCALL_NR(SMC_ENTITY_VM, 112) +#define SMC_SC_VM_NOP SMC_STDCALL_NR(SMC_ENTITY_VM, 120) +#define SMC_SC_VM_NOP_LOCKED SMC_STDCALL_NR(SMC_ENTITY_VM, 121) +#define SMC_SC_VM_RESTART_LAST SMC_STDCALL_NR(SMC_ENTITY_VM, 122) +#define SMC_SC_VM_VIRTIO_GET_DESCR SMC_STDCALL_NR(SMC_ENTITY_VM, 130) +#define SMC_SC_VM_VIRTIO_START SMC_STDCALL_NR(SMC_ENTITY_VM, 131) +#define SMC_SC_VM_VIRTIO_STOP SMC_STDCALL_NR(SMC_ENTITY_VM, 132) +#define SMC_SC_VM_VDEV_RESET SMC_STDCALL_NR(SMC_ENTITY_VM, 133) +#define SMC_SC_VM_VDEV_KICK_VQ SMC_STDCALL_NR(SMC_ENTITY_VM, 134) +#define SMC_SC_VM_TEST_ADD SMC_STDCALL_NR(SMC_ENTITY_VM, 200) +#define SMC_SC_VM_TEST_MULTIPLY SMC_STDCALL_NR(SMC_ENTITY_VM, 201) + +/****************************************************/ +/********** PLATFORM Specific SMC Calls *************/ +/****************************************************/ +#define SMC_FC_PLAT_GET_UART_PA SMC_FASTCALL_NR(SMC_ENTITY_PLAT, 100) +#define SMC_FC_PLAT_REGISTER_IRQ SMC_FASTCALL_NR(SMC_ENTITY_PLAT, 101) +#define SMC_FC_PLAT_GET_NEXT_IRQ SMC_FASTCALL_NR(SMC_ENTITY_PLAT, 102) +#define SMC_FC_PLAT_GET_GIC_VERSION SMC_FASTCALL_NR(SMC_ENTITY_PLAT, 103) +#define SMC_FC_PLAT_GET_GICD_PA SMC_FASTCALL_NR(SMC_ENTITY_PLAT, 104) +#define SMC_FC_PLAT_GET_GICR_PA SMC_FASTCALL_NR(SMC_ENTITY_PLAT, 105) +#define SMC_FC_PLAT_REGISTER_BOOT_ENTRY SMC_FASTCALL_NR(SMC_ENTITY_PLAT, 106) +#define SMC_FC_PLAT_GET_RPMB_KEY SMC_FASTCALL_NR(SMC_ENTITY_PLAT, 107) + +#define SMC_SC_GZ_SHARED_LOG_VERSION SMC_STDCALL_NR(SMC_ENTITY_PLAT, 100) +#define SMC_SC_GZ_SHARED_LOG_ADD SMC_STDCALL_NR(SMC_ENTITY_PLAT, 101) +#define SMC_SC_GZ_SHARED_LOG_RM SMC_STDCALL_NR(SMC_ENTITY_PLAT, 102) +#define SMC_SC_GZ_NOP SMC_STDCALL_NR(SMC_ENTITY_PLAT, 110) +#define SMC_SC_GZ_NOP_LOCKED SMC_STDCALL_NR(SMC_ENTITY_PLAT, 111) +#define SMC_SC_GZ_RESTART_LAST SMC_STDCALL_NR(SMC_ENTITY_PLAT, 112) +#define SMC_SC_PLAT_TEST_MULTIPLY SMC_STDCALL_NR(SMC_ENTITY_PLAT, 115) +#define SMC_SC_PLAT_INIT_SHARE_MEMORY SMC_STDCALL_NR(SMC_ENTITY_PLAT, 120) +#define SMC_SC_PLAT_MTEE_SERVICE_CMD SMC_STDCALL_NR(SMC_ENTITY_PLAT, 121) +#define SMC_SC_GZ_VIRTIO_GET_DESCR SMC_STDCALL_NR(SMC_ENTITY_PLAT, 130) +#define SMC_SC_GZ_VIRTIO_START SMC_STDCALL_NR(SMC_ENTITY_PLAT, 131) +#define SMC_SC_GZ_VIRTIO_STOP SMC_STDCALL_NR(SMC_ENTITY_PLAT, 132) +#define SMC_SC_GZ_VDEV_RESET SMC_STDCALL_NR(SMC_ENTITY_PLAT, 133) +#define SMC_SC_GZ_VDEV_KICK_VQ SMC_STDCALL_NR(SMC_ENTITY_PLAT, 134) + +#endif /* __HV_CALL_H__ */ diff --git a/include/linux/trusty/sm_err.h b/include/linux/trusty/sm_err.h new file mode 100644 index 000000000000..1c096175ccf3 --- /dev/null +++ b/include/linux/trusty/sm_err.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 Google Inc. All rights reserved + * Copyright (C) 2021 XiaoMi, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef __LINUX_TRUSTY_SM_ERR_H +#define __LINUX_TRUSTY_SM_ERR_H + +/* Errors from the secure monitor */ +#define SM_ERR_UNDEFINED_SMC \ + 0xFFFFFFFF /* Unknown SMC (defined by ARM DEN 0028A(0.9.0) */ +#define SM_ERR_INVALID_PARAMETERS -2 +#define SM_ERR_INTERRUPTED -3 /* Got interrupted. Call back with restart SMC */ +#define SM_ERR_UNEXPECTED_RESTART \ + -4 /* Got an restart SMC when we didn't expect it */ +#define SM_ERR_BUSY -5 /* Temporarily busy. Call back with original args */ +#define SM_ERR_INTERLEAVED_SMC \ + -6 /* Got a trusted_service SMC when a restart SMC is required */ +#define SM_ERR_INTERNAL_FAILURE -7 /* Unknown error */ +#define SM_ERR_NOT_SUPPORTED -8 +#define SM_ERR_NOT_ALLOWED -9 /* SMC call not allowed */ +#define SM_ERR_END_OF_INPUT -10 +#define SM_ERR_PANIC -11 /* Secure OS crashed */ +#define SM_ERR_FIQ_INTERRUPTED \ + -12 /* Got interrupted by FIQ. Call back with SMC_SC_RESTART_FIQ on same CPU */ +#define SM_ERR_CPU_IDLE -13 /* SMC call waiting for another CPU */ +#define SM_ERR_NOP_INTERRUPTED \ + -14 /* Got interrupted. Call back with new SMC_SC_NOP */ +#define SM_ERR_NOP_DONE -15 /* Cpu idle after SMC_SC_NOP (not an error) */ + +#endif diff --git a/include/linux/trusty/smcall.h b/include/linux/trusty/smcall.h new file mode 100644 index 000000000000..37aa533177b3 --- /dev/null +++ b/include/linux/trusty/smcall.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2018 GoldenRiver Technology Co., Ltd. All rights reserved + * Copyright (C) 2021 XiaoMi, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Copyright (c) 2013-2014 Google Inc. All rights reserved + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __LINUX_TRUSTY_SMCALL_H +#define __LINUX_TRUSTY_SMCALL_H + +#define SMC_NUM_ENTITIES 64 +#define SMC_NUM_ARGS 4 +#define SMC_NUM_PARAMS (SMC_NUM_ARGS - 1) + +#define SMC_IS_FASTCALL(smc_nr) ((smc_nr) & 0x80000000) +#define SMC_IS_SMC64(smc_nr) ((smc_nr) & 0x40000000) +#define SMC_ENTITY(smc_nr) (((smc_nr) & 0x3F000000) >> 24) +#define SMC_FUNCTION(smc_nr) ((smc_nr) & 0x0000FFFF) + +#define SMC_NR(_entity, _fn, _fastcall, _smc64) \ + ((((_fastcall) & 0x1) << 31) | (((_smc64) & 0x1) << 30) | \ + (((_entity) & 0x3F) << 24) | ((_fn) & 0xFFFF)) + +#define SMC_FASTCALL_NR(entity, fn) SMC_NR((entity), (fn), 1, 0) +#define SMC_STDCALL_NR(entity, fn) SMC_NR((entity), (fn), 0, 0) +#define SMC_FASTCALL64_NR(entity, fn) SMC_NR((entity), (fn), 1, 1) +#define SMC_STDCALL64_NR(entity, fn) SMC_NR((entity), (fn), 0, 1) + +#include "hvcall.h" + +#define SMC_ENTITY_ARCH 0 /* ARM Architecture calls */ +#define SMC_ENTITY_CPU 1 /* CPU Service calls */ +#define SMC_ENTITY_SIP 2 /* SIP Service calls */ +#define SMC_ENTITY_OEM 3 /* OEM Service calls */ +#define SMC_ENTITY_STD 4 /* Standard Service calls */ +#define SMC_ENTITY_RESERVED 5 /* Reserved for future use */ +#define SMC_ENTITY_TRUSTED_APP 48 /* Trusted Application calls */ +#define SMC_ENTITY_TRUSTED_OS SMC_ENTITY_VM /* Trusted OS calls */ +#define SMC_ENTITY_LOGGING \ + SMC_ENTITY_VM /* Used for secure -> nonsecure logging */ +#define SMC_ENTITY_SECURE_MONITOR \ + SMC_ENTITY_VM /* Trusted OS calls internal to secure monitor */ + +/****************************************************/ +/********** Secure Monitor SMC Calls ****************/ +/****************************************************/ +/* Standard call */ +#define SMC_SC_RESTART_LAST SMC_SC_VM_RESTART_LAST +#define SMC_SC_LOCKED_NOP SMC_SC_VM_NOP_LOCKED +#define SMC_SC_RESTART_FIQ SMC_STDCALL_NR(SMC_ENTITY_SECURE_MONITOR, 123) +#define SMC_SC_NOP SMC_SC_VM_NOP +#define SMC_SC_NS_RETURN SMC_SC_VM_SMC_RETURN +/* Fast call */ +#define SMC_FC_RESERVED SMC_FASTCALL_NR(SMC_ENTITY_SECURE_MONITOR, 0) +#define SMC_FC_FIQ_EXIT SMC_FASTCALL_NR(SMC_ENTITY_SECURE_MONITOR, 1) +#define SMC_FC_REQUEST_FIQ SMC_FASTCALL_NR(SMC_ENTITY_SECURE_MONITOR, 2) +#define SMC_FC_GET_NEXT_IRQ SMC_FASTCALL_NR(SMC_ENTITY_SECURE_MONITOR, 3) +#define SMC_FC_FIQ_ENTER SMC_FASTCALL_NR(SMC_ENTITY_SECURE_MONITOR, 4) +#define SMC_FC64_SET_FIQ_HANDLER SMC_FASTCALL64_NR(SMC_ENTITY_SECURE_MONITOR, 5) +#define SMC_FC64_GET_FIQ_REGS SMC_FASTCALL64_NR(SMC_ENTITY_SECURE_MONITOR, 6) +#define SMC_FC_CPU_SUSPEND SMC_FASTCALL_NR(SMC_ENTITY_SECURE_MONITOR, 7) +#define SMC_FC_CPU_RESUME SMC_FASTCALL_NR(SMC_ENTITY_SECURE_MONITOR, 8) +#define SMC_FC_AARCH_SWITCH SMC_FASTCALL_NR(SMC_ENTITY_SECURE_MONITOR, 9) +#define SMC_FC_GET_VERSION_STR SMC_FASTCALL_NR(SMC_ENTITY_SECURE_MONITOR, 10) +#define SMC_FC_API_VERSION SMC_FASTCALL_NR(SMC_ENTITY_SECURE_MONITOR, 11) +#define SMC_FC_FIQ_RESUME SMC_FASTCALL_NR(SMC_ENTITY_SECURE_MONITOR, 12) +#define SMC_FC_IOREMAP_PA_INFO SMC_FASTCALL_NR(SMC_ENTITY_SECURE_MONITOR, 13) + +/****************************************************/ +/********** Trusted OS SMC Calls ********************/ +/****************************************************/ +/* Standard call */ +#define SMC_SC_VIRTIO_GET_DESCR SMC_SC_VM_VIRTIO_GET_DESCR +#define SMC_SC_VIRTIO_START SMC_SC_VM_VIRTIO_START +#define SMC_SC_VIRTIO_STOP SMC_SC_VM_VIRTIO_STOP +#define SMC_SC_VDEV_RESET SMC_SC_VM_VDEV_RESET +#define SMC_SC_VDEV_KICK_VQ SMC_SC_VM_VDEV_KICK_VQ +#define SMC_NC_VDEV_KICK_VQ SMC_STDCALL_NR(SMC_ENTITY_TRUSTED_OS, 135) +#define SMC_SC_CREATE_QL_TIPC_DEV SMC_STDCALL_NR(SMC_ENTITY_TRUSTED_OS, 136) +#define SMC_SC_SHUTDOWN_QL_TIPC_DEV SMC_STDCALL_NR(SMC_ENTITY_TRUSTED_OS, 137) +#define SMC_SC_HANDLE_QL_TIPC_DEV_CMD SMC_STDCALL_NR(SMC_ENTITY_TRUSTED_OS, 138) + +/****************************************************/ +/********** Logging SMC Calls ***********************/ +/****************************************************/ +/* Standard call */ +#define SMC_SC_SHARED_LOG_VERSION SMC_SC_VM_SHARED_LOG_VERSION +#define SMC_SC_SHARED_LOG_ADD SMC_SC_VM_SHARED_LOG_ADD +#define SMC_SC_SHARED_LOG_RM SMC_SC_VM_SHARED_LOG_RM + +#define TRUSTY_API_VERSION_RESTART_FIQ (1) +#define TRUSTY_API_VERSION_SMP (2) +#define TRUSTY_API_VERSION_SMP_NOP (3) +#define TRUSTY_API_VERSION_CURRENT (3) + +#endif /* __LINUX_TRUSTY_SMCALL_H */ diff --git a/include/linux/trusty/trusty.h b/include/linux/trusty/trusty.h new file mode 100644 index 000000000000..749f23d5a326 --- /dev/null +++ b/include/linux/trusty/trusty.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2013 Google, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 __LINUX_TRUSTY_TRUSTY_H +#define __LINUX_TRUSTY_TRUSTY_H + +#include +#include +#include +#include + +#define TRUSTY_PROBE_DEFER (0x44425054) + +#ifdef CONFIG_TRUSTY +void trusty_probe_late(void); +void trusty_notifier_call(void); +s32 trusty_std_call32(struct device *dev, u32 smcnr, u32 a0, u32 a1, u32 a2); +s32 trusty_fast_call32(struct device *dev, u32 smcnr, u32 a0, u32 a1, u32 a2); +#ifdef CONFIG_64BIT +s64 trusty_fast_call64(struct device *dev, u64 smcnr, u64 a0, u64 a1, u64 a2); +#endif +#else +static inline s32 trusty_std_call32(struct device *dev, u32 smcnr, u32 a0, + u32 a1, u32 a2) +{ + return SM_ERR_UNDEFINED_SMC; +} +static inline s32 trusty_fast_call32(struct device *dev, u32 smcnr, u32 a0, + u32 a1, u32 a2) +{ + return SM_ERR_UNDEFINED_SMC; +} +#ifdef CONFIG_64BIT +static inline s64 trusty_fast_call64(struct device *dev, u64 smcnr, u64 a0, + u64 a1, u64 a2) +{ + return SM_ERR_UNDEFINED_SMC; +} +#endif +#endif + +struct notifier_block; +enum { + TRUSTY_CALL_PREPARE, + TRUSTY_CALL_RETURNED, +}; +int trusty_call_notifier_register(struct device *dev, struct notifier_block *n); +int trusty_call_notifier_unregister(struct device *dev, + struct notifier_block *n); +const char *trusty_version_str_get(struct device *dev); +u32 trusty_get_api_version(struct device *dev); + +struct ns_mem_page_info { + uint64_t attr; +}; + +int trusty_encode_page_info(struct ns_mem_page_info *inf, struct page *page, + pgprot_t pgprot, bool writable); + +int trusty_call32_mem_buf(struct device *dev, u32 smcnr, struct page *page, + u32 size, pgprot_t pgprot, bool writable); + +struct trusty_nop { + struct list_head node; + u32 args[3]; +}; + +static inline void trusty_nop_init(struct trusty_nop *nop, u32 arg0, u32 arg1, + u32 arg2) +{ + INIT_LIST_HEAD(&nop->node); + nop->args[0] = arg0; + nop->args[1] = arg1; + nop->args[2] = arg2; +} + +void trusty_enqueue_nop(struct device *dev, struct trusty_nop *nop); +void trusty_dequeue_nop(struct device *dev, struct trusty_nop *nop); + +#endif diff --git a/include/linux/trusty/trusty_ipc.h b/include/linux/trusty/trusty_ipc.h new file mode 100644 index 000000000000..14c53d3090d2 --- /dev/null +++ b/include/linux/trusty/trusty_ipc.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2015 Google, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 __LINUX_TRUSTY_TRUSTY_IPC_H +#define __LINUX_TRUSTY_TRUSTY_IPC_H + +struct tipc_chan; + +struct tipc_msg_buf { + void *buf_va; + phys_addr_t buf_pa; + size_t buf_sz; + size_t wpos; + size_t rpos; + struct list_head node; +}; + +enum tipc_chan_event { + TIPC_CHANNEL_CONNECTED = 1, + TIPC_CHANNEL_DISCONNECTED, + TIPC_CHANNEL_SHUTDOWN, +}; + +struct tipc_chan_ops { + void (*handle_event)(void *cb_arg, int event); + struct tipc_msg_buf *(*handle_msg)(void *cb_arg, + struct tipc_msg_buf *mb); + void (*handle_release)(void *cb_arg); +}; + +struct tipc_chan *tipc_create_channel(struct device *dev, + const struct tipc_chan_ops *ops, + void *cb_arg); + +int tipc_chan_connect(struct tipc_chan *chan, const char *port); + +int tipc_chan_queue_msg(struct tipc_chan *chan, struct tipc_msg_buf *mb); + +int tipc_chan_shutdown(struct tipc_chan *chan); + +void tipc_chan_destroy(struct tipc_chan *chan); + +struct tipc_msg_buf *tipc_chan_get_rxbuf(struct tipc_chan *chan); + +void tipc_chan_put_rxbuf(struct tipc_chan *chan, struct tipc_msg_buf *mb); + +struct tipc_msg_buf *tipc_chan_get_txbuf_timeout(struct tipc_chan *chan, + long timeout); + +void tipc_chan_put_txbuf(struct tipc_chan *chan, struct tipc_msg_buf *mb); + +static inline size_t mb_avail_space(struct tipc_msg_buf *mb) +{ + return mb->buf_sz - mb->wpos; +} + +static inline size_t mb_avail_data(struct tipc_msg_buf *mb) +{ + return mb->wpos - mb->rpos; +} + +static inline void *mb_put_data(struct tipc_msg_buf *mb, size_t len) +{ + void *pos = (u8 *)mb->buf_va + mb->wpos; + BUG_ON(mb->wpos + len > mb->buf_sz); + mb->wpos += len; + return pos; +} + +static inline void *mb_get_data(struct tipc_msg_buf *mb, size_t len) +{ + void *pos = (u8 *)mb->buf_va + mb->rpos; + BUG_ON(mb->rpos + len > mb->wpos); + mb->rpos += len; + return pos; +} + +#endif /* __LINUX_TRUSTY_TRUSTY_IPC_H */ diff --git a/include/linux/trusty/trusty_shm.h b/include/linux/trusty/trusty_shm.h new file mode 100644 index 000000000000..1f933f678553 --- /dev/null +++ b/include/linux/trusty/trusty_shm.h @@ -0,0 +1,26 @@ +/* + * Copyright 2018 GoldenRiver Technologies Co., Ltd. All rights reserved. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 __LINUX_TRUSTY_SHM_H +#define __LINUX_TRUSTY_SHM_H + +void *trusty_shm_alloc(size_t size, gfp_t gfp); +void trusty_shm_free(void *virt, size_t size); +int trusty_shm_init_pool(struct device *dev); +void trusty_shm_destroy_pool(struct device *dev); +phys_addr_t trusty_shm_virt_to_phys(void *vaddr); +void *trusty_shm_phys_to_virt(unsigned long addr); + +#endif diff --git a/include/uapi/linux/virtio_ids.h b/include/uapi/linux/virtio_ids.h index b8947df69d7e..88a1fa044d6f 100644 --- a/include/uapi/linux/virtio_ids.h +++ b/include/uapi/linux/virtio_ids.h @@ -39,6 +39,7 @@ #define VIRTIO_ID_9P 9 /* 9p virtio console */ #define VIRTIO_ID_RPROC_SERIAL 11 /* virtio remoteproc serial link */ #define VIRTIO_ID_CAIF 12 /* Virtio caif */ +#define VIRTIO_ID_TRUSTY_IPC 13 /* virtio trusty ipc */ #define VIRTIO_ID_GPU 16 /* virtio GPU */ #define VIRTIO_ID_INPUT 18 /* virtio input */ #define VIRTIO_ID_VSOCK 19 /* virtio vsock transport */ From b0920a3810fbb3c1909a0808e889e2bc10b918fe Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:46:21 +0200 Subject: [PATCH 094/226] drivers: usb: Import Xiaomi changes Change-Id: I0c11d47f789ffe489a08c9149e94a39c3bad27f0 Signed-off-by: firebird11 --- drivers/usb/core/hub.c | 2 + drivers/usb/dwc3/dwc3-msm.c | 2 + drivers/usb/gadget/configfs.c | 29 ++ drivers/usb/pd/policy_engine.c | 842 +++++++++++++++++++++++++++++++++ drivers/usb/pd/usbpd.h | 56 +++ 5 files changed, 931 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 95a9267f4ffc..db6d4f3c8fc1 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4825,7 +4825,9 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, /* notify HCD that we have a device connected and addressed */ if (hcd->driver->update_device) hcd->driver->update_device(hcd, udev); +#ifndef CONFIG_MACH_XIAOMI_SM8150 /*disable USB 2.0 Link PM to fix long time usb storage recognition issue*/ hub_set_initial_usb2_lpm_policy(udev); +#endif fail: if (retval) { hub_port_disable(hub, port1, 0); diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index a3f9651b6763..102aaf99f850 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -4939,8 +4939,10 @@ static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned int mA) * bail out if suspend happened with float cable * connected */ +#ifndef CONFIG_MACH_XIAOMI_SM8150 /* xiaomi charger driver need this current config float current, so remove this qcom default retuen feature. */ if (mA == 2) return 0; +#endif if (!mA) pval.intval = -ETIMEDOUT; diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index d2a55c1ab7a0..7f29c9f0e568 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -5,6 +5,9 @@ #include #include #include +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#include +#endif #include "configfs.h" #include "u_f.h" #include "u_os_desc.h" @@ -1435,6 +1438,29 @@ static int configfs_composite_bind(struct usb_gadget *gadget, return ret; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static int smblib_canncel_recheck(void) +{ + union power_supply_propval pval = {0}; + struct power_supply *usb_psy = NULL; + int rc = 0; + + if (!usb_psy) { + usb_psy = power_supply_get_by_name("usb"); + if (!usb_psy) { + pr_err("Could not get usb psy by canncel recheck\n"); + return -ENODEV; + } + } + + pval.intval = 0; + rc = power_supply_set_property(usb_psy, + POWER_SUPPLY_PROP_TYPE_RECHECK, &pval); + + return rc; +} +#endif + #ifdef CONFIG_USB_CONFIGFS_UEVENT static void android_work(struct work_struct *data) { @@ -1472,6 +1498,9 @@ static void android_work(struct work_struct *data) kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, configured); pr_info("%s: sent uevent %s\n", __func__, configured[0]); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + smblib_canncel_recheck(); +#endif uevent_sent = true; } diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index ff13ee1e70de..62ed739d4d30 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -354,6 +354,15 @@ static void *usbpd_ipc_log; #define ID_HDR_PRODUCT_AMA 5 #define ID_HDR_PRODUCT_VPD 6 +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define PD_VBUS_MAX_VOLTAGE_LIMIT 9000000 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define PD_MAX_CURRENT_LIMIT 4000000 +#endif +#define MAX_FIXED_PDO_MA 2000 +#define MAX_NON_COMPLIANT_PPS_UA 2000000 +#endif + static bool check_vsafe0v = true; module_param(check_vsafe0v, bool, 0600); @@ -454,6 +463,16 @@ struct usbpd { struct regulator *vconn; bool vbus_enabled; bool vconn_enabled; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool vconn_is_external; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + u32 limit_curr; + u32 pd_max_curr_limit; +#else + u32 limit_pd_vbus; + u32 pd_vbus_max_limit; +#endif +#endif u8 tx_msgid[SOPII_MSG + 1]; u8 rx_msgid[SOPII_MSG + 1]; @@ -469,12 +488,33 @@ struct usbpd { struct list_head svid_handlers; ktime_t svdm_start_time; bool vdm_in_suspend; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + bool verify_process; +#endif struct list_head instance; bool has_dp; u16 ss_lane_svid; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /*for xiaomi verifed pd adapter*/ + u32 adapter_id; + u32 adapter_svid; + struct usbpd_vdm_data vdm_data; + struct usbpd_svid_handler svid_handler; + bool verifed; + int uvdm_state; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + bool pps_weak_limit; +#endif + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* non-qcom pps control */ + bool non_qcom_pps_ctr; +#endif +#endif + /* ext msg support */ bool send_get_src_cap_ext; u8 src_cap_ext_db[PD_SRC_CAP_EXT_DB_LEN]; @@ -836,6 +876,131 @@ static int pd_select_pdo(struct usbpd *pd, int pdo_pos, int uv, int ua) pd->requested_voltage = PD_SRC_PDO_FIXED_VOLTAGE(pdo) * 50 * 1000; + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* pd request uv will less than pd vbus max 9V for fixed pdos */ + if (pd->requested_voltage > PD_VBUS_MAX_VOLTAGE_LIMIT) + return -ENOTSUPP; + + /* + * set maxium allowed current for fixed pdo to 2A if request + * voltage is 9V, as we should limit charger to 18W for more safety + * both for charger and our device(such as charge ic inductor) + */ + if (pd->requested_voltage == PD_VBUS_MAX_VOLTAGE_LIMIT + && curr >= MAX_FIXED_PDO_MA) + curr = MAX_FIXED_PDO_MA; +#endif + + pd->rdo = PD_RDO_FIXED(pdo_pos, 0, mismatch, 1, 1, curr / 10, + max_current / 10); + } else if (type == PD_SRC_PDO_TYPE_AUGMENTED) { + if ((uv / 100000) > PD_APDO_MAX_VOLT(pdo) || + (uv / 100000) < PD_APDO_MIN_VOLT(pdo) || + (ua / 50000) > PD_APDO_MAX_CURR(pdo) || (ua < 0)) { + usbpd_err(&pd->dev, "uv (%d) and ua (%d) out of range of APDO\n", + uv, ua); + return -EINVAL; + } + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* use xiaomi pps control state machine */ + if (pd->non_qcom_pps_ctr) { + usbpd_err(&pd->dev, + "PPS is controlled by ourself, return not support\n"); + return -ENOTSUPP; + } + + /* if limit_pd_vbus is enabled, pd request uv will less than pd vbus max */ + if (pd->limit_curr && ua > pd->pd_max_curr_limit) { + ua = pd->pd_max_curr_limit; + } + + if ((pd->pps_weak_limit) && (ua > USBPD_WAKK_PPS_CURR_LIMIT)) { + ua = USBPD_WAKK_PPS_CURR_LIMIT; + } +#endif + + curr = ua / 1000; + +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if !defined(CONFIG_MACH_XIAOMI_VAYU) && !defined(CONFIG_MACH_XIAOMI_NABU) + /* if limit_pd_vbus is enabled, pd request uv will less than pd vbus max */ + if (pd->limit_pd_vbus && uv > pd->pd_vbus_max_limit) + uv = pd->pd_vbus_max_limit; +#endif + + /* + * workaround for Zimi and similar non-compliant QC4+/PPS chargers: + * if PPS power limit bit is set and QC4+ not compliant PPS chargers, + * hvdcp_opti will set 0mA for these PPS chargers, we treat them as + * maxium 2A PPS chargers to avoid not charging issue. + */ + if (curr == 0) { + ua = MAX_NON_COMPLIANT_PPS_UA; + curr = ua / 1000; + } +#endif + + pd->requested_voltage = uv; + pd->rdo = PD_RDO_AUGMENTED(pdo_pos, mismatch, 1, 1, + uv / 20000, ua / 50000); + } else { + usbpd_err(&pd->dev, "Only Fixed or Programmable PDOs supported\n"); + return -ENOTSUPP; + } + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* Can't sink more than 5V if VCONN is sourced from the VBUS input */ + if (pd->vconn_enabled && !pd->vconn_is_external && + pd->requested_voltage > 5000000) + return -ENOTSUPP; +#endif + + pd->requested_current = curr; + pd->requested_pdo = pdo_pos; + + return 0; +} + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static int pd_select_pdo_for_bq(struct usbpd *pd, int pdo_pos, int uv, int ua) +{ + int curr; + int max_current; + bool mismatch = false; + u8 type; + u32 pdo = pd->received_pdos[pdo_pos - 1]; + + type = PD_SRC_PDO_TYPE(pdo); + if (type == PD_SRC_PDO_TYPE_FIXED) { + curr = max_current = PD_SRC_PDO_FIXED_MAX_CURR(pdo) * 10; + + /* + * Check if the PDO has enough current, otherwise set the + * Capability Mismatch flag + */ + if (curr < min_sink_current) { + mismatch = true; + max_current = min_sink_current; + } + + pd->requested_voltage = + PD_SRC_PDO_FIXED_VOLTAGE(pdo) * 50 * 1000; + + /* pd request uv will less than pd vbus max 9V for fixed pdos */ + if (pd->requested_voltage > PD_VBUS_MAX_VOLTAGE_LIMIT) + return -ENOTSUPP; + + /* + * set maxium allowed current for fixed pdo to 2A if request + * voltage is 9V, as we should limit charger to 18W for more safety + * both for charger and our device(such as charge ic inductor) + */ + if (pd->requested_voltage == PD_VBUS_MAX_VOLTAGE_LIMIT + && curr >= MAX_FIXED_PDO_MA) + curr = MAX_FIXED_PDO_MA; + pd->rdo = PD_RDO_FIXED(pdo_pos, 0, mismatch, 1, 1, curr / 10, max_current / 10); } else if (type == PD_SRC_PDO_TYPE_AUGMENTED) { @@ -847,7 +1012,27 @@ static int pd_select_pdo(struct usbpd *pd, int pdo_pos, int uv, int ua) return -EINVAL; } + /* if limit_pd_vbus is enabled, pd request uv will less than pd vbus max */ + if (pd->limit_curr && ua > pd->pd_max_curr_limit) { + ua = pd->pd_max_curr_limit; + } + if ((pd->pps_weak_limit) && (ua > USBPD_WAKK_PPS_CURR_LIMIT)) { + ua = USBPD_WAKK_PPS_CURR_LIMIT; + } + curr = ua / 1000; + + /* + * workaround for Zimi and similar non-compliant QC4+/PPS chargers: + * if PPS power limit bit is set and QC4+ not compliant PPS chargers, + * hvdcp_opti will set 0mA for these PPS chargers, we treat them as + * maxium 2A PPS chargers to avoid not charging issue. + */ + if (curr == 0) { + ua = MAX_NON_COMPLIANT_PPS_UA; + curr = ua / 1000; + } + pd->requested_voltage = uv; pd->rdo = PD_RDO_AUGMENTED(pdo_pos, mismatch, 1, 1, uv / 20000, ua / 50000); @@ -861,6 +1046,7 @@ static int pd_select_pdo(struct usbpd *pd, int pdo_pos, int uv, int ua) return 0; } +#endif static int pd_eval_src_caps(struct usbpd *pd) { @@ -868,6 +1054,10 @@ static int pd_eval_src_caps(struct usbpd *pd) union power_supply_propval val; bool pps_found = false; u32 first_pdo = pd->received_pdos[0]; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int max_volt, min_volt, max_curr; + int pps_min_power = 0; +#endif if (PD_SRC_PDO_TYPE(first_pdo) != PD_SRC_PDO_TYPE_FIXED) { usbpd_err(&pd->dev, "First src_cap invalid! %08x\n", first_pdo); @@ -894,6 +1084,34 @@ static int pd_eval_src_caps(struct usbpd *pd) } } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + for (i = 0; i < ARRAY_SIZE(pd->received_pdos); i++) { + u32 pdo = pd->received_pdos[i]; + + if (pdo == 0) + break; + + if (PD_SRC_PDO_TYPE(pdo) == PD_SRC_PDO_TYPE_FIXED) { + max_volt = PD_SRC_PDO_FIXED_VOLTAGE(pdo) * 50; + min_volt = PD_SRC_PDO_FIXED_VOLTAGE(pdo) * 50; + max_curr = PD_SRC_PDO_FIXED_MAX_CURR(pdo) * 10; + } else if (PD_SRC_PDO_TYPE(pdo) == PD_SRC_PDO_TYPE_AUGMENTED) { + max_volt = PD_APDO_MAX_VOLT(pdo) * 100; + min_volt = PD_APDO_MIN_VOLT(pdo) * 100; + max_curr = PD_APDO_MAX_CURR(pdo) * 50; + + if (pps_min_power < max_volt * max_curr || pps_min_power == 0) { + pps_min_power = max_volt * max_curr; + if (pps_min_power < USBPD_WEAK_PPS_POWER) + pd->pps_weak_limit = true; + } + } + usbpd_info(&pd->dev, "%s max_volt:%d,min_volt:%d,max_curr:%d\n", + (PD_SRC_PDO_TYPE(pdo) == PD_SRC_PDO_TYPE_AUGMENTED) ? "PPS" : "PD2.0", + max_volt, min_volt, max_curr); + } +#endif + val.intval = pps_found ? POWER_SUPPLY_PD_PPS_ACTIVE : POWER_SUPPLY_PD_ACTIVE; @@ -2019,6 +2237,15 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) break; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (num_vdos != 0) { + for (i = 0; i < num_vdos; i++) { + pd->adapter_id = vdos[i] & 0xFFFF; + usbpd_info(&pd->dev, "pd->adapter_id:0x%x\n", pd->adapter_id); + } + } +#endif + pd->vdm_state = DISCOVERED_ID; usbpd_send_svdm(pd, USBPD_SID, USBPD_SVDM_DISCOVER_SVIDS, @@ -2084,6 +2311,9 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) if (svid) { usbpd_dbg(&pd->dev, "Discovered SVID: 0x%04x\n", svid); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + pd->adapter_svid = svid; +#endif *psvid++ = svid; } } @@ -2127,6 +2357,9 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) switch (cmd) { case USBPD_SVDM_DISCOVER_IDENTITY: case USBPD_SVDM_DISCOVER_SVIDS: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + pd->uvdm_state = USBPD_UVDM_NAN_ACK; +#endif break; default: break; @@ -2546,6 +2779,14 @@ static void usbpd_sm(struct work_struct *w) pd->peer_usb_comm = pd->peer_pr_swap = pd->peer_dr_swap = false; memset(&pd->received_pdos, 0, sizeof(pd->received_pdos)); rx_msg_cleanup(pd); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + pd->verifed = false; + pd->uvdm_state = USBPD_UVDM_DISCONNECT; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + pd->verify_process = 0; + pd->pps_weak_limit = false; +#endif +#endif power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val); @@ -4101,6 +4342,11 @@ static ssize_t select_pdo_store(struct device *dev, mutex_lock(&pd->swap_lock); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (pd->verify_process) + goto out; +#endif + /* Only allowed if we are already in explicit sink contract */ if (pd->current_state != PE_SNK_READY) { usbpd_err(&pd->dev, "select_pdo: Cannot select new PDO yet\n"); @@ -4283,6 +4529,11 @@ static ssize_t get_src_cap_ext_show(struct device *dev, int i, ret, len = 0; struct usbpd *pd = dev_get_drvdata(dev); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* as some pps charger do not support this message, do not send */ + return -EINVAL; +#endif + if (pd->spec_rev == USBPD_REV_20) return -EINVAL; @@ -4307,6 +4558,11 @@ static ssize_t get_status_show(struct device *dev, int i, ret, len = 0; struct usbpd *pd = dev_get_drvdata(dev); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* as some pps charger do not support this message, do not send */ + return -EINVAL; +#endif + if (pd->spec_rev == USBPD_REV_20) return -EINVAL; @@ -4331,6 +4587,11 @@ static ssize_t get_pps_status_show(struct device *dev, int ret; struct usbpd *pd = dev_get_drvdata(dev); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* as some pps charger do not support this message, do not send */ + return -EINVAL; +#endif + if (pd->spec_rev == USBPD_REV_20) return -EINVAL; @@ -4410,6 +4671,254 @@ static ssize_t get_battery_status_show(struct device *dev, } static DEVICE_ATTR_RW(get_battery_status); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static ssize_t current_state_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct usbpd *pd = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%s", + usbpd_state_strings[pd->current_state]); +} +static DEVICE_ATTR_RO(current_state); + +static ssize_t usbpd_verifed_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct usbpd *pd = dev_get_drvdata(dev); + int val, ret; + + if (sscanf(buf, "%d\n", &val) != 1) { + pd->verifed = 0; + return -EINVAL; + } + usbpd_err(&pd->dev, "batterysecret set usbpd verifed :%d\n", val); + + pd->verifed = val; + + if (pd->verifed) { + ret = pd_send_msg(pd, MSG_GET_SOURCE_CAP, NULL, 0, SOP_MSG); + if (ret) { + usbpd_set_state(pd, PE_SEND_SOFT_RESET); + return size; + } + } + + return size; +} + +static ssize_t usbpd_verifed_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usbpd *pd = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", pd->verifed); +} +static DEVICE_ATTR_RW(usbpd_verifed); + +static ssize_t adapter_id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usbpd *pd = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%08x", pd->adapter_id); +} +static DEVICE_ATTR_RO(adapter_id); + +static ssize_t adapter_svid_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usbpd *pd = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%04x", pd->adapter_svid); +} +static DEVICE_ATTR_RO(adapter_svid); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static ssize_t verify_process_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct usbpd *pd = dev_get_drvdata(dev); + int val; + + if (sscanf(buf, "%d\n", &val) != 1) { + pd->verify_process = 0; + return -EINVAL; + } + + pd->verify_process = !!val; + usbpd_info(&pd->dev, "batterysecret verify process :%d\n", pd->verify_process); + + return size; +} + +static ssize_t verify_process_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usbpd *pd = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", pd->verify_process); +} +static DEVICE_ATTR_RW(verify_process); +#endif + +static ssize_t adapter_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usbpd *pd = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%08x", pd->vdm_data.ta_version); +} +static DEVICE_ATTR_RO(adapter_version); + +static int StringToHex(char *str, unsigned char *out, unsigned int *outlen) +{ + char *p = str; + char high = 0, low = 0; + int tmplen = strlen(p), cnt = 0; + tmplen = strlen(p); + while (cnt < (tmplen / 2)) { + high = ((*p > '9') && ((*p <= 'F') || (*p <= 'f'))) ? *p - 48 - 7 : *p - 48; + low = (*(++p) > '9' && ((*p <= 'F') || (*p <= 'f'))) ? *(p) - 48 - 7 : *(p) - 48; + out[cnt] = ((high & 0x0f) << 4 | (low & 0x0f)); + p++; + cnt++; + } + if (tmplen % 2 != 0) + out[cnt] = ((*p > '9') && ((*p <= 'F') || (*p <= 'f'))) ? *p - 48 - 7 : *p - 48; + + if (outlen != NULL) + *outlen = tmplen / 2 + tmplen % 2; + + return tmplen / 2 + tmplen % 2; +} + +#define BSWAP_32(x) \ + (u32)((((u32)(x) & 0xff000000) >> 24) | \ + (((u32)(x) & 0x00ff0000) >> 8) | \ + (((u32)(x) & 0x0000ff00) << 8) | \ + (((u32)(x) & 0x000000ff) << 24)) + +static void usbpd_sha256_bitswap32(unsigned int *array, int len) +{ + int i; + + for (i = 0; i < len; i++) { + array[i] = BSWAP_32(array[i]); + } +} + +static int usbpd_request_vdm_cmd(struct usbpd *pd, enum uvdm_state cmd, unsigned int *data) +{ + u32 vdm_hdr = 0; + int rc = 0; + struct usbpd_svid_handler *hdlr = &pd->svid_handler; + + vdm_hdr = VDM_HDR(hdlr->svid, USBPD_VDM_REQUEST, cmd); + + switch (cmd) { + case USBPD_UVDM_CHARGER_VERSION: + case USBPD_UVDM_CHARGER_TEMP: + case USBPD_UVDM_CHARGER_VOLTAGE: + rc = usbpd_send_vdm(pd, vdm_hdr, NULL, 0); + if (rc < 0) { + usbpd_err(&pd->dev, "failed to send %d\n", cmd); + return rc; + } + break; + case USBPD_UVDM_VERIFIED: +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + case USBPD_UVDM_REMOVE_COMPENSATION: + if (pd->non_qcom_pps_ctr) { + if (cmd == USBPD_UVDM_REMOVE_COMPENSATION) + break; + } +#endif + rc = usbpd_send_vdm(pd, vdm_hdr, data, USBPD_UVDM_VERIFIED_LEN); + if (rc < 0) { + usbpd_err(&pd->dev, "failed to send %d\n", cmd); + return rc; + } + break; + case USBPD_UVDM_SESSION_SEED: + case USBPD_UVDM_AUTHENTICATION: + usbpd_sha256_bitswap32(data, USBPD_UVDM_SS_LEN); + rc = usbpd_send_vdm(pd, vdm_hdr, data, USBPD_UVDM_SS_LEN); + if (rc < 0) { + usbpd_err(&pd->dev, "failed to send %d\n", cmd); + return rc; + } + break; + default: + usbpd_err(&pd->dev, "cmd:%d is not support\n", cmd); + break; + } + + return rc; +} + +static ssize_t request_vdm_cmd_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct usbpd *pd = dev_get_drvdata(dev); + int cmd, ret; + unsigned char buffer[64]; + unsigned char data[32]; + int count; + + ret = sscanf(buf, "%d,%s\n", &cmd, buffer); + + usbpd_dbg(&pd->dev, "%s:cmd:%d, buffer:%s\n", __func__, cmd, buffer); + + StringToHex(buffer, data, &count); + usbpd_request_vdm_cmd(pd, cmd, (unsigned int *)data); + + return size; +} + +static ssize_t request_vdm_cmd_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usbpd *pd = dev_get_drvdata(dev); + int i; + char data[16], str_buf[128] = {0}; + int cmd = pd->uvdm_state; + + switch (cmd) { + case USBPD_UVDM_CHARGER_VERSION: + return snprintf(buf, PAGE_SIZE, "%d,%x", cmd, pd->vdm_data.ta_version); + break; + case USBPD_UVDM_CHARGER_TEMP: + return snprintf(buf, PAGE_SIZE, "%d,%d", cmd, pd->vdm_data.ta_temp); + break; + case USBPD_UVDM_CHARGER_VOLTAGE: + return snprintf(buf, PAGE_SIZE, "%d,%d", cmd, pd->vdm_data.ta_voltage); + break; + case USBPD_UVDM_SESSION_SEED: + case USBPD_UVDM_CONNECT: + case USBPD_UVDM_DISCONNECT: + case USBPD_UVDM_VERIFIED: + case USBPD_UVDM_NAN_ACK: + return snprintf(buf, PAGE_SIZE, "%d,Null", cmd); + break; + case USBPD_UVDM_AUTHENTICATION: + for (i = 0; i < USBPD_UVDM_SS_LEN; i++) { + memset(data, 0, sizeof(data)); + snprintf(data, sizeof(data), "%08lx", pd->vdm_data.digest[i]); + strlcat(str_buf, data, sizeof(str_buf)); + } + return snprintf(buf, PAGE_SIZE, "%d,%s", cmd, str_buf); + break; + default: + usbpd_err(&pd->dev, "feedbak cmd:%d is not support\n", cmd); + break; + } + return snprintf(buf, PAGE_SIZE, "%d,%s", cmd, str_buf); + +} +static DEVICE_ATTR_RW(request_vdm_cmd); +#endif + static struct attribute *usbpd_attrs[] = { &dev_attr_contract.attr, &dev_attr_initial_pr.attr, @@ -4434,6 +4943,17 @@ static struct attribute *usbpd_attrs[] = { &dev_attr_get_pps_status.attr, &dev_attr_get_battery_cap.attr, &dev_attr_get_battery_status.attr, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + &dev_attr_request_vdm_cmd.attr, + &dev_attr_current_state.attr, + &dev_attr_adapter_id.attr, + &dev_attr_adapter_svid.attr, + &dev_attr_adapter_version.attr, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + &dev_attr_verify_process.attr, +#endif + &dev_attr_usbpd_verifed.attr, +#endif NULL, }; ATTRIBUTE_GROUPS(usbpd); @@ -4504,6 +5024,257 @@ struct usbpd *devm_usbpd_get_by_phandle(struct device *dev, const char *phandle) } EXPORT_SYMBOL(devm_usbpd_get_by_phandle); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static void usbpd_mi_connect_cb(struct usbpd_svid_handler *hdlr, + bool peer_usb_comm) +{ + struct usbpd *pd; + + pd = container_of(hdlr, struct usbpd, svid_handler); + if(!pd) { + pr_err("get_usbpd phandle failed\n"); + return; + } + + pr_debug("peer_usb_comm: %d\n", peer_usb_comm); +// pd->dp_usbpd.base.peer_usb_comm = peer_usb_comm; + + pd->uvdm_state = USBPD_UVDM_CONNECT; + usbpd_info(&pd->dev, "hdlr->svid:%x has connect\n", hdlr->svid); + + return; +} + +static void usbpd_mi_disconnect_cb(struct usbpd_svid_handler *hdlr) +{ + struct usbpd *pd; + + pd = container_of(hdlr, struct usbpd, svid_handler); + + pd->adapter_id = 0; + pd->adapter_svid = 0; + pd->vdm_data.ta_version = 0; + pd->uvdm_state = USBPD_UVDM_DISCONNECT; + usbpd_info(&pd->dev, "hdlr->svid:%x has disconnect\n", hdlr->svid); + + return; +} + +static void usbpd_mi_vdm_received_cb(struct usbpd_svid_handler *hdlr, u32 vdm_hdr, + const u32 *vdos, int num_vdos) +{ + struct usbpd *pd; + int i, cmd; + int usb_current, usb_voltage, r_cable; + union power_supply_propval val = {0}; + int ret; + + pd = container_of(hdlr, struct usbpd, svid_handler); + cmd = UVDM_HDR_CMD(vdm_hdr); + + usbpd_dbg(&pd->dev, "hdlr->svid:0x%x, vdm_hdr:0x%x, num_vdos:%d, cmd:%d\n", + hdlr->svid, vdm_hdr, num_vdos); + + switch (cmd) { + case USBPD_UVDM_CHARGER_VERSION: + pd->vdm_data.ta_version = vdos[0]; + usbpd_dbg(&pd->dev, "ta_version:%x\n", pd->vdm_data.ta_version); + break; + case USBPD_UVDM_CHARGER_TEMP: + pd->vdm_data.ta_temp = (vdos[0] & 0xFFFF) * 10; + usbpd_dbg(&pd->dev, "pd->vdm_data.ta_temp:%d\n", pd->vdm_data.ta_temp); + break; + case USBPD_UVDM_CHARGER_VOLTAGE: + pd->vdm_data.ta_voltage = (vdos[0] & 0xFFFF) * 10; + pd->vdm_data.ta_voltage *= 1000; /*V->mV*/ + usbpd_dbg(&pd->dev, "ta_voltage:%d\n", pd->vdm_data.ta_voltage); + + ret = power_supply_get_property(pd->usb_psy, + POWER_SUPPLY_PROP_VOLTAGE_NOW, &val); + if (ret) { + usbpd_err(&pd->dev, "failed to get usb voltage now\n"); + break; + } + usb_voltage = val.intval; + usbpd_dbg(&pd->dev, "usb voltage now:%d\n", usb_voltage); + ret = power_supply_get_property(pd->usb_psy, + POWER_SUPPLY_PROP_INPUT_CURRENT_NOW, &val); + if (ret) { + usbpd_err(&pd->dev, "failed to get usb current now\n"); + break; + } + usb_current = val.intval / 1000; + usbpd_dbg(&pd->dev, "usb current now:%d\n", usb_current); + + r_cable = (pd->vdm_data.ta_voltage - usb_voltage) / usb_current; + usbpd_dbg(&pd->dev, "usb r_cable now:%dmohm\n", r_cable); + break; + case USBPD_UVDM_SESSION_SEED: +#ifdef CONFIG_MACH_XIAOMI_NABU + if (num_vdos != 0) { + for (i = 0; i < num_vdos; i++) { + pd->vdm_data.s_secert[i] = vdos[i]; + usbpd_dbg(&pd->dev, "usbpd s_secert vdos[%d]=0x%x", i, vdos[i]); + } + } +#else + for (i = 0; i < USBPD_UVDM_SS_LEN; i++) { + pd->vdm_data.s_secert[i] = vdos[i]; + usbpd_dbg(&pd->dev, "usbpd s_secert vdos[%d]=0x%x", i, vdos[i]); + } +#endif + break; + case USBPD_UVDM_AUTHENTICATION: +#ifdef CONFIG_MACH_XIAOMI_NABU + if (num_vdos != 0) { + for (i = 0; i < num_vdos; i++) { + pd->vdm_data.digest[i] = vdos[i]; + usbpd_dbg(&pd->dev, "usbpd digest[%d]=0x%x", i, vdos[i]); + } + } +#else + for (i = 0; i < USBPD_UVDM_SS_LEN; i++) { + pd->vdm_data.digest[i] = vdos[i]; + usbpd_dbg(&pd->dev, "usbpd digest[%d]=0x%x", i, vdos[i]); + } +#endif + break; + default: + break; + } + pd->uvdm_state = cmd; +} + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +int usbpd_get_pps_status(struct usbpd *pd, u32 *pps_status) +{ + int ret; + + if (pd->spec_rev == USBPD_REV_20) + return -EINVAL; + + ret = trigger_tx_msg(pd, &pd->send_get_pps_status); + if (ret) + return ret; + + *pps_status = pd->pps_status_db; + + return ret; +} +EXPORT_SYMBOL(usbpd_get_pps_status); + +int usbpd_fetch_pdo(struct usbpd *pd, struct usbpd_pdo *pdos) +{ + int ret = 0; + int pdo; + int i; + + if (!pd || !pdos) + return -EINVAL; + + mutex_lock(&pd->swap_lock); + + if (pd->current_pr == PR_SRC) { + usbpd_err(&pd->dev, "not support in SRC mode\n"); + ret = -ENOTSUPP; + goto out; + } + + for (i = 0; i < 7; i++) { + pdo = pd->received_pdos[i]; + if (pdo == 0) + break; + + pdos[i].pos = i + 1; + pdos[i].pps = PD_APDO_PPS(pdo) == 0; + pdos[i].type = PD_SRC_PDO_TYPE(pdo); + + if (pdos[i].type == PD_SRC_PDO_TYPE_FIXED) { + pdos[i].curr_ma = PD_SRC_PDO_FIXED_MAX_CURR(pdo) * 10; + pdos[i].max_volt_mv = PD_SRC_PDO_FIXED_VOLTAGE(pdo) * 50; + pdos[i].min_volt_mv = PD_SRC_PDO_FIXED_VOLTAGE(pdo) * 50; + usbpd_info(&pd->dev, + "pdo:%d, Fixed supply, volt:%d(mv), max curr:%d\n", + i+1, pdos[i].max_volt_mv, + pdos[i].curr_ma); + } else if (pdos[i].type == PD_SRC_PDO_TYPE_AUGMENTED) { + pdos[i].max_volt_mv = PD_APDO_MAX_VOLT(pdo) * 100; + pdos[i].min_volt_mv = PD_APDO_MIN_VOLT(pdo) * 100; + pdos[i].curr_ma = PD_APDO_MAX_CURR(pdo) * 50; + usbpd_info(&pd->dev, + "pdo:%d, PPS, volt: %d(mv), max curr:%d\n", + i+1, pdos[i].max_volt_mv, + pdos[i].curr_ma); + } else { + usbpd_err(&pd->dev, "only fixed and pps pdo supported\n"); + } + } + +out: + mutex_unlock(&pd->swap_lock); + return ret; +} +EXPORT_SYMBOL(usbpd_fetch_pdo); + +int usbpd_select_pdo(struct usbpd *pd, int pdo, int uv, int ua) +{ + int ret; + + mutex_lock(&pd->swap_lock); + + if (pd->verify_process) + goto out; + + if (pd->current_pr != PR_SINK) { + ret = -ENOTSUPP; + goto out; + } + + /* Only allowed if we are already in explicit sink contract */ + if (pd->current_state != PE_SNK_READY || !is_sink_tx_ok(pd)) { + usbpd_err(&pd->dev, "select_pdo: Cannot select new PDO yet\n"); + ret = -EBUSY; + goto out; + } + + if (pdo < 1 || pdo > 7) { + usbpd_err(&pd->dev, "select_pdo: invalid PDO:%d\n", pdo); + ret = -EINVAL; + goto out; + } + + ret = pd_select_pdo_for_bq(pd, pdo, uv, ua); + if (ret) + goto out; + + reinit_completion(&pd->is_ready); + pd->send_request = true; + kick_sm(pd, 0); + + /* wait for operation to complete */ + if (!wait_for_completion_timeout(&pd->is_ready, + msecs_to_jiffies(1000))) { + usbpd_err(&pd->dev, "select_pdo: request timed out\n"); + ret = -ETIMEDOUT; + goto out; + } + + /* determine if request was accepted/rejected */ + if (pd->selected_pdo != pd->requested_pdo || + pd->current_voltage != pd->requested_voltage) { + usbpd_err(&pd->dev, "select_pdo: request rejected\n"); + ret = -EINVAL; + } + +out: + pd->send_request = false; + mutex_unlock(&pd->swap_lock); + return ret; +} +EXPORT_SYMBOL(usbpd_select_pdo); +#endif +#endif + static void usbpd_release(struct device *dev) { struct usbpd *pd = container_of(dev, struct usbpd, dev); @@ -4528,6 +5299,15 @@ struct usbpd *usbpd_create(struct device *parent) int ret; struct usbpd *pd; union power_supply_propval val = {0}; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct usbpd_svid_handler svid_handler = { + .svid = USB_PD_MI_SVID, + .vdm_received = &usbpd_mi_vdm_received_cb, + .connect = &usbpd_mi_connect_cb, + .svdm_received = NULL, + .disconnect = &usbpd_mi_disconnect_cb, + }; +#endif pd = kzalloc(sizeof(*pd), GFP_KERNEL); if (!pd) @@ -4614,6 +5394,60 @@ struct usbpd *usbpd_create(struct device *parent) extcon_set_property_capability(pd->extcon, EXTCON_USB_HOST, EXTCON_PROP_USB_SS); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + ret = of_property_read_u32(parent->of_node, "mi,pd_curr_limit", + &pd->limit_curr); + if (ret) { + usbpd_err(&pd->dev, "do not limit current\n"); + pd->limit_curr = false; + } + + if (pd->limit_curr) { + ret = of_property_read_u32(parent->of_node, "mi,pd_max_curr_limit", + &pd->pd_max_curr_limit); + if (ret) { + usbpd_err(&pd->dev, "failed to read pd vbus max limit\n"); + pd->pd_max_curr_limit = PD_MAX_CURRENT_LIMIT; + } + } + + pd->non_qcom_pps_ctr = of_property_read_bool(parent->of_node, + "mi,non-qcom-pps-ctrl"); +#else + pd->vbus = devm_regulator_get(parent, "vbus"); + if (IS_ERR(pd->vbus)) { + ret = PTR_ERR(pd->vbus); + goto put_psy; + } + + pd->vconn = devm_regulator_get(parent, "vconn"); + if (IS_ERR(pd->vconn)) { + ret = PTR_ERR(pd->vconn); + goto put_psy; + } + + ret = of_property_read_u32(parent->of_node, "mi,limit_pd_vbus", + &pd->limit_pd_vbus); + if (ret) { + usbpd_err(&pd->dev, "failed to read pd vbus limit\n"); + pd->limit_pd_vbus = false; + } + + if (pd->limit_pd_vbus) { + ret = of_property_read_u32(parent->of_node, "mi,pd_vbus_max_limit", + &pd->pd_vbus_max_limit); + if (ret) { + usbpd_err(&pd->dev, "failed to read pd vbus max limit\n"); + pd->pd_vbus_max_limit = PD_VBUS_MAX_VOLTAGE_LIMIT; + } + } +#endif + + pd->vconn_is_external = device_property_present(parent, + "qcom,vconn-uses-external-source"); +#endif + pd->num_sink_caps = device_property_read_u32_array(parent, "qcom,default-sink-caps", NULL, 0); if (pd->num_sink_caps > 0) { @@ -4704,6 +5538,14 @@ struct usbpd *usbpd_create(struct device *parent) if (ret) goto del_inst; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + pd->svid_handler = svid_handler; + ret = usbpd_register_svid(pd, &pd->svid_handler); + if (ret) { + usbpd_err(&pd->dev, "usbpd registration failed\n"); + } +#endif + /* force read initial power_supply values */ psy_changed(&pd->psy_nb, PSY_EVENT_PROP_CHANGED, pd->usb_psy); diff --git a/drivers/usb/pd/usbpd.h b/drivers/usb/pd/usbpd.h index 5c7c5cdf4c7d..fcc59291e332 100644 --- a/drivers/usb/pd/usbpd.h +++ b/drivers/usb/pd/usbpd.h @@ -110,4 +110,60 @@ static inline void pd_phy_close(void) { } #endif + +#ifdef CONFIG_MACH_XIAOMI_SM8150 +enum uvdm_state { + USBPD_UVDM_DISCONNECT, + USBPD_UVDM_CHARGER_VERSION, + USBPD_UVDM_CHARGER_VOLTAGE, + USBPD_UVDM_CHARGER_TEMP, + USBPD_UVDM_SESSION_SEED, + USBPD_UVDM_AUTHENTICATION, + USBPD_UVDM_VERIFIED, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + USBPD_UVDM_REMOVE_COMPENSATION, +#endif + USBPD_UVDM_CONNECT, + USBPD_UVDM_NAN_ACK, +}; + +#define USB_PD_MI_SVID 0x2717 +#define USBPD_UVDM_SS_LEN 4 +#define USBPD_UVDM_VERIFIED_LEN 1 + +#define VDM_HDR(svid, cmd0, cmd1) \ + (((svid) << 16) | (0 << 15) | ((cmd0) << 8) \ + | (cmd1)) +#define UVDM_HDR_CMD(hdr) ((hdr) & 0xFF) + +#define USBPD_VDM_RANDOM_NUM 4 +#define USBPD_VDM_REQUEST 0x1 +#define USBPD_ACK 0x2 + +struct usbpd_vdm_data { + int ta_version; + int ta_temp; + int ta_voltage; + unsigned long s_secert[USBPD_UVDM_SS_LEN]; + unsigned long digest[USBPD_UVDM_SS_LEN]; +}; + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define USBPD_WEAK_PPS_POWER 18000000 +#define USBPD_WAKK_PPS_CURR_LIMIT 1500000 + +struct usbpd_pdo { + bool pps; + int type; + int max_volt_mv; + int min_volt_mv; + int curr_ma; + int pos; +}; + +int usbpd_get_pps_status(struct usbpd *pd, u32 *status); +int usbpd_fetch_pdo(struct usbpd *pd, struct usbpd_pdo *pdos); +#endif +#endif + #endif /* _USBPD_H */ From 0f2cbd1182223b14ea1b84a5d7d2df8f633c9e9d Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Sun, 28 Jan 2024 18:59:29 +0100 Subject: [PATCH 095/226] drivers: video: backlight: Import KTZ8866 driver * From nabu-r-oss * Run clang-format on source files Change-Id: I0a0aac3f9b239503bf2d955b57b847b253ab7316 Signed-off-by: firebird11 --- drivers/video/backlight/Kconfig | 6 + drivers/video/backlight/Makefile | 1 + drivers/video/backlight/ktz8866.c | 277 ++++++++++++++++++++++++++ include/linux/platform_data/ktz8866.h | 256 ++++++++++++++++++++++++ 4 files changed, 540 insertions(+) create mode 100644 drivers/video/backlight/ktz8866.c create mode 100644 include/linux/platform_data/ktz8866.h diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 298ce75a2178..53087e6288f4 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -476,6 +476,12 @@ config BACKLIGHT_ARCXCNN If you have an ARCxCnnnn family backlight say Y to enable the backlight driver. +config BACKLIGHT_KTZ8866 + tristate "KTZ8866 Backlight" + depends on I2C + help + If you have a KTZ8866 say Y to enable the backlight driver. + endif # BACKLIGHT_CLASS_DEVICE endif # BACKLIGHT_LCD_SUPPORT diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index f6627e5e2120..fc0487774f7a 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -58,3 +58,4 @@ obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o obj-$(CONFIG_BACKLIGHT_ARCXCNN) += arcxcnn_bl.o +obj-$(CONFIG_BACKLIGHT_KTZ8866) += ktz8866.o diff --git a/drivers/video/backlight/ktz8866.c b/drivers/video/backlight/ktz8866.c new file mode 100644 index 000000000000..b5d574a7e7ce --- /dev/null +++ b/drivers/video/backlight/ktz8866.c @@ -0,0 +1,277 @@ +/* + * KTZ Semiconductor KTZ8866 LED Driver + * + * Copyright (C) 2013 Ideas on board SPRL + * Copyright (C) 2021 XiaoMi, Inc. + * + * Contact: Zhang Teng + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define u8 unsigned char + +struct ktz8866 { + struct i2c_client *client; + struct backlight_device *backlight; + struct ktz8866_platform_data *pdata; +}; + +struct ktz8866 *bd; + +static struct ktz8866_led g_ktz8866_led; + +int ktz8866_read(u8 reg, u8 *data) +{ + int ret; + + ret = i2c_smbus_read_byte_data(bd->client, reg); + if (ret < 0) { + dev_err(&bd->client->dev, "failed reading at 0x%02x\n", reg); + return ret; + } + + *data = (uint8_t)ret; + + return 0; +} +EXPORT_SYMBOL(ktz8866_read); + +int ktz8866_write(u8 reg, u8 data) +{ + return i2c_smbus_write_byte_data(bd->client, reg, data); +} +EXPORT_SYMBOL(ktz8866_write); + +static int ktz8866_backlight_update_status(struct backlight_device *backlight) +{ + //struct ktz8866 *bd = bl_get_data(backlight); + int exponential_bl = backlight->props.brightness; + int brightness = 0; + u8 v[2]; + brightness = bl_level_remap[exponential_bl]; + //brightness = exponential_bl; + + if (brightness < 0 || brightness > BL_LEVEL_MAX || + brightness == g_ktz8866_led.level) + return 0; + + mutex_lock(&g_ktz8866_led.lock); + + dev_warn(&bd->client->dev, + "ktz8866 backlight 0x%02x ,exponential brightness %d \n", + brightness, exponential_bl); + if (!g_ktz8866_led.ktz8866_status && brightness > 0) { + ktz8866_write(KTZ8866_DISP_BL_ENABLE, 0x5f); + g_ktz8866_led.ktz8866_status = 1; + dev_warn(&bd->client->dev, + "ktz8866 backlight enable,dimming close"); + } else if (brightness == 0) { + ktz8866_write(KTZ8866_DISP_BL_ENABLE, 0x1f); + g_ktz8866_led.ktz8866_status = 0; + usleep_range((10 * 1000), (10 * 1000) + 10); + dev_warn(&bd->client->dev, + "ktz8866 backlight disable,dimming close"); + } + v[0] = (brightness >> 3) & 0xff; + v[1] = (brightness - (brightness >> 3) * 8) & 0x7; + + //v[0] = brightness & 0xff; + //v[1] = (brightness >> 8) & 0x7; + + ktz8866_write(KTZ8866_DISP_BB_LSB, v[1]); + ktz8866_write(KTZ8866_DISP_BB_MSB, v[0]); + + if (!g_ktz8866_led.dimming_status) { + usleep_range((5 * 1000), (5 * 1000) + 10); + ktz8866_write(KTZ8866_DISP_BC2, 0xbd); + g_ktz8866_led.dimming_status = 1; + dev_warn(&bd->client->dev, "ktz8866 backlight dimming 128ms"); + } + g_ktz8866_led.level = brightness; + mutex_unlock(&g_ktz8866_led.lock); + return 0; +} + +static int ktz8866_backlight_get_brightness(struct backlight_device *backlight) +{ + //struct ktz8866 *bd = bl_get_data(backlight); + int brightness = backlight->props.brightness; + u8 v[2]; + + ktz8866_read(0x5, &v[0]); + ktz8866_read(0x4, &v[1]); + + brightness = (v[1] << 8) + v[0]; + + return brightness; +} + +static const struct backlight_ops ktz8866_backlight_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = ktz8866_backlight_update_status, + .get_brightness = ktz8866_backlight_get_brightness, +}; + +static int ktz8866_backlight_conf(struct ktz8866 *bd) +{ + int ret, i, reg_count; + u8 read; + + dev_warn(&bd->client->dev, "K81 ktz8866_backlight_conf \n"); + + reg_count = ARRAY_SIZE(ktz8866_regs_conf); + for (i = 0; i < reg_count; i++) { + ret = ktz8866_write(ktz8866_regs_conf[i].reg, + ktz8866_regs_conf[i].value); + ktz8866_read(ktz8866_regs_conf[i].reg, &read); + dev_err(&bd->client->dev, "K81 reading 0x%02x is 0x%02x\n", + ktz8866_regs_conf[i].reg, read); + } + + return ret; +} + +static int parse_dt(struct device *dev, struct ktz8866_platform_data *pdata) +{ + struct device_node *np = dev->of_node; + + pdata->hw_en_gpio = + of_get_named_gpio_flags(np, "ktz8866,hwen-gpio", 0, NULL); + + pdata->enp_gpio = + of_get_named_gpio_flags(np, "ktz8866,enp-gpio", 0, NULL); + + pdata->enn_gpio = + of_get_named_gpio_flags(np, "ktz8866,enn-gpio", 0, NULL); + + return 0; +} + +static int ktz8866_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + //struct ktz8866_platform_data *pdata = dev_get_platdata(&client->dev); + struct backlight_device *backlight; + struct backlight_properties props; + int ret; + u8 read; + + dev_warn(&client->dev, + "ktz8866_probe I2C adapter support I2C_FUNC_SMBUS_BYTE\n"); + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_warn( + &client->dev, + "ktz8866 I2C adapter doesn't support I2C_FUNC_SMBUS_BYTE\n"); + return -EIO; + } + dev_warn( + &client->dev, + "ktz8866 i2c_check_functionality I2C adapter support I2C_FUNC_SMBUS_BYTE\n"); + + bd = devm_kzalloc(&client->dev, sizeof(*bd), GFP_KERNEL); + if (!bd) + return -ENOMEM; + dev_warn(&client->dev, "ktz8866 bd = devm_kzalloc \n"); + + bd->client = client; + + bd->pdata = devm_kzalloc( + &client->dev, sizeof(struct ktz8866_platform_data), GFP_KERNEL); + if (!bd->pdata) + return -ENOMEM; + dev_warn(&client->dev, "bd->pdata = devm_kzalloc \n"); + + memset(&props, 0, sizeof(props)); + props.type = BACKLIGHT_RAW; + props.max_brightness = 2047; + props.brightness = clamp_t(unsigned int, 253, 16, props.max_brightness); + dev_warn(&client->dev, "ktz8866 devm_backlight_device_register \n"); + backlight = devm_backlight_device_register( + &client->dev, dev_name(&client->dev), &bd->client->dev, bd, + &ktz8866_backlight_ops, &props); + if (IS_ERR(backlight)) { + dev_err(&client->dev, "K81 failed to register backlight\n"); + return PTR_ERR(backlight); + } + dev_warn(&client->dev, "ktz8866 backlight_update_status \n"); + backlight_update_status(backlight); + dev_warn(&client->dev, "ktz8866 i2c_set_clientdata \n"); + i2c_set_clientdata(client, backlight); + + parse_dt(&client->dev, bd->pdata); + dev_warn(&client->dev, "ktz8866 parse_dt \n"); + + dev_warn(&client->dev, "ktz8866 ktz8866_probe KTZ8866_LCD_DRV_HW_EN\n"); + ret = devm_gpio_request_one(&client->dev, bd->pdata->hw_en_gpio, + GPIOF_DIR_OUT | GPIOF_INIT_HIGH, "HW_EN"); + if (ret < 0) { + dev_err(&client->dev, "unable to request K81 HW_EN GPIO\n"); + return ret; + } + + dev_warn(&client->dev, "K81 ktz8866_backlight_conf \n"); + ktz8866_backlight_conf(bd); + + ktz8866_read(KTZ8866_DISP_FLAGS, &read); + dev_err(&bd->client->dev, "ktz8866 reading 0x%02x is 0x%02x\n", + KTZ8866_DISP_FLAGS, read); + + return ret; +} + +static int ktz8866_remove(struct i2c_client *client) +{ + struct backlight_device *backlight = i2c_get_clientdata(client); + + backlight->props.brightness = 0; + backlight_update_status(backlight); + + return 0; +} + +static const struct i2c_device_id ktz8866_ids[] = { + { "ktz8866", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, ktz8866_ids); + +static struct of_device_id ktz8866_match_table[] = { + { + .compatible = "ktz,ktz8866", + }, + {}, +}; + +static struct i2c_driver ktz8866_driver = { + .driver = { + .name = "ktz8866", + .owner = THIS_MODULE, + .of_match_table = ktz8866_match_table, + }, + .probe = ktz8866_probe, + .remove = ktz8866_remove, + .id_table = ktz8866_ids, +}; + +module_i2c_driver(ktz8866_driver); + +MODULE_DESCRIPTION("zhangteng3 ktz8866 Backlight Driver"); +MODULE_AUTHOR("Laurent Pinchart "); +MODULE_LICENSE("GPL"); diff --git a/include/linux/platform_data/ktz8866.h b/include/linux/platform_data/ktz8866.h new file mode 100644 index 000000000000..b87ec0250a93 --- /dev/null +++ b/include/linux/platform_data/ktz8866.h @@ -0,0 +1,256 @@ +/* + * ktz8866.h - ktz8866 LEDs Driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __KTZ8866_H__ +#define __KTZ8866_H__ + +struct device; + +struct ktz8866_platform_data { + struct device *fbdev; + int hw_en_gpio; + int enp_gpio; + int enn_gpio; +}; + +/* KTZ8866 backlight I2C driver */ +#define KTZ8866_backlight_EN_MASK 0x40 +#define KTZ8866_backlight_EN_SHIFT 6 +#define KTZ8866_backlight_DISABLE 0 +#define KTZ8866_backlight_ENABLE 1 + +#define KTZ8866_LCD_DRV_HW_EN 27 /* GPIO for Active high hardware enable pin */ +#define KTZ8866_LCD_BIAS_ENP \ + 114 /* GPIO for Enable pin for positive power (OUTP) */ +#define KTZ8866_LCD_BIAS_ENN \ + 115 /* GPIO for Enable pin for negative power (OUTN) */ + +#define KTZ8866_LCD_DRV_I2C_SCL 1 /* I2C Clock pin */ +#define KTZ8866_LCD_DRV_I2C_SDA 0 /* I2C Data pin */ + +#define KTZ8866_DISP_ID 0x01 +#define KTZ8866_DISP_BC1 0x02 +#define KTZ8866_DISP_BC2 0x03 +#define KTZ8866_DISP_BB_LSB 0x04 +#define KTZ8866_DISP_BB_MSB 0x05 +#define KTZ8866_DISP_BL_ENABLE 0x08 +#define KTZ8866_DISP_BIAS_CONF1 0x09 +#define KTZ8866_DISP_BIAS_CONF2 0x0a +#define KTZ8866_DISP_BIAS_CONF3 0x0b +#define KTZ8866_DISP_BIAS_BOOST 0x0c +#define KTZ8866_DISP_BIAS_VPOS 0x0d +#define KTZ8866_DISP_BIAS_VNEG 0x0e +#define KTZ8866_DISP_FLAGS 0x0f +#define KTZ8866_DISP_OPTION1 0x10 +#define KTZ8866_DISP_OPTION2 0x11 +#define KTZ8866_DISP_PTD_LSB 0x12 +#define KTZ8866_DISP_PTD_MSB 0x13 +#define KTZ8866_DISP_DIMMING 0x14 +#define KTZ8866_DISP_FULL_CURRENT 0x15 +#define BL_LEVEL_MAX 2047 + +struct ktz8866_reg { + unsigned char reg; + unsigned char value; +}; + +struct ktz8866_led { + struct mutex lock; + int level; + bool ktz8866_status; + bool dimming_status; +}; + +static struct ktz8866_reg ktz8866_regs_conf[] = { + { KTZ8866_DISP_BB_LSB, 0x00 }, /* LSB: limit I2C code 1360 DBV level*/ + { KTZ8866_DISP_BB_MSB, 0xAA }, /* MSB: limit I2C code 1360 DBV level*/ + { KTZ8866_DISP_BC1, + 0x33 }, /* Backlight OVP 26.4V, exponential mapping*/ + { KTZ8866_DISP_FULL_CURRENT, + 0xb1 }, /* Backlight Full-scale LED Current 23mA*/ + { KTZ8866_DISP_BC2, 0xbd }, /* LED ramping time 128ms*/ + { KTZ8866_DISP_DIMMING, 0x11 }, /* LED on/off ramping time 1ms*/ + { KTZ8866_DISP_BIAS_CONF1, + 0x9f }, /* OUTP and OUTN enabled via pin ENP and ENN*/ + { KTZ8866_DISP_BL_ENABLE, 0x5f }, /* KTZ8866_DISP_BL_ENABLE BL_EN*/ +}; + +const int bl_level_remap[BL_LEVEL_MAX + 1] = { + 0, 17, 17, 31, 40, 54, 107, 132, 163, 186, 213, 222, + 241, 260, 279, 300, 321, 330, 349, 365, 379, 395, 408, 419, + 430, 440, 449, 458, 466, 485, 507, 525, 540, 558, 573, 583, + 594, 607, 621, 635, 646, 659, 669, 676, 681, 690, 703, 711, + 720, 728, 738, 746, 751, 759, 768, 775, 783, 789, 797, 804, + 810, 815, 821, 830, 835, 842, 847, 852, 859, 862, 868, 874, + 879, 886, 891, 897, 902, 911, 916, 921, 926, 930, 936, 940, + 944, 948, 952, 957, 962, 966, 970, 974, 978, 980, 984, 988, + 992, 996, 1000, 1004, 1008, 1011, 1014, 1018, 1022, 1025, 1029, 1032, + 1035, 1038, 1040, 1041, 1044, 1048, 1051, 1054, 1057, 1061, 1063, 1065, + 1068, 1071, 1075, 1078, 1081, 1084, 1087, 1090, 1091, 1094, 1096, 1099, + 1102, 1105, 1107, 1108, 1111, 1114, 1117, 1120, 1122, 1124, 1127, 1130, + 1132, 1135, 1138, 1140, 1142, 1146, 1148, 1151, 1153, 1154, 1156, 1159, + 1161, 1163, 1165, 1168, 1170, 1172, 1173, 1176, 1178, 1180, 1182, 1185, + 1187, 1189, 1190, 1193, 1195, 1197, 1199, 1202, 1204, 1206, 1208, 1209, + 1211, 1213, 1215, 1217, 1219, 1221, 1222, 1224, 1225, 1227, 1228, 1230, + 1232, 1234, 1236, 1237, 1238, 1240, 1242, 1243, 1245, 1247, 1249, 1251, + 1252, 1253, 1255, 1256, 1258, 1260, 1262, 1263, 1265, 1268, 1270, 1272, + 1274, 1275, 1276, 1279, 1280, 1282, 1283, 1284, 1286, 1287, 1289, 1290, + 1292, 1293, 1294, 1296, 1297, 1299, 1300, 1302, 1303, 1304, 1305, 1307, + 1308, 1310, 1311, 1313, 1314, 1316, 1317, 1318, 1319, 1321, 1322, 1323, + 1325, 1326, 1328, 1329, 1330, 1332, 1334, 1335, 1337, 1338, 1339, 1341, + 1342, 1343, 1345, 1346, 1347, 1348, 1349, 1351, 1352, 1353, 1354, 1355, + 1356, 1357, 1358, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, + 1369, 1370, 1371, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, + 1382, 1383, 1384, 1385, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1395, + 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, + 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, 1419, + 1420, 1421, 1422, 1423, 1424, 1425, 1426, 1427, 1428, 1429, 1430, 1431, + 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443, + 1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455, + 1456, 1457, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1466, + 1467, 1467, 1468, 1469, 1470, 1471, 1471, 1472, 1473, 1473, 1474, 1475, + 1476, 1477, 1478, 1479, 1480, 1481, 1481, 1482, 1483, 1484, 1484, 1485, + 1486, 1487, 1488, 1489, 1490, 1490, 1491, 1492, 1493, 1494, 1495, 1496, + 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, + 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, + 1521, 1522, 1523, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1525, + 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, + 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, + 1550, 1551, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, + 1552, 1552, 1552, 1553, 1554, 1554, 1555, 1556, 1556, 1557, 1557, 1558, + 1559, 1559, 1560, 1561, 1562, 1562, 1563, 1564, 1564, 1565, 1565, 1566, + 1566, 1567, 1567, 1567, 1568, 1569, 1569, 1570, 1571, 1572, 1572, 1573, + 1574, 1574, 1575, 1575, 1576, 1577, 1578, 1578, 1579, 1580, 1581, 1582, + 1583, 1584, 1585, 1585, 1586, 1586, 1587, 1587, 1588, 1588, 1588, 1588, + 1589, 1589, 1589, 1589, 1590, 1590, 1590, 1590, 1591, 1592, 1593, 1593, + 1594, 1595, 1596, 1596, 1597, 1597, 1598, 1598, 1599, 1599, 1600, 1600, + 1601, 1602, 1603, 1603, 1604, 1604, 1605, 1605, 1606, 1606, 1607, 1607, + 1608, 1608, 1609, 1609, 1610, 1610, 1611, 1611, 1612, 1612, 1613, 1613, + 1614, 1615, 1615, 1616, 1617, 1617, 1618, 1618, 1619, 1619, 1620, 1620, + 1621, 1621, 1622, 1622, 1623, 1624, 1625, 1626, 1627, 1627, 1628, 1628, + 1629, 1629, 1630, 1630, 1631, 1631, 1632, 1632, 1633, 1633, 1634, 1634, + 1635, 1635, 1636, 1636, 1637, 1638, 1638, 1639, 1640, 1640, 1641, 1641, + 1642, 1642, 1643, 1643, 1644, 1644, 1645, 1645, 1646, 1647, 1647, 1648, + 1648, 1649, 1649, 1650, 1650, 1651, 1651, 1652, 1653, 1653, 1654, 1654, + 1655, 1656, 1656, 1657, 1657, 1658, 1658, 1659, 1659, 1660, 1660, 1661, + 1662, 1662, 1663, 1663, 1664, 1664, 1664, 1665, 1665, 1665, 1666, 1666, + 1667, 1667, 1668, 1668, 1669, 1669, 1670, 1670, 1671, 1671, 1672, 1672, + 1673, 1673, 1674, 1674, 1675, 1675, 1676, 1676, 1676, 1677, 1677, 1678, + 1678, 1679, 1679, 1679, 1680, 1680, 1681, 1681, 1682, 1682, 1683, 1683, + 1684, 1684, 1685, 1685, 1686, 1686, 1686, 1686, 1687, 1687, 1687, 1688, + 1688, 1689, 1689, 1690, 1690, 1691, 1692, 1693, 1693, 1694, 1694, 1695, + 1695, 1696, 1696, 1697, 1697, 1698, 1698, 1699, 1699, 1700, 1700, 1701, + 1701, 1701, 1702, 1702, 1702, 1703, 1703, 1704, 1704, 1705, 1705, 1706, + 1706, 1707, 1707, 1708, 1708, 1709, 1709, 1710, 1710, 1710, 1711, 1711, + 1711, 1712, 1712, 1713, 1713, 1714, 1714, 1715, 1715, 1716, 1716, 1717, + 1717, 1718, 1718, 1719, 1719, 1720, 1720, 1721, 1721, 1722, 1722, 1723, + 1723, 1724, 1724, 1724, 1724, 1725, 1725, 1725, 1726, 1726, 1726, 1727, + 1727, 1728, 1728, 1729, 1729, 1730, 1730, 1730, 1731, 1731, 1732, 1732, + 1732, 1733, 1733, 1733, 1734, 1734, 1734, 1735, 1735, 1736, 1736, 1736, + 1736, 1737, 1737, 1738, 1738, 1739, 1739, 1739, 1740, 1740, 1740, 1741, + 1741, 1741, 1742, 1742, 1743, 1743, 1743, 1744, 1744, 1744, 1745, 1745, + 1746, 1747, 1747, 1748, 1748, 1749, 1749, 1749, 1750, 1750, 1751, 1751, + 1751, 1752, 1752, 1752, 1752, 1753, 1753, 1754, 1754, 1755, 1755, 1756, + 1756, 1756, 1757, 1757, 1757, 1758, 1758, 1759, 1759, 1760, 1760, 1761, + 1761, 1761, 1762, 1762, 1762, 1763, 1763, 1763, 1764, 1764, 1765, 1765, + 1765, 1766, 1766, 1766, 1766, 1767, 1767, 1767, 1767, 1768, 1768, 1769, + 1769, 1770, 1770, 1770, 1771, 1771, 1771, 1772, 1772, 1772, 1773, 1773, + 1773, 1774, 1774, 1775, 1775, 1776, 1776, 1776, 1776, 1777, 1777, 1777, + 1778, 1778, 1778, 1779, 1779, 1779, 1780, 1780, 1781, 1781, 1782, 1782, + 1782, 1783, 1783, 1784, 1784, 1784, 1785, 1785, 1786, 1786, 1787, 1787, + 1788, 1788, 1789, 1789, 1789, 1789, 1790, 1790, 1791, 1791, 1792, 1792, + 1792, 1792, 1793, 1793, 1793, 1793, 1794, 1794, 1794, 1794, 1795, 1795, + 1796, 1796, 1796, 1797, 1797, 1798, 1798, 1799, 1799, 1799, 1800, 1800, + 1800, 1800, 1801, 1801, 1801, 1801, 1802, 1802, 1802, 1803, 1803, 1804, + 1804, 1804, 1805, 1805, 1805, 1805, 1806, 1806, 1806, 1806, 1807, 1807, + 1807, 1807, 1808, 1808, 1809, 1809, 1810, 1810, 1810, 1810, 1811, 1811, + 1811, 1811, 1812, 1812, 1813, 1813, 1814, 1814, 1814, 1814, 1815, 1815, + 1815, 1815, 1815, 1815, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, + 1816, 1816, 1817, 1817, 1817, 1817, 1818, 1818, 1818, 1818, 1819, 1819, + 1819, 1819, 1820, 1820, 1820, 1820, 1821, 1821, 1822, 1822, 1822, 1823, + 1823, 1823, 1824, 1824, 1824, 1824, 1825, 1825, 1825, 1825, 1826, 1826, + 1826, 1826, 1827, 1827, 1828, 1828, 1829, 1829, 1829, 1829, 1830, 1830, + 1830, 1831, 1831, 1832, 1832, 1832, 1833, 1833, 1833, 1833, 1834, 1834, + 1834, 1835, 1835, 1835, 1836, 1836, 1837, 1837, 1837, 1837, 1838, 1838, + 1838, 1838, 1839, 1839, 1840, 1840, 1841, 1841, 1841, 1841, 1842, 1842, + 1842, 1842, 1843, 1843, 1843, 1843, 1844, 1844, 1845, 1845, 1846, 1846, + 1846, 1846, 1847, 1847, 1847, 1848, 1848, 1849, 1849, 1849, 1850, 1850, + 1850, 1850, 1850, 1851, 1851, 1851, 1851, 1852, 1852, 1852, 1853, 1853, + 1854, 1854, 1854, 1855, 1855, 1855, 1855, 1856, 1856, 1856, 1856, 1857, + 1857, 1857, 1857, 1858, 1858, 1858, 1858, 1859, 1859, 1859, 1859, 1860, + 1860, 1861, 1861, 1862, 1862, 1862, 1862, 1863, 1863, 1863, 1863, 1864, + 1864, 1864, 1864, 1865, 1865, 1865, 1865, 1866, 1866, 1866, 1866, 1867, + 1867, 1867, 1867, 1868, 1868, 1868, 1868, 1869, 1869, 1869, 1869, 1870, + 1870, 1870, 1870, 1871, 1871, 1871, 1871, 1872, 1872, 1873, 1873, 1874, + 1874, 1874, 1874, 1875, 1875, 1875, 1875, 1876, 1876, 1876, 1876, 1877, + 1877, 1877, 1877, 1878, 1878, 1878, 1878, 1879, 1879, 1880, 1880, 1881, + 1881, 1881, 1881, 1882, 1882, 1882, 1882, 1883, 1883, 1883, 1883, 1884, + 1884, 1884, 1884, 1885, 1885, 1885, 1885, 1886, 1886, 1886, 1886, 1887, + 1887, 1887, 1887, 1888, 1888, 1888, 1888, 1889, 1889, 1889, 1889, 1890, + 1890, 1890, 1890, 1891, 1891, 1891, 1891, 1892, 1892, 1892, 1893, 1893, + 1893, 1894, 1894, 1895, 1895, 1895, 1895, 1896, 1896, 1896, 1896, 1897, + 1897, 1897, 1897, 1898, 1898, 1898, 1898, 1899, 1899, 1899, 1899, 1900, + 1900, 1900, 1900, 1901, 1901, 1901, 1901, 1902, 1902, 1902, 1902, 1903, + 1903, 1903, 1904, 1904, 1904, 1905, 1905, 1906, 1906, 1906, 1906, 1907, + 1907, 1907, 1907, 1908, 1908, 1908, 1908, 1909, 1909, 1909, 1909, 1910, + 1910, 1910, 1910, 1911, 1911, 1911, 1912, 1912, 1913, 1913, 1913, 1914, + 1914, 1914, 1914, 1914, 1915, 1915, 1915, 1915, 1916, 1916, 1916, 1916, + 1917, 1917, 1917, 1917, 1918, 1918, 1918, 1918, 1919, 1919, 1919, 1919, + 1920, 1920, 1920, 1920, 1921, 1921, 1921, 1921, 1922, 1922, 1922, 1922, + 1923, 1923, 1923, 1923, 1924, 1924, 1924, 1924, 1925, 1925, 1925, 1925, + 1925, 1925, 1925, 1925, 1926, 1926, 1926, 1926, 1927, 1927, 1927, 1927, + 1928, 1928, 1928, 1928, 1929, 1929, 1929, 1929, 1930, 1930, 1930, 1930, + 1931, 1931, 1931, 1931, 1932, 1932, 1932, 1932, 1933, 1933, 1933, 1933, + 1934, 1934, 1934, 1934, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, + 1936, 1936, 1936, 1936, 1937, 1937, 1937, 1937, 1938, 1938, 1938, 1939, + 1939, 1939, 1939, 1939, 1940, 1940, 1940, 1940, 1941, 1941, 1941, 1941, + 1942, 1942, 1942, 1942, 1943, 1943, 1943, 1943, 1944, 1944, 1944, 1944, + 1945, 1945, 1945, 1945, 1946, 1946, 1946, 1946, 1947, 1947, 1947, 1947, + 1948, 1948, 1948, 1948, 1949, 1949, 1949, 1949, 1950, 1950, 1950, 1950, + 1950, 1950, 1950, 1950, 1951, 1951, 1951, 1951, 1952, 1952, 1952, 1952, + 1952, 1952, 1952, 1952, 1953, 1953, 1953, 1953, 1954, 1954, 1954, 1954, + 1955, 1955, 1955, 1955, 1956, 1956, 1956, 1956, 1957, 1957, 1957, 1957, + 1958, 1958, 1958, 1958, 1959, 1959, 1959, 1959, 1960, 1960, 1960, 1960, + 1961, 1961, 1961, 1961, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, + 1963, 1963, 1963, 1963, 1964, 1964, 1964, 1964, 1965, 1965, 1965, 1965, + 1965, 1966, 1966, 1966, 1966, 1967, 1967, 1967, 1967, 1968, 1968, 1968, + 1968, 1969, 1969, 1969, 1969, 1970, 1970, 1970, 1970, 1971, 1971, 1971, + 1971, 1972, 1972, 1972, 1972, 1973, 1973, 1973, 1973, 1974, 1974, 1974, + 1974, 1975, 1975, 1975, 1975, 1976, 1976, 1976, 1976, 1977, 1977, 1977, + 1977, 1978, 1978, 1978, 1978, 1979, 1979, 1979, 1979, 1980, 1980, 1980, + 1980, 1981, 1981, 1981, 1981, 1982, 1982, 1982, 1982, 1983, 1983, 1983, + 1983, 1983, 1983, 1983, 1983, 1984, 1984, 1984, 1984, 1985, 1985, 1985, + 1985, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1987, 1987, 1987, + 1987, 1988, 1988, 1988, 1988, 1989, 1989, 1989, 1989, 1989, 1989, 1989, + 1989, 1990, 1990, 1990, 1990, 1991, 1991, 1991, 1991, 1992, 1992, 1992, + 1992, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, + 1993, 1995, 1995, 1995, 1995, 1996, 1996, 1996, 1996, 1996, 1996, 1996, + 1996, 1997, 1997, 1997, 1997, 1998, 1998, 1998, 1998, 1999, 1999, 1999, + 1999, 1999, 1999, 1999, 1999, 2000, 2000, 2000, 2000, 2001, 2001, 2001, + 2001, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2003, 2003, 2003, + 2003, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2005, 2005, 2005, + 2005, 2006, 2006, 2006, 2006, 2006, 2007, 2007, 2007, 2008, 2008, 2008, + 2008, 2008, 2008, 2008, 2008, 2009, 2009, 2009, 2009, 2010, 2010, 2010, + 2010, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2012, 2012, + 2012, 2012, 2013, 2013, 2013, 2013, 2014, 2014, 2014, 2014, 2015, 2015, + 2015, 2015, 2015, 2015, 2015, 2015, 2016, 2016, 2016, 2016, 2017, 2017, + 2017, 2017, 2018, 2018, 2018, 2018, 2019, 2019, 2019, 2019, 2019, 2019, + 2019, 2019, 2020, 2020, 2020, 2020, 2021, 2021, 2021, 2021, 2021, 2021, + 2021, 2021, 2022, 2022, 2022, 2022, 2023, 2023, 2023, 2023, 2024, 2024, + 2024, 2024, 2025, 2025, 2025, 2025, 2026, 2026, 2026, 2026, 2027, 2027, + 2027, 2027, 2027, 2027, 2027, 2027, 2028, 2028, 2028, 2028, 2029, 2029, + 2029, 2029, 2029, 2029, 2029, 2029, 2030, 2030, 2030, 2030, 2031, 2031, + 2031, 2031, 2032, 2032, 2032, 2032, 2032, 2032, 2033, 2033, 2033, 2033, + 2033, 2033, 2034, 2034, 2034, 2034, 2035, 2035, 2035, 2035, 2036, 2036, + 2036, 2036, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2038, 2038, + 2038, 2038, 2039, 2039, 2039, 2039, 2039, 2040, 2040, 2040, 2040, 2040, + 2040, 2041, 2041, 2041, 2041, 2041, 2042, 2042, 2042, 2042, 2042, 2042, + 2042, 2043, 2043, 2043, 2043, 2044, 2044, 2044, 2044, 2045, 2045, 2045, + 2045, 2045, 2046, 2046, 2046, 2047, 2047, 2047 +}; + +#endif From 190ffe45b693c9bbd8401914b86af9333197d66d Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:46:43 +0200 Subject: [PATCH 096/226] drivers: video: backlight: Import Xiaomi changes Change-Id: I0b3488cc6d49d4a9b3cbcaa699489e608e685713 Signed-off-by: firebird11 --- drivers/video/backlight/backlight.c | 12 ++++++++++++ include/linux/backlight.h | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 8c835f16af82..361e7e5118bf 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -24,6 +24,9 @@ static struct list_head backlight_dev_list; static struct mutex backlight_dev_list_mutex; static struct blocking_notifier_head backlight_notifier; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static int bl_event; +#endif static const char *const backlight_types[] = { [BACKLIGHT_RAW] = "raw", @@ -181,6 +184,15 @@ int backlight_device_set_brightness(struct backlight_device *bd, rc = -EINVAL; else { pr_debug("set brightness to %lu\n", brightness); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (!brightness) { + bl_event = BACKLIGHT_OFF; + blocking_notifier_call_chain(&backlight_notifier, BACKLIGHT_UPDATED, &bl_event); + } else if (bl_event != BACKLIGHT_ON) { + bl_event = BACKLIGHT_ON; + blocking_notifier_call_chain(&backlight_notifier, BACKLIGHT_UPDATED, &bl_event); + } +#endif bd->props.brightness = brightness; rc = backlight_update_status(bd); } diff --git a/include/linux/backlight.h b/include/linux/backlight.h index 16f02e0718b4..f6abdbd274db 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h @@ -45,7 +45,17 @@ enum backlight_type { enum backlight_notification { BACKLIGHT_REGISTERED, BACKLIGHT_UNREGISTERED, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + BACKLIGHT_UPDATED, +#endif +}; + +#ifdef CONFIG_MACH_XIAOMI_SM8150 +enum backlight_brightness { + BACKLIGHT_OFF, + BACKLIGHT_ON, }; +#endif struct backlight_device; struct fb_info; From 754b5b749942a688377d9fa9c415d68c65909b8c Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:47:55 +0200 Subject: [PATCH 097/226] fs: pstore: Import Xiaomi changes Change-Id: Icde2a6c8842c67dc8a0c7240069b07d66b149000 Signed-off-by: firebird11 --- fs/pstore/Kconfig | 8 ++++++++ fs/pstore/inode.c | 39 ++++++++++++++++++++++++++++++++++++++ fs/pstore/ram.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig index 144e5027fe84..45d5f7f99456 100644 --- a/fs/pstore/Kconfig +++ b/fs/pstore/Kconfig @@ -88,3 +88,11 @@ config PSTORE_RAM "ramoops.ko". For more information, see Documentation/admin-guide/ramoops.rst. + +config PSTORE_LAST_KMSG + bool "export /proc/last_kmsg" + default n + depends on PSTORE + help + When the option is enabled, pstore will export a proc filesystem + interface /proc/last_kmsg. diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index d814723fb27d..7f3a0f077006 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c @@ -36,6 +36,9 @@ #include #include #include +#ifdef CONFIG_PSTORE_LAST_KMSG +#include +#endif #include "internal.h" @@ -294,6 +297,24 @@ bool pstore_is_mounted(void) return pstore_sb != NULL; } +#ifdef CONFIG_PSTORE_LAST_KMSG +static char *console_buffer; +static ssize_t console_bufsize; + +static ssize_t last_kmsg_read(struct file *file, char __user *buf, + size_t len, loff_t *offset) +{ + return simple_read_from_buffer(buf, len, offset, + console_buffer, console_bufsize); +} + +static const struct file_operations last_kmsg_fops = { + .owner = THIS_MODULE, + .read = last_kmsg_read, + .llseek = default_llseek, +}; +#endif + /* * Make a regular file in the root directory of our file system. * Load it up with "size" bytes of data from "buf". @@ -400,6 +421,13 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record) list_add(&private->list, &allpstore); spin_unlock_irqrestore(&allpstore_lock, flags); +#ifdef CONFIG_PSTORE_LAST_KMSG + if (record->type == PSTORE_TYPE_CONSOLE) { + console_buffer = private->record->buf; + console_bufsize = size; + } +#endif + return 0; fail_private: @@ -485,6 +513,9 @@ static struct file_system_type pstore_fs_type = { static int __init init_pstore_fs(void) { int err; +#ifdef CONFIG_PSTORE_LAST_KMSG + struct proc_dir_entry *last_kmsg_entry = NULL; +#endif /* Create a convenient mount point for people to access pstore */ err = sysfs_create_mount_point(fs_kobj, "pstore"); @@ -495,6 +526,14 @@ static int __init init_pstore_fs(void) if (err < 0) sysfs_remove_mount_point(fs_kobj, "pstore"); +#ifdef CONFIG_PSTORE_LAST_KMSG + last_kmsg_entry = proc_create_data("last_kmsg", S_IFREG | S_IRUGO, + NULL, &last_kmsg_fops, NULL); + if (!last_kmsg_entry) { + pr_err("Failed to create last_kmsg\n"); + goto out; + } +#endif out: return err; } diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 73aa3c297701..d9bebdd2a922 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -35,6 +35,9 @@ #include #include #include +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#include +#endif #define RAMOOPS_KERNMSG_HDR "====" #define MIN_MEM_SIZE 4096UL @@ -963,6 +966,51 @@ static void ramoops_register_dummy(void) } } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static struct ramoops_platform_data ramoops_data; + +static struct platform_device ramoops_dev = { + .name = "ramoops", + .dev = { + .platform_data = &ramoops_data, + }, +}; + +static int __init ramoops_memreserve(char *p) +{ + unsigned long size; + + if (!p) + return 1; + + size = memparse(p, &p) & PAGE_MASK; + ramoops_data.mem_size = size; + ramoops_data.mem_address = 0xB0000000; + ramoops_data.console_size = size / 2; + ramoops_data.pmsg_size = size / 2; + ramoops_data.dump_oops = 1; + + pr_info("msm_reserve_ramoops_memory addr=%llx,size=%lx\n", + ramoops_data.mem_address, ramoops_data.mem_size); + pr_info("msm_reserve_ramoops_memory record_size=%lx,ftrace_size=%lx\n", + ramoops_data.record_size, ramoops_data.ftrace_size); + + memblock_reserve(ramoops_data.mem_address, ramoops_data.mem_size); + + return 0; +} +early_param("ramoops_memreserve", ramoops_memreserve); + +static int __init msm_register_ramoops_device(void) +{ + pr_info("msm_register_ramoops_device\n"); + if (platform_device_register(&ramoops_dev)) + pr_info("Unable to register ramoops platform device\n"); + return 0; +} +core_initcall(msm_register_ramoops_device); +#endif + static int __init ramoops_init(void) { ramoops_register_dummy(); From 9bd7dae8e7496b3b2a773551980b4f1207d09cb0 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 22 Jun 2022 19:55:32 +0200 Subject: [PATCH 098/226] sound: soc: Import Xiaomi changes Change-Id: If6a6823c3d84e95330c37b0bd125e80328f03ebd Signed-off-by: firebird11 --- sound/soc/soc-pcm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index be75e3fe5e4e..097b987d5ad5 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -46,6 +46,10 @@ static const struct snd_pcm_hardware no_host_hardware = { SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, .formats = SNDRV_PCM_FMTBIT_S16_LE | +#ifdef CONFIG_MACH_XIAOMI_SM8150 + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | +#endif SNDRV_PCM_FMTBIT_S32_LE, .period_bytes_min = PAGE_SIZE >> 2, .period_bytes_max = PAGE_SIZE >> 1, From cd69b16991cf3b1ff82f4f6d66b7b0cdc801e899 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 6 Nov 2023 12:57:40 +0100 Subject: [PATCH 099/226] techpack: audio: Allow ASoC codecs selection through Kconfig * Not every device may want all the additional codecs from OEM, especially on common kernel sources with a lot of codecs Change-Id: I1521f714c90e74f1f674495bee312e28e55cf87a Signed-off-by: firebird11 --- techpack/Kconfig | 2 ++ techpack/audio/Kconfig | 2 ++ techpack/audio/asoc/Kconfig | 1 + techpack/audio/asoc/codecs/Kconfig | 3 +++ techpack/audio/dsp/Kconfig | 3 +++ 5 files changed, 11 insertions(+) create mode 100644 techpack/audio/Kconfig create mode 100644 techpack/audio/asoc/Kconfig create mode 100644 techpack/audio/asoc/codecs/Kconfig create mode 100644 techpack/audio/dsp/Kconfig diff --git a/techpack/Kconfig b/techpack/Kconfig index b3c5013ad893..9f07eebc0410 100644 --- a/techpack/Kconfig +++ b/techpack/Kconfig @@ -1,5 +1,7 @@ menu "Tech packages" +source "techpack/audio/Kconfig" + source "techpack/data/Kconfig" endmenu diff --git a/techpack/audio/Kconfig b/techpack/audio/Kconfig new file mode 100644 index 000000000000..0fd02b6a725d --- /dev/null +++ b/techpack/audio/Kconfig @@ -0,0 +1,2 @@ +source "techpack/audio/asoc/Kconfig" +source "techpack/audio/dsp/Kconfig" diff --git a/techpack/audio/asoc/Kconfig b/techpack/audio/asoc/Kconfig new file mode 100644 index 000000000000..335df2d0d6b7 --- /dev/null +++ b/techpack/audio/asoc/Kconfig @@ -0,0 +1 @@ +source "techpack/audio/asoc/codecs/Kconfig" diff --git a/techpack/audio/asoc/codecs/Kconfig b/techpack/audio/asoc/codecs/Kconfig new file mode 100644 index 000000000000..6fbac4e91012 --- /dev/null +++ b/techpack/audio/asoc/codecs/Kconfig @@ -0,0 +1,3 @@ +menu "Qualcomm ASoC additional codecs" + +endmenu diff --git a/techpack/audio/dsp/Kconfig b/techpack/audio/dsp/Kconfig new file mode 100644 index 000000000000..9d6601d1e644 --- /dev/null +++ b/techpack/audio/dsp/Kconfig @@ -0,0 +1,3 @@ +menu "Qualcomm DSP" + +endmenu From 3ef25e49260a4d1e4cbf6c26e07030296a23ea38 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 7 Jul 2021 16:30:41 +0200 Subject: [PATCH 100/226] techpack: audio: Import Xiaomi drivers * cs35l41: From cepheus-q-oss * tas2557: From cepheus-q-oss * tfa98xx: From cepheus-q-oss * cirrus: From cepheus-q-oss * elliptic: From cepheus-q-oss * mius: From cepheus-q-oss * tas256x: From vayu-r-oss * cs35l41_v2: From nabu-r-oss * Run clang-format on source files Change-Id: If9f9dd884f924ef31d01623f11144134b2c8c206 Signed-off-by: firebird11 --- techpack/audio/Makefile | 8 + techpack/audio/asoc/codecs/Kbuild | 5 + techpack/audio/asoc/codecs/Kconfig | 6 + techpack/audio/asoc/codecs/cs35l41/Android.mk | 55 + techpack/audio/asoc/codecs/cs35l41/Kbuild | 114 + techpack/audio/asoc/codecs/cs35l41/Kconfig | 5 + techpack/audio/asoc/codecs/cs35l41/Makefile | 433 ++ .../audio/asoc/codecs/cs35l41/cs35l41-i2c.c | 123 + .../audio/asoc/codecs/cs35l41/cs35l41-spi.c | 113 + .../asoc/codecs/cs35l41/cs35l41-tables.c | 946 +++ techpack/audio/asoc/codecs/cs35l41/cs35l41.c | 2015 +++++++ techpack/audio/asoc/codecs/cs35l41/cs35l41.h | 766 +++ .../audio/asoc/codecs/cs35l41/cs35l41.txt | 184 + techpack/audio/asoc/codecs/cs35l41/wm_adsp.c | 5106 ++++++++++++++++ techpack/audio/asoc/codecs/cs35l41/wm_adsp.h | 208 + techpack/audio/asoc/codecs/cs35l41/wmfw.h | 202 + .../audio/asoc/codecs/cs35l41_v2/Android.mk | 55 + techpack/audio/asoc/codecs/cs35l41_v2/Kbuild | 125 + techpack/audio/asoc/codecs/cs35l41_v2/Kconfig | 5 + .../asoc/codecs/cs35l41_v2/cs35l41-i2c.c | 121 + .../asoc/codecs/cs35l41_v2/cs35l41-spi.c | 112 + .../asoc/codecs/cs35l41_v2/cs35l41-tables.c | 997 ++++ .../audio/asoc/codecs/cs35l41_v2/cs35l41.c | 3831 ++++++++++++ .../audio/asoc/codecs/cs35l41_v2/cs35l41.h | 842 +++ .../audio/asoc/codecs/cs35l41_v2/cs35l41.txt | 255 + .../codecs/cs35l41_v2/send_data_to_xlog.c | 49 + .../codecs/cs35l41_v2/send_data_to_xlog.h | 26 + .../audio/asoc/codecs/cs35l41_v2/wm_adsp.c | 5167 +++++++++++++++++ .../audio/asoc/codecs/cs35l41_v2/wm_adsp.h | 244 + techpack/audio/asoc/codecs/cs35l41_v2/wmfw.h | 223 + techpack/audio/asoc/codecs/tas2557/Android.mk | 55 + techpack/audio/asoc/codecs/tas2557/Kbuild | 115 + techpack/audio/asoc/codecs/tas2557/Kconfig | 23 + .../audio/asoc/codecs/tas2557/tas2557-codec.c | 673 +++ .../audio/asoc/codecs/tas2557/tas2557-codec.h | 31 + .../audio/asoc/codecs/tas2557/tas2557-core.c | 2397 ++++++++ .../audio/asoc/codecs/tas2557/tas2557-core.h | 86 + .../audio/asoc/codecs/tas2557/tas2557-misc.c | 702 +++ .../audio/asoc/codecs/tas2557/tas2557-misc.h | 60 + .../asoc/codecs/tas2557/tas2557-regmap.c | 964 +++ techpack/audio/asoc/codecs/tas2557/tas2557.h | 485 ++ techpack/audio/asoc/codecs/tas2557/tiload.c | 447 ++ techpack/audio/asoc/codecs/tas2557/tiload.h | 66 + techpack/audio/asoc/codecs/tas256x/Android.mk | 55 + techpack/audio/asoc/codecs/tas256x/Kbuild | 116 + techpack/audio/asoc/codecs/tas256x/Kconfig | 23 + techpack/audio/asoc/codecs/tas256x/Makefile | 9 + techpack/audio/asoc/codecs/tas256x/tas2562.h | 731 +++ techpack/audio/asoc/codecs/tas256x/tas2564.h | 718 +++ .../audio/asoc/codecs/tas256x/tas256x-codec.c | 1956 +++++++ .../audio/asoc/codecs/tas256x/tas256x-codec.h | 33 + .../asoc/codecs/tas256x/tas256x-device.h | 152 + .../asoc/codecs/tas256x/tas256x-regmap.c | 1931 ++++++ techpack/audio/asoc/codecs/tas256x/tas256x.c | 1557 +++++ techpack/audio/asoc/codecs/tas256x/tas256x.h | 647 +++ .../audio/asoc/codecs/tas256x/tas25xx-algo.c | 995 ++++ .../audio/asoc/codecs/tas256x/tas25xx-calib.c | 202 + .../audio/asoc/codecs/tas256x/tas25xx-calib.h | 29 + techpack/audio/asoc/codecs/tfa98xx/Android.mk | 55 + techpack/audio/asoc/codecs/tfa98xx/Kbuild | 120 + techpack/audio/asoc/codecs/tfa98xx/Kconfig | 5 + .../audio/asoc/codecs/tfa98xx/inc/config.h | 44 + .../audio/asoc/codecs/tfa98xx/inc/dbgprint.h | 200 + .../audio/asoc/codecs/tfa98xx/inc/spk-id.h | 33 + techpack/audio/asoc/codecs/tfa98xx/inc/tfa.h | 57 + .../codecs/tfa98xx/inc/tfa1_tfafieldnames.h | 1705 ++++++ .../tfa98xx/inc/tfa2_tfafieldnames_N1C.h | 2930 ++++++++++ .../tfa98xx/inc/tfa9872_tfafieldnames.h | 2312 ++++++++ .../tfa98xx/inc/tfa9874_tfafieldnames.h | 1612 +++++ .../tfa98xx/inc/tfa9887_tfafieldnames.h | 109 + .../tfa98xx/inc/tfa9890_tfafieldnames.h | 140 + .../asoc/codecs/tfa98xx/inc/tfa9891_genregs.h | 1099 ++++ .../tfa98xx/inc/tfa9891_tfafieldnames.h | 1000 ++++ .../tfa98xx/inc/tfa9894_tfafieldnames.h | 2102 +++++++ .../tfa98xx/inc/tfa9896_tfafieldnames.h | 1732 ++++++ .../audio/asoc/codecs/tfa98xx/inc/tfa98xx.h | 189 + .../codecs/tfa98xx/inc/tfa98xx_genregs_N1C.h | 3795 ++++++++++++ .../codecs/tfa98xx/inc/tfa98xx_parameters.h | 744 +++ .../tfa98xx/inc/tfa98xx_tfafieldnames.h | 149 + .../tfa98xx/inc/tfa9912_tfafieldnames.h | 3384 +++++++++++ .../asoc/codecs/tfa98xx/inc/tfa_container.h | 379 ++ .../asoc/codecs/tfa98xx/inc/tfa_device.h | 343 ++ .../asoc/codecs/tfa98xx/inc/tfa_dsp_fw.h | 169 + .../audio/asoc/codecs/tfa98xx/inc/tfa_ext.h | 64 + .../asoc/codecs/tfa98xx/inc/tfa_internal.h | 41 + .../inc/tfa_platform_interface_definition.h | 97 + .../asoc/codecs/tfa98xx/inc/tfa_service.h | 1057 ++++ .../audio/asoc/codecs/tfa98xx/inc/versions.h | 4 + .../audio/asoc/codecs/tfa98xx/src/tfa98xx.c | 4412 ++++++++++++++ .../asoc/codecs/tfa98xx/src/tfa_container.c | 2570 ++++++++ .../audio/asoc/codecs/tfa98xx/src/tfa_debug.c | 439 ++ .../audio/asoc/codecs/tfa98xx/src/tfa_dsp.c | 4165 +++++++++++++ .../audio/asoc/codecs/tfa98xx/src/tfa_init.c | 1727 ++++++ techpack/audio/dsp/Kbuild | 26 + techpack/audio/dsp/Kconfig | 10 + techpack/audio/dsp/apr_elliptic.c | 435 ++ techpack/audio/dsp/apr_mius.c | 464 ++ techpack/audio/dsp/elliptic/Makefile | 28 + techpack/audio/dsp/elliptic/elliptic.c | 776 +++ .../dsp/elliptic/elliptic_mixer_controls.c | 1367 +++++ techpack/audio/dsp/elliptic/elliptic_sysfs.c | 648 +++ .../audio/dsp/elliptic/elliptic_version.h | 8 + .../audio/dsp/elliptic/io_modules/Makefile | 2 + .../io_modules/msm/elliptic_data_msm_io.c | 105 + .../elliptic/io_modules/userspace/Makefile | 2 + .../userspace/elliptic_data_userspace_ctrl.c | 263 + .../userspace/elliptic_data_userspace_io.c | 143 + .../io_modules/userspace_test/Makefile | 2 + .../userspace_test/elliptic_data_io.c | 121 + techpack/audio/dsp/mius/Makefile | 28 + techpack/audio/dsp/mius/io_modules/Makefile | 2 + .../mius/io_modules/msm/mius_data_msm_io.c | 105 + .../dsp/mius/io_modules/userspace/Makefile | 2 + .../userspace/mius_data_userspace_ctrl.c | 263 + .../userspace/mius_data_userspace_io.c | 143 + .../mius/io_modules/userspace_test/Makefile | 2 + .../io_modules/userspace_test/mius_data_io.c | 120 + techpack/audio/dsp/mius/mius.c | 752 +++ techpack/audio/dsp/mius/mius_mixer_controls.c | 1344 +++++ techpack/audio/dsp/mius/mius_sysfs.c | 645 ++ techpack/audio/dsp/mius/mius_version.h | 8 + techpack/audio/dsp/msm-cirrus-playback-v2.c | 1405 +++++ techpack/audio/dsp/msm-cirrus-playback.c | 1550 +++++ techpack/audio/include/dsp/apr_elliptic.h | 41 + techpack/audio/include/dsp/apr_mius.h | 41 + .../include/dsp/msm-cirrus-playback-v2.h | 177 + .../audio/include/dsp/msm-cirrus-playback.h | 183 + techpack/audio/include/dsp/tas_smart_amp_v2.h | 177 + .../audio/include/elliptic/elliptic_data_io.h | 155 + .../audio/include/elliptic/elliptic_device.h | 50 + .../elliptic/elliptic_mixer_controls.h | 185 + .../audio/include/elliptic/elliptic_sysfs.h | 14 + techpack/audio/include/mius/mius_data_io.h | 155 + techpack/audio/include/mius/mius_device.h | 49 + .../audio/include/mius/mius_mixer_controls.h | 183 + techpack/audio/include/mius/mius_sysfs.h | 14 + techpack/audio/include/uapi/sound/cs35l41.h | 84 + .../audio/include/uapi/sound/cs35l41_v2.h | 137 + .../include/uapi/sound/msm-cirrus-playback.h | 119 + 139 files changed, 89115 insertions(+) create mode 100755 techpack/audio/asoc/codecs/cs35l41/Android.mk create mode 100755 techpack/audio/asoc/codecs/cs35l41/Kbuild create mode 100755 techpack/audio/asoc/codecs/cs35l41/Kconfig create mode 100755 techpack/audio/asoc/codecs/cs35l41/Makefile create mode 100644 techpack/audio/asoc/codecs/cs35l41/cs35l41-i2c.c create mode 100644 techpack/audio/asoc/codecs/cs35l41/cs35l41-spi.c create mode 100644 techpack/audio/asoc/codecs/cs35l41/cs35l41-tables.c create mode 100644 techpack/audio/asoc/codecs/cs35l41/cs35l41.c create mode 100644 techpack/audio/asoc/codecs/cs35l41/cs35l41.h create mode 100755 techpack/audio/asoc/codecs/cs35l41/cs35l41.txt create mode 100644 techpack/audio/asoc/codecs/cs35l41/wm_adsp.c create mode 100644 techpack/audio/asoc/codecs/cs35l41/wm_adsp.h create mode 100644 techpack/audio/asoc/codecs/cs35l41/wmfw.h create mode 100755 techpack/audio/asoc/codecs/cs35l41_v2/Android.mk create mode 100755 techpack/audio/asoc/codecs/cs35l41_v2/Kbuild create mode 100755 techpack/audio/asoc/codecs/cs35l41_v2/Kconfig create mode 100644 techpack/audio/asoc/codecs/cs35l41_v2/cs35l41-i2c.c create mode 100644 techpack/audio/asoc/codecs/cs35l41_v2/cs35l41-spi.c create mode 100644 techpack/audio/asoc/codecs/cs35l41_v2/cs35l41-tables.c create mode 100644 techpack/audio/asoc/codecs/cs35l41_v2/cs35l41.c create mode 100644 techpack/audio/asoc/codecs/cs35l41_v2/cs35l41.h create mode 100755 techpack/audio/asoc/codecs/cs35l41_v2/cs35l41.txt create mode 100644 techpack/audio/asoc/codecs/cs35l41_v2/send_data_to_xlog.c create mode 100644 techpack/audio/asoc/codecs/cs35l41_v2/send_data_to_xlog.h create mode 100644 techpack/audio/asoc/codecs/cs35l41_v2/wm_adsp.c create mode 100644 techpack/audio/asoc/codecs/cs35l41_v2/wm_adsp.h create mode 100644 techpack/audio/asoc/codecs/cs35l41_v2/wmfw.h create mode 100755 techpack/audio/asoc/codecs/tas2557/Android.mk create mode 100755 techpack/audio/asoc/codecs/tas2557/Kbuild create mode 100644 techpack/audio/asoc/codecs/tas2557/Kconfig create mode 100644 techpack/audio/asoc/codecs/tas2557/tas2557-codec.c create mode 100755 techpack/audio/asoc/codecs/tas2557/tas2557-codec.h create mode 100644 techpack/audio/asoc/codecs/tas2557/tas2557-core.c create mode 100644 techpack/audio/asoc/codecs/tas2557/tas2557-core.h create mode 100644 techpack/audio/asoc/codecs/tas2557/tas2557-misc.c create mode 100644 techpack/audio/asoc/codecs/tas2557/tas2557-misc.h create mode 100644 techpack/audio/asoc/codecs/tas2557/tas2557-regmap.c create mode 100644 techpack/audio/asoc/codecs/tas2557/tas2557.h create mode 100644 techpack/audio/asoc/codecs/tas2557/tiload.c create mode 100644 techpack/audio/asoc/codecs/tas2557/tiload.h create mode 100644 techpack/audio/asoc/codecs/tas256x/Android.mk create mode 100644 techpack/audio/asoc/codecs/tas256x/Kbuild create mode 100644 techpack/audio/asoc/codecs/tas256x/Kconfig create mode 100644 techpack/audio/asoc/codecs/tas256x/Makefile create mode 100644 techpack/audio/asoc/codecs/tas256x/tas2562.h create mode 100644 techpack/audio/asoc/codecs/tas256x/tas2564.h create mode 100644 techpack/audio/asoc/codecs/tas256x/tas256x-codec.c create mode 100644 techpack/audio/asoc/codecs/tas256x/tas256x-codec.h create mode 100644 techpack/audio/asoc/codecs/tas256x/tas256x-device.h create mode 100644 techpack/audio/asoc/codecs/tas256x/tas256x-regmap.c create mode 100644 techpack/audio/asoc/codecs/tas256x/tas256x.c create mode 100644 techpack/audio/asoc/codecs/tas256x/tas256x.h create mode 100644 techpack/audio/asoc/codecs/tas256x/tas25xx-algo.c create mode 100644 techpack/audio/asoc/codecs/tas256x/tas25xx-calib.c create mode 100644 techpack/audio/asoc/codecs/tas256x/tas25xx-calib.h create mode 100755 techpack/audio/asoc/codecs/tfa98xx/Android.mk create mode 100755 techpack/audio/asoc/codecs/tfa98xx/Kbuild create mode 100644 techpack/audio/asoc/codecs/tfa98xx/Kconfig create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/config.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/dbgprint.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/spk-id.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa1_tfafieldnames.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa2_tfafieldnames_N1C.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa9872_tfafieldnames.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa9874_tfafieldnames.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa9887_tfafieldnames.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa9890_tfafieldnames.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa9891_genregs.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa9891_tfafieldnames.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa9894_tfafieldnames.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa9896_tfafieldnames.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx_genregs_N1C.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx_parameters.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx_tfafieldnames.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa9912_tfafieldnames.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa_container.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa_device.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa_dsp_fw.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa_ext.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa_internal.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa_platform_interface_definition.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/tfa_service.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/versions.h create mode 100644 techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c create mode 100644 techpack/audio/asoc/codecs/tfa98xx/src/tfa_container.c create mode 100644 techpack/audio/asoc/codecs/tfa98xx/src/tfa_debug.c create mode 100644 techpack/audio/asoc/codecs/tfa98xx/src/tfa_dsp.c create mode 100644 techpack/audio/asoc/codecs/tfa98xx/src/tfa_init.c create mode 100644 techpack/audio/dsp/apr_elliptic.c create mode 100644 techpack/audio/dsp/apr_mius.c create mode 100644 techpack/audio/dsp/elliptic/Makefile create mode 100644 techpack/audio/dsp/elliptic/elliptic.c create mode 100644 techpack/audio/dsp/elliptic/elliptic_mixer_controls.c create mode 100644 techpack/audio/dsp/elliptic/elliptic_sysfs.c create mode 100755 techpack/audio/dsp/elliptic/elliptic_version.h create mode 100644 techpack/audio/dsp/elliptic/io_modules/Makefile create mode 100644 techpack/audio/dsp/elliptic/io_modules/msm/elliptic_data_msm_io.c create mode 100644 techpack/audio/dsp/elliptic/io_modules/userspace/Makefile create mode 100644 techpack/audio/dsp/elliptic/io_modules/userspace/elliptic_data_userspace_ctrl.c create mode 100644 techpack/audio/dsp/elliptic/io_modules/userspace/elliptic_data_userspace_io.c create mode 100644 techpack/audio/dsp/elliptic/io_modules/userspace_test/Makefile create mode 100644 techpack/audio/dsp/elliptic/io_modules/userspace_test/elliptic_data_io.c create mode 100644 techpack/audio/dsp/mius/Makefile create mode 100644 techpack/audio/dsp/mius/io_modules/Makefile create mode 100644 techpack/audio/dsp/mius/io_modules/msm/mius_data_msm_io.c create mode 100644 techpack/audio/dsp/mius/io_modules/userspace/Makefile create mode 100644 techpack/audio/dsp/mius/io_modules/userspace/mius_data_userspace_ctrl.c create mode 100644 techpack/audio/dsp/mius/io_modules/userspace/mius_data_userspace_io.c create mode 100644 techpack/audio/dsp/mius/io_modules/userspace_test/Makefile create mode 100644 techpack/audio/dsp/mius/io_modules/userspace_test/mius_data_io.c create mode 100644 techpack/audio/dsp/mius/mius.c create mode 100644 techpack/audio/dsp/mius/mius_mixer_controls.c create mode 100644 techpack/audio/dsp/mius/mius_sysfs.c create mode 100644 techpack/audio/dsp/mius/mius_version.h create mode 100644 techpack/audio/dsp/msm-cirrus-playback-v2.c create mode 100644 techpack/audio/dsp/msm-cirrus-playback.c create mode 100644 techpack/audio/include/dsp/apr_elliptic.h create mode 100644 techpack/audio/include/dsp/apr_mius.h create mode 100644 techpack/audio/include/dsp/msm-cirrus-playback-v2.h create mode 100644 techpack/audio/include/dsp/msm-cirrus-playback.h create mode 100644 techpack/audio/include/dsp/tas_smart_amp_v2.h create mode 100644 techpack/audio/include/elliptic/elliptic_data_io.h create mode 100644 techpack/audio/include/elliptic/elliptic_device.h create mode 100644 techpack/audio/include/elliptic/elliptic_mixer_controls.h create mode 100644 techpack/audio/include/elliptic/elliptic_sysfs.h create mode 100644 techpack/audio/include/mius/mius_data_io.h create mode 100644 techpack/audio/include/mius/mius_device.h create mode 100644 techpack/audio/include/mius/mius_mixer_controls.h create mode 100644 techpack/audio/include/mius/mius_sysfs.h create mode 100644 techpack/audio/include/uapi/sound/cs35l41.h create mode 100644 techpack/audio/include/uapi/sound/cs35l41_v2.h create mode 100644 techpack/audio/include/uapi/sound/msm-cirrus-playback.h diff --git a/techpack/audio/Makefile b/techpack/audio/Makefile index 304c00aa49d9..185b633a5716 100644 --- a/techpack/audio/Makefile +++ b/techpack/audio/Makefile @@ -45,8 +45,16 @@ USERINCLUDE += \ # Needed to be compatible with the O= option LINUXINCLUDE += \ -I$(srctree)/techpack/audio/include/uapi \ + -I$(srctree)/techpack/audio/include/elliptic \ -I$(srctree)/techpack/audio/include +#for mius start +ifeq ($(CONFIG_US_PROXIMITY), y) +LINUXINCLUDE += \ + -I$(srctree)/techpack/audio/include/mius +endif +#for mius end + ifeq ($(CONFIG_ARCH_SDM845), y) LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/sdm845autoconf.h diff --git a/techpack/audio/asoc/codecs/Kbuild b/techpack/audio/asoc/codecs/Kbuild index a52da6d08cac..13fd8bbc41c2 100644 --- a/techpack/audio/asoc/codecs/Kbuild +++ b/techpack/audio/asoc/codecs/Kbuild @@ -210,6 +210,11 @@ ifeq ($(KERNEL_BUILD), 1) obj-y += wcd9360/ obj-y += wcd937x/ obj-y += bolero/ + obj-y += cs35l41/ + obj-y += cs35l41_v2/ + obj-y += tas2557/ + obj-y += tas256x/ + obj-y += tfa98xx/ endif ifeq ($(CONFIG_SND_SOC_GCOV), y) diff --git a/techpack/audio/asoc/codecs/Kconfig b/techpack/audio/asoc/codecs/Kconfig index 6fbac4e91012..8f87d049ba09 100644 --- a/techpack/audio/asoc/codecs/Kconfig +++ b/techpack/audio/asoc/codecs/Kconfig @@ -1,3 +1,9 @@ menu "Qualcomm ASoC additional codecs" +source "techpack/audio/asoc/codecs/cs35l41/Kconfig" +source "techpack/audio/asoc/codecs/cs35l41_v2/Kconfig" +source "techpack/audio/asoc/codecs/tas2557/Kconfig" +source "techpack/audio/asoc/codecs/tas256x/Kconfig" +source "techpack/audio/asoc/codecs/tfa98xx/Kconfig" + endmenu diff --git a/techpack/audio/asoc/codecs/cs35l41/Android.mk b/techpack/audio/asoc/codecs/cs35l41/Android.mk new file mode 100755 index 000000000000..9b2b116f0487 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41/Android.mk @@ -0,0 +1,55 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,msmnile),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m +endif + +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE)),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + #AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=cs35l41_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_cs35l41.ko +LOCAL_MODULE_KBUILD_NAME := cs35l41_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/techpack/audio/asoc/codecs/cs35l41/Kbuild b/techpack/audio/asoc/codecs/cs35l41/Kbuild new file mode 100755 index 000000000000..e7af92f568a1 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41/Kbuild @@ -0,0 +1,114 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + + + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_SM8150), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif + ifeq ($(CONFIG_ARCH_SM6150), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif + + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ CS35L41 ############ + +# for CS35L41 Codec +ifdef CONFIG_SND_SOC_CS35L41 + CS35L41_OBJS += cs35l41.o + CS35L41_OBJS += cs35l41-i2c.o + CS35L41_OBJS += cs35l41-tables.o + CS35L41_OBJS += wm_adsp.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_CS35L41) += cs35l41_dlkm.o +cs35l41_dlkm-y := $(CS35L41_OBJS) diff --git a/techpack/audio/asoc/codecs/cs35l41/Kconfig b/techpack/audio/asoc/codecs/cs35l41/Kconfig new file mode 100755 index 000000000000..7a21d8b67413 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41/Kconfig @@ -0,0 +1,5 @@ +config SND_SOC_CS35L41 + tristate "Cirrus Logic CS35L41 codec" + help + Say Y or M here if you want to add support for the Cirrus Logic + CS35L41 codec. diff --git a/techpack/audio/asoc/codecs/cs35l41/Makefile b/techpack/audio/asoc/codecs/cs35l41/Makefile new file mode 100755 index 000000000000..e7e3ce8cf43a --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41/Makefile @@ -0,0 +1,433 @@ +snd-soc-88pm860x-objs := 88pm860x-codec.o +snd-soc-ab8500-codec-objs := ab8500-codec.o +snd-soc-ac97-objs := ac97.o +snd-soc-ad1836-objs := ad1836.o +snd-soc-ad193x-objs := ad193x.o +snd-soc-ad193x-spi-objs := ad193x-spi.o +snd-soc-ad193x-i2c-objs := ad193x-i2c.o +snd-soc-ad1980-objs := ad1980.o +snd-soc-ad73311-objs := ad73311.o +snd-soc-adau1373-objs := adau1373.o +snd-soc-adau1701-objs := adau1701.o +snd-soc-adau17x1-objs := adau17x1.o +snd-soc-adau1761-objs := adau1761.o +snd-soc-adau1761-i2c-objs := adau1761-i2c.o +snd-soc-adau1761-spi-objs := adau1761-spi.o +snd-soc-adau1781-objs := adau1781.o +snd-soc-adau1781-i2c-objs := adau1781-i2c.o +snd-soc-adau1781-spi-objs := adau1781-spi.o +snd-soc-adau1977-objs := adau1977.o +snd-soc-adau1977-spi-objs := adau1977-spi.o +snd-soc-adau1977-i2c-objs := adau1977-i2c.o +snd-soc-adav80x-objs := adav80x.o +snd-soc-adav801-objs := adav801.o +snd-soc-adav803-objs := adav803.o +snd-soc-ads117x-objs := ads117x.o +snd-soc-ak4104-objs := ak4104.o +snd-soc-ak4535-objs := ak4535.o +snd-soc-ak4554-objs := ak4554.o +snd-soc-ak4613-objs := ak4613.o +snd-soc-ak4641-objs := ak4641.o +snd-soc-ak4642-objs := ak4642.o +snd-soc-ak4671-objs := ak4671.o +snd-soc-ak5386-objs := ak5386.o +snd-soc-arizona-objs := arizona.o +snd-soc-cq93vc-objs := cq93vc.o +snd-soc-cirrus-psia-objs := cirrus-psia.o +snd-soc-cs35l32-objs := cs35l32.o +snd-soc-cs35l33-objs := cs35l33.o +snd-soc-cs35l34-objs := cs35l34.o +snd-soc-cs35l35-objs := cs35l35.o +snd-soc-cs35l36-objs := cs35l36.o cs35l36-tables.o +snd-soc-cs35l41-objs := cs35l41.o +snd-soc-cs35l41-spi-objs := cs35l41-spi.o cs35l41-tables.o +snd-soc-cs35l41-i2c-objs := cs35l41-i2c.o cs35l41-tables.o +snd-soc-cs42l42-objs := cs42l42.o +snd-soc-cs42l51-objs := cs42l51.o +snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o +snd-soc-cs42l52-objs := cs42l52.o +snd-soc-cs42l56-objs := cs42l56.o +snd-soc-cs42l73-objs := cs42l73.o +snd-soc-cs4265-objs := cs4265.o +snd-soc-cs4270-objs := cs4270.o +snd-soc-cs4271-objs := cs4271.o +snd-soc-cs4271-i2c-objs := cs4271-i2c.o +snd-soc-cs4271-spi-objs := cs4271-spi.o +snd-soc-cs42xx8-objs := cs42xx8.o +snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o +snd-soc-cs4349-objs := cs4349.o +snd-soc-cs43130-objs := cs43130.o +snd-soc-cs47l24-objs := cs47l24.o +snd-soc-cs53l30-objs := cs53l30.o +snd-soc-cx20442-objs := cx20442.o +snd-soc-da7210-objs := da7210.o +snd-soc-da7213-objs := da7213.o +snd-soc-da7218-objs := da7218.o +snd-soc-da7219-objs := da7219.o da7219-aad.o +snd-soc-da732x-objs := da732x.o +snd-soc-da9055-objs := da9055.o +snd-soc-bt-sco-objs := bt-sco.o +snd-soc-dmic-objs := dmic.o +snd-soc-es8328-objs := es8328.o +snd-soc-es8328-i2c-objs := es8328-i2c.o +snd-soc-es8328-spi-objs := es8328-spi.o +snd-soc-gtm601-objs := gtm601.o +snd-soc-hdac-hdmi-objs := hdac_hdmi.o +snd-soc-ics43432-objs := ics43432.o +snd-soc-inno-rk3036-objs := inno_rk3036.o +snd-soc-isabelle-objs := isabelle.o +snd-soc-jz4740-codec-objs := jz4740.o +snd-soc-l3-objs := l3.o +snd-soc-lm4857-objs := lm4857.o +snd-soc-lm49453-objs := lm49453.o +snd-soc-max9768-objs := max9768.o +snd-soc-max98088-objs := max98088.o +snd-soc-max98090-objs := max98090.o +snd-soc-max98095-objs := max98095.o +snd-soc-max98357a-objs := max98357a.o +snd-soc-max9867-objs := max9867.o +snd-soc-max98925-objs := max98925.o +snd-soc-max98926-objs := max98926.o +snd-soc-max9850-objs := max9850.o +snd-soc-mc13783-objs := mc13783.o +snd-soc-ml26124-objs := ml26124.o +snd-soc-nau8825-objs := nau8825.o +snd-soc-pcm1681-objs := pcm1681.o +snd-soc-pcm179x-codec-objs := pcm179x.o +snd-soc-pcm179x-i2c-objs := pcm179x-i2c.o +snd-soc-pcm179x-spi-objs := pcm179x-spi.o +snd-soc-pcm3008-objs := pcm3008.o +snd-soc-pcm3168a-objs := pcm3168a.o +snd-soc-pcm3168a-i2c-objs := pcm3168a-i2c.o +snd-soc-pcm3168a-spi-objs := pcm3168a-spi.o +snd-soc-pcm512x-objs := pcm512x.o +snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o +snd-soc-pcm512x-spi-objs := pcm512x-spi.o +snd-soc-rl6231-objs := rl6231.o +snd-soc-rl6347a-objs := rl6347a.o +snd-soc-rt286-objs := rt286.o +snd-soc-rt298-objs := rt298.o +snd-soc-rt5514-objs := rt5514.o +snd-soc-rt5616-objs := rt5616.o +snd-soc-rt5631-objs := rt5631.o +snd-soc-rt5640-objs := rt5640.o +snd-soc-rt5645-objs := rt5645.o +snd-soc-rt5651-objs := rt5651.o +snd-soc-rt5659-objs := rt5659.o +snd-soc-rt5670-objs := rt5670.o +snd-soc-rt5677-objs := rt5677.o +snd-soc-rt5677-spi-objs := rt5677-spi.o +snd-soc-sgtl5000-objs := sgtl5000.o +snd-soc-alc5623-objs := alc5623.o +snd-soc-alc5632-objs := alc5632.o +snd-soc-sigmadsp-objs := sigmadsp.o +snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o +snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o +snd-soc-si476x-objs := si476x.o +snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o +snd-soc-sn95031-objs := sn95031.o +snd-soc-spdif-tx-objs := spdif_transmitter.o +snd-soc-spdif-rx-objs := spdif_receiver.o +snd-soc-ssm2518-objs := ssm2518.o +snd-soc-ssm2602-objs := ssm2602.o +snd-soc-ssm2602-spi-objs := ssm2602-spi.o +snd-soc-ssm2602-i2c-objs := ssm2602-i2c.o +snd-soc-ssm4567-objs := ssm4567.o +snd-soc-sta32x-objs := sta32x.o +snd-soc-sta350-objs := sta350.o +snd-soc-sta529-objs := sta529.o +snd-soc-stac9766-objs := stac9766.o +snd-soc-sti-sas-objs := sti-sas.o +snd-soc-tas5086-objs := tas5086.o +snd-soc-tas571x-objs := tas571x.o +snd-soc-tfa9879-objs := tfa9879.o +snd-soc-tlv320aic23-objs := tlv320aic23.o +snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o +snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o +snd-soc-tlv320aic26-objs := tlv320aic26.o +snd-soc-tlv320aic31xx-objs := tlv320aic31xx.o +snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o +snd-soc-tlv320aic3x-objs := tlv320aic3x.o +snd-soc-tlv320dac33-objs := tlv320dac33.o +snd-soc-ts3a227e-objs := ts3a227e.o +snd-soc-twl4030-objs := twl4030.o +snd-soc-twl6040-objs := twl6040.o +snd-soc-uda134x-objs := uda134x.o +snd-soc-uda1380-objs := uda1380.o +snd-soc-wl1273-objs := wl1273.o +snd-soc-wm-adsp-objs := wm_adsp.o +snd-soc-wm0010-objs := wm0010.o +snd-soc-wm1250-ev1-objs := wm1250-ev1.o +snd-soc-wm2000-objs := wm2000.o +snd-soc-wm2200-objs := wm2200.o +snd-soc-wm5100-objs := wm5100.o wm5100-tables.o +snd-soc-wm5102-objs := wm5102.o +snd-soc-wm5110-objs := wm5110.o +snd-soc-wm8350-objs := wm8350.o +snd-soc-wm8400-objs := wm8400.o +snd-soc-wm8510-objs := wm8510.o +snd-soc-wm8523-objs := wm8523.o +snd-soc-wm8580-objs := wm8580.o +snd-soc-wm8711-objs := wm8711.o +snd-soc-wm8727-objs := wm8727.o +snd-soc-wm8728-objs := wm8728.o +snd-soc-wm8731-objs := wm8731.o +snd-soc-wm8737-objs := wm8737.o +snd-soc-wm8741-objs := wm8741.o +snd-soc-wm8750-objs := wm8750.o +snd-soc-wm8753-objs := wm8753.o +snd-soc-wm8770-objs := wm8770.o +snd-soc-wm8776-objs := wm8776.o +snd-soc-wm8782-objs := wm8782.o +snd-soc-wm8804-objs := wm8804.o +snd-soc-wm8804-i2c-objs := wm8804-i2c.o +snd-soc-wm8804-spi-objs := wm8804-spi.o +snd-soc-wm8900-objs := wm8900.o +snd-soc-wm8903-objs := wm8903.o +snd-soc-wm8904-objs := wm8904.o +snd-soc-wm8996-objs := wm8996.o +snd-soc-wm8940-objs := wm8940.o +snd-soc-wm8955-objs := wm8955.o +snd-soc-wm8960-objs := wm8960.o +snd-soc-wm8961-objs := wm8961.o +snd-soc-wm8962-objs := wm8962.o +snd-soc-wm8971-objs := wm8971.o +snd-soc-wm8974-objs := wm8974.o +snd-soc-wm8978-objs := wm8978.o +snd-soc-wm8983-objs := wm8983.o +snd-soc-wm8985-objs := wm8985.o +snd-soc-wm8988-objs := wm8988.o +snd-soc-wm8990-objs := wm8990.o +snd-soc-wm8991-objs := wm8991.o +snd-soc-wm8993-objs := wm8993.o +snd-soc-wm8994-objs := wm8994.o wm8958-dsp2.o +snd-soc-wm8995-objs := wm8995.o +snd-soc-wm8997-objs := wm8997.o +snd-soc-wm8998-objs := wm8998.o +snd-soc-wm9081-objs := wm9081.o +snd-soc-wm9090-objs := wm9090.o +snd-soc-wm9705-objs := wm9705.o +snd-soc-wm9712-objs := wm9712.o +snd-soc-wm9713-objs := wm9713.o +snd-soc-wm-hubs-objs := wm_hubs.o + +# Amp +snd-soc-max9877-objs := max9877.o +snd-soc-tpa6130a2-objs := tpa6130a2.o +snd-soc-tas2552-objs := tas2552.o + +obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o +obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o +obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o +obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o +obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o +obj-$(CONFIG_SND_SOC_AD193X_SPI) += snd-soc-ad193x-spi.o +obj-$(CONFIG_SND_SOC_AD193X_I2C) += snd-soc-ad193x-i2c.o +obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o +obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o +obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o +obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o +obj-$(CONFIG_SND_SOC_ADAU17X1) += snd-soc-adau17x1.o +obj-$(CONFIG_SND_SOC_ADAU1761) += snd-soc-adau1761.o +obj-$(CONFIG_SND_SOC_ADAU1761_I2C) += snd-soc-adau1761-i2c.o +obj-$(CONFIG_SND_SOC_ADAU1761_SPI) += snd-soc-adau1761-spi.o +obj-$(CONFIG_SND_SOC_ADAU1781) += snd-soc-adau1781.o +obj-$(CONFIG_SND_SOC_ADAU1781_I2C) += snd-soc-adau1781-i2c.o +obj-$(CONFIG_SND_SOC_ADAU1781_SPI) += snd-soc-adau1781-spi.o +obj-$(CONFIG_SND_SOC_ADAU1977) += snd-soc-adau1977.o +obj-$(CONFIG_SND_SOC_ADAU1977_SPI) += snd-soc-adau1977-spi.o +obj-$(CONFIG_SND_SOC_ADAU1977_I2C) += snd-soc-adau1977-i2c.o +obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o +obj-$(CONFIG_SND_SOC_ADAV801) += snd-soc-adav801.o +obj-$(CONFIG_SND_SOC_ADAV803) += snd-soc-adav803.o +obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o +obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o +obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o +obj-$(CONFIG_SND_SOC_AK4554) += snd-soc-ak4554.o +obj-$(CONFIG_SND_SOC_AK4613) += snd-soc-ak4613.o +obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o +obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o +obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o +obj-$(CONFIG_SND_SOC_AK5386) += snd-soc-ak5386.o +obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o +obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o +obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o +obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o +obj-$(CONFIG_SND_SOC_CIRRUS_PSIA) += snd-soc-cirrus-psia.o +obj-$(CONFIG_SND_SOC_CS35L32) += snd-soc-cs35l32.o +obj-$(CONFIG_SND_SOC_CS35L33) += snd-soc-cs35l33.o +obj-$(CONFIG_SND_SOC_CS35L34) += snd-soc-cs35l34.o +obj-$(CONFIG_SND_SOC_CS35L35) += snd-soc-cs35l35.o +obj-$(CONFIG_SND_SOC_CS35L41) += snd-soc-cs35l41.o +obj-$(CONFIG_SND_SOC_CS35L41_SPI) += snd-soc-cs35l41-spi.o +obj-$(CONFIG_SND_SOC_CS35L41_I2C) += snd-soc-cs35l41-i2c.o +obj-$(CONFIG_SND_SOC_CS35L36) += snd-soc-cs35l36.o +obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o +obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o +obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o +obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o +obj-$(CONFIG_SND_SOC_CS42L56) += snd-soc-cs42l56.o +obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o +obj-$(CONFIG_SND_SOC_CS4265) += snd-soc-cs4265.o +obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o +obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o +obj-$(CONFIG_SND_SOC_CS4271_I2C) += snd-soc-cs4271-i2c.o +obj-$(CONFIG_SND_SOC_CS4271_SPI) += snd-soc-cs4271-spi.o +obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o +obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o +obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o +obj-$(CONFIG_SND_SOC_CS43130) += snd-soc-cs43130.o +obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o +obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o +obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o +obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o +obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o +obj-$(CONFIG_SND_SOC_DA7218) += snd-soc-da7218.o +obj-$(CONFIG_SND_SOC_DA7219) += snd-soc-da7219.o +obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o +obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o +obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o +obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o +obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o +obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o +obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o +obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o +obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o +obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o +obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o +obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o +obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o +obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o +obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o +obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o +obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o +obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o +obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o +obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o +obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o +obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o +obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o +obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o +obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o +obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o +obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o +obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o +obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o +obj-$(CONFIG_SND_SOC_PCM179X) += snd-soc-pcm179x-codec.o +obj-$(CONFIG_SND_SOC_PCM179X_I2C) += snd-soc-pcm179x-i2c.o +obj-$(CONFIG_SND_SOC_PCM179X_SPI) += snd-soc-pcm179x-spi.o +obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o +obj-$(CONFIG_SND_SOC_PCM3168A) += snd-soc-pcm3168a.o +obj-$(CONFIG_SND_SOC_PCM3168A_I2C) += snd-soc-pcm3168a-i2c.o +obj-$(CONFIG_SND_SOC_PCM3168A_SPI) += snd-soc-pcm3168a-spi.o +obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o +obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o +obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o +obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o +obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o +obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o +obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o +obj-$(CONFIG_SND_SOC_RT5514) += snd-soc-rt5514.o +obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o +obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o +obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o +obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o +obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o +obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o +obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o +obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o +obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o +obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o +obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o +obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o +obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o +obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o +obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o +obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o +obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o +obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o +obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o +obj-$(CONFIG_SND_SOC_SSM2602_I2C) += snd-soc-ssm2602-i2c.o +obj-$(CONFIG_SND_SOC_SSM4567) += snd-soc-ssm4567.o +obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o +obj-$(CONFIG_SND_SOC_STA350) += snd-soc-sta350.o +obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o +obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o +obj-$(CONFIG_SND_SOC_STI_SAS) += snd-soc-sti-sas.o +obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o +obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o +obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o +obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o +obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o +obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o +obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o +obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o +obj-$(CONFIG_SND_SOC_TLV320AIC31XX) += snd-soc-tlv320aic31xx.o +obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o +obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o +obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o +obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o +obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o +obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o +obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o +obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o +obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o +obj-$(CONFIG_SND_SOC_WM0010) += snd-soc-wm0010.o +obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o +obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o +obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o +obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o +obj-$(CONFIG_SND_SOC_WM5102) += snd-soc-wm5102.o +obj-$(CONFIG_SND_SOC_WM5110) += snd-soc-wm5110.o +obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o +obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o +obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o +obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o +obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o +obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o +obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o +obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o +obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o +obj-$(CONFIG_SND_SOC_WM8737) += snd-soc-wm8737.o +obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o +obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o +obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o +obj-$(CONFIG_SND_SOC_WM8770) += snd-soc-wm8770.o +obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o +obj-$(CONFIG_SND_SOC_WM8782) += snd-soc-wm8782.o +obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o +obj-$(CONFIG_SND_SOC_WM8804_I2C) += snd-soc-wm8804-i2c.o +obj-$(CONFIG_SND_SOC_WM8804_SPI) += snd-soc-wm8804-spi.o +obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o +obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o +obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o +obj-$(CONFIG_SND_SOC_WM8996) += snd-soc-wm8996.o +obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o +obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o +obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o +obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o +obj-$(CONFIG_SND_SOC_WM8962) += snd-soc-wm8962.o +obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o +obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o +obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o +obj-$(CONFIG_SND_SOC_WM8983) += snd-soc-wm8983.o +obj-$(CONFIG_SND_SOC_WM8985) += snd-soc-wm8985.o +obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o +obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o +obj-$(CONFIG_SND_SOC_WM8991) += snd-soc-wm8991.o +obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o +obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o +obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o +obj-$(CONFIG_SND_SOC_WM8997) += snd-soc-wm8997.o +obj-$(CONFIG_SND_SOC_WM8998) += snd-soc-wm8998.o +obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o +obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o +obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o +obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o +obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o +obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o +obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o + +# Amp +obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o +obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o diff --git a/techpack/audio/asoc/codecs/cs35l41/cs35l41-i2c.c b/techpack/audio/asoc/codecs/cs35l41/cs35l41-i2c.c new file mode 100644 index 000000000000..f9cb15f43f31 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41/cs35l41-i2c.c @@ -0,0 +1,123 @@ +/* + * cs35l41-i2c.c -- CS35l41 I2C driver + * + * Copyright 2017 Cirrus Logic, Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * + * Author: David Rhodes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm_adsp.h" +#include "cs35l41.h" +#include + +static struct regmap_config cs35l41_regmap_i2c = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .val_format_endian = REGMAP_ENDIAN_BIG, + .max_register = CS35L41_LASTREG, + .reg_defaults = cs35l41_reg, + .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), + .volatile_reg = cs35l41_volatile_reg, + .readable_reg = cs35l41_readable_reg, + .precious_reg = cs35l41_precious_reg, + .cache_type = REGCACHE_RBTREE, +}; + +static const struct i2c_device_id cs35l41_id_i2c[] = { + { "cs35l40", 0 }, + { "cs35l41", 0 }, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, cs35l41_id_i2c); + +static int cs35l41_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cs35l41_private *cs35l41; + struct device *dev = &client->dev; + struct cs35l41_platform_data *pdata = dev_get_platdata(dev); + const struct regmap_config *regmap_config = &cs35l41_regmap_i2c; + int ret; + + dev_info(dev, "cs35l41 i2c probe start\n"); + + cs35l41 = devm_kzalloc(dev, sizeof(struct cs35l41_private), GFP_KERNEL); + + if (cs35l41 == NULL) + return -ENOMEM; + + cs35l41->dev = dev; + cs35l41->irq = client->irq; + cs35l41->bus_spi = false; + + i2c_set_clientdata(client, cs35l41); + cs35l41->regmap = devm_regmap_init_i2c(client, regmap_config); + if (IS_ERR(cs35l41->regmap)) { + ret = PTR_ERR(cs35l41->regmap); + dev_err(cs35l41->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + return cs35l41_probe(cs35l41, pdata); +} + +static int cs35l41_i2c_remove(struct i2c_client *client) +{ + struct cs35l41_private *cs35l41 = i2c_get_clientdata(client); + + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); + wm_adsp2_remove(&cs35l41->dsp); + regulator_bulk_disable(cs35l41->num_supplies, cs35l41->supplies); + snd_soc_unregister_codec(cs35l41->dev); + return 0; +} + +static const struct of_device_id cs35l41_of_match[] = { + { .compatible = "cirrus,cs35l40" }, + { .compatible = "cirrus,cs35l41" }, + {}, +}; +MODULE_DEVICE_TABLE(of, cs35l41_of_match); + +static struct i2c_driver cs35l41_i2c_driver = { + .driver = { + .name = "cs35l41", + .of_match_table = cs35l41_of_match, + }, + .id_table = cs35l41_id_i2c, + .probe = cs35l41_i2c_probe, + .remove = cs35l41_i2c_remove, +}; + +module_i2c_driver(cs35l41_i2c_driver); + +MODULE_DESCRIPTION("I2C CS35L41 driver"); +MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); +MODULE_LICENSE("GPL"); diff --git a/techpack/audio/asoc/codecs/cs35l41/cs35l41-spi.c b/techpack/audio/asoc/codecs/cs35l41/cs35l41-spi.c new file mode 100644 index 000000000000..07af1c7fc7e3 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41/cs35l41-spi.c @@ -0,0 +1,113 @@ +/* + * cs35l41-spi.c -- CS35l41 SPI driver + * + * Copyright 2017 Cirrus Logic, Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * + * Author: David Rhodes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm_adsp.h" +#include "cs35l41.h" +#include + +static struct regmap_config cs35l41_regmap_spi = { + .reg_bits = 32, + .val_bits = 32, + .pad_bits = 16, + .reg_stride = 4, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .val_format_endian = REGMAP_ENDIAN_BIG, + .max_register = CS35L41_LASTREG, + .reg_defaults = cs35l41_reg, + .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), + .volatile_reg = cs35l41_volatile_reg, + .readable_reg = cs35l41_readable_reg, + .cache_type = REGCACHE_RBTREE, +}; + +static const struct spi_device_id cs35l41_id_spi[] = { + { "cs35l40", 0 }, + { "cs35l41", 0 }, + {}, +}; + +MODULE_DEVICE_TABLE(spi, cs35l41_id_spi); + +static int cs35l41_spi_probe(struct spi_device *spi) +{ + const struct regmap_config *regmap_config = &cs35l41_regmap_spi; + struct cs35l41_platform_data *pdata = dev_get_platdata(&spi->dev); + struct cs35l41_private *cs35l41; + int ret; + + cs35l41 = devm_kzalloc(&spi->dev, sizeof(struct cs35l41_private), + GFP_KERNEL); + if (cs35l41 == NULL) + return -ENOMEM; + + spi_set_drvdata(spi, cs35l41); + cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config); + if (IS_ERR(cs35l41->regmap)) { + ret = PTR_ERR(cs35l41->regmap); + dev_err(&spi->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + cs35l41->dev = &spi->dev; + cs35l41->irq = spi->irq; + + return cs35l41_probe(cs35l41, pdata); +} + +static int cs35l41_spi_remove(struct spi_device *spi) +{ + struct cs35l41_private *cs35l41 = spi_get_drvdata(spi); + + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); + wm_adsp2_remove(&cs35l41->dsp); + regulator_bulk_disable(cs35l41->num_supplies, cs35l41->supplies); + snd_soc_unregister_codec(cs35l41->dev); + return 0; +} + +static const struct of_device_id cs35l41_of_match[] = { + { .compatible = "cirrus,cs35l40" }, + { .compatible = "cirrus,cs35l41" }, + {}, +}; +MODULE_DEVICE_TABLE(of, cs35l41_of_match); + +static struct spi_driver cs35l41_spi_driver = { + .driver = { + .name = "cs35l41", + .of_match_table = cs35l41_of_match, + }, + .id_table = cs35l41_id_spi, + .probe = cs35l41_spi_probe, + .remove = cs35l41_spi_remove, +}; + +module_spi_driver(cs35l41_spi_driver); + +MODULE_DESCRIPTION("SPI CS35L41 driver"); +MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); +MODULE_LICENSE("GPL"); diff --git a/techpack/audio/asoc/codecs/cs35l41/cs35l41-tables.c b/techpack/audio/asoc/codecs/cs35l41/cs35l41-tables.c new file mode 100644 index 000000000000..04c9cfd7b38a --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41/cs35l41-tables.c @@ -0,0 +1,946 @@ +/* + * cs35l41-tables.c -- CS35L41 ALSA SoC audio driver + * + * Copyright 2018 Cirrus Logic, Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * + * Author: Brian Austin + * David Rhodes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include "cs35l41.h" + +const struct reg_default cs35l41_reg[CS35L41_MAX_CACHE_REG] = { + { CS35L41_TEST_KEY_CTL, 0x00000000 }, + { CS35L41_USER_KEY_CTL, 0x00000000 }, + { CS35L41_OTP_CTRL0, 0x00006418 }, + { CS35L41_OTP_CTRL1, 0x00000000 }, + { CS35L41_OTP_CTRL3, 0x00000000 }, + { CS35L41_OTP_CTRL4, 0x00000000 }, + { CS35L41_OTP_CTRL5, 0x00000030 }, + { CS35L41_OTP_CTRL6, 0x00000000 }, + { CS35L41_OTP_CTRL7, 0x00000000 }, + { CS35L41_OTP_CTRL8, 0x00000000 }, + { CS35L41_PWR_CTRL1, 0x00000000 }, + { CS35L41_PWR_CTRL3, 0x01000010 }, + { CS35L41_CTRL_OVRRIDE, 0x00000002 }, + { CS35L41_AMP_OUT_MUTE, 0x00000000 }, + { CS35L41_PROTECT_REL_ERR_IGN, 0x00000000 }, + { CS35L41_GPIO_PAD_CONTROL, 0x00000000 }, + { CS35L41_JTAG_CONTROL, 0x00000000 }, + { CS35L41_PLL_CLK_CTRL, 0x00000010 }, + { CS35L41_DSP_CLK_CTRL, 0x00000003 }, + { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, + { CS35L41_DATA_FS_SEL, 0x00000000 }, + { CS35L41_MDSYNC_EN, 0x00000200 }, + { CS35L41_MDSYNC_TX_ID, 0x00000000 }, + { CS35L41_MDSYNC_PWR_CTRL, 0x00000002 }, + { CS35L41_MDSYNC_DATA_TX, 0x00000000 }, + { CS35L41_MDSYNC_TX_STATUS, 0x00000002 }, + { CS35L41_MDSYNC_DATA_RX, 0x00000000 }, + { CS35L41_MDSYNC_RX_STATUS, 0x00000002 }, + { CS35L41_MDSYNC_ERR_STATUS, 0x00000000 }, + { CS35L41_MDSYNC_SYNC_PTE2, 0x00000000 }, + { CS35L41_MDSYNC_SYNC_PTE3, 0x00000000 }, + { CS35L41_MDSYNC_SYNC_MSM_STATUS, 0x00000000 }, + { CS35L41_BSTCVRT_VCTRL1, 0x00000000 }, + { CS35L41_BSTCVRT_VCTRL2, 0x00000001 }, + { CS35L41_BSTCVRT_PEAK_CUR, 0x0000004A }, + { CS35L41_BSTCVRT_SFT_RAMP, 0x00000003 }, + { CS35L41_BSTCVRT_COEFF, 0x00002424 }, + { CS35L41_BSTCVRT_SLOPE_LBST, 0x00007500 }, + { CS35L41_BSTCVRT_SW_FREQ, 0x01008000 }, + { CS35L41_BSTCVRT_DCM_CTRL, 0x00002001 }, + { CS35L41_BSTCVRT_DCM_MODE_FORCE, 0x00000000 }, + { CS35L41_BSTCVRT_OVERVOLT_CTRL, 0x00000130 }, + { CS35L41_VI_VOL_POL, 0x08000800 }, + { CS35L41_DTEMP_WARN_THLD, 0x00000002 }, + { CS35L41_DTEMP_EN, 0x00000000 }, + { CS35L41_VPVBST_FS_SEL, 0x00000001 }, + { CS35L41_SP_ENABLES, 0x00000000 }, + { CS35L41_SP_RATE_CTRL, 0x00000028 }, + { CS35L41_SP_FORMAT, 0x10100200 }, + { CS35L41_SP_HIZ_CTRL, 0x00000002 }, + { CS35L41_SP_FRAME_TX_SLOT, 0x03020100 }, + { CS35L41_SP_FRAME_RX_SLOT, 0x00000100 }, + { CS35L41_SP_TX_WL, 0x00000010 }, + { CS35L41_SP_RX_WL, 0x00000018 }, + { CS35L41_DAC_PCM1_SRC, 0x00000008 }, + { CS35L41_ASP_TX1_SRC, 0x00000018 }, + { CS35L41_ASP_TX2_SRC, 0x00000019 }, + { CS35L41_ASP_TX3_SRC, 0x00000020 }, + { CS35L41_ASP_TX4_SRC, 0x00000021 }, + { CS35L41_DSP1_RX1_SRC, 0x00000008 }, + { CS35L41_DSP1_RX2_SRC, 0x00000009 }, + { CS35L41_DSP1_RX3_SRC, 0x00000018 }, + { CS35L41_DSP1_RX4_SRC, 0x00000019 }, + { CS35L41_DSP1_RX5_SRC, 0x00000020 }, + { CS35L41_DSP1_RX6_SRC, 0x00000021 }, + { CS35L41_DSP1_RX7_SRC, 0x0000003A }, + { CS35L41_DSP1_RX8_SRC, 0x00000001 }, + { CS35L41_NGATE1_SRC, 0x00000008 }, + { CS35L41_NGATE2_SRC, 0x00000009 }, + { CS35L41_AMP_DIG_VOL_CTRL, 0x00008000 }, + { CS35L41_VPBR_CFG, 0x02AA1905 }, + { CS35L41_VBBR_CFG, 0x02AA1905 }, + { CS35L41_VPBR_STATUS, 0x00000000 }, + { CS35L41_VBBR_STATUS, 0x00000000 }, + { CS35L41_OVERTEMP_CFG, 0x00000001 }, + { CS35L41_AMP_ERR_VOL, 0x00000000 }, + { CS35L41_VOL_STATUS_TO_DSP, 0x00000000 }, + { CS35L41_CLASSH_CFG, 0x000B0405 }, + { CS35L41_WKFET_CFG, 0x00000111 }, + { CS35L41_NG_CFG, 0x00000033 }, + { CS35L41_AMP_GAIN_CTRL, 0x00000273 }, + { CS35L41_DAC_MSM_CFG, 0x00580000 }, + { CS35L41_GPIO1_CTRL1, 0xE1000001 }, + { CS35L41_GPIO2_CTRL1, 0xE1000001 }, + { CS35L41_MIXER_NGATE_CFG, 0x00000000 }, + { CS35L41_MIXER_NGATE_CH1_CFG, 0x00000303 }, + { CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303 }, + { CS35L41_CLOCK_DETECT_1, 0x00000000 }, + { CS35L41_TIMER1_CONTROL, 0x00000000 }, + { CS35L41_TIMER1_COUNT_PRESET, 0x00000000 }, + { CS35L41_TIMER1_START_STOP, 0x00000000 }, + { CS35L41_TIMER1_STATUS, 0x00000000 }, + { CS35L41_TIMER1_COUNT_READBACK, 0x00000000 }, + { CS35L41_TIMER1_DSP_CLK_CFG, 0x00000000 }, + { CS35L41_TIMER1_DSP_CLK_STATUS, 0x00000000 }, + { CS35L41_TIMER2_CONTROL, 0x00000000 }, + { CS35L41_TIMER2_COUNT_PRESET, 0x00000000 }, + { CS35L41_TIMER2_START_STOP, 0x00000000 }, + { CS35L41_TIMER2_STATUS, 0x00000000 }, + { CS35L41_TIMER2_COUNT_READBACK, 0x00000000 }, + { CS35L41_TIMER2_DSP_CLK_CFG, 0x00000000 }, + { CS35L41_TIMER2_DSP_CLK_STATUS, 0x00000000 }, + { CS35L41_DFT_JTAG_CONTROL, 0x00000000 }, + { CS35L41_DIE_STS1, 0x00000000 }, + { CS35L41_DIE_STS2, 0x00000000 }, + { CS35L41_TEMP_CAL1, 0x00000000 }, + { CS35L41_TEMP_CAL2, 0x00000000 }, +}; + +bool cs35l41_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L41_DEVID: + case CS35L41_REVID: + case CS35L41_FABID: + case CS35L41_RELID: + case CS35L41_OTPID: + case CS35L41_TEST_KEY_CTL: + case CS35L41_USER_KEY_CTL: + case CS35L41_OTP_CTRL0: + case CS35L41_OTP_CTRL3: + case CS35L41_OTP_CTRL4: + case CS35L41_OTP_CTRL5: + case CS35L41_OTP_CTRL6: + case CS35L41_OTP_CTRL7: + case CS35L41_OTP_CTRL8: + case CS35L41_PWR_CTRL1: + case CS35L41_PWR_CTRL2: + case CS35L41_PWR_CTRL3: + case CS35L41_CTRL_OVRRIDE: + case CS35L41_AMP_OUT_MUTE: + case CS35L41_PROTECT_REL_ERR_IGN: + case CS35L41_GPIO_PAD_CONTROL: + case CS35L41_JTAG_CONTROL: + case CS35L41_PLL_CLK_CTRL: + case CS35L41_DSP_CLK_CTRL: + case CS35L41_GLOBAL_CLK_CTRL: + case CS35L41_DATA_FS_SEL: + case CS35L41_MDSYNC_EN: + case CS35L41_MDSYNC_TX_ID: + case CS35L41_MDSYNC_PWR_CTRL: + case CS35L41_MDSYNC_DATA_TX: + case CS35L41_MDSYNC_TX_STATUS: + case CS35L41_MDSYNC_DATA_RX: + case CS35L41_MDSYNC_RX_STATUS: + case CS35L41_MDSYNC_ERR_STATUS: + case CS35L41_MDSYNC_SYNC_PTE2: + case CS35L41_MDSYNC_SYNC_PTE3: + case CS35L41_MDSYNC_SYNC_MSM_STATUS: + case CS35L41_BSTCVRT_VCTRL1: + case CS35L41_BSTCVRT_VCTRL2: + case CS35L41_BSTCVRT_PEAK_CUR: + case CS35L41_BSTCVRT_SFT_RAMP: + case CS35L41_BSTCVRT_COEFF: + case CS35L41_BSTCVRT_SLOPE_LBST: + case CS35L41_BSTCVRT_SW_FREQ: + case CS35L41_BSTCVRT_DCM_CTRL: + case CS35L41_BSTCVRT_DCM_MODE_FORCE: + case CS35L41_BSTCVRT_OVERVOLT_CTRL: + case CS35L41_VI_VOL_POL: + case CS35L41_DTEMP_WARN_THLD: + case CS35L41_DTEMP_CFG: + case CS35L41_DTEMP_EN: + case CS35L41_VPVBST_FS_SEL: + case CS35L41_SP_ENABLES: + case CS35L41_SP_RATE_CTRL: + case CS35L41_SP_FORMAT: + case CS35L41_SP_HIZ_CTRL: + case CS35L41_SP_FRAME_TX_SLOT: + case CS35L41_SP_FRAME_RX_SLOT: + case CS35L41_SP_TX_WL: + case CS35L41_SP_RX_WL: + case CS35L41_DAC_PCM1_SRC: + case CS35L41_ASP_TX1_SRC: + case CS35L41_ASP_TX2_SRC: + case CS35L41_ASP_TX3_SRC: + case CS35L41_ASP_TX4_SRC: + case CS35L41_DSP1_RX1_SRC: + case CS35L41_DSP1_RX2_SRC: + case CS35L41_DSP1_RX3_SRC: + case CS35L41_DSP1_RX4_SRC: + case CS35L41_DSP1_RX5_SRC: + case CS35L41_DSP1_RX6_SRC: + case CS35L41_DSP1_RX7_SRC: + case CS35L41_DSP1_RX8_SRC: + case CS35L41_NGATE1_SRC: + case CS35L41_NGATE2_SRC: + case CS35L41_AMP_DIG_VOL_CTRL: + case CS35L41_VPBR_CFG: + case CS35L41_VBBR_CFG: + case CS35L41_VPBR_STATUS: + case CS35L41_VBBR_STATUS: + case CS35L41_OVERTEMP_CFG: + case CS35L41_AMP_ERR_VOL: + case CS35L41_VOL_STATUS_TO_DSP: + case CS35L41_CLASSH_CFG: + case CS35L41_WKFET_CFG: + case CS35L41_NG_CFG: + case CS35L41_AMP_GAIN_CTRL: + case CS35L41_DAC_MSM_CFG: + case CS35L41_IRQ1_CFG: + case CS35L41_IRQ1_STATUS: + case CS35L41_IRQ1_STATUS1: + case CS35L41_IRQ1_STATUS2: + case CS35L41_IRQ1_STATUS3: + case CS35L41_IRQ1_STATUS4: + case CS35L41_IRQ1_RAW_STATUS1: + case CS35L41_IRQ1_RAW_STATUS2: + case CS35L41_IRQ1_RAW_STATUS3: + case CS35L41_IRQ1_RAW_STATUS4: + case CS35L41_IRQ1_MASK1: + case CS35L41_IRQ1_MASK2: + case CS35L41_IRQ1_MASK3: + case CS35L41_IRQ1_MASK4: + case CS35L41_IRQ1_FRC1: + case CS35L41_IRQ1_FRC2: + case CS35L41_IRQ1_FRC3: + case CS35L41_IRQ1_FRC4: + case CS35L41_IRQ1_EDGE1: + case CS35L41_IRQ1_EDGE4: + case CS35L41_IRQ1_POL1: + case CS35L41_IRQ1_POL2: + case CS35L41_IRQ1_POL3: + case CS35L41_IRQ1_POL4: + case CS35L41_IRQ1_DB3: + case CS35L41_IRQ2_CFG: + case CS35L41_IRQ2_STATUS: + case CS35L41_IRQ2_STATUS1: + case CS35L41_IRQ2_STATUS2: + case CS35L41_IRQ2_STATUS3: + case CS35L41_IRQ2_STATUS4: + case CS35L41_IRQ2_RAW_STATUS1: + case CS35L41_IRQ2_RAW_STATUS2: + case CS35L41_IRQ2_RAW_STATUS3: + case CS35L41_IRQ2_RAW_STATUS4: + case CS35L41_IRQ2_MASK1: + case CS35L41_IRQ2_MASK2: + case CS35L41_IRQ2_MASK3: + case CS35L41_IRQ2_MASK4: + case CS35L41_IRQ2_FRC1: + case CS35L41_IRQ2_FRC2: + case CS35L41_IRQ2_FRC3: + case CS35L41_IRQ2_FRC4: + case CS35L41_IRQ2_EDGE1: + case CS35L41_IRQ2_EDGE4: + case CS35L41_IRQ2_POL1: + case CS35L41_IRQ2_POL2: + case CS35L41_IRQ2_POL3: + case CS35L41_IRQ2_POL4: + case CS35L41_IRQ2_DB3: + case CS35L41_GPIO_STATUS1: + case CS35L41_GPIO1_CTRL1: + case CS35L41_GPIO2_CTRL1: + case CS35L41_MIXER_NGATE_CFG: + case CS35L41_MIXER_NGATE_CH1_CFG: + case CS35L41_MIXER_NGATE_CH2_CFG: + case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: + case CS35L41_CLOCK_DETECT_1: + case CS35L41_TIMER1_CONTROL: + case CS35L41_TIMER1_COUNT_PRESET: + case CS35L41_TIMER1_STATUS: + case CS35L41_TIMER1_COUNT_READBACK: + case CS35L41_TIMER1_DSP_CLK_CFG: + case CS35L41_TIMER1_DSP_CLK_STATUS: + case CS35L41_TIMER2_CONTROL: + case CS35L41_TIMER2_COUNT_PRESET: + case CS35L41_TIMER2_STATUS: + case CS35L41_TIMER2_COUNT_READBACK: + case CS35L41_TIMER2_DSP_CLK_CFG: + case CS35L41_TIMER2_DSP_CLK_STATUS: + case CS35L41_DFT_JTAG_CONTROL: + case CS35L41_DIE_STS1: + case CS35L41_DIE_STS2: + case CS35L41_TEMP_CAL1: + case CS35L41_TEMP_CAL2: + case CS35L41_DSP1_TIMESTAMP_COUNT: + case CS35L41_DSP1_SYS_ID: + case CS35L41_DSP1_SYS_VERSION: + case CS35L41_DSP1_SYS_CORE_ID: + case CS35L41_DSP1_SYS_AHB_ADDR: + case CS35L41_DSP1_SYS_XSRAM_SIZE: + case CS35L41_DSP1_SYS_YSRAM_SIZE: + case CS35L41_DSP1_SYS_PSRAM_SIZE: + case CS35L41_DSP1_SYS_PM_BOOT_SIZE: + case CS35L41_DSP1_SYS_FEATURES: + case CS35L41_DSP1_SYS_FIR_FILTERS: + case CS35L41_DSP1_SYS_LMS_FILTERS: + case CS35L41_DSP1_SYS_XM_BANK_SIZE: + case CS35L41_DSP1_SYS_YM_BANK_SIZE: + case CS35L41_DSP1_SYS_PM_BANK_SIZE: + case CS35L41_DSP1_AHBM_WIN0_CTRL0: + case CS35L41_DSP1_AHBM_WIN0_CTRL1: + case CS35L41_DSP1_AHBM_WIN1_CTRL0: + case CS35L41_DSP1_AHBM_WIN1_CTRL1: + case CS35L41_DSP1_AHBM_WIN2_CTRL0: + case CS35L41_DSP1_AHBM_WIN2_CTRL1: + case CS35L41_DSP1_AHBM_WIN3_CTRL0: + case CS35L41_DSP1_AHBM_WIN3_CTRL1: + case CS35L41_DSP1_AHBM_WIN4_CTRL0: + case CS35L41_DSP1_AHBM_WIN4_CTRL1: + case CS35L41_DSP1_AHBM_WIN5_CTRL0: + case CS35L41_DSP1_AHBM_WIN5_CTRL1: + case CS35L41_DSP1_AHBM_WIN6_CTRL0: + case CS35L41_DSP1_AHBM_WIN6_CTRL1: + case CS35L41_DSP1_AHBM_WIN7_CTRL0: + case CS35L41_DSP1_AHBM_WIN7_CTRL1: + case CS35L41_DSP1_AHBM_WIN_DBG_CTRL0: + case CS35L41_DSP1_AHBM_WIN_DBG_CTRL1: + case CS35L41_DSP1_DEBUG: + case CS35L41_DSP1_TIMER_CTRL: + case CS35L41_DSP1_RX1_RATE: + case CS35L41_DSP1_RX2_RATE: + case CS35L41_DSP1_RX3_RATE: + case CS35L41_DSP1_RX4_RATE: + case CS35L41_DSP1_RX5_RATE: + case CS35L41_DSP1_RX6_RATE: + case CS35L41_DSP1_RX7_RATE: + case CS35L41_DSP1_RX8_RATE: + case CS35L41_DSP1_TX1_RATE: + case CS35L41_DSP1_TX2_RATE: + case CS35L41_DSP1_TX3_RATE: + case CS35L41_DSP1_TX4_RATE: + case CS35L41_DSP1_TX5_RATE: + case CS35L41_DSP1_TX6_RATE: + case CS35L41_DSP1_TX7_RATE: + case CS35L41_DSP1_TX8_RATE: + case CS35L41_DSP1_NMI_CTRL1: + case CS35L41_DSP1_NMI_CTRL2: + case CS35L41_DSP1_NMI_CTRL3: + case CS35L41_DSP1_NMI_CTRL4: + case CS35L41_DSP1_NMI_CTRL5: + case CS35L41_DSP1_NMI_CTRL6: + case CS35L41_DSP1_NMI_CTRL7: + case CS35L41_DSP1_NMI_CTRL8: + case CS35L41_DSP1_RESUME_CTRL: + case CS35L41_DSP1_IRQ1_CTRL: + case CS35L41_DSP1_IRQ2_CTRL: + case CS35L41_DSP1_IRQ3_CTRL: + case CS35L41_DSP1_IRQ4_CTRL: + case CS35L41_DSP1_IRQ5_CTRL: + case CS35L41_DSP1_IRQ6_CTRL: + case CS35L41_DSP1_IRQ7_CTRL: + case CS35L41_DSP1_IRQ8_CTRL: + case CS35L41_DSP1_IRQ9_CTRL: + case CS35L41_DSP1_IRQ10_CTRL: + case CS35L41_DSP1_IRQ11_CTRL: + case CS35L41_DSP1_IRQ12_CTRL: + case CS35L41_DSP1_IRQ13_CTRL: + case CS35L41_DSP1_IRQ14_CTRL: + case CS35L41_DSP1_IRQ15_CTRL: + case CS35L41_DSP1_IRQ16_CTRL: + case CS35L41_DSP1_IRQ17_CTRL: + case CS35L41_DSP1_IRQ18_CTRL: + case CS35L41_DSP1_IRQ19_CTRL: + case CS35L41_DSP1_IRQ20_CTRL: + case CS35L41_DSP1_IRQ21_CTRL: + case CS35L41_DSP1_IRQ22_CTRL: + case CS35L41_DSP1_IRQ23_CTRL: + case CS35L41_DSP1_SCRATCH1: + case CS35L41_DSP1_SCRATCH2: + case CS35L41_DSP1_SCRATCH3: + case CS35L41_DSP1_SCRATCH4: + case CS35L41_DSP1_CCM_CORE_CTRL: + case CS35L41_DSP1_CCM_CLK_OVERRIDE: + case CS35L41_DSP1_XM_MSTR_EN: + case CS35L41_DSP1_XM_CORE_PRI: + case CS35L41_DSP1_XM_AHB_PACK_PL_PRI: + case CS35L41_DSP1_XM_AHB_UP_PL_PRI: + case CS35L41_DSP1_XM_ACCEL_PL0_PRI: + case CS35L41_DSP1_XM_NPL0_PRI: + case CS35L41_DSP1_YM_MSTR_EN: + case CS35L41_DSP1_YM_CORE_PRI: + case CS35L41_DSP1_YM_AHB_PACK_PL_PRI: + case CS35L41_DSP1_YM_AHB_UP_PL_PRI: + case CS35L41_DSP1_YM_ACCEL_PL0_PRI: + case CS35L41_DSP1_YM_NPL0_PRI: + case CS35L41_DSP1_PM_MSTR_EN: + case CS35L41_DSP1_PM_PATCH0_ADDR: + case CS35L41_DSP1_PM_PATCH0_EN: + case CS35L41_DSP1_PM_PATCH0_DATA_LO: + case CS35L41_DSP1_PM_PATCH0_DATA_HI: + case CS35L41_DSP1_PM_PATCH1_ADDR: + case CS35L41_DSP1_PM_PATCH1_EN: + case CS35L41_DSP1_PM_PATCH1_DATA_LO: + case CS35L41_DSP1_PM_PATCH1_DATA_HI: + case CS35L41_DSP1_PM_PATCH2_ADDR: + case CS35L41_DSP1_PM_PATCH2_EN: + case CS35L41_DSP1_PM_PATCH2_DATA_LO: + case CS35L41_DSP1_PM_PATCH2_DATA_HI: + case CS35L41_DSP1_PM_PATCH3_ADDR: + case CS35L41_DSP1_PM_PATCH3_EN: + case CS35L41_DSP1_PM_PATCH3_DATA_LO: + case CS35L41_DSP1_PM_PATCH3_DATA_HI: + case CS35L41_DSP1_PM_PATCH4_ADDR: + case CS35L41_DSP1_PM_PATCH4_EN: + case CS35L41_DSP1_PM_PATCH4_DATA_LO: + case CS35L41_DSP1_PM_PATCH4_DATA_HI: + case CS35L41_DSP1_PM_PATCH5_ADDR: + case CS35L41_DSP1_PM_PATCH5_EN: + case CS35L41_DSP1_PM_PATCH5_DATA_LO: + case CS35L41_DSP1_PM_PATCH5_DATA_HI: + case CS35L41_DSP1_PM_PATCH6_ADDR: + case CS35L41_DSP1_PM_PATCH6_EN: + case CS35L41_DSP1_PM_PATCH6_DATA_LO: + case CS35L41_DSP1_PM_PATCH6_DATA_HI: + case CS35L41_DSP1_PM_PATCH7_ADDR: + case CS35L41_DSP1_PM_PATCH7_EN: + case CS35L41_DSP1_PM_PATCH7_DATA_LO: + case CS35L41_DSP1_PM_PATCH7_DATA_HI: + case CS35L41_DSP1_MPU_XM_ACCESS0: + case CS35L41_DSP1_MPU_YM_ACCESS0: + case CS35L41_DSP1_MPU_WNDW_ACCESS0: + case CS35L41_DSP1_MPU_XREG_ACCESS0: + case CS35L41_DSP1_MPU_YREG_ACCESS0: + case CS35L41_DSP1_MPU_XM_ACCESS1: + case CS35L41_DSP1_MPU_YM_ACCESS1: + case CS35L41_DSP1_MPU_WNDW_ACCESS1: + case CS35L41_DSP1_MPU_XREG_ACCESS1: + case CS35L41_DSP1_MPU_YREG_ACCESS1: + case CS35L41_DSP1_MPU_XM_ACCESS2: + case CS35L41_DSP1_MPU_YM_ACCESS2: + case CS35L41_DSP1_MPU_WNDW_ACCESS2: + case CS35L41_DSP1_MPU_XREG_ACCESS2: + case CS35L41_DSP1_MPU_YREG_ACCESS2: + case CS35L41_DSP1_MPU_XM_ACCESS3: + case CS35L41_DSP1_MPU_YM_ACCESS3: + case CS35L41_DSP1_MPU_WNDW_ACCESS3: + case CS35L41_DSP1_MPU_XREG_ACCESS3: + case CS35L41_DSP1_MPU_YREG_ACCESS3: + case CS35L41_DSP1_MPU_XM_VIO_ADDR: + case CS35L41_DSP1_MPU_XM_VIO_STATUS: + case CS35L41_DSP1_MPU_YM_VIO_ADDR: + case CS35L41_DSP1_MPU_YM_VIO_STATUS: + case CS35L41_DSP1_MPU_PM_VIO_ADDR: + case CS35L41_DSP1_MPU_PM_VIO_STATUS: + case CS35L41_DSP1_MPU_LOCK_CONFIG: + case CS35L41_DSP1_MPU_WDT_RST_CTRL: + case CS35L41_DSP1_STRMARB_MSTR0_CFG0: + case CS35L41_DSP1_STRMARB_MSTR0_CFG1: + case CS35L41_DSP1_STRMARB_MSTR0_CFG2: + case CS35L41_DSP1_STRMARB_MSTR1_CFG0: + case CS35L41_DSP1_STRMARB_MSTR1_CFG1: + case CS35L41_DSP1_STRMARB_MSTR1_CFG2: + case CS35L41_DSP1_STRMARB_MSTR2_CFG0: + case CS35L41_DSP1_STRMARB_MSTR2_CFG1: + case CS35L41_DSP1_STRMARB_MSTR2_CFG2: + case CS35L41_DSP1_STRMARB_MSTR3_CFG0: + case CS35L41_DSP1_STRMARB_MSTR3_CFG1: + case CS35L41_DSP1_STRMARB_MSTR3_CFG2: + case CS35L41_DSP1_STRMARB_MSTR4_CFG0: + case CS35L41_DSP1_STRMARB_MSTR4_CFG1: + case CS35L41_DSP1_STRMARB_MSTR4_CFG2: + case CS35L41_DSP1_STRMARB_MSTR5_CFG0: + case CS35L41_DSP1_STRMARB_MSTR5_CFG1: + case CS35L41_DSP1_STRMARB_MSTR5_CFG2: + case CS35L41_DSP1_STRMARB_MSTR6_CFG0: + case CS35L41_DSP1_STRMARB_MSTR6_CFG1: + case CS35L41_DSP1_STRMARB_MSTR6_CFG2: + case CS35L41_DSP1_STRMARB_MSTR7_CFG0: + case CS35L41_DSP1_STRMARB_MSTR7_CFG1: + case CS35L41_DSP1_STRMARB_MSTR7_CFG2: + case CS35L41_DSP1_STRMARB_TX0_CFG0: + case CS35L41_DSP1_STRMARB_TX0_CFG1: + case CS35L41_DSP1_STRMARB_TX1_CFG0: + case CS35L41_DSP1_STRMARB_TX1_CFG1: + case CS35L41_DSP1_STRMARB_TX2_CFG0: + case CS35L41_DSP1_STRMARB_TX2_CFG1: + case CS35L41_DSP1_STRMARB_TX3_CFG0: + case CS35L41_DSP1_STRMARB_TX3_CFG1: + case CS35L41_DSP1_STRMARB_TX4_CFG0: + case CS35L41_DSP1_STRMARB_TX4_CFG1: + case CS35L41_DSP1_STRMARB_TX5_CFG0: + case CS35L41_DSP1_STRMARB_TX5_CFG1: + case CS35L41_DSP1_STRMARB_TX6_CFG0: + case CS35L41_DSP1_STRMARB_TX6_CFG1: + case CS35L41_DSP1_STRMARB_TX7_CFG0: + case CS35L41_DSP1_STRMARB_TX7_CFG1: + case CS35L41_DSP1_STRMARB_RX0_CFG0: + case CS35L41_DSP1_STRMARB_RX0_CFG1: + case CS35L41_DSP1_STRMARB_RX1_CFG0: + case CS35L41_DSP1_STRMARB_RX1_CFG1: + case CS35L41_DSP1_STRMARB_RX2_CFG0: + case CS35L41_DSP1_STRMARB_RX2_CFG1: + case CS35L41_DSP1_STRMARB_RX3_CFG0: + case CS35L41_DSP1_STRMARB_RX3_CFG1: + case CS35L41_DSP1_STRMARB_RX4_CFG0: + case CS35L41_DSP1_STRMARB_RX4_CFG1: + case CS35L41_DSP1_STRMARB_RX5_CFG0: + case CS35L41_DSP1_STRMARB_RX5_CFG1: + case CS35L41_DSP1_STRMARB_RX6_CFG0: + case CS35L41_DSP1_STRMARB_RX6_CFG1: + case CS35L41_DSP1_STRMARB_RX7_CFG0: + case CS35L41_DSP1_STRMARB_RX7_CFG1: + case CS35L41_DSP1_STRMARB_IRQ0_CFG0: + case CS35L41_DSP1_STRMARB_IRQ0_CFG1: + case CS35L41_DSP1_STRMARB_IRQ0_CFG2: + case CS35L41_DSP1_STRMARB_IRQ1_CFG0: + case CS35L41_DSP1_STRMARB_IRQ1_CFG1: + case CS35L41_DSP1_STRMARB_IRQ1_CFG2: + case CS35L41_DSP1_STRMARB_IRQ2_CFG0: + case CS35L41_DSP1_STRMARB_IRQ2_CFG1: + case CS35L41_DSP1_STRMARB_IRQ2_CFG2: + case CS35L41_DSP1_STRMARB_IRQ3_CFG0: + case CS35L41_DSP1_STRMARB_IRQ3_CFG1: + case CS35L41_DSP1_STRMARB_IRQ3_CFG2: + case CS35L41_DSP1_STRMARB_IRQ4_CFG0: + case CS35L41_DSP1_STRMARB_IRQ4_CFG1: + case CS35L41_DSP1_STRMARB_IRQ4_CFG2: + case CS35L41_DSP1_STRMARB_IRQ5_CFG0: + case CS35L41_DSP1_STRMARB_IRQ5_CFG1: + case CS35L41_DSP1_STRMARB_IRQ5_CFG2: + case CS35L41_DSP1_STRMARB_IRQ6_CFG0: + case CS35L41_DSP1_STRMARB_IRQ6_CFG1: + case CS35L41_DSP1_STRMARB_IRQ6_CFG2: + case CS35L41_DSP1_STRMARB_IRQ7_CFG0: + case CS35L41_DSP1_STRMARB_IRQ7_CFG1: + case CS35L41_DSP1_STRMARB_IRQ7_CFG2: + case CS35L41_DSP1_STRMARB_RESYNC_MSK: + case CS35L41_DSP1_STRMARB_ERR_STATUS: + case CS35L41_DSP1_INTPCTL_RES_STATIC: + case CS35L41_DSP1_INTPCTL_RES_DYN: + case CS35L41_DSP1_INTPCTL_NMI_CTRL: + case CS35L41_DSP1_INTPCTL_IRQ_INV: + case CS35L41_DSP1_INTPCTL_IRQ_MODE: + case CS35L41_DSP1_INTPCTL_IRQ_EN: + case CS35L41_DSP1_INTPCTL_IRQ_MSK: + case CS35L41_DSP1_INTPCTL_IRQ_ERR: + case CS35L41_DSP1_INTPCTL_IRQ_PEND: + case CS35L41_DSP1_INTPCTL_TESTBITS: + case CS35L41_DSP1_WDT_CONTROL: + case CS35L41_DSP1_WDT_STATUS: + case CS35L41_OTP_TRIM_1: + case CS35L41_OTP_TRIM_2: + case CS35L41_OTP_TRIM_3: + case CS35L41_OTP_TRIM_4: + case CS35L41_OTP_TRIM_5: + case CS35L41_OTP_TRIM_6: + case CS35L41_OTP_TRIM_7: + case CS35L41_OTP_TRIM_8: + case CS35L41_OTP_TRIM_9: + case CS35L41_OTP_TRIM_10: + case CS35L41_OTP_TRIM_11: + case CS35L41_OTP_TRIM_12: + case CS35L41_OTP_TRIM_13: + case CS35L41_OTP_TRIM_14: + case CS35L41_OTP_TRIM_15: + case CS35L41_OTP_TRIM_16: + case CS35L41_OTP_TRIM_17: + case CS35L41_OTP_TRIM_18: + case CS35L41_OTP_TRIM_19: + case CS35L41_OTP_TRIM_20: + case CS35L41_OTP_TRIM_21: + case CS35L41_OTP_TRIM_22: + case CS35L41_OTP_TRIM_23: + case CS35L41_OTP_TRIM_24: + case CS35L41_OTP_TRIM_25: + case CS35L41_OTP_TRIM_26: + case CS35L41_OTP_TRIM_27: + case CS35L41_OTP_TRIM_28: + case CS35L41_OTP_TRIM_29: + case CS35L41_OTP_TRIM_30: + case CS35L41_OTP_TRIM_31: + case CS35L41_OTP_TRIM_32: + case CS35L41_OTP_TRIM_33: + case CS35L41_OTP_TRIM_34: + case CS35L41_OTP_TRIM_35: + case CS35L41_OTP_TRIM_36: + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: + case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: + case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: + case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: + case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: + case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: + case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: + case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: + /*test regs*/ + case CS35L41_PLL_OVR: + case CS35L41_BST_TEST_DUTY: + case CS35L41_DIGPWM_IOCTRL: + return true; + default: + return false; + } +} + +bool cs35l41_precious_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: + return true; + default: + return false; + } +} + +bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L41_DEVID: + case CS35L41_SFT_RESET: + case CS35L41_FABID: + case CS35L41_REVID: + case CS35L41_DTEMP_EN: + case CS35L41_IRQ1_STATUS: + case CS35L41_IRQ1_STATUS1: + case CS35L41_IRQ1_STATUS2: + case CS35L41_IRQ1_STATUS3: + case CS35L41_IRQ1_STATUS4: + case CS35L41_IRQ1_RAW_STATUS1: + case CS35L41_IRQ1_RAW_STATUS2: + case CS35L41_IRQ1_RAW_STATUS3: + case CS35L41_IRQ1_RAW_STATUS4: + case CS35L41_IRQ1_FRC1: + case CS35L41_IRQ1_FRC2: + case CS35L41_IRQ1_FRC3: + case CS35L41_IRQ1_FRC4: + case CS35L41_IRQ1_EDGE1: + case CS35L41_IRQ1_EDGE4: + case CS35L41_IRQ1_POL1: + case CS35L41_IRQ1_POL2: + case CS35L41_IRQ1_POL3: + case CS35L41_IRQ1_POL4: + case CS35L41_IRQ1_DB3: + case CS35L41_IRQ2_STATUS: + case CS35L41_IRQ2_STATUS1: + case CS35L41_IRQ2_STATUS2: + case CS35L41_IRQ2_STATUS3: + case CS35L41_IRQ2_STATUS4: + case CS35L41_IRQ2_RAW_STATUS1: + case CS35L41_IRQ2_RAW_STATUS2: + case CS35L41_IRQ2_RAW_STATUS3: + case CS35L41_IRQ2_RAW_STATUS4: + case CS35L41_IRQ2_FRC1: + case CS35L41_IRQ2_FRC2: + case CS35L41_IRQ2_FRC3: + case CS35L41_IRQ2_FRC4: + case CS35L41_IRQ2_EDGE1: + case CS35L41_IRQ2_EDGE4: + case CS35L41_IRQ2_POL1: + case CS35L41_IRQ2_POL2: + case CS35L41_IRQ2_POL3: + case CS35L41_IRQ2_POL4: + case CS35L41_IRQ2_DB3: + case CS35L41_GPIO_STATUS1: + case CS35L41_OTP_TRIM_1: + case CS35L41_OTP_TRIM_2: + case CS35L41_OTP_TRIM_3: + case CS35L41_OTP_TRIM_4: + case CS35L41_OTP_TRIM_5: + case CS35L41_OTP_TRIM_6: + case CS35L41_OTP_TRIM_7: + case CS35L41_OTP_TRIM_8: + case CS35L41_OTP_TRIM_9: + case CS35L41_OTP_TRIM_10: + case CS35L41_OTP_TRIM_11: + case CS35L41_OTP_TRIM_12: + case CS35L41_OTP_TRIM_13: + case CS35L41_OTP_TRIM_14: + case CS35L41_OTP_TRIM_15: + case CS35L41_OTP_TRIM_16: + case CS35L41_OTP_TRIM_17: + case CS35L41_OTP_TRIM_18: + case CS35L41_OTP_TRIM_19: + case CS35L41_OTP_TRIM_20: + case CS35L41_OTP_TRIM_21: + case CS35L41_OTP_TRIM_22: + case CS35L41_OTP_TRIM_23: + case CS35L41_OTP_TRIM_24: + case CS35L41_OTP_TRIM_25: + case CS35L41_OTP_TRIM_26: + case CS35L41_OTP_TRIM_27: + case CS35L41_OTP_TRIM_28: + case CS35L41_OTP_TRIM_29: + case CS35L41_OTP_TRIM_30: + case CS35L41_OTP_TRIM_31: + case CS35L41_OTP_TRIM_32: + case CS35L41_OTP_TRIM_33: + case CS35L41_OTP_TRIM_34: + case CS35L41_OTP_TRIM_35: + case CS35L41_OTP_TRIM_36: + case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: + case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: + case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: + case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: + case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: + case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: + case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: + case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: + case CS35L41_DSP1_CCM_CORE_CTRL ... CS35L41_DSP1_WDT_STATUS: + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: + return true; + default: + return false; + } +} + +static const struct cs35l41_otp_packed_element_t + otp_map_1[CS35L41_NUM_OTP_ELEM] = { + /* addr shift size */ + { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ + { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ + { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ + { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ + { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ + { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ + { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ + { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ + { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ + { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ + { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ + { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ + { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ + { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ + { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ + { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ + { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ + { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ + { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ + { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ + { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ + { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ + { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ + { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ + { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ + { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ + { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ + { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ + { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ + { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ + { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ + { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ + { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ + { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ + { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ + { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ + { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ + { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ + { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ + { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ + { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ + { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ + { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ + { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ + { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ + { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ + { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ + { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ + { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ + { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ + { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ + { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ + { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ + { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ + { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ + { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ + { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ + { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ + { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ + { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ + { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ + { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ + { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ + { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ + { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ + { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ + { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ + { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ + { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ + { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ + { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ + { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ + { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ + { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ + { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ + { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ + { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ + { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ + { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ + { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ + { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ + { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ + { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ + { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ + { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ + { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ + { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ + { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ + { 0x00007434, 17, 1 }, /*FORCE_CAL*/ + { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ + { 0x00007068, 0, 9 }, /*MODIX*/ + { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ + { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ + { 0x00000000, 0, 1 }, /*extra bit*/ + { 0x00017040, 0, 8 }, /*X_COORDINATE*/ + { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ + { 0x00017040, 16, 8 }, /*WAFER_ID*/ + { 0x00017040, 24, 8 }, /*DVS*/ + { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ + }; + +static const struct cs35l41_otp_packed_element_t + otp_map_2[CS35L41_NUM_OTP_ELEM] = { + /* addr shift size */ + { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ + { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ + { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ + { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ + { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ + { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ + { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ + { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ + { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ + { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ + { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ + { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ + { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ + { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ + { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ + { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ + { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ + { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ + { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ + { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ + { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ + { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ + { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ + { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ + { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ + { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ + { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ + { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ + { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ + { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ + { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ + { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ + { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ + { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ + { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ + { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ + { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ + { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ + { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ + { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ + { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ + { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ + { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ + { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ + { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ + { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ + { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ + { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ + { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ + { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ + { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ + { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ + { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ + { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ + { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ + { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ + { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ + { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ + { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ + { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ + { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ + { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ + { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ + { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ + { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ + { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ + { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ + { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ + { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ + { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ + { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ + { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ + { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ + { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ + { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ + { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ + { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ + { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ + { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ + { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ + { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ + { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ + { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ + { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ + { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ + { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ + { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ + { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ + { 0x00007434, 17, 1 }, /*FORCE_CAL*/ + { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ + { 0x00007068, 0, 9 }, /*MODIX*/ + { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ + { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ + { 0x00004000, 11, 1 }, /*VMON_POL*/ + { 0x00017040, 0, 8 }, /*X_COORDINATE*/ + { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ + { 0x00017040, 16, 8 }, /*WAFER_ID*/ + { 0x00017040, 24, 8 }, /*DVS*/ + { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ + }; + +const struct cs35l41_otp_map_element_t + cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] = { + { + .id = 0x01, + .map = otp_map_1, + .num_elements = CS35L41_NUM_OTP_ELEM, + .bit_offset = 16, + .word_offset = 2, + }, + { + .id = 0x02, + .map = otp_map_2, + .num_elements = CS35L41_NUM_OTP_ELEM, + .bit_offset = 16, + .word_offset = 2, + }, + { + .id = 0x06, + .map = otp_map_2, + .num_elements = CS35L41_NUM_OTP_ELEM, + .bit_offset = 16, + .word_offset = 2, + }, + }; diff --git a/techpack/audio/asoc/codecs/cs35l41/cs35l41.c b/techpack/audio/asoc/codecs/cs35l41/cs35l41.c new file mode 100644 index 000000000000..47150d81329d --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41/cs35l41.c @@ -0,0 +1,2015 @@ +/* + * cs35l41.c -- CS35l41 ALSA SoC audio driver + * + * Copyright 2018 Cirrus Logic, Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * + * Author: David Rhodes + * Brian Austin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#define DEBUG 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm_adsp.h" +#include "cs35l41.h" +#include + +static const char *const cs35l41_supplies[] = { + "VA", + "VP", +}; + +struct cs35l41_pll_sysclk_config { + int freq; + int clk_cfg; +}; + +static const struct cs35l41_pll_sysclk_config cs35l41_pll_sysclk[] = { + { 32768, 0x00 }, { 8000, 0x01 }, { 11025, 0x02 }, + { 12000, 0x03 }, { 16000, 0x04 }, { 22050, 0x05 }, + { 24000, 0x06 }, { 32000, 0x07 }, { 44100, 0x08 }, + { 48000, 0x09 }, { 88200, 0x0A }, { 96000, 0x0B }, + { 128000, 0x0C }, { 176400, 0x0D }, { 192000, 0x0E }, + { 256000, 0x0F }, { 352800, 0x10 }, { 384000, 0x11 }, + { 512000, 0x12 }, { 705600, 0x13 }, { 750000, 0x14 }, + { 768000, 0x15 }, { 1000000, 0x16 }, { 1024000, 0x17 }, + { 1200000, 0x18 }, { 1411200, 0x19 }, { 1500000, 0x1A }, + { 1536000, 0x1B }, { 2000000, 0x1C }, { 2048000, 0x1D }, + { 2400000, 0x1E }, { 2822400, 0x1F }, { 3000000, 0x20 }, + { 3072000, 0x21 }, { 3200000, 0x22 }, { 4000000, 0x23 }, + { 4096000, 0x24 }, { 4800000, 0x25 }, { 5644800, 0x26 }, + { 6000000, 0x27 }, { 6144000, 0x28 }, { 6250000, 0x29 }, + { 6400000, 0x2A }, { 6500000, 0x2B }, { 6750000, 0x2C }, + { 7526400, 0x2D }, { 8000000, 0x2E }, { 8192000, 0x2F }, + { 9600000, 0x30 }, { 11289600, 0x31 }, { 12000000, 0x32 }, + { 12288000, 0x33 }, { 12500000, 0x34 }, { 12800000, 0x35 }, + { 13000000, 0x36 }, { 13500000, 0x37 }, { 19200000, 0x38 }, + { 22579200, 0x39 }, { 24000000, 0x3A }, { 24576000, 0x3B }, + { 25000000, 0x3C }, { 25600000, 0x3D }, { 26000000, 0x3E }, + { 27000000, 0x3F }, +}; + +static const unsigned char cs35l41_bst_k1_table[4][5] = { + { 0x24, 0x32, 0x32, 0x4F, 0x57 }, + { 0x24, 0x32, 0x32, 0x4F, 0x57 }, + { 0x40, 0x32, 0x32, 0x4F, 0x57 }, + { 0x40, 0x32, 0x32, 0x4F, 0x57 } +}; + +static const unsigned char cs35l41_bst_k2_table[4][5] = { + { 0x24, 0x49, 0x66, 0xA3, 0xEA }, + { 0x24, 0x49, 0x66, 0xA3, 0xEA }, + { 0x48, 0x49, 0x66, 0xA3, 0xEA }, + { 0x48, 0x49, 0x66, 0xA3, 0xEA } +}; + +static const unsigned char cs35l41_bst_slope_table[4] = { 0x75, 0x6B, 0x3B, + 0x28 }; + +static int cs35l41_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, + int source, unsigned int freq, int dir); + +static int cs35l41_dsp_power_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (cs35l41->halo_booted == false) + wm_halo_early_event(w, kcontrol, event); + else + cs35l41->dsp.booted = true; + + return 0; + case SND_SOC_DAPM_PRE_PMD: + if (cs35l41->halo_booted == false) { + wm_halo_early_event(w, kcontrol, event); + wm_halo_event(w, kcontrol, event); + } + default: + return 0; + } +} + +static int cs35l41_dsp_load_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (cs35l41->halo_booted == false) { + wm_halo_event(w, kcontrol, event); + cs35l41->halo_booted = true; + } + default: + return 0; + } +} + +static int cs35l41_halo_booted_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = cs35l41->halo_booted; + + return 0; +} + +static int cs35l41_halo_booted_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec); + + cs35l41->halo_booted = ucontrol->value.integer.value[0]; + + return 0; +} + +static int vendor_id_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = VENDOR_ID_NONE; + + if (cs35l41->pdata.spk_id_gpio_p) + ucontrol->value.integer.value[0] = + spk_id_get(cs35l41->pdata.spk_id_gpio_p); + + return 0; +} + +static const DECLARE_TLV_DB_RANGE(dig_vol_tlv, 0, 0, + TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), 1, + 913, TLV_DB_SCALE_ITEM(-10200, 25, 0)); +static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1); + +static const struct snd_kcontrol_new dre_ctrl = + SOC_DAPM_SINGLE("Switch", CS35L41_PWR_CTRL3, 20, 1, 0); + +static const char *const cs35l41_pcm_sftramp_text[] = { "Off", ".5ms", "1ms", + "2ms", "4ms", "8ms", + "15ms", "30ms" }; + +static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp, CS35L41_AMP_DIG_VOL_CTRL, 0, + cs35l41_pcm_sftramp_text); + +static const char *const cs35l41_cspl_cmd_text[] = { + "CSPL_MBOX_CMD_RESUME", + "CSPL_MBOX_CMD_REINIT", + "CSPL_MBOX_CMD_STOP_PRE_REINIT", +}; + +static const unsigned int cs35l41_cspl_cmd_val[] = { + (unsigned int)CSPL_MBOX_CMD_RESUME, + (unsigned int)CSPL_MBOX_CMD_REINIT, + (unsigned int)CSPL_MBOX_CMD_STOP_PRE_REINIT, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_cspl_cmd, SND_SOC_NOPM, 0, 0, + cs35l41_cspl_cmd_text, cs35l41_cspl_cmd_val); + +static bool cs35l41_is_csplmboxsts_correct(enum cs35l41_cspl_mboxcmd cmd, + enum cs35l41_cspl_mboxstate sts) +{ + switch (cmd) { + case CSPL_MBOX_CMD_NONE: + case CSPL_MBOX_CMD_UNKNOWN_CMD: + return true; + case CSPL_MBOX_CMD_PAUSE: + return (sts == CSPL_MBOX_STS_PAUSED); + case CSPL_MBOX_CMD_RESUME: + return (sts == CSPL_MBOX_STS_RUNNING); + case CSPL_MBOX_CMD_REINIT: + return (sts == CSPL_MBOX_STS_RUNNING); + case CSPL_MBOX_CMD_STOP_PRE_REINIT: + return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT); + default: + return false; + } +} + +static int cs35l41_set_csplmboxcmd(struct cs35l41_private *cs35l41, + enum cs35l41_cspl_mboxcmd cmd) +{ + int ret; + unsigned int sts; + + /* Reset DSP sticky bit */ + regmap_write(cs35l41->regmap, CS35L41_IRQ2_STATUS2, + 1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT); + + /* Reset AP sticky bit */ + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS2, + 1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT); + + /* + * Set mailbox cmd + */ + reinit_completion(&cs35l41->mbox_cmd); + /* Unmask DSP INT */ + regmap_update_bits(cs35l41->regmap, CS35L41_IRQ2_MASK2, + 1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT, 0); + /* Unmask AP INT */ + regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK2, + 1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT, 0); + regmap_write(cs35l41->regmap, CS35L41_CSPL_MBOX_CMD_DRV, cmd); + ret = wait_for_completion_timeout(&cs35l41->mbox_cmd, + msecs_to_jiffies(CS35L41_MBOXWAIT)); + if (ret == 0) { + dev_err(cs35l41->dev, + "Timout waiting for DSP to set mbox cmd\n"); + ret = -ETIMEDOUT; + } + + /* Mask AP INT */ + regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK2, + 1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT, + 1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT); + /* Mask DSP INT */ + regmap_update_bits(cs35l41->regmap, CS35L41_IRQ2_MASK2, + 1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT, + 1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT); + + if (regmap_read(cs35l41->regmap, CS35L41_CSPL_MBOX_STS, &sts) < 0) { + dev_err(cs35l41->dev, "Failed to read %u\n", + CS35L41_CSPL_MBOX_STS); + ret = -EACCES; + } + + if (!cs35l41_is_csplmboxsts_correct(cmd, + (enum cs35l41_cspl_mboxstate)sts)) { + dev_err(cs35l41->dev, + "Failed to set mailbox(cmd: %u, sts: %u)\n", cmd, sts); + ret = -ENOMSG; + } + + return ret; +} + +static int cs35l41_cspl_cmd_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec); + struct soc_enum *soc_enum; + unsigned int i = ucontrol->value.enumerated.item[0]; + + soc_enum = (struct soc_enum *)kcontrol->private_value; + + if (i >= soc_enum->items) { + dev_err(codec->dev, "Invalid mixer input (%u)\n", i); + return -EINVAL; + } + + cs35l41->cspl_cmd = soc_enum->values[i]; + + return 0; +} + +static int cs35l41_cspl_cmd_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec); + struct soc_enum *soc_enum; + unsigned int i; + int ret = 0; + + soc_enum = (struct soc_enum *)kcontrol->private_value; + + for (i = 0; i < soc_enum->items; i++) { + if (cs35l41->cspl_cmd == soc_enum->values[i]) + break; + } + + if (i >= soc_enum->items) { + /* Cannot find value */ + dev_err(cs35l41->dev, "Cannot find cspl cmd\n"); + i = 0; + ret = -EINVAL; + } + + ucontrol->value.enumerated.item[0] = i; + + return ret; +} +static const char *virt_text[] = { "None", "Ref" }; +static SOC_ENUM_SINGLE_DECL(virt_enum, SND_SOC_NOPM, 2, virt_text); + +static const struct snd_kcontrol_new virt_mux = + SOC_DAPM_ENUM("Virt Connect", virt_enum); + +static const char *const cs35l41_pcm_source_texts[] = { "None", "ASP", "DSP" }; +static const unsigned int cs35l41_pcm_source_values[] = { 0x00, 0x08, 0x32 }; +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_pcm_source_enum, CS35L41_DAC_PCM1_SRC, + 0, CS35L41_ASP_SOURCE_MASK, + cs35l41_pcm_source_texts, + cs35l41_pcm_source_values); + +static const struct snd_kcontrol_new pcm_source_mux = + SOC_DAPM_ENUM("PCM Source", cs35l41_pcm_source_enum); + +static const char *const cs35l41_tx_input_texts[] = { + "Zero", "ASPRX1", "ASPRX2", "VMON", "IMON", "VPMON", "DSPTX1", "DSPTX2" +}; +static const unsigned int cs35l41_tx_input_values[] = { + 0x00, + CS35L41_INPUT_SRC_ASPRX1, + CS35L41_INPUT_SRC_ASPRX2, + CS35L41_INPUT_SRC_VMON, + CS35L41_INPUT_SRC_IMON, + CS35L41_INPUT_SRC_VPMON, + CS35L41_INPUT_DSP_TX1, + CS35L41_INPUT_DSP_TX2 +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx1_enum, CS35L41_ASP_TX1_SRC, 0, + CS35L41_ASP_SOURCE_MASK, + cs35l41_tx_input_texts, + cs35l41_tx_input_values); + +static const struct snd_kcontrol_new asp_tx1_mux = + SOC_DAPM_ENUM("ASPTX1 SRC", cs35l41_asptx1_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx2_enum, CS35L41_ASP_TX2_SRC, 0, + CS35L41_ASP_SOURCE_MASK, + cs35l41_tx_input_texts, + cs35l41_tx_input_values); + +static const struct snd_kcontrol_new asp_tx2_mux = + SOC_DAPM_ENUM("ASPTX2 SRC", cs35l41_asptx2_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx3_enum, CS35L41_ASP_TX3_SRC, 0, + CS35L41_ASP_SOURCE_MASK, + cs35l41_tx_input_texts, + cs35l41_tx_input_values); + +static const struct snd_kcontrol_new asp_tx3_mux = + SOC_DAPM_ENUM("ASPTX3 SRC", cs35l41_asptx3_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx4_enum, CS35L41_ASP_TX4_SRC, 0, + CS35L41_ASP_SOURCE_MASK, + cs35l41_tx_input_texts, + cs35l41_tx_input_values); + +static const struct snd_kcontrol_new asp_tx4_mux = + SOC_DAPM_ENUM("ASPTX4 SRC", cs35l41_asptx4_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_dsprx1_enum, CS35L41_DSP1_RX1_SRC, 0, + CS35L41_ASP_SOURCE_MASK, + cs35l41_tx_input_texts, + cs35l41_tx_input_values); + +static const struct snd_kcontrol_new dsp_rx1_mux = + SOC_DAPM_ENUM("DSPRX1 SRC", cs35l41_dsprx1_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_dsprx2_enum, CS35L41_DSP1_RX2_SRC, 0, + CS35L41_ASP_SOURCE_MASK, + cs35l41_tx_input_texts, + cs35l41_tx_input_values); + +static const struct snd_kcontrol_new dsp_rx2_mux = + SOC_DAPM_ENUM("DSPRX2 SRC", cs35l41_dsprx2_enum); + +static const char *const vendor_id_text[] = { "None", "AAC", "SSI", "GOER", + "Unknown" }; +static const struct soc_enum vendor_id[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(vendor_id_text), vendor_id_text), +}; + +static const struct snd_kcontrol_new cs35l41_aud_controls[] = { + SOC_SINGLE_SX_TLV("Digital PCM Volume", CS35L41_AMP_DIG_VOL_CTRL, 3, + 0x4CF, 0x391, dig_vol_tlv), + SOC_SINGLE_TLV("AMP PCM Gain", CS35L41_AMP_GAIN_CTRL, 5, 0x14, 0, + amp_gain_tlv), + SOC_SINGLE_RANGE("ASPTX1 Slot Position", CS35L41_SP_FRAME_TX_SLOT, 0, 0, + 7, 0), + SOC_SINGLE_RANGE("ASPTX2 Slot Position", CS35L41_SP_FRAME_TX_SLOT, 8, 0, + 7, 0), + SOC_SINGLE_RANGE("ASPTX3 Slot Position", CS35L41_SP_FRAME_TX_SLOT, 16, + 0, 7, 0), + SOC_SINGLE_RANGE("ASPTX4 Slot Position", CS35L41_SP_FRAME_TX_SLOT, 24, + 0, 7, 0), + SOC_SINGLE_RANGE("ASPRX1 Slot Position", CS35L41_SP_FRAME_RX_SLOT, 0, 0, + 7, 0), + SOC_SINGLE_RANGE("ASPRX2 Slot Position", CS35L41_SP_FRAME_RX_SLOT, 8, 0, + 7, 0), + SOC_ENUM("PCM Soft Ramp", pcm_sft_ramp), + SOC_VALUE_ENUM_EXT("CSPL Command", cs35l41_cspl_cmd, + cs35l41_cspl_cmd_get, cs35l41_cspl_cmd_put), + SOC_SINGLE_EXT("DSP Booted", SND_SOC_NOPM, 0, 1, 0, + cs35l41_halo_booted_get, cs35l41_halo_booted_put), + WM_ADSP2_PRELOAD_SWITCH("DSP1", 1), + SOC_ENUM_EXT("SPK ID", vendor_id, vendor_id_get, NULL), +}; + +static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs35l41_otp_map_map); i++) { + if (cs35l41_otp_map_map[i].id == otp_id) + return &cs35l41_otp_map_map[i]; + } + + return NULL; +} + +static int cs35l41_otp_unpack(void *data) +{ + struct cs35l41_private *cs35l41 = data; + u32 otp_mem[32]; + int i; + int bit_offset, word_offset; + unsigned int bit_sum = 8; + u32 otp_val, otp_id_reg; + const struct cs35l41_otp_map_element_t *otp_map_match; + const struct cs35l41_otp_packed_element_t *otp_map; + int ret; + struct spi_device *spi = NULL; + u32 orig_spi_freq = 0; + + ret = regmap_read(cs35l41->regmap, CS35L41_OTPID, &otp_id_reg); + if (ret < 0) { + dev_err(cs35l41->dev, "Read OTP ID failed\n"); + return -EINVAL; + } + + otp_map_match = cs35l41_find_otp_map(otp_id_reg); + + if (otp_map_match == NULL) { + dev_err(cs35l41->dev, "OTP Map matching ID %d not found\n", + otp_id_reg); + return -EINVAL; + } + + if (cs35l41->bus_spi) { + spi = to_spi_device(cs35l41->dev); + orig_spi_freq = spi->max_speed_hz; + spi->max_speed_hz = CS35L41_SPI_MAX_FREQ_OTP; + spi_setup(spi); + } + +#define MAX_BULK_READ_SIZE 4 + for (i = 0; i < CS35L41_OTP_SIZE_WORDS / MAX_BULK_READ_SIZE; i++) { + ret = regmap_bulk_read( + cs35l41->regmap, + CS35L41_OTP_MEM0 + i * 4 * MAX_BULK_READ_SIZE, + &otp_mem[i * MAX_BULK_READ_SIZE], MAX_BULK_READ_SIZE); + } + + if (ret < 0) { + dev_err(cs35l41->dev, "Read OTP Mem failed\n"); + return -EINVAL; + } + + if (cs35l41->bus_spi) { + spi->max_speed_hz = orig_spi_freq; + spi_setup(spi); + } + + otp_map = otp_map_match->map; + + bit_offset = otp_map_match->bit_offset; + word_offset = otp_map_match->word_offset; + + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055); + if (ret < 0) { + dev_err(cs35l41->dev, "Write Unlock key failed 1/2\n"); + return -EINVAL; + } + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); + if (ret < 0) { + dev_err(cs35l41->dev, "Write Unlock key failed 2/2\n"); + return -EINVAL; + } + + for (i = 0; i < otp_map_match->num_elements; i++) { + dev_dbg(cs35l41->dev, + "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", + bit_offset, word_offset, bit_sum % 32); + if (bit_offset + otp_map[i].size - 1 >= 32) { + otp_val = (otp_mem[word_offset] & + GENMASK(31, bit_offset)) >> + bit_offset; + otp_val |= + (otp_mem[++word_offset] & + GENMASK(bit_offset + otp_map[i].size - 33, 0)) + << (32 - bit_offset); + bit_offset += otp_map[i].size - 32; + } else { + otp_val = (otp_mem[word_offset] & + GENMASK(bit_offset + otp_map[i].size - 1, + bit_offset)) >> + bit_offset; + bit_offset += otp_map[i].size; + } + bit_sum += otp_map[i].size; + + if (bit_offset == 32) { + bit_offset = 0; + word_offset++; + } + + if (otp_map[i].reg != 0) { + ret = regmap_update_bits( + cs35l41->regmap, otp_map[i].reg, + GENMASK(otp_map[i].shift + otp_map[i].size - 1, + otp_map[i].shift), + otp_val << otp_map[i].shift); + if (ret < 0) { + dev_err(cs35l41->dev, "Write OTP val failed\n"); + return -EINVAL; + } + } + } + + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); + if (ret < 0) { + dev_err(cs35l41->dev, "Write Lock key failed 1/2\n"); + return -EINVAL; + } + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033); + if (ret < 0) { + dev_err(cs35l41->dev, "Write Lock key failed 2/2\n"); + return -EINVAL; + } + + return 0; +} + +static irqreturn_t cs35l41_irq(int irq, void *data) +{ + struct cs35l41_private *cs35l41 = data; + unsigned int status[4]; + unsigned int masks[4]; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(status); i++) { + regmap_read(cs35l41->regmap, + CS35L41_IRQ1_STATUS1 + (i * CS35L41_REGSTRIDE), + &status[i]); + regmap_read(cs35l41->regmap, + CS35L41_IRQ1_MASK1 + (i * CS35L41_REGSTRIDE), + &masks[i]); + } + + /* Check to see if unmasked bits are active */ + if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) && + !(status[2] & ~masks[2]) && !(status[3] & ~masks[3])) + return IRQ_NONE; + + if (status[1] & (1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT)) { + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS2, + 1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT); + complete(&cs35l41->mbox_cmd); + } + + if (status[0] & CS35L41_PUP_DONE_MASK) { + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_PUP_DONE_MASK); + complete(&cs35l41->global_pup_done); + } + + if (status[0] & CS35L41_PDN_DONE_MASK) { + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_PDN_DONE_MASK); + complete(&cs35l41->global_pdn_done); + } + + /* + * The following interrupts require a + * protection release cycle to get the + * speaker out of Safe-Mode. + */ + if (status[0] & CS35L41_AMP_SHORT_ERR) { + dev_crit(cs35l41->dev, "Amp short error\n"); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_AMP_SHORT_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_AMP_SHORT_ERR_RLS, + CS35L41_AMP_SHORT_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_AMP_SHORT_ERR_RLS, 0); + } + + if (status[0] & CS35L41_TEMP_WARN) { + dev_crit(cs35l41->dev, "Over temperature warning\n"); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_TEMP_WARN); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_TEMP_WARN_ERR_RLS, + CS35L41_TEMP_WARN_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_TEMP_WARN_ERR_RLS, 0); + } + + if (status[0] & CS35L41_TEMP_ERR) { + dev_crit(cs35l41->dev, "Over temperature error\n"); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_TEMP_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_TEMP_ERR_RLS, CS35L41_TEMP_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_TEMP_ERR_RLS, 0); + } + + if (status[0] & CS35L41_BST_OVP_ERR) { + dev_crit(cs35l41->dev, "VBST Over Voltage error\n"); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_BST_EN_MASK, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_BST_OVP_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_BST_OVP_ERR_RLS, + CS35L41_BST_OVP_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_BST_OVP_ERR_RLS, 0); + regmap_update_bits( + cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK, + CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT); + } + + if (status[0] & CS35L41_BST_DCM_UVP_ERR) { + dev_crit(cs35l41->dev, "DCM VBST Under Voltage Error\n"); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_BST_EN_MASK, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_BST_DCM_UVP_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_BST_UVP_ERR_RLS, + CS35L41_BST_UVP_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_BST_UVP_ERR_RLS, 0); + regmap_update_bits( + cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK, + CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT); + } + + if (status[0] & CS35L41_BST_SHORT_ERR) { + dev_crit(cs35l41->dev, "LBST error: powering off!\n"); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_BST_EN_MASK, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_BST_SHORT_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_BST_SHORT_ERR_RLS, + CS35L41_BST_SHORT_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_BST_SHORT_ERR_RLS, 0); + regmap_update_bits( + cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK, + CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT); + } + + if (status[3] & CS35L41_OTP_BOOT_DONE) { + regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK4, + CS35L41_OTP_BOOT_DONE, + CS35L41_OTP_BOOT_DONE); + } + + return IRQ_HANDLED; +} + +static const struct reg_sequence cs35l41_pup_patch[] = { + { 0x00000040, 0x00000055 }, { 0x00000040, 0x000000AA }, + { 0x00002084, 0x002F1AA0 }, { 0x00000040, 0x000000CC }, + { 0x00000040, 0x00000033 }, +}; + +static const struct reg_sequence cs35l41_pdn_patch[] = { + { 0x00000040, 0x00000055 }, { 0x00000040, 0x000000AA }, + { 0x00002084, 0x002F1AA3 }, { 0x00000040, 0x000000CC }, + { 0x00000040, 0x00000033 }, +}; + +static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + pr_debug("++++>CSPL: %s, event = %d.\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_POST_PMU: + regmap_multi_reg_write_bypassed(cs35l41->regmap, + cs35l41_pup_patch, + ARRAY_SIZE(cs35l41_pup_patch)); + + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, + CS35L41_GLOBAL_EN_MASK, + 1 << CS35L41_GLOBAL_EN_SHIFT); + + usleep_range(1000, 1100); + + if (cs35l41->halo_booted) { + if (cs35l41->cspl_cmd == CSPL_MBOX_CMD_STOP_PRE_REINIT) + /* Send this command on power down event */ + ret = cs35l41_set_csplmboxcmd( + cs35l41, CSPL_MBOX_CMD_RESUME); + else + ret = cs35l41_set_csplmboxcmd( + cs35l41, cs35l41->cspl_cmd); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (cs35l41->halo_booted) { + if (cs35l41->cspl_cmd == CSPL_MBOX_CMD_STOP_PRE_REINIT) + ret = cs35l41_set_csplmboxcmd( + cs35l41, cs35l41->cspl_cmd); + else + ret = cs35l41_set_csplmboxcmd( + cs35l41, CSPL_MBOX_CMD_PAUSE); + } + + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, + CS35L41_GLOBAL_EN_MASK, 0); + + usleep_range(1000, 1100); + + regmap_multi_reg_write_bypassed(cs35l41->regmap, + cs35l41_pdn_patch, + ARRAY_SIZE(cs35l41_pdn_patch)); + break; + default: + dev_err(codec->dev, "Invalid event = 0x%x\n", event); + ret = -EINVAL; + } + pr_debug("----CSPL: %s.\n", __func__); + return ret; +} + +static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = { + + SND_SOC_DAPM_SPK("DSP1 Preload", NULL), + SND_SOC_DAPM_SUPPLY_S("DSP1 Preloader", 100, SND_SOC_NOPM, 0, 0, + cs35l41_dsp_power_ev, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_OUT_DRV_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, + cs35l41_dsp_load_ev, SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_OUTPUT("SPK"), + + SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0, CS35L41_SP_ENABLES, 16, 0), + SND_SOC_DAPM_AIF_IN("ASPRX2", NULL, 0, CS35L41_SP_ENABLES, 17, 0), + SND_SOC_DAPM_AIF_OUT("ASPTX1", NULL, 0, CS35L41_SP_ENABLES, 0, 0), + SND_SOC_DAPM_AIF_OUT("ASPTX2", NULL, 0, CS35L41_SP_ENABLES, 1, 0), + SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 0, CS35L41_SP_ENABLES, 2, 0), + SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 0, CS35L41_SP_ENABLES, 3, 0), + + SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L41_PWR_CTRL2, 12, 0), + SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L41_PWR_CTRL2, 13, 0), + SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L41_PWR_CTRL2, 8, 0), + SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L41_PWR_CTRL2, 9, 0), + SND_SOC_DAPM_ADC("TEMPMON ADC", NULL, CS35L41_PWR_CTRL2, 10, 0), + SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L41_PWR_CTRL3, 4, 0), + + SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0, + cs35l41_main_amp_event, + SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_INPUT("VP"), + SND_SOC_DAPM_INPUT("VBST"), + SND_SOC_DAPM_INPUT("ISENSE"), + SND_SOC_DAPM_INPUT("VSENSE"), + SND_SOC_DAPM_INPUT("TEMP"), + + SND_SOC_DAPM_MUX("ASPTX Ref", SND_SOC_NOPM, 0, 0, &virt_mux), + SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux), + SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux), + SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux), + SND_SOC_DAPM_MUX("ASP TX4 Source", SND_SOC_NOPM, 0, 0, &asp_tx4_mux), + SND_SOC_DAPM_MUX("DSP RX1 Source", SND_SOC_NOPM, 0, 0, &dsp_rx1_mux), + SND_SOC_DAPM_MUX("DSP RX2 Source", SND_SOC_NOPM, 0, 0, &dsp_rx2_mux), + SND_SOC_DAPM_MUX("PCM Source", SND_SOC_NOPM, 0, 0, &pcm_source_mux), + SND_SOC_DAPM_SWITCH("DRE", SND_SOC_NOPM, 0, 0, &dre_ctrl), + +}; + +static const struct snd_soc_dapm_route cs35l41_audio_map[] = { + + { "DSP1", NULL, "DSP1 Preloader" }, + { "DSP1 Preload", NULL, "DSP1 Preloader" }, + + { "DSP RX1 Source", "VMON", "VMON ADC" }, + { "DSP RX1 Source", "IMON", "IMON ADC" }, + { "DSP RX1 Source", "VPMON", "VPMON ADC" }, + { "DSP RX1 Source", "DSPTX1", "DSP1" }, + { "DSP RX1 Source", "DSPTX2", "DSP1" }, + { "DSP RX1 Source", "ASPRX1", "ASPRX1" }, + { "DSP RX1 Source", "ASPRX2", "ASPRX2" }, + { "DSP RX1 Source", "Zero", "ASPRX1" }, + { "DSP1", NULL, "DSP RX1 Source" }, + + { "DSP RX2 Source", "VMON", "VMON ADC" }, + { "DSP RX2 Source", "IMON", "IMON ADC" }, + { "DSP RX2 Source", "VPMON", "VPMON ADC" }, + { "DSP RX2 Source", "DSPTX1", "DSP1" }, + { "DSP RX2 Source", "DSPTX2", "DSP1" }, + { "DSP RX2 Source", "ASPRX1", "ASPRX1" }, + { "DSP RX2 Source", "ASPRX2", "ASPRX2" }, + { "DSP RX2 Source", "Zero", "ASPRX1" }, + { "DSP1", NULL, "DSP RX2 Source" }, + + { "ASP TX1 Source", "VMON", "VMON ADC" }, + { "ASP TX1 Source", "IMON", "IMON ADC" }, + { "ASP TX1 Source", "VPMON", "VPMON ADC" }, + { "ASP TX1 Source", "DSPTX1", "DSP1" }, + { "ASP TX1 Source", "DSPTX2", "DSP1" }, + { "ASP TX1 Source", "ASPRX1", "ASPRX1" }, + { "ASP TX1 Source", "ASPRX2", "ASPRX2" }, + { "ASP TX2 Source", "VMON", "VMON ADC" }, + { "ASP TX2 Source", "IMON", "IMON ADC" }, + { "ASP TX2 Source", "VPMON", "VPMON ADC" }, + { "ASP TX2 Source", "DSPTX1", "DSP1" }, + { "ASP TX2 Source", "DSPTX2", "DSP1" }, + { "ASP TX2 Source", "ASPRX1", "ASPRX1" }, + { "ASP TX2 Source", "ASPRX2", "ASPRX2" }, + { "ASP TX3 Source", "VMON", "VMON ADC" }, + { "ASP TX3 Source", "IMON", "IMON ADC" }, + { "ASP TX3 Source", "VPMON", "VPMON ADC" }, + { "ASP TX3 Source", "DSPTX1", "DSP1" }, + { "ASP TX3 Source", "DSPTX2", "DSP1" }, + { "ASP TX3 Source", "ASPRX1", "ASPRX1" }, + { "ASP TX3 Source", "ASPRX2", "ASPRX2" }, + { "ASP TX4 Source", "VMON", "VMON ADC" }, + { "ASP TX4 Source", "IMON", "IMON ADC" }, + { "ASP TX4 Source", "VPMON", "VPMON ADC" }, + { "ASP TX4 Source", "DSPTX1", "DSP1" }, + { "ASP TX4 Source", "DSPTX2", "DSP1" }, + { "ASP TX4 Source", "ASPRX1", "ASPRX1" }, + { "ASP TX4 Source", "ASPRX2", "ASPRX2" }, + { "ASPTX1", NULL, "ASP TX1 Source" }, + { "ASPTX2", NULL, "ASP TX2 Source" }, + { "ASPTX3", NULL, "ASP TX3 Source" }, + { "ASPTX4", NULL, "ASP TX4 Source" }, + { "AMP Capture", NULL, "ASPTX1" }, + { "AMP Capture", NULL, "ASPTX2" }, + { "AMP Capture", NULL, "ASPTX3" }, + { "AMP Capture", NULL, "ASPTX4" }, + + { "VMON ADC", NULL, "ASPRX1" }, + { "IMON ADC", NULL, "ASPRX1" }, + { "VPMON ADC", NULL, "ASPRX1" }, + { "TEMPMON ADC", NULL, "ASPRX1" }, + { "VBSTMON ADC", NULL, "ASPRX1" }, + + { "DSP1", NULL, "IMON ADC" }, + { "DSP1", NULL, "VMON ADC" }, + { "DSP1", NULL, "VBSTMON ADC" }, + { "DSP1", NULL, "VPMON ADC" }, + { "DSP1", NULL, "TEMPMON ADC" }, + + { "ASPRX1", NULL, "AMP Playback" }, + { "ASPRX2", NULL, "AMP Playback" }, + { "DRE", "Switch", "CLASS H" }, + { "Main AMP", NULL, "CLASS H" }, + { "Main AMP", NULL, "DRE" }, + { "SPK", NULL, "Main AMP" }, + { "Main AMP", NULL, "ASPTX Ref" }, + { "ASPTX Ref", "Ref", "ASPTX1" }, + { "ASPTX Ref", "Ref", "ASPTX2" }, + { "PCM Source", "ASP", "ASPRX1" }, + { "PCM Source", "DSP", "DSP1" }, + { "CLASS H", NULL, "PCM Source" }, + +}; + +static const struct wm_adsp_region cs35l41_dsp1_regions[] = { + { .type = WMFW_HALO_PM_PACKED, .base = CS35L41_DSP1_PMEM_0 }, + { .type = WMFW_HALO_XM_PACKED, .base = CS35L41_DSP1_XMEM_PACK_0 }, + { .type = WMFW_HALO_YM_PACKED, .base = CS35L41_DSP1_YMEM_PACK_0 }, + { .type = WMFW_ADSP2_XM, .base = CS35L41_DSP1_XMEM_UNPACK24_0 }, + { .type = WMFW_ADSP2_YM, .base = CS35L41_DSP1_YMEM_UNPACK24_0 }, +}; + +static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + struct cs35l41_private *cs35l41 = + snd_soc_codec_get_drvdata(codec_dai->codec); + unsigned int asp_fmt, lrclk_fmt, sclk_fmt, slave_mode; + + pr_debug("++++>CSPL: %s, fmt = %d.\n", __func__, fmt); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + slave_mode = 1; + break; + case SND_SOC_DAIFMT_CBS_CFS: + slave_mode = 0; + break; + default: + dev_warn( + cs35l41->dev, + "cs35l41_set_dai_fmt: Mixed master mode unsupported\n"); + return -EINVAL; + } + + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_SCLK_MSTR_MASK, + slave_mode << CS35L41_SCLK_MSTR_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_LRCLK_MSTR_MASK, + slave_mode << CS35L41_LRCLK_MSTR_SHIFT); + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + asp_fmt = 0; + cs35l41->i2s_mode = false; + cs35l41->dspa_mode = true; + break; + case SND_SOC_DAIFMT_I2S: + asp_fmt = 2; + cs35l41->i2s_mode = true; + cs35l41->dspa_mode = false; + break; + default: + dev_warn( + cs35l41->dev, + "cs35l41_set_dai_fmt: Invalid or unsupported DAI format\n"); + return -EINVAL; + } + + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_ASP_FMT_MASK, + asp_fmt << CS35L41_ASP_FMT_SHIFT); + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_IF: + lrclk_fmt = 1; + sclk_fmt = 0; + break; + case SND_SOC_DAIFMT_IB_NF: + lrclk_fmt = 0; + sclk_fmt = 1; + break; + case SND_SOC_DAIFMT_IB_IF: + lrclk_fmt = 1; + sclk_fmt = 1; + break; + case SND_SOC_DAIFMT_NB_NF: + lrclk_fmt = 0; + sclk_fmt = 0; + break; + default: + dev_warn(cs35l41->dev, + "cs35l41_set_dai_fmt: Invalid DAI clock INV\n"); + return -EINVAL; + } + + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_LRCLK_INV_MASK, + lrclk_fmt << CS35L41_LRCLK_INV_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_SCLK_INV_MASK, + sclk_fmt << CS35L41_SCLK_INV_SHIFT); + + pr_debug("---->CSPL: %s, fmt = %d.\n", __func__, fmt); + return 0; +} + +struct cs35l41_global_fs_config { + int rate; + int fs_cfg; +}; + +static const struct cs35l41_global_fs_config cs35l41_fs_rates[] = { + { 12000, 0x01 }, { 24000, 0x02 }, { 48000, 0x03 }, { 96000, 0x04 }, + { 192000, 0x05 }, { 11025, 0x09 }, { 22050, 0x0A }, { 44100, 0x0B }, + { 88200, 0x0C }, { 176400, 0x0D }, { 8000, 0x11 }, { 16000, 0x12 }, + { 32000, 0x13 }, +}; + +static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(dai->codec); + int i; + unsigned int rate = params_rate(params); + u8 asp_width, asp_wl; + + pr_debug("++++>CSPL: %s.\n", __func__); + for (i = 0; i < ARRAY_SIZE(cs35l41_fs_rates); i++) { + if (rate == cs35l41_fs_rates[i].rate) + break; + } + regmap_update_bits(cs35l41->regmap, CS35L41_GLOBAL_CLK_CTRL, + CS35L41_GLOBAL_FS_MASK, + cs35l41_fs_rates[i].fs_cfg + << CS35L41_GLOBAL_FS_SHIFT); + + asp_wl = params_width(params); + asp_width = params_physical_width(params); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_ASP_WIDTH_RX_MASK, + asp_width << CS35L41_ASP_WIDTH_RX_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_RX_WL, + CS35L41_ASP_RX_WL_MASK, + asp_wl << CS35L41_ASP_RX_WL_SHIFT); + if (cs35l41->i2s_mode || cs35l41->dspa_mode) { + regmap_update_bits( + cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, + CS35L41_ASP_RX1_SLOT_MASK, + ((cs35l41->pdata.right_channel) ? 1 : 0) + << CS35L41_ASP_RX1_SLOT_SHIFT); + regmap_update_bits( + cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, + CS35L41_ASP_RX2_SLOT_MASK, + ((cs35l41->pdata.right_channel) ? 0 : 1) + << CS35L41_ASP_RX2_SLOT_SHIFT); + } + } else { + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_ASP_WIDTH_TX_MASK, + asp_width << CS35L41_ASP_WIDTH_TX_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_TX_WL, + CS35L41_ASP_TX_WL_MASK, + asp_wl << CS35L41_ASP_TX_WL_SHIFT); + } + + pr_debug("---->CSPL: %s.\n", __func__); + return 0; +} + +static int cs35l41_get_clk_config(int freq) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs35l41_pll_sysclk); i++) { + if (cs35l41_pll_sysclk[i].freq == freq) + return cs35l41_pll_sysclk[i].clk_cfg; + } + + return -EINVAL; +} + +#if 0 +static const unsigned int cs35l41_src_rates[] = { + 8000, 12000, 11025, 16000, 22050, 24000, 32000, + 44100, 48000, 88200, 96000, 176400, 192000 +}; + +static const struct snd_pcm_hw_constraint_list cs35l41_constraints = { + .count = ARRAY_SIZE(cs35l41_src_rates), + .list = cs35l41_src_rates, +}; +#endif + +static int cs35l41_pcm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + pr_debug("++++>CSPL: %s.\n", __func__); + + cs35l41_set_dai_fmt(dai, SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S); + cs35l41_codec_set_sysclk(codec, 0, 0, 1536000, 0); +#if 0 + if (substream->runtime) + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, &cs35l41_constraints); +#endif + pr_debug("---->CSPL: %s.\n", __func__); + return 0; +} + +static int cs35l41_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, + int source, unsigned int freq, int dir) +{ + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec); + + int val = 0; + cs35l41->extclk_freq = freq; + + pr_debug("++++>CSPL: %s: clk_id = %d, src = %d, freq = %d, dir = %d.\n", + __func__, clk_id, source, freq, dir); + dev_info(codec->dev, "%s: clk_id=%d, src=%d, freq=%d\n", __func__, + clk_id, source, freq); + + switch (clk_id) { + case 0: + cs35l41->clksrc = CS35L41_PLLSRC_SCLK; + break; + case 1: + cs35l41->clksrc = CS35L41_PLLSRC_LRCLK; + break; + case 2: + cs35l41->clksrc = CS35L41_PLLSRC_PDMCLK; + break; + case 3: + cs35l41->clksrc = CS35L41_PLLSRC_SELF; + break; + case 4: + cs35l41->clksrc = CS35L41_PLLSRC_MCLK; + break; + default: + dev_err(codec->dev, "Invalid CLK Config\n"); + return -EINVAL; + } + + cs35l41->extclk_cfg = cs35l41_get_clk_config(freq); + + if (cs35l41->extclk_cfg < 0) { + dev_err(codec->dev, "Invalid CLK Config: %d, freq: %u\n", + cs35l41->extclk_cfg, freq); + return -EINVAL; + } + + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_OPENLOOP_MASK, + 1 << CS35L41_PLL_OPENLOOP_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_REFCLK_FREQ_MASK, + cs35l41->extclk_cfg << CS35L41_REFCLK_FREQ_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_CLK_EN_MASK, + 0 << CS35L41_PLL_CLK_EN_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_CLK_SEL_MASK, cs35l41->clksrc); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_OPENLOOP_MASK, + 0 << CS35L41_PLL_OPENLOOP_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_CLK_EN_MASK, + 1 << CS35L41_PLL_CLK_EN_SHIFT); + + regmap_read(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, &val); + dev_info(codec->dev, "%s: 0x%x <== 0x%x\n", __func__, + CS35L41_PLL_CLK_CTRL, val); + pr_debug("---->CSPL: %s.\n", __func__); + + return 0; +} + +static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = dai->codec; + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec); + + pr_debug("++++>CSPL: %s: clk_id=%d, freq=%d, dir=%d\n", __func__, + clk_id, freq, dir); + if (cs35l41_get_clk_config(freq) < 0) { + dev_err(codec->dev, "Invalid CLK Config freq: %u\n", freq); + return -EINVAL; + } + + if (clk_id == CS35L41_PLLSRC_SCLK) + cs35l41->sclk = freq; + pr_debug("---->CSPL: %s.\n", __func__); + + return 0; +} + +static int cs35l41_digital_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(cs35l41->dev, "%s: %d\n", __func__, mute); + pr_debug("++++>CSPL: %s, mute = %d.\n", __func__, mute); + + if (mute) { + regmap_update_bits(cs35l41->regmap, 0x6000, 0x7ff << 3, + 0x400 << 3 | 0x7); + mdelay(30); + } else { + regmap_update_bits(cs35l41->regmap, 0x6000, 0x7ff << 3, + 0x0 << 3 | 0x4); + } + + pr_debug("---->CSPL: %s.\n", __func__); + return 0; +} + +static int cs35l41_boost_config(struct cs35l41_private *cs35l41, int boost_ind, + int boost_cap, int boost_ipk) +{ + int ret; + unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled; + struct regmap *regmap = cs35l41->regmap; + struct device *dev = cs35l41->dev; + + switch (boost_ind) { + case 1000: /* 1.0 uH */ + bst_lbst_val = 0; + break; + case 1200: /* 1.2 uH */ + bst_lbst_val = 1; + break; + case 1500: /* 1.5 uH */ + bst_lbst_val = 2; + break; + case 2200: /* 2.2 uH */ + bst_lbst_val = 3; + break; + default: + dev_err(dev, "Invalid boost inductor value: %d nH\n", + boost_ind); + return -EINVAL; + } + + switch (boost_cap) { + case 0 ... 19: + bst_cbst_range = 0; + break; + case 20 ... 50: + bst_cbst_range = 1; + break; + case 51 ... 100: + bst_cbst_range = 2; + break; + case 101 ... 200: + bst_cbst_range = 3; + break; + default: /* 201 uF and greater */ + bst_cbst_range = 4; + } + + ret = regmap_update_bits( + regmap, CS35L41_BSTCVRT_COEFF, CS35L41_BST_K1_MASK, + cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range] + << CS35L41_BST_K1_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost K1 coefficient\n"); + return ret; + } + + ret = regmap_update_bits( + regmap, CS35L41_BSTCVRT_COEFF, CS35L41_BST_K2_MASK, + cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range] + << CS35L41_BST_K2_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost K2 coefficient\n"); + return ret; + } + + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, + CS35L41_BST_SLOPE_MASK, + cs35l41_bst_slope_table[bst_lbst_val] + << CS35L41_BST_SLOPE_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost slope coefficient\n"); + return ret; + } + + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, + CS35L41_BST_LBST_VAL_MASK, + bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost inductor value\n"); + return ret; + } + + if ((boost_ipk < 1600) || (boost_ipk > 4500)) { + dev_err(dev, "Invalid boost inductor peak current: %d mA\n", + boost_ipk); + return -EINVAL; + } + bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10; + + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR, + CS35L41_BST_IPK_MASK, + bst_ipk_scaled << CS35L41_BST_IPK_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost inductor peak current\n"); + return ret; + } + + return 0; +} + +static int cs35l41_codec_probe(struct snd_soc_codec *codec) +{ + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct classh_cfg *classh = &cs35l41->pdata.classh_config; + int ret; + + /* Set Platform Data */ + /* Required */ + if (cs35l41->pdata.bst_ipk && cs35l41->pdata.bst_ind && + cs35l41->pdata.bst_cap) { + ret = cs35l41_boost_config(cs35l41, cs35l41->pdata.bst_ind, + cs35l41->pdata.bst_cap, + cs35l41->pdata.bst_ipk); + if (ret) { + dev_err(cs35l41->dev, "Error in Boost DT config\n"); + return ret; + } + } else { + dev_err(cs35l41->dev, "Incomplete Boost component DT config\n"); + return -EINVAL; + } + + /* Optional */ + if (cs35l41->pdata.sclk_frc) + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_SCLK_FRC_MASK, + cs35l41->pdata.sclk_frc + << CS35L41_SCLK_FRC_SHIFT); + + if (cs35l41->pdata.lrclk_frc) + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_LRCLK_FRC_MASK, + cs35l41->pdata.lrclk_frc + << CS35L41_LRCLK_FRC_SHIFT); + + if (cs35l41->pdata.amp_gain_zc) + regmap_update_bits(cs35l41->regmap, CS35L41_AMP_GAIN_CTRL, + CS35L41_AMP_GAIN_ZC_MASK, + cs35l41->pdata.amp_gain_zc + << CS35L41_AMP_GAIN_ZC_SHIFT); + + if (cs35l41->pdata.bst_vctrl) + regmap_update_bits(cs35l41->regmap, CS35L41_BSTCVRT_VCTRL1, + CS35L41_BST_CTL_MASK, + cs35l41->pdata.bst_vctrl); + + if (cs35l41->pdata.temp_warn_thld) + regmap_update_bits(cs35l41->regmap, CS35L41_DTEMP_WARN_THLD, + CS35L41_TEMP_THLD_MASK, + cs35l41->pdata.temp_warn_thld); + + if (cs35l41->pdata.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && + cs35l41->pdata.dout_hiz >= 0) + regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL, + CS35L41_ASP_DOUT_HIZ_MASK, + cs35l41->pdata.dout_hiz); + + if (cs35l41->pdata.ng_enable) { + regmap_update_bits(cs35l41->regmap, CS35L41_MIXER_NGATE_CH1_CFG, + CS35L41_NG_ENABLE_MASK, + CS35L41_NG_ENABLE_MASK); + regmap_update_bits(cs35l41->regmap, CS35L41_MIXER_NGATE_CH2_CFG, + CS35L41_NG_ENABLE_MASK, + CS35L41_NG_ENABLE_MASK); + + if (cs35l41->pdata.ng_pcm_thld) { + regmap_update_bits(cs35l41->regmap, + CS35L41_MIXER_NGATE_CH1_CFG, + CS35L41_NG_THLD_MASK, + cs35l41->pdata.ng_pcm_thld); + regmap_update_bits(cs35l41->regmap, + CS35L41_MIXER_NGATE_CH2_CFG, + CS35L41_NG_THLD_MASK, + cs35l41->pdata.ng_pcm_thld); + } + + if (cs35l41->pdata.ng_delay) { + regmap_update_bits(cs35l41->regmap, + CS35L41_MIXER_NGATE_CH1_CFG, + CS35L41_NG_DELAY_MASK, + cs35l41->pdata.ng_delay + << CS35L41_NG_DELAY_SHIFT); + regmap_update_bits(cs35l41->regmap, + CS35L41_MIXER_NGATE_CH2_CFG, + CS35L41_NG_DELAY_MASK, + cs35l41->pdata.ng_delay + << CS35L41_NG_DELAY_SHIFT); + } + } + + if (classh->classh_algo_enable) { + if (classh->classh_bst_override) + regmap_update_bits(cs35l41->regmap, + CS35L41_BSTCVRT_VCTRL2, + CS35L41_BST_CTL_SEL_MASK, + CS35L41_BST_CTL_SEL_REG); + if (classh->classh_bst_max_limit) + regmap_update_bits(cs35l41->regmap, + CS35L41_BSTCVRT_VCTRL2, + CS35L41_BST_LIM_MASK, + classh->classh_bst_max_limit + << CS35L41_BST_LIM_SHIFT); + if (classh->classh_mem_depth) + regmap_update_bits( + cs35l41->regmap, CS35L41_CLASSH_CFG, + CS35L41_CH_MEM_DEPTH_MASK, + classh->classh_mem_depth + << CS35L41_CH_MEM_DEPTH_SHIFT); + if (classh->classh_headroom) + regmap_update_bits( + cs35l41->regmap, CS35L41_CLASSH_CFG, + CS35L41_CH_HDRM_CTL_MASK, + classh->classh_headroom + << CS35L41_CH_HDRM_CTL_SHIFT); + if (classh->classh_release_rate) + regmap_update_bits( + cs35l41->regmap, CS35L41_CLASSH_CFG, + CS35L41_CH_REL_RATE_MASK, + classh->classh_release_rate + << CS35L41_CH_REL_RATE_SHIFT); + if (classh->classh_wk_fet_delay) + regmap_update_bits( + cs35l41->regmap, CS35L41_WKFET_CFG, + CS35L41_CH_WKFET_DLY_MASK, + classh->classh_wk_fet_delay + << CS35L41_CH_WKFET_DLY_SHIFT); + if (classh->classh_wk_fet_thld) + regmap_update_bits( + cs35l41->regmap, CS35L41_WKFET_CFG, + CS35L41_CH_WKFET_THLD_MASK, + classh->classh_wk_fet_thld + << CS35L41_CH_WKFET_THLD_SHIFT); + } + + wm_adsp2_codec_probe(&cs35l41->dsp, codec); + + snd_soc_dapm_ignore_suspend(dapm, "AMP Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AMP Capture"); + snd_soc_dapm_ignore_suspend(dapm, "Main AMP"); + snd_soc_dapm_ignore_suspend(dapm, "SPK"); + snd_soc_dapm_ignore_suspend(dapm, "VP"); + snd_soc_dapm_ignore_suspend(dapm, "VBST"); + snd_soc_dapm_ignore_suspend(dapm, "ISENSE"); + snd_soc_dapm_ignore_suspend(dapm, "VSENSE"); + snd_soc_dapm_ignore_suspend(dapm, "TEMP"); + snd_soc_dapm_ignore_suspend(dapm, "DSP1 Preloader"); + snd_soc_dapm_ignore_suspend(dapm, "DSP1 Preload"); + + return 0; +} + +static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41) +{ + struct irq_cfg *irq_gpio_cfg1 = &cs35l41->pdata.irq_config1; + struct irq_cfg *irq_gpio_cfg2 = &cs35l41->pdata.irq_config2; + int irq_pol = IRQF_TRIGGER_NONE; + + if (irq_gpio_cfg1->is_present) { + if (irq_gpio_cfg1->irq_pol_inv) + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1, + CS35L41_GPIO_POL_MASK, + CS35L41_GPIO_POL_MASK); + if (irq_gpio_cfg1->irq_out_en) + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1, + CS35L41_GPIO_DIR_MASK, 0); + if (irq_gpio_cfg1->irq_src_sel) + regmap_update_bits(cs35l41->regmap, + CS35L41_GPIO_PAD_CONTROL, + CS35L41_GPIO1_CTRL_MASK, + irq_gpio_cfg1->irq_src_sel + << CS35L41_GPIO1_CTRL_SHIFT); + } + + if (irq_gpio_cfg2->is_present) { + if (irq_gpio_cfg2->irq_pol_inv) + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1, + CS35L41_GPIO_POL_MASK, + CS35L41_GPIO_POL_MASK); + if (irq_gpio_cfg2->irq_out_en) + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1, + CS35L41_GPIO_DIR_MASK, 0); + if (irq_gpio_cfg2->irq_src_sel) + regmap_update_bits(cs35l41->regmap, + CS35L41_GPIO_PAD_CONTROL, + CS35L41_GPIO2_CTRL_MASK, + irq_gpio_cfg2->irq_src_sel + << CS35L41_GPIO2_CTRL_SHIFT); + } + + if (irq_gpio_cfg2->irq_src_sel == + (CS35L41_GPIO_CTRL_ACTV_LO | CS35L41_VALID_PDATA)) + irq_pol = IRQF_TRIGGER_LOW; + else if (irq_gpio_cfg2->irq_src_sel == + (CS35L41_GPIO_CTRL_ACTV_HI | CS35L41_VALID_PDATA)) + irq_pol = IRQF_TRIGGER_HIGH; + + return irq_pol; +} + +static int cs35l41_codec_remove(struct snd_soc_codec *codec) +{ + struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec); + + wm_adsp2_codec_remove(&cs35l41->dsp, codec); + return 0; +} + +static const struct snd_soc_dai_ops cs35l41_ops = { + .startup = cs35l41_pcm_startup, + .set_fmt = cs35l41_set_dai_fmt, + .hw_params = cs35l41_pcm_hw_params, + .set_sysclk = cs35l41_dai_set_sysclk, + .digital_mute = cs35l41_digital_mute, +}; + +static struct snd_soc_dai_driver cs35l41_dai[] = { + { + .name = "cs35l41-pcm", + .id = 0, + .playback = { + .stream_name = "AMP Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = CS35L41_RX_FORMATS, + }, + .capture = { + .stream_name = "AMP Capture", + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = CS35L41_TX_FORMATS, + }, + .ops = &cs35l41_ops, + .symmetric_rates = 1, + }, +}; + +static struct snd_soc_codec_driver soc_codec_dev_cs35l41 = { + .probe = cs35l41_codec_probe, + .remove = cs35l41_codec_remove, + .component_driver = { + .dapm_widgets = cs35l41_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(cs35l41_dapm_widgets), + .dapm_routes = cs35l41_audio_map, + .num_dapm_routes = ARRAY_SIZE(cs35l41_audio_map), + .controls = cs35l41_aud_controls, + .num_controls = ARRAY_SIZE(cs35l41_aud_controls), + }, + .set_sysclk = cs35l41_codec_set_sysclk, + .ignore_pmdown_time = false, + .idle_bias_off = true, +}; + +int spk_id_get(struct device_node *np) +{ + int id; + int state; + + state = spk_id_get_pin_3state(np); + if (state < 0) { + pr_err("%s: Can not get id pin state, %d\n", __func__, state); + return VENDOR_ID_NONE; + } + + switch (state) { + case PIN_PULL_DOWN: + id = VENDOR_ID_AAC; + break; + case PIN_PULL_UP: + id = VENDOR_ID_UNKNOWN; + break; + case PIN_FLOAT: + id = VENDOR_ID_GOER; + break; + default: + id = VENDOR_ID_UNKNOWN; + break; + } + return id; +} + +static int cs35l41_handle_of_data(struct device *dev, + struct cs35l41_platform_data *pdata) +{ + struct device_node *np = dev->of_node; + unsigned int val; + int ret; + struct device_node *sub_node; + struct classh_cfg *classh_config = &pdata->classh_config; + struct irq_cfg *irq_gpio1_config = &pdata->irq_config1; + struct irq_cfg *irq_gpio2_config = &pdata->irq_config2; + + if (!np) + return 0; + + pdata->right_channel = + of_property_read_bool(np, "cirrus,right-channel-amp"); + pdata->sclk_frc = of_property_read_bool(np, "cirrus,sclk-force-output"); + pdata->lrclk_frc = + of_property_read_bool(np, "cirrus,lrclk-force-output"); + pdata->amp_gain_zc = of_property_read_bool(np, "cirrus,amp-gain-zc"); + + if (of_property_read_u32(np, "cirrus,temp-warn_threshold", &val) >= 0) + pdata->temp_warn_thld = val | CS35L41_VALID_PDATA; + + ret = of_property_read_u32(np, "cirrus,boost-ctl-millivolt", &val); + if (ret >= 0) { + if (val < 2550 || val > 11000) { + dev_err(dev, "Invalid Boost Voltage %u mV\n", val); + return -EINVAL; + } + pdata->bst_vctrl = ((val - 2550) / 100) + 1; + } + + ret = of_property_read_u32(np, "cirrus,boost-peak-milliamp", &val); + if (ret >= 0) + pdata->bst_ipk = val; + + ret = of_property_read_u32(np, "cirrus,boost-ind-nanohenry", &val); + if (ret >= 0) + pdata->bst_ind = val; + + ret = of_property_read_u32(np, "cirrus,boost-cap-microfarad", &val); + if (ret >= 0) + pdata->bst_cap = val; + + ret = of_property_read_u32(np, "cirrus,asp-sdout-hiz", &val); + if (ret >= 0) + pdata->dout_hiz = val; + else + pdata->dout_hiz = -1; + + pdata->ng_enable = + of_property_read_bool(np, "cirrus,noise-gate-enable"); + if (of_property_read_u32(np, "cirrus,noise-gate-threshold", &val) >= 0) + pdata->ng_pcm_thld = val | CS35L41_VALID_PDATA; + if (of_property_read_u32(np, "cirrus,noise-gate-delay", &val) >= 0) + pdata->ng_delay = val | CS35L41_VALID_PDATA; + + pdata->spk_id_gpio_p = of_parse_phandle(np, "cirrus,spk-id-pin", 0); + if (!pdata->spk_id_gpio_p) { + dev_err(dev, "property %s not detected in node %s", + "cirrus,spk-id-pin", np->full_name); + pdata->mnSpkType = VENDOR_ID_NONE; + } else { + pdata->mnSpkType = spk_id_get(pdata->spk_id_gpio_p); + } + dev_info(dev, "spk is is %d", pdata->mnSpkType); + + sub_node = of_get_child_by_name(np, "cirrus,classh-internal-algo"); + classh_config->classh_algo_enable = sub_node ? true : false; + + if (classh_config->classh_algo_enable) { + classh_config->classh_bst_override = of_property_read_bool( + sub_node, "cirrus,classh-bst-overide"); + + ret = of_property_read_u32(sub_node, + "cirrus,classh-bst-max-limit", &val); + if (ret >= 0) { + val |= CS35L41_VALID_PDATA; + classh_config->classh_bst_max_limit = val; + } + + ret = of_property_read_u32(sub_node, "cirrus,classh-mem-depth", + &val); + if (ret >= 0) { + val |= CS35L41_VALID_PDATA; + classh_config->classh_mem_depth = val; + } + + ret = of_property_read_u32(sub_node, + "cirrus,classh-release-rate", &val); + if (ret >= 0) + classh_config->classh_release_rate = val; + + ret = of_property_read_u32(sub_node, "cirrus,classh-headroom", + &val); + if (ret >= 0) { + val |= CS35L41_VALID_PDATA; + classh_config->classh_headroom = val; + } + + ret = of_property_read_u32(sub_node, + "cirrus,classh-wk-fet-delay", &val); + if (ret >= 0) { + val |= CS35L41_VALID_PDATA; + classh_config->classh_wk_fet_delay = val; + } + + ret = of_property_read_u32(sub_node, + "cirrus,classh-wk-fet-thld", &val); + if (ret >= 0) + classh_config->classh_wk_fet_thld = val; + } + of_node_put(sub_node); + + /* GPIO1 Pin Config */ + sub_node = of_get_child_by_name(np, "cirrus,gpio-config1"); + irq_gpio1_config->is_present = sub_node ? true : false; + if (irq_gpio1_config->is_present) { + irq_gpio1_config->irq_pol_inv = of_property_read_bool( + sub_node, "cirrus,gpio-polarity-invert"); + irq_gpio1_config->irq_out_en = of_property_read_bool( + sub_node, "cirrus,gpio-output-enable"); + ret = of_property_read_u32(sub_node, "cirrus,gpio-src-select", + &val); + if (ret >= 0) { + val |= CS35L41_VALID_PDATA; + irq_gpio1_config->irq_src_sel = val; + } + } + of_node_put(sub_node); + + /* GPIO2 Pin Config */ + sub_node = of_get_child_by_name(np, "cirrus,gpio-config2"); + irq_gpio2_config->is_present = sub_node ? true : false; + if (irq_gpio2_config->is_present) { + irq_gpio2_config->irq_pol_inv = of_property_read_bool( + sub_node, "cirrus,gpio-polarity-invert"); + irq_gpio2_config->irq_out_en = of_property_read_bool( + sub_node, "cirrus,gpio-output-enable"); + ret = of_property_read_u32(sub_node, "cirrus,gpio-src-select", + &val); + if (ret >= 0) { + val |= CS35L41_VALID_PDATA; + irq_gpio2_config->irq_src_sel = val; + } + } + of_node_put(sub_node); + + return 0; +} + +static const struct reg_sequence cs35l41_reva0_errata_patch[] = { + { 0x00000040, 0x00005555 }, + { 0x00000040, 0x0000AAAA }, + { 0x00003854, 0x05180240 }, + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, + { CS35L41_OTP_TRIM_30, 0x9091A1C8 }, + { 0x00003014, 0x0200EE0E }, + { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, + { 0x00000054, 0x00000004 }, + { CS35L41_IRQ1_DB3, 0x00000000 }, + { CS35L41_IRQ2_DB3, 0x00000000 }, + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_ASP_CONTROL4, 0x00000000 }, + { 0x00000040, 0x0000CCCC }, + { 0x00000040, 0x00003333 }, +}; + +static const struct reg_sequence cs35l41_revb0_errata_patch[] = { + { 0x00000040, 0x00005555 }, + { 0x00000040, 0x0000AAAA }, + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, + { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_ASP_CONTROL4, 0x00000000 }, + { 0x00000040, 0x0000CCCC }, + { 0x00000040, 0x00003333 }, +}; + +static int cs35l41_dsp_init(struct cs35l41_private *cs35l41) +{ + struct wm_adsp *dsp; + int ret; + + dsp = &cs35l41->dsp; + dsp->part = "cs35l41"; + dsp->num = 1; + dsp->type = WMFW_HALO; + dsp->rev = 0; + dsp->dev = cs35l41->dev; + dsp->regmap = cs35l41->regmap; + + dsp->base = CS35L41_DSP1_CTRL_BASE; + dsp->base_sysinfo = CS35L41_DSP1_SYS_ID; + dsp->mem = cs35l41_dsp1_regions; + dsp->num_mems = ARRAY_SIZE(cs35l41_dsp1_regions); + dsp->unlock_all = true; + + dsp->n_rx_rates = CS35L41_DSP_N_RX_RATES; + dsp->n_tx_rates = CS35L41_DSP_N_TX_RATES; + ret = wm_halo_init(dsp); + cs35l41->halo_booted = false; + + regmap_write(cs35l41->regmap, CS35L41_DSP1_RX5_SRC, + CS35L41_INPUT_SRC_VPMON); + regmap_write(cs35l41->regmap, CS35L41_DSP1_RX6_SRC, + CS35L41_INPUT_SRC_CLASSH); + regmap_write(cs35l41->regmap, CS35L41_DSP1_RX7_SRC, + CS35L41_INPUT_SRC_TEMPMON); + regmap_write(cs35l41->regmap, CS35L41_DSP1_RX8_SRC, + CS35L41_INPUT_SRC_RSVD); + + return ret; +} + +int cs35l41_probe(struct cs35l41_private *cs35l41, + struct cs35l41_platform_data *pdata) +{ + int ret; + u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match; + int timeout = 100; + int irq_pol = 0; + + dev_info(cs35l41->dev, "cs35l41 proble\n"); + + /* Default to RESUME cmd */ + cs35l41->cspl_cmd = (unsigned int)CSPL_MBOX_CMD_RESUME; + + for (i = 0; i < ARRAY_SIZE(cs35l41_supplies); i++) + cs35l41->supplies[i].supply = cs35l41_supplies[i]; + + cs35l41->num_supplies = ARRAY_SIZE(cs35l41_supplies); + + ret = devm_regulator_bulk_get(cs35l41->dev, cs35l41->num_supplies, + cs35l41->supplies); + if (ret != 0) { + dev_err(cs35l41->dev, "Failed to request core supplies: %d\n", + ret); + return ret; + } + + if (pdata) { + cs35l41->pdata = *pdata; + } else if (cs35l41->dev->of_node) { + ret = cs35l41_handle_of_data(cs35l41->dev, &cs35l41->pdata); + if (ret != 0) + return ret; + } else { + ret = -EINVAL; + goto err; + } + + ret = regulator_bulk_enable(cs35l41->num_supplies, cs35l41->supplies); + if (ret != 0) { + dev_err(cs35l41->dev, "Failed to enable core supplies: %d\n", + ret); + return ret; + } + + /* returning NULL can be an option if in stereo mode */ + cs35l41->reset_gpio = of_get_named_gpio(cs35l41->dev->of_node, + "cs,cdc-reset-gpio", 0); + + dev_err(cs35l41->dev, "Set GPIO %d as RESET pin\n", + cs35l41->reset_gpio); + if (!gpio_is_valid(cs35l41->reset_gpio)) { + dev_err(cs35l41->dev, "GPIO %d is invalid!\n", + cs35l41->reset_gpio); + } + + if (cs35l41->reset_gpio) { + dev_err(cs35l41->dev, "Reset cs35l41\n"); + /* satisfy minimum reset pulse width spec */ + usleep_range(2000, 2100); + + gpio_direction_output(cs35l41->reset_gpio, 0); + msleep(5); + gpio_direction_output(cs35l41->reset_gpio, 1); + msleep(2); + } + + usleep_range(2000, 2100); + + do { + if (timeout == 0) { + dev_err(cs35l41->dev, + "Timeout waiting for OTP_BOOT_DONE\n"); + ret = -EBUSY; + goto err; + } + usleep_range(1000, 1100); + regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS4, &int_status); + timeout--; + } while (!(int_status & CS35L41_OTP_BOOT_DONE)); + + regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_status); + if (int_status & CS35L41_OTP_BOOT_ERR) { + dev_err(cs35l41->dev, "OTP Boot error\n"); + ret = -EINVAL; + goto err; + } + + ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, ®id); + if (ret < 0) { + dev_err(cs35l41->dev, "Get Device ID failed\n"); + goto err; + } + + ret = regmap_read(cs35l41->regmap, CS35L41_REVID, ®_revid); + if (ret < 0) { + dev_err(cs35l41->dev, "Get Revision ID failed\n"); + goto err; + } + + mtl_revid = reg_revid & CS35L41_MTLREVID_MASK; + + /* CS35L41 will have even MTLREVID + * CS35L41R will have odd MTLREVID + */ + chipid_match = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID; + if (regid != chipid_match) { + dev_err(cs35l41->dev, + "CS35L41 Device ID (%X). Expected ID %X\n", regid, + chipid_match); + ret = -ENODEV; + goto err; + } + + irq_pol = cs35l41_irq_gpio_config(cs35l41); + + init_completion(&cs35l41->global_pdn_done); + init_completion(&cs35l41->global_pup_done); + + init_completion(&cs35l41->mbox_cmd); + + ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, + cs35l41_irq, irq_pol | IRQF_ONESHOT, + "cs35l41", cs35l41); + + /* CS35L41 needs INT for PDN_DONE */ + if (ret != 0) { + dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", + cs35l41->irq); + //goto err; + } + + /* Set interrupt masks for critical errors */ + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, + CS35L41_INT1_MASK_DEFAULT); + + switch (reg_revid) { + case CS35L41_REVID_A0: + ret = regmap_multi_reg_write( + cs35l41->regmap, cs35l41_reva0_errata_patch, + ARRAY_SIZE(cs35l41_reva0_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, + "Failed to apply A0 errata patch %d\n", ret); + goto err; + } + break; + case CS35L41_REVID_B0: + ret = regmap_multi_reg_write( + cs35l41->regmap, cs35l41_revb0_errata_patch, + ARRAY_SIZE(cs35l41_revb0_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, + "Failed to apply B0 errata patch %d\n", ret); + goto err; + } + break; + } + + ret = cs35l41_otp_unpack(cs35l41); + if (ret < 0) { + dev_err(cs35l41->dev, "OTP Unpack failed\n"); + goto err; + } + + cs35l41_dsp_init(cs35l41); + + ret = snd_soc_register_codec(cs35l41->dev, &soc_codec_dev_cs35l41, + cs35l41_dai, ARRAY_SIZE(cs35l41_dai)); + if (ret < 0) { + dev_err(cs35l41->dev, "%s: Register codec failed\n", __func__); + goto err; + } + + dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", + regid, reg_revid); + +err: + regulator_bulk_disable(cs35l41->num_supplies, cs35l41->supplies); + return ret; +} + +MODULE_DESCRIPTION("ASoC CS35L41 driver"); +MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); +MODULE_LICENSE("GPL"); diff --git a/techpack/audio/asoc/codecs/cs35l41/cs35l41.h b/techpack/audio/asoc/codecs/cs35l41/cs35l41.h new file mode 100644 index 000000000000..ce63c2b1daeb --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41/cs35l41.h @@ -0,0 +1,766 @@ +/* + * cs35l41.h -- CS35L41 ALSA SoC audio driver + * + * Copyright 2018 Cirrus Logic, Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * + * Author: Brian Austin + * David Rhodes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __CS35L41_H__ +#define __CS35L41_H__ + +#include + +#define CS35L41_FIRSTREG 0x00000000 +#define CS35L41_LASTREG 0x03804FE8 +#define CS35L41_DEVID 0x00000000 +#define CS35L41_REVID 0x00000004 +#define CS35L41_FABID 0x00000008 +#define CS35L41_RELID 0x0000000C +#define CS35L41_OTPID 0x00000010 +#define CS35L41_SFT_RESET 0x00000020 +#define CS35L41_TEST_KEY_CTL 0x00000040 +#define CS35L41_USER_KEY_CTL 0x00000044 +#define CS35L41_OTP_MEM0 0x00000400 +#define CS35L41_OTP_MEM31 0x0000047C +#define CS35L41_OTP_CTRL0 0x00000500 +#define CS35L41_OTP_CTRL1 0x00000504 +#define CS35L41_OTP_CTRL3 0x00000508 +#define CS35L41_OTP_CTRL4 0x0000050C +#define CS35L41_OTP_CTRL5 0x00000510 +#define CS35L41_OTP_CTRL6 0x00000514 +#define CS35L41_OTP_CTRL7 0x00000518 +#define CS35L41_OTP_CTRL8 0x0000051C +#define CS35L41_PWR_CTRL1 0x00002014 +#define CS35L41_PWR_CTRL2 0x00002018 +#define CS35L41_PWR_CTRL3 0x0000201C +#define CS35L41_CTRL_OVRRIDE 0x00002020 +#define CS35L41_AMP_OUT_MUTE 0x00002024 +#define CS35L41_PROTECT_REL_ERR_IGN 0x00002034 +#define CS35L41_GPIO_PAD_CONTROL 0x0000242C +#define CS35L41_JTAG_CONTROL 0x00002438 +#define CS35L41_PLL_CLK_CTRL 0x00002C04 +#define CS35L41_DSP_CLK_CTRL 0x00002C08 +#define CS35L41_GLOBAL_CLK_CTRL 0x00002C0C +#define CS35L41_DATA_FS_SEL 0x00002C10 +#define CS35L41_MDSYNC_EN 0x00003400 +#define CS35L41_MDSYNC_TX_ID 0x00003408 +#define CS35L41_MDSYNC_PWR_CTRL 0x0000340C +#define CS35L41_MDSYNC_DATA_TX 0x00003410 +#define CS35L41_MDSYNC_TX_STATUS 0x00003414 +#define CS35L41_MDSYNC_DATA_RX 0x0000341C +#define CS35L41_MDSYNC_RX_STATUS 0x00003420 +#define CS35L41_MDSYNC_ERR_STATUS 0x00003424 +#define CS35L41_MDSYNC_SYNC_PTE2 0x00003528 +#define CS35L41_MDSYNC_SYNC_PTE3 0x0000352C +#define CS35L41_MDSYNC_SYNC_MSM_STATUS 0x0000353C +#define CS35L41_BSTCVRT_VCTRL1 0x00003800 +#define CS35L41_BSTCVRT_VCTRL2 0x00003804 +#define CS35L41_BSTCVRT_PEAK_CUR 0x00003808 +#define CS35L41_BSTCVRT_SFT_RAMP 0x0000380C +#define CS35L41_BSTCVRT_COEFF 0x00003810 +#define CS35L41_BSTCVRT_SLOPE_LBST 0x00003814 +#define CS35L41_BSTCVRT_SW_FREQ 0x00003818 +#define CS35L41_BSTCVRT_DCM_CTRL 0x0000381C +#define CS35L41_BSTCVRT_DCM_MODE_FORCE 0x00003820 +#define CS35L41_BSTCVRT_OVERVOLT_CTRL 0x00003830 +#define CS35L41_VI_VOL_POL 0x00004000 +#define CS35L41_VIMON_SPKMON_RESYNC 0x00004100 +#define CS35L41_DTEMP_WARN_THLD 0x00004220 +#define CS35L41_DTEMP_CFG 0x00004224 +#define CS35L41_DTEMP_EN 0x00004308 +#define CS35L41_VPVBST_FS_SEL 0x00004400 +#define CS35L41_SP_ENABLES 0x00004800 +#define CS35L41_SP_RATE_CTRL 0x00004804 +#define CS35L41_SP_FORMAT 0x00004808 +#define CS35L41_SP_HIZ_CTRL 0x0000480C +#define CS35L41_SP_FRAME_TX_SLOT 0x00004810 +#define CS35L41_SP_FRAME_RX_SLOT 0x00004820 +#define CS35L41_SP_TX_WL 0x00004830 +#define CS35L41_SP_RX_WL 0x00004840 +#define CS35L41_ASP_CONTROL4 0x00004854 +#define CS35L41_DAC_PCM1_SRC 0x00004C00 +#define CS35L41_ASP_TX1_SRC 0x00004C20 +#define CS35L41_ASP_TX2_SRC 0x00004C24 +#define CS35L41_ASP_TX3_SRC 0x00004C28 +#define CS35L41_ASP_TX4_SRC 0x00004C2C +#define CS35L41_DSP1_RX1_SRC 0x00004C40 +#define CS35L41_DSP1_RX2_SRC 0x00004C44 +#define CS35L41_DSP1_RX3_SRC 0x00004C48 +#define CS35L41_DSP1_RX4_SRC 0x00004C4C +#define CS35L41_DSP1_RX5_SRC 0x00004C50 +#define CS35L41_DSP1_RX6_SRC 0x00004C54 +#define CS35L41_DSP1_RX7_SRC 0x00004C58 +#define CS35L41_DSP1_RX8_SRC 0x00004C5C +#define CS35L41_NGATE1_SRC 0x00004C60 +#define CS35L41_NGATE2_SRC 0x00004C64 +#define CS35L41_AMP_DIG_VOL_CTRL 0x00006000 +#define CS35L41_VPBR_CFG 0x00006404 +#define CS35L41_VBBR_CFG 0x00006408 +#define CS35L41_VPBR_STATUS 0x0000640C +#define CS35L41_VBBR_STATUS 0x00006410 +#define CS35L41_OVERTEMP_CFG 0x00006414 +#define CS35L41_AMP_ERR_VOL 0x00006418 +#define CS35L41_VOL_STATUS_TO_DSP 0x00006450 +#define CS35L41_CLASSH_CFG 0x00006800 +#define CS35L41_WKFET_CFG 0x00006804 +#define CS35L41_NG_CFG 0x00006808 +#define CS35L41_AMP_GAIN_CTRL 0x00006C04 +#define CS35L41_DAC_MSM_CFG 0x00007400 +#define CS35L41_IRQ1_CFG 0x00010000 +#define CS35L41_IRQ1_STATUS 0x00010004 +#define CS35L41_IRQ1_STATUS1 0x00010010 +#define CS35L41_IRQ1_STATUS2 0x00010014 +#define CS35L41_IRQ1_STATUS3 0x00010018 +#define CS35L41_IRQ1_STATUS4 0x0001001C +#define CS35L41_IRQ1_RAW_STATUS1 0x00010090 +#define CS35L41_IRQ1_RAW_STATUS2 0x00010094 +#define CS35L41_IRQ1_RAW_STATUS3 0x00010098 +#define CS35L41_IRQ1_RAW_STATUS4 0x0001009C +#define CS35L41_IRQ1_MASK1 0x00010110 +#define CS35L41_IRQ1_MASK2 0x00010114 +#define CS35L41_IRQ1_MASK3 0x00010118 +#define CS35L41_IRQ1_MASK4 0x0001011C +#define CS35L41_IRQ1_FRC1 0x00010190 +#define CS35L41_IRQ1_FRC2 0x00010194 +#define CS35L41_IRQ1_FRC3 0x00010198 +#define CS35L41_IRQ1_FRC4 0x0001019C +#define CS35L41_IRQ1_EDGE1 0x00010210 +#define CS35L41_IRQ1_EDGE4 0x0001021C +#define CS35L41_IRQ1_POL1 0x00010290 +#define CS35L41_IRQ1_POL2 0x00010294 +#define CS35L41_IRQ1_POL3 0x00010298 +#define CS35L41_IRQ1_POL4 0x0001029C +#define CS35L41_IRQ1_DB3 0x00010318 +#define CS35L41_IRQ2_CFG 0x00010800 +#define CS35L41_IRQ2_STATUS 0x00010804 +#define CS35L41_IRQ2_STATUS1 0x00010810 +#define CS35L41_IRQ2_STATUS2 0x00010814 +#define CS35L41_IRQ2_STATUS3 0x00010818 +#define CS35L41_IRQ2_STATUS4 0x0001081C +#define CS35L41_IRQ2_RAW_STATUS1 0x00010890 +#define CS35L41_IRQ2_RAW_STATUS2 0x00010894 +#define CS35L41_IRQ2_RAW_STATUS3 0x00010898 +#define CS35L41_IRQ2_RAW_STATUS4 0x0001089C +#define CS35L41_IRQ2_MASK1 0x00010910 +#define CS35L41_IRQ2_MASK2 0x00010914 +#define CS35L41_IRQ2_MASK3 0x00010918 +#define CS35L41_IRQ2_MASK4 0x0001091C +#define CS35L41_IRQ2_FRC1 0x00010990 +#define CS35L41_IRQ2_FRC2 0x00010994 +#define CS35L41_IRQ2_FRC3 0x00010998 +#define CS35L41_IRQ2_FRC4 0x0001099C +#define CS35L41_IRQ2_EDGE1 0x00010A10 +#define CS35L41_IRQ2_EDGE4 0x00010A1C +#define CS35L41_IRQ2_POL1 0x00010A90 +#define CS35L41_IRQ2_POL2 0x00010A94 +#define CS35L41_IRQ2_POL3 0x00010A98 +#define CS35L41_IRQ2_POL4 0x00010A9C +#define CS35L41_IRQ2_DB3 0x00010B18 +#define CS35L41_GPIO_STATUS1 0x00011000 +#define CS35L41_GPIO1_CTRL1 0x00011008 +#define CS35L41_GPIO2_CTRL1 0x0001100C +#define CS35L41_MIXER_NGATE_CFG 0x00012000 +#define CS35L41_MIXER_NGATE_CH1_CFG 0x00012004 +#define CS35L41_MIXER_NGATE_CH2_CFG 0x00012008 +#define CS35L41_DSP_MBOX_1 0x00013000 +#define CS35L41_DSP_MBOX_2 0x00013004 +#define CS35L41_DSP_MBOX_3 0x00013008 +#define CS35L41_DSP_MBOX_4 0x0001300C +#define CS35L41_DSP_MBOX_5 0x00013010 +#define CS35L41_DSP_MBOX_6 0x00013014 +#define CS35L41_DSP_MBOX_7 0x00013018 +#define CS35L41_DSP_MBOX_8 0x0001301C +#define CS35L41_DSP_VIRT1_MBOX_1 0x00013020 +#define CS35L41_DSP_VIRT1_MBOX_2 0x00013024 +#define CS35L41_DSP_VIRT1_MBOX_3 0x00013028 +#define CS35L41_DSP_VIRT1_MBOX_4 0x0001302C +#define CS35L41_DSP_VIRT1_MBOX_5 0x00013030 +#define CS35L41_DSP_VIRT1_MBOX_6 0x00013034 +#define CS35L41_DSP_VIRT1_MBOX_7 0x00013038 +#define CS35L41_DSP_VIRT1_MBOX_8 0x0001303C +#define CS35L41_DSP_VIRT2_MBOX_1 0x00013040 +#define CS35L41_DSP_VIRT2_MBOX_2 0x00013044 +#define CS35L41_DSP_VIRT2_MBOX_3 0x00013048 +#define CS35L41_DSP_VIRT2_MBOX_4 0x0001304C +#define CS35L41_DSP_VIRT2_MBOX_5 0x00013050 +#define CS35L41_DSP_VIRT2_MBOX_6 0x00013054 +#define CS35L41_DSP_VIRT2_MBOX_7 0x00013058 +#define CS35L41_DSP_VIRT2_MBOX_8 0x0001305C +#define CS35L41_CLOCK_DETECT_1 0x00014000 +#define CS35L41_TIMER1_CONTROL 0x00015000 +#define CS35L41_TIMER1_COUNT_PRESET 0x00015004 +#define CS35L41_TIMER1_START_STOP 0x0001500C +#define CS35L41_TIMER1_STATUS 0x00015010 +#define CS35L41_TIMER1_COUNT_READBACK 0x00015014 +#define CS35L41_TIMER1_DSP_CLK_CFG 0x00015018 +#define CS35L41_TIMER1_DSP_CLK_STATUS 0x0001501C +#define CS35L41_TIMER2_CONTROL 0x00015100 +#define CS35L41_TIMER2_COUNT_PRESET 0x00015104 +#define CS35L41_TIMER2_START_STOP 0x0001510C +#define CS35L41_TIMER2_STATUS 0x00015110 +#define CS35L41_TIMER2_COUNT_READBACK 0x00015114 +#define CS35L41_TIMER2_DSP_CLK_CFG 0x00015118 +#define CS35L41_TIMER2_DSP_CLK_STATUS 0x0001511C +#define CS35L41_DFT_JTAG_CONTROL 0x00016000 +#define CS35L41_DIE_STS1 0x00017040 +#define CS35L41_DIE_STS2 0x00017044 +#define CS35L41_TEMP_CAL1 0x00017048 +#define CS35L41_TEMP_CAL2 0x0001704C +#define CS35L41_DSP1_XMEM_PACK_0 0x02000000 +#define CS35L41_DSP1_XMEM_PACK_3068 0x02002FF0 +#define CS35L41_DSP1_XMEM_UNPACK32_0 0x02400000 +#define CS35L41_DSP1_XMEM_UNPACK32_2046 0x02401FF8 +#define CS35L41_DSP1_TIMESTAMP_COUNT 0x025C0800 +#define CS35L41_DSP1_SYS_ID 0x025E0000 +#define CS35L41_DSP1_SYS_VERSION 0x025E0004 +#define CS35L41_DSP1_SYS_CORE_ID 0x025E0008 +#define CS35L41_DSP1_SYS_AHB_ADDR 0x025E000C +#define CS35L41_DSP1_SYS_XSRAM_SIZE 0x025E0010 +#define CS35L41_DSP1_SYS_YSRAM_SIZE 0x025E0018 +#define CS35L41_DSP1_SYS_PSRAM_SIZE 0x025E0020 +#define CS35L41_DSP1_SYS_PM_BOOT_SIZE 0x025E0028 +#define CS35L41_DSP1_SYS_FEATURES 0x025E002C +#define CS35L41_DSP1_SYS_FIR_FILTERS 0x025E0030 +#define CS35L41_DSP1_SYS_LMS_FILTERS 0x025E0034 +#define CS35L41_DSP1_SYS_XM_BANK_SIZE 0x025E0038 +#define CS35L41_DSP1_SYS_YM_BANK_SIZE 0x025E003C +#define CS35L41_DSP1_SYS_PM_BANK_SIZE 0x025E0040 +#define CS35L41_DSP1_AHBM_WIN0_CTRL0 0x025E2000 +#define CS35L41_DSP1_AHBM_WIN0_CTRL1 0x025E2004 +#define CS35L41_DSP1_AHBM_WIN1_CTRL0 0x025E2008 +#define CS35L41_DSP1_AHBM_WIN1_CTRL1 0x025E200C +#define CS35L41_DSP1_AHBM_WIN2_CTRL0 0x025E2010 +#define CS35L41_DSP1_AHBM_WIN2_CTRL1 0x025E2014 +#define CS35L41_DSP1_AHBM_WIN3_CTRL0 0x025E2018 +#define CS35L41_DSP1_AHBM_WIN3_CTRL1 0x025E201C +#define CS35L41_DSP1_AHBM_WIN4_CTRL0 0x025E2020 +#define CS35L41_DSP1_AHBM_WIN4_CTRL1 0x025E2024 +#define CS35L41_DSP1_AHBM_WIN5_CTRL0 0x025E2028 +#define CS35L41_DSP1_AHBM_WIN5_CTRL1 0x025E202C +#define CS35L41_DSP1_AHBM_WIN6_CTRL0 0x025E2030 +#define CS35L41_DSP1_AHBM_WIN6_CTRL1 0x025E2034 +#define CS35L41_DSP1_AHBM_WIN7_CTRL0 0x025E2038 +#define CS35L41_DSP1_AHBM_WIN7_CTRL1 0x025E203C +#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL0 0x025E2040 +#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL1 0x025E2044 +#define CS35L41_DSP1_XMEM_UNPACK24_0 0x02800000 +#define CS35L41_DSP1_XMEM_UNPACK24_4093 0x02803FF4 +#define CS35L41_DSP1_CTRL_BASE 0x02B80000 +#define CS35L41_DSP1_CORE_SOFT_RESET 0x02B80010 +#define CS35L41_DSP1_DEBUG 0x02B80040 +#define CS35L41_DSP1_TIMER_CTRL 0x02B80048 +#define CS35L41_DSP1_STREAM_ARB_CTRL 0x02B80050 +#define CS35L41_DSP1_RX1_RATE 0x02B80080 +#define CS35L41_DSP1_RX2_RATE 0x02B80088 +#define CS35L41_DSP1_RX3_RATE 0x02B80090 +#define CS35L41_DSP1_RX4_RATE 0x02B80098 +#define CS35L41_DSP1_RX5_RATE 0x02B800A0 +#define CS35L41_DSP1_RX6_RATE 0x02B800A8 +#define CS35L41_DSP1_RX7_RATE 0x02B800B0 +#define CS35L41_DSP1_RX8_RATE 0x02B800B8 +#define CS35L41_DSP1_TX1_RATE 0x02B80280 +#define CS35L41_DSP1_TX2_RATE 0x02B80288 +#define CS35L41_DSP1_TX3_RATE 0x02B80290 +#define CS35L41_DSP1_TX4_RATE 0x02B80298 +#define CS35L41_DSP1_TX5_RATE 0x02B802A0 +#define CS35L41_DSP1_TX6_RATE 0x02B802A8 +#define CS35L41_DSP1_TX7_RATE 0x02B802B0 +#define CS35L41_DSP1_TX8_RATE 0x02B802B8 +#define CS35L41_DSP1_NMI_CTRL1 0x02B80480 +#define CS35L41_DSP1_NMI_CTRL2 0x02B80488 +#define CS35L41_DSP1_NMI_CTRL3 0x02B80490 +#define CS35L41_DSP1_NMI_CTRL4 0x02B80498 +#define CS35L41_DSP1_NMI_CTRL5 0x02B804A0 +#define CS35L41_DSP1_NMI_CTRL6 0x02B804A8 +#define CS35L41_DSP1_NMI_CTRL7 0x02B804B0 +#define CS35L41_DSP1_NMI_CTRL8 0x02B804B8 +#define CS35L41_DSP1_RESUME_CTRL 0x02B80500 +#define CS35L41_DSP1_IRQ1_CTRL 0x02B80508 +#define CS35L41_DSP1_IRQ2_CTRL 0x02B80510 +#define CS35L41_DSP1_IRQ3_CTRL 0x02B80518 +#define CS35L41_DSP1_IRQ4_CTRL 0x02B80520 +#define CS35L41_DSP1_IRQ5_CTRL 0x02B80528 +#define CS35L41_DSP1_IRQ6_CTRL 0x02B80530 +#define CS35L41_DSP1_IRQ7_CTRL 0x02B80538 +#define CS35L41_DSP1_IRQ8_CTRL 0x02B80540 +#define CS35L41_DSP1_IRQ9_CTRL 0x02B80548 +#define CS35L41_DSP1_IRQ10_CTRL 0x02B80550 +#define CS35L41_DSP1_IRQ11_CTRL 0x02B80558 +#define CS35L41_DSP1_IRQ12_CTRL 0x02B80560 +#define CS35L41_DSP1_IRQ13_CTRL 0x02B80568 +#define CS35L41_DSP1_IRQ14_CTRL 0x02B80570 +#define CS35L41_DSP1_IRQ15_CTRL 0x02B80578 +#define CS35L41_DSP1_IRQ16_CTRL 0x02B80580 +#define CS35L41_DSP1_IRQ17_CTRL 0x02B80588 +#define CS35L41_DSP1_IRQ18_CTRL 0x02B80590 +#define CS35L41_DSP1_IRQ19_CTRL 0x02B80598 +#define CS35L41_DSP1_IRQ20_CTRL 0x02B805A0 +#define CS35L41_DSP1_IRQ21_CTRL 0x02B805A8 +#define CS35L41_DSP1_IRQ22_CTRL 0x02B805B0 +#define CS35L41_DSP1_IRQ23_CTRL 0x02B805B8 +#define CS35L41_DSP1_SCRATCH1 0x02B805C0 +#define CS35L41_DSP1_SCRATCH2 0x02B805C8 +#define CS35L41_DSP1_SCRATCH3 0x02B805D0 +#define CS35L41_DSP1_SCRATCH4 0x02B805D8 +#define CS35L41_DSP1_CCM_CORE_CTRL 0x02BC1000 +#define CS35L41_DSP1_CCM_CLK_OVERRIDE 0x02BC1008 +#define CS35L41_DSP1_XM_MSTR_EN 0x02BC2000 +#define CS35L41_DSP1_XM_CORE_PRI 0x02BC2008 +#define CS35L41_DSP1_XM_AHB_PACK_PL_PRI 0x02BC2010 +#define CS35L41_DSP1_XM_AHB_UP_PL_PRI 0x02BC2018 +#define CS35L41_DSP1_XM_ACCEL_PL0_PRI 0x02BC2020 +#define CS35L41_DSP1_XM_NPL0_PRI 0x02BC2078 +#define CS35L41_DSP1_YM_MSTR_EN 0x02BC20C0 +#define CS35L41_DSP1_YM_CORE_PRI 0x02BC20C8 +#define CS35L41_DSP1_YM_AHB_PACK_PL_PRI 0x02BC20D0 +#define CS35L41_DSP1_YM_AHB_UP_PL_PRI 0x02BC20D8 +#define CS35L41_DSP1_YM_ACCEL_PL0_PRI 0x02BC20E0 +#define CS35L41_DSP1_YM_NPL0_PRI 0x02BC2138 +#define CS35L41_DSP1_PM_MSTR_EN 0x02BC2180 +#define CS35L41_DSP1_PM_PATCH0_ADDR 0x02BC2188 +#define CS35L41_DSP1_PM_PATCH0_EN 0x02BC218C +#define CS35L41_DSP1_PM_PATCH0_DATA_LO 0x02BC2190 +#define CS35L41_DSP1_PM_PATCH0_DATA_HI 0x02BC2194 +#define CS35L41_DSP1_PM_PATCH1_ADDR 0x02BC2198 +#define CS35L41_DSP1_PM_PATCH1_EN 0x02BC219C +#define CS35L41_DSP1_PM_PATCH1_DATA_LO 0x02BC21A0 +#define CS35L41_DSP1_PM_PATCH1_DATA_HI 0x02BC21A4 +#define CS35L41_DSP1_PM_PATCH2_ADDR 0x02BC21A8 +#define CS35L41_DSP1_PM_PATCH2_EN 0x02BC21AC +#define CS35L41_DSP1_PM_PATCH2_DATA_LO 0x02BC21B0 +#define CS35L41_DSP1_PM_PATCH2_DATA_HI 0x02BC21B4 +#define CS35L41_DSP1_PM_PATCH3_ADDR 0x02BC21B8 +#define CS35L41_DSP1_PM_PATCH3_EN 0x02BC21BC +#define CS35L41_DSP1_PM_PATCH3_DATA_LO 0x02BC21C0 +#define CS35L41_DSP1_PM_PATCH3_DATA_HI 0x02BC21C4 +#define CS35L41_DSP1_PM_PATCH4_ADDR 0x02BC21C8 +#define CS35L41_DSP1_PM_PATCH4_EN 0x02BC21CC +#define CS35L41_DSP1_PM_PATCH4_DATA_LO 0x02BC21D0 +#define CS35L41_DSP1_PM_PATCH4_DATA_HI 0x02BC21D4 +#define CS35L41_DSP1_PM_PATCH5_ADDR 0x02BC21D8 +#define CS35L41_DSP1_PM_PATCH5_EN 0x02BC21DC +#define CS35L41_DSP1_PM_PATCH5_DATA_LO 0x02BC21E0 +#define CS35L41_DSP1_PM_PATCH5_DATA_HI 0x02BC21E4 +#define CS35L41_DSP1_PM_PATCH6_ADDR 0x02BC21E8 +#define CS35L41_DSP1_PM_PATCH6_EN 0x02BC21EC +#define CS35L41_DSP1_PM_PATCH6_DATA_LO 0x02BC21F0 +#define CS35L41_DSP1_PM_PATCH6_DATA_HI 0x02BC21F4 +#define CS35L41_DSP1_PM_PATCH7_ADDR 0x02BC21F8 +#define CS35L41_DSP1_PM_PATCH7_EN 0x02BC21FC +#define CS35L41_DSP1_PM_PATCH7_DATA_LO 0x02BC2200 +#define CS35L41_DSP1_PM_PATCH7_DATA_HI 0x02BC2204 +#define CS35L41_DSP1_MPU_XM_ACCESS0 0x02BC3000 +#define CS35L41_DSP1_MPU_YM_ACCESS0 0x02BC3004 +#define CS35L41_DSP1_MPU_WNDW_ACCESS0 0x02BC3008 +#define CS35L41_DSP1_MPU_XREG_ACCESS0 0x02BC300C +#define CS35L41_DSP1_MPU_YREG_ACCESS0 0x02BC3014 +#define CS35L41_DSP1_MPU_XM_ACCESS1 0x02BC3018 +#define CS35L41_DSP1_MPU_YM_ACCESS1 0x02BC301C +#define CS35L41_DSP1_MPU_WNDW_ACCESS1 0x02BC3020 +#define CS35L41_DSP1_MPU_XREG_ACCESS1 0x02BC3024 +#define CS35L41_DSP1_MPU_YREG_ACCESS1 0x02BC302C +#define CS35L41_DSP1_MPU_XM_ACCESS2 0x02BC3030 +#define CS35L41_DSP1_MPU_YM_ACCESS2 0x02BC3034 +#define CS35L41_DSP1_MPU_WNDW_ACCESS2 0x02BC3038 +#define CS35L41_DSP1_MPU_XREG_ACCESS2 0x02BC303C +#define CS35L41_DSP1_MPU_YREG_ACCESS2 0x02BC3044 +#define CS35L41_DSP1_MPU_XM_ACCESS3 0x02BC3048 +#define CS35L41_DSP1_MPU_YM_ACCESS3 0x02BC304C +#define CS35L41_DSP1_MPU_WNDW_ACCESS3 0x02BC3050 +#define CS35L41_DSP1_MPU_XREG_ACCESS3 0x02BC3054 +#define CS35L41_DSP1_MPU_YREG_ACCESS3 0x02BC305C +#define CS35L41_DSP1_MPU_XM_VIO_ADDR 0x02BC3100 +#define CS35L41_DSP1_MPU_XM_VIO_STATUS 0x02BC3104 +#define CS35L41_DSP1_MPU_YM_VIO_ADDR 0x02BC3108 +#define CS35L41_DSP1_MPU_YM_VIO_STATUS 0x02BC310C +#define CS35L41_DSP1_MPU_PM_VIO_ADDR 0x02BC3110 +#define CS35L41_DSP1_MPU_PM_VIO_STATUS 0x02BC3114 +#define CS35L41_DSP1_MPU_LOCK_CONFIG 0x02BC3140 +#define CS35L41_DSP1_MPU_WDT_RST_CTRL 0x02BC3180 +#define CS35L41_DSP1_STRMARB_MSTR0_CFG0 0x02BC5000 +#define CS35L41_DSP1_STRMARB_MSTR0_CFG1 0x02BC5004 +#define CS35L41_DSP1_STRMARB_MSTR0_CFG2 0x02BC5008 +#define CS35L41_DSP1_STRMARB_MSTR1_CFG0 0x02BC5010 +#define CS35L41_DSP1_STRMARB_MSTR1_CFG1 0x02BC5014 +#define CS35L41_DSP1_STRMARB_MSTR1_CFG2 0x02BC5018 +#define CS35L41_DSP1_STRMARB_MSTR2_CFG0 0x02BC5020 +#define CS35L41_DSP1_STRMARB_MSTR2_CFG1 0x02BC5024 +#define CS35L41_DSP1_STRMARB_MSTR2_CFG2 0x02BC5028 +#define CS35L41_DSP1_STRMARB_MSTR3_CFG0 0x02BC5030 +#define CS35L41_DSP1_STRMARB_MSTR3_CFG1 0x02BC5034 +#define CS35L41_DSP1_STRMARB_MSTR3_CFG2 0x02BC5038 +#define CS35L41_DSP1_STRMARB_MSTR4_CFG0 0x02BC5040 +#define CS35L41_DSP1_STRMARB_MSTR4_CFG1 0x02BC5044 +#define CS35L41_DSP1_STRMARB_MSTR4_CFG2 0x02BC5048 +#define CS35L41_DSP1_STRMARB_MSTR5_CFG0 0x02BC5050 +#define CS35L41_DSP1_STRMARB_MSTR5_CFG1 0x02BC5054 +#define CS35L41_DSP1_STRMARB_MSTR5_CFG2 0x02BC5058 +#define CS35L41_DSP1_STRMARB_MSTR6_CFG0 0x02BC5060 +#define CS35L41_DSP1_STRMARB_MSTR6_CFG1 0x02BC5064 +#define CS35L41_DSP1_STRMARB_MSTR6_CFG2 0x02BC5068 +#define CS35L41_DSP1_STRMARB_MSTR7_CFG0 0x02BC5070 +#define CS35L41_DSP1_STRMARB_MSTR7_CFG1 0x02BC5074 +#define CS35L41_DSP1_STRMARB_MSTR7_CFG2 0x02BC5078 +#define CS35L41_DSP1_STRMARB_TX0_CFG0 0x02BC5200 +#define CS35L41_DSP1_STRMARB_TX0_CFG1 0x02BC5204 +#define CS35L41_DSP1_STRMARB_TX1_CFG0 0x02BC5208 +#define CS35L41_DSP1_STRMARB_TX1_CFG1 0x02BC520C +#define CS35L41_DSP1_STRMARB_TX2_CFG0 0x02BC5210 +#define CS35L41_DSP1_STRMARB_TX2_CFG1 0x02BC5214 +#define CS35L41_DSP1_STRMARB_TX3_CFG0 0x02BC5218 +#define CS35L41_DSP1_STRMARB_TX3_CFG1 0x02BC521C +#define CS35L41_DSP1_STRMARB_TX4_CFG0 0x02BC5220 +#define CS35L41_DSP1_STRMARB_TX4_CFG1 0x02BC5224 +#define CS35L41_DSP1_STRMARB_TX5_CFG0 0x02BC5228 +#define CS35L41_DSP1_STRMARB_TX5_CFG1 0x02BC522C +#define CS35L41_DSP1_STRMARB_TX6_CFG0 0x02BC5230 +#define CS35L41_DSP1_STRMARB_TX6_CFG1 0x02BC5234 +#define CS35L41_DSP1_STRMARB_TX7_CFG0 0x02BC5238 +#define CS35L41_DSP1_STRMARB_TX7_CFG1 0x02BC523C +#define CS35L41_DSP1_STRMARB_RX0_CFG0 0x02BC5400 +#define CS35L41_DSP1_STRMARB_RX0_CFG1 0x02BC5404 +#define CS35L41_DSP1_STRMARB_RX1_CFG0 0x02BC5408 +#define CS35L41_DSP1_STRMARB_RX1_CFG1 0x02BC540C +#define CS35L41_DSP1_STRMARB_RX2_CFG0 0x02BC5410 +#define CS35L41_DSP1_STRMARB_RX2_CFG1 0x02BC5414 +#define CS35L41_DSP1_STRMARB_RX3_CFG0 0x02BC5418 +#define CS35L41_DSP1_STRMARB_RX3_CFG1 0x02BC541C +#define CS35L41_DSP1_STRMARB_RX4_CFG0 0x02BC5420 +#define CS35L41_DSP1_STRMARB_RX4_CFG1 0x02BC5424 +#define CS35L41_DSP1_STRMARB_RX5_CFG0 0x02BC5428 +#define CS35L41_DSP1_STRMARB_RX5_CFG1 0x02BC542C +#define CS35L41_DSP1_STRMARB_RX6_CFG0 0x02BC5430 +#define CS35L41_DSP1_STRMARB_RX6_CFG1 0x02BC5434 +#define CS35L41_DSP1_STRMARB_RX7_CFG0 0x02BC5438 +#define CS35L41_DSP1_STRMARB_RX7_CFG1 0x02BC543C +#define CS35L41_DSP1_STRMARB_IRQ0_CFG0 0x02BC5600 +#define CS35L41_DSP1_STRMARB_IRQ0_CFG1 0x02BC5604 +#define CS35L41_DSP1_STRMARB_IRQ0_CFG2 0x02BC5608 +#define CS35L41_DSP1_STRMARB_IRQ1_CFG0 0x02BC5610 +#define CS35L41_DSP1_STRMARB_IRQ1_CFG1 0x02BC5614 +#define CS35L41_DSP1_STRMARB_IRQ1_CFG2 0x02BC5618 +#define CS35L41_DSP1_STRMARB_IRQ2_CFG0 0x02BC5620 +#define CS35L41_DSP1_STRMARB_IRQ2_CFG1 0x02BC5624 +#define CS35L41_DSP1_STRMARB_IRQ2_CFG2 0x02BC5628 +#define CS35L41_DSP1_STRMARB_IRQ3_CFG0 0x02BC5630 +#define CS35L41_DSP1_STRMARB_IRQ3_CFG1 0x02BC5634 +#define CS35L41_DSP1_STRMARB_IRQ3_CFG2 0x02BC5638 +#define CS35L41_DSP1_STRMARB_IRQ4_CFG0 0x02BC5640 +#define CS35L41_DSP1_STRMARB_IRQ4_CFG1 0x02BC5644 +#define CS35L41_DSP1_STRMARB_IRQ4_CFG2 0x02BC5648 +#define CS35L41_DSP1_STRMARB_IRQ5_CFG0 0x02BC5650 +#define CS35L41_DSP1_STRMARB_IRQ5_CFG1 0x02BC5654 +#define CS35L41_DSP1_STRMARB_IRQ5_CFG2 0x02BC5658 +#define CS35L41_DSP1_STRMARB_IRQ6_CFG0 0x02BC5660 +#define CS35L41_DSP1_STRMARB_IRQ6_CFG1 0x02BC5664 +#define CS35L41_DSP1_STRMARB_IRQ6_CFG2 0x02BC5668 +#define CS35L41_DSP1_STRMARB_IRQ7_CFG0 0x02BC5670 +#define CS35L41_DSP1_STRMARB_IRQ7_CFG1 0x02BC5674 +#define CS35L41_DSP1_STRMARB_IRQ7_CFG2 0x02BC5678 +#define CS35L41_DSP1_STRMARB_RESYNC_MSK 0x02BC5A00 +#define CS35L41_DSP1_STRMARB_ERR_STATUS 0x02BC5A08 +#define CS35L41_DSP1_INTPCTL_RES_STATIC 0x02BC6000 +#define CS35L41_DSP1_INTPCTL_RES_DYN 0x02BC6004 +#define CS35L41_DSP1_INTPCTL_NMI_CTRL 0x02BC6008 +#define CS35L41_DSP1_INTPCTL_IRQ_INV 0x02BC6010 +#define CS35L41_DSP1_INTPCTL_IRQ_MODE 0x02BC6014 +#define CS35L41_DSP1_INTPCTL_IRQ_EN 0x02BC6018 +#define CS35L41_DSP1_INTPCTL_IRQ_MSK 0x02BC601C +#define CS35L41_DSP1_INTPCTL_IRQ_FLUSH 0x02BC6020 +#define CS35L41_DSP1_INTPCTL_IRQ_MSKCLR 0x02BC6024 +#define CS35L41_DSP1_INTPCTL_IRQ_FRC 0x02BC6028 +#define CS35L41_DSP1_INTPCTL_IRQ_MSKSET 0x02BC602C +#define CS35L41_DSP1_INTPCTL_IRQ_ERR 0x02BC6030 +#define CS35L41_DSP1_INTPCTL_IRQ_PEND 0x02BC6034 +#define CS35L41_DSP1_INTPCTL_IRQ_GEN 0x02BC6038 +#define CS35L41_DSP1_INTPCTL_TESTBITS 0x02BC6040 +#define CS35L41_DSP1_WDT_CONTROL 0x02BC7000 +#define CS35L41_DSP1_WDT_STATUS 0x02BC7008 +#define CS35L41_DSP1_YMEM_PACK_0 0x02C00000 +#define CS35L41_DSP1_YMEM_PACK_1532 0x02C017F0 +#define CS35L41_DSP1_YMEM_UNPACK32_0 0x03000000 +#define CS35L41_DSP1_YMEM_UNPACK32_1022 0x03000FF8 +#define CS35L41_DSP1_YMEM_UNPACK24_0 0x03400000 +#define CS35L41_DSP1_YMEM_UNPACK24_2045 0x03401FF4 +#define CS35L41_DSP1_PMEM_0 0x03800000 +#define CS35L41_DSP1_PMEM_5114 0x03804FE8 + +/*test regs for emulation bringup*/ +#define CS35L41_PLL_OVR 0x00003018 +#define CS35L41_BST_TEST_DUTY 0x00003900 +#define CS35L41_DIGPWM_IOCTRL 0x0000706C + +/*registers populated by OTP*/ +#define CS35L41_OTP_TRIM_1 0x0000208c +#define CS35L41_OTP_TRIM_2 0x00002090 +#define CS35L41_OTP_TRIM_3 0x00003010 +#define CS35L41_OTP_TRIM_4 0x0000300C +#define CS35L41_OTP_TRIM_5 0x0000394C +#define CS35L41_OTP_TRIM_6 0x00003950 +#define CS35L41_OTP_TRIM_7 0x00003954 +#define CS35L41_OTP_TRIM_8 0x00003958 +#define CS35L41_OTP_TRIM_9 0x0000395C +#define CS35L41_OTP_TRIM_10 0x0000416C +#define CS35L41_OTP_TRIM_11 0x00004160 +#define CS35L41_OTP_TRIM_12 0x00004170 +#define CS35L41_OTP_TRIM_13 0x00004360 +#define CS35L41_OTP_TRIM_14 0x00004448 +#define CS35L41_OTP_TRIM_15 0x0000444C +#define CS35L41_OTP_TRIM_16 0x00006E30 +#define CS35L41_OTP_TRIM_17 0x00006E34 +#define CS35L41_OTP_TRIM_18 0x00006E38 +#define CS35L41_OTP_TRIM_19 0x00006E3C +#define CS35L41_OTP_TRIM_20 0x00006E40 +#define CS35L41_OTP_TRIM_21 0x00006E44 +#define CS35L41_OTP_TRIM_22 0x00006E48 +#define CS35L41_OTP_TRIM_23 0x00006E4C +#define CS35L41_OTP_TRIM_24 0x00006E50 +#define CS35L41_OTP_TRIM_25 0x00006E54 +#define CS35L41_OTP_TRIM_26 0x00006E58 +#define CS35L41_OTP_TRIM_27 0x00006E5C +#define CS35L41_OTP_TRIM_28 0x00006E60 +#define CS35L41_OTP_TRIM_29 0x00006E64 +#define CS35L41_OTP_TRIM_30 0x00007418 +#define CS35L41_OTP_TRIM_31 0x0000741C +#define CS35L41_OTP_TRIM_32 0x00007434 +#define CS35L41_OTP_TRIM_33 0x00007068 +#define CS35L41_OTP_TRIM_34 0x0000410C +#define CS35L41_OTP_TRIM_35 0x0000400C +#define CS35L41_OTP_TRIM_36 0x00002030 + +#define CS35L41_MAX_CACHE_REG 0x0000006B +#define CS35L41_OTP_SIZE_WORDS 32 +#define CS35L41_NUM_OTP_ELEM 100 +#define CS35L41_NUM_OTP_MAPS 3 + +#define CS35L41_VALID_PDATA 0x80000000 + +#define CS35L41_SCLK_MSTR_MASK 0x10 +#define CS35L41_SCLK_MSTR_SHIFT 4 +#define CS35L41_LRCLK_MSTR_MASK 0x01 +#define CS35L41_LRCLK_MSTR_SHIFT 0 +#define CS35L41_SCLK_INV_MASK 0x40 +#define CS35L41_SCLK_INV_SHIFT 6 +#define CS35L41_LRCLK_INV_MASK 0x04 +#define CS35L41_LRCLK_INV_SHIFT 2 +#define CS35L41_SCLK_FRC_MASK 0x20 +#define CS35L41_SCLK_FRC_SHIFT 5 +#define CS35L41_LRCLK_FRC_MASK 0x02 +#define CS35L41_LRCLK_FRC_SHIFT 1 + +#define CS35L41_AMP_GAIN_ZC_MASK 0x0400 +#define CS35L41_AMP_GAIN_ZC_SHIFT 10 + +#define CS35L41_BST_CTL_MASK 0xFF +#define CS35L41_BST_CTL_SEL_MASK 0x03 +#define CS35L41_BST_CTL_SEL_REG 0x00 +#define CS35L41_BST_CTL_SEL_CLASSH 0x01 +#define CS35L41_BST_IPK_MASK 0x7F +#define CS35L41_BST_IPK_SHIFT 0 +#define CS35L41_BST_LIM_MASK 0x4 +#define CS35L41_BST_LIM_SHIFT 2 +#define CS35L41_BST_K1_MASK 0x000000FF +#define CS35L41_BST_K1_SHIFT 0 +#define CS35L41_BST_K2_MASK 0x0000FF00 +#define CS35L41_BST_K2_SHIFT 8 +#define CS35L41_BST_SLOPE_MASK 0x0000FF00 +#define CS35L41_BST_SLOPE_SHIFT 8 +#define CS35L41_BST_LBST_VAL_MASK 0x00000003 +#define CS35L41_BST_LBST_VAL_SHIFT 0 + +#define CS35L41_TEMP_THLD_MASK 0x03 +#define CS35L41_VMON_IMON_VOL_MASK 0x07FF07FF +#define CS35L41_PDM_MODE_MASK 0x01 +#define CS35L41_PDM_MODE_SHIFT 0 + +#define CS35L41_CH_MEM_DEPTH_MASK 0x07 +#define CS35L41_CH_MEM_DEPTH_SHIFT 0 +#define CS35L41_CH_HDRM_CTL_MASK 0x007F0000 +#define CS35L41_CH_HDRM_CTL_SHIFT 16 +#define CS35L41_CH_REL_RATE_MASK 0xFF00 +#define CS35L41_CH_REL_RATE_SHIFT 8 +#define CS35L41_CH_WKFET_DLY_MASK 0x001C +#define CS35L41_CH_WKFET_DLY_SHIFT 2 +#define CS35L41_CH_WKFET_THLD_MASK 0x0F00 +#define CS35L41_CH_WKFET_THLD_SHIFT 8 + +#define CS35L41_NG_ENABLE_MASK 0x00010000 +#define CS35L41_NG_ENABLE_SHIFT 16 +#define CS35L41_NG_THLD_MASK 0x7 +#define CS35L41_NG_THLD_SHIFT 0 +#define CS35L41_NG_DELAY_MASK 0x0F00 +#define CS35L41_NG_DELAY_SHIFT 8 + +#define CS35L41_ASP_FMT_MASK 0x0700 +#define CS35L41_ASP_FMT_SHIFT 8 +#define CS35L41_ASP_DOUT_HIZ_MASK 0x03 +#define CS35L41_ASP_DOUT_HIZ_SHIFT 0 +#define CS35L41_ASP_WIDTH_16 0x10 +#define CS35L41_ASP_WIDTH_24 0x18 +#define CS35L41_ASP_WIDTH_32 0x20 +#define CS35L41_ASP_WIDTH_TX_MASK 0xFF0000 +#define CS35L41_ASP_WIDTH_TX_SHIFT 16 +#define CS35L41_ASP_WIDTH_RX_MASK 0xFF000000 +#define CS35L41_ASP_WIDTH_RX_SHIFT 24 +#define CS35L41_ASP_RX1_SLOT_MASK 0x3F +#define CS35L41_ASP_RX1_SLOT_SHIFT 0 +#define CS35L41_ASP_RX2_SLOT_MASK 0x3F00 +#define CS35L41_ASP_RX2_SLOT_SHIFT 8 +#define CS35L41_ASP_RX_WL_MASK 0x3F +#define CS35L41_ASP_TX_WL_MASK 0x3F +#define CS35L41_ASP_RX_WL_SHIFT 0 +#define CS35L41_ASP_TX_WL_SHIFT 0 +#define CS35L41_ASP_SOURCE_MASK 0x7F + +#define CS35L41_INPUT_SRC_ASPRX1 0x08 +#define CS35L41_INPUT_SRC_ASPRX2 0x09 +#define CS35L41_INPUT_SRC_VMON 0x18 +#define CS35L41_INPUT_SRC_IMON 0x19 +#define CS35L41_INPUT_SRC_CLASSH 0x21 +#define CS35L41_INPUT_SRC_VPMON 0x28 +#define CS35L41_INPUT_SRC_VBSTMON 0x29 +#define CS35L41_INPUT_SRC_TEMPMON 0x3A +#define CS35L41_INPUT_SRC_RSVD 0x3B +#define CS35L41_INPUT_DSP_TX1 0x32 +#define CS35L41_INPUT_DSP_TX2 0x33 + +#define CS35L41_PLL_CLK_SEL_MASK 0x07 +#define CS35L41_PLL_CLK_SEL_SHIFT 0 +#define CS35L41_PLL_CLK_EN_MASK 0x10 +#define CS35L41_PLL_CLK_EN_SHIFT 4 +#define CS35L41_PLL_OPENLOOP_MASK 0x0800 +#define CS35L41_PLL_OPENLOOP_SHIFT 11 +#define CS35L41_PLLSRC_SCLK 0 +#define CS35L41_PLLSRC_LRCLK 1 +#define CS35L41_PLLSRC_SELF 3 +#define CS35L41_PLLSRC_PDMCLK 4 +#define CS35L41_PLLSRC_MCLK 5 +#define CS35L41_PLLSRC_SWIRE 7 +#define CS35L41_REFCLK_FREQ_MASK 0x7E0 +#define CS35L41_REFCLK_FREQ_SHIFT 5 + +#define CS35L41_GLOBAL_FS_MASK 0x1F +#define CS35L41_GLOBAL_FS_SHIFT 0 + +#define CS35L41_GLOBAL_EN_MASK 0x01 +#define CS35L41_GLOBAL_EN_SHIFT 0 +#define CS35L41_BST_EN_MASK 0x0030 +#define CS35L41_BST_EN_SHIFT 4 +#define CS35L41_BST_EN_DEFAULT 0x2 + +#define CS35L41_PDN_DONE_MASK 0x00800000 +#define CS35L41_PDN_DONE_SHIFT 23 +#define CS35L41_PUP_DONE_MASK 0x01000000 +#define CS35L41_PUP_DONE_SHIFT 24 + +#define CS35L36_PUP_DONE_IRQ_UNMASK 0x5F +#define CS35L36_PUP_DONE_IRQ_MASK 0xBF + +#define CS35L41_AMP_SHORT_ERR 0x80000000 +#define CS35L41_BST_SHORT_ERR 0x0100 +#define CS35L41_TEMP_WARN 0x8000 +#define CS35L41_TEMP_ERR 0x00020000 +#define CS35L41_BST_OVP_ERR 0x40 +#define CS35L41_BST_DCM_UVP_ERR 0x80 +#define CS35L41_OTP_BOOT_DONE 0x02 +#define CS35L41_PLL_UNLOCK 0x10 +#define CS35L41_OTP_BOOT_ERR 0x80000000 + +#define CS35L41_AMP_SHORT_ERR_RLS 0x02 +#define CS35L41_BST_SHORT_ERR_RLS 0x04 +#define CS35L41_BST_OVP_ERR_RLS 0x08 +#define CS35L41_BST_UVP_ERR_RLS 0x10 +#define CS35L41_TEMP_WARN_ERR_RLS 0x20 +#define CS35L41_TEMP_ERR_RLS 0x40 + +#define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F +#define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF +#define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF + +#define CS35L41_GPIO_DIR_MASK 0x80000000 +#define CS35L41_GPIO1_CTRL_MASK 0x00030000 +#define CS35L41_GPIO1_CTRL_SHIFT 16 +#define CS35L41_GPIO2_CTRL_MASK 0x07000000 +#define CS35L41_GPIO2_CTRL_SHIFT 24 +#define CS35L41_GPIO_CTRL_ACTV_LO 4 +#define CS35L41_GPIO_CTRL_ACTV_HI 5 +#define CS35L41_GPIO_POL_MASK 0x1000 +#define CS35L41_GPIO_POL_SHIFT 12 + +#define CS35L41_CHIP_ID 0x35a40 +#define CS35L41R_CHIP_ID 0x35b40 +#define CS35L41_MTLREVID_MASK 0x0F +#define CS35L41_REVID_A0 0xA0 +#define CS35L41_REVID_B0 0xB0 + +#define CS35L41_DSP_N_RX_RATES 8 +#define CS35L41_DSP_N_TX_RATES 8 +#define CS35L41_HALO_CORE_RESET 0x00000200 + +#define CS35L41_SPI_MAX_FREQ_OTP 4000000 + +#define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) +#define CS35L41_TX_FORMATS \ + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +bool cs35l41_readable_reg(struct device *dev, unsigned int reg); +bool cs35l41_precious_reg(struct device *dev, unsigned int reg); +bool cs35l41_volatile_reg(struct device *dev, unsigned int reg); + +struct cs35l41_otp_packed_element_t { + u32 reg; + u8 shift; + u8 size; +}; + +struct cs35l41_otp_map_element_t { + u32 id; + u32 num_elements; + const struct cs35l41_otp_packed_element_t *map; + u32 bit_offset; + u32 word_offset; +}; + +extern const struct reg_default cs35l41_reg[CS35L41_MAX_CACHE_REG]; +extern const struct cs35l41_otp_map_element_t + cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS]; + +#define CS35L41_REGSTRIDE 4 +#define CS35L41_MBOXWAIT 100 + +#define CS35L41_DSP_VIRT1_MBOX_SHIFT 20 +#define CS35L41_DSP_VIRT2_MBOX_SHIFT 21 +#define CS35L41_CSPL_MBOX_STS CS35L41_DSP_MBOX_2 +/* Firmware update following reg */ +#define CS35L41_CSPL_MBOX_CMD_FW CS35L41_DSP_VIRT2_MBOX_1 +#define CS35L41_CSPL_MBOX_CMD_FW_SHIFT CS35L41_DSP_VIRT2_MBOX_SHIFT +/* Driver update following reg */ +#define CS35L41_CSPL_MBOX_CMD_DRV CS35L41_DSP_VIRT1_MBOX_1 +#define CS35L41_CSPL_MBOX_CMD_DRV_SHIFT CS35L41_DSP_VIRT1_MBOX_SHIFT + +enum cs35l41_cspl_mboxstate { + CSPL_MBOX_STS_RUNNING = 0, + CSPL_MBOX_STS_PAUSED = 1, + CSPL_MBOX_STS_RDY_FOR_REINIT = 2, +}; + +enum cs35l41_cspl_mboxcmd { + CSPL_MBOX_CMD_NONE = 0, + CSPL_MBOX_CMD_PAUSE = 1, + CSPL_MBOX_CMD_RESUME = 2, + CSPL_MBOX_CMD_REINIT = 3, + CSPL_MBOX_CMD_STOP_PRE_REINIT = 4, + CSPL_MBOX_CMD_UNKNOWN_CMD = -1, + CSPL_MBOX_CMD_INVALID_SEQUENCE = -2, +}; + +#endif /*__CS35L41_H__*/ diff --git a/techpack/audio/asoc/codecs/cs35l41/cs35l41.txt b/techpack/audio/asoc/codecs/cs35l41/cs35l41.txt new file mode 100755 index 000000000000..9ce49ac9ac68 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41/cs35l41.txt @@ -0,0 +1,184 @@ +CS35L41 Speaker Amplifier + +Required properties: + + - compatible : "cirrus,cs35l41" + "cirrus,cs35l40" + + - reg : the SPI chip select line for the device + + - VA-supply, VP-supply : power supplies for the device, + as covered in + Documentation/devicetree/bindings/regulator/regulator.txt. + +Optional properties: + - cirrus,sclk-force-output : Audio serial port SCLK force + output control. Forces the SCLK to continue to drive even + if no ASP_TXn channels are enabled. + + - cirrus,lrclk-force-output : Audio serial port LRCLK force + output control. Forces the LRCLK to continue to drive even + if no ASP_TXn channels are enabled. + + - cirrus,right-channel-amp : Boolean to determine which channel + the amplifier is to receive the audio data on. If present the + amplifier receives data on the right channel of I2S data. + If not present the amplifier receives data on the left + channel of I2S data + + - cirrus,boost-ctl-millivolt : Boost Voltage Value. Configures the + boost converter's output voltage in mV. The range is from 2550 mV to + 11000 mV with increments of 50 mV. + (Default) VP + + Boost hardware configuration: + + These three properties should be used together to specify the external + component configuration of the part. See section 4.3.6 of the datasheet + for details regarding how these values are used to configure the + digital boost converter's control loop. + + - cirrus,boost-peak-milliamp : Boost-converter peak current limit in mA. + Configures the peak current by monitoring the current through the boost FET. + Range starts at 1600 mA and goes to a maximum of 4500 mA with increments + of 50 mA. + (Default) 4.50 Amps + + - cirrus,boost-ind-nanohenry : Boost inductor value, expressed in nH. Valid + values include 1000, 1200, 1500 and 2200. + + - cirrus,boost-cap-microfarad : Total equivalent boost capacitance on the VBST + and VAMP pins, derated at 11 volts DC. The value must be rounded to the + nearest integer and expressed in uF. + + - cirrus,amp-gain-zc : Boolean to determine whether to use the amplifier + gain-change zero-crossing feature. If the feature is enabled, any + user-controlled amplifier gain change will occur on a zero-crossing point. + (Default) Disabled + + - cirrus,temp-warn-threshold : Amplifier overtemperature warning threshold. + Configures the threshold at which the overtemperature warning condition occurs. + When the threshold is met, the ovetemperature warning attenuation is applied + and the TEMP_WARN_EINT interrupt status bit is set. + If TEMP_WARN_MASK = 0, INTb is asserted. + + 0 = 105C + 1 = 115C + 2 = 125C (Default) + 3 = 135C + + - cirrus,noise-gate-enable : DSP Noise Gate feature. If present, noise + gate feature will be enabled. + + - cirrus,noise-gate-threshold : Threshold of audio signal input which the + noise gate considers the input audio to be at a low enough level to be + valid to enter a noise gating state of operation. + + 0 = -66 dBFS + 1 = -72 dBFS + 2 = -78 dBFS + 3 = -84 dBFS (default) + 4 = -90 dBFS + 5 = -96 dBFS + 6 = -102 dBFS + 7 = -108 dBFS + + - cirrus,noise-gate-delay : Time that the incoming audio signal must be + below the noise gate threshold prior to entering a noise gated state + + 0 = 5 ms + 1 = 10 ms + 2 = 25 ms + 3 = 50 ms (default) + 4 = 100 ms + 5 = 250 ms + 6 = 500 ms + 7 = 1 s + 8 = 5 s + 9 = 10 s + 10 = 20 s + 11 = 30 s + 12 = 40 s + 13 = 50 s + 14 = 60 s + 15 = 120 s + +Optional H/G Algorithm sub-node: + + The cs35l41 node can have a single "cirrus,classh-internal-algo" sub-node + that will disable automatic control of the internal H/G Algorithm. + + It is strongly recommended that the Datasheet be referenced when adjusting + or using these Class H Algorithm controls over the internal Algorithm. + Serious damage can occur to the Device and surrounding components. + + - cirrus,classh-internal-algo : Sub-node for the Internal Class H Algorithm + See Section 4.4 Internal Class H Algorithm in the Datasheet. + If not used, the device manages the ClassH Algorithm internally. + +Optional properties for the "cirrus,classh-internal-algo" Sub-node + + Section 7.9 Boost Control + - cirrus,classh-bst-overide : Boolean + - cirrus,classh-bst-max-limit + + Section 7.17 Class H, Weak-FET Control + - cirrus,classh-headroom + - cirrus,classh-release-rate + - cirrus,classh-mem-depth + - cirrus,classh-wk-fet-delay + - cirrus,classh-wk-fet-thld + + +Optional GPIO1 sub-node: + +The cs35l41 node can have an single "cirrus,gpio-config1" sub-node for +configuring the GPIO1 pin. + +- cirrus,gpio-polarity-invert : Boolean which specifies whether the GPIO1 +level is inverted. If this property is not present the level is not inverted. + +- cirrus,gpio-output-enable : Boolean which specifies whether the GPIO1 pin +is configured as an output. If this property is not present the +pin will be configured as an input. + +- cirrus,gpio-src-select : Configures the function of the GPIO1 pin. +Note that the options are different from the GPIO2 pin. + +0 = High Impedance (Default) +1 = GPIO +2 = Sync +3 = MCLK input + + +Optional GPIO2 sub-node: + +The cs35l41 node can have an single "cirrus,gpio-config2" sub-node for +configuring the GPIO1 pin. + +- cirrus,gpio-polarity-invert : Boolean which specifies whether the GPIO2 +level is inverted. If this property is not present the level is not inverted. + +- cirrus,gpio-output-enable : Boolean which specifies whether the GPIO2 pin +is configured as an output. If this property is not present the +pin will be configured as an input. + +- cirrus,gpio-src-select : Configures the function of the GPIO2 pin. +Note that the options are different from the GPIO1 pin. + +0 = High Impedance (Default) +1 = GPIO +2 = Open Drain INTB +3 = MCLK input +4 = Push-pull INTB (active low) +5 = Push-pull INT (active high) + + +Example: + +cs35l41: cs35l41@2 { + compatible = "cirrus,cs35l41"; + reg = <2>; + VA-supply = <&dummy_vreg>; + VP-supply = <&dummy_vreg>; +}; diff --git a/techpack/audio/asoc/codecs/cs35l41/wm_adsp.c b/techpack/audio/asoc/codecs/cs35l41/wm_adsp.c new file mode 100644 index 000000000000..adc22ca13d92 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41/wm_adsp.c @@ -0,0 +1,5106 @@ +/* + * wm_adsp.c -- Wolfson ADSP support + * + * Copyright 2012 Wolfson Microelectronics plc + * Copyright (C) 2019 XiaoMi, Inc. + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#define DEBUG +//#define WM_ADSP_DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm_adsp.h" + +#define adsp_crit(_dsp, fmt, ...) \ + dev_crit(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) +#define adsp_err(_dsp, fmt, ...) \ + dev_err(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) +#define adsp_warn(_dsp, fmt, ...) \ + dev_warn(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) +#define adsp_info(_dsp, fmt, ...) \ + dev_info(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) +#define adsp_dbg(_dsp, fmt, ...) \ + dev_info(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) + +#define MAXBULK 4 /* Max byte I2C bulk limit */ + +#define ADSP1_CONTROL_1 0x00 +#define ADSP1_CONTROL_2 0x02 +#define ADSP1_CONTROL_3 0x03 +#define ADSP1_CONTROL_4 0x04 +#define ADSP1_CONTROL_5 0x06 +#define ADSP1_CONTROL_6 0x07 +#define ADSP1_CONTROL_7 0x08 +#define ADSP1_CONTROL_8 0x09 +#define ADSP1_CONTROL_9 0x0A +#define ADSP1_CONTROL_10 0x0B +#define ADSP1_CONTROL_11 0x0C +#define ADSP1_CONTROL_12 0x0D +#define ADSP1_CONTROL_13 0x0F +#define ADSP1_CONTROL_14 0x10 +#define ADSP1_CONTROL_15 0x11 +#define ADSP1_CONTROL_16 0x12 +#define ADSP1_CONTROL_17 0x13 +#define ADSP1_CONTROL_18 0x14 +#define ADSP1_CONTROL_19 0x16 +#define ADSP1_CONTROL_20 0x17 +#define ADSP1_CONTROL_21 0x18 +#define ADSP1_CONTROL_22 0x1A +#define ADSP1_CONTROL_23 0x1B +#define ADSP1_CONTROL_24 0x1C +#define ADSP1_CONTROL_25 0x1E +#define ADSP1_CONTROL_26 0x20 +#define ADSP1_CONTROL_27 0x21 +#define ADSP1_CONTROL_28 0x22 +#define ADSP1_CONTROL_29 0x23 +#define ADSP1_CONTROL_30 0x24 +#define ADSP1_CONTROL_31 0x26 + +/* + * ADSP1 Control 19 + */ +#define ADSP1_WDMA_BUFFER_LENGTH_MASK \ + 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ +#define ADSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ +#define ADSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ + +/* + * ADSP1 Control 30 + */ +#define ADSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ +#define ADSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ +#define ADSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ +#define ADSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ +#define ADSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ +#define ADSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ +#define ADSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ +#define ADSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ +#define ADSP1_START 0x0001 /* DSP1_START */ +#define ADSP1_START_MASK 0x0001 /* DSP1_START */ +#define ADSP1_START_SHIFT 0 /* DSP1_START */ +#define ADSP1_START_WIDTH 1 /* DSP1_START */ + +/* + * ADSP1 Control 31 + */ +#define ADSP1_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ +#define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ +#define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ + +#define ADSP2_CONTROL 0x0 +#define ADSP2_CLOCKING 0x1 +#define ADSP2V2_CLOCKING 0x2 +#define ADSP2_STATUS1 0x4 +#define ADSP2_WDMA_CONFIG_1 0x30 +#define ADSP2_WDMA_CONFIG_2 0x31 +#define ADSP2V2_WDMA_CONFIG_2 0x32 +#define ADSP2_RDMA_CONFIG_1 0x34 + +#define ADSP2_SCRATCH0 0x40 +#define ADSP2_SCRATCH1 0x41 +#define ADSP2_SCRATCH2 0x42 +#define ADSP2_SCRATCH3 0x43 + +#define ADSP2V2_SCRATCH0_1 0x40 +#define ADSP2V2_SCRATCH2_3 0x42 + +/* + * ADSP2 Control + */ + +#define ADSP2_MEM_ENA 0x0010 /* DSP1_MEM_ENA */ +#define ADSP2_MEM_ENA_MASK 0x0010 /* DSP1_MEM_ENA */ +#define ADSP2_MEM_ENA_SHIFT 4 /* DSP1_MEM_ENA */ +#define ADSP2_MEM_ENA_WIDTH 1 /* DSP1_MEM_ENA */ +#define ADSP2_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ +#define ADSP2_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ +#define ADSP2_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ +#define ADSP2_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ +#define ADSP2_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ +#define ADSP2_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ +#define ADSP2_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ +#define ADSP2_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ +#define ADSP2_START 0x0001 /* DSP1_START */ +#define ADSP2_START_MASK 0x0001 /* DSP1_START */ +#define ADSP2_START_SHIFT 0 /* DSP1_START */ +#define ADSP2_START_WIDTH 1 /* DSP1_START */ + +/* + * ADSP2 clocking + */ +#define ADSP2_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ +#define ADSP2_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ +#define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ + +/* + * ADSP2V2 clocking + */ +#define ADSP2V2_CLK_SEL_MASK 0x70000 /* CLK_SEL_ENA */ +#define ADSP2V2_CLK_SEL_SHIFT 16 /* CLK_SEL_ENA */ +#define ADSP2V2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ + +#define ADSP2V2_RATE_MASK 0x7800 /* DSP_RATE */ +#define ADSP2V2_RATE_SHIFT 11 /* DSP_RATE */ +#define ADSP2V2_RATE_WIDTH 4 /* DSP_RATE */ + +/* + * ADSP2 Status 1 + */ +#define ADSP2_RAM_RDY 0x0001 +#define ADSP2_RAM_RDY_MASK 0x0001 +#define ADSP2_RAM_RDY_SHIFT 0 +#define ADSP2_RAM_RDY_WIDTH 1 + +/* + * ADSP2 Lock support + */ +#define ADSP2_LOCK_CODE_0 0x5555 +#define ADSP2_LOCK_CODE_1 0xAAAA + +#define ADSP2_WATCHDOG 0x0A +#define ADSP2_BUS_ERR_ADDR 0x52 +#define ADSP2_REGION_LOCK_STATUS 0x64 +#define ADSP2_LOCK_REGION_1_LOCK_REGION_0 0x66 +#define ADSP2_LOCK_REGION_3_LOCK_REGION_2 0x68 +#define ADSP2_LOCK_REGION_5_LOCK_REGION_4 0x6A +#define ADSP2_LOCK_REGION_7_LOCK_REGION_6 0x6C +#define ADSP2_LOCK_REGION_9_LOCK_REGION_8 0x6E +#define ADSP2_LOCK_REGION_CTRL 0x7A +#define ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR 0x7C + +#define ADSP2_REGION_LOCK_ERR_MASK 0x8000 +#define ADSP2_SLAVE_ERR_MASK 0x4000 +#define ADSP2_WDT_TIMEOUT_STS_MASK 0x2000 +#define ADSP2_CTRL_ERR_PAUSE_ENA 0x0002 +#define ADSP2_CTRL_ERR_EINT 0x0001 + +#define ADSP2_BUS_ERR_ADDR_MASK 0x00FFFFFF +#define ADSP2_XMEM_ERR_ADDR_MASK 0x0000FFFF +#define ADSP2_PMEM_ERR_ADDR_MASK 0x7FFF0000 +#define ADSP2_PMEM_ERR_ADDR_SHIFT 16 +#define ADSP2_WDT_ENA_MASK 0xFFFFFFFD + +#define ADSP2_LOCK_REGION_SHIFT 16 + +#define ADSP_MAX_STD_CTRL_SIZE 512 + +#define WM_ADSP_ACKED_CTL_TIMEOUT_MS 100 +#define WM_ADSP_ACKED_CTL_N_QUICKPOLLS 10 +#define WM_ADSP_ACKED_CTL_MIN_VALUE 0 +#define WM_ADSP_ACKED_CTL_MAX_VALUE 0xFFFFFF + +/* + * Event control messages + */ +#define WM_ADSP_FW_EVENT_SHUTDOWN 0x000001 + +/* + * HALO system info + */ +#define HALO_SYS_INFO_XM_SRAM_SIZE 0x00010 +#define HALO_SYS_INFO_YM_SRAM_SIZE 0x00018 +#define HALO_SYS_INFO_XM_BANK_SIZE 0x00038 +#define HALO_SYS_INFO_YM_BANK_SIZE 0x0003c +#define HALO_AHBM_WINDOW_DEBUG_0 0x02040 +#define HALO_AHBM_WINDOW_DEBUG_1 0x02044 + +/* + * HALO core + */ +#define HALO_SAMPLE_RATE_RX1 0x00080 +#define HALO_SAMPLE_RATE_TX1 0x00280 +#define HALO_SCRATCH1 0x005c0 +#define HALO_CCM_CORE_CONTROL 0x41000 + +/* + * HALO Lock support + */ +#define HALO_MPU_UNLOCK_CODE_0 0x5555 +#define HALO_MPU_UNLOCK_CODE_1 0xaaaa + +/* + * HALO MPU banks + */ +#define HALO_MPU_XMEM_ACCESS_0 0x43000 +#define HALO_MPU_YMEM_ACCESS_0 0x43004 +#define HALO_MPU_WINDOW_ACCESS_0 0x43008 +#define HALO_MPU_XREG_ACCESS_0 0x4300C +#define HALO_MPU_YREG_ACCESS_0 0x43014 +#define HALO_MPU_XMEM_ACCESS_1 0x43018 +#define HALO_MPU_YMEM_ACCESS_1 0x4301C +#define HALO_MPU_WINDOW_ACCESS_1 0x43020 +#define HALO_MPU_XREG_ACCESS_1 0x43024 +#define HALO_MPU_YREG_ACCESS_1 0x4302C +#define HALO_MPU_XMEM_ACCESS_2 0x43030 +#define HALO_MPU_YMEM_ACCESS_2 0x43034 +#define HALO_MPU_WINDOW_ACCESS_2 0x43038 +#define HALO_MPU_XREG_ACCESS_2 0x4303C +#define HALO_MPU_YREG_ACCESS_2 0x43044 +#define HALO_MPU_XMEM_ACCESS_3 0x43048 +#define HALO_MPU_YMEM_ACCESS_3 0x4304C +#define HALO_MPU_WINDOW_ACCESS_3 0x43050 +#define HALO_MPU_XREG_ACCESS_3 0x43054 +#define HALO_MPU_YREG_ACCESS_3 0x4305C +#define HALO_MPU_XM_VIO_ADDR 0x43100 +#define HALO_MPU_XM_VIO_STATUS 0x43104 +#define HALO_MPU_YM_VIO_ADDR 0x43108 +#define HALO_MPU_YM_VIO_STATUS 0x4310C +#define HALO_MPU_PM_VIO_ADDR 0x43110 +#define HALO_MPU_PM_VIO_STATUS 0x43114 +#define HALO_MPU_LOCK_CONFIG 0x43140 + +/* + * HALO stream arb + */ +#define HALO_STREAM_ARB_MSTR0_CONFIG_0 0x45000 +#define HALO_STREAM_ARB_MSTR0_CONFIG_1 0x45004 +#define HALO_STREAM_ARB_MSTR0_CONFIG_2 0x45008 +#define HALO_STREAM_ARB_MSTR1_CONFIG_0 0x45010 +#define HALO_STREAM_ARB_MSTR1_CONFIG_1 0x45014 +#define HALO_STREAM_ARB_MSTR1_CONFIG_2 0x45018 +#define HALO_STREAM_ARB_MSTR2_CONFIG_0 0x45020 +#define HALO_STREAM_ARB_MSTR2_CONFIG_1 0x45024 +#define HALO_STREAM_ARB_MSTR2_CONFIG_2 0x45028 +#define HALO_STREAM_ARB_MSTR3_CONFIG_0 0x45030 +#define HALO_STREAM_ARB_MSTR3_CONFIG_1 0x45034 +#define HALO_STREAM_ARB_MSTR3_CONFIG_2 0x45038 +#define HALO_STREAM_ARB_MSTR4_CONFIG_0 0x45040 +#define HALO_STREAM_ARB_MSTR4_CONFIG_1 0x45044 +#define HALO_STREAM_ARB_MSTR4_CONFIG_2 0x45048 +#define HALO_STREAM_ARB_MSTR5_CONFIG_0 0x45050 +#define HALO_STREAM_ARB_MSTR5_CONFIG_1 0x45054 +#define HALO_STREAM_ARB_MSTR5_CONFIG_2 0x45058 + +#define HALO_STREAM_ARB_TX1_CONFIG_0 0x45200 +#define HALO_STREAM_ARB_TX1_CONFIG_1 0x45204 +#define HALO_STREAM_ARB_TX2_CONFIG_0 0x45208 +#define HALO_STREAM_ARB_TX2_CONFIG_1 0x4520C +#define HALO_STREAM_ARB_TX3_CONFIG_0 0x45210 +#define HALO_STREAM_ARB_TX3_CONFIG_1 0x45214 +#define HALO_STREAM_ARB_TX4_CONFIG_0 0x45218 +#define HALO_STREAM_ARB_TX4_CONFIG_1 0x4521C +#define HALO_STREAM_ARB_TX5_CONFIG_0 0x45220 +#define HALO_STREAM_ARB_TX5_CONFIG_1 0x45224 +#define HALO_STREAM_ARB_TX6_CONFIG_0 0x45228 +#define HALO_STREAM_ARB_TX6_CONFIG_1 0x4522C +#define HALO_STREAM_ARB_TX7_CONFIG_0 0x45230 +#define HALO_STREAM_ARB_TX7_CONFIG_1 0x45234 +#define HALO_STREAM_ARB_TX8_CONFIG_0 0x45238 +#define HALO_STREAM_ARB_TX8_CONFIG_1 0x4523C +#define HALO_STREAM_ARB_RX1_CONFIG_0 0x45400 +#define HALO_STREAM_ARB_RX1_CONFIG_1 0x45404 +#define HALO_STREAM_ARB_RX2_CONFIG_0 0x45408 +#define HALO_STREAM_ARB_RX2_CONFIG_1 0x4540C +#define HALO_STREAM_ARB_RX3_CONFIG_0 0x45410 +#define HALO_STREAM_ARB_RX3_CONFIG_1 0x45414 +#define HALO_STREAM_ARB_RX4_CONFIG_0 0x45418 +#define HALO_STREAM_ARB_RX4_CONFIG_1 0x4541C +#define HALO_STREAM_ARB_RX5_CONFIG_0 0x45420 +#define HALO_STREAM_ARB_RX5_CONFIG_1 0x45424 +#define HALO_STREAM_ARB_RX6_CONFIG_0 0x45428 +#define HALO_STREAM_ARB_RX6_CONFIG_1 0x4542C +#define HALO_STREAM_ARB_RX7_CONFIG_0 0x45430 +#define HALO_STREAM_ARB_RX7_CONFIG_1 0x45434 +#define HALO_STREAM_ARB_RX8_CONFIG_0 0x45438 +#define HALO_STREAM_ARB_RX8_CONFIG_1 0x4543C + +#define HALO_STREAM_ARB_IRQ0_CONFIG_0 0x45600 +#define HALO_STREAM_ARB_IRQ0_CONFIG_1 0x45604 +#define HALO_STREAM_ARB_IRQ0_CONFIG_2 0x45608 +#define HALO_STREAM_ARB_IRQ1_CONFIG_0 0x45610 +#define HALO_STREAM_ARB_IRQ1_CONFIG_1 0x45614 +#define HALO_STREAM_ARB_IRQ1_CONFIG_2 0x45618 +#define HALO_STREAM_ARB_IRQ2_CONFIG_0 0x45620 +#define HALO_STREAM_ARB_IRQ2_CONFIG_1 0x45624 +#define HALO_STREAM_ARB_IRQ2_CONFIG_2 0x45628 +#define HALO_STREAM_ARB_IRQ3_CONFIG_0 0x45630 +#define HALO_STREAM_ARB_IRQ3_CONFIG_1 0x45634 +#define HALO_STREAM_ARB_IRQ3_CONFIG_2 0x45638 +#define HALO_STREAM_ARB_IRQ4_CONFIG_0 0x45640 +#define HALO_STREAM_ARB_IRQ4_CONFIG_1 0x45644 +#define HALO_STREAM_ARB_IRQ4_CONFIG_2 0x45648 +#define HALO_STREAM_ARB_IRQ5_CONFIG_0 0x45650 +#define HALO_STREAM_ARB_IRQ5_CONFIG_1 0x45654 +#define HALO_STREAM_ARB_IRQ5_CONFIG_2 0x45658 +#define HALO_STREAM_ARB_IRQ6_CONFIG_0 0x45660 +#define HALO_STREAM_ARB_IRQ6_CONFIG_1 0x45664 +#define HALO_STREAM_ARB_IRQ6_CONFIG_2 0x45668 +#define HALO_STREAM_ARB_IRQ7_CONFIG_0 0x45670 +#define HALO_STREAM_ARB_IRQ7_CONFIG_1 0x45674 +#define HALO_STREAM_ARB_IRQ7_CONFIG_2 0x45678 + +#define HALO_INTP_CTL_NMI_CONTROL 0x46008 + +/* + * HALO_AHBM_WINDOW_DEBUG_1 + */ +#define HALO_AHBM_CORE_ERR_ADDR_MASK 0x0fffff00 +#define HALO_AHBM_CORE_ERR_ADDR_SHIFT 8 +#define HALO_AHBM_ADDR_ERR_MASK 0x00000080 +#define HALO_AHBM_LOCKED_ERR_MASK 0x00000040 +#define HALO_AHBM_SIZE_ERR_MASK 0x00000020 +#define HALO_AHBM_MODE_ERR_MASK 0x00000010 +#define HALO_AHBM_AHB_ERR_MASK 0x00000001 + +/* + * HALO_SAMPLE_RATE_[RX|TX]n + */ +#define HALO_DSP_RATE_SHIFT 0 +#define HALO_DSP_RATE_MASK 0x1f + +/* + * HALO_CCM_CORE_CONTROL + */ +#define HALO_CORE_EN 0x00000001 +#define HALO_CORE_EN_MASK 0x00000001 +#define HALO_CORE_EN_SHIFT 0 +#define HALO_CORE_EN_WIDTH 1 +#define HALO_CORE_RESET 0x00000200 + +/* + * HALO_MPU_?M_VIO_STATUS + */ +#define HALO_MPU_VIO_STS_MASK 0x007e0000 +#define HALO_MPU_VIO_STS_SHIFT 17 +#define HALO_MPU_VIO_ERR_MASK 0x00010000 +#define HALO_MPU_VIO_ERR_SHIFT 16 +#define HALO_MPU_VIO_ERR_WR_MASK 0x00008000 +#define HALO_MPU_VIO_ERR_WR_SHIFT 15 +#define HALO_MPU_VIO_ERR_SRC_MASK 0x00007fff +#define HALO_MPU_VIO_ERR_SRC_SHIFT 0 + +#define HALO_MPU_VIO_SRAM 0x01 +#define HALO_MPU_VIO_REG 0x02 +#define HALO_MPU_VIO_AHB 0x04 +#define HALO_MPU_VIO_EREG 0x08 +#define HALO_MPU_VIO_EXTERNAL_MEM 0x10 +#define HALO_MPU_VIO_NON_EXIST 0x20 + +/* + * HALO_STREAM_ARB_MSTRn_CONFIG_0 + */ +#define HALO_STREAM_ARB_MSTR_EN_MASK 0x1 + +/* + * HALO_STREAM_ARB_[TX|RX]n_CONFIG_0 + * HALO_STREAM_ARB_IRQn_CONFIG_0 + */ +#define HALO_STREAM_ARB_MSTR_SEL_DEFAULT 0xfc + +static const unsigned int halo_mpu_access[18] = { + HALO_MPU_WINDOW_ACCESS_0, HALO_MPU_XREG_ACCESS_0, + HALO_MPU_YREG_ACCESS_0, HALO_MPU_XMEM_ACCESS_1, + HALO_MPU_YMEM_ACCESS_1, HALO_MPU_WINDOW_ACCESS_1, + HALO_MPU_XREG_ACCESS_1, HALO_MPU_YREG_ACCESS_1, + HALO_MPU_XMEM_ACCESS_2, HALO_MPU_YMEM_ACCESS_2, + HALO_MPU_WINDOW_ACCESS_2, HALO_MPU_XREG_ACCESS_2, + HALO_MPU_YREG_ACCESS_2, HALO_MPU_XMEM_ACCESS_3, + HALO_MPU_YMEM_ACCESS_3, HALO_MPU_WINDOW_ACCESS_3, + HALO_MPU_XREG_ACCESS_3, HALO_MPU_YREG_ACCESS_3, +}; + +struct wm_adsp_buf { + struct list_head list; + void *buf; +}; + +static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len, + struct list_head *list) +{ + struct wm_adsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); + + if (buf == NULL) + return NULL; + + buf->buf = kmemdup(src, len, GFP_KERNEL | GFP_DMA); + if (!buf->buf) { + kfree(buf); + return NULL; + } + memcpy(buf->buf, src, len); + + if (list) + list_add_tail(&buf->list, list); + + return buf; +} + +static void wm_adsp_buf_free(struct list_head *list) +{ + while (!list_empty(list)) { + struct wm_adsp_buf *buf = + list_first_entry(list, struct wm_adsp_buf, list); + list_del(&buf->list); + kfree(buf->buf); + kfree(buf); + } +} + +#define WM_ADSP_FW_MBC_VSS 0 +#define WM_ADSP_FW_HIFI 1 +#define WM_ADSP_FW_TX 2 +#define WM_ADSP_FW_TX_SPK 3 +#define WM_ADSP_FW_RX 4 +#define WM_ADSP_FW_RX_ANC 5 +#define WM_ADSP_FW_CTRL 6 +#define WM_ADSP_FW_ASR 7 +#define WM_ADSP_FW_TRACE 8 +#define WM_ADSP_FW_SPK_PROT 9 +#define WM_ADSP_FW_DIAG 10 +#define WM_ADSP_FW_CALIB 11 + +#define WM_ADSP_NUM_FW 12 + +#define AMBIENT_DEFAULT 30 +#define CAL_R_DEFAULT 8392 +#define CAL_STATUS_DEFAULT 1 + +static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = { + [WM_ADSP_FW_MBC_VSS] = "MBC/VSS", [WM_ADSP_FW_HIFI] = "MasterHiFi", + [WM_ADSP_FW_TX] = "Tx", [WM_ADSP_FW_TX_SPK] = "Tx Speaker", + [WM_ADSP_FW_RX] = "Rx", [WM_ADSP_FW_RX_ANC] = "Rx ANC", + [WM_ADSP_FW_CTRL] = "Voice Ctrl", [WM_ADSP_FW_ASR] = "ASR Assist", + [WM_ADSP_FW_TRACE] = "Dbg Trace", [WM_ADSP_FW_SPK_PROT] = "Protection", + [WM_ADSP_FW_DIAG] = "Diag", [WM_ADSP_FW_CALIB] = "Diag Z", +}; + +struct wm_adsp_system_config_xm_hdr { + __be32 sys_enable; + __be32 fw_id; + __be32 fw_rev; + __be32 boot_status; + __be32 watchdog; + __be32 dma_buffer_size; + __be32 rdma[6]; + __be32 wdma[8]; + __be32 build_job_name[3]; + __be32 build_job_number; +}; + +struct wm_adsp_alg_xm_struct { + __be32 magic; + __be32 smoothing; + __be32 threshold; + __be32 host_buf_ptr; + __be32 start_seq; + __be32 high_water_mark; + __be32 low_water_mark; + __be64 smoothed_power; +}; + +struct wm_adsp_buffer { + __be32 X_buf_base; /* XM base addr of first X area */ + __be32 X_buf_size; /* Size of 1st X area in words */ + __be32 X_buf_base2; /* XM base addr of 2nd X area */ + __be32 X_buf_brk; /* Total X size in words */ + __be32 Y_buf_base; /* YM base addr of Y area */ + __be32 wrap; /* Total size X and Y in words */ + __be32 high_water_mark; /* Point at which IRQ is asserted */ + __be32 irq_count; /* bits 1-31 count IRQ assertions */ + __be32 irq_ack; /* acked IRQ count, bit 0 enables IRQ */ + __be32 next_write_index; /* word index of next write */ + __be32 next_read_index; /* word index of next read */ + __be32 error; /* error if any */ + __be32 oldest_block_index; /* word index of oldest surviving */ + __be32 requested_rewind; /* how many blocks rewind was done */ + __be32 reserved_space; /* internal */ + __be32 min_free; /* min free space since stream start */ + __be32 blocks_written[2]; /* total blocks written (64 bit) */ + __be32 words_written[2]; /* total words written (64 bit) */ +}; + +struct wm_adsp_compr; + +struct wm_adsp_compr_buf { + struct wm_adsp *dsp; + struct wm_adsp_compr *compr; + + struct wm_adsp_buffer_region *regions; + u32 host_buf_ptr; + + u32 error; + u32 irq_count; + int read_index; + int avail; +}; + +struct wm_adsp_compr { + struct wm_adsp *dsp; + struct wm_adsp_compr_buf *buf; + + struct snd_compr_stream *stream; + struct snd_compressed_buffer size; + + u32 *raw_buf; + unsigned int copied_total; + + unsigned int sample_rate; +}; + +#define WM_ADSP_DATA_WORD_SIZE 3 + +#define WM_ADSP_MIN_FRAGMENTS 1 +#define WM_ADSP_MAX_FRAGMENTS 256 +#define WM_ADSP_MIN_FRAGMENT_SIZE (64 * WM_ADSP_DATA_WORD_SIZE) +#define WM_ADSP_MAX_FRAGMENT_SIZE (4096 * WM_ADSP_DATA_WORD_SIZE) + +#define WM_ADSP_ALG_XM_STRUCT_MAGIC 0x49aec7 + +#define HOST_BUFFER_FIELD(field) \ + (offsetof(struct wm_adsp_buffer, field) / sizeof(__be32)) + +#define ALG_XM_FIELD(field) \ + (offsetof(struct wm_adsp_alg_xm_struct, field) / sizeof(__be32)) + +static int wm_adsp_buffer_init(struct wm_adsp *dsp); +static int wm_adsp_buffer_free(struct wm_adsp *dsp); + +struct wm_adsp_buffer_region { + unsigned int offset; + unsigned int cumulative_size; + unsigned int mem_type; + unsigned int base_addr; +}; + +struct wm_adsp_buffer_region_def { + unsigned int mem_type; + unsigned int base_offset; + unsigned int size_offset; +}; + +static const struct wm_adsp_buffer_region_def default_regions[] = { + { + .mem_type = WMFW_ADSP2_XM, + .base_offset = HOST_BUFFER_FIELD(X_buf_base), + .size_offset = HOST_BUFFER_FIELD(X_buf_size), + }, + { + .mem_type = WMFW_ADSP2_XM, + .base_offset = HOST_BUFFER_FIELD(X_buf_base2), + .size_offset = HOST_BUFFER_FIELD(X_buf_brk), + }, + { + .mem_type = WMFW_ADSP2_YM, + .base_offset = HOST_BUFFER_FIELD(Y_buf_base), + .size_offset = HOST_BUFFER_FIELD(wrap), + }, +}; + +struct wm_adsp_fw_caps { + u32 id; + struct snd_codec_desc desc; + int num_regions; + const struct wm_adsp_buffer_region_def *region_defs; +}; + +static const struct wm_adsp_fw_caps ctrl_caps[] = { + { + .id = SND_AUDIOCODEC_BESPOKE, + .desc = { + .max_ch = 1, + .sample_rates = { 16000 }, + .num_sample_rates = 1, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .num_regions = ARRAY_SIZE(default_regions), + .region_defs = default_regions, + }, +}; + +static const struct wm_adsp_fw_caps trace_caps[] = { + { + .id = SND_AUDIOCODEC_BESPOKE, + .desc = { + .max_ch = 8, + .sample_rates = { + 4000, 8000, 11025, 12000, 16000, 22050, + 24000, 32000, 44100, 48000, 64000, 88200, + 96000, 176400, 192000 + }, + .num_sample_rates = 15, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .num_regions = ARRAY_SIZE(default_regions), + .region_defs = default_regions, + }, +}; + +static const struct { + const char *file; + int compr_direction; + int num_caps; + const struct wm_adsp_fw_caps *caps; + bool voice_trigger; +} wm_adsp_fw[WM_ADSP_NUM_FW] = { + [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" }, + [WM_ADSP_FW_HIFI] = { .file = "hifi" }, + [WM_ADSP_FW_TX] = { .file = "tx" }, + [WM_ADSP_FW_TX_SPK] = { .file = "tx-spk" }, + [WM_ADSP_FW_RX] = { .file = "rx" }, + [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" }, + [WM_ADSP_FW_CTRL] = { + .file = "ctrl", + .compr_direction = SND_COMPRESS_CAPTURE, + .num_caps = ARRAY_SIZE(ctrl_caps), + .caps = ctrl_caps, + .voice_trigger = true, + }, + [WM_ADSP_FW_ASR] = { .file = "asr" }, + [WM_ADSP_FW_TRACE] = { + .file = "trace", + .compr_direction = SND_COMPRESS_CAPTURE, + .num_caps = ARRAY_SIZE(trace_caps), + .caps = trace_caps, + }, + [WM_ADSP_FW_SPK_PROT] = { .file = "spk-prot" }, + [WM_ADSP_FW_DIAG] = { .file = "diag" }, + [WM_ADSP_FW_CALIB] = { .file = "diag-z" }, +}; + +struct wm_coeff_ctl_ops { + int (*xget)(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + int (*xput)(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +}; + +struct wm_coeff_ctl { + const char *name; + const char *fw_name; + struct wm_adsp_alg_region alg_region; + struct wm_coeff_ctl_ops ops; + struct wm_adsp *dsp; + unsigned int enabled : 1; + struct list_head list; + void *cache; + unsigned int offset; + size_t len; + unsigned int set : 1; + struct soc_bytes_ext bytes_ext; + unsigned int flags; + unsigned int type; +}; + +static const char *wm_adsp_mem_region_name(unsigned int type) +{ + switch (type) { + case WMFW_ADSP1_PM: + return "PM"; + case WMFW_HALO_PM_PACKED: + return "PM_PACKED"; + case WMFW_ADSP1_DM: + return "DM"; + case WMFW_ADSP2_XM: + return "XM"; + case WMFW_HALO_XM_PACKED: + return "XM_PACKED"; + case WMFW_ADSP2_YM: + return "YM"; + case WMFW_HALO_YM_PACKED: + return "YM_PACKED"; + case WMFW_ADSP1_ZM: + return "ZM"; + default: + return NULL; + } +} +static int wm_halo_apply_calibration(struct snd_soc_dapm_widget *w); +static int wm_adsp_k_ctl_put(struct wm_adsp *dsp, const char *name, int value); +static int wm_adsp_k_ctl_get(struct wm_adsp *dsp, const char *name); + +#ifdef CONFIG_DEBUG_FS +static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) +{ + char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); + + kfree(dsp->wmfw_file_name); + dsp->wmfw_file_name = tmp; +} + +static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) +{ + char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); + + kfree(dsp->bin_file_name); + dsp->bin_file_name = tmp; +} + +static void wm_adsp_debugfs_clear(struct wm_adsp *dsp) +{ + kfree(dsp->wmfw_file_name); + kfree(dsp->bin_file_name); + dsp->wmfw_file_name = NULL; + dsp->bin_file_name = NULL; +} + +static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + struct wm_adsp *dsp = file->private_data; + ssize_t ret; + + mutex_lock(&dsp->pwr_lock); + + if (!dsp->wmfw_file_name || !dsp->booted) + ret = 0; + else + ret = simple_read_from_buffer(user_buf, count, ppos, + dsp->wmfw_file_name, + strlen(dsp->wmfw_file_name)); + + mutex_unlock(&dsp->pwr_lock); + return ret; +} + +static ssize_t wm_adsp_debugfs_bin_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + struct wm_adsp *dsp = file->private_data; + ssize_t ret; + + mutex_lock(&dsp->pwr_lock); + + if (!dsp->bin_file_name || !dsp->booted) + ret = 0; + else + ret = simple_read_from_buffer(user_buf, count, ppos, + dsp->bin_file_name, + strlen(dsp->bin_file_name)); + + mutex_unlock(&dsp->pwr_lock); + return ret; +} + +static const struct { + const char *name; + const struct file_operations fops; +} wm_adsp_debugfs_fops[] = { + { + .name = "wmfw_file_name", + .fops = { + .open = simple_open, + .read = wm_adsp_debugfs_wmfw_read, + }, + }, + { + .name = "bin_file_name", + .fops = { + .open = simple_open, + .read = wm_adsp_debugfs_bin_read, + }, + }, +}; + +static void wm_adsp2_init_debugfs(struct wm_adsp *dsp, + struct snd_soc_codec *codec) +{ + struct dentry *root = NULL; + char *root_name; + int i; + + if (!codec->component.debugfs_root) { + adsp_err(dsp, "No codec debugfs root\n"); + goto err; + } + + root_name = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!root_name) + goto err; + + snprintf(root_name, PAGE_SIZE, "dsp%d", dsp->num); + root = debugfs_create_dir(root_name, codec->component.debugfs_root); + kfree(root_name); + + if (!root) + goto err; + + if (!debugfs_create_bool("booted", S_IRUGO, root, &dsp->booted)) + goto err; + + if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running)) + goto err; + + if (!debugfs_create_x32("fw_id", S_IRUGO, root, &dsp->fw_id)) + goto err; + + if (!debugfs_create_x32("fw_version", S_IRUGO, root, + &dsp->fw_id_version)) + goto err; + + for (i = 0; i < ARRAY_SIZE(wm_adsp_debugfs_fops); ++i) { + if (!debugfs_create_file(wm_adsp_debugfs_fops[i].name, S_IRUGO, + root, dsp, + &wm_adsp_debugfs_fops[i].fops)) + goto err; + } + + dsp->debugfs_root = root; + return; + +err: + debugfs_remove_recursive(root); + adsp_err(dsp, "Failed to create debugfs\n"); +} + +static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) +{ + wm_adsp_debugfs_clear(dsp); + debugfs_remove_recursive(dsp->debugfs_root); +} +#else +static inline void wm_adsp2_init_debugfs(struct wm_adsp *dsp, + struct snd_soc_codec *codec) +{ +} + +static inline void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) +{ +} + +static inline void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, + const char *s) +{ +} + +static inline void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, + const char *s) +{ +} + +static inline void wm_adsp_debugfs_clear(struct wm_adsp *dsp) +{ +} +#endif + +static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = dsp[e->shift_l].fw; + + return 0; +} + +static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + if (ucontrol->value.enumerated.item[0] == dsp[e->shift_l].fw) + return 0; + + if (ucontrol->value.enumerated.item[0] >= WM_ADSP_NUM_FW) + return -EINVAL; + + mutex_lock(&dsp[e->shift_l].pwr_lock); + + if (dsp[e->shift_l].booted || dsp[e->shift_l].compr) + ret = -EBUSY; + else + dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0]; + + mutex_unlock(&dsp[e->shift_l].pwr_lock); + + return ret; +} + +static int wm_adsp_cal_z_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = dsp->cal_z; + + return 0; +} + +static int wm_adsp_cal_z_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + dsp->cal_z = ucontrol->value.enumerated.item[0]; + dsp->cal_chksum = dsp->cal_z + CAL_STATUS_DEFAULT; + + dev_info(codec->dev, "cal_z = %d\n", dsp->cal_z); + + return 0; +} + +static int wm_adsp_ambient_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = dsp->ambient; + + return 0; +} + +static int wm_adsp_ambient_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + dsp->ambient = ucontrol->value.enumerated.item[0]; + + dev_info(codec->dev, "ambient = %d\n", dsp->ambient); + + return 0; +} + +static int wm_adsp_cal_status_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = dsp->cal_status; + + return 0; +} + +static int wm_adsp_cal_status_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + dsp->cal_status = ucontrol->value.enumerated.item[0]; + + dev_info(codec->dev, "cal_status = %d\n", dsp->cal_status); + + return 0; +} + +static int wm_adsp_cal_chksum_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = dsp->cal_chksum; + + return 0; +} + +static int wm_adsp_cal_chksum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + dsp->cal_chksum = ucontrol->value.enumerated.item[0]; + + dev_info(codec->dev, "cal_chksum = %d\n", dsp->cal_chksum); + + return 0; +} + +static int wm_adsp_block_bypass_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = dsp->block_bypass; + + return 0; +} + +static int wm_adsp_block_bypass_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + dsp->block_bypass = ucontrol->value.enumerated.item[0]; + + switch (dsp->block_bypass) { + case 0: + wm_adsp_k_ctl_put(dsp, "DSP1X Protection cd BYPASS_IN_ENH", + 0x00000000); + wm_adsp_k_ctl_put(dsp, "DSP1X Protection cd BYPASS_EQ", + 0x00000000); + wm_adsp_k_ctl_put(dsp, "DSP1X Protection cd BYPASS_ACTI", + 0x00000000); + wm_adsp_k_ctl_put(dsp, "DSP1X Protection cd BYPASS_MBL", + 0x00000000); + break; + case 1: + wm_adsp_k_ctl_put(dsp, "DSP1X Protection cd BYPASS_IN_ENH", + 0x00400001); + wm_adsp_k_ctl_put(dsp, "DSP1X Protection cd BYPASS_EQ", + 0x00400001); + wm_adsp_k_ctl_put(dsp, "DSP1X Protection cd BYPASS_ACTI", + 0x00400001); + wm_adsp_k_ctl_put(dsp, "DSP1X Protection cd BYPASS_MBL", + 0x00400001); + break; + default: + break; + } + + dev_info(codec->dev, "block_bypass = %d\n", dsp->block_bypass); + + return 0; +} + +static int wm_adsp_block_bypass_in_enh_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = dsp->block_bypass_in_enh; + + return 0; +} + +static int wm_adsp_block_bypass_in_enh_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + dsp->block_bypass_in_enh = ucontrol->value.enumerated.item[0]; + + switch (dsp->block_bypass_in_enh) { + case 0: + dev_info(codec->dev, + "block_bypass_in_enh = %d, put 0x00000000.\n", + dsp->block_bypass_in_enh); + wm_adsp_k_ctl_put(dsp, "DSP1X Protection cd BYPASS_IN_ENH", + 0x00000000); + break; + case 1: + dev_info(codec->dev, + "block_bypass_in_enh = %d, put 0x00400001.\n", + dsp->block_bypass_in_enh); + wm_adsp_k_ctl_put(dsp, "DSP1X Protection cd BYPASS_IN_ENH", + 0x00400001); + break; + default: + break; + } + + dev_info(codec->dev, "block_bypass_in_enh = %d\n", + dsp->block_bypass_in_enh); + + return 0; +} + +static const struct soc_enum wm_adsp_fw_enum[] = { + SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), + SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), + SOC_ENUM_SINGLE(0, 2, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), + SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), + SOC_ENUM_SINGLE(0, 4, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), + SOC_ENUM_SINGLE(0, 5, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), + SOC_ENUM_SINGLE(0, 6, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), +}; +static const char *wm_adsp_block_bypass_text[2] = { "Off", "On" }; +static const struct soc_enum wm_adsp_block_bypass_enum[] = { + SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(wm_adsp_block_bypass_text), + wm_adsp_block_bypass_text), +}; +const struct snd_kcontrol_new wm_adsp_fw_controls[] = { + SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], wm_adsp_fw_get, + wm_adsp_fw_put), + SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], wm_adsp_fw_get, + wm_adsp_fw_put), + SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], wm_adsp_fw_get, + wm_adsp_fw_put), + SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], wm_adsp_fw_get, + wm_adsp_fw_put), + SOC_ENUM_EXT("DSP5 Firmware", wm_adsp_fw_enum[4], wm_adsp_fw_get, + wm_adsp_fw_put), + SOC_ENUM_EXT("DSP6 Firmware", wm_adsp_fw_enum[5], wm_adsp_fw_get, + wm_adsp_fw_put), + SOC_ENUM_EXT("DSP7 Firmware", wm_adsp_fw_enum[6], wm_adsp_fw_get, + wm_adsp_fw_put), +}; + +const struct snd_kcontrol_new wm_adsp_cal_controls[] = { + /* In Halo DSP, values are 24-bit */ + SOC_SINGLE_EXT("DSP Set CAL_Z", SND_SOC_NOPM, 0, 0xFFFFFF, 0, + wm_adsp_cal_z_get, wm_adsp_cal_z_put), + SOC_SINGLE_EXT("DSP Set AMBIENT", SND_SOC_NOPM, 0, 0xFFFFFF, 0, + wm_adsp_ambient_get, wm_adsp_ambient_put), + SOC_SINGLE_EXT("DSP Set CAL_STATUS", SND_SOC_NOPM, 0, 0xFFFFFF, 0, + wm_adsp_cal_status_get, wm_adsp_cal_status_put), + SOC_SINGLE_EXT("DSP Set CAL_CHKSUM", SND_SOC_NOPM, 0, 0xFFFFFF, 0, + wm_adsp_cal_chksum_get, wm_adsp_cal_chksum_put), + SOC_ENUM_EXT("DSP Block Bypass", wm_adsp_block_bypass_enum[0], + wm_adsp_block_bypass_get, wm_adsp_block_bypass_put), + SOC_ENUM_EXT("DSP Block Bypass_IN_ENH", wm_adsp_block_bypass_enum[0], + wm_adsp_block_bypass_in_enh_get, + wm_adsp_block_bypass_in_enh_put), +}; +EXPORT_SYMBOL_GPL(wm_adsp_cal_controls); + +static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, + int type) +{ + int i; + + for (i = 0; i < dsp->num_mems; i++) + if (dsp->mem[i].type == type) + return &dsp->mem[i]; + + return NULL; +} + +static unsigned int wm_adsp_region_to_reg(struct wm_adsp *dsp, + struct wm_adsp_region const *mem, + unsigned int offset) +{ + if (WARN_ON(!mem)) + return offset; + switch (dsp->type) { + case WMFW_ADSP1: + case WMFW_ADSP2: + switch (mem->type) { + case WMFW_ADSP1_PM: + return mem->base + (offset * 3); + case WMFW_ADSP1_DM: + return mem->base + (offset * 2); + case WMFW_ADSP2_XM: + return mem->base + (offset * 2); + case WMFW_ADSP2_YM: + return mem->base + (offset * 2); + case WMFW_ADSP1_ZM: + return mem->base + (offset * 2); + default: + WARN(1, "Unknown memory region type"); + return offset; + } + case WMFW_HALO: + switch (mem->type) { + case WMFW_ADSP2_XM: + return mem->base + (offset * 4); + case WMFW_ADSP2_YM: + return mem->base + (offset * 4); + case WMFW_HALO_XM_PACKED: + return (mem->base + (offset * 3)) & ~0x3; + case WMFW_HALO_YM_PACKED: + return (mem->base + (offset * 3)) & ~0x3; + case WMFW_HALO_PM_PACKED: + return mem->base + (offset * 5); + default: + WARN(1, "Unknown memory region type"); + return offset; + } + default: + WARN(1, "Unknown DSP type"); + return offset; + } +} +static int wm_adsp2_raw_read(size_t maxbulk, struct regmap *map, + unsigned int reg, void *val, size_t len) +{ + int ret; + size_t read_len = 0; + size_t toread_len; + + while ((len - read_len) > 0) { + toread_len = + (len - read_len) > maxbulk ? maxbulk : (len - read_len); + ret = regmap_raw_read(map, reg + read_len, val + read_len, + toread_len); + if (ret < 0) { + printk("%s failed, toread_len:%u reg base:%u reg:%u read_len:%u\n", + __func__, toread_len, reg, reg + read_len, + read_len); + return ret; + } + read_len += toread_len; + } + + return 0; +} + +static void wm_adsp2_show_fw_status(struct wm_adsp *dsp) +{ + u16 scratch[4]; + int ret; + + ret = wm_adsp2_raw_read(MAXBULK, dsp->regmap, + dsp->base + ADSP2_SCRATCH0, scratch, + sizeof(scratch)); + if (ret) { + adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret); + return; + } + + adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", + be16_to_cpu(scratch[0]), be16_to_cpu(scratch[1]), + be16_to_cpu(scratch[2]), be16_to_cpu(scratch[3])); +} + +static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp) +{ + u32 scratch[2]; + int ret; + + ret = wm_adsp2_raw_read(MAXBULK, dsp->regmap, + dsp->base + ADSP2V2_SCRATCH0_1, scratch, + sizeof(scratch)); + + if (ret) { + adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret); + return; + } + + scratch[0] = be32_to_cpu(scratch[0]); + scratch[1] = be32_to_cpu(scratch[1]); + + adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", + scratch[0] & 0xFFFF, scratch[0] >> 16, scratch[1] & 0xFFFF, + scratch[1] >> 16); +} + +static void wm_halo_show_fw_status(struct wm_adsp *dsp) +{ + u32 scratch[4]; + int ret; + + ret = wm_adsp2_raw_read(MAXBULK, dsp->regmap, dsp->base + HALO_SCRATCH1, + scratch, sizeof(scratch)); + if (ret) { + adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret); + return; + } + + adsp_dbg(dsp, "FW SCRATCH 1:0x%x 2:0x%x 3:0x%x 4:0x%x\n", + be32_to_cpu(scratch[0]), be32_to_cpu(scratch[1]), + be32_to_cpu(scratch[2]), be32_to_cpu(scratch[3])); +} + +static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) +{ + return container_of(ext, struct wm_coeff_ctl, bytes_ext); +} + +static int wm_coeff_base_reg(struct wm_coeff_ctl *ctl, unsigned int *reg) +{ + const struct wm_adsp_alg_region *alg_region = &ctl->alg_region; + struct wm_adsp *dsp = ctl->dsp; + const struct wm_adsp_region *mem; + + mem = wm_adsp_find_region(dsp, alg_region->type); + if (!mem) { + adsp_err(dsp, "No base for region %x\n", alg_region->type); + return -EINVAL; + } + + *reg = wm_adsp_region_to_reg(dsp, mem, + ctl->alg_region.base + ctl->offset); + + return 0; +} + +static int wm_coeff_info(struct snd_kcontrol *kctl, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + + switch (ctl->type) { + case WMFW_CTL_TYPE_ACKED: + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->value.integer.min = WM_ADSP_ACKED_CTL_MIN_VALUE; + uinfo->value.integer.max = WM_ADSP_ACKED_CTL_MAX_VALUE; + uinfo->value.integer.step = 1; + uinfo->count = 1; + break; + default: + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = ctl->len; + break; + } + + return 0; +} + +static int wm_coeff_write_acked_control(struct wm_coeff_ctl *ctl, + unsigned int event_id) +{ + struct wm_adsp *dsp = ctl->dsp; + u32 val = cpu_to_be32(event_id); + unsigned int reg; + int i, ret; + + ret = wm_coeff_base_reg(ctl, ®); + if (ret) + return ret; + + adsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", + event_id, ctl->alg_region.alg, + wm_adsp_mem_region_name(ctl->alg_region.type), ctl->offset); + + ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); + if (ret) { + adsp_err(dsp, "Failed to write %x: %d\n", reg, ret); + return ret; + } + + /* + * Poll for ack, we initially poll at ~1ms intervals for firmwares + * that respond quickly, then go to ~10ms polls. A firmware is unlikely + * to ack instantly so we do the first 1ms delay before reading the + * control to avoid a pointless bus transaction + */ + for (i = 0; i < WM_ADSP_ACKED_CTL_TIMEOUT_MS;) { + switch (i) { + case 0 ... WM_ADSP_ACKED_CTL_N_QUICKPOLLS - 1: + usleep_range(1000, 2000); + i++; + break; + default: + usleep_range(10000, 20000); + i += 10; + break; + } + + ret = wm_adsp2_raw_read(MAXBULK, dsp->regmap, reg, &val, + sizeof(val)); + if (ret) { + adsp_err(dsp, "Failed to read %x: %d\n", reg, ret); + return ret; + } + + if (val == 0) { + adsp_dbg(dsp, "Acked control ACKED at poll %u\n", i); + return 0; + } + } + + adsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", reg, + ctl->alg_region.alg, + wm_adsp_mem_region_name(ctl->alg_region.type), ctl->offset); + + return -ETIMEDOUT; +} + +static int wm_coeff_write_control(struct wm_coeff_ctl *ctl, const void *buf, + size_t len) +{ + struct wm_adsp *dsp = ctl->dsp; + void *scratch; + int ret; + unsigned int reg; + + ret = wm_coeff_base_reg(ctl, ®); + if (ret) + return ret; + + scratch = kmemdup(buf, len, GFP_KERNEL | GFP_DMA); + if (!scratch) + return -ENOMEM; + + ret = regmap_raw_write(dsp->regmap, reg, scratch, len); + if (ret) { + adsp_err(dsp, "Failed to write %zu bytes to %x: %d\n", len, reg, + ret); + kfree(scratch); + return ret; + } + adsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg); + + kfree(scratch); + + return 0; +} + +static int wm_coeff_put(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + char *p = ucontrol->value.bytes.data; + int ret = 0; + + mutex_lock(&ctl->dsp->pwr_lock); + + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) + ret = -EPERM; + else + memcpy(ctl->cache, p, ctl->len); + + ctl->set = 1; + if (ctl->enabled && ctl->dsp->running) + ret = wm_coeff_write_control(ctl, p, ctl->len); + + mutex_unlock(&ctl->dsp->pwr_lock); + + return ret; +} + +static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, + const unsigned int __user *bytes, unsigned int size) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + int ret = 0; + + mutex_lock(&ctl->dsp->pwr_lock); + + if (copy_from_user(ctl->cache, bytes, size)) { + ret = -EFAULT; + } else { + ctl->set = 1; + if (ctl->enabled && ctl->dsp->running) + ret = wm_coeff_write_control(ctl, ctl->cache, size); + else if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) + ret = -EPERM; + } + + mutex_unlock(&ctl->dsp->pwr_lock); + + return ret; +} + +static int wm_coeff_put_acked(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + unsigned int val = ucontrol->value.integer.value[0]; + int ret; + + if (val == 0) + return 0; /* 0 means no event */ + + mutex_lock(&ctl->dsp->pwr_lock); + + if (ctl->enabled && ctl->dsp->running) + ret = wm_coeff_write_acked_control(ctl, val); + else + ret = -EPERM; + + mutex_unlock(&ctl->dsp->pwr_lock); + + return ret; +} + +static int wm_coeff_read_control(struct wm_coeff_ctl *ctl, void *buf, + size_t len) +{ + struct wm_adsp *dsp = ctl->dsp; + void *scratch; + int ret; + unsigned int reg; + + ret = wm_coeff_base_reg(ctl, ®); + if (ret) + return ret; + + scratch = kmalloc(len, GFP_KERNEL | GFP_DMA); + if (!scratch) + return -ENOMEM; + + ret = wm_adsp2_raw_read(MAXBULK, dsp->regmap, reg, scratch, len); + if (ret) { + adsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", len, + reg, ret); + kfree(scratch); + return ret; + } + adsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg); + + memcpy(buf, scratch, len); + kfree(scratch); + + return 0; +} + +static int wm_coeff_get(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + char *p = ucontrol->value.bytes.data; + int ret = 0; + + mutex_lock(&ctl->dsp->pwr_lock); + + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { + if (ctl->enabled && ctl->dsp->running) + ret = wm_coeff_read_control(ctl, p, ctl->len); + else + ret = -EPERM; + } else { + if (!ctl->flags && ctl->enabled && ctl->dsp->running) + ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); + + memcpy(p, ctl->cache, ctl->len); + } + + mutex_unlock(&ctl->dsp->pwr_lock); + + return ret; +} + +static int wm_coeff_tlv_get(struct snd_kcontrol *kctl, + unsigned int __user *bytes, unsigned int size) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + int ret = 0; + + mutex_lock(&ctl->dsp->pwr_lock); + + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { + if (ctl->enabled && ctl->dsp->running) + ret = wm_coeff_read_control(ctl, ctl->cache, size); + else + ret = -EPERM; + } else { + if (!ctl->flags && ctl->enabled && ctl->dsp->running) + ret = wm_coeff_read_control(ctl, ctl->cache, size); + } + + if (!ret && copy_to_user(bytes, ctl->cache, size)) + ret = -EFAULT; + + mutex_unlock(&ctl->dsp->pwr_lock); + + return ret; +} + +static int wm_coeff_get_acked(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Although it's not useful to read an acked control, we must satisfy + * user-side assumptions that all controls are readable and that a + * write of the same value should be filtered out (it's valid to send + * the same event number again to the firmware). We therefore return 0, + * meaning "no event" so valid event numbers will always be a change + */ + ucontrol->value.integer.value[0] = 0; + + return 0; +} + +struct wmfw_ctl_work { + struct wm_adsp *dsp; + struct wm_coeff_ctl *ctl; + struct work_struct work; +}; + +static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len) +{ + unsigned int out, rd, wr, vol; + + if (len > ADSP_MAX_STD_CTRL_SIZE) { + rd = SNDRV_CTL_ELEM_ACCESS_TLV_READ; + wr = SNDRV_CTL_ELEM_ACCESS_TLV_WRITE; + vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE; + + out = SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; + } else { + rd = SNDRV_CTL_ELEM_ACCESS_READ; + wr = SNDRV_CTL_ELEM_ACCESS_WRITE; + vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE; + + out = 0; + } + + if (in) { + if (in & WMFW_CTL_FLAG_READABLE) + out |= rd; + if (in & WMFW_CTL_FLAG_WRITEABLE) + out |= wr; + if (in & WMFW_CTL_FLAG_VOLATILE) + out |= vol; + } else { + out |= rd | wr | vol; + } + + return out; +} + +static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) +{ + struct snd_kcontrol_new *kcontrol; + int ret; + + if (!ctl || !ctl->name) + return -EINVAL; + + kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); + if (!kcontrol) + return -ENOMEM; + + kcontrol->name = ctl->name; + kcontrol->info = wm_coeff_info; + kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER; + kcontrol->tlv.c = snd_soc_bytes_tlv_callback; + kcontrol->private_value = (unsigned long)&ctl->bytes_ext; + kcontrol->access = wmfw_convert_flags(ctl->flags, ctl->len); + + switch (ctl->type) { + case WMFW_CTL_TYPE_ACKED: + kcontrol->get = wm_coeff_get_acked; + kcontrol->put = wm_coeff_put_acked; + break; + default: + kcontrol->get = wm_coeff_get; + kcontrol->put = wm_coeff_put; + + ctl->bytes_ext.max = ctl->len; + ctl->bytes_ext.get = wm_coeff_tlv_get; + ctl->bytes_ext.put = wm_coeff_tlv_put; + break; + } + + ret = snd_soc_add_codec_controls(dsp->codec, kcontrol, 1); + if (ret < 0) + goto err_kcontrol; + + kfree(kcontrol); + + return 0; + +err_kcontrol: + kfree(kcontrol); + return ret; +} + +static int wm_coeff_init_control_caches(struct wm_adsp *dsp) +{ + struct wm_coeff_ctl *ctl; + int ret; + + list_for_each_entry (ctl, &dsp->ctl_list, list) { + if (!ctl->enabled || ctl->set) + continue; + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) + continue; + + ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); + if (ret < 0) + return ret; + } + + return 0; +} + +static int wm_coeff_sync_controls(struct wm_adsp *dsp) +{ + struct wm_coeff_ctl *ctl; + int ret; + + list_for_each_entry (ctl, &dsp->ctl_list, list) { + if (!ctl->enabled) + continue; + if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) { + ret = wm_coeff_write_control(ctl, ctl->cache, ctl->len); + if (ret < 0) + return ret; + } + } + + return 0; +} + +static void wm_adsp_signal_event_controls(struct wm_adsp *dsp, + unsigned int event) +{ + struct wm_coeff_ctl *ctl; + int ret; + + list_for_each_entry (ctl, &dsp->ctl_list, list) { + if (ctl->type != WMFW_CTL_TYPE_HOSTEVENT) + continue; + + if (!ctl->enabled) + continue; + + ret = wm_coeff_write_acked_control(ctl, event); + if (ret) + adsp_warn( + dsp, + "Failed to send 0x%x event to alg 0x%x (%d)\n", + event, ctl->alg_region.alg, ret); + } +} + +static void wm_adsp_ctl_work(struct work_struct *work) +{ + struct wmfw_ctl_work *ctl_work = + container_of(work, struct wmfw_ctl_work, work); + + wmfw_add_ctl(ctl_work->dsp, ctl_work->ctl); + kfree(ctl_work); +} + +static void wm_adsp_free_ctl_blk(struct wm_coeff_ctl *ctl) +{ + kfree(ctl->cache); + kfree(ctl->name); + kfree(ctl); +} + +static int wm_adsp_create_control(struct wm_adsp *dsp, + const struct wm_adsp_alg_region *alg_region, + unsigned int offset, unsigned int len, + const char *subname, unsigned int subname_len, + unsigned int flags, unsigned int type) +{ + struct wm_coeff_ctl *ctl; + struct wmfw_ctl_work *ctl_work; + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + const char *region_name; + int ret; + + region_name = wm_adsp_mem_region_name(alg_region->type); + if (!region_name) { + adsp_err(dsp, "Unknown region type: %d\n", alg_region->type); + return -EINVAL; + } + + switch (dsp->fw_ver) { + case 0: + case 1: + snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "DSP%d %s %x", + dsp->num, region_name, alg_region->alg); + break; + default: + ret = snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, + "DSP%d%c %.12s %x", dsp->num, *region_name, + wm_adsp_fw_text[dsp->fw], alg_region->alg); + + /* Truncate the subname from the start if it is too long */ + if (subname) { + int avail = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret - 2; + int skip = 0; + + if (subname_len > avail) + skip = subname_len - avail; + + snprintf(name + ret, + SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret, " %.*s", + subname_len - skip, subname + skip); + } + break; + } + + list_for_each_entry (ctl, &dsp->ctl_list, list) { + if (!strcmp(ctl->name, name)) { + if (!ctl->enabled) + ctl->enabled = 1; + return 0; + } + } + + ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + if (!ctl) + return -ENOMEM; + ctl->fw_name = wm_adsp_fw_text[dsp->fw]; + ctl->alg_region = *alg_region; + ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL); + if (!ctl->name) { + ret = -ENOMEM; + goto err_ctl; + } + ctl->enabled = 1; + ctl->set = 0; + ctl->ops.xget = wm_coeff_get; + ctl->ops.xput = wm_coeff_put; + ctl->dsp = dsp; + + ctl->flags = flags; + ctl->type = type; + ctl->offset = offset; + ctl->len = len; + ctl->cache = kzalloc(ctl->len, GFP_KERNEL); + if (!ctl->cache) { + ret = -ENOMEM; + goto err_ctl_name; + } + + list_add(&ctl->list, &dsp->ctl_list); + + if (flags & WMFW_CTL_FLAG_SYS) + return 0; + + ctl_work = kzalloc(sizeof(*ctl_work), GFP_KERNEL); + if (!ctl_work) { + ret = -ENOMEM; + goto err_ctl_cache; + } + + ctl_work->dsp = dsp; + ctl_work->ctl = ctl; + INIT_WORK(&ctl_work->work, wm_adsp_ctl_work); + schedule_work(&ctl_work->work); + + return 0; + +err_ctl_cache: + kfree(ctl->cache); +err_ctl_name: + kfree(ctl->name); +err_ctl: + kfree(ctl); + + return ret; +} + +struct wm_coeff_parsed_alg { + int id; + const u8 *name; + int name_len; + int ncoeff; +}; + +struct wm_coeff_parsed_coeff { + int offset; + int mem_type; + const u8 *name; + int name_len; + int ctl_type; + int flags; + int len; +}; + +static int wm_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) +{ + int length; + + switch (bytes) { + case 1: + length = **pos; + break; + case 2: + length = le16_to_cpu(*((__le16 *)*pos)); + break; + default: + return 0; + } + + if (str) + *str = *pos + bytes; + + *pos += ((length + bytes) + 3) & ~0x03; + + return length; +} + +static int wm_coeff_parse_int(int bytes, const u8 **pos) +{ + int val = 0; + + switch (bytes) { + case 2: + val = le16_to_cpu(*((__le16 *)*pos)); + break; + case 4: + val = le32_to_cpu(*((__le32 *)*pos)); + break; + default: + break; + } + + *pos += bytes; + + return val; +} + +static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, + struct wm_coeff_parsed_alg *blk) +{ + const struct wmfw_adsp_alg_data *raw; + + switch (dsp->fw_ver) { + case 0: + case 1: + raw = (const struct wmfw_adsp_alg_data *)*data; + *data = raw->data; + + blk->id = le32_to_cpu(raw->id); + blk->name = raw->name; + blk->name_len = strlen(raw->name); + blk->ncoeff = le32_to_cpu(raw->ncoeff); + break; + default: + blk->id = wm_coeff_parse_int(sizeof(raw->id), data); + blk->name_len = + wm_coeff_parse_string(sizeof(u8), data, &blk->name); + wm_coeff_parse_string(sizeof(u16), data, NULL); + blk->ncoeff = wm_coeff_parse_int(sizeof(raw->ncoeff), data); + break; + } + + adsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); + adsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); + adsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); +} + +static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, + struct wm_coeff_parsed_coeff *blk) +{ + const struct wmfw_adsp_coeff_data *raw; + const u8 *tmp; + int length; + + switch (dsp->fw_ver) { + case 0: + case 1: + raw = (const struct wmfw_adsp_coeff_data *)*data; + *data = *data + sizeof(raw->hdr) + le32_to_cpu(raw->hdr.size); + + blk->offset = le16_to_cpu(raw->hdr.offset); + blk->mem_type = le16_to_cpu(raw->hdr.type); + blk->name = raw->name; + blk->name_len = strlen(raw->name); + blk->ctl_type = le16_to_cpu(raw->ctl_type); + blk->flags = le16_to_cpu(raw->flags); + blk->len = le32_to_cpu(raw->len); + break; + default: + tmp = *data; + blk->offset = wm_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); + blk->mem_type = wm_coeff_parse_int(sizeof(raw->hdr.type), &tmp); + length = wm_coeff_parse_int(sizeof(raw->hdr.size), &tmp); + blk->name_len = + wm_coeff_parse_string(sizeof(u8), &tmp, &blk->name); + wm_coeff_parse_string(sizeof(u8), &tmp, NULL); + wm_coeff_parse_string(sizeof(u16), &tmp, NULL); + blk->ctl_type = wm_coeff_parse_int(sizeof(raw->ctl_type), &tmp); + blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp); + blk->len = wm_coeff_parse_int(sizeof(raw->len), &tmp); + + *data = *data + sizeof(raw->hdr) + length; + break; + } + + adsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); + adsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); + adsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); + adsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); + adsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); + adsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); +} + +static int +wm_adsp_check_coeff_flags(struct wm_adsp *dsp, + const struct wm_coeff_parsed_coeff *coeff_blk, + unsigned int f_required, unsigned int f_illegal) +{ + if ((coeff_blk->flags & f_illegal) || + ((coeff_blk->flags & f_required) != f_required)) { + adsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", + coeff_blk->flags, coeff_blk->ctl_type); + return -EINVAL; + } + + return 0; +} + +static int wm_adsp_parse_coeff(struct wm_adsp *dsp, + const struct wmfw_region *region) +{ + struct wm_adsp_alg_region alg_region = {}; + struct wm_coeff_parsed_alg alg_blk; + struct wm_coeff_parsed_coeff coeff_blk; + const u8 *data = region->data; + int i, ret; + + wm_coeff_parse_alg(dsp, &data, &alg_blk); + for (i = 0; i < alg_blk.ncoeff; i++) { + wm_coeff_parse_coeff(dsp, &data, &coeff_blk); + + switch (coeff_blk.ctl_type) { + case SNDRV_CTL_ELEM_TYPE_BYTES: + break; + case WMFW_CTL_TYPE_ACKED: + if (coeff_blk.flags & WMFW_CTL_FLAG_SYS) + continue; /* ignore */ + + ret = wm_adsp_check_coeff_flags( + dsp, &coeff_blk, + WMFW_CTL_FLAG_VOLATILE | + WMFW_CTL_FLAG_WRITEABLE | + WMFW_CTL_FLAG_READABLE, + 0); + if (ret) + return -EINVAL; + break; + case WMFW_CTL_TYPE_HOSTEVENT: + ret = wm_adsp_check_coeff_flags( + dsp, &coeff_blk, + WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_VOLATILE | + WMFW_CTL_FLAG_WRITEABLE | + WMFW_CTL_FLAG_READABLE, + 0); + if (ret) + return -EINVAL; + break; + default: + adsp_err(dsp, "Unknown control type: %d\n", + coeff_blk.ctl_type); + return -EINVAL; + } + + alg_region.type = coeff_blk.mem_type; + alg_region.alg = alg_blk.id; + + ret = wm_adsp_create_control(dsp, &alg_region, coeff_blk.offset, + coeff_blk.len, coeff_blk.name, + coeff_blk.name_len, + coeff_blk.flags, + coeff_blk.ctl_type); + if (ret < 0) + adsp_err(dsp, "Failed to create control: %.*s, %d\n", + coeff_blk.name_len, coeff_blk.name, ret); + } + + return 0; +} + +static int wm_adsp_load(struct wm_adsp *dsp) +{ + LIST_HEAD(buf_list); + const struct firmware *firmware; + struct regmap *regmap = dsp->regmap; + unsigned int pos = 0; + const struct wmfw_header *header; + const struct wmfw_adsp1_sizes *adsp1_sizes; + const struct wmfw_adsp2_sizes *adsp2_sizes; + const struct wmfw_footer *footer; + const struct wmfw_region *region; + const struct wm_adsp_region *mem; + const char *region_name; + char *file, *text = NULL; + struct wm_adsp_buf *buf; +#ifdef WM_ADSP_DEBUG + void *bufVerify; +#endif + unsigned int reg; + int regions = 0; + int ret, offset, type, sizes; +#ifdef WM_ADSP_DEBUG + size_t i; + bool verifyOk = true; + int tempA, tempB; + int *pTempA, *pTempB; + int max_failures = 666666; + int num_failures = 0; + int whileLoopCount = 0; +#endif + file = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (file == NULL) + return -ENOMEM; + + snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.wmfw", dsp->part, dsp->num, + wm_adsp_fw[dsp->fw].file); + file[PAGE_SIZE - 1] = '\0'; + + ret = request_firmware(&firmware, file, dsp->dev); + if (ret != 0) { + adsp_err(dsp, "Failed to request '%s'\n", file); + goto out; + } + ret = -EINVAL; + + pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); + if (pos >= firmware->size) { + adsp_err(dsp, "%s: file too short, %zu bytes\n", file, + firmware->size); + goto out_fw; + } + + header = (void *)&firmware->data[0]; + + if (memcmp(&header->magic[0], "WMFW", 4) != 0) { + adsp_err(dsp, "%s: invalid magic\n", file); + goto out_fw; + } + + switch (dsp->type) { + case WMFW_ADSP1: + case WMFW_ADSP2: + switch (header->ver) { + case 0: + adsp_warn(dsp, "%s: Deprecated file format %d\n", file, + header->ver); + break; + case 1: + case 2: + break; + default: + adsp_err(dsp, "%s: unknown file format %d\n", file, + header->ver); + goto out_fw; + } + break; + case WMFW_HALO: + switch (header->ver) { + case 1: + case 2: + /* + * we are required to load these for testing purposes + * but this format is not allowed for production fw + */ + adsp_warn( + dsp, + "%s: Not a production firmware (deprecated file format %d)\n", + file, header->ver); + break; + case 3: + break; + default: + adsp_err(dsp, "%s: unknown file format %d\n", file, + header->ver); + goto out_fw; + } + } + + adsp_info(dsp, "Firmware version: %d\n", header->ver); + dsp->fw_ver = header->ver; + + if (header->core != dsp->type) { + adsp_err(dsp, "%s: invalid core %d != %d\n", file, header->core, + dsp->type); + goto out_fw; + } + + switch (dsp->type) { + case WMFW_ADSP1: + pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); + adsp1_sizes = (void *)&(header[1]); + footer = (void *)&(adsp1_sizes[1]); + sizes = sizeof(*adsp1_sizes); + + adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file, + le32_to_cpu(adsp1_sizes->dm), + le32_to_cpu(adsp1_sizes->pm), + le32_to_cpu(adsp1_sizes->zm)); + break; + + case WMFW_HALO: + case WMFW_ADSP2: + pos = sizeof(*header) + sizeof(*adsp2_sizes) + sizeof(*footer); + adsp2_sizes = (void *)&(header[1]); + footer = (void *)&(adsp2_sizes[1]); + sizes = sizeof(*adsp2_sizes); + + adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file, + le32_to_cpu(adsp2_sizes->xm), + le32_to_cpu(adsp2_sizes->ym), + le32_to_cpu(adsp2_sizes->pm), + le32_to_cpu(adsp2_sizes->zm)); + break; + + default: + WARN(1, "Unknown DSP type"); + goto out_fw; + } + + if (le32_to_cpu(header->len) != + sizeof(*header) + sizes + sizeof(*footer)) { + adsp_err(dsp, "%s: unexpected header length %d\n", file, + le32_to_cpu(header->len)); + goto out_fw; + } + + adsp_dbg(dsp, "%s: timestamp %llu\n", file, + le64_to_cpu(footer->timestamp)); + + while (pos < firmware->size && pos - firmware->size > sizeof(*region)) { +#ifdef WM_ADSP_DEBUG + num_failures = 0; +#endif + region = (void *)&(firmware->data[pos]); + region_name = "Unknown"; + reg = 0; + text = NULL; + offset = le32_to_cpu(region->offset) & 0xffffff; + type = be32_to_cpu(region->type) & 0xff; + mem = wm_adsp_find_region(dsp, type); + + switch (type) { + case WMFW_NAME_TEXT: + region_name = "Firmware name"; + text = kzalloc(le32_to_cpu(region->len) + 1, + GFP_KERNEL); + break; + case WMFW_ALGORITHM_DATA: + region_name = "Algorithm"; + ret = wm_adsp_parse_coeff(dsp, region); + if (ret != 0) + goto out_fw; + break; + case WMFW_INFO_TEXT: + region_name = "Information"; + text = kzalloc(le32_to_cpu(region->len) + 1, + GFP_KERNEL); + break; + case WMFW_ABSOLUTE: + region_name = "Absolute"; + reg = offset; + break; + case WMFW_ADSP1_PM: + case WMFW_ADSP1_DM: + case WMFW_ADSP2_XM: + case WMFW_ADSP2_YM: + case WMFW_ADSP1_ZM: + case WMFW_HALO_PM_PACKED: + case WMFW_HALO_XM_PACKED: + case WMFW_HALO_YM_PACKED: + region_name = wm_adsp_mem_region_name(type); + reg = wm_adsp_region_to_reg(dsp, mem, offset); + break; + default: + adsp_warn(dsp, + "%s.%d: Unknown region type %x at %d(%x)\n", + file, regions, type, pos, pos); + break; + } + + adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, regions, + le32_to_cpu(region->len), offset, region_name); + + if ((pos + le32_to_cpu(region->len) + sizeof(*region)) > + firmware->size) { + adsp_err( + dsp, + "%s.%d: %s region len %d bytes exceeds file length %zu\n", + file, regions, region_name, + le32_to_cpu(region->len), firmware->size); + ret = -EINVAL; + goto out_fw; + } + + if (text) { + memcpy(text, region->data, le32_to_cpu(region->len)); + adsp_info(dsp, "%s: %s\n", file, text); + kfree(text); + text = NULL; + } + + if (reg) { + buf = wm_adsp_buf_alloc(region->data, + le32_to_cpu(region->len), + &buf_list); + if (!buf) { + adsp_err(dsp, "Out of memory\n"); + ret = -ENOMEM; + goto out_fw; + } +#ifdef WM_ADSP_DEBUG + bufVerify = vmalloc(le32_to_cpu(region->len)); + if (!bufVerify) { + adsp_err( + dsp, + "Could not allocate memory for verification buffer\n"); + ret = -ENOMEM; + goto out_fw; + } +#endif + + ret = regmap_raw_write_async(regmap, reg, buf->buf, + le32_to_cpu(region->len)); + + if (ret != 0) { + adsp_err( + dsp, + "%s.%d: Failed to write %d bytes at %d in %s: %d\n", + file, regions, le32_to_cpu(region->len), + offset, region_name, ret); + goto out_fw; + } +#ifdef WM_ADSP_DEBUG + /* abb. 3/5/18 - DEBUG. Wait for this write to complete + Then we will read back the registers and verify contents */ + adsp_info(dsp, "%s: Waiting to complete async write\n", + __func__); + ret = regmap_async_complete(regmap); + if (ret != 0) { + adsp_err( + dsp, + "[1] Failed to complete async write: %d\n", + ret); + goto out_fw; + } + adsp_err(dsp, "%s: Async write completed\n", __func__); + + ret = wm_adsp2_raw_read(MAXBULK, regmap, reg, bufVerify, + le32_to_cpu(region->len)); + + adsp_err(dsp, "%s: Beginning Verification (loop %d)\n", + __func__, whileLoopCount); + adsp_err(dsp, "%s: Total loop length: %d\n", __func__, + le32_to_cpu(region->len) / 4); + pTempA = (int *)buf->buf; + pTempB = (int *)bufVerify; + for (i = 0; i < le32_to_cpu(region->len) / 4; i++) { + tempA = pTempA[i]; + tempB = pTempB[i]; + + if (tempA != tempB) { + adsp_err( + dsp, + "** Verify failed on reg 0x%x at i=%zu (wrote 0x%x vs read 0x%x)\n", + reg, i, tempA, tempB); + verifyOk = false; + num_failures++; + } + + if (num_failures >= max_failures) { + adsp_err( + dsp, + "** Too many failed register verifies (hit max of %d). Exiting\n", + max_failures); + break; + } + } + + vfree(bufVerify); +#endif + } + + pos += le32_to_cpu(region->len) + sizeof(*region); + regions++; +#ifdef WM_ADSP_DEBUG + whileLoopCount++; +#endif + } + + ret = regmap_async_complete(regmap); + if (ret != 0) { + adsp_err(dsp, "Failed to complete async write: %d\n", ret); + goto out_fw; + } + + if (pos > firmware->size) + adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", file, + regions, pos - firmware->size); + + wm_adsp_debugfs_save_wmfwname(dsp, file); + +out_fw: + regmap_async_complete(regmap); + wm_adsp_buf_free(&buf_list); + release_firmware(firmware); + kfree(text); +out: + kfree(file); +#ifdef WM_ADSP_DEBUG + adsp_err(dsp, "wm_adsp_load- with verifyOk = %d and ret = %d", verifyOk, + ret); +#endif + return ret; +} + +static void wm_adsp_ctl_fixup_base(struct wm_adsp *dsp, + const struct wm_adsp_alg_region *alg_region) +{ + struct wm_coeff_ctl *ctl; + + list_for_each_entry (ctl, &dsp->ctl_list, list) { + if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && + alg_region->alg == ctl->alg_region.alg && + alg_region->type == ctl->alg_region.type) { + ctl->alg_region.base = alg_region->base; + } + } +} + +static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs, + unsigned int pos, unsigned int len) +{ + void *alg; + int ret; + __be32 val; + + if (n_algs == 0) { + adsp_err(dsp, "No algorithms\n"); + return ERR_PTR(-EINVAL); + } + + if (n_algs > 1024) { + adsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); + return ERR_PTR(-EINVAL); + } + + /* Read the terminator first to validate the length */ + ret = wm_adsp2_raw_read(MAXBULK, dsp->regmap, pos + len, &val, + sizeof(val)); + if (ret != 0) { + adsp_err(dsp, "Failed to read algorithm list end: %d\n", ret); + return ERR_PTR(ret); + } + + if (be32_to_cpu(val) != 0xbedead) + adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n", + pos + len, be32_to_cpu(val)); + + alg = kzalloc(len * 2, GFP_KERNEL | GFP_DMA); + if (!alg) + return ERR_PTR(-ENOMEM); + + ret = wm_adsp2_raw_read(MAXBULK, dsp->regmap, pos, alg, len * 2); + if (ret != 0) { + adsp_err(dsp, "Failed to read algorithm list: %d\n", ret); + kfree(alg); + return ERR_PTR(ret); + } + + return alg; +} + +static struct wm_adsp_alg_region * +wm_adsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id) +{ + struct wm_adsp_alg_region *alg_region; + + list_for_each_entry (alg_region, &dsp->alg_regions, list) { + if (id == alg_region->alg && type == alg_region->type) + return alg_region; + } + + return NULL; +} + +static struct wm_adsp_alg_region * +wm_adsp_create_region(struct wm_adsp *dsp, int type, __be32 id, __be32 base) +{ + struct wm_adsp_alg_region *alg_region; + + alg_region = kzalloc(sizeof(*alg_region), GFP_KERNEL); + if (!alg_region) + return ERR_PTR(-ENOMEM); + + alg_region->type = type; + alg_region->alg = be32_to_cpu(id); + alg_region->base = be32_to_cpu(base); + + list_add_tail(&alg_region->list, &dsp->alg_regions); + + if (dsp->fw_ver > 0) + wm_adsp_ctl_fixup_base(dsp, alg_region); + + return alg_region; +} + +static void wm_adsp_free_alg_regions(struct wm_adsp *dsp) +{ + struct wm_adsp_alg_region *alg_region; + + while (!list_empty(&dsp->alg_regions)) { + alg_region = list_first_entry(&dsp->alg_regions, + struct wm_adsp_alg_region, list); + list_del(&alg_region->list); + kfree(alg_region); + } +} + +static int wm_adsp1_setup_algs(struct wm_adsp *dsp) +{ + struct wmfw_adsp1_id_hdr adsp1_id; + struct wmfw_adsp1_alg_hdr *adsp1_alg; + struct wm_adsp_alg_region *alg_region; + const struct wm_adsp_region *mem; + unsigned int pos, len; + size_t n_algs; + int i, ret; + + mem = wm_adsp_find_region(dsp, WMFW_ADSP1_DM); + if (WARN_ON(!mem)) + return -EINVAL; + + ret = wm_adsp2_raw_read(MAXBULK, dsp->regmap, mem->base, &adsp1_id, + sizeof(adsp1_id)); + if (ret != 0) { + adsp_err(dsp, "Failed to read algorithm info: %d\n", ret); + return ret; + } + + n_algs = be32_to_cpu(adsp1_id.n_algs); + dsp->fw_id = be32_to_cpu(adsp1_id.fw.id); + adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", dsp->fw_id, + (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16, + (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8, + be32_to_cpu(adsp1_id.fw.ver) & 0xff, n_algs); + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, adsp1_id.fw.id, + adsp1_id.zm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, adsp1_id.fw.id, + adsp1_id.dm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + pos = sizeof(adsp1_id) / 2; + len = (sizeof(*adsp1_alg) * n_algs) / 2; + + adsp1_alg = wm_adsp_read_algs(dsp, n_algs, mem->base + pos, len); + if (IS_ERR(adsp1_alg)) + return PTR_ERR(adsp1_alg); + + for (i = 0; i < n_algs; i++) { + adsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", i, + be32_to_cpu(adsp1_alg[i].alg.id), + (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff, + be32_to_cpu(adsp1_alg[i].dm), + be32_to_cpu(adsp1_alg[i].zm)); + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, + adsp1_alg[i].alg.id, + adsp1_alg[i].dm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp1_alg[i + 1].dm); + len -= be32_to_cpu(adsp1_alg[i].dm); + len *= 4; + wm_adsp_create_control( + dsp, alg_region, 0, len, NULL, 0, 0, + SNDRV_CTL_ELEM_TYPE_BYTES); + } else { + adsp_warn( + dsp, + "Missing length info for region DM with ID %x\n", + be32_to_cpu(adsp1_alg[i].alg.id)); + } + } + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, + adsp1_alg[i].alg.id, + adsp1_alg[i].zm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp1_alg[i + 1].zm); + len -= be32_to_cpu(adsp1_alg[i].zm); + len *= 4; + wm_adsp_create_control( + dsp, alg_region, 0, len, NULL, 0, 0, + SNDRV_CTL_ELEM_TYPE_BYTES); + } else { + adsp_warn( + dsp, + "Missing length info for region ZM with ID %x\n", + be32_to_cpu(adsp1_alg[i].alg.id)); + } + } + } + +out: + kfree(adsp1_alg); + return ret; +} + +static int wm_adsp2_setup_algs(struct wm_adsp *dsp) +{ + struct wmfw_adsp2_id_hdr adsp2_id; + struct wmfw_adsp2_alg_hdr *adsp2_alg; + struct wm_adsp_alg_region *alg_region; + const struct wm_adsp_region *mem; + unsigned int pos, len; + size_t n_algs; + int i, ret; + + mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM); + if (WARN_ON(!mem)) + return -EINVAL; + + ret = wm_adsp2_raw_read(MAXBULK, dsp->regmap, mem->base, &adsp2_id, + sizeof(adsp2_id)); + if (ret != 0) { + adsp_err(dsp, "Failed to read algorithm info: %d\n", ret); + return ret; + } + + n_algs = be32_to_cpu(adsp2_id.n_algs); + dsp->fw_id = be32_to_cpu(adsp2_id.fw.id); + dsp->fw_id_version = be32_to_cpu(adsp2_id.fw.ver); + dsp->fw_vendor_id = 0; + adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", dsp->fw_id, + (dsp->fw_id_version & 0xff0000) >> 16, + (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, + n_algs); + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, adsp2_id.fw.id, + adsp2_id.xm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, adsp2_id.fw.id, + adsp2_id.ym); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + switch (dsp->type) { + case WMFW_HALO: + pos = sizeof(adsp2_id); + len = sizeof(*adsp2_alg) * n_algs; + break; + default: + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, + adsp2_id.fw.id, adsp2_id.zm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + pos = sizeof(adsp2_id) / 2; + len = (sizeof(*adsp2_alg) * n_algs) / 2; + break; + } + + adsp2_alg = wm_adsp_read_algs(dsp, n_algs, mem->base + pos, len); + if (IS_ERR(adsp2_alg)) + return PTR_ERR(adsp2_alg); + + for (i = 0; i < n_algs; i++) { + adsp_info(dsp, "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", i, + be32_to_cpu(adsp2_alg[i].alg.id), + (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, + be32_to_cpu(adsp2_alg[i].xm), + be32_to_cpu(adsp2_alg[i].ym), + be32_to_cpu(adsp2_alg[i].zm)); + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, + adsp2_alg[i].alg.id, + adsp2_alg[i].xm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp2_alg[i + 1].xm); + len -= be32_to_cpu(adsp2_alg[i].xm); + len *= 4; + wm_adsp_create_control( + dsp, alg_region, 0, len, NULL, 0, 0, + SNDRV_CTL_ELEM_TYPE_BYTES); + } else { + adsp_warn( + dsp, + "Missing length info for region XM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, + adsp2_alg[i].alg.id, + adsp2_alg[i].ym); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp2_alg[i + 1].ym); + len -= be32_to_cpu(adsp2_alg[i].ym); + len *= 4; + wm_adsp_create_control( + dsp, alg_region, 0, len, NULL, 0, 0, + SNDRV_CTL_ELEM_TYPE_BYTES); + } else { + adsp_warn( + dsp, + "Missing length info for region YM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + + /* no ZM on HALO */ + if (dsp->type == WMFW_HALO) + continue; + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, + adsp2_alg[i].alg.id, + adsp2_alg[i].zm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp2_alg[i + 1].zm); + len -= be32_to_cpu(adsp2_alg[i].zm); + len *= 4; + wm_adsp_create_control( + dsp, alg_region, 0, len, NULL, 0, 0, + SNDRV_CTL_ELEM_TYPE_BYTES); + } else { + adsp_warn( + dsp, + "Missing length info for region ZM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + } + +out: + kfree(adsp2_alg); + return ret; +} + +static int wm_halo_setup_algs(struct wm_adsp *dsp) +{ + struct wmfw_halo_id_hdr halo_id; + struct wmfw_halo_alg_hdr *halo_alg; + struct wm_adsp_alg_region *alg_region; + const struct wm_adsp_region *mem; + unsigned int pos, len, block_rev; + size_t n_algs; + int i, ret; + + mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM); + if (WARN_ON(!mem)) + return -EINVAL; + + ret = wm_adsp2_raw_read(MAXBULK, dsp->regmap, mem->base, &halo_id, + sizeof(halo_id)); + if (ret != 0) { + adsp_err(dsp, "Failed to read algorithm info: %d\n", ret); + return ret; + } + + block_rev = be32_to_cpu(halo_id.fw.block_rev) >> 16; + switch (block_rev) { + case 3: + break; + default: + adsp_err(dsp, "Unknown firmware ID block version 0x%x\n", + block_rev); + return -EINVAL; + } + + n_algs = be32_to_cpu(halo_id.n_algs); + dsp->fw_id = be32_to_cpu(halo_id.fw.id); + dsp->fw_id_version = be32_to_cpu(halo_id.fw.ver); + dsp->fw_vendor_id = be32_to_cpu(halo_id.fw.vendor_id); + adsp_info(dsp, "Firmware: %x vendor: 0x%x v%d.%d.%d, %zu algorithms\n", + dsp->fw_id, dsp->fw_vendor_id, + (dsp->fw_id_version & 0xff0000) >> 16, + (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, + n_algs); + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, halo_id.fw.id, + halo_id.xm_base); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + alg_region = wm_adsp_create_region(dsp, WMFW_HALO_XM_PACKED, + halo_id.fw.id, halo_id.xm_base); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, halo_id.fw.id, + halo_id.ym_base); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + alg_region = wm_adsp_create_region(dsp, WMFW_HALO_YM_PACKED, + halo_id.fw.id, halo_id.ym_base); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + pos = sizeof(halo_id); + len = (sizeof(*halo_alg) * n_algs); + + halo_alg = wm_adsp_read_algs(dsp, n_algs, mem->base + pos, len); + if (IS_ERR(halo_alg)) + return PTR_ERR(halo_alg); + + for (i = 0; i < n_algs; i++) { + adsp_info(dsp, "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", i, + be32_to_cpu(halo_alg[i].alg.id), + (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(halo_alg[i].alg.ver) & 0xff, + be32_to_cpu(halo_alg[i].xm_base), + be32_to_cpu(halo_alg[i].ym_base)); + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, + halo_alg[i].alg.id, + halo_alg[i].xm_base); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + + alg_region = wm_adsp_create_region(dsp, WMFW_HALO_XM_PACKED, + halo_alg[i].alg.id, + halo_alg[i].xm_base); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, + halo_alg[i].alg.id, + halo_alg[i].ym_base); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + + alg_region = wm_adsp_create_region(dsp, WMFW_HALO_YM_PACKED, + halo_alg[i].alg.id, + halo_alg[i].ym_base); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + } + +out: + kfree(halo_alg); + return ret; +} + +static int wm_adsp_load_coeff(struct wm_adsp *dsp) +{ + LIST_HEAD(buf_list); + struct regmap *regmap = dsp->regmap; + struct wmfw_coeff_hdr *hdr; + struct wmfw_coeff_item *blk; + const struct firmware *firmware; + const struct wm_adsp_region *mem; + struct wm_adsp_alg_region *alg_region; + const char *region_name; + int ret, pos, blocks, type, offset, reg; + char *file; + struct wm_adsp_buf *buf; + + file = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (file == NULL) + return -ENOMEM; + + snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.bin", dsp->part, dsp->num, + wm_adsp_fw[dsp->fw].file); + file[PAGE_SIZE - 1] = '\0'; + + ret = request_firmware(&firmware, file, dsp->dev); + if (ret != 0) { + adsp_warn(dsp, "Failed to request '%s'\n", file); + ret = 0; + goto out; + } + ret = -EINVAL; + + if (sizeof(*hdr) >= firmware->size) { + adsp_err(dsp, "%s: file too short, %zu bytes\n", file, + firmware->size); + goto out_fw; + } + + hdr = (void *)&firmware->data[0]; + if (memcmp(hdr->magic, "WMDR", 4) != 0) { + adsp_err(dsp, "%s: invalid magic\n", file); + goto out_fw; + } + + switch (be32_to_cpu(hdr->rev) & 0xff) { + case 1: + break; + default: + adsp_err(dsp, "%s: Unsupported coefficient file format %d\n", + file, be32_to_cpu(hdr->rev) & 0xff); + ret = -EINVAL; + goto out_fw; + } + + adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, + (le32_to_cpu(hdr->ver) >> 16) & 0xff, + (le32_to_cpu(hdr->ver) >> 8) & 0xff, + le32_to_cpu(hdr->ver) & 0xff); + + pos = le32_to_cpu(hdr->len); + + blocks = 0; + while (pos < firmware->size && pos - firmware->size > sizeof(*blk)) { + blk = (void *)(&firmware->data[pos]); + + type = le16_to_cpu(blk->type); + offset = le16_to_cpu(blk->offset); + + adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", file, blocks, + le32_to_cpu(blk->id), + (le32_to_cpu(blk->ver) >> 16) & 0xff, + (le32_to_cpu(blk->ver) >> 8) & 0xff, + le32_to_cpu(blk->ver) & 0xff); + adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", file, blocks, + le32_to_cpu(blk->len), offset, type); + + reg = 0; + region_name = "Unknown"; + switch (type) { + case (WMFW_NAME_TEXT << 8): + case (WMFW_INFO_TEXT << 8): + break; + case (WMFW_ABSOLUTE << 8): + /* + * Old files may use this for global + * coefficients. + */ + if (le32_to_cpu(blk->id) == dsp->fw_id && offset == 0) { + region_name = "global coefficients"; + mem = wm_adsp_find_region(dsp, type); + if (!mem) { + adsp_err(dsp, "No ZM\n"); + break; + } + reg = wm_adsp_region_to_reg(dsp, mem, 0); + + } else { + region_name = "register"; + reg = offset; + } + break; + + case WMFW_ADSP1_DM: + case WMFW_ADSP1_ZM: + case WMFW_ADSP2_XM: + case WMFW_ADSP2_YM: + case WMFW_HALO_XM_PACKED: + case WMFW_HALO_YM_PACKED: + case WMFW_HALO_PM_PACKED: + adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", file, + blocks, le32_to_cpu(blk->len), type, + le32_to_cpu(blk->id)); + + mem = wm_adsp_find_region(dsp, type); + if (!mem) { + adsp_err(dsp, "No base for region %x\n", type); + break; + } + + alg_region = wm_adsp_find_alg_region( + dsp, type, le32_to_cpu(blk->id)); + if (alg_region) { + reg = alg_region->base; + reg = wm_adsp_region_to_reg(dsp, mem, reg); + reg += offset; + } else { + adsp_err(dsp, "No %x for algorithm %x\n", type, + le32_to_cpu(blk->id)); + } + break; + + default: + adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", + file, blocks, type, pos); + break; + } + + if (reg) { + if ((pos + le32_to_cpu(blk->len) + sizeof(*blk)) > + firmware->size) { + adsp_err( + dsp, + "%s.%d: %s region len %d bytes exceeds file length %zu\n", + file, blocks, region_name, + le32_to_cpu(blk->len), firmware->size); + ret = -EINVAL; + goto out_fw; + } + + buf = wm_adsp_buf_alloc( + blk->data, le32_to_cpu(blk->len), &buf_list); + if (!buf) { + adsp_err(dsp, "Out of memory\n"); + ret = -ENOMEM; + goto out_fw; + } + + adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", file, + blocks, le32_to_cpu(blk->len), reg); + ret = regmap_raw_write_async(regmap, reg, buf->buf, + le32_to_cpu(blk->len)); + if (ret != 0) { + adsp_err( + dsp, + "%s.%d: Failed to write to %x in %s: %d\n", + file, blocks, reg, region_name, ret); + } + } + + pos += (le32_to_cpu(blk->len) + sizeof(*blk) + 3) & ~0x03; + blocks++; + } + + ret = regmap_async_complete(regmap); + if (ret != 0) + adsp_err(dsp, "Failed to complete async write: %d\n", ret); + + if (pos > firmware->size) + adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", file, + blocks, pos - firmware->size); + + wm_adsp_debugfs_save_binname(dsp, file); + +out_fw: + regmap_async_complete(regmap); + release_firmware(firmware); + wm_adsp_buf_free(&buf_list); +out: + kfree(file); + return ret; +} + +int wm_adsp1_init(struct wm_adsp *dsp) +{ + INIT_LIST_HEAD(&dsp->alg_regions); + + mutex_init(&dsp->pwr_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp1_init); + +int wm_adsp1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); + struct wm_adsp *dsp = &dsps[w->shift]; + struct wm_coeff_ctl *ctl; + int ret; + unsigned int val; + + dsp->codec = codec; + + mutex_lock(&dsp->pwr_lock); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, ADSP1_SYS_ENA); + + /* + * For simplicity set the DSP clock rate to be the + * SYSCLK rate rather than making it configurable. + */ + if (dsp->sysclk_reg) { + ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); + if (ret != 0) { + adsp_err(dsp, + "Failed to read SYSCLK state: %d\n", + ret); + goto err_mutex; + } + + val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; + + ret = regmap_update_bits(dsp->regmap, + dsp->base + ADSP1_CONTROL_31, + ADSP1_CLK_SEL_MASK, val); + if (ret != 0) { + adsp_err(dsp, "Failed to set clock rate: %d\n", + ret); + goto err_mutex; + } + } + + ret = wm_adsp_load(dsp); + if (ret != 0) + goto err_ena; + + ret = wm_adsp1_setup_algs(dsp); + if (ret != 0) + goto err_ena; + + ret = wm_adsp_load_coeff(dsp); + if (ret != 0) + goto err_ena; + + /* Initialize caches for enabled and unset controls */ + ret = wm_coeff_init_control_caches(dsp); + if (ret != 0) + goto err_ena; + + /* Sync set controls */ + ret = wm_coeff_sync_controls(dsp); + if (ret != 0) + goto err_ena; + + dsp->booted = true; + + /* Start the core running */ + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_CORE_ENA | ADSP1_START, + ADSP1_CORE_ENA | ADSP1_START); + + dsp->running = true; + break; + + case SND_SOC_DAPM_PRE_PMD: + dsp->running = false; + dsp->booted = false; + + /* Halt the core */ + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_CORE_ENA | ADSP1_START, 0); + + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, + ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); + + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, 0); + + list_for_each_entry (ctl, &dsp->ctl_list, list) + ctl->enabled = 0; + + wm_adsp_free_alg_regions(dsp); + break; + + default: + break; + } + + mutex_unlock(&dsp->pwr_lock); + + return 0; + +err_ena: + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, 0); +err_mutex: + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp1_event); + +static int wm_adsp2_ena(struct wm_adsp *dsp) +{ + unsigned int val; + int ret, count; + + switch (dsp->rev) { + case 0: + ret = regmap_update_bits_async(dsp->regmap, + dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA, ADSP2_SYS_ENA); + if (ret != 0) + return ret; + break; + default: + break; + } + + /* Wait for the RAM to start, should be near instantaneous */ + for (count = 0; count < 10; ++count) { + ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val); + if (ret != 0) + return ret; + + if (val & ADSP2_RAM_RDY) + break; + + usleep_range(250, 500); + } + + if (!(val & ADSP2_RAM_RDY)) { + adsp_err(dsp, "Failed to start DSP RAM\n"); + return -EBUSY; + } + + adsp_dbg(dsp, "RAM ready after %d polls\n", count); + + return 0; +} + +static void wm_adsp2_boot_work(struct work_struct *work) +{ + struct wm_adsp *dsp = container_of(work, struct wm_adsp, boot_work); + int ret; + + mutex_lock(&dsp->pwr_lock); + + ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, ADSP2_MEM_ENA); + if (ret != 0) + goto err_mutex; + + ret = wm_adsp2_ena(dsp); + if (ret != 0) + goto err_mem; + + ret = wm_adsp_load(dsp); + if (ret != 0) + goto err_ena; + + ret = wm_adsp2_setup_algs(dsp); + if (ret != 0) + goto err_ena; + + ret = wm_adsp_load_coeff(dsp); + if (ret != 0) + goto err_ena; + + /* Initialize caches for enabled and unset controls */ + ret = wm_coeff_init_control_caches(dsp); + if (ret != 0) + goto err_ena; + + switch (dsp->rev) { + case 0: + /* Turn DSP back off until we are ready to run */ + ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA, 0); + if (ret != 0) + goto err_ena; + break; + default: + break; + } + + dsp->booted = true; + + mutex_unlock(&dsp->pwr_lock); + + return; + +err_ena: + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); +err_mem: + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, 0); +err_mutex: + mutex_unlock(&dsp->pwr_lock); +} + +static int wm_halo_set_rate_block(struct wm_adsp *dsp, unsigned int rate_base, + unsigned int n_rates, const u8 *rate_cache) +{ + unsigned int addr = dsp->base + rate_base, val; + int ret, i; + + for (i = 0; i < n_rates; ++i) { + val = rate_cache[i] << HALO_DSP_RATE_SHIFT; + + ret = regmap_update_bits(dsp->regmap, addr + (i * 8), + HALO_DSP_RATE_MASK, val); + if (ret) { + adsp_err(dsp, "Failed to set rate: %d\n", ret); + return ret; + } + + adsp_dbg(dsp, "Set rate %d to 0x%x\n", i, val); + } + + return 0; +} + +static int wm_halo_clear_stream_arb(struct wm_adsp *dsp) +{ + struct regmap *regmap = dsp->regmap; + unsigned int dspbase = dsp->base, reg; + u32 values[3] = { 0, 0, 0 }; + int ret; + + /* disable stream arbiter masters */ + for (reg = dspbase + HALO_STREAM_ARB_MSTR0_CONFIG_0; + reg <= dspbase + HALO_STREAM_ARB_MSTR5_CONFIG_0; reg += 0x10) { + ret = regmap_update_bits(regmap, reg, + HALO_STREAM_ARB_MSTR_EN_MASK, 0); + if (ret) + goto error; + } + + /* clear stream arbiter masters */ + for (reg = dspbase + HALO_STREAM_ARB_MSTR0_CONFIG_0; + reg <= dspbase + HALO_STREAM_ARB_MSTR5_CONFIG_0; reg += 0x10) { + ret = regmap_bulk_write(regmap, reg, values, 3); + if (ret) + goto error; + } + + /* clear stream arbiter channel configs */ + for (reg = dspbase + HALO_STREAM_ARB_TX1_CONFIG_0; + reg <= dspbase + HALO_STREAM_ARB_RX8_CONFIG_0; reg += 0x8) { + ret = regmap_write(regmap, reg, + HALO_STREAM_ARB_MSTR_SEL_DEFAULT); + if (ret) + goto error; + } + + /* clear stream arbiter interrupt registers */ + values[0] = HALO_STREAM_ARB_MSTR_SEL_DEFAULT; + for (reg = dspbase + HALO_STREAM_ARB_IRQ0_CONFIG_0; + reg <= dspbase + HALO_STREAM_ARB_IRQ7_CONFIG_1; reg += 0x10) { + ret = regmap_bulk_write(regmap, reg, values, 2); + if (ret) + goto error; + } + return 0; + +error: + adsp_err(dsp, + "Error while clearing stream arbiter config (reg 0x%x): %d\n", + reg, ret); + return ret; +} + +static int wm_halo_configure_mpu(struct wm_adsp *dsp) +{ + struct regmap *regmap = dsp->regmap; + int i = 0, len = 0, ret; + unsigned int sysinfo_base = dsp->base_sysinfo, dsp_base = dsp->base; + unsigned int xm_sz, xm_bank_sz, ym_sz, ym_bank_sz; + unsigned int xm_acc_cfg, ym_acc_cfg; + unsigned int lock_cfg; + + ret = regmap_read(regmap, sysinfo_base + HALO_SYS_INFO_XM_BANK_SIZE, + &xm_bank_sz); + if (ret) { + adsp_err(dsp, "Failed to read XM bank size.\n"); + goto err; + } + + if (!xm_bank_sz) { + adsp_err(dsp, "Failed to configure MPU (XM_BANK_SIZE = 0)\n"); + goto err; + } + + ret = regmap_read(regmap, sysinfo_base + HALO_SYS_INFO_YM_BANK_SIZE, + &ym_bank_sz); + if (ret) { + adsp_err(dsp, "Failed to read YM bank size.\n"); + goto err; + } + + if (!ym_bank_sz) { + adsp_err(dsp, "Failed to configure MPU (YM_BANK_SIZE = 0)\n"); + goto err; + } + + ret = regmap_read(regmap, sysinfo_base + HALO_SYS_INFO_XM_SRAM_SIZE, + &xm_sz); + if (ret) { + adsp_err(dsp, "Failed to read XM size.\n"); + goto err; + } + + ret = regmap_read(regmap, sysinfo_base + HALO_SYS_INFO_YM_SRAM_SIZE, + &ym_sz); + if (ret) { + adsp_err(dsp, "Failed to read YM size.\n"); + goto err; + } + + adsp_dbg( + dsp, + "XM size 0x%x XM bank size 0x%x YM size 0x%x YM bank size 0x%x\n", + xm_sz, xm_bank_sz, ym_sz, ym_bank_sz); + + /* calculate amount of banks to unlock */ + xm_acc_cfg = (1 << (xm_sz / xm_bank_sz)) - 1; + ym_acc_cfg = (1 << (ym_sz / ym_bank_sz)) - 1; + + /* unlock MPU */ + ret = regmap_write(regmap, dsp_base + HALO_MPU_LOCK_CONFIG, + HALO_MPU_UNLOCK_CODE_0); + if (ret) { + adsp_err(dsp, "Error while unlocking MPU: %d\n", ret); + goto err; + } + + ret = regmap_write(regmap, dsp_base + HALO_MPU_LOCK_CONFIG, + HALO_MPU_UNLOCK_CODE_1); + if (ret) { + adsp_err(dsp, "Error while unlocking MPU: %d\n", ret); + goto err; + } + + adsp_dbg(dsp, "Unlocking XM (cfg: %x) and YM (cfg: %x)", xm_acc_cfg, + ym_acc_cfg); + + /* unlock XMEM and YMEM */ + ret = regmap_write(regmap, dsp_base + HALO_MPU_XMEM_ACCESS_0, + xm_acc_cfg); + if (ret) + goto err; + + ret = regmap_write(regmap, dsp_base + HALO_MPU_YMEM_ACCESS_0, + ym_acc_cfg); + if (ret) + goto err; + + len = sizeof(halo_mpu_access) / sizeof(halo_mpu_access[0]); + lock_cfg = (dsp->unlock_all) ? 0xFFFFFFFF : 0; + /* configure all other banks */ + for (i = 0; i < len; i++) { /* TODO: think if can be done without LUT */ + ret = regmap_write(regmap, dsp_base + halo_mpu_access[i], + lock_cfg); + if (ret) + goto err; + } + + /* lock MPU */ + ret = regmap_write(regmap, dsp_base + HALO_MPU_LOCK_CONFIG, 0); + if (ret) + adsp_err(dsp, "Error while locking MPU: %d\n", ret); + +err: + return ret; +} + +static void wm_halo_boot_work(struct work_struct *work) +{ + struct wm_adsp *dsp = container_of(work, struct wm_adsp, boot_work); + int ret; + + mutex_lock(&dsp->pwr_lock); + + ret = wm_adsp_load(dsp); + if (ret != 0) + goto err; + + switch (dsp->fw_ver) { + case 1: + case 2: + ret = wm_adsp2_setup_algs(dsp); + if (ret != 0) + goto err; + break; + default: + ret = wm_halo_setup_algs(dsp); + if (ret != 0) + goto err; + break; + } + + ret = wm_adsp_load_coeff(dsp); + if (ret != 0) + goto err; + + /* Initialize caches for enabled and unset controls */ + ret = wm_coeff_init_control_caches(dsp); + if (ret != 0) + goto err; + + dsp->booted = true; + + mutex_unlock(&dsp->pwr_lock); + + return; + +err: + regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, + HALO_CORE_EN, 0); + mutex_unlock(&dsp->pwr_lock); +} + +static void wm_adsp2_set_dspclk(struct wm_adsp *dsp, unsigned int freq) +{ + int ret; + + switch (dsp->rev) { + case 0: + ret = regmap_update_bits_async(dsp->regmap, + dsp->base + ADSP2_CLOCKING, + ADSP2_CLK_SEL_MASK, + freq << ADSP2_CLK_SEL_SHIFT); + if (ret) { + adsp_err(dsp, "Failed to set clock rate: %d\n", ret); + return; + } + break; + default: + /* clock is handled by parent codec driver */ + break; + } +} + +int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = dsp->preloaded; + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp2_preloader_get); + +int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + char preload[32]; + + snprintf(preload, ARRAY_SIZE(preload), "DSP%u Preload", mc->shift); + + dsp->preloaded = ucontrol->value.integer.value[0]; + + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_force_enable_pin(dapm, preload); + else + snd_soc_dapm_disable_pin(dapm, preload); + + snd_soc_dapm_sync(dapm); + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put); + +static void wm_adsp_stop_watchdog(struct wm_adsp *dsp) +{ + switch (dsp->rev) { + case 0: + case 1: + return; + default: + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG, + ADSP2_WDT_ENA_MASK, 0); + } +} + +int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event, + unsigned int freq) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); + struct wm_adsp *dsp = &dsps[w->shift]; + struct wm_coeff_ctl *ctl; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wm_adsp2_set_dspclk(dsp, freq); + queue_work(system_unbound_wq, &dsp->boot_work); + break; + case SND_SOC_DAPM_PRE_PMD: + mutex_lock(&dsp->pwr_lock); + + wm_adsp_debugfs_clear(dsp); + + dsp->fw_id = 0; + dsp->fw_id_version = 0; + + dsp->booted = false; + + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, 0); + + list_for_each_entry (ctl, &dsp->ctl_list, list) + ctl->enabled = 0; + + wm_adsp_free_alg_regions(dsp); + + mutex_unlock(&dsp->pwr_lock); + + adsp_dbg(dsp, "Shutdown complete\n"); + break; + default: + break; + } + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp2_early_event); + +int wm_halo_early_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); + struct wm_adsp *dsp = &dsps[w->shift]; + struct wm_coeff_ctl *ctl; + int ret; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = regmap_update_bits(dsp->regmap, + dsp->base + HALO_CCM_CORE_CONTROL, + HALO_CORE_RESET, HALO_CORE_RESET); + if (ret != 0) { + adsp_err(dsp, "Error while resetting core: %d\n", ret); + return ret; + } + + queue_work(system_unbound_wq, &dsp->boot_work); + break; + case SND_SOC_DAPM_PRE_PMD: + mutex_lock(&dsp->pwr_lock); + + wm_adsp_debugfs_clear(dsp); + + dsp->fw_id = 0; + dsp->fw_id_version = 0; + + dsp->booted = false; + + list_for_each_entry (ctl, &dsp->ctl_list, list) + ctl->enabled = 0; + + wm_adsp_free_alg_regions(dsp); + + mutex_unlock(&dsp->pwr_lock); + + adsp_dbg(dsp, "Shutdown complete\n"); + break; + default: + break; + } + + return 0; +} +EXPORT_SYMBOL_GPL(wm_halo_early_event); + +int wm_adsp2_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); + struct wm_adsp *dsp = &dsps[w->shift]; + int ret; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + flush_work(&dsp->boot_work); + + mutex_lock(&dsp->pwr_lock); + + if (!dsp->booted) { + ret = -EIO; + goto err; + } + + ret = wm_adsp2_ena(dsp); + if (ret != 0) + goto err; + + /* Sync set controls */ + ret = wm_coeff_sync_controls(dsp); + if (ret != 0) + goto err; + + wm_adsp2_lock(dsp, dsp->lock_regions); + + ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_CORE_ENA | ADSP2_START, + ADSP2_CORE_ENA | ADSP2_START); + if (ret != 0) + goto err; + + if (wm_adsp_fw[dsp->fw].num_caps != 0) { + ret = wm_adsp_buffer_init(dsp); + if (ret < 0) + goto err; + } + + dsp->running = true; + + mutex_unlock(&dsp->pwr_lock); + + break; + + case SND_SOC_DAPM_PRE_PMD: + /* Tell the firmware to cleanup */ + wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN); + + wm_adsp_stop_watchdog(dsp); + + /* Log firmware state, it can be useful for analysis */ + switch (dsp->rev) { + case 0: + wm_adsp2_show_fw_status(dsp); + break; + default: + wm_adsp2v2_show_fw_status(dsp); + break; + } + + mutex_lock(&dsp->pwr_lock); + + dsp->running = false; + + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_CORE_ENA | ADSP2_START, 0); + + /* Make sure DMAs are quiesced */ + switch (dsp->rev) { + case 0: + regmap_write(dsp->regmap, + dsp->base + ADSP2_RDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, + dsp->base + ADSP2_WDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, + dsp->base + ADSP2_WDMA_CONFIG_2, 0); + + regmap_update_bits(dsp->regmap, + dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA, 0); + break; + default: + regmap_write(dsp->regmap, + dsp->base + ADSP2_RDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, + dsp->base + ADSP2_WDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, + dsp->base + ADSP2V2_WDMA_CONFIG_2, 0); + break; + } + + if (wm_adsp_fw[dsp->fw].num_caps != 0) + wm_adsp_buffer_free(dsp); + + mutex_unlock(&dsp->pwr_lock); + + adsp_dbg(dsp, "Execution stopped\n"); + break; + + default: + break; + } + + return 0; +err: + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); + mutex_unlock(&dsp->pwr_lock); + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp2_event); + +int wm_halo_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); + struct wm_adsp *dsp = &dsps[w->shift]; + int ret; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + flush_work(&dsp->boot_work); + + mutex_lock(&dsp->pwr_lock); + + if (!dsp->booted) { + ret = -EIO; + goto err; + } + wm_halo_apply_calibration(w); + /* Sync set controls */ + ret = wm_coeff_sync_controls(dsp); + if (ret != 0) + goto err; + + //wm_halo_apply_calibration(w); + + adsp_dbg(dsp, "Setting RX rates.\n"); + ret = wm_halo_set_rate_block(dsp, HALO_SAMPLE_RATE_RX1, + dsp->n_rx_rates, + dsp->rx_rate_cache); + if (ret) { + adsp_err(dsp, "Failed to set RX rates.\n"); + goto err; + } + + adsp_dbg(dsp, "Setting TX rates.\n"); + ret = wm_halo_set_rate_block(dsp, HALO_SAMPLE_RATE_TX1, + dsp->n_tx_rates, + dsp->tx_rate_cache); + if (ret) { + adsp_err(dsp, "Failed to set TX rates.\n"); + goto err; + } + + ret = wm_halo_clear_stream_arb(dsp); + if (ret != 0) + goto err; + + /* disable NMI */ + ret = regmap_write(dsp->regmap, + dsp->base + HALO_INTP_CTL_NMI_CONTROL, 0); + if (ret != 0) { + adsp_err(dsp, "Error while disabling NMI: %d\n", ret); + goto err; + } + + ret = wm_halo_configure_mpu(dsp); + if (ret != 0) + goto err; + + ret = regmap_update_bits(dsp->regmap, + dsp->base + HALO_CCM_CORE_CONTROL, + HALO_CORE_EN, HALO_CORE_EN); + + if (ret != 0) + goto err; + + if (wm_adsp_fw[dsp->fw].num_caps != 0) { + ret = wm_adsp_buffer_init(dsp); + if (ret < 0) + goto err; + } + + dsp->running = true; + + mutex_unlock(&dsp->pwr_lock); + + break; + case SND_SOC_DAPM_PRE_PMD: + /* Tell the firmware to cleanup */ + wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN); + + /* Log firmware state, it can be useful for analysis */ + wm_halo_show_fw_status(dsp); + + mutex_lock(&dsp->pwr_lock); + + dsp->running = false; + + regmap_update_bits(dsp->regmap, + dsp->base + HALO_CCM_CORE_CONTROL, + HALO_CORE_EN, 0); + + wm_halo_clear_stream_arb(dsp); + + if (wm_adsp_fw[dsp->fw].num_caps != 0) + wm_adsp_buffer_free(dsp); + + mutex_unlock(&dsp->pwr_lock); + + adsp_info(dsp, "Execution stopped\n"); + break; + default: + break; + } + + return 0; +err: + mutex_unlock(&dsp->pwr_lock); + regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, + HALO_CORE_EN, 0); + return ret; +} +EXPORT_SYMBOL_GPL(wm_halo_event); + +static int wm_coeff_k_put(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + char *p = ucontrol->value.bytes.data; + int ret = 0; + + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { + ret = 0; + } else + memcpy(ctl->cache, p, ctl->len); + + ctl->set = 1; + ret = wm_coeff_write_control(ctl, p, ctl->len); + + return ret; +} +static int wm_coeff_k_get(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + char *p = ucontrol->value.bytes.data; + int ret = 0; + + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { + ret = wm_coeff_read_control(ctl, p, ctl->len); + } else { + ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); + memcpy(p, ctl->cache, ctl->len); + } + + return ret; +} +static int wm_adsp_k_ctl_put(struct wm_adsp *dsp, const char *name, int value) +{ + struct snd_kcontrol *kctl = NULL; + struct snd_ctl_elem_value ucontrol; + struct snd_soc_card *card = dsp->codec->component.card; + + kctl = snd_soc_card_get_kcontrol(card, name); + if (kctl == NULL) { + adsp_warn(dsp, "%s: %s isn't found\n", __func__, name); + return -1; + } + + adsp_dbg(dsp, "%s: %s:0x%x\n", __func__, kctl->id.name, value); + value = cpu_to_be32(value); + memcpy((char *)ucontrol.value.bytes.data, (char *)&value, + sizeof(value)); + wm_coeff_k_put(kctl, &ucontrol); + + return 0; +} + +static int wm_adsp_k_ctl_get(struct wm_adsp *dsp, const char *name) +{ + struct snd_kcontrol *kctl = NULL; + struct snd_ctl_elem_value ucontrol; + struct snd_soc_card *card = dsp->codec->component.card; + + int value = 0; + + kctl = snd_soc_card_get_kcontrol(card, name); + if (kctl == NULL) { + adsp_warn(dsp, "%s: %s isn't found\n", __func__, name); + return -1; + } + + wm_coeff_k_get(kctl, &ucontrol); + memcpy((char *)&value, (char *)ucontrol.value.bytes.data, + sizeof(value)); + value = be32_to_cpu(value); + + adsp_dbg(dsp, "%s: %s:0x%x\n", __func__, kctl->id.name, value); + + return 0; +} + +static int wm_halo_apply_calibration(struct snd_soc_dapm_widget *w) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); + struct wm_adsp *dsp = &dsps[w->shift]; + + switch (dsp->fw) { + case WM_ADSP_FW_CALIB: + adsp_warn(dsp, "Set ambient %d, only for Z Diagnostic\n", + dsp->ambient); + wm_adsp_k_ctl_put(dsp, "DSP1X Diag Z cd CAL_AMBIENT", + dsp->ambient); + break; + case WM_ADSP_FW_DIAG: + adsp_warn(dsp, "Set ambient %d, only for Diagnostic\n", + dsp->ambient); + wm_adsp_k_ctl_put(dsp, "DSP1X Diag cd CAL_AMBIENT", + dsp->ambient); + break; + case WM_ADSP_FW_SPK_PROT: + wm_adsp_k_ctl_put(dsp, "DSP1X Protection cd CAL_R", dsp->cal_z); + wm_adsp_k_ctl_put(dsp, "DSP1X Protection cd CAL_STATUS", + dsp->cal_status); + wm_adsp_k_ctl_put(dsp, "DSP1X Protection cd CAL_CHECKSUM", + dsp->cal_chksum); + wm_adsp_k_ctl_get(dsp, "DSP1X Protection cd CAL_R"); + wm_adsp_k_ctl_get(dsp, "DSP1X Protection cd CAL_STATUS"); + wm_adsp_k_ctl_get(dsp, "DSP1X Protection cd CAL_CHECKSUM"); + break; + default: + break; + } + + adsp_warn(dsp, "Do thing'\n"); + return 0; +} + +int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + char preload[32]; + + snprintf(preload, ARRAY_SIZE(preload), "DSP%d Preload", dsp->num); + snd_soc_dapm_disable_pin(dapm, preload); + + wm_adsp2_init_debugfs(dsp, codec); + + dsp->codec = codec; + + snd_soc_add_codec_controls(codec, wm_adsp_cal_controls, + ARRAY_SIZE(wm_adsp_cal_controls)); + + return snd_soc_add_codec_controls( + codec, &wm_adsp_fw_controls[dsp->num - 1], 1); +} +EXPORT_SYMBOL_GPL(wm_adsp2_codec_probe); + +int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec) +{ + wm_adsp2_cleanup_debugfs(dsp); + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp2_codec_remove); + +int wm_adsp2_init(struct wm_adsp *dsp) +{ + int ret; + + switch (dsp->rev) { + case 0: + /* + * Disable the DSP memory by default when in reset for a small + * power saving. + */ + ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, 0); + if (ret) { + adsp_err(dsp, "Failed to clear memory retention: %d\n", + ret); + return ret; + } + break; + default: + break; + } + + INIT_LIST_HEAD(&dsp->alg_regions); + INIT_LIST_HEAD(&dsp->ctl_list); + INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work); + + mutex_init(&dsp->pwr_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp2_init); + +int wm_halo_init(struct wm_adsp *dsp) +{ + INIT_LIST_HEAD(&dsp->alg_regions); + INIT_LIST_HEAD(&dsp->ctl_list); + INIT_WORK(&dsp->boot_work, wm_halo_boot_work); + + mutex_init(&dsp->pwr_lock); + + dsp->rx_rate_cache = kcalloc(dsp->n_rx_rates, sizeof(u8), GFP_KERNEL); + dsp->tx_rate_cache = kcalloc(dsp->n_tx_rates, sizeof(u8), GFP_KERNEL); + + dsp->ambient = AMBIENT_DEFAULT; + dsp->cal_z = CAL_R_DEFAULT; + dsp->cal_status = CAL_STATUS_DEFAULT; + dsp->cal_chksum = CAL_R_DEFAULT + CAL_STATUS_DEFAULT; + return 0; +} +EXPORT_SYMBOL_GPL(wm_halo_init); + +void wm_adsp2_remove(struct wm_adsp *dsp) +{ + struct wm_coeff_ctl *ctl; + + while (!list_empty(&dsp->ctl_list)) { + ctl = list_first_entry(&dsp->ctl_list, struct wm_coeff_ctl, + list); + list_del(&ctl->list); + wm_adsp_free_ctl_blk(ctl); + } + + kfree(dsp->rx_rate_cache); + kfree(dsp->tx_rate_cache); +} +EXPORT_SYMBOL_GPL(wm_adsp2_remove); + +static inline int wm_adsp_compr_attached(struct wm_adsp_compr *compr) +{ + return compr->buf != NULL; +} + +static int wm_adsp_compr_attach(struct wm_adsp_compr *compr) +{ + /* + * Note this will be more complex once each DSP can support multiple + * streams + */ + if (!compr->dsp->buffer) + return -EINVAL; + + compr->buf = compr->dsp->buffer; + compr->buf->compr = compr; + + return 0; +} + +static void wm_adsp_compr_detach(struct wm_adsp_compr *compr) +{ + if (!compr) + return; + + /* Wake the poll so it can see buffer is no longer attached */ + if (compr->stream) + snd_compr_fragment_elapsed(compr->stream); + + if (wm_adsp_compr_attached(compr)) { + compr->buf->compr = NULL; + compr->buf = NULL; + } +} + +int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) +{ + struct wm_adsp_compr *compr; + int ret = 0; + + mutex_lock(&dsp->pwr_lock); + + if (wm_adsp_fw[dsp->fw].num_caps == 0) { + adsp_err(dsp, "Firmware does not support compressed API\n"); + ret = -ENXIO; + goto out; + } + + if (wm_adsp_fw[dsp->fw].compr_direction != stream->direction) { + adsp_err(dsp, "Firmware does not support stream direction\n"); + ret = -EINVAL; + goto out; + } + + if (dsp->compr) { + /* It is expect this limitation will be removed in future */ + adsp_err(dsp, "Only a single stream supported per DSP\n"); + ret = -EBUSY; + goto out; + } + + compr = kzalloc(sizeof(*compr), GFP_KERNEL); + if (!compr) { + ret = -ENOMEM; + goto out; + } + + compr->dsp = dsp; + compr->stream = stream; + + dsp->compr = compr; + + stream->runtime->private_data = compr; + +out: + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_open); + +int wm_adsp_compr_free(struct snd_compr_stream *stream) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + struct wm_adsp *dsp = compr->dsp; + + mutex_lock(&dsp->pwr_lock); + + wm_adsp_compr_detach(compr); + dsp->compr = NULL; + + kfree(compr->raw_buf); + kfree(compr); + + mutex_unlock(&dsp->pwr_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_free); + +static int wm_adsp_compr_check_params(struct snd_compr_stream *stream, + struct snd_compr_params *params) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + struct wm_adsp *dsp = compr->dsp; + const struct wm_adsp_fw_caps *caps; + const struct snd_codec_desc *desc; + int i, j; + + if (params->buffer.fragment_size < WM_ADSP_MIN_FRAGMENT_SIZE || + params->buffer.fragment_size > WM_ADSP_MAX_FRAGMENT_SIZE || + params->buffer.fragments < WM_ADSP_MIN_FRAGMENTS || + params->buffer.fragments > WM_ADSP_MAX_FRAGMENTS || + params->buffer.fragment_size % WM_ADSP_DATA_WORD_SIZE) { + adsp_err(dsp, "Invalid buffer fragsize=%d fragments=%d\n", + params->buffer.fragment_size, + params->buffer.fragments); + + return -EINVAL; + } + + for (i = 0; i < wm_adsp_fw[dsp->fw].num_caps; i++) { + caps = &wm_adsp_fw[dsp->fw].caps[i]; + desc = &caps->desc; + + if (caps->id != params->codec.id) + continue; + + if (stream->direction == SND_COMPRESS_PLAYBACK) { + if (desc->max_ch < params->codec.ch_out) + continue; + } else { + if (desc->max_ch < params->codec.ch_in) + continue; + } + + if (!(desc->formats & (1 << params->codec.format))) + continue; + + for (j = 0; j < desc->num_sample_rates; ++j) + if (desc->sample_rates[j] == params->codec.sample_rate) + return 0; + } + + adsp_err(dsp, "Invalid params id=%u ch=%u,%u rate=%u fmt=%u\n", + params->codec.id, params->codec.ch_in, params->codec.ch_out, + params->codec.sample_rate, params->codec.format); + return -EINVAL; +} + +static inline unsigned int wm_adsp_compr_frag_words(struct wm_adsp_compr *compr) +{ + return compr->size.fragment_size / WM_ADSP_DATA_WORD_SIZE; +} + +int wm_adsp_compr_set_params(struct snd_compr_stream *stream, + struct snd_compr_params *params) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + unsigned int size; + int ret; + + ret = wm_adsp_compr_check_params(stream, params); + if (ret) + return ret; + + compr->size = params->buffer; + + adsp_dbg(compr->dsp, "fragment_size=%d fragments=%d\n", + compr->size.fragment_size, compr->size.fragments); + + size = wm_adsp_compr_frag_words(compr) * sizeof(*compr->raw_buf); + compr->raw_buf = kmalloc(size, GFP_DMA | GFP_KERNEL); + if (!compr->raw_buf) + return -ENOMEM; + + compr->sample_rate = params->codec.sample_rate; + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_set_params); + +int wm_adsp_compr_get_caps(struct snd_compr_stream *stream, + struct snd_compr_caps *caps) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + int fw = compr->dsp->fw; + int i; + + if (wm_adsp_fw[fw].caps) { + for (i = 0; i < wm_adsp_fw[fw].num_caps; i++) + caps->codecs[i] = wm_adsp_fw[fw].caps[i].id; + + caps->num_codecs = i; + caps->direction = wm_adsp_fw[fw].compr_direction; + + caps->min_fragment_size = WM_ADSP_MIN_FRAGMENT_SIZE; + caps->max_fragment_size = WM_ADSP_MAX_FRAGMENT_SIZE; + caps->min_fragments = WM_ADSP_MIN_FRAGMENTS; + caps->max_fragments = WM_ADSP_MAX_FRAGMENTS; + } + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps); + +static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type, + unsigned int mem_addr, + unsigned int num_words, u32 *data) +{ + struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); + unsigned int i, reg; + int ret; + + if (!mem) + return -EINVAL; + + reg = wm_adsp_region_to_reg(dsp, mem, mem_addr); + + ret = wm_adsp2_raw_read(MAXBULK, dsp->regmap, reg, data, + sizeof(*data) * num_words); + if (ret < 0) + return ret; + + for (i = 0; i < num_words; ++i) + data[i] = be32_to_cpu(data[i]) & 0x00ffffffu; + + return 0; +} + +static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, + unsigned int mem_addr, u32 *data) +{ + return wm_adsp_read_data_block(dsp, mem_type, mem_addr, 1, data); +} + +static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, + unsigned int mem_addr, u32 data) +{ + struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); + unsigned int reg; + + if (!mem) + return -EINVAL; + + reg = wm_adsp_region_to_reg(dsp, mem, mem_addr); + + data = cpu_to_be32(data & 0x00ffffffu); + + return regmap_raw_write(dsp->regmap, reg, &data, sizeof(data)); +} + +static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf, + unsigned int field_offset, u32 *data) +{ + return wm_adsp_read_data_word(buf->dsp, WMFW_ADSP2_XM, + buf->host_buf_ptr + field_offset, data); +} + +static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, + unsigned int field_offset, u32 data) +{ + return wm_adsp_write_data_word(buf->dsp, WMFW_ADSP2_XM, + buf->host_buf_ptr + field_offset, data); +} + +static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf) +{ + struct wm_adsp_alg_region *alg_region; + struct wm_adsp *dsp = buf->dsp; + u32 xmalg, addr, magic; + int i, ret; + + alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); + xmalg = sizeof(struct wm_adsp_system_config_xm_hdr) / sizeof(__be32); + + addr = alg_region->base + xmalg + ALG_XM_FIELD(magic); + ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic); + if (ret < 0) + return ret; + + if (magic != WM_ADSP_ALG_XM_STRUCT_MAGIC) + return -EINVAL; + + addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr); + for (i = 0; i < 5; ++i) { + ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, + &buf->host_buf_ptr); + if (ret < 0) + return ret; + + if (buf->host_buf_ptr) + break; + + usleep_range(1000, 2000); + } + + if (!buf->host_buf_ptr) + return -EIO; + + adsp_dbg(dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); + + return 0; +} + +static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) +{ + const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps; + struct wm_adsp_buffer_region *region; + u32 offset = 0; + int i, ret; + + for (i = 0; i < caps->num_regions; ++i) { + region = &buf->regions[i]; + + region->offset = offset; + region->mem_type = caps->region_defs[i].mem_type; + + ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset, + ®ion->base_addr); + if (ret < 0) + return ret; + + ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset, + &offset); + if (ret < 0) + return ret; + + region->cumulative_size = offset; + + adsp_dbg(buf->dsp, + "region=%d type=%d base=%04x off=%04x size=%04x\n", i, + region->mem_type, region->base_addr, region->offset, + region->cumulative_size); + } + + return 0; +} + +static int wm_adsp_buffer_init(struct wm_adsp *dsp) +{ + struct wm_adsp_compr_buf *buf; + int ret; + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return -ENOMEM; + + buf->dsp = dsp; + buf->read_index = -1; + buf->irq_count = 0xFFFFFFFF; + + ret = wm_adsp_buffer_locate(buf); + if (ret < 0) { + adsp_err(dsp, "Failed to acquire host buffer: %d\n", ret); + goto err_buffer; + } + + buf->regions = kcalloc(wm_adsp_fw[dsp->fw].caps->num_regions, + sizeof(*buf->regions), GFP_KERNEL); + if (!buf->regions) { + ret = -ENOMEM; + goto err_buffer; + } + + ret = wm_adsp_buffer_populate(buf); + if (ret < 0) { + adsp_err(dsp, "Failed to populate host buffer: %d\n", ret); + goto err_regions; + } + + dsp->buffer = buf; + + return 0; + +err_regions: + kfree(buf->regions); +err_buffer: + kfree(buf); + return ret; +} + +static int wm_adsp_buffer_free(struct wm_adsp *dsp) +{ + if (dsp->buffer) { + wm_adsp_compr_detach(dsp->buffer->compr); + + kfree(dsp->buffer->regions); + kfree(dsp->buffer); + + dsp->buffer = NULL; + } + + return 0; +} + +int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + struct wm_adsp *dsp = compr->dsp; + int ret = 0; + + adsp_dbg(dsp, "Trigger: %d\n", cmd); + + mutex_lock(&dsp->pwr_lock); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + if (wm_adsp_compr_attached(compr)) + break; + + ret = wm_adsp_compr_attach(compr); + if (ret < 0) { + adsp_err(dsp, "Failed to link buffer and stream: %d\n", + ret); + break; + } + + /* Trigger the IRQ at one fragment of data */ + ret = wm_adsp_buffer_write(compr->buf, + HOST_BUFFER_FIELD(high_water_mark), + wm_adsp_compr_frag_words(compr)); + if (ret < 0) { + adsp_err(dsp, "Failed to set high water mark: %d\n", + ret); + break; + } + break; + case SNDRV_PCM_TRIGGER_STOP: + break; + default: + ret = -EINVAL; + break; + } + + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_trigger); + +static inline int wm_adsp_buffer_size(struct wm_adsp_compr_buf *buf) +{ + int last_region = wm_adsp_fw[buf->dsp->fw].caps->num_regions - 1; + + return buf->regions[last_region].cumulative_size; +} + +static int wm_adsp_buffer_update_avail(struct wm_adsp_compr_buf *buf) +{ + u32 next_read_index, next_write_index; + int write_index, read_index, avail; + int ret; + + /* Only sync read index if we haven't already read a valid index */ + if (buf->read_index < 0) { + ret = wm_adsp_buffer_read(buf, + HOST_BUFFER_FIELD(next_read_index), + &next_read_index); + if (ret < 0) + return ret; + + read_index = sign_extend32(next_read_index, 23); + + if (read_index < 0) { + adsp_dbg(buf->dsp, "Avail check on unstarted stream\n"); + return 0; + } + + buf->read_index = read_index; + } + + ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(next_write_index), + &next_write_index); + if (ret < 0) + return ret; + + write_index = sign_extend32(next_write_index, 23); + + avail = write_index - buf->read_index; + if (avail < 0) + avail += wm_adsp_buffer_size(buf); + + adsp_dbg(buf->dsp, "readindex=0x%x, writeindex=0x%x, avail=%d\n", + buf->read_index, write_index, avail * WM_ADSP_DATA_WORD_SIZE); + + buf->avail = avail; + + return 0; +} + +static int wm_adsp_buffer_get_error(struct wm_adsp_compr_buf *buf) +{ + int ret; + + ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error); + if (ret < 0) { + adsp_err(buf->dsp, "Failed to check buffer error: %d\n", ret); + return ret; + } + if (buf->error != 0) { + adsp_err(buf->dsp, "Buffer error occurred: %d\n", buf->error); + return -EIO; + } + + return 0; +} + +int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) +{ + struct wm_adsp_compr_buf *buf; + struct wm_adsp_compr *compr; + int ret = 0; + + mutex_lock(&dsp->pwr_lock); + + buf = dsp->buffer; + compr = dsp->compr; + + if (!buf) { + ret = -ENODEV; + goto out; + } + + adsp_dbg(dsp, "Handling buffer IRQ\n"); + + ret = wm_adsp_buffer_get_error(buf); + if (ret < 0) + goto out_notify; /* Wake poll to report error */ + + ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(irq_count), + &buf->irq_count); + if (ret < 0) { + adsp_err(dsp, "Failed to get irq_count: %d\n", ret); + goto out; + } + + ret = wm_adsp_buffer_update_avail(buf); + if (ret < 0) { + adsp_err(dsp, "Error reading avail: %d\n", ret); + goto out; + } + + if (wm_adsp_fw[dsp->fw].voice_trigger && buf->irq_count == 2) + ret = WM_ADSP_COMPR_VOICE_TRIGGER; + +out_notify: + if (compr && compr->stream) + snd_compr_fragment_elapsed(compr->stream); + +out: + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_handle_irq); + +static int wm_adsp_buffer_reenable_irq(struct wm_adsp_compr_buf *buf) +{ + if (buf->irq_count & 0x01) + return 0; + + adsp_dbg(buf->dsp, "Enable IRQ(0x%x) for next fragment\n", + buf->irq_count); + + buf->irq_count |= 0x01; + + return wm_adsp_buffer_write(buf, HOST_BUFFER_FIELD(irq_ack), + buf->irq_count); +} + +int wm_adsp_compr_pointer(struct snd_compr_stream *stream, + struct snd_compr_tstamp *tstamp) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + struct wm_adsp *dsp = compr->dsp; + struct wm_adsp_compr_buf *buf; + int ret = 0; + + adsp_dbg(dsp, "Pointer request\n"); + + mutex_lock(&dsp->pwr_lock); + + buf = compr->buf; + + if (!compr->buf || compr->buf->error) { + snd_compr_stop_error(stream, SNDRV_PCM_STATE_XRUN); + ret = -EIO; + goto out; + } + + if (buf->avail < wm_adsp_compr_frag_words(compr)) { + ret = wm_adsp_buffer_update_avail(buf); + if (ret < 0) { + adsp_err(dsp, "Error reading avail: %d\n", ret); + goto out; + } + + /* + * If we really have less than 1 fragment available tell the + * DSP to inform us once a whole fragment is available. + */ + if (buf->avail < wm_adsp_compr_frag_words(compr)) { + ret = wm_adsp_buffer_get_error(buf); + if (ret < 0) { + if (compr->buf->error) + snd_compr_stop_error( + stream, SNDRV_PCM_STATE_XRUN); + goto out; + } + + ret = wm_adsp_buffer_reenable_irq(buf); + if (ret < 0) { + adsp_err(dsp, + "Failed to re-enable buffer IRQ: %d\n", + ret); + goto out; + } + } + } + + tstamp->copied_total = compr->copied_total; + tstamp->copied_total += buf->avail * WM_ADSP_DATA_WORD_SIZE; + tstamp->sampling_rate = compr->sample_rate; + +out: + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_pointer); + +static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) +{ + struct wm_adsp_compr_buf *buf = compr->buf; + u8 *pack_in = (u8 *)compr->raw_buf; + u8 *pack_out = (u8 *)compr->raw_buf; + unsigned int adsp_addr; + int mem_type, nwords, max_read; + int i, j, ret; + + /* Calculate read parameters */ + for (i = 0; i < wm_adsp_fw[buf->dsp->fw].caps->num_regions; ++i) + if (buf->read_index < buf->regions[i].cumulative_size) + break; + + if (i == wm_adsp_fw[buf->dsp->fw].caps->num_regions) + return -EINVAL; + + mem_type = buf->regions[i].mem_type; + adsp_addr = buf->regions[i].base_addr + + (buf->read_index - buf->regions[i].offset); + + max_read = wm_adsp_compr_frag_words(compr); + nwords = buf->regions[i].cumulative_size - buf->read_index; + + if (nwords > target) + nwords = target; + if (nwords > buf->avail) + nwords = buf->avail; + if (nwords > max_read) + nwords = max_read; + if (!nwords) + return 0; + + /* Read data from DSP */ + ret = wm_adsp_read_data_block(buf->dsp, mem_type, adsp_addr, nwords, + compr->raw_buf); + if (ret < 0) + return ret; + + /* Remove the padding bytes from the data read from the DSP */ + for (i = 0; i < nwords; i++) { + for (j = 0; j < WM_ADSP_DATA_WORD_SIZE; j++) + *pack_out++ = *pack_in++; + + pack_in += sizeof(*(compr->raw_buf)) - WM_ADSP_DATA_WORD_SIZE; + } + + /* update read index to account for words read */ + buf->read_index += nwords; + if (buf->read_index == wm_adsp_buffer_size(buf)) + buf->read_index = 0; + + ret = wm_adsp_buffer_write(buf, HOST_BUFFER_FIELD(next_read_index), + buf->read_index); + if (ret < 0) + return ret; + + /* update avail to account for words read */ + buf->avail -= nwords; + + return nwords; +} + +static int wm_adsp_compr_read(struct wm_adsp_compr *compr, char __user *buf, + size_t count) +{ + struct wm_adsp *dsp = compr->dsp; + int ntotal = 0; + int nwords, nbytes; + + adsp_dbg(dsp, "Requested read of %zu bytes\n", count); + + if (!compr->buf || compr->buf->error) { + snd_compr_stop_error(compr->stream, SNDRV_PCM_STATE_XRUN); + return -EIO; + } + + count /= WM_ADSP_DATA_WORD_SIZE; + + do { + nwords = wm_adsp_buffer_capture_block(compr, count); + if (nwords < 0) { + adsp_err(dsp, "Failed to capture block: %d\n", nwords); + return nwords; + } + + nbytes = nwords * WM_ADSP_DATA_WORD_SIZE; + + adsp_dbg(dsp, "Read %d bytes\n", nbytes); + + if (copy_to_user(buf + ntotal, compr->raw_buf, nbytes)) { + adsp_err(dsp, "Failed to copy data to user: %d, %d\n", + ntotal, nbytes); + return -EFAULT; + } + + count -= nwords; + ntotal += nbytes; + } while (nwords > 0 && count > 0); + + compr->copied_total += ntotal; + + return ntotal; +} + +int wm_adsp_compr_copy(struct snd_compr_stream *stream, char __user *buf, + size_t count) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + struct wm_adsp *dsp = compr->dsp; + int ret; + + mutex_lock(&dsp->pwr_lock); + + if (stream->direction == SND_COMPRESS_CAPTURE) + ret = wm_adsp_compr_read(compr, buf, count); + else + ret = -ENOTSUPP; + + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_copy); + +int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) +{ + struct regmap *regmap = dsp->regmap; + unsigned int code0, code1, lock_reg; + + if (!(lock_regions & WM_ADSP2_REGION_ALL)) + return 0; + + lock_regions &= WM_ADSP2_REGION_ALL; + lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0; + + while (lock_regions) { + code0 = code1 = 0; + if (lock_regions & BIT(0)) { + code0 = ADSP2_LOCK_CODE_0; + code1 = ADSP2_LOCK_CODE_1; + } + if (lock_regions & BIT(1)) { + code0 |= ADSP2_LOCK_CODE_0 << ADSP2_LOCK_REGION_SHIFT; + code1 |= ADSP2_LOCK_CODE_1 << ADSP2_LOCK_REGION_SHIFT; + } + regmap_write(regmap, lock_reg, code0); + regmap_write(regmap, lock_reg, code1); + lock_regions >>= 2; + lock_reg += 2; + } + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp2_lock); + +irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) +{ + unsigned int val; + struct regmap *regmap = dsp->regmap; + int ret = 0; + + ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); + if (ret) { + adsp_err(dsp, "Failed to read Region Lock Ctrl register: %d\n", + ret); + return IRQ_HANDLED; + } + + if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { + adsp_err(dsp, "watchdog timeout error\n"); + wm_adsp_stop_watchdog(dsp); + } + + if (val & (ADSP2_SLAVE_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { + if (val & ADSP2_SLAVE_ERR_MASK) + adsp_err(dsp, "bus error: slave error\n"); + else + adsp_err(dsp, "bus error: region lock error\n"); + + ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val); + if (ret) { + adsp_err(dsp, + "Failed to read Bus Err Addr register: %d\n", + ret); + return IRQ_HANDLED; + } + + adsp_err(dsp, "bus error address = 0x%x\n", + val & ADSP2_BUS_ERR_ADDR_MASK); + + ret = regmap_read(regmap, + dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR, + &val); + if (ret) { + adsp_err( + dsp, + "Failed to read Pmem Xmem Err Addr register: %d\n", + ret); + return IRQ_HANDLED; + } + + adsp_err(dsp, "xmem error address = 0x%x\n", + val & ADSP2_XMEM_ERR_ADDR_MASK); + adsp_err(dsp, "pmem error address = 0x%x\n", + (val & ADSP2_PMEM_ERR_ADDR_MASK) >> + ADSP2_PMEM_ERR_ADDR_SHIFT); + } + + regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, + ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT); + + return IRQ_HANDLED; +} +EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); + +static void wm_halo_dump_fault_info(struct wm_adsp *dsp, const char *region, + unsigned int addr, unsigned int status) +{ + unsigned int write = status & HALO_MPU_VIO_ERR_WR_MASK; + unsigned int type = + (status & HALO_MPU_VIO_STS_MASK) >> HALO_MPU_VIO_STS_SHIFT; + unsigned int src = (status & HALO_MPU_VIO_ERR_SRC_MASK) >> + HALO_MPU_VIO_ERR_SRC_SHIFT; + + adsp_warn(dsp, "%s: FAULT_ADDR:0x%x FAULT_STATUS:0x%x %s\n", region, + addr, status, write ? "write" : "read"); + + switch (src) { + case 0: + adsp_warn(dsp, "%s: SRC=HALO\n", region); + break; + default: + adsp_warn(dsp, "%s: SRC=Requestor%u\n", region, src); + break; + } + + adsp_warn(dsp, "%s: %s %s %s %s %s %s\n", region, + type & HALO_MPU_VIO_SRAM ? "SRAM" : "", + type & HALO_MPU_VIO_REG ? "REG" : "", + type & HALO_MPU_VIO_AHB ? "AHB" : "", + type & HALO_MPU_VIO_EREG ? "EREG" : "", + type & HALO_MPU_VIO_EXTERNAL_MEM ? "ExtMem" : "", + type & HALO_MPU_VIO_NON_EXIST ? "NotExist" : ""); +} + +irqreturn_t wm_halo_bus_error(struct wm_adsp *dsp) +{ + struct regmap *regmap = dsp->regmap; + unsigned int fault[6], ahb_sts, reg; + int ret; + + mutex_lock(&dsp->pwr_lock); + + /* Ensure we log the fault even if we fail to read the fault info */ + adsp_warn(dsp, "MPU FAULT\n"); + + ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_1, + &ahb_sts); + if (ret) { + adsp_warn(dsp, "Failed to read AHB DEBUG_1 (%d)\n", ret); + goto exit_unlock; + } + + adsp_warn(dsp, "AHB WINDOW: ADDR: 0x%x STATUS: 0x%x\n", + (ahb_sts & HALO_AHBM_CORE_ERR_ADDR_MASK) >> + HALO_AHBM_CORE_ERR_ADDR_SHIFT, + ahb_sts); + adsp_warn(dsp, "AHB WINDOW: %s %s %s %s\n", + (ahb_sts & HALO_AHBM_ADDR_ERR_MASK) ? "ADDR" : "", + (ahb_sts & HALO_AHBM_LOCKED_ERR_MASK) ? "LOCKED" : "", + (ahb_sts & HALO_AHBM_SIZE_ERR_MASK) ? "SIZE" : "", + (ahb_sts & HALO_AHBM_MODE_ERR_MASK) ? "MODE" : ""); + + ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_0, + &ahb_sts); + if (ret) { + adsp_warn(dsp, "Failed to read AHB DEBUG_0 (%d)\n", ret); + goto exit_unlock; + } + + adsp_warn(dsp, "AHB SYS_ADDR: 0x%x\n", ahb_sts); + + ret = regmap_bulk_read(regmap, dsp->base + HALO_MPU_XM_VIO_ADDR, fault, + ARRAY_SIZE(fault)); + if (ret) { + adsp_warn(dsp, "Failed to read MPU fault info (%d)\n", ret); + goto exit_unlock; + } + + wm_halo_dump_fault_info(dsp, "XM", fault[0], fault[1]); + wm_halo_dump_fault_info(dsp, "YM", fault[2], fault[3]); + wm_halo_dump_fault_info(dsp, "PM", fault[4], fault[5]); + + /* Clear fault status */ + for (reg = HALO_MPU_XM_VIO_STATUS; reg <= HALO_MPU_PM_VIO_STATUS; + reg += 8) { + ret = regmap_write(regmap, dsp->base + reg, 0); + if (ret) + adsp_warn(dsp, + "Failed to clear MPU status @0x%x (%d)\n", + reg, ret); + } + +exit_unlock: + mutex_unlock(&dsp->pwr_lock); + + return IRQ_HANDLED; +} +EXPORT_SYMBOL_GPL(wm_halo_bus_error); + +MODULE_LICENSE("GPL v2"); diff --git a/techpack/audio/asoc/codecs/cs35l41/wm_adsp.h b/techpack/audio/asoc/codecs/cs35l41/wm_adsp.h new file mode 100644 index 000000000000..6c58e4767817 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41/wm_adsp.h @@ -0,0 +1,208 @@ +/* + * wm_adsp.h -- Wolfson ADSP support + * + * Copyright 2012 Wolfson Microelectronics plc + * Copyright (C) 2019 XiaoMi, Inc. + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __WM_ADSP_H +#define __WM_ADSP_H + +#include +#include +#include + +#include "wmfw.h" + +/* Return values for wm_adsp_compr_handle_irq */ +#define WM_ADSP_COMPR_OK 0 +#define WM_ADSP_COMPR_VOICE_TRIGGER 1 + +#define WM_ADSP2_REGION_0 BIT(0) +#define WM_ADSP2_REGION_1 BIT(1) +#define WM_ADSP2_REGION_2 BIT(2) +#define WM_ADSP2_REGION_3 BIT(3) +#define WM_ADSP2_REGION_4 BIT(4) +#define WM_ADSP2_REGION_5 BIT(5) +#define WM_ADSP2_REGION_6 BIT(6) +#define WM_ADSP2_REGION_7 BIT(7) +#define WM_ADSP2_REGION_8 BIT(8) +#define WM_ADSP2_REGION_9 BIT(9) +#define WM_ADSP2_REGION_1_9 \ + (WM_ADSP2_REGION_1 | WM_ADSP2_REGION_2 | WM_ADSP2_REGION_3 | \ + WM_ADSP2_REGION_4 | WM_ADSP2_REGION_5 | WM_ADSP2_REGION_6 | \ + WM_ADSP2_REGION_7 | WM_ADSP2_REGION_8 | WM_ADSP2_REGION_9) +#define WM_ADSP2_REGION_ALL (WM_ADSP2_REGION_0 | WM_ADSP2_REGION_1_9) + +struct wm_adsp_region { + int type; + unsigned int base; +}; + +struct wm_adsp_alg_region { + struct list_head list; + unsigned int alg; + int type; + unsigned int base; +}; + +struct wm_adsp_compr; +struct wm_adsp_compr_buf; + +struct wm_adsp { + const char *part; + int rev; + int num; + int type; + struct device *dev; + struct regmap *regmap; + struct snd_soc_codec *codec; + int cal_z; + int ambient; + int cal_status; + int cal_chksum; + int block_bypass; + int block_bypass_in_enh; + int base; + int base_sysinfo; + int sysclk_reg; + int sysclk_mask; + int sysclk_shift; + + struct list_head alg_regions; + + unsigned int fw_id; + unsigned int fw_id_version; + unsigned int fw_vendor_id; + + const struct wm_adsp_region *mem; + int num_mems; + + int fw; + int fw_ver; + + bool preloaded; + bool booted; + bool running; + + struct list_head ctl_list; + + struct work_struct boot_work; + + struct wm_adsp_compr *compr; + struct wm_adsp_compr_buf *buffer; + + struct mutex pwr_lock; + + unsigned int lock_regions; + bool unlock_all; + + unsigned int n_rx_rates; + unsigned int n_tx_rates; + + u8 *rx_rate_cache; + u8 *tx_rate_cache; + +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_root; + char *wmfw_file_name; + char *bin_file_name; +#endif +}; + +#define WM_ADSP1(wname, num) \ + SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \ + wm_adsp1_event, \ + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) + +#define WM_ADSP2_PRELOAD_SWITCH(wname, num) \ + SOC_SINGLE_EXT(wname " Preload Switch", SND_SOC_NOPM, num, 1, 0, \ + wm_adsp2_preloader_get, wm_adsp2_preloader_put) + +#define WM_ADSP2(wname, num, event_fn) \ + SND_SOC_DAPM_SPK(wname " Preload", NULL), \ + { .id = snd_soc_dapm_supply, \ + .name = wname " Preloader", \ + .reg = SND_SOC_NOPM, \ + .shift = num, \ + .event = event_fn, \ + .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \ + .subseq = 100, \ + /* Ensure we run after SYSCLK supply widget */ }, \ + { \ + .id = snd_soc_dapm_out_drv, .name = wname, \ + .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD \ + } + +#define WM_HALO(wname, num, event_fn) \ + SND_SOC_DAPM_SPK(wname " Preload", NULL), \ + { .id = snd_soc_dapm_supply, \ + .name = wname " Preloader", \ + .reg = SND_SOC_NOPM, \ + .shift = num, \ + .event = event_fn, \ + .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \ + .subseq = 100, \ + /* Ensure we run after SYSCLK supply widget */ }, \ + { \ + .id = snd_soc_dapm_out_drv, .name = wname, \ + .reg = SND_SOC_NOPM, .shift = num, .event = wm_halo_event, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD \ + } + +extern const struct snd_kcontrol_new wm_adsp_fw_controls[]; + +int wm_adsp1_init(struct wm_adsp *dsp); +int wm_adsp2_init(struct wm_adsp *dsp); +void wm_adsp2_remove(struct wm_adsp *dsp); +int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec); +int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec); +int wm_halo_init(struct wm_adsp *dsp); +int wm_adsp1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event); + +int wm_halo_set_clocking(struct wm_adsp *dsp, unsigned int freq, + struct mutex *rate_lock); + +int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event, + unsigned int freq); + +int wm_adsp2_lock(struct wm_adsp *adsp, unsigned int regions); +irqreturn_t wm_adsp2_bus_error(struct wm_adsp *adsp); +irqreturn_t wm_halo_bus_error(struct wm_adsp *dsp); + +int wm_adsp2_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event); + +int wm_halo_early_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); +int wm_halo_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event); + +int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + +int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream); +int wm_adsp_compr_free(struct snd_compr_stream *stream); +int wm_adsp_compr_set_params(struct snd_compr_stream *stream, + struct snd_compr_params *params); +int wm_adsp_compr_get_caps(struct snd_compr_stream *stream, + struct snd_compr_caps *caps); +int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd); +int wm_adsp_compr_handle_irq(struct wm_adsp *dsp); +int wm_adsp_compr_pointer(struct snd_compr_stream *stream, + struct snd_compr_tstamp *tstamp); +int wm_adsp_compr_copy(struct snd_compr_stream *stream, char __user *buf, + size_t count); + +#endif diff --git a/techpack/audio/asoc/codecs/cs35l41/wmfw.h b/techpack/audio/asoc/codecs/cs35l41/wmfw.h new file mode 100644 index 000000000000..0a7c62e7107b --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41/wmfw.h @@ -0,0 +1,202 @@ +/* + * wmfw.h - Wolfson firmware format information + * + * Copyright 2012 Wolfson Microelectronics plc + * Copyright (C) 2019 XiaoMi, Inc. + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __WMFW_H +#define __WMFW_H + +#include + +#define WMFW_MAX_ALG_NAME 256 +#define WMFW_MAX_ALG_DESCR_NAME 256 + +#define WMFW_MAX_COEFF_NAME 256 +#define WMFW_MAX_COEFF_DESCR_NAME 256 + +#define WMFW_CTL_FLAG_SYS 0x8000 +#define WMFW_CTL_FLAG_VOLATILE 0x0004 +#define WMFW_CTL_FLAG_WRITEABLE 0x0002 +#define WMFW_CTL_FLAG_READABLE 0x0001 + +/* Non-ALSA coefficient types start at 0x1000 */ +#define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */ +#define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */ + +struct wmfw_header { + char magic[4]; + __le32 len; + __le16 rev; + u8 core; + u8 ver; +} __packed; + +struct wmfw_footer { + __le64 timestamp; + __le32 checksum; +} __packed; + +struct wmfw_adsp1_sizes { + __le32 dm; + __le32 pm; + __le32 zm; +} __packed; + +struct wmfw_adsp2_sizes { + __le32 xm; + __le32 ym; + __le32 pm; + __le32 zm; +} __packed; + +struct wmfw_region { + union { + __be32 type; + __le32 offset; + }; + __le32 len; + u8 data[]; +} __packed; + +struct wmfw_id_hdr { + __be32 core_id; + __be32 core_rev; + __be32 id; + __be32 ver; +} __packed; + +struct wmfw_adsp1_id_hdr { + struct wmfw_id_hdr fw; + __be32 zm; + __be32 dm; + __be32 n_algs; +} __packed; + +struct wmfw_adsp2_id_hdr { + struct wmfw_id_hdr fw; + __be32 zm; + __be32 xm; + __be32 ym; + __be32 n_algs; +} __packed; + +struct wmfw_halo_fwid_hdr { + __be32 core_id; + __be32 block_rev; + __be32 vendor_id; + __be32 id; + __be32 ver; +} __packed; + +struct wmfw_halo_id_hdr { + struct wmfw_halo_fwid_hdr fw; + __be32 xm_base; + __be32 xm_size; + __be32 ym_base; + __be32 ym_size; + __be32 n_algs; +} __packed; + +struct wmfw_alg_hdr { + __be32 id; + __be32 ver; +} __packed; + +struct wmfw_adsp1_alg_hdr { + struct wmfw_alg_hdr alg; + __be32 zm; + __be32 dm; +} __packed; + +struct wmfw_adsp2_alg_hdr { + struct wmfw_alg_hdr alg; + __be32 zm; + __be32 xm; + __be32 ym; +} __packed; + +struct wmfw_halo_alg_hdr { + struct wmfw_alg_hdr alg; + __be32 xm_base; + __be32 xm_size; + __be32 ym_base; + __be32 ym_size; +} __packed; + +struct wmfw_adsp_alg_data { + __le32 id; + u8 name[WMFW_MAX_ALG_NAME]; + u8 descr[WMFW_MAX_ALG_DESCR_NAME]; + __le32 ncoeff; + u8 data[]; +} __packed; + +struct wmfw_adsp_coeff_data { + struct { + __le16 offset; + __le16 type; + __le32 size; + } hdr; + u8 name[WMFW_MAX_COEFF_NAME]; + u8 descr[WMFW_MAX_COEFF_DESCR_NAME]; + __le16 ctl_type; + __le16 flags; + __le32 len; + u8 data[]; +} __packed; + +struct wmfw_coeff_hdr { + u8 magic[4]; + __le32 len; + union { + __be32 rev; + __le32 ver; + }; + union { + __be32 core; + __le32 core_ver; + }; + u8 data[]; +} __packed; + +struct wmfw_coeff_item { + __le16 offset; + __le16 type; + __le32 id; + __le32 ver; + __le32 sr; + __le32 len; + u8 data[]; +} __packed; + +#define WMFW_ADSP1 1 +#define WMFW_ADSP2 2 +#define WMFW_HALO 4 + +#define WMFW_ABSOLUTE 0xf0 +#define WMFW_ALGORITHM_DATA 0xf2 +#define WMFW_NAME_TEXT 0xfe +#define WMFW_INFO_TEXT 0xff + +#define WMFW_ADSP1_PM 2 +#define WMFW_ADSP1_DM 3 +#define WMFW_ADSP1_ZM 4 + +#define WMFW_ADSP2_PM 2 +#define WMFW_ADSP2_ZM 4 +#define WMFW_ADSP2_XM 5 +#define WMFW_ADSP2_YM 6 + +#define WMFW_HALO_PM_PACKED 0x10 +#define WMFW_HALO_XM_PACKED 0x11 +#define WMFW_HALO_YM_PACKED 0x12 + +#endif diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/Android.mk b/techpack/audio/asoc/codecs/cs35l41_v2/Android.mk new file mode 100755 index 000000000000..9b2b116f0487 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/Android.mk @@ -0,0 +1,55 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,msmnile),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m +endif + +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE)),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + #AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=cs35l41_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_cs35l41.ko +LOCAL_MODULE_KBUILD_NAME := cs35l41_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/Kbuild b/techpack/audio/asoc/codecs/cs35l41_v2/Kbuild new file mode 100755 index 000000000000..2d57817c1d12 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/Kbuild @@ -0,0 +1,125 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + + + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_SM8150), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif + ifeq ($(CONFIG_ARCH_SM6150), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif + + ifeq ($(CONFIG_ARCH_KONA), y) + include $(AUDIO_ROOT)/config/konaauto.conf + INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h + endif + + ifeq ($(CONFIG_ARCH_LITO), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif + + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ CS35L41 ############ + +# for CS35L41 Codec +ifdef CONFIG_SND_SOC_CS35L41_V2 + CS35L41_V2_OBJS += cs35l41.o + CS35L41_V2_OBJS += cs35l41-i2c.o + CS35L41_V2_OBJS += cs35l41-tables.o + CS35L41_V2_OBJS += wm_adsp.o + #CS35L41_V2_OBJS += send_data_to_xlog.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +EXTRA_CFLAGS += $(INCS) + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_CS35L41_V2) += cs35l41_v2_dlkm.o +cs35l41_v2_dlkm-y := $(CS35L41_V2_OBJS) diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/Kconfig b/techpack/audio/asoc/codecs/cs35l41_v2/Kconfig new file mode 100755 index 000000000000..62fc5be2bc16 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/Kconfig @@ -0,0 +1,5 @@ +config SND_SOC_CS35L41_V2 + tristate "Cirrus Logic CS35L41 codec" + help + Say Y or M here if you want to add support for the Cirrus Logic + CS35L41 codec. diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41-i2c.c b/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41-i2c.c new file mode 100644 index 000000000000..ac959e8da733 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41-i2c.c @@ -0,0 +1,121 @@ +/* + * cs35l41-i2c.c -- CS35l41 I2C driver + * + * Copyright 2017 Cirrus Logic, Inc. + * + * Author: David Rhodes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm_adsp.h" +#include "cs35l41.h" +#include + +static struct regmap_config cs35l41_regmap_i2c = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .val_format_endian = REGMAP_ENDIAN_BIG, + .max_register = CS35L41_LASTREG, + .reg_defaults = cs35l41_reg, + .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), + .volatile_reg = cs35l41_volatile_reg, + .readable_reg = cs35l41_readable_reg, + .precious_reg = cs35l41_precious_reg, + .cache_type = REGCACHE_RBTREE, +}; + +static const struct i2c_device_id cs35l41_id_i2c[] = { + { "cs35l40", 0 }, + { "cs35l41", 0 }, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, cs35l41_id_i2c); + +static int cs35l41_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cs35l41_private *cs35l41; + struct device *dev = &client->dev; + struct cs35l41_platform_data *pdata = dev_get_platdata(dev); + const struct regmap_config *regmap_config = &cs35l41_regmap_i2c; + int ret; + + dev_info(dev, "ZL: cs35l41 i2c probe start\n"); + + cs35l41 = devm_kzalloc(dev, sizeof(struct cs35l41_private), GFP_KERNEL); + + if (cs35l41 == NULL) + return -ENOMEM; + + mutex_init(&cs35l41->rate_lock); + + cs35l41->dev = dev; + cs35l41->irq = client->irq; + cs35l41->bus_spi = false; + + i2c_set_clientdata(client, cs35l41); + cs35l41->regmap = devm_regmap_init_i2c(client, regmap_config); + if (IS_ERR(cs35l41->regmap)) { + ret = PTR_ERR(cs35l41->regmap); + dev_err(cs35l41->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + dev_info(dev, "ZL: before cs35l41 probe\n"); + + return cs35l41_probe(cs35l41, pdata); +} + +static int cs35l41_i2c_remove(struct i2c_client *client) +{ + struct cs35l41_private *cs35l41 = i2c_get_clientdata(client); + + return cs35l41_remove(cs35l41); +} + +static const struct of_device_id cs35l41_of_match[] = { + { .compatible = "cirrus,cs35l40" }, + { .compatible = "cirrus,cs35l41" }, + {}, +}; +MODULE_DEVICE_TABLE(of, cs35l41_of_match); + +static struct i2c_driver cs35l41_i2c_driver = { + .driver = { + .name = "cs35l41", + .of_match_table = cs35l41_of_match, + }, + .id_table = cs35l41_id_i2c, + .probe = cs35l41_i2c_probe, + .remove = cs35l41_i2c_remove, +}; + +module_i2c_driver(cs35l41_i2c_driver); + +MODULE_DESCRIPTION("I2C CS35L41 driver"); +MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); +MODULE_LICENSE("GPL"); diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41-spi.c b/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41-spi.c new file mode 100644 index 000000000000..54a104cdb777 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41-spi.c @@ -0,0 +1,112 @@ +/* + * cs35l41-spi.c -- CS35l41 SPI driver + * + * Copyright 2017 Cirrus Logic, Inc. + * + * Author: David Rhodes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm_adsp.h" +#include "cs35l41.h" +#include + +static struct regmap_config cs35l41_regmap_spi = { + .reg_bits = 32, + .val_bits = 32, + .pad_bits = 16, + .reg_stride = 4, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .val_format_endian = REGMAP_ENDIAN_BIG, + .max_register = CS35L41_LASTREG, + .reg_defaults = cs35l41_reg, + .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), + .volatile_reg = cs35l41_volatile_reg, + .readable_reg = cs35l41_readable_reg, + .precious_reg = cs35l41_precious_reg, + .cache_type = REGCACHE_RBTREE, +}; + +static const struct spi_device_id cs35l41_id_spi[] = { + { "cs35l40", 0 }, + { "cs35l41", 0 }, + {}, +}; + +MODULE_DEVICE_TABLE(spi, cs35l41_id_spi); + +static int cs35l41_spi_probe(struct spi_device *spi) +{ + const struct regmap_config *regmap_config = &cs35l41_regmap_spi; + struct cs35l41_platform_data *pdata = dev_get_platdata(&spi->dev); + struct cs35l41_private *cs35l41; + int ret; + + cs35l41 = devm_kzalloc(&spi->dev, sizeof(struct cs35l41_private), + GFP_KERNEL); + if (cs35l41 == NULL) + return -ENOMEM; + + mutex_init(&cs35l41->rate_lock); + + spi_set_drvdata(spi, cs35l41); + cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config); + if (IS_ERR(cs35l41->regmap)) { + ret = PTR_ERR(cs35l41->regmap); + dev_err(&spi->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + cs35l41->dev = &spi->dev; + cs35l41->irq = spi->irq; + cs35l41->bus_spi = true; + + return cs35l41_probe(cs35l41, pdata); +} + +static int cs35l41_spi_remove(struct spi_device *spi) +{ + struct cs35l41_private *cs35l41 = spi_get_drvdata(spi); + + return cs35l41_remove(cs35l41); +} + +static const struct of_device_id cs35l41_of_match[] = { + { .compatible = "cirrus,cs35l40" }, + { .compatible = "cirrus,cs35l41" }, + {}, +}; +MODULE_DEVICE_TABLE(of, cs35l41_of_match); + +static struct spi_driver cs35l41_spi_driver = { + .driver = { + .name = "cs35l41", + .of_match_table = cs35l41_of_match, + }, + .id_table = cs35l41_id_spi, + .probe = cs35l41_spi_probe, + .remove = cs35l41_spi_remove, +}; + +module_spi_driver(cs35l41_spi_driver); + +MODULE_DESCRIPTION("SPI CS35L41 driver"); +MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); +MODULE_LICENSE("GPL"); diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41-tables.c b/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41-tables.c new file mode 100644 index 000000000000..5560bae7a209 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41-tables.c @@ -0,0 +1,997 @@ +/* + * cs35l41-tables.c -- CS35L41 ALSA SoC audio driver + * + * Copyright 2018 Cirrus Logic, Inc. + * + * Author: Brian Austin + * David Rhodes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include "cs35l41.h" + +const struct reg_default cs35l41_reg[CS35L41_MAX_CACHE_REG] = { + { CS35L41_TEST_KEY_CTL, 0x00000000 }, + { CS35L41_USER_KEY_CTL, 0x00000000 }, + { CS35L41_OTP_CTRL0, 0x00006418 }, + { CS35L41_OTP_CTRL1, 0x00000000 }, + { CS35L41_OTP_CTRL3, 0x00000000 }, + { CS35L41_OTP_CTRL4, 0x00000000 }, + { CS35L41_OTP_CTRL5, 0x00000030 }, + { CS35L41_OTP_CTRL6, 0x00000000 }, + { CS35L41_OTP_CTRL7, 0x00000000 }, + { CS35L41_OTP_CTRL8, 0x00000000 }, + { CS35L41_PWR_CTRL1, 0x00000000 }, + { CS35L41_PWR_CTRL3, 0x01000010 }, + { CS35L41_CTRL_OVRRIDE, 0x00000002 }, + { CS35L41_AMP_OUT_MUTE, 0x00000000 }, + { CS35L41_PROTECT_REL_ERR_IGN, 0x00000000 }, + { CS35L41_GPIO_PAD_CONTROL, 0x00000000 }, + { CS35L41_JTAG_CONTROL, 0x00000000 }, + { CS35L41_PLL_CLK_CTRL, 0x00000010 }, + { CS35L41_DSP_CLK_CTRL, 0x00000003 }, + { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, + { CS35L41_DATA_FS_SEL, 0x00000000 }, + { CS35L41_MDSYNC_EN, 0x00000200 }, + { CS35L41_MDSYNC_TX_ID, 0x00000000 }, + { CS35L41_MDSYNC_PWR_CTRL, 0x00000002 }, + { CS35L41_MDSYNC_DATA_TX, 0x00000000 }, + { CS35L41_MDSYNC_TX_STATUS, 0x00000002 }, + { CS35L41_MDSYNC_DATA_RX, 0x00000000 }, + { CS35L41_MDSYNC_RX_STATUS, 0x00000002 }, + { CS35L41_MDSYNC_ERR_STATUS, 0x00000000 }, + { CS35L41_MDSYNC_SYNC_PTE2, 0x00000000 }, + { CS35L41_MDSYNC_SYNC_PTE3, 0x00000000 }, + { CS35L41_MDSYNC_SYNC_MSM_STATUS, 0x00000000 }, + { CS35L41_BSTCVRT_VCTRL1, 0x00000000 }, + { CS35L41_BSTCVRT_VCTRL2, 0x00000001 }, + { CS35L41_BSTCVRT_PEAK_CUR, 0x0000004A }, + { CS35L41_BSTCVRT_SFT_RAMP, 0x00000003 }, + { CS35L41_BSTCVRT_COEFF, 0x00002424 }, + { CS35L41_BSTCVRT_SLOPE_LBST, 0x00007500 }, + { CS35L41_BSTCVRT_SW_FREQ, 0x01008000 }, + { CS35L41_BSTCVRT_DCM_CTRL, 0x00002001 }, + { CS35L41_BSTCVRT_DCM_MODE_FORCE, 0x00000000 }, + { CS35L41_BSTCVRT_OVERVOLT_CTRL, 0x00000130 }, + { CS35L41_VI_VOL_POL, 0x08000800 }, + { CS35L41_DTEMP_WARN_THLD, 0x00000002 }, + { CS35L41_DTEMP_EN, 0x00000000 }, + { CS35L41_VPVBST_FS_SEL, 0x00000001 }, + { CS35L41_SP_ENABLES, 0x00000000 }, + { CS35L41_SP_RATE_CTRL, 0x00000028 }, + { CS35L41_SP_FORMAT, 0x18180200 }, + { CS35L41_SP_HIZ_CTRL, 0x00000002 }, + { CS35L41_SP_FRAME_TX_SLOT, 0x03020100 }, + { CS35L41_SP_FRAME_RX_SLOT, 0x00000100 }, + { CS35L41_SP_TX_WL, 0x00000018 }, + { CS35L41_SP_RX_WL, 0x00000018 }, + { CS35L41_DAC_PCM1_SRC, 0x00000008 }, + { CS35L41_ASP_TX1_SRC, 0x00000018 }, + { CS35L41_ASP_TX2_SRC, 0x00000019 }, + { CS35L41_ASP_TX3_SRC, 0x00000020 }, + { CS35L41_ASP_TX4_SRC, 0x00000021 }, + { CS35L41_DSP1_RX1_SRC, 0x00000008 }, + { CS35L41_DSP1_RX2_SRC, 0x00000009 }, + { CS35L41_DSP1_RX3_SRC, 0x00000018 }, + { CS35L41_DSP1_RX4_SRC, 0x00000019 }, + { CS35L41_DSP1_RX5_SRC, 0x00000020 }, + { CS35L41_DSP1_RX6_SRC, 0x00000021 }, + { CS35L41_DSP1_RX7_SRC, 0x0000003A }, + { CS35L41_DSP1_RX8_SRC, 0x00000001 }, + { CS35L41_NGATE1_SRC, 0x00000008 }, + { CS35L41_NGATE2_SRC, 0x00000009 }, + { CS35L41_AMP_DIG_VOL_CTRL, 0x00008000 }, + { CS35L41_VPBR_CFG, 0x02AA1905 }, + { CS35L41_VBBR_CFG, 0x02AA1905 }, + { CS35L41_VPBR_STATUS, 0x00000000 }, + { CS35L41_VBBR_STATUS, 0x00000000 }, + { CS35L41_OVERTEMP_CFG, 0x00000001 }, + { CS35L41_AMP_ERR_VOL, 0x00000000 }, + { CS35L41_VOL_STATUS_TO_DSP, 0x00000000 }, + { CS35L41_CLASSH_CFG, 0x000B0405 }, + { CS35L41_WKFET_CFG, 0x00000111 }, + { CS35L41_NG_CFG, 0x00000033 }, + { CS35L41_AMP_GAIN_CTRL, 0x00000273 }, + { CS35L41_DAC_MSM_CFG, 0x00580000 }, + { CS35L41_GPIO1_CTRL1, 0xE1000001 }, + { CS35L41_GPIO2_CTRL1, 0xE1000001 }, + { CS35L41_MIXER_NGATE_CFG, 0x00000000 }, + { CS35L41_MIXER_NGATE_CH1_CFG, 0x00000303 }, + { CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303 }, + { CS35L41_CLOCK_DETECT_1, 0x00000000 }, + { CS35L41_TIMER1_CONTROL, 0x00000000 }, + { CS35L41_TIMER1_COUNT_PRESET, 0x00000000 }, + { CS35L41_TIMER1_START_STOP, 0x00000000 }, + { CS35L41_TIMER1_STATUS, 0x00000000 }, + { CS35L41_TIMER1_COUNT_READBACK, 0x00000000 }, + { CS35L41_TIMER1_DSP_CLK_CFG, 0x00000000 }, + { CS35L41_TIMER1_DSP_CLK_STATUS, 0x00000000 }, + { CS35L41_TIMER2_CONTROL, 0x00000000 }, + { CS35L41_TIMER2_COUNT_PRESET, 0x00000000 }, + { CS35L41_TIMER2_START_STOP, 0x00000000 }, + { CS35L41_TIMER2_STATUS, 0x00000000 }, + { CS35L41_TIMER2_COUNT_READBACK, 0x00000000 }, + { CS35L41_TIMER2_DSP_CLK_CFG, 0x00000000 }, + { CS35L41_TIMER2_DSP_CLK_STATUS, 0x00000000 }, + { CS35L41_DFT_JTAG_CONTROL, 0x00000000 }, + { CS35L41_DIE_STS1, 0x00000000 }, + { CS35L41_DIE_STS2, 0x00000000 }, + { CS35L41_TEMP_CAL1, 0x00000000 }, + { CS35L41_TEMP_CAL2, 0x00000000 }, +}; + +bool cs35l41_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L41_DEVID: + case CS35L41_REVID: + case CS35L41_FABID: + case CS35L41_RELID: + case CS35L41_OTPID: + case CS35L41_TEST_KEY_CTL: + case CS35L41_USER_KEY_CTL: + case CS35L41_OTP_CTRL0: + case CS35L41_OTP_CTRL3: + case CS35L41_OTP_CTRL4: + case CS35L41_OTP_CTRL5: + case CS35L41_OTP_CTRL6: + case CS35L41_OTP_CTRL7: + case CS35L41_OTP_CTRL8: + case CS35L41_PWR_CTRL1: + case CS35L41_PWR_CTRL2: + case CS35L41_PWR_CTRL3: + case CS35L41_CTRL_OVRRIDE: + case CS35L41_AMP_OUT_MUTE: + case CS35L41_PROTECT_REL_ERR_IGN: + case CS35L41_GPIO_PAD_CONTROL: + case CS35L41_JTAG_CONTROL: + case CS35L41_DEVID_OTP: + case CS35L41_PLL_CLK_CTRL: + case CS35L41_DSP_CLK_CTRL: + case CS35L41_GLOBAL_CLK_CTRL: + case CS35L41_DATA_FS_SEL: + case CS35L41_MDSYNC_EN: + case CS35L41_MDSYNC_TX_ID: + case CS35L41_MDSYNC_PWR_CTRL: + case CS35L41_MDSYNC_DATA_TX: + case CS35L41_MDSYNC_TX_STATUS: + case CS35L41_MDSYNC_DATA_RX: + case CS35L41_MDSYNC_RX_STATUS: + case CS35L41_MDSYNC_ERR_STATUS: + case CS35L41_MDSYNC_SYNC_PTE2: + case CS35L41_MDSYNC_SYNC_PTE3: + case CS35L41_MDSYNC_SYNC_MSM_STATUS: + case CS35L41_BSTCVRT_VCTRL1: + case CS35L41_BSTCVRT_VCTRL2: + case CS35L41_BSTCVRT_PEAK_CUR: + case CS35L41_BSTCVRT_SFT_RAMP: + case CS35L41_BSTCVRT_COEFF: + case CS35L41_BSTCVRT_SLOPE_LBST: + case CS35L41_BSTCVRT_SW_FREQ: + case CS35L41_BSTCVRT_DCM_CTRL: + case CS35L41_BSTCVRT_DCM_MODE_FORCE: + case CS35L41_BSTCVRT_OVERVOLT_CTRL: + case CS35L41_VI_VOL_POL: + case CS35L41_DTEMP_WARN_THLD: + case CS35L41_DTEMP_CFG: + case CS35L41_DTEMP_EN: + case CS35L41_VPVBST_FS_SEL: + case CS35L41_SP_ENABLES: + case CS35L41_SP_RATE_CTRL: + case CS35L41_SP_FORMAT: + case CS35L41_SP_HIZ_CTRL: + case CS35L41_SP_FRAME_TX_SLOT: + case CS35L41_SP_FRAME_RX_SLOT: + case CS35L41_SP_TX_WL: + case CS35L41_SP_RX_WL: + case CS35L41_DAC_PCM1_SRC: + case CS35L41_ASP_TX1_SRC: + case CS35L41_ASP_TX2_SRC: + case CS35L41_ASP_TX3_SRC: + case CS35L41_ASP_TX4_SRC: + case CS35L41_DSP1_RX1_SRC: + case CS35L41_DSP1_RX2_SRC: + case CS35L41_DSP1_RX3_SRC: + case CS35L41_DSP1_RX4_SRC: + case CS35L41_DSP1_RX5_SRC: + case CS35L41_DSP1_RX6_SRC: + case CS35L41_DSP1_RX7_SRC: + case CS35L41_DSP1_RX8_SRC: + case CS35L41_NGATE1_SRC: + case CS35L41_NGATE2_SRC: + case CS35L41_AMP_DIG_VOL_CTRL: + case CS35L41_VPBR_CFG: + case CS35L41_VBBR_CFG: + case CS35L41_VPBR_STATUS: + case CS35L41_VBBR_STATUS: + case CS35L41_OVERTEMP_CFG: + case CS35L41_AMP_ERR_VOL: + case CS35L41_VOL_STATUS_TO_DSP: + case CS35L41_CLASSH_CFG: + case CS35L41_WKFET_CFG: + case CS35L41_NG_CFG: + case CS35L41_AMP_GAIN_CTRL: + case CS35L41_DAC_MSM_CFG: + case CS35L41_IRQ1_CFG: + case CS35L41_IRQ1_STATUS: + case CS35L41_IRQ1_STATUS1: + case CS35L41_IRQ1_STATUS2: + case CS35L41_IRQ1_STATUS3: + case CS35L41_IRQ1_STATUS4: + case CS35L41_IRQ1_RAW_STATUS1: + case CS35L41_IRQ1_RAW_STATUS2: + case CS35L41_IRQ1_RAW_STATUS3: + case CS35L41_IRQ1_RAW_STATUS4: + case CS35L41_IRQ1_MASK1: + case CS35L41_IRQ1_MASK2: + case CS35L41_IRQ1_MASK3: + case CS35L41_IRQ1_MASK4: + case CS35L41_IRQ1_FRC1: + case CS35L41_IRQ1_FRC2: + case CS35L41_IRQ1_FRC3: + case CS35L41_IRQ1_FRC4: + case CS35L41_IRQ1_EDGE1: + case CS35L41_IRQ1_EDGE4: + case CS35L41_IRQ1_POL1: + case CS35L41_IRQ1_POL2: + case CS35L41_IRQ1_POL3: + case CS35L41_IRQ1_POL4: + case CS35L41_IRQ1_DB3: + case CS35L41_IRQ2_CFG: + case CS35L41_IRQ2_STATUS: + case CS35L41_IRQ2_STATUS1: + case CS35L41_IRQ2_STATUS2: + case CS35L41_IRQ2_STATUS3: + case CS35L41_IRQ2_STATUS4: + case CS35L41_IRQ2_RAW_STATUS1: + case CS35L41_IRQ2_RAW_STATUS2: + case CS35L41_IRQ2_RAW_STATUS3: + case CS35L41_IRQ2_RAW_STATUS4: + case CS35L41_IRQ2_MASK1: + case CS35L41_IRQ2_MASK2: + case CS35L41_IRQ2_MASK3: + case CS35L41_IRQ2_MASK4: + case CS35L41_IRQ2_FRC1: + case CS35L41_IRQ2_FRC2: + case CS35L41_IRQ2_FRC3: + case CS35L41_IRQ2_FRC4: + case CS35L41_IRQ2_EDGE1: + case CS35L41_IRQ2_EDGE4: + case CS35L41_IRQ2_POL1: + case CS35L41_IRQ2_POL2: + case CS35L41_IRQ2_POL3: + case CS35L41_IRQ2_POL4: + case CS35L41_IRQ2_DB3: + case CS35L41_GPIO_STATUS1: + case CS35L41_GPIO1_CTRL1: + case CS35L41_GPIO2_CTRL1: + case CS35L41_MIXER_NGATE_CFG: + case CS35L41_MIXER_NGATE_CH1_CFG: + case CS35L41_MIXER_NGATE_CH2_CFG: + case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: + case CS35L41_CLOCK_DETECT_1: + case CS35L41_TIMER1_CONTROL: + case CS35L41_TIMER1_COUNT_PRESET: + case CS35L41_TIMER1_STATUS: + case CS35L41_TIMER1_COUNT_READBACK: + case CS35L41_TIMER1_DSP_CLK_CFG: + case CS35L41_TIMER1_DSP_CLK_STATUS: + case CS35L41_TIMER2_CONTROL: + case CS35L41_TIMER2_COUNT_PRESET: + case CS35L41_TIMER2_STATUS: + case CS35L41_TIMER2_COUNT_READBACK: + case CS35L41_TIMER2_DSP_CLK_CFG: + case CS35L41_TIMER2_DSP_CLK_STATUS: + case CS35L41_DFT_JTAG_CONTROL: + case CS35L41_DIE_STS1: + case CS35L41_DIE_STS2: + case CS35L41_TEMP_CAL1: + case CS35L41_TEMP_CAL2: + case CS35L41_DSP1_TIMESTAMP_COUNT: + case CS35L41_DSP1_SYS_ID: + case CS35L41_DSP1_SYS_VERSION: + case CS35L41_DSP1_SYS_CORE_ID: + case CS35L41_DSP1_SYS_AHB_ADDR: + case CS35L41_DSP1_SYS_XSRAM_SIZE: + case CS35L41_DSP1_SYS_YSRAM_SIZE: + case CS35L41_DSP1_SYS_PSRAM_SIZE: + case CS35L41_DSP1_SYS_PM_BOOT_SIZE: + case CS35L41_DSP1_SYS_FEATURES: + case CS35L41_DSP1_SYS_FIR_FILTERS: + case CS35L41_DSP1_SYS_LMS_FILTERS: + case CS35L41_DSP1_SYS_XM_BANK_SIZE: + case CS35L41_DSP1_SYS_YM_BANK_SIZE: + case CS35L41_DSP1_SYS_PM_BANK_SIZE: + case CS35L41_DSP1_AHBM_WIN0_CTRL0: + case CS35L41_DSP1_AHBM_WIN0_CTRL1: + case CS35L41_DSP1_AHBM_WIN1_CTRL0: + case CS35L41_DSP1_AHBM_WIN1_CTRL1: + case CS35L41_DSP1_AHBM_WIN2_CTRL0: + case CS35L41_DSP1_AHBM_WIN2_CTRL1: + case CS35L41_DSP1_AHBM_WIN3_CTRL0: + case CS35L41_DSP1_AHBM_WIN3_CTRL1: + case CS35L41_DSP1_AHBM_WIN4_CTRL0: + case CS35L41_DSP1_AHBM_WIN4_CTRL1: + case CS35L41_DSP1_AHBM_WIN5_CTRL0: + case CS35L41_DSP1_AHBM_WIN5_CTRL1: + case CS35L41_DSP1_AHBM_WIN6_CTRL0: + case CS35L41_DSP1_AHBM_WIN6_CTRL1: + case CS35L41_DSP1_AHBM_WIN7_CTRL0: + case CS35L41_DSP1_AHBM_WIN7_CTRL1: + case CS35L41_DSP1_AHBM_WIN_DBG_CTRL0: + case CS35L41_DSP1_AHBM_WIN_DBG_CTRL1: + case CS35L41_DSP1_DEBUG: + case CS35L41_DSP1_TIMER_CTRL: + case CS35L41_DSP1_RX1_RATE: + case CS35L41_DSP1_RX2_RATE: + case CS35L41_DSP1_RX3_RATE: + case CS35L41_DSP1_RX4_RATE: + case CS35L41_DSP1_RX5_RATE: + case CS35L41_DSP1_RX6_RATE: + case CS35L41_DSP1_RX7_RATE: + case CS35L41_DSP1_RX8_RATE: + case CS35L41_DSP1_TX1_RATE: + case CS35L41_DSP1_TX2_RATE: + case CS35L41_DSP1_TX3_RATE: + case CS35L41_DSP1_TX4_RATE: + case CS35L41_DSP1_TX5_RATE: + case CS35L41_DSP1_TX6_RATE: + case CS35L41_DSP1_TX7_RATE: + case CS35L41_DSP1_TX8_RATE: + case CS35L41_DSP1_NMI_CTRL1: + case CS35L41_DSP1_NMI_CTRL2: + case CS35L41_DSP1_NMI_CTRL3: + case CS35L41_DSP1_NMI_CTRL4: + case CS35L41_DSP1_NMI_CTRL5: + case CS35L41_DSP1_NMI_CTRL6: + case CS35L41_DSP1_NMI_CTRL7: + case CS35L41_DSP1_NMI_CTRL8: + case CS35L41_DSP1_RESUME_CTRL: + case CS35L41_DSP1_IRQ1_CTRL: + case CS35L41_DSP1_IRQ2_CTRL: + case CS35L41_DSP1_IRQ3_CTRL: + case CS35L41_DSP1_IRQ4_CTRL: + case CS35L41_DSP1_IRQ5_CTRL: + case CS35L41_DSP1_IRQ6_CTRL: + case CS35L41_DSP1_IRQ7_CTRL: + case CS35L41_DSP1_IRQ8_CTRL: + case CS35L41_DSP1_IRQ9_CTRL: + case CS35L41_DSP1_IRQ10_CTRL: + case CS35L41_DSP1_IRQ11_CTRL: + case CS35L41_DSP1_IRQ12_CTRL: + case CS35L41_DSP1_IRQ13_CTRL: + case CS35L41_DSP1_IRQ14_CTRL: + case CS35L41_DSP1_IRQ15_CTRL: + case CS35L41_DSP1_IRQ16_CTRL: + case CS35L41_DSP1_IRQ17_CTRL: + case CS35L41_DSP1_IRQ18_CTRL: + case CS35L41_DSP1_IRQ19_CTRL: + case CS35L41_DSP1_IRQ20_CTRL: + case CS35L41_DSP1_IRQ21_CTRL: + case CS35L41_DSP1_IRQ22_CTRL: + case CS35L41_DSP1_IRQ23_CTRL: + case CS35L41_DSP1_SCRATCH1: + case CS35L41_DSP1_SCRATCH2: + case CS35L41_DSP1_SCRATCH3: + case CS35L41_DSP1_SCRATCH4: + case CS35L41_DSP1_CCM_CORE_CTRL: + case CS35L41_DSP1_CCM_CLK_OVERRIDE: + case CS35L41_DSP1_XM_MSTR_EN: + case CS35L41_DSP1_XM_CORE_PRI: + case CS35L41_DSP1_XM_AHB_PACK_PL_PRI: + case CS35L41_DSP1_XM_AHB_UP_PL_PRI: + case CS35L41_DSP1_XM_ACCEL_PL0_PRI: + case CS35L41_DSP1_XM_NPL0_PRI: + case CS35L41_DSP1_YM_MSTR_EN: + case CS35L41_DSP1_YM_CORE_PRI: + case CS35L41_DSP1_YM_AHB_PACK_PL_PRI: + case CS35L41_DSP1_YM_AHB_UP_PL_PRI: + case CS35L41_DSP1_YM_ACCEL_PL0_PRI: + case CS35L41_DSP1_YM_NPL0_PRI: + case CS35L41_DSP1_PM_MSTR_EN: + case CS35L41_DSP1_PM_PATCH0_ADDR: + case CS35L41_DSP1_PM_PATCH0_EN: + case CS35L41_DSP1_PM_PATCH0_DATA_LO: + case CS35L41_DSP1_PM_PATCH0_DATA_HI: + case CS35L41_DSP1_PM_PATCH1_ADDR: + case CS35L41_DSP1_PM_PATCH1_EN: + case CS35L41_DSP1_PM_PATCH1_DATA_LO: + case CS35L41_DSP1_PM_PATCH1_DATA_HI: + case CS35L41_DSP1_PM_PATCH2_ADDR: + case CS35L41_DSP1_PM_PATCH2_EN: + case CS35L41_DSP1_PM_PATCH2_DATA_LO: + case CS35L41_DSP1_PM_PATCH2_DATA_HI: + case CS35L41_DSP1_PM_PATCH3_ADDR: + case CS35L41_DSP1_PM_PATCH3_EN: + case CS35L41_DSP1_PM_PATCH3_DATA_LO: + case CS35L41_DSP1_PM_PATCH3_DATA_HI: + case CS35L41_DSP1_PM_PATCH4_ADDR: + case CS35L41_DSP1_PM_PATCH4_EN: + case CS35L41_DSP1_PM_PATCH4_DATA_LO: + case CS35L41_DSP1_PM_PATCH4_DATA_HI: + case CS35L41_DSP1_PM_PATCH5_ADDR: + case CS35L41_DSP1_PM_PATCH5_EN: + case CS35L41_DSP1_PM_PATCH5_DATA_LO: + case CS35L41_DSP1_PM_PATCH5_DATA_HI: + case CS35L41_DSP1_PM_PATCH6_ADDR: + case CS35L41_DSP1_PM_PATCH6_EN: + case CS35L41_DSP1_PM_PATCH6_DATA_LO: + case CS35L41_DSP1_PM_PATCH6_DATA_HI: + case CS35L41_DSP1_PM_PATCH7_ADDR: + case CS35L41_DSP1_PM_PATCH7_EN: + case CS35L41_DSP1_PM_PATCH7_DATA_LO: + case CS35L41_DSP1_PM_PATCH7_DATA_HI: + case CS35L41_DSP1_MPU_XM_ACCESS0: + case CS35L41_DSP1_MPU_YM_ACCESS0: + case CS35L41_DSP1_MPU_WNDW_ACCESS0: + case CS35L41_DSP1_MPU_XREG_ACCESS0: + case CS35L41_DSP1_MPU_YREG_ACCESS0: + case CS35L41_DSP1_MPU_XM_ACCESS1: + case CS35L41_DSP1_MPU_YM_ACCESS1: + case CS35L41_DSP1_MPU_WNDW_ACCESS1: + case CS35L41_DSP1_MPU_XREG_ACCESS1: + case CS35L41_DSP1_MPU_YREG_ACCESS1: + case CS35L41_DSP1_MPU_XM_ACCESS2: + case CS35L41_DSP1_MPU_YM_ACCESS2: + case CS35L41_DSP1_MPU_WNDW_ACCESS2: + case CS35L41_DSP1_MPU_XREG_ACCESS2: + case CS35L41_DSP1_MPU_YREG_ACCESS2: + case CS35L41_DSP1_MPU_XM_ACCESS3: + case CS35L41_DSP1_MPU_YM_ACCESS3: + case CS35L41_DSP1_MPU_WNDW_ACCESS3: + case CS35L41_DSP1_MPU_XREG_ACCESS3: + case CS35L41_DSP1_MPU_YREG_ACCESS3: + case CS35L41_DSP1_MPU_XM_VIO_ADDR: + case CS35L41_DSP1_MPU_XM_VIO_STATUS: + case CS35L41_DSP1_MPU_YM_VIO_ADDR: + case CS35L41_DSP1_MPU_YM_VIO_STATUS: + case CS35L41_DSP1_MPU_PM_VIO_ADDR: + case CS35L41_DSP1_MPU_PM_VIO_STATUS: + case CS35L41_DSP1_MPU_LOCK_CONFIG: + case CS35L41_DSP1_MPU_WDT_RST_CTRL: + case CS35L41_DSP1_STRMARB_MSTR0_CFG0: + case CS35L41_DSP1_STRMARB_MSTR0_CFG1: + case CS35L41_DSP1_STRMARB_MSTR0_CFG2: + case CS35L41_DSP1_STRMARB_MSTR1_CFG0: + case CS35L41_DSP1_STRMARB_MSTR1_CFG1: + case CS35L41_DSP1_STRMARB_MSTR1_CFG2: + case CS35L41_DSP1_STRMARB_MSTR2_CFG0: + case CS35L41_DSP1_STRMARB_MSTR2_CFG1: + case CS35L41_DSP1_STRMARB_MSTR2_CFG2: + case CS35L41_DSP1_STRMARB_MSTR3_CFG0: + case CS35L41_DSP1_STRMARB_MSTR3_CFG1: + case CS35L41_DSP1_STRMARB_MSTR3_CFG2: + case CS35L41_DSP1_STRMARB_MSTR4_CFG0: + case CS35L41_DSP1_STRMARB_MSTR4_CFG1: + case CS35L41_DSP1_STRMARB_MSTR4_CFG2: + case CS35L41_DSP1_STRMARB_MSTR5_CFG0: + case CS35L41_DSP1_STRMARB_MSTR5_CFG1: + case CS35L41_DSP1_STRMARB_MSTR5_CFG2: + case CS35L41_DSP1_STRMARB_MSTR6_CFG0: + case CS35L41_DSP1_STRMARB_MSTR6_CFG1: + case CS35L41_DSP1_STRMARB_MSTR6_CFG2: + case CS35L41_DSP1_STRMARB_MSTR7_CFG0: + case CS35L41_DSP1_STRMARB_MSTR7_CFG1: + case CS35L41_DSP1_STRMARB_MSTR7_CFG2: + case CS35L41_DSP1_STRMARB_TX0_CFG0: + case CS35L41_DSP1_STRMARB_TX0_CFG1: + case CS35L41_DSP1_STRMARB_TX1_CFG0: + case CS35L41_DSP1_STRMARB_TX1_CFG1: + case CS35L41_DSP1_STRMARB_TX2_CFG0: + case CS35L41_DSP1_STRMARB_TX2_CFG1: + case CS35L41_DSP1_STRMARB_TX3_CFG0: + case CS35L41_DSP1_STRMARB_TX3_CFG1: + case CS35L41_DSP1_STRMARB_TX4_CFG0: + case CS35L41_DSP1_STRMARB_TX4_CFG1: + case CS35L41_DSP1_STRMARB_TX5_CFG0: + case CS35L41_DSP1_STRMARB_TX5_CFG1: + case CS35L41_DSP1_STRMARB_TX6_CFG0: + case CS35L41_DSP1_STRMARB_TX6_CFG1: + case CS35L41_DSP1_STRMARB_TX7_CFG0: + case CS35L41_DSP1_STRMARB_TX7_CFG1: + case CS35L41_DSP1_STRMARB_RX0_CFG0: + case CS35L41_DSP1_STRMARB_RX0_CFG1: + case CS35L41_DSP1_STRMARB_RX1_CFG0: + case CS35L41_DSP1_STRMARB_RX1_CFG1: + case CS35L41_DSP1_STRMARB_RX2_CFG0: + case CS35L41_DSP1_STRMARB_RX2_CFG1: + case CS35L41_DSP1_STRMARB_RX3_CFG0: + case CS35L41_DSP1_STRMARB_RX3_CFG1: + case CS35L41_DSP1_STRMARB_RX4_CFG0: + case CS35L41_DSP1_STRMARB_RX4_CFG1: + case CS35L41_DSP1_STRMARB_RX5_CFG0: + case CS35L41_DSP1_STRMARB_RX5_CFG1: + case CS35L41_DSP1_STRMARB_RX6_CFG0: + case CS35L41_DSP1_STRMARB_RX6_CFG1: + case CS35L41_DSP1_STRMARB_RX7_CFG0: + case CS35L41_DSP1_STRMARB_RX7_CFG1: + case CS35L41_DSP1_STRMARB_IRQ0_CFG0: + case CS35L41_DSP1_STRMARB_IRQ0_CFG1: + case CS35L41_DSP1_STRMARB_IRQ0_CFG2: + case CS35L41_DSP1_STRMARB_IRQ1_CFG0: + case CS35L41_DSP1_STRMARB_IRQ1_CFG1: + case CS35L41_DSP1_STRMARB_IRQ1_CFG2: + case CS35L41_DSP1_STRMARB_IRQ2_CFG0: + case CS35L41_DSP1_STRMARB_IRQ2_CFG1: + case CS35L41_DSP1_STRMARB_IRQ2_CFG2: + case CS35L41_DSP1_STRMARB_IRQ3_CFG0: + case CS35L41_DSP1_STRMARB_IRQ3_CFG1: + case CS35L41_DSP1_STRMARB_IRQ3_CFG2: + case CS35L41_DSP1_STRMARB_IRQ4_CFG0: + case CS35L41_DSP1_STRMARB_IRQ4_CFG1: + case CS35L41_DSP1_STRMARB_IRQ4_CFG2: + case CS35L41_DSP1_STRMARB_IRQ5_CFG0: + case CS35L41_DSP1_STRMARB_IRQ5_CFG1: + case CS35L41_DSP1_STRMARB_IRQ5_CFG2: + case CS35L41_DSP1_STRMARB_IRQ6_CFG0: + case CS35L41_DSP1_STRMARB_IRQ6_CFG1: + case CS35L41_DSP1_STRMARB_IRQ6_CFG2: + case CS35L41_DSP1_STRMARB_IRQ7_CFG0: + case CS35L41_DSP1_STRMARB_IRQ7_CFG1: + case CS35L41_DSP1_STRMARB_IRQ7_CFG2: + case CS35L41_DSP1_STRMARB_RESYNC_MSK: + case CS35L41_DSP1_STRMARB_ERR_STATUS: + case CS35L41_DSP1_INTPCTL_RES_STATIC: + case CS35L41_DSP1_INTPCTL_RES_DYN: + case CS35L41_DSP1_INTPCTL_NMI_CTRL: + case CS35L41_DSP1_INTPCTL_IRQ_INV: + case CS35L41_DSP1_INTPCTL_IRQ_MODE: + case CS35L41_DSP1_INTPCTL_IRQ_EN: + case CS35L41_DSP1_INTPCTL_IRQ_MSK: + case CS35L41_DSP1_INTPCTL_IRQ_ERR: + case CS35L41_DSP1_INTPCTL_IRQ_PEND: + case CS35L41_DSP1_INTPCTL_TESTBITS: + case CS35L41_DSP1_WDT_CONTROL: + case CS35L41_DSP1_WDT_STATUS: + case CS35L41_OTP_TRIM_1: + case CS35L41_OTP_TRIM_2: + case CS35L41_OTP_TRIM_3: + case CS35L41_OTP_TRIM_4: + case CS35L41_OTP_TRIM_5: + case CS35L41_OTP_TRIM_6: + case CS35L41_OTP_TRIM_7: + case CS35L41_OTP_TRIM_8: + case CS35L41_OTP_TRIM_9: + case CS35L41_OTP_TRIM_10: + case CS35L41_OTP_TRIM_11: + case CS35L41_OTP_TRIM_12: + case CS35L41_OTP_TRIM_13: + case CS35L41_OTP_TRIM_14: + case CS35L41_OTP_TRIM_15: + case CS35L41_OTP_TRIM_16: + case CS35L41_OTP_TRIM_17: + case CS35L41_OTP_TRIM_18: + case CS35L41_OTP_TRIM_19: + case CS35L41_OTP_TRIM_20: + case CS35L41_OTP_TRIM_21: + case CS35L41_OTP_TRIM_22: + case CS35L41_OTP_TRIM_23: + case CS35L41_OTP_TRIM_24: + case CS35L41_OTP_TRIM_25: + case CS35L41_OTP_TRIM_26: + case CS35L41_OTP_TRIM_27: + case CS35L41_OTP_TRIM_28: + case CS35L41_OTP_TRIM_29: + case CS35L41_OTP_TRIM_30: + case CS35L41_OTP_TRIM_31: + case CS35L41_OTP_TRIM_32: + case CS35L41_OTP_TRIM_33: + case CS35L41_OTP_TRIM_34: + case CS35L41_OTP_TRIM_35: + case CS35L41_OTP_TRIM_36: + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: + case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: + case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: + case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: + case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: + case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: + case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: + case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: + /*test regs*/ + case CS35L41_PLL_OVR: + case CS35L41_BST_TEST_DUTY: + case CS35L41_DIGPWM_IOCTRL: + return true; + default: + return false; + } +} + +bool cs35l41_precious_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: + return true; + default: + return false; + } +} + +bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L41_DEVID: + case CS35L41_SFT_RESET: + case CS35L41_FABID: + case CS35L41_REVID: + case CS35L41_DEVID_OTP: + case CS35L41_CTRL_OVRRIDE: + case CS35L41_DTEMP_EN: + case CS35L41_IRQ1_STATUS: + case CS35L41_IRQ1_STATUS1: + case CS35L41_IRQ1_STATUS2: + case CS35L41_IRQ1_STATUS3: + case CS35L41_IRQ1_STATUS4: + case CS35L41_IRQ1_RAW_STATUS1: + case CS35L41_IRQ1_RAW_STATUS2: + case CS35L41_IRQ1_RAW_STATUS3: + case CS35L41_IRQ1_RAW_STATUS4: + case CS35L41_IRQ1_FRC1: + case CS35L41_IRQ1_FRC2: + case CS35L41_IRQ1_FRC3: + case CS35L41_IRQ1_FRC4: + case CS35L41_IRQ1_EDGE1: + case CS35L41_IRQ1_EDGE4: + case CS35L41_IRQ1_POL1: + case CS35L41_IRQ1_POL2: + case CS35L41_IRQ1_POL3: + case CS35L41_IRQ1_POL4: + case CS35L41_IRQ1_DB3: + case CS35L41_IRQ2_STATUS: + case CS35L41_IRQ2_STATUS1: + case CS35L41_IRQ2_STATUS2: + case CS35L41_IRQ2_STATUS3: + case CS35L41_IRQ2_STATUS4: + case CS35L41_IRQ2_RAW_STATUS1: + case CS35L41_IRQ2_RAW_STATUS2: + case CS35L41_IRQ2_RAW_STATUS3: + case CS35L41_IRQ2_RAW_STATUS4: + case CS35L41_IRQ2_FRC1: + case CS35L41_IRQ2_FRC2: + case CS35L41_IRQ2_FRC3: + case CS35L41_IRQ2_FRC4: + case CS35L41_IRQ2_EDGE1: + case CS35L41_IRQ2_EDGE4: + case CS35L41_IRQ2_POL1: + case CS35L41_IRQ2_POL2: + case CS35L41_IRQ2_POL3: + case CS35L41_IRQ2_POL4: + case CS35L41_IRQ2_DB3: + case CS35L41_GPIO_STATUS1: + case CS35L41_OTP_TRIM_1: + case CS35L41_OTP_TRIM_2: + case CS35L41_OTP_TRIM_3: + case CS35L41_OTP_TRIM_4: + case CS35L41_OTP_TRIM_5: + case CS35L41_OTP_TRIM_6: + case CS35L41_OTP_TRIM_7: + case CS35L41_OTP_TRIM_8: + case CS35L41_OTP_TRIM_9: + case CS35L41_OTP_TRIM_10: + case CS35L41_OTP_TRIM_11: + case CS35L41_OTP_TRIM_12: + case CS35L41_OTP_TRIM_13: + case CS35L41_OTP_TRIM_14: + case CS35L41_OTP_TRIM_15: + case CS35L41_OTP_TRIM_16: + case CS35L41_OTP_TRIM_17: + case CS35L41_OTP_TRIM_18: + case CS35L41_OTP_TRIM_19: + case CS35L41_OTP_TRIM_20: + case CS35L41_OTP_TRIM_21: + case CS35L41_OTP_TRIM_22: + case CS35L41_OTP_TRIM_23: + case CS35L41_OTP_TRIM_24: + case CS35L41_OTP_TRIM_25: + case CS35L41_OTP_TRIM_26: + case CS35L41_OTP_TRIM_27: + case CS35L41_OTP_TRIM_28: + case CS35L41_OTP_TRIM_29: + case CS35L41_OTP_TRIM_30: + case CS35L41_OTP_TRIM_31: + case CS35L41_OTP_TRIM_32: + case CS35L41_OTP_TRIM_33: + case CS35L41_OTP_TRIM_34: + case CS35L41_OTP_TRIM_35: + case CS35L41_OTP_TRIM_36: + case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: + case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: + case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: + case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: + case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: + case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: + case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: + case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: + case CS35L41_DSP1_CCM_CORE_CTRL ... CS35L41_DSP1_WDT_STATUS: + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: + return true; + default: + return false; + } +} + +static const struct cs35l41_otp_packed_element_t otp_map_1[] = { + /* addr shift size */ + { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ + { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ + { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ + { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ + { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ + { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ + { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ + { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ + { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ + { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ + { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ + { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ + { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ + { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ + { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ + { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ + { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ + { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ + { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ + { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ + { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ + { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ + { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ + { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ + { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ + { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ + { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ + { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ + { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ + { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ + { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ + { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ + { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ + { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ + { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ + { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ + { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ + { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ + { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ + { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ + { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ + { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ + { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ + { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ + { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ + { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ + { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ + { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ + { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ + { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ + { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ + { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ + { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ + { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ + { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ + { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ + { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ + { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ + { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ + { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ + { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ + { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ + { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ + { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ + { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ + { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ + { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ + { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ + { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ + { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ + { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ + { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ + { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ + { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ + { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ + { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ + { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ + { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ + { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ + { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ + { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ + { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ + { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ + { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ + { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ + { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ + { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ + { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ + { 0x00007434, 17, 1 }, /*FORCE_CAL*/ + { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ + { 0x00007068, 0, 9 }, /*MODIX*/ + { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ + { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ + { 0x00000000, 0, 1 }, /*extra bit*/ + { 0x00017040, 0, 8 }, /*X_COORDINATE*/ + { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ + { 0x00017040, 16, 8 }, /*WAFER_ID*/ + { 0x00017040, 24, 8 }, /*DVS*/ + { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ +}; + +static const struct cs35l41_otp_packed_element_t otp_map_2[] = { + /* addr shift size */ + { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ + { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ + { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ + { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ + { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ + { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ + { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ + { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ + { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ + { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ + { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ + { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ + { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ + { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ + { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ + { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ + { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ + { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ + { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ + { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ + { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ + { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ + { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ + { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ + { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ + { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ + { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ + { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ + { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ + { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ + { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ + { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ + { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ + { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ + { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ + { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ + { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ + { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ + { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ + { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ + { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ + { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ + { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ + { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ + { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ + { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ + { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ + { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ + { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ + { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ + { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ + { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ + { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ + { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ + { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ + { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ + { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ + { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ + { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ + { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ + { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ + { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ + { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ + { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ + { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ + { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ + { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ + { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ + { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ + { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ + { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ + { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ + { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ + { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ + { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ + { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ + { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ + { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ + { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ + { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ + { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ + { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ + { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ + { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ + { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ + { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ + { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ + { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ + { 0x00007434, 17, 1 }, /*FORCE_CAL*/ + { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ + { 0x00007068, 0, 9 }, /*MODIX*/ + { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ + { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ + { 0x00004000, 11, 1 }, /*VMON_POL*/ + { 0x00017040, 0, 8 }, /*X_COORDINATE*/ + { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ + { 0x00017040, 16, 8 }, /*WAFER_ID*/ + { 0x00017040, 24, 8 }, /*DVS*/ + { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ +}; + +const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[] = { + { + .devid_otp = CS35L41_CHIP_ID, /* unset by OTP */ + .id = 0x01, + .map = otp_map_1, + .num_elements = ARRAY_SIZE(otp_map_1), + .bit_offset = 16, + .word_offset = 2, + }, + { + .devid_otp = CS35L41_CHIP_ID, /* unset by OTP */ + .id = 0x02, + .map = otp_map_2, + .num_elements = ARRAY_SIZE(otp_map_2), + .bit_offset = 16, + .word_offset = 2, + }, + { + .devid_otp = 0, /* unset by OTP */ + .id = 0x03, + .map = otp_map_2, + .num_elements = ARRAY_SIZE(otp_map_2), + .bit_offset = 16, + .word_offset = 2, + }, + { + .devid_otp = CS35L41_CHIP_ID, /* unset by OTP */ + .id = 0x06, + .map = otp_map_2, + .num_elements = ARRAY_SIZE(otp_map_2), + .bit_offset = 16, + .word_offset = 2, + }, + { + .devid_otp = CS35L41_CHIP_ID, /* unset by OTP */ + .id = 0x08, + .map = otp_map_1, + .num_elements = ARRAY_SIZE(otp_map_1), + .bit_offset = 16, + .word_offset = 2, + }, + { + .devid_otp = CS35L41LV_CHIP_ID, + .id = 0x01, + .map = otp_map_1, + .num_elements = ARRAY_SIZE(otp_map_1), + .bit_offset = 16, + .word_offset = 4, + }, +}; + +const struct cs35l41_otp_maps cs35l41_otp_maps = { + .map = cs35l41_otp_map_map, + .len = ARRAY_SIZE(cs35l41_otp_map_map), +}; + +const unsigned int cs35l41_ctl_cache_regs[CS35L41_CTRL_CACHE_SIZE] = { + CS35L41_DAC_PCM1_SRC, CS35L41_DSP1_RX1_SRC, + CS35L41_DSP1_RX2_SRC, CS35L41_ASP_TX1_SRC, + CS35L41_ASP_TX2_SRC, CS35L41_ASP_TX3_SRC, + CS35L41_ASP_TX4_SRC, CS35L41_SP_FRAME_TX_SLOT, + CS35L41_AMP_GAIN_CTRL, CS35L41_AMP_DIG_VOL_CTRL, + CS35L41_PWR_CTRL1, CS35L41_PWR_CTRL2, + CS35L41_BSTCVRT_VCTRL1, CS35L41_BSTCVRT_VCTRL2, +}; + +const struct cs35l41_otp_trim_region_t + cs35l41_trim_cache_regs[CS35L41_TRIM_CACHE_REGIONS] = { + { 0x00002030, 1 }, { 0x0000208c, 2 }, { 0x0000300C, 1 }, + { 0x0000394C, 5 }, { 0x0000416C, 1 }, { 0x00004160, 1 }, + { 0x00004170, 1 }, { 0x00004360, 1 }, { 0x00004448, 2 }, + { 0x00006E30, 14 }, { 0x00007418, 2 }, { 0x00007434, 1 }, + { 0x00007068, 1 }, { 0x0000410C, 1 }, { 0x0000400C, 1 }, + { 0x00004000, 1 }, { 0x00017040, 2 }, + }; diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41.c b/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41.c new file mode 100644 index 000000000000..d3e3ef245190 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41.c @@ -0,0 +1,3831 @@ +/* + * cs35l41.c -- CS35l41 ALSA SoC audio driver + * + * Copyright 2018 Cirrus Logic, Inc. + * + * Author: David Rhodes + * Brian Austin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#define DEBUG + +//#define BRINGUP_IRQ_VERIFY +#define FAST_SWITCH_WORKAROUND + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm_adsp.h" +#include "cs35l41.h" +#include + +static const char *const cs35l41_supplies[] = { + "VA", + "VP", +}; + +struct cs35l41_pll_sysclk_config { + int freq; + int clk_cfg; +}; + +static const struct cs35l41_pll_sysclk_config cs35l41_pll_sysclk[] = { + { 32768, 0x00 }, { 8000, 0x01 }, { 11025, 0x02 }, + { 12000, 0x03 }, { 16000, 0x04 }, { 22050, 0x05 }, + { 24000, 0x06 }, { 32000, 0x07 }, { 44100, 0x08 }, + { 48000, 0x09 }, { 88200, 0x0A }, { 96000, 0x0B }, + { 128000, 0x0C }, { 176400, 0x0D }, { 192000, 0x0E }, + { 256000, 0x0F }, { 352800, 0x10 }, { 384000, 0x11 }, + { 512000, 0x12 }, { 705600, 0x13 }, { 750000, 0x14 }, + { 768000, 0x15 }, { 1000000, 0x16 }, { 1024000, 0x17 }, + { 1200000, 0x18 }, { 1411200, 0x19 }, { 1500000, 0x1A }, + { 1536000, 0x1B }, { 2000000, 0x1C }, { 2048000, 0x1D }, + { 2400000, 0x1E }, { 2822400, 0x1F }, { 3000000, 0x20 }, + { 3072000, 0x21 }, { 3200000, 0x22 }, { 4000000, 0x23 }, + { 4096000, 0x24 }, { 4800000, 0x25 }, { 5644800, 0x26 }, + { 6000000, 0x27 }, { 6144000, 0x28 }, { 6250000, 0x29 }, + { 6400000, 0x2A }, { 6500000, 0x2B }, { 6750000, 0x2C }, + { 7526400, 0x2D }, { 8000000, 0x2E }, { 8192000, 0x2F }, + { 9600000, 0x30 }, { 11289600, 0x31 }, { 12000000, 0x32 }, + { 12288000, 0x33 }, { 12500000, 0x34 }, { 12800000, 0x35 }, + { 13000000, 0x36 }, { 13500000, 0x37 }, { 19200000, 0x38 }, + { 22579200, 0x39 }, { 24000000, 0x3A }, { 24576000, 0x3B }, + { 25000000, 0x3C }, { 25600000, 0x3D }, { 26000000, 0x3E }, + { 27000000, 0x3F }, +}; + +static const unsigned char cs35l41_bst_k1_table[4][5] = { + { 0x24, 0x32, 0x32, 0x4F, 0x57 }, + { 0x24, 0x32, 0x32, 0x4F, 0x57 }, + { 0x40, 0x32, 0x32, 0x4F, 0x57 }, + { 0x40, 0x32, 0x32, 0x4F, 0x57 } +}; + +static const unsigned char cs35l41_bst_k2_table[4][5] = { + { 0x24, 0x49, 0x66, 0xA3, 0xEA }, + { 0x24, 0x49, 0x66, 0xA3, 0xEA }, + { 0x48, 0x49, 0x66, 0xA3, 0xEA }, + { 0x48, 0x49, 0x66, 0xA3, 0xEA } +}; + +static const unsigned char cs35l41_bst_slope_table[4] = { 0x75, 0x6B, 0x3B, + 0x28 }; + +static int cs35l41_enter_hibernate(struct cs35l41_private *cs35l41); +static int cs35l41_exit_hibernate(struct cs35l41_private *cs35l41); +static int cs35l41_restore(struct cs35l41_private *cs35l41); +static int cs35l41_component_set_sysclk(struct snd_soc_component *component, + int clk_id, int source, + unsigned int freq, int dir); + +static int cs35l41_dsp_power_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + + dev_dbg(cs35l41->dev, "%s: event = 0x%x\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (cs35l41->halo_booted == false) + wm_adsp_early_event(w, kcontrol, event); + else + cs35l41->dsp.booted = true; + + return 0; + case SND_SOC_DAPM_PRE_PMD: + if (cs35l41->halo_booted == false) { + cancel_delayed_work(&cs35l41->hb_work); + mutex_lock(&cs35l41->hb_lock); + cs35l41_exit_hibernate(cs35l41); + mutex_unlock(&cs35l41->hb_lock); + + if (cs35l41->amp_hibernate != + CS35L41_HIBERNATE_INCOMPATIBLE) + cs35l41->amp_hibernate = + CS35L41_HIBERNATE_NOT_LOADED; + + wm_adsp_early_event(w, kcontrol, event); + wm_adsp_event(w, kcontrol, event); + } + default: + return 0; + } +} + +static int cs35l41_set_csplmboxcmd(struct cs35l41_private *cs35l41, + enum cs35l41_cspl_mboxcmd cmd); + +static int cs35l41_dsp_load_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + enum cs35l41_cspl_mboxcmd mboxcmd = CSPL_MBOX_CMD_NONE; + enum cs35l41_cspl_mboxstate fw_status = CSPL_MBOX_STS_RUNNING; + int ret = 0; + + dev_dbg(cs35l41->dev, "%s: event = 0x%x\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (cs35l41->halo_booted == false) { + wm_adsp_event(w, kcontrol, event); + cs35l41->halo_booted = true; + } + if (cs35l41->dsp.running) { + regmap_read(cs35l41->regmap, CS35L41_DSP_MBOX_2, + (unsigned int *)&fw_status); + switch (fw_status) { + case CSPL_MBOX_STS_RDY_FOR_REINIT: + mboxcmd = CSPL_MBOX_CMD_REINIT; + break; + case CSPL_MBOX_STS_PAUSED: + mboxcmd = CSPL_MBOX_CMD_RESUME; + break; + case CSPL_MBOX_STS_RUNNING: + /* + * First time playing audio + * means fw_status is running + */ + mboxcmd = CSPL_MBOX_CMD_RESUME; + break; + default: + dev_err(cs35l41->dev, + "Firmware status is invalid(%u)\n", + fw_status); + break; + } + ret = cs35l41_set_csplmboxcmd(cs35l41, mboxcmd); + } + break; + case SND_SOC_DAPM_PRE_PMD: + /* + * Workaround for PB 5.41.6 FW power consumption issue. + * FW sets bit FILT_GLOBAL_OVR, so it should be cleared + * after FW boot up + */ + regmap_update_bits(cs35l41->regmap, CS35L41_CTRL_OVRRIDE, + CS35L41_FILT_GLOBAL_OVR_MASK, 0); + break; + default: + break; + } + + return ret; +} + +static int cs35l41_halo_booted_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + + dev_dbg(cs35l41->dev, "%s: get=%d\n", __func__, cs35l41->halo_booted); + + ucontrol->value.integer.value[0] = cs35l41->halo_booted; + + return 0; +} + +static int cs35l41_halo_booted_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + + dev_dbg(cs35l41->dev, "%s: put=%ld\n", __func__, + ucontrol->value.integer.value[0]); + + cs35l41->halo_booted = ucontrol->value.integer.value[0]; + + return 0; +} + +static int cs35l41_force_int_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = cs35l41->force_int; + + return 0; +} + +static int cs35l41_force_int_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + bool force_int_changed = + (cs35l41->force_int != (bool)ucontrol->value.integer.value[0]); + + mutex_lock(&cs35l41->force_int_lock); + + cs35l41->force_int = ucontrol->value.integer.value[0]; + + if (force_int_changed) { + if (cs35l41->force_int) { + disable_irq(cs35l41->irq); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, + CS35L41_INT1_MASK_FORCE); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_FRC1, 1); + } else { + regmap_write(cs35l41->regmap, CS35L41_IRQ1_FRC1, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, + CS35L41_INT1_MASK_DEFAULT); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, 1); + enable_irq(cs35l41->irq); + } + } + + mutex_unlock(&cs35l41->force_int_lock); + + return 0; +} + +static int cs35l41_ccm_reset_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static int cs35l41_ccm_reset_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + unsigned int val = 0; + int ret = 0; + + val = ucontrol->value.integer.value[0]; + + if (val) { + ret = regmap_update_bits(cs35l41->regmap, CS35L41_DSP_CLK_CTRL, + 0x3, 0x2); + ret = regmap_update_bits(cs35l41->regmap, + CS35L41_DSP1_CCM_CORE_CTRL, + CS35L41_HALO_CORE_RESET, + CS35L41_HALO_CORE_RESET); + ret = regmap_update_bits(cs35l41->regmap, CS35L41_DSP_CLK_CTRL, + 0x3, 0x3); + } + + return 0; +} + +static int cs35l41_hibernate_force_wake_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = cs35l41->hibernate_force_wake; + + return 0; +} + +static int cs35l41_hibernate_force_wake_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + bool valid_transition = cs35l41->hibernate_force_wake != + ucontrol->value.integer.value[0]; + unsigned int amp_active; + + regmap_read(cs35l41->regmap, CS35L41_PWR_CTRL1, &_active); + + if (cs35l41->amp_hibernate == CS35L41_HIBERNATE_AWAKE || + (cs35l41->amp_hibernate == CS35L41_HIBERNATE_NOT_LOADED && + cs35l41->dsp.running)) { + cs35l41->hibernate_force_wake = + ucontrol->value.integer.value[0]; + if (!cs35l41->hibernate_force_wake && valid_transition && + !(amp_active & CS35L41_GLOBAL_EN_MASK)) { + /* return to standby */ + queue_delayed_work(cs35l41->wq, &cs35l41->hb_work, + msecs_to_jiffies(100)); + } + } else if (cs35l41->amp_hibernate == CS35L41_HIBERNATE_STANDBY) { + cs35l41->hibernate_force_wake = + ucontrol->value.integer.value[0]; + if (cs35l41->hibernate_force_wake && valid_transition) { + /* wake from standby */ + cancel_delayed_work(&cs35l41->hb_work); + mutex_lock(&cs35l41->hb_lock); + cs35l41_exit_hibernate(cs35l41); + mutex_unlock(&cs35l41->hb_lock); + } + } + + return 0; +} + +static const char *cs35l41_fast_switch_text[] = { + "fast_switch1.txt", "fast_switch2.txt", "fast_switch3.txt", + "fast_switch4.txt", "fast_switch5.txt", +}; + +static int cs35l41_fast_switch_en_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = cs35l41->fast_switch_en; + + return 0; +} + +static int cs35l41_do_fast_switch(struct cs35l41_private *cs35l41) +{ + char val_str[CS35L41_BUFSIZE]; + const char *fw_name; + const struct firmware *fw; + int ret; + unsigned int i, j, k; + s32 data_ctl_len, val; + __be32 *data_ctl_buf, cmd_ctl, st_ctl; + bool fw_running = false; + + data_ctl_buf = NULL; + + fw_name = cs35l41->fast_switch_names[cs35l41->fast_switch_file_idx]; + dev_dbg(cs35l41->dev, "fw_name:%s\n", fw_name); + ret = request_firmware(&fw, fw_name, cs35l41->dev); + if (ret < 0) { + dev_err(cs35l41->dev, "Failed to request firmware:%s\n", + fw_name); + return -EIO; + } + + /* Parse number of data in file */ + for (i = 0, j = 0; (char)fw->data[i] != ','; i++) { + if ((char)fw->data[i] == ' ') { + /* Skip white space */ + } else { + /* fw->data[i] must be numerical digit */ + if (j < CS35L41_BUFSIZE - 1) { + val_str[j] = fw->data[i]; + j++; + } else { + dev_err(cs35l41->dev, "Invalid input\n"); + ret = -EINVAL; + goto exit; + } + } + } + i++; /* points to beginning of next number */ + val_str[j] = '\0'; + ret = kstrtos32(val_str, 10, &data_ctl_len); + if (ret < 0) { + dev_err(cs35l41->dev, "kstrtos32 failed (%d) val_str:%s\n", ret, + val_str); + goto exit; + } + + dev_dbg(cs35l41->dev, "data_ctl_len:%u\n", data_ctl_len); + + data_ctl_buf = kcalloc(1, data_ctl_len * sizeof(s32), GFP_KERNEL); + if (!data_ctl_buf) { + ret = -ENOMEM; + goto exit; + } + + data_ctl_buf[0] = cpu_to_be32(data_ctl_len); + + /* i continues from end of previous loop */ + for (j = 0, k = 1; i <= fw->size; i++) { + if (i == fw->size || (char)fw->data[i] == ',') { + /* + * Reached end of parameter + * delimited either by ',' or end of file + * Parse number and write parameter + */ + val_str[j] = '\0'; + ret = kstrtos32(val_str, 10, &val); + if (ret < 0) { + dev_err(cs35l41->dev, + "kstrtos32 failed (%d) val_str:%s\n", + ret, val_str); + goto exit; + } + data_ctl_buf[k] = cpu_to_be32(val); + j = 0; + k++; + } else if ((char)fw->data[i] == ' ') { + /* Skip white space */ + } else { + /* fw->data[i] must be numerical digit */ + if (j < CS35L41_BUFSIZE - 1) { + val_str[j] = fw->data[i]; + j++; + } else { + dev_err(cs35l41->dev, "Invalid input\n"); + ret = -EINVAL; + goto exit; + } + } + } + + wm_adsp_write_ctl(&cs35l41->dsp, "CSPL_UPDATE_PARAMS_CONFIG", + data_ctl_buf, data_ctl_len * sizeof(s32)); + + dev_dbg(cs35l41->dev, "Wrote %u reg for CSPL_UPDATE_PARAMS_CONFIG\n", + data_ctl_len); + +#ifdef DEBUG + wm_adsp_read_ctl(&cs35l41->dsp, "CSPL_UPDATE_PARAMS_CONFIG", + data_ctl_buf, data_ctl_len * sizeof(s32)); + dev_dbg(cs35l41->dev, "read CSPL_UPDATE_PARAMS_CONFIG:\n"); + for (i = 0; i < data_ctl_len; i++) + dev_dbg(cs35l41->dev, "%u\n", be32_to_cpu(data_ctl_buf[i])); +#endif + cmd_ctl = cpu_to_be32(CSPL_CMD_UPDATE_PARAM); + wm_adsp_write_ctl(&cs35l41->dsp, "CSPL_COMMAND", &cmd_ctl, sizeof(s32)); + + /* Verify CSPL COMMAND */ + for (i = 0; i < 5; i++) { + wm_adsp_read_ctl(&cs35l41->dsp, "CSPL_STATE", &st_ctl, + sizeof(s32)); + if (be32_to_cpu(st_ctl) == CSPL_ST_RUNNING) { + dev_dbg(cs35l41->dev, + "CSPL STATE == RUNNING (%u attempt)\n", i); + fw_running = true; + break; + } + + usleep_range(100, 110); + } + + if (!fw_running) { + dev_err(cs35l41->dev, "CSPL_STATE (%d) is not running\n", + st_ctl); + ret = -1; + goto exit; + } +exit: + kfree(data_ctl_buf); + release_firmware(fw); + return ret; +} + +static int cs35l41_fast_switch_en_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + +#if !defined(FAST_SWITCH_WORKAROUND) + if (!cs35l41->fast_switch_en && ucontrol->value.integer.value[0]) + /* + * Rising on fast switch enable + * Perform fast use case switching + */ + ret = cs35l41_do_fast_switch(cs35l41); +#endif + + cs35l41->fast_switch_en = ucontrol->value.integer.value[0]; + + return ret; +} + +static int cs35l41_fast_switch_file_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + struct soc_enum *soc_enum; + unsigned int i = ucontrol->value.enumerated.item[0]; + + soc_enum = (struct soc_enum *)kcontrol->private_value; + + if (i >= soc_enum->items) { + dev_err(cs35l41->dev, "Invalid mixer input (%u)\n", i); + return -EINVAL; + } + +#if defined(FAST_SWITCH_WORKAROUND) + if (!cs35l41->dsp.running) { + dev_err(cs35l41->dev, "DSP not running\n"); + return 0; + } + + if ((i != cs35l41->fast_switch_file_idx) && cs35l41->fast_switch_en) { + int ret; + + cs35l41->fast_switch_file_idx = i; + ret = cs35l41_do_fast_switch(cs35l41); + dev_dbg(cs35l41->dev, "%s: fast switch %s\n", __func__, + ret ? "fail" : "success"); + } +#endif + + return 0; +} + +static int cs35l41_fast_switch_file_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + + ucontrol->value.enumerated.item[0] = cs35l41->fast_switch_file_idx; + + return 0; +} + +static const DECLARE_TLV_DB_RANGE(dig_vol_tlv, 0, 0, + TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), 1, + CS35L41_MAX_PCM_VOL, + TLV_DB_MINMAX_ITEM(-10200, 1200)); +static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1); + +static const struct snd_kcontrol_new dre_ctrl = + SOC_DAPM_SINGLE("DRE Switch", CS35L41_PWR_CTRL3, 20, 1, 0); + +static const struct snd_kcontrol_new vbstmon_out_ctrl = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const char *const cs35l41_pcm_sftramp_text[] = { "Off", ".5ms", "1ms", + "2ms", "4ms", "8ms", + "15ms", "30ms" }; + +static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp, CS35L41_AMP_DIG_VOL_CTRL, 0, + cs35l41_pcm_sftramp_text); + +static int cs35l41_reload_tuning_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = cs35l41->reload_tuning; + + return 0; +} + +static int cs35l41_reload_tuning_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + + cs35l41->reload_tuning = ucontrol->value.integer.value[0]; + + return 0; +} + +static bool cs35l41_is_csplmboxsts_correct(enum cs35l41_cspl_mboxcmd cmd, + enum cs35l41_cspl_mboxstate sts) +{ + switch (cmd) { + case CSPL_MBOX_CMD_NONE: + case CSPL_MBOX_CMD_UNKNOWN_CMD: + return true; + case CSPL_MBOX_CMD_PAUSE: + return (sts == CSPL_MBOX_STS_PAUSED); + case CSPL_MBOX_CMD_RESUME: + return (sts == CSPL_MBOX_STS_RUNNING); + case CSPL_MBOX_CMD_REINIT: + return (sts == CSPL_MBOX_STS_RUNNING); + case CSPL_MBOX_CMD_STOP_PRE_REINIT: + return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT); + default: + return false; + } +} + +static int cs35l41_set_csplmboxcmd(struct cs35l41_private *cs35l41, + enum cs35l41_cspl_mboxcmd cmd) +{ + int ret = 0; + unsigned int sts, i; + bool ack = false; + + /* Reset DSP sticky bit */ + regmap_write(cs35l41->regmap, CS35L41_IRQ2_STATUS2, + 1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT); + + /* Reset AP sticky bit */ + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS2, + 1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT); + + /* + * Set mailbox cmd + */ + /* Unmask DSP INT */ + regmap_update_bits(cs35l41->regmap, CS35L41_IRQ2_MASK2, + 1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT, 0); + regmap_write(cs35l41->regmap, CS35L41_CSPL_MBOX_CMD_DRV, cmd); + + /* Poll for DSP ACK */ + for (i = 0; i < 5; i++) { + usleep_range(1000, 1010); + ret = regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS2, &sts); + if (ret < 0) { + dev_err(cs35l41->dev, "regmap_read failed (%d)\n", ret); + continue; + } + if (sts & (1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT)) { + dev_dbg(cs35l41->dev, + "%u: Received ACK in EINT for mbox cmd (%d)\n", + i, cmd); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS2, + 1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT); + ack = true; + break; + } + } + + if (!ack) { + dev_err(cs35l41->dev, + "Timeout waiting for DSP to set mbox cmd\n"); + ret = -ETIMEDOUT; + } + + /* Mask DSP INT */ + regmap_update_bits(cs35l41->regmap, CS35L41_IRQ2_MASK2, + 1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT, + 1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT); + + if (regmap_read(cs35l41->regmap, CS35L41_CSPL_MBOX_STS, &sts) < 0) { + dev_err(cs35l41->dev, "Failed to read %u\n", + CS35L41_CSPL_MBOX_STS); + ret = -EACCES; + } + + if (!cs35l41_is_csplmboxsts_correct(cmd, + (enum cs35l41_cspl_mboxstate)sts)) { + dev_err(cs35l41->dev, + "Failed to set mailbox(cmd: %u, sts: %u)\n", cmd, sts); + ret = -ENOMSG; + } + + return ret; +} + +static void cs35l41_abort_ramp(struct cs35l41_private *cs35l41) +{ + if (!work_busy(&cs35l41->vol_ctl.ramp_work)) + return; + atomic_set(&cs35l41->vol_ctl.ramp_abort, 1); + cancel_work_sync(&cs35l41->vol_ctl.ramp_work); + flush_workqueue(cs35l41->vol_ctl.ramp_wq); + atomic_set(&cs35l41->vol_ctl.ramp_abort, 0); +} + +static int cs35l41_put_output_dev(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + struct soc_enum *soc_enum; + unsigned int i = ucontrol->value.enumerated.item[0]; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + dev_dbg(cs35l41->dev, "%s: output_dev = %u\n", __func__, i); + + soc_enum = (struct soc_enum *)kcontrol->private_value; + + if (i >= soc_enum->items) { + dev_err(component->dev, "Invalid mixer input (%u)\n", i); + return -EINVAL; + } + + if (atomic_read(&cs35l41->vol_ctl.playback) && + cs35l41->vol_ctl.auto_ramp_timeout > 0 && + cs35l41->vol_ctl.output_dev == CS35L41_OUTPUT_DEV_RCV && + soc_enum->values[i] == CS35L41_OUTPUT_DEV_SPK) { + /* + * While audio is playing, + * auto volume ramp is enabled, + * output device changes from RCV to SPK. + * In this case, perform volume ramp. + */ + cs35l41_abort_ramp(cs35l41); + queue_work(cs35l41->vol_ctl.ramp_wq, + &cs35l41->vol_ctl.ramp_work); + } + + cs35l41->vol_ctl.output_dev = soc_enum->values[i]; + + return 0; +} + +static int cs35l41_get_output_dev(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + int ret = 0; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + ucontrol->value.enumerated.item[0] = cs35l41->vol_ctl.output_dev; + + return ret; +} + +static const char *const channel_swap_texts[] = { "Off", "On" }; +static SOC_ENUM_SINGLE_DECL(channel_swap_enum, SND_SOC_NOPM, 0, + channel_swap_texts); + +static const char *virt_text[] = { "None", "Ref" }; +static SOC_ENUM_SINGLE_DECL(virt_enum, SND_SOC_NOPM, 2, virt_text); + +static const struct snd_kcontrol_new virt_mux = + SOC_DAPM_ENUM("Virt Connect", virt_enum); + +static const char *const cs35l41_pcm_source_texts[] = { "None", "ASP", "DSP" }; +static const unsigned int cs35l41_pcm_source_values[] = { 0x00, 0x08, 0x32 }; +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_pcm_source_enum, CS35L41_DAC_PCM1_SRC, + 0, CS35L41_ASP_SOURCE_MASK, + cs35l41_pcm_source_texts, + cs35l41_pcm_source_values); + +static const struct snd_kcontrol_new pcm_source_mux = + SOC_DAPM_ENUM("PCM Source", cs35l41_pcm_source_enum); + +static const char *const cs35l41_tx_input_texts[] = { + "Zero", "ASPRX1", "ASPRX2", "VMON", "IMON", + "VPMON", "VBSTMON", "DSPTX1", "DSPTX2" +}; +static const unsigned int cs35l41_tx_input_values[] = { + 0x00, + CS35L41_INPUT_SRC_ASPRX1, + CS35L41_INPUT_SRC_ASPRX2, + CS35L41_INPUT_SRC_VMON, + CS35L41_INPUT_SRC_IMON, + CS35L41_INPUT_SRC_VPMON, + CS35L41_INPUT_SRC_VBSTMON, + CS35L41_INPUT_DSP_TX1, + CS35L41_INPUT_DSP_TX2 +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx1_enum, CS35L41_ASP_TX1_SRC, 0, + CS35L41_ASP_SOURCE_MASK, + cs35l41_tx_input_texts, + cs35l41_tx_input_values); + +static const struct snd_kcontrol_new asp_tx1_mux = + SOC_DAPM_ENUM("ASPTX1 SRC", cs35l41_asptx1_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx2_enum, CS35L41_ASP_TX2_SRC, 0, + CS35L41_ASP_SOURCE_MASK, + cs35l41_tx_input_texts, + cs35l41_tx_input_values); + +static const struct snd_kcontrol_new asp_tx2_mux = + SOC_DAPM_ENUM("ASPTX2 SRC", cs35l41_asptx2_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx3_enum, CS35L41_ASP_TX3_SRC, 0, + CS35L41_ASP_SOURCE_MASK, + cs35l41_tx_input_texts, + cs35l41_tx_input_values); + +static const struct snd_kcontrol_new asp_tx3_mux = + SOC_DAPM_ENUM("ASPTX3 SRC", cs35l41_asptx3_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx4_enum, CS35L41_ASP_TX4_SRC, 0, + CS35L41_ASP_SOURCE_MASK, + cs35l41_tx_input_texts, + cs35l41_tx_input_values); + +static const struct snd_kcontrol_new asp_tx4_mux = + SOC_DAPM_ENUM("ASPTX4 SRC", cs35l41_asptx4_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_dsprx1_enum, CS35L41_DSP1_RX1_SRC, 0, + CS35L41_ASP_SOURCE_MASK, + cs35l41_tx_input_texts, + cs35l41_tx_input_values); + +static const struct snd_kcontrol_new dsp_rx1_mux = + SOC_DAPM_ENUM("DSPRX1 SRC", cs35l41_dsprx1_enum); + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_dsprx2_enum, CS35L41_DSP1_RX2_SRC, 0, + CS35L41_ASP_SOURCE_MASK, + cs35l41_tx_input_texts, + cs35l41_tx_input_values); + +static const struct snd_kcontrol_new dsp_rx2_mux = + SOC_DAPM_ENUM("DSPRX2 SRC", cs35l41_dsprx2_enum); + +static void cs35l41_set_vol(int vol, struct cs35l41_private *cs35l41) +{ + unsigned int val; + int ret; + + mutex_lock(&cs35l41->vol_ctl.vol_mutex); + + if (vol < 0 || vol > CS35L41_MAX_PCM_VOL) { + dev_err(cs35l41->dev, "Invalid PCM VOLUME %d\n", vol); + goto exit; + } + + if (vol < CS35L41_ZERO_PCM_VOL) + /* PCM Volume is attenuation */ + val = (unsigned int)(vol + CS35L41_AMP_PCM_VOL_MUTE); + else + /* CS35L41_ZERO_PCM_VOL <= dig_vol <= CS35L41_MAX_PCM_VOL */ + val = (unsigned int)(vol - CS35L41_ZERO_PCM_VOL); + ret = regmap_update_bits(cs35l41->regmap, CS35L41_AMP_DIG_VOL_CTRL, + CS35L41_AMP_PCM_VOL_MASK, + val << CS35L41_AMP_PCM_VOL_SHIFT); + if (ret < 0) + dev_err(cs35l41->dev, "Failed to set PCM VOLUME %d\n", ret); + +exit: + mutex_unlock(&cs35l41->vol_ctl.vol_mutex); +} + +static int cs35l41_vol_ramp0(struct cs35l41_private *cs35l41, long final_x, + long init_y, long final_y) +{ + long curr_x = 0; + long curr_y = init_y; + long delta_x = final_x; + long delta_y = final_y - init_y; + long step_x, step_y; + int ret = 0; + + if (final_x < 0 || final_y < 0 || init_y < 0) { + ret = -EINVAL; + goto exit; + } + + if (final_y <= init_y) { + dev_info(cs35l41->dev, "Vol ramp slope is not positive\n"); + cs35l41_set_vol((int)init_y, cs35l41); + usleep_range(final_x, final_x + 1); + cs35l41_set_vol((int)final_y, cs35l41); + goto exit; + } + + step_y = 1; /* 1/8 dB, min IC supported step */ + step_x = delta_x / delta_y; /* in micro-second */ + if (step_x == 0) + /* Take care of case where delta_x < delta_y */ + step_x = 1; + + dev_dbg(cs35l41->dev, "vol ramp delta x:%ld delta y:%ld step x:%ld\n", + delta_x, delta_y, step_x); + while (1) { + if (atomic_read(&cs35l41->vol_ctl.ramp_abort)) { + ret = -EINTR; + goto exit; + } + if (curr_x >= final_x) { + /* Delay is complete */ + cs35l41_set_vol((int)final_y, cs35l41); + break; + } + if (curr_y == final_y) { + /* Volume ramp is completed */ + usleep_range(final_x - curr_x, final_x - curr_x + 1); + break; + } + cs35l41_set_vol((int)curr_y, cs35l41); + curr_y += step_y; + curr_x += step_x; + usleep_range(step_x, step_x + 1); + } +exit: + return ret; +} + +static void cs35l41_vol_ramp(struct work_struct *wk) +{ + struct cs35l41_vol_ctl *vol_ctl; + struct cs35l41_private *cs35l41; + long final_x_knee, final_x_end; + long init_y_knee, init_y_end, final_y_end; + int ret = 0; + + vol_ctl = container_of(wk, struct cs35l41_vol_ctl, ramp_work); + cs35l41 = container_of(vol_ctl, struct cs35l41_private, vol_ctl); + dev_dbg(cs35l41->dev, "%s: dig_vol = %d\n", __func__, + cs35l41->vol_ctl.dig_vol); + + atomic_set(&cs35l41->vol_ctl.vol_ramp, 1); + /* + * vol_ramp must be true at this point, + * which guarantee ramp_init_att, ramp_knee_att, + * ramp_knee_time, ramp_end_time cannot be changed + */ + final_x_knee = (long)(cs35l41->vol_ctl.ramp_knee_time) * 1000; /* us */ + final_x_end = (long)(cs35l41->vol_ctl.ramp_end_time) * 1000; + /* 1/8 dB minimum step */ + init_y_knee = (long)(cs35l41->vol_ctl.dig_vol - + cs35l41->vol_ctl.ramp_init_att * 8); + if (init_y_knee < 0) + /* Hit floor */ + init_y_knee = 0; + init_y_end = (long)(cs35l41->vol_ctl.dig_vol - + cs35l41->vol_ctl.ramp_knee_att * 8); + if (init_y_end < 0) + /* Hit floor */ + init_y_end = 0; + final_y_end = (long)cs35l41->vol_ctl.dig_vol; + if (final_y_end < 0) + /* Hit floor */ + final_y_end = 0; + ret = cs35l41_vol_ramp0(cs35l41, final_x_knee, init_y_knee, init_y_end); + if (ret == -EINTR) { + /* Abort ramp */ + cs35l41_set_vol(cs35l41->vol_ctl.dig_vol, cs35l41); + goto exit; + } + ret = cs35l41_vol_ramp0(cs35l41, final_x_end, init_y_end, final_y_end); + if (ret == -EINTR) { + /* Abort ramp */ + cs35l41_set_vol(cs35l41->vol_ctl.dig_vol, cs35l41); + goto exit; + } +exit: + atomic_set(&cs35l41->vol_ctl.vol_ramp, 0); + /* Make manual ramp one-shot */ + atomic_set(&cs35l41->vol_ctl.manual_ramp, 0); +} + +static int cs35l41_get_vol(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = (long)cs35l41->vol_ctl.dig_vol; + + return 0; +} + +static int cs35l41_put_vol(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + int ret = 0; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + if (ucontrol->value.integer.value[0] < 0 || + ucontrol->value.integer.value[0] > CS35L41_MAX_PCM_VOL) + return -EINVAL; + + if (atomic_read(&cs35l41->vol_ctl.vol_ramp) == 0) { + cs35l41->vol_ctl.dig_vol = + (int)ucontrol->value.integer.value[0]; + cs35l41_set_vol(cs35l41->vol_ctl.dig_vol, cs35l41); + } + + return ret; +} + +static int cs35l41_get_ramp_status(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = + (long)atomic_read(&cs35l41->vol_ctl.vol_ramp); + + return 0; +} + +static int cs35l41_put_ramp_status(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + dev_info(cs35l41->dev, "Volume ramp status cannot be set\n"); + return 0; +} + +static int cs35l41_get_manual_ramp(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = + (long)atomic_read(&cs35l41->vol_ctl.manual_ramp); + + return 0; +} + +static int cs35l41_put_manual_ramp(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + if (ucontrol->value.integer.value[0] < 0 || + ucontrol->value.integer.value[0] > 1) + return -EINVAL; + + if (atomic_read(&cs35l41->vol_ctl.manual_ramp) == 0 && + ucontrol->value.integer.value[0] == 1) { + /* Rising edge */ + if (atomic_read(&cs35l41->vol_ctl.playback)) { + /* Stop existing ramp and start new ramp */ + cs35l41_abort_ramp(cs35l41); + queue_work(cs35l41->vol_ctl.ramp_wq, + &cs35l41->vol_ctl.ramp_work); + } + /* + * In else case, + * let DAPM event handle ramp on playback start. + */ + } else if (atomic_read(&cs35l41->vol_ctl.manual_ramp) == 1 && + ucontrol->value.integer.value[0] == 0) { + /* Falling edge */ + if (atomic_read(&cs35l41->vol_ctl.playback)) + /* Stop existing ramp */ + cs35l41_abort_ramp(cs35l41); + } + atomic_set(&cs35l41->vol_ctl.manual_ramp, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int cs35l41_get_init_attenuation(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = (long)cs35l41->vol_ctl.ramp_init_att; + return 0; +} + +static int cs35l41_put_init_attenuation(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + if (ucontrol->value.integer.value[0] < 0 || + ucontrol->value.integer.value[0] > CS35L41_MAX_VOL_ATT) + return -EINVAL; + + if (atomic_read(&cs35l41->vol_ctl.vol_ramp) == 0) + cs35l41->vol_ctl.ramp_init_att = + (int)ucontrol->value.integer.value[0]; + return 0; +} + +static int cs35l41_get_knee_attenuation(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = (long)cs35l41->vol_ctl.ramp_knee_att; + return 0; +} + +static int cs35l41_put_knee_attenuation(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + if (ucontrol->value.integer.value[0] < 0 || + ucontrol->value.integer.value[0] > CS35L41_MAX_VOL_ATT) + return -EINVAL; + + if (atomic_read(&cs35l41->vol_ctl.vol_ramp) == 0) + cs35l41->vol_ctl.ramp_knee_att = + (int)ucontrol->value.integer.value[0]; + return 0; +} + +static int cs35l41_get_ramp_end_time(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = (long)cs35l41->vol_ctl.ramp_end_time; + return 0; +} + +static int cs35l41_put_ramp_end_time(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + if (ucontrol->value.integer.value[0] < 0 || + ucontrol->value.integer.value[0] > CS35L41_MAX_AUTO_RAMP_TIMEOUT) + return -EINVAL; + + if (atomic_read(&cs35l41->vol_ctl.vol_ramp) == 0) + cs35l41->vol_ctl.ramp_end_time = + (unsigned int)ucontrol->value.integer.value[0]; + return 0; +} + +static int cs35l41_get_auto_ramp_timeout(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = + (long)cs35l41->vol_ctl.auto_ramp_timeout; + return 0; +} + +static int cs35l41_put_auto_ramp_timeout(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + if (ucontrol->value.integer.value[0] < 0 || + ucontrol->value.integer.value[0] > CS35L41_MAX_AUTO_RAMP_TIMEOUT) + return -EINVAL; + + cs35l41->vol_ctl.auto_ramp_timeout = + (unsigned int)ucontrol->value.integer.value[0]; + + return 0; +} + +static int cs35l41_get_ramp_knee_time(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = + (long)cs35l41->vol_ctl.ramp_knee_time; + return 0; +} + +static int cs35l41_put_ramp_knee_time(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component; + struct cs35l41_private *cs35l41; + + component = snd_soc_kcontrol_component(kcontrol); + cs35l41 = snd_soc_component_get_drvdata(component); + + if (ucontrol->value.integer.value[0] < 0 || + ucontrol->value.integer.value[0] > CS35L41_MAX_AUTO_RAMP_TIMEOUT) + return -EINVAL; + + if (atomic_read(&cs35l41->vol_ctl.vol_ramp) == 0) + cs35l41->vol_ctl.ramp_knee_time = + (unsigned int)ucontrol->value.integer.value[0]; + return 0; +} + +static int cs35l41_channel_swap_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + int swapped = 0; + int val; + if (cs35l41->dsp.booted) { + wm_adsp_read_ctl(&cs35l41->dsp, "CH_BAL", (void *)&val, + sizeof(__be32)); + + dev_dbg(cs35l41->dev, "%s: CH_BAL = 0x%08x\n", __func__, + be32_to_cpu(val)); + swapped = (0x400000 == be32_to_cpu(val)) ? 1 : 0; + } + + ucontrol->value.integer.value[0] = swapped; + + return 0; +} + +static int cs35l41_channel_swap_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + int val; + + if (cs35l41->dsp.booted) { + if (ucontrol->value.integer.value[0]) + val = 0x400000; + else + val = 0; + + val = cpu_to_be32(val); + wm_adsp_write_ctl(&cs35l41->dsp, "CH_BAL", (void *)&val, + sizeof(__be32)); + } + + return 0; +} + +static const char *const cs35l41_output_dev_text[] = { + "Speaker", + "Receiver", +}; + +/* Ensure SPK and RCV defined values match array index */ +static const unsigned int cs35l41_output_dev_val[] = { + CS35L41_OUTPUT_DEV_SPK, + CS35L41_OUTPUT_DEV_RCV, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_output_dev, SND_SOC_NOPM, 0, 0, + cs35l41_output_dev_text, + cs35l41_output_dev_val); + +static const struct snd_kcontrol_new cs35l41_aud_controls[] = { + SOC_SINGLE_RANGE_EXT_TLV("Digital PCM Volume", SND_SOC_NOPM, 0, 0, + CS35L41_MAX_PCM_VOL, 0, cs35l41_get_vol, + cs35l41_put_vol, dig_vol_tlv), + SOC_SINGLE_TLV("AMP PCM Gain", CS35L41_AMP_GAIN_CTRL, 5, 0x14, 0, + amp_gain_tlv), + SOC_SINGLE_RANGE("ASPTX1 Slot Position", CS35L41_SP_FRAME_TX_SLOT, 0, 0, + 7, 0), + SOC_SINGLE_RANGE("ASPTX2 Slot Position", CS35L41_SP_FRAME_TX_SLOT, 8, 0, + 7, 0), + SOC_SINGLE_RANGE("ASPTX3 Slot Position", CS35L41_SP_FRAME_TX_SLOT, 16, + 0, 7, 0), + SOC_SINGLE_RANGE("ASPTX4 Slot Position", CS35L41_SP_FRAME_TX_SLOT, 24, + 0, 7, 0), + SOC_SINGLE_RANGE("ASPRX1 Slot Position", CS35L41_SP_FRAME_RX_SLOT, 0, 0, + 7, 0), + SOC_SINGLE_RANGE("ASPRX2 Slot Position", CS35L41_SP_FRAME_RX_SLOT, 8, 0, + 7, 0), + SOC_ENUM("PCM Soft Ramp", pcm_sft_ramp), + SOC_SINGLE_EXT("DSP Booted", SND_SOC_NOPM, 0, 1, 0, + cs35l41_halo_booted_get, cs35l41_halo_booted_put), + SOC_SINGLE_EXT("CCM Reset", CS35L41_DSP1_CCM_CORE_CTRL, 0, 1, 0, + cs35l41_ccm_reset_get, cs35l41_ccm_reset_put), + SOC_SINGLE_EXT("Force Interrupt", SND_SOC_NOPM, 0, 1, 0, + cs35l41_force_int_get, cs35l41_force_int_put), + SOC_SINGLE_EXT("Fast Use Case Switch Enable", SND_SOC_NOPM, 0, 1, 0, + cs35l41_fast_switch_en_get, cs35l41_fast_switch_en_put), + SOC_SINGLE_EXT("Firmware Reload Tuning", SND_SOC_NOPM, 0, 1, 0, + cs35l41_reload_tuning_get, cs35l41_reload_tuning_put), + SOC_ENUM_EXT("Channel Swap", channel_swap_enum, + cs35l41_channel_swap_get, cs35l41_channel_swap_put), + SOC_SINGLE("VPBR Config", CS35L41_VPBR_CFG, 0, 0x7FFFFFF, 0), + SOC_SINGLE("Noise Gate Config", CS35L41_NG_CFG, 0, 0x3FFF, 0), + SOC_SINGLE("GLOBAL_EN from GPIO Control", CS35L41_PWR_CTRL1, 8, 1, 0), + SOC_SINGLE("Boost Converter Enable", CS35L41_PWR_CTRL2, 4, 3, 0), + SOC_SINGLE("AMP Enable", CS35L41_PWR_CTRL2, 0, 1, 0), + WM_ADSP_FW_CONTROL("DSP1", 0), + SOC_SINGLE_BOOL_EXT("Safety Volume Ramp Status", 0, + cs35l41_get_ramp_status, cs35l41_put_ramp_status), + SOC_SINGLE_BOOL_EXT("Manual Ramp Control", 0, cs35l41_get_manual_ramp, + cs35l41_put_manual_ramp), + SOC_SINGLE_EXT("Initial Ramp Volume Attenuation", SND_SOC_NOPM, 0, + CS35L41_MAX_VOL_ATT, 0, cs35l41_get_init_attenuation, + cs35l41_put_init_attenuation), + SOC_SINGLE_EXT("Knee Ramp Volume Attenuation", SND_SOC_NOPM, 0, + CS35L41_MAX_VOL_ATT, 0, cs35l41_get_knee_attenuation, + cs35l41_put_knee_attenuation), + SOC_SINGLE_EXT("Ramp Knee Time", SND_SOC_NOPM, 0, + CS35L41_MAX_AUTO_RAMP_TIMEOUT, 0, + cs35l41_get_ramp_knee_time, cs35l41_put_ramp_knee_time), + SOC_SINGLE_EXT("Ramp End Time", SND_SOC_NOPM, 0, + CS35L41_MAX_AUTO_RAMP_TIMEOUT, 0, + cs35l41_get_ramp_end_time, cs35l41_put_ramp_end_time), + SOC_SINGLE_EXT("Auto Ramp Safety Timeout", SND_SOC_NOPM, 0, + CS35L41_MAX_AUTO_RAMP_TIMEOUT, 0, + cs35l41_get_auto_ramp_timeout, + cs35l41_put_auto_ramp_timeout), + SOC_VALUE_ENUM_EXT("Audio Output Device", cs35l41_output_dev, + cs35l41_get_output_dev, cs35l41_put_output_dev), + WM_ADSP2_PRELOAD_SWITCH("DSP1", 1), +}; + +static const struct snd_kcontrol_new cs35l41_bst_ctl[] = { + SOC_SINGLE("Boost Class-H Tracking Enable", CS35L41_BSTCVRT_VCTRL2, 0, + 1, 0), + SOC_SINGLE("Boost Target Voltage", CS35L41_BSTCVRT_VCTRL1, 0, 0xAA, 0), + SOC_SINGLE_EXT("Hibernate Force Wake", SND_SOC_NOPM, 0, 1, 0, + cs35l41_hibernate_force_wake_get, + cs35l41_hibernate_force_wake_put), +}; + +static const struct snd_kcontrol_new cs35l41_lv_ctl[] = { + SOC_SINGLE("Boost Target Voltage", CS35L41_BSTCVRT_VCTRL1, 0, 0x8C, 0), +}; + +static const struct cs35l41_otp_map_element_t * +cs35l41_find_otp_map(u32 otp_id, u32 devid_otp) +{ + int i; + + for (i = 0; i < cs35l41_otp_maps.len; i++) { + if (cs35l41_otp_maps.map[i].id == otp_id && + cs35l41_otp_maps.map[i].devid_otp == devid_otp) + return &cs35l41_otp_maps.map[i]; + } + + return NULL; +} + +static int cs35l41_otp_unpack(void *data) +{ + struct cs35l41_private *cs35l41 = data; + u32 *otp_mem; + int i; + int bit_offset, word_offset; + unsigned int bit_sum = 8; + u32 otp_val, otp_id_reg; + const struct cs35l41_otp_map_element_t *otp_map_match; + const struct cs35l41_otp_packed_element_t *otp_map; + int ret; + struct spi_device *spi = NULL; + u32 orig_spi_freq = 0; + u32 devid_otp; + + otp_mem = kmalloc_array(32, sizeof(*otp_mem), GFP_KERNEL); + if (!otp_mem) + return -ENOMEM; + + ret = regmap_read(cs35l41->regmap, CS35L41_OTPID, &otp_id_reg); + if (ret < 0) { + dev_err(cs35l41->dev, "Read OTP ID failed\n"); + ret = -EINVAL; + goto err_otp_unpack; + } + + ret = regmap_read(cs35l41->regmap, CS35L41_DEVID_OTP, &devid_otp); + if (ret < 0) { + dev_err(cs35l41->dev, "Read DEVID OTP failed\n"); + ret = -EINVAL; + goto err_otp_unpack; + } + + otp_map_match = cs35l41_find_otp_map(otp_id_reg, devid_otp); + + if (otp_map_match == NULL) { + dev_err(cs35l41->dev, "OTP Map matching ID %d not found\n", + otp_id_reg); + ret = -EINVAL; + goto err_otp_unpack; + } + + if (cs35l41->bus_spi) { + spi = to_spi_device(cs35l41->dev); + orig_spi_freq = spi->max_speed_hz; + spi->max_speed_hz = CS35L41_SPI_MAX_FREQ_OTP; + spi_setup(spi); + } + + ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem, + CS35L41_OTP_SIZE_WORDS); + if (ret < 0) { + dev_err(cs35l41->dev, "Read OTP Mem failed\n"); + ret = -EINVAL; + goto err_otp_unpack; + } + + if (cs35l41->bus_spi) { + spi->max_speed_hz = orig_spi_freq; + spi_setup(spi); + } + + otp_map = otp_map_match->map; + + bit_offset = otp_map_match->bit_offset; + word_offset = otp_map_match->word_offset; + + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055); + if (ret < 0) { + dev_err(cs35l41->dev, "Write Unlock key failed 1/2\n"); + ret = -EINVAL; + goto err_otp_unpack; + } + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); + if (ret < 0) { + dev_err(cs35l41->dev, "Write Unlock key failed 2/2\n"); + ret = -EINVAL; + goto err_otp_unpack; + } + + for (i = 0; i < otp_map_match->num_elements; i++) { + dev_dbg(cs35l41->dev, + "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", + bit_offset, word_offset, bit_sum % 32); + if (bit_offset + otp_map[i].size - 1 >= 32) { + otp_val = (otp_mem[word_offset] & + GENMASK(31, bit_offset)) >> + bit_offset; + otp_val |= + (otp_mem[++word_offset] & + GENMASK(bit_offset + otp_map[i].size - 33, 0)) + << (32 - bit_offset); + bit_offset += otp_map[i].size - 32; + } else { + otp_val = (otp_mem[word_offset] & + GENMASK(bit_offset + otp_map[i].size - 1, + bit_offset)) >> + bit_offset; + bit_offset += otp_map[i].size; + } + bit_sum += otp_map[i].size; + + if (bit_offset == 32) { + bit_offset = 0; + word_offset++; + } + + if (otp_map[i].reg != 0) { + ret = regmap_update_bits( + cs35l41->regmap, otp_map[i].reg, + GENMASK(otp_map[i].shift + otp_map[i].size - 1, + otp_map[i].shift), + otp_val << otp_map[i].shift); + if (ret < 0) { + dev_err(cs35l41->dev, "Write OTP val failed\n"); + ret = -EINVAL; + goto err_otp_unpack; + } + } + } + + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); + if (ret < 0) { + dev_err(cs35l41->dev, "Write Lock key failed 1/2\n"); + ret = -EINVAL; + goto err_otp_unpack; + } + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033); + if (ret < 0) { + dev_err(cs35l41->dev, "Write Lock key failed 2/2\n"); + ret = -EINVAL; + goto err_otp_unpack; + } + ret = 0; + +err_otp_unpack: + kfree(otp_mem); + return ret; +} + +static irqreturn_t cs35l41_irq(int irq, void *data) +{ + struct cs35l41_private *cs35l41 = data; + unsigned int status[4]; + unsigned int masks[4]; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(status); i++) { + regmap_read(cs35l41->regmap, + CS35L41_IRQ1_STATUS1 + (i * CS35L41_REGSTRIDE), + &status[i]); + regmap_read(cs35l41->regmap, + CS35L41_IRQ1_MASK1 + (i * CS35L41_REGSTRIDE), + &masks[i]); + } + + /* Check to see if unmasked bits are active */ + if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) && + !(status[2] & ~masks[2]) && !(status[3] & ~masks[3])) + return IRQ_NONE; + + /* + * The following interrupts require a + * protection release cycle to get the + * speaker out of Safe-Mode. + */ + if (status[0] & CS35L41_AMP_SHORT_ERR) { + dev_crit(cs35l41->dev, "Amp short error\n"); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_AMP_SHORT_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_AMP_SHORT_ERR_RLS, + CS35L41_AMP_SHORT_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_AMP_SHORT_ERR_RLS, 0); + } + + if (status[0] & CS35L41_TEMP_WARN) { + dev_crit(cs35l41->dev, "Over temperature warning\n"); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_TEMP_WARN); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_TEMP_WARN_ERR_RLS, + CS35L41_TEMP_WARN_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_TEMP_WARN_ERR_RLS, 0); + } + + if (status[0] & CS35L41_TEMP_ERR) { + dev_crit(cs35l41->dev, "Over temperature error\n"); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_TEMP_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_TEMP_ERR_RLS, CS35L41_TEMP_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_TEMP_ERR_RLS, 0); + } + + if (status[0] & CS35L41_BST_OVP_ERR) { + dev_crit(cs35l41->dev, "VBST Over Voltage error\n"); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_BST_EN_MASK, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_BST_OVP_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_BST_OVP_ERR_RLS, + CS35L41_BST_OVP_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_BST_OVP_ERR_RLS, 0); + regmap_update_bits( + cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK, + CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT); + } + + if (status[0] & CS35L41_BST_DCM_UVP_ERR) { + dev_crit(cs35l41->dev, "DCM VBST Under Voltage Error\n"); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_BST_EN_MASK, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_BST_DCM_UVP_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_BST_UVP_ERR_RLS, + CS35L41_BST_UVP_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_BST_UVP_ERR_RLS, 0); + regmap_update_bits( + cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK, + CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT); + } + + if (status[0] & CS35L41_BST_SHORT_ERR) { + dev_crit(cs35l41->dev, "LBST error: powering off!\n"); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_BST_EN_MASK, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_BST_SHORT_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_BST_SHORT_ERR_RLS, + CS35L41_BST_SHORT_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, + CS35L41_BST_SHORT_ERR_RLS, 0); + regmap_update_bits( + cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK, + CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT); + } + + if (status[3] & CS35L41_OTP_BOOT_DONE) { + regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK4, + CS35L41_OTP_BOOT_DONE, + CS35L41_OTP_BOOT_DONE); + } + +#if defined(BRINGUP_IRQ_VERIFY) + if (status[0] & CS35L41_PUP_DONE_MASK) { + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_PUP_DONE_MASK); + dev_dbg(cs35l41->dev, "AMP powered up\n"); + } +#endif + + return IRQ_HANDLED; +} + +static const struct reg_sequence cs35l41_pup_patch[] = { + { 0x00000040, 0x00000055 }, { 0x00000040, 0x000000AA }, + { 0x00002084, 0x002F1AA0 }, { 0x00000040, 0x000000CC }, + { 0x00000040, 0x00000033 }, +}; + +static const struct reg_sequence cs35l41_pdn_patch[] = { + { 0x00000040, 0x00000055 }, { 0x00000040, 0x000000AA }, + { 0x00002084, 0x002F1AA3 }, { 0x00000040, 0x000000CC }, + { 0x00000040, 0x00000033 }, +}; + +static void cs35l41_hibernate_work(struct work_struct *work) +{ + struct delayed_work *dwork = to_delayed_work(work); + struct cs35l41_private *cs35l41 = + container_of(dwork, struct cs35l41_private, hb_work); + + mutex_lock(&cs35l41->hb_lock); + cs35l41_enter_hibernate(cs35l41); + mutex_unlock(&cs35l41->hb_lock); +} + +static int cs35l41_hibernate(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + int ret = 0; + + if (!cs35l41->dsp.running || + cs35l41->amp_hibernate == CS35L41_HIBERNATE_INCOMPATIBLE || + cs35l41->hibernate_force_wake) + return 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + cancel_delayed_work(&cs35l41->hb_work); + mutex_lock(&cs35l41->hb_lock); + ret = cs35l41_exit_hibernate(cs35l41); + mutex_unlock(&cs35l41->hb_lock); + break; + case SND_SOC_DAPM_POST_PMD: + queue_delayed_work(cs35l41->wq, &cs35l41->hb_work, + msecs_to_jiffies(2000)); + break; + default: + dev_err(cs35l41->dev, "Invalid event = 0x%x\n", event); + ret = -EINVAL; + } + return ret; +} + +static bool cs35l41_need_auto_vol_ramp(struct cs35l41_private *cs35l41) +{ + bool ramp = false; + ktime_t curr_timestamp; + s64 dev_timeout = (s64)cs35l41->vol_ctl.auto_ramp_timeout * 1000000; + s64 elapsed_time; + + if (cs35l41->vol_ctl.prev_active_dev == CS35L41_OUTPUT_DEV_RCV && + cs35l41->vol_ctl.output_dev == CS35L41_OUTPUT_DEV_SPK) { + if (cs35l41->vol_ctl.auto_ramp_timeout == 0) { + /* Never ramp */ + } else if (cs35l41->vol_ctl.auto_ramp_timeout == + CS35L41_MAX_AUTO_RAMP_TIMEOUT) { + /* Always ramp */ + ramp = true; + } else { + /* + * Guaranteed: + * 0 < auto_ramp_timeout < CS35L41_MAX_AUTO_RAMP_TIMEOUT + */ + curr_timestamp = ktime_get(); + elapsed_time = + ktime_to_ns(curr_timestamp) - + ktime_to_ns(cs35l41->vol_ctl.dev_timestamp); + if (elapsed_time < dev_timeout) + ramp = true; + dev_dbg(cs35l41->dev, + "elapsed_time:%lld dev_timeout:%lld\n", + elapsed_time, dev_timeout); + } + } + + return ramp; +} + +static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + enum cs35l41_cspl_mboxcmd mboxcmd = CSPL_MBOX_CMD_NONE; + int ret = 0; + int i; + bool pdn; + unsigned int val; + + dev_dbg(cs35l41->dev, "%s: event = 0x%x\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + regmap_multi_reg_write_bypassed(cs35l41->regmap, + cs35l41_pup_patch, + ARRAY_SIZE(cs35l41_pup_patch)); + + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, + CS35L41_GLOBAL_EN_MASK, + 1 << CS35L41_GLOBAL_EN_SHIFT); + + usleep_range(1000, 1100); + + atomic_set(&cs35l41->vol_ctl.playback, 1); + if (atomic_read(&cs35l41->vol_ctl.manual_ramp) || + cs35l41_need_auto_vol_ramp(cs35l41)) + /* Enable volume ramp */ + queue_work(cs35l41->vol_ctl.ramp_wq, + &cs35l41->vol_ctl.ramp_work); + break; + case SND_SOC_DAPM_POST_PMD: + if (cs35l41->dsp.running) { + if (cs35l41->reload_tuning) { + mboxcmd = CSPL_MBOX_CMD_STOP_PRE_REINIT; + /* + * Reset reload_tuning, so driver does not + * continuously reload tuning file + */ + cs35l41->reload_tuning = false; + } else { + mboxcmd = CSPL_MBOX_CMD_PAUSE; + } + ret = cs35l41_set_csplmboxcmd(cs35l41, mboxcmd); + } + + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, + CS35L41_GLOBAL_EN_MASK, 0); + + pdn = false; + for (i = 0; i < 100; i++) { + regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + &val); + if (val & CS35L41_PDN_DONE_MASK) { + pdn = true; + break; + } + usleep_range(1000, 1010); + } + + if (!pdn) + dev_warn(cs35l41->dev, "PDN failed\n"); + + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_PDN_DONE_MASK); + + regmap_multi_reg_write_bypassed(cs35l41->regmap, + cs35l41_pdn_patch, + ARRAY_SIZE(cs35l41_pdn_patch)); + atomic_set(&cs35l41->vol_ctl.playback, 0); + cs35l41_abort_ramp(cs35l41); + cs35l41->vol_ctl.prev_active_dev = cs35l41->vol_ctl.output_dev; + if (cs35l41->vol_ctl.output_dev == CS35L41_OUTPUT_DEV_RCV && + cs35l41->vol_ctl.auto_ramp_timeout > 0 && + cs35l41->vol_ctl.auto_ramp_timeout < + CS35L41_MAX_AUTO_RAMP_TIMEOUT) + /* Auto Receiver Timeout is used */ + cs35l41->vol_ctl.dev_timestamp = ktime_get(); + break; + default: + dev_err(cs35l41->dev, "Invalid event = 0x%x\n", event); + ret = -EINVAL; + } + return ret; +} + +static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = { + + SND_SOC_DAPM_SPK("DSP1 Preload", NULL), + SND_SOC_DAPM_SUPPLY_S("DSP1 Preloader", 100, SND_SOC_NOPM, 0, 0, + cs35l41_dsp_power_ev, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_OUT_DRV_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, + cs35l41_dsp_load_ev, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_OUTPUT("SPK"), + + SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0, CS35L41_SP_ENABLES, 16, 0), + SND_SOC_DAPM_AIF_IN("ASPRX2", NULL, 0, CS35L41_SP_ENABLES, 17, 0), + SND_SOC_DAPM_AIF_OUT("ASPTX1", NULL, 0, CS35L41_SP_ENABLES, 0, 0), + SND_SOC_DAPM_AIF_OUT("ASPTX2", NULL, 0, CS35L41_SP_ENABLES, 1, 0), + SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 0, CS35L41_SP_ENABLES, 2, 0), + SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 0, CS35L41_SP_ENABLES, 3, 0), + + SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L41_PWR_CTRL2, 12, 0), + SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L41_PWR_CTRL2, 13, 0), + SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L41_PWR_CTRL2, 8, 0), + SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L41_PWR_CTRL2, 9, 0), + SND_SOC_DAPM_ADC("TEMPMON ADC", NULL, CS35L41_PWR_CTRL2, 10, 0), + SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L41_PWR_CTRL3, 4, 0), + + SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0, + cs35l41_main_amp_event, + SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_INPUT("VP"), + SND_SOC_DAPM_INPUT("VBST"), + SND_SOC_DAPM_INPUT("ISENSE"), + SND_SOC_DAPM_INPUT("VSENSE"), + SND_SOC_DAPM_INPUT("TEMP"), + + SND_SOC_DAPM_MUX("ASPTX Ref", SND_SOC_NOPM, 0, 0, &virt_mux), + SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux), + SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux), + SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux), + SND_SOC_DAPM_MUX("ASP TX4 Source", SND_SOC_NOPM, 0, 0, &asp_tx4_mux), + SND_SOC_DAPM_MUX("DSP RX1 Source", SND_SOC_NOPM, 0, 0, &dsp_rx1_mux), + SND_SOC_DAPM_MUX("DSP RX2 Source", SND_SOC_NOPM, 0, 0, &dsp_rx2_mux), + SND_SOC_DAPM_MUX("PCM Source", SND_SOC_NOPM, 0, 0, &pcm_source_mux), + SND_SOC_DAPM_SWITCH("DRE", SND_SOC_NOPM, 0, 0, &dre_ctrl), + SND_SOC_DAPM_SWITCH("VBSTMON Output", SND_SOC_NOPM, 0, 0, + &vbstmon_out_ctrl), +}; + +static const struct snd_soc_dapm_widget cs35l41_hib_widgets[] = { + SND_SOC_DAPM_SUPPLY("Hibernate", SND_SOC_NOPM, 0, 0, cs35l41_hibernate, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route cs35l41_audio_map[] = { + + { "DSP1", NULL, "DSP1 Preloader" }, + { "DSP1 Preload", NULL, "DSP1 Preloader" }, + + { "DSP RX1 Source", "VMON", "VMON ADC" }, + { "DSP RX1 Source", "IMON", "IMON ADC" }, + { "DSP RX1 Source", "VPMON", "VPMON ADC" }, + { "DSP RX1 Source", "DSPTX1", "DSP1" }, + { "DSP RX1 Source", "DSPTX2", "DSP1" }, + { "DSP RX1 Source", "ASPRX1", "ASPRX1" }, + { "DSP RX1 Source", "ASPRX2", "ASPRX2" }, + { "DSP RX1 Source", "Zero", "ASPRX1" }, + { "DSP1", NULL, "DSP RX1 Source" }, + + { "DSP RX2 Source", "VMON", "VMON ADC" }, + { "DSP RX2 Source", "IMON", "IMON ADC" }, + { "DSP RX2 Source", "VPMON", "VPMON ADC" }, + { "DSP RX2 Source", "DSPTX1", "DSP1" }, + { "DSP RX2 Source", "DSPTX2", "DSP1" }, + { "DSP RX2 Source", "ASPRX1", "ASPRX1" }, + { "DSP RX2 Source", "ASPRX2", "ASPRX2" }, + { "DSP RX2 Source", "Zero", "ASPRX1" }, + { "DSP1", NULL, "DSP RX2 Source" }, + + { "ASP TX1 Source", "VMON", "VMON ADC" }, + { "ASP TX1 Source", "IMON", "IMON ADC" }, + { "ASP TX1 Source", "VPMON", "VPMON ADC" }, + { "ASP TX1 Source", "VBSTMON", "VBSTMON ADC" }, + { "ASP TX1 Source", "DSPTX1", "DSP1" }, + { "ASP TX1 Source", "DSPTX2", "DSP1" }, + { "ASP TX1 Source", "ASPRX1", "ASPRX1" }, + { "ASP TX1 Source", "ASPRX2", "ASPRX2" }, + { "ASP TX2 Source", "VMON", "VMON ADC" }, + { "ASP TX2 Source", "IMON", "IMON ADC" }, + { "ASP TX2 Source", "VPMON", "VPMON ADC" }, + { "ASP TX2 Source", "VBSTMON", "VBSTMON ADC" }, + { "ASP TX2 Source", "DSPTX1", "DSP1" }, + { "ASP TX2 Source", "DSPTX2", "DSP1" }, + { "ASP TX2 Source", "ASPRX1", "ASPRX1" }, + { "ASP TX2 Source", "ASPRX2", "ASPRX2" }, + { "ASP TX3 Source", "VMON", "VMON ADC" }, + { "ASP TX3 Source", "IMON", "IMON ADC" }, + { "ASP TX3 Source", "VPMON", "VPMON ADC" }, + { "ASP TX3 Source", "VBSTMON", "VBSTMON ADC" }, + { "ASP TX3 Source", "DSPTX1", "DSP1" }, + { "ASP TX3 Source", "DSPTX2", "DSP1" }, + { "ASP TX3 Source", "ASPRX1", "ASPRX1" }, + { "ASP TX3 Source", "ASPRX2", "ASPRX2" }, + { "ASP TX4 Source", "VMON", "VMON ADC" }, + { "ASP TX4 Source", "IMON", "IMON ADC" }, + { "ASP TX4 Source", "VPMON", "VPMON ADC" }, + { "ASP TX4 Source", "VBSTMON", "VBSTMON ADC" }, + { "ASP TX4 Source", "DSPTX1", "DSP1" }, + { "ASP TX4 Source", "DSPTX2", "DSP1" }, + { "ASP TX4 Source", "ASPRX1", "ASPRX1" }, + { "ASP TX4 Source", "ASPRX2", "ASPRX2" }, + { "ASPTX1", NULL, "ASP TX1 Source" }, + { "ASPTX2", NULL, "ASP TX2 Source" }, + { "ASPTX3", NULL, "ASP TX3 Source" }, + { "ASPTX4", NULL, "ASP TX4 Source" }, + { "AMP Capture", NULL, "ASPTX1" }, + { "AMP Capture", NULL, "ASPTX2" }, + { "AMP Capture", NULL, "ASPTX3" }, + { "AMP Capture", NULL, "ASPTX4" }, + + { "VMON ADC", NULL, "ASPRX1" }, + { "IMON ADC", NULL, "ASPRX1" }, + { "VPMON ADC", NULL, "ASPRX1" }, + { "TEMPMON ADC", NULL, "ASPRX1" }, + { "VBSTMON ADC", NULL, "ASPRX1" }, + + { "VBSTMON Output", "Switch", "VBST" }, + { "CLASS H", NULL, "VBSTMON Output" }, + { "VBSTMON ADC", NULL, "VBSTMON Output" }, + + { "DSP1", NULL, "IMON ADC" }, + { "DSP1", NULL, "VMON ADC" }, + { "DSP1", NULL, "VBSTMON ADC" }, + { "DSP1", NULL, "VPMON ADC" }, + { "DSP1", NULL, "TEMPMON ADC" }, + + { "ASPRX1", NULL, "AMP Playback" }, + { "ASPRX2", NULL, "AMP Playback" }, + { "DRE", "DRE Switch", "CLASS H" }, + { "ASPTX Ref", "Ref", "ASPTX1" }, + { "ASPTX Ref", "Ref", "ASPTX2" }, + { "Main AMP", NULL, "ASPTX Ref" }, + { "Main AMP", NULL, "CLASS H" }, + { "Main AMP", NULL, "DRE" }, + { "SPK", NULL, "Main AMP" }, + + { "PCM Source", "ASP", "ASPRX1" }, + { "PCM Source", "DSP", "DSP1" }, + { "CLASS H", NULL, "PCM Source" }, + +}; + +static const struct snd_soc_dapm_route cs35l41_hib_map[] = { + { "SPK", NULL, "Hibernate" }, +}; + +static const struct wm_adsp_region cs35l41_dsp1_regions[] = { + { .type = WMFW_HALO_PM_PACKED, .base = CS35L41_DSP1_PMEM_0 }, + { .type = WMFW_HALO_XM_PACKED, .base = CS35L41_DSP1_XMEM_PACK_0 }, + { .type = WMFW_HALO_YM_PACKED, .base = CS35L41_DSP1_YMEM_PACK_0 }, + { .type = WMFW_ADSP2_XM, .base = CS35L41_DSP1_XMEM_UNPACK24_0 }, + { .type = WMFW_ADSP2_YM, .base = CS35L41_DSP1_YMEM_UNPACK24_0 }, +}; + +static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(codec_dai->component); + unsigned int asp_fmt, lrclk_fmt, sclk_fmt, slave_mode; + + dev_dbg(cs35l41->dev, "%s: fmt = 0x%x\n", __func__, fmt); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + slave_mode = 1; + break; + case SND_SOC_DAIFMT_CBS_CFS: + slave_mode = 0; + break; + default: + dev_warn(cs35l41->dev, "%s: Mixed master mode unsupported\n", + __func__); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + asp_fmt = 0; + cs35l41->i2s_mode = false; + cs35l41->dspa_mode = true; + break; + case SND_SOC_DAIFMT_I2S: + asp_fmt = 2; + cs35l41->i2s_mode = true; + cs35l41->dspa_mode = false; + break; + default: + dev_warn(cs35l41->dev, + "%s: Invalid or unsupported DAI format\n", __func__); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_IF: + lrclk_fmt = 1; + sclk_fmt = 0; + break; + case SND_SOC_DAIFMT_IB_NF: + lrclk_fmt = 0; + sclk_fmt = 1; + break; + case SND_SOC_DAIFMT_IB_IF: + lrclk_fmt = 1; + sclk_fmt = 1; + break; + case SND_SOC_DAIFMT_NB_NF: + lrclk_fmt = 0; + sclk_fmt = 0; + break; + default: + dev_warn(cs35l41->dev, "%s: Invalid DAI clock INV\n", __func__); + return -EINVAL; + } + + cs35l41->reset_cache.slave_mode = slave_mode; + cs35l41->reset_cache.asp_fmt = asp_fmt; + cs35l41->reset_cache.lrclk_fmt = lrclk_fmt; + cs35l41->reset_cache.sclk_fmt = sclk_fmt; + /* Amp is in reset. Cache values to be applied later. */ + if (cs35l41->amp_hibernate == CS35L41_HIBERNATE_STANDBY) + return 0; + + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_ASP_FMT_MASK, + asp_fmt << CS35L41_ASP_FMT_SHIFT); + + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_SCLK_MSTR_MASK, + slave_mode << CS35L41_SCLK_MSTR_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_LRCLK_MSTR_MASK, + slave_mode << CS35L41_LRCLK_MSTR_SHIFT); + + cs35l41->lrclk_fmt = lrclk_fmt; + cs35l41->sclk_fmt = sclk_fmt; + + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_LRCLK_INV_MASK, + lrclk_fmt << CS35L41_LRCLK_INV_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_SCLK_INV_MASK, + sclk_fmt << CS35L41_SCLK_INV_SHIFT); + + return 0; +} + +struct cs35l41_global_fs_config { + int rate; + int fs_cfg; +}; + +static const struct cs35l41_global_fs_config cs35l41_fs_rates[] = { + { 12000, 0x01 }, { 24000, 0x02 }, { 48000, 0x03 }, { 96000, 0x04 }, + { 192000, 0x05 }, { 11025, 0x09 }, { 22050, 0x0A }, { 44100, 0x0B }, + { 88200, 0x0C }, { 176400, 0x0D }, { 8000, 0x11 }, { 16000, 0x12 }, + { 32000, 0x13 }, +}; + +static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(dai->component); + int i; + unsigned int rate = params_rate(params); + u8 asp_width, asp_wl; + + for (i = 0; i < ARRAY_SIZE(cs35l41_fs_rates); i++) { + if (rate == cs35l41_fs_rates[i].rate) + break; + } + + asp_wl = params_width(params); + asp_width = params_physical_width(params); + + dev_dbg(cs35l41->dev, "%s: rate = %u, asp_wl = %u, asp_width = %u\n", + __func__, rate, asp_wl, asp_width); + + cs35l41->reset_cache.asp_wl = asp_wl; + cs35l41->reset_cache.asp_width = asp_width; + if (i < ARRAY_SIZE(cs35l41_fs_rates)) + cs35l41->reset_cache.fs_cfg = cs35l41_fs_rates[i].fs_cfg; + + /* Amp is in reset. Cache values to be applied later */ + if (cs35l41->amp_hibernate == CS35L41_HIBERNATE_STANDBY) + return 0; + + regmap_update_bits(cs35l41->regmap, CS35L41_GLOBAL_CLK_CTRL, + CS35L41_GLOBAL_FS_MASK, + cs35l41_fs_rates[i].fs_cfg + << CS35L41_GLOBAL_FS_SHIFT); + + cs35l41_component_set_sysclk(dai->component, 0, 0, 8 * rate * asp_width, + 0); + + /* Note: To keep RX and TX using same data width */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || + substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + //if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_ASP_WIDTH_RX_MASK, + asp_width << CS35L41_ASP_WIDTH_RX_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_RX_WL, + CS35L41_ASP_RX_WL_MASK, + asp_wl << CS35L41_ASP_RX_WL_SHIFT); + if (cs35l41->i2s_mode) { + regmap_update_bits( + cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, + CS35L41_ASP_RX1_SLOT_MASK, + ((cs35l41->pdata.right_channel) ? 1 : 0) + << CS35L41_ASP_RX1_SLOT_SHIFT); + regmap_update_bits( + cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, + CS35L41_ASP_RX2_SLOT_MASK, + ((cs35l41->pdata.right_channel) ? 0 : 1) + << CS35L41_ASP_RX2_SLOT_SHIFT); + } + //} else { + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_ASP_WIDTH_TX_MASK, + asp_width << CS35L41_ASP_WIDTH_TX_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_TX_WL, + CS35L41_ASP_TX_WL_MASK, + asp_wl << CS35L41_ASP_TX_WL_SHIFT); + } + + return 0; +} + +static int cs35l41_get_clk_config(int freq) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs35l41_pll_sysclk); i++) { + if (cs35l41_pll_sysclk[i].freq == freq) + return cs35l41_pll_sysclk[i].clk_cfg; + } + + return -EINVAL; +} + +static const unsigned int cs35l41_src_rates[] = { 8000, 12000, 11025, 16000, + 22050, 24000, 32000, 44100, + 48000, 88200, 96000, 176400, + 192000 }; + +static const struct snd_pcm_hw_constraint_list cs35l41_constraints = { + .count = ARRAY_SIZE(cs35l41_src_rates), + .list = cs35l41_src_rates, +}; + +static int cs35l41_pcm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(dai->component); + + dev_dbg(cs35l41->dev, "%s\n", __func__); + cs35l41_set_dai_fmt(dai, SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_DSP_A); + + if (substream->runtime) + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &cs35l41_constraints); + return 0; +} + +static int cs35l41_component_set_sysclk(struct snd_soc_component *component, + int clk_id, int source, + unsigned int freq, int dir) +{ + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + + dev_dbg(cs35l41->dev, + "%s: clk_id = %d, source = %d, freq = %u, dir = %d\n", __func__, + clk_id, source, freq, dir); + + cs35l41->extclk_freq = freq; + + switch (clk_id) { + case 0: + cs35l41->clksrc = CS35L41_PLLSRC_SCLK; + break; + case 1: + cs35l41->clksrc = CS35L41_PLLSRC_LRCLK; + break; + case 2: + cs35l41->clksrc = CS35L41_PLLSRC_PDMCLK; + break; + case 3: + cs35l41->clksrc = CS35L41_PLLSRC_SELF; + break; + case 4: + cs35l41->clksrc = CS35L41_PLLSRC_MCLK; + break; + default: + dev_err(cs35l41->dev, "Invalid CLK Config\n"); + return -EINVAL; + } + + cs35l41->extclk_cfg = cs35l41_get_clk_config(freq); + + if (cs35l41->extclk_cfg < 0) { + dev_err(cs35l41->dev, "Invalid CLK Config: %d, freq: %u\n", + cs35l41->extclk_cfg, freq); + return -EINVAL; + } + + cs35l41->reset_cache.extclk_cfg = true; + /* Amp is in reset. Set flag to restore clock config */ + if (cs35l41->amp_hibernate == CS35L41_HIBERNATE_STANDBY) + return 0; + + regmap_read(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, &freq); + freq &= (CS35L41_REFCLK_FREQ_MASK | CS35L41_PLL_CLK_EN_MASK | + CS35L41_PLL_CLK_SEL_MASK); + if ((cs35l41->extclk_cfg << CS35L41_REFCLK_FREQ_SHIFT | + CS35L41_PLL_CLK_EN_MASK | cs35l41->clksrc) == freq) { + dev_dbg(cs35l41->dev, "%s: Ignore duplicate PLL setting\n", + __func__); + return 0; + } + + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_OPENLOOP_MASK, + 1 << CS35L41_PLL_OPENLOOP_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_REFCLK_FREQ_MASK, + cs35l41->extclk_cfg << CS35L41_REFCLK_FREQ_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_CLK_EN_MASK, + 0 << CS35L41_PLL_CLK_EN_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_CLK_SEL_MASK, cs35l41->clksrc); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_OPENLOOP_MASK, + 0 << CS35L41_PLL_OPENLOOP_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_CLK_EN_MASK, + 1 << CS35L41_PLL_CLK_EN_SHIFT); + + return 0; +} + +static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) +{ + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(dai->component); + unsigned int fs1_val = 0; + unsigned int fs2_val = 0; + unsigned int val; + + dev_dbg(cs35l41->dev, "%s: clk_id = %d, freq = %u, dir = %d\n", + __func__, clk_id, freq, dir); + + if (cs35l41_get_clk_config(freq) < 0) { + dev_err(cs35l41->dev, "Invalid CLK Config freq: %u\n", freq); + return -EINVAL; + } + + /* Need the SCLK Frequency regardless of sysclk source */ + cs35l41->sclk = freq; + + dev_dbg(cs35l41->dev, "Set DAI sysclk %d\n", freq); + if (cs35l41->sclk > 6000000) { + fs1_val = 3 * 4 + 4; + fs2_val = 8 * 4 + 4; + } + + if (cs35l41->sclk <= 6000000) { + fs1_val = 3 * ((24000000 + cs35l41->sclk - 1) / cs35l41->sclk) + + 4; + fs2_val = 5 * ((24000000 + cs35l41->sclk - 1) / cs35l41->sclk) + + 4; + } + + val = fs1_val; + val |= (fs2_val << CS35L41_FS2_WINDOW_SHIFT) & CS35L41_FS2_WINDOW_MASK; + regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055); + regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); + regmap_write(cs35l41->regmap, CS35L41_TST_FS_MON0, val); + regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); + regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033); + + return 0; +} + +static int cs35l41_boost_config(struct cs35l41_private *cs35l41, int boost_ind, + int boost_cap, int boost_ipk) +{ + int ret; + unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled; + struct regmap *regmap = cs35l41->regmap; + struct device *dev = cs35l41->dev; + + switch (boost_ind) { + case 1000: /* 1.0 uH */ + bst_lbst_val = 0; + break; + case 1200: /* 1.2 uH */ + bst_lbst_val = 1; + break; + case 1500: /* 1.5 uH */ + bst_lbst_val = 2; + break; + case 2200: /* 2.2 uH */ + bst_lbst_val = 3; + break; + default: + dev_err(dev, "Invalid boost inductor value: %d nH\n", + boost_ind); + return -EINVAL; + } + + switch (boost_cap) { + case 0 ... 19: + bst_cbst_range = 0; + break; + case 20 ... 50: + bst_cbst_range = 1; + break; + case 51 ... 100: + bst_cbst_range = 2; + break; + case 101 ... 200: + bst_cbst_range = 3; + break; + default: /* 201 uF and greater */ + bst_cbst_range = 4; + } + + ret = regmap_update_bits( + regmap, CS35L41_BSTCVRT_COEFF, CS35L41_BST_K1_MASK, + cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range] + << CS35L41_BST_K1_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost K1 coefficient\n"); + return ret; + } + + ret = regmap_update_bits( + regmap, CS35L41_BSTCVRT_COEFF, CS35L41_BST_K2_MASK, + cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range] + << CS35L41_BST_K2_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost K2 coefficient\n"); + return ret; + } + + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, + CS35L41_BST_SLOPE_MASK, + cs35l41_bst_slope_table[bst_lbst_val] + << CS35L41_BST_SLOPE_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost slope coefficient\n"); + return ret; + } + + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, + CS35L41_BST_LBST_VAL_MASK, + bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost inductor value\n"); + return ret; + } + + if ((boost_ipk < 1600) || (boost_ipk > 4500)) { + dev_err(dev, "Invalid boost inductor peak current: %d mA\n", + boost_ipk); + return -EINVAL; + } + bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10; + + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR, + CS35L41_BST_IPK_MASK, + bst_ipk_scaled << CS35L41_BST_IPK_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost inductor peak current\n"); + return ret; + } + + return 0; +} + +static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) +{ + struct classh_cfg *classh = &cs35l41->pdata.classh_config; + int ret; + u32 devid_otp; + + /* Set Platform Data */ + /* Required */ + if (cs35l41->pdata.bst_ipk && cs35l41->pdata.bst_ind && + cs35l41->pdata.bst_cap) { + ret = cs35l41_boost_config(cs35l41, cs35l41->pdata.bst_ind, + cs35l41->pdata.bst_cap, + cs35l41->pdata.bst_ipk); + if (ret) { + dev_err(cs35l41->dev, "Error in Boost DT config\n"); + return ret; + } + } else { + dev_err(cs35l41->dev, "Incomplete Boost component DT config\n"); + return -EINVAL; + } + + /* Optional */ + if (cs35l41->pdata.sclk_frc) + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_SCLK_FRC_MASK, + cs35l41->pdata.sclk_frc + << CS35L41_SCLK_FRC_SHIFT); + + if (cs35l41->pdata.lrclk_frc) + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_LRCLK_FRC_MASK, + cs35l41->pdata.lrclk_frc + << CS35L41_LRCLK_FRC_SHIFT); + + if (cs35l41->pdata.amp_gain_zc) + regmap_update_bits(cs35l41->regmap, CS35L41_AMP_GAIN_CTRL, + CS35L41_AMP_GAIN_ZC_MASK, + cs35l41->pdata.amp_gain_zc + << CS35L41_AMP_GAIN_ZC_SHIFT); + + if (cs35l41->pdata.bst_vctrl) + regmap_update_bits(cs35l41->regmap, CS35L41_BSTCVRT_VCTRL1, + CS35L41_BST_CTL_MASK, + cs35l41->pdata.bst_vctrl); + + if (cs35l41->pdata.temp_warn_thld) + regmap_update_bits(cs35l41->regmap, CS35L41_DTEMP_WARN_THLD, + CS35L41_TEMP_THLD_MASK, + cs35l41->pdata.temp_warn_thld); + + if (cs35l41->pdata.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && + cs35l41->pdata.dout_hiz >= 0) + regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL, + CS35L41_ASP_DOUT_HIZ_MASK, + cs35l41->pdata.dout_hiz); + + if (cs35l41->pdata.invert_pcm) + regmap_update_bits(cs35l41->regmap, CS35L41_AMP_DIG_VOL_CTRL, + CS35L41_AMP_INV_PCM_MASK, + cs35l41->pdata.invert_pcm + << CS35L41_AMP_INV_PCM_SHIFT); + + if (cs35l41->pdata.dsp_ng_enable) { + regmap_update_bits(cs35l41->regmap, CS35L41_MIXER_NGATE_CH1_CFG, + CS35L41_DSP_NG_ENABLE_MASK, + CS35L41_DSP_NG_ENABLE_MASK); + regmap_update_bits(cs35l41->regmap, CS35L41_MIXER_NGATE_CH2_CFG, + CS35L41_DSP_NG_ENABLE_MASK, + CS35L41_DSP_NG_ENABLE_MASK); + + if (cs35l41->pdata.dsp_ng_pcm_thld) { + regmap_update_bits(cs35l41->regmap, + CS35L41_MIXER_NGATE_CH1_CFG, + CS35L41_DSP_NG_THLD_MASK, + cs35l41->pdata.dsp_ng_pcm_thld); + regmap_update_bits(cs35l41->regmap, + CS35L41_MIXER_NGATE_CH2_CFG, + CS35L41_DSP_NG_THLD_MASK, + cs35l41->pdata.dsp_ng_pcm_thld); + } + + if (cs35l41->pdata.dsp_ng_delay) { + regmap_update_bits( + cs35l41->regmap, CS35L41_MIXER_NGATE_CH1_CFG, + CS35L41_DSP_NG_DELAY_MASK, + cs35l41->pdata.dsp_ng_delay + << CS35L41_DSP_NG_DELAY_SHIFT); + regmap_update_bits( + cs35l41->regmap, CS35L41_MIXER_NGATE_CH2_CFG, + CS35L41_DSP_NG_DELAY_MASK, + cs35l41->pdata.dsp_ng_delay + << CS35L41_DSP_NG_DELAY_SHIFT); + } + } + + if (cs35l41->pdata.hw_ng_sel) + regmap_update_bits( + cs35l41->regmap, CS35L41_NG_CFG, CS35L41_HW_NG_SEL_MASK, + cs35l41->pdata.hw_ng_sel << CS35L41_HW_NG_SEL_SHIFT); + + if (cs35l41->pdata.hw_ng_thld) + regmap_update_bits(cs35l41->regmap, CS35L41_NG_CFG, + CS35L41_HW_NG_THLD_MASK, + cs35l41->pdata.hw_ng_thld + << CS35L41_HW_NG_THLD_SHIFT); + + if (cs35l41->pdata.hw_ng_delay) + regmap_update_bits( + cs35l41->regmap, CS35L41_NG_CFG, CS35L41_HW_NG_DLY_MASK, + cs35l41->pdata.hw_ng_delay << CS35L41_HW_NG_DLY_SHIFT); + + if (regmap_read(cs35l41->regmap, CS35L41_DEVID_OTP, &devid_otp) < 0) { + dev_err(cs35l41->dev, "Read DEVID OTP failed\n"); + return -EINVAL; + } + if (classh->classh_algo_enable) { + if (classh->classh_bst_override && + devid_otp != CS35L41LV_CHIP_ID) + regmap_update_bits(cs35l41->regmap, + CS35L41_BSTCVRT_VCTRL2, + CS35L41_BST_CTL_SEL_MASK, + CS35L41_BST_CTL_SEL_REG); + if (classh->classh_bst_max_limit && + devid_otp != CS35L41LV_CHIP_ID) + regmap_update_bits(cs35l41->regmap, + CS35L41_BSTCVRT_VCTRL2, + CS35L41_BST_LIM_MASK, + classh->classh_bst_max_limit + << CS35L41_BST_LIM_SHIFT); + if (classh->classh_mem_depth) + regmap_update_bits( + cs35l41->regmap, CS35L41_CLASSH_CFG, + CS35L41_CH_MEM_DEPTH_MASK, + classh->classh_mem_depth + << CS35L41_CH_MEM_DEPTH_SHIFT); + if (classh->classh_headroom) + regmap_update_bits( + cs35l41->regmap, CS35L41_CLASSH_CFG, + CS35L41_CH_HDRM_CTL_MASK, + classh->classh_headroom + << CS35L41_CH_HDRM_CTL_SHIFT); + if (classh->classh_release_rate) + regmap_update_bits( + cs35l41->regmap, CS35L41_CLASSH_CFG, + CS35L41_CH_REL_RATE_MASK, + classh->classh_release_rate + << CS35L41_CH_REL_RATE_SHIFT); + if (classh->classh_wk_fet_delay) + regmap_update_bits( + cs35l41->regmap, CS35L41_WKFET_CFG, + CS35L41_CH_WKFET_DLY_MASK, + classh->classh_wk_fet_delay + << CS35L41_CH_WKFET_DLY_SHIFT); + if (classh->classh_wk_fet_thld) + regmap_update_bits( + cs35l41->regmap, CS35L41_WKFET_CFG, + CS35L41_CH_WKFET_THLD_MASK, + classh->classh_wk_fet_thld + << CS35L41_CH_WKFET_THLD_SHIFT); + } + + return 0; +} + +static int cs35l41_component_probe(struct snd_soc_component *component) +{ + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + struct snd_kcontrol_new *kcontrol; + int ret = 0; + u32 devid_otp; + + dev_info(cs35l41->dev, "cs35l41_component_probe E\n"); + component->regmap = cs35l41->regmap; + + cs35l41_set_pdata(cs35l41); + ret = regmap_read(cs35l41->regmap, CS35L41_DEVID_OTP, &devid_otp); + if (ret < 0) { + dev_err(cs35l41->dev, "Read DEVID OTP failed\n"); + ret = -EINVAL; + goto exit; + } + if (devid_otp == CS35L41LV_CHIP_ID) + /* BST_CTL_LIM_EN = 1 BST_CTL_SEL = b'01 (Class H tracking) */ + regmap_write(cs35l41->regmap, CS35L41_BSTCVRT_VCTRL2, 0x5); + + dev_err(cs35l41->dev, "skip wm_adsp\n"); + /* These should only run once, not every hibernate cycle */ + if (!(cs35l41->skip_codec_probe)) { + wm_adsp2_component_probe(&cs35l41->dsp, component); + cs35l41->skip_codec_probe = true; + + /* Add run-time mixer control for fast use case switch */ + kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); + if (!kcontrol) { + ret = -ENOMEM; + goto exit; + } + kcontrol->name = "Fast Use Case Delta File"; + kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER; + kcontrol->info = snd_soc_info_enum_double; + kcontrol->get = cs35l41_fast_switch_file_get; + kcontrol->put = cs35l41_fast_switch_file_put; + kcontrol->private_value = + (unsigned long)&cs35l41->fast_switch_enum; + ret = snd_soc_add_component_controls(component, kcontrol, 1); + if (ret < 0) + dev_err(cs35l41->dev, + "snd_soc_add_codec_controls failed (%d)\n", + ret); + + dev_dbg(cs35l41->dev, "Start queue boot_work\n"); + //queue_work(system_highpri_wq, &cs35l41->dsp.boot_work); + queue_work(cs35l41->dsp.work_queue, &cs35l41->dsp.boot_work); + kfree(kcontrol); + } +exit: + dev_info(cs35l41->dev, "cs35l41_component_probe X\n"); + return ret; +} + +static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41) +{ + struct irq_cfg *irq_gpio_cfg1 = &cs35l41->pdata.irq_config1; + struct irq_cfg *irq_gpio_cfg2 = &cs35l41->pdata.irq_config2; + int irq_pol = IRQF_TRIGGER_NONE; + + if (irq_gpio_cfg1->is_present) { + if (irq_gpio_cfg1->irq_pol_inv) + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1, + CS35L41_GPIO_POL_MASK, + CS35L41_GPIO_POL_MASK); + if (irq_gpio_cfg1->irq_out_en) + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1, + CS35L41_GPIO_DIR_MASK, 0); + if (irq_gpio_cfg1->irq_src_sel) + regmap_update_bits(cs35l41->regmap, + CS35L41_GPIO_PAD_CONTROL, + CS35L41_GPIO1_CTRL_MASK, + irq_gpio_cfg1->irq_src_sel + << CS35L41_GPIO1_CTRL_SHIFT); + } + + if (irq_gpio_cfg2->is_present) { + if (irq_gpio_cfg2->irq_pol_inv) + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1, + CS35L41_GPIO_POL_MASK, + CS35L41_GPIO_POL_MASK); + if (irq_gpio_cfg2->irq_out_en) + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1, + CS35L41_GPIO_DIR_MASK, 0); + if (irq_gpio_cfg2->irq_src_sel) + regmap_update_bits(cs35l41->regmap, + CS35L41_GPIO_PAD_CONTROL, + CS35L41_GPIO2_CTRL_MASK, + irq_gpio_cfg2->irq_src_sel + << CS35L41_GPIO2_CTRL_SHIFT); + } + + if (irq_gpio_cfg2->irq_src_sel == + (CS35L41_GPIO_CTRL_ACTV_LO | CS35L41_VALID_PDATA)) + irq_pol = IRQF_TRIGGER_LOW; + else if (irq_gpio_cfg2->irq_src_sel == + (CS35L41_GPIO_CTRL_ACTV_HI | CS35L41_VALID_PDATA)) + irq_pol = IRQF_TRIGGER_HIGH; + + return irq_pol; +} + +static void cs35l41_component_remove(struct snd_soc_component *component) +{ + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(component); + + wm_adsp2_component_remove(&cs35l41->dsp, component); +} + +static const struct snd_soc_dai_ops cs35l41_ops = { + .startup = cs35l41_pcm_startup, + .set_fmt = cs35l41_set_dai_fmt, + .hw_params = cs35l41_pcm_hw_params, + .set_sysclk = cs35l41_dai_set_sysclk, +}; + +static struct snd_soc_dai_driver cs35l41_dai[] = { + { + .name = "cs35l41-pcm", + .id = 0, + .playback = { + .stream_name = "AMP Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = CS35L41_RX_FORMATS, + }, + .capture = { + .stream_name = "AMP Capture", + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = CS35L41_TX_FORMATS, + }, + .ops = &cs35l41_ops, + .symmetric_rates = 1, + }, +}; + +static struct snd_soc_component_driver soc_component_dev_cs35l41 = { + .probe = cs35l41_component_probe, + .remove = cs35l41_component_remove, + + .dapm_widgets = cs35l41_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(cs35l41_dapm_widgets), + + .set_sysclk = cs35l41_component_set_sysclk, +}; + +static int cs35l41_handle_of_data(struct device *dev, + struct cs35l41_platform_data *pdata, + struct cs35l41_private *cs35l41) +{ + struct device_node *np = dev->of_node; + unsigned int val; + int ret; + size_t num_fast_switch; + struct device_node *sub_node; + struct classh_cfg *classh_config = &pdata->classh_config; + struct irq_cfg *irq_gpio1_config = &pdata->irq_config1; + struct irq_cfg *irq_gpio2_config = &pdata->irq_config2; + unsigned int i; + + if (!np) + return 0; + + ret = of_property_count_strings(np, "cirrus,fast-switch"); + if (ret < 0) { + /* + * device tree do not provide file name. + * Use default value + */ + num_fast_switch = ARRAY_SIZE(cs35l41_fast_switch_text); + cs35l41->fast_switch_enum.items = + ARRAY_SIZE(cs35l41_fast_switch_text); + cs35l41->fast_switch_enum.texts = cs35l41_fast_switch_text; + cs35l41->fast_switch_names = cs35l41_fast_switch_text; + } else { + /* Device tree provides file name */ + num_fast_switch = (size_t)ret; + dev_info(dev, "num_fast_switch:%zu\n", num_fast_switch); + cs35l41->fast_switch_names = devm_kmalloc( + dev, num_fast_switch * sizeof(char *), GFP_KERNEL); + if (!cs35l41->fast_switch_names) + return -ENOMEM; + of_property_read_string_array(np, "cirrus,fast-switch", + cs35l41->fast_switch_names, + num_fast_switch); + for (i = 0; i < num_fast_switch; i++) { + dev_info(dev, "%d:%s\n", i, + cs35l41->fast_switch_names[i]); + } + cs35l41->fast_switch_enum.items = num_fast_switch; + cs35l41->fast_switch_enum.texts = cs35l41->fast_switch_names; + } + + cs35l41->fast_switch_enum.reg = SND_SOC_NOPM; + cs35l41->fast_switch_enum.shift_l = 0; + cs35l41->fast_switch_enum.shift_r = 0; + cs35l41->fast_switch_enum.mask = + roundup_pow_of_two(num_fast_switch) - 1; + + pdata->right_channel = + of_property_read_bool(np, "cirrus,right-channel-amp"); + pdata->sclk_frc = of_property_read_bool(np, "cirrus,sclk-force-output"); + pdata->lrclk_frc = + of_property_read_bool(np, "cirrus,lrclk-force-output"); + pdata->amp_gain_zc = of_property_read_bool(np, "cirrus,amp-gain-zc"); + pdata->tuning_has_prefix = + of_property_read_bool(np, "cirrus,tuning-has-prefix"); + pdata->invert_pcm = of_property_read_bool(np, "cirrus,invert-pcm"); + + pdata->fwname_use_revid = + of_property_read_bool(np, "cirrus,fwname-use-revid"); + + if (of_property_read_u32(np, "cirrus,temp-warn_threshold", &val) >= 0) + pdata->temp_warn_thld = val | CS35L41_VALID_PDATA; + + ret = of_property_read_u32(np, "cirrus,boost-ctl-millivolt", &val); + if (ret >= 0) { + if (val < 2550 || val > 11000) { + dev_err(dev, "Invalid Boost Voltage %u mV\n", val); + return -EINVAL; + } + pdata->bst_vctrl = ((val - 2550) / 100) + 1; + } + + ret = of_property_read_u32(np, "cirrus,boost-peak-milliamp", &val); + if (ret >= 0) + pdata->bst_ipk = val; + + ret = of_property_read_u32(np, "cirrus,boost-ind-nanohenry", &val); + if (ret >= 0) + pdata->bst_ind = val; + + ret = of_property_read_u32(np, "cirrus,boost-cap-microfarad", &val); + if (ret >= 0) + pdata->bst_cap = val; + + ret = of_property_read_u32(np, "cirrus,asp-sdout-hiz", &val); + if (ret >= 0) + pdata->dout_hiz = val; + else + pdata->dout_hiz = -1; + + pdata->dsp_ng_enable = + of_property_read_bool(np, "cirrus,dsp-noise-gate-enable"); + if (of_property_read_u32(np, "cirrus,dsp-noise-gate-threshold", &val) >= + 0) + pdata->dsp_ng_pcm_thld = val | CS35L41_VALID_PDATA; + if (of_property_read_u32(np, "cirrus,dsp-noise-gate-delay", &val) >= 0) + pdata->dsp_ng_delay = val | CS35L41_VALID_PDATA; + + if (of_property_read_u32(np, "cirrus,hw-noise-gate-select", &val) >= 0) + pdata->hw_ng_sel = val | CS35L41_VALID_PDATA; + if (of_property_read_u32(np, "cirrus,hw-noise-gate-threshold", &val) >= + 0) + pdata->hw_ng_thld = val | CS35L41_VALID_PDATA; + if (of_property_read_u32(np, "cirrus,hw-noise-gate-delay", &val) >= 0) + pdata->hw_ng_delay = val | CS35L41_VALID_PDATA; + + sub_node = of_get_child_by_name(np, "cirrus,classh-internal-algo"); + classh_config->classh_algo_enable = sub_node ? true : false; + + if (classh_config->classh_algo_enable) { + classh_config->classh_bst_override = of_property_read_bool( + sub_node, "cirrus,classh-bst-overide"); + + ret = of_property_read_u32(sub_node, + "cirrus,classh-bst-max-limit", &val); + if (ret >= 0) { + val |= CS35L41_VALID_PDATA; + classh_config->classh_bst_max_limit = val; + } + + ret = of_property_read_u32(sub_node, "cirrus,classh-mem-depth", + &val); + if (ret >= 0) { + val |= CS35L41_VALID_PDATA; + classh_config->classh_mem_depth = val; + } + + ret = of_property_read_u32(sub_node, + "cirrus,classh-release-rate", &val); + if (ret >= 0) + classh_config->classh_release_rate = val; + + ret = of_property_read_u32(sub_node, "cirrus,classh-headroom", + &val); + if (ret >= 0) { + val |= CS35L41_VALID_PDATA; + classh_config->classh_headroom = val; + } + + ret = of_property_read_u32(sub_node, + "cirrus,classh-wk-fet-delay", &val); + if (ret >= 0) { + val |= CS35L41_VALID_PDATA; + classh_config->classh_wk_fet_delay = val; + } + + ret = of_property_read_u32(sub_node, + "cirrus,classh-wk-fet-thld", &val); + if (ret >= 0) + classh_config->classh_wk_fet_thld = val; + } + of_node_put(sub_node); + + /* GPIO1 Pin Config */ + sub_node = of_get_child_by_name(np, "cirrus,gpio-config1"); + irq_gpio1_config->is_present = sub_node ? true : false; + if (irq_gpio1_config->is_present) { + irq_gpio1_config->irq_pol_inv = of_property_read_bool( + sub_node, "cirrus,gpio-polarity-invert"); + irq_gpio1_config->irq_out_en = of_property_read_bool( + sub_node, "cirrus,gpio-output-enable"); + ret = of_property_read_u32(sub_node, "cirrus,gpio-src-select", + &val); + if (ret >= 0) { + val |= CS35L41_VALID_PDATA; + irq_gpio1_config->irq_src_sel = val; + } + } + of_node_put(sub_node); + + /* GPIO2 Pin Config */ + sub_node = of_get_child_by_name(np, "cirrus,gpio-config2"); + irq_gpio2_config->is_present = sub_node ? true : false; + if (irq_gpio2_config->is_present) { + irq_gpio2_config->irq_pol_inv = of_property_read_bool( + sub_node, "cirrus,gpio-polarity-invert"); + irq_gpio2_config->irq_out_en = of_property_read_bool( + sub_node, "cirrus,gpio-output-enable"); + ret = of_property_read_u32(sub_node, "cirrus,gpio-src-select", + &val); + if (ret >= 0) { + val |= CS35L41_VALID_PDATA; + irq_gpio2_config->irq_src_sel = val; + } + } + of_node_put(sub_node); + + pdata->hibernate_enable = + of_property_read_bool(np, "cirrus,hibernate-enable"); + + return 0; +} + +static const struct reg_sequence cs35l41_reva0_errata_patch[] = { + { 0x00000040, 0x00005555 }, + { 0x00000040, 0x0000AAAA }, + { 0x00003854, 0x05180240 }, + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, + { 0x00004310, 0x00000000 }, + { CS35L41_VPVBST_FS_SEL, 0x00000000 }, + { CS35L41_OTP_TRIM_30, 0x9091A1C8 }, + { 0x00003014, 0x0200EE0E }, + { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, + { 0x00000054, 0x00000004 }, + { CS35L41_IRQ1_DB3, 0x00000000 }, + { CS35L41_IRQ2_DB3, 0x00000000 }, + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { 0x00000040, 0x0000CCCC }, + { 0x00000040, 0x00003333 }, +}; + +static const struct reg_sequence cs35l41_revb0_errata_patch[] = { + { 0x00000040, 0x00005555 }, + { 0x00000040, 0x0000AAAA }, + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, + { 0x00004310, 0x00000000 }, + { CS35L41_VPVBST_FS_SEL, 0x00000000 }, + { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { 0x00000040, 0x0000CCCC }, + { 0x00000040, 0x00003333 }, +}; + +static const struct reg_sequence cs35l41_revb2_errata_patch[] = { + { 0x00000040, 0x00005555 }, + { 0x00000040, 0x0000AAAA }, + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, + { 0x00004310, 0x00000000 }, + { CS35L41_VPVBST_FS_SEL, 0x00000000 }, + { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { 0x00000040, 0x0000CCCC }, + { 0x00000040, 0x00003333 }, +}; + +static int cs35l41_dsp_init(struct cs35l41_private *cs35l41) +{ + struct wm_adsp *dsp; + int ret, i; + + dsp = &cs35l41->dsp; + dsp->num = 1; + dsp->type = WMFW_HALO; + dsp->rev = 0; + dsp->dev = cs35l41->dev; + dsp->regmap = cs35l41->regmap; + dsp->tuning_has_prefix = cs35l41->pdata.tuning_has_prefix; + dsp->first_booting = true; + + if (!cs35l41->pdata.fwname_use_revid) + dsp->part = "cs35l41"; + + dsp->base = CS35L41_DSP1_CTRL_BASE; + dsp->base_sysinfo = CS35L41_DSP1_SYS_ID; + dsp->mem = cs35l41_dsp1_regions; + dsp->num_mems = ARRAY_SIZE(cs35l41_dsp1_regions); + dsp->lock_regions = 0xFFFFFFFF; + + dsp->n_rx_channels = CS35L41_DSP_N_RX_RATES; + dsp->n_tx_channels = CS35L41_DSP_N_TX_RATES; + + mutex_init(&cs35l41->rate_lock); + ret = wm_halo_init(dsp, &cs35l41->rate_lock); + cs35l41->halo_booted = false; + + for (i = 0; i < CS35L41_DSP_N_RX_RATES; i++) + dsp->rx_rate_cache[i] = 0x1; + for (i = 0; i < CS35L41_DSP_N_TX_RATES; i++) + dsp->tx_rate_cache[i] = 0x1; + + regmap_write(cs35l41->regmap, CS35L41_DSP1_RX5_SRC, + CS35L41_INPUT_SRC_VPMON); + regmap_write(cs35l41->regmap, CS35L41_DSP1_RX6_SRC, + CS35L41_INPUT_SRC_CLASSH); + regmap_write(cs35l41->regmap, CS35L41_DSP1_RX7_SRC, + CS35L41_INPUT_SRC_TEMPMON); + regmap_write(cs35l41->regmap, CS35L41_DSP1_RX8_SRC, + CS35L41_INPUT_SRC_RSVD); + + return ret; +} + +static int cs35l41_enter_hibernate(struct cs35l41_private *cs35l41) +{ + int i; + + dev_dbg(cs35l41->dev, "%s: hibernate state %d\n", __func__, + cs35l41->amp_hibernate); + + if (cs35l41->amp_hibernate == CS35L41_HIBERNATE_STANDBY) + return 0; + + /* read all ctl regs */ + for (i = 0; i < CS35L41_CTRL_CACHE_SIZE; i++) + regmap_read(cs35l41->regmap, cs35l41_ctl_cache_regs[i], + &cs35l41->ctl_cache[i]); + + /* Disable interrupts */ + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); + disable_irq(cs35l41->irq); + + /* Reset DSP sticky bit */ + regmap_write(cs35l41->regmap, CS35L41_IRQ2_STATUS2, + 1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT); + + /* Reset AP sticky bit */ + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS2, + 1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT); + + regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088); + regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188); + + regmap_write(cs35l41->regmap, CS35L41_CSPL_MBOX_CMD_DRV, + CSPL_MBOX_CMD_HIBERNATE); + + regcache_cache_only(cs35l41->regmap, true); + + cs35l41->amp_hibernate = CS35L41_HIBERNATE_STANDBY; + return 0; +} + +static int cs35l41_wait_for_pwrmgt_sts(struct cs35l41_private *cs35l41) +{ + int i, ret = 0; + unsigned int wrpend_sts = 0x2; + + for (i = 0; (i < 10) && (wrpend_sts & 0x2); i++) + ret = regmap_read(cs35l41->regmap, CS35L41_PWRMGT_STS, + &wrpend_sts); + return ret; +} + +static int cs35l41_exit_hibernate(struct cs35l41_private *cs35l41) +{ + int timeout = 10, ret; + unsigned int status; + int retries = 5, i; + u32 *p_trim_data; + + dev_dbg(cs35l41->dev, "%s: hibernate state %d\n", __func__, + cs35l41->amp_hibernate); + + if (cs35l41->amp_hibernate != CS35L41_HIBERNATE_STANDBY) + return 0; + + /* update any regs that changed while in cache-only mode */ + for (i = 0; i < CS35L41_CTRL_CACHE_SIZE; i++) + regmap_read(cs35l41->regmap, cs35l41_ctl_cache_regs[i], + &cs35l41->ctl_cache[i]); + + regcache_cache_only(cs35l41->regmap, false); + + do { + do { + ret = regmap_write(cs35l41->regmap, + CS35L41_CSPL_MBOX_CMD_DRV, + CSPL_MBOX_CMD_OUT_OF_HIBERNATE); + if (ret < 0) + dev_dbg(cs35l41->dev, "%s: wakeup write fail\n", + __func__); + + usleep_range(1000, 1100); + + ret = regmap_read(cs35l41->regmap, + CS35L41_CSPL_MBOX_STS, &status); + if (ret < 0) + dev_err(cs35l41->dev, + "%s: mbox status read fail\n", + __func__); + + } while (status != CSPL_MBOX_STS_PAUSED && --timeout > 0); + + if (timeout != 0) + break; + + dev_err(cs35l41->dev, "hibernate wake failed\n"); + + cs35l41_wait_for_pwrmgt_sts(cs35l41); + regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088); + + cs35l41_wait_for_pwrmgt_sts(cs35l41); + regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188); + + cs35l41_wait_for_pwrmgt_sts(cs35l41); + regmap_write(cs35l41->regmap, CS35L41_PWRMGT_CTL, 0x3); + + timeout = 10; + + } while (--retries > 0); + + /* Reset DSP sticky bit */ + regmap_write(cs35l41->regmap, CS35L41_IRQ2_STATUS2, + 1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT); + + /* Reset AP sticky bit */ + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS2, + 1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT); + + cs35l41->amp_hibernate = CS35L41_HIBERNATE_AWAKE; + + /* invalidate all cached values which have now been reset */ + regcache_drop_region(cs35l41->regmap, CS35L41_DEVID, + CS35L41_MIXER_NGATE_CH2_CFG); + + /* sync all control regs to cache value */ + for (i = 0; i < CS35L41_CTRL_CACHE_SIZE; i++) + regmap_write(cs35l41->regmap, cs35l41_ctl_cache_regs[i], + cs35l41->ctl_cache[i]); + + regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055); + regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); + + /* trim with cache values */ + p_trim_data = cs35l41->trim_cache; + for (i = 0; i < CS35L41_TRIM_CACHE_REGIONS; i++) { + regmap_raw_write(cs35l41->regmap, + cs35l41_trim_cache_regs[i].reg, p_trim_data, + cs35l41_trim_cache_regs[i].size * sizeof(u32)); + p_trim_data += cs35l41_trim_cache_regs[i].size; + } + + regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); + regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033); + + retries = 5; + + do { + dev_dbg(cs35l41->dev, "cs35l41_restore attempt %d\n", + 6 - retries); + ret = cs35l41_restore(cs35l41); + usleep_range(4000, 5000); + } while (ret < 0 && --retries > 0); + + if (retries < 0) + dev_err(cs35l41->dev, "Failed to exit from hibernate\n"); + else + dev_dbg(cs35l41->dev, "cs35l41 restored in %d attempts\n", + 6 - retries); + + enable_irq(cs35l41->irq); + + return ret; +} + +/* Restore amp state after hibernate */ +static int cs35l41_restore(struct cs35l41_private *cs35l41) +{ + int ret; + u32 regid, reg_revid, mtl_revid, chipid_match; + u32 devid_otp; + + ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, ®id); + if (ret < 0) { + dev_err(cs35l41->dev, "%s: Get Device ID fail\n", __func__); + return -ENODEV; + } + + ret = regmap_read(cs35l41->regmap, CS35L41_REVID, ®_revid); + if (ret < 0) { + dev_err(cs35l41->dev, "Get Revision ID failed\n"); + return -ENODEV; + } + + mtl_revid = reg_revid & CS35L41_MTLREVID_MASK; + chipid_match = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID; + if (regid != chipid_match && regid != CS35L41LV_CHIP_ID) { + dev_err(cs35l41->dev, + "CS35L41 Device ID (%X). Expected ID %X\n", regid, + chipid_match); + return -ENODEV; + } + + cs35l41_irq_gpio_config(cs35l41); + + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, + CS35L41_INT1_MASK_DEFAULT); + + regmap_write(cs35l41->regmap, CS35L41_DSP1_RX5_SRC, + CS35L41_INPUT_SRC_VPMON); + regmap_write(cs35l41->regmap, CS35L41_DSP1_RX6_SRC, + CS35L41_INPUT_SRC_CLASSH); + regmap_write(cs35l41->regmap, CS35L41_DSP1_RX7_SRC, + CS35L41_INPUT_SRC_TEMPMON); + regmap_write(cs35l41->regmap, CS35L41_DSP1_RX8_SRC, + CS35L41_INPUT_SRC_RSVD); + + switch (reg_revid) { + case CS35L41_REVID_A0: + ret = regmap_multi_reg_write( + cs35l41->regmap, cs35l41_reva0_errata_patch, + ARRAY_SIZE(cs35l41_reva0_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, + "Failed to apply A0 errata patch %d\n", ret); + } + break; + case CS35L41_REVID_B0: + ret = regmap_multi_reg_write( + cs35l41->regmap, cs35l41_revb0_errata_patch, + ARRAY_SIZE(cs35l41_revb0_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, + "Failed to apply B0 errata patch %d\n", ret); + } + break; + case CS35L41_REVID_B2: + ret = regmap_multi_reg_write( + cs35l41->regmap, cs35l41_revb2_errata_patch, + ARRAY_SIZE(cs35l41_revb2_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, + "Failed to apply B2 errata patch %d\n", ret); + } + break; + } + + dev_dbg(cs35l41->dev, "Restored CS35L41 (%x), Revision: %02X\n", regid, + reg_revid); + + cs35l41_set_pdata(cs35l41); + ret = regmap_read(cs35l41->regmap, CS35L41_DEVID_OTP, &devid_otp); + if (ret < 0) { + dev_err(cs35l41->dev, "Read DEVID OTP failed\n"); + return -EINVAL; + } + if (devid_otp == CS35L41LV_CHIP_ID) + /* BST_CTL_LIM_EN = 1 BST_CTL_SEL = b'01 (Class H tracking) */ + regmap_write(cs35l41->regmap, CS35L41_BSTCVRT_VCTRL2, 0x5); + + /* Restore cached values set by ALSA during or before amp reset */ + + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, + CS35L41_ASP_RX1_SLOT_MASK, + ((cs35l41->pdata.right_channel) ? 1 : 0) + << CS35L41_ASP_RX1_SLOT_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, + CS35L41_ASP_RX2_SLOT_MASK, + ((cs35l41->pdata.right_channel) ? 0 : 1) + << CS35L41_ASP_RX2_SLOT_SHIFT); + + if (cs35l41->reset_cache.extclk_cfg) { + /* These values are already cached in cs35l41_private struct */ + + if (cs35l41->clksrc == CS35L41_PLLSRC_SCLK) + regmap_update_bits(cs35l41->regmap, + CS35L41_SP_RATE_CTRL, 0x3F, + cs35l41->extclk_cfg); + + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_OPENLOOP_MASK, + 1 << CS35L41_PLL_OPENLOOP_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_REFCLK_FREQ_MASK, + cs35l41->extclk_cfg + << CS35L41_REFCLK_FREQ_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_CLK_EN_MASK, + 0 << CS35L41_PLL_CLK_EN_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_CLK_SEL_MASK, cs35l41->clksrc); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_OPENLOOP_MASK, + 0 << CS35L41_PLL_OPENLOOP_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, + CS35L41_PLL_CLK_EN_MASK, + 1 << CS35L41_PLL_CLK_EN_SHIFT); + } + + if (cs35l41->reset_cache.asp_width >= 0) { + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_ASP_WIDTH_RX_MASK, + cs35l41->reset_cache.asp_width + << CS35L41_ASP_WIDTH_RX_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_ASP_WIDTH_TX_MASK, + cs35l41->reset_cache.asp_width + << CS35L41_ASP_WIDTH_TX_SHIFT); + } + + if (cs35l41->reset_cache.asp_wl >= 0) { + regmap_update_bits(cs35l41->regmap, CS35L41_SP_RX_WL, + CS35L41_ASP_RX_WL_MASK, + cs35l41->reset_cache.asp_wl + << CS35L41_ASP_RX_WL_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_TX_WL, + CS35L41_ASP_TX_WL_MASK, + cs35l41->reset_cache.asp_wl + << CS35L41_ASP_TX_WL_SHIFT); + } + + if (cs35l41->reset_cache.asp_fmt >= 0) + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_ASP_FMT_MASK, + cs35l41->reset_cache.asp_fmt + << CS35L41_ASP_FMT_SHIFT); + + if (cs35l41->reset_cache.lrclk_fmt >= 0) + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_LRCLK_INV_MASK, + cs35l41->reset_cache.lrclk_fmt + << CS35L41_LRCLK_INV_SHIFT); + + if (cs35l41->reset_cache.sclk_fmt >= 0) + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_SCLK_INV_MASK, + cs35l41->reset_cache.sclk_fmt + << CS35L41_SCLK_INV_SHIFT); + + if (cs35l41->reset_cache.slave_mode >= 0) { + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_SCLK_MSTR_MASK, + cs35l41->reset_cache.slave_mode + << CS35L41_SCLK_MSTR_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, + CS35L41_LRCLK_MSTR_MASK, + cs35l41->reset_cache.slave_mode + << CS35L41_LRCLK_MSTR_SHIFT); + } + + if (cs35l41->reset_cache.fs_cfg >= 0) + regmap_update_bits(cs35l41->regmap, CS35L41_GLOBAL_CLK_CTRL, + CS35L41_GLOBAL_FS_MASK, + cs35l41->reset_cache.fs_cfg + << CS35L41_GLOBAL_FS_SHIFT); + + return 0; +} + +static int cs35l41_preset_sample_rate(struct cs35l41_private *cs35l41, int rate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs35l41_fs_rates); i++) { + if (rate == cs35l41_fs_rates[i].rate) + break; + } + + if (i >= ARRAY_SIZE(cs35l41_fs_rates)) { + dev_err(cs35l41->dev, "%s: Invalid sample rate = %d\n", + __func__, rate); + return -EINVAL; + } + + regmap_update_bits(cs35l41->regmap, CS35L41_GLOBAL_CLK_CTRL, + CS35L41_GLOBAL_FS_MASK, + cs35l41_fs_rates[i].fs_cfg + << CS35L41_GLOBAL_FS_SHIFT); + + return 0; +} + +int cs35l41_probe(struct cs35l41_private *cs35l41, + struct cs35l41_platform_data *pdata) +{ + int ret; + u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match; + int timeout = 100; + int irq_pol = 0; + u32 *p_trim_data; + struct snd_kcontrol_new *cs35l41_ctl; + struct snd_soc_dapm_route *cs35l41_map; + struct snd_soc_dapm_widget *cs35l41_widgets; + const struct snd_kcontrol_new *cs35l41_tmp_ctl; + const struct snd_soc_dapm_route *cs35l41_tmp_map; + const struct snd_soc_dapm_widget *cs35l41_tmp_widgets; + int num_cs35l41_tmp_ctl; + int num_cs35l41_tmp_map; + int num_cs35l41_tmp_widgets; + u32 devid_otp; + + dev_info(cs35l41->dev, "cs35l41 probe E\n"); + + cs35l41->fast_switch_en = false; + cs35l41->fast_switch_file_idx = 0; + cs35l41->reload_tuning = false; + + for (i = 0; i < ARRAY_SIZE(cs35l41_supplies); i++) + cs35l41->supplies[i].supply = cs35l41_supplies[i]; + + cs35l41->num_supplies = ARRAY_SIZE(cs35l41_supplies); + + ret = devm_regulator_bulk_get(cs35l41->dev, cs35l41->num_supplies, + cs35l41->supplies); + if (ret != 0) { + dev_err(cs35l41->dev, "Failed to request core supplies: %d\n", + ret); + return ret; + } + + if (pdata) { + cs35l41->pdata = *pdata; + } else if (cs35l41->dev->of_node) { + ret = cs35l41_handle_of_data(cs35l41->dev, &cs35l41->pdata, + cs35l41); + if (ret != 0) + return ret; + } else { + ret = -EINVAL; + goto err; + } + + ret = regulator_bulk_enable(cs35l41->num_supplies, cs35l41->supplies); + if (ret != 0) { + dev_err(cs35l41->dev, "Failed to enable core supplies: %d\n", + ret); + return ret; + } + + /* returning NULL can be an option if in stereo mode */ + cs35l41->reset_gpio = + devm_gpiod_get_optional(cs35l41->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(cs35l41->reset_gpio)) { + ret = PTR_ERR(cs35l41->reset_gpio); + cs35l41->reset_gpio = NULL; + if (ret == -EBUSY) { + dev_info(cs35l41->dev, + "Reset line busy, assuming shared reset\n"); + } else { + dev_err(cs35l41->dev, "Failed to get reset GPIO: %d\n", + ret); + goto err; + } + } + if (cs35l41->reset_gpio) { + /* satisfy minimum reset pulse width spec */ + usleep_range(2000, 2100); + gpiod_set_value_cansleep(cs35l41->reset_gpio, 1); + } + + usleep_range(2000, 2100); + + do { + if (timeout == 0) { + dev_err(cs35l41->dev, + "Timeout waiting for OTP_BOOT_DONE\n"); + ret = -EBUSY; + goto err; + } + usleep_range(1000, 1100); + regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS4, &int_status); + timeout--; + } while (!(int_status & CS35L41_OTP_BOOT_DONE)); + + regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_status); + if (int_status & CS35L41_OTP_BOOT_ERR) { + dev_err(cs35l41->dev, "OTP Boot error\n"); + ret = -EINVAL; + goto err; + } + + ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, ®id); + if (ret < 0) { + dev_err(cs35l41->dev, "Get Device ID failed\n"); + goto err; + } + + ret = regmap_read(cs35l41->regmap, CS35L41_REVID, ®_revid); + if (ret < 0) { + dev_err(cs35l41->dev, "Get Revision ID failed\n"); + goto err; + } + + mtl_revid = reg_revid & CS35L41_MTLREVID_MASK; + + /* CS35L41 will have even MTLREVID + * CS35L41R will have odd MTLREVID + */ + chipid_match = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID; + if (regid != chipid_match && regid != CS35L41LV_CHIP_ID) { + dev_err(cs35l41->dev, + "CS35L41 Device ID (%X). Expected ID %X\n", regid, + chipid_match); + ret = -ENODEV; + goto err; + } + + irq_pol = cs35l41_irq_gpio_config(cs35l41); + + mutex_init(&cs35l41->vol_ctl.vol_mutex); + cs35l41->vol_ctl.dig_vol = 0; + cs35l41->vol_ctl.ramp_init_att = 0; + cs35l41->vol_ctl.ramp_knee_att = 0; + cs35l41->vol_ctl.ramp_knee_time = 0; + cs35l41->vol_ctl.ramp_end_time = 0; + atomic_set(&cs35l41->vol_ctl.playback, 0); + atomic_set(&cs35l41->vol_ctl.vol_ramp, 0); + atomic_set(&cs35l41->vol_ctl.manual_ramp, 0); + atomic_set(&cs35l41->vol_ctl.ramp_abort, 0); + cs35l41->vol_ctl.auto_ramp_timeout = 0; + cs35l41->vol_ctl.output_dev = CS35L41_OUTPUT_DEV_SPK; + cs35l41->vol_ctl.prev_active_dev = CS35L41_OUTPUT_DEV_SPK; + cs35l41->vol_ctl.ramp_wq = + create_singlethread_workqueue("cs35l41_ramp"); + INIT_WORK(&cs35l41->vol_ctl.ramp_work, cs35l41_vol_ramp); + + ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, + cs35l41_irq, + IRQF_ONESHOT | IRQF_SHARED | irq_pol, + "cs35l41", cs35l41); + + /* CS35L41 needs INT for PDN_DONE */ + if (ret != 0) { + dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", ret); + //goto err; + } + + /* Set interrupt masks for critical errors */ +#if defined(BRINGUP_IRQ_VERIFY) + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, + CS35L41_INT1_MASK_DEFAULT & CS35L41_INT1_UNMASK_PUP); +#else + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, + CS35L41_INT1_MASK_DEFAULT); +#endif + + mutex_init(&cs35l41->force_int_lock); + + switch (reg_revid) { + case CS35L41_REVID_A0: + cs35l41->amp_hibernate = CS35L41_HIBERNATE_INCOMPATIBLE; + if (cs35l41->pdata.fwname_use_revid) + cs35l41->dsp.part = "cs35l41-revA"; + ret = regmap_multi_reg_write( + cs35l41->regmap, cs35l41_reva0_errata_patch, + ARRAY_SIZE(cs35l41_reva0_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, + "Failed to apply A0 errata patch %d\n", ret); + goto err; + } + break; + case CS35L41_REVID_B0: + cs35l41->amp_hibernate = CS35L41_HIBERNATE_INCOMPATIBLE; + if (cs35l41->pdata.fwname_use_revid) + cs35l41->dsp.part = "cs35l41-revB0"; + ret = regmap_multi_reg_write( + cs35l41->regmap, cs35l41_revb0_errata_patch, + ARRAY_SIZE(cs35l41_revb0_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, + "Failed to apply B0 errata patch %d\n", ret); + goto err; + } + break; + case CS35L41_REVID_B2: + if (cs35l41->pdata.fwname_use_revid) + cs35l41->dsp.part = "cs35l41-revB2"; + ret = regmap_multi_reg_write( + cs35l41->regmap, cs35l41_revb2_errata_patch, + ARRAY_SIZE(cs35l41_revb2_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, + "Failed to apply B2 errata patch %d\n", ret); + goto err; + } + + if (cs35l41->pdata.hibernate_enable && + devid_otp != CS35L41LV_CHIP_ID) + cs35l41->amp_hibernate = CS35L41_HIBERNATE_NOT_LOADED; + else + cs35l41->amp_hibernate = CS35L41_HIBERNATE_INCOMPATIBLE; + + cs35l41->reset_cache.extclk_cfg = false; + cs35l41->reset_cache.asp_wl = -1; + cs35l41->reset_cache.asp_width = -1; + cs35l41->reset_cache.asp_fmt = -1; + cs35l41->reset_cache.sclk_fmt = -1; + cs35l41->reset_cache.slave_mode = -1; + cs35l41->reset_cache.lrclk_fmt = -1; + cs35l41->reset_cache.fs_cfg = -1; + break; + } + + ret = cs35l41_otp_unpack(cs35l41); + if (ret < 0) { + dev_err(cs35l41->dev, "OTP Unpack failed\n"); + goto err; + } + + /* read all trim regs */ + p_trim_data = cs35l41->trim_cache; + for (i = 0; i < CS35L41_TRIM_CACHE_REGIONS; i++) { + regmap_raw_read(cs35l41->regmap, cs35l41_trim_cache_regs[i].reg, + p_trim_data, + cs35l41_trim_cache_regs[i].size * sizeof(u32)); + p_trim_data += cs35l41_trim_cache_regs[i].size; + } + + regmap_write(cs35l41->regmap, CS35L41_DSP1_CCM_CORE_CTRL, 0); + cs35l41_dsp_init(cs35l41); + + ret = regmap_read(cs35l41->regmap, CS35L41_DEVID_OTP, &devid_otp); + if (ret < 0) { + dev_err(cs35l41->dev, "Read DEVID OTP failed\n"); + ret = -EINVAL; + goto err; + } + if (devid_otp == CS35L41LV_CHIP_ID) { + cs35l41_tmp_ctl = cs35l41_lv_ctl; + num_cs35l41_tmp_ctl = ARRAY_SIZE(cs35l41_lv_ctl); + cs35l41_tmp_map = NULL; + num_cs35l41_tmp_map = 0; + cs35l41_tmp_widgets = NULL; + num_cs35l41_tmp_widgets = 0; + } else { + cs35l41_tmp_ctl = cs35l41_bst_ctl; + num_cs35l41_tmp_ctl = ARRAY_SIZE(cs35l41_bst_ctl); + cs35l41_tmp_map = cs35l41_hib_map; + num_cs35l41_tmp_map = ARRAY_SIZE(cs35l41_hib_map); + cs35l41_tmp_widgets = cs35l41_hib_widgets; + num_cs35l41_tmp_widgets = ARRAY_SIZE(cs35l41_hib_widgets); + } + cs35l41_ctl = devm_kmalloc(cs35l41->dev, + sizeof(struct snd_kcontrol_new) * + (num_cs35l41_tmp_ctl + + ARRAY_SIZE(cs35l41_aud_controls)), + GFP_KERNEL); + if (!cs35l41_ctl) { + ret = -ENOMEM; + goto err; + } + memcpy(cs35l41_ctl, cs35l41_tmp_ctl, + num_cs35l41_tmp_ctl * sizeof(struct snd_kcontrol_new)); + memcpy(cs35l41_ctl + num_cs35l41_tmp_ctl, cs35l41_aud_controls, + ARRAY_SIZE(cs35l41_aud_controls) * + sizeof(struct snd_kcontrol_new)); + soc_component_dev_cs35l41.controls = cs35l41_ctl; + soc_component_dev_cs35l41.num_controls = + num_cs35l41_tmp_ctl + ARRAY_SIZE(cs35l41_aud_controls); + cs35l41_map = devm_kmalloc( + cs35l41->dev, + sizeof(struct snd_soc_dapm_route) * + (num_cs35l41_tmp_map + ARRAY_SIZE(cs35l41_audio_map)), + GFP_KERNEL); + if (!cs35l41_map) { + ret = -ENOMEM; + goto err; + } + memcpy(cs35l41_map, cs35l41_tmp_map, + num_cs35l41_tmp_map * sizeof(struct snd_soc_dapm_route)); + memcpy(cs35l41_map + num_cs35l41_tmp_map, cs35l41_audio_map, + ARRAY_SIZE(cs35l41_audio_map) * + sizeof(struct snd_soc_dapm_route)); + soc_component_dev_cs35l41.dapm_routes = cs35l41_map; + soc_component_dev_cs35l41.num_dapm_routes = + num_cs35l41_tmp_map + ARRAY_SIZE(cs35l41_audio_map); + cs35l41_widgets = + devm_kmalloc(cs35l41->dev, + sizeof(struct snd_soc_dapm_widget) * + (num_cs35l41_tmp_widgets + + ARRAY_SIZE(cs35l41_dapm_widgets)), + GFP_KERNEL); + if (!cs35l41_widgets) { + ret = -ENOMEM; + goto err; + } + memcpy(cs35l41_widgets, cs35l41_tmp_widgets, + num_cs35l41_tmp_widgets * sizeof(struct snd_soc_dapm_widget)); + memcpy(cs35l41_widgets + num_cs35l41_tmp_widgets, cs35l41_dapm_widgets, + ARRAY_SIZE(cs35l41_dapm_widgets) * + sizeof(struct snd_soc_dapm_widget)); + soc_component_dev_cs35l41.dapm_widgets = cs35l41_widgets; + soc_component_dev_cs35l41.num_dapm_widgets = + num_cs35l41_tmp_widgets + ARRAY_SIZE(cs35l41_dapm_widgets); + ret = snd_soc_register_component(cs35l41->dev, + &soc_component_dev_cs35l41, + cs35l41_dai, ARRAY_SIZE(cs35l41_dai)); + if (ret < 0) { + dev_err(cs35l41->dev, "%s: Register codec failed\n", __func__); + goto err; + } + + dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", + regid, reg_revid); + + cs35l41->wq = create_singlethread_workqueue("cs35l41"); + if (cs35l41->wq == NULL) { + ret = -ENOMEM; + goto err; + } + + INIT_DELAYED_WORK(&cs35l41->hb_work, cs35l41_hibernate_work); + mutex_init(&cs35l41->hb_lock); + + /* Workarounds for specific project: */ + // Preset sample rate + cs35l41_preset_sample_rate(cs35l41, 48000); + + dev_info(cs35l41->dev, "cs35l41 probe X\n"); + + return 0; + +err: + regulator_bulk_disable(cs35l41->num_supplies, cs35l41->supplies); + return ret; +} + +int cs35l41_remove(struct cs35l41_private *cs35l41) +{ + destroy_workqueue(cs35l41->wq); + mutex_destroy(&cs35l41->hb_lock); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); + mutex_destroy(&cs35l41->force_int_lock); + wm_adsp2_remove(&cs35l41->dsp); + regulator_bulk_disable(cs35l41->num_supplies, cs35l41->supplies); + snd_soc_unregister_component(cs35l41->dev); + return 0; +} + +MODULE_DESCRIPTION("ASoC CS35L41 driver"); +MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); +MODULE_LICENSE("GPL"); diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41.h b/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41.h new file mode 100644 index 000000000000..14933bddc28f --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41.h @@ -0,0 +1,842 @@ +/* + * cs35l41.h -- CS35L41 ALSA SoC audio driver + * + * Copyright 2018 Cirrus Logic, Inc. + * + * Author: Brian Austin + * David Rhodes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __CS35L41_H__ +#define __CS35L41_H__ + +#include + +#define CS35L41_FIRSTREG 0x00000000 +#define CS35L41_LASTREG 0x03804FE8 +#define CS35L41_DEVID 0x00000000 +#define CS35L41_REVID 0x00000004 +#define CS35L41_FABID 0x00000008 +#define CS35L41_RELID 0x0000000C +#define CS35L41_OTPID 0x00000010 +#define CS35L41_SFT_RESET 0x00000020 +#define CS35L41_TEST_KEY_CTL 0x00000040 +#define CS35L41_USER_KEY_CTL 0x00000044 +#define CS35L41_OTP_MEM0 0x00000400 +#define CS35L41_OTP_MEM31 0x0000047C +#define CS35L41_OTP_CTRL0 0x00000500 +#define CS35L41_OTP_CTRL1 0x00000504 +#define CS35L41_OTP_CTRL3 0x00000508 +#define CS35L41_OTP_CTRL4 0x0000050C +#define CS35L41_OTP_CTRL5 0x00000510 +#define CS35L41_OTP_CTRL6 0x00000514 +#define CS35L41_OTP_CTRL7 0x00000518 +#define CS35L41_OTP_CTRL8 0x0000051C +#define CS35L41_PWR_CTRL1 0x00002014 +#define CS35L41_PWR_CTRL2 0x00002018 +#define CS35L41_PWR_CTRL3 0x0000201C +#define CS35L41_CTRL_OVRRIDE 0x00002020 +#define CS35L41_AMP_OUT_MUTE 0x00002024 +#define CS35L41_PROTECT_REL_ERR_IGN 0x00002034 +#define CS35L41_GPIO_PAD_CONTROL 0x0000242C +#define CS35L41_JTAG_CONTROL 0x00002438 +#define CS35L41_DEVID_OTP 0x00002850 +#define CS35L41_PWRMGT_CTL 0x00002900 +#define CS35L41_WAKESRC_CTL 0x00002904 +#define CS35L41_PWRMGT_STS 0x00002908 +#define CS35L41_PLL_CLK_CTRL 0x00002C04 +#define CS35L41_DSP_CLK_CTRL 0x00002C08 +#define CS35L41_GLOBAL_CLK_CTRL 0x00002C0C +#define CS35L41_DATA_FS_SEL 0x00002C10 +#define CS35L41_TST_FS_MON0 0x00002D10 +#define CS35L41_MDSYNC_EN 0x00003400 +#define CS35L41_MDSYNC_TX_ID 0x00003408 +#define CS35L41_MDSYNC_PWR_CTRL 0x0000340C +#define CS35L41_MDSYNC_DATA_TX 0x00003410 +#define CS35L41_MDSYNC_TX_STATUS 0x00003414 +#define CS35L41_MDSYNC_DATA_RX 0x0000341C +#define CS35L41_MDSYNC_RX_STATUS 0x00003420 +#define CS35L41_MDSYNC_ERR_STATUS 0x00003424 +#define CS35L41_MDSYNC_SYNC_PTE2 0x00003528 +#define CS35L41_MDSYNC_SYNC_PTE3 0x0000352C +#define CS35L41_MDSYNC_SYNC_MSM_STATUS 0x0000353C +#define CS35L41_BSTCVRT_VCTRL1 0x00003800 +#define CS35L41_BSTCVRT_VCTRL2 0x00003804 +#define CS35L41_BSTCVRT_PEAK_CUR 0x00003808 +#define CS35L41_BSTCVRT_SFT_RAMP 0x0000380C +#define CS35L41_BSTCVRT_COEFF 0x00003810 +#define CS35L41_BSTCVRT_SLOPE_LBST 0x00003814 +#define CS35L41_BSTCVRT_SW_FREQ 0x00003818 +#define CS35L41_BSTCVRT_DCM_CTRL 0x0000381C +#define CS35L41_BSTCVRT_DCM_MODE_FORCE 0x00003820 +#define CS35L41_BSTCVRT_OVERVOLT_CTRL 0x00003830 +#define CS35L41_VI_VOL_POL 0x00004000 +#define CS35L41_VIMON_SPKMON_RESYNC 0x00004100 +#define CS35L41_DTEMP_WARN_THLD 0x00004220 +#define CS35L41_DTEMP_CFG 0x00004224 +#define CS35L41_DTEMP_EN 0x00004308 +#define CS35L41_VPVBST_FS_SEL 0x00004400 +#define CS35L41_SP_ENABLES 0x00004800 +#define CS35L41_SP_RATE_CTRL 0x00004804 +#define CS35L41_SP_FORMAT 0x00004808 +#define CS35L41_SP_HIZ_CTRL 0x0000480C +#define CS35L41_SP_FRAME_TX_SLOT 0x00004810 +#define CS35L41_SP_FRAME_RX_SLOT 0x00004820 +#define CS35L41_SP_TX_WL 0x00004830 +#define CS35L41_SP_RX_WL 0x00004840 +#define CS35L41_ASP_CONTROL4 0x00004854 +#define CS35L41_DAC_PCM1_SRC 0x00004C00 +#define CS35L41_ASP_TX1_SRC 0x00004C20 +#define CS35L41_ASP_TX2_SRC 0x00004C24 +#define CS35L41_ASP_TX3_SRC 0x00004C28 +#define CS35L41_ASP_TX4_SRC 0x00004C2C +#define CS35L41_DSP1_RX1_SRC 0x00004C40 +#define CS35L41_DSP1_RX2_SRC 0x00004C44 +#define CS35L41_DSP1_RX3_SRC 0x00004C48 +#define CS35L41_DSP1_RX4_SRC 0x00004C4C +#define CS35L41_DSP1_RX5_SRC 0x00004C50 +#define CS35L41_DSP1_RX6_SRC 0x00004C54 +#define CS35L41_DSP1_RX7_SRC 0x00004C58 +#define CS35L41_DSP1_RX8_SRC 0x00004C5C +#define CS35L41_NGATE1_SRC 0x00004C60 +#define CS35L41_NGATE2_SRC 0x00004C64 +#define CS35L41_AMP_DIG_VOL_CTRL 0x00006000 +#define CS35L41_VPBR_CFG 0x00006404 +#define CS35L41_VBBR_CFG 0x00006408 +#define CS35L41_VPBR_STATUS 0x0000640C +#define CS35L41_VBBR_STATUS 0x00006410 +#define CS35L41_OVERTEMP_CFG 0x00006414 +#define CS35L41_AMP_ERR_VOL 0x00006418 +#define CS35L41_VOL_STATUS_TO_DSP 0x00006450 +#define CS35L41_CLASSH_CFG 0x00006800 +#define CS35L41_WKFET_CFG 0x00006804 +#define CS35L41_NG_CFG 0x00006808 +#define CS35L41_AMP_GAIN_CTRL 0x00006C04 +#define CS35L41_DAC_MSM_CFG 0x00007400 +#define CS35L41_IRQ1_CFG 0x00010000 +#define CS35L41_IRQ1_STATUS 0x00010004 +#define CS35L41_IRQ1_STATUS1 0x00010010 +#define CS35L41_IRQ1_STATUS2 0x00010014 +#define CS35L41_IRQ1_STATUS3 0x00010018 +#define CS35L41_IRQ1_STATUS4 0x0001001C +#define CS35L41_IRQ1_RAW_STATUS1 0x00010090 +#define CS35L41_IRQ1_RAW_STATUS2 0x00010094 +#define CS35L41_IRQ1_RAW_STATUS3 0x00010098 +#define CS35L41_IRQ1_RAW_STATUS4 0x0001009C +#define CS35L41_IRQ1_MASK1 0x00010110 +#define CS35L41_IRQ1_MASK2 0x00010114 +#define CS35L41_IRQ1_MASK3 0x00010118 +#define CS35L41_IRQ1_MASK4 0x0001011C +#define CS35L41_IRQ1_FRC1 0x00010190 +#define CS35L41_IRQ1_FRC2 0x00010194 +#define CS35L41_IRQ1_FRC3 0x00010198 +#define CS35L41_IRQ1_FRC4 0x0001019C +#define CS35L41_IRQ1_EDGE1 0x00010210 +#define CS35L41_IRQ1_EDGE4 0x0001021C +#define CS35L41_IRQ1_POL1 0x00010290 +#define CS35L41_IRQ1_POL2 0x00010294 +#define CS35L41_IRQ1_POL3 0x00010298 +#define CS35L41_IRQ1_POL4 0x0001029C +#define CS35L41_IRQ1_DB3 0x00010318 +#define CS35L41_IRQ2_CFG 0x00010800 +#define CS35L41_IRQ2_STATUS 0x00010804 +#define CS35L41_IRQ2_STATUS1 0x00010810 +#define CS35L41_IRQ2_STATUS2 0x00010814 +#define CS35L41_IRQ2_STATUS3 0x00010818 +#define CS35L41_IRQ2_STATUS4 0x0001081C +#define CS35L41_IRQ2_RAW_STATUS1 0x00010890 +#define CS35L41_IRQ2_RAW_STATUS2 0x00010894 +#define CS35L41_IRQ2_RAW_STATUS3 0x00010898 +#define CS35L41_IRQ2_RAW_STATUS4 0x0001089C +#define CS35L41_IRQ2_MASK1 0x00010910 +#define CS35L41_IRQ2_MASK2 0x00010914 +#define CS35L41_IRQ2_MASK3 0x00010918 +#define CS35L41_IRQ2_MASK4 0x0001091C +#define CS35L41_IRQ2_FRC1 0x00010990 +#define CS35L41_IRQ2_FRC2 0x00010994 +#define CS35L41_IRQ2_FRC3 0x00010998 +#define CS35L41_IRQ2_FRC4 0x0001099C +#define CS35L41_IRQ2_EDGE1 0x00010A10 +#define CS35L41_IRQ2_EDGE4 0x00010A1C +#define CS35L41_IRQ2_POL1 0x00010A90 +#define CS35L41_IRQ2_POL2 0x00010A94 +#define CS35L41_IRQ2_POL3 0x00010A98 +#define CS35L41_IRQ2_POL4 0x00010A9C +#define CS35L41_IRQ2_DB3 0x00010B18 +#define CS35L41_GPIO_STATUS1 0x00011000 +#define CS35L41_GPIO1_CTRL1 0x00011008 +#define CS35L41_GPIO2_CTRL1 0x0001100C +#define CS35L41_MIXER_NGATE_CFG 0x00012000 +#define CS35L41_MIXER_NGATE_CH1_CFG 0x00012004 +#define CS35L41_MIXER_NGATE_CH2_CFG 0x00012008 +#define CS35L41_DSP_MBOX_1 0x00013000 +#define CS35L41_DSP_MBOX_2 0x00013004 +#define CS35L41_DSP_MBOX_3 0x00013008 +#define CS35L41_DSP_MBOX_4 0x0001300C +#define CS35L41_DSP_MBOX_5 0x00013010 +#define CS35L41_DSP_MBOX_6 0x00013014 +#define CS35L41_DSP_MBOX_7 0x00013018 +#define CS35L41_DSP_MBOX_8 0x0001301C +#define CS35L41_DSP_VIRT1_MBOX_1 0x00013020 +#define CS35L41_DSP_VIRT1_MBOX_2 0x00013024 +#define CS35L41_DSP_VIRT1_MBOX_3 0x00013028 +#define CS35L41_DSP_VIRT1_MBOX_4 0x0001302C +#define CS35L41_DSP_VIRT1_MBOX_5 0x00013030 +#define CS35L41_DSP_VIRT1_MBOX_6 0x00013034 +#define CS35L41_DSP_VIRT1_MBOX_7 0x00013038 +#define CS35L41_DSP_VIRT1_MBOX_8 0x0001303C +#define CS35L41_DSP_VIRT2_MBOX_1 0x00013040 +#define CS35L41_DSP_VIRT2_MBOX_2 0x00013044 +#define CS35L41_DSP_VIRT2_MBOX_3 0x00013048 +#define CS35L41_DSP_VIRT2_MBOX_4 0x0001304C +#define CS35L41_DSP_VIRT2_MBOX_5 0x00013050 +#define CS35L41_DSP_VIRT2_MBOX_6 0x00013054 +#define CS35L41_DSP_VIRT2_MBOX_7 0x00013058 +#define CS35L41_DSP_VIRT2_MBOX_8 0x0001305C +#define CS35L41_CLOCK_DETECT_1 0x00014000 +#define CS35L41_TIMER1_CONTROL 0x00015000 +#define CS35L41_TIMER1_COUNT_PRESET 0x00015004 +#define CS35L41_TIMER1_START_STOP 0x0001500C +#define CS35L41_TIMER1_STATUS 0x00015010 +#define CS35L41_TIMER1_COUNT_READBACK 0x00015014 +#define CS35L41_TIMER1_DSP_CLK_CFG 0x00015018 +#define CS35L41_TIMER1_DSP_CLK_STATUS 0x0001501C +#define CS35L41_TIMER2_CONTROL 0x00015100 +#define CS35L41_TIMER2_COUNT_PRESET 0x00015104 +#define CS35L41_TIMER2_START_STOP 0x0001510C +#define CS35L41_TIMER2_STATUS 0x00015110 +#define CS35L41_TIMER2_COUNT_READBACK 0x00015114 +#define CS35L41_TIMER2_DSP_CLK_CFG 0x00015118 +#define CS35L41_TIMER2_DSP_CLK_STATUS 0x0001511C +#define CS35L41_DFT_JTAG_CONTROL 0x00016000 +#define CS35L41_DIE_STS1 0x00017040 +#define CS35L41_DIE_STS2 0x00017044 +#define CS35L41_TEMP_CAL1 0x00017048 +#define CS35L41_TEMP_CAL2 0x0001704C +#define CS35L41_DSP1_XMEM_PACK_0 0x02000000 +#define CS35L41_DSP1_XMEM_PACK_3068 0x02002FF0 +#define CS35L41_DSP1_XMEM_UNPACK32_0 0x02400000 +#define CS35L41_DSP1_XMEM_UNPACK32_2046 0x02401FF8 +#define CS35L41_DSP1_TIMESTAMP_COUNT 0x025C0800 +#define CS35L41_DSP1_SYS_ID 0x025E0000 +#define CS35L41_DSP1_SYS_VERSION 0x025E0004 +#define CS35L41_DSP1_SYS_CORE_ID 0x025E0008 +#define CS35L41_DSP1_SYS_AHB_ADDR 0x025E000C +#define CS35L41_DSP1_SYS_XSRAM_SIZE 0x025E0010 +#define CS35L41_DSP1_SYS_YSRAM_SIZE 0x025E0018 +#define CS35L41_DSP1_SYS_PSRAM_SIZE 0x025E0020 +#define CS35L41_DSP1_SYS_PM_BOOT_SIZE 0x025E0028 +#define CS35L41_DSP1_SYS_FEATURES 0x025E002C +#define CS35L41_DSP1_SYS_FIR_FILTERS 0x025E0030 +#define CS35L41_DSP1_SYS_LMS_FILTERS 0x025E0034 +#define CS35L41_DSP1_SYS_XM_BANK_SIZE 0x025E0038 +#define CS35L41_DSP1_SYS_YM_BANK_SIZE 0x025E003C +#define CS35L41_DSP1_SYS_PM_BANK_SIZE 0x025E0040 +#define CS35L41_DSP1_AHBM_WIN0_CTRL0 0x025E2000 +#define CS35L41_DSP1_AHBM_WIN0_CTRL1 0x025E2004 +#define CS35L41_DSP1_AHBM_WIN1_CTRL0 0x025E2008 +#define CS35L41_DSP1_AHBM_WIN1_CTRL1 0x025E200C +#define CS35L41_DSP1_AHBM_WIN2_CTRL0 0x025E2010 +#define CS35L41_DSP1_AHBM_WIN2_CTRL1 0x025E2014 +#define CS35L41_DSP1_AHBM_WIN3_CTRL0 0x025E2018 +#define CS35L41_DSP1_AHBM_WIN3_CTRL1 0x025E201C +#define CS35L41_DSP1_AHBM_WIN4_CTRL0 0x025E2020 +#define CS35L41_DSP1_AHBM_WIN4_CTRL1 0x025E2024 +#define CS35L41_DSP1_AHBM_WIN5_CTRL0 0x025E2028 +#define CS35L41_DSP1_AHBM_WIN5_CTRL1 0x025E202C +#define CS35L41_DSP1_AHBM_WIN6_CTRL0 0x025E2030 +#define CS35L41_DSP1_AHBM_WIN6_CTRL1 0x025E2034 +#define CS35L41_DSP1_AHBM_WIN7_CTRL0 0x025E2038 +#define CS35L41_DSP1_AHBM_WIN7_CTRL1 0x025E203C +#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL0 0x025E2040 +#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL1 0x025E2044 +#define CS35L41_DSP1_XMEM_UNPACK24_0 0x02800000 +#define CS35L41_DSP1_XMEM_UNPACK24_4093 0x02803FF4 +#define CS35L41_DSP1_CTRL_BASE 0x02B80000 +#define CS35L41_DSP1_CORE_SOFT_RESET 0x02B80010 +#define CS35L41_DSP1_DEBUG 0x02B80040 +#define CS35L41_DSP1_TIMER_CTRL 0x02B80048 +#define CS35L41_DSP1_STREAM_ARB_CTRL 0x02B80050 +#define CS35L41_DSP1_RX1_RATE 0x02B80080 +#define CS35L41_DSP1_RX2_RATE 0x02B80088 +#define CS35L41_DSP1_RX3_RATE 0x02B80090 +#define CS35L41_DSP1_RX4_RATE 0x02B80098 +#define CS35L41_DSP1_RX5_RATE 0x02B800A0 +#define CS35L41_DSP1_RX6_RATE 0x02B800A8 +#define CS35L41_DSP1_RX7_RATE 0x02B800B0 +#define CS35L41_DSP1_RX8_RATE 0x02B800B8 +#define CS35L41_DSP1_TX1_RATE 0x02B80280 +#define CS35L41_DSP1_TX2_RATE 0x02B80288 +#define CS35L41_DSP1_TX3_RATE 0x02B80290 +#define CS35L41_DSP1_TX4_RATE 0x02B80298 +#define CS35L41_DSP1_TX5_RATE 0x02B802A0 +#define CS35L41_DSP1_TX6_RATE 0x02B802A8 +#define CS35L41_DSP1_TX7_RATE 0x02B802B0 +#define CS35L41_DSP1_TX8_RATE 0x02B802B8 +#define CS35L41_DSP1_NMI_CTRL1 0x02B80480 +#define CS35L41_DSP1_NMI_CTRL2 0x02B80488 +#define CS35L41_DSP1_NMI_CTRL3 0x02B80490 +#define CS35L41_DSP1_NMI_CTRL4 0x02B80498 +#define CS35L41_DSP1_NMI_CTRL5 0x02B804A0 +#define CS35L41_DSP1_NMI_CTRL6 0x02B804A8 +#define CS35L41_DSP1_NMI_CTRL7 0x02B804B0 +#define CS35L41_DSP1_NMI_CTRL8 0x02B804B8 +#define CS35L41_DSP1_RESUME_CTRL 0x02B80500 +#define CS35L41_DSP1_IRQ1_CTRL 0x02B80508 +#define CS35L41_DSP1_IRQ2_CTRL 0x02B80510 +#define CS35L41_DSP1_IRQ3_CTRL 0x02B80518 +#define CS35L41_DSP1_IRQ4_CTRL 0x02B80520 +#define CS35L41_DSP1_IRQ5_CTRL 0x02B80528 +#define CS35L41_DSP1_IRQ6_CTRL 0x02B80530 +#define CS35L41_DSP1_IRQ7_CTRL 0x02B80538 +#define CS35L41_DSP1_IRQ8_CTRL 0x02B80540 +#define CS35L41_DSP1_IRQ9_CTRL 0x02B80548 +#define CS35L41_DSP1_IRQ10_CTRL 0x02B80550 +#define CS35L41_DSP1_IRQ11_CTRL 0x02B80558 +#define CS35L41_DSP1_IRQ12_CTRL 0x02B80560 +#define CS35L41_DSP1_IRQ13_CTRL 0x02B80568 +#define CS35L41_DSP1_IRQ14_CTRL 0x02B80570 +#define CS35L41_DSP1_IRQ15_CTRL 0x02B80578 +#define CS35L41_DSP1_IRQ16_CTRL 0x02B80580 +#define CS35L41_DSP1_IRQ17_CTRL 0x02B80588 +#define CS35L41_DSP1_IRQ18_CTRL 0x02B80590 +#define CS35L41_DSP1_IRQ19_CTRL 0x02B80598 +#define CS35L41_DSP1_IRQ20_CTRL 0x02B805A0 +#define CS35L41_DSP1_IRQ21_CTRL 0x02B805A8 +#define CS35L41_DSP1_IRQ22_CTRL 0x02B805B0 +#define CS35L41_DSP1_IRQ23_CTRL 0x02B805B8 +#define CS35L41_DSP1_SCRATCH1 0x02B805C0 +#define CS35L41_DSP1_SCRATCH2 0x02B805C8 +#define CS35L41_DSP1_SCRATCH3 0x02B805D0 +#define CS35L41_DSP1_SCRATCH4 0x02B805D8 +#define CS35L41_DSP1_CCM_CORE_CTRL 0x02BC1000 +#define CS35L41_DSP1_CCM_CLK_OVERRIDE 0x02BC1008 +#define CS35L41_DSP1_XM_MSTR_EN 0x02BC2000 +#define CS35L41_DSP1_XM_CORE_PRI 0x02BC2008 +#define CS35L41_DSP1_XM_AHB_PACK_PL_PRI 0x02BC2010 +#define CS35L41_DSP1_XM_AHB_UP_PL_PRI 0x02BC2018 +#define CS35L41_DSP1_XM_ACCEL_PL0_PRI 0x02BC2020 +#define CS35L41_DSP1_XM_NPL0_PRI 0x02BC2078 +#define CS35L41_DSP1_YM_MSTR_EN 0x02BC20C0 +#define CS35L41_DSP1_YM_CORE_PRI 0x02BC20C8 +#define CS35L41_DSP1_YM_AHB_PACK_PL_PRI 0x02BC20D0 +#define CS35L41_DSP1_YM_AHB_UP_PL_PRI 0x02BC20D8 +#define CS35L41_DSP1_YM_ACCEL_PL0_PRI 0x02BC20E0 +#define CS35L41_DSP1_YM_NPL0_PRI 0x02BC2138 +#define CS35L41_DSP1_PM_MSTR_EN 0x02BC2180 +#define CS35L41_DSP1_PM_PATCH0_ADDR 0x02BC2188 +#define CS35L41_DSP1_PM_PATCH0_EN 0x02BC218C +#define CS35L41_DSP1_PM_PATCH0_DATA_LO 0x02BC2190 +#define CS35L41_DSP1_PM_PATCH0_DATA_HI 0x02BC2194 +#define CS35L41_DSP1_PM_PATCH1_ADDR 0x02BC2198 +#define CS35L41_DSP1_PM_PATCH1_EN 0x02BC219C +#define CS35L41_DSP1_PM_PATCH1_DATA_LO 0x02BC21A0 +#define CS35L41_DSP1_PM_PATCH1_DATA_HI 0x02BC21A4 +#define CS35L41_DSP1_PM_PATCH2_ADDR 0x02BC21A8 +#define CS35L41_DSP1_PM_PATCH2_EN 0x02BC21AC +#define CS35L41_DSP1_PM_PATCH2_DATA_LO 0x02BC21B0 +#define CS35L41_DSP1_PM_PATCH2_DATA_HI 0x02BC21B4 +#define CS35L41_DSP1_PM_PATCH3_ADDR 0x02BC21B8 +#define CS35L41_DSP1_PM_PATCH3_EN 0x02BC21BC +#define CS35L41_DSP1_PM_PATCH3_DATA_LO 0x02BC21C0 +#define CS35L41_DSP1_PM_PATCH3_DATA_HI 0x02BC21C4 +#define CS35L41_DSP1_PM_PATCH4_ADDR 0x02BC21C8 +#define CS35L41_DSP1_PM_PATCH4_EN 0x02BC21CC +#define CS35L41_DSP1_PM_PATCH4_DATA_LO 0x02BC21D0 +#define CS35L41_DSP1_PM_PATCH4_DATA_HI 0x02BC21D4 +#define CS35L41_DSP1_PM_PATCH5_ADDR 0x02BC21D8 +#define CS35L41_DSP1_PM_PATCH5_EN 0x02BC21DC +#define CS35L41_DSP1_PM_PATCH5_DATA_LO 0x02BC21E0 +#define CS35L41_DSP1_PM_PATCH5_DATA_HI 0x02BC21E4 +#define CS35L41_DSP1_PM_PATCH6_ADDR 0x02BC21E8 +#define CS35L41_DSP1_PM_PATCH6_EN 0x02BC21EC +#define CS35L41_DSP1_PM_PATCH6_DATA_LO 0x02BC21F0 +#define CS35L41_DSP1_PM_PATCH6_DATA_HI 0x02BC21F4 +#define CS35L41_DSP1_PM_PATCH7_ADDR 0x02BC21F8 +#define CS35L41_DSP1_PM_PATCH7_EN 0x02BC21FC +#define CS35L41_DSP1_PM_PATCH7_DATA_LO 0x02BC2200 +#define CS35L41_DSP1_PM_PATCH7_DATA_HI 0x02BC2204 +#define CS35L41_DSP1_MPU_XM_ACCESS0 0x02BC3000 +#define CS35L41_DSP1_MPU_YM_ACCESS0 0x02BC3004 +#define CS35L41_DSP1_MPU_WNDW_ACCESS0 0x02BC3008 +#define CS35L41_DSP1_MPU_XREG_ACCESS0 0x02BC300C +#define CS35L41_DSP1_MPU_YREG_ACCESS0 0x02BC3014 +#define CS35L41_DSP1_MPU_XM_ACCESS1 0x02BC3018 +#define CS35L41_DSP1_MPU_YM_ACCESS1 0x02BC301C +#define CS35L41_DSP1_MPU_WNDW_ACCESS1 0x02BC3020 +#define CS35L41_DSP1_MPU_XREG_ACCESS1 0x02BC3024 +#define CS35L41_DSP1_MPU_YREG_ACCESS1 0x02BC302C +#define CS35L41_DSP1_MPU_XM_ACCESS2 0x02BC3030 +#define CS35L41_DSP1_MPU_YM_ACCESS2 0x02BC3034 +#define CS35L41_DSP1_MPU_WNDW_ACCESS2 0x02BC3038 +#define CS35L41_DSP1_MPU_XREG_ACCESS2 0x02BC303C +#define CS35L41_DSP1_MPU_YREG_ACCESS2 0x02BC3044 +#define CS35L41_DSP1_MPU_XM_ACCESS3 0x02BC3048 +#define CS35L41_DSP1_MPU_YM_ACCESS3 0x02BC304C +#define CS35L41_DSP1_MPU_WNDW_ACCESS3 0x02BC3050 +#define CS35L41_DSP1_MPU_XREG_ACCESS3 0x02BC3054 +#define CS35L41_DSP1_MPU_YREG_ACCESS3 0x02BC305C +#define CS35L41_DSP1_MPU_XM_VIO_ADDR 0x02BC3100 +#define CS35L41_DSP1_MPU_XM_VIO_STATUS 0x02BC3104 +#define CS35L41_DSP1_MPU_YM_VIO_ADDR 0x02BC3108 +#define CS35L41_DSP1_MPU_YM_VIO_STATUS 0x02BC310C +#define CS35L41_DSP1_MPU_PM_VIO_ADDR 0x02BC3110 +#define CS35L41_DSP1_MPU_PM_VIO_STATUS 0x02BC3114 +#define CS35L41_DSP1_MPU_LOCK_CONFIG 0x02BC3140 +#define CS35L41_DSP1_MPU_WDT_RST_CTRL 0x02BC3180 +#define CS35L41_DSP1_STRMARB_MSTR0_CFG0 0x02BC5000 +#define CS35L41_DSP1_STRMARB_MSTR0_CFG1 0x02BC5004 +#define CS35L41_DSP1_STRMARB_MSTR0_CFG2 0x02BC5008 +#define CS35L41_DSP1_STRMARB_MSTR1_CFG0 0x02BC5010 +#define CS35L41_DSP1_STRMARB_MSTR1_CFG1 0x02BC5014 +#define CS35L41_DSP1_STRMARB_MSTR1_CFG2 0x02BC5018 +#define CS35L41_DSP1_STRMARB_MSTR2_CFG0 0x02BC5020 +#define CS35L41_DSP1_STRMARB_MSTR2_CFG1 0x02BC5024 +#define CS35L41_DSP1_STRMARB_MSTR2_CFG2 0x02BC5028 +#define CS35L41_DSP1_STRMARB_MSTR3_CFG0 0x02BC5030 +#define CS35L41_DSP1_STRMARB_MSTR3_CFG1 0x02BC5034 +#define CS35L41_DSP1_STRMARB_MSTR3_CFG2 0x02BC5038 +#define CS35L41_DSP1_STRMARB_MSTR4_CFG0 0x02BC5040 +#define CS35L41_DSP1_STRMARB_MSTR4_CFG1 0x02BC5044 +#define CS35L41_DSP1_STRMARB_MSTR4_CFG2 0x02BC5048 +#define CS35L41_DSP1_STRMARB_MSTR5_CFG0 0x02BC5050 +#define CS35L41_DSP1_STRMARB_MSTR5_CFG1 0x02BC5054 +#define CS35L41_DSP1_STRMARB_MSTR5_CFG2 0x02BC5058 +#define CS35L41_DSP1_STRMARB_MSTR6_CFG0 0x02BC5060 +#define CS35L41_DSP1_STRMARB_MSTR6_CFG1 0x02BC5064 +#define CS35L41_DSP1_STRMARB_MSTR6_CFG2 0x02BC5068 +#define CS35L41_DSP1_STRMARB_MSTR7_CFG0 0x02BC5070 +#define CS35L41_DSP1_STRMARB_MSTR7_CFG1 0x02BC5074 +#define CS35L41_DSP1_STRMARB_MSTR7_CFG2 0x02BC5078 +#define CS35L41_DSP1_STRMARB_TX0_CFG0 0x02BC5200 +#define CS35L41_DSP1_STRMARB_TX0_CFG1 0x02BC5204 +#define CS35L41_DSP1_STRMARB_TX1_CFG0 0x02BC5208 +#define CS35L41_DSP1_STRMARB_TX1_CFG1 0x02BC520C +#define CS35L41_DSP1_STRMARB_TX2_CFG0 0x02BC5210 +#define CS35L41_DSP1_STRMARB_TX2_CFG1 0x02BC5214 +#define CS35L41_DSP1_STRMARB_TX3_CFG0 0x02BC5218 +#define CS35L41_DSP1_STRMARB_TX3_CFG1 0x02BC521C +#define CS35L41_DSP1_STRMARB_TX4_CFG0 0x02BC5220 +#define CS35L41_DSP1_STRMARB_TX4_CFG1 0x02BC5224 +#define CS35L41_DSP1_STRMARB_TX5_CFG0 0x02BC5228 +#define CS35L41_DSP1_STRMARB_TX5_CFG1 0x02BC522C +#define CS35L41_DSP1_STRMARB_TX6_CFG0 0x02BC5230 +#define CS35L41_DSP1_STRMARB_TX6_CFG1 0x02BC5234 +#define CS35L41_DSP1_STRMARB_TX7_CFG0 0x02BC5238 +#define CS35L41_DSP1_STRMARB_TX7_CFG1 0x02BC523C +#define CS35L41_DSP1_STRMARB_RX0_CFG0 0x02BC5400 +#define CS35L41_DSP1_STRMARB_RX0_CFG1 0x02BC5404 +#define CS35L41_DSP1_STRMARB_RX1_CFG0 0x02BC5408 +#define CS35L41_DSP1_STRMARB_RX1_CFG1 0x02BC540C +#define CS35L41_DSP1_STRMARB_RX2_CFG0 0x02BC5410 +#define CS35L41_DSP1_STRMARB_RX2_CFG1 0x02BC5414 +#define CS35L41_DSP1_STRMARB_RX3_CFG0 0x02BC5418 +#define CS35L41_DSP1_STRMARB_RX3_CFG1 0x02BC541C +#define CS35L41_DSP1_STRMARB_RX4_CFG0 0x02BC5420 +#define CS35L41_DSP1_STRMARB_RX4_CFG1 0x02BC5424 +#define CS35L41_DSP1_STRMARB_RX5_CFG0 0x02BC5428 +#define CS35L41_DSP1_STRMARB_RX5_CFG1 0x02BC542C +#define CS35L41_DSP1_STRMARB_RX6_CFG0 0x02BC5430 +#define CS35L41_DSP1_STRMARB_RX6_CFG1 0x02BC5434 +#define CS35L41_DSP1_STRMARB_RX7_CFG0 0x02BC5438 +#define CS35L41_DSP1_STRMARB_RX7_CFG1 0x02BC543C +#define CS35L41_DSP1_STRMARB_IRQ0_CFG0 0x02BC5600 +#define CS35L41_DSP1_STRMARB_IRQ0_CFG1 0x02BC5604 +#define CS35L41_DSP1_STRMARB_IRQ0_CFG2 0x02BC5608 +#define CS35L41_DSP1_STRMARB_IRQ1_CFG0 0x02BC5610 +#define CS35L41_DSP1_STRMARB_IRQ1_CFG1 0x02BC5614 +#define CS35L41_DSP1_STRMARB_IRQ1_CFG2 0x02BC5618 +#define CS35L41_DSP1_STRMARB_IRQ2_CFG0 0x02BC5620 +#define CS35L41_DSP1_STRMARB_IRQ2_CFG1 0x02BC5624 +#define CS35L41_DSP1_STRMARB_IRQ2_CFG2 0x02BC5628 +#define CS35L41_DSP1_STRMARB_IRQ3_CFG0 0x02BC5630 +#define CS35L41_DSP1_STRMARB_IRQ3_CFG1 0x02BC5634 +#define CS35L41_DSP1_STRMARB_IRQ3_CFG2 0x02BC5638 +#define CS35L41_DSP1_STRMARB_IRQ4_CFG0 0x02BC5640 +#define CS35L41_DSP1_STRMARB_IRQ4_CFG1 0x02BC5644 +#define CS35L41_DSP1_STRMARB_IRQ4_CFG2 0x02BC5648 +#define CS35L41_DSP1_STRMARB_IRQ5_CFG0 0x02BC5650 +#define CS35L41_DSP1_STRMARB_IRQ5_CFG1 0x02BC5654 +#define CS35L41_DSP1_STRMARB_IRQ5_CFG2 0x02BC5658 +#define CS35L41_DSP1_STRMARB_IRQ6_CFG0 0x02BC5660 +#define CS35L41_DSP1_STRMARB_IRQ6_CFG1 0x02BC5664 +#define CS35L41_DSP1_STRMARB_IRQ6_CFG2 0x02BC5668 +#define CS35L41_DSP1_STRMARB_IRQ7_CFG0 0x02BC5670 +#define CS35L41_DSP1_STRMARB_IRQ7_CFG1 0x02BC5674 +#define CS35L41_DSP1_STRMARB_IRQ7_CFG2 0x02BC5678 +#define CS35L41_DSP1_STRMARB_RESYNC_MSK 0x02BC5A00 +#define CS35L41_DSP1_STRMARB_ERR_STATUS 0x02BC5A08 +#define CS35L41_DSP1_INTPCTL_RES_STATIC 0x02BC6000 +#define CS35L41_DSP1_INTPCTL_RES_DYN 0x02BC6004 +#define CS35L41_DSP1_INTPCTL_NMI_CTRL 0x02BC6008 +#define CS35L41_DSP1_INTPCTL_IRQ_INV 0x02BC6010 +#define CS35L41_DSP1_INTPCTL_IRQ_MODE 0x02BC6014 +#define CS35L41_DSP1_INTPCTL_IRQ_EN 0x02BC6018 +#define CS35L41_DSP1_INTPCTL_IRQ_MSK 0x02BC601C +#define CS35L41_DSP1_INTPCTL_IRQ_FLUSH 0x02BC6020 +#define CS35L41_DSP1_INTPCTL_IRQ_MSKCLR 0x02BC6024 +#define CS35L41_DSP1_INTPCTL_IRQ_FRC 0x02BC6028 +#define CS35L41_DSP1_INTPCTL_IRQ_MSKSET 0x02BC602C +#define CS35L41_DSP1_INTPCTL_IRQ_ERR 0x02BC6030 +#define CS35L41_DSP1_INTPCTL_IRQ_PEND 0x02BC6034 +#define CS35L41_DSP1_INTPCTL_IRQ_GEN 0x02BC6038 +#define CS35L41_DSP1_INTPCTL_TESTBITS 0x02BC6040 +#define CS35L41_DSP1_WDT_CONTROL 0x02BC7000 +#define CS35L41_DSP1_WDT_STATUS 0x02BC7008 +#define CS35L41_DSP1_YMEM_PACK_0 0x02C00000 +#define CS35L41_DSP1_YMEM_PACK_1532 0x02C017F0 +#define CS35L41_DSP1_YMEM_UNPACK32_0 0x03000000 +#define CS35L41_DSP1_YMEM_UNPACK32_1022 0x03000FF8 +#define CS35L41_DSP1_YMEM_UNPACK24_0 0x03400000 +#define CS35L41_DSP1_YMEM_UNPACK24_2045 0x03401FF4 +#define CS35L41_DSP1_PMEM_0 0x03800000 +#define CS35L41_DSP1_PMEM_5114 0x03804FE8 + +/*test regs for emulation bringup*/ +#define CS35L41_PLL_OVR 0x00003018 +#define CS35L41_BST_TEST_DUTY 0x00003900 +#define CS35L41_DIGPWM_IOCTRL 0x0000706C + +/*registers populated by OTP*/ +#define CS35L41_OTP_TRIM_1 0x0000208c +#define CS35L41_OTP_TRIM_2 0x00002090 +#define CS35L41_OTP_TRIM_3 0x00003010 +#define CS35L41_OTP_TRIM_4 0x0000300C +#define CS35L41_OTP_TRIM_5 0x0000394C +#define CS35L41_OTP_TRIM_6 0x00003950 +#define CS35L41_OTP_TRIM_7 0x00003954 +#define CS35L41_OTP_TRIM_8 0x00003958 +#define CS35L41_OTP_TRIM_9 0x0000395C +#define CS35L41_OTP_TRIM_10 0x0000416C +#define CS35L41_OTP_TRIM_11 0x00004160 +#define CS35L41_OTP_TRIM_12 0x00004170 +#define CS35L41_OTP_TRIM_13 0x00004360 +#define CS35L41_OTP_TRIM_14 0x00004448 +#define CS35L41_OTP_TRIM_15 0x0000444C +#define CS35L41_OTP_TRIM_16 0x00006E30 +#define CS35L41_OTP_TRIM_17 0x00006E34 +#define CS35L41_OTP_TRIM_18 0x00006E38 +#define CS35L41_OTP_TRIM_19 0x00006E3C +#define CS35L41_OTP_TRIM_20 0x00006E40 +#define CS35L41_OTP_TRIM_21 0x00006E44 +#define CS35L41_OTP_TRIM_22 0x00006E48 +#define CS35L41_OTP_TRIM_23 0x00006E4C +#define CS35L41_OTP_TRIM_24 0x00006E50 +#define CS35L41_OTP_TRIM_25 0x00006E54 +#define CS35L41_OTP_TRIM_26 0x00006E58 +#define CS35L41_OTP_TRIM_27 0x00006E5C +#define CS35L41_OTP_TRIM_28 0x00006E60 +#define CS35L41_OTP_TRIM_29 0x00006E64 +#define CS35L41_OTP_TRIM_30 0x00007418 +#define CS35L41_OTP_TRIM_31 0x0000741C +#define CS35L41_OTP_TRIM_32 0x00007434 +#define CS35L41_OTP_TRIM_33 0x00007068 +#define CS35L41_OTP_TRIM_34 0x0000410C +#define CS35L41_OTP_TRIM_35 0x0000400C +#define CS35L41_OTP_TRIM_36 0x00002030 + +#define CS35L41_MAX_CACHE_REG 0x0000006B +#define CS35L41_OTP_SIZE_WORDS 32 + +#define CS35L41_VALID_PDATA 0x80000000 + +#define CS35L41_SCLK_MSTR_MASK 0x10 +#define CS35L41_SCLK_MSTR_SHIFT 4 +#define CS35L41_LRCLK_MSTR_MASK 0x01 +#define CS35L41_LRCLK_MSTR_SHIFT 0 +#define CS35L41_SCLK_INV_MASK 0x40 +#define CS35L41_SCLK_INV_SHIFT 6 +#define CS35L41_LRCLK_INV_MASK 0x04 +#define CS35L41_LRCLK_INV_SHIFT 2 +#define CS35L41_SCLK_FRC_MASK 0x20 +#define CS35L41_SCLK_FRC_SHIFT 5 +#define CS35L41_LRCLK_FRC_MASK 0x02 +#define CS35L41_LRCLK_FRC_SHIFT 1 + +#define CS35L41_AMP_GAIN_ZC_MASK 0x0400 +#define CS35L41_AMP_GAIN_ZC_SHIFT 10 + +#define CS35L41_BST_CTL_MASK 0xFF +#define CS35L41_BST_CTL_SEL_MASK 0x03 +#define CS35L41_BST_CTL_SEL_REG 0x00 +#define CS35L41_BST_CTL_SEL_CLASSH 0x01 +#define CS35L41_BST_IPK_MASK 0x7F +#define CS35L41_BST_IPK_SHIFT 0 +#define CS35L41_BST_LIM_MASK 0x4 +#define CS35L41_BST_LIM_SHIFT 2 +#define CS35L41_BST_K1_MASK 0x000000FF +#define CS35L41_BST_K1_SHIFT 0 +#define CS35L41_BST_K2_MASK 0x0000FF00 +#define CS35L41_BST_K2_SHIFT 8 +#define CS35L41_BST_SLOPE_MASK 0x0000FF00 +#define CS35L41_BST_SLOPE_SHIFT 8 +#define CS35L41_BST_LBST_VAL_MASK 0x00000003 +#define CS35L41_BST_LBST_VAL_SHIFT 0 + +#define CS35L41_TEMP_THLD_MASK 0x03 +#define CS35L41_VMON_IMON_VOL_MASK 0x07FF07FF +#define CS35L41_PDM_MODE_MASK 0x01 +#define CS35L41_PDM_MODE_SHIFT 0 + +#define CS35L41_CH_MEM_DEPTH_MASK 0x07 +#define CS35L41_CH_MEM_DEPTH_SHIFT 0 +#define CS35L41_CH_HDRM_CTL_MASK 0x007F0000 +#define CS35L41_CH_HDRM_CTL_SHIFT 16 +#define CS35L41_CH_REL_RATE_MASK 0xFF00 +#define CS35L41_CH_REL_RATE_SHIFT 8 +#define CS35L41_CH_WKFET_DLY_MASK 0x001C +#define CS35L41_CH_WKFET_DLY_SHIFT 2 +#define CS35L41_CH_WKFET_THLD_MASK 0x0F00 +#define CS35L41_CH_WKFET_THLD_SHIFT 8 + +#define CS35L41_HW_NG_SEL_MASK 0x3F00 +#define CS35L41_HW_NG_SEL_SHIFT 8 +#define CS35L41_HW_NG_DLY_MASK 0x0070 +#define CS35L41_HW_NG_DLY_SHIFT 4 +#define CS35L41_HW_NG_THLD_MASK 0x0007 +#define CS35L41_HW_NG_THLD_SHIFT 0 + +#define CS35L41_DSP_NG_ENABLE_MASK 0x00010000 +#define CS35L41_DSP_NG_ENABLE_SHIFT 16 +#define CS35L41_DSP_NG_THLD_MASK 0x7 +#define CS35L41_DSP_NG_THLD_SHIFT 0 +#define CS35L41_DSP_NG_DELAY_MASK 0x0F00 +#define CS35L41_DSP_NG_DELAY_SHIFT 8 + +#define CS35L41_ASP_FMT_MASK 0x0700 +#define CS35L41_ASP_FMT_SHIFT 8 +#define CS35L41_ASP_DOUT_HIZ_MASK 0x03 +#define CS35L41_ASP_DOUT_HIZ_SHIFT 0 +#define CS35L41_ASP_WIDTH_16 0x10 +#define CS35L41_ASP_WIDTH_24 0x18 +#define CS35L41_ASP_WIDTH_32 0x20 +#define CS35L41_ASP_WIDTH_TX_MASK 0xFF0000 +#define CS35L41_ASP_WIDTH_TX_SHIFT 16 +#define CS35L41_ASP_WIDTH_RX_MASK 0xFF000000 +#define CS35L41_ASP_WIDTH_RX_SHIFT 24 +#define CS35L41_ASP_RX1_SLOT_MASK 0x3F +#define CS35L41_ASP_RX1_SLOT_SHIFT 0 +#define CS35L41_ASP_RX2_SLOT_MASK 0x3F00 +#define CS35L41_ASP_RX2_SLOT_SHIFT 8 +#define CS35L41_ASP_RX_WL_MASK 0x3F +#define CS35L41_ASP_TX_WL_MASK 0x3F +#define CS35L41_ASP_RX_WL_SHIFT 0 +#define CS35L41_ASP_TX_WL_SHIFT 0 +#define CS35L41_ASP_SOURCE_MASK 0x7F + +#define CS35L41_INPUT_SRC_ASPRX1 0x08 +#define CS35L41_INPUT_SRC_ASPRX2 0x09 +#define CS35L41_INPUT_SRC_VMON 0x18 +#define CS35L41_INPUT_SRC_IMON 0x19 +#define CS35L41_INPUT_SRC_CLASSH 0x21 +#define CS35L41_INPUT_SRC_VPMON 0x28 +#define CS35L41_INPUT_SRC_VBSTMON 0x29 +#define CS35L41_INPUT_SRC_TEMPMON 0x3A +#define CS35L41_INPUT_SRC_RSVD 0x3B +#define CS35L41_INPUT_DSP_TX1 0x32 +#define CS35L41_INPUT_DSP_TX2 0x33 + +#define CS35L41_PLL_CLK_SEL_MASK 0x07 +#define CS35L41_PLL_CLK_SEL_SHIFT 0 +#define CS35L41_PLL_CLK_EN_MASK 0x10 +#define CS35L41_PLL_CLK_EN_SHIFT 4 +#define CS35L41_PLL_OPENLOOP_MASK 0x0800 +#define CS35L41_PLL_OPENLOOP_SHIFT 11 +#define CS35L41_PLL_FORCE_EN_MASK 0x10000 +#define CS35L41_PLL_FORCE_EN_SHIFT 16 +#define CS35L41_PLLSRC_SCLK 0 +#define CS35L41_PLLSRC_LRCLK 1 +#define CS35L41_PLLSRC_SELF 3 +#define CS35L41_PLLSRC_PDMCLK 4 +#define CS35L41_PLLSRC_MCLK 5 +#define CS35L41_PLLSRC_SWIRE 7 +#define CS35L41_REFCLK_FREQ_MASK 0x7E0 +#define CS35L41_REFCLK_FREQ_SHIFT 5 + +#define CS35L41_GLOBAL_FS_MASK 0x1F +#define CS35L41_GLOBAL_FS_SHIFT 0 + +#define CS35L41_GLOBAL_EN_MASK 0x01 +#define CS35L41_GLOBAL_EN_SHIFT 0 +#define CS35L41_BST_EN_MASK 0x0030 +#define CS35L41_BST_EN_SHIFT 4 +#define CS35L41_BST_EN_DEFAULT 0x2 + +#define CS35L41_PDN_DONE_MASK 0x00800000 +#define CS35L41_PDN_DONE_SHIFT 23 +#define CS35L41_PUP_DONE_MASK 0x01000000 +#define CS35L41_PUP_DONE_SHIFT 24 + +#define CS35L36_PUP_DONE_IRQ_UNMASK 0x5F +#define CS35L36_PUP_DONE_IRQ_MASK 0xBF + +#define CS35L41_AMP_SHORT_ERR 0x80000000 +#define CS35L41_BST_SHORT_ERR 0x0100 +#define CS35L41_TEMP_WARN 0x8000 +#define CS35L41_TEMP_ERR 0x00020000 +#define CS35L41_BST_OVP_ERR 0x40 +#define CS35L41_BST_DCM_UVP_ERR 0x80 +#define CS35L41_OTP_BOOT_DONE 0x02 +#define CS35L41_PLL_UNLOCK 0x10 +#define CS35L41_OTP_BOOT_ERR 0x80000000 + +#define CS35L41_AMP_SHORT_ERR_RLS 0x02 +#define CS35L41_BST_SHORT_ERR_RLS 0x04 +#define CS35L41_BST_OVP_ERR_RLS 0x08 +#define CS35L41_BST_UVP_ERR_RLS 0x10 +#define CS35L41_TEMP_WARN_ERR_RLS 0x20 +#define CS35L41_TEMP_ERR_RLS 0x40 + +#define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F +#define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF +#define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF +#define CS35L41_INT1_MASK_FORCE 0xFFFFFFFE + +#define CS35L41_GPIO_DIR_MASK 0x80000000 +#define CS35L41_GPIO1_CTRL_MASK 0x00030000 +#define CS35L41_GPIO1_CTRL_SHIFT 16 +#define CS35L41_GPIO2_CTRL_MASK 0x07000000 +#define CS35L41_GPIO2_CTRL_SHIFT 24 +#define CS35L41_GPIO_CTRL_ACTV_LO 4 +#define CS35L41_GPIO_CTRL_ACTV_HI 5 +#define CS35L41_GPIO_POL_MASK 0x1000 +#define CS35L41_GPIO_POL_SHIFT 12 + +#define CS35L41_AMP_INV_PCM_SHIFT 14 +#define CS35L41_AMP_INV_PCM_MASK (1 << CS35L41_AMP_INV_PCM_SHIFT) +#define CS35L41_AMP_PCM_VOL_SHIFT 3 +#define CS35L41_AMP_PCM_VOL_MASK (0x7FF << 3) +#define CS35L41_AMP_PCM_VOL_MUTE 0x4CF + +#define CS35L41_FILT_GLOBAL_OVR_MASK 0x4 + +#define CS35L41_CHIP_ID 0x35a40 +#define CS35L41R_CHIP_ID 0x35b40 +#define CS35L41LV_CHIP_ID 0x35a41 +#define CS35L41_MTLREVID_MASK 0x0F +#define CS35L41_REVID_A0 0xA0 +#define CS35L41_REVID_B0 0xB0 +#define CS35L41_REVID_B2 0xB2 + +#define CS35L41_DSP_N_RX_RATES 8 +#define CS35L41_DSP_N_TX_RATES 8 +#define CS35L41_HALO_CORE_RESET 0x00000200 + +#define CS35L41_FS1_WINDOW_MASK 0x000007FF +#define CS35L41_FS2_WINDOW_MASK 0x00FFF800 +#define CS35L41_FS2_WINDOW_SHIFT 12 + +#define CS35L41_SPI_MAX_FREQ_OTP 4000000 + +#define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) +#define CS35L41_TX_FORMATS \ + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define CS35L41_MAX_AUTO_RAMP_TIMEOUT 65535 +#define CS35L41_MAX_PCM_VOL 913 +#define CS35L41_MAX_VOL_ATT 120 +#define CS35L41_ZERO_PCM_VOL 817 +#define CS35L41_OUTPUT_DEV_SPK 0 +#define CS35L41_OUTPUT_DEV_RCV 1 + +bool cs35l41_readable_reg(struct device *dev, unsigned int reg); +bool cs35l41_precious_reg(struct device *dev, unsigned int reg); +bool cs35l41_volatile_reg(struct device *dev, unsigned int reg); + +struct cs35l41_otp_packed_element_t { + u32 reg; + u8 shift; + u8 size; +}; + +struct cs35l41_otp_map_element_t { + u32 devid_otp; + u32 id; + u32 num_elements; + const struct cs35l41_otp_packed_element_t *map; + u32 bit_offset; + u32 word_offset; +}; + +struct cs35l41_otp_trim_region_t { + u32 reg; + u8 size; +}; + +struct cs35l41_otp_maps { + const struct cs35l41_otp_map_element_t *map; + int len; +}; + +extern const struct reg_default cs35l41_reg[CS35L41_MAX_CACHE_REG]; +extern const struct cs35l41_otp_maps cs35l41_otp_maps; + +#define CS35L41_REGSTRIDE 4 +#define CS35L41_BUFSIZE 64 + +#define CS35L41_DSP_VIRT1_MBOX_SHIFT 20 +#define CS35L41_DSP_VIRT2_MBOX_SHIFT 21 +#define CS35L41_CSPL_MBOX_STS CS35L41_DSP_MBOX_2 +/* Firmware update following reg */ +#define CS35L41_CSPL_MBOX_CMD_FW CS35L41_DSP_VIRT2_MBOX_1 +#define CS35L41_CSPL_MBOX_CMD_FW_SHIFT CS35L41_DSP_VIRT2_MBOX_SHIFT +/* Driver update following reg */ +#define CS35L41_CSPL_MBOX_CMD_DRV CS35L41_DSP_VIRT1_MBOX_1 +#define CS35L41_CSPL_MBOX_CMD_DRV_SHIFT CS35L41_DSP_VIRT1_MBOX_SHIFT + +#define CS35L41_CTRL_CACHE_SIZE 14 +#define CS35L41_TRIM_CACHE_REGIONS 18 +#define CS35L41_TRIM_CACHE_SIZE 38 + +extern const unsigned int cs35l41_ctl_cache_regs[CS35L41_CTRL_CACHE_SIZE]; +extern const struct cs35l41_otp_trim_region_t + cs35l41_trim_cache_regs[CS35L41_TRIM_CACHE_REGIONS]; + +enum cs35l41_cspl_mboxstate { + CSPL_MBOX_STS_RUNNING = 0, + CSPL_MBOX_STS_PAUSED = 1, + CSPL_MBOX_STS_RDY_FOR_REINIT = 2, + CSPL_MBOX_STS_HIBERNATE = 3, +}; + +enum cs35l41_cspl_mboxcmd { + CSPL_MBOX_CMD_NONE = 0, + CSPL_MBOX_CMD_PAUSE = 1, + CSPL_MBOX_CMD_RESUME = 2, + CSPL_MBOX_CMD_REINIT = 3, + CSPL_MBOX_CMD_STOP_PRE_REINIT = 4, + CSPL_MBOX_CMD_HIBERNATE = 5, + CSPL_MBOX_CMD_OUT_OF_HIBERNATE = 6, + CSPL_MBOX_CMD_UNKNOWN_CMD = -1, + CSPL_MBOX_CMD_INVALID_SEQUENCE = -2, +}; + +enum cs35l41_cspl_cmd { + CSPL_CMD_NONE = 0, + CSPL_CMD_MUTE = 1, + CSPL_CMD_UNMUTE = 2, + CSPL_CMD_UPDATE_PARAM = 8, +}; + +enum cs35l41_cspl_st { + CSPL_ST_RUNNING = 0, + CSPL_ST_ERROR = 1, + CSPL_ST_MUTED = 2, + CSPL_ST_REINITING = 3, + CSPL_ST_DIAGNOSING = 6, +}; + +enum cs35l41_hibernate_state { + CS35L41_HIBERNATE_AWAKE = 0, + CS35L41_HIBERNATE_STANDBY = 1, + CS35L41_HIBERNATE_NOT_LOADED = 2, + CS35L41_HIBERNATE_INCOMPATIBLE = 3, +}; + +#endif /*__CS35L41_H__*/ diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41.txt b/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41.txt new file mode 100755 index 000000000000..ecd422bec9b4 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/cs35l41.txt @@ -0,0 +1,255 @@ +CS35L41 Speaker Amplifier + +Required properties: + + - compatible : "cirrus,cs35l41" + "cirrus,cs35l40" + + - reg : the SPI chip select line for the device + + - VA-supply, VP-supply : power supplies for the device, + as covered in + Documentation/devicetree/bindings/regulator/regulator.txt. + + + Boost hardware configuration: + + These three properties should be used together to specify the external + component configuration of the part. See section 4.3.6 of the datasheet + for details regarding how these values are used to configure the + digital boost converter's control loop. + + - cirrus,boost-peak-milliamp : Boost-converter peak current limit in mA. + Configures the peak current by monitoring the current through the boost FET. + Range starts at 1600 mA and goes to a maximum of 4500 mA with increments + of 50 mA. + (Default) 4.50 Amps + + - cirrus,boost-ind-nanohenry : Boost inductor value, expressed in nH. Valid + values include 1000, 1200, 1500 and 2200. + + - cirrus,boost-cap-microfarad : Total equivalent boost capacitance on the VBST + and VAMP pins, derated at 11 volts DC. The value must be rounded to the + nearest integer and expressed in uF. + + +Optional properties: + - cirrus,sclk-force-output : Audio serial port SCLK force + output control. Forces the SCLK to continue to drive even + if no ASP_TXn channels are enabled. + + - cirrus,lrclk-force-output : Audio serial port LRCLK force + output control. Forces the LRCLK to continue to drive even + if no ASP_TXn channels are enabled. + + - cirrus,right-channel-amp : Boolean to determine which channel + the amplifier is to receive the audio data on. If present the + amplifier receives data on the right channel of I2S data. + If not present the amplifier receives data on the left + channel of I2S data + + - cirrus,boost-ctl-millivolt : Boost Voltage Value. Configures the + boost converter's output voltage in mV. The range is from 2550 mV to + 11000 mV with increments of 50 mV. + (Default) VP + + - cirrus,amp-gain-zc : Boolean to determine whether to use the amplifier + gain-change zero-crossing feature. If the feature is enabled, any + user-controlled amplifier gain change will occur on a zero-crossing point. + (Default) Disabled + + - cirrus,asp-sdout-hiz : Audio serial port SDOUT Hi-Z control. Sets the Hi-Z + configuration for SDOUT pin of amplifier. + + 0 = Logic 0 during unused slots, and while all transmit channels disabled + 1 = Hi-Z during unused slots but logic 0 while all transmit channels disabled + 2 = (Default) Logic 0 during unused slots, but Hi-Z while all transmit channels disabled + 3 = Hi-Z during unused slots and while all transmit channels disabled + + - cirrus,temp-warn-threshold : Amplifier overtemperature warning threshold. + Configures the threshold at which the overtemperature warning condition occurs. + When the threshold is met, the ovetemperature warning attenuation is applied + and the TEMP_WARN_EINT interrupt status bit is set. + If TEMP_WARN_MASK = 0, INTb is asserted. + + 0 = 105C + 1 = 115C + 2 = 125C (Default) + 3 = 135C + + - cirrus,hw-noise-gate-select : Hardware Noise Gate feature. Each bit selects + a different block for detection. + + 000000 - All noise gating functionality disabled + xxxxx1 - Amplifier noise gating detection enabled + xxxx1x - Boost converter DCM detection enabled + xxx1xx - VMON low power mode detection enabled + xx1xxx - IMON low power mode detection enabled + x1xxxx - VP brownout prevention detection enabled + 1xxxxx - VBST brownout prevention detection enabled + + - cirrus,hw-noise-gate-delay : Time that the incoming audio signal must be + below the noise gate threshold prior to entering a noise gated state + + 0 = 5 ms + 1 = 10 ms + 2 = 25 ms + 3 = 50 ms (default) + 4 = 100 ms + 5 = 250 ms + 6 = 500 ms + 7 = 1 s + + - cirrus,hw-noise-gate-threshold : Threshold of audio signal input which the + noise gate considers the input audio to be at a low enough level to be + valid to enter a noise gating state of operation. + + 0 = 0.654 mVpk + 1 = 0.328 mVpk + 2 = 0.164 mVpk + 3 = 0.082 mVpk (default) + 4 = 0.041 mVpk + 5 = 0.021 mVpk + 6 = 0.010 mVpk + 7 = True zero data (no LSB dither) + + - cirrus,dsp-noise-gate-enable : DSP Noise Gate feature. If present, noise + gate feature will be enabled. + + - cirrus,dsp-noise-gate-threshold : Threshold of audio signal input which the + noise gate considers the input audio to be at a low enough level to be + valid to enter a noise gating state of operation. + + 0 = -66 dBFS + 1 = -72 dBFS + 2 = -78 dBFS + 3 = -84 dBFS (default) + 4 = -90 dBFS + 5 = -96 dBFS + 6 = -102 dBFS + 7 = -108 dBFS + + - cirrus,dsp-noise-gate-delay : Time that the incoming audio signal must be + below the noise gate threshold prior to entering a noise gated state + + 0 = 5 ms + 1 = 10 ms + 2 = 25 ms + 3 = 50 ms (default) + 4 = 100 ms + 5 = 250 ms + 6 = 500 ms + 7 = 1 s + 8 = 5 s + 9 = 10 s + 10 = 20 s + 11 = 30 s + 12 = 40 s + 13 = 50 s + 14 = 60 s + 15 = 120 s + + - cirrus,tuning-has-prefix : Add ALSA component name prefix to + DSP firmware tuning file name. + For example, if the AMP prefix is 'Left' and FW set to 'Protection' + the driver will look for a .bin file named + Left-cs35l41-dsp1-spk-prot.bin + + - cirrus,fwname-use-revid : Add Rev ID prefix to DSP firmware file name. + For example, if FW is set to 'Protection' + CS35l41 Rev A: cs35l41-revA-dsp1-spk-prot.wmfw + CS35l41 Rev B0: cs35l41-revB0-dsp1-spk-prot.wmfw + CS35l41 Rev B2: cs35l41-revB2-dsp1-spk-prot.wmfw + + - cirrus,fast-switch : Specify file names for Fast Use Case Switching DSP + feature. Files names are comma-separated strings. + + - cirrus,invert-pcm : Inverts the polarity of the audio signal output from + the Class-D amplifier. + +Optional H/G Algorithm sub-node: + + The cs35l41 node can have a single "cirrus,classh-internal-algo" sub-node + that will disable automatic control of the internal H/G Algorithm. + + It is strongly recommended that the Datasheet be referenced when adjusting + or using these Class H Algorithm controls over the internal Algorithm. + Serious damage can occur to the Device and surrounding components. + + - cirrus,classh-internal-algo : Sub-node for the Internal Class H Algorithm + See Section 4.4 Internal Class H Algorithm in the Datasheet. + If not used, the device manages the ClassH Algorithm internally. + +Optional properties for the "cirrus,classh-internal-algo" Sub-node + + Section 7.9 Boost Control + - cirrus,classh-bst-overide : Boolean + - cirrus,classh-bst-max-limit + + Above two controls are unavailable for cs35l41l (Low voltage variant) + + Section 7.17 Class H, Weak-FET Control + - cirrus,classh-headroom + - cirrus,classh-release-rate + - cirrus,classh-mem-depth + - cirrus,classh-wk-fet-delay + - cirrus,classh-wk-fet-thld + + +Optional GPIO1 sub-node: + +The cs35l41 node can have an single "cirrus,gpio-config1" sub-node for +configuring the GPIO1 pin. + +- cirrus,gpio-polarity-invert : Boolean which specifies whether the GPIO1 +level is inverted. If this property is not present the level is not inverted. + +- cirrus,gpio-output-enable : Boolean which specifies whether the GPIO1 pin +is configured as an output. If this property is not present the +pin will be configured as an input. + +- cirrus,gpio-src-select : Configures the function of the GPIO1 pin. +Note that the options are different from the GPIO2 pin. + +0 = High Impedance (Default) +1 = GPIO +2 = Sync +3 = MCLK input + + +Optional GPIO2 sub-node: + +The cs35l41 node can have an single "cirrus,gpio-config2" sub-node for +configuring the GPIO1 pin. + +- cirrus,gpio-polarity-invert : Boolean which specifies whether the GPIO2 +level is inverted. If this property is not present the level is not inverted. + +- cirrus,gpio-output-enable : Boolean which specifies whether the GPIO2 pin +is configured as an output. If this property is not present the +pin will be configured as an input. + +- cirrus,gpio-src-select : Configures the function of the GPIO2 pin. +Note that the options are different from the GPIO1 pin. + +0 = High Impedance (Default) +1 = GPIO +2 = Open Drain INTB +3 = MCLK input +4 = Push-pull INTB (active low) +5 = Push-pull INT (active high) + + +Example: + +cs35l41: cs35l41@2 { + compatible = "cirrus,cs35l41"; + reg = <2>; + VA-supply = <&dummy_vreg>; + VP-supply = <&dummy_vreg>; + + cirrus,boost-peak-milliamp = <4500>; + cirrus,boost-ind-nanohenry = <1000>; + cirrus,boost-cap-microfarad = <15>; + cirrus,fast-switch = "sample_fast_switch1.txt", "sample_fast_switch2.txt"; +}; diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/send_data_to_xlog.c b/techpack/audio/asoc/codecs/cs35l41_v2/send_data_to_xlog.c new file mode 100644 index 000000000000..34a87fcdcf19 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/send_data_to_xlog.c @@ -0,0 +1,49 @@ +#include "send_data_to_xlog.h" +#include + +char msg_format[] = + "{\"name\":\"DC detection\",\"audio_event\":{\"count\":\"%d\",\"reason\":\"%s\"},\"dgt\":\"null\",\"audio_ext\":\"null\" }"; + +#define MAX_LEN 512 + +void send_DC_data_to_xlog(int dc_current_cnt, char *reason) +{ + int ret = -1; + pr_info("%s: dc_current_cnt: %d, reason: %s", __func__, dc_current_cnt, + reason); + ret = xlog_send_int(dc_current_cnt, reason); + if (ret < 0) { + pr_info("%s: failed", __func__); + } else { + pr_info("%s: success", __func__); + } + j; + lkj;:w +} + +int xlog_send_int(int dc_current_cnt, char *reason) +{ + int ret = 0; + char msg[512]; + pr_info("%s: cs35l41->dc_current_cnt: %d, reason: %s", __func__, + dc_current_cnt, reason); + ret = xlog_format_msg_int(msg, dc_current_cnt, reason); + if (ret < 0) { + return ret; + } + xlogchar_kwrite(msg, sizeof(msg)); + pr_info("%s: send msg: %s", __func__, msg); + return ret; +} + +int xlog_format_msg_int(char *msg, int dc_current_cnt, char *reason) +{ + if (msg == NULL) { + pr_info("%s: the msg is NULL", __func__); + return -EINVAL; + } + pr_info("%s start", __func__); + snprintf(msg, MAX_LEN, msg_format, dc_current_cnt, reason); + pr_info("%s end", __func__); + return 0; +} diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/send_data_to_xlog.h b/techpack/audio/asoc/codecs/cs35l41_v2/send_data_to_xlog.h new file mode 100644 index 000000000000..bcf593a05b93 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/send_data_to_xlog.h @@ -0,0 +1,26 @@ +#ifndef SEND_DATA_TO_XLOG +#define SEND_DATA_TO_XLOG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern ssize_t xlogchar_kwrite(const char __user *buf, size_t count); + +void send_DC_data_to_xlog(int dc_current_cnt, char *reason); +int xlog_send_int(int dc_current_cnt, char *reason); +int xlog_format_msg_int(char *msg, int dc_current_cnt, char *reason); + +#endif diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/wm_adsp.c b/techpack/audio/asoc/codecs/cs35l41_v2/wm_adsp.c new file mode 100644 index 000000000000..ccc75edeef1f --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/wm_adsp.c @@ -0,0 +1,5167 @@ +/* + * wm_adsp.c -- Wolfson ADSP support + * + * Copyright 2012 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm_adsp.h" + +#define MAX_BULKSIZE 1024 +#define REG_BYTESIZE 4 + +#define adsp_crit(_dsp, fmt, ...) \ + dev_crit(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +#define adsp_err(_dsp, fmt, ...) \ + dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +#define adsp_warn(_dsp, fmt, ...) \ + dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +#define adsp_info(_dsp, fmt, ...) \ + dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +#define adsp_dbg(_dsp, fmt, ...) \ + dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) + +#define compr_err(_obj, fmt, ...) \ + adsp_err(_obj->dsp, "%s: " fmt, _obj->name ? _obj->name : "legacy", \ + ##__VA_ARGS__) +#define compr_dbg(_obj, fmt, ...) \ + adsp_dbg(_obj->dsp, "%s: " fmt, _obj->name ? _obj->name : "legacy", \ + ##__VA_ARGS__) + +#define ADSP1_CONTROL_1 0x00 +#define ADSP1_CONTROL_2 0x02 +#define ADSP1_CONTROL_3 0x03 +#define ADSP1_CONTROL_4 0x04 +#define ADSP1_CONTROL_5 0x06 +#define ADSP1_CONTROL_6 0x07 +#define ADSP1_CONTROL_7 0x08 +#define ADSP1_CONTROL_8 0x09 +#define ADSP1_CONTROL_9 0x0A +#define ADSP1_CONTROL_10 0x0B +#define ADSP1_CONTROL_11 0x0C +#define ADSP1_CONTROL_12 0x0D +#define ADSP1_CONTROL_13 0x0F +#define ADSP1_CONTROL_14 0x10 +#define ADSP1_CONTROL_15 0x11 +#define ADSP1_CONTROL_16 0x12 +#define ADSP1_CONTROL_17 0x13 +#define ADSP1_CONTROL_18 0x14 +#define ADSP1_CONTROL_19 0x16 +#define ADSP1_CONTROL_20 0x17 +#define ADSP1_CONTROL_21 0x18 +#define ADSP1_CONTROL_22 0x1A +#define ADSP1_CONTROL_23 0x1B +#define ADSP1_CONTROL_24 0x1C +#define ADSP1_CONTROL_25 0x1E +#define ADSP1_CONTROL_26 0x20 +#define ADSP1_CONTROL_27 0x21 +#define ADSP1_CONTROL_28 0x22 +#define ADSP1_CONTROL_29 0x23 +#define ADSP1_CONTROL_30 0x24 +#define ADSP1_CONTROL_31 0x26 + +/* + * ADSP1 Control 19 + */ +#define ADSP1_WDMA_BUFFER_LENGTH_MASK \ + 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ +#define ADSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ +#define ADSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ + +/* + * ADSP1 Control 30 + */ +#define ADSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ +#define ADSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ +#define ADSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ +#define ADSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ +#define ADSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ +#define ADSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ +#define ADSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ +#define ADSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ +#define ADSP1_START 0x0001 /* DSP1_START */ +#define ADSP1_START_MASK 0x0001 /* DSP1_START */ +#define ADSP1_START_SHIFT 0 /* DSP1_START */ +#define ADSP1_START_WIDTH 1 /* DSP1_START */ + +/* + * ADSP1 Control 31 + */ +#define ADSP1_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ +#define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ +#define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ + +#define ADSP2_CONTROL 0x0 +#define ADSP2_CLOCKING 0x1 +#define ADSP2V2_CLOCKING 0x2 +#define ADSP2_STATUS1 0x4 +#define ADSP2_WDMA_CONFIG_1 0x30 +#define ADSP2_WDMA_CONFIG_2 0x31 +#define ADSP2V2_WDMA_CONFIG_2 0x32 +#define ADSP2_RDMA_CONFIG_1 0x34 + +#define ADSP2_SCRATCH0 0x40 +#define ADSP2_SCRATCH1 0x41 +#define ADSP2_SCRATCH2 0x42 +#define ADSP2_SCRATCH3 0x43 + +#define ADSP2V2_SCRATCH0_1 0x40 +#define ADSP2V2_SCRATCH2_3 0x42 + +/* + * ADSP2 Control + */ + +#define ADSP2_MEM_ENA 0x0010 /* DSP1_MEM_ENA */ +#define ADSP2_MEM_ENA_MASK 0x0010 /* DSP1_MEM_ENA */ +#define ADSP2_MEM_ENA_SHIFT 4 /* DSP1_MEM_ENA */ +#define ADSP2_MEM_ENA_WIDTH 1 /* DSP1_MEM_ENA */ +#define ADSP2_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ +#define ADSP2_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ +#define ADSP2_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ +#define ADSP2_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ +#define ADSP2_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ +#define ADSP2_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ +#define ADSP2_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ +#define ADSP2_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ +#define ADSP2_START 0x0001 /* DSP1_START */ +#define ADSP2_START_MASK 0x0001 /* DSP1_START */ +#define ADSP2_START_SHIFT 0 /* DSP1_START */ +#define ADSP2_START_WIDTH 1 /* DSP1_START */ + +/* + * ADSP2 clocking + */ +#define ADSP2_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ +#define ADSP2_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ +#define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ + +/* + * ADSP2V2 clocking + */ +#define ADSP2V2_CLK_SEL_MASK 0x70000 /* CLK_SEL_ENA */ +#define ADSP2V2_CLK_SEL_SHIFT 16 /* CLK_SEL_ENA */ +#define ADSP2V2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ + +#define ADSP2V2_RATE_MASK 0x7800 /* DSP_RATE */ +#define ADSP2V2_RATE_SHIFT 11 /* DSP_RATE */ +#define ADSP2V2_RATE_WIDTH 4 /* DSP_RATE */ + +/* + * ADSP2 Status 1 + */ +#define ADSP2_RAM_RDY 0x0001 +#define ADSP2_RAM_RDY_MASK 0x0001 +#define ADSP2_RAM_RDY_SHIFT 0 +#define ADSP2_RAM_RDY_WIDTH 1 + +/* + * ADSP2 Lock support + */ +#define ADSP2_LOCK_CODE_0 0x5555 +#define ADSP2_LOCK_CODE_1 0xAAAA + +#define ADSP2_WATCHDOG 0x0A +#define ADSP2_BUS_ERR_ADDR 0x52 +#define ADSP2_REGION_LOCK_STATUS 0x64 +#define ADSP2_LOCK_REGION_1_LOCK_REGION_0 0x66 +#define ADSP2_LOCK_REGION_3_LOCK_REGION_2 0x68 +#define ADSP2_LOCK_REGION_5_LOCK_REGION_4 0x6A +#define ADSP2_LOCK_REGION_7_LOCK_REGION_6 0x6C +#define ADSP2_LOCK_REGION_9_LOCK_REGION_8 0x6E +#define ADSP2_LOCK_REGION_CTRL 0x7A +#define ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR 0x7C + +#define ADSP2_REGION_LOCK_ERR_MASK 0x8000 +#define ADSP2_SLAVE_ERR_MASK 0x4000 +#define ADSP2_WDT_TIMEOUT_STS_MASK 0x2000 +#define ADSP2_CTRL_ERR_PAUSE_ENA 0x0002 +#define ADSP2_CTRL_ERR_EINT 0x0001 + +#define ADSP2_BUS_ERR_ADDR_MASK 0x00FFFFFF +#define ADSP2_XMEM_ERR_ADDR_MASK 0x0000FFFF +#define ADSP2_PMEM_ERR_ADDR_MASK 0x7FFF0000 +#define ADSP2_PMEM_ERR_ADDR_SHIFT 16 +#define ADSP2_WDT_ENA_MASK 0xFFFFFFFD + +#define ADSP2_LOCK_REGION_SHIFT 16 + +#define ADSP_MAX_STD_CTRL_SIZE 512 + +#define WM_ADSP_ACKED_CTL_TIMEOUT_MS 100 +#define WM_ADSP_ACKED_CTL_N_QUICKPOLLS 10 +#define WM_ADSP_ACKED_CTL_MIN_VALUE 0 +#define WM_ADSP_ACKED_CTL_MAX_VALUE 0xFFFFFF + +/* + * Event control messages + */ +#define WM_ADSP_FW_EVENT_SHUTDOWN 0x000001 + +/* + * HALO system info + */ +#define HALO_AHBM_WINDOW_DEBUG_0 0x02040 +#define HALO_AHBM_WINDOW_DEBUG_1 0x02044 + +/* + * HALO core + */ +#define HALO_SAMPLE_RATE_RX1 0x00080 +#define HALO_SAMPLE_RATE_TX1 0x00280 +#define HALO_SCRATCH1 0x005c0 +#define HALO_SCRATCH2 0x005c8 +#define HALO_SCRATCH3 0x005d0 +#define HALO_SCRATCH4 0x005d8 +#define HALO_CCM_CORE_CONTROL 0x41000 +#define HALO_CORE_SOFT_RESET 0x00010 +#define HALO_WDT_CONTROL 0x47000 + +/* + * HALO MPU banks + */ +#define HALO_MPU_XMEM_ACCESS_0 0x43000 +#define HALO_MPU_YMEM_ACCESS_0 0x43004 +#define HALO_MPU_WINDOW_ACCESS_0 0x43008 +#define HALO_MPU_XREG_ACCESS_0 0x4300C +#define HALO_MPU_YREG_ACCESS_0 0x43014 +#define HALO_MPU_XMEM_ACCESS_1 0x43018 +#define HALO_MPU_YMEM_ACCESS_1 0x4301C +#define HALO_MPU_WINDOW_ACCESS_1 0x43020 +#define HALO_MPU_XREG_ACCESS_1 0x43024 +#define HALO_MPU_YREG_ACCESS_1 0x4302C +#define HALO_MPU_XMEM_ACCESS_2 0x43030 +#define HALO_MPU_YMEM_ACCESS_2 0x43034 +#define HALO_MPU_WINDOW_ACCESS_2 0x43038 +#define HALO_MPU_XREG_ACCESS_2 0x4303C +#define HALO_MPU_YREG_ACCESS_2 0x43044 +#define HALO_MPU_XMEM_ACCESS_3 0x43048 +#define HALO_MPU_YMEM_ACCESS_3 0x4304C +#define HALO_MPU_WINDOW_ACCESS_3 0x43050 +#define HALO_MPU_XREG_ACCESS_3 0x43054 +#define HALO_MPU_YREG_ACCESS_3 0x4305C +#define HALO_MPU_XM_VIO_ADDR 0x43100 +#define HALO_MPU_XM_VIO_STATUS 0x43104 +#define HALO_MPU_YM_VIO_ADDR 0x43108 +#define HALO_MPU_YM_VIO_STATUS 0x4310C +#define HALO_MPU_PM_VIO_ADDR 0x43110 +#define HALO_MPU_PM_VIO_STATUS 0x43114 +#define HALO_MPU_LOCK_CONFIG 0x43140 + +/* + * HALO_AHBM_WINDOW_DEBUG_1 + */ +#define HALO_AHBM_CORE_ERR_ADDR_MASK 0x0fffff00 +#define HALO_AHBM_CORE_ERR_ADDR_SHIFT 8 +#define HALO_AHBM_FLAGS_ERR_MASK 0x000000ff + +/* + * HALO_SAMPLE_RATE_[RX|TX]n + */ +#define HALO_DSP_RATE_SHIFT 0 +#define HALO_DSP_RATE_MASK 0x1f + +/* + * HALO_CCM_CORE_CONTROL + */ +#define HALO_CORE_EN 0x00000001 + +/* + * HALO_CORE_SOFT_RESET + */ +#define HALO_CORE_SOFT_RESET_MASK 0x00000001 + +/* + * HALO_WDT_CONTROL + */ +#define HALO_WDT_EN_MASK 0x00000001 + +/* + * HALO_MPU_?M_VIO_STATUS + */ +#define HALO_MPU_VIO_STS_MASK 0x007e0000 +#define HALO_MPU_VIO_STS_SHIFT 17 +#define HALO_MPU_VIO_ERR_WR_MASK 0x00008000 +#define HALO_MPU_VIO_ERR_SRC_MASK 0x00007fff +#define HALO_MPU_VIO_ERR_SRC_SHIFT 0 + +#define HALO_MPU_VIO_SRAM 0x01 +#define HALO_MPU_VIO_REG 0x02 +#define HALO_MPU_VIO_AHB 0x04 +#define HALO_MPU_VIO_EREG 0x08 +#define HALO_MPU_VIO_EXTERNAL_MEM 0x10 +#define HALO_MPU_VIO_NON_EXIST 0x20 + +static struct wm_adsp_ops wm_adsp1_ops; +static struct wm_adsp_ops wm_adsp2_ops[]; +static struct wm_adsp_ops wm_halo_ops; +static struct wm_adsp_ops wm_vpu_ops; + +struct wm_adsp_buf { + struct list_head list; + void *buf; +}; + +static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len, + struct list_head *list) +{ + struct wm_adsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); + + if (buf == NULL) + return NULL; + + buf->buf = kmalloc(len, GFP_KERNEL | GFP_DMA); + if (!buf->buf) { + kfree(buf); + return NULL; + } + memcpy(buf->buf, src, len); + + if (list) + list_add_tail(&buf->list, list); + + return buf; +} + +static void wm_adsp_buf_free(struct list_head *list) +{ + while (!list_empty(list)) { + struct wm_adsp_buf *buf = + list_first_entry(list, struct wm_adsp_buf, list); + list_del(&buf->list); + kfree(buf->buf); + kfree(buf); + } +} + +// Speaker calibration default value +#define CAL_R_DEFAULT 8392 +#define AMBIENT_DEFAULT 30 +#define CAL_STATUS_DEFAULT 1 + +#define WM_ADSP_FW_MBC_VSS 0 +#define WM_ADSP_FW_HIFI 1 +#define WM_ADSP_FW_TX 2 +#define WM_ADSP_FW_TX_SPK 3 +#define WM_ADSP_FW_RX 4 +#define WM_ADSP_FW_RX_ANC 5 +#define WM_ADSP_FW_CTRL 6 +#define WM_ADSP_FW_ASR 7 +#define WM_ADSP_FW_TRACE 8 +#define WM_ADSP_FW_SPK_PROT 9 +#define WM_ADSP_FW_SPK_CALI 10 +#define WM_ADSP_FW_SPK_DIAG 11 +#define WM_ADSP_FW_MISC 12 + +#define WM_ADSP_NUM_FW 13 + +static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = { + [WM_ADSP_FW_MBC_VSS] = "MBC/VSS", + [WM_ADSP_FW_HIFI] = "MasterHiFi", + [WM_ADSP_FW_TX] = "Tx", + [WM_ADSP_FW_TX_SPK] = "Tx Speaker", + [WM_ADSP_FW_RX] = "Rx", + [WM_ADSP_FW_RX_ANC] = "Rx ANC", + [WM_ADSP_FW_CTRL] = "Voice Ctrl", + [WM_ADSP_FW_ASR] = "ASR Assist", + [WM_ADSP_FW_TRACE] = "Dbg Trace", + [WM_ADSP_FW_SPK_PROT] = "Protection", + [WM_ADSP_FW_SPK_CALI] = "Calibration", + [WM_ADSP_FW_SPK_DIAG] = "Diagnostic", + [WM_ADSP_FW_MISC] = "Misc", +}; + +struct wm_adsp_system_config_xm_hdr { + __be32 sys_enable; + __be32 fw_id; + __be32 fw_rev; + __be32 boot_status; + __be32 watchdog; + __be32 dma_buffer_size; + __be32 rdma[6]; + __be32 wdma[8]; + __be32 build_job_name[3]; + __be32 build_job_number; +}; + +struct wm_halo_system_config_xm_hdr { + __be32 halo_heartbeat; + __be32 build_job_name[3]; + __be32 build_job_number; +}; + +struct wm_adsp_alg_xm_struct { + __be32 magic; + __be32 smoothing; + __be32 threshold; + __be32 host_buf_ptr; + __be32 start_seq; + __be32 high_water_mark; + __be32 low_water_mark; + __be64 smoothed_power; +}; + +struct wm_adsp_host_buf_coeff_v1 { + __be32 host_buf_ptr; /* Host buffer pointer */ + __be32 versions; /* Version numbers */ + __be32 name[4]; /* The buffer name */ +}; + +struct wm_adsp_buffer { + __be32 buf1_base; /* Base addr of first buffer area */ + __be32 buf1_size; /* Size of buf1 area in DSP words */ + __be32 buf2_base; /* Base addr of 2nd buffer area */ + __be32 buf1_buf2_size; /* Size of buf1+buf2 in DSP words */ + __be32 buf3_base; /* Base addr of buf3 area */ + __be32 buf_total_size; /* Size of buf1+buf2+buf3 in DSP words */ + __be32 high_water_mark; /* Point at which IRQ is asserted */ + __be32 irq_count; /* bits 1-31 count IRQ assertions */ + __be32 irq_ack; /* acked IRQ count, bit 0 enables IRQ */ + __be32 next_write_index; /* word index of next write */ + __be32 next_read_index; /* word index of next read */ + __be32 error; /* error if any */ + __be32 oldest_block_index; /* word index of oldest surviving */ + __be32 requested_rewind; /* how many blocks rewind was done */ + __be32 reserved_space; /* internal */ + __be32 min_free; /* min free space since stream start */ + __be32 blocks_written[2]; /* total blocks written (64 bit) */ + __be32 words_written[2]; /* total words written (64 bit) */ +}; + +struct wm_adsp_compr; + +struct wm_adsp_compr_buf { + struct list_head list; + struct wm_adsp *dsp; + struct wm_adsp_compr *compr; + + struct wm_adsp_buffer_region *regions; + u32 host_buf_ptr; + + u32 error; + u32 irq_count; + int read_index; + int avail; + int host_buf_mem_type; + int num_regions; + const struct wm_adsp_buffer_region_def *region_def; + + char *name; +}; + +struct wm_adsp_compr { + struct list_head list; + struct wm_adsp *dsp; + struct wm_adsp_compr_buf *buf; + + struct snd_compr_stream *stream; + struct snd_compressed_buffer size; + + u32 *raw_buf; + unsigned int copied_total; + + unsigned int sample_rate; + + const char *name; +}; + +#define WM_ADSP_DATA_WORD_SIZE_DEFAULT 3 +#define WM_ADSP_DATA_WORD_SIZE_VPU 4 + +#define WM_ADSP_DATA_WORD_MASK_DEFAULT 0x00ffffffu +#define WM_ADSP_DATA_WORD_MASK_VPU 0xffffffffu + +#define WM_ADSP_MIN_FRAGMENTS 1 +#define WM_ADSP_MAX_FRAGMENTS 256 +#define WM_ADSP_MIN_FRAGMENT_SIZE_WORDS 64 +#define WM_ADSP_MAX_FRAGMENT_SIZE_WORDS 4096 + +#define WM_ADSP_ALG_XM_STRUCT_MAGIC 0x49aec7 + +#define HOST_BUFFER_FIELD(field) \ + (offsetof(struct wm_adsp_buffer, field) / sizeof(__be32)) + +#define ALG_XM_FIELD(field) \ + (offsetof(struct wm_adsp_alg_xm_struct, field) / sizeof(__be32)) + +#define HOST_BUF_COEFF_SUPPORTED_COMPAT_VER 1 + +#define HOST_BUF_COEFF_COMPAT_VER_MASK 0xFF00 +#define HOST_BUF_COEFF_COMPAT_VER_SHIFT 8 + +static int wm_adsp_buffer_init(struct wm_adsp *dsp); +static int wm_adsp_buffer_free(struct wm_adsp *dsp); + +struct wm_adsp_buffer_region { + unsigned int offset; + unsigned int cumulative_size; + unsigned int mem_type; + unsigned int base_addr; +}; + +struct wm_adsp_buffer_region_def { + unsigned int mem_type; + unsigned int base_offset; + unsigned int size_offset; +}; + +static const struct wm_adsp_buffer_region_def default_regions[] = { + { + .mem_type = WMFW_ADSP2_XM, + .base_offset = HOST_BUFFER_FIELD(buf1_base), + .size_offset = HOST_BUFFER_FIELD(buf1_size), + }, + { + .mem_type = WMFW_ADSP2_XM, + .base_offset = HOST_BUFFER_FIELD(buf2_base), + .size_offset = HOST_BUFFER_FIELD(buf1_buf2_size), + }, + { + .mem_type = WMFW_ADSP2_YM, + .base_offset = HOST_BUFFER_FIELD(buf3_base), + .size_offset = HOST_BUFFER_FIELD(buf_total_size), + }, +}; + +static const struct wm_adsp_buffer_region_def vpu_regions[] = { + { + .mem_type = WMFW_VPU_DM, + .base_offset = HOST_BUFFER_FIELD(buf1_base), + .size_offset = HOST_BUFFER_FIELD(buf1_size), + }, + { + .mem_type = WMFW_VPU_DM, + .base_offset = HOST_BUFFER_FIELD(buf2_base), + .size_offset = HOST_BUFFER_FIELD(buf1_buf2_size), + }, + { + .mem_type = WMFW_VPU_DM, + .base_offset = HOST_BUFFER_FIELD(buf3_base), + .size_offset = HOST_BUFFER_FIELD(buf_total_size), + }, +}; + +struct wm_adsp_fw_caps { + u32 id; + struct snd_codec_desc desc; +}; + +static const struct wm_adsp_fw_caps ctrl_caps[] = { + { + .id = SND_AUDIOCODEC_BESPOKE, + .desc = { + .max_ch = 8, + .sample_rates = { 16000 }, + .num_sample_rates = 1, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + }, +}; + +static const struct wm_adsp_fw_caps trace_caps[] = { + { + .id = SND_AUDIOCODEC_BESPOKE, + .desc = { + .max_ch = 8, + .sample_rates = { + 4000, 8000, 11025, 12000, 16000, 22050, + 24000, 32000, 44100, 48000, 64000, 88200, + 96000, 176400, 192000 + }, + .num_sample_rates = 15, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + }, +}; + +static const struct { + const char *file; + int compr_direction; + int num_caps; + const struct wm_adsp_fw_caps *caps; + bool voice_trigger; +} wm_adsp_fw[WM_ADSP_NUM_FW] = { + [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" }, + [WM_ADSP_FW_HIFI] = { .file = "hifi" }, + [WM_ADSP_FW_TX] = { .file = "tx" }, + [WM_ADSP_FW_TX_SPK] = { .file = "tx-spk" }, + [WM_ADSP_FW_RX] = { .file = "rx" }, + [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" }, + [WM_ADSP_FW_CTRL] = { + .file = "ctrl", + .compr_direction = SND_COMPRESS_CAPTURE, + .num_caps = ARRAY_SIZE(ctrl_caps), + .caps = ctrl_caps, + .voice_trigger = true, + }, + [WM_ADSP_FW_ASR] = { .file = "asr" }, + [WM_ADSP_FW_TRACE] = { + .file = "trace", + .compr_direction = SND_COMPRESS_CAPTURE, + .num_caps = ARRAY_SIZE(trace_caps), + .caps = trace_caps, + }, + [WM_ADSP_FW_SPK_PROT] = { .file = "spk-prot" }, + [WM_ADSP_FW_SPK_CALI] = { .file = "spk-cali" }, + [WM_ADSP_FW_SPK_DIAG] = { .file = "spk-diag" }, + [WM_ADSP_FW_MISC] = { .file = "misc" }, +}; + +struct wm_coeff_ctl_ops { + int (*xget)(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + int (*xput)(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +}; + +struct wm_coeff_ctl { + const char *name; + const char *fw_name; + /* Subname is needed to match with firmwanre */ + const char *subname; + unsigned int subname_len; + struct wm_adsp_alg_region alg_region; + struct wm_coeff_ctl_ops ops; + struct wm_adsp *dsp; + unsigned int enabled : 1; + struct list_head list; + void *cache; + unsigned int offset; + size_t len; + unsigned int set : 1; + struct soc_bytes_ext bytes_ext; + unsigned int flags; + unsigned int type; +}; + +static const char *wm_adsp_mem_region_name(unsigned int type) +{ + switch (type) { + case WMFW_ADSP1_PM: + return "PM"; + case WMFW_HALO_PM_PACKED: + return "PM_PACKED"; + case WMFW_ADSP1_DM: + return "DM"; + case WMFW_ADSP2_XM: + return "XM"; + case WMFW_HALO_XM_PACKED: + return "XM_PACKED"; + case WMFW_ADSP2_YM: + return "YM"; + case WMFW_HALO_YM_PACKED: + return "YM_PACKED"; + case WMFW_ADSP1_ZM: + return "ZM"; + case WMFW_VPU_DM: + return "DM"; + default: + return NULL; + } +} + +#ifdef CONFIG_DEBUG_FS +static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) +{ + char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); + + kfree(dsp->wmfw_file_name); + dsp->wmfw_file_name = tmp; +} + +static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) +{ + char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); + + kfree(dsp->bin_file_name); + dsp->bin_file_name = tmp; +} + +static void wm_adsp_debugfs_clear(struct wm_adsp *dsp) +{ + kfree(dsp->wmfw_file_name); + kfree(dsp->bin_file_name); + dsp->wmfw_file_name = NULL; + dsp->bin_file_name = NULL; +} + +static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + struct wm_adsp *dsp = file->private_data; + ssize_t ret; + + mutex_lock(&dsp->pwr_lock); + + if (!dsp->wmfw_file_name || !dsp->booted) + ret = 0; + else + ret = simple_read_from_buffer(user_buf, count, ppos, + dsp->wmfw_file_name, + strlen(dsp->wmfw_file_name)); + + mutex_unlock(&dsp->pwr_lock); + return ret; +} + +static ssize_t wm_adsp_debugfs_bin_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + struct wm_adsp *dsp = file->private_data; + ssize_t ret; + + mutex_lock(&dsp->pwr_lock); + + if (!dsp->bin_file_name || !dsp->booted) + ret = 0; + else + ret = simple_read_from_buffer(user_buf, count, ppos, + dsp->bin_file_name, + strlen(dsp->bin_file_name)); + + mutex_unlock(&dsp->pwr_lock); + return ret; +} + +static const struct { + const char *name; + const struct file_operations fops; +} wm_adsp_debugfs_fops[] = { + { + .name = "wmfw_file_name", + .fops = { + .open = simple_open, + .read = wm_adsp_debugfs_wmfw_read, + }, + }, + { + .name = "bin_file_name", + .fops = { + .open = simple_open, + .read = wm_adsp_debugfs_bin_read, + }, + }, +}; + +static void wm_adsp2_init_debugfs(struct wm_adsp *dsp, + struct snd_soc_component *component) +{ + struct dentry *root = NULL; + int i; + + if (!component->debugfs_root) { + adsp_err(dsp, "No codec debugfs root\n"); + goto err; + } + + root = debugfs_create_dir(dsp->name, component->debugfs_root); + + if (!root) + goto err; + + if (!debugfs_create_bool("booted", 0444, root, &dsp->booted)) + goto err; + + if (!debugfs_create_bool("running", 0444, root, &dsp->running)) + goto err; + + if (!debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id)) + goto err; + + if (!debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version)) + goto err; + + for (i = 0; i < ARRAY_SIZE(wm_adsp_debugfs_fops); ++i) { + if (!debugfs_create_file(wm_adsp_debugfs_fops[i].name, 0444, + root, dsp, + &wm_adsp_debugfs_fops[i].fops)) + goto err; + } + + dsp->debugfs_root = root; + return; + +err: + debugfs_remove_recursive(root); + adsp_err(dsp, "Failed to create debugfs\n"); +} + +static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) +{ + wm_adsp_debugfs_clear(dsp); + debugfs_remove_recursive(dsp->debugfs_root); +} +#else +static inline void wm_adsp2_init_debugfs(struct wm_adsp *dsp, + struct snd_soc_component *component) +{ +} + +static inline void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) +{ +} + +static inline void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, + const char *s) +{ +} + +static inline void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, + const char *s) +{ +} + +static inline void wm_adsp_debugfs_clear(struct wm_adsp *dsp) +{ +} +#endif + +int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct wm_adsp *dsp = snd_soc_component_get_drvdata(component); + + ucontrol->value.enumerated.item[0] = dsp[e->shift_l].fw; + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp_fw_get); + +int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct wm_adsp *dsp = snd_soc_component_get_drvdata(component); + int ret = 0; + + if (ucontrol->value.enumerated.item[0] == dsp[e->shift_l].fw) + return 0; + + if (ucontrol->value.enumerated.item[0] >= WM_ADSP_NUM_FW) + return -EINVAL; + + mutex_lock(&dsp[e->shift_l].pwr_lock); + + if (dsp[e->shift_l].booted || !list_empty(&dsp[e->shift_l].compr_list)) + ret = -EBUSY; + else + dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0]; + + mutex_unlock(&dsp[e->shift_l].pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp_fw_put); + +const struct soc_enum wm_adsp_fw_enum[] = { + SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), + SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), + SOC_ENUM_SINGLE(0, 2, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), + SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), + SOC_ENUM_SINGLE(0, 4, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), + SOC_ENUM_SINGLE(0, 5, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), + SOC_ENUM_SINGLE(0, 6, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), +}; +EXPORT_SYMBOL_GPL(wm_adsp_fw_enum); + +static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, + int type) +{ + int i; + + for (i = 0; i < dsp->num_mems; i++) + if (dsp->mem[i].type == type) + return &dsp->mem[i]; + + return NULL; +} + +static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *mem, + unsigned int offset) +{ + switch (mem->type) { + case WMFW_ADSP1_PM: + return mem->base + (offset * 3); + case WMFW_ADSP1_DM: + case WMFW_ADSP2_XM: + case WMFW_ADSP2_YM: + case WMFW_ADSP1_ZM: + return mem->base + (offset * 2); + default: + WARN(1, "Unknown memory region type"); + return offset; + } +} + +static unsigned int wm_halo_region_to_reg(struct wm_adsp_region const *mem, + unsigned int offset) +{ + switch (mem->type) { + case WMFW_ADSP2_XM: + case WMFW_ADSP2_YM: + return mem->base + (offset * 4); + case WMFW_HALO_XM_PACKED: + case WMFW_HALO_YM_PACKED: + return (mem->base + (offset * 3)) & ~0x3; + case WMFW_HALO_PM_PACKED: + return mem->base + (offset * 5); + default: + WARN(1, "Unknown memory region type"); + return offset; + } +} + +static unsigned int wm_vpu_region_to_reg(struct wm_adsp_region const *mem, + unsigned int offset) +{ + switch (mem->type) { + case WMFW_VPU_DM: + return mem->base + (offset * 4); + default: + WARN(1, "Unknown memory region type"); + return offset; + } +} + +static void wm_adsp_read_fw_status(struct wm_adsp *dsp, int noffs, + unsigned int *offs) +{ + unsigned int *scratch; + unsigned int i; + int ret; + + scratch = kmalloc(sizeof(*scratch), GFP_KERNEL | GFP_DMA); + if (!scratch) + return; + + for (i = 0; i < noffs; ++i) { + ret = regmap_read(dsp->regmap, dsp->base + offs[i], scratch); + if (ret) { + adsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret); + goto out; + } + + offs[i] = *scratch; + } + +out: + kfree(scratch); +} + +static void wm_adsp2_show_fw_status(struct wm_adsp *dsp) +{ + unsigned int offs[] = { + ADSP2_SCRATCH0, + ADSP2_SCRATCH1, + ADSP2_SCRATCH2, + ADSP2_SCRATCH3, + }; + + wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + + adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", offs[0], + offs[1], offs[2], offs[3]); +} + +static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp) +{ + unsigned int offs[] = { ADSP2V2_SCRATCH0_1, ADSP2V2_SCRATCH2_3 }; + + wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + + adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", + offs[0] & 0xFFFF, offs[0] >> 16, offs[1] & 0xFFFF, + offs[1] >> 16); +} + +static void wm_halo_show_fw_status(struct wm_adsp *dsp) +{ + unsigned int offs[] = { + HALO_SCRATCH1, + HALO_SCRATCH2, + HALO_SCRATCH3, + HALO_SCRATCH4, + }; + + wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + + adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", offs[0], + offs[1], offs[2], offs[3]); +} + +static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) +{ + return container_of(ext, struct wm_coeff_ctl, bytes_ext); +} + +static int wm_coeff_base_reg(struct wm_coeff_ctl *ctl, unsigned int *reg) +{ + const struct wm_adsp_alg_region *alg_region = &ctl->alg_region; + struct wm_adsp *dsp = ctl->dsp; + const struct wm_adsp_region *mem; + + mem = wm_adsp_find_region(dsp, alg_region->type); + if (!mem) { + adsp_err(dsp, "No base for region %x\n", alg_region->type); + return -EINVAL; + } + + *reg = dsp->ops->region_to_reg(mem, ctl->alg_region.base + ctl->offset); + + return 0; +} + +static int wm_coeff_info(struct snd_kcontrol *kctl, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + + switch (ctl->type) { + case WMFW_CTL_TYPE_ACKED: + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->value.integer.min = WM_ADSP_ACKED_CTL_MIN_VALUE; + uinfo->value.integer.max = WM_ADSP_ACKED_CTL_MAX_VALUE; + uinfo->value.integer.step = 1; + uinfo->count = 1; + break; + default: + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = ctl->len; + break; + } + + return 0; +} + +static int wm_coeff_write_acked_control(struct wm_coeff_ctl *ctl, + unsigned int event_id) +{ + struct wm_adsp *dsp = ctl->dsp; + u32 val = cpu_to_be32(event_id); + unsigned int reg; + int i, ret; + + ret = wm_coeff_base_reg(ctl, ®); + if (ret) + return ret; + + adsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", + event_id, ctl->alg_region.alg, + wm_adsp_mem_region_name(ctl->alg_region.type), ctl->offset); + + ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); + if (ret) { + adsp_err(dsp, "Failed to write %x: %d\n", reg, ret); + return ret; + } + + /* + * Poll for ack, we initially poll at ~1ms intervals for firmwares + * that respond quickly, then go to ~10ms polls. A firmware is unlikely + * to ack instantly so we do the first 1ms delay before reading the + * control to avoid a pointless bus transaction + */ + for (i = 0; i < WM_ADSP_ACKED_CTL_TIMEOUT_MS;) { + switch (i) { + case 0 ... WM_ADSP_ACKED_CTL_N_QUICKPOLLS - 1: + usleep_range(1000, 2000); + i++; + break; + default: + usleep_range(10000, 20000); + i += 10; + break; + } + + ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); + if (ret) { + adsp_err(dsp, "Failed to read %x: %d\n", reg, ret); + return ret; + } + + if (val == 0) { + adsp_dbg(dsp, "Acked control ACKED at poll %u\n", i); + return 0; + } + } + + adsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", reg, + ctl->alg_region.alg, + wm_adsp_mem_region_name(ctl->alg_region.type), ctl->offset); + + return -ETIMEDOUT; +} + +static int wm_coeff_write_control(struct wm_coeff_ctl *ctl, const void *buf, + size_t len) +{ + struct wm_adsp *dsp = ctl->dsp; + void *scratch; + int ret; + unsigned int reg; + + ret = wm_coeff_base_reg(ctl, ®); + if (ret) + return ret; + + scratch = kmemdup(buf, len, GFP_KERNEL | GFP_DMA); + if (!scratch) + return -ENOMEM; + + ret = regmap_raw_write(dsp->regmap, reg, scratch, len); + if (ret) { + adsp_err(dsp, "Failed to write %zu bytes to %x: %d\n", len, reg, + ret); + kfree(scratch); + return ret; + } + adsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg); + + kfree(scratch); + + return 0; +} + +static int wm_coeff_put(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + char *p = ucontrol->value.bytes.data; + int ret = 0; + + mutex_lock(&ctl->dsp->pwr_lock); + + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) + ret = -EPERM; + else + memcpy(ctl->cache, p, ctl->len); + + ctl->set = 1; + if (ctl->enabled && ctl->dsp->running) + ret = wm_coeff_write_control(ctl, p, ctl->len); + + mutex_unlock(&ctl->dsp->pwr_lock); + + return ret; +} + +static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, + const unsigned int __user *bytes, unsigned int size) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + int ret = 0; + + mutex_lock(&ctl->dsp->pwr_lock); + + if (copy_from_user(ctl->cache, bytes, size)) { + ret = -EFAULT; + } else { + ctl->set = 1; + if (ctl->enabled && ctl->dsp->running) + ret = wm_coeff_write_control(ctl, ctl->cache, size); + else if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) + ret = -EPERM; + } + + mutex_unlock(&ctl->dsp->pwr_lock); + + return ret; +} + +static int wm_coeff_put_acked(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + unsigned int val = ucontrol->value.integer.value[0]; + int ret; + + if (val == 0) + return 0; /* 0 means no event */ + + mutex_lock(&ctl->dsp->pwr_lock); + + if (ctl->enabled && ctl->dsp->running) + ret = wm_coeff_write_acked_control(ctl, val); + else + ret = -EPERM; + + mutex_unlock(&ctl->dsp->pwr_lock); + + return ret; +} + +static int wm_coeff_read_control(struct wm_coeff_ctl *ctl, void *buf, + size_t len) +{ + struct wm_adsp *dsp = ctl->dsp; + void *scratch; + int ret; + unsigned int reg; + int read_len = 0; + int toread_len; + + ret = wm_coeff_base_reg(ctl, ®); + if (ret) + return ret; + + scratch = kmalloc(len, GFP_KERNEL | GFP_DMA); + if (!scratch) + return -ENOMEM; + + while ((len - read_len) > 0) { + toread_len = (len - read_len) > MAX_BULKSIZE ? MAX_BULKSIZE : + (len - read_len); + regmap_raw_read(dsp->regmap, reg + read_len / REG_BYTESIZE, + scratch + read_len, toread_len); + if (ret) { + adsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", + toread_len, reg + read_len / REG_BYTESIZE, + ret); + kfree(scratch); + return ret; + } + adsp_dbg(dsp, "Read %zu bytes from %x\n", toread_len, + reg + read_len / REG_BYTESIZE); + read_len += toread_len; + } + + memcpy(buf, scratch, len); + kfree(scratch); + + return 0; +} + +static int wm_coeff_get(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + char *p = ucontrol->value.bytes.data; + int ret = 0; + + mutex_lock(&ctl->dsp->pwr_lock); + + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { + if (ctl->enabled && ctl->dsp->running) + ret = wm_coeff_read_control(ctl, p, ctl->len); + else + ret = -EPERM; + } else { + if (!ctl->flags && ctl->enabled && ctl->dsp->running) + ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); + + memcpy(p, ctl->cache, ctl->len); + } + + mutex_unlock(&ctl->dsp->pwr_lock); + + return ret; +} + +static int wm_coeff_tlv_get(struct snd_kcontrol *kctl, + unsigned int __user *bytes, unsigned int size) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + int ret = 0; + + mutex_lock(&ctl->dsp->pwr_lock); + + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { + if (ctl->enabled && ctl->dsp->running) + ret = wm_coeff_read_control(ctl, ctl->cache, size); + else + ret = -EPERM; + } else { + if (!ctl->flags && ctl->enabled && ctl->dsp->running) + ret = wm_coeff_read_control(ctl, ctl->cache, size); + } + + if (!ret && copy_to_user(bytes, ctl->cache, size)) + ret = -EFAULT; + + mutex_unlock(&ctl->dsp->pwr_lock); + + return ret; +} + +static int wm_coeff_get_acked(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Although it's not useful to read an acked control, we must satisfy + * user-side assumptions that all controls are readable and that a + * write of the same value should be filtered out (it's valid to send + * the same event number again to the firmware). We therefore return 0, + * meaning "no event" so valid event numbers will always be a change + */ + ucontrol->value.integer.value[0] = 0; + + return 0; +} + +struct wmfw_ctl_work { + struct wm_adsp *dsp; + struct wm_coeff_ctl *ctl; + struct work_struct work; +}; + +static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len) +{ + unsigned int out, rd, wr, vol; + + if (len > ADSP_MAX_STD_CTRL_SIZE) { + rd = SNDRV_CTL_ELEM_ACCESS_TLV_READ; + wr = SNDRV_CTL_ELEM_ACCESS_TLV_WRITE; + vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE; + + out = SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; + } else { + rd = SNDRV_CTL_ELEM_ACCESS_READ; + wr = SNDRV_CTL_ELEM_ACCESS_WRITE; + vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE; + + out = 0; + } + + if (in) { + if (in & WMFW_CTL_FLAG_READABLE) + out |= rd; + if (in & WMFW_CTL_FLAG_WRITEABLE) + out |= wr; + if (in & WMFW_CTL_FLAG_VOLATILE) + out |= vol; + } else { + out |= rd | wr | vol; + } + + return out; +} + +static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) +{ + struct snd_kcontrol_new *kcontrol; + int ret; + + if (!ctl || !ctl->name) + return -EINVAL; + + kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); + if (!kcontrol) + return -ENOMEM; + + kcontrol->name = ctl->name; + kcontrol->info = wm_coeff_info; + kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER; + kcontrol->tlv.c = snd_soc_bytes_tlv_callback; + kcontrol->private_value = (unsigned long)&ctl->bytes_ext; + kcontrol->access = wmfw_convert_flags(ctl->flags, ctl->len); + + switch (ctl->type) { + case WMFW_CTL_TYPE_ACKED: + kcontrol->get = wm_coeff_get_acked; + kcontrol->put = wm_coeff_put_acked; + break; + default: + if (kcontrol->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { + ctl->bytes_ext.max = ctl->len; + ctl->bytes_ext.get = wm_coeff_tlv_get; + ctl->bytes_ext.put = wm_coeff_tlv_put; + } else { + kcontrol->get = wm_coeff_get; + kcontrol->put = wm_coeff_put; + } + break; + } + + ret = snd_soc_add_component_controls(dsp->component, kcontrol, 1); + if (ret < 0) + goto err_kcontrol; + + kfree(kcontrol); + + return 0; + +err_kcontrol: + kfree(kcontrol); + return ret; +} + +static int wm_coeff_init_control_caches(struct wm_adsp *dsp) +{ + struct wm_coeff_ctl *ctl; + int ret; + + list_for_each_entry (ctl, &dsp->ctl_list, list) { + if (!ctl->enabled || ctl->set) + continue; + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) + continue; + + /* + * For readable controls populate the cache from the DSP memory. + * For non-readable controls the cache was zero-filled when + * created so we don't need to do anything. + */ + if (!ctl->flags || (ctl->flags & WMFW_CTL_FLAG_READABLE)) { + ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); + if (ret < 0) + return ret; + } + } + + return 0; +} + +static int wm_coeff_sync_controls(struct wm_adsp *dsp) +{ + struct wm_coeff_ctl *ctl; + int ret; + + list_for_each_entry (ctl, &dsp->ctl_list, list) { + if (!ctl->enabled) + continue; + if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) { + ret = wm_coeff_write_control(ctl, ctl->cache, ctl->len); + if (ret < 0) + return ret; + } + } + + return 0; +} + +static void wm_adsp_signal_event_controls(struct wm_adsp *dsp, + unsigned int event) +{ + struct wm_coeff_ctl *ctl; + int ret; + + list_for_each_entry (ctl, &dsp->ctl_list, list) { + if (ctl->type != WMFW_CTL_TYPE_HOSTEVENT) + continue; + + if (!ctl->enabled) + continue; + + ret = wm_coeff_write_acked_control(ctl, event); + if (ret) + adsp_warn( + dsp, + "Failed to send 0x%x event to alg 0x%x (%d)\n", + event, ctl->alg_region.alg, ret); + } +} + +static void wm_adsp_ctl_work(struct work_struct *work) +{ + struct wmfw_ctl_work *ctl_work = + container_of(work, struct wmfw_ctl_work, work); + + wmfw_add_ctl(ctl_work->dsp, ctl_work->ctl); + kfree(ctl_work); +} + +static void wm_adsp_free_ctl_blk(struct wm_coeff_ctl *ctl) +{ + kfree(ctl->cache); + kfree(ctl->name); + kfree(ctl->subname); + kfree(ctl); +} + +static int wm_adsp_create_control(struct wm_adsp *dsp, + const struct wm_adsp_alg_region *alg_region, + unsigned int offset, unsigned int len, + const char *subname, unsigned int subname_len, + unsigned int flags, unsigned int type) +{ + struct wm_coeff_ctl *ctl; + struct wmfw_ctl_work *ctl_work; + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + const char *region_name; + const char *fw_txt; + int ret; + + region_name = wm_adsp_mem_region_name(alg_region->type); + if (!region_name) { + adsp_err(dsp, "Unknown region type: %d\n", alg_region->type); + return -EINVAL; + } + + fw_txt = wm_adsp_fw_text[dsp->fw]; + + switch (dsp->fw_ver) { + case 0: + case 1: + snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s %x", + dsp->name, region_name, alg_region->alg); + subname = NULL; /* don't append subname */ + break; + case 2: + ret = snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, + "%s%c %.12s %x", dsp->name, *region_name, fw_txt, + alg_region->alg); + break; + default: + ret = snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, + "%s %.12s %x", dsp->name, fw_txt, + alg_region->alg); + break; + } + + if (subname) { + int avail = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret - 2; + int skip = 0; + + if (dsp->component->name_prefix) + avail -= strlen(dsp->component->name_prefix) + 1; + + /* Truncate the subname from the start if it is too long */ + if (subname_len > avail) + skip = subname_len - avail; + + snprintf(name + ret, SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret, + " %.*s", subname_len - skip, subname + skip); + } + + list_for_each_entry (ctl, &dsp->ctl_list, list) { + if (!strcmp(ctl->name, name)) { + if (!ctl->enabled) + ctl->enabled = 1; + return 0; + } + } + + ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + if (!ctl) + return -ENOMEM; + ctl->fw_name = fw_txt; + ctl->alg_region = *alg_region; + ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL); + if (!ctl->name) { + ret = -ENOMEM; + goto err_ctl; + } + ctl->subname_len = subname_len; + if (subname) + ctl->subname = + kmemdup(subname, strlen(subname) + 1, GFP_KERNEL); + else + ctl->subname = NULL; + if (!ctl->subname) { + ret = -ENOMEM; + goto err_ctl; + } + ctl->enabled = 1; + ctl->set = 0; + ctl->ops.xget = wm_coeff_get; + ctl->ops.xput = wm_coeff_put; + ctl->dsp = dsp; + + ctl->flags = flags; + ctl->type = type; + ctl->offset = offset; + ctl->len = len; + ctl->cache = kzalloc(ctl->len, GFP_KERNEL); + if (!ctl->cache) { + ret = -ENOMEM; + goto err_ctl_name; + } + + list_add(&ctl->list, &dsp->ctl_list); + + if (flags & WMFW_CTL_FLAG_SYS) + return 0; + + ctl_work = kzalloc(sizeof(*ctl_work), GFP_KERNEL); + if (!ctl_work) { + ret = -ENOMEM; + goto err_ctl_cache; + } + + ctl_work->dsp = dsp; + ctl_work->ctl = ctl; + INIT_WORK(&ctl_work->work, wm_adsp_ctl_work); + schedule_work(&ctl_work->work); + + return 0; + +err_ctl_cache: + kfree(ctl->cache); +err_ctl_name: + kfree(ctl->name); +err_ctl: + kfree(ctl->subname); + kfree(ctl); + + return ret; +} + +struct wm_coeff_parsed_alg { + int id; + const u8 *name; + int name_len; + int ncoeff; +}; + +struct wm_coeff_parsed_coeff { + int offset; + int mem_type; + const u8 *name; + int name_len; + int ctl_type; + int flags; + int len; +}; + +static int wm_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) +{ + int length; + + switch (bytes) { + case 1: + length = **pos; + break; + case 2: + length = le16_to_cpu(*((__le16 *)*pos)); + break; + default: + return 0; + } + + if (str) + *str = *pos + bytes; + + *pos += ((length + bytes) + 3) & ~0x03; + + return length; +} + +static int wm_coeff_parse_int(int bytes, const u8 **pos) +{ + int val = 0; + + switch (bytes) { + case 2: + val = le16_to_cpu(*((__le16 *)*pos)); + break; + case 4: + val = le32_to_cpu(*((__le32 *)*pos)); + break; + default: + break; + } + + *pos += bytes; + + return val; +} + +static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, + struct wm_coeff_parsed_alg *blk) +{ + const struct wmfw_adsp_alg_data *raw; + + switch (dsp->fw_ver) { + case 0: + case 1: + raw = (const struct wmfw_adsp_alg_data *)*data; + *data = raw->data; + + blk->id = le32_to_cpu(raw->id); + blk->name = raw->name; + blk->name_len = strlen(raw->name); + blk->ncoeff = le32_to_cpu(raw->ncoeff); + break; + default: + blk->id = wm_coeff_parse_int(sizeof(raw->id), data); + blk->name_len = + wm_coeff_parse_string(sizeof(u8), data, &blk->name); + wm_coeff_parse_string(sizeof(u16), data, NULL); + blk->ncoeff = wm_coeff_parse_int(sizeof(raw->ncoeff), data); + break; + } + + adsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); + adsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); + adsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); +} + +static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, + struct wm_coeff_parsed_coeff *blk) +{ + const struct wmfw_adsp_coeff_data *raw; + const u8 *tmp; + int length; + + switch (dsp->fw_ver) { + case 0: + case 1: + raw = (const struct wmfw_adsp_coeff_data *)*data; + *data = *data + sizeof(raw->hdr) + le32_to_cpu(raw->hdr.size); + + blk->offset = le16_to_cpu(raw->hdr.offset); + blk->mem_type = le16_to_cpu(raw->hdr.type); + blk->name = raw->name; + blk->name_len = strlen(raw->name); + blk->ctl_type = le16_to_cpu(raw->ctl_type); + blk->flags = le16_to_cpu(raw->flags); + blk->len = le32_to_cpu(raw->len); + break; + default: + tmp = *data; + blk->offset = wm_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); + blk->mem_type = wm_coeff_parse_int(sizeof(raw->hdr.type), &tmp); + length = wm_coeff_parse_int(sizeof(raw->hdr.size), &tmp); + blk->name_len = + wm_coeff_parse_string(sizeof(u8), &tmp, &blk->name); + wm_coeff_parse_string(sizeof(u8), &tmp, NULL); + wm_coeff_parse_string(sizeof(u16), &tmp, NULL); + blk->ctl_type = wm_coeff_parse_int(sizeof(raw->ctl_type), &tmp); + blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp); + blk->len = wm_coeff_parse_int(sizeof(raw->len), &tmp); + + *data = *data + sizeof(raw->hdr) + length; + break; + } + + adsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); + adsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); + adsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); + adsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); + adsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); + adsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); +} + +static int +wm_adsp_check_coeff_flags(struct wm_adsp *dsp, + const struct wm_coeff_parsed_coeff *coeff_blk, + unsigned int f_required, unsigned int f_illegal) +{ + if ((coeff_blk->flags & f_illegal) || + ((coeff_blk->flags & f_required) != f_required)) { + adsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", + coeff_blk->flags, coeff_blk->ctl_type); + return -EINVAL; + } + + return 0; +} + +static int wm_adsp_parse_coeff(struct wm_adsp *dsp, + const struct wmfw_region *region) +{ + struct wm_adsp_alg_region alg_region = {}; + struct wm_coeff_parsed_alg alg_blk; + struct wm_coeff_parsed_coeff coeff_blk; + const u8 *data = region->data; + int i, ret; + + wm_coeff_parse_alg(dsp, &data, &alg_blk); + for (i = 0; i < alg_blk.ncoeff; i++) { + wm_coeff_parse_coeff(dsp, &data, &coeff_blk); + + switch (coeff_blk.ctl_type) { + case SNDRV_CTL_ELEM_TYPE_BYTES: + break; + case WMFW_CTL_TYPE_ACKED: + if (coeff_blk.flags & WMFW_CTL_FLAG_SYS) + continue; /* ignore */ + + ret = wm_adsp_check_coeff_flags( + dsp, &coeff_blk, + WMFW_CTL_FLAG_VOLATILE | + WMFW_CTL_FLAG_WRITEABLE | + WMFW_CTL_FLAG_READABLE, + 0); + if (ret) + return -EINVAL; + break; + case WMFW_CTL_TYPE_HOSTEVENT: + ret = wm_adsp_check_coeff_flags( + dsp, &coeff_blk, + WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_VOLATILE | + WMFW_CTL_FLAG_WRITEABLE | + WMFW_CTL_FLAG_READABLE, + 0); + if (ret) + return -EINVAL; + break; + case WMFW_CTL_TYPE_HOST_BUFFER: + ret = wm_adsp_check_coeff_flags( + dsp, &coeff_blk, + WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_VOLATILE | + WMFW_CTL_FLAG_READABLE, + 0); + if (ret) + return -EINVAL; + break; + default: + adsp_err(dsp, "Unknown control type: %d\n", + coeff_blk.ctl_type); + return -EINVAL; + } + + alg_region.type = coeff_blk.mem_type; + alg_region.alg = alg_blk.id; + + ret = wm_adsp_create_control(dsp, &alg_region, coeff_blk.offset, + coeff_blk.len, coeff_blk.name, + coeff_blk.name_len, + coeff_blk.flags, + coeff_blk.ctl_type); + if (ret < 0) + adsp_err(dsp, "Failed to create control: %.*s, %d\n", + coeff_blk.name_len, coeff_blk.name, ret); + } + + return 0; +} + +static int wm_adsp_write_blocks(struct wm_adsp *dsp, const u8 *data, size_t len, + unsigned int reg, struct list_head *list, + size_t burst_multiple) + +{ + size_t to_write = PAGE_SIZE - (PAGE_SIZE % burst_multiple); + size_t remain = len; + struct wm_adsp_buf *buf; + unsigned int addr_div; + int ret; + + switch (dsp->type) { + case WMFW_ADSP1: + case WMFW_ADSP2: + addr_div = 2; + break; + default: + addr_div = 1; + break; + } + + while (remain > 0) { + if (remain < to_write) + to_write = remain; + + buf = wm_adsp_buf_alloc(data, to_write, list); + if (!buf) { + adsp_err(dsp, "Out of memory\n"); + return -ENOMEM; + } + + ret = regmap_raw_write_async(dsp->regmap, reg, buf->buf, + to_write); + if (ret != 0) { + adsp_err(dsp, "Failed to write %zd bytes at %d\n", + to_write, reg); + + return ret; + } + + data += to_write; + reg += to_write / addr_div; + remain -= to_write; + } + + return 0; +} + +static unsigned int wm_adsp1_parse_sizes(struct wm_adsp *dsp, + const char *const file, + unsigned int pos, + const struct firmware *firmware) +{ + const struct wmfw_adsp1_sizes *adsp1_sizes; + + adsp1_sizes = (void *)&firmware->data[pos]; + + adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file, + le32_to_cpu(adsp1_sizes->dm), le32_to_cpu(adsp1_sizes->pm), + le32_to_cpu(adsp1_sizes->zm)); + + return pos + sizeof(*adsp1_sizes); +} + +static unsigned int wm_adsp2_parse_sizes(struct wm_adsp *dsp, + const char *const file, + unsigned int pos, + const struct firmware *firmware) +{ + const struct wmfw_adsp2_sizes *adsp2_sizes; + + adsp2_sizes = (void *)&firmware->data[pos]; + + adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file, + le32_to_cpu(adsp2_sizes->xm), le32_to_cpu(adsp2_sizes->ym), + le32_to_cpu(adsp2_sizes->pm), le32_to_cpu(adsp2_sizes->zm)); + + return pos + sizeof(*adsp2_sizes); +} + +static unsigned int wm_vpu_parse_sizes(struct wm_adsp *dsp, + const char *const file, unsigned int pos, + const struct firmware *firmware) +{ + const struct wmfw_vpu_sizes *vpu_sizes; + + vpu_sizes = (void *)&firmware->data[pos]; + + return pos + sizeof(*vpu_sizes); +} + +static bool wm_adsp_validate_version(struct wm_adsp *dsp, unsigned int version) +{ + switch (version) { + case 0: + adsp_warn(dsp, "Deprecated file format %d\n", version); + return true; + case 1: + case 2: + return true; + default: + return false; + } +} + +static bool wm_halo_validate_version(struct wm_adsp *dsp, unsigned int version) +{ + switch (version) { + case 3: + return true; + default: + return false; + } +} + +static int wm_adsp_load(struct wm_adsp *dsp) +{ + LIST_HEAD(buf_list); + const struct firmware *firmware; + struct regmap *regmap = dsp->regmap; + unsigned int pos = 0; + const struct wmfw_header *header; + const struct wmfw_adsp1_sizes *adsp1_sizes; + const struct wmfw_footer *footer; + const struct wmfw_region *region; + const struct wm_adsp_region *mem; + const char *region_name; + char *file, *text = NULL; + unsigned int reg; + int regions = 0; + int ret, offset, type; + unsigned int burst_multiple; + + file = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (file == NULL) + return -ENOMEM; + + if (dsp->first_booting) + dsp->fw = WM_ADSP_FW_SPK_PROT; + + snprintf(file, PAGE_SIZE, "%s-%s-%s.wmfw", dsp->part, dsp->fwf_name, + wm_adsp_fw[dsp->fw].file); + file[PAGE_SIZE - 1] = '\0'; + adsp_info(dsp, "download fw algo %s, pid %d.\n", file, current->pid); + + ret = request_firmware(&firmware, file, dsp->dev); + if (ret != 0) { + adsp_err(dsp, "Failed to request '%s'\n", file); + goto out; + } + ret = -EINVAL; + + pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); + if (pos >= firmware->size) { + adsp_err(dsp, "%s: file too short, %zu bytes\n", file, + firmware->size); + goto out_fw; + } + + header = (void *)&firmware->data[0]; + + if (memcmp(&header->magic[0], "WMFW", 4) != 0) { + adsp_err(dsp, "%s: invalid magic\n", file); + goto out_fw; + } + + if (!dsp->ops->validate_version(dsp, header->ver)) { + adsp_err(dsp, "%s: unknown file format %d\n", file, + header->ver); + goto out_fw; + } + + adsp_info(dsp, "Firmware version: %d\n", header->ver); + dsp->fw_ver = header->ver; + + if (header->core != dsp->type) { + adsp_err(dsp, "%s: invalid core %d != %d\n", file, header->core, + dsp->type); + goto out_fw; + } + + pos = sizeof(*header); + pos = dsp->ops->parse_sizes(dsp, file, pos, firmware); + + footer = (void *)&firmware->data[pos]; + pos += sizeof(*footer); + + if (le32_to_cpu(header->len) != pos) { + adsp_err(dsp, "%s: unexpected header length %d\n", file, + le32_to_cpu(header->len)); + goto out_fw; + } + + adsp_dbg(dsp, "%s: timestamp %llu\n", file, + le64_to_cpu(footer->timestamp)); + + while (pos < firmware->size && sizeof(*region) < firmware->size - pos) { + region = (void *)&(firmware->data[pos]); + region_name = "Unknown"; + reg = 0; + burst_multiple = 4; + text = NULL; + offset = le32_to_cpu(region->offset) & 0xffffff; + type = be32_to_cpu(region->type) & 0xff; + + switch (type) { + case WMFW_NAME_TEXT: + region_name = "Firmware name"; + text = kzalloc(le32_to_cpu(region->len) + 1, + GFP_KERNEL); + break; + case WMFW_ALGORITHM_DATA: + region_name = "Algorithm"; + ret = wm_adsp_parse_coeff(dsp, region); + if (ret != 0) + goto out_fw; + break; + case WMFW_INFO_TEXT: + region_name = "Information"; + text = kzalloc(le32_to_cpu(region->len) + 1, + GFP_KERNEL); + break; + case WMFW_ABSOLUTE: + region_name = "Absolute"; + reg = offset; + break; + case WMFW_ADSP1_PM: + case WMFW_ADSP1_DM: + case WMFW_ADSP2_XM: + case WMFW_ADSP2_YM: + case WMFW_ADSP1_ZM: + case WMFW_HALO_PM_PACKED: + case WMFW_HALO_XM_PACKED: + case WMFW_HALO_YM_PACKED: + mem = wm_adsp_find_region(dsp, type); + if (!mem) { + adsp_err(dsp, "No region of type: %x\n", type); + goto out_fw; + } + region_name = wm_adsp_mem_region_name(type); + reg = dsp->ops->region_to_reg(mem, offset); + + if (type == WMFW_HALO_PM_PACKED) + burst_multiple = 20; + else if ((type == WMFW_HALO_XM_PACKED) || + (type == WMFW_HALO_YM_PACKED)) + burst_multiple = 12; + + break; + default: + adsp_warn(dsp, + "%s.%d: Unknown region type %x at %d(%x)\n", + file, regions, type, pos, pos); + break; + } + + adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, regions, + le32_to_cpu(region->len), offset, region_name); + + if (le32_to_cpu(region->len) > + firmware->size - pos - sizeof(*region)) { + adsp_err( + dsp, + "%s.%d: %s region len %d bytes exceeds file length %zu\n", + file, regions, region_name, + le32_to_cpu(region->len), firmware->size); + ret = -EINVAL; + goto out_fw; + } + + if (text) { + memcpy(text, region->data, le32_to_cpu(region->len)); + adsp_info(dsp, "%s: %s\n", file, text); + kfree(text); + text = NULL; + } + + if (reg) { + ret = wm_adsp_write_blocks(dsp, region->data, + le32_to_cpu(region->len), + reg, &buf_list, + burst_multiple); + if (ret != 0) { + adsp_err( + dsp, + "%s.%d: Failed writing data at %d in %s: %d\n", + file, regions, offset, region_name, + ret); + goto out_fw; + } + } + + pos += le32_to_cpu(region->len) + sizeof(*region); + regions++; + } + + ret = regmap_async_complete(regmap); + if (ret != 0) { + adsp_err(dsp, "Failed to complete async write: %d\n", ret); + goto out_fw; + } + + if (pos > firmware->size) + adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", file, + regions, pos - firmware->size); + + wm_adsp_debugfs_save_wmfwname(dsp, file); + +out_fw: + regmap_async_complete(regmap); + wm_adsp_buf_free(&buf_list); + release_firmware(firmware); + kfree(text); +out: + kfree(file); + + return ret; +} + +/* + * Find wm_coeff_ctl with input name as its subname + * If not found, return NULL + */ +static struct wm_coeff_ctl *wm_adsp_get_ctl(struct wm_adsp *dsp, + const char *name) +{ + struct wm_coeff_ctl *pos, *rslt = NULL; + + list_for_each_entry (pos, &dsp->ctl_list, list) { + if (strncmp(pos->subname, name, pos->subname_len) == 0 && + pos->enabled) { + rslt = pos; + break; + } + } + + return rslt; +} + +int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, const void *buf, + size_t len) +{ + struct wm_coeff_ctl *ctl; + + ctl = wm_adsp_get_ctl(dsp, name); + if (!ctl) + return -EINVAL; + + if (len > ctl->len) + return -EINVAL; + + return wm_coeff_write_control(ctl, buf, len); +} +EXPORT_SYMBOL_GPL(wm_adsp_write_ctl); + +int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, void *buf, + size_t len) +{ + struct wm_coeff_ctl *ctl; + + ctl = wm_adsp_get_ctl(dsp, name); + if (!ctl) + return -EINVAL; + + if (len > ctl->len) + return -EINVAL; + + return wm_coeff_read_control(ctl, buf, len); +} +EXPORT_SYMBOL_GPL(wm_adsp_read_ctl); + +static void wm_adsp_ctl_fixup_base(struct wm_adsp *dsp, + const struct wm_adsp_alg_region *alg_region) +{ + struct wm_coeff_ctl *ctl; + + list_for_each_entry (ctl, &dsp->ctl_list, list) { + if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && + alg_region->alg == ctl->alg_region.alg && + alg_region->type == ctl->alg_region.type) { + ctl->alg_region.base = alg_region->base; + } + } +} + +static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs, + const struct wm_adsp_region *mem, + unsigned int pos, unsigned int len) +{ + void *alg; + unsigned int reg; + int ret; + __be32 val; + + if (n_algs == 0) { + adsp_err(dsp, "No algorithms\n"); + return ERR_PTR(-EINVAL); + } + + if (n_algs > 1024) { + adsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); + return ERR_PTR(-EINVAL); + } + + /* Read the terminator first to validate the length */ + reg = dsp->ops->region_to_reg(mem, pos + len); + + ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); + if (ret != 0) { + adsp_err(dsp, "Failed to read algorithm list end: %d\n", ret); + return ERR_PTR(ret); + } + + if (be32_to_cpu(val) != 0xbedead) + adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n", reg, + be32_to_cpu(val)); + + /* Convert length from DSP words to bytes */ + len *= sizeof(u32); + + alg = kzalloc(len, GFP_KERNEL | GFP_DMA); + if (!alg) + return ERR_PTR(-ENOMEM); + + reg = dsp->ops->region_to_reg(mem, pos); + + ret = regmap_raw_read(dsp->regmap, reg, alg, len); + if (ret != 0) { + adsp_err(dsp, "Failed to read algorithm list: %d\n", ret); + kfree(alg); + return ERR_PTR(ret); + } + + return alg; +} + +static struct wm_adsp_alg_region * +wm_adsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id) +{ + struct wm_adsp_alg_region *alg_region; + + list_for_each_entry (alg_region, &dsp->alg_regions, list) { + if (id == alg_region->alg && type == alg_region->type) + return alg_region; + } + + return NULL; +} + +static struct wm_adsp_alg_region * +wm_adsp_create_region(struct wm_adsp *dsp, int type, __be32 id, __be32 base) +{ + struct wm_adsp_alg_region *alg_region; + + alg_region = kzalloc(sizeof(*alg_region), GFP_KERNEL); + if (!alg_region) + return ERR_PTR(-ENOMEM); + + alg_region->type = type; + alg_region->alg = be32_to_cpu(id); + alg_region->base = be32_to_cpu(base); + + list_add_tail(&alg_region->list, &dsp->alg_regions); + + if (dsp->fw_ver > 0) + wm_adsp_ctl_fixup_base(dsp, alg_region); + + return alg_region; +} + +static void wm_adsp_free_alg_regions(struct wm_adsp *dsp) +{ + struct wm_adsp_alg_region *alg_region; + + while (!list_empty(&dsp->alg_regions)) { + alg_region = list_first_entry(&dsp->alg_regions, + struct wm_adsp_alg_region, list); + list_del(&alg_region->list); + kfree(alg_region); + } +} + +static void wmfw_parse_id_header(struct wm_adsp *dsp, struct wmfw_id_hdr *fw, + int nalgs) +{ + dsp->fw_id = be32_to_cpu(fw->id); + dsp->fw_id_version = be32_to_cpu(fw->ver); + + adsp_info(dsp, "Firmware: %x v%d.%d.%d, %d algorithms\n", dsp->fw_id, + (dsp->fw_id_version & 0xff0000) >> 16, + (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, + nalgs); +} + +static void wmfw_v3_parse_id_header(struct wm_adsp *dsp, + struct wmfw_v3_id_hdr *fw, int nalgs) +{ + dsp->fw_id = be32_to_cpu(fw->id); + dsp->fw_id_version = be32_to_cpu(fw->ver); + dsp->fw_vendor_id = be32_to_cpu(fw->vendor_id); + + adsp_info(dsp, "Firmware: %x vendor: 0x%x v%d.%d.%d, %d algorithms\n", + dsp->fw_id, dsp->fw_vendor_id, + (dsp->fw_id_version & 0xff0000) >> 16, + (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, + nalgs); +} + +static int wm_adsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, + int *type, __be32 *base) +{ + struct wm_adsp_alg_region *alg_region; + int i; + + for (i = 0; i < nregions; i++) { + alg_region = wm_adsp_create_region(dsp, type[i], id, base[i]); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + } + + return 0; +} + +static int wm_adsp1_setup_algs(struct wm_adsp *dsp) +{ + struct wmfw_adsp1_id_hdr *adsp1_id; + struct wmfw_adsp1_alg_hdr *adsp1_alg; + struct wm_adsp_alg_region *alg_region; + const struct wm_adsp_region *mem; + unsigned int pos, len; + size_t n_algs; + int i, ret; + + mem = wm_adsp_find_region(dsp, WMFW_ADSP1_DM); + if (WARN_ON(!mem)) + return -EINVAL; + + adsp1_id = kmalloc(sizeof(*adsp1_id), GFP_KERNEL | GFP_DMA); + if (!adsp1_id) + return -ENOMEM; + + ret = regmap_raw_read(dsp->regmap, mem->base, adsp1_id, + sizeof(*adsp1_id)); + if (ret != 0) { + adsp_err(dsp, "Failed to read algorithm info: %d\n", ret); + goto out_adsp1_id; + } + + n_algs = be32_to_cpu(adsp1_id->n_algs); + + wmfw_parse_id_header(dsp, &adsp1_id->fw, n_algs); + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, adsp1_id->fw.id, + adsp1_id->zm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out_adsp1_id; + } + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, adsp1_id->fw.id, + adsp1_id->dm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out_adsp1_id; + } + + /* Calculate offset and length in DSP words */ + pos = sizeof(*adsp1_id) / sizeof(u32); + len = (sizeof(*adsp1_alg) * n_algs) / sizeof(u32); + + adsp1_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len); + if (IS_ERR(adsp1_alg)) { + ret = PTR_ERR(adsp1_alg); + goto out_adsp1_id; + } + + for (i = 0; i < n_algs; i++) { + adsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", i, + be32_to_cpu(adsp1_alg[i].alg.id), + (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff, + be32_to_cpu(adsp1_alg[i].dm), + be32_to_cpu(adsp1_alg[i].zm)); + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, + adsp1_alg[i].alg.id, + adsp1_alg[i].dm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp1_alg[i + 1].dm); + len -= be32_to_cpu(adsp1_alg[i].dm); + len *= 4; + wm_adsp_create_control( + dsp, alg_region, 0, len, NULL, 0, 0, + SNDRV_CTL_ELEM_TYPE_BYTES); + } else { + adsp_warn( + dsp, + "Missing length info for region DM with ID %x\n", + be32_to_cpu(adsp1_alg[i].alg.id)); + } + } + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, + adsp1_alg[i].alg.id, + adsp1_alg[i].zm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp1_alg[i + 1].zm); + len -= be32_to_cpu(adsp1_alg[i].zm); + len *= 4; + wm_adsp_create_control( + dsp, alg_region, 0, len, NULL, 0, 0, + SNDRV_CTL_ELEM_TYPE_BYTES); + } else { + adsp_warn( + dsp, + "Missing length info for region ZM with ID %x\n", + be32_to_cpu(adsp1_alg[i].alg.id)); + } + } + } + +out: + kfree(adsp1_alg); +out_adsp1_id: + kfree(adsp1_id); + return ret; +} + +static int wm_adsp2_setup_algs(struct wm_adsp *dsp) +{ + struct wmfw_adsp2_id_hdr *adsp2_id; + struct wmfw_adsp2_alg_hdr *adsp2_alg; + struct wm_adsp_alg_region *alg_region; + const struct wm_adsp_region *mem; + unsigned int pos, len; + size_t n_algs; + int i, ret; + + mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM); + if (WARN_ON(!mem)) + return -EINVAL; + + adsp2_id = kmalloc(sizeof(*adsp2_id), GFP_KERNEL | GFP_DMA); + if (!adsp2_id) + return -ENOMEM; + + ret = regmap_raw_read(dsp->regmap, mem->base, adsp2_id, + sizeof(*adsp2_id)); + if (ret != 0) { + adsp_err(dsp, "Failed to read algorithm info: %d\n", ret); + goto out_adsp2_id; + } + + n_algs = be32_to_cpu(adsp2_id->n_algs); + + wmfw_parse_id_header(dsp, &adsp2_id->fw, n_algs); + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, adsp2_id->fw.id, + adsp2_id->xm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out_adsp2_id; + } + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, adsp2_id->fw.id, + adsp2_id->ym); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out_adsp2_id; + } + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, adsp2_id->fw.id, + adsp2_id->zm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + /* Calculate offset and length in DSP words */ + pos = sizeof(*adsp2_id) / sizeof(u32); + len = (sizeof(*adsp2_alg) * n_algs) / sizeof(u32); + + adsp2_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len); + if (IS_ERR(adsp2_alg)) { + ret = PTR_ERR(adsp2_alg); + goto out_adsp2_id; + } + + for (i = 0; i < n_algs; i++) { + adsp_info(dsp, "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", i, + be32_to_cpu(adsp2_alg[i].alg.id), + (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, + be32_to_cpu(adsp2_alg[i].xm), + be32_to_cpu(adsp2_alg[i].ym), + be32_to_cpu(adsp2_alg[i].zm)); + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, + adsp2_alg[i].alg.id, + adsp2_alg[i].xm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp2_alg[i + 1].xm); + len -= be32_to_cpu(adsp2_alg[i].xm); + len *= 4; + wm_adsp_create_control( + dsp, alg_region, 0, len, NULL, 0, 0, + SNDRV_CTL_ELEM_TYPE_BYTES); + } else { + adsp_warn( + dsp, + "Missing length info for region XM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, + adsp2_alg[i].alg.id, + adsp2_alg[i].ym); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp2_alg[i + 1].ym); + len -= be32_to_cpu(adsp2_alg[i].ym); + len *= 4; + wm_adsp_create_control( + dsp, alg_region, 0, len, NULL, 0, 0, + SNDRV_CTL_ELEM_TYPE_BYTES); + } else { + adsp_warn( + dsp, + "Missing length info for region YM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + + alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, + adsp2_alg[i].alg.id, + adsp2_alg[i].zm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp2_alg[i + 1].zm); + len -= be32_to_cpu(adsp2_alg[i].zm); + len *= 4; + wm_adsp_create_control( + dsp, alg_region, 0, len, NULL, 0, 0, + SNDRV_CTL_ELEM_TYPE_BYTES); + } else { + adsp_warn( + dsp, + "Missing length info for region ZM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + } + +out: + kfree(adsp2_alg); +out_adsp2_id: + kfree(adsp2_id); + return ret; +} + +static int wm_halo_create_regions(struct wm_adsp *dsp, __be32 id, + __be32 xm_base, __be32 ym_base) +{ + int types[] = { WMFW_ADSP2_XM, WMFW_HALO_XM_PACKED, WMFW_ADSP2_YM, + WMFW_HALO_YM_PACKED }; + __be32 bases[] = { xm_base, xm_base, ym_base, ym_base }; + + return wm_adsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); +} + +static int wm_halo_setup_algs(struct wm_adsp *dsp) +{ + struct wmfw_halo_id_hdr *halo_id; + struct wmfw_halo_alg_hdr *halo_alg; + const struct wm_adsp_region *mem; + unsigned int pos, len, block_rev; + size_t n_algs; + int i, ret; + + mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM); + if (WARN_ON(!mem)) + return -EINVAL; + + halo_id = kmalloc(sizeof(*halo_id), GFP_KERNEL | GFP_DMA); + if (!halo_id) + return -ENOMEM; + + ret = regmap_raw_read(dsp->regmap, mem->base, halo_id, + sizeof(*halo_id)); + if (ret != 0) { + adsp_err(dsp, "Failed to read algorithm info: %d\n", ret); + goto out_halo_id; + } + + block_rev = be32_to_cpu(halo_id->fw.block_rev) >> 16; + switch (block_rev) { + case 3: + break; + default: + adsp_err(dsp, "Unknown firmware ID block version 0x%x\n", + block_rev); + ret = -EINVAL; + goto out_halo_id; + } + + n_algs = be32_to_cpu(halo_id->n_algs); + + wmfw_v3_parse_id_header(dsp, &halo_id->fw, n_algs); + + ret = wm_halo_create_regions(dsp, halo_id->fw.id, halo_id->xm_base, + halo_id->ym_base); + if (ret) + return ret; + + /* Calculate offset and length in DSP words */ + pos = sizeof(*halo_id) / sizeof(u32); + len = (sizeof(*halo_alg) * n_algs) / sizeof(u32); + + halo_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len); + if (IS_ERR(halo_alg)) { + ret = PTR_ERR(halo_alg); + goto out_halo_id; + } + + for (i = 0; i < n_algs; i++) { + adsp_info(dsp, "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", i, + be32_to_cpu(halo_alg[i].alg.id), + (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(halo_alg[i].alg.ver) & 0xff, + be32_to_cpu(halo_alg[i].xm_base), + be32_to_cpu(halo_alg[i].ym_base)); + + ret = wm_halo_create_regions(dsp, halo_alg[i].alg.id, + halo_alg[i].xm_base, + halo_alg[i].ym_base); + if (ret) + goto out; + } + +out: + kfree(halo_alg); +out_halo_id: + kfree(halo_id); + return ret; +} + +static int wm_vpu_setup_algs(struct wm_adsp *vpu) +{ + const struct wm_adsp_region *mem; + struct wmfw_vpu_id_hdr *vpu_id; + struct wmfw_vpu_alg_hdr *vpu_alg; + unsigned int pos, len, block_rev; + struct wm_adsp_alg_region *alg_region; + size_t n_algs; + int i, ret; + + mem = wm_adsp_find_region(vpu, WMFW_VPU_DM); + if (WARN_ON(!mem)) + return -EINVAL; + + vpu_id = kmalloc(sizeof(*vpu_id), GFP_KERNEL | GFP_DMA); + if (!vpu_id) + return -ENOMEM; + + ret = regmap_raw_read(vpu->regmap, mem->base, vpu_id, sizeof(*vpu_id)); + if (ret != 0) { + adsp_err(vpu, "Failed to read algorithm info: %d\n", ret); + goto out_vpu_id; + } + + block_rev = be32_to_cpu(vpu_id->fw.block_rev) >> 16; + switch (block_rev) { + case 3: + break; + default: + adsp_err(vpu, "Unknown firmware ID block version 0x%x\n", + block_rev); + ret = -EINVAL; + goto out_vpu_id; + } + + n_algs = be32_to_cpu(vpu_id->n_algs); + + wmfw_v3_parse_id_header(vpu, &vpu_id->fw, n_algs); + + alg_region = wm_adsp_create_region(vpu, WMFW_VPU_DM, vpu_id->fw.id, + vpu_id->dm_base); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + pos = sizeof(*vpu_id) / sizeof(u32); + len = (sizeof(*vpu_alg) * n_algs) / sizeof(u32); + + vpu_alg = wm_adsp_read_algs(vpu, n_algs, mem, pos, len); + if (IS_ERR(vpu_alg)) { + ret = PTR_ERR(vpu_alg); + goto out_vpu_id; + } + + for (i = 0; i < n_algs; i++) { + adsp_info(vpu, "%d: ID %x v%d.%d.%d DM@%x\n", i, + be32_to_cpu(vpu_alg[i].alg.id), + (be32_to_cpu(vpu_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(vpu_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(vpu_alg[i].alg.ver) & 0xff, + be32_to_cpu(vpu_alg[i].dm_base)); + + alg_region = wm_adsp_create_region(vpu, WMFW_VPU_DM, + vpu_alg[i].alg.id, + vpu_alg[i].dm_base); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + } + +out: + kfree(vpu_alg); +out_vpu_id: + kfree(vpu_id); + return ret; +} + +static int wm_adsp_load_coeff(struct wm_adsp *dsp) +{ + LIST_HEAD(buf_list); + struct regmap *regmap = dsp->regmap; + struct wmfw_coeff_hdr *hdr; + struct wmfw_coeff_item *blk; + const struct firmware *firmware; + const struct wm_adsp_region *mem; + struct wm_adsp_alg_region *alg_region; + const char *region_name; + int ret, pos, blocks, type, offset, reg; + char *file; + unsigned int burst_multiple; + + file = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (file == NULL) + return -ENOMEM; + + if (dsp->tuning_has_prefix || dsp->component->name_prefix) + snprintf(file, PAGE_SIZE, "%s-%s-%s-%s.bin", + dsp->component->name_prefix, dsp->part, dsp->fwf_name, + wm_adsp_fw[dsp->fw].file); + else + snprintf(file, PAGE_SIZE, "%s-%s-%s.bin", dsp->part, + dsp->fwf_name, wm_adsp_fw[dsp->fw].file); + + file[PAGE_SIZE - 1] = '\0'; + adsp_info(dsp, "download fw parm %s\n", file); + + ret = request_firmware(&firmware, file, dsp->dev); + if (ret != 0) { + adsp_warn(dsp, "Failed to request '%s'\n", file); + ret = 0; + goto out; + } + ret = -EINVAL; + + if (sizeof(*hdr) >= firmware->size) { + adsp_err(dsp, "%s: file too short, %zu bytes\n", file, + firmware->size); + goto out_fw; + } + + hdr = (void *)&firmware->data[0]; + if (memcmp(hdr->magic, "WMDR", 4) != 0) { + adsp_err(dsp, "%s: invalid magic\n", file); + goto out_fw; + } + + switch (be32_to_cpu(hdr->rev) & 0xff) { + case 1: + break; + default: + adsp_err(dsp, "%s: Unsupported coefficient file format %d\n", + file, be32_to_cpu(hdr->rev) & 0xff); + ret = -EINVAL; + goto out_fw; + } + + adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, + (le32_to_cpu(hdr->ver) >> 16) & 0xff, + (le32_to_cpu(hdr->ver) >> 8) & 0xff, + le32_to_cpu(hdr->ver) & 0xff); + + pos = le32_to_cpu(hdr->len); + + blocks = 0; + while (pos < firmware->size && sizeof(*blk) < firmware->size - pos) { + blk = (void *)(&firmware->data[pos]); + + type = le16_to_cpu(blk->type); + offset = le16_to_cpu(blk->offset); + + adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", file, blocks, + le32_to_cpu(blk->id), + (le32_to_cpu(blk->ver) >> 16) & 0xff, + (le32_to_cpu(blk->ver) >> 8) & 0xff, + le32_to_cpu(blk->ver) & 0xff); + adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", file, blocks, + le32_to_cpu(blk->len), offset, type); + + reg = 0; + burst_multiple = 4; + region_name = "Unknown"; + switch (type) { + case (WMFW_NAME_TEXT << 8): + case (WMFW_INFO_TEXT << 8): + case (WMFW_METADATA << 8): + break; + case (WMFW_ABSOLUTE << 8): + /* + * Old files may use this for global + * coefficients. + */ + if (le32_to_cpu(blk->id) == dsp->fw_id && offset == 0) { + region_name = "global coefficients"; + mem = wm_adsp_find_region(dsp, type); + if (!mem) { + adsp_err(dsp, "No ZM\n"); + break; + } + reg = dsp->ops->region_to_reg(mem, 0); + + } else { + region_name = "register"; + reg = offset; + } + break; + case WMFW_HALO_PM_PACKED: + burst_multiple += 8; /* plus the 8 below yields 20 */ + /* fall through */ + case WMFW_HALO_XM_PACKED: + case WMFW_HALO_YM_PACKED: + burst_multiple += 8; /* yields 12 */ + /* fall through */ + case WMFW_VPU_DM: + case WMFW_ADSP1_DM: + case WMFW_ADSP1_ZM: + case WMFW_ADSP2_XM: + case WMFW_ADSP2_YM: + adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", file, + blocks, le32_to_cpu(blk->len), type, + le32_to_cpu(blk->id)); + + mem = wm_adsp_find_region(dsp, type); + if (!mem) { + adsp_err(dsp, "No base for region %x\n", type); + break; + } + + alg_region = wm_adsp_find_alg_region( + dsp, type, le32_to_cpu(blk->id)); + if (alg_region) { + reg = alg_region->base; + reg = dsp->ops->region_to_reg(mem, reg); + reg += offset; + } else { + adsp_err(dsp, "No %x for algorithm %x\n", type, + le32_to_cpu(blk->id)); + } + break; + + default: + adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", + file, blocks, type, pos); + break; + } + + if (reg) { + if (le32_to_cpu(blk->len) > + firmware->size - pos - sizeof(*blk)) { + adsp_err( + dsp, + "%s.%d: %s region len %d bytes exceeds file length %zu\n", + file, blocks, region_name, + le32_to_cpu(blk->len), firmware->size); + ret = -EINVAL; + goto out_fw; + } + + adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", file, + blocks, le32_to_cpu(blk->len), reg); + ret = wm_adsp_write_blocks(dsp, blk->data, + le32_to_cpu(blk->len), reg, + &buf_list, burst_multiple); + if (ret != 0) { + adsp_err( + dsp, + "%s.%d: Failed to write to %x in %s: %d\n", + file, blocks, reg, region_name, ret); + } + } + + pos += (le32_to_cpu(blk->len) + sizeof(*blk) + 3) & ~0x03; + blocks++; + } + + ret = regmap_async_complete(regmap); + if (ret != 0) + adsp_err(dsp, "Failed to complete async write: %d\n", ret); + + if (pos > firmware->size) + adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", file, + blocks, pos - firmware->size); + + wm_adsp_debugfs_save_binname(dsp, file); + +out_fw: + regmap_async_complete(regmap); + release_firmware(firmware); + wm_adsp_buf_free(&buf_list); +out: + kfree(file); + return ret; +} + +static int wm_adsp_create_name(struct wm_adsp *dsp) +{ + char *p; + + if (!dsp->name) { + dsp->name = + devm_kasprintf(dsp->dev, GFP_KERNEL, "DSP%d", dsp->num); + if (!dsp->name) + return -ENOMEM; + } + + if (!dsp->fwf_name) { + p = devm_kstrdup(dsp->dev, dsp->name, GFP_KERNEL); + if (!p) + return -ENOMEM; + + dsp->fwf_name = p; + for (; *p != 0; ++p) + *p = tolower(*p); + } + + return 0; +} + +static int wm_adsp_common_init(struct wm_adsp *dsp) +{ + int ret; + + ret = wm_adsp_create_name(dsp); + if (ret) + return ret; + + INIT_LIST_HEAD(&dsp->alg_regions); + INIT_LIST_HEAD(&dsp->ctl_list); + INIT_LIST_HEAD(&dsp->compr_list); + INIT_LIST_HEAD(&dsp->buffer_list); + + mutex_init(&dsp->pwr_lock); + + return 0; +} + +int wm_adsp1_init(struct wm_adsp *dsp) +{ + dsp->ops = &wm_adsp1_ops; + + return wm_adsp_common_init(dsp); +} +EXPORT_SYMBOL_GPL(wm_adsp1_init); + +int wm_adsp1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); + struct wm_adsp *dsp = &dsps[w->shift]; + struct wm_coeff_ctl *ctl; + int ret; + unsigned int val; + + dsp->component = component; + + mutex_lock(&dsp->pwr_lock); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, ADSP1_SYS_ENA); + + /* + * For simplicity set the DSP clock rate to be the + * SYSCLK rate rather than making it configurable. + */ + if (dsp->sysclk_reg) { + ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); + if (ret != 0) { + adsp_err(dsp, + "Failed to read SYSCLK state: %d\n", + ret); + goto err_mutex; + } + + val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; + + ret = regmap_update_bits(dsp->regmap, + dsp->base + ADSP1_CONTROL_31, + ADSP1_CLK_SEL_MASK, val); + if (ret != 0) { + adsp_err(dsp, "Failed to set clock rate: %d\n", + ret); + goto err_mutex; + } + } + + ret = wm_adsp_load(dsp); + if (ret != 0) + goto err_ena; + + ret = wm_adsp1_setup_algs(dsp); + if (ret != 0) + goto err_ena; + + ret = wm_adsp_load_coeff(dsp); + if (ret != 0) + goto err_ena; + + /* Initialize caches for enabled and unset controls */ + ret = wm_coeff_init_control_caches(dsp); + if (ret != 0) + goto err_ena; + + /* Sync set controls */ + ret = wm_coeff_sync_controls(dsp); + if (ret != 0) + goto err_ena; + + dsp->booted = true; + + /* Start the core running */ + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_CORE_ENA | ADSP1_START, + ADSP1_CORE_ENA | ADSP1_START); + + dsp->running = true; + break; + + case SND_SOC_DAPM_PRE_PMD: + dsp->running = false; + dsp->booted = false; + + /* Halt the core */ + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_CORE_ENA | ADSP1_START, 0); + + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, + ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); + + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, 0); + + list_for_each_entry (ctl, &dsp->ctl_list, list) + ctl->enabled = 0; + + wm_adsp_free_alg_regions(dsp); + break; + + default: + break; + } + + mutex_unlock(&dsp->pwr_lock); + + return 0; + +err_ena: + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, 0); +err_mutex: + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp1_event); + +static int wm_adsp2v2_enable_core(struct wm_adsp *dsp) +{ + unsigned int val; + int ret, count; + + /* Wait for the RAM to start, should be near instantaneous */ + for (count = 0; count < 10; ++count) { + ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val); + if (ret != 0) + return ret; + + if (val & ADSP2_RAM_RDY) + break; + + usleep_range(250, 500); + } + + if (!(val & ADSP2_RAM_RDY)) { + adsp_err(dsp, "Failed to start DSP RAM\n"); + return -EBUSY; + } + + adsp_dbg(dsp, "RAM ready after %d polls\n", count); + + return 0; +} + +static int wm_adsp2_enable_core(struct wm_adsp *dsp) +{ + int ret; + + ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA, ADSP2_SYS_ENA); + if (ret != 0) + return ret; + + return wm_adsp2v2_enable_core(dsp); +} + +static int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) +{ + struct regmap *regmap = dsp->regmap; + unsigned int code0, code1, lock_reg; + + if (!(lock_regions & WM_ADSP2_REGION_ALL)) + return 0; + + lock_regions &= WM_ADSP2_REGION_ALL; + lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0; + + while (lock_regions) { + code0 = code1 = 0; + if (lock_regions & BIT(0)) { + code0 = ADSP2_LOCK_CODE_0; + code1 = ADSP2_LOCK_CODE_1; + } + if (lock_regions & BIT(1)) { + code0 |= ADSP2_LOCK_CODE_0 << ADSP2_LOCK_REGION_SHIFT; + code1 |= ADSP2_LOCK_CODE_1 << ADSP2_LOCK_REGION_SHIFT; + } + regmap_write(regmap, lock_reg, code0); + regmap_write(regmap, lock_reg, code1); + lock_regions >>= 2; + lock_reg += 2; + } + + return 0; +} + +static int wm_adsp2_enable_memory(struct wm_adsp *dsp) +{ + return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, ADSP2_MEM_ENA); +} + +static void wm_adsp2_disable_memory(struct wm_adsp *dsp) +{ + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, 0); +} + +static void wm_adsp2_disable_core(struct wm_adsp *dsp) +{ + regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); + + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA, 0); +} + +static void wm_adsp2v2_disable_core(struct wm_adsp *dsp) +{ + regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, dsp->base + ADSP2V2_WDMA_CONFIG_2, 0); +} + +void wm_adsp_boot_work(struct work_struct *work) +{ + struct wm_adsp *dsp = container_of(work, struct wm_adsp, boot_work); + int ret; + + mutex_lock(&dsp->pwr_lock); + + if (dsp->ops->enable_memory) { + ret = dsp->ops->enable_memory(dsp); + if (ret != 0) + goto err_mutex; + } + + if (dsp->ops->enable_core) { + ret = dsp->ops->enable_core(dsp); + if (ret != 0) + goto err_mem; + } + + ret = wm_adsp_load(dsp); + if (ret != 0) + goto err_ena; + + ret = dsp->ops->setup_algs(dsp); + if (ret != 0) + goto err_ena; + + ret = wm_adsp_load_coeff(dsp); + if (ret != 0) + goto err_ena; + + /* Initialize caches for enabled and unset controls */ + ret = wm_coeff_init_control_caches(dsp); + if (ret != 0) + goto err_ena; + + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); + + dsp->booted = true; + + mutex_unlock(&dsp->pwr_lock); + + return; + +err_ena: + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); +err_mem: + if (dsp->ops->disable_memory) + dsp->ops->disable_memory(dsp); +err_mutex: + mutex_unlock(&dsp->pwr_lock); +} + +static int wm_halo_set_rate_block(struct wm_adsp *dsp, unsigned int rate_base, + unsigned int n_rates, const u8 *rate_cache) +{ + unsigned int addr = dsp->base + rate_base, val; + int ret, i; + + mutex_lock(dsp->rate_lock); + + for (i = 0; i < n_rates; ++i) { + val = rate_cache[i] << HALO_DSP_RATE_SHIFT; + + ret = regmap_update_bits(dsp->regmap, addr + (i * 8), + HALO_DSP_RATE_MASK, val); + if (ret) { + adsp_err(dsp, "Failed to set rate: %d\n", ret); + mutex_unlock(dsp->rate_lock); + return ret; + } + + // adsp_dbg(dsp, "Set rate %d to 0x%x\n", i, val); + } + + udelay(300); + + mutex_unlock(dsp->rate_lock); + + return 0; +} + +static int wm_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regions) +{ + struct reg_sequence config[] = { + { dsp->base + HALO_MPU_LOCK_CONFIG, 0x5555 }, + { dsp->base + HALO_MPU_LOCK_CONFIG, 0xAAAA }, + { dsp->base + HALO_MPU_XMEM_ACCESS_0, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_YMEM_ACCESS_0, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_WINDOW_ACCESS_0, lock_regions }, + { dsp->base + HALO_MPU_XREG_ACCESS_0, lock_regions }, + { dsp->base + HALO_MPU_YREG_ACCESS_0, lock_regions }, + { dsp->base + HALO_MPU_XMEM_ACCESS_1, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_YMEM_ACCESS_1, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_WINDOW_ACCESS_1, lock_regions }, + { dsp->base + HALO_MPU_XREG_ACCESS_1, lock_regions }, + { dsp->base + HALO_MPU_YREG_ACCESS_1, lock_regions }, + { dsp->base + HALO_MPU_XMEM_ACCESS_2, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_YMEM_ACCESS_2, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_WINDOW_ACCESS_2, lock_regions }, + { dsp->base + HALO_MPU_XREG_ACCESS_2, lock_regions }, + { dsp->base + HALO_MPU_YREG_ACCESS_2, lock_regions }, + { dsp->base + HALO_MPU_XMEM_ACCESS_3, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_YMEM_ACCESS_3, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_WINDOW_ACCESS_3, lock_regions }, + { dsp->base + HALO_MPU_XREG_ACCESS_3, lock_regions }, + { dsp->base + HALO_MPU_YREG_ACCESS_3, lock_regions }, + { dsp->base + HALO_MPU_LOCK_CONFIG, 0 }, + }; + + return regmap_multi_reg_write(dsp->regmap, config, ARRAY_SIZE(config)); +} + +int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); + struct wm_adsp *dsp = &dsps[w->shift]; + int ret; + + ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CLOCKING, + ADSP2_CLK_SEL_MASK, + freq << ADSP2_CLK_SEL_SHIFT); + if (ret) + adsp_err(dsp, "Failed to set clock rate: %d\n", ret); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp2_set_dspclk); + +int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct wm_adsp *dsp = &dsps[mc->shift - 1]; + + ucontrol->value.integer.value[0] = dsp->preloaded; + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp2_preloader_get); + +int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct wm_adsp *dsp = &dsps[mc->shift - 1]; + char preload[32]; + + snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->name); + + dsp->preloaded = ucontrol->value.integer.value[0]; + + if (ucontrol->value.integer.value[0]) + snd_soc_component_force_enable_pin(component, preload); + else + snd_soc_component_disable_pin(component, preload); + + snd_soc_dapm_sync(dapm); + + //flush_work(&dsp->boot_work); + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put); + +static void wm_adsp_stop_watchdog(struct wm_adsp *dsp) +{ + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG, + ADSP2_WDT_ENA_MASK, 0); +} + +static void wm_halo_stop_watchdog(struct wm_adsp *dsp) +{ + regmap_update_bits(dsp->regmap, dsp->base + HALO_WDT_CONTROL, + HALO_WDT_EN_MASK, 0); +} + +int wm_adsp_early_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); + struct wm_adsp *dsp = &dsps[w->shift]; + struct wm_coeff_ctl *ctl; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (dsp->first_booting) { + adsp_dbg( + dsp, + "During first time booting, not queue boot_work again.\n"); + flush_work(&dsp->boot_work); + dsp->first_booting = false; + } else + queue_work(dsp->work_queue, &dsp->boot_work); + + break; + case SND_SOC_DAPM_PRE_PMD: + mutex_lock(&dsp->pwr_lock); + + wm_adsp_debugfs_clear(dsp); + + dsp->fw_id = 0; + dsp->fw_id_version = 0; + + dsp->booted = false; + + if (dsp->ops->disable_memory) + dsp->ops->disable_memory(dsp); + + list_for_each_entry (ctl, &dsp->ctl_list, list) + ctl->enabled = 0; + + wm_adsp_free_alg_regions(dsp); + + mutex_unlock(&dsp->pwr_lock); + + adsp_dbg(dsp, "Shutdown complete\n"); + break; + default: + break; + } + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp_early_event); + +static int wm_adsp2_start_core(struct wm_adsp *dsp) +{ + return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_CORE_ENA | ADSP2_START, + ADSP2_CORE_ENA | ADSP2_START); +} + +static void wm_adsp2_stop_core(struct wm_adsp *dsp) +{ + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_CORE_ENA | ADSP2_START, 0); +} + +static int wm_halo_apply_calibration(struct snd_soc_dapm_widget *w) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); + struct wm_adsp *dsp = &dsps[w->shift]; + int ret, val; + + adsp_dbg(dsp, "%s:\n", __func__); + + switch (dsp->fw) { + case WM_ADSP_FW_SPK_CALI: + val = cpu_to_be32(dsp->cal_ambient); + ret = wm_adsp_write_ctl(dsp, "CAL_AMBIENT", (void *)&val, + sizeof(__be32)); + if (ret) + adsp_dbg(dsp, "%s: Write CAL_AMBIENT, ret=%d\n", + __func__, ret); + break; + case WM_ADSP_FW_SPK_PROT: + val = cpu_to_be32(dsp->cal_r); + ret = wm_adsp_write_ctl(dsp, "CAL_R", (void *)&val, + sizeof(__be32)); + if (ret) + adsp_dbg(dsp, "%s: Write CAL_R, ret=%d\n", __func__, + ret); + + val = cpu_to_be32(dsp->cal_status); + ret = wm_adsp_write_ctl(dsp, "CAL_STATUS", (void *)&val, + sizeof(__be32)); + if (ret) + adsp_dbg(dsp, "%s: Write CAL_STATUS ret=%d\n", __func__, + ret); + + val = cpu_to_be32(dsp->cal_checksum); + ret = wm_adsp_write_ctl(dsp, "CAL_CHECKSUM", (void *)&val, + sizeof(__be32)); + if (ret) + adsp_dbg(dsp, "%s: Write CAL_CHECKSUM ret=%d\n", + __func__, ret); + +#if 0 // DC detection + val = cpu_to_be32(150); + ret = wm_adsp_write_ctl(dsp, "DC_OFFSET_HOLD_TIME", (void *)&val, sizeof(__be32)); + if (ret) + adsp_warn(dsp, "%s: Write DC_OFFSET_HOLD_TIME ret=%d\n", __func__, ret); +#endif + break; + default: + adsp_dbg(dsp, "Do nothing\n"); + break; + } + + return 0; +} + +int wm_adsp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); + struct wm_adsp *dsp = &dsps[w->shift]; + int ret; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + flush_work(&dsp->boot_work); + + mutex_lock(&dsp->pwr_lock); + + if (!dsp->booted) { + ret = -EIO; + goto err; + } + + if (dsp->ops->enable_core) { + ret = dsp->ops->enable_core(dsp); + if (ret != 0) + goto err; + } + + wm_halo_apply_calibration(w); + + /* Sync set controls */ + ret = wm_coeff_sync_controls(dsp); + if (ret != 0) + goto err; + + if (dsp->ops->lock_memory) { + ret = dsp->ops->lock_memory(dsp, dsp->lock_regions); + if (ret != 0) { + adsp_err(dsp, "Error configuring MPU: %d\n", + ret); + goto err; + } + } + + if (dsp->ops->start_core) { + ret = dsp->ops->start_core(dsp); + if (ret != 0) + goto err; + } + + if (wm_adsp_fw[dsp->fw].num_caps != 0) { + ret = wm_adsp_buffer_init(dsp); + if (ret < 0) + goto err; + } + + dsp->running = true; + + mutex_unlock(&dsp->pwr_lock); + adsp_dbg(dsp, "Execution started\n"); + break; + + case SND_SOC_DAPM_PRE_PMD: + /* Tell the firmware to cleanup */ + wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN); + + if (dsp->ops->stop_watchdog) + dsp->ops->stop_watchdog(dsp); + + /* Log firmware state, it can be useful for analysis */ + if (dsp->ops->show_fw_status) + dsp->ops->show_fw_status(dsp); + + mutex_lock(&dsp->pwr_lock); + + dsp->running = false; + + if (dsp->ops->stop_core) + dsp->ops->stop_core(dsp); + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); + + if (wm_adsp_fw[dsp->fw].num_caps != 0) + wm_adsp_buffer_free(dsp); + + dsp->fatal_error = false; + + mutex_unlock(&dsp->pwr_lock); + + adsp_dbg(dsp, "Execution stopped\n"); + break; + + default: + break; + } + + return 0; +err: + if (dsp->ops->stop_core) + dsp->ops->stop_core(dsp); + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); + mutex_unlock(&dsp->pwr_lock); + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp_event); + +static int wm_halo_start_core(struct wm_adsp *dsp) +{ + int ret; + + adsp_dbg(dsp, "Setting RX rates.\n"); + ret = wm_halo_set_rate_block(dsp, HALO_SAMPLE_RATE_RX1, + dsp->n_rx_channels, dsp->rx_rate_cache); + if (ret) { + adsp_err(dsp, "Failed to set RX rates.\n"); + return ret; + } + + adsp_dbg(dsp, "Setting TX rates.\n"); + ret = wm_halo_set_rate_block(dsp, HALO_SAMPLE_RATE_TX1, + dsp->n_tx_channels, dsp->tx_rate_cache); + if (ret) { + adsp_err(dsp, "Failed to set TX rates.\n"); + return ret; + } + + return regmap_update_bits(dsp->regmap, + dsp->base + HALO_CCM_CORE_CONTROL, + HALO_CORE_EN, HALO_CORE_EN); +} + +static void wm_halo_stop_core(struct wm_adsp *dsp) +{ + regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, + HALO_CORE_EN, 0); + + /* reset halo core with CORE_SOFT_RESET */ + regmap_update_bits(dsp->regmap, dsp->base + HALO_CORE_SOFT_RESET, + HALO_CORE_SOFT_RESET_MASK, 1); +} + +static int wm_adsp_cal_ambient_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wm_adsp *dsp = snd_soc_component_get_drvdata(component); + + ucontrol->value.enumerated.item[0] = dsp->cal_ambient; + adsp_dbg(dsp, "get ambient = %d\n", ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int wm_adsp_cal_ambient_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wm_adsp *dsp = snd_soc_component_get_drvdata(component); + + dsp->cal_ambient = ucontrol->value.enumerated.item[0]; + + adsp_dbg(dsp, "put ambient = %d\n", dsp->cal_ambient); + + return 0; +} + +static int wm_adsp_cal_r_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wm_adsp *dsp = snd_soc_component_get_drvdata(component); + + ucontrol->value.enumerated.item[0] = dsp->cal_r; + adsp_dbg(dsp, "get cal_r = %d\n", ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int wm_adsp_cal_r_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wm_adsp *dsp = snd_soc_component_get_drvdata(component); + + dsp->cal_r = ucontrol->value.enumerated.item[0]; + dsp->cal_checksum = dsp->cal_r + CAL_STATUS_DEFAULT; + + adsp_dbg(dsp, "put cal_r = %d, cal_checksum = %d\n", dsp->cal_r, + dsp->cal_checksum); + + return 0; +} + +static int wm_adsp_cal_status_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wm_adsp *dsp = snd_soc_component_get_drvdata(component); + + ucontrol->value.enumerated.item[0] = dsp->cal_status; + adsp_dbg(dsp, "get calib status = %d\n", + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int wm_adsp_cal_status_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wm_adsp *dsp = snd_soc_component_get_drvdata(component); + + dsp->cal_status = ucontrol->value.enumerated.item[0]; + + adsp_dbg(dsp, "put calib status = %d\n", dsp->cal_status); + + return 0; +} + +static int wm_adsp_cal_checksum_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wm_adsp *dsp = snd_soc_component_get_drvdata(component); + + ucontrol->value.enumerated.item[0] = dsp->cal_checksum; + adsp_dbg(dsp, "get calib checksum = %d\n", + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int wm_adsp_cal_checksum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wm_adsp *dsp = snd_soc_component_get_drvdata(component); + + dsp->cal_checksum = ucontrol->value.enumerated.item[0]; + + adsp_dbg(dsp, "put calib checksum = %d\n", dsp->cal_checksum); + + return 0; +} + +const struct snd_kcontrol_new wm_adsp_cal_controls[] = { + /* In Halo DSP, values are 24-bit */ + SOC_SINGLE_EXT("DSP Set CAL_AMBIENT", SND_SOC_NOPM, 0, 0xFFFFFF, 0, + wm_adsp_cal_ambient_get, wm_adsp_cal_ambient_put), + SOC_SINGLE_EXT("DSP Set CAL_R", SND_SOC_NOPM, 0, 0xFFFFFF, 0, + wm_adsp_cal_r_get, wm_adsp_cal_r_put), + SOC_SINGLE_EXT("DSP Set CAL_STATUS", SND_SOC_NOPM, 0, 0xFFFFFF, 0, + wm_adsp_cal_status_get, wm_adsp_cal_status_put), + SOC_SINGLE_EXT("DSP Set CAL_CHECKSUM", SND_SOC_NOPM, 0, 0xFFFFFF, 0, + wm_adsp_cal_checksum_get, wm_adsp_cal_checksum_put), +}; +EXPORT_SYMBOL_GPL(wm_adsp_cal_controls); + +int wm_adsp2_component_probe(struct wm_adsp *dsp, + struct snd_soc_component *component) +{ + char preload[32]; + + if (!dsp->no_preloader) { + snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->name); + snd_soc_component_disable_pin(component, preload); + } + + wm_adsp2_init_debugfs(dsp, component); + + dsp->component = component; + + snd_soc_add_component_controls(component, wm_adsp_cal_controls, + ARRAY_SIZE(wm_adsp_cal_controls)); + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp2_component_probe); + +int wm_adsp2_component_remove(struct wm_adsp *dsp, + struct snd_soc_component *component) +{ + wm_adsp2_cleanup_debugfs(dsp); + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp2_component_remove); + +int wm_adsp2_init(struct wm_adsp *dsp) +{ + int ret; + + ret = wm_adsp_common_init(dsp); + if (ret) + return ret; + + switch (dsp->rev) { + case 0: + /* + * Disable the DSP memory by default when in reset for a small + * power saving. + */ + ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, 0); + if (ret) { + adsp_err(dsp, "Failed to clear memory retention: %d\n", + ret); + return ret; + } + + dsp->ops = &wm_adsp2_ops[0]; + break; + case 1: + dsp->ops = &wm_adsp2_ops[1]; + break; + default: + dsp->ops = &wm_adsp2_ops[2]; + break; + } + + INIT_WORK(&dsp->boot_work, wm_adsp_boot_work); + + dsp->data_word_size = WM_ADSP_DATA_WORD_SIZE_DEFAULT; + dsp->data_word_mask = WM_ADSP_DATA_WORD_MASK_DEFAULT; + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp2_init); + +int wm_halo_init(struct wm_adsp *dsp, struct mutex *rate_lock) +{ + int ret; + + ret = wm_adsp_common_init(dsp); + if (ret) + return ret; + + dsp->ops = &wm_halo_ops; + dsp->work_queue = create_workqueue("cirrus_fw"); + INIT_WORK(&dsp->boot_work, wm_adsp_boot_work); + + dsp->rate_lock = rate_lock; + dsp->rx_rate_cache = + kcalloc(dsp->n_rx_channels, sizeof(u8), GFP_KERNEL); + dsp->tx_rate_cache = + kcalloc(dsp->n_tx_channels, sizeof(u8), GFP_KERNEL); + + dsp->data_word_size = WM_ADSP_DATA_WORD_SIZE_DEFAULT; + dsp->data_word_mask = WM_ADSP_DATA_WORD_MASK_DEFAULT; + + // Preset speaker calibration default value + dsp->cal_ambient = AMBIENT_DEFAULT; + dsp->cal_r = CAL_R_DEFAULT; + dsp->cal_status = CAL_STATUS_DEFAULT; + dsp->cal_checksum = CAL_R_DEFAULT + CAL_STATUS_DEFAULT; + + return 0; +} +EXPORT_SYMBOL_GPL(wm_halo_init); + +int wm_vpu_init(struct wm_adsp *vpu) +{ + int ret; + + ret = wm_adsp_common_init(vpu); + if (ret) + return ret; + + vpu->ops = &wm_vpu_ops; + + INIT_WORK(&vpu->boot_work, wm_adsp_boot_work); + + vpu->data_word_size = WM_ADSP_DATA_WORD_SIZE_VPU; + vpu->data_word_mask = WM_ADSP_DATA_WORD_MASK_VPU; + + return 0; +} +EXPORT_SYMBOL_GPL(wm_vpu_init); + +void wm_adsp2_remove(struct wm_adsp *dsp) +{ + struct wm_coeff_ctl *ctl; + + while (!list_empty(&dsp->ctl_list)) { + ctl = list_first_entry(&dsp->ctl_list, struct wm_coeff_ctl, + list); + list_del(&ctl->list); + wm_adsp_free_ctl_blk(ctl); + } + + kfree(dsp->rx_rate_cache); + kfree(dsp->tx_rate_cache); +} +EXPORT_SYMBOL_GPL(wm_adsp2_remove); + +static inline int wm_adsp_compr_attached(struct wm_adsp_compr *compr) +{ + return compr->buf != NULL; +} + +static int wm_adsp_compr_attach(struct wm_adsp_compr *compr) +{ + struct wm_adsp_compr_buf *buf = NULL, *tmp; + + if (compr->dsp->fatal_error) + return -EINVAL; + + list_for_each_entry (tmp, &compr->dsp->buffer_list, list) { + if (!tmp->name || !strcmp(compr->name, tmp->name)) { + buf = tmp; + break; + } + } + + if (!buf) + return -EINVAL; + + compr->buf = buf; + buf->compr = compr; + + return 0; +} + +static void wm_adsp_compr_detach(struct wm_adsp_compr *compr) +{ + if (!compr) + return; + + /* Wake the poll so it can see buffer is no longer attached */ + if (compr->stream) + snd_compr_fragment_elapsed(compr->stream); + + if (wm_adsp_compr_attached(compr)) { + compr->buf->compr = NULL; + compr->buf = NULL; + } +} + +int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) +{ + struct wm_adsp_compr *compr, *tmp; + struct snd_soc_pcm_runtime *rtd = stream->private_data; + int ret = 0; + + mutex_lock(&dsp->pwr_lock); + + if (wm_adsp_fw[dsp->fw].num_caps == 0) { + adsp_err(dsp, "%s: Firmware does not support compressed API\n", + rtd->codec_dai->name); + ret = -ENXIO; + goto out; + } + + if (wm_adsp_fw[dsp->fw].compr_direction != stream->direction) { + adsp_err(dsp, + "%s: Firmware does not support stream direction\n", + rtd->codec_dai->name); + ret = -EINVAL; + goto out; + } + + list_for_each_entry (tmp, &dsp->compr_list, list) { + if (!strcmp(tmp->name, rtd->codec_dai->name)) { + adsp_err(dsp, + "%s: Only a single stream supported per dai\n", + rtd->codec_dai->name); + ret = -EBUSY; + goto out; + } + } + + compr = kzalloc(sizeof(*compr), GFP_KERNEL); + if (!compr) { + ret = -ENOMEM; + goto out; + } + + compr->dsp = dsp; + compr->stream = stream; + compr->name = rtd->codec_dai->name; + + list_add_tail(&compr->list, &dsp->compr_list); + + stream->runtime->private_data = compr; + +out: + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_open); + +int wm_adsp_compr_free(struct snd_compr_stream *stream) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + struct wm_adsp *dsp = compr->dsp; + + mutex_lock(&dsp->pwr_lock); + + wm_adsp_compr_detach(compr); + list_del(&compr->list); + + kfree(compr->raw_buf); + kfree(compr); + + mutex_unlock(&dsp->pwr_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_free); + +static int wm_adsp_compr_check_params(struct snd_compr_stream *stream, + struct snd_compr_params *params) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + struct wm_adsp *dsp = compr->dsp; + const struct wm_adsp_fw_caps *caps; + const struct snd_codec_desc *desc; + int i, j; + + if (params->buffer.fragment_size < + (WM_ADSP_MIN_FRAGMENT_SIZE_WORDS * dsp->data_word_size) || + params->buffer.fragment_size > + (WM_ADSP_MAX_FRAGMENT_SIZE_WORDS * dsp->data_word_size) || + params->buffer.fragments < WM_ADSP_MIN_FRAGMENTS || + params->buffer.fragments > WM_ADSP_MAX_FRAGMENTS || + params->buffer.fragment_size % dsp->data_word_size) { + compr_err(compr, "Invalid buffer fragsize=%d fragments=%d\n", + params->buffer.fragment_size, + params->buffer.fragments); + + return -EINVAL; + } + + for (i = 0; i < wm_adsp_fw[dsp->fw].num_caps; i++) { + caps = &wm_adsp_fw[dsp->fw].caps[i]; + desc = &caps->desc; + + if (caps->id != params->codec.id) + continue; + + if (stream->direction == SND_COMPRESS_PLAYBACK) { + if (desc->max_ch < params->codec.ch_out) + continue; + } else { + if (desc->max_ch < params->codec.ch_in) + continue; + } + + if (!(desc->formats & (1 << params->codec.format))) + continue; + + for (j = 0; j < desc->num_sample_rates; ++j) + if (desc->sample_rates[j] == params->codec.sample_rate) + return 0; + } + + compr_err(compr, "Invalid params id=%u ch=%u,%u rate=%u fmt=%u\n", + params->codec.id, params->codec.ch_in, params->codec.ch_out, + params->codec.sample_rate, params->codec.format); + return -EINVAL; +} + +static inline unsigned int wm_adsp_compr_frag_words(struct wm_adsp_compr *compr) +{ + return compr->size.fragment_size / compr->dsp->data_word_size; +} + +int wm_adsp_compr_set_params(struct snd_compr_stream *stream, + struct snd_compr_params *params) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + unsigned int size; + int ret; + + ret = wm_adsp_compr_check_params(stream, params); + if (ret) + return ret; + + compr->size = params->buffer; + + compr_dbg(compr, "fragment_size=%d fragments=%d\n", + compr->size.fragment_size, compr->size.fragments); + + size = wm_adsp_compr_frag_words(compr) * sizeof(*compr->raw_buf); + compr->raw_buf = kmalloc(size, GFP_DMA | GFP_KERNEL); + if (!compr->raw_buf) + return -ENOMEM; + + compr->sample_rate = params->codec.sample_rate; + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_set_params); + +int wm_adsp_compr_get_caps(struct snd_compr_stream *stream, + struct snd_compr_caps *caps) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + struct wm_adsp *dsp = compr->dsp; + int fw = compr->dsp->fw; + int i; + + if (wm_adsp_fw[fw].caps) { + for (i = 0; i < wm_adsp_fw[fw].num_caps; i++) + caps->codecs[i] = wm_adsp_fw[fw].caps[i].id; + + caps->num_codecs = i; + caps->direction = wm_adsp_fw[fw].compr_direction; + + caps->min_fragment_size = + WM_ADSP_MIN_FRAGMENT_SIZE_WORDS * dsp->data_word_size; + caps->max_fragment_size = + WM_ADSP_MAX_FRAGMENT_SIZE_WORDS * dsp->data_word_size; + caps->min_fragments = WM_ADSP_MIN_FRAGMENTS; + caps->max_fragments = WM_ADSP_MAX_FRAGMENTS; + } + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps); + +static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type, + unsigned int mem_addr, + unsigned int num_words, u32 *data) +{ + struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); + unsigned int i, reg; + unsigned int data_word_mask = dsp->data_word_mask; + int ret; + + if (!mem) + return -EINVAL; + + reg = dsp->ops->region_to_reg(mem, mem_addr); + + ret = regmap_raw_read(dsp->regmap, reg, data, + sizeof(*data) * num_words); + if (ret < 0) + return ret; + + for (i = 0; i < num_words; ++i) + data[i] = be32_to_cpu(data[i]) & data_word_mask; + + return 0; +} + +static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, + unsigned int mem_addr, u32 *data) +{ + return wm_adsp_read_data_block(dsp, mem_type, mem_addr, 1, data); +} + +static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, + unsigned int mem_addr, u32 data) +{ + struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); + unsigned int reg; + + if (!mem) + return -EINVAL; + + reg = dsp->ops->region_to_reg(mem, mem_addr); + + data = cpu_to_be32(data & dsp->data_word_mask); + + return regmap_raw_write(dsp->regmap, reg, &data, sizeof(data)); +} + +static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf, + unsigned int field_offset, u32 *data) +{ + return wm_adsp_read_data_word(buf->dsp, buf->host_buf_mem_type, + buf->host_buf_ptr + field_offset, data); +} + +static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, + unsigned int field_offset, u32 data) +{ + return wm_adsp_write_data_word(buf->dsp, buf->host_buf_mem_type, + buf->host_buf_ptr + field_offset, data); +} + +static void wm_adsp_remove_padding(u32 *buf, int nwords, int data_word_size) +{ + u8 *pack_in = (u8 *)buf; + u8 *pack_out = (u8 *)buf; + int i, j; + + /* Remove the padding bytes from the data read from the DSP */ + for (i = 0; i < nwords; i++) { + for (j = 0; j < data_word_size; j++) + *pack_out++ = *pack_in++; + + pack_in += sizeof(*buf) - data_word_size; + } +} + +static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) +{ + struct wm_adsp_buffer_region *region; + u32 offset = 0; + int i, ret; + + switch (buf->dsp->type) { + case WMFW_ADSP1: + case WMFW_ADSP2: + case WMFW_HALO: + buf->num_regions = ARRAY_SIZE(default_regions); + buf->region_def = default_regions; + break; + case WMFW_VPU: + buf->num_regions = ARRAY_SIZE(vpu_regions); + buf->region_def = vpu_regions; + break; + default: + return -EINVAL; + } + + buf->regions = + kcalloc(buf->num_regions, sizeof(*buf->regions), GFP_KERNEL); + if (!buf->regions) + return -ENOMEM; + + for (i = 0; i < buf->num_regions; ++i) { + region = &buf->regions[i]; + + region->offset = offset; + region->mem_type = buf->region_def[i].mem_type; + + ret = wm_adsp_buffer_read(buf, buf->region_def[i].base_offset, + ®ion->base_addr); + if (ret < 0) + return ret; + + ret = wm_adsp_buffer_read(buf, buf->region_def[i].size_offset, + &offset); + if (ret < 0) + return ret; + + region->cumulative_size = offset; + + compr_dbg(buf, + "region=%d type=%d base=%08x off=%08x size=%08x\n", i, + region->mem_type, region->base_addr, region->offset, + region->cumulative_size); + } + + return 0; +} + +static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf) +{ + buf->irq_count = 0xFFFFFFFF; + buf->read_index = -1; + buf->avail = 0; +} + +static struct wm_adsp_compr_buf *wm_adsp_buffer_alloc(struct wm_adsp *dsp) +{ + struct wm_adsp_compr_buf *buf; + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return NULL; + + buf->dsp = dsp; + + wm_adsp_buffer_clear(buf); + + list_add_tail(&buf->list, &dsp->buffer_list); + + return buf; +} + +static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) +{ + struct wm_adsp_alg_region *alg_region; + struct wm_adsp_compr_buf *buf; + u32 xmalg, addr, magic; + int i, ret; + + alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); + if (!alg_region) { + adsp_err(dsp, "No algorithm region found\n"); + return -EINVAL; + } + + buf = wm_adsp_buffer_alloc(dsp); + if (!buf) + return -ENOMEM; + + xmalg = dsp->ops->sys_config_size / sizeof(__be32); + + addr = alg_region->base + xmalg + ALG_XM_FIELD(magic); + ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic); + if (ret < 0) + return ret; + + if (magic != WM_ADSP_ALG_XM_STRUCT_MAGIC) + return -ENODEV; + + addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr); + for (i = 0; i < 5; ++i) { + ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, + &buf->host_buf_ptr); + if (ret < 0) + return ret; + + if (buf->host_buf_ptr) + break; + + usleep_range(1000, 2000); + } + + if (!buf->host_buf_ptr) + return -EIO; + + buf->host_buf_mem_type = WMFW_ADSP2_XM; + + ret = wm_adsp_buffer_populate(buf); + if (ret < 0) + return ret; + + compr_dbg(buf, "legacy host_buf_ptr=%x\n", buf->host_buf_ptr); + + return 0; +} + +static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) +{ + int ret, i; + unsigned int val, reg; + struct wm_adsp_host_buf_coeff_v1 coeff_v1; + struct wm_adsp_compr_buf *buf; + + ret = wm_coeff_base_reg(ctl, ®); + if (ret) + return ret; + + for (i = 0; i < 5; ++i) { + ret = regmap_raw_read(ctl->dsp->regmap, reg, &val, sizeof(val)); + if (ret < 0) + return ret; + + if (val) + break; + + usleep_range(1000, 2000); + } + + if (!val) { + adsp_err(ctl->dsp, "Failed to acquire host buffer\n"); + return -EIO; + } + + buf = wm_adsp_buffer_alloc(ctl->dsp); + if (!buf) + return -ENOMEM; + + buf->host_buf_mem_type = ctl->alg_region.type; + buf->host_buf_ptr = be32_to_cpu(val); + + ret = wm_adsp_buffer_populate(buf); + if (ret < 0) + return ret; + + /* + * v0 host_buffer coefficients didn't have versioning, so if the + * control is one word, assume version 0. + */ + if (ctl->len == 4) { + compr_dbg(buf, "host_buf_ptr=%x\n", buf->host_buf_ptr); + return 0; + } + + ret = regmap_raw_read(ctl->dsp->regmap, reg, &coeff_v1, + sizeof(coeff_v1)); + if (ret < 0) + return ret; + + coeff_v1.versions = be32_to_cpu(coeff_v1.versions); + val = coeff_v1.versions & HOST_BUF_COEFF_COMPAT_VER_MASK; + val >>= HOST_BUF_COEFF_COMPAT_VER_SHIFT; + + if (val > HOST_BUF_COEFF_SUPPORTED_COMPAT_VER) { + adsp_err(ctl->dsp, + "Host buffer coeff ver %u > supported version %u\n", + val, HOST_BUF_COEFF_SUPPORTED_COMPAT_VER); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(coeff_v1.name); i++) + coeff_v1.name[i] = be32_to_cpu(coeff_v1.name[i]); + + wm_adsp_remove_padding((u32 *)&coeff_v1.name, ARRAY_SIZE(coeff_v1.name), + ctl->dsp->data_word_size); + + buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part, + (char *)&coeff_v1.name); + + compr_dbg(buf, "host_buf_ptr=%x coeff version %u\n", buf->host_buf_ptr, + val); + + return val; +} + +static int wm_adsp_buffer_init(struct wm_adsp *dsp) +{ + struct wm_coeff_ctl *ctl; + int ret; + + list_for_each_entry (ctl, &dsp->ctl_list, list) { + if (ctl->type != WMFW_CTL_TYPE_HOST_BUFFER) + continue; + + if (!ctl->enabled) + continue; + + ret = wm_adsp_buffer_parse_coeff(ctl); + if (ret < 0) { + adsp_err(dsp, "Failed to parse coeff: %d\n", ret); + goto error; + } else if (ret == 0) { + /* Only one buffer supported for version 0 */ + return 0; + } + } + + if (list_empty(&dsp->buffer_list)) { + /* Fall back to legacy support */ + ret = wm_adsp_buffer_parse_legacy(dsp); + if (ret) { + adsp_err(dsp, "Failed to parse legacy: %d\n", ret); + goto error; + } + } + + return 0; + +error: + wm_adsp_buffer_free(dsp); + return ret; +} + +static int wm_adsp_buffer_free(struct wm_adsp *dsp) +{ + struct wm_adsp_compr_buf *buf, *tmp; + + list_for_each_entry_safe (buf, tmp, &dsp->buffer_list, list) { + wm_adsp_compr_detach(buf->compr); + + kfree(buf->name); + kfree(buf->regions); + list_del(&buf->list); + kfree(buf); + } + + return 0; +} + +static int wm_adsp_buffer_get_error(struct wm_adsp_compr_buf *buf) +{ + int ret; + + ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error); + if (ret < 0) { + compr_err(buf, "Failed to check buffer error: %d\n", ret); + return ret; + } + if (buf->error != 0) { + compr_err(buf, "Buffer error occurred: %d\n", buf->error); + return -EIO; + } + + return 0; +} + +int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + struct wm_adsp *dsp = compr->dsp; + int ret = 0; + + compr_dbg(compr, "Trigger: %d\n", cmd); + + mutex_lock(&dsp->pwr_lock); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + if (!wm_adsp_compr_attached(compr)) { + ret = wm_adsp_compr_attach(compr); + if (ret < 0) { + compr_err( + compr, + "Failed to link buffer and stream: %d\n", + ret); + break; + } + } + + ret = wm_adsp_buffer_get_error(compr->buf); + if (ret < 0) + break; + + /* Trigger the IRQ at one fragment of data */ + ret = wm_adsp_buffer_write(compr->buf, + HOST_BUFFER_FIELD(high_water_mark), + wm_adsp_compr_frag_words(compr)); + if (ret < 0) { + compr_err(compr, "Failed to set high water mark: %d\n", + ret); + break; + } + break; + case SNDRV_PCM_TRIGGER_STOP: + if (wm_adsp_compr_attached(compr)) + wm_adsp_buffer_clear(compr->buf); + break; + default: + ret = -EINVAL; + break; + } + + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_trigger); + +static inline int wm_adsp_buffer_size(struct wm_adsp_compr_buf *buf) +{ + int last_region = buf->num_regions - 1; + + return buf->regions[last_region].cumulative_size; +} + +static int wm_adsp_buffer_update_avail(struct wm_adsp_compr_buf *buf) +{ + u32 next_read_index, next_write_index; + int write_index, read_index, avail; + int ret; + + /* Only sync read index if we haven't already read a valid index */ + if (buf->read_index < 0) { + ret = wm_adsp_buffer_read(buf, + HOST_BUFFER_FIELD(next_read_index), + &next_read_index); + if (ret < 0) + return ret; + + read_index = sign_extend32(next_read_index, 23); + + if (read_index < 0) { + compr_dbg(buf, "Avail check on unstarted stream\n"); + return 0; + } + + buf->read_index = read_index; + } + + ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(next_write_index), + &next_write_index); + if (ret < 0) + return ret; + + write_index = sign_extend32(next_write_index, 23); + + avail = write_index - buf->read_index; + if (avail < 0) + avail += wm_adsp_buffer_size(buf); + + compr_dbg(buf, "readindex=0x%x, writeindex=0x%x, avail=%d\n", + buf->read_index, write_index, + avail * buf->dsp->data_word_size); + + buf->avail = avail; + + return 0; +} + +int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) +{ + struct wm_adsp_compr_buf *buf; + struct wm_adsp_compr *compr; + int ret = 0; + + mutex_lock(&dsp->pwr_lock); + + if (list_empty(&dsp->buffer_list)) { + ret = -ENODEV; + goto out; + } + + adsp_dbg(dsp, "Handling buffer IRQ\n"); + + list_for_each_entry (buf, &dsp->buffer_list, list) { + compr = buf->compr; + + ret = wm_adsp_buffer_get_error(buf); + if (ret < 0) + goto out_notify; /* Wake poll to report error */ + + ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(irq_count), + &buf->irq_count); + if (ret < 0) { + compr_err(buf, "Failed to get irq_count: %d\n", ret); + goto out; + } + + ret = wm_adsp_buffer_update_avail(buf); + if (ret < 0) { + compr_err(buf, "Error reading avail: %d\n", ret); + goto out; + } + + if (wm_adsp_fw[dsp->fw].voice_trigger && buf->irq_count == 2) + ret = WM_ADSP_COMPR_VOICE_TRIGGER; + + out_notify: + if (compr && compr->stream) + snd_compr_fragment_elapsed(compr->stream); + } + +out: + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_handle_irq); + +static int wm_adsp_buffer_reenable_irq(struct wm_adsp_compr_buf *buf) +{ + if (buf->irq_count & 0x01) + return 0; + + compr_dbg(buf, "Enable IRQ(0x%x) for next fragment\n", buf->irq_count); + + buf->irq_count |= 0x01; + + return wm_adsp_buffer_write(buf, HOST_BUFFER_FIELD(irq_ack), + buf->irq_count); +} + +int wm_adsp_compr_pointer(struct snd_compr_stream *stream, + struct snd_compr_tstamp *tstamp) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + struct wm_adsp *dsp = compr->dsp; + struct wm_adsp_compr_buf *buf; + int ret = 0; + + compr_dbg(compr, "Pointer request\n"); + + mutex_lock(&dsp->pwr_lock); + + buf = compr->buf; + + if (dsp->fatal_error || !buf || buf->error) { + snd_compr_stop_error(stream, SNDRV_PCM_STATE_XRUN); + ret = -EIO; + goto out; + } + + if (buf->avail < wm_adsp_compr_frag_words(compr)) { + ret = wm_adsp_buffer_update_avail(buf); + if (ret < 0) { + compr_err(compr, "Error reading avail: %d\n", ret); + goto out; + } + + /* + * If we really have less than 1 fragment available tell the + * DSP to inform us once a whole fragment is available. + */ + if (buf->avail < wm_adsp_compr_frag_words(compr)) { + ret = wm_adsp_buffer_get_error(buf); + if (ret < 0) { + if (buf->error) + snd_compr_stop_error( + stream, SNDRV_PCM_STATE_XRUN); + goto out; + } + + ret = wm_adsp_buffer_reenable_irq(buf); + if (ret < 0) { + compr_err( + compr, + "Failed to re-enable buffer IRQ: %d\n", + ret); + goto out; + } + } + } + + tstamp->copied_total = compr->copied_total; + tstamp->copied_total += buf->avail * dsp->data_word_size; + tstamp->sampling_rate = compr->sample_rate; + +out: + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_pointer); + +static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) +{ + struct wm_adsp_compr_buf *buf = compr->buf; + unsigned int adsp_addr; + int mem_type, nwords, max_read; + int i, ret; + int data_word_size = buf->dsp->data_word_size; + + /* Calculate read parameters */ + for (i = 0; i < buf->num_regions; ++i) + if (buf->read_index < buf->regions[i].cumulative_size) + break; + + if (i == buf->num_regions) + return -EINVAL; + + mem_type = buf->regions[i].mem_type; + adsp_addr = buf->regions[i].base_addr + + (buf->read_index - buf->regions[i].offset); + + max_read = wm_adsp_compr_frag_words(compr); + nwords = buf->regions[i].cumulative_size - buf->read_index; + + if (nwords > target) + nwords = target; + if (nwords > buf->avail) + nwords = buf->avail; + if (nwords > max_read) + nwords = max_read; + if (!nwords) + return 0; + + /* Read data from DSP */ + ret = wm_adsp_read_data_block(buf->dsp, mem_type, adsp_addr, nwords, + compr->raw_buf); + if (ret < 0) + return ret; + + wm_adsp_remove_padding(compr->raw_buf, nwords, data_word_size); + + /* update read index to account for words read */ + buf->read_index += nwords; + if (buf->read_index == wm_adsp_buffer_size(buf)) + buf->read_index = 0; + + ret = wm_adsp_buffer_write(buf, HOST_BUFFER_FIELD(next_read_index), + buf->read_index); + if (ret < 0) + return ret; + + /* update avail to account for words read */ + buf->avail -= nwords; + + return nwords; +} + +static int wm_adsp_compr_read(struct wm_adsp_compr *compr, char __user *buf, + size_t count) +{ + struct wm_adsp *dsp = compr->dsp; + int ntotal = 0; + int nwords, nbytes; + + compr_dbg(compr, "Requested read of %zu bytes\n", count); + + if (dsp->fatal_error || !compr->buf || compr->buf->error) { + snd_compr_stop_error(compr->stream, SNDRV_PCM_STATE_XRUN); + return -EIO; + } + + count /= dsp->data_word_size; + + do { + nwords = wm_adsp_buffer_capture_block(compr, count); + if (nwords < 0) { + compr_err(compr, "Failed to capture block: %d\n", + nwords); + return nwords; + } + + nbytes = nwords * dsp->data_word_size; + + compr_dbg(compr, "Read %d bytes\n", nbytes); + + if (copy_to_user(buf + ntotal, compr->raw_buf, nbytes)) { + compr_err(compr, + "Failed to copy data to user: %d, %d\n", + ntotal, nbytes); + return -EFAULT; + } + + count -= nwords; + ntotal += nbytes; + } while (nwords > 0 && count > 0); + + compr->copied_total += ntotal; + + return ntotal; +} + +int wm_adsp_compr_copy(struct snd_compr_stream *stream, char __user *buf, + size_t count) +{ + struct wm_adsp_compr *compr = stream->runtime->private_data; + struct wm_adsp *dsp = compr->dsp; + int ret; + + mutex_lock(&dsp->pwr_lock); + + if (stream->direction == SND_COMPRESS_CAPTURE) + ret = wm_adsp_compr_read(compr, buf, count); + else + ret = -ENOTSUPP; + + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(wm_adsp_compr_copy); + +static void wm_adsp_fatal_error(struct wm_adsp *dsp) +{ + struct wm_adsp_compr *compr; + + dsp->fatal_error = true; + + list_for_each_entry (compr, &dsp->compr_list, list) { + if (compr->stream) + snd_compr_fragment_elapsed(compr->stream); + } +} + +irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) +{ + unsigned int val; + struct regmap *regmap = dsp->regmap; + int ret = 0; + + mutex_lock(&dsp->pwr_lock); + + ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); + if (ret) { + adsp_err(dsp, "Failed to read Region Lock Ctrl register: %d\n", + ret); + goto error; + } + + if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { + adsp_err(dsp, "watchdog timeout error\n"); + dsp->ops->stop_watchdog(dsp); + wm_adsp_fatal_error(dsp); + } + + if (val & (ADSP2_SLAVE_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { + if (val & ADSP2_SLAVE_ERR_MASK) + adsp_err(dsp, "bus error: slave error\n"); + else + adsp_err(dsp, "bus error: region lock error\n"); + + ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val); + if (ret) { + adsp_err(dsp, + "Failed to read Bus Err Addr register: %d\n", + ret); + goto error; + } + + adsp_err(dsp, "bus error address = 0x%x\n", + val & ADSP2_BUS_ERR_ADDR_MASK); + + ret = regmap_read(regmap, + dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR, + &val); + if (ret) { + adsp_err( + dsp, + "Failed to read Pmem Xmem Err Addr register: %d\n", + ret); + goto error; + } + + adsp_err(dsp, "xmem error address = 0x%x\n", + val & ADSP2_XMEM_ERR_ADDR_MASK); + adsp_err(dsp, "pmem error address = 0x%x\n", + (val & ADSP2_PMEM_ERR_ADDR_MASK) >> + ADSP2_PMEM_ERR_ADDR_SHIFT); + } + + regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, + ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT); + +error: + mutex_unlock(&dsp->pwr_lock); + + return IRQ_HANDLED; +} +EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); + +irqreturn_t wm_halo_bus_error(struct wm_adsp *dsp) +{ + struct regmap *regmap = dsp->regmap; + unsigned int *fault; + struct reg_sequence clear[] = { + { dsp->base + HALO_MPU_XM_VIO_STATUS, 0x0 }, + { dsp->base + HALO_MPU_YM_VIO_STATUS, 0x0 }, + { dsp->base + HALO_MPU_PM_VIO_STATUS, 0x0 }, + }; + int ret; + + fault = kcalloc(6, sizeof(*fault), GFP_KERNEL | GFP_DMA); + if (!fault) + return IRQ_NONE; + + mutex_lock(&dsp->pwr_lock); + + ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_1, + fault); + if (ret) { + adsp_warn(dsp, "Failed to read AHB DEBUG_1: %d\n", ret); + goto exit_unlock; + } + + adsp_warn(dsp, "AHB: STATUS: 0x%x ADDR: 0x%x\n", + *fault & HALO_AHBM_FLAGS_ERR_MASK, + (*fault & HALO_AHBM_CORE_ERR_ADDR_MASK) >> + HALO_AHBM_CORE_ERR_ADDR_SHIFT); + + ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_0, + fault); + if (ret) { + adsp_warn(dsp, "Failed to read AHB DEBUG_0: %d\n", ret); + goto exit_unlock; + } + + adsp_warn(dsp, "AHB: SYS_ADDR: 0x%x\n", *fault); + + ret = regmap_bulk_read(regmap, dsp->base + HALO_MPU_XM_VIO_ADDR, fault, + 6); + if (ret) { + adsp_warn(dsp, "Failed to read MPU fault info: %d\n", ret); + goto exit_unlock; + } + + adsp_warn(dsp, "XM: STATUS:0x%x ADDR:0x%x\n", fault[1], fault[0]); + adsp_warn(dsp, "YM: STATUS:0x%x ADDR:0x%x\n", fault[3], fault[2]); + adsp_warn(dsp, "PM: STATUS:0x%x ADDR:0x%x\n", fault[5], fault[4]); + + ret = regmap_multi_reg_write(dsp->regmap, clear, ARRAY_SIZE(clear)); + if (ret) + adsp_warn(dsp, "Failed to clear MPU status: %d\n", ret); + +exit_unlock: + mutex_unlock(&dsp->pwr_lock); + kfree(fault); + + return IRQ_HANDLED; +} +EXPORT_SYMBOL_GPL(wm_halo_bus_error); + +irqreturn_t wm_halo_wdt_expire(int irq, void *data) +{ + struct wm_adsp *dsp = data; + + mutex_lock(&dsp->pwr_lock); + + adsp_warn(dsp, "WDT Expiry Fault\n"); + dsp->ops->stop_watchdog(dsp); + wm_adsp_fatal_error(dsp); + + mutex_unlock(&dsp->pwr_lock); + + return IRQ_HANDLED; +} +EXPORT_SYMBOL_GPL(wm_halo_wdt_expire); + +static struct wm_adsp_ops wm_adsp1_ops = { + .validate_version = wm_adsp_validate_version, + .parse_sizes = wm_adsp1_parse_sizes, + .region_to_reg = wm_adsp_region_to_reg, +}; + +static struct wm_adsp_ops wm_adsp2_ops[] = { + { + .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), + .parse_sizes = wm_adsp2_parse_sizes, + .validate_version = wm_adsp_validate_version, + .setup_algs = wm_adsp2_setup_algs, + .region_to_reg = wm_adsp_region_to_reg, + + .show_fw_status = wm_adsp2_show_fw_status, + + .enable_memory = wm_adsp2_enable_memory, + .disable_memory = wm_adsp2_disable_memory, + + .enable_core = wm_adsp2_enable_core, + .disable_core = wm_adsp2_disable_core, + + .start_core = wm_adsp2_start_core, + .stop_core = wm_adsp2_stop_core, + + }, + { + .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), + .parse_sizes = wm_adsp2_parse_sizes, + .validate_version = wm_adsp_validate_version, + .setup_algs = wm_adsp2_setup_algs, + .region_to_reg = wm_adsp_region_to_reg, + + .show_fw_status = wm_adsp2v2_show_fw_status, + + .enable_memory = wm_adsp2_enable_memory, + .disable_memory = wm_adsp2_disable_memory, + .lock_memory = wm_adsp2_lock, + + .enable_core = wm_adsp2v2_enable_core, + .disable_core = wm_adsp2v2_disable_core, + + .start_core = wm_adsp2_start_core, + .stop_core = wm_adsp2_stop_core, + }, + { + .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), + .parse_sizes = wm_adsp2_parse_sizes, + .validate_version = wm_adsp_validate_version, + .setup_algs = wm_adsp2_setup_algs, + .region_to_reg = wm_adsp_region_to_reg, + + .show_fw_status = wm_adsp2v2_show_fw_status, + .stop_watchdog = wm_adsp_stop_watchdog, + + .enable_memory = wm_adsp2_enable_memory, + .disable_memory = wm_adsp2_disable_memory, + .lock_memory = wm_adsp2_lock, + + .enable_core = wm_adsp2v2_enable_core, + .disable_core = wm_adsp2v2_disable_core, + + .start_core = wm_adsp2_start_core, + .stop_core = wm_adsp2_stop_core, + }, +}; + +static struct wm_adsp_ops wm_halo_ops = { + .sys_config_size = sizeof(struct wm_halo_system_config_xm_hdr), + .parse_sizes = wm_adsp2_parse_sizes, + .validate_version = wm_halo_validate_version, + .setup_algs = wm_halo_setup_algs, + .region_to_reg = wm_halo_region_to_reg, + + .show_fw_status = wm_halo_show_fw_status, + .stop_watchdog = wm_halo_stop_watchdog, + + .lock_memory = wm_halo_configure_mpu, + + .start_core = wm_halo_start_core, + .stop_core = wm_halo_stop_core, +}; + +static struct wm_adsp_ops wm_vpu_ops = { + .parse_sizes = wm_vpu_parse_sizes, + .validate_version = wm_halo_validate_version, + .setup_algs = wm_vpu_setup_algs, + .region_to_reg = wm_vpu_region_to_reg, +}; + +MODULE_LICENSE("GPL v2"); diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/wm_adsp.h b/techpack/audio/asoc/codecs/cs35l41_v2/wm_adsp.h new file mode 100644 index 000000000000..74caf0ce9ef0 --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/wm_adsp.h @@ -0,0 +1,244 @@ +/* + * wm_adsp.h -- Wolfson ADSP support + * + * Copyright 2012 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __WM_ADSP_H +#define __WM_ADSP_H + +#include +#include +#include + +#include "wmfw.h" + +/* Return values for wm_adsp_compr_handle_irq */ +#define WM_ADSP_COMPR_OK 0 +#define WM_ADSP_COMPR_VOICE_TRIGGER 1 + +#define WM_ADSP2_REGION_0 BIT(0) +#define WM_ADSP2_REGION_1 BIT(1) +#define WM_ADSP2_REGION_2 BIT(2) +#define WM_ADSP2_REGION_3 BIT(3) +#define WM_ADSP2_REGION_4 BIT(4) +#define WM_ADSP2_REGION_5 BIT(5) +#define WM_ADSP2_REGION_6 BIT(6) +#define WM_ADSP2_REGION_7 BIT(7) +#define WM_ADSP2_REGION_8 BIT(8) +#define WM_ADSP2_REGION_9 BIT(9) +#define WM_ADSP2_REGION_1_9 \ + (WM_ADSP2_REGION_1 | WM_ADSP2_REGION_2 | WM_ADSP2_REGION_3 | \ + WM_ADSP2_REGION_4 | WM_ADSP2_REGION_5 | WM_ADSP2_REGION_6 | \ + WM_ADSP2_REGION_7 | WM_ADSP2_REGION_8 | WM_ADSP2_REGION_9) +#define WM_ADSP2_REGION_ALL (WM_ADSP2_REGION_0 | WM_ADSP2_REGION_1_9) + +struct wm_adsp_region { + int type; + unsigned int base; +}; + +struct wm_adsp_alg_region { + struct list_head list; + unsigned int alg; + int type; + unsigned int base; +}; + +struct wm_adsp_compr; +struct wm_adsp_compr_buf; +struct wm_adsp_ops; + +struct wm_adsp { + const char *part; + const char *name; + const char *fwf_name; + int rev; + int num; + int type; + struct device *dev; + struct regmap *regmap; + struct snd_soc_component *component; + + struct wm_adsp_ops *ops; + + unsigned int base; + unsigned int base_sysinfo; + unsigned int sysclk_reg; + unsigned int sysclk_mask; + unsigned int sysclk_shift; + + // Speaker calibration parameters + int cal_ambient; + int cal_r; + int cal_status; + int cal_checksum; + + struct list_head alg_regions; + + unsigned int fw_id; + unsigned int fw_id_version; + unsigned int fw_vendor_id; + + const struct wm_adsp_region *mem; + int num_mems; + + int fw; + int fw_ver; + + bool no_preloader; + bool preloaded; + bool booted; + bool running; + bool fatal_error; + bool tuning_has_prefix; + bool first_booting; + struct list_head ctl_list; + + struct workqueue_struct *work_queue; + struct work_struct boot_work; + + struct list_head compr_list; + struct list_head buffer_list; + + struct mutex pwr_lock; + + unsigned int lock_regions; + + unsigned int n_rx_channels; + unsigned int n_tx_channels; + + struct mutex *rate_lock; + u8 *rx_rate_cache; + u8 *tx_rate_cache; + +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_root; + char *wmfw_file_name; + char *bin_file_name; +#endif + unsigned int data_word_mask; + int data_word_size; +}; + +struct wm_adsp_ops { + unsigned int sys_config_size; + + bool (*validate_version)(struct wm_adsp *dsp, unsigned int version); + unsigned int (*parse_sizes)(struct wm_adsp *dsp, const char *const file, + unsigned int pos, + const struct firmware *firmware); + int (*setup_algs)(struct wm_adsp *dsp); + unsigned int (*region_to_reg)(struct wm_adsp_region const *mem, + unsigned int offset); + + void (*show_fw_status)(struct wm_adsp *dsp); + void (*stop_watchdog)(struct wm_adsp *dsp); + + int (*enable_memory)(struct wm_adsp *dsp); + void (*disable_memory)(struct wm_adsp *dsp); + int (*lock_memory)(struct wm_adsp *dsp, unsigned int lock_regions); + + int (*enable_core)(struct wm_adsp *dsp); + void (*disable_core)(struct wm_adsp *dsp); + + int (*start_core)(struct wm_adsp *dsp); + void (*stop_core)(struct wm_adsp *dsp); +}; + +#define WM_ADSP_PRELOADER(wname, num, event_fn) \ + { \ + .id = snd_soc_dapm_supply, .name = wname " Preloader", \ + .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \ + .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \ + .subseq = 100, /* Ensure we run after SYSCLK supply widget */ \ + } + +#define WM_ADSP1(wname, num) \ + SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \ + wm_adsp1_event, \ + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) + +#define WM_ADSP2_PRELOAD_SWITCH(wname, num) \ + SOC_SINGLE_EXT(wname " Preload Switch", SND_SOC_NOPM, num, 1, 0, \ + wm_adsp2_preloader_get, wm_adsp2_preloader_put) + +#define WM_ADSP2(wname, num, event_fn) \ + SND_SOC_DAPM_SPK(wname " Preload", NULL), \ + WM_ADSP_PRELOADER(wname, num, event_fn), \ + { \ + .id = snd_soc_dapm_out_drv, .name = wname, \ + .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp_event, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD \ + } + +#define WM_HALO(wname, num, event_fn) WM_ADSP2(wname, num, event_fn) + +#define WM_ADSP_FW_CONTROL(dspname, num) \ + SOC_ENUM_EXT(dspname " Firmware", wm_adsp_fw_enum[num], \ + wm_adsp_fw_get, wm_adsp_fw_put) + +extern const struct soc_enum wm_adsp_fw_enum[]; + +int wm_adsp1_init(struct wm_adsp *dsp); +int wm_adsp2_init(struct wm_adsp *dsp); +void wm_adsp2_remove(struct wm_adsp *dsp); +int wm_adsp2_component_probe(struct wm_adsp *dsp, + struct snd_soc_component *component); +int wm_adsp2_component_remove(struct wm_adsp *dsp, + struct snd_soc_component *component); +void wm_adsp_queue_boot_work(struct wm_adsp *dsp); +int wm_vpu_init(struct wm_adsp *vpu); +int wm_halo_init(struct wm_adsp *dsp, struct mutex *rate_lock); + +int wm_adsp1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event); + +int wm_adsp_early_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); + +irqreturn_t wm_adsp2_bus_error(struct wm_adsp *adsp); +irqreturn_t wm_halo_bus_error(struct wm_adsp *dsp); +irqreturn_t wm_halo_wdt_expire(int irq, void *data); + +int wm_adsp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event); +int wm_vpu_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event); + +int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq); + +int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + +int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream); +int wm_adsp_compr_free(struct snd_compr_stream *stream); +int wm_adsp_compr_set_params(struct snd_compr_stream *stream, + struct snd_compr_params *params); +int wm_adsp_compr_get_caps(struct snd_compr_stream *stream, + struct snd_compr_caps *caps); +int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd); +int wm_adsp_compr_handle_irq(struct wm_adsp *dsp); +int wm_adsp_compr_pointer(struct snd_compr_stream *stream, + struct snd_compr_tstamp *tstamp); +int wm_adsp_compr_copy(struct snd_compr_stream *stream, char __user *buf, + size_t count); +int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, const void *buf, + size_t len); +int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, void *buf, + size_t len); +void wm_adsp_boot_work(struct work_struct *work); + +#endif diff --git a/techpack/audio/asoc/codecs/cs35l41_v2/wmfw.h b/techpack/audio/asoc/codecs/cs35l41_v2/wmfw.h new file mode 100644 index 000000000000..4134ba23adfa --- /dev/null +++ b/techpack/audio/asoc/codecs/cs35l41_v2/wmfw.h @@ -0,0 +1,223 @@ +/* + * wmfw.h - Wolfson firmware format information + * + * Copyright 2012 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __WMFW_H +#define __WMFW_H + +#include + +#define WMFW_MAX_ALG_NAME 256 +#define WMFW_MAX_ALG_DESCR_NAME 256 + +#define WMFW_MAX_COEFF_NAME 256 +#define WMFW_MAX_COEFF_DESCR_NAME 256 + +#define WMFW_CTL_FLAG_SYS 0x8000 +#define WMFW_CTL_FLAG_VOLATILE 0x0004 +#define WMFW_CTL_FLAG_WRITEABLE 0x0002 +#define WMFW_CTL_FLAG_READABLE 0x0001 + +/* Non-ALSA coefficient types start at 0x1000 */ +#define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */ +#define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */ +#define WMFW_CTL_TYPE_HOST_BUFFER 0x1002 /* host buffer pointer */ + +struct wmfw_header { + char magic[4]; + __le32 len; + __le16 rev; + u8 core; + u8 ver; +} __packed; + +struct wmfw_footer { + __le64 timestamp; + __le32 checksum; +} __packed; + +struct wmfw_adsp1_sizes { + __le32 dm; + __le32 pm; + __le32 zm; +} __packed; + +struct wmfw_adsp2_sizes { + __le32 xm; + __le32 ym; + __le32 pm; + __le32 zm; +} __packed; + +struct wmfw_vpu_sizes { + __le32 dm; +} __packed; + +struct wmfw_region { + union { + __be32 type; + __le32 offset; + }; + __le32 len; + u8 data[]; +} __packed; + +struct wmfw_id_hdr { + __be32 core_id; + __be32 core_rev; + __be32 id; + __be32 ver; +} __packed; + +struct wmfw_v3_id_hdr { + __be32 core_id; + __be32 block_rev; + __be32 vendor_id; + __be32 id; + __be32 ver; +} __packed; + +struct wmfw_adsp1_id_hdr { + struct wmfw_id_hdr fw; + __be32 zm; + __be32 dm; + __be32 n_algs; +} __packed; + +struct wmfw_adsp2_id_hdr { + struct wmfw_id_hdr fw; + __be32 zm; + __be32 xm; + __be32 ym; + __be32 n_algs; +} __packed; + +struct wmfw_halo_id_hdr { + struct wmfw_v3_id_hdr fw; + __be32 xm_base; + __be32 xm_size; + __be32 ym_base; + __be32 ym_size; + __be32 n_algs; +} __packed; + +struct wmfw_vpu_id_hdr { + struct wmfw_v3_id_hdr fw; + __be32 dm_base; + __be32 dm_size; + __be32 n_algs; +} __packed; + +struct wmfw_alg_hdr { + __be32 id; + __be32 ver; +} __packed; + +struct wmfw_adsp1_alg_hdr { + struct wmfw_alg_hdr alg; + __be32 zm; + __be32 dm; +} __packed; + +struct wmfw_adsp2_alg_hdr { + struct wmfw_alg_hdr alg; + __be32 zm; + __be32 xm; + __be32 ym; +} __packed; + +struct wmfw_vpu_alg_hdr { + struct wmfw_alg_hdr alg; + __be32 dm_base; + __be32 dm_size; +} __packed; + +struct wmfw_halo_alg_hdr { + struct wmfw_alg_hdr alg; + __be32 xm_base; + __be32 xm_size; + __be32 ym_base; + __be32 ym_size; +} __packed; + +struct wmfw_adsp_alg_data { + __le32 id; + u8 name[WMFW_MAX_ALG_NAME]; + u8 descr[WMFW_MAX_ALG_DESCR_NAME]; + __le32 ncoeff; + u8 data[]; +} __packed; + +struct wmfw_adsp_coeff_data { + struct { + __le16 offset; + __le16 type; + __le32 size; + } hdr; + u8 name[WMFW_MAX_COEFF_NAME]; + u8 descr[WMFW_MAX_COEFF_DESCR_NAME]; + __le16 ctl_type; + __le16 flags; + __le32 len; + u8 data[]; +} __packed; + +struct wmfw_coeff_hdr { + u8 magic[4]; + __le32 len; + union { + __be32 rev; + __le32 ver; + }; + union { + __be32 core; + __le32 core_ver; + }; + u8 data[]; +} __packed; + +struct wmfw_coeff_item { + __le16 offset; + __le16 type; + __le32 id; + __le32 ver; + __le32 sr; + __le32 len; + u8 data[]; +} __packed; + +#define WMFW_ADSP1 1 +#define WMFW_ADSP2 2 +#define WMFW_HALO 4 +#define WMFW_VPU 0x45 + +#define WMFW_ABSOLUTE 0xf0 +#define WMFW_ALGORITHM_DATA 0xf2 +#define WMFW_METADATA 0xfc +#define WMFW_NAME_TEXT 0xfe +#define WMFW_INFO_TEXT 0xff + +#define WMFW_ADSP1_PM 2 +#define WMFW_ADSP1_DM 3 +#define WMFW_ADSP1_ZM 4 + +#define WMFW_ADSP2_PM 2 +#define WMFW_ADSP2_ZM 4 +#define WMFW_ADSP2_XM 5 +#define WMFW_ADSP2_YM 6 + +#define WMFW_HALO_PM_PACKED 0x10 +#define WMFW_HALO_XM_PACKED 0x11 +#define WMFW_HALO_YM_PACKED 0x12 + +#define WMFW_VPU_DM 0x30 + +#endif diff --git a/techpack/audio/asoc/codecs/tas2557/Android.mk b/techpack/audio/asoc/codecs/tas2557/Android.mk new file mode 100755 index 000000000000..279ede3ee009 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas2557/Android.mk @@ -0,0 +1,55 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,msmnile),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m +endif + +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE)),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + #AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=tas2557_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_tas2557.ko +LOCAL_MODULE_KBUILD_NAME := tas2557_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/techpack/audio/asoc/codecs/tas2557/Kbuild b/techpack/audio/asoc/codecs/tas2557/Kbuild new file mode 100755 index 000000000000..2215081edeb1 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas2557/Kbuild @@ -0,0 +1,115 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + + + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_SM8150), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif + ifeq ($(CONFIG_ARCH_SM6150), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif + + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ CS35L41 ############ + +# for CS35L41 Codec +ifdef CONFIG_SND_SOC_TAS2557 + TAS2557_OBJS += tas2557-core.o + TAS2557_OBJS += tas2557-misc.o + TAS2557_OBJS += tas2557-codec.o + TAS2557_OBJS += tas2557-regmap.o + TAS2557_OBJS += tiload.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_TAS2557) += tas2557_dlkm.o +tas2557_dlkm-y := $(TAS2557_OBJS) diff --git a/techpack/audio/asoc/codecs/tas2557/Kconfig b/techpack/audio/asoc/codecs/tas2557/Kconfig new file mode 100644 index 000000000000..ecac9592e4bb --- /dev/null +++ b/techpack/audio/asoc/codecs/tas2557/Kconfig @@ -0,0 +1,23 @@ +config SND_SOC_TAS2557 + tristate "Texas Instruments TAS2557 Smart Amplifier" + help + Say Y here if you want to add support for the TAS2557 Smart Amplifier. + +if SND_SOC_TAS2557 + +config TAS2557_REGMAP + bool "Texas Instruments TAS2557 Regmap" + help + Say Y here if you want to add support for the TAS2557 Regmap. + +config TAS2557_CODEC + bool "Texas Instruments TAS2557 Codec" + help + Say Y here if you want to add support for the TAS2557 Codec. + +config TAS2557_MISC + bool "Texas Instruments TAS2557 Misc" + help + Say Y here if you want to add support for the TAS2557 Misc. + +endif diff --git a/techpack/audio/asoc/codecs/tas2557/tas2557-codec.c b/techpack/audio/asoc/codecs/tas2557/tas2557-codec.c new file mode 100644 index 000000000000..03f964805ad0 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas2557/tas2557-codec.c @@ -0,0 +1,673 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** Copyright (C) 2019 XiaoMi, Inc. +** +** 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; version 2. +** +** 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. +** +** File: +** tas2557-codec.c +** +** Description: +** ALSA SoC driver for Texas Instruments TAS2557 High Performance 4W Smart Amplifier +** +** ============================================================================= +*/ + +#ifdef CONFIG_TAS2557_CODEC + +#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tas2557-core.h" +#include "tas2557-codec.h" + +#define KCONTROL_CODEC + +static unsigned int tas2557_codec_read(struct snd_soc_codec *pCodec, + unsigned int nRegister) +{ + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + int ret = 0; + unsigned int Value = 0; + + mutex_lock(&pTAS2557->codec_lock); + + ret = pTAS2557->read(pTAS2557, nRegister, &Value); + if (ret < 0) + dev_err(pTAS2557->dev, "%s, %d, ERROR happen=%d\n", __func__, + __LINE__, ret); + else + ret = Value; + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static int tas2557_codec_write(struct snd_soc_codec *pCodec, + unsigned int nRegister, unsigned int nValue) +{ + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + int ret = 0; + + mutex_lock(&pTAS2557->codec_lock); + + ret = pTAS2557->write(pTAS2557, nRegister, nValue); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static int tas2557_codec_suspend(struct snd_soc_codec *pCodec) +{ + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + int ret = 0; + + mutex_lock(&pTAS2557->codec_lock); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + pTAS2557->runtime_suspend(pTAS2557); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static int tas2557_codec_resume(struct snd_soc_codec *pCodec) +{ + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + int ret = 0; + + mutex_lock(&pTAS2557->codec_lock); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + pTAS2557->runtime_resume(pTAS2557); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static const struct snd_soc_dapm_widget tas2557_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("ASI2", "ASI2 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("ASIM", "ASIM Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_OUT_DRV("ClassD", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_SUPPLY("PLL", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("NDivider", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_OUTPUT("OUT") +}; + +static const struct snd_soc_dapm_route tas2557_audio_map[] = { + { "DAC", NULL, "ASI1" }, { "DAC", NULL, "ASI2" }, + { "DAC", NULL, "ASIM" }, { "ClassD", NULL, "DAC" }, + { "OUT", NULL, "ClassD" }, { "DAC", NULL, "PLL" }, + { "DAC", NULL, "NDivider" }, +}; + +static int tas2557_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + return 0; +} + +static void tas2557_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); +} + +static int tas2557_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&pTAS2557->codec_lock); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + tas2557_enable(pTAS2557, !mute); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_set_dai_sysclk(struct snd_soc_dai *pDAI, int nClkID, + unsigned int nFreqency, int nDir) +{ + struct snd_soc_codec *pCodec = pDAI->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + + dev_dbg(pTAS2557->dev, "tas2557_set_dai_sysclk: freq = %u\n", + nFreqency); + + return 0; +} + +static int tas2557_hw_params(struct snd_pcm_substream *pSubstream, + struct snd_pcm_hw_params *pParams, + struct snd_soc_dai *pDAI) +{ + struct snd_soc_codec *pCodec = pDAI->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + + mutex_lock(&pTAS2557->codec_lock); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + /* do bit rate setting during platform data */ + /* tas2557_set_bit_rate(pTAS2557, channel_both, snd_pcm_format_width(params_format(pParams))); */ + tas2557_set_sampling_rate(pTAS2557, params_rate(pParams)); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_set_dai_fmt(struct snd_soc_dai *pDAI, unsigned int nFormat) +{ + struct snd_soc_codec *codec = pDAI->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + return 0; +} + +static int tas2557_prepare(struct snd_pcm_substream *pSubstream, + struct snd_soc_dai *pDAI) +{ + struct snd_soc_codec *codec = pDAI->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + return 0; +} + +static int tas2557_set_bias_level(struct snd_soc_codec *pCodec, + enum snd_soc_bias_level eLevel) +{ + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + + dev_dbg(pTAS2557->dev, "%s: %d\n", __func__, eLevel); + return 0; +} + +static int tas2557_codec_probe(struct snd_soc_codec *pCodec) +{ + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + return 0; +} + +static int tas2557_codec_remove(struct snd_soc_codec *pCodec) +{ + return 0; +} +static int tas2557_mute_ctrl_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&pTAS2557->codec_lock); + + pValue->value.integer.value[0] = pTAS2557->mbMute; + dev_dbg(pTAS2557->dev, "tas2557_mute_ctrl_get = %d\n", + pTAS2557->mbMute); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_mute_ctrl_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + int mbMute = pValue->value.integer.value[0]; + + mutex_lock(&pTAS2557->codec_lock); + + dev_dbg(pTAS2557->dev, "tas2557_mute_ctrl_put = %d\n", mbMute); + + tas2557_permanent_mute(pTAS2557, mbMute); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_power_ctrl_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&pTAS2557->codec_lock); + + pValue->value.integer.value[0] = pTAS2557->mbPowerUp; + dev_dbg(pTAS2557->dev, "tas2557_power_ctrl_get = %d\n", + pTAS2557->mbPowerUp); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_power_ctrl_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + int nPowerOn = pValue->value.integer.value[0]; + + mutex_lock(&pTAS2557->codec_lock); + + dev_dbg(pTAS2557->dev, "tas2557_power_ctrl_put = %d\n", nPowerOn); + tas2557_enable(pTAS2557, (nPowerOn != 0)); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int vendor_id_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = VENDOR_ID_NONE; + + if (pTAS2557->spk_id_gpio_p) + ucontrol->value.integer.value[0] = + spk_id_get(pTAS2557->spk_id_gpio_p); + + return 0; +} + +static int pa_version_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = 0; + + if (pTAS2557->mnPGID == TAS2557_PG_VERSION_1P0) + ucontrol->value.integer.value[0] = 1; + else if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P0) + ucontrol->value.integer.value[0] = 2; + else if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) + ucontrol->value.integer.value[0] = 3; + return 0; +} + +static int tas2557_fs_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + int nFS = 48000; + + mutex_lock(&pTAS2557->codec_lock); + + if (pTAS2557->mpFirmware->mnConfigurations) + nFS = pTAS2557->mpFirmware + ->mpConfigurations[pTAS2557->mnCurrentConfiguration] + .mnSamplingRate; + pValue->value.integer.value[0] = nFS; + dev_dbg(pTAS2557->dev, "tas2557_fs_get = %d\n", nFS); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_fs_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + int ret = 0; + int nFS = pValue->value.integer.value[0]; + + mutex_lock(&pTAS2557->codec_lock); + + dev_info(pTAS2557->dev, "tas2557_fs_put = %d\n", nFS); + ret = tas2557_set_sampling_rate(pTAS2557, nFS); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static int tas2557_Cali_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + bool ret = 0; + int prm_r0 = 0; + + mutex_lock(&pTAS2557->codec_lock); + + ret = tas2557_get_Cali_prm_r0(pTAS2557, &prm_r0); + if (ret) + pValue->value.integer.value[0] = prm_r0; + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_program_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&pTAS2557->codec_lock); + + pValue->value.integer.value[0] = pTAS2557->mnCurrentProgram; + dev_dbg(pTAS2557->dev, "tas2557_program_get = %d\n", + pTAS2557->mnCurrentProgram); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_program_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + unsigned int nProgram = pValue->value.integer.value[0]; + int ret = 0, nConfiguration = -1; + + mutex_lock(&pTAS2557->codec_lock); + + if (nProgram == pTAS2557->mnCurrentProgram) + nConfiguration = pTAS2557->mnCurrentConfiguration; + ret = tas2557_set_program(pTAS2557, nProgram, nConfiguration); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static int tas2557_configuration_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&pTAS2557->codec_lock); + + pValue->value.integer.value[0] = pTAS2557->mnCurrentConfiguration; + dev_dbg(pTAS2557->dev, "tas2557_configuration_get = %d\n", + pTAS2557->mnCurrentConfiguration); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_configuration_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + unsigned int nConfiguration = pValue->value.integer.value[0]; + int ret = 0; + + mutex_lock(&pTAS2557->codec_lock); + + dev_info(pTAS2557->dev, "%s = %d\n", __func__, nConfiguration); + ret = tas2557_set_config(pTAS2557, nConfiguration); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static int tas2557_calibration_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&pTAS2557->codec_lock); + + pValue->value.integer.value[0] = pTAS2557->mnCurrentCalibration; + dev_info(pTAS2557->dev, "tas2557_calibration_get = %d\n", + pTAS2557->mnCurrentCalibration); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_calibration_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + unsigned int nCalibration = pValue->value.integer.value[0]; + int ret = 0; + + mutex_lock(&pTAS2557->codec_lock); + + ret = tas2557_set_calibration(pTAS2557, nCalibration); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static const char *const vendor_id_text[] = { "None", "AAC", "SSI", "GOER", + "Unknown" }; +static const struct soc_enum vendor_id[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(vendor_id_text), vendor_id_text), +}; + +static const char *const pa_version_text[] = { "Unknown", "tas2557_v1.0", + "tas2557_v2.0", "tas2557_v2.1" }; +static const struct soc_enum pa_version[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(pa_version_text), pa_version_text), +}; + +static const struct snd_kcontrol_new tas2557_snd_controls[] = { + SOC_SINGLE_EXT("PowerCtrl", SND_SOC_NOPM, 0, 0x0001, 0, + tas2557_power_ctrl_get, tas2557_power_ctrl_put), + SOC_SINGLE_EXT("Program", SND_SOC_NOPM, 0, 0x00FF, 0, + tas2557_program_get, tas2557_program_put), + SOC_SINGLE_EXT("Configuration", SND_SOC_NOPM, 0, 0x00FF, 0, + tas2557_configuration_get, tas2557_configuration_put), + SOC_SINGLE_EXT("FS", SND_SOC_NOPM, 8000, 48000, 0, tas2557_fs_get, + tas2557_fs_put), + SOC_SINGLE_EXT("Get Cali_Re", SND_SOC_NOPM, 0, 0x7f000000, 0, + tas2557_Cali_get, NULL), + SOC_SINGLE_EXT("Calibration", SND_SOC_NOPM, 0, 0x00FF, 0, + tas2557_calibration_get, tas2557_calibration_put), + SOC_ENUM_EXT("SPK ID", vendor_id, vendor_id_get, NULL), + SOC_ENUM_EXT("SmartPA Version", pa_version, pa_version_get, NULL), + SOC_SINGLE_EXT("SmartPA Mute", SND_SOC_NOPM, 0, 0x0001, 0, + tas2557_mute_ctrl_get, tas2557_mute_ctrl_put), + +}; + +static struct snd_soc_codec_driver soc_codec_driver_tas2557 = { + .probe = tas2557_codec_probe, + .remove = tas2557_codec_remove, + .read = tas2557_codec_read, + .write = tas2557_codec_write, + .suspend = tas2557_codec_suspend, + .resume = tas2557_codec_resume, + .set_bias_level = tas2557_set_bias_level, + .idle_bias_off = true, + .component_driver = { + .controls = tas2557_snd_controls, + .num_controls = ARRAY_SIZE(tas2557_snd_controls), + .dapm_widgets = tas2557_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tas2557_dapm_widgets), + .dapm_routes = tas2557_audio_map, + .num_dapm_routes = ARRAY_SIZE(tas2557_audio_map), + }, +}; + +static struct snd_soc_dai_ops tas2557_dai_ops = { + .startup = tas2557_startup, + .shutdown = tas2557_shutdown, + .digital_mute = tas2557_mute, + .hw_params = tas2557_hw_params, + .prepare = tas2557_prepare, + .set_sysclk = tas2557_set_dai_sysclk, + .set_fmt = tas2557_set_dai_fmt, +}; + +#define TAS2557_FORMATS \ + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) +static struct snd_soc_dai_driver tas2557_dai_driver[] = { + { + .name = "tas2557 ASI1", + .id = 0, + .playback = { + .stream_name = "ASI1 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = TAS2557_FORMATS, + }, + .ops = &tas2557_dai_ops, + .symmetric_rates = 1, + }, + { + .name = "tas2557 ASI2", + .id = 1, + .playback = { + .stream_name = "ASI2 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = TAS2557_FORMATS, + }, + .ops = &tas2557_dai_ops, + .symmetric_rates = 1, + }, + { + .name = "tas2557 ASIM", + .id = 2, + .playback = { + .stream_name = "ASIM Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = TAS2557_FORMATS, + }, + .ops = &tas2557_dai_ops, + .symmetric_rates = 1, + }, +}; + +int tas2557_register_codec(struct tas2557_priv *pTAS2557) +{ + int nResult = 0; + + dev_info(pTAS2557->dev, "%s, enter\n", __func__); + nResult = + snd_soc_register_codec(pTAS2557->dev, &soc_codec_driver_tas2557, + tas2557_dai_driver, + ARRAY_SIZE(tas2557_dai_driver)); + return nResult; +} + +int tas2557_deregister_codec(struct tas2557_priv *pTAS2557) +{ + snd_soc_unregister_codec(pTAS2557->dev); + return 0; +} + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("TAS2557 ALSA SOC Smart Amplifier driver"); +MODULE_LICENSE("GPL v2"); +#endif diff --git a/techpack/audio/asoc/codecs/tas2557/tas2557-codec.h b/techpack/audio/asoc/codecs/tas2557/tas2557-codec.h new file mode 100755 index 000000000000..20babdde5025 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas2557/tas2557-codec.h @@ -0,0 +1,31 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** Copyright (C) 2019 XiaoMi, Inc. +** +** 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; version 2. +** +** 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. +** +** File: +** tas2557-codec.h +** +** Description: +** header file for tas2557-codec.c +** +** ============================================================================= +*/ + +#ifndef _TAS2557_CODEC_H +#define _TAS2557_CODEC_H + +#include "tas2557.h" + +int tas2557_register_codec(struct tas2557_priv *pTAS2557); +int tas2557_deregister_codec(struct tas2557_priv *pTAS2557); + +#endif /* _TAS2557_CODEC_H */ diff --git a/techpack/audio/asoc/codecs/tas2557/tas2557-core.c b/techpack/audio/asoc/codecs/tas2557/tas2557-core.c new file mode 100644 index 000000000000..45f6e9b3264e --- /dev/null +++ b/techpack/audio/asoc/codecs/tas2557/tas2557-core.c @@ -0,0 +1,2397 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** Copyright (C) 2019 XiaoMi, Inc. +** +** 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; version 2. +** +** 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. +** +** File: +** tas2557-core.c +** +** Description: +** TAS2557 common functions for Android Linux +** +** ============================================================================= +*/ + +#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tas2557.h" +#include "tas2557-core.h" + +#define PPC_DRIVER_CRCCHK 0x00000200 +#define PPC_DRIVER_CONFDEV 0x00000300 +#define PPC_DRIVER_MTPLLSRC 0x00000400 +#define PPC_DRIVER_CFGDEV_NONCRC 0x00000101 + +#define TAS2557_CAL_NAME "/mnt/vendor/persist/audio/tas2557_cal.bin" +#define RESTART_MAX 3 + +static int tas2557_load_calibration(struct tas2557_priv *pTAS2557, + char *pFileName); +static int tas2557_load_data(struct tas2557_priv *pTAS2557, struct TData *pData, + unsigned int nType); +static void tas2557_clear_firmware(struct TFirmware *pFirmware); +static int tas2557_load_block(struct tas2557_priv *pTAS2557, + struct TBlock *pBlock); +static int tas2557_load_configuration(struct tas2557_priv *pTAS2557, + unsigned int nConfiguration, + bool bLoadSame); + +#define TAS2557_UDELAY 0xFFFFFFFE +#define TAS2557_MDELAY 0xFFFFFFFD + +#define TAS2557_BLOCK_PLL 0x00 +#define TAS2557_BLOCK_PGM_ALL 0x0d +#define TAS2557_BLOCK_PGM_DEV_A 0x01 +#define TAS2557_BLOCK_PGM_DEV_B 0x08 +#define TAS2557_BLOCK_CFG_COEFF_DEV_A 0x03 +#define TAS2557_BLOCK_CFG_COEFF_DEV_B 0x0a +#define TAS2557_BLOCK_CFG_PRE_DEV_A 0x04 +#define TAS2557_BLOCK_CFG_PRE_DEV_B 0x0b +#define TAS2557_BLOCK_CFG_POST 0x05 +#define TAS2557_BLOCK_CFG_POST_POWER 0x06 + +static unsigned int p_tas2557_default_data[] = { + TAS2557_SAR_ADC2_REG, + 0x05, /* enable SAR ADC */ + TAS2557_CLK_ERR_CTRL2, + 0x21, /*clk1:clock hysteresis, 0.34ms; clock halt, 22ms*/ + TAS2557_CLK_ERR_CTRL3, + 0x21, /*clk2: rampDown 15dB/us, clock hysteresis, 10.66us; clock halt, 22ms */ + TAS2557_SAFE_GUARD_REG, + TAS2557_SAFE_GUARD_PATTERN, /* safe guard */ + 0xFFFFFFFF, + 0xFFFFFFFF +}; + +static unsigned int p_tas2557_irq_config[] = { + TAS2557_CLK_HALT_REG, + 0x71, /* enable clk halt detect2 interrupt */ + TAS2557_INT_GEN1_REG, + 0x11, /* enable spk OC and OV */ + TAS2557_INT_GEN2_REG, + 0x11, /* enable clk err1 and die OT */ + TAS2557_INT_GEN3_REG, + 0x11, /* enable clk err2 and brownout */ + TAS2557_INT_GEN4_REG, + 0x01, /* disable SAR, enable clk halt */ + TAS2557_GPIO4_PIN_REG, + 0x07, /* set GPIO4 as int1, default */ + TAS2557_INT_MODE_REG, + 0x80, /* active high until INT_STICKY_1 and INT_STICKY_2 are read to be cleared. */ + 0xFFFFFFFF, + 0xFFFFFFFF +}; + +static unsigned int p_tas2557_startup_data[] = { + TAS2557_GPI_PIN_REG, + 0x15, /* enable DIN, MCLK, CCI */ + TAS2557_GPIO1_PIN_REG, + 0x01, /* enable BCLK */ + TAS2557_GPIO2_PIN_REG, + 0x01, /* enable WCLK */ + TAS2557_POWER_CTRL2_REG, + 0xA0, /* Class-D, Boost power up */ + TAS2557_POWER_CTRL2_REG, + 0xA3, /* Class-D, Boost, IV sense power up */ + TAS2557_POWER_CTRL1_REG, + 0xF8, /* PLL, DSP, clock dividers power up */ + TAS2557_UDELAY, + 2000, /* delay */ + TAS2557_CLK_ERR_CTRL, + 0x2b, /* enable clock error detection */ + 0xFFFFFFFF, + 0xFFFFFFFF +}; + +static unsigned int p_tas2557_unmute_data[] = { TAS2557_MUTE_REG, + 0x00, /* unmute */ + TAS2557_SOFT_MUTE_REG, + 0x00, /* soft unmute */ + 0xFFFFFFFF, + 0xFFFFFFFF }; + +static unsigned int p_tas2557_shutdown_data[] = { + TAS2557_CLK_ERR_CTRL, + 0x00, /* disable clock error detection */ + TAS2557_SOFT_MUTE_REG, + 0x01, /* soft mute */ + TAS2557_UDELAY, + 10000, /* delay 10ms */ + TAS2557_MUTE_REG, + 0x03, /* mute */ + TAS2557_POWER_CTRL1_REG, + 0x60, /* DSP power down */ + TAS2557_UDELAY, + 2000, /* delay 2ms */ + TAS2557_POWER_CTRL2_REG, + 0x00, /* Class-D, Boost power down */ + TAS2557_POWER_CTRL1_REG, + 0x00, /* all power down */ + TAS2557_GPIO1_PIN_REG, + 0x00, /* disable BCLK */ + TAS2557_GPIO2_PIN_REG, + 0x00, /* disable WCLK */ + TAS2557_GPI_PIN_REG, + 0x00, /* disable DIN, MCLK, CCI */ + 0xFFFFFFFF, + 0xFFFFFFFF +}; + +static int tas2557_dev_load_data(struct tas2557_priv *pTAS2557, + unsigned int *pData) +{ + int ret = 0; + unsigned int n = 0; + unsigned int nRegister; + unsigned int nData; + + do { + nRegister = pData[n * 2]; + nData = pData[n * 2 + 1]; + if (nRegister == TAS2557_UDELAY) + udelay(nData); + else if (nRegister != 0xFFFFFFFF) { + ret = pTAS2557->write(pTAS2557, nRegister, nData); + if (ret < 0) + break; + } + n++; + } while (nRegister != 0xFFFFFFFF); + return ret; +} + +int tas2557_configIRQ(struct tas2557_priv *pTAS2557) +{ + return tas2557_dev_load_data(pTAS2557, p_tas2557_irq_config); +} + +int tas2557_set_bit_rate(struct tas2557_priv *pTAS2557, unsigned int nBitRate) +{ + int ret = 0, n = -1; + + dev_dbg(pTAS2557->dev, "tas2557_set_bit_rate: nBitRate = %d\n", + nBitRate); + + switch (nBitRate) { + case 16: + n = 0; + break; + case 20: + n = 1; + break; + case 24: + n = 2; + break; + case 32: + n = 3; + break; + } + + if (n >= 0) + ret = pTAS2557->update_bits( + pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, 0x18, n << 3); + return ret; +} + +int tas2557_get_bit_rate(struct tas2557_priv *pTAS2557, unsigned char *pBitRate) +{ + int ret = 0; + unsigned int nValue = 0; + unsigned char bitRate; + + ret = pTAS2557->read(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, &nValue); + if (ret >= 0) { + bitRate = (nValue & 0x18) >> 3; + if (bitRate == 0) + bitRate = 16; + else if (bitRate == 1) + bitRate = 20; + else if (bitRate == 2) + bitRate = 24; + else if (bitRate == 3) + bitRate = 32; + *pBitRate = bitRate; + } + + return ret; +} + +int tas2557_get_DAC_gain(struct tas2557_priv *pTAS2557, unsigned char *pnGain) +{ + int ret = 0; + unsigned int nValue = 0; + + ret = pTAS2557->read(pTAS2557, TAS2557_SPK_CTRL_REG, &nValue); + if (ret >= 0) + *pnGain = ((nValue & TAS2557_DAC_GAIN_MASK) >> + TAS2557_DAC_GAIN_SHIFT); + + return ret; +} + +int tas2557_set_DAC_gain(struct tas2557_priv *pTAS2557, unsigned int nGain) +{ + int ret = 0; + + ret = pTAS2557->update_bits(pTAS2557, TAS2557_SPK_CTRL_REG, + TAS2557_DAC_GAIN_MASK, + (nGain << TAS2557_DAC_GAIN_SHIFT)); + return ret; +} + +/* +* die temperature calculation: +* DieTemp = readout / 2^23 +*/ +int tas2557_get_die_temperature(struct tas2557_priv *pTAS2557, + int *pTemperature) +{ + int nResult = 0; + unsigned char nBuf[4]; + int temp; + + if (!pTAS2557->mpFirmware->mnConfigurations) { + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + goto end; + } + + if (!pTAS2557->mbPowerUp) { + dev_err(pTAS2557->dev, "%s, device not powered on\n", __func__); + goto end; + } + + nResult = pTAS2557->bulk_read(pTAS2557, TAS2557_DIE_TEMP_REG, nBuf, 4); + if (nResult >= 0) { + temp = ((int)nBuf[0] << 24) | ((int)nBuf[1] << 16) | + ((int)nBuf[2] << 8) | nBuf[3]; + *pTemperature = temp; + } + +end: + + return nResult; +} + +int tas2557_load_platdata(struct tas2557_priv *pTAS2557) +{ + int nResult = 0; + + if (gpio_is_valid(pTAS2557->mnGpioINT)) { + nResult = tas2557_configIRQ(pTAS2557); + if (nResult < 0) + goto end; + } + + nResult = tas2557_set_bit_rate(pTAS2557, pTAS2557->mnI2SBits); + +end: + + return nResult; +} + +int tas2557_load_default(struct tas2557_priv *pTAS2557) +{ + int nResult = 0; + + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_default_data); + if (nResult < 0) + goto end; + + nResult = tas2557_load_platdata(pTAS2557); + if (nResult < 0) + goto end; + + /* enable DOUT tri-state for extra BCLKs */ + nResult = pTAS2557->update_bits(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, + 0x01, 0x01); +end: + + return nResult; +} + +static void failsafe(struct tas2557_priv *pTAS2557) +{ + dev_err(pTAS2557->dev, "%s\n", __func__); + pTAS2557->mnErrCode |= ERROR_FAILSAFE; + if (hrtimer_active(&pTAS2557->mtimer)) + hrtimer_cancel(&pTAS2557->mtimer); + if (pTAS2557->mnRestart < RESTART_MAX) { + pTAS2557->mnRestart++; + msleep(100); + dev_err(pTAS2557->dev, "I2C COMM error, restart SmartAmp.\n"); + schedule_delayed_work(&pTAS2557->irq_work, + msecs_to_jiffies(100)); + return; + } + pTAS2557->enableIRQ(pTAS2557, false); + tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); + pTAS2557->mbPowerUp = false; + pTAS2557->hw_reset(pTAS2557); + pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01); + udelay(1000); + pTAS2557->write(pTAS2557, TAS2557_SPK_CTRL_REG, 0x04); + if (pTAS2557->mpFirmware != NULL) + tas2557_clear_firmware(pTAS2557->mpFirmware); +} + +int tas2557_checkPLL(struct tas2557_priv *pTAS2557) +{ + int nResult = 0; + /* +* TO DO +*/ + + return nResult; +} + +/* +* tas2557_load_coefficient +*/ +static int tas2557_load_coefficient(struct tas2557_priv *pTAS2557, + int nPrevConfig, int nNewConfig, + bool bPowerOn) +{ + int nResult = 0; + struct TPLL *pPLL; + struct TProgram *pProgram; + struct TConfiguration *pPrevConfiguration; + struct TConfiguration *pNewConfiguration; + bool bRestorePower = false; + + if (!pTAS2557->mpFirmware->mnConfigurations) { + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + goto end; + } + + if (nNewConfig >= pTAS2557->mpFirmware->mnConfigurations) { + dev_err(pTAS2557->dev, + "%s, invalid configuration New=%d, total=%d\n", + __func__, nNewConfig, + pTAS2557->mpFirmware->mnConfigurations); + goto end; + } + + if (nPrevConfig < 0) + pPrevConfiguration = NULL; + else if (nPrevConfig == nNewConfig) { + dev_dbg(pTAS2557->dev, "%s, config [%d] already loaded\n", + __func__, nNewConfig); + goto end; + } else + pPrevConfiguration = + &(pTAS2557->mpFirmware->mpConfigurations[nPrevConfig]); + + pNewConfiguration = + &(pTAS2557->mpFirmware->mpConfigurations[nNewConfig]); + pTAS2557->mnCurrentConfiguration = nNewConfig; + if (pPrevConfiguration) { + if (pPrevConfiguration->mnPLL == pNewConfiguration->mnPLL) { + dev_dbg(pTAS2557->dev, "%s, PLL same\n", __func__); + goto prog_coefficient; + } + } + + pProgram = + &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); + if (bPowerOn) { + dev_dbg(pTAS2557->dev, "%s, power down to load new PLL\n", + __func__); + if (hrtimer_active(&pTAS2557->mtimer)) + hrtimer_cancel(&pTAS2557->mtimer); + + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) + pTAS2557->enableIRQ(pTAS2557, false); + + nResult = tas2557_dev_load_data(pTAS2557, + p_tas2557_shutdown_data); + if (nResult < 0) + goto end; + bRestorePower = true; + } + + /* load PLL */ + pPLL = &(pTAS2557->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]); + dev_dbg(pTAS2557->dev, "load PLL: %s block for Configuration %s\n", + pPLL->mpName, pNewConfiguration->mpName); + nResult = tas2557_load_block(pTAS2557, &(pPLL->mBlock)); + if (nResult < 0) + goto end; + pTAS2557->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate; + + dev_dbg(pTAS2557->dev, "load configuration %s conefficient pre block\n", + pNewConfiguration->mpName); + nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData), + TAS2557_BLOCK_CFG_PRE_DEV_A); + if (nResult < 0) + goto end; + +prog_coefficient: + dev_dbg(pTAS2557->dev, "load new configuration: %s, coeff block data\n", + pNewConfiguration->mpName); + nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData), + TAS2557_BLOCK_CFG_COEFF_DEV_A); + if (nResult < 0) + goto end; + + if (pTAS2557->mpCalFirmware->mnCalibrations) { + nResult = tas2557_set_calibration( + pTAS2557, pTAS2557->mnCurrentCalibration); + if (nResult < 0) + goto end; + } + + if (bRestorePower) { + pTAS2557->clearIRQ(pTAS2557); + dev_dbg(pTAS2557->dev, "device powered up, load startup\n"); + nResult = + tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data); + if (nResult < 0) + goto end; + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + nResult = tas2557_checkPLL(pTAS2557); + if (nResult < 0) { + nResult = tas2557_dev_load_data( + pTAS2557, p_tas2557_shutdown_data); + pTAS2557->mbPowerUp = false; + goto end; + } + } + dev_dbg(pTAS2557->dev, "device powered up, load unmute\n"); + nResult = + tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data); + if (nResult < 0) + goto end; + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + pTAS2557->enableIRQ(pTAS2557, true); + if (!hrtimer_active(&pTAS2557->mtimer)) { + pTAS2557->mnDieTvReadCounter = 0; + hrtimer_start( + &pTAS2557->mtimer, + ns_to_ktime( + (u64)LOW_TEMPERATURE_CHECK_PERIOD * + NSEC_PER_MSEC), + HRTIMER_MODE_REL); + } + } + } +end: + + pTAS2557->mnNewConfiguration = pTAS2557->mnCurrentConfiguration; + return nResult; +} + +int tas2557_permanent_mute(struct tas2557_priv *pTAS2557, bool bmute) +{ + int nResult = 0; + + nResult = tas2557_enable(pTAS2557, !bmute); + if (nResult) { + dev_dbg(pTAS2557->dev, "set mute = %d faild\n", bmute); + goto end; + } + + pTAS2557->mbMute = bmute; + + if (bmute) { //make sure codec is permanent mute + p_tas2557_unmute_data[1] = 0x03; + p_tas2557_unmute_data[3] = 0x01; + } else { + p_tas2557_unmute_data[1] = 0x00; + p_tas2557_unmute_data[3] = 0x00; + } + +end: + return nResult; +} +int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable) +{ + int nResult = 0; + unsigned int nValue; + const char *pFWName; + struct TProgram *pProgram; + + dev_dbg(pTAS2557->dev, "Enable: %d\n", bEnable); + + if ((pTAS2557->mpFirmware->mnPrograms == 0) || + (pTAS2557->mpFirmware->mnConfigurations == 0)) { + dev_err(pTAS2557->dev, + "%s, firmware not loaded, try to load again\n", + __func__); + /*Load firmware*/ + if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) { + dev_info(pTAS2557->dev, "PG2.1 Silicon found\n"); + pFWName = TAS2557_AAC_FW_NAME; + } else if (pTAS2557->mnPGID == TAS2557_PG_VERSION_1P0) { + dev_info(pTAS2557->dev, "PG1.0 Silicon found\n"); + pFWName = TAS2557_PG1P0_FW_NAME; + } else { + nResult = -ENOTSUPP; + dev_info(pTAS2557->dev, "unsupport Silicon 0x%x\n", + pTAS2557->mnPGID); + goto end; + } + if (pTAS2557->mnSpkType == VENDOR_ID_GOER) + pFWName = TAS2557_GOER_FW_NAME; + else if (pTAS2557->mnSpkType == VENDOR_ID_AAC) + pFWName = TAS2557_AAC_FW_NAME; + else + pFWName = TAS2557_DEFAULT_FW_NAME; + + nResult = request_firmware_nowait(THIS_MODULE, 1, pFWName, + pTAS2557->dev, GFP_KERNEL, + pTAS2557, tas2557_fw_ready); + if (nResult < 0) + goto end; + dev_err(pTAS2557->dev, "%s, firmware is loaded\n", __func__); + } + + /* check safe guard*/ + nResult = pTAS2557->read(pTAS2557, TAS2557_SAFE_GUARD_REG, &nValue); + if (nResult < 0) + goto end; + if ((nValue & 0xff) != TAS2557_SAFE_GUARD_PATTERN) { + dev_err(pTAS2557->dev, "ERROR safe guard failure!\n"); + nResult = -EPIPE; + pTAS2557->mnErrCode = ERROR_SAFE_GUARD; + pTAS2557->mbPowerUp = true; + goto end; + } + + pProgram = + &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); + if (bEnable) { + if (!pTAS2557->mbPowerUp) { + if (!pTAS2557->mbCalibrationLoaded) { + if (tas2557_set_calibration(pTAS2557, 0xFF) < 0) + dev_err(pTAS2557->dev, + "calibration data load fail!\n"); + else + pTAS2557->mbCalibrationLoaded = true; + } + if (pTAS2557->mbLoadConfigurationPrePowerUp) { + dev_dbg(pTAS2557->dev, + "load coefficient before power\n"); + pTAS2557->mbLoadConfigurationPrePowerUp = false; + nResult = tas2557_load_coefficient( + pTAS2557, + pTAS2557->mnCurrentConfiguration, + pTAS2557->mnNewConfiguration, false); + if (nResult < 0) + goto end; + } + + pTAS2557->clearIRQ(pTAS2557); + /* power on device */ + dev_dbg(pTAS2557->dev, + "Enable: load startup sequence\n"); + nResult = tas2557_dev_load_data(pTAS2557, + p_tas2557_startup_data); + if (nResult < 0) + goto end; + + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + nResult = tas2557_checkPLL(pTAS2557); + if (nResult < 0) { + nResult = tas2557_dev_load_data( + pTAS2557, + p_tas2557_shutdown_data); + goto end; + } + } + dev_dbg(pTAS2557->dev, + "Enable: load unmute sequence\n"); + nResult = tas2557_dev_load_data(pTAS2557, + p_tas2557_unmute_data); + if (nResult < 0) + goto end; + + pTAS2557->mbPowerUp = true; + + nResult = + tas2557_get_die_temperature(pTAS2557, &nValue); + if ((nValue == 0x80000000) || (nResult < 0)) { + dev_err(pTAS2557->dev, + "%s, thermal sensor is wrong, mute output, mbPower: %d\n", + __func__, pTAS2557->mbPowerUp); + nResult = tas2557_dev_load_data( + pTAS2557, p_tas2557_shutdown_data); + pTAS2557->mbPowerUp = false; + goto end; + } + + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + /* turn on IRQ */ + pTAS2557->enableIRQ(pTAS2557, true); + if (!hrtimer_active(&pTAS2557->mtimer)) { + pTAS2557->mnDieTvReadCounter = 0; + hrtimer_start( + &pTAS2557->mtimer, + ns_to_ktime( + (u64)LOW_TEMPERATURE_CHECK_PERIOD * + NSEC_PER_MSEC), + HRTIMER_MODE_REL); + } + } + pTAS2557->mnRestart = 0; + } + } else { + if (pTAS2557->mbPowerUp) { + if (hrtimer_active(&pTAS2557->mtimer)) + hrtimer_cancel(&pTAS2557->mtimer); + + dev_dbg(pTAS2557->dev, + "Enable: load shutdown sequence\n"); + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + /* turn off IRQ */ + pTAS2557->enableIRQ(pTAS2557, false); + } + nResult = tas2557_dev_load_data( + pTAS2557, p_tas2557_shutdown_data); + if (nResult < 0) + goto end; + + pTAS2557->mbPowerUp = false; + pTAS2557->mnRestart = 0; + } + } + + nResult = 0; + +end: + if (nResult < 0) { + if (pTAS2557->mnErrCode & + (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | + ERROR_YRAM_CRCCHK | ERROR_SAFE_GUARD)) + failsafe(pTAS2557); + } + + return nResult; +} + +int tas2557_set_sampling_rate(struct tas2557_priv *pTAS2557, + unsigned int nSamplingRate) +{ + int nResult = 0; + struct TConfiguration *pConfiguration; + unsigned int nConfiguration; + + dev_dbg(pTAS2557->dev, + "tas2557_setup_clocks: nSamplingRate = %d [Hz]\n", + nSamplingRate); + + if ((!pTAS2557->mpFirmware->mpPrograms) || + (!pTAS2557->mpFirmware->mpConfigurations)) { + dev_err(pTAS2557->dev, "Firmware not loaded\n"); + nResult = -EINVAL; + goto end; + } + + pConfiguration = + &(pTAS2557->mpFirmware + ->mpConfigurations[pTAS2557->mnCurrentConfiguration]); + if (pConfiguration->mnSamplingRate == nSamplingRate) { + dev_info( + pTAS2557->dev, + "Sampling rate for current configuration matches: %d\n", + nSamplingRate); + nResult = 0; + goto end; + } + + for (nConfiguration = 0; + nConfiguration < pTAS2557->mpFirmware->mnConfigurations; + nConfiguration++) { + pConfiguration = &( + pTAS2557->mpFirmware->mpConfigurations[nConfiguration]); + if ((pConfiguration->mnSamplingRate == nSamplingRate) && + (pConfiguration->mnProgram == pTAS2557->mnCurrentProgram)) { + dev_info( + pTAS2557->dev, + "Found configuration: %s, with compatible sampling rate %d\n", + pConfiguration->mpName, nSamplingRate); + nResult = tas2557_load_configuration( + pTAS2557, nConfiguration, false); + goto end; + } + } + + dev_err(pTAS2557->dev, + "Cannot find a configuration that supports sampling rate: %d\n", + nSamplingRate); + +end: + + return nResult; +} + +static void fw_print_header(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware) +{ + dev_info(pTAS2557->dev, "FW Size = %d", pFirmware->mnFWSize); + dev_info(pTAS2557->dev, "Checksum = 0x%04X", + pFirmware->mnChecksum); + dev_info(pTAS2557->dev, "PPC Version = 0x%04X", + pFirmware->mnPPCVersion); + dev_info(pTAS2557->dev, "FW Version = 0x%04X", + pFirmware->mnFWVersion); + dev_info(pTAS2557->dev, "Driver Version= 0x%04X", + pFirmware->mnDriverVersion); + dev_info(pTAS2557->dev, "Timestamp = %d", pFirmware->mnTimeStamp); + dev_info(pTAS2557->dev, "DDC Name = %s", pFirmware->mpDDCName); + dev_info(pTAS2557->dev, "Description = %s", pFirmware->mpDescription); +} + +inline unsigned int fw_convert_number(unsigned char *pData) +{ + return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24); +} + +static int fw_parse_header(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware, unsigned char *pData, + unsigned int nSize) +{ + unsigned char *pDataStart = pData; + unsigned int n; + unsigned char pMagicNumber[] = { 0x35, 0x35, 0x35, 0x32 }; + + if (nSize < 104) { + dev_err(pTAS2557->dev, "Firmware: Header too short"); + return -EINVAL; + } + + if (memcmp(pData, pMagicNumber, 4)) { + dev_err(pTAS2557->dev, "Firmware: Magic number doesn't match"); + return -EINVAL; + } + pData += 4; + + pFirmware->mnFWSize = fw_convert_number(pData); + pData += 4; + + pFirmware->mnChecksum = fw_convert_number(pData); + pData += 4; + + pFirmware->mnPPCVersion = fw_convert_number(pData); + pData += 4; + + pFirmware->mnFWVersion = fw_convert_number(pData); + pData += 4; + + pFirmware->mnDriverVersion = fw_convert_number(pData); + pData += 4; + + pFirmware->mnTimeStamp = fw_convert_number(pData); + pData += 4; + + memcpy(pFirmware->mpDDCName, pData, 64); + pData += 64; + + n = strlen(pData); + pFirmware->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL); + pData += n + 1; + if ((pData - pDataStart) >= nSize) { + dev_err(pTAS2557->dev, + "Firmware: Header too short after DDC description"); + return -EINVAL; + } + + pFirmware->mnDeviceFamily = fw_convert_number(pData); + pData += 4; + if (pFirmware->mnDeviceFamily != 0) { + dev_err(pTAS2557->dev, "deviceFamily %d, not TAS device", + pFirmware->mnDeviceFamily); + return -EINVAL; + } + + pFirmware->mnDevice = fw_convert_number(pData); + pData += 4; + + if (pFirmware->mnDevice != 2) { + dev_err(pTAS2557->dev, "device %d, not TAS2557 Dual Mono", + pFirmware->mnDevice); + return -EINVAL; + } + + fw_print_header(pTAS2557, pFirmware); + return pData - pDataStart; +} + +static int fw_parse_block_data(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware, + struct TBlock *pBlock, unsigned char *pData) +{ + unsigned char *pDataStart = pData; + unsigned int n; + + pBlock->mnType = fw_convert_number(pData); + pData += 4; + + if (pFirmware->mnDriverVersion >= PPC_DRIVER_CRCCHK) { + pBlock->mbPChkSumPresent = pData[0]; + pData++; + + pBlock->mnPChkSum = pData[0]; + pData++; + + pBlock->mbYChkSumPresent = pData[0]; + pData++; + + pBlock->mnYChkSum = pData[0]; + pData++; + } else { + pBlock->mbPChkSumPresent = 0; + pBlock->mbYChkSumPresent = 0; + } + + pBlock->mnCommands = fw_convert_number(pData); + pData += 4; + + n = pBlock->mnCommands * 4; + pBlock->mpData = kmemdup(pData, n, GFP_KERNEL); + pData += n; + return pData - pDataStart; +} + +static int fw_parse_data(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware, struct TData *pImageData, + unsigned char *pData) +{ + unsigned char *pDataStart = pData; + unsigned int nBlock; + unsigned int n; + + memcpy(pImageData->mpName, pData, 64); + pData += 64; + + n = strlen(pData); + pImageData->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL); + pData += n + 1; + + pImageData->mnBlocks = (pData[0] << 8) + pData[1]; + pData += 2; + + pImageData->mpBlocks = kmalloc( + sizeof(struct TBlock) * pImageData->mnBlocks, GFP_KERNEL); + + for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) { + n = fw_parse_block_data(pTAS2557, pFirmware, + &(pImageData->mpBlocks[nBlock]), pData); + pData += n; + } + return pData - pDataStart; +} + +static int fw_parse_pll_data(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware, unsigned char *pData) +{ + unsigned char *pDataStart = pData; + unsigned int n; + unsigned int nPLL; + struct TPLL *pPLL; + + pFirmware->mnPLLs = (pData[0] << 8) + pData[1]; + pData += 2; + + if (pFirmware->mnPLLs == 0) + goto end; + + pFirmware->mpPLLs = kmalloc_array(pFirmware->mnPLLs, + sizeof(struct TPLL), GFP_KERNEL); + for (nPLL = 0; nPLL < pFirmware->mnPLLs; nPLL++) { + pPLL = &(pFirmware->mpPLLs[nPLL]); + + memcpy(pPLL->mpName, pData, 64); + pData += 64; + + n = strlen(pData); + pPLL->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL); + pData += n + 1; + + n = fw_parse_block_data(pTAS2557, pFirmware, &(pPLL->mBlock), + pData); + pData += n; + } + +end: + return pData - pDataStart; +} + +static int fw_parse_program_data(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware, + unsigned char *pData) +{ + unsigned char *pDataStart = pData; + unsigned int n; + unsigned int nProgram; + struct TProgram *pProgram; + + pFirmware->mnPrograms = (pData[0] << 8) + pData[1]; + pData += 2; + + if (pFirmware->mnPrograms == 0) + goto end; + + pFirmware->mpPrograms = kmalloc( + sizeof(struct TProgram) * pFirmware->mnPrograms, GFP_KERNEL); + for (nProgram = 0; nProgram < pFirmware->mnPrograms; nProgram++) { + pProgram = &(pFirmware->mpPrograms[nProgram]); + memcpy(pProgram->mpName, pData, 64); + pData += 64; + + n = strlen(pData); + pProgram->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL); + pData += n + 1; + + pProgram->mnAppMode = pData[0]; + pData++; + + pProgram->mnBoost = (pData[0] << 8) + pData[1]; + pData += 2; + + n = fw_parse_data(pTAS2557, pFirmware, &(pProgram->mData), + pData); + pData += n; + } + +end: + + return pData - pDataStart; +} + +static int fw_parse_configuration_data(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware, + unsigned char *pData) +{ + unsigned char *pDataStart = pData; + unsigned int n; + unsigned int nConfiguration; + struct TConfiguration *pConfiguration; + + pFirmware->mnConfigurations = (pData[0] << 8) + pData[1]; + pData += 2; + + if (pFirmware->mnConfigurations == 0) + goto end; + + pFirmware->mpConfigurations = kmalloc( + sizeof(struct TConfiguration) * pFirmware->mnConfigurations, + GFP_KERNEL); + for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations; + nConfiguration++) { + pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]); + memcpy(pConfiguration->mpName, pData, 64); + pData += 64; + + n = strlen(pData); + pConfiguration->mpDescription = + kmemdup(pData, n + 1, GFP_KERNEL); + pData += n + 1; + + if ((pFirmware->mnDriverVersion >= PPC_DRIVER_CONFDEV) || + ((pFirmware->mnDriverVersion >= PPC_DRIVER_CFGDEV_NONCRC) && + (pFirmware->mnDriverVersion < PPC_DRIVER_CRCCHK))) { + pConfiguration->mnDevices = (pData[0] << 8) + pData[1]; + pData += 2; + } else + pConfiguration->mnDevices = 1; + + pConfiguration->mnProgram = pData[0]; + pData++; + + pConfiguration->mnPLL = pData[0]; + pData++; + + pConfiguration->mnSamplingRate = fw_convert_number(pData); + pData += 4; + + if (pFirmware->mnDriverVersion >= PPC_DRIVER_MTPLLSRC) { + pConfiguration->mnPLLSrc = pData[0]; + pData++; + + pConfiguration->mnPLLSrcRate = fw_convert_number(pData); + pData += 4; + } + + n = fw_parse_data(pTAS2557, pFirmware, &(pConfiguration->mData), + pData); + pData += n; + } + +end: + + return pData - pDataStart; +} + +int fw_parse_calibration_data(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware, unsigned char *pData) +{ + unsigned char *pDataStart = pData; + unsigned int n; + unsigned int nCalibration; + struct TCalibration *pCalibration; + + pFirmware->mnCalibrations = (pData[0] << 8) + pData[1]; + pData += 2; + + if (pFirmware->mnCalibrations == 0) + goto end; + + pFirmware->mpCalibrations = + kmalloc(sizeof(struct TCalibration) * pFirmware->mnCalibrations, + GFP_KERNEL); + for (nCalibration = 0; nCalibration < pFirmware->mnCalibrations; + nCalibration++) { + pCalibration = &(pFirmware->mpCalibrations[nCalibration]); + memcpy(pCalibration->mpName, pData, 64); + pData += 64; + + n = strlen(pData); + pCalibration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL); + pData += n + 1; + + pCalibration->mnProgram = pData[0]; + pData++; + + pCalibration->mnConfiguration = pData[0]; + pData++; + + n = fw_parse_data(pTAS2557, pFirmware, &(pCalibration->mData), + pData); + pData += n; + } + +end: + + return pData - pDataStart; +} + +static int fw_parse(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware, + unsigned char *pData, unsigned int nSize) +{ + int nPosition = 0; + + nPosition = fw_parse_header(pTAS2557, pFirmware, pData, nSize); + if (nPosition < 0) { + dev_err(pTAS2557->dev, "Firmware: Wrong Header"); + return -EINVAL; + } + + if (nPosition >= nSize) { + dev_err(pTAS2557->dev, "Firmware: Too short"); + return -EINVAL; + } + + pData += nPosition; + nSize -= nPosition; + nPosition = 0; + + nPosition = fw_parse_pll_data(pTAS2557, pFirmware, pData); + + pData += nPosition; + nSize -= nPosition; + nPosition = 0; + + nPosition = fw_parse_program_data(pTAS2557, pFirmware, pData); + + pData += nPosition; + nSize -= nPosition; + nPosition = 0; + + nPosition = fw_parse_configuration_data(pTAS2557, pFirmware, pData); + + pData += nPosition; + nSize -= nPosition; + nPosition = 0; + + if (nSize > 64) + nPosition = + fw_parse_calibration_data(pTAS2557, pFirmware, pData); + return 0; +} + +static const unsigned char crc8_lookup_table[CRC8_TABLE_SIZE] = { + 0x00, 0x4D, 0x9A, 0xD7, 0x79, 0x34, 0xE3, 0xAE, 0xF2, 0xBF, 0x68, 0x25, + 0x8B, 0xC6, 0x11, 0x5C, 0xA9, 0xE4, 0x33, 0x7E, 0xD0, 0x9D, 0x4A, 0x07, + 0x5B, 0x16, 0xC1, 0x8C, 0x22, 0x6F, 0xB8, 0xF5, 0x1F, 0x52, 0x85, 0xC8, + 0x66, 0x2B, 0xFC, 0xB1, 0xED, 0xA0, 0x77, 0x3A, 0x94, 0xD9, 0x0E, 0x43, + 0xB6, 0xFB, 0x2C, 0x61, 0xCF, 0x82, 0x55, 0x18, 0x44, 0x09, 0xDE, 0x93, + 0x3D, 0x70, 0xA7, 0xEA, 0x3E, 0x73, 0xA4, 0xE9, 0x47, 0x0A, 0xDD, 0x90, + 0xCC, 0x81, 0x56, 0x1B, 0xB5, 0xF8, 0x2F, 0x62, 0x97, 0xDA, 0x0D, 0x40, + 0xEE, 0xA3, 0x74, 0x39, 0x65, 0x28, 0xFF, 0xB2, 0x1C, 0x51, 0x86, 0xCB, + 0x21, 0x6C, 0xBB, 0xF6, 0x58, 0x15, 0xC2, 0x8F, 0xD3, 0x9E, 0x49, 0x04, + 0xAA, 0xE7, 0x30, 0x7D, 0x88, 0xC5, 0x12, 0x5F, 0xF1, 0xBC, 0x6B, 0x26, + 0x7A, 0x37, 0xE0, 0xAD, 0x03, 0x4E, 0x99, 0xD4, 0x7C, 0x31, 0xE6, 0xAB, + 0x05, 0x48, 0x9F, 0xD2, 0x8E, 0xC3, 0x14, 0x59, 0xF7, 0xBA, 0x6D, 0x20, + 0xD5, 0x98, 0x4F, 0x02, 0xAC, 0xE1, 0x36, 0x7B, 0x27, 0x6A, 0xBD, 0xF0, + 0x5E, 0x13, 0xC4, 0x89, 0x63, 0x2E, 0xF9, 0xB4, 0x1A, 0x57, 0x80, 0xCD, + 0x91, 0xDC, 0x0B, 0x46, 0xE8, 0xA5, 0x72, 0x3F, 0xCA, 0x87, 0x50, 0x1D, + 0xB3, 0xFE, 0x29, 0x64, 0x38, 0x75, 0xA2, 0xEF, 0x41, 0x0C, 0xDB, 0x96, + 0x42, 0x0F, 0xD8, 0x95, 0x3B, 0x76, 0xA1, 0xEC, 0xB0, 0xFD, 0x2A, 0x67, + 0xC9, 0x84, 0x53, 0x1E, 0xEB, 0xA6, 0x71, 0x3C, 0x92, 0xDF, 0x08, 0x45, + 0x19, 0x54, 0x83, 0xCE, 0x60, 0x2D, 0xFA, 0xB7, 0x5D, 0x10, 0xC7, 0x8A, + 0x24, 0x69, 0xBE, 0xF3, 0xAF, 0xE2, 0x35, 0x78, 0xD6, 0x9B, 0x4C, 0x01, + 0xF4, 0xB9, 0x6E, 0x23, 0x8D, 0xC0, 0x17, 0x5A, 0x06, 0x4B, 0x9C, 0xD1, + 0x7F, 0x32, 0xE5, 0xA8 +}; + +static int isInPageYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData, + unsigned char nBook, unsigned char nPage, + unsigned char nReg, unsigned char len) +{ + int nResult = 0; + + if (nBook == TAS2557_YRAM_BOOK1) { + if (nPage == TAS2557_YRAM1_PAGE) { + if (nReg >= TAS2557_YRAM1_START_REG) { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = len; + nResult = 1; + } else if ((nReg + len) > TAS2557_YRAM1_START_REG) { + pCRCData->mnOffset = TAS2557_YRAM1_START_REG; + pCRCData->mnLen = + len - (TAS2557_YRAM1_START_REG - nReg); + nResult = 1; + } else + nResult = 0; + } else if (nPage == TAS2557_YRAM3_PAGE) { + if (nReg > TAS2557_YRAM3_END_REG) { + nResult = 0; + } else if (nReg >= TAS2557_YRAM3_START_REG) { + if ((nReg + len) > TAS2557_YRAM3_END_REG) { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = + TAS2557_YRAM3_END_REG - nReg + + 1; + nResult = 1; + } else { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = len; + nResult = 1; + } + } else { + if ((nReg + (len - 1)) < + TAS2557_YRAM3_START_REG) + nResult = 0; + else { + pCRCData->mnOffset = + TAS2557_YRAM3_START_REG; + pCRCData->mnLen = + len - (TAS2557_YRAM3_START_REG - + nReg); + nResult = 1; + } + } + } + } else if (nBook == TAS2557_YRAM_BOOK2) { + if (nPage == TAS2557_YRAM5_PAGE) { + if (nReg > TAS2557_YRAM5_END_REG) { + nResult = 0; + } else if (nReg >= TAS2557_YRAM5_START_REG) { + if ((nReg + len) > TAS2557_YRAM5_END_REG) { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = + TAS2557_YRAM5_END_REG - nReg + + 1; + nResult = 1; + } else { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = len; + nResult = 1; + } + } else { + if ((nReg + (len - 1)) < + TAS2557_YRAM5_START_REG) + nResult = 0; + else { + pCRCData->mnOffset = + TAS2557_YRAM5_START_REG; + pCRCData->mnLen = + len - (TAS2557_YRAM5_START_REG - + nReg); + nResult = 1; + } + } + } + } else + nResult = 0; + + return nResult; +} + +static int isInBlockYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData, + unsigned char nBook, unsigned char nPage, + unsigned char nReg, unsigned char len) +{ + int nResult; + + if (nBook == TAS2557_YRAM_BOOK1) { + if (nPage < TAS2557_YRAM2_START_PAGE) + nResult = 0; + else if (nPage <= TAS2557_YRAM2_END_PAGE) { + if (nReg > TAS2557_YRAM2_END_REG) + nResult = 0; + else if (nReg >= TAS2557_YRAM2_START_REG) { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = len; + nResult = 1; + } else { + if ((nReg + (len - 1)) < + TAS2557_YRAM2_START_REG) + nResult = 0; + else { + pCRCData->mnOffset = + TAS2557_YRAM2_START_REG; + pCRCData->mnLen = + nReg + len - + TAS2557_YRAM2_START_REG; + nResult = 1; + } + } + } else + nResult = 0; + } else if (nBook == TAS2557_YRAM_BOOK2) { + if (nPage < TAS2557_YRAM4_START_PAGE) + nResult = 0; + else if (nPage <= TAS2557_YRAM4_END_PAGE) { + if (nReg > TAS2557_YRAM2_END_REG) + nResult = 0; + else if (nReg >= TAS2557_YRAM2_START_REG) { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = len; + nResult = 1; + } else { + if ((nReg + (len - 1)) < + TAS2557_YRAM2_START_REG) + nResult = 0; + else { + pCRCData->mnOffset = + TAS2557_YRAM2_START_REG; + pCRCData->mnLen = + nReg + len - + TAS2557_YRAM2_START_REG; + nResult = 1; + } + } + } else + nResult = 0; + } else + nResult = 0; + + return nResult; +} + +static int isYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData, + unsigned char nBook, unsigned char nPage, unsigned char nReg, + unsigned char len) +{ + int nResult; + + nResult = isInPageYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, len); + + if (nResult == 0) + nResult = isInBlockYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, + len); + + return nResult; +} + +/* + * crc8 - calculate a crc8 over the given input data. + * + * table: crc table used for calculation. + * pdata: pointer to data buffer. + * nbytes: number of bytes in data buffer. + * crc: previous returned crc8 value. + */ +static u8 ti_crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, + u8 crc) +{ + /* loop over the buffer data */ + while (nbytes-- > 0) + crc = table[(crc ^ *pdata++) & 0xff]; + + return crc; +} + +static int doSingleRegCheckSum(struct tas2557_priv *pTAS2557, + unsigned char nBook, unsigned char nPage, + unsigned char nReg, unsigned char nValue) +{ + int nResult = 0; + struct TYCRC sCRCData; + unsigned int nData1 = 0; + + if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG)) && + (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG)) && + (nReg >= TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG)) && + (nReg <= (TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG) + 4))) { + /* DSP swap command, pass */ + nResult = 0; + goto end; + } + + nResult = isYRAM(pTAS2557, &sCRCData, nBook, nPage, nReg, 1); + if (nResult == 1) { + nResult = pTAS2557->read( + pTAS2557, TAS2557_REG(nBook, nPage, nReg), &nData1); + if (nResult < 0) + goto end; + + if (nData1 != nValue) { + dev_err(pTAS2557->dev, + "error2 (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n", + __LINE__, nBook, nPage, nReg, nValue, nData1); + nResult = -EAGAIN; + goto end; + } + + nResult = ti_crc8(crc8_lookup_table, &nValue, 1, 0); + } + +end: + + return nResult; +} + +static int doMultiRegCheckSum(struct tas2557_priv *pTAS2557, + unsigned char nBook, unsigned char nPage, + unsigned char nReg, unsigned int len) +{ + int nResult = 0, i; + unsigned char nCRCChkSum = 0; + unsigned char nBuf1[128]; + struct TYCRC TCRCData; + + if ((nReg + len - 1) > 127) { + nResult = -EINVAL; + dev_err(pTAS2557->dev, "firmware error\n"); + goto end; + } + + if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG)) && + (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG)) && + (nReg == TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG)) && + (len == 4)) { + /* DSP swap command, pass */ + nResult = 0; + goto end; + } + + nResult = isYRAM(pTAS2557, &TCRCData, nBook, nPage, nReg, len); + if (nResult == 1) { + if (len == 1) { + dev_err(pTAS2557->dev, "firmware error\n"); + nResult = -EINVAL; + goto end; + } else { + nResult = pTAS2557->bulk_read( + pTAS2557, + TAS2557_REG(nBook, nPage, TCRCData.mnOffset), + nBuf1, TCRCData.mnLen); + if (nResult < 0) + goto end; + + for (i = 0; i < TCRCData.mnLen; i++) { + if ((nBook == + TAS2557_BOOK_ID( + TAS2557_SA_COEFF_SWAP_REG)) && + (nPage == + TAS2557_PAGE_ID( + TAS2557_SA_COEFF_SWAP_REG)) && + ((i + TCRCData.mnOffset) >= + TAS2557_PAGE_REG( + TAS2557_SA_COEFF_SWAP_REG)) && + ((i + TCRCData.mnOffset) <= + (TAS2557_PAGE_REG( + TAS2557_SA_COEFF_SWAP_REG) + + 4))) { + /* DSP swap command, bypass */ + continue; + } else + nCRCChkSum += ti_crc8(crc8_lookup_table, + &nBuf1[i], 1, 0); + } + + nResult = nCRCChkSum; + } + } + +end: + + return nResult; +} + +static int tas2557_load_block(struct tas2557_priv *pTAS2557, + struct TBlock *pBlock) +{ + int nResult = 0; + unsigned int nCommand = 0; + unsigned char nBook; + unsigned char nPage; + unsigned char nOffset; + unsigned char nData; + unsigned int nLength; + unsigned int nSleep; + unsigned char nCRCChkSum = 0; + unsigned int nValue1; + int nRetry = 6; + unsigned char *pData = pBlock->mpData; + + dev_dbg(pTAS2557->dev, "TAS2557 load block: Type = %d, commands = %d\n", + pBlock->mnType, pBlock->mnCommands); +start: + if (pBlock->mbPChkSumPresent) { + nResult = pTAS2557->write(pTAS2557, TAS2557_CRC_RESET_REG, 1); + if (nResult < 0) + goto end; + } + + if (pBlock->mbYChkSumPresent) + nCRCChkSum = 0; + + nCommand = 0; + + while (nCommand < pBlock->mnCommands) { + pData = pBlock->mpData + nCommand * 4; + + nBook = pData[0]; + nPage = pData[1]; + nOffset = pData[2]; + nData = pData[3]; + + nCommand++; + + if (nOffset <= 0x7F) { + nResult = pTAS2557->write( + pTAS2557, TAS2557_REG(nBook, nPage, nOffset), + nData); + if (nResult < 0) + goto end; + if (pBlock->mbYChkSumPresent) { + nResult = doSingleRegCheckSum( + pTAS2557, nBook, nPage, nOffset, nData); + if (nResult < 0) + goto check; + nCRCChkSum += (unsigned char)nResult; + } + } else if (nOffset == 0x81) { + nSleep = (nBook << 8) + nPage; + msleep(nSleep); + } else if (nOffset == 0x85) { + pData += 4; + nLength = (nBook << 8) + nPage; + nBook = pData[0]; + nPage = pData[1]; + nOffset = pData[2]; + if (nLength > 1) { + nResult = pTAS2557->bulk_write( + pTAS2557, + TAS2557_REG(nBook, nPage, nOffset), + pData + 3, nLength); + if (nResult < 0) + goto end; + if (pBlock->mbYChkSumPresent) { + nResult = doMultiRegCheckSum( + pTAS2557, nBook, nPage, nOffset, + nLength); + if (nResult < 0) + goto check; + nCRCChkSum += (unsigned char)nResult; + } + } else { + nResult = pTAS2557->write( + pTAS2557, + TAS2557_REG(nBook, nPage, nOffset), + pData[3]); + if (nResult < 0) + goto end; + if (pBlock->mbYChkSumPresent) { + nResult = doSingleRegCheckSum( + pTAS2557, nBook, nPage, nOffset, + pData[3]); + if (nResult < 0) + goto check; + nCRCChkSum += (unsigned char)nResult; + } + } + + nCommand++; + + if (nLength >= 2) + nCommand += ((nLength - 2) / 4) + 1; + } + } + if (pBlock->mbPChkSumPresent) { + nResult = pTAS2557->read(pTAS2557, TAS2557_CRC_CHECKSUM_REG, + &nValue1); + if (nResult < 0) + goto end; + if ((nValue1 & 0xff) != pBlock->mnPChkSum) { + dev_err(pTAS2557->dev, + "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n", + pBlock->mnPChkSum, (nValue1 & 0xff)); + nResult = -EAGAIN; + pTAS2557->mnErrCode |= ERROR_PRAM_CRCCHK; + goto check; + } + + nResult = 0; + pTAS2557->mnErrCode &= ~ERROR_PRAM_CRCCHK; + dev_dbg(pTAS2557->dev, "Block[0x%x] PChkSum match\n", + pBlock->mnType); + } + + if (pBlock->mbYChkSumPresent) { + if (nCRCChkSum != pBlock->mnYChkSum) { + dev_err(pTAS2557->dev, + "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n", + pBlock->mnYChkSum, nCRCChkSum); + nResult = -EAGAIN; + pTAS2557->mnErrCode |= ERROR_YRAM_CRCCHK; + goto check; + } + pTAS2557->mnErrCode &= ~ERROR_YRAM_CRCCHK; + nResult = 0; + dev_dbg(pTAS2557->dev, "Block[0x%x] YChkSum match\n", + pBlock->mnType); + } + +check: + if (nResult == -EAGAIN) { + nRetry--; + if (nRetry > 0) + goto start; + } + +end: + if (nResult < 0) { + dev_err(pTAS2557->dev, "Block (%d) load error\n", + pBlock->mnType); + } + return nResult; +} + +static int tas2557_load_data(struct tas2557_priv *pTAS2557, struct TData *pData, + unsigned int nType) +{ + int nResult = 0; + unsigned int nBlock; + struct TBlock *pBlock; + + dev_dbg(pTAS2557->dev, + "TAS2557 load data: %s, Blocks = %d, Block Type = %d\n", + pData->mpName, pData->mnBlocks, nType); + + for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) { + pBlock = &(pData->mpBlocks[nBlock]); + if (pBlock->mnType == nType) { + nResult = tas2557_load_block(pTAS2557, pBlock); + if (nResult < 0) + break; + } + } + + return nResult; +} + +static int tas2557_load_configuration(struct tas2557_priv *pTAS2557, + unsigned int nConfiguration, + bool bLoadSame) +{ + int nResult = 0; + struct TConfiguration *pCurrentConfiguration = NULL; + struct TConfiguration *pNewConfiguration = NULL; + + dev_dbg(pTAS2557->dev, "%s: %d\n", __func__, nConfiguration); + + if ((!pTAS2557->mpFirmware->mpPrograms) || + (!pTAS2557->mpFirmware->mpConfigurations)) { + dev_err(pTAS2557->dev, "Firmware not loaded\n"); + nResult = 0; + goto end; + } + + if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) { + dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n", + nConfiguration); + nResult = 0; + goto end; + } + + if ((!pTAS2557->mbLoadConfigurationPrePowerUp) && + (nConfiguration == pTAS2557->mnCurrentConfiguration) && + (!bLoadSame)) { + dev_info(pTAS2557->dev, "Configuration %d is already loaded\n", + nConfiguration); + nResult = 0; + goto end; + } + + pCurrentConfiguration = + &(pTAS2557->mpFirmware + ->mpConfigurations[pTAS2557->mnCurrentConfiguration]); + pNewConfiguration = + &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]); + if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) { + dev_err(pTAS2557->dev, + "Configuration %d, %s doesn't share the same program as current %d\n", + nConfiguration, pNewConfiguration->mpName, + pCurrentConfiguration->mnProgram); + nResult = 0; + goto end; + } + + if (pNewConfiguration->mnPLL >= pTAS2557->mpFirmware->mnPLLs) { + dev_err(pTAS2557->dev, + "Configuration %d, %s doesn't have a valid PLL index %d\n", + nConfiguration, pNewConfiguration->mpName, + pNewConfiguration->mnPLL); + nResult = 0; + goto end; + } + + if (pTAS2557->mbPowerUp) { + pTAS2557->mbLoadConfigurationPrePowerUp = false; + nResult = tas2557_load_coefficient( + pTAS2557, pTAS2557->mnCurrentConfiguration, + nConfiguration, true); + } else { + dev_dbg(pTAS2557->dev, + "TAS2557 was powered down, will load coefficient when power up\n"); + pTAS2557->mbLoadConfigurationPrePowerUp = true; + pTAS2557->mnNewConfiguration = nConfiguration; + } + +end: + + if (nResult < 0) { + if (pTAS2557->mnErrCode & + (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | + ERROR_YRAM_CRCCHK)) + failsafe(pTAS2557); + } + + return nResult; +} + +int tas2557_set_config(struct tas2557_priv *pTAS2557, int config) +{ + struct TConfiguration *pConfiguration; + struct TProgram *pProgram; + unsigned int nProgram = pTAS2557->mnCurrentProgram; + unsigned int nConfiguration = config; + int nResult = 0; + + if ((!pTAS2557->mpFirmware->mpPrograms) || + (!pTAS2557->mpFirmware->mpConfigurations)) { + dev_err(pTAS2557->dev, "Firmware not loaded\n"); + nResult = -EINVAL; + goto end; + } + + if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) { + dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n", + nConfiguration); + nResult = -EINVAL; + goto end; + } + + pConfiguration = + &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]); + pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]); + + if (nProgram != pConfiguration->mnProgram) { + dev_err(pTAS2557->dev, + "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n", + nConfiguration, pConfiguration->mpName, + pConfiguration->mnProgram, nProgram, pProgram->mpName); + nResult = -EINVAL; + goto end; + } + + nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false); + +end: + + return nResult; +} + +void tas2557_clear_firmware(struct TFirmware *pFirmware) +{ + unsigned int n, nn; + + if (!pFirmware) + return; + + kfree(pFirmware->mpDescription); + + if (pFirmware->mpPLLs != NULL) { + for (n = 0; n < pFirmware->mnPLLs; n++) { + kfree(pFirmware->mpPLLs[n].mpDescription); + kfree(pFirmware->mpPLLs[n].mBlock.mpData); + } + kfree(pFirmware->mpPLLs); + } + + if (pFirmware->mpPrograms != NULL) { + for (n = 0; n < pFirmware->mnPrograms; n++) { + kfree(pFirmware->mpPrograms[n].mpDescription); + kfree(pFirmware->mpPrograms[n].mData.mpDescription); + for (nn = 0; + nn < pFirmware->mpPrograms[n].mData.mnBlocks; nn++) + kfree(pFirmware->mpPrograms[n] + .mData.mpBlocks[nn] + .mpData); + kfree(pFirmware->mpPrograms[n].mData.mpBlocks); + } + kfree(pFirmware->mpPrograms); + } + + if (pFirmware->mpConfigurations != NULL) { + for (n = 0; n < pFirmware->mnConfigurations; n++) { + kfree(pFirmware->mpConfigurations[n].mpDescription); + kfree(pFirmware->mpConfigurations[n] + .mData.mpDescription); + for (nn = 0; + nn < pFirmware->mpConfigurations[n].mData.mnBlocks; + nn++) + kfree(pFirmware->mpConfigurations[n] + .mData.mpBlocks[nn] + .mpData); + kfree(pFirmware->mpConfigurations[n].mData.mpBlocks); + } + kfree(pFirmware->mpConfigurations); + } + + if (pFirmware->mpCalibrations != NULL) { + for (n = 0; n < pFirmware->mnCalibrations; n++) { + kfree(pFirmware->mpCalibrations[n].mpDescription); + kfree(pFirmware->mpCalibrations[n].mData.mpDescription); + for (nn = 0; + nn < pFirmware->mpCalibrations[n].mData.mnBlocks; + nn++) + kfree(pFirmware->mpCalibrations[n] + .mData.mpBlocks[nn] + .mpData); + kfree(pFirmware->mpCalibrations[n].mData.mpBlocks); + } + kfree(pFirmware->mpCalibrations); + } + + memset(pFirmware, 0x00, sizeof(struct TFirmware)); +} + +static int tas2557_load_calibration(struct tas2557_priv *pTAS2557, + char *pFileName) +{ + int nResult = 0; + struct file *nFile = NULL; + mm_segment_t fs; + unsigned char pBuffer[1000]; + int nSize = 0; + loff_t pos = 0; + + dev_dbg(pTAS2557->dev, "%s:\n", __func__); + fs = get_fs(); + set_fs(KERNEL_DS); + nFile = filp_open(pFileName, O_RDONLY, 0); + + dev_info(pTAS2557->dev, "TAS2557 calibration file = %s\n", pFileName); + if (IS_ERR(nFile)) { + if (PTR_ERR(nFile) == -ENOENT) + dev_err(pTAS2557->dev, + "TAS2557 calibration file %s is not exit\n", + pFileName); + else + dev_err(pTAS2557->dev, + "TAS2557 cannot open calibration file: %s errno:%d\n", + pFileName, (int)PTR_ERR(nFile)); + } else { + pos = nFile->f_pos; + nSize = vfs_read(nFile, pBuffer, 1000, &pos); + filp_close(nFile, NULL); + } + + set_fs(fs); + if (!nSize) + goto end; + + tas2557_clear_firmware(pTAS2557->mpCalFirmware); + dev_info(pTAS2557->dev, "TAS2557 calibration file size = %d\n", nSize); + nResult = fw_parse(pTAS2557, pTAS2557->mpCalFirmware, pBuffer, nSize); + + if (nResult) + dev_err(pTAS2557->dev, "TAS2557 calibration file is corrupt\n"); + else + dev_info(pTAS2557->dev, + "TAS2557 calibration: %d calibrations\n", + pTAS2557->mpCalFirmware->mnCalibrations); + +end: + return nResult; +} + +static bool tas2557_get_coefficient_in_block(struct tas2557_priv *pTAS2557, + struct TBlock *pBlock, int nReg, + int *pnValue) +{ + int nCoefficient = 0; + bool bFound = false; + unsigned char *pCommands; + int nBook, nPage, nOffset, len; + int i, n; + + pCommands = pBlock->mpData; + for (i = 0; i < pBlock->mnCommands;) { + nBook = pCommands[4 * i + 0]; + nPage = pCommands[4 * i + 1]; + nOffset = pCommands[4 * i + 2]; + if ((nOffset < 0x7f) || (nOffset == 0x81)) + i++; + else if (nOffset == 0x85) { + len = ((int)nBook << 8) | nPage; + nBook = pCommands[4 * i + 4]; + nPage = pCommands[4 * i + 5]; + nOffset = pCommands[4 * i + 6]; + n = 4 * i + 7; + i += 2; + i += ((len - 1) / 4); + if ((len - 1) % 4) + i++; + if ((nBook != TAS2557_BOOK_ID(nReg)) || + (nPage != TAS2557_PAGE_ID(nReg))) + continue; + if (nOffset > TAS2557_PAGE_REG(nReg)) + continue; + if ((len + nOffset) >= (TAS2557_PAGE_REG(nReg) + 4)) { + n += (TAS2557_PAGE_REG(nReg) - nOffset); + nCoefficient = ((int)pCommands[n] << 24) | + ((int)pCommands[n + 1] << 16) | + ((int)pCommands[n + 2] << 8) | + (int)pCommands[n + 3]; + bFound = true; + break; + } + } else { + dev_err(pTAS2557->dev, "%s, format error %d\n", + __func__, nOffset); + break; + } + } + + if (bFound) { + *pnValue = nCoefficient; + dev_dbg(pTAS2557->dev, "%s, B[0x%x]P[0x%x]R[0x%x]=0x%x\n", + __func__, TAS2557_BOOK_ID(nReg), TAS2557_PAGE_ID(nReg), + TAS2557_PAGE_REG(nReg), nCoefficient); + } + + return bFound; +} + +static bool tas2557_get_coefficient_in_data(struct tas2557_priv *pTAS2557, + struct TData *pData, int blockType, + int nReg, int *pnValue) +{ + bool bFound = false; + struct TBlock *pBlock; + int i; + + for (i = 0; i < pData->mnBlocks; i++) { + pBlock = &(pData->mpBlocks[i]); + if (pBlock->mnType == blockType) { + bFound = tas2557_get_coefficient_in_block( + pTAS2557, pBlock, nReg, pnValue); + if (bFound) + break; + } + } + + return bFound; +} + +static bool +tas2557_find_Tmax_in_configuration(struct tas2557_priv *pTAS2557, + struct TConfiguration *pConfiguration, + int *pnTMax) +{ + struct TData *pData; + bool bFound = false; + int nBlockType, nReg, nCoefficient; + + if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) + nReg = TAS2557_PG2P1_CALI_T_REG; + else + nReg = TAS2557_PG1P0_CALI_T_REG; + + nBlockType = TAS2557_BLOCK_CFG_COEFF_DEV_A; + + pData = &(pConfiguration->mData); + bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, + nReg, &nCoefficient); + if (bFound) + *pnTMax = nCoefficient; + + return bFound; +} + +void tas2557_fw_ready(const struct firmware *pFW, void *pContext) +{ + struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)pContext; + int nResult; + unsigned int nProgram = 0; + unsigned int nSampleRate = 0; + +#ifdef CONFIG_TAS2557_CODEC + mutex_lock(&pTAS2557->codec_lock); +#endif + +#ifdef CONFIG_TAS2557_MISC + mutex_lock(&pTAS2557->file_lock); +#endif + + dev_info(pTAS2557->dev, "%s:\n", __func__); + + if (unlikely(!pFW) || unlikely(!pFW->data)) { + dev_err(pTAS2557->dev, "firmware is not loaded.\n"); + goto end; + } + + if (pTAS2557->mpFirmware->mpConfigurations) { + nProgram = pTAS2557->mnCurrentProgram; + nSampleRate = pTAS2557->mnCurrentSampleRate; + dev_dbg(pTAS2557->dev, "clear current firmware\n"); + tas2557_clear_firmware(pTAS2557->mpFirmware); + } + + nResult = fw_parse(pTAS2557, pTAS2557->mpFirmware, + (unsigned char *)(pFW->data), pFW->size); + release_firmware(pFW); + if (nResult < 0) { + dev_err(pTAS2557->dev, "firmware is corrupt\n"); + goto end; + } + + if (!pTAS2557->mpFirmware->mnPrograms) { + dev_err(pTAS2557->dev, "firmware contains no programs\n"); + nResult = -EINVAL; + goto end; + } + + if (!pTAS2557->mpFirmware->mnConfigurations) { + dev_err(pTAS2557->dev, "firmware contains no configurations\n"); + nResult = -EINVAL; + goto end; + } + + if (nProgram >= pTAS2557->mpFirmware->mnPrograms) { + dev_info(pTAS2557->dev, + "no previous program, set to default\n"); + nProgram = 0; + } + + pTAS2557->mnCurrentSampleRate = nSampleRate; + nResult = tas2557_set_program(pTAS2557, nProgram, -1); + +end: + +#ifdef CONFIG_TAS2557_CODEC + mutex_unlock(&pTAS2557->codec_lock); +#endif + +#ifdef CONFIG_TAS2557_MISC + mutex_unlock(&pTAS2557->file_lock); +#endif +} + +int tas2557_set_program(struct tas2557_priv *pTAS2557, unsigned int nProgram, + int nConfig) +{ + struct TProgram *pProgram; + unsigned int nConfiguration = 0; + unsigned int nSampleRate = 0; + unsigned char nGain; + bool bFound = false; + int nResult = 0; + + if ((!pTAS2557->mpFirmware->mpPrograms) || + (!pTAS2557->mpFirmware->mpConfigurations)) { + dev_err(pTAS2557->dev, "Firmware not loaded\n"); + nResult = 0; + goto end; + } + + if (nProgram >= pTAS2557->mpFirmware->mnPrograms) { + dev_err(pTAS2557->dev, "TAS2557: Program %d doesn't exist\n", + nProgram); + nResult = 0; + goto end; + } + + if (nConfig < 0) { + nConfiguration = 0; + nSampleRate = pTAS2557->mnCurrentSampleRate; + while (!bFound && (nConfiguration < + pTAS2557->mpFirmware->mnConfigurations)) { + if (pTAS2557->mpFirmware + ->mpConfigurations[nConfiguration] + .mnProgram == nProgram) { + if (nSampleRate == 0) { + bFound = true; + dev_info( + pTAS2557->dev, + "find default configuration %d\n", + nConfiguration); + } else if (nSampleRate == + pTAS2557->mpFirmware + ->mpConfigurations + [nConfiguration] + .mnSamplingRate) { + bFound = true; + dev_info( + pTAS2557->dev, + "find matching configuration %d\n", + nConfiguration); + } else { + nConfiguration++; + } + } else { + nConfiguration++; + } + } + if (!bFound) { + dev_err(pTAS2557->dev, + "Program %d, no valid configuration found for sample rate %d, ignore\n", + nProgram, nSampleRate); + nResult = 0; + goto end; + } + } else { + if (pTAS2557->mpFirmware->mpConfigurations[nConfig].mnProgram != + nProgram) { + dev_err(pTAS2557->dev, + "%s, configuration program doesn't match\n", + __func__); + nResult = 0; + goto end; + } + nConfiguration = nConfig; + } + + pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]); + if (pTAS2557->mbPowerUp) { + dev_info( + pTAS2557->dev, + "device powered up, power down to load program %d (%s)\n", + nProgram, pProgram->mpName); + if (hrtimer_active(&pTAS2557->mtimer)) + hrtimer_cancel(&pTAS2557->mtimer); + + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) + pTAS2557->enableIRQ(pTAS2557, false); + + nResult = tas2557_dev_load_data(pTAS2557, + p_tas2557_shutdown_data); + if (nResult < 0) + goto end; + } + + pTAS2557->hw_reset(pTAS2557); + nResult = pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01); + if (nResult < 0) + goto end; + msleep(1); + nResult = tas2557_load_default(pTAS2557); + if (nResult < 0) + goto end; + + dev_info(pTAS2557->dev, "load program %d (%s)\n", nProgram, + pProgram->mpName); + nResult = tas2557_load_data(pTAS2557, &(pProgram->mData), + TAS2557_BLOCK_PGM_DEV_A); + if (nResult < 0) + goto end; + pTAS2557->mnCurrentProgram = nProgram; + + nResult = tas2557_get_DAC_gain(pTAS2557, &nGain); + if (nResult < 0) + goto end; + pTAS2557->mnDevGain = nGain; + pTAS2557->mnDevCurrentGain = nGain; + + nResult = tas2557_load_coefficient(pTAS2557, -1, nConfiguration, false); + if (nResult < 0) + goto end; + + if (pTAS2557->mbPowerUp) { + pTAS2557->clearIRQ(pTAS2557); + dev_dbg(pTAS2557->dev, "device powered up, load startup\n"); + nResult = + tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data); + if (nResult < 0) + goto end; + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + nResult = tas2557_checkPLL(pTAS2557); + if (nResult < 0) { + nResult = tas2557_dev_load_data( + pTAS2557, p_tas2557_shutdown_data); + pTAS2557->mbPowerUp = false; + goto end; + } + } + dev_dbg(pTAS2557->dev, "device powered up, load unmute\n"); + nResult = + tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data); + if (nResult < 0) + goto end; + + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + pTAS2557->enableIRQ(pTAS2557, true); + if (!hrtimer_active(&pTAS2557->mtimer)) { + pTAS2557->mnDieTvReadCounter = 0; + hrtimer_start( + &pTAS2557->mtimer, + ns_to_ktime( + (u64)LOW_TEMPERATURE_CHECK_PERIOD * + NSEC_PER_MSEC), + HRTIMER_MODE_REL); + } + } + } + +end: + + if (nResult < 0) { + if (pTAS2557->mnErrCode & + (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | + ERROR_YRAM_CRCCHK)) + failsafe(pTAS2557); + } + return nResult; +} + +int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration) +{ + struct TCalibration *pCalibration = NULL; + struct TConfiguration *pConfiguration; + struct TProgram *pProgram; + int nTmax = 0; + bool bFound = false; + int nResult = 0; + + if ((!pTAS2557->mpFirmware->mpPrograms) || + (!pTAS2557->mpFirmware->mpConfigurations)) { + dev_err(pTAS2557->dev, "Firmware not loaded\n\r"); + nResult = 0; + goto end; + } + + if (nCalibration == 0x00FF) { + nResult = tas2557_load_calibration(pTAS2557, TAS2557_CAL_NAME); + if (nResult < 0) { + dev_info(pTAS2557->dev, + "load new calibration file %s fail %d\n", + TAS2557_CAL_NAME, nResult); + goto end; + } + nCalibration = 0; + } + + if (nCalibration >= pTAS2557->mpCalFirmware->mnCalibrations) { + dev_err(pTAS2557->dev, "Calibration %d doesn't exist\n", + nCalibration); + nResult = 0; + goto end; + } + + pTAS2557->mnCurrentCalibration = nCalibration; + if (pTAS2557->mbLoadConfigurationPrePowerUp) + goto end; + + pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[nCalibration]); + pProgram = + &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); + pConfiguration = + &(pTAS2557->mpFirmware + ->mpConfigurations[pTAS2557->mnCurrentConfiguration]); + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + if (pTAS2557->mbBypassTMax) { + bFound = tas2557_find_Tmax_in_configuration( + pTAS2557, pConfiguration, &nTmax); + if (bFound && (nTmax == TAS2557_COEFFICIENT_TMAX)) { + dev_dbg(pTAS2557->dev, + "%s, config[%s] bypass load calibration\n", + __func__, pConfiguration->mpName); + goto end; + } + } + + dev_dbg(pTAS2557->dev, "%s, load calibration\n", __func__); + nResult = tas2557_load_data(pTAS2557, &(pCalibration->mData), + TAS2557_BLOCK_CFG_COEFF_DEV_A); + if (nResult < 0) + goto end; + } + +end: + if (nResult < 0) { + tas2557_clear_firmware(pTAS2557->mpCalFirmware); + nResult = tas2557_set_program(pTAS2557, + pTAS2557->mnCurrentProgram, + pTAS2557->mnCurrentConfiguration); + } + + return nResult; +} + +bool tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0) +{ + struct TCalibration *pCalibration; + struct TData *pData; + int nReg; + int nCali_Re; + bool bFound = false; + int nBlockType; + + if (!pTAS2557->mpCalFirmware->mnCalibrations) { + dev_err(pTAS2557->dev, "%s, no calibration data\n", __func__); + goto end; + } + + if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) + nReg = TAS2557_PG2P1_CALI_R0_REG; + else + nReg = TAS2557_PG1P0_CALI_R0_REG; + + nBlockType = TAS2557_BLOCK_CFG_COEFF_DEV_A; + + pCalibration = + &(pTAS2557->mpCalFirmware + ->mpCalibrations[pTAS2557->mnCurrentCalibration]); + pData = &(pCalibration->mData); + + bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, + nReg, &nCali_Re); + +end: + + if (bFound) + *prm_r0 = nCali_Re; + + return bFound; +} + +int spk_id_get(struct device_node *np) +{ + int id; + int state; + + state = spk_id_get_pin_3state(np); + if (state < 0) { + pr_err("%s: Can not get id pin state, %d\n", __func__, state); + return VENDOR_ID_NONE; + } + + switch (state) { + case PIN_PULL_DOWN: + id = VENDOR_ID_AAC; + break; + case PIN_PULL_UP: + id = VENDOR_ID_UNKNOWN; + break; + case PIN_FLOAT: + id = VENDOR_ID_GOER; + break; + default: + id = VENDOR_ID_UNKNOWN; + break; + } + return id; +} + +int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557) +{ + struct device_node *np = dev->of_node; + int rc = 0, ret = 0; + unsigned int value; + + pTAS2557->spk_id_gpio_p = of_parse_phandle(np, "ti,spk-id-pin", 0); + if (!pTAS2557->spk_id_gpio_p) { + dev_dbg(pTAS2557->dev, "property %s not detected in node %s", + "ti,spk-id-pin", np->full_name); + pTAS2557->mnSpkType = VENDOR_ID_NONE; + } else { + pTAS2557->mnSpkType = spk_id_get(pTAS2557->spk_id_gpio_p); + } + dev_dbg(pTAS2557->dev, "spk is is %d", pTAS2557->mnSpkType); + + pTAS2557->mnResetGPIO = of_get_named_gpio(np, "ti,cdc-reset-gpio", 0); + if (!gpio_is_valid(pTAS2557->mnResetGPIO)) { + dev_err(pTAS2557->dev, + "Looking up %s property in node %s failed %d\n", + "ti,cdc-reset-gpio", np->full_name, + pTAS2557->mnResetGPIO); + ret = -EINVAL; + goto end; + } else + dev_dbg(pTAS2557->dev, "ti,cdc-reset-gpio=%d\n", + pTAS2557->mnResetGPIO); + + pTAS2557->mnGpioINT = of_get_named_gpio(np, "ti,irq-gpio", 0); + if (!gpio_is_valid(pTAS2557->mnGpioINT)) + dev_err(pTAS2557->dev, + "Looking up %s property in node %s failed %d\n", + "ti,irq-gpio", np->full_name, pTAS2557->mnGpioINT); + + rc = of_property_read_u32(np, "ti,i2s-bits", &value); + if (rc) + dev_err(pTAS2557->dev, + "Looking up %s property in node %s failed %d\n", + "ti,i2s-bits", np->full_name, rc); + else + pTAS2557->mnI2SBits = value; + + rc = of_property_read_u32(np, "ti,bypass-tmax", &value); + if (rc) + dev_err(pTAS2557->dev, + "Looking up %s property in node %s failed %d\n", + "ti,bypass-tmax", np->full_name, rc); + else + pTAS2557->mbBypassTMax = (value > 0); + +end: + + return ret; +} + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("TAS2557 common functions for Android Linux"); +MODULE_LICENSE("GPL v2"); diff --git a/techpack/audio/asoc/codecs/tas2557/tas2557-core.h b/techpack/audio/asoc/codecs/tas2557/tas2557-core.h new file mode 100644 index 000000000000..95a544f45547 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas2557/tas2557-core.h @@ -0,0 +1,86 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** Copyright (C) 2019 XiaoMi, Inc. +** +** 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; version 2. +** +** 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. +** +** File: +** tas2557-core.h +** +** Description: +** header file for tas2557-core.c +** +** ============================================================================= +*/ + +#ifndef _TAS2557_CORE_H +#define _TAS2557_CORE_H + +#include "tas2557.h" + +#define TAS2557_YRAM_BOOK1 140 + +#define TAS2557_YRAM1_PAGE 42 +#define TAS2557_YRAM1_START_REG 88 +#define TAS2557_YRAM1_END_REG 127 + +#define TAS2557_YRAM2_START_PAGE 43 +#define TAS2557_YRAM2_END_PAGE 49 +#define TAS2557_YRAM2_START_REG 8 +#define TAS2557_YRAM2_END_REG 127 + +#define TAS2557_YRAM3_PAGE 50 +#define TAS2557_YRAM3_START_REG 8 +#define TAS2557_YRAM3_END_REG 27 + +/* should not include B0_P53_R44-R47 */ +#define TAS2557_YRAM_BOOK2 0 +#define TAS2557_YRAM4_START_PAGE 50 +#define TAS2557_YRAM4_END_PAGE 60 +#define TAS2557_YRAM4_START_REG 8 +#define TAS2557_YRAM4_END_REG 127 + +#define TAS2557_YRAM5_PAGE 61 +#define TAS2557_YRAM5_START_REG 8 +#define TAS2557_YRAM5_END_REG 27 + +#define TAS2557_COEFFICIENT_TMAX 0x7fffffff +#define TAS2557_SAFE_GUARD_PATTERN 0x5a +#define LOW_TEMPERATURE_CHECK_PERIOD 5000 /* 5 second */ + +struct TYCRC { + unsigned char mnOffset; + unsigned char mnLen; +}; + +int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable); +int tas2557_permanent_mute(struct tas2557_priv *pTAS2557, bool bmute); +int tas2557_SA_DevChnSetup(struct tas2557_priv *pTAS2557, unsigned int mode); +int tas2557_get_die_temperature(struct tas2557_priv *pTAS2557, + int *pTemperature); +int tas2557_set_sampling_rate(struct tas2557_priv *pTAS2557, + unsigned int nSamplingRate); +int tas2557_set_bit_rate(struct tas2557_priv *pTAS2557, unsigned int nBitRate); +int tas2557_get_bit_rate(struct tas2557_priv *pTAS2557, + unsigned char *pBitRate); +int tas2557_set_config(struct tas2557_priv *pTAS2557, int config); +void tas2557_fw_ready(const struct firmware *pFW, void *pContext); +bool tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0); +int tas2557_set_program(struct tas2557_priv *pTAS2557, unsigned int nProgram, + int nConfig); +int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration); +int tas2557_load_default(struct tas2557_priv *pTAS2557); +int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557); +int tas2557_get_DAC_gain(struct tas2557_priv *pTAS2557, unsigned char *pnGain); +int tas2557_set_DAC_gain(struct tas2557_priv *pTAS2557, unsigned int nGain); +int tas2557_configIRQ(struct tas2557_priv *pTAS2557); +int spk_id_get(struct device_node *np); + +#endif /* _TAS2557_CORE_H */ diff --git a/techpack/audio/asoc/codecs/tas2557/tas2557-misc.c b/techpack/audio/asoc/codecs/tas2557/tas2557-misc.c new file mode 100644 index 000000000000..5ef257de8ea0 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas2557/tas2557-misc.c @@ -0,0 +1,702 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** Copyright (C) 2019 XiaoMi, Inc. +** +** 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; version 2. +** +** 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. +** +** File: +** tas2557-misc.c +** +** Description: +** misc driver for Texas Instruments TAS2557 High Performance 4W Smart Amplifier +** +** ============================================================================= +*/ + +#ifdef CONFIG_TAS2557_MISC + +#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tas2557.h" +#include "tas2557-core.h" +#include "tas2557-misc.h" + +static int g_logEnable = 1; +static struct tas2557_priv *g_tas2557; + +static int tas2557_file_open(struct inode *inode, struct file *file) +{ + struct tas2557_priv *pTAS2557 = g_tas2557; + + if (!try_module_get(THIS_MODULE)) + return -ENODEV; + + file->private_data = (void *)pTAS2557; + if (g_logEnable) + dev_info(pTAS2557->dev, "%s\n", __func__); + return 0; +} + +static int tas2557_file_release(struct inode *inode, struct file *file) +{ + struct tas2557_priv *pTAS2557 = + (struct tas2557_priv *)file->private_data; + + if (g_logEnable) + dev_info(pTAS2557->dev, "%s\n", __func__); + file->private_data = (void *)NULL; + module_put(THIS_MODULE); + + return 0; +} + +static ssize_t tas2557_file_read(struct file *file, char *buf, size_t count, + loff_t *ppos) +{ + struct tas2557_priv *pTAS2557 = + (struct tas2557_priv *)file->private_data; + int ret = 0; + unsigned int nValue = 0; + unsigned char value = 0; + unsigned char *p_kBuf = NULL; + + mutex_lock(&pTAS2557->file_lock); + + switch (pTAS2557->mnDBGCmd) { + case TIAUDIO_CMD_REG_READ: { + if (g_logEnable) + dev_info( + pTAS2557->dev, + "TIAUDIO_CMD_REG_READ: current_reg = 0x%x, count=%d\n", + pTAS2557->mnCurrentReg, (int)count); + if (count == 1) { + ret = pTAS2557->read(pTAS2557, pTAS2557->mnCurrentReg, + &nValue); + if (ret < 0) + break; + + value = (u8)nValue; + if (g_logEnable) + dev_info( + pTAS2557->dev, + "TIAUDIO_CMD_REG_READ: nValue=0x%x, value=0x%x\n", + nValue, value); + ret = copy_to_user(buf, &value, 1); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, "copy to user fail %d\n", + ret); + } + } else if (count > 1) { + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf != NULL) { + ret = pTAS2557->bulk_read( + pTAS2557, pTAS2557->mnCurrentReg, + p_kBuf, count); + if (ret < 0) + break; + ret = copy_to_user(buf, p_kBuf, count); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, + "copy to user fail %d\n", ret); + } + kfree(p_kBuf); + } else + dev_err(pTAS2557->dev, "read no mem\n"); + } + } break; + + case TIAUDIO_CMD_PROGRAM: { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) && + (pTAS2557->mpFirmware->mnPrograms > 0)) { + if (g_logEnable) + dev_info(pTAS2557->dev, + "TIAUDIO_CMD_PROGRAM: count = %d\n", + (int)count); + + if (count == PROGRAM_BUF_SIZE) { + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf != NULL) { + struct TProgram *pProgram = &( + pTAS2557->mpFirmware->mpPrograms + [pTAS2557->mnCurrentProgram]); + p_kBuf[0] = + pTAS2557->mpFirmware->mnPrograms; + p_kBuf[1] = pTAS2557->mnCurrentProgram; + p_kBuf[2] = pProgram->mnAppMode; + p_kBuf[3] = + (pProgram->mnBoost & 0xff00) >> + 8; + p_kBuf[4] = + (pProgram->mnBoost & 0x00ff); + memcpy(&p_kBuf[5], pProgram->mpName, + FW_NAME_SIZE); + strlcpy(&p_kBuf[5 + FW_NAME_SIZE], + pProgram->mpDescription, + strlen(pProgram->mpDescription) + + 1); + ret = copy_to_user(buf, p_kBuf, count); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, + "copy to user fail %d\n", + ret); + } + kfree(p_kBuf); + } else + dev_err(pTAS2557->dev, "read no mem\n"); + } else + dev_err(pTAS2557->dev, + "read buffer not sufficient\n"); + } else + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", + __func__); + } break; + + case TIAUDIO_CMD_CONFIGURATION: { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) && + (pTAS2557->mpFirmware->mnPrograms > 0)) { + if (g_logEnable) + dev_info( + pTAS2557->dev, + "TIAUDIO_CMD_CONFIGURATION: count = %d\n", + (int)count); + if (count == CONFIGURATION_BUF_SIZE) { + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf != NULL) { + struct TConfiguration *pConfiguration = &( + pTAS2557->mpFirmware->mpConfigurations + [pTAS2557->mnCurrentConfiguration]); + + p_kBuf[0] = pTAS2557->mpFirmware + ->mnConfigurations; + p_kBuf[1] = + pTAS2557->mnCurrentConfiguration; + memcpy(&p_kBuf[2], + pConfiguration->mpName, + FW_NAME_SIZE); + p_kBuf[2 + FW_NAME_SIZE] = + pConfiguration->mnProgram; + p_kBuf[3 + FW_NAME_SIZE] = + pConfiguration->mnPLL; + p_kBuf[4 + FW_NAME_SIZE] = + (pConfiguration->mnSamplingRate & + 0x000000ff); + p_kBuf[5 + FW_NAME_SIZE] = + ((pConfiguration->mnSamplingRate & + 0x0000ff00) >> + 8); + p_kBuf[6 + FW_NAME_SIZE] = + ((pConfiguration->mnSamplingRate & + 0x00ff0000) >> + 16); + p_kBuf[7 + FW_NAME_SIZE] = + ((pConfiguration->mnSamplingRate & + 0xff000000) >> + 24); + strlcpy(&p_kBuf[8 + FW_NAME_SIZE], + pConfiguration->mpDescription, + strlen(pConfiguration + ->mpDescription) + + 1); + ret = copy_to_user(buf, p_kBuf, count); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, + "copy to user fail %d\n", + ret); + } + kfree(p_kBuf); + } else + dev_err(pTAS2557->dev, "read no mem\n"); + } else + dev_err(pTAS2557->dev, + "read buffer not sufficient\n"); + } else + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", + __func__); + } break; + + case TIAUDIO_CMD_FW_TIMESTAMP: { + if (g_logEnable) + dev_info(pTAS2557->dev, + "TIAUDIO_CMD_FW_TIMESTAMP: count = %d\n", + (int)count); + + if (count == 4) { + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf != NULL) { + p_kBuf[0] = (pTAS2557->mpFirmware->mnTimeStamp & + 0x000000ff); + p_kBuf[1] = + ((pTAS2557->mpFirmware->mnTimeStamp & + 0x0000ff00) >> + 8); + p_kBuf[2] = + ((pTAS2557->mpFirmware->mnTimeStamp & + 0x00ff0000) >> + 16); + p_kBuf[3] = + ((pTAS2557->mpFirmware->mnTimeStamp & + 0xff000000) >> + 24); + ret = copy_to_user(buf, p_kBuf, count); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, + "copy to user fail %d\n", ret); + } + kfree(p_kBuf); + } else + dev_err(pTAS2557->dev, "read no mem\n"); + } + } break; + + case TIAUDIO_CMD_CALIBRATION: { + if (g_logEnable) + dev_info(pTAS2557->dev, + "TIAUDIO_CMD_CALIBRATION: count = %d\n", + (int)count); + + if (count == 1) { + unsigned char curCal = pTAS2557->mnCurrentCalibration; + + ret = copy_to_user(buf, &curCal, 1); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, "copy to user fail %d\n", + ret); + } + } + } break; + + case TIAUDIO_CMD_SAMPLERATE: { + if (g_logEnable) + dev_info(pTAS2557->dev, + "TIAUDIO_CMD_SAMPLERATE: count = %d\n", + (int)count); + if (count == 4) { + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf != NULL) { + struct TConfiguration *pConfiguration = &( + pTAS2557->mpFirmware->mpConfigurations + [pTAS2557->mnCurrentConfiguration]); + + p_kBuf[0] = (pConfiguration->mnSamplingRate & + 0x000000ff); + p_kBuf[1] = ((pConfiguration->mnSamplingRate & + 0x0000ff00) >> + 8); + p_kBuf[2] = ((pConfiguration->mnSamplingRate & + 0x00ff0000) >> + 16); + p_kBuf[3] = ((pConfiguration->mnSamplingRate & + 0xff000000) >> + 24); + + ret = copy_to_user(buf, p_kBuf, count); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, + "copy to user fail %d\n", ret); + } + + kfree(p_kBuf); + } else + dev_err(pTAS2557->dev, "read no mem\n"); + } + } break; + + case TIAUDIO_CMD_BITRATE: { + if (g_logEnable) + dev_info(pTAS2557->dev, + "TIAUDIO_CMD_BITRATE: count = %d\n", + (int)count); + + if (count == 1) { + unsigned char bitRate = 0; + ret = tas2557_get_bit_rate(pTAS2557, &bitRate); + if (ret >= 0) { + ret = copy_to_user(buf, &bitRate, 1); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, + "copy to user fail %d\n", ret); + } + } + } + } break; + + case TIAUDIO_CMD_DACVOLUME: { + if (g_logEnable) + dev_info(pTAS2557->dev, + "TIAUDIO_CMD_DACVOLUME: count = %d\n", + (int)count); + + if (count == 1) { + unsigned char volume = 0; + + ret = tas2557_get_DAC_gain(pTAS2557, &volume); + if (ret >= 0) { + ret = copy_to_user(buf, &volume, 1); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, + "copy to user fail %d\n", ret); + } + } + } + } break; + } + pTAS2557->mnDBGCmd = 0; + + mutex_unlock(&pTAS2557->file_lock); + return count; +} + +static ssize_t tas2557_file_write(struct file *file, const char *buf, + size_t count, loff_t *ppos) +{ + struct tas2557_priv *pTAS2557 = + (struct tas2557_priv *)file->private_data; + int ret = 0; + unsigned char *p_kBuf = NULL; + unsigned int reg = 0; + unsigned int len = 0; + + mutex_lock(&pTAS2557->file_lock); + + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf == NULL) { + dev_err(pTAS2557->dev, "write no mem\n"); + goto err; + } + + ret = copy_from_user(p_kBuf, buf, count); + if (ret != 0) { + dev_err(pTAS2557->dev, "copy_from_user failed.\n"); + goto err; + } + + pTAS2557->mnDBGCmd = p_kBuf[0]; + switch (pTAS2557->mnDBGCmd) { + case TIAUDIO_CMD_REG_WITE: + if (count > 5) { + reg = ((unsigned int)p_kBuf[1] << 24) + + ((unsigned int)p_kBuf[2] << 16) + + ((unsigned int)p_kBuf[3] << 8) + + (unsigned int)p_kBuf[4]; + len = count - 5; + if (len == 1) { + ret = pTAS2557->write(pTAS2557, reg, p_kBuf[5]); + if (g_logEnable) + dev_info( + pTAS2557->dev, + "TIAUDIO_CMD_REG_WITE, Reg=0x%x, Val=0x%x\n", + reg, p_kBuf[5]); + } else + ret = pTAS2557->bulk_write(pTAS2557, reg, + &p_kBuf[5], len); + } else + dev_err(pTAS2557->dev, + "%s, write len fail, count=%d.\n", __func__, + (int)count); + pTAS2557->mnDBGCmd = 0; + break; + + case TIAUDIO_CMD_REG_READ: + if (count == 5) { + pTAS2557->mnCurrentReg = + ((unsigned int)p_kBuf[1] << 24) + + ((unsigned int)p_kBuf[2] << 16) + + ((unsigned int)p_kBuf[3] << 8) + + (unsigned int)p_kBuf[4]; + if (g_logEnable) + dev_info(pTAS2557->dev, + "TIAUDIO_CMD_REG_READ whole=0x%x\n", + pTAS2557->mnCurrentReg); + } else + dev_err(pTAS2557->dev, "read len fail.\n"); + break; + + case TIAUDIO_CMD_DEBUG_ON: + if (count == 2) + g_logEnable = p_kBuf[1]; + + pTAS2557->mnDBGCmd = 0; + break; + + case TIAUDIO_CMD_PROGRAM: { + if (count == 2) { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) && + (pTAS2557->mpFirmware->mnPrograms > 0)) { + int config = -1; + + if (p_kBuf[1] == pTAS2557->mnCurrentProgram) + config = + pTAS2557->mnCurrentConfiguration; + if (g_logEnable) + dev_info( + pTAS2557->dev, + "TIAUDIO_CMD_PROGRAM, set to %d, cfg=%d\n", + p_kBuf[1], config); + tas2557_set_program(pTAS2557, p_kBuf[1], + config); + pTAS2557->mnDBGCmd = 0; + } else + dev_err(pTAS2557->dev, + "%s, firmware not loaded\n", __func__); + } + } break; + + case TIAUDIO_CMD_CONFIGURATION: { + if (count == 2) { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) && + (pTAS2557->mpFirmware->mnPrograms > 0)) { + if (g_logEnable) + dev_info( + pTAS2557->dev, + "TIAUDIO_CMD_CONFIGURATION, set to %d\n", + p_kBuf[1]); + tas2557_set_config(pTAS2557, p_kBuf[1]); + pTAS2557->mnDBGCmd = 0; + } else + dev_err(pTAS2557->dev, + "%s, firmware not loaded\n", __func__); + } + } break; + + case TIAUDIO_CMD_FW_TIMESTAMP: + /*let go*/ + break; + + case TIAUDIO_CMD_CALIBRATION: { + if (count == 2) { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) && + (pTAS2557->mpFirmware->mnPrograms > 0)) { + if (g_logEnable) + dev_info( + pTAS2557->dev, + "TIAUDIO_CMD_CALIBRATION, set to %d\n", + p_kBuf[1]); + tas2557_set_calibration(pTAS2557, p_kBuf[1]); + pTAS2557->mnDBGCmd = 0; + } + } + } break; + + case TIAUDIO_CMD_SAMPLERATE: + if (count == 5) { + unsigned int nSampleRate = + ((unsigned int)p_kBuf[1] << 24) + + ((unsigned int)p_kBuf[2] << 16) + + ((unsigned int)p_kBuf[3] << 8) + + (unsigned int)p_kBuf[4]; + if (g_logEnable) + dev_info(pTAS2557->dev, + "TIAUDIO_CMD_SAMPLERATE, set to %d\n", + nSampleRate); + + tas2557_set_sampling_rate(pTAS2557, nSampleRate); + } + break; + + case TIAUDIO_CMD_BITRATE: + if (count == 2) { + if (g_logEnable) + dev_info(pTAS2557->dev, + "TIAUDIO_CMD_BITRATE, set to %d\n", + p_kBuf[1]); + + tas2557_set_bit_rate(pTAS2557, p_kBuf[1]); + } + break; + + case TIAUDIO_CMD_DACVOLUME: + if (count == 2) { + unsigned char volume; + + volume = (p_kBuf[1] & 0x0f); + if (g_logEnable) + dev_info(pTAS2557->dev, + "TIAUDIO_CMD_DACVOLUME, set to %d\n", + volume); + + tas2557_set_DAC_gain(pTAS2557, volume); + } + break; + + case TIAUDIO_CMD_SPEAKER: + if (count == 2) { + if (g_logEnable) + dev_info(pTAS2557->dev, + "TIAUDIO_CMD_SPEAKER, set to %d\n", + p_kBuf[1]); + tas2557_enable(pTAS2557, (p_kBuf[1] > 0)); + } + break; + + case TIAUDIO_CMD_FW_RELOAD: + if (count == 1) { + const char *pFWName; + if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) + pFWName = TAS2557_AAC_FW_NAME; + else if (pTAS2557->mnPGID == TAS2557_PG_VERSION_1P0) + pFWName = TAS2557_PG1P0_FW_NAME; + else + break; + + if (pTAS2557->mnSpkType == VENDOR_ID_GOER) + pFWName = TAS2557_GOER_FW_NAME; + else if (pTAS2557->mnSpkType == VENDOR_ID_AAC) + pFWName = TAS2557_AAC_FW_NAME; + else if (pTAS2557->mnSpkType == VENDOR_ID_SSI) + pFWName = TAS2557_SSI_FW_NAME; + else + pFWName = TAS2557_DEFAULT_FW_NAME; + + ret = request_firmware_nowait(THIS_MODULE, 1, pFWName, + pTAS2557->dev, GFP_KERNEL, + pTAS2557, + tas2557_fw_ready); + + if (g_logEnable) + dev_info(pTAS2557->dev, + "TIAUDIO_CMD_FW_RELOAD: ret = %d\n", + ret); + } + break; + + default: + pTAS2557->mnDBGCmd = 0; + break; + } + +err: + if (p_kBuf != NULL) + kfree(p_kBuf); + + mutex_unlock(&pTAS2557->file_lock); + + return count; +} + +static long tas2557_file_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct tas2557_priv *pTAS2557 = file->private_data; + int ret = 0; + + mutex_lock(&pTAS2557->file_lock); + + switch (cmd) { + case SMARTPA_SPK_DAC_VOLUME: { + } break; + + case SMARTPA_SPK_POWER_ON: { + tas2557_enable(pTAS2557, true); + } break; + + case SMARTPA_SPK_POWER_OFF: { + tas2557_enable(pTAS2557, false); + } break; + + case SMARTPA_SPK_SWITCH_PROGRAM: { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) && + (pTAS2557->mpFirmware->mnPrograms > 0)) + tas2557_set_program(pTAS2557, arg, -1); + } break; + + case SMARTPA_SPK_SWITCH_CONFIGURATION: { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) && + (pTAS2557->mpFirmware->mnPrograms > 0)) + tas2557_set_config(pTAS2557, arg); + } break; + + case SMARTPA_SPK_SWITCH_CALIBRATION: { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) && + (pTAS2557->mpFirmware->mnPrograms > 0)) + tas2557_set_calibration(pTAS2557, arg); + } break; + + case SMARTPA_SPK_SET_SAMPLERATE: { + tas2557_set_sampling_rate(pTAS2557, arg); + } break; + + case SMARTPA_SPK_SET_BITRATE: { + tas2557_set_bit_rate(pTAS2557, arg); + } break; + } + + mutex_unlock(&pTAS2557->file_lock); + return ret; +} + +static const struct file_operations fops = { + .owner = THIS_MODULE, + .read = tas2557_file_read, + .write = tas2557_file_write, + .unlocked_ioctl = tas2557_file_unlocked_ioctl, + .open = tas2557_file_open, + .release = tas2557_file_release, +}; + +#define MODULE_NAME "tas2557" +static struct miscdevice tas2557_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = MODULE_NAME, + .fops = &fops, +}; + +int tas2557_register_misc(struct tas2557_priv *pTAS2557) +{ + int ret = 0; + + g_tas2557 = pTAS2557; + + ret = misc_register(&tas2557_misc); + if (ret) + dev_err(pTAS2557->dev, "TAS2557 misc fail: %d\n", ret); + + dev_info(pTAS2557->dev, "%s, leave\n", __func__); + + return ret; +} + +int tas2557_deregister_misc(struct tas2557_priv *pTAS2557) +{ + misc_deregister(&tas2557_misc); + return 0; +} + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("TAS2557 Misc Smart Amplifier driver"); +MODULE_LICENSE("GPL v2"); +#endif diff --git a/techpack/audio/asoc/codecs/tas2557/tas2557-misc.h b/techpack/audio/asoc/codecs/tas2557/tas2557-misc.h new file mode 100644 index 000000000000..c9336ccc66f6 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas2557/tas2557-misc.h @@ -0,0 +1,60 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** Copyright (C) 2019 XiaoMi, Inc. +** +** 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; version 2. +** +** 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. +** +** File: +** tas2557-misc.h +** +** Description: +** header file for tas2557-misc.c +** +** ============================================================================= +*/ + +#ifndef _TAS2557_MISC_H +#define _TAS2557_MISC_H + +#define FW_NAME_SIZE 64 +#define FW_DESCRIPTION_SIZE 256 +#define PROGRAM_BUF_SIZE (5 + FW_NAME_SIZE + FW_DESCRIPTION_SIZE) +#define CONFIGURATION_BUF_SIZE (8 + FW_NAME_SIZE + FW_DESCRIPTION_SIZE) + +#define TIAUDIO_CMD_REG_WITE 1 +#define TIAUDIO_CMD_REG_READ 2 +#define TIAUDIO_CMD_DEBUG_ON 3 +#define TIAUDIO_CMD_PROGRAM 4 +#define TIAUDIO_CMD_CONFIGURATION 5 +#define TIAUDIO_CMD_FW_TIMESTAMP 6 +#define TIAUDIO_CMD_CALIBRATION 7 +#define TIAUDIO_CMD_SAMPLERATE 8 +#define TIAUDIO_CMD_BITRATE 9 +#define TIAUDIO_CMD_DACVOLUME 10 +#define TIAUDIO_CMD_SPEAKER 11 +#define TIAUDIO_CMD_FW_RELOAD 12 + +#define TAS2557_MAGIC_NUMBER 0x3235 /* '2557' */ + +#define SMARTPA_SPK_DAC_VOLUME _IOWR(TAS2557_MAGIC_NUMBER, 1, unsigned long) +#define SMARTPA_SPK_POWER_ON _IOWR(TAS2557_MAGIC_NUMBER, 2, unsigned long) +#define SMARTPA_SPK_POWER_OFF _IOWR(TAS2557_MAGIC_NUMBER, 3, unsigned long) +#define SMARTPA_SPK_SWITCH_PROGRAM _IOWR(TAS2557_MAGIC_NUMBER, 4, unsigned long) +#define SMARTPA_SPK_SWITCH_CONFIGURATION \ + _IOWR(TAS2557_MAGIC_NUMBER, 5, unsigned long) +#define SMARTPA_SPK_SWITCH_CALIBRATION \ + _IOWR(TAS2557_MAGIC_NUMBER, 6, unsigned long) +#define SMARTPA_SPK_SET_SAMPLERATE _IOWR(TAS2557_MAGIC_NUMBER, 7, unsigned long) +#define SMARTPA_SPK_SET_BITRATE _IOWR(TAS2557_MAGIC_NUMBER, 8, unsigned long) + +int tas2557_register_misc(struct tas2557_priv *pTAS2557); +int tas2557_deregister_misc(struct tas2557_priv *pTAS2557); + +#endif /* _TAS2557_MISC_H */ diff --git a/techpack/audio/asoc/codecs/tas2557/tas2557-regmap.c b/techpack/audio/asoc/codecs/tas2557/tas2557-regmap.c new file mode 100644 index 000000000000..9923660efa97 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas2557/tas2557-regmap.c @@ -0,0 +1,964 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** Copyright (C) 2019 XiaoMi, Inc. +** +** 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; version 2. +** +** 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. +** +** File: +** tas2557-regmap.c +** +** Description: +** I2C driver with regmap for Texas Instruments TAS2557 High Performance 4W Smart Amplifier +** +** ============================================================================= +*/ + +#ifdef CONFIG_TAS2557_REGMAP + +#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tas2557.h" +#include "tas2557-core.h" +#include +#include +#ifdef CONFIG_TAS2557_CODEC +#include "tas2557-codec.h" +#endif + +#ifdef CONFIG_TAS2557_MISC +#include "tas2557-misc.h" +#endif + +#define ENABLE_TILOAD +#ifdef ENABLE_TILOAD +#include "tiload.h" +#endif +#include "../spk-id.h" + +#define LOW_TEMPERATURE_GAIN 6 +#define LOW_TEMPERATURE_COUNTER 12 + +static int tas2557_change_book_page(struct tas2557_priv *pTAS2557, + unsigned char nBook, unsigned char nPage) +{ + int nResult = 0; + + if ((pTAS2557->mnCurrentBook == nBook) && + pTAS2557->mnCurrentPage == nPage) + goto end; + + if (pTAS2557->mnCurrentBook != nBook) { + nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_PAGE, + 0); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + goto end; + } + pTAS2557->mnCurrentPage = 0; + nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_REG, + nBook); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + goto end; + } + pTAS2557->mnCurrentBook = nBook; + if (nPage != 0) { + nResult = regmap_write(pTAS2557->mpRegmap, + TAS2557_BOOKCTL_PAGE, nPage); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + goto end; + } + pTAS2557->mnCurrentPage = nPage; + } + } else if (pTAS2557->mnCurrentPage != nPage) { + nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_PAGE, + nPage); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + goto end; + } + pTAS2557->mnCurrentPage = nPage; + } + +end: + if (nResult < 0) + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; + + return nResult; +} + +static int tas2557_dev_read(struct tas2557_priv *pTAS2557, + unsigned int nRegister, unsigned int *pValue) +{ + int nResult = 0; + unsigned int Value = 0; + + mutex_lock(&pTAS2557->dev_lock); + + if (pTAS2557->mbTILoadActive) { + if (!(nRegister & 0x80000000)) + goto end; /* let only reads from TILoad pass. */ + nRegister &= ~0x80000000; + + dev_dbg(pTAS2557->dev, "TiLoad R REG B[%d]P[%d]R[%d]\n", + TAS2557_BOOK_ID(nRegister), TAS2557_PAGE_ID(nRegister), + TAS2557_PAGE_REG(nRegister)); + } + + nResult = tas2557_change_book_page(pTAS2557, TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister)); + if (nResult >= 0) { + nResult = regmap_read(pTAS2557->mpRegmap, + TAS2557_PAGE_REG(nRegister), &Value); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + goto end; + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; + *pValue = Value; + } + +end: + + mutex_unlock(&pTAS2557->dev_lock); + return nResult; +} + +static int tas2557_dev_write(struct tas2557_priv *pTAS2557, + unsigned int nRegister, unsigned int nValue) +{ + int nResult = 0; + + mutex_lock(&pTAS2557->dev_lock); + if ((nRegister == 0xAFFEAFFE) && (nValue == 0xBABEBABE)) { + pTAS2557->mbTILoadActive = true; + goto end; + } + + if ((nRegister == 0xBABEBABE) && (nValue == 0xAFFEAFFE)) { + pTAS2557->mbTILoadActive = false; + goto end; + } + + if (pTAS2557->mbTILoadActive) { + if (!(nRegister & 0x80000000)) + goto end; /* let only writes from TILoad pass. */ + nRegister &= ~0x80000000; + + dev_dbg(pTAS2557->dev, "TiLoad W REG B[%d]P[%d]R[%d] =0x%x\n", + TAS2557_BOOK_ID(nRegister), TAS2557_PAGE_ID(nRegister), + TAS2557_PAGE_REG(nRegister), nValue); + } + + nResult = tas2557_change_book_page(pTAS2557, TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister)); + if (nResult >= 0) { + nResult = regmap_write(pTAS2557->mpRegmap, + TAS2557_PAGE_REG(nRegister), nValue); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; + } + +end: + + mutex_unlock(&pTAS2557->dev_lock); + + return nResult; +} + +static int tas2557_dev_bulk_read(struct tas2557_priv *pTAS2557, + unsigned int nRegister, u8 *pData, + unsigned int nLength) +{ + int nResult = 0; + int i; + + mutex_lock(&pTAS2557->dev_lock); + if (pTAS2557->mbTILoadActive) { + if (!(nRegister & 0x80000000)) + goto end; /* let only writes from TILoad pass. */ + + nRegister &= ~0x80000000; + dev_dbg(pTAS2557->dev, + "TiLoad BR REG B[%d]P[%d]R[%d], count=%d\n", + TAS2557_BOOK_ID(nRegister), TAS2557_PAGE_ID(nRegister), + TAS2557_PAGE_REG(nRegister), nLength); + } + + nResult = tas2557_change_book_page(pTAS2557, TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister)); + if (nResult >= 0) { +#define STRIDE 4 + /* Read chunk bytes defined by STRIDE */ + for (i = 0; i < (nLength / STRIDE); i++) { + nResult = regmap_bulk_read( + pTAS2557->mpRegmap, + TAS2557_PAGE_REG((nRegister + i * STRIDE)), + &pData[i * STRIDE], STRIDE); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + } else { + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; + } + } + + /* Read remaining bytes */ + if ((nLength % STRIDE) != 0) { + nResult = regmap_bulk_read( + pTAS2557->mpRegmap, + TAS2557_PAGE_REG(nRegister + i * STRIDE), + &pData[i * STRIDE], (nLength % STRIDE)); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + } else { + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; + } + } + } + +end: + mutex_unlock(&pTAS2557->dev_lock); + return nResult; +} + +static int tas2557_dev_bulk_write(struct tas2557_priv *pTAS2557, + unsigned int nRegister, u8 *pData, + unsigned int nLength) +{ + int nResult = 0; + + mutex_lock(&pTAS2557->dev_lock); + if (pTAS2557->mbTILoadActive) { + if (!(nRegister & 0x80000000)) + goto end; /* let only writes from TILoad pass. */ + + nRegister &= ~0x80000000; + + dev_dbg(pTAS2557->dev, + "TiLoad BW REG B[%d]P[%d]R[%d], count=%d\n", + TAS2557_BOOK_ID(nRegister), TAS2557_PAGE_ID(nRegister), + TAS2557_PAGE_REG(nRegister), nLength); + } + + nResult = tas2557_change_book_page(pTAS2557, TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister)); + if (nResult >= 0) { + nResult = regmap_bulk_write(pTAS2557->mpRegmap, + TAS2557_PAGE_REG(nRegister), pData, + nLength); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; + } + +end: + + mutex_unlock(&pTAS2557->dev_lock); + return nResult; +} + +static int tas2557_dev_update_bits(struct tas2557_priv *pTAS2557, + unsigned int nRegister, unsigned int nMask, + unsigned int nValue) +{ + int nResult = 0; + + mutex_lock(&pTAS2557->dev_lock); + + if (pTAS2557->mbTILoadActive) { + if (!(nRegister & 0x80000000)) + goto end; /* let only writes from TILoad pass. */ + + nRegister &= ~0x80000000; + dev_dbg(pTAS2557->dev, + "TiLoad SB REG B[%d]P[%d]R[%d], mask=0x%x, value=0x%x\n", + TAS2557_BOOK_ID(nRegister), TAS2557_PAGE_ID(nRegister), + TAS2557_PAGE_REG(nRegister), nMask, nValue); + } + + nResult = tas2557_change_book_page(pTAS2557, TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister)); + if (nResult >= 0) { + nResult = regmap_update_bits(pTAS2557->mpRegmap, + TAS2557_PAGE_REG(nRegister), nMask, + nValue); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; + } + +end: + mutex_unlock(&pTAS2557->dev_lock); + return nResult; +} + +void tas2557_clearIRQ(struct tas2557_priv *pTAS2557) +{ + unsigned int nValue; + int nResult = 0; + + nResult = pTAS2557->read(pTAS2557, TAS2557_FLAGS_1, &nValue); + if (nResult >= 0) + pTAS2557->read(pTAS2557, TAS2557_FLAGS_2, &nValue); +} + +void tas2557_enableIRQ(struct tas2557_priv *pTAS2557, bool enable) +{ + if (enable) { + if (!pTAS2557->mbIRQEnable) { + if (gpio_is_valid(pTAS2557->mnGpioINT)) { + enable_irq(pTAS2557->mnIRQ); + /* check after 10 ms */ + schedule_delayed_work(&pTAS2557->irq_work, + msecs_to_jiffies(10)); + pTAS2557->mbIRQEnable = true; + } + } + } else { + if (gpio_is_valid(pTAS2557->mnGpioINT)) + disable_irq_nosync(pTAS2557->mnIRQ); + pTAS2557->mbIRQEnable = false; + } +} + +static void tas2557_hw_reset(struct tas2557_priv *pTAS2557) +{ + if (gpio_is_valid(pTAS2557->mnResetGPIO)) { + gpio_direction_output(pTAS2557->mnResetGPIO, 0); + msleep(5); + gpio_direction_output(pTAS2557->mnResetGPIO, 1); + msleep(2); + } + + pTAS2557->mnCurrentBook = -1; + pTAS2557->mnCurrentPage = -1; + if (pTAS2557->mnErrCode) + dev_info(pTAS2557->dev, "before reset, ErrCode=0x%x\n", + pTAS2557->mnErrCode); + pTAS2557->mnErrCode = 0; +} + +static void irq_work_routine(struct work_struct *work) +{ + int nResult = 0; + unsigned int nDevInt1Status = 0, nDevInt2Status = 0; + unsigned int nDevPowerUpFlag = 0; + int nCounter = 2; + struct tas2557_priv *pTAS2557 = + container_of(work, struct tas2557_priv, irq_work.work); + +#ifdef CONFIG_TAS2557_CODEC + mutex_lock(&pTAS2557->codec_lock); +#endif + +#ifdef CONFIG_TAS2557_MISC + mutex_lock(&pTAS2557->file_lock); +#endif + + if (pTAS2557->mnErrCode & ERROR_FAILSAFE) + goto program; + + if (pTAS2557->mbRuntimeSuspend) { + dev_info(pTAS2557->dev, "%s, Runtime Suspended\n", __func__); + goto end; + } + + if (!pTAS2557->mbPowerUp) { + dev_info(pTAS2557->dev, "%s, device not powered\n", __func__); + goto end; + } + + if ((!pTAS2557->mpFirmware->mnConfigurations) || + (!pTAS2557->mpFirmware->mnPrograms)) { + dev_info(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + goto end; + } + + nResult = tas2557_dev_read(pTAS2557, TAS2557_FLAGS_1, &nDevInt1Status); + if (nResult >= 0) + nResult = tas2557_dev_read(pTAS2557, TAS2557_FLAGS_2, + &nDevInt2Status); + + if (nResult < 0) + goto program; + + if (((nDevInt1Status & 0xfc) != 0) || ((nDevInt2Status & 0x0c) != 0)) { + /* in case of INT_OC, INT_UV, INT_OT, INT_BO, INT_CL, INT_CLK1, INT_CLK2 */ + dev_err(pTAS2557->dev, "critical error: 0x%x, 0x%x\n", + nDevInt1Status, nDevInt2Status); + if (nDevInt1Status & 0x80) { + pTAS2557->mnErrCode |= ERROR_OVER_CURRENT; + dev_err(pTAS2557->dev, "DEVA SPK over current!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_OVER_CURRENT; + + if (nDevInt1Status & 0x40) { + pTAS2557->mnErrCode |= ERROR_UNDER_VOLTAGE; + dev_err(pTAS2557->dev, "DEVA SPK under voltage!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_UNDER_VOLTAGE; + + if (nDevInt1Status & 0x20) { + pTAS2557->mnErrCode |= ERROR_CLK_HALT; + dev_err(pTAS2557->dev, "DEVA clk halted!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_CLK_HALT; + + if (nDevInt1Status & 0x10) { + pTAS2557->mnErrCode |= ERROR_DIE_OVERTEMP; + dev_err(pTAS2557->dev, "DEVA die over temperature!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_DIE_OVERTEMP; + + if (nDevInt1Status & 0x08) { + pTAS2557->mnErrCode |= ERROR_BROWNOUT; + dev_err(pTAS2557->dev, "DEVA brownout!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_BROWNOUT; + + if (nDevInt1Status & 0x04) { + pTAS2557->mnErrCode |= ERROR_CLK_LOST; + dev_err(pTAS2557->dev, "DEVA clock lost!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_CLK_LOST; + + if (nDevInt2Status & 0x08) { + pTAS2557->mnErrCode |= ERROR_CLK_DET1; + dev_err(pTAS2557->dev, "DEVA clk detection 1!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_CLK_DET1; + + if (nDevInt2Status & 0x04) { + pTAS2557->mnErrCode |= ERROR_CLK_DET2; + dev_err(pTAS2557->dev, "DEVA clk detection 2!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_CLK_DET2; + + goto program; + } else { + dev_dbg(pTAS2557->dev, "IRQ Status: 0x%x, 0x%x\n", + nDevInt1Status, nDevInt2Status); + nCounter = 2; + while (nCounter > 0) { + nResult = tas2557_dev_read(pTAS2557, + TAS2557_POWER_UP_FLAG_REG, + &nDevPowerUpFlag); + if (nResult < 0) + goto program; + if ((nDevPowerUpFlag & 0xc0) == 0xc0) + break; + nCounter--; + if (nCounter > 0) { + /* in case check pow status just after power on TAS2557 */ + dev_dbg(pTAS2557->dev, + "PowSts: 0x%x, check again after 10ms\n", + nDevPowerUpFlag); + msleep(10); + } + } + if ((nDevPowerUpFlag & 0xc0) != 0xc0) { + dev_err(pTAS2557->dev, + "%s, Critical ERROR B[%d]_P[%d]_R[%d]= 0x%x\n", + __func__, + TAS2557_BOOK_ID(TAS2557_POWER_UP_FLAG_REG), + TAS2557_PAGE_ID(TAS2557_POWER_UP_FLAG_REG), + TAS2557_PAGE_REG(TAS2557_POWER_UP_FLAG_REG), + nDevPowerUpFlag); + pTAS2557->mnErrCode |= ERROR_CLASSD_PWR; + goto program; + } + pTAS2557->mnErrCode &= ~ERROR_CLASSD_PWR; + + dev_dbg(pTAS2557->dev, + "%s: INT1=0x%x, INT2=0x%x; PowerUpFlag=0x%x\n", + __func__, nDevInt1Status, nDevInt2Status, + nDevPowerUpFlag); + goto end; + } + +program: + /* hardware reset and reload */ + tas2557_set_program(pTAS2557, pTAS2557->mnCurrentProgram, + pTAS2557->mnCurrentConfiguration); + +end: + +#ifdef CONFIG_TAS2557_MISC + mutex_unlock(&pTAS2557->file_lock); +#endif + +#ifdef CONFIG_TAS2557_CODEC + mutex_unlock(&pTAS2557->codec_lock); +#endif +} + +static irqreturn_t tas2557_irq_handler(int irq, void *dev_id) +{ + struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)dev_id; + + tas2557_enableIRQ(pTAS2557, false); + /* get IRQ status after 100 ms */ + schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(100)); + return IRQ_HANDLED; +} + +static enum hrtimer_restart temperature_timer_func(struct hrtimer *timer) +{ + struct tas2557_priv *pTAS2557 = + container_of(timer, struct tas2557_priv, mtimer); + + if (pTAS2557->mbPowerUp) { + schedule_work(&pTAS2557->mtimerwork); + schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(1)); + } + return HRTIMER_NORESTART; +} + +static void timer_work_routine(struct work_struct *work) +{ + struct tas2557_priv *pTAS2557 = + container_of(work, struct tas2557_priv, mtimerwork); + int nResult, nTemp, nActTemp; + struct TProgram *pProgram; + static int nAvg; + +#ifdef CONFIG_TAS2557_CODEC + mutex_lock(&pTAS2557->codec_lock); +#endif + +#ifdef CONFIG_TAS2557_MISC + mutex_lock(&pTAS2557->file_lock); +#endif + + if (pTAS2557->mbRuntimeSuspend) { + dev_info(pTAS2557->dev, "%s, Runtime Suspended\n", __func__); + goto end; + } + + if (!pTAS2557->mpFirmware->mnConfigurations) { + dev_info(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + goto end; + } + + pProgram = + &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); + if (!pTAS2557->mbPowerUp || + (pProgram->mnAppMode != TAS2557_APP_TUNINGMODE)) { + dev_info(pTAS2557->dev, "%s, pass, Pow=%d, program=%s\n", + __func__, pTAS2557->mbPowerUp, pProgram->mpName); + goto end; + } + + nResult = tas2557_get_die_temperature(pTAS2557, &nTemp); + if (nResult >= 0) { + nActTemp = (int)(nTemp >> 23); + dev_dbg(pTAS2557->dev, "Die=0x%x, degree=%d\n", nTemp, + nActTemp); + if (!pTAS2557->mnDieTvReadCounter) + nAvg = 0; + pTAS2557->mnDieTvReadCounter++; + nAvg += nActTemp; + if (!(pTAS2557->mnDieTvReadCounter % LOW_TEMPERATURE_COUNTER)) { + nAvg /= LOW_TEMPERATURE_COUNTER; + dev_dbg(pTAS2557->dev, "check : avg=%d\n", nAvg); + if (nAvg < -6) { + /* if Die temperature is below -6 degree C */ + if (pTAS2557->mnDevCurrentGain != + LOW_TEMPERATURE_GAIN) { + nResult = tas2557_set_DAC_gain( + pTAS2557, LOW_TEMPERATURE_GAIN); + if (nResult < 0) + goto end; + pTAS2557->mnDevCurrentGain = + LOW_TEMPERATURE_GAIN; + dev_dbg(pTAS2557->dev, + "LOW Temp: set gain to %d\n", + LOW_TEMPERATURE_GAIN); + } + } else if (nAvg > 5) { + /* if Die temperature is above 5 degree C */ + if (pTAS2557->mnDevCurrentGain != + pTAS2557->mnDevGain) { + nResult = tas2557_set_DAC_gain( + pTAS2557, pTAS2557->mnDevGain); + if (nResult < 0) + goto end; + pTAS2557->mnDevCurrentGain = + pTAS2557->mnDevGain; + dev_dbg(pTAS2557->dev, + "LOW Temp: set gain to original\n"); + } + } + nAvg = 0; + } + + if (pTAS2557->mbPowerUp) + hrtimer_start( + &pTAS2557->mtimer, + ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * + NSEC_PER_MSEC), + HRTIMER_MODE_REL); + } + +end: + +#ifdef CONFIG_TAS2557_MISC + mutex_unlock(&pTAS2557->file_lock); +#endif + +#ifdef CONFIG_TAS2557_CODEC + mutex_unlock(&pTAS2557->codec_lock); +#endif +} + +static int tas2557_runtime_suspend(struct tas2557_priv *pTAS2557) +{ + dev_dbg(pTAS2557->dev, "%s\n", __func__); + + pTAS2557->mbRuntimeSuspend = true; + + if (hrtimer_active(&pTAS2557->mtimer)) { + dev_dbg(pTAS2557->dev, "cancel die temp timer\n"); + hrtimer_cancel(&pTAS2557->mtimer); + } + if (work_pending(&pTAS2557->mtimerwork)) { + dev_dbg(pTAS2557->dev, "cancel timer work\n"); + cancel_work_sync(&pTAS2557->mtimerwork); + } + if (delayed_work_pending(&pTAS2557->irq_work)) { + dev_dbg(pTAS2557->dev, "cancel IRQ work\n"); + cancel_delayed_work_sync(&pTAS2557->irq_work); + } + + return 0; +} + +static int tas2557_runtime_resume(struct tas2557_priv *pTAS2557) +{ + struct TProgram *pProgram; + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + if (!pTAS2557->mpFirmware->mpPrograms) { + dev_dbg(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + goto end; + } + + if (pTAS2557->mnCurrentProgram >= pTAS2557->mpFirmware->mnPrograms) { + dev_err(pTAS2557->dev, "%s, firmware corrupted\n", __func__); + goto end; + } + + pProgram = + &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); + if (pTAS2557->mbPowerUp && + (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)) { + if (!hrtimer_active(&pTAS2557->mtimer)) { + dev_dbg(pTAS2557->dev, + "%s, start Die Temp check timer\n", __func__); + pTAS2557->mnDieTvReadCounter = 0; + hrtimer_start( + &pTAS2557->mtimer, + ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * + NSEC_PER_MSEC), + HRTIMER_MODE_REL); + } + } + + pTAS2557->mbRuntimeSuspend = false; +end: + + return 0; +} + +static bool tas2557_volatile(struct device *pDev, unsigned int nRegister) +{ + return true; +} + +static bool tas2557_writeable(struct device *pDev, unsigned int nRegister) +{ + return true; +} + +static const struct regmap_config tas2557_i2c_regmap = { + .reg_bits = 8, + .val_bits = 8, + .writeable_reg = tas2557_writeable, + .volatile_reg = tas2557_volatile, + .cache_type = REGCACHE_NONE, + .max_register = 128, +}; + +/* tas2557_i2c_probe : +* platform dependent +* should implement hardware reset functionality +*/ +static int tas2557_i2c_probe(struct i2c_client *pClient, + const struct i2c_device_id *pID) +{ + struct tas2557_priv *pTAS2557; + int nResult = 0; + unsigned int nValue = 0; + const char *pFWName; + + dev_info(&pClient->dev, "%s enter\n", __func__); + + pTAS2557 = devm_kzalloc(&pClient->dev, sizeof(struct tas2557_priv), + GFP_KERNEL); + if (!pTAS2557) { + nResult = -ENOMEM; + goto err; + } + + pTAS2557->dev = &pClient->dev; + i2c_set_clientdata(pClient, pTAS2557); + dev_set_drvdata(&pClient->dev, pTAS2557); + + pTAS2557->mpRegmap = devm_regmap_init_i2c(pClient, &tas2557_i2c_regmap); + if (IS_ERR(pTAS2557->mpRegmap)) { + nResult = PTR_ERR(pTAS2557->mpRegmap); + dev_err(&pClient->dev, "Failed to allocate register map: %d\n", + nResult); + goto err; + } + + if (pClient->dev.of_node) + tas2557_parse_dt(&pClient->dev, pTAS2557); + + if (gpio_is_valid(pTAS2557->mnResetGPIO)) { + nResult = gpio_request(pTAS2557->mnResetGPIO, "TAS2557-RESET"); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s: GPIO %d request error\n", + __func__, pTAS2557->mnResetGPIO); + goto err; + } + tas2557_hw_reset(pTAS2557); + } + + pTAS2557->read = tas2557_dev_read; + pTAS2557->write = tas2557_dev_write; + pTAS2557->bulk_read = tas2557_dev_bulk_read; + pTAS2557->bulk_write = tas2557_dev_bulk_write; + pTAS2557->update_bits = tas2557_dev_update_bits; + pTAS2557->enableIRQ = tas2557_enableIRQ; + pTAS2557->clearIRQ = tas2557_clearIRQ; + pTAS2557->set_config = tas2557_set_config; + pTAS2557->set_calibration = tas2557_set_calibration; + pTAS2557->hw_reset = tas2557_hw_reset; + pTAS2557->runtime_suspend = tas2557_runtime_suspend; + pTAS2557->runtime_resume = tas2557_runtime_resume; + pTAS2557->mnRestart = 0; + + mutex_init(&pTAS2557->dev_lock); + + /* Reset the chip */ + nResult = tas2557_dev_write(pTAS2557, TAS2557_SW_RESET_REG, 0x01); + if (nResult < 0) { + dev_err(&pClient->dev, "I2c fail, %d\n", nResult); + goto err; + } + + msleep(1); + { + int i; + for (i = 0; i < 0x10; i++) { + tas2557_dev_read(pTAS2557, i, &nValue); + dev_err(pTAS2557->dev, "address:%x value: %x\n", i, + nValue); + } + } + + /* Ti's original codes logic (which firmware binary selected) */ + tas2557_dev_read(pTAS2557, TAS2557_REV_PGID_REG, &nValue); + pTAS2557->mnPGID = nValue; + if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) { + dev_info(pTAS2557->dev, "PG2.1 Silicon found\n"); + pFWName = TAS2557_AAC_FW_NAME; + } else if (pTAS2557->mnPGID == TAS2557_PG_VERSION_1P0) { + dev_info(pTAS2557->dev, "PG1.0 Silicon found\n"); + pFWName = TAS2557_PG1P0_FW_NAME; + } else { + nResult = -ENOTSUPP; + dev_info(pTAS2557->dev, "unsupport Silicon 0x%x\n", + pTAS2557->mnPGID); + goto err; + } + + /* Use our codecs logic to select Firmware binary */ + if (pTAS2557->mnSpkType == VENDOR_ID_GOER) + pFWName = TAS2557_GOER_FW_NAME; + else if (pTAS2557->mnSpkType == VENDOR_ID_AAC) + pFWName = TAS2557_AAC_FW_NAME; + else if (pTAS2557->mnSpkType == VENDOR_ID_SSI) + pFWName = TAS2557_SSI_FW_NAME; + else + pFWName = TAS2557_DEFAULT_FW_NAME; + + if (gpio_is_valid(pTAS2557->mnGpioINT)) { + nResult = gpio_request(pTAS2557->mnGpioINT, "TAS2557-IRQ"); + if (nResult < 0) { + dev_err(pTAS2557->dev, + "%s: GPIO %d request INT error\n", __func__, + pTAS2557->mnGpioINT); + goto err; + } + + gpio_direction_input(pTAS2557->mnGpioINT); + pTAS2557->mnIRQ = gpio_to_irq(pTAS2557->mnGpioINT); + dev_dbg(pTAS2557->dev, "irq = %d\n", pTAS2557->mnIRQ); + INIT_DELAYED_WORK(&pTAS2557->irq_work, irq_work_routine); + nResult = request_threaded_irq(pTAS2557->mnIRQ, + tas2557_irq_handler, NULL, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + pClient->name, pTAS2557); + if (nResult < 0) { + dev_err(pTAS2557->dev, "request_irq failed, %d\n", + nResult); + goto err; + } + disable_irq_nosync(pTAS2557->mnIRQ); + } + + pTAS2557->mpFirmware = devm_kzalloc( + &pClient->dev, sizeof(struct TFirmware), GFP_KERNEL); + if (!pTAS2557->mpFirmware) { + nResult = -ENOMEM; + goto err; + } + + pTAS2557->mpCalFirmware = devm_kzalloc( + &pClient->dev, sizeof(struct TFirmware), GFP_KERNEL); + if (!pTAS2557->mpCalFirmware) { + nResult = -ENOMEM; + goto err; + } + +#ifdef CONFIG_TAS2557_CODEC + mutex_init(&pTAS2557->codec_lock); + tas2557_register_codec(pTAS2557); +#endif + +#ifdef CONFIG_TAS2557_MISC + mutex_init(&pTAS2557->file_lock); + tas2557_register_misc(pTAS2557); +#endif + +#ifdef ENABLE_TILOAD + tiload_driver_init(pTAS2557); +#endif + dev_dbg(pTAS2557->dev, " firmware name %s\n", pFWName); + hrtimer_init(&pTAS2557->mtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + pTAS2557->mtimer.function = temperature_timer_func; + INIT_WORK(&pTAS2557->mtimerwork, timer_work_routine); + + nResult = + request_firmware_nowait(THIS_MODULE, 1, pFWName, pTAS2557->dev, + GFP_KERNEL, pTAS2557, tas2557_fw_ready); + +err: + + return nResult; +} + +static int tas2557_i2c_remove(struct i2c_client *pClient) +{ + struct tas2557_priv *pTAS2557 = i2c_get_clientdata(pClient); + + dev_info(pTAS2557->dev, "%s\n", __func__); + +#ifdef CONFIG_TAS2557_CODEC + tas2557_deregister_codec(pTAS2557); + mutex_destroy(&pTAS2557->codec_lock); +#endif + +#ifdef CONFIG_TAS2557_MISC + tas2557_deregister_misc(pTAS2557); + mutex_destroy(&pTAS2557->file_lock); +#endif + + mutex_destroy(&pTAS2557->dev_lock); + return 0; +} + +static const struct i2c_device_id tas2557_i2c_id[] = { + { "tas2557", 0 }, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, tas2557_i2c_id); + +#if defined(CONFIG_OF) +static const struct of_device_id tas2557_of_match[] = { + { .compatible = "ti,tas2557" }, + {}, +}; + +MODULE_DEVICE_TABLE(of, tas2557_of_match); +#endif + +static struct i2c_driver tas2557_i2c_driver = { + .driver = { + .name = "tas2557", + .owner = THIS_MODULE, +#if defined(CONFIG_OF) + .of_match_table = of_match_ptr(tas2557_of_match), +#endif + }, + .probe = tas2557_i2c_probe, + .remove = tas2557_i2c_remove, + .id_table = tas2557_i2c_id, +}; + +module_i2c_driver(tas2557_i2c_driver); + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("TAS2557 I2C Smart Amplifier driver"); +MODULE_LICENSE("GPL v2"); + +#endif diff --git a/techpack/audio/asoc/codecs/tas2557/tas2557.h b/techpack/audio/asoc/codecs/tas2557/tas2557.h new file mode 100644 index 000000000000..b99b129e2a63 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas2557/tas2557.h @@ -0,0 +1,485 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** Copyright (C) 2019 XiaoMi, Inc. +** +** 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; version 2. +** +** 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. +** +** File: +** tas2557.h +** +** Description: +** definitions and data structures for TAS2557 Android Linux driver +** +** ============================================================================= +*/ + +#ifndef _TAS2557_H +#define _TAS2557_H + +#include +#include +#include + +/* Page Control Register */ +#define TAS2557_PAGECTL_REG 0 + +/* Book Control Register (available in page0 of each book) */ +#define TAS2557_BOOKCTL_PAGE 0 +#define TAS2557_BOOKCTL_REG 127 + +/* 0000 0000 0BBB BBBB BPPP PPPP PRRR RRRR */ + +#define TAS2557_REG(book, page, reg) \ + ((((unsigned int)book * 256 * 128) + ((unsigned int)page * 128)) + reg) + +#define TAS2557_BOOK_ID(reg) ((unsigned char)(reg / (256 * 128))) +#define TAS2557_PAGE_ID(reg) ((unsigned char)((reg % (256 * 128)) / 128)) +#define TAS2557_BOOK_REG(reg) ((unsigned char)(reg % (256 * 128))) +#define TAS2557_PAGE_REG(reg) ((unsigned char)((reg % (256 * 128)) % 128)) + +/* Book0, Page0 registers */ +#define TAS2557_SW_RESET_REG TAS2557_REG(0, 0, 1) + +#define TAS2557_REV_PGID_REG TAS2557_REG(0, 0, 3) +#define TAS2557_PG_VERSION_1P0 0x80 +#define TAS2557_PG_VERSION_2P0 0x90 +#define TAS2557_PG_VERSION_2P1 0xa0 + +#define TAS2557_POWER_CTRL1_REG TAS2557_REG(0, 0, 4) +#define TAS2557_POWER_CTRL2_REG TAS2557_REG(0, 0, 5) + +#define TAS2557_SPK_CTRL_REG TAS2557_REG(0, 0, 6) +/* B0P0R6 - TAS2557_SPK_CTRL_REG */ +#define TAS2557_DAC_GAIN_MASK (0xf << 3) +#define TAS2557_DAC_GAIN_SHIFT 0x03 + +#define TAS2557_MUTE_REG TAS2557_REG(0, 0, 7) +#define TAS2557_SNS_CTRL_REG TAS2557_REG(0, 0, 8) +#define TAS2557_ADC_INPUT_SEL_REG TAS2557_REG(0, 0, 9) +#define TAS2557_DBOOST_CTL_REG TAS2557_REG(0, 0, 10) +#define TAS2557_NONAME11_REG TAS2557_REG(0, 0, 11) +#define TAS2557_NONAME12_REG TAS2557_REG(0, 0, 12) +#define TAS2557_NONAME13_REG TAS2557_REG(0, 0, 13) +#define TAS2557_NONAME14_REG TAS2557_REG(0, 0, 14) +#define TAS2557_NONAME15_REG TAS2557_REG(0, 0, 15) +#define TAS2557_NONAME16_REG TAS2557_REG(0, 0, 16) +#define TAS2557_NONAME17_REG TAS2557_REG(0, 0, 17) +#define TAS2557_NONAME18_REG TAS2557_REG(0, 0, 18) +#define TAS2557_SAR_SAMPLING_TIME_REG TAS2557_REG(0, 0, 19) +#define TAS2557_SAR_ADC1_REG TAS2557_REG(0, 0, 20) +#define TAS2557_SAR_ADC2_REG TAS2557_REG(0, 0, 21) /* B0_P0_R0x15*/ +#define TAS2557_CRC_CHECKSUM_REG TAS2557_REG(0, 0, 32) +#define TAS2557_CRC_RESET_REG TAS2557_REG(0, 0, 33) +#define TAS2557_DSP_MODE_SELECT_REG TAS2557_REG(0, 0, 34) +#define TAS2557_SAFE_GUARD_REG TAS2557_REG(0, 0, 37) +#define TAS2557_ASI_CTL1_REG TAS2557_REG(0, 0, 42) +#define TAS2557_CLK_ERR_CTRL TAS2557_REG(0, 0, 44) /* B0_P0_R0x2c*/ +#define TAS2557_CLK_ERR_CTRL2 TAS2557_REG(0, 0, 45) /* B0_P0_R0x2d*/ +#define TAS2557_CLK_ERR_CTRL3 TAS2557_REG(0, 0, 46) /* B0_P0_R0x2e*/ +#define TAS2557_DBOOST_CFG_REG TAS2557_REG(0, 0, 52) +#define TAS2557_POWER_UP_FLAG_REG TAS2557_REG(0, 0, 100) +#define TAS2557_FLAGS_1 TAS2557_REG(0, 0, 104) /* B0_P0_R0x68*/ +#define TAS2557_FLAGS_2 TAS2557_REG(0, 0, 108) /* B0_P0_R0x6c*/ + +/* Book0, Page1 registers */ +#define TAS2557_ASI1_DAC_FORMAT_REG TAS2557_REG(0, 1, 1) +#define TAS2557_ASI1_ADC_FORMAT_REG TAS2557_REG(0, 1, 2) +#define TAS2557_ASI1_OFFSET1_REG TAS2557_REG(0, 1, 3) +#define TAS2557_ASI1_ADC_PATH_REG TAS2557_REG(0, 1, 7) +#define TAS2557_ASI1_DAC_BCLK_REG TAS2557_REG(0, 1, 8) +#define TAS2557_ASI1_DAC_WCLK_REG TAS2557_REG(0, 1, 9) +#define TAS2557_ASI1_ADC_BCLK_REG TAS2557_REG(0, 1, 10) +#define TAS2557_ASI1_ADC_WCLK_REG TAS2557_REG(0, 1, 11) +#define TAS2557_ASI1_DIN_DOUT_MUX_REG TAS2557_REG(0, 1, 12) +#define TAS2557_ASI1_BDIV_CLK_SEL_REG TAS2557_REG(0, 1, 13) +#define TAS2557_ASI1_BDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 14) +#define TAS2557_ASI1_WDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 15) +#define TAS2557_ASI1_DAC_CLKOUT_REG TAS2557_REG(0, 1, 16) +#define TAS2557_ASI1_ADC_CLKOUT_REG TAS2557_REG(0, 1, 17) +#define TAS2557_ASI2_DAC_FORMAT_REG TAS2557_REG(0, 1, 21) +#define TAS2557_ASI2_ADC_FORMAT_REG TAS2557_REG(0, 1, 22) +#define TAS2557_ASI2_OFFSET1_REG TAS2557_REG(0, 1, 23) +#define TAS2557_ASI2_ADC_PATH_REG TAS2557_REG(0, 1, 27) +#define TAS2557_ASI2_DAC_BCLK_REG TAS2557_REG(0, 1, 28) +#define TAS2557_ASI2_DAC_WCLK_REG TAS2557_REG(0, 1, 29) +#define TAS2557_ASI2_ADC_BCLK_REG TAS2557_REG(0, 1, 30) +#define TAS2557_ASI2_ADC_WCLK_REG TAS2557_REG(0, 1, 31) +#define TAS2557_ASI2_DIN_DOUT_MUX_REG TAS2557_REG(0, 1, 32) +#define TAS2557_ASI2_BDIV_CLK_SEL_REG TAS2557_REG(0, 1, 33) +#define TAS2557_ASI2_BDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 34) +#define TAS2557_ASI2_WDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 35) +#define TAS2557_ASI2_DAC_CLKOUT_REG TAS2557_REG(0, 1, 36) +#define TAS2557_ASI2_ADC_CLKOUT_REG TAS2557_REG(0, 1, 37) +#define TAS2557_GPIO1_PIN_REG TAS2557_REG(0, 1, 61) /*B0_P1_R0x3d */ +#define TAS2557_GPIO2_PIN_REG TAS2557_REG(0, 1, 62) /*B0_P1_R0x3e */ +#define TAS2557_GPIO3_PIN_REG TAS2557_REG(0, 1, 63) /*B0_P1_R0x3f */ +#define TAS2557_GPIO4_PIN_REG TAS2557_REG(0, 1, 64) /*B0_P1_R0x40 */ +#define TAS2557_GPIO5_PIN_REG TAS2557_REG(0, 1, 65) +#define TAS2557_GPIO6_PIN_REG TAS2557_REG(0, 1, 66) +#define TAS2557_GPIO7_PIN_REG TAS2557_REG(0, 1, 67) +#define TAS2557_GPIO8_PIN_REG TAS2557_REG(0, 1, 68) +#define TAS2557_GPIO9_PIN_REG TAS2557_REG(0, 1, 69) +#define TAS2557_GPIO10_PIN_REG TAS2557_REG(0, 1, 70) +#define TAS2557_GPI_PIN_REG TAS2557_REG(0, 1, 77) /*B0_P1_R0x4d */ +#define TAS2557_GPIO_HIZ_CTRL1_REG TAS2557_REG(0, 1, 79) +#define TAS2557_GPIO_HIZ_CTRL2_REG TAS2557_REG(0, 1, 80) /*B0_P1_R0x50 */ +#define TAS2557_GPIO_HIZ_CTRL3_REG TAS2557_REG(0, 1, 81) +#define TAS2557_GPIO_HIZ_CTRL4_REG TAS2557_REG(0, 1, 82) +#define TAS2557_GPIO_HIZ_CTRL5_REG TAS2557_REG(0, 1, 83) +#define TAS2557_BIT_BANG_CTRL_REG TAS2557_REG(0, 1, 87) +#define TAS2557_BIT_BANG_OUT1_REG TAS2557_REG(0, 1, 88) +#define TAS2557_BIT_BANG_OUT2_REG TAS2557_REG(0, 1, 89) +#define TAS2557_BIT_BANG_IN1_REG TAS2557_REG(0, 1, 90) +#define TAS2557_BIT_BANG_IN2_REG TAS2557_REG(0, 1, 91) +#define TAS2557_BIT_BANG_IN3_REG TAS2557_REG(0, 1, 92) +#define TAS2557_PDM_IN_CLK_REG TAS2557_REG(0, 1, 94) +#define TAS2557_PDM_IN_PIN_REG TAS2557_REG(0, 1, 95) +#define TAS2557_ASIM_IFACE1_REG TAS2557_REG(0, 1, 98) +#define TAS2557_ASIM_FORMAT_REG TAS2557_REG(0, 1, 99) +#define TAS2557_ASIM_IFACE3_REG TAS2557_REG(0, 1, 100) +#define TAS2557_ASIM_IFACE4_REG TAS2557_REG(0, 1, 101) +#define TAS2557_ASIM_IFACE5_REG TAS2557_REG(0, 1, 102) +#define TAS2557_ASIM_IFACE6_REG TAS2557_REG(0, 1, 103) +#define TAS2557_ASIM_IFACE7_REG TAS2557_REG(0, 1, 104) +#define TAS2557_ASIM_IFACE8_REG TAS2557_REG(0, 1, 105) +#define TAS2557_CLK_HALT_REG TAS2557_REG(0, 1, 106) /* B0_P1_R0x6a */ +#define TAS2557_INT_GEN1_REG TAS2557_REG(0, 1, 108) /* B0_P1_R0x6c */ +#define TAS2557_INT_GEN2_REG TAS2557_REG(0, 1, 109) /* B0_P1_R0x6d */ +#define TAS2557_INT_GEN3_REG TAS2557_REG(0, 1, 110) /* B0_P1_R0x6e */ +#define TAS2557_INT_GEN4_REG TAS2557_REG(0, 1, 111) /* B0_P1_R0x6f */ +#define TAS2557_INT_MODE_REG TAS2557_REG(0, 1, 114) /* B0_P1_R0x72 */ +#define TAS2557_MAIN_CLKIN_REG TAS2557_REG(0, 1, 115) +#define TAS2557_PLL_CLKIN_REG TAS2557_REG(0, 1, 116) +#define TAS2557_CLKOUT_MUX_REG TAS2557_REG(0, 1, 117) +#define TAS2557_CLKOUT_CDIV_REG TAS2557_REG(0, 1, 118) +#define TAS2557_HACK_GP01_REG TAS2557_REG(0, 1, 122) + +#define TAS2557_HACK01_REG TAS2557_REG(0, 2, 10) + +#define TAS2557_ISENSE_THRESHOLD TAS2557_REG(0, 50, 104) +#define TAS2557_BOOSTON_EFFICIENCY TAS2557_REG(0, 51, 16) +#define TAS2557_BOOSTOFF_EFFICIENCY TAS2557_REG(0, 51, 20) +#define TAS2557_BOOST_HEADROOM TAS2557_REG(0, 51, 24) +#define TAS2557_THERMAL_FOLDBACK_REG TAS2557_REG(0, 51, 100) + +#define TAS2557_SA_PG2P1_CHL_CTRL_REG \ + TAS2557_REG(0, 53, 20) /* B0_P0x35_R0x14 */ +#define TAS2557_SA_COEFF_SWAP_REG TAS2557_REG(0, 53, 44) /* B0_P0x35_R0x2c */ + +#define TAS2557_SA_PG1P0_CHL_CTRL_REG \ + TAS2557_REG(0, 58, 120) /* B0_P0x3a_R0x78 */ + +#define TAS2557_TEST_MODE_REG TAS2557_REG(0, 253, 13) /* B0_P0xfd_R0x0d */ +#define TAS2557_BROADCAST_REG TAS2557_REG(0, 253, 54) /* B0_P0xfd_R0x36 */ +#define TAS2557_CRYPTIC_REG TAS2557_REG(0, 253, 71) +#define TAS2557_PG2P1_CALI_R0_REG TAS2557_REG(0x8c, 0x2f, 0x40) +#define TAS2557_PG1P0_CALI_R0_REG TAS2557_REG(0x8c, 0x2f, 0x28) +#define TAS2557_PG2P1_CALI_T_REG TAS2557_REG(0x8c, 0x30, 0x20) +#define TAS2557_PG1P0_CALI_T_REG TAS2557_REG(0x8c, 0x30, 0x08) + +#define TAS2557_DAC_INTERPOL_REG TAS2557_REG(100, 0, 1) +#define TAS2557_SOFT_MUTE_REG TAS2557_REG(100, 0, 7) +#define TAS2557_PLL_P_VAL_REG TAS2557_REG(100, 0, 27) +#define TAS2557_PLL_J_VAL_REG TAS2557_REG(100, 0, 28) +#define TAS2557_PLL_D_VAL_MSB_REG TAS2557_REG(100, 0, 29) +#define TAS2557_PLL_D_VAL_LSB_REG TAS2557_REG(100, 0, 30) +#define TAS2557_CLK_MISC_REG TAS2557_REG(100, 0, 31) +#define TAS2557_PLL_N_VAL_REG TAS2557_REG(100, 0, 32) +#define TAS2557_DAC_MADC_VAL_REG TAS2557_REG(100, 0, 33) +#define TAS2557_ISENSE_DIV_REG TAS2557_REG(100, 0, 42) +#define TAS2557_RAMP_CLK_DIV_MSB_REG TAS2557_REG(100, 0, 43) +#define TAS2557_RAMP_CLK_DIV_LSB_REG TAS2557_REG(100, 0, 44) + +#define TAS2557_DIE_TEMP_REG TAS2557_REG(130, 2, 124) /* B0x82_P0x02_R0x7C */ + +/* Bits */ +/* B0P0R4 - TAS2557_POWER_CTRL1_REG */ +#define TAS2557_SW_SHUTDOWN (0x1 << 0) +#define TAS2557_MADC_POWER_UP (0x1 << 3) +#define TAS2557_MDAC_POWER_UP (0x1 << 4) +#define TAS2557_NDIV_POWER_UP (0x1 << 5) +#define TAS2557_PLL_POWER_UP (0x1 << 6) +#define TAS2557_DSP_POWER_UP (0x1 << 7) + +/* B0P0R5 - TAS2557_POWER_CTRL2_REG */ +#define TAS2557_VSENSE_ENABLE (0x1 << 0) +#define TAS2557_ISENSE_ENABLE (0x1 << 1) +#define TAS2557_BOOST_ENABLE (0x1 << 5) +#define TAS2557_CLASSD_ENABLE (0x1 << 7) + +/* B0P0R7 - TAS2557_MUTE_REG */ +#define TAS2557_CLASSD_MUTE (0x1 << 0) +#define TAS2557_ISENSE_MUTE (0x1 << 1) + +/* B0P253R13 - TAS2557_TEST_MODE_REG */ +#define TAS2557_TEST_MODE_ENABLE (13) +#define TAS2557_TEST_MODE_MASK (0xf << 0) + +/* B0P253R71 - TAS2557_CRYPTIC_REG */ +#define TAS2557_OSC_TRIM_CAP(x) ((x & 0x3f) << 0) +#define TAS2557_DISABLE_ENCRYPTION (0x1 << 6) +#define TAS2557_SL_COMP (0x1 << 7) + +/* B0P1R115/6 - TAS2557_MAIN/PLL_CLKIN_REG */ +#define TAS2557_XXX_CLKIN_GPIO1 (0) +#define TAS2557_XXX_CLKIN_GPIO2 (1) +#define TAS2557_XXX_CLKIN_GPIO3 (2) +#define TAS2557_XXX_CLKIN_GPIO4 (3) +#define TAS2557_XXX_CLKIN_GPIO5 (4) +#define TAS2557_XXX_CLKIN_GPIO6 (5) +#define TAS2557_XXX_CLKIN_GPIO7 (6) +#define TAS2557_XXX_CLKIN_GPIO8 (7) +#define TAS2557_XXX_CLKIN_GPIO9 (8) +#define TAS2557_XXX_CLKIN_GPIO10 (9) +#define TAS2557_XXX_CLKIN_GPI1 (12) +#define TAS2557_XXX_CLKIN_GPI2 (13) +#define TAS2557_XXX_CLKIN_GPI3 (14) +#define TAS2557_NDIV_CLKIN_PLL (15) +#define TAS2557_PLL_CLKIN_INT_OSC (15) + +#define TAS2557_MCLK_CLKIN_SRC_GPIO1 (0) +#define TAS2557_MCLK_CLKIN_SRC_GPIO2 (1) +#define TAS2557_MCLK_CLKIN_SRC_GPIO3 (2) +#define TAS2557_MCLK_CLKIN_SRC_GPIO4 (3) +#define TAS2557_MCLK_CLKIN_SRC_GPIO5 (4) +#define TAS2557_MCLK_CLKIN_SRC_GPIO6 (5) +#define TAS2557_MCLK_CLKIN_SRC_GPIO7 (6) +#define TAS2557_MCLK_CLKIN_SRC_GPIO8 (7) +#define TAS2557_MCLK_CLKIN_SRC_GPIO9 (8) +#define TAS2557_MCLK_CLKIN_SRC_GPIO10 (9) +#define TAS2557_MCLK_CLKIN_SRC_GPI1 (12) +#define TAS2557_MCLK_CLKIN_SRC_GPI2 (13) +#define TAS2557_MCLK_CLKIN_SRC_GPI3 (14) + +#define TAS2557_FORMAT_I2S (0x0 << 5) +#define TAS2557_FORMAT_DSP (0x1 << 5) +#define TAS2557_FORMAT_RIGHT_J (0x2 << 5) +#define TAS2557_FORMAT_LEFT_J (0x3 << 5) +#define TAS2557_FORMAT_MONO_PCM (0x4 << 5) +#define TAS2557_FORMAT_MASK (0x7 << 5) + +#define TAS2557_WORDLENGTH_16BIT (0x0 << 3) +#define TAS2557_WORDLENGTH_20BIT (0x1 << 3) +#define TAS2557_WORDLENGTH_24BIT (0x2 << 3) +#define TAS2557_WORDLENGTH_32BIT (0x3 << 3) +#define TAS2557_WORDLENGTH_MASK TAS2557_WORDLENGTH_32BIT + +/* B100P0R7 - TAS2557_SOFT_MUTE_REG */ +#define TAS2557_PDM_SOFT_MUTE (0x1 << 0) +#define TAS2557_VSENSE_SOFT_MUTE (0x1 << 1) +#define TAS2557_ISENSE_SOFT_MUTE (0x1 << 2) +#define TAS2557_CLASSD_SOFT_MUTE (0x1 << 3) + +/* B100P0R27 - TAS2557_PLL_P_VAL_REG */ +#define TAS2557_PLL_P_VAL_MASK (0x3f << 0) + +/* B100P0R28 - TAS2557_PLL_J_VAL_REG */ +#define TAS2557_PLL_J_VAL_MASK ((unsigned int)(0x7f << 0)) +#define TAS2557_PLL_J_VAL_MASKX 0x00 + +/* B100P0R29-30 - TAS2557_PLL_D_VAL_MSB/LSB_REG */ +#define TAS2557_PLL_D_MSB_VAL(x) ((x >> 8) & 0x3f) +#define TAS2557_PLL_D_LSB_VAL(x) (x & 0xff) + +/* B100P0R31 - TAS2557_CLK_MISC_REG */ +#define TAS2557_DSP_CLK_FROM_PLL (0x1 << 5) + +#define TAS2557_AAC_FW_NAME "tas2557_uCDSP_aac.bin" +#define TAS2557_GOER_FW_NAME "tas2557_uCDSP_goer.bin" +#define TAS2557_SSI_FW_NAME "tas2557_uCDSP_ssi.bin" +#define TAS2557_DEFAULT_FW_NAME "tas2557_uCDSP.bin" + +#define TAS2557_PG1P0_FW_NAME "tas2557_pg1p0_uCDSP.bin" + +#define TAS2557_APP_ROM1MODE 0 +#define TAS2557_APP_ROM2MODE 1 +#define TAS2557_APP_TUNINGMODE 2 +#define TAS2557_APP_ROM1_96KHZ 3 +#define TAS2557_APP_ROM2_96KHZ 4 +#define TAS2557_APP_RAMMODE 5 + +#define TAS2557_BOOST_OFF 0 +#define TAS2557_BOOST_DEVA 1 +#define TAS2557_BOOST_DEVB 2 +#define TAS2557_BOOST_BOTH 3 + +#define ERROR_NONE 0x00000000 +#define ERROR_PLL_ABSENT 0x00000001 +#define ERROR_DEVA_I2C_COMM 0x00000002 +#define ERROR_PRAM_CRCCHK 0x00000008 +#define ERROR_YRAM_CRCCHK 0x00000010 +#define ERROR_CLK_DET2 0x00000020 +#define ERROR_CLK_DET1 0x00000040 +#define ERROR_CLK_LOST 0x00000080 +#define ERROR_BROWNOUT 0x00000100 +#define ERROR_DIE_OVERTEMP 0x00000200 +#define ERROR_CLK_HALT 0x00000400 +#define ERROR_UNDER_VOLTAGE 0x00000800 +#define ERROR_OVER_CURRENT 0x00001000 +#define ERROR_CLASSD_PWR 0x00002000 +#define ERROR_SAFE_GUARD 0x00004000 +#define ERROR_FAILSAFE 0x40000000 + +struct TBlock { + unsigned int mnType; + unsigned char mbPChkSumPresent; + unsigned char mnPChkSum; + unsigned char mbYChkSumPresent; + unsigned char mnYChkSum; + unsigned int mnCommands; + unsigned char *mpData; +}; + +struct TData { + char mpName[64]; + char *mpDescription; + unsigned int mnBlocks; + struct TBlock *mpBlocks; +}; + +struct TProgram { + char mpName[64]; + char *mpDescription; + unsigned char mnAppMode; + unsigned short mnBoost; + struct TData mData; +}; + +struct TPLL { + char mpName[64]; + char *mpDescription; + struct TBlock mBlock; +}; + +struct TConfiguration { + char mpName[64]; + char *mpDescription; + unsigned int mnDevices; + unsigned int mnProgram; + unsigned int mnPLL; + unsigned int mnSamplingRate; + unsigned char mnPLLSrc; + unsigned int mnPLLSrcRate; + struct TData mData; +}; + +struct TCalibration { + char mpName[64]; + char *mpDescription; + unsigned int mnProgram; + unsigned int mnConfiguration; + struct TData mData; +}; + +struct TFirmware { + unsigned int mnFWSize; + unsigned int mnChecksum; + unsigned int mnPPCVersion; + unsigned int mnFWVersion; + unsigned int mnDriverVersion; + unsigned int mnTimeStamp; + char mpDDCName[64]; + char *mpDescription; + unsigned int mnDeviceFamily; + unsigned int mnDevice; + unsigned int mnPLLs; + struct TPLL *mpPLLs; + unsigned int mnPrograms; + struct TProgram *mpPrograms; + unsigned int mnConfigurations; + struct TConfiguration *mpConfigurations; + unsigned int mnCalibrations; + struct TCalibration *mpCalibrations; +}; + +struct tas2557_register { + int book; + int page; + int reg; +}; + +struct tas2557_priv { + struct device *dev; + struct regmap *mpRegmap; + int mnPGID; + int mnResetGPIO; + struct mutex dev_lock; + struct TFirmware *mpFirmware; + struct TFirmware *mpCalFirmware; + unsigned int mnCurrentProgram; + unsigned int mnCurrentSampleRate; + unsigned int mnNewConfiguration; + unsigned int mnCurrentConfiguration; + unsigned int mnCurrentCalibration; + unsigned char mnCurrentBook; + unsigned char mnCurrentPage; + bool mbTILoadActive; + bool mbPowerUp; + bool mbMute; + bool mbLoadConfigurationPrePowerUp; + bool mbLoadCalibrationPostPowerUp; + bool mbCalibrationLoaded; + int (*read)(struct tas2557_priv *pTAS2557, unsigned int reg, + unsigned int *pValue); + int (*write)(struct tas2557_priv *pTAS2557, unsigned int reg, + unsigned int Value); + int (*bulk_read)(struct tas2557_priv *pTAS2557, unsigned int reg, + unsigned char *pData, unsigned int len); + int (*bulk_write)(struct tas2557_priv *pTAS2557, unsigned int reg, + unsigned char *pData, unsigned int len); + int (*update_bits)(struct tas2557_priv *pTAS2557, unsigned int reg, + unsigned int mask, unsigned int value); + int (*set_config)(struct tas2557_priv *pTAS2557, int config); + int (*set_calibration)(struct tas2557_priv *pTAS2557, int calibration); + void (*clearIRQ)(struct tas2557_priv *pTAS2557); + void (*enableIRQ)(struct tas2557_priv *pTAS2557, bool enable); + void (*hw_reset)(struct tas2557_priv *pTAS2557); + /* device is working, but system is suspended */ + int (*runtime_suspend)(struct tas2557_priv *pTAS2557); + int (*runtime_resume)(struct tas2557_priv *pTAS2557); + + int mnGpioINT; + struct delayed_work irq_work; + unsigned int mnIRQ; + bool mbIRQEnable; + unsigned char mnI2SBits; + + /* for low temperature check */ + unsigned int mnDevGain; + unsigned int mnDevCurrentGain; + unsigned int mnDieTvReadCounter; + struct hrtimer mtimer; + struct work_struct mtimerwork; + + /* device is working, but system is suspended */ + bool mbRuntimeSuspend; + + unsigned int mnErrCode; + unsigned int mnRestart; + + /* for configurations with maximum TLimit 0x7fffffff, + * bypass calibration update, usually used in factory test + */ + bool mbBypassTMax; + +#ifdef CONFIG_TAS2557_CODEC + struct mutex codec_lock; +#endif + +#ifdef CONFIG_TAS2557_MISC + int mnDBGCmd; + int mnCurrentReg; + struct mutex file_lock; +#endif + int mnSpkType; + struct device_node *spk_id_gpio_p; +}; + +#endif /* _TAS2557_H */ diff --git a/techpack/audio/asoc/codecs/tas2557/tiload.c b/techpack/audio/asoc/codecs/tas2557/tiload.c new file mode 100644 index 000000000000..bc88bf6cca0c --- /dev/null +++ b/techpack/audio/asoc/codecs/tas2557/tiload.c @@ -0,0 +1,447 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** Copyright (C) 2019 XiaoMi, Inc. +** +** 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; version 2. +** +** 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. +** +** File: +** tiload.c +** +** Description: +** utility for TAS2557 Android in-system tuning +** +** ============================================================================= +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tiload.h" + +/* enable debug prints in the driver */ +#define DEBUG + +static struct cdev *tiload_cdev; +static int tiload_major; /* Dynamic allocation of Mjr No. */ +static int tiload_opened; /* Dynamic allocation of Mjr No. */ +static struct tas2557_priv *g_TAS2557; +struct class *tiload_class; +static unsigned int magic_num; + +static char gPage; +static char gBook; +/******************************** Debug section *****************************/ + +/*---------------------------------------------------------------------------- + * Function : tiload_open + * + * Purpose : open method for tiload programming interface + *---------------------------------------------------------------------------- + */ +static int tiload_open(struct inode *in, struct file *filp) +{ + struct tas2557_priv *pTAS2557 = g_TAS2557; + + dev_info(pTAS2557->dev, "%s\n", __func__); + + if (tiload_opened) { + dev_info(pTAS2557->dev, "%s device is already opened\n", + "tiload"); + return -EINVAL; + } + filp->private_data = (void *)pTAS2557; + tiload_opened++; + return 0; +} + +/*---------------------------------------------------------------------------- + * Function : tiload_release + * + * Purpose : close method for tiload programming interface + *---------------------------------------------------------------------------- + */ +static int tiload_release(struct inode *in, struct file *filp) +{ + struct tas2557_priv *pTAS2557 = + (struct tas2557_priv *)filp->private_data; + + dev_info(pTAS2557->dev, "%s\n", __func__); + filp->private_data = NULL; + tiload_opened--; + return 0; +} + +#define MAX_LENGTH 128 +/*---------------------------------------------------------------------------- + * Function : tiload_read + * + * Purpose : read from codec + *---------------------------------------------------------------------------- + */ +static ssize_t tiload_read(struct file *filp, char __user *buf, size_t count, + loff_t *offset) +{ + struct tas2557_priv *pTAS2557 = + (struct tas2557_priv *)filp->private_data; + char *rd_data; + unsigned int nCompositeRegister = 0, Value = 0; + char reg_addr; + size_t size; + int ret = 0; +#ifdef DEBUG + /* int i; */ +#endif + + dev_info(pTAS2557->dev, "%s\n", __func__); + if (count > MAX_LENGTH) { + dev_err(pTAS2557->dev, "Max %d bytes can be read\n", + MAX_LENGTH); + return -EINVAL; + } + + /* copy register address from user space */ + size = copy_from_user(®_addr, buf, 1); + if (size != 0) { + dev_err(pTAS2557->dev, "read: copy_from_user failure\n"); + return -EINVAL; + } + + size = count; + + rd_data = kmalloc(MAX_LENGTH + 1, GFP_KERNEL | GFP_DMA); + + if (rd_data == NULL) { + dev_err(pTAS2557->dev, "kmalloc fail \n"); + return -EINVAL; + } + + nCompositeRegister = BPR_REG(gBook, gPage, reg_addr); + if (count == 1) { + ret = pTAS2557->read(pTAS2557, 0x80000000 | nCompositeRegister, + &Value); + if (ret >= 0) + rd_data[0] = (char)Value; + } else if (count > 1) { + ret = pTAS2557->bulk_read(pTAS2557, + 0x80000000 | nCompositeRegister, + rd_data, size); + } + if (ret < 0) + dev_err(pTAS2557->dev, + "%s, %d, ret=%d, count=%zu error happen!\n", __func__, + __LINE__, ret, count); + +#ifdef DEBUG + dev_info(pTAS2557->dev, "read size = %d, reg_addr= %x , count = %d\n", + (int)size, reg_addr, (int)count); +/* for (i = 0; i < (int) size; i++) { +* dev_dbg(pTAS2557->dev, "rd_data[%d]=%x\n", i, rd_data[i]); +* } +*/ +#endif + if (size != count) + dev_err(pTAS2557->dev, "read %d registers from the codec\n", + (int)size); + + if (copy_to_user(buf, rd_data, size) != 0) { + dev_err(pTAS2557->dev, "copy_to_user failed\n"); + kfree(rd_data); + return -EINVAL; + } + + kfree(rd_data); + return size; +} + +/* + *---------------------------------------------------------------------------- + * Function : tiload_write + * + * Purpose : write to codec + *---------------------------------------------------------------------------- + */ +static ssize_t tiload_write(struct file *filp, const char __user *buf, + size_t count, loff_t *offset) +{ + struct tas2557_priv *pTAS2557 = + (struct tas2557_priv *)filp->private_data; + char *wr_data; + char *pData; + size_t size; + unsigned int nCompositeRegister = 0; + unsigned int nRegister; + int ret = 0; +#ifdef DEBUG + /* int i; */ +#endif + dev_info(pTAS2557->dev, "%s\n", __func__); + + if (count > MAX_LENGTH) { + dev_err(pTAS2557->dev, "Max %d bytes can be read\n", + MAX_LENGTH); + return -EINVAL; + } + + wr_data = kmalloc(MAX_LENGTH + 1, GFP_KERNEL | GFP_DMA); + if (wr_data == NULL) { + dev_err(pTAS2557->dev, "kmalloc fail \n"); + return -EINVAL; + } + pData = wr_data; + + /* copy buffer from user space */ + size = copy_from_user(wr_data, buf, count); + if (size != 0) { + dev_err(pTAS2557->dev, "copy_from_user failure %d\n", + (int)size); + kfree(wr_data); + return -EINVAL; + } +#ifdef DEBUG + dev_info(pTAS2557->dev, "write size = %zu\n", count); +/* for (i = 0; i < (int) count; i++) { +* dev_info(pTAS2557->dev, "wr_data[%d]=%x\n", i, wr_data[i]); +* } +*/ +#endif + nRegister = wr_data[0]; + size = count; + if ((nRegister == 127) && (gPage == 0)) { + gBook = wr_data[1]; + kfree(wr_data); + return size; + } + + if (nRegister == 0) { + gPage = wr_data[1]; + pData++; + count--; + } + + nCompositeRegister = BPR_REG(gBook, gPage, nRegister); + if (count == 2) { + ret = pTAS2557->write(pTAS2557, 0x80000000 | nCompositeRegister, + pData[1]); + } else if (count > 2) { + ret = pTAS2557->bulk_write(pTAS2557, + 0x80000000 | nCompositeRegister, + &pData[1], count - 1); + } + + if (ret < 0) + dev_err(pTAS2557->dev, + "%s, %d, ret=%d, count=%zu, ERROR Happen\n", __func__, + __LINE__, ret, count); + kfree(wr_data); + return size; +} + +static void tiload_route_IO(struct tas2557_priv *pTAS2557, unsigned int bLock) +{ + if (bLock) + pTAS2557->write(pTAS2557, 0xAFFEAFFE, 0xBABEBABE); + else + pTAS2557->write(pTAS2557, 0xBABEBABE, 0xAFFEAFFE); +} + +static long tiload_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct tas2557_priv *pTAS2557 = + (struct tas2557_priv *)filp->private_data; + long num = 0; + void __user *argp = (void __user *)arg; + int val; + struct BPR bpr; + + dev_info(pTAS2557->dev, "%s, cmd=0x%x\n", __func__, cmd); + /* if (_IOC_TYPE(cmd) != TILOAD_IOC_MAGIC) + * return -ENOTTY; + */ + + switch (cmd) { + case TILOAD_IOMAGICNUM_GET: + num = copy_to_user(argp, &magic_num, sizeof(int)); + break; + case TILOAD_IOMAGICNUM_SET: + num = copy_from_user(&magic_num, argp, sizeof(int)); + dev_info(pTAS2557->dev, "TILOAD_IOMAGICNUM_SET\n"); + tiload_route_IO(pTAS2557, magic_num); + break; + case TILOAD_BPR_READ: + break; + case TILOAD_BPR_WRITE: + num = copy_from_user(&bpr, argp, sizeof(struct BPR)); + dev_info(pTAS2557->dev, + "TILOAD_BPR_WRITE: 0x%02X, 0x%02X, 0x%02X\n\r", + bpr.nBook, bpr.nPage, bpr.nRegister); + break; + case TILOAD_IOCTL_SET_CHL: + break; + case TILOAD_IOCTL_SET_CONFIG: + num = copy_from_user(&val, argp, sizeof(val)); + pTAS2557->set_config(pTAS2557, val); + break; + case TILOAD_IOCTL_SET_CALIBRATION: + num = copy_from_user(&val, argp, sizeof(val)); + pTAS2557->set_calibration(pTAS2557, val); + break; + default: + break; + } + return num; +} + +#ifdef CONFIG_COMPAT +static long tiload_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct tas2557_priv *pTAS2557 = + (struct tas2557_priv *)filp->private_data; + long nResult = 0; + + switch (cmd) { + case TILOAD_COMPAT_IOMAGICNUM_GET: + dev_info(pTAS2557->dev, + "%s, TILOAD_COMPAT_IOMAGICNUM_GET=0x%x\n", __func__, + cmd); + nResult = tiload_ioctl(filp, TILOAD_IOMAGICNUM_GET, + (unsigned long)compat_ptr(arg)); + break; + + case TILOAD_COMPAT_IOMAGICNUM_SET: + dev_info(pTAS2557->dev, + "%s, TILOAD_COMPAT_IOMAGICNUM_SET=0x%x\n", __func__, + cmd); + nResult = tiload_ioctl(filp, TILOAD_IOMAGICNUM_SET, + (unsigned long)compat_ptr(arg)); + break; + + case TILOAD_COMPAT_BPR_READ: + dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_BPR_READ=0x%x\n", + __func__, cmd); + nResult = tiload_ioctl(filp, TILOAD_BPR_READ, + (unsigned long)compat_ptr(arg)); + break; + + case TILOAD_COMPAT_BPR_WRITE: + dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_BPR_WRITE=0x%x\n", + __func__, cmd); + nResult = tiload_ioctl(filp, TILOAD_BPR_WRITE, + (unsigned long)compat_ptr(arg)); + break; + + case TILOAD_COMPAT_IOCTL_SET_CHL: + dev_info(pTAS2557->dev, + "%s, TILOAD_COMPAT_IOCTL_SET_CHL=0x%x\n", __func__, + cmd); + nResult = tiload_ioctl(filp, TILOAD_IOCTL_SET_CHL, + (unsigned long)compat_ptr(arg)); + break; + + case TILOAD_COMPAT_IOCTL_SET_CONFIG: + dev_info(pTAS2557->dev, + "%s, TILOAD_COMPAT_IOCTL_SET_CONFIG=0x%x\n", __func__, + cmd); + nResult = tiload_ioctl(filp, TILOAD_IOCTL_SET_CONFIG, + (unsigned long)compat_ptr(arg)); + break; + + case TILOAD_COMPAT_IOCTL_SET_CALIBRATION: + dev_info(pTAS2557->dev, + "%s, TILOAD_COMPAT_IOCTL_SET_CALIBRATION=0x%x\n", + __func__, cmd); + nResult = tiload_ioctl(filp, TILOAD_IOCTL_SET_CALIBRATION, + (unsigned long)compat_ptr(arg)); + break; + + default: + dev_err(pTAS2557->dev, "%s, unsupport compat ioctl=0x%x\n", + __func__, cmd); + break; + } + + return nResult; +} +#endif + +/*********** File operations structure for tiload *************/ +static const struct file_operations tiload_fops = { + .owner = THIS_MODULE, + .open = tiload_open, + .release = tiload_release, + .read = tiload_read, + .write = tiload_write, + .unlocked_ioctl = tiload_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = tiload_compat_ioctl, +#endif +}; + +/*---------------------------------------------------------------------------- + * Function : tiload_driver_init + * + * Purpose : Register a char driver for dynamic tiload programming + *---------------------------------------------------------------------------- + */ +int tiload_driver_init(struct tas2557_priv *pTAS2557) +{ + int result; + dev_t dev = MKDEV(tiload_major, 0); + + g_TAS2557 = pTAS2557; + + dev_info(pTAS2557->dev, "%s\n", __func__); + + result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); + if (result < 0) { + dev_err(pTAS2557->dev, "cannot allocate major number %d\n", + tiload_major); + return result; + } + tiload_class = class_create(THIS_MODULE, DEVICE_NAME); + tiload_major = MAJOR(dev); + dev_info(pTAS2557->dev, "allocated Major Number: %d\n", tiload_major); + + tiload_cdev = cdev_alloc(); + cdev_init(tiload_cdev, &tiload_fops); + tiload_cdev->owner = THIS_MODULE; + tiload_cdev->ops = &tiload_fops; + + if (device_create(tiload_class, NULL, dev, NULL, "tiload_node") == NULL) + dev_err(pTAS2557->dev, "Device creation failed\n"); + + if (cdev_add(tiload_cdev, dev, 1) < 0) { + dev_err(pTAS2557->dev, "tiload_driver: cdev_add failed\n"); + unregister_chrdev_region(dev, 1); + tiload_cdev = NULL; + return 1; + } + dev_info(pTAS2557->dev, "Registered TiLoad driver, Major number: %d\n", + tiload_major); + /* class_device_create(tiload_class, NULL, dev, NULL, DEVICE_NAME, 0); */ + return 0; +} + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("Utility for TAS2557 Android in-system tuning"); +MODULE_LICENSE("GPL v2"); diff --git a/techpack/audio/asoc/codecs/tas2557/tiload.h b/techpack/audio/asoc/codecs/tas2557/tiload.h new file mode 100644 index 000000000000..832093771f7f --- /dev/null +++ b/techpack/audio/asoc/codecs/tas2557/tiload.h @@ -0,0 +1,66 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** Copyright (C) 2019 XiaoMi, Inc. +** +** 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; version 2. +** +** 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. +** +** File: +** tiload.h +** +** Description: +** header file for tiload.c +** +** ============================================================================= +*/ + +#ifndef _TILOAD_H +#define _TILOAD_H + +#ifdef CONFIG_COMPAT +#include +#endif + +#include "tas2557.h" + +#define BPR_REG(book, page, reg) (((book * 256 * 128) + (page * 128)) + reg) + +/* typedefs required for the included header files */ +struct BPR { + unsigned char nBook; + unsigned char nPage; + unsigned char nRegister; +}; + +/* defines */ +#define DEVICE_NAME "tiload_node" + +#define TILOAD_IOC_MAGIC 0xE0 +#define TILOAD_IOMAGICNUM_GET _IOR(TILOAD_IOC_MAGIC, 1, int) +#define TILOAD_IOMAGICNUM_SET _IOW(TILOAD_IOC_MAGIC, 2, int) +#define TILOAD_BPR_READ _IOR(TILOAD_IOC_MAGIC, 3, struct BPR) +#define TILOAD_BPR_WRITE _IOW(TILOAD_IOC_MAGIC, 4, struct BPR) +#define TILOAD_IOCTL_SET_CHL _IOW(TILOAD_IOC_MAGIC, 5, int) +#define TILOAD_IOCTL_SET_CONFIG _IOW(TILOAD_IOC_MAGIC, 6, int) +#define TILOAD_IOCTL_SET_CALIBRATION _IOW(TILOAD_IOC_MAGIC, 7, int) + +#ifdef CONFIG_COMPAT +#define TILOAD_COMPAT_IOMAGICNUM_GET _IOR(TILOAD_IOC_MAGIC, 1, compat_int_t) +#define TILOAD_COMPAT_IOMAGICNUM_SET _IOW(TILOAD_IOC_MAGIC, 2, compat_int_t) +#define TILOAD_COMPAT_BPR_READ _IOR(TILOAD_IOC_MAGIC, 3, struct BPR) +#define TILOAD_COMPAT_BPR_WRITE _IOW(TILOAD_IOC_MAGIC, 4, struct BPR) +#define TILOAD_COMPAT_IOCTL_SET_CHL _IOW(TILOAD_IOC_MAGIC, 5, compat_int_t) +#define TILOAD_COMPAT_IOCTL_SET_CONFIG _IOW(TILOAD_IOC_MAGIC, 6, compat_int_t) +#define TILOAD_COMPAT_IOCTL_SET_CALIBRATION \ + _IOW(TILOAD_IOC_MAGIC, 7, compat_int_t) +#endif + +int tiload_driver_init(struct tas2557_priv *pTAS2557); + +#endif diff --git a/techpack/audio/asoc/codecs/tas256x/Android.mk b/techpack/audio/asoc/codecs/tas256x/Android.mk new file mode 100644 index 000000000000..a8e7721869ec --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/Android.mk @@ -0,0 +1,55 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,msmnile),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m +endif + +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE)),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + #AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=tas256x_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_tas256x.ko +LOCAL_MODULE_KBUILD_NAME := tas256x_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/techpack/audio/asoc/codecs/tas256x/Kbuild b/techpack/audio/asoc/codecs/tas256x/Kbuild new file mode 100644 index 000000000000..b86ec227a743 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/Kbuild @@ -0,0 +1,116 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + + + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_SM8150), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif + ifeq ($(CONFIG_ARCH_SM6150), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif + + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ TAS2562 ############ + +# for TAS2562 Codec +ifdef CONFIG_SND_SOC_TAS256X + TAS256X_OBJS := tas256x-codec.o tas256x-regmap.o tas256x.o +endif +# for TAS2562 Algo +ifdef CONFIG_TAS25XX_ALGO + EXTRA_CFLAGS += -DCONFIG_TAS25XX_ALGO + TAS256X_OBJS += tas25xx-algo.o tas25xx-calib.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_TAS256X) += tas256x_dlkm.o +tas256x_dlkm-y := $(TAS256X_OBJS) diff --git a/techpack/audio/asoc/codecs/tas256x/Kconfig b/techpack/audio/asoc/codecs/tas256x/Kconfig new file mode 100644 index 000000000000..ffc6b777ce89 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/Kconfig @@ -0,0 +1,23 @@ +# +# TAS256X codec +# + +menuconfig SND_SOC_TAS256X + tristate "SND_SOC_TAS256X" + default n + +if SND_SOC_TAS256X + +config TAS256X_CODEC + tristate "TAS256X_CODEC" + default n + +config TAS256X_REGMAP + tristate "TAS256X_REGMAP" + default n + +config TAS25XX_ALGO + tristate "TAS25XX_ALGO" + default n + +endif diff --git a/techpack/audio/asoc/codecs/tas256x/Makefile b/techpack/audio/asoc/codecs/tas256x/Makefile new file mode 100644 index 000000000000..60b4454a6fab --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/Makefile @@ -0,0 +1,9 @@ +ccflags-y += -I$(srctree)/sound/soc/codecs/tas256x + +obj-y += snd-soc-tas256x.o + +snd-soc-tas256x-y := tas256x-codec.o \ + tas256x-regmap.o \ + tas256x.o +snd-soc-tas256x-$(CONFIG_TAS25XX_ALGO) += algo/src/tas25xx-algo.o \ + algo/src/tas25xx-calib.o diff --git a/techpack/audio/asoc/codecs/tas256x/tas2562.h b/techpack/audio/asoc/codecs/tas256x/tas2562.h new file mode 100644 index 000000000000..efd60f0849eb --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/tas2562.h @@ -0,0 +1,731 @@ +#ifndef __TAS2562_ +#define __TAS2562_ +/* Software Reset */ +#define TAS2562_SOFTWARERESET (TAS256X_SOFTWARERESET) +#define TAS2562_SOFTWARERESET_SOFTWARERESET_MASK \ + (TAS256X_SOFTWARERESET_SOFTWARERESET_MASK) +#define TAS2562_SOFTWARERESET_SOFTWARERESET_DONTRESET \ + (TAS256X_SOFTWARERESET_SOFTWARERESET_DONTRESET) +#define TAS2562_SOFTWARERESET_SOFTWARERESET_RESET \ + (TAS256X_SOFTWARERESET_SOFTWARERESET_RESET) + +/* Power Control */ +#define TAS2562_POWERCONTROL (TAS256X_POWERCONTROL) +#define TAS2562_POWERCONTROL_ISNSPOWER_MASK \ + (TAS256X_POWERCONTROL_ISNSPOWER_MASK) +#define TAS2562_POWERCONTROL_ISNSPOWER_ACTIVE \ + (TAS256X_POWERCONTROL_ISNSPOWER_ACTIVE) +#define TAS2562_POWERCONTROL_ISNSPOWER_POWEREDDOWN \ + (TAS256X_POWERCONTROL_ISNSPOWER_POWEREDDOWN) +#define TAS2562_POWERCONTROL_VSNSPOWER_MASK \ + (TAS256X_POWERCONTROL_VSNSPOWER_MASK) +#define TAS2562_POWERCONTROL_VSNSPOWER_ACTIVE \ + (TAS256X_POWERCONTROL_VSNSPOWER_ACTIVE) +#define TAS2562_POWERCONTROL_VSNSPOWER_POWEREDDOWN \ + (TAS256X_POWERCONTROL_VSNSPOWER_POWEREDDOWN) +#define TAS2562_POWERCONTROL_OPERATIONALMODE10_MASK \ + (TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK) +#define TAS2562_POWERCONTROL_OPERATIONALMODE10_ACTIVE \ + (TAS256X_POWERCONTROL_OPERATIONALMODE10_ACTIVE) +#define TAS2562_POWERCONTROL_OPERATIONALMODE10_MUTE \ + (TAS256X_POWERCONTROL_OPERATIONALMODE10_MUTE) +#define TAS2562_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN \ + (TAS256X_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN) + +/* Playback Configuration Reg0 */ +#define TAS2562_PLAYBACKCONFIGURATIONREG0 (TAS256X_PLAYBACKCONFIGURATIONREG0) +#define TAS2562_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_MASK \ + (TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_MASK) +#define TAS2562_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_ENABLED \ + (TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_ENABLED) +#define TAS2562_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_DISABLED \ + (TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_DISABLED) +#define TAS2562_PLAYBACKCONFIGURATIONREG0_AMPLIFIERLEVEL51_MASK (0x1f << 1) + +/* Misc Configuration Reg0 */ +#define TAS2562_MISCCONFIGURATIONREG0 (TAS256X_MISCCONFIGURATIONREG0) +#define TAS2562_MISCCONFIGURATIONREG0_CPPGRETRY_MASK \ + (TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_MASK) +#define TAS2562_MISCCONFIGURATIONREG0_CPPGRETRY_DONOTRETRY \ + (TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_DONOTRETRY) +#define TAS2562_MISCCONFIGURATIONREG0_CPPGRETRY_RETRY \ + (TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_RETRY) +#define TAS2562_MISCCONFIGURATIONREG0_VBATPRORETRY_MASK \ + (TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_MASK) +#define TAS2562_MISCCONFIGURATIONREG0_VBATPRORETRY_DONOTRETRY \ + (TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_DONOTRETRY) +#define TAS2562_MISCCONFIGURATIONREG0_VBATPRORETRY_RETRY \ + (TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_RETRY) +#define TAS2562_MISCCONFIGURATIONREG0_OCERETRY_MASK \ + (TAS256X_MISCCONFIGURATIONREG0_OCERETRY_MASK) +#define TAS2562_MISCCONFIGURATIONREG0_OCERETRY_DONOTRETRY \ + (TAS256X_MISCCONFIGURATIONREG0_OCERETRY_DONOTRETRY) +#define TAS2562_MISCCONFIGURATIONREG0_OCERETRY_RETRY \ + (TAS256X_MISCCONFIGURATIONREG0_OCERETRY_RETRY) +#define TAS2562_MISCCONFIGURATIONREG0_OTERETRY_MASK \ + (TAS256X_MISCCONFIGURATIONREG0_OTERETRY_MASK) +#define TAS2562_MISCCONFIGURATIONREG0_OTERETRY_DONOTRETRY \ + (TAS256X_MISCCONFIGURATIONREG0_OTERETRY_DONOTRETRY) +#define TAS2562_MISCCONFIGURATIONREG0_OTERETRY_RETRY \ + (TAS256X_MISCCONFIGURATIONREG0_OTERETRY_RETRY) +#define TAS2562_MISCCONFIGURATIONREG0_IRQZPULL_MASK \ + (TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_MASK) +#define TAS2562_MISCCONFIGURATIONREG0_IRQZPULL_DISABLED \ + (TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_DISABLED) +#define TAS2562_MISCCONFIGURATIONREG0_IRQZPULL_ENABLED \ + (TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_ENABLED) +#define TAS2562_MISCCONFIGURATIONREG0_AMPSS_MASK \ + (TAS256X_MISCCONFIGURATIONREG0_AMPSS_MASK) +#define TAS2562_MISCCONFIGURATIONREG0_AMPSS_DISABLED \ + (TAS256X_MISCCONFIGURATIONREG0_AMPSS_DISABLED) +#define TAS2562_MISCCONFIGURATIONREG0_AMPSS_ENABLED \ + (TAS256X_MISCCONFIGURATIONREG0_AMPSS_ENABLED) + +/* TDM Configuration Reg0 */ +#define TAS2562_TDMCONFIGURATIONREG0 (TAS256X_TDMCONFIGURATIONREG0) +#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK) +#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ) +#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ) +#define TAS2562_TDMCONFIGURATIONREG0_DETECTSAMPRATE_MASK \ + (TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_MASK) +#define TAS2562_TDMCONFIGURATIONREG0_DETECTSAMPRATE_DISABLED \ + (TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_DISABLED) +#define TAS2562_TDMCONFIGURATIONREG0_DETECTSAMPRATE_ENABLED \ + (TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_ENABLED) +#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATE31_MASK \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK) +#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATE31_14_7_16KHZ \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_14_7_16KHZ) +#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ) +#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ) +#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ) +#define TAS2562_TDMCONFIGURATIONREG0_FRAMESTART_MASK \ + (TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_MASK) +#define TAS2562_TDMCONFIGURATIONREG0_FRAMESTART_LOWTOHIGH \ + (TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_LOWTOHIGH) +#define TAS2562_TDMCONFIGURATIONREG0_FRAMESTART_HIGHTOLOW \ + (TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_HIGHTOLOW) + +/* TDM Configuration Reg1 */ +#define TAS2562_TDMCONFIGURATIONREG1 (TAS256X_TDMCONFIGURATIONREG1) +#define TAS2562_TDMCONFIGURATIONREG1_RXJUSTIFY_MASK \ + (TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_MASK) +#define TAS2562_TDMCONFIGURATIONREG1_RXJUSTIFY_LEFT \ + (TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_LEFT) +#define TAS2562_TDMCONFIGURATIONREG1_RXJUSTIFY_RIGHT \ + (TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_RIGHT) +#define TAS2562_TDMCONFIGURATIONREG1_RXOFFSET51_MASK \ + (TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_MASK) +#define TAS2562_TDMCONFIGURATIONREG1_RXOFFSET51_SHIFT \ + (TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_SHIFT) +#define TAS2562_TDMCONFIGURATIONREG1_RXEDGE_MASK \ + (TAS256X_TDMCONFIGURATIONREG1_RXEDGE_MASK) +#define TAS2562_TDMCONFIGURATIONREG1_RXEDGE_RISING \ + (TAS256X_TDMCONFIGURATIONREG1_RXEDGE_RISING) +#define TAS2562_TDMCONFIGURATIONREG1_RXEDGE_FALLING \ + (TAS256X_TDMCONFIGURATIONREG1_RXEDGE_FALLING) + +/* TDM Configuration Reg2 */ +#define TAS2562_TDMCONFIGURATIONREG2 (TAS256X_TDMCONFIGURATIONREG2) +#define TAS2562_TDMCONFIGURATIONREG2_IVLEN76_MASK \ + (TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK) +#define TAS2562_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS \ + (TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS) +#define TAS2562_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS \ + (TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS) +#define TAS2562_TDMCONFIGURATIONREG2_IVLENCFG76_8BITS \ + (TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_8BITS) +#define TAS2562_TDMCONFIGURATIONREG2_IVMONLEN76_MASK \ + (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_MASK) +#define TAS2562_TDMCONFIGURATIONREG2_IVMONLEN76_8BITS \ + (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_8BITS) +#define TAS2562_TDMCONFIGURATIONREG2_IVMONLEN76_12BITS \ + (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_12BITS) +#define TAS2562_TDMCONFIGURATIONREG2_IVMONLEN76_16BITS \ + (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_16BITS) +#define TAS2562_TDMCONFIGURATIONREG2_RXSCFG54_MASK \ + (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MASK) +#define TAS2562_TDMCONFIGURATIONREG2_RXSCFG54_MONO_I2C \ + (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_I2C) +#define TAS2562_TDMCONFIGURATIONREG2_RXSCFG54_MONO_LEFT \ + (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_LEFT) +#define TAS2562_TDMCONFIGURATIONREG2_RXSCFG54_MONO_RIGHT \ + (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_RIGHT) +#define TAS2562_TDMCONFIGURATIONREG2_RXSCFG54_STEREO_DOWNMIX \ + (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_STEREO_DOWNMIX) +#define TAS2562_TDMCONFIGURATIONREG2_RXWLEN32_MASK \ + (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_MASK) +#define TAS2562_TDMCONFIGURATIONREG2_RXWLEN32_16BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_16BITS) +#define TAS2562_TDMCONFIGURATIONREG2_RXWLEN32_20BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_20BITS) +#define TAS2562_TDMCONFIGURATIONREG2_RXWLEN32_24BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_24BITS) +#define TAS2562_TDMCONFIGURATIONREG2_RXWLEN32_32BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_32BITS) +#define TAS2562_TDMCONFIGURATIONREG2_RXSLEN10_MASK \ + (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_MASK) +#define TAS2562_TDMCONFIGURATIONREG2_RXSLEN10_16BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_16BITS) +#define TAS2562_TDMCONFIGURATIONREG2_RXSLEN10_24BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_24BITS) +#define TAS2562_TDMCONFIGURATIONREG2_RXSLEN10_32BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_32BITS) + +/* TDM Configuration Reg3 */ +#define TAS2562_TDMCONFIGURATIONREG3 TAS256X_REG(0x0, 0x0, 0x09) +#define TAS2562_TDMCONFIGURATIONREG3_RXSLOTRIGHT74_MASK (0xf << 4) +#define TAS2562_TDMCONFIGURATIONREG3_RXSLOTLeft30_Mask (0xf << 0) + +/* TDM Configuration Reg4 */ +#define TAS2562_TDMConfigurationReg4 (TAS256X_TDMConfigurationReg4) +#define TAS2562_TDMCONFIGURATIONREG4_TXKEEPER_MASK \ + (TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_MASK) +#define TAS2562_TDMCONFIGURATIONREG4_TXKEEPER_DISABLE \ + (TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_DISABLE) +#define TAS2562_TDMCONFIGURATIONREG4_TXKEEPER_ENABLE \ + (TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_ENABLE) +#define TAS2562_TDMCONFIGURATIONREG4_TXFILL_MASK \ + (TAS256X_TDMCONFIGURATIONREG4_TXFILL_MASK) +#define TAS2562_TDMCONFIGURATIONREG4_TXFILL_TRANSMIT0 \ + (TAS256X_TDMCONFIGURATIONREG4_TXFILL_TRANSMIT0) +#define TAS2562_TDMCONFIGURATIONREG4_TXFILL_TRANSMITHIZ \ + (TAS256X_TDMCONFIGURATIONREG4_TXFILL_TRANSMITHIZ) +#define TAS2562_TDMCONFIGURATIONREG4_TXOFFSET31_MASK \ + (TAS256X_TDMCONFIGURATIONREG4_TXOFFSET31_MASK) +#define TAS2562_TDMCONFIGURATIONREG4_TXEDGE_MASK \ + (TAS256X_TDMCONFIGURATIONREG4_TXEDGE_MASK) +#define TAS2562_TDMCONFIGURATIONREG4_TXEDGE_RISING \ + (TAS256X_TDMCONFIGURATIONREG4_TXEDGE_RISING) +#define TAS2562_TDMCONFIGURATIONREG4_TXEDGE_FALLING \ + (TAS256X_TDMCONFIGURATIONREG4_TXEDGE_FALLING) + +/* TDM Configuration Reg5 */ +#define TAS2562_TDMCONFIGURATIONREG5 (TAS256X_TDMCONFIGURATIONREG5) +#define TAS2562_TDMCONFIGURATIONREG5_VSNSTX_MASK \ + (TAS256X_TDMCONFIGURATIONREG5_VSNSTX_MASK) +#define TAS2562_TDMCONFIGURATIONREG5_VSNSTX_DISABLE \ + (TAS256X_TDMCONFIGURATIONREG5_VSNSTX_DISABLE) +#define TAS2562_TDMCONFIGURATIONREG5_VSNSTX_ENABLE \ + (TAS256X_TDMCONFIGURATIONREG5_VSNSTX_ENABLE) +#define TAS2562_TDMCONFIGURATIONREG5_VSNSSLOT50_MASK \ + (TAS256X_TDMCONFIGURATIONREG5_VSNSSLOT50_MASK) + +/* TDM Configuration Reg6 */ +#define TAS2562_TDMCONFIGURATIONREG6 (TAS256X_TDMCONFIGURATIONREG6) +#define TAS2562_TDMCONFIGURATIONREG6_ISNSTX_MASK \ + (TAS256X_TDMCONFIGURATIONREG6_ISNSTX_MASK) +#define TAS2562_TDMCONFIGURATIONREG6_ISNSTX_DISABLE \ + (TAS256X_TDMCONFIGURATIONREG6_ISNSTX_DISABLE) +#define TAS2562_TDMCONFIGURATIONREG6_ISNSTX_ENABLE \ + (TAS256X_TDMCONFIGURATIONREG6_ISNSTX_ENABLE) +#define TAS2562_TDMCONFIGURATIONREG6_ISNSSLOT50_MASK \ + (TAS256X_TDMCONFIGURATIONREG6_ISNSSLOT50_MASK) + +/* TDM Configuration Reg7 */ +#define TAS2562_TDMCONFIGURATIONREG7 (TAS256X_TDMCONFIGURATIONREG7) +#define TAS2562_TDMCONFIGURATIONREG7_VBATSLEN_MASK \ + (TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_MASK) +#define TAS2562_TDMCONFIGURATIONREG7_VBATSLEN_8BITS \ + (TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_8BITS) +#define TAS2562_TDMCONFIGURATIONREG7_VBATSLEN_16BITS \ + (TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_16BITS) +#define TAS2562_TDMCONFIGURATIONREG7_VBATTX_MASK \ + (TAS256X_TDMCONFIGURATIONREG7_VBATTX_MASK) +#define TAS2562_TDMCONFIGURATIONREG7_VBATTX_DISABLE \ + (TAS256X_TDMCONFIGURATIONREG7_VBATTX_DISABLE) +#define TAS2562_TDMCONFIGURATIONREG7_VBATTX_ENABLE \ + (TAS256X_TDMCONFIGURATIONREG7_VBATTX_ENABLE) +#define TAS2562_TDMCONFIGURATIONREG7_VBATSLOT50_MASK \ + (TAS256X_TDMCONFIGURATIONREG7_VBATSLOT50_MASK) + +/* TDM Configuration Reg8 */ +#define TAS2562_TDMCONFIGURATIONREG8 TAS256X_REG(0x0, 0x0, 0x0E) +#define TAS2562_TDMCONFIGURATIONREG8_TEMPTX_MASK (0x1 << 6) +#define TAS2562_TDMCONFIGURATIONREG8_TEMPTX_DISABLE (0x0 << 6) +#define TAS2562_TDMCONFIGURATIONREG8_TEMPTX_ENABLE (0x1 << 6) +#define TAS2562_TDMCONFIGURATIONREG8_TEMPSLOT50_MASK (0x3f << 0) + +/* TDM Configuration Reg9 */ +#define TAS2562_TDMCONFIGURATIONREG9 TAS256X_REG(0x0, 0x0, 0x0F) +#define TAS2562_TDMCONFIGURATIONREG9_GAINTX_MASK (0x1 << 6) +#define TAS2562_TDMCONFIGURATIONREG9_GAINTX_DISABLE (0x0 << 6) +#define TAS2562_TDMCONFIGURATIONREG9_GAINTX_ENABLE (0x1 << 6) +#define TAS2562_TDMCONFIGURATIONREG9_GAINSLOT50_MASK (0x3f << 0) + +/* Limiter Configuration Reg0 */ +#define TAS2562_LIMITERCONFIGURATIONREG0 TAS256X_REG(0x0, 0x0, 0x12) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKST54_MASK (0x3 << 4) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKST54_1 (0x2 << 4) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKST54_2 (0x3 << 4) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKST54_0_25 (0x0 << 4) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKST54_0_5 (0x1 << 4) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_MASK (0x7 << 1) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_5 (0x0 << 1) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_10 (0x1 << 1) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_20 (0x2 << 1) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_40 (0x3 << 1) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_80 (0x4 << 1) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_160 (0x5 << 1) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_320 (0x6 << 1) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_640 (0x7 << 1) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMEN_MASK (0x1 << 0) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMEN_DISABLED (0x0 << 0) +#define TAS2562_LIMITERCONFIGURATIONREG0_LIMEN_ENABLED (0x1 << 0) + +/* Limiter Configuration Reg1 */ +#define TAS2562_LIMITERCONFIGURATIONREG1 TAS256X_REG(0x0, 0x0, 0x13) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSST76_MASK (0x3 << 6) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSST76_1 (0x2 << 6) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSST76_2 (0x3 << 6) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSST76_0_25 (0x0 << 6) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSST76_0_5 (0x1 << 6) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_MASK (0x7 << 3) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_10 (0x0 << 3) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_50 (0x1 << 3) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_100 (0x2 << 3) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_250 (0x3 << 3) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_500 (0x4 << 3) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_750 (0x5 << 3) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_1000 (0x6 << 3) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_1500 (0x7 << 3) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_MASK (0x7 << 0) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_0 (0x0 << 0) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_10 (0x1 << 0) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_25 (0x2 << 0) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_50 (0x3 << 0) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_100 (0x4 << 0) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_250 (0x5 << 0) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_500 (0x6 << 0) +#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_1000 (0x7 << 0) + +/* Brown Out Prevention Reg0 */ +#define TAS2562_BROWNOUTPREVENTIONREG0 TAS256X_REG(0x0, 0x0, 0x14) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPSDEN_MASK (0x1 << 4) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPSDEN_DISABLED (0x0 << 4) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPSDEN_ENABLED (0x1 << 4) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPHLDCLR_MASK (0x1 << 3) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPHLDCLR_DONTCLEAR (0x0 << 3) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPHLDCLR_CLEAR (0x1 << 3) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPINFHLD_MASK (0x1 << 2) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPINFHLD_USEHOLDTIME (0x0 << 2) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPINFHLD_HOLDUNTILCLEARED (0x1 << 2) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPMUTE_MASK (0x1 << 1) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPMUTE_DONOTMUTE (0x0 << 1) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPMUTE_MUTE (0x1 << 1) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPEN_MASK (0x1 << 0) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPEN_DISABLED (0x0 << 0) +#define TAS2562_BROWNOUTPREVENTIONREG0_BOPEN_ENABLED (0x1 << 0) + +/* Brown Out Prevention Reg1 */ +#define TAS2562_BROWNOUTPREVENTIONREG1 TAS256X_REG(0x0, 0x0, 0x15) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_MASK (0x7 << 5) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_1 (0x0 << 5) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_2 (0x1 << 5) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_4 (0x2 << 5) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_8 (0x3 << 5) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_16 (0x4 << 5) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_32 (0x5 << 5) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_64 (0x6 << 5) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_128 (0x7 << 5) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKST43_MASK (0x3 << 3) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKST43_1 (0x1 << 3) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKST43_2 (0x3 << 3) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKST43_0_5 (0x0 << 3) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKST43_1_5 (0x2 << 3) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_MASK (0x7 << 0) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_0 (0x0 << 0) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_10 (0x1 << 0) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_25 (0x2 << 0) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_50 (0x3 << 0) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_100 (0x4 << 0) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_250 (0x5 << 0) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_500 (0x6 << 0) +#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_1000 (0x7 << 0) + +/* Interrupt Mask Reg0 */ +#define TAS2562_INTERRUPTMASKREG0 (TAS256X_INTERRUPTMASKREG0) +#define TAS2562_INTERRUPTMASKREG0_LIMMUTEINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_MASK) +#define TAS2562_INTERRUPTMASKREG0_LIMMUTEINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_UNMASK) +#define TAS2562_INTERRUPTMASKREG0_LIMMUTEINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_DISABLE) +#define TAS2562_INTERRUPTMASKREG0_LIMINFHLDINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_MASK) +#define TAS2562_INTERRUPTMASKREG0_LIMINFHLDINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_UNMASK) +#define TAS2562_INTERRUPTMASKREG0_LIMINFHLDINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_DISABLE) +#define TAS2562_INTERRUPTMASKREG0_LIMMAXATNINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_MASK) +#define TAS2562_INTERRUPTMASKREG0_LIMMAXATNINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_UNMASK) +#define TAS2562_INTERRUPTMASKREG0_LIMMAXATNINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_DISABLE) +#define TAS2562_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_MASK) +#define TAS2562_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_UNMASK) +#define TAS2562_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_DISABLE) +#define TAS2562_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_MASK) +#define TAS2562_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_UNMASK) +#define TAS2562_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_DISABLE) +#define TAS2562_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_MASK) +#define TAS2562_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_UNMASK) +#define TAS2562_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_DISABLE) +#define TAS2562_INTERRUPTMASKREG0_OCEINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_OCEINTMASK_MASK) +#define TAS2562_INTERRUPTMASKREG0_OCEINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_OCEINTMASK_UNMASK) +#define TAS2562_INTERRUPTMASKREG0_OCEINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_OCEINTMASK_DISABLE) +#define TAS2562_INTERRUPTMASKREG0_OTEINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_OTEINTMASK_MASK) +#define TAS2562_INTERRUPTMASKREG0_OTEINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_OTEINTMASK_UNMASK) +#define TAS2562_INTERRUPTMASKREG0_OTEINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_OTEINTMASK_DISABLE) +#define TAS2562_INTERRUPTMASKREG0_DISABLE (TAS256X_INTERRUPTMASKREG0_DISABLE) + +/* Interrupt Mask Reg1 */ +#define TAS2562_INTERRUPTMASKREG1 (TAS256X_INTERRUPTMASKREG1) +#define TAS2562_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_MASK) +#define TAS2562_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_UNMASK) +#define TAS2562_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_DISABLE) +#define TAS2562_INTERRUPTMASKREG1_CRCINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG1_CRCINTMASK_MASK) +#define TAS2562_INTERRUPTMASKREG1_CRCINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG1_CRCINTMASK_UNMASK) +#define TAS2562_INTERRUPTMASKREG1_CRCINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG1_CRCINTMASK_DISABLE) +#define TAS2562_INTERRUPTMASKREG1_VBATOVLOINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_MASK) +#define TAS2562_INTERRUPTMASKREG1_VBATOVLOINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_UNMASK) +#define TAS2562_INTERRUPTMASKREG1_VBATOVLOINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_DISABLE) +#define TAS2562_INTERRUPTMASKREG1_VBATUVLOINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_MASK) +#define TAS2562_INTERRUPTMASKREG1_VBATUVLOINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_UNMASK) +#define TAS2562_INTERRUPTMASKREG1_VBATUVLOINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_DISABLE) +#define TAS2562_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_MASK) +#define TAS2562_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_UNMASK) +#define TAS2562_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_DISABLE) +#define TAS2562_INTERRUPTMASKREG1_DISABLE (TAS256X_INTERRUPTMASKREG1_DISABLE) + +/* Interrupt Mask Reg2 */ +#define TAS2562_INTERRUPTMASKREG2 TAS256X_REG(0x0, 0x0, 0x1C) +#define TAS2562_INTERRUPTMASKREG2_DACLKINTMASK_MASK (0x1 << 7) +#define TAS2562_INTERRUPTMASKREG2_DACLKINTMASK_UNMASK (0x0 << 7) +#define TAS2562_INTERRUPTMASKREG2_DACLKINTMASK_DISABLE (0x1 << 7) +#define TAS2562_INTERRUPTMASKREG2_BSTCLKINTMASK_MASK (0x1 << 6) +#define TAS2562_INTERRUPTMASKREG2_BSTCLKINTMASK_UNMASK (0x0 << 6) +#define TAS2562_INTERRUPTMASKREG2_BSTCLKINTMASK_DISABLE (0x1 << 6) +#define TAS2562_INTERRUPTMASKREG2_VBATPORCLKINTMASK_MASK (0x1 << 5) +#define TAS2562_INTERRUPTMASKREG2_VBATPORCLKINTMASK_UNMASK (0x0 << 5) +#define TAS2562_INTERRUPTMASKREG2_VBATPORCLKINTMASK_DISABLE (0x1 << 5) +#define TAS2562_INTERRUPTMASKREG2_PLLOCKINTMASK_MASK (0x1 << 4) +#define TAS2562_INTERRUPTMASKREG2_PLLOCKINTMASK_UNMASK (0x0 << 4) +#define TAS2562_INTERRUPTMASKREG2_PLLOCKINTMASK_DISABLE (0x1 << 4) +#define TAS2562_INTERRUPTMASKREG2_DCDETECTINTMASK_MASK (0x1 << 3) +#define TAS2562_INTERRUPTMASKREG2_DCDETECTINTMASK_UNMASK (0x0 << 3) +#define TAS2562_INTERRUPTMASKREG2_DCDETECTINTMASK_DISABLE (0x1 << 3) + +/* Live-Interrupt Reg0 */ +#define TAS2562_LIVEINTERRUPTREG0 TAS256X_REG(0x0, 0x0, 0x1F) +#define TAS2562_LIVEINTERRUPTREG0_LIMMUTE_MASK (0x1 << 7) +#define TAS2562_LIVEINTERRUPTREG0_LIMMUTE_NOINTERRUPT (0x0 << 7) +#define TAS2562_LIVEINTERRUPTREG0_LIMMUTE_INTERRUPT (0x1 << 7) +#define TAS2562_LIVEINTERRUPTREG0_LIMINFHLD_MASK (0x1 << 6) +#define TAS2562_LIVEINTERRUPTREG0_LIMINFHLD_NOINTERRUPT (0x0 << 6) +#define TAS2562_LIVEINTERRUPTREG0_LIMINFHLD_INTERRUPT (0x1 << 6) +#define TAS2562_LIVEINTERRUPTREG0_LIMMAXATN_MASK (0x1 << 5) +#define TAS2562_LIVEINTERRUPTREG0_LIMMAXATN_NOINTERRUPT (0x0 << 5) +#define TAS2562_LIVEINTERRUPTREG0_LIMMAXATN_INTERRUPT (0x1 << 5) +#define TAS2562_LIVEINTERRUPTREG0_VBATLESSTHANINF_MASK (0x1 << 4) +#define TAS2562_LIVEINTERRUPTREG0_VBATLESSTHANINF_NOINTERRUPT (0x0 << 4) +#define TAS2562_LIVEINTERRUPTREG0_VBATLESSTHANINF_INTERRUPT (0x1 << 4) +#define TAS2562_LIVEINTERRUPTREG0_LIMACTIVEFLAG_MASK (0x1 << 3) +#define TAS2562_LIVEINTERRUPTREG0_LIMACTIVEFLAG_NOINTERRUPT (0x0 << 3) +#define TAS2562_LIVEINTERRUPTREG0_LIMACTIVEFLAG_INTERRUPT (0x1 << 3) +#define TAS2562_LIVEINTERRUPTREG0_TDMCLOCKERROR_MASK (0x1 << 2) +#define TAS2562_LIVEINTERRUPTREG0_TDMCLOCKERROR_NOINTERRUPT (0x0 << 2) +#define TAS2562_LIVEINTERRUPTREG0_TDMCLOCKERROR_INTERRUPT (0x1 << 2) +#define TAS2562_LIVEINTERRUPTREG0_OCEFLAG_MASK (0x1 << 1) +#define TAS2562_LIVEINTERRUPTREG0_OCEFLAG_NOINTERRUPT (0x0 << 1) +#define TAS2562_LIVEINTERRUPTREG0_OCEFLAG_INTERRUPT (0x1 << 1) +#define TAS2562_LIVEINTERRUPTREG0_OTEFLAG_MASK (0x1 << 0) +#define TAS2562_LIVEINTERRUPTREG0_OTEFLAG_NOINTERRUPT (0x0 << 0) +#define TAS2562_LIVEINTERRUPTREG0_OTEFLAG_INTERRUPT (0x1 << 0) + +/* Live-Interrupt Reg1 */ +#define TAS2562_LIVEINTERRUPTREG1 TAS256X_REG(0x0, 0x0, 0x20) +#define TAS2562_LIVEINTERRUPTREG1_DSPINTOUTPUT_MASK (0x1 << 7) +#define TAS2562_LIVEINTERRUPTREG1_DSPINTOUTPUT_NOINTERRUPT (0x0 << 7) +#define TAS2562_LIVEINTERRUPTREG1_DSPINTOUTPUT_INTERRUPT (0x1 << 7) +#define TAS2562_LIVEINTERRUPTREG1_OTPCRC_MASK (0x1 << 6) +#define TAS2562_LIVEINTERRUPTREG1_OTPCRC_NOINTERRUPT (0x0 << 6) +#define TAS2562_LIVEINTERRUPTREG1_OTPCRC_INTERRUPT (0x1 << 6) +#define TAS2562_LIVEINTERRUPTREG1_BROWNOUTFLAG_MASK (0x1 << 1) +#define TAS2562_LIVEINTERRUPTREG1_BROWNOUTFLAG_NOINTERRUPT (0x0 << 1) +#define TAS2562_LIVEINTERRUPTREG1_BROWNOUTFLAG_INTERRUPT (0x1 << 1) +#define TAS2562_LIVEINTERRUPTREG1_BROWNOUTDETECTED_MASK (0x1 << 1) +#define TAS2562_LIVEINTERRUPTREG1_BROWNOUTDETECTED_NOINTERRUPT (0x0 << 1) +#define TAS2562_LIVEINTERRUPTREG1_BROWNOUTDETECTED_INTERRUPT (0x1 << 1) + +/* Latched-Interrupt Reg0 */ +#define TAS2562_LATCHEDINTERRUPTREG0 (TAS256X_LATCHEDINTERRUPTREG0) +#define TAS2562_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_MASK) +#define TAS2562_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_NOINTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_INTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_MASK) +#define TAS2562_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_NOINTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_INTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_MASK) +#define TAS2562_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_NOINTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_INTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_MASK) +#define TAS2562_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_NOINTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_INTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_MASK) +#define TAS2562_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_NOINTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_INTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_MASK) +#define TAS2562_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_NOINTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_INTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_MASK) +#define TAS2562_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_NOINTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_INTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_MASK) +#define TAS2562_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_NOINTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_INTERRUPT) + +/* Latched-Interrupt Reg1 */ +#define TAS2562_LATCHEDINTERRUPTREG1 (TAS256X_LATCHEDINTERRUPTREG1) +#define TAS2562_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_MASK) +#define TAS2562_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_NOINTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_INTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_MASK) +#define TAS2562_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_NOINTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_INTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_MASK) +#define TAS2562_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_NOINTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_INTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_MASK) +#define TAS2562_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_NOINTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_INTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_MASK) +#define TAS2562_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_NOINTERRUPT) +#define TAS2562_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_INTERRUPT) + +/* VBAT MSB */ +#define TAS2562_VBATMSB TAS256X_REG(0x0, 0x0, 0x2A) +#define TAS2562_VBATMSB_VBATMSB70_MASK (0xff << 0) + +/* VBAT LSB */ +#define TAS2562_VBATLSB TAS256X_REG(0x0, 0x0, 0x2B) +#define TAS2562_VBATLSB_VBATLSB74_MASK (0xf << 4) + +/* TEMP */ +#define TAS2562_TEMP TAS256X_REG(0x0, 0x0, 0x2C) +#define TAS2562_TEMP_TEMPMSB70_MASK (0xff << 0) + +/* Interrupt Configuration */ +#define TAS2562_INTERRUPTCONFIGURATION (TAS256X_INTERRUPTCONFIGURATION) +#define TAS2562_INTERRUPTCONFIGURATION_LTCHINTCLEAR_MASK \ + (TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR_MASK) +#define TAS2562_INTERRUPTCONFIGURATION_LTCHINTCLEAR \ + (TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR) +#define TAS2562_INTERRUPTCONFIGURATION_PININTCONFIG10_MASK \ + (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_MASK) +#define TAS2562_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLIVEINTERRUPTS \ + (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLIVEINTERRUPTS) +#define TAS2562_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLATCHEDINTERRUPTS \ + (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLATCHEDINTERRUPTS) +#define TAS2562_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLIVEINTERRUPTS \ + (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLIVEINTERRUPTS) +#define TAS2562_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLATCHEDINTERRUPTS \ + (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLATCHEDINTERRUPTS) + +/* Digital Input Pin Pull Down */ +#define TAS2562_DIGITALINPUTPINPULLDOWN TAS256X_REG(0x0, 0x0, 0x31) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSDOUT_MASK (0x1 << 7) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSDOUT_DISABLED (0x0 << 7) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSDOUT_ENABLED (0x1 << 7) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSDIN_MASK (0x1 << 6) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSDIN_DISABLED (0x0 << 6) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSDIN_ENABLED (0x1 << 6) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNFSYNC_MASK (0x1 << 5) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNFSYNC_DISABLED (0x0 << 5) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNFSYNC_ENABLED (0x1 << 5) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSBCLK_MASK (0x1 << 4) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSBCLK_DISABLED (0x0 << 4) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSBCLK_ENABLED (0x1 << 4) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMD0_MASK (0x1 << 3) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMD0_DISABLED (0x0 << 3) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMD0_ENABLED (0x1 << 3) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMD1_MASK (0x1 << 2) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMD1_DISABLED (0x0 << 2) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMD1_ENABLED (0x1 << 2) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMCK0_MASK (0x1 << 1) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMCK0_DISABLED (0x0 << 1) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMCK0_ENABLED (0x1 << 1) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMCK1_MASK (0x1 << 0) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMCK1_DISABLED (0x0 << 0) +#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMCK1_ENABLED (0x1 << 0) + +/* Misc IRQ */ +#define TAS2562_MISCIRQ TAS256X_REG(0x0, 0x0, 0x32) +#define TAS2562_MISCIRQ_IRQZREQD_MASK (0x1 << 7) +#define TAS2562_MISCIRQ_IRQZREQD_ACTIVEHIGH (0x0 << 7) +#define TAS2562_MISCIRQ_IRQZREQD_ACTIVELOW (0x1 << 7) +#define TAS2562_MISCIRQ_IRQZBITBANG_MASK (0x1 << 0) +#define TAS2562_MISCIRQ_IRQZBITBANG_IRQZINPUTBUF0 (0x0 << 0) +#define TAS2562_MISCIRQ_IRQZBITBANG_IRQZINPUTBUF1 (0x1 << 0) + +#define TAS2562_BOOSTCONFIGURATION2 TAS256X_REG(0x0, 0x0, 0x34) +#define TAS2562_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_MASK (0x0f << 0) +#define TAS2562_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_SHIFT 0 +#define TAS2562_BOOSTCONFIGURATION4 (TAS256X_BOOSTCONFIGURATION4) +#define TAS2562_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_MASK \ + (TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_MASK) +#define TAS2562_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_SHIFT \ + (TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_SHIFT) + +#define TAS2562_BOOSTSLOPE (TAS256X_BOOSTSLOPE) +#define TAS2562_BOOSTSLOPE_MASK (TAS256X_BOOSTSLOPE_MASK) +#define TAS2562_BOOSTSLOPE_3AV (0x1 << 2) +#define TAS2562_BOOSTSLOPE_2AV (0x2 << 2) + +/* Clock Configuration */ +#define TAS2562_CLOCKCONFIGURATION (TAS256X_CLOCKCONFIGURATION) +#define TAS2562_CLOCKCONFIGURATION_SBCLKTOFS52_MASK \ + (TAS256X_CLOCKCONFIGURATION_SBCLKTOFS52_MASK) +#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_16 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_16) +#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_24 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_24) +#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_32 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_32) +#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_48 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_48) +#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_64 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_64) +#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_96 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_96) +#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_128 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_128) +#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_192 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_192) +#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_256 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_256) +#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_384 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_384) +#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_512 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_512) +#define TAS2562_CLOCKCONFIGURATION_DISCLKRATEDETECT10_MASK \ + (TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_MASK) +#define TAS2562_CLOCKCONFIGURATION_DISCLKRATEDETECT10_DISABLED \ + (TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_DISABLED) +#define TAS2562_CLOCKCONFIGURATION_DISCLKRATEDETECT10_ENABLED \ + (TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_ENABLED) + +#define TAS2562_VBATFILTER (TAS256X_VBATFILTER) +#define TAS2562_CLASSHRELEASETIMER (TAS256X_CLASSHRELEASETIMER) + +#define TAS2562_BOOST_CFG4 (TAS256X_BOOST_CFG4) +#define TAS2562_BOOST_CFG4_PEAK_CURRENT_LIMIT_MASK (0xff << 0) + +#define TAS2562_ICN_THRESHOLD_REG (TAS256X_ICN_THRESHOLD_REG) +#define TAS2562_ICN_HYSTERESIS_REG (TAS256X_ICN_HYSTERESIS_REG) + +#define TAS2562_ICN_SW_REG (TAS256X_ICN_SW_REG) +#define TAS2562_ICN_SW_MASK (TAS256X_ICN_SW_MASK) +#define TAS2562_ICN_SW_ENABLE (TAS256X_ICN_SW_ENABLE) +#define TAS2562_ICN_SW_DISABLE (TAS256X_ICN_SW_DISABLE) +#define TAS2562_TESTPAGECONFIGURATION (TAS256X_TESTPAGECONFIGURATION) +#define TAS2562_CLASSDCONFIGURATION1 (TAS256X_CLASSDCONFIGURATION1) +#define TAS2562_CLASSDCONFIGURATION2 (TAS256X_CLASSDCONFIGURATION2) +#define TAS2562_CLASSDCONFIGURATION3 (TAS256X_CLASSDCONFIGURATION3) +#define TAS2562_CLASSDCONFIGURATION4 (TAS256X_CLASSDCONFIGURATION4) +#define TAS2562_EFFICIENCYCONFIGURATION (TAS256X_EFFICIENCYCONFIGURATION) + +#define TAS2562_HPF (TAS256X_HPF) +#define TAS2562_CLASSHHEADROOM (TAS256X_CLASSHHEADROOM) +#define TAS2562_CLASSHHYSTERESIS (TAS256X_CLASSHHYSTERESIS) +#define TAS2562_CLASSHMTCT (TAS256X_CLASSHMTCT) + +/* Revision and PG ID */ +#define TAS2562_REVISIONANDPGID TAS256X_REG(0x0, 0x0, 0x7D) +#define TAS2562_REVISIONANDPGID_REVISIONID74_MASK (0xf << 4) +#define TAS2562_REVISIONANDPGID_PGID30_MASK (0xf << 0) + +/* I2C Checksum */ +#define TAS2562_I2CCHECKSUM TAS256X_REG(0x0, 0x0, 0x7E) +#define TAS2562_I2CCHECKSUM_I2CCHECKSUM70_MASK (0xff << 0) + +/* Book */ +#define TAS2562_BOOK (TAS256X_BOOK) +#define TAS2562_BOOK_BOOK70_MASK (TAS256X_BOOK_BOOK70_MASK) +#endif /* __TAS2562_ */ \ No newline at end of file diff --git a/techpack/audio/asoc/codecs/tas256x/tas2564.h b/techpack/audio/asoc/codecs/tas256x/tas2564.h new file mode 100644 index 000000000000..d42707f18ed7 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/tas2564.h @@ -0,0 +1,718 @@ +#ifndef __TAS2564_ +#define __TAS2564_ +/* Software Reset */ +#define TAS2564_SOFTWARERESET (TAS256X_SOFTWARERESET) +#define TAS2564_SOFTWARERESET_SOFTWARERESET_MASK \ + (TAS256X_SOFTWARERESET_SOFTWARERESET_MASK) +#define TAS2564_SOFTWARERESET_SOFTWARERESET_DONTRESET \ + (TAS256X_SOFTWARERESET_SOFTWARERESET_DONTRESET) +#define TAS2564_SOFTWARERESET_SOFTWARERESET_RESET \ + (TAS256X_SOFTWARERESET_SOFTWARERESET_RESET) + +/* Power Control */ +#define TAS2564_POWERCONTROL (TAS256X_POWERCONTROL) +//NEW Beging +#define TAS2564_POWERCONTROL_VSNS2_PD_MASK (0x1 << 7) +#define TAS2564_POWERCONTROL_VSNS2_PD_ACTIVE (0x0 << 7) +#define TAS2564_POWERCONTROL_VSNS2_PD_POWEREDDOWN (0x1 << 7) +//NEW End +#define TAS2564_POWERCONTROL_ISNSPOWER_MASK \ + (TAS256X_POWERCONTROL_ISNSPOWER_MASK) +#define TAS2564_POWERCONTROL_ISNSPOWER_ACTIVE \ + (TAS256X_POWERCONTROL_ISNSPOWER_ACTIVE) +#define TAS2564_POWERCONTROL_ISNSPOWER_POWEREDDOWN \ + (TAS256X_POWERCONTROL_ISNSPOWER_POWEREDDOWN) +#define TAS2564_POWERCONTROL_VSNSPOWER_MASK \ + (TAS256X_POWERCONTROL_VSNSPOWER_MASK) +#define TAS2564_POWERCONTROL_VSNSPOWER_ACTIVE \ + (TAS256X_POWERCONTROL_VSNSPOWER_ACTIVE) +#define TAS2564_POWERCONTROL_VSNSPOWER_POWEREDDOWN \ + (TAS256X_POWERCONTROL_VSNSPOWER_POWEREDDOWN) +#define TAS2564_POWERCONTROL_OPERATIONALMODE10_MASK \ + (TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK) +#define TAS2564_POWERCONTROL_OPERATIONALMODE10_ACTIVE \ + (TAS256X_POWERCONTROL_OPERATIONALMODE10_ACTIVE) +#define TAS2564_POWERCONTROL_OPERATIONALMODE10_MUTE \ + (TAS256X_POWERCONTROL_OPERATIONALMODE10_MUTE) +#define TAS2564_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN \ + (TAS256X_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN) + +/* Playback Configuration Reg0 */ +#define TAS2564_PLAYBACKCONFIGURATIONREG0 (TAS256X_PLAYBACKCONFIGURATIONREG0) +#define TAS2564_PLAYBACKCONFIGURATION_AMP_LEVEL_MASK (0x1F << 1) +#define TAS2564_AMP_LEVEL_16dBV (0x0D << 1) + +//NEW Begin +#define TAS2564_PLAYBACKCONFIGURATIONREG_RX_SPKR_MODE_MASK (0x1 << 7) +#define TAS2564_PLAYBACKCONFIGURATIONREG_SPKR_MODE (0x0 << 7) +#define TAS2564_PLAYBACKCONFIGURATIONREG_RX_MODE (0x1 << 7) +//NEW End +#define TAS2564_BOOSTCONFIGURATION2 TAS256X_REG(0x0, 0x0, 0x48) +#define TAS2564_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_MASK (0x1f << 3) +#define TAS2564_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_MASK_SHIFT 3 +#define TAS2564_BOOSTCONFIGURATION4 (TAS256X_BOOSTCONFIGURATION4) +#define TAS2564_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_MASK \ + (TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_MASK) +#define TAS2564_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_SHIFT \ + (TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_SHIFT) + +#define TAS2564_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_MASK \ + (TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_MASK) +#define TAS2564_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_ENABLED \ + (TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_ENABLED) +#define TAS2564_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_DISABLED \ + (TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_DISABLED) +#define TAS2564_PLAYBACKCONFIGURATIONREG0_AMPLIFIERLEVEL51_MASK (0x1f << 1) + +/* Misc Configuration Reg0 */ +#define TAS2564_MISCCONFIGURATIONREG0 (TAS256X_MISCCONFIGURATIONREG0) +#define TAS2564_MISCCONFIGURATIONREG0_CPPGRETRY_MASK \ + (TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_MASK) +#define TAS2564_MISCCONFIGURATIONREG0_CPPGRETRY_DONOTRETRY \ + (TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_DONOTRETRY) +#define TAS2564_MISCCONFIGURATIONREG0_CPPGRETRY_RETRY \ + (TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_RETRY) +#define TAS2564_MISCCONFIGURATIONREG0_VBATPRORETRY_MASK \ + (TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_MASK) +#define TAS2564_MISCCONFIGURATIONREG0_VBATPRORETRY_DONOTRETRY \ + (TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_DONOTRETRY) +#define TAS2564_MISCCONFIGURATIONREG0_VBATPRORETRY_RETRY \ + (TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_RETRY) +#define TAS2564_MISCCONFIGURATIONREG0_OCERETRY_MASK \ + (TAS256X_MISCCONFIGURATIONREG0_OCERETRY_MASK) +#define TAS2564_MISCCONFIGURATIONREG0_OCERETRY_DONOTRETRY \ + (TAS256X_MISCCONFIGURATIONREG0_OCERETRY_DONOTRETRY) +#define TAS2564_MISCCONFIGURATIONREG0_OCERETRY_RETRY \ + (TAS256X_MISCCONFIGURATIONREG0_OCERETRY_RETRY) +#define TAS2564_MISCCONFIGURATIONREG0_OTERETRY_MASK \ + (TAS256X_MISCCONFIGURATIONREG0_OTERETRY_MASK) +#define TAS2564_MISCCONFIGURATIONREG0_OTERETRY_DONOTRETRY \ + (TAS256X_MISCCONFIGURATIONREG0_OTERETRY_DONOTRETRY) +#define TAS2564_MISCCONFIGURATIONREG0_OTERETRY_RETRY \ + (TAS256X_MISCCONFIGURATIONREG0_OTERETRY_RETRY) +#define TAS2564_MISCCONFIGURATIONREG0_IRQZPULL_MASK \ + (TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_MASK) +#define TAS2564_MISCCONFIGURATIONREG0_IRQZPULL_DISABLED \ + (TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_DISABLED) +#define TAS2564_MISCCONFIGURATIONREG0_IRQZPULL_ENABLED \ + (TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_ENABLED) +#define TAS2564_MISCCONFIGURATIONREG0_AMPSS_MASK \ + (TAS256X_MISCCONFIGURATIONREG0_AMPSS_MASK) +#define TAS2564_MISCCONFIGURATIONREG0_AMPSS_DISABLED \ + (TAS256X_MISCCONFIGURATIONREG0_AMPSS_DISABLED) +#define TAS2564_MISCCONFIGURATIONREG0_AMPSS_ENABLED \ + (TAS256X_MISCCONFIGURATIONREG0_AMPSS_ENABLED) + +/* TDM Configuration Reg0 */ +#define TAS2564_TDMCONFIGURATIONREG0 (TAS256X_TDMCONFIGURATIONREG0) +#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK) +#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ) +#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ) +#define TAS2564_TDMCONFIGURATIONREG0_DETECTSAMPRATE_MASK \ + (TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_MASK) +#define TAS2564_TDMCONFIGURATIONREG0_DETECTSAMPRATE_DISABLED \ + (TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_DISABLED) +#define TAS2564_TDMCONFIGURATIONREG0_DETECTSAMPRATE_ENABLED \ + (TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_ENABLED) +#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATE31_MASK \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK) +#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATE31_14_7_16KHZ \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_14_7_16KHZ) +#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ) +#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ) +#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ \ + (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ) +#define TAS2564_TDMCONFIGURATIONREG0_FRAMESTART_MASK \ + (TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_MASK) +#define TAS2564_TDMCONFIGURATIONREG0_FRAMESTART_LOWTOHIGH \ + (TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_LOWTOHIGH) +#define TAS2564_TDMCONFIGURATIONREG0_FRAMESTART_HIGHTOLOW \ + (TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_HIGHTOLOW) + +/* TDM Configuration Reg1 */ +#define TAS2564_TDMCONFIGURATIONREG1 (TAS256X_TDMCONFIGURATIONREG1) +#define TAS2564_TDMCONFIGURATIONREG1_RXJUSTIFY_MASK \ + (TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_MASK) +#define TAS2564_TDMCONFIGURATIONREG1_RXJUSTIFY_LEFT \ + (TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_LEFT) +#define TAS2564_TDMCONFIGURATIONREG1_RXJUSTIFY_RIGHT \ + (TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_RIGHT) +#define TAS2564_TDMCONFIGURATIONREG1_RXOFFSET51_MASK \ + (TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_MASK) +#define TAS2564_TDMCONFIGURATIONREG1_RXOFFSET51_SHIFT \ + (TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_SHIFT) +#define TAS2564_TDMCONFIGURATIONREG1_RXEDGE_MASK \ + (TAS256X_TDMCONFIGURATIONREG1_RXEDGE_MASK) +#define TAS2564_TDMCONFIGURATIONREG1_RXEDGE_RISING \ + (TAS256X_TDMCONFIGURATIONREG1_RXEDGE_RISING) +#define TAS2564_TDMCONFIGURATIONREG1_RXEDGE_FALLING \ + (TAS256X_TDMCONFIGURATIONREG1_RXEDGE_FALLING) + +/* TDM Configuration Reg2 */ +#define TAS2564_TDMCONFIGURATIONREG2 (TAS256X_TDMCONFIGURATIONREG2) +#define TAS2564_TDMCONFIGURATIONREG2_IVLEN76_MASK \ + (TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK) +#define TAS2564_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS \ + (TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS) +#define TAS2564_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS \ + (TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS) +#define TAS2564_TDMCONFIGURATIONREG2_IVLENCFG76_8BITS \ + (TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_8BITS) +#define TAS2564_TDMCONFIGURATIONREG2_IVMONLEN76_MASK \ + (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_MASK) +#define TAS2564_TDMCONFIGURATIONREG2_IVMONLEN76_8BITS \ + (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_8BITS) +#define TAS2564_TDMCONFIGURATIONREG2_IVMONLEN76_12BITS \ + (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_12BITS) +#define TAS2564_TDMCONFIGURATIONREG2_IVMONLEN76_16BITS \ + (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_16BITS) +#define TAS2564_TDMCONFIGURATIONREG2_RXSCFG54_MASK \ + (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MASK) +#define TAS2564_TDMCONFIGURATIONREG2_RXSCFG54_MONO_I2C \ + (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_I2C) +#define TAS2564_TDMCONFIGURATIONREG2_RXSCFG54_MONO_LEFT \ + (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_LEFT) +#define TAS2564_TDMCONFIGURATIONREG2_RXSCFG54_MONO_RIGHT \ + (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_RIGHT) +#define TAS2564_TDMCONFIGURATIONREG2_RXSCFG54_STEREO_DOWNMIX \ + (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_STEREO_DOWNMIX) +#define TAS2564_TDMCONFIGURATIONREG2_RXWLEN32_MASK \ + (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_MASK) +#define TAS2564_TDMCONFIGURATIONREG2_RXWLEN32_16BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_16BITS) +#define TAS2564_TDMCONFIGURATIONREG2_RXWLEN32_20BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_20BITS) +#define TAS2564_TDMCONFIGURATIONREG2_RXWLEN32_24BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_24BITS) +#define TAS2564_TDMCONFIGURATIONREG2_RXWLEN32_32BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_32BITS) +#define TAS2564_TDMCONFIGURATIONREG2_RXSLEN10_MASK \ + (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_MASK) +#define TAS2564_TDMCONFIGURATIONREG2_RXSLEN10_16BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_16BITS) +#define TAS2564_TDMCONFIGURATIONREG2_RXSLEN10_24BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_24BITS) +#define TAS2564_TDMCONFIGURATIONREG2_RXSLEN10_32BITS \ + (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_32BITS) + +/* TDM Configuration Reg3 */ +#define TAS2564_TDMCONFIGURATIONREG3 TAS256X_REG(0x0, 0x0, 0x09) +#define TAS2564_TDMCONFIGURATIONREG3_RXSLOTRIGHT74_MASK (0xf << 4) +#define TAS2564_TDMCONFIGURATIONREG3_RXSLOTLeft30_Mask (0xf << 0) + +/* TDM Configuration Reg4 */ +#define TAS2564_TDMConfigurationReg4 (TAS256X_TDMConfigurationReg4) +#define TAS2564_TDMCONFIGURATIONREG4_TXKEEPER_MASK \ + (TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_MASK) +#define TAS2564_TDMCONFIGURATIONREG4_TXKEEPER_DISABLE \ + (TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_DISABLE) +#define TAS2564_TDMCONFIGURATIONREG4_TXKEEPER_ENABLE \ + (TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_ENABLE) +#define TAS2564_TDMCONFIGURATIONREG4_TXFILL_MASK \ + (TAS256X_TDMCONFIGURATIONREG4_TXFILL_MASK) +#define TAS2564_TDMCONFIGURATIONREG4_TXFILL_TRANSMIT0 \ + (TAS256X_TDMCONFIGURATIONREG4_TXFILL_TRANSMIT0) +#define TAS2564_TDMCONFIGURATIONREG4_TXFILL_TRANSMITHIZ \ + (TAS256X_TDMCONFIGURATIONREG4_TXFILL_TRANSMITHIZ) +#define TAS2564_TDMCONFIGURATIONREG4_TXOFFSET31_MASK \ + (TAS256X_TDMCONFIGURATIONREG4_TXOFFSET31_MASK) +#define TAS2564_TDMCONFIGURATIONREG4_TXEDGE_MASK \ + (TAS256X_TDMCONFIGURATIONREG4_TXEDGE_MASK) +#define TAS2564_TDMCONFIGURATIONREG4_TXEDGE_RISING \ + (TAS256X_TDMCONFIGURATIONREG4_TXEDGE_RISING) +#define TAS2564_TDMCONFIGURATIONREG4_TXEDGE_FALLING \ + (TAS256X_TDMCONFIGURATIONREG4_TXEDGE_FALLING) + +/* TDM Configuration Reg5 */ +#define TAS2564_TDMCONFIGURATIONREG5 (TAS256X_TDMCONFIGURATIONREG5) +#define TAS2564_TDMCONFIGURATIONREG5_VSNSTX_MASK \ + (TAS256X_TDMCONFIGURATIONREG5_VSNSTX_MASK) +#define TAS2564_TDMCONFIGURATIONREG5_VSNSTX_DISABLE \ + (TAS256X_TDMCONFIGURATIONREG5_VSNSTX_DISABLE) +#define TAS2564_TDMCONFIGURATIONREG5_VSNSTX_ENABLE \ + (TAS256X_TDMCONFIGURATIONREG5_VSNSTX_ENABLE) +#define TAS2564_TDMCONFIGURATIONREG5_VSNSSLOT50_MASK \ + (TAS256X_TDMCONFIGURATIONREG5_VSNSSLOT50_MASK) + +/* TDM Configuration Reg6 */ +#define TAS2564_TDMCONFIGURATIONREG6 (TAS256X_TDMCONFIGURATIONREG6) +#define TAS2564_TDMCONFIGURATIONREG6_ISNSTX_MASK \ + (TAS256X_TDMCONFIGURATIONREG6_ISNSTX_MASK) +#define TAS2564_TDMCONFIGURATIONREG6_ISNSTX_DISABLE \ + (TAS256X_TDMCONFIGURATIONREG6_ISNSTX_DISABLE) +#define TAS2564_TDMCONFIGURATIONREG6_ISNSTX_ENABLE \ + (TAS256X_TDMCONFIGURATIONREG6_ISNSTX_ENABLE) +#define TAS2564_TDMCONFIGURATIONREG6_ISNSSLOT50_MASK \ + (TAS256X_TDMCONFIGURATIONREG6_ISNSSLOT50_MASK) + +/* TDM Configuration Reg7 */ +#define TAS2564_TDMCONFIGURATIONREG7 (TAS256X_TDMCONFIGURATIONREG7) +#define TAS2564_TDMCONFIGURATIONREG7_VBATSLEN_MASK \ + (TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_MASK) +#define TAS2564_TDMCONFIGURATIONREG7_VBATSLEN_8BITS \ + (TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_8BITS) +#define TAS2564_TDMCONFIGURATIONREG7_VBATSLEN_16BITS \ + (TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_16BITS) +#define TAS2564_TDMCONFIGURATIONREG7_VBATTX_MASK \ + (TAS256X_TDMCONFIGURATIONREG7_VBATTX_MASK) +#define TAS2564_TDMCONFIGURATIONREG7_VBATTX_DISABLE \ + (TAS256X_TDMCONFIGURATIONREG7_VBATTX_DISABLE) +#define TAS2564_TDMCONFIGURATIONREG7_VBATTX_ENABLE \ + (TAS256X_TDMCONFIGURATIONREG7_VBATTX_ENABLE) +#define TAS2564_TDMCONFIGURATIONREG7_VBATSLOT50_MASK \ + (TAS256X_TDMCONFIGURATIONREG7_VBATSLOT50_MASK) + +/* TDM Configuration Reg8 */ +#define TAS2564_TDMCONFIGURATIONREG8 TAS256X_REG(0x0, 0x0, 0x0E) +#define TAS2564_TDMCONFIGURATIONREG8_TEMPTX_MASK (0x1 << 6) +#define TAS2564_TDMCONFIGURATIONREG8_TEMPTX_DISABLE (0x0 << 6) +#define TAS2564_TDMCONFIGURATIONREG8_TEMPTX_ENABLE (0x1 << 6) +#define TAS2564_TDMCONFIGURATIONREG8_TEMPSLOT50_MASK (0x3f << 0) + +/* TDM Configuration Reg9 */ +#define TAS2564_TDMCONFIGURATIONREG9 TAS256X_REG(0x0, 0x0, 0x0F) +#define TAS2564_TDMCONFIGURATIONREG9_GAINTX_MASK (0x1 << 6) +#define TAS2564_TDMCONFIGURATIONREG9_GAINTX_DISABLE (0x0 << 6) +#define TAS2564_TDMCONFIGURATIONREG9_GAINTX_ENABLE (0x1 << 6) +#define TAS2564_TDMCONFIGURATIONREG9_GAINSLOT50_MASK (0x3f << 0) + +/* Limiter Configuration Reg0 */ +#define TAS2564_LIMITERCONFIGURATIONREG0 TAS256X_REG(0x0, 0x0, 0x12) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKST54_MASK (0x3 << 4) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKST54_1 (0x2 << 4) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKST54_2 (0x3 << 4) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKST54_0_25 (0x0 << 4) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKST54_0_5 (0x1 << 4) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_MASK (0x7 << 1) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_5 (0x0 << 1) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_10 (0x1 << 1) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_20 (0x2 << 1) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_40 (0x3 << 1) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_80 (0x4 << 1) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_160 (0x5 << 1) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_320 (0x6 << 1) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_640 (0x7 << 1) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMEN_MASK (0x1 << 0) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMEN_DISABLED (0x0 << 0) +#define TAS2564_LIMITERCONFIGURATIONREG0_LIMEN_ENABLED (0x1 << 0) + +/* Limiter Configuration Reg1 */ +#define TAS2564_LIMITERCONFIGURATIONREG1 TAS256X_REG(0x0, 0x0, 0x13) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSST76_MASK (0x3 << 6) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSST76_1 (0x2 << 6) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSST76_2 (0x3 << 6) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSST76_0_25 (0x0 << 6) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSST76_0_5 (0x1 << 6) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_MASK (0x7 << 3) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_10 (0x0 << 3) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_50 (0x1 << 3) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_100 (0x2 << 3) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_250 (0x3 << 3) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_500 (0x4 << 3) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_750 (0x5 << 3) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_1000 (0x6 << 3) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_1500 (0x7 << 3) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_MASK (0x7 << 0) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_0 (0x0 << 0) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_10 (0x1 << 0) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_25 (0x2 << 0) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_50 (0x3 << 0) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_100 (0x4 << 0) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_250 (0x5 << 0) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_500 (0x6 << 0) +#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_1000 (0x7 << 0) + +/* Brown Out Prevention Reg0 */ +#define TAS2564_BROWNOUTPREVENTIONREG0 TAS256X_REG(0x0, 0x0, 0x14) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPSDEN_MASK (0x1 << 4) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPSDEN_DISABLED (0x0 << 4) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPSDEN_ENABLED (0x1 << 4) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPHLDCLR_MASK (0x1 << 3) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPHLDCLR_DONTCLEAR (0x0 << 3) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPHLDCLR_CLEAR (0x1 << 3) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPINFHLD_MASK (0x1 << 2) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPINFHLD_USEHOLDTIME (0x0 << 2) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPINFHLD_HOLDUNTILCLEARED (0x1 << 2) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPMUTE_MASK (0x1 << 1) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPMUTE_DONOTMUTE (0x0 << 1) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPMUTE_MUTE (0x1 << 1) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPEN_MASK (0x1 << 0) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPEN_DISABLED (0x0 << 0) +#define TAS2564_BROWNOUTPREVENTIONREG0_BOPEN_ENABLED (0x1 << 0) + +/* Brown Out Prevention Reg1 */ +#define TAS2564_BROWNOUTPREVENTIONREG1 TAS256X_REG(0x0, 0x0, 0x15) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_MASK (0x7 << 5) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_1 (0x0 << 5) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_2 (0x1 << 5) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_4 (0x2 << 5) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_8 (0x3 << 5) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_16 (0x4 << 5) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_32 (0x5 << 5) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_64 (0x6 << 5) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_128 (0x7 << 5) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKST43_MASK (0x3 << 3) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKST43_1 (0x1 << 3) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKST43_2 (0x3 << 3) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKST43_0_5 (0x0 << 3) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKST43_1_5 (0x2 << 3) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_MASK (0x7 << 0) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_0 (0x0 << 0) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_10 (0x1 << 0) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_25 (0x2 << 0) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_50 (0x3 << 0) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_100 (0x4 << 0) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_250 (0x5 << 0) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_500 (0x6 << 0) +#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_1000 (0x7 << 0) + +/* Interrupt Mask Reg0 */ +#define TAS2564_INTERRUPTMASKREG0 (TAS256X_INTERRUPTMASKREG0) +#define TAS2564_INTERRUPTMASKREG0_LIMMUTEINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_MASK) +#define TAS2564_INTERRUPTMASKREG0_LIMMUTEINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_UNMASK) +#define TAS2564_INTERRUPTMASKREG0_LIMMUTEINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_DISABLE) +#define TAS2564_INTERRUPTMASKREG0_LIMINFHLDINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_MASK) +#define TAS2564_INTERRUPTMASKREG0_LIMINFHLDINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_UNMASK) +#define TAS2564_INTERRUPTMASKREG0_LIMINFHLDINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_DISABLE) +#define TAS2564_INTERRUPTMASKREG0_LIMMAXATNINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_MASK) +#define TAS2564_INTERRUPTMASKREG0_LIMMAXATNINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_UNMASK) +#define TAS2564_INTERRUPTMASKREG0_LIMMAXATNINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_DISABLE) +#define TAS2564_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_MASK) +#define TAS2564_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_UNMASK) +#define TAS2564_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_DISABLE) +#define TAS2564_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_MASK) +#define TAS2564_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_UNMASK) +#define TAS2564_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_DISABLE) +#define TAS2564_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_MASK) +#define TAS2564_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_UNMASK) +#define TAS2564_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_DISABLE) +#define TAS2564_INTERRUPTMASKREG0_OCEINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_OCEINTMASK_MASK) +#define TAS2564_INTERRUPTMASKREG0_OCEINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_OCEINTMASK_UNMASK) +#define TAS2564_INTERRUPTMASKREG0_OCEINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_OCEINTMASK_DISABLE) +#define TAS2564_INTERRUPTMASKREG0_OTEINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG0_OTEINTMASK_MASK) +#define TAS2564_INTERRUPTMASKREG0_OTEINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG0_OTEINTMASK_UNMASK) +#define TAS2564_INTERRUPTMASKREG0_OTEINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG0_OTEINTMASK_DISABLE) +#define TAS2564_INTERRUPTMASKREG0_DISABLE (TAS256X_INTERRUPTMASKREG0_DISABLE) + +/* Interrupt Mask Reg1 */ +#define TAS2564_INTERRUPTMASKREG1 (TAS256X_INTERRUPTMASKREG1) +#define TAS2564_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_MASK) +#define TAS2564_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_UNMASK) +#define TAS2564_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_DISABLE) +#define TAS2564_INTERRUPTMASKREG1_CRCINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG1_CRCINTMASK_MASK) +#define TAS2564_INTERRUPTMASKREG1_CRCINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG1_CRCINTMASK_UNMASK) +#define TAS2564_INTERRUPTMASKREG1_CRCINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG1_CRCINTMASK_DISABLE) +#define TAS2564_INTERRUPTMASKREG1_VBATOVLOINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_MASK) +#define TAS2564_INTERRUPTMASKREG1_VBATOVLOINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_UNMASK) +#define TAS2564_INTERRUPTMASKREG1_VBATOVLOINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_DISABLE) +#define TAS2564_INTERRUPTMASKREG1_VBATUVLOINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_MASK) +#define TAS2564_INTERRUPTMASKREG1_VBATUVLOINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_UNMASK) +#define TAS2564_INTERRUPTMASKREG1_VBATUVLOINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_DISABLE) +#define TAS2564_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_MASK \ + (TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_MASK) +#define TAS2564_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_UNMASK \ + (TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_UNMASK) +#define TAS2564_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_DISABLE \ + (TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_DISABLE) +#define TAS2564_INTERRUPTMASKREG1_DISABLE (TAS256X_INTERRUPTMASKREG1_DISABLE) + +/* Interrupt Mask Reg2 */ +#define TAS2564_INTERRUPTMASKREG2 TAS256X_REG(0x0, 0x0, 0x1C) +#define TAS2564_INTERRUPTMASKREG2_DACLKINTMASK_MASK (0x1 << 7) +#define TAS2564_INTERRUPTMASKREG2_DACLKINTMASK_UNMASK (0x0 << 7) +#define TAS2564_INTERRUPTMASKREG2_DACLKINTMASK_DISABLE (0x1 << 7) +#define TAS2564_INTERRUPTMASKREG2_BSTCLKINTMASK_MASK (0x1 << 6) +#define TAS2564_INTERRUPTMASKREG2_BSTCLKINTMASK_UNMASK (0x0 << 6) +#define TAS2564_INTERRUPTMASKREG2_BSTCLKINTMASK_DISABLE (0x1 << 6) +#define TAS2564_INTERRUPTMASKREG2_VBATPORCLKINTMASK_MASK (0x1 << 5) +#define TAS2564_INTERRUPTMASKREG2_VBATPORCLKINTMASK_UNMASK (0x0 << 5) +#define TAS2564_INTERRUPTMASKREG2_VBATPORCLKINTMASK_DISABLE (0x1 << 5) +#define TAS2564_INTERRUPTMASKREG2_PLLOCKINTMASK_MASK (0x1 << 4) +#define TAS2564_INTERRUPTMASKREG2_PLLOCKINTMASK_UNMASK (0x0 << 4) +#define TAS2564_INTERRUPTMASKREG2_PLLOCKINTMASK_DISABLE (0x1 << 4) +#define TAS2564_INTERRUPTMASKREG2_DCDETECTINTMASK_MASK (0x1 << 3) +#define TAS2564_INTERRUPTMASKREG2_DCDETECTINTMASK_UNMASK (0x0 << 3) +#define TAS2564_INTERRUPTMASKREG2_DCDETECTINTMASK_DISABLE (0x1 << 3) + +//NEW Begin +/* Interrupt Mask Reg4 */ +#define TAS2564_INTERRUPTMASKREG4 TAS256X_REG(0x0, 0x0, 0x1E) +#define TAS2564_INTERRUPTMASKREG4_DSP_DC_DETECT_FLAG_MASK (0x1 << 7) +#define TAS2564_INTERRUPTMASKREG4_DSP_DC_DETECT_FLAG_UNMASK (0x0 << 7) +#define TAS2564_INTERRUPTMASKREG4_DSP_DC_DETECT_FLAG_DISABLE (0x1 << 7) +//NEW End + +/* Latched-Interrupt Reg0 */ +#define TAS2564_LATCHEDINTERRUPTREG0 (TAS256X_LATCHEDINTERRUPTREG0) +#define TAS2564_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_MASK) +#define TAS2564_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_NOINTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_INTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_MASK) +#define TAS2564_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_NOINTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_INTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_MASK) +#define TAS2564_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_NOINTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_INTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_MASK) +#define TAS2564_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_NOINTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_INTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_MASK) +#define TAS2564_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_NOINTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_INTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_MASK) +#define TAS2564_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_NOINTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_INTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_MASK) +#define TAS2564_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_NOINTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_INTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_MASK) +#define TAS2564_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_NOINTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_INTERRUPT) + +/* Latched-Interrupt Reg1 */ +#define TAS2564_LATCHEDINTERRUPTREG1 (TAS256X_LATCHEDINTERRUPTREG1) +#define TAS2564_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_MASK) +#define TAS2564_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_NOINTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_INTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_MASK) +#define TAS2564_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_NOINTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_INTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_MASK) +#define TAS2564_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_NOINTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_INTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_MASK) +#define TAS2564_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_NOINTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_INTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_MASK \ + (TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_MASK) +#define TAS2564_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_NOINTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_NOINTERRUPT) +#define TAS2564_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_INTERRUPT \ + (TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_INTERRUPT) + +//NEW Begin +/* Latched-Interrupt Reg4 */ +#define TAS2564_LATCHEDINTERRUPTREG4 TAS256X_REG(0x0, 0x0, 0x28) +#define TAS2564_LATCHEDINTERRUPTREG4_DSP_DC_DETECT_FLAG_MASK (0x1 << 7) +#define TAS2564_LATCHEDINTERRUPTREG4_DSP_DC_DETECT_FLAG_UNMASK (0x0 << 7) +#define TAS2564_LATCHEDINTERRUPTREG4_DSP_DC_DETECT_FLAG_DISABLE (0x1 << 7) +//NEW End + +/* VBAT MSB */ +#define TAS2564_VBATMSB TAS256X_REG(0x0, 0x0, 0x2A) +#define TAS2564_VBATMSB_VBATMSB70_MASK (0xff << 0) + +/* VBAT LSB */ +#define TAS2564_VBATLSB TAS256X_REG(0x0, 0x0, 0x2B) +#define TAS2564_VBATLSB_VBATLSB74_MASK (0xf << 4) + +/* TEMP */ +#define TAS2564_TEMP TAS256X_REG(0x0, 0x0, 0x2C) +#define TAS2564_TEMP_TEMPMSB70_MASK (0xff << 0) + +/* Interrupt Configuration */ +#define TAS2564_INTERRUPTCONFIGURATION (TAS256X_INTERRUPTCONFIGURATION) +#define TAS2564_INTERRUPTCONFIGURATION_LTCHINTCLEAR_MASK \ + (TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR_MASK) +#define TAS2564_INTERRUPTCONFIGURATION_LTCHINTCLEAR \ + (TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR) +#define TAS2564_INTERRUPTCONFIGURATION_PININTCONFIG10_MASK \ + (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_MASK) +#define TAS2564_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLIVEINTERRUPTS \ + (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLIVEINTERRUPTS) +#define TAS2564_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLATCHEDINTERRUPTS \ + (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLATCHEDINTERRUPTS) +#define TAS2564_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLIVEINTERRUPTS \ + (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLIVEINTERRUPTS) +#define TAS2564_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLATCHEDINTERRUPTS \ + (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLATCHEDINTERRUPTS) + +/* Digital Input Pin Pull Down */ +//NEW Begin +#define TAS2564_DIGITALINPUTPINPULLDOWN TAS256X_REG(0x0, 0x0, 0x31) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_AD1_MASK (0x1 << 5) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_AD1_DISABLED (0x0 << 5) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_AD1_ENABLED (0x1 << 5) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_AD0_MASK (0x1 << 4) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_AD0_DISABLED (0x0 << 4) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_AD0_ENABLED (0x1 << 4) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SDOUT_MASK (0x1 << 3) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SDOUT_DISABLED (0x0 << 3) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SDOUT_ENABLED (0x1 << 3) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SDIN_MASK (0x1 << 2) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SDIN_DISABLED (0x0 << 2) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SDIN_ENABLED (0x1 << 2) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_FSYNC_MASK (0x1 << 1) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_FSYNC_DISABLED (0x0 << 1) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_FSYNC_ENABLED (0x1 << 1) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SBCLK_MASK (0x1 << 0) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SBCLK_DISABLED (0x0 << 0) +#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SBCLK_ENABLED (0x1 << 0) +//NEW End + +/* Misc IRQ */ +#define TAS2564_MISCIRQ TAS256X_REG(0x0, 0x0, 0x32) +#define TAS2564_MISCIRQ_IRQZREQD_MASK (0x1 << 7) +#define TAS2564_MISCIRQ_IRQZREQD_ACTIVEHIGH (0x0 << 7) +#define TAS2564_MISCIRQ_IRQZREQD_ACTIVELOW (0x1 << 7) +#define TAS2564_MISCIRQ_IRQZBITBANG_MASK (0x1 << 0) +#define TAS2564_MISCIRQ_IRQZBITBANG_IRQZINPUTBUF0 (0x0 << 0) +#define TAS2564_MISCIRQ_IRQZBITBANG_IRQZINPUTBUF1 (0x1 << 0) + +#define TAS2564_BOOSTSLOPE (TAS256X_BOOSTSLOPE) +#define TAS2564_BOOSTSLOPE_MASK (TAS256X_BOOSTSLOPE_MASK) +#define TAS2564_BOOSTSLOPE_3DOT67AV (0x1 << 2) +#define TAS2564_BOOSTSLOPE_2DOT93AV (0x2 << 2) + +/* Clock Configuration */ +#define TAS2564_CLOCKCONFIGURATION (TAS256X_CLOCKCONFIGURATION) +#define TAS2564_CLOCKCONFIGURATION_SBCLKTOFS52_MASK \ + (TAS256X_CLOCKCONFIGURATION_SBCLKTOFS52_MASK) +#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_16 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_16) +#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_24 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_24) +#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_32 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_32) +#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_48 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_48) +#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_64 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_64) +#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_96 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_96) +#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_128 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_128) +#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_192 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_192) +#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_256 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_256) +#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_384 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_384) +#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_512 \ + (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_512) +#define TAS2564_CLOCKCONFIGURATION_DISCLKRATEDETECT10_MASK \ + (TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_MASK) +#define TAS2564_CLOCKCONFIGURATION_DISCLKRATEDETECT10_DISABLED \ + (TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_DISABLED) +#define TAS2564_CLOCKCONFIGURATION_DISCLKRATEDETECT10_ENABLED \ + (TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_ENABLED) + +#define TAS2564_VBATFILTER (TAS256X_VBATFILTER) +#define TAS2564_CLASSHRELEASETIMER (TAS256X_CLASSHRELEASETIMER) + +#define TAS2564_BOOST_CFG4 (TAS256X_BOOST_CFG4) +#define TAS2564_BOOST_CFG4_PEAK_CURRENT_LIMIT_MASK (0x3f << 0) + +#define TAS2564_BOOST_CFG5 TAS256X_REG(0x0, 0x0, 0x48) +#define TAS2564_BOOST_CFG5_BOOSTMAXVOLTAGE_MASK (0x1f << 3) +#define TAS2564_BOOST_CFG5_BOOSTMAXVOLTAGE_6V (0x7 << 3) + +#define TAS2564_ICN_THRESHOLD_REG (TAS256X_ICN_THRESHOLD_REG) +#define TAS2564_ICN_HYSTERESIS_REG (TAS256X_ICN_HYSTERESIS_REG) + +#define TAS2564_ICN_SW_REG (TAS256X_ICN_SW_REG) +#define TAS2564_ICN_SW_MASK (TAS256X_ICN_SW_MASK) +#define TAS2564_ICN_SW_ENABLE (TAS256X_ICN_SW_ENABLE) +#define TAS2564_ICN_SW_DISABLE (TAS256X_ICN_SW_DISABLE) +#define TAS2564_TESTPAGECONFIGURATION (TAS256X_TESTPAGECONFIGURATION) +#define TAS2564_CLASSDCONFIGURATION1 (TAS256X_CLASSDCONFIGURATION1) +#define TAS2564_CLASSDCONFIGURATION2 (TAS256X_CLASSDCONFIGURATION2) +#define TAS2564_CLASSDCONFIGURATION3 (TAS256X_CLASSDCONFIGURATION3) +#define TAS2564_CLASSDCONFIGURATION4 (TAS256X_CLASSDCONFIGURATION4) +#define TAS2564_EFFICIENCYCONFIGURATION (TAS256X_EFFICIENCYCONFIGURATION) + +#define TAS2564_HPF (TAS256X_HPF) +#define TAS2564_CLASSHHEADROOM (TAS256X_CLASSHHEADROOM) +#define TAS2564_CLASSHHYSTERESIS (TAS256X_CLASSHHYSTERESIS) +#define TAS2564_CLASSHMTCT (TAS256X_CLASSHMTCT) + +/* Revision and PG ID */ +#define TAS2564_REVISIONANDPGID TAS256X_REG(0x0, 0x0, 0x7D) +#define TAS2564_REVISIONANDPGID_REVISIONID74_MASK (0xf << 4) +#define TAS2564_REVISIONANDPGID_PGID30_MASK (0xf << 0) + +/* I2C Checksum */ +#define TAS2564_I2CCHECKSUM TAS256X_REG(0x0, 0x0, 0x7E) +#define TAS2564_I2CCHECKSUM_I2CCHECKSUM70_MASK (0xff << 0) + +/* Book */ +#define TAS2564_BOOK (TAS256X_BOOK) +#define TAS2564_BOOK_BOOK70_MASK (TAS256X_BOOK_BOOK70_MASK) +#endif /* __TAS2564_ */ \ No newline at end of file diff --git a/techpack/audio/asoc/codecs/tas256x/tas256x-codec.c b/techpack/audio/asoc/codecs/tas256x/tas256x-codec.c new file mode 100644 index 000000000000..b95e7e03a3ca --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/tas256x-codec.c @@ -0,0 +1,1956 @@ +/* + * ============================================================================= + * Copyright (c) 2016 Texas Instruments Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * 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; version 2. + * + * 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. + * + * File: + * tas256x-codec.c + * + * Description: + * ALSA SoC driver for Texas Instruments TAS256X High Performance 4W Smart + * Amplifier + * + * ============================================================================= + */ + +#ifdef CONFIG_TAS256X_CODEC +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tas256x.h" +#include "tas256x-device.h" +#ifdef CONFIG_TAS25XX_ALGO +#ifdef CONFIG_PLATFORM_EXYNOS +#include +#else +#include +#endif /*CONFIG_PLATFORM_EXYNOS*/ +#include "tas25xx-calib.h" +#endif /*CONFIG_TAS25XX_ALGO*/ + +#define TAS256X_MDELAY 0xFFFFFFFE +#define TAS256X_MSLEEP 0xFFFFFFFD +#define TAS256X_IVSENSER_ENABLE 1 +#define TAS256X_IVSENSER_DISABLE 0 +/* #define TAS2558_CODEC */ + +static char const *iv_enable_text[] = { "Off", "On" }; + +static const struct soc_enum tas256x_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(iv_enable_text), iv_enable_text), +}; +static int tas256x_set_fmt(struct tas256x_priv *p_tas256x, unsigned int fmt); +static int tas256x_system_mute_ctrl_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue); +static int tas256x_system_mute_ctrl_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue); +static int tas256x_mute_ctrl_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue); +static int tas256x_mute_ctrl_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue); + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE +static unsigned int tas256x_codec_read(struct snd_soc_component *codec, + unsigned int reg) +{ + unsigned int value = 0; + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); + int ret = 0; + + switch (reg) { + case TAS256X_LEFT_SWITCH: + value = p_tas256x->devs[0]->spk_control; + break; + case TAS256X_RIGHT_SWITCH: + value = p_tas256x->devs[1]->spk_control; + break; + case RX_SCFG_LEFT: + value = p_tas256x->devs[0]->rx_cfg; + break; + case RX_SCFG_RIGHT: + value = p_tas256x->devs[1]->rx_cfg; + break; + default: + ret = p_tas256x->read(p_tas256x, channel_left, reg, &value); + break; + } + + dev_dbg(p_tas256x->dev, "%s, reg=%d, value=%d", __func__, reg, value); + + if (ret == 0) + return value; + else + return ret; +} +#else +static unsigned int tas256x_codec_read(struct snd_soc_codec *codec, + unsigned int reg) +{ + unsigned int value = 0; + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); + + int ret = 0; + + switch (reg) { + case TAS256X_LEFT_SWITCH: + value = p_tas256x->devs[0]->spk_control; + break; + case TAS256X_RIGHT_SWITCH: + value = p_tas256x->devs[1]->spk_control; + break; + case RX_SCFG_LEFT: + value = p_tas256x->devs[0]->rx_cfg; + break; + case RX_SCFG_RIGHT: + value = p_tas256x->devs[1]->rx_cfg; + break; + default: + ret = p_tas256x->read(p_tas256x, channel_left, reg, &value); + break; + } + + dev_dbg(p_tas256x->dev, "%s, reg=%d, value=%d", __func__, reg, value); + + if (ret == 0) + return value; + else + return ret; + + return value; +} +#endif + +static int tas256xiv_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); +#endif + struct tas256x_priv *p_tas256x = NULL; + int iv_enable = 0, n_result = 0; + + if (codec == NULL) { + pr_err("%s:codec is NULL\n", __func__); + return 0; + } + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + p_tas256x = snd_soc_component_get_drvdata(codec); +#else + p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + if (p_tas256x == NULL) { + pr_err("%s:p_tas256x is NULL\n", __func__); + return 0; + } + + iv_enable = ucontrol->value.integer.value[0]; + + n_result = + tas256x_iv_sense_enable_set(p_tas256x, iv_enable, channel_both); + + pr_debug("%s: tas256x->iv_enable = %d\n", __func__, + p_tas256x->iv_enable); + + return n_result; +} + +static int tas256xiv_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); +#endif + struct tas256x_priv *p_tas256x = NULL; + + if (codec == NULL) { + pr_err("%s:codec is NULL\n", __func__); + return 0; + } + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + p_tas256x = snd_soc_component_get_drvdata(codec); +#else + p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + if (p_tas256x == NULL) { + pr_err("%s:p_tas256x is NULL\n", __func__); + return 0; + } + + ucontrol->value.integer.value[0] = + tas256x_iv_sense_enable_get(p_tas256x, channel_left); + p_tas256x->iv_enable = ucontrol->value.integer.value[0]; + + dev_info(p_tas256x->dev, "p_tas256x->iv_enable %d\n", + p_tas256x->iv_enable); + + return 0; +} + +static const struct snd_kcontrol_new tas256x_controls[] = { + SOC_ENUM_EXT("TAS256X IVSENSE ENABLE", tas256x_enum[0], tas256xiv_get, + tas256xiv_put), +}; + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE +static int tas256x_codec_write(struct snd_soc_component *codec, + unsigned int reg, unsigned int value) +{ + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); + int ret = 0; + + dev_dbg(p_tas256x->dev, "%s: %d, %d", __func__, reg, value); + + switch (reg) { + case TAS256X_LEFT_SWITCH: + p_tas256x->devs[0]->spk_control = value; + break; + case TAS256X_RIGHT_SWITCH: + p_tas256x->devs[1]->spk_control = value; + break; + case RX_SCFG_LEFT: + ret = tas256x_update_rx_cfg(p_tas256x, value, channel_left); + break; + case RX_SCFG_RIGHT: + ret = tas256x_update_rx_cfg(p_tas256x, value, channel_right); + break; + default: + ret = p_tas256x->write(p_tas256x, channel_both, reg, value); + break; + } + + return ret; +} +#else +static int tas256x_codec_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + dev_dbg(p_tas256x->dev, "%s: %d, %d", __func__, reg, value); + + switch (reg) { + case TAS256X_LEFT_SWITCH: + p_tas256x->devs[0]->spk_control = value; + break; + case TAS256X_RIGHT_SWITCH: + p_tas256x->devs[1]->spk_control = value; + break; + case RX_SCFG_LEFT: + ret = tas256x_update_rx_cfg(p_tas256x, value, channel_left); + break; + case RX_SCFG_RIGHT: + ret = tas256x_update_rx_cfg(p_tas256x, value, channel_right); + break; + default: + ret = p_tas256x->write(p_tas256x, channel_both, reg, value); + break; + } + + return ret; +} +#endif + +#ifdef CODEC_PM +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE +static int tas256x_codec_suspend(struct snd_soc_component *codec) +{ + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); + int ret = 0; + + mutex_lock(&p_tas256x->codec_lock); + + dev_dbg(p_tas256x->dev, "%s\n", __func__); + p_tas256x->runtime_suspend(p_tas256x); + + mutex_unlock(&p_tas256x->codec_lock); + return ret; +} + +static int tas256x_codec_resume(struct snd_soc_component *codec) +{ + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); + int ret = 0; + + mutex_lock(&p_tas256x->codec_lock); + + dev_dbg(p_tas256x->dev, "%s\n", __func__); + p_tas256x->runtime_resume(p_tas256x); + + mutex_unlock(&p_tas256x->codec_lock); + return ret; +} +#else +static int tas256x_codec_suspend(struct snd_soc_codec *codec) +{ + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + mutex_lock(&p_tas256x->codec_lock); + + dev_dbg(p_tas256x->dev, "%s\n", __func__); + p_tas256x->runtime_suspend(p_tas256x); + + mutex_unlock(&p_tas256x->codec_lock); + return ret; +} + +static int tas256x_codec_resume(struct snd_soc_codec *codec) +{ + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + mutex_lock(&p_tas256x->codec_lock); + + dev_dbg(p_tas256x->dev, "%s\n", __func__); + p_tas256x->runtime_resume(p_tas256x); + + mutex_unlock(&p_tas256x->codec_lock); + return ret; +} +#endif +#endif + +static int tas256x_set_power_state(struct tas256x_priv *p_tas256x, + enum channel chn, int state) +{ + int n_result = 0, i = 0; + + if ((p_tas256x->mb_mute) && (state == TAS256X_POWER_ACTIVE)) + state = TAS256X_POWER_MUTE; + dev_info(p_tas256x->dev, "set power state: %d\n", state); + + switch (state) { + case TAS256X_POWER_ACTIVE: + /* if set format was not called by asoc, then set it default */ + if (p_tas256x->mn_asi_format == 0) + p_tas256x->mn_asi_format = SND_SOC_DAIFMT_CBS_CFS | + SND_SOC_DAIFMT_IB_NF | + SND_SOC_DAIFMT_I2S; + n_result = tas256x_set_fmt(p_tas256x, p_tas256x->mn_asi_format); + if (n_result < 0) + return n_result; + tas256x_iv_sense_enable_set(p_tas256x, 1, chn); +#ifdef CONFIG_TAS25XX_ALGO + //tas25xx_send_algo_calibration(); + + /*Moved to probe*/ + /*tas25xx_set_iv_bit_fomat (p_tas256x->mn_iv_width, + *p_tas256x->mn_vbat, 1); + */ +#endif + /* Clear latched IRQ before power on */ + + tas256x_interrupt_clear(p_tas256x, chn); + + /*Mask interrupt for TDM*/ + n_result = tas256x_interrupt_enable(p_tas256x, 0 /*Disable*/, + channel_both); +#ifdef CONFIG_TAS256X_BIN_PARSER + // tas256x_select_cfg_blk(p_tas256x, 0, TAS256X_BIN_BLK_PRE_POWER_UP);//Normal + tas256x_select_cfg_blk(p_tas256x, 1, + TAS256X_BIN_BLK_PRE_POWER_UP); //Swap + dev_info(p_tas256x->dev, + "IRQ reg is: %s tas256x_select_cfg_blk %d\n", __func__, + __LINE__); + +#endif + n_result = tas256x_set_power_up(p_tas256x, chn); + + pr_info("%s: set ICN to -80dB\n", __func__); + n_result = tas256x_icn_data(p_tas256x, chn); + p_tas256x->mb_power_up = true; + p_tas256x->mn_power_state = TAS256X_POWER_ACTIVE; + schedule_delayed_work(&p_tas256x->init_work, + msecs_to_jiffies(50)); + break; + + case TAS256X_POWER_MUTE: + n_result = tas256x_set_power_mute(p_tas256x, chn); + p_tas256x->mb_power_up = true; + p_tas256x->mn_power_state = TAS256X_POWER_MUTE; + + /*Mask interrupt for TDM*/ + n_result = + tas256x_interrupt_enable(p_tas256x, 0 /*Disable*/, chn); + break; + + case TAS256X_POWER_SHUTDOWN: + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (p_tas256x->devs[i]->device_id == DEVICE_TAS2564) { + if (chn & (i + 1)) { + /*Mask interrupt for TDM*/ + n_result = tas256x_interrupt_enable( + p_tas256x, 0 /*Disable*/, + i + 1); + n_result = tas256x_set_power_mute( + p_tas256x, i + 1); + n_result = tas256x_iv_sense_enable_set( + p_tas256x, 0, i + 1); + p_tas256x->mb_power_up = false; + p_tas256x->mn_power_state = + TAS256X_POWER_SHUTDOWN; + } + } else { + n_result = tas256x_set_power_shutdown(p_tas256x, + i + 1); + n_result = tas256x_iv_sense_enable_set( + p_tas256x, 0, i + 1); + p_tas256x->mb_power_up = false; + p_tas256x->mn_power_state = + TAS256X_POWER_SHUTDOWN; + /*Mask interrupt for TDM*/ + n_result = tas256x_interrupt_enable( + p_tas256x, 0 /*Disable*/, i + 1); + } + } + msleep(20); + p_tas256x->enable_irq(p_tas256x, false); +#ifdef CONFIG_TAS25XX_ALGO + //tas25xx_update_big_data(); +#endif + break; + + default: + dev_err(p_tas256x->dev, "wrong power state setting %d\n", + state); + } + + return n_result; +} + +void failsafe(struct tas256x_priv *p_tas256x) +{ + int n_result; + + dev_err(p_tas256x->dev, "%s\n", __func__); + p_tas256x->mn_err_code |= ERROR_FAILSAFE; + + if (p_tas256x->mnRestart < RESTART_MAX) { + p_tas256x->mnRestart++; + msleep(100); + dev_err(p_tas256x->dev, "I2C COMM error, restart SmartAmp.\n"); + tas256x_set_power_state(p_tas256x, channel_both, + p_tas256x->mn_power_state); + return; + } + + n_result = tas256x_set_power_shutdown(p_tas256x, channel_both); + p_tas256x->mb_power_up = false; + p_tas256x->mn_power_state = TAS256X_POWER_SHUTDOWN; + msleep(20); + /*Mask interrupt for TDM*/ + n_result = tas256x_interrupt_enable(p_tas256x, 0 /*Disable*/, + channel_both); + p_tas256x->enable_irq(p_tas256x, false); + p_tas256x->hw_reset(p_tas256x); + p_tas256x->write(p_tas256x, channel_both, TAS256X_SOFTWARERESET, + TAS256X_SOFTWARERESET_SOFTWARERESET_RESET); + udelay(1000); + /*pTAS256x->write(pTAS256x, channel_both, TAS256X_SPK_CTRL_REG, 0x04);*/ +} + +static int tas256x_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm); + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + switch (event) { + case SND_SOC_DAPM_POST_PMU: + dev_info(p_tas256x->dev, "SND_SOC_DAPM_POST_PMU\n"); + break; + case SND_SOC_DAPM_PRE_PMD: + dev_info(p_tas256x->dev, "SND_SOC_DAPM_PRE_PMD\n"); + break; + } + + return 0; +} + +static const char *const tas256x_ASI1_src[] = { + "I2C offset", + "Left", + "Right", + "LeftRightDiv2", +}; + +static SOC_ENUM_SINGLE_DECL(tas2562_ASI1_src_left_enum, RX_SCFG_LEFT, 0, + tas256x_ASI1_src); +static SOC_ENUM_SINGLE_DECL(tas2562_ASI1_src_right_enum, RX_SCFG_RIGHT, 0, + tas256x_ASI1_src); + +static const struct snd_kcontrol_new dapm_switch_left = + SOC_DAPM_SINGLE("Switch", TAS256X_LEFT_SWITCH, 0, 1, 0); +static const struct snd_kcontrol_new dapm_switch_right = + SOC_DAPM_SINGLE("Switch", TAS256X_RIGHT_SWITCH, 0, 1, 0); +static const struct snd_kcontrol_new tas256x_asi1_left_mux = + SOC_DAPM_ENUM("Mux", tas2562_ASI1_src_left_enum); +static const struct snd_kcontrol_new tas256x_asi1_right_mux = + SOC_DAPM_ENUM("Mux", tas2562_ASI1_src_right_enum); + +static const struct snd_soc_dapm_widget tas256x_dapm_widgets_stereo[] = { + SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_SWITCH("TAS256X ASI Left", SND_SOC_NOPM, 0, 0, + &dapm_switch_left), + SND_SOC_DAPM_SWITCH("TAS256X ASI Right", SND_SOC_NOPM, 0, 0, + &dapm_switch_right), + SND_SOC_DAPM_MUX("TAS256X ASI1 SEL LEFT", SND_SOC_NOPM, 0, 0, + &tas256x_asi1_left_mux), + SND_SOC_DAPM_MUX("TAS256X ASI1 SEL RIGHT", SND_SOC_NOPM, 0, 0, + &tas256x_asi1_right_mux), + SND_SOC_DAPM_AIF_OUT("Voltage Sense", "ASI1 Capture", 0, SND_SOC_NOPM, + 0, 0), + SND_SOC_DAPM_AIF_OUT("Current Sense", "ASI1 Capture", 0, SND_SOC_NOPM, + 0, 0), + SND_SOC_DAPM_DAC_E("DAC1", NULL, SND_SOC_NOPM, 0, 0, tas256x_dac_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_DAC_E("DAC2", NULL, SND_SOC_NOPM, 0, 0, tas256x_dac_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_OUTPUT("OUT1"), + SND_SOC_DAPM_OUTPUT("OUT2"), + SND_SOC_DAPM_SIGGEN("VMON"), + SND_SOC_DAPM_SIGGEN("IMON") +}; + +static const struct snd_soc_dapm_route tas256x_audio_map_stereo[] = { + { "TAS256X ASI1 SEL LEFT", "Left", "ASI1" }, + { "TAS256X ASI1 SEL LEFT", "Right", "ASI1" }, + { "TAS256X ASI1 SEL LEFT", "LeftRightDiv2", "ASI1" }, + { "TAS256X ASI1 SEL RIGHT", "Left", "ASI1" }, + { "TAS256X ASI1 SEL RIGHT", "Right", "ASI1" }, + { "TAS256X ASI1 SEL RIGHT", "LeftRightDiv2", "ASI1" }, + { "DAC1", NULL, "TAS256X ASI1 SEL LEFT" }, + { "DAC2", NULL, "TAS256X ASI1 SEL RIGHT" }, + { "TAS256X ASI Left", "Switch", "DAC1" }, + { "TAS256X ASI Right", "Switch", "DAC2" }, + { "OUT1", NULL, "TAS256X ASI Left" }, + { "OUT2", NULL, "TAS256X ASI Right" }, + { "Voltage Sense", NULL, "VMON" }, + { "Current Sense", NULL, "IMON" } +}; + +static const struct snd_soc_dapm_widget tas256x_dapm_widgets_mono[] = { + SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_SWITCH("TAS256X ASI", SND_SOC_NOPM, 0, 0, + &dapm_switch_left), + SND_SOC_DAPM_MUX("TAS256X ASI1 SEL", SND_SOC_NOPM, 0, 0, + &tas256x_asi1_left_mux), + SND_SOC_DAPM_AIF_OUT("Voltage Sense", "ASI1 Capture", 1, + TAS256X_POWERCONTROL, 2, 1), + SND_SOC_DAPM_AIF_OUT("Current Sense", "ASI1 Capture", 0, + TAS256X_POWERCONTROL, 3, 1), + SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas256x_dac_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_OUTPUT("OUT"), + SND_SOC_DAPM_SIGGEN("VMON"), + SND_SOC_DAPM_SIGGEN("IMON") +}; + +static const struct snd_soc_dapm_route tas256x_audio_map_mono[] = { + { "TAS256X ASI1 SEL", "Left", "ASI1" }, + { "TAS256X ASI1 SEL", "Right", "ASI1" }, + { "TAS256X ASI1 SEL", "LeftRightDiv2", "ASI1" }, + { "DAC", NULL, "TAS256X ASI1 SEL" }, + { "TAS256X ASI", "Switch", "DAC" }, + { "OUT", NULL, "TAS256X ASI" }, + { "Voltage Sense", NULL, "VMON" }, + { "Current Sense", NULL, "IMON" } +}; + +static int tas256x_set_bitwidth(struct tas256x_priv *p_tas256x, int bitwidth, + int stream) +{ + int slot_width_tmp = 16; + + dev_info(p_tas256x->dev, "%s %d\n", __func__, bitwidth); + switch (bitwidth) { + case SNDRV_PCM_FORMAT_S16_LE: + p_tas256x->mn_ch_size = 16; + slot_width_tmp = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + p_tas256x->mn_ch_size = 24; + slot_width_tmp = 32; + break; + case SNDRV_PCM_FORMAT_S32_LE: + p_tas256x->mn_ch_size = 32; + slot_width_tmp = 32; + break; + } + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + tas256x_rx_set_bitwidth(p_tas256x, p_tas256x->mn_ch_size); + tas256x_rx_set_slot(p_tas256x, slot_width_tmp); + } else { /*stream == SNDRV_PCM_STREAM_CAPTURE*/ + tas256x_iv_slot_config(p_tas256x); + tas256x_iv_bitwidth_config(p_tas256x); + } + + dev_info(p_tas256x->dev, "mn_ch_size: %d\n", p_tas256x->mn_ch_size); + p_tas256x->mn_pcm_format = bitwidth; + + return 0; +} + +static int tas256x_system_mute_ctrl_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + pValue->value.integer.value[0] = p_tas256x->mb_mute; + dev_dbg(p_tas256x->dev, "%s = %d\n", __func__, p_tas256x->mb_mute); + + return 0; +} + +static int tas256x_system_mute_ctrl_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + int mb_mute = pValue->value.integer.value[0]; + + dev_dbg(p_tas256x->dev, "%s = %d\n", __func__, mb_mute); + + p_tas256x->mb_mute = !!mb_mute; + + return 0; +} + +static int tas256x_mute_ctrl_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + pValue->value.integer.value[0] = p_tas256x->mb_mute; + + if ((p_tas256x->mb_power_up == true) && + (p_tas256x->mn_power_state == TAS256X_POWER_ACTIVE)) + pValue->value.integer.value[0] = 0; + else + pValue->value.integer.value[0] = 1; + + dev_dbg(p_tas256x->dev, "%s = %ld\n", __func__, + pValue->value.integer.value[0]); + + return 0; +} + +static int tas256x_mute_ctrl_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + enum channel chn = channel_left; + int mute = pValue->value.integer.value[0]; + int i = 0, chnTemp = 0; + + dev_dbg(p_tas256x->dev, "%s, %d\n", __func__, mute); + mutex_lock(&p_tas256x->codec_lock); + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (p_tas256x->devs[i]->spk_control == 1) + chnTemp |= 1 << i; + } + chn = (chnTemp == 0) ? chn : (enum channel)chnTemp; + + if (mute) { + tas256x_set_power_state(p_tas256x, chn, TAS256X_POWER_MUTE); + } else { + tas256x_set_power_state(p_tas256x, chn, TAS256X_POWER_ACTIVE); + } + mutex_unlock(&p_tas256x->codec_lock); + return 0; +} + +static int tas256x_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = dai->component; + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = dai->codec; + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + /* int blr_clk_ratio; */ + int n_result = 0; + + dev_dbg(p_tas256x->dev, "%s, stream %s format: %d\n", __func__, + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? + ("Playback") : + ("Capture"), + params_format(params)); + + mutex_lock(&p_tas256x->codec_lock); + + n_result = tas256x_set_bitwidth(p_tas256x, params_format(params), + substream->stream); + if (n_result < 0) { + dev_info(p_tas256x->dev, "set bitwidth failed, %d\n", n_result); + goto ret; + } + + dev_info(p_tas256x->dev, "%s, stream %s sample rate: %d\n", __func__, + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? + ("Playback") : + ("Capture"), + params_rate(params)); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + n_result = + tas256x_set_samplerate(p_tas256x, params_rate(params)); + +ret: + if (n_result < 0) { + if (p_tas256x->mn_err_code & + (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM)) + failsafe(p_tas256x); + } + + mutex_unlock(&p_tas256x->codec_lock); + return n_result; +} + +static int tas256x_set_fmt(struct tas256x_priv *p_tas256x, unsigned int fmt) +{ + u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0; + int ret = 0; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + asi_cfg_1 = 0x00; + break; + default: + dev_err(p_tas256x->dev, "ASI format master is not found\n"); + ret = -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + dev_info(p_tas256x->dev, "INV format: NBNF\n"); + asi_cfg_1 = 1; /* Rising */ + break; + case SND_SOC_DAIFMT_IB_NF: + dev_info(p_tas256x->dev, "INV format: IBNF\n"); + asi_cfg_1 = 0; /* Faling */ + break; + default: + dev_err(p_tas256x->dev, "ASI format Inverse is not found\n"); + ret = -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case (SND_SOC_DAIFMT_I2S): + tdm_rx_start_slot = 1; + break; + case (SND_SOC_DAIFMT_DSP_A): + case (SND_SOC_DAIFMT_DSP_B): + tdm_rx_start_slot = 1; + break; + case (SND_SOC_DAIFMT_LEFT_J): + tdm_rx_start_slot = 0; + break; + default: + dev_err(p_tas256x->dev, "DAI Format is not found, fmt=0x%x\n", + fmt); + ret = -EINVAL; + break; + } + + ret = tas256x_rx_set_fmt(p_tas256x, asi_cfg_1, tdm_rx_start_slot); + + p_tas256x->mn_asi_format = fmt; + + if (ret < 0) { + if (p_tas256x->mn_err_code & + (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM)) + failsafe(p_tas256x); + } + + return 0; +} + +static int tas256x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = dai->component; + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = dai->codec; + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + int ret = 0; + + dev_dbg(p_tas256x->dev, "%s, format=0x%x\n", __func__, fmt); + + return ret; +} + +static int tas256x_set_dai_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, unsigned int rx_mask, + int slots, int slot_width) +{ + int ret = 0; +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = dai->component; + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = dai->codec; + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + dev_dbg(p_tas256x->dev, "%s, tx_mask:%d, rx_mask:%d", __func__, tx_mask, + rx_mask); + dev_dbg(p_tas256x->dev, "%s, slots:%d,slot_width:%d", __func__, slots, + slot_width); + + p_tas256x->mn_slot_width = slot_width; + + if (rx_mask) + ret = tas256x_rx_set_slot(p_tas256x, slot_width); + else + ret = tas256x_iv_slot_config(p_tas256x); + + if (ret < 0) { + if (p_tas256x->mn_err_code & + (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM)) + failsafe(p_tas256x); + } + + return ret; +} + +static int tas256x_mute_stream(struct snd_soc_dai *dai, int mute, int stream) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = dai->component; + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = dai->codec; + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + enum channel chn = channel_left; + int i = 0, chnTemp = 0; + int ret = 0; + + dev_info(p_tas256x->dev, "%s =>stream %s mute %d\n", __func__, + (stream == SNDRV_PCM_STREAM_PLAYBACK) ? ("Playback") : + ("Capture"), + mute); + mutex_lock(&p_tas256x->codec_lock); + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + if (mute) { + ret = tas256x_set_power_state(p_tas256x, channel_both, + TAS256X_POWER_SHUTDOWN); + } else { + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (p_tas256x->devs[i]->spk_control == 1) + chnTemp |= 1 << i; + } + chn = (chnTemp == 0) ? chn : (enum channel)chnTemp; + ret = tas256x_set_power_state(p_tas256x, chn, + TAS256X_POWER_ACTIVE); + } + } + + mutex_unlock(&p_tas256x->codec_lock); + + if (ret < 0) { + if (p_tas256x->mn_err_code & + (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM)) + failsafe(p_tas256x); + } + + return 0; +} + +static void tas256x_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = dai->component; + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = dai->codec; + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + int n_result = 0; + int i = 0, chnTemp = 0; + enum channel chn = channel_left; + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (p_tas256x->devs[i]->spk_control == 1) + chnTemp |= 1 << i; + } + chn = (chnTemp == 0) ? chn : (enum channel)chnTemp; + + dev_dbg(p_tas256x->dev, "%s, stream %s\n", __func__, + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? + ("Playback") : + ("Capture")); + if (p_tas256x->mb_power_up == true && + substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + n_result = tas256x_set_power_state(p_tas256x, chn, + TAS256X_POWER_SHUTDOWN); +} + +static struct snd_soc_dai_ops tas256x_dai_ops = { + .hw_params = tas256x_hw_params, + .set_fmt = tas256x_set_dai_fmt, + .set_tdm_slot = tas256x_set_dai_tdm_slot, + .mute_stream = tas256x_mute_stream, + .shutdown = tas256x_shutdown, +}; + +#define TAS256X_FORMATS \ + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver tas256x_dai_driver[] = { + { + .name = "tas256x ASI1", + .id = 0, + .playback = { + .stream_name = "ASI1 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = TAS256X_FORMATS, + }, + .capture = { + .stream_name = "ASI1 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = TAS256X_FORMATS, + }, + .ops = &tas256x_dai_ops, + .symmetric_rates = 1, + }, +}; + +static int tas256x_load_init(struct tas256x_priv *p_tas256x) +{ + int ret = 0, i; + + ret = tas256x_set_misc_config(p_tas256x, 0 /*Ignored*/, channel_both); + if (ret < 0) + goto end; + ret = tas256x_set_tx_config(p_tas256x, 0 /*Ignored*/, channel_both); + if (ret < 0) + goto end; + ret = tas256x_set_clock_config(p_tas256x, 0 /*Ignored*/, channel_both); + if (ret < 0) + goto end; + /*ICN Improve Performance*/ + ret = tas256x_icn_config(p_tas256x, 0 /*Ignored*/, channel_both); + if (ret < 0) + goto end; + /*Disable the HPF in Forward Path*/ + ret = tas256x_HPF_FF_Bypass(p_tas256x, 0 /*Ignored*/, channel_both); + if (ret < 0) + goto end; + /*Disable the HPF in Reverse Path*/ + ret = tas256x_HPF_FB_Bypass(p_tas256x, 0 /*Ignored*/, channel_both); + if (ret < 0) + goto end; + ret = tas256x_set_classH_config(p_tas256x, 0 /*Ignored*/, channel_both); + if (ret < 0) + goto end; + + /* To Overwrite the defaults */ + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (p_tas256x->devs[i]->dev_ops.tas_init) + ret |= (p_tas256x->devs[i]->dev_ops.tas_init)(p_tas256x, + i + 1); + } +end: + return ret; +} + +#ifdef CONFIG_TAS256X_BIN_PARSER +static char *fw_name = "tas256x_reg.bin"; + +const char *blocktype[5] = { "COEFF", "POST_POWER_UP", "PRE_SHUTDOWN", + "PRE_POWER_UP", "POST_SHUTDOWN" }; + +static int tas256x_process_block(void *pContext, unsigned char *data, + unsigned char dev_idx, int sublocksize) +{ + struct tas256x_priv *pTAS256x = (struct tas256x_priv *)pContext; + unsigned char subblk_typ = data[1]; + int subblk_offset = 2; + enum channel chn = + (0 == dev_idx) ? channel_both : (enum channel)dev_idx; + + switch (subblk_typ) { + case TAS256X_CMD_SING_W: { + int i = 0; + unsigned short len = SMS_HTONS(data[2], data[3]); + subblk_offset += 2; + if (subblk_offset + 4 * len > sublocksize) { + dev_err(pTAS256x->dev, "Out of memory %s: %u\n", + __func__, __LINE__); + break; + } + + for (i = 0; i < len; i++) { + pTAS256x->write(pTAS256x, chn, + TAS256X_REG(data[subblk_offset], + data[subblk_offset + 1], + data[subblk_offset + 2]), + data[subblk_offset + 3]); + subblk_offset += 4; + } + } break; + case TAS256X_CMD_BURST: { + // int i = 0; + unsigned short len = SMS_HTONS(data[2], data[3]); + subblk_offset += 2; + if (subblk_offset + 4 + len > sublocksize) { + dev_err(pTAS256x->dev, "Out of memory %s: %u\n", + __func__, __LINE__); + break; + } + if (len % 4) { + dev_err(pTAS256x->dev, "Burst len is wrong\n"); + break; + } + + pTAS256x->bulk_write(pTAS256x, chn, + TAS256X_REG(data[subblk_offset], + data[subblk_offset + 1], + data[subblk_offset + 2]), + &(data[subblk_offset + 4]), len); + subblk_offset += (len + 4); + + } break; + case TAS256X_CMD_DELAY: { + unsigned short delay_time = 0; + if (subblk_offset + 2 > sublocksize) { + dev_err(pTAS256x->dev, "Out of memory %s: %u\n", + __func__, __LINE__); + break; + } + delay_time = SMS_HTONS(data[2], data[3]); + usleep_range(delay_time * 1000, delay_time * 1000); + subblk_offset += 2; + } break; + case TAS256X_CMD_FIELD_W: + if (subblk_offset + 6 > sublocksize) { + dev_err(pTAS256x->dev, "Out of memory %s: %u\n", + __func__, __LINE__); + } + pTAS256x->update_bits(pTAS256x, chn, + TAS256X_REG(data[subblk_offset + 2], + data[subblk_offset + 3], + data[subblk_offset + 4]), + data[subblk_offset + 1], + data[subblk_offset + 5]); + subblk_offset += 6; + break; + default: + break; + }; + + return subblk_offset; +} + +void tas256x_select_cfg_blk(void *pContext, int conf_no, + unsigned char block_type) +{ + struct tas256x_priv *pTAS256x = (struct tas256x_priv *)pContext; + struct tas256x_config_info **cfg_info = pTAS256x->cfg_info; + int i = 0, j = 0, k = 0; + + if (conf_no > pTAS256x->ncfgs || conf_no < 0 || NULL == cfg_info) { + dev_err(pTAS256x->dev, + "ERROR!!!conf_no shoud be in range from 0 to %u\n", + pTAS256x->ncfgs - 1); + goto EXIT; + } + for (i = 0; i < pTAS256x->ncfgs; i++) { + if (conf_no == i) { + for (j = 0; j < (int)cfg_info[i]->real_nblocks; j++) { + unsigned int length = 0, rc = 0; + if (block_type > 5 || block_type < 2) { + dev_err(pTAS256x->dev, + "ERROR!!!block_type shoud be in range from 2 to 5\n"); + goto EXIT; + } + if (block_type != + cfg_info[i]->blk_data[j]->block_type) + continue; + dev_info(pTAS256x->dev, "conf %d\n", i); + dev_info( + pTAS256x->dev, + "\tblock type:%s\t device idx = 0x%02x\n", + blocktype[cfg_info[i] + ->blk_data[j] + ->block_type - + 1], + cfg_info[i]->blk_data[j]->dev_idx); + for (k = 0; + k < + (int)cfg_info[i]->blk_data[j]->nSublocks; + k++) { + rc = tas256x_process_block( + pTAS256x, + cfg_info[i]->blk_data[j] + ->regdata + + length, + cfg_info[i] + ->blk_data[j] + ->dev_idx, + cfg_info[i]->blk_data[j] + ->block_size - + length); + length += rc; + if (cfg_info[i]->blk_data[j]->block_size < + length) { + dev_err(pTAS256x->dev, + "%s:%u:ERROR:%u %u out of memory\n", + __func__, __LINE__, + length, + cfg_info[i] + ->blk_data[j] + ->block_size); + break; + } + } + if (length != + cfg_info[i]->blk_data[j]->block_size) { + dev_err(pTAS256x->dev, + "%s:%u:ERROR: %u %u size is not same\n", + __func__, __LINE__, length, + cfg_info[i] + ->blk_data[j] + ->block_size); + } + } + } else + continue; + } +EXIT: + return; +} + +static struct tas256x_config_info * +tas256x_add_config(unsigned char *config_data, unsigned int config_size) +{ + struct tas256x_config_info *cfg_info = NULL; + int config_offset = 0, i = 0; + cfg_info = (struct tas256x_config_info *)kzalloc( + sizeof(struct tas256x_config_info), GFP_KERNEL); + if (!cfg_info) { + pr_err("%s:%u:Memory alloc failed!\n", __func__, __LINE__); + goto EXIT; + } + if (config_offset + 4 > (int)config_size) { + pr_err("%s:%u:Out of memory\n", __func__, __LINE__); + goto EXIT; + } + cfg_info->nblocks = SMS_HTONL(config_data[config_offset], + config_data[config_offset + 1], + config_data[config_offset + 2], + config_data[config_offset + 3]); + config_offset += 4; + pr_info("cfg_info->num_blocks = %u\n", cfg_info->nblocks); + cfg_info->blk_data = (struct tas256x_block_data **)kzalloc( + cfg_info->nblocks * sizeof(struct tas256x_block_data *), + GFP_KERNEL); + if (!cfg_info->blk_data) { + pr_err("%s:%u:Memory alloc failed!\n", __func__, __LINE__); + goto EXIT; + } + cfg_info->real_nblocks = 0; + for (i = 0; i < (int)cfg_info->nblocks; i++) { + if (config_offset + 12 > config_size) { + pr_err("%s:%u:Out of memory: i = %d nblocks = %u!\n", + __func__, __LINE__, i, cfg_info->nblocks); + break; + } + cfg_info->blk_data[i] = (struct tas256x_block_data *)kzalloc( + sizeof(struct tas256x_block_data), GFP_KERNEL); + if (!cfg_info->blk_data[i]) { + pr_err("%s:%u:Memory alloc failed!\n", __func__, + __LINE__); + break; + } + cfg_info->blk_data[i]->dev_idx = config_data[config_offset]; + config_offset++; + pr_info("blk_data(%d).dev_idx = 0x%02x\n", i, + cfg_info->blk_data[i]->dev_idx); + cfg_info->blk_data[i]->block_type = config_data[config_offset]; + config_offset++; + pr_info("blk_data(%d).block_type = 0x%02x\n", i, + cfg_info->blk_data[i]->block_type); + cfg_info->blk_data[i]->yram_checksum = + SMS_HTONS(config_data[config_offset], + config_data[config_offset + 1]); + config_offset += 2; + cfg_info->blk_data[i]->block_size = + SMS_HTONL(config_data[config_offset], + config_data[config_offset + 1], + config_data[config_offset + 2], + config_data[config_offset + 3]); + config_offset += 4; + pr_info("blk_data(%d).block_size = %u\n", i, + cfg_info->blk_data[i]->block_size); + cfg_info->blk_data[i]->nSublocks = + SMS_HTONL(config_data[config_offset], + config_data[config_offset + 1], + config_data[config_offset + 2], + config_data[config_offset + 3]); + pr_info("blk_data(%d).num_subblocks = %u\n", i, + cfg_info->blk_data[i]->nSublocks); + config_offset += 4; + pr_info("config_offset = %d\n", config_offset); + cfg_info->blk_data[i]->regdata = (unsigned char *)kzalloc( + cfg_info->blk_data[i]->block_size, GFP_KERNEL); + if (!cfg_info->blk_data[i]->regdata) { + pr_err("%s:%u:Memory alloc failed!\n", __func__, + __LINE__); + goto EXIT; + } + if (config_offset + cfg_info->blk_data[i]->block_size > + config_size) { + pr_err("%s:%u:Out of memory: i = %d nblocks = %u!\n", + __func__, __LINE__, i, cfg_info->nblocks); + break; + } + memcpy(cfg_info->blk_data[i]->regdata, + &config_data[config_offset], + cfg_info->blk_data[i]->block_size); + config_offset += cfg_info->blk_data[i]->block_size; + cfg_info->real_nblocks += 1; + } + +EXIT: + return cfg_info; +} + +static void tas256x_fw_ready(const struct firmware *pFW, void *pContext) +{ + struct tas256x_priv *pTAS256x = (struct tas256x_priv *)pContext; + struct tas256x_fw_hdr *fw_hdr = &(pTAS256x->fw_hdr); + struct tas256x_config_info **cfg_info = NULL; + unsigned char *buf = NULL; + int offset = 0, i = 0; + unsigned int total_config_sz = 0; + + pTAS256x->fw_state = TAS256X_DSP_FW_FAIL; + + if (unlikely(!pFW) || unlikely(!pFW->data)) { + dev_err(pTAS256x->dev, + "Failed to read %s, no side-effect on driver running\n", + fw_name); + return; + } + buf = (unsigned char *)pFW->data; +#ifdef CONFIG_TAS256X_CODEC + mutex_lock(&pTAS256x->codec_lock); +#endif +#ifdef CONFIG_TAS256X_MISC + mutex_lock(&pTAS256x->file_lock); +#endif + dev_info(pTAS256x->dev, "%s: start\n", __func__); + fw_hdr->img_sz = SMS_HTONL(buf[offset], buf[offset + 1], + buf[offset + 2], buf[offset + 3]); + offset += 4; + if (fw_hdr->img_sz != pFW->size) { + dev_err(pTAS256x->dev, "File size not match, %d %d", + (int)pFW->size, (int)fw_hdr->img_sz); + goto EXIT; + } + + fw_hdr->checksum = SMS_HTONL(buf[offset], buf[offset + 1], + buf[offset + 2], buf[offset + 3]); + offset += 4; + fw_hdr->binnary_version_num = SMS_HTONL( + buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]); + offset += 4; + fw_hdr->drv_fw_version = SMS_HTONL(buf[offset], buf[offset + 1], + buf[offset + 2], buf[offset + 3]); + offset += 4; + fw_hdr->timestamp = SMS_HTONL(buf[offset], buf[offset + 1], + buf[offset + 2], buf[offset + 3]); + offset += 4; + fw_hdr->plat_type = buf[offset]; + offset += 1; + fw_hdr->dev_family = buf[offset]; + offset += 1; + fw_hdr->reserve = buf[offset]; + offset += 1; + fw_hdr->ndev = buf[offset]; + offset += 1; + + dev_info(pTAS256x->dev, "ndev = %u\n", fw_hdr->ndev); + + if (offset + TAS256X_DEVICE_SUM > fw_hdr->img_sz) { + dev_err(pTAS256x->dev, "%s:%u:Out of Memory!\n", __func__, + __LINE__); + goto EXIT; + } + + for (i = 0; i < TAS256X_DEVICE_SUM; i++) { + fw_hdr->devs[i] = buf[offset]; + offset += 1; + dev_info(pTAS256x->dev, "devs[%d] = %u\n", i, fw_hdr->devs[i]); + } + fw_hdr->nconfig = SMS_HTONL(buf[offset], buf[offset + 1], + buf[offset + 2], buf[offset + 3]); + offset += 4; + dev_info(pTAS256x->dev, "nconfig = %u\n", fw_hdr->nconfig); + for (i = 0; i < TAS256X_CONFIG_SIZE; i++) { + fw_hdr->config_size[i] = + SMS_HTONL(buf[offset], buf[offset + 1], buf[offset + 2], + buf[offset + 3]); + offset += 4; + dev_info(pTAS256x->dev, "config_size[%d] = %u\n", i, + fw_hdr->config_size[i]); + total_config_sz += fw_hdr->config_size[i]; + } + dev_info(pTAS256x->dev, + "img_sz = %u total_config_sz = %u offset = %d\n", + fw_hdr->img_sz, total_config_sz, offset); + if (fw_hdr->img_sz - total_config_sz != (unsigned int)offset) { + dev_err(pTAS256x->dev, "Bin file error!\n"); + goto EXIT; + } + cfg_info = (struct tas256x_config_info **)kzalloc( + fw_hdr->nconfig * sizeof(struct tas256x_config_info *), + GFP_KERNEL); + if (!cfg_info) { + dev_err(pTAS256x->dev, "%s:%u:Memory alloc failed!\n", __func__, + __LINE__); + goto EXIT; + } + pTAS256x->cfg_info = cfg_info; + pTAS256x->ncfgs = 0; + for (i = 0; i < (int)fw_hdr->nconfig; i++) { + cfg_info[i] = tas256x_add_config(&buf[offset], + fw_hdr->config_size[i]); + if (!cfg_info[i]) { + dev_err(pTAS256x->dev, "%s:%u:Memory alloc failed!\n", + __func__, __LINE__); + break; + } + offset += (int)fw_hdr->config_size[i]; + pTAS256x->ncfgs += 1; + } + + pTAS256x->fw_state = TAS256X_DSP_FW_OK; + +EXIT: +#ifdef CONFIG_TAS256X_MISC + mutex_unlock(&pTAS256x->file_lock); +#endif +#ifdef CONFIG_TAS256X_CODEC + mutex_unlock(&pTAS256x->codec_lock); +#endif + release_firmware(pFW); + dev_info(pTAS256x->dev, "%s: Firmware init complete\n", __func__); + return; +} + +static int tas256x_load_container(struct tas256x_priv *pTAS256x) +{ + pTAS256x->fw_state = TAS256X_DSP_FW_PENDING; + return request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, fw_name, + pTAS256x->dev, GFP_KERNEL, pTAS256x, + tas256x_fw_ready); +} +static void tas256x_config_info_remove(void *pContext) +{ + struct tas256x_priv *pTAS256x = (struct tas256x_priv *)pContext; + struct tas256x_config_info **cfg_info = pTAS256x->cfg_info; + int i = 0, j = 0; + + if (cfg_info) { + for (i = 0; i < pTAS256x->ncfgs; i++) { + if (cfg_info[i]) { + for (j = 0; j < (int)cfg_info[i]->real_nblocks; + j++) { + if (cfg_info[i]->blk_data[j]->regdata) + kfree(cfg_info[i] + ->blk_data[j] + ->regdata); + if (cfg_info[i]->blk_data[j]) + kfree(cfg_info[i]->blk_data[j]); + } + if (cfg_info[i]->blk_data) + kfree(cfg_info[i]->blk_data); + kfree(cfg_info[i]); + } + } + kfree(cfg_info); + } +} +#endif + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE +static int tas256x_codec_probe(struct snd_soc_component *codec) +{ + int ret, i; + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); + + ret = snd_soc_add_component_controls(codec, tas256x_controls, + ARRAY_SIZE(tas256x_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed, err %d\n", __func__, + ret); + return ret; + } + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (p_tas256x->devs[i]->dev_ops.tas_probe) + ret |= (p_tas256x->devs[i]->dev_ops.tas_probe)( + p_tas256x, codec, i + 1); + } + + ret = tas256x_load_init(p_tas256x); + if (ret < 0) + goto end; + ret = tas256x_iv_sense_enable_set(p_tas256x, 1, channel_both); + if (ret < 0) + goto end; +#ifdef CONFIG_TAS25XX_ALGO + tas_smartamp_add_algo_controls(codec); + /*Send IV Vbat format but don't update to algo yet*/ + tas25xx_set_iv_bit_fomat(p_tas256x->mn_iv_width, p_tas256x->mn_vbat, 0); +#endif +#ifdef CONFIG_TAS256X_BIN_PARSER + ret = tas256x_load_container(p_tas256x); + dev_info(p_tas256x->dev, "%s Bin file loading requested: %d\n", + __func__, ret); +#endif + dev_dbg(p_tas256x->dev, "%s\n", __func__); + +end: + if (ret < 0) { + if (p_tas256x->mn_err_code & + (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM)) + failsafe(p_tas256x); + } + return ret; +} +#else +static int tas256x_codec_probe(struct snd_soc_codec *codec) +{ + int ret, i; + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); + + dev_info(p_tas256x->dev, "Driver Tag: %s\n", TAS256X_DRIVER_TAG); + ret = snd_soc_add_codec_controls(codec, tas256x_controls, + ARRAY_SIZE(tas256x_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed, err %d\n", __func__, + ret); + return ret; + } + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (p_tas256x->devs[i]->dev_ops.tas_probe) + ret |= (p_tas256x->devs[i]->dev_ops.tas_probe)( + p_tas256x, codec, i + 1); + } + + ret = tas256x_load_init(p_tas256x); + if (ret < 0) + goto end; + ret = tas256x_iv_sense_enable_set(p_tas256x, 1, channel_both); + if (ret < 0) + goto end; +#ifdef CONFIG_TAS25XX_ALGO + tas_smartamp_add_algo_controls(codec); + /*Send IV Vbat format but don't update to algo yet*/ + tas25xx_set_iv_bit_fomat(p_tas256x->mn_iv_width, p_tas256x->mn_vbat, 0); +#endif +#ifdef CONFIG_TAS256X_BIN_PARSER + ret = tas256x_load_container(p_tas256x); + dev_info(p_tas256x->dev, "%s Bin file loading requested: %d\n", + __func__, ret); +#endif + dev_dbg(p_tas256x->dev, "%s\n", __func__); + +end: + if (ret < 0) { + if (p_tas256x->mn_err_code & + (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM)) + failsafe(p_tas256x); + } + + return ret; +} +#endif + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE +static void tas256x_codec_remove(struct snd_soc_component *codec) +{ +#ifdef CONFIG_TAS256X_BIN_PARSER + struct tas2562_priv *pTAS256x = snd_soc_component_get_drvdata(codec); + tas256x_config_info_remove(pTAS256x); +#endif +} +#else +static int tas256x_codec_remove(struct snd_soc_codec *codec) +{ +#ifdef CONFIG_TAS256X_BIN_PARSER + struct tas256x_priv *pTAS256x = snd_soc_codec_get_drvdata(codec); + //struct tas2562_priv *pTAS256x = snd_soc_component_get_drvdata(codec); + tas256x_config_info_remove(pTAS256x); +#endif + return 0; +} +#endif + +static DECLARE_TLV_DB_SCALE(tas256x_digital_tlv, 1100, 50, 0); + +static const char *const icn_sw_text[] = { "Enable", "Disable" }; +static const struct soc_enum icn_sw_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(icn_sw_text), icn_sw_text), +}; +static int tas256x_get_icn_switch(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *p_u_control) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + dev_info(p_tas256x->dev, "%s, icn_sw = %ld\n", __func__, + p_u_control->value.integer.value[0]); + p_u_control->value.integer.value[0] = p_tas256x->icn_sw; + return 0; +} +static int tas256x_set_icn_switch(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *p_u_control) +{ + int ret = 0; +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + p_tas256x->icn_sw = p_u_control->value.integer.value[0]; + ret = tas256x_icn_enable(p_tas256x, p_tas256x->icn_sw, channel_both); + + return ret; +} + +static int tas256x_dac_mute_ctrl_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + pValue->value.integer.value[0] = p_tas256x->dac_mute; + + dev_dbg(p_tas256x->dev, "%s = %ld\n", __func__, + pValue->value.integer.value[0]); + + return 0; +} + +static int tas256x_dac_mute_ctrl_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ + int n_result = 0; + enum channel chn = channel_left; + int mute = pValue->value.integer.value[0]; + int i = 0, chnTemp = 0; +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); + struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + dev_dbg(p_tas256x->dev, "%s, %d\n", __func__, mute); + mutex_lock(&p_tas256x->codec_lock); + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (p_tas256x->devs[i]->spk_control == 1) + chnTemp |= 1 << i; + } + chn = (chnTemp == 0) ? chn : (enum channel)chnTemp; + + if (mute) + n_result = tas256x_set_power_mute(p_tas256x, chn); + else + n_result = tas256x_set_power_up(p_tas256x, chn); + + p_tas256x->dac_mute = mute; + mutex_unlock(&p_tas256x->codec_lock); + + return n_result; +} + +static const struct snd_kcontrol_new tas256x_snd_controls[] = { + SOC_SINGLE_TLV("Amp Output Level", TAS256X_PLAYBACKCONFIGURATIONREG0, 1, + 0x16, 0, tas256x_digital_tlv), + SOC_SINGLE_EXT("SmartPA System Mute", SND_SOC_NOPM, 0, 0x0001, 0, + tas256x_system_mute_ctrl_get, + tas256x_system_mute_ctrl_put), + SOC_SINGLE_EXT("SmartPA Mute", SND_SOC_NOPM, 0, 0x0001, 0, + tas256x_mute_ctrl_get, tas256x_mute_ctrl_put), + SOC_SINGLE_EXT("TAS256X DAC Mute", SND_SOC_NOPM, 0, 0x0001, 0, + tas256x_dac_mute_ctrl_get, tas256x_dac_mute_ctrl_put), + SOC_ENUM_EXT("TAS256X ICN Switch", icn_sw_enum[0], + tas256x_get_icn_switch, tas256x_set_icn_switch), +}; + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE +static const struct snd_soc_component_driver soc_codec_driver_tas256x = { + .probe = tas256x_codec_probe, + .remove = tas256x_codec_remove, + .read = tas256x_codec_read, + .write = tas256x_codec_write, +#ifdef CODEC_PM + .suspend = tas256x_codec_suspend, + .resume = tas256x_codec_resume, +#endif + .controls = tas256x_snd_controls, + .num_controls = ARRAY_SIZE(tas256x_snd_controls), + .dapm_widgets = tas256x_dapm_widgets_mono, + .num_dapm_widgets = ARRAY_SIZE(tas256x_dapm_widgets_mono), + .dapm_routes = tas256x_audio_map_stereo, + .num_dapm_routes = ARRAY_SIZE(tas256x_audio_map_stereo), +}; +#else +static struct snd_soc_codec_driver soc_codec_driver_tas256x = { + .probe = tas256x_codec_probe, + .remove = tas256x_codec_remove, + .read = tas256x_codec_read, + .write = tas256x_codec_write, +#ifdef CODEC_PM + .suspend = tas256x_codec_suspend, + .resume = tas256x_codec_resume, +#endif + .component_driver = { + .controls = tas256x_snd_controls, + .num_controls = ARRAY_SIZE(tas256x_snd_controls), + .dapm_widgets = tas256x_dapm_widgets_mono, + .num_dapm_widgets = ARRAY_SIZE(tas256x_dapm_widgets_mono), + .dapm_routes = tas256x_audio_map_mono, + .num_dapm_routes = ARRAY_SIZE(tas256x_audio_map_mono), + }, +}; +#endif + +int tas256x_register_codec(struct tas256x_priv *p_tas256x) +{ + int n_result = 0; + + dev_info(p_tas256x->dev, "%s, enter\n", __func__); + + if (p_tas256x->mn_channels == 2) { +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + soc_codec_driver_tas256x.dapm_widgets = + tas256x_dapm_widgets_stereo; + soc_codec_driver_tas256x.num_dapm_widgets = + ARRAY_SIZE(tas256x_dapm_widgets_stereo); + soc_codec_driver_tas256x.dapm_routes = tas256x_audio_map_stereo; + soc_codec_driver_tas256x.num_dapm_routes = + ARRAY_SIZE(tas256x_audio_map_stereo); +#else + soc_codec_driver_tas256x.component_driver.dapm_widgets = + tas256x_dapm_widgets_stereo; + soc_codec_driver_tas256x.component_driver.num_dapm_widgets = + ARRAY_SIZE(tas256x_dapm_widgets_stereo); + soc_codec_driver_tas256x.component_driver.dapm_routes = + tas256x_audio_map_stereo; + soc_codec_driver_tas256x.component_driver.num_dapm_routes = + ARRAY_SIZE(tas256x_audio_map_stereo); +#endif + } + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + n_result = devm_snd_soc_register_component( + p_tas256x->dev, &soc_codec_driver_tas256x, tas256x_dai_driver, + ARRAY_SIZE(tas256x_dai_driver)); +#else + n_result = snd_soc_register_codec(p_tas256x->dev, + &soc_codec_driver_tas256x, + tas256x_dai_driver, + ARRAY_SIZE(tas256x_dai_driver)); +#endif + return n_result; +} + +int tas256x_deregister_codec(struct tas256x_priv *p_tas256x) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + snd_soc_unregister_component(p_tas256x->dev); +#else + snd_soc_unregister_codec(p_tas256x->dev); +#endif + return 0; +} + +int tas256x_load_ctrl_values(struct tas256x_priv *p_tas256x, int ch) +{ + int n_result = 0; + + n_result |= tas256x_update_playback_volume( + p_tas256x, p_tas256x->devs[ch - 1]->dvc_pcm, ch); + + n_result |= tas256x_update_lim_max_attenuation( + p_tas256x, p_tas256x->devs[ch - 1]->lim_max_attn, ch); + + n_result |= tas256x_update_lim_max_thr( + p_tas256x, p_tas256x->devs[ch - 1]->lim_thr_max, ch); + + n_result |= tas256x_update_lim_min_thr( + p_tas256x, p_tas256x->devs[ch - 1]->lim_thr_min, ch); + + n_result |= tas256x_update_lim_inflection_point( + p_tas256x, p_tas256x->devs[ch - 1]->lim_infl_pt, ch); + + n_result |= tas256x_update_lim_slope( + p_tas256x, p_tas256x->devs[ch - 1]->lim_trk_slp, ch); + + n_result |= tas256x_update_bop_thr( + p_tas256x, p_tas256x->devs[ch - 1]->bop_thd, ch); + + n_result |= tas256x_update_bosd_thr( + p_tas256x, p_tas256x->devs[ch - 1]->bosd_thd, ch); + + n_result |= tas256x_update_boost_voltage( + p_tas256x, p_tas256x->devs[ch - 1]->bst_vltg, ch); + + n_result |= tas256x_update_current_limit( + p_tas256x, p_tas256x->devs[ch - 1]->bst_ilm, ch); + + n_result |= tas256x_update_limiter_enable( + p_tas256x, p_tas256x->devs[ch - 1]->lim_switch, ch); + + n_result |= tas256x_update_limiter_attack_rate( + p_tas256x, p_tas256x->devs[ch - 1]->lim_att_rate, ch); + + n_result |= tas256x_update_limiter_attack_step_size( + p_tas256x, p_tas256x->devs[ch - 1]->lim_att_stp_size, ch); + + n_result |= tas256x_update_limiter_release_rate( + p_tas256x, p_tas256x->devs[ch - 1]->lim_rel_rate, ch); + + n_result |= tas256x_update_limiter_release_step_size( + p_tas256x, p_tas256x->devs[ch - 1]->lim_rel_stp_size, ch); + + n_result |= tas256x_update_bop_enable( + p_tas256x, p_tas256x->devs[ch - 1]->bop_enable, ch); + + n_result |= tas256x_update_bop_mute( + p_tas256x, p_tas256x->devs[ch - 1]->bop_mute, ch); + + n_result |= tas256x_update_bop_shutdown_enable( + p_tas256x, p_tas256x->devs[ch - 1]->bosd_enable, ch); + + n_result |= tas256x_update_bop_attack_rate( + p_tas256x, p_tas256x->devs[ch - 1]->bop_att_rate, ch); + + n_result |= tas256x_update_bop_attack_step_size( + p_tas256x, p_tas256x->devs[ch - 1]->bop_att_stp_size, ch); + + n_result |= tas256x_update_bop_hold_time( + p_tas256x, p_tas256x->devs[ch - 1]->bop_hld_time, ch); + + n_result |= tas256x_update_vbat_lpf( + p_tas256x, p_tas256x->devs[ch - 1]->vbat_lpf, ch); + + n_result |= tas256x_update_rx_cfg(p_tas256x, + p_tas256x->devs[ch - 1]->rx_cfg, ch); + + /* TAS2564 Specific*/ + if (p_tas256x->devs[ch - 1]->device_id == DEVICE_TAS2564) + n_result |= tas2564_rx_mode_update( + p_tas256x, p_tas256x->devs[ch - 1]->rx_mode, ch); + + return n_result; +} + +void tas256x_load_config(struct tas256x_priv *p_tas256x) +{ + int ret = 0; + + p_tas256x->hw_reset(p_tas256x); + msleep(20); + + ret = tas56x_software_reset(p_tas256x, channel_both); + if (ret < 0) + goto end; + ret = tas256x_iv_slot_config(p_tas256x); + if (ret < 0) + goto end; + ret = tas256x_load_init(p_tas256x); + if (ret < 0) + goto end; + ret = tas256x_update_rx_cfg(p_tas256x, p_tas256x->devs[0]->rx_cfg, + channel_left); + if (ret < 0) + goto end; + ret |= tas256x_load_ctrl_values(p_tas256x, channel_left); + if (ret < 0) + goto end; + if (p_tas256x->mn_channels == 2) { + ret = tas256x_update_rx_cfg( + p_tas256x, p_tas256x->devs[1]->rx_cfg, channel_right); + if (ret < 0) + goto end; + ret |= tas256x_load_ctrl_values(p_tas256x, channel_right); + if (ret < 0) + goto end; + } + ret = tas256x_rx_set_slot(p_tas256x, p_tas256x->mn_slot_width); + if (ret < 0) + goto end; + ret = tas256x_set_fmt(p_tas256x, p_tas256x->mn_asi_format); + if (ret < 0) + goto end; + ret = tas256x_set_bitwidth(p_tas256x, p_tas256x->mn_pcm_format, + SNDRV_PCM_STREAM_PLAYBACK); + if (ret < 0) + goto end; + ret = tas256x_set_bitwidth(p_tas256x, p_tas256x->mn_pcm_format, + SNDRV_PCM_STREAM_CAPTURE); + if (ret < 0) + goto end; + ret = tas256x_set_samplerate(p_tas256x, p_tas256x->mn_sampling_rate); + if (ret < 0) + goto end; + ret = tas256x_set_power_state(p_tas256x, channel_both, + p_tas256x->mn_power_state); + if (ret < 0) + goto end; + +end: + /* power up failed, restart later */ + if (ret < 0) { + if (p_tas256x->mn_err_code & + (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM)) + failsafe(p_tas256x); + } +} + +void tas_reload(struct tas256x_priv *p_tas256x, int chn) +{ + int ret = 0; + /*To be used later*/ + (void)chn; + + p_tas256x->enable_irq(p_tas256x, false); + + ret = tas56x_software_reset(p_tas256x, channel_both); + if (ret < 0) + goto end; + ret = tas256x_load_init(p_tas256x); + if (ret < 0) + goto end; + ret |= tas256x_load_ctrl_values(p_tas256x, chn); + if (ret < 0) + goto end; + ret = tas256x_rx_set_slot(p_tas256x, p_tas256x->mn_slot_width); + if (ret < 0) + goto end; + ret = tas256x_set_fmt(p_tas256x, p_tas256x->mn_asi_format); + if (ret < 0) + goto end; + ret = tas256x_set_bitwidth(p_tas256x, p_tas256x->mn_pcm_format, + SNDRV_PCM_STREAM_PLAYBACK); + if (ret < 0) + goto end; + ret = tas256x_set_bitwidth(p_tas256x, p_tas256x->mn_pcm_format, + SNDRV_PCM_STREAM_CAPTURE); + if (ret < 0) + goto end; + ret = tas256x_set_samplerate(p_tas256x, p_tas256x->mn_sampling_rate); + if (ret < 0) + goto end; + ret = tas256x_set_power_state(p_tas256x, channel_both, + p_tas256x->mn_power_state); + if (ret < 0) + goto end; + +end: + /* power up failed, restart later */ + if (ret < 0) { + if (p_tas256x->mn_err_code & + (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM)) + failsafe(p_tas256x); + } + + p_tas256x->enable_irq(p_tas256x, true); +} + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("TAS256X ALSA SOC Smart Amplifier driver"); +MODULE_LICENSE("GPL v2"); +#endif /* CONFIG_TAS256X_CODEC */ diff --git a/techpack/audio/asoc/codecs/tas256x/tas256x-codec.h b/techpack/audio/asoc/codecs/tas256x/tas256x-codec.h new file mode 100644 index 000000000000..a16782176815 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/tas256x-codec.h @@ -0,0 +1,33 @@ +/* + * ============================================================================= + * Copyright (c) 2016 Texas Instruments Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * 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; version 2. + * + * 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. + * + * File: + * tas256x-codec.h + * + * Description: + * header file for tas256x-codec.c + * + * ============================================================================= + */ + +#ifndef _TAS256X_CODEC_H +#define _TAS256X_CODEC_H + +#include "tas256x.h" + +int tas256x_register_codec(struct tas256x_priv *p_tas256x); +int tas256x_deregister_codec(struct tas256x_priv *p_tas256x); +int tas256x_load_config(struct tas256x_priv *p_tas256x); +void tas_reload(struct tas256x_priv *p_tas256x, int chn); + +#endif /* _TAS256X_CODEC_H */ diff --git a/techpack/audio/asoc/codecs/tas256x/tas256x-device.h b/techpack/audio/asoc/codecs/tas256x/tas256x-device.h new file mode 100644 index 000000000000..03da258b6df7 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/tas256x-device.h @@ -0,0 +1,152 @@ +#ifndef __TAS256X_DEVICE_ +#define __TAS256X_DEVICE_ + +#include "tas256x.h" +#include +#define DEVICE_TAS2558 0x2558 +#define DEVICE_TAS2562 0x2562 +#define DEVICE_TAS2564 0x2564 + +#define DVC_PCM 0x1 +#define LIM_MAX_ATN 0x2 +#define LIMB_TH_MAX_MIN 0x3 +#define LIMB_INF_PT 0x4 +#define LIMB_SLOPE 0x5 +#define BOP_BOSD_TH 0x6 +#define LIMB_ATK_RT 0x7 +#define LIMB_RLS_RT 0x8 +#define LIMB_ATK_ST 0x9 +#define LIMB_RLS_ST 0xA +#define BOP_ATK_RT 0xB +#define BOP_ATK_ST 0xC +#define BOP_HLD_TM 0xD +#define BST_VREG 0xE +#define BST_ILIM 0xF + +int tas56x_software_reset(struct tas256x_priv *p_tas256x, int ch); + +int tas56x_get_chipid(struct tas256x_priv *p_tas256x, int *chipid, int ch); + +/* Power Up related functions */ +int tas256x_set_power_up(struct tas256x_priv *p_tas256x, enum channel chn); + +int tas256x_set_power_mute(struct tas256x_priv *p_tas256x, enum channel chn); + +int tas256x_set_power_shutdown(struct tas256x_priv *p_tas256x, + enum channel chn); + +int tas256x_power_check(struct tas256x_priv *p_tas256x, int *state, int ch); + +/* IV Sense Format Related functions */ +int tas256x_iv_sense_enable_set(struct tas256x_priv *p_tas256x, bool enable, + int ch); + +bool tas256x_iv_sense_enable_get(struct tas256x_priv *p_tas256x, int ch); + +int tas256x_iv_slot_config(struct tas256x_priv *p_tas256x); + +int tas256x_iv_bitwidth_config(struct tas256x_priv *p_tas256x); + +int tas256x_set_tx_config(struct tas256x_priv *p_tas256x, int value, int ch); + +/* Rx Format Related functions */ +int tas256x_set_samplerate(struct tas256x_priv *p_tas256x, int samplerate); + +int tas256x_rx_set_fmt(struct tas256x_priv *p_tas256x, unsigned int rx_edge, + unsigned int rx_start_slot); + +int tas256x_rx_set_slot(struct tas256x_priv *p_tas256x, int slot_width); + +int tas256x_rx_set_bitwidth(struct tas256x_priv *p_tas256x, int bitwidth); + +/* Interrupt Related Functions */ +int tas256x_interrupt_clear(struct tas256x_priv *p_tas256x, int ch); + +int tas256x_interrupt_enable(struct tas256x_priv *p_tas256x, int val, int ch); + +int tas256x_interrupt_read(struct tas256x_priv *p_tas256x, int *intr1, + int *intr2, int ch); + +int tas256x_interrupt_determine(struct tas256x_priv *p_tas256x, int ch, + int int1status, int int2status); + +/* ICN Related Functions */ +int tas256x_icn_enable(struct tas256x_priv *p_tas256x, int enable, int ch); + +int tas256x_icn_data(struct tas256x_priv *p_tas256x, int ch); + +int tas256x_icn_config(struct tas256x_priv *p_tas256x, int value, int ch); + +/* Boost/Volt Related functions */ +int tas256x_boost_volt_update(struct tas256x_priv *p_tas256x, int value, + int ch); + +int tas256x_set_misc_config(struct tas256x_priv *p_tas256x, int value, int ch); + +/* Clock Configuration */ +int tas256x_set_clock_config(struct tas256x_priv *p_tas256x, int value, int ch); + +/* ClassH Configuration*/ +int tas256x_set_classH_config(struct tas256x_priv *p_tas256x, int value, + int ch); + +/* HPF Related functions*/ +int tas256x_HPF_FF_Bypass(struct tas256x_priv *p_tas256x, int value, int ch); + +int tas256x_HPF_FB_Bypass(struct tas256x_priv *p_tas256x, int value, int ch); + +/*Speaker Receiever mode - specific to TAS2564*/ +int tas2564_rx_mode_update(struct tas256x_priv *p_tas256x, int rx_mode, int ch); + +/*Playback Volume*/ +int tas256x_update_playback_volume(struct tas256x_priv *p_tas256x, int value, + int ch); + +/*Limiter Related functions*/ +int tas256x_update_lim_max_attenuation(struct tas256x_priv *p_tas256x, + int value, int ch); +int tas256x_update_lim_max_thr(struct tas256x_priv *p_tas256x, int value, + int ch); +int tas256x_update_lim_min_thr(struct tas256x_priv *p_tas256x, int value, + int ch); +int tas256x_update_lim_inflection_point(struct tas256x_priv *p_tas256x, + int value, int ch); +int tas256x_update_lim_slope(struct tas256x_priv *p_tas256x, int value, int ch); + +/*Brown Out Protection related functions*/ +int tas256x_update_bop_thr(struct tas256x_priv *p_tas256x, int value, int ch); +int tas256x_update_bosd_thr(struct tas256x_priv *p_tas256x, int value, int ch); + +int tas256x_update_boost_voltage(struct tas256x_priv *p_tas256x, int value, + int ch); +int tas256x_update_current_limit(struct tas256x_priv *p_tas256x, int value, + int ch); +int tas256x_update_limiter_enable(struct tas256x_priv *p_tas256x, int value, + int ch); +int tas256x_update_limiter_attack_rate(struct tas256x_priv *p_tas256x, + int value, int ch); +int tas256x_update_limiter_attack_step_size(struct tas256x_priv *p_tas256x, + int value, int ch); +int tas256x_update_limiter_release_rate(struct tas256x_priv *p_tas256x, + int value, int ch); +int tas256x_update_limiter_release_step_size(struct tas256x_priv *p_tas256x, + int value, int ch); +int tas256x_update_bop_enable(struct tas256x_priv *p_tas256x, int value, + int ch); +int tas256x_update_bop_mute(struct tas256x_priv *p_tas256x, int value, int ch); +int tas256x_update_bop_shutdown_enable(struct tas256x_priv *p_tas256x, + int value, int ch); +int tas256x_update_bop_attack_rate(struct tas256x_priv *p_tas256x, int value, + int ch); +int tas256x_update_bop_attack_step_size(struct tas256x_priv *p_tas256x, + int value, int ch); +int tas256x_update_bop_hold_time(struct tas256x_priv *p_tas256x, int value, + int ch); +int tas256x_update_vbat_lpf(struct tas256x_priv *p_tas256x, int value, int ch); + +/*Initialize to defaults*/ +int tas256x_update_default_params(struct tas256x_priv *p_tas256x, int ch); + +int tas256x_update_rx_cfg(struct tas256x_priv *p_tas256x, int value, int ch); + +#endif /* __TAS256X_DEVICE_ */ \ No newline at end of file diff --git a/techpack/audio/asoc/codecs/tas256x/tas256x-regmap.c b/techpack/audio/asoc/codecs/tas256x/tas256x-regmap.c new file mode 100644 index 000000000000..02f8090cbf13 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/tas256x-regmap.c @@ -0,0 +1,1931 @@ +/* + * ALSA SoC Texas Instruments TAS256X High Performance 4W Smart Amplifier + * + * Copyright (C) 2016 Texas Instruments, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * Author: saiprasad + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ +#ifdef CONFIG_TAS256X_REGMAP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tas256x.h" +#include "tas2562.h" +#include "tas2564.h" +#include "tas256x-device.h" +#include "tas256x-codec.h" + +#ifdef CONFIG_TAS25XX_ALGO +#ifdef CONFIG_PLATFORM_EXYNOS +#include +#else +#include +#endif +static dc_detection_data_t s_dc_detect; +#endif /*CONFIG_TAS25XX_ALGO*/ + +/*For mixer_control implementation*/ +#define MAX_STRING 200 + +static const char *dts_tag[][3] = { + { "ti,left-channel", "ti,reset-gpio", "ti,irq-gpio" }, + { "ti,right-channel", "ti,reset-gpio2", "ti,irq-gpio2" } +}; + +static const char *reset_gpio_label[2] = { "TAS256X_RESET", "TAS256X_RESET2" }; + +static const char *irq_gpio_label[2] = { "TAS256X-IRQ", "TAS256X-IRQ2" }; + +static int tas256x_regmap_write(struct tas256x_priv *p_tas256x, + unsigned int reg, unsigned int value) +{ + int nResult = 0; + int retry_count = TAS256X_I2C_RETRY_COUNT; + + if (p_tas256x->i2c_suspend) + return ERROR_I2C_SUSPEND; + + while (retry_count--) { + nResult = regmap_write(p_tas256x->regmap, reg, value); + if (nResult >= 0) + break; + msleep(20); + } + if (retry_count == -1) + return ERROR_I2C_FAILED; + else + return 0; +} + +static int tas256x_regmap_bulk_write(struct tas256x_priv *p_tas256x, + unsigned int reg, unsigned char *pData, + unsigned int nLength) +{ + int nResult = 0; + int retry_count = TAS256X_I2C_RETRY_COUNT; + + if (p_tas256x->i2c_suspend) + return ERROR_I2C_SUSPEND; + + while (retry_count--) { + nResult = regmap_bulk_write(p_tas256x->regmap, reg, pData, + nLength); + if (nResult >= 0) + break; + msleep(20); + } + if (retry_count == -1) + return ERROR_I2C_FAILED; + else + return 0; +} + +static int tas256x_regmap_read(struct tas256x_priv *p_tas256x, unsigned int reg, + unsigned int *value) +{ + int nResult = 0; + int retry_count = TAS256X_I2C_RETRY_COUNT; + + if (p_tas256x->i2c_suspend) + return ERROR_I2C_SUSPEND; + + while (retry_count--) { + nResult = regmap_read(p_tas256x->regmap, reg, value); + if (nResult >= 0) + break; + msleep(20); + } + if (retry_count == -1) + return ERROR_I2C_FAILED; + else + return 0; +} + +static int tas256x_regmap_bulk_read(struct tas256x_priv *p_tas256x, + unsigned int reg, unsigned char *pData, + unsigned int nLength) +{ + int nResult = 0; + int retry_count = TAS256X_I2C_RETRY_COUNT; + + if (p_tas256x->i2c_suspend) + return ERROR_I2C_SUSPEND; + + while (retry_count--) { + nResult = regmap_bulk_read(p_tas256x->regmap, reg, pData, + nLength); + if (nResult >= 0) + break; + msleep(20); + } + if (retry_count == -1) + return ERROR_I2C_FAILED; + else + return 0; +} + +static int tas256x_regmap_update_bits(struct tas256x_priv *p_tas256x, + unsigned int reg, unsigned int mask, + unsigned int value) +{ + int nResult = 0; + int retry_count = TAS256X_I2C_RETRY_COUNT; + + if (p_tas256x->i2c_suspend) + return ERROR_I2C_SUSPEND; + + while (retry_count--) { + nResult = + regmap_update_bits(p_tas256x->regmap, reg, mask, value); + if (nResult >= 0) + break; + msleep(20); + } + if (retry_count == -1) + return ERROR_I2C_FAILED; + else + return 0; +} + +static int tas256x_change_book_page(struct tas256x_priv *p_tas256x, + enum channel chn, int book, int page) +{ + int n_result = 0, rc = 0; + int i = 0; + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (((chn & channel_left) && (i == 0)) || + ((chn & channel_right) && (i == 1))) { + p_tas256x->client->addr = p_tas256x->devs[i]->mn_addr; + if (p_tas256x->devs[i]->mn_current_book != book) { + n_result = tas256x_regmap_write( + p_tas256x, TAS256X_BOOKCTL_PAGE, 0); + if (n_result < 0) { + dev_err(p_tas256x->dev, + "%s, ERROR, L=%d, E=%d\n", + __func__, __LINE__, n_result); + rc |= n_result; + continue; + } + p_tas256x->devs[i]->mn_current_page = 0; + n_result = tas256x_regmap_write( + p_tas256x, TAS256X_BOOKCTL_REG, book); + if (n_result < 0) { + dev_err(p_tas256x->dev, + "%s, ERROR, L=%d, E=%d\n", + __func__, __LINE__, n_result); + rc |= n_result; + continue; + } + p_tas256x->devs[i]->mn_current_book = book; + } + + if (p_tas256x->devs[i]->mn_current_page != page) { + n_result = tas256x_regmap_write( + p_tas256x, TAS256X_BOOKCTL_PAGE, page); + if (n_result < 0) { + dev_err(p_tas256x->dev, + "%s, ERROR, L=%d, E=%d\n", + __func__, __LINE__, n_result); + rc |= n_result; + continue; + } + p_tas256x->devs[i]->mn_current_page = page; + } + } + } + if (rc < 0) { + if (chn & channel_left) + p_tas256x->mn_err_code |= ERROR_DEVA_I2C_COMM; + if (chn & channel_right) + p_tas256x->mn_err_code |= ERROR_DEVB_I2C_COMM; + } else { + if (chn & channel_left) + p_tas256x->mn_err_code &= ~ERROR_DEVA_I2C_COMM; + if (chn & channel_right) + p_tas256x->mn_err_code &= ~ERROR_DEVB_I2C_COMM; + } + + return rc; +} + +static int tas256x_dev_read(struct tas256x_priv *p_tas256x, enum channel chn, + unsigned int reg, unsigned int *pValue) +{ + int n_result = 0; + + mutex_lock(&p_tas256x->dev_lock); + + n_result = tas256x_change_book_page( + p_tas256x, chn, TAS256X_BOOK_ID(reg), TAS256X_PAGE_ID(reg)); + if (n_result < 0) + goto end; + + /*Force left incase of mono*/ + if ((chn == channel_right) && (p_tas256x->mn_channels == 1)) + chn = channel_left; + + if ((chn == channel_left) || (p_tas256x->mn_channels == 1)) + p_tas256x->client->addr = p_tas256x->devs[chn >> 1]->mn_addr; + else if (chn == channel_right) + p_tas256x->client->addr = p_tas256x->devs[chn >> 1]->mn_addr; + else + dev_err(p_tas256x->dev, "%s, wrong channel number\n", __func__); + + n_result = + tas256x_regmap_read(p_tas256x, TAS256X_PAGE_REG(reg), pValue); + if (n_result < 0) { + dev_err(p_tas256x->dev, "%s, ERROR, L=%d, E=%d\n", __func__, + __LINE__, n_result); + if (chn & channel_left) + p_tas256x->mn_err_code |= ERROR_DEVA_I2C_COMM; + if (chn & channel_right) + p_tas256x->mn_err_code |= ERROR_DEVB_I2C_COMM; + } else { + dev_dbg(p_tas256x->dev, + "%s: chn:%x:BOOK:PAGE:REG 0x%02x:0x%02x:0x%02x,0x%02x\n", + __func__, p_tas256x->client->addr, TAS256X_BOOK_ID(reg), + TAS256X_PAGE_ID(reg), TAS256X_PAGE_REG(reg), *pValue); + if (chn & channel_left) + p_tas256x->mn_err_code &= ~ERROR_DEVA_I2C_COMM; + if (chn & channel_right) + p_tas256x->mn_err_code &= ~ERROR_DEVB_I2C_COMM; + } +end: + mutex_unlock(&p_tas256x->dev_lock); + return n_result; +} + +static int tas256x_dev_write(struct tas256x_priv *p_tas256x, enum channel chn, + unsigned int reg, unsigned int value) +{ + int n_result = 0, rc = 0; + int i = 0; + + mutex_lock(&p_tas256x->dev_lock); + + n_result = tas256x_change_book_page( + p_tas256x, chn, TAS256X_BOOK_ID(reg), TAS256X_PAGE_ID(reg)); + if (n_result < 0) + goto end; + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (((chn & channel_left) && (i == 0)) || + ((chn & channel_right) && (i == 1))) { + p_tas256x->client->addr = p_tas256x->devs[i]->mn_addr; + + n_result = tas256x_regmap_write( + p_tas256x, TAS256X_PAGE_REG(reg), value); + if (n_result < 0) { + dev_err(p_tas256x->dev, + "%s, ERROR, L=%u, chn=0x%02x, E=%d\n", + __func__, __LINE__, + p_tas256x->client->addr, n_result); + rc |= n_result; + if (chn & channel_left) + p_tas256x->mn_err_code |= + ERROR_DEVA_I2C_COMM; + if (chn & channel_right) + p_tas256x->mn_err_code |= + ERROR_DEVB_I2C_COMM; + } else { + dev_dbg(p_tas256x->dev, + "%s: %u: chn:0x%02x:BOOK:PAGE:REG 0x%02x:0x%02x:0x%02x, VAL: 0x%02x\n", + __func__, __LINE__, + p_tas256x->client->addr, + TAS256X_BOOK_ID(reg), + TAS256X_PAGE_ID(reg), + TAS256X_PAGE_REG(reg), value); + if (chn & channel_left) + p_tas256x->mn_err_code &= + ~ERROR_DEVA_I2C_COMM; + if (chn & channel_right) + p_tas256x->mn_err_code &= + ~ERROR_DEVB_I2C_COMM; + } + } + } +end: + mutex_unlock(&p_tas256x->dev_lock); + return rc; +} + +static int tas256x_dev_bulk_write(struct tas256x_priv *p_tas256x, + enum channel chn, unsigned int reg, + unsigned char *p_data, unsigned int n_length) +{ + int n_result = 0, rc = 0; + int i = 0; + + mutex_lock(&p_tas256x->dev_lock); + + n_result = tas256x_change_book_page( + p_tas256x, chn, TAS256X_BOOK_ID(reg), TAS256X_PAGE_ID(reg)); + if (n_result < 0) + goto end; + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (((chn & channel_left) && (i == 0)) || + ((chn & channel_right) && (i == 1))) { + p_tas256x->client->addr = p_tas256x->devs[i]->mn_addr; + n_result = + tas256x_regmap_bulk_write(p_tas256x, + TAS256X_PAGE_REG(reg), + p_data, n_length); + if (n_result < 0) { + dev_err(p_tas256x->dev, + "%s, ERROR, L=%u, chn=0x%02x: E=%d\n", + __func__, __LINE__, + p_tas256x->client->addr, n_result); + rc |= n_result; + if (chn & channel_left) + p_tas256x->mn_err_code |= + ERROR_DEVA_I2C_COMM; + if (chn & channel_right) + p_tas256x->mn_err_code |= + ERROR_DEVB_I2C_COMM; + } else { + dev_dbg(p_tas256x->dev, + "%s: chn%x:BOOK:PAGE:REG 0x%02x:0x%02x:0x%02x, len: %u\n", + __func__, p_tas256x->client->addr, + TAS256X_BOOK_ID(reg), + TAS256X_PAGE_ID(reg), + TAS256X_PAGE_REG(reg), n_length); + if (chn & channel_left) + p_tas256x->mn_err_code &= + ~ERROR_DEVA_I2C_COMM; + if (chn & channel_right) + p_tas256x->mn_err_code &= + ~ERROR_DEVB_I2C_COMM; + } + } + } + +end: + mutex_unlock(&p_tas256x->dev_lock); + return rc; +} + +static int tas256x_dev_bulk_read(struct tas256x_priv *p_tas256x, + enum channel chn, unsigned int reg, + unsigned char *p_data, unsigned int n_length) +{ + int n_result = 0; + + mutex_lock(&p_tas256x->dev_lock); + + if ((chn == channel_left) || (p_tas256x->mn_channels == 1)) + p_tas256x->client->addr = p_tas256x->devs[chn >> 1]->mn_addr; + else if (chn == channel_right) + p_tas256x->client->addr = p_tas256x->devs[chn >> 1]->mn_addr; + else + dev_err(p_tas256x->dev, "%s, wrong channel number\n", __func__); + + n_result = tas256x_change_book_page( + p_tas256x, chn, TAS256X_BOOK_ID(reg), TAS256X_PAGE_ID(reg)); + if (n_result < 0) + goto end; + + n_result = tas256x_regmap_bulk_read(p_tas256x, TAS256X_PAGE_REG(reg), + p_data, n_length); + if (n_result < 0) { + dev_err(p_tas256x->dev, "%s, ERROR, L=%d, E=%d\n", __func__, + __LINE__, n_result); + if (chn & channel_left) + p_tas256x->mn_err_code |= ERROR_DEVA_I2C_COMM; + if (chn & channel_right) + p_tas256x->mn_err_code |= ERROR_DEVB_I2C_COMM; + } else { + dev_dbg(p_tas256x->dev, + "%s: chn%x:BOOK:PAGE:REG %u:%u:%u, len: 0x%02x\n", + __func__, p_tas256x->client->addr, TAS256X_BOOK_ID(reg), + TAS256X_PAGE_ID(reg), TAS256X_PAGE_REG(reg), n_length); + if (chn & channel_left) + p_tas256x->mn_err_code &= ~ERROR_DEVA_I2C_COMM; + if (chn & channel_right) + p_tas256x->mn_err_code &= ~ERROR_DEVB_I2C_COMM; + } +end: + mutex_unlock(&p_tas256x->dev_lock); + return n_result; +} + +static int tas256x_dev_update_bits(struct tas256x_priv *p_tas256x, + enum channel chn, unsigned int reg, + unsigned int mask, unsigned int value) +{ + int n_result = 0, rc = 0; + int i = 0; + + mutex_lock(&p_tas256x->dev_lock); + n_result = tas256x_change_book_page( + p_tas256x, chn, TAS256X_BOOK_ID(reg), TAS256X_PAGE_ID(reg)); + if (n_result < 0) { + rc = n_result; + goto end; + } + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (((chn & channel_left) && (i == 0)) || + ((chn & channel_right) && (i == 1))) { + p_tas256x->client->addr = p_tas256x->devs[i]->mn_addr; + n_result = tas256x_regmap_update_bits( + p_tas256x, TAS256X_PAGE_REG(reg), mask, value); + if (n_result < 0) { + dev_err(p_tas256x->dev, + "%s, ERROR, L=%u, chn=0x%02x: E=%d\n", + __func__, __LINE__, + p_tas256x->client->addr, n_result); + rc |= n_result; + if (chn & channel_left) + p_tas256x->mn_err_code |= + ERROR_DEVA_I2C_COMM; + if (chn & channel_right) + p_tas256x->mn_err_code |= + ERROR_DEVB_I2C_COMM; + } else { + dev_dbg(p_tas256x->dev, + "%s: chn%x:BOOK:PAGE:REG 0x%02x:0x%02x:0x%02x, mask: 0x%02x, val: 0x%02x\n", + __func__, p_tas256x->client->addr, + TAS256X_BOOK_ID(reg), + TAS256X_PAGE_ID(reg), + TAS256X_PAGE_REG(reg), mask, value); + if (chn & channel_left) + p_tas256x->mn_err_code &= + ~ERROR_DEVA_I2C_COMM; + if (chn & channel_right) + p_tas256x->mn_err_code &= + ~ERROR_DEVB_I2C_COMM; + } + } + } + +end: + mutex_unlock(&p_tas256x->dev_lock); + return rc; +} + +static int tas2558_specific(struct tas256x_priv *p_tas256x, int chn) +{ + int ret = 0; + + ret = tas256x_boost_volt_update(p_tas256x, DEVICE_TAS2558, chn); + + return ret; +} + +static int tas2564_specific(struct tas256x_priv *p_tas256x, int chn) +{ + int ret = 0; + + ret = tas256x_boost_volt_update(p_tas256x, DEVICE_TAS2564, chn); + ret |= tas2564_rx_mode_update(p_tas256x, 0, chn); + + return ret; +} + +static char const *tas2564_rx_mode_text[] = { "Speaker", "Receiver" }; + +static const struct soc_enum tas2564_rx_mode_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas2564_rx_mode_text), + tas2564_rx_mode_text), +}; + +static int tas2564_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); +#endif + struct tas256x_priv *p_tas256x = NULL; + int ret = -1; + + if (codec == NULL) { + pr_err("%s:codec is NULL\n", __func__); + return ret; + } + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + p_tas256x = snd_soc_component_get_drvdata(codec); +#else + p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + if (p_tas256x == NULL) { + pr_err("%s:p_tas256x is NULL\n", __func__); + return ret; + } + + if (strnstr(ucontrol->id.name, "LEFT", MAX_STRING)) + ret = tas2564_rx_mode_update(p_tas256x, + ucontrol->value.integer.value[0], + channel_left); + else if (strnstr(ucontrol->id.name, "RIGHT", MAX_STRING)) + ret = tas2564_rx_mode_update(p_tas256x, + ucontrol->value.integer.value[0], + channel_right); + else + dev_err(p_tas256x->dev, "Invalid Channel %s\n", + ucontrol->id.name); + + return ret; +} + +static int tas2564_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = -1; +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); +#endif + struct tas256x_priv *p_tas256x = NULL; + + if (codec == NULL) { + pr_err("%s:codec is NULL\n", __func__); + return ret; + } + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + p_tas256x = snd_soc_component_get_drvdata(codec); +#else + p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + if (p_tas256x == NULL) { + pr_err("%s:p_tas256x is NULL\n", __func__); + return ret; + } + + if (strnstr(ucontrol->id.name, "LEFT", MAX_STRING)) + ucontrol->value.integer.value[0] = p_tas256x->devs[0]->rx_mode; + else if (strnstr(ucontrol->id.name, "RIGHT", MAX_STRING)) + ucontrol->value.integer.value[0] = p_tas256x->devs[1]->rx_mode; + else + dev_err(p_tas256x->dev, "Invalid Channel %s\n", + ucontrol->id.name); + + return 0; +} + +static int tas256x_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); +#endif + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct tas256x_priv *p_tas256x = NULL; + int ret = -1; + + if ((codec == NULL) || (mc == NULL)) { + pr_err("%s:codec or control is NULL\n", __func__); + return ret; + } + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + p_tas256x = snd_soc_component_get_drvdata(codec); +#else + p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + if (p_tas256x == NULL) { + pr_err("%s:p_tas256x is NULL\n", __func__); + return ret; + } + + if (ucontrol->value.integer.value[0] > mc->max) + return ret; + + switch (mc->reg) { + case DVC_PCM: + ret = tas256x_update_playback_volume( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + break; + case LIM_MAX_ATN: + ret = tas256x_update_lim_max_attenuation( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + break; + case LIMB_INF_PT: + ret = tas256x_update_lim_inflection_point( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + break; + case LIMB_SLOPE: + ret = tas256x_update_lim_slope( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + break; + case LIMB_ATK_RT: + ret = tas256x_update_limiter_attack_rate( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + break; + case LIMB_RLS_RT: + ret = tas256x_update_limiter_release_rate( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + break; + case LIMB_RLS_ST: + ret = tas256x_update_limiter_release_step_size( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + break; + case LIMB_ATK_ST: + ret = tas256x_update_limiter_attack_step_size( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + break; + case BOP_ATK_RT: + ret = tas256x_update_bop_attack_rate( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + break; + case BOP_ATK_ST: + ret = tas256x_update_bop_attack_step_size( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + break; + case BOP_HLD_TM: + ret = tas256x_update_bop_hold_time( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + break; + case BST_VREG: + ret = tas256x_update_boost_voltage( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + break; + case BST_ILIM: + ret = tas256x_update_current_limit( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + break; + } + return ret; +} + +static int tas256x_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); +#endif + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct tas256x_priv *p_tas256x = NULL; + int ret = -1; + + if ((codec == NULL) || (mc == NULL)) { + pr_err("%s:codec or control is NULL\n", __func__); + return ret; + } + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + p_tas256x = snd_soc_component_get_drvdata(codec); +#else + p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + if (p_tas256x == NULL) { + pr_err("%s:p_tas256x is NULL\n", __func__); + return ret; + } + + switch (mc->reg) { + case DVC_PCM: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->dvc_pcm; + break; + case LIM_MAX_ATN: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->lim_max_attn; + break; + case LIMB_INF_PT: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->lim_infl_pt; + break; + case LIMB_SLOPE: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->lim_trk_slp; + break; + case LIMB_ATK_RT: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->lim_att_rate; + break; + case LIMB_RLS_RT: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->lim_rel_rate; + break; + case LIMB_RLS_ST: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->lim_rel_stp_size; + break; + case LIMB_ATK_ST: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->lim_att_stp_size; + break; + case BOP_ATK_RT: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->bop_att_rate; + break; + case BOP_ATK_ST: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->bop_att_stp_size; + break; + case BOP_HLD_TM: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->bop_hld_time; + break; + case BST_VREG: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->bst_vltg; + break; + case BST_ILIM: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->bst_ilm; + break; + } + return 0; +} + +static int tas256x_multi_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); +#endif + struct soc_multi_mixer_control *mc = + (struct soc_multi_mixer_control *)kcontrol->private_value; + struct tas256x_priv *p_tas256x = NULL; + int ret = -1; + + if ((codec == NULL) || (mc == NULL)) { + pr_err("%s:codec or control is NULL\n", __func__); + return ret; + } + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + p_tas256x = snd_soc_component_get_drvdata(codec); +#else + p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + if (p_tas256x == NULL) { + pr_err("%s:p_tas256x is NULL\n", __func__); + return ret; + } + + if ((ucontrol->value.integer.value[0] > mc->max) || + (ucontrol->value.integer.value[1] > mc->max)) + return ret; + + switch (mc->reg) { + case LIMB_TH_MAX_MIN: + ret = tas256x_update_lim_max_thr( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + ret = tas256x_update_lim_min_thr( + p_tas256x, ucontrol->value.integer.value[1], mc->shift); + break; + case BOP_BOSD_TH: + ret = tas256x_update_bop_thr( + p_tas256x, ucontrol->value.integer.value[0], mc->shift); + ret = tas256x_update_bosd_thr( + p_tas256x, ucontrol->value.integer.value[1], mc->shift); + break; + } + return ret; +} + +static int tas256x_multi_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); +#endif + struct soc_multi_mixer_control *mc = + (struct soc_multi_mixer_control *)kcontrol->private_value; + struct tas256x_priv *p_tas256x = NULL; + int ret = -1; + + if ((codec == NULL) || (mc == NULL)) { + pr_err("%s:codec or control is NULL\n", __func__); + return ret; + } + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + p_tas256x = snd_soc_component_get_drvdata(codec); +#else + p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + if (p_tas256x == NULL) { + pr_err("%s:p_tas256x is NULL\n", __func__); + return ret; + } + + switch (mc->reg) { + case LIMB_TH_MAX_MIN: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->lim_thr_max; + ucontrol->value.integer.value[1] = + p_tas256x->devs[mc->shift - 1]->lim_thr_min; + break; + case BOP_BOSD_TH: + ucontrol->value.integer.value[0] = + p_tas256x->devs[mc->shift - 1]->bop_thd; + ucontrol->value.integer.value[1] = + p_tas256x->devs[mc->shift - 1]->bosd_thd; + break; + } + return 0; +} + +static int tas256x_enum_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = -1; +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); +#endif + struct tas256x_priv *p_tas256x = NULL; + + if (codec == NULL) { + pr_err("%s:codec is NULL\n", __func__); + return ret; + } + + if (ucontrol == NULL) { + pr_err("%s:ucontrol is NULL\n", __func__); + return ret; + } + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + p_tas256x = snd_soc_component_get_drvdata(codec); +#else + p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + if (p_tas256x == NULL) { + pr_err("%s:p_tas256x is NULL\n", __func__); + return ret; + } + + if (strnstr(ucontrol->id.name, "LEFT", MAX_STRING)) { + if (strnstr(ucontrol->id.name, "LIMITER SWITCH", MAX_STRING)) + ucontrol->value.integer.value[0] = + p_tas256x->devs[0]->lim_switch; + else if (strnstr(ucontrol->id.name, "BOP ENABLE", MAX_STRING)) + ucontrol->value.integer.value[0] = + p_tas256x->devs[0]->bop_enable; + else if (strnstr(ucontrol->id.name, "BOP MUTE", MAX_STRING)) + ucontrol->value.integer.value[0] = + p_tas256x->devs[0]->bop_mute; + else if (strnstr(ucontrol->id.name, "BROWNOUT SHUTDOWN", + MAX_STRING)) + ucontrol->value.integer.value[0] = + p_tas256x->devs[0]->bosd_enable; + else if (strnstr(ucontrol->id.name, "VBAT LPF", MAX_STRING)) + ucontrol->value.integer.value[0] = + p_tas256x->devs[0]->vbat_lpf; + else + dev_err(p_tas256x->dev, "Invalid controll %s\n", + ucontrol->id.name); + } else if (strnstr(ucontrol->id.name, "RIGHT", MAX_STRING)) { + if (strnstr(ucontrol->id.name, "LIMITER SWITCH", MAX_STRING)) + ucontrol->value.integer.value[0] = + p_tas256x->devs[1]->lim_switch; + else if (strnstr(ucontrol->id.name, "BOP ENABLE", MAX_STRING)) + ucontrol->value.integer.value[0] = + p_tas256x->devs[1]->bop_enable; + else if (strnstr(ucontrol->id.name, "BOP MUTE", MAX_STRING)) + ucontrol->value.integer.value[0] = + p_tas256x->devs[1]->bop_mute; + else if (strnstr(ucontrol->id.name, "BROWNOUT SHUTDOWN", + MAX_STRING)) + ucontrol->value.integer.value[0] = + p_tas256x->devs[1]->bosd_enable; + else if (strnstr(ucontrol->id.name, "VBAT LPF", MAX_STRING)) + ucontrol->value.integer.value[0] = + p_tas256x->devs[1]->vbat_lpf; + else + dev_err(p_tas256x->dev, "Invalid controll %s\n", + ucontrol->id.name); + } else { + dev_err(p_tas256x->dev, "Invalid Channel %s\n", + ucontrol->id.name); + } + return 0; +} + +static int tas256x_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); +#else + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); +#endif + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct tas256x_priv *p_tas256x = NULL; + int ret = -1; + + if ((codec == NULL) || (mc == NULL)) { + pr_err("%s:codec or control is NULL\n", __func__); + return ret; + } + +#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE + p_tas256x = snd_soc_component_get_drvdata(codec); +#else + p_tas256x = snd_soc_codec_get_drvdata(codec); +#endif + if (p_tas256x == NULL) { + pr_err("%s:p_tas256x is NULL\n", __func__); + return ret; + } + + if (strnstr(ucontrol->id.name, "LEFT", MAX_STRING)) { + if (strnstr(ucontrol->id.name, "LIMITER SWITCH", MAX_STRING)) + ret = tas256x_update_limiter_enable( + p_tas256x, ucontrol->value.integer.value[0], + channel_left); + else if (strnstr(ucontrol->id.name, "BOP ENABLE", MAX_STRING)) + ret = tas256x_update_bop_enable( + p_tas256x, ucontrol->value.integer.value[0], + channel_left); + else if (strnstr(ucontrol->id.name, "BOP MUTE", MAX_STRING)) + ret = tas256x_update_bop_mute( + p_tas256x, ucontrol->value.integer.value[0], + channel_left); + else if (strnstr(ucontrol->id.name, "BROWNOUT SHUTDOWN", + MAX_STRING)) + ret = tas256x_update_bop_shutdown_enable( + p_tas256x, ucontrol->value.integer.value[0], + channel_left); + else if (strnstr(ucontrol->id.name, "VBAT LPF", MAX_STRING)) + ret = tas256x_update_vbat_lpf( + p_tas256x, ucontrol->value.integer.value[0], + channel_left); + else + dev_err(p_tas256x->dev, "Invalid Control %s\n", + ucontrol->id.name); + } else if (strnstr(ucontrol->id.name, "RIGHT", MAX_STRING)) { + if (strnstr(ucontrol->id.name, "LIMITER SWITCH", MAX_STRING)) + ret = tas256x_update_limiter_enable( + p_tas256x, ucontrol->value.integer.value[0], + channel_right); + else if (strnstr(ucontrol->id.name, "BOP ENABLE", MAX_STRING)) + ret = tas256x_update_bop_enable( + p_tas256x, ucontrol->value.integer.value[0], + channel_right); + else if (strnstr(ucontrol->id.name, "BOP MUTE", MAX_STRING)) + ret = tas256x_update_bop_mute( + p_tas256x, ucontrol->value.integer.value[0], + channel_right); + else if (strnstr(ucontrol->id.name, "BROWNOUT SHUTDOWN", + MAX_STRING)) + ret = tas256x_update_bop_shutdown_enable( + p_tas256x, ucontrol->value.integer.value[0], + channel_right); + else if (strnstr(ucontrol->id.name, "VBAT LPF", MAX_STRING)) + ret = tas256x_update_vbat_lpf( + p_tas256x, ucontrol->value.integer.value[0], + channel_right); + else + dev_err(p_tas256x->dev, "Invalid control %s\n", + ucontrol->id.name); + } else { + dev_err(p_tas256x->dev, "Invalid Channel %s\n", + ucontrol->id.name); + } + return ret; +} + +static char const *tas256x_rx_switch_text[] = { "DISABLE", "ENABLE" }; +static const struct soc_enum tas256x_rx_switch_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas256x_rx_switch_text), + tas256x_rx_switch_text), +}; + +static const struct snd_kcontrol_new tas256x_left_controls[] = { + SOC_SINGLE_EXT("TAS256X PLAYBACK VOLUME LEFT", DVC_PCM, 1, 56, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X LIM MAX ATTN LEFT", LIM_MAX_ATN, 1, 15, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_MULTI_EXT("TAS256X LIM THR MAX MIN LEFT", LIMB_TH_MAX_MIN, 1, + 26, 0, 2, tas256x_multi_get, tas256x_multi_put), + SOC_SINGLE_EXT("TAS256X LIM INFLECTION POINT LEFT", LIMB_INF_PT, 1, 40, + 0, tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X LIM SLOPE LEFT", LIMB_SLOPE, 1, 6, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_MULTI_EXT("TAS256X BOP THR SHUTDOWN THR LEFT", BOP_BOSD_TH, + 1, 15, 0, 2, tas256x_multi_get, tas256x_multi_put), + SOC_SINGLE_EXT("TAS256X LIM ATTACT RATE LEFT", LIMB_ATK_RT, 1, 7, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X LIM RELEASE RATE LEFT", LIMB_RLS_RT, 1, 7, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X LIM ATTACK STEP LEFT", LIMB_ATK_ST, 1, 3, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X LIM RELEASE STEP LEFT", LIMB_RLS_ST, 1, 3, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X BOP ATTACK RATE LEFT", BOP_ATK_RT, 1, 7, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X BOP ATTACK STEP LEFT", BOP_ATK_ST, 1, 3, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X BOP HOLD TIME LEFT", BOP_HLD_TM, 1, 7, 0, + tas256x_get, tas256x_put), + SOC_ENUM_EXT("TAS256X LIMITER SWITCH LEFT", tas256x_rx_switch_enum[0], + tas256x_enum_get, tas256x_enum_put), + SOC_ENUM_EXT("TAS256X BOP ENABLE LEFT", tas256x_rx_switch_enum[0], + tas256x_enum_get, tas256x_enum_put), + SOC_ENUM_EXT("TAS256X BOP MUTE LEFT", tas256x_rx_switch_enum[0], + tas256x_enum_get, tas256x_enum_put), + SOC_ENUM_EXT("TAS256X BROWNOUT SHUTDOWN LEFT", + tas256x_rx_switch_enum[0], tas256x_enum_get, + tas256x_enum_put), +}; + +static const struct snd_kcontrol_new tas256x_right_controls[] = { + SOC_SINGLE_EXT("TAS256X PLAYBACK VOLUME RIGHT", DVC_PCM, 2, 56, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X LIM MAX ATTN RIGHT", LIM_MAX_ATN, 2, 15, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_MULTI_EXT("TAS256X LIM THR MAX MIN RIGHT", LIMB_TH_MAX_MIN, + 2, 26, 0, 2, tas256x_multi_get, tas256x_multi_put), + SOC_SINGLE_EXT("TAS256X LIM INFLECTION POINT RIGHT", LIMB_INF_PT, 2, 40, + 0, tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X LIM SLOPE RIGHT", LIMB_SLOPE, 2, 6, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_MULTI_EXT("TAS256X BOP THR SHUTDOWN THR RIGHT", BOP_BOSD_TH, + 2, 15, 0, 2, tas256x_multi_get, tas256x_multi_put), + SOC_SINGLE_EXT("TAS256X LIM ATTACT RATE RIGHT", LIMB_ATK_RT, 2, 7, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X LIM RELEASE RATE RIGHT", LIMB_RLS_RT, 2, 7, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X LIM ATTACK STEP RIGHT", LIMB_ATK_ST, 2, 3, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X LIM RELEASE STEP RIGHT", LIMB_RLS_ST, 2, 3, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X BOP ATTACK RATE RIGHT", BOP_ATK_RT, 2, 7, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X BOP ATTACK STEP RIGHT", BOP_ATK_ST, 2, 3, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X BOP HOLD TIME RIGHT", BOP_HLD_TM, 2, 7, 0, + tas256x_get, tas256x_put), + SOC_ENUM_EXT("TAS256X LIMITER SWITCH RIGHT", tas256x_rx_switch_enum[0], + tas256x_enum_get, tas256x_enum_put), + SOC_ENUM_EXT("TAS256X BOP ENABLE RIGHT", tas256x_rx_switch_enum[0], + tas256x_enum_get, tas256x_enum_put), + SOC_ENUM_EXT("TAS256X BOP MUTE RIGHT", tas256x_rx_switch_enum[0], + tas256x_enum_get, tas256x_enum_put), + SOC_ENUM_EXT("TAS256X BROWNOUT SHUTDOWN RIGHT", + tas256x_rx_switch_enum[0], tas256x_enum_get, + tas256x_enum_put), +}; + +static char const *tas2564_vbat_lpf_text[] = { "DISABLE", "HZ_10", "HZ_100", + "KHZ_1" }; +static const struct soc_enum tas2564_vbat_lpf_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas2564_vbat_lpf_text), + tas2564_vbat_lpf_text), +}; + +static char const *tas2562_vbat_lpf_text[] = { "DISABLE", "HZ_100", "KHZ_1", + "KHZ_10" }; +static const struct soc_enum tas2562_vbat_lpf_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas2562_vbat_lpf_text), + tas2562_vbat_lpf_text), +}; + +static const struct snd_kcontrol_new tas2564_left_controls[] = { + SOC_ENUM_EXT("TAS256X RX MODE LEFT", tas2564_rx_mode_enum[0], + tas2564_get, tas2564_put), + SOC_ENUM_EXT("TAS256X VBAT LPF LEFT", tas2564_vbat_lpf_enum[0], + tas256x_enum_get, tas256x_enum_put), + SOC_SINGLE_EXT("TAS256X BOOST VOLTAGE LEFT", BST_VREG, 1, 15, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X BOOST CURRENT LEFT", BST_ILIM, 1, 63, 0, + tas256x_get, tas256x_put), +}; + +static const struct snd_kcontrol_new tas2564_right_controls[] = { + SOC_ENUM_EXT("TAS256X RX MODE RIGHT", tas2564_rx_mode_enum[0], + tas2564_get, tas2564_put), + SOC_ENUM_EXT("TAS256X VBAT LPF RIGHT", tas2564_vbat_lpf_enum[0], + tas256x_enum_get, tas256x_enum_put), + SOC_SINGLE_EXT("TAS256X BOOST VOLTAGE RIGHT", BST_VREG, 2, 15, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X BOOST CURRENT RIGHT", BST_ILIM, 2, 63, 0, + tas256x_get, tas256x_put), +}; + +static const struct snd_kcontrol_new tas2562_left_controls[] = { + SOC_ENUM_EXT("TAS256X VBAT LPF LEFT", tas2562_vbat_lpf_enum[0], + tas256x_enum_get, tas256x_enum_put), + SOC_SINGLE_EXT("TAS256X BOOST VOLTAGE LEFT", BST_VREG, 1, 12, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X BOOST CURRENT LEFT", BST_ILIM, 1, 55, 0, + tas256x_get, tas256x_put), +}; + +static const struct snd_kcontrol_new tas2562_right_controls[] = { + SOC_ENUM_EXT("TAS256X VBAT LPF RIGHT", tas2562_vbat_lpf_enum[0], + tas256x_enum_get, tas256x_enum_put), + SOC_SINGLE_EXT("TAS256X BOOST VOLTAGE RIGHT", BST_VREG, 2, 12, 0, + tas256x_get, tas256x_put), + SOC_SINGLE_EXT("TAS256X BOOST CURRENT RIGHT", BST_ILIM, 2, 55, 0, + tas256x_get, tas256x_put), +}; + +static int tas2564_probe(struct tas256x_priv *p_tas256x, + struct snd_soc_codec *codec, int chn) +{ + int ret = -1; + + if ((!p_tas256x) || (!codec)) { + pr_err("tas256x:%s p_tas256x or codec is Null\n", __func__); + return ret; + } + dev_dbg(p_tas256x->dev, "%s channel %d", __func__, chn); + + tas256x_update_default_params(p_tas256x, chn); + if (chn == channel_left) { + ret = snd_soc_add_codec_controls( + codec, tas256x_left_controls, + ARRAY_SIZE(tas256x_left_controls)); + ret = snd_soc_add_codec_controls( + codec, tas2564_left_controls, + ARRAY_SIZE(tas2564_left_controls)); + } else if (chn == channel_right) { + ret = snd_soc_add_codec_controls( + codec, tas256x_right_controls, + ARRAY_SIZE(tas256x_right_controls)); + ret = snd_soc_add_codec_controls( + codec, tas2564_right_controls, + ARRAY_SIZE(tas2564_right_controls)); + } else { + dev_err(p_tas256x->dev, "Invalid Channel %d\n", chn); + } + + return ret; +} + +static int tas2562_probe(struct tas256x_priv *p_tas256x, + struct snd_soc_codec *codec, int chn) +{ + int ret = -1; + + if ((!p_tas256x) || (!codec)) { + pr_err("tas256x:%s p_tas256x or codec is Null\n", __func__); + return ret; + } + dev_dbg(p_tas256x->dev, "%s channel %d", __func__, chn); + + tas256x_update_default_params(p_tas256x, chn); + if (chn == channel_left) { + ret = snd_soc_add_codec_controls( + codec, tas256x_left_controls, + ARRAY_SIZE(tas256x_left_controls)); + ret = snd_soc_add_codec_controls( + codec, tas2562_left_controls, + ARRAY_SIZE(tas2562_left_controls)); + } else if (chn == channel_right) { + ret = snd_soc_add_codec_controls( + codec, tas256x_right_controls, + ARRAY_SIZE(tas256x_right_controls)); + ret = snd_soc_add_codec_controls( + codec, tas2562_right_controls, + ARRAY_SIZE(tas2562_right_controls)); + } else { + dev_err(p_tas256x->dev, "Invalid Channel %d\n", chn); + } + + return ret; +} + +static bool tas256x_volatile(struct device *dev, unsigned int reg) +{ + return true; +} + +static bool tas256x_writeable(struct device *dev, unsigned int reg) +{ + return true; +} +static const struct regmap_config tas256x_i2c_regmap = { + .reg_bits = 8, + .val_bits = 8, + .writeable_reg = tas256x_writeable, + .volatile_reg = tas256x_volatile, + .cache_type = REGCACHE_NONE, + .max_register = 1 * 128, +}; + +static void tas256x_hw_reset(struct tas256x_priv *p_tas256x) +{ + int i = 0; + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (gpio_is_valid(p_tas256x->devs[i]->mn_reset_gpio)) { + gpio_direction_output(p_tas256x->devs[i]->mn_reset_gpio, + 0); + } + } + msleep(20); + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (gpio_is_valid(p_tas256x->devs[i]->mn_reset_gpio)) { + gpio_direction_output(p_tas256x->devs[i]->mn_reset_gpio, + 1); + } + p_tas256x->devs[i]->mn_current_book = -1; + p_tas256x->devs[i]->mn_current_page = -1; + } + msleep(20); + + dev_info(p_tas256x->dev, "reset gpio up !!\n"); +} + +void tas256x_enable_irq(struct tas256x_priv *p_tas256x, bool enable) +{ + static int irq_enabled[2]; + struct irq_desc *desc = NULL; + int i = 0; + + if (enable) { + if (p_tas256x->mb_irq_eable) + return; + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (gpio_is_valid(p_tas256x->devs[i]->mn_irq_gpio) && + irq_enabled[i] == 0) { + if (i == 0) { + desc = irq_to_desc( + p_tas256x->devs[i]->mn_irq); + if (desc && desc->depth > 0) + enable_irq(p_tas256x->devs[i] + ->mn_irq); + else + dev_info( + p_tas256x->dev, + "### irq already enabled"); + } else { + enable_irq(p_tas256x->devs[i]->mn_irq); + } + irq_enabled[i] = 1; + } + } + p_tas256x->mb_irq_eable = true; + } else { + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (gpio_is_valid(p_tas256x->devs[i]->mn_irq_gpio) && + irq_enabled[i] == 1) { + disable_irq_nosync(p_tas256x->devs[i]->mn_irq); + irq_enabled[i] = 0; + } + } + p_tas256x->mb_irq_eable = false; + } +} + +static void irq_work_routine(struct work_struct *work) +{ + struct tas256x_priv *p_tas256x = + container_of(work, struct tas256x_priv, irq_work.work); + unsigned int nDevInt1Status = 0, nDevInt2Status = 0, nDevInt3Status = 0, + nDevInt4Status = 0; + int n_counter = 2; + int n_result = 0; + int irqreg, irqreg2, i, chnTemp = 0; + enum channel chn = channel_left; + + dev_info(p_tas256x->dev, "%s\n", __func__); +#ifdef CONFIG_TAS256X_CODEC + mutex_lock(&p_tas256x->codec_lock); +#endif + tas256x_enable_irq(p_tas256x, false); + + if (p_tas256x->mn_err_code & ERROR_FAILSAFE) + goto reload; + + if (p_tas256x->mb_runtime_suspend) { + dev_info(p_tas256x->dev, "%s, Runtime Suspended\n", __func__); + goto end; + } + + if (p_tas256x->mn_power_state == TAS256X_POWER_SHUTDOWN) { + dev_info(p_tas256x->dev, "%s, device not powered\n", __func__); + goto end; + } + + n_result = tas256x_interrupt_enable(p_tas256x, 0 /*Disable*/, + channel_both); + if (n_result < 0) + goto reload; + + /*Reset error codes*/ + p_tas256x->mn_err_code = 0; + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (p_tas256x->devs[i]->spk_control == 1) + chnTemp |= 1 << i; + } + chn = (chnTemp == 0) ? chn : (enum channel)chnTemp; + + if (chn & channel_left) { + n_result = + tas256x_interrupt_read(p_tas256x, &nDevInt1Status, + &nDevInt2Status, channel_left); + if (n_result < 0) + goto reload; + p_tas256x->mn_err_code = + tas256x_interrupt_determine(p_tas256x, channel_left, + nDevInt1Status, + nDevInt2Status); + } + + if (chn & channel_right) { + n_result = + tas256x_interrupt_read(p_tas256x, &nDevInt3Status, + &nDevInt4Status, channel_right); + if (n_result < 0) + goto reload; + p_tas256x->mn_err_code |= + tas256x_interrupt_determine(p_tas256x, channel_right, + nDevInt3Status, + nDevInt4Status); + } + + dev_dbg(p_tas256x->dev, + "IRQ status : 0x%x, 0x%x, 0x%x, 0x%x mn_err_code %d\n", + nDevInt1Status, nDevInt2Status, nDevInt3Status, nDevInt4Status, + p_tas256x->mn_err_code); + + if (p_tas256x->mn_err_code) + goto reload; + else { + n_counter = 2; + + while (n_counter > 0) { + if (chn & channel_left) + n_result = tas256x_power_check(p_tas256x, + &nDevInt1Status, + channel_left); + if (n_result < 0) + goto reload; + if (chn & channel_right) + n_result = tas256x_power_check(p_tas256x, + &nDevInt3Status, + channel_right); + if (n_result < 0) + goto reload; + + if (nDevInt1Status) { + /* If only left should be power on */ + if (chn == channel_left) + break; + /* If both should be power on */ + if (nDevInt3Status) + break; + } else if (chn == channel_right) { + /*If only right should be power on */ + if (nDevInt3Status) + break; + } + + tas256x_interrupt_read(p_tas256x, &irqreg, &irqreg2, + channel_left); + dev_info(p_tas256x->dev, "IRQ reg is: %s %d, %d\n", + __func__, irqreg, __LINE__); + tas256x_interrupt_read(p_tas256x, &irqreg, &irqreg2, + channel_right); + dev_info(p_tas256x->dev, "IRQ reg is: %s %d, %d\n", + __func__, irqreg, __LINE__); + + n_counter--; + if (n_counter > 0) { + /* in case check pow status + *just after power on TAS256x + */ + dev_dbg(p_tas256x->dev, + "PowSts B: 0x%x, check again after 10ms\n", + nDevInt1Status); + msleep(20); + } + } + + if (((!nDevInt1Status) && (chn & channel_left)) || + ((!nDevInt3Status) && (chn & channel_right))) { + dev_err(p_tas256x->dev, + "%s, Critical ERROR REG[POWERCONTROL] = 0x%x\n", + __func__, nDevInt1Status); + goto reload; + } + } + + n_result = + tas256x_interrupt_enable(p_tas256x, 1 /*Enable*/, channel_both); + if (n_result < 0) + goto reload; + + goto end; + +reload: + /* hardware reset and reload */ + tas256x_load_config(p_tas256x); + +end: + tas256x_enable_irq(p_tas256x, true); +#ifdef CONFIG_TAS256X_CODEC + mutex_unlock(&p_tas256x->codec_lock); +#endif +} + +static void init_work_routine(struct work_struct *work) +{ + struct tas256x_priv *p_tas256x = + container_of(work, struct tas256x_priv, init_work.work); + int n_result = 0; + int irqreg = 0, irqreg2 = 0; + + pr_info("%s:\n", __func__); + + tas256x_interrupt_read(p_tas256x, &irqreg, &irqreg2, channel_left); + dev_info(p_tas256x->dev, "IRQ reg is: %s %d, %d\n", __func__, irqreg, + __LINE__); + tas256x_interrupt_read(p_tas256x, &irqreg, &irqreg2, channel_right); + dev_info(p_tas256x->dev, "IRQ reg is: %s %d, %d\n", __func__, irqreg, + __LINE__); + + /* Clear latched IRQ before power on */ + n_result = tas256x_interrupt_clear(p_tas256x, channel_both); + + /*Un-Mask interrupt for TDM*/ + n_result = + tas256x_interrupt_enable(p_tas256x, 1 /*Enable*/, channel_both); + + p_tas256x->enable_irq(p_tas256x, true); +} + +static irqreturn_t tas256x_irq_handler(int irq, void *dev_id) +{ + struct tas256x_priv *p_tas256x = (struct tas256x_priv *)dev_id; + + /* get IRQ status after 100 ms */ + schedule_delayed_work(&p_tas256x->irq_work, msecs_to_jiffies(100)); + return IRQ_HANDLED; +} + +static int tas256x_runtime_suspend(struct tas256x_priv *p_tas256x) +{ + dev_dbg(p_tas256x->dev, "%s\n", __func__); + + p_tas256x->mb_runtime_suspend = true; + + if (delayed_work_pending(&p_tas256x->irq_work)) { + dev_dbg(p_tas256x->dev, "cancel IRQ work\n"); + cancel_delayed_work_sync(&p_tas256x->irq_work); + } + + return 0; +} + +static int tas256x_runtime_resume(struct tas256x_priv *p_tas256x) +{ + dev_dbg(p_tas256x->dev, "%s\n", __func__); + + p_tas256x->mb_runtime_suspend = false; + + return 0; +} + +static int tas256x_pm_suspend(struct device *dev) +{ + struct tas256x_priv *p_tas256x = dev_get_drvdata(dev); + + if (!p_tas256x) { + dev_err(p_tas256x->dev, "drvdata is NULL\n"); + return -EINVAL; + } + + mutex_lock(&p_tas256x->codec_lock); + p_tas256x->i2c_suspend = true; + tas256x_runtime_suspend(p_tas256x); + mutex_unlock(&p_tas256x->codec_lock); + return 0; +} + +static int tas256x_pm_resume(struct device *dev) +{ + struct tas256x_priv *p_tas256x = dev_get_drvdata(dev); + + if (!p_tas256x) { + dev_err(p_tas256x->dev, "drvdata is NULL\n"); + return -EINVAL; + } + mutex_lock(&p_tas256x->codec_lock); + p_tas256x->i2c_suspend = false; + tas256x_runtime_resume(p_tas256x); + mutex_unlock(&p_tas256x->codec_lock); + return 0; +} + +#ifdef CONFIG_TAS25XX_ALGO +/*TODO: FIX Use of private data causes crash*/ +struct tas256x_priv *g_p_tas256x; + +void tas256x_software_reset(void *prv_data) +{ + pr_err("[TI-SmartPA:%s]\n", __func__); + schedule_delayed_work(&g_p_tas256x->dc_work, msecs_to_jiffies(10)); +} + +static void dc_work_routine(struct work_struct *work) +{ + struct tas256x_priv *p_tas256x = + container_of(work, struct tas256x_priv, dc_work.work); + + pr_err("[TI-SmartPA:%s] DC in channel = %d\n", __func__, + s_dc_detect.channel); +#ifdef CONFIG_TAS2562_CODEC + mutex_lock(&p_tas256x->codec_lock); +#endif + tas_reload(p_tas256x, s_dc_detect.channel); + +#ifdef CONFIG_TAS2562_CODEC + mutex_unlock(&p_tas256x->codec_lock); +#endif +} +#endif /*CONFIG_TAS25XX_ALGO*/ + +static int tas256x_parse_dt(struct device *dev, struct tas256x_priv *p_tas256x) +{ + struct device_node *np = dev->of_node; + int rc = 0, i = 0; + + rc = of_property_read_u32(np, "ti,channels", &p_tas256x->mn_channels); + if (rc) { + dev_err(p_tas256x->dev, + "Looking up %s property in node %s failed %d\n", + "ti,channels", np->full_name, rc); + goto EXIT; + } else { + dev_dbg(p_tas256x->dev, "ti,channels=%d", + p_tas256x->mn_channels); + } + + /*the device structures array*/ + p_tas256x->devs = + kmalloc(p_tas256x->mn_channels * sizeof(struct tas_device *), + GFP_KERNEL); + for (i = 0; i < p_tas256x->mn_channels; i++) { + p_tas256x->devs[i] = + kmalloc(sizeof(struct tas_device), GFP_KERNEL); + if (p_tas256x->devs[i] == NULL) { + dev_err(p_tas256x->dev, "%s:%u:kmalloc failed!\n", + __func__, __LINE__); + rc = -1; + break; + } + p_tas256x->devs[i]->i2c = p_tas256x->client; + p_tas256x->devs[i]->regmap = p_tas256x->regmap; + + rc = of_property_read_u32(np, dts_tag[i][0], + &p_tas256x->devs[i]->mn_addr); + if (rc) { + dev_err(p_tas256x->dev, + "Looking up %s property in node %s failed %d\n", + dts_tag[i][0], np->full_name, rc); + break; + } else { + dev_dbg(p_tas256x->dev, "%s = 0x%02x", dts_tag[i][0], + p_tas256x->devs[i]->mn_addr); + } + + p_tas256x->devs[i]->mn_reset_gpio = + of_get_named_gpio(np, dts_tag[i][1], 0); + if (!gpio_is_valid(p_tas256x->devs[i]->mn_reset_gpio)) + dev_err(p_tas256x->dev, + "Looking up %s property in node %s failed %d\n", + dts_tag[i][1], np->full_name, + p_tas256x->devs[i]->mn_reset_gpio); + else + dev_dbg(p_tas256x->dev, "%s = %d", dts_tag[i][1], + p_tas256x->devs[i]->mn_reset_gpio); + + p_tas256x->devs[i]->mn_irq_gpio = + of_get_named_gpio(np, dts_tag[i][2], 0); + if (!gpio_is_valid(p_tas256x->devs[i]->mn_irq_gpio)) { + dev_err(p_tas256x->dev, + "Looking up %s property in node %s failed %d\n", + dts_tag[i][2], np->full_name, + p_tas256x->devs[i]->mn_irq_gpio); + } else { + dev_dbg(p_tas256x->dev, "%s = %d", dts_tag[i][2], + p_tas256x->devs[i]->mn_irq_gpio); + } + p_tas256x->devs[i]->spk_control = 1; + } + + if (rc) + goto EXIT; + + rc = of_property_read_u32(np, "ti,iv-width", &p_tas256x->mn_iv_width); + if (rc) { + dev_err(p_tas256x->dev, + "Looking up %s property in node %s failed %d\n", + "ti,iv-width", np->full_name, rc); + } else { + dev_dbg(p_tas256x->dev, "ti,iv-width=0x%x", + p_tas256x->mn_iv_width); + } + + rc = of_property_read_u32(np, "ti,vbat-mon", &p_tas256x->mn_vbat); + if (rc) { + dev_err(p_tas256x->dev, + "Looking up %s property in node %s failed %d\n", + "ti,vbat-mon", np->full_name, rc); + } else { + dev_dbg(p_tas256x->dev, "ti,vbat-mon=0x%x", p_tas256x->mn_vbat); + } +#ifdef CONFIG_TAS25XX_ALGO + /*TODO: Enable if feature is needed*/ + /*tas25xx_parse_algo_dt(np);*/ +#endif /*CONFIG_TAS25XX_ALGO*/ +EXIT: + return rc; +} + +static int tas256x_i2c_probe(struct i2c_client *p_client, + const struct i2c_device_id *id) +{ + struct tas256x_priv *p_tas256x; + int n_result = 0; + int i = 0; + + dev_info(&p_client->dev, "Driver Tag: %s\n", TAS256X_DRIVER_TAG); + dev_info(&p_client->dev, "%s enter\n", __func__); + + p_tas256x = devm_kzalloc(&p_client->dev, sizeof(struct tas256x_priv), + GFP_KERNEL); + if (p_tas256x == NULL) { + /* dev_err(&p_client->dev, "failed to get i2c device\n"); */ + n_result = -ENOMEM; + goto err; + } + + p_tas256x->client = p_client; + p_tas256x->dev = &p_client->dev; + i2c_set_clientdata(p_client, p_tas256x); + dev_set_drvdata(&p_client->dev, p_tas256x); + + p_tas256x->regmap = devm_regmap_init_i2c(p_client, &tas256x_i2c_regmap); + if (IS_ERR(p_tas256x->regmap)) { + n_result = PTR_ERR(p_tas256x->regmap); + dev_err(&p_client->dev, "Failed to allocate register map: %d\n", + n_result); + goto err; + } + + mutex_init(&p_tas256x->dev_lock); + + p_tas256x->read = tas256x_dev_read; + p_tas256x->write = tas256x_dev_write; + p_tas256x->bulk_read = tas256x_dev_bulk_read; + p_tas256x->bulk_write = tas256x_dev_bulk_write; + p_tas256x->update_bits = tas256x_dev_update_bits; + p_tas256x->hw_reset = tas256x_hw_reset; + p_tas256x->enable_irq = tas256x_enable_irq; +#ifdef CODEC_PM + p_tas256x->runtime_suspend = tas256x_runtime_suspend; + p_tas256x->runtime_resume = tas256x_runtime_resume; + p_tas256x->mn_power_state = TAS256X_POWER_SHUTDOWN; +#endif + p_tas256x->mn_power_state = TAS256X_POWER_SHUTDOWN; + + if (p_client->dev.of_node) + tas256x_parse_dt(&p_client->dev, p_tas256x); + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (gpio_is_valid(p_tas256x->devs[i]->mn_reset_gpio)) { + n_result = + gpio_request(p_tas256x->devs[i]->mn_reset_gpio, + reset_gpio_label[i]); + if (n_result) { + dev_err(p_tas256x->dev, + "%s: Failed to request gpio %d\n", + __func__, + p_tas256x->devs[i]->mn_reset_gpio); + n_result = -EINVAL; + goto err; + } + } + } + + tas256x_hw_reset(p_tas256x); + + dev_info(&p_client->dev, "Before SW reset\n"); + /* Reset the chip */ + n_result = tas56x_software_reset(p_tas256x, channel_both); + if (n_result < 0) { + dev_err(&p_client->dev, "I2c fail, %d\n", n_result); + goto err; + } + dev_info(&p_client->dev, "After SW reset\n"); + + for (i = 0; i < p_tas256x->mn_channels; i++) { + n_result = tas56x_get_chipid( + p_tas256x, &(p_tas256x->devs[i]->mChipID), + (i == 0) ? channel_left : channel_right); + switch (p_tas256x->devs[i]->mChipID) { + case 0x10: + case 0x20: + dev_dbg(p_tas256x->dev, "TAS2562 chip"); + p_tas256x->devs[i]->device_id = DEVICE_TAS2562; + p_tas256x->devs[i]->dev_ops.tas_init = NULL; + p_tas256x->devs[i]->dev_ops.tas_probe = tas2562_probe; + break; + case 0x00: + dev_dbg(p_tas256x->dev, "TAS2564 chip"); + p_tas256x->devs[i]->device_id = DEVICE_TAS2564; + p_tas256x->devs[i]->dev_ops.tas_init = tas2564_specific; + p_tas256x->devs[i]->dev_ops.tas_probe = tas2564_probe; + break; + default: + dev_dbg(p_tas256x->dev, "TAS2558 chip"); + p_tas256x->devs[i]->device_id = DEVICE_TAS2558; + p_tas256x->devs[i]->dev_ops.tas_init = tas2558_specific; + p_tas256x->devs[i]->dev_ops.tas_probe = NULL; + break; + } + } + + INIT_DELAYED_WORK(&p_tas256x->irq_work, irq_work_routine); + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (gpio_is_valid(p_tas256x->devs[i]->mn_irq_gpio)) { + n_result = gpio_request(p_tas256x->devs[i]->mn_irq_gpio, + irq_gpio_label[i]); + if (n_result < 0) { + dev_err(p_tas256x->dev, + "%s:%u: ch 0x%02x: GPIO %d request error\n", + __func__, __LINE__, + p_tas256x->devs[i]->mn_addr, + p_tas256x->devs[i]->mn_irq_gpio); + goto err; + } + gpio_direction_input(p_tas256x->devs[i]->mn_irq_gpio); + /*tas256x_dev_write(p_tas256x, + * (i == 0)? channel_left : channel_right, + * TAS256X_MISCCONFIGURATIONREG0, 0xce); + */ + tas256x_set_misc_config(p_tas256x, 0, + (i == 0) ? channel_left : + channel_right); + + p_tas256x->devs[i]->mn_irq = + gpio_to_irq(p_tas256x->devs[i]->mn_irq_gpio); + dev_info(p_tas256x->dev, "irq = %d\n", + p_tas256x->devs[i]->mn_irq); + + n_result = request_threaded_irq( + p_tas256x->devs[i]->mn_irq, tas256x_irq_handler, + NULL, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + p_client->name, p_tas256x); + if (n_result < 0) { + dev_err(p_tas256x->dev, + "request_irq failed, %d\n", n_result); + goto err; + } + disable_irq_nosync(p_tas256x->devs[i]->mn_irq); + } + } + + tas256x_enable_irq(p_tas256x, true); + INIT_DELAYED_WORK(&p_tas256x->init_work, init_work_routine); + +#ifdef CONFIG_TAS256X_CODEC + mutex_init(&p_tas256x->codec_lock); + n_result = tas256x_register_codec(p_tas256x); + if (n_result < 0) { + dev_err(p_tas256x->dev, "register codec failed, %d\n", + n_result); + goto err; + } +#endif + +#ifdef CONFIG_TAS256X_MISC + mutex_init(&p_tas256x->file_lock); + n_result = tas256x_register_misc(p_tas256x); + if (n_result < 0) { + dev_err(p_tas256x->dev, "register codec failed %d\n", n_result); + goto err; + } +#endif + +#ifdef CONFIG_TAS25XX_ALGO + INIT_DELAYED_WORK(&p_tas256x->dc_work, dc_work_routine); + g_p_tas256x = p_tas256x; + register_tas256x_reset_func(tas256x_software_reset, &s_dc_detect); +#endif /*CONFIG_TAS25XX_ALGO*/ + +err: + return n_result; +} + +static int tas256x_i2c_remove(struct i2c_client *p_client) +{ + int i = 0; + struct tas256x_priv *p_tas256x = i2c_get_clientdata(p_client); + + dev_info(p_tas256x->dev, "%s\n", __func__); + +#ifdef CONFIG_TAS256X_CODEC + tas256x_deregister_codec(p_tas256x); + mutex_destroy(&p_tas256x->codec_lock); +#endif + +#ifdef CONFIG_TAS256X_MISC + tas256x_deregister_misc(p_tas256x); + mutex_destroy(&p_tas256x->file_lock); +#endif + + for (i = 0; i < p_tas256x->mn_channels; i++) { + if (gpio_is_valid(p_tas256x->devs[i]->mn_reset_gpio)) + gpio_free(p_tas256x->devs[i]->mn_reset_gpio); + if (gpio_is_valid(p_tas256x->devs[i]->mn_irq_gpio)) + gpio_free(p_tas256x->devs[i]->mn_irq_gpio); + if (p_tas256x->devs[i]) + kfree(p_tas256x->devs[i]); + } + + if (p_tas256x->devs) + kfree(p_tas256x->devs); + + return 0; +} + +static const struct i2c_device_id tas256x_i2c_id[] = { + { "tas256x", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, tas256x_i2c_id); + +#if defined(CONFIG_OF) +static const struct of_device_id tas256x_of_match[] = { + { .compatible = "ti, tas256x" }, + { .compatible = "ti, tas2562" }, + { .compatible = "ti, tas2564" }, + {}, +}; +MODULE_DEVICE_TABLE(of, tas256x_of_match); +#endif + +static const struct dev_pm_ops tas256x_pm_ops = { .suspend = tas256x_pm_suspend, + .resume = tas256x_pm_resume }; + +static struct i2c_driver tas256x_i2c_driver = { + .driver = { + .name = "tas256x", + .owner = THIS_MODULE, +#if defined(CONFIG_OF) + .of_match_table = of_match_ptr(tas256x_of_match), +#endif + .pm = &tas256x_pm_ops, + }, + .probe = tas256x_i2c_probe, + .remove = tas256x_i2c_remove, + .id_table = tas256x_i2c_id, +}; + +module_i2c_driver(tas256x_i2c_driver); + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("TAS256X I2C Smart Amplifier driver"); +MODULE_LICENSE("GPL v2"); +#endif diff --git a/techpack/audio/asoc/codecs/tas256x/tas256x.c b/techpack/audio/asoc/codecs/tas256x/tas256x.c new file mode 100644 index 000000000000..d785c8fcebea --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/tas256x.c @@ -0,0 +1,1557 @@ +#include "tas256x.h" +#include "tas2562.h" +#include "tas2564.h" +#include "tas256x-device.h" + +#define LOG_TAG "[tas256x]" + +#define TAS256X_MDELAY 0xFFFFFFFE +#define TAS256X_MSLEEP 0xFFFFFFFD +#define TAS256X_IVSENSER_ENABLE 1 +#define TAS256X_IVSENSER_DISABLE 0 +static char p_icn_threshold[] = { 0x00, 0x01, 0x2f, 0x2c }; +static char p_icn_hysteresis[] = { 0x00, 0x01, 0x5d, 0xc0 }; + +static unsigned int p_tas256x_classh_d_data[] = { + /* reg address size values */ + TAS256X_CLASSHHEADROOM, + 0x4, + 0x09, + 0x99, + 0x99, + 0x9a, + TAS256X_CLASSHHYSTERESIS, + 0x4, + 0x0, + 0x0, + 0x0, + 0x0, + TAS256X_CLASSHMTCT, + 0x4, + 0xb, + 0x0, + 0x0, + 0x0, + TAS256X_VBATFILTER, + 0x1, + 0x38, + TAS256X_CLASSHRELEASETIMER, + 0x1, + 0x3c, + TAS256X_BOOSTSLOPE, + 0x1, + 0x78, + TAS256X_TESTPAGECONFIGURATION, + 0x1, + 0xd, + TAS256X_CLASSDCONFIGURATION3, + 0x1, + 0x8e, + TAS256X_CLASSDCONFIGURATION2, + 0x1, + 0x49, + TAS256X_CLASSDCONFIGURATION4, + 0x1, + 0x21, + TAS256X_CLASSDCONFIGURATION1, + 0x1, + 0x80, + TAS256X_EFFICIENCYCONFIGURATION, + 0x1, + 0xc1, + 0xFFFFFFFF, + 0xFFFFFFFF +}; + +static char HPF_reverse_path[] = { 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +static char dvc_pcm[57][4] = { + { 0x00, 0x00, 0x0D, 0x43 }, { 0x00, 0x00, 0x10, 0xB3 }, + { 0x00, 0x00, 0x15, 0x05 }, { 0x00, 0x00, 0x1A, 0x77 }, + { 0x00, 0x00, 0x21, 0x51 }, { 0x00, 0x00, 0x29, 0xF1 }, + { 0x00, 0x00, 0x34, 0xCE }, { 0x00, 0x00, 0x42, 0x7A }, + { 0x00, 0x00, 0x53, 0xB0 }, { 0x00, 0x00, 0x69, 0x5B }, + { 0x00, 0x00, 0x84, 0xA3 }, { 0x00, 0x00, 0xA6, 0xFA }, + { 0x00, 0x00, 0xD2, 0x37 }, { 0x00, 0x01, 0x08, 0xA5 }, + { 0x00, 0x01, 0x4D, 0x2A }, { 0x00, 0x01, 0xA3, 0x6E }, + { 0x00, 0x02, 0x10, 0x08 }, { 0x00, 0x02, 0x98, 0xC1 }, + { 0x00, 0x03, 0x44, 0xE0 }, { 0x00, 0x04, 0x1D, 0x90 }, + { 0x00, 0x05, 0x2E, 0x5B }, { 0x00, 0x06, 0x85, 0xC8 }, + { 0x00, 0x08, 0x36, 0x22 }, { 0x00, 0x0A, 0x56, 0x6D }, + { 0x00, 0x0D, 0x03, 0xA7 }, { 0x00, 0x10, 0x62, 0x4E }, + { 0x00, 0x14, 0xA0, 0x51 }, { 0x00, 0x19, 0xF7, 0x86 }, + { 0x00, 0x20, 0xB0, 0xBD }, { 0x00, 0x29, 0x27, 0x9E }, + { 0x00, 0x33, 0xCF, 0x8E }, { 0x00, 0x41, 0x39, 0xD3 }, + { 0x00, 0x52, 0x1D, 0x51 }, { 0x00, 0x67, 0x60, 0x45 }, + { 0x00, 0x82, 0x24, 0x8A }, { 0x00, 0xA3, 0xD7, 0x0A }, + { 0x00, 0xCE, 0x43, 0x29 }, { 0x01, 0x03, 0xAB, 0x3D }, + { 0x01, 0x46, 0xE7, 0x5E }, { 0x01, 0x9B, 0x8C, 0x27 }, + { 0x02, 0x06, 0x1B, 0x8A }, { 0x02, 0x8C, 0x42, 0x40 }, + { 0x03, 0x35, 0x25, 0x29 }, { 0x04, 0x09, 0xC2, 0xB1 }, + { 0x05, 0x15, 0x6D, 0x69 }, { 0x06, 0x66, 0x66, 0x66 }, + { 0x08, 0x0E, 0x9F, 0x97 }, { 0x0A, 0x24, 0xB0, 0x63 }, + { 0x0C, 0xC5, 0x09, 0xAC }, { 0x10, 0x13, 0x79, 0x88 }, + { 0x14, 0x3D, 0x13, 0x62 }, { 0x19, 0x7A, 0x96, 0x7F }, + { 0x20, 0x13, 0x73, 0x9E }, { 0x28, 0x61, 0x9A, 0xEA }, + { 0x32, 0xD6, 0x46, 0x18 }, { 0x40, 0x00, 0x00, 0x00 }, + { 0x50, 0x92, 0x3B, 0xE4 } +}; + +static char lim_max_attn[16][4] = { + { 0x14, 0x49, 0x60, 0xC5 }, { 0x16, 0xC3, 0x10, 0xE3 }, + { 0x19, 0x8A, 0x13, 0x57 }, { 0x1C, 0xA7, 0xD7, 0x68 }, + { 0x20, 0x26, 0xF3, 0x10 }, { 0x24, 0x13, 0x46, 0xF6 }, + { 0x28, 0x7A, 0x26, 0xC5 }, { 0x2D, 0x6A, 0x86, 0x6F }, + { 0x32, 0xF5, 0x2C, 0xFF }, { 0x39, 0x2C, 0xED, 0x8E }, + { 0x40, 0x26, 0xE7, 0x3D }, { 0x47, 0xFA, 0xCC, 0xF0 }, + { 0x50, 0xC3, 0x35, 0xD4 }, { 0x5A, 0x9D, 0xF7, 0xAC }, + { 0x65, 0xAC, 0x8C, 0x2F }, { 0x72, 0x14, 0x82, 0xC0 } +}; + +static char vbat_lim_max_thd[27][4] = { + { 0x14, 0x00, 0x00, 0x00 }, { 0x18, 0x00, 0x00, 0x00 }, + { 0x1C, 0x00, 0x00, 0x00 }, { 0x20, 0x00, 0x00, 0x00 }, + { 0x24, 0x00, 0x00, 0x00 }, { 0x28, 0x00, 0x00, 0x00 }, + { 0x2C, 0x00, 0x00, 0x00 }, { 0x30, 0x00, 0x00, 0x00 }, + { 0x34, 0x00, 0x00, 0x00 }, { 0x38, 0x00, 0x00, 0x00 }, + { 0x3C, 0x00, 0x00, 0x00 }, { 0x40, 0x00, 0x00, 0x00 }, + { 0x44, 0x00, 0x00, 0x00 }, { 0x48, 0x00, 0x00, 0x00 }, + { 0x4C, 0x00, 0x00, 0x00 }, { 0x50, 0x00, 0x00, 0x00 }, + { 0x54, 0x00, 0x00, 0x00 }, { 0x58, 0x00, 0x00, 0x00 }, + { 0x5C, 0x00, 0x00, 0x00 }, { 0x60, 0x00, 0x00, 0x00 }, + { 0x64, 0x00, 0x00, 0x00 }, { 0x68, 0x00, 0x00, 0x00 }, + { 0x6C, 0x00, 0x00, 0x00 }, { 0x70, 0x00, 0x00, 0x00 }, + { 0x74, 0x00, 0x00, 0x00 }, { 0x78, 0x00, 0x00, 0x00 }, + { 0x7C, 0x00, 0x00, 0x00 } +}; + +static char vbat_lim_min_thd[27][4] = { + { 0x14, 0x00, 0x00, 0x00 }, { 0x18, 0x00, 0x00, 0x00 }, + { 0x1C, 0x00, 0x00, 0x00 }, { 0x20, 0x00, 0x00, 0x00 }, + { 0x24, 0x00, 0x00, 0x00 }, { 0x28, 0x00, 0x00, 0x00 }, + { 0x2C, 0x00, 0x00, 0x00 }, { 0x30, 0x00, 0x00, 0x00 }, + { 0x34, 0x00, 0x00, 0x00 }, { 0x38, 0x00, 0x00, 0x00 }, + { 0x3C, 0x00, 0x00, 0x00 }, { 0x40, 0x00, 0x00, 0x00 }, + { 0x44, 0x00, 0x00, 0x00 }, { 0x48, 0x00, 0x00, 0x00 }, + { 0x4C, 0x00, 0x00, 0x00 }, { 0x50, 0x00, 0x00, 0x00 }, + { 0x54, 0x00, 0x00, 0x00 }, { 0x58, 0x00, 0x00, 0x00 }, + { 0x5C, 0x00, 0x00, 0x00 }, { 0x60, 0x00, 0x00, 0x00 }, + { 0x64, 0x00, 0x00, 0x00 }, { 0x68, 0x00, 0x00, 0x00 }, + { 0x6C, 0x00, 0x00, 0x00 }, { 0x70, 0x00, 0x00, 0x00 }, + { 0x74, 0x00, 0x00, 0x00 }, { 0x78, 0x00, 0x00, 0x00 }, + { 0x7C, 0x00, 0x00, 0x00 } +}; + +static char vbat_lim_infl_pt[41][4] = { + { 0x20, 0x00, 0x00, 0x00 }, { 0x21, 0x99, 0x99, 0x99 }, + { 0x23, 0x33, 0x33, 0x33 }, { 0x24, 0xCC, 0xCC, 0xCC }, + { 0x26, 0x66, 0x66, 0x66 }, { 0x28, 0x00, 0x00, 0x00 }, + { 0x29, 0x99, 0x99, 0x99 }, { 0x2B, 0x33, 0x33, 0x33 }, + { 0x2C, 0xCC, 0xCC, 0xCC }, { 0x2E, 0x66, 0x66, 0x66 }, + { 0x30, 0x00, 0x00, 0x00 }, { 0x31, 0x99, 0x99, 0x99 }, + { 0x33, 0x33, 0x33, 0x33 }, { 0x34, 0xCC, 0xCC, 0xCC }, + { 0x36, 0x66, 0x66, 0x66 }, { 0x38, 0x00, 0x00, 0x00 }, + { 0x39, 0x99, 0x99, 0x99 }, { 0x3B, 0x33, 0x33, 0x33 }, + { 0x3C, 0xCC, 0xCC, 0xCC }, { 0x3E, 0x66, 0x66, 0x66 }, + { 0x40, 0x00, 0x00, 0x00 }, { 0x41, 0x99, 0x99, 0x99 }, + { 0x43, 0x33, 0x33, 0x33 }, { 0x44, 0xCC, 0xCC, 0xCC }, + { 0x46, 0x66, 0x66, 0x66 }, { 0x48, 0x00, 0x00, 0x00 }, + { 0x49, 0x99, 0x99, 0x99 }, { 0x4B, 0x33, 0x33, 0x33 }, + { 0x4C, 0xCC, 0xCC, 0xCC }, { 0x4E, 0x66, 0x66, 0x66 }, + { 0x4F, 0xFF, 0xFF, 0xFF }, { 0x51, 0x99, 0x99, 0x99 }, + { 0x53, 0x33, 0x33, 0x33 }, { 0x54, 0xCC, 0xCC, 0xCC }, + { 0x56, 0x66, 0x66, 0x66 }, { 0x57, 0xFF, 0xFF, 0xFF }, + { 0x59, 0x99, 0x99, 0x99 }, { 0x5B, 0x33, 0x33, 0x33 }, + { 0x5C, 0xCC, 0xCC, 0xCC }, { 0x5E, 0x66, 0x66, 0x66 }, + { 0x5F, 0xFF, 0xFF, 0xFF } +}; + +static char vbat_lim_track_slope[7][4] = { + { 0x10, 0x00, 0x00, 0x00 }, { 0x18, 0x00, 0x00, 0x00 }, + { 0x20, 0x00, 0x00, 0x00 }, { 0x28, 0x00, 0x00, 0x00 }, + { 0x30, 0x00, 0x00, 0x00 }, { 0x38, 0x00, 0x00, 0x00 }, + { 0x40, 0x00, 0x00, 0x00 } +}; + +static char bop_thd[16][4] = { + { 0x28, 0x00, 0x00, 0x00 }, { 0x29, 0x99, 0x99, 0x99 }, + { 0x2B, 0x33, 0x33, 0x33 }, { 0x2C, 0xCC, 0xCC, 0xCC }, + { 0x2E, 0x66, 0x66, 0x66 }, { 0x30, 0x00, 0x00, 0x00 }, + { 0x31, 0x99, 0x99, 0x99 }, { 0x33, 0x33, 0x33, 0x33 }, + { 0x34, 0xCC, 0xCC, 0xCC }, { 0x36, 0x66, 0x66, 0x66 }, + { 0x38, 0x00, 0x00, 0x00 }, { 0x39, 0x99, 0x99, 0x99 }, + { 0x3B, 0x33, 0x33, 0x33 }, { 0x3C, 0xCC, 0xCC, 0xCC }, + { 0x3E, 0x66, 0x66, 0x66 }, { 0x40, 0x00, 0x00, 0x00 } +}; + +static char bsd_thd[16][4] = { + { 0x28, 0x00, 0x00, 0x00 }, { 0x29, 0x99, 0x99, 0x99 }, + { 0x2B, 0x33, 0x33, 0x33 }, { 0x2C, 0xCC, 0xCC, 0xCC }, + { 0x2E, 0x66, 0x66, 0x66 }, { 0x30, 0x00, 0x00, 0x00 }, + { 0x31, 0x99, 0x99, 0x99 }, { 0x33, 0x33, 0x33, 0x33 }, + { 0x34, 0xCC, 0xCC, 0xCC }, { 0x36, 0x66, 0x66, 0x66 }, + { 0x38, 0x00, 0x00, 0x00 }, { 0x39, 0x99, 0x99, 0x99 }, + { 0x3B, 0x33, 0x33, 0x33 }, { 0x3C, 0xCC, 0xCC, 0xCC }, + { 0x3E, 0x66, 0x66, 0x66 }, { 0x40, 0x00, 0x00, 0x00 } +}; + +static int tas256x_i2c_load_data(struct tas256x_priv *p_tas256x, + enum channel chn, unsigned int *p_data) +{ + unsigned int n_register; + unsigned int *n_data; + unsigned char buf[128]; + unsigned int n_length = 0; + unsigned int i = 0; + unsigned int n_size = 0; + int n_result = 0; + + do { + n_register = p_data[n_length]; + n_size = p_data[n_length + 1]; + n_data = &p_data[n_length + 2]; + if (n_register == TAS256X_MSLEEP) { + msleep(n_data[0]); + pr_debug("%s %s, msleep = %d\n", LOG_TAG, __func__, + n_data[0]); + } else if (n_register == TAS256X_MDELAY) { + msleep(n_data[0]); + pr_debug("%s %s, mdelay = %d\n", LOG_TAG, __func__, + n_data[0]); + } else { + if (n_register != 0xFFFFFFFF) { + if (n_size > 128) { + pr_err("%s %s, Line=%d, invalid size, maximum is 128 bytes!\n", + LOG_TAG, __func__, __LINE__); + break; + } + if (n_size > 1) { + for (i = 0; i < n_size; i++) + buf[i] = (unsigned char) + n_data[i]; + n_result = p_tas256x->bulk_write( + p_tas256x, chn, n_register, buf, + n_size); + if (n_result < 0) + break; + } else if (n_size == 1) { + n_result = + p_tas256x->write(p_tas256x, chn, + n_register, + n_data[0]); + if (n_result < 0) + break; + } else { + pr_err("%s %s, Line=%d,invalid size, minimum is 1 bytes!\n", + LOG_TAG, __func__, __LINE__); + } + } + } + n_length = n_length + 2 + p_data[n_length + 1]; + } while (n_register != 0xFFFFFFFF); + return n_result; +} + +int tas256x_update_default_params(struct tas256x_priv *p_tas256x, int ch) +{ + int n_result = 0; + + /*Initialize to default values*/ + if (p_tas256x->devs[ch - 1]->device_id == DEVICE_TAS2562) { + p_tas256x->devs[ch - 1]->dvc_pcm = 55; /*0dB*/ + p_tas256x->devs[ch - 1]->lim_max_attn = 7; /*-9dB*/ + p_tas256x->devs[ch - 1]->lim_thr_max = 13; /*9V*/ + p_tas256x->devs[ch - 1]->lim_thr_min = 3; /*4V*/ + p_tas256x->devs[ch - 1]->lim_infl_pt = 13; /*3.3V*/ + p_tas256x->devs[ch - 1]->lim_trk_slp = 0; /*1 V/V*/ + p_tas256x->devs[ch - 1]->bop_thd = 4; /*2.9 V*/ + p_tas256x->devs[ch - 1]->bosd_thd = 2; /*2.7 V*/ + p_tas256x->devs[ch - 1]->bst_vltg = 0xA; /*Mode = speaker*/ + p_tas256x->devs[ch - 1]->bst_ilm = 0x36; /*0dB*/ + p_tas256x->devs[ch - 1]->lim_switch = 0; /*-9dB*/ + p_tas256x->devs[ch - 1]->lim_att_rate = 1; /*9V*/ + p_tas256x->devs[ch - 1]->lim_att_stp_size = 1; /*4V*/ + p_tas256x->devs[ch - 1]->lim_rel_rate = 6; /*3.3V*/ + p_tas256x->devs[ch - 1]->lim_rel_stp_size = 1; /*1 V/V*/ + p_tas256x->devs[ch - 1]->bop_enable = 1; /*2.9 V*/ + p_tas256x->devs[ch - 1]->bop_mute = 0; /*2.7 V*/ + p_tas256x->devs[ch - 1]->bosd_enable = 0; /*3.3V*/ + p_tas256x->devs[ch - 1]->bop_att_rate = 1; /*1 V/V*/ + p_tas256x->devs[ch - 1]->bop_att_stp_size = 1; /*2.9 V*/ + p_tas256x->devs[ch - 1]->bop_hld_time = 6; /*2.7 V*/ + p_tas256x->devs[ch - 1]->vbat_lpf = 2; /*2.7 V*/ + p_tas256x->devs[ch - 1]->rx_cfg = 0; + } else if (p_tas256x->devs[ch - 1]->device_id == DEVICE_TAS2564) { + p_tas256x->devs[ch - 1]->rx_mode = 0; /*Mode = speaker*/ + p_tas256x->devs[ch - 1]->dvc_pcm = 55; /*0dB*/ + p_tas256x->devs[ch - 1]->lim_max_attn = 7; /*-9dB*/ + p_tas256x->devs[ch - 1]->lim_thr_max = 13; /*9V*/ + p_tas256x->devs[ch - 1]->lim_thr_min = 3; /*4V*/ + p_tas256x->devs[ch - 1]->lim_infl_pt = 13; /*3.3V*/ + p_tas256x->devs[ch - 1]->lim_trk_slp = 0; /*1 V/V*/ + p_tas256x->devs[ch - 1]->bop_thd = 4; /*2.9 V*/ + p_tas256x->devs[ch - 1]->bosd_thd = 2; /*2.7 V*/ + p_tas256x->devs[ch - 1]->bst_vltg = 13; /*Mode = speaker*/ + p_tas256x->devs[ch - 1]->bst_ilm = 0x39; /*0dB*/ + p_tas256x->devs[ch - 1]->lim_switch = 0; /*-9dB*/ + p_tas256x->devs[ch - 1]->lim_att_rate = 1; /*9V*/ + p_tas256x->devs[ch - 1]->lim_att_stp_size = 1; /*4V*/ + p_tas256x->devs[ch - 1]->lim_rel_rate = 6; /*3.3V*/ + p_tas256x->devs[ch - 1]->lim_rel_stp_size = 1; /*1 V/V*/ + p_tas256x->devs[ch - 1]->bop_enable = 1; /*2.9 V*/ + p_tas256x->devs[ch - 1]->bop_mute = 0; /*2.7 V*/ + p_tas256x->devs[ch - 1]->bosd_enable = 0; /*3.3V*/ + p_tas256x->devs[ch - 1]->bop_att_rate = 1; /*1 V/V*/ + p_tas256x->devs[ch - 1]->bop_att_stp_size = 1; /*2.9 V*/ + p_tas256x->devs[ch - 1]->bop_hld_time = 6; /*2.7 V*/ + p_tas256x->devs[ch - 1]->vbat_lpf = 2; /*2.7 V*/ + p_tas256x->devs[ch - 1]->rx_cfg = 0; + } + return n_result; +} + +int tas256x_set_power_up(struct tas256x_priv *p_tas256x, enum channel chn) +{ + int n_result = 0; + + n_result = p_tas256x->update_bits( + p_tas256x, chn, TAS256X_POWERCONTROL, + TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK, + TAS256X_POWERCONTROL_OPERATIONALMODE10_ACTIVE); + + /* Let Power on the device */ + msleep(20); + + /* Enable Comparator Hysteresis */ + n_result = p_tas256x->update_bits(p_tas256x, chn, TAS256X_MISC_CLASSD, + TAS256X_CMP_HYST_MASK, + (0x01 << TAS256X_CMP_HYST_SHIFT)); + return n_result; +} + +int tas256x_set_power_mute(struct tas256x_priv *p_tas256x, enum channel chn) +{ + int n_result = 0; + + /*Disable Comparator Hysteresis before Power Mute */ + n_result = p_tas256x->update_bits(p_tas256x, chn, TAS256X_MISC_CLASSD, + TAS256X_CMP_HYST_MASK, + (0x00 << TAS256X_CMP_HYST_SHIFT)); + + n_result = p_tas256x->update_bits( + p_tas256x, chn, TAS256X_POWERCONTROL, + TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK, + TAS256X_POWERCONTROL_OPERATIONALMODE10_MUTE); + + return n_result; +} + +int tas256x_set_power_shutdown(struct tas256x_priv *p_tas256x, enum channel chn) +{ + int n_result = 0; + /*Disable Comparator Hysteresis before Power Down */ + n_result = p_tas256x->update_bits(p_tas256x, chn, TAS256X_MISC_CLASSD, + TAS256X_CMP_HYST_MASK, + (0x00 << TAS256X_CMP_HYST_SHIFT)); + + n_result = p_tas256x->update_bits( + p_tas256x, chn, TAS256X_POWERCONTROL, + TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK, + TAS256X_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN); + + /*Device Shutdown need 20ms after shutdown writes are made*/ + msleep(20); + + return n_result; +} + +int tas256x_power_check(struct tas256x_priv *p_tas256x, int *state, int ch) +{ + int n_result = 0; + int status; + + n_result = + p_tas256x->read(p_tas256x, ch, TAS256X_POWERCONTROL, &status); + + status &= TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK; + + if ((status != TAS256X_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN) && + (status != TAS256X_POWERCONTROL_OPERATIONALMODE10_MUTE)) + *state = 1; + else + *state = 0; + + return n_result; +} + +/* + *bool enable = 1; IV Sense Power UP = 0; + * IV Sense Power Down + */ +int tas256x_iv_sense_enable_set(struct tas256x_priv *p_tas256x, bool enable, + int ch) +{ + int n_result = 0; + + if (enable) /*IV Sense Power Up*/ + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_POWERCONTROL, + TAS256X_POWERCONTROL_ISNSPOWER_MASK | + TAS256X_POWERCONTROL_VSNSPOWER_MASK, + TAS256X_POWERCONTROL_VSNSPOWER_ACTIVE | + TAS256X_POWERCONTROL_ISNSPOWER_ACTIVE); + else /*IV Sense Power Down*/ + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_POWERCONTROL, + TAS256X_POWERCONTROL_ISNSPOWER_MASK | + TAS256X_POWERCONTROL_VSNSPOWER_MASK, + TAS256X_POWERCONTROL_VSNSPOWER_POWEREDDOWN | + TAS256X_POWERCONTROL_ISNSPOWER_POWEREDDOWN); + + p_tas256x->iv_enable = enable; + return n_result; +} + +bool tas256x_iv_sense_enable_get(struct tas256x_priv *p_tas256x, int ch) +{ + int n_result = 0; + bool enable = 0; + int value = 0; + + n_result = p_tas256x->read(p_tas256x, ch, TAS256X_POWERCONTROL, &value); + if (n_result < 0) + pr_err("%s can't get ivsensor state %s, L=%d\n", LOG_TAG, + __func__, __LINE__); + else if (((value & TAS256X_POWERCONTROL_ISNSPOWER_MASK) == + TAS256X_POWERCONTROL_ISNSPOWER_ACTIVE) && + ((value & TAS256X_POWERCONTROL_VSNSPOWER_MASK) == + TAS256X_POWERCONTROL_VSNSPOWER_ACTIVE)) { + enable = TAS256X_IVSENSER_ENABLE; + } else { + enable = TAS256X_IVSENSER_DISABLE; + } + return enable; +} + +/*No need channel argument*/ +int tas256x_iv_slot_config(struct tas256x_priv *p_tas256x) +{ + int n_result = 0; + + if (p_tas256x->mn_channels == 2) { + if (p_tas256x->mn_slot_width == 16) { + p_tas256x->update_bits(p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG5, + 0xff, 0x41); + + p_tas256x->update_bits(p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG6, + 0xff, 0x40); + + p_tas256x->update_bits(p_tas256x, channel_right, + TAS256X_TDMCONFIGURATIONREG5, + 0xff, 0x43); + + p_tas256x->update_bits(p_tas256x, channel_right, + TAS256X_TDMCONFIGURATIONREG6, + 0xff, 0x42); + } else { + if (p_tas256x->mn_iv_width == 8) { + p_tas256x->update_bits( + p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG5, 0xff, + 0x41); + + p_tas256x->update_bits( + p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG6, 0xff, + 0x40); + + p_tas256x->update_bits( + p_tas256x, channel_right, + TAS256X_TDMCONFIGURATIONREG5, 0xff, + 0x45); + + p_tas256x->update_bits( + p_tas256x, channel_right, + TAS256X_TDMCONFIGURATIONREG6, 0xff, + 0x44); + + if (p_tas256x->mn_vbat == 1) { + p_tas256x->update_bits( + p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG7, + 0xff, 0x42); + + p_tas256x->update_bits( + p_tas256x, channel_right, + TAS256X_TDMCONFIGURATIONREG7, + 0xff, 0x46); + } + } else { + p_tas256x->update_bits( + p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG5, 0xff, + 0x42); + + p_tas256x->update_bits( + p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG6, 0xff, + 0x40); + + p_tas256x->update_bits( + p_tas256x, channel_right, + TAS256X_TDMCONFIGURATIONREG5, 0xff, + 0x46); + + p_tas256x->update_bits( + p_tas256x, channel_right, + TAS256X_TDMCONFIGURATIONREG6, 0xff, + 0x44); + } + } + } else if ((p_tas256x->mn_channels == 1) && + (p_tas256x->mn_slot_width == 32)) { + if (p_tas256x->mn_iv_width == 16) { + p_tas256x->update_bits( + p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK, + TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS); + p_tas256x->update_bits(p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG5, + 0xff, 0x44); + + p_tas256x->update_bits(p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG6, + 0xff, 0x40); + } else if (p_tas256x->mn_iv_width == 12) { + p_tas256x->update_bits( + p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK, + TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS); + p_tas256x->update_bits(p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG5, + 0xff, 0x41); + p_tas256x->update_bits(p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG6, + 0xff, 0x40); + if (p_tas256x->mn_vbat == 1) + p_tas256x->update_bits( + p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG7, 0xff, + 0x44); + } + } else if ((p_tas256x->mn_channels == 1) && + (p_tas256x->mn_slot_width == 16)) { + if (p_tas256x->mn_iv_width == 16) { + p_tas256x->update_bits( + p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK, + TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS); + p_tas256x->update_bits(p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG5, + 0xff, 0x42); + + p_tas256x->update_bits(p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG6, + 0xff, 0x40); + } else if (p_tas256x->mn_iv_width == 12) { + p_tas256x->update_bits( + p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK, + TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS); + p_tas256x->update_bits(p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG5, + 0xff, 0x41); + p_tas256x->update_bits(p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG6, + 0xff, 0x40); + if (p_tas256x->mn_vbat == 1) + p_tas256x->update_bits( + p_tas256x, channel_left, + TAS256X_TDMCONFIGURATIONREG7, 0xff, + 0x43); + } + } else { + pr_err("%s %s, wrong params, slot %d\n", LOG_TAG, __func__, + p_tas256x->mn_slot_width); + } + + return n_result; +} + +/*No need channel argument*/ +int tas256x_iv_bitwidth_config(struct tas256x_priv *p_tas256x) +{ + int n_result = 0; + + if (p_tas256x->mn_iv_width == 8) + n_result = p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_MASK, + TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_8BITS); + else if (p_tas256x->mn_iv_width == 12) + n_result = p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK, + TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS); + else /*mn_iv_width == 16*/ + n_result = p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK, + TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS); + + return n_result; +} + +/**/ +int tas256x_set_samplerate(struct tas256x_priv *p_tas256x, int samplerate) +{ + int n_result = 0; + + switch (samplerate) { + case 48000: + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG0, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ); + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG0, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ); + break; + case 44100: + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG0, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ); + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG0, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ); + break; + case 96000: + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG0, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ); + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG0, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ); + break; + case 88200: + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG0, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ); + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG0, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ); + break; + case 19200: + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG0, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ); + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG0, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ); + break; + case 17640: + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG0, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ); + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG0, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK, + TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ); + break; + default: + pr_info("%s %s, unsupported sample rate, %d\n", LOG_TAG, + __func__, samplerate); + } + + p_tas256x->mn_sampling_rate = samplerate; + + return n_result; +} + +/* + *rx_edge = 0; Falling + *= 1; Rising + */ +int tas256x_rx_set_fmt(struct tas256x_priv *p_tas256x, unsigned int rx_edge, + unsigned int rx_start_slot) +{ + int n_result = 0; + + if (rx_edge) + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG1, + TAS256X_TDMCONFIGURATIONREG1_RXEDGE_MASK, + TAS256X_TDMCONFIGURATIONREG1_RXEDGE_RISING); + else + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG1, + TAS256X_TDMCONFIGURATIONREG1_RXEDGE_MASK, + TAS256X_TDMCONFIGURATIONREG1_RXEDGE_FALLING); + + p_tas256x->update_bits( + p_tas256x, channel_left, TAS256X_TDMCONFIGURATIONREG1, + TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_MASK, + (rx_start_slot + << TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_SHIFT)); + + if (p_tas256x->mn_channels == 2) + p_tas256x->update_bits( + p_tas256x, channel_right, TAS256X_TDMCONFIGURATIONREG1, + TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_MASK, + (rx_start_slot + << TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_SHIFT)); + + return n_result; +} + +int tas256x_rx_set_slot(struct tas256x_priv *p_tas256x, int slot_width) +{ + int n_result = -1; + + switch (slot_width) { + case 16: + n_result = p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_MASK, + TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_16BITS); + break; + case 24: + n_result = p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_MASK, + TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_24BITS); + break; + case 32: + n_result = p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_MASK, + TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_32BITS); + break; + case 0: + /* Do not change slot width */ + break; + } + + if (n_result == 0) + p_tas256x->mn_slot_width = slot_width; + + return n_result; +} + +int tas256x_rx_set_bitwidth(struct tas256x_priv *p_tas256x, int bitwidth) +{ + int n_result = 0; + + switch (bitwidth) { + case 16: + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_MASK, + TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_16BITS); + break; + case 24: + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_MASK, + TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_24BITS); + break; + case 32: + p_tas256x->update_bits( + p_tas256x, channel_both, TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_MASK, + TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_32BITS); + break; + + default: + pr_info("%s Not supported params format\n", LOG_TAG); + break; + } + + return n_result; +} + +int tas256x_interrupt_clear(struct tas256x_priv *p_tas256x, int ch) +{ + int n_result = 0; + + p_tas256x->update_bits(p_tas256x, ch, TAS256X_INTERRUPTCONFIGURATION, + TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR_MASK, + TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR); + + return n_result; +} + +int tas256x_interrupt_enable(struct tas256x_priv *p_tas256x, int val, int ch) +{ + int n_result = 0; + + if (val) { + /*Enable Interrupts*/ + n_result = p_tas256x->write(p_tas256x, ch, + TAS256X_INTERRUPTMASKREG0, 0xf8); + n_result = p_tas256x->write(p_tas256x, ch, + TAS256X_INTERRUPTMASKREG1, 0xb1); + } else { + /*Disable Interrupts*/ + n_result = p_tas256x->write(p_tas256x, ch, + TAS256X_INTERRUPTMASKREG0, + TAS256X_INTERRUPTMASKREG0_DISABLE); + n_result = p_tas256x->write(p_tas256x, ch, + TAS256X_INTERRUPTMASKREG1, + TAS256X_INTERRUPTMASKREG1_DISABLE); + } + + return n_result; +} + +int tas256x_interrupt_read(struct tas256x_priv *p_tas256x, int *intr1, + int *intr2, int ch) +{ + int n_result = 0; + + n_result = p_tas256x->read(p_tas256x, ch, TAS256X_LATCHEDINTERRUPTREG0, + intr1); + n_result = p_tas256x->read(p_tas256x, ch, TAS256X_LATCHEDINTERRUPTREG1, + intr2); + + return n_result; +} + +int tas256x_icn_enable(struct tas256x_priv *p_tas256x, int enable, int ch) +{ + int n_result = 0; + + if (enable) { /*Enable*/ + p_tas256x->update_bits(p_tas256x, ch, TAS256X_ICN_SW_REG, + TAS256X_ICN_SW_MASK, + TAS256X_ICN_SW_ENABLE); + pr_info("%s %s: ICN Enable!\n", LOG_TAG, __func__); + } else { /*Disable*/ + p_tas256x->update_bits(p_tas256x, ch, TAS256X_ICN_SW_REG, + TAS256X_ICN_SW_MASK, + TAS256X_ICN_SW_DISABLE); + pr_info("%s %s: ICN Disable!\n", LOG_TAG, __func__); + } + + return n_result; +} + +/* icn_hysteresis & p_icn_thresholds*/ +int tas256x_icn_data(struct tas256x_priv *p_tas256x, int ch) +{ + int n_result = 0; + + pr_info("%s set ICN to -80dB\n", LOG_TAG); + n_result = + p_tas256x->bulk_write(p_tas256x, ch, TAS256X_ICN_THRESHOLD_REG, + p_icn_threshold, sizeof(p_icn_threshold)); + n_result = + p_tas256x->bulk_write(p_tas256x, ch, TAS256X_ICN_HYSTERESIS_REG, + p_icn_hysteresis, + sizeof(p_icn_hysteresis)); + + return n_result; +} + +int tas256x_icn_config(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = 0; + + n_result = + p_tas256x->write(p_tas256x, ch, TAS256X_REG(0, 253, 13), 0x0d); + if (n_result < 0) + return n_result; + + n_result = + p_tas256x->write(p_tas256x, ch, TAS256X_REG(0, 253, 25), 0x80); + + return n_result; +} + +int tas256x_boost_volt_update(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = 0; + + if (value == DEVICE_TAS2558) { + /* Max voltage to 9V */ + /*TODO: Need to be fixed*/ + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS2562_BOOSTCONFIGURATION2, + TAS2562_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_MASK, 0x7); + if (n_result < 0) + return n_result; + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS2562_PLAYBACKCONFIGURATIONREG0, + TAS2562_PLAYBACKCONFIGURATIONREG0_AMPLIFIERLEVEL51_MASK, + 0xd << 1); + } else if (value == DEVICE_TAS2562) { + /*TODO: ??*/ + } else if (value == DEVICE_TAS2564) { + /*Update Channel Gain to 16dBV*/ + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_PLAYBACKCONFIGURATIONREG0, + TAS2564_PLAYBACKCONFIGURATION_AMP_LEVEL_MASK, + TAS2564_AMP_LEVEL_16dBV); + } + return n_result; +} + +int tas256x_set_misc_config(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = 0; + + n_result = p_tas256x->write(p_tas256x, ch, + TAS256X_MISCCONFIGURATIONREG0, 0xcf); + + return n_result; +} + +int tas256x_set_tx_config(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = 0; + +#ifdef CONFIG_PLATFORM_EXYNOS + if (p_tas256x->mn_channels == 2) { + n_result = p_tas256x->write(p_tas256x, channel_left, + TAS256X_TDMConfigurationReg4, 0xf3); + if (n_result < 0) + return n_result; + n_result = p_tas256x->write(p_tas256x, channel_right, + TAS256X_TDMConfigurationReg4, 0x13); + if (n_result < 0) + return n_result; + } else { + n_result = p_tas256x->write(p_tas256x, channel_both, + TAS256X_TDMConfigurationReg4, 0x03); + if (n_result < 0) + return n_result; + } +#else + if (p_tas256x->mn_channels == 2) { + n_result = p_tas256x->write(p_tas256x, channel_left, + TAS256X_TDMConfigurationReg4, 0xf1); + if (n_result < 0) + return n_result; + n_result = p_tas256x->write(p_tas256x, channel_right, + TAS256X_TDMConfigurationReg4, 0x11); + if (n_result < 0) + return n_result; + } else { + n_result = p_tas256x->write(p_tas256x, channel_both, + TAS256X_TDMConfigurationReg4, 0x01); + if (n_result < 0) + return n_result; + } +#endif + + return n_result; +} + +int tas256x_set_clock_config(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = 0; + + n_result = p_tas256x->write(p_tas256x, ch, TAS256X_CLOCKCONFIGURATION, + 0x0c); + + /* Increase the clock halt timer to 838ms to avoid + * TDM Clock errors during playback start/stop + */ + n_result |= p_tas256x->update_bits(p_tas256x, ch, + TAS256X_INTERRUPTCONFIGURATION, + TAS256X_CLOCK_HALT_TIMER_MASK, + TAS256X_CLOCK_HALT_838MS); + return n_result; +} + +int tas256x_set_classH_config(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = 0; + + n_result = + tas256x_i2c_load_data(p_tas256x, ch, p_tas256x_classh_d_data); + + return n_result; +} + +int tas256x_HPF_FF_Bypass(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = 0; + + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_PLAYBACKCONFIGURATIONREG0, + TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_MASK, + TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_DISABLED); + + return n_result; +} + +int tas256x_HPF_FB_Bypass(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = 0; + + n_result = p_tas256x->bulk_write( + p_tas256x, ch, TAS256X_HPF, HPF_reverse_path, + sizeof(HPF_reverse_path) / sizeof(HPF_reverse_path[0])); + + return n_result; +} + +int tas56x_software_reset(struct tas256x_priv *p_tas256x, int ch) +{ + int n_result = 0; + + n_result = p_tas256x->write(p_tas256x, ch, TAS256X_SOFTWARERESET, + TAS256X_SOFTWARERESET_SOFTWARERESET_RESET); + + msleep(20); + + return n_result; +} + +int tas256x_interrupt_determine(struct tas256x_priv *p_tas256x, int ch, + int int1status, int int2status) +{ + int mn_err_code = 0; + + if (((int1status & 0x7) != 0) || ((int2status & 0x0f) != 0)) { + if (int1status & + TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_INTERRUPT) { + mn_err_code |= ERROR_CLOCK; + pr_err("%s TDM clock error!\n", LOG_TAG); + } else { + mn_err_code &= ~ERROR_CLOCK; + } + + if (int1status & + TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_INTERRUPT) { + mn_err_code |= ERROR_OVER_CURRENT; + pr_err("%s SPK over current!\n", LOG_TAG); + } else { + mn_err_code &= ~ERROR_OVER_CURRENT; + } + + if (int1status & + TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_INTERRUPT) { + mn_err_code |= ERROR_DIE_OVERTEMP; + pr_err("%s die over temperature!\n", LOG_TAG); + } else { + mn_err_code &= ~ERROR_DIE_OVERTEMP; + } + + if (int2status & + TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_INTERRUPT) { + mn_err_code |= ERROR_OVER_VOLTAGE; + pr_err("%s SPK over voltage!\n", LOG_TAG); + } else { + mn_err_code &= ~ERROR_OVER_VOLTAGE; + } + + if (int2status & + TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_INTERRUPT) { + mn_err_code |= ERROR_UNDER_VOLTAGE; + pr_err("%s SPK under voltage!\n", LOG_TAG); + } else { + mn_err_code &= ~ERROR_UNDER_VOLTAGE; + } + + if (int2status & + TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_INTERRUPT) { + mn_err_code |= ERROR_BROWNOUT; + pr_err("%s brownout!\n", LOG_TAG); + } else { + mn_err_code &= ~ERROR_BROWNOUT; + } + } else { + return 0; + } + + return mn_err_code; +} + +int tas56x_get_chipid(struct tas256x_priv *p_tas256x, int *chipid, int ch) +{ + int n_result = 0; + + n_result = p_tas256x->read(p_tas256x, ch, TAS256X_CHIPID, chipid); + + return n_result; +} + +int tas2564_rx_mode_update(struct tas256x_priv *p_tas256x, int rx_mode, int ch) +{ + int n_result = 0; + + if (rx_mode) { + /* Default code */ + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS2564_PLAYBACKCONFIGURATIONREG0, + TAS2564_PLAYBACKCONFIGURATIONREG_RX_SPKR_MODE_MASK, + TAS2564_PLAYBACKCONFIGURATIONREG_RX_MODE); + + /*Unlock test page*/ + n_result = p_tas256x->write(p_tas256x, ch, + TAS256X_TEST_PAGE_LOCK, 0xd); + /*Keep DAC modulator dither to minimum*/ + n_result |= p_tas256x->write(p_tas256x, ch, + TAS256X_DAC_MODULATOR, 0xc0); + /* ICN improvement*/ + n_result |= p_tas256x->write(p_tas256x, ch, TAS256X_ICN_IMPROVE, + 0x1f); + /* LSFB strength bias current 9uA -> 3uA*/ + n_result |= p_tas256x->write( + p_tas256x, ch, TAS256X_CLASSDCONFIGURATION2, 0x08); + /*Enable IRQ pull-up, disable SSM*/ + n_result |= p_tas256x->write( + p_tas256x, ch, TAS256X_MISCCONFIGURATIONREG0, 0xca); + /*Mask reaction of idle channel detect on IV sense*/ + n_result |= p_tas256x->write(p_tas256x, ch, TAS256X_ICN_SW_REG, + 0x00); + } else { + /* Default code */ + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS2564_PLAYBACKCONFIGURATIONREG0, + TAS2564_PLAYBACKCONFIGURATIONREG_RX_SPKR_MODE_MASK, + TAS2564_PLAYBACKCONFIGURATIONREG_SPKR_MODE); + + /*Unlock test page*/ + n_result = p_tas256x->write(p_tas256x, ch, + TAS256X_TEST_PAGE_LOCK, 0xd); + /*Keep DAC modulator dither to minimum*/ + n_result |= p_tas256x->write(p_tas256x, ch, + TAS256X_DAC_MODULATOR, 0x00); + /* ICN improvement*/ + n_result |= p_tas256x->write(p_tas256x, ch, TAS256X_ICN_IMPROVE, + 0x1f); + /* Default value = 0x28; LSFB strength = 9uA max.*/ + n_result |= p_tas256x->write( + p_tas256x, ch, TAS256X_CLASSDCONFIGURATION2, 0x28); + /*Enable IRQ pull-up, disable SSM*/ + n_result |= p_tas256x->write( + p_tas256x, ch, TAS256X_MISCCONFIGURATIONREG0, 0xc6); + /*Mask reaction of idle channel detect on IV sense*/ + n_result |= p_tas256x->write(p_tas256x, ch, TAS256X_ICN_SW_REG, + 0x10); + } + if (n_result == 0) + p_tas256x->devs[ch - 1]->rx_mode = rx_mode; + + return n_result; +} + +int tas256x_update_playback_volume(struct tas256x_priv *p_tas256x, int value, + int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 57)) { + n_result = p_tas256x->bulk_write(p_tas256x, ch, TAS256X_DVC_PCM, + (char *)&(dvc_pcm[value][0]), + sizeof(int)); + if (n_result == 0) + p_tas256x->devs[ch - 1]->dvc_pcm = value; + } + + return n_result; +} + +int tas256x_update_lim_max_attenuation(struct tas256x_priv *p_tas256x, + int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 16)) { + n_result = p_tas256x->bulk_write( + p_tas256x, ch, TAS256X_LIM_MAX_ATN, + (char *)&(lim_max_attn[value][0]), sizeof(int)); + if (n_result == 0) + p_tas256x->devs[ch - 1]->lim_max_attn = value; + } + + return n_result; +} + +int tas256x_update_lim_max_thr(struct tas256x_priv *p_tas256x, int value, + int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 27)) { + n_result = p_tas256x->bulk_write( + p_tas256x, ch, TAS256X_LIMB_TH_MAX, + (char *)&(vbat_lim_max_thd[value][0]), sizeof(int)); + if (n_result == 0) + p_tas256x->devs[ch - 1]->lim_thr_max = value; + } + + return n_result; +} + +int tas256x_update_lim_min_thr(struct tas256x_priv *p_tas256x, int value, + int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 27)) { + n_result = p_tas256x->bulk_write( + p_tas256x, ch, TAS256X_LIMB_TH_MIN, + (char *)&(vbat_lim_min_thd[value][0]), sizeof(int)); + if (n_result == 0) + p_tas256x->devs[ch - 1]->lim_thr_min = value; + } + + return n_result; +} + +int tas256x_update_lim_inflection_point(struct tas256x_priv *p_tas256x, + int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 41)) { + n_result = p_tas256x->bulk_write( + p_tas256x, ch, TAS256X_LIMB_INF_PT, + (char *)&(vbat_lim_infl_pt[value][0]), sizeof(int)); + if (n_result == 0) + p_tas256x->devs[ch - 1]->lim_infl_pt = value; + } + + return n_result; +} + +int tas256x_update_lim_slope(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 7)) { + n_result = p_tas256x->bulk_write( + p_tas256x, ch, TAS256X_LIMB_SLOPE, + (char *)&(vbat_lim_track_slope[value][0]), sizeof(int)); + if (n_result == 0) + p_tas256x->devs[ch - 1]->lim_trk_slp = value; + } + + return n_result; +} + +int tas256x_update_bop_thr(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 16)) { + n_result = p_tas256x->bulk_write(p_tas256x, ch, TAS256X_BOP_TH, + (char *)&(bop_thd[value][0]), + sizeof(int)); + if (n_result == 0) + p_tas256x->devs[ch - 1]->bop_thd = value; + } + return n_result; +} + +int tas256x_update_bosd_thr(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 16)) { + n_result = p_tas256x->bulk_write(p_tas256x, ch, TAS256X_BOSD_TH, + (char *)&(bsd_thd[value][0]), + sizeof(int)); + if (n_result == 0) + p_tas256x->devs[ch - 1]->bosd_thd = value; + } + + return n_result; +} + +int tas256x_update_boost_voltage(struct tas256x_priv *p_tas256x, int value, + int ch) +{ + int n_result = -1; + + if (p_tas256x->devs[ch - 1]->device_id == DEVICE_TAS2562) { + if ((value >= 0) && (value < 16)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS2562_BOOSTCONFIGURATION2, + TAS2562_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_MASK, + (value + + 1) << TAS2562_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_SHIFT); + } else if (p_tas256x->devs[ch - 1]->device_id == DEVICE_TAS2564) { + if ((value >= 0) && (value < 32)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS2564_BOOSTCONFIGURATION2, + TAS2564_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_MASK, + (value + + 7) << TAS2562_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_SHIFT); + } + + if (n_result == 0) + p_tas256x->devs[ch - 1]->bst_vltg = value; + + return n_result; +} + +int tas256x_update_current_limit(struct tas256x_priv *p_tas256x, int value, + int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 64)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_BOOSTCONFIGURATION4, + TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_MASK, + (value) << TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_SHIFT); + + if (n_result == 0) + p_tas256x->devs[ch - 1]->bst_ilm = value; + + return n_result; +} + +int tas256x_update_limiter_enable(struct tas256x_priv *p_tas256x, int value, + int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 2)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_LIMITERCONFIGURATION0, + TAS256X_LIMITER_ENABLE_MASK, + (value) << TAS256X_LIMITER_ENABLE_SHIFT); + + if (n_result == 0) + p_tas256x->devs[ch - 1]->lim_switch = value; + + return n_result; +} + +int tas256x_update_limiter_attack_rate(struct tas256x_priv *p_tas256x, + int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 8)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_LIMITERCONFIGURATION0, + TAS256X_LIMITER_ATTACKRATE_MASK, + (value) << TAS256X_LIMITER_ATTACKRATE_SHIFT); + + if (n_result == 0) + p_tas256x->devs[ch - 1]->lim_att_rate = value; + + return n_result; +} + +int tas256x_update_limiter_attack_step_size(struct tas256x_priv *p_tas256x, + int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 4)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_LIMITERCONFIGURATION0, + TAS256X_LIMITER_ATTACKSTEPSIZE_MASK, + (value) << TAS256X_LIMITER_ATTACKSTEPSIZE_SHIFT); + + if (n_result == 0) + p_tas256x->devs[ch - 1]->lim_att_stp_size = value; + + return n_result; +} + +int tas256x_update_limiter_release_rate(struct tas256x_priv *p_tas256x, + int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 8)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_LIMITERCONFIGURATION1, + TAS256X_LIMITER_RELEASERATE_MASK, + (value) << TAS256X_LIMITER_RELEASERATE_SHIFT); + + if (n_result == 0) + p_tas256x->devs[ch - 1]->lim_rel_rate = value; + + return n_result; +} + +int tas256x_update_limiter_release_step_size(struct tas256x_priv *p_tas256x, + int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 4)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_LIMITERCONFIGURATION1, + TAS256X_LIMITER_RELEASESTEPSIZE_MASK, + (value) << TAS256X_LIMITER_RELEASESTEPSIZE_SHIFT); + + if (n_result == 0) + p_tas256x->devs[ch - 1]->lim_rel_stp_size = value; + + return n_result; +} + +int tas256x_update_bop_enable(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 2)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_BOPCONFIGURATION0, + TAS256X_BOP_ENABLE_MASK, + (value) << TAS256X_BOP_ENABLE_SHIFT); + + if (n_result == 0) + p_tas256x->devs[ch - 1]->bop_enable = value; + + return n_result; +} + +int tas256x_update_bop_mute(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 2)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_BOPCONFIGURATION0, + TAS256X_BOP_MUTE_MASK, + (value) << TAS256X_BOP_MUTE_SHIFT); + + if (n_result == 0) + p_tas256x->devs[ch - 1]->bop_mute = value; + + return n_result; +} + +int tas256x_update_bop_shutdown_enable(struct tas256x_priv *p_tas256x, + int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 2)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_BOPCONFIGURATION0, + TAS256X_BOP_SHUTDOWN_ENABLE_MASK, + (value) << TAS256X_BOP_SHUTDOWN_ENABLE_SHIFT); + + if (n_result == 0) + p_tas256x->devs[ch - 1]->bosd_enable = value; + + return n_result; +} + +int tas256x_update_bop_attack_rate(struct tas256x_priv *p_tas256x, int value, + int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 8)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_BOPCONFIGURATION1, + TAS256X_BOP_ATTACKRATE_MASK, + (value) << TAS256X_BOP_ATTACKRATE_SHIFT); + + if (n_result == 0) + p_tas256x->devs[ch - 1]->bop_att_rate = value; + + return n_result; +} + +int tas256x_update_bop_attack_step_size(struct tas256x_priv *p_tas256x, + int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 4)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_BOPCONFIGURATION1, + TAS256X_BOP_ATTACKSTEPSIZE_MASK, + (value) << TAS256X_BOP_ATTACKSTEPSIZE_SHIFT); + + if (n_result == 0) + p_tas256x->devs[ch - 1]->bop_att_stp_size = value; + + return n_result; +} + +int tas256x_update_bop_hold_time(struct tas256x_priv *p_tas256x, int value, + int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 8)) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_BOPCONFIGURATION1, + TAS256X_BOP_HOLDTIME_MASK, + (value) << TAS256X_BOP_HOLDTIME_SHIFT); + + if (n_result == 0) + p_tas256x->devs[ch - 1]->bop_hld_time = value; + + return n_result; +} + +int tas256x_update_vbat_lpf(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = -1; + + if ((value >= 0) && (value < 4)) { + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_VBATFILTER, + TAS256X_VBAT_LPF_MASK, + (value) << TAS256X_VBAT_LPF_SHIFT); + if (n_result == 0) + p_tas256x->devs[ch - 1]->vbat_lpf = value; + } + + return n_result; +} + +int tas256x_update_rx_cfg(struct tas256x_priv *p_tas256x, int value, int ch) +{ + int n_result = -1; + int data = -1; + + switch (value) { + case 0: + data = TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_I2C; + break; + case 1: + data = TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_LEFT; + break; + case 2: + data = TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_RIGHT; + break; + case 3: + data = TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_STEREO_DOWNMIX; + break; + } + + if (data >= 0) + n_result = p_tas256x->update_bits( + p_tas256x, ch, TAS256X_TDMCONFIGURATIONREG2, + TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MASK, data); + + if (n_result == 0) + p_tas256x->devs[ch - 1]->rx_cfg = value; + + return n_result; +} diff --git a/techpack/audio/asoc/codecs/tas256x/tas256x.h b/techpack/audio/asoc/codecs/tas256x/tas256x.h new file mode 100644 index 000000000000..960f0946931a --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/tas256x.h @@ -0,0 +1,647 @@ +#ifndef __TAS256X_ +#define __TAS256X_ + +#include +#include +#include +#include +#include +#include +#define CODEC_PM +#define TAS256X_DRIVER_TAG "202003201710" + +/* Page Control Register */ +#define TAS256X_PAGECTL_REG 0 +#define CONFIG_TAS256X_BIN_PARSER +/* Book Control Register (available in page0 of each book) */ +#define TAS256X_BOOKCTL_PAGE 0 +#define TAS256X_BOOKCTL_REG 127 + +#define TAS256X_REG(book, page, reg) (((book * 256 * 128) + (page * 128)) + reg) + +#define TAS256X_BOOK_ID(reg) (reg / (256 * 128)) + +#define TAS256X_PAGE_ID(reg) ((reg % (256 * 128)) / 128) + +#define TAS256X_BOOK_REG(reg) (reg % (256 * 128)) + +#define TAS256X_PAGE_REG(reg) ((reg % (256 * 128)) % 128) + +/* Software Reset */ +#define TAS256X_SOFTWARERESET TAS256X_REG(0x0, 0x0, 0x01) +#define TAS256X_SOFTWARERESET_SOFTWARERESET_MASK (0x1 << 0) +#define TAS256X_SOFTWARERESET_SOFTWARERESET_DONTRESET (0x0 << 0) +#define TAS256X_SOFTWARERESET_SOFTWARERESET_RESET (0x1 << 0) + +/* Power Control */ +#define TAS256X_POWERCONTROL TAS256X_REG(0x0, 0x0, 0x02) +#define TAS256X_POWERCONTROL_ISNSPOWER_MASK (0x1 << 3) +#define TAS256X_POWERCONTROL_ISNSPOWER_ACTIVE (0x0 << 3) +#define TAS256X_POWERCONTROL_ISNSPOWER_POWEREDDOWN (0x1 << 3) +#define TAS256X_POWERCONTROL_VSNSPOWER_MASK (0x1 << 2) +#define TAS256X_POWERCONTROL_VSNSPOWER_ACTIVE (0x0 << 2) +#define TAS256X_POWERCONTROL_VSNSPOWER_POWEREDDOWN (0x1 << 2) +#define TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK (0x3 << 0) +#define TAS256X_POWERCONTROL_OPERATIONALMODE10_ACTIVE (0x0 << 0) +#define TAS256X_POWERCONTROL_OPERATIONALMODE10_MUTE (0x1 << 0) +#define TAS256X_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN (0x2 << 0) + +/* Playback Configuration Reg0 */ +#define TAS256X_PLAYBACKCONFIGURATIONREG0 TAS256X_REG(0x0, 0x0, 0x03) +#define TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_MASK (0x1 << 6) +#define TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_ENABLED (0x0 << 6) +#define TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_DISABLED (0x1 << 6) + +/* Misc Configuration Reg0 */ +#define TAS256X_MISCCONFIGURATIONREG0 TAS256X_REG(0x0, 0x0, 0x04) +#define TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_MASK (0x1 << 7) +#define TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_DONOTRETRY (0x0 << 7) +#define TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_RETRY (0x1 << 7) +#define TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_MASK (0x1 << 6) +#define TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_DONOTRETRY (0x0 << 6) +#define TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_RETRY (0x1 << 6) +#define TAS256X_MISCCONFIGURATIONREG0_OCERETRY_MASK (0x1 << 5) +#define TAS256X_MISCCONFIGURATIONREG0_OCERETRY_DONOTRETRY (0x0 << 5) +#define TAS256X_MISCCONFIGURATIONREG0_OCERETRY_RETRY (0x1 << 5) +#define TAS256X_MISCCONFIGURATIONREG0_OTERETRY_MASK (0x1 << 4) +#define TAS256X_MISCCONFIGURATIONREG0_OTERETRY_DONOTRETRY (0x0 << 4) +#define TAS256X_MISCCONFIGURATIONREG0_OTERETRY_RETRY (0x1 << 4) +#define TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_MASK (0x1 << 3) +#define TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_DISABLED (0x0 << 3) +#define TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_ENABLED (0x1 << 3) +#define TAS256X_MISCCONFIGURATIONREG0_AMPSS_MASK (0x1 << 2) +#define TAS256X_MISCCONFIGURATIONREG0_AMPSS_DISABLED (0x0 << 2) +#define TAS256X_MISCCONFIGURATIONREG0_AMPSS_ENABLED (0x1 << 2) + +/* TDM Configuration Reg0 */ +#define TAS256X_TDMCONFIGURATIONREG0 TAS256X_REG(0x0, 0x0, 0x06) +#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK (0x1 << 5) +#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ (0x0 << 5) +#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ (0x1 << 5) +#define TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_MASK (0x1 << 4) +#define TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_DISABLED (0x1 << 4) +#define TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_ENABLED (0x0 << 4) +#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK (0x7 << 1) +#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_14_7_16KHZ (0x1 << 1) +#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ (0x4 << 1) +#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ (0x5 << 1) +#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ (0x6 << 1) +#define TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_MASK (0x1 << 0) +#define TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_LOWTOHIGH (0x0 << 0) +#define TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_HIGHTOLOW (0x1 << 0) + +/* TDM Configuration Reg1 */ +#define TAS256X_TDMCONFIGURATIONREG1 TAS256X_REG(0x0, 0x0, 0x07) +#define TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_MASK (0x1 << 6) +#define TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_LEFT (0x0 << 6) +#define TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_RIGHT (0x1 << 6) +#define TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_MASK (0x1f << 1) +#define TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_SHIFT (1) +#define TAS256X_TDMCONFIGURATIONREG1_RXEDGE_MASK (0x1 << 0) +#define TAS256X_TDMCONFIGURATIONREG1_RXEDGE_RISING (0x0 << 0) +#define TAS256X_TDMCONFIGURATIONREG1_RXEDGE_FALLING (0x1 << 0) + +/* TDM Configuration Reg2 */ +#define TAS256X_TDMCONFIGURATIONREG2 TAS256X_REG(0x0, 0x0, 0x08) +#define TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK (0X3 << 6) +#define TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS (0x0 << 6) +#define TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS (0x1 << 6) +#define TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_8BITS (0x2 << 6) +#define TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_MASK (0x3 << 6) +#define TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_8BITS (0x2 << 6) +#define TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_12BITS (0x1 << 6) +#define TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_16BITS (0x0 << 6) +#define TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MASK (0x3 << 4) +#define TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_I2C (0x0 << 4) +#define TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_LEFT (0x1 << 4) +#define TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_RIGHT (0x2 << 4) +#define TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_STEREO_DOWNMIX (0x3 << 4) +#define TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_MASK (0x3 << 2) +#define TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_16BITS (0x0 << 2) +#define TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_20BITS (0x1 << 2) +#define TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_24BITS (0x2 << 2) +#define TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_32BITS (0x3 << 2) +#define TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_MASK (0x3 << 0) +#define TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_16BITS (0x0 << 0) +#define TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_24BITS (0x1 << 0) +#define TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_32BITS (0x2 << 0) + +/* TDM Configuration Reg4 */ +#define TAS256X_TDMConfigurationReg4 TAS256X_REG(0x0, 0x0, 0x0A) +#define TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_MASK (0x1 << 5) +#define TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_DISABLE (0x0 << 5) +#define TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_ENABLE (0x1 << 5) +#define TAS256X_TDMCONFIGURATIONREG4_TXFILL_MASK (0x1 << 4) +#define TAS256X_TDMCONFIGURATIONREG4_TXFILL_TRANSMIT0 (0x0 << 4) +#define TAS256X_TDMCONFIGURATIONREG4_TXFILL_TRANSMITHIZ (0x1 << 4) +#define TAS256X_TDMCONFIGURATIONREG4_TXOFFSET31_MASK (0x7 << 1) +#define TAS256X_TDMCONFIGURATIONREG4_TXEDGE_MASK (0x1 << 0) +#define TAS256X_TDMCONFIGURATIONREG4_TXEDGE_RISING (0x0 << 0) +#define TAS256X_TDMCONFIGURATIONREG4_TXEDGE_FALLING (0x1 << 0) + +/* TDM Configuration Reg5 */ +#define TAS256X_TDMCONFIGURATIONREG5 TAS256X_REG(0x0, 0x0, 0x0B) +#define TAS256X_TDMCONFIGURATIONREG5_VSNSTX_MASK (0x1 << 6) +#define TAS256X_TDMCONFIGURATIONREG5_VSNSTX_DISABLE (0x0 << 6) +#define TAS256X_TDMCONFIGURATIONREG5_VSNSTX_ENABLE (0x1 << 6) +#define TAS256X_TDMCONFIGURATIONREG5_VSNSSLOT50_MASK (0x3f << 0) + +/* TDM Configuration Reg6 */ +#define TAS256X_TDMCONFIGURATIONREG6 TAS256X_REG(0x0, 0x0, 0x0C) +#define TAS256X_TDMCONFIGURATIONREG6_ISNSTX_MASK (0x1 << 6) +#define TAS256X_TDMCONFIGURATIONREG6_ISNSTX_DISABLE (0x0 << 6) +#define TAS256X_TDMCONFIGURATIONREG6_ISNSTX_ENABLE (0x1 << 6) +#define TAS256X_TDMCONFIGURATIONREG6_ISNSSLOT50_MASK (0x3f << 0) + +/* TDM Configuration Reg7 */ +#define TAS256X_TDMCONFIGURATIONREG7 TAS256X_REG(0x0, 0x0, 0x0D) +#define TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_MASK (0x1 << 7) +#define TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_8BITS (0x0 << 7) +#define TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_16BITS (0x1 << 7) +#define TAS256X_TDMCONFIGURATIONREG7_VBATTX_MASK (0x1 << 6) +#define TAS256X_TDMCONFIGURATIONREG7_VBATTX_DISABLE (0x0 << 6) +#define TAS256X_TDMCONFIGURATIONREG7_VBATTX_ENABLE (0x1 << 6) +#define TAS256X_TDMCONFIGURATIONREG7_VBATSLOT50_MASK (0x3f << 0) + +/* Interrupt Mask Reg0 */ +#define TAS256X_INTERRUPTMASKREG0 TAS256X_REG(0x0, 0x0, 0x1A) +#define TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_MASK (0x1 << 7) +#define TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_UNMASK (0x0 << 7) +#define TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_DISABLE (0x1 << 7) +#define TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_MASK (0x1 << 6) +#define TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_UNMASK (0x0 << 6) +#define TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_DISABLE (0x1 << 6) +#define TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_MASK (0x1 << 5) +#define TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_UNMASK (0x0 << 5) +#define TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_DISABLE (0x1 << 5) +#define TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_MASK (0x1 << 4) +#define TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_UNMASK (0x0 << 4) +#define TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_DISABLE (0x1 << 4) +#define TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_MASK (0x1 << 3) +#define TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_UNMASK (0x0 << 3) +#define TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_DISABLE (0x1 << 3) +#define TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_MASK (0x1 << 2) +#define TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_UNMASK (0x0 << 2) +#define TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_DISABLE (0x1 << 2) +#define TAS256X_INTERRUPTMASKREG0_OCEINTMASK_MASK (0x1 << 1) +#define TAS256X_INTERRUPTMASKREG0_OCEINTMASK_UNMASK (0x0 << 1) +#define TAS256X_INTERRUPTMASKREG0_OCEINTMASK_DISABLE (0x1 << 1) +#define TAS256X_INTERRUPTMASKREG0_OTEINTMASK_MASK (0x1 << 0) +#define TAS256X_INTERRUPTMASKREG0_OTEINTMASK_UNMASK (0x0 << 0) +#define TAS256X_INTERRUPTMASKREG0_OTEINTMASK_DISABLE (0x1 << 0) +#define TAS256X_INTERRUPTMASKREG0_DISABLE 0xff + +/* Interrupt Mask Reg1 */ +#define TAS256X_INTERRUPTMASKREG1 TAS256X_REG(0x0, 0x0, 0x1B) +#define TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_MASK (0x1 << 7) +#define TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_UNMASK (0x0 << 7) +#define TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_DISABLE (0x1 << 7) +#define TAS256X_INTERRUPTMASKREG1_CRCINTMASK_MASK (0x1 << 6) +#define TAS256X_INTERRUPTMASKREG1_CRCINTMASK_UNMASK (0x0 << 6) +#define TAS256X_INTERRUPTMASKREG1_CRCINTMASK_DISABLE (0x1 << 6) +#define TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_MASK (0x1 << 2) +#define TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_UNMASK (0x0 << 2) +#define TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_DISABLE (0x1 << 2) +#define TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_MASK (0x1 << 1) +#define TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_UNMASK (0x0 << 1) +#define TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_DISABLE (0x1 << 1) +#define TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_MASK (0x1 << 0) +#define TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_UNMASK (0x0 << 0) +#define TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_DISABLE (0x1 << 0) +#define TAS256X_INTERRUPTMASKREG1_DISABLE 0xff + +/* Latched-Interrupt Reg0 */ +#define TAS256X_LATCHEDINTERRUPTREG0 TAS256X_REG(0x0, 0x0, 0x24) +#define TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_MASK (0x1 << 7) +#define TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_NOINTERRUPT (0x0 << 7) +#define TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_INTERRUPT (0x1 << 7) +#define TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_MASK (0x1 << 6) +#define TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_NOINTERRUPT (0x0 << 6) +#define TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_INTERRUPT (0x1 << 6) +#define TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_MASK (0x1 << 5) +#define TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_NOINTERRUPT (0x0 << 5) +#define TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_INTERRUPT (0x1 << 5) +#define TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_MASK (0x1 << 4) +#define TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_NOINTERRUPT \ + (0x0 << 4) +#define TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_INTERRUPT (0x1 << 4) +#define TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_MASK (0x1 << 3) +#define TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_NOINTERRUPT (0x0 << 3) +#define TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_INTERRUPT (0x1 << 3) +#define TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_MASK (0x1 << 2) +#define TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_NOINTERRUPT (0x0 << 2) +#define TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_INTERRUPT (0x1 << 2) +#define TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_MASK (0x1 << 1) +#define TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_NOINTERRUPT (0x0 << 1) +#define TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_INTERRUPT (0x1 << 1) +#define TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_MASK (0x1 << 0) +#define TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_NOINTERRUPT (0x0 << 0) +#define TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_INTERRUPT (0x1 << 0) + +/* Latched-Interrupt Reg1 */ +#define TAS256X_LATCHEDINTERRUPTREG1 TAS256X_REG(0x0, 0x0, 0x25) +#define TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_MASK (0x1 << 7) +#define TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_NOINTERRUPT \ + (0x0 << 7) +#define TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_INTERRUPT \ + (0x1 << 7) +#define TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_MASK (0x1 << 3) +#define TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_NOINTERRUPT (0x0 << 3) +#define TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_INTERRUPT (0x1 << 3) +#define TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_MASK (0x1 << 2) +#define TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_NOINTERRUPT (0x0 << 2) +#define TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_INTERRUPT (0x1 << 2) +#define TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_MASK (0x1 << 1) +#define TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_NOINTERRUPT (0x0 << 1) +#define TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_INTERRUPT (0x1 << 1) +#define TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_MASK (0x1 << 0) +#define TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_NOINTERRUPT (0x0 << 0) +#define TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_INTERRUPT (0x1 << 0) + +/* Interrupt Configuration */ +#define TAS256X_INTERRUPTCONFIGURATION TAS256X_REG(0x0, 0x0, 0x30) +#define TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR_MASK (0x1 << 2) +#define TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR (0x1 << 2) +#define TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_MASK (0x3 << 0) +#define TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLIVEINTERRUPTS \ + (0x0 << 0) +#define TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLATCHEDINTERRUPTS \ + (0x1 << 0) +#define TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLIVEINTERRUPTS \ + (0x2 << 0) +#define TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLATCHEDINTERRUPTS \ + (0x3 << 0) + +#define TAS256X_CLOCK_HALT_TIMER_MASK (0x7 << 3) +#define TAS256X_CLOCK_HALT_1MS (0x0 << 3) +#define TAS256X_CLOCK_HALT_3MS (0x1 << 3) +#define TAS256X_CLOCK_HALT_26MS (0x2 << 3) +#define TAS256X_CLOCK_HALT_52MS (0x3 << 3) +#define TAS256X_CLOCK_HALT_104MS (0x4 << 3) +#define TAS256X_CLOCK_HALT_209MS (0x5 << 3) +#define TAS256X_CLOCK_HALT_419MS (0x6 << 3) +#define TAS256X_CLOCK_HALT_838MS (0x7 << 3) +#define TAS256X_BOOSTSLOPE TAS256X_REG(0x0, 0x0, 0x35) +#define TAS256X_BOOSTSLOPE_MASK (0x3 << 2) + +/* Clock Configuration */ +#define TAS256X_CLOCKCONFIGURATION TAS256X_REG(0x0, 0x0, 0x38) +#define TAS256X_CLOCKCONFIGURATION_SBCLKTOFS52_MASK (0xf << 2) +#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_16 (0x0 << 2) +#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_24 (0x1 << 2) +#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_32 (0x2 << 2) +#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_48 (0x3 << 2) +#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_64 (0x4 << 2) +#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_96 (0x5 << 2) +#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_128 (0x6 << 2) +#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_192 (0x7 << 2) +#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_256 (0x8 << 2) +#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_384 (0x9 << 2) +#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_512 (0xa << 2) +#define TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_MASK (0x3 << 0) +#define TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_DISABLED (0x1 << 0) +#define TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_ENABLED (0x0 << 0) + +#define TAS256X_VBATFILTER TAS256X_REG(0x0, 0x0, 0x3b) +#define TAS256X_VBAT_LPF_MASK (0x3 << 5) +#define TAS256X_VBAT_LPF_SHIFT 5 + +#define TAS256X_CLASSHRELEASETIMER TAS256X_REG(0x0, 0x0, 0x3c) + +#define TAS256X_BOOST_CFG4 TAS256X_REG(0x0, 0x0, 0x40) + +#define TAS256X_CHIPID TAS256X_REG(0x0, 0x0, 0x7D) + +#define TAS256X_ICN_THRESHOLD_REG TAS256X_REG(0x0, 0x2, 0x64) +#define TAS256X_ICN_HYSTERESIS_REG TAS256X_REG(0x0, 0x2, 0x6c) + +#define TAS256X_ICN_SW_REG TAS256X_REG(0x0, 0x0, 0x3e) +#define TAS256X_ICN_SW_MASK (0x01 << 4) +#define TAS256X_ICN_SW_ENABLE (0x10) +#define TAS256X_ICN_SW_DISABLE (0x00) +#define TAS256X_TESTPAGECONFIGURATION TAS256X_REG(0x0, 0xfd, 0xd) +#define TAS256X_CLASSDCONFIGURATION1 TAS256X_REG(0x0, 0xfd, 0x19) +#define TAS256X_CLASSDCONFIGURATION2 TAS256X_REG(0x0, 0xfd, 0x32) +#define TAS256X_CLASSDCONFIGURATION3 TAS256X_REG(0x0, 0xfd, 0x33) +#define TAS256X_CLASSDCONFIGURATION4 TAS256X_REG(0x0, 0xfd, 0x3f) +#define TAS256X_EFFICIENCYCONFIGURATION TAS256X_REG(0x0, 0xfd, 0x5f) + +#define TAS256X_HPF TAS256X_REG(0x0, 0x2, 0x70) +#define TAS256X_CLASSHHEADROOM TAS256X_REG(0x64, 0x7, 0x48) +#define TAS256X_CLASSHHYSTERESIS TAS256X_REG(0x64, 0x7, 0x4c) +#define TAS256X_CLASSHMTCT TAS256X_REG(0x64, 0x5, 0x4c) + +/*PCM Digital Volume Control*/ +#define TAS256X_DVC_PCM TAS256X_REG(0x0, 0x2, 0x0c) + +/*Limiter Controls*/ +#define TAS256X_LIM_MAX_ATN TAS256X_REG(0x0, 0x2, 0x14) +#define TAS256X_LIMB_TH_MAX TAS256X_REG(0x0, 0x2, 0x18) +#define TAS256X_LIMB_TH_MIN TAS256X_REG(0x0, 0x2, 0x1c) +#define TAS256X_LIMB_INF_PT TAS256X_REG(0x0, 0x2, 0x20) +#define TAS256X_LIMB_SLOPE TAS256X_REG(0x0, 0x2, 0x24) + +/*Brown Out Protection Control*/ +#define TAS256X_BOP_TH TAS256X_REG(0x0, 0x2, 0x28) +#define TAS256X_BOSD_TH TAS256X_REG(0x0, 0x2, 0x2c) + +#define TAS256X_BOOSTCONFIGURATION4 TAS256X_REG(0x0, 0x0, 0x40) +#define TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_MASK (0x3f << 0) +#define TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_SHIFT 0 + +#define TAS256X_LIMITERCONFIGURATION0 TAS256X_REG(0x0, 0x0, 0x12) +#define TAS256X_LIMITER_ENABLE_MASK (0x1 << 0) +#define TAS256X_LIMITER_ENABLE_SHIFT 0x0 +#define TAS256X_LIMITER_ATTACKRATE_MASK (0x7 << 1) +#define TAS256X_LIMITER_ATTACKRATE_SHIFT 0x1 +#define TAS256X_LIMITER_ATTACKSTEPSIZE_MASK (0x3 << 4) +#define TAS256X_LIMITER_ATTACKSTEPSIZE_SHIFT 0x4 + +#define TAS256X_LIMITERCONFIGURATION1 TAS256X_REG(0x0, 0x0, 0x13) +#define TAS256X_LIMITER_RELEASERATE_MASK (0x7 << 3) +#define TAS256X_LIMITER_RELEASERATE_SHIFT 0x3 +#define TAS256X_LIMITER_RELEASESTEPSIZE_MASK (0x3 << 6) +#define TAS256X_LIMITER_RELEASESTEPSIZE_SHIFT 0x6 + +#define TAS256X_BOPCONFIGURATION0 TAS256X_REG(0x0, 0x0, 0x14) +#define TAS256X_BOP_ENABLE_MASK (0x1 << 0) +#define TAS256X_BOP_ENABLE_SHIFT 0x0 +#define TAS256X_BOP_MUTE_MASK (0x1 << 1) +#define TAS256X_BOP_MUTE_SHIFT 0x1 +#define TAS256X_BOP_SHUTDOWN_ENABLE_MASK (0x1 << 4) +#define TAS256X_BOP_SHUTDOWN_ENABLE_SHIFT 0x4 + +#define TAS256X_BOPCONFIGURATION1 TAS256X_REG(0x0, 0x0, 0x15) +#define TAS256X_BOP_ATTACKRATE_MASK (0x7 << 5) +#define TAS256X_BOP_ATTACKRATE_SHIFT 0x5 +#define TAS256X_BOP_ATTACKSTEPSIZE_MASK (0x3 << 0x3) +#define TAS256X_BOP_ATTACKSTEPSIZE_SHIFT 0x3 +#define TAS256X_BOP_HOLDTIME_MASK (0x7 << 0x0) +#define TAS256X_BOP_HOLDTIME_SHIFT 0x0 + +/*Test Page*/ +#define TAS256X_TEST_PAGE_LOCK TAS256X_REG(0x00, 0xfd, 0x0d) +#define TAS256X_DAC_MODULATOR TAS256X_REG(0x00, 0xfd, 0x12) +#define TAS256X_DAC_MUTE TAS256X_REG(0x00, 0xfd, 0x47) +#define TAS256X_ICN_MODE TAS256X_REG(0x00, 0xfd, 0x64) +#define TAS256X_ICN_IMPROVE TAS256X_REG(0x00, 0xfd, 0x46) + +#define TAS256X_MISC_CLASSD TAS256X_REG(0x0, 0x01, 0x21) +#define TAS256X_CMP_HYST_MASK (0x1 << 3) +#define TAS256X_CMP_HYST_SHIFT (0x3) + +/* Book */ +#define TAS256X_BOOK TAS256X_REG(0x0, 0x0, 0x7F) +#define TAS256X_BOOK_BOOK70_MASK (0xff << 0) + +/* data format */ +#define TAS256X_DATAFORMAT_SHIFT 2 +#define TAS256X_DATAFORMAT_I2S 0x0 +#define TAS256X_DATAFORMAT_DSP 0x1 +#define TAS256X_DATAFORMAT_RIGHT_J 0x2 +#define TAS256X_DATAFORMAT_LEFT_J 0x3 + +#define TAS256X_DAI_FMT_MASK (0x7 << TAS256X_DATAFORMAT_SHIFT) + +#define TAS256X_POWER_ACTIVE 0 +#define TAS256X_POWER_MUTE 1 +#define TAS256X_POWER_SHUTDOWN 2 + +#define ERROR_NONE 0x0000000 +#define ERROR_PLL_ABSENT 0x0000001 +#define ERROR_DEVA_I2C_COMM 0x0000002 +#define ERROR_DEVB_I2C_COMM 0x0000004 +#define ERROR_CLOCK 0x0000008 +#define ERROR_YRAM_CRCCHK 0x0000010 +#define ERROR_OVER_CURRENT 0x0000020 +#define ERROR_DIE_OVERTEMP 0x0000040 +#define ERROR_OVER_VOLTAGE 0x0000080 +#define ERROR_UNDER_VOLTAGE 0x0000100 +#define ERROR_BROWNOUT 0x0000200 +#define ERROR_CLASSD_PWR 0x0000400 +#define ERROR_FAILSAFE 0x0000800 + +#define CHECK_PERIOD 5000 /* 5 second */ + +#define TAS256X_I2C_RETRY_COUNT 3 +#define ERROR_I2C_SUSPEND -1 +#define ERROR_I2C_FAILED -2 + +#define TAS256X_LEFT_SWITCH 0x10000001 +#define TAS256X_RIGHT_SWITCH 0x10000002 +#define RX_SCFG_LEFT 0x10000003 +#define RX_SCFG_RIGHT 0x10000004 + +#define RESTART_MAX 3 + +struct tas256x_priv; + +#ifdef CONFIG_TAS256X_BIN_PARSER +#define TAS256X_CONFIG_SIZE (10) +#define TAS256X_DEVICE_SUM (8) + +#define TAS256X_CMD_SING_W (0x1) +#define TAS256X_CMD_BURST (0x2) +#define TAS256X_CMD_DELAY (0x3) +#define TAS256X_CMD_FIELD_W (0x4) + +#define SMS_HTONS(a, b) ((((a) & 0x00FF) << 8) | ((b) & 0x00FF)) +#define SMS_HTONL(a, b, c, d) \ + ((((a) & 0x000000FF) << 24) | (((b) & 0x000000FF) << 16) | \ + (((c) & 0x000000FF) << 8) | ((d) & 0x000000FF)) + +enum tas256x_dsp_fw_state { + TAS256X_DSP_FW_NONE = 0, + TAS256X_DSP_FW_PENDING, + TAS256X_DSP_FW_FAIL, + TAS256X_DSP_FW_OK, +}; + +enum tas256x_bin_blk_type { + TAS256X_BIN_BLK_COEFF = 1, + TAS256X_BIN_BLK_POST_POWER_UP, + TAS256X_BIN_BLK_PRE_SHUTDOWN, + TAS256X_BIN_BLK_PRE_POWER_UP, + TAS256X_BIN_BLK_POST_SHUTDOWN +}; + +struct tas256x_fw_hdr { + unsigned int img_sz; + unsigned int checksum; + unsigned int binnary_version_num; + unsigned int drv_fw_version; + unsigned int timestamp; + unsigned char plat_type; + unsigned char dev_family; + unsigned char reserve; + unsigned char ndev; + unsigned char devs[TAS256X_DEVICE_SUM]; + unsigned int nconfig; + unsigned int config_size[TAS256X_CONFIG_SIZE]; +}; + +struct tas256x_block_data { + unsigned char dev_idx; + unsigned char block_type; + unsigned short yram_checksum; + unsigned int block_size; + unsigned int nSublocks; + unsigned char *regdata; +}; + +struct tas256x_config_info { + unsigned int nblocks; + unsigned int real_nblocks; + struct tas256x_block_data **blk_data; +}; + +void tas256x_select_cfg_blk(void *pContext, int conf_no, + unsigned char block_type); +#endif //CONFIG_TAS256X_BIN_PARSER + +struct tas256x_register { + int book; + int page; + int reg; +}; + +struct tas256x_dai_cfg { + unsigned int dai_fmt; + unsigned int tdm_delay; +}; + +/*struct tas256x_buf_cfg { + unsigned short bufSize; + unsigned char *buf; +};*/ + +enum channel { + channel_left = 0x01, + channel_right = 0x02, + channel_both = channel_left | channel_right +}; + +/* + * device ops function structure + */ +struct tas_device_ops { + int (*tas_init)( + struct tas256x_priv *p_tas256x, + int chn); /**< init typically for loading optimal settings */ + int (*tas_probe)(struct tas256x_priv *p_tas256x, + struct snd_soc_codec *codec, int chn); + //TODO: +}; + +struct tas_device { + int mChipID; + int mn_current_book; + int mn_current_page; + int mn_addr; + int mn_reset_gpio; + int mn_irq_gpio; + int mn_irq; + int spk_control; + int device_id; + int rx_mode; + int dvc_pcm; + int bst_vltg; + int bst_ilm; + int lim_switch; + int lim_max_attn; + int lim_thr_max; + int lim_thr_min; + int lim_att_rate; + int lim_rel_rate; + int lim_att_stp_size; + int lim_rel_stp_size; + int lim_max_thd; + int lim_min_thd; + int lim_infl_pt; + int lim_trk_slp; + int bop_enable; + int bop_thd; + int bop_att_rate; + int bop_att_stp_size; + int bop_hld_time; + int bop_mute; + int bosd_enable; + int bosd_thd; + int vbat_lpf; + int rx_cfg; + struct i2c_client *i2c; + struct regmap *regmap; + struct tas_device_ops dev_ops; +}; + +struct tas256x_priv { + struct device *dev; + struct i2c_client *client; + struct regmap *regmap; + struct mutex dev_lock; + struct delayed_work irq_work; + struct delayed_work init_work; + struct delayed_work dc_work; + struct hrtimer mtimer; + bool mb_power_up; + int mn_power_state; + int mn_asi_format; + bool mb_irq_eable; + int mn_sampling_rate; + int mn_frame_size; + int mn_ppg; + int mn_ch_size; + int mn_slot_width; + int mn_pcm_format; + int mn_iv_width; + int mn_vbat; + bool mb_mute; + bool dac_mute; + bool i2c_suspend; + int mn_channels; + struct tas_device **devs; + int icn_sw; + int (*read)(struct tas256x_priv *p_tas256x, enum channel chn, + unsigned int reg, unsigned int *pValue); + int (*write)(struct tas256x_priv *p_tas256x, enum channel chn, + unsigned int reg, unsigned int Value); + int (*bulk_read)(struct tas256x_priv *p_tas256x, enum channel chn, + unsigned int reg, unsigned char *p_data, + unsigned int len); + int (*bulk_write)(struct tas256x_priv *p_tas256x, enum channel chn, + unsigned int reg, unsigned char *p_data, + unsigned int len); + int (*update_bits)(struct tas256x_priv *p_tas256x, enum channel chn, + unsigned int reg, unsigned int mask, + unsigned int value); + void (*hw_reset)(struct tas256x_priv *p_tas256x); + void (*clear_irq)(struct tas256x_priv *p_tas256x); + void (*enable_irq)(struct tas256x_priv *p_tas256x, bool enable); + /* device is working, but system is suspended */ + int (*runtime_suspend)(struct tas256x_priv *p_tas256x); + int (*runtime_resume)(struct tas256x_priv *p_tas256x); + bool mb_runtime_suspend; + + unsigned int mn_err_code; + unsigned int mnRestart; +#ifdef CONFIG_TAS256X_CODEC + struct mutex codec_lock; +#endif + +#ifdef CONFIG_TAS256X_MISC + int mn_dbg_cmd; + int mn_current_reg; + //struct tas256x_buf_cfg misc_buf; + struct mutex file_lock; +#endif + + int iv_enable; +#ifdef CONFIG_TAS256X_BIN_PARSER + int fw_state; + struct tas256x_fw_hdr fw_hdr; + int ncfgs; + struct tas256x_config_info **cfg_info; +#endif +}; + +#endif /* __TAS256X_ */ diff --git a/techpack/audio/asoc/codecs/tas256x/tas25xx-algo.c b/techpack/audio/asoc/codecs/tas256x/tas25xx-algo.c new file mode 100644 index 000000000000..4da82e22090d --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/tas25xx-algo.c @@ -0,0 +1,995 @@ +#include +#include +#include +#include +#include +#include "tas25xx-calib.h" + +#define USE_VFS 1 +#define CODEC_CONTROL 1 +#define POISON_VAL 0xDEADDEAD +#define MAX_STRING (300) + +/*Master Control to Bypass the Smartamp TI CAPIv2 module*/ +static int s_tas_smartamp_bypass; +static int s_tas_smartamp_enable; +static int s_debug_enable; +static int s_calib_test_flag; +static int s_profile_id; +static struct mutex routing_lock; +static int32_t g_fmt; + +bool tas25xx_set_iv_bit_fomat(int iv_data_with, int vbat, int update_now) +{ + int32_t param_id; + int32_t ret; + bool success; + + if ((vbat == 1) && (iv_data_with == 12)) + g_fmt = IV_SENSE_FORMAT_12_BIT_WITH_8BIT_VBAT; + else if ((vbat == 1) && (iv_data_with == 8)) + g_fmt = IV_SENSE_FORMAT_8_BIT_WITH_8BIT_VBAT; + else + g_fmt = IV_SENSE_FORMAT_NO_VBAT; + + success = true; + + if (update_now) { + param_id = TAS_CALC_PARAM_IDX(TAS_SA_IV_VBAT_FMT, 1, CHANNEL0); + pr_info("TI-SmartPA: %s: Sending IV,Vbat format %d\n", __func__, + g_fmt); + ret = tas25xx_smartamp_algo_ctrl((u8 *)&g_fmt, param_id, + TAS_SET_PARAM, + sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) { + pr_err("TI-SmartPA: %s: Failed to set config\n", + __func__); + success = false; + } + } + + return success; +} + +#ifdef CONFIG_SET_RE_IN_KERNEL +static int get_calibrated_re_tcalib(uint32_t *rdc_fix, uint32_t *tv_fix, + int channel_count) +{ + struct file *file = NULL; + char calib_data[MAX_STRING] = { 0 }; + char filepath[128] = SMARTAMP_SPEAKER_CALIBDATA_FILE; + mm_segment_t fs; + int ret = 0; + static uint32_t s_rdc_fix[2] = { POISON_VAL, POISON_VAL }; + static uint32_t s_tv_fix = POISON_VAL; + +#if USE_VFS + loff_t pos = 0; +#else + int size; + int fd; +#endif + + if ((s_rdc_fix[0] == POISON_VAL) && (s_rdc_fix[1] == POISON_VAL)) { + fs = get_fs(); + set_fs(get_ds()); +#if USE_VFS + file = filp_open(filepath, O_RDONLY, 0); + if (!IS_ERR(file)) { + vfs_read(file, calib_data, MAX_STRING - 1, &pos); + + if (channel_count == 1) { + if (sscanf(calib_data, "%d;%d;", s_rdc_fix, + &s_tv_fix) != 2) { + pr_err("TI-SmartPA: %s: file %s read error\n", + __func__, filepath); + ret = -EIO; + } + } else if (channel_count == 2) { + if (sscanf(calib_data, "%d;%d;%d;", + &s_rdc_fix[0], &s_rdc_fix[1], + &s_tv_fix) != 3) { + pr_err("TI-SmartPA: %s: file %s read error\n", + __func__, filepath); + ret = -EIO; + } + } + filp_close(file, NULL); + + } else { + pr_err("TI-SmartPA: %s: file %s open failed %p \n ", + __func__, filepath, file); + ret = -EIO; + } +#else + fd = sys_open(filepath, O_RDONLY, 0); + if (fd > 0) { + memset(calib_data, 0, sizeof(calib_data)); + size = sys_read(fd, calib_data, MAX_STRING - 1); + sys_close(fd); + + pr_info("TI-SmartPA: %s: *** sys_read size = %d\n", + __func__, size); + + if (channel_count == 1) { + if (sscanf(calib_data, "%d;%d;", &rdc_fix[0], + tv_fix) != 2) { + pr_err("TI-SmartPA: %s: file %s read error\n", + __func__, filepath); + ret = -EIO; + } + } else if (channel_count == 2) { + if (sscanf(calib_data, "%d;%d;%d;", &rdc_fix[0], + &rdc_fix[1], tv_fix) != 3) { + pr_err("TI-SmartPA: %s: file %s read error\n", + __func__, filepath); + ret = -EIO; + } + } + } else { + pr_err("TI-SmartPA: %s: file %s open failed %p \n ", + __func__, filepath, file); + ret = -EIO; + } +#endif + set_fs(fs); + } + + if (ret == 0) { + if (rdc_fix) { + rdc_fix[0] = (uint32_t)s_rdc_fix[0]; + if (channel_count == 2) + rdc_fix[1] = (uint32_t)s_rdc_fix[1]; + } + if (tv_fix) + *tv_fix = (uint32_t)s_tv_fix; + } + return ret; +} +#endif //CONFIG_SET_RE_IN_KERNEL + +static int tas25xx_smartamp_get_set(u8 *user_data, uint32_t param_id, + uint8_t get_set, uint32_t length, + uint32_t module_id) +{ + int ret = 0; + + switch (get_set) { + case TAS_SET_PARAM: + if (s_tas_smartamp_bypass) { + pr_err("TI-SmartPA: %s: SmartAmp is bypassed no control set\n", + __func__); + goto fail_cmd; + } + ret = afe_tas_smartamp_set_calib_data(module_id, param_id, + length, user_data); + break; + + case TAS_GET_PARAM: + if (!s_tas_smartamp_bypass) { + memset(user_data, 0, length); + ret = afe_tas_smartamp_get_calib_data( + module_id, param_id, length, user_data); + } + break; + + default: + goto fail_cmd; + } + +fail_cmd: + return ret; +} + +/*Wrapper arround set/get parameter, + *all set/get commands pass through this wrapper + */ +int tas25xx_smartamp_algo_ctrl(u8 *user_data, uint32_t param_id, + uint8_t get_set, uint32_t length, + uint32_t module_id) +{ + int ret = 0; + + mutex_lock(&routing_lock); + ret = tas25xx_smartamp_get_set(user_data, param_id, get_set, length, + module_id); + mutex_unlock(&routing_lock); + return ret; +} +EXPORT_SYMBOL(tas25xx_smartamp_algo_ctrl); + +/*Control-1: Set Profile*/ +static const char *profile_index_text[] = { "NONE", TAS_ALGO_PROFILE_LIST, + "CALIB" }; +static const struct soc_enum profile_index_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(profile_index_text), profile_index_text), +}; + +static int tas25xx_set_profile(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret; + int profile_id = pUcontrol->value.integer.value[0]; + int param_id = 0; + int max_number_of_profiles = + sizeof(profile_index_text) / sizeof(profile_index_text[0]); + + if ((profile_id >= max_number_of_profiles) || (profile_id < 0)) + return -EINVAL; + + s_profile_id = profile_id; + + pr_info("TI-SmartPA: %s: Setting profile %s \n", __func__, + profile_index_text[profile_id]); + if (profile_id) + profile_id -= 1; + else + return 0; + + param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_PROFILE, 1, CHANNEL0); + pr_info("TI-SmartPA: %s: Sending set profile\n", __func__); + ret = tas25xx_smartamp_algo_ctrl((u8 *)&profile_id, param_id, + TAS_SET_PARAM, sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) + pr_err("TI-SmartPA: %s: Failed to set config\n", __func__); + return ret; +} + +static int tas25xx_get_profile(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret; + int profile_id = 0; + int param_id = 0; + int max_number_of_profiles = + sizeof(profile_index_text) / sizeof(profile_index_text[0]); + + if (s_tas_smartamp_enable && s_debug_enable) { + param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_PROFILE, 1, CHANNEL0); + ret = tas25xx_smartamp_algo_ctrl((u8 *)&profile_id, param_id, + TAS_GET_PARAM, + sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) { + pr_err("TI-SmartPA: %s: Failed to get profile\n", + __func__); + profile_id = 0; + } else { + profile_id += 1; + } + } else { + profile_id = s_profile_id; + } + + pUcontrol->value.integer.value[0] = profile_id; + + if ((profile_id < max_number_of_profiles) && (profile_id > -1)) + pr_info("TI-SmartPA: %s: getting profile %s\n", __func__, + profile_index_text[profile_id]); + + return 0; +} + +/*Control-2: Set Calibrated Rdc*/ +static int tas25xx_set_Re_common(int re_value_in, int channel) +{ + int ret; + int param_id = 0; + int re_value = re_value_in; + + param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_RE, 1, channel); + ret = tas25xx_smartamp_algo_ctrl((u8 *)&re_value, param_id, + TAS_SET_PARAM, sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + + return ret; +} + +static int tas25xx_set_Re_left(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int re_value = pUcontrol->value.integer.value[0]; + + pr_info("TI-SmartPA: %s: Setting Re %d", __func__, re_value); + return tas25xx_set_Re_common(re_value, CHANNEL0); +} + +static int tas25xx_dummy_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = 0; + + pUcontrol->value.integer.value[0] = 0; + return ret; +} + +static int tas25xx_dummy_set(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + return 0; +} + +/*Control-3: Calibration and Test(F0,Q,Tv) Controls*/ +static const char *tas25xx_calib_test_text[] = { "NONE", "CALIB_START", + "CALIB_STOP", "TEST_START", + "TEST_STOP" }; + +static const struct soc_enum tas25xx_calib_test_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas25xx_calib_test_text), + tas25xx_calib_test_text), +}; + +static int tas25xx_calib_test_set_common(int calib_command, int channel) +{ + int ret = 0; + int param_id = 0; + int data = 1; + + switch (calib_command) { + case CALIB_START: + pr_info("TI-SmartPA: %s: CALIB_START", __func__); + s_calib_test_flag = 1; + param_id = TAS_CALC_PARAM_IDX(TAS_SA_CALIB_INIT, 1, channel); + break; + + case CALIB_STOP: + pr_info("TI-SmartPA: %s: CALIB_STOP", __func__); + s_calib_test_flag = 0; + param_id = TAS_CALC_PARAM_IDX(TAS_SA_CALIB_DEINIT, 1, channel); + break; + + case TEST_START: + s_calib_test_flag = 1; + break; + + case TEST_STOP: + s_calib_test_flag = 0; + break; + + default: + pr_info("TI-SmartPA: %s: no impl calib_command %d\n", __func__, + calib_command); + ret = -EINVAL; + break; + } + + if (param_id) { + ret = tas25xx_smartamp_algo_ctrl((u8 *)&data, param_id, + TAS_SET_PARAM, + sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) { + s_calib_test_flag = 0; + pr_err("TI-SmartPA: %s: Failed to set calib/test, ret=%d\n", + __func__, ret); + } + } + + return ret; +} + +static int tas25xx_calib_test_set(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = 0; + int user_data = pUcontrol->value.integer.value[0]; + + ret = tas25xx_calib_test_set_common(user_data, CHANNEL0); + + if (ret == 0) { +#ifdef CONFIG_TAS25XX_ALGO_STEREO + ret = tas25xx_calib_test_set_common(user_data, CHANNEL1); +#endif + } + + return ret; +} + +/*Control-4: Get Re*/ +//returns -ve error or +ve re value, 0 if not called +static int tas25xx_get_re_common(int channel) +{ + int ret = 0; + int re_value = 0; + int param_id = 0; + + pr_info("TI-SmartPA: %s, channel=%d\n", __func__, channel); + + if (s_tas_smartamp_enable && (s_calib_test_flag || s_debug_enable)) { + param_id = TAS_CALC_PARAM_IDX(TAS_SA_GET_RE, 1, channel); + ret = tas25xx_smartamp_algo_ctrl((u8 *)&re_value, param_id, + TAS_GET_PARAM, + sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) + pr_err("TI-SmartPA: %s: Failed to get Re\n", __func__); + else + ret = re_value; + } + + return ret; +} + +static int tas25xx_get_re_left(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = tas25xx_get_re_common(CHANNEL0); + if (ret >= 0) { + pUcontrol->value.integer.value[0] = ret; + ret = 0; + pr_info("TI-SmartPA: %s: Getting Re %d\n", __func__, ret); + } + + return ret; +} + +/*Control-5: Get F0*/ +static int tas25xx_get_f0_common(int channel) +{ + int f0_value = 0; + int param_id = 0; + int ret = 0; + + pr_info("TI-SmartPA: %s, channel=%d\n", __func__, channel); + + if (s_tas_smartamp_enable && (s_calib_test_flag || s_debug_enable)) { + param_id = TAS_CALC_PARAM_IDX(TAS_SA_GET_F0, 1, channel); + ret = tas25xx_smartamp_algo_ctrl((u8 *)&f0_value, param_id, + TAS_GET_PARAM, + sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) + pr_err("TI-SmartPA: %s: Failed to get F0\n", __func__); + else + ret = f0_value; + } + + return ret; +} + +static int tas25xx_get_f0_left(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = tas25xx_get_f0_common(CHANNEL0); + + if (ret >= 0) { + pUcontrol->value.integer.value[0] = ret; + pr_info("TI-SmartPA: %s: Getting F0 val=%d\n", __func__, ret); + ret = 0; + } + + return ret; +} + +/*Control-6: Get Q*/ +static int tas25xx_get_q_common(int channel) +{ + int ret = 0; + int q_value = 0; + int param_id = 0; + + pr_info("TI-SmartPA: %s, channel=%d", __func__, channel); + + if (s_tas_smartamp_enable && (s_calib_test_flag || s_debug_enable)) { + param_id = TAS_CALC_PARAM_IDX(TAS_SA_GET_Q, 1, channel); + ret = tas25xx_smartamp_algo_ctrl((u8 *)&q_value, param_id, + TAS_GET_PARAM, + sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) + pr_err("TI-SmartPA: %s: Failed to get F0\n", __func__); + else + ret = q_value; + } + + return ret; +} + +static int tas25xx_get_q_left(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = tas25xx_get_q_common(CHANNEL0); + + if (ret >= 0) { + pUcontrol->value.integer.value[0] = ret; + pr_info("TI-SmartPA: %s: Getting Q %d\n", __func__, ret); + ret = 0; + } + + return ret; +} + +/*Control-7: Get Tv*/ +static int tas25xx_get_tv_common(int channel) +{ + int ret = 0; + int tv_value = 0; + int param_id = 0; + + pr_info("TI-SmartPA: %s, channel=%d", __func__, channel); + + if (s_tas_smartamp_enable && (s_calib_test_flag || s_debug_enable)) { + param_id = TAS_CALC_PARAM_IDX(TAS_SA_GET_TV, 1, channel); + ret = tas25xx_smartamp_algo_ctrl((u8 *)&tv_value, param_id, + TAS_GET_PARAM, + sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) + pr_err("TI-SmartPA: %s: Failed to get Tv\n", __func__); + else + ret = tv_value; + } + + return ret; +} + +static int tas25xx_get_tv_left(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = tas25xx_get_tv_common(CHANNEL0); + + if (ret >= 0) { + pUcontrol->value.integer.value[0] = ret; + pr_info("TI-SmartPA: %s: Getting Tv %d\n", __func__, ret); + ret = 0; + } + + return ret; +} + +/*Control-8: Smartamp Enable*/ +static const char *tas25xx_smartamp_enable_text[] = { "DISABLE", "ENABLE" }; + +static const struct soc_enum tas25xx_smartamp_enable_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas25xx_smartamp_enable_text), + tas25xx_smartamp_enable_text), +}; + +static int tas25xx_smartamp_enable_set(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = 0; + int param_id = 0; + int user_data = pUcontrol->value.integer.value[0]; +#ifdef CONFIG_SET_RE_IN_KERNEL + uint32_t calibration_data[3]; +#endif + +#ifdef CONFIG_TAS25XX_ALGO_STEREO + int number_of_ch = 2; +#else + int number_of_ch = 1; +#endif + + if (s_tas_smartamp_bypass) { + pr_info("TI-SmartPA: bypass enabled, not enabling\n"); + return 0; + } + + pr_info("TI-SmartPA: %s: case %d, number_of_ch=%d\n", __func__, + user_data, number_of_ch); + + s_tas_smartamp_enable = user_data; + if (s_tas_smartamp_enable == 0) { + s_profile_id = 0; + s_calib_test_flag = 0; + pr_info("TI-SmartPA: %s: Disable called\n", __func__); + return 0; + } + + pr_info("TI-SmartPA: %s: Setting the feedback module info for TAS\n", + __func__); + ret = afe_spk_prot_feed_back_cfg(TAS_TX_PORT, TAS_RX_PORT, 1, 0, 1); + if (ret) + pr_err("TI-SmartPA: %s: FB Path Info failed ignoring ret = 0x%x\n", + __func__, ret); + + pr_info("TI-SmartPA: %s: Sending TX Enable\n", __func__); + param_id = CAPI_V2_TAS_TX_ENABLE; + ret = tas25xx_smartamp_algo_ctrl((u8 *)&user_data, param_id, + TAS_SET_PARAM, sizeof(uint32_t), + AFE_SMARTAMP_MODULE_TX); + if (ret) { + pr_err("TI-SmartPA: %s: TX Enable Failed ret = 0x%x\n", + __func__, ret); + goto fail_cmd; + } + + user_data = 0xB1B1B1B1; + pr_info("TI-SmartPA: %s: Sending TX Config\n", __func__); + param_id = CAPI_V2_TAS_TX_CFG; + ret = tas25xx_smartamp_algo_ctrl((u8 *)&user_data, param_id, + TAS_SET_PARAM, sizeof(uint32_t), + AFE_SMARTAMP_MODULE_TX); + if (ret < 0) { + pr_err("TI-SmartPA: %s: Failed to set config\n", __func__); + goto fail_cmd; + } + + user_data = 1; + pr_info("TI-SmartPA: %s: Sending RX Enable\n", __func__); + param_id = CAPI_V2_TAS_RX_ENABLE; + ret = tas25xx_smartamp_algo_ctrl((u8 *)&user_data, param_id, + TAS_SET_PARAM, sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret) { + pr_err("TI-SmartPA: %s: RX Enable Failed ret = 0x%x\n", + __func__, ret); + goto fail_cmd; + } + + user_data = 0xB1B1B1B1; + pr_info("TI-SmartPA: %s: Sending RX Config\n", __func__); + param_id = CAPI_V2_TAS_RX_CFG; + ret = tas25xx_smartamp_algo_ctrl((u8 *)&user_data, param_id, + TAS_SET_PARAM, sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) { + pr_err("TI-SmartPA: %s: Failed to set config\n", __func__); + goto fail_cmd; + } + + param_id = TAS_CALC_PARAM_IDX(TAS_SA_IV_VBAT_FMT, 1, CHANNEL0); + pr_info("TI-SmartPA: %s: Sending IV,Vbat format %d\n", __func__, g_fmt); + ret = tas25xx_smartamp_algo_ctrl((u8 *)&g_fmt, param_id, TAS_SET_PARAM, + sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) { + pr_err("TI-SmartPA: %s: Failed to set config\n", __func__); + goto fail_cmd; + } + + s_tas_smartamp_enable = true; + +#ifdef CONFIG_SET_RE_IN_KERNEL + if (number_of_ch == 2) + ret = get_calibrated_re_tcalib( + calibration_data, &calibration_data[2], number_of_ch); + else + ret = get_calibrated_re_tcalib( + calibration_data, &calibration_data[1], number_of_ch); + + if (ret) { + pr_err("[Smartamp:%s] unable to get the calibration data = 0x%x\n", + __func__, ret); + //TODO: Ignore the calibration read error + ret = 0; + } else { + int32_t t_cal; + if (number_of_ch == 2) { + t_cal = calibration_data[2]; + pr_info("[Smartamp:%s] setting re %d,%d and tcal %d\n", + __func__, calibration_data[0], + calibration_data[1], calibration_data[2]); + } else { + t_cal = calibration_data[1]; + pr_info("[Smartamp:%s] setting re %d and tcal %d\n", + __func__, calibration_data[0], + calibration_data[1]); + } + + param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_TCAL, 1, CHANNEL0); + ret = tas25xx_smartamp_algo_ctrl((u8 *)&t_cal, param_id, + TAS_SET_PARAM, + sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) { + pr_err("[Smartamp:%s] Failed to set Tcal\n", __func__); + goto fail_cmd; + } + + param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_RE, 1, CHANNEL0); + ret = tas25xx_smartamp_algo_ctrl((u8 *)(&(calibration_data[0])), + param_id, TAS_SET_PARAM, + sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) { + pr_err("TI-SmartPA: %s: Failed to set Re\n", __func__); + goto fail_cmd; + } + + if (number_of_ch == 2) { + param_id = + TAS_CALC_PARAM_IDX(TAS_SA_SET_RE, 1, CHANNEL1); + ret = tas25xx_smartamp_algo_ctrl( + (u8 *)&(calibration_data[1]), param_id, + TAS_SET_PARAM, sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) { + pr_err("TI-SmartPA: %s: Failed to set Re\n", + __func__); + goto fail_cmd; + } + } + } +#endif //CONFIG_SET_RE_IN_KERNEL + +fail_cmd: + return ret; +} + +static int tas25xx_smartamp_enable_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = 0; + int user_data = s_tas_smartamp_enable; + + pUcontrol->value.integer.value[0] = user_data; + pr_info("TI-SmartPA: %s: case %d(0=DISABLE, 1=ENABLE)\n", __func__, + user_data); + return ret; +} + +/*Control-9: Smartamp Bypass */ +static const char *tas25xx_smartamp_bypass_text[] = { "FALSE", "TRUE" }; + +static const struct soc_enum tas25xx_smartamp_bypass_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas25xx_smartamp_bypass_text), + tas25xx_smartamp_bypass_text), +}; + +static int tas25xx_smartamp_bypass_set(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = 0; + int user_data = pUcontrol->value.integer.value[0]; + + if (s_tas_smartamp_enable) { + pr_debug( + "TI-SmartPA: %s: cannot update while smartamp enabled\n", + __func__); + return -EINVAL; + } + + s_tas_smartamp_bypass = user_data; + pr_info("TI-SmartPA: %s: case %d(FALSE=0,TRUE=1)\n", __func__, + user_data); + return ret; +} + +static int tas25xx_smartamp_bypass_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = 0; + + pUcontrol->value.integer.value[0] = s_tas_smartamp_bypass; + pr_info("TI-SmartPA: %s: case %d\n", __func__, s_tas_smartamp_bypass); + return ret; +} + +/*Control-9: Smartamp Bypass */ +static const char *tas25xx_smartamp_debug_enable_text[] = { "FALSE", "TRUE" }; + +static const struct soc_enum tas25xx_smartamp_debug_enable_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas25xx_smartamp_debug_enable_text), + tas25xx_smartamp_debug_enable_text), +}; + +static int +tas25xx_smartamp_debug_enable_set(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = 0; + int user_data = pUcontrol->value.integer.value[0]; + + s_debug_enable = user_data; + pr_info("TI-SmartPA: %s: case %d(FALSE=0,TRUE=1)\n", __func__, + user_data); + return ret; +} + +static int +tas25xx_smartamp_debug_enable_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = 0; + + pUcontrol->value.integer.value[0] = s_debug_enable; + pr_info("TI-SmartPA: %s: case %d\n", __func__, s_debug_enable); + return ret; +} + +static int tas25xx_set_spk_id(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = 0; + int speaker_id = pUcontrol->value.integer.value[0]; + int param_id = 0; + + pr_info("TI-SmartPA: %s: spk-id set %d\n", __func__, speaker_id); + param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_SPKID, 1, CHANNEL0); + ret = tas25xx_smartamp_algo_ctrl((u8 *)&speaker_id, param_id, + TAS_SET_PARAM, sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) + pr_err("TI-SmartPA: %s: Failed to set spk id\n", __func__); + + return ret; +} + +static int tas25xx_set_t_calib(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = 0; + int calib_temp = pUcontrol->value.integer.value[0]; + int param_id = 0; + + pr_info("TI-SmartPA: %s: tcalib set %d\n", __func__, calib_temp); + if (s_tas_smartamp_enable) { + param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_TCAL, 1, CHANNEL0); + ret = tas25xx_smartamp_algo_ctrl((u8 *)&calib_temp, param_id, + TAS_SET_PARAM, + sizeof(uint32_t), + AFE_SMARTAMP_MODULE_RX); + if (ret < 0) + pr_err("TI-SmartPA: %s: Failed to set spk id\n", + __func__); + } + + return ret; +} + +#ifdef CONFIG_TAS25XX_ALGO_STEREO +static int tas25xx_set_Re_right(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int re_value = pUcontrol->value.integer.value[0]; + + pr_info("TI-SmartPA: %s: Setting Re %d\n", __func__, re_value); + return tas25xx_set_Re_common(re_value, CHANNEL1); +} + +static int tas25xx_get_re_right(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret; + + ret = tas25xx_get_re_common(CHANNEL1); + if (ret >= 0) { + pUcontrol->value.integer.value[0] = ret; + ret = 0; + pr_info("TI-SmartPA: %s: Getting Re value=%d\n", __func__, ret); + } + + return ret; +} + +static int tas25xx_get_f0_right(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = tas25xx_get_f0_common(CHANNEL1); + + if (ret >= 0) { + pUcontrol->value.integer.value[0] = ret; + pr_info("TI-SmartPA: %s: Getting F0 valu=%d\n", __func__, ret); + ret = 0; + } + + return ret; +} + +static int tas25xx_get_q_right(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = tas25xx_get_q_common(CHANNEL1); + + if (ret >= 0) { + pUcontrol->value.integer.value[0] = ret; + pr_info("TI-SmartPA: %s: Getting Q val=%d\n", __func__, ret); + ret = 0; + } + + return ret; +} + +static int tas25xx_get_tv_right(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pUcontrol) +{ + int ret = tas25xx_get_tv_common(CHANNEL1); + + if (ret >= 0) { + pUcontrol->value.integer.value[0] = ret; + pr_info("TI-SmartPA: %s: Getting Tv %d\n", __func__, ret); + ret = 0; + } + + return ret; +} +#endif + +static const struct snd_kcontrol_new smartamp_tas25xx_mixer_controls[] = { + SOC_ENUM_EXT("TAS25XX_DEBUG_ENABLE", + tas25xx_smartamp_debug_enable_enum[0], + tas25xx_smartamp_debug_enable_get, + tas25xx_smartamp_debug_enable_set), + SOC_ENUM_EXT("TAS25XX_ALGO_PROFILE", profile_index_enum[0], + tas25xx_get_profile, tas25xx_set_profile), + SOC_ENUM_EXT("TAS25XX_ALGO_CALIB_TEST", tas25xx_calib_test_enum[0], + tas25xx_dummy_get, tas25xx_calib_test_set), + SOC_SINGLE_EXT("TAS25XX_SET_SPK_ID", SND_SOC_NOPM, 0, 0x7fffffff, 0, + tas25xx_dummy_get, tas25xx_set_spk_id), + SOC_SINGLE_EXT("TAS25XX_SET_T_CALIB", SND_SOC_NOPM, 0, 100, 0, + tas25xx_dummy_get, tas25xx_set_t_calib), + + //left + SOC_SINGLE_EXT("TAS25XX_SET_RE_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0, + tas25xx_dummy_get, tas25xx_set_Re_left), + SOC_SINGLE_EXT("TAS25XX_GET_RE_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0, + tas25xx_get_re_left, tas25xx_dummy_set), + SOC_SINGLE_EXT("TAS25XX_GET_F0_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0, + tas25xx_get_f0_left, tas25xx_dummy_set), + SOC_SINGLE_EXT("TAS25XX_GET_Q_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0, + tas25xx_get_q_left, tas25xx_dummy_set), + SOC_SINGLE_EXT("TAS25XX_GET_TV_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0, + tas25xx_get_tv_left, tas25xx_dummy_set), + +//Right +#ifdef CONFIG_TAS25XX_ALGO_STEREO + SOC_SINGLE_EXT("TAS25XX_SET_RE_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0, + tas25xx_dummy_get, tas25xx_set_Re_right), + SOC_SINGLE_EXT("TAS25XX_GET_RE_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0, + tas25xx_get_re_right, tas25xx_dummy_set), + SOC_SINGLE_EXT("TAS25XX_GET_F0_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0, + tas25xx_get_f0_right, tas25xx_dummy_set), + SOC_SINGLE_EXT("TAS25XX_GET_Q_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0, + tas25xx_get_q_right, tas25xx_dummy_set), + SOC_SINGLE_EXT("TAS25XX_GET_TV_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0, + tas25xx_get_tv_right, tas25xx_dummy_set), +#endif + SOC_ENUM_EXT("TAS25XX_SMARTPA_ENABLE", tas25xx_smartamp_enable_enum[0], + tas25xx_smartamp_enable_get, tas25xx_smartamp_enable_set), + + SOC_ENUM_EXT("TAS25XX_ALGO_BYPASS", tas25xx_smartamp_bypass_enum[0], + tas25xx_smartamp_bypass_get, tas25xx_smartamp_bypass_set), +}; + +#if CODEC_CONTROL +void tas_smartamp_add_algo_controls(struct snd_soc_codec *codec) +{ + pr_err("TI-SmartPA: %s: Adding smartamp controls\n", __func__); + + /*Initialize all to global variables to 0s*/ + s_tas_smartamp_bypass = 0; + s_tas_smartamp_enable = 0; + s_debug_enable = 0; + s_calib_test_flag = 0; + s_profile_id = 0; + g_fmt = 0; + + mutex_init(&routing_lock); + snd_soc_add_codec_controls(codec, smartamp_tas25xx_mixer_controls, + ARRAY_SIZE(smartamp_tas25xx_mixer_controls)); + tas_calib_init(); +} +EXPORT_SYMBOL(tas_smartamp_add_algo_controls); +#else +void tas_smartamp_add_algo_controls_for_platform( + struct snd_soc_platform *platform) +{ + pr_err("TI-SmartPA: %s: Adding smartamp controls\n", __func__); + + /*Initialize all to global variables to 0s*/ + s_tas_smartamp_bypass = 0; + s_tas_smartamp_enable = 0; + s_debug_enable = 0; + s_calib_test_flag = 0; + s_profile_id = 0; + g_fmt = 0; + + mutex_init(&routing_lock); + snd_soc_add_platform_controls( + platform, smartamp_tas25xx_mixer_controls, + ARRAY_SIZE(smartamp_tas25xx_mixer_controls)); + tas_calib_init(); +} +EXPORT_SYMBOL(tas_smartamp_add_algo_controls_for_platform); +#endif + +void tas_smartamp_remove_algo_controls(struct snd_soc_codec *codec) +{ + (void)codec; + tas_calib_exit(); +} +EXPORT_SYMBOL(tas_smartamp_remove_algo_controls); diff --git a/techpack/audio/asoc/codecs/tas256x/tas25xx-calib.c b/techpack/audio/asoc/codecs/tas256x/tas25xx-calib.c new file mode 100644 index 000000000000..862025d74c0b --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/tas25xx-calib.c @@ -0,0 +1,202 @@ +/* +** ============================================================================= +** Copyright (c) 2017 Texas Instruments Inc. +** Copyright (C) 2021 XiaoMi, Inc. +** +** 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; version 2. +** +** 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. +** +** File: +** tas25xx-calib.c +** +** Description: +** misc driver for interfacing for Texas Instruments TAS25xx algorithm +** +** ============================================================================= +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Holds the Packet data required for processing */ +struct tas_dsp_pkt { + u8 slave_id; + u8 book; + u8 page; + u8 offset; + u8 data[TAS_PAYLOAD_SIZE * 4]; +}; + +static int smartamp_params_ctrl(uint8_t *input, u8 dir, u8 count) +{ + u32 length = count / 4; + u32 paramid = 0; + u32 index; + int ret = 0; + int special_index = 0; + struct tas_dsp_pkt *ppacket; + + ppacket = (struct tas_dsp_pkt *)kmalloc(sizeof(struct tas_dsp_pkt), + GFP_KERNEL); + if (!ppacket) { + pr_err("TI-SmartPA: %s: kmalloc failed!", __func__); + return -ENOMEM; + } + + memset(ppacket, 0, sizeof(struct tas_dsp_pkt)); + ret = copy_from_user(ppacket, input, sizeof(struct tas_dsp_pkt)); + if (ret) { + pr_err("TI-SmartPA: %s: Error copying from user\n", __func__); + kfree(ppacket); + return -EFAULT; + } + + index = (ppacket->page - 1) * 30 + (ppacket->offset - 8) / 4; + special_index = TAS_SA_IS_SPL_IDX(index); + pr_info("TI-SmartPA: %s: index = %d", __func__, index); + if (special_index == 0) { + if ((index < 0 || index > MAX_DSP_PARAM_INDEX)) { + pr_err("TI-SmartPA: %s: invalid index !\n", __func__); + kfree(ppacket); + return -EINVAL; + } + } + pr_info("TI-SmartPA: %s: Valid Index. special = %s\n", __func__, + special_index ? "Yes" : "No"); + + /* speakers are differentiated by slave ids */ + if (ppacket->slave_id == SLAVE1) { + paramid = (paramid | (index) | (length << 16) | (1 << 24)); + pr_err("TI-SmartPA: %s: Rcvd Slave id for slave 1, %x\n", + __func__, ppacket->slave_id); + } else if (ppacket->slave_id == SLAVE2) { + paramid = (paramid | (index) | (length << 16) | (2 << 24)); + pr_err("TI-SmartPA: %s: Rcvd Slave id for slave 2, %x\n", + __func__, ppacket->slave_id); + } else { + pr_err("TI-SmartPA: %s: Wrong slaveid = %x\n", __func__, + ppacket->slave_id); + } + + /* + * Note: In any case calculated paramid should not match with + */ + if ((paramid == CAPI_V2_TAS_RX_ENABLE) || + (paramid == CAPI_V2_TAS_TX_ENABLE) || + (paramid == CAPI_V2_TAS_RX_CFG) || + (paramid == CAPI_V2_TAS_TX_CFG)) { + pr_err("TI-SmartPA: %s: %s Slave 0x%x params failed, paramid mismatch\n", + __func__, dir == TAS_GET_PARAM ? "get" : "set", + ppacket->slave_id); + kfree(ppacket); + return -EINVAL; + } + + ret = tas25xx_smartamp_algo_ctrl(ppacket->data, paramid, dir, + length * 4, AFE_SMARTAMP_MODULE_RX); + if (ret) + pr_err("TI-SmartPA: %s: %s Slave 0x%x params failed from afe, ret=%x\n", + __func__, dir == TAS_GET_PARAM ? "get" : "set", + ppacket->slave_id, ret); + else + pr_info("TI-SmartPA: %s: Algo control returned %d\n", __func__, + ret); + + if (dir == TAS_GET_PARAM) { + ret = copy_to_user(input, ppacket, sizeof(struct tas_dsp_pkt)); + if (ret) { + pr_err("TI-SmartPA: %s: Error copying to user after DSP", + __func__); + ret = -EFAULT; + } + } + + kfree(ppacket); + return ret; +} + +static int tas_calib_open(struct inode *inode, struct file *fd) +{ + return 0; +} + +static ssize_t tas_calib_write(struct file *file, const char __user *buffer, + size_t count, loff_t *offp) +{ + int rc = 0; + + rc = smartamp_params_ctrl((uint8_t *)buffer, TAS_SET_PARAM, count); + return rc; +} + +static ssize_t tas_calib_read(struct file *file, char __user *buffer, + size_t count, loff_t *ptr) +{ + int rc; + + rc = smartamp_params_ctrl((uint8_t *)buffer, TAS_GET_PARAM, count); + if (rc < 0) + count = rc; + return count; +} + +static long tas_calib_ioctl(struct file *filp, uint cmd, ulong arg) +{ + return 0; +} + +static int tas_calib_release(struct inode *inode, struct file *fd) +{ + return 0; +} + +const struct file_operations tas_calib_fops = { + .owner = THIS_MODULE, + .open = tas_calib_open, + .write = tas_calib_write, + .read = tas_calib_read, + .release = tas_calib_release, + .unlocked_ioctl = tas_calib_ioctl, +}; + +static struct miscdevice tas_calib_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "tas_calib", + .fops = &tas_calib_fops, +}; + +int tas_calib_init(void) +{ + int rc; + + pr_err("TI-SmartPA: %s", __func__); + rc = misc_register(&tas_calib_misc); + if (rc) + pr_err("TI-SmartPA: %s: register calib misc failed\n", + __func__); + return rc; +} + +void tas_calib_exit(void) +{ + misc_deregister(&tas_calib_misc); +} + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("tas2560 Misc driver"); +MODULE_LICENSE("GPL v2"); diff --git a/techpack/audio/asoc/codecs/tas256x/tas25xx-calib.h b/techpack/audio/asoc/codecs/tas256x/tas25xx-calib.h new file mode 100644 index 000000000000..8f8d24519d98 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/tas25xx-calib.h @@ -0,0 +1,29 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** Copyright (C) 2021 XiaoMi, Inc. +** +** 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; version 2. +** +** 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. +** +** File: +** tas25xx-calib.h +** +** Description: +** header file for tas25xx-calib.c +** +** ============================================================================= +*/ + +#ifndef _TAS25XX_CALIB_H_ +#define _TAS25XX_CALIB_H_ + +int tas_calib_init(void); +void tas_calib_exit(void); + +#endif /* _TAS25XX_CALIB_H */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/Android.mk b/techpack/audio/asoc/codecs/tfa98xx/Android.mk new file mode 100755 index 000000000000..f7bdf5f3a10f --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/Android.mk @@ -0,0 +1,55 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,msmnile),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m +endif + +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE)),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + #AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=tfa98xx_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_tfa98xx.ko +LOCAL_MODULE_KBUILD_NAME := tfa98xx_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/techpack/audio/asoc/codecs/tfa98xx/Kbuild b/techpack/audio/asoc/codecs/tfa98xx/Kbuild new file mode 100755 index 000000000000..d0ffa5848306 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/Kbuild @@ -0,0 +1,120 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + + + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_SM8150), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif + ifeq ($(CONFIG_ARCH_SM6150), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif + + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) +TFA_INC := -I$(AUDIO_ROOT)/asoc/codecs/tfa98xx/inc + +# for TFA9874 Amplifer +ifdef CONFIG_SND_SOC_TFA9874 + TFA98XX_OBJS += src/tfa98xx.o + TFA98XX_OBJS += src/tfa_container.o + TFA98XX_OBJS += src/tfa_dsp.o + TFA98XX_OBJS += src/tfa_init.o + #TFA98XX_OBJS += src/tfa_debug.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) \ + $(TFA_INC) + +EXTRA_CFLAGS += $(INCS) + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ \ + -DDEBUG + + +ifeq (y,$(filter y,$(CONFIG_MACH_XIAOMI_RAPHAEL))) + CDEFINES += -DTFA_NON_DSP_SOLUTION +endif + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_TFA9874) += tfa98xx_dlkm.o +tfa98xx_dlkm-y := $(TFA98XX_OBJS) diff --git a/techpack/audio/asoc/codecs/tfa98xx/Kconfig b/techpack/audio/asoc/codecs/tfa98xx/Kconfig new file mode 100644 index 000000000000..82115774f64e --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/Kconfig @@ -0,0 +1,5 @@ +config SND_SOC_TFA9874 + tristate "NXP TFA9874A audio amplifier" + help + Say Y here if you want to add support for the NXP TFA9874A audio + amplifier. diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/config.h b/techpack/audio/asoc/codecs/tfa98xx/inc/config.h new file mode 100644 index 000000000000..d057bc3394fb --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/config.h @@ -0,0 +1,44 @@ +/* + * Copyright 2014-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + Linux kernel specific definitions used by code shared with + Linux/Windows user space. +*/ + +#ifndef __CONFIG_LINUX_KERNEL_INC__ +#define __CONFIG_LINUX_KERNEL_INC__ + +#include +#include +#include +#include +#include + +#define _ASSERT(e) +#define PRINT_ASSERT(e) \ + if ((e)) \ + printk(KERN_ERR "PrintAssert:%s (%s:%d) error code:%d\n", \ + __FUNCTION__, __FILE__, __LINE__, e) + +#if defined(CONFIG_TRACING) && defined(DEBUG) +#define tfa98xx_trace_printk(...) trace_printk(__VA_ARGS__) +#else +#define tfa98xx_trace_printk(...) +#endif + +#endif /* __CONFIG_LINUX_KERNEL_INC__ */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/dbgprint.h b/techpack/audio/asoc/codecs/tfa98xx/inc/dbgprint.h new file mode 100644 index 000000000000..1abaf5fecb7f --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/dbgprint.h @@ -0,0 +1,200 @@ +/* + * Copyright 2014-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _DBGPRINT_H +#define _DBGPRINT_H + +/* Debugging macro's. */ +#ifndef DEBUG +#define DEBUG +#endif + +#ifndef ASSERT +//#define ASSERT +#endif +//TODO wwwim +#ifndef _ASSERT +#define _ASSERT(e) +#endif + +#ifndef PREFIX +#define PREFIX "tfa98xx: " +#define DRIVER_NAME "tfa98xx" +#endif + +#ifdef __KERNEL__ + +#ifdef DEBUG +#define _DEBUG(level, fmt, va...) \ + do { \ + if (unlikely(debug >= (level))) \ + printk(KERN_INFO PREFIX "%s:%d: " fmt, __func__, \ + __LINE__, ##va); \ + } while (0) + +#else +#define _DEBUG(level, fmt, va...) \ + do { \ + } while (0) +#endif + +#define MSG(fmt, va...) \ + printk(KERN_INFO PREFIX "%s:%d: " fmt, __func__, __LINE__, ##va) +#define _ERRORMSG(fmt, va...) \ + printk(KERN_ERR PREFIX "ERROR %s:%d: " fmt, __func__, __LINE__, ##va) + +#define DEBUG0(x...) MSG(x) +#define DEBUG1(x...) _DEBUG(1, x) +#define DEBUG2(x...) _DEBUG(2, x) +#define DEBUG3(x...) _DEBUG(3, x) +#define ERRORMSG(x...) _ERRORMSG(x) +#define PRINT(x...) printk(x) +#define PRINT_ERROR(x...) printk(KERN_INFO PREFIX " **ERROR** " x) +#define PRINT_ASSERT(e) \ + if ((e)) \ + printk(KERN_ERR "PrintAssert:%s (%s:%d) error code:%d\n", \ + __FUNCTION__, __FILE__, __LINE__, e) + +#define PRINT_ENTRY DEBUG2("+[%s]\n", __func__) +#define PRINT_EXIT DEBUG2("-[%s]\n", __func__) + +#ifdef ASSERT +#define assert(cond, action) \ + do { \ + if (unlikely(!(cond))) { \ + DEBUG0("Assert: %s\n", #cond); \ + action; \ + } \ + } while (0) +#else +#define assert(cond, action) \ + do { \ + } while (0) +#endif + +#else /* __KERNEL__ */ +#if defined(WIN32) || defined(_X64) +#include +/* user mode */ +#ifdef DEBUG +#define _DEBUGMSG(level, fmt, ...) \ + printf(PREFIX "%s:%d: " fmt, __FUNCTION__, __LINE__, __VA_ARGS__); +#else +#define _DEBUGMSG(level, fmt, ...) \ + do { \ + } while (0) +#endif + +#define _ERRORMSG(fmt, ...) \ + printf(PREFIX "%s:%s:%d: " fmt, __FILE__, __FUNCTION__, __LINE__, \ + __VA_ARGS__) + +#define DEBUG0(...) MSG(__VA_ARGS__) +#define DEBUG1(...) _DEBUGMSG(1, __VA_ARGS__) +#define DEBUG2(...) _DEBUGMSG(2, __VA_ARGS__) +#define DEBUG3(...) _DEBUGMSG(3, __VA_ARGS__) +#define ERRORMSG(fmt, ...) _ERRORMSG(fmt, __VA_ARGS__) +#define PRINT(...) printf(__VA_ARGS__) +/* +# define PRINT(...) { FILE *stream; \ + if((stream = freopen("nxp_tfa.txt", "ab+", stdout)) == NULL) exit(-1); \ + printf(__VA_ARGS__); \ + freopen( "CON", "ab+", stdout ); \ + } +*/ +#define PRINT_ERROR(...) fprintf(stderr, __VA_ARGS__) +#define PRINT_FILE(file, ...) fprintf(file, __VA_ARGS__) +#define PRINT_ASSERT(e) \ + if ((e)) \ + fprintf(stderr, "PrintAssert:%s (%s:%d) error code:%d\n", \ + __FUNCTION__, __FILE__, __LINE__, e) +//# define PRINT_ASSERT(e) if ((e)) fprintf(stderr, "PrintAssert:%s (%s:%d) %s\n",__FUNCTION__,__FILE__,__LINE__, Tfa98xx_GetErrorString(e)) + +#elif defined(__CODE_RED) +#include "app_global.h" +#ifdef DEBUG +#define _DEBUG(level, fmt, va...) TB_TRACE_INF(TbTracePfx2("tfa", TB_FUNC, va)) +//printf(PREFIX "%s:%d: "fmt,__func__,__LINE__,##va); +#else +#define _DEBUG(level, fmt, va...) \ + do { \ + } while (0) +#endif + +#define MSG(fmt, ...) TB_TRACE_INF(TbTracePfx2("tfa", TB_FUNC, __VA_ARGS__)) +//printf(PREFIX "%s:%s:%d: "fmt,__FILE__,__func__,__LINE__,##va) +//TB_TRACE_INF(TbTracePfx2(APP_PFX,TB_FUNC,"path=%s, chan=%u, muted=%s, vol=%d\n", +// path->isRecording ? "recording" : "playback", +// i, +// channelVol.currentMuteValue ? "YES" : "NO", +// channelVol.currentVolumeValue +// )); +//# define _ERRORMSG(fmt,va...) TB_TRACE_INF(TbTracePfx2("tfa",TB_FUNC,va)) +#define ERRORMSG(...) TB_TRACE_INF(TbTracePfx2("tfa", TB_FUNC, __VA_ARGS__)) +//fprintf(stderr, PREFIX "ERROR %s:%s:%d: "fmt,__FILE__,__func__,__LINE__, ##va) + +#define DEBUG0(x...) MSG(x) +#define DEBUG1(x...) _DEBUG(1, x) +#define DEBUG2(x...) _DEBUG(2, x) +#define DEBUG3(x...) _DEBUG(3, x) +//# define ERRORMSG(x...) _ERRORMSG(x) +#define PRINT(x...) TB_TRACE_INF(TbTracePfx2("tfa", TB_FUNC, x)) +//printf(x) +#define PRINT_ERROR(x...) TB_TRACE_INF(TbTracePfx2("tfa", TB_FUNC, x)) +//fprintf(stderr,__VA_ARGS__) +#define PRINT_FILE(file, x...) TB_TRACE_INF(TbTracePfx2("tfa", TB_FUNC, x)) +//fprintf(file,__VA_ARGS__) +#define PRINT_ASSERT(e) +//TB_TRACE_INF(TbTracePfx2("tfa",TB_FUNC,Tfa98xx_GetErrorString(e))) +//if ((e)) fprintf(stderr, "PrintAssert:%s (%s:%d) %s\n",__FUNCTION__,__FILE__,__LINE__, Tfa98xx_GetErrorString(e)) +#else +#include +/* user mode */ +#ifdef DEBUG +#define _DEBUG(level, fmt, va...) \ + printf(PREFIX "%s:%d: " fmt, __func__, __LINE__, ##va); +#else +#define _DEBUG(level, fmt, va...) \ + do { \ + } while (0) +#endif + +#define MSG(fmt, va...) \ + printf(PREFIX "%s:%s:%d: " fmt, __FILE__, __func__, __LINE__, ##va) +#define _ERRORMSG(fmt, va...) \ + fprintf(stderr, PREFIX "ERROR %s:%s:%d: " fmt, __FILE__, __func__, \ + __LINE__, ##va) + +#define DEBUG0(x...) MSG(x) +#define DEBUG1(x...) _DEBUG(1, x) +#define DEBUG2(x...) _DEBUG(2, x) +#define DEBUG3(x...) _DEBUG(3, x) +#define ERRORMSG(x...) _ERRORMSG(x) +#define PRINT(x...) printf(x) +#define PRINT_ERROR(...) fprintf(stderr, __VA_ARGS__) +#define PRINT_FILE(file, ...) fprintf(file, __VA_ARGS__) +#define PRINT_ASSERT(e) \ + if ((e)) \ + fprintf(stderr, "PrintAssert:%s (%s:%d) error code:%d\n", \ + __FUNCTION__, __FILE__, __LINE__, e) +//# define PRINT_ASSERT(e) if ((e)) fprintf(stderr, "PrintAssert:%s (%s:%d) %s\n",__FUNCTION__,__FILE__,__LINE__, Tfa98xx_GetErrorString(e)) + +#endif /* WIN32 */ + +#endif /* user */ + +#endif /* _DBGPRINT_H --------------- */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/spk-id.h b/techpack/audio/asoc/codecs/tfa98xx/inc/spk-id.h new file mode 100644 index 000000000000..8303b93c3498 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/spk-id.h @@ -0,0 +1,33 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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 __SPK_ID_H_ +#define __SPK_ID_H_ + +#include +#include + +#define PIN_PULL_DOWN 0 +#define PIN_PULL_UP 1 +#define PIN_FLOAT 2 + +#define VENDOR_ID_NONE 0 +#define VENDOR_ID_AAC 1 +#define VENDOR_ID_SSI 2 +#define VENDOR_ID_GOER 3 + +#define VENDOR_ID_UNKNOWN 4 + +extern int spk_id_get_pin_3state(struct device_node *np); + +#endif diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa.h new file mode 100644 index 000000000000..9c1762dba314 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa.h @@ -0,0 +1,57 @@ +/* + * Copyright 2015-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TFA_H_ +#define TFA_H_ + +/* set the limit for the container file length */ +#define TFA_MAX_CNT_LENGTH (256 * 1024) + +extern struct tfa_device **devs; + +/** + * tfa error return codes + */ +enum tfa_error { + tfa_error_ok, /**< no error */ + tfa_error_device, /**< no response from device */ + tfa_error_bad_param, /**< parameter no accepted */ + tfa_error_noclock, /**< required clock not present */ + tfa_error_timeout, /**< a timeout occurred */ + tfa_error_dsp, /**< a DSP error was returned */ + tfa_error_container, /**< no or wrong container file */ + tfa_error_max /**< impossible value, max enum */ +}; + +enum Tfa98xx_Error tfa_write_filters(struct tfa_device *tfa, int prof_idx); + +struct tfa_device **tfa_devs_create(int count); +void tfa_devs_destroy(int count); + +struct tfa_device **tfa_get_device_struct(void); + +/*[nxp34663] CR: support 16bit/24bit/32bit audio data. begin*/ +#ifdef __KERNEL__ +int tfa_plop_noise_interrupt(struct tfa_device *tfa, int profile, int vstep, + u8 pcm_format); +#else +int tfa_plop_noise_interrupt(struct tfa_device *tfa, int profile, int vstep); +#endif +/*[nxp34663] CR: support 16bit/24bit/32bit audio data. end*/ +void tfa_lp_mode_interrupt(struct tfa_device *tfa); + +#endif /* TFA_H_ */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa1_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa1_tfafieldnames.h new file mode 100644 index 000000000000..53a7db921df7 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa1_tfafieldnames.h @@ -0,0 +1,1705 @@ +/** Filename: Tfa1_TfaFieldnames.h + * This file was generated automatically on 03/20/2015 at 01:55:46 PM. + * Source file: TFA9897N1B_I2C_list_URT_Source_v34.xls + */ +#define TFA9897_I2CVERSION 34 +typedef enum nxpTfa1BfEnumList { + TFA1_BF_VDDS = + 0x0000, /*!< Power-on-reset flag */ + TFA1_BF_PLLS = + 0x0010, /*!< PLL lock */ + TFA1_BF_OTDS = + 0x0020, /*!< Over Temperature Protection alarm */ + TFA1_BF_OVDS = + 0x0030, /*!< Over Voltage Protection alarm */ + TFA1_BF_UVDS = + 0x0040, /*!< Under Voltage Protection alarm */ + TFA1_BF_OCDS = + 0x0050, /*!< Over Current Protection alarm */ + TFA1_BF_CLKS = + 0x0060, /*!< Clocks stable flag */ + TFA1_BF_CLIPS = + 0x0070, /*!< Amplifier clipping */ + TFA1_BF_MTPB = + 0x0080, /*!< MTP busy */ + TFA1_BF_NOCLK = + 0x0090, /*!< Flag lost clock from clock generation unit */ + TFA1_BF_SPKS = + 0x00a0, /*!< Speaker error flag */ + TFA1_BF_ACS = + 0x00b0, /*!< Cold Start flag */ + TFA1_BF_SWS = + 0x00c0, /*!< Flag Engage */ + TFA1_BF_WDS = + 0x00d0, /*!< Flag watchdog reset */ + TFA1_BF_AMPS = + 0x00e0, /*!< Amplifier is enabled by manager */ + TFA1_BF_AREFS = + 0x00f0, /*!< References are enabled by manager */ + TFA1_BF_BATS = + 0x0109, /*!< Battery voltage readout; 0 .. 5.5 [V] */ + TFA1_BF_TEMPS = + 0x0208, /*!< Temperature readout from the temperature sensor */ + TFA1_BF_REV = + 0x030b, /*!< Device type number is B97 */ + TFA1_BF_RCV = + 0x0420, /*!< Enable Receiver Mode */ + TFA1_BF_CHS12 = + 0x0431, /*!< Channel Selection TDM input for Coolflux */ + TFA1_BF_INPLVL = + 0x0450, /*!< Input level selection control */ + TFA1_BF_CHSA = + 0x0461, /*!< Input selection for amplifier */ + TFA1_BF_I2SDOE = + 0x04b0, /*!< Enable data output */ + TFA1_BF_AUDFS = + 0x04c3, /*!< Audio sample rate setting */ + TFA1_BF_BSSCR = + 0x0501, /*!< Protection Attack Time */ + TFA1_BF_BSST = + 0x0523, /*!< ProtectionThreshold */ + TFA1_BF_BSSRL = + 0x0561, /*!< Protection Maximum Reduction */ + TFA1_BF_BSSRR = + 0x0582, /*!< Battery Protection Release Time */ + TFA1_BF_BSSHY = + 0x05b1, /*!< Battery Protection Hysteresis */ + TFA1_BF_BSSR = + 0x05e0, /*!< battery voltage for I2C read out only */ + TFA1_BF_BSSBY = + 0x05f0, /*!< bypass clipper battery protection */ + TFA1_BF_DPSA = + 0x0600, /*!< Enable dynamic powerstage activation */ + TFA1_BF_CFSM = + 0x0650, /*!< Soft mute in CoolFlux */ + TFA1_BF_BSSS = + 0x0670, /*!< BatSenseSteepness */ + TFA1_BF_VOL = + 0x0687, /*!< volume control (in CoolFlux) */ + TFA1_BF_DCVO = + 0x0702, /*!< Boost Voltage */ + TFA1_BF_DCMCC = + 0x0733, /*!< Max boost coil current - step of 175 mA */ + TFA1_BF_DCIE = + 0x07a0, /*!< Adaptive boost mode */ + TFA1_BF_DCSR = + 0x07b0, /*!< Soft RampUp/Down mode for DCDC controller */ + TFA1_BF_DCPAVG = + 0x07c0, /*!< ctrl_peak2avg for analog part of DCDC */ + TFA1_BF_TROS = + 0x0800, /*!< Select external temperature also the ext_temp will be put on the temp read out */ + TFA1_BF_EXTTS = + 0x0818, /*!< external temperature setting to be given by host */ + TFA1_BF_PWDN = + 0x0900, /*!< Device Mode */ + TFA1_BF_I2CR = + 0x0910, /*!< I2C Reset */ + TFA1_BF_CFE = + 0x0920, /*!< Enable CoolFlux */ + TFA1_BF_AMPE = + 0x0930, /*!< Enable Amplifier */ + TFA1_BF_DCA = + 0x0940, /*!< EnableBoost */ + TFA1_BF_SBSL = + 0x0950, /*!< Coolflux configured */ + TFA1_BF_AMPC = + 0x0960, /*!< Selection on how Amplifier is enabled */ + TFA1_BF_DCDIS = + 0x0970, /*!< DCDC not connected */ + TFA1_BF_PSDR = + 0x0980, /*!< IDDQ test amplifier */ + TFA1_BF_DCCV = + 0x0991, /*!< Coil Value */ + TFA1_BF_CCFD = + 0x09b0, /*!< Selection CoolFlux Clock */ + TFA1_BF_INTPAD = + 0x09c1, /*!< INT pad configuration control */ + TFA1_BF_IPLL = + 0x09e0, /*!< PLL input reference clock selection */ + TFA1_BF_MTPK = + 0x0b07, /*!< 5Ah, 90d To access KEY1_Protected registers (Default for engineering) */ + TFA1_BF_CVFDLY = + 0x0c25, /*!< Fractional delay adjustment between current and voltage sense */ + TFA1_BF_TDMPRF = + 0x1011, /*!< TDM_usecase */ + TFA1_BF_TDMEN = + 0x1030, /*!< TDM interface control */ + TFA1_BF_TDMCKINV = + 0x1040, /*!< TDM clock inversion */ + TFA1_BF_TDMFSLN = + 0x1053, /*!< TDM FS length */ + TFA1_BF_TDMFSPOL = + 0x1090, /*!< TDM FS polarity */ + TFA1_BF_TDMSAMSZ = + 0x10a4, /*!< TDM Sample Size for all tdm sinks/sources */ + TFA1_BF_TDMSLOTS = + 0x1103, /*!< Number of slots */ + TFA1_BF_TDMSLLN = + 0x1144, /*!< Slot length */ + TFA1_BF_TDMBRMG = + 0x1194, /*!< Bits remaining */ + TFA1_BF_TDMDDEL = + 0x11e0, /*!< Data delay */ + TFA1_BF_TDMDADJ = + 0x11f0, /*!< Data adjustment */ + TFA1_BF_TDMTXFRM = + 0x1201, /*!< TXDATA format */ + TFA1_BF_TDMUUS0 = + 0x1221, /*!< TXDATA format unused slot sd0 */ + TFA1_BF_TDMUUS1 = + 0x1241, /*!< TXDATA format unused slot sd1 */ + TFA1_BF_TDMSI0EN = + 0x1270, /*!< TDM sink0 enable */ + TFA1_BF_TDMSI1EN = + 0x1280, /*!< TDM sink1 enable */ + TFA1_BF_TDMSI2EN = + 0x1290, /*!< TDM sink2 enable */ + TFA1_BF_TDMSO0EN = + 0x12a0, /*!< TDM source0 enable */ + TFA1_BF_TDMSO1EN = + 0x12b0, /*!< TDM source1 enable */ + TFA1_BF_TDMSO2EN = + 0x12c0, /*!< TDM source2 enable */ + TFA1_BF_TDMSI0IO = + 0x12d0, /*!< tdm_sink0_io */ + TFA1_BF_TDMSI1IO = + 0x12e0, /*!< tdm_sink1_io */ + TFA1_BF_TDMSI2IO = + 0x12f0, /*!< tdm_sink2_io */ + TFA1_BF_TDMSO0IO = + 0x1300, /*!< tdm_source0_io */ + TFA1_BF_TDMSO1IO = + 0x1310, /*!< tdm_source1_io */ + TFA1_BF_TDMSO2IO = + 0x1320, /*!< tdm_source2_io */ + TFA1_BF_TDMSI0SL = + 0x1333, /*!< sink0_slot [GAIN IN] */ + TFA1_BF_TDMSI1SL = + 0x1373, /*!< sink1_slot [CH1 IN] */ + TFA1_BF_TDMSI2SL = + 0x13b3, /*!< sink2_slot [CH2 IN] */ + TFA1_BF_TDMSO0SL = + 0x1403, /*!< source0_slot [GAIN OUT] */ + TFA1_BF_TDMSO1SL = + 0x1443, /*!< source1_slot [Voltage Sense] */ + TFA1_BF_TDMSO2SL = + 0x1483, /*!< source2_slot [Current Sense] */ + TFA1_BF_NBCK = + 0x14c3, /*!< NBCK */ + TFA1_BF_INTOVDDS = + 0x2000, /*!< flag_por_int_out */ + TFA1_BF_INTOPLLS = + 0x2010, /*!< flag_pll_lock_int_out */ + TFA1_BF_INTOOTDS = + 0x2020, /*!< flag_otpok_int_out */ + TFA1_BF_INTOOVDS = + 0x2030, /*!< flag_ovpok_int_out */ + TFA1_BF_INTOUVDS = + 0x2040, /*!< flag_uvpok_int_out */ + TFA1_BF_INTOOCDS = + 0x2050, /*!< flag_ocp_alarm_int_out */ + TFA1_BF_INTOCLKS = + 0x2060, /*!< flag_clocks_stable_int_out */ + TFA1_BF_INTOCLIPS = + 0x2070, /*!< flag_clip_int_out */ + TFA1_BF_INTOMTPB = + 0x2080, /*!< mtp_busy_int_out */ + TFA1_BF_INTONOCLK = + 0x2090, /*!< flag_lost_clk_int_out */ + TFA1_BF_INTOSPKS = + 0x20a0, /*!< flag_cf_speakererror_int_out */ + TFA1_BF_INTOACS = + 0x20b0, /*!< flag_cold_started_int_out */ + TFA1_BF_INTOSWS = + 0x20c0, /*!< flag_engage_int_out */ + TFA1_BF_INTOWDS = + 0x20d0, /*!< flag_watchdog_reset_int_out */ + TFA1_BF_INTOAMPS = + 0x20e0, /*!< flag_enbl_amp_int_out */ + TFA1_BF_INTOAREFS = + 0x20f0, /*!< flag_enbl_ref_int_out */ + TFA1_BF_INTOACK = + 0x2201, /*!< Interrupt status register output - Corresponding flag */ + TFA1_BF_INTIVDDS = + 0x2300, /*!< flag_por_int_in */ + TFA1_BF_INTIPLLS = + 0x2310, /*!< flag_pll_lock_int_in */ + TFA1_BF_INTIOTDS = + 0x2320, /*!< flag_otpok_int_in */ + TFA1_BF_INTIOVDS = + 0x2330, /*!< flag_ovpok_int_in */ + TFA1_BF_INTIUVDS = + 0x2340, /*!< flag_uvpok_int_in */ + TFA1_BF_INTIOCDS = + 0x2350, /*!< flag_ocp_alarm_int_in */ + TFA1_BF_INTICLKS = + 0x2360, /*!< flag_clocks_stable_int_in */ + TFA1_BF_INTICLIPS = + 0x2370, /*!< flag_clip_int_in */ + TFA1_BF_INTIMTPB = + 0x2380, /*!< mtp_busy_int_in */ + TFA1_BF_INTINOCLK = + 0x2390, /*!< flag_lost_clk_int_in */ + TFA1_BF_INTISPKS = + 0x23a0, /*!< flag_cf_speakererror_int_in */ + TFA1_BF_INTIACS = + 0x23b0, /*!< flag_cold_started_int_in */ + TFA1_BF_INTISWS = + 0x23c0, /*!< flag_engage_int_in */ + TFA1_BF_INTIWDS = + 0x23d0, /*!< flag_watchdog_reset_int_in */ + TFA1_BF_INTIAMPS = + 0x23e0, /*!< flag_enbl_amp_int_in */ + TFA1_BF_INTIAREFS = + 0x23f0, /*!< flag_enbl_ref_int_in */ + TFA1_BF_INTIACK = + 0x2501, /*!< Interrupt register input */ + TFA1_BF_INTENVDDS = + 0x2600, /*!< flag_por_int_enable */ + TFA1_BF_INTENPLLS = + 0x2610, /*!< flag_pll_lock_int_enable */ + TFA1_BF_INTENOTDS = + 0x2620, /*!< flag_otpok_int_enable */ + TFA1_BF_INTENOVDS = + 0x2630, /*!< flag_ovpok_int_enable */ + TFA1_BF_INTENUVDS = + 0x2640, /*!< flag_uvpok_int_enable */ + TFA1_BF_INTENOCDS = + 0x2650, /*!< flag_ocp_alarm_int_enable */ + TFA1_BF_INTENCLKS = + 0x2660, /*!< flag_clocks_stable_int_enable */ + TFA1_BF_INTENCLIPS = + 0x2670, /*!< flag_clip_int_enable */ + TFA1_BF_INTENMTPB = + 0x2680, /*!< mtp_busy_int_enable */ + TFA1_BF_INTENNOCLK = + 0x2690, /*!< flag_lost_clk_int_enable */ + TFA1_BF_INTENSPKS = + 0x26a0, /*!< flag_cf_speakererror_int_enable */ + TFA1_BF_INTENACS = + 0x26b0, /*!< flag_cold_started_int_enable */ + TFA1_BF_INTENSWS = + 0x26c0, /*!< flag_engage_int_enable */ + TFA1_BF_INTENWDS = + 0x26d0, /*!< flag_watchdog_reset_int_enable */ + TFA1_BF_INTENAMPS = + 0x26e0, /*!< flag_enbl_amp_int_enable */ + TFA1_BF_INTENAREFS = + 0x26f0, /*!< flag_enbl_ref_int_enable */ + TFA1_BF_INTENACK = + 0x2801, /*!< Interrupt enable register */ + TFA1_BF_INTPOLVDDS = + 0x2900, /*!< flag_por_int_pol */ + TFA1_BF_INTPOLPLLS = + 0x2910, /*!< flag_pll_lock_int_pol */ + TFA1_BF_INTPOLOTDS = + 0x2920, /*!< flag_otpok_int_pol */ + TFA1_BF_INTPOLOVDS = + 0x2930, /*!< flag_ovpok_int_pol */ + TFA1_BF_INTPOLUVDS = + 0x2940, /*!< flag_uvpok_int_pol */ + TFA1_BF_INTPOLOCDS = + 0x2950, /*!< flag_ocp_alarm_int_pol */ + TFA1_BF_INTPOLCLKS = + 0x2960, /*!< flag_clocks_stable_int_pol */ + TFA1_BF_INTPOLCLIPS = + 0x2970, /*!< flag_clip_int_pol */ + TFA1_BF_INTPOLMTPB = + 0x2980, /*!< mtp_busy_int_pol */ + TFA1_BF_INTPOLNOCLK = + 0x2990, /*!< flag_lost_clk_int_pol */ + TFA1_BF_INTPOLSPKS = + 0x29a0, /*!< flag_cf_speakererror_int_pol */ + TFA1_BF_INTPOLACS = + 0x29b0, /*!< flag_cold_started_int_pol */ + TFA1_BF_INTPOLSWS = + 0x29c0, /*!< flag_engage_int_pol */ + TFA1_BF_INTPOLWDS = + 0x29d0, /*!< flag_watchdog_reset_int_pol */ + TFA1_BF_INTPOLAMPS = + 0x29e0, /*!< flag_enbl_amp_int_pol */ + TFA1_BF_INTPOLAREFS = + 0x29f0, /*!< flag_enbl_ref_int_pol */ + TFA1_BF_INTPOLACK = + 0x2b01, /*!< Interrupt status flags polarity register */ + TFA1_BF_CLIP = + 0x4900, /*!< Bypass clip control */ + TFA1_BF_CIMTP = + 0x62b0, /*!< start copying all the data from i2cregs_mtp to mtp [Key 2 protected] */ + TFA1_BF_RST = + 0x7000, /*!< Reset CoolFlux DSP */ + TFA1_BF_DMEM = + 0x7011, /*!< Target memory for access */ + TFA1_BF_AIF = + 0x7030, /*!< Autoincrement-flag for memory-address */ + TFA1_BF_CFINT = + 0x7040, /*!< Interrupt CoolFlux DSP */ + TFA1_BF_REQ = + 0x7087, /*!< request for access (8 channels) */ + TFA1_BF_REQCMD = + 0x7080, /*!< Firmware event request rpc command */ + TFA1_BF_REQRST = + 0x7090, /*!< Firmware event request reset restart */ + TFA1_BF_REQMIPS = + 0x70a0, /*!< Firmware event request short on mips */ + TFA1_BF_REQMUTED = + 0x70b0, /*!< Firmware event request mute sequence ready */ + TFA1_BF_REQVOL = + 0x70c0, /*!< Firmware event request volume ready */ + TFA1_BF_REQDMG = + 0x70d0, /*!< Firmware event request speaker damage detected */ + TFA1_BF_REQCAL = + 0x70e0, /*!< Firmware event request calibration completed */ + TFA1_BF_REQRSV = + 0x70f0, /*!< Firmware event request reserved */ + TFA1_BF_MADD = + 0x710f, /*!< memory-address to be accessed */ + TFA1_BF_MEMA = + 0x720f, /*!< activate memory access (24- or 32-bits data is written/read to/from memory */ + TFA1_BF_ERR = + 0x7307, /*!< Coolflux error flags */ + TFA1_BF_ACK = + 0x7387, /*!< acknowledge of requests (8 channels) */ + TFA1_BF_MTPOTC = + 0x8000, /*!< Calibration schedule (key2 protected) */ + TFA1_BF_MTPEX = + 0x8010, /*!< (key2 protected) */ +} nxpTfa1BfEnumList_t; +#define TFA1_NAMETABLE \ + static tfaBfName_t Tfa1DatasheetNames[] = { \ + { 0x0, \ + "VDDS" }, /* Power-on-reset flag , */ \ + { 0x10, \ + "PLLS" }, /* PLL lock , */ \ + { 0x20, \ + "OTDS" }, /* Over Temperature Protection alarm , */ \ + { 0x30, \ + "OVDS" }, /* Over Voltage Protection alarm , */ \ + { 0x40, \ + "UVDS" }, /* Under Voltage Protection alarm , */ \ + { 0x50, \ + "OCDS" }, /* Over Current Protection alarm , */ \ + { 0x60, \ + "CLKS" }, /* Clocks stable flag , */ \ + { 0x70, \ + "CLIPS" }, /* Amplifier clipping , */ \ + { 0x80, \ + "MTPB" }, /* MTP busy , */ \ + { 0x90, \ + "NOCLK" }, /* Flag lost clock from clock generation unit , */ \ + { 0xa0, \ + "SPKS" }, /* Speaker error flag , */ \ + { 0xb0, \ + "ACS" }, /* Cold Start flag , */ \ + { 0xc0, \ + "SWS" }, /* Flag Engage , */ \ + { 0xd0, \ + "WDS" }, /* Flag watchdog reset , */ \ + { 0xe0, \ + "AMPS" }, /* Amplifier is enabled by manager , */ \ + { 0xf0, \ + "AREFS" }, /* References are enabled by manager , */ \ + { 0x109, \ + "BATS" }, /* Battery voltage readout; 0 .. 5.5 [V] , */ \ + { 0x208, \ + "TEMPS" }, /* Temperature readout from the temperature sensor , */ \ + { 0x30b, \ + "REV" }, /* Device type number is B97 , */ \ + { 0x420, \ + "RCV" }, /* Enable Receiver Mode , */ \ + { 0x431, \ + "CHS12" }, /* Channel Selection TDM input for Coolflux , */ \ + { 0x450, \ + "INPLVL" }, /* Input level selection control , */ \ + { 0x461, \ + "CHSA" }, /* Input selection for amplifier , */ \ + { 0x4b0, \ + "I2SDOE" }, /* Enable data output , */ \ + { 0x4c3, \ + "AUDFS" }, /* Audio sample rate setting , */ \ + { 0x501, \ + "SSCR" }, /* Protection Attack Time , */ \ + { 0x523, \ + "SST" }, /* ProtectionThreshold , */ \ + { 0x561, \ + "SSRL" }, /* Protection Maximum Reduction , */ \ + { 0x582, \ + "SSRR" }, /* Battery Protection Release Time , */ \ + { 0x5b1, \ + "SSHY" }, /* Battery Protection Hysteresis , */ \ + { 0x5e0, \ + "SSR" }, /* battery voltage for I2C read out only , */ \ + { 0x5f0, \ + "SSBY" }, /* bypass clipper battery protection , */ \ + { 0x600, \ + "DPSA" }, /* Enable dynamic powerstage activation , */ \ + { 0x650, \ + "CFSM" }, /* Soft mute in CoolFlux , */ \ + { 0x670, \ + "SSS" }, /* BatSenseSteepness , */ \ + { 0x687, \ + "VOL" }, /* volume control (in CoolFlux) , */ \ + { 0x702, \ + "DCVO" }, /* Boost Voltage , */ \ + { 0x733, \ + "DCMCC" }, /* Max boost coil current - step of 175 mA , */ \ + { 0x7a0, \ + "DCIE" }, /* Adaptive boost mode , */ \ + { 0x7b0, \ + "DCSR" }, /* Soft RampUp/Down mode for DCDC controller , */ \ + { 0x7c0, \ + "DCPAVG" }, /* ctrl_peak2avg for analog part of DCDC , */ \ + { 0x800, \ + "TROS" }, /* Select external temperature also the ext_temp will be put on the temp read out , */ \ + { 0x818, \ + "EXTTS" }, /* external temperature setting to be given by host , */ \ + { 0x900, \ + "PWDN" }, /* Device Mode , */ \ + { 0x910, \ + "I2CR" }, /* I2C Reset , */ \ + { 0x920, \ + "CFE" }, /* Enable CoolFlux , */ \ + { 0x930, \ + "AMPE" }, /* Enable Amplifier , */ \ + { 0x940, \ + "DCA" }, /* EnableBoost , */ \ + { 0x950, \ + "SBSL" }, /* Coolflux configured , */ \ + { 0x960, \ + "AMPC" }, /* Selection on how Amplifier is enabled , */ \ + { 0x970, \ + "DCDIS" }, /* DCDC not connected , */ \ + { 0x980, \ + "PSDR" }, /* IDDQ test amplifier , */ \ + { 0x991, \ + "DCCV" }, /* Coil Value , */ \ + { 0x9b0, \ + "CCFD" }, /* Selection CoolFlux Clock , */ \ + { 0x9c1, \ + "INTPAD" }, /* INT pad configuration control , */ \ + { 0x9e0, \ + "IPLL" }, /* PLL input reference clock selection , */ \ + { 0xb07, \ + "MTPK" }, /* 5Ah, 90d To access KEY1_Protected registers (Default for engineering), */ \ + { 0xc25, \ + "CVFDLY" }, /* Fractional delay adjustment between current and voltage sense, */ \ + { 0x1011, \ + "TDMPRF" }, /* TDM_usecase , */ \ + { 0x1030, \ + "TDMEN" }, /* TDM interface control , */ \ + { 0x1040, \ + "TDMCKINV" }, /* TDM clock inversion , */ \ + { 0x1053, \ + "TDMFSLN" }, /* TDM FS length , */ \ + { 0x1090, \ + "TDMFSPOL" }, /* TDM FS polarity , */ \ + { 0x10a4, \ + "TDMSAMSZ" }, /* TDM Sample Size for all tdm sinks/sources , */ \ + { 0x1103, \ + "TDMSLOTS" }, /* Number of slots , */ \ + { 0x1144, \ + "TDMSLLN" }, /* Slot length , */ \ + { 0x1194, \ + "TDMBRMG" }, /* Bits remaining , */ \ + { 0x11e0, \ + "TDMDDEL" }, /* Data delay , */ \ + { 0x11f0, \ + "TDMDADJ" }, /* Data adjustment , */ \ + { 0x1201, \ + "TDMTXFRM" }, /* TXDATA format , */ \ + { 0x1221, \ + "TDMUUS0" }, /* TXDATA format unused slot sd0 , */ \ + { 0x1241, \ + "TDMUUS1" }, /* TXDATA format unused slot sd1 , */ \ + { 0x1270, \ + "TDMSI0EN" }, /* TDM sink0 enable , */ \ + { 0x1280, \ + "TDMSI1EN" }, /* TDM sink1 enable , */ \ + { 0x1290, \ + "TDMSI2EN" }, /* TDM sink2 enable , */ \ + { 0x12a0, \ + "TDMSO0EN" }, /* TDM source0 enable , */ \ + { 0x12b0, \ + "TDMSO1EN" }, /* TDM source1 enable , */ \ + { 0x12c0, \ + "TDMSO2EN" }, /* TDM source2 enable , */ \ + { 0x12d0, \ + "TDMSI0IO" }, /* tdm_sink0_io , */ \ + { 0x12e0, \ + "TDMSI1IO" }, /* tdm_sink1_io , */ \ + { 0x12f0, \ + "TDMSI2IO" }, /* tdm_sink2_io , */ \ + { 0x1300, \ + "TDMSO0IO" }, /* tdm_source0_io , */ \ + { 0x1310, \ + "TDMSO1IO" }, /* tdm_source1_io , */ \ + { 0x1320, \ + "TDMSO2IO" }, /* tdm_source2_io , */ \ + { 0x1333, \ + "TDMSI0SL" }, /* sink0_slot [GAIN IN] , */ \ + { 0x1373, \ + "TDMSI1SL" }, /* sink1_slot [CH1 IN] , */ \ + { 0x13b3, \ + "TDMSI2SL" }, /* sink2_slot [CH2 IN] , */ \ + { 0x1403, \ + "TDMSO0SL" }, /* source0_slot [GAIN OUT] , */ \ + { 0x1443, \ + "TDMSO1SL" }, /* source1_slot [Voltage Sense] , */ \ + { 0x1483, \ + "TDMSO2SL" }, /* source2_slot [Current Sense] , */ \ + { 0x14c3, \ + "NBCK" }, /* NBCK , */ \ + { 0x2000, \ + "INTOVDDS" }, /* flag_por_int_out , */ \ + { 0x2010, \ + "INTOPLLS" }, /* flag_pll_lock_int_out , */ \ + { 0x2020, \ + "INTOOTDS" }, /* flag_otpok_int_out , */ \ + { 0x2030, \ + "INTOOVDS" }, /* flag_ovpok_int_out , */ \ + { 0x2040, \ + "INTOUVDS" }, /* flag_uvpok_int_out , */ \ + { 0x2050, \ + "INTOOCDS" }, /* flag_ocp_alarm_int_out , */ \ + { 0x2060, \ + "INTOCLKS" }, /* flag_clocks_stable_int_out , */ \ + { 0x2070, \ + "INTOCLIPS" }, /* flag_clip_int_out , */ \ + { 0x2080, \ + "INTOMTPB" }, /* mtp_busy_int_out , */ \ + { 0x2090, \ + "INTONOCLK" }, /* flag_lost_clk_int_out , */ \ + { 0x20a0, \ + "INTOSPKS" }, /* flag_cf_speakererror_int_out , */ \ + { 0x20b0, \ + "INTOACS" }, /* flag_cold_started_int_out , */ \ + { 0x20c0, \ + "INTOSWS" }, /* flag_engage_int_out , */ \ + { 0x20d0, \ + "INTOWDS" }, /* flag_watchdog_reset_int_out , */ \ + { 0x20e0, \ + "INTOAMPS" }, /* flag_enbl_amp_int_out , */ \ + { 0x20f0, \ + "INTOAREFS" }, /* flag_enbl_ref_int_out , */ \ + { 0x2201, \ + "INTOACK" }, /* Interrupt status register output - Corresponding flag, */ \ + { 0x2300, \ + "INTIVDDS" }, /* flag_por_int_in , */ \ + { 0x2310, \ + "INTIPLLS" }, /* flag_pll_lock_int_in , */ \ + { 0x2320, \ + "INTIOTDS" }, /* flag_otpok_int_in , */ \ + { 0x2330, \ + "INTIOVDS" }, /* flag_ovpok_int_in , */ \ + { 0x2340, \ + "INTIUVDS" }, /* flag_uvpok_int_in , */ \ + { 0x2350, \ + "INTIOCDS" }, /* flag_ocp_alarm_int_in , */ \ + { 0x2360, \ + "INTICLKS" }, /* flag_clocks_stable_int_in , */ \ + { 0x2370, \ + "INTICLIPS" }, /* flag_clip_int_in , */ \ + { 0x2380, \ + "INTIMTPB" }, /* mtp_busy_int_in , */ \ + { 0x2390, \ + "INTINOCLK" }, /* flag_lost_clk_int_in , */ \ + { 0x23a0, \ + "INTISPKS" }, /* flag_cf_speakererror_int_in , */ \ + { 0x23b0, \ + "INTIACS" }, /* flag_cold_started_int_in , */ \ + { 0x23c0, \ + "INTISWS" }, /* flag_engage_int_in , */ \ + { 0x23d0, \ + "INTIWDS" }, /* flag_watchdog_reset_int_in , */ \ + { 0x23e0, \ + "INTIAMPS" }, /* flag_enbl_amp_int_in , */ \ + { 0x23f0, \ + "INTIAREFS" }, /* flag_enbl_ref_int_in , */ \ + { 0x2501, \ + "INTIACK" }, /* Interrupt register input , */ \ + { 0x2600, \ + "INTENVDDS" }, /* flag_por_int_enable , */ \ + { 0x2610, \ + "INTENPLLS" }, /* flag_pll_lock_int_enable , */ \ + { 0x2620, \ + "INTENOTDS" }, /* flag_otpok_int_enable , */ \ + { 0x2630, \ + "INTENOVDS" }, /* flag_ovpok_int_enable , */ \ + { 0x2640, \ + "INTENUVDS" }, /* flag_uvpok_int_enable , */ \ + { 0x2650, \ + "INTENOCDS" }, /* flag_ocp_alarm_int_enable , */ \ + { 0x2660, \ + "INTENCLKS" }, /* flag_clocks_stable_int_enable , */ \ + { 0x2670, \ + "INTENCLIPS" }, /* flag_clip_int_enable , */ \ + { 0x2680, \ + "INTENMTPB" }, /* mtp_busy_int_enable , */ \ + { 0x2690, \ + "INTENNOCLK" }, /* flag_lost_clk_int_enable , */ \ + { 0x26a0, \ + "INTENSPKS" }, /* flag_cf_speakererror_int_enable , */ \ + { 0x26b0, \ + "INTENACS" }, /* flag_cold_started_int_enable , */ \ + { 0x26c0, \ + "INTENSWS" }, /* flag_engage_int_enable , */ \ + { 0x26d0, \ + "INTENWDS" }, /* flag_watchdog_reset_int_enable , */ \ + { 0x26e0, \ + "INTENAMPS" }, /* flag_enbl_amp_int_enable , */ \ + { 0x26f0, \ + "INTENAREFS" }, /* flag_enbl_ref_int_enable , */ \ + { 0x2801, \ + "INTENACK" }, /* Interrupt enable register , */ \ + { 0x2900, \ + "INTPOLVDDS" }, /* flag_por_int_pol , */ \ + { 0x2910, \ + "INTPOLPLLS" }, /* flag_pll_lock_int_pol , */ \ + { 0x2920, \ + "INTPOLOTDS" }, /* flag_otpok_int_pol , */ \ + { 0x2930, \ + "INTPOLOVDS" }, /* flag_ovpok_int_pol , */ \ + { 0x2940, \ + "INTPOLUVDS" }, /* flag_uvpok_int_pol , */ \ + { 0x2950, \ + "INTPOLOCDS" }, /* flag_ocp_alarm_int_pol , */ \ + { 0x2960, \ + "INTPOLCLKS" }, /* flag_clocks_stable_int_pol , */ \ + { 0x2970, \ + "INTPOLCLIPS" }, /* flag_clip_int_pol , */ \ + { 0x2980, \ + "INTPOLMTPB" }, /* mtp_busy_int_pol , */ \ + { 0x2990, \ + "INTPOLNOCLK" }, /* flag_lost_clk_int_pol , */ \ + { 0x29a0, \ + "INTPOLSPKS" }, /* flag_cf_speakererror_int_pol , */ \ + { 0x29b0, \ + "INTPOLACS" }, /* flag_cold_started_int_pol , */ \ + { 0x29c0, \ + "INTPOLSWS" }, /* flag_engage_int_pol , */ \ + { 0x29d0, \ + "INTPOLWDS" }, /* flag_watchdog_reset_int_pol , */ \ + { 0x29e0, \ + "INTPOLAMPS" }, /* flag_enbl_amp_int_pol , */ \ + { 0x29f0, \ + "INTPOLAREFS" }, /* flag_enbl_ref_int_pol , */ \ + { 0x2b01, \ + "INTPOLACK" }, /* Interrupt status flags polarity register , */ \ + { 0x4900, \ + "CLIP" }, /* Bypass clip control , */ \ + { 0x62b0, \ + "CIMTP" }, /* start copying all the data from i2cregs_mtp to mtp [Key 2 protected], */ \ + { 0x7000, \ + "RST" }, /* Reset CoolFlux DSP , */ \ + { 0x7011, \ + "DMEM" }, /* Target memory for access , */ \ + { 0x7030, \ + "AIF" }, /* Autoincrement-flag for memory-address , */ \ + { 0x7040, \ + "CFINT" }, /* Interrupt CoolFlux DSP , */ \ + { 0x7087, \ + "REQ" }, /* request for access (8 channels) , */ \ + { 0x7080, \ + "REQCMD" }, /* Firmware event request rpc command , */ \ + { 0x7090, \ + "REQRST" }, /* Firmware event request reset restart , */ \ + { 0x70a0, \ + "REQMIPS" }, /* Firmware event request short on mips , */ \ + { 0x70b0, \ + "REQMUTED" }, /* Firmware event request mute sequence ready , */ \ + { 0x70c0, \ + "REQVOL" }, /* Firmware event request volume ready , */ \ + { 0x70d0, \ + "REQDMG" }, /* Firmware event request speaker damage detected , */ \ + { 0x70e0, \ + "REQCAL" }, /* Firmware event request calibration completed , */ \ + { 0x70f0, \ + "REQRSV" }, /* Firmware event request reserved , */ \ + { 0x710f, \ + "MADD" }, /* memory-address to be accessed , */ \ + { 0x720f, \ + "MEMA" }, /* activate memory access (24- or 32-bits data is written/read to/from memory, */ \ + { 0x7307, \ + "ERR" }, /* Coolflux error flags , */ \ + { 0x7387, \ + "ACK" }, /* acknowledge of requests (8 channels) , */ \ + { 0x7380, \ + "ACKCMD" }, /* Firmware event acknowledge rpc command , */ \ + { 0x7390, \ + "ACKRST" }, /* Firmware event acknowledge reset restart , */ \ + { 0x73a0, \ + "ACKMIPS" }, /* Firmware event acknowledge short on mips , */ \ + { 0x73b0, \ + "ACKMUTED" }, /* Firmware event acknowledge mute sequence ready , */ \ + { 0x73c0, \ + "ACKVOL" }, /* Firmware event acknowledge volume ready , */ \ + { 0x73d0, \ + "ACKDMG" }, /* Firmware event acknowledge speaker damage detected, */ \ + { 0x73e0, \ + "ACKCAL" }, /* Firmware event acknowledge calibration completed , */ \ + { 0x73f0, \ + "ACKRSV" }, /* Firmware event acknowledge reserved , */ \ + { 0x8000, \ + "MTPOTC" }, /* Calibration schedule (key2 protected) , */ \ + { 0x8010, \ + "MTPEX" }, /* (key2 protected) , */ \ + { 0x8045, "SWPROFIL" }, \ + { 0x80a5, "SWVSTEP" }, \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +#define TFA1_BITNAMETABLE \ + static tfaBfName_t Tfa1BitNames[] = { \ + { 0x0, \ + "flag_por" }, /* Power-on-reset flag , */ \ + { 0x10, \ + "flag_pll_lock" }, /* PLL lock , */ \ + { 0x20, \ + "flag_otpok" }, /* Over Temperature Protection alarm , */ \ + { 0x30, \ + "flag_ovpok" }, /* Over Voltage Protection alarm , */ \ + { 0x40, \ + "flag_uvpok" }, /* Under Voltage Protection alarm , */ \ + { 0x50, \ + "flag_ocp_alarm" }, /* Over Current Protection alarm , */ \ + { 0x60, \ + "flag_clocks_stable" }, /* Clocks stable flag , */ \ + { 0x70, \ + "flag_clip" }, /* Amplifier clipping , */ \ + { 0x80, \ + "mtp_busy" }, /* MTP busy , */ \ + { 0x90, \ + "flag_lost_clk" }, /* Flag lost clock from clock generation unit , */ \ + { 0xa0, \ + "flag_cf_speakererror" }, /* Speaker error flag , */ \ + { 0xb0, \ + "flag_cold_started" }, /* Cold Start flag , */ \ + { 0xc0, \ + "flag_engage" }, /* Flag Engage , */ \ + { 0xd0, \ + "flag_watchdog_reset" }, /* Flag watchdog reset , */ \ + { 0xe0, \ + "flag_enbl_amp" }, /* Amplifier is enabled by manager , */ \ + { 0xf0, \ + "flag_enbl_ref" }, /* References are enabled by manager , */ \ + { 0x109, \ + "bat_adc" }, /* Battery voltage readout; 0 .. 5.5 [V] , */ \ + { 0x208, \ + "temp_adc" }, /* Temperature readout from the temperature sensor , */ \ + { 0x30b, \ + "rev_reg" }, /* Device type number is B97 , */ \ + { 0x420, \ + "ctrl_rcv" }, /* Enable Receiver Mode , */ \ + { 0x431, \ + "chan_sel" }, /* Channel Selection TDM input for Coolflux , */ \ + { 0x450, \ + "input_level" }, /* Input level selection control , */ \ + { 0x461, \ + "vamp_sel" }, /* Input selection for amplifier , */ \ + { 0x4c3, \ + "audio_fs" }, /* Audio sample rate setting , */ \ + { 0x501, \ + "vbat_prot_attacktime" }, /* Protection Attack Time , */ \ + { 0x523, \ + "vbat_prot_thlevel" }, /* ProtectionThreshold , */ \ + { 0x561, \ + "vbat_prot_max_reduct" }, /* Protection Maximum Reduction , */ \ + { 0x582, \ + "vbat_prot_release_t" }, /* Battery Protection Release Time , */ \ + { 0x5b1, \ + "vbat_prot_hysterese" }, /* Battery Protection Hysteresis , */ \ + { 0x5d0, \ + "reset_min_vbat" }, /* reset clipper , */ \ + { 0x5e0, \ + "sel_vbat" }, /* battery voltage for I2C read out only , */ \ + { 0x5f0, \ + "bypass_clipper" }, /* bypass clipper battery protection , */ \ + { 0x600, \ + "dpsa" }, /* Enable dynamic powerstage activation , */ \ + { 0x650, \ + "cf_mute" }, /* Soft mute in CoolFlux , */ \ + { 0x670, \ + "batsense_steepness" }, /* BatSenseSteepness , */ \ + { 0x687, \ + "vol" }, /* volume control (in CoolFlux) , */ \ + { 0x702, \ + "boost_volt" }, /* Boost Voltage , */ \ + { 0x733, \ + "boost_cur" }, /* Max boost coil current - step of 175 mA , */ \ + { 0x7a0, \ + "boost_intel" }, /* Adaptive boost mode , */ \ + { 0x7b0, \ + "boost_speed" }, /* Soft RampUp/Down mode for DCDC controller , */ \ + { 0x7c0, \ + "boost_peak2avg" }, /* ctrl_peak2avg for analog part of DCDC , */ \ + { 0x800, \ + "ext_temp_sel" }, /* Select external temperature also the ext_temp will be put on the temp read out , */ \ + { 0x818, \ + "ext_temp" }, /* external temperature setting to be given by host , */ \ + { 0x8b2, \ + "dcdc_synchronisation" }, /* DCDC synchronisation off + 7 positions , */ \ + { 0x900, \ + "powerdown" }, /* Device Mode , */ \ + { 0x910, \ + "reset" }, /* I2C Reset , */ \ + { 0x920, \ + "enbl_coolflux" }, /* Enable CoolFlux , */ \ + { 0x930, \ + "enbl_amplifier" }, /* Enable Amplifier , */ \ + { 0x940, \ + "enbl_boost" }, /* EnableBoost , */ \ + { 0x950, \ + "coolflux_configured" }, /* Coolflux configured , */ \ + { 0x960, \ + "sel_enbl_amplifier" }, /* Selection on how Amplifier is enabled , */ \ + { 0x970, \ + "dcdcoff_mode" }, /* DCDC not connected , */ \ + { 0x980, \ + "iddqtest" }, /* IDDQ test amplifier , */ \ + { 0x991, \ + "coil_value" }, /* Coil Value , */ \ + { 0x9b0, \ + "sel_cf_clock" }, /* Selection CoolFlux Clock , */ \ + { 0x9c1, \ + "int_pad_io" }, /* INT pad configuration control , */ \ + { 0x9e0, \ + "sel_fs_bck" }, /* PLL input reference clock selection , */ \ + { 0x9f0, \ + "sel_scl_cf_clock" }, /* Coolflux sub-system clock , */ \ + { 0xb07, \ + "mtpkey2" }, /* 5Ah, 90d To access KEY1_Protected registers (Default for engineering), */ \ + { 0xc00, \ + "enbl_volt_sense" }, /* Voltage sense enabling control bit , */ \ + { 0xc10, \ + "vsense_pwm_sel" }, /* Voltage sense PWM source selection control , */ \ + { 0xc25, \ + "vi_frac_delay" }, /* Fractional delay adjustment between current and voltage sense, */ \ + { 0xc80, \ + "sel_voltsense_out" }, /* TDM output data selection control , */ \ + { 0xc90, \ + "vsense_bypass_avg" }, /* Voltage Sense Average Block Bypass , */ \ + { 0xd05, \ + "cf_frac_delay" }, /* Fractional delay adjustment between current and voltage sense by firmware, */ \ + { 0xe00, \ + "bypass_dcdc_curr_prot" }, /* Control to switch off dcdc current reduction with bat protection, */ \ + { 0xe80, \ + "disable_clock_sh_prot" }, /* disable clock_sh protection , */ \ + { 0xe96, \ + "reserve_reg_1_15_9" }, /* , */ \ + { 0x1011, \ + "tdm_usecase" }, /* TDM_usecase , */ \ + { 0x1030, \ + "tdm_enable" }, /* TDM interface control , */ \ + { 0x1040, \ + "tdm_clk_inversion" }, /* TDM clock inversion , */ \ + { 0x1053, \ + "tdm_fs_ws_length" }, /* TDM FS length , */ \ + { 0x1090, \ + "tdm_fs_ws_polarity" }, /* TDM FS polarity , */ \ + { 0x10a4, \ + "tdm_sample_size" }, /* TDM Sample Size for all tdm sinks/sources , */ \ + { 0x1103, \ + "tdm_nb_of_slots" }, /* Number of slots , */ \ + { 0x1144, \ + "tdm_slot_length" }, /* Slot length , */ \ + { 0x1194, \ + "tdm_bits_remaining" }, /* Bits remaining , */ \ + { 0x11e0, \ + "tdm_data_delay" }, /* Data delay , */ \ + { 0x11f0, \ + "tdm_data_adjustment" }, /* Data adjustment , */ \ + { 0x1201, \ + "tdm_txdata_format" }, /* TXDATA format , */ \ + { 0x1221, \ + "tdm_txdata_format_unused_slot_sd0" }, /* TXDATA format unused slot sd0 , */ \ + { 0x1241, \ + "tdm_txdata_format_unused_slot_sd1" }, /* TXDATA format unused slot sd1 , */ \ + { 0x1270, \ + "tdm_sink0_enable" }, /* TDM sink0 enable , */ \ + { 0x1280, \ + "tdm_sink1_enable" }, /* TDM sink1 enable , */ \ + { 0x1290, \ + "tdm_sink2_enable" }, /* TDM sink2 enable , */ \ + { 0x12a0, \ + "tdm_source0_enable" }, /* TDM source0 enable , */ \ + { 0x12b0, \ + "tdm_source1_enable" }, /* TDM source1 enable , */ \ + { 0x12c0, \ + "tdm_source2_enable" }, /* TDM source2 enable , */ \ + { 0x12d0, \ + "tdm_sink0_io" }, /* tdm_sink0_io , */ \ + { 0x12e0, \ + "tdm_sink1_io" }, /* tdm_sink1_io , */ \ + { 0x12f0, \ + "tdm_sink2_io" }, /* tdm_sink2_io , */ \ + { 0x1300, \ + "tdm_source0_io" }, /* tdm_source0_io , */ \ + { 0x1310, \ + "tdm_source1_io" }, /* tdm_source1_io , */ \ + { 0x1320, \ + "tdm_source2_io" }, /* tdm_source2_io , */ \ + { 0x1333, \ + "tdm_sink0_slot" }, /* sink0_slot [GAIN IN] , */ \ + { 0x1373, \ + "tdm_sink1_slot" }, /* sink1_slot [CH1 IN] , */ \ + { 0x13b3, \ + "tdm_sink2_slot" }, /* sink2_slot [CH2 IN] , */ \ + { 0x1403, \ + "tdm_source0_slot" }, /* source0_slot [GAIN OUT] , */ \ + { 0x1443, \ + "tdm_source1_slot" }, /* source1_slot [Voltage Sense] , */ \ + { 0x1483, \ + "tdm_source2_slot" }, /* source2_slot [Current Sense] , */ \ + { 0x14c3, \ + "tdm_nbck" }, /* NBCK , */ \ + { 0x1500, \ + "flag_tdm_lut_error" }, /* TDM LUT error flag , */ \ + { 0x1512, \ + "flag_tdm_status" }, /* TDM interface status bits , */ \ + { 0x1540, \ + "flag_tdm_error" }, /* TDM interface error indicator , */ \ + { 0x2000, \ + "flag_por_int_out" }, /* flag_por_int_out , */ \ + { 0x2010, \ + "flag_pll_lock_int_out" }, /* flag_pll_lock_int_out , */ \ + { 0x2020, \ + "flag_otpok_int_out" }, /* flag_otpok_int_out , */ \ + { 0x2030, \ + "flag_ovpok_int_out" }, /* flag_ovpok_int_out , */ \ + { 0x2040, \ + "flag_uvpok_int_out" }, /* flag_uvpok_int_out , */ \ + { 0x2050, \ + "flag_ocp_alarm_int_out" }, /* flag_ocp_alarm_int_out , */ \ + { 0x2060, \ + "flag_clocks_stable_int_out" }, /* flag_clocks_stable_int_out , */ \ + { 0x2070, \ + "flag_clip_int_out" }, /* flag_clip_int_out , */ \ + { 0x2080, \ + "mtp_busy_int_out" }, /* mtp_busy_int_out , */ \ + { 0x2090, \ + "flag_lost_clk_int_out" }, /* flag_lost_clk_int_out , */ \ + { 0x20a0, \ + "flag_cf_speakererror_int_out" }, /* flag_cf_speakererror_int_out , */ \ + { 0x20b0, \ + "flag_cold_started_int_out" }, /* flag_cold_started_int_out , */ \ + { 0x20c0, \ + "flag_engage_int_out" }, /* flag_engage_int_out , */ \ + { 0x20d0, \ + "flag_watchdog_reset_int_out" }, /* flag_watchdog_reset_int_out , */ \ + { 0x20e0, \ + "flag_enbl_amp_int_out" }, /* flag_enbl_amp_int_out , */ \ + { 0x20f0, \ + "flag_enbl_ref_int_out" }, /* flag_enbl_ref_int_out , */ \ + { 0x2100, \ + "flag_voutcomp_int_out" }, /* flag_voutcomp_int_out , */ \ + { 0x2110, \ + "flag_voutcomp93_int_out" }, /* flag_voutcomp93_int_out , */ \ + { 0x2120, \ + "flag_voutcomp86_int_out" }, /* flag_voutcomp86_int_out , */ \ + { 0x2130, \ + "flag_hiz_int_out" }, /* flag_hiz_int_out , */ \ + { 0x2140, \ + "flag_ocpokbst_int_out" }, /* flag_ocpokbst_int_out , */ \ + { 0x2150, \ + "flag_peakcur_int_out" }, /* flag_peakcur_int_out , */ \ + { 0x2160, \ + "flag_ocpokap_int_out" }, /* flag_ocpokap_int_out , */ \ + { 0x2170, \ + "flag_ocpokan_int_out" }, /* flag_ocpokan_int_out , */ \ + { 0x2180, \ + "flag_ocpokbp_int_out" }, /* flag_ocpokbp_int_out , */ \ + { 0x2190, \ + "flag_ocpokbn_int_out" }, /* flag_ocpokbn_int_out , */ \ + { 0x21a0, \ + "flag_adc10_ready_int_out" }, /* flag_adc10_ready_int_out , */ \ + { 0x21b0, \ + "flag_clipa_high_int_out" }, /* flag_clipa_high_int_out , */ \ + { 0x21c0, \ + "flag_clipa_low_int_out" }, /* flag_clipa_low_int_out , */ \ + { 0x21d0, \ + "flag_clipb_high_int_out" }, /* flag_clipb_high_int_out , */ \ + { 0x21e0, \ + "flag_clipb_low_int_out" }, /* flag_clipb_low_int_out , */ \ + { 0x21f0, \ + "flag_tdm_error_int_out" }, /* flag_tdm_error_int_out , */ \ + { 0x2201, \ + "interrupt_out3" }, /* Interrupt status register output - Corresponding flag, */ \ + { 0x2300, \ + "flag_por_int_in" }, /* flag_por_int_in , */ \ + { 0x2310, \ + "flag_pll_lock_int_in" }, /* flag_pll_lock_int_in , */ \ + { 0x2320, \ + "flag_otpok_int_in" }, /* flag_otpok_int_in , */ \ + { 0x2330, \ + "flag_ovpok_int_in" }, /* flag_ovpok_int_in , */ \ + { 0x2340, \ + "flag_uvpok_int_in" }, /* flag_uvpok_int_in , */ \ + { 0x2350, \ + "flag_ocp_alarm_int_in" }, /* flag_ocp_alarm_int_in , */ \ + { 0x2360, \ + "flag_clocks_stable_int_in" }, /* flag_clocks_stable_int_in , */ \ + { 0x2370, \ + "flag_clip_int_in" }, /* flag_clip_int_in , */ \ + { 0x2380, \ + "mtp_busy_int_in" }, /* mtp_busy_int_in , */ \ + { 0x2390, \ + "flag_lost_clk_int_in" }, /* flag_lost_clk_int_in , */ \ + { 0x23a0, \ + "flag_cf_speakererror_int_in" }, /* flag_cf_speakererror_int_in , */ \ + { 0x23b0, \ + "flag_cold_started_int_in" }, /* flag_cold_started_int_in , */ \ + { 0x23c0, \ + "flag_engage_int_in" }, /* flag_engage_int_in , */ \ + { 0x23d0, \ + "flag_watchdog_reset_int_in" }, /* flag_watchdog_reset_int_in , */ \ + { 0x23e0, \ + "flag_enbl_amp_int_in" }, /* flag_enbl_amp_int_in , */ \ + { 0x23f0, \ + "flag_enbl_ref_int_in" }, /* flag_enbl_ref_int_in , */ \ + { 0x2400, \ + "flag_voutcomp_int_in" }, /* flag_voutcomp_int_in , */ \ + { 0x2410, \ + "flag_voutcomp93_int_in" }, /* flag_voutcomp93_int_in , */ \ + { 0x2420, \ + "flag_voutcomp86_int_in" }, /* flag_voutcomp86_int_in , */ \ + { 0x2430, \ + "flag_hiz_int_in" }, /* flag_hiz_int_in , */ \ + { 0x2440, \ + "flag_ocpokbst_int_in" }, /* flag_ocpokbst_int_in , */ \ + { 0x2450, \ + "flag_peakcur_int_in" }, /* flag_peakcur_int_in , */ \ + { 0x2460, \ + "flag_ocpokap_int_in" }, /* flag_ocpokap_int_in , */ \ + { 0x2470, \ + "flag_ocpokan_int_in" }, /* flag_ocpokan_int_in , */ \ + { 0x2480, \ + "flag_ocpokbp_int_in" }, /* flag_ocpokbp_int_in , */ \ + { 0x2490, \ + "flag_ocpokbn_int_in" }, /* flag_ocpokbn_int_in , */ \ + { 0x24a0, \ + "flag_adc10_ready_int_in" }, /* flag_adc10_ready_int_in , */ \ + { 0x24b0, \ + "flag_clipa_high_int_in" }, /* flag_clipa_high_int_in , */ \ + { 0x24c0, \ + "flag_clipa_low_int_in" }, /* flag_clipa_low_int_in , */ \ + { 0x24d0, \ + "flag_clipb_high_int_in" }, /* flag_clipb_high_int_in , */ \ + { 0x24e0, \ + "flag_clipb_low_int_in" }, /* flag_clipb_low_int_in , */ \ + { 0x24f0, \ + "flag_tdm_error_int_in" }, /* flag_tdm_error_int_in , */ \ + { 0x2501, \ + "interrupt_in3" }, /* Interrupt register input , */ \ + { 0x2600, \ + "flag_por_int_enable" }, /* flag_por_int_enable , */ \ + { 0x2610, \ + "flag_pll_lock_int_enable" }, /* flag_pll_lock_int_enable , */ \ + { 0x2620, \ + "flag_otpok_int_enable" }, /* flag_otpok_int_enable , */ \ + { 0x2630, \ + "flag_ovpok_int_enable" }, /* flag_ovpok_int_enable , */ \ + { 0x2640, \ + "flag_uvpok_int_enable" }, /* flag_uvpok_int_enable , */ \ + { 0x2650, \ + "flag_ocp_alarm_int_enable" }, /* flag_ocp_alarm_int_enable , */ \ + { 0x2660, \ + "flag_clocks_stable_int_enable" }, /* flag_clocks_stable_int_enable , */ \ + { 0x2670, \ + "flag_clip_int_enable" }, /* flag_clip_int_enable , */ \ + { 0x2680, \ + "mtp_busy_int_enable" }, /* mtp_busy_int_enable , */ \ + { 0x2690, \ + "flag_lost_clk_int_enable" }, /* flag_lost_clk_int_enable , */ \ + { 0x26a0, \ + "flag_cf_speakererror_int_enable" }, /* flag_cf_speakererror_int_enable , */ \ + { 0x26b0, \ + "flag_cold_started_int_enable" }, /* flag_cold_started_int_enable , */ \ + { 0x26c0, \ + "flag_engage_int_enable" }, /* flag_engage_int_enable , */ \ + { 0x26d0, \ + "flag_watchdog_reset_int_enable" }, /* flag_watchdog_reset_int_enable , */ \ + { 0x26e0, \ + "flag_enbl_amp_int_enable" }, /* flag_enbl_amp_int_enable , */ \ + { 0x26f0, \ + "flag_enbl_ref_int_enable" }, /* flag_enbl_ref_int_enable , */ \ + { 0x2700, \ + "flag_voutcomp_int_enable" }, /* flag_voutcomp_int_enable , */ \ + { 0x2710, \ + "flag_voutcomp93_int_enable" }, /* flag_voutcomp93_int_enable , */ \ + { 0x2720, \ + "flag_voutcomp86_int_enable" }, /* flag_voutcomp86_int_enable , */ \ + { 0x2730, \ + "flag_hiz_int_enable" }, /* flag_hiz_int_enable , */ \ + { 0x2740, \ + "flag_ocpokbst_int_enable" }, /* flag_ocpokbst_int_enable , */ \ + { 0x2750, \ + "flag_peakcur_int_enable" }, /* flag_peakcur_int_enable , */ \ + { 0x2760, \ + "flag_ocpokap_int_enable" }, /* flag_ocpokap_int_enable , */ \ + { 0x2770, \ + "flag_ocpokan_int_enable" }, /* flag_ocpokan_int_enable , */ \ + { 0x2780, \ + "flag_ocpokbp_int_enable" }, /* flag_ocpokbp_int_enable , */ \ + { 0x2790, \ + "flag_ocpokbn_int_enable" }, /* flag_ocpokbn_int_enable , */ \ + { 0x27a0, \ + "flag_adc10_ready_int_enable" }, /* flag_adc10_ready_int_enable , */ \ + { 0x27b0, \ + "flag_clipa_high_int_enable" }, /* flag_clipa_high_int_enable , */ \ + { 0x27c0, \ + "flag_clipa_low_int_enable" }, /* flag_clipa_low_int_enable , */ \ + { 0x27d0, \ + "flag_clipb_high_int_enable" }, /* flag_clipb_high_int_enable , */ \ + { 0x27e0, \ + "flag_clipb_low_int_enable" }, /* flag_clipb_low_int_enable , */ \ + { 0x27f0, \ + "flag_tdm_error_int_enable" }, /* flag_tdm_error_int_enable , */ \ + { 0x2801, \ + "interrupt_enable3" }, /* Interrupt enable register , */ \ + { 0x2900, \ + "flag_por_int_pol" }, /* flag_por_int_pol , */ \ + { 0x2910, \ + "flag_pll_lock_int_pol" }, /* flag_pll_lock_int_pol , */ \ + { 0x2920, \ + "flag_otpok_int_pol" }, /* flag_otpok_int_pol , */ \ + { 0x2930, \ + "flag_ovpok_int_pol" }, /* flag_ovpok_int_pol , */ \ + { 0x2940, \ + "flag_uvpok_int_pol" }, /* flag_uvpok_int_pol , */ \ + { 0x2950, \ + "flag_ocp_alarm_int_pol" }, /* flag_ocp_alarm_int_pol , */ \ + { 0x2960, \ + "flag_clocks_stable_int_pol" }, /* flag_clocks_stable_int_pol , */ \ + { 0x2970, \ + "flag_clip_int_pol" }, /* flag_clip_int_pol , */ \ + { 0x2980, \ + "mtp_busy_int_pol" }, /* mtp_busy_int_pol , */ \ + { 0x2990, \ + "flag_lost_clk_int_pol" }, /* flag_lost_clk_int_pol , */ \ + { 0x29a0, \ + "flag_cf_speakererror_int_pol" }, /* flag_cf_speakererror_int_pol , */ \ + { 0x29b0, \ + "flag_cold_started_int_pol" }, /* flag_cold_started_int_pol , */ \ + { 0x29c0, \ + "flag_engage_int_pol" }, /* flag_engage_int_pol , */ \ + { 0x29d0, \ + "flag_watchdog_reset_int_pol" }, /* flag_watchdog_reset_int_pol , */ \ + { 0x29e0, \ + "flag_enbl_amp_int_pol" }, /* flag_enbl_amp_int_pol , */ \ + { 0x29f0, \ + "flag_enbl_ref_int_pol" }, /* flag_enbl_ref_int_pol , */ \ + { 0x2a00, \ + "flag_voutcomp_int_pol" }, /* flag_voutcomp_int_pol , */ \ + { 0x2a10, \ + "flag_voutcomp93_int_pol" }, /* flag_voutcomp93_int_pol , */ \ + { 0x2a20, \ + "flag_voutcomp86_int_pol" }, /* flag_voutcomp86_int_pol , */ \ + { 0x2a30, \ + "flag_hiz_int_pol" }, /* flag_hiz_int_pol , */ \ + { 0x2a40, \ + "flag_ocpokbst_int_pol" }, /* flag_ocpokbst_int_pol , */ \ + { 0x2a50, \ + "flag_peakcur_int_pol" }, /* flag_peakcur_int_pol , */ \ + { 0x2a60, \ + "flag_ocpokap_int_pol" }, /* flag_ocpokap_int_pol , */ \ + { 0x2a70, \ + "flag_ocpokan_int_pol" }, /* flag_ocpokan_int_pol , */ \ + { 0x2a80, \ + "flag_ocpokbp_int_pol" }, /* flag_ocpokbp_int_pol , */ \ + { 0x2a90, \ + "flag_ocpokbn_int_pol" }, /* flag_ocpokbn_int_pol , */ \ + { 0x2aa0, \ + "flag_adc10_ready_int_pol" }, /* flag_adc10_ready_int_pol , */ \ + { 0x2ab0, \ + "flag_clipa_high_int_pol" }, /* flag_clipa_high_int_pol , */ \ + { 0x2ac0, \ + "flag_clipa_low_int_pol" }, /* flag_clipa_low_int_pol , */ \ + { 0x2ad0, \ + "flag_clipb_high_int_pol" }, /* flag_clipb_high_int_pol , */ \ + { 0x2ae0, \ + "flag_clipb_low_int_pol" }, /* flag_clipb_low_int_pol , */ \ + { 0x2af0, \ + "flag_tdm_error_int_pol" }, /* flag_tdm_error_int_pol , */ \ + { 0x2b01, \ + "status_polarity3" }, /* Interrupt status flags polarity register , */ \ + { 0x3000, \ + "flag_voutcomp" }, /* flag_voutcomp, indication Vset is larger than Vbat, */ \ + { 0x3010, \ + "flag_voutcomp93" }, /* flag_voutcomp93, indication Vset is larger than 1.07* Vbat, */ \ + { 0x3020, \ + "flag_voutcomp86" }, /* flag_voutcomp86, indication Vset is larger than 1.14* Vbat, */ \ + { 0x3030, \ + "flag_hiz" }, /* flag_hiz, indication Vbst is larger than Vbat , */ \ + { 0x3040, \ + "flag_ocpokbst" }, /* flag_ocpokbst, indication no over current in boost converter pmos switch, */ \ + { 0x3050, \ + "flag_peakcur" }, /* flag_peakcur, indication current is max in dcdc converter, */ \ + { 0x3060, \ + "flag_ocpokap" }, /* flag_ocpokap, indication no over current in amplifier "a" pmos output stage, */ \ + { 0x3070, \ + "flag_ocpokan" }, /* flag_ocpokan, indication no over current in amplifier "a" nmos output stage, */ \ + { 0x3080, \ + "flag_ocpokbp" }, /* flag_ocpokbp, indication no over current in amplifier "b" pmos output stage, */ \ + { 0x3090, \ + "flag_ocpokbn" }, /* flag_ocpokbn, indication no over current in amplifier"b" nmos output stage, */ \ + { 0x30a0, \ + "flag_adc10_ready" }, /* flag_adc10_ready, indication adc10 is ready , */ \ + { 0x30b0, \ + "flag_clipa_high" }, /* flag_clipa_high, indication pmos amplifier "a" is clipping, */ \ + { 0x30c0, \ + "flag_clipa_low" }, /* flag_clipa_low, indication nmos amplifier "a" is clipping, */ \ + { 0x30d0, \ + "flag_clipb_high" }, /* flag_clipb_high, indication pmos amplifier "b" is clipping, */ \ + { 0x30e0, \ + "flag_clipb_low" }, /* flag_clipb_low, indication nmos amplifier "b" is clipping, */ \ + { 0x310f, \ + "mtp_man_data_out" }, /* single word read from MTP (manual copy) , */ \ + { 0x3200, \ + "key01_locked" }, /* key01_locked, indication key 1 is locked , */ \ + { 0x3210, \ + "key02_locked" }, /* key02_locked, indication key 2 is locked , */ \ + { 0x3225, \ + "mtp_ecc_tcout" }, /* mtp_ecc_tcout , */ \ + { 0x3280, \ + "mtpctrl_valid_test_rd" }, /* mtp test readout for read , */ \ + { 0x3290, \ + "mtpctrl_valid_test_wr" }, /* mtp test readout for write , */ \ + { 0x32a0, \ + "flag_in_alarm_state" }, /* Alarm state , */ \ + { 0x32b0, \ + "mtp_ecc_err2" }, /* two or more bit errors detected in MTP, can not reconstruct value, */ \ + { 0x32c0, \ + "mtp_ecc_err1" }, /* one bit error detected in MTP, reconstructed value, */ \ + { 0x32d0, \ + "mtp_mtp_hvf" }, /* high voltage ready flag for MTP , */ \ + { 0x32f0, \ + "mtp_zero_check_fail" }, /* zero check failed (tbd) for MTP , */ \ + { 0x3309, \ + "data_adc10_tempbat" }, /* data_adc10_tempbat[9;0], adc 10 data output for testing, */ \ + { 0x400f, \ + "hid_code" }, /* 5A6Bh, 23147d to access registers (Default for engineering), */ \ + { 0x4100, \ + "bypass_hp" }, /* Bypass_High Pass Filter , */ \ + { 0x4110, \ + "hard_mute" }, /* Hard Mute , */ \ + { 0x4120, \ + "soft_mute" }, /* Soft Mute , */ \ + { 0x4134, \ + "pwm_delay" }, /* PWM DelayBits to set the delay , */ \ + { 0x4180, \ + "pwm_shape" }, /* PWM Shape , */ \ + { 0x4190, \ + "pwm_bitlength" }, /* PWM Bitlength in noise shaper , */ \ + { 0x4203, \ + "drive" }, /* Drive bits to select amount of power stage amplifier, */ \ + { 0x4240, \ + "reclock_pwm" }, /* , */ \ + { 0x4250, \ + "reclock_voltsense" }, /* , */ \ + { 0x4281, \ + "dpsalevel" }, /* DPSA Threshold level , */ \ + { 0x42a1, \ + "dpsa_release" }, /* DPSA Release time , */ \ + { 0x42c0, \ + "coincidence" }, /* Prevent simultaneously switching of output stage , */ \ + { 0x42d0, \ + "kickback" }, /* Prevent double pulses of output stage , */ \ + { 0x4306, \ + "drivebst" }, /* Drive bits to select the powertransistor sections boost converter, */ \ + { 0x43a0, \ + "ocptestbst" }, /* Boost OCP. For old ocp (ctrl_reversebst is 0);For new ocp (ctrl_reversebst is 1);, */ \ + { 0x43d0, \ + "test_abistfft_enbl" }, /* FFT coolflux , */ \ + { 0x43f0, \ + "test_bcontrol" }, /* test _bcontrol , */ \ + { 0x4400, \ + "reversebst" }, /* OverCurrent Protection selection of power stage boost converter, */ \ + { 0x4410, \ + "sensetest" }, /* Test option for the sense NMOS in booster for current mode control., */ \ + { 0x4420, \ + "enbl_engagebst" }, /* Enable power stage dcdc controller , */ \ + { 0x4470, \ + "enbl_slopecur" }, /* Enable bit of max-current dac , */ \ + { 0x4480, \ + "enbl_voutcomp" }, /* Enable vout comparators , */ \ + { 0x4490, \ + "enbl_voutcomp93" }, /* Enable vout-93 comparators , */ \ + { 0x44a0, \ + "enbl_voutcomp86" }, /* Enable vout-86 comparators , */ \ + { 0x44b0, \ + "enbl_hizcom" }, /* Enable hiz comparator , */ \ + { 0x44c0, \ + "enbl_peakcur" }, /* Enable peak current , */ \ + { 0x44d0, \ + "bypass_ovpglitch" }, /* Bypass OVP Glitch Filter , */ \ + { 0x44e0, \ + "enbl_windac" }, /* Enable window dac , */ \ + { 0x44f0, \ + "enbl_powerbst" }, /* Enable line of the powerstage , */ \ + { 0x4507, \ + "ocp_thr" }, /* ocp_thr threshold level for OCP , */ \ + { 0x4580, \ + "bypass_glitchfilter" }, /* Bypass glitch filter , */ \ + { 0x4590, \ + "bypass_ovp" }, /* Bypass OVP , */ \ + { 0x45a0, \ + "bypass_uvp" }, /* Bypass UVP , */ \ + { 0x45b0, \ + "bypass_otp" }, /* Bypass OTP , */ \ + { 0x45c0, \ + "bypass_ocp" }, /* Bypass OCP , */ \ + { 0x45d0, \ + "bypass_ocpcounter" }, /* BypassOCPCounter , */ \ + { 0x45e0, \ + "bypass_lost_clk" }, /* Bypasslost_clk detector , */ \ + { 0x45f0, \ + "vpalarm" }, /* vpalarm (uvp ovp handling) , */ \ + { 0x4600, \ + "bypass_gc" }, /* bypass_gc, bypasses the CS gain correction , */ \ + { 0x4610, \ + "cs_gain_control" }, /* gain control by means of MTP or i2c; 0 is MTP , */ \ + { 0x4627, \ + "cs_gain" }, /* + / - 128 steps in steps of 1/4 percent 2's compliment, */ \ + { 0x46a0, \ + "bypass_lp" }, /* bypass Low-Pass filter in temperature sensor , */ \ + { 0x46b0, \ + "bypass_pwmcounter" }, /* bypass_pwmcounter , */ \ + { 0x46c0, \ + "cs_negfixed" }, /* does not switch to neg , */ \ + { 0x46d2, \ + "cs_neghyst" }, /* switches to neg depending on level , */ \ + { 0x4700, \ + "switch_fb" }, /* switch_fb , */ \ + { 0x4713, \ + "se_hyst" }, /* se_hyst , */ \ + { 0x4754, \ + "se_level" }, /* se_level , */ \ + { 0x47a5, \ + "ktemp" }, /* temperature compensation trimming , */ \ + { 0x4800, \ + "cs_negin" }, /* negin , */ \ + { 0x4810, \ + "cs_sein" }, /* cs_sein , */ \ + { 0x4820, \ + "cs_coincidence" }, /* Coincidence current sense , */ \ + { 0x4830, \ + "iddqtestbst" }, /* for iddq testing in powerstage of boost convertor , */ \ + { 0x4840, \ + "coincidencebst" }, /* Switch protection on to prevent simultaneously switching power stages bst and amp, */ \ + { 0x4876, \ + "delay_se_neg" }, /* delay of se and neg , */ \ + { 0x48e1, \ + "cs_ttrack" }, /* sample & hold track time , */ \ + { 0x4900, \ + "bypass_clip" }, /* Bypass clip control , */ \ + { 0x4920, \ + "cf_cgate_off" }, /* to disable clock gating in the coolflux , */ \ + { 0x4940, \ + "clipfast" }, /* clock switch for battery protection clipper, it switches back to old frequency, */ \ + { 0x4950, \ + "cs_8ohm" }, /* 8 ohm mode for current sense (gain mode) , */ \ + { 0x4974, \ + "delay_clock_sh" }, /* delay_sh, tunes S7H delay , */ \ + { 0x49c0, \ + "inv_clksh" }, /* Invert the sample/hold clock for current sense ADC, */ \ + { 0x49d0, \ + "inv_neg" }, /* Invert neg signal , */ \ + { 0x49e0, \ + "inv_se" }, /* Invert se signal , */ \ + { 0x49f0, \ + "setse" }, /* switches between Single Ende and differential mode; 1 is single ended, */ \ + { 0x4a12, \ + "adc10_sel" }, /* select the input to convert the 10b ADC , */ \ + { 0x4a60, \ + "adc10_reset" }, /* Global asynchronous reset (active HIGH) 10 bit ADC, */ \ + { 0x4a81, \ + "adc10_test" }, /* Test mode selection signal 10 bit ADC , */ \ + { 0x4aa0, \ + "bypass_lp_vbat" }, /* lp filter in batt sensor , */ \ + { 0x4ae0, \ + "dc_offset" }, /* switch offset control on/off, is decimator offset control, */ \ + { 0x4af0, \ + "tsense_hibias" }, /* bit to set the biasing in temp sensor to high , */ \ + { 0x4b00, \ + "adc13_iset" }, /* Micadc Setting of current consumption. Debug use only, */ \ + { 0x4b14, \ + "adc13_gain" }, /* Micadc gain setting (2-compl) , */ \ + { 0x4b61, \ + "adc13_slowdel" }, /* Micadc Delay setting for internal clock. Debug use only, */ \ + { 0x4b83, \ + "adc13_offset" }, /* Micadc ADC offset setting , */ \ + { 0x4bc0, \ + "adc13_bsoinv" }, /* Micadc bit stream output invert mode for test , */ \ + { 0x4bd0, \ + "adc13_resonator_enable" }, /* Micadc Give extra SNR with less stability. Debug use only, */ \ + { 0x4be0, \ + "testmicadc" }, /* Mux at input of MICADC for test purpose , */ \ + { 0x4c0f, \ + "abist_offset" }, /* offset control for ABIST testing , */ \ + { 0x4d05, \ + "windac" }, /* for testing direct control windac , */ \ + { 0x4dc3, \ + "pwm_dcc_cnt" }, /* control pwm duty cycle when enbl_pwm_dcc is 1 , */ \ + { 0x4e04, \ + "slopecur" }, /* for testing direct control slopecur , */ \ + { 0x4e50, \ + "ctrl_dem" }, /* dyn element matching control, rest of codes are optional, */ \ + { 0x4ed0, \ + "enbl_pwm_dcc" }, /* to enable direct control of pwm duty cycle , */ \ + { 0x5007, \ + "gain" }, /* Gain setting of the gain multiplier , */ \ + { 0x5081, \ + "sourceb" }, /* Set OUTB to , */ \ + { 0x50a1, \ + "sourcea" }, /* Set OUTA to , */ \ + { 0x50c1, \ + "sourcebst" }, /* Sets the source of the pwmbst output to boost converter input for testing, */ \ + { 0x50e0, \ + "tdm_enable_loopback" }, /* TDM loopback test , */ \ + { 0x5104, \ + "pulselengthbst" }, /* pulse length setting test input for boost converter, */ \ + { 0x5150, \ + "bypasslatchbst" }, /* bypass_latch in boost converter , */ \ + { 0x5160, \ + "invertbst" }, /* invert pwmbst test signal , */ \ + { 0x5174, \ + "pulselength" }, /* pulse length setting test input for amplifier , */ \ + { 0x51c0, \ + "bypasslatch" }, /* bypass_latch in PWM source selection module , */ \ + { 0x51d0, \ + "invertb" }, /* invert pwmb test signal , */ \ + { 0x51e0, \ + "inverta" }, /* invert pwma test signal , */ \ + { 0x51f0, \ + "bypass_ctrlloop" }, /* bypass_ctrlloop bypasses the control loop of the amplifier, */ \ + { 0x5210, \ + "test_rdsona" }, /* tbd for rdson testing , */ \ + { 0x5220, \ + "test_rdsonb" }, /* tbd for rdson testing , */ \ + { 0x5230, \ + "test_rdsonbst" }, /* tbd for rdson testing , */ \ + { 0x5240, \ + "test_cvia" }, /* tbd for rdson testing , */ \ + { 0x5250, \ + "test_cvib" }, /* tbd for rdson testing , */ \ + { 0x5260, \ + "test_cvibst" }, /* tbd for rdson testing , */ \ + { 0x5306, \ + "digimuxa_sel" }, /* DigimuxA input selection control (see Digimux list for details), */ \ + { 0x5376, \ + "digimuxb_sel" }, /* DigimuxB input selection control (see Digimux list for details), */ \ + { 0x5400, \ + "hs_mode" }, /* hs_mode, high speed mode I2C bus , */ \ + { 0x5412, \ + "test_parametric_io" }, /* test_parametric_io for testing pads , */ \ + { 0x5440, \ + "enbl_ringo" }, /* enbl_ringo, for test purpose to check with ringo , */ \ + { 0x5456, \ + "digimuxc_sel" }, /* DigimuxC input selection control (see Digimux list for details), */ \ + { 0x54c0, \ + "dio_ehs" }, /* Slew control for DIO in output mode , */ \ + { 0x54d0, \ + "gainio_ehs" }, /* Slew control for GAINIO in output mode , */ \ + { 0x550d, \ + "enbl_amp" }, /* enbl_amp for testing to enable all analoge blocks in amplifier, */ \ + { 0x5600, \ + "use_direct_ctrls" }, /* use_direct_ctrls, to overrule several functions direct for testing, */ \ + { 0x5610, \ + "rst_datapath" }, /* rst_datapath, datapath reset , */ \ + { 0x5620, \ + "rst_cgu" }, /* rst_cgu, cgu reset , */ \ + { 0x5637, \ + "enbl_ref" }, /* for testing to enable all analoge blocks in references, */ \ + { 0x56b0, \ + "enbl_engage" }, /* Enable output stage amplifier , */ \ + { 0x56c0, \ + "use_direct_clk_ctrl" }, /* use_direct_clk_ctrl, to overrule several functions direct for testing, */ \ + { 0x56d0, \ + "use_direct_pll_ctrl" }, /* use_direct_pll_ctrl, to overrule several functions direct for testing, */ \ + { 0x56e0, \ + "use_direct_ctrls_2" }, /* use_direct_sourseamp_ctrls, to overrule several functions direct for testing, */ \ + { 0x5707, \ + "anamux" }, /* Anamux control , */ \ + { 0x57c0, \ + "ocptest" }, /* ctrl_ocptest, deactivates the over current protection in the power stages of the amplifier. The ocp flag signals stay active., */ \ + { 0x57e0, \ + "otptest" }, /* otptest, test mode otp amplifier , */ \ + { 0x57f0, \ + "reverse" }, /* 1: Normal mode, slope is controlled , */ \ + { 0x5813, \ + "pll_selr" }, /* pll_selr , */ \ + { 0x5854, \ + "pll_selp" }, /* pll_selp , */ \ + { 0x58a5, \ + "pll_seli" }, /* pll_seli , */ \ + { 0x5950, \ + "pll_mdec_msb" }, /* most significant bits of pll_mdec[16] , */ \ + { 0x5960, \ + "pll_ndec_msb" }, /* most significant bits of pll_ndec[9] , */ \ + { 0x5970, \ + "pll_frm" }, /* pll_frm , */ \ + { 0x5980, \ + "pll_directi" }, /* pll_directi , */ \ + { 0x5990, \ + "pll_directo" }, /* pll_directo , */ \ + { 0x59a0, \ + "enbl_pll" }, /* enbl_pll , */ \ + { 0x59f0, \ + "pll_bypass" }, /* pll_bypass , */ \ + { 0x5a0f, \ + "tsig_freq" }, /* tsig_freq, internal sinus test generator, frequency control, */ \ + { 0x5b02, \ + "tsig_freq_msb" }, /* select internal sinus test generator, frequency control msb bits, */ \ + { 0x5b30, \ + "inject_tsig" }, /* inject_tsig, control bit to switch to internal sinus test generator, */ \ + { 0x5b44, \ + "adc10_prog_sample" }, /* control ADC10 , */ \ + { 0x5c0f, \ + "pll_mdec" }, /* bits 15..0 of pll_mdec[16;0] , */ \ + { 0x5d06, \ + "pll_pdec" }, /* pll_pdec , */ \ + { 0x5d78, \ + "pll_ndec" }, /* bits 8..0 of pll_ndec[9;0] , */ \ + { 0x6007, \ + "mtpkey1" }, /* 5Ah, 90d To access KEY1_Protected registers (Default for engineering), */ \ + { 0x6185, \ + "mtp_ecc_tcin" }, /* Mtp_ecc_tcin , */ \ + { 0x6203, \ + "mtp_man_address_in" }, /* address from I2C regs for writing one word single mtp, */ \ + { 0x6260, \ + "mtp_ecc_eeb" }, /* enable code bit generation (active low!) , */ \ + { 0x6270, \ + "mtp_ecc_ecb" }, /* enable correction signal (active low!) , */ \ + { 0x6280, \ + "man_copy_mtp_to_iic" }, /* start copying single word from mtp to i2cregs_mtp , */ \ + { 0x6290, \ + "man_copy_iic_to_mtp" }, /* start copying single word from i2cregs_mtp to mtp [Key 1 protected], */ \ + { 0x62a0, \ + "auto_copy_mtp_to_iic" }, /* start copying all the data from mtp to i2cregs_mtp, */ \ + { 0x62b0, \ + "auto_copy_iic_to_mtp" }, /* start copying all the data from i2cregs_mtp to mtp [Key 2 protected], */ \ + { 0x62d2, \ + "mtp_speed_mode" }, /* Speed mode , */ \ + { 0x6340, \ + "mtp_direct_enable" }, /* mtp_direct_enable (key1 protected) , */ \ + { 0x6350, \ + "mtp_direct_wr" }, /* mtp_direct_wr (key1 protected) , */ \ + { 0x6360, \ + "mtp_direct_rd" }, /* mtp_direct_rd (key1 protected) , */ \ + { 0x6370, \ + "mtp_direct_rst" }, /* mtp_direct_rst (key1 protected) , */ \ + { 0x6380, \ + "mtp_direct_ers" }, /* mtp_direct_ers (key1 protected) , */ \ + { 0x6390, \ + "mtp_direct_prg" }, /* mtp_direct_prg (key1 protected) , */ \ + { 0x63a0, \ + "mtp_direct_epp" }, /* mtp_direct_epp (key1 protected) , */ \ + { 0x63b4, \ + "mtp_direct_test" }, /* mtp_direct_test (key1 protected) , */ \ + { 0x640f, \ + "mtp_man_data_in" }, /* single word to be written to MTP (manual copy) , */ \ + { 0x7000, \ + "cf_rst_dsp" }, /* Reset CoolFlux DSP , */ \ + { 0x7011, \ + "cf_dmem" }, /* Target memory for access , */ \ + { 0x7030, \ + "cf_aif" }, /* Autoincrement-flag for memory-address , */ \ + { 0x7040, \ + "cf_int" }, /* Interrupt CoolFlux DSP , */ \ + { 0x7087, \ + "cf_req" }, /* request for access (8 channels) , */ \ + { 0x710f, \ + "cf_madd" }, /* memory-address to be accessed , */ \ + { 0x720f, \ + "cf_mema" }, /* activate memory access (24- or 32-bits data is written/read to/from memory, */ \ + { 0x7307, \ + "cf_err" }, /* Coolflux error flags , */ \ + { 0x7387, \ + "cf_ack" }, /* acknowledge of requests (8 channels) , */ \ + { 0x8000, \ + "calibration_onetime" }, /* Calibration schedule (key2 protected) , */ \ + { 0x8010, \ + "calibr_ron_done" }, /* (key2 protected) , */ \ + { 0x8105, \ + "calibr_vout_offset" }, /* calibr_vout_offset (DCDCoffset) 2's compliment (key1 protected), */ \ + { 0x8163, \ + "calibr_delta_gain" }, /* delta gain for vamp (alpha) 2's compliment (key1 protected), */ \ + { 0x81a5, \ + "calibr_offs_amp" }, /* offset for vamp (Ampoffset) 2's compliment (key1 protected), */ \ + { 0x8207, \ + "calibr_gain_cs" }, /* gain current sense (Imeasalpha) 2's compliment (key1 protected), */ \ + { 0x8284, \ + "calibr_temp_offset" }, /* temperature offset 2's compliment (key1 protected), */ \ + { 0x82d2, \ + "calibr_temp_gain" }, /* temperature gain 2's compliment (key1 protected) , */ \ + { 0x830f, \ + "calibr_ron" }, /* Ron resistance of coil (key1 protected) , */ \ + { 0x8505, \ + "type_bits_HW" }, /* Key1_Protected_MTP5 , */ \ + { 0x8601, \ + "type_bits_1_0_SW" }, /* MTP-control SW , */ \ + { 0x8681, \ + "type_bits_8_9_SW" }, /* MTP-control SW , */ \ + { 0x870f, \ + "type_bits2_SW" }, /* MTP-control SW2 , */ \ + { 0x8806, \ + "htol_iic_addr" }, /* 7-bit I2C address to be used during HTOL testing , */ \ + { 0x8870, \ + "htol_iic_addr_en" }, /* HTOL_I2C_Address_Enable , */ \ + { 0x8881, \ + "ctrl_ovp_response" }, /* OVP response control , */ \ + { 0x88a0, \ + "disable_ovp_alarm_state" }, /* OVP alarm state control , */ \ + { 0x88b0, \ + "enbl_stretch_ovp" }, /* OVP alram strech control , */ \ + { 0x88c0, \ + "cf_debug_mode" }, /* Coolflux debug mode , */ \ + { 0x8a0f, \ + "production_data1" }, /* (key1 protected) , */ \ + { 0x8b0f, \ + "production_data2" }, /* (key1 protected) , */ \ + { 0x8c0f, \ + "production_data3" }, /* (key1 protected) , */ \ + { 0x8d0f, \ + "production_data4" }, /* (key1 protected) , */ \ + { 0x8e0f, \ + "production_data5" }, /* (key1 protected) , */ \ + { 0x8f0f, \ + "production_data6" }, /* (key1 protected) , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +enum tfa1_irq { + tfa1_irq_vdds = 0, + tfa1_irq_plls = 1, + tfa1_irq_ds = 2, + tfa1_irq_vds = 3, + tfa1_irq_uvds = 4, + tfa1_irq_cds = 5, + tfa1_irq_clks = 6, + tfa1_irq_clips = 7, + tfa1_irq_mtpb = 8, + tfa1_irq_clk = 9, + tfa1_irq_spks = 10, + tfa1_irq_acs = 11, + tfa1_irq_sws = 12, + tfa1_irq_wds = 13, + tfa1_irq_amps = 14, + tfa1_irq_arefs = 15, + tfa1_irq_ack = 32, + tfa1_irq_max = 33, + tfa1_irq_all = -1 /* all irqs */ +}; + +#define TFA1_IRQ_NAMETABLE \ + static tfaIrqName_t Tfa1IrqNames[] = { \ + { 0, "VDDS" }, { 1, "PLLS" }, { 2, "DS" }, { 3, "VDS" }, \ + { 4, "UVDS" }, { 5, "CDS" }, { 6, "CLKS" }, { 7, "CLIPS" }, \ + { 8, "MTPB" }, { 9, "CLK" }, { 10, "SPKS" }, { 11, "ACS" }, \ + { 12, "SWS" }, { 13, "WDS" }, { 14, "AMPS" }, { 15, "AREFS" }, \ + { 16, "16" }, { 17, "17" }, { 18, "18" }, { 19, "19" }, \ + { 20, "20" }, { 21, "21" }, { 22, "22" }, { 23, "23" }, \ + { 24, "24" }, { 25, "25" }, { 26, "26" }, { 27, "27" }, \ + { 28, "28" }, { 29, "29" }, { 30, "30" }, { 31, "31" }, \ + { 32, "ACK" }, { 33, "33" }, \ + }; diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa2_tfafieldnames_N1C.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa2_tfafieldnames_N1C.h new file mode 100644 index 000000000000..afe0bfcd31d3 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa2_tfafieldnames_N1C.h @@ -0,0 +1,2930 @@ +/** Filename: Tfa98xx_TfaFieldnames.h + * This file was generated automatically on 09/01/15 at 09:40:28. + * Source file: TFA9888_N1C_I2C_regmap_V1.xlsx + */ +#define TFA9888_I2CVERSION 18 +typedef enum nxpTfa2BfEnumList { + TFA2_BF_PWDN = + 0x0000, /*!< Powerdown selection */ + TFA2_BF_I2CR = + 0x0010, /*!< I2C Reset - Auto clear */ + TFA2_BF_CFE = + 0x0020, /*!< Enable CoolFlux */ + TFA2_BF_AMPE = + 0x0030, /*!< Activate Amplifier */ + TFA2_BF_DCA = + 0x0040, /*!< Activate DC-to-DC converter */ + TFA2_BF_SBSL = + 0x0050, /*!< Coolflux configured */ + TFA2_BF_AMPC = + 0x0060, /*!< CoolFlux controls amplifier */ + TFA2_BF_INTP = + 0x0071, /*!< Interrupt config */ + TFA2_BF_FSSSEL = + 0x0091, /*!< Audio sample reference */ + TFA2_BF_BYPOCP = + 0x00b0, /*!< Bypass OCP */ + TFA2_BF_TSTOCP = + 0x00c0, /*!< OCP testing control */ + TFA2_BF_AMPINSEL = + 0x0101, /*!< Amplifier input selection */ + TFA2_BF_MANSCONF = + 0x0120, /*!< I2C configured */ + TFA2_BF_MANCOLD = + 0x0130, /*!< Execute cold start */ + TFA2_BF_MANAOOSC = + 0x0140, /*!< Internal osc off at PWDN */ + TFA2_BF_MANROBOD = + 0x0150, /*!< Reaction on BOD */ + TFA2_BF_BODE = + 0x0160, /*!< BOD Enable */ + TFA2_BF_BODHYS = + 0x0170, /*!< BOD Hysteresis */ + TFA2_BF_BODFILT = + 0x0181, /*!< BOD filter */ + TFA2_BF_BODTHLVL = + 0x01a1, /*!< BOD threshold */ + TFA2_BF_MUTETO = + 0x01d0, /*!< Time out SB mute sequence */ + TFA2_BF_RCVNS = + 0x01e0, /*!< Noise shaper selection */ + TFA2_BF_MANWDE = + 0x01f0, /*!< Watchdog manager reaction */ + TFA2_BF_AUDFS = + 0x0203, /*!< Sample rate (fs) */ + TFA2_BF_INPLEV = + 0x0240, /*!< TDM output attenuation */ + TFA2_BF_FRACTDEL = + 0x0255, /*!< V/I Fractional delay */ + TFA2_BF_BYPHVBF = + 0x02b0, /*!< Bypass HVBAT filter */ + TFA2_BF_LDOBYP = + 0x02c0, /*!< Receiver LDO bypass */ + TFA2_BF_REV = + 0x030f, /*!< Revision info */ + TFA2_BF_REFCKEXT = + 0x0401, /*!< PLL external ref clock */ + TFA2_BF_REFCKSEL = + 0x0420, /*!< PLL internal ref clock */ + TFA2_BF_SSLEFTE = + 0x0500, /*!< Enable left channel */ + TFA2_BF_SSRIGHTE = + 0x0510, /*!< Enable right channel */ + TFA2_BF_VSLEFTE = + 0x0520, /*!< Voltage sense left */ + TFA2_BF_VSRIGHTE = + 0x0530, /*!< Voltage sense right */ + TFA2_BF_CSLEFTE = + 0x0540, /*!< Current sense left */ + TFA2_BF_CSRIGHTE = + 0x0550, /*!< Current sense right */ + TFA2_BF_SSPDME = + 0x0560, /*!< Sub-system PDM */ + TFA2_BF_STGAIN = + 0x0d18, /*!< Side tone gain */ + TFA2_BF_PDMSMUTE = + 0x0da0, /*!< Side tone soft mute */ + TFA2_BF_SWVSTEP = + 0x0e06, /*!< Register for the host SW to record the current active vstep */ + TFA2_BF_VDDS = + 0x1000, /*!< POR */ + TFA2_BF_PLLS = + 0x1010, /*!< PLL lock */ + TFA2_BF_OTDS = + 0x1020, /*!< OTP alarm */ + TFA2_BF_OVDS = + 0x1030, /*!< OVP alarm */ + TFA2_BF_UVDS = + 0x1040, /*!< UVP alarm */ + TFA2_BF_CLKS = + 0x1050, /*!< Clocks stable */ + TFA2_BF_MTPB = + 0x1060, /*!< MTP busy */ + TFA2_BF_NOCLK = + 0x1070, /*!< Lost clock */ + TFA2_BF_SPKS = + 0x1080, /*!< Speaker error */ + TFA2_BF_ACS = + 0x1090, /*!< Cold Start */ + TFA2_BF_SWS = + 0x10a0, /*!< Amplifier engage */ + TFA2_BF_WDS = + 0x10b0, /*!< Watchdog */ + TFA2_BF_AMPS = + 0x10c0, /*!< Amplifier enable */ + TFA2_BF_AREFS = + 0x10d0, /*!< References enable */ + TFA2_BF_ADCCR = + 0x10e0, /*!< Control ADC */ + TFA2_BF_BODNOK = + 0x10f0, /*!< BOD */ + TFA2_BF_DCIL = + 0x1100, /*!< DCDC current limiting */ + TFA2_BF_DCDCA = + 0x1110, /*!< DCDC active */ + TFA2_BF_DCOCPOK = + 0x1120, /*!< DCDC OCP nmos */ + TFA2_BF_DCHVBAT = + 0x1140, /*!< DCDC level 1x */ + TFA2_BF_DCH114 = + 0x1150, /*!< DCDC level 1.14x */ + TFA2_BF_DCH107 = + 0x1160, /*!< DCDC level 1.07x */ + TFA2_BF_STMUTEB = + 0x1170, /*!< side tone (un)mute busy */ + TFA2_BF_STMUTE = + 0x1180, /*!< side tone mute state */ + TFA2_BF_TDMLUTER = + 0x1190, /*!< TDM LUT error */ + TFA2_BF_TDMSTAT = + 0x11a2, /*!< TDM status bits */ + TFA2_BF_TDMERR = + 0x11d0, /*!< TDM error */ + TFA2_BF_HAPTIC = + 0x11e0, /*!< Status haptic driver */ + TFA2_BF_OCPOAPL = + 0x1200, /*!< OCPOK pmos A left */ + TFA2_BF_OCPOANL = + 0x1210, /*!< OCPOK nmos A left */ + TFA2_BF_OCPOBPL = + 0x1220, /*!< OCPOK pmos B left */ + TFA2_BF_OCPOBNL = + 0x1230, /*!< OCPOK nmos B left */ + TFA2_BF_CLIPAHL = + 0x1240, /*!< Clipping A left to Vddp */ + TFA2_BF_CLIPALL = + 0x1250, /*!< Clipping A left to gnd */ + TFA2_BF_CLIPBHL = + 0x1260, /*!< Clipping B left to Vddp */ + TFA2_BF_CLIPBLL = + 0x1270, /*!< Clipping B left to gnd */ + TFA2_BF_OCPOAPRC = + 0x1280, /*!< OCPOK pmos A RCV */ + TFA2_BF_OCPOANRC = + 0x1290, /*!< OCPOK nmos A RCV */ + TFA2_BF_OCPOBPRC = + 0x12a0, /*!< OCPOK pmos B RCV */ + TFA2_BF_OCPOBNRC = + 0x12b0, /*!< OCPOK nmos B RCV */ + TFA2_BF_RCVLDOR = + 0x12c0, /*!< RCV LDO regulates */ + TFA2_BF_RCVLDOBR = + 0x12d0, /*!< Receiver LDO ready */ + TFA2_BF_OCDSL = + 0x12e0, /*!< OCP left amplifier */ + TFA2_BF_CLIPSL = + 0x12f0, /*!< Amplifier left clipping */ + TFA2_BF_OCPOAPR = + 0x1300, /*!< OCPOK pmos A right */ + TFA2_BF_OCPOANR = + 0x1310, /*!< OCPOK nmos A right */ + TFA2_BF_OCPOBPR = + 0x1320, /*!< OCPOK pmos B right */ + TFA2_BF_OCPOBNR = + 0x1330, /*!< OCPOK nmos B right */ + TFA2_BF_CLIPAHR = + 0x1340, /*!< Clipping A right to Vddp */ + TFA2_BF_CLIPALR = + 0x1350, /*!< Clipping A right to gnd */ + TFA2_BF_CLIPBHR = + 0x1360, /*!< Clipping B left to Vddp */ + TFA2_BF_CLIPBLR = + 0x1370, /*!< Clipping B right to gnd */ + TFA2_BF_OCDSR = + 0x1380, /*!< OCP right amplifier */ + TFA2_BF_CLIPSR = + 0x1390, /*!< Amplifier right clipping */ + TFA2_BF_OCPOKMC = + 0x13a0, /*!< OCPOK MICVDD */ + TFA2_BF_MANALARM = + 0x13b0, /*!< Alarm state */ + TFA2_BF_MANWAIT1 = + 0x13c0, /*!< Wait HW I2C settings */ + TFA2_BF_MANWAIT2 = + 0x13d0, /*!< Wait CF config */ + TFA2_BF_MANMUTE = + 0x13e0, /*!< Audio mute sequence */ + TFA2_BF_MANOPER = + 0x13f0, /*!< Operating state */ + TFA2_BF_SPKSL = + 0x1400, /*!< Left speaker status */ + TFA2_BF_SPKSR = + 0x1410, /*!< Right speaker status */ + TFA2_BF_CLKOOR = + 0x1420, /*!< External clock status */ + TFA2_BF_MANSTATE = + 0x1433, /*!< Device manager status */ + TFA2_BF_BATS = + 0x1509, /*!< Battery voltage (V) */ + TFA2_BF_TEMPS = + 0x1608, /*!< IC Temperature (C) */ + TFA2_BF_TDMUC = + 0x2003, /*!< Usecase setting */ + TFA2_BF_TDME = + 0x2040, /*!< Enable interface */ + TFA2_BF_TDMMODE = + 0x2050, /*!< Slave/master */ + TFA2_BF_TDMCLINV = + 0x2060, /*!< Reception data to BCK clock */ + TFA2_BF_TDMFSLN = + 0x2073, /*!< FS length (master mode only) */ + TFA2_BF_TDMFSPOL = + 0x20b0, /*!< FS polarity */ + TFA2_BF_TDMNBCK = + 0x20c3, /*!< N-BCK's in FS */ + TFA2_BF_TDMSLOTS = + 0x2103, /*!< N-slots in Frame */ + TFA2_BF_TDMSLLN = + 0x2144, /*!< N-bits in slot */ + TFA2_BF_TDMBRMG = + 0x2194, /*!< N-bits remaining */ + TFA2_BF_TDMDEL = + 0x21e0, /*!< data delay to FS */ + TFA2_BF_TDMADJ = + 0x21f0, /*!< data adjustment */ + TFA2_BF_TDMOOMP = + 0x2201, /*!< Received audio compression */ + TFA2_BF_TDMSSIZE = + 0x2224, /*!< Sample size per slot */ + TFA2_BF_TDMTXDFO = + 0x2271, /*!< Format unused bits */ + TFA2_BF_TDMTXUS0 = + 0x2291, /*!< Format unused slots GAINIO */ + TFA2_BF_TDMTXUS1 = + 0x22b1, /*!< Format unused slots DIO1 */ + TFA2_BF_TDMTXUS2 = + 0x22d1, /*!< Format unused slots DIO2 */ + TFA2_BF_TDMLE = + 0x2310, /*!< Control audio left */ + TFA2_BF_TDMRE = + 0x2320, /*!< Control audio right */ + TFA2_BF_TDMVSRE = + 0x2340, /*!< Control voltage sense right */ + TFA2_BF_TDMCSRE = + 0x2350, /*!< Control current sense right */ + TFA2_BF_TDMVSLE = + 0x2360, /*!< Voltage sense left control */ + TFA2_BF_TDMCSLE = + 0x2370, /*!< Current sense left control */ + TFA2_BF_TDMCFRE = + 0x2380, /*!< DSP out right control */ + TFA2_BF_TDMCFLE = + 0x2390, /*!< DSP out left control */ + TFA2_BF_TDMCF3E = + 0x23a0, /*!< AEC ref left control */ + TFA2_BF_TDMCF4E = + 0x23b0, /*!< AEC ref right control */ + TFA2_BF_TDMPD1E = + 0x23c0, /*!< PDM 1 control */ + TFA2_BF_TDMPD2E = + 0x23d0, /*!< PDM 2 control */ + TFA2_BF_TDMLIO = + 0x2421, /*!< IO audio left */ + TFA2_BF_TDMRIO = + 0x2441, /*!< IO audio right */ + TFA2_BF_TDMVSRIO = + 0x2481, /*!< IO voltage sense right */ + TFA2_BF_TDMCSRIO = + 0x24a1, /*!< IO current sense right */ + TFA2_BF_TDMVSLIO = + 0x24c1, /*!< IO voltage sense left */ + TFA2_BF_TDMCSLIO = + 0x24e1, /*!< IO current sense left */ + TFA2_BF_TDMCFRIO = + 0x2501, /*!< IO dspout right */ + TFA2_BF_TDMCFLIO = + 0x2521, /*!< IO dspout left */ + TFA2_BF_TDMCF3IO = + 0x2541, /*!< IO AEC ref left control */ + TFA2_BF_TDMCF4IO = + 0x2561, /*!< IO AEC ref right control */ + TFA2_BF_TDMPD1IO = + 0x2581, /*!< IO pdm1 */ + TFA2_BF_TDMPD2IO = + 0x25a1, /*!< IO pdm2 */ + TFA2_BF_TDMLS = + 0x2643, /*!< Position audio left */ + TFA2_BF_TDMRS = + 0x2683, /*!< Position audio right */ + TFA2_BF_TDMVSRS = + 0x2703, /*!< Position voltage sense right */ + TFA2_BF_TDMCSRS = + 0x2743, /*!< Position current sense right */ + TFA2_BF_TDMVSLS = + 0x2783, /*!< Position voltage sense left */ + TFA2_BF_TDMCSLS = + 0x27c3, /*!< Position current sense left */ + TFA2_BF_TDMCFRS = + 0x2803, /*!< Position dspout right */ + TFA2_BF_TDMCFLS = + 0x2843, /*!< Position dspout left */ + TFA2_BF_TDMCF3S = + 0x2883, /*!< Position AEC ref left control */ + TFA2_BF_TDMCF4S = + 0x28c3, /*!< Position AEC ref right control */ + TFA2_BF_TDMPD1S = + 0x2903, /*!< Position pdm1 */ + TFA2_BF_TDMPD2S = + 0x2943, /*!< Position pdm2 */ + TFA2_BF_PDMSM = + 0x3100, /*!< PDM control */ + TFA2_BF_PDMSTSEL = + 0x3111, /*!< Side tone input */ + TFA2_BF_PDMLSEL = + 0x3130, /*!< PDM data selection for left channel during PDM direct mode */ + TFA2_BF_PDMRSEL = + 0x3140, /*!< PDM data selection for right channel during PDM direct mode */ + TFA2_BF_MICVDDE = + 0x3150, /*!< Enable MICVDD */ + TFA2_BF_PDMCLRAT = + 0x3201, /*!< PDM BCK/Fs ratio */ + TFA2_BF_PDMGAIN = + 0x3223, /*!< PDM gain */ + TFA2_BF_PDMOSEL = + 0x3263, /*!< PDM output selection - RE/FE data combination */ + TFA2_BF_SELCFHAPD = + 0x32a0, /*!< Select the source for haptic data output (not for customer) */ + TFA2_BF_HAPTIME = + 0x3307, /*!< Duration (ms) */ + TFA2_BF_HAPLEVEL = + 0x3387, /*!< DC value (FFS) */ + TFA2_BF_GPIODIN = + 0x3403, /*!< Receiving value */ + TFA2_BF_GPIOCTRL = + 0x3500, /*!< GPIO master control over GPIO1/2 ports (not for customer) */ + TFA2_BF_GPIOCONF = + 0x3513, /*!< Configuration */ + TFA2_BF_GPIODOUT = + 0x3553, /*!< Transmitting value */ + TFA2_BF_ISTVDDS = + 0x4000, /*!< Status POR */ + TFA2_BF_ISTPLLS = + 0x4010, /*!< Status PLL lock */ + TFA2_BF_ISTOTDS = + 0x4020, /*!< Status OTP alarm */ + TFA2_BF_ISTOVDS = + 0x4030, /*!< Status OVP alarm */ + TFA2_BF_ISTUVDS = + 0x4040, /*!< Status UVP alarm */ + TFA2_BF_ISTCLKS = + 0x4050, /*!< Status clocks stable */ + TFA2_BF_ISTMTPB = + 0x4060, /*!< Status MTP busy */ + TFA2_BF_ISTNOCLK = + 0x4070, /*!< Status lost clock */ + TFA2_BF_ISTSPKS = + 0x4080, /*!< Status speaker error */ + TFA2_BF_ISTACS = + 0x4090, /*!< Status cold start */ + TFA2_BF_ISTSWS = + 0x40a0, /*!< Status amplifier engage */ + TFA2_BF_ISTWDS = + 0x40b0, /*!< Status watchdog */ + TFA2_BF_ISTAMPS = + 0x40c0, /*!< Status amplifier enable */ + TFA2_BF_ISTAREFS = + 0x40d0, /*!< Status Ref enable */ + TFA2_BF_ISTADCCR = + 0x40e0, /*!< Status Control ADC */ + TFA2_BF_ISTBODNOK = + 0x40f0, /*!< Status BOD */ + TFA2_BF_ISTBSTCU = + 0x4100, /*!< Status DCDC current limiting */ + TFA2_BF_ISTBSTHI = + 0x4110, /*!< Status DCDC active */ + TFA2_BF_ISTBSTOC = + 0x4120, /*!< Status DCDC OCP */ + TFA2_BF_ISTBSTPKCUR = + 0x4130, /*!< Status bst peakcur */ + TFA2_BF_ISTBSTVC = + 0x4140, /*!< Status DCDC level 1x */ + TFA2_BF_ISTBST86 = + 0x4150, /*!< Status DCDC level 1.14x */ + TFA2_BF_ISTBST93 = + 0x4160, /*!< Status DCDC level 1.07x */ + TFA2_BF_ISTRCVLD = + 0x4170, /*!< Status rcvldop ready */ + TFA2_BF_ISTOCPL = + 0x4180, /*!< Status ocp alarm left */ + TFA2_BF_ISTOCPR = + 0x4190, /*!< Status ocp alarm right */ + TFA2_BF_ISTMWSRC = + 0x41a0, /*!< Status Waits HW I2C settings */ + TFA2_BF_ISTMWCFC = + 0x41b0, /*!< Status waits CF config */ + TFA2_BF_ISTMWSMU = + 0x41c0, /*!< Status Audio mute sequence */ + TFA2_BF_ISTCFMER = + 0x41d0, /*!< Status cfma error */ + TFA2_BF_ISTCFMAC = + 0x41e0, /*!< Status cfma ack */ + TFA2_BF_ISTCLKOOR = + 0x41f0, /*!< Status flag_clk_out_of_range */ + TFA2_BF_ISTTDMER = + 0x4200, /*!< Status tdm error */ + TFA2_BF_ISTCLPL = + 0x4210, /*!< Status clip left */ + TFA2_BF_ISTCLPR = + 0x4220, /*!< Status clip right */ + TFA2_BF_ISTOCPM = + 0x4230, /*!< Status mic ocpok */ + TFA2_BF_ICLVDDS = + 0x4400, /*!< Clear POR */ + TFA2_BF_ICLPLLS = + 0x4410, /*!< Clear PLL lock */ + TFA2_BF_ICLOTDS = + 0x4420, /*!< Clear OTP alarm */ + TFA2_BF_ICLOVDS = + 0x4430, /*!< Clear OVP alarm */ + TFA2_BF_ICLUVDS = + 0x4440, /*!< Clear UVP alarm */ + TFA2_BF_ICLCLKS = + 0x4450, /*!< Clear clocks stable */ + TFA2_BF_ICLMTPB = + 0x4460, /*!< Clear mtp busy */ + TFA2_BF_ICLNOCLK = + 0x4470, /*!< Clear lost clk */ + TFA2_BF_ICLSPKS = + 0x4480, /*!< Clear speaker error */ + TFA2_BF_ICLACS = + 0x4490, /*!< Clear cold started */ + TFA2_BF_ICLSWS = + 0x44a0, /*!< Clear amplifier engage */ + TFA2_BF_ICLWDS = + 0x44b0, /*!< Clear watchdog */ + TFA2_BF_ICLAMPS = + 0x44c0, /*!< Clear enbl amp */ + TFA2_BF_ICLAREFS = + 0x44d0, /*!< Clear ref enable */ + TFA2_BF_ICLADCCR = + 0x44e0, /*!< Clear control ADC */ + TFA2_BF_ICLBODNOK = + 0x44f0, /*!< Clear BOD */ + TFA2_BF_ICLBSTCU = + 0x4500, /*!< Clear DCDC current limiting */ + TFA2_BF_ICLBSTHI = + 0x4510, /*!< Clear DCDC active */ + TFA2_BF_ICLBSTOC = + 0x4520, /*!< Clear DCDC OCP */ + TFA2_BF_ICLBSTPC = + 0x4530, /*!< Clear bst peakcur */ + TFA2_BF_ICLBSTVC = + 0x4540, /*!< Clear DCDC level 1x */ + TFA2_BF_ICLBST86 = + 0x4550, /*!< Clear DCDC level 1.14x */ + TFA2_BF_ICLBST93 = + 0x4560, /*!< Clear DCDC level 1.07x */ + TFA2_BF_ICLRCVLD = + 0x4570, /*!< Clear rcvldop ready */ + TFA2_BF_ICLOCPL = + 0x4580, /*!< Clear ocp alarm left */ + TFA2_BF_ICLOCPR = + 0x4590, /*!< Clear ocp alarm right */ + TFA2_BF_ICLMWSRC = + 0x45a0, /*!< Clear wait HW I2C settings */ + TFA2_BF_ICLMWCFC = + 0x45b0, /*!< Clear wait cf config */ + TFA2_BF_ICLMWSMU = + 0x45c0, /*!< Clear audio mute sequence */ + TFA2_BF_ICLCFMER = + 0x45d0, /*!< Clear cfma err */ + TFA2_BF_ICLCFMAC = + 0x45e0, /*!< Clear cfma ack */ + TFA2_BF_ICLCLKOOR = + 0x45f0, /*!< Clear flag_clk_out_of_range */ + TFA2_BF_ICLTDMER = + 0x4600, /*!< Clear tdm error */ + TFA2_BF_ICLCLPL = + 0x4610, /*!< Clear clip left */ + TFA2_BF_ICLCLPR = + 0x4620, /*!< Clear clip right */ + TFA2_BF_ICLOCPM = + 0x4630, /*!< Clear mic ocpok */ + TFA2_BF_IEVDDS = + 0x4800, /*!< Enable por */ + TFA2_BF_IEPLLS = + 0x4810, /*!< Enable pll lock */ + TFA2_BF_IEOTDS = + 0x4820, /*!< Enable OTP alarm */ + TFA2_BF_IEOVDS = + 0x4830, /*!< Enable OVP alarm */ + TFA2_BF_IEUVDS = + 0x4840, /*!< Enable UVP alarm */ + TFA2_BF_IECLKS = + 0x4850, /*!< Enable clocks stable */ + TFA2_BF_IEMTPB = + 0x4860, /*!< Enable mtp busy */ + TFA2_BF_IENOCLK = + 0x4870, /*!< Enable lost clk */ + TFA2_BF_IESPKS = + 0x4880, /*!< Enable speaker error */ + TFA2_BF_IEACS = + 0x4890, /*!< Enable cold started */ + TFA2_BF_IESWS = + 0x48a0, /*!< Enable amplifier engage */ + TFA2_BF_IEWDS = + 0x48b0, /*!< Enable watchdog */ + TFA2_BF_IEAMPS = + 0x48c0, /*!< Enable enbl amp */ + TFA2_BF_IEAREFS = + 0x48d0, /*!< Enable ref enable */ + TFA2_BF_IEADCCR = + 0x48e0, /*!< Enable Control ADC */ + TFA2_BF_IEBODNOK = + 0x48f0, /*!< Enable BOD */ + TFA2_BF_IEBSTCU = + 0x4900, /*!< Enable DCDC current limiting */ + TFA2_BF_IEBSTHI = + 0x4910, /*!< Enable DCDC active */ + TFA2_BF_IEBSTOC = + 0x4920, /*!< Enable DCDC OCP */ + TFA2_BF_IEBSTPC = + 0x4930, /*!< Enable bst peakcur */ + TFA2_BF_IEBSTVC = + 0x4940, /*!< Enable DCDC level 1x */ + TFA2_BF_IEBST86 = + 0x4950, /*!< Enable DCDC level 1.14x */ + TFA2_BF_IEBST93 = + 0x4960, /*!< Enable DCDC level 1.07x */ + TFA2_BF_IERCVLD = + 0x4970, /*!< Enable rcvldop ready */ + TFA2_BF_IEOCPL = + 0x4980, /*!< Enable ocp alarm left */ + TFA2_BF_IEOCPR = + 0x4990, /*!< Enable ocp alarm right */ + TFA2_BF_IEMWSRC = + 0x49a0, /*!< Enable waits HW I2C settings */ + TFA2_BF_IEMWCFC = + 0x49b0, /*!< Enable man wait cf config */ + TFA2_BF_IEMWSMU = + 0x49c0, /*!< Enable man Audio mute sequence */ + TFA2_BF_IECFMER = + 0x49d0, /*!< Enable cfma err */ + TFA2_BF_IECFMAC = + 0x49e0, /*!< Enable cfma ack */ + TFA2_BF_IECLKOOR = + 0x49f0, /*!< Enable flag_clk_out_of_range */ + TFA2_BF_IETDMER = + 0x4a00, /*!< Enable tdm error */ + TFA2_BF_IECLPL = + 0x4a10, /*!< Enable clip left */ + TFA2_BF_IECLPR = + 0x4a20, /*!< Enable clip right */ + TFA2_BF_IEOCPM1 = + 0x4a30, /*!< Enable mic ocpok */ + TFA2_BF_IPOVDDS = + 0x4c00, /*!< Polarity por */ + TFA2_BF_IPOPLLS = + 0x4c10, /*!< Polarity pll lock */ + TFA2_BF_IPOOTDS = + 0x4c20, /*!< Polarity OTP alarm */ + TFA2_BF_IPOOVDS = + 0x4c30, /*!< Polarity OVP alarm */ + TFA2_BF_IPOUVDS = + 0x4c40, /*!< Polarity UVP alarm */ + TFA2_BF_IPOCLKS = + 0x4c50, /*!< Polarity clocks stable */ + TFA2_BF_IPOMTPB = + 0x4c60, /*!< Polarity mtp busy */ + TFA2_BF_IPONOCLK = + 0x4c70, /*!< Polarity lost clk */ + TFA2_BF_IPOSPKS = + 0x4c80, /*!< Polarity speaker error */ + TFA2_BF_IPOACS = + 0x4c90, /*!< Polarity cold started */ + TFA2_BF_IPOSWS = + 0x4ca0, /*!< Polarity amplifier engage */ + TFA2_BF_IPOWDS = + 0x4cb0, /*!< Polarity watchdog */ + TFA2_BF_IPOAMPS = + 0x4cc0, /*!< Polarity enbl amp */ + TFA2_BF_IPOAREFS = + 0x4cd0, /*!< Polarity ref enable */ + TFA2_BF_IPOADCCR = + 0x4ce0, /*!< Polarity Control ADC */ + TFA2_BF_IPOBODNOK = + 0x4cf0, /*!< Polarity BOD */ + TFA2_BF_IPOBSTCU = + 0x4d00, /*!< Polarity DCDC current limiting */ + TFA2_BF_IPOBSTHI = + 0x4d10, /*!< Polarity DCDC active */ + TFA2_BF_IPOBSTOC = + 0x4d20, /*!< Polarity DCDC OCP */ + TFA2_BF_IPOBSTPC = + 0x4d30, /*!< Polarity bst peakcur */ + TFA2_BF_IPOBSTVC = + 0x4d40, /*!< Polarity DCDC level 1x */ + TFA2_BF_IPOBST86 = + 0x4d50, /*!< Polarity DCDC level 1.14x */ + TFA2_BF_IPOBST93 = + 0x4d60, /*!< Polarity DCDC level 1.07x */ + TFA2_BF_IPORCVLD = + 0x4d70, /*!< Polarity rcvldop ready */ + TFA2_BF_IPOOCPL = + 0x4d80, /*!< Polarity ocp alarm left */ + TFA2_BF_IPOOCPR = + 0x4d90, /*!< Polarity ocp alarm right */ + TFA2_BF_IPOMWSRC = + 0x4da0, /*!< Polarity waits HW I2C settings */ + TFA2_BF_IPOMWCFC = + 0x4db0, /*!< Polarity man wait cf config */ + TFA2_BF_IPOMWSMU = + 0x4dc0, /*!< Polarity man audio mute sequence */ + TFA2_BF_IPOCFMER = + 0x4dd0, /*!< Polarity cfma err */ + TFA2_BF_IPOCFMAC = + 0x4de0, /*!< Polarity cfma ack */ + TFA2_BF_IPCLKOOR = + 0x4df0, /*!< Polarity flag_clk_out_of_range */ + TFA2_BF_IPOTDMER = + 0x4e00, /*!< Polarity tdm error */ + TFA2_BF_IPOCLPL = + 0x4e10, /*!< Polarity clip left */ + TFA2_BF_IPOCLPR = + 0x4e20, /*!< Polarity clip right */ + TFA2_BF_IPOOCPM = + 0x4e30, /*!< Polarity mic ocpok */ + TFA2_BF_BSSCR = + 0x5001, /*!< Battery protection attack Time */ + TFA2_BF_BSST = + 0x5023, /*!< Battery protection threshold voltage level */ + TFA2_BF_BSSRL = + 0x5061, /*!< Battery protection maximum reduction */ + TFA2_BF_BSSRR = + 0x5082, /*!< Battery protection release time */ + TFA2_BF_BSSHY = + 0x50b1, /*!< Battery protection hysteresis */ + TFA2_BF_BSSR = + 0x50e0, /*!< Battery voltage read out */ + TFA2_BF_BSSBY = + 0x50f0, /*!< Bypass HW clipper */ + TFA2_BF_BSSS = + 0x5100, /*!< Vbat prot steepness */ + TFA2_BF_INTSMUTE = + 0x5110, /*!< Soft mute HW */ + TFA2_BF_CFSML = + 0x5120, /*!< Soft mute FW left */ + TFA2_BF_CFSMR = + 0x5130, /*!< Soft mute FW right */ + TFA2_BF_HPFBYPL = + 0x5140, /*!< Bypass HPF left */ + TFA2_BF_HPFBYPR = + 0x5150, /*!< Bypass HPF right */ + TFA2_BF_DPSAL = + 0x5160, /*!< Enable DPSA left */ + TFA2_BF_DPSAR = + 0x5170, /*!< Enable DPSA right */ + TFA2_BF_VOL = + 0x5187, /*!< FW volume control for primary audio channel */ + TFA2_BF_HNDSFRCV = + 0x5200, /*!< Selection receiver */ + TFA2_BF_CLIPCTRL = + 0x5222, /*!< Clip control setting */ + TFA2_BF_AMPGAIN = + 0x5257, /*!< Amplifier gain */ + TFA2_BF_SLOPEE = + 0x52d0, /*!< Enables slope control */ + TFA2_BF_SLOPESET = + 0x52e1, /*!< Set slope */ + TFA2_BF_VOLSEC = + 0x5a07, /*!< FW volume control for secondary audio channel */ + TFA2_BF_SWPROFIL = + 0x5a87, /*!< Software profile data */ + TFA2_BF_DCVO = + 0x7002, /*!< Boost voltage */ + TFA2_BF_DCMCC = + 0x7033, /*!< Max coil current */ + TFA2_BF_DCCV = + 0x7071, /*!< Coil Value */ + TFA2_BF_DCIE = + 0x7090, /*!< Adaptive boost mode */ + TFA2_BF_DCSR = + 0x70a0, /*!< Soft ramp up/down */ + TFA2_BF_DCSYNCP = + 0x70b2, /*!< DCDC synchronization off + 7 positions */ + TFA2_BF_DCDIS = + 0x70e0, /*!< DCDC on/off */ + TFA2_BF_RST = + 0x9000, /*!< Reset */ + TFA2_BF_DMEM = + 0x9011, /*!< Target memory */ + TFA2_BF_AIF = + 0x9030, /*!< Auto increment */ + TFA2_BF_CFINT = + 0x9040, /*!< Interrupt - auto clear */ + TFA2_BF_CFCGATE = + 0x9050, /*!< Coolflux clock gating disabling control */ + TFA2_BF_REQ = + 0x9087, /*!< request for access (8 channels) */ + TFA2_BF_REQCMD = + 0x9080, /*!< Firmware event request rpc command */ + TFA2_BF_REQRST = + 0x9090, /*!< Firmware event request reset restart */ + TFA2_BF_REQMIPS = + 0x90a0, /*!< Firmware event request short on mips */ + TFA2_BF_REQMUTED = + 0x90b0, /*!< Firmware event request mute sequence ready */ + TFA2_BF_REQVOL = + 0x90c0, /*!< Firmware event request volume ready */ + TFA2_BF_REQDMG = + 0x90d0, /*!< Firmware event request speaker damage detected */ + TFA2_BF_REQCAL = + 0x90e0, /*!< Firmware event request calibration completed */ + TFA2_BF_REQRSV = + 0x90f0, /*!< Firmware event request reserved */ + TFA2_BF_MADD = + 0x910f, /*!< Memory address */ + TFA2_BF_MEMA = + 0x920f, /*!< Activate memory access */ + TFA2_BF_ERR = + 0x9307, /*!< Error flags */ + TFA2_BF_ACK = + 0x9387, /*!< Acknowledge of requests */ + TFA2_BF_ACKCMD = + 0x9380, /*!< Firmware event acknowledge rpc command */ + TFA2_BF_ACKRST = + 0x9390, /*!< Firmware event acknowledge reset restart */ + TFA2_BF_ACKMIPS = + 0x93a0, /*!< Firmware event acknowledge short on mips */ + TFA2_BF_ACKMUTED = + 0x93b0, /*!< Firmware event acknowledge mute sequence ready */ + TFA2_BF_ACKVOL = + 0x93c0, /*!< Firmware event acknowledge volume ready */ + TFA2_BF_ACKDMG = + 0x93d0, /*!< Firmware event acknowledge speaker damage detected */ + TFA2_BF_ACKCAL = + 0x93e0, /*!< Firmware event acknowledge calibration completed */ + TFA2_BF_ACKRSV = + 0x93f0, /*!< Firmware event acknowledge reserved */ + TFA2_BF_MTPK = + 0xa107, /*!< MTP KEY2 register */ + TFA2_BF_KEY1LOCKED = + 0xa200, /*!< Indicates KEY1 is locked */ + TFA2_BF_KEY2LOCKED = + 0xa210, /*!< Indicates KEY2 is locked */ + TFA2_BF_CIMTP = + 0xa360, /*!< Start copying data from I2C mtp registers to mtp */ + TFA2_BF_MTPRDMSB = + 0xa50f, /*!< MSB word of MTP manual read data */ + TFA2_BF_MTPRDLSB = + 0xa60f, /*!< LSB word of MTP manual read data */ + TFA2_BF_EXTTS = + 0xb108, /*!< External temperature (C) */ + TFA2_BF_TROS = + 0xb190, /*!< Select temp Speaker calibration */ + TFA2_BF_MTPOTC = + 0xf000, /*!< Calibration schedule */ + TFA2_BF_MTPEX = + 0xf010, /*!< Calibration Ron executed */ + TFA2_BF_DCMCCAPI = + 0xf020, /*!< Calibration current limit DCDC */ + TFA2_BF_DCMCCSB = + 0xf030, /*!< Sign bit for delta calibration current limit DCDC */ + TFA2_BF_USERDEF = + 0xf042, /*!< Calibration delta current limit DCDC */ + TFA2_BF_R25CL = + 0xf40f, /*!< Ron resistance of left channel speaker coil */ + TFA2_BF_R25CR = + 0xf50f, /*!< Ron resistance of right channel speaker coil */ +} nxpTfa2BfEnumList_t; +#define TFA2_NAMETABLE \ + static tfaBfName_t Tfa2DatasheetNames[] = { \ + { 0x0, \ + "PWDN" }, /* Powerdown selection , */ \ + { 0x10, \ + "I2CR" }, /* I2C Reset - Auto clear , */ \ + { 0x20, \ + "CFE" }, /* Enable CoolFlux , */ \ + { 0x30, \ + "AMPE" }, /* Activate Amplifier , */ \ + { 0x40, \ + "DCA" }, /* Activate DC-to-DC converter , */ \ + { 0x50, \ + "SBSL" }, /* Coolflux configured , */ \ + { 0x60, \ + "AMPC" }, /* CoolFlux controls amplifier , */ \ + { 0x71, \ + "INTP" }, /* Interrupt config , */ \ + { 0x91, \ + "FSSSEL" }, /* Audio sample reference , */ \ + { 0xb0, \ + "BYPOCP" }, /* Bypass OCP , */ \ + { 0xc0, \ + "TSTOCP" }, /* OCP testing control , */ \ + { 0x101, \ + "AMPINSEL" }, /* Amplifier input selection , */ \ + { 0x120, \ + "MANSCONF" }, /* I2C configured , */ \ + { 0x130, \ + "MANCOLD" }, /* Execute cold start , */ \ + { 0x140, \ + "MANAOOSC" }, /* Internal osc off at PWDN , */ \ + { 0x150, \ + "MANROBOD" }, /* Reaction on BOD , */ \ + { 0x160, \ + "BODE" }, /* BOD Enable , */ \ + { 0x170, \ + "BODHYS" }, /* BOD Hysteresis , */ \ + { 0x181, \ + "BODFILT" }, /* BOD filter , */ \ + { 0x1a1, \ + "BODTHLVL" }, /* BOD threshold , */ \ + { 0x1d0, \ + "MUTETO" }, /* Time out SB mute sequence , */ \ + { 0x1e0, \ + "RCVNS" }, /* Noise shaper selection , */ \ + { 0x1f0, \ + "MANWDE" }, /* Watchdog manager reaction , */ \ + { 0x203, \ + "AUDFS" }, /* Sample rate (fs) , */ \ + { 0x240, \ + "INPLEV" }, /* TDM output attenuation , */ \ + { 0x255, \ + "FRACTDEL" }, /* V/I Fractional delay , */ \ + { 0x2b0, \ + "BYPHVBF" }, /* Bypass HVBAT filter , */ \ + { 0x2c0, \ + "LDOBYP" }, /* Receiver LDO bypass , */ \ + { 0x30f, \ + "REV" }, /* Revision info , */ \ + { 0x401, \ + "REFCKEXT" }, /* PLL external ref clock , */ \ + { 0x420, \ + "REFCKSEL" }, /* PLL internal ref clock , */ \ + { 0x500, \ + "SSLEFTE" }, /* Enable left channel , */ \ + { 0x510, \ + "SSRIGHTE" }, /* Enable right channel , */ \ + { 0x520, \ + "VSLEFTE" }, /* Voltage sense left , */ \ + { 0x530, \ + "VSRIGHTE" }, /* Voltage sense right , */ \ + { 0x540, \ + "CSLEFTE" }, /* Current sense left , */ \ + { 0x550, \ + "CSRIGHTE" }, /* Current sense right , */ \ + { 0x560, \ + "SSPDME" }, /* Sub-system PDM , */ \ + { 0xd18, \ + "STGAIN" }, /* Side tone gain , */ \ + { 0xda0, \ + "PDMSMUTE" }, /* Side tone soft mute , */ \ + { 0xe06, \ + "SWVSTEP" }, /* Register for the host SW to record the current active vstep, */ \ + { 0x1000, \ + "VDDS" }, /* POR , */ \ + { 0x1010, \ + "PLLS" }, /* PLL lock , */ \ + { 0x1020, \ + "OTDS" }, /* OTP alarm , */ \ + { 0x1030, \ + "OVDS" }, /* OVP alarm , */ \ + { 0x1040, \ + "UVDS" }, /* UVP alarm , */ \ + { 0x1050, \ + "CLKS" }, /* Clocks stable , */ \ + { 0x1060, \ + "MTPB" }, /* MTP busy , */ \ + { 0x1070, \ + "NOCLK" }, /* Lost clock , */ \ + { 0x1080, \ + "SPKS" }, /* Speaker error , */ \ + { 0x1090, \ + "ACS" }, /* Cold Start , */ \ + { 0x10a0, \ + "SWS" }, /* Amplifier engage , */ \ + { 0x10b0, \ + "WDS" }, /* Watchdog , */ \ + { 0x10c0, \ + "AMPS" }, /* Amplifier enable , */ \ + { 0x10d0, \ + "AREFS" }, /* References enable , */ \ + { 0x10e0, \ + "ADCCR" }, /* Control ADC , */ \ + { 0x10f0, \ + "BODNOK" }, /* BOD , */ \ + { 0x1100, \ + "DCIL" }, /* DCDC current limiting , */ \ + { 0x1110, \ + "DCDCA" }, /* DCDC active , */ \ + { 0x1120, \ + "DCOCPOK" }, /* DCDC OCP nmos , */ \ + { 0x1140, \ + "DCHVBAT" }, /* DCDC level 1x , */ \ + { 0x1150, \ + "DCH114" }, /* DCDC level 1.14x , */ \ + { 0x1160, \ + "DCH107" }, /* DCDC level 1.07x , */ \ + { 0x1170, \ + "STMUTEB" }, /* side tone (un)mute busy , */ \ + { 0x1180, \ + "STMUTE" }, /* side tone mute state , */ \ + { 0x1190, \ + "TDMLUTER" }, /* TDM LUT error , */ \ + { 0x11a2, \ + "TDMSTAT" }, /* TDM status bits , */ \ + { 0x11d0, \ + "TDMERR" }, /* TDM error , */ \ + { 0x11e0, \ + "HAPTIC" }, /* Status haptic driver , */ \ + { 0x1200, \ + "OCPOAPL" }, /* OCPOK pmos A left , */ \ + { 0x1210, \ + "OCPOANL" }, /* OCPOK nmos A left , */ \ + { 0x1220, \ + "OCPOBPL" }, /* OCPOK pmos B left , */ \ + { 0x1230, \ + "OCPOBNL" }, /* OCPOK nmos B left , */ \ + { 0x1240, \ + "CLIPAHL" }, /* Clipping A left to Vddp , */ \ + { 0x1250, \ + "CLIPALL" }, /* Clipping A left to gnd , */ \ + { 0x1260, \ + "CLIPBHL" }, /* Clipping B left to Vddp , */ \ + { 0x1270, \ + "CLIPBLL" }, /* Clipping B left to gnd , */ \ + { 0x1280, \ + "OCPOAPRC" }, /* OCPOK pmos A RCV , */ \ + { 0x1290, \ + "OCPOANRC" }, /* OCPOK nmos A RCV , */ \ + { 0x12a0, \ + "OCPOBPRC" }, /* OCPOK pmos B RCV , */ \ + { 0x12b0, \ + "OCPOBNRC" }, /* OCPOK nmos B RCV , */ \ + { 0x12c0, \ + "RCVLDOR" }, /* RCV LDO regulates , */ \ + { 0x12d0, \ + "RCVLDOBR" }, /* Receiver LDO ready , */ \ + { 0x12e0, \ + "OCDSL" }, /* OCP left amplifier , */ \ + { 0x12f0, \ + "CLIPSL" }, /* Amplifier left clipping , */ \ + { 0x1300, \ + "OCPOAPR" }, /* OCPOK pmos A right , */ \ + { 0x1310, \ + "OCPOANR" }, /* OCPOK nmos A right , */ \ + { 0x1320, \ + "OCPOBPR" }, /* OCPOK pmos B right , */ \ + { 0x1330, \ + "OCPOBNR" }, /* OCPOK nmos B right , */ \ + { 0x1340, \ + "CLIPAHR" }, /* Clipping A right to Vddp , */ \ + { 0x1350, \ + "CLIPALR" }, /* Clipping A right to gnd , */ \ + { 0x1360, \ + "CLIPBHR" }, /* Clipping B left to Vddp , */ \ + { 0x1370, \ + "CLIPBLR" }, /* Clipping B right to gnd , */ \ + { 0x1380, \ + "OCDSR" }, /* OCP right amplifier , */ \ + { 0x1390, \ + "CLIPSR" }, /* Amplifier right clipping , */ \ + { 0x13a0, \ + "OCPOKMC" }, /* OCPOK MICVDD , */ \ + { 0x13b0, \ + "MANALARM" }, /* Alarm state , */ \ + { 0x13c0, \ + "MANWAIT1" }, /* Wait HW I2C settings , */ \ + { 0x13d0, \ + "MANWAIT2" }, /* Wait CF config , */ \ + { 0x13e0, \ + "MANMUTE" }, /* Audio mute sequence , */ \ + { 0x13f0, \ + "MANOPER" }, /* Operating state , */ \ + { 0x1400, \ + "SPKSL" }, /* Left speaker status , */ \ + { 0x1410, \ + "SPKSR" }, /* Right speaker status , */ \ + { 0x1420, \ + "CLKOOR" }, /* External clock status , */ \ + { 0x1433, \ + "MANSTATE" }, /* Device manager status , */ \ + { 0x1509, \ + "BATS" }, /* Battery voltage (V) , */ \ + { 0x1608, \ + "TEMPS" }, /* IC Temperature (C) , */ \ + { 0x2003, \ + "TDMUC" }, /* Usecase setting , */ \ + { 0x2040, \ + "TDME" }, /* Enable interface , */ \ + { 0x2050, \ + "TDMMODE" }, /* Slave/master , */ \ + { 0x2060, \ + "TDMCLINV" }, /* Reception data to BCK clock , */ \ + { 0x2073, \ + "TDMFSLN" }, /* FS length (master mode only) , */ \ + { 0x20b0, \ + "TDMFSPOL" }, /* FS polarity , */ \ + { 0x20c3, \ + "TDMNBCK" }, /* N-BCK's in FS , */ \ + { 0x2103, \ + "TDMSLOTS" }, /* N-slots in Frame , */ \ + { 0x2144, \ + "TDMSLLN" }, /* N-bits in slot , */ \ + { 0x2194, \ + "TDMBRMG" }, /* N-bits remaining , */ \ + { 0x21e0, \ + "TDMDEL" }, /* data delay to FS , */ \ + { 0x21f0, \ + "TDMADJ" }, /* data adjustment , */ \ + { 0x2201, \ + "TDMOOMP" }, /* Received audio compression , */ \ + { 0x2224, \ + "TDMSSIZE" }, /* Sample size per slot , */ \ + { 0x2271, \ + "TDMTXDFO" }, /* Format unused bits , */ \ + { 0x2291, \ + "TDMTXUS0" }, /* Format unused slots GAINIO , */ \ + { 0x22b1, \ + "TDMTXUS1" }, /* Format unused slots DIO1 , */ \ + { 0x22d1, \ + "TDMTXUS2" }, /* Format unused slots DIO2 , */ \ + { 0x2310, \ + "TDMLE" }, /* Control audio left , */ \ + { 0x2320, \ + "TDMRE" }, /* Control audio right , */ \ + { 0x2340, \ + "TDMVSRE" }, /* Control voltage sense right , */ \ + { 0x2350, \ + "TDMCSRE" }, /* Control current sense right , */ \ + { 0x2360, \ + "TDMVSLE" }, /* Voltage sense left control , */ \ + { 0x2370, \ + "TDMCSLE" }, /* Current sense left control , */ \ + { 0x2380, \ + "TDMCFRE" }, /* DSP out right control , */ \ + { 0x2390, \ + "TDMCFLE" }, /* DSP out left control , */ \ + { 0x23a0, \ + "TDMCF3E" }, /* AEC ref left control , */ \ + { 0x23b0, \ + "TDMCF4E" }, /* AEC ref right control , */ \ + { 0x23c0, \ + "TDMPD1E" }, /* PDM 1 control , */ \ + { 0x23d0, \ + "TDMPD2E" }, /* PDM 2 control , */ \ + { 0x2421, \ + "TDMLIO" }, /* IO audio left , */ \ + { 0x2441, \ + "TDMRIO" }, /* IO audio right , */ \ + { 0x2481, \ + "TDMVSRIO" }, /* IO voltage sense right , */ \ + { 0x24a1, \ + "TDMCSRIO" }, /* IO current sense right , */ \ + { 0x24c1, \ + "TDMVSLIO" }, /* IO voltage sense left , */ \ + { 0x24e1, \ + "TDMCSLIO" }, /* IO current sense left , */ \ + { 0x2501, \ + "TDMCFRIO" }, /* IO dspout right , */ \ + { 0x2521, \ + "TDMCFLIO" }, /* IO dspout left , */ \ + { 0x2541, \ + "TDMCF3IO" }, /* IO AEC ref left control , */ \ + { 0x2561, \ + "TDMCF4IO" }, /* IO AEC ref right control , */ \ + { 0x2581, \ + "TDMPD1IO" }, /* IO pdm1 , */ \ + { 0x25a1, \ + "TDMPD2IO" }, /* IO pdm2 , */ \ + { 0x2643, \ + "TDMLS" }, /* Position audio left , */ \ + { 0x2683, \ + "TDMRS" }, /* Position audio right , */ \ + { 0x2703, \ + "TDMVSRS" }, /* Position voltage sense right , */ \ + { 0x2743, \ + "TDMCSRS" }, /* Position current sense right , */ \ + { 0x2783, \ + "TDMVSLS" }, /* Position voltage sense left , */ \ + { 0x27c3, \ + "TDMCSLS" }, /* Position current sense left , */ \ + { 0x2803, \ + "TDMCFRS" }, /* Position dspout right , */ \ + { 0x2843, \ + "TDMCFLS" }, /* Position dspout left , */ \ + { 0x2883, \ + "TDMCF3S" }, /* Position AEC ref left control , */ \ + { 0x28c3, \ + "TDMCF4S" }, /* Position AEC ref right control , */ \ + { 0x2903, \ + "TDMPD1S" }, /* Position pdm1 , */ \ + { 0x2943, \ + "TDMPD2S" }, /* Position pdm2 , */ \ + { 0x3100, \ + "PDMSM" }, /* PDM control , */ \ + { 0x3111, \ + "PDMSTSEL" }, /* Side tone input , */ \ + { 0x3130, \ + "PDMLSEL" }, /* PDM data selection for left channel during PDM direct mode, */ \ + { 0x3140, \ + "PDMRSEL" }, /* PDM data selection for right channel during PDM direct mode, */ \ + { 0x3150, \ + "MICVDDE" }, /* Enable MICVDD , */ \ + { 0x3201, \ + "PDMCLRAT" }, /* PDM BCK/Fs ratio , */ \ + { 0x3223, \ + "PDMGAIN" }, /* PDM gain , */ \ + { 0x3263, \ + "PDMOSEL" }, /* PDM output selection - RE/FE data combination , */ \ + { 0x32a0, \ + "SELCFHAPD" }, /* Select the source for haptic data output (not for customer), */ \ + { 0x3307, \ + "HAPTIME" }, /* Duration (ms) , */ \ + { 0x3387, \ + "HAPLEVEL" }, /* DC value (FFS) , */ \ + { 0x3403, \ + "GPIODIN" }, /* Receiving value , */ \ + { 0x3500, \ + "GPIOCTRL" }, /* GPIO master control over GPIO1/2 ports (not for customer), */ \ + { 0x3513, \ + "GPIOCONF" }, /* Configuration , */ \ + { 0x3553, \ + "GPIODOUT" }, /* Transmitting value , */ \ + { 0x4000, \ + "ISTVDDS" }, /* Status POR , */ \ + { 0x4010, \ + "ISTPLLS" }, /* Status PLL lock , */ \ + { 0x4020, \ + "ISTOTDS" }, /* Status OTP alarm , */ \ + { 0x4030, \ + "ISTOVDS" }, /* Status OVP alarm , */ \ + { 0x4040, \ + "ISTUVDS" }, /* Status UVP alarm , */ \ + { 0x4050, \ + "ISTCLKS" }, /* Status clocks stable , */ \ + { 0x4060, \ + "ISTMTPB" }, /* Status MTP busy , */ \ + { 0x4070, \ + "ISTNOCLK" }, /* Status lost clock , */ \ + { 0x4080, \ + "ISTSPKS" }, /* Status speaker error , */ \ + { 0x4090, \ + "ISTACS" }, /* Status cold start , */ \ + { 0x40a0, \ + "ISTSWS" }, /* Status amplifier engage , */ \ + { 0x40b0, \ + "ISTWDS" }, /* Status watchdog , */ \ + { 0x40c0, \ + "ISTAMPS" }, /* Status amplifier enable , */ \ + { 0x40d0, \ + "ISTAREFS" }, /* Status Ref enable , */ \ + { 0x40e0, \ + "ISTADCCR" }, /* Status Control ADC , */ \ + { 0x40f0, \ + "ISTBODNOK" }, /* Status BOD , */ \ + { 0x4100, \ + "ISTBSTCU" }, /* Status DCDC current limiting , */ \ + { 0x4110, \ + "ISTBSTHI" }, /* Status DCDC active , */ \ + { 0x4120, \ + "ISTBSTOC" }, /* Status DCDC OCP , */ \ + { 0x4130, \ + "ISTBSTPKCUR" }, /* Status bst peakcur , */ \ + { 0x4140, \ + "ISTBSTVC" }, /* Status DCDC level 1x , */ \ + { 0x4150, \ + "ISTBST86" }, /* Status DCDC level 1.14x , */ \ + { 0x4160, \ + "ISTBST93" }, /* Status DCDC level 1.07x , */ \ + { 0x4170, \ + "ISTRCVLD" }, /* Status rcvldop ready , */ \ + { 0x4180, \ + "ISTOCPL" }, /* Status ocp alarm left , */ \ + { 0x4190, \ + "ISTOCPR" }, /* Status ocp alarm right , */ \ + { 0x41a0, \ + "ISTMWSRC" }, /* Status Waits HW I2C settings , */ \ + { 0x41b0, \ + "ISTMWCFC" }, /* Status waits CF config , */ \ + { 0x41c0, \ + "ISTMWSMU" }, /* Status Audio mute sequence , */ \ + { 0x41d0, \ + "ISTCFMER" }, /* Status cfma error , */ \ + { 0x41e0, \ + "ISTCFMAC" }, /* Status cfma ack , */ \ + { 0x41f0, \ + "ISTCLKOOR" }, /* Status flag_clk_out_of_range , */ \ + { 0x4200, \ + "ISTTDMER" }, /* Status tdm error , */ \ + { 0x4210, \ + "ISTCLPL" }, /* Status clip left , */ \ + { 0x4220, \ + "ISTCLPR" }, /* Status clip right , */ \ + { 0x4230, \ + "ISTOCPM" }, /* Status mic ocpok , */ \ + { 0x4400, \ + "ICLVDDS" }, /* Clear POR , */ \ + { 0x4410, \ + "ICLPLLS" }, /* Clear PLL lock , */ \ + { 0x4420, \ + "ICLOTDS" }, /* Clear OTP alarm , */ \ + { 0x4430, \ + "ICLOVDS" }, /* Clear OVP alarm , */ \ + { 0x4440, \ + "ICLUVDS" }, /* Clear UVP alarm , */ \ + { 0x4450, \ + "ICLCLKS" }, /* Clear clocks stable , */ \ + { 0x4460, \ + "ICLMTPB" }, /* Clear mtp busy , */ \ + { 0x4470, \ + "ICLNOCLK" }, /* Clear lost clk , */ \ + { 0x4480, \ + "ICLSPKS" }, /* Clear speaker error , */ \ + { 0x4490, \ + "ICLACS" }, /* Clear cold started , */ \ + { 0x44a0, \ + "ICLSWS" }, /* Clear amplifier engage , */ \ + { 0x44b0, \ + "ICLWDS" }, /* Clear watchdog , */ \ + { 0x44c0, \ + "ICLAMPS" }, /* Clear enbl amp , */ \ + { 0x44d0, \ + "ICLAREFS" }, /* Clear ref enable , */ \ + { 0x44e0, \ + "ICLADCCR" }, /* Clear control ADC , */ \ + { 0x44f0, \ + "ICLBODNOK" }, /* Clear BOD , */ \ + { 0x4500, \ + "ICLBSTCU" }, /* Clear DCDC current limiting , */ \ + { 0x4510, \ + "ICLBSTHI" }, /* Clear DCDC active , */ \ + { 0x4520, \ + "ICLBSTOC" }, /* Clear DCDC OCP , */ \ + { 0x4530, \ + "ICLBSTPC" }, /* Clear bst peakcur , */ \ + { 0x4540, \ + "ICLBSTVC" }, /* Clear DCDC level 1x , */ \ + { 0x4550, \ + "ICLBST86" }, /* Clear DCDC level 1.14x , */ \ + { 0x4560, \ + "ICLBST93" }, /* Clear DCDC level 1.07x , */ \ + { 0x4570, \ + "ICLRCVLD" }, /* Clear rcvldop ready , */ \ + { 0x4580, \ + "ICLOCPL" }, /* Clear ocp alarm left , */ \ + { 0x4590, \ + "ICLOCPR" }, /* Clear ocp alarm right , */ \ + { 0x45a0, \ + "ICLMWSRC" }, /* Clear wait HW I2C settings , */ \ + { 0x45b0, \ + "ICLMWCFC" }, /* Clear wait cf config , */ \ + { 0x45c0, \ + "ICLMWSMU" }, /* Clear audio mute sequence , */ \ + { 0x45d0, \ + "ICLCFMER" }, /* Clear cfma err , */ \ + { 0x45e0, \ + "ICLCFMAC" }, /* Clear cfma ack , */ \ + { 0x45f0, \ + "ICLCLKOOR" }, /* Clear flag_clk_out_of_range , */ \ + { 0x4600, \ + "ICLTDMER" }, /* Clear tdm error , */ \ + { 0x4610, \ + "ICLCLPL" }, /* Clear clip left , */ \ + { 0x4620, \ + "ICLCLPR" }, /* Clear clip right , */ \ + { 0x4630, \ + "ICLOCPM" }, /* Clear mic ocpok , */ \ + { 0x4800, \ + "IEVDDS" }, /* Enable por , */ \ + { 0x4810, \ + "IEPLLS" }, /* Enable pll lock , */ \ + { 0x4820, \ + "IEOTDS" }, /* Enable OTP alarm , */ \ + { 0x4830, \ + "IEOVDS" }, /* Enable OVP alarm , */ \ + { 0x4840, \ + "IEUVDS" }, /* Enable UVP alarm , */ \ + { 0x4850, \ + "IECLKS" }, /* Enable clocks stable , */ \ + { 0x4860, \ + "IEMTPB" }, /* Enable mtp busy , */ \ + { 0x4870, \ + "IENOCLK" }, /* Enable lost clk , */ \ + { 0x4880, \ + "IESPKS" }, /* Enable speaker error , */ \ + { 0x4890, \ + "IEACS" }, /* Enable cold started , */ \ + { 0x48a0, \ + "IESWS" }, /* Enable amplifier engage , */ \ + { 0x48b0, \ + "IEWDS" }, /* Enable watchdog , */ \ + { 0x48c0, \ + "IEAMPS" }, /* Enable enbl amp , */ \ + { 0x48d0, \ + "IEAREFS" }, /* Enable ref enable , */ \ + { 0x48e0, \ + "IEADCCR" }, /* Enable Control ADC , */ \ + { 0x48f0, \ + "IEBODNOK" }, /* Enable BOD , */ \ + { 0x4900, \ + "IEBSTCU" }, /* Enable DCDC current limiting , */ \ + { 0x4910, \ + "IEBSTHI" }, /* Enable DCDC active , */ \ + { 0x4920, \ + "IEBSTOC" }, /* Enable DCDC OCP , */ \ + { 0x4930, \ + "IEBSTPC" }, /* Enable bst peakcur , */ \ + { 0x4940, \ + "IEBSTVC" }, /* Enable DCDC level 1x , */ \ + { 0x4950, \ + "IEBST86" }, /* Enable DCDC level 1.14x , */ \ + { 0x4960, \ + "IEBST93" }, /* Enable DCDC level 1.07x , */ \ + { 0x4970, \ + "IERCVLD" }, /* Enable rcvldop ready , */ \ + { 0x4980, \ + "IEOCPL" }, /* Enable ocp alarm left , */ \ + { 0x4990, \ + "IEOCPR" }, /* Enable ocp alarm right , */ \ + { 0x49a0, \ + "IEMWSRC" }, /* Enable waits HW I2C settings , */ \ + { 0x49b0, \ + "IEMWCFC" }, /* Enable man wait cf config , */ \ + { 0x49c0, \ + "IEMWSMU" }, /* Enable man Audio mute sequence , */ \ + { 0x49d0, \ + "IECFMER" }, /* Enable cfma err , */ \ + { 0x49e0, \ + "IECFMAC" }, /* Enable cfma ack , */ \ + { 0x49f0, \ + "IECLKOOR" }, /* Enable flag_clk_out_of_range , */ \ + { 0x4a00, \ + "IETDMER" }, /* Enable tdm error , */ \ + { 0x4a10, \ + "IECLPL" }, /* Enable clip left , */ \ + { 0x4a20, \ + "IECLPR" }, /* Enable clip right , */ \ + { 0x4a30, \ + "IEOCPM1" }, /* Enable mic ocpok , */ \ + { 0x4c00, \ + "IPOVDDS" }, /* Polarity por , */ \ + { 0x4c10, \ + "IPOPLLS" }, /* Polarity pll lock , */ \ + { 0x4c20, \ + "IPOOTDS" }, /* Polarity OTP alarm , */ \ + { 0x4c30, \ + "IPOOVDS" }, /* Polarity OVP alarm , */ \ + { 0x4c40, \ + "IPOUVDS" }, /* Polarity UVP alarm , */ \ + { 0x4c50, \ + "IPOCLKS" }, /* Polarity clocks stable , */ \ + { 0x4c60, \ + "IPOMTPB" }, /* Polarity mtp busy , */ \ + { 0x4c70, \ + "IPONOCLK" }, /* Polarity lost clk , */ \ + { 0x4c80, \ + "IPOSPKS" }, /* Polarity speaker error , */ \ + { 0x4c90, \ + "IPOACS" }, /* Polarity cold started , */ \ + { 0x4ca0, \ + "IPOSWS" }, /* Polarity amplifier engage , */ \ + { 0x4cb0, \ + "IPOWDS" }, /* Polarity watchdog , */ \ + { 0x4cc0, \ + "IPOAMPS" }, /* Polarity enbl amp , */ \ + { 0x4cd0, \ + "IPOAREFS" }, /* Polarity ref enable , */ \ + { 0x4ce0, \ + "IPOADCCR" }, /* Polarity Control ADC , */ \ + { 0x4cf0, \ + "IPOBODNOK" }, /* Polarity BOD , */ \ + { 0x4d00, \ + "IPOBSTCU" }, /* Polarity DCDC current limiting , */ \ + { 0x4d10, \ + "IPOBSTHI" }, /* Polarity DCDC active , */ \ + { 0x4d20, \ + "IPOBSTOC" }, /* Polarity DCDC OCP , */ \ + { 0x4d30, \ + "IPOBSTPC" }, /* Polarity bst peakcur , */ \ + { 0x4d40, \ + "IPOBSTVC" }, /* Polarity DCDC level 1x , */ \ + { 0x4d50, \ + "IPOBST86" }, /* Polarity DCDC level 1.14x , */ \ + { 0x4d60, \ + "IPOBST93" }, /* Polarity DCDC level 1.07x , */ \ + { 0x4d70, \ + "IPORCVLD" }, /* Polarity rcvldop ready , */ \ + { 0x4d80, \ + "IPOOCPL" }, /* Polarity ocp alarm left , */ \ + { 0x4d90, \ + "IPOOCPR" }, /* Polarity ocp alarm right , */ \ + { 0x4da0, \ + "IPOMWSRC" }, /* Polarity waits HW I2C settings , */ \ + { 0x4db0, \ + "IPOMWCFC" }, /* Polarity man wait cf config , */ \ + { 0x4dc0, \ + "IPOMWSMU" }, /* Polarity man audio mute sequence , */ \ + { 0x4dd0, \ + "IPOCFMER" }, /* Polarity cfma err , */ \ + { 0x4de0, \ + "IPOCFMAC" }, /* Polarity cfma ack , */ \ + { 0x4df0, \ + "IPCLKOOR" }, /* Polarity flag_clk_out_of_range , */ \ + { 0x4e00, \ + "IPOTDMER" }, /* Polarity tdm error , */ \ + { 0x4e10, \ + "IPOCLPL" }, /* Polarity clip left , */ \ + { 0x4e20, \ + "IPOCLPR" }, /* Polarity clip right , */ \ + { 0x4e30, \ + "IPOOCPM" }, /* Polarity mic ocpok , */ \ + { 0x5001, \ + "BSSCR" }, /* Battery protection attack Time , */ \ + { 0x5023, \ + "BSST" }, /* Battery protection threshold voltage level , */ \ + { 0x5061, \ + "BSSRL" }, /* Battery protection maximum reduction , */ \ + { 0x5082, \ + "BSSRR" }, /* Battery protection release time , */ \ + { 0x50b1, \ + "BSSHY" }, /* Battery protection hysteresis , */ \ + { 0x50e0, \ + "BSSR" }, /* Battery voltage read out , */ \ + { 0x50f0, \ + "BSSBY" }, /* Bypass HW clipper , */ \ + { 0x5100, \ + "BSSS" }, /* Vbat prot steepness , */ \ + { 0x5110, \ + "INTSMUTE" }, /* Soft mute HW , */ \ + { 0x5120, \ + "CFSML" }, /* Soft mute FW left , */ \ + { 0x5130, \ + "CFSMR" }, /* Soft mute FW right , */ \ + { 0x5140, \ + "HPFBYPL" }, /* Bypass HPF left , */ \ + { 0x5150, \ + "HPFBYPR" }, /* Bypass HPF right , */ \ + { 0x5160, \ + "DPSAL" }, /* Enable DPSA left , */ \ + { 0x5170, \ + "DPSAR" }, /* Enable DPSA right , */ \ + { 0x5187, \ + "VOL" }, /* FW volume control for primary audio channel , */ \ + { 0x5200, \ + "HNDSFRCV" }, /* Selection receiver , */ \ + { 0x5222, \ + "CLIPCTRL" }, /* Clip control setting , */ \ + { 0x5257, \ + "AMPGAIN" }, /* Amplifier gain , */ \ + { 0x52d0, \ + "SLOPEE" }, /* Enables slope control , */ \ + { 0x52e1, \ + "SLOPESET" }, /* Set slope , */ \ + { 0x5a07, \ + "VOLSEC" }, /* FW volume control for secondary audio channel , */ \ + { 0x5a87, \ + "SWPROFIL" }, /* Software profile data , */ \ + { 0x7002, \ + "DCVO" }, /* Boost voltage , */ \ + { 0x7033, \ + "DCMCC" }, /* Max coil current , */ \ + { 0x7071, \ + "DCCV" }, /* Coil Value , */ \ + { 0x7090, \ + "DCIE" }, /* Adaptive boost mode , */ \ + { 0x70a0, \ + "DCSR" }, /* Soft ramp up/down , */ \ + { 0x70b2, \ + "DCSYNCP" }, /* DCDC synchronization off + 7 positions , */ \ + { 0x70e0, \ + "DCDIS" }, /* DCDC on/off , */ \ + { 0x9000, \ + "RST" }, /* Reset , */ \ + { 0x9011, \ + "DMEM" }, /* Target memory , */ \ + { 0x9030, \ + "AIF" }, /* Auto increment , */ \ + { 0x9040, \ + "CFINT" }, /* Interrupt - auto clear , */ \ + { 0x9050, \ + "CFCGATE" }, /* Coolflux clock gating disabling control , */ \ + { 0x9080, \ + "REQCMD" }, /* Firmware event request rpc command , */ \ + { 0x9090, \ + "REQRST" }, /* Firmware event request reset restart , */ \ + { 0x90a0, \ + "REQMIPS" }, /* Firmware event request short on mips , */ \ + { 0x90b0, \ + "REQMUTED" }, /* Firmware event request mute sequence ready , */ \ + { 0x90c0, \ + "REQVOL" }, /* Firmware event request volume ready , */ \ + { 0x90d0, \ + "REQDMG" }, /* Firmware event request speaker damage detected , */ \ + { 0x90e0, \ + "REQCAL" }, /* Firmware event request calibration completed , */ \ + { 0x90f0, \ + "REQRSV" }, /* Firmware event request reserved , */ \ + { 0x910f, \ + "MADD" }, /* Memory address , */ \ + { 0x920f, \ + "MEMA" }, /* Activate memory access , */ \ + { 0x9307, \ + "ERR" }, /* Error flags , */ \ + { 0x9387, \ + "ACK" }, /* Acknowledge of requests , */ \ + { 0x9380, \ + "ACKCMD" }, /* Firmware event acknowledge rpc command , */ \ + { 0x9390, \ + "ACKRST" }, /* Firmware event acknowledge reset restart , */ \ + { 0x93a0, \ + "ACKMIPS" }, /* Firmware event acknowledge short on mips , */ \ + { 0x93b0, \ + "ACKMUTED" }, /* Firmware event acknowledge mute sequence ready , */ \ + { 0x93c0, \ + "ACKVOL" }, /* Firmware event acknowledge volume ready , */ \ + { 0x93d0, \ + "ACKDMG" }, /* Firmware event acknowledge speaker damage detected, */ \ + { 0x93e0, \ + "ACKCAL" }, /* Firmware event acknowledge calibration completed , */ \ + { 0x93f0, \ + "ACKRSV" }, /* Firmware event acknowledge reserved , */ \ + { 0xa107, \ + "MTPK" }, /* MTP KEY2 register , */ \ + { 0xa200, \ + "KEY1LOCKED" }, /* Indicates KEY1 is locked , */ \ + { 0xa210, \ + "KEY2LOCKED" }, /* Indicates KEY2 is locked , */ \ + { 0xa360, \ + "CIMTP" }, /* Start copying data from I2C mtp registers to mtp , */ \ + { 0xa50f, \ + "MTPRDMSB" }, /* MSB word of MTP manual read data , */ \ + { 0xa60f, \ + "MTPRDLSB" }, /* LSB word of MTP manual read data , */ \ + { 0xb108, \ + "EXTTS" }, /* External temperature (C) , */ \ + { 0xb190, \ + "TROS" }, /* Select temp Speaker calibration , */ \ + { 0xf000, \ + "MTPOTC" }, /* Calibration schedule , */ \ + { 0xf010, \ + "MTPEX" }, /* Calibration Ron executed , */ \ + { 0xf020, \ + "DCMCCAPI" }, /* Calibration current limit DCDC , */ \ + { 0xf030, \ + "DCMCCSB" }, /* Sign bit for delta calibration current limit DCDC , */ \ + { 0xf042, \ + "USERDEF" }, /* Calibration delta current limit DCDC , */ \ + { 0xf40f, \ + "R25CL" }, /* Ron resistance of left channel speaker coil , */ \ + { 0xf50f, \ + "R25CR" }, /* Ron resistance of right channel speaker coil , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +#define TFA2_BITNAMETABLE \ + static tfaBfName_t Tfa2BitNames[] = { \ + { 0x0, \ + "powerdown" }, /* Powerdown selection , */ \ + { 0x10, \ + "reset" }, /* I2C Reset - Auto clear , */ \ + { 0x20, \ + "enbl_coolflux" }, /* Enable CoolFlux , */ \ + { 0x30, \ + "enbl_amplifier" }, /* Activate Amplifier , */ \ + { 0x40, \ + "enbl_boost" }, /* Activate DC-to-DC converter , */ \ + { 0x50, \ + "coolflux_configured" }, /* Coolflux configured , */ \ + { 0x60, \ + "sel_enbl_amplifier" }, /* CoolFlux controls amplifier , */ \ + { 0x71, \ + "int_pad_io" }, /* Interrupt config , */ \ + { 0x91, \ + "fs_pulse_sel" }, /* Audio sample reference , */ \ + { 0xb0, \ + "bypass_ocp" }, /* Bypass OCP , */ \ + { 0xc0, \ + "test_ocp" }, /* OCP testing control , */ \ + { 0x101, \ + "vamp_sel" }, /* Amplifier input selection , */ \ + { 0x120, \ + "src_set_configured" }, /* I2C configured , */ \ + { 0x130, \ + "execute_cold_start" }, /* Execute cold start , */ \ + { 0x140, \ + "enbl_osc1m_auto_off" }, /* Internal osc off at PWDN , */ \ + { 0x150, \ + "man_enbl_brown_out" }, /* Reaction on BOD , */ \ + { 0x160, \ + "enbl_bod" }, /* BOD Enable , */ \ + { 0x170, \ + "enbl_bod_hyst" }, /* BOD Hysteresis , */ \ + { 0x181, \ + "bod_delay" }, /* BOD filter , */ \ + { 0x1a1, \ + "bod_lvlsel" }, /* BOD threshold , */ \ + { 0x1d0, \ + "disable_mute_time_out" }, /* Time out SB mute sequence , */ \ + { 0x1e0, \ + "pwm_sel_rcv_ns" }, /* Noise shaper selection , */ \ + { 0x1f0, \ + "man_enbl_watchdog" }, /* Watchdog manager reaction , */ \ + { 0x203, \ + "audio_fs" }, /* Sample rate (fs) , */ \ + { 0x240, \ + "input_level" }, /* TDM output attenuation , */ \ + { 0x255, \ + "cs_frac_delay" }, /* V/I Fractional delay , */ \ + { 0x2b0, \ + "bypass_hvbat_filter" }, /* Bypass HVBAT filter , */ \ + { 0x2c0, \ + "ctrl_rcvldop_bypass" }, /* Receiver LDO bypass , */ \ + { 0x30f, \ + "device_rev" }, /* Revision info , */ \ + { 0x401, \ + "pll_clkin_sel" }, /* PLL external ref clock , */ \ + { 0x420, \ + "pll_clkin_sel_osc" }, /* PLL internal ref clock , */ \ + { 0x500, \ + "enbl_spkr_ss_left" }, /* Enable left channel , */ \ + { 0x510, \ + "enbl_spkr_ss_right" }, /* Enable right channel , */ \ + { 0x520, \ + "enbl_volsense_left" }, /* Voltage sense left , */ \ + { 0x530, \ + "enbl_volsense_right" }, /* Voltage sense right , */ \ + { 0x540, \ + "enbl_cursense_left" }, /* Current sense left , */ \ + { 0x550, \ + "enbl_cursense_right" }, /* Current sense right , */ \ + { 0x560, \ + "enbl_pdm_ss" }, /* Sub-system PDM , */ \ + { 0xd00, \ + "side_tone_gain_sel" }, /* PDM side tone gain selector , */ \ + { 0xd18, \ + "side_tone_gain" }, /* Side tone gain , */ \ + { 0xda0, \ + "mute_side_tone" }, /* Side tone soft mute , */ \ + { 0xe06, \ + "ctrl_digtoana" }, /* Register for the host SW to record the current active vstep, */ \ + { 0xe70, \ + "enbl_cmfb_left" }, /* Current sense common mode feedback control for left channel, */ \ + { 0xf0f, \ + "hidden_code" }, /* 5A6Bh, 23147d to access registers (default for engineering), */ \ + { 0x1000, \ + "flag_por" }, /* POR , */ \ + { 0x1010, \ + "flag_pll_lock" }, /* PLL lock , */ \ + { 0x1020, \ + "flag_otpok" }, /* OTP alarm , */ \ + { 0x1030, \ + "flag_ovpok" }, /* OVP alarm , */ \ + { 0x1040, \ + "flag_uvpok" }, /* UVP alarm , */ \ + { 0x1050, \ + "flag_clocks_stable" }, /* Clocks stable , */ \ + { 0x1060, \ + "flag_mtp_busy" }, /* MTP busy , */ \ + { 0x1070, \ + "flag_lost_clk" }, /* Lost clock , */ \ + { 0x1080, \ + "flag_cf_speakererror" }, /* Speaker error , */ \ + { 0x1090, \ + "flag_cold_started" }, /* Cold Start , */ \ + { 0x10a0, \ + "flag_engage" }, /* Amplifier engage , */ \ + { 0x10b0, \ + "flag_watchdog_reset" }, /* Watchdog , */ \ + { 0x10c0, \ + "flag_enbl_amp" }, /* Amplifier enable , */ \ + { 0x10d0, \ + "flag_enbl_ref" }, /* References enable , */ \ + { 0x10e0, \ + "flag_adc10_ready" }, /* Control ADC , */ \ + { 0x10f0, \ + "flag_bod_vddd_nok" }, /* BOD , */ \ + { 0x1100, \ + "flag_bst_bstcur" }, /* DCDC current limiting , */ \ + { 0x1110, \ + "flag_bst_hiz" }, /* DCDC active , */ \ + { 0x1120, \ + "flag_bst_ocpok" }, /* DCDC OCP nmos , */ \ + { 0x1130, \ + "flag_bst_peakcur" }, /* Indicates current is max in DC-to-DC converter , */ \ + { 0x1140, \ + "flag_bst_voutcomp" }, /* DCDC level 1x , */ \ + { 0x1150, \ + "flag_bst_voutcomp86" }, /* DCDC level 1.14x , */ \ + { 0x1160, \ + "flag_bst_voutcomp93" }, /* DCDC level 1.07x , */ \ + { 0x1170, \ + "flag_soft_mute_busy" }, /* side tone (un)mute busy , */ \ + { 0x1180, \ + "flag_soft_mute_state" }, /* side tone mute state , */ \ + { 0x1190, \ + "flag_tdm_lut_error" }, /* TDM LUT error , */ \ + { 0x11a2, \ + "flag_tdm_status" }, /* TDM status bits , */ \ + { 0x11d0, \ + "flag_tdm_error" }, /* TDM error , */ \ + { 0x11e0, \ + "flag_haptic_busy" }, /* Status haptic driver , */ \ + { 0x1200, \ + "flag_ocpokap_left" }, /* OCPOK pmos A left , */ \ + { 0x1210, \ + "flag_ocpokan_left" }, /* OCPOK nmos A left , */ \ + { 0x1220, \ + "flag_ocpokbp_left" }, /* OCPOK pmos B left , */ \ + { 0x1230, \ + "flag_ocpokbn_left" }, /* OCPOK nmos B left , */ \ + { 0x1240, \ + "flag_clipa_high_left" }, /* Clipping A left to Vddp , */ \ + { 0x1250, \ + "flag_clipa_low_left" }, /* Clipping A left to gnd , */ \ + { 0x1260, \ + "flag_clipb_high_left" }, /* Clipping B left to Vddp , */ \ + { 0x1270, \ + "flag_clipb_low_left" }, /* Clipping B left to gnd , */ \ + { 0x1280, \ + "flag_ocpokap_rcv" }, /* OCPOK pmos A RCV , */ \ + { 0x1290, \ + "flag_ocpokan_rcv" }, /* OCPOK nmos A RCV , */ \ + { 0x12a0, \ + "flag_ocpokbp_rcv" }, /* OCPOK pmos B RCV , */ \ + { 0x12b0, \ + "flag_ocpokbn_rcv" }, /* OCPOK nmos B RCV , */ \ + { 0x12c0, \ + "flag_rcvldop_ready" }, /* RCV LDO regulates , */ \ + { 0x12d0, \ + "flag_rcvldop_bypassready" }, /* Receiver LDO ready , */ \ + { 0x12e0, \ + "flag_ocp_alarm_left" }, /* OCP left amplifier , */ \ + { 0x12f0, \ + "flag_clip_left" }, /* Amplifier left clipping , */ \ + { 0x1300, \ + "flag_ocpokap_right" }, /* OCPOK pmos A right , */ \ + { 0x1310, \ + "flag_ocpokan_right" }, /* OCPOK nmos A right , */ \ + { 0x1320, \ + "flag_ocpokbp_right" }, /* OCPOK pmos B right , */ \ + { 0x1330, \ + "flag_ocpokbn_right" }, /* OCPOK nmos B right , */ \ + { 0x1340, \ + "flag_clipa_high_right" }, /* Clipping A right to Vddp , */ \ + { 0x1350, \ + "flag_clipa_low_right" }, /* Clipping A right to gnd , */ \ + { 0x1360, \ + "flag_clipb_high_right" }, /* Clipping B left to Vddp , */ \ + { 0x1370, \ + "flag_clipb_low_right" }, /* Clipping B right to gnd , */ \ + { 0x1380, \ + "flag_ocp_alarm_right" }, /* OCP right amplifier , */ \ + { 0x1390, \ + "flag_clip_right" }, /* Amplifier right clipping , */ \ + { 0x13a0, \ + "flag_mic_ocpok" }, /* OCPOK MICVDD , */ \ + { 0x13b0, \ + "flag_man_alarm_state" }, /* Alarm state , */ \ + { 0x13c0, \ + "flag_man_wait_src_settings" }, /* Wait HW I2C settings , */ \ + { 0x13d0, \ + "flag_man_wait_cf_config" }, /* Wait CF config , */ \ + { 0x13e0, \ + "flag_man_start_mute_audio" }, /* Audio mute sequence , */ \ + { 0x13f0, \ + "flag_man_operating_state" }, /* Operating state , */ \ + { 0x1400, \ + "flag_cf_speakererror_left" }, /* Left speaker status , */ \ + { 0x1410, \ + "flag_cf_speakererror_right" }, /* Right speaker status , */ \ + { 0x1420, \ + "flag_clk_out_of_range" }, /* External clock status , */ \ + { 0x1433, \ + "man_state" }, /* Device manager status , */ \ + { 0x1509, \ + "bat_adc" }, /* Battery voltage (V) , */ \ + { 0x1608, \ + "temp_adc" }, /* IC Temperature (C) , */ \ + { 0x2003, \ + "tdm_usecase" }, /* Usecase setting , */ \ + { 0x2040, \ + "tdm_enable" }, /* Enable interface , */ \ + { 0x2050, \ + "tdm_mode" }, /* Slave/master , */ \ + { 0x2060, \ + "tdm_clk_inversion" }, /* Reception data to BCK clock , */ \ + { 0x2073, \ + "tdm_fs_ws_length" }, /* FS length (master mode only) , */ \ + { 0x20b0, \ + "tdm_fs_ws_polarity" }, /* FS polarity , */ \ + { 0x20c3, \ + "tdm_nbck" }, /* N-BCK's in FS , */ \ + { 0x2103, \ + "tdm_nb_of_slots" }, /* N-slots in Frame , */ \ + { 0x2144, \ + "tdm_slot_length" }, /* N-bits in slot , */ \ + { 0x2194, \ + "tdm_bits_remaining" }, /* N-bits remaining , */ \ + { 0x21e0, \ + "tdm_data_delay" }, /* data delay to FS , */ \ + { 0x21f0, \ + "tdm_data_adjustment" }, /* data adjustment , */ \ + { 0x2201, \ + "tdm_audio_sample_compression" }, /* Received audio compression , */ \ + { 0x2224, \ + "tdm_sample_size" }, /* Sample size per slot , */ \ + { 0x2271, \ + "tdm_txdata_format" }, /* Format unused bits , */ \ + { 0x2291, \ + "tdm_txdata_format_unused_slot_sd0" }, /* Format unused slots GAINIO , */ \ + { 0x22b1, \ + "tdm_txdata_format_unused_slot_sd1" }, /* Format unused slots DIO1 , */ \ + { 0x22d1, \ + "tdm_txdata_format_unused_slot_sd2" }, /* Format unused slots DIO2 , */ \ + { 0x2300, \ + "tdm_sink0_enable" }, /* Control gainin (not used in DSP) , */ \ + { 0x2310, \ + "tdm_sink1_enable" }, /* Control audio left , */ \ + { 0x2320, \ + "tdm_sink2_enable" }, /* Control audio right , */ \ + { 0x2330, \ + "tdm_source0_enable" }, /* Control gainout (not used in DSP) , */ \ + { 0x2340, \ + "tdm_source1_enable" }, /* Control voltage sense right , */ \ + { 0x2350, \ + "tdm_source2_enable" }, /* Control current sense right , */ \ + { 0x2360, \ + "tdm_source3_enable" }, /* Voltage sense left control , */ \ + { 0x2370, \ + "tdm_source4_enable" }, /* Current sense left control , */ \ + { 0x2380, \ + "tdm_source5_enable" }, /* DSP out right control , */ \ + { 0x2390, \ + "tdm_source6_enable" }, /* DSP out left control , */ \ + { 0x23a0, \ + "tdm_source7_enable" }, /* AEC ref left control , */ \ + { 0x23b0, \ + "tdm_source8_enable" }, /* AEC ref right control , */ \ + { 0x23c0, \ + "tdm_source9_enable" }, /* PDM 1 control , */ \ + { 0x23d0, \ + "tdm_source10_enable" }, /* PDM 2 control , */ \ + { 0x2401, \ + "tdm_sink0_io" }, /* IO gainin (not used in DSP) , */ \ + { 0x2421, \ + "tdm_sink1_io" }, /* IO audio left , */ \ + { 0x2441, \ + "tdm_sink2_io" }, /* IO audio right , */ \ + { 0x2461, \ + "tdm_source0_io" }, /* IO gainout (not used in DSP) , */ \ + { 0x2481, \ + "tdm_source1_io" }, /* IO voltage sense right , */ \ + { 0x24a1, \ + "tdm_source2_io" }, /* IO current sense right , */ \ + { 0x24c1, \ + "tdm_source3_io" }, /* IO voltage sense left , */ \ + { 0x24e1, \ + "tdm_source4_io" }, /* IO current sense left , */ \ + { 0x2501, \ + "tdm_source5_io" }, /* IO dspout right , */ \ + { 0x2521, \ + "tdm_source6_io" }, /* IO dspout left , */ \ + { 0x2541, \ + "tdm_source7_io" }, /* IO AEC ref left control , */ \ + { 0x2561, \ + "tdm_source8_io" }, /* IO AEC ref right control , */ \ + { 0x2581, \ + "tdm_source9_io" }, /* IO pdm1 , */ \ + { 0x25a1, \ + "tdm_source10_io" }, /* IO pdm2 , */ \ + { 0x2603, \ + "tdm_sink0_slot" }, /* Position gainin (not used in DSP) , */ \ + { 0x2643, \ + "tdm_sink1_slot" }, /* Position audio left , */ \ + { 0x2683, \ + "tdm_sink2_slot" }, /* Position audio right , */ \ + { 0x26c3, \ + "tdm_source0_slot" }, /* Position gainout (not used in DSP) , */ \ + { 0x2703, \ + "tdm_source1_slot" }, /* Position voltage sense right , */ \ + { 0x2743, \ + "tdm_source2_slot" }, /* Position current sense right , */ \ + { 0x2783, \ + "tdm_source3_slot" }, /* Position voltage sense left , */ \ + { 0x27c3, \ + "tdm_source4_slot" }, /* Position current sense left , */ \ + { 0x2803, \ + "tdm_source5_slot" }, /* Position dspout right , */ \ + { 0x2843, \ + "tdm_source6_slot" }, /* Position dspout left , */ \ + { 0x2883, \ + "tdm_source7_slot" }, /* Position AEC ref left control , */ \ + { 0x28c3, \ + "tdm_source8_slot" }, /* Position AEC ref right control , */ \ + { 0x2903, \ + "tdm_source9_slot" }, /* Position pdm1 , */ \ + { 0x2943, \ + "tdm_source10_slot" }, /* Position pdm2 , */ \ + { 0x3100, \ + "pdm_mode" }, /* PDM control , */ \ + { 0x3111, \ + "pdm_side_tone_sel" }, /* Side tone input , */ \ + { 0x3130, \ + "pdm_left_sel" }, /* PDM data selection for left channel during PDM direct mode, */ \ + { 0x3140, \ + "pdm_right_sel" }, /* PDM data selection for right channel during PDM direct mode, */ \ + { 0x3150, \ + "enbl_micvdd" }, /* Enable MICVDD , */ \ + { 0x3160, \ + "bypass_micvdd_ocp" }, /* Bypass control for the MICVDD OCP flag processing , */ \ + { 0x3201, \ + "pdm_nbck" }, /* PDM BCK/Fs ratio , */ \ + { 0x3223, \ + "pdm_gain" }, /* PDM gain , */ \ + { 0x3263, \ + "sel_pdm_out_data" }, /* PDM output selection - RE/FE data combination , */ \ + { 0x32a0, \ + "sel_cf_haptic_data" }, /* Select the source for haptic data output (not for customer), */ \ + { 0x3307, \ + "haptic_duration" }, /* Duration (ms) , */ \ + { 0x3387, \ + "haptic_data" }, /* DC value (FFS) , */ \ + { 0x3403, \ + "gpio_datain" }, /* Receiving value , */ \ + { 0x3500, \ + "gpio_ctrl" }, /* GPIO master control over GPIO1/2 ports (not for customer), */ \ + { 0x3513, \ + "gpio_dir" }, /* Configuration , */ \ + { 0x3553, \ + "gpio_dataout" }, /* Transmitting value , */ \ + { 0x4000, \ + "int_out_flag_por" }, /* Status POR , */ \ + { 0x4010, \ + "int_out_flag_pll_lock" }, /* Status PLL lock , */ \ + { 0x4020, \ + "int_out_flag_otpok" }, /* Status OTP alarm , */ \ + { 0x4030, \ + "int_out_flag_ovpok" }, /* Status OVP alarm , */ \ + { 0x4040, \ + "int_out_flag_uvpok" }, /* Status UVP alarm , */ \ + { 0x4050, \ + "int_out_flag_clocks_stable" }, /* Status clocks stable , */ \ + { 0x4060, \ + "int_out_flag_mtp_busy" }, /* Status MTP busy , */ \ + { 0x4070, \ + "int_out_flag_lost_clk" }, /* Status lost clock , */ \ + { 0x4080, \ + "int_out_flag_cf_speakererror" }, /* Status speaker error , */ \ + { 0x4090, \ + "int_out_flag_cold_started" }, /* Status cold start , */ \ + { 0x40a0, \ + "int_out_flag_engage" }, /* Status amplifier engage , */ \ + { 0x40b0, \ + "int_out_flag_watchdog_reset" }, /* Status watchdog , */ \ + { 0x40c0, \ + "int_out_flag_enbl_amp" }, /* Status amplifier enable , */ \ + { 0x40d0, \ + "int_out_flag_enbl_ref" }, /* Status Ref enable , */ \ + { 0x40e0, \ + "int_out_flag_adc10_ready" }, /* Status Control ADC , */ \ + { 0x40f0, \ + "int_out_flag_bod_vddd_nok" }, /* Status BOD , */ \ + { 0x4100, \ + "int_out_flag_bst_bstcur" }, /* Status DCDC current limiting , */ \ + { 0x4110, \ + "int_out_flag_bst_hiz" }, /* Status DCDC active , */ \ + { 0x4120, \ + "int_out_flag_bst_ocpok" }, /* Status DCDC OCP , */ \ + { 0x4130, \ + "int_out_flag_bst_peakcur" }, /* Status bst peakcur , */ \ + { 0x4140, \ + "int_out_flag_bst_voutcomp" }, /* Status DCDC level 1x , */ \ + { 0x4150, \ + "int_out_flag_bst_voutcomp86" }, /* Status DCDC level 1.14x , */ \ + { 0x4160, \ + "int_out_flag_bst_voutcomp93" }, /* Status DCDC level 1.07x , */ \ + { 0x4170, \ + "int_out_flag_rcvldop_ready" }, /* Status rcvldop ready , */ \ + { 0x4180, \ + "int_out_flag_ocp_alarm_left" }, /* Status ocp alarm left , */ \ + { 0x4190, \ + "int_out_flag_ocp_alarm_right" }, /* Status ocp alarm right , */ \ + { 0x41a0, \ + "int_out_flag_man_wait_src_settings" }, /* Status Waits HW I2C settings , */ \ + { 0x41b0, \ + "int_out_flag_man_wait_cf_config" }, /* Status waits CF config , */ \ + { 0x41c0, \ + "int_out_flag_man_start_mute_audio" }, /* Status Audio mute sequence , */ \ + { 0x41d0, \ + "int_out_flag_cfma_err" }, /* Status cfma error , */ \ + { 0x41e0, \ + "int_out_flag_cfma_ack" }, /* Status cfma ack , */ \ + { 0x41f0, \ + "int_out_flag_clk_out_of_range" }, /* Status flag_clk_out_of_range , */ \ + { 0x4200, \ + "int_out_flag_tdm_error" }, /* Status tdm error , */ \ + { 0x4210, \ + "int_out_flag_clip_left" }, /* Status clip left , */ \ + { 0x4220, \ + "int_out_flag_clip_right" }, /* Status clip right , */ \ + { 0x4230, \ + "int_out_flag_mic_ocpok" }, /* Status mic ocpok , */ \ + { 0x4400, \ + "int_in_flag_por" }, /* Clear POR , */ \ + { 0x4410, \ + "int_in_flag_pll_lock" }, /* Clear PLL lock , */ \ + { 0x4420, \ + "int_in_flag_otpok" }, /* Clear OTP alarm , */ \ + { 0x4430, \ + "int_in_flag_ovpok" }, /* Clear OVP alarm , */ \ + { 0x4440, \ + "int_in_flag_uvpok" }, /* Clear UVP alarm , */ \ + { 0x4450, \ + "int_in_flag_clocks_stable" }, /* Clear clocks stable , */ \ + { 0x4460, \ + "int_in_flag_mtp_busy" }, /* Clear mtp busy , */ \ + { 0x4470, \ + "int_in_flag_lost_clk" }, /* Clear lost clk , */ \ + { 0x4480, \ + "int_in_flag_cf_speakererror" }, /* Clear speaker error , */ \ + { 0x4490, \ + "int_in_flag_cold_started" }, /* Clear cold started , */ \ + { 0x44a0, \ + "int_in_flag_engage" }, /* Clear amplifier engage , */ \ + { 0x44b0, \ + "int_in_flag_watchdog_reset" }, /* Clear watchdog , */ \ + { 0x44c0, \ + "int_in_flag_enbl_amp" }, /* Clear enbl amp , */ \ + { 0x44d0, \ + "int_in_flag_enbl_ref" }, /* Clear ref enable , */ \ + { 0x44e0, \ + "int_in_flag_adc10_ready" }, /* Clear control ADC , */ \ + { 0x44f0, \ + "int_in_flag_bod_vddd_nok" }, /* Clear BOD , */ \ + { 0x4500, \ + "int_in_flag_bst_bstcur" }, /* Clear DCDC current limiting , */ \ + { 0x4510, \ + "int_in_flag_bst_hiz" }, /* Clear DCDC active , */ \ + { 0x4520, \ + "int_in_flag_bst_ocpok" }, /* Clear DCDC OCP , */ \ + { 0x4530, \ + "int_in_flag_bst_peakcur" }, /* Clear bst peakcur , */ \ + { 0x4540, \ + "int_in_flag_bst_voutcomp" }, /* Clear DCDC level 1x , */ \ + { 0x4550, \ + "int_in_flag_bst_voutcomp86" }, /* Clear DCDC level 1.14x , */ \ + { 0x4560, \ + "int_in_flag_bst_voutcomp93" }, /* Clear DCDC level 1.07x , */ \ + { 0x4570, \ + "int_in_flag_rcvldop_ready" }, /* Clear rcvldop ready , */ \ + { 0x4580, \ + "int_in_flag_ocp_alarm_left" }, /* Clear ocp alarm left , */ \ + { 0x4590, \ + "int_in_flag_ocp_alarm_right" }, /* Clear ocp alarm right , */ \ + { 0x45a0, \ + "int_in_flag_man_wait_src_settings" }, /* Clear wait HW I2C settings , */ \ + { 0x45b0, \ + "int_in_flag_man_wait_cf_config" }, /* Clear wait cf config , */ \ + { 0x45c0, \ + "int_in_flag_man_start_mute_audio" }, /* Clear audio mute sequence , */ \ + { 0x45d0, \ + "int_in_flag_cfma_err" }, /* Clear cfma err , */ \ + { 0x45e0, \ + "int_in_flag_cfma_ack" }, /* Clear cfma ack , */ \ + { 0x45f0, \ + "int_in_flag_clk_out_of_range" }, /* Clear flag_clk_out_of_range , */ \ + { 0x4600, \ + "int_in_flag_tdm_error" }, /* Clear tdm error , */ \ + { 0x4610, \ + "int_in_flag_clip_left" }, /* Clear clip left , */ \ + { 0x4620, \ + "int_in_flag_clip_right" }, /* Clear clip right , */ \ + { 0x4630, \ + "int_in_flag_mic_ocpok" }, /* Clear mic ocpok , */ \ + { 0x4800, \ + "int_enable_flag_por" }, /* Enable por , */ \ + { 0x4810, \ + "int_enable_flag_pll_lock" }, /* Enable pll lock , */ \ + { 0x4820, \ + "int_enable_flag_otpok" }, /* Enable OTP alarm , */ \ + { 0x4830, \ + "int_enable_flag_ovpok" }, /* Enable OVP alarm , */ \ + { 0x4840, \ + "int_enable_flag_uvpok" }, /* Enable UVP alarm , */ \ + { 0x4850, \ + "int_enable_flag_clocks_stable" }, /* Enable clocks stable , */ \ + { 0x4860, \ + "int_enable_flag_mtp_busy" }, /* Enable mtp busy , */ \ + { 0x4870, \ + "int_enable_flag_lost_clk" }, /* Enable lost clk , */ \ + { 0x4880, \ + "int_enable_flag_cf_speakererror" }, /* Enable speaker error , */ \ + { 0x4890, \ + "int_enable_flag_cold_started" }, /* Enable cold started , */ \ + { 0x48a0, \ + "int_enable_flag_engage" }, /* Enable amplifier engage , */ \ + { 0x48b0, \ + "int_enable_flag_watchdog_reset" }, /* Enable watchdog , */ \ + { 0x48c0, \ + "int_enable_flag_enbl_amp" }, /* Enable enbl amp , */ \ + { 0x48d0, \ + "int_enable_flag_enbl_ref" }, /* Enable ref enable , */ \ + { 0x48e0, \ + "int_enable_flag_adc10_ready" }, /* Enable Control ADC , */ \ + { 0x48f0, \ + "int_enable_flag_bod_vddd_nok" }, /* Enable BOD , */ \ + { 0x4900, \ + "int_enable_flag_bst_bstcur" }, /* Enable DCDC current limiting , */ \ + { 0x4910, \ + "int_enable_flag_bst_hiz" }, /* Enable DCDC active , */ \ + { 0x4920, \ + "int_enable_flag_bst_ocpok" }, /* Enable DCDC OCP , */ \ + { 0x4930, \ + "int_enable_flag_bst_peakcur" }, /* Enable bst peakcur , */ \ + { 0x4940, \ + "int_enable_flag_bst_voutcomp" }, /* Enable DCDC level 1x , */ \ + { 0x4950, \ + "int_enable_flag_bst_voutcomp86" }, /* Enable DCDC level 1.14x , */ \ + { 0x4960, \ + "int_enable_flag_bst_voutcomp93" }, /* Enable DCDC level 1.07x , */ \ + { 0x4970, \ + "int_enable_flag_rcvldop_ready" }, /* Enable rcvldop ready , */ \ + { 0x4980, \ + "int_enable_flag_ocp_alarm_left" }, /* Enable ocp alarm left , */ \ + { 0x4990, \ + "int_enable_flag_ocp_alarm_right" }, /* Enable ocp alarm right , */ \ + { 0x49a0, \ + "int_enable_flag_man_wait_src_settings" }, /* Enable waits HW I2C settings , */ \ + { 0x49b0, \ + "int_enable_flag_man_wait_cf_config" }, /* Enable man wait cf config , */ \ + { 0x49c0, \ + "int_enable_flag_man_start_mute_audio" }, /* Enable man Audio mute sequence , */ \ + { 0x49d0, \ + "int_enable_flag_cfma_err" }, /* Enable cfma err , */ \ + { 0x49e0, \ + "int_enable_flag_cfma_ack" }, /* Enable cfma ack , */ \ + { 0x49f0, \ + "int_enable_flag_clk_out_of_range" }, /* Enable flag_clk_out_of_range , */ \ + { 0x4a00, \ + "int_enable_flag_tdm_error" }, /* Enable tdm error , */ \ + { 0x4a10, \ + "int_enable_flag_clip_left" }, /* Enable clip left , */ \ + { 0x4a20, \ + "int_enable_flag_clip_right" }, /* Enable clip right , */ \ + { 0x4a30, \ + "int_enable_flag_mic_ocpok" }, /* Enable mic ocpok , */ \ + { 0x4c00, \ + "int_polarity_flag_por" }, /* Polarity por , */ \ + { 0x4c10, \ + "int_polarity_flag_pll_lock" }, /* Polarity pll lock , */ \ + { 0x4c20, \ + "int_polarity_flag_otpok" }, /* Polarity OTP alarm , */ \ + { 0x4c30, \ + "int_polarity_flag_ovpok" }, /* Polarity OVP alarm , */ \ + { 0x4c40, \ + "int_polarity_flag_uvpok" }, /* Polarity UVP alarm , */ \ + { 0x4c50, \ + "int_polarity_flag_clocks_stable" }, /* Polarity clocks stable , */ \ + { 0x4c60, \ + "int_polarity_flag_mtp_busy" }, /* Polarity mtp busy , */ \ + { 0x4c70, \ + "int_polarity_flag_lost_clk" }, /* Polarity lost clk , */ \ + { 0x4c80, \ + "int_polarity_flag_cf_speakererror" }, /* Polarity speaker error , */ \ + { 0x4c90, \ + "int_polarity_flag_cold_started" }, /* Polarity cold started , */ \ + { 0x4ca0, \ + "int_polarity_flag_engage" }, /* Polarity amplifier engage , */ \ + { 0x4cb0, \ + "int_polarity_flag_watchdog_reset" }, /* Polarity watchdog , */ \ + { 0x4cc0, \ + "int_polarity_flag_enbl_amp" }, /* Polarity enbl amp , */ \ + { 0x4cd0, \ + "int_polarity_flag_enbl_ref" }, /* Polarity ref enable , */ \ + { 0x4ce0, \ + "int_polarity_flag_adc10_ready" }, /* Polarity Control ADC , */ \ + { 0x4cf0, \ + "int_polarity_flag_bod_vddd_nok" }, /* Polarity BOD , */ \ + { 0x4d00, \ + "int_polarity_flag_bst_bstcur" }, /* Polarity DCDC current limiting , */ \ + { 0x4d10, \ + "int_polarity_flag_bst_hiz" }, /* Polarity DCDC active , */ \ + { 0x4d20, \ + "int_polarity_flag_bst_ocpok" }, /* Polarity DCDC OCP , */ \ + { 0x4d30, \ + "int_polarity_flag_bst_peakcur" }, /* Polarity bst peakcur , */ \ + { 0x4d40, \ + "int_polarity_flag_bst_voutcomp" }, /* Polarity DCDC level 1x , */ \ + { 0x4d50, \ + "int_polarity_flag_bst_voutcomp86" }, /* Polarity DCDC level 1.14x , */ \ + { 0x4d60, \ + "int_polarity_flag_bst_voutcomp93" }, /* Polarity DCDC level 1.07x , */ \ + { 0x4d70, \ + "int_polarity_flag_rcvldop_ready" }, /* Polarity rcvldop ready , */ \ + { 0x4d80, \ + "int_polarity_flag_ocp_alarm_left" }, /* Polarity ocp alarm left , */ \ + { 0x4d90, \ + "int_polarity_flag_ocp_alarm_right" }, /* Polarity ocp alarm right , */ \ + { 0x4da0, \ + "int_polarity_flag_man_wait_src_settings" }, /* Polarity waits HW I2C settings , */ \ + { 0x4db0, \ + "int_polarity_flag_man_wait_cf_config" }, /* Polarity man wait cf config , */ \ + { 0x4dc0, \ + "int_polarity_flag_man_start_mute_audio" }, /* Polarity man audio mute sequence , */ \ + { 0x4dd0, \ + "int_polarity_flag_cfma_err" }, /* Polarity cfma err , */ \ + { 0x4de0, \ + "int_polarity_flag_cfma_ack" }, /* Polarity cfma ack , */ \ + { 0x4df0, \ + "int_polarity_flag_clk_out_of_range" }, /* Polarity flag_clk_out_of_range , */ \ + { 0x4e00, \ + "int_polarity_flag_tdm_error" }, /* Polarity tdm error , */ \ + { 0x4e10, \ + "int_polarity_flag_clip_left" }, /* Polarity clip left , */ \ + { 0x4e20, \ + "int_polarity_flag_clip_right" }, /* Polarity clip right , */ \ + { 0x4e30, \ + "int_polarity_flag_mic_ocpok" }, /* Polarity mic ocpok , */ \ + { 0x5001, \ + "vbat_prot_attack_time" }, /* Battery protection attack Time , */ \ + { 0x5023, \ + "vbat_prot_thlevel" }, /* Battery protection threshold voltage level , */ \ + { 0x5061, \ + "vbat_prot_max_reduct" }, /* Battery protection maximum reduction , */ \ + { 0x5082, \ + "vbat_prot_release_time" }, /* Battery protection release time , */ \ + { 0x50b1, \ + "vbat_prot_hysterese" }, /* Battery protection hysteresis , */ \ + { 0x50d0, \ + "rst_min_vbat" }, /* Reset clipper - Auto clear , */ \ + { 0x50e0, \ + "sel_vbat" }, /* Battery voltage read out , */ \ + { 0x50f0, \ + "bypass_clipper" }, /* Bypass HW clipper , */ \ + { 0x5100, \ + "batsense_steepness" }, /* Vbat prot steepness , */ \ + { 0x5110, \ + "soft_mute" }, /* Soft mute HW , */ \ + { 0x5120, \ + "cf_mute_left" }, /* Soft mute FW left , */ \ + { 0x5130, \ + "cf_mute_right" }, /* Soft mute FW right , */ \ + { 0x5140, \ + "bypass_hp_left" }, /* Bypass HPF left , */ \ + { 0x5150, \ + "bypass_hp_right" }, /* Bypass HPF right , */ \ + { 0x5160, \ + "enbl_dpsa_left" }, /* Enable DPSA left , */ \ + { 0x5170, \ + "enbl_dpsa_right" }, /* Enable DPSA right , */ \ + { 0x5187, \ + "cf_volume" }, /* FW volume control for primary audio channel , */ \ + { 0x5200, \ + "ctrl_rcv" }, /* Selection receiver , */ \ + { 0x5210, \ + "ctrl_rcv_fb_100k" }, /* Selection of feedback resistor for receiver mode (not for customer), */ \ + { 0x5222, \ + "ctrl_cc" }, /* Clip control setting , */ \ + { 0x5257, \ + "gain" }, /* Amplifier gain , */ \ + { 0x52d0, \ + "ctrl_slopectrl" }, /* Enables slope control , */ \ + { 0x52e1, \ + "ctrl_slope" }, /* Set slope , */ \ + { 0x5301, \ + "dpsa_level" }, /* DPSA threshold levels , */ \ + { 0x5321, \ + "dpsa_release" }, /* DPSA Release time , */ \ + { 0x5340, \ + "clipfast" }, /* Clock selection for HW clipper for battery protection, */ \ + { 0x5350, \ + "bypass_lp" }, /* Bypass the low power filter inside temperature sensor, */ \ + { 0x5360, \ + "enbl_low_latency" }, /* CF low latency outputs for add module , */ \ + { 0x5400, \ + "first_order_mode" }, /* Overrule to 1st order mode of control stage when clipping, */ \ + { 0x5410, \ + "bypass_ctrlloop" }, /* Switch amplifier into open loop configuration , */ \ + { 0x5420, \ + "fb_hz" }, /* Feedback resistor set to high ohmic , */ \ + { 0x5430, \ + "icomp_engage" }, /* Engage of icomp , */ \ + { 0x5440, \ + "ctrl_kickback" }, /* Prevent double pulses of output stage , */ \ + { 0x5450, \ + "icomp_engage_overrule" }, /* To overrule the functional icomp_engage signal during validation, */ \ + { 0x5503, \ + "ctrl_dem" }, /* Enable DEM icomp and DEM one bit dac , */ \ + { 0x5543, \ + "ctrl_dem_mismatch" }, /* Enable DEM icomp mismatch for testing , */ \ + { 0x5581, \ + "dpsa_drive" }, /* Control of the number of power stage sections, total of 4 sections. Each section is 1/4 of the total power stages., */ \ + { 0x560a, \ + "enbl_amp_left" }, /* Switch on the class-D power sections, each part of the analog sections can be switched on/off individually - Left channel, */ \ + { 0x56b0, \ + "enbl_engage_left" }, /* Enables/engage power stage and control loop - left channel, */ \ + { 0x570a, \ + "enbl_amp_right" }, /* Switch on the class-D power sections, each part of the analog sections can be switched on/off individually - Right channel, */ \ + { 0x57b0, \ + "enbl_engage_right" }, /* Enables/engage power stage and control loop - right channel, */ \ + { 0x5800, \ + "hard_mute_left" }, /* Hard mute - PWM module left , */ \ + { 0x5810, \ + "hard_mute_right" }, /* Hard mute - PWM module right , */ \ + { 0x5820, \ + "pwm_shape" }, /* PWM shape , */ \ + { 0x5830, \ + "pwm_bitlength" }, /* PWM bit length in noise shaper , */ \ + { 0x5844, \ + "pwm_delay" }, /* PWM delay bits to set the delay, clockd is 1/(k*2048*fs), */ \ + { 0x5890, \ + "reclock_pwm" }, /* Reclock the pwm signal inside analog , */ \ + { 0x58a0, \ + "reclock_voltsense" }, /* Reclock the voltage sense pwm signal , */ \ + { 0x58b0, \ + "enbl_pwm_phase_shift_left" }, /* Control for pwm phase shift, inverted function - left channel, */ \ + { 0x58c0, \ + "enbl_pwm_phase_shift_right" }, /* Control for pwm phase shift - right channel , */ \ + { 0x5900, \ + "ctrl_rcvldop_pulldown" }, /* Pulldown of LDO (2.7V) , */ \ + { 0x5910, \ + "ctrl_rcvldop_test_comp" }, /* Enable testing of LDO comparator , */ \ + { 0x5920, \ + "ctrl_rcvldop_test_loadedldo" }, /* Load connected to rcvldo , */ \ + { 0x5930, \ + "enbl_rcvldop" }, /* Enables the LDO (2.7) , */ \ + { 0x5a07, \ + "cf_volume_sec" }, /* FW volume control for secondary audio channel , */ \ + { 0x5a87, \ + "sw_profile" }, /* Software profile data , */ \ + { 0x7002, \ + "boost_volt" }, /* Boost voltage , */ \ + { 0x7033, \ + "boost_cur" }, /* Max coil current , */ \ + { 0x7071, \ + "bst_coil_value" }, /* Coil Value , */ \ + { 0x7090, \ + "boost_intel" }, /* Adaptive boost mode , */ \ + { 0x70a0, \ + "boost_speed" }, /* Soft ramp up/down , */ \ + { 0x70b2, \ + "dcdc_synchronisation" }, /* DCDC synchronization off + 7 positions , */ \ + { 0x70e0, \ + "dcdcoff_mode" }, /* DCDC on/off , */ \ + { 0x7104, \ + "bst_drive" }, /* Binary coded drive setting for boost converter power stage, */ \ + { 0x7151, \ + "bst_scalecur" }, /* For testing direct control scale current , */ \ + { 0x7174, \ + "bst_slopecur" }, /* For testing direct control slope current , */ \ + { 0x71c1, \ + "bst_slope" }, /* Boost slope speed , */ \ + { 0x71e0, \ + "bst_bypass_bstcur" }, /* Bypass control for boost current settings , */ \ + { 0x71f0, \ + "bst_bypass_bstfoldback" }, /* Bypass control for boost foldback , */ \ + { 0x7200, \ + "enbl_bst_engage" }, /* Enable power stage dcdc controller , */ \ + { 0x7210, \ + "enbl_bst_hizcom" }, /* Enable hiz comparator , */ \ + { 0x7220, \ + "enbl_bst_peak2avg" }, /* Enable boost peak2avg functionality , */ \ + { 0x7230, \ + "enbl_bst_peakcur" }, /* Enable peak current , */ \ + { 0x7240, \ + "enbl_bst_power" }, /* Enable line of the powerstage , */ \ + { 0x7250, \ + "enbl_bst_slopecur" }, /* Enable bit of max-current dac , */ \ + { 0x7260, \ + "enbl_bst_voutcomp" }, /* Enable vout comparators , */ \ + { 0x7270, \ + "enbl_bst_voutcomp86" }, /* Enable vout-86 comparators , */ \ + { 0x7280, \ + "enbl_bst_voutcomp93" }, /* Enable vout-93 comparators , */ \ + { 0x7290, \ + "enbl_bst_windac" }, /* Enable window dac , */ \ + { 0x72a5, \ + "bst_windac" }, /* for testing direct control windac , */ \ + { 0x7300, \ + "boost_alg" }, /* Control for boost adaptive loop gain , */ \ + { 0x7311, \ + "boost_loopgain" }, /* DCDC boost loopgain setting , */ \ + { 0x7332, \ + "bst_freq" }, /* DCDC bost frequency control , */ \ + { 0x8001, \ + "sel_clk_cs" }, /* Current sense clock duty cycle control , */ \ + { 0x8021, \ + "micadc_speed" }, /* Current sense clock for MiCADC selection - 32/44.1/48 KHz Fs band only, */ \ + { 0x8040, \ + "cs_dc_offset" }, /* Current sense decimator offset control , */ \ + { 0x8050, \ + "cs_gain_control" }, /* Current sense gain control , */ \ + { 0x8060, \ + "cs_bypass_gc" }, /* Bypasses the CS gain correction , */ \ + { 0x8087, \ + "cs_gain" }, /* Current sense gain , */ \ + { 0x8110, \ + "invertpwm_left" }, /* Current sense common mode feedback pwm invert control for left channel, */ \ + { 0x8122, \ + "cmfb_gain_left" }, /* Current sense common mode feedback control gain for left channel, */ \ + { 0x8154, \ + "cmfb_offset_left" }, /* Current sense common mode feedback control offset for left channel, */ \ + { 0x8200, \ + "enbl_cmfb_right" }, /* Current sense common mode feedback control for right channel, */ \ + { 0x8210, \ + "invertpwm_right" }, /* Current sense common mode feedback pwm invert control for right channel, */ \ + { 0x8222, \ + "cmfb_gain_right" }, /* Current sense common mode feedback control gain for right channel, */ \ + { 0x8254, \ + "cmfb_offset_right" }, /* Current sense common mode feedback control offset for right channel, */ \ + { 0x8305, \ + "cs_ktemp" }, /* Current sense temperature compensation trimming (1 - VALUE*TEMP)*signal, */ \ + { 0x8400, \ + "cs_adc_bsoinv" }, /* Bitstream inversion for current sense ADC , */ \ + { 0x8421, \ + "cs_adc_hifreq" }, /* Frequency mode current sense ADC , */ \ + { 0x8440, \ + "cs_adc_nortz" }, /* Return to zero for current sense ADC , */ \ + { 0x8453, \ + "cs_adc_offset" }, /* Micadc ADC offset setting , */ \ + { 0x8490, \ + "cs_adc_slowdel" }, /* Select delay for current sense ADC (internal decision circuitry), */ \ + { 0x84a4, \ + "cs_adc_gain" }, /* Gain setting for current sense ADC (two's complement), */ \ + { 0x8500, \ + "cs_resonator_enable" }, /* Enable for resonator to improve SRN , */ \ + { 0x8510, \ + "cs_classd_tran_skip" }, /* Skip current sense connection during a classD amplifier transition, */ \ + { 0x8530, \ + "cs_inn_short" }, /* Short current sense negative to common mode , */ \ + { 0x8540, \ + "cs_inp_short" }, /* Short current sense positive to common mode , */ \ + { 0x8550, \ + "cs_ldo_bypass" }, /* Bypass current sense LDO , */ \ + { 0x8560, \ + "cs_ldo_pulldown" }, /* Pull down current sense LDO, only valid if left_enbl_cs_ldo is high, */ \ + { 0x8574, \ + "cs_ldo_voset" }, /* Current sense LDO voltage level setting (two's complement), */ \ + { 0x8600, \ + "enbl_cs_adc_left" }, /* Enable current sense ADC , */ \ + { 0x8610, \ + "enbl_cs_inn1_left" }, /* Enable connection of current sense negative1 , */ \ + { 0x8630, \ + "enbl_cs_inp1_left" }, /* Enable connection of current sense positive1 , */ \ + { 0x8650, \ + "enbl_cs_ldo_left" }, /* Enable current sense LDO , */ \ + { 0x8660, \ + "enbl_cs_nofloating_n_left" }, /* Connect current sense negative to gnda at transitions of booster or classd amplifiers. Otherwise floating (0), */ \ + { 0x8670, \ + "enbl_cs_nofloating_p_left" }, /* Connect current sense positive to gnda at transitions of booster or classd amplifiers. Otherwise floating (0), */ \ + { 0x8680, \ + "enbl_cs_vbatldo_left" }, /* Enable of current sense LDO , */ \ + { 0x8700, \ + "enbl_cs_adc_right" }, /* Enable current sense ADC , */ \ + { 0x8710, \ + "enbl_cs_inn1_right" }, /* Enable connection of current sense negative1 , */ \ + { 0x8730, \ + "enbl_cs_inp1_right" }, /* Enable connection of current sense positive1 , */ \ + { 0x8750, \ + "enbl_cs_ldo_right" }, /* Enable current sense LDO , */ \ + { 0x8760, \ + "enbl_cs_nofloating_n_right" }, /* Connect current sense negative to gnda at transitions of booster or classd amplifiers. Otherwise floating (0), */ \ + { 0x8770, \ + "enbl_cs_nofloating_p_right" }, /* Connect current sense positive to gnda at transitions of booster or classd amplifiers. Otherwise floating (0), */ \ + { 0x8780, \ + "enbl_cs_vbatldo_right" }, /* Enable of current sense LDO , */ \ + { 0x8800, \ + "volsense_pwm_sel" }, /* Voltage sense PWM source selection control , */ \ + { 0x8810, \ + "volsense_dc_offset" }, /* Voltage sense decimator offset control , */ \ + { 0x9000, \ + "cf_rst_dsp" }, /* Reset , */ \ + { 0x9011, \ + "cf_dmem" }, /* Target memory , */ \ + { 0x9030, \ + "cf_aif" }, /* Auto increment , */ \ + { 0x9040, \ + "cf_int" }, /* Interrupt - auto clear , */ \ + { 0x9050, \ + "cf_cgate_off" }, /* Coolflux clock gating disabling control , */ \ + { 0x9080, \ + "cf_req_cmd" }, /* Firmware event request rpc command , */ \ + { 0x9090, \ + "cf_req_reset" }, /* Firmware event request reset restart , */ \ + { 0x90a0, \ + "cf_req_mips" }, /* Firmware event request short on mips , */ \ + { 0x90b0, \ + "cf_req_mute_ready" }, /* Firmware event request mute sequence ready , */ \ + { 0x90c0, \ + "cf_req_volume_ready" }, /* Firmware event request volume ready , */ \ + { 0x90d0, \ + "cf_req_damage" }, /* Firmware event request speaker damage detected , */ \ + { 0x90e0, \ + "cf_req_calibrate_ready" }, /* Firmware event request calibration completed , */ \ + { 0x90f0, \ + "cf_req_reserved" }, /* Firmware event request reserved , */ \ + { 0x910f, \ + "cf_madd" }, /* Memory address , */ \ + { 0x920f, \ + "cf_mema" }, /* Activate memory access , */ \ + { 0x9307, \ + "cf_err" }, /* Error flags , */ \ + { 0x9387, \ + "cf_ack" }, /* Acknowledge of requests , */ \ + { 0x9380, \ + "cf_ack_cmd" }, /* Firmware event acknowledge rpc command , */ \ + { 0x9390, \ + "cf_ack_reset" }, /* Firmware event acknowledge reset restart , */ \ + { 0x93a0, \ + "cf_ack_mips" }, /* Firmware event acknowledge short on mips , */ \ + { 0x93b0, \ + "cf_ack_mute_ready" }, /* Firmware event acknowledge mute sequence ready , */ \ + { 0x93c0, \ + "cf_ack_volume_ready" }, /* Firmware event acknowledge volume ready , */ \ + { 0x93d0, \ + "cf_ack_damage" }, /* Firmware event acknowledge speaker damage detected, */ \ + { 0x93e0, \ + "cf_ack_calibrate_ready" }, /* Firmware event acknowledge calibration completed , */ \ + { 0x93f0, \ + "cf_ack_reserved" }, /* Firmware event acknowledge reserved , */ \ + { 0x980f, \ + "ivt_addr0_msb" }, /* Coolflux interrupt vector table address0 MSB , */ \ + { 0x990f, \ + "ivt_addr0_lsb" }, /* Coolflux interrupt vector table address0 LSB , */ \ + { 0x9a0f, \ + "ivt_addr1_msb" }, /* Coolflux interrupt vector table address1 MSB , */ \ + { 0x9b0f, \ + "ivt_addr1_lsb" }, /* Coolflux interrupt vector table address1 LSB , */ \ + { 0x9c0f, \ + "ivt_addr2_msb" }, /* Coolflux interrupt vector table address2 MSB , */ \ + { 0x9d0f, \ + "ivt_addr2_lsb" }, /* Coolflux interrupt vector table address2 LSB , */ \ + { 0x9e0f, \ + "ivt_addr3_msb" }, /* Coolflux interrupt vector table address3 MSB , */ \ + { 0x9f0f, \ + "ivt_addr3_lsb" }, /* Coolflux interrupt vector table address3 LSB , */ \ + { 0xa007, \ + "mtpkey1" }, /* 5Ah, 90d To access KEY1_Protected registers (Default for engineering), */ \ + { 0xa107, \ + "mtpkey2" }, /* MTP KEY2 register , */ \ + { 0xa200, \ + "key01_locked" }, /* Indicates KEY1 is locked , */ \ + { 0xa210, \ + "key02_locked" }, /* Indicates KEY2 is locked , */ \ + { 0xa302, \ + "mtp_man_address_in" }, /* MTP address from I2C register for read/writing mtp in manual single word mode, */ \ + { 0xa330, \ + "man_copy_mtp_to_iic" }, /* Start copying single word from mtp to I2C mtp register, */ \ + { 0xa340, \ + "man_copy_iic_to_mtp" }, /* Start copying single word from I2C mtp register to mtp, */ \ + { 0xa350, \ + "auto_copy_mtp_to_iic" }, /* Start copying all the data from mtp to I2C mtp registers, */ \ + { 0xa360, \ + "auto_copy_iic_to_mtp" }, /* Start copying data from I2C mtp registers to mtp , */ \ + { 0xa400, \ + "faim_set_clkws" }, /* Sets the faim controller clock wait state register, */ \ + { 0xa410, \ + "faim_sel_evenrows" }, /* All even rows of the faim are selected, active high, */ \ + { 0xa420, \ + "faim_sel_oddrows" }, /* All odd rows of the faim are selected, all rows in combination with sel_evenrows, */ \ + { 0xa430, \ + "faim_program_only" }, /* Skip the erase access at wr_faim command (write-program-marginread), */ \ + { 0xa440, \ + "faim_erase_only" }, /* Skip the program access at wr_faim command (write-erase-marginread), */ \ + { 0xa50f, \ + "mtp_man_data_out_msb" }, /* MSB word of MTP manual read data , */ \ + { 0xa60f, \ + "mtp_man_data_out_lsb" }, /* LSB word of MTP manual read data , */ \ + { 0xa70f, \ + "mtp_man_data_in_msb" }, /* MSB word of write data for MTP manual write , */ \ + { 0xa80f, \ + "mtp_man_data_in_lsb" }, /* LSB word of write data for MTP manual write , */ \ + { 0xb010, \ + "bypass_ocpcounter" }, /* Bypass OCP Counter , */ \ + { 0xb020, \ + "bypass_glitchfilter" }, /* Bypass glitch filter , */ \ + { 0xb030, \ + "bypass_ovp" }, /* Bypass OVP , */ \ + { 0xb040, \ + "bypass_uvp" }, /* Bypass UVP , */ \ + { 0xb050, \ + "bypass_otp" }, /* Bypass OTP , */ \ + { 0xb060, \ + "bypass_lost_clk" }, /* Bypass lost clock detector , */ \ + { 0xb070, \ + "ctrl_vpalarm" }, /* vpalarm (uvp ovp handling) , */ \ + { 0xb087, \ + "ocp_threshold" }, /* OCP threshold level , */ \ + { 0xb108, \ + "ext_temp" }, /* External temperature (C) , */ \ + { 0xb190, \ + "ext_temp_sel" }, /* Select temp Speaker calibration , */ \ + { 0xc000, \ + "use_direct_ctrls" }, /* Direct control to overrule several functions for testing, */ \ + { 0xc010, \ + "rst_datapath" }, /* Direct control for datapath reset , */ \ + { 0xc020, \ + "rst_cgu" }, /* Direct control for cgu reset , */ \ + { 0xc038, \ + "enbl_ref" }, /* Switch on the analog references, each part of the references can be switched on/off individually, */ \ + { 0xc0d0, \ + "enbl_ringo" }, /* Enable the ring oscillator for test purpose , */ \ + { 0xc0e0, \ + "use_direct_clk_ctrl" }, /* Direct clock control to overrule several functions for testing, */ \ + { 0xc0f0, \ + "use_direct_pll_ctrl" }, /* Direct PLL control to overrule several functions for testing, */ \ + { 0xc100, \ + "enbl_tsense" }, /* Temperature sensor enable control - I2C direct mode, */ \ + { 0xc110, \ + "tsense_hibias" }, /* Bit to set the biasing in temp sensor to high , */ \ + { 0xc120, \ + "enbl_flag_vbg" }, /* Enable flagging of bandgap out of control , */ \ + { 0xc20f, \ + "abist_offset" }, /* Offset control for ABIST testing (two's complement), */ \ + { 0xc300, \ + "bypasslatch" }, /* Bypass latch , */ \ + { 0xc311, \ + "sourcea" }, /* Set OUTA to , */ \ + { 0xc331, \ + "sourceb" }, /* Set OUTB to , */ \ + { 0xc350, \ + "inverta" }, /* Invert pwma test signal , */ \ + { 0xc360, \ + "invertb" }, /* Invert pwmb test signal , */ \ + { 0xc374, \ + "pulselength" }, /* Pulse length setting test input for amplifier (clock d - k*2048*fs), */ \ + { 0xc3c0, \ + "tdm_enable_loopback" }, /* TDM loopback test , */ \ + { 0xc3d0, \ + "test_abistfft_enbl" }, /* FFT Coolflux , */ \ + { 0xc3e0, \ + "test_pwr_switch" }, /* Test mode for digital power switches core sw/mem sw/micvdd sw, */ \ + { 0xc400, \ + "bst_bypasslatch" }, /* Bypass latch in boost converter , */ \ + { 0xc411, \ + "bst_source" }, /* Sets the source of the pwmbst output to boost converter input for testing, */ \ + { 0xc430, \ + "bst_invertb" }, /* Invert pwmbst test signal , */ \ + { 0xc444, \ + "bst_pulselength" }, /* Pulse length setting test input for boost converter , */ \ + { 0xc490, \ + "test_bst_ctrlsthv" }, /* Test mode for boost control stage , */ \ + { 0xc4a0, \ + "test_bst_iddq" }, /* IDDQ testing in power stage of boost converter , */ \ + { 0xc4b0, \ + "test_bst_rdson" }, /* RDSON testing - boost power stage , */ \ + { 0xc4c0, \ + "test_bst_cvi" }, /* CVI testing - boost power stage , */ \ + { 0xc4d0, \ + "test_bst_ocp" }, /* Boost OCP. For old ocp (ctrl_reversebst is 0), For new ocp (ctrl_reversebst is 1), */ \ + { 0xc4e0, \ + "test_bst_sense" }, /* Test option for the sense NMOS in booster for current mode control., */ \ + { 0xc500, \ + "test_cvi" }, /* Analog BIST, switch choose which transistor will be used as current source (also cross coupled sources possible), */ \ + { 0xc510, \ + "test_discrete" }, /* Test function noise measurement , */ \ + { 0xc520, \ + "test_iddq" }, /* Set the power stages in iddq mode for gate stress., */ \ + { 0xc540, \ + "test_rdson" }, /* Analog BIST, switch to enable Rdson measurement , */ \ + { 0xc550, \ + "test_sdelta" }, /* Analog BIST, noise test , */ \ + { 0xc570, \ + "test_enbl_cs" }, /* Enable for digimux mode of current sense , */ \ + { 0xc600, \ + "enbl_pwm_dcc" }, /* Enables direct control of pwm duty cycle for DCDC power stage, */ \ + { 0xc613, \ + "pwm_dcc_cnt" }, /* Control pwm duty cycle when enbl_pwm_dcc is 1 , */ \ + { 0xc650, \ + "enbl_ldo_stress" }, /* Enable stress of internal supply voltages powerstages, */ \ + { 0xc660, \ + "bypass_diosw_ovp" }, /* Bypass ovp for memory switch diosw , */ \ + { 0xc670, \ + "enbl_powerswitch" }, /* Vddd core power switch control - overrules the manager control, */ \ + { 0xc707, \ + "digimuxa_sel" }, /* DigimuxA input selection control routed to GPIO1 (see Digimux list for details), */ \ + { 0xc787, \ + "digimuxb_sel" }, /* DigimuxB input selection control routed to GPIO2 (see Digimux list for details), */ \ + { 0xc807, \ + "digimuxc_sel" }, /* DigimuxC input selection control routed to GPIO3 (see Digimux list for details), */ \ + { 0xc887, \ + "digimuxd_sel" }, /* DigimuxD input selection control routed to GPIO4 (see Digimux list for details), */ \ + { 0xc901, \ + "dio1_ehs" }, /* Speed/load setting for DIO1 IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc921, \ + "dio2_ehs" }, /* Speed/load setting for DIO2 IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc941, \ + "gainio_ehs" }, /* Speed/load setting for GAINIO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc961, \ + "pdmo_ehs" }, /* Speed/load setting for PDMO IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc981, \ + "int_ehs" }, /* Speed/load setting for INT IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc9a1, \ + "tdo_ehs" }, /* Speed/load setting for TDO IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc9c0, \ + "hs_mode" }, /* I2C high speed mode control , */ \ + { 0xca00, \ + "enbl_anamux1" }, /* Enable anamux1 , */ \ + { 0xca10, \ + "enbl_anamux2" }, /* Enable anamux2 , */ \ + { 0xca20, \ + "enbl_anamux3" }, /* Enable anamux3 , */ \ + { 0xca30, \ + "enbl_anamux4" }, /* Enable anamux4 , */ \ + { 0xca40, \ + "enbl_anamux5" }, /* Enable anamux5 , */ \ + { 0xca50, \ + "enbl_anamux6" }, /* Enable anamux6 , */ \ + { 0xca60, \ + "enbl_anamux7" }, /* Enable anamux7 , */ \ + { 0xca74, \ + "anamux1" }, /* Anamux selection control - anamux on TEST1 , */ \ + { 0xcb04, \ + "anamux2" }, /* Anamux selection control - anamux on TEST2 , */ \ + { 0xcb54, \ + "anamux3" }, /* Anamux selection control - anamux on TEST3 , */ \ + { 0xcba4, \ + "anamux4" }, /* Anamux selection control - anamux on TEST4 , */ \ + { 0xcc04, \ + "anamux5" }, /* Anamux selection control - anamux on TEST5 , */ \ + { 0xcc54, \ + "anamux6" }, /* Anamux selection control - anamux on TEST6 , */ \ + { 0xcca4, \ + "anamux7" }, /* Anamux selection control - anamux on TEST7 , */ \ + { 0xcd05, \ + "pll_seli" }, /* PLL SELI - I2C direct PLL control mode only , */ \ + { 0xcd64, \ + "pll_selp" }, /* PLL SELP - I2C direct PLL control mode only , */ \ + { 0xcdb3, \ + "pll_selr" }, /* PLL SELR - I2C direct PLL control mode only , */ \ + { 0xcdf0, \ + "pll_frm" }, /* PLL free running mode control; 1 in TCB direct control mode, else this control bit, */ \ + { 0xce09, \ + "pll_ndec" }, /* PLL NDEC - I2C direct PLL control mode only , */ \ + { 0xcea0, \ + "pll_mdec_msb" }, /* MSB of pll_mdec - I2C direct PLL control mode only, */ \ + { 0xceb0, \ + "enbl_pll" }, /* Enables PLL in I2C direct PLL control mode only , */ \ + { 0xcec0, \ + "enbl_osc" }, /* Enables OSC1M in I2C direct control mode only , */ \ + { 0xced0, \ + "pll_bypass" }, /* PLL bypass control in I2C direct PLL control mode only, */ \ + { 0xcee0, \ + "pll_directi" }, /* PLL directi control in I2C direct PLL control mode only, */ \ + { 0xcef0, \ + "pll_directo" }, /* PLL directo control in I2C direct PLL control mode only, */ \ + { 0xcf0f, \ + "pll_mdec_lsb" }, /* Bits 15..0 of PLL MDEC are I2C direct PLL control mode only, */ \ + { 0xd006, \ + "pll_pdec" }, /* PLL PDEC - I2C direct PLL control mode only , */ \ + { 0xd10f, \ + "tsig_freq_lsb" }, /* Internal sinus test generator frequency control , */ \ + { 0xd202, \ + "tsig_freq_msb" }, /* Select internal sinus test generator, frequency control msb bits, */ \ + { 0xd230, \ + "inject_tsig" }, /* Control bit to switch to internal sinus test generator, */ \ + { 0xd243, \ + "tsig_gain_left" }, /* Test signal gain for left channel , */ \ + { 0xd283, \ + "tsig_gain_right" }, /* Test signal gain for right channel , */ \ + { 0xd300, \ + "adc10_reset" }, /* Reset for ADC10 - I2C direct control mode , */ \ + { 0xd311, \ + "adc10_test" }, /* Test mode selection signal for ADC10 - I2C direct control mode, */ \ + { 0xd332, \ + "adc10_sel" }, /* Select the input to convert for ADC10 - I2C direct control mode, */ \ + { 0xd364, \ + "adc10_prog_sample" }, /* ADC10 program sample setting - I2C direct control mode, */ \ + { 0xd3b0, \ + "adc10_enbl" }, /* Enable ADC10 - I2C direct control mode , */ \ + { 0xd3c0, \ + "bypass_lp_vbat" }, /* Bypass control for Low pass filter in batt sensor , */ \ + { 0xd409, \ + "data_adc10_tempbat" }, /* ADC 10 data output data for testing , */ \ + { 0xd506, \ + "ctrl_digtoana_hidden" }, /* Spare digital to analog control bits - Hidden , */ \ + { 0xd570, \ + "enbl_clk_out_of_range" }, /* Clock out of range , */ \ + { 0xf000, \ + "calibration_onetime" }, /* Calibration schedule , */ \ + { 0xf010, \ + "calibr_ron_done" }, /* Calibration Ron executed , */ \ + { 0xf020, \ + "calibr_dcdc_api_calibrate" }, /* Calibration current limit DCDC , */ \ + { 0xf030, \ + "calibr_dcdc_delta_sign" }, /* Sign bit for delta calibration current limit DCDC , */ \ + { 0xf042, \ + "calibr_dcdc_delta" }, /* Calibration delta current limit DCDC , */ \ + { 0xf078, \ + "calibr_speaker_info" }, /* Reserved space for allowing customer to store speaker information, */ \ + { 0xf105, \ + "calibr_vout_offset" }, /* DCDC offset calibration 2's complement (key1 protected), */ \ + { 0xf163, \ + "calibr_gain_left" }, /* HW gain module - left channel (2's complement) , */ \ + { 0xf1a5, \ + "calibr_offset_left" }, /* Offset for amplifier, HW gain module - left channel (2's complement), */ \ + { 0xf203, \ + "calibr_gain_right" }, /* HW gain module - right channel (2's complement) , */ \ + { 0xf245, \ + "calibr_offset_right" }, /* Offset for amplifier, HW gain module - right channel (2's complement), */ \ + { 0xf2a3, \ + "calibr_rcvldop_trim" }, /* Trimming of LDO (2.7V) , */ \ + { 0xf307, \ + "calibr_gain_cs_left" }, /* Current sense gain - left channel (signed two's complement format), */ \ + { 0xf387, \ + "calibr_gain_cs_right" }, /* Current sense gain - right channel (signed two's complement format), */ \ + { 0xf40f, \ + "calibr_R25C_L" }, /* Ron resistance of left channel speaker coil , */ \ + { 0xf50f, \ + "calibr_R25C_R" }, /* Ron resistance of right channel speaker coil , */ \ + { 0xf606, \ + "ctrl_offset_a_left" }, /* Offset of left amplifier level shifter A , */ \ + { 0xf686, \ + "ctrl_offset_b_left" }, /* Offset of left amplifier level shifter B , */ \ + { 0xf706, \ + "ctrl_offset_a_right" }, /* Offset of right amplifier level shifter A , */ \ + { 0xf786, \ + "ctrl_offset_b_right" }, /* Offset of right amplifier level shifter B , */ \ + { 0xf806, \ + "htol_iic_addr" }, /* 7-bit I2C address to be used during HTOL testing , */ \ + { 0xf870, \ + "htol_iic_addr_en" }, /* HTOL I2C address enable control , */ \ + { 0xf884, \ + "calibr_temp_offset" }, /* Temperature offset 2's compliment (key1 protected), */ \ + { 0xf8d2, \ + "calibr_temp_gain" }, /* Temperature gain 2's compliment (key1 protected) , */ \ + { 0xf900, \ + "mtp_lock_dcdcoff_mode" }, /* Disable function dcdcoff_mode , */ \ + { 0xf910, \ + "mtp_lock_enbl_coolflux" }, /* Disable function enbl_coolflux , */ \ + { 0xf920, \ + "mtp_lock_bypass_clipper" }, /* Disable function bypass_clipper , */ \ + { 0xf930, \ + "mtp_lock_max_dcdc_voltage" }, /* Disable programming of max dcdc boost voltage , */ \ + { 0xf943, \ + "calibr_vbg_trim" }, /* Bandgap trimming control , */ \ + { 0xf987, \ + "type_bits_fw" }, /* MTP-control FW - See Firmware I2C API document for details, */ \ + { 0xfa0f, \ + "mtpdataA" }, /* MTPdataA (key1 protected) , */ \ + { 0xfb0f, \ + "mtpdataB" }, /* MTPdataB (key1 protected) , */ \ + { 0xfc0f, \ + "mtpdataC" }, /* MTPdataC (key1 protected) , */ \ + { 0xfd0f, \ + "mtpdataD" }, /* MTPdataD (key1 protected) , */ \ + { 0xfe0f, \ + "mtpdataE" }, /* MTPdataE (key1 protected) , */ \ + { 0xff05, \ + "calibr_osc_delta_ndiv" }, /* Calibration data for OSC1M, signed number representation, */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +enum tfa2_irq { + tfa2_irq_stvdds = 0, + tfa2_irq_stplls = 1, + tfa2_irq_stotds = 2, + tfa2_irq_stovds = 3, + tfa2_irq_stuvds = 4, + tfa2_irq_stclks = 5, + tfa2_irq_stmtpb = 6, + tfa2_irq_stnoclk = 7, + tfa2_irq_stspks = 8, + tfa2_irq_stacs = 9, + tfa2_irq_stsws = 10, + tfa2_irq_stwds = 11, + tfa2_irq_stamps = 12, + tfa2_irq_starefs = 13, + tfa2_irq_stadccr = 14, + tfa2_irq_stbodnok = 15, + tfa2_irq_stbstcu = 16, + tfa2_irq_stbsthi = 17, + tfa2_irq_stbstoc = 18, + tfa2_irq_stbstpkcur = 19, + tfa2_irq_stbstvc = 20, + tfa2_irq_stbst86 = 21, + tfa2_irq_stbst93 = 22, + tfa2_irq_strcvld = 23, + tfa2_irq_stocpl = 24, + tfa2_irq_stocpr = 25, + tfa2_irq_stmwsrc = 26, + tfa2_irq_stmwcfc = 27, + tfa2_irq_stmwsmu = 28, + tfa2_irq_stcfmer = 29, + tfa2_irq_stcfmac = 30, + tfa2_irq_stclkoor = 31, + tfa2_irq_sttdmer = 32, + tfa2_irq_stclpl = 33, + tfa2_irq_stclpr = 34, + tfa2_irq_stocpm = 35, + tfa2_irq_max = 36, + tfa2_irq_all = -1 /* all irqs */ +}; + +#define TFA2_IRQ_NAMETABLE \ + static tfaIrqName_t Tfa2IrqNames[] = { \ + { 0, "STVDDS" }, { 1, "STPLLS" }, { 2, "STOTDS" }, \ + { 3, "STOVDS" }, { 4, "STUVDS" }, { 5, "STCLKS" }, \ + { 6, "STMTPB" }, { 7, "STNOCLK" }, { 8, "STSPKS" }, \ + { 9, "STACS" }, { 10, "STSWS" }, { 11, "STWDS" }, \ + { 12, "STAMPS" }, { 13, "STAREFS" }, { 14, "STADCCR" }, \ + { 15, "STBODNOK" }, { 16, "STBSTCU" }, { 17, "STBSTHI" }, \ + { 18, "STBSTOC" }, { 19, "STBSTPKCUR" }, { 20, "STBSTVC" }, \ + { 21, "STBST86" }, { 22, "STBST93" }, { 23, "STRCVLD" }, \ + { 24, "STOCPL" }, { 25, "STOCPR" }, { 26, "STMWSRC" }, \ + { 27, "STMWCFC" }, { 28, "STMWSMU" }, { 29, "STCFMER" }, \ + { 30, "STCFMAC" }, { 31, "STCLKOOR" }, { 32, "STTDMER" }, \ + { 33, "STCLPL" }, { 34, "STCLPR" }, { 35, "STOCPM" }, \ + { 36, "36" }, \ + }; diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9872_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9872_tfafieldnames.h new file mode 100644 index 000000000000..c3615273e3ed --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9872_tfafieldnames.h @@ -0,0 +1,2312 @@ +/** Filename: Tfa9872_TfaFieldnames.h + * This file was generated automatically on 10/11/16 at 10:19:27. + * Source file: TFA9872N1B2_DefaultI2CSettings -v16.xlsx + */ + +#ifndef _TFA9872_TFAFIELDNAMES_H +#define _TFA9872_TFAFIELDNAMES_H + +#define TFA9872_I2CVERSION_N1A 26 +#define TFA9872_I2CVERSION_N1B 29 +#define TFA9872_I2CVERSION_N1B2 21 + +typedef enum nxpTfa9872BfEnumList { + TFA9872_BF_PWDN = + 0x0000, /*!< Powerdown selection */ + TFA9872_BF_I2CR = + 0x0010, /*!< I2C Reset - Auto clear */ + TFA9872_BF_AMPE = + 0x0030, /*!< Activate Amplifier */ + TFA9872_BF_DCA = + 0x0040, /*!< Activate DC-to-DC converter */ + TFA9872_BF_INTP = + 0x0071, /*!< Interrupt config */ + TFA9872_BF_BYPOCP = + 0x00b0, /*!< Bypass OCP */ + TFA9872_BF_TSTOCP = + 0x00c0, /*!< OCP testing control */ + TFA9872_BF_MANSCONF = + 0x0120, /*!< I2C configured */ + TFA9872_BF_MANAOOSC = + 0x0140, /*!< Internal osc off at PWDN */ + TFA9872_BF_MUTETO = + 0x01d0, /*!< Time out SB mute sequence */ + TFA9872_BF_RCVNS = + 0x01e0, /*!< Noise shaper selection */ + TFA9872_BF_AUDFS = + 0x0203, /*!< Sample rate (fs) */ + TFA9872_BF_INPLEV = + 0x0240, /*!< TDM output attenuation */ + TFA9872_BF_FRACTDEL = + 0x0255, /*!< V/I Fractional delay */ + TFA9872_BF_BYPHVBF = + 0x02b0, /*!< Bypass HVBAT filter */ + TFA9872_BF_REV = + 0x030f, /*!< Revision info */ + TFA9872_BF_REFCKEXT = + 0x0401, /*!< PLL external ref clock */ + TFA9872_BF_REFCKSEL = + 0x0420, /*!< PLL internal ref clock */ + TFA9872_BF_SSE = + 0x0510, /*!< Enable speaker path */ + TFA9872_BF_VSE = + 0x0530, /*!< Voltage sense */ + TFA9872_BF_CSE = + 0x0550, /*!< Current sense */ + TFA9872_BF_SSPDME = + 0x0560, /*!< Sub-system PDM */ + TFA9872_BF_PGAE = + 0x0580, /*!< Enable PGA chop clock */ + TFA9872_BF_SSTDME = + 0x0590, /*!< Sub-system TDM */ + TFA9872_BF_SSPBSTE = + 0x05a0, /*!< Sub-system boost */ + TFA9872_BF_SSADCE = + 0x05b0, /*!< Sub-system ADC */ + TFA9872_BF_SSFAIME = + 0x05c0, /*!< Sub-system FAIM */ + TFA9872_BF_STGAIN = + 0x0d18, /*!< Side tone gain */ + TFA9872_BF_STSMUTE = + 0x0da0, /*!< Side tone soft mute */ + TFA9872_BF_ST1C = + 0x0db0, /*!< side tone one s complement */ + TFA9872_BF_VDDS = + 0x1000, /*!< POR */ + TFA9872_BF_PLLS = + 0x1010, /*!< PLL lock */ + TFA9872_BF_OTDS = + 0x1020, /*!< OTP alarm */ + TFA9872_BF_OVDS = + 0x1030, /*!< OVP alarm */ + TFA9872_BF_UVDS = + 0x1040, /*!< UVP alarm */ + TFA9872_BF_CLKS = + 0x1050, /*!< Clocks stable */ + TFA9872_BF_MTPB = + 0x1060, /*!< MTP busy */ + TFA9872_BF_NOCLK = + 0x1070, /*!< Lost clock */ + TFA9872_BF_SWS = + 0x10a0, /*!< Amplifier engage */ + TFA9872_BF_AMPS = + 0x10c0, /*!< Amplifier enable */ + TFA9872_BF_AREFS = + 0x10d0, /*!< References enable */ + TFA9872_BF_ADCCR = + 0x10e0, /*!< Control ADC */ + TFA9872_BF_DCIL = + 0x1100, /*!< DCDC current limiting */ + TFA9872_BF_DCDCA = + 0x1110, /*!< DCDC active */ + TFA9872_BF_DCOCPOK = + 0x1120, /*!< DCDC OCP nmos */ + TFA9872_BF_DCHVBAT = + 0x1140, /*!< DCDC level 1x */ + TFA9872_BF_DCH114 = + 0x1150, /*!< DCDC level 1.14x */ + TFA9872_BF_DCH107 = + 0x1160, /*!< DCDC level 1.07x */ + TFA9872_BF_STMUTEB = + 0x1170, /*!< side tone (un)mute busy */ + TFA9872_BF_STMUTE = + 0x1180, /*!< side tone mute state */ + TFA9872_BF_TDMLUTER = + 0x1190, /*!< TDM LUT error */ + TFA9872_BF_TDMSTAT = + 0x11a2, /*!< TDM status bits */ + TFA9872_BF_TDMERR = + 0x11d0, /*!< TDM error */ + TFA9872_BF_OCPOAP = + 0x1300, /*!< OCPOK pmos A */ + TFA9872_BF_OCPOAN = + 0x1310, /*!< OCPOK nmos A */ + TFA9872_BF_OCPOBP = + 0x1320, /*!< OCPOK pmos B */ + TFA9872_BF_OCPOBN = + 0x1330, /*!< OCPOK nmos B */ + TFA9872_BF_CLIPAH = + 0x1340, /*!< Clipping A to Vddp */ + TFA9872_BF_CLIPAL = + 0x1350, /*!< Clipping A to gnd */ + TFA9872_BF_CLIPBH = + 0x1360, /*!< Clipping B to Vddp */ + TFA9872_BF_CLIPBL = + 0x1370, /*!< Clipping B to gnd */ + TFA9872_BF_OCDS = + 0x1380, /*!< OCP amplifier */ + TFA9872_BF_CLIPS = + 0x1390, /*!< Amplifier clipping */ + TFA9872_BF_OCPOKMC = + 0x13a0, /*!< OCPOK MICVDD */ + TFA9872_BF_MANALARM = + 0x13b0, /*!< Alarm state */ + TFA9872_BF_MANWAIT1 = + 0x13c0, /*!< Wait HW I2C settings */ + TFA9872_BF_MANMUTE = + 0x13e0, /*!< Audio mute sequence */ + TFA9872_BF_MANOPER = + 0x13f0, /*!< Operating state */ + TFA9872_BF_CLKOOR = + 0x1420, /*!< External clock status */ + TFA9872_BF_MANSTATE = + 0x1433, /*!< Device manager status */ + TFA9872_BF_DCMODE = + 0x1471, /*!< DCDC mode status bits */ + TFA9872_BF_BATS = + 0x1509, /*!< Battery voltage (V) */ + TFA9872_BF_TEMPS = + 0x1608, /*!< IC Temperature (C) */ + TFA9872_BF_VDDPS = + 0x1709, /*!< IC VDDP voltage ( 1023*VDDP/9.5 V) */ + TFA9872_BF_TDME = + 0x2040, /*!< Enable interface */ + TFA9872_BF_TDMMODE = + 0x2050, /*!< Slave/master */ + TFA9872_BF_TDMCLINV = + 0x2060, /*!< Reception data to BCK clock */ + TFA9872_BF_TDMFSLN = + 0x2073, /*!< FS length (master mode only) */ + TFA9872_BF_TDMFSPOL = + 0x20b0, /*!< FS polarity */ + TFA9872_BF_TDMNBCK = + 0x20c3, /*!< N-BCK's in FS */ + TFA9872_BF_TDMSLOTS = + 0x2103, /*!< N-slots in Frame */ + TFA9872_BF_TDMSLLN = + 0x2144, /*!< N-bits in slot */ + TFA9872_BF_TDMBRMG = + 0x2194, /*!< N-bits remaining */ + TFA9872_BF_TDMDEL = + 0x21e0, /*!< data delay to FS */ + TFA9872_BF_TDMADJ = + 0x21f0, /*!< data adjustment */ + TFA9872_BF_TDMOOMP = + 0x2201, /*!< Received audio compression */ + TFA9872_BF_TDMSSIZE = + 0x2224, /*!< Sample size per slot */ + TFA9872_BF_TDMTXDFO = + 0x2271, /*!< Format unused bits */ + TFA9872_BF_TDMTXUS0 = + 0x2291, /*!< Format unused slots DATAO */ + TFA9872_BF_TDMSPKE = + 0x2300, /*!< Control audio tdm channel in 0 (spkr + dcdc) */ + TFA9872_BF_TDMDCE = + 0x2310, /*!< Control audio tdm channel in 1 (dcdc) */ + TFA9872_BF_TDMCSE = + 0x2330, /*!< current sense vbat temperature and vddp feedback */ + TFA9872_BF_TDMVSE = + 0x2340, /*!< Voltage sense vbat temperature and vddp feedback */ + TFA9872_BF_TDMSPKS = + 0x2603, /*!< tdm slot for sink 0 (speaker + dcdc) */ + TFA9872_BF_TDMDCS = + 0x2643, /*!< tdm slot for sink 1 (dcdc) */ + TFA9872_BF_TDMCSS = + 0x26c3, /*!< Slot Position of current sense vbat temperature and vddp feedback */ + TFA9872_BF_TDMVSS = + 0x2703, /*!< Slot Position of Voltage sense vbat temperature and vddp feedback */ + TFA9872_BF_PDMSTSEL = + 0x3111, /*!< Side tone input */ + TFA9872_BF_ISTVDDS = + 0x4000, /*!< Status POR */ + TFA9872_BF_ISTPLLS = + 0x4010, /*!< Status PLL lock */ + TFA9872_BF_ISTOTDS = + 0x4020, /*!< Status OTP alarm */ + TFA9872_BF_ISTOVDS = + 0x4030, /*!< Status OVP alarm */ + TFA9872_BF_ISTUVDS = + 0x4040, /*!< Status UVP alarm */ + TFA9872_BF_ISTCLKS = + 0x4050, /*!< Status clocks stable */ + TFA9872_BF_ISTMTPB = + 0x4060, /*!< Status MTP busy */ + TFA9872_BF_ISTNOCLK = + 0x4070, /*!< Status lost clock */ + TFA9872_BF_ISTSWS = + 0x40a0, /*!< Status amplifier engage */ + TFA9872_BF_ISTAMPS = + 0x40c0, /*!< Status amplifier enable */ + TFA9872_BF_ISTAREFS = + 0x40d0, /*!< Status Ref enable */ + TFA9872_BF_ISTADCCR = + 0x40e0, /*!< Status Control ADC */ + TFA9872_BF_ISTBSTCU = + 0x4100, /*!< Status DCDC current limiting */ + TFA9872_BF_ISTBSTHI = + 0x4110, /*!< Status DCDC active */ + TFA9872_BF_ISTBSTOC = + 0x4120, /*!< Status DCDC OCP */ + TFA9872_BF_ISTBSTPKCUR = + 0x4130, /*!< Status bst peakcur */ + TFA9872_BF_ISTBSTVC = + 0x4140, /*!< Status DCDC level 1x */ + TFA9872_BF_ISTBST86 = + 0x4150, /*!< Status DCDC level 1.14x */ + TFA9872_BF_ISTBST93 = + 0x4160, /*!< Status DCDC level 1.07x */ + TFA9872_BF_ISTOCPR = + 0x4190, /*!< Status ocp alarm */ + TFA9872_BF_ISTMWSRC = + 0x41a0, /*!< Status Waits HW I2C settings */ + TFA9872_BF_ISTMWSMU = + 0x41c0, /*!< Status Audio mute sequence */ + TFA9872_BF_ISTCLKOOR = + 0x41f0, /*!< Status flag_clk_out_of_range */ + TFA9872_BF_ISTTDMER = + 0x4200, /*!< Status tdm error */ + TFA9872_BF_ISTCLPR = + 0x4220, /*!< Status clip */ + TFA9872_BF_ISTLP0 = + 0x4240, /*!< Status low power mode0 */ + TFA9872_BF_ISTLP1 = + 0x4250, /*!< Status low power mode1 */ + TFA9872_BF_ISTLA = + 0x4260, /*!< Status low noise detection */ + TFA9872_BF_ISTVDDPH = + 0x4270, /*!< Status VDDP greater than VBAT */ + TFA9872_BF_ICLVDDS = + 0x4400, /*!< Clear POR */ + TFA9872_BF_ICLPLLS = + 0x4410, /*!< Clear PLL lock */ + TFA9872_BF_ICLOTDS = + 0x4420, /*!< Clear OTP alarm */ + TFA9872_BF_ICLOVDS = + 0x4430, /*!< Clear OVP alarm */ + TFA9872_BF_ICLUVDS = + 0x4440, /*!< Clear UVP alarm */ + TFA9872_BF_ICLCLKS = + 0x4450, /*!< Clear clocks stable */ + TFA9872_BF_ICLMTPB = + 0x4460, /*!< Clear mtp busy */ + TFA9872_BF_ICLNOCLK = + 0x4470, /*!< Clear lost clk */ + TFA9872_BF_ICLSWS = + 0x44a0, /*!< Clear amplifier engage */ + TFA9872_BF_ICLAMPS = + 0x44c0, /*!< Clear enbl amp */ + TFA9872_BF_ICLAREFS = + 0x44d0, /*!< Clear ref enable */ + TFA9872_BF_ICLADCCR = + 0x44e0, /*!< Clear control ADC */ + TFA9872_BF_ICLBSTCU = + 0x4500, /*!< Clear DCDC current limiting */ + TFA9872_BF_ICLBSTHI = + 0x4510, /*!< Clear DCDC active */ + TFA9872_BF_ICLBSTOC = + 0x4520, /*!< Clear DCDC OCP */ + TFA9872_BF_ICLBSTPC = + 0x4530, /*!< Clear bst peakcur */ + TFA9872_BF_ICLBSTVC = + 0x4540, /*!< Clear DCDC level 1x */ + TFA9872_BF_ICLBST86 = + 0x4550, /*!< Clear DCDC level 1.14x */ + TFA9872_BF_ICLBST93 = + 0x4560, /*!< Clear DCDC level 1.07x */ + TFA9872_BF_ICLOCPR = + 0x4590, /*!< Clear ocp alarm */ + TFA9872_BF_ICLMWSRC = + 0x45a0, /*!< Clear wait HW I2C settings */ + TFA9872_BF_ICLMWSMU = + 0x45c0, /*!< Clear audio mute sequence */ + TFA9872_BF_ICLCLKOOR = + 0x45f0, /*!< Clear flag_clk_out_of_range */ + TFA9872_BF_ICLTDMER = + 0x4600, /*!< Clear tdm error */ + TFA9872_BF_ICLCLPR = + 0x4620, /*!< Clear clip */ + TFA9872_BF_ICLLP0 = + 0x4640, /*!< Clear low power mode0 */ + TFA9872_BF_ICLLP1 = + 0x4650, /*!< Clear low power mode1 */ + TFA9872_BF_ICLLA = + 0x4660, /*!< Clear low noise detection */ + TFA9872_BF_ICLVDDPH = + 0x4670, /*!< Clear VDDP greater then VBAT */ + TFA9872_BF_IEVDDS = + 0x4800, /*!< Enable por */ + TFA9872_BF_IEPLLS = + 0x4810, /*!< Enable pll lock */ + TFA9872_BF_IEOTDS = + 0x4820, /*!< Enable OTP alarm */ + TFA9872_BF_IEOVDS = + 0x4830, /*!< Enable OVP alarm */ + TFA9872_BF_IEUVDS = + 0x4840, /*!< Enable UVP alarm */ + TFA9872_BF_IECLKS = + 0x4850, /*!< Enable clocks stable */ + TFA9872_BF_IEMTPB = + 0x4860, /*!< Enable mtp busy */ + TFA9872_BF_IENOCLK = + 0x4870, /*!< Enable lost clk */ + TFA9872_BF_IESWS = + 0x48a0, /*!< Enable amplifier engage */ + TFA9872_BF_IEAMPS = + 0x48c0, /*!< Enable enbl amp */ + TFA9872_BF_IEAREFS = + 0x48d0, /*!< Enable ref enable */ + TFA9872_BF_IEADCCR = + 0x48e0, /*!< Enable Control ADC */ + TFA9872_BF_IEBSTCU = + 0x4900, /*!< Enable DCDC current limiting */ + TFA9872_BF_IEBSTHI = + 0x4910, /*!< Enable DCDC active */ + TFA9872_BF_IEBSTOC = + 0x4920, /*!< Enable DCDC OCP */ + TFA9872_BF_IEBSTPC = + 0x4930, /*!< Enable bst peakcur */ + TFA9872_BF_IEBSTVC = + 0x4940, /*!< Enable DCDC level 1x */ + TFA9872_BF_IEBST86 = + 0x4950, /*!< Enable DCDC level 1.14x */ + TFA9872_BF_IEBST93 = + 0x4960, /*!< Enable DCDC level 1.07x */ + TFA9872_BF_IEOCPR = + 0x4990, /*!< Enable ocp alarm */ + TFA9872_BF_IEMWSRC = + 0x49a0, /*!< Enable waits HW I2C settings */ + TFA9872_BF_IEMWSMU = + 0x49c0, /*!< Enable man Audio mute sequence */ + TFA9872_BF_IECLKOOR = + 0x49f0, /*!< Enable flag_clk_out_of_range */ + TFA9872_BF_IETDMER = + 0x4a00, /*!< Enable tdm error */ + TFA9872_BF_IECLPR = + 0x4a20, /*!< Enable clip */ + TFA9872_BF_IELP0 = + 0x4a40, /*!< Enable low power mode0 */ + TFA9872_BF_IELP1 = + 0x4a50, /*!< Enable low power mode1 */ + TFA9872_BF_IELA = + 0x4a60, /*!< Enable low noise detection */ + TFA9872_BF_IEVDDPH = + 0x4a70, /*!< Enable VDDP greater tehn VBAT */ + TFA9872_BF_IPOVDDS = + 0x4c00, /*!< Polarity por */ + TFA9872_BF_IPOPLLS = + 0x4c10, /*!< Polarity pll lock */ + TFA9872_BF_IPOOTDS = + 0x4c20, /*!< Polarity OTP alarm */ + TFA9872_BF_IPOOVDS = + 0x4c30, /*!< Polarity OVP alarm */ + TFA9872_BF_IPOUVDS = + 0x4c40, /*!< Polarity UVP alarm */ + TFA9872_BF_IPOCLKS = + 0x4c50, /*!< Polarity clocks stable */ + TFA9872_BF_IPOMTPB = + 0x4c60, /*!< Polarity mtp busy */ + TFA9872_BF_IPONOCLK = + 0x4c70, /*!< Polarity lost clk */ + TFA9872_BF_IPOSWS = + 0x4ca0, /*!< Polarity amplifier engage */ + TFA9872_BF_IPOAMPS = + 0x4cc0, /*!< Polarity enbl amp */ + TFA9872_BF_IPOAREFS = + 0x4cd0, /*!< Polarity ref enable */ + TFA9872_BF_IPOADCCR = + 0x4ce0, /*!< Polarity Control ADC */ + TFA9872_BF_IPOBSTCU = + 0x4d00, /*!< Polarity DCDC current limiting */ + TFA9872_BF_IPOBSTHI = + 0x4d10, /*!< Polarity DCDC active */ + TFA9872_BF_IPOBSTOC = + 0x4d20, /*!< Polarity DCDC OCP */ + TFA9872_BF_IPOBSTPC = + 0x4d30, /*!< Polarity bst peakcur */ + TFA9872_BF_IPOBSTVC = + 0x4d40, /*!< Polarity DCDC level 1x */ + TFA9872_BF_IPOBST86 = + 0x4d50, /*!< Polarity DCDC level 1.14x */ + TFA9872_BF_IPOBST93 = + 0x4d60, /*!< Polarity DCDC level 1.07x */ + TFA9872_BF_IPOOCPR = + 0x4d90, /*!< Polarity ocp alarm */ + TFA9872_BF_IPOMWSRC = + 0x4da0, /*!< Polarity waits HW I2C settings */ + TFA9872_BF_IPOMWSMU = + 0x4dc0, /*!< Polarity man audio mute sequence */ + TFA9872_BF_IPCLKOOR = + 0x4df0, /*!< Polarity flag_clk_out_of_range */ + TFA9872_BF_IPOTDMER = + 0x4e00, /*!< Polarity tdm error */ + TFA9872_BF_IPOCLPR = + 0x4e20, /*!< Polarity clip right */ + TFA9872_BF_IPOLP0 = + 0x4e40, /*!< Polarity low power mode0 */ + TFA9872_BF_IPOLP1 = + 0x4e50, /*!< Polarity low power mode1 */ + TFA9872_BF_IPOLA = + 0x4e60, /*!< Polarity low noise mode */ + TFA9872_BF_IPOVDDPH = + 0x4e70, /*!< Polarity VDDP greater than VBAT */ + TFA9872_BF_BSSCR = + 0x5001, /*!< Battery Safeguard attack time */ + TFA9872_BF_BSST = + 0x5023, /*!< Battery Safeguard threshold voltage level */ + TFA9872_BF_BSSRL = + 0x5061, /*!< Battery Safeguard maximum reduction */ + TFA9872_BF_BSSR = + 0x50e0, /*!< Battery voltage read out */ + TFA9872_BF_BSSBY = + 0x50f0, /*!< Bypass battery safeguard */ + TFA9872_BF_BSSS = + 0x5100, /*!< Vbat prot steepness */ + TFA9872_BF_INTSMUTE = + 0x5110, /*!< Soft mute HW */ + TFA9872_BF_HPFBYP = + 0x5150, /*!< Bypass HPF */ + TFA9872_BF_DPSA = + 0x5170, /*!< Enable DPSA */ + TFA9872_BF_CLIPCTRL = + 0x5222, /*!< Clip control setting */ + TFA9872_BF_AMPGAIN = + 0x5257, /*!< Amplifier gain */ + TFA9872_BF_SLOPEE = + 0x52d0, /*!< Enables slope control */ + TFA9872_BF_SLOPESET = + 0x52e0, /*!< Slope speed setting (bin. coded) */ + TFA9872_BF_PGAGAIN = + 0x6081, /*!< PGA gain selection */ + TFA9872_BF_PGALPE = + 0x60b0, /*!< Lowpass enable */ + TFA9872_BF_LPM0BYP = + 0x6110, /*!< bypass low power idle mode */ + TFA9872_BF_TDMDCG = + 0x6123, /*!< Second channel gain in case of stereo using a single coil. (Total gain depending on INPLEV). (In case of mono OR stereo using 2 separate DCDC channel 1 should be disabled using TDMDCE) */ + TFA9872_BF_TDMSPKG = + 0x6163, /*!< Total gain depending on INPLEV setting (channel 0) */ + TFA9872_BF_STIDLEEN = + 0x61b0, /*!< enable idle feature for channel 1 */ + TFA9872_BF_LNMODE = + 0x62e1, /*!< ctrl select mode */ + TFA9872_BF_LPM1MODE = + 0x64e1, /*!< low power mode control */ + TFA9872_BF_LPM1DIS = + 0x65c0, /*!< low power mode1 detector control */ + TFA9872_BF_TDMSRCMAP = + 0x6801, /*!< tdm source mapping */ + TFA9872_BF_TDMSRCAS = + 0x6821, /*!< Sensed value A */ + TFA9872_BF_TDMSRCBS = + 0x6841, /*!< Sensed value B */ + TFA9872_BF_ANCSEL = + 0x6881, /*!< anc input */ + TFA9872_BF_ANC1C = + 0x68a0, /*!< ANC one s complement */ + TFA9872_BF_SAMMODE = + 0x6901, /*!< sam enable */ + TFA9872_BF_SAMSEL = + 0x6920, /*!< sam source */ + TFA9872_BF_PDMOSELH = + 0x6931, /*!< pdm out value when pdm_clk is higth */ + TFA9872_BF_PDMOSELL = + 0x6951, /*!< pdm out value when pdm_clk is low */ + TFA9872_BF_SAMOSEL = + 0x6970, /*!< ram output on mode sam and audio */ + TFA9872_BF_LP0 = + 0x6e00, /*!< low power mode 0 detection */ + TFA9872_BF_LP1 = + 0x6e10, /*!< low power mode 1 detection */ + TFA9872_BF_LA = + 0x6e20, /*!< low amplitude detection */ + TFA9872_BF_VDDPH = + 0x6e30, /*!< vddp greater than vbat */ + TFA9872_BF_DELCURCOMP = + 0x6f02, /*!< delay to allign compensation signal with current sense signal */ + TFA9872_BF_SIGCURCOMP = + 0x6f40, /*!< polarity of compensation for current sense */ + TFA9872_BF_ENCURCOMP = + 0x6f50, /*!< enable current sense compensation */ + TFA9872_BF_SELCLPPWM = + 0x6f60, /*!< Select pwm clip flag */ + TFA9872_BF_LVLCLPPWM = + 0x6f72, /*!< set the amount of pwm pulse that may be skipped before clip-flag is triggered */ + TFA9872_BF_DCVOS = + 0x7002, /*!< Second boost voltage level */ + TFA9872_BF_DCMCC = + 0x7033, /*!< Max coil current */ + TFA9872_BF_DCCV = + 0x7071, /*!< Slope compensation current, represents LxF (inductance x frequency) value */ + TFA9872_BF_DCIE = + 0x7090, /*!< Adaptive boost mode */ + TFA9872_BF_DCSR = + 0x70a0, /*!< Soft ramp up/down */ + TFA9872_BF_DCDIS = + 0x70e0, /*!< DCDC on/off */ + TFA9872_BF_DCPWM = + 0x70f0, /*!< DCDC PWM only mode */ + TFA9872_BF_DCVOF = + 0x7402, /*!< 1st boost voltage level */ + TFA9872_BF_DCTRACK = + 0x7430, /*!< Boost algorithm selection, effective only when boost_intelligent is set to 1 */ + TFA9872_BF_DCTRIP = + 0x7444, /*!< 1st Adaptive boost trip levels, effective only when DCIE is set to 1 */ + TFA9872_BF_DCHOLD = + 0x7494, /*!< Hold time for DCDC booster, effective only when boost_intelligent is set to 1 */ + TFA9872_BF_DCTRIP2 = + 0x7534, /*!< 2nd Adaptive boost trip levels, effective only when DCIE is set to 1 */ + TFA9872_BF_DCTRIPT = + 0x7584, /*!< Track Adaptive boost trip levels, effective only when boost_intelligent is set to 1 */ + TFA9872_BF_MTPK = + 0xa107, /*!< MTP KEY2 register */ + TFA9872_BF_KEY1LOCKED = + 0xa200, /*!< Indicates KEY1 is locked */ + TFA9872_BF_KEY2LOCKED = + 0xa210, /*!< Indicates KEY2 is locked */ + TFA9872_BF_CMTPI = + 0xa350, /*!< Start copying all the data from mtp to I2C mtp registers */ + TFA9872_BF_CIMTP = + 0xa360, /*!< Start copying data from I2C mtp registers to mtp */ + TFA9872_BF_MTPRDMSB = + 0xa50f, /*!< MSB word of MTP manual read data */ + TFA9872_BF_MTPRDLSB = + 0xa60f, /*!< LSB word of MTP manual read data */ + TFA9872_BF_EXTTS = + 0xb108, /*!< External temperature (C) */ + TFA9872_BF_TROS = + 0xb190, /*!< Select temp Speaker calibration */ + TFA9872_BF_SWPROFIL = + 0xee0f, /*!< Software profile data */ + TFA9872_BF_SWVSTEP = + 0xef0f, /*!< Software vstep information */ + TFA9872_BF_MTPOTC = + 0xf000, /*!< Calibration schedule */ + TFA9872_BF_MTPEX = + 0xf010, /*!< Calibration Ron executed */ + TFA9872_BF_DCMCCAPI = + 0xf020, /*!< Calibration current limit DCDC */ + TFA9872_BF_DCMCCSB = + 0xf030, /*!< Sign bit for delta calibration current limit DCDC */ + TFA9872_BF_USERDEF = + 0xf042, /*!< Calibration delta current limit DCDC */ + TFA9872_BF_CUSTINFO = + 0xf078, /*!< Reserved space for allowing customer to store speaker information */ + TFA9872_BF_R25C = + 0xf50f, /*!< Ron resistance of speaker coil */ +} nxpTfa9872BfEnumList_t; +#define TFA9872_NAMETABLE \ + static tfaBfName_t Tfa9872DatasheetNames[] = { \ + { 0x0, \ + "PWDN" }, /* Powerdown selection , */ \ + { 0x10, \ + "I2CR" }, /* I2C Reset - Auto clear , */ \ + { 0x30, \ + "AMPE" }, /* Activate Amplifier , */ \ + { 0x40, \ + "DCA" }, /* Activate DC-to-DC converter , */ \ + { 0x71, \ + "INTP" }, /* Interrupt config , */ \ + { 0xb0, \ + "BYPOCP" }, /* Bypass OCP , */ \ + { 0xc0, \ + "TSTOCP" }, /* OCP testing control , */ \ + { 0x120, \ + "MANSCONF" }, /* I2C configured , */ \ + { 0x140, \ + "MANAOOSC" }, /* Internal osc off at PWDN , */ \ + { 0x1d0, \ + "MUTETO" }, /* Time out SB mute sequence , */ \ + { 0x1e0, \ + "RCVNS" }, /* Noise shaper selection , */ \ + { 0x203, \ + "AUDFS" }, /* Sample rate (fs) , */ \ + { 0x240, \ + "INPLEV" }, /* TDM output attenuation , */ \ + { 0x255, \ + "FRACTDEL" }, /* V/I Fractional delay , */ \ + { 0x2b0, \ + "BYPHVBF" }, /* Bypass HVBAT filter , */ \ + { 0x30f, \ + "REV" }, /* Revision info , */ \ + { 0x401, \ + "REFCKEXT" }, /* PLL external ref clock , */ \ + { 0x420, \ + "REFCKSEL" }, /* PLL internal ref clock , */ \ + { 0x510, \ + "SSE" }, /* Enable speaker path , */ \ + { 0x530, \ + "VSE" }, /* Voltage sense , */ \ + { 0x550, \ + "CSE" }, /* Current sense , */ \ + { 0x560, \ + "SSPDME" }, /* Sub-system PDM , */ \ + { 0x580, \ + "PGAE" }, /* Enable PGA chop clock , */ \ + { 0x590, \ + "SSTDME" }, /* Sub-system TDM , */ \ + { 0x5a0, \ + "SSPBSTE" }, /* Sub-system boost , */ \ + { 0x5b0, \ + "SSADCE" }, /* Sub-system ADC , */ \ + { 0x5c0, \ + "SSFAIME" }, /* Sub-system FAIM , */ \ + { 0xd18, \ + "STGAIN" }, /* Side tone gain , */ \ + { 0xda0, \ + "STSMUTE" }, /* Side tone soft mute , */ \ + { 0xdb0, \ + "ST1C" }, /* side tone one s complement , */ \ + { 0x1000, \ + "VDDS" }, /* POR , */ \ + { 0x1010, \ + "PLLS" }, /* PLL lock , */ \ + { 0x1020, \ + "OTDS" }, /* OTP alarm , */ \ + { 0x1030, \ + "OVDS" }, /* OVP alarm , */ \ + { 0x1040, \ + "UVDS" }, /* UVP alarm , */ \ + { 0x1050, \ + "CLKS" }, /* Clocks stable , */ \ + { 0x1060, \ + "MTPB" }, /* MTP busy , */ \ + { 0x1070, \ + "NOCLK" }, /* Lost clock , */ \ + { 0x10a0, \ + "SWS" }, /* Amplifier engage , */ \ + { 0x10c0, \ + "AMPS" }, /* Amplifier enable , */ \ + { 0x10d0, \ + "AREFS" }, /* References enable , */ \ + { 0x10e0, \ + "ADCCR" }, /* Control ADC , */ \ + { 0x1100, \ + "DCIL" }, /* DCDC current limiting , */ \ + { 0x1110, \ + "DCDCA" }, /* DCDC active , */ \ + { 0x1120, \ + "DCOCPOK" }, /* DCDC OCP nmos , */ \ + { 0x1140, \ + "DCHVBAT" }, /* DCDC level 1x , */ \ + { 0x1150, \ + "DCH114" }, /* DCDC level 1.14x , */ \ + { 0x1160, \ + "DCH107" }, /* DCDC level 1.07x , */ \ + { 0x1170, \ + "STMUTEB" }, /* side tone (un)mute busy , */ \ + { 0x1180, \ + "STMUTE" }, /* side tone mute state , */ \ + { 0x1190, \ + "TDMLUTER" }, /* TDM LUT error , */ \ + { 0x11a2, \ + "TDMSTAT" }, /* TDM status bits , */ \ + { 0x11d0, \ + "TDMERR" }, /* TDM error , */ \ + { 0x1300, \ + "OCPOAP" }, /* OCPOK pmos A , */ \ + { 0x1310, \ + "OCPOAN" }, /* OCPOK nmos A , */ \ + { 0x1320, \ + "OCPOBP" }, /* OCPOK pmos B , */ \ + { 0x1330, \ + "OCPOBN" }, /* OCPOK nmos B , */ \ + { 0x1340, \ + "CLIPAH" }, /* Clipping A to Vddp , */ \ + { 0x1350, \ + "CLIPAL" }, /* Clipping A to gnd , */ \ + { 0x1360, \ + "CLIPBH" }, /* Clipping B to Vddp , */ \ + { 0x1370, \ + "CLIPBL" }, /* Clipping B to gnd , */ \ + { 0x1380, \ + "OCDS" }, /* OCP amplifier , */ \ + { 0x1390, \ + "CLIPS" }, /* Amplifier clipping , */ \ + { 0x13a0, \ + "OCPOKMC" }, /* OCPOK MICVDD , */ \ + { 0x13b0, \ + "MANALARM" }, /* Alarm state , */ \ + { 0x13c0, \ + "MANWAIT1" }, /* Wait HW I2C settings , */ \ + { 0x13e0, \ + "MANMUTE" }, /* Audio mute sequence , */ \ + { 0x13f0, \ + "MANOPER" }, /* Operating state , */ \ + { 0x1420, \ + "CLKOOR" }, /* External clock status , */ \ + { 0x1433, \ + "MANSTATE" }, /* Device manager status , */ \ + { 0x1471, \ + "DCMODE" }, /* DCDC mode status bits , */ \ + { 0x1509, \ + "BATS" }, /* Battery voltage (V) , */ \ + { 0x1608, \ + "TEMPS" }, /* IC Temperature (C) , */ \ + { 0x1709, \ + "VDDPS" }, /* IC VDDP voltage ( 1023*VDDP/9.5 V) , */ \ + { 0x2040, \ + "TDME" }, /* Enable interface , */ \ + { 0x2050, \ + "TDMMODE" }, /* Slave/master , */ \ + { 0x2060, \ + "TDMCLINV" }, /* Reception data to BCK clock , */ \ + { 0x2073, \ + "TDMFSLN" }, /* FS length (master mode only) , */ \ + { 0x20b0, \ + "TDMFSPOL" }, /* FS polarity , */ \ + { 0x20c3, \ + "TDMNBCK" }, /* N-BCK's in FS , */ \ + { 0x2103, \ + "TDMSLOTS" }, /* N-slots in Frame , */ \ + { 0x2144, \ + "TDMSLLN" }, /* N-bits in slot , */ \ + { 0x2194, \ + "TDMBRMG" }, /* N-bits remaining , */ \ + { 0x21e0, \ + "TDMDEL" }, /* data delay to FS , */ \ + { 0x21f0, \ + "TDMADJ" }, /* data adjustment , */ \ + { 0x2201, \ + "TDMOOMP" }, /* Received audio compression , */ \ + { 0x2224, \ + "TDMSSIZE" }, /* Sample size per slot , */ \ + { 0x2271, \ + "TDMTXDFO" }, /* Format unused bits , */ \ + { 0x2291, \ + "TDMTXUS0" }, /* Format unused slots DATAO , */ \ + { 0x2300, \ + "TDMSPKE" }, /* Control audio tdm channel in 0 (spkr + dcdc) , */ \ + { 0x2310, \ + "TDMDCE" }, /* Control audio tdm channel in 1 (dcdc) , */ \ + { 0x2330, \ + "TDMCSE" }, /* current sense vbat temperature and vddp feedback , */ \ + { 0x2340, \ + "TDMVSE" }, /* Voltage sense vbat temperature and vddp feedback , */ \ + { 0x2603, \ + "TDMSPKS" }, /* tdm slot for sink 0 (speaker + dcdc) , */ \ + { 0x2643, \ + "TDMDCS" }, /* tdm slot for sink 1 (dcdc) , */ \ + { 0x26c3, \ + "TDMCSS" }, /* Slot Position of current sense vbat temperature and vddp feedback, */ \ + { 0x2703, \ + "TDMVSS" }, /* Slot Position of Voltage sense vbat temperature and vddp feedback, */ \ + { 0x3111, \ + "PDMSTSEL" }, /* Side tone input , */ \ + { 0x4000, \ + "ISTVDDS" }, /* Status POR , */ \ + { 0x4010, \ + "ISTPLLS" }, /* Status PLL lock , */ \ + { 0x4020, \ + "ISTOTDS" }, /* Status OTP alarm , */ \ + { 0x4030, \ + "ISTOVDS" }, /* Status OVP alarm , */ \ + { 0x4040, \ + "ISTUVDS" }, /* Status UVP alarm , */ \ + { 0x4050, \ + "ISTCLKS" }, /* Status clocks stable , */ \ + { 0x4060, \ + "ISTMTPB" }, /* Status MTP busy , */ \ + { 0x4070, \ + "ISTNOCLK" }, /* Status lost clock , */ \ + { 0x40a0, \ + "ISTSWS" }, /* Status amplifier engage , */ \ + { 0x40c0, \ + "ISTAMPS" }, /* Status amplifier enable , */ \ + { 0x40d0, \ + "ISTAREFS" }, /* Status Ref enable , */ \ + { 0x40e0, \ + "ISTADCCR" }, /* Status Control ADC , */ \ + { 0x4100, \ + "ISTBSTCU" }, /* Status DCDC current limiting , */ \ + { 0x4110, \ + "ISTBSTHI" }, /* Status DCDC active , */ \ + { 0x4120, \ + "ISTBSTOC" }, /* Status DCDC OCP , */ \ + { 0x4130, \ + "ISTBSTPKCUR" }, /* Status bst peakcur , */ \ + { 0x4140, \ + "ISTBSTVC" }, /* Status DCDC level 1x , */ \ + { 0x4150, \ + "ISTBST86" }, /* Status DCDC level 1.14x , */ \ + { 0x4160, \ + "ISTBST93" }, /* Status DCDC level 1.07x , */ \ + { 0x4190, \ + "ISTOCPR" }, /* Status ocp alarm , */ \ + { 0x41a0, \ + "ISTMWSRC" }, /* Status Waits HW I2C settings , */ \ + { 0x41c0, \ + "ISTMWSMU" }, /* Status Audio mute sequence , */ \ + { 0x41f0, \ + "ISTCLKOOR" }, /* Status flag_clk_out_of_range , */ \ + { 0x4200, \ + "ISTTDMER" }, /* Status tdm error , */ \ + { 0x4220, \ + "ISTCLPR" }, /* Status clip , */ \ + { 0x4240, \ + "ISTLP0" }, /* Status low power mode0 , */ \ + { 0x4250, \ + "ISTLP1" }, /* Status low power mode1 , */ \ + { 0x4260, \ + "ISTLA" }, /* Status low noise detection , */ \ + { 0x4270, \ + "ISTVDDPH" }, /* Status VDDP greater than VBAT , */ \ + { 0x4400, \ + "ICLVDDS" }, /* Clear POR , */ \ + { 0x4410, \ + "ICLPLLS" }, /* Clear PLL lock , */ \ + { 0x4420, \ + "ICLOTDS" }, /* Clear OTP alarm , */ \ + { 0x4430, \ + "ICLOVDS" }, /* Clear OVP alarm , */ \ + { 0x4440, \ + "ICLUVDS" }, /* Clear UVP alarm , */ \ + { 0x4450, \ + "ICLCLKS" }, /* Clear clocks stable , */ \ + { 0x4460, \ + "ICLMTPB" }, /* Clear mtp busy , */ \ + { 0x4470, \ + "ICLNOCLK" }, /* Clear lost clk , */ \ + { 0x44a0, \ + "ICLSWS" }, /* Clear amplifier engage , */ \ + { 0x44c0, \ + "ICLAMPS" }, /* Clear enbl amp , */ \ + { 0x44d0, \ + "ICLAREFS" }, /* Clear ref enable , */ \ + { 0x44e0, \ + "ICLADCCR" }, /* Clear control ADC , */ \ + { 0x4500, \ + "ICLBSTCU" }, /* Clear DCDC current limiting , */ \ + { 0x4510, \ + "ICLBSTHI" }, /* Clear DCDC active , */ \ + { 0x4520, \ + "ICLBSTOC" }, /* Clear DCDC OCP , */ \ + { 0x4530, \ + "ICLBSTPC" }, /* Clear bst peakcur , */ \ + { 0x4540, \ + "ICLBSTVC" }, /* Clear DCDC level 1x , */ \ + { 0x4550, \ + "ICLBST86" }, /* Clear DCDC level 1.14x , */ \ + { 0x4560, \ + "ICLBST93" }, /* Clear DCDC level 1.07x , */ \ + { 0x4590, \ + "ICLOCPR" }, /* Clear ocp alarm , */ \ + { 0x45a0, \ + "ICLMWSRC" }, /* Clear wait HW I2C settings , */ \ + { 0x45c0, \ + "ICLMWSMU" }, /* Clear audio mute sequence , */ \ + { 0x45f0, \ + "ICLCLKOOR" }, /* Clear flag_clk_out_of_range , */ \ + { 0x4600, \ + "ICLTDMER" }, /* Clear tdm error , */ \ + { 0x4620, \ + "ICLCLPR" }, /* Clear clip , */ \ + { 0x4640, \ + "ICLLP0" }, /* Clear low power mode0 , */ \ + { 0x4650, \ + "ICLLP1" }, /* Clear low power mode1 , */ \ + { 0x4660, \ + "ICLLA" }, /* Clear low noise detection , */ \ + { 0x4670, \ + "ICLVDDPH" }, /* Clear VDDP greater then VBAT , */ \ + { 0x4800, \ + "IEVDDS" }, /* Enable por , */ \ + { 0x4810, \ + "IEPLLS" }, /* Enable pll lock , */ \ + { 0x4820, \ + "IEOTDS" }, /* Enable OTP alarm , */ \ + { 0x4830, \ + "IEOVDS" }, /* Enable OVP alarm , */ \ + { 0x4840, \ + "IEUVDS" }, /* Enable UVP alarm , */ \ + { 0x4850, \ + "IECLKS" }, /* Enable clocks stable , */ \ + { 0x4860, \ + "IEMTPB" }, /* Enable mtp busy , */ \ + { 0x4870, \ + "IENOCLK" }, /* Enable lost clk , */ \ + { 0x48a0, \ + "IESWS" }, /* Enable amplifier engage , */ \ + { 0x48c0, \ + "IEAMPS" }, /* Enable enbl amp , */ \ + { 0x48d0, \ + "IEAREFS" }, /* Enable ref enable , */ \ + { 0x48e0, \ + "IEADCCR" }, /* Enable Control ADC , */ \ + { 0x4900, \ + "IEBSTCU" }, /* Enable DCDC current limiting , */ \ + { 0x4910, \ + "IEBSTHI" }, /* Enable DCDC active , */ \ + { 0x4920, \ + "IEBSTOC" }, /* Enable DCDC OCP , */ \ + { 0x4930, \ + "IEBSTPC" }, /* Enable bst peakcur , */ \ + { 0x4940, \ + "IEBSTVC" }, /* Enable DCDC level 1x , */ \ + { 0x4950, \ + "IEBST86" }, /* Enable DCDC level 1.14x , */ \ + { 0x4960, \ + "IEBST93" }, /* Enable DCDC level 1.07x , */ \ + { 0x4990, \ + "IEOCPR" }, /* Enable ocp alarm , */ \ + { 0x49a0, \ + "IEMWSRC" }, /* Enable waits HW I2C settings , */ \ + { 0x49c0, \ + "IEMWSMU" }, /* Enable man Audio mute sequence , */ \ + { 0x49f0, \ + "IECLKOOR" }, /* Enable flag_clk_out_of_range , */ \ + { 0x4a00, \ + "IETDMER" }, /* Enable tdm error , */ \ + { 0x4a20, \ + "IECLPR" }, /* Enable clip , */ \ + { 0x4a40, \ + "IELP0" }, /* Enable low power mode0 , */ \ + { 0x4a50, \ + "IELP1" }, /* Enable low power mode1 , */ \ + { 0x4a60, \ + "IELA" }, /* Enable low noise detection , */ \ + { 0x4a70, \ + "IEVDDPH" }, /* Enable VDDP greater tehn VBAT , */ \ + { 0x4c00, \ + "IPOVDDS" }, /* Polarity por , */ \ + { 0x4c10, \ + "IPOPLLS" }, /* Polarity pll lock , */ \ + { 0x4c20, \ + "IPOOTDS" }, /* Polarity OTP alarm , */ \ + { 0x4c30, \ + "IPOOVDS" }, /* Polarity OVP alarm , */ \ + { 0x4c40, \ + "IPOUVDS" }, /* Polarity UVP alarm , */ \ + { 0x4c50, \ + "IPOCLKS" }, /* Polarity clocks stable , */ \ + { 0x4c60, \ + "IPOMTPB" }, /* Polarity mtp busy , */ \ + { 0x4c70, \ + "IPONOCLK" }, /* Polarity lost clk , */ \ + { 0x4ca0, \ + "IPOSWS" }, /* Polarity amplifier engage , */ \ + { 0x4cc0, \ + "IPOAMPS" }, /* Polarity enbl amp , */ \ + { 0x4cd0, \ + "IPOAREFS" }, /* Polarity ref enable , */ \ + { 0x4ce0, \ + "IPOADCCR" }, /* Polarity Control ADC , */ \ + { 0x4d00, \ + "IPOBSTCU" }, /* Polarity DCDC current limiting , */ \ + { 0x4d10, \ + "IPOBSTHI" }, /* Polarity DCDC active , */ \ + { 0x4d20, \ + "IPOBSTOC" }, /* Polarity DCDC OCP , */ \ + { 0x4d30, \ + "IPOBSTPC" }, /* Polarity bst peakcur , */ \ + { 0x4d40, \ + "IPOBSTVC" }, /* Polarity DCDC level 1x , */ \ + { 0x4d50, \ + "IPOBST86" }, /* Polarity DCDC level 1.14x , */ \ + { 0x4d60, \ + "IPOBST93" }, /* Polarity DCDC level 1.07x , */ \ + { 0x4d90, \ + "IPOOCPR" }, /* Polarity ocp alarm , */ \ + { 0x4da0, \ + "IPOMWSRC" }, /* Polarity waits HW I2C settings , */ \ + { 0x4dc0, \ + "IPOMWSMU" }, /* Polarity man audio mute sequence , */ \ + { 0x4df0, \ + "IPCLKOOR" }, /* Polarity flag_clk_out_of_range , */ \ + { 0x4e00, \ + "IPOTDMER" }, /* Polarity tdm error , */ \ + { 0x4e20, \ + "IPOCLPR" }, /* Polarity clip right , */ \ + { 0x4e40, \ + "IPOLP0" }, /* Polarity low power mode0 , */ \ + { 0x4e50, \ + "IPOLP1" }, /* Polarity low power mode1 , */ \ + { 0x4e60, \ + "IPOLA" }, /* Polarity low noise mode , */ \ + { 0x4e70, \ + "IPOVDDPH" }, /* Polarity VDDP greater than VBAT , */ \ + { 0x5001, \ + "BSSCR" }, /* Battery Safeguard attack time , */ \ + { 0x5023, \ + "BSST" }, /* Battery Safeguard threshold voltage level , */ \ + { 0x5061, \ + "BSSRL" }, /* Battery Safeguard maximum reduction , */ \ + { 0x50e0, \ + "BSSR" }, /* Battery voltage read out , */ \ + { 0x50f0, \ + "BSSBY" }, /* Bypass battery safeguard , */ \ + { 0x5100, \ + "BSSS" }, /* Vbat prot steepness , */ \ + { 0x5110, \ + "INTSMUTE" }, /* Soft mute HW , */ \ + { 0x5150, \ + "HPFBYP" }, /* Bypass HPF , */ \ + { 0x5170, \ + "DPSA" }, /* Enable DPSA , */ \ + { 0x5222, \ + "CLIPCTRL" }, /* Clip control setting , */ \ + { 0x5257, \ + "AMPGAIN" }, /* Amplifier gain , */ \ + { 0x52d0, \ + "SLOPEE" }, /* Enables slope control , */ \ + { 0x52e0, \ + "SLOPESET" }, /* Slope speed setting (bin. coded) , */ \ + { 0x6081, \ + "PGAGAIN" }, /* PGA gain selection , */ \ + { 0x60b0, \ + "PGALPE" }, /* Lowpass enable , */ \ + { 0x6110, \ + "LPM0BYP" }, /* bypass low power idle mode , */ \ + { 0x6123, \ + "TDMDCG" }, /* Second channel gain in case of stereo using a single coil. (Total gain depending on INPLEV). (In case of mono OR stereo using 2 separate DCDC channel 1 should be disabled using TDMDCE), */ \ + { 0x6163, \ + "TDMSPKG" }, /* Total gain depending on INPLEV setting (channel 0), */ \ + { 0x61b0, \ + "STIDLEEN" }, /* enable idle feature for channel 1 , */ \ + { 0x62e1, \ + "LNMODE" }, /* ctrl select mode , */ \ + { 0x64e1, \ + "LPM1MODE" }, /* low power mode control , */ \ + { 0x65c0, \ + "LPM1DIS" }, /* low power mode1 detector control , */ \ + { 0x6801, \ + "TDMSRCMAP" }, /* tdm source mapping , */ \ + { 0x6821, \ + "TDMSRCAS" }, /* Sensed value A , */ \ + { 0x6841, \ + "TDMSRCBS" }, /* Sensed value B , */ \ + { 0x6881, \ + "ANCSEL" }, /* anc input , */ \ + { 0x68a0, \ + "ANC1C" }, /* ANC one s complement , */ \ + { 0x6901, \ + "SAMMODE" }, /* sam enable , */ \ + { 0x6920, \ + "SAMSEL" }, /* sam source , */ \ + { 0x6931, \ + "PDMOSELH" }, /* pdm out value when pdm_clk is higth , */ \ + { 0x6951, \ + "PDMOSELL" }, /* pdm out value when pdm_clk is low , */ \ + { 0x6970, \ + "SAMOSEL" }, /* ram output on mode sam and audio , */ \ + { 0x6e00, \ + "LP0" }, /* low power mode 0 detection , */ \ + { 0x6e10, \ + "LP1" }, /* low power mode 1 detection , */ \ + { 0x6e20, \ + "LA" }, /* low amplitude detection , */ \ + { 0x6e30, \ + "VDDPH" }, /* vddp greater than vbat , */ \ + { 0x6f02, \ + "DELCURCOMP" }, /* delay to allign compensation signal with current sense signal, */ \ + { 0x6f40, \ + "SIGCURCOMP" }, /* polarity of compensation for current sense , */ \ + { 0x6f50, \ + "ENCURCOMP" }, /* enable current sense compensation , */ \ + { 0x6f60, \ + "SELCLPPWM" }, /* Select pwm clip flag , */ \ + { 0x6f72, \ + "LVLCLPPWM" }, /* set the amount of pwm pulse that may be skipped before clip-flag is triggered, */ \ + { 0x7002, \ + "DCVOS" }, /* Second boost voltage level , */ \ + { 0x7033, \ + "DCMCC" }, /* Max coil current , */ \ + { 0x7071, \ + "DCCV" }, /* Slope compensation current, represents LxF (inductance x frequency) value , */ \ + { 0x7090, \ + "DCIE" }, /* Adaptive boost mode , */ \ + { 0x70a0, \ + "DCSR" }, /* Soft ramp up/down , */ \ + { 0x70e0, \ + "DCDIS" }, /* DCDC on/off , */ \ + { 0x70f0, \ + "DCPWM" }, /* DCDC PWM only mode , */ \ + { 0x7402, \ + "DCVOF" }, /* 1st boost voltage level , */ \ + { 0x7430, \ + "DCTRACK" }, /* Boost algorithm selection, effective only when boost_intelligent is set to 1, */ \ + { 0x7444, \ + "DCTRIP" }, /* 1st Adaptive boost trip levels, effective only when DCIE is set to 1, */ \ + { 0x7494, \ + "DCHOLD" }, /* Hold time for DCDC booster, effective only when boost_intelligent is set to 1, */ \ + { 0x7534, \ + "DCTRIP2" }, /* 2nd Adaptive boost trip levels, effective only when DCIE is set to 1, */ \ + { 0x7584, \ + "DCTRIPT" }, /* Track Adaptive boost trip levels, effective only when boost_intelligent is set to 1, */ \ + { 0xa107, \ + "MTPK" }, /* MTP KEY2 register , */ \ + { 0xa200, \ + "KEY1LOCKED" }, /* Indicates KEY1 is locked , */ \ + { 0xa210, \ + "KEY2LOCKED" }, /* Indicates KEY2 is locked , */ \ + { 0xa350, \ + "CMTPI" }, /* Start copying all the data from mtp to I2C mtp registers, */ \ + { 0xa360, \ + "CIMTP" }, /* Start copying data from I2C mtp registers to mtp , */ \ + { 0xa50f, \ + "MTPRDMSB" }, /* MSB word of MTP manual read data , */ \ + { 0xa60f, \ + "MTPRDLSB" }, /* LSB word of MTP manual read data , */ \ + { 0xb108, \ + "EXTTS" }, /* External temperature (C) , */ \ + { 0xb190, \ + "TROS" }, /* Select temp Speaker calibration , */ \ + { 0xee0f, \ + "SWPROFIL" }, /* Software profile data , */ \ + { 0xef0f, \ + "SWVSTEP" }, /* Software vstep information , */ \ + { 0xf000, \ + "MTPOTC" }, /* Calibration schedule , */ \ + { 0xf010, \ + "MTPEX" }, /* Calibration Ron executed , */ \ + { 0xf020, \ + "DCMCCAPI" }, /* Calibration current limit DCDC , */ \ + { 0xf030, \ + "DCMCCSB" }, /* Sign bit for delta calibration current limit DCDC , */ \ + { 0xf042, \ + "USERDEF" }, /* Calibration delta current limit DCDC , */ \ + { 0xf078, \ + "CUSTINFO" }, /* Reserved space for allowing customer to store speaker information, */ \ + { 0xf50f, \ + "R25C" }, /* Ron resistance of speaker coil , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +#define TFA9872_BITNAMETABLE \ + static tfaBfName_t Tfa9872BitNames[] = { \ + { 0x0, \ + "powerdown" }, /* Powerdown selection , */ \ + { 0x10, \ + "reset" }, /* I2C Reset - Auto clear , */ \ + { 0x30, \ + "enbl_amplifier" }, /* Activate Amplifier , */ \ + { 0x40, \ + "enbl_boost" }, /* Activate DC-to-DC converter , */ \ + { 0x71, \ + "int_pad_io" }, /* Interrupt config , */ \ + { 0xb0, \ + "bypass_ocp" }, /* Bypass OCP , */ \ + { 0xc0, \ + "test_ocp" }, /* OCP testing control , */ \ + { 0x120, \ + "src_set_configured" }, /* I2C configured , */ \ + { 0x140, \ + "enbl_osc1m_auto_off" }, /* Internal osc off at PWDN , */ \ + { 0x1d0, \ + "disable_mute_time_out" }, /* Time out SB mute sequence , */ \ + { 0x203, \ + "audio_fs" }, /* Sample rate (fs) , */ \ + { 0x240, \ + "input_level" }, /* TDM output attenuation , */ \ + { 0x255, \ + "cs_frac_delay" }, /* V/I Fractional delay , */ \ + { 0x2b0, \ + "bypass_hvbat_filter" }, /* Bypass HVBAT filter , */ \ + { 0x2d0, \ + "sel_hysteresis" }, /* Select hysteresis for clock range detector , */ \ + { 0x30f, \ + "device_rev" }, /* Revision info , */ \ + { 0x401, \ + "pll_clkin_sel" }, /* PLL external ref clock , */ \ + { 0x420, \ + "pll_clkin_sel_osc" }, /* PLL internal ref clock , */ \ + { 0x510, \ + "enbl_spkr_ss" }, /* Enable speaker path , */ \ + { 0x530, \ + "enbl_volsense" }, /* Voltage sense , */ \ + { 0x550, \ + "enbl_cursense" }, /* Current sense , */ \ + { 0x560, \ + "enbl_pdm_ss" }, /* Sub-system PDM , */ \ + { 0x580, \ + "enbl_pga_chop" }, /* Enable PGA chop clock , */ \ + { 0x590, \ + "enbl_tdm_ss" }, /* Sub-system TDM , */ \ + { 0x5a0, \ + "enbl_bst_ss" }, /* Sub-system boost , */ \ + { 0x5b0, \ + "enbl_adc_ss" }, /* Sub-system ADC , */ \ + { 0x5c0, \ + "enbl_faim_ss" }, /* Sub-system FAIM , */ \ + { 0xd18, \ + "side_tone_gain" }, /* Side tone gain , */ \ + { 0xda0, \ + "mute_side_tone" }, /* Side tone soft mute , */ \ + { 0xdb0, \ + "side_tone_1scomplement" }, /* side tone one s complement , */ \ + { 0xe07, \ + "ctrl_digtoana" }, /* Spare control from digital to analog , */ \ + { 0xf0f, \ + "hidden_code" }, /* 5A6Bh, 23147d to access registers (default for engineering), */ \ + { 0x1000, \ + "flag_por" }, /* POR , */ \ + { 0x1010, \ + "flag_pll_lock" }, /* PLL lock , */ \ + { 0x1020, \ + "flag_otpok" }, /* OTP alarm , */ \ + { 0x1030, \ + "flag_ovpok" }, /* OVP alarm , */ \ + { 0x1040, \ + "flag_uvpok" }, /* UVP alarm , */ \ + { 0x1050, \ + "flag_clocks_stable" }, /* Clocks stable , */ \ + { 0x1060, \ + "flag_mtp_busy" }, /* MTP busy , */ \ + { 0x1070, \ + "flag_lost_clk" }, /* Lost clock , */ \ + { 0x10a0, \ + "flag_engage" }, /* Amplifier engage , */ \ + { 0x10c0, \ + "flag_enbl_amp" }, /* Amplifier enable , */ \ + { 0x10d0, \ + "flag_enbl_ref" }, /* References enable , */ \ + { 0x10e0, \ + "flag_adc10_ready" }, /* Control ADC , */ \ + { 0x1100, \ + "flag_bst_bstcur" }, /* DCDC current limiting , */ \ + { 0x1110, \ + "flag_bst_hiz" }, /* DCDC active , */ \ + { 0x1120, \ + "flag_bst_ocpok" }, /* DCDC OCP nmos , */ \ + { 0x1130, \ + "flag_bst_peakcur" }, /* Indicates current is max in DC-to-DC converter , */ \ + { 0x1140, \ + "flag_bst_voutcomp" }, /* DCDC level 1x , */ \ + { 0x1150, \ + "flag_bst_voutcomp86" }, /* DCDC level 1.14x , */ \ + { 0x1160, \ + "flag_bst_voutcomp93" }, /* DCDC level 1.07x , */ \ + { 0x1170, \ + "flag_soft_mute_busy" }, /* side tone (un)mute busy , */ \ + { 0x1180, \ + "flag_soft_mute_state" }, /* side tone mute state , */ \ + { 0x1190, \ + "flag_tdm_lut_error" }, /* TDM LUT error , */ \ + { 0x11a2, \ + "flag_tdm_status" }, /* TDM status bits , */ \ + { 0x11d0, \ + "flag_tdm_error" }, /* TDM error , */ \ + { 0x1300, \ + "flag_ocpokap" }, /* OCPOK pmos A , */ \ + { 0x1310, \ + "flag_ocpokan" }, /* OCPOK nmos A , */ \ + { 0x1320, \ + "flag_ocpokbp" }, /* OCPOK pmos B , */ \ + { 0x1330, \ + "flag_ocpokbn" }, /* OCPOK nmos B , */ \ + { 0x1340, \ + "flag_clipa_high" }, /* Clipping A to Vddp , */ \ + { 0x1350, \ + "flag_clipa_low" }, /* Clipping A to gnd , */ \ + { 0x1360, \ + "flag_clipb_high" }, /* Clipping B to Vddp , */ \ + { 0x1370, \ + "flag_clipb_low" }, /* Clipping B to gnd , */ \ + { 0x1380, \ + "flag_ocp_alarm" }, /* OCP amplifier , */ \ + { 0x1390, \ + "flag_clip" }, /* Amplifier clipping , */ \ + { 0x13b0, \ + "flag_man_alarm_state" }, /* Alarm state , */ \ + { 0x13c0, \ + "flag_man_wait_src_settings" }, /* Wait HW I2C settings , */ \ + { 0x13e0, \ + "flag_man_start_mute_audio" }, /* Audio mute sequence , */ \ + { 0x13f0, \ + "flag_man_operating_state" }, /* Operating state , */ \ + { 0x1420, \ + "flag_clk_out_of_range" }, /* External clock status , */ \ + { 0x1433, \ + "man_state" }, /* Device manager status , */ \ + { 0x1471, \ + "status_bst_mode" }, /* DCDC mode status bits , */ \ + { 0x1509, \ + "bat_adc" }, /* Battery voltage (V) , */ \ + { 0x1608, \ + "temp_adc" }, /* IC Temperature (C) , */ \ + { 0x1709, \ + "vddp_adc" }, /* IC VDDP voltage ( 1023*VDDP/9.5 V) , */ \ + { 0x2040, \ + "tdm_enable" }, /* Enable interface , */ \ + { 0x2050, \ + "tdm_mode" }, /* Slave/master , */ \ + { 0x2060, \ + "tdm_clk_inversion" }, /* Reception data to BCK clock , */ \ + { 0x2073, \ + "tdm_fs_ws_length" }, /* FS length (master mode only) , */ \ + { 0x20b0, \ + "tdm_fs_ws_polarity" }, /* FS polarity , */ \ + { 0x20c3, \ + "tdm_nbck" }, /* N-BCK's in FS , */ \ + { 0x2103, \ + "tdm_nb_of_slots" }, /* N-slots in Frame , */ \ + { 0x2144, \ + "tdm_slot_length" }, /* N-bits in slot , */ \ + { 0x2194, \ + "tdm_bits_remaining" }, /* N-bits remaining , */ \ + { 0x21e0, \ + "tdm_data_delay" }, /* data delay to FS , */ \ + { 0x21f0, \ + "tdm_data_adjustment" }, /* data adjustment , */ \ + { 0x2201, \ + "tdm_audio_sample_compression" }, /* Received audio compression , */ \ + { 0x2224, \ + "tdm_sample_size" }, /* Sample size per slot , */ \ + { 0x2271, \ + "tdm_txdata_format" }, /* Format unused bits , */ \ + { 0x2291, \ + "tdm_txdata_format_unused_slot_sd0" }, /* Format unused slots DATAO , */ \ + { 0x2300, \ + "tdm_sink0_enable" }, /* Control audio tdm channel in 0 (spkr + dcdc) , */ \ + { 0x2310, \ + "tdm_sink1_enable" }, /* Control audio tdm channel in 1 (dcdc) , */ \ + { 0x2330, \ + "tdm_source0_enable" }, /* current sense vbat temperature and vddp feedback , */ \ + { 0x2340, \ + "tdm_source1_enable" }, /* Voltage sense vbat temperature and vddp feedback , */ \ + { 0x2603, \ + "tdm_sink0_slot" }, /* tdm slot for sink 0 (speaker + dcdc) , */ \ + { 0x2643, \ + "tdm_sink1_slot" }, /* tdm slot for sink 1 (dcdc) , */ \ + { 0x26c3, \ + "tdm_source0_slot" }, /* Slot Position of current sense vbat temperature and vddp feedback, */ \ + { 0x2703, \ + "tdm_source1_slot" }, /* Slot Position of Voltage sense vbat temperature and vddp feedback, */ \ + { 0x3111, \ + "pdm_side_tone_sel" }, /* Side tone input , */ \ + { 0x3201, \ + "pdm_nbck" }, /* PDM BCK/Fs ratio , */ \ + { 0x4000, \ + "int_out_flag_por" }, /* Status POR , */ \ + { 0x4010, \ + "int_out_flag_pll_lock" }, /* Status PLL lock , */ \ + { 0x4020, \ + "int_out_flag_otpok" }, /* Status OTP alarm , */ \ + { 0x4030, \ + "int_out_flag_ovpok" }, /* Status OVP alarm , */ \ + { 0x4040, \ + "int_out_flag_uvpok" }, /* Status UVP alarm , */ \ + { 0x4050, \ + "int_out_flag_clocks_stable" }, /* Status clocks stable , */ \ + { 0x4060, \ + "int_out_flag_mtp_busy" }, /* Status MTP busy , */ \ + { 0x4070, \ + "int_out_flag_lost_clk" }, /* Status lost clock , */ \ + { 0x40a0, \ + "int_out_flag_engage" }, /* Status amplifier engage , */ \ + { 0x40c0, \ + "int_out_flag_enbl_amp" }, /* Status amplifier enable , */ \ + { 0x40d0, \ + "int_out_flag_enbl_ref" }, /* Status Ref enable , */ \ + { 0x40e0, \ + "int_out_flag_adc10_ready" }, /* Status Control ADC , */ \ + { 0x4100, \ + "int_out_flag_bst_bstcur" }, /* Status DCDC current limiting , */ \ + { 0x4110, \ + "int_out_flag_bst_hiz" }, /* Status DCDC active , */ \ + { 0x4120, \ + "int_out_flag_bst_ocpok" }, /* Status DCDC OCP , */ \ + { 0x4130, \ + "int_out_flag_bst_peakcur" }, /* Status bst peakcur , */ \ + { 0x4140, \ + "int_out_flag_bst_voutcomp" }, /* Status DCDC level 1x , */ \ + { 0x4150, \ + "int_out_flag_bst_voutcomp86" }, /* Status DCDC level 1.14x , */ \ + { 0x4160, \ + "int_out_flag_bst_voutcomp93" }, /* Status DCDC level 1.07x , */ \ + { 0x4190, \ + "int_out_flag_ocp_alarm" }, /* Status ocp alarm , */ \ + { 0x41a0, \ + "int_out_flag_man_wait_src_settings" }, /* Status Waits HW I2C settings , */ \ + { 0x41c0, \ + "int_out_flag_man_start_mute_audio" }, /* Status Audio mute sequence , */ \ + { 0x41f0, \ + "int_out_flag_clk_out_of_range" }, /* Status flag_clk_out_of_range , */ \ + { 0x4200, \ + "int_out_flag_tdm_error" }, /* Status tdm error , */ \ + { 0x4220, \ + "int_out_flag_clip" }, /* Status clip , */ \ + { 0x4240, \ + "int_out_flag_lp_detect_mode0" }, /* Status low power mode0 , */ \ + { 0x4250, \ + "int_out_flag_lp_detect_mode1" }, /* Status low power mode1 , */ \ + { 0x4260, \ + "int_out_flag_low_amplitude" }, /* Status low noise detection , */ \ + { 0x4270, \ + "int_out_flag_vddp_gt_vbat" }, /* Status VDDP greater than VBAT , */ \ + { 0x4400, \ + "int_in_flag_por" }, /* Clear POR , */ \ + { 0x4410, \ + "int_in_flag_pll_lock" }, /* Clear PLL lock , */ \ + { 0x4420, \ + "int_in_flag_otpok" }, /* Clear OTP alarm , */ \ + { 0x4430, \ + "int_in_flag_ovpok" }, /* Clear OVP alarm , */ \ + { 0x4440, \ + "int_in_flag_uvpok" }, /* Clear UVP alarm , */ \ + { 0x4450, \ + "int_in_flag_clocks_stable" }, /* Clear clocks stable , */ \ + { 0x4460, \ + "int_in_flag_mtp_busy" }, /* Clear mtp busy , */ \ + { 0x4470, \ + "int_in_flag_lost_clk" }, /* Clear lost clk , */ \ + { 0x44a0, \ + "int_in_flag_engage" }, /* Clear amplifier engage , */ \ + { 0x44c0, \ + "int_in_flag_enbl_amp" }, /* Clear enbl amp , */ \ + { 0x44d0, \ + "int_in_flag_enbl_ref" }, /* Clear ref enable , */ \ + { 0x44e0, \ + "int_in_flag_adc10_ready" }, /* Clear control ADC , */ \ + { 0x4500, \ + "int_in_flag_bst_bstcur" }, /* Clear DCDC current limiting , */ \ + { 0x4510, \ + "int_in_flag_bst_hiz" }, /* Clear DCDC active , */ \ + { 0x4520, \ + "int_in_flag_bst_ocpok" }, /* Clear DCDC OCP , */ \ + { 0x4530, \ + "int_in_flag_bst_peakcur" }, /* Clear bst peakcur , */ \ + { 0x4540, \ + "int_in_flag_bst_voutcomp" }, /* Clear DCDC level 1x , */ \ + { 0x4550, \ + "int_in_flag_bst_voutcomp86" }, /* Clear DCDC level 1.14x , */ \ + { 0x4560, \ + "int_in_flag_bst_voutcomp93" }, /* Clear DCDC level 1.07x , */ \ + { 0x4590, \ + "int_in_flag_ocp_alarm" }, /* Clear ocp alarm , */ \ + { 0x45a0, \ + "int_in_flag_man_wait_src_settings" }, /* Clear wait HW I2C settings , */ \ + { 0x45c0, \ + "int_in_flag_man_start_mute_audio" }, /* Clear audio mute sequence , */ \ + { 0x45f0, \ + "int_in_flag_clk_out_of_range" }, /* Clear flag_clk_out_of_range , */ \ + { 0x4600, \ + "int_in_flag_tdm_error" }, /* Clear tdm error , */ \ + { 0x4620, \ + "int_in_flag_clip" }, /* Clear clip , */ \ + { 0x4640, \ + "int_in_flag_lp_detect_mode0" }, /* Clear low power mode0 , */ \ + { 0x4650, \ + "int_in_flag_lp_detect_mode1" }, /* Clear low power mode1 , */ \ + { 0x4660, \ + "int_in_flag_low_amplitude" }, /* Clear low noise detection , */ \ + { 0x4670, \ + "int_in_flag_vddp_gt_vbat" }, /* Clear VDDP greater then VBAT , */ \ + { 0x4800, \ + "int_enable_flag_por" }, /* Enable por , */ \ + { 0x4810, \ + "int_enable_flag_pll_lock" }, /* Enable pll lock , */ \ + { 0x4820, \ + "int_enable_flag_otpok" }, /* Enable OTP alarm , */ \ + { 0x4830, \ + "int_enable_flag_ovpok" }, /* Enable OVP alarm , */ \ + { 0x4840, \ + "int_enable_flag_uvpok" }, /* Enable UVP alarm , */ \ + { 0x4850, \ + "int_enable_flag_clocks_stable" }, /* Enable clocks stable , */ \ + { 0x4860, \ + "int_enable_flag_mtp_busy" }, /* Enable mtp busy , */ \ + { 0x4870, \ + "int_enable_flag_lost_clk" }, /* Enable lost clk , */ \ + { 0x48a0, \ + "int_enable_flag_engage" }, /* Enable amplifier engage , */ \ + { 0x48c0, \ + "int_enable_flag_enbl_amp" }, /* Enable enbl amp , */ \ + { 0x48d0, \ + "int_enable_flag_enbl_ref" }, /* Enable ref enable , */ \ + { 0x48e0, \ + "int_enable_flag_adc10_ready" }, /* Enable Control ADC , */ \ + { 0x4900, \ + "int_enable_flag_bst_bstcur" }, /* Enable DCDC current limiting , */ \ + { 0x4910, \ + "int_enable_flag_bst_hiz" }, /* Enable DCDC active , */ \ + { 0x4920, \ + "int_enable_flag_bst_ocpok" }, /* Enable DCDC OCP , */ \ + { 0x4930, \ + "int_enable_flag_bst_peakcur" }, /* Enable bst peakcur , */ \ + { 0x4940, \ + "int_enable_flag_bst_voutcomp" }, /* Enable DCDC level 1x , */ \ + { 0x4950, \ + "int_enable_flag_bst_voutcomp86" }, /* Enable DCDC level 1.14x , */ \ + { 0x4960, \ + "int_enable_flag_bst_voutcomp93" }, /* Enable DCDC level 1.07x , */ \ + { 0x4990, \ + "int_enable_flag_ocp_alarm" }, /* Enable ocp alarm , */ \ + { 0x49a0, \ + "int_enable_flag_man_wait_src_settings" }, /* Enable waits HW I2C settings , */ \ + { 0x49c0, \ + "int_enable_flag_man_start_mute_audio" }, /* Enable man Audio mute sequence , */ \ + { 0x49f0, \ + "int_enable_flag_clk_out_of_range" }, /* Enable flag_clk_out_of_range , */ \ + { 0x4a00, \ + "int_enable_flag_tdm_error" }, /* Enable tdm error , */ \ + { 0x4a20, \ + "int_enable_flag_clip" }, /* Enable clip , */ \ + { 0x4a40, \ + "int_enable_flag_lp_detect_mode0" }, /* Enable low power mode0 , */ \ + { 0x4a50, \ + "int_enable_flag_lp_detect_mode1" }, /* Enable low power mode1 , */ \ + { 0x4a60, \ + "int_enable_flag_low_amplitude" }, /* Enable low noise detection , */ \ + { 0x4a70, \ + "int_enable_flag_vddp_gt_vbat" }, /* Enable VDDP greater tehn VBAT , */ \ + { 0x4c00, \ + "int_polarity_flag_por" }, /* Polarity por , */ \ + { 0x4c10, \ + "int_polarity_flag_pll_lock" }, /* Polarity pll lock , */ \ + { 0x4c20, \ + "int_polarity_flag_otpok" }, /* Polarity OTP alarm , */ \ + { 0x4c30, \ + "int_polarity_flag_ovpok" }, /* Polarity OVP alarm , */ \ + { 0x4c40, \ + "int_polarity_flag_uvpok" }, /* Polarity UVP alarm , */ \ + { 0x4c50, \ + "int_polarity_flag_clocks_stable" }, /* Polarity clocks stable , */ \ + { 0x4c60, \ + "int_polarity_flag_mtp_busy" }, /* Polarity mtp busy , */ \ + { 0x4c70, \ + "int_polarity_flag_lost_clk" }, /* Polarity lost clk , */ \ + { 0x4ca0, \ + "int_polarity_flag_engage" }, /* Polarity amplifier engage , */ \ + { 0x4cc0, \ + "int_polarity_flag_enbl_amp" }, /* Polarity enbl amp , */ \ + { 0x4cd0, \ + "int_polarity_flag_enbl_ref" }, /* Polarity ref enable , */ \ + { 0x4ce0, \ + "int_polarity_flag_adc10_ready" }, /* Polarity Control ADC , */ \ + { 0x4d00, \ + "int_polarity_flag_bst_bstcur" }, /* Polarity DCDC current limiting , */ \ + { 0x4d10, \ + "int_polarity_flag_bst_hiz" }, /* Polarity DCDC active , */ \ + { 0x4d20, \ + "int_polarity_flag_bst_ocpok" }, /* Polarity DCDC OCP , */ \ + { 0x4d30, \ + "int_polarity_flag_bst_peakcur" }, /* Polarity bst peakcur , */ \ + { 0x4d40, \ + "int_polarity_flag_bst_voutcomp" }, /* Polarity DCDC level 1x , */ \ + { 0x4d50, \ + "int_polarity_flag_bst_voutcomp86" }, /* Polarity DCDC level 1.14x , */ \ + { 0x4d60, \ + "int_polarity_flag_bst_voutcomp93" }, /* Polarity DCDC level 1.07x , */ \ + { 0x4d90, \ + "int_polarity_flag_ocp_alarm" }, /* Polarity ocp alarm , */ \ + { 0x4da0, \ + "int_polarity_flag_man_wait_src_settings" }, /* Polarity waits HW I2C settings , */ \ + { 0x4dc0, \ + "int_polarity_flag_man_start_mute_audio" }, /* Polarity man audio mute sequence , */ \ + { 0x4df0, \ + "int_polarity_flag_clk_out_of_range" }, /* Polarity flag_clk_out_of_range , */ \ + { 0x4e00, \ + "int_polarity_flag_tdm_error" }, /* Polarity tdm error , */ \ + { 0x4e20, \ + "int_polarity_flag_clip" }, /* Polarity clip right , */ \ + { 0x4e40, \ + "int_polarity_flag_lp_detect_mode0" }, /* Polarity low power mode0 , */ \ + { 0x4e50, \ + "int_polarity_flag_lp_detect_mode1" }, /* Polarity low power mode1 , */ \ + { 0x4e60, \ + "int_polarity_flag_low_amplitude" }, /* Polarity low noise mode , */ \ + { 0x4e70, \ + "int_polarity_flag_vddp_gt_vbat" }, /* Polarity VDDP greater than VBAT , */ \ + { 0x5001, \ + "vbat_prot_attack_time" }, /* Battery Safeguard attack time , */ \ + { 0x5023, \ + "vbat_prot_thlevel" }, /* Battery Safeguard threshold voltage level , */ \ + { 0x5061, \ + "vbat_prot_max_reduct" }, /* Battery Safeguard maximum reduction , */ \ + { 0x50d0, \ + "rst_min_vbat" }, /* Reset clipper - Auto clear , */ \ + { 0x50e0, \ + "sel_vbat" }, /* Battery voltage read out , */ \ + { 0x50f0, \ + "bypass_clipper" }, /* Bypass battery safeguard , */ \ + { 0x5100, \ + "batsense_steepness" }, /* Vbat prot steepness , */ \ + { 0x5110, \ + "soft_mute" }, /* Soft mute HW , */ \ + { 0x5150, \ + "bypass_hp" }, /* Bypass HPF , */ \ + { 0x5170, \ + "enbl_dpsa" }, /* Enable DPSA , */ \ + { 0x5222, \ + "ctrl_cc" }, /* Clip control setting , */ \ + { 0x5257, \ + "gain" }, /* Amplifier gain , */ \ + { 0x52d0, \ + "ctrl_slopectrl" }, /* Enables slope control , */ \ + { 0x52e0, \ + "ctrl_slope" }, /* Slope speed setting (bin. coded) , */ \ + { 0x5301, \ + "dpsa_level" }, /* DPSA threshold levels , */ \ + { 0x5321, \ + "dpsa_release" }, /* DPSA Release time , */ \ + { 0x5340, \ + "clipfast" }, /* Clock selection for HW clipper for Battery Safeguard, */ \ + { 0x5350, \ + "bypass_lp" }, /* Bypass the low power filter inside temperature sensor, */ \ + { 0x5400, \ + "first_order_mode" }, /* Overrule to 1st order mode of control stage when clipping, */ \ + { 0x5410, \ + "bypass_ctrlloop" }, /* Switch amplifier into open loop configuration , */ \ + { 0x5420, \ + "fb_hz" }, /* Feedback resistor set to high ohmic , */ \ + { 0x5430, \ + "icomp_engage" }, /* Engage of icomp , */ \ + { 0x5440, \ + "ctrl_kickback" }, /* Prevent double pulses of output stage , */ \ + { 0x5450, \ + "icomp_engage_overrule" }, /* To overrule the functional icomp_engage signal during validation, */ \ + { 0x5503, \ + "ctrl_dem" }, /* Enable DEM icomp and DEM one bit dac , */ \ + { 0x5543, \ + "ctrl_dem_mismatch" }, /* Enable DEM icomp mismatch for testing , */ \ + { 0x5582, \ + "dpsa_drive" }, /* Drive setting (bin. coded) , */ \ + { 0x570a, \ + "enbl_amp" }, /* Switch on the class-D power sections, each part of the analog sections can be switched on/off individually, */ \ + { 0x57b0, \ + "enbl_engage" }, /* Enables/engage power stage and control loop , */ \ + { 0x57c0, \ + "enbl_engage_pst" }, /* Enables/engage power stage and control loop , */ \ + { 0x5810, \ + "hard_mute" }, /* Hard mute - PWM , */ \ + { 0x5820, \ + "pwm_shape" }, /* PWM shape , */ \ + { 0x5844, \ + "pwm_delay" }, /* PWM delay bits to set the delay, clockd is 1/(k*2048*fs), */ \ + { 0x5890, \ + "reclock_pwm" }, /* Reclock the pwm signal inside analog , */ \ + { 0x58a0, \ + "reclock_voltsense" }, /* Reclock the voltage sense pwm signal , */ \ + { 0x58c0, \ + "enbl_pwm_phase_shift" }, /* Control for pwm phase shift , */ \ + { 0x6081, \ + "pga_gain_set" }, /* PGA gain selection , */ \ + { 0x60b0, \ + "pga_lowpass_enable" }, /* Lowpass enable , */ \ + { 0x60c0, \ + "pga_pwr_enable" }, /* Power enable, directcontrol mode only , */ \ + { 0x60d0, \ + "pga_switch_enable" }, /* Switch enable, directcontrol mode only , */ \ + { 0x60e0, \ + "pga_switch_aux_enable" }, /* Switch enable aux, directcontrol mode only , */ \ + { 0x6100, \ + "force_idle" }, /* force low power in idle mode , */ \ + { 0x6110, \ + "bypass_idle" }, /* bypass low power idle mode , */ \ + { 0x6123, \ + "ctrl_attl" }, /* Second channel gain in case of stereo using a single coil. (Total gain depending on INPLEV). (In case of mono OR stereo using 2 separate DCDC channel 1 should be disabled using TDMDCE), */ \ + { 0x6163, \ + "ctrl_attr" }, /* Total gain depending on INPLEV setting (channel 0), */ \ + { 0x61a0, \ + "idle_cnt" }, /* idle counter , */ \ + { 0x61b0, \ + "enbl_idle_ch1" }, /* enable idle feature for channel 1 , */ \ + { 0x6265, \ + "zero_lvl" }, /* low noise gain switch zero trigger level , */ \ + { 0x62c1, \ + "ctrl_fb_classd" }, /* class D gain ctrl_fb_50k ctrl_fb_100k , */ \ + { 0x62e1, \ + "lownoisegain_mode" }, /* ctrl select mode , */ \ + { 0x6305, \ + "threshold_lvl" }, /* low noise gain switch trigger level , */ \ + { 0x6365, \ + "hold_time" }, /* ctrl hold time before low audio is reckoned to be low audio, */ \ + { 0x6405, \ + "lpm1_cal_offset" }, /* low power mode1 detector ctrl cal_offset from gain module , */ \ + { 0x6465, \ + "lpm1_zero_lvl" }, /* low power mode1 zero crossing detection level , */ \ + { 0x64e1, \ + "lpm1_mode" }, /* low power mode control , */ \ + { 0x6505, \ + "lpm1_threshold_lvl" }, /* low power mode1 amplitude trigger level , */ \ + { 0x6565, \ + "lpm1_hold_time" }, /* low power mode1 detector ctrl hold time before low audio is reckoned to be low audio, */ \ + { 0x65c0, \ + "disable_low_power_mode" }, /* low power mode1 detector control , */ \ + { 0x6600, \ + "dcdc_pfm20khz_limit" }, /* DCDC in PFM mode pwm mode is activated each 50us to force a pwm pulse, */ \ + { 0x6611, \ + "dcdc_ctrl_maxzercnt" }, /* DCDC. Number of zero current flags to count before going to pfm mode, */ \ + { 0x6656, \ + "dcdc_vbat_delta_detect" }, /* Threshold before booster is reacting on a delta Vbat (in PFM mode) by temporarily switching to PWM mode, */ \ + { 0x66c0, \ + "dcdc_ignore_vbat" }, /* Ignore an increase on Vbat , */ \ + { 0x6700, \ + "enbl_minion" }, /* Enables minion (small) power stage , */ \ + { 0x6713, \ + "vth_vddpvbat" }, /* select vddp-vbat thres signal , */ \ + { 0x6750, \ + "lpen_vddpvbat" }, /* select vddp-vbat filtred vs unfiltered compare , */ \ + { 0x6801, \ + "tdm_source_mapping" }, /* tdm source mapping , */ \ + { 0x6821, \ + "tdm_sourcea_frame_sel" }, /* Sensed value A , */ \ + { 0x6841, \ + "tdm_sourceb_frame_sel" }, /* Sensed value B , */ \ + { 0x6881, \ + "pdm_anc_sel" }, /* anc input , */ \ + { 0x68a0, \ + "anc_1scomplement" }, /* ANC one s complement , */ \ + { 0x6901, \ + "sam_mode" }, /* sam enable , */ \ + { 0x6920, \ + "sam_src" }, /* sam source , */ \ + { 0x6931, \ + "pdmdat_h_sel" }, /* pdm out value when pdm_clk is higth , */ \ + { 0x6951, \ + "pdmdat_l_sel" }, /* pdm out value when pdm_clk is low , */ \ + { 0x6970, \ + "sam_spkr_sel" }, /* ram output on mode sam and audio , */ \ + { 0x6a02, \ + "rst_min_vbat_delay" }, /* rst_min_vbat delay (nb fs) , */ \ + { 0x6b00, \ + "disable_auto_engage" }, /* disable auto engange , */ \ + { 0x6b10, \ + "sel_tdm_data_valid" }, /* select tdm valid for speaker subsystem , */ \ + { 0x6c02, \ + "ns_hp2ln_criterion" }, /* 0..7 zeroes at ns as threshold to swap from high_power to low_noise, */ \ + { 0x6c32, \ + "ns_ln2hp_criterion" }, /* 0..7 zeroes at ns as threshold to swap from low_noise to high_power, */ \ + { 0x6c69, \ + "spare_out" }, /* spare_out , */ \ + { 0x6d0f, \ + "spare_in" }, /* spare_in , */ \ + { 0x6e00, \ + "flag_lp_detect_mode0" }, /* low power mode 0 detection , */ \ + { 0x6e10, \ + "flag_lp_detect_mode1" }, /* low power mode 1 detection , */ \ + { 0x6e20, \ + "flag_low_amplitude" }, /* low amplitude detection , */ \ + { 0x6e30, \ + "flag_vddp_gt_vbat" }, /* vddp greater than vbat , */ \ + { 0x6f02, \ + "cursense_comp_delay" }, /* delay to allign compensation signal with current sense signal, */ \ + { 0x6f40, \ + "cursense_comp_sign" }, /* polarity of compensation for current sense , */ \ + { 0x6f50, \ + "enbl_cursense_comp" }, /* enable current sense compensation , */ \ + { 0x6f60, \ + "sel_clip_pwms" }, /* Select pwm clip flag , */ \ + { 0x6f72, \ + "pwms_clip_lvl" }, /* set the amount of pwm pulse that may be skipped before clip-flag is triggered, */ \ + { 0x7002, \ + "scnd_boost_voltage" }, /* Second boost voltage level , */ \ + { 0x7033, \ + "boost_cur" }, /* Max coil current , */ \ + { 0x7071, \ + "bst_slpcmplvl" }, /* Slope compensation current, represents LxF (inductance x frequency) value , */ \ + { 0x7090, \ + "boost_intel" }, /* Adaptive boost mode , */ \ + { 0x70a0, \ + "boost_speed" }, /* Soft ramp up/down , */ \ + { 0x70e0, \ + "dcdcoff_mode" }, /* DCDC on/off , */ \ + { 0x70f0, \ + "dcdc_pwmonly" }, /* DCDC PWM only mode , */ \ + { 0x7104, \ + "bst_drive" }, /* Binary coded drive setting for boost converter power stage, */ \ + { 0x7151, \ + "bst_scalecur" }, /* For testing direct control scale current , */ \ + { 0x7174, \ + "bst_slopecur" }, /* For testing direct control slope current , */ \ + { 0x71c1, \ + "bst_slope" }, /* Boost slope speed , */ \ + { 0x71e0, \ + "bst_bypass_bstcur" }, /* Bypass control for boost current settings , */ \ + { 0x71f0, \ + "bst_bypass_bstfoldback" }, /* Bypass control for boost foldback , */ \ + { 0x7200, \ + "enbl_bst_engage" }, /* Enable power stage dcdc controller , */ \ + { 0x7210, \ + "enbl_bst_hizcom" }, /* Enable hiz comparator , */ \ + { 0x7220, \ + "enbl_bst_peak2avg" }, /* Enable boost peak2avg functionality , */ \ + { 0x7230, \ + "enbl_bst_peakcur" }, /* Enable peak current , */ \ + { 0x7240, \ + "enbl_bst_power" }, /* Enable line of the powerstage , */ \ + { 0x7250, \ + "enbl_bst_slopecur" }, /* Enable bit of max-current dac , */ \ + { 0x7260, \ + "enbl_bst_voutcomp" }, /* Enable vout comparators , */ \ + { 0x7270, \ + "enbl_bst_voutcomp86" }, /* Enable vout-86 comparators , */ \ + { 0x7280, \ + "enbl_bst_voutcomp93" }, /* Enable vout-93 comparators , */ \ + { 0x7290, \ + "enbl_bst_windac" }, /* Enable window dac , */ \ + { 0x72a5, \ + "bst_windac" }, /* for testing direct control windac , */ \ + { 0x7300, \ + "boost_alg" }, /* Control for boost adaptive loop gain , */ \ + { 0x7311, \ + "boost_loopgain" }, /* DCDC boost loopgain setting , */ \ + { 0x7331, \ + "bst_freq" }, /* DCDC boost frequency control , */ \ + { 0x7402, \ + "frst_boost_voltage" }, /* 1st boost voltage level , */ \ + { 0x7430, \ + "boost_track" }, /* Boost algorithm selection, effective only when boost_intelligent is set to 1, */ \ + { 0x7444, \ + "boost_trip_lvl_1st" }, /* 1st Adaptive boost trip levels, effective only when DCIE is set to 1, */ \ + { 0x7494, \ + "boost_hold_time" }, /* Hold time for DCDC booster, effective only when boost_intelligent is set to 1, */ \ + { 0x74e0, \ + "sel_dcdc_envelope_8fs" }, /* Selection of data for adaptive boost algorithm, effective only when boost_intelligent is set to 1, */ \ + { 0x74f0, \ + "ignore_flag_voutcomp86" }, /* Ignore flag_voutcomp86 , */ \ + { 0x7502, \ + "track_decay" }, /* DCDC Boost decay speed after a peak value, effective only when boost_track is set to 1, */ \ + { 0x7534, \ + "boost_trip_lvl_2nd" }, /* 2nd Adaptive boost trip levels, effective only when DCIE is set to 1, */ \ + { 0x7584, \ + "boost_trip_lvl_track" }, /* Track Adaptive boost trip levels, effective only when boost_intelligent is set to 1, */ \ + { 0x7620, \ + "pga_test_ldo_bypass" }, /* bypass internal PGA LDO , */ \ + { 0x8001, \ + "sel_clk_cs" }, /* Current sense clock duty cycle control , */ \ + { 0x8021, \ + "micadc_speed" }, /* Current sense clock for MiCADC selection - 32/44.1/48 KHz Fs band only, */ \ + { 0x8050, \ + "cs_gain_control" }, /* Current sense gain control , */ \ + { 0x8060, \ + "cs_bypass_gc" }, /* Bypasses the CS gain correction , */ \ + { 0x8087, \ + "cs_gain" }, /* Current sense gain , */ \ + { 0x8200, \ + "enbl_cmfb" }, /* Current sense common mode feedback control , */ \ + { 0x8210, \ + "invertpwm" }, /* Current sense common mode feedback pwm invert control, */ \ + { 0x8222, \ + "cmfb_gain" }, /* Current sense common mode feedback control gain , */ \ + { 0x8254, \ + "cmfb_offset" }, /* Current sense common mode feedback control offset , */ \ + { 0x82a0, \ + "cs_sam_set" }, /* Enable SAM input for current sense , */ \ + { 0x8305, \ + "cs_ktemp" }, /* Current sense temperature compensation trimming (1 - VALUE*TEMP)*signal, */ \ + { 0x8400, \ + "cs_adc_bsoinv" }, /* Bitstream inversion for current sense ADC , */ \ + { 0x8421, \ + "cs_adc_hifreq" }, /* Frequency mode current sense ADC , */ \ + { 0x8440, \ + "cs_adc_nortz" }, /* Return to zero for current sense ADC , */ \ + { 0x8453, \ + "cs_adc_offset" }, /* Micadc ADC offset setting , */ \ + { 0x8490, \ + "cs_adc_slowdel" }, /* Select delay for current sense ADC (internal decision circuitry), */ \ + { 0x84a4, \ + "cs_adc_gain" }, /* Gain setting for current sense ADC (two's complement), */ \ + { 0x8500, \ + "cs_resonator_enable" }, /* Enable for resonator to improve SRN , */ \ + { 0x8510, \ + "cs_classd_tran_skip" }, /* Skip current sense connection during a classD amplifier transition, */ \ + { 0x8530, \ + "cs_inn_short" }, /* Short current sense negative to common mode , */ \ + { 0x8540, \ + "cs_inp_short" }, /* Short current sense positive to common mode , */ \ + { 0x8550, \ + "cs_ldo_bypass" }, /* Bypass current sense LDO , */ \ + { 0x8560, \ + "cs_ldo_pulldown" }, /* Pull down current sense LDO, only valid if left_enbl_cs_ldo is high, */ \ + { 0x8574, \ + "cs_ldo_voset" }, /* Current sense LDO voltage level setting (two's complement), */ \ + { 0x8700, \ + "enbl_cs_adc" }, /* Enable current sense ADC , */ \ + { 0x8710, \ + "enbl_cs_inn1" }, /* Enable connection of current sense negative1 , */ \ + { 0x8720, \ + "enbl_cs_inn2" }, /* Enable connection of current sense negative2 , */ \ + { 0x8730, \ + "enbl_cs_inp1" }, /* Enable connection of current sense positive1 , */ \ + { 0x8740, \ + "enbl_cs_inp2" }, /* Enable connection of current sense positive2 , */ \ + { 0x8750, \ + "enbl_cs_ldo" }, /* Enable current sense LDO , */ \ + { 0x8760, \ + "enbl_cs_nofloating_n" }, /* Connect current sense negative to gnda at transitions of booster or classd amplifiers. Otherwise floating (0), */ \ + { 0x8770, \ + "enbl_cs_nofloating_p" }, /* Connect current sense positive to gnda at transitions of booster or classd amplifiers. Otherwise floating (0), */ \ + { 0x8780, \ + "enbl_cs_vbatldo" }, /* Enable of current sense LDO , */ \ + { 0x8800, \ + "volsense_pwm_sel" }, /* Voltage sense PWM source selection control , */ \ + { 0x8810, \ + "vol_cur_sense_dc_offset" }, /* voltage and current sense decimator offset control, */ \ + { 0xa007, \ + "mtpkey1" }, /* 5Ah, 90d To access KEY1_Protected registers (Default for engineering), */ \ + { 0xa107, \ + "mtpkey2" }, /* MTP KEY2 register , */ \ + { 0xa200, \ + "key01_locked" }, /* Indicates KEY1 is locked , */ \ + { 0xa210, \ + "key02_locked" }, /* Indicates KEY2 is locked , */ \ + { 0xa302, \ + "mtp_man_address_in" }, /* MTP address from I2C register for read/writing mtp in manual single word mode, */ \ + { 0xa330, \ + "man_copy_mtp_to_iic" }, /* Start copying single word from mtp to I2C mtp register, */ \ + { 0xa340, \ + "man_copy_iic_to_mtp" }, /* Start copying single word from I2C mtp register to mtp, */ \ + { 0xa350, \ + "auto_copy_mtp_to_iic" }, /* Start copying all the data from mtp to I2C mtp registers, */ \ + { 0xa360, \ + "auto_copy_iic_to_mtp" }, /* Start copying data from I2C mtp registers to mtp , */ \ + { 0xa400, \ + "faim_set_clkws" }, /* Sets the faim controller clock wait state register, */ \ + { 0xa410, \ + "faim_sel_evenrows" }, /* All even rows of the faim are selected, active high, */ \ + { 0xa420, \ + "faim_sel_oddrows" }, /* All odd rows of the faim are selected, all rows in combination with sel_evenrows, */ \ + { 0xa430, \ + "faim_program_only" }, /* Skip the erase access at wr_faim command (write-program-marginread), */ \ + { 0xa440, \ + "faim_erase_only" }, /* Skip the program access at wr_faim command (write-erase-marginread), */ \ + { 0xa50f, \ + "mtp_man_data_out_msb" }, /* MSB word of MTP manual read data , */ \ + { 0xa60f, \ + "mtp_man_data_out_lsb" }, /* LSB word of MTP manual read data , */ \ + { 0xa70f, \ + "mtp_man_data_in_msb" }, /* MSB word of write data for MTP manual write , */ \ + { 0xa80f, \ + "mtp_man_data_in_lsb" }, /* LSB word of write data for MTP manual write , */ \ + { 0xb010, \ + "bypass_ocpcounter" }, /* Bypass OCP Counter , */ \ + { 0xb020, \ + "bypass_glitchfilter" }, /* Bypass glitch filter , */ \ + { 0xb030, \ + "bypass_ovp" }, /* Bypass OVP , */ \ + { 0xb040, \ + "bypass_uvp" }, /* Bypass UVP , */ \ + { 0xb050, \ + "bypass_otp" }, /* Bypass OTP , */ \ + { 0xb060, \ + "bypass_lost_clk" }, /* Bypass lost clock detector , */ \ + { 0xb070, \ + "ctrl_vpalarm" }, /* vpalarm (uvp ovp handling) , */ \ + { 0xb087, \ + "ocp_threshold" }, /* OCP threshold level , */ \ + { 0xb108, \ + "ext_temp" }, /* External temperature (C) , */ \ + { 0xb190, \ + "ext_temp_sel" }, /* Select temp Speaker calibration , */ \ + { 0xc000, \ + "use_direct_ctrls" }, /* Direct control to overrule several functions for testing, */ \ + { 0xc010, \ + "rst_datapath" }, /* Direct control for datapath reset , */ \ + { 0xc020, \ + "rst_cgu" }, /* Direct control for cgu reset , */ \ + { 0xc038, \ + "enbl_ref" }, /* Switch on the analog references, each part of the references can be switched on/off individually, */ \ + { 0xc0d0, \ + "enbl_ringo" }, /* Enable the ring oscillator for test purpose , */ \ + { 0xc0e0, \ + "use_direct_clk_ctrl" }, /* Direct clock control to overrule several functions for testing, */ \ + { 0xc0f0, \ + "use_direct_pll_ctrl" }, /* Direct PLL control to overrule several functions for testing, */ \ + { 0xc100, \ + "enbl_tsense" }, /* Temperature sensor enable control - I2C direct mode, */ \ + { 0xc110, \ + "tsense_hibias" }, /* Bit to set the biasing in temp sensor to high , */ \ + { 0xc120, \ + "enbl_flag_vbg" }, /* Enable flagging of bandgap out of control , */ \ + { 0xc20f, \ + "abist_offset" }, /* Offset control for ABIST testing (two's complement), */ \ + { 0xc300, \ + "bypasslatch" }, /* Bypass latch , */ \ + { 0xc311, \ + "sourcea" }, /* Set OUTA to , */ \ + { 0xc331, \ + "sourceb" }, /* Set OUTB to , */ \ + { 0xc350, \ + "inverta" }, /* Invert pwma test signal , */ \ + { 0xc360, \ + "invertb" }, /* Invert pwmb test signal , */ \ + { 0xc374, \ + "pulselength" }, /* Pulse length setting test input for amplifier (clock d - k*2048*fs), */ \ + { 0xc3c0, \ + "tdm_enable_loopback" }, /* TDM loopback test , */ \ + { 0xc400, \ + "bst_bypasslatch" }, /* Bypass latch in boost converter , */ \ + { 0xc411, \ + "bst_source" }, /* Sets the source of the pwmbst output to boost converter input for testing, */ \ + { 0xc430, \ + "bst_invertb" }, /* Invert pwmbst test signal , */ \ + { 0xc444, \ + "bst_pulselength" }, /* Pulse length setting test input for boost converter , */ \ + { 0xc490, \ + "test_bst_ctrlsthv" }, /* Test mode for boost control stage , */ \ + { 0xc4a0, \ + "test_bst_iddq" }, /* IDDQ testing in power stage of boost converter , */ \ + { 0xc4b0, \ + "test_bst_rdson" }, /* RDSON testing - boost power stage , */ \ + { 0xc4c0, \ + "test_bst_cvi" }, /* CVI testing - boost power stage , */ \ + { 0xc4d0, \ + "test_bst_ocp" }, /* Boost OCP. For old ocp (ctrl_reversebst is 0), For new ocp (ctrl_reversebst is 1), */ \ + { 0xc4e0, \ + "test_bst_sense" }, /* Test option for the sense NMOS in booster for current mode control., */ \ + { 0xc500, \ + "test_cvi" }, /* Analog BIST, switch choose which transistor will be used as current source (also cross coupled sources possible), */ \ + { 0xc510, \ + "test_discrete" }, /* Test function noise measurement , */ \ + { 0xc520, \ + "test_iddq" }, /* Set the power stages in iddq mode for gate stress., */ \ + { 0xc540, \ + "test_rdson" }, /* Analog BIST, switch to enable Rdson measurement , */ \ + { 0xc550, \ + "test_sdelta" }, /* Analog BIST, noise test , */ \ + { 0xc570, \ + "test_enbl_cs" }, /* Enable for digimux mode of current sense , */ \ + { 0xc5b0, \ + "pga_test_enable" }, /* Enable PGA test mode , */ \ + { 0xc5c0, \ + "pga_test_offset_enable" }, /* Enable PGA test offset , */ \ + { 0xc5d0, \ + "pga_test_shortinput_enable" }, /* Enable PGA test shortinput , */ \ + { 0xc600, \ + "enbl_pwm_dcc" }, /* Enables direct control of pwm duty cycle for DCDC power stage, */ \ + { 0xc613, \ + "pwm_dcc_cnt" }, /* Control pwm duty cycle when enbl_pwm_dcc is 1 , */ \ + { 0xc650, \ + "enbl_ldo_stress" }, /* Enable stress of internal supply voltages powerstages, */ \ + { 0xc707, \ + "digimuxa_sel" }, /* DigimuxA input selection control routed to DATAO (see Digimux list for details), */ \ + { 0xc787, \ + "digimuxb_sel" }, /* DigimuxB input selection control routed to INT (see Digimux list for details), */ \ + { 0xc807, \ + "digimuxc_sel" }, /* DigimuxC input selection control routed to PDMDAT (see Digimux list for details), */ \ + { 0xc981, \ + "int_ehs" }, /* Speed/load setting for INT IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc9c0, \ + "hs_mode" }, /* I2C high speed mode control , */ \ + { 0xca00, \ + "enbl_anamux1" }, /* Enable anamux1 , */ \ + { 0xca10, \ + "enbl_anamux2" }, /* Enable anamux2 , */ \ + { 0xca20, \ + "enbl_anamux3" }, /* Enable anamux3 , */ \ + { 0xca30, \ + "enbl_anamux4" }, /* Enable anamux4 , */ \ + { 0xca74, \ + "anamux1" }, /* Anamux selection control - anamux on TEST1 , */ \ + { 0xcb04, \ + "anamux2" }, /* Anamux selection control - anamux on TEST2 , */ \ + { 0xcb54, \ + "anamux3" }, /* Anamux selection control - anamux on TEST3 , */ \ + { 0xcba4, \ + "anamux4" }, /* Anamux selection control - anamux on TEST4 , */ \ + { 0xcd05, \ + "pll_seli" }, /* PLL SELI - I2C direct PLL control mode only , */ \ + { 0xcd64, \ + "pll_selp" }, /* PLL SELP - I2C direct PLL control mode only , */ \ + { 0xcdb3, \ + "pll_selr" }, /* PLL SELR - I2C direct PLL control mode only , */ \ + { 0xcdf0, \ + "pll_frm" }, /* PLL free running mode control; 1 in TCB direct control mode, else this control bit, */ \ + { 0xce09, \ + "pll_ndec" }, /* PLL NDEC - I2C direct PLL control mode only , */ \ + { 0xcea0, \ + "pll_mdec_msb" }, /* MSB of pll_mdec - I2C direct PLL control mode only, */ \ + { 0xceb0, \ + "enbl_pll" }, /* Enables PLL in I2C direct PLL control mode only , */ \ + { 0xcec0, \ + "enbl_osc" }, /* Enables OSC1M in I2C direct control mode only , */ \ + { 0xced0, \ + "pll_bypass" }, /* PLL bypass control in I2C direct PLL control mode only, */ \ + { 0xcee0, \ + "pll_directi" }, /* PLL directi control in I2C direct PLL control mode only, */ \ + { 0xcef0, \ + "pll_directo" }, /* PLL directo control in I2C direct PLL control mode only, */ \ + { 0xcf0f, \ + "pll_mdec_lsb" }, /* Bits 15..0 of PLL MDEC are I2C direct PLL control mode only, */ \ + { 0xd006, \ + "pll_pdec" }, /* PLL PDEC - I2C direct PLL control mode only , */ \ + { 0xd10f, \ + "tsig_freq_lsb" }, /* Internal sinus test generator frequency control , */ \ + { 0xd202, \ + "tsig_freq_msb" }, /* Select internal sinus test generator, frequency control msb bits, */ \ + { 0xd230, \ + "inject_tsig" }, /* Control bit to switch to internal sinus test generator, */ \ + { 0xd283, \ + "tsig_gain" }, /* Test signal gain , */ \ + { 0xd300, \ + "adc10_reset" }, /* Reset for ADC10 - I2C direct control mode , */ \ + { 0xd311, \ + "adc10_test" }, /* Test mode selection signal for ADC10 - I2C direct control mode, */ \ + { 0xd332, \ + "adc10_sel" }, /* Select the input to convert for ADC10 - I2C direct control mode, */ \ + { 0xd364, \ + "adc10_prog_sample" }, /* ADC10 program sample setting - I2C direct control mode, */ \ + { 0xd3b0, \ + "adc10_enbl" }, /* Enable ADC10 - I2C direct control mode , */ \ + { 0xd3c0, \ + "bypass_lp_vbat" }, /* Bypass control for Low pass filter in batt sensor , */ \ + { 0xd409, \ + "data_adc10_tempbat" }, /* ADC 10 data output data for testing , */ \ + { 0xd507, \ + "ctrl_digtoana_hidden" }, /* Spare digital to analog control bits - Hidden , */ \ + { 0xd580, \ + "enbl_clk_out_of_range" }, /* Clock out of range , */ \ + { 0xd621, \ + "clkdiv_audio_sel" }, /* Audio clock divider selection in direct clock control mode, */ \ + { 0xd641, \ + "clkdiv_muxa_sel" }, /* DCDC MUXA clock divider selection in direct clock control mode, */ \ + { 0xd661, \ + "clkdiv_muxb_sel" }, /* DCDC MUXB clock divider selection in direct clock control mode, */ \ + { 0xd701, \ + "pdmdat_ehs" }, /* Speed/load setting for PDMDAT IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xd721, \ + "datao_ehs" }, /* Speed/load setting for DATAO IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xd740, \ + "bck_ehs" }, /* Speed/load setting for DATAO IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xd750, \ + "datai_ehs" }, /* Speed/load setting for DATAO IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xd760, \ + "pdmclk_ehs" }, /* Speed/load setting for DATAO IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xd800, \ + "source_in_testmode" }, /* tdm source in test mode (return only current and voltage sense), */ \ + { 0xd810, \ + "gainatt_feedback" }, /* gainatt feedback to tdm , */ \ + { 0xd822, \ + "test_parametric_io" }, /* test io parametric , */ \ + { 0xd850, \ + "ctrl_bst_clk_lp1" }, /* boost clock control in low power mode1 , */ \ + { 0xd861, \ + "test_spare_out1" }, /* test spare out 1 , */ \ + { 0xd880, \ + "bst_dcmbst" }, /* dcm boost , */ \ + { 0xd890, \ + "pdm_loopback" }, /* pdm loop back to tdm , */ \ + { 0xd8a1, \ + "force_pga_clock" }, /* force pga clock , */ \ + { 0xd8c3, \ + "test_spare_out2" }, /* test spare out 1 , */ \ + { 0xee0f, \ + "sw_profile" }, /* Software profile data , */ \ + { 0xef0f, \ + "sw_vstep" }, /* Software vstep information , */ \ + { 0xf000, \ + "calibration_onetime" }, /* Calibration schedule , */ \ + { 0xf010, \ + "calibr_ron_done" }, /* Calibration Ron executed , */ \ + { 0xf020, \ + "calibr_dcdc_api_calibrate" }, /* Calibration current limit DCDC , */ \ + { 0xf030, \ + "calibr_dcdc_delta_sign" }, /* Sign bit for delta calibration current limit DCDC , */ \ + { 0xf042, \ + "calibr_dcdc_delta" }, /* Calibration delta current limit DCDC , */ \ + { 0xf078, \ + "calibr_speaker_info" }, /* Reserved space for allowing customer to store speaker information, */ \ + { 0xf105, \ + "calibr_vout_offset" }, /* DCDC offset calibration 2's complement (key1 protected), */ \ + { 0xf163, \ + "spare_mpt1_9_6" }, /* HW gain module - left channel (2's complement) , */ \ + { 0xf1a5, \ + "spare_mpt1_15_10" }, /* Offset for amplifier, HW gain module - left channel (2's complement), */ \ + { 0xf203, \ + "calibr_gain" }, /* HW gain module (2's complement) , */ \ + { 0xf245, \ + "calibr_offset" }, /* Offset for amplifier, HW gain module (2's complement), */ \ + { 0xf2a3, \ + "spare_mpt2_13_10" }, /* Trimming of LDO (2.7V) , */ \ + { 0xf307, \ + "spare_mpt3_7_0" }, /* SPARE , */ \ + { 0xf387, \ + "calibr_gain_cs" }, /* Current sense gain (signed two's complement format), */ \ + { 0xf40f, \ + "spare_mtp4_15_0" }, /* SPARE , */ \ + { 0xf50f, \ + "calibr_R25C_R" }, /* Ron resistance of speaker coil , */ \ + { 0xf606, \ + "spare_mpt6_6_0" }, /* SPARE , */ \ + { 0xf686, \ + "spare_mpt6_14_8" }, /* Offset of left amplifier level shifter B , */ \ + { 0xf706, \ + "ctrl_offset_a" }, /* Offset of level shifter A , */ \ + { 0xf786, \ + "ctrl_offset_b" }, /* Offset of amplifier level shifter B , */ \ + { 0xf806, \ + "htol_iic_addr" }, /* 7-bit I2C address to be used during HTOL testing , */ \ + { 0xf870, \ + "htol_iic_addr_en" }, /* HTOL I2C address enable control , */ \ + { 0xf884, \ + "calibr_temp_offset" }, /* Temperature offset 2's compliment (key1 protected), */ \ + { 0xf8d2, \ + "calibr_temp_gain" }, /* Temperature gain 2's compliment (key1 protected) , */ \ + { 0xf900, \ + "mtp_lock_dcdcoff_mode" }, /* Disable function dcdcoff_mode , */ \ + { 0xf910, \ + "disable_sam_mode" }, /* Disable same mode , */ \ + { 0xf920, \ + "mtp_lock_bypass_clipper" }, /* Disable function bypass_clipper , */ \ + { 0xf930, \ + "mtp_lock_max_dcdc_voltage" }, /* Disable programming of max dcdc boost voltage , */ \ + { 0xf943, \ + "calibr_vbg_trim" }, /* Bandgap trimming control , */ \ + { 0xf980, \ + "mtp_enbl_amp_in_state_alarm" }, /* Enbl_amp in alarm state , */ \ + { 0xf990, \ + "mtp_enbl_pwm_delay_clock_gating" }, /* pwm delay clock auto gating , */ \ + { 0xf9a0, \ + "mtp_enbl_ocp_clock_gating" }, /* ocpclock auto gating , */ \ + { 0xf9b0, \ + "mtp_gate_cgu_clock_for_test" }, /* cgu test clock control , */ \ + { 0xf9c3, \ + "spare_mtp9_15_12" }, /* MTP-control FW - See Firmware I2C API document for details, */ \ + { 0xfa0f, \ + "mtpdataA" }, /* MTPdataA (key1 protected) , */ \ + { 0xfb0f, \ + "mtpdataB" }, /* MTPdataB (key1 protected) , */ \ + { 0xfc0f, \ + "mtpdataC" }, /* MTPdataC (key1 protected) , */ \ + { 0xfd0f, \ + "mtpdataD" }, /* MTPdataD (key1 protected) , */ \ + { 0xfe0f, \ + "mtpdataE" }, /* MTPdataE (key1 protected) , */ \ + { 0xff07, \ + "calibr_osc_delta_ndiv" }, /* Calibration data for OSC1M, signed number representation, */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +enum TFA9872_irq { + TFA9872_irq_stvdds = 0, + TFA9872_irq_stplls = 1, + TFA9872_irq_stotds = 2, + TFA9872_irq_stovds = 3, + TFA9872_irq_stuvds = 4, + TFA9872_irq_stclks = 5, + TFA9872_irq_stmtpb = 6, + TFA9872_irq_stnoclk = 7, + TFA9872_irq_stsws = 10, + TFA9872_irq_stamps = 12, + TFA9872_irq_starefs = 13, + TFA9872_irq_stadccr = 14, + TFA9872_irq_stbstcu = 16, + TFA9872_irq_stbsthi = 17, + TFA9872_irq_stbstoc = 18, + TFA9872_irq_stbstpkcur = 19, + TFA9872_irq_stbstvc = 20, + TFA9872_irq_stbst86 = 21, + TFA9872_irq_stbst93 = 22, + TFA9872_irq_stocpr = 25, + TFA9872_irq_stmwsrc = 26, + TFA9872_irq_stmwsmu = 28, + TFA9872_irq_stclkoor = 31, + TFA9872_irq_sttdmer = 32, + TFA9872_irq_stclpr = 34, + TFA9872_irq_stlp0 = 36, + TFA9872_irq_stlp1 = 37, + TFA9872_irq_stla = 38, + TFA9872_irq_stvddph = 39, + TFA9872_irq_max = 40, + TFA9872_irq_all = -1 /* all irqs */ +}; + +#define TFA9872_IRQ_NAMETABLE \ + static tfaIrqName_t Tfa9872IrqNames[] = { \ + { 0, "STVDDS" }, { 1, "STPLLS" }, { 2, "STOTDS" }, \ + { 3, "STOVDS" }, { 4, "STUVDS" }, { 5, "STCLKS" }, \ + { 6, "STMTPB" }, { 7, "STNOCLK" }, { 8, "8" }, \ + { 9, "9" }, { 10, "STSWS" }, { 11, "11" }, \ + { 12, "STAMPS" }, { 13, "STAREFS" }, { 14, "STADCCR" }, \ + { 15, "15" }, { 16, "STBSTCU" }, { 17, "STBSTHI" }, \ + { 18, "STBSTOC" }, { 19, "STBSTPKCUR" }, { 20, "STBSTVC" }, \ + { 21, "STBST86" }, { 22, "STBST93" }, { 23, "23" }, \ + { 24, "24" }, { 25, "STOCPR" }, { 26, "STMWSRC" }, \ + { 27, "27" }, { 28, "STMWSMU" }, { 29, "29" }, \ + { 30, "30" }, { 31, "STCLKOOR" }, { 32, "STTDMER" }, \ + { 33, "33" }, { 34, "STCLPR" }, { 35, "35" }, \ + { 36, "STLP0" }, { 37, "STLP1" }, { 38, "STLA" }, \ + { 39, "STVDDPH" }, { 40, "40" }, \ + }; +#endif /* _TFA9872_TFAFIELDNAMES_H */ \ No newline at end of file diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9874_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9874_tfafieldnames.h new file mode 100644 index 000000000000..06aba84cb547 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9874_tfafieldnames.h @@ -0,0 +1,1612 @@ +/** Filename: tfa9874_tfafieldnames.h + * This file was generated automatically on 08/22/17 at 13:43:43. + * Source file: TFA9874N1C0_DefaultI2CSettings.xlsx + */ + +#ifndef _TFA9874_TFAFIELDNAMES_H +#define _TFA9874_TFAFIELDNAMES_H + +#define TFA9874_I2CVERSION 1 + +typedef enum nxpTfa9874BfEnumList { + TFA9874_BF_PWDN = + 0x0000, /*!< Powerdown selection */ + TFA9874_BF_I2CR = + 0x0010, /*!< I2C Reset - Auto clear */ + TFA9874_BF_AMPE = + 0x0030, /*!< Activate Amplifier */ + TFA9874_BF_DCA = + 0x0040, /*!< Activate DC-to-DC converter */ + TFA9874_BF_INTP = + 0x0071, /*!< Interrupt config */ + TFA9874_BF_BYPOCP = + 0x00b0, /*!< Bypass OCP */ + TFA9874_BF_TSTOCP = + 0x00c0, /*!< OCP testing control */ + TFA9874_BF_MANSCONF = + 0x0120, /*!< I2C configured */ + TFA9874_BF_MANAOOSC = + 0x0140, /*!< Internal osc off at PWDN */ + TFA9874_BF_MUTETO = + 0x01d0, /*!< Time out SB mute sequence */ + TFA9874_BF_OPENMTP = + 0x01e0, /*!< Control for FAIM protection */ + TFA9874_BF_AUDFS = + 0x0203, /*!< Sample rate (fs) */ + TFA9874_BF_INPLEV = + 0x0240, /*!< TDM output attenuation */ + TFA9874_BF_FRACTDEL = + 0x0255, /*!< V/I Fractional delay */ + TFA9874_BF_REV = + 0x030f, /*!< Revision info */ + TFA9874_BF_REFCKEXT = + 0x0401, /*!< PLL external ref clock */ + TFA9874_BF_REFCKSEL = + 0x0420, /*!< PLL internal ref clock */ + TFA9874_BF_SSFAIME = + 0x05c0, /*!< Sub-system FAIM */ + TFA9874_BF_AMPOCRT = + 0x0802, /*!< Amplifier on-off criteria for shutdown */ + TFA9874_BF_VDDS = + 0x1000, /*!< POR */ + TFA9874_BF_DCOCPOK = + 0x1010, /*!< DCDC OCP nmos (sticky register , clear on read) */ + TFA9874_BF_OTDS = + 0x1020, /*!< OTP alarm (sticky register , clear on read) */ + TFA9874_BF_OCDS = + 0x1030, /*!< OCP amplifier (sticky register , clear on read) */ + TFA9874_BF_UVDS = + 0x1040, /*!< UVP alarm (sticky register , clear on read) */ + TFA9874_BF_MANALARM = + 0x1050, /*!< Alarm state */ + TFA9874_BF_TDMERR = + 0x1060, /*!< TDM error */ + TFA9874_BF_NOCLK = + 0x1070, /*!< Lost clock (sticky register , clear on read) */ + TFA9874_BF_DCIL = + 0x1100, /*!< DCDC current limiting */ + TFA9874_BF_DCDCA = + 0x1110, /*!< DCDC active (sticky register , clear on read) */ + TFA9874_BF_DCHVBAT = + 0x1130, /*!< DCDC level 1x */ + TFA9874_BF_DCH114 = + 0x1140, /*!< DCDC level 1.14x */ + TFA9874_BF_DCH107 = + 0x1150, /*!< DCDC level 1.07x */ + TFA9874_BF_PLLS = + 0x1160, /*!< PLL lock */ + TFA9874_BF_CLKS = + 0x1170, /*!< Clocks stable */ + TFA9874_BF_TDMLUTER = + 0x1180, /*!< TDM LUT error */ + TFA9874_BF_TDMSTAT = + 0x1192, /*!< TDM status bits */ + TFA9874_BF_MTPB = + 0x11c0, /*!< MTP busy */ + TFA9874_BF_SWS = + 0x11d0, /*!< Amplifier engage */ + TFA9874_BF_AMPS = + 0x11e0, /*!< Amplifier enable */ + TFA9874_BF_AREFS = + 0x11f0, /*!< References enable */ + TFA9874_BF_OCPOAP = + 0x1300, /*!< OCPOK pmos A */ + TFA9874_BF_OCPOAN = + 0x1310, /*!< OCPOK nmos A */ + TFA9874_BF_OCPOBP = + 0x1320, /*!< OCPOK pmos B */ + TFA9874_BF_OCPOBN = + 0x1330, /*!< OCPOK nmos B */ + TFA9874_BF_OVDS = + 0x1380, /*!< OVP alarm */ + TFA9874_BF_CLIPS = + 0x1390, /*!< Amplifier clipping */ + TFA9874_BF_ADCCR = + 0x13a0, /*!< Control ADC */ + TFA9874_BF_MANWAIT1 = + 0x13c0, /*!< Wait HW I2C settings */ + TFA9874_BF_MANMUTE = + 0x13e0, /*!< Audio mute sequence */ + TFA9874_BF_MANOPER = + 0x13f0, /*!< Operating state */ + TFA9874_BF_CLKOOR = + 0x1420, /*!< External clock status */ + TFA9874_BF_MANSTATE = + 0x1433, /*!< Device manager status */ + TFA9874_BF_DCMODE = + 0x1471, /*!< DCDC mode status bits */ + TFA9874_BF_BATS = + 0x1509, /*!< Battery voltage (V) */ + TFA9874_BF_TEMPS = + 0x1608, /*!< IC Temperature (C) */ + TFA9874_BF_VDDPS = + 0x1709, /*!< IC VDDP voltage ( 1023*VDDP/13 V) */ + TFA9874_BF_TDME = + 0x2040, /*!< Enable interface */ + TFA9874_BF_TDMMODE = + 0x2050, /*!< Slave/master */ + TFA9874_BF_TDMCLINV = + 0x2060, /*!< Reception data to BCK clock */ + TFA9874_BF_TDMFSLN = + 0x2073, /*!< FS length (master mode only) */ + TFA9874_BF_TDMFSPOL = + 0x20b0, /*!< FS polarity */ + TFA9874_BF_TDMNBCK = + 0x20c3, /*!< N-BCK's in FS */ + TFA9874_BF_TDMSLOTS = + 0x2103, /*!< N-slots in Frame */ + TFA9874_BF_TDMSLLN = + 0x2144, /*!< N-bits in slot */ + TFA9874_BF_TDMBRMG = + 0x2194, /*!< N-bits remaining */ + TFA9874_BF_TDMDEL = + 0x21e0, /*!< data delay to FS */ + TFA9874_BF_TDMADJ = + 0x21f0, /*!< data adjustment */ + TFA9874_BF_TDMOOMP = + 0x2201, /*!< Received audio compression */ + TFA9874_BF_TDMSSIZE = + 0x2224, /*!< Sample size per slot */ + TFA9874_BF_TDMTXDFO = + 0x2271, /*!< Format unused bits */ + TFA9874_BF_TDMTXUS0 = + 0x2291, /*!< Format unused slots DATAO */ + TFA9874_BF_TDMSPKE = + 0x2300, /*!< Control audio tdm channel in 0 (spkr + dcdc) */ + TFA9874_BF_TDMDCE = + 0x2310, /*!< Control audio tdm channel in 1 (dcdc) */ + TFA9874_BF_TDMCSE = + 0x2330, /*!< current sense vbat temperature and vddp feedback */ + TFA9874_BF_TDMVSE = + 0x2340, /*!< Voltage sense vbat temperature and vddp feedback */ + TFA9874_BF_TDMSPKS = + 0x2603, /*!< tdm slot for sink 0 (speaker + dcdc) */ + TFA9874_BF_TDMDCS = + 0x2643, /*!< tdm slot for sink 1 (dcdc) */ + TFA9874_BF_TDMCSS = + 0x26c3, /*!< Slot Position of current sense vbat temperature and vddp feedback */ + TFA9874_BF_TDMVSS = + 0x2703, /*!< Slot Position of Voltage sense vbat temperature and vddp feedback */ + TFA9874_BF_ISTVDDS = + 0x4000, /*!< Status POR */ + TFA9874_BF_ISTBSTOC = + 0x4010, /*!< Status DCDC OCP */ + TFA9874_BF_ISTOTDS = + 0x4020, /*!< Status OTP alarm */ + TFA9874_BF_ISTOCPR = + 0x4030, /*!< Status ocp alarm */ + TFA9874_BF_ISTUVDS = + 0x4040, /*!< Status UVP alarm */ + TFA9874_BF_ISTMANALARM = + 0x4050, /*!< Status nanager Alarm state */ + TFA9874_BF_ISTTDMER = + 0x4060, /*!< Status tdm error */ + TFA9874_BF_ISTNOCLK = + 0x4070, /*!< Status lost clock */ + TFA9874_BF_ICLVDDS = + 0x4400, /*!< Clear POR */ + TFA9874_BF_ICLBSTOC = + 0x4410, /*!< Clear DCDC OCP */ + TFA9874_BF_ICLOTDS = + 0x4420, /*!< Clear OTP alarm */ + TFA9874_BF_ICLOCPR = + 0x4430, /*!< Clear ocp alarm */ + TFA9874_BF_ICLUVDS = + 0x4440, /*!< Clear UVP alarm */ + TFA9874_BF_ICLMANALARM = + 0x4450, /*!< clear nanager Alarm state */ + TFA9874_BF_ICLTDMER = + 0x4460, /*!< Clear tdm error */ + TFA9874_BF_ICLNOCLK = + 0x4470, /*!< Clear lost clk */ + TFA9874_BF_IEVDDS = + 0x4800, /*!< Enable por */ + TFA9874_BF_IEBSTOC = + 0x4810, /*!< Enable DCDC OCP */ + TFA9874_BF_IEOTDS = + 0x4820, /*!< Enable OTP alarm */ + TFA9874_BF_IEOCPR = + 0x4830, /*!< Enable ocp alarm */ + TFA9874_BF_IEUVDS = + 0x4840, /*!< Enable UVP alarm */ + TFA9874_BF_IEMANALARM = + 0x4850, /*!< Enable nanager Alarm state */ + TFA9874_BF_IETDMER = + 0x4860, /*!< Enable tdm error */ + TFA9874_BF_IENOCLK = + 0x4870, /*!< Enable lost clk */ + TFA9874_BF_IPOVDDS = + 0x4c00, /*!< Polarity por */ + TFA9874_BF_IPOBSTOC = + 0x4c10, /*!< Polarity DCDC OCP */ + TFA9874_BF_IPOOTDS = + 0x4c20, /*!< Polarity OTP alarm */ + TFA9874_BF_IPOOCPR = + 0x4c30, /*!< Polarity ocp alarm */ + TFA9874_BF_IPOUVDS = + 0x4c40, /*!< Polarity UVP alarm */ + TFA9874_BF_IPOMANALARM = + 0x4c50, /*!< Polarity nanager Alarm state */ + TFA9874_BF_IPOTDMER = + 0x4c60, /*!< Polarity tdm error */ + TFA9874_BF_IPONOCLK = + 0x4c70, /*!< Polarity lost clk */ + TFA9874_BF_BSSCR = + 0x5001, /*!< Battery Safeguard attack time */ + TFA9874_BF_BSST = + 0x5023, /*!< Battery Safeguard threshold voltage level */ + TFA9874_BF_BSSRL = + 0x5061, /*!< Battery Safeguard maximum reduction */ + TFA9874_BF_VBATFLTL = + 0x5080, /*!< vbat filter limit */ + TFA9874_BF_BSSR = + 0x50e0, /*!< Battery voltage read out */ + TFA9874_BF_BSSBY = + 0x50f0, /*!< Bypass battery safeguard */ + TFA9874_BF_BSSS = + 0x5100, /*!< Vbat prot steepness */ + TFA9874_BF_HPFBYP = + 0x5150, /*!< Bypass HPF */ + TFA9874_BF_DPSA = + 0x5170, /*!< Enable DPSA */ + TFA9874_BF_CLIPCTRL = + 0x5222, /*!< Clip control setting */ + TFA9874_BF_AMPGAIN = + 0x5257, /*!< Amplifier gain */ + TFA9874_BF_SLOPEE = + 0x52d0, /*!< Enables slope control */ + TFA9874_BF_SLOPESET = + 0x52e0, /*!< Slope speed setting (bin. coded) */ + TFA9874_BF_TDMDCG = + 0x6123, /*!< Second channel gain in case of stereo using a single coil. (Total gain depending on INPLEV). (In case of mono OR stereo using 2 separate DCDC channel 1 should be disabled using TDMDCE) */ + TFA9874_BF_TDMSPKG = + 0x6163, /*!< Total gain depending on INPLEV setting (channel 0) */ + TFA9874_BF_LNMODE = + 0x62e1, /*!< ctrl select mode */ + TFA9874_BF_LPM1MODE = + 0x64e1, /*!< low power mode control */ + TFA9874_BF_TDMSRCMAP = + 0x6802, /*!< tdm source mapping */ + TFA9874_BF_TDMSRCAS = + 0x6831, /*!< Sensed value A */ + TFA9874_BF_TDMSRCBS = + 0x6851, /*!< Sensed value B */ + TFA9874_BF_TDMSRCACLIP = + 0x6871, /*!< clip information (analog /digital) for source0 */ + TFA9874_BF_TDMSRCBCLIP = + 0x6891, /*!< clip information (analog /digital) for source1 */ + TFA9874_BF_LP1 = + 0x6e10, /*!< low power mode 1 detection */ + TFA9874_BF_LA = + 0x6e20, /*!< low amplitude detection */ + TFA9874_BF_VDDPH = + 0x6e30, /*!< vddp greater than vbat */ + TFA9874_BF_DELCURCOMP = + 0x6f02, /*!< delay to allign compensation signal with current sense signal */ + TFA9874_BF_SIGCURCOMP = + 0x6f40, /*!< polarity of compensation for current sense */ + TFA9874_BF_ENCURCOMP = + 0x6f50, /*!< enable current sense compensation */ + TFA9874_BF_LVLCLPPWM = + 0x6f72, /*!< set the amount of pwm pulse that may be skipped before clip-flag is triggered */ + TFA9874_BF_DCMCC = + 0x7033, /*!< Max coil current */ + TFA9874_BF_DCCV = + 0x7071, /*!< Slope compensation current, represents LxF (inductance x frequency) value */ + TFA9874_BF_DCIE = + 0x7090, /*!< Adaptive boost mode */ + TFA9874_BF_DCSR = + 0x70a0, /*!< Soft ramp up/down */ + TFA9874_BF_DCDIS = + 0x70e0, /*!< DCDC on/off */ + TFA9874_BF_DCPWM = + 0x70f0, /*!< DCDC PWM only mode */ + TFA9874_BF_DCTRACK = + 0x7430, /*!< Boost algorithm selection, effective only when boost_intelligent is set to 1 */ + TFA9874_BF_DCTRIP = + 0x7444, /*!< 1st Adaptive boost trip levels, effective only when DCIE is set to 1 */ + TFA9874_BF_DCHOLD = + 0x7494, /*!< Hold time for DCDC booster, effective only when boost_intelligent is set to 1 */ + TFA9874_BF_DCTRIP2 = + 0x7534, /*!< 2nd Adaptive boost trip levels, effective only when DCIE is set to 1 */ + TFA9874_BF_DCTRIPT = + 0x7584, /*!< Track Adaptive boost trip levels, effective only when boost_intelligent is set to 1 */ + TFA9874_BF_DCTRIPHYSTE = + 0x75f0, /*!< Enable hysteresis on booster trip levels */ + TFA9874_BF_DCVOF = + 0x7635, /*!< First boost voltage level */ + TFA9874_BF_DCVOS = + 0x7695, /*!< Second boost voltage level */ + TFA9874_BF_MTPK = + 0xa107, /*!< MTP KEY2 register */ + TFA9874_BF_KEY1LOCKED = + 0xa200, /*!< Indicates KEY1 is locked */ + TFA9874_BF_KEY2LOCKED = + 0xa210, /*!< Indicates KEY2 is locked */ + TFA9874_BF_CIMTP = + 0xa360, /*!< Start copying data from I2C mtp registers to mtp */ + TFA9874_BF_MTPRDMSB = + 0xa50f, /*!< MSB word of MTP manual read data */ + TFA9874_BF_MTPRDLSB = + 0xa60f, /*!< LSB word of MTP manual read data */ + TFA9874_BF_EXTTS = + 0xb108, /*!< External temperature (C) */ + TFA9874_BF_TROS = + 0xb190, /*!< Select temp Speaker calibration */ + TFA9874_BF_SWPROFIL = + 0xee0f, /*!< Software profile data */ + TFA9874_BF_SWVSTEP = + 0xef0f, /*!< Software vstep information */ + TFA9874_BF_MTPOTC = + 0xf000, /*!< Calibration schedule */ + TFA9874_BF_MTPEX = + 0xf010, /*!< Calibration Ron executed */ + TFA9874_BF_DCMCCAPI = + 0xf020, /*!< Calibration current limit DCDC */ + TFA9874_BF_DCMCCSB = + 0xf030, /*!< Sign bit for delta calibration current limit DCDC */ + TFA9874_BF_USERDEF = + 0xf042, /*!< Calibration delta current limit DCDC */ + TFA9874_BF_CUSTINFO = + 0xf078, /*!< Reserved space for allowing customer to store speaker information */ + TFA9874_BF_R25C = + 0xf50f, /*!< Ron resistance of speaker coil */ +} nxpTfa9874BfEnumList_t; +#define TFA9874_NAMETABLE \ + static tfaBfName_t Tfa9874DatasheetNames[] = { \ + { 0x0, \ + "PWDN" }, /* Powerdown selection , */ \ + { 0x10, \ + "I2CR" }, /* I2C Reset - Auto clear , */ \ + { 0x30, \ + "AMPE" }, /* Activate Amplifier , */ \ + { 0x40, \ + "DCA" }, /* Activate DC-to-DC converter , */ \ + { 0x71, \ + "INTP" }, /* Interrupt config , */ \ + { 0xb0, \ + "BYPOCP" }, /* Bypass OCP , */ \ + { 0xc0, \ + "TSTOCP" }, /* OCP testing control , */ \ + { 0x120, \ + "MANSCONF" }, /* I2C configured , */ \ + { 0x140, \ + "MANAOOSC" }, /* Internal osc off at PWDN , */ \ + { 0x1d0, \ + "MUTETO" }, /* Time out SB mute sequence , */ \ + { 0x1e0, \ + "OPENMTP" }, /* Control for FAIM protection , */ \ + { 0x203, \ + "AUDFS" }, /* Sample rate (fs) , */ \ + { 0x240, \ + "INPLEV" }, /* TDM output attenuation , */ \ + { 0x255, \ + "FRACTDEL" }, /* V/I Fractional delay , */ \ + { 0x30f, \ + "REV" }, /* Revision info , */ \ + { 0x401, \ + "REFCKEXT" }, /* PLL external ref clock , */ \ + { 0x420, \ + "REFCKSEL" }, /* PLL internal ref clock , */ \ + { 0x5c0, \ + "SSFAIME" }, /* Sub-system FAIM , */ \ + { 0x802, \ + "AMPOCRT" }, /* Amplifier on-off criteria for shutdown , */ \ + { 0x1000, \ + "VDDS" }, /* POR , */ \ + { 0x1010, \ + "DCOCPOK" }, /* DCDC OCP nmos (sticky register , clear on read) , */ \ + { 0x1020, \ + "OTDS" }, /* OTP alarm (sticky register , clear on read) , */ \ + { 0x1030, \ + "OCDS" }, /* OCP amplifier (sticky register , clear on read), */ \ + { 0x1040, \ + "UVDS" }, /* UVP alarm (sticky register , clear on read) , */ \ + { 0x1050, \ + "MANALARM" }, /* Alarm state , */ \ + { 0x1060, \ + "TDMERR" }, /* TDM error , */ \ + { 0x1070, \ + "NOCLK" }, /* Lost clock (sticky register , clear on read) , */ \ + { 0x1100, \ + "DCIL" }, /* DCDC current limiting , */ \ + { 0x1110, \ + "DCDCA" }, /* DCDC active (sticky register , clear on read) , */ \ + { 0x1130, \ + "DCHVBAT" }, /* DCDC level 1x , */ \ + { 0x1140, \ + "DCH114" }, /* DCDC level 1.14x , */ \ + { 0x1150, \ + "DCH107" }, /* DCDC level 1.07x , */ \ + { 0x1160, \ + "PLLS" }, /* PLL lock , */ \ + { 0x1170, \ + "CLKS" }, /* Clocks stable , */ \ + { 0x1180, \ + "TDMLUTER" }, /* TDM LUT error , */ \ + { 0x1192, \ + "TDMSTAT" }, /* TDM status bits , */ \ + { 0x11c0, \ + "MTPB" }, /* MTP busy , */ \ + { 0x11d0, \ + "SWS" }, /* Amplifier engage , */ \ + { 0x11e0, \ + "AMPS" }, /* Amplifier enable , */ \ + { 0x11f0, \ + "AREFS" }, /* References enable , */ \ + { 0x1300, \ + "OCPOAP" }, /* OCPOK pmos A , */ \ + { 0x1310, \ + "OCPOAN" }, /* OCPOK nmos A , */ \ + { 0x1320, \ + "OCPOBP" }, /* OCPOK pmos B , */ \ + { 0x1330, \ + "OCPOBN" }, /* OCPOK nmos B , */ \ + { 0x1380, \ + "OVDS" }, /* OVP alarm , */ \ + { 0x1390, \ + "CLIPS" }, /* Amplifier clipping , */ \ + { 0x13a0, \ + "ADCCR" }, /* Control ADC , */ \ + { 0x13c0, \ + "MANWAIT1" }, /* Wait HW I2C settings , */ \ + { 0x13e0, \ + "MANMUTE" }, /* Audio mute sequence , */ \ + { 0x13f0, \ + "MANOPER" }, /* Operating state , */ \ + { 0x1420, \ + "CLKOOR" }, /* External clock status , */ \ + { 0x1433, \ + "MANSTATE" }, /* Device manager status , */ \ + { 0x1471, \ + "DCMODE" }, /* DCDC mode status bits , */ \ + { 0x1509, \ + "BATS" }, /* Battery voltage (V) , */ \ + { 0x1608, \ + "TEMPS" }, /* IC Temperature (C) , */ \ + { 0x1709, \ + "VDDPS" }, /* IC VDDP voltage ( 1023*VDDP/13 V) , */ \ + { 0x2040, \ + "TDME" }, /* Enable interface , */ \ + { 0x2050, \ + "TDMMODE" }, /* Slave/master , */ \ + { 0x2060, \ + "TDMCLINV" }, /* Reception data to BCK clock , */ \ + { 0x2073, \ + "TDMFSLN" }, /* FS length (master mode only) , */ \ + { 0x20b0, \ + "TDMFSPOL" }, /* FS polarity , */ \ + { 0x20c3, \ + "TDMNBCK" }, /* N-BCK's in FS , */ \ + { 0x2103, \ + "TDMSLOTS" }, /* N-slots in Frame , */ \ + { 0x2144, \ + "TDMSLLN" }, /* N-bits in slot , */ \ + { 0x2194, \ + "TDMBRMG" }, /* N-bits remaining , */ \ + { 0x21e0, \ + "TDMDEL" }, /* data delay to FS , */ \ + { 0x21f0, \ + "TDMADJ" }, /* data adjustment , */ \ + { 0x2201, \ + "TDMOOMP" }, /* Received audio compression , */ \ + { 0x2224, \ + "TDMSSIZE" }, /* Sample size per slot , */ \ + { 0x2271, \ + "TDMTXDFO" }, /* Format unused bits , */ \ + { 0x2291, \ + "TDMTXUS0" }, /* Format unused slots DATAO , */ \ + { 0x2300, \ + "TDMSPKE" }, /* Control audio tdm channel in 0 (spkr + dcdc) , */ \ + { 0x2310, \ + "TDMDCE" }, /* Control audio tdm channel in 1 (dcdc) , */ \ + { 0x2330, \ + "TDMCSE" }, /* current sense vbat temperature and vddp feedback , */ \ + { 0x2340, \ + "TDMVSE" }, /* Voltage sense vbat temperature and vddp feedback , */ \ + { 0x2603, \ + "TDMSPKS" }, /* tdm slot for sink 0 (speaker + dcdc) , */ \ + { 0x2643, \ + "TDMDCS" }, /* tdm slot for sink 1 (dcdc) , */ \ + { 0x26c3, \ + "TDMCSS" }, /* Slot Position of current sense vbat temperature and vddp feedback, */ \ + { 0x2703, \ + "TDMVSS" }, /* Slot Position of Voltage sense vbat temperature and vddp feedback, */ \ + { 0x4000, \ + "ISTVDDS" }, /* Status POR , */ \ + { 0x4010, \ + "ISTBSTOC" }, /* Status DCDC OCP , */ \ + { 0x4020, \ + "ISTOTDS" }, /* Status OTP alarm , */ \ + { 0x4030, \ + "ISTOCPR" }, /* Status ocp alarm , */ \ + { 0x4040, \ + "ISTUVDS" }, /* Status UVP alarm , */ \ + { 0x4050, \ + "ISTMANALARM" }, /* Status nanager Alarm state , */ \ + { 0x4060, \ + "ISTTDMER" }, /* Status tdm error , */ \ + { 0x4070, \ + "ISTNOCLK" }, /* Status lost clock , */ \ + { 0x4400, \ + "ICLVDDS" }, /* Clear POR , */ \ + { 0x4410, \ + "ICLBSTOC" }, /* Clear DCDC OCP , */ \ + { 0x4420, \ + "ICLOTDS" }, /* Clear OTP alarm , */ \ + { 0x4430, \ + "ICLOCPR" }, /* Clear ocp alarm , */ \ + { 0x4440, \ + "ICLUVDS" }, /* Clear UVP alarm , */ \ + { 0x4450, \ + "ICLMANALARM" }, /* clear nanager Alarm state , */ \ + { 0x4460, \ + "ICLTDMER" }, /* Clear tdm error , */ \ + { 0x4470, \ + "ICLNOCLK" }, /* Clear lost clk , */ \ + { 0x4800, \ + "IEVDDS" }, /* Enable por , */ \ + { 0x4810, \ + "IEBSTOC" }, /* Enable DCDC OCP , */ \ + { 0x4820, \ + "IEOTDS" }, /* Enable OTP alarm , */ \ + { 0x4830, \ + "IEOCPR" }, /* Enable ocp alarm , */ \ + { 0x4840, \ + "IEUVDS" }, /* Enable UVP alarm , */ \ + { 0x4850, \ + "IEMANALARM" }, /* Enable nanager Alarm state , */ \ + { 0x4860, \ + "IETDMER" }, /* Enable tdm error , */ \ + { 0x4870, \ + "IENOCLK" }, /* Enable lost clk , */ \ + { 0x4c00, \ + "IPOVDDS" }, /* Polarity por , */ \ + { 0x4c10, \ + "IPOBSTOC" }, /* Polarity DCDC OCP , */ \ + { 0x4c20, \ + "IPOOTDS" }, /* Polarity OTP alarm , */ \ + { 0x4c30, \ + "IPOOCPR" }, /* Polarity ocp alarm , */ \ + { 0x4c40, \ + "IPOUVDS" }, /* Polarity UVP alarm , */ \ + { 0x4c50, \ + "IPOMANALARM" }, /* Polarity nanager Alarm state , */ \ + { 0x4c60, \ + "IPOTDMER" }, /* Polarity tdm error , */ \ + { 0x4c70, \ + "IPONOCLK" }, /* Polarity lost clk , */ \ + { 0x5001, \ + "BSSCR" }, /* Battery Safeguard attack time , */ \ + { 0x5023, \ + "BSST" }, /* Battery Safeguard threshold voltage level , */ \ + { 0x5061, \ + "BSSRL" }, /* Battery Safeguard maximum reduction , */ \ + { 0x5080, \ + "VBATFLTL" }, /* vbat filter limit , */ \ + { 0x50e0, \ + "BSSR" }, /* Battery voltage read out , */ \ + { 0x50f0, \ + "BSSBY" }, /* Bypass battery safeguard , */ \ + { 0x5100, \ + "BSSS" }, /* Vbat prot steepness , */ \ + { 0x5150, \ + "HPFBYP" }, /* Bypass HPF , */ \ + { 0x5170, \ + "DPSA" }, /* Enable DPSA , */ \ + { 0x5222, \ + "CLIPCTRL" }, /* Clip control setting , */ \ + { 0x5257, \ + "AMPGAIN" }, /* Amplifier gain , */ \ + { 0x52d0, \ + "SLOPEE" }, /* Enables slope control , */ \ + { 0x52e0, \ + "SLOPESET" }, /* Slope speed setting (bin. coded) , */ \ + { 0x6123, \ + "TDMDCG" }, /* Second channel gain in case of stereo using a single coil. (Total gain depending on INPLEV). (In case of mono OR stereo using 2 separate DCDC channel 1 should be disabled using TDMDCE), */ \ + { 0x6163, \ + "TDMSPKG" }, /* Total gain depending on INPLEV setting (channel 0), */ \ + { 0x62e1, \ + "LNMODE" }, /* ctrl select mode , */ \ + { 0x64e1, \ + "LPM1MODE" }, /* low power mode control , */ \ + { 0x6802, \ + "TDMSRCMAP" }, /* tdm source mapping , */ \ + { 0x6831, \ + "TDMSRCAS" }, /* Sensed value A , */ \ + { 0x6851, \ + "TDMSRCBS" }, /* Sensed value B , */ \ + { 0x6871, \ + "TDMSRCACLIP" }, /* clip information (analog /digital) for source0 , */ \ + { 0x6891, \ + "TDMSRCBCLIP" }, /* clip information (analog /digital) for source1 , */ \ + { 0x6e10, \ + "LP1" }, /* low power mode 1 detection , */ \ + { 0x6e20, \ + "LA" }, /* low amplitude detection , */ \ + { 0x6e30, \ + "VDDPH" }, /* vddp greater than vbat , */ \ + { 0x6f02, \ + "DELCURCOMP" }, /* delay to allign compensation signal with current sense signal, */ \ + { 0x6f40, \ + "SIGCURCOMP" }, /* polarity of compensation for current sense , */ \ + { 0x6f50, \ + "ENCURCOMP" }, /* enable current sense compensation , */ \ + { 0x6f72, \ + "LVLCLPPWM" }, /* set the amount of pwm pulse that may be skipped before clip-flag is triggered, */ \ + { 0x7033, \ + "DCMCC" }, /* Max coil current , */ \ + { 0x7071, \ + "DCCV" }, /* Slope compensation current, represents LxF (inductance x frequency) value , */ \ + { 0x7090, \ + "DCIE" }, /* Adaptive boost mode , */ \ + { 0x70a0, \ + "DCSR" }, /* Soft ramp up/down , */ \ + { 0x70e0, \ + "DCDIS" }, /* DCDC on/off , */ \ + { 0x70f0, \ + "DCPWM" }, /* DCDC PWM only mode , */ \ + { 0x7430, \ + "DCTRACK" }, /* Boost algorithm selection, effective only when boost_intelligent is set to 1, */ \ + { 0x7444, \ + "DCTRIP" }, /* 1st Adaptive boost trip levels, effective only when DCIE is set to 1, */ \ + { 0x7494, \ + "DCHOLD" }, /* Hold time for DCDC booster, effective only when boost_intelligent is set to 1, */ \ + { 0x7534, \ + "DCTRIP2" }, /* 2nd Adaptive boost trip levels, effective only when DCIE is set to 1, */ \ + { 0x7584, \ + "DCTRIPT" }, /* Track Adaptive boost trip levels, effective only when boost_intelligent is set to 1, */ \ + { 0x75f0, \ + "DCTRIPHYSTE" }, /* Enable hysteresis on booster trip levels , */ \ + { 0x7635, \ + "DCVOF" }, /* First boost voltage level , */ \ + { 0x7695, \ + "DCVOS" }, /* Second boost voltage level , */ \ + { 0xa107, \ + "MTPK" }, /* MTP KEY2 register , */ \ + { 0xa200, \ + "KEY1LOCKED" }, /* Indicates KEY1 is locked , */ \ + { 0xa210, \ + "KEY2LOCKED" }, /* Indicates KEY2 is locked , */ \ + { 0xa360, \ + "CIMTP" }, /* Start copying data from I2C mtp registers to mtp , */ \ + { 0xa50f, \ + "MTPRDMSB" }, /* MSB word of MTP manual read data , */ \ + { 0xa60f, \ + "MTPRDLSB" }, /* LSB word of MTP manual read data , */ \ + { 0xb108, \ + "EXTTS" }, /* External temperature (C) , */ \ + { 0xb190, \ + "TROS" }, /* Select temp Speaker calibration , */ \ + { 0xee0f, \ + "SWPROFIL" }, /* Software profile data , */ \ + { 0xef0f, \ + "SWVSTEP" }, /* Software vstep information , */ \ + { 0xf000, \ + "MTPOTC" }, /* Calibration schedule , */ \ + { 0xf010, \ + "MTPEX" }, /* Calibration Ron executed , */ \ + { 0xf020, \ + "DCMCCAPI" }, /* Calibration current limit DCDC , */ \ + { 0xf030, \ + "DCMCCSB" }, /* Sign bit for delta calibration current limit DCDC , */ \ + { 0xf042, \ + "USERDEF" }, /* Calibration delta current limit DCDC , */ \ + { 0xf078, \ + "CUSTINFO" }, /* Reserved space for allowing customer to store speaker information, */ \ + { 0xf50f, \ + "R25C" }, /* Ron resistance of speaker coil , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +#define TFA9874_BITNAMETABLE \ + static tfaBfName_t Tfa9874BitNames[] = { \ + { 0x0, \ + "powerdown" }, /* Powerdown selection , */ \ + { 0x10, \ + "reset" }, /* I2C Reset - Auto clear , */ \ + { 0x30, \ + "enbl_amplifier" }, /* Activate Amplifier , */ \ + { 0x40, \ + "enbl_boost" }, /* Activate DC-to-DC converter , */ \ + { 0x71, \ + "int_pad_io" }, /* Interrupt config , */ \ + { 0xb0, \ + "bypass_ocp" }, /* Bypass OCP , */ \ + { 0xc0, \ + "test_ocp" }, /* OCP testing control , */ \ + { 0x120, \ + "src_set_configured" }, /* I2C configured , */ \ + { 0x140, \ + "enbl_osc1m_auto_off" }, /* Internal osc off at PWDN , */ \ + { 0x1d0, \ + "disable_mute_time_out" }, /* Time out SB mute sequence , */ \ + { 0x1e0, \ + "unprotect_faim" }, /* Control for FAIM protection , */ \ + { 0x203, \ + "audio_fs" }, /* Sample rate (fs) , */ \ + { 0x240, \ + "input_level" }, /* TDM output attenuation , */ \ + { 0x255, \ + "cs_frac_delay" }, /* V/I Fractional delay , */ \ + { 0x2d0, \ + "sel_hysteresis" }, /* Select hysteresis for clock range detector , */ \ + { 0x30f, \ + "device_rev" }, /* Revision info , */ \ + { 0x401, \ + "pll_clkin_sel" }, /* PLL external ref clock , */ \ + { 0x420, \ + "pll_clkin_sel_osc" }, /* PLL internal ref clock , */ \ + { 0x5c0, \ + "enbl_faim_ss" }, /* Sub-system FAIM , */ \ + { 0x802, \ + "ctrl_on2off_criterion" }, /* Amplifier on-off criteria for shutdown , */ \ + { 0xe07, \ + "ctrl_digtoana" }, /* Spare control from digital to analog , */ \ + { 0xf0f, \ + "hidden_code" }, /* 5A6Bh, 23147d to access registers (default for engineering), */ \ + { 0x1000, \ + "flag_por" }, /* POR , */ \ + { 0x1010, \ + "flag_bst_ocpok" }, /* DCDC OCP nmos (sticky register , clear on read) , */ \ + { 0x1020, \ + "flag_otpok" }, /* OTP alarm (sticky register , clear on read) , */ \ + { 0x1030, \ + "flag_ocp_alarm" }, /* OCP amplifier (sticky register , clear on read), */ \ + { 0x1040, \ + "flag_uvpok" }, /* UVP alarm (sticky register , clear on read) , */ \ + { 0x1050, \ + "flag_man_alarm_state" }, /* Alarm state , */ \ + { 0x1060, \ + "flag_tdm_error" }, /* TDM error , */ \ + { 0x1070, \ + "flag_lost_clk" }, /* Lost clock (sticky register , clear on read) , */ \ + { 0x1100, \ + "flag_bst_bstcur" }, /* DCDC current limiting , */ \ + { 0x1110, \ + "flag_bst_hiz" }, /* DCDC active (sticky register , clear on read) , */ \ + { 0x1120, \ + "flag_bst_peakcur" }, /* Indicates current is max in DC-to-DC converter , */ \ + { 0x1130, \ + "flag_bst_voutcomp" }, /* DCDC level 1x , */ \ + { 0x1140, \ + "flag_bst_voutcomp86" }, /* DCDC level 1.14x , */ \ + { 0x1150, \ + "flag_bst_voutcomp93" }, /* DCDC level 1.07x , */ \ + { 0x1160, \ + "flag_pll_lock" }, /* PLL lock , */ \ + { 0x1170, \ + "flag_clocks_stable" }, /* Clocks stable , */ \ + { 0x1180, \ + "flag_tdm_lut_error" }, /* TDM LUT error , */ \ + { 0x1192, \ + "flag_tdm_status" }, /* TDM status bits , */ \ + { 0x11c0, \ + "flag_mtp_busy" }, /* MTP busy , */ \ + { 0x11d0, \ + "flag_engage" }, /* Amplifier engage , */ \ + { 0x11e0, \ + "flag_enbl_amp" }, /* Amplifier enable , */ \ + { 0x11f0, \ + "flag_enbl_ref" }, /* References enable , */ \ + { 0x1300, \ + "flag_ocpokap" }, /* OCPOK pmos A , */ \ + { 0x1310, \ + "flag_ocpokan" }, /* OCPOK nmos A , */ \ + { 0x1320, \ + "flag_ocpokbp" }, /* OCPOK pmos B , */ \ + { 0x1330, \ + "flag_ocpokbn" }, /* OCPOK nmos B , */ \ + { 0x1380, \ + "flag_ovpok" }, /* OVP alarm , */ \ + { 0x1390, \ + "flag_clip" }, /* Amplifier clipping , */ \ + { 0x13a0, \ + "flag_adc10_ready" }, /* Control ADC , */ \ + { 0x13c0, \ + "flag_man_wait_src_settings" }, /* Wait HW I2C settings , */ \ + { 0x13e0, \ + "flag_man_start_mute_audio" }, /* Audio mute sequence , */ \ + { 0x13f0, \ + "flag_man_operating_state" }, /* Operating state , */ \ + { 0x1420, \ + "flag_clk_out_of_range" }, /* External clock status , */ \ + { 0x1433, \ + "man_state" }, /* Device manager status , */ \ + { 0x1471, \ + "status_bst_mode" }, /* DCDC mode status bits , */ \ + { 0x1509, \ + "bat_adc" }, /* Battery voltage (V) , */ \ + { 0x1608, \ + "temp_adc" }, /* IC Temperature (C) , */ \ + { 0x1709, \ + "vddp_adc" }, /* IC VDDP voltage ( 1023*VDDP/13 V) , */ \ + { 0x2040, \ + "tdm_enable" }, /* Enable interface , */ \ + { 0x2050, \ + "tdm_mode" }, /* Slave/master , */ \ + { 0x2060, \ + "tdm_clk_inversion" }, /* Reception data to BCK clock , */ \ + { 0x2073, \ + "tdm_fs_ws_length" }, /* FS length (master mode only) , */ \ + { 0x20b0, \ + "tdm_fs_ws_polarity" }, /* FS polarity , */ \ + { 0x20c3, \ + "tdm_nbck" }, /* N-BCK's in FS , */ \ + { 0x2103, \ + "tdm_nb_of_slots" }, /* N-slots in Frame , */ \ + { 0x2144, \ + "tdm_slot_length" }, /* N-bits in slot , */ \ + { 0x2194, \ + "tdm_bits_remaining" }, /* N-bits remaining , */ \ + { 0x21e0, \ + "tdm_data_delay" }, /* data delay to FS , */ \ + { 0x21f0, \ + "tdm_data_adjustment" }, /* data adjustment , */ \ + { 0x2201, \ + "tdm_audio_sample_compression" }, /* Received audio compression , */ \ + { 0x2224, \ + "tdm_sample_size" }, /* Sample size per slot , */ \ + { 0x2271, \ + "tdm_txdata_format" }, /* Format unused bits , */ \ + { 0x2291, \ + "tdm_txdata_format_unused_slot_sd0" }, /* Format unused slots DATAO , */ \ + { 0x2300, \ + "tdm_sink0_enable" }, /* Control audio tdm channel in 0 (spkr + dcdc) , */ \ + { 0x2310, \ + "tdm_sink1_enable" }, /* Control audio tdm channel in 1 (dcdc) , */ \ + { 0x2330, \ + "tdm_source0_enable" }, /* current sense vbat temperature and vddp feedback , */ \ + { 0x2340, \ + "tdm_source1_enable" }, /* Voltage sense vbat temperature and vddp feedback , */ \ + { 0x2603, \ + "tdm_sink0_slot" }, /* tdm slot for sink 0 (speaker + dcdc) , */ \ + { 0x2643, \ + "tdm_sink1_slot" }, /* tdm slot for sink 1 (dcdc) , */ \ + { 0x26c3, \ + "tdm_source0_slot" }, /* Slot Position of current sense vbat temperature and vddp feedback, */ \ + { 0x2703, \ + "tdm_source1_slot" }, /* Slot Position of Voltage sense vbat temperature and vddp feedback, */ \ + { 0x4000, \ + "int_out_flag_por" }, /* Status POR , */ \ + { 0x4010, \ + "int_out_flag_bst_ocpok" }, /* Status DCDC OCP , */ \ + { 0x4020, \ + "int_out_flag_otpok" }, /* Status OTP alarm , */ \ + { 0x4030, \ + "int_out_flag_ocp_alarm" }, /* Status ocp alarm , */ \ + { 0x4040, \ + "int_out_flag_uvpok" }, /* Status UVP alarm , */ \ + { 0x4050, \ + "int_out_flag_man_alarm_state" }, /* Status nanager Alarm state , */ \ + { 0x4060, \ + "int_out_flag_tdm_error" }, /* Status tdm error , */ \ + { 0x4070, \ + "int_out_flag_lost_clk" }, /* Status lost clock , */ \ + { 0x4400, \ + "int_in_flag_por" }, /* Clear POR , */ \ + { 0x4410, \ + "int_in_flag_bst_ocpok" }, /* Clear DCDC OCP , */ \ + { 0x4420, \ + "int_in_flag_otpok" }, /* Clear OTP alarm , */ \ + { 0x4430, \ + "int_in_flag_ocp_alarm" }, /* Clear ocp alarm , */ \ + { 0x4440, \ + "int_in_flag_uvpok" }, /* Clear UVP alarm , */ \ + { 0x4450, \ + "int_in_flag_man_alarm_state" }, /* clear nanager Alarm state , */ \ + { 0x4460, \ + "int_in_flag_tdm_error" }, /* Clear tdm error , */ \ + { 0x4470, \ + "int_in_flag_lost_clk" }, /* Clear lost clk , */ \ + { 0x4800, \ + "int_enable_flag_por" }, /* Enable por , */ \ + { 0x4810, \ + "int_enable_flag_bst_ocpok" }, /* Enable DCDC OCP , */ \ + { 0x4820, \ + "int_enable_flag_otpok" }, /* Enable OTP alarm , */ \ + { 0x4830, \ + "int_enable_flag_ocp_alarm" }, /* Enable ocp alarm , */ \ + { 0x4840, \ + "int_enable_flag_uvpok" }, /* Enable UVP alarm , */ \ + { 0x4850, \ + "int_enable_flag_man_alarm_state" }, /* Enable nanager Alarm state , */ \ + { 0x4860, \ + "int_enable_flag_tdm_error" }, /* Enable tdm error , */ \ + { 0x4870, \ + "int_enable_flag_lost_clk" }, /* Enable lost clk , */ \ + { 0x4c00, \ + "int_polarity_flag_por" }, /* Polarity por , */ \ + { 0x4c10, \ + "int_polarity_flag_bst_ocpok" }, /* Polarity DCDC OCP , */ \ + { 0x4c20, \ + "int_polarity_flag_otpok" }, /* Polarity OTP alarm , */ \ + { 0x4c30, \ + "int_polarity_flag_ocp_alarm" }, /* Polarity ocp alarm , */ \ + { 0x4c40, \ + "int_polarity_flag_uvpok" }, /* Polarity UVP alarm , */ \ + { 0x4c50, \ + "int_polarity_flag_man_alarm_state" }, /* Polarity nanager Alarm state , */ \ + { 0x4c60, \ + "int_polarity_flag_tdm_error" }, /* Polarity tdm error , */ \ + { 0x4c70, \ + "int_polarity_flag_lost_clk" }, /* Polarity lost clk , */ \ + { 0x5001, \ + "vbat_prot_attack_time" }, /* Battery Safeguard attack time , */ \ + { 0x5023, \ + "vbat_prot_thlevel" }, /* Battery Safeguard threshold voltage level , */ \ + { 0x5061, \ + "vbat_prot_max_reduct" }, /* Battery Safeguard maximum reduction , */ \ + { 0x5080, \ + "vbat_flt_limit" }, /* vbat filter limit , */ \ + { 0x50d0, \ + "rst_min_vbat" }, /* Reset clipper - Auto clear , */ \ + { 0x50e0, \ + "sel_vbat" }, /* Battery voltage read out , */ \ + { 0x50f0, \ + "bypass_clipper" }, /* Bypass battery safeguard , */ \ + { 0x5100, \ + "batsense_steepness" }, /* Vbat prot steepness , */ \ + { 0x5150, \ + "bypass_hp" }, /* Bypass HPF , */ \ + { 0x5170, \ + "enbl_dpsa" }, /* Enable DPSA , */ \ + { 0x5222, \ + "ctrl_cc" }, /* Clip control setting , */ \ + { 0x5257, \ + "gain" }, /* Amplifier gain , */ \ + { 0x52d0, \ + "ctrl_slopectrl" }, /* Enables slope control , */ \ + { 0x52e0, \ + "ctrl_slope" }, /* Slope speed setting (bin. coded) , */ \ + { 0x5301, \ + "dpsa_level" }, /* DPSA threshold levels , */ \ + { 0x5321, \ + "dpsa_release" }, /* DPSA Release time , */ \ + { 0x5340, \ + "clipfast" }, /* Clock selection for HW clipper for Battery Safeguard, */ \ + { 0x5350, \ + "bypass_lp" }, /* Bypass the low power filter inside temperature sensor, */ \ + { 0x5400, \ + "first_order_mode" }, /* Overrule to 1st order mode of control stage when clipping, */ \ + { 0x5410, \ + "bypass_ctrlloop" }, /* Switch amplifier into open loop configuration , */ \ + { 0x5430, \ + "icomp_engage" }, /* Engage of icomp , */ \ + { 0x5440, \ + "ctrl_kickback" }, /* Prevent double pulses of output stage , */ \ + { 0x5450, \ + "icomp_engage_overrule" }, /* To overrule the functional icomp_engage signal during validation, */ \ + { 0x5503, \ + "ctrl_dem" }, /* Enable DEM icomp and DEM one bit dac , */ \ + { 0x5543, \ + "ctrl_dem_mismatch" }, /* Enable DEM icomp mismatch for testing , */ \ + { 0x5582, \ + "dpsa_drive" }, /* Drive setting (bin. coded) , */ \ + { 0x5690, \ + "sel_pwm_delay_src" }, /* Control for selection for PWM delay line source , */ \ + { 0x56a1, \ + "enbl_odd_up_even_down" }, /* Control for PWM reference sawtooth generartion , */ \ + { 0x570a, \ + "enbl_amp" }, /* Switch on the class-D power sections, each part of the analog sections can be switched on/off individually, */ \ + { 0x57b0, \ + "enbl_engage" }, /* Enables/engage power stage and control loop , */ \ + { 0x57c0, \ + "enbl_engage_pst" }, /* Enables/engage power stage and control loop , */ \ + { 0x5810, \ + "hard_mute" }, /* Hard mute - PWM , */ \ + { 0x5820, \ + "pwm_shape" }, /* PWM shape , */ \ + { 0x5844, \ + "pwm_delay" }, /* PWM delay bits to set the delay, clockd is 1/(k*2048*fs), */ \ + { 0x5890, \ + "reclock_pwm" }, /* Reclock the pwm signal inside analog , */ \ + { 0x58a0, \ + "reclock_voltsense" }, /* Reclock the voltage sense pwm signal , */ \ + { 0x58c0, \ + "enbl_pwm_phase_shift" }, /* Control for pwm phase shift , */ \ + { 0x6123, \ + "ctrl_attl" }, /* Second channel gain in case of stereo using a single coil. (Total gain depending on INPLEV). (In case of mono OR stereo using 2 separate DCDC channel 1 should be disabled using TDMDCE), */ \ + { 0x6163, \ + "ctrl_attr" }, /* Total gain depending on INPLEV setting (channel 0), */ \ + { 0x6265, \ + "zero_lvl" }, /* low noise gain switch zero trigger level , */ \ + { 0x62c1, \ + "ctrl_fb_resistor" }, /* Select amplifier feedback resistor connection , */ \ + { 0x62e1, \ + "lownoisegain_mode" }, /* ctrl select mode , */ \ + { 0x6305, \ + "threshold_lvl" }, /* low noise gain switch trigger level , */ \ + { 0x6365, \ + "hold_time" }, /* ctrl hold time before low audio is reckoned to be low audio, */ \ + { 0x6405, \ + "lpm1_cal_offset" }, /* low power mode1 detector ctrl cal_offset from gain module , */ \ + { 0x6465, \ + "lpm1_zero_lvl" }, /* low power mode1 zero crossing detection level , */ \ + { 0x64e1, \ + "lpm1_mode" }, /* low power mode control , */ \ + { 0x6505, \ + "lpm1_threshold_lvl" }, /* low power mode1 amplitude trigger level , */ \ + { 0x6565, \ + "lpm1_hold_time" }, /* low power mode1 detector ctrl hold time before low audio is reckoned to be low audio, */ \ + { 0x65c0, \ + "disable_low_power_mode" }, /* low power mode1 detector control , */ \ + { 0x6600, \ + "dcdc_pfm20khz_limit" }, /* DCDC in PFM mode pwm mode is activated each 50us to force a pwm pulse, */ \ + { 0x6611, \ + "dcdc_ctrl_maxzercnt" }, /* DCDC. Number of zero current flags to count before going to pfm mode, */ \ + { 0x6656, \ + "dcdc_vbat_delta_detect" }, /* Threshold before booster is reacting on a delta Vbat (in PFM mode) by temporarily switching to PWM mode, */ \ + { 0x66c0, \ + "dcdc_ignore_vbat" }, /* Ignore an increase on Vbat , */ \ + { 0x6700, \ + "enbl_minion" }, /* Enables minion (small) power stage , */ \ + { 0x6713, \ + "vth_vddpvbat" }, /* select vddp-vbat thres signal , */ \ + { 0x6750, \ + "lpen_vddpvbat" }, /* select vddp-vbat filtred vs unfiltered compare , */ \ + { 0x6761, \ + "ctrl_rfb" }, /* Feedback resistor selection - I2C direct mode , */ \ + { 0x6802, \ + "tdm_source_mapping" }, /* tdm source mapping , */ \ + { 0x6831, \ + "tdm_sourcea_frame_sel" }, /* Sensed value A , */ \ + { 0x6851, \ + "tdm_sourceb_frame_sel" }, /* Sensed value B , */ \ + { 0x6871, \ + "tdm_source0_clip_sel" }, /* clip information (analog /digital) for source0 , */ \ + { 0x6891, \ + "tdm_source1_clip_sel" }, /* clip information (analog /digital) for source1 , */ \ + { 0x6a02, \ + "rst_min_vbat_delay" }, /* rst_min_vbat delay (nb fs) , */ \ + { 0x6b00, \ + "disable_auto_engage" }, /* disable auto engange , */ \ + { 0x6b10, \ + "disable_engage" }, /* disable engange , */ \ + { 0x6c02, \ + "ns_hp2ln_criterion" }, /* 0..7 zeroes at ns as threshold to swap from high_power to low_noise, */ \ + { 0x6c32, \ + "ns_ln2hp_criterion" }, /* 0..7 zeroes at ns as threshold to swap from low_noise to high_power, */ \ + { 0x6c69, \ + "spare_out" }, /* spare_out , */ \ + { 0x6d0f, \ + "spare_in" }, /* spare_in , */ \ + { 0x6e10, \ + "flag_lp_detect_mode1" }, /* low power mode 1 detection , */ \ + { 0x6e20, \ + "flag_low_amplitude" }, /* low amplitude detection , */ \ + { 0x6e30, \ + "flag_vddp_gt_vbat" }, /* vddp greater than vbat , */ \ + { 0x6f02, \ + "cursense_comp_delay" }, /* delay to allign compensation signal with current sense signal, */ \ + { 0x6f40, \ + "cursense_comp_sign" }, /* polarity of compensation for current sense , */ \ + { 0x6f50, \ + "enbl_cursense_comp" }, /* enable current sense compensation , */ \ + { 0x6f72, \ + "pwms_clip_lvl" }, /* set the amount of pwm pulse that may be skipped before clip-flag is triggered, */ \ + { 0x7033, \ + "boost_cur" }, /* Max coil current , */ \ + { 0x7071, \ + "bst_slpcmplvl" }, /* Slope compensation current, represents LxF (inductance x frequency) value , */ \ + { 0x7090, \ + "boost_intel" }, /* Adaptive boost mode , */ \ + { 0x70a0, \ + "boost_speed" }, /* Soft ramp up/down , */ \ + { 0x70e0, \ + "dcdcoff_mode" }, /* DCDC on/off , */ \ + { 0x70f0, \ + "dcdc_pwmonly" }, /* DCDC PWM only mode , */ \ + { 0x7104, \ + "bst_drive" }, /* Binary coded drive setting for boost converter power stage, */ \ + { 0x7151, \ + "bst_scalecur" }, /* For testing direct control scale current , */ \ + { 0x7174, \ + "bst_slopecur" }, /* For testing direct control slope current , */ \ + { 0x71c1, \ + "bst_slope" }, /* Boost slope speed , */ \ + { 0x71e0, \ + "bst_bypass_bstcur" }, /* Bypass control for boost current settings , */ \ + { 0x71f0, \ + "bst_bypass_bstfoldback" }, /* Bypass control for boost foldback , */ \ + { 0x7200, \ + "enbl_bst_engage" }, /* Enable power stage dcdc controller , */ \ + { 0x7210, \ + "enbl_bst_hizcom" }, /* Enable hiz comparator , */ \ + { 0x7220, \ + "enbl_bst_peak2avg" }, /* Enable boost peak2avg functionality , */ \ + { 0x7230, \ + "enbl_bst_peakcur" }, /* Enable peak current , */ \ + { 0x7240, \ + "enbl_bst_power" }, /* Enable line of the powerstage , */ \ + { 0x7250, \ + "enbl_bst_slopecur" }, /* Enable bit of max-current dac , */ \ + { 0x7260, \ + "enbl_bst_voutcomp" }, /* Enable vout comparators , */ \ + { 0x7270, \ + "enbl_bst_voutcomp86" }, /* Enable vout-86 comparators , */ \ + { 0x7280, \ + "enbl_bst_voutcomp93" }, /* Enable vout-93 comparators , */ \ + { 0x7290, \ + "enbl_bst_windac" }, /* Enable window dac , */ \ + { 0x72a5, \ + "bst_windac" }, /* for testing direct control windac , */ \ + { 0x7300, \ + "boost_alg" }, /* Control for boost adaptive loop gain , */ \ + { 0x7311, \ + "boost_loopgain" }, /* DCDC boost loopgain setting , */ \ + { 0x7331, \ + "bst_freq" }, /* DCDC boost frequency control , */ \ + { 0x7360, \ + "bst_use_new_zercur_detect" }, /* Enable new zero current detection for boost control, */ \ + { 0x7430, \ + "boost_track" }, /* Boost algorithm selection, effective only when boost_intelligent is set to 1, */ \ + { 0x7444, \ + "boost_trip_lvl_1st" }, /* 1st Adaptive boost trip levels, effective only when DCIE is set to 1, */ \ + { 0x7494, \ + "boost_hold_time" }, /* Hold time for DCDC booster, effective only when boost_intelligent is set to 1, */ \ + { 0x74e0, \ + "sel_dcdc_envelope_8fs" }, /* Selection of data for adaptive boost algorithm, effective only when boost_intelligent is set to 1, */ \ + { 0x74f0, \ + "ignore_flag_voutcomp86" }, /* Determines the maximum PWM frequency be the most efficient in relation to the Booster inductor value, */ \ + { 0x7534, \ + "boost_trip_lvl_2nd" }, /* 2nd Adaptive boost trip levels, effective only when DCIE is set to 1, */ \ + { 0x7584, \ + "boost_trip_lvl_track" }, /* Track Adaptive boost trip levels, effective only when boost_intelligent is set to 1, */ \ + { 0x75f0, \ + "enbl_trip_hyst" }, /* Enable hysteresis on booster trip levels , */ \ + { 0x7635, \ + "frst_boost_voltage" }, /* First boost voltage level , */ \ + { 0x7695, \ + "scnd_boost_voltage" }, /* Second boost voltage level , */ \ + { 0x8001, \ + "sel_clk_cs" }, /* Current sense clock duty cycle control , */ \ + { 0x8021, \ + "micadc_speed" }, /* Current sense clock for MiCADC selection - 32/44.1/48 KHz Fs band only, */ \ + { 0x8050, \ + "cs_gain_control" }, /* Current sense gain control , */ \ + { 0x8060, \ + "cs_bypass_gc" }, /* Bypasses the CS gain correction , */ \ + { 0x8087, \ + "cs_gain" }, /* Current sense gain , */ \ + { 0x8210, \ + "invertpwm" }, /* Current sense common mode feedback pwm invert control, */ \ + { 0x8305, \ + "cs_ktemp" }, /* Current sense temperature compensation trimming (1 - VALUE*TEMP)*signal, */ \ + { 0x8364, \ + "cs_ktemp2" }, /* Second order temperature compensation coefficient , */ \ + { 0x8400, \ + "cs_adc_bsoinv" }, /* Bitstream inversion for current sense ADC , */ \ + { 0x8421, \ + "cs_adc_hifreq" }, /* Frequency mode current sense ADC , */ \ + { 0x8440, \ + "cs_adc_nortz" }, /* Return to zero for current sense ADC , */ \ + { 0x8453, \ + "cs_adc_offset" }, /* Micadc ADC offset setting , */ \ + { 0x8490, \ + "cs_adc_slowdel" }, /* Select delay for current sense ADC (internal decision circuitry), */ \ + { 0x84a4, \ + "cs_adc_gain" }, /* Gain setting for current sense ADC (two's complement), */ \ + { 0x8500, \ + "cs_resonator_enable" }, /* Enable for resonator to improve SRN , */ \ + { 0x8510, \ + "cs_classd_tran_skip" }, /* Skip current sense connection during a classD amplifier transition, */ \ + { 0x8530, \ + "cs_inn_short" }, /* Short current sense negative to common mode , */ \ + { 0x8540, \ + "cs_inp_short" }, /* Short current sense positive to common mode , */ \ + { 0x8550, \ + "cs_ldo_bypass" }, /* Bypass current sense LDO , */ \ + { 0x8560, \ + "cs_ldo_pulldown" }, /* Pull down current sense LDO, only valid if left_enbl_cs_ldo is high, */ \ + { 0x8574, \ + "cs_ldo_voset" }, /* Current sense LDO voltage level setting (two's complement), */ \ + { 0x8700, \ + "enbl_cs_adc" }, /* Enable current sense ADC , */ \ + { 0x8710, \ + "enbl_cs_inn1" }, /* Enable connection of current sense negative1 , */ \ + { 0x8720, \ + "enbl_cs_inn2" }, /* Enable connection of current sense negative2 , */ \ + { 0x8730, \ + "enbl_cs_inp1" }, /* Enable connection of current sense positive1 , */ \ + { 0x8740, \ + "enbl_cs_inp2" }, /* Enable connection of current sense positive2 , */ \ + { 0x8750, \ + "enbl_cs_ldo" }, /* Enable current sense LDO , */ \ + { 0x8780, \ + "enbl_cs_vbatldo" }, /* Enable of current sense LDO , */ \ + { 0x8790, \ + "enbl_dc_filter" }, /* Control for enabling the DC blocking filter for voltage and current sense, */ \ + { 0x8801, \ + "volsense_pwm_sel" }, /* Voltage sense source selection control , */ \ + { 0x8850, \ + "vs_gain_control" }, /* Voltage sense gain control , */ \ + { 0x8860, \ + "vs_bypass_gc" }, /* Bypasses the VS gain correction , */ \ + { 0x8870, \ + "vs_igen_supply" }, /* Switch internal supply of current generator , */ \ + { 0x8887, \ + "vs_gain" }, /* voltage sense gain , */ \ + { 0x8c00, \ + "vs_adc_bsoinv" }, /* Bitstream inversion for voltage sense ADC , */ \ + { 0x8c40, \ + "vs_adc_nortz" }, /* Return to zero for voltage sense ADC , */ \ + { 0x8c90, \ + "vs_adc_slowdel" }, /* Select delay for voltage sense ADC (internal decision circuitry), */ \ + { 0x8d10, \ + "vs_classd_tran_skip" }, /* Skip voltage sense connection during a classD amplifier transition, */ \ + { 0x8d30, \ + "vs_inn_short" }, /* Short voltage sense negative to common mode , */ \ + { 0x8d40, \ + "vs_inp_short" }, /* Short voltage sense positive to common mode , */ \ + { 0x8d50, \ + "vs_ldo_bypass" }, /* Bypass voltage sense LDO , */ \ + { 0x8d60, \ + "vs_ldo_pulldown" }, /* Pull down voltage sense LDO, only valid if left_enbl_cs_ldo is high, */ \ + { 0x8d74, \ + "vs_ldo_voset" }, /* Voltage sense LDO voltage level setting (two's complement), */ \ + { 0x8f00, \ + "enbl_vs_adc" }, /* Enable voltage sense ADC (Direct Control only only others done by manager), */ \ + { 0x8f10, \ + "enbl_vs_inn1" }, /* Enable connection of voltage sense negative1 , */ \ + { 0x8f20, \ + "enbl_vs_inn2" }, /* Enable connection of voltage sense negative2 , */ \ + { 0x8f30, \ + "enbl_vs_inp1" }, /* Enable connection of voltage sense positive1 , */ \ + { 0x8f40, \ + "enbl_vs_inp2" }, /* Enable connection of voltage sense positive2 , */ \ + { 0x8f50, \ + "enbl_vs_ldo" }, /* Enable voltage sense LDO (Direct Control only only others done by manager), */ \ + { 0x8f80, \ + "enbl_vs_vbatldo" }, /* Enable of voltage sense LDO (Direct Control only others done by manager), */ \ + { 0xa007, \ + "mtpkey1" }, /* 5Ah, 90d To access KEY1_Protected registers (Default for engineering), */ \ + { 0xa107, \ + "mtpkey2" }, /* MTP KEY2 register , */ \ + { 0xa200, \ + "key01_locked" }, /* Indicates KEY1 is locked , */ \ + { 0xa210, \ + "key02_locked" }, /* Indicates KEY2 is locked , */ \ + { 0xa302, \ + "mtp_man_address_in" }, /* MTP address from I2C register for read/writing mtp in manual single word mode, */ \ + { 0xa330, \ + "man_copy_mtp_to_iic" }, /* Start copying single word from mtp to I2C mtp register, */ \ + { 0xa340, \ + "man_copy_iic_to_mtp" }, /* Start copying single word from I2C mtp register to mtp, */ \ + { 0xa350, \ + "auto_copy_mtp_to_iic" }, /* Start copying all the data from mtp to I2C mtp registers, */ \ + { 0xa360, \ + "auto_copy_iic_to_mtp" }, /* Start copying data from I2C mtp registers to mtp , */ \ + { 0xa400, \ + "faim_set_clkws" }, /* Sets the faim controller clock wait state register, */ \ + { 0xa410, \ + "faim_sel_evenrows" }, /* All even rows of the faim are selected, active high, */ \ + { 0xa420, \ + "faim_sel_oddrows" }, /* All odd rows of the faim are selected, all rows in combination with sel_evenrows, */ \ + { 0xa430, \ + "faim_program_only" }, /* Skip the erase access at wr_faim command (write-program-marginread), */ \ + { 0xa440, \ + "faim_erase_only" }, /* Skip the program access at wr_faim command (write-erase-marginread), */ \ + { 0xa50f, \ + "mtp_man_data_out_msb" }, /* MSB word of MTP manual read data , */ \ + { 0xa60f, \ + "mtp_man_data_out_lsb" }, /* LSB word of MTP manual read data , */ \ + { 0xa70f, \ + "mtp_man_data_in_msb" }, /* MSB word of write data for MTP manual write , */ \ + { 0xa80f, \ + "mtp_man_data_in_lsb" }, /* LSB word of write data for MTP manual write , */ \ + { 0xb010, \ + "bypass_ocpcounter" }, /* Bypass OCP Counter , */ \ + { 0xb020, \ + "bypass_glitchfilter" }, /* Bypass glitch filter , */ \ + { 0xb030, \ + "bypass_ovp" }, /* Bypass OVP , */ \ + { 0xb040, \ + "bypass_uvp" }, /* Bypass UVP , */ \ + { 0xb050, \ + "bypass_otp" }, /* Bypass OTP , */ \ + { 0xb060, \ + "bypass_lost_clk" }, /* Bypass lost clock detector , */ \ + { 0xb070, \ + "ctrl_vpalarm" }, /* vpalarm (uvp ovp handling) , */ \ + { 0xb087, \ + "ocp_threshold" }, /* OCP threshold level , */ \ + { 0xb108, \ + "ext_temp" }, /* External temperature (C) , */ \ + { 0xb190, \ + "ext_temp_sel" }, /* Select temp Speaker calibration , */ \ + { 0xc000, \ + "use_direct_ctrls" }, /* Direct control to overrule several functions for testing, */ \ + { 0xc010, \ + "rst_datapath" }, /* Direct control for datapath reset , */ \ + { 0xc020, \ + "rst_cgu" }, /* Direct control for cgu reset , */ \ + { 0xc038, \ + "enbl_ref" }, /* Switch on the analog references, each part of the references can be switched on/off individually, */ \ + { 0xc0c0, \ + "use_direct_vs_ctrls" }, /* voltage sense Direct control to overrule several functions for testing, */ \ + { 0xc0d0, \ + "enbl_ringo" }, /* Enable the ring oscillator for test purpose , */ \ + { 0xc0e0, \ + "use_direct_clk_ctrl" }, /* Direct clock control to overrule several functions for testing, */ \ + { 0xc0f0, \ + "use_direct_pll_ctrl" }, /* Direct PLL control to overrule several functions for testing, */ \ + { 0xc100, \ + "enbl_tsense" }, /* Temperature sensor enable control - I2C direct mode, */ \ + { 0xc110, \ + "tsense_hibias" }, /* Bit to set the biasing in temp sensor to high , */ \ + { 0xc120, \ + "enbl_flag_vbg" }, /* Enable flagging of bandgap out of control , */ \ + { 0xc20f, \ + "abist_offset" }, /* Offset control for ABIST testing (two's complement), */ \ + { 0xc300, \ + "bypasslatch" }, /* Bypass latch , */ \ + { 0xc311, \ + "sourcea" }, /* Set OUTA to , */ \ + { 0xc331, \ + "sourceb" }, /* Set OUTB to , */ \ + { 0xc350, \ + "inverta" }, /* Invert pwma test signal , */ \ + { 0xc360, \ + "invertb" }, /* Invert pwmb test signal , */ \ + { 0xc374, \ + "pulselength" }, /* Pulse length setting test input for amplifier (clock d - k*2048*fs), */ \ + { 0xc3c0, \ + "tdm_enable_loopback" }, /* TDM loopback test , */ \ + { 0xc400, \ + "bst_bypasslatch" }, /* Bypass latch in boost converter , */ \ + { 0xc411, \ + "bst_source" }, /* Sets the source of the pwmbst output to boost converter input for testing, */ \ + { 0xc430, \ + "bst_invertb" }, /* Invert pwmbst test signal , */ \ + { 0xc444, \ + "bst_pulselength" }, /* Pulse length setting test input for boost converter , */ \ + { 0xc490, \ + "test_bst_ctrlsthv" }, /* Test mode for boost control stage , */ \ + { 0xc4a0, \ + "test_bst_iddq" }, /* IDDQ testing in power stage of boost converter , */ \ + { 0xc4b0, \ + "test_bst_rdson" }, /* RDSON testing - boost power stage , */ \ + { 0xc4c0, \ + "test_bst_cvi" }, /* CVI testing - boost power stage , */ \ + { 0xc4d0, \ + "test_bst_ocp" }, /* Boost OCP. For old ocp (ctrl_reversebst is 0), For new ocp (ctrl_reversebst is 1), */ \ + { 0xc4e0, \ + "test_bst_sense" }, /* Test option for the sense NMOS in booster for current mode control., */ \ + { 0xc500, \ + "test_cvi" }, /* Analog BIST, switch choose which transistor will be used as current source (also cross coupled sources possible), */ \ + { 0xc510, \ + "test_discrete" }, /* Test function noise measurement , */ \ + { 0xc520, \ + "test_iddq" }, /* Set the power stages in iddq mode for gate stress., */ \ + { 0xc540, \ + "test_rdson" }, /* Analog BIST, switch to enable Rdson measurement , */ \ + { 0xc550, \ + "test_sdelta" }, /* Analog BIST, noise test , */ \ + { 0xc570, \ + "test_enbl_cs" }, /* Enable for digimux mode of current sense , */ \ + { 0xc580, \ + "test_enbl_vs" }, /* Enable for digimux mode of voltage sense , */ \ + { 0xc600, \ + "enbl_pwm_dcc" }, /* Enables direct control of pwm duty cycle for DCDC power stage, */ \ + { 0xc613, \ + "pwm_dcc_cnt" }, /* Control pwm duty cycle when enbl_pwm_dcc is 1 , */ \ + { 0xc650, \ + "enbl_ldo_stress" }, /* Enable stress of internal supply voltages powerstages, */ \ + { 0xc707, \ + "digimuxa_sel" }, /* DigimuxA input selection control routed to DATAO (see Digimux list for details), */ \ + { 0xc787, \ + "digimuxb_sel" }, /* DigimuxB input selection control routed to INT (see Digimux list for details), */ \ + { 0xc807, \ + "digimuxc_sel" }, /* DigimuxC input selection control routed to PDMDAT (see Digimux list for details), */ \ + { 0xc981, \ + "int_ehs" }, /* Speed/load setting for INT IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc9c0, \ + "hs_mode" }, /* I2C high speed mode control , */ \ + { 0xca00, \ + "enbl_anamux1" }, /* Enable anamux1 , */ \ + { 0xca10, \ + "enbl_anamux2" }, /* Enable anamux2 , */ \ + { 0xca20, \ + "enbl_anamux3" }, /* Enable anamux3 , */ \ + { 0xca30, \ + "enbl_anamux4" }, /* Enable anamux4 , */ \ + { 0xca74, \ + "anamux1" }, /* Anamux selection control - anamux on TEST1 , */ \ + { 0xcb04, \ + "anamux2" }, /* Anamux selection control - anamux on TEST2 , */ \ + { 0xcb53, \ + "anamux3" }, /* Anamux selection control - anamux on TEST3 , */ \ + { 0xcba3, \ + "anamux4" }, /* Anamux selection control - anamux on TEST4 , */ \ + { 0xcd05, \ + "pll_seli" }, /* PLL SELI - I2C direct PLL control mode only , */ \ + { 0xcd64, \ + "pll_selp" }, /* PLL SELP - I2C direct PLL control mode only , */ \ + { 0xcdb3, \ + "pll_selr" }, /* PLL SELR - I2C direct PLL control mode only , */ \ + { 0xcdf0, \ + "pll_frm" }, /* PLL free running mode control; 1 in TCB direct control mode, else this control bit, */ \ + { 0xce09, \ + "pll_ndec" }, /* PLL NDEC - I2C direct PLL control mode only , */ \ + { 0xcea0, \ + "pll_mdec_msb" }, /* MSB of pll_mdec - I2C direct PLL control mode only, */ \ + { 0xceb0, \ + "enbl_pll" }, /* Enables PLL in I2C direct PLL control mode only , */ \ + { 0xcec0, \ + "enbl_osc" }, /* Enables OSC1M in I2C direct control mode only , */ \ + { 0xced0, \ + "pll_bypass" }, /* PLL bypass control in I2C direct PLL control mode only, */ \ + { 0xcee0, \ + "pll_directi" }, /* PLL directi control in I2C direct PLL control mode only, */ \ + { 0xcef0, \ + "pll_directo" }, /* PLL directo control in I2C direct PLL control mode only, */ \ + { 0xcf0f, \ + "pll_mdec_lsb" }, /* Bits 15..0 of PLL MDEC are I2C direct PLL control mode only, */ \ + { 0xd006, \ + "pll_pdec" }, /* PLL PDEC - I2C direct PLL control mode only , */ \ + { 0xd10f, \ + "tsig_freq_lsb" }, /* Internal sinus test generator frequency control , */ \ + { 0xd202, \ + "tsig_freq_msb" }, /* Select internal sinus test generator, frequency control msb bits, */ \ + { 0xd230, \ + "inject_tsig" }, /* Control bit to switch to internal sinus test generator, */ \ + { 0xd283, \ + "tsig_gain" }, /* Test signal gain , */ \ + { 0xd300, \ + "adc10_reset" }, /* Reset for ADC10 - I2C direct control mode , */ \ + { 0xd311, \ + "adc10_test" }, /* Test mode selection signal for ADC10 - I2C direct control mode, */ \ + { 0xd332, \ + "adc10_sel" }, /* Select the input to convert for ADC10 - I2C direct control mode, */ \ + { 0xd364, \ + "adc10_prog_sample" }, /* ADC10 program sample setting - I2C direct control mode, */ \ + { 0xd3b0, \ + "adc10_enbl" }, /* Enable ADC10 - I2C direct control mode , */ \ + { 0xd3c0, \ + "bypass_lp_vbat" }, /* Bypass control for Low pass filter in batt sensor , */ \ + { 0xd409, \ + "data_adc10_tempbat" }, /* ADC 10 data output data for testing , */ \ + { 0xd507, \ + "ctrl_digtoana_hidden" }, /* Spare digital to analog control bits - Hidden , */ \ + { 0xd580, \ + "enbl_clk_out_of_range" }, /* Clock out of range , */ \ + { 0xd621, \ + "clkdiv_audio_sel" }, /* Audio clock divider selection in direct clock control mode, */ \ + { 0xd641, \ + "clkdiv_muxa_sel" }, /* DCDC MUXA clock divider selection in direct clock control mode, */ \ + { 0xd661, \ + "clkdiv_muxb_sel" }, /* DCDC MUXB clock divider selection in direct clock control mode, */ \ + { 0xd721, \ + "datao_ehs" }, /* Speed/load setting for DATAO IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xd740, \ + "bck_ehs" }, /* High-speed and standard/fast mode selection for BCK IO cell (see IIC3V3 IO cell datasheet), */ \ + { 0xd750, \ + "datai_ehs" }, /* High-speed and standard/fast mode selection for DATAI IO cell (see IIC3V3 IO cell datasheet), */ \ + { 0xd800, \ + "source_in_testmode" }, /* tdm source in test mode (return only current and voltage sense), */ \ + { 0xd810, \ + "gainatt_feedback" }, /* gainatt feedback to tdm , */ \ + { 0xd822, \ + "test_parametric_io" }, /* test io parametric , */ \ + { 0xd850, \ + "ctrl_bst_clk_lp1" }, /* boost clock control in low power mode1 , */ \ + { 0xd861, \ + "test_spare_out1" }, /* test spare out 1 , */ \ + { 0xd880, \ + "bst_dcmbst" }, /* dcm boost , */ \ + { 0xd8c3, \ + "test_spare_out2" }, /* test spare out 1 , */ \ + { 0xee0f, \ + "sw_profile" }, /* Software profile data , */ \ + { 0xef0f, \ + "sw_vstep" }, /* Software vstep information , */ \ + { 0xf000, \ + "calibration_onetime" }, /* Calibration schedule , */ \ + { 0xf010, \ + "calibr_ron_done" }, /* Calibration Ron executed , */ \ + { 0xf020, \ + "calibr_dcdc_api_calibrate" }, /* Calibration current limit DCDC , */ \ + { 0xf030, \ + "calibr_dcdc_delta_sign" }, /* Sign bit for delta calibration current limit DCDC , */ \ + { 0xf042, \ + "calibr_dcdc_delta" }, /* Calibration delta current limit DCDC , */ \ + { 0xf078, \ + "calibr_speaker_info" }, /* Reserved space for allowing customer to store speaker information, */ \ + { 0xf105, \ + "calibr_vout_offset" }, /* DCDC offset calibration 2's complement (key1 protected), */ \ + { 0xf169, \ + "spare_mpt1_15_6" }, /* SPARE , */ \ + { 0xf203, \ + "calibr_gain" }, /* HW gain module (2's complement) , */ \ + { 0xf245, \ + "calibr_offset" }, /* Offset for amplifier, HW gain module (2's complement), */ \ + { 0xf2a5, \ + "spare_mtp2_15_10" }, /* SPARE , */ \ + { 0xf307, \ + "calibr_gain_vs" }, /* Voltage sense gain , */ \ + { 0xf387, \ + "calibr_gain_cs" }, /* Current sense gain (signed two's complement format), */ \ + { 0xf407, \ + "spare_mtp4_15_0" }, /* SPARE , */ \ + { 0xf487, \ + "vs_trim" }, /* VS Trimming , */ \ + { 0xf50f, \ + "calibr_R25C_R" }, /* Ron resistance of speaker coil , */ \ + { 0xf60f, \ + "spare_mpt6_6_0" }, /* SPARE , */ \ + { 0xf706, \ + "ctrl_offset_a" }, /* Offset of level shifter A , */ \ + { 0xf770, \ + "spare_mtp7_07" }, /* SPARE , */ \ + { 0xf786, \ + "ctrl_offset_b" }, /* Offset of amplifier level shifter B , */ \ + { 0xf7f0, \ + "spare_mtp7_15" }, /* SPARE , */ \ + { 0xf806, \ + "htol_iic_addr" }, /* 7-bit I2C address to be used during HTOL testing , */ \ + { 0xf870, \ + "htol_iic_addr_en" }, /* HTOL I2C address enable control , */ \ + { 0xf884, \ + "calibr_temp_offset" }, /* Temperature offset 2's compliment (key1 protected), */ \ + { 0xf8d2, \ + "calibr_temp_gain" }, /* Temperature gain 2's compliment (key1 protected) , */ \ + { 0xf900, \ + "mtp_lock_dcdcoff_mode" }, /* Disable function dcdcoff_mode , */ \ + { 0xf910, \ + "spare_mtp9_1" }, /* SPARE , */ \ + { 0xf920, \ + "mtp_lock_bypass_clipper" }, /* Disable function bypass_clipper , */ \ + { 0xf930, \ + "mtp_lock_max_dcdc_voltage" }, /* Force Boost in follower mode , */ \ + { 0xf943, \ + "calibr_vbg_trim" }, /* Bandgap trimming control , */ \ + { 0xf980, \ + "spare_mtp9_8" }, /* SPARE , */ \ + { 0xf990, \ + "mtp_enbl_pwm_delay_clock_gating" }, /* pwm delay clock auto gating , */ \ + { 0xf9a0, \ + "mtp_enbl_ocp_clock_gating" }, /* ocpclock auto gating , */ \ + { 0xf9b0, \ + "mtp_gate_cgu_clock_for_test" }, /* cgu test clock control , */ \ + { 0xf9c0, \ + "mtp_tdm_pad_sel" }, /* tdm pad selection , */ \ + { 0xf9d2, \ + "spare_mtp9_15_12" }, /* MTP-control FW - See Firmware I2C API document for details, */ \ + { 0xfa0f, \ + "mtpdataA" }, /* MTPdataA (key1 protected) , */ \ + { 0xfb0f, \ + "mtpdataB" }, /* MTPdataB (key1 protected) , */ \ + { 0xfc0f, \ + "mtpdataC" }, /* MTPdataC (key1 protected) , */ \ + { 0xfd0f, \ + "mtpdataD" }, /* MTPdataD (key1 protected) , */ \ + { 0xfe0f, \ + "mtpdataE" }, /* MTPdataE (key1 protected) , */ \ + { 0xff07, \ + "calibr_osc_delta_ndiv" }, /* Calibration data for OSC1M, signed number representation, */ \ + { 0xff87, \ + "spare_mtp7_15_08" }, /* SPARE , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +enum tfa9874_irq { + tfa9874_irq_stvdds = 0, + tfa9874_irq_stbstoc = 1, + tfa9874_irq_stotds = 2, + tfa9874_irq_stocpr = 3, + tfa9874_irq_stuvds = 4, + tfa9874_irq_stmanalarm = 5, + tfa9874_irq_sttdmer = 6, + tfa9874_irq_stnoclk = 7, + tfa9874_irq_max = 8, + tfa9874_irq_all = -1 /* all irqs */ +}; + +#define TFA9874_IRQ_NAMETABLE \ + static tfaIrqName_t Tfa9874IrqNames[] = { \ + { 0, "STVDDS" }, { 1, "STBSTOC" }, { 2, "STOTDS" }, \ + { 3, "STOCPR" }, { 4, "STUVDS" }, { 5, "STMANALARM" }, \ + { 6, "STTDMER" }, { 7, "STNOCLK" }, { 8, "8" }, \ + }; +#endif /* _TFA9874_TFAFIELDNAMES_H */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9887_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9887_tfafieldnames.h new file mode 100644 index 000000000000..1451bb4edabe --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9887_tfafieldnames.h @@ -0,0 +1,109 @@ +/** Filename: Tfa9887_TfaFieldnames.h + * This file was generated automatically on 04/14/15 at 10:23:40. + * Source file: TFA9897N1B_I2C_list_URT_source_v34_87Only.xls + */ +#define TFA9887_I2CVERSION 34 +#define TFA9895_I2CVERSION 34 +#define TFA9887_NAMETABLE \ + static tfaBfName_t Tfa9887DatasheetNames[] = { \ + { 0x402, \ + "I2SF" }, /* I2SFormat data 1 input: , */ \ + { 0x431, \ + "CHS12" }, /* ChannelSelection data1 input (In CoolFlux) , */ \ + { 0x450, \ + "CHS3" }, /* ChannelSelection data 2 input (coolflux input, the DCDC converter gets the other signal), */ \ + { 0x461, \ + "CHSA" }, /* Input selection for amplifier , */ \ + { 0x4b0, \ + "I2SDOE" }, /* Enable data output , */ \ + { 0x4c3, \ + "I2SSR" }, /* sample rate setting , */ \ + { 0x500, \ + "BSSBY" }, /* , */ \ + { 0x511, \ + "BSSCR" }, /* 00 = 0.56 dB/Sample , */ \ + { 0x532, \ + "BSST" }, /* 000 = 2.92V , */ \ + { 0x5f0, \ + "I2SDOC" }, /* selection data out , */ \ + { 0xa02, \ + "DOLS" }, /* Output selection dataout left channel , */ \ + { 0xa32, \ + "DORS" }, /* Output selection dataout right channel , */ \ + { 0xa62, \ + "SPKL" }, /* Selection speaker induction , */ \ + { 0xa91, \ + "SPKR" }, /* Selection speaker impedance , */ \ + { 0xab3, \ + "DCFG" }, /* DCDC speaker current compensation gain , */ \ + { 0x4134, \ + "PWMDEL" }, /* PWM DelayBits to set the delay , */ \ + { 0x4180, \ + "PWMSH" }, /* PWM Shape , */ \ + { 0x4190, \ + "PWMRE" }, /* PWM Bitlength in noise shaper , */ \ + { 0x48e1, \ + "TCC" }, /* sample & hold track time: , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +#define TFA9887_BITNAMETABLE \ + static tfaBfName_t Tfa9887BitNames[] = { \ + { 0x402, \ + "i2s_seti" }, /* I2SFormat data 1 input: , */ \ + { 0x431, \ + "chan_sel1" }, /* ChannelSelection data1 input (In CoolFlux) , */ \ + { 0x450, \ + "lr_sw_i2si2" }, /* ChannelSelection data 2 input (coolflux input, the DCDC converter gets the other signal), */ \ + { 0x461, \ + "input_sel" }, /* Input selection for amplifier , */ \ + { 0x4b0, \ + "enbl_datao" }, /* Enable data output , */ \ + { 0x4c3, \ + "i2s_fs" }, /* sample rate setting , */ \ + { 0x500, \ + "bypass_clipper" }, /* , */ \ + { 0x511, \ + "vbat_prot_attacktime[1:0]" }, /* 00 = 0.56 dB/Sample , */ \ + { 0x532, \ + "vbat_prot_thlevel[2:0]" }, /* 000 = 2.92V , */ \ + { 0x5d0, \ + "reset_min_vbat" }, /* to reset the clipper via I2C in case the CF is bypassed, */ \ + { 0x5f0, \ + "datao_sel" }, /* selection data out , */ \ + { 0xa02, \ + "sel_i2so_l" }, /* Output selection dataout left channel , */ \ + { 0xa32, \ + "sel_i2so_r" }, /* Output selection dataout right channel , */ \ + { 0xa62, \ + "ctrl_spkr_coil" }, /* Selection speaker induction , */ \ + { 0xa91, \ + "ctrl_spr_res" }, /* Selection speaker impedance , */ \ + { 0xab3, \ + "ctrl_dcdc_spkr_i_comp_gain" }, /* DCDC speaker current compensation gain , */ \ + { 0xaf0, \ + "ctrl_dcdc_spkr_i_comp_sign" }, /* DCDC speaker current compensation sign , */ \ + { 0x4100, \ + "bypass_hp" }, /* bypass_hp, to bypass the hp filter byhind the CoolFlux, */ \ + { 0x4110, \ + "hard_mute" }, /* hard mute setting in HW , */ \ + { 0x4120, \ + "soft_mute" }, /* Soft mute setting in HW , */ \ + { 0x4134, \ + "PWM_Delay[4:0]" }, /* PWM DelayBits to set the delay , */ \ + { 0x4180, \ + "PWM_Shape" }, /* PWM Shape , */ \ + { 0x4190, \ + "PWM_BitLength" }, /* PWM Bitlength in noise shaper , */ \ + { 0x4800, \ + "ctrl_negin" }, /* , */ \ + { 0x4810, \ + "ctrl_cs_sein" }, /* , */ \ + { 0x4820, \ + "ctrl_coincidencecs" }, /* HIGH => Prevent dcdc switching during clk_cs_clksh, */ \ + { 0x4876, \ + "delay_se_neg[6:0]" }, /* delayshiftse2 , */ \ + { 0x48e1, \ + "ctrl_cs_ttrack[1:0]" }, /* sample & hold track time: , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9890_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9890_tfafieldnames.h new file mode 100644 index 000000000000..baf247451dcd --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9890_tfafieldnames.h @@ -0,0 +1,140 @@ +/** Filename: Tfa9890_TfaFieldnames.h + * This file was generated automatically on 04/07/15 at 14:46:37. + * Source file: TFA9897N1B_I2C_list_URT_source_v34_90Only.xls + */ +#define TFA9890_I2CVERSION 34 +#define TFA9890_NAMETABLE \ + static tfaBfName_t Tfa9890DatasheetNames[] = { \ + { 0x402, \ + "I2SF" }, /* I2SFormat data 1 input: , */ \ + { 0x431, \ + "CHS12" }, /* ChannelSelection data1 input (In CoolFlux) , */ \ + { 0x450, \ + "CHS3" }, /* ChannelSelection data 2 input (coolflux input, the DCDC converter gets the other signal), */ \ + { 0x461, \ + "CHSA" }, /* Input selection for amplifier , */ \ + { 0x481, \ + "I2SDOC" }, /* selection data out , */ \ + { 0x4a0, \ + "DISP" }, /* idp protection , */ \ + { 0x4b0, \ + "I2SDOE" }, /* Enable data output , */ \ + { 0x4c3, \ + "I2SSR" }, /* sample rate setting , */ \ + { 0x732, \ + "DCMCC" }, /* Max boost coil current - step of 500 mA , */ \ + { 0x9c0, \ + "CCFD" }, /* Selection CoolFlux Clock , */ \ + { 0x9d0, \ + "ISEL" }, /* selection input 1 or 2 , */ \ + { 0xa02, \ + "DOLS" }, /* Output selection dataout left channel , */ \ + { 0xa32, \ + "DORS" }, /* Output selection dataout right channel , */ \ + { 0xa62, \ + "SPKL" }, /* Selection speaker induction , */ \ + { 0xa91, \ + "SPKR" }, /* Selection speaker impedance , */ \ + { 0xab3, \ + "DCFG" }, /* DCDC speaker current compensation gain , */ \ + { 0xf00, \ + "VDDD" }, /* mask flag_por for interupt generation , */ \ + { 0xf10, \ + "OTDD" }, /* mask flag_otpok for interupt generation , */ \ + { 0xf20, \ + "OVDD" }, /* mask flag_ovpok for interupt generation , */ \ + { 0xf30, \ + "UVDD" }, /* mask flag_uvpok for interupt generation , */ \ + { 0xf40, \ + "OCDD" }, /* mask flag_ocp_alarm for interupt generation , */ \ + { 0xf50, \ + "CLKD" }, /* mask flag_clocks_stable for interupt generation , */ \ + { 0xf60, \ + "DCCD" }, /* mask flag_pwrokbst for interupt generation , */ \ + { 0xf70, \ + "SPKD" }, /* mask flag_cf_speakererror for interupt generation , */ \ + { 0xf80, \ + "WDD" }, /* mask flag_watchdog_reset for interupt generation , */ \ + { 0xf90, \ + "LCLK" }, /* mask flag_lost_clk for interupt generation , */ \ + { 0xfe0, \ + "INT" }, /* enabling interrupt , */ \ + { 0xff0, \ + "INTP" }, /* Setting polarity interupt , */ \ + { 0x8f0f, \ + "VERSION" }, /* (key1 protected) , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +#define TFA9890_BITNAMETABLE \ + static tfaBfName_t Tfa9890BitNames[] = { \ + { 0x402, \ + "i2s_seti" }, /* I2SFormat data 1 input: , */ \ + { 0x431, \ + "chan_sel1" }, /* ChannelSelection data1 input (In CoolFlux) , */ \ + { 0x450, \ + "lr_sw_i2si2" }, /* ChannelSelection data 2 input (coolflux input, the DCDC converter gets the other signal), */ \ + { 0x461, \ + "input_sel" }, /* Input selection for amplifier , */ \ + { 0x481, \ + "datao_sel" }, /* selection data out , */ \ + { 0x4a0, \ + "disable_idp" }, /* idp protection , */ \ + { 0x4b0, \ + "enbl_datao" }, /* Enable data output , */ \ + { 0x4c3, \ + "i2s_fs" }, /* sample rate setting , */ \ + { 0x732, \ + "ctrl_bstcur" }, /* Max boost coil current - step of 500 mA , */ \ + { 0x9c0, \ + "sel_cf_clk" }, /* Selection CoolFlux Clock , */ \ + { 0x9d0, \ + "intf_sel" }, /* selection input 1 or 2 , */ \ + { 0xa02, \ + "sel_i2so_l" }, /* Output selection dataout left channel , */ \ + { 0xa32, \ + "sel_i2so_r" }, /* Output selection dataout right channel , */ \ + { 0xa62, \ + "ctrl_spkr_coil" }, /* Selection speaker induction , */ \ + { 0xa91, \ + "ctrl_spr_res" }, /* Selection speaker impedance , */ \ + { 0xab3, \ + "ctrl_dcdc_spkr_i_comp_gain" }, /* DCDC speaker current compensation gain , */ \ + { 0xaf0, \ + "ctrl_dcdc_spkr_i_comp_sign" }, /* DCDC speaker current compensation sign , */ \ + { 0xf00, \ + "flag_por_mask" }, /* mask flag_por for interupt generation , */ \ + { 0xf10, \ + "flag_otpok_mask" }, /* mask flag_otpok for interupt generation , */ \ + { 0xf20, \ + "flag_ovpok_mask" }, /* mask flag_ovpok for interupt generation , */ \ + { 0xf30, \ + "flag_uvpok_mask" }, /* mask flag_uvpok for interupt generation , */ \ + { 0xf40, \ + "flag_ocp_alarm_mask" }, /* mask flag_ocp_alarm for interupt generation , */ \ + { 0xf50, \ + "flag_clocks_stable_mask" }, /* mask flag_clocks_stable for interupt generation , */ \ + { 0xf60, \ + "flag_pwrokbst_mask" }, /* mask flag_pwrokbst for interupt generation , */ \ + { 0xf70, \ + "flag_cf_speakererror_mask" }, /* mask flag_cf_speakererror for interupt generation , */ \ + { 0xf80, \ + "flag_watchdog_reset_mask" }, /* mask flag_watchdog_reset for interupt generation , */ \ + { 0xf90, \ + "flag_lost_clk_mask" }, /* mask flag_lost_clk for interupt generation , */ \ + { 0xfe0, \ + "enable_interrupt" }, /* enabling interrupt , */ \ + { 0xff0, \ + "invert_int_polarity" }, /* Setting polarity interupt , */ \ + { 0x4700, \ + "switch_fb" }, /* switch_fb , */ \ + { 0x4713, \ + "se_hyst" }, /* se_hyst , */ \ + { 0x4754, \ + "se_level" }, /* se_level , */ \ + { 0x47a5, \ + "ktemp" }, /* temperature compensation trimming , */ \ + { 0x8f0f, \ + "production_data6" }, /* (key1 protected) , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9891_genregs.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9891_genregs.h new file mode 100644 index 000000000000..3b3ffb9b9bff --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9891_genregs.h @@ -0,0 +1,1099 @@ +/** Filename: Tfa98xx_genregs.h + * This file was generated automatically on 07/01/15 at 10:25:08. + * Source file: TFA9891_I2C_list_V11.xls + */ + +#ifndef TFA9891_GENREGS_H +#define TFA9891_GENREGS_H + +#define TFA98XX_STATUSREG 0x00 +#define TFA98XX_BATTERYVOLTAGE 0x01 +#define TFA9891_TEMPERATURE 0x02 +#define TFA98XX_REVISIONNUMBER 0x03 +#define TFA98XX_I2SREG 0x04 +#define TFA98XX_BAT_PROT 0x05 +#define TFA98XX_AUDIO_CTR 0x06 +#define TFA98XX_DCDCBOOST 0x07 +#define TFA98XX_SPKR_CALIBRATION 0x08 +#define TFA98XX_SYS_CTRL 0x09 +#define TFA98XX_I2S_SEL_REG 0x0a +#define TFA98XX_HIDDEN_MTP_KEY2 0x0b +#define TFA98XX_INTERRUPT_REG 0x0f +#define TFA98XX_PDM_CTRL 0x10 +#define TFA98XX_PDM_OUT_CTRL 0x11 +#define TFA98XX_PDM_DS4_R 0x12 +#define TFA98XX_PDM_DS4_L 0x13 +#define TFA98XX_CTRL_SAAM_PGA 0x22 +#define TFA98XX_MISC_CTRL 0x25 +#define TFA98XX_CURRENTSENSE1 0x46 +#define TFA98XX_CURRENTSENSE4 0x49 +#define TFA98XX_HIDDEN_MTP_CTRL_REG3 0x62 +#define TFA9891_CF_CONTROLS 0x70 +#define TFA9891_CF_MAD 0x71 +#define TFA9891_CF_MEM 0x72 +#define TFA9891_CF_STATUS 0x73 +#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP 0x80 + +/* + * (0x00)-StatusReg + */ + +/* + * POR + */ +#define TFA98XX_STATUSREG_VDDS (0x1 << 0) +#define TFA98XX_STATUSREG_VDDS_POS 0 +#define TFA98XX_STATUSREG_VDDS_LEN 1 +#define TFA98XX_STATUSREG_VDDS_MAX 1 +#define TFA98XX_STATUSREG_VDDS_MSK 0x1 + +/* + * PLL_LOCK + */ +#define TFA98XX_STATUSREG_PLLS (0x1 << 1) +#define TFA98XX_STATUSREG_PLLS_POS 1 +#define TFA98XX_STATUSREG_PLLS_LEN 1 +#define TFA98XX_STATUSREG_PLLS_MAX 1 +#define TFA98XX_STATUSREG_PLLS_MSK 0x2 + +/* + * flag_otpok + */ +#define TFA98XX_STATUSREG_OTDS (0x1 << 2) +#define TFA98XX_STATUSREG_OTDS_POS 2 +#define TFA98XX_STATUSREG_OTDS_LEN 1 +#define TFA98XX_STATUSREG_OTDS_MAX 1 +#define TFA98XX_STATUSREG_OTDS_MSK 0x4 + +/* + * flag_ovpok + */ +#define TFA98XX_STATUSREG_OVDS (0x1 << 3) +#define TFA98XX_STATUSREG_OVDS_POS 3 +#define TFA98XX_STATUSREG_OVDS_LEN 1 +#define TFA98XX_STATUSREG_OVDS_MAX 1 +#define TFA98XX_STATUSREG_OVDS_MSK 0x8 + +/* + * flag_uvpok + */ +#define TFA98XX_STATUSREG_UVDS (0x1 << 4) +#define TFA98XX_STATUSREG_UVDS_POS 4 +#define TFA98XX_STATUSREG_UVDS_LEN 1 +#define TFA98XX_STATUSREG_UVDS_MAX 1 +#define TFA98XX_STATUSREG_UVDS_MSK 0x10 + +/* + * flag_OCP_alarm + */ +#define TFA98XX_STATUSREG_OCDS (0x1 << 5) +#define TFA98XX_STATUSREG_OCDS_POS 5 +#define TFA98XX_STATUSREG_OCDS_LEN 1 +#define TFA98XX_STATUSREG_OCDS_MAX 1 +#define TFA98XX_STATUSREG_OCDS_MSK 0x20 + +/* + * flag_clocks_stable + */ +#define TFA98XX_STATUSREG_CLKS (0x1 << 6) +#define TFA98XX_STATUSREG_CLKS_POS 6 +#define TFA98XX_STATUSREG_CLKS_LEN 1 +#define TFA98XX_STATUSREG_CLKS_MAX 1 +#define TFA98XX_STATUSREG_CLKS_MSK 0x40 + +/* + * CLIP + */ +#define TFA98XX_STATUSREG_CLIPS (0x1 << 7) +#define TFA98XX_STATUSREG_CLIPS_POS 7 +#define TFA98XX_STATUSREG_CLIPS_LEN 1 +#define TFA98XX_STATUSREG_CLIPS_MAX 1 +#define TFA98XX_STATUSREG_CLIPS_MSK 0x80 + +/* + * mtp_busy + */ +#define TFA98XX_STATUSREG_MTPB (0x1 << 8) +#define TFA98XX_STATUSREG_MTPB_POS 8 +#define TFA98XX_STATUSREG_MTPB_LEN 1 +#define TFA98XX_STATUSREG_MTPB_MAX 1 +#define TFA98XX_STATUSREG_MTPB_MSK 0x100 + +/* + * flag_pwrokbst + */ +#define TFA98XX_STATUSREG_DCCS (0x1 << 9) +#define TFA98XX_STATUSREG_DCCS_POS 9 +#define TFA98XX_STATUSREG_DCCS_LEN 1 +#define TFA98XX_STATUSREG_DCCS_MAX 1 +#define TFA98XX_STATUSREG_DCCS_MSK 0x200 + +/* + * flag_cf_speakererror + */ +#define TFA98XX_STATUSREG_SPKS (0x1 << 10) +#define TFA98XX_STATUSREG_SPKS_POS 10 +#define TFA98XX_STATUSREG_SPKS_LEN 1 +#define TFA98XX_STATUSREG_SPKS_MAX 1 +#define TFA98XX_STATUSREG_SPKS_MSK 0x400 + +/* + * flag_cold_started + */ +#define TFA98XX_STATUSREG_ACS (0x1 << 11) +#define TFA98XX_STATUSREG_ACS_POS 11 +#define TFA98XX_STATUSREG_ACS_LEN 1 +#define TFA98XX_STATUSREG_ACS_MAX 1 +#define TFA98XX_STATUSREG_ACS_MSK 0x800 + +/* + * flag_engage + */ +#define TFA98XX_STATUSREG_SWS (0x1 << 12) +#define TFA98XX_STATUSREG_SWS_POS 12 +#define TFA98XX_STATUSREG_SWS_LEN 1 +#define TFA98XX_STATUSREG_SWS_MAX 1 +#define TFA98XX_STATUSREG_SWS_MSK 0x1000 + +/* + * flag_watchdog_reset + */ +#define TFA98XX_STATUSREG_WDS (0x1 << 13) +#define TFA98XX_STATUSREG_WDS_POS 13 +#define TFA98XX_STATUSREG_WDS_LEN 1 +#define TFA98XX_STATUSREG_WDS_MAX 1 +#define TFA98XX_STATUSREG_WDS_MSK 0x2000 + +/* + * flag_enbl_amp + */ +#define TFA98XX_STATUSREG_AMPS (0x1 << 14) +#define TFA98XX_STATUSREG_AMPS_POS 14 +#define TFA98XX_STATUSREG_AMPS_LEN 1 +#define TFA98XX_STATUSREG_AMPS_MAX 1 +#define TFA98XX_STATUSREG_AMPS_MSK 0x4000 + +/* + * flag_enbl_ref + */ +#define TFA98XX_STATUSREG_AREFS (0x1 << 15) +#define TFA98XX_STATUSREG_AREFS_POS 15 +#define TFA98XX_STATUSREG_AREFS_LEN 1 +#define TFA98XX_STATUSREG_AREFS_MAX 1 +#define TFA98XX_STATUSREG_AREFS_MSK 0x8000 + +/* + * (0x01)-BatteryVoltage + */ + +/* + * bat_adc + */ +#define TFA98XX_BATTERYVOLTAGE_BATS (0x3ff << 0) +#define TFA98XX_BATTERYVOLTAGE_BATS_POS 0 +#define TFA98XX_BATTERYVOLTAGE_BATS_LEN 10 +#define TFA98XX_BATTERYVOLTAGE_BATS_MAX 1023 +#define TFA98XX_BATTERYVOLTAGE_BATS_MSK 0x3ff + +/* + * (0x02)-Temperature + */ + +/* + * temp_adc + */ +#define TFA9891_TEMPERATURE_TEMPS (0x1ff << 0) +#define TFA9891_TEMPERATURE_TEMPS_POS 0 +#define TFA9891_TEMPERATURE_TEMPS_LEN 9 +#define TFA9891_TEMPERATURE_TEMPS_MAX 511 +#define TFA9891_TEMPERATURE_TEMPS_MSK 0x1ff + +/* + * (0x03)-RevisionNumber + */ + +/* + * rev_reg + */ +#define TFA98XX_REVISIONNUMBER_REV (0xff << 0) +#define TFA98XX_REVISIONNUMBER_REV_POS 0 +#define TFA98XX_REVISIONNUMBER_REV_LEN 8 +#define TFA98XX_REVISIONNUMBER_REV_MAX 255 +#define TFA98XX_REVISIONNUMBER_REV_MSK 0xff + +/* + * (0x04)-I2SReg + */ + +/* + * i2s_seti + */ +#define TFA98XX_I2SREG_I2SF (0x7 << 0) +#define TFA98XX_I2SREG_I2SF_POS 0 +#define TFA98XX_I2SREG_I2SF_LEN 3 +#define TFA98XX_I2SREG_I2SF_MAX 7 +#define TFA98XX_I2SREG_I2SF_MSK 0x7 + +/* + * chan_sel1 + */ +#define TFA98XX_I2SREG_CHS12 (0x3 << 3) +#define TFA98XX_I2SREG_CHS12_POS 3 +#define TFA98XX_I2SREG_CHS12_LEN 2 +#define TFA98XX_I2SREG_CHS12_MAX 3 +#define TFA98XX_I2SREG_CHS12_MSK 0x18 + +/* + * lr_sw_i2si2 + */ +#define TFA98XX_I2SREG_CHS3 (0x1 << 5) +#define TFA98XX_I2SREG_CHS3_POS 5 +#define TFA98XX_I2SREG_CHS3_LEN 1 +#define TFA98XX_I2SREG_CHS3_MAX 1 +#define TFA98XX_I2SREG_CHS3_MSK 0x20 + +/* + * input_sel + */ +#define TFA98XX_I2SREG_CHSA (0x3 << 6) +#define TFA98XX_I2SREG_CHSA_POS 6 +#define TFA98XX_I2SREG_CHSA_LEN 2 +#define TFA98XX_I2SREG_CHSA_MAX 3 +#define TFA98XX_I2SREG_CHSA_MSK 0xc0 + +/* + * datao_sel + */ +#define TFA98XX_I2SREG_I2SDOC (0x3 << 8) +#define TFA98XX_I2SREG_I2SDOC_POS 8 +#define TFA98XX_I2SREG_I2SDOC_LEN 2 +#define TFA98XX_I2SREG_I2SDOC_MAX 3 +#define TFA98XX_I2SREG_I2SDOC_MSK 0x300 + +/* + * disable_idp + */ +#define TFA98XX_I2SREG_DISP (0x1 << 10) +#define TFA98XX_I2SREG_DISP_POS 10 +#define TFA98XX_I2SREG_DISP_LEN 1 +#define TFA98XX_I2SREG_DISP_MAX 1 +#define TFA98XX_I2SREG_DISP_MSK 0x400 + +/* + * enbl_datao + */ +#define TFA98XX_I2SREG_I2SDOE (0x1 << 11) +#define TFA98XX_I2SREG_I2SDOE_POS 11 +#define TFA98XX_I2SREG_I2SDOE_LEN 1 +#define TFA98XX_I2SREG_I2SDOE_MAX 1 +#define TFA98XX_I2SREG_I2SDOE_MSK 0x800 + +/* + * i2s_fs + */ +#define TFA98XX_I2SREG_I2SSR (0xf << 12) +#define TFA98XX_I2SREG_I2SSR_POS 12 +#define TFA98XX_I2SREG_I2SSR_LEN 4 +#define TFA98XX_I2SREG_I2SSR_MAX 15 +#define TFA98XX_I2SREG_I2SSR_MSK 0xf000 + +/* + * (0x05)-bat_prot + */ + +/* + * vbat_prot_attacktime + */ +#define TFA98XX_BAT_PROT_BSSCR (0x3 << 0) +#define TFA98XX_BAT_PROT_BSSCR_POS 0 +#define TFA98XX_BAT_PROT_BSSCR_LEN 2 +#define TFA98XX_BAT_PROT_BSSCR_MAX 3 +#define TFA98XX_BAT_PROT_BSSCR_MSK 0x3 + +/* + * vbat_prot_thlevel + */ +#define TFA98XX_BAT_PROT_BSST (0xf << 2) +#define TFA98XX_BAT_PROT_BSST_POS 2 +#define TFA98XX_BAT_PROT_BSST_LEN 4 +#define TFA98XX_BAT_PROT_BSST_MAX 15 +#define TFA98XX_BAT_PROT_BSST_MSK 0x3c + +/* + * vbat_prot_max_reduct + */ +#define TFA98XX_BAT_PROT_BSSRL (0x3 << 6) +#define TFA98XX_BAT_PROT_BSSRL_POS 6 +#define TFA98XX_BAT_PROT_BSSRL_LEN 2 +#define TFA98XX_BAT_PROT_BSSRL_MAX 3 +#define TFA98XX_BAT_PROT_BSSRL_MSK 0xc0 + +/* + * vbat_prot_release_t + */ +#define TFA98XX_BAT_PROT_BSSRR (0x7 << 8) +#define TFA98XX_BAT_PROT_BSSRR_POS 8 +#define TFA98XX_BAT_PROT_BSSRR_LEN 3 +#define TFA98XX_BAT_PROT_BSSRR_MAX 7 +#define TFA98XX_BAT_PROT_BSSRR_MSK 0x700 + +/* + * vbat_prot_hysterese + */ +#define TFA98XX_BAT_PROT_BSSHY (0x3 << 11) +#define TFA98XX_BAT_PROT_BSSHY_POS 11 +#define TFA98XX_BAT_PROT_BSSHY_LEN 2 +#define TFA98XX_BAT_PROT_BSSHY_MAX 3 +#define TFA98XX_BAT_PROT_BSSHY_MSK 0x1800 + +/* + * sel_vbat + */ +#define TFA98XX_BAT_PROT_BSSR (0x1 << 14) +#define TFA98XX_BAT_PROT_BSSR_POS 14 +#define TFA98XX_BAT_PROT_BSSR_LEN 1 +#define TFA98XX_BAT_PROT_BSSR_MAX 1 +#define TFA98XX_BAT_PROT_BSSR_MSK 0x4000 + +/* + * bypass_clipper + */ +#define TFA98XX_BAT_PROT_BSSBY (0x1 << 15) +#define TFA98XX_BAT_PROT_BSSBY_POS 15 +#define TFA98XX_BAT_PROT_BSSBY_LEN 1 +#define TFA98XX_BAT_PROT_BSSBY_MAX 1 +#define TFA98XX_BAT_PROT_BSSBY_MSK 0x8000 + +/* + * (0x06)-audio_ctr + */ + +/* + * dpsa + */ +#define TFA98XX_AUDIO_CTR_DPSA (0x1 << 0) +#define TFA98XX_AUDIO_CTR_DPSA_POS 0 +#define TFA98XX_AUDIO_CTR_DPSA_LEN 1 +#define TFA98XX_AUDIO_CTR_DPSA_MAX 1 +#define TFA98XX_AUDIO_CTR_DPSA_MSK 0x1 + +/* + * ctrl_slope + */ +#define TFA98XX_AUDIO_CTR_AMPSL (0xf << 1) +#define TFA98XX_AUDIO_CTR_AMPSL_POS 1 +#define TFA98XX_AUDIO_CTR_AMPSL_LEN 4 +#define TFA98XX_AUDIO_CTR_AMPSL_MAX 15 +#define TFA98XX_AUDIO_CTR_AMPSL_MSK 0x1e + +/* + * cf_mute + */ +#define TFA98XX_AUDIO_CTR_CFSM (0x1 << 5) +#define TFA98XX_AUDIO_CTR_CFSM_POS 5 +#define TFA98XX_AUDIO_CTR_CFSM_LEN 1 +#define TFA98XX_AUDIO_CTR_CFSM_MAX 1 +#define TFA98XX_AUDIO_CTR_CFSM_MSK 0x20 + +/* + * ctrl_batsensesteepness + */ +#define TFA98XX_AUDIO_CTR_BSSS (0x1 << 7) +#define TFA98XX_AUDIO_CTR_BSSS_POS 7 +#define TFA98XX_AUDIO_CTR_BSSS_LEN 1 +#define TFA98XX_AUDIO_CTR_BSSS_MAX 1 +#define TFA98XX_AUDIO_CTR_BSSS_MSK 0x80 + +/* + * vol + */ +#define TFA98XX_AUDIO_CTR_VOL (0xff << 8) +#define TFA98XX_AUDIO_CTR_VOL_POS 8 +#define TFA98XX_AUDIO_CTR_VOL_LEN 8 +#define TFA98XX_AUDIO_CTR_VOL_MAX 255 +#define TFA98XX_AUDIO_CTR_VOL_MSK 0xff00 + +/* + * (0x07)-DCDCboost + */ + +/* + * ctrl_bstvolt + */ +#define TFA98XX_DCDCBOOST_DCVO (0x7 << 0) +#define TFA98XX_DCDCBOOST_DCVO_POS 0 +#define TFA98XX_DCDCBOOST_DCVO_LEN 3 +#define TFA98XX_DCDCBOOST_DCVO_MAX 7 +#define TFA98XX_DCDCBOOST_DCVO_MSK 0x7 + +/* + * ctrl_bstcur + */ +#define TFA98XX_DCDCBOOST_DCMCC (0x7 << 3) +#define TFA98XX_DCDCBOOST_DCMCC_POS 3 +#define TFA98XX_DCDCBOOST_DCMCC_LEN 3 +#define TFA98XX_DCDCBOOST_DCMCC_MAX 7 +#define TFA98XX_DCDCBOOST_DCMCC_MSK 0x38 + +/* + * boost_intel + */ +#define TFA98XX_DCDCBOOST_DCIE (0x1 << 10) +#define TFA98XX_DCDCBOOST_DCIE_POS 10 +#define TFA98XX_DCDCBOOST_DCIE_LEN 1 +#define TFA98XX_DCDCBOOST_DCIE_MAX 1 +#define TFA98XX_DCDCBOOST_DCIE_MSK 0x400 + +/* + * boost_speed + */ +#define TFA98XX_DCDCBOOST_DCSR (0x1 << 11) +#define TFA98XX_DCDCBOOST_DCSR_POS 11 +#define TFA98XX_DCDCBOOST_DCSR_LEN 1 +#define TFA98XX_DCDCBOOST_DCSR_MAX 1 +#define TFA98XX_DCDCBOOST_DCSR_MSK 0x800 + +/* + * (0x08)-spkr_calibration + */ + +/* + * ext_temp_sel + */ +#define TFA98XX_SPKR_CALIBRATION_TROS (0x1 << 0) +#define TFA98XX_SPKR_CALIBRATION_TROS_POS 0 +#define TFA98XX_SPKR_CALIBRATION_TROS_LEN 1 +#define TFA98XX_SPKR_CALIBRATION_TROS_MAX 1 +#define TFA98XX_SPKR_CALIBRATION_TROS_MSK 0x1 + +/* + * ext_temp + */ +#define TFA98XX_SPKR_CALIBRATION_EXTTS (0x1ff << 1) +#define TFA98XX_SPKR_CALIBRATION_EXTTS_POS 1 +#define TFA98XX_SPKR_CALIBRATION_EXTTS_LEN 9 +#define TFA98XX_SPKR_CALIBRATION_EXTTS_MAX 511 +#define TFA98XX_SPKR_CALIBRATION_EXTTS_MSK 0x3fe + +/* + * (0x09)-sys_ctrl + */ + +/* + * PowerDown + */ +#define TFA98XX_SYS_CTRL_PWDN (0x1 << 0) +#define TFA98XX_SYS_CTRL_PWDN_POS 0 +#define TFA98XX_SYS_CTRL_PWDN_LEN 1 +#define TFA98XX_SYS_CTRL_PWDN_MAX 1 +#define TFA98XX_SYS_CTRL_PWDN_MSK 0x1 + +/* + * reset + */ +#define TFA98XX_SYS_CTRL_I2CR (0x1 << 1) +#define TFA98XX_SYS_CTRL_I2CR_POS 1 +#define TFA98XX_SYS_CTRL_I2CR_LEN 1 +#define TFA98XX_SYS_CTRL_I2CR_MAX 1 +#define TFA98XX_SYS_CTRL_I2CR_MSK 0x2 + +/* + * enbl_coolflux + */ +#define TFA98XX_SYS_CTRL_CFE (0x1 << 2) +#define TFA98XX_SYS_CTRL_CFE_POS 2 +#define TFA98XX_SYS_CTRL_CFE_LEN 1 +#define TFA98XX_SYS_CTRL_CFE_MAX 1 +#define TFA98XX_SYS_CTRL_CFE_MSK 0x4 + +/* + * enbl_amplifier + */ +#define TFA98XX_SYS_CTRL_AMPE (0x1 << 3) +#define TFA98XX_SYS_CTRL_AMPE_POS 3 +#define TFA98XX_SYS_CTRL_AMPE_LEN 1 +#define TFA98XX_SYS_CTRL_AMPE_MAX 1 +#define TFA98XX_SYS_CTRL_AMPE_MSK 0x8 + +/* + * enbl_boost + */ +#define TFA98XX_SYS_CTRL_DCA (0x1 << 4) +#define TFA98XX_SYS_CTRL_DCA_POS 4 +#define TFA98XX_SYS_CTRL_DCA_LEN 1 +#define TFA98XX_SYS_CTRL_DCA_MAX 1 +#define TFA98XX_SYS_CTRL_DCA_MSK 0x10 + +/* + * cf_configured + */ +#define TFA98XX_SYS_CTRL_SBSL (0x1 << 5) +#define TFA98XX_SYS_CTRL_SBSL_POS 5 +#define TFA98XX_SYS_CTRL_SBSL_LEN 1 +#define TFA98XX_SYS_CTRL_SBSL_MAX 1 +#define TFA98XX_SYS_CTRL_SBSL_MSK 0x20 + +/* + * sel_enbl_amplifier + */ +#define TFA98XX_SYS_CTRL_AMPC (0x1 << 6) +#define TFA98XX_SYS_CTRL_AMPC_POS 6 +#define TFA98XX_SYS_CTRL_AMPC_LEN 1 +#define TFA98XX_SYS_CTRL_AMPC_MAX 1 +#define TFA98XX_SYS_CTRL_AMPC_MSK 0x40 + +/* + * dcdcoff_mode + */ +#define TFA98XX_SYS_CTRL_DCDIS (0x1 << 7) +#define TFA98XX_SYS_CTRL_DCDIS_POS 7 +#define TFA98XX_SYS_CTRL_DCDIS_LEN 1 +#define TFA98XX_SYS_CTRL_DCDIS_MAX 1 +#define TFA98XX_SYS_CTRL_DCDIS_MSK 0x80 + +/* + * cttr_iddqtest + */ +#define TFA98XX_SYS_CTRL_PSDR (0x1 << 8) +#define TFA98XX_SYS_CTRL_PSDR_POS 8 +#define TFA98XX_SYS_CTRL_PSDR_LEN 1 +#define TFA98XX_SYS_CTRL_PSDR_MAX 1 +#define TFA98XX_SYS_CTRL_PSDR_MSK 0x100 + +/* + * ctrl_coil_value + */ +#define TFA98XX_SYS_CTRL_DCCV (0x3 << 9) +#define TFA98XX_SYS_CTRL_DCCV_POS 9 +#define TFA98XX_SYS_CTRL_DCCV_LEN 2 +#define TFA98XX_SYS_CTRL_DCCV_MAX 3 +#define TFA98XX_SYS_CTRL_DCCV_MSK 0x600 + +/* + * ctrl_sel_cf_clock + */ +#define TFA98XX_SYS_CTRL_CCFD (0x3 << 11) +#define TFA98XX_SYS_CTRL_CCFD_POS 11 +#define TFA98XX_SYS_CTRL_CCFD_LEN 2 +#define TFA98XX_SYS_CTRL_CCFD_MAX 3 +#define TFA98XX_SYS_CTRL_CCFD_MSK 0x1800 + +/* + * intf_sel + */ +#define TFA98XX_SYS_CTRL_ISEL (0x1 << 13) +#define TFA98XX_SYS_CTRL_ISEL_POS 13 +#define TFA98XX_SYS_CTRL_ISEL_LEN 1 +#define TFA98XX_SYS_CTRL_ISEL_MAX 1 +#define TFA98XX_SYS_CTRL_ISEL_MSK 0x2000 + +/* + * sel_ws_bck + */ +#define TFA98XX_SYS_CTRL_IPLL (0x1 << 14) +#define TFA98XX_SYS_CTRL_IPLL_POS 14 +#define TFA98XX_SYS_CTRL_IPLL_LEN 1 +#define TFA98XX_SYS_CTRL_IPLL_MAX 1 +#define TFA98XX_SYS_CTRL_IPLL_MSK 0x4000 + +/* + * (0x0a)-I2S_sel_reg + */ + +/* + * sel_i2so_l + */ +#define TFA98XX_I2S_SEL_REG_DOLS (0x7 << 0) +#define TFA98XX_I2S_SEL_REG_DOLS_POS 0 +#define TFA98XX_I2S_SEL_REG_DOLS_LEN 3 +#define TFA98XX_I2S_SEL_REG_DOLS_MAX 7 +#define TFA98XX_I2S_SEL_REG_DOLS_MSK 0x7 + +/* + * sel_i2so_r + */ +#define TFA98XX_I2S_SEL_REG_DORS (0x7 << 3) +#define TFA98XX_I2S_SEL_REG_DORS_POS 3 +#define TFA98XX_I2S_SEL_REG_DORS_LEN 3 +#define TFA98XX_I2S_SEL_REG_DORS_MAX 7 +#define TFA98XX_I2S_SEL_REG_DORS_MSK 0x38 + +/* + * ctrl_spkr_coil + */ +#define TFA98XX_I2S_SEL_REG_SPKL (0x7 << 6) +#define TFA98XX_I2S_SEL_REG_SPKL_POS 6 +#define TFA98XX_I2S_SEL_REG_SPKL_LEN 3 +#define TFA98XX_I2S_SEL_REG_SPKL_MAX 7 +#define TFA98XX_I2S_SEL_REG_SPKL_MSK 0x1c0 + +/* + * ctrl_spr_res + */ +#define TFA98XX_I2S_SEL_REG_SPKR (0x3 << 9) +#define TFA98XX_I2S_SEL_REG_SPKR_POS 9 +#define TFA98XX_I2S_SEL_REG_SPKR_LEN 2 +#define TFA98XX_I2S_SEL_REG_SPKR_MAX 3 +#define TFA98XX_I2S_SEL_REG_SPKR_MSK 0x600 + +/* + * ctrl_dcdc_spkr_i_comp_gain + */ +#define TFA98XX_I2S_SEL_REG_DCFG (0xf << 11) +#define TFA98XX_I2S_SEL_REG_DCFG_POS 11 +#define TFA98XX_I2S_SEL_REG_DCFG_LEN 4 +#define TFA98XX_I2S_SEL_REG_DCFG_MAX 15 +#define TFA98XX_I2S_SEL_REG_DCFG_MSK 0x7800 + +/* + * (0x0b)-Hidden_mtp_key2 + */ + +/* + * MTP_key2 + */ +#define TFA98XX_HIDDEN_MTP_KEY2_MTPK (0xff << 0) +#define TFA98XX_HIDDEN_MTP_KEY2_MTPK_POS 0 +#define TFA98XX_HIDDEN_MTP_KEY2_MTPK_LEN 8 +#define TFA98XX_HIDDEN_MTP_KEY2_MTPK_MAX 255 +#define TFA98XX_HIDDEN_MTP_KEY2_MTPK_MSK 0xff + +/* + * (0x0f)-interrupt_reg + */ + +/* + * flag_por_mask + */ +#define TFA98XX_INTERRUPT_REG_VDDD (0x1 << 0) +#define TFA98XX_INTERRUPT_REG_VDDD_POS 0 +#define TFA98XX_INTERRUPT_REG_VDDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_VDDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_VDDD_MSK 0x1 + +/* + * flag_otpok_mask + */ +#define TFA98XX_INTERRUPT_REG_OTDD (0x1 << 1) +#define TFA98XX_INTERRUPT_REG_OTDD_POS 1 +#define TFA98XX_INTERRUPT_REG_OTDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_OTDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_OTDD_MSK 0x2 + +/* + * flag_ovpok_mask + */ +#define TFA98XX_INTERRUPT_REG_OVDD (0x1 << 2) +#define TFA98XX_INTERRUPT_REG_OVDD_POS 2 +#define TFA98XX_INTERRUPT_REG_OVDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_OVDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_OVDD_MSK 0x4 + +/* + * flag_uvpok_mask + */ +#define TFA98XX_INTERRUPT_REG_UVDD (0x1 << 3) +#define TFA98XX_INTERRUPT_REG_UVDD_POS 3 +#define TFA98XX_INTERRUPT_REG_UVDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_UVDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_UVDD_MSK 0x8 + +/* + * flag_ocp_alarm_mask + */ +#define TFA98XX_INTERRUPT_REG_OCDD (0x1 << 4) +#define TFA98XX_INTERRUPT_REG_OCDD_POS 4 +#define TFA98XX_INTERRUPT_REG_OCDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_OCDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_OCDD_MSK 0x10 + +/* + * flag_clocks_stable_mask + */ +#define TFA98XX_INTERRUPT_REG_CLKD (0x1 << 5) +#define TFA98XX_INTERRUPT_REG_CLKD_POS 5 +#define TFA98XX_INTERRUPT_REG_CLKD_LEN 1 +#define TFA98XX_INTERRUPT_REG_CLKD_MAX 1 +#define TFA98XX_INTERRUPT_REG_CLKD_MSK 0x20 + +/* + * flag_pwrokbst_mask + */ +#define TFA98XX_INTERRUPT_REG_DCCD (0x1 << 6) +#define TFA98XX_INTERRUPT_REG_DCCD_POS 6 +#define TFA98XX_INTERRUPT_REG_DCCD_LEN 1 +#define TFA98XX_INTERRUPT_REG_DCCD_MAX 1 +#define TFA98XX_INTERRUPT_REG_DCCD_MSK 0x40 + +/* + * flag_cf_speakererror_mask + */ +#define TFA98XX_INTERRUPT_REG_SPKD (0x1 << 7) +#define TFA98XX_INTERRUPT_REG_SPKD_POS 7 +#define TFA98XX_INTERRUPT_REG_SPKD_LEN 1 +#define TFA98XX_INTERRUPT_REG_SPKD_MAX 1 +#define TFA98XX_INTERRUPT_REG_SPKD_MSK 0x80 + +/* + * flag_watchdog_reset_mask + */ +#define TFA98XX_INTERRUPT_REG_WDD (0x1 << 8) +#define TFA98XX_INTERRUPT_REG_WDD_POS 8 +#define TFA98XX_INTERRUPT_REG_WDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_WDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_WDD_MSK 0x100 + +/* + * enable_interrupt + */ +#define TFA98XX_INTERRUPT_REG_INT (0x1 << 14) +#define TFA98XX_INTERRUPT_REG_INT_POS 14 +#define TFA98XX_INTERRUPT_REG_INT_LEN 1 +#define TFA98XX_INTERRUPT_REG_INT_MAX 1 +#define TFA98XX_INTERRUPT_REG_INT_MSK 0x4000 + +/* + * invert_int_polarity + */ +#define TFA98XX_INTERRUPT_REG_INTP (0x1 << 15) +#define TFA98XX_INTERRUPT_REG_INTP_POS 15 +#define TFA98XX_INTERRUPT_REG_INTP_LEN 1 +#define TFA98XX_INTERRUPT_REG_INTP_MAX 1 +#define TFA98XX_INTERRUPT_REG_INTP_MSK 0x8000 + +/* + * (0x10)-pdm_ctrl + */ + +/* + * pdm_i2s_input + */ +#define TFA98XX_PDM_CTRL_PDMSEL (0x1 << 0) +#define TFA98XX_PDM_CTRL_PDMSEL_POS 0 +#define TFA98XX_PDM_CTRL_PDMSEL_LEN 1 +#define TFA98XX_PDM_CTRL_PDMSEL_MAX 1 +#define TFA98XX_PDM_CTRL_PDMSEL_MSK 0x1 + +/* + * I2S_master_ena + */ +#define TFA98XX_PDM_CTRL_I2SMOUTEN (0x1 << 1) +#define TFA98XX_PDM_CTRL_I2SMOUTEN_POS 1 +#define TFA98XX_PDM_CTRL_I2SMOUTEN_LEN 1 +#define TFA98XX_PDM_CTRL_I2SMOUTEN_MAX 1 +#define TFA98XX_PDM_CTRL_I2SMOUTEN_MSK 0x2 + +/* + * pdm_out_sel_r + */ +#define TFA98XX_PDM_CTRL_PDMORSEL (0x3 << 2) +#define TFA98XX_PDM_CTRL_PDMORSEL_POS 2 +#define TFA98XX_PDM_CTRL_PDMORSEL_LEN 2 +#define TFA98XX_PDM_CTRL_PDMORSEL_MAX 3 +#define TFA98XX_PDM_CTRL_PDMORSEL_MSK 0xc + +/* + * pdm_out_sel_l + */ +#define TFA98XX_PDM_CTRL_PDMOLSEL (0x3 << 4) +#define TFA98XX_PDM_CTRL_PDMOLSEL_POS 4 +#define TFA98XX_PDM_CTRL_PDMOLSEL_LEN 2 +#define TFA98XX_PDM_CTRL_PDMOLSEL_MAX 3 +#define TFA98XX_PDM_CTRL_PDMOLSEL_MSK 0x30 + +/* + * micdat_out_sel + */ +#define TFA98XX_PDM_CTRL_PADSEL (0x3 << 6) +#define TFA98XX_PDM_CTRL_PADSEL_POS 6 +#define TFA98XX_PDM_CTRL_PADSEL_LEN 2 +#define TFA98XX_PDM_CTRL_PADSEL_MAX 3 +#define TFA98XX_PDM_CTRL_PADSEL_MSK 0xc0 + +/* + * (0x11)-pdm_out_ctrl + */ + +/* + * secure_dly + */ +#define TFA98XX_PDM_OUT_CTRL_PDMOSDEN (0x1 << 0) +#define TFA98XX_PDM_OUT_CTRL_PDMOSDEN_POS 0 +#define TFA98XX_PDM_OUT_CTRL_PDMOSDEN_LEN 1 +#define TFA98XX_PDM_OUT_CTRL_PDMOSDEN_MAX 1 +#define TFA98XX_PDM_OUT_CTRL_PDMOSDEN_MSK 0x1 + +/* + * d_out_valid_rf_mux + */ +#define TFA98XX_PDM_OUT_CTRL_PDMOSDCF (0x1 << 1) +#define TFA98XX_PDM_OUT_CTRL_PDMOSDCF_POS 1 +#define TFA98XX_PDM_OUT_CTRL_PDMOSDCF_LEN 1 +#define TFA98XX_PDM_OUT_CTRL_PDMOSDCF_MAX 1 +#define TFA98XX_PDM_OUT_CTRL_PDMOSDCF_MSK 0x2 + +/* + * Speak_As_Mic_en + */ +#define TFA98XX_PDM_OUT_CTRL_SAAMEN (0x1 << 4) +#define TFA98XX_PDM_OUT_CTRL_SAAMEN_POS 4 +#define TFA98XX_PDM_OUT_CTRL_SAAMEN_LEN 1 +#define TFA98XX_PDM_OUT_CTRL_SAAMEN_MAX 1 +#define TFA98XX_PDM_OUT_CTRL_SAAMEN_MSK 0x10 + +/* + * speak_as_mic_lp_mode + */ +#define TFA98XX_PDM_OUT_CTRL_SAAMLPEN (0x1 << 5) +#define TFA98XX_PDM_OUT_CTRL_SAAMLPEN_POS 5 +#define TFA98XX_PDM_OUT_CTRL_SAAMLPEN_LEN 1 +#define TFA98XX_PDM_OUT_CTRL_SAAMLPEN_MAX 1 +#define TFA98XX_PDM_OUT_CTRL_SAAMLPEN_MSK 0x20 + +/* + * pdm_out_rate + */ +#define TFA98XX_PDM_OUT_CTRL_PDMOINTEN (0x1 << 6) +#define TFA98XX_PDM_OUT_CTRL_PDMOINTEN_POS 6 +#define TFA98XX_PDM_OUT_CTRL_PDMOINTEN_LEN 1 +#define TFA98XX_PDM_OUT_CTRL_PDMOINTEN_MAX 1 +#define TFA98XX_PDM_OUT_CTRL_PDMOINTEN_MSK 0x40 + +/* + * (0x12)-pdm_ds4_r + */ + +/* + * ds4_g1_r + */ +#define TFA98XX_PDM_DS4_R_PDMORG1 (0xf << 0) +#define TFA98XX_PDM_DS4_R_PDMORG1_POS 0 +#define TFA98XX_PDM_DS4_R_PDMORG1_LEN 4 +#define TFA98XX_PDM_DS4_R_PDMORG1_MAX 15 +#define TFA98XX_PDM_DS4_R_PDMORG1_MSK 0xf + +/* + * ds4_g2_r + */ +#define TFA98XX_PDM_DS4_R_PDMORG2 (0xf << 4) +#define TFA98XX_PDM_DS4_R_PDMORG2_POS 4 +#define TFA98XX_PDM_DS4_R_PDMORG2_LEN 4 +#define TFA98XX_PDM_DS4_R_PDMORG2_MAX 15 +#define TFA98XX_PDM_DS4_R_PDMORG2_MSK 0xf0 + +/* + * (0x13)-pdm_ds4_l + */ + +/* + * ds4_g1_l + */ +#define TFA98XX_PDM_DS4_L_PDMOLG1 (0xf << 0) +#define TFA98XX_PDM_DS4_L_PDMOLG1_POS 0 +#define TFA98XX_PDM_DS4_L_PDMOLG1_LEN 4 +#define TFA98XX_PDM_DS4_L_PDMOLG1_MAX 15 +#define TFA98XX_PDM_DS4_L_PDMOLG1_MSK 0xf + +/* + * ds4_g2_l + */ +#define TFA98XX_PDM_DS4_L_PDMOLG2 (0xf << 4) +#define TFA98XX_PDM_DS4_L_PDMOLG2_POS 4 +#define TFA98XX_PDM_DS4_L_PDMOLG2_LEN 4 +#define TFA98XX_PDM_DS4_L_PDMOLG2_MAX 15 +#define TFA98XX_PDM_DS4_L_PDMOLG2_MSK 0xf0 + +/* + * (0x22)-ctrl_saam_pga + */ + +/* + * Ctrl_saam_pga_gain + */ +#define TFA98XX_CTRL_SAAM_PGA_SAAMGAIN (0x7 << 0) +#define TFA98XX_CTRL_SAAM_PGA_SAAMGAIN_POS 0 +#define TFA98XX_CTRL_SAAM_PGA_SAAMGAIN_LEN 3 +#define TFA98XX_CTRL_SAAM_PGA_SAAMGAIN_MAX 7 +#define TFA98XX_CTRL_SAAM_PGA_SAAMGAIN_MSK 0x7 + +/* + * ctrl_saam_pga_src + */ +#define TFA98XX_CTRL_SAAM_PGA_SAAMPGACTRL (0x1 << 5) +#define TFA98XX_CTRL_SAAM_PGA_SAAMPGACTRL_POS 5 +#define TFA98XX_CTRL_SAAM_PGA_SAAMPGACTRL_LEN 1 +#define TFA98XX_CTRL_SAAM_PGA_SAAMPGACTRL_MAX 1 +#define TFA98XX_CTRL_SAAM_PGA_SAAMPGACTRL_MSK 0x20 + +/* + * (0x25)-misc_ctrl + */ + +/* + * pll_fcco + */ +#define TFA98XX_MISC_CTRL_PLLCCOSEL (0x1 << 0) +#define TFA98XX_MISC_CTRL_PLLCCOSEL_POS 0 +#define TFA98XX_MISC_CTRL_PLLCCOSEL_LEN 1 +#define TFA98XX_MISC_CTRL_PLLCCOSEL_MAX 1 +#define TFA98XX_MISC_CTRL_PLLCCOSEL_MSK 0x1 + +/* + * (0x46)-CurrentSense1 + */ + +/* + * bypass_gc + */ +#define TFA98XX_CURRENTSENSE1_CSBYPGC (0x1 << 0) +#define TFA98XX_CURRENTSENSE1_CSBYPGC_POS 0 +#define TFA98XX_CURRENTSENSE1_CSBYPGC_LEN 1 +#define TFA98XX_CURRENTSENSE1_CSBYPGC_MAX 1 +#define TFA98XX_CURRENTSENSE1_CSBYPGC_MSK 0x1 + +/* + * (0x49)-CurrentSense4 + */ + +/* + * ctrl_bypassclip + */ +#define TFA98XX_CURRENTSENSE4_CLIP (0x1 << 0) +#define TFA98XX_CURRENTSENSE4_CLIP_POS 0 +#define TFA98XX_CURRENTSENSE4_CLIP_LEN 1 +#define TFA98XX_CURRENTSENSE4_CLIP_MAX 1 +#define TFA98XX_CURRENTSENSE4_CLIP_MSK 0x1 + +/* + * ctrl_bypassclip2 + */ +#define TFA98XX_CURRENTSENSE4_CLIP2 (0x1 << 1) +#define TFA98XX_CURRENTSENSE4_CLIP2_POS 1 +#define TFA98XX_CURRENTSENSE4_CLIP2_LEN 1 +#define TFA98XX_CURRENTSENSE4_CLIP2_MAX 1 +#define TFA98XX_CURRENTSENSE4_CLIP2_MSK 0x2 + +/* + * (0x62)-Hidden_mtp_ctrl_reg3 + */ + +/* + * (0x70)-cf_controls + */ + +/* + * cf_rst_dsp + */ +#define TFA98XX_CF_CONTROLS_RST (0x1 << 0) +#define TFA98XX_CF_CONTROLS_RST_POS 0 +#define TFA98XX_CF_CONTROLS_RST_LEN 1 +#define TFA98XX_CF_CONTROLS_RST_MAX 1 +#define TFA98XX_CF_CONTROLS_RST_MSK 0x1 + +/* + * cf_dmem + */ +#define TFA98XX_CF_CONTROLS_DMEM (0x3 << 1) +#define TFA98XX_CF_CONTROLS_DMEM_POS 1 +#define TFA98XX_CF_CONTROLS_DMEM_LEN 2 +#define TFA98XX_CF_CONTROLS_DMEM_MAX 3 +#define TFA98XX_CF_CONTROLS_DMEM_MSK 0x6 + +/* + * cf_aif + */ +#define TFA98XX_CF_CONTROLS_AIF (0x1 << 3) +#define TFA98XX_CF_CONTROLS_AIF_POS 3 +#define TFA98XX_CF_CONTROLS_AIF_LEN 1 +#define TFA98XX_CF_CONTROLS_AIF_MAX 1 +#define TFA98XX_CF_CONTROLS_AIF_MSK 0x8 + +/* + * cf_int + */ +#define TFA98XX_CF_CONTROLS_CFINT (0x1 << 4) +#define TFA98XX_CF_CONTROLS_CFINT_POS 4 +#define TFA98XX_CF_CONTROLS_CFINT_LEN 1 +#define TFA98XX_CF_CONTROLS_CFINT_MAX 1 +#define TFA98XX_CF_CONTROLS_CFINT_MSK 0x10 + +/* + * cf_req + */ +#define TFA98XX_CF_CONTROLS_REQ (0xff << 8) +#define TFA98XX_CF_CONTROLS_REQ_POS 8 +#define TFA98XX_CF_CONTROLS_REQ_LEN 8 +#define TFA98XX_CF_CONTROLS_REQ_MAX 255 +#define TFA98XX_CF_CONTROLS_REQ_MSK 0xff00 + +/* + * (0x71)-cf_mad + */ + +/* + * cf_madd + */ +#define TFA9891_CF_MAD_MADD (0xffff << 0) +#define TFA9891_CF_MAD_MADD_POS 0 +#define TFA9891_CF_MAD_MADD_LEN 16 +#define TFA9891_CF_MAD_MADD_MAX 65535 +#define TFA9891_CF_MAD_MADD_MSK 0xffff + +/* + * (0x72)-cf_mem + */ + +/* + * cf_mema + */ +#define TFA9891_CF_MEM_MEMA (0xffff << 0) +#define TFA9891_CF_MEM_MEMA_POS 0 +#define TFA9891_CF_MEM_MEMA_LEN 16 +#define TFA9891_CF_MEM_MEMA_MAX 65535 +#define TFA9891_CF_MEM_MEMA_MSK 0xffff + +/* + * (0x73)-cf_status + */ + +/* + * cf_err + */ +#define TFA9891_CF_STATUS_ERR (0xff << 0) +#define TFA9891_CF_STATUS_ERR_POS 0 +#define TFA9891_CF_STATUS_ERR_LEN 8 +#define TFA9891_CF_STATUS_ERR_MAX 255 +#define TFA9891_CF_STATUS_ERR_MSK 0xff + +/* + * cf_ack + */ +#define TFA9891_CF_STATUS_ACK (0xff << 8) +#define TFA9891_CF_STATUS_ACK_POS 8 +#define TFA9891_CF_STATUS_ACK_LEN 8 +#define TFA9891_CF_STATUS_ACK_MAX 255 +#define TFA9891_CF_STATUS_ACK_MSK 0xff00 + +/* + * (0x80)-Key2Protected_spkr_cal_mtp + */ + +/* + * calibration_onetime + */ +#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPOTC (0x1 << 0) +#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPOTC_POS 0 +#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPOTC_LEN 1 +#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPOTC_MAX 1 +#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPOTC_MSK 0x1 + +/* + * calibr_ron_done + */ +#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPEX (0x1 << 1) +#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPEX_POS 1 +#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPEX_LEN 1 +#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPEX_MAX 1 +#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPEX_MSK 0x2 + +#endif /* TFA9891_GENREGS_H */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9891_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9891_tfafieldnames.h new file mode 100644 index 000000000000..943a31d5e900 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9891_tfafieldnames.h @@ -0,0 +1,1000 @@ +/* + * tfa9891_tfafieldnames.h + * + * Created on: Jul 16, 2015 + * Author: wim + */ + +#ifndef TFA_INC_TFA9891_TFAFIELDNAMES_H_ +#define TFA_INC_TFA9891_TFAFIELDNAMES_H_ + +/** Filename: Tfa9891_TfaFieldnames.h + * This file was generated automatically on 07/16/15 at 15:00:02. + * Source file: TFA9891_I2C_list_V13.xls + */ + +#define TFA9891_I2CVERSION 13 + +#define TFA9891_NAMETABLE \ + static tfaBfName_t Tfa9891DatasheetNames[] = { \ + { 0x0, \ + "VDDS" }, /* POR , */ \ + { 0x10, \ + "PLLS" }, /* PLL , */ \ + { 0x20, \ + "OTDS" }, /* OTP , */ \ + { 0x30, \ + "OVDS" }, /* OVP , */ \ + { 0x40, \ + "UVDS" }, /* UVP , */ \ + { 0x50, \ + "OCDS" }, /* OCP , */ \ + { 0x60, \ + "CLKS" }, /* Clocks , */ \ + { 0x70, \ + "CLIPS" }, /* CLIP , */ \ + { 0x80, \ + "MTPB" }, /* MTP , */ \ + { 0x90, \ + "DCCS" }, /* BOOST , */ \ + { 0xa0, \ + "SPKS" }, /* Speaker , */ \ + { 0xb0, \ + "ACS" }, /* cold start flag , */ \ + { 0xc0, \ + "SWS" }, /* flag engage , */ \ + { 0xd0, \ + "WDS" }, /* flag watchdog reset , */ \ + { 0xe0, \ + "AMPS" }, /* amplifier is enabled by manager , */ \ + { 0xf0, \ + "AREFS" }, /* references are enabled by manager , */ \ + { 0x109, \ + "BATS" }, /* Battery voltage readout; 0[V]..5.5[V] , */ \ + { 0x208, \ + "TEMPS" }, /* Temperature readout , */ \ + { 0x307, \ + "REV" }, /* Device Revision , */ \ + { 0x402, \ + "I2SF" }, /* I2SFormat data 1 input , */ \ + { 0x431, \ + "CHS12" }, /* ChannelSelection data1 input (In CoolFlux) , */ \ + { 0x450, \ + "CHS3" }, /* Channel Selection data 2 input (coolflux input, the DCDC converter gets the other signal), */ \ + { 0x461, \ + "CHSA" }, /* Input selection for amplifier , */ \ + { 0x481, \ + "I2SDOC" }, /* Selection for I2S data out , */ \ + { 0x4a0, \ + "DISP" }, /* idp protection , */ \ + { 0x4b0, \ + "I2SDOE" }, /* Enable data output , */ \ + { 0x4c3, \ + "I2SSR" }, /* sample rate setting , */ \ + { 0x501, \ + "BSSCR" }, /* ProtectionAttackTime , */ \ + { 0x523, \ + "BSST" }, /* ProtectionThreshold , */ \ + { 0x561, \ + "BSSRL" }, /* ProtectionMaximumReduction , */ \ + { 0x582, \ + "BSSRR" }, /* Protection Release Timer , */ \ + { 0x5b1, \ + "BSSHY" }, /* ProtectionHysterese , */ \ + { 0x5e0, \ + "BSSR" }, /* battery voltage for I2C read out only , */ \ + { 0x5f0, \ + "BSSBY" }, /* bypass clipper battery protection , */ \ + { 0x600, \ + "DPSA" }, /* Enable dynamic powerstage activation , */ \ + { 0x613, \ + "AMPSL" }, /* control slope , */ \ + { 0x650, \ + "CFSM" }, /* Soft mute in CoolFlux , */ \ + { 0x670, \ + "BSSS" }, /* batsensesteepness , */ \ + { 0x687, \ + "VOL" }, /* volume control (in CoolFlux) , */ \ + { 0x702, \ + "DCVO" }, /* Boost voltage , */ \ + { 0x732, \ + "DCMCC" }, /* Max boost coil current , */ \ + { 0x7a0, \ + "DCIE" }, /* Adaptive boost mode , */ \ + { 0x7b0, \ + "DCSR" }, /* Soft RampUp/Down mode for DCDC controller , */ \ + { 0x800, \ + "TROS" }, /* select external temperature also the ext_temp will be put on the temp read out , */ \ + { 0x818, \ + "EXTTS" }, /* external temperature setting to be given by host , */ \ + { 0x900, \ + "PWDN" }, /* ON/OFF , */ \ + { 0x910, \ + "I2CR" }, /* I2CReset , */ \ + { 0x920, \ + "CFE" }, /* EnableCoolFlux , */ \ + { 0x930, \ + "AMPE" }, /* EnableAmplifier , */ \ + { 0x940, \ + "DCA" }, /* EnableBoost , */ \ + { 0x950, \ + "SBSL" }, /* Coolflux configured , */ \ + { 0x960, \ + "AMPC" }, /* Selection on how AmplifierEnabling , */ \ + { 0x970, \ + "DCDIS" }, /* DCDC not connected , */ \ + { 0x980, \ + "PSDR" }, /* Iddq test amplifier , */ \ + { 0x991, \ + "DCCV" }, /* Coil Value , */ \ + { 0x9b1, \ + "CCFD" }, /* Selection CoolFluxClock , */ \ + { 0x9d0, \ + "ISEL" }, /* Interface Selection , */ \ + { 0x9e0, \ + "IPLL" }, /* selection input PLL for lock , */ \ + { 0xa02, \ + "DOLS" }, /* Output selection dataout left channel , */ \ + { 0xa32, \ + "DORS" }, /* Output selection dataout right channel , */ \ + { 0xa62, \ + "SPKL" }, /* Selection speaker induction , */ \ + { 0xa91, \ + "SPKR" }, /* Selection speaker impedance , */ \ + { 0xab3, \ + "DCFG" }, /* DCDC speaker current compensation gain , */ \ + { 0xb07, \ + "MTPK" }, /* MTP KEY2 register , */ \ + { 0xf00, \ + "VDDD" }, /* mask flag_por for interupt generation , */ \ + { 0xf10, \ + "OTDD" }, /* mask flag_otpok for interupt generation , */ \ + { 0xf20, \ + "OVDD" }, /* mask flag_ovpok for interupt generation , */ \ + { 0xf30, \ + "UVDD" }, /* mask flag_uvpok for interupt generation , */ \ + { 0xf40, \ + "OCDD" }, /* mask flag_ocp_alarm for interupt generation , */ \ + { 0xf50, \ + "CLKD" }, /* mask flag_clocks_stable for interupt generation , */ \ + { 0xf60, \ + "DCCD" }, /* mask flag_pwrokbst for interupt generation , */ \ + { 0xf70, \ + "SPKD" }, /* mask flag_cf_speakererror for interupt generation , */ \ + { 0xf80, \ + "WDD" }, /* mask flag_watchdog_reset for interupt generation , */ \ + { 0xfe0, \ + "INT" }, /* enabling interrupt , */ \ + { 0xff0, \ + "INTP" }, /* Setting polarity interupt , */ \ + { 0x1000, \ + "PDMSEL" }, /* Audio input interface mode , */ \ + { 0x1010, \ + "I2SMOUTEN" }, /* I2S Master enable (CLK and WS pads) , */ \ + { 0x1021, \ + "PDMORSEL" }, /* PDM Output right channel source selection , */ \ + { 0x1041, \ + "PDMOLSEL" }, /* PDM Output Left/Mono channel source selection , */ \ + { 0x1061, \ + "PADSEL" }, /* Output interface mode and ball selection , */ \ + { 0x1100, \ + "PDMOSDEN" }, /* Secure delay Cell , */ \ + { 0x1110, \ + "PDMOSDCF" }, /* Rising Falling Resync control Mux , */ \ + { 0x1140, \ + "SAAMEN" }, /* Speaker As a Mic feature ON/OFF , */ \ + { 0x1150, \ + "SAAMLPEN" }, /* speaker_as_mic low power mode (only in PDM_out mode), */ \ + { 0x1160, \ + "PDMOINTEN" }, /* PDM output interpolation ratio , */ \ + { 0x1203, \ + "PDMORG1" }, /* PDM Interpolator Right Channel DS4 G1 Gain Value , */ \ + { 0x1243, \ + "PDMORG2" }, /* PDM Interpolator Right Channel DS4 G2 Gain Value , */ \ + { 0x1303, \ + "PDMOLG1" }, /* PDM Interpolator Left Channel DS4 G1 Gain Value , */ \ + { 0x1343, \ + "PDMOLG2" }, /* PDM Interpolator Left Channel DS4 G2 Gain Value , */ \ + { 0x2202, \ + "SAAMGAIN" }, /* pga gain , */ \ + { 0x2250, \ + "SAAMPGACTRL" }, /* 0 = active input common mode voltage source at the attenuator/PGA level, */ \ + { 0x2500, \ + "PLLCCOSEL" }, /* pll cco frequency , */ \ + { 0x4600, \ + "CSBYPGC" }, /* bypass_gc, bypasses the CS gain correction , */ \ + { 0x4900, \ + "CLIP" }, /* Bypass clip control (function depending on digimux clip_x), */ \ + { 0x4910, \ + "CLIP2" }, /* Bypass clip control (function depending on digimux clip_x), */ \ + { 0x62b0, \ + "CIMTP" }, /* start copying all the data from i2cregs_mtp to mtp [Key 2 protected], */ \ + { 0x7000, \ + "RST" }, /* Reset CoolFlux DSP , */ \ + { 0x7011, \ + "DMEM" }, /* Target memory for access , */ \ + { 0x7030, \ + "AIF" }, /* Autoincrement-flag for memory-address , */ \ + { 0x7040, \ + "CFINT" }, /* Interrupt CoolFlux DSP , */ \ + { 0x7087, \ + "REQ" }, /* request for access (8 channels) , */ \ + { 0x710f, \ + "MADD" }, /* memory-address to be accessed , */ \ + { 0x720f, \ + "MEMA" }, /* activate memory access (24- or 32-bits data is written/read to/from memory, */ \ + { 0x7307, \ + "ERR" }, /* cf error Flags , */ \ + { 0x7387, \ + "ACK" }, /* acknowledge of requests (8 channels")" , */ \ + { 0x8000, \ + "MTPOTC" }, /* Calibration schedule (key2 protected) , */ \ + { 0x8010, \ + "MTPEX" }, /* (key2 protected) calibration of Ron has been executed, */ \ + { 0x8045, "SWPROFIL" }, \ + { 0x80a5, "SWVSTEP" }, \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +#define TFA9891_BITNAMETABLE \ + static tfaBfName_t Tfa9891BitNames[] = { \ + { 0x0, \ + "POR" }, /* POR , */ \ + { 0x10, \ + "PLL_LOCK" }, /* PLL , */ \ + { 0x20, \ + "flag_otpok" }, /* OTP , */ \ + { 0x30, \ + "flag_ovpok" }, /* OVP , */ \ + { 0x40, \ + "flag_uvpok" }, /* UVP , */ \ + { 0x50, \ + "flag_OCP_alarm" }, /* OCP , */ \ + { 0x60, \ + "flag_clocks_stable" }, /* Clocks , */ \ + { 0x70, \ + "CLIP" }, /* CLIP , */ \ + { 0x80, \ + "mtp_busy" }, /* MTP , */ \ + { 0x90, \ + "flag_pwrokbst" }, /* BOOST , */ \ + { 0xa0, \ + "flag_cf_speakererror" }, /* Speaker , */ \ + { 0xb0, \ + "flag_cold_started" }, /* cold start flag , */ \ + { 0xc0, \ + "flag_engage" }, /* flag engage , */ \ + { 0xd0, \ + "flag_watchdog_reset" }, /* flag watchdog reset , */ \ + { 0xe0, \ + "flag_enbl_amp" }, /* amplifier is enabled by manager , */ \ + { 0xf0, \ + "flag_enbl_ref" }, /* references are enabled by manager , */ \ + { 0x109, \ + "bat_adc" }, /* Battery voltage readout; 0[V]..5.5[V] , */ \ + { 0x208, \ + "temp_adc" }, /* Temperature readout , */ \ + { 0x307, \ + "rev_reg" }, /* Device Revision , */ \ + { 0x402, \ + "i2s_seti" }, /* I2SFormat data 1 input , */ \ + { 0x431, \ + "chan_sel1" }, /* ChannelSelection data1 input (In CoolFlux) , */ \ + { 0x450, \ + "lr_sw_i2si2" }, /* Channel Selection data 2 input (coolflux input, the DCDC converter gets the other signal), */ \ + { 0x461, \ + "input_sel" }, /* Input selection for amplifier , */ \ + { 0x481, \ + "datao_sel" }, /* Selection for I2S data out , */ \ + { 0x4a0, \ + "disable_idp" }, /* idp protection , */ \ + { 0x4b0, \ + "enbl_datao" }, /* Enable data output , */ \ + { 0x4c3, \ + "i2s_fs" }, /* sample rate setting , */ \ + { 0x501, \ + "vbat_prot_attacktime" }, /* ProtectionAttackTime , */ \ + { 0x523, \ + "vbat_prot_thlevel" }, /* ProtectionThreshold , */ \ + { 0x561, \ + "vbat_prot_max_reduct" }, /* ProtectionMaximumReduction , */ \ + { 0x582, \ + "vbat_prot_release_t" }, /* Protection Release Timer , */ \ + { 0x5b1, \ + "vbat_prot_hysterese" }, /* ProtectionHysterese , */ \ + { 0x5d0, \ + "reset_min_vbat" }, /* reset clipper , */ \ + { 0x5e0, \ + "sel_vbat" }, /* battery voltage for I2C read out only , */ \ + { 0x5f0, \ + "bypass_clipper" }, /* bypass clipper battery protection , */ \ + { 0x600, \ + "dpsa" }, /* Enable dynamic powerstage activation , */ \ + { 0x613, \ + "ctrl_slope" }, /* control slope , */ \ + { 0x650, \ + "cf_mute" }, /* Soft mute in CoolFlux , */ \ + { 0x660, \ + "sel_other_vamp" }, /* Input selection for the second channel of the DCDC inteligent mode detector, */ \ + { 0x670, \ + "ctrl_batsensesteepness" }, /* batsensesteepness , */ \ + { 0x687, \ + "vol" }, /* volume control (in CoolFlux) , */ \ + { 0x702, \ + "ctrl_bstvolt" }, /* Boost voltage , */ \ + { 0x732, \ + "ctrl_bstcur" }, /* Max boost coil current , */ \ + { 0x761, \ + "ctrl_slopebst_1_0" }, /* Setting for the slope of the boost converter power stage, */ \ + { 0x781, \ + "ctrl_slopebst_3_2" }, /* Setting for the part of the power transistor voltage to be used in peak current mode control, */ \ + { 0x7a0, \ + "boost_intel" }, /* Adaptive boost mode , */ \ + { 0x7b0, \ + "boost_speed" }, /* Soft RampUp/Down mode for DCDC controller , */ \ + { 0x7c1, \ + "ctrl_delay_comp_dcdc" }, /* delay compensation in current patg compared to delay in the audio path (relative) , */ \ + { 0x7e0, \ + "boost_input" }, /* Selection intelligent boost detector input , */ \ + { 0x7f0, \ + "ctrl_supplysense" }, /* ADC10 input selection , */ \ + { 0x800, \ + "ext_temp_sel" }, /* select external temperature also the ext_temp will be put on the temp read out , */ \ + { 0x818, \ + "ext_temp" }, /* external temperature setting to be given by host , */ \ + { 0x8a0, \ + "ctrl_spk_coilpvp_bst" }, /* Peak voltage protection boost converter , */ \ + { 0x8b2, \ + "ctrl_dcdc_synchronisation" }, /* DCDC synchronisation off + 7 positions , */ \ + { 0x8e0, \ + "ctrl_cs_samplevalid" }, /* sample valid moment for CS in single sample moment mode, */ \ + { 0x900, \ + "PowerDown" }, /* ON/OFF , */ \ + { 0x910, \ + "reset" }, /* I2CReset , */ \ + { 0x920, \ + "enbl_coolflux" }, /* EnableCoolFlux , */ \ + { 0x930, \ + "enbl_amplifier" }, /* EnableAmplifier , */ \ + { 0x940, \ + "enbl_boost" }, /* EnableBoost , */ \ + { 0x950, \ + "cf_configured" }, /* Coolflux configured , */ \ + { 0x960, \ + "sel_enbl_amplifier" }, /* Selection on how AmplifierEnabling , */ \ + { 0x970, \ + "dcdcoff_mode" }, /* DCDC not connected , */ \ + { 0x980, \ + "cttr_iddqtest" }, /* Iddq test amplifier , */ \ + { 0x991, \ + "ctrl_coil_value" }, /* Coil Value , */ \ + { 0x9b1, \ + "ctrl_sel_cf_clock" }, /* Selection CoolFluxClock , */ \ + { 0x9d0, \ + "intf_sel" }, /* Interface Selection , */ \ + { 0x9e0, \ + "sel_ws_bck" }, /* selection input PLL for lock , */ \ + { 0xa02, \ + "sel_i2so_l" }, /* Output selection dataout left channel , */ \ + { 0xa32, \ + "sel_i2so_r" }, /* Output selection dataout right channel , */ \ + { 0xa62, \ + "ctrl_spkr_coil" }, /* Selection speaker induction , */ \ + { 0xa91, \ + "ctrl_spr_res" }, /* Selection speaker impedance , */ \ + { 0xab3, \ + "ctrl_dcdc_spkr_i_comp_gain" }, /* DCDC speaker current compensation gain , */ \ + { 0xaf0, \ + "ctrl_dcdc_spkr_i_comp_sign" }, /* DCDC speaker current compensation sign , */ \ + { 0xb07, \ + "MTP_key2" }, /* MTP KEY2 register , */ \ + { 0xc0c, \ + "clk_sync_delay" }, /* Delay count for clock synchronisation , */ \ + { 0xcf0, \ + "enbl_clk_sync" }, /* Enable CGU clock synchronisation , */ \ + { 0xd0c, \ + "adc_sync_delay" }, /* Delay count for ADC synchronisation , */ \ + { 0xdf0, \ + "enable_adc_sync" }, /* Enable ADC synchronisation , */ \ + { 0xe00, \ + "bypass_dcdc_curr_prot" }, /* to switch off dcdc reduction with bat prot , */ \ + { 0xe24, \ + "ctrl_digtoana6_2" }, /* for extra connections digital to analog , */ \ + { 0xe70, \ + "switch_on_icomp" }, /* icomp dem switch , */ \ + { 0xe87, \ + "reserve_reg_1_7_0" }, /* reserved , */ \ + { 0xf00, \ + "flag_por_mask" }, /* mask flag_por for interupt generation , */ \ + { 0xf10, \ + "flag_otpok_mask" }, /* mask flag_otpok for interupt generation , */ \ + { 0xf20, \ + "flag_ovpok_mask" }, /* mask flag_ovpok for interupt generation , */ \ + { 0xf30, \ + "flag_uvpok_mask" }, /* mask flag_uvpok for interupt generation , */ \ + { 0xf40, \ + "flag_ocp_alarm_mask" }, /* mask flag_ocp_alarm for interupt generation , */ \ + { 0xf50, \ + "flag_clocks_stable_mask" }, /* mask flag_clocks_stable for interupt generation , */ \ + { 0xf60, \ + "flag_pwrokbst_mask" }, /* mask flag_pwrokbst for interupt generation , */ \ + { 0xf70, \ + "flag_cf_speakererror_mask" }, /* mask flag_cf_speakererror for interupt generation , */ \ + { 0xf80, \ + "flag_watchdog_reset_mask" }, /* mask flag_watchdog_reset for interupt generation , */ \ + { 0xf90, \ + "flag_lost_clk_mask" }, /* mask flag_lost_clk for interupt generation , */ \ + { 0xfe0, \ + "enable_interrupt" }, /* enabling interrupt , */ \ + { 0xff0, \ + "invert_int_polarity" }, /* Setting polarity interupt , */ \ + { 0x1000, \ + "pdm_i2s_input" }, /* Audio input interface mode , */ \ + { 0x1010, \ + "I2S_master_ena" }, /* I2S Master enable (CLK and WS pads) , */ \ + { 0x1021, \ + "pdm_out_sel_r" }, /* PDM Output right channel source selection , */ \ + { 0x1041, \ + "pdm_out_sel_l" }, /* PDM Output Left/Mono channel source selection , */ \ + { 0x1061, \ + "micdat_out_sel" }, /* Output interface mode and ball selection , */ \ + { 0x1100, \ + "secure_dly" }, /* Secure delay Cell , */ \ + { 0x1110, \ + "d_out_valid_rf_mux" }, /* Rising Falling Resync control Mux , */ \ + { 0x1140, \ + "Speak_As_Mic_en" }, /* Speaker As a Mic feature ON/OFF , */ \ + { 0x1150, \ + "speak_as_mic_lp_mode" }, /* speaker_as_mic low power mode (only in PDM_out mode), */ \ + { 0x1160, \ + "pdm_out_rate" }, /* PDM output interpolation ratio , */ \ + { 0x1203, \ + "ds4_g1_r" }, /* PDM Interpolator Right Channel DS4 G1 Gain Value , */ \ + { 0x1243, \ + "ds4_g2_r" }, /* PDM Interpolator Right Channel DS4 G2 Gain Value , */ \ + { 0x1303, \ + "ds4_g1_l" }, /* PDM Interpolator Left Channel DS4 G1 Gain Value , */ \ + { 0x1343, \ + "ds4_g2_l" }, /* PDM Interpolator Left Channel DS4 G2 Gain Value , */ \ + { 0x1400, \ + "clk_secure_dly" }, /* Secure delay Cell on clock path , */ \ + { 0x1410, \ + "data_secure_dly" }, /* Secure delay Cell enable on PDM data path , */ \ + { 0x2202, \ + "Ctrl_saam_pga_gain" }, /* pga gain , */ \ + { 0x2250, \ + "ctrl_saam_pga_src" }, /* 0 = active input common mode voltage source at the attenuator/PGA level, */ \ + { 0x2300, \ + "flag_saam_spare" }, /* spare flag , */ \ + { 0x2400, \ + "ctrl_saam_pga_tm" }, /* enables PGA test mode , */ \ + { 0x2500, \ + "pll_fcco" }, /* pll cco frequency , */ \ + { 0x3000, \ + "flag_hi_small" }, /* positive small window dcdc converter , */ \ + { 0x3010, \ + "flag_hi_large" }, /* positive large window dcdc converter , */ \ + { 0x3020, \ + "flag_lo_small" }, /* negative small window dcdc converter , */ \ + { 0x3030, \ + "flag_lo_large" }, /* negative large window dcdc converter , */ \ + { 0x3040, \ + "flag_voutcomp" }, /* flag_voutcomp, indication Vset is larger than Vbat, */ \ + { 0x3050, \ + "flag_voutcomp93" }, /* flag_voutcomp93, indication Vset is larger than 1.07* Vbat , */ \ + { 0x3060, \ + "flag_voutcomp86" }, /* flag_voutcomp86, indication Vset is larger than 1.14* Vbat , */ \ + { 0x3070, \ + "flag_hiz" }, /* flag_hiz, indication Vbst is larger than Vbat , */ \ + { 0x3080, \ + "flag_hi_peak" }, /* flag_hi_peak, indication hi_peak , */ \ + { 0x3090, \ + "flag_ocpokbst" }, /* flag_ocpokbst, indication no over current in boost converter pmos switch, */ \ + { 0x30a0, \ + "flag_peakcur" }, /* flag_peakcur, indication current is max in dcdc converter, */ \ + { 0x30b0, \ + "flag_ocpokap" }, /* flag_ocpokap, indication no over current in amplifier "a" pmos output stage, */ \ + { 0x30c0, \ + "flag_ocpokan" }, /* flag_ocpokan, indication no over current in amplifier "a" nmos output stage, */ \ + { 0x30d0, \ + "flag_ocpokbp" }, /* flag_ocpokbp, indication no over current in amplifier "b" pmos output stage, */ \ + { 0x30e0, \ + "flag_ocpokbn" }, /* flag_ocpokbn, indication no over current in amplifier"b" nmos output stage, */ \ + { 0x30f0, \ + "lost_clk" }, /* lost_clk, lost clock indication CGU , */ \ + { 0x310f, \ + "mtp_man_data_out" }, /* single word read from MTP (manual copy) , */ \ + { 0x3200, \ + "key01_locked" }, /* key01_locked, indication key 1 is locked , */ \ + { 0x3210, \ + "key02_locked" }, /* key02_locked, indication key 2 is locked , */ \ + { 0x3225, \ + "mtp_ecc_tcout" }, /* mtp_ecc_tcout , */ \ + { 0x3280, \ + "mtpctrl_valid_test_rd" }, /* mtp test readout for read , */ \ + { 0x3290, \ + "mtpctrl_valid_test_wr" }, /* mtp test readout for write , */ \ + { 0x32a0, \ + "flag_in_alarm_state" }, /* alarm state , */ \ + { 0x32b0, \ + "mtp_ecc_err2" }, /* two or more bit errors detected in MTP, can not reconstruct value, */ \ + { 0x32c0, \ + "mtp_ecc_err1" }, /* one bit error detected in MTP, reconstructed value, */ \ + { 0x32d0, \ + "mtp_mtp_hvf" }, /* high voltage ready flag for MTP , */ \ + { 0x32f0, \ + "mtp_zero_check_fail" }, /* zero check failed (tbd) for MTP , */ \ + { 0x3300, \ + "flag_adc10_ready" }, /* flag_adc10_ready, indication adc10 is ready , */ \ + { 0x3310, \ + "flag_clipa_high" }, /* flag_clipa_high, indication pmos amplifier "a" is clipping, */ \ + { 0x3320, \ + "flag_clipa_low" }, /* flag_clipa_low, indication nmos amplifier "a" is clipping, */ \ + { 0x3330, \ + "flag_clipb_high" }, /* flag_clipb_high, indication pmos amplifier "b" is clipping, */ \ + { 0x3340, \ + "flag_clipb_low" }, /* flag_clipb_low, indication nmos amplifier "b" is clipping, */ \ + { 0x3359, \ + "data_adc10_tempbat" }, /* adc 10 data output for testing , */ \ + { 0x33f0, \ + "flag_vddd_comp_nok" }, /* power switch flag 2 for testing , */ \ + { 0x400f, \ + "hid_code" }, /* hidden code , */ \ + { 0x4100, \ + "bypass_hp" }, /* Bypass_High Pass Filter , */ \ + { 0x4110, \ + "hard_mute" }, /* Hard Mute , */ \ + { 0x4120, \ + "soft_mute" }, /* Soft Mute , */ \ + { 0x4134, \ + "PWM_Delay" }, /* PWM DelayBits to set the delay , */ \ + { 0x4180, \ + "PWM_Shape" }, /* PWM Shape , */ \ + { 0x4190, \ + "PWM_BitLength" }, /* PWM Bitlength in noise shaper , */ \ + { 0x4207, \ + "ctrl_drive" }, /* drive bits to select amount of power stages amplifier, */ \ + { 0x4281, \ + "dpsalevel" }, /* DPSA Threshold level , */ \ + { 0x42a1, \ + "dpsa_release" }, /* DPSA Release time , */ \ + { 0x42c0, \ + "ctrl_coincidence" }, /* Prevent simultaneously switching of output stage , */ \ + { 0x42d0, \ + "ctrl_kickback" }, /* Prevent double pulses of output stage , */ \ + { 0x42e0, \ + "ctrl_test_sdeltaoffset" }, /* ctrl_test_sdeltaoffset , */ \ + { 0x42f0, \ + "ctrl_test_sdeltaclk" }, /* ctrl_test_sdeltaclk , */ \ + { 0x4309, \ + "ctrl_drivebst" }, /* Drive bits to select the powertransistor sections boost converter, */ \ + { 0x43a0, \ + "ctrl_ocptestbst" }, /* Boost OCP. , */ \ + { 0x43c0, \ + "enbl_hi_peak" }, /* enable for high peak comparator , */ \ + { 0x43d0, \ + "test_abistfft_enbl" }, /* FFT coolflux , */ \ + { 0x43e0, \ + "ctrl_sensetest_amp" }, /* sensetest amplifier , */ \ + { 0x43f0, \ + "test_bcontrol" }, /* test _bcontrol , */ \ + { 0x4400, \ + "ctrl_reversebst" }, /* OverCurrent Protection selection of power stage boost converter, */ \ + { 0x4410, \ + "ctrl_sensetest" }, /* Test option for the sense NMOS in booster for current mode control., */ \ + { 0x4420, \ + "enbl_engagebst" }, /* Enable power stage dcdc controller , */ \ + { 0x4430, \ + "enbl_hi_small" }, /* Enable bit of hi (small) comparator , */ \ + { 0x4440, \ + "enbl_hi_large" }, /* Enable bit of hi (large) comparator , */ \ + { 0x4450, \ + "enbl_lo_small" }, /* Enable bit of lo (small) comparator , */ \ + { 0x4460, \ + "enbl_lo_large" }, /* Enable bit of lo (large) comparator , */ \ + { 0x4470, \ + "enbl_slopecur" }, /* Enable bit of max-current dac , */ \ + { 0x4480, \ + "enbl_voutcomp" }, /* Enable vout comparators , */ \ + { 0x4490, \ + "enbl_voutcomp93" }, /* Enable vout-93 comparators , */ \ + { 0x44a0, \ + "enbl_voutcomp86" }, /* Enable vout-86 comparators , */ \ + { 0x44b0, \ + "enbl_hizcom" }, /* Enable hiz comparator , */ \ + { 0x44c0, \ + "enbl_pcdac" }, /* Enable peak current dac , */ \ + { 0x44d0, \ + "enbl_pccomp" }, /* Enable peak current comparator , */ \ + { 0x44e0, \ + "enbl_windac" }, /* Enable window dac , */ \ + { 0x44f0, \ + "enbl_powerbst" }, /* Enable line of the powerstage , */ \ + { 0x4507, \ + "ocp_thr" }, /* ocp_thr threshold level for OCP , */ \ + { 0x4580, \ + "bypass_glitchfilter" }, /* Bypass glitchfilter , */ \ + { 0x4590, \ + "bypass_ovp" }, /* Bypass OVP , */ \ + { 0x45a0, \ + "bypass_uvp" }, /* Bypass UVP , */ \ + { 0x45b0, \ + "bypass_otp" }, /* Bypass OTP , */ \ + { 0x45c0, \ + "bypass_ocp" }, /* Bypass OCP , */ \ + { 0x45d0, \ + "bypass_ocpcounter" }, /* BypassOCPCounter , */ \ + { 0x45e0, \ + "bypass_lost_clk" }, /* Bypasslost_clk detector , */ \ + { 0x45f0, \ + "vpalarm" }, /* vpalarm (uvp ovp handling) , */ \ + { 0x4600, \ + "bypass_gc" }, /* bypass_gc, bypasses the CS gain correction , */ \ + { 0x4610, \ + "cs_gain_control" }, /* gain control by means of MTP or i2c , */ \ + { 0x4627, \ + "cs_gain" }, /* + / - 128 steps in steps of 1/4 % 2's compliment , */ \ + { 0x46a0, \ + "bypass_lp" }, /* bypass Low-Pass filter in temperature sensor , */ \ + { 0x46b0, \ + "bypass_pwmcounter" }, /* bypass_pwmcounter , */ \ + { 0x46c0, \ + "ctrl_cs_negfixed" }, /* does not switch to neg , */ \ + { 0x46d2, \ + "ctrl_cs_neghyst" }, /* switches to neg depending on level , */ \ + { 0x4700, \ + "switch_fb" }, /* switch_fb , */ \ + { 0x4713, \ + "se_hyst" }, /* se_hyst , */ \ + { 0x4754, \ + "se_level" }, /* se_level , */ \ + { 0x47a5, \ + "ktemp" }, /* temperature compensation trimming , */ \ + { 0x4800, \ + "ctrl_negin" }, /* negin , */ \ + { 0x4810, \ + "ctrl_cs_sein" }, /* cs_sein , */ \ + { 0x4820, \ + "ctrl_coincidencecs" }, /* Coincidence current sense , */ \ + { 0x4830, \ + "ctrl_iddqtestbst" }, /* for iddq testing in powerstage of boost convertor , */ \ + { 0x4840, \ + "ctrl_coincidencebst" }, /* Switch protection on to prevent simultaniously switching power stages bst and amp, */ \ + { 0x4851, \ + "clock_sh_sel" }, /* Clock SH selection , */ \ + { 0x4876, \ + "delay_se_neg" }, /* delay of se and neg , */ \ + { 0x48e1, \ + "ctrl_cs_ttrack" }, /* sample & hold track time , */ \ + { 0x4900, \ + "ctrl_bypassclip" }, /* Bypass clip control (function depending on digimux clip_x), */ \ + { 0x4910, \ + "ctrl_bypassclip2" }, /* Bypass clip control (function depending on digimux clip_x), */ \ + { 0x4920, \ + "ctrl_clkgateCFoff" }, /* to disable clock gating in the coolflux , */ \ + { 0x4930, \ + "ctrl_testabst" }, /* testabst , */ \ + { 0x4940, \ + "ctrl_clipfast" }, /* clock switch for battery protection clipper, it switches back to old frequency, */ \ + { 0x4950, \ + "ctrl_cs_8ohm" }, /* 8 ohm mode for current sense (gain mode) , */ \ + { 0x4960, \ + "reserved" }, /* reserved , */ \ + { 0x4974, \ + "delay_clock_sh" }, /* delay_sh, tunes S7H delay , */ \ + { 0x49c0, \ + "inv_clksh" }, /* Invert the sample/hold clock for current sense ADC, */ \ + { 0x49d0, \ + "inv_neg" }, /* Invert neg signal , */ \ + { 0x49e0, \ + "inv_se" }, /* Invert se signal , */ \ + { 0x49f0, \ + "setse" }, /* switches between Single Ende and differentail mode, */ \ + { 0x4a12, \ + "ctrl_adc10_sel" }, /* select the input to convert the 10b ADC , */ \ + { 0x4a60, \ + "ctrl_adc10_reset" }, /* Global asynchronous reset (active HIGH) 10 bit ADC, */ \ + { 0x4a81, \ + "ctrl_adc10_test" }, /* Test mode selection signal 10 bit ADC , */ \ + { 0x4aa0, \ + "ctrl_bypass_lp_vbat" }, /* lp filter in batt sensor , */ \ + { 0x4ae0, \ + "ctrl_dc_offset" }, /* switch offset control on/off, is decimator offset control, */ \ + { 0x4af0, \ + "ctrl_tsense_hibias" }, /* bit to set the biasing in temp sensor to high , */ \ + { 0x4b00, \ + "ctrl_adc13_iset" }, /* Micadc Setting of current consumption. Debug use only, */ \ + { 0x4b14, \ + "ctrl_adc13_gain" }, /* Micadc gain setting (2-compl) , */ \ + { 0x4b61, \ + "ctrl_adc13_slowdel" }, /* Micadc Delay setting for internal clock. Debug use only, */ \ + { 0x4b83, \ + "ctrl_adc13_offset" }, /* Micadc ADC offset setting , */ \ + { 0x4bc0, \ + "ctrl_adc13_bsoinv" }, /* Micadc bit stream output invert mode for test , */ \ + { 0x4bd0, \ + "ctrl_adc13_resonator_enable" }, /* Micadc Give extra SNR with less stability. Debug use only, */ \ + { 0x4be0, \ + "ctrl_testmicadc" }, /* Mux at input of MICADC for test purpose , */ \ + { 0x4c0f, \ + "ctrl_offset" }, /* offset control for ABIST testing , */ \ + { 0x4d05, \ + "ctrl_windac" }, /* for testing direct control windac , */ \ + { 0x4d65, \ + "ctrl_peakcur" }, /* Control peakcur , */ \ + { 0x4dc3, \ + "pwm_dcc_cnt" }, /* control pwm duty cycle when enbl_pwm_dcc is 1 , */ \ + { 0x4e04, \ + "ctrl_slopecur" }, /* for testing direct control slopecur , */ \ + { 0x4e53, \ + "ctrl_dem" }, /* dyn element matching control, rest of codes are optional, */ \ + { 0x4e93, \ + "ctrl_demmismatch" }, /* dyn element matching add offset , */ \ + { 0x4ed0, \ + "enbl_pwm_dcc" }, /* to enable direct control of pwm duty cycle , */ \ + { 0x5007, \ + "gain" }, /* gain setting of the gain multiplier gain need to increase with factor 1.41 (3dB), */ \ + { 0x5081, \ + "ctrl_sourceb" }, /* Set OUTB to , */ \ + { 0x50a1, \ + "ctrl_sourcea" }, /* Set OUTA to , */ \ + { 0x50c1, \ + "ctrl_sourcebst" }, /* Sets the source of the pwmbst output to boost converter input for testing, */ \ + { 0x50e1, \ + "ctrl_test_mono" }, /* ABIST mode to add both amplifier halfs as stereo or one amplifier half as mono, */ \ + { 0x5104, \ + "pulselengthbst" }, /* pulselength setting test input for boost converter , */ \ + { 0x5150, \ + "ctrl_bypasslatchbst" }, /* bypass_latch in boost converter , */ \ + { 0x5160, \ + "invertbst" }, /* invert pwmbst test signal , */ \ + { 0x5174, \ + "pulselength" }, /* pulselength setting test input for amplifier , */ \ + { 0x51c0, \ + "ctrl_bypasslatch" }, /* bypass_latch in boost convert , */ \ + { 0x51d0, \ + "invertb" }, /* invert pwmb test signal , */ \ + { 0x51e0, \ + "inverta" }, /* invert pwma test signal , */ \ + { 0x51f0, \ + "ctrl_bypass_ctrlloop" }, /* bypass_ctrlloop bypasses the control loop of the amplifier, */ \ + { 0x5200, \ + "ctrl_test_discrete" }, /* tbd for rdson testing , */ \ + { 0x5210, \ + "ctrl_test_rdsona" }, /* tbd for rdson testing , */ \ + { 0x5220, \ + "ctrl_test_rdsonb" }, /* tbd for rdson testing , */ \ + { 0x5230, \ + "ctrl_test_rdsonbst" }, /* tbd for rdson testing , */ \ + { 0x5240, \ + "ctrl_test_cvia" }, /* tbd for rdson testing , */ \ + { 0x5250, \ + "ctrl_test_cvib" }, /* tbd for rdson testing , */ \ + { 0x5260, \ + "ctrl_test_cvibst" }, /* tbd for rdson testing , */ \ + { 0x5290, \ + "test_bypass_pwmdiscretea" }, /* for testing ( ABIST) , */ \ + { 0x52a0, \ + "test_bypass_pwmdiscreteb" }, /* for testing ( ABIST) , */ \ + { 0x52b0, \ + "ctrl_clipc_forcehigh" }, /* test signal for clipcontrol , */ \ + { 0x52c0, \ + "ctrl_clipc_forcelow" }, /* test signal for clipcontrol , */ \ + { 0x52d0, \ + "ctrl_test_sdelta" }, /* for testing ( ABIST) , */ \ + { 0x52e0, \ + "ctrl_test_swhvp" }, /* for testing ( ABIST) , */ \ + { 0x52f0, \ + "test_gain_reduction" }, /* test gain reduction , */ \ + { 0x5303, \ + "ctrl_digimux_out_test1" }, /* Digimux TEST1 out , */ \ + { 0x5343, \ + "ctrl_digimux_out_test2" }, /* Digimux TEST2 out. output flag_clipa_low depending on cntr_bypassclip setting, */ \ + { 0x5383, \ + "ctrl_digimux_out_data1" }, /* Digimux DATA1 out (output flag_clipb_high depending on cntr_bypassclip setting), */ \ + { 0x53c3, \ + "ctrl_digimux_out_data3" }, /* Digimux DATA3 out (output flag_clipx_x depending on cntr_bypassclip setting), */ \ + { 0x5400, \ + "hs_mode" }, /* hs_mode, high speed mode I2C bus , */ \ + { 0x5412, \ + "test_parametric_io" }, /* test_parametric_io for testing pads , */ \ + { 0x5440, \ + "enbl_ringo" }, /* enbl_ringo, for test purpose to check with ringo , */ \ + { 0x5480, \ + "ctrl_cliplevel" }, /* Clip level , */ \ + { 0x5491, \ + "ctrl_anamux_sel" }, /* anamux selection , */ \ + { 0x54b0, \ + "test_vdddsw_dio" }, /* to overrule the power switches for memory , */ \ + { 0x54c0, \ + "ctrl_bypass_diosw_ovp" }, /* To disable the overvoltage protection of vddd_dio_sw, */ \ + { 0x54d0, \ + "test_vddd_sw" }, /* test vdd sw , */ \ + { 0x54e0, \ + "test_vddd_sw_comp" }, /* test vdd sw comp , */ \ + { 0x550e, \ + "enbl_amp" }, /* enbl_amp for testing to enable all analoge blocks in amplifier, */ \ + { 0x55f0, \ + "fr_fsp" }, /* extr free running clock mode for testing , */ \ + { 0x5600, \ + "use_direct_ctrls" }, /* use_direct_ctrls, to overrule several functions direct for testing, */ \ + { 0x5610, \ + "rst_datapath" }, /* rst_datapath, datapath reset , */ \ + { 0x5620, \ + "rst_cgu" }, /* rst_cgu, cgu reset , */ \ + { 0x5637, \ + "enbl_ref" }, /* for testing to enable all analoge blocks in references, */ \ + { 0x56b0, \ + "enbl_engage" }, /* Enable output stage amplifier , */ \ + { 0x56c0, \ + "use_direct_clk_ctrl" }, /* use_direct_clk_ctrl, to overrule several functions direct for testing, */ \ + { 0x56d0, \ + "use_direct_pll_ctrl" }, /* use_direct_pll_ctrl, to overrule several functions direct for test, */ \ + { 0x56e0, \ + "use_direct_ctrls_2" }, /* use_direct_sourseamp_ctrls, to overrule several functions direct for testing, */ \ + { 0x5707, \ + "ctrl_anamux_out_test1" }, /* Anamux control , */ \ + { 0x5782, \ + "ctrl_zero" }, /* Bandwith control feedbackloop , */ \ + { 0x57b0, \ + "enbl_ldo_stress" }, /* LDO stress function frinch capacitors , */ \ + { 0x57c0, \ + "ctrl_ocptest" }, /* ctrl_ocptest, deactivates the over current protection in the power stages of the amplifier. The ocp flag signals stay active., */ \ + { 0x57e0, \ + "ctrl_otptest" }, /* otptest, test mode otp amplifier , */ \ + { 0x57f0, \ + "ctrl_reverse" }, /* CTRL revers , */ \ + { 0x5802, \ + "pll_mdec_msb" }, /* most significant bits pll_mdec , */ \ + { 0x5833, \ + "pll_selr" }, /* pll_selr , */ \ + { 0x5874, \ + "pll_selp" }, /* pll_selp , */ \ + { 0x58c3, \ + "pll_seli" }, /* pll_seli , */ \ + { 0x5900, \ + "pll_psel" }, /* pll_psel , */ \ + { 0x5910, \ + "use_direct_pll_psel" }, /* use_direct_pll_psel , */ \ + { 0x5923, \ + "nbck" }, /* NBCK , */ \ + { 0x5960, \ + "auto_nbck" }, /* AUTO_NBCK , */ \ + { 0x5970, \ + "pll_frm" }, /* pll_frm , */ \ + { 0x5980, \ + "pll_directi" }, /* pll_directi , */ \ + { 0x5990, \ + "pll_directo" }, /* pll_directo , */ \ + { 0x59a0, \ + "enbl_PLL" }, /* enbl_PLL , */ \ + { 0x59b0, \ + "sel_clkout" }, /* SEL_CLKOUT , */ \ + { 0x59e0, \ + "fr_lost_clk" }, /* fr_lost_clk , */ \ + { 0x59f0, \ + "pll_bypass" }, /* pll_bypass , */ \ + { 0x5a0f, \ + "tsig_freq" }, /* tsig_freq, internal sinus test generator, frequency control, */ \ + { 0x5b02, \ + "tsig_freq_msb" }, /* select internal sinus test generator, frequency control msb bits, */ \ + { 0x5b30, \ + "inject_tsig" }, /* inject_tsig, control bit to switch to internal sinus test generator, */ \ + { 0x5b44, \ + "ctrl_adc10_prog_sample" }, /* control ADC10 , */ \ + { 0x5c01, \ + "pll_ndec_msb" }, /* most significant bits of pll_ndec , */ \ + { 0x5c2d, \ + "pll_mdec" }, /* bits 13..0 of pll_mdec , */ \ + { 0x5d06, \ + "pll_pdec" }, /* pll_pdec , */ \ + { 0x5d87, \ + "pll_ndec" }, /* bits 7..0 of pll_ndec , */ \ + { 0x5e00, \ + "pdm_ch_sel_reg" }, /* PDM channel selection , */ \ + { 0x5e10, \ + "pdm_iis_rst_reg" }, /* PDM Interface reset , */ \ + { 0x5e20, \ + "clk_src_sel_reg" }, /* WS Source Selection , */ \ + { 0x5e70, \ + "pdm_resync_bypass" }, /* PDM resynchronization bypass , */ \ + { 0x6007, \ + "MTP_key1" }, /* MTP Key1 , */ \ + { 0x6185, \ + "mtp_ecc_tcin" }, /* Mtp_ecc_tcin , */ \ + { 0x6203, \ + "mtp_man_address_in" }, /* address from i2cregs for writing one word single mtp, */ \ + { 0x6260, \ + "mtp_ecc_eeb" }, /* enable code bit generation (active low!) , */ \ + { 0x6270, \ + "mtp_ecc_ecb" }, /* enable correction signal (active low!) , */ \ + { 0x6280, \ + "man_copy_mtp_to_iic" }, /* start copying single word from mtp to i2cregs_mtp , */ \ + { 0x6290, \ + "man_copy_iic_to_mtp" }, /* start copying single word from i2cregs_mtp to mtp [Key 1 protected], */ \ + { 0x62a0, \ + "auto_copy_mtp_to_iic" }, /* start copying all the data from mtp to i2cregs_mtp, */ \ + { 0x62b0, \ + "auto_copy_iic_to_mtp" }, /* start copying all the data from i2cregs_mtp to mtp [Key 2 protected], */ \ + { 0x62d2, \ + "mtp_speed_mode" }, /* Speed mode , */ \ + { 0x6340, \ + "mtp_dircet_enable" }, /* mtp_direct_enable (key1 protected) , */ \ + { 0x6350, \ + "mtp_direct_wr" }, /* mtp_direct_wr (key1 protected) direct value for mtp pin wr. To be enabled via iic2mtp_mtp_direct_enable, */ \ + { 0x6360, \ + "mtp_direct_rd" }, /* mtp_direct_rd (key1 protected) direct value for mtp pin rd. To be enabled via iic2mtp_mtp_direct_enable, */ \ + { 0x6370, \ + "mtp_direct_rst" }, /* mtp_direct_rst (key1 protected) direct value for mtp pin rst. To be enabled via iic2mtp_mtp_direct_enable, */ \ + { 0x6380, \ + "mtp_direct_ers" }, /* mtp_direct_ers (key1 protected) direct value for mtp pin ers. To be enabled via iic2mtp_mtp_direct_enable, */ \ + { 0x6390, \ + "mtp_direct_prg" }, /* mtp_direct_prg (key1 protected) direct value for mtp pin prg. To be enabled via iic2mtp_mtp_direct_enable, */ \ + { 0x63a0, \ + "mtp_direct_epp" }, /* mtp_direct_epp (key1 protected) direct value for mtp pin epp. To be enabled via iic2mtp_mtp_direct_enable, */ \ + { 0x63b4, \ + "mtp_direct_test" }, /* mtp_direct_test (key1 protected) , */ \ + { 0x640f, \ + "mtp_man_data_in" }, /* single wordt be written to MTP (manual copy) , */ \ + { 0x7000, \ + "cf_rst_dsp" }, /* Reset CoolFlux DSP , */ \ + { 0x7011, \ + "cf_dmem" }, /* Target memory for access , */ \ + { 0x7030, \ + "cf_aif" }, /* Autoincrement-flag for memory-address , */ \ + { 0x7040, \ + "cf_int" }, /* Interrupt CoolFlux DSP , */ \ + { 0x7087, \ + "cf_req" }, /* request for access (8 channels) , */ \ + { 0x710f, \ + "cf_madd" }, /* memory-address to be accessed , */ \ + { 0x720f, \ + "cf_mema" }, /* activate memory access (24- or 32-bits data is written/read to/from memory, */ \ + { 0x7307, \ + "cf_err" }, /* cf error Flags , */ \ + { 0x7387, \ + "cf_ack" }, /* acknowledge of requests (8 channels")" , */ \ + { 0x8000, \ + "calibration_onetime" }, /* Calibration schedule (key2 protected) , */ \ + { 0x8010, \ + "calibr_ron_done" }, /* (key2 protected) calibration of Ron has been executed, */ \ + { 0x8105, \ + "calibr_vout_offset" }, /* calibr_vout_offset (DCDCoffset) 2's compliment (key1 protected), */ \ + { 0x8163, \ + "calibr_delta_gain" }, /* delta gain for vamp (alpha) 2's compliment (key1 protected), */ \ + { 0x81a5, \ + "calibr_offs_amp" }, /* offset for vamp (Ampoffset) 2's compliment (key1 protected), */ \ + { 0x8207, \ + "calibr_gain_cs" }, /* gain current sense (Imeasalpha) 2's compliment (key1 protected), */ \ + { 0x8284, \ + "calibr_temp_offset" }, /* temperature offset 2's compliment (key1 protected), */ \ + { 0x82d2, \ + "calibr_temp_gain" }, /* temperature gain 2's compliment (key1 protected) , */ \ + { 0x830f, \ + "calibr_ron" }, /* Ron resistance of coil (key1 protected) , */ \ + { 0x8406, \ + "ctrl_offset_a" }, /* Offset of amplifier level shifter , */ \ + { 0x8486, \ + "ctrl_offset_b" }, /* Offset of amplifier level shifter , */ \ + { 0x850f, \ + "type_bits_HW" }, /* HW Bits , */ \ + { 0x860f, \ + "type_bits1_SW" }, /* MTP-control SW1 , */ \ + { 0x870f, \ + "type_bits2_SW" }, /* MTP-control SW2 , */ \ + { 0x8a0f, \ + "production_data1" }, /* (key1 protected) , */ \ + { 0x8b0f, \ + "production_data2" }, /* (key1 protected) , */ \ + { 0x8c0f, \ + "production_data3" }, /* (key1 protected) , */ \ + { 0x8d0f, \ + "production_data4" }, /* (key1 protected) , */ \ + { 0x8e0f, \ + "production_data5" }, /* (key1 protected) , */ \ + { 0x8f0f, \ + "production_data6" }, /* (key1 protected) , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +#endif /* TFA_INC_TFA9891_TFAFIELDNAMES_H_ */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9894_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9894_tfafieldnames.h new file mode 100644 index 000000000000..6f1df93a17ba --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9894_tfafieldnames.h @@ -0,0 +1,2102 @@ +/** Filename: tfa9894_tfaFieldnames.h + * This file was generated automatically on 09/06/17 at 14:51:37. + * Source file: TFA9894_N1A1_I2C_RegisterMap.xlsx + */ + +#ifndef _TFA9894_TFAFIELDNAMES_H +#define _TFA9894_TFAFIELDNAMES_H + +#define TFA9894_I2CVERSION 7 + +typedef enum nxpTfa9894BfEnumList { + TFA9894_BF_PWDN = + 0x0000, /*!< Powerdown control */ + TFA9894_BF_I2CR = + 0x0010, /*!< I2C Reset - Auto clear */ + TFA9894_BF_CFE = + 0x0020, /*!< Enable CoolFlux DSP */ + TFA9894_BF_AMPE = + 0x0030, /*!< Enable Amplifier */ + TFA9894_BF_DCA = + 0x0040, /*!< Enable DCDC Boost converter */ + TFA9894_BF_SBSL = + 0x0050, /*!< Coolflux configured */ + TFA9894_BF_AMPC = + 0x0060, /*!< CoolFlux control over amplifier */ + TFA9894_BF_INTP = + 0x0071, /*!< Interrupt config */ + TFA9894_BF_FSSSEL = + 0x0090, /*!< Audio sample reference */ + TFA9894_BF_BYPOCP = + 0x00a0, /*!< Bypass OCP */ + TFA9894_BF_TSTOCP = + 0x00b0, /*!< OCP testing control */ + TFA9894_BF_BSSS = + 0x00c0, /*!< Vbat protection steepness */ + TFA9894_BF_HPFBYP = + 0x00d0, /*!< Bypass High Pass Filter */ + TFA9894_BF_DPSA = + 0x00e0, /*!< Enable DPSA */ + TFA9894_BF_AMPINSEL = + 0x0101, /*!< Amplifier input selection */ + TFA9894_BF_MANSCONF = + 0x0120, /*!< Device I2C settings configured */ + TFA9894_BF_MANCOLD = + 0x0130, /*!< Execute cold start */ + TFA9894_BF_MANROBOD = + 0x0140, /*!< Reaction on BOD */ + TFA9894_BF_BODE = + 0x0150, /*!< Enable BOD (only in direct control mode) */ + TFA9894_BF_BODHYS = + 0x0160, /*!< Enable Hysteresis of BOD */ + TFA9894_BF_BODFILT = + 0x0171, /*!< BOD filter */ + TFA9894_BF_BODTHLVL = + 0x0191, /*!< BOD threshold */ + TFA9894_BF_MUTETO = + 0x01b0, /*!< Time out SB mute sequence */ + TFA9894_BF_MANWDE = + 0x01c0, /*!< Watchdog enable */ + TFA9894_BF_OPENMTP = + 0x01e0, /*!< Control for FAIM protection */ + TFA9894_BF_FAIMVBGOVRRL = + 0x01f0, /*!< Overrule the enabling of VBG for faim erase/write access */ + TFA9894_BF_AUDFS = + 0x0203, /*!< Audio sample rate Fs */ + TFA9894_BF_INPLEV = + 0x0240, /*!< TDM output attenuation */ + TFA9894_BF_FRACTDEL = + 0x0255, /*!< Current sense fractional delay */ + TFA9894_BF_TDMPRES = + 0x02b1, /*!< Control for HW manager */ + TFA9894_BF_AMPOCRT = + 0x02d2, /*!< Amplifier on-off criteria for shutdown */ + TFA9894_BF_REV = + 0x030f, /*!< Revision info */ + TFA9894_BF_REFCKEXT = + 0x0401, /*!< PLL external reference clock */ + TFA9894_BF_REFCKSEL = + 0x0420, /*!< PLL internal reference clock */ + TFA9894_BF_MCLKSEL = + 0x0432, /*!< Master Clock Selection */ + TFA9894_BF_MANAOOSC = + 0x0460, /*!< Internal OSC1M off at PWDN */ + TFA9894_BF_ACKCLDDIS = + 0x0470, /*!< Automatic PLL reference clock selection for cold start */ + TFA9894_BF_SPKSSEN = + 0x0510, /*!< Enable speaker sub-system */ + TFA9894_BF_MTPSSEN = + 0x0520, /*!< Enable FAIM sub-system */ + TFA9894_BF_WDTCLKEN = + 0x0530, /*!< Enable Coolflux watchdog clock */ + TFA9894_BF_VDDS = + 0x1000, /*!< POR */ + TFA9894_BF_PLLS = + 0x1010, /*!< PLL Lock */ + TFA9894_BF_OTDS = + 0x1020, /*!< OTP alarm */ + TFA9894_BF_OVDS = + 0x1030, /*!< OVP alarm */ + TFA9894_BF_UVDS = + 0x1040, /*!< UVP alarm */ + TFA9894_BF_OCDS = + 0x1050, /*!< OCP amplifier (sticky register, clear on read) */ + TFA9894_BF_CLKS = + 0x1060, /*!< Clocks stable */ + TFA9894_BF_MTPB = + 0x1070, /*!< MTP busy */ + TFA9894_BF_NOCLK = + 0x1080, /*!< Lost clock */ + TFA9894_BF_ACS = + 0x1090, /*!< Cold Start */ + TFA9894_BF_WDS = + 0x10a0, /*!< Watchdog */ + TFA9894_BF_SWS = + 0x10b0, /*!< Amplifier engage */ + TFA9894_BF_AMPS = + 0x10c0, /*!< Amplifier enable */ + TFA9894_BF_AREFS = + 0x10d0, /*!< References enable */ + TFA9894_BF_ADCCR = + 0x10e0, /*!< Control ADC */ + TFA9894_BF_BODNOK = + 0x10f0, /*!< BOD Flag - VDD NOT OK */ + TFA9894_BF_DCIL = + 0x1100, /*!< DCDC current limiting */ + TFA9894_BF_DCDCA = + 0x1110, /*!< DCDC active (sticky register, clear on read) */ + TFA9894_BF_DCOCPOK = + 0x1120, /*!< DCDC OCP nmos (sticky register, clear on read) */ + TFA9894_BF_DCHVBAT = + 0x1140, /*!< DCDC level 1x */ + TFA9894_BF_DCH114 = + 0x1150, /*!< DCDC level 1.14x */ + TFA9894_BF_DCH107 = + 0x1160, /*!< DCDC level 1.07x */ + TFA9894_BF_SPKS = + 0x1170, /*!< Speaker status */ + TFA9894_BF_CLKOOR = + 0x1180, /*!< External clock status */ + TFA9894_BF_MANALARM = + 0x1190, /*!< Alarm state */ + TFA9894_BF_TDMERR = + 0x11a0, /*!< TDM error */ + TFA9894_BF_TDMLUTER = + 0x11b0, /*!< TDM lookup table error */ + TFA9894_BF_OCPOAP = + 0x1200, /*!< OCPOK pmos A */ + TFA9894_BF_OCPOAN = + 0x1210, /*!< OCPOK nmos A */ + TFA9894_BF_OCPOBP = + 0x1220, /*!< OCPOK pmos B */ + TFA9894_BF_OCPOBN = + 0x1230, /*!< OCPOK nmos B */ + TFA9894_BF_CLIPS = + 0x1240, /*!< Amplifier clipping */ + TFA9894_BF_MANMUTE = + 0x1250, /*!< Audio mute sequence */ + TFA9894_BF_MANOPER = + 0x1260, /*!< Device in Operating state */ + TFA9894_BF_LP1 = + 0x1270, /*!< Low power MODE1 detection */ + TFA9894_BF_LA = + 0x1280, /*!< Low amplitude detection */ + TFA9894_BF_VDDPH = + 0x1290, /*!< VDDP greater than VBAT flag */ + TFA9894_BF_TDMSTAT = + 0x1402, /*!< TDM Status bits */ + TFA9894_BF_MANSTATE = + 0x1433, /*!< Device Manager status */ + TFA9894_BF_DCMODE = + 0x14b1, /*!< DCDC mode status bits */ + TFA9894_BF_BATS = + 0x1509, /*!< Battery voltage (V) */ + TFA9894_BF_TEMPS = + 0x1608, /*!< IC Temperature (C) */ + TFA9894_BF_VDDPS = + 0x1709, /*!< IC VDDP voltage (1023*VDDP/13V) */ + TFA9894_BF_TDME = + 0x2000, /*!< Enable interface */ + TFA9894_BF_TDMSPKE = + 0x2010, /*!< Control audio tdm channel in sink0 */ + TFA9894_BF_TDMDCE = + 0x2020, /*!< Control audio tdm channel in sink1 */ + TFA9894_BF_TDMCSE = + 0x2030, /*!< Source 0 enable */ + TFA9894_BF_TDMVSE = + 0x2040, /*!< Source 1 enable */ + TFA9894_BF_TDMCFE = + 0x2050, /*!< Source 2 enable */ + TFA9894_BF_TDMCF2E = + 0x2060, /*!< Source 3 enable */ + TFA9894_BF_TDMCLINV = + 0x2070, /*!< Reception data to BCK clock */ + TFA9894_BF_TDMFSPOL = + 0x2080, /*!< FS polarity */ + TFA9894_BF_TDMDEL = + 0x2090, /*!< Data delay to FS */ + TFA9894_BF_TDMADJ = + 0x20a0, /*!< Data adjustment */ + TFA9894_BF_TDMOOMP = + 0x20b1, /*!< Received audio compression */ + TFA9894_BF_TDMNBCK = + 0x2103, /*!< TDM NBCK - Bit clock to FS ratio */ + TFA9894_BF_TDMFSLN = + 0x2143, /*!< FS length (master mode only) */ + TFA9894_BF_TDMSLOTS = + 0x2183, /*!< N-slots in Frame */ + TFA9894_BF_TDMTXDFO = + 0x21c1, /*!< Format unused bits */ + TFA9894_BF_TDMTXUS0 = + 0x21e1, /*!< Format unused slots DATAO */ + TFA9894_BF_TDMSLLN = + 0x2204, /*!< N-bits in slot */ + TFA9894_BF_TDMBRMG = + 0x2254, /*!< N-bits remaining */ + TFA9894_BF_TDMSSIZE = + 0x22a4, /*!< Sample size per slot */ + TFA9894_BF_TDMSPKS = + 0x2303, /*!< TDM slot for sink 0 */ + TFA9894_BF_TDMDCS = + 0x2343, /*!< TDM slot for sink 1 */ + TFA9894_BF_TDMCFSEL = + 0x2381, /*!< TDM Source 2 data selection */ + TFA9894_BF_TDMCF2SEL = + 0x23a1, /*!< TDM Source 3 data selection */ + TFA9894_BF_TDMCSS = + 0x2403, /*!< Slot Position of source 0 data */ + TFA9894_BF_TDMVSS = + 0x2443, /*!< Slot Position of source 1 data */ + TFA9894_BF_TDMCFS = + 0x2483, /*!< Slot Position of source 2 data */ + TFA9894_BF_TDMCF2S = + 0x24c3, /*!< Slot Position of source 3 data */ + TFA9894_BF_ISTVDDS = + 0x4000, /*!< Status POR */ + TFA9894_BF_ISTBSTOC = + 0x4010, /*!< Status DCDC OCP */ + TFA9894_BF_ISTOTDS = + 0x4020, /*!< Status OTP alarm */ + TFA9894_BF_ISTOCPR = + 0x4030, /*!< Status OCP alarm */ + TFA9894_BF_ISTUVDS = + 0x4040, /*!< Status UVP alarm */ + TFA9894_BF_ISTMANALARM = + 0x4050, /*!< Status manager alarm state */ + TFA9894_BF_ISTTDMER = + 0x4060, /*!< Status TDM error */ + TFA9894_BF_ISTNOCLK = + 0x4070, /*!< Status lost clock */ + TFA9894_BF_ISTCFMER = + 0x4080, /*!< Status cfma error */ + TFA9894_BF_ISTCFMAC = + 0x4090, /*!< Status cfma ack */ + TFA9894_BF_ISTSPKS = + 0x40a0, /*!< Status coolflux speaker error */ + TFA9894_BF_ISTACS = + 0x40b0, /*!< Status cold started */ + TFA9894_BF_ISTWDS = + 0x40c0, /*!< Status watchdog reset */ + TFA9894_BF_ISTBODNOK = + 0x40d0, /*!< Status brown out detect */ + TFA9894_BF_ISTLP1 = + 0x40e0, /*!< Status low power mode1 detect */ + TFA9894_BF_ISTCLKOOR = + 0x40f0, /*!< Status clock out of range */ + TFA9894_BF_ICLVDDS = + 0x4400, /*!< Clear POR */ + TFA9894_BF_ICLBSTOC = + 0x4410, /*!< Clear DCDC OCP */ + TFA9894_BF_ICLOTDS = + 0x4420, /*!< Clear OTP alarm */ + TFA9894_BF_ICLOCPR = + 0x4430, /*!< Clear OCP alarm */ + TFA9894_BF_ICLUVDS = + 0x4440, /*!< Clear UVP alarm */ + TFA9894_BF_ICLMANALARM = + 0x4450, /*!< Clear manager alarm state */ + TFA9894_BF_ICLTDMER = + 0x4460, /*!< Clear TDM error */ + TFA9894_BF_ICLNOCLK = + 0x4470, /*!< Clear lost clk */ + TFA9894_BF_ICLCFMER = + 0x4480, /*!< Clear cfma err */ + TFA9894_BF_ICLCFMAC = + 0x4490, /*!< Clear cfma ack */ + TFA9894_BF_ICLSPKS = + 0x44a0, /*!< Clear coolflux speaker error */ + TFA9894_BF_ICLACS = + 0x44b0, /*!< Clear cold started */ + TFA9894_BF_ICLWDS = + 0x44c0, /*!< Clear watchdog reset */ + TFA9894_BF_ICLBODNOK = + 0x44d0, /*!< Clear brown out detect */ + TFA9894_BF_ICLLP1 = + 0x44e0, /*!< Clear low power mode1 detect */ + TFA9894_BF_ICLCLKOOR = + 0x44f0, /*!< Clear clock out of range */ + TFA9894_BF_IEVDDS = + 0x4800, /*!< Enable POR */ + TFA9894_BF_IEBSTOC = + 0x4810, /*!< Enable DCDC OCP */ + TFA9894_BF_IEOTDS = + 0x4820, /*!< Enable OTP alarm */ + TFA9894_BF_IEOCPR = + 0x4830, /*!< Enable OCP alarm */ + TFA9894_BF_IEUVDS = + 0x4840, /*!< Enable UVP alarm */ + TFA9894_BF_IEMANALARM = + 0x4850, /*!< Enable Manager Alarm state */ + TFA9894_BF_IETDMER = + 0x4860, /*!< Enable TDM error */ + TFA9894_BF_IENOCLK = + 0x4870, /*!< Enable lost clk */ + TFA9894_BF_IECFMER = + 0x4880, /*!< Enable cfma err */ + TFA9894_BF_IECFMAC = + 0x4890, /*!< Enable cfma ack */ + TFA9894_BF_IESPKS = + 0x48a0, /*!< Enable coolflux speaker error */ + TFA9894_BF_IEACS = + 0x48b0, /*!< Enable cold started */ + TFA9894_BF_IEWDS = + 0x48c0, /*!< Enable watchdog reset */ + TFA9894_BF_IEBODNOK = + 0x48d0, /*!< Enable brown out detect */ + TFA9894_BF_IELP1 = + 0x48e0, /*!< Enable low power mode1 detect */ + TFA9894_BF_IECLKOOR = + 0x48f0, /*!< Enable clock out of range */ + TFA9894_BF_IPOVDDS = + 0x4c00, /*!< Polarity POR */ + TFA9894_BF_IPOBSTOC = + 0x4c10, /*!< Polarity DCDC OCP */ + TFA9894_BF_IPOOTDS = + 0x4c20, /*!< Polarity OTP alarm */ + TFA9894_BF_IPOOCPR = + 0x4c30, /*!< Polarity ocp alarm */ + TFA9894_BF_IPOUVDS = + 0x4c40, /*!< Polarity UVP alarm */ + TFA9894_BF_IPOMANALARM = + 0x4c50, /*!< Polarity manager alarm state */ + TFA9894_BF_IPOTDMER = + 0x4c60, /*!< Polarity TDM error */ + TFA9894_BF_IPONOCLK = + 0x4c70, /*!< Polarity lost clk */ + TFA9894_BF_IPOCFMER = + 0x4c80, /*!< Polarity cfma err */ + TFA9894_BF_IPOCFMAC = + 0x4c90, /*!< Polarity cfma ack */ + TFA9894_BF_IPOSPKS = + 0x4ca0, /*!< Polarity coolflux speaker error */ + TFA9894_BF_IPOACS = + 0x4cb0, /*!< Polarity cold started */ + TFA9894_BF_IPOWDS = + 0x4cc0, /*!< Polarity watchdog reset */ + TFA9894_BF_IPOBODNOK = + 0x4cd0, /*!< Polarity brown out detect */ + TFA9894_BF_IPOLP1 = + 0x4ce0, /*!< Polarity low power mode1 detect */ + TFA9894_BF_IPOCLKOOR = + 0x4cf0, /*!< Polarity clock out of range */ + TFA9894_BF_BSSCR = + 0x5001, /*!< Battery safeguard attack time */ + TFA9894_BF_BSST = + 0x5023, /*!< Battery safeguard threshold voltage level */ + TFA9894_BF_BSSRL = + 0x5061, /*!< Battery safeguard maximum reduction */ + TFA9894_BF_BSSRR = + 0x5082, /*!< Battery safeguard release time */ + TFA9894_BF_BSSHY = + 0x50b1, /*!< Battery Safeguard hysteresis */ + TFA9894_BF_BSSR = + 0x50e0, /*!< Battery voltage read out */ + TFA9894_BF_BSSBY = + 0x50f0, /*!< Bypass HW clipper */ + TFA9894_BF_CFSM = + 0x5130, /*!< Coolflux firmware soft mute control */ + TFA9894_BF_VOL = + 0x5187, /*!< CF firmware volume control */ + TFA9894_BF_CLIPCTRL = + 0x5202, /*!< Clip control setting */ + TFA9894_BF_SLOPEE = + 0x5230, /*!< Enables slope control */ + TFA9894_BF_SLOPESET = + 0x5240, /*!< Slope speed setting (binary coded) */ + TFA9894_BF_AMPGAIN = + 0x5287, /*!< Amplifier gain */ + TFA9894_BF_TDMDCG = + 0x5703, /*!< Second channel gain in case of stereo using a single coil. (Total gain depending on INPLEV). (In case of mono OR stereo using 2 separate DCDC channel 1 should be disabled using TDMDCE) */ + TFA9894_BF_TDMSPKG = + 0x5743, /*!< Total gain depending on INPLEV setting (channel 0) */ + TFA9894_BF_DCINSEL = + 0x5781, /*!< VAMP_OUT2 input selection */ + TFA9894_BF_LNMODE = + 0x5881, /*!< Low noise gain mode control */ + TFA9894_BF_LPM1MODE = + 0x5ac1, /*!< Low power mode control */ + TFA9894_BF_TDMSRCMAP = + 0x5d02, /*!< TDM source mapping */ + TFA9894_BF_TDMSRCAS = + 0x5d31, /*!< Sensed value A */ + TFA9894_BF_TDMSRCBS = + 0x5d51, /*!< Sensed value B */ + TFA9894_BF_TDMSRCACLIP = + 0x5d71, /*!< Clip information (analog /digital) for source0 */ + TFA9894_BF_TDMSRCBCLIP = + 0x5d91, /*!< Clip information (analog /digital) for source1 */ + TFA9894_BF_DELCURCOMP = + 0x6102, /*!< Delay to allign compensation signal with current sense signal */ + TFA9894_BF_SIGCURCOMP = + 0x6130, /*!< Polarity of compensation for current sense */ + TFA9894_BF_ENCURCOMP = + 0x6140, /*!< Enable current sense compensation */ + TFA9894_BF_LVLCLPPWM = + 0x6152, /*!< Set the amount of pwm pulse that may be skipped before clip-flag is triggered */ + TFA9894_BF_DCVOF = + 0x7005, /*!< First Boost Voltage Level */ + TFA9894_BF_DCVOS = + 0x7065, /*!< Second Boost Voltage Level */ + TFA9894_BF_DCMCC = + 0x70c3, /*!< Max Coil Current */ + TFA9894_BF_DCCV = + 0x7101, /*!< Slope compensation current, represents LxF (inductance x frequency) value */ + TFA9894_BF_DCIE = + 0x7120, /*!< Adaptive boost mode */ + TFA9894_BF_DCSR = + 0x7130, /*!< Soft ramp up/down */ + TFA9894_BF_DCDIS = + 0x7140, /*!< DCDC on/off */ + TFA9894_BF_DCPWM = + 0x7150, /*!< DCDC PWM only mode */ + TFA9894_BF_DCTRACK = + 0x7160, /*!< Boost algorithm selection, effective only when boost_intelligent is set to 1 */ + TFA9894_BF_DCTRIP = + 0x7204, /*!< 1st adaptive boost trip levels, effective only when DCIE is set to 1 */ + TFA9894_BF_DCTRIP2 = + 0x7254, /*!< 2nd adaptive boost trip levels, effective only when DCIE is set to 1 */ + TFA9894_BF_DCTRIPT = + 0x72a4, /*!< Track adaptive boost trip levels, effective only when boost_intelligent is set to 1 */ + TFA9894_BF_DCTRIPHYSTE = + 0x72f0, /*!< Enable hysteresis on booster trip levels */ + TFA9894_BF_DCHOLD = + 0x7304, /*!< Hold time for DCDC booster, effective only when boost_intelligent is set to 1 */ + TFA9894_BF_RST = + 0x9000, /*!< Reset for Coolflux DSP */ + TFA9894_BF_DMEM = + 0x9011, /*!< Target memory for CFMA using I2C interface */ + TFA9894_BF_AIF = + 0x9030, /*!< Auto increment */ + TFA9894_BF_CFINT = + 0x9040, /*!< Coolflux Interrupt - auto clear */ + TFA9894_BF_CFCGATE = + 0x9050, /*!< Coolflux clock gating disabling control */ + TFA9894_BF_REQCMD = + 0x9080, /*!< Firmware event request rpc command */ + TFA9894_BF_REQRST = + 0x9090, /*!< Firmware event request reset restart */ + TFA9894_BF_REQMIPS = + 0x90a0, /*!< Firmware event request short on mips */ + TFA9894_BF_REQMUTED = + 0x90b0, /*!< Firmware event request mute sequence ready */ + TFA9894_BF_REQVOL = + 0x90c0, /*!< Firmware event request volume ready */ + TFA9894_BF_REQDMG = + 0x90d0, /*!< Firmware event request speaker damage detected */ + TFA9894_BF_REQCAL = + 0x90e0, /*!< Firmware event request calibration completed */ + TFA9894_BF_REQRSV = + 0x90f0, /*!< Firmware event request reserved */ + TFA9894_BF_MADD = + 0x910f, /*!< CF memory address */ + TFA9894_BF_MEMA = + 0x920f, /*!< Activate memory access */ + TFA9894_BF_ERR = + 0x9307, /*!< CF error flags */ + TFA9894_BF_ACKCMD = + 0x9380, /*!< Firmware event acknowledge rpc command */ + TFA9894_BF_ACKRST = + 0x9390, /*!< Firmware event acknowledge reset restart */ + TFA9894_BF_ACKMIPS = + 0x93a0, /*!< Firmware event acknowledge short on mips */ + TFA9894_BF_ACKMUTED = + 0x93b0, /*!< Firmware event acknowledge mute sequence ready */ + TFA9894_BF_ACKVOL = + 0x93c0, /*!< Firmware event acknowledge volume ready */ + TFA9894_BF_ACKDMG = + 0x93d0, /*!< Firmware event acknowledge speaker damage detected */ + TFA9894_BF_ACKCAL = + 0x93e0, /*!< Firmware event acknowledge calibration completed */ + TFA9894_BF_ACKRSV = + 0x93f0, /*!< Firmware event acknowledge reserved */ + TFA9894_BF_MTPK = + 0xa107, /*!< KEY2 to access KEY2 protected registers, customer key */ + TFA9894_BF_KEY1LOCKED = + 0xa200, /*!< Indicates KEY1 is locked */ + TFA9894_BF_KEY2LOCKED = + 0xa210, /*!< Indicates KEY2 is locked */ + TFA9894_BF_CMTPI = + 0xa350, /*!< Start copying all the data from mtp to I2C mtp registers - auto clear */ + TFA9894_BF_CIMTP = + 0xa360, /*!< Start copying data from I2C mtp registers to mtp - auto clear */ + TFA9894_BF_MTPRDMSB = + 0xa50f, /*!< MSB word of MTP manual read data */ + TFA9894_BF_MTPRDLSB = + 0xa60f, /*!< LSB word of MTP manual read data */ + TFA9894_BF_EXTTS = + 0xb108, /*!< External temperature (C) */ + TFA9894_BF_TROS = + 0xb190, /*!< Select temp Speaker calibration */ + TFA9894_BF_SWPROFIL = + 0xe00f, /*!< Software profile data */ + TFA9894_BF_SWVSTEP = + 0xe10f, /*!< Software vstep information */ + TFA9894_BF_MTPOTC = + 0xf000, /*!< Calibration schedule */ + TFA9894_BF_MTPEX = + 0xf010, /*!< Calibration Ron executed */ + TFA9894_BF_DCMCCAPI = + 0xf020, /*!< Calibration current limit DCDC */ + TFA9894_BF_DCMCCSB = + 0xf030, /*!< Sign bit for delta calibration current limit DCDC */ + TFA9894_BF_USERDEF = + 0xf042, /*!< Calibration delta current limit DCDC */ + TFA9894_BF_CUSTINFO = + 0xf078, /*!< Reserved space for allowing customer to store speaker information */ + TFA9894_BF_R25C = + 0xf50f, /*!< Ron resistance of speaker coil */ +} nxpTfa9894BfEnumList_t; +#define TFA9894_NAMETABLE \ + static tfaBfName_t Tfa9894DatasheetNames[] = { \ + { 0x0, \ + "PWDN" }, /* Powerdown control , */ \ + { 0x10, \ + "I2CR" }, /* I2C Reset - Auto clear , */ \ + { 0x20, \ + "CFE" }, /* Enable CoolFlux DSP , */ \ + { 0x30, \ + "AMPE" }, /* Enable Amplifier , */ \ + { 0x40, \ + "DCA" }, /* Enable DCDC Boost converter , */ \ + { 0x50, \ + "SBSL" }, /* Coolflux configured , */ \ + { 0x60, \ + "AMPC" }, /* CoolFlux control over amplifier , */ \ + { 0x71, \ + "INTP" }, /* Interrupt config , */ \ + { 0x90, \ + "FSSSEL" }, /* Audio sample reference , */ \ + { 0xa0, \ + "BYPOCP" }, /* Bypass OCP , */ \ + { 0xb0, \ + "TSTOCP" }, /* OCP testing control , */ \ + { 0xc0, \ + "BSSS" }, /* Vbat protection steepness , */ \ + { 0xd0, \ + "HPFBYP" }, /* Bypass High Pass Filter , */ \ + { 0xe0, \ + "DPSA" }, /* Enable DPSA , */ \ + { 0x101, \ + "AMPINSEL" }, /* Amplifier input selection , */ \ + { 0x120, \ + "MANSCONF" }, /* Device I2C settings configured , */ \ + { 0x130, \ + "MANCOLD" }, /* Execute cold start , */ \ + { 0x140, \ + "MANROBOD" }, /* Reaction on BOD , */ \ + { 0x150, \ + "BODE" }, /* Enable BOD (only in direct control mode) , */ \ + { 0x160, \ + "BODHYS" }, /* Enable Hysteresis of BOD , */ \ + { 0x171, \ + "BODFILT" }, /* BOD filter , */ \ + { 0x191, \ + "BODTHLVL" }, /* BOD threshold , */ \ + { 0x1b0, \ + "MUTETO" }, /* Time out SB mute sequence , */ \ + { 0x1c0, \ + "MANWDE" }, /* Watchdog enable , */ \ + { 0x1e0, \ + "OPENMTP" }, /* Control for FAIM protection , */ \ + { 0x1f0, \ + "FAIMVBGOVRRL" }, /* Overrule the enabling of VBG for faim erase/write access, */ \ + { 0x203, \ + "AUDFS" }, /* Audio sample rate Fs , */ \ + { 0x240, \ + "INPLEV" }, /* TDM output attenuation , */ \ + { 0x255, \ + "FRACTDEL" }, /* Current sense fractional delay , */ \ + { 0x2b1, \ + "TDMPRES" }, /* Control for HW manager , */ \ + { 0x2d2, \ + "AMPOCRT" }, /* Amplifier on-off criteria for shutdown , */ \ + { 0x30f, \ + "REV" }, /* Revision info , */ \ + { 0x401, \ + "REFCKEXT" }, /* PLL external reference clock , */ \ + { 0x420, \ + "REFCKSEL" }, /* PLL internal reference clock , */ \ + { 0x432, \ + "MCLKSEL" }, /* Master Clock Selection , */ \ + { 0x460, \ + "MANAOOSC" }, /* Internal OSC1M off at PWDN , */ \ + { 0x470, \ + "ACKCLDDIS" }, /* Automatic PLL reference clock selection for cold start, */ \ + { 0x510, \ + "SPKSSEN" }, /* Enable speaker sub-system , */ \ + { 0x520, \ + "MTPSSEN" }, /* Enable FAIM sub-system , */ \ + { 0x530, \ + "WDTCLKEN" }, /* Enable Coolflux watchdog clock , */ \ + { 0x1000, \ + "VDDS" }, /* POR , */ \ + { 0x1010, \ + "PLLS" }, /* PLL Lock , */ \ + { 0x1020, \ + "OTDS" }, /* OTP alarm , */ \ + { 0x1030, \ + "OVDS" }, /* OVP alarm , */ \ + { 0x1040, \ + "UVDS" }, /* UVP alarm , */ \ + { 0x1050, \ + "OCDS" }, /* OCP amplifier (sticky register, clear on read) , */ \ + { 0x1060, \ + "CLKS" }, /* Clocks stable , */ \ + { 0x1070, \ + "MTPB" }, /* MTP busy , */ \ + { 0x1080, \ + "NOCLK" }, /* Lost clock , */ \ + { 0x1090, \ + "ACS" }, /* Cold Start , */ \ + { 0x10a0, \ + "WDS" }, /* Watchdog , */ \ + { 0x10b0, \ + "SWS" }, /* Amplifier engage , */ \ + { 0x10c0, \ + "AMPS" }, /* Amplifier enable , */ \ + { 0x10d0, \ + "AREFS" }, /* References enable , */ \ + { 0x10e0, \ + "ADCCR" }, /* Control ADC , */ \ + { 0x10f0, \ + "BODNOK" }, /* BOD Flag - VDD NOT OK , */ \ + { 0x1100, \ + "DCIL" }, /* DCDC current limiting , */ \ + { 0x1110, \ + "DCDCA" }, /* DCDC active (sticky register, clear on read) , */ \ + { 0x1120, \ + "DCOCPOK" }, /* DCDC OCP nmos (sticky register, clear on read) , */ \ + { 0x1140, \ + "DCHVBAT" }, /* DCDC level 1x , */ \ + { 0x1150, \ + "DCH114" }, /* DCDC level 1.14x , */ \ + { 0x1160, \ + "DCH107" }, /* DCDC level 1.07x , */ \ + { 0x1170, \ + "SPKS" }, /* Speaker status , */ \ + { 0x1180, \ + "CLKOOR" }, /* External clock status , */ \ + { 0x1190, \ + "MANALARM" }, /* Alarm state , */ \ + { 0x11a0, \ + "TDMERR" }, /* TDM error , */ \ + { 0x11b0, \ + "TDMLUTER" }, /* TDM lookup table error , */ \ + { 0x1200, \ + "OCPOAP" }, /* OCPOK pmos A , */ \ + { 0x1210, \ + "OCPOAN" }, /* OCPOK nmos A , */ \ + { 0x1220, \ + "OCPOBP" }, /* OCPOK pmos B , */ \ + { 0x1230, \ + "OCPOBN" }, /* OCPOK nmos B , */ \ + { 0x1240, \ + "CLIPS" }, /* Amplifier clipping , */ \ + { 0x1250, \ + "MANMUTE" }, /* Audio mute sequence , */ \ + { 0x1260, \ + "MANOPER" }, /* Device in Operating state , */ \ + { 0x1270, \ + "LP1" }, /* Low power MODE1 detection , */ \ + { 0x1280, \ + "LA" }, /* Low amplitude detection , */ \ + { 0x1290, \ + "VDDPH" }, /* VDDP greater than VBAT flag , */ \ + { 0x1402, \ + "TDMSTAT" }, /* TDM Status bits , */ \ + { 0x1433, \ + "MANSTATE" }, /* Device Manager status , */ \ + { 0x14b1, \ + "DCMODE" }, /* DCDC mode status bits , */ \ + { 0x1509, \ + "BATS" }, /* Battery voltage (V) , */ \ + { 0x1608, \ + "TEMPS" }, /* IC Temperature (C) , */ \ + { 0x1709, \ + "VDDPS" }, /* IC VDDP voltage (1023*VDDP/13V) , */ \ + { 0x2000, \ + "TDME" }, /* Enable interface , */ \ + { 0x2010, \ + "TDMSPKE" }, /* Control audio tdm channel in sink0 , */ \ + { 0x2020, \ + "TDMDCE" }, /* Control audio tdm channel in sink1 , */ \ + { 0x2030, \ + "TDMCSE" }, /* Source 0 enable , */ \ + { 0x2040, \ + "TDMVSE" }, /* Source 1 enable , */ \ + { 0x2050, \ + "TDMCFE" }, /* Source 2 enable , */ \ + { 0x2060, \ + "TDMCF2E" }, /* Source 3 enable , */ \ + { 0x2070, \ + "TDMCLINV" }, /* Reception data to BCK clock , */ \ + { 0x2080, \ + "TDMFSPOL" }, /* FS polarity , */ \ + { 0x2090, \ + "TDMDEL" }, /* Data delay to FS , */ \ + { 0x20a0, \ + "TDMADJ" }, /* Data adjustment , */ \ + { 0x20b1, \ + "TDMOOMP" }, /* Received audio compression , */ \ + { 0x2103, \ + "TDMNBCK" }, /* TDM NBCK - Bit clock to FS ratio , */ \ + { 0x2143, \ + "TDMFSLN" }, /* FS length (master mode only) , */ \ + { 0x2183, \ + "TDMSLOTS" }, /* N-slots in Frame , */ \ + { 0x21c1, \ + "TDMTXDFO" }, /* Format unused bits , */ \ + { 0x21e1, \ + "TDMTXUS0" }, /* Format unused slots DATAO , */ \ + { 0x2204, \ + "TDMSLLN" }, /* N-bits in slot , */ \ + { 0x2254, \ + "TDMBRMG" }, /* N-bits remaining , */ \ + { 0x22a4, \ + "TDMSSIZE" }, /* Sample size per slot , */ \ + { 0x2303, \ + "TDMSPKS" }, /* TDM slot for sink 0 , */ \ + { 0x2343, \ + "TDMDCS" }, /* TDM slot for sink 1 , */ \ + { 0x2381, \ + "TDMCFSEL" }, /* TDM Source 2 data selection , */ \ + { 0x23a1, \ + "TDMCF2SEL" }, /* TDM Source 3 data selection , */ \ + { 0x2403, \ + "TDMCSS" }, /* Slot Position of source 0 data , */ \ + { 0x2443, \ + "TDMVSS" }, /* Slot Position of source 1 data , */ \ + { 0x2483, \ + "TDMCFS" }, /* Slot Position of source 2 data , */ \ + { 0x24c3, \ + "TDMCF2S" }, /* Slot Position of source 3 data , */ \ + { 0x4000, \ + "ISTVDDS" }, /* Status POR , */ \ + { 0x4010, \ + "ISTBSTOC" }, /* Status DCDC OCP , */ \ + { 0x4020, \ + "ISTOTDS" }, /* Status OTP alarm , */ \ + { 0x4030, \ + "ISTOCPR" }, /* Status OCP alarm , */ \ + { 0x4040, \ + "ISTUVDS" }, /* Status UVP alarm , */ \ + { 0x4050, \ + "ISTMANALARM" }, /* Status manager alarm state , */ \ + { 0x4060, \ + "ISTTDMER" }, /* Status TDM error , */ \ + { 0x4070, \ + "ISTNOCLK" }, /* Status lost clock , */ \ + { 0x4080, \ + "ISTCFMER" }, /* Status cfma error , */ \ + { 0x4090, \ + "ISTCFMAC" }, /* Status cfma ack , */ \ + { 0x40a0, \ + "ISTSPKS" }, /* Status coolflux speaker error , */ \ + { 0x40b0, \ + "ISTACS" }, /* Status cold started , */ \ + { 0x40c0, \ + "ISTWDS" }, /* Status watchdog reset , */ \ + { 0x40d0, \ + "ISTBODNOK" }, /* Status brown out detect , */ \ + { 0x40e0, \ + "ISTLP1" }, /* Status low power mode1 detect , */ \ + { 0x40f0, \ + "ISTCLKOOR" }, /* Status clock out of range , */ \ + { 0x4400, \ + "ICLVDDS" }, /* Clear POR , */ \ + { 0x4410, \ + "ICLBSTOC" }, /* Clear DCDC OCP , */ \ + { 0x4420, \ + "ICLOTDS" }, /* Clear OTP alarm , */ \ + { 0x4430, \ + "ICLOCPR" }, /* Clear OCP alarm , */ \ + { 0x4440, \ + "ICLUVDS" }, /* Clear UVP alarm , */ \ + { 0x4450, \ + "ICLMANALARM" }, /* Clear manager alarm state , */ \ + { 0x4460, \ + "ICLTDMER" }, /* Clear TDM error , */ \ + { 0x4470, \ + "ICLNOCLK" }, /* Clear lost clk , */ \ + { 0x4480, \ + "ICLCFMER" }, /* Clear cfma err , */ \ + { 0x4490, \ + "ICLCFMAC" }, /* Clear cfma ack , */ \ + { 0x44a0, \ + "ICLSPKS" }, /* Clear coolflux speaker error , */ \ + { 0x44b0, \ + "ICLACS" }, /* Clear cold started , */ \ + { 0x44c0, \ + "ICLWDS" }, /* Clear watchdog reset , */ \ + { 0x44d0, \ + "ICLBODNOK" }, /* Clear brown out detect , */ \ + { 0x44e0, \ + "ICLLP1" }, /* Clear low power mode1 detect , */ \ + { 0x44f0, \ + "ICLCLKOOR" }, /* Clear clock out of range , */ \ + { 0x4800, \ + "IEVDDS" }, /* Enable POR , */ \ + { 0x4810, \ + "IEBSTOC" }, /* Enable DCDC OCP , */ \ + { 0x4820, \ + "IEOTDS" }, /* Enable OTP alarm , */ \ + { 0x4830, \ + "IEOCPR" }, /* Enable OCP alarm , */ \ + { 0x4840, \ + "IEUVDS" }, /* Enable UVP alarm , */ \ + { 0x4850, \ + "IEMANALARM" }, /* Enable Manager Alarm state , */ \ + { 0x4860, \ + "IETDMER" }, /* Enable TDM error , */ \ + { 0x4870, \ + "IENOCLK" }, /* Enable lost clk , */ \ + { 0x4880, \ + "IECFMER" }, /* Enable cfma err , */ \ + { 0x4890, \ + "IECFMAC" }, /* Enable cfma ack , */ \ + { 0x48a0, \ + "IESPKS" }, /* Enable coolflux speaker error , */ \ + { 0x48b0, \ + "IEACS" }, /* Enable cold started , */ \ + { 0x48c0, \ + "IEWDS" }, /* Enable watchdog reset , */ \ + { 0x48d0, \ + "IEBODNOK" }, /* Enable brown out detect , */ \ + { 0x48e0, \ + "IELP1" }, /* Enable low power mode1 detect , */ \ + { 0x48f0, \ + "IECLKOOR" }, /* Enable clock out of range , */ \ + { 0x4c00, \ + "IPOVDDS" }, /* Polarity POR , */ \ + { 0x4c10, \ + "IPOBSTOC" }, /* Polarity DCDC OCP , */ \ + { 0x4c20, \ + "IPOOTDS" }, /* Polarity OTP alarm , */ \ + { 0x4c30, \ + "IPOOCPR" }, /* Polarity ocp alarm , */ \ + { 0x4c40, \ + "IPOUVDS" }, /* Polarity UVP alarm , */ \ + { 0x4c50, \ + "IPOMANALARM" }, /* Polarity manager alarm state , */ \ + { 0x4c60, \ + "IPOTDMER" }, /* Polarity TDM error , */ \ + { 0x4c70, \ + "IPONOCLK" }, /* Polarity lost clk , */ \ + { 0x4c80, \ + "IPOCFMER" }, /* Polarity cfma err , */ \ + { 0x4c90, \ + "IPOCFMAC" }, /* Polarity cfma ack , */ \ + { 0x4ca0, \ + "IPOSPKS" }, /* Polarity coolflux speaker error , */ \ + { 0x4cb0, \ + "IPOACS" }, /* Polarity cold started , */ \ + { 0x4cc0, \ + "IPOWDS" }, /* Polarity watchdog reset , */ \ + { 0x4cd0, \ + "IPOBODNOK" }, /* Polarity brown out detect , */ \ + { 0x4ce0, \ + "IPOLP1" }, /* Polarity low power mode1 detect , */ \ + { 0x4cf0, \ + "IPOCLKOOR" }, /* Polarity clock out of range , */ \ + { 0x5001, \ + "BSSCR" }, /* Battery safeguard attack time , */ \ + { 0x5023, \ + "BSST" }, /* Battery safeguard threshold voltage level , */ \ + { 0x5061, \ + "BSSRL" }, /* Battery safeguard maximum reduction , */ \ + { 0x5082, \ + "BSSRR" }, /* Battery safeguard release time , */ \ + { 0x50b1, \ + "BSSHY" }, /* Battery Safeguard hysteresis , */ \ + { 0x50e0, \ + "BSSR" }, /* Battery voltage read out , */ \ + { 0x50f0, \ + "BSSBY" }, /* Bypass HW clipper , */ \ + { 0x5130, \ + "CFSM" }, /* Coolflux firmware soft mute control , */ \ + { 0x5187, \ + "VOL" }, /* CF firmware volume control , */ \ + { 0x5202, \ + "CLIPCTRL" }, /* Clip control setting , */ \ + { 0x5230, \ + "SLOPEE" }, /* Enables slope control , */ \ + { 0x5240, \ + "SLOPESET" }, /* Slope speed setting (binary coded) , */ \ + { 0x5287, \ + "AMPGAIN" }, /* Amplifier gain , */ \ + { 0x5703, \ + "TDMDCG" }, /* Second channel gain in case of stereo using a single coil. (Total gain depending on INPLEV). (In case of mono OR stereo using 2 separate DCDC channel 1 should be disabled using TDMDCE), */ \ + { 0x5743, \ + "TDMSPKG" }, /* Total gain depending on INPLEV setting (channel 0), */ \ + { 0x5781, \ + "DCINSEL" }, /* VAMP_OUT2 input selection , */ \ + { 0x5881, \ + "LNMODE" }, /* Low noise gain mode control , */ \ + { 0x5ac1, \ + "LPM1MODE" }, /* Low power mode control , */ \ + { 0x5d02, \ + "TDMSRCMAP" }, /* TDM source mapping , */ \ + { 0x5d31, \ + "TDMSRCAS" }, /* Sensed value A , */ \ + { 0x5d51, \ + "TDMSRCBS" }, /* Sensed value B , */ \ + { 0x5d71, \ + "TDMSRCACLIP" }, /* Clip information (analog /digital) for source0 , */ \ + { 0x5d91, \ + "TDMSRCBCLIP" }, /* Clip information (analog /digital) for source1 , */ \ + { 0x6102, \ + "DELCURCOMP" }, /* Delay to allign compensation signal with current sense signal, */ \ + { 0x6130, \ + "SIGCURCOMP" }, /* Polarity of compensation for current sense , */ \ + { 0x6140, \ + "ENCURCOMP" }, /* Enable current sense compensation , */ \ + { 0x6152, \ + "LVLCLPPWM" }, /* Set the amount of pwm pulse that may be skipped before clip-flag is triggered, */ \ + { 0x7005, \ + "DCVOF" }, /* First Boost Voltage Level , */ \ + { 0x7065, \ + "DCVOS" }, /* Second Boost Voltage Level , */ \ + { 0x70c3, \ + "DCMCC" }, /* Max Coil Current , */ \ + { 0x7101, \ + "DCCV" }, /* Slope compensation current, represents LxF (inductance x frequency) value , */ \ + { 0x7120, \ + "DCIE" }, /* Adaptive boost mode , */ \ + { 0x7130, \ + "DCSR" }, /* Soft ramp up/down , */ \ + { 0x7140, \ + "DCDIS" }, /* DCDC on/off , */ \ + { 0x7150, \ + "DCPWM" }, /* DCDC PWM only mode , */ \ + { 0x7160, \ + "DCTRACK" }, /* Boost algorithm selection, effective only when boost_intelligent is set to 1, */ \ + { 0x7204, \ + "DCTRIP" }, /* 1st adaptive boost trip levels, effective only when DCIE is set to 1, */ \ + { 0x7254, \ + "DCTRIP2" }, /* 2nd adaptive boost trip levels, effective only when DCIE is set to 1, */ \ + { 0x72a4, \ + "DCTRIPT" }, /* Track adaptive boost trip levels, effective only when boost_intelligent is set to 1, */ \ + { 0x72f0, \ + "DCTRIPHYSTE" }, /* Enable hysteresis on booster trip levels , */ \ + { 0x7304, \ + "DCHOLD" }, /* Hold time for DCDC booster, effective only when boost_intelligent is set to 1, */ \ + { 0x9000, \ + "RST" }, /* Reset for Coolflux DSP , */ \ + { 0x9011, \ + "DMEM" }, /* Target memory for CFMA using I2C interface , */ \ + { 0x9030, \ + "AIF" }, /* Auto increment , */ \ + { 0x9040, \ + "CFINT" }, /* Coolflux Interrupt - auto clear , */ \ + { 0x9050, \ + "CFCGATE" }, /* Coolflux clock gating disabling control , */ \ + { 0x9080, \ + "REQCMD" }, /* Firmware event request rpc command , */ \ + { 0x9090, \ + "REQRST" }, /* Firmware event request reset restart , */ \ + { 0x90a0, \ + "REQMIPS" }, /* Firmware event request short on mips , */ \ + { 0x90b0, \ + "REQMUTED" }, /* Firmware event request mute sequence ready , */ \ + { 0x90c0, \ + "REQVOL" }, /* Firmware event request volume ready , */ \ + { 0x90d0, \ + "REQDMG" }, /* Firmware event request speaker damage detected , */ \ + { 0x90e0, \ + "REQCAL" }, /* Firmware event request calibration completed , */ \ + { 0x90f0, \ + "REQRSV" }, /* Firmware event request reserved , */ \ + { 0x910f, \ + "MADD" }, /* CF memory address , */ \ + { 0x920f, \ + "MEMA" }, /* Activate memory access , */ \ + { 0x9307, \ + "ERR" }, /* CF error flags , */ \ + { 0x9380, \ + "ACKCMD" }, /* Firmware event acknowledge rpc command , */ \ + { 0x9390, \ + "ACKRST" }, /* Firmware event acknowledge reset restart , */ \ + { 0x93a0, \ + "ACKMIPS" }, /* Firmware event acknowledge short on mips , */ \ + { 0x93b0, \ + "ACKMUTED" }, /* Firmware event acknowledge mute sequence ready , */ \ + { 0x93c0, \ + "ACKVOL" }, /* Firmware event acknowledge volume ready , */ \ + { 0x93d0, \ + "ACKDMG" }, /* Firmware event acknowledge speaker damage detected, */ \ + { 0x93e0, \ + "ACKCAL" }, /* Firmware event acknowledge calibration completed , */ \ + { 0x93f0, \ + "ACKRSV" }, /* Firmware event acknowledge reserved , */ \ + { 0xa107, \ + "MTPK" }, /* KEY2 to access KEY2 protected registers, customer key, */ \ + { 0xa200, \ + "KEY1LOCKED" }, /* Indicates KEY1 is locked , */ \ + { 0xa210, \ + "KEY2LOCKED" }, /* Indicates KEY2 is locked , */ \ + { 0xa350, \ + "CMTPI" }, /* Start copying all the data from mtp to I2C mtp registers - auto clear, */ \ + { 0xa360, \ + "CIMTP" }, /* Start copying data from I2C mtp registers to mtp - auto clear, */ \ + { 0xa50f, \ + "MTPRDMSB" }, /* MSB word of MTP manual read data , */ \ + { 0xa60f, \ + "MTPRDLSB" }, /* LSB word of MTP manual read data , */ \ + { 0xb108, \ + "EXTTS" }, /* External temperature (C) , */ \ + { 0xb190, \ + "TROS" }, /* Select temp Speaker calibration , */ \ + { 0xe00f, \ + "SWPROFIL" }, /* Software profile data , */ \ + { 0xe10f, \ + "SWVSTEP" }, /* Software vstep information , */ \ + { 0xf000, \ + "MTPOTC" }, /* Calibration schedule , */ \ + { 0xf010, \ + "MTPEX" }, /* Calibration Ron executed , */ \ + { 0xf020, \ + "DCMCCAPI" }, /* Calibration current limit DCDC , */ \ + { 0xf030, \ + "DCMCCSB" }, /* Sign bit for delta calibration current limit DCDC , */ \ + { 0xf042, \ + "USERDEF" }, /* Calibration delta current limit DCDC , */ \ + { 0xf078, \ + "CUSTINFO" }, /* Reserved space for allowing customer to store speaker information, */ \ + { 0xf50f, \ + "R25C" }, /* Ron resistance of speaker coil , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +#define TFA9894_BITNAMETABLE \ + static tfaBfName_t Tfa9894BitNames[] = { \ + { 0x0, \ + "powerdown" }, /* Powerdown control , */ \ + { 0x10, \ + "reset" }, /* I2C Reset - Auto clear , */ \ + { 0x20, \ + "enbl_coolflux" }, /* Enable CoolFlux DSP , */ \ + { 0x30, \ + "enbl_amplifier" }, /* Enable Amplifier , */ \ + { 0x40, \ + "enbl_boost" }, /* Enable DCDC Boost converter , */ \ + { 0x50, \ + "coolflux_configured" }, /* Coolflux configured , */ \ + { 0x60, \ + "sel_enbl_amplifier" }, /* CoolFlux control over amplifier , */ \ + { 0x71, \ + "int_pad_io" }, /* Interrupt config , */ \ + { 0x90, \ + "fs_pulse_sel" }, /* Audio sample reference , */ \ + { 0xa0, \ + "bypass_ocp" }, /* Bypass OCP , */ \ + { 0xb0, \ + "test_ocp" }, /* OCP testing control , */ \ + { 0xc0, \ + "batsense_steepness" }, /* Vbat protection steepness , */ \ + { 0xd0, \ + "bypass_hp" }, /* Bypass High Pass Filter , */ \ + { 0xe0, \ + "enbl_dpsa" }, /* Enable DPSA , */ \ + { 0xf0, \ + "sel_hysteresis" }, /* Select hysteresis for clock range detector , */ \ + { 0x101, \ + "vamp_sel1" }, /* Amplifier input selection , */ \ + { 0x120, \ + "src_set_configured" }, /* Device I2C settings configured , */ \ + { 0x130, \ + "execute_cold_start" }, /* Execute cold start , */ \ + { 0x140, \ + "man_enbl_brown_out" }, /* Reaction on BOD , */ \ + { 0x150, \ + "bod_enbl" }, /* Enable BOD (only in direct control mode) , */ \ + { 0x160, \ + "bod_hyst_enbl" }, /* Enable Hysteresis of BOD , */ \ + { 0x171, \ + "bod_delay_set" }, /* BOD filter , */ \ + { 0x191, \ + "bod_lvl_set" }, /* BOD threshold , */ \ + { 0x1b0, \ + "disable_mute_time_out" }, /* Time out SB mute sequence , */ \ + { 0x1c0, \ + "man_enbl_watchdog" }, /* Watchdog enable , */ \ + { 0x1d0, \ + "disable_engage" }, /* Disable Engage , */ \ + { 0x1e0, \ + "unprotect_faim" }, /* Control for FAIM protection , */ \ + { 0x1f0, \ + "faim_enable_vbg" }, /* Overrule the enabling of VBG for faim erase/write access, */ \ + { 0x203, \ + "audio_fs" }, /* Audio sample rate Fs , */ \ + { 0x240, \ + "input_level" }, /* TDM output attenuation , */ \ + { 0x255, \ + "cs_frac_delay" }, /* Current sense fractional delay , */ \ + { 0x2b1, \ + "use_tdm_presence" }, /* Control for HW manager , */ \ + { 0x2d2, \ + "ctrl_on2off_criterion" }, /* Amplifier on-off criteria for shutdown , */ \ + { 0x30f, \ + "device_rev" }, /* Revision info , */ \ + { 0x401, \ + "pll_clkin_sel" }, /* PLL external reference clock , */ \ + { 0x420, \ + "pll_clkin_sel_osc" }, /* PLL internal reference clock , */ \ + { 0x432, \ + "mclk_sel" }, /* Master Clock Selection , */ \ + { 0x460, \ + "enbl_osc1m_auto_off" }, /* Internal OSC1M off at PWDN , */ \ + { 0x470, \ + "disable_auto_sel_refclk" }, /* Automatic PLL reference clock selection for cold start, */ \ + { 0x510, \ + "enbl_spkr_ss" }, /* Enable speaker sub-system , */ \ + { 0x520, \ + "enbl_faim_ss" }, /* Enable FAIM sub-system , */ \ + { 0x530, \ + "enbl_wdt_clk" }, /* Enable Coolflux watchdog clock , */ \ + { 0xe07, \ + "ctrl_digtoana" }, /* Spare control from digital to analog , */ \ + { 0xf0f, \ + "hidden_code" }, /* Hidden code to enable access to hidden register. (0x5A6B/23147 default for engineering), */ \ + { 0x1000, \ + "flag_por" }, /* POR , */ \ + { 0x1010, \ + "flag_pll_lock" }, /* PLL Lock , */ \ + { 0x1020, \ + "flag_otpok" }, /* OTP alarm , */ \ + { 0x1030, \ + "flag_ovpok" }, /* OVP alarm , */ \ + { 0x1040, \ + "flag_uvpok" }, /* UVP alarm , */ \ + { 0x1050, \ + "flag_ocp_alarm" }, /* OCP amplifier (sticky register, clear on read) , */ \ + { 0x1060, \ + "flag_clocks_stable" }, /* Clocks stable , */ \ + { 0x1070, \ + "flag_mtp_busy" }, /* MTP busy , */ \ + { 0x1080, \ + "flag_lost_clk" }, /* Lost clock , */ \ + { 0x1090, \ + "flag_cold_started" }, /* Cold Start , */ \ + { 0x10a0, \ + "flag_watchdog_reset" }, /* Watchdog , */ \ + { 0x10b0, \ + "flag_engage" }, /* Amplifier engage , */ \ + { 0x10c0, \ + "flag_enbl_amp" }, /* Amplifier enable , */ \ + { 0x10d0, \ + "flag_enbl_ref" }, /* References enable , */ \ + { 0x10e0, \ + "flag_adc10_ready" }, /* Control ADC , */ \ + { 0x10f0, \ + "flag_bod_vddd_nok" }, /* BOD Flag - VDD NOT OK , */ \ + { 0x1100, \ + "flag_bst_bstcur" }, /* DCDC current limiting , */ \ + { 0x1110, \ + "flag_bst_hiz" }, /* DCDC active (sticky register, clear on read) , */ \ + { 0x1120, \ + "flag_bst_ocpok" }, /* DCDC OCP nmos (sticky register, clear on read) , */ \ + { 0x1130, \ + "flag_bst_peakcur" }, /* Indicates current is max in DC-to-DC converter , */ \ + { 0x1140, \ + "flag_bst_voutcomp" }, /* DCDC level 1x , */ \ + { 0x1150, \ + "flag_bst_voutcomp86" }, /* DCDC level 1.14x , */ \ + { 0x1160, \ + "flag_bst_voutcomp93" }, /* DCDC level 1.07x , */ \ + { 0x1170, \ + "flag_cf_speakererror" }, /* Speaker status , */ \ + { 0x1180, \ + "flag_clk_out_of_range" }, /* External clock status , */ \ + { 0x1190, \ + "flag_man_alarm_state" }, /* Alarm state , */ \ + { 0x11a0, \ + "flag_tdm_error" }, /* TDM error , */ \ + { 0x11b0, \ + "flag_tdm_lut_error" }, /* TDM lookup table error , */ \ + { 0x1200, \ + "flag_ocpokap" }, /* OCPOK pmos A , */ \ + { 0x1210, \ + "flag_ocpokan" }, /* OCPOK nmos A , */ \ + { 0x1220, \ + "flag_ocpokbp" }, /* OCPOK pmos B , */ \ + { 0x1230, \ + "flag_ocpokbn" }, /* OCPOK nmos B , */ \ + { 0x1240, \ + "flag_clip" }, /* Amplifier clipping , */ \ + { 0x1250, \ + "flag_man_start_mute_audio" }, /* Audio mute sequence , */ \ + { 0x1260, \ + "flag_man_operating_state" }, /* Device in Operating state , */ \ + { 0x1270, \ + "flag_lp_detect_mode1" }, /* Low power MODE1 detection , */ \ + { 0x1280, \ + "flag_low_amplitude" }, /* Low amplitude detection , */ \ + { 0x1290, \ + "flag_vddp_gt_vbat" }, /* VDDP greater than VBAT flag , */ \ + { 0x1402, \ + "tdm_status" }, /* TDM Status bits , */ \ + { 0x1433, \ + "man_state" }, /* Device Manager status , */ \ + { 0x1473, \ + "amp_ctrl_state" }, /* Amplifier control status , */ \ + { 0x14b1, \ + "status_bst_mode" }, /* DCDC mode status bits , */ \ + { 0x1509, \ + "bat_adc" }, /* Battery voltage (V) , */ \ + { 0x1608, \ + "temp_adc" }, /* IC Temperature (C) , */ \ + { 0x1709, \ + "vddp_adc" }, /* IC VDDP voltage (1023*VDDP/13V) , */ \ + { 0x2000, \ + "tdm_enable" }, /* Enable interface , */ \ + { 0x2010, \ + "tdm_sink0_enable" }, /* Control audio tdm channel in sink0 , */ \ + { 0x2020, \ + "tdm_sink1_enable" }, /* Control audio tdm channel in sink1 , */ \ + { 0x2030, \ + "tdm_source0_enable" }, /* Source 0 enable , */ \ + { 0x2040, \ + "tdm_source1_enable" }, /* Source 1 enable , */ \ + { 0x2050, \ + "tdm_source2_enable" }, /* Source 2 enable , */ \ + { 0x2060, \ + "tdm_source3_enable" }, /* Source 3 enable , */ \ + { 0x2070, \ + "tdm_clk_inversion" }, /* Reception data to BCK clock , */ \ + { 0x2080, \ + "tdm_fs_ws_polarity" }, /* FS polarity , */ \ + { 0x2090, \ + "tdm_data_delay" }, /* Data delay to FS , */ \ + { 0x20a0, \ + "tdm_data_adjustment" }, /* Data adjustment , */ \ + { 0x20b1, \ + "tdm_audio_sample_compression" }, /* Received audio compression , */ \ + { 0x2103, \ + "tdm_nbck" }, /* TDM NBCK - Bit clock to FS ratio , */ \ + { 0x2143, \ + "tdm_fs_ws_length" }, /* FS length (master mode only) , */ \ + { 0x2183, \ + "tdm_nb_of_slots" }, /* N-slots in Frame , */ \ + { 0x21c1, \ + "tdm_txdata_format" }, /* Format unused bits , */ \ + { 0x21e1, \ + "tdm_txdata_format_unused_slot" }, /* Format unused slots DATAO , */ \ + { 0x2204, \ + "tdm_slot_length" }, /* N-bits in slot , */ \ + { 0x2254, \ + "tdm_bits_remaining" }, /* N-bits remaining , */ \ + { 0x22a4, \ + "tdm_sample_size" }, /* Sample size per slot , */ \ + { 0x2303, \ + "tdm_sink0_slot" }, /* TDM slot for sink 0 , */ \ + { 0x2343, \ + "tdm_sink1_slot" }, /* TDM slot for sink 1 , */ \ + { 0x2381, \ + "tdm_source2_sel" }, /* TDM Source 2 data selection , */ \ + { 0x23a1, \ + "tdm_source3_sel" }, /* TDM Source 3 data selection , */ \ + { 0x2403, \ + "tdm_source0_slot" }, /* Slot Position of source 0 data , */ \ + { 0x2443, \ + "tdm_source1_slot" }, /* Slot Position of source 1 data , */ \ + { 0x2483, \ + "tdm_source2_slot" }, /* Slot Position of source 2 data , */ \ + { 0x24c3, \ + "tdm_source3_slot" }, /* Slot Position of source 3 data , */ \ + { 0x4000, \ + "int_out_flag_por" }, /* Status POR , */ \ + { 0x4010, \ + "int_out_flag_bst_ocpok" }, /* Status DCDC OCP , */ \ + { 0x4020, \ + "int_out_flag_otpok" }, /* Status OTP alarm , */ \ + { 0x4030, \ + "int_out_flag_ocp_alarm" }, /* Status OCP alarm , */ \ + { 0x4040, \ + "int_out_flag_uvpok" }, /* Status UVP alarm , */ \ + { 0x4050, \ + "int_out_flag_man_alarm_state" }, /* Status manager alarm state , */ \ + { 0x4060, \ + "int_out_flag_tdm_error" }, /* Status TDM error , */ \ + { 0x4070, \ + "int_out_flag_lost_clk" }, /* Status lost clock , */ \ + { 0x4080, \ + "int_out_flag_cfma_err" }, /* Status cfma error , */ \ + { 0x4090, \ + "int_out_flag_cfma_ack" }, /* Status cfma ack , */ \ + { 0x40a0, \ + "int_out_flag_cf_speakererror" }, /* Status coolflux speaker error , */ \ + { 0x40b0, \ + "int_out_flag_cold_started" }, /* Status cold started , */ \ + { 0x40c0, \ + "int_out_flag_watchdog_reset" }, /* Status watchdog reset , */ \ + { 0x40d0, \ + "int_out_flag_bod_vddd_nok" }, /* Status brown out detect , */ \ + { 0x40e0, \ + "int_out_flag_lp_detect_mode1" }, /* Status low power mode1 detect , */ \ + { 0x40f0, \ + "int_out_flag_clk_out_of_range" }, /* Status clock out of range , */ \ + { 0x4400, \ + "int_in_flag_por" }, /* Clear POR , */ \ + { 0x4410, \ + "int_in_flag_bst_ocpok" }, /* Clear DCDC OCP , */ \ + { 0x4420, \ + "int_in_flag_otpok" }, /* Clear OTP alarm , */ \ + { 0x4430, \ + "int_in_flag_ocp_alarm" }, /* Clear OCP alarm , */ \ + { 0x4440, \ + "int_in_flag_uvpok" }, /* Clear UVP alarm , */ \ + { 0x4450, \ + "int_in_flag_man_alarm_state" }, /* Clear manager alarm state , */ \ + { 0x4460, \ + "int_in_flag_tdm_error" }, /* Clear TDM error , */ \ + { 0x4470, \ + "int_in_flag_lost_clk" }, /* Clear lost clk , */ \ + { 0x4480, \ + "int_in_flag_cfma_err" }, /* Clear cfma err , */ \ + { 0x4490, \ + "int_in_flag_cfma_ack" }, /* Clear cfma ack , */ \ + { 0x44a0, \ + "int_in_flag_cf_speakererror" }, /* Clear coolflux speaker error , */ \ + { 0x44b0, \ + "int_in_flag_cold_started" }, /* Clear cold started , */ \ + { 0x44c0, \ + "int_in_flag_watchdog_reset" }, /* Clear watchdog reset , */ \ + { 0x44d0, \ + "int_in_flag_bod_vddd_nok" }, /* Clear brown out detect , */ \ + { 0x44e0, \ + "int_in_flag_lp_detect_mode1" }, /* Clear low power mode1 detect , */ \ + { 0x44f0, \ + "int_in_flag_clk_out_of_range" }, /* Clear clock out of range , */ \ + { 0x4800, \ + "int_enable_flag_por" }, /* Enable POR , */ \ + { 0x4810, \ + "int_enable_flag_bst_ocpok" }, /* Enable DCDC OCP , */ \ + { 0x4820, \ + "int_enable_flag_otpok" }, /* Enable OTP alarm , */ \ + { 0x4830, \ + "int_enable_flag_ocp_alarm" }, /* Enable OCP alarm , */ \ + { 0x4840, \ + "int_enable_flag_uvpok" }, /* Enable UVP alarm , */ \ + { 0x4850, \ + "int_enable_flag_man_alarm_state" }, /* Enable Manager Alarm state , */ \ + { 0x4860, \ + "int_enable_flag_tdm_error" }, /* Enable TDM error , */ \ + { 0x4870, \ + "int_enable_flag_lost_clk" }, /* Enable lost clk , */ \ + { 0x4880, \ + "int_enable_flag_cfma_err" }, /* Enable cfma err , */ \ + { 0x4890, \ + "int_enable_flag_cfma_ack" }, /* Enable cfma ack , */ \ + { 0x48a0, \ + "int_enable_flag_cf_speakererror" }, /* Enable coolflux speaker error , */ \ + { 0x48b0, \ + "int_enable_flag_cold_started" }, /* Enable cold started , */ \ + { 0x48c0, \ + "int_enable_flag_watchdog_reset" }, /* Enable watchdog reset , */ \ + { 0x48d0, \ + "int_enable_flag_bod_vddd_nok" }, /* Enable brown out detect , */ \ + { 0x48e0, \ + "int_enable_flag_lp_detect_mode1" }, /* Enable low power mode1 detect , */ \ + { 0x48f0, \ + "int_enable_flag_clk_out_of_range" }, /* Enable clock out of range , */ \ + { 0x4c00, \ + "int_polarity_flag_por" }, /* Polarity POR , */ \ + { 0x4c10, \ + "int_polarity_flag_bst_ocpok" }, /* Polarity DCDC OCP , */ \ + { 0x4c20, \ + "int_polarity_flag_otpok" }, /* Polarity OTP alarm , */ \ + { 0x4c30, \ + "int_polarity_flag_ocp_alarm" }, /* Polarity ocp alarm , */ \ + { 0x4c40, \ + "int_polarity_flag_uvpok" }, /* Polarity UVP alarm , */ \ + { 0x4c50, \ + "int_polarity_flag_man_alarm_state" }, /* Polarity manager alarm state , */ \ + { 0x4c60, \ + "int_polarity_flag_tdm_error" }, /* Polarity TDM error , */ \ + { 0x4c70, \ + "int_polarity_flag_lost_clk" }, /* Polarity lost clk , */ \ + { 0x4c80, \ + "int_polarity_flag_cfma_err" }, /* Polarity cfma err , */ \ + { 0x4c90, \ + "int_polarity_flag_cfma_ack" }, /* Polarity cfma ack , */ \ + { 0x4ca0, \ + "int_polarity_flag_cf_speakererror" }, /* Polarity coolflux speaker error , */ \ + { 0x4cb0, \ + "int_polarity_flag_cold_started" }, /* Polarity cold started , */ \ + { 0x4cc0, \ + "int_polarity_flag_watchdog_reset" }, /* Polarity watchdog reset , */ \ + { 0x4cd0, \ + "int_polarity_flag_bod_vddd_nok" }, /* Polarity brown out detect , */ \ + { 0x4ce0, \ + "int_polarity_flag_lp_detect_mode1" }, /* Polarity low power mode1 detect , */ \ + { 0x4cf0, \ + "int_polarity_flag_clk_out_of_range" }, /* Polarity clock out of range , */ \ + { 0x5001, \ + "vbat_prot_attack_time" }, /* Battery safeguard attack time , */ \ + { 0x5023, \ + "vbat_prot_thlevel" }, /* Battery safeguard threshold voltage level , */ \ + { 0x5061, \ + "vbat_prot_max_reduct" }, /* Battery safeguard maximum reduction , */ \ + { 0x5082, \ + "vbat_prot_release_time" }, /* Battery safeguard release time , */ \ + { 0x50b1, \ + "vbat_prot_hysterese" }, /* Battery Safeguard hysteresis , */ \ + { 0x50d0, \ + "rst_min_vbat" }, /* Reset clipper - auto clear , */ \ + { 0x50e0, \ + "sel_vbat" }, /* Battery voltage read out , */ \ + { 0x50f0, \ + "bypass_clipper" }, /* Bypass HW clipper , */ \ + { 0x5130, \ + "cf_mute" }, /* Coolflux firmware soft mute control , */ \ + { 0x5187, \ + "cf_volume" }, /* CF firmware volume control , */ \ + { 0x5202, \ + "ctrl_cc" }, /* Clip control setting , */ \ + { 0x5230, \ + "ctrl_slopectrl" }, /* Enables slope control , */ \ + { 0x5240, \ + "ctrl_slope" }, /* Slope speed setting (binary coded) , */ \ + { 0x5287, \ + "gain" }, /* Amplifier gain , */ \ + { 0x5301, \ + "dpsa_level" }, /* DPSA threshold levels , */ \ + { 0x5321, \ + "dpsa_release" }, /* DPSA Release time , */ \ + { 0x5340, \ + "clipfast" }, /* Clock selection for HW clipper for battery safeguard, */ \ + { 0x5350, \ + "bypass_lp" }, /* Bypass the low power filter inside temperature sensor, */ \ + { 0x5360, \ + "first_order_mode" }, /* Overrule to 1st order mode of control stage when clipping, */ \ + { 0x5370, \ + "icomp_engage" }, /* Engage of icomp , */ \ + { 0x5380, \ + "ctrl_kickback" }, /* Prevent double pulses of output stage , */ \ + { 0x5390, \ + "icomp_engage_overrule" }, /* To overrule the functional icomp_engage signal during validation, */ \ + { 0x53a3, \ + "ctrl_dem" }, /* Enable DEM icomp and DEM one bit dac , */ \ + { 0x5400, \ + "bypass_ctrlloop" }, /* Switch amplifier into open loop configuration , */ \ + { 0x5413, \ + "ctrl_dem_mismatch" }, /* Enable DEM icomp mismatch for testing , */ \ + { 0x5452, \ + "dpsa_drive" }, /* Drive setting (binary coded) , */ \ + { 0x550a, \ + "enbl_amp" }, /* Switch on the class-D power sections, each part of the analog sections can be switched on/off individually, */ \ + { 0x55b0, \ + "enbl_engage" }, /* Enables/engage power stage and control loop , */ \ + { 0x55c0, \ + "enbl_engage_pst" }, /* Enables/engage power stage and control loop , */ \ + { 0x5600, \ + "pwm_shape" }, /* PWM shape , */ \ + { 0x5614, \ + "pwm_delay" }, /* PWM delay bits to set the delay, clockd is 1/(k*2048*fs), */ \ + { 0x5660, \ + "reclock_pwm" }, /* Reclock the PWM signal inside analog , */ \ + { 0x5670, \ + "reclock_voltsense" }, /* Reclock the voltage sense PWM signal , */ \ + { 0x5680, \ + "enbl_pwm_phase_shift" }, /* Control for PWM phase shift , */ \ + { 0x5690, \ + "sel_pwm_delay_src" }, /* Control for selection for PWM delay line source , */ \ + { 0x56a1, \ + "enbl_odd_up_even_down" }, /* Control for PWM reference sawtooth generartion , */ \ + { 0x5703, \ + "ctrl_att_dcdc" }, /* Second channel gain in case of stereo using a single coil. (Total gain depending on INPLEV). (In case of mono OR stereo using 2 separate DCDC channel 1 should be disabled using TDMDCE), */ \ + { 0x5743, \ + "ctrl_att_spkr" }, /* Total gain depending on INPLEV setting (channel 0), */ \ + { 0x5781, \ + "vamp_sel2" }, /* VAMP_OUT2 input selection , */ \ + { 0x5805, \ + "zero_lvl" }, /* Low noise gain switch zero trigger level , */ \ + { 0x5861, \ + "ctrl_fb_resistor" }, /* Select amplifier feedback resistor connection , */ \ + { 0x5881, \ + "lownoisegain_mode" }, /* Low noise gain mode control , */ \ + { 0x5905, \ + "threshold_lvl" }, /* Low noise gain switch trigger level , */ \ + { 0x5965, \ + "hold_time" }, /* Low noise mode hold time before entering into low noise mode, */ \ + { 0x5a05, \ + "lpm1_cal_offset" }, /* Low power mode1 detector ctrl cal_offset from gain module , */ \ + { 0x5a65, \ + "lpm1_zero_lvl" }, /* Low power mode1 zero crossing detection level , */ \ + { 0x5ac1, \ + "lpm1_mode" }, /* Low power mode control , */ \ + { 0x5b05, \ + "lpm1_threshold_lvl" }, /* Low power mode1 amplitude trigger level , */ \ + { 0x5b65, \ + "lpm1_hold_time" }, /* Low power mode hold time before entering into low power mode, */ \ + { 0x5bc0, \ + "disable_low_power_mode" }, /* Low power mode1 detector control , */ \ + { 0x5c00, \ + "enbl_minion" }, /* Enables minion (small) power stage , */ \ + { 0x5c13, \ + "vth_vddpvbat" }, /* Select vddp-vbat threshold signal , */ \ + { 0x5c50, \ + "lpen_vddpvbat" }, /* Select vddp-vbat filtred vs unfiltered compare , */ \ + { 0x5c61, \ + "ctrl_rfb" }, /* Feedback resistor selection - I2C direct mode , */ \ + { 0x5d02, \ + "tdm_source_mapping" }, /* TDM source mapping , */ \ + { 0x5d31, \ + "tdm_sourcea_frame_sel" }, /* Sensed value A , */ \ + { 0x5d51, \ + "tdm_sourceb_frame_sel" }, /* Sensed value B , */ \ + { 0x5d71, \ + "tdm_source0_clip_sel" }, /* Clip information (analog /digital) for source0 , */ \ + { 0x5d91, \ + "tdm_source1_clip_sel" }, /* Clip information (analog /digital) for source1 , */ \ + { 0x5e02, \ + "rst_min_vbat_delay" }, /* Delay for reseting the min_vbat value inside HW Clipper (number of Fs pulses), */ \ + { 0x5e30, \ + "rst_min_vbat_sel" }, /* Control for selecting reset signal for min_bat , */ \ + { 0x5f00, \ + "hard_mute" }, /* Hard mute - PWM , */ \ + { 0x5f12, \ + "ns_hp2ln_criterion" }, /* 0..7 zeroes at ns as threshold to swap from high_power to low_noise, */ \ + { 0x5f42, \ + "ns_ln2hp_criterion" }, /* 0..7 zeroes at ns as threshold to swap from low_noise to high_power, */ \ + { 0x5f78, \ + "spare_out" }, /* Spare out register , */ \ + { 0x600f, \ + "spare_in" }, /* Spare IN , */ \ + { 0x6102, \ + "cursense_comp_delay" }, /* Delay to allign compensation signal with current sense signal, */ \ + { 0x6130, \ + "cursense_comp_sign" }, /* Polarity of compensation for current sense , */ \ + { 0x6140, \ + "enbl_cursense_comp" }, /* Enable current sense compensation , */ \ + { 0x6152, \ + "pwms_clip_lvl" }, /* Set the amount of pwm pulse that may be skipped before clip-flag is triggered, */ \ + { 0x7005, \ + "frst_boost_voltage" }, /* First Boost Voltage Level , */ \ + { 0x7065, \ + "scnd_boost_voltage" }, /* Second Boost Voltage Level , */ \ + { 0x70c3, \ + "boost_cur" }, /* Max Coil Current , */ \ + { 0x7101, \ + "bst_slpcmplvl" }, /* Slope compensation current, represents LxF (inductance x frequency) value , */ \ + { 0x7120, \ + "boost_intel" }, /* Adaptive boost mode , */ \ + { 0x7130, \ + "boost_speed" }, /* Soft ramp up/down , */ \ + { 0x7140, \ + "dcdcoff_mode" }, /* DCDC on/off , */ \ + { 0x7150, \ + "dcdc_pwmonly" }, /* DCDC PWM only mode , */ \ + { 0x7160, \ + "boost_track" }, /* Boost algorithm selection, effective only when boost_intelligent is set to 1, */ \ + { 0x7170, \ + "sel_dcdc_envelope_8fs" }, /* Selection of data for adaptive boost algorithm, effective only when boost_intelligent is set to 1, */ \ + { 0x7180, \ + "ignore_flag_voutcomp86" }, /* Determines the maximum PWM frequency be the most efficient in relation to the Booster inductor value, */ \ + { 0x7204, \ + "boost_trip_lvl_1st" }, /* 1st adaptive boost trip levels, effective only when DCIE is set to 1, */ \ + { 0x7254, \ + "boost_trip_lvl_2nd" }, /* 2nd adaptive boost trip levels, effective only when DCIE is set to 1, */ \ + { 0x72a4, \ + "boost_trip_lvl_track" }, /* Track adaptive boost trip levels, effective only when boost_intelligent is set to 1, */ \ + { 0x72f0, \ + "enbl_trip_hyst" }, /* Enable hysteresis on booster trip levels , */ \ + { 0x7304, \ + "boost_hold_time" }, /* Hold time for DCDC booster, effective only when boost_intelligent is set to 1, */ \ + { 0x7350, \ + "dcdc_pfm20khz_limit" }, /* DCDC in PFM mode pwm mode is activated each 50us to force a pwm pulse, */ \ + { 0x7361, \ + "dcdc_ctrl_maxzercnt" }, /* Number of zero current flags to count before going to pfm mode, */ \ + { 0x7386, \ + "dcdc_vbat_delta_detect" }, /* Threshold before booster is reacting on a delta Vbat (in PFM mode) by temporarily switching to PWM mode, */ \ + { 0x73f0, \ + "dcdc_ignore_vbat" }, /* Ignore an increase on Vbat , */ \ + { 0x7404, \ + "bst_drive" }, /* Binary coded drive setting for boost converter power stage, */ \ + { 0x7451, \ + "bst_scalecur" }, /* For testing direct control scale current , */ \ + { 0x7474, \ + "bst_slopecur" }, /* For testing direct control slope current , */ \ + { 0x74c1, \ + "bst_slope" }, /* Boost slope speed , */ \ + { 0x74e0, \ + "bst_bypass_bstcur" }, /* Bypass control for boost current settings , */ \ + { 0x74f0, \ + "bst_bypass_bstfoldback" }, /* Bypass control for boost foldback , */ \ + { 0x7500, \ + "enbl_bst_engage" }, /* Enable power stage dcdc controller , */ \ + { 0x7510, \ + "enbl_bst_hizcom" }, /* Enable hiz comparator , */ \ + { 0x7520, \ + "enbl_bst_peakcur" }, /* Enable peak current , */ \ + { 0x7530, \ + "enbl_bst_power" }, /* Enable line of the powerstage , */ \ + { 0x7540, \ + "enbl_bst_slopecur" }, /* Enable bit of max-current dac , */ \ + { 0x7550, \ + "enbl_bst_voutcomp" }, /* Enable vout comparators , */ \ + { 0x7560, \ + "enbl_bst_voutcomp86" }, /* Enable vout-86 comparators , */ \ + { 0x7570, \ + "enbl_bst_voutcomp93" }, /* Enable vout-93 comparators , */ \ + { 0x7580, \ + "enbl_bst_windac" }, /* Enable window dac , */ \ + { 0x7595, \ + "bst_windac" }, /* For testing direct control windac , */ \ + { 0x7600, \ + "boost_alg" }, /* Control for boost adaptive loop gain , */ \ + { 0x7611, \ + "boost_loopgain" }, /* DCDC boost loopgain setting , */ \ + { 0x7631, \ + "bst_freq" }, /* DCDC boost frequency control , */ \ + { 0x7650, \ + "enbl_bst_peak2avg" }, /* Enable boost peak2avg functionality , */ \ + { 0x7660, \ + "bst_use_new_zercur_detect" }, /* Enable new zero current detection for boost control, */ \ + { 0x8001, \ + "sel_clk_cs" }, /* Current sense clock duty cycle control , */ \ + { 0x8021, \ + "micadc_speed" }, /* Current sense clock for MiCADC selection - 32/44.1/48 KHz Fs band only, */ \ + { 0x8040, \ + "cs_gain_control" }, /* Current sense gain control , */ \ + { 0x8050, \ + "cs_bypass_gc" }, /* Bypasses the CS gain correction , */ \ + { 0x8060, \ + "invertpwm" }, /* Current sense common mode feedback pwm invert control, */ \ + { 0x8087, \ + "cs_gain" }, /* Current sense gain , */ \ + { 0x8105, \ + "cs_ktemp" }, /* Current sense temperature compensation trimming (1 - VALUE*TEMP) * signal, */ \ + { 0x8164, \ + "cs_ktemp2" }, /* Second order temperature compensation coefficient , */ \ + { 0x81b0, \ + "enbl_cs_adc" }, /* Enable current sense ADC , */ \ + { 0x81c0, \ + "enbl_cs_inn1" }, /* Enable connection of current sense negative1 , */ \ + { 0x81d0, \ + "enbl_cs_inn2" }, /* Enable connection of current sense negative2 , */ \ + { 0x81e0, \ + "enbl_cs_inp1" }, /* Enable connection of current sense positive1 , */ \ + { 0x81f0, \ + "enbl_cs_inp2" }, /* Enable connection of current sense positive2 , */ \ + { 0x8200, \ + "enbl_cs_ldo" }, /* Enable current sense LDO , */ \ + { 0x8210, \ + "enbl_cs_vbatldo" }, /* Enable of current sense LDO , */ \ + { 0x8220, \ + "cs_adc_bsoinv" }, /* Bitstream inversion for current sense ADC , */ \ + { 0x8231, \ + "cs_adc_hifreq" }, /* Frequency mode current sense ADC , */ \ + { 0x8250, \ + "cs_adc_nortz" }, /* Return to zero for current sense ADC , */ \ + { 0x8263, \ + "cs_adc_offset" }, /* Micadc ADC offset setting , */ \ + { 0x82a0, \ + "cs_adc_slowdel" }, /* Select delay for current sense ADC (internal decision circuitry), */ \ + { 0x82b4, \ + "cs_adc_gain" }, /* Gain setting for current sense ADC (two's complement), */ \ + { 0x8300, \ + "cs_resonator_enable" }, /* Enable for resonator to improve SRN , */ \ + { 0x8310, \ + "cs_classd_tran_skip" }, /* Skip current sense connection during a classD amplifier transition, */ \ + { 0x8320, \ + "cs_inn_short" }, /* Short current sense negative to common mode , */ \ + { 0x8330, \ + "cs_inp_short" }, /* Short current sense positive to common mode , */ \ + { 0x8340, \ + "cs_ldo_bypass" }, /* Bypass current sense LDO , */ \ + { 0x8350, \ + "cs_ldo_pulldown" }, /* Pull down current sense LDO, only valid if enbl_cs_ldo is high, */ \ + { 0x8364, \ + "cs_ldo_voset" }, /* Current sense LDO voltage level setting (two's complement), */ \ + { 0x8800, \ + "ctrl_vs_igen_supply" }, /* Control for selecting supply for VS current generator, */ \ + { 0x8810, \ + "ctrl_vs_force_div2" }, /* Select input resistive divider gain , */ \ + { 0x8820, \ + "enbl_dc_filter" }, /* Control for enabling the DC blocking filter for voltage and current sense, */ \ + { 0x8901, \ + "volsense_pwm_sel" }, /* Voltage sense source selection control , */ \ + { 0x8920, \ + "vs_gain_control" }, /* Voltage sense gain control , */ \ + { 0x8930, \ + "vs_bypass_gc" }, /* Bypasses the VS gain correction , */ \ + { 0x8940, \ + "vs_adc_bsoinv" }, /* Bitstream inversion for voltage sense ADC , */ \ + { 0x8950, \ + "vs_adc_nortz" }, /* Return to zero for voltage sense ADC , */ \ + { 0x8960, \ + "vs_adc_slowdel" }, /* Select delay for voltage sense ADC (internal decision circuitry), */ \ + { 0x8970, \ + "vs_classd_tran_skip" }, /* Skip voltage sense connection during a classD amplifier transition, */ \ + { 0x8987, \ + "vs_gain" }, /* Voltage sense gain , */ \ + { 0x8a00, \ + "vs_inn_short" }, /* Short voltage sense negative to common mode , */ \ + { 0x8a10, \ + "vs_inp_short" }, /* Short voltage sense positive to common mode , */ \ + { 0x8a20, \ + "vs_ldo_bypass" }, /* Bypass voltage sense LDO , */ \ + { 0x8a30, \ + "vs_ldo_pulldown" }, /* Pull down voltage sense LDO, only valid if enbl_cs_ldo is high, */ \ + { 0x8a44, \ + "vs_ldo_voset" }, /* Voltage sense LDO voltage level setting (two's complement), */ \ + { 0x8a90, \ + "enbl_vs_adc" }, /* Enable voltage sense ADC , */ \ + { 0x8aa0, \ + "enbl_vs_inn1" }, /* Enable connection of voltage sense negative1 , */ \ + { 0x8ab0, \ + "enbl_vs_inn2" }, /* Enable connection of voltage sense negative2 , */ \ + { 0x8ac0, \ + "enbl_vs_inp1" }, /* Enable connection of voltage sense positive1 , */ \ + { 0x8ad0, \ + "enbl_vs_inp2" }, /* Enable connection of voltage sense positive2 , */ \ + { 0x8ae0, \ + "enbl_vs_ldo" }, /* Enable voltage sense LDO , */ \ + { 0x8af0, \ + "enbl_vs_vbatldo" }, /* Enable of voltage sense LDO , */ \ + { 0x9000, \ + "cf_rst_dsp" }, /* Reset for Coolflux DSP , */ \ + { 0x9011, \ + "cf_dmem" }, /* Target memory for CFMA using I2C interface , */ \ + { 0x9030, \ + "cf_aif" }, /* Auto increment , */ \ + { 0x9040, \ + "cf_int" }, /* Coolflux Interrupt - auto clear , */ \ + { 0x9050, \ + "cf_cgate_off" }, /* Coolflux clock gating disabling control , */ \ + { 0x9080, \ + "cf_req_cmd" }, /* Firmware event request rpc command , */ \ + { 0x9090, \ + "cf_req_reset" }, /* Firmware event request reset restart , */ \ + { 0x90a0, \ + "cf_req_mips" }, /* Firmware event request short on mips , */ \ + { 0x90b0, \ + "cf_req_mute_ready" }, /* Firmware event request mute sequence ready , */ \ + { 0x90c0, \ + "cf_req_volume_ready" }, /* Firmware event request volume ready , */ \ + { 0x90d0, \ + "cf_req_damage" }, /* Firmware event request speaker damage detected , */ \ + { 0x90e0, \ + "cf_req_calibrate_ready" }, /* Firmware event request calibration completed , */ \ + { 0x90f0, \ + "cf_req_reserved" }, /* Firmware event request reserved , */ \ + { 0x910f, \ + "cf_madd" }, /* CF memory address , */ \ + { 0x920f, \ + "cf_mema" }, /* Activate memory access , */ \ + { 0x9307, \ + "cf_err" }, /* CF error flags , */ \ + { 0x9380, \ + "cf_ack_cmd" }, /* Firmware event acknowledge rpc command , */ \ + { 0x9390, \ + "cf_ack_reset" }, /* Firmware event acknowledge reset restart , */ \ + { 0x93a0, \ + "cf_ack_mips" }, /* Firmware event acknowledge short on mips , */ \ + { 0x93b0, \ + "cf_ack_mute_ready" }, /* Firmware event acknowledge mute sequence ready , */ \ + { 0x93c0, \ + "cf_ack_volume_ready" }, /* Firmware event acknowledge volume ready , */ \ + { 0x93d0, \ + "cf_ack_damage" }, /* Firmware event acknowledge speaker damage detected, */ \ + { 0x93e0, \ + "cf_ack_calibrate_ready" }, /* Firmware event acknowledge calibration completed , */ \ + { 0x93f0, \ + "cf_ack_reserved" }, /* Firmware event acknowledge reserved , */ \ + { 0xa007, \ + "mtpkey1" }, /* KEY1 To access KEY1 protected registers 0x5A/90d (default for engineering), */ \ + { 0xa107, \ + "mtpkey2" }, /* KEY2 to access KEY2 protected registers, customer key, */ \ + { 0xa200, \ + "key01_locked" }, /* Indicates KEY1 is locked , */ \ + { 0xa210, \ + "key02_locked" }, /* Indicates KEY2 is locked , */ \ + { 0xa302, \ + "mtp_man_address_in" }, /* MTP address from I2C register for read/writing mtp in manual single word mode, */ \ + { 0xa330, \ + "man_copy_mtp_to_iic" }, /* Start copying single word from MTP to I2C mtp register - auto clear, */ \ + { 0xa340, \ + "man_copy_iic_to_mtp" }, /* Start copying single word from I2C mtp register to mtp - auto clear, */ \ + { 0xa350, \ + "auto_copy_mtp_to_iic" }, /* Start copying all the data from mtp to I2C mtp registers - auto clear, */ \ + { 0xa360, \ + "auto_copy_iic_to_mtp" }, /* Start copying data from I2C mtp registers to mtp - auto clear, */ \ + { 0xa400, \ + "faim_set_clkws" }, /* Sets the FaIM controller clock wait state register, */ \ + { 0xa410, \ + "faim_sel_evenrows" }, /* All even rows of the FaIM are selected, active high, */ \ + { 0xa420, \ + "faim_sel_oddrows" }, /* All odd rows of the FaIM are selected, all rows in combination with sel_evenrows, */ \ + { 0xa430, \ + "faim_program_only" }, /* Skip the erase access at wr_faim command (write-program-marginread), */ \ + { 0xa440, \ + "faim_erase_only" }, /* Skip the program access at wr_faim command (write-erase-marginread), */ \ + { 0xa50f, \ + "mtp_man_data_out_msb" }, /* MSB word of MTP manual read data , */ \ + { 0xa60f, \ + "mtp_man_data_out_lsb" }, /* LSB word of MTP manual read data , */ \ + { 0xa70f, \ + "mtp_man_data_in_msb" }, /* MSB word of write data for MTP manual write , */ \ + { 0xa80f, \ + "mtp_man_data_in_lsb" }, /* LSB word of write data for MTP manual write , */ \ + { 0xb000, \ + "bypass_ocpcounter" }, /* Bypass OCP Counter , */ \ + { 0xb010, \ + "bypass_glitchfilter" }, /* Bypass glitch filter , */ \ + { 0xb020, \ + "bypass_ovp" }, /* Bypass OVP , */ \ + { 0xb030, \ + "bypass_uvp" }, /* Bypass UVP , */ \ + { 0xb040, \ + "bypass_otp" }, /* Bypass OTP , */ \ + { 0xb050, \ + "bypass_lost_clk" }, /* Bypass lost clock detector , */ \ + { 0xb060, \ + "ctrl_vpalarm" }, /* vpalarm (uvp ovp handling) , */ \ + { 0xb070, \ + "disable_main_ctrl_change_prot" }, /* Disable main control change protection , */ \ + { 0xb087, \ + "ocp_threshold" }, /* OCP threshold level , */ \ + { 0xb108, \ + "ext_temp" }, /* External temperature (C) , */ \ + { 0xb190, \ + "ext_temp_sel" }, /* Select temp Speaker calibration , */ \ + { 0xc000, \ + "use_direct_ctrls" }, /* Direct control to overrule several functions for testing, */ \ + { 0xc010, \ + "rst_datapath" }, /* Direct control for datapath reset , */ \ + { 0xc020, \ + "rst_cgu" }, /* Direct control for cgu reset , */ \ + { 0xc038, \ + "enbl_ref" }, /* Switch on the analog references, each part of the references can be switched on/off individually, */ \ + { 0xc0c0, \ + "use_direct_vs_ctrls" }, /* Voltage sense direct control to overrule several functions for testing, */ \ + { 0xc0d0, \ + "enbl_ringo" }, /* Enable the ring oscillator for test purpose , */ \ + { 0xc0e0, \ + "use_direct_clk_ctrl" }, /* Direct clock control to overrule several functions for testing, */ \ + { 0xc0f0, \ + "use_direct_pll_ctrl" }, /* Direct PLL control to overrule several functions for testing, */ \ + { 0xc100, \ + "enbl_tsense" }, /* Temperature sensor enable control - I2C direct mode, */ \ + { 0xc110, \ + "tsense_hibias" }, /* Bit to set the biasing in temp sensor to high , */ \ + { 0xc120, \ + "enbl_flag_vbg" }, /* Enable flagging of bandgap out of control , */ \ + { 0xc20f, \ + "abist_offset" }, /* Offset control for ABIST testing (two's complement), */ \ + { 0xc300, \ + "bypasslatch" }, /* Bypass latch , */ \ + { 0xc311, \ + "sourcea" }, /* Set OUTA to , */ \ + { 0xc331, \ + "sourceb" }, /* Set OUTB to , */ \ + { 0xc350, \ + "inverta" }, /* Invert pwma test signal , */ \ + { 0xc360, \ + "invertb" }, /* Invert pwmb test signal , */ \ + { 0xc374, \ + "pulselength" }, /* Pulse length setting test input for amplifier (clock d - k*2048*fs), */ \ + { 0xc3d0, \ + "test_abistfft_enbl" }, /* Enable ABIST with FFT on Coolflux DSP , */ \ + { 0xc400, \ + "bst_bypasslatch" }, /* Bypass latch in boost converter , */ \ + { 0xc411, \ + "bst_source" }, /* Sets the source of the pwmbst output to boost converter input for testing, */ \ + { 0xc430, \ + "bst_invertb" }, /* Invert pwmbst test signal , */ \ + { 0xc444, \ + "bst_pulselength" }, /* Pulse length setting test input for boost converter , */ \ + { 0xc490, \ + "test_bst_ctrlsthv" }, /* Test mode for boost control stage , */ \ + { 0xc4a0, \ + "test_bst_iddq" }, /* IDDQ testing in power stage of boost converter , */ \ + { 0xc4b0, \ + "test_bst_rdson" }, /* RDSON testing - boost power stage , */ \ + { 0xc4c0, \ + "test_bst_cvi" }, /* CVI testing - boost power stage , */ \ + { 0xc4d0, \ + "test_bst_ocp" }, /* Boost OCP. For old ocp (ctrl_reversebst is 0), For new ocp (ctrl_reversebst is 1), */ \ + { 0xc4e0, \ + "test_bst_sense" }, /* Test option for the sense NMOS in booster for current mode control., */ \ + { 0xc500, \ + "test_cvi" }, /* Analog BIST, switch choose which transistor will be used as current source (also cross coupled sources possible), */ \ + { 0xc510, \ + "test_discrete" }, /* Test function noise measurement , */ \ + { 0xc520, \ + "test_iddq" }, /* Set the power stages in iddq mode for gate stress., */ \ + { 0xc530, \ + "test_rdson" }, /* Analog BIST, switch to enable Rdson measurement , */ \ + { 0xc540, \ + "test_sdelta" }, /* Analog BIST, noise test , */ \ + { 0xc550, \ + "test_enbl_cs" }, /* Enable for digimux mode of current sense , */ \ + { 0xc560, \ + "test_enbl_vs" }, /* Enable for digimux mode of voltage sense , */ \ + { 0xc570, \ + "enbl_pwm_dcc" }, /* Enables direct control of pwm duty cycle for DCDC power stage, */ \ + { 0xc583, \ + "pwm_dcc_cnt" }, /* Control pwm duty cycle when enbl_pwm_dcc is 1 , */ \ + { 0xc5c0, \ + "enbl_ldo_stress" }, /* Enable stress of internal supply voltages powerstages, */ \ + { 0xc607, \ + "digimuxa_sel" }, /* DigimuxA input selection control routed to DATAO , */ \ + { 0xc687, \ + "digimuxb_sel" }, /* DigimuxB input selection control routed to INT , */ \ + { 0xc707, \ + "digimuxc_sel" }, /* DigimuxC input selection control routed to ADS1 , */ \ + { 0xc800, \ + "enbl_anamux1" }, /* Enable anamux1 , */ \ + { 0xc810, \ + "enbl_anamux2" }, /* Enable anamux2 , */ \ + { 0xc820, \ + "enbl_anamux3" }, /* Enable anamux3 , */ \ + { 0xc830, \ + "enbl_anamux4" }, /* Enable anamux4 , */ \ + { 0xc844, \ + "anamux1" }, /* Anamux selection control - anamux on TEST1 , */ \ + { 0xc894, \ + "anamux2" }, /* Anamux selection control - anamux on TEST2 , */ \ + { 0xc903, \ + "anamux3" }, /* Anamux selection control - anamux on TEST3 , */ \ + { 0xc943, \ + "anamux4" }, /* Anamux selection control - anamux on TEST4 , */ \ + { 0xca05, \ + "pll_seli" }, /* PLL SELI - I2C direct PLL control mode only , */ \ + { 0xca64, \ + "pll_selp" }, /* PLL SELP - I2C direct PLL control mode only , */ \ + { 0xcab3, \ + "pll_selr" }, /* PLL SELR - I2C direct PLL control mode only , */ \ + { 0xcaf0, \ + "pll_frm" }, /* PLL free running mode control; 1 in TCB direct control mode, else this control bit, */ \ + { 0xcb09, \ + "pll_ndec" }, /* PLL NDEC - I2C direct PLL control mode only , */ \ + { 0xcba0, \ + "pll_mdec_msb" }, /* MSB of PLL_mdec - I2C direct PLL control mode only, */ \ + { 0xcbb0, \ + "enbl_pll" }, /* Enables PLL in I2C direct PLL control mode only , */ \ + { 0xcbc0, \ + "enbl_osc" }, /* Enables OSC1M in I2C direct control mode only , */ \ + { 0xcbd0, \ + "pll_bypass" }, /* PLL bypass control in I2C direct PLL control mode only, */ \ + { 0xcbe0, \ + "pll_directi" }, /* PLL directi control in I2C direct PLL control mode only, */ \ + { 0xcbf0, \ + "pll_directo" }, /* PLL directo control in I2C direct PLL control mode only, */ \ + { 0xcc0f, \ + "pll_mdec_lsb" }, /* Bits 15..0 of PLL MDEC are I2C direct PLL control mode only, */ \ + { 0xcd06, \ + "pll_pdec" }, /* PLL PDEC - I2C direct PLL control mode only , */ \ + { 0xce0f, \ + "tsig_freq_lsb" }, /* Internal sinus test generator frequency control , */ \ + { 0xcf02, \ + "tsig_freq_msb" }, /* Select internal sinus test generator, frequency control msb bits, */ \ + { 0xcf33, \ + "tsig_gain" }, /* Test signal gain , */ \ + { 0xd000, \ + "adc10_reset" }, /* Reset for ADC10 - I2C direct control mode , */ \ + { 0xd011, \ + "adc10_test" }, /* Test mode selection signal for ADC10 - I2C direct control mode, */ \ + { 0xd032, \ + "adc10_sel" }, /* Select the input to convert for ADC10 - I2C direct control mode, */ \ + { 0xd064, \ + "adc10_prog_sample" }, /* ADC10 program sample setting - I2C direct control mode, */ \ + { 0xd0b0, \ + "adc10_enbl" }, /* Enable ADC10 - I2C direct control mode , */ \ + { 0xd0c0, \ + "bypass_lp_vbat" }, /* Bypass control for Low pass filter in batt sensor , */ \ + { 0xd109, \ + "data_adc10_tempbat" }, /* ADC 10 data output data for testing , */ \ + { 0xd201, \ + "clkdiv_audio_sel" }, /* Audio clock divider selection in direct clock control mode, */ \ + { 0xd221, \ + "clkdiv_muxa_sel" }, /* DCDC MUXA clock divider selection in direct clock control mode, */ \ + { 0xd241, \ + "clkdiv_muxb_sel" }, /* DCDC MUXB clock divider selection in direct clock control mode, */ \ + { 0xd301, \ + "int_ehs" }, /* Speed/load setting for INT IO cell, clk or data mode range (see SLIMMF IO datasheet), */ \ + { 0xd321, \ + "datao_ehs" }, /* Speed/load setting for DATAO IO cell, clk or data mode range (see SLIMMF IO datasheet), */ \ + { 0xd340, \ + "hs_mode" }, /* I2C high speed mode control , */ \ + { 0xd407, \ + "ctrl_digtoana_hidden" }, /* Spare digital to analog control bits - Hidden , */ \ + { 0xd480, \ + "enbl_clk_out_of_range" }, /* Clock out of range , */ \ + { 0xd491, \ + "sel_wdt_clk" }, /* Watch dog clock divider settings , */ \ + { 0xd4b0, \ + "inject_tsig" }, /* Control bit to switch to internal sinus test generator, */ \ + { 0xd500, \ + "source_in_testmode" }, /* TDM source in test mode (return only current and voltage sense), */ \ + { 0xd510, \ + "gainatt_feedback" }, /* Gainatt feedback to tdm , */ \ + { 0xd522, \ + "test_parametric_io" }, /* Test IO parametric , */ \ + { 0xd550, \ + "ctrl_bst_clk_lp1" }, /* Boost clock control in low power mode1 , */ \ + { 0xd561, \ + "test_spare_out1" }, /* Test spare out 1 , */ \ + { 0xd580, \ + "bst_dcmbst" }, /* DCM boost , */ \ + { 0xd593, \ + "test_spare_out2" }, /* Test spare out 2 , */ \ + { 0xe00f, \ + "sw_profile" }, /* Software profile data , */ \ + { 0xe10f, \ + "sw_vstep" }, /* Software vstep information , */ \ + { 0xf000, \ + "calibration_onetime" }, /* Calibration schedule , */ \ + { 0xf010, \ + "calibr_ron_done" }, /* Calibration Ron executed , */ \ + { 0xf020, \ + "calibr_dcdc_api_calibrate" }, /* Calibration current limit DCDC , */ \ + { 0xf030, \ + "calibr_dcdc_delta_sign" }, /* Sign bit for delta calibration current limit DCDC , */ \ + { 0xf042, \ + "calibr_dcdc_delta" }, /* Calibration delta current limit DCDC , */ \ + { 0xf078, \ + "calibr_speaker_info" }, /* Reserved space for allowing customer to store speaker information, */ \ + { 0xf105, \ + "calibr_vout_offset" }, /* DCDC offset calibration 2's complement (key1 protected), */ \ + { 0xf163, \ + "calibr_vbg_trim" }, /* Bandgap trimming control , */ \ + { 0xf203, \ + "calibr_gain" }, /* HW gain module (2's complement) , */ \ + { 0xf245, \ + "calibr_offset" }, /* Offset for amplifier, HW gain module (2's complement), */ \ + { 0xf307, \ + "calibr_gain_vs" }, /* Voltage sense gain , */ \ + { 0xf387, \ + "calibr_gain_cs" }, /* Current sense gain (signed two's complement format), */ \ + { 0xf40f, \ + "mtpdata4" }, /* MTP4 data , */ \ + { 0xf50f, \ + "calibr_R25C" }, /* Ron resistance of speaker coil , */ \ + { 0xf60f, \ + "mtpdata6" }, /* MTP6 data , */ \ + { 0xf706, \ + "ctrl_offset_a" }, /* Offset of level shifter A , */ \ + { 0xf786, \ + "ctrl_offset_b" }, /* Offset of amplifier level shifter B , */ \ + { 0xf806, \ + "htol_iic_addr" }, /* 7-bit I2C address to be used during HTOL testing , */ \ + { 0xf870, \ + "htol_iic_addr_en" }, /* HTOL I2C address enable control , */ \ + { 0xf884, \ + "calibr_temp_offset" }, /* Temperature offset 2's compliment (key1 protected), */ \ + { 0xf8d2, \ + "calibr_temp_gain" }, /* Temperature gain 2's compliment (key1 protected) , */ \ + { 0xf900, \ + "mtp_lock_dcdcoff_mode" }, /* Disable functionality of dcdcoff_mode bit , */ \ + { 0xf910, \ + "mtp_lock_enbl_coolflux" }, /* Disable functionality of enbl_coolflux bit , */ \ + { 0xf920, \ + "mtp_lock_bypass_clipper" }, /* Disable function bypass_clipper , */ \ + { 0xf930, \ + "mtp_enbl_pwm_delay_clock_gating" }, /* PWM delay clock auto gating , */ \ + { 0xf940, \ + "mtp_enbl_ocp_clock_gating" }, /* OCP clock auto gating , */ \ + { 0xf950, \ + "mtp_gate_cgu_clock_for_test" }, /* CGU test clock control , */ \ + { 0xf987, \ + "type_bits_fw" }, /* MTP control for firmware features - See Firmware I2C API document for details, */ \ + { 0xfa0f, \ + "mtpdataA" }, /* MTPdataA , */ \ + { 0xfb0f, \ + "mtpdataB" }, /* MTPdataB , */ \ + { 0xfc0f, \ + "mtpdataC" }, /* MTPdataC , */ \ + { 0xfd0f, \ + "mtpdataD" }, /* MTPdataD , */ \ + { 0xfe0f, \ + "mtpdataE" }, /* MTPdataE , */ \ + { 0xff07, \ + "calibr_osc_delta_ndiv" }, /* Calibration data for OSC1M, signed number representation, */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +enum tfa9894_irq { tfa9894_irq_max = -1, tfa9894_irq_all = -1 /* all irqs */ }; + +#define TFA9894_IRQ_NAMETABLE static tfaIrqName_t Tfa9894IrqNames[] = {}; +#endif /* _TFA9894_TFAFIELDNAMES_H */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9896_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9896_tfafieldnames.h new file mode 100644 index 000000000000..7d0a6fda5108 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9896_tfafieldnames.h @@ -0,0 +1,1732 @@ +/** Filename: tfa9896_tfafieldnames.h + * This file was generated automatically on 08/15/16 at 09:43:38. + * Source file: TFA9896_N1B1_I2C_regmap_V16.xlsx + */ + +#ifndef _TFA9896_TFAFIELDNAMES_H +#define _TFA9896_TFAFIELDNAMES_H + +#define TFA9896_I2CVERSION 16 + +typedef enum nxpTFA9896BfEnumList { + TFA9896_BF_VDDS = + 0x0000, /*!< Power-on-reset flag (auto clear by reading) */ + TFA9896_BF_PLLS = + 0x0010, /*!< PLL lock to programmed frequency */ + TFA9896_BF_OTDS = + 0x0020, /*!< Over Temperature Protection alarm */ + TFA9896_BF_OVDS = + 0x0030, /*!< Over Voltage Protection alarm */ + TFA9896_BF_UVDS = + 0x0040, /*!< Under Voltage Protection alarm */ + TFA9896_BF_OCDS = + 0x0050, /*!< Over Current Protection alarm */ + TFA9896_BF_CLKS = + 0x0060, /*!< Clocks stable flag */ + TFA9896_BF_CLIPS = + 0x0070, /*!< Amplifier clipping */ + TFA9896_BF_MTPB = + 0x0080, /*!< MTP busy copying data to/from I2C registers */ + TFA9896_BF_NOCLK = + 0x0090, /*!< lost clock detection (reference input clock) */ + TFA9896_BF_SPKS = + 0x00a0, /*!< Speaker error */ + TFA9896_BF_ACS = + 0x00b0, /*!< Cold Start required */ + TFA9896_BF_SWS = + 0x00c0, /*!< Amplifier engage (Amp Switching) */ + TFA9896_BF_WDS = + 0x00d0, /*!< watchdog reset (activates reset) */ + TFA9896_BF_AMPS = + 0x00e0, /*!< Amplifier is enabled by manager */ + TFA9896_BF_AREFS = + 0x00f0, /*!< References are enabled by manager */ + TFA9896_BF_BATS = + 0x0109, /*!< Battery voltage from ADC readout */ + TFA9896_BF_TEMPS = + 0x0208, /*!< Temperature readout from the temperature sensor ( C) */ + TFA9896_BF_REV = + 0x030f, /*!< Device revision information */ + TFA9896_BF_RCV = + 0x0420, /*!< Enable receiver mode */ + TFA9896_BF_CHS12 = + 0x0431, /*!< Channel Selection TDM input for Coolflux */ + TFA9896_BF_INPLVL = + 0x0450, /*!< Input level selection attenuator ( */ + TFA9896_BF_CHSA = + 0x0461, /*!< Input selection for amplifier */ + TFA9896_BF_AUDFS = + 0x04c3, /*!< Audio sample rate setting */ + TFA9896_BF_BSSCR = + 0x0501, /*!< Batteery protection attack time */ + TFA9896_BF_BSST = + 0x0523, /*!< Battery protection threshold level */ + TFA9896_BF_BSSRL = + 0x0561, /*!< Battery protection maximum reduction */ + TFA9896_BF_BSSRR = + 0x0582, /*!< Battery protection release time */ + TFA9896_BF_BSSHY = + 0x05b1, /*!< Battery Protection Hysteresis */ + TFA9896_BF_BSSR = + 0x05e0, /*!< Battery voltage value for read out (only) */ + TFA9896_BF_BSSBY = + 0x05f0, /*!< Bypass clipper battery protection */ + TFA9896_BF_DPSA = + 0x0600, /*!< Enable dynamic powerstage activation (DPSA) */ + TFA9896_BF_ATTEN = + 0x0613, /*!< Gain attenuation setting */ + TFA9896_BF_CFSM = + 0x0650, /*!< Soft mute in CoolFlux */ + TFA9896_BF_BSSS = + 0x0670, /*!< Battery sense steepness */ + TFA9896_BF_VOL = + 0x0687, /*!< Coolflux volume control */ + TFA9896_BF_DCVO2 = + 0x0702, /*!< Second Boost Voltage */ + TFA9896_BF_DCMCC = + 0x0733, /*!< Max boost coil current - step of 175 mA */ + TFA9896_BF_DCVO1 = + 0x0772, /*!< First Boost Voltage */ + TFA9896_BF_DCIE = + 0x07a0, /*!< Adaptive boost mode */ + TFA9896_BF_DCSR = + 0x07b0, /*!< Soft Rampup/down mode for DCDC controller */ + TFA9896_BF_DCPAVG = + 0x07c0, /*!< ctrl_peak2avg for analog part of DCDC */ + TFA9896_BF_DCPWM = + 0x07d0, /*!< DCDC PWM only mode */ + TFA9896_BF_TROS = + 0x0800, /*!< Selection ambient temperature for speaker calibration */ + TFA9896_BF_EXTTS = + 0x0818, /*!< External temperature for speaker calibration (C) */ + TFA9896_BF_PWDN = + 0x0900, /*!< powerdown selection */ + TFA9896_BF_I2CR = + 0x0910, /*!< All I2C registers reset to default */ + TFA9896_BF_CFE = + 0x0920, /*!< Enable CoolFlux */ + TFA9896_BF_AMPE = + 0x0930, /*!< Enable Amplifier */ + TFA9896_BF_DCA = + 0x0940, /*!< Enable DCDC Boost converter */ + TFA9896_BF_SBSL = + 0x0950, /*!< Coolflux configured */ + TFA9896_BF_AMPC = + 0x0960, /*!< Selection if Coolflux enables amplifier */ + TFA9896_BF_DCDIS = + 0x0970, /*!< DCDC boost converter not connected */ + TFA9896_BF_PSDR = + 0x0980, /*!< IDDQ amplifier test selection */ + TFA9896_BF_INTPAD = + 0x09c1, /*!< INT pad (interrupt bump output) configuration */ + TFA9896_BF_IPLL = + 0x09e0, /*!< PLL input reference clock selection */ + TFA9896_BF_DCTRIP = + 0x0a04, /*!< Adaptive boost trip levels (effective only when boost_intel is set to 1) */ + TFA9896_BF_DCHOLD = + 0x0a54, /*!< Hold time for DCDC booster (effective only when boost_intel is set to 1) */ + TFA9896_BF_MTPK = + 0x0b07, /*!< KEY2 to access key2 protected registers (default for engineering) */ + TFA9896_BF_CVFDLY = + 0x0c25, /*!< Fractional delay adjustment between current and voltage sense */ + TFA9896_BF_OPENMTP = + 0x0ec0, /*!< Enable programming of the MTP memory */ + TFA9896_BF_TDMPRF = + 0x1011, /*!< TDM usecase selection control */ + TFA9896_BF_TDMEN = + 0x1030, /*!< TDM interface enable */ + TFA9896_BF_TDMCKINV = + 0x1040, /*!< TDM clock inversion, receive on */ + TFA9896_BF_TDMFSLN = + 0x1053, /*!< TDM FS length */ + TFA9896_BF_TDMFSPOL = + 0x1090, /*!< TDM FS polarity (start frame) */ + TFA9896_BF_TDMSAMSZ = + 0x10a4, /*!< TDM sample size for all TDM sinks and sources */ + TFA9896_BF_TDMSLOTS = + 0x1103, /*!< TDM number of slots */ + TFA9896_BF_TDMSLLN = + 0x1144, /*!< TDM slot length */ + TFA9896_BF_TDMBRMG = + 0x1194, /*!< TDM bits remaining after the last slot */ + TFA9896_BF_TDMDDEL = + 0x11e0, /*!< TDM data delay */ + TFA9896_BF_TDMDADJ = + 0x11f0, /*!< TDM data adjustment */ + TFA9896_BF_TDMTXFRM = + 0x1201, /*!< TDM TXDATA format */ + TFA9896_BF_TDMUUS0 = + 0x1221, /*!< TDM TXDATA format unused slot SD0 */ + TFA9896_BF_TDMUUS1 = + 0x1241, /*!< TDM TXDATA format unused slot SD1 */ + TFA9896_BF_TDMSI0EN = + 0x1270, /*!< TDM sink0 enable */ + TFA9896_BF_TDMSI1EN = + 0x1280, /*!< TDM sink1 enable */ + TFA9896_BF_TDMSI2EN = + 0x1290, /*!< TDM sink2 enable */ + TFA9896_BF_TDMSO0EN = + 0x12a0, /*!< TDM source0 enable */ + TFA9896_BF_TDMSO1EN = + 0x12b0, /*!< TDM source1 enable */ + TFA9896_BF_TDMSO2EN = + 0x12c0, /*!< TDM source2 enable */ + TFA9896_BF_TDMSI0IO = + 0x12d0, /*!< TDM sink0 IO selection */ + TFA9896_BF_TDMSI1IO = + 0x12e0, /*!< TDM sink1 IO selection */ + TFA9896_BF_TDMSI2IO = + 0x12f0, /*!< TDM sink2 IO selection */ + TFA9896_BF_TDMSO0IO = + 0x1300, /*!< TDM source0 IO selection */ + TFA9896_BF_TDMSO1IO = + 0x1310, /*!< TDM source1 IO selection */ + TFA9896_BF_TDMSO2IO = + 0x1320, /*!< TDM source2 IO selection */ + TFA9896_BF_TDMSI0SL = + 0x1333, /*!< TDM sink0 slot position [GAIN IN] */ + TFA9896_BF_TDMSI1SL = + 0x1373, /*!< TDM sink1 slot position [CH1 IN] */ + TFA9896_BF_TDMSI2SL = + 0x13b3, /*!< TDM sink2 slot position [CH2 IN] */ + TFA9896_BF_TDMSO0SL = + 0x1403, /*!< TDM source0 slot position [GAIN OUT] */ + TFA9896_BF_TDMSO1SL = + 0x1443, /*!< TDM source1 slot position [Voltage Sense] */ + TFA9896_BF_TDMSO2SL = + 0x1483, /*!< TDM source2 slot position [Current Sense] */ + TFA9896_BF_NBCK = + 0x14c3, /*!< TDM NBCK bit clock ratio */ + TFA9896_BF_INTOVDDS = + 0x2000, /*!< flag_por_int_out */ + TFA9896_BF_INTOPLLS = + 0x2010, /*!< flag_pll_lock_int_out */ + TFA9896_BF_INTOOTDS = + 0x2020, /*!< flag_otpok_int_out */ + TFA9896_BF_INTOOVDS = + 0x2030, /*!< flag_ovpok_int_out */ + TFA9896_BF_INTOUVDS = + 0x2040, /*!< flag_uvpok_int_out */ + TFA9896_BF_INTOOCDS = + 0x2050, /*!< flag_ocp_alarm_int_out */ + TFA9896_BF_INTOCLKS = + 0x2060, /*!< flag_clocks_stable_int_out */ + TFA9896_BF_INTOCLIPS = + 0x2070, /*!< flag_clip_int_out */ + TFA9896_BF_INTOMTPB = + 0x2080, /*!< mtp_busy_int_out */ + TFA9896_BF_INTONOCLK = + 0x2090, /*!< flag_lost_clk_int_out */ + TFA9896_BF_INTOSPKS = + 0x20a0, /*!< flag_cf_speakererror_int_out */ + TFA9896_BF_INTOACS = + 0x20b0, /*!< flag_cold_started_int_out */ + TFA9896_BF_INTOSWS = + 0x20c0, /*!< flag_engage_int_out */ + TFA9896_BF_INTOWDS = + 0x20d0, /*!< flag_watchdog_reset_int_out */ + TFA9896_BF_INTOAMPS = + 0x20e0, /*!< flag_enbl_amp_int_out */ + TFA9896_BF_INTOAREFS = + 0x20f0, /*!< flag_enbl_ref_int_out */ + TFA9896_BF_INTOERR = + 0x2200, /*!< flag_cfma_err_int_out */ + TFA9896_BF_INTOACK = + 0x2210, /*!< flag_cfma_ack_int_out */ + TFA9896_BF_INTIVDDS = + 0x2300, /*!< flag_por_int_in */ + TFA9896_BF_INTIPLLS = + 0x2310, /*!< flag_pll_lock_int_in */ + TFA9896_BF_INTIOTDS = + 0x2320, /*!< flag_otpok_int_in */ + TFA9896_BF_INTIOVDS = + 0x2330, /*!< flag_ovpok_int_in */ + TFA9896_BF_INTIUVDS = + 0x2340, /*!< flag_uvpok_int_in */ + TFA9896_BF_INTIOCDS = + 0x2350, /*!< flag_ocp_alarm_int_in */ + TFA9896_BF_INTICLKS = + 0x2360, /*!< flag_clocks_stable_int_in */ + TFA9896_BF_INTICLIPS = + 0x2370, /*!< flag_clip_int_in */ + TFA9896_BF_INTIMTPB = + 0x2380, /*!< mtp_busy_int_in */ + TFA9896_BF_INTINOCLK = + 0x2390, /*!< flag_lost_clk_int_in */ + TFA9896_BF_INTISPKS = + 0x23a0, /*!< flag_cf_speakererror_int_in */ + TFA9896_BF_INTIACS = + 0x23b0, /*!< flag_cold_started_int_in */ + TFA9896_BF_INTISWS = + 0x23c0, /*!< flag_engage_int_in */ + TFA9896_BF_INTIWDS = + 0x23d0, /*!< flag_watchdog_reset_int_in */ + TFA9896_BF_INTIAMPS = + 0x23e0, /*!< flag_enbl_amp_int_in */ + TFA9896_BF_INTIAREFS = + 0x23f0, /*!< flag_enbl_ref_int_in */ + TFA9896_BF_INTIERR = + 0x2500, /*!< flag_cfma_err_int_in */ + TFA9896_BF_INTIACK = + 0x2510, /*!< flag_cfma_ack_int_in */ + TFA9896_BF_INTENVDDS = + 0x2600, /*!< flag_por_int_enable */ + TFA9896_BF_INTENPLLS = + 0x2610, /*!< flag_pll_lock_int_enable */ + TFA9896_BF_INTENOTDS = + 0x2620, /*!< flag_otpok_int_enable */ + TFA9896_BF_INTENOVDS = + 0x2630, /*!< flag_ovpok_int_enable */ + TFA9896_BF_INTENUVDS = + 0x2640, /*!< flag_uvpok_int_enable */ + TFA9896_BF_INTENOCDS = + 0x2650, /*!< flag_ocp_alarm_int_enable */ + TFA9896_BF_INTENCLKS = + 0x2660, /*!< flag_clocks_stable_int_enable */ + TFA9896_BF_INTENCLIPS = + 0x2670, /*!< flag_clip_int_enable */ + TFA9896_BF_INTENMTPB = + 0x2680, /*!< mtp_busy_int_enable */ + TFA9896_BF_INTENNOCLK = + 0x2690, /*!< flag_lost_clk_int_enable */ + TFA9896_BF_INTENSPKS = + 0x26a0, /*!< flag_cf_speakererror_int_enable */ + TFA9896_BF_INTENACS = + 0x26b0, /*!< flag_cold_started_int_enable */ + TFA9896_BF_INTENSWS = + 0x26c0, /*!< flag_engage_int_enable */ + TFA9896_BF_INTENWDS = + 0x26d0, /*!< flag_watchdog_reset_int_enable */ + TFA9896_BF_INTENAMPS = + 0x26e0, /*!< flag_enbl_amp_int_enable */ + TFA9896_BF_INTENAREFS = + 0x26f0, /*!< flag_enbl_ref_int_enable */ + TFA9896_BF_INTENERR = + 0x2800, /*!< flag_cfma_err_int_enable */ + TFA9896_BF_INTENACK = + 0x2810, /*!< flag_cfma_ack_int_enable */ + TFA9896_BF_INTPOLVDDS = + 0x2900, /*!< flag_por_int_pol */ + TFA9896_BF_INTPOLPLLS = + 0x2910, /*!< flag_pll_lock_int_pol */ + TFA9896_BF_INTPOLOTDS = + 0x2920, /*!< flag_otpok_int_pol */ + TFA9896_BF_INTPOLOVDS = + 0x2930, /*!< flag_ovpok_int_pol */ + TFA9896_BF_INTPOLUVDS = + 0x2940, /*!< flag_uvpok_int_pol */ + TFA9896_BF_INTPOLOCDS = + 0x2950, /*!< flag_ocp_alarm_int_pol */ + TFA9896_BF_INTPOLCLKS = + 0x2960, /*!< flag_clocks_stable_int_pol */ + TFA9896_BF_INTPOLCLIPS = + 0x2970, /*!< flag_clip_int_pol */ + TFA9896_BF_INTPOLMTPB = + 0x2980, /*!< mtp_busy_int_pol */ + TFA9896_BF_INTPOLNOCLK = + 0x2990, /*!< flag_lost_clk_int_pol */ + TFA9896_BF_INTPOLSPKS = + 0x29a0, /*!< flag_cf_speakererror_int_pol */ + TFA9896_BF_INTPOLACS = + 0x29b0, /*!< flag_cold_started_int_pol */ + TFA9896_BF_INTPOLSWS = + 0x29c0, /*!< flag_engage_int_pol */ + TFA9896_BF_INTPOLWDS = + 0x29d0, /*!< flag_watchdog_reset_int_pol */ + TFA9896_BF_INTPOLAMPS = + 0x29e0, /*!< flag_enbl_amp_int_pol */ + TFA9896_BF_INTPOLAREFS = + 0x29f0, /*!< flag_enbl_ref_int_pol */ + TFA9896_BF_INTPOLERR = + 0x2b00, /*!< flag_cfma_err_int_pol */ + TFA9896_BF_INTPOLACK = + 0x2b10, /*!< flag_cfma_ack_int_pol */ + TFA9896_BF_CLIP = + 0x4900, /*!< Bypass clip control */ + TFA9896_BF_CIMTP = + 0x62b0, /*!< Start copying data from I2C mtp registers to mtp */ + TFA9896_BF_RST = + 0x7000, /*!< Reset CoolFlux DSP */ + TFA9896_BF_DMEM = + 0x7011, /*!< Target memory for access */ + TFA9896_BF_AIF = + 0x7030, /*!< Auto increment flag for memory-address */ + TFA9896_BF_CFINT = + 0x7040, /*!< CF Interrupt - auto clear */ + TFA9896_BF_REQ = + 0x7087, /*!< CF request for accessing the 8 channels */ + TFA9896_BF_MADD = + 0x710f, /*!< Memory address */ + TFA9896_BF_MEMA = + 0x720f, /*!< Activate memory access */ + TFA9896_BF_ERR = + 0x7307, /*!< CF error flags */ + TFA9896_BF_ACK = + 0x7387, /*!< CF acknowledgement of the requests channels */ + TFA9896_BF_MTPOTC = + 0x8000, /*!< Calibration schedule selection */ + TFA9896_BF_MTPEX = + 0x8010, /*!< Calibration of RON status bit */ +} nxpTFA9896BfEnumList_t; +#define TFA9896_NAMETABLE \ + static tfaBfName_t Tfa9896DatasheetNames[] = { \ + { 0x0, \ + "VDDS" }, /* Power-on-reset flag (auto clear by reading) , */ \ + { 0x10, \ + "PLLS" }, /* PLL lock to programmed frequency , */ \ + { 0x20, \ + "OTDS" }, /* Over Temperature Protection alarm , */ \ + { 0x30, \ + "OVDS" }, /* Over Voltage Protection alarm , */ \ + { 0x40, \ + "UVDS" }, /* Under Voltage Protection alarm , */ \ + { 0x50, \ + "OCDS" }, /* Over Current Protection alarm , */ \ + { 0x60, \ + "CLKS" }, /* Clocks stable flag , */ \ + { 0x70, \ + "CLIPS" }, /* Amplifier clipping , */ \ + { 0x80, \ + "MTPB" }, /* MTP busy copying data to/from I2C registers , */ \ + { 0x90, \ + "NOCLK" }, /* lost clock detection (reference input clock) , */ \ + { 0xa0, \ + "SPKS" }, /* Speaker error , */ \ + { 0xb0, \ + "ACS" }, /* Cold Start required , */ \ + { 0xc0, \ + "SWS" }, /* Amplifier engage (Amp Switching) , */ \ + { 0xd0, \ + "WDS" }, /* watchdog reset (activates reset) , */ \ + { 0xe0, \ + "AMPS" }, /* Amplifier is enabled by manager , */ \ + { 0xf0, \ + "AREFS" }, /* References are enabled by manager , */ \ + { 0x109, \ + "BATS" }, /* Battery voltage from ADC readout , */ \ + { 0x208, \ + "TEMPS" }, /* Temperature readout from the temperature sensor ( C), */ \ + { 0x30f, \ + "REV" }, /* Device revision information , */ \ + { 0x420, \ + "RCV" }, /* Enable receiver mode , */ \ + { 0x431, \ + "CHS12" }, /* Channel Selection TDM input for Coolflux , */ \ + { 0x450, \ + "INPLVL" }, /* Input level selection attenuator ( , */ \ + { 0x461, \ + "CHSA" }, /* Input selection for amplifier , */ \ + { 0x4c3, \ + "AUDFS" }, /* Audio sample rate setting , */ \ + { 0x501, \ + "BSSCR" }, /* Batteery protection attack time , */ \ + { 0x523, \ + "BSST" }, /* Battery protection threshold level , */ \ + { 0x561, \ + "BSSRL" }, /* Battery protection maximum reduction , */ \ + { 0x582, \ + "BSSRR" }, /* Battery protection release time , */ \ + { 0x5b1, \ + "BSSHY" }, /* Battery Protection Hysteresis , */ \ + { 0x5e0, \ + "BSSR" }, /* Battery voltage value for read out (only) , */ \ + { 0x5f0, \ + "BSSBY" }, /* Bypass clipper battery protection , */ \ + { 0x600, \ + "DPSA" }, /* Enable dynamic powerstage activation (DPSA) , */ \ + { 0x613, \ + "ATTEN" }, /* Gain attenuation setting , */ \ + { 0x650, \ + "CFSM" }, /* Soft mute in CoolFlux , */ \ + { 0x670, \ + "BSSS" }, /* Battery sense steepness , */ \ + { 0x687, \ + "VOL" }, /* Coolflux volume control , */ \ + { 0x702, \ + "DCVO2" }, /* Second Boost Voltage , */ \ + { 0x733, \ + "DCMCC" }, /* Max boost coil current - step of 175 mA , */ \ + { 0x772, \ + "DCVO1" }, /* First Boost Voltage , */ \ + { 0x7a0, \ + "DCIE" }, /* Adaptive boost mode , */ \ + { 0x7b0, \ + "DCSR" }, /* Soft Rampup/down mode for DCDC controller , */ \ + { 0x7c0, \ + "DCPAVG" }, /* ctrl_peak2avg for analog part of DCDC , */ \ + { 0x7d0, \ + "DCPWM" }, /* DCDC PWM only mode , */ \ + { 0x800, \ + "TROS" }, /* Selection ambient temperature for speaker calibration , */ \ + { 0x818, \ + "EXTTS" }, /* External temperature for speaker calibration (C) , */ \ + { 0x900, \ + "PWDN" }, /* powerdown selection , */ \ + { 0x910, \ + "I2CR" }, /* All I2C registers reset to default , */ \ + { 0x920, \ + "CFE" }, /* Enable CoolFlux , */ \ + { 0x930, \ + "AMPE" }, /* Enable Amplifier , */ \ + { 0x940, \ + "DCA" }, /* Enable DCDC Boost converter , */ \ + { 0x950, \ + "SBSL" }, /* Coolflux configured , */ \ + { 0x960, \ + "AMPC" }, /* Selection if Coolflux enables amplifier , */ \ + { 0x970, \ + "DCDIS" }, /* DCDC boost converter not connected , */ \ + { 0x980, \ + "PSDR" }, /* IDDQ amplifier test selection , */ \ + { 0x9c1, \ + "INTPAD" }, /* INT pad (interrupt bump output) configuration , */ \ + { 0x9e0, \ + "IPLL" }, /* PLL input reference clock selection , */ \ + { 0xa04, \ + "DCTRIP" }, /* Adaptive boost trip levels (effective only when boost_intel is set to 1), */ \ + { 0xa54, \ + "DCHOLD" }, /* Hold time for DCDC booster (effective only when boost_intel is set to 1), */ \ + { 0xb07, \ + "MTPK" }, /* KEY2 to access key2 protected registers (default for engineering), */ \ + { 0xc25, \ + "CVFDLY" }, /* Fractional delay adjustment between current and voltage sense, */ \ + { 0xec0, \ + "OPENMTP" }, /* Enable programming of the MTP memory , */ \ + { 0x1011, \ + "TDMPRF" }, /* TDM usecase selection control , */ \ + { 0x1030, \ + "TDMEN" }, /* TDM interface enable , */ \ + { 0x1040, \ + "TDMCKINV" }, /* TDM clock inversion, receive on , */ \ + { 0x1053, \ + "TDMFSLN" }, /* TDM FS length , */ \ + { 0x1090, \ + "TDMFSPOL" }, /* TDM FS polarity (start frame) , */ \ + { 0x10a4, \ + "TDMSAMSZ" }, /* TDM sample size for all TDM sinks and sources , */ \ + { 0x1103, \ + "TDMSLOTS" }, /* TDM number of slots , */ \ + { 0x1144, \ + "TDMSLLN" }, /* TDM slot length , */ \ + { 0x1194, \ + "TDMBRMG" }, /* TDM bits remaining after the last slot , */ \ + { 0x11e0, \ + "TDMDDEL" }, /* TDM data delay , */ \ + { 0x11f0, \ + "TDMDADJ" }, /* TDM data adjustment , */ \ + { 0x1201, \ + "TDMTXFRM" }, /* TDM TXDATA format , */ \ + { 0x1221, \ + "TDMUUS0" }, /* TDM TXDATA format unused slot SD0 , */ \ + { 0x1241, \ + "TDMUUS1" }, /* TDM TXDATA format unused slot SD1 , */ \ + { 0x1270, \ + "TDMSI0EN" }, /* TDM sink0 enable , */ \ + { 0x1280, \ + "TDMSI1EN" }, /* TDM sink1 enable , */ \ + { 0x1290, \ + "TDMSI2EN" }, /* TDM sink2 enable , */ \ + { 0x12a0, \ + "TDMSO0EN" }, /* TDM source0 enable , */ \ + { 0x12b0, \ + "TDMSO1EN" }, /* TDM source1 enable , */ \ + { 0x12c0, \ + "TDMSO2EN" }, /* TDM source2 enable , */ \ + { 0x12d0, \ + "TDMSI0IO" }, /* TDM sink0 IO selection , */ \ + { 0x12e0, \ + "TDMSI1IO" }, /* TDM sink1 IO selection , */ \ + { 0x12f0, \ + "TDMSI2IO" }, /* TDM sink2 IO selection , */ \ + { 0x1300, \ + "TDMSO0IO" }, /* TDM source0 IO selection , */ \ + { 0x1310, \ + "TDMSO1IO" }, /* TDM source1 IO selection , */ \ + { 0x1320, \ + "TDMSO2IO" }, /* TDM source2 IO selection , */ \ + { 0x1333, \ + "TDMSI0SL" }, /* TDM sink0 slot position [GAIN IN] , */ \ + { 0x1373, \ + "TDMSI1SL" }, /* TDM sink1 slot position [CH1 IN] , */ \ + { 0x13b3, \ + "TDMSI2SL" }, /* TDM sink2 slot position [CH2 IN] , */ \ + { 0x1403, \ + "TDMSO0SL" }, /* TDM source0 slot position [GAIN OUT] , */ \ + { 0x1443, \ + "TDMSO1SL" }, /* TDM source1 slot position [Voltage Sense] , */ \ + { 0x1483, \ + "TDMSO2SL" }, /* TDM source2 slot position [Current Sense] , */ \ + { 0x14c3, \ + "NBCK" }, /* TDM NBCK bit clock ratio , */ \ + { 0x2000, \ + "INTOVDDS" }, /* flag_por_int_out , */ \ + { 0x2010, \ + "INTOPLLS" }, /* flag_pll_lock_int_out , */ \ + { 0x2020, \ + "INTOOTDS" }, /* flag_otpok_int_out , */ \ + { 0x2030, \ + "INTOOVDS" }, /* flag_ovpok_int_out , */ \ + { 0x2040, \ + "INTOUVDS" }, /* flag_uvpok_int_out , */ \ + { 0x2050, \ + "INTOOCDS" }, /* flag_ocp_alarm_int_out , */ \ + { 0x2060, \ + "INTOCLKS" }, /* flag_clocks_stable_int_out , */ \ + { 0x2070, \ + "INTOCLIPS" }, /* flag_clip_int_out , */ \ + { 0x2080, \ + "INTOMTPB" }, /* mtp_busy_int_out , */ \ + { 0x2090, \ + "INTONOCLK" }, /* flag_lost_clk_int_out , */ \ + { 0x20a0, \ + "INTOSPKS" }, /* flag_cf_speakererror_int_out , */ \ + { 0x20b0, \ + "INTOACS" }, /* flag_cold_started_int_out , */ \ + { 0x20c0, \ + "INTOSWS" }, /* flag_engage_int_out , */ \ + { 0x20d0, \ + "INTOWDS" }, /* flag_watchdog_reset_int_out , */ \ + { 0x20e0, \ + "INTOAMPS" }, /* flag_enbl_amp_int_out , */ \ + { 0x20f0, \ + "INTOAREFS" }, /* flag_enbl_ref_int_out , */ \ + { 0x2200, \ + "INTOERR" }, /* flag_cfma_err_int_out , */ \ + { 0x2210, \ + "INTOACK" }, /* flag_cfma_ack_int_out , */ \ + { 0x2300, \ + "INTIVDDS" }, /* flag_por_int_in , */ \ + { 0x2310, \ + "INTIPLLS" }, /* flag_pll_lock_int_in , */ \ + { 0x2320, \ + "INTIOTDS" }, /* flag_otpok_int_in , */ \ + { 0x2330, \ + "INTIOVDS" }, /* flag_ovpok_int_in , */ \ + { 0x2340, \ + "INTIUVDS" }, /* flag_uvpok_int_in , */ \ + { 0x2350, \ + "INTIOCDS" }, /* flag_ocp_alarm_int_in , */ \ + { 0x2360, \ + "INTICLKS" }, /* flag_clocks_stable_int_in , */ \ + { 0x2370, \ + "INTICLIPS" }, /* flag_clip_int_in , */ \ + { 0x2380, \ + "INTIMTPB" }, /* mtp_busy_int_in , */ \ + { 0x2390, \ + "INTINOCLK" }, /* flag_lost_clk_int_in , */ \ + { 0x23a0, \ + "INTISPKS" }, /* flag_cf_speakererror_int_in , */ \ + { 0x23b0, \ + "INTIACS" }, /* flag_cold_started_int_in , */ \ + { 0x23c0, \ + "INTISWS" }, /* flag_engage_int_in , */ \ + { 0x23d0, \ + "INTIWDS" }, /* flag_watchdog_reset_int_in , */ \ + { 0x23e0, \ + "INTIAMPS" }, /* flag_enbl_amp_int_in , */ \ + { 0x23f0, \ + "INTIAREFS" }, /* flag_enbl_ref_int_in , */ \ + { 0x2500, \ + "INTIERR" }, /* flag_cfma_err_int_in , */ \ + { 0x2510, \ + "INTIACK" }, /* flag_cfma_ack_int_in , */ \ + { 0x2600, \ + "INTENVDDS" }, /* flag_por_int_enable , */ \ + { 0x2610, \ + "INTENPLLS" }, /* flag_pll_lock_int_enable , */ \ + { 0x2620, \ + "INTENOTDS" }, /* flag_otpok_int_enable , */ \ + { 0x2630, \ + "INTENOVDS" }, /* flag_ovpok_int_enable , */ \ + { 0x2640, \ + "INTENUVDS" }, /* flag_uvpok_int_enable , */ \ + { 0x2650, \ + "INTENOCDS" }, /* flag_ocp_alarm_int_enable , */ \ + { 0x2660, \ + "INTENCLKS" }, /* flag_clocks_stable_int_enable , */ \ + { 0x2670, \ + "INTENCLIPS" }, /* flag_clip_int_enable , */ \ + { 0x2680, \ + "INTENMTPB" }, /* mtp_busy_int_enable , */ \ + { 0x2690, \ + "INTENNOCLK" }, /* flag_lost_clk_int_enable , */ \ + { 0x26a0, \ + "INTENSPKS" }, /* flag_cf_speakererror_int_enable , */ \ + { 0x26b0, \ + "INTENACS" }, /* flag_cold_started_int_enable , */ \ + { 0x26c0, \ + "INTENSWS" }, /* flag_engage_int_enable , */ \ + { 0x26d0, \ + "INTENWDS" }, /* flag_watchdog_reset_int_enable , */ \ + { 0x26e0, \ + "INTENAMPS" }, /* flag_enbl_amp_int_enable , */ \ + { 0x26f0, \ + "INTENAREFS" }, /* flag_enbl_ref_int_enable , */ \ + { 0x2800, \ + "INTENERR" }, /* flag_cfma_err_int_enable , */ \ + { 0x2810, \ + "INTENACK" }, /* flag_cfma_ack_int_enable , */ \ + { 0x2900, \ + "INTPOLVDDS" }, /* flag_por_int_pol , */ \ + { 0x2910, \ + "INTPOLPLLS" }, /* flag_pll_lock_int_pol , */ \ + { 0x2920, \ + "INTPOLOTDS" }, /* flag_otpok_int_pol , */ \ + { 0x2930, \ + "INTPOLOVDS" }, /* flag_ovpok_int_pol , */ \ + { 0x2940, \ + "INTPOLUVDS" }, /* flag_uvpok_int_pol , */ \ + { 0x2950, \ + "INTPOLOCDS" }, /* flag_ocp_alarm_int_pol , */ \ + { 0x2960, \ + "INTPOLCLKS" }, /* flag_clocks_stable_int_pol , */ \ + { 0x2970, \ + "INTPOLCLIPS" }, /* flag_clip_int_pol , */ \ + { 0x2980, \ + "INTPOLMTPB" }, /* mtp_busy_int_pol , */ \ + { 0x2990, \ + "INTPOLNOCLK" }, /* flag_lost_clk_int_pol , */ \ + { 0x29a0, \ + "INTPOLSPKS" }, /* flag_cf_speakererror_int_pol , */ \ + { 0x29b0, \ + "INTPOLACS" }, /* flag_cold_started_int_pol , */ \ + { 0x29c0, \ + "INTPOLSWS" }, /* flag_engage_int_pol , */ \ + { 0x29d0, \ + "INTPOLWDS" }, /* flag_watchdog_reset_int_pol , */ \ + { 0x29e0, \ + "INTPOLAMPS" }, /* flag_enbl_amp_int_pol , */ \ + { 0x29f0, \ + "INTPOLAREFS" }, /* flag_enbl_ref_int_pol , */ \ + { 0x2b00, \ + "INTPOLERR" }, /* flag_cfma_err_int_pol , */ \ + { 0x2b10, \ + "INTPOLACK" }, /* flag_cfma_ack_int_pol , */ \ + { 0x4900, \ + "CLIP" }, /* Bypass clip control , */ \ + { 0x62b0, \ + "CIMTP" }, /* Start copying data from I2C mtp registers to mtp , */ \ + { 0x7000, \ + "RST" }, /* Reset CoolFlux DSP , */ \ + { 0x7011, \ + "DMEM" }, /* Target memory for access , */ \ + { 0x7030, \ + "AIF" }, /* Auto increment flag for memory-address , */ \ + { 0x7040, \ + "CFINT" }, /* CF Interrupt - auto clear , */ \ + { 0x7087, \ + "REQ" }, /* CF request for accessing the 8 channels , */ \ + { 0x710f, \ + "MADD" }, /* Memory address , */ \ + { 0x720f, \ + "MEMA" }, /* Activate memory access , */ \ + { 0x7307, \ + "ERR" }, /* CF error flags , */ \ + { 0x7387, \ + "ACK" }, /* CF acknowledgement of the requests channels , */ \ + { 0x8000, \ + "MTPOTC" }, /* Calibration schedule selection , */ \ + { 0x8010, \ + "MTPEX" }, /* Calibration of RON status bit , */ \ + { 0x8045, "SWPROFIL" }, \ + { 0x80a5, "SWVSTEP" }, \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +#define TFA9896_BITNAMETABLE \ + static tfaBfName_t Tfa9896BitNames[] = { \ + { 0x0, \ + "flag_por" }, /* Power-on-reset flag (auto clear by reading) , */ \ + { 0x10, \ + "flag_pll_lock" }, /* PLL lock to programmed frequency , */ \ + { 0x20, \ + "flag_otpok" }, /* Over Temperature Protection alarm , */ \ + { 0x30, \ + "flag_ovpok" }, /* Over Voltage Protection alarm , */ \ + { 0x40, \ + "flag_uvpok" }, /* Under Voltage Protection alarm , */ \ + { 0x50, \ + "flag_ocp_alarm" }, /* Over Current Protection alarm , */ \ + { 0x60, \ + "flag_clocks_stable" }, /* Clocks stable flag , */ \ + { 0x70, \ + "flag_clip" }, /* Amplifier clipping , */ \ + { 0x80, \ + "mtp_busy" }, /* MTP busy copying data to/from I2C registers , */ \ + { 0x90, \ + "flag_lost_clk" }, /* lost clock detection (reference input clock) , */ \ + { 0xa0, \ + "flag_cf_speakererror" }, /* Speaker error , */ \ + { 0xb0, \ + "flag_cold_started" }, /* Cold Start required , */ \ + { 0xc0, \ + "flag_engage" }, /* Amplifier engage (Amp Switching) , */ \ + { 0xd0, \ + "flag_watchdog_reset" }, /* watchdog reset (activates reset) , */ \ + { 0xe0, \ + "flag_enbl_amp" }, /* Amplifier is enabled by manager , */ \ + { 0xf0, \ + "flag_enbl_ref" }, /* References are enabled by manager , */ \ + { 0x109, \ + "bat_adc" }, /* Battery voltage from ADC readout , */ \ + { 0x208, \ + "temp_adc" }, /* Temperature readout from the temperature sensor ( C), */ \ + { 0x30f, \ + "device_rev" }, /* Device revision information , */ \ + { 0x420, \ + "ctrl_rcv" }, /* Enable receiver mode , */ \ + { 0x431, \ + "chan_sel" }, /* Channel Selection TDM input for Coolflux , */ \ + { 0x450, \ + "input_level" }, /* Input level selection attenuator ( , */ \ + { 0x461, \ + "vamp_sel" }, /* Input selection for amplifier , */ \ + { 0x4c3, \ + "audio_fs" }, /* Audio sample rate setting , */ \ + { 0x501, \ + "vbat_prot_attacktime" }, /* Batteery protection attack time , */ \ + { 0x523, \ + "vbat_prot_thlevel" }, /* Battery protection threshold level , */ \ + { 0x561, \ + "vbat_prot_max_reduct" }, /* Battery protection maximum reduction , */ \ + { 0x582, \ + "vbat_prot_release_t" }, /* Battery protection release time , */ \ + { 0x5b1, \ + "vbat_prot_hysterese" }, /* Battery Protection Hysteresis , */ \ + { 0x5d0, \ + "reset_min_vbat" }, /* Battery supply safeguard clipper reset ( if CF_DSP is bypassed), */ \ + { 0x5e0, \ + "sel_vbat" }, /* Battery voltage value for read out (only) , */ \ + { 0x5f0, \ + "bypass_clipper" }, /* Bypass clipper battery protection , */ \ + { 0x600, \ + "dpsa" }, /* Enable dynamic powerstage activation (DPSA) , */ \ + { 0x613, \ + "ctrl_att" }, /* Gain attenuation setting , */ \ + { 0x650, \ + "cf_mute" }, /* Soft mute in CoolFlux , */ \ + { 0x670, \ + "batsense_steepness" }, /* Battery sense steepness , */ \ + { 0x687, \ + "vol" }, /* Coolflux volume control , */ \ + { 0x702, \ + "scnd_boost_voltage" }, /* Second Boost Voltage , */ \ + { 0x733, \ + "boost_cur" }, /* Max boost coil current - step of 175 mA , */ \ + { 0x772, \ + "frst_boost_voltage" }, /* First Boost Voltage , */ \ + { 0x7a0, \ + "boost_intel" }, /* Adaptive boost mode , */ \ + { 0x7b0, \ + "boost_speed" }, /* Soft Rampup/down mode for DCDC controller , */ \ + { 0x7c0, \ + "boost_peak2avg" }, /* ctrl_peak2avg for analog part of DCDC , */ \ + { 0x7d0, \ + "dcdc_pwmonly" }, /* DCDC PWM only mode , */ \ + { 0x7e0, \ + "ignore_flag_voutcomp86" }, /* Ignore flag_voutcomp86 (flag from analog) , */ \ + { 0x800, \ + "ext_temp_sel" }, /* Selection ambient temperature for speaker calibration , */ \ + { 0x818, \ + "ext_temp" }, /* External temperature for speaker calibration (C) , */ \ + { 0x900, \ + "powerdown" }, /* powerdown selection , */ \ + { 0x910, \ + "reset" }, /* All I2C registers reset to default , */ \ + { 0x920, \ + "enbl_coolflux" }, /* Enable CoolFlux , */ \ + { 0x930, \ + "enbl_amplifier" }, /* Enable Amplifier , */ \ + { 0x940, \ + "enbl_boost" }, /* Enable DCDC Boost converter , */ \ + { 0x950, \ + "coolflux_configured" }, /* Coolflux configured , */ \ + { 0x960, \ + "sel_enbl_amplifier" }, /* Selection if Coolflux enables amplifier , */ \ + { 0x970, \ + "dcdcoff_mode" }, /* DCDC boost converter not connected , */ \ + { 0x980, \ + "iddqtest" }, /* IDDQ amplifier test selection , */ \ + { 0x9c1, \ + "int_pad_io" }, /* INT pad (interrupt bump output) configuration , */ \ + { 0x9e0, \ + "sel_fs_bck" }, /* PLL input reference clock selection , */ \ + { 0x9f0, \ + "sel_scl_cf_clock" }, /* Coolflux sub-system clock selection , */ \ + { 0xa04, \ + "boost_trip_lvl" }, /* Adaptive boost trip levels (effective only when boost_intel is set to 1), */ \ + { 0xa54, \ + "boost_hold_time" }, /* Hold time for DCDC booster (effective only when boost_intel is set to 1), */ \ + { 0xaa1, \ + "bst_slpcmplvl" }, /* Slope compensation current, represents LxF (inductance x frequency) value , */ \ + { 0xb07, \ + "mtpkey2" }, /* KEY2 to access key2 protected registers (default for engineering), */ \ + { 0xc00, \ + "enbl_volt_sense" }, /* Voltage sense enabling control bit , */ \ + { 0xc10, \ + "vsense_pwm_sel" }, /* Voltage sense source selection , */ \ + { 0xc25, \ + "vi_frac_delay" }, /* Fractional delay adjustment between current and voltage sense, */ \ + { 0xc80, \ + "sel_voltsense_out" }, /* TDM output data selection for AEC , */ \ + { 0xc90, \ + "vsense_bypass_avg" }, /* Voltage sense average block bypass , */ \ + { 0xd05, \ + "cf_frac_delay" }, /* Fractional delay adjustment between current and voltage sense by firmware, */ \ + { 0xe00, \ + "bypass_dcdc_curr_prot" }, /* Control to switch off dcdc current reduction with bat protection, */ \ + { 0xe10, \ + "bypass_ocp" }, /* Bypass OCP (digital IP block) , */ \ + { 0xe20, \ + "ocptest" }, /* ocptest (analog IP block) enable , */ \ + { 0xe80, \ + "disable_clock_sh_prot" }, /* Disable clock_sh protection , */ \ + { 0xe92, \ + "reserve_reg_15_09" }, /* Spare control bits for future usage , */ \ + { 0xec0, \ + "unprotect_mtp" }, /* Enable programming of the MTP memory , */ \ + { 0xed2, \ + "reserve_reg_15_13" }, /* Spare control bits for future usage , */ \ + { 0xf00, \ + "dcdc_pfm20khz_limit" }, /* DCDC in PFM mode forcing each 50us a pwm pulse , */ \ + { 0xf11, \ + "dcdc_ctrl_maxzercnt" }, /* DCDC number of zero current flags required to go to pfm mode, */ \ + { 0xf36, \ + "dcdc_vbat_delta_detect" }, /* DCDC threshold required on a delta Vbat (in PFM mode) switching to PWM mode, */ \ + { 0xfa0, \ + "dcdc_ignore_vbat" }, /* Ignore an increase on Vbat , */ \ + { 0x1011, \ + "tdm_usecase" }, /* TDM usecase selection control , */ \ + { 0x1030, \ + "tdm_enable" }, /* TDM interface enable , */ \ + { 0x1040, \ + "tdm_clk_inversion" }, /* TDM clock inversion, receive on , */ \ + { 0x1053, \ + "tdm_fs_ws_length" }, /* TDM FS length , */ \ + { 0x1090, \ + "tdm_fs_ws_polarity" }, /* TDM FS polarity (start frame) , */ \ + { 0x10a4, \ + "tdm_sample_size" }, /* TDM sample size for all TDM sinks and sources , */ \ + { 0x1103, \ + "tdm_nb_of_slots" }, /* TDM number of slots , */ \ + { 0x1144, \ + "tdm_slot_length" }, /* TDM slot length , */ \ + { 0x1194, \ + "tdm_bits_remaining" }, /* TDM bits remaining after the last slot , */ \ + { 0x11e0, \ + "tdm_data_delay" }, /* TDM data delay , */ \ + { 0x11f0, \ + "tdm_data_adjustment" }, /* TDM data adjustment , */ \ + { 0x1201, \ + "tdm_txdata_format" }, /* TDM TXDATA format , */ \ + { 0x1221, \ + "tdm_txdata_format_unused_slot_sd0" }, /* TDM TXDATA format unused slot SD0 , */ \ + { 0x1241, \ + "tdm_txdata_format_unused_slot_sd1" }, /* TDM TXDATA format unused slot SD1 , */ \ + { 0x1270, \ + "tdm_sink0_enable" }, /* TDM sink0 enable , */ \ + { 0x1280, \ + "tdm_sink1_enable" }, /* TDM sink1 enable , */ \ + { 0x1290, \ + "tdm_sink2_enable" }, /* TDM sink2 enable , */ \ + { 0x12a0, \ + "tdm_source0_enable" }, /* TDM source0 enable , */ \ + { 0x12b0, \ + "tdm_source1_enable" }, /* TDM source1 enable , */ \ + { 0x12c0, \ + "tdm_source2_enable" }, /* TDM source2 enable , */ \ + { 0x12d0, \ + "tdm_sink0_io" }, /* TDM sink0 IO selection , */ \ + { 0x12e0, \ + "tdm_sink1_io" }, /* TDM sink1 IO selection , */ \ + { 0x12f0, \ + "tdm_sink2_io" }, /* TDM sink2 IO selection , */ \ + { 0x1300, \ + "tdm_source0_io" }, /* TDM source0 IO selection , */ \ + { 0x1310, \ + "tdm_source1_io" }, /* TDM source1 IO selection , */ \ + { 0x1320, \ + "tdm_source2_io" }, /* TDM source2 IO selection , */ \ + { 0x1333, \ + "tdm_sink0_slot" }, /* TDM sink0 slot position [GAIN IN] , */ \ + { 0x1373, \ + "tdm_sink1_slot" }, /* TDM sink1 slot position [CH1 IN] , */ \ + { 0x13b3, \ + "tdm_sink2_slot" }, /* TDM sink2 slot position [CH2 IN] , */ \ + { 0x1403, \ + "tdm_source0_slot" }, /* TDM source0 slot position [GAIN OUT] , */ \ + { 0x1443, \ + "tdm_source1_slot" }, /* TDM source1 slot position [Voltage Sense] , */ \ + { 0x1483, \ + "tdm_source2_slot" }, /* TDM source2 slot position [Current Sense] , */ \ + { 0x14c3, \ + "tdm_nbck" }, /* TDM NBCK bit clock ratio , */ \ + { 0x1500, \ + "flag_tdm_lut_error" }, /* TDM LUT error flag , */ \ + { 0x1512, \ + "flag_tdm_status" }, /* TDM interface status bits , */ \ + { 0x1540, \ + "flag_tdm_error" }, /* TDM interface error indicator , */ \ + { 0x1551, \ + "status_bst_mode" }, /* DCDC mode status bits , */ \ + { 0x2000, \ + "flag_por_int_out" }, /* flag_por_int_out , */ \ + { 0x2010, \ + "flag_pll_lock_int_out" }, /* flag_pll_lock_int_out , */ \ + { 0x2020, \ + "flag_otpok_int_out" }, /* flag_otpok_int_out , */ \ + { 0x2030, \ + "flag_ovpok_int_out" }, /* flag_ovpok_int_out , */ \ + { 0x2040, \ + "flag_uvpok_int_out" }, /* flag_uvpok_int_out , */ \ + { 0x2050, \ + "flag_ocp_alarm_int_out" }, /* flag_ocp_alarm_int_out , */ \ + { 0x2060, \ + "flag_clocks_stable_int_out" }, /* flag_clocks_stable_int_out , */ \ + { 0x2070, \ + "flag_clip_int_out" }, /* flag_clip_int_out , */ \ + { 0x2080, \ + "mtp_busy_int_out" }, /* mtp_busy_int_out , */ \ + { 0x2090, \ + "flag_lost_clk_int_out" }, /* flag_lost_clk_int_out , */ \ + { 0x20a0, \ + "flag_cf_speakererror_int_out" }, /* flag_cf_speakererror_int_out , */ \ + { 0x20b0, \ + "flag_cold_started_int_out" }, /* flag_cold_started_int_out , */ \ + { 0x20c0, \ + "flag_engage_int_out" }, /* flag_engage_int_out , */ \ + { 0x20d0, \ + "flag_watchdog_reset_int_out" }, /* flag_watchdog_reset_int_out , */ \ + { 0x20e0, \ + "flag_enbl_amp_int_out" }, /* flag_enbl_amp_int_out , */ \ + { 0x20f0, \ + "flag_enbl_ref_int_out" }, /* flag_enbl_ref_int_out , */ \ + { 0x2100, \ + "flag_voutcomp_int_out" }, /* flag_voutcomp_int_out , */ \ + { 0x2110, \ + "flag_voutcomp93_int_out" }, /* flag_voutcomp93_int_out , */ \ + { 0x2120, \ + "flag_voutcomp86_int_out" }, /* flag_voutcomp86_int_out , */ \ + { 0x2130, \ + "flag_hiz_int_out" }, /* flag_hiz_int_out , */ \ + { 0x2140, \ + "flag_ocpokbst_int_out" }, /* flag_ocpokbst_int_out , */ \ + { 0x2150, \ + "flag_peakcur_int_out" }, /* flag_peakcur_int_out , */ \ + { 0x2160, \ + "flag_ocpokap_int_out" }, /* flag_ocpokap_int_out , */ \ + { 0x2170, \ + "flag_ocpokan_int_out" }, /* flag_ocpokan_int_out , */ \ + { 0x2180, \ + "flag_ocpokbp_int_out" }, /* flag_ocpokbp_int_out , */ \ + { 0x2190, \ + "flag_ocpokbn_int_out" }, /* flag_ocpokbn_int_out , */ \ + { 0x21a0, \ + "flag_adc10_ready_int_out" }, /* flag_adc10_ready_int_out , */ \ + { 0x21b0, \ + "flag_clipa_high_int_out" }, /* flag_clipa_high_int_out , */ \ + { 0x21c0, \ + "flag_clipa_low_int_out" }, /* flag_clipa_low_int_out , */ \ + { 0x21d0, \ + "flag_clipb_high_int_out" }, /* flag_clipb_high_int_out , */ \ + { 0x21e0, \ + "flag_clipb_low_int_out" }, /* flag_clipb_low_int_out , */ \ + { 0x21f0, \ + "flag_tdm_error_int_out" }, /* flag_tdm_error_int_out , */ \ + { 0x2200, \ + "flag_cfma_err_int_out" }, /* flag_cfma_err_int_out , */ \ + { 0x2210, \ + "flag_cfma_ack_int_out" }, /* flag_cfma_ack_int_out , */ \ + { 0x2300, \ + "flag_por_int_in" }, /* flag_por_int_in , */ \ + { 0x2310, \ + "flag_pll_lock_int_in" }, /* flag_pll_lock_int_in , */ \ + { 0x2320, \ + "flag_otpok_int_in" }, /* flag_otpok_int_in , */ \ + { 0x2330, \ + "flag_ovpok_int_in" }, /* flag_ovpok_int_in , */ \ + { 0x2340, \ + "flag_uvpok_int_in" }, /* flag_uvpok_int_in , */ \ + { 0x2350, \ + "flag_ocp_alarm_int_in" }, /* flag_ocp_alarm_int_in , */ \ + { 0x2360, \ + "flag_clocks_stable_int_in" }, /* flag_clocks_stable_int_in , */ \ + { 0x2370, \ + "flag_clip_int_in" }, /* flag_clip_int_in , */ \ + { 0x2380, \ + "mtp_busy_int_in" }, /* mtp_busy_int_in , */ \ + { 0x2390, \ + "flag_lost_clk_int_in" }, /* flag_lost_clk_int_in , */ \ + { 0x23a0, \ + "flag_cf_speakererror_int_in" }, /* flag_cf_speakererror_int_in , */ \ + { 0x23b0, \ + "flag_cold_started_int_in" }, /* flag_cold_started_int_in , */ \ + { 0x23c0, \ + "flag_engage_int_in" }, /* flag_engage_int_in , */ \ + { 0x23d0, \ + "flag_watchdog_reset_int_in" }, /* flag_watchdog_reset_int_in , */ \ + { 0x23e0, \ + "flag_enbl_amp_int_in" }, /* flag_enbl_amp_int_in , */ \ + { 0x23f0, \ + "flag_enbl_ref_int_in" }, /* flag_enbl_ref_int_in , */ \ + { 0x2400, \ + "flag_voutcomp_int_in" }, /* flag_voutcomp_int_in , */ \ + { 0x2410, \ + "flag_voutcomp93_int_in" }, /* flag_voutcomp93_int_in , */ \ + { 0x2420, \ + "flag_voutcomp86_int_in" }, /* flag_voutcomp86_int_in , */ \ + { 0x2430, \ + "flag_hiz_int_in" }, /* flag_hiz_int_in , */ \ + { 0x2440, \ + "flag_ocpokbst_int_in" }, /* flag_ocpokbst_int_in , */ \ + { 0x2450, \ + "flag_peakcur_int_in" }, /* flag_peakcur_int_in , */ \ + { 0x2460, \ + "flag_ocpokap_int_in" }, /* flag_ocpokap_int_in , */ \ + { 0x2470, \ + "flag_ocpokan_int_in" }, /* flag_ocpokan_int_in , */ \ + { 0x2480, \ + "flag_ocpokbp_int_in" }, /* flag_ocpokbp_int_in , */ \ + { 0x2490, \ + "flag_ocpokbn_int_in" }, /* flag_ocpokbn_int_in , */ \ + { 0x24a0, \ + "flag_adc10_ready_int_in" }, /* flag_adc10_ready_int_in , */ \ + { 0x24b0, \ + "flag_clipa_high_int_in" }, /* flag_clipa_high_int_in , */ \ + { 0x24c0, \ + "flag_clipa_low_int_in" }, /* flag_clipa_low_int_in , */ \ + { 0x24d0, \ + "flag_clipb_high_int_in" }, /* flag_clipb_high_int_in , */ \ + { 0x24e0, \ + "flag_clipb_low_int_in" }, /* flag_clipb_low_int_in , */ \ + { 0x24f0, \ + "flag_tdm_error_int_in" }, /* flag_tdm_error_int_in , */ \ + { 0x2500, \ + "flag_cfma_err_int_in" }, /* flag_cfma_err_int_in , */ \ + { 0x2510, \ + "flag_cfma_ack_int_in" }, /* flag_cfma_ack_int_in , */ \ + { 0x2600, \ + "flag_por_int_enable" }, /* flag_por_int_enable , */ \ + { 0x2610, \ + "flag_pll_lock_int_enable" }, /* flag_pll_lock_int_enable , */ \ + { 0x2620, \ + "flag_otpok_int_enable" }, /* flag_otpok_int_enable , */ \ + { 0x2630, \ + "flag_ovpok_int_enable" }, /* flag_ovpok_int_enable , */ \ + { 0x2640, \ + "flag_uvpok_int_enable" }, /* flag_uvpok_int_enable , */ \ + { 0x2650, \ + "flag_ocp_alarm_int_enable" }, /* flag_ocp_alarm_int_enable , */ \ + { 0x2660, \ + "flag_clocks_stable_int_enable" }, /* flag_clocks_stable_int_enable , */ \ + { 0x2670, \ + "flag_clip_int_enable" }, /* flag_clip_int_enable , */ \ + { 0x2680, \ + "mtp_busy_int_enable" }, /* mtp_busy_int_enable , */ \ + { 0x2690, \ + "flag_lost_clk_int_enable" }, /* flag_lost_clk_int_enable , */ \ + { 0x26a0, \ + "flag_cf_speakererror_int_enable" }, /* flag_cf_speakererror_int_enable , */ \ + { 0x26b0, \ + "flag_cold_started_int_enable" }, /* flag_cold_started_int_enable , */ \ + { 0x26c0, \ + "flag_engage_int_enable" }, /* flag_engage_int_enable , */ \ + { 0x26d0, \ + "flag_watchdog_reset_int_enable" }, /* flag_watchdog_reset_int_enable , */ \ + { 0x26e0, \ + "flag_enbl_amp_int_enable" }, /* flag_enbl_amp_int_enable , */ \ + { 0x26f0, \ + "flag_enbl_ref_int_enable" }, /* flag_enbl_ref_int_enable , */ \ + { 0x2700, \ + "flag_voutcomp_int_enable" }, /* flag_voutcomp_int_enable , */ \ + { 0x2710, \ + "flag_voutcomp93_int_enable" }, /* flag_voutcomp93_int_enable , */ \ + { 0x2720, \ + "flag_voutcomp86_int_enable" }, /* flag_voutcomp86_int_enable , */ \ + { 0x2730, \ + "flag_hiz_int_enable" }, /* flag_hiz_int_enable , */ \ + { 0x2740, \ + "flag_ocpokbst_int_enable" }, /* flag_ocpokbst_int_enable , */ \ + { 0x2750, \ + "flag_peakcur_int_enable" }, /* flag_peakcur_int_enable , */ \ + { 0x2760, \ + "flag_ocpokap_int_enable" }, /* flag_ocpokap_int_enable , */ \ + { 0x2770, \ + "flag_ocpokan_int_enable" }, /* flag_ocpokan_int_enable , */ \ + { 0x2780, \ + "flag_ocpokbp_int_enable" }, /* flag_ocpokbp_int_enable , */ \ + { 0x2790, \ + "flag_ocpokbn_int_enable" }, /* flag_ocpokbn_int_enable , */ \ + { 0x27a0, \ + "flag_adc10_ready_int_enable" }, /* flag_adc10_ready_int_enable , */ \ + { 0x27b0, \ + "flag_clipa_high_int_enable" }, /* flag_clipa_high_int_enable , */ \ + { 0x27c0, \ + "flag_clipa_low_int_enable" }, /* flag_clipa_low_int_enable , */ \ + { 0x27d0, \ + "flag_clipb_high_int_enable" }, /* flag_clipb_high_int_enable , */ \ + { 0x27e0, \ + "flag_clipb_low_int_enable" }, /* flag_clipb_low_int_enable , */ \ + { 0x27f0, \ + "flag_tdm_error_int_enable" }, /* flag_tdm_error_int_enable , */ \ + { 0x2800, \ + "flag_cfma_err_int_enable" }, /* flag_cfma_err_int_enable , */ \ + { 0x2810, \ + "flag_cfma_ack_int_enable" }, /* flag_cfma_ack_int_enable , */ \ + { 0x2900, \ + "flag_por_int_pol" }, /* flag_por_int_pol , */ \ + { 0x2910, \ + "flag_pll_lock_int_pol" }, /* flag_pll_lock_int_pol , */ \ + { 0x2920, \ + "flag_otpok_int_pol" }, /* flag_otpok_int_pol , */ \ + { 0x2930, \ + "flag_ovpok_int_pol" }, /* flag_ovpok_int_pol , */ \ + { 0x2940, \ + "flag_uvpok_int_pol" }, /* flag_uvpok_int_pol , */ \ + { 0x2950, \ + "flag_ocp_alarm_int_pol" }, /* flag_ocp_alarm_int_pol , */ \ + { 0x2960, \ + "flag_clocks_stable_int_pol" }, /* flag_clocks_stable_int_pol , */ \ + { 0x2970, \ + "flag_clip_int_pol" }, /* flag_clip_int_pol , */ \ + { 0x2980, \ + "mtp_busy_int_pol" }, /* mtp_busy_int_pol , */ \ + { 0x2990, \ + "flag_lost_clk_int_pol" }, /* flag_lost_clk_int_pol , */ \ + { 0x29a0, \ + "flag_cf_speakererror_int_pol" }, /* flag_cf_speakererror_int_pol , */ \ + { 0x29b0, \ + "flag_cold_started_int_pol" }, /* flag_cold_started_int_pol , */ \ + { 0x29c0, \ + "flag_engage_int_pol" }, /* flag_engage_int_pol , */ \ + { 0x29d0, \ + "flag_watchdog_reset_int_pol" }, /* flag_watchdog_reset_int_pol , */ \ + { 0x29e0, \ + "flag_enbl_amp_int_pol" }, /* flag_enbl_amp_int_pol , */ \ + { 0x29f0, \ + "flag_enbl_ref_int_pol" }, /* flag_enbl_ref_int_pol , */ \ + { 0x2a00, \ + "flag_voutcomp_int_pol" }, /* flag_voutcomp_int_pol , */ \ + { 0x2a10, \ + "flag_voutcomp93_int_pol" }, /* flag_voutcomp93_int_pol , */ \ + { 0x2a20, \ + "flag_voutcomp86_int_pol" }, /* flag_voutcomp86_int_pol , */ \ + { 0x2a30, \ + "flag_hiz_int_pol" }, /* flag_hiz_int_pol , */ \ + { 0x2a40, \ + "flag_ocpokbst_int_pol" }, /* flag_ocpokbst_int_pol , */ \ + { 0x2a50, \ + "flag_peakcur_int_pol" }, /* flag_peakcur_int_pol , */ \ + { 0x2a60, \ + "flag_ocpokap_int_pol" }, /* flag_ocpokap_int_pol , */ \ + { 0x2a70, \ + "flag_ocpokan_int_pol" }, /* flag_ocpokan_int_pol , */ \ + { 0x2a80, \ + "flag_ocpokbp_int_pol" }, /* flag_ocpokbp_int_pol , */ \ + { 0x2a90, \ + "flag_ocpokbn_int_pol" }, /* flag_ocpokbn_int_pol , */ \ + { 0x2aa0, \ + "flag_adc10_ready_int_pol" }, /* flag_adc10_ready_int_pol , */ \ + { 0x2ab0, \ + "flag_clipa_high_int_pol" }, /* flag_clipa_high_int_pol , */ \ + { 0x2ac0, \ + "flag_clipa_low_int_pol" }, /* flag_clipa_low_int_pol , */ \ + { 0x2ad0, \ + "flag_clipb_high_int_pol" }, /* flag_clipb_high_int_pol , */ \ + { 0x2ae0, \ + "flag_clipb_low_int_pol" }, /* flag_clipb_low_int_pol , */ \ + { 0x2af0, \ + "flag_tdm_error_int_pol" }, /* flag_tdm_error_int_pol , */ \ + { 0x2b00, \ + "flag_cfma_err_int_pol" }, /* flag_cfma_err_int_pol , */ \ + { 0x2b10, \ + "flag_cfma_ack_int_pol" }, /* flag_cfma_ack_int_pol , */ \ + { 0x3000, \ + "flag_voutcomp" }, /* Status flag_voutcomp, indication Vset is larger than Vbat, */ \ + { 0x3010, \ + "flag_voutcomp93" }, /* Status flag_voutcomp93, indication Vset is larger than 1.07 x Vbat, */ \ + { 0x3020, \ + "flag_voutcomp86" }, /* Status flag voutcomp86, indication Vset is larger than 1.14 x Vbat, */ \ + { 0x3030, \ + "flag_hiz" }, /* Status flag_hiz, indication Vbst is larger than Vbat, */ \ + { 0x3040, \ + "flag_ocpokbst" }, /* Status flag_ocpokbst, indication no over current in boost converter PMOS switch, */ \ + { 0x3050, \ + "flag_peakcur" }, /* Status flag_peakcur, indication current is max in dcdc converter, */ \ + { 0x3060, \ + "flag_ocpokap" }, /* Status flag_ocpokap, indication no over current in amplifier A PMOS output stage, */ \ + { 0x3070, \ + "flag_ocpokan" }, /* Status flag_ocpokan, indication no over current in amplifier A NMOS output stage, */ \ + { 0x3080, \ + "flag_ocpokbp" }, /* Status flag_ocpokbp, indication no over current in amplifier B PMOS output stage, */ \ + { 0x3090, \ + "flag_ocpokbn" }, /* Status flag_ocpokbn, indication no over current in amplifier B NMOS output stage, */ \ + { 0x30a0, \ + "flag_adc10_ready" }, /* Status flag_adc10_ready, indication adc10 is ready, */ \ + { 0x30b0, \ + "flag_clipa_high" }, /* Status flag_clipa_high, indication pmos amplifier A is clipping, */ \ + { 0x30c0, \ + "flag_clipa_low" }, /* Status flag_clipa_low, indication nmos amplifier A is clipping, */ \ + { 0x30d0, \ + "flag_clipb_high" }, /* Status flag_clipb_high, indication pmos amplifier B is clipping, */ \ + { 0x30e0, \ + "flag_clipb_low" }, /* Status flag_clipb_low, indication nmos amplifier B is clipping, */ \ + { 0x310f, \ + "mtp_man_data_out" }, /* MTP manual read out data , */ \ + { 0x3200, \ + "key01_locked" }, /* Indicates KEY1 is locked , */ \ + { 0x3210, \ + "key02_locked" }, /* Indicates KEY2 is locked , */ \ + { 0x3225, \ + "mtp_ecc_tcout" }, /* MTP error correction test data out , */ \ + { 0x3280, \ + "mtpctrl_valid_test_rd" }, /* MTP test readout for read , */ \ + { 0x3290, \ + "mtpctrl_valid_test_wr" }, /* MTP test readout for write , */ \ + { 0x32a0, \ + "flag_in_alarm_state" }, /* Flag alarm state , */ \ + { 0x32b0, \ + "mtp_ecc_err2" }, /* Two or more bit errors detected in MTP, can not reconstruct value, */ \ + { 0x32c0, \ + "mtp_ecc_err1" }, /* One bit error detected in MTP, reconstructed value, */ \ + { 0x32d0, \ + "mtp_mtp_hvf" }, /* High voltage ready flag for MTP , */ \ + { 0x32f0, \ + "mtp_zero_check_fail" }, /* Zero check failed for MTP , */ \ + { 0x3309, \ + "data_adc10_tempbat" }, /* ADC10 data output for testing battery voltage and temperature, */ \ + { 0x400f, \ + "hid_code" }, /* 5A6Bh, 23147d to access hidden registers (default for engineering), */ \ + { 0x4100, \ + "bypass_hp" }, /* Bypass High Pass Filter , */ \ + { 0x4110, \ + "hard_mute" }, /* Hard Mute , */ \ + { 0x4120, \ + "soft_mute" }, /* Soft Mute , */ \ + { 0x4134, \ + "pwm_delay" }, /* PWM delay setting , */ \ + { 0x4180, \ + "pwm_shape" }, /* PWM Shape , */ \ + { 0x4190, \ + "pwm_bitlength" }, /* PWM Bitlength in noise shaper , */ \ + { 0x4203, \ + "drive" }, /* Drive bits to select number of amplifier power stages, */ \ + { 0x4240, \ + "reclock_pwm" }, /* Control for enabling reclocking of PWM signal , */ \ + { 0x4250, \ + "reclock_voltsense" }, /* Control for enabling reclocking of voltage sense signal, */ \ + { 0x4281, \ + "dpsalevel" }, /* DPSA threshold level , */ \ + { 0x42a1, \ + "dpsa_release" }, /* DPSA release time , */ \ + { 0x42c0, \ + "coincidence" }, /* Prevent simultaneously switching of output stage , */ \ + { 0x42d0, \ + "kickback" }, /* Prevent double pulses of output stage , */ \ + { 0x4306, \ + "drivebst" }, /* Drive bits to select the power transistor sections boost converter, */ \ + { 0x4370, \ + "boost_alg" }, /* Control for boost adaptive loop gain , */ \ + { 0x4381, \ + "boost_loopgain" }, /* DCDC boost loopgain setting , */ \ + { 0x43a0, \ + "ocptestbst" }, /* Boost OCP. For old ocp (ctrl_reversebst is 0); For new ocp (ctrl_reversebst is 1), */ \ + { 0x43d0, \ + "test_abistfft_enbl" }, /* FFT Coolflux , */ \ + { 0x43e0, \ + "bst_dcmbst" }, /* DCM mode control for DCDC during I2C direct control mode, */ \ + { 0x43f0, \ + "test_bcontrol" }, /* test_bcontrol , */ \ + { 0x4400, \ + "reversebst" }, /* OverCurrent Protection selection of power stage boost converter, */ \ + { 0x4410, \ + "sensetest" }, /* Test option for the sense NMOS in booster for current mode control., */ \ + { 0x4420, \ + "enbl_engagebst" }, /* Enable power stage of dcdc controller , */ \ + { 0x4470, \ + "enbl_slopecur" }, /* Enable bit of max-current dac , */ \ + { 0x4480, \ + "enbl_voutcomp" }, /* Enable vout comparators , */ \ + { 0x4490, \ + "enbl_voutcomp93" }, /* Enable vout-93 comparators , */ \ + { 0x44a0, \ + "enbl_voutcomp86" }, /* Enable vout-86 comparators , */ \ + { 0x44b0, \ + "enbl_hizcom" }, /* Enable hiz comparator , */ \ + { 0x44c0, \ + "enbl_peakcur" }, /* Enable peak current , */ \ + { 0x44d0, \ + "bypass_ovpglitch" }, /* Bypass OVP Glitch Filter , */ \ + { 0x44e0, \ + "enbl_windac" }, /* Enable window dac , */ \ + { 0x44f0, \ + "enbl_powerbst" }, /* Enable line of the powerstage , */ \ + { 0x4507, \ + "ocp_thr" }, /* OCP threshold level , */ \ + { 0x4580, \ + "bypass_glitchfilter" }, /* Bypass glitch filter , */ \ + { 0x4590, \ + "bypass_ovp" }, /* Bypass OVP , */ \ + { 0x45a0, \ + "bypass_uvp" }, /* Bypass UVP , */ \ + { 0x45b0, \ + "bypass_otp" }, /* Bypass OTP , */ \ + { 0x45d0, \ + "bypass_ocpcounter" }, /* Bypass OCP counter , */ \ + { 0x45e0, \ + "bypass_lost_clk" }, /* Bypass lost clock detector , */ \ + { 0x45f0, \ + "vpalarm" }, /* vpalarm (UVP/OUP handling) , */ \ + { 0x4600, \ + "bypass_gc" }, /* Bypasses the CS gain correction , */ \ + { 0x4610, \ + "cs_gain_control" }, /* Current sense gain control , */ \ + { 0x4627, \ + "cs_gain" }, /* Current sense gain , */ \ + { 0x46a0, \ + "bypass_lp" }, /* Bypass the low power filter inside temperature sensor, */ \ + { 0x46b0, \ + "bypass_pwmcounter" }, /* Bypass PWM Counter , */ \ + { 0x46c0, \ + "cs_negfixed" }, /* Current sense does not switch to neg , */ \ + { 0x46d2, \ + "cs_neghyst" }, /* Current sense switches to neg depending on hyseteris level, */ \ + { 0x4700, \ + "switch_fb" }, /* Current sense control switch_fb , */ \ + { 0x4713, \ + "se_hyst" }, /* Current sense control se_hyst , */ \ + { 0x4754, \ + "se_level" }, /* Current sense control se_level , */ \ + { 0x47a5, \ + "ktemp" }, /* Current sense control temperature compensation trimming, */ \ + { 0x4800, \ + "cs_negin" }, /* Current sense control negin , */ \ + { 0x4810, \ + "cs_sein" }, /* Current sense control cs_sein , */ \ + { 0x4820, \ + "cs_coincidence" }, /* Coincidence current sense , */ \ + { 0x4830, \ + "iddqtestbst" }, /* IDDQ testing in powerstage of DCDC boost converter, */ \ + { 0x4840, \ + "coincidencebst" }, /* Switch protection on to prevent simultaneously switching power stages bst and amp, */ \ + { 0x4876, \ + "delay_se_neg" }, /* delay of se and neg , */ \ + { 0x48e1, \ + "cs_ttrack" }, /* Sample and hold track time , */ \ + { 0x4900, \ + "bypass_clip" }, /* Bypass clip control , */ \ + { 0x4920, \ + "cf_cgate_off" }, /* Disable clock gating in the coolflux , */ \ + { 0x4940, \ + "clipfast" }, /* Clock selection for HW clipper for battery safeguard, */ \ + { 0x4950, \ + "cs_8ohm" }, /* 8 ohm mode for current sense (gain mode) , */ \ + { 0x4974, \ + "delay_clock_sh" }, /* delay_sh, tunes S7H delay , */ \ + { 0x49c0, \ + "inv_clksh" }, /* Invert the sample/hold clock for current sense ADC, */ \ + { 0x49d0, \ + "inv_neg" }, /* Invert neg signal , */ \ + { 0x49e0, \ + "inv_se" }, /* Invert se signal , */ \ + { 0x49f0, \ + "setse" }, /* Switches between Single Ended and differential mode; 1 is single ended, */ \ + { 0x4a12, \ + "adc10_sel" }, /* Select the input to convert the 10b ADC , */ \ + { 0x4a60, \ + "adc10_reset" }, /* Reset for ADC10 - I2C direct control mode , */ \ + { 0x4a81, \ + "adc10_test" }, /* Test mode selection signal for ADC10 - I2C direct control mode, */ \ + { 0x4aa0, \ + "bypass_lp_vbat" }, /* LP filter in batt sensor , */ \ + { 0x4ae0, \ + "dc_offset" }, /* Current sense decimator offset control , */ \ + { 0x4af0, \ + "tsense_hibias" }, /* Bit to set the biasing in temp sensor to high , */ \ + { 0x4b00, \ + "adc13_iset" }, /* MICADC setting of current consumption (debug use only), */ \ + { 0x4b14, \ + "adc13_gain" }, /* MICADC gain setting (two's complement format) , */ \ + { 0x4b61, \ + "adc13_slowdel" }, /* MICADC delay setting for internal clock (debug use only), */ \ + { 0x4b83, \ + "adc13_offset" }, /* MICADC offset setting , */ \ + { 0x4bc0, \ + "adc13_bsoinv" }, /* MICADC bit stream output invert mode for test , */ \ + { 0x4bd0, \ + "adc13_resonator_enable" }, /* MICADC give extra SNR with less stability (debug use only), */ \ + { 0x4be0, \ + "testmicadc" }, /* Mux at input of MICADC for test purpose , */ \ + { 0x4c0f, \ + "abist_offset" }, /* Offset control for ABIST testing , */ \ + { 0x4d05, \ + "windac" }, /* For testing direct control windac , */ \ + { 0x4dc3, \ + "pwm_dcc_cnt" }, /* control pwm duty cycle when enbl_pwm_dcc is 1 , */ \ + { 0x4e04, \ + "slopecur" }, /* For testing direct control slopecur , */ \ + { 0x4e50, \ + "ctrl_dem" }, /* Dynamic element matching control, rest of codes are optional, */ \ + { 0x4ed0, \ + "enbl_pwm_dcc" }, /* Enable direct control of pwm duty cycle , */ \ + { 0x4f00, \ + "bst_bypass_bstcur" }, /* Bypass control for boost current settings , */ \ + { 0x4f10, \ + "bst_bypass_bstfoldback" }, /* Bypass control for boost foldback , */ \ + { 0x4f20, \ + "bst_ctrl_azbst" }, /* Control of auto-zeroing of zero current comparator, */ \ + { 0x5007, \ + "gain" }, /* Gain setting of the gain multiplier , */ \ + { 0x5081, \ + "sourceb" }, /* PWM OUTB selection control , */ \ + { 0x50a1, \ + "sourcea" }, /* PWM OUTA selection control , */ \ + { 0x50c1, \ + "sourcebst" }, /* Sets the source of the pwmbst output to boost converter input for testing, */ \ + { 0x50e0, \ + "tdm_enable_loopback" }, /* TDM loopback test , */ \ + { 0x5104, \ + "pulselengthbst" }, /* Pulse length setting test input for boost converter, */ \ + { 0x5150, \ + "bypasslatchbst" }, /* Bypass latch in boost converter , */ \ + { 0x5160, \ + "invertbst" }, /* Invert pwmbst test signal , */ \ + { 0x5174, \ + "pulselength" }, /* Pulse length setting test input for amplifier , */ \ + { 0x51c0, \ + "bypasslatch" }, /* Bypass latch in PWM source selection module , */ \ + { 0x51d0, \ + "invertb" }, /* invert pwmb test signal , */ \ + { 0x51e0, \ + "inverta" }, /* invert pwma test signal , */ \ + { 0x51f0, \ + "bypass_ctrlloop" }, /* bypass_ctrlloop bypasses the control loop of the amplifier, */ \ + { 0x5210, \ + "test_rdsona" }, /* tbd for rdson testing , */ \ + { 0x5220, \ + "test_rdsonb" }, /* tbd for rdson testing , */ \ + { 0x5230, \ + "test_rdsonbst" }, /* tbd for rdson testing , */ \ + { 0x5240, \ + "test_cvia" }, /* tbd for rdson testing , */ \ + { 0x5250, \ + "test_cvib" }, /* tbd for rdson testing , */ \ + { 0x5260, \ + "test_cvibst" }, /* tbd for rdson testing , */ \ + { 0x5306, \ + "digimuxa_sel" }, /* DigimuxA input selection control (see Digimux list for details), */ \ + { 0x5376, \ + "digimuxb_sel" }, /* DigimuxB input selection control (see Digimux list for details), */ \ + { 0x5400, \ + "hs_mode" }, /* I2C high speed mode selection control , */ \ + { 0x5412, \ + "test_parametric_io" }, /* Control for parametric tests of IO cells , */ \ + { 0x5440, \ + "enbl_ringo" }, /* Enable ring oscillator control, for test purpose to check with ringo, */ \ + { 0x5456, \ + "digimuxc_sel" }, /* DigimuxC input selection control (see Digimux list for details), */ \ + { 0x54c0, \ + "dio_ehs" }, /* Slew control for DIO in output mode , */ \ + { 0x54d0, \ + "gainio_ehs" }, /* Slew control for GAINIO in output mode , */ \ + { 0x550d, \ + "enbl_amp" }, /* enbl_amp for testing to enable all analoge blocks in amplifier, */ \ + { 0x5600, \ + "use_direct_ctrls" }, /* Use direct controls to overrule several functions for testing - I2C direct control mode, */ \ + { 0x5610, \ + "rst_datapath" }, /* Reset datapath during direct control mode , */ \ + { 0x5620, \ + "rst_cgu" }, /* Reset CGU during durect control mode , */ \ + { 0x5637, \ + "enbl_ref" }, /* For testing to enable all analoge blocks in references, */ \ + { 0x56b0, \ + "enbl_engage" }, /* Enable output stage amplifier , */ \ + { 0x56c0, \ + "use_direct_clk_ctrl" }, /* use_direct_clk_ctrl, to overrule several functions direct for testing, */ \ + { 0x56d0, \ + "use_direct_pll_ctrl" }, /* use_direct_pll_ctrl, to overrule several functions direct for testing, */ \ + { 0x5707, \ + "anamux" }, /* Anamux control , */ \ + { 0x57e0, \ + "otptest" }, /* otptest, test mode otp amplifier , */ \ + { 0x57f0, \ + "reverse" }, /* 1b = Normal mode, slope is controlled , */ \ + { 0x5813, \ + "pll_selr" }, /* PLL pll_selr , */ \ + { 0x5854, \ + "pll_selp" }, /* PLL pll_selp , */ \ + { 0x58a5, \ + "pll_seli" }, /* PLL pll_seli , */ \ + { 0x5950, \ + "pll_mdec_msb" }, /* Most significant bits of pll_mdec[16] , */ \ + { 0x5960, \ + "pll_ndec_msb" }, /* Most significant bits of pll_ndec[9] , */ \ + { 0x5970, \ + "pll_frm" }, /* PLL pll_frm , */ \ + { 0x5980, \ + "pll_directi" }, /* PLL pll_directi , */ \ + { 0x5990, \ + "pll_directo" }, /* PLL pll_directo , */ \ + { 0x59a0, \ + "enbl_pll" }, /* PLL enbl_pll , */ \ + { 0x59f0, \ + "pll_bypass" }, /* PLL bypass , */ \ + { 0x5a0f, \ + "tsig_freq" }, /* Internal sinus test generator frequency control LSB bits, */ \ + { 0x5b02, \ + "tsig_freq_msb" }, /* Select internal sine wave generator, frequency control MSB bits, */ \ + { 0x5b30, \ + "inject_tsig" }, /* Control bit to switch to internal sinus test generator, */ \ + { 0x5b44, \ + "adc10_prog_sample" }, /* ADC10 program sample setting - I2C direct control mode, */ \ + { 0x5c0f, \ + "pll_mdec" }, /* PLL MDEC - I2C direct PLL control mode only , */ \ + { 0x5d06, \ + "pll_pdec" }, /* PLL PDEC - I2C direct PLL control mode only , */ \ + { 0x5d78, \ + "pll_ndec" }, /* PLL NDEC - I2C direct PLL control mode only , */ \ + { 0x6007, \ + "mtpkey1" }, /* 5Ah, 90d To access KEY1_Protected registers (Default for engineering), */ \ + { 0x6185, \ + "mtp_ecc_tcin" }, /* MTP ECC TCIN data , */ \ + { 0x6203, \ + "mtp_man_address_in" }, /* MTP address from I2C register for read/writing mtp in manual single word mode, */ \ + { 0x6260, \ + "mtp_ecc_eeb" }, /* Enable code bit generation (active low!) , */ \ + { 0x6270, \ + "mtp_ecc_ecb" }, /* Enable correction signal (active low!) , */ \ + { 0x6280, \ + "man_copy_mtp_to_iic" }, /* Start copying single word from mtp to I2C mtp register, */ \ + { 0x6290, \ + "man_copy_iic_to_mtp" }, /* Start copying single word from I2C mtp register to mtp, */ \ + { 0x62a0, \ + "auto_copy_mtp_to_iic" }, /* Start copying all the data from mtp to I2C mtp registers, */ \ + { 0x62b0, \ + "auto_copy_iic_to_mtp" }, /* Start copying data from I2C mtp registers to mtp , */ \ + { 0x62d2, \ + "mtp_speed_mode" }, /* MTP speed mode , */ \ + { 0x6340, \ + "mtp_direct_enable" }, /* mtp_direct_enable , */ \ + { 0x6350, \ + "mtp_direct_wr" }, /* mtp_direct_wr , */ \ + { 0x6360, \ + "mtp_direct_rd" }, /* mtp_direct_rd , */ \ + { 0x6370, \ + "mtp_direct_rst" }, /* mtp_direct_rst , */ \ + { 0x6380, \ + "mtp_direct_ers" }, /* mtp_direct_ers , */ \ + { 0x6390, \ + "mtp_direct_prg" }, /* mtp_direct_prg , */ \ + { 0x63a0, \ + "mtp_direct_epp" }, /* mtp_direct_epp , */ \ + { 0x63b4, \ + "mtp_direct_test" }, /* mtp_direct_test , */ \ + { 0x640f, \ + "mtp_man_data_in" }, /* Write data for MTP manual write , */ \ + { 0x7000, \ + "cf_rst_dsp" }, /* Reset CoolFlux DSP , */ \ + { 0x7011, \ + "cf_dmem" }, /* Target memory for access , */ \ + { 0x7030, \ + "cf_aif" }, /* Auto increment flag for memory-address , */ \ + { 0x7040, \ + "cf_int" }, /* CF Interrupt - auto clear , */ \ + { 0x7087, \ + "cf_req" }, /* CF request for accessing the 8 channels , */ \ + { 0x710f, \ + "cf_madd" }, /* Memory address , */ \ + { 0x720f, \ + "cf_mema" }, /* Activate memory access , */ \ + { 0x7307, \ + "cf_err" }, /* CF error flags , */ \ + { 0x7387, \ + "cf_ack" }, /* CF acknowledgement of the requests channels , */ \ + { 0x8000, \ + "calibration_onetime" }, /* Calibration schedule selection , */ \ + { 0x8010, \ + "calibr_ron_done" }, /* Calibration of RON status bit , */ \ + { 0x8105, \ + "calibr_vout_offset" }, /* calibr_vout_offset (DCDCoffset) 2's compliment (key1 protected), */ \ + { 0x8163, \ + "calibr_delta_gain" }, /* delta gain for vamp (alpha) 2's compliment (key1 protected), */ \ + { 0x81a5, \ + "calibr_offs_amp" }, /* offset for vamp (Ampoffset) 2's compliment (key1 protected), */ \ + { 0x8207, \ + "calibr_gain_cs" }, /* gain current sense (Imeasalpha) 2's compliment (key1 protected), */ \ + { 0x8284, \ + "calibr_temp_offset" }, /* temperature offset 2's compliment (key1 protected), */ \ + { 0x82d2, \ + "calibr_temp_gain" }, /* temperature gain 2's compliment (key1 protected) , */ \ + { 0x830f, \ + "calibr_ron" }, /* calibration value of the RON resistance of the coil, */ \ + { 0x8505, \ + "type_bits_hw" }, /* bit0 = disable function dcdcoff_mode ($09[7]) , */ \ + { 0x8601, \ + "type_bits_1_0_sw" }, /* MTP control SW , */ \ + { 0x8681, \ + "type_bits_9_8_sw" }, /* MTP control SW , */ \ + { 0x870f, \ + "type_bits2_sw" }, /* MTP-control SW2 , */ \ + { 0x8806, \ + "htol_iic_addr" }, /* 7-bit I2C address to be used during HTOL testing , */ \ + { 0x8870, \ + "htol_iic_addr_en" }, /* HTOL I2C_Address_Enable , */ \ + { 0x8881, \ + "ctrl_ovp_response" }, /* OVP response control , */ \ + { 0x88a0, \ + "disable_ovp_alarm_state" }, /* OVP alarm state control , */ \ + { 0x88b0, \ + "enbl_stretch_ovp" }, /* OVP alram strech control , */ \ + { 0x88c0, \ + "cf_debug_mode" }, /* Coolflux debug mode , */ \ + { 0x8a0f, \ + "production_data1" }, /* production_data1 , */ \ + { 0x8b0f, \ + "production_data2" }, /* production_data2 , */ \ + { 0x8c0f, \ + "production_data3" }, /* production_data3 , */ \ + { 0x8d0f, \ + "production_data4" }, /* production_data4 , */ \ + { 0x8e0f, \ + "production_data5" }, /* production_data5 , */ \ + { 0x8f0f, \ + "production_data6" }, /* production_data6 , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +enum TFA9896_irq { + TFA9896_irq_vdds = 0, + TFA9896_irq_plls = 1, + TFA9896_irq_ds = 2, + TFA9896_irq_vds = 3, + TFA9896_irq_uvds = 4, + TFA9896_irq_cds = 5, + TFA9896_irq_clks = 6, + TFA9896_irq_clips = 7, + TFA9896_irq_mtpb = 8, + TFA9896_irq_clk = 9, + TFA9896_irq_spks = 10, + TFA9896_irq_acs = 11, + TFA9896_irq_sws = 12, + TFA9896_irq_wds = 13, + TFA9896_irq_amps = 14, + TFA9896_irq_arefs = 15, + TFA9896_irq_err = 32, + TFA9896_irq_ack = 33, + TFA9896_irq_max = 34, + TFA9896_irq_all = -1 /* all irqs */ +}; + +#define TFA9896_IRQ_NAMETABLE \ + static tfaIrqName_t TFA9896IrqNames[] = { \ + { 0, "VDDS" }, { 1, "PLLS" }, { 2, "DS" }, { 3, "VDS" }, \ + { 4, "UVDS" }, { 5, "CDS" }, { 6, "CLKS" }, { 7, "CLIPS" }, \ + { 8, "MTPB" }, { 9, "CLK" }, { 10, "SPKS" }, { 11, "ACS" }, \ + { 12, "SWS" }, { 13, "WDS" }, { 14, "AMPS" }, { 15, "AREFS" }, \ + { 16, "16" }, { 17, "17" }, { 18, "18" }, { 19, "19" }, \ + { 20, "20" }, { 21, "21" }, { 22, "22" }, { 23, "23" }, \ + { 24, "24" }, { 25, "25" }, { 26, "26" }, { 27, "27" }, \ + { 28, "28" }, { 29, "29" }, { 30, "30" }, { 31, "31" }, \ + { 32, "ERR" }, { 33, "ACK" }, { 34, "34" }, \ + }; +#endif /* _TFA9896_TFAFIELDNAMES_H */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx.h new file mode 100644 index 000000000000..c1b7e2f3fc57 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx.h @@ -0,0 +1,189 @@ +/* + * Copyright 2014-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFA98XX_INC__ +#define __TFA98XX_INC__ + +#include +#include +#include +#include + +#include "tfa_device.h" +#include "tfa_container.h" +#include "config.h" + +/* max. length of a alsa mixer control name */ +#define MAX_CONTROL_NAME 48 + +#define TFA98XX_MAX_REGISTER 0xff + +#define TFA98XX_FLAG_SKIP_INTERRUPTS (1 << 0) +#define TFA98XX_FLAG_SAAM_AVAILABLE (1 << 1) +#define TFA98XX_FLAG_STEREO_DEVICE (1 << 2) +#define TFA98XX_FLAG_MULTI_MIC_INPUTS (1 << 3) +#define TFA98XX_FLAG_TAPDET_AVAILABLE (1 << 4) +#define TFA98XX_FLAG_CALIBRATION_CTL (1 << 5) +#define TFA98XX_FLAG_REMOVE_PLOP_NOISE (1 << 6) +#define TFA98XX_FLAG_LP_MODES (1 << 7) +#define TFA98XX_FLAG_TDM_DEVICE (1 << 8) + +#define TFA98XX_NUM_RATES 9 + +/* DSP init status */ +enum tfa98xx_dsp_init_state { + TFA98XX_DSP_INIT_STOPPED, /* DSP not running */ + TFA98XX_DSP_INIT_RECOVER, /* DSP error detected at runtime */ + TFA98XX_DSP_INIT_FAIL, /* DSP init failed */ + TFA98XX_DSP_INIT_PENDING, /* DSP start requested */ + TFA98XX_DSP_INIT_DONE, /* DSP running */ + TFA98XX_DSP_INIT_INVALIDATED, /* DSP was running, requires re-init */ +}; + +enum tfa98xx_dsp_fw_state { + TFA98XX_DSP_FW_NONE = 0, + TFA98XX_DSP_FW_PENDING, + TFA98XX_DSP_FW_FAIL, + TFA98XX_DSP_FW_OK, +}; + +enum tfa98xx_misc_device_id { + MISC_DEVICE_TFA98XX_REG, + MISC_DEVICE_TFA98XX_RW, + MISC_DEVICE_TFA98XX_RPC, + MISC_DEVICE_TFA98XX_PROFILE, + MISC_DEVICE_TFA98XX_IOCTL, + MISC_DEVICE_MAX +}; + +struct tfa98xx_miscdevice_info { + char devicename[255]; + struct file_operations operations; +}; + +enum TFA_DEVICE_TYPE { + TFA_DEVICE_TYPE_9894, + TFA_DEVICE_TYPE_9874_PRIMARY, + TFA_DEVICE_TYPE_9874_SECONDARY, + TFA_DEVICE_TYPE_MAX +}; + +enum TFA_DEVICE_MUTE { + TFA98XX_DEVICE_MUTE_OFF = 0, + TFA98XX_DEVICE_MUTE_ON, +}; + +enum { + IOCTL_CMD_GET_MEMTRACK_DATA = 0, + IOCTL_CMD_GET_CNT_VERSION, +}; + +enum { + MEMTRACK_ITEM_SPEAKER_F0 = 0, + MEMTRACK_ITEM_SPEAKER_TEMPERATURE, + MEMTRACK_ITEM_SPEAKER_IMPEDANCE, + MEMTRACK_ITEM_MAX +}; + +struct livedata_cfg { + int address; + int track; + int scaler; +}; + +struct tfa98xx_firmware { + void *base; + struct tfa98xx_device *dev; + char name[9]; //TODO get length from tfa parameter defs +}; + +struct tfa98xx_baseprofile { + char basename[MAX_CONTROL_NAME]; /* profile basename */ + int len; /* profile length */ + int item_id; /* profile id */ + int sr_rate_sup + [TFA98XX_NUM_RATES]; /* sample rates supported by this profile */ + struct list_head list; /* list of all profiles */ +}; + +struct tfa98xx { + struct regmap *regmap; + struct i2c_client *i2c; + struct regulator *vdd; + struct snd_soc_codec *codec; + struct workqueue_struct *tfa98xx_wq; + struct delayed_work init_work; + struct delayed_work monitor_work; + struct delayed_work interrupt_work; + struct delayed_work tapdet_work; + struct mutex dsp_lock; + int dsp_init; + int dsp_fw_state; + int sysclk; + int rst_gpio; + u16 rev; + int audio_mode; + struct tfa98xx_firmware fw; + char *fw_name; + int rate; + /*[nxp34663] CR: support 16bit/24bit/32bit audio data. begin*/ + u8 pcm_format; + /*[nxp34663] CR: support 16bit/24bit/32bit audio data. end*/ + wait_queue_head_t wq; + struct device *dev; + unsigned int init_count; + int pstream; + int cstream; + struct input_dev *input; + bool tapdet_enabled; /* service enabled */ + bool tapdet_open; /* device file opened */ + unsigned int tapdet_profiles; /* tapdet profile bitfield */ + bool tapdet_poll; /* tapdet running on polling mode */ + + unsigned int rate_constraint_list[TFA98XX_NUM_RATES]; + struct snd_pcm_hw_constraint_list rate_constraint; + + int reset_gpio; + int power_gpio; + int irq_gpio; + + struct list_head list; + struct tfa_device *tfa; + int vstep; + int profile; + int prof_vsteps + [TFACONT_MAXPROFS]; /* store vstep per profile (single device) */ + +#ifdef CONFIG_DEBUG_FS + struct dentry *dbg_dir; +#endif + u8 reg; + unsigned int flags; + bool set_mtp_cal; + uint16_t cal_data; + enum TFA_DEVICE_MUTE tfa_mute_mode; + + struct device_node *spk_id_gpio_p; + + struct miscdevice tfa98xx_reg; + struct miscdevice tfa98xx_rw; + struct miscdevice tfa98xx_rpc; + struct miscdevice tfa98xx_profile; + struct miscdevice tfa98xx_control; +}; + +#endif /* __TFA98XX_INC__ */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx_genregs_N1C.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx_genregs_N1C.h new file mode 100644 index 000000000000..719f09ef1776 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx_genregs_N1C.h @@ -0,0 +1,3795 @@ +/** Filename: Tfa98xx_genregs.h + * This file was generated automatically on 09/01/15 at 09:40:23. + * Source file: TFA9888_N1C_I2C_regmap_V1.xlsx + */ + +#ifndef TFA2_GENREGS_H +#define TFA2_GENREGS_H + +#define TFA98XX_SYS_CONTROL0 0x00 +#define TFA98XX_SYS_CONTROL1 0x01 +#define TFA98XX_SYS_CONTROL2 0x02 +#define TFA98XX_DEVICE_REVISION 0x03 +#define TFA98XX_CLOCK_CONTROL 0x04 +#define TFA98XX_CLOCK_GATING_CONTROL 0x05 +#define TFA98XX_SIDE_TONE_CONFIG 0x0d +#define TFA98XX_CTRL_DIGTOANA_REG 0x0e +#define TFA98XX_STATUS_FLAGS0 0x10 +#define TFA98XX_STATUS_FLAGS1 0x11 +#define TFA98XX_STATUS_FLAGS2 0x12 +#define TFA98XX_STATUS_FLAGS3 0x13 +#define TFA98XX_STATUS_FLAGS4 0x14 +#define TFA98XX_BATTERY_VOLTAGE 0x15 +#define TFA98XX_TEMPERATURE 0x16 +#define TFA98XX_TDM_CONFIG0 0x20 +#define TFA98XX_TDM_CONFIG1 0x21 +#define TFA98XX_TDM_CONFIG2 0x22 +#define TFA98XX_TDM_CONFIG3 0x23 +#define TFA98XX_TDM_CONFIG4 0x24 +#define TFA98XX_TDM_CONFIG5 0x25 +#define TFA98XX_TDM_CONFIG6 0x26 +#define TFA98XX_TDM_CONFIG7 0x27 +#define TFA98XX_TDM_CONFIG8 0x28 +#define TFA98XX_TDM_CONFIG9 0x29 +#define TFA98XX_PDM_CONFIG0 0x31 +#define TFA98XX_PDM_CONFIG1 0x32 +#define TFA98XX_HAPTIC_DRIVER_CONFIG 0x33 +#define TFA98XX_GPIO_DATAIN_REG 0x34 +#define TFA98XX_GPIO_CONFIG 0x35 +#define TFA98XX_INTERRUPT_OUT_REG1 0x40 +#define TFA98XX_INTERRUPT_OUT_REG2 0x41 +#define TFA98XX_INTERRUPT_OUT_REG3 0x42 +#define TFA98XX_INTERRUPT_IN_REG1 0x44 +#define TFA98XX_INTERRUPT_IN_REG2 0x45 +#define TFA98XX_INTERRUPT_IN_REG3 0x46 +#define TFA98XX_INTERRUPT_ENABLE_REG1 0x48 +#define TFA98XX_INTERRUPT_ENABLE_REG2 0x49 +#define TFA98XX_INTERRUPT_ENABLE_REG3 0x4a +#define TFA98XX_STATUS_POLARITY_REG1 0x4c +#define TFA98XX_STATUS_POLARITY_REG2 0x4d +#define TFA98XX_STATUS_POLARITY_REG3 0x4e +#define TFA98XX_BAT_PROT_CONFIG 0x50 +#define TFA98XX_AUDIO_CONTROL 0x51 +#define TFA98XX_AMPLIFIER_CONFIG 0x52 +#define TFA98XX_AUDIO_CONTROL2 0x5a +#define TFA98XX_DCDC_CONTROL0 0x70 +#define TFA98XX_CF_CONTROLS 0x90 +#define TFA98XX_CF_MAD 0x91 +#define TFA98XX_CF_MEM 0x92 +#define TFA98XX_CF_STATUS 0x93 +#define TFA98XX_MTPKEY2_REG 0xa1 +#define TFA98XX_MTP_STATUS 0xa2 +#define TFA98XX_KEY_PROTECTED_MTP_CONTROL 0xa3 +#define TFA98XX_MTP_DATA_OUT_MSB 0xa5 +#define TFA98XX_MTP_DATA_OUT_LSB 0xa6 +#define TFA98XX_TEMP_SENSOR_CONFIG 0xb1 +#define TFA98XX_KEY2_PROTECTED_MTP0 0xf0 +#define TFA98XX_KEY1_PROTECTED_MTP4 0xf4 +#define TFA98XX_KEY1_PROTECTED_MTP5 0xf5 + +/* + * (0x00)-sys_control0 + */ + +/* + * powerdown + */ +#define TFA98XX_SYS_CONTROL0_PWDN (0x1 << 0) +#define TFA98XX_SYS_CONTROL0_PWDN_POS 0 +#define TFA98XX_SYS_CONTROL0_PWDN_LEN 1 +#define TFA98XX_SYS_CONTROL0_PWDN_MAX 1 +#define TFA98XX_SYS_CONTROL0_PWDN_MSK 0x1 + +/* + * reset + */ +#define TFA98XX_SYS_CONTROL0_I2CR (0x1 << 1) +#define TFA98XX_SYS_CONTROL0_I2CR_POS 1 +#define TFA98XX_SYS_CONTROL0_I2CR_LEN 1 +#define TFA98XX_SYS_CONTROL0_I2CR_MAX 1 +#define TFA98XX_SYS_CONTROL0_I2CR_MSK 0x2 + +/* + * enbl_coolflux + */ +#define TFA98XX_SYS_CONTROL0_CFE (0x1 << 2) +#define TFA98XX_SYS_CONTROL0_CFE_POS 2 +#define TFA98XX_SYS_CONTROL0_CFE_LEN 1 +#define TFA98XX_SYS_CONTROL0_CFE_MAX 1 +#define TFA98XX_SYS_CONTROL0_CFE_MSK 0x4 + +/* + * enbl_amplifier + */ +#define TFA98XX_SYS_CONTROL0_AMPE (0x1 << 3) +#define TFA98XX_SYS_CONTROL0_AMPE_POS 3 +#define TFA98XX_SYS_CONTROL0_AMPE_LEN 1 +#define TFA98XX_SYS_CONTROL0_AMPE_MAX 1 +#define TFA98XX_SYS_CONTROL0_AMPE_MSK 0x8 + +/* + * enbl_boost + */ +#define TFA98XX_SYS_CONTROL0_DCA (0x1 << 4) +#define TFA98XX_SYS_CONTROL0_DCA_POS 4 +#define TFA98XX_SYS_CONTROL0_DCA_LEN 1 +#define TFA98XX_SYS_CONTROL0_DCA_MAX 1 +#define TFA98XX_SYS_CONTROL0_DCA_MSK 0x10 + +/* + * coolflux_configured + */ +#define TFA98XX_SYS_CONTROL0_SBSL (0x1 << 5) +#define TFA98XX_SYS_CONTROL0_SBSL_POS 5 +#define TFA98XX_SYS_CONTROL0_SBSL_LEN 1 +#define TFA98XX_SYS_CONTROL0_SBSL_MAX 1 +#define TFA98XX_SYS_CONTROL0_SBSL_MSK 0x20 + +/* + * sel_enbl_amplifier + */ +#define TFA98XX_SYS_CONTROL0_AMPC (0x1 << 6) +#define TFA98XX_SYS_CONTROL0_AMPC_POS 6 +#define TFA98XX_SYS_CONTROL0_AMPC_LEN 1 +#define TFA98XX_SYS_CONTROL0_AMPC_MAX 1 +#define TFA98XX_SYS_CONTROL0_AMPC_MSK 0x40 + +/* + * int_pad_io + */ +#define TFA98XX_SYS_CONTROL0_INTP (0x3 << 7) +#define TFA98XX_SYS_CONTROL0_INTP_POS 7 +#define TFA98XX_SYS_CONTROL0_INTP_LEN 2 +#define TFA98XX_SYS_CONTROL0_INTP_MAX 3 +#define TFA98XX_SYS_CONTROL0_INTP_MSK 0x180 + +/* + * fs_pulse_sel + */ +#define TFA98XX_SYS_CONTROL0_FSSSEL (0x3 << 9) +#define TFA98XX_SYS_CONTROL0_FSSSEL_POS 9 +#define TFA98XX_SYS_CONTROL0_FSSSEL_LEN 2 +#define TFA98XX_SYS_CONTROL0_FSSSEL_MAX 3 +#define TFA98XX_SYS_CONTROL0_FSSSEL_MSK 0x600 + +/* + * bypass_ocp + */ +#define TFA98XX_SYS_CONTROL0_BYPOCP (0x1 << 11) +#define TFA98XX_SYS_CONTROL0_BYPOCP_POS 11 +#define TFA98XX_SYS_CONTROL0_BYPOCP_LEN 1 +#define TFA98XX_SYS_CONTROL0_BYPOCP_MAX 1 +#define TFA98XX_SYS_CONTROL0_BYPOCP_MSK 0x800 + +/* + * test_ocp + */ +#define TFA98XX_SYS_CONTROL0_TSTOCP (0x1 << 12) +#define TFA98XX_SYS_CONTROL0_TSTOCP_POS 12 +#define TFA98XX_SYS_CONTROL0_TSTOCP_LEN 1 +#define TFA98XX_SYS_CONTROL0_TSTOCP_MAX 1 +#define TFA98XX_SYS_CONTROL0_TSTOCP_MSK 0x1000 + +/* + * (0x01)-sys_control1 + */ + +/* + * vamp_sel + */ +#define TFA98XX_SYS_CONTROL1_AMPINSEL (0x3 << 0) +#define TFA98XX_SYS_CONTROL1_AMPINSEL_POS 0 +#define TFA98XX_SYS_CONTROL1_AMPINSEL_LEN 2 +#define TFA98XX_SYS_CONTROL1_AMPINSEL_MAX 3 +#define TFA98XX_SYS_CONTROL1_AMPINSEL_MSK 0x3 + +/* + * src_set_configured + */ +#define TFA98XX_SYS_CONTROL1_MANSCONF (0x1 << 2) +#define TFA98XX_SYS_CONTROL1_MANSCONF_POS 2 +#define TFA98XX_SYS_CONTROL1_MANSCONF_LEN 1 +#define TFA98XX_SYS_CONTROL1_MANSCONF_MAX 1 +#define TFA98XX_SYS_CONTROL1_MANSCONF_MSK 0x4 + +/* + * execute_cold_start + */ +#define TFA98XX_SYS_CONTROL1_MANCOLD (0x1 << 3) +#define TFA98XX_SYS_CONTROL1_MANCOLD_POS 3 +#define TFA98XX_SYS_CONTROL1_MANCOLD_LEN 1 +#define TFA98XX_SYS_CONTROL1_MANCOLD_MAX 1 +#define TFA98XX_SYS_CONTROL1_MANCOLD_MSK 0x8 + +/* + * enbl_osc1m_auto_off + */ +#define TFA98XX_SYS_CONTROL1_MANAOOSC (0x1 << 4) +#define TFA98XX_SYS_CONTROL1_MANAOOSC_POS 4 +#define TFA98XX_SYS_CONTROL1_MANAOOSC_LEN 1 +#define TFA98XX_SYS_CONTROL1_MANAOOSC_MAX 1 +#define TFA98XX_SYS_CONTROL1_MANAOOSC_MSK 0x10 + +/* + * man_enbl_brown_out + */ +#define TFA98XX_SYS_CONTROL1_MANROBOD (0x1 << 5) +#define TFA98XX_SYS_CONTROL1_MANROBOD_POS 5 +#define TFA98XX_SYS_CONTROL1_MANROBOD_LEN 1 +#define TFA98XX_SYS_CONTROL1_MANROBOD_MAX 1 +#define TFA98XX_SYS_CONTROL1_MANROBOD_MSK 0x20 + +/* + * enbl_bod + */ +#define TFA98XX_SYS_CONTROL1_BODE (0x1 << 6) +#define TFA98XX_SYS_CONTROL1_BODE_POS 6 +#define TFA98XX_SYS_CONTROL1_BODE_LEN 1 +#define TFA98XX_SYS_CONTROL1_BODE_MAX 1 +#define TFA98XX_SYS_CONTROL1_BODE_MSK 0x40 + +/* + * enbl_bod_hyst + */ +#define TFA98XX_SYS_CONTROL1_BODHYS (0x1 << 7) +#define TFA98XX_SYS_CONTROL1_BODHYS_POS 7 +#define TFA98XX_SYS_CONTROL1_BODHYS_LEN 1 +#define TFA98XX_SYS_CONTROL1_BODHYS_MAX 1 +#define TFA98XX_SYS_CONTROL1_BODHYS_MSK 0x80 + +/* + * bod_delay + */ +#define TFA98XX_SYS_CONTROL1_BODFILT (0x3 << 8) +#define TFA98XX_SYS_CONTROL1_BODFILT_POS 8 +#define TFA98XX_SYS_CONTROL1_BODFILT_LEN 2 +#define TFA98XX_SYS_CONTROL1_BODFILT_MAX 3 +#define TFA98XX_SYS_CONTROL1_BODFILT_MSK 0x300 + +/* + * bod_lvlsel + */ +#define TFA98XX_SYS_CONTROL1_BODTHLVL (0x3 << 10) +#define TFA98XX_SYS_CONTROL1_BODTHLVL_POS 10 +#define TFA98XX_SYS_CONTROL1_BODTHLVL_LEN 2 +#define TFA98XX_SYS_CONTROL1_BODTHLVL_MAX 3 +#define TFA98XX_SYS_CONTROL1_BODTHLVL_MSK 0xc00 + +/* + * disable_mute_time_out + */ +#define TFA98XX_SYS_CONTROL1_MUTETO (0x1 << 13) +#define TFA98XX_SYS_CONTROL1_MUTETO_POS 13 +#define TFA98XX_SYS_CONTROL1_MUTETO_LEN 1 +#define TFA98XX_SYS_CONTROL1_MUTETO_MAX 1 +#define TFA98XX_SYS_CONTROL1_MUTETO_MSK 0x2000 + +/* + * pwm_sel_rcv_ns + */ +#define TFA98XX_SYS_CONTROL1_RCVNS (0x1 << 14) +#define TFA98XX_SYS_CONTROL1_RCVNS_POS 14 +#define TFA98XX_SYS_CONTROL1_RCVNS_LEN 1 +#define TFA98XX_SYS_CONTROL1_RCVNS_MAX 1 +#define TFA98XX_SYS_CONTROL1_RCVNS_MSK 0x4000 + +/* + * man_enbl_watchdog + */ +#define TFA98XX_SYS_CONTROL1_MANWDE (0x1 << 15) +#define TFA98XX_SYS_CONTROL1_MANWDE_POS 15 +#define TFA98XX_SYS_CONTROL1_MANWDE_LEN 1 +#define TFA98XX_SYS_CONTROL1_MANWDE_MAX 1 +#define TFA98XX_SYS_CONTROL1_MANWDE_MSK 0x8000 + +/* + * (0x02)-sys_control2 + */ + +/* + * audio_fs + */ +#define TFA98XX_SYS_CONTROL2_AUDFS (0xf << 0) +#define TFA98XX_SYS_CONTROL2_AUDFS_POS 0 +#define TFA98XX_SYS_CONTROL2_AUDFS_LEN 4 +#define TFA98XX_SYS_CONTROL2_AUDFS_MAX 15 +#define TFA98XX_SYS_CONTROL2_AUDFS_MSK 0xf + +/* + * input_level + */ +#define TFA98XX_SYS_CONTROL2_INPLEV (0x1 << 4) +#define TFA98XX_SYS_CONTROL2_INPLEV_POS 4 +#define TFA98XX_SYS_CONTROL2_INPLEV_LEN 1 +#define TFA98XX_SYS_CONTROL2_INPLEV_MAX 1 +#define TFA98XX_SYS_CONTROL2_INPLEV_MSK 0x10 + +/* + * cs_frac_delay + */ +#define TFA98XX_SYS_CONTROL2_FRACTDEL (0x3f << 5) +#define TFA98XX_SYS_CONTROL2_FRACTDEL_POS 5 +#define TFA98XX_SYS_CONTROL2_FRACTDEL_LEN 6 +#define TFA98XX_SYS_CONTROL2_FRACTDEL_MAX 63 +#define TFA98XX_SYS_CONTROL2_FRACTDEL_MSK 0x7e0 + +/* + * bypass_hvbat_filter + */ +#define TFA98XX_SYS_CONTROL2_BYPHVBF (0x1 << 11) +#define TFA98XX_SYS_CONTROL2_BYPHVBF_POS 11 +#define TFA98XX_SYS_CONTROL2_BYPHVBF_LEN 1 +#define TFA98XX_SYS_CONTROL2_BYPHVBF_MAX 1 +#define TFA98XX_SYS_CONTROL2_BYPHVBF_MSK 0x800 + +/* + * ctrl_rcvldop_bypass + */ +#define TFA98XX_SYS_CONTROL2_LDOBYP (0x1 << 12) +#define TFA98XX_SYS_CONTROL2_LDOBYP_POS 12 +#define TFA98XX_SYS_CONTROL2_LDOBYP_LEN 1 +#define TFA98XX_SYS_CONTROL2_LDOBYP_MAX 1 +#define TFA98XX_SYS_CONTROL2_LDOBYP_MSK 0x1000 + +/* + * (0x03)-device_revision + */ + +/* + * device_rev + */ +#define TFA98XX_DEVICE_REVISION_REV (0xffff << 0) +#define TFA98XX_DEVICE_REVISION_REV_POS 0 +#define TFA98XX_DEVICE_REVISION_REV_LEN 16 +#define TFA98XX_DEVICE_REVISION_REV_MAX 65535 +#define TFA98XX_DEVICE_REVISION_REV_MSK 0xffff + +/* + * (0x04)-clock_control + */ + +/* + * pll_clkin_sel + */ +#define TFA98XX_CLOCK_CONTROL_REFCKEXT (0x3 << 0) +#define TFA98XX_CLOCK_CONTROL_REFCKEXT_POS 0 +#define TFA98XX_CLOCK_CONTROL_REFCKEXT_LEN 2 +#define TFA98XX_CLOCK_CONTROL_REFCKEXT_MAX 3 +#define TFA98XX_CLOCK_CONTROL_REFCKEXT_MSK 0x3 + +/* + * pll_clkin_sel_osc + */ +#define TFA98XX_CLOCK_CONTROL_REFCKSEL (0x1 << 2) +#define TFA98XX_CLOCK_CONTROL_REFCKSEL_POS 2 +#define TFA98XX_CLOCK_CONTROL_REFCKSEL_LEN 1 +#define TFA98XX_CLOCK_CONTROL_REFCKSEL_MAX 1 +#define TFA98XX_CLOCK_CONTROL_REFCKSEL_MSK 0x4 + +/* + * (0x05)-clock_gating_control + */ + +/* + * enbl_spkr_ss_left + */ +#define TFA98XX_CLOCK_GATING_CONTROL_SSLEFTE (0x1 << 0) +#define TFA98XX_CLOCK_GATING_CONTROL_SSLEFTE_POS 0 +#define TFA98XX_CLOCK_GATING_CONTROL_SSLEFTE_LEN 1 +#define TFA98XX_CLOCK_GATING_CONTROL_SSLEFTE_MAX 1 +#define TFA98XX_CLOCK_GATING_CONTROL_SSLEFTE_MSK 0x1 + +/* + * enbl_spkr_ss_right + */ +#define TFA98XX_CLOCK_GATING_CONTROL_SSRIGHTE (0x1 << 1) +#define TFA98XX_CLOCK_GATING_CONTROL_SSRIGHTE_POS 1 +#define TFA98XX_CLOCK_GATING_CONTROL_SSRIGHTE_LEN 1 +#define TFA98XX_CLOCK_GATING_CONTROL_SSRIGHTE_MAX 1 +#define TFA98XX_CLOCK_GATING_CONTROL_SSRIGHTE_MSK 0x2 + +/* + * enbl_volsense_left + */ +#define TFA98XX_CLOCK_GATING_CONTROL_VSLEFTE (0x1 << 2) +#define TFA98XX_CLOCK_GATING_CONTROL_VSLEFTE_POS 2 +#define TFA98XX_CLOCK_GATING_CONTROL_VSLEFTE_LEN 1 +#define TFA98XX_CLOCK_GATING_CONTROL_VSLEFTE_MAX 1 +#define TFA98XX_CLOCK_GATING_CONTROL_VSLEFTE_MSK 0x4 + +/* + * enbl_volsense_right + */ +#define TFA98XX_CLOCK_GATING_CONTROL_VSRIGHTE (0x1 << 3) +#define TFA98XX_CLOCK_GATING_CONTROL_VSRIGHTE_POS 3 +#define TFA98XX_CLOCK_GATING_CONTROL_VSRIGHTE_LEN 1 +#define TFA98XX_CLOCK_GATING_CONTROL_VSRIGHTE_MAX 1 +#define TFA98XX_CLOCK_GATING_CONTROL_VSRIGHTE_MSK 0x8 + +/* + * enbl_cursense_left + */ +#define TFA98XX_CLOCK_GATING_CONTROL_CSLEFTE (0x1 << 4) +#define TFA98XX_CLOCK_GATING_CONTROL_CSLEFTE_POS 4 +#define TFA98XX_CLOCK_GATING_CONTROL_CSLEFTE_LEN 1 +#define TFA98XX_CLOCK_GATING_CONTROL_CSLEFTE_MAX 1 +#define TFA98XX_CLOCK_GATING_CONTROL_CSLEFTE_MSK 0x10 + +/* + * enbl_cursense_right + */ +#define TFA98XX_CLOCK_GATING_CONTROL_CSRIGHTE (0x1 << 5) +#define TFA98XX_CLOCK_GATING_CONTROL_CSRIGHTE_POS 5 +#define TFA98XX_CLOCK_GATING_CONTROL_CSRIGHTE_LEN 1 +#define TFA98XX_CLOCK_GATING_CONTROL_CSRIGHTE_MAX 1 +#define TFA98XX_CLOCK_GATING_CONTROL_CSRIGHTE_MSK 0x20 + +/* + * enbl_pdm_ss + */ +#define TFA98XX_CLOCK_GATING_CONTROL_SSPDME (0x1 << 6) +#define TFA98XX_CLOCK_GATING_CONTROL_SSPDME_POS 6 +#define TFA98XX_CLOCK_GATING_CONTROL_SSPDME_LEN 1 +#define TFA98XX_CLOCK_GATING_CONTROL_SSPDME_MAX 1 +#define TFA98XX_CLOCK_GATING_CONTROL_SSPDME_MSK 0x40 + +/* + * (0x0d)-side_tone_config + */ + +/* + * side_tone_gain + */ +#define TFA98XX_SIDE_TONE_CONFIG_STGAIN (0x1ff << 1) +#define TFA98XX_SIDE_TONE_CONFIG_STGAIN_POS 1 +#define TFA98XX_SIDE_TONE_CONFIG_STGAIN_LEN 9 +#define TFA98XX_SIDE_TONE_CONFIG_STGAIN_MAX 511 +#define TFA98XX_SIDE_TONE_CONFIG_STGAIN_MSK 0x3fe + +/* + * mute_side_tone + */ +#define TFA98XX_SIDE_TONE_CONFIG_PDMSMUTE (0x1 << 10) +#define TFA98XX_SIDE_TONE_CONFIG_PDMSMUTE_POS 10 +#define TFA98XX_SIDE_TONE_CONFIG_PDMSMUTE_LEN 1 +#define TFA98XX_SIDE_TONE_CONFIG_PDMSMUTE_MAX 1 +#define TFA98XX_SIDE_TONE_CONFIG_PDMSMUTE_MSK 0x400 + +/* + * (0x0e)-ctrl_digtoana_reg + */ + +/* + * ctrl_digtoana + */ +#define TFA98XX_CTRL_DIGTOANA_REG_SWVSTEP (0x7f << 0) +#define TFA98XX_CTRL_DIGTOANA_REG_SWVSTEP_POS 0 +#define TFA98XX_CTRL_DIGTOANA_REG_SWVSTEP_LEN 7 +#define TFA98XX_CTRL_DIGTOANA_REG_SWVSTEP_MAX 127 +#define TFA98XX_CTRL_DIGTOANA_REG_SWVSTEP_MSK 0x7f + +/* + * (0x10)-status_flags0 + */ + +/* + * flag_por + */ +#define TFA98XX_STATUS_FLAGS0_VDDS (0x1 << 0) +#define TFA98XX_STATUS_FLAGS0_VDDS_POS 0 +#define TFA98XX_STATUS_FLAGS0_VDDS_LEN 1 +#define TFA98XX_STATUS_FLAGS0_VDDS_MAX 1 +#define TFA98XX_STATUS_FLAGS0_VDDS_MSK 0x1 + +/* + * flag_pll_lock + */ +#define TFA98XX_STATUS_FLAGS0_PLLS (0x1 << 1) +#define TFA98XX_STATUS_FLAGS0_PLLS_POS 1 +#define TFA98XX_STATUS_FLAGS0_PLLS_LEN 1 +#define TFA98XX_STATUS_FLAGS0_PLLS_MAX 1 +#define TFA98XX_STATUS_FLAGS0_PLLS_MSK 0x2 + +/* + * flag_otpok + */ +#define TFA98XX_STATUS_FLAGS0_OTDS (0x1 << 2) +#define TFA98XX_STATUS_FLAGS0_OTDS_POS 2 +#define TFA98XX_STATUS_FLAGS0_OTDS_LEN 1 +#define TFA98XX_STATUS_FLAGS0_OTDS_MAX 1 +#define TFA98XX_STATUS_FLAGS0_OTDS_MSK 0x4 + +/* + * flag_ovpok + */ +#define TFA98XX_STATUS_FLAGS0_OVDS (0x1 << 3) +#define TFA98XX_STATUS_FLAGS0_OVDS_POS 3 +#define TFA98XX_STATUS_FLAGS0_OVDS_LEN 1 +#define TFA98XX_STATUS_FLAGS0_OVDS_MAX 1 +#define TFA98XX_STATUS_FLAGS0_OVDS_MSK 0x8 + +/* + * flag_uvpok + */ +#define TFA98XX_STATUS_FLAGS0_UVDS (0x1 << 4) +#define TFA98XX_STATUS_FLAGS0_UVDS_POS 4 +#define TFA98XX_STATUS_FLAGS0_UVDS_LEN 1 +#define TFA98XX_STATUS_FLAGS0_UVDS_MAX 1 +#define TFA98XX_STATUS_FLAGS0_UVDS_MSK 0x10 + +/* + * flag_clocks_stable + */ +#define TFA98XX_STATUS_FLAGS0_CLKS (0x1 << 6) +#define TFA98XX_STATUS_FLAGS0_CLKS_POS 5 +#define TFA98XX_STATUS_FLAGS0_CLKS_LEN 1 +#define TFA98XX_STATUS_FLAGS0_CLKS_MAX 1 +#define TFA98XX_STATUS_FLAGS0_CLKS_MSK 0x20 + +/* + * flag_mtp_busy + */ +#define TFA98XX_STATUS_FLAGS0_MTPB (0x1 < 7) +#define TFA98XX_STATUS_FLAGS0_MTPB_POS 7 +#define TFA98XX_STATUS_FLAGS0_MTPB_LEN 1 +#define TFA98XX_STATUS_FLAGS0_MTPB_MAX 1 +#define TFA98XX_STATUS_FLAGS0_MTPB_MSK 0x40 + +/* + * flag_lost_clk + */ +#define TFA98XX_STATUS_FLAGS0_NOCLK (0x1 << 8) +#define TFA98XX_STATUS_FLAGS0_NOCLK_POS 8 +#define TFA98XX_STATUS_FLAGS0_NOCLK_LEN 1 +#define TFA98XX_STATUS_FLAGS0_NOCLK_MAX 1 +#define TFA98XX_STATUS_FLAGS0_NOCLK_MSK 0x80 + +#if 0 +/* + * flag_cf_speakererror + */ +#define TFA98XX_STATUS_FLAGS0_SPKS (0x1 << 8) +#define TFA98XX_STATUS_FLAGS0_SPKS_POS 8 +#define TFA98XX_STATUS_FLAGS0_SPKS_LEN 1 +#define TFA98XX_STATUS_FLAGS0_SPKS_MAX 1 +#define TFA98XX_STATUS_FLAGS0_SPKS_MSK 0x100 +#endif + +/* + * flag_cold_started + */ +#define TFA98XX_STATUS_FLAGS0_ACS (0x1 << 9) +#define TFA98XX_STATUS_FLAGS0_ACS_POS 9 +#define TFA98XX_STATUS_FLAGS0_ACS_LEN 1 +#define TFA98XX_STATUS_FLAGS0_ACS_MAX 1 +#define TFA98XX_STATUS_FLAGS0_ACS_MSK 0x200 + +/* + * flag_engage + */ +#define TFA98XX_STATUS_FLAGS0_SWS (0x1 << 11) +#define TFA98XX_STATUS_FLAGS0_SWS_POS 11 +#define TFA98XX_STATUS_FLAGS0_SWS_LEN 1 +#define TFA98XX_STATUS_FLAGS0_SWS_MAX 1 +#define TFA98XX_STATUS_FLAGS0_SWS_MSK 0x400 + +/* + * flag_watchdog_reset + */ +#define TFA98XX_STATUS_FLAGS0_WDS (0x1 << 10) +#define TFA98XX_STATUS_FLAGS0_WDS_POS 10 +#define TFA98XX_STATUS_FLAGS0_WDS_LEN 1 +#define TFA98XX_STATUS_FLAGS0_WDS_MAX 1 +#define TFA98XX_STATUS_FLAGS0_WDS_MSK 0x800 + +/* + * flag_enbl_amp + */ +#define TFA98XX_STATUS_FLAGS0_AMPS (0x1 << 12) +#define TFA98XX_STATUS_FLAGS0_AMPS_POS 12 +#define TFA98XX_STATUS_FLAGS0_AMPS_LEN 1 +#define TFA98XX_STATUS_FLAGS0_AMPS_MAX 1 +#define TFA98XX_STATUS_FLAGS0_AMPS_MSK 0x1000 + +/* + * flag_enbl_ref + */ +#define TFA98XX_STATUS_FLAGS0_AREFS (0x1 << 13) +#define TFA98XX_STATUS_FLAGS0_AREFS_POS 13 +#define TFA98XX_STATUS_FLAGS0_AREFS_LEN 1 +#define TFA98XX_STATUS_FLAGS0_AREFS_MAX 1 +#define TFA98XX_STATUS_FLAGS0_AREFS_MSK 0x2000 + +/* + * flag_adc10_ready + */ +#define TFA98XX_STATUS_FLAGS0_ADCCR (0x1 << 14) +#define TFA98XX_STATUS_FLAGS0_ADCCR_POS 14 +#define TFA98XX_STATUS_FLAGS0_ADCCR_LEN 1 +#define TFA98XX_STATUS_FLAGS0_ADCCR_MAX 1 +#define TFA98XX_STATUS_FLAGS0_ADCCR_MSK 0x4000 + +/* + * flag_bod_vddd_nok + */ +#define TFA98XX_STATUS_FLAGS0_BODNOK (0x1 << 15) +#define TFA98XX_STATUS_FLAGS0_BODNOK_POS 15 +#define TFA98XX_STATUS_FLAGS0_BODNOK_LEN 1 +#define TFA98XX_STATUS_FLAGS0_BODNOK_MAX 1 +#define TFA98XX_STATUS_FLAGS0_BODNOK_MSK 0x8000 + +/* + * (0x11)-status_flags1 + */ + +/* + * flag_bst_bstcur + */ +#define TFA98XX_STATUS_FLAGS1_DCIL (0x1 << 0) +#define TFA98XX_STATUS_FLAGS1_DCIL_POS 0 +#define TFA98XX_STATUS_FLAGS1_DCIL_LEN 1 +#define TFA98XX_STATUS_FLAGS1_DCIL_MAX 1 +#define TFA98XX_STATUS_FLAGS1_DCIL_MSK 0x1 + +/* + * flag_bst_hiz + */ +#define TFA98XX_STATUS_FLAGS1_DCDCA (0x1 << 1) +#define TFA98XX_STATUS_FLAGS1_DCDCA_POS 1 +#define TFA98XX_STATUS_FLAGS1_DCDCA_LEN 1 +#define TFA98XX_STATUS_FLAGS1_DCDCA_MAX 1 +#define TFA98XX_STATUS_FLAGS1_DCDCA_MSK 0x2 + +/* + * flag_bst_ocpok + */ +#define TFA98XX_STATUS_FLAGS1_DCOCPOK (0x1 << 2) +#define TFA98XX_STATUS_FLAGS1_DCOCPOK_POS 2 +#define TFA98XX_STATUS_FLAGS1_DCOCPOK_LEN 1 +#define TFA98XX_STATUS_FLAGS1_DCOCPOK_MAX 1 +#define TFA98XX_STATUS_FLAGS1_DCOCPOK_MSK 0x4 + +/* + * flag_bst_voutcomp + */ +#define TFA98XX_STATUS_FLAGS1_DCHVBAT (0x1 << 4) +#define TFA98XX_STATUS_FLAGS1_DCHVBAT_POS 4 +#define TFA98XX_STATUS_FLAGS1_DCHVBAT_LEN 1 +#define TFA98XX_STATUS_FLAGS1_DCHVBAT_MAX 1 +#define TFA98XX_STATUS_FLAGS1_DCHVBAT_MSK 0x10 + +/* + * flag_bst_voutcomp86 + */ +#define TFA98XX_STATUS_FLAGS1_DCH114 (0x1 << 5) +#define TFA98XX_STATUS_FLAGS1_DCH114_POS 5 +#define TFA98XX_STATUS_FLAGS1_DCH114_LEN 1 +#define TFA98XX_STATUS_FLAGS1_DCH114_MAX 1 +#define TFA98XX_STATUS_FLAGS1_DCH114_MSK 0x20 + +/* + * flag_bst_voutcomp93 + */ +#define TFA98XX_STATUS_FLAGS1_DCH107 (0x1 << 6) +#define TFA98XX_STATUS_FLAGS1_DCH107_POS 6 +#define TFA98XX_STATUS_FLAGS1_DCH107_LEN 1 +#define TFA98XX_STATUS_FLAGS1_DCH107_MAX 1 +#define TFA98XX_STATUS_FLAGS1_DCH107_MSK 0x40 + +/* + * flag_soft_mute_busy + */ +#define TFA98XX_STATUS_FLAGS1_STMUTEB (0x1 << 7) +#define TFA98XX_STATUS_FLAGS1_STMUTEB_POS 7 +#define TFA98XX_STATUS_FLAGS1_STMUTEB_LEN 1 +#define TFA98XX_STATUS_FLAGS1_STMUTEB_MAX 1 +#define TFA98XX_STATUS_FLAGS1_STMUTEB_MSK 0x80 + +/* + * flag_soft_mute_state + */ +#define TFA98XX_STATUS_FLAGS1_STMUTE (0x1 << 8) +#define TFA98XX_STATUS_FLAGS1_STMUTE_POS 8 +#define TFA98XX_STATUS_FLAGS1_STMUTE_LEN 1 +#define TFA98XX_STATUS_FLAGS1_STMUTE_MAX 1 +#define TFA98XX_STATUS_FLAGS1_STMUTE_MSK 0x100 + +/* + * flag_tdm_lut_error + */ +#define TFA98XX_STATUS_FLAGS1_TDMLUTER (0x1 << 9) +#define TFA98XX_STATUS_FLAGS1_TDMLUTER_POS 9 +#define TFA98XX_STATUS_FLAGS1_TDMLUTER_LEN 1 +#define TFA98XX_STATUS_FLAGS1_TDMLUTER_MAX 1 +#define TFA98XX_STATUS_FLAGS1_TDMLUTER_MSK 0x200 + +/* + * flag_tdm_status + */ +#define TFA98XX_STATUS_FLAGS1_TDMSTAT (0x7 << 10) +#define TFA98XX_STATUS_FLAGS1_TDMSTAT_POS 10 +#define TFA98XX_STATUS_FLAGS1_TDMSTAT_LEN 3 +#define TFA98XX_STATUS_FLAGS1_TDMSTAT_MAX 7 +#define TFA98XX_STATUS_FLAGS1_TDMSTAT_MSK 0x1c00 + +/* + * flag_tdm_error + */ +#define TFA98XX_STATUS_FLAGS1_TDMERR (0x1 << 13) +#define TFA98XX_STATUS_FLAGS1_TDMERR_POS 13 +#define TFA98XX_STATUS_FLAGS1_TDMERR_LEN 1 +#define TFA98XX_STATUS_FLAGS1_TDMERR_MAX 1 +#define TFA98XX_STATUS_FLAGS1_TDMERR_MSK 0x2000 + +/* + * flag_haptic_busy + */ +#define TFA98XX_STATUS_FLAGS1_HAPTIC (0x1 << 14) +#define TFA98XX_STATUS_FLAGS1_HAPTIC_POS 14 +#define TFA98XX_STATUS_FLAGS1_HAPTIC_LEN 1 +#define TFA98XX_STATUS_FLAGS1_HAPTIC_MAX 1 +#define TFA98XX_STATUS_FLAGS1_HAPTIC_MSK 0x4000 + +/* + * (0x12)-status_flags2 + */ + +/* + * flag_ocpokap_left + */ +#define TFA98XX_STATUS_FLAGS2_OCPOAPL (0x1 << 0) +#define TFA98XX_STATUS_FLAGS2_OCPOAPL_POS 0 +#define TFA98XX_STATUS_FLAGS2_OCPOAPL_LEN 1 +#define TFA98XX_STATUS_FLAGS2_OCPOAPL_MAX 1 +#define TFA98XX_STATUS_FLAGS2_OCPOAPL_MSK 0x1 + +/* + * flag_ocpokan_left + */ +#define TFA98XX_STATUS_FLAGS2_OCPOANL (0x1 << 1) +#define TFA98XX_STATUS_FLAGS2_OCPOANL_POS 1 +#define TFA98XX_STATUS_FLAGS2_OCPOANL_LEN 1 +#define TFA98XX_STATUS_FLAGS2_OCPOANL_MAX 1 +#define TFA98XX_STATUS_FLAGS2_OCPOANL_MSK 0x2 + +/* + * flag_ocpokbp_left + */ +#define TFA98XX_STATUS_FLAGS2_OCPOBPL (0x1 << 2) +#define TFA98XX_STATUS_FLAGS2_OCPOBPL_POS 2 +#define TFA98XX_STATUS_FLAGS2_OCPOBPL_LEN 1 +#define TFA98XX_STATUS_FLAGS2_OCPOBPL_MAX 1 +#define TFA98XX_STATUS_FLAGS2_OCPOBPL_MSK 0x4 + +/* + * flag_ocpokbn_left + */ +#define TFA98XX_STATUS_FLAGS2_OCPOBNL (0x1 << 3) +#define TFA98XX_STATUS_FLAGS2_OCPOBNL_POS 3 +#define TFA98XX_STATUS_FLAGS2_OCPOBNL_LEN 1 +#define TFA98XX_STATUS_FLAGS2_OCPOBNL_MAX 1 +#define TFA98XX_STATUS_FLAGS2_OCPOBNL_MSK 0x8 + +/* + * flag_clipa_high_left + */ +#define TFA98XX_STATUS_FLAGS2_CLIPAHL (0x1 << 4) +#define TFA98XX_STATUS_FLAGS2_CLIPAHL_POS 4 +#define TFA98XX_STATUS_FLAGS2_CLIPAHL_LEN 1 +#define TFA98XX_STATUS_FLAGS2_CLIPAHL_MAX 1 +#define TFA98XX_STATUS_FLAGS2_CLIPAHL_MSK 0x10 + +/* + * flag_clipa_low_left + */ +#define TFA98XX_STATUS_FLAGS2_CLIPALL (0x1 << 5) +#define TFA98XX_STATUS_FLAGS2_CLIPALL_POS 5 +#define TFA98XX_STATUS_FLAGS2_CLIPALL_LEN 1 +#define TFA98XX_STATUS_FLAGS2_CLIPALL_MAX 1 +#define TFA98XX_STATUS_FLAGS2_CLIPALL_MSK 0x20 + +/* + * flag_clipb_high_left + */ +#define TFA98XX_STATUS_FLAGS2_CLIPBHL (0x1 << 6) +#define TFA98XX_STATUS_FLAGS2_CLIPBHL_POS 6 +#define TFA98XX_STATUS_FLAGS2_CLIPBHL_LEN 1 +#define TFA98XX_STATUS_FLAGS2_CLIPBHL_MAX 1 +#define TFA98XX_STATUS_FLAGS2_CLIPBHL_MSK 0x40 + +/* + * flag_clipb_low_left + */ +#define TFA98XX_STATUS_FLAGS2_CLIPBLL (0x1 << 7) +#define TFA98XX_STATUS_FLAGS2_CLIPBLL_POS 7 +#define TFA98XX_STATUS_FLAGS2_CLIPBLL_LEN 1 +#define TFA98XX_STATUS_FLAGS2_CLIPBLL_MAX 1 +#define TFA98XX_STATUS_FLAGS2_CLIPBLL_MSK 0x80 + +/* + * flag_ocpokap_rcv + */ +#define TFA98XX_STATUS_FLAGS2_OCPOAPRC (0x1 << 8) +#define TFA98XX_STATUS_FLAGS2_OCPOAPRC_POS 8 +#define TFA98XX_STATUS_FLAGS2_OCPOAPRC_LEN 1 +#define TFA98XX_STATUS_FLAGS2_OCPOAPRC_MAX 1 +#define TFA98XX_STATUS_FLAGS2_OCPOAPRC_MSK 0x100 + +/* + * flag_ocpokan_rcv + */ +#define TFA98XX_STATUS_FLAGS2_OCPOANRC (0x1 << 9) +#define TFA98XX_STATUS_FLAGS2_OCPOANRC_POS 9 +#define TFA98XX_STATUS_FLAGS2_OCPOANRC_LEN 1 +#define TFA98XX_STATUS_FLAGS2_OCPOANRC_MAX 1 +#define TFA98XX_STATUS_FLAGS2_OCPOANRC_MSK 0x200 + +/* + * flag_ocpokbp_rcv + */ +#define TFA98XX_STATUS_FLAGS2_OCPOBPRC (0x1 << 10) +#define TFA98XX_STATUS_FLAGS2_OCPOBPRC_POS 10 +#define TFA98XX_STATUS_FLAGS2_OCPOBPRC_LEN 1 +#define TFA98XX_STATUS_FLAGS2_OCPOBPRC_MAX 1 +#define TFA98XX_STATUS_FLAGS2_OCPOBPRC_MSK 0x400 + +/* + * flag_ocpokbn_rcv + */ +#define TFA98XX_STATUS_FLAGS2_OCPOBNRC (0x1 << 11) +#define TFA98XX_STATUS_FLAGS2_OCPOBNRC_POS 11 +#define TFA98XX_STATUS_FLAGS2_OCPOBNRC_LEN 1 +#define TFA98XX_STATUS_FLAGS2_OCPOBNRC_MAX 1 +#define TFA98XX_STATUS_FLAGS2_OCPOBNRC_MSK 0x800 + +/* + * flag_rcvldop_ready + */ +#define TFA98XX_STATUS_FLAGS2_RCVLDOR (0x1 << 12) +#define TFA98XX_STATUS_FLAGS2_RCVLDOR_POS 12 +#define TFA98XX_STATUS_FLAGS2_RCVLDOR_LEN 1 +#define TFA98XX_STATUS_FLAGS2_RCVLDOR_MAX 1 +#define TFA98XX_STATUS_FLAGS2_RCVLDOR_MSK 0x1000 + +/* + * flag_rcvldop_bypassready + */ +#define TFA98XX_STATUS_FLAGS2_RCVLDOBR (0x1 << 13) +#define TFA98XX_STATUS_FLAGS2_RCVLDOBR_POS 13 +#define TFA98XX_STATUS_FLAGS2_RCVLDOBR_LEN 1 +#define TFA98XX_STATUS_FLAGS2_RCVLDOBR_MAX 1 +#define TFA98XX_STATUS_FLAGS2_RCVLDOBR_MSK 0x2000 + +/* + * flag_ocp_alarm_left + */ +#define TFA98XX_STATUS_FLAGS2_OCDSL (0x1 << 14) +#define TFA98XX_STATUS_FLAGS2_OCDSL_POS 14 +#define TFA98XX_STATUS_FLAGS2_OCDSL_LEN 1 +#define TFA98XX_STATUS_FLAGS2_OCDSL_MAX 1 +#define TFA98XX_STATUS_FLAGS2_OCDSL_MSK 0x4000 + +/* + * flag_clip_left + */ +#define TFA98XX_STATUS_FLAGS2_CLIPSL (0x1 << 15) +#define TFA98XX_STATUS_FLAGS2_CLIPSL_POS 15 +#define TFA98XX_STATUS_FLAGS2_CLIPSL_LEN 1 +#define TFA98XX_STATUS_FLAGS2_CLIPSL_MAX 1 +#define TFA98XX_STATUS_FLAGS2_CLIPSL_MSK 0x8000 + +/* + * (0x13)-status_flags3 + */ + +/* + * flag_ocpokap_right + */ +#define TFA98XX_STATUS_FLAGS3_OCPOAPR (0x1 << 0) +#define TFA98XX_STATUS_FLAGS3_OCPOAPR_POS 0 +#define TFA98XX_STATUS_FLAGS3_OCPOAPR_LEN 1 +#define TFA98XX_STATUS_FLAGS3_OCPOAPR_MAX 1 +#define TFA98XX_STATUS_FLAGS3_OCPOAPR_MSK 0x1 + +/* + * flag_ocpokan_right + */ +#define TFA98XX_STATUS_FLAGS3_OCPOANR (0x1 << 1) +#define TFA98XX_STATUS_FLAGS3_OCPOANR_POS 1 +#define TFA98XX_STATUS_FLAGS3_OCPOANR_LEN 1 +#define TFA98XX_STATUS_FLAGS3_OCPOANR_MAX 1 +#define TFA98XX_STATUS_FLAGS3_OCPOANR_MSK 0x2 + +/* + * flag_ocpokbp_right + */ +#define TFA98XX_STATUS_FLAGS3_OCPOBPR (0x1 << 2) +#define TFA98XX_STATUS_FLAGS3_OCPOBPR_POS 2 +#define TFA98XX_STATUS_FLAGS3_OCPOBPR_LEN 1 +#define TFA98XX_STATUS_FLAGS3_OCPOBPR_MAX 1 +#define TFA98XX_STATUS_FLAGS3_OCPOBPR_MSK 0x4 + +/* + * flag_ocpokbn_right + */ +#define TFA98XX_STATUS_FLAGS3_OCPOBNR (0x1 << 3) +#define TFA98XX_STATUS_FLAGS3_OCPOBNR_POS 3 +#define TFA98XX_STATUS_FLAGS3_OCPOBNR_LEN 1 +#define TFA98XX_STATUS_FLAGS3_OCPOBNR_MAX 1 +#define TFA98XX_STATUS_FLAGS3_OCPOBNR_MSK 0x8 + +/* + * flag_clipa_high_right + */ +#define TFA98XX_STATUS_FLAGS3_CLIPAHR (0x1 << 4) +#define TFA98XX_STATUS_FLAGS3_CLIPAHR_POS 4 +#define TFA98XX_STATUS_FLAGS3_CLIPAHR_LEN 1 +#define TFA98XX_STATUS_FLAGS3_CLIPAHR_MAX 1 +#define TFA98XX_STATUS_FLAGS3_CLIPAHR_MSK 0x10 + +/* + * flag_clipa_low_right + */ +#define TFA98XX_STATUS_FLAGS3_CLIPALR (0x1 << 5) +#define TFA98XX_STATUS_FLAGS3_CLIPALR_POS 5 +#define TFA98XX_STATUS_FLAGS3_CLIPALR_LEN 1 +#define TFA98XX_STATUS_FLAGS3_CLIPALR_MAX 1 +#define TFA98XX_STATUS_FLAGS3_CLIPALR_MSK 0x20 + +/* + * flag_clipb_high_right + */ +#define TFA98XX_STATUS_FLAGS3_CLIPBHR (0x1 << 6) +#define TFA98XX_STATUS_FLAGS3_CLIPBHR_POS 6 +#define TFA98XX_STATUS_FLAGS3_CLIPBHR_LEN 1 +#define TFA98XX_STATUS_FLAGS3_CLIPBHR_MAX 1 +#define TFA98XX_STATUS_FLAGS3_CLIPBHR_MSK 0x40 + +/* + * flag_clipb_low_right + */ +#define TFA98XX_STATUS_FLAGS3_CLIPBLR (0x1 << 7) +#define TFA98XX_STATUS_FLAGS3_CLIPBLR_POS 7 +#define TFA98XX_STATUS_FLAGS3_CLIPBLR_LEN 1 +#define TFA98XX_STATUS_FLAGS3_CLIPBLR_MAX 1 +#define TFA98XX_STATUS_FLAGS3_CLIPBLR_MSK 0x80 + +/* + * flag_ocp_alarm_right + */ +#define TFA98XX_STATUS_FLAGS3_OCDSR (0x1 << 8) +#define TFA98XX_STATUS_FLAGS3_OCDSR_POS 8 +#define TFA98XX_STATUS_FLAGS3_OCDSR_LEN 1 +#define TFA98XX_STATUS_FLAGS3_OCDSR_MAX 1 +#define TFA98XX_STATUS_FLAGS3_OCDSR_MSK 0x100 + +/* + * flag_clip_right + */ +#define TFA98XX_STATUS_FLAGS3_CLIPSR (0x1 << 9) +#define TFA98XX_STATUS_FLAGS3_CLIPSR_POS 9 +#define TFA98XX_STATUS_FLAGS3_CLIPSR_LEN 1 +#define TFA98XX_STATUS_FLAGS3_CLIPSR_MAX 1 +#define TFA98XX_STATUS_FLAGS3_CLIPSR_MSK 0x200 + +/* + * flag_mic_ocpok + */ +#define TFA98XX_STATUS_FLAGS3_OCPOKMC (0x1 << 10) +#define TFA98XX_STATUS_FLAGS3_OCPOKMC_POS 10 +#define TFA98XX_STATUS_FLAGS3_OCPOKMC_LEN 1 +#define TFA98XX_STATUS_FLAGS3_OCPOKMC_MAX 1 +#define TFA98XX_STATUS_FLAGS3_OCPOKMC_MSK 0x400 + +/* + * flag_man_alarm_state + */ +#define TFA98XX_STATUS_FLAGS3_MANALARM (0x1 << 11) +#define TFA98XX_STATUS_FLAGS3_MANALARM_POS 11 +#define TFA98XX_STATUS_FLAGS3_MANALARM_LEN 1 +#define TFA98XX_STATUS_FLAGS3_MANALARM_MAX 1 +#define TFA98XX_STATUS_FLAGS3_MANALARM_MSK 0x800 + +/* + * flag_man_wait_src_settings + */ +#define TFA98XX_STATUS_FLAGS3_MANWAIT1 (0x1 << 12) +#define TFA98XX_STATUS_FLAGS3_MANWAIT1_POS 12 +#define TFA98XX_STATUS_FLAGS3_MANWAIT1_LEN 1 +#define TFA98XX_STATUS_FLAGS3_MANWAIT1_MAX 1 +#define TFA98XX_STATUS_FLAGS3_MANWAIT1_MSK 0x1000 + +/* + * flag_man_wait_cf_config + */ +#define TFA98XX_STATUS_FLAGS3_MANWAIT2 (0x1 << 13) +#define TFA98XX_STATUS_FLAGS3_MANWAIT2_POS 13 +#define TFA98XX_STATUS_FLAGS3_MANWAIT2_LEN 1 +#define TFA98XX_STATUS_FLAGS3_MANWAIT2_MAX 1 +#define TFA98XX_STATUS_FLAGS3_MANWAIT2_MSK 0x2000 + +/* + * flag_man_start_mute_audio + */ +#define TFA98XX_STATUS_FLAGS3_MANMUTE (0x1 << 14) +#define TFA98XX_STATUS_FLAGS3_MANMUTE_POS 14 +#define TFA98XX_STATUS_FLAGS3_MANMUTE_LEN 1 +#define TFA98XX_STATUS_FLAGS3_MANMUTE_MAX 1 +#define TFA98XX_STATUS_FLAGS3_MANMUTE_MSK 0x4000 + +/* + * flag_man_operating_state + */ +#define TFA98XX_STATUS_FLAGS3_MANOPER (0x1 << 15) +#define TFA98XX_STATUS_FLAGS3_MANOPER_POS 15 +#define TFA98XX_STATUS_FLAGS3_MANOPER_LEN 1 +#define TFA98XX_STATUS_FLAGS3_MANOPER_MAX 1 +#define TFA98XX_STATUS_FLAGS3_MANOPER_MSK 0x8000 + +/* + * (0x14)-status_flags4 + */ + +/* + * flag_cf_speakererror_left + */ +#define TFA98XX_STATUS_FLAGS4_SPKSL (0x1 << 0) +#define TFA98XX_STATUS_FLAGS4_SPKSL_POS 0 +#define TFA98XX_STATUS_FLAGS4_SPKSL_LEN 1 +#define TFA98XX_STATUS_FLAGS4_SPKSL_MAX 1 +#define TFA98XX_STATUS_FLAGS4_SPKSL_MSK 0x1 + +/* + * flag_cf_speakererror_right + */ +#define TFA98XX_STATUS_FLAGS4_SPKSR (0x1 << 1) +#define TFA98XX_STATUS_FLAGS4_SPKSR_POS 1 +#define TFA98XX_STATUS_FLAGS4_SPKSR_LEN 1 +#define TFA98XX_STATUS_FLAGS4_SPKSR_MAX 1 +#define TFA98XX_STATUS_FLAGS4_SPKSR_MSK 0x2 + +/* + * flag_clk_out_of_range + */ +#define TFA98XX_STATUS_FLAGS4_CLKOOR (0x1 << 2) +#define TFA98XX_STATUS_FLAGS4_CLKOOR_POS 2 +#define TFA98XX_STATUS_FLAGS4_CLKOOR_LEN 1 +#define TFA98XX_STATUS_FLAGS4_CLKOOR_MAX 1 +#define TFA98XX_STATUS_FLAGS4_CLKOOR_MSK 0x4 + +/* + * man_state + */ +#define TFA98XX_STATUS_FLAGS4_MANSTATE (0xf << 3) +#define TFA98XX_STATUS_FLAGS4_MANSTATE_POS 3 +#define TFA98XX_STATUS_FLAGS4_MANSTATE_LEN 4 +#define TFA98XX_STATUS_FLAGS4_MANSTATE_MAX 15 +#define TFA98XX_STATUS_FLAGS4_MANSTATE_MSK 0x78 + +/* + * (0x15)-battery_voltage + */ + +/* + * bat_adc + */ +#define TFA98XX_BATTERY_VOLTAGE_BATS (0x3ff << 0) +#define TFA98XX_BATTERY_VOLTAGE_BATS_POS 0 +#define TFA98XX_BATTERY_VOLTAGE_BATS_LEN 10 +#define TFA98XX_BATTERY_VOLTAGE_BATS_MAX 1023 +#define TFA98XX_BATTERY_VOLTAGE_BATS_MSK 0x3ff + +/* + * (0x16)-temperature + */ + +/* + * temp_adc + */ +#define TFA98XX_TEMPERATURE_TEMPS (0x1ff << 0) +#define TFA98XX_TEMPERATURE_TEMPS_POS 0 +#define TFA98XX_TEMPERATURE_TEMPS_LEN 9 +#define TFA98XX_TEMPERATURE_TEMPS_MAX 511 +#define TFA98XX_TEMPERATURE_TEMPS_MSK 0x1ff + +/* + * (0x20)-tdm_config0 + */ + +/* + * tdm_usecase + */ +#define TFA98XX_TDM_CONFIG0_TDMUC (0xf << 0) +#define TFA98XX_TDM_CONFIG0_TDMUC_POS 0 +#define TFA98XX_TDM_CONFIG0_TDMUC_LEN 4 +#define TFA98XX_TDM_CONFIG0_TDMUC_MAX 15 +#define TFA98XX_TDM_CONFIG0_TDMUC_MSK 0xf + +/* + * tdm_enable + */ +#define TFA98XX_TDM_CONFIG0_TDME (0x1 << 4) +#define TFA98XX_TDM_CONFIG0_TDME_POS 4 +#define TFA98XX_TDM_CONFIG0_TDME_LEN 1 +#define TFA98XX_TDM_CONFIG0_TDME_MAX 1 +#define TFA98XX_TDM_CONFIG0_TDME_MSK 0x10 + +/* + * tdm_mode + */ +#define TFA98XX_TDM_CONFIG0_TDMMODE (0x1 << 5) +#define TFA98XX_TDM_CONFIG0_TDMMODE_POS 5 +#define TFA98XX_TDM_CONFIG0_TDMMODE_LEN 1 +#define TFA98XX_TDM_CONFIG0_TDMMODE_MAX 1 +#define TFA98XX_TDM_CONFIG0_TDMMODE_MSK 0x20 + +/* + * tdm_clk_inversion + */ +#define TFA98XX_TDM_CONFIG0_TDMCLINV (0x1 << 6) +#define TFA98XX_TDM_CONFIG0_TDMCLINV_POS 6 +#define TFA98XX_TDM_CONFIG0_TDMCLINV_LEN 1 +#define TFA98XX_TDM_CONFIG0_TDMCLINV_MAX 1 +#define TFA98XX_TDM_CONFIG0_TDMCLINV_MSK 0x40 + +/* + * tdm_fs_ws_length + */ +#define TFA98XX_TDM_CONFIG0_TDMFSLN (0xf << 7) +#define TFA98XX_TDM_CONFIG0_TDMFSLN_POS 7 +#define TFA98XX_TDM_CONFIG0_TDMFSLN_LEN 4 +#define TFA98XX_TDM_CONFIG0_TDMFSLN_MAX 15 +#define TFA98XX_TDM_CONFIG0_TDMFSLN_MSK 0x780 + +/* + * tdm_fs_ws_polarity + */ +#define TFA98XX_TDM_CONFIG0_TDMFSPOL (0x1 << 11) +#define TFA98XX_TDM_CONFIG0_TDMFSPOL_POS 11 +#define TFA98XX_TDM_CONFIG0_TDMFSPOL_LEN 1 +#define TFA98XX_TDM_CONFIG0_TDMFSPOL_MAX 1 +#define TFA98XX_TDM_CONFIG0_TDMFSPOL_MSK 0x800 + +/* + * tdm_nbck + */ +#define TFA98XX_TDM_CONFIG0_TDMNBCK (0xf << 12) +#define TFA98XX_TDM_CONFIG0_TDMNBCK_POS 12 +#define TFA98XX_TDM_CONFIG0_TDMNBCK_LEN 4 +#define TFA98XX_TDM_CONFIG0_TDMNBCK_MAX 15 +#define TFA98XX_TDM_CONFIG0_TDMNBCK_MSK 0xf000 + +/* + * (0x21)-tdm_config1 + */ + +/* + * tdm_nb_of_slots + */ +#define TFA98XX_TDM_CONFIG1_TDMSLOTS (0xf << 0) +#define TFA98XX_TDM_CONFIG1_TDMSLOTS_POS 0 +#define TFA98XX_TDM_CONFIG1_TDMSLOTS_LEN 4 +#define TFA98XX_TDM_CONFIG1_TDMSLOTS_MAX 15 +#define TFA98XX_TDM_CONFIG1_TDMSLOTS_MSK 0xf + +/* + * tdm_slot_length + */ +#define TFA98XX_TDM_CONFIG1_TDMSLLN (0x1f << 4) +#define TFA98XX_TDM_CONFIG1_TDMSLLN_POS 4 +#define TFA98XX_TDM_CONFIG1_TDMSLLN_LEN 5 +#define TFA98XX_TDM_CONFIG1_TDMSLLN_MAX 31 +#define TFA98XX_TDM_CONFIG1_TDMSLLN_MSK 0x1f0 + +/* + * tdm_bits_remaining + */ +#define TFA98XX_TDM_CONFIG1_TDMBRMG (0x1f << 9) +#define TFA98XX_TDM_CONFIG1_TDMBRMG_POS 9 +#define TFA98XX_TDM_CONFIG1_TDMBRMG_LEN 5 +#define TFA98XX_TDM_CONFIG1_TDMBRMG_MAX 31 +#define TFA98XX_TDM_CONFIG1_TDMBRMG_MSK 0x3e00 + +/* + * tdm_data_delay + */ +#define TFA98XX_TDM_CONFIG1_TDMDEL (0x1 << 14) +#define TFA98XX_TDM_CONFIG1_TDMDEL_POS 14 +#define TFA98XX_TDM_CONFIG1_TDMDEL_LEN 1 +#define TFA98XX_TDM_CONFIG1_TDMDEL_MAX 1 +#define TFA98XX_TDM_CONFIG1_TDMDEL_MSK 0x4000 + +/* + * tdm_data_adjustment + */ +#define TFA98XX_TDM_CONFIG1_TDMADJ (0x1 << 15) +#define TFA98XX_TDM_CONFIG1_TDMADJ_POS 15 +#define TFA98XX_TDM_CONFIG1_TDMADJ_LEN 1 +#define TFA98XX_TDM_CONFIG1_TDMADJ_MAX 1 +#define TFA98XX_TDM_CONFIG1_TDMADJ_MSK 0x8000 + +/* + * (0x22)-tdm_config2 + */ + +/* + * tdm_audio_sample_compression + */ +#define TFA98XX_TDM_CONFIG2_TDMOOMP (0x3 << 0) +#define TFA98XX_TDM_CONFIG2_TDMOOMP_POS 0 +#define TFA98XX_TDM_CONFIG2_TDMOOMP_LEN 2 +#define TFA98XX_TDM_CONFIG2_TDMOOMP_MAX 3 +#define TFA98XX_TDM_CONFIG2_TDMOOMP_MSK 0x3 + +/* + * tdm_sample_size + */ +#define TFA98XX_TDM_CONFIG2_TDMSSIZE (0x1f << 2) +#define TFA98XX_TDM_CONFIG2_TDMSSIZE_POS 2 +#define TFA98XX_TDM_CONFIG2_TDMSSIZE_LEN 5 +#define TFA98XX_TDM_CONFIG2_TDMSSIZE_MAX 31 +#define TFA98XX_TDM_CONFIG2_TDMSSIZE_MSK 0x7c + +/* + * tdm_txdata_format + */ +#define TFA98XX_TDM_CONFIG2_TDMTXDFO (0x3 << 7) +#define TFA98XX_TDM_CONFIG2_TDMTXDFO_POS 7 +#define TFA98XX_TDM_CONFIG2_TDMTXDFO_LEN 2 +#define TFA98XX_TDM_CONFIG2_TDMTXDFO_MAX 3 +#define TFA98XX_TDM_CONFIG2_TDMTXDFO_MSK 0x180 + +/* + * tdm_txdata_format_unused_slot_sd0 + */ +#define TFA98XX_TDM_CONFIG2_TDMTXUS0 (0x3 << 9) +#define TFA98XX_TDM_CONFIG2_TDMTXUS0_POS 9 +#define TFA98XX_TDM_CONFIG2_TDMTXUS0_LEN 2 +#define TFA98XX_TDM_CONFIG2_TDMTXUS0_MAX 3 +#define TFA98XX_TDM_CONFIG2_TDMTXUS0_MSK 0x600 + +/* + * tdm_txdata_format_unused_slot_sd1 + */ +#define TFA98XX_TDM_CONFIG2_TDMTXUS1 (0x3 << 11) +#define TFA98XX_TDM_CONFIG2_TDMTXUS1_POS 11 +#define TFA98XX_TDM_CONFIG2_TDMTXUS1_LEN 2 +#define TFA98XX_TDM_CONFIG2_TDMTXUS1_MAX 3 +#define TFA98XX_TDM_CONFIG2_TDMTXUS1_MSK 0x1800 + +/* + * tdm_txdata_format_unused_slot_sd2 + */ +#define TFA98XX_TDM_CONFIG2_TDMTXUS2 (0x3 << 13) +#define TFA98XX_TDM_CONFIG2_TDMTXUS2_POS 13 +#define TFA98XX_TDM_CONFIG2_TDMTXUS2_LEN 2 +#define TFA98XX_TDM_CONFIG2_TDMTXUS2_MAX 3 +#define TFA98XX_TDM_CONFIG2_TDMTXUS2_MSK 0x6000 + +/* + * (0x23)-tdm_config3 + */ + +/* + * tdm_sink1_enable + */ +#define TFA98XX_TDM_CONFIG3_TDMLE (0x1 << 1) +#define TFA98XX_TDM_CONFIG3_TDMLE_POS 1 +#define TFA98XX_TDM_CONFIG3_TDMLE_LEN 1 +#define TFA98XX_TDM_CONFIG3_TDMLE_MAX 1 +#define TFA98XX_TDM_CONFIG3_TDMLE_MSK 0x2 + +/* + * tdm_sink2_enable + */ +#define TFA98XX_TDM_CONFIG3_TDMRE (0x1 << 2) +#define TFA98XX_TDM_CONFIG3_TDMRE_POS 2 +#define TFA98XX_TDM_CONFIG3_TDMRE_LEN 1 +#define TFA98XX_TDM_CONFIG3_TDMRE_MAX 1 +#define TFA98XX_TDM_CONFIG3_TDMRE_MSK 0x4 + +/* + * tdm_source1_enable + */ +#define TFA98XX_TDM_CONFIG3_TDMVSRE (0x1 << 4) +#define TFA98XX_TDM_CONFIG3_TDMVSRE_POS 4 +#define TFA98XX_TDM_CONFIG3_TDMVSRE_LEN 1 +#define TFA98XX_TDM_CONFIG3_TDMVSRE_MAX 1 +#define TFA98XX_TDM_CONFIG3_TDMVSRE_MSK 0x10 + +/* + * tdm_source2_enable + */ +#define TFA98XX_TDM_CONFIG3_TDMCSRE (0x1 << 5) +#define TFA98XX_TDM_CONFIG3_TDMCSRE_POS 5 +#define TFA98XX_TDM_CONFIG3_TDMCSRE_LEN 1 +#define TFA98XX_TDM_CONFIG3_TDMCSRE_MAX 1 +#define TFA98XX_TDM_CONFIG3_TDMCSRE_MSK 0x20 + +/* + * tdm_source3_enable + */ +#define TFA98XX_TDM_CONFIG3_TDMVSLE (0x1 << 6) +#define TFA98XX_TDM_CONFIG3_TDMVSLE_POS 6 +#define TFA98XX_TDM_CONFIG3_TDMVSLE_LEN 1 +#define TFA98XX_TDM_CONFIG3_TDMVSLE_MAX 1 +#define TFA98XX_TDM_CONFIG3_TDMVSLE_MSK 0x40 + +/* + * tdm_source4_enable + */ +#define TFA98XX_TDM_CONFIG3_TDMCSLE (0x1 << 7) +#define TFA98XX_TDM_CONFIG3_TDMCSLE_POS 7 +#define TFA98XX_TDM_CONFIG3_TDMCSLE_LEN 1 +#define TFA98XX_TDM_CONFIG3_TDMCSLE_MAX 1 +#define TFA98XX_TDM_CONFIG3_TDMCSLE_MSK 0x80 + +/* + * tdm_source5_enable + */ +#define TFA98XX_TDM_CONFIG3_TDMCFRE (0x1 << 8) +#define TFA98XX_TDM_CONFIG3_TDMCFRE_POS 8 +#define TFA98XX_TDM_CONFIG3_TDMCFRE_LEN 1 +#define TFA98XX_TDM_CONFIG3_TDMCFRE_MAX 1 +#define TFA98XX_TDM_CONFIG3_TDMCFRE_MSK 0x100 + +/* + * tdm_source6_enable + */ +#define TFA98XX_TDM_CONFIG3_TDMCFLE (0x1 << 9) +#define TFA98XX_TDM_CONFIG3_TDMCFLE_POS 9 +#define TFA98XX_TDM_CONFIG3_TDMCFLE_LEN 1 +#define TFA98XX_TDM_CONFIG3_TDMCFLE_MAX 1 +#define TFA98XX_TDM_CONFIG3_TDMCFLE_MSK 0x200 + +/* + * tdm_source7_enable + */ +#define TFA98XX_TDM_CONFIG3_TDMCF3E (0x1 << 10) +#define TFA98XX_TDM_CONFIG3_TDMCF3E_POS 10 +#define TFA98XX_TDM_CONFIG3_TDMCF3E_LEN 1 +#define TFA98XX_TDM_CONFIG3_TDMCF3E_MAX 1 +#define TFA98XX_TDM_CONFIG3_TDMCF3E_MSK 0x400 + +/* + * tdm_source8_enable + */ +#define TFA98XX_TDM_CONFIG3_TDMCF4E (0x1 << 11) +#define TFA98XX_TDM_CONFIG3_TDMCF4E_POS 11 +#define TFA98XX_TDM_CONFIG3_TDMCF4E_LEN 1 +#define TFA98XX_TDM_CONFIG3_TDMCF4E_MAX 1 +#define TFA98XX_TDM_CONFIG3_TDMCF4E_MSK 0x800 + +/* + * tdm_source9_enable + */ +#define TFA98XX_TDM_CONFIG3_TDMPD1E (0x1 << 12) +#define TFA98XX_TDM_CONFIG3_TDMPD1E_POS 12 +#define TFA98XX_TDM_CONFIG3_TDMPD1E_LEN 1 +#define TFA98XX_TDM_CONFIG3_TDMPD1E_MAX 1 +#define TFA98XX_TDM_CONFIG3_TDMPD1E_MSK 0x1000 + +/* + * tdm_source10_enable + */ +#define TFA98XX_TDM_CONFIG3_TDMPD2E (0x1 << 13) +#define TFA98XX_TDM_CONFIG3_TDMPD2E_POS 13 +#define TFA98XX_TDM_CONFIG3_TDMPD2E_LEN 1 +#define TFA98XX_TDM_CONFIG3_TDMPD2E_MAX 1 +#define TFA98XX_TDM_CONFIG3_TDMPD2E_MSK 0x2000 + +/* + * (0x24)-tdm_config4 + */ + +/* + * tdm_sink1_io + */ +#define TFA98XX_TDM_CONFIG4_TDMLIO (0x3 << 2) +#define TFA98XX_TDM_CONFIG4_TDMLIO_POS 2 +#define TFA98XX_TDM_CONFIG4_TDMLIO_LEN 2 +#define TFA98XX_TDM_CONFIG4_TDMLIO_MAX 3 +#define TFA98XX_TDM_CONFIG4_TDMLIO_MSK 0xc + +/* + * tdm_sink2_io + */ +#define TFA98XX_TDM_CONFIG4_TDMRIO (0x3 << 4) +#define TFA98XX_TDM_CONFIG4_TDMRIO_POS 4 +#define TFA98XX_TDM_CONFIG4_TDMRIO_LEN 2 +#define TFA98XX_TDM_CONFIG4_TDMRIO_MAX 3 +#define TFA98XX_TDM_CONFIG4_TDMRIO_MSK 0x30 + +/* + * tdm_source1_io + */ +#define TFA98XX_TDM_CONFIG4_TDMVSRIO (0x3 << 8) +#define TFA98XX_TDM_CONFIG4_TDMVSRIO_POS 8 +#define TFA98XX_TDM_CONFIG4_TDMVSRIO_LEN 2 +#define TFA98XX_TDM_CONFIG4_TDMVSRIO_MAX 3 +#define TFA98XX_TDM_CONFIG4_TDMVSRIO_MSK 0x300 + +/* + * tdm_source2_io + */ +#define TFA98XX_TDM_CONFIG4_TDMCSRIO (0x3 << 10) +#define TFA98XX_TDM_CONFIG4_TDMCSRIO_POS 10 +#define TFA98XX_TDM_CONFIG4_TDMCSRIO_LEN 2 +#define TFA98XX_TDM_CONFIG4_TDMCSRIO_MAX 3 +#define TFA98XX_TDM_CONFIG4_TDMCSRIO_MSK 0xc00 + +/* + * tdm_source3_io + */ +#define TFA98XX_TDM_CONFIG4_TDMVSLIO (0x3 << 12) +#define TFA98XX_TDM_CONFIG4_TDMVSLIO_POS 12 +#define TFA98XX_TDM_CONFIG4_TDMVSLIO_LEN 2 +#define TFA98XX_TDM_CONFIG4_TDMVSLIO_MAX 3 +#define TFA98XX_TDM_CONFIG4_TDMVSLIO_MSK 0x3000 + +/* + * tdm_source4_io + */ +#define TFA98XX_TDM_CONFIG4_TDMCSLIO (0x3 << 14) +#define TFA98XX_TDM_CONFIG4_TDMCSLIO_POS 14 +#define TFA98XX_TDM_CONFIG4_TDMCSLIO_LEN 2 +#define TFA98XX_TDM_CONFIG4_TDMCSLIO_MAX 3 +#define TFA98XX_TDM_CONFIG4_TDMCSLIO_MSK 0xc000 + +/* + * (0x25)-tdm_config5 + */ + +/* + * tdm_source5_io + */ +#define TFA98XX_TDM_CONFIG5_TDMCFRIO (0x3 << 0) +#define TFA98XX_TDM_CONFIG5_TDMCFRIO_POS 0 +#define TFA98XX_TDM_CONFIG5_TDMCFRIO_LEN 2 +#define TFA98XX_TDM_CONFIG5_TDMCFRIO_MAX 3 +#define TFA98XX_TDM_CONFIG5_TDMCFRIO_MSK 0x3 + +/* + * tdm_source6_io + */ +#define TFA98XX_TDM_CONFIG5_TDMCFLIO (0x3 << 2) +#define TFA98XX_TDM_CONFIG5_TDMCFLIO_POS 2 +#define TFA98XX_TDM_CONFIG5_TDMCFLIO_LEN 2 +#define TFA98XX_TDM_CONFIG5_TDMCFLIO_MAX 3 +#define TFA98XX_TDM_CONFIG5_TDMCFLIO_MSK 0xc + +/* + * tdm_source7_io + */ +#define TFA98XX_TDM_CONFIG5_TDMCF3IO (0x3 << 4) +#define TFA98XX_TDM_CONFIG5_TDMCF3IO_POS 4 +#define TFA98XX_TDM_CONFIG5_TDMCF3IO_LEN 2 +#define TFA98XX_TDM_CONFIG5_TDMCF3IO_MAX 3 +#define TFA98XX_TDM_CONFIG5_TDMCF3IO_MSK 0x30 + +/* + * tdm_source8_io + */ +#define TFA98XX_TDM_CONFIG5_TDMCF4IO (0x3 << 6) +#define TFA98XX_TDM_CONFIG5_TDMCF4IO_POS 6 +#define TFA98XX_TDM_CONFIG5_TDMCF4IO_LEN 2 +#define TFA98XX_TDM_CONFIG5_TDMCF4IO_MAX 3 +#define TFA98XX_TDM_CONFIG5_TDMCF4IO_MSK 0xc0 + +/* + * tdm_source9_io + */ +#define TFA98XX_TDM_CONFIG5_TDMPD1IO (0x3 << 8) +#define TFA98XX_TDM_CONFIG5_TDMPD1IO_POS 8 +#define TFA98XX_TDM_CONFIG5_TDMPD1IO_LEN 2 +#define TFA98XX_TDM_CONFIG5_TDMPD1IO_MAX 3 +#define TFA98XX_TDM_CONFIG5_TDMPD1IO_MSK 0x300 + +/* + * tdm_source10_io + */ +#define TFA98XX_TDM_CONFIG5_TDMPD2IO (0x3 << 10) +#define TFA98XX_TDM_CONFIG5_TDMPD2IO_POS 10 +#define TFA98XX_TDM_CONFIG5_TDMPD2IO_LEN 2 +#define TFA98XX_TDM_CONFIG5_TDMPD2IO_MAX 3 +#define TFA98XX_TDM_CONFIG5_TDMPD2IO_MSK 0xc00 + +/* + * (0x26)-tdm_config6 + */ + +/* + * tdm_sink1_slot + */ +#define TFA98XX_TDM_CONFIG6_TDMLS (0xf << 4) +#define TFA98XX_TDM_CONFIG6_TDMLS_POS 4 +#define TFA98XX_TDM_CONFIG6_TDMLS_LEN 4 +#define TFA98XX_TDM_CONFIG6_TDMLS_MAX 15 +#define TFA98XX_TDM_CONFIG6_TDMLS_MSK 0xf0 + +/* + * tdm_sink2_slot + */ +#define TFA98XX_TDM_CONFIG6_TDMRS (0xf << 8) +#define TFA98XX_TDM_CONFIG6_TDMRS_POS 8 +#define TFA98XX_TDM_CONFIG6_TDMRS_LEN 4 +#define TFA98XX_TDM_CONFIG6_TDMRS_MAX 15 +#define TFA98XX_TDM_CONFIG6_TDMRS_MSK 0xf00 + +/* + * (0x27)-tdm_config7 + */ + +/* + * tdm_source1_slot + */ +#define TFA98XX_TDM_CONFIG7_TDMVSRS (0xf << 0) +#define TFA98XX_TDM_CONFIG7_TDMVSRS_POS 0 +#define TFA98XX_TDM_CONFIG7_TDMVSRS_LEN 4 +#define TFA98XX_TDM_CONFIG7_TDMVSRS_MAX 15 +#define TFA98XX_TDM_CONFIG7_TDMVSRS_MSK 0xf + +/* + * tdm_source2_slot + */ +#define TFA98XX_TDM_CONFIG7_TDMCSRS (0xf << 4) +#define TFA98XX_TDM_CONFIG7_TDMCSRS_POS 4 +#define TFA98XX_TDM_CONFIG7_TDMCSRS_LEN 4 +#define TFA98XX_TDM_CONFIG7_TDMCSRS_MAX 15 +#define TFA98XX_TDM_CONFIG7_TDMCSRS_MSK 0xf0 + +/* + * tdm_source3_slot + */ +#define TFA98XX_TDM_CONFIG7_TDMVSLS (0xf << 8) +#define TFA98XX_TDM_CONFIG7_TDMVSLS_POS 8 +#define TFA98XX_TDM_CONFIG7_TDMVSLS_LEN 4 +#define TFA98XX_TDM_CONFIG7_TDMVSLS_MAX 15 +#define TFA98XX_TDM_CONFIG7_TDMVSLS_MSK 0xf00 + +/* + * tdm_source4_slot + */ +#define TFA98XX_TDM_CONFIG7_TDMCSLS (0xf << 12) +#define TFA98XX_TDM_CONFIG7_TDMCSLS_POS 12 +#define TFA98XX_TDM_CONFIG7_TDMCSLS_LEN 4 +#define TFA98XX_TDM_CONFIG7_TDMCSLS_MAX 15 +#define TFA98XX_TDM_CONFIG7_TDMCSLS_MSK 0xf000 + +/* + * (0x28)-tdm_config8 + */ + +/* + * tdm_source5_slot + */ +#define TFA98XX_TDM_CONFIG8_TDMCFRS (0xf << 0) +#define TFA98XX_TDM_CONFIG8_TDMCFRS_POS 0 +#define TFA98XX_TDM_CONFIG8_TDMCFRS_LEN 4 +#define TFA98XX_TDM_CONFIG8_TDMCFRS_MAX 15 +#define TFA98XX_TDM_CONFIG8_TDMCFRS_MSK 0xf + +/* + * tdm_source6_slot + */ +#define TFA98XX_TDM_CONFIG8_TDMCFLS (0xf << 4) +#define TFA98XX_TDM_CONFIG8_TDMCFLS_POS 4 +#define TFA98XX_TDM_CONFIG8_TDMCFLS_LEN 4 +#define TFA98XX_TDM_CONFIG8_TDMCFLS_MAX 15 +#define TFA98XX_TDM_CONFIG8_TDMCFLS_MSK 0xf0 + +/* + * tdm_source7_slot + */ +#define TFA98XX_TDM_CONFIG8_TDMCF3S (0xf << 8) +#define TFA98XX_TDM_CONFIG8_TDMCF3S_POS 8 +#define TFA98XX_TDM_CONFIG8_TDMCF3S_LEN 4 +#define TFA98XX_TDM_CONFIG8_TDMCF3S_MAX 15 +#define TFA98XX_TDM_CONFIG8_TDMCF3S_MSK 0xf00 + +/* + * tdm_source8_slot + */ +#define TFA98XX_TDM_CONFIG8_TDMCF4S (0xf << 12) +#define TFA98XX_TDM_CONFIG8_TDMCF4S_POS 12 +#define TFA98XX_TDM_CONFIG8_TDMCF4S_LEN 4 +#define TFA98XX_TDM_CONFIG8_TDMCF4S_MAX 15 +#define TFA98XX_TDM_CONFIG8_TDMCF4S_MSK 0xf000 + +/* + * (0x29)-tdm_config9 + */ + +/* + * tdm_source9_slot + */ +#define TFA98XX_TDM_CONFIG9_TDMPD1S (0xf << 0) +#define TFA98XX_TDM_CONFIG9_TDMPD1S_POS 0 +#define TFA98XX_TDM_CONFIG9_TDMPD1S_LEN 4 +#define TFA98XX_TDM_CONFIG9_TDMPD1S_MAX 15 +#define TFA98XX_TDM_CONFIG9_TDMPD1S_MSK 0xf + +/* + * tdm_source10_slot + */ +#define TFA98XX_TDM_CONFIG9_TDMPD2S (0xf << 4) +#define TFA98XX_TDM_CONFIG9_TDMPD2S_POS 4 +#define TFA98XX_TDM_CONFIG9_TDMPD2S_LEN 4 +#define TFA98XX_TDM_CONFIG9_TDMPD2S_MAX 15 +#define TFA98XX_TDM_CONFIG9_TDMPD2S_MSK 0xf0 + +/* + * (0x31)-pdm_config0 + */ + +/* + * pdm_mode + */ +#define TFA98XX_PDM_CONFIG0_PDMSM (0x1 << 0) +#define TFA98XX_PDM_CONFIG0_PDMSM_POS 0 +#define TFA98XX_PDM_CONFIG0_PDMSM_LEN 1 +#define TFA98XX_PDM_CONFIG0_PDMSM_MAX 1 +#define TFA98XX_PDM_CONFIG0_PDMSM_MSK 0x1 + +/* + * pdm_side_tone_sel + */ +#define TFA98XX_PDM_CONFIG0_PDMSTSEL (0x3 << 1) +#define TFA98XX_PDM_CONFIG0_PDMSTSEL_POS 1 +#define TFA98XX_PDM_CONFIG0_PDMSTSEL_LEN 2 +#define TFA98XX_PDM_CONFIG0_PDMSTSEL_MAX 3 +#define TFA98XX_PDM_CONFIG0_PDMSTSEL_MSK 0x6 + +/* + * pdm_left_sel + */ +#define TFA98XX_PDM_CONFIG0_PDMLSEL (0x1 << 3) +#define TFA98XX_PDM_CONFIG0_PDMLSEL_POS 3 +#define TFA98XX_PDM_CONFIG0_PDMLSEL_LEN 1 +#define TFA98XX_PDM_CONFIG0_PDMLSEL_MAX 1 +#define TFA98XX_PDM_CONFIG0_PDMLSEL_MSK 0x8 + +/* + * pdm_right_sel + */ +#define TFA98XX_PDM_CONFIG0_PDMRSEL (0x1 << 4) +#define TFA98XX_PDM_CONFIG0_PDMRSEL_POS 4 +#define TFA98XX_PDM_CONFIG0_PDMRSEL_LEN 1 +#define TFA98XX_PDM_CONFIG0_PDMRSEL_MAX 1 +#define TFA98XX_PDM_CONFIG0_PDMRSEL_MSK 0x10 + +/* + * enbl_micvdd + */ +#define TFA98XX_PDM_CONFIG0_MICVDDE (0x1 << 5) +#define TFA98XX_PDM_CONFIG0_MICVDDE_POS 5 +#define TFA98XX_PDM_CONFIG0_MICVDDE_LEN 1 +#define TFA98XX_PDM_CONFIG0_MICVDDE_MAX 1 +#define TFA98XX_PDM_CONFIG0_MICVDDE_MSK 0x20 + +/* + * (0x32)-pdm_config1 + */ + +/* + * pdm_nbck + */ +#define TFA98XX_PDM_CONFIG1_PDMCLRAT (0x3 << 0) +#define TFA98XX_PDM_CONFIG1_PDMCLRAT_POS 0 +#define TFA98XX_PDM_CONFIG1_PDMCLRAT_LEN 2 +#define TFA98XX_PDM_CONFIG1_PDMCLRAT_MAX 3 +#define TFA98XX_PDM_CONFIG1_PDMCLRAT_MSK 0x3 + +/* + * pdm_gain + */ +#define TFA98XX_PDM_CONFIG1_PDMGAIN (0xf << 2) +#define TFA98XX_PDM_CONFIG1_PDMGAIN_POS 2 +#define TFA98XX_PDM_CONFIG1_PDMGAIN_LEN 4 +#define TFA98XX_PDM_CONFIG1_PDMGAIN_MAX 15 +#define TFA98XX_PDM_CONFIG1_PDMGAIN_MSK 0x3c + +/* + * sel_pdm_out_data + */ +#define TFA98XX_PDM_CONFIG1_PDMOSEL (0xf << 6) +#define TFA98XX_PDM_CONFIG1_PDMOSEL_POS 6 +#define TFA98XX_PDM_CONFIG1_PDMOSEL_LEN 4 +#define TFA98XX_PDM_CONFIG1_PDMOSEL_MAX 15 +#define TFA98XX_PDM_CONFIG1_PDMOSEL_MSK 0x3c0 + +/* + * sel_cf_haptic_data + */ +#define TFA98XX_PDM_CONFIG1_SELCFHAPD (0x1 << 10) +#define TFA98XX_PDM_CONFIG1_SELCFHAPD_POS 10 +#define TFA98XX_PDM_CONFIG1_SELCFHAPD_LEN 1 +#define TFA98XX_PDM_CONFIG1_SELCFHAPD_MAX 1 +#define TFA98XX_PDM_CONFIG1_SELCFHAPD_MSK 0x400 + +/* + * (0x33)-haptic_driver_config + */ + +/* + * haptic_duration + */ +#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPTIME (0xff << 0) +#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPTIME_POS 0 +#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPTIME_LEN 8 +#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPTIME_MAX 255 +#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPTIME_MSK 0xff + +/* + * haptic_data + */ +#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPLEVEL (0xff << 8) +#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPLEVEL_POS 8 +#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPLEVEL_LEN 8 +#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPLEVEL_MAX 255 +#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPLEVEL_MSK 0xff00 + +/* + * (0x34)-gpio_datain_reg + */ + +/* + * gpio_datain + */ +#define TFA98XX_GPIO_DATAIN_REG_GPIODIN (0xf << 0) +#define TFA98XX_GPIO_DATAIN_REG_GPIODIN_POS 0 +#define TFA98XX_GPIO_DATAIN_REG_GPIODIN_LEN 4 +#define TFA98XX_GPIO_DATAIN_REG_GPIODIN_MAX 15 +#define TFA98XX_GPIO_DATAIN_REG_GPIODIN_MSK 0xf + +/* + * (0x35)-gpio_config + */ + +/* + * gpio_ctrl + */ +#define TFA98XX_GPIO_CONFIG_GPIOCTRL (0x1 << 0) +#define TFA98XX_GPIO_CONFIG_GPIOCTRL_POS 0 +#define TFA98XX_GPIO_CONFIG_GPIOCTRL_LEN 1 +#define TFA98XX_GPIO_CONFIG_GPIOCTRL_MAX 1 +#define TFA98XX_GPIO_CONFIG_GPIOCTRL_MSK 0x1 + +/* + * gpio_dir + */ +#define TFA98XX_GPIO_CONFIG_GPIOCONF (0xf << 1) +#define TFA98XX_GPIO_CONFIG_GPIOCONF_POS 1 +#define TFA98XX_GPIO_CONFIG_GPIOCONF_LEN 4 +#define TFA98XX_GPIO_CONFIG_GPIOCONF_MAX 15 +#define TFA98XX_GPIO_CONFIG_GPIOCONF_MSK 0x1e + +/* + * gpio_dataout + */ +#define TFA98XX_GPIO_CONFIG_GPIODOUT (0xf << 5) +#define TFA98XX_GPIO_CONFIG_GPIODOUT_POS 5 +#define TFA98XX_GPIO_CONFIG_GPIODOUT_LEN 4 +#define TFA98XX_GPIO_CONFIG_GPIODOUT_MAX 15 +#define TFA98XX_GPIO_CONFIG_GPIODOUT_MSK 0x1e0 + +/* + * (0x40)-interrupt_out_reg1 + */ + +/* + * int_out_flag_por + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTVDDS (0x1 << 0) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTVDDS_POS 0 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTVDDS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTVDDS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTVDDS_MSK 0x1 + +/* + * int_out_flag_pll_lock + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTPLLS (0x1 << 1) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTPLLS_POS 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTPLLS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTPLLS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTPLLS_MSK 0x2 + +/* + * int_out_flag_otpok + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTOTDS (0x1 << 2) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTOTDS_POS 2 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTOTDS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTOTDS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTOTDS_MSK 0x4 + +/* + * int_out_flag_ovpok + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTOVDS (0x1 << 3) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTOVDS_POS 3 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTOVDS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTOVDS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTOVDS_MSK 0x8 + +/* + * int_out_flag_uvpok + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTUVDS (0x1 << 4) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTUVDS_POS 4 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTUVDS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTUVDS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTUVDS_MSK 0x10 + +/* + * int_out_flag_clocks_stable + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTCLKS (0x1 << 5) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTCLKS_POS 5 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTCLKS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTCLKS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTCLKS_MSK 0x20 + +/* + * int_out_flag_mtp_busy + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTMTPB (0x1 << 6) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTMTPB_POS 6 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTMTPB_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTMTPB_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTMTPB_MSK 0x40 + +/* + * int_out_flag_lost_clk + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTNOCLK (0x1 << 7) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTNOCLK_POS 7 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTNOCLK_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTNOCLK_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTNOCLK_MSK 0x80 + +/* + * int_out_flag_cf_speakererror + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTSPKS (0x1 << 8) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTSPKS_POS 8 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTSPKS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTSPKS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTSPKS_MSK 0x100 + +/* + * int_out_flag_cold_started + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTACS (0x1 << 9) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTACS_POS 9 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTACS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTACS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTACS_MSK 0x200 + +/* + * int_out_flag_engage + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTSWS (0x1 << 10) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTSWS_POS 10 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTSWS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTSWS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTSWS_MSK 0x400 + +/* + * int_out_flag_watchdog_reset + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTWDS (0x1 << 11) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTWDS_POS 11 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTWDS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTWDS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTWDS_MSK 0x800 + +/* + * int_out_flag_enbl_amp + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTAMPS (0x1 << 12) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTAMPS_POS 12 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTAMPS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTAMPS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTAMPS_MSK 0x1000 + +/* + * int_out_flag_enbl_ref + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTAREFS (0x1 << 13) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTAREFS_POS 13 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTAREFS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTAREFS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTAREFS_MSK 0x2000 + +/* + * int_out_flag_adc10_ready + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTADCCR (0x1 << 14) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTADCCR_POS 14 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTADCCR_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTADCCR_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTADCCR_MSK 0x4000 + +/* + * int_out_flag_bod_vddd_nok + */ +#define TFA98XX_INTERRUPT_OUT_REG1_ISTBODNOK (0x1 << 15) +#define TFA98XX_INTERRUPT_OUT_REG1_ISTBODNOK_POS 15 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTBODNOK_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTBODNOK_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_ISTBODNOK_MSK 0x8000 + +/* + * (0x41)-interrupt_out_reg2 + */ + +/* + * int_out_flag_bst_bstcur + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTCU (0x1 << 0) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTCU_POS 0 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTCU_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTCU_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTCU_MSK 0x1 + +/* + * int_out_flag_bst_hiz + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTHI (0x1 << 1) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTHI_POS 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTHI_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTHI_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTHI_MSK 0x2 + +/* + * int_out_flag_bst_ocpok + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTOC (0x1 << 2) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTOC_POS 2 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTOC_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTOC_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTOC_MSK 0x4 + +/* + * int_out_flag_bst_peakcur + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTPKCUR (0x1 << 3) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTPKCUR_POS 3 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTPKCUR_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTPKCUR_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTPKCUR_MSK 0x8 + +/* + * int_out_flag_bst_voutcomp + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTVC (0x1 << 4) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTVC_POS 4 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTVC_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTVC_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTVC_MSK 0x10 + +/* + * int_out_flag_bst_voutcomp86 + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST86 (0x1 << 5) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST86_POS 5 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST86_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST86_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST86_MSK 0x20 + +/* + * int_out_flag_bst_voutcomp93 + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST93 (0x1 << 6) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST93_POS 6 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST93_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST93_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST93_MSK 0x40 + +/* + * int_out_flag_rcvldop_ready + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTRCVLD (0x1 << 7) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTRCVLD_POS 7 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTRCVLD_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTRCVLD_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTRCVLD_MSK 0x80 + +/* + * int_out_flag_ocp_alarm_left + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPL (0x1 << 8) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPL_POS 8 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPL_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPL_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPL_MSK 0x100 + +/* + * int_out_flag_ocp_alarm_right + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPR (0x1 << 9) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPR_POS 9 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPR_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPR_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPR_MSK 0x200 + +/* + * int_out_flag_man_wait_src_settings + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSRC (0x1 << 10) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSRC_POS 10 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSRC_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSRC_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSRC_MSK 0x400 + +/* + * int_out_flag_man_wait_cf_config + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWCFC (0x1 << 11) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWCFC_POS 11 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWCFC_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWCFC_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWCFC_MSK 0x800 + +/* + * int_out_flag_man_start_mute_audio + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSMU (0x1 << 12) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSMU_POS 12 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSMU_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSMU_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSMU_MSK 0x1000 + +/* + * int_out_flag_cfma_err + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMER (0x1 << 13) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMER_POS 13 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMER_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMER_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMER_MSK 0x2000 + +/* + * int_out_flag_cfma_ack + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMAC (0x1 << 14) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMAC_POS 14 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMAC_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMAC_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMAC_MSK 0x4000 + +/* + * int_out_flag_clk_out_of_range + */ +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCLKOOR (0x1 << 15) +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCLKOOR_POS 15 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCLKOOR_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCLKOOR_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG2_ISTCLKOOR_MSK 0x8000 + +/* + * (0x42)-interrupt_out_reg3 + */ + +/* + * int_out_flag_tdm_error + */ +#define TFA98XX_INTERRUPT_OUT_REG3_ISTTDMER (0x1 << 0) +#define TFA98XX_INTERRUPT_OUT_REG3_ISTTDMER_POS 0 +#define TFA98XX_INTERRUPT_OUT_REG3_ISTTDMER_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG3_ISTTDMER_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG3_ISTTDMER_MSK 0x1 + +/* + * int_out_flag_clip_left + */ +#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPL (0x1 << 1) +#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPL_POS 1 +#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPL_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPL_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPL_MSK 0x2 + +/* + * int_out_flag_clip_right + */ +#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPR (0x1 << 2) +#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPR_POS 2 +#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPR_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPR_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPR_MSK 0x4 + +/* + * int_out_flag_mic_ocpok + */ +#define TFA98XX_INTERRUPT_OUT_REG3_ISTOCPM (0x1 << 3) +#define TFA98XX_INTERRUPT_OUT_REG3_ISTOCPM_POS 3 +#define TFA98XX_INTERRUPT_OUT_REG3_ISTOCPM_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG3_ISTOCPM_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG3_ISTOCPM_MSK 0x8 + +/* + * (0x44)-interrupt_in_reg1 + */ + +/* + * int_in_flag_por + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLVDDS (0x1 << 0) +#define TFA98XX_INTERRUPT_IN_REG1_ICLVDDS_POS 0 +#define TFA98XX_INTERRUPT_IN_REG1_ICLVDDS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLVDDS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLVDDS_MSK 0x1 + +/* + * int_in_flag_pll_lock + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLPLLS (0x1 << 1) +#define TFA98XX_INTERRUPT_IN_REG1_ICLPLLS_POS 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLPLLS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLPLLS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLPLLS_MSK 0x2 + +/* + * int_in_flag_otpok + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLOTDS (0x1 << 2) +#define TFA98XX_INTERRUPT_IN_REG1_ICLOTDS_POS 2 +#define TFA98XX_INTERRUPT_IN_REG1_ICLOTDS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLOTDS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLOTDS_MSK 0x4 + +/* + * int_in_flag_ovpok + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLOVDS (0x1 << 3) +#define TFA98XX_INTERRUPT_IN_REG1_ICLOVDS_POS 3 +#define TFA98XX_INTERRUPT_IN_REG1_ICLOVDS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLOVDS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLOVDS_MSK 0x8 + +/* + * int_in_flag_uvpok + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLUVDS (0x1 << 4) +#define TFA98XX_INTERRUPT_IN_REG1_ICLUVDS_POS 4 +#define TFA98XX_INTERRUPT_IN_REG1_ICLUVDS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLUVDS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLUVDS_MSK 0x10 + +/* + * int_in_flag_clocks_stable + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLCLKS (0x1 << 5) +#define TFA98XX_INTERRUPT_IN_REG1_ICLCLKS_POS 5 +#define TFA98XX_INTERRUPT_IN_REG1_ICLCLKS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLCLKS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLCLKS_MSK 0x20 + +/* + * int_in_flag_mtp_busy + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLMTPB (0x1 << 6) +#define TFA98XX_INTERRUPT_IN_REG1_ICLMTPB_POS 6 +#define TFA98XX_INTERRUPT_IN_REG1_ICLMTPB_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLMTPB_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLMTPB_MSK 0x40 + +/* + * int_in_flag_lost_clk + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLNOCLK (0x1 << 7) +#define TFA98XX_INTERRUPT_IN_REG1_ICLNOCLK_POS 7 +#define TFA98XX_INTERRUPT_IN_REG1_ICLNOCLK_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLNOCLK_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLNOCLK_MSK 0x80 + +/* + * int_in_flag_cf_speakererror + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLSPKS (0x1 << 8) +#define TFA98XX_INTERRUPT_IN_REG1_ICLSPKS_POS 8 +#define TFA98XX_INTERRUPT_IN_REG1_ICLSPKS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLSPKS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLSPKS_MSK 0x100 + +/* + * int_in_flag_cold_started + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLACS (0x1 << 9) +#define TFA98XX_INTERRUPT_IN_REG1_ICLACS_POS 9 +#define TFA98XX_INTERRUPT_IN_REG1_ICLACS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLACS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLACS_MSK 0x200 + +/* + * int_in_flag_engage + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLSWS (0x1 << 10) +#define TFA98XX_INTERRUPT_IN_REG1_ICLSWS_POS 10 +#define TFA98XX_INTERRUPT_IN_REG1_ICLSWS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLSWS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLSWS_MSK 0x400 + +/* + * int_in_flag_watchdog_reset + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLWDS (0x1 << 11) +#define TFA98XX_INTERRUPT_IN_REG1_ICLWDS_POS 11 +#define TFA98XX_INTERRUPT_IN_REG1_ICLWDS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLWDS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLWDS_MSK 0x800 + +/* + * int_in_flag_enbl_amp + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLAMPS (0x1 << 12) +#define TFA98XX_INTERRUPT_IN_REG1_ICLAMPS_POS 12 +#define TFA98XX_INTERRUPT_IN_REG1_ICLAMPS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLAMPS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLAMPS_MSK 0x1000 + +/* + * int_in_flag_enbl_ref + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLAREFS (0x1 << 13) +#define TFA98XX_INTERRUPT_IN_REG1_ICLAREFS_POS 13 +#define TFA98XX_INTERRUPT_IN_REG1_ICLAREFS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLAREFS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLAREFS_MSK 0x2000 + +/* + * int_in_flag_adc10_ready + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLADCCR (0x1 << 14) +#define TFA98XX_INTERRUPT_IN_REG1_ICLADCCR_POS 14 +#define TFA98XX_INTERRUPT_IN_REG1_ICLADCCR_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLADCCR_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLADCCR_MSK 0x4000 + +/* + * int_in_flag_bod_vddd_nok + */ +#define TFA98XX_INTERRUPT_IN_REG1_ICLBODNOK (0x1 << 15) +#define TFA98XX_INTERRUPT_IN_REG1_ICLBODNOK_POS 15 +#define TFA98XX_INTERRUPT_IN_REG1_ICLBODNOK_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLBODNOK_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_ICLBODNOK_MSK 0x8000 + +/* + * (0x45)-interrupt_in_reg2 + */ + +/* + * int_in_flag_bst_bstcur + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTCU (0x1 << 0) +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTCU_POS 0 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTCU_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTCU_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTCU_MSK 0x1 + +/* + * int_in_flag_bst_hiz + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTHI (0x1 << 1) +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTHI_POS 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTHI_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTHI_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTHI_MSK 0x2 + +/* + * int_in_flag_bst_ocpok + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTOC (0x1 << 2) +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTOC_POS 2 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTOC_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTOC_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTOC_MSK 0x4 + +/* + * int_in_flag_bst_peakcur + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTPC (0x1 << 3) +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTPC_POS 3 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTPC_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTPC_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTPC_MSK 0x8 + +/* + * int_in_flag_bst_voutcomp + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTVC (0x1 << 4) +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTVC_POS 4 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTVC_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTVC_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTVC_MSK 0x10 + +/* + * int_in_flag_bst_voutcomp86 + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLBST86 (0x1 << 5) +#define TFA98XX_INTERRUPT_IN_REG2_ICLBST86_POS 5 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBST86_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBST86_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBST86_MSK 0x20 + +/* + * int_in_flag_bst_voutcomp93 + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLBST93 (0x1 << 6) +#define TFA98XX_INTERRUPT_IN_REG2_ICLBST93_POS 6 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBST93_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBST93_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLBST93_MSK 0x40 + +/* + * int_in_flag_rcvldop_ready + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLRCVLD (0x1 << 7) +#define TFA98XX_INTERRUPT_IN_REG2_ICLRCVLD_POS 7 +#define TFA98XX_INTERRUPT_IN_REG2_ICLRCVLD_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLRCVLD_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLRCVLD_MSK 0x80 + +/* + * int_in_flag_ocp_alarm_left + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPL (0x1 << 8) +#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPL_POS 8 +#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPL_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPL_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPL_MSK 0x100 + +/* + * int_in_flag_ocp_alarm_right + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPR (0x1 << 9) +#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPR_POS 9 +#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPR_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPR_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPR_MSK 0x200 + +/* + * int_in_flag_man_wait_src_settings + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSRC (0x1 << 10) +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSRC_POS 10 +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSRC_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSRC_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSRC_MSK 0x400 + +/* + * int_in_flag_man_wait_cf_config + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWCFC (0x1 << 11) +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWCFC_POS 11 +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWCFC_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWCFC_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWCFC_MSK 0x800 + +/* + * int_in_flag_man_start_mute_audio + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSMU (0x1 << 12) +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSMU_POS 12 +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSMU_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSMU_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSMU_MSK 0x1000 + +/* + * int_in_flag_cfma_err + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMER (0x1 << 13) +#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMER_POS 13 +#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMER_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMER_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMER_MSK 0x2000 + +/* + * int_in_flag_cfma_ack + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMAC (0x1 << 14) +#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMAC_POS 14 +#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMAC_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMAC_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMAC_MSK 0x4000 + +/* + * int_in_flag_clk_out_of_range + */ +#define TFA98XX_INTERRUPT_IN_REG2_ICLCLKOOR (0x1 << 15) +#define TFA98XX_INTERRUPT_IN_REG2_ICLCLKOOR_POS 15 +#define TFA98XX_INTERRUPT_IN_REG2_ICLCLKOOR_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLCLKOOR_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG2_ICLCLKOOR_MSK 0x8000 + +/* + * (0x46)-interrupt_in_reg3 + */ + +/* + * int_in_flag_tdm_error + */ +#define TFA98XX_INTERRUPT_IN_REG3_ICLTDMER (0x1 << 0) +#define TFA98XX_INTERRUPT_IN_REG3_ICLTDMER_POS 0 +#define TFA98XX_INTERRUPT_IN_REG3_ICLTDMER_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG3_ICLTDMER_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG3_ICLTDMER_MSK 0x1 + +/* + * int_in_flag_clip_left + */ +#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPL (0x1 << 1) +#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPL_POS 1 +#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPL_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPL_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPL_MSK 0x2 + +/* + * int_in_flag_clip_right + */ +#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPR (0x1 << 2) +#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPR_POS 2 +#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPR_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPR_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPR_MSK 0x4 + +/* + * int_in_flag_mic_ocpok + */ +#define TFA98XX_INTERRUPT_IN_REG3_ICLOCPM (0x1 << 3) +#define TFA98XX_INTERRUPT_IN_REG3_ICLOCPM_POS 3 +#define TFA98XX_INTERRUPT_IN_REG3_ICLOCPM_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG3_ICLOCPM_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG3_ICLOCPM_MSK 0x8 + +/* + * (0x48)-interrupt_enable_reg1 + */ + +/* + * int_enable_flag_por + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEVDDS (0x1 << 0) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEVDDS_POS 0 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEVDDS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEVDDS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEVDDS_MSK 0x1 + +/* + * int_enable_flag_pll_lock + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEPLLS (0x1 << 1) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEPLLS_POS 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEPLLS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEPLLS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEPLLS_MSK 0x2 + +/* + * int_enable_flag_otpok + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOTDS (0x1 << 2) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOTDS_POS 2 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOTDS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOTDS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOTDS_MSK 0x4 + +/* + * int_enable_flag_ovpok + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOVDS (0x1 << 3) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOVDS_POS 3 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOVDS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOVDS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOVDS_MSK 0x8 + +/* + * int_enable_flag_uvpok + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEUVDS (0x1 << 4) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEUVDS_POS 4 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEUVDS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEUVDS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEUVDS_MSK 0x10 + +/* + * int_enable_flag_clocks_stable + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IECLKS (0x1 << 5) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IECLKS_POS 5 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IECLKS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IECLKS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IECLKS_MSK 0x20 + +/* + * int_enable_flag_mtp_busy + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEMTPB (0x1 << 6) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEMTPB_POS 6 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEMTPB_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEMTPB_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEMTPB_MSK 0x40 + +/* + * int_enable_flag_lost_clk + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IENOCLK (0x1 << 7) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IENOCLK_POS 7 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IENOCLK_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IENOCLK_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IENOCLK_MSK 0x80 + +/* + * int_enable_flag_cf_speakererror + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IESPKS (0x1 << 8) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IESPKS_POS 8 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IESPKS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IESPKS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IESPKS_MSK 0x100 + +/* + * int_enable_flag_cold_started + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEACS (0x1 << 9) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEACS_POS 9 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEACS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEACS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEACS_MSK 0x200 + +/* + * int_enable_flag_engage + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IESWS (0x1 << 10) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IESWS_POS 10 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IESWS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IESWS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IESWS_MSK 0x400 + +/* + * int_enable_flag_watchdog_reset + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEWDS (0x1 << 11) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEWDS_POS 11 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEWDS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEWDS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEWDS_MSK 0x800 + +/* + * int_enable_flag_enbl_amp + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAMPS (0x1 << 12) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAMPS_POS 12 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAMPS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAMPS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAMPS_MSK 0x1000 + +/* + * int_enable_flag_enbl_ref + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAREFS (0x1 << 13) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAREFS_POS 13 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAREFS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAREFS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAREFS_MSK 0x2000 + +/* + * int_enable_flag_adc10_ready + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEADCCR (0x1 << 14) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEADCCR_POS 14 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEADCCR_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEADCCR_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEADCCR_MSK 0x4000 + +/* + * int_enable_flag_bod_vddd_nok + */ +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEBODNOK (0x1 << 15) +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEBODNOK_POS 15 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEBODNOK_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEBODNOK_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_IEBODNOK_MSK 0x8000 + +/* + * (0x49)-interrupt_enable_reg2 + */ + +/* + * int_enable_flag_bst_bstcur + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTCU (0x1 << 0) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTCU_POS 0 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTCU_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTCU_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTCU_MSK 0x1 + +/* + * int_enable_flag_bst_hiz + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTHI (0x1 << 1) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTHI_POS 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTHI_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTHI_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTHI_MSK 0x2 + +/* + * int_enable_flag_bst_ocpok + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTOC (0x1 << 2) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTOC_POS 2 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTOC_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTOC_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTOC_MSK 0x4 + +/* + * int_enable_flag_bst_peakcur + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTPC (0x1 << 3) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTPC_POS 3 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTPC_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTPC_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTPC_MSK 0x8 + +/* + * int_enable_flag_bst_voutcomp + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTVC (0x1 << 4) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTVC_POS 4 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTVC_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTVC_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTVC_MSK 0x10 + +/* + * int_enable_flag_bst_voutcomp86 + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST86 (0x1 << 5) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST86_POS 5 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST86_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST86_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST86_MSK 0x20 + +/* + * int_enable_flag_bst_voutcomp93 + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST93 (0x1 << 6) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST93_POS 6 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST93_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST93_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST93_MSK 0x40 + +/* + * int_enable_flag_rcvldop_ready + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IERCVLD (0x1 << 7) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IERCVLD_POS 7 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IERCVLD_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IERCVLD_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IERCVLD_MSK 0x80 + +/* + * int_enable_flag_ocp_alarm_left + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPL (0x1 << 8) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPL_POS 8 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPL_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPL_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPL_MSK 0x100 + +/* + * int_enable_flag_ocp_alarm_right + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPR (0x1 << 9) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPR_POS 9 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPR_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPR_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPR_MSK 0x200 + +/* + * int_enable_flag_man_wait_src_settings + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSRC (0x1 << 10) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSRC_POS 10 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSRC_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSRC_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSRC_MSK 0x400 + +/* + * int_enable_flag_man_wait_cf_config + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWCFC (0x1 << 11) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWCFC_POS 11 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWCFC_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWCFC_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWCFC_MSK 0x800 + +/* + * int_enable_flag_man_start_mute_audio + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSMU (0x1 << 12) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSMU_POS 12 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSMU_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSMU_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSMU_MSK 0x1000 + +/* + * int_enable_flag_cfma_err + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMER (0x1 << 13) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMER_POS 13 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMER_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMER_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMER_MSK 0x2000 + +/* + * int_enable_flag_cfma_ack + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMAC (0x1 << 14) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMAC_POS 14 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMAC_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMAC_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMAC_MSK 0x4000 + +/* + * int_enable_flag_clk_out_of_range + */ +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECLKOOR (0x1 << 15) +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECLKOOR_POS 15 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECLKOOR_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECLKOOR_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG2_IECLKOOR_MSK 0x8000 + +/* + * (0x4a)-interrupt_enable_reg3 + */ + +/* + * int_enable_flag_tdm_error + */ +#define TFA98XX_INTERRUPT_ENABLE_REG3_IETDMER (0x1 << 0) +#define TFA98XX_INTERRUPT_ENABLE_REG3_IETDMER_POS 0 +#define TFA98XX_INTERRUPT_ENABLE_REG3_IETDMER_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG3_IETDMER_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG3_IETDMER_MSK 0x1 + +/* + * int_enable_flag_clip_left + */ +#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPL (0x1 << 1) +#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPL_POS 1 +#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPL_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPL_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPL_MSK 0x2 + +/* + * int_enable_flag_clip_right + */ +#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPR (0x1 << 2) +#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPR_POS 2 +#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPR_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPR_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPR_MSK 0x4 + +/* + * int_enable_flag_mic_ocpok + */ +#define TFA98XX_INTERRUPT_ENABLE_REG3_IEOCPM1 (0x1 << 3) +#define TFA98XX_INTERRUPT_ENABLE_REG3_IEOCPM1_POS 3 +#define TFA98XX_INTERRUPT_ENABLE_REG3_IEOCPM1_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG3_IEOCPM1_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG3_IEOCPM1_MSK 0x8 + +/* + * (0x4c)-status_polarity_reg1 + */ + +/* + * int_polarity_flag_por + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOVDDS (0x1 << 0) +#define TFA98XX_STATUS_POLARITY_REG1_IPOVDDS_POS 0 +#define TFA98XX_STATUS_POLARITY_REG1_IPOVDDS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOVDDS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOVDDS_MSK 0x1 + +/* + * int_polarity_flag_pll_lock + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOPLLS (0x1 << 1) +#define TFA98XX_STATUS_POLARITY_REG1_IPOPLLS_POS 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOPLLS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOPLLS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOPLLS_MSK 0x2 + +/* + * int_polarity_flag_otpok + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOOTDS (0x1 << 2) +#define TFA98XX_STATUS_POLARITY_REG1_IPOOTDS_POS 2 +#define TFA98XX_STATUS_POLARITY_REG1_IPOOTDS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOOTDS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOOTDS_MSK 0x4 + +/* + * int_polarity_flag_ovpok + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOOVDS (0x1 << 3) +#define TFA98XX_STATUS_POLARITY_REG1_IPOOVDS_POS 3 +#define TFA98XX_STATUS_POLARITY_REG1_IPOOVDS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOOVDS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOOVDS_MSK 0x8 + +/* + * int_polarity_flag_uvpok + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOUVDS (0x1 << 4) +#define TFA98XX_STATUS_POLARITY_REG1_IPOUVDS_POS 4 +#define TFA98XX_STATUS_POLARITY_REG1_IPOUVDS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOUVDS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOUVDS_MSK 0x10 + +/* + * int_polarity_flag_clocks_stable + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOCLKS (0x1 << 5) +#define TFA98XX_STATUS_POLARITY_REG1_IPOCLKS_POS 5 +#define TFA98XX_STATUS_POLARITY_REG1_IPOCLKS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOCLKS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOCLKS_MSK 0x20 + +/* + * int_polarity_flag_mtp_busy + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOMTPB (0x1 << 6) +#define TFA98XX_STATUS_POLARITY_REG1_IPOMTPB_POS 6 +#define TFA98XX_STATUS_POLARITY_REG1_IPOMTPB_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOMTPB_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOMTPB_MSK 0x40 + +/* + * int_polarity_flag_lost_clk + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPONOCLK (0x1 << 7) +#define TFA98XX_STATUS_POLARITY_REG1_IPONOCLK_POS 7 +#define TFA98XX_STATUS_POLARITY_REG1_IPONOCLK_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPONOCLK_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPONOCLK_MSK 0x80 + +/* + * int_polarity_flag_cf_speakererror + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOSPKS (0x1 << 8) +#define TFA98XX_STATUS_POLARITY_REG1_IPOSPKS_POS 8 +#define TFA98XX_STATUS_POLARITY_REG1_IPOSPKS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOSPKS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOSPKS_MSK 0x100 + +/* + * int_polarity_flag_cold_started + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOACS (0x1 << 9) +#define TFA98XX_STATUS_POLARITY_REG1_IPOACS_POS 9 +#define TFA98XX_STATUS_POLARITY_REG1_IPOACS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOACS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOACS_MSK 0x200 + +/* + * int_polarity_flag_engage + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOSWS (0x1 << 10) +#define TFA98XX_STATUS_POLARITY_REG1_IPOSWS_POS 10 +#define TFA98XX_STATUS_POLARITY_REG1_IPOSWS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOSWS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOSWS_MSK 0x400 + +/* + * int_polarity_flag_watchdog_reset + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOWDS (0x1 << 11) +#define TFA98XX_STATUS_POLARITY_REG1_IPOWDS_POS 11 +#define TFA98XX_STATUS_POLARITY_REG1_IPOWDS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOWDS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOWDS_MSK 0x800 + +/* + * int_polarity_flag_enbl_amp + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOAMPS (0x1 << 12) +#define TFA98XX_STATUS_POLARITY_REG1_IPOAMPS_POS 12 +#define TFA98XX_STATUS_POLARITY_REG1_IPOAMPS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOAMPS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOAMPS_MSK 0x1000 + +/* + * int_polarity_flag_enbl_ref + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOAREFS (0x1 << 13) +#define TFA98XX_STATUS_POLARITY_REG1_IPOAREFS_POS 13 +#define TFA98XX_STATUS_POLARITY_REG1_IPOAREFS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOAREFS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOAREFS_MSK 0x2000 + +/* + * int_polarity_flag_adc10_ready + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOADCCR (0x1 << 14) +#define TFA98XX_STATUS_POLARITY_REG1_IPOADCCR_POS 14 +#define TFA98XX_STATUS_POLARITY_REG1_IPOADCCR_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOADCCR_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOADCCR_MSK 0x4000 + +/* + * int_polarity_flag_bod_vddd_nok + */ +#define TFA98XX_STATUS_POLARITY_REG1_IPOBODNOK (0x1 << 15) +#define TFA98XX_STATUS_POLARITY_REG1_IPOBODNOK_POS 15 +#define TFA98XX_STATUS_POLARITY_REG1_IPOBODNOK_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOBODNOK_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_IPOBODNOK_MSK 0x8000 + +/* + * (0x4d)-status_polarity_reg2 + */ + +/* + * int_polarity_flag_bst_bstcur + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTCU (0x1 << 0) +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTCU_POS 0 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTCU_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTCU_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTCU_MSK 0x1 + +/* + * int_polarity_flag_bst_hiz + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTHI (0x1 << 1) +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTHI_POS 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTHI_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTHI_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTHI_MSK 0x2 + +/* + * int_polarity_flag_bst_ocpok + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTOC (0x1 << 2) +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTOC_POS 2 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTOC_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTOC_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTOC_MSK 0x4 + +/* + * int_polarity_flag_bst_peakcur + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTPC (0x1 << 3) +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTPC_POS 3 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTPC_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTPC_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTPC_MSK 0x8 + +/* + * int_polarity_flag_bst_voutcomp + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTVC (0x1 << 4) +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTVC_POS 4 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTVC_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTVC_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTVC_MSK 0x10 + +/* + * int_polarity_flag_bst_voutcomp86 + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOBST86 (0x1 << 5) +#define TFA98XX_STATUS_POLARITY_REG2_IPOBST86_POS 5 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBST86_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBST86_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBST86_MSK 0x20 + +/* + * int_polarity_flag_bst_voutcomp93 + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOBST93 (0x1 << 6) +#define TFA98XX_STATUS_POLARITY_REG2_IPOBST93_POS 6 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBST93_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBST93_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOBST93_MSK 0x40 + +/* + * int_polarity_flag_rcvldop_ready + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPORCVLD (0x1 << 7) +#define TFA98XX_STATUS_POLARITY_REG2_IPORCVLD_POS 7 +#define TFA98XX_STATUS_POLARITY_REG2_IPORCVLD_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPORCVLD_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPORCVLD_MSK 0x80 + +/* + * int_polarity_flag_ocp_alarm_left + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPL (0x1 << 8) +#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPL_POS 8 +#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPL_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPL_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPL_MSK 0x100 + +/* + * int_polarity_flag_ocp_alarm_right + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPR (0x1 << 9) +#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPR_POS 9 +#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPR_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPR_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPR_MSK 0x200 + +/* + * int_polarity_flag_man_wait_src_settings + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSRC (0x1 << 10) +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSRC_POS 10 +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSRC_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSRC_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSRC_MSK 0x400 + +/* + * int_polarity_flag_man_wait_cf_config + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWCFC (0x1 << 11) +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWCFC_POS 11 +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWCFC_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWCFC_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWCFC_MSK 0x800 + +/* + * int_polarity_flag_man_start_mute_audio + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSMU (0x1 << 12) +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSMU_POS 12 +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSMU_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSMU_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSMU_MSK 0x1000 + +/* + * int_polarity_flag_cfma_err + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMER (0x1 << 13) +#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMER_POS 13 +#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMER_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMER_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMER_MSK 0x2000 + +/* + * int_polarity_flag_cfma_ack + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMAC (0x1 << 14) +#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMAC_POS 14 +#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMAC_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMAC_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMAC_MSK 0x4000 + +/* + * int_polarity_flag_clk_out_of_range + */ +#define TFA98XX_STATUS_POLARITY_REG2_IPCLKOOR (0x1 << 15) +#define TFA98XX_STATUS_POLARITY_REG2_IPCLKOOR_POS 15 +#define TFA98XX_STATUS_POLARITY_REG2_IPCLKOOR_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPCLKOOR_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG2_IPCLKOOR_MSK 0x8000 + +/* + * (0x4e)-status_polarity_reg3 + */ + +/* + * int_polarity_flag_tdm_error + */ +#define TFA98XX_STATUS_POLARITY_REG3_IPOTDMER (0x1 << 0) +#define TFA98XX_STATUS_POLARITY_REG3_IPOTDMER_POS 0 +#define TFA98XX_STATUS_POLARITY_REG3_IPOTDMER_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG3_IPOTDMER_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG3_IPOTDMER_MSK 0x1 + +/* + * int_polarity_flag_clip_left + */ +#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPL (0x1 << 1) +#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPL_POS 1 +#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPL_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPL_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPL_MSK 0x2 + +/* + * int_polarity_flag_clip_right + */ +#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPR (0x1 << 2) +#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPR_POS 2 +#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPR_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPR_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPR_MSK 0x4 + +/* + * int_polarity_flag_mic_ocpok + */ +#define TFA98XX_STATUS_POLARITY_REG3_IPOOCPM (0x1 << 3) +#define TFA98XX_STATUS_POLARITY_REG3_IPOOCPM_POS 3 +#define TFA98XX_STATUS_POLARITY_REG3_IPOOCPM_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG3_IPOOCPM_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG3_IPOOCPM_MSK 0x8 + +/* + * (0x50)-bat_prot_config + */ + +/* + * vbat_prot_attack_time + */ +#define TFA98XX_BAT_PROT_CONFIG_BSSCR (0x3 << 0) +#define TFA98XX_BAT_PROT_CONFIG_BSSCR_POS 0 +#define TFA98XX_BAT_PROT_CONFIG_BSSCR_LEN 2 +#define TFA98XX_BAT_PROT_CONFIG_BSSCR_MAX 3 +#define TFA98XX_BAT_PROT_CONFIG_BSSCR_MSK 0x3 + +/* + * vbat_prot_thlevel + */ +#define TFA98XX_BAT_PROT_CONFIG_BSST (0xf << 2) +#define TFA98XX_BAT_PROT_CONFIG_BSST_POS 2 +#define TFA98XX_BAT_PROT_CONFIG_BSST_LEN 4 +#define TFA98XX_BAT_PROT_CONFIG_BSST_MAX 15 +#define TFA98XX_BAT_PROT_CONFIG_BSST_MSK 0x3c + +/* + * vbat_prot_max_reduct + */ +#define TFA98XX_BAT_PROT_CONFIG_BSSRL (0x3 << 6) +#define TFA98XX_BAT_PROT_CONFIG_BSSRL_POS 6 +#define TFA98XX_BAT_PROT_CONFIG_BSSRL_LEN 2 +#define TFA98XX_BAT_PROT_CONFIG_BSSRL_MAX 3 +#define TFA98XX_BAT_PROT_CONFIG_BSSRL_MSK 0xc0 + +/* + * vbat_prot_release_time + */ +#define TFA98XX_BAT_PROT_CONFIG_BSSRR (0x7 << 8) +#define TFA98XX_BAT_PROT_CONFIG_BSSRR_POS 8 +#define TFA98XX_BAT_PROT_CONFIG_BSSRR_LEN 3 +#define TFA98XX_BAT_PROT_CONFIG_BSSRR_MAX 7 +#define TFA98XX_BAT_PROT_CONFIG_BSSRR_MSK 0x700 + +/* + * vbat_prot_hysterese + */ +#define TFA98XX_BAT_PROT_CONFIG_BSSHY (0x3 << 11) +#define TFA98XX_BAT_PROT_CONFIG_BSSHY_POS 11 +#define TFA98XX_BAT_PROT_CONFIG_BSSHY_LEN 2 +#define TFA98XX_BAT_PROT_CONFIG_BSSHY_MAX 3 +#define TFA98XX_BAT_PROT_CONFIG_BSSHY_MSK 0x1800 + +/* + * sel_vbat + */ +#define TFA98XX_BAT_PROT_CONFIG_BSSR (0x1 << 14) +#define TFA98XX_BAT_PROT_CONFIG_BSSR_POS 14 +#define TFA98XX_BAT_PROT_CONFIG_BSSR_LEN 1 +#define TFA98XX_BAT_PROT_CONFIG_BSSR_MAX 1 +#define TFA98XX_BAT_PROT_CONFIG_BSSR_MSK 0x4000 + +/* + * bypass_clipper + */ +#define TFA98XX_BAT_PROT_CONFIG_BSSBY (0x1 << 15) +#define TFA98XX_BAT_PROT_CONFIG_BSSBY_POS 15 +#define TFA98XX_BAT_PROT_CONFIG_BSSBY_LEN 1 +#define TFA98XX_BAT_PROT_CONFIG_BSSBY_MAX 1 +#define TFA98XX_BAT_PROT_CONFIG_BSSBY_MSK 0x8000 + +/* + * (0x51)-audio_control + */ + +/* + * batsense_steepness + */ +#define TFA98XX_AUDIO_CONTROL_BSSS (0x1 << 0) +#define TFA98XX_AUDIO_CONTROL_BSSS_POS 0 +#define TFA98XX_AUDIO_CONTROL_BSSS_LEN 1 +#define TFA98XX_AUDIO_CONTROL_BSSS_MAX 1 +#define TFA98XX_AUDIO_CONTROL_BSSS_MSK 0x1 + +/* + * soft_mute + */ +#define TFA98XX_AUDIO_CONTROL_INTSMUTE (0x1 << 1) +#define TFA98XX_AUDIO_CONTROL_INTSMUTE_POS 1 +#define TFA98XX_AUDIO_CONTROL_INTSMUTE_LEN 1 +#define TFA98XX_AUDIO_CONTROL_INTSMUTE_MAX 1 +#define TFA98XX_AUDIO_CONTROL_INTSMUTE_MSK 0x2 + +/* + * cf_mute_left + */ +#define TFA98XX_AUDIO_CONTROL_CFSML (0x1 << 2) +#define TFA98XX_AUDIO_CONTROL_CFSML_POS 2 +#define TFA98XX_AUDIO_CONTROL_CFSML_LEN 1 +#define TFA98XX_AUDIO_CONTROL_CFSML_MAX 1 +#define TFA98XX_AUDIO_CONTROL_CFSML_MSK 0x4 + +/* + * cf_mute_right + */ +#define TFA98XX_AUDIO_CONTROL_CFSMR (0x1 << 3) +#define TFA98XX_AUDIO_CONTROL_CFSMR_POS 3 +#define TFA98XX_AUDIO_CONTROL_CFSMR_LEN 1 +#define TFA98XX_AUDIO_CONTROL_CFSMR_MAX 1 +#define TFA98XX_AUDIO_CONTROL_CFSMR_MSK 0x8 + +/* + * bypass_hp_left + */ +#define TFA98XX_AUDIO_CONTROL_HPFBYPL (0x1 << 4) +#define TFA98XX_AUDIO_CONTROL_HPFBYPL_POS 4 +#define TFA98XX_AUDIO_CONTROL_HPFBYPL_LEN 1 +#define TFA98XX_AUDIO_CONTROL_HPFBYPL_MAX 1 +#define TFA98XX_AUDIO_CONTROL_HPFBYPL_MSK 0x10 + +/* + * bypass_hp_right + */ +#define TFA98XX_AUDIO_CONTROL_HPFBYPR (0x1 << 5) +#define TFA98XX_AUDIO_CONTROL_HPFBYPR_POS 5 +#define TFA98XX_AUDIO_CONTROL_HPFBYPR_LEN 1 +#define TFA98XX_AUDIO_CONTROL_HPFBYPR_MAX 1 +#define TFA98XX_AUDIO_CONTROL_HPFBYPR_MSK 0x20 + +/* + * enbl_dpsa_left + */ +#define TFA98XX_AUDIO_CONTROL_DPSAL (0x1 << 6) +#define TFA98XX_AUDIO_CONTROL_DPSAL_POS 6 +#define TFA98XX_AUDIO_CONTROL_DPSAL_LEN 1 +#define TFA98XX_AUDIO_CONTROL_DPSAL_MAX 1 +#define TFA98XX_AUDIO_CONTROL_DPSAL_MSK 0x40 + +/* + * enbl_dpsa_right + */ +#define TFA98XX_AUDIO_CONTROL_DPSAR (0x1 << 7) +#define TFA98XX_AUDIO_CONTROL_DPSAR_POS 7 +#define TFA98XX_AUDIO_CONTROL_DPSAR_LEN 1 +#define TFA98XX_AUDIO_CONTROL_DPSAR_MAX 1 +#define TFA98XX_AUDIO_CONTROL_DPSAR_MSK 0x80 + +/* + * cf_volume + */ +#define TFA98XX_AUDIO_CONTROL_VOL (0xff << 8) +#define TFA98XX_AUDIO_CONTROL_VOL_POS 8 +#define TFA98XX_AUDIO_CONTROL_VOL_LEN 8 +#define TFA98XX_AUDIO_CONTROL_VOL_MAX 255 +#define TFA98XX_AUDIO_CONTROL_VOL_MSK 0xff00 + +/* + * (0x52)-amplifier_config + */ + +/* + * ctrl_rcv + */ +#define TFA98XX_AMPLIFIER_CONFIG_HNDSFRCV (0x1 << 0) +#define TFA98XX_AMPLIFIER_CONFIG_HNDSFRCV_POS 0 +#define TFA98XX_AMPLIFIER_CONFIG_HNDSFRCV_LEN 1 +#define TFA98XX_AMPLIFIER_CONFIG_HNDSFRCV_MAX 1 +#define TFA98XX_AMPLIFIER_CONFIG_HNDSFRCV_MSK 0x1 + +/* + * ctrl_cc + */ +#define TFA98XX_AMPLIFIER_CONFIG_CLIPCTRL (0x7 << 2) +#define TFA98XX_AMPLIFIER_CONFIG_CLIPCTRL_POS 2 +#define TFA98XX_AMPLIFIER_CONFIG_CLIPCTRL_LEN 3 +#define TFA98XX_AMPLIFIER_CONFIG_CLIPCTRL_MAX 7 +#define TFA98XX_AMPLIFIER_CONFIG_CLIPCTRL_MSK 0x1c + +/* + * gain + */ +#define TFA98XX_AMPLIFIER_CONFIG_AMPGAIN (0xff << 5) +#define TFA98XX_AMPLIFIER_CONFIG_AMPGAIN_POS 5 +#define TFA98XX_AMPLIFIER_CONFIG_AMPGAIN_LEN 8 +#define TFA98XX_AMPLIFIER_CONFIG_AMPGAIN_MAX 255 +#define TFA98XX_AMPLIFIER_CONFIG_AMPGAIN_MSK 0x1fe0 + +/* + * ctrl_slopectrl + */ +#define TFA98XX_AMPLIFIER_CONFIG_SLOPEE (0x1 << 13) +#define TFA98XX_AMPLIFIER_CONFIG_SLOPEE_POS 13 +#define TFA98XX_AMPLIFIER_CONFIG_SLOPEE_LEN 1 +#define TFA98XX_AMPLIFIER_CONFIG_SLOPEE_MAX 1 +#define TFA98XX_AMPLIFIER_CONFIG_SLOPEE_MSK 0x2000 + +/* + * ctrl_slope + */ +#define TFA98XX_AMPLIFIER_CONFIG_SLOPESET (0x3 << 14) +#define TFA98XX_AMPLIFIER_CONFIG_SLOPESET_POS 14 +#define TFA98XX_AMPLIFIER_CONFIG_SLOPESET_LEN 2 +#define TFA98XX_AMPLIFIER_CONFIG_SLOPESET_MAX 3 +#define TFA98XX_AMPLIFIER_CONFIG_SLOPESET_MSK 0xc000 + +/* + * (0x5a)-audio_control2 + */ + +/* + * cf_volume_sec + */ +#define TFA98XX_AUDIO_CONTROL2_VOLSEC (0xff << 0) +#define TFA98XX_AUDIO_CONTROL2_VOLSEC_POS 0 +#define TFA98XX_AUDIO_CONTROL2_VOLSEC_LEN 8 +#define TFA98XX_AUDIO_CONTROL2_VOLSEC_MAX 255 +#define TFA98XX_AUDIO_CONTROL2_VOLSEC_MSK 0xff + +/* + * sw_profile + */ +#define TFA98XX_AUDIO_CONTROL2_SWPROFIL (0xff << 8) +#define TFA98XX_AUDIO_CONTROL2_SWPROFIL_POS 8 +#define TFA98XX_AUDIO_CONTROL2_SWPROFIL_LEN 8 +#define TFA98XX_AUDIO_CONTROL2_SWPROFIL_MAX 255 +#define TFA98XX_AUDIO_CONTROL2_SWPROFIL_MSK 0xff00 + +/* + * (0x70)-dcdc_control0 + */ + +/* + * boost_volt + */ +#define TFA98XX_DCDC_CONTROL0_DCVO (0x7 << 0) +#define TFA98XX_DCDC_CONTROL0_DCVO_POS 0 +#define TFA98XX_DCDC_CONTROL0_DCVO_LEN 3 +#define TFA98XX_DCDC_CONTROL0_DCVO_MAX 7 +#define TFA98XX_DCDC_CONTROL0_DCVO_MSK 0x7 + +/* + * boost_cur + */ +#define TFA98XX_DCDC_CONTROL0_DCMCC (0xf << 3) +#define TFA98XX_DCDC_CONTROL0_DCMCC_POS 3 +#define TFA98XX_DCDC_CONTROL0_DCMCC_LEN 4 +#define TFA98XX_DCDC_CONTROL0_DCMCC_MAX 15 +#define TFA98XX_DCDC_CONTROL0_DCMCC_MSK 0x78 + +/* + * bst_coil_value + */ +#define TFA98XX_DCDC_CONTROL0_DCCV (0x3 << 7) +#define TFA98XX_DCDC_CONTROL0_DCCV_POS 7 +#define TFA98XX_DCDC_CONTROL0_DCCV_LEN 2 +#define TFA98XX_DCDC_CONTROL0_DCCV_MAX 3 +#define TFA98XX_DCDC_CONTROL0_DCCV_MSK 0x180 + +/* + * boost_intel + */ +#define TFA98XX_DCDC_CONTROL0_DCIE (0x1 << 9) +#define TFA98XX_DCDC_CONTROL0_DCIE_POS 9 +#define TFA98XX_DCDC_CONTROL0_DCIE_LEN 1 +#define TFA98XX_DCDC_CONTROL0_DCIE_MAX 1 +#define TFA98XX_DCDC_CONTROL0_DCIE_MSK 0x200 + +/* + * boost_speed + */ +#define TFA98XX_DCDC_CONTROL0_DCSR (0x1 << 10) +#define TFA98XX_DCDC_CONTROL0_DCSR_POS 10 +#define TFA98XX_DCDC_CONTROL0_DCSR_LEN 1 +#define TFA98XX_DCDC_CONTROL0_DCSR_MAX 1 +#define TFA98XX_DCDC_CONTROL0_DCSR_MSK 0x400 + +/* + * dcdc_synchronisation + */ +#define TFA98XX_DCDC_CONTROL0_DCSYNCP (0x7 << 11) +#define TFA98XX_DCDC_CONTROL0_DCSYNCP_POS 11 +#define TFA98XX_DCDC_CONTROL0_DCSYNCP_LEN 3 +#define TFA98XX_DCDC_CONTROL0_DCSYNCP_MAX 7 +#define TFA98XX_DCDC_CONTROL0_DCSYNCP_MSK 0x3800 + +/* + * dcdcoff_mode + */ +#define TFA98XX_DCDC_CONTROL0_DCDIS (0x1 << 14) +#define TFA98XX_DCDC_CONTROL0_DCDIS_POS 14 +#define TFA98XX_DCDC_CONTROL0_DCDIS_LEN 1 +#define TFA98XX_DCDC_CONTROL0_DCDIS_MAX 1 +#define TFA98XX_DCDC_CONTROL0_DCDIS_MSK 0x4000 + +/* + * (0x90)-cf_controls + */ + +/* + * cf_rst_dsp + */ +#define TFA98XX_CF_CONTROLS_RST (0x1 << 0) +#define TFA98XX_CF_CONTROLS_RST_POS 0 +#define TFA98XX_CF_CONTROLS_RST_LEN 1 +#define TFA98XX_CF_CONTROLS_RST_MAX 1 +#define TFA98XX_CF_CONTROLS_RST_MSK 0x1 + +/* + * cf_dmem + */ +#define TFA98XX_CF_CONTROLS_DMEM (0x3 << 1) +#define TFA98XX_CF_CONTROLS_DMEM_POS 1 +#define TFA98XX_CF_CONTROLS_DMEM_LEN 2 +#define TFA98XX_CF_CONTROLS_DMEM_MAX 3 +#define TFA98XX_CF_CONTROLS_DMEM_MSK 0x6 + +/* + * cf_aif + */ +#define TFA98XX_CF_CONTROLS_AIF (0x1 << 3) +#define TFA98XX_CF_CONTROLS_AIF_POS 3 +#define TFA98XX_CF_CONTROLS_AIF_LEN 1 +#define TFA98XX_CF_CONTROLS_AIF_MAX 1 +#define TFA98XX_CF_CONTROLS_AIF_MSK 0x8 + +/* + * cf_int + */ +#define TFA98XX_CF_CONTROLS_CFINT (0x1 << 4) +#define TFA98XX_CF_CONTROLS_CFINT_POS 4 +#define TFA98XX_CF_CONTROLS_CFINT_LEN 1 +#define TFA98XX_CF_CONTROLS_CFINT_MAX 1 +#define TFA98XX_CF_CONTROLS_CFINT_MSK 0x10 + +/* + * cf_cgate_off + */ +#define TFA98XX_CF_CONTROLS_CFCGATE (0x1 << 5) +#define TFA98XX_CF_CONTROLS_CFCGATE_POS 5 +#define TFA98XX_CF_CONTROLS_CFCGATE_LEN 1 +#define TFA98XX_CF_CONTROLS_CFCGATE_MAX 1 +#define TFA98XX_CF_CONTROLS_CFCGATE_MSK 0x20 + +/* + * cf_req_cmd + */ +#define TFA98XX_CF_CONTROLS_REQCMD (0x1 << 8) +#define TFA98XX_CF_CONTROLS_REQCMD_POS 8 +#define TFA98XX_CF_CONTROLS_REQCMD_LEN 1 +#define TFA98XX_CF_CONTROLS_REQCMD_MAX 1 +#define TFA98XX_CF_CONTROLS_REQCMD_MSK 0x100 + +/* + * cf_req_reset + */ +#define TFA98XX_CF_CONTROLS_REQRST (0x1 << 9) +#define TFA98XX_CF_CONTROLS_REQRST_POS 9 +#define TFA98XX_CF_CONTROLS_REQRST_LEN 1 +#define TFA98XX_CF_CONTROLS_REQRST_MAX 1 +#define TFA98XX_CF_CONTROLS_REQRST_MSK 0x200 + +/* + * cf_req_mips + */ +#define TFA98XX_CF_CONTROLS_REQMIPS (0x1 << 10) +#define TFA98XX_CF_CONTROLS_REQMIPS_POS 10 +#define TFA98XX_CF_CONTROLS_REQMIPS_LEN 1 +#define TFA98XX_CF_CONTROLS_REQMIPS_MAX 1 +#define TFA98XX_CF_CONTROLS_REQMIPS_MSK 0x400 + +/* + * cf_req_mute_ready + */ +#define TFA98XX_CF_CONTROLS_REQMUTED (0x1 << 11) +#define TFA98XX_CF_CONTROLS_REQMUTED_POS 11 +#define TFA98XX_CF_CONTROLS_REQMUTED_LEN 1 +#define TFA98XX_CF_CONTROLS_REQMUTED_MAX 1 +#define TFA98XX_CF_CONTROLS_REQMUTED_MSK 0x800 + +/* + * cf_req_volume_ready + */ +#define TFA98XX_CF_CONTROLS_REQVOL (0x1 << 12) +#define TFA98XX_CF_CONTROLS_REQVOL_POS 12 +#define TFA98XX_CF_CONTROLS_REQVOL_LEN 1 +#define TFA98XX_CF_CONTROLS_REQVOL_MAX 1 +#define TFA98XX_CF_CONTROLS_REQVOL_MSK 0x1000 + +/* + * cf_req_damage + */ +#define TFA98XX_CF_CONTROLS_REQDMG (0x1 << 13) +#define TFA98XX_CF_CONTROLS_REQDMG_POS 13 +#define TFA98XX_CF_CONTROLS_REQDMG_LEN 1 +#define TFA98XX_CF_CONTROLS_REQDMG_MAX 1 +#define TFA98XX_CF_CONTROLS_REQDMG_MSK 0x2000 + +/* + * cf_req_calibrate_ready + */ +#define TFA98XX_CF_CONTROLS_REQCAL (0x1 << 14) +#define TFA98XX_CF_CONTROLS_REQCAL_POS 14 +#define TFA98XX_CF_CONTROLS_REQCAL_LEN 1 +#define TFA98XX_CF_CONTROLS_REQCAL_MAX 1 +#define TFA98XX_CF_CONTROLS_REQCAL_MSK 0x4000 + +/* + * cf_req_reserved + */ +#define TFA98XX_CF_CONTROLS_REQRSV (0x1 << 15) +#define TFA98XX_CF_CONTROLS_REQRSV_POS 15 +#define TFA98XX_CF_CONTROLS_REQRSV_LEN 1 +#define TFA98XX_CF_CONTROLS_REQRSV_MAX 1 +#define TFA98XX_CF_CONTROLS_REQRSV_MSK 0x8000 + +/* + * (0x91)-cf_mad + */ + +/* + * cf_madd + */ +#define TFA98XX_CF_MAD_MADD (0xffff << 0) +#define TFA98XX_CF_MAD_MADD_POS 0 +#define TFA98XX_CF_MAD_MADD_LEN 16 +#define TFA98XX_CF_MAD_MADD_MAX 65535 +#define TFA98XX_CF_MAD_MADD_MSK 0xffff + +/* + * (0x92)-cf_mem + */ + +/* + * cf_mema + */ +#define TFA98XX_CF_MEM_MEMA (0xffff << 0) +#define TFA98XX_CF_MEM_MEMA_POS 0 +#define TFA98XX_CF_MEM_MEMA_LEN 16 +#define TFA98XX_CF_MEM_MEMA_MAX 65535 +#define TFA98XX_CF_MEM_MEMA_MSK 0xffff + +/* + * (0x93)-cf_status + */ + +/* + * cf_err + */ +#define TFA98XX_CF_STATUS_ERR (0xff << 0) +#define TFA98XX_CF_STATUS_ERR_POS 0 +#define TFA98XX_CF_STATUS_ERR_LEN 8 +#define TFA98XX_CF_STATUS_ERR_MAX 255 +#define TFA98XX_CF_STATUS_ERR_MSK 0xff + +/* + * cf_ack_cmd + */ +#define TFA98XX_CF_STATUS_ACKCMD (0x1 << 8) +#define TFA98XX_CF_STATUS_ACKCMD_POS 8 +#define TFA98XX_CF_STATUS_ACKCMD_LEN 1 +#define TFA98XX_CF_STATUS_ACKCMD_MAX 1 +#define TFA98XX_CF_STATUS_ACKCMD_MSK 0x100 + +/* + * cf_ack_reset + */ +#define TFA98XX_CF_STATUS_ACKRST (0x1 << 9) +#define TFA98XX_CF_STATUS_ACKRST_POS 9 +#define TFA98XX_CF_STATUS_ACKRST_LEN 1 +#define TFA98XX_CF_STATUS_ACKRST_MAX 1 +#define TFA98XX_CF_STATUS_ACKRST_MSK 0x200 + +/* + * cf_ack_mips + */ +#define TFA98XX_CF_STATUS_ACKMIPS (0x1 << 10) +#define TFA98XX_CF_STATUS_ACKMIPS_POS 10 +#define TFA98XX_CF_STATUS_ACKMIPS_LEN 1 +#define TFA98XX_CF_STATUS_ACKMIPS_MAX 1 +#define TFA98XX_CF_STATUS_ACKMIPS_MSK 0x400 + +/* + * cf_ack_mute_ready + */ +#define TFA98XX_CF_STATUS_ACKMUTED (0x1 << 11) +#define TFA98XX_CF_STATUS_ACKMUTED_POS 11 +#define TFA98XX_CF_STATUS_ACKMUTED_LEN 1 +#define TFA98XX_CF_STATUS_ACKMUTED_MAX 1 +#define TFA98XX_CF_STATUS_ACKMUTED_MSK 0x800 + +/* + * cf_ack_volume_ready + */ +#define TFA98XX_CF_STATUS_ACKVOL (0x1 << 12) +#define TFA98XX_CF_STATUS_ACKVOL_POS 12 +#define TFA98XX_CF_STATUS_ACKVOL_LEN 1 +#define TFA98XX_CF_STATUS_ACKVOL_MAX 1 +#define TFA98XX_CF_STATUS_ACKVOL_MSK 0x1000 + +/* + * cf_ack_damage + */ +#define TFA98XX_CF_STATUS_ACKDMG (0x1 << 13) +#define TFA98XX_CF_STATUS_ACKDMG_POS 13 +#define TFA98XX_CF_STATUS_ACKDMG_LEN 1 +#define TFA98XX_CF_STATUS_ACKDMG_MAX 1 +#define TFA98XX_CF_STATUS_ACKDMG_MSK 0x2000 + +/* + * cf_ack_calibrate_ready + */ +#define TFA98XX_CF_STATUS_ACKCAL (0x1 << 14) +#define TFA98XX_CF_STATUS_ACKCAL_POS 14 +#define TFA98XX_CF_STATUS_ACKCAL_LEN 1 +#define TFA98XX_CF_STATUS_ACKCAL_MAX 1 +#define TFA98XX_CF_STATUS_ACKCAL_MSK 0x4000 + +/* + * cf_ack_reserved + */ +#define TFA98XX_CF_STATUS_ACKRSV (0x1 << 15) +#define TFA98XX_CF_STATUS_ACKRSV_POS 15 +#define TFA98XX_CF_STATUS_ACKRSV_LEN 1 +#define TFA98XX_CF_STATUS_ACKRSV_MAX 1 +#define TFA98XX_CF_STATUS_ACKRSV_MSK 0x8000 + +/* + * (0xa1)-mtpkey2_reg + */ + +/* + * mtpkey2 + */ +#define TFA98XX_MTPKEY2_REG_MTPK (0xff << 0) +#define TFA98XX_MTPKEY2_REG_MTPK_POS 0 +#define TFA98XX_MTPKEY2_REG_MTPK_LEN 8 +#define TFA98XX_MTPKEY2_REG_MTPK_MAX 255 +#define TFA98XX_MTPKEY2_REG_MTPK_MSK 0xff + +/* + * (0xa2)-mtp_status + */ + +/* + * key01_locked + */ +#define TFA98XX_MTP_STATUS_KEY1LOCKED (0x1 << 0) +#define TFA98XX_MTP_STATUS_KEY1LOCKED_POS 0 +#define TFA98XX_MTP_STATUS_KEY1LOCKED_LEN 1 +#define TFA98XX_MTP_STATUS_KEY1LOCKED_MAX 1 +#define TFA98XX_MTP_STATUS_KEY1LOCKED_MSK 0x1 + +/* + * key02_locked + */ +#define TFA98XX_MTP_STATUS_KEY2LOCKED (0x1 << 1) +#define TFA98XX_MTP_STATUS_KEY2LOCKED_POS 1 +#define TFA98XX_MTP_STATUS_KEY2LOCKED_LEN 1 +#define TFA98XX_MTP_STATUS_KEY2LOCKED_MAX 1 +#define TFA98XX_MTP_STATUS_KEY2LOCKED_MSK 0x2 + +/* + * (0xa3)-KEY_protected_mtp_control + */ + +/* + * auto_copy_iic_to_mtp + */ +#define TFA98XX_KEY_PROTECTED_MTP_CONTROL_CIMTP (0x1 << 6) +#define TFA98XX_KEY_PROTECTED_MTP_CONTROL_CIMTP_POS 6 +#define TFA98XX_KEY_PROTECTED_MTP_CONTROL_CIMTP_LEN 1 +#define TFA98XX_KEY_PROTECTED_MTP_CONTROL_CIMTP_MAX 1 +#define TFA98XX_KEY_PROTECTED_MTP_CONTROL_CIMTP_MSK 0x40 + +/* + * (0xa5)-mtp_data_out_msb + */ + +/* + * mtp_man_data_out_msb + */ +#define TFA98XX_MTP_DATA_OUT_MSB_MTPRDMSB (0xffff << 0) +#define TFA98XX_MTP_DATA_OUT_MSB_MTPRDMSB_POS 0 +#define TFA98XX_MTP_DATA_OUT_MSB_MTPRDMSB_LEN 16 +#define TFA98XX_MTP_DATA_OUT_MSB_MTPRDMSB_MAX 65535 +#define TFA98XX_MTP_DATA_OUT_MSB_MTPRDMSB_MSK 0xffff + +/* + * (0xa6)-mtp_data_out_lsb + */ + +/* + * mtp_man_data_out_lsb + */ +#define TFA98XX_MTP_DATA_OUT_LSB_MTPRDLSB (0xffff << 0) +#define TFA98XX_MTP_DATA_OUT_LSB_MTPRDLSB_POS 0 +#define TFA98XX_MTP_DATA_OUT_LSB_MTPRDLSB_LEN 16 +#define TFA98XX_MTP_DATA_OUT_LSB_MTPRDLSB_MAX 65535 +#define TFA98XX_MTP_DATA_OUT_LSB_MTPRDLSB_MSK 0xffff + +/* + * (0xb1)-temp_sensor_config + */ + +/* + * ext_temp + */ +#define TFA98XX_TEMP_SENSOR_CONFIG_EXTTS (0x1ff << 0) +#define TFA98XX_TEMP_SENSOR_CONFIG_EXTTS_POS 0 +#define TFA98XX_TEMP_SENSOR_CONFIG_EXTTS_LEN 9 +#define TFA98XX_TEMP_SENSOR_CONFIG_EXTTS_MAX 511 +#define TFA98XX_TEMP_SENSOR_CONFIG_EXTTS_MSK 0x1ff + +/* + * ext_temp_sel + */ +#define TFA98XX_TEMP_SENSOR_CONFIG_TROS (0x1 << 9) +#define TFA98XX_TEMP_SENSOR_CONFIG_TROS_POS 9 +#define TFA98XX_TEMP_SENSOR_CONFIG_TROS_LEN 1 +#define TFA98XX_TEMP_SENSOR_CONFIG_TROS_MAX 1 +#define TFA98XX_TEMP_SENSOR_CONFIG_TROS_MSK 0x200 + +/* + * (0xf0)-KEY2_protected_MTP0 + */ + +/* + * calibration_onetime + */ +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC (0x1 << 0) +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_POS 0 +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_LEN 1 +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_MAX 1 +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_MSK 0x1 + +/* + * calibr_ron_done + */ +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPEX (0x1 << 1) +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_POS 1 +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_LEN 1 +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_MAX 1 +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_MSK 0x2 + +/* + * calibr_dcdc_api_calibrate + */ +#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCAPI (0x1 << 2) +#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCAPI_POS 2 +#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCAPI_LEN 1 +#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCAPI_MAX 1 +#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCAPI_MSK 0x4 + +/* + * calibr_dcdc_delta_sign + */ +#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCSB (0x1 << 3) +#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCSB_POS 3 +#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCSB_LEN 1 +#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCSB_MAX 1 +#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCSB_MSK 0x8 + +/* + * calibr_dcdc_delta + */ +#define TFA98XX_KEY2_PROTECTED_MTP0_USERDEF (0x7 << 4) +#define TFA98XX_KEY2_PROTECTED_MTP0_USERDEF_POS 4 +#define TFA98XX_KEY2_PROTECTED_MTP0_USERDEF_LEN 3 +#define TFA98XX_KEY2_PROTECTED_MTP0_USERDEF_MAX 7 +#define TFA98XX_KEY2_PROTECTED_MTP0_USERDEF_MSK 0x70 + +/* + * (0xf4)-KEY1_protected_MTP4 + */ + +/* + * (0xf5)-KEY1_protected_MTP5 + */ + +#endif /* TFA98XX_GENREGS_H */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx_parameters.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx_parameters.h new file mode 100644 index 000000000000..f24745431ed6 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx_parameters.h @@ -0,0 +1,744 @@ +/* + * Copyright 2013-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * tfa98xx_parameters.h + * + * Created on: Jul 22, 2013 + * Author: NLV02095 + */ + +#ifndef TFA98XXPARAMETERS_H_ +#define TFA98XXPARAMETERS_H_ + +//#include "config.h" +// workaround for Visual Studio: +// fatal error C1083: Cannot open include file: 'config.h': No such file or directory +#ifdef __KERNEL__ +#include +#else +#include +#endif + +#include "tfa_service.h" + +#if (defined(WIN32) || defined(_X64)) +/* These warnings are disabled because it is only given by Windows and there is no easy fix */ +#pragma warning(disable : 4200) +#pragma warning(disable : 4214) +#endif + +/* + * profiles & volumesteps + * + */ +#define TFA_MAX_PROFILES (64) +#define TFA_MAX_VSTEPS (64) +#define TFA_MAX_VSTEP_MSG_MARKER \ + (100) /* This marker is used to indicate if all msgs need to be written to the device */ +#define TFA_MAX_MSGS (10) + +// the pack pragma is required to make that the size in memory +// matches the actual variable lenghts +// This is to assure that the binary files can be transported between +// different platforms. +#pragma pack(push, 1) + +/* + * typedef for 24 bit value using 3 bytes + */ +typedef struct uint24 { + uint8_t b[3]; +} uint24_t; +/* + * the generic header + * all char types are in ASCII + */ +typedef struct nxpTfaHeader { + uint16_t id; + char version[2]; // "V_" : V=version, vv=subversion + char subversion[2]; // "vv" : vv=subversion + uint16_t size; // data size in bytes following CRC + uint32_t CRC; // 32-bits CRC for following data + char customer[8]; // “name of customer†+ char application[8]; // “application name†+ char type[8]; // “application type name†+} nxpTfaHeader_t; + +typedef enum nxpTfaSamplerate { + fs_8k, // 8kHz + fs_11k025, // 11.025kHz + fs_12k, // 12kHz + fs_16k, // 16kHz + fs_22k05, // 22.05kHz + fs_24k, // 24kHz + fs_32k, // 32kHz + fs_44k1, // 44.1kHz + fs_48k, // 48kHz + fs_96k, // 96kHz + fs_count // Should always be last item. +} nxpTfaSamplerate_t; + +// Keep in sync with nxpTfaSamplerate_t ! +static const int nxpTfaSamplerateHz[fs_count] = { 8000, 11025, 12000, 16000, + 22050, 24000, 32000, 44100, + 48000, 96000 }; + +/* + * coolflux direct memory access + */ +typedef struct nxpTfaDspMem { + uint8_t type; /* 0--3: p, x, y, iomem */ + uint16_t address; /* target address */ + uint8_t size; /* data size in words */ + int words[]; /* payload in signed 32bit integer (two's complement) */ +} nxpTfaDspMem_t; + +/* + * the biquad coefficients for the API together with index in filter + * the biquad_index is the actual index in the equalizer +1 + */ +#define BIQUAD_COEFF_SIZE 6 + +/* +* Output fixed point coeffs structure +*/ +typedef struct { + int a2; + int a1; + int b2; + int b1; + int b0; +} nxpTfaBiquad_t; + +typedef struct nxpTfaBiquadOld { + uint8_t bytes[BIQUAD_COEFF_SIZE * sizeof(uint24_t)]; +} nxpTfaBiquadOld_t; + +typedef struct nxpTfaBiquadFloat { + float headroom; + float b0; + float b1; + float b2; + float a1; + float a2; +} nxpTfaBiquadFloat_t; + +/* +* EQ filter definitions +* Note: This is not in line with smartstudio (JV: 12/12/2016) +*/ +typedef enum nxpTfaFilterType { + fCustom, //User defined biquad coefficients + fFlat, //Vary only gain + fLowpass, //2nd order Butterworth low pass + fHighpass, //2nd order Butterworth high pass + fLowshelf, + fHighshelf, + fNotch, + fPeak, + fBandpass, + f1stLP, + f1stHP, + fElliptic +} nxpTfaFilterType_t; + +/* + * filter parameters for biquad (re-)calculation + */ +typedef struct nxpTfaFilter { + nxpTfaBiquadOld_t biquad; + uint8_t enabled; + uint8_t type; // (== enum FilterTypes, assure 8bits length) + float frequency; + float Q; + float gain; +} nxpTfaFilter_t; //8 * float + int32 + byte == 37 + +/* + * biquad params for calculation +*/ + +#define TFA_BQ_EQ_INDEX 0 +#define TFA_BQ_ANTI_ALIAS_INDEX 10 +#define TFA_BQ_INTEGRATOR_INDEX 13 + +/* +* Loudspeaker Compensation filter definitions +*/ +typedef struct nxpTfaLsCompensationFilter { + nxpTfaBiquad_t biquad; + uint8_t lsCompOn; // Loudspeaker compensation on/off; when 'off', the DSP code doesn't apply the bwExt => bwExtOn GUI flag should be gray to avoid confusion + uint8_t bwExtOn; // Bandwidth extension on/off + float fRes; // [Hz] speaker resonance frequency + float Qt; // Speaker resonance Q-factor + float fBwExt; // [Hz] Band width extension frequency + float samplingFreq; // [Hz] Sampling frequency +} nxpTfaLsCompensationFilter_t; + +/* +* Anti Aliasing Elliptic filter definitions +*/ +typedef struct nxpTfaAntiAliasFilter { + nxpTfaBiquad_t biquad; /**< Output results fixed point coeffs */ + uint8_t enabled; + float cutOffFreq; // cut off frequency + float samplingFreq; // sampling frequency + float rippleDb; // range: [0.1 3.0] + float rolloff; // range: [-1.0 1.0] +} nxpTfaAntiAliasFilter_t; + +/** +* Integrator filter input definitions +*/ +typedef struct nxpTfaIntegratorFilter { + nxpTfaBiquad_t biquad; /**< Output results fixed point coeffs */ + uint8_t type; /**< Butterworth filter type: high or low pass */ + float cutOffFreq; /**< cut off frequency in Hertz; range: [100.0 4000.0] */ + float samplingFreq; /**< sampling frequency in Hertz */ + float leakage; /**< leakage factor; range [0.0 1.0] */ +} nxpTfaIntegratorFilter_t; + +typedef struct nxpTfaEqFilter { + nxpTfaBiquad_t biquad; + uint8_t enabled; + uint8_t type; // (== enum FilterTypes, assure 8bits length) + float cutOffFreq; // cut off frequency, // range: [100.0 4000.0] + float samplingFreq; // sampling frequency + float Q; // range: [0.5 5.0] + float gainDb; // range: [-10.0 10.0] +} nxpTfaEqFilter_t; //8 * float + int32 + byte == 37 + +typedef struct nxpTfaContAntiAlias { + int8_t index; /**< index determines destination type; anti-alias, integrator,eq */ + uint8_t type; + float cutOffFreq; // cut off frequency + float samplingFreq; + float rippleDb; // integrator leakage + float rolloff; + uint8_t bytes[5 * 3]; // payload 5*24buts coeffs +} nxpTfaContAntiAlias_t; + +typedef struct nxpTfaContIntegrator { + int8_t index; /**< index determines destination type; anti-alias, integrator,eq */ + uint8_t type; + float cutOffFreq; // cut off frequency + float samplingFreq; + float leakage; // integrator leakage + float reserved; + uint8_t bytes[5 * 3]; // payload 5*24buts coeffs +} nxpTfaContIntegrator_t; + +typedef struct nxpTfaContEq { + int8_t index; + uint8_t type; // (== enum FilterTypes, assure 8bits length) + float cutOffFreq; // cut off frequency, // range: [100.0 4000.0] + float samplingFreq; // sampling frequency + float Q; // range: [0.5 5.0] + float gainDb; // range: [-10.0 10.0] + uint8_t bytes[5 * 3]; // payload 5*24buts coeffs +} nxpTfaContEq_t; //8 * float + int32 + byte == 37 + +typedef union nxpTfaContBiquad { + nxpTfaContEq_t eq; + nxpTfaContAntiAlias_t aa; + nxpTfaContIntegrator_t in; +} nxpTfaContBiquad_t; + +#define TFA_BQ_EQ_INDEX 0 +#define TFA_BQ_ANTI_ALIAS_INDEX 10 +#define TFA_BQ_INTEGRATOR_INDEX 13 +#define TFA98XX_MAX_EQ 10 + +typedef struct nxpTfaEqualizer { + nxpTfaFilter_t filter[TFA98XX_MAX_EQ]; +} nxpTfaEqualizer_t; + +/* + * files + */ +#define HDR(c1, c2) (c2 << 8 | c1) // little endian +typedef enum nxpTfaHeaderType { + paramsHdr = HDR('P', 'M'), /* containter file */ + volstepHdr = HDR('V', 'P'), + patchHdr = HDR('P', 'A'), + speakerHdr = HDR('S', 'P'), + presetHdr = HDR('P', 'R'), + configHdr = HDR('C', 'O'), + equalizerHdr = HDR('E', 'Q'), + drcHdr = HDR('D', 'R'), + msgHdr = HDR('M', 'G'), /* generic message */ + infoHdr = HDR('I', 'N') +} nxpTfaHeaderType_t; + +/* + * equalizer file + */ +#define NXPTFA_EQ_VERSION '1' +#define NXPTFA_EQ_SUBVERSION "00" +typedef struct nxpTfaEqualizerFile { + nxpTfaHeader_t hdr; + uint8_t samplerate; // ==enum samplerates, assure 8 bits + nxpTfaFilter_t + filter[TFA98XX_MAX_EQ]; // note: API index counts from 1..10 +} nxpTfaEqualizerFile_t; + +/* + * patch file + */ +#define NXPTFA_PA_VERSION '1' +#define NXPTFA_PA_SUBVERSION "00" +typedef struct nxpTfaPatchFile { + nxpTfaHeader_t hdr; + uint8_t data[]; +} nxpTfaPatch_t; + +/* + * generic message file + * - the payload of this file includes the opcode and is send straight to the DSP + */ +#define NXPTFA_MG_VERSION '3' +#define NXPTFA_MG_SUBVERSION "00" +typedef struct nxpTfaMsgFile { + nxpTfaHeader_t hdr; + uint8_t data[]; +} nxpTfaMsgFile_t; + +/* + * NOTE the tfa98xx API defines the enum Tfa98xx_config_type that defines + * the subtypes as decribes below. + * tfa98xx_dsp_config_parameter_type() can be used to get the + * supported type for the active device.. + */ +/* + * config file V1 sub 1 + */ +#define NXPTFA_CO_VERSION '1' +#define NXPTFA_CO3_VERSION '3' +#define NXPTFA_CO_SUBVERSION1 "01" +typedef struct nxpTfaConfigS1File { + nxpTfaHeader_t hdr; + uint8_t data[55 * 3]; +} nxpTfaConfigS1_t; + +/* + * config file V1 sub 2 + */ +#define NXPTFA_CO_SUBVERSION2 "02" +typedef struct nxpTfaConfigS2File { + nxpTfaHeader_t hdr; + uint8_t data[67 * 3]; +} nxpTfaConfigS2_t; + +/* + * config file V1 sub 3 + */ +#define NXPTFA_CO_SUBVERSION3 "03" +typedef struct nxpTfaConfigS3File { + nxpTfaHeader_t hdr; + uint8_t data[67 * 3]; +} nxpTfaConfigS3_t; + +/* + * config file V1.0 + */ +#define NXPTFA_CO_SUBVERSION "00" +typedef struct nxpTfaConfigFile { + nxpTfaHeader_t hdr; + uint8_t data[]; +} nxpTfaConfig_t; + +/* + * preset file + */ +#define NXPTFA_PR_VERSION '1' +#define NXPTFA_PR_SUBVERSION "00" +typedef struct nxpTfaPresetFile { + nxpTfaHeader_t hdr; + uint8_t data[]; +} nxpTfaPreset_t; + +/* + * drc file + */ +#define NXPTFA_DR_VERSION '1' +#define NXPTFA_DR_SUBVERSION "00" +typedef struct nxpTfaDrcFile { + nxpTfaHeader_t hdr; + uint8_t data[]; +} nxpTfaDrc_t; + +/* + * drc file + * for tfa 2 there is also a xml-version + */ +#define NXPTFA_DR3_VERSION '3' +#define NXPTFA_DR3_SUBVERSION "00" +typedef struct nxpTfaDrcFile2 { + nxpTfaHeader_t hdr; + uint8_t version[3]; + uint8_t data[]; +} nxpTfaDrc2_t; + +/* + * volume step structures + */ +// VP01 +#define NXPTFA_VP1_VERSION '1' +#define NXPTFA_VP1_SUBVERSION "01" +typedef struct nxpTfaVolumeStep1 { + float attenuation; // IEEE single float + uint8_t preset[TFA98XX_PRESET_LENGTH]; +} nxpTfaVolumeStep1_t; + +// VP02 +#define NXPTFA_VP2_VERSION '2' +#define NXPTFA_VP2_SUBVERSION "01" +typedef struct nxpTfaVolumeStep2 { + float attenuation; // IEEE single float + uint8_t preset[TFA98XX_PRESET_LENGTH]; + nxpTfaFilter_t + filter[TFA98XX_MAX_EQ]; // note: API index counts from 1..10 +} nxpTfaVolumeStep2_t; + +/* + * volumestep file + */ +#define NXPTFA_VP_VERSION '1' +#define NXPTFA_VP_SUBVERSION "00" +typedef struct nxpTfaVolumeStepFile { + nxpTfaHeader_t hdr; + uint8_t vsteps; // can also be calulated from size+type + uint8_t samplerate; // ==enum samplerates, assure 8 bits + uint8_t payload; //start of variable length contents:N times volsteps +} nxpTfaVolumeStepFile_t; +/* + * volumestep2 file + */ +typedef struct nxpTfaVolumeStep2File { + nxpTfaHeader_t hdr; + uint8_t vsteps; // can also be calulated from size+type + uint8_t samplerate; // ==enum samplerates, assure 8 bits + nxpTfaVolumeStep2_t + vstep[]; //start of variable length contents:N times volsteps +} nxpTfaVolumeStep2File_t; + +/* + * volumestepMax2 file + */ +typedef struct nxpTfaVolumeStepMax2File { + nxpTfaHeader_t hdr; + uint8_t version[3]; + uint8_t NrOfVsteps; + uint8_t vstepsBin[]; +} nxpTfaVolumeStepMax2File_t; + +/* + * volumestepMax2 file + * This volumestep should ONLY be used for the use of bin2hdr! + * This can only be used to find the messagetype of the vstep (without header) + */ +typedef struct nxpTfaVolumeStepMax2_1File { + uint8_t version[3]; + uint8_t NrOfVsteps; + uint8_t vstepsBin[]; +} nxpTfaVolumeStepMax2_1File_t; + +struct nxpTfaVolumeStepRegisterInfo { + uint8_t NrOfRegisters; + uint16_t registerInfo[]; +}; + +struct nxpTfaVolumeStepMessageInfo { + uint8_t NrOfMessages; + uint8_t MessageType; + uint24_t MessageLength; + uint8_t CmdId[3]; + uint8_t ParameterData[]; +}; +/**************************old v2 *************************************************/ + +/* + * subv 00 volumestep file + */ +typedef struct nxpTfaOldHeader { + uint16_t id; + char version[2]; // "V_" : V=version, vv=subversion + char subversion[2]; // "vv" : vv=subversion + uint16_t size; // data size in bytes following CRC + uint32_t CRC; // 32-bits CRC for following data +} nxpTfaOldHeader_t; + +typedef struct nxpOldTfaFilter { + double bq[5]; + int32_t type; + double frequency; + double Q; + double gain; + uint8_t enabled; +} nxpTfaOldFilter_t; + +typedef struct nxpTfaOldVolumeStep2 { + float attenuation; // IEEE single float + uint8_t preset[TFA98XX_PRESET_LENGTH]; + nxpTfaOldFilter_t eq[10]; +} nxpTfaOldVolumeStep2_t; + +typedef struct nxpTfaOldVolumeStepFile { + nxpTfaOldHeader_t hdr; + nxpTfaOldVolumeStep2_t step[]; +} nxpTfaOldVolumeStep2File_t; +/**************************end old v2 *************************************************/ + +/* + * speaker file header + */ +struct nxpTfaSpkHeader { + struct nxpTfaHeader hdr; + char name[8]; // speaker nick name (e.g. “dumboâ€) + char vendor[16]; + char type[8]; + // dimensions (mm) + uint8_t height; + uint8_t width; + uint8_t depth; + uint16_t ohm; +}; + +/* + * speaker file + */ +#define NXPTFA_SP_VERSION '1' +#define NXPTFA_SP_SUBVERSION "00" +typedef struct nxpTfaSpeakerFile { + nxpTfaHeader_t hdr; + char name[8]; // speaker nick name (e.g. “dumboâ€) + char vendor[16]; + char type[8]; + // dimensions (mm) + uint8_t height; + uint8_t width; + uint8_t depth; + uint8_t ohm_primary; + uint8_t ohm_secondary; + uint8_t data[]; //payload TFA98XX_SPEAKERPARAMETER_LENGTH +} nxpTfaSpeakerFile_t; + +#define NXPTFA_VP3_VERSION '3' +#define NXPTFA_VP3_SUBVERSION "00" + +struct nxpTfaFWVer { + uint8_t Major; + uint8_t minor; + uint8_t minor_update : 6; + uint8_t Update : 2; +}; + +struct nxpTfaFWMsg { + struct nxpTfaFWVer fwVersion; + struct nxpTfaMsg payload; +}; + +typedef struct nxpTfaLiveData { + char name[25]; + char addrs[25]; + int tracker; + int scalefactor; +} nxpTfaLiveData_t; + +#define NXPTFA_SP3_VERSION '3' +#define NXPTFA_SP3_SUBVERSION "00" +struct nxpTfaSpeakerFileMax2 { + nxpTfaHeader_t hdr; + char name[8]; // speaker nick name (e.g. “dumboâ€) + char vendor[16]; + char type[8]; + // dimensions (mm) + uint8_t height; + uint8_t width; + uint8_t depth; + uint8_t ohm_primary; + uint8_t ohm_secondary; + struct nxpTfaFWMsg FWmsg; //payload including FW ver and Cmd ID +}; + +/* + * parameter container file + */ +/* + * descriptors + * Note 1: append new DescriptorType at the end + * Note 2: add new descriptors to dsc_name[] in tfaContUtil.c + */ +typedef enum nxpTfaDescriptorType { + dscDevice, // device list + dscProfile, // profile list + dscRegister, // register patch + dscString, // ascii, zero terminated string + dscFile, // filename + file contents + dscPatch, // patch file + dscMarker, // marker to indicate end of a list + dscMode, + dscSetInputSelect, + dscSetOutputSelect, + dscSetProgramConfig, + dscSetLagW, + dscSetGains, + dscSetvBatFactors, + dscSetSensesCal, + dscSetSensesDelay, + dscBitfield, + dscDefault, // used to reset bitfields to there default values + dscLiveData, + dscLiveDataString, + dscGroup, + dscCmd, + dscSetMBDrc, + dscFilter, + dscNoInit, + dscFeatures, + dscCfMem, // coolflux memory x,y,io + dscSetFwkUseCase, + dscSetVddpConfig, + dsc_last // trailer +} nxpTfaDescriptorType_t; + +#define TFA_BITFIELDDSCMSK 0x7fffffff +typedef struct nxpTfaDescPtr { + uint32_t offset : 24; + uint32_t type : 8; // (== enum nxpTfaDescriptorType, assure 8bits length) +} nxpTfaDescPtr_t; + +/* + * generic file descriptor + */ +typedef struct nxpTfaFileDsc { + nxpTfaDescPtr_t name; + uint32_t size; // file data length in bytes + uint8_t data[]; //payload +} nxpTfaFileDsc_t; + +/* + * device descriptor list + */ +typedef struct nxpTfaDeviceList { + uint8_t length; // nr of items in the list + uint8_t bus; // bus + uint8_t dev; // device + uint8_t func; // subfunction or subdevice + uint32_t devid; // device hw fw id + nxpTfaDescPtr_t name; // device name + nxpTfaDescPtr_t list[]; // items list +} nxpTfaDeviceList_t; + +/* + * profile descriptor list + */ +typedef struct nxpTfaProfileList { + uint32_t length : 8; // nr of items in the list + name + uint32_t group : 8; // profile group number + uint32_t ID : 16; // profile ID + nxpTfaDescPtr_t name; // profile name + nxpTfaDescPtr_t list[]; // items list (lenght-1 items) +} nxpTfaProfileList_t; +#define TFA_PROFID 0x1234 + +/* + * livedata descriptor list + */ +typedef struct nxpTfaLiveDataList { + uint32_t length : 8; // nr of items in the list + uint32_t ID : 24; // profile ID + nxpTfaDescPtr_t name; // livedata name + nxpTfaDescPtr_t list[]; // items list +} nxpTfaLiveDataList_t; +#define TFA_LIVEDATAID 0x5678 + +/* + * Bitfield descriptor + */ +typedef struct nxpTfaBitfield { + uint16_t value; + uint16_t field; // ==datasheet defined, 16 bits +} nxpTfaBitfield_t; + +/* + * Bitfield enumuration bits descriptor + */ +typedef struct nxpTfaBfEnum { + unsigned int len : 4; // this is the actual length-1 + unsigned int pos : 4; + unsigned int address : 8; +} nxpTfaBfEnum_t; + +/* + * Register patch descriptor + */ +typedef struct nxpTfaRegpatch { + uint8_t address; // register address + uint16_t value; // value to write + uint16_t mask; // mask of bits to write +} nxpTfaRegpatch_t; + +/* + * Mode descriptor + */ +typedef struct nxpTfaUseCase { + int value; // mode value, maps to enum Tfa98xx_Mode +} nxpTfaMode_t; + +/* + * NoInit descriptor + */ +typedef struct nxpTfaNoInit { + uint8_t value; // noInit value +} nxpTfaNoInit_t; + +/* + * Features descriptor + */ +typedef struct nxpTfaFeatures { + uint16_t value[3]; // features value +} nxpTfaFeatures_t; + +/* + * the container file + * - the size field is 32bits long (generic=16) + * - all char types are in ASCII + */ +#define NXPTFA_PM_VERSION '1' +#define NXPTFA_PM3_VERSION '3' +#define NXPTFA_PM_SUBVERSION '1' +typedef struct nxpTfaContainer { + char id[2]; // "XX" : XX=type + char version[2]; // "V_" : V=version, vv=subversion + char subversion[2]; // "vv" : vv=subversion + uint32_t size; // data size in bytes following CRC + uint32_t CRC; // 32-bits CRC for following data + uint16_t rev; // "extra chars for rev nr" + char customer[8]; // “name of customer†+ char application[8]; // “application name†+ char type[8]; // “application type name†+ uint16_t ndev; // "nr of device lists" + uint16_t nprof; // "nr of profile lists" + uint16_t nliveData; // "nr of livedata lists" + nxpTfaDescPtr_t index[]; // start of item index table +} nxpTfaContainer_t; + +#pragma pack(pop) + +#endif /* TFA98XXPARAMETERS_H_ */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx_tfafieldnames.h new file mode 100644 index 000000000000..4684ae4e69ed --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa98xx_tfafieldnames.h @@ -0,0 +1,149 @@ +/* + * Copyright 2014-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +typedef struct TfaBfName { + unsigned short bfEnum; + char *bfName; +} tfaBfName_t; + +typedef struct TfaIrqName { + unsigned short irqEnum; + char *irqName; +} tfaIrqName_t; + +#include "tfa1_tfafieldnames.h" +#include "tfa2_tfafieldnames_N1C.h" +/* diffs for specific devices */ +#include "tfa9887_tfafieldnames.h" +#include "tfa9890_tfafieldnames.h" +#include "tfa9891_tfafieldnames.h" +#include "tfa9872_tfafieldnames.h" +#include "tfa9912_tfafieldnames.h" +#include "tfa9896_tfafieldnames.h" +#include "tfa9874_tfafieldnames.h" +#include "tfa9894_tfafieldnames.h" + +/* missing 'common' defs break the build but unused in TFA1 context */ +#define TFA1_BF_AMPINSEL -1 +#define TFA1_BF_MANSCONF -1 +#define TFA1_BF_MANCOLD -1 +#define TFA1_BF_INTSMUTE -1 +#define TFA1_BF_CFSMR -1 +#define TFA1_BF_CFSML -1 +#define TFA1_BF_DCMCCAPI -1 +#define TFA1_BF_DCMCCSB -1 +#define TFA1_BF_USERDEF -1 +#define TFA1_BF_MANSTATE -1 +#define TFA1_BF_MANOPER -1 +#define TFA1_BF_REFCKSEL -1 +#define TFA1_BF_VOLSEC -1 +#define TFA1_BF_FRACTDEL -1 +#define TFA1_BF_ACKDMG -1 +#define TFA1_BF_SSRIGHTE -1 +#define TFA1_BF_SSLEFTE -1 +#define TFA1_BF_R25CL -1 +#define TFA1_BF_R25CR -1 +#define TFA1_BF_SWPROFIL 0x8045 /*!< profile save */ +#define TFA1_BF_SWVSTEP 0x80a5 /*!< vstep save */ + +#define TFA1_BF_TDMNBCK -1 +#define TFA1_BF_TDMSSIZE -1 + +/* missing 'common' defs break the build */ +#define TFA2_BF_CFSM -1 + +/* MTP access uses registers + * defs are derived from corresponding bitfield names as used in the BF macros + */ +#define MTPKEY2 MTPK /* unlock key2 MTPK */ +#define MTP0 MTPOTC /* MTP data */ +#define MTP_CONTROL CIMTP /* copy i2c to mtp */ + +/* interrupt enable register uses HW name in TFA2 */ +#define TFA2_BF_INTENVDDS TFA2_BF_IEVDDS + +/* TFA9891 specific bit field names */ +#define TFA1_BF_SAAMGAIN 0x2202 +#define TFA2_BF_SAAMGAIN -1 + +/* TFA9872 specific bit field names */ +#define TFA2_BF_IELP0 TFA9872_BF_IELP0 +#define TFA2_BF_ISTLP0 TFA9872_BF_ISTLP0 +#define TFA2_BF_IPOLP0 TFA9872_BF_IPOLP0 +#define TFA2_BF_IELP1 TFA9872_BF_IELP1 +#define TFA2_BF_ISTLP1 TFA9872_BF_ISTLP1 +#define TFA2_BF_IPOLP1 TFA9872_BF_IPOLP1 +#define TFA2_BF_LP0 TFA9872_BF_LP0 +#define TFA2_BF_LP1 TFA9872_BF_LP1 +#define TFA2_BF_R25C TFA9872_BF_R25C +#define TFA2_BF_SAMMODE TFA9872_BF_SAMMODE + +/* interrupt bit field names of TFA2 and TFA1 do not match */ +#define TFA1_BF_IEACS TFA1_BF_INTENACS +#define TFA1_BF_IPOACS TFA1_BF_INTPOLACS +#define TFA1_BF_ISTACS TFA1_BF_INTOACS +#define TFA1_BF_ISTVDDS TFA1_BF_INTOVDDS +#define TFA1_BF_ICLVDDS TFA1_BF_INTIVDDS +#define TFA1_BF_IPOVDDS TFA1_BF_INTPOLVDDS +#define TFA1_BF_IENOCLK TFA1_BF_INTENNOCLK +#define TFA1_BF_ISTNOCLK TFA1_BF_INTONOCLK +#define TFA1_BF_IPONOCLK TFA1_BF_INTPOLNOCLK + +/* interrupt bit fields not available on TFA1 */ +#define TFA1_BF_IECLKOOR -1 +#define TFA1_BF_ISTCLKOOR -1 +#define TFA1_BF_IEMWSRC -1 +#define TFA1_BF_ISTMWSRC -1 +#define TFA1_BF_IPOMWSRC -1 +#define TFA1_BF_IEMWSMU -1 +#define TFA1_BF_ISTMWSMU -1 +#define TFA1_BF_IPOMWSMU -1 +#define TFA1_BF_IEMWCFC -1 +#define TFA1_BF_ISTMWCFC -1 +#define TFA1_BF_IPOMWCFC -1 +#define TFA1_BF_CLKOOR -1 +#define TFA1_BF_MANWAIT1 -1 +#define TFA1_BF_MANWAIT2 -1 +#define TFA1_BF_MANMUTE -1 +#define TFA1_BF_IPCLKOOR -1 +#define TFA1_BF_ICLCLKOOR -1 +#define TFA1_BF_IPOSWS -1 +#define TFA1_BF_IESWS -1 +#define TFA1_BF_ISTSWS -1 +#define TFA1_BF_IESPKS -1 +#define TFA1_BF_ISTSPKS -1 +#define TFA1_BF_IPOSPKS -1 +#define TFA1_BF_IECLKS -1 +#define TFA1_BF_ISTCLKS -1 +#define TFA1_BF_IPOCLKS -1 +#define TFA1_BF_IEAMPS -1 +#define TFA1_BF_ISTAMPS -1 +#define TFA1_BF_IPOAMPS -1 +#define TFA1_BF_IELP0 -1 +#define TFA1_BF_ISTLP0 -1 +#define TFA1_BF_IPOLP0 -1 +#define TFA1_BF_IELP1 -1 +#define TFA1_BF_ISTLP1 -1 +#define TFA1_BF_IPOLP1 -1 +#define TFA1_BF_LP0 -1 +#define TFA1_BF_LP1 -1 +#define TFA1_BF_R25C -1 +#define TFA1_BF_SAMMODE -1 + +/* TDM STATUS fields not available on TFA1 */ +#define TFA1_BF_TDMLUTER -1 +#define TFA1_BF_TDMERR -1 diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9912_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9912_tfafieldnames.h new file mode 100644 index 000000000000..26ff9cf8d9e5 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa9912_tfafieldnames.h @@ -0,0 +1,3384 @@ +/** Filename: tfa9912_tfafieldnames.h + * This file was generated automatically on 06/14/17 at 18:04:05. + * Source file: TFA9912_N1A_I2C_regmap_V1.41.xlsx + */ + +#ifndef _TFA9912_TFAFIELDNAMES_H +#define _TFA9912_TFAFIELDNAMES_H + +#define TFA9912_I2CVERSION 1.41 + +typedef enum nxpTfa9912BfEnumList { + TFA9912_BF_PWDN = + 0x0000, /*!< Powerdown selection */ + TFA9912_BF_I2CR = + 0x0010, /*!< I2C Reset - Auto clear */ + TFA9912_BF_CFE = + 0x0020, /*!< Enable CoolFlux */ + TFA9912_BF_AMPE = + 0x0030, /*!< Enables the Amplifier */ + TFA9912_BF_DCA = + 0x0040, /*!< Activate DC-to-DC converter */ + TFA9912_BF_SBSL = + 0x0050, /*!< Coolflux configured */ + TFA9912_BF_AMPC = + 0x0060, /*!< CoolFlux controls amplifier */ + TFA9912_BF_INTP = + 0x0071, /*!< Interrupt config */ + TFA9912_BF_FSSSEL = + 0x0090, /*!< Audio sample reference */ + TFA9912_BF_BYPOCP = + 0x00b0, /*!< Bypass OCP */ + TFA9912_BF_TSTOCP = + 0x00c0, /*!< OCP testing control */ + TFA9912_BF_AMPINSEL = + 0x0101, /*!< Amplifier input selection */ + TFA9912_BF_MANSCONF = + 0x0120, /*!< I2C configured */ + TFA9912_BF_MANCOLD = + 0x0130, /*!< Execute cold start */ + TFA9912_BF_MANAOOSC = + 0x0140, /*!< Internal osc off at PWDN */ + TFA9912_BF_MANROBOD = + 0x0150, /*!< Reaction on BOD */ + TFA9912_BF_BODE = + 0x0160, /*!< BOD Enable */ + TFA9912_BF_BODHYS = + 0x0170, /*!< BOD Hysteresis */ + TFA9912_BF_BODFILT = + 0x0181, /*!< BOD filter */ + TFA9912_BF_BODTHLVL = + 0x01a1, /*!< BOD threshold */ + TFA9912_BF_MUTETO = + 0x01d0, /*!< Time out SB mute sequence */ + TFA9912_BF_RCVNS = + 0x01e0, /*!< Noise shaper selection */ + TFA9912_BF_MANWDE = + 0x01f0, /*!< Watchdog enable */ + TFA9912_BF_AUDFS = + 0x0203, /*!< Sample rate (fs) */ + TFA9912_BF_INPLEV = + 0x0240, /*!< TDM output attenuation */ + TFA9912_BF_FRACTDEL = + 0x0255, /*!< V/I Fractional delay */ + TFA9912_BF_BYPHVBF = + 0x02b0, /*!< Bypass HVBAT filter */ + TFA9912_BF_TDMC = + 0x02c0, /*!< TDM Compatibility with TFA9872 */ + TFA9912_BF_ENBLADC10 = + 0x02e0, /*!< ADC10 Enable - I2C direct mode */ + TFA9912_BF_REV = + 0x030f, /*!< Revision info */ + TFA9912_BF_REFCKEXT = + 0x0401, /*!< PLL external ref clock */ + TFA9912_BF_REFCKSEL = + 0x0420, /*!< PLL internal ref clock */ + TFA9912_BF_ENCFCKSEL = + 0x0430, /*!< Coolflux DSP clock scaling, low power mode */ + TFA9912_BF_CFCKSEL = + 0x0441, /*!< Coolflux DSP clock scaler selection for low power mode */ + TFA9912_BF_TDMINFSEL = + 0x0460, /*!< TDM clock selection */ + TFA9912_BF_DISBLAUTOCLKSEL = + 0x0470, /*!< Disable Automatic dsp clock source selection */ + TFA9912_BF_SELCLKSRC = + 0x0480, /*!< I2C selection of DSP clock when auto select is disabled */ + TFA9912_BF_SELTIMSRC = + 0x0490, /*!< I2C selection of Watchdog and Timer clock */ + TFA9912_BF_SSLEFTE = + 0x0500, /*!< */ + TFA9912_BF_SPKSSEN = + 0x0510, /*!< Enable speaker path */ + TFA9912_BF_VSLEFTE = + 0x0520, /*!< */ + TFA9912_BF_VSRIGHTE = + 0x0530, /*!< Voltage sense */ + TFA9912_BF_CSLEFTE = + 0x0540, /*!< */ + TFA9912_BF_CSRIGHTE = + 0x0550, /*!< Current sense */ + TFA9912_BF_SSPDME = + 0x0560, /*!< Sub-system PDM */ + TFA9912_BF_PGALE = + 0x0570, /*!< Enable PGA chop clock for left channel */ + TFA9912_BF_PGARE = + 0x0580, /*!< Enable PGA chop clock */ + TFA9912_BF_SSTDME = + 0x0590, /*!< Sub-system TDM */ + TFA9912_BF_SSPBSTE = + 0x05a0, /*!< Sub-system boost */ + TFA9912_BF_SSADCE = + 0x05b0, /*!< Sub-system ADC */ + TFA9912_BF_SSFAIME = + 0x05c0, /*!< Sub-system FAIM */ + TFA9912_BF_SSCFTIME = + 0x05d0, /*!< CF Sub-system timer */ + TFA9912_BF_SSCFWDTE = + 0x05e0, /*!< CF Sub-system WDT */ + TFA9912_BF_FAIMVBGOVRRL = + 0x05f0, /*!< Over rule of vbg for FaIM access */ + TFA9912_BF_SAMSPKSEL = + 0x0600, /*!< Input selection for TAP/SAM */ + TFA9912_BF_PDM2IISEN = + 0x0610, /*!< PDM2IIS Bridge enable */ + TFA9912_BF_TAPRSTBYPASS = + 0x0620, /*!< Tap decimator reset bypass - Bypass the decimator reset from tapdec */ + TFA9912_BF_CARDECISEL0 = + 0x0631, /*!< Cardec input 0 sel */ + TFA9912_BF_CARDECISEL1 = + 0x0651, /*!< Cardec input sel */ + TFA9912_BF_TAPDECSEL = + 0x0670, /*!< Select TAP/Cardec for TAP */ + TFA9912_BF_COMPCOUNT = + 0x0680, /*!< Comparator o/p filter selection */ + TFA9912_BF_STARTUPMODE = + 0x0691, /*!< Startup Mode Selection */ + TFA9912_BF_AUTOTAP = + 0x06b0, /*!< Enable auto tap switching */ + TFA9912_BF_COMPINITIME = + 0x06c1, /*!< Comparator initialization time to be used in Tap Machine */ + TFA9912_BF_ANAPINITIME = + 0x06e1, /*!< Analog initialization time to be used in Tap Machine */ + TFA9912_BF_CCHKTH = + 0x0707, /*!< Clock check Higher Threshold */ + TFA9912_BF_CCHKTL = + 0x0787, /*!< Clock check Higher Threshold */ + TFA9912_BF_AMPOCRT = + 0x0802, /*!< Amplifier on-off criteria for shutdown */ + TFA9912_BF_AMPTCRR = + 0x0832, /*!< Amplifier on-off criteria for tap mode entry */ + TFA9912_BF_STGS = + 0x0d00, /*!< PDM side tone gain selector */ + TFA9912_BF_STGAIN = + 0x0d18, /*!< Side tone gain */ + TFA9912_BF_STSMUTE = + 0x0da0, /*!< Side tone soft mute */ + TFA9912_BF_ST1C = + 0x0db0, /*!< side tone one s complement */ + TFA9912_BF_CMFBEL = + 0x0e80, /*!< CMFB enable left */ + TFA9912_BF_VDDS = + 0x1000, /*!< POR */ + TFA9912_BF_PLLS = + 0x1010, /*!< PLL lock */ + TFA9912_BF_OTDS = + 0x1020, /*!< OTP alarm */ + TFA9912_BF_OVDS = + 0x1030, /*!< OVP alarm */ + TFA9912_BF_UVDS = + 0x1040, /*!< UVP alarm */ + TFA9912_BF_CLKS = + 0x1050, /*!< Clocks stable */ + TFA9912_BF_MTPB = + 0x1060, /*!< MTP busy */ + TFA9912_BF_NOCLK = + 0x1070, /*!< Lost clock */ + TFA9912_BF_ACS = + 0x1090, /*!< Cold Start */ + TFA9912_BF_SWS = + 0x10a0, /*!< Amplifier engage */ + TFA9912_BF_WDS = + 0x10b0, /*!< Watchdog */ + TFA9912_BF_AMPS = + 0x10c0, /*!< Amplifier enable */ + TFA9912_BF_AREFS = + 0x10d0, /*!< References enable */ + TFA9912_BF_ADCCR = + 0x10e0, /*!< Control ADC */ + TFA9912_BF_BODNOK = + 0x10f0, /*!< BOD */ + TFA9912_BF_DCIL = + 0x1100, /*!< DCDC current limiting */ + TFA9912_BF_DCDCA = + 0x1110, /*!< DCDC active */ + TFA9912_BF_DCOCPOK = + 0x1120, /*!< DCDC OCP nmos */ + TFA9912_BF_DCPEAKCUR = + 0x1130, /*!< Indicates current is max in DC-to-DC converter */ + TFA9912_BF_DCHVBAT = + 0x1140, /*!< DCDC level 1x */ + TFA9912_BF_DCH114 = + 0x1150, /*!< DCDC level 1.14x */ + TFA9912_BF_DCH107 = + 0x1160, /*!< DCDC level 1.07x */ + TFA9912_BF_STMUTEB = + 0x1170, /*!< side tone (un)mute busy */ + TFA9912_BF_STMUTE = + 0x1180, /*!< side tone mute state */ + TFA9912_BF_TDMLUTER = + 0x1190, /*!< TDM LUT error */ + TFA9912_BF_TDMSTAT = + 0x11a2, /*!< TDM status bits */ + TFA9912_BF_TDMERR = + 0x11d0, /*!< TDM error */ + TFA9912_BF_HAPTIC = + 0x11e0, /*!< Status haptic driver */ + TFA9912_BF_OCPOAP = + 0x1300, /*!< OCPOK pmos A */ + TFA9912_BF_OCPOAN = + 0x1310, /*!< OCPOK nmos A */ + TFA9912_BF_OCPOBP = + 0x1320, /*!< OCPOK pmos B */ + TFA9912_BF_OCPOBN = + 0x1330, /*!< OCPOK nmos B */ + TFA9912_BF_CLIPAH = + 0x1340, /*!< Clipping A to Vddp */ + TFA9912_BF_CLIPAL = + 0x1350, /*!< Clipping A to gnd */ + TFA9912_BF_CLIPBH = + 0x1360, /*!< Clipping B to Vddp */ + TFA9912_BF_CLIPBL = + 0x1370, /*!< Clipping B to gnd */ + TFA9912_BF_OCDS = + 0x1380, /*!< OCP amplifier */ + TFA9912_BF_CLIPS = + 0x1390, /*!< Amplifier clipping */ + TFA9912_BF_TCMPTRG = + 0x13a0, /*!< Status Tap comparator triggered */ + TFA9912_BF_TAPDET = + 0x13b0, /*!< Status Tap detected */ + TFA9912_BF_MANWAIT1 = + 0x13c0, /*!< Wait HW I2C settings */ + TFA9912_BF_MANWAIT2 = + 0x13d0, /*!< Wait CF config */ + TFA9912_BF_MANMUTE = + 0x13e0, /*!< Audio mute sequence */ + TFA9912_BF_MANOPER = + 0x13f0, /*!< Operating state */ + TFA9912_BF_SPKSL = + 0x1400, /*!< Left speaker status */ + TFA9912_BF_SPKS = + 0x1410, /*!< Speaker status */ + TFA9912_BF_CLKOOR = + 0x1420, /*!< External clock status */ + TFA9912_BF_MANSTATE = + 0x1433, /*!< Device manager status */ + TFA9912_BF_DCMODE = + 0x1471, /*!< DCDC mode status bits */ + TFA9912_BF_DSPCLKSRC = + 0x1490, /*!< DSP clock source selected by manager */ + TFA9912_BF_STARTUPMODSTAT = + 0x14a1, /*!< Startup Mode Selected by Manager(Read Only) */ + TFA9912_BF_TSPMSTATE = + 0x14c3, /*!< Tap Machine State */ + TFA9912_BF_BATS = + 0x1509, /*!< Battery voltage (V) */ + TFA9912_BF_TEMPS = + 0x1608, /*!< IC Temperature (C) */ + TFA9912_BF_VDDPS = + 0x1709, /*!< IC VDDP voltage ( 1023*VDDP/13 V) */ + TFA9912_BF_DCILCF = + 0x17a0, /*!< DCDC current limiting for DSP */ + TFA9912_BF_TDMUC = + 0x2000, /*!< Mode setting */ + TFA9912_BF_DIO4SEL = + 0x2011, /*!< DIO4 Input selection */ + TFA9912_BF_TDME = + 0x2040, /*!< Enable TDM interface */ + TFA9912_BF_TDMMODE = + 0x2050, /*!< Slave/master */ + TFA9912_BF_TDMCLINV = + 0x2060, /*!< Reception data to BCK clock */ + TFA9912_BF_TDMFSLN = + 0x2073, /*!< FS length */ + TFA9912_BF_TDMFSPOL = + 0x20b0, /*!< FS polarity */ + TFA9912_BF_TDMNBCK = + 0x20c3, /*!< N-BCK's in FS */ + TFA9912_BF_TDMSLOTS = + 0x2103, /*!< N-slots in Frame */ + TFA9912_BF_TDMSLLN = + 0x2144, /*!< N-bits in slot */ + TFA9912_BF_TDMBRMG = + 0x2194, /*!< N-bits remaining */ + TFA9912_BF_TDMDEL = + 0x21e0, /*!< data delay to FS */ + TFA9912_BF_TDMADJ = + 0x21f0, /*!< data adjustment */ + TFA9912_BF_TDMOOMP = + 0x2201, /*!< Received audio compression */ + TFA9912_BF_TDMSSIZE = + 0x2224, /*!< Sample size per slot */ + TFA9912_BF_TDMTXDFO = + 0x2271, /*!< Format unused bits in a slot */ + TFA9912_BF_TDMTXUS0 = + 0x2291, /*!< Format unused slots GAINIO */ + TFA9912_BF_TDMTXUS1 = + 0x22b1, /*!< Format unused slots DIO1 */ + TFA9912_BF_TDMTXUS2 = + 0x22d1, /*!< Format unused slots DIO2 */ + TFA9912_BF_TDMGIE = + 0x2300, /*!< Control gain (channel in 0) */ + TFA9912_BF_TDMDCE = + 0x2310, /*!< Control audio left (channel in 1 ) */ + TFA9912_BF_TDMSPKE = + 0x2320, /*!< Control audio right (channel in 2 ) */ + TFA9912_BF_TDMCSE = + 0x2330, /*!< Current sense */ + TFA9912_BF_TDMVSE = + 0x2340, /*!< Voltage sense */ + TFA9912_BF_TDMGOE = + 0x2350, /*!< DSP Gainout */ + TFA9912_BF_TDMCF2E = + 0x2360, /*!< DSP 2 */ + TFA9912_BF_TDMCF3E = + 0x2370, /*!< DSP 3 */ + TFA9912_BF_TDMCFE = + 0x2380, /*!< DSP */ + TFA9912_BF_TDMES6 = + 0x2390, /*!< Loopback of Audio left (channel 1) */ + TFA9912_BF_TDMES7 = + 0x23a0, /*!< Loopback of Audio right (channel 2) */ + TFA9912_BF_TDMCF4E = + 0x23b0, /*!< AEC ref right control */ + TFA9912_BF_TDMPD1E = + 0x23c0, /*!< PDM 1 control */ + TFA9912_BF_TDMPD2E = + 0x23d0, /*!< PDM 2 control */ + TFA9912_BF_TDMGIN = + 0x2401, /*!< IO gainin */ + TFA9912_BF_TDMLIO = + 0x2421, /*!< IO audio left */ + TFA9912_BF_TDMRIO = + 0x2441, /*!< IO audio right */ + TFA9912_BF_TDMCSIO = + 0x2461, /*!< IO Current Sense */ + TFA9912_BF_TDMVSIO = + 0x2481, /*!< IO voltage sense */ + TFA9912_BF_TDMGOIO = + 0x24a1, /*!< IO gain out */ + TFA9912_BF_TDMCFIO2 = + 0x24c1, /*!< IO DSP 2 */ + TFA9912_BF_TDMCFIO3 = + 0x24e1, /*!< IO DSP 3 */ + TFA9912_BF_TDMCFIO = + 0x2501, /*!< IO DSP */ + TFA9912_BF_TDMLPB6 = + 0x2521, /*!< IO Source 6 */ + TFA9912_BF_TDMLPB7 = + 0x2541, /*!< IO Source 7 */ + TFA9912_BF_TDMGS = + 0x2603, /*!< Control gainin */ + TFA9912_BF_TDMDCS = + 0x2643, /*!< tdm slot for audio left (channel 1) */ + TFA9912_BF_TDMSPKS = + 0x2683, /*!< tdm slot for audio right (channel 2) */ + TFA9912_BF_TDMCSS = + 0x26c3, /*!< Slot Position of Current Sense Out */ + TFA9912_BF_TDMVSS = + 0x2703, /*!< Slot Position of Voltage sense */ + TFA9912_BF_TDMCGOS = + 0x2743, /*!< Slot Position of GAIN out */ + TFA9912_BF_TDMCF2S = + 0x2783, /*!< Slot Position DSPout2 */ + TFA9912_BF_TDMCF3S = + 0x27c3, /*!< Slot Position DSPout3 */ + TFA9912_BF_TDMCFS = + 0x2803, /*!< Slot Position of DSPout */ + TFA9912_BF_TDMEDAT6S = + 0x2843, /*!< Slot Position of loopback channel left */ + TFA9912_BF_TDMEDAT7S = + 0x2883, /*!< Slot Position of loopback channel right */ + TFA9912_BF_TDMTXUS3 = + 0x2901, /*!< Format unused slots D3 */ + TFA9912_BF_PDMSM = + 0x3100, /*!< PDM control */ + TFA9912_BF_PDMSTSEL = + 0x3110, /*!< PDM Decimator input selection */ + TFA9912_BF_PDMSTENBL = + 0x3120, /*!< Side tone input enable */ + TFA9912_BF_PDMLSEL = + 0x3130, /*!< PDM data selection for left channel during PDM direct mode */ + TFA9912_BF_PDMRSEL = + 0x3140, /*!< PDM data selection for right channel during PDM direct mode */ + TFA9912_BF_MICVDDE = + 0x3150, /*!< Enable MICVDD */ + TFA9912_BF_PDMCLRAT = + 0x3201, /*!< PDM BCK/Fs ratio */ + TFA9912_BF_PDMGAIN = + 0x3223, /*!< PDM gain */ + TFA9912_BF_PDMOSEL = + 0x3263, /*!< PDM output selection - RE/FE data combination */ + TFA9912_BF_SELCFHAPD = + 0x32a0, /*!< Select the source for haptic data output (not for customer) */ + TFA9912_BF_ISTVDDS = + 0x4000, /*!< Status POR */ + TFA9912_BF_ISTPLLS = + 0x4010, /*!< Status PLL lock */ + TFA9912_BF_ISTOTDS = + 0x4020, /*!< Status OTP alarm */ + TFA9912_BF_ISTOVDS = + 0x4030, /*!< Status OVP alarm */ + TFA9912_BF_ISTUVDS = + 0x4040, /*!< Status UVP alarm */ + TFA9912_BF_ISTCLKS = + 0x4050, /*!< Status clocks stable */ + TFA9912_BF_ISTMTPB = + 0x4060, /*!< Status MTP busy */ + TFA9912_BF_ISTNOCLK = + 0x4070, /*!< Status lost clock */ + TFA9912_BF_ISTSPKS = + 0x4080, /*!< Status speaker error */ + TFA9912_BF_ISTACS = + 0x4090, /*!< Status cold start */ + TFA9912_BF_ISTSWS = + 0x40a0, /*!< Status amplifier engage */ + TFA9912_BF_ISTWDS = + 0x40b0, /*!< Status watchdog */ + TFA9912_BF_ISTAMPS = + 0x40c0, /*!< Status amplifier enable */ + TFA9912_BF_ISTAREFS = + 0x40d0, /*!< Status Ref enable */ + TFA9912_BF_ISTADCCR = + 0x40e0, /*!< Status Control ADC */ + TFA9912_BF_ISTBODNOK = + 0x40f0, /*!< Status BOD */ + TFA9912_BF_ISTBSTCU = + 0x4100, /*!< Status DCDC current limiting */ + TFA9912_BF_ISTBSTHI = + 0x4110, /*!< Status DCDC active */ + TFA9912_BF_ISTBSTOC = + 0x4120, /*!< Status DCDC OCP */ + TFA9912_BF_ISTBSTPKCUR = + 0x4130, /*!< Status bst peakcur */ + TFA9912_BF_ISTBSTVC = + 0x4140, /*!< Status DCDC level 1x */ + TFA9912_BF_ISTBST86 = + 0x4150, /*!< Status DCDC level 1.14x */ + TFA9912_BF_ISTBST93 = + 0x4160, /*!< Status DCDC level 1.07x */ + TFA9912_BF_ISTRCVLD = + 0x4170, /*!< Status rcvldop ready */ + TFA9912_BF_ISTOCPL = + 0x4180, /*!< Status ocp alarm left */ + TFA9912_BF_ISTOCPR = + 0x4190, /*!< Status ocp alarm */ + TFA9912_BF_ISTMWSRC = + 0x41a0, /*!< Status Waits HW I2C settings */ + TFA9912_BF_ISTMWCFC = + 0x41b0, /*!< Status waits CF config */ + TFA9912_BF_ISTMWSMU = + 0x41c0, /*!< Status Audio mute sequence */ + TFA9912_BF_ISTCFMER = + 0x41d0, /*!< Status cfma error */ + TFA9912_BF_ISTCFMAC = + 0x41e0, /*!< Status cfma ack */ + TFA9912_BF_ISTCLKOOR = + 0x41f0, /*!< Status flag_clk_out_of_range */ + TFA9912_BF_ISTTDMER = + 0x4200, /*!< Status tdm error */ + TFA9912_BF_ISTCLPL = + 0x4210, /*!< Status clip left */ + TFA9912_BF_ISTCLPR = + 0x4220, /*!< Status clip */ + TFA9912_BF_ISTOCPM = + 0x4230, /*!< Status mic ocpok */ + TFA9912_BF_ISTLP1 = + 0x4250, /*!< Status low power mode1 */ + TFA9912_BF_ISTLA = + 0x4260, /*!< Status low amplitude detection */ + TFA9912_BF_ISTVDDP = + 0x4270, /*!< Status VDDP greater than VBAT */ + TFA9912_BF_ISTTAPDET = + 0x4280, /*!< Status Tap detected */ + TFA9912_BF_ISTAUDMOD = + 0x4290, /*!< Status Audio Mode activated */ + TFA9912_BF_ISTSAMMOD = + 0x42a0, /*!< Status SAM Mode activated */ + TFA9912_BF_ISTTAPMOD = + 0x42b0, /*!< Status Tap Mode Activated */ + TFA9912_BF_ISTTAPTRG = + 0x42c0, /*!< Status Tap comparator triggered */ + TFA9912_BF_ICLVDDS = + 0x4400, /*!< Clear POR */ + TFA9912_BF_ICLPLLS = + 0x4410, /*!< Clear PLL lock */ + TFA9912_BF_ICLOTDS = + 0x4420, /*!< Clear OTP alarm */ + TFA9912_BF_ICLOVDS = + 0x4430, /*!< Clear OVP alarm */ + TFA9912_BF_ICLUVDS = + 0x4440, /*!< Clear UVP alarm */ + TFA9912_BF_ICLCLKS = + 0x4450, /*!< Clear clocks stable */ + TFA9912_BF_ICLMTPB = + 0x4460, /*!< Clear mtp busy */ + TFA9912_BF_ICLNOCLK = + 0x4470, /*!< Clear lost clk */ + TFA9912_BF_ICLSPKS = + 0x4480, /*!< Clear speaker error */ + TFA9912_BF_ICLACS = + 0x4490, /*!< Clear cold started */ + TFA9912_BF_ICLSWS = + 0x44a0, /*!< Clear amplifier engage */ + TFA9912_BF_ICLWDS = + 0x44b0, /*!< Clear watchdog */ + TFA9912_BF_ICLAMPS = + 0x44c0, /*!< Clear enbl amp */ + TFA9912_BF_ICLAREFS = + 0x44d0, /*!< Clear ref enable */ + TFA9912_BF_ICLADCCR = + 0x44e0, /*!< Clear control ADC */ + TFA9912_BF_ICLBODNOK = + 0x44f0, /*!< Clear BOD */ + TFA9912_BF_ICLBSTCU = + 0x4500, /*!< Clear DCDC current limiting */ + TFA9912_BF_ICLBSTHI = + 0x4510, /*!< Clear DCDC active */ + TFA9912_BF_ICLBSTOC = + 0x4520, /*!< Clear DCDC OCP */ + TFA9912_BF_ICLBSTPC = + 0x4530, /*!< Clear bst peakcur */ + TFA9912_BF_ICLBSTVC = + 0x4540, /*!< Clear DCDC level 1x */ + TFA9912_BF_ICLBST86 = + 0x4550, /*!< Clear DCDC level 1.14x */ + TFA9912_BF_ICLBST93 = + 0x4560, /*!< Clear DCDC level 1.07x */ + TFA9912_BF_ICLRCVLD = + 0x4570, /*!< Clear rcvldop ready */ + TFA9912_BF_ICLOCPL = + 0x4580, /*!< Clear ocp alarm left */ + TFA9912_BF_ICLOCPR = + 0x4590, /*!< Clear ocp alarm */ + TFA9912_BF_ICLMWSRC = + 0x45a0, /*!< Clear wait HW I2C settings */ + TFA9912_BF_ICLMWCFC = + 0x45b0, /*!< Clear wait cf config */ + TFA9912_BF_ICLMWSMU = + 0x45c0, /*!< Clear audio mute sequence */ + TFA9912_BF_ICLCFMER = + 0x45d0, /*!< Clear cfma err */ + TFA9912_BF_ICLCFMAC = + 0x45e0, /*!< Clear cfma ack */ + TFA9912_BF_ICLCLKOOR = + 0x45f0, /*!< Clear flag_clk_out_of_range */ + TFA9912_BF_ICLTDMER = + 0x4600, /*!< Clear tdm error */ + TFA9912_BF_ICLCLPL = + 0x4610, /*!< Clear clip left */ + TFA9912_BF_ICLCLP = + 0x4620, /*!< Clear clip */ + TFA9912_BF_ICLOCPM = + 0x4630, /*!< Clear mic ocpok */ + TFA9912_BF_ICLLP1 = + 0x4650, /*!< Clear low power mode1 */ + TFA9912_BF_ICLLA = + 0x4660, /*!< Clear low amplitude detection */ + TFA9912_BF_ICLVDDP = + 0x4670, /*!< Clear VDDP greater then VBAT */ + TFA9912_BF_ICLTAPDET = + 0x4680, /*!< Clear Tap detected */ + TFA9912_BF_ICLAUDMOD = + 0x4690, /*!< Clear Audio Mode activated */ + TFA9912_BF_ICLSAMMOD = + 0x46a0, /*!< Clear SAM Mode activated */ + TFA9912_BF_ICLTAPMOD = + 0x46b0, /*!< Clear Tap Mode Activated */ + TFA9912_BF_ICLTAPTRG = + 0x46c0, /*!< Clear Comparator Interrupt */ + TFA9912_BF_IEVDDS = + 0x4800, /*!< Enable por */ + TFA9912_BF_IEPLLS = + 0x4810, /*!< Enable pll lock */ + TFA9912_BF_IEOTDS = + 0x4820, /*!< Enable OTP alarm */ + TFA9912_BF_IEOVDS = + 0x4830, /*!< Enable OVP alarm */ + TFA9912_BF_IEUVDS = + 0x4840, /*!< Enable UVP alarm */ + TFA9912_BF_IECLKS = + 0x4850, /*!< Enable clocks stable */ + TFA9912_BF_IEMTPB = + 0x4860, /*!< Enable mtp busy */ + TFA9912_BF_IENOCLK = + 0x4870, /*!< Enable lost clk */ + TFA9912_BF_IESPKS = + 0x4880, /*!< Enable speaker error */ + TFA9912_BF_IEACS = + 0x4890, /*!< Enable cold started */ + TFA9912_BF_IESWS = + 0x48a0, /*!< Enable amplifier engage */ + TFA9912_BF_IEWDS = + 0x48b0, /*!< Enable watchdog */ + TFA9912_BF_IEAMPS = + 0x48c0, /*!< Enable enbl amp */ + TFA9912_BF_IEAREFS = + 0x48d0, /*!< Enable ref enable */ + TFA9912_BF_IEADCCR = + 0x48e0, /*!< Enable Control ADC */ + TFA9912_BF_IEBODNOK = + 0x48f0, /*!< Enable BOD */ + TFA9912_BF_IEBSTCU = + 0x4900, /*!< Enable DCDC current limiting */ + TFA9912_BF_IEBSTHI = + 0x4910, /*!< Enable DCDC active */ + TFA9912_BF_IEBSTOC = + 0x4920, /*!< Enable DCDC OCP */ + TFA9912_BF_IEBSTPC = + 0x4930, /*!< Enable bst peakcur */ + TFA9912_BF_IEBSTVC = + 0x4940, /*!< Enable DCDC level 1x */ + TFA9912_BF_IEBST86 = + 0x4950, /*!< Enable DCDC level 1.14x */ + TFA9912_BF_IEBST93 = + 0x4960, /*!< Enable DCDC level 1.07x */ + TFA9912_BF_IERCVLD = + 0x4970, /*!< Enable rcvldop ready */ + TFA9912_BF_IEOCPL = + 0x4980, /*!< Enable ocp alarm left */ + TFA9912_BF_IEOCPR = + 0x4990, /*!< Enable ocp alarm */ + TFA9912_BF_IEMWSRC = + 0x49a0, /*!< Enable waits HW I2C settings */ + TFA9912_BF_IEMWCFC = + 0x49b0, /*!< Enable man wait cf config */ + TFA9912_BF_IEMWSMU = + 0x49c0, /*!< Enable man Audio mute sequence */ + TFA9912_BF_IECFMER = + 0x49d0, /*!< Enable cfma err */ + TFA9912_BF_IECFMAC = + 0x49e0, /*!< Enable cfma ack */ + TFA9912_BF_IECLKOOR = + 0x49f0, /*!< Enable flag_clk_out_of_range */ + TFA9912_BF_IETDMER = + 0x4a00, /*!< Enable tdm error */ + TFA9912_BF_IECLPL = + 0x4a10, /*!< Enable clip left */ + TFA9912_BF_IECLPR = + 0x4a20, /*!< Enable clip */ + TFA9912_BF_IEOCPM1 = + 0x4a30, /*!< Enable mic ocpok */ + TFA9912_BF_IELP1 = + 0x4a50, /*!< Enable low power mode1 */ + TFA9912_BF_IELA = + 0x4a60, /*!< Enable low amplitude detection */ + TFA9912_BF_IEVDDP = + 0x4a70, /*!< Enable VDDP greater than VBAT */ + TFA9912_BF_IETAPDET = + 0x4a80, /*!< Enable Tap detected */ + TFA9912_BF_IEAUDMOD = + 0x4a90, /*!< Enable Audio Mode activated */ + TFA9912_BF_IESAMMOD = + 0x4aa0, /*!< Enable SAM Mode activated */ + TFA9912_BF_IETAPMOD = + 0x4ab0, /*!< Enable Tap Mode Activated */ + TFA9912_BF_IETAPTRG = + 0x4ac0, /*!< Enable comparator interrupt */ + TFA9912_BF_IPOVDDS = + 0x4c00, /*!< Polarity por */ + TFA9912_BF_IPOPLLS = + 0x4c10, /*!< Polarity pll lock */ + TFA9912_BF_IPOOTDS = + 0x4c20, /*!< Polarity OTP alarm */ + TFA9912_BF_IPOOVDS = + 0x4c30, /*!< Polarity OVP alarm */ + TFA9912_BF_IPOUVDS = + 0x4c40, /*!< Polarity UVP alarm */ + TFA9912_BF_IPOCLKS = + 0x4c50, /*!< Polarity clocks stable */ + TFA9912_BF_IPOMTPB = + 0x4c60, /*!< Polarity mtp busy */ + TFA9912_BF_IPONOCLK = + 0x4c70, /*!< Polarity lost clk */ + TFA9912_BF_IPOSPKS = + 0x4c80, /*!< Polarity speaker error */ + TFA9912_BF_IPOACS = + 0x4c90, /*!< Polarity cold started */ + TFA9912_BF_IPOSWS = + 0x4ca0, /*!< Polarity amplifier engage */ + TFA9912_BF_IPOWDS = + 0x4cb0, /*!< Polarity watchdog */ + TFA9912_BF_IPOAMPS = + 0x4cc0, /*!< Polarity enbl amp */ + TFA9912_BF_IPOAREFS = + 0x4cd0, /*!< Polarity ref enable */ + TFA9912_BF_IPOADCCR = + 0x4ce0, /*!< Polarity Control ADC */ + TFA9912_BF_IPOBODNOK = + 0x4cf0, /*!< Polarity BOD */ + TFA9912_BF_IPOBSTCU = + 0x4d00, /*!< Polarity DCDC current limiting */ + TFA9912_BF_IPOBSTHI = + 0x4d10, /*!< Polarity DCDC active */ + TFA9912_BF_IPOBSTOC = + 0x4d20, /*!< Polarity DCDC OCP */ + TFA9912_BF_IPOBSTPC = + 0x4d30, /*!< Polarity bst peakcur */ + TFA9912_BF_IPOBSTVC = + 0x4d40, /*!< Polarity DCDC level 1x */ + TFA9912_BF_IPOBST86 = + 0x4d50, /*!< Polarity DCDC level 1.14x */ + TFA9912_BF_IPOBST93 = + 0x4d60, /*!< Polarity DCDC level 1.07x */ + TFA9912_BF_IPORCVLD = + 0x4d70, /*!< Polarity rcvldop ready */ + TFA9912_BF_IPOOCPL = + 0x4d80, /*!< Polarity ocp alarm left */ + TFA9912_BF_IPOOCPR = + 0x4d90, /*!< Polarity ocp alarm */ + TFA9912_BF_IPOMWSRC = + 0x4da0, /*!< Polarity waits HW I2C settings */ + TFA9912_BF_IPOMWCFC = + 0x4db0, /*!< Polarity man wait cf config */ + TFA9912_BF_IPOMWSMU = + 0x4dc0, /*!< Polarity man audio mute sequence */ + TFA9912_BF_IPOCFMER = + 0x4dd0, /*!< Polarity cfma err */ + TFA9912_BF_IPOCFMAC = + 0x4de0, /*!< Polarity cfma ack */ + TFA9912_BF_IPOCLKOOR = + 0x4df0, /*!< Polarity flag_clk_out_of_range */ + TFA9912_BF_IPOTDMER = + 0x4e00, /*!< Polarity tdm error */ + TFA9912_BF_IPOCLPL = + 0x4e10, /*!< Polarity clip left */ + TFA9912_BF_IPOCLPR = + 0x4e20, /*!< Polarity clip */ + TFA9912_BF_IPOOCPM = + 0x4e30, /*!< Polarity mic ocpok */ + TFA9912_BF_IPOLP1 = + 0x4e50, /*!< Polarity low power mode1 */ + TFA9912_BF_IPOLA = + 0x4e60, /*!< Polarity low amplitude detection */ + TFA9912_BF_IPOVDDP = + 0x4e70, /*!< Polarity VDDP greater than VBAT */ + TFA9912_BF_IPOLTAPDET = + 0x4e80, /*!< PolarityTap detected */ + TFA9912_BF_IPOLAUDMOD = + 0x4e90, /*!< PolarityAudio Mode activated */ + TFA9912_BF_IPOLSAMMOD = + 0x4ea0, /*!< PolaritySAM Mode activated */ + TFA9912_BF_IPOLTAPMOD = + 0x4eb0, /*!< Polarity Tap Mode Activated */ + TFA9912_BF_IPOLTAPTRG = + 0x4ec0, /*!< PolarityTap Comparator Trigger */ + TFA9912_BF_BSSCR = + 0x5001, /*!< Battery Safeguard attack time */ + TFA9912_BF_BSST = + 0x5023, /*!< Battery Safeguard threshold voltage level */ + TFA9912_BF_BSSRL = + 0x5061, /*!< Battery Safeguard maximum reduction */ + TFA9912_BF_BSSRR = + 0x5082, /*!< Battery Safeguard release time */ + TFA9912_BF_BSSHY = + 0x50b1, /*!< Battery Safeguard hysteresis */ + TFA9912_BF_BSSAC = + 0x50d0, /*!< Reset clipper - Auto clear */ + TFA9912_BF_BSSR = + 0x50e0, /*!< Battery voltage read out */ + TFA9912_BF_BSSBY = + 0x50f0, /*!< Bypass HW clipper */ + TFA9912_BF_BSSS = + 0x5100, /*!< Vbat prot steepness */ + TFA9912_BF_INTSMUTE = + 0x5110, /*!< Soft mute HW */ + TFA9912_BF_CFSML = + 0x5120, /*!< Soft mute FW left */ + TFA9912_BF_CFSM = + 0x5130, /*!< Soft mute FW */ + TFA9912_BF_HPFBYPL = + 0x5140, /*!< Bypass HPF left */ + TFA9912_BF_HPFBYP = + 0x5150, /*!< Bypass HPF */ + TFA9912_BF_DPSAL = + 0x5160, /*!< Enable DPSA left */ + TFA9912_BF_DPSA = + 0x5170, /*!< Enable DPSA */ + TFA9912_BF_VOL = + 0x5187, /*!< FW volume control for primary audio channel */ + TFA9912_BF_HNDSFRCV = + 0x5200, /*!< Selection receiver */ + TFA9912_BF_CLIPCTRL = + 0x5222, /*!< Clip control setting */ + TFA9912_BF_AMPGAIN = + 0x5257, /*!< Amplifier gain */ + TFA9912_BF_SLOPEE = + 0x52d0, /*!< Enables slope control */ + TFA9912_BF_SLOPESET = + 0x52e0, /*!< Slope speed setting (bin. coded) */ + TFA9912_BF_CFTAPPAT = + 0x5c07, /*!< Coolflux tap pattern */ + TFA9912_BF_TAPDBGINFO = + 0x5c83, /*!< Reserved */ + TFA9912_BF_TATPSTAT1 = + 0x5d0f, /*!< Tap Status 1 from CF FW */ + TFA9912_BF_TCOMPTHR = + 0x5f03, /*!< Comparator threshold (in uV) */ + TFA9912_BF_PGAGAIN = + 0x6081, /*!< PGA gain selection */ + TFA9912_BF_TDMSPKG = + 0x6123, /*!< System gain (INPLEV 0) */ + TFA9912_BF_LPM1LVL = + 0x6505, /*!< low power mode1 detector ctrl threshold for low_audio_lvl */ + TFA9912_BF_LPM1HLD = + 0x6565, /*!< Low power mode1 detector, ctrl hold time before low audio is reckoned to be low audio */ + TFA9912_BF_LPM1DIS = + 0x65c0, /*!< low power mode1 detector control */ + TFA9912_BF_DCDIS = + 0x6630, /*!< DCDC */ + TFA9912_BF_TDMSRCMAP = + 0x6801, /*!< tdm source mapping */ + TFA9912_BF_TDMSRCAS = + 0x6821, /*!< frame a selection */ + TFA9912_BF_TDMSRCBS = + 0x6841, /*!< frame b selection */ + TFA9912_BF_ANC1C = + 0x68a0, /*!< ANC one s complement */ + TFA9912_BF_SAMMODE = + 0x6901, /*!< Sam mode */ + TFA9912_BF_DCMCC = + 0x7033, /*!< Max coil current */ + TFA9912_BF_DCCV = + 0x7071, /*!< Slope compensation current, represents LxF (inductance x frequency) value */ + TFA9912_BF_DCIE = + 0x7090, /*!< Adaptive boost mode */ + TFA9912_BF_DCSR = + 0x70a0, /*!< Soft ramp up/down */ + TFA9912_BF_DCINSEL = + 0x70c1, /*!< DCDC IIR input Selection */ + TFA9912_BF_DCPWM = + 0x70f0, /*!< DCDC PWM only mode */ + TFA9912_BF_DCTRIP = + 0x7504, /*!< Adaptive boost trip levels 1, effective only when boost_intelligent is set to 1 */ + TFA9912_BF_DCTRIP2 = + 0x7554, /*!< Adaptive boost trip level 2, effective only when boost_intelligent is set to 1 */ + TFA9912_BF_DCTRIPT = + 0x75a4, /*!< Adaptive boost trip levels, effective only when boost_intelligent is set to 1 */ + TFA9912_BF_DCVOF = + 0x7635, /*!< First boost voltage level */ + TFA9912_BF_DCVOS = + 0x7695, /*!< Second boost voltage level */ + TFA9912_BF_RST = + 0x9000, /*!< Reset */ + TFA9912_BF_DMEM = + 0x9011, /*!< Target memory */ + TFA9912_BF_AIF = + 0x9030, /*!< Auto increment */ + TFA9912_BF_CFINT = + 0x9040, /*!< Interrupt - auto clear */ + TFA9912_BF_CFCGATE = + 0x9050, /*!< Coolflux clock gating disabling control */ + TFA9912_BF_REQCMD = + 0x9080, /*!< Firmware event request rpc command */ + TFA9912_BF_REQRST = + 0x9090, /*!< Firmware event request reset restart */ + TFA9912_BF_REQMIPS = + 0x90a0, /*!< Firmware event request short on mips */ + TFA9912_BF_REQMUTED = + 0x90b0, /*!< Firmware event request mute sequence ready */ + TFA9912_BF_REQVOL = + 0x90c0, /*!< Firmware event request volume ready */ + TFA9912_BF_REQDMG = + 0x90d0, /*!< Firmware event request speaker damage detected */ + TFA9912_BF_REQCAL = + 0x90e0, /*!< Firmware event request calibration completed */ + TFA9912_BF_REQRSV = + 0x90f0, /*!< Firmware event request reserved */ + TFA9912_BF_MADD = + 0x910f, /*!< Memory address */ + TFA9912_BF_MEMA = + 0x920f, /*!< Activate memory access */ + TFA9912_BF_ERR = + 0x9307, /*!< Error flags */ + TFA9912_BF_ACKCMD = + 0x9380, /*!< Firmware event acknowledge rpc command */ + TFA9912_BF_ACKRST = + 0x9390, /*!< Firmware event acknowledge reset restart */ + TFA9912_BF_ACKMIPS = + 0x93a0, /*!< Firmware event acknowledge short on mips */ + TFA9912_BF_ACKMUTED = + 0x93b0, /*!< Firmware event acknowledge mute sequence ready */ + TFA9912_BF_ACKVOL = + 0x93c0, /*!< Firmware event acknowledge volume ready */ + TFA9912_BF_ACKDMG = + 0x93d0, /*!< Firmware event acknowledge speaker damage detected */ + TFA9912_BF_ACKCAL = + 0x93e0, /*!< Firmware event acknowledge calibration completed */ + TFA9912_BF_ACKRSV = + 0x93f0, /*!< Firmware event acknowledge reserved */ + TFA9912_BF_MTPK = + 0xa107, /*!< MTP KEY2 register */ + TFA9912_BF_KEY1LOCKED = + 0xa200, /*!< Indicates KEY1 is locked */ + TFA9912_BF_KEY2LOCKED = + 0xa210, /*!< Indicates KEY2 is locked */ + TFA9912_BF_CIMTP = + 0xa360, /*!< Start copying data from I2C mtp registers to mtp */ + TFA9912_BF_MTPRDMSB = + 0xa50f, /*!< MSB word of MTP manual read data */ + TFA9912_BF_MTPRDLSB = + 0xa60f, /*!< LSB word of MTP manual read data */ + TFA9912_BF_EXTTS = + 0xb108, /*!< External temperature (C) */ + TFA9912_BF_TROS = + 0xb190, /*!< Select temp Speaker calibration */ + TFA9912_BF_SWPROFIL = + 0xee0f, /*!< Software profile data */ + TFA9912_BF_SWVSTEP = + 0xef0f, /*!< Software vstep information */ + TFA9912_BF_MTPOTC = + 0xf000, /*!< Calibration schedule */ + TFA9912_BF_MTPEX = + 0xf010, /*!< Calibration Ron executed */ + TFA9912_BF_DCMCCAPI = + 0xf020, /*!< Calibration current limit DCDC */ + TFA9912_BF_DCMCCSB = + 0xf030, /*!< Sign bit for delta calibration current limit DCDC */ + TFA9912_BF_DCMCCCL = + 0xf042, /*!< Calibration delta current limit DCDC */ + TFA9912_BF_USERDEF = + 0xf078, /*!< Reserved space for allowing customer to store speaker information */ + TFA9912_BF_R25C = + 0xf40f, /*!< Ron resistance of speaker coil */ +} nxpTfa9912BfEnumList_t; +#define TFA9912_NAMETABLE \ + static tfaBfName_t Tfa9912DatasheetNames[] = { \ + { 0x0, \ + "PWDN" }, /* Powerdown selection , */ \ + { 0x10, \ + "I2CR" }, /* I2C Reset - Auto clear , */ \ + { 0x20, \ + "CFE" }, /* Enable CoolFlux , */ \ + { 0x30, \ + "AMPE" }, /* Enables the Amplifier , */ \ + { 0x40, \ + "DCA" }, /* Activate DC-to-DC converter , */ \ + { 0x50, \ + "SBSL" }, /* Coolflux configured , */ \ + { 0x60, \ + "AMPC" }, /* CoolFlux controls amplifier , */ \ + { 0x71, \ + "INTP" }, /* Interrupt config , */ \ + { 0x90, \ + "FSSSEL" }, /* Audio sample reference , */ \ + { 0xb0, \ + "BYPOCP" }, /* Bypass OCP , */ \ + { 0xc0, \ + "TSTOCP" }, /* OCP testing control , */ \ + { 0x101, \ + "AMPINSEL" }, /* Amplifier input selection , */ \ + { 0x120, \ + "MANSCONF" }, /* I2C configured , */ \ + { 0x130, \ + "MANCOLD" }, /* Execute cold start , */ \ + { 0x140, \ + "MANAOOSC" }, /* Internal osc off at PWDN , */ \ + { 0x150, \ + "MANROBOD" }, /* Reaction on BOD , */ \ + { 0x160, \ + "BODE" }, /* BOD Enable , */ \ + { 0x170, \ + "BODHYS" }, /* BOD Hysteresis , */ \ + { 0x181, \ + "BODFILT" }, /* BOD filter , */ \ + { 0x1a1, \ + "BODTHLVL" }, /* BOD threshold , */ \ + { 0x1d0, \ + "MUTETO" }, /* Time out SB mute sequence , */ \ + { 0x1e0, \ + "RCVNS" }, /* Noise shaper selection , */ \ + { 0x1f0, \ + "MANWDE" }, /* Watchdog enable , */ \ + { 0x203, \ + "AUDFS" }, /* Sample rate (fs) , */ \ + { 0x240, \ + "INPLEV" }, /* TDM output attenuation , */ \ + { 0x255, \ + "FRACTDEL" }, /* V/I Fractional delay , */ \ + { 0x2b0, \ + "BYPHVBF" }, /* Bypass HVBAT filter , */ \ + { 0x2c0, \ + "TDMC" }, /* TDM Compatibility with TFA9872 , */ \ + { 0x2e0, \ + "ENBLADC10" }, /* ADC10 Enable - I2C direct mode , */ \ + { 0x30f, \ + "REV" }, /* Revision info , */ \ + { 0x401, \ + "REFCKEXT" }, /* PLL external ref clock , */ \ + { 0x420, \ + "REFCKSEL" }, /* PLL internal ref clock , */ \ + { 0x430, \ + "ENCFCKSEL" }, /* Coolflux DSP clock scaling, low power mode , */ \ + { 0x441, \ + "CFCKSEL" }, /* Coolflux DSP clock scaler selection for low power mode, */ \ + { 0x460, \ + "TDMINFSEL" }, /* TDM clock selection , */ \ + { 0x470, \ + "DISBLAUTOCLKSEL" }, /* Disable Automatic dsp clock source selection , */ \ + { 0x480, \ + "SELCLKSRC" }, /* I2C selection of DSP clock when auto select is disabled, */ \ + { 0x490, \ + "SELTIMSRC" }, /* I2C selection of Watchdog and Timer clock , */ \ + { 0x500, \ + "SSLEFTE" }, /* , */ \ + { 0x510, \ + "SPKSSEN" }, /* Enable speaker path , */ \ + { 0x520, \ + "VSLEFTE" }, /* , */ \ + { 0x530, \ + "VSRIGHTE" }, /* Voltage sense , */ \ + { 0x540, \ + "CSLEFTE" }, /* , */ \ + { 0x550, \ + "CSRIGHTE" }, /* Current sense , */ \ + { 0x560, \ + "SSPDME" }, /* Sub-system PDM , */ \ + { 0x570, \ + "PGALE" }, /* Enable PGA chop clock for left channel , */ \ + { 0x580, \ + "PGARE" }, /* Enable PGA chop clock , */ \ + { 0x590, \ + "SSTDME" }, /* Sub-system TDM , */ \ + { 0x5a0, \ + "SSPBSTE" }, /* Sub-system boost , */ \ + { 0x5b0, \ + "SSADCE" }, /* Sub-system ADC , */ \ + { 0x5c0, \ + "SSFAIME" }, /* Sub-system FAIM , */ \ + { 0x5d0, \ + "SSCFTIME" }, /* CF Sub-system timer , */ \ + { 0x5e0, \ + "SSCFWDTE" }, /* CF Sub-system WDT , */ \ + { 0x5f0, \ + "FAIMVBGOVRRL" }, /* Over rule of vbg for FaIM access , */ \ + { 0x600, \ + "SAMSPKSEL" }, /* Input selection for TAP/SAM , */ \ + { 0x610, \ + "PDM2IISEN" }, /* PDM2IIS Bridge enable , */ \ + { 0x620, \ + "TAPRSTBYPASS" }, /* Tap decimator reset bypass - Bypass the decimator reset from tapdec, */ \ + { 0x631, \ + "CARDECISEL0" }, /* Cardec input 0 sel , */ \ + { 0x651, \ + "CARDECISEL1" }, /* Cardec input sel , */ \ + { 0x670, \ + "TAPDECSEL" }, /* Select TAP/Cardec for TAP , */ \ + { 0x680, \ + "COMPCOUNT" }, /* Comparator o/p filter selection , */ \ + { 0x691, \ + "STARTUPMODE" }, /* Startup Mode Selection , */ \ + { 0x6b0, \ + "AUTOTAP" }, /* Enable auto tap switching , */ \ + { 0x6c1, \ + "COMPINITIME" }, /* Comparator initialization time to be used in Tap Machine, */ \ + { 0x6e1, \ + "ANAPINITIME" }, /* Analog initialization time to be used in Tap Machine, */ \ + { 0x707, \ + "CCHKTH" }, /* Clock check Higher Threshold , */ \ + { 0x787, \ + "CCHKTL" }, /* Clock check Higher Threshold , */ \ + { 0x802, \ + "AMPOCRT" }, /* Amplifier on-off criteria for shutdown , */ \ + { 0x832, \ + "AMPTCRR" }, /* Amplifier on-off criteria for tap mode entry , */ \ + { 0xd00, \ + "STGS" }, /* PDM side tone gain selector , */ \ + { 0xd18, \ + "STGAIN" }, /* Side tone gain , */ \ + { 0xda0, \ + "STSMUTE" }, /* Side tone soft mute , */ \ + { 0xdb0, \ + "ST1C" }, /* side tone one s complement , */ \ + { 0xe80, \ + "CMFBEL" }, /* CMFB enable left , */ \ + { 0x1000, \ + "VDDS" }, /* POR , */ \ + { 0x1010, \ + "PLLS" }, /* PLL lock , */ \ + { 0x1020, \ + "OTDS" }, /* OTP alarm , */ \ + { 0x1030, \ + "OVDS" }, /* OVP alarm , */ \ + { 0x1040, \ + "UVDS" }, /* UVP alarm , */ \ + { 0x1050, \ + "CLKS" }, /* Clocks stable , */ \ + { 0x1060, \ + "MTPB" }, /* MTP busy , */ \ + { 0x1070, \ + "NOCLK" }, /* Lost clock , */ \ + { 0x1090, \ + "ACS" }, /* Cold Start , */ \ + { 0x10a0, \ + "SWS" }, /* Amplifier engage , */ \ + { 0x10b0, \ + "WDS" }, /* Watchdog , */ \ + { 0x10c0, \ + "AMPS" }, /* Amplifier enable , */ \ + { 0x10d0, \ + "AREFS" }, /* References enable , */ \ + { 0x10e0, \ + "ADCCR" }, /* Control ADC , */ \ + { 0x10f0, \ + "BODNOK" }, /* BOD , */ \ + { 0x1100, \ + "DCIL" }, /* DCDC current limiting , */ \ + { 0x1110, \ + "DCDCA" }, /* DCDC active , */ \ + { 0x1120, \ + "DCOCPOK" }, /* DCDC OCP nmos , */ \ + { 0x1130, \ + "DCPEAKCUR" }, /* Indicates current is max in DC-to-DC converter , */ \ + { 0x1140, \ + "DCHVBAT" }, /* DCDC level 1x , */ \ + { 0x1150, \ + "DCH114" }, /* DCDC level 1.14x , */ \ + { 0x1160, \ + "DCH107" }, /* DCDC level 1.07x , */ \ + { 0x1170, \ + "STMUTEB" }, /* side tone (un)mute busy , */ \ + { 0x1180, \ + "STMUTE" }, /* side tone mute state , */ \ + { 0x1190, \ + "TDMLUTER" }, /* TDM LUT error , */ \ + { 0x11a2, \ + "TDMSTAT" }, /* TDM status bits , */ \ + { 0x11d0, \ + "TDMERR" }, /* TDM error , */ \ + { 0x11e0, \ + "HAPTIC" }, /* Status haptic driver , */ \ + { 0x1300, \ + "OCPOAP" }, /* OCPOK pmos A , */ \ + { 0x1310, \ + "OCPOAN" }, /* OCPOK nmos A , */ \ + { 0x1320, \ + "OCPOBP" }, /* OCPOK pmos B , */ \ + { 0x1330, \ + "OCPOBN" }, /* OCPOK nmos B , */ \ + { 0x1340, \ + "CLIPAH" }, /* Clipping A to Vddp , */ \ + { 0x1350, \ + "CLIPAL" }, /* Clipping A to gnd , */ \ + { 0x1360, \ + "CLIPBH" }, /* Clipping B to Vddp , */ \ + { 0x1370, \ + "CLIPBL" }, /* Clipping B to gnd , */ \ + { 0x1380, \ + "OCDS" }, /* OCP amplifier , */ \ + { 0x1390, \ + "CLIPS" }, /* Amplifier clipping , */ \ + { 0x13a0, \ + "TCMPTRG" }, /* Status Tap comparator triggered , */ \ + { 0x13b0, \ + "TAPDET" }, /* Status Tap detected , */ \ + { 0x13c0, \ + "MANWAIT1" }, /* Wait HW I2C settings , */ \ + { 0x13d0, \ + "MANWAIT2" }, /* Wait CF config , */ \ + { 0x13e0, \ + "MANMUTE" }, /* Audio mute sequence , */ \ + { 0x13f0, \ + "MANOPER" }, /* Operating state , */ \ + { 0x1400, \ + "SPKSL" }, /* Left speaker status , */ \ + { 0x1410, \ + "SPKS" }, /* Speaker status , */ \ + { 0x1420, \ + "CLKOOR" }, /* External clock status , */ \ + { 0x1433, \ + "MANSTATE" }, /* Device manager status , */ \ + { 0x1471, \ + "DCMODE" }, /* DCDC mode status bits , */ \ + { 0x1490, \ + "DSPCLKSRC" }, /* DSP clock source selected by manager , */ \ + { 0x14a1, \ + "STARTUPMODSTAT" }, /* Startup Mode Selected by Manager(Read Only) , */ \ + { 0x14c3, \ + "TSPMSTATE" }, /* Tap Machine State , */ \ + { 0x1509, \ + "BATS" }, /* Battery voltage (V) , */ \ + { 0x1608, \ + "TEMPS" }, /* IC Temperature (C) , */ \ + { 0x1709, \ + "VDDPS" }, /* IC VDDP voltage ( 1023*VDDP/13 V) , */ \ + { 0x17a0, \ + "DCILCF" }, /* DCDC current limiting for DSP , */ \ + { 0x2000, \ + "TDMUC" }, /* Mode setting , */ \ + { 0x2011, \ + "DIO4SEL" }, /* DIO4 Input selection , */ \ + { 0x2040, \ + "TDME" }, /* Enable TDM interface , */ \ + { 0x2050, \ + "TDMMODE" }, /* Slave/master , */ \ + { 0x2060, \ + "TDMCLINV" }, /* Reception data to BCK clock , */ \ + { 0x2073, \ + "TDMFSLN" }, /* FS length , */ \ + { 0x20b0, \ + "TDMFSPOL" }, /* FS polarity , */ \ + { 0x20c3, \ + "TDMNBCK" }, /* N-BCK's in FS , */ \ + { 0x2103, \ + "TDMSLOTS" }, /* N-slots in Frame , */ \ + { 0x2144, \ + "TDMSLLN" }, /* N-bits in slot , */ \ + { 0x2194, \ + "TDMBRMG" }, /* N-bits remaining , */ \ + { 0x21e0, \ + "TDMDEL" }, /* data delay to FS , */ \ + { 0x21f0, \ + "TDMADJ" }, /* data adjustment , */ \ + { 0x2201, \ + "TDMOOMP" }, /* Received audio compression , */ \ + { 0x2224, \ + "TDMSSIZE" }, /* Sample size per slot , */ \ + { 0x2271, \ + "TDMTXDFO" }, /* Format unused bits in a slot , */ \ + { 0x2291, \ + "TDMTXUS0" }, /* Format unused slots GAINIO , */ \ + { 0x22b1, \ + "TDMTXUS1" }, /* Format unused slots DIO1 , */ \ + { 0x22d1, \ + "TDMTXUS2" }, /* Format unused slots DIO2 , */ \ + { 0x2300, \ + "TDMGIE" }, /* Control gain (channel in 0) , */ \ + { 0x2310, \ + "TDMDCE" }, /* Control audio left (channel in 1 ) , */ \ + { 0x2320, \ + "TDMSPKE" }, /* Control audio right (channel in 2 ) , */ \ + { 0x2330, \ + "TDMCSE" }, /* Current sense , */ \ + { 0x2340, \ + "TDMVSE" }, /* Voltage sense , */ \ + { 0x2350, \ + "TDMGOE" }, /* DSP Gainout , */ \ + { 0x2360, \ + "TDMCF2E" }, /* DSP 2 , */ \ + { 0x2370, \ + "TDMCF3E" }, /* DSP 3 , */ \ + { 0x2380, \ + "TDMCFE" }, /* DSP , */ \ + { 0x2390, \ + "TDMES6" }, /* Loopback of Audio left (channel 1) , */ \ + { 0x23a0, \ + "TDMES7" }, /* Loopback of Audio right (channel 2) , */ \ + { 0x23b0, \ + "TDMCF4E" }, /* AEC ref right control , */ \ + { 0x23c0, \ + "TDMPD1E" }, /* PDM 1 control , */ \ + { 0x23d0, \ + "TDMPD2E" }, /* PDM 2 control , */ \ + { 0x2401, \ + "TDMGIN" }, /* IO gainin , */ \ + { 0x2421, \ + "TDMLIO" }, /* IO audio left , */ \ + { 0x2441, \ + "TDMRIO" }, /* IO audio right , */ \ + { 0x2461, \ + "TDMCSIO" }, /* IO Current Sense , */ \ + { 0x2481, \ + "TDMVSIO" }, /* IO voltage sense , */ \ + { 0x24a1, \ + "TDMGOIO" }, /* IO gain out , */ \ + { 0x24c1, \ + "TDMCFIO2" }, /* IO DSP 2 , */ \ + { 0x24e1, \ + "TDMCFIO3" }, /* IO DSP 3 , */ \ + { 0x2501, \ + "TDMCFIO" }, /* IO DSP , */ \ + { 0x2521, \ + "TDMLPB6" }, /* IO Source 6 , */ \ + { 0x2541, \ + "TDMLPB7" }, /* IO Source 7 , */ \ + { 0x2603, \ + "TDMGS" }, /* Control gainin , */ \ + { 0x2643, \ + "TDMDCS" }, /* tdm slot for audio left (channel 1) , */ \ + { 0x2683, \ + "TDMSPKS" }, /* tdm slot for audio right (channel 2) , */ \ + { 0x26c3, \ + "TDMCSS" }, /* Slot Position of Current Sense Out , */ \ + { 0x2703, \ + "TDMVSS" }, /* Slot Position of Voltage sense , */ \ + { 0x2743, \ + "TDMCGOS" }, /* Slot Position of GAIN out , */ \ + { 0x2783, \ + "TDMCF2S" }, /* Slot Position DSPout2 , */ \ + { 0x27c3, \ + "TDMCF3S" }, /* Slot Position DSPout3 , */ \ + { 0x2803, \ + "TDMCFS" }, /* Slot Position of DSPout , */ \ + { 0x2843, \ + "TDMEDAT6S" }, /* Slot Position of loopback channel left , */ \ + { 0x2883, \ + "TDMEDAT7S" }, /* Slot Position of loopback channel right , */ \ + { 0x2901, \ + "TDMTXUS3" }, /* Format unused slots D3 , */ \ + { 0x3100, \ + "PDMSM" }, /* PDM control , */ \ + { 0x3110, \ + "PDMSTSEL" }, /* PDM Decimator input selection , */ \ + { 0x3120, \ + "PDMSTENBL" }, /* Side tone input enable , */ \ + { 0x3130, \ + "PDMLSEL" }, /* PDM data selection for left channel during PDM direct mode, */ \ + { 0x3140, \ + "PDMRSEL" }, /* PDM data selection for right channel during PDM direct mode, */ \ + { 0x3150, \ + "MICVDDE" }, /* Enable MICVDD , */ \ + { 0x3201, \ + "PDMCLRAT" }, /* PDM BCK/Fs ratio , */ \ + { 0x3223, \ + "PDMGAIN" }, /* PDM gain , */ \ + { 0x3263, \ + "PDMOSEL" }, /* PDM output selection - RE/FE data combination , */ \ + { 0x32a0, \ + "SELCFHAPD" }, /* Select the source for haptic data output (not for customer), */ \ + { 0x4000, \ + "ISTVDDS" }, /* Status POR , */ \ + { 0x4010, \ + "ISTPLLS" }, /* Status PLL lock , */ \ + { 0x4020, \ + "ISTOTDS" }, /* Status OTP alarm , */ \ + { 0x4030, \ + "ISTOVDS" }, /* Status OVP alarm , */ \ + { 0x4040, \ + "ISTUVDS" }, /* Status UVP alarm , */ \ + { 0x4050, \ + "ISTCLKS" }, /* Status clocks stable , */ \ + { 0x4060, \ + "ISTMTPB" }, /* Status MTP busy , */ \ + { 0x4070, \ + "ISTNOCLK" }, /* Status lost clock , */ \ + { 0x4080, \ + "ISTSPKS" }, /* Status speaker error , */ \ + { 0x4090, \ + "ISTACS" }, /* Status cold start , */ \ + { 0x40a0, \ + "ISTSWS" }, /* Status amplifier engage , */ \ + { 0x40b0, \ + "ISTWDS" }, /* Status watchdog , */ \ + { 0x40c0, \ + "ISTAMPS" }, /* Status amplifier enable , */ \ + { 0x40d0, \ + "ISTAREFS" }, /* Status Ref enable , */ \ + { 0x40e0, \ + "ISTADCCR" }, /* Status Control ADC , */ \ + { 0x40f0, \ + "ISTBODNOK" }, /* Status BOD , */ \ + { 0x4100, \ + "ISTBSTCU" }, /* Status DCDC current limiting , */ \ + { 0x4110, \ + "ISTBSTHI" }, /* Status DCDC active , */ \ + { 0x4120, \ + "ISTBSTOC" }, /* Status DCDC OCP , */ \ + { 0x4130, \ + "ISTBSTPKCUR" }, /* Status bst peakcur , */ \ + { 0x4140, \ + "ISTBSTVC" }, /* Status DCDC level 1x , */ \ + { 0x4150, \ + "ISTBST86" }, /* Status DCDC level 1.14x , */ \ + { 0x4160, \ + "ISTBST93" }, /* Status DCDC level 1.07x , */ \ + { 0x4170, \ + "ISTRCVLD" }, /* Status rcvldop ready , */ \ + { 0x4180, \ + "ISTOCPL" }, /* Status ocp alarm left , */ \ + { 0x4190, \ + "ISTOCPR" }, /* Status ocp alarm , */ \ + { 0x41a0, \ + "ISTMWSRC" }, /* Status Waits HW I2C settings , */ \ + { 0x41b0, \ + "ISTMWCFC" }, /* Status waits CF config , */ \ + { 0x41c0, \ + "ISTMWSMU" }, /* Status Audio mute sequence , */ \ + { 0x41d0, \ + "ISTCFMER" }, /* Status cfma error , */ \ + { 0x41e0, \ + "ISTCFMAC" }, /* Status cfma ack , */ \ + { 0x41f0, \ + "ISTCLKOOR" }, /* Status flag_clk_out_of_range , */ \ + { 0x4200, \ + "ISTTDMER" }, /* Status tdm error , */ \ + { 0x4210, \ + "ISTCLPL" }, /* Status clip left , */ \ + { 0x4220, \ + "ISTCLPR" }, /* Status clip , */ \ + { 0x4230, \ + "ISTOCPM" }, /* Status mic ocpok , */ \ + { 0x4250, \ + "ISTLP1" }, /* Status low power mode1 , */ \ + { 0x4260, \ + "ISTLA" }, /* Status low amplitude detection , */ \ + { 0x4270, \ + "ISTVDDP" }, /* Status VDDP greater than VBAT , */ \ + { 0x4280, \ + "ISTTAPDET" }, /* Status Tap detected , */ \ + { 0x4290, \ + "ISTAUDMOD" }, /* Status Audio Mode activated , */ \ + { 0x42a0, \ + "ISTSAMMOD" }, /* Status SAM Mode activated , */ \ + { 0x42b0, \ + "ISTTAPMOD" }, /* Status Tap Mode Activated , */ \ + { 0x42c0, \ + "ISTTAPTRG" }, /* Status Tap comparator triggered , */ \ + { 0x4400, \ + "ICLVDDS" }, /* Clear POR , */ \ + { 0x4410, \ + "ICLPLLS" }, /* Clear PLL lock , */ \ + { 0x4420, \ + "ICLOTDS" }, /* Clear OTP alarm , */ \ + { 0x4430, \ + "ICLOVDS" }, /* Clear OVP alarm , */ \ + { 0x4440, \ + "ICLUVDS" }, /* Clear UVP alarm , */ \ + { 0x4450, \ + "ICLCLKS" }, /* Clear clocks stable , */ \ + { 0x4460, \ + "ICLMTPB" }, /* Clear mtp busy , */ \ + { 0x4470, \ + "ICLNOCLK" }, /* Clear lost clk , */ \ + { 0x4480, \ + "ICLSPKS" }, /* Clear speaker error , */ \ + { 0x4490, \ + "ICLACS" }, /* Clear cold started , */ \ + { 0x44a0, \ + "ICLSWS" }, /* Clear amplifier engage , */ \ + { 0x44b0, \ + "ICLWDS" }, /* Clear watchdog , */ \ + { 0x44c0, \ + "ICLAMPS" }, /* Clear enbl amp , */ \ + { 0x44d0, \ + "ICLAREFS" }, /* Clear ref enable , */ \ + { 0x44e0, \ + "ICLADCCR" }, /* Clear control ADC , */ \ + { 0x44f0, \ + "ICLBODNOK" }, /* Clear BOD , */ \ + { 0x4500, \ + "ICLBSTCU" }, /* Clear DCDC current limiting , */ \ + { 0x4510, \ + "ICLBSTHI" }, /* Clear DCDC active , */ \ + { 0x4520, \ + "ICLBSTOC" }, /* Clear DCDC OCP , */ \ + { 0x4530, \ + "ICLBSTPC" }, /* Clear bst peakcur , */ \ + { 0x4540, \ + "ICLBSTVC" }, /* Clear DCDC level 1x , */ \ + { 0x4550, \ + "ICLBST86" }, /* Clear DCDC level 1.14x , */ \ + { 0x4560, \ + "ICLBST93" }, /* Clear DCDC level 1.07x , */ \ + { 0x4570, \ + "ICLRCVLD" }, /* Clear rcvldop ready , */ \ + { 0x4580, \ + "ICLOCPL" }, /* Clear ocp alarm left , */ \ + { 0x4590, \ + "ICLOCPR" }, /* Clear ocp alarm , */ \ + { 0x45a0, \ + "ICLMWSRC" }, /* Clear wait HW I2C settings , */ \ + { 0x45b0, \ + "ICLMWCFC" }, /* Clear wait cf config , */ \ + { 0x45c0, \ + "ICLMWSMU" }, /* Clear audio mute sequence , */ \ + { 0x45d0, \ + "ICLCFMER" }, /* Clear cfma err , */ \ + { 0x45e0, \ + "ICLCFMAC" }, /* Clear cfma ack , */ \ + { 0x45f0, \ + "ICLCLKOOR" }, /* Clear flag_clk_out_of_range , */ \ + { 0x4600, \ + "ICLTDMER" }, /* Clear tdm error , */ \ + { 0x4610, \ + "ICLCLPL" }, /* Clear clip left , */ \ + { 0x4620, \ + "ICLCLP" }, /* Clear clip , */ \ + { 0x4630, \ + "ICLOCPM" }, /* Clear mic ocpok , */ \ + { 0x4650, \ + "ICLLP1" }, /* Clear low power mode1 , */ \ + { 0x4660, \ + "ICLLA" }, /* Clear low amplitude detection , */ \ + { 0x4670, \ + "ICLVDDP" }, /* Clear VDDP greater then VBAT , */ \ + { 0x4680, \ + "ICLTAPDET" }, /* Clear Tap detected , */ \ + { 0x4690, \ + "ICLAUDMOD" }, /* Clear Audio Mode activated , */ \ + { 0x46a0, \ + "ICLSAMMOD" }, /* Clear SAM Mode activated , */ \ + { 0x46b0, \ + "ICLTAPMOD" }, /* Clear Tap Mode Activated , */ \ + { 0x46c0, \ + "ICLTAPTRG" }, /* Clear Comparator Interrupt , */ \ + { 0x4800, \ + "IEVDDS" }, /* Enable por , */ \ + { 0x4810, \ + "IEPLLS" }, /* Enable pll lock , */ \ + { 0x4820, \ + "IEOTDS" }, /* Enable OTP alarm , */ \ + { 0x4830, \ + "IEOVDS" }, /* Enable OVP alarm , */ \ + { 0x4840, \ + "IEUVDS" }, /* Enable UVP alarm , */ \ + { 0x4850, \ + "IECLKS" }, /* Enable clocks stable , */ \ + { 0x4860, \ + "IEMTPB" }, /* Enable mtp busy , */ \ + { 0x4870, \ + "IENOCLK" }, /* Enable lost clk , */ \ + { 0x4880, \ + "IESPKS" }, /* Enable speaker error , */ \ + { 0x4890, \ + "IEACS" }, /* Enable cold started , */ \ + { 0x48a0, \ + "IESWS" }, /* Enable amplifier engage , */ \ + { 0x48b0, \ + "IEWDS" }, /* Enable watchdog , */ \ + { 0x48c0, \ + "IEAMPS" }, /* Enable enbl amp , */ \ + { 0x48d0, \ + "IEAREFS" }, /* Enable ref enable , */ \ + { 0x48e0, \ + "IEADCCR" }, /* Enable Control ADC , */ \ + { 0x48f0, \ + "IEBODNOK" }, /* Enable BOD , */ \ + { 0x4900, \ + "IEBSTCU" }, /* Enable DCDC current limiting , */ \ + { 0x4910, \ + "IEBSTHI" }, /* Enable DCDC active , */ \ + { 0x4920, \ + "IEBSTOC" }, /* Enable DCDC OCP , */ \ + { 0x4930, \ + "IEBSTPC" }, /* Enable bst peakcur , */ \ + { 0x4940, \ + "IEBSTVC" }, /* Enable DCDC level 1x , */ \ + { 0x4950, \ + "IEBST86" }, /* Enable DCDC level 1.14x , */ \ + { 0x4960, \ + "IEBST93" }, /* Enable DCDC level 1.07x , */ \ + { 0x4970, \ + "IERCVLD" }, /* Enable rcvldop ready , */ \ + { 0x4980, \ + "IEOCPL" }, /* Enable ocp alarm left , */ \ + { 0x4990, \ + "IEOCPR" }, /* Enable ocp alarm , */ \ + { 0x49a0, \ + "IEMWSRC" }, /* Enable waits HW I2C settings , */ \ + { 0x49b0, \ + "IEMWCFC" }, /* Enable man wait cf config , */ \ + { 0x49c0, \ + "IEMWSMU" }, /* Enable man Audio mute sequence , */ \ + { 0x49d0, \ + "IECFMER" }, /* Enable cfma err , */ \ + { 0x49e0, \ + "IECFMAC" }, /* Enable cfma ack , */ \ + { 0x49f0, \ + "IECLKOOR" }, /* Enable flag_clk_out_of_range , */ \ + { 0x4a00, \ + "IETDMER" }, /* Enable tdm error , */ \ + { 0x4a10, \ + "IECLPL" }, /* Enable clip left , */ \ + { 0x4a20, \ + "IECLPR" }, /* Enable clip , */ \ + { 0x4a30, \ + "IEOCPM1" }, /* Enable mic ocpok , */ \ + { 0x4a50, \ + "IELP1" }, /* Enable low power mode1 , */ \ + { 0x4a60, \ + "IELA" }, /* Enable low amplitude detection , */ \ + { 0x4a70, \ + "IEVDDP" }, /* Enable VDDP greater than VBAT , */ \ + { 0x4a80, \ + "IETAPDET" }, /* Enable Tap detected , */ \ + { 0x4a90, \ + "IEAUDMOD" }, /* Enable Audio Mode activated , */ \ + { 0x4aa0, \ + "IESAMMOD" }, /* Enable SAM Mode activated , */ \ + { 0x4ab0, \ + "IETAPMOD" }, /* Enable Tap Mode Activated , */ \ + { 0x4ac0, \ + "IETAPTRG" }, /* Enable comparator interrupt , */ \ + { 0x4c00, \ + "IPOVDDS" }, /* Polarity por , */ \ + { 0x4c10, \ + "IPOPLLS" }, /* Polarity pll lock , */ \ + { 0x4c20, \ + "IPOOTDS" }, /* Polarity OTP alarm , */ \ + { 0x4c30, \ + "IPOOVDS" }, /* Polarity OVP alarm , */ \ + { 0x4c40, \ + "IPOUVDS" }, /* Polarity UVP alarm , */ \ + { 0x4c50, \ + "IPOCLKS" }, /* Polarity clocks stable , */ \ + { 0x4c60, \ + "IPOMTPB" }, /* Polarity mtp busy , */ \ + { 0x4c70, \ + "IPONOCLK" }, /* Polarity lost clk , */ \ + { 0x4c80, \ + "IPOSPKS" }, /* Polarity speaker error , */ \ + { 0x4c90, \ + "IPOACS" }, /* Polarity cold started , */ \ + { 0x4ca0, \ + "IPOSWS" }, /* Polarity amplifier engage , */ \ + { 0x4cb0, \ + "IPOWDS" }, /* Polarity watchdog , */ \ + { 0x4cc0, \ + "IPOAMPS" }, /* Polarity enbl amp , */ \ + { 0x4cd0, \ + "IPOAREFS" }, /* Polarity ref enable , */ \ + { 0x4ce0, \ + "IPOADCCR" }, /* Polarity Control ADC , */ \ + { 0x4cf0, \ + "IPOBODNOK" }, /* Polarity BOD , */ \ + { 0x4d00, \ + "IPOBSTCU" }, /* Polarity DCDC current limiting , */ \ + { 0x4d10, \ + "IPOBSTHI" }, /* Polarity DCDC active , */ \ + { 0x4d20, \ + "IPOBSTOC" }, /* Polarity DCDC OCP , */ \ + { 0x4d30, \ + "IPOBSTPC" }, /* Polarity bst peakcur , */ \ + { 0x4d40, \ + "IPOBSTVC" }, /* Polarity DCDC level 1x , */ \ + { 0x4d50, \ + "IPOBST86" }, /* Polarity DCDC level 1.14x , */ \ + { 0x4d60, \ + "IPOBST93" }, /* Polarity DCDC level 1.07x , */ \ + { 0x4d70, \ + "IPORCVLD" }, /* Polarity rcvldop ready , */ \ + { 0x4d80, \ + "IPOOCPL" }, /* Polarity ocp alarm left , */ \ + { 0x4d90, \ + "IPOOCPR" }, /* Polarity ocp alarm , */ \ + { 0x4da0, \ + "IPOMWSRC" }, /* Polarity waits HW I2C settings , */ \ + { 0x4db0, \ + "IPOMWCFC" }, /* Polarity man wait cf config , */ \ + { 0x4dc0, \ + "IPOMWSMU" }, /* Polarity man audio mute sequence , */ \ + { 0x4dd0, \ + "IPOCFMER" }, /* Polarity cfma err , */ \ + { 0x4de0, \ + "IPOCFMAC" }, /* Polarity cfma ack , */ \ + { 0x4df0, \ + "IPOCLKOOR" }, /* Polarity flag_clk_out_of_range , */ \ + { 0x4e00, \ + "IPOTDMER" }, /* Polarity tdm error , */ \ + { 0x4e10, \ + "IPOCLPL" }, /* Polarity clip left , */ \ + { 0x4e20, \ + "IPOCLPR" }, /* Polarity clip , */ \ + { 0x4e30, \ + "IPOOCPM" }, /* Polarity mic ocpok , */ \ + { 0x4e50, \ + "IPOLP1" }, /* Polarity low power mode1 , */ \ + { 0x4e60, \ + "IPOLA" }, /* Polarity low amplitude detection , */ \ + { 0x4e70, \ + "IPOVDDP" }, /* Polarity VDDP greater than VBAT , */ \ + { 0x4e80, \ + "IPOLTAPDET" }, /* PolarityTap detected , */ \ + { 0x4e90, \ + "IPOLAUDMOD" }, /* PolarityAudio Mode activated , */ \ + { 0x4ea0, \ + "IPOLSAMMOD" }, /* PolaritySAM Mode activated , */ \ + { 0x4eb0, \ + "IPOLTAPMOD" }, /* Polarity Tap Mode Activated , */ \ + { 0x4ec0, \ + "IPOLTAPTRG" }, /* PolarityTap Comparator Trigger , */ \ + { 0x5001, \ + "BSSCR" }, /* Battery Safeguard attack time , */ \ + { 0x5023, \ + "BSST" }, /* Battery Safeguard threshold voltage level , */ \ + { 0x5061, \ + "BSSRL" }, /* Battery Safeguard maximum reduction , */ \ + { 0x5082, \ + "BSSRR" }, /* Battery Safeguard release time , */ \ + { 0x50b1, \ + "BSSHY" }, /* Battery Safeguard hysteresis , */ \ + { 0x50d0, \ + "BSSAC" }, /* Reset clipper - Auto clear , */ \ + { 0x50e0, \ + "BSSR" }, /* Battery voltage read out , */ \ + { 0x50f0, \ + "BSSBY" }, /* Bypass HW clipper , */ \ + { 0x5100, \ + "BSSS" }, /* Vbat prot steepness , */ \ + { 0x5110, \ + "INTSMUTE" }, /* Soft mute HW , */ \ + { 0x5120, \ + "CFSML" }, /* Soft mute FW left , */ \ + { 0x5130, \ + "CFSM" }, /* Soft mute FW , */ \ + { 0x5140, \ + "HPFBYPL" }, /* Bypass HPF left , */ \ + { 0x5150, \ + "HPFBYP" }, /* Bypass HPF , */ \ + { 0x5160, \ + "DPSAL" }, /* Enable DPSA left , */ \ + { 0x5170, \ + "DPSA" }, /* Enable DPSA , */ \ + { 0x5187, \ + "VOL" }, /* FW volume control for primary audio channel , */ \ + { 0x5200, \ + "HNDSFRCV" }, /* Selection receiver , */ \ + { 0x5222, \ + "CLIPCTRL" }, /* Clip control setting , */ \ + { 0x5257, \ + "AMPGAIN" }, /* Amplifier gain , */ \ + { 0x52d0, \ + "SLOPEE" }, /* Enables slope control , */ \ + { 0x52e0, \ + "SLOPESET" }, /* Slope speed setting (bin. coded) , */ \ + { 0x5c07, \ + "CFTAPPAT" }, /* Coolflux tap pattern , */ \ + { 0x5c83, \ + "TAPDBGINFO" }, /* Reserved , */ \ + { 0x5d0f, \ + "TATPSTAT1" }, /* Tap Status 1 from CF FW , */ \ + { 0x5f03, \ + "TCOMPTHR" }, /* Comparator threshold (in uV) , */ \ + { 0x6081, \ + "PGAGAIN" }, /* PGA gain selection , */ \ + { 0x6123, \ + "TDMSPKG" }, /* System gain (INPLEV 0) , */ \ + { 0x6505, \ + "LPM1LVL" }, /* low power mode1 detector ctrl threshold for low_audio_lvl , */ \ + { 0x6565, \ + "LPM1HLD" }, /* Low power mode1 detector, ctrl hold time before low audio is reckoned to be low audio, */ \ + { 0x65c0, \ + "LPM1DIS" }, /* low power mode1 detector control , */ \ + { 0x6630, \ + "DCDIS" }, /* DCDC , */ \ + { 0x6801, \ + "TDMSRCMAP" }, /* tdm source mapping , */ \ + { 0x6821, \ + "TDMSRCAS" }, /* frame a selection , */ \ + { 0x6841, \ + "TDMSRCBS" }, /* frame b selection , */ \ + { 0x68a0, \ + "ANC1C" }, /* ANC one s complement , */ \ + { 0x6901, \ + "SAMMODE" }, /* Sam mode , */ \ + { 0x7033, \ + "DCMCC" }, /* Max coil current , */ \ + { 0x7071, \ + "DCCV" }, /* Slope compensation current, represents LxF (inductance x frequency) value , */ \ + { 0x7090, \ + "DCIE" }, /* Adaptive boost mode , */ \ + { 0x70a0, \ + "DCSR" }, /* Soft ramp up/down , */ \ + { 0x70c1, \ + "DCINSEL" }, /* DCDC IIR input Selection , */ \ + { 0x70f0, \ + "DCPWM" }, /* DCDC PWM only mode , */ \ + { 0x7504, \ + "DCTRIP" }, /* Adaptive boost trip levels 1, effective only when boost_intelligent is set to 1, */ \ + { 0x7554, \ + "DCTRIP2" }, /* Adaptive boost trip level 2, effective only when boost_intelligent is set to 1, */ \ + { 0x75a4, \ + "DCTRIPT" }, /* Adaptive boost trip levels, effective only when boost_intelligent is set to 1, */ \ + { 0x7635, \ + "DCVOF" }, /* First boost voltage level , */ \ + { 0x7695, \ + "DCVOS" }, /* Second boost voltage level , */ \ + { 0x9000, \ + "RST" }, /* Reset , */ \ + { 0x9011, \ + "DMEM" }, /* Target memory , */ \ + { 0x9030, \ + "AIF" }, /* Auto increment , */ \ + { 0x9040, \ + "CFINT" }, /* Interrupt - auto clear , */ \ + { 0x9050, \ + "CFCGATE" }, /* Coolflux clock gating disabling control , */ \ + { 0x9080, \ + "REQCMD" }, /* Firmware event request rpc command , */ \ + { 0x9090, \ + "REQRST" }, /* Firmware event request reset restart , */ \ + { 0x90a0, \ + "REQMIPS" }, /* Firmware event request short on mips , */ \ + { 0x90b0, \ + "REQMUTED" }, /* Firmware event request mute sequence ready , */ \ + { 0x90c0, \ + "REQVOL" }, /* Firmware event request volume ready , */ \ + { 0x90d0, \ + "REQDMG" }, /* Firmware event request speaker damage detected , */ \ + { 0x90e0, \ + "REQCAL" }, /* Firmware event request calibration completed , */ \ + { 0x90f0, \ + "REQRSV" }, /* Firmware event request reserved , */ \ + { 0x910f, \ + "MADD" }, /* Memory address , */ \ + { 0x920f, \ + "MEMA" }, /* Activate memory access , */ \ + { 0x9307, \ + "ERR" }, /* Error flags , */ \ + { 0x9380, \ + "ACKCMD" }, /* Firmware event acknowledge rpc command , */ \ + { 0x9390, \ + "ACKRST" }, /* Firmware event acknowledge reset restart , */ \ + { 0x93a0, \ + "ACKMIPS" }, /* Firmware event acknowledge short on mips , */ \ + { 0x93b0, \ + "ACKMUTED" }, /* Firmware event acknowledge mute sequence ready , */ \ + { 0x93c0, \ + "ACKVOL" }, /* Firmware event acknowledge volume ready , */ \ + { 0x93d0, \ + "ACKDMG" }, /* Firmware event acknowledge speaker damage detected, */ \ + { 0x93e0, \ + "ACKCAL" }, /* Firmware event acknowledge calibration completed , */ \ + { 0x93f0, \ + "ACKRSV" }, /* Firmware event acknowledge reserved , */ \ + { 0xa107, \ + "MTPK" }, /* MTP KEY2 register , */ \ + { 0xa200, \ + "KEY1LOCKED" }, /* Indicates KEY1 is locked , */ \ + { 0xa210, \ + "KEY2LOCKED" }, /* Indicates KEY2 is locked , */ \ + { 0xa360, \ + "CIMTP" }, /* Start copying data from I2C mtp registers to mtp , */ \ + { 0xa50f, \ + "MTPRDMSB" }, /* MSB word of MTP manual read data , */ \ + { 0xa60f, \ + "MTPRDLSB" }, /* LSB word of MTP manual read data , */ \ + { 0xb108, \ + "EXTTS" }, /* External temperature (C) , */ \ + { 0xb190, \ + "TROS" }, /* Select temp Speaker calibration , */ \ + { 0xee0f, \ + "SWPROFIL" }, /* Software profile data , */ \ + { 0xef0f, \ + "SWVSTEP" }, /* Software vstep information , */ \ + { 0xf000, \ + "MTPOTC" }, /* Calibration schedule , */ \ + { 0xf010, \ + "MTPEX" }, /* Calibration Ron executed , */ \ + { 0xf020, \ + "DCMCCAPI" }, /* Calibration current limit DCDC , */ \ + { 0xf030, \ + "DCMCCSB" }, /* Sign bit for delta calibration current limit DCDC , */ \ + { 0xf042, \ + "DCMCCCL" }, /* Calibration delta current limit DCDC , */ \ + { 0xf078, \ + "USERDEF" }, /* Reserved space for allowing customer to store speaker information, */ \ + { 0xf40f, \ + "R25C" }, /* Ron resistance of speaker coil , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +#define TFA9912_BITNAMETABLE \ + static tfaBfName_t Tfa9912BitNames[] = { \ + { 0x0, \ + "powerdown" }, /* Powerdown selection , */ \ + { 0x10, \ + "reset" }, /* I2C Reset - Auto clear , */ \ + { 0x20, \ + "enbl_coolflux" }, /* Enable CoolFlux , */ \ + { 0x30, \ + "enbl_amplifier" }, /* Enables the Amplifier , */ \ + { 0x40, \ + "enbl_boost" }, /* Activate DC-to-DC converter , */ \ + { 0x50, \ + "coolflux_configured" }, /* Coolflux configured , */ \ + { 0x60, \ + "sel_enbl_amplifier" }, /* CoolFlux controls amplifier , */ \ + { 0x71, \ + "int_pad_io" }, /* Interrupt config , */ \ + { 0x90, \ + "fs_pulse_sel" }, /* Audio sample reference , */ \ + { 0xb0, \ + "bypass_ocp" }, /* Bypass OCP , */ \ + { 0xc0, \ + "test_ocp" }, /* OCP testing control , */ \ + { 0x101, \ + "vamp_sel" }, /* Amplifier input selection , */ \ + { 0x120, \ + "src_set_configured" }, /* I2C configured , */ \ + { 0x130, \ + "execute_cold_start" }, /* Execute cold start , */ \ + { 0x140, \ + "enbl_fro8m_auto_off" }, /* Internal osc off at PWDN , */ \ + { 0x150, \ + "man_enbl_brown_out" }, /* Reaction on BOD , */ \ + { 0x160, \ + "enbl_bod" }, /* BOD Enable , */ \ + { 0x170, \ + "enbl_bod_hyst" }, /* BOD Hysteresis , */ \ + { 0x181, \ + "bod_delay" }, /* BOD filter , */ \ + { 0x1a1, \ + "bod_lvlsel" }, /* BOD threshold , */ \ + { 0x1d0, \ + "disable_mute_time_out" }, /* Time out SB mute sequence , */ \ + { 0x1e0, \ + "pwm_sel_rcv_ns" }, /* Noise shaper selection , */ \ + { 0x1f0, \ + "man_enbl_watchdog" }, /* Watchdog enable , */ \ + { 0x203, \ + "audio_fs" }, /* Sample rate (fs) , */ \ + { 0x240, \ + "input_level" }, /* TDM output attenuation , */ \ + { 0x255, \ + "cs_frac_delay" }, /* V/I Fractional delay , */ \ + { 0x2b0, \ + "bypass_hvbat_filter" }, /* Bypass HVBAT filter , */ \ + { 0x2c0, \ + "tdm_tfa9872_compatible" }, /* TDM Compatibility with TFA9872 , */ \ + { 0x2d0, \ + "sel_hysteresis" }, /* Select hysteresis for clock range detector , */ \ + { 0x2e0, \ + "enbl_adc10" }, /* ADC10 Enable - I2C direct mode , */ \ + { 0x30f, \ + "device_rev" }, /* Revision info , */ \ + { 0x401, \ + "pll_clkin_sel" }, /* PLL external ref clock , */ \ + { 0x420, \ + "pll_clkin_sel_osc" }, /* PLL internal ref clock , */ \ + { 0x430, \ + "cf_clock_scaling" }, /* Coolflux DSP clock scaling, low power mode , */ \ + { 0x441, \ + "sel_cf_clock" }, /* Coolflux DSP clock scaler selection for low power mode, */ \ + { 0x460, \ + "tdm_intf_sel" }, /* TDM clock selection , */ \ + { 0x470, \ + "disable_auto_sel_refclk" }, /* Disable Automatic dsp clock source selection , */ \ + { 0x480, \ + "sel_clk_src" }, /* I2C selection of DSP clock when auto select is disabled, */ \ + { 0x490, \ + "wdt_tim_clk_src" }, /* I2C selection of Watchdog and Timer clock , */ \ + { 0x510, \ + "enbl_spkr_ss" }, /* Enable speaker path , */ \ + { 0x530, \ + "enbl_volsense" }, /* Voltage sense , */ \ + { 0x550, \ + "enbl_cursense" }, /* Current sense , */ \ + { 0x560, \ + "enbl_pdm_ss" }, /* Sub-system PDM , */ \ + { 0x580, \ + "enbl_pga_chop" }, /* Enable PGA chop clock , */ \ + { 0x590, \ + "enbl_tdm_ss" }, /* Sub-system TDM , */ \ + { 0x5a0, \ + "enbl_bst_ss" }, /* Sub-system boost , */ \ + { 0x5b0, \ + "enbl_adc10_ss" }, /* Sub-system ADC , */ \ + { 0x5c0, \ + "enbl_faim_ss" }, /* Sub-system FAIM , */ \ + { 0x5d0, \ + "enbl_tim_clk" }, /* CF Sub-system timer , */ \ + { 0x5e0, \ + "enbl_wdt_clk" }, /* CF Sub-system WDT , */ \ + { 0x5f0, \ + "faim_enable_vbg" }, /* Over rule of vbg for FaIM access , */ \ + { 0x600, \ + "aux_spkr_sel" }, /* Input selection for TAP/SAM , */ \ + { 0x620, \ + "bypass_tapdec_reset" }, /* Tap decimator reset bypass - Bypass the decimator reset from tapdec, */ \ + { 0x631, \ + "car_dec_in_sel0" }, /* Cardec input 0 sel , */ \ + { 0x651, \ + "car_dec_in_sel1" }, /* Cardec input sel , */ \ + { 0x670, \ + "tapdec_sel" }, /* Select TAP/Cardec for TAP , */ \ + { 0x680, \ + "comp_count" }, /* Comparator o/p filter selection , */ \ + { 0x691, \ + "startup_mode" }, /* Startup Mode Selection , */ \ + { 0x6b0, \ + "enable_auto_tap_switching" }, /* Enable auto tap switching , */ \ + { 0x6c1, \ + "comp_init_time" }, /* Comparator initialization time to be used in Tap Machine, */ \ + { 0x6e1, \ + "ana_init_time" }, /* Analog initialization time to be used in Tap Machine, */ \ + { 0x707, \ + "clkchk_th_hi" }, /* Clock check Higher Threshold , */ \ + { 0x787, \ + "clkchk_th_lo" }, /* Clock check Higher Threshold , */ \ + { 0x802, \ + "ctrl_on2off_criterion" }, /* Amplifier on-off criteria for shutdown , */ \ + { 0x832, \ + "ctrl_on2tap_criterion" }, /* Amplifier on-off criteria for tap mode entry , */ \ + { 0xd00, \ + "side_tone_gain_sel" }, /* PDM side tone gain selector , */ \ + { 0xd18, \ + "side_tone_gain" }, /* Side tone gain , */ \ + { 0xda0, \ + "mute_side_tone" }, /* Side tone soft mute , */ \ + { 0xdb0, \ + "side_tone_1scomplement" }, /* side tone one s complement , */ \ + { 0xe07, \ + "ctrl_digtoana" }, /* Spare control from digital to analog , */ \ + { 0xf0f, \ + "hidden_code" }, /* 5A6Bh, 23147d to access registers (default for engineering), */ \ + { 0x1000, \ + "flag_por" }, /* POR , */ \ + { 0x1010, \ + "flag_pll_lock" }, /* PLL lock , */ \ + { 0x1020, \ + "flag_otpok" }, /* OTP alarm , */ \ + { 0x1030, \ + "flag_ovpok" }, /* OVP alarm , */ \ + { 0x1040, \ + "flag_uvpok" }, /* UVP alarm , */ \ + { 0x1050, \ + "flag_clocks_stable" }, /* Clocks stable , */ \ + { 0x1060, \ + "flag_mtp_busy" }, /* MTP busy , */ \ + { 0x1070, \ + "flag_lost_clk" }, /* Lost clock , */ \ + { 0x1090, \ + "flag_cold_started" }, /* Cold Start , */ \ + { 0x10a0, \ + "flag_engage" }, /* Amplifier engage , */ \ + { 0x10b0, \ + "flag_watchdog_reset" }, /* Watchdog , */ \ + { 0x10c0, \ + "flag_enbl_amp" }, /* Amplifier enable , */ \ + { 0x10d0, \ + "flag_enbl_ref" }, /* References enable , */ \ + { 0x10e0, \ + "flag_adc10_ready" }, /* Control ADC , */ \ + { 0x10f0, \ + "flag_bod_vddd_nok" }, /* BOD , */ \ + { 0x1100, \ + "flag_bst_bstcur" }, /* DCDC current limiting , */ \ + { 0x1110, \ + "flag_bst_hiz" }, /* DCDC active , */ \ + { 0x1120, \ + "flag_bst_ocpok" }, /* DCDC OCP nmos , */ \ + { 0x1130, \ + "flag_bst_peakcur" }, /* Indicates current is max in DC-to-DC converter , */ \ + { 0x1140, \ + "flag_bst_voutcomp" }, /* DCDC level 1x , */ \ + { 0x1150, \ + "flag_bst_voutcomp86" }, /* DCDC level 1.14x , */ \ + { 0x1160, \ + "flag_bst_voutcomp93" }, /* DCDC level 1.07x , */ \ + { 0x1170, \ + "flag_soft_mute_busy" }, /* side tone (un)mute busy , */ \ + { 0x1180, \ + "flag_soft_mute_state" }, /* side tone mute state , */ \ + { 0x1190, \ + "flag_tdm_lut_error" }, /* TDM LUT error , */ \ + { 0x11a2, \ + "flag_tdm_status" }, /* TDM status bits , */ \ + { 0x11d0, \ + "flag_tdm_error" }, /* TDM error , */ \ + { 0x1300, \ + "flag_ocpokap" }, /* OCPOK pmos A , */ \ + { 0x1310, \ + "flag_ocpokan" }, /* OCPOK nmos A , */ \ + { 0x1320, \ + "flag_ocpokbp" }, /* OCPOK pmos B , */ \ + { 0x1330, \ + "flag_ocpokbn" }, /* OCPOK nmos B , */ \ + { 0x1340, \ + "flag_clipa_high" }, /* Clipping A to Vddp , */ \ + { 0x1350, \ + "flag_clipa_low" }, /* Clipping A to gnd , */ \ + { 0x1360, \ + "flag_clipb_high" }, /* Clipping B to Vddp , */ \ + { 0x1370, \ + "flag_clipb_low" }, /* Clipping B to gnd , */ \ + { 0x1380, \ + "flag_ocp_alarm" }, /* OCP amplifier , */ \ + { 0x1390, \ + "flag_clip" }, /* Amplifier clipping , */ \ + { 0x13a0, \ + "flag_tap_comp_trig" }, /* Status Tap comparator triggered , */ \ + { 0x13b0, \ + "flag_cf_tapdetected" }, /* Status Tap detected , */ \ + { 0x13c0, \ + "flag_man_wait_src_settings" }, /* Wait HW I2C settings , */ \ + { 0x13d0, \ + "flag_man_wait_cf_config" }, /* Wait CF config , */ \ + { 0x13e0, \ + "flag_man_start_mute_audio" }, /* Audio mute sequence , */ \ + { 0x1410, \ + "flag_cf_speakererror" }, /* Speaker status , */ \ + { 0x1420, \ + "flag_clk_out_of_range" }, /* External clock status , */ \ + { 0x1433, \ + "man_state" }, /* Device manager status , */ \ + { 0x1471, \ + "status_bst_mode" }, /* DCDC mode status bits , */ \ + { 0x1490, \ + "man_dsp_clk_src" }, /* DSP clock source selected by manager , */ \ + { 0x14a1, \ + "man_startup_mode" }, /* Startup Mode Selected by Manager(Read Only) , */ \ + { 0x14c3, \ + "tap_machine_state" }, /* Tap Machine State , */ \ + { 0x1509, \ + "bat_adc" }, /* Battery voltage (V) , */ \ + { 0x1608, \ + "temp_adc" }, /* IC Temperature (C) , */ \ + { 0x1709, \ + "vddp_adc" }, /* IC VDDP voltage ( 1023*VDDP/13 V) , */ \ + { 0x17a0, \ + "flag_bst_bstcur_cf" }, /* DCDC current limiting for DSP , */ \ + { 0x2000, \ + "tdm_usecase" }, /* Mode setting , */ \ + { 0x2011, \ + "dio4_input_sel" }, /* DIO4 Input selection , */ \ + { 0x2040, \ + "tdm_enable" }, /* Enable TDM interface , */ \ + { 0x2060, \ + "tdm_clk_inversion" }, /* Reception data to BCK clock , */ \ + { 0x2073, \ + "tdm_fs_ws_length" }, /* FS length , */ \ + { 0x20b0, \ + "tdm_fs_ws_polarity" }, /* FS polarity , */ \ + { 0x20c3, \ + "tdm_nbck" }, /* N-BCK's in FS , */ \ + { 0x2103, \ + "tdm_nb_of_slots" }, /* N-slots in Frame , */ \ + { 0x2144, \ + "tdm_slot_length" }, /* N-bits in slot , */ \ + { 0x2194, \ + "tdm_bits_remaining" }, /* N-bits remaining , */ \ + { 0x21e0, \ + "tdm_data_delay" }, /* data delay to FS , */ \ + { 0x21f0, \ + "tdm_data_adjustment" }, /* data adjustment , */ \ + { 0x2201, \ + "tdm_audio_sample_compression" }, /* Received audio compression , */ \ + { 0x2224, \ + "tdm_sample_size" }, /* Sample size per slot , */ \ + { 0x2271, \ + "tdm_txdata_format" }, /* Format unused bits in a slot , */ \ + { 0x2291, \ + "tdm_txdata_format_unused_slot_sd0" }, /* Format unused slots GAINIO , */ \ + { 0x22b1, \ + "tdm_txdata_format_unused_slot_sd1" }, /* Format unused slots DIO1 , */ \ + { 0x22d1, \ + "tdm_txdata_format_unused_slot_sd2" }, /* Format unused slots DIO2 , */ \ + { 0x2300, \ + "tdm_sink0_enable" }, /* Control gain (channel in 0) , */ \ + { 0x2310, \ + "tdm_sink1_enable" }, /* Control audio left (channel in 1 ) , */ \ + { 0x2320, \ + "tdm_sink2_enable" }, /* Control audio right (channel in 2 ) , */ \ + { 0x2330, \ + "tdm_source0_enable" }, /* Current sense , */ \ + { 0x2340, \ + "tdm_source1_enable" }, /* Voltage sense , */ \ + { 0x2350, \ + "tdm_source2_enable" }, /* DSP Gainout , */ \ + { 0x2360, \ + "tdm_source3_enable" }, /* DSP 2 , */ \ + { 0x2370, \ + "tdm_source4_enable" }, /* DSP 3 , */ \ + { 0x2380, \ + "tdm_source5_enable" }, /* DSP , */ \ + { 0x2390, \ + "tdm_source6_enable" }, /* Loopback of Audio left (channel 1) , */ \ + { 0x23a0, \ + "tdm_source7_enable" }, /* Loopback of Audio right (channel 2) , */ \ + { 0x2401, \ + "tdm_sink0_io" }, /* IO gainin , */ \ + { 0x2421, \ + "tdm_sink1_io" }, /* IO audio left , */ \ + { 0x2441, \ + "tdm_sink2_io" }, /* IO audio right , */ \ + { 0x2461, \ + "tdm_source0_io" }, /* IO Current Sense , */ \ + { 0x2481, \ + "tdm_source1_io" }, /* IO voltage sense , */ \ + { 0x24a1, \ + "tdm_source2_io" }, /* IO gain out , */ \ + { 0x24c1, \ + "tdm_source3_io" }, /* IO DSP 2 , */ \ + { 0x24e1, \ + "tdm_source4_io" }, /* IO DSP 3 , */ \ + { 0x2501, \ + "tdm_source5_io" }, /* IO DSP , */ \ + { 0x2521, \ + "tdm_source6_io" }, /* IO Source 6 , */ \ + { 0x2541, \ + "tdm_source7_io" }, /* IO Source 7 , */ \ + { 0x2603, \ + "tdm_sink0_slot" }, /* Control gainin , */ \ + { 0x2643, \ + "tdm_sink1_slot" }, /* tdm slot for audio left (channel 1) , */ \ + { 0x2683, \ + "tdm_sink2_slot" }, /* tdm slot for audio right (channel 2) , */ \ + { 0x26c3, \ + "tdm_source0_slot" }, /* Slot Position of Current Sense Out , */ \ + { 0x2703, \ + "tdm_source1_slot" }, /* Slot Position of Voltage sense , */ \ + { 0x2743, \ + "tdm_source2_slot" }, /* Slot Position of GAIN out , */ \ + { 0x2783, \ + "tdm_source3_slot" }, /* Slot Position DSPout2 , */ \ + { 0x27c3, \ + "tdm_source4_slot" }, /* Slot Position DSPout3 , */ \ + { 0x2803, \ + "tdm_source5_slot" }, /* Slot Position of DSPout , */ \ + { 0x2843, \ + "tdm_source6_slot" }, /* Slot Position of loopback channel left , */ \ + { 0x2883, \ + "tdm_source7_slot" }, /* Slot Position of loopback channel right , */ \ + { 0x2901, \ + "tdm_txdata_format_unused_slot_sd3" }, /* Format unused slots D3 , */ \ + { 0x3100, \ + "pdm_mode" }, /* PDM control , */ \ + { 0x3110, \ + "pdm_input_sel" }, /* PDM Decimator input selection , */ \ + { 0x3120, \ + "enbl_pdm_side_tone" }, /* Side tone input enable , */ \ + { 0x3201, \ + "pdm_nbck" }, /* PDM BCK/Fs ratio , */ \ + { 0x4000, \ + "int_out_flag_por" }, /* Status POR , */ \ + { 0x4010, \ + "int_out_flag_pll_lock" }, /* Status PLL lock , */ \ + { 0x4020, \ + "int_out_flag_otpok" }, /* Status OTP alarm , */ \ + { 0x4030, \ + "int_out_flag_ovpok" }, /* Status OVP alarm , */ \ + { 0x4040, \ + "int_out_flag_uvpok" }, /* Status UVP alarm , */ \ + { 0x4050, \ + "int_out_flag_clocks_stable" }, /* Status clocks stable , */ \ + { 0x4060, \ + "int_out_flag_mtp_busy" }, /* Status MTP busy , */ \ + { 0x4070, \ + "int_out_flag_lost_clk" }, /* Status lost clock , */ \ + { 0x4080, \ + "int_out_flag_cf_speakererror" }, /* Status speaker error , */ \ + { 0x4090, \ + "int_out_flag_cold_started" }, /* Status cold start , */ \ + { 0x40a0, \ + "int_out_flag_engage" }, /* Status amplifier engage , */ \ + { 0x40b0, \ + "int_out_flag_watchdog_reset" }, /* Status watchdog , */ \ + { 0x40c0, \ + "int_out_flag_enbl_amp" }, /* Status amplifier enable , */ \ + { 0x40d0, \ + "int_out_flag_enbl_ref" }, /* Status Ref enable , */ \ + { 0x40e0, \ + "int_out_flag_adc10_ready" }, /* Status Control ADC , */ \ + { 0x40f0, \ + "int_out_flag_bod_vddd_nok" }, /* Status BOD , */ \ + { 0x4100, \ + "int_out_flag_bst_bstcur" }, /* Status DCDC current limiting , */ \ + { 0x4110, \ + "int_out_flag_bst_hiz" }, /* Status DCDC active , */ \ + { 0x4120, \ + "int_out_flag_bst_ocpok" }, /* Status DCDC OCP , */ \ + { 0x4130, \ + "int_out_flag_bst_peakcur" }, /* Status bst peakcur , */ \ + { 0x4140, \ + "int_out_flag_bst_voutcomp" }, /* Status DCDC level 1x , */ \ + { 0x4150, \ + "int_out_flag_bst_voutcomp86" }, /* Status DCDC level 1.14x , */ \ + { 0x4160, \ + "int_out_flag_bst_voutcomp93" }, /* Status DCDC level 1.07x , */ \ + { 0x4190, \ + "int_out_flag_ocp_alarm" }, /* Status ocp alarm , */ \ + { 0x41a0, \ + "int_out_flag_man_wait_src_settings" }, /* Status Waits HW I2C settings , */ \ + { 0x41b0, \ + "int_out_flag_man_wait_cf_config" }, /* Status waits CF config , */ \ + { 0x41c0, \ + "int_out_flag_man_start_mute_audio" }, /* Status Audio mute sequence , */ \ + { 0x41d0, \ + "int_out_flag_cfma_err" }, /* Status cfma error , */ \ + { 0x41e0, \ + "int_out_flag_cfma_ack" }, /* Status cfma ack , */ \ + { 0x41f0, \ + "int_out_flag_clk_out_of_range" }, /* Status flag_clk_out_of_range , */ \ + { 0x4200, \ + "int_out_flag_tdm_error" }, /* Status tdm error , */ \ + { 0x4220, \ + "int_out_flag_clip" }, /* Status clip , */ \ + { 0x4250, \ + "int_out_flag_lp_detect_mode1" }, /* Status low power mode1 , */ \ + { 0x4260, \ + "int_out_flag_low_amplitude" }, /* Status low amplitude detection , */ \ + { 0x4270, \ + "int_out_flag_vddp_gt_vbat" }, /* Status VDDP greater than VBAT , */ \ + { 0x4280, \ + "int_out_newtap" }, /* Status Tap detected , */ \ + { 0x4290, \ + "int_out_audiomodeactive" }, /* Status Audio Mode activated , */ \ + { 0x42a0, \ + "int_out_sammodeactive" }, /* Status SAM Mode activated , */ \ + { 0x42b0, \ + "int_out_tapmodeactive" }, /* Status Tap Mode Activated , */ \ + { 0x42c0, \ + "int_out_flag_tap_comp_trig" }, /* Status Tap comparator triggered , */ \ + { 0x4400, \ + "int_in_flag_por" }, /* Clear POR , */ \ + { 0x4410, \ + "int_in_flag_pll_lock" }, /* Clear PLL lock , */ \ + { 0x4420, \ + "int_in_flag_otpok" }, /* Clear OTP alarm , */ \ + { 0x4430, \ + "int_in_flag_ovpok" }, /* Clear OVP alarm , */ \ + { 0x4440, \ + "int_in_flag_uvpok" }, /* Clear UVP alarm , */ \ + { 0x4450, \ + "int_in_flag_clocks_stable" }, /* Clear clocks stable , */ \ + { 0x4460, \ + "int_in_flag_mtp_busy" }, /* Clear mtp busy , */ \ + { 0x4470, \ + "int_in_flag_lost_clk" }, /* Clear lost clk , */ \ + { 0x4480, \ + "int_in_flag_cf_speakererror" }, /* Clear speaker error , */ \ + { 0x4490, \ + "int_in_flag_cold_started" }, /* Clear cold started , */ \ + { 0x44a0, \ + "int_in_flag_engage" }, /* Clear amplifier engage , */ \ + { 0x44b0, \ + "int_in_flag_watchdog_reset" }, /* Clear watchdog , */ \ + { 0x44c0, \ + "int_in_flag_enbl_amp" }, /* Clear enbl amp , */ \ + { 0x44d0, \ + "int_in_flag_enbl_ref" }, /* Clear ref enable , */ \ + { 0x44e0, \ + "int_in_flag_adc10_ready" }, /* Clear control ADC , */ \ + { 0x44f0, \ + "int_in_flag_bod_vddd_nok" }, /* Clear BOD , */ \ + { 0x4500, \ + "int_in_flag_bst_bstcur" }, /* Clear DCDC current limiting , */ \ + { 0x4510, \ + "int_in_flag_bst_hiz" }, /* Clear DCDC active , */ \ + { 0x4520, \ + "int_in_flag_bst_ocpok" }, /* Clear DCDC OCP , */ \ + { 0x4530, \ + "int_in_flag_bst_peakcur" }, /* Clear bst peakcur , */ \ + { 0x4540, \ + "int_in_flag_bst_voutcomp" }, /* Clear DCDC level 1x , */ \ + { 0x4550, \ + "int_in_flag_bst_voutcomp86" }, /* Clear DCDC level 1.14x , */ \ + { 0x4560, \ + "int_in_flag_bst_voutcomp93" }, /* Clear DCDC level 1.07x , */ \ + { 0x4590, \ + "int_in_flag_ocp_alarm" }, /* Clear ocp alarm , */ \ + { 0x45a0, \ + "int_in_flag_man_wait_src_settings" }, /* Clear wait HW I2C settings , */ \ + { 0x45b0, \ + "int_in_flag_man_wait_cf_config" }, /* Clear wait cf config , */ \ + { 0x45c0, \ + "int_in_flag_man_start_mute_audio" }, /* Clear audio mute sequence , */ \ + { 0x45d0, \ + "int_in_flag_cfma_err" }, /* Clear cfma err , */ \ + { 0x45e0, \ + "int_in_flag_cfma_ack" }, /* Clear cfma ack , */ \ + { 0x45f0, \ + "int_in_flag_clk_out_of_range" }, /* Clear flag_clk_out_of_range , */ \ + { 0x4600, \ + "int_in_flag_tdm_error" }, /* Clear tdm error , */ \ + { 0x4620, \ + "int_in_flag_clip" }, /* Clear clip , */ \ + { 0x4650, \ + "int_in_flag_lp_detect_mode1" }, /* Clear low power mode1 , */ \ + { 0x4660, \ + "int_in_flag_low_amplitude" }, /* Clear low amplitude detection , */ \ + { 0x4670, \ + "int_in_flag_vddp_gt_vbat" }, /* Clear VDDP greater then VBAT , */ \ + { 0x4680, \ + "int_in_newtap" }, /* Clear Tap detected , */ \ + { 0x4690, \ + "int_in_audiomodeactive" }, /* Clear Audio Mode activated , */ \ + { 0x46a0, \ + "int_in_sammodeactive" }, /* Clear SAM Mode activated , */ \ + { 0x46b0, \ + "int_in_tapmodeactive" }, /* Clear Tap Mode Activated , */ \ + { 0x46c0, \ + "int_in_flag_tap_comp_trig" }, /* Clear Comparator Interrupt , */ \ + { 0x4800, \ + "int_enable_flag_por" }, /* Enable por , */ \ + { 0x4810, \ + "int_enable_flag_pll_lock" }, /* Enable pll lock , */ \ + { 0x4820, \ + "int_enable_flag_otpok" }, /* Enable OTP alarm , */ \ + { 0x4830, \ + "int_enable_flag_ovpok" }, /* Enable OVP alarm , */ \ + { 0x4840, \ + "int_enable_flag_uvpok" }, /* Enable UVP alarm , */ \ + { 0x4850, \ + "int_enable_flag_clocks_stable" }, /* Enable clocks stable , */ \ + { 0x4860, \ + "int_enable_flag_mtp_busy" }, /* Enable mtp busy , */ \ + { 0x4870, \ + "int_enable_flag_lost_clk" }, /* Enable lost clk , */ \ + { 0x4880, \ + "int_enable_flag_cf_speakererror" }, /* Enable speaker error , */ \ + { 0x4890, \ + "int_enable_flag_cold_started" }, /* Enable cold started , */ \ + { 0x48a0, \ + "int_enable_flag_engage" }, /* Enable amplifier engage , */ \ + { 0x48b0, \ + "int_enable_flag_watchdog_reset" }, /* Enable watchdog , */ \ + { 0x48c0, \ + "int_enable_flag_enbl_amp" }, /* Enable enbl amp , */ \ + { 0x48d0, \ + "int_enable_flag_enbl_ref" }, /* Enable ref enable , */ \ + { 0x48e0, \ + "int_enable_flag_adc10_ready" }, /* Enable Control ADC , */ \ + { 0x48f0, \ + "int_enable_flag_bod_vddd_nok" }, /* Enable BOD , */ \ + { 0x4900, \ + "int_enable_flag_bst_bstcur" }, /* Enable DCDC current limiting , */ \ + { 0x4910, \ + "int_enable_flag_bst_hiz" }, /* Enable DCDC active , */ \ + { 0x4920, \ + "int_enable_flag_bst_ocpok" }, /* Enable DCDC OCP , */ \ + { 0x4930, \ + "int_enable_flag_bst_peakcur" }, /* Enable bst peakcur , */ \ + { 0x4940, \ + "int_enable_flag_bst_voutcomp" }, /* Enable DCDC level 1x , */ \ + { 0x4950, \ + "int_enable_flag_bst_voutcomp86" }, /* Enable DCDC level 1.14x , */ \ + { 0x4960, \ + "int_enable_flag_bst_voutcomp93" }, /* Enable DCDC level 1.07x , */ \ + { 0x4990, \ + "int_enable_flag_ocp_alarm" }, /* Enable ocp alarm , */ \ + { 0x49a0, \ + "int_enable_flag_man_wait_src_settings" }, /* Enable waits HW I2C settings , */ \ + { 0x49b0, \ + "int_enable_flag_man_wait_cf_config" }, /* Enable man wait cf config , */ \ + { 0x49c0, \ + "int_enable_flag_man_start_mute_audio" }, /* Enable man Audio mute sequence , */ \ + { 0x49d0, \ + "int_enable_flag_cfma_err" }, /* Enable cfma err , */ \ + { 0x49e0, \ + "int_enable_flag_cfma_ack" }, /* Enable cfma ack , */ \ + { 0x49f0, \ + "int_enable_flag_clk_out_of_range" }, /* Enable flag_clk_out_of_range , */ \ + { 0x4a00, \ + "int_enable_flag_tdm_error" }, /* Enable tdm error , */ \ + { 0x4a20, \ + "int_enable_flag_clip" }, /* Enable clip , */ \ + { 0x4a50, \ + "int_enable_flag_lp_detect_mode1" }, /* Enable low power mode1 , */ \ + { 0x4a60, \ + "int_enable_flag_low_amplitude" }, /* Enable low amplitude detection , */ \ + { 0x4a70, \ + "int_enable_flag_vddp_gt_vbat" }, /* Enable VDDP greater than VBAT , */ \ + { 0x4a80, \ + "int_enable_newtap" }, /* Enable Tap detected , */ \ + { 0x4a90, \ + "int_enable_audiomodeactive" }, /* Enable Audio Mode activated , */ \ + { 0x4aa0, \ + "int_enable_sammodeactive" }, /* Enable SAM Mode activated , */ \ + { 0x4ab0, \ + "int_enable_tapmodeactive" }, /* Enable Tap Mode Activated , */ \ + { 0x4ac0, \ + "int_enable_flag_tap_comp_trig" }, /* Enable comparator interrupt , */ \ + { 0x4c00, \ + "int_polarity_flag_por" }, /* Polarity por , */ \ + { 0x4c10, \ + "int_polarity_flag_pll_lock" }, /* Polarity pll lock , */ \ + { 0x4c20, \ + "int_polarity_flag_otpok" }, /* Polarity OTP alarm , */ \ + { 0x4c30, \ + "int_polarity_flag_ovpok" }, /* Polarity OVP alarm , */ \ + { 0x4c40, \ + "int_polarity_flag_uvpok" }, /* Polarity UVP alarm , */ \ + { 0x4c50, \ + "int_polarity_flag_clocks_stable" }, /* Polarity clocks stable , */ \ + { 0x4c60, \ + "int_polarity_flag_mtp_busy" }, /* Polarity mtp busy , */ \ + { 0x4c70, \ + "int_polarity_flag_lost_clk" }, /* Polarity lost clk , */ \ + { 0x4c80, \ + "int_polarity_flag_cf_speakererror" }, /* Polarity speaker error , */ \ + { 0x4c90, \ + "int_polarity_flag_cold_started" }, /* Polarity cold started , */ \ + { 0x4ca0, \ + "int_polarity_flag_engage" }, /* Polarity amplifier engage , */ \ + { 0x4cb0, \ + "int_polarity_flag_watchdog_reset" }, /* Polarity watchdog , */ \ + { 0x4cc0, \ + "int_polarity_flag_enbl_amp" }, /* Polarity enbl amp , */ \ + { 0x4cd0, \ + "int_polarity_flag_enbl_ref" }, /* Polarity ref enable , */ \ + { 0x4ce0, \ + "int_polarity_flag_adc10_ready" }, /* Polarity Control ADC , */ \ + { 0x4cf0, \ + "int_polarity_flag_bod_vddd_nok" }, /* Polarity BOD , */ \ + { 0x4d00, \ + "int_polarity_flag_bst_bstcur" }, /* Polarity DCDC current limiting , */ \ + { 0x4d10, \ + "int_polarity_flag_bst_hiz" }, /* Polarity DCDC active , */ \ + { 0x4d20, \ + "int_polarity_flag_bst_ocpok" }, /* Polarity DCDC OCP , */ \ + { 0x4d30, \ + "int_polarity_flag_bst_peakcur" }, /* Polarity bst peakcur , */ \ + { 0x4d40, \ + "int_polarity_flag_bst_voutcomp" }, /* Polarity DCDC level 1x , */ \ + { 0x4d50, \ + "int_polarity_flag_bst_voutcomp86" }, /* Polarity DCDC level 1.14x , */ \ + { 0x4d60, \ + "int_polarity_flag_bst_voutcomp93" }, /* Polarity DCDC level 1.07x , */ \ + { 0x4d90, \ + "int_polarity_flag_ocp_alarm" }, /* Polarity ocp alarm , */ \ + { 0x4da0, \ + "int_polarity_flag_man_wait_src_settings" }, /* Polarity waits HW I2C settings , */ \ + { 0x4db0, \ + "int_polarity_flag_man_wait_cf_config" }, /* Polarity man wait cf config , */ \ + { 0x4dc0, \ + "int_polarity_flag_man_start_mute_audio" }, /* Polarity man audio mute sequence , */ \ + { 0x4dd0, \ + "int_polarity_flag_cfma_err" }, /* Polarity cfma err , */ \ + { 0x4de0, \ + "int_polarity_flag_cfma_ack" }, /* Polarity cfma ack , */ \ + { 0x4df0, \ + "int_polarity_flag_clk_out_of_range" }, /* Polarity flag_clk_out_of_range , */ \ + { 0x4e00, \ + "int_polarity_flag_tdm_error" }, /* Polarity tdm error , */ \ + { 0x4e20, \ + "int_polarity_flag_clip" }, /* Polarity clip , */ \ + { 0x4e50, \ + "int_polarity_flag_lp_detect_mode1" }, /* Polarity low power mode1 , */ \ + { 0x4e60, \ + "int_polarity_flag_low_amplitude" }, /* Polarity low amplitude detection , */ \ + { 0x4e70, \ + "int_polarity_flag_vddp_gt_vbat" }, /* Polarity VDDP greater than VBAT , */ \ + { 0x4e80, \ + "int_polarity_newtap" }, /* PolarityTap detected , */ \ + { 0x4e90, \ + "int_polarity_audiomodeactive" }, /* PolarityAudio Mode activated , */ \ + { 0x4ea0, \ + "int_polarity_sammodeactive" }, /* PolaritySAM Mode activated , */ \ + { 0x4eb0, \ + "int_polarity_tapmodeactive" }, /* Polarity Tap Mode Activated , */ \ + { 0x4ec0, \ + "int_polarity_flag_tap_comp_trig" }, /* PolarityTap Comparator Trigger , */ \ + { 0x5001, \ + "vbat_prot_attack_time" }, /* Battery Safeguard attack time , */ \ + { 0x5023, \ + "vbat_prot_thlevel" }, /* Battery Safeguard threshold voltage level , */ \ + { 0x5061, \ + "vbat_prot_max_reduct" }, /* Battery Safeguard maximum reduction , */ \ + { 0x5082, \ + "vbat_prot_release_time" }, /* Battery Safeguard release time , */ \ + { 0x50b1, \ + "vbat_prot_hysterese" }, /* Battery Safeguard hysteresis , */ \ + { 0x50d0, \ + "rst_min_vbat" }, /* Reset clipper - Auto clear , */ \ + { 0x50e0, \ + "sel_vbat" }, /* Battery voltage read out , */ \ + { 0x50f0, \ + "bypass_clipper" }, /* Bypass HW clipper , */ \ + { 0x5100, \ + "batsense_steepness" }, /* Vbat prot steepness , */ \ + { 0x5110, \ + "soft_mute" }, /* Soft mute HW , */ \ + { 0x5130, \ + "cf_mute" }, /* Soft mute FW , */ \ + { 0x5150, \ + "bypass_hp" }, /* Bypass HPF , */ \ + { 0x5170, \ + "enbl_dpsa" }, /* Enable DPSA , */ \ + { 0x5187, \ + "cf_volume" }, /* FW volume control for primary audio channel , */ \ + { 0x5222, \ + "ctrl_cc" }, /* Clip control setting , */ \ + { 0x5257, \ + "gain" }, /* Amplifier gain , */ \ + { 0x52d0, \ + "ctrl_slopectrl" }, /* Enables slope control , */ \ + { 0x52e0, \ + "ctrl_slope" }, /* Slope speed setting (bin. coded) , */ \ + { 0x5301, \ + "dpsa_level" }, /* DPSA threshold levels , */ \ + { 0x5321, \ + "dpsa_release" }, /* DPSA Release time , */ \ + { 0x5340, \ + "clipfast" }, /* Clock selection for HW clipper for Battery Safeguard, */ \ + { 0x5350, \ + "bypass_lp" }, /* Bypass the low power filter inside temperature sensor, */ \ + { 0x5360, \ + "enbl_low_latency" }, /* CF low latency outputs for add module , */ \ + { 0x5400, \ + "first_order_mode" }, /* Overrule to 1st order mode of control stage when clipping, */ \ + { 0x5410, \ + "bypass_ctrlloop" }, /* Switch amplifier into open loop configuration , */ \ + { 0x5430, \ + "icomp_engage" }, /* Engage of icomp , */ \ + { 0x5440, \ + "ctrl_kickback" }, /* Prevent double pulses of output stage , */ \ + { 0x5450, \ + "icomp_engage_overrule" }, /* To overrule the functional icomp_engage signal during validation, */ \ + { 0x5503, \ + "ctrl_dem" }, /* Enable DEM icomp and DEM one bit dac , */ \ + { 0x5543, \ + "ctrl_dem_mismatch" }, /* Enable DEM icomp mismatch for testing , */ \ + { 0x5582, \ + "dpsa_drive" }, /* Drive setting (bin. coded) - I2C direct mode , */ \ + { 0x570a, \ + "enbl_amp" }, /* Switch on the class-D power sections, each part of the analog sections can be switched on/off individually , */ \ + { 0x57b0, \ + "enbl_engage" }, /* Enables/engage power stage and control loop - I2C direct mode, */ \ + { 0x57c0, \ + "enbl_engage_pst" }, /* Enables/engage power stage and control loop , */ \ + { 0x5810, \ + "hard_mute" }, /* Hard mute - PWM , */ \ + { 0x5820, \ + "pwm_shape" }, /* PWM shape , */ \ + { 0x5844, \ + "pwm_delay" }, /* PWM delay bits to set the delay, clock is 1/(k*2048*fs), */ \ + { 0x5890, \ + "reclock_pwm" }, /* Reclock the pwm signal inside analog , */ \ + { 0x58a0, \ + "reclock_voltsense" }, /* Reclock the voltage sense pwm signal , */ \ + { 0x58c0, \ + "enbl_pwm_phase_shift" }, /* Control for pwm phase shift , */ \ + { 0x5c07, \ + "flag_cf_tap_pattern" }, /* Coolflux tap pattern , */ \ + { 0x5c83, \ + "tap_debug_info" }, /* Reserved , */ \ + { 0x5d0f, \ + "tap_status_1" }, /* Tap Status 1 from CF FW , */ \ + { 0x5f03, \ + "tap_comp_threshold" }, /* Comparator threshold (in uV) , */ \ + { 0x6081, \ + "pga_gain_set" }, /* PGA gain selection , */ \ + { 0x60b0, \ + "pga_lowpass_enable" }, /* Lowpass enable , */ \ + { 0x60c0, \ + "pga_pwr_enable" }, /* PGA power enable , */ \ + { 0x60d0, \ + "pga_switch_enable" }, /* PGA switch enable , */ \ + { 0x60e0, \ + "pga_switch_aux_enable" }, /* Switch enable aux , */ \ + { 0x6123, \ + "ctrl_att" }, /* System gain (INPLEV 0) , */ \ + { 0x6265, \ + "zero_lvl" }, /* ctrl threshold for zero X-ing , */ \ + { 0x62c1, \ + "ctrl_fb_resistor" }, /* Select amplifier feedback resistor connection , */ \ + { 0x62e1, \ + "lownoisegain_mode" }, /* ctrl select mode , */ \ + { 0x6305, \ + "threshold_lvl" }, /* ctrl threshold for low_audio_lvl , */ \ + { 0x6365, \ + "hold_time" }, /* ctrl hold time before low audio is reckoned to be low audio, */ \ + { 0x6405, \ + "lpm1_cal_offset" }, /* low power mode1 detector ctrl cal_offset from gain module , */ \ + { 0x6465, \ + "lpm1_zero_lvl" }, /* low power mode1 detector ctrl threshold for zero X-ing , */ \ + { 0x64e1, \ + "lpm1_mode" }, /* low power mode1 detector ctrl select mode , */ \ + { 0x6505, \ + "lpm1_threshold_lvl" }, /* low power mode1 detector ctrl threshold for low_audio_lvl , */ \ + { 0x6565, \ + "lpm1_hold_time" }, /* Low power mode1 detector, ctrl hold time before low audio is reckoned to be low audio, */ \ + { 0x65c0, \ + "disable_low_power_mode" }, /* low power mode1 detector control , */ \ + { 0x6600, \ + "dcdc_pfm20khz_limit" }, /* DCDC in PFM mode pwm mode is activated each 50us to force a pwm pulse, */ \ + { 0x6611, \ + "dcdc_ctrl_maxzercnt" }, /* DCDC. Number of zero current flags to count before going to pfm mode, */ \ + { 0x6630, \ + "dcdcoff_mode" }, /* DCDC , */ \ + { 0x6656, \ + "dcdc_vbat_delta_detect" }, /* Threshold before booster is reacting on a delta Vbat (in PFM mode) by temporarily switching to PWM mode, */ \ + { 0x66c0, \ + "dcdc_ignore_vbat" }, /* Ignore an increase on Vbat , */ \ + { 0x6700, \ + "enbl_minion" }, /* Enables minion (small) power stage - direct ctrl , */ \ + { 0x6713, \ + "vth_vddpvbat" }, /* select vddp-vbat thres signal , */ \ + { 0x6750, \ + "lpen_vddpvbat" }, /* select vddp-vbat filtered vs unfiltered compare , */ \ + { 0x6761, \ + "ctrl_rfb" }, /* Feedback resistor selection - I2C direct mode , */ \ + { 0x6801, \ + "tdm_source_mapping" }, /* tdm source mapping , */ \ + { 0x6821, \ + "tdm_sourcea_frame_sel" }, /* frame a selection , */ \ + { 0x6841, \ + "tdm_sourceb_frame_sel" }, /* frame b selection , */ \ + { 0x6901, \ + "sam_mode" }, /* Sam mode , */ \ + { 0x6931, \ + "pdmdat_h_sel" }, /* pdm out value when pdm_clk is higth , */ \ + { 0x6951, \ + "pdmdat_l_sel" }, /* pdm out value when pdm_clk is low , */ \ + { 0x6970, \ + "cs_sam_set" }, /* Enable SAM input for current sense - I2C Direct Mode, */ \ + { 0x6980, \ + "cs_adc_nortz" }, /* Return to zero for current sense ADC , */ \ + { 0x6990, \ + "sam_spkr_sel" }, /* SAM o/p sel during SAM and audio , */ \ + { 0x6b00, \ + "disable_engage" }, /* Disable auto engage , */ \ + { 0x6c02, \ + "ns_hp2ln_criterion" }, /* 0..7 zeroes at ns as threshold to swap from high_power to low_noise, */ \ + { 0x6c32, \ + "ns_ln2hp_criterion" }, /* 0..7 zeroes at ns as threshold to swap from low_noise to high_power, */ \ + { 0x6c60, \ + "sel_clip_pwms" }, /* To select clip-flags , */ \ + { 0x6c72, \ + "pwms_clip_lvl" }, /* To set the amount of pwm pulse that may be skipped before clip-flag is triggered. , */ \ + { 0x6ca5, \ + "spare_out" }, /* spare_out , */ \ + { 0x6d0f, \ + "spare_in" }, /* spare_in , */ \ + { 0x6e10, \ + "flag_lp_detect_mode1" }, /* low power mode 1 detection , */ \ + { 0x6e20, \ + "flag_low_amplitude" }, /* low amplitude detection , */ \ + { 0x6e30, \ + "flag_vddp_gt_vbat" }, /* vddp greater than vbat , */ \ + { 0x7033, \ + "boost_cur" }, /* Max coil current , */ \ + { 0x7071, \ + "bst_slpcmplvl" }, /* Slope compensation current, represents LxF (inductance x frequency) value , */ \ + { 0x7090, \ + "boost_intel" }, /* Adaptive boost mode , */ \ + { 0x70a0, \ + "boost_speed" }, /* Soft ramp up/down , */ \ + { 0x70c1, \ + "dcdc_sel" }, /* DCDC IIR input Selection , */ \ + { 0x70f0, \ + "dcdc_pwmonly" }, /* DCDC PWM only mode , */ \ + { 0x7104, \ + "bst_drive" }, /* Binary coded drive setting for boost converter power stage, */ \ + { 0x7151, \ + "bst_scalecur" }, /* For testing direct control scale current , */ \ + { 0x7174, \ + "bst_slopecur" }, /* For testing direct control slope current - I2C direct mode, */ \ + { 0x71c1, \ + "bst_slope" }, /* Boost slope speed , */ \ + { 0x71e0, \ + "bst_bypass_bstcur" }, /* Bypass control for boost current settings , */ \ + { 0x71f0, \ + "bst_bypass_bstfoldback" }, /* Bypass control for boost foldback , */ \ + { 0x7200, \ + "enbl_bst_engage" }, /* Enable power stage dcdc controller - I2C direct mode, */ \ + { 0x7210, \ + "enbl_bst_hizcom" }, /* Enable hiz comparator - I2C direct mode , */ \ + { 0x7220, \ + "enbl_bst_peak2avg" }, /* Enable boost peak2avg functionality , */ \ + { 0x7230, \ + "enbl_bst_peakcur" }, /* Enable peak current - I2C direct mode , */ \ + { 0x7240, \ + "enbl_bst_power" }, /* Enable line of the powerstage - I2C direct mode , */ \ + { 0x7250, \ + "enbl_bst_slopecur" }, /* Enable bit of max-current dac - I2C direct mode , */ \ + { 0x7260, \ + "enbl_bst_voutcomp" }, /* Enable vout comparators - I2C direct mode , */ \ + { 0x7270, \ + "enbl_bst_voutcomp86" }, /* Enable vout-86 comparators - I2C direct mode , */ \ + { 0x7280, \ + "enbl_bst_voutcomp93" }, /* Enable vout-93 comparators - I2C direct mode , */ \ + { 0x7290, \ + "enbl_bst_windac" }, /* Enable window dac - I2C direct mode , */ \ + { 0x72a5, \ + "bst_windac" }, /* for testing direct control windac - I2C direct mode, */ \ + { 0x7300, \ + "boost_alg" }, /* Control for boost adaptive loop gain , */ \ + { 0x7311, \ + "boost_loopgain" }, /* DCDC boost loopgain setting , */ \ + { 0x7331, \ + "bst_freq" }, /* DCDC boost frequency control , */ \ + { 0x7430, \ + "boost_track" }, /* Boost algorithm selection, effective only when boost_intelligent is set to 1, */ \ + { 0x7494, \ + "boost_hold_time" }, /* Hold time for DCDC booster, effective only when boost_intelligent is set to 1, */ \ + { 0x74e0, \ + "sel_dcdc_envelope_8fs" }, /* Selection of data for adaptive boost algorithm, effective only when boost_intelligent is set to 1, */ \ + { 0x74f0, \ + "ignore_flag_voutcomp86" }, /* Ignore flag_voutcomp86 , */ \ + { 0x7504, \ + "boost_trip_lvl_1st" }, /* Adaptive boost trip levels 1, effective only when boost_intelligent is set to 1, */ \ + { 0x7554, \ + "boost_trip_lvl_2nd" }, /* Adaptive boost trip level 2, effective only when boost_intelligent is set to 1, */ \ + { 0x75a4, \ + "boost_trip_lvl_track" }, /* Adaptive boost trip levels, effective only when boost_intelligent is set to 1, */ \ + { 0x7602, \ + "track_decay" }, /* DCDC Boost decay speed after a peak value, effective only when boost_track is set to 1, */ \ + { 0x7635, \ + "frst_boost_voltage" }, /* First boost voltage level , */ \ + { 0x7695, \ + "scnd_boost_voltage" }, /* Second boost voltage level , */ \ + { 0x7720, \ + "pga_test_ldo_bypass" }, /* bypass internal PGA LDO , */ \ + { 0x8001, \ + "sel_clk_cs" }, /* Current sense clock duty cycle control , */ \ + { 0x8021, \ + "micadc_speed" }, /* Current sense clock for MiCADC selection - 32/44.1/48 KHz Fs band only, */ \ + { 0x8050, \ + "cs_gain_control" }, /* Current sense gain control , */ \ + { 0x8060, \ + "cs_bypass_gc" }, /* Bypasses the CS gain correction , */ \ + { 0x8087, \ + "cs_gain" }, /* Current sense gain , */ \ + { 0x8200, \ + "enbl_cmfb" }, /* Current sense common mode feedback control , */ \ + { 0x8210, \ + "invertpwm" }, /* Current sense common mode feedback pwm invert control, */ \ + { 0x8222, \ + "cmfb_gain" }, /* Current sense common mode feedback control gain , */ \ + { 0x8256, \ + "cmfb_offset" }, /* Current sense common mode feedback control offset , */ \ + { 0x8305, \ + "cs_ktemp" }, /* First order temperature compensation coefficient , */ \ + { 0x8364, \ + "cs_ktemp2" }, /* Second order temperature compensation coefficient , */ \ + { 0x8400, \ + "cs_adc_bsoinv" }, /* Bitstream inversion for current sense ADC , */ \ + { 0x8421, \ + "cs_adc_hifreq" }, /* Frequency mode current sense ADC , */ \ + { 0x8453, \ + "cs_adc_offset" }, /* Micadc ADC offset setting , */ \ + { 0x8490, \ + "cs_adc_slowdel" }, /* Select delay for current sense ADC (internal decision circuitry), */ \ + { 0x84a4, \ + "cs_adc_gain" }, /* Gain setting for current sense ADC (two's complement), */ \ + { 0x8500, \ + "cs_resonator_enable" }, /* Enable for resonator to improve SRN , */ \ + { 0x8510, \ + "cs_classd_tran_skip" }, /* Skip current sense connection during a classD amplifier transition, */ \ + { 0x8530, \ + "cs_inn_short" }, /* Short current sense negative to common mode , */ \ + { 0x8540, \ + "cs_inp_short" }, /* Short current sense positive to common mode , */ \ + { 0x8550, \ + "cs_ldo_bypass" }, /* Bypass current sense LDO , */ \ + { 0x8560, \ + "cs_ldo_pulldown" }, /* Pull down current sense LDO, only valid if left_enbl_cs_ldo is high, */ \ + { 0x8574, \ + "cs_ldo_voset" }, /* Current sense LDO voltage level setting (two's complement), */ \ + { 0x8700, \ + "enbl_cs_adc" }, /* Enable current sense ADC - I2C direct mode , */ \ + { 0x8710, \ + "enbl_cs_inn1" }, /* Enable connection of current sense negative1 - I2C direct mode, */ \ + { 0x8720, \ + "enbl_cs_inn2" }, /* Enable connection of current sense negative2 - I2C direct mode, */ \ + { 0x8730, \ + "enbl_cs_inp1" }, /* Enable connection of current sense positive1 , */ \ + { 0x8740, \ + "enbl_cs_inp2" }, /* Enable connection of current sense positive2 - I2C direct mode, */ \ + { 0x8750, \ + "enbl_cs_ldo" }, /* Enable current sense LDO - I2C direct mode , */ \ + { 0x8760, \ + "enbl_cs_nofloating_n" }, /* Connect current sense negative to gnda at transitions of booster or classd amplifiers. Otherwise floating (0), */ \ + { 0x8770, \ + "enbl_cs_nofloating_p" }, /* Connect current sense positive to gnda at transitions of booster or classd amplifiers. Otherwise floating (0), */ \ + { 0x8780, \ + "enbl_cs_vbatldo" }, /* Enable of current sense LDO -- I2C direct mode , */ \ + { 0x8800, \ + "volsense_pwm_sel" }, /* Voltage sense PWM source selection control , */ \ + { 0x8810, \ + "vol_cur_sense_dc_offset" }, /* voltage and current sense decimator offset control, */ \ + { 0x8902, \ + "cursense_comp_delay" }, /* To align compensation signal with current sense signal, */ \ + { 0x8930, \ + "cursense_comp_sign" }, /* To change polarity of compensation for current sense compensation, */ \ + { 0x8940, \ + "enbl_cursense_comp" }, /* To enable current sense compensation , */ \ + { 0x9000, \ + "cf_rst_dsp" }, /* Reset , */ \ + { 0x9011, \ + "cf_dmem" }, /* Target memory , */ \ + { 0x9030, \ + "cf_aif" }, /* Auto increment , */ \ + { 0x9040, \ + "cf_int" }, /* Interrupt - auto clear , */ \ + { 0x9050, \ + "cf_cgate_off" }, /* Coolflux clock gating disabling control , */ \ + { 0x9080, \ + "cf_req_cmd" }, /* Firmware event request rpc command , */ \ + { 0x9090, \ + "cf_req_reset" }, /* Firmware event request reset restart , */ \ + { 0x90a0, \ + "cf_req_mips" }, /* Firmware event request short on mips , */ \ + { 0x90b0, \ + "cf_req_mute_ready" }, /* Firmware event request mute sequence ready , */ \ + { 0x90c0, \ + "cf_req_volume_ready" }, /* Firmware event request volume ready , */ \ + { 0x90d0, \ + "cf_req_damage" }, /* Firmware event request speaker damage detected , */ \ + { 0x90e0, \ + "cf_req_calibrate_ready" }, /* Firmware event request calibration completed , */ \ + { 0x90f0, \ + "cf_req_reserved" }, /* Firmware event request reserved , */ \ + { 0x910f, \ + "cf_madd" }, /* Memory address , */ \ + { 0x920f, \ + "cf_mema" }, /* Activate memory access , */ \ + { 0x9307, \ + "cf_err" }, /* Error flags , */ \ + { 0x9380, \ + "cf_ack_cmd" }, /* Firmware event acknowledge rpc command , */ \ + { 0x9390, \ + "cf_ack_reset" }, /* Firmware event acknowledge reset restart , */ \ + { 0x93a0, \ + "cf_ack_mips" }, /* Firmware event acknowledge short on mips , */ \ + { 0x93b0, \ + "cf_ack_mute_ready" }, /* Firmware event acknowledge mute sequence ready , */ \ + { 0x93c0, \ + "cf_ack_volume_ready" }, /* Firmware event acknowledge volume ready , */ \ + { 0x93d0, \ + "cf_ack_damage" }, /* Firmware event acknowledge speaker damage detected, */ \ + { 0x93e0, \ + "cf_ack_calibrate_ready" }, /* Firmware event acknowledge calibration completed , */ \ + { 0x93f0, \ + "cf_ack_reserved" }, /* Firmware event acknowledge reserved , */ \ + { 0xa007, \ + "mtpkey1" }, /* 5Ah, 90d To access KEY1_Protected registers (Default for engineering), */ \ + { 0xa107, \ + "mtpkey2" }, /* MTP KEY2 register , */ \ + { 0xa200, \ + "key01_locked" }, /* Indicates KEY1 is locked , */ \ + { 0xa210, \ + "key02_locked" }, /* Indicates KEY2 is locked , */ \ + { 0xa302, \ + "mtp_man_address_in" }, /* MTP address from I2C register for read/writing mtp in manual single word mode, */ \ + { 0xa330, \ + "man_copy_mtp_to_iic" }, /* Start copying single word from mtp to I2C mtp register, */ \ + { 0xa340, \ + "man_copy_iic_to_mtp" }, /* Start copying single word from I2C mtp register to mtp, */ \ + { 0xa350, \ + "auto_copy_mtp_to_iic" }, /* Start copying all the data from mtp to I2C mtp registers, */ \ + { 0xa360, \ + "auto_copy_iic_to_mtp" }, /* Start copying data from I2C mtp registers to mtp , */ \ + { 0xa400, \ + "faim_set_clkws" }, /* Sets the FaIM controller clock wait state register, */ \ + { 0xa410, \ + "faim_sel_evenrows" }, /* All even rows of the FaIM are selected, active high, */ \ + { 0xa420, \ + "faim_sel_oddrows" }, /* All odd rows of the FaIM are selected, all rows in combination with sel_evenrows, */ \ + { 0xa430, \ + "faim_program_only" }, /* Skip the erase access at wr_faim command (write-program-marginread), */ \ + { 0xa440, \ + "faim_erase_only" }, /* Skip the program access at wr_faim command (write-erase-marginread), */ \ + { 0xa50f, \ + "mtp_man_data_out_msb" }, /* MSB word of MTP manual read data , */ \ + { 0xa60f, \ + "mtp_man_data_out_lsb" }, /* LSB word of MTP manual read data , */ \ + { 0xa70f, \ + "mtp_man_data_in_msb" }, /* MSB word of write data for MTP manual write , */ \ + { 0xa80f, \ + "mtp_man_data_in_lsb" }, /* LSB word of write data for MTP manual write , */ \ + { 0xb010, \ + "bypass_ocpcounter" }, /* Bypass OCP Counter , */ \ + { 0xb020, \ + "bypass_glitchfilter" }, /* Bypass glitch filter , */ \ + { 0xb030, \ + "bypass_ovp" }, /* Bypass OVP , */ \ + { 0xb040, \ + "bypass_uvp" }, /* Bypass UVP , */ \ + { 0xb050, \ + "bypass_otp" }, /* Bypass OTP , */ \ + { 0xb060, \ + "bypass_lost_clk" }, /* Bypass lost clock detector , */ \ + { 0xb070, \ + "ctrl_vpalarm" }, /* vpalarm (uvp ovp handling) , */ \ + { 0xb087, \ + "ocp_threshold" }, /* OCP threshold level , */ \ + { 0xb108, \ + "ext_temp" }, /* External temperature (C) , */ \ + { 0xb190, \ + "ext_temp_sel" }, /* Select temp Speaker calibration , */ \ + { 0xc000, \ + "use_direct_ctrls" }, /* Direct control to overrule several functions for testing, */ \ + { 0xc010, \ + "rst_datapath" }, /* Direct control for datapath reset , */ \ + { 0xc020, \ + "rst_cgu" }, /* Direct control for cgu reset , */ \ + { 0xc038, \ + "enbl_ref" }, /* Switch on the analog references, each part of the references can be switched on/off individually - - I2C direct mode, */ \ + { 0xc0d0, \ + "enbl_ringo" }, /* Enable the ring oscillator for test purpose , */ \ + { 0xc0e0, \ + "use_direct_clk_ctrl" }, /* Direct clock control to overrule several functions for testing, */ \ + { 0xc0f0, \ + "use_direct_pll_ctrl" }, /* Direct PLL control to overrule several functions for testing, */ \ + { 0xc100, \ + "enbl_tsense" }, /* Temperature sensor enable control - I2C direct mode, */ \ + { 0xc110, \ + "tsense_hibias" }, /* Bit to set the biasing in temp sensor to high - I2C direct mode, */ \ + { 0xc120, \ + "enbl_flag_vbg" }, /* Enable flagging of bandgap out of control , */ \ + { 0xc130, \ + "tap_comp_enable" }, /* Tap Comparator enable control - I2C direct mode , */ \ + { 0xc140, \ + "tap_comp_switch_enable" }, /* Tap Comparator Switch enable control - I2C direct mode, */ \ + { 0xc150, \ + "tap_comp_switch_aux_enable" }, /* Tap Comparator Switch enable control - I2C direct mode, */ \ + { 0xc161, \ + "tap_comp_test_enable" }, /* Comparator threshold - fine value , */ \ + { 0xc180, \ + "curdist_enable" }, /* Enable control - I2C direct mode , */ \ + { 0xc190, \ + "vbg2i_enbl" }, /* Enable control - I2C direct mode , */ \ + { 0xc1a0, \ + "bg_filt_bypass_enbl" }, /* Enable control , */ \ + { 0xc20f, \ + "abist_offset" }, /* Offset control for ABIST testing (two's complement), */ \ + { 0xc300, \ + "bypasslatch" }, /* Bypass latch , */ \ + { 0xc311, \ + "sourcea" }, /* Set OUTA to , */ \ + { 0xc331, \ + "sourceb" }, /* Set OUTB to , */ \ + { 0xc350, \ + "inverta" }, /* Invert pwma test signal , */ \ + { 0xc360, \ + "invertb" }, /* Invert pwmb test signal , */ \ + { 0xc374, \ + "pulselength" }, /* Pulse length setting test input for amplifier (clock d - k*2048*fs), */ \ + { 0xc3c0, \ + "tdm_enable_loopback" }, /* TDM loopback test , */ \ + { 0xc3d0, \ + "test_abistfft_enbl" }, /* FFT Coolflux , */ \ + { 0xc3e0, \ + "test_pwr_switch" }, /* Test mode for digital power switches core sw/mem sw/micvdd sw, */ \ + { 0xc400, \ + "bst_bypasslatch" }, /* Bypass latch in boost converter , */ \ + { 0xc411, \ + "bst_source" }, /* Sets the source of the pwmbst output to boost converter input for testing, */ \ + { 0xc430, \ + "bst_invertb" }, /* Invert pwmbst test signal , */ \ + { 0xc444, \ + "bst_pulselength" }, /* Pulse length setting test input for boost converter , */ \ + { 0xc490, \ + "test_bst_ctrlsthv" }, /* Test mode for boost control stage , */ \ + { 0xc4a0, \ + "test_bst_iddq" }, /* IDDQ testing in power stage of boost converter , */ \ + { 0xc4b0, \ + "test_bst_rdson" }, /* RDSON testing - boost power stage , */ \ + { 0xc4c0, \ + "test_bst_cvi" }, /* CVI testing - boost power stage , */ \ + { 0xc4d0, \ + "test_bst_ocp" }, /* Boost OCP. For old ocp (ctrl_reversebst is 0), For new ocp (ctrl_reversebst is 1), */ \ + { 0xc4e0, \ + "test_bst_sense" }, /* Test option for the sense NMOS in booster for current mode control., */ \ + { 0xc500, \ + "test_cvi" }, /* Analog BIST, switch choose which transistor will be used as current source (also cross coupled sources possible), */ \ + { 0xc510, \ + "test_discrete" }, /* Test function noise measurement , */ \ + { 0xc520, \ + "test_iddq" }, /* Set the power stages in iddq mode for gate stress., */ \ + { 0xc540, \ + "test_rdson" }, /* Analog BIST, switch to enable Rdson measurement , */ \ + { 0xc550, \ + "test_sdelta" }, /* Analog BIST, noise test , */ \ + { 0xc560, \ + "bypass_fro8" }, /* Bypass fro8 with pdm_clk , */ \ + { 0xc570, \ + "test_enbl_cs" }, /* Enable for digimux mode of current sense , */ \ + { 0xc5b0, \ + "pga_test_enable" }, /* Enable PGA test mode , */ \ + { 0xc5c0, \ + "pga_test_offset_enable" }, /* Enable PGA test offset , */ \ + { 0xc5d0, \ + "pga_test_shortinput_enable" }, /* Enable PGA test short input , */ \ + { 0xc600, \ + "enbl_pwm_dcc" }, /* Enables direct control of pwm duty cycle for DCDC power stage, */ \ + { 0xc613, \ + "pwm_dcc_cnt" }, /* Control pwm duty cycle when enbl_pwm_dcc is 1 , */ \ + { 0xc650, \ + "enbl_ldo_stress" }, /* Enable stress of internal supply voltages powerstages, */ \ + { 0xc660, \ + "enbl_powerswitch" }, /* Vddd core power switch control - overrules the manager control, */ \ + { 0xc707, \ + "digimuxa_sel" }, /* DigimuxA input selection control routed to DIO4 (see Digimux list for details), */ \ + { 0xc787, \ + "digimuxb_sel" }, /* DigimuxB input selection control routed to DIO3 (see Digimux list for details), */ \ + { 0xc807, \ + "digimuxc_sel" }, /* DigimuxC input selection control routed to TDO (see Digimux list for details), */ \ + { 0xc901, \ + "dio1_ehs" }, /* Speed/load setting for DIO1 IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc921, \ + "dio2_ehs" }, /* Speed/load setting for DIO2 IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc941, \ + "dio3_ehs" }, /* Speed/load setting for DIO3 cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc961, \ + "dio4_ehs" }, /* Speed/load setting for DIO4 IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc981, \ + "spdmo_ehs" }, /* Speed/load setting for PDMO IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc9a1, \ + "tdo_ehs" }, /* Speed/load setting for TDM IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */ \ + { 0xc9c0, \ + "int_ehs" }, /* Slew Rate INT IO cell, clk or data mode range (see IIC3V3 IO cell datasheet), */ \ + { 0xc9d0, \ + "pdmclk_ehs" }, /* Slew RateBCK2/PDMCLK IO cell, clk or data mode range (see IIC3V3 IO cell datasheet), */ \ + { 0xc9e0, \ + "fs2_ehs" }, /* Slew Rate DS2 IO cell, clk or data mode range (see IIC3V3 IO cell datasheet), */ \ + { 0xc9f0, \ + "hs_mode" }, /* I2C high speed mode control , */ \ + { 0xca00, \ + "enbl_anamux1" }, /* Enable anamux1 , */ \ + { 0xca10, \ + "enbl_anamux2" }, /* Enable anamux2 , */ \ + { 0xca20, \ + "enbl_anamux3" }, /* Enable anamux3 , */ \ + { 0xca30, \ + "enbl_anamux4" }, /* Enable anamux4 , */ \ + { 0xca74, \ + "anamux1" }, /* Anamux selection control - anamux on TEST1 , */ \ + { 0xcb04, \ + "anamux2" }, /* Anamux selection control - anamux on TEST2 , */ \ + { 0xcb54, \ + "anamux3" }, /* Anamux selection control - anamux on TEST3 , */ \ + { 0xcba4, \ + "anamux4" }, /* Anamux selection control - anamux on TEST4 , */ \ + { 0xcc05, \ + "pll_seli_lbw" }, /* PLL SELI - Low B/W PLL control mode or I2C direct PLL control mode only, */ \ + { 0xcc64, \ + "pll_selp_lbw" }, /* PLL SELP - Low B/W PLL control mode or I2C direct PLL control mode only, */ \ + { 0xccb3, \ + "pll_selr_lbw" }, /* PLL SELR - Low B/W PLL control mode or I2C direct PLL control mode only, */ \ + { 0xccf0, \ + "sel_user_pll_bw" }, /* PLL Low Bandwidth Mode control , */ \ + { 0xcdf0, \ + "pll_frm" }, /* PLL free running mode control; 1 in TCB direct control mode, else this control bit, */ \ + { 0xce09, \ + "pll_ndec" }, /* PLL NDEC - I2C direct PLL control mode only , */ \ + { 0xcea0, \ + "pll_mdec_msb" }, /* MSB of pll_mdec - I2C direct PLL control mode only, */ \ + { 0xceb0, \ + "enbl_pll" }, /* Enables PLL in I2C direct PLL control mode only , */ \ + { 0xcec0, \ + "enbl_fro8" }, /* Enables FRO8M in I2C direct control mode only , */ \ + { 0xced0, \ + "pll_bypass" }, /* PLL bypass control in I2C direct PLL control mode only, */ \ + { 0xcee0, \ + "pll_directi" }, /* PLL directi control in I2C direct PLL control mode only, */ \ + { 0xcef0, \ + "pll_directo" }, /* PLL directo control in I2C direct PLL control mode only, */ \ + { 0xcf0f, \ + "pll_mdec_lsb" }, /* Bits 15..0 of PLL MDEC are I2C direct PLL control mode only, */ \ + { 0xd006, \ + "pll_pdec" }, /* PLL PDEC - I2C direct PLL control mode only , */ \ + { 0xd10f, \ + "tsig_freq_lsb" }, /* Internal sinus test generator frequency control , */ \ + { 0xd202, \ + "tsig_freq_msb" }, /* Select internal sinus test generator, frequency control msb bits, */ \ + { 0xd230, \ + "inject_tsig" }, /* Control bit to switch to internal sinus test generator, */ \ + { 0xd283, \ + "tsig_gain" }, /* Test signal gain , */ \ + { 0xd300, \ + "adc10_reset" }, /* Reset for ADC10 - I2C direct control mode , */ \ + { 0xd311, \ + "adc10_test" }, /* Test mode selection signal for ADC10 - I2C direct control mode, */ \ + { 0xd332, \ + "adc10_sel" }, /* Select the input to convert for ADC10 - I2C direct control mode, */ \ + { 0xd364, \ + "adc10_prog_sample" }, /* ADC10 program sample setting - I2C direct control mode, */ \ + { 0xd3b0, \ + "adc10_enbl" }, /* Enable ADC10 - I2C direct control mode , */ \ + { 0xd3c0, \ + "bypass_lp_vbat" }, /* Bypass control for Low pass filter in batt sensor , */ \ + { 0xd409, \ + "data_adc10_tempbat" }, /* ADC 10 data output data for testing , */ \ + { 0xd507, \ + "ctrl_digtoana_hidden" }, /* Spare digital to analog control bits - Hidden , */ \ + { 0xd580, \ + "enbl_clk_range_chk" }, /* Clock out of range , */ \ + { 0xd601, \ + "clkdiv_dsp_sel" }, /* DSP clock divider selection in direct clock control mode, */ \ + { 0xd621, \ + "clkdiv_audio_sel" }, /* Audio clock divider selection in direct clock control mode, */ \ + { 0xd641, \ + "clkdiv_muxa_sel" }, /* DCDC MUXA clock divider selection in direct clock control mode, */ \ + { 0xd661, \ + "clkdiv_muxb_sel" }, /* DCDC MUXB clock divider selection in direct clock control mode, */ \ + { 0xd681, \ + "dsp_tap_clk" }, /* Dsp clock frequency selection in TAP mode; , */ \ + { 0xd6a1, \ + "sel_wdt_clk" }, /* Watch dog clock post divider value , */ \ + { 0xd6c1, \ + "sel_tim_clk" }, /* Timer clock post divider value , */ \ + { 0xd700, \ + "ads1_ehs" }, /* Slew Rate ADS1 IO cell, clk or data mode range (see IIC3V3 IO cell datasheet), */ \ + { 0xd710, \ + "ads2_ehs" }, /* Slew Rate ADS2 IO cell, clk or data mode range (see IIC3V3 IO cell datasheet), */ \ + { 0xd822, \ + "test_parametric_io" }, /* test io parametric , */ \ + { 0xd850, \ + "ctrl_bst_clk_lp1" }, /* boost clock control in low power mode1 , */ \ + { 0xd861, \ + "test_spare_out1" }, /* test spare out 1 , */ \ + { 0xd880, \ + "bst_dcmbst" }, /* dcm boost - I2C direct mode , */ \ + { 0xd8a1, \ + "force_pga_clock" }, /* force pga clock , */ \ + { 0xd8c3, \ + "test_spare_out2" }, /* test spare out 1 , */ \ + { 0xd900, \ + "overrules_usercase" }, /* Overrule Mode control use , */ \ + { 0xd910, \ + "ovr_switch_ref" }, /* Overrule Value , */ \ + { 0xd920, \ + "ovr_enbl_pll" }, /* Overrule Value , */ \ + { 0xd930, \ + "ovr_switch_amp" }, /* Overrule Value , */ \ + { 0xd940, \ + "ovr_enbl_clk_cs" }, /* Overrule Value , */ \ + { 0xd951, \ + "ovr_sel_clk_cs" }, /* CS clock selection overrule , */ \ + { 0xd970, \ + "ovr_switch_cs" }, /* Overrule Value , */ \ + { 0xd980, \ + "ovr_enbl_csvs_ss" }, /* Overrule Value , */ \ + { 0xd990, \ + "ovr_enbl_comp" }, /* Overrule Value , */ \ + { 0xed00, \ + "enbl_fro8cal" }, /* Enable FRO calibration , */ \ + { 0xed10, \ + "start_fro8_calibration" }, /* Start FRO8 Calibration , */ \ + { 0xed20, \ + "fro8_calibration_done" }, /* FRO8 Calibration done - Read Only , */ \ + { 0xed45, \ + "fro8_auto_trim_val" }, /* Calibration value from Auto Calibration block, to be written into MTP - Read Only, */ \ + { 0xee0f, \ + "sw_profile" }, /* Software profile data , */ \ + { 0xef0f, \ + "sw_vstep" }, /* Software vstep information , */ \ + { 0xf000, \ + "calibration_onetime" }, /* Calibration schedule , */ \ + { 0xf010, \ + "calibr_ron_done" }, /* Calibration Ron executed , */ \ + { 0xf020, \ + "calibr_dcdc_api_calibrate" }, /* Calibration current limit DCDC , */ \ + { 0xf030, \ + "calibr_dcdc_delta_sign" }, /* Sign bit for delta calibration current limit DCDC , */ \ + { 0xf042, \ + "calibr_dcdc_delta" }, /* Calibration delta current limit DCDC , */ \ + { 0xf078, \ + "calibr_speaker_info" }, /* Reserved space for allowing customer to store speaker information, */ \ + { 0xf105, \ + "calibr_vout_offset" }, /* DCDC offset calibration 2's complement (key1 protected), */ \ + { 0xf163, \ + "spare_mtp1_9_6" }, /* HW gain module - left channel (2's complement) , */ \ + { 0xf1a5, \ + "spare_mtp1_15_10" }, /* Offset for amplifier, HW gain module - left channel (2's complement), */ \ + { 0xf203, \ + "calibr_gain" }, /* HW gain module (2's complement) , */ \ + { 0xf245, \ + "calibr_offset" }, /* Offset for amplifier, HW gain module (2's complement), */ \ + { 0xf2a3, \ + "spare_mtp2_13_10" }, /* Trimming of LDO (2.7V) , */ \ + { 0xf307, \ + "spare_mtp3_7_0" }, /* SPARE , */ \ + { 0xf387, \ + "calibr_gain_cs" }, /* Current sense gain (signed two's complement format), */ \ + { 0xf40f, \ + "calibr_R25C" }, /* Ron resistance of speaker coil , */ \ + { 0xf50f, \ + "spare_mtp5_15_0" }, /* SPARE , */ \ + { 0xf600, \ + "mtp_lock_enbl_coolflux" }, /* Disable function dcdcoff_mode , */ \ + { 0xf610, \ + "mtp_pwm_delay_enbl_clk_auto_gating" }, /* Auto clock gating on pwm_delay , */ \ + { 0xf620, \ + "mtp_ocp_enbl_clk_auto_gating" }, /* Auto clock gating on module ocp , */ \ + { 0xf630, \ + "mtp_disable_clk_a_gating" }, /* Disable clock_a gating , */ \ + { 0xf642, \ + "spare_mtp6_6_3" }, /* SPARE , */ \ + { 0xf686, \ + "spare_mtp6_14_8" }, /* Offset of left amplifier level shifter B , */ \ + { 0xf706, \ + "ctrl_offset_a" }, /* Offset of level shifter A , */ \ + { 0xf786, \ + "ctrl_offset_b" }, /* Offset of amplifier level shifter B , */ \ + { 0xf806, \ + "htol_iic_addr" }, /* 7-bit I2C address to be used during HTOL testing , */ \ + { 0xf870, \ + "htol_iic_addr_en" }, /* HTOL I2C address enable control , */ \ + { 0xf884, \ + "calibr_temp_offset" }, /* Temperature offset 2's compliment (key1 protected), */ \ + { 0xf8d2, \ + "calibr_temp_gain" }, /* Temperature gain 2's compliment (key1 protected) , */ \ + { 0xf910, \ + "disable_sam_mode" }, /* Disable sam mode , */ \ + { 0xf920, \ + "mtp_lock_bypass_clipper" }, /* Disable function bypass_clipper , */ \ + { 0xf930, \ + "mtp_lock_max_dcdc_voltage" }, /* Disable programming of max dcdc boost voltage , */ \ + { 0xf943, \ + "calibr_vbg_trim" }, /* Bandgap trimming control , */ \ + { 0xf987, \ + "type_bits_fw" }, /* MTP-control FW - See Firmware I2C API document for details, */ \ + { 0xfa0f, \ + "mtpdataA" }, /* MTPdataA (key1 protected) , */ \ + { 0xfb0f, \ + "mtpdataB" }, /* MTPdataB (key1 protected) , */ \ + { 0xfc0f, \ + "mtpdataC" }, /* MTPdataC (key1 protected) , */ \ + { 0xfd0f, \ + "mtpdataD" }, /* MTPdataD (key1 protected) , */ \ + { 0xfe0f, \ + "mtpdataE" }, /* MTPdataE (key1 protected) , */ \ + { 0xff05, \ + "fro8_trim" }, /* 8 MHz oscillator trim code , */ \ + { 0xff61, \ + "fro8_short_nwell_r" }, /* Short 4 or 6 n-well resistors , */ \ + { 0xff81, \ + "fro8_boost_i" }, /* Self bias current selection , */ \ + { 0xffff, "Unknown bitfield enum" } /* not found */ \ + }; + +enum tfa9912_irq { + tfa9912_irq_stvdds = 0, + tfa9912_irq_stplls = 1, + tfa9912_irq_stotds = 2, + tfa9912_irq_stovds = 3, + tfa9912_irq_stuvds = 4, + tfa9912_irq_stclks = 5, + tfa9912_irq_stmtpb = 6, + tfa9912_irq_stnoclk = 7, + tfa9912_irq_stspks = 8, + tfa9912_irq_stacs = 9, + tfa9912_irq_stsws = 10, + tfa9912_irq_stwds = 11, + tfa9912_irq_stamps = 12, + tfa9912_irq_starefs = 13, + tfa9912_irq_stadccr = 14, + tfa9912_irq_stbodnok = 15, + tfa9912_irq_stbstcu = 16, + tfa9912_irq_stbsthi = 17, + tfa9912_irq_stbstoc = 18, + tfa9912_irq_stbstpkcur = 19, + tfa9912_irq_stbstvc = 20, + tfa9912_irq_stbst86 = 21, + tfa9912_irq_stbst93 = 22, + tfa9912_irq_strcvld = 23, + tfa9912_irq_stocpl = 24, + tfa9912_irq_stocpr = 25, + tfa9912_irq_stmwsrc = 26, + tfa9912_irq_stmwcfc = 27, + tfa9912_irq_stmwsmu = 28, + tfa9912_irq_stcfmer = 29, + tfa9912_irq_stcfmac = 30, + tfa9912_irq_stclkoor = 31, + tfa9912_irq_sttdmer = 32, + tfa9912_irq_stclpl = 33, + tfa9912_irq_stclpr = 34, + tfa9912_irq_stocpm = 35, + tfa9912_irq_stlp1 = 37, + tfa9912_irq_stla = 38, + tfa9912_irq_stvddp = 39, + tfa9912_irq_sttapdet = 40, + tfa9912_irq_staudmod = 41, + tfa9912_irq_stsammod = 42, + tfa9912_irq_sttapmod = 43, + tfa9912_irq_sttaptrg = 44, + tfa9912_irq_max = 45, + tfa9912_irq_all = -1 /* all irqs */ +}; + +#define TFA9912_IRQ_NAMETABLE \ + static tfaIrqName_t Tfa9912IrqNames[] = { \ + { 0, "STVDDS" }, { 1, "STPLLS" }, { 2, "STOTDS" }, \ + { 3, "STOVDS" }, { 4, "STUVDS" }, { 5, "STCLKS" }, \ + { 6, "STMTPB" }, { 7, "STNOCLK" }, { 8, "STSPKS" }, \ + { 9, "STACS" }, { 10, "STSWS" }, { 11, "STWDS" }, \ + { 12, "STAMPS" }, { 13, "STAREFS" }, { 14, "STADCCR" }, \ + { 15, "STBODNOK" }, { 16, "STBSTCU" }, { 17, "STBSTHI" }, \ + { 18, "STBSTOC" }, { 19, "STBSTPKCUR" }, { 20, "STBSTVC" }, \ + { 21, "STBST86" }, { 22, "STBST93" }, { 23, "STRCVLD" }, \ + { 24, "STOCPL" }, { 25, "STOCPR" }, { 26, "STMWSRC" }, \ + { 27, "STMWCFC" }, { 28, "STMWSMU" }, { 29, "STCFMER" }, \ + { 30, "STCFMAC" }, { 31, "STCLKOOR" }, { 32, "STTDMER" }, \ + { 33, "STCLPL" }, { 34, "STCLPR" }, { 35, "STOCPM" }, \ + { 36, "36" }, { 37, "STLP1" }, { 38, "STLA" }, \ + { 39, "STVDDP" }, { 40, "STTAPDET" }, { 41, "STAUDMOD" }, \ + { 42, "STSAMMOD" }, { 43, "STTAPMOD" }, { 44, "STTAPTRG" }, \ + }; +#endif /* _TFA9912_TFAFIELDNAMES_H */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_container.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_container.h new file mode 100644 index 000000000000..5ec02468884b --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_container.h @@ -0,0 +1,379 @@ +/* + * Copyright 2013-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * tfaContainer.h + * + * Created on: Sep 11, 2013 + * Author: wim + */ + +#ifndef TFACONTAINER_H_ +#define TFACONTAINER_H_ + +/* static limits */ +#define TFACONT_MAXDEVS (4) /* maximum nr of devices */ +#define TFACONT_MAXPROFS (16) /* maximum nr of profiles */ + +#include "tfa98xx_parameters.h" + +/** +* Pass the container buffer, initialize and allocate internal memory. +* +* @param cnt pointer to the start of the buffer holding the container file +* @param length of the data in bytes +* @return +* - tfa_error_ok if normal +* - tfa_error_container invalid container data +* - tfa_error_bad_param invalid parameter +* +*/ +enum tfa_error tfa_load_cnt(void *cnt, int length); + +/** + * Return the descriptor string + * @param cnt pointer to the container struct + * @param dsc pointer to nxpTfa descriptor + * @return descriptor string + */ +char *tfaContGetString(nxpTfaContainer_t *cnt, nxpTfaDescPtr_t *dsc); + +/** + * Gets the string for the given command type number + * @param type number representing a command + * @return string of a command + */ +char *tfaContGetCommandString(uint32_t type); + +/** + * get the device type from the patch in this devicelist + * - find the patch file for this devidx + * - return the devid from the patch or 0 if not found + * @param cnt pointer to container file + * @param dev_idx device index + * @return descriptor string + */ +int tfa_cnt_get_devid(nxpTfaContainer_t *cnt, int dev_idx); + +/** + * Get the slave for the device if it exists. + * @param tfa the device struct pointer + * @param slave_addr the index of the device + * @return Tfa98xx_Error + */ +enum Tfa98xx_Error tfaContGetSlave(struct tfa_device *tfa, uint8_t *slave_addr); + +void tfaContSetSlave(uint8_t slave_addr); + +/** + * Get the index for a skave address. + * @param tfa the device struct pointer + * @return the device index + */ +int tfa_cont_get_idx(struct tfa_device *tfa); + +/** + * Write reg and bitfield items in the devicelist to the target. + * @param tfa the device struct pointer + * @return Tfa98xx_Error + */ +enum Tfa98xx_Error tfaContWriteRegsDev(struct tfa_device *tfa); + +/** + * Write reg and bitfield items in the profilelist to the target. + * @param tfa the device struct pointer + * @param prof_idx the profile index + * @return Tfa98xx_Error + */ +enum Tfa98xx_Error tfaContWriteRegsProf(struct tfa_device *tfa, int prof_idx); + +/** + * Write a patchfile in the devicelist to the target. + * @param tfa the device struct pointer + * @return Tfa98xx_Error + */ +enum Tfa98xx_Error tfaContWritePatch(struct tfa_device *tfa); + +/** + * Write all param files in the devicelist to the target. + * @param tfa the device struct pointer + * @return Tfa98xx_Error + */ +enum Tfa98xx_Error tfaContWriteFiles(struct tfa_device *tfa); + +/** + * Get sample rate from passed profile index + * @param tfa the device struct pointer + * @param prof_idx the index of the profile + * @return sample rate value + */ +unsigned int tfa98xx_get_profile_sr(struct tfa_device *tfa, + unsigned int prof_idx); + +/** + * Get the device name string + * @param cnt the pointer to the container struct + * @param dev_idx the index of the device + * @return device name string or error string if not found + */ +char *tfaContDeviceName(nxpTfaContainer_t *cnt, int dev_idx); + +/** + * Get the application name from the container file application field + * @param tfa the device struct pointer + * @param name the input stringbuffer with size: sizeof(application field)+1 + * @return actual string length + */ +int tfa_cnt_get_app_name(struct tfa_device *tfa, char *name); + +/** + * Get profile index of the calibration profile + * @param tfa the device struct pointer + * @return profile index, -2 if no calibration profile is found or -1 on error + */ +int tfaContGetCalProfile(struct tfa_device *tfa); + +/** + * Is the profile a tap profile ? + * @param tfa the device struct pointer + * @param prof_idx the index of the profile + * @return 1 if the profile is a tap profile or 0 if not + */ +int tfaContIsTapProfile(struct tfa_device *tfa, int prof_idx); + +/** + * Get the name of the profile at certain index for a device in the container file + * @param cnt the pointer to the container struct + * @param dev_idx the index of the device + * @param prof_idx the index of the profile + * @return profile name string or error string if not found + */ +char *tfaContProfileName(nxpTfaContainer_t *cnt, int dev_idx, int prof_idx); + +/** + * Process all items in the profilelist + * NOTE an error return during processing will leave the device muted + * @param tfa the device struct pointer + * @param prof_idx index of the profile + * @param vstep_idx index of the vstep + * @return Tfa98xx_Error + */ +enum Tfa98xx_Error tfaContWriteProfile(struct tfa_device *tfa, int prof_idx, + int vstep_idx); + +/** + * Specify the speaker configurations (cmd id) (Left, right, both, none) + * @param dev_idx index of the device + * @param configuration name string of the configuration + */ +void tfa98xx_set_spkr_select(int dev_idx, char *configuration); + +enum Tfa98xx_Error tfa_cont_write_filterbank(struct tfa_device *tfa, + nxpTfaFilter_t *filter); + +/** + * Write all param files in the profilelist to the target + * this is used during startup when maybe ACS is set + * @param tfa the device struct pointer + * @param prof_idx the index of the profile + * @param vstep_idx the index of the vstep + * @return Tfa98xx_Error + */ +enum Tfa98xx_Error tfaContWriteFilesProf(struct tfa_device *tfa, int prof_idx, + int vstep_idx); +enum Tfa98xx_Error tfaContWriteFilesVstep(struct tfa_device *tfa, int prof_idx, + int vstep_idx); +enum Tfa98xx_Error tfaContWriteDrcFile(struct tfa_device *tfa, int size, + uint8_t data[]); + +/** + * Get the device list dsc from the tfaContainer + * @param cont pointer to the tfaContainer + * @param dev_idx the index of the device + * @return device list pointer + */ +nxpTfaDeviceList_t *tfaContGetDevList(nxpTfaContainer_t *cont, int dev_idx); + +/** + * Get the Nth profile for the Nth device + * @param cont pointer to the tfaContainer + * @param dev_idx the index of the device + * @param prof_idx the index of the profile + * @return profile list pointer + */ +nxpTfaProfileList_t *tfaContGetDevProfList(nxpTfaContainer_t *cont, int dev_idx, + int prof_idx); + +/** + * Get the number of profiles for device from contaienr + * @param cont pointer to the tfaContainer + * @param dev_idx the index of the device + * @return device list pointer + */ +int tfa_cnt_get_dev_nprof(struct tfa_device *tfa); + +/** + * Get the Nth livedata for the Nth device + * @param cont pointer to the tfaContainer + * @param dev_idx the index of the device + * @param livedata_idx the index of the livedata + * @return livedata list pointer + */ +nxpTfaLiveDataList_t *tfaContGetDevLiveDataList(nxpTfaContainer_t *cont, + int dev_idx, int livedata_idx); + +/** + * Check CRC for container + * @param cont pointer to the tfaContainer + * @return error value 0 on error + */ +int tfaContCrcCheckContainer(nxpTfaContainer_t *cont); + +/** + * Get the device list pointer + * @param cnt pointer to the container struct + * @param dev_idx the index of the device + * @return pointer to device list + */ +nxpTfaDeviceList_t *tfaContDevice(nxpTfaContainer_t *cnt, int dev_idx); + +/** + * Return the pointer to the first profile in a list from the tfaContainer + * @param cont pointer to the tfaContainer + * @return pointer to first profile in profile list + */ +nxpTfaProfileList_t *tfaContGet1stProfList(nxpTfaContainer_t *cont); + +/** + * Return the pointer to the next profile in a list + * @param prof is the pointer to the profile list + * @return profile list pointer + */ +nxpTfaProfileList_t *tfaContNextProfile(nxpTfaProfileList_t *prof); + +/** + * Return the pointer to the first livedata in a list from the tfaContainer + * @param cont pointer to the tfaContainer + * @return pointer to first livedata in profile list + */ +nxpTfaLiveDataList_t *tfaContGet1stLiveDataList(nxpTfaContainer_t *cont); + +/** + * Return the pointer to the next livedata in a list + * @param livedata_idx is the pointer to the livedata list + * @return livedata list pointer + */ +nxpTfaLiveDataList_t *tfaContNextLiveData(nxpTfaLiveDataList_t *livedata_idx); + +/** + * Write a bit field + * @param tfa the device struct pointer + * @param bf bitfield to write + * @return Tfa98xx_Error + */ +enum Tfa98xx_Error tfaRunWriteBitfield(struct tfa_device *tfa, + nxpTfaBitfield_t bf); + +/** + * Write a parameter file to the device + * @param tfa the device struct pointer + * @param file filedescriptor pointer + * @param vstep_idx index to vstep + * @param vstep_msg_idx index to vstep message + * @return Tfa98xx_Error + */ +enum Tfa98xx_Error tfaContWriteFile(struct tfa_device *tfa, + nxpTfaFileDsc_t *file, int vstep_idx, + int vstep_msg_idx); + +/** + * Get the max volume step associated with Nth profile for the Nth device + * @param tfa the device struct pointer + * @param prof_idx profile index + * @return the number of vsteps + */ +int tfacont_get_max_vstep(struct tfa_device *tfa, int prof_idx); + +/** + * Get the file contents associated with the device or profile + * Search within the device tree, if not found, search within the profile + * tree. There can only be one type of file within profile or device. + * @param tfa the device struct pointer + * @param prof_idx I2C profile index in the device + * @param type file type + * @return 0 NULL if file type is not found + * @return 1 file contents + */ +nxpTfaFileDsc_t *tfacont_getfiledata(struct tfa_device *tfa, int prof_idx, + enum nxpTfaHeaderType type); + +/** + * Dump the contents of the file header + * @param hdr pointer to file header data + */ +void tfaContShowHeader(nxpTfaHeader_t *hdr); + +/** + * Read a bit field + * @param tfa the device struct pointer + * @param bf bitfield to read out + * @return Tfa98xx_Error + */ +enum Tfa98xx_Error tfaRunReadBitfield(struct tfa_device *tfa, + nxpTfaBitfield_t *bf); + +/** + * Get hw feature bits from container file + * @param tfa the device struct pointer + * @param hw_feature_register pointer to where hw features are stored + */ +void get_hw_features_from_cnt(struct tfa_device *tfa, int *hw_feature_register); + +/** + * Get sw feature bits from container file + * @param tfa the device struct pointer + * @param sw_feature_register pointer to where sw features are stored + */ +void get_sw_features_from_cnt(struct tfa_device *tfa, + int sw_feature_register[2]); + +/** + * Factory trimming for the Boost converter + * check if there is a correction needed + * @param tfa the device struct pointer + */ +enum Tfa98xx_Error tfa98xx_factory_trimmer(struct tfa_device *tfa); + +/** + * Search for filters settings and if found then write them to the device + * @param tfa the device struct pointer + * @param prof_idx profile to look in + * @return Tfa98xx_Error + */ +enum Tfa98xx_Error tfa_set_filters(struct tfa_device *tfa, int prof_idx); + +/** + * Get the firmware version from the patch in the container file + * @param tfa the device struct pointer + * @return firmware version + */ +int tfa_cnt_get_patch_version(struct tfa_device *tfa); + +int tfa_tib_dsp_msgmulti(struct tfa_device *tfa, int length, + const char *buffer); + +#endif /* TFACONTAINER_H_ */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_device.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_device.h new file mode 100644 index 000000000000..6a878c4d5797 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_device.h @@ -0,0 +1,343 @@ +/* + * Copyright 2014-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/**\file + * + * The tfa_device interface controls a single I2C device instance by + * referencing to the device specific context provided by means of the + * tfa_device structure pointer. + * Multiple instances of tfa_device structures will be created and maintained + * by the caller. + * + * The API is functionally grouped as: + * - tfa_dev basic codec interface to probe, start/stop and control the device state + * - access to internal MTP storage + * - abstraction for interrupt bits and handling + * - container reading support + */ +#ifndef __TFA_DEVICE_H__ +#define __TFA_DEVICE_H__ + +#include "config.h" + +struct tfa_device; + +/* + * hw/sw feature bit settings in MTP + */ +enum featureSupport { + supportNotSet, /**< default means not set yet */ + supportNo, /**< no support */ + supportYes /**< supported */ +}; +/* + * supported Digital Audio Interfaces bitmap + */ +enum Tfa98xx_DAI { + Tfa98xx_DAI_I2S = 0x01, /**< I2S only */ + Tfa98xx_DAI_TDM = 0x02, /**< TDM, I2S */ + Tfa98xx_DAI_PDM = 0x04, /**< PDM */ +}; + +/* + * device ops function structure + */ +struct tfa_device_ops { + enum Tfa98xx_Error (*dsp_msg)(struct tfa_device *tfa, int length, + const char *buf); + enum Tfa98xx_Error (*dsp_msg_read)(struct tfa_device *tfa, int length, + unsigned char *bytes); + enum Tfa98xx_Error (*reg_read)(struct tfa_device *tfa, + unsigned char subaddress, + unsigned short *value); + enum Tfa98xx_Error (*reg_write)(struct tfa_device *tfa, + unsigned char subaddress, + unsigned short value); + enum Tfa98xx_Error (*mem_read)(struct tfa_device *tfa, + unsigned int start_offset, int num_words, + int *pValues); + enum Tfa98xx_Error (*mem_write)(struct tfa_device *tfa, + unsigned short address, int value, + int memtype); + + enum Tfa98xx_Error (*tfa_init)( + struct tfa_device * + tfa); /**< init typically for loading optimal settings */ + enum Tfa98xx_Error (*dsp_reset)( + struct tfa_device *tfa, + int state); /**< reset the coolflux dsp */ + enum Tfa98xx_Error (*dsp_system_stable)( + struct tfa_device *tfa, + int *ready); /**< ready when clocks are stable to allow DSP subsystem access */ + enum Tfa98xx_Error (*dsp_write_tables)( + struct tfa_device *tfa, + int sample_rate); /**< write the device/type specific delaytables */ + enum Tfa98xx_Error (*auto_copy_mtp_to_iic)( + struct tfa_device *tfa); /**< Set auto_copy_mtp_to_iic */ + enum Tfa98xx_Error (*factory_trimmer)( + struct tfa_device + *tfa); /**< Factory trimming for the Boost converter */ + int (*set_swprof)( + struct tfa_device *tfa, + unsigned short + new_value); /**< Set the sw profile in the struct and the hw register */ + int (*get_swprof)( + struct tfa_device + *tfa); /**< Get the sw profile from the hw register */ + int (*set_swvstep)( + struct tfa_device *tfa, + unsigned short + new_value); /**< Set the sw vstep in the struct and the hw register */ + int (*get_swvstep)( + struct tfa_device + *tfa); /**< Get the sw vstep from the hw register */ + int (*get_mtpb)( + struct tfa_device *tfa); /**< get status of MTB busy bit*/ + enum Tfa98xx_Error (*set_mute)(struct tfa_device *tfa, + int mute); /**< set mute */ + enum Tfa98xx_Error (*faim_protect)( + struct tfa_device *tfa, + int state); /**< Protect FAIM from being corrupted */ + enum Tfa98xx_Error (*set_osc_powerdown)( + struct tfa_device *tfa, + int state); /**< Allow to change internal osc. gating settings */ +}; + +/** + * Device states and modifier flags to allow a device/type independent fine + * grained control of the internal state.\n + * Values below 0x10 are referred to as base states which can be or-ed with + * state modifiers, from 0x10 and higher. + * + */ +enum tfa_state { + TFA_STATE_UNKNOWN, /**< unknown or invalid */ + TFA_STATE_POWERDOWN, /**< PLL in powerdown, Algo is up/warm */ + TFA_STATE_INIT_HW, /**< load I2C/PLL hardware setting (~wait2srcsettings) */ + TFA_STATE_INIT_CF, /**< coolflux HW access possible (~initcf) */ + TFA_STATE_INIT_FW, /**< DSP framework active (~patch loaded) */ + TFA_STATE_OPERATING, /**< Amp and Algo running */ + TFA_STATE_FAULT, /**< An alarm or error occurred */ + TFA_STATE_RESET, /**< I2C reset and ACS set */ + /* --sticky state modifiers-- */ + TFA_STATE_MUTE = 0x10, /**< Algo & Amp mute */ + TFA_STATE_UNMUTE = 0x20, /**< Algo & Amp unmute */ + TFA_STATE_CLOCK_ALWAYS = + 0x40, /**< PLL connect to internal oscillator */ + TFA_STATE_CLOCK_AUDIO = + 0x80, /**< PLL connect to audio clock (BCK/FS) */ + TFA_STATE_LOW_POWER = 0x100, /**< lowest possible power state */ +}; + +/** + * This is the main tfa device context structure, it will carry all information + * that is needed to handle a single I2C device instance. + * All functions dealing with the device will need access to the fields herein. + */ +struct tfa_device { + int dev_idx; /**< device container index */ + int in_use; + int buffer_size; /**< lowest level max buffer size */ + int has_msg; /**< support direct dsp messaging */ + unsigned char slave_address; /**< I2C slave address (not shifted) */ + unsigned short rev; /**< full revid of this device */ + unsigned char tfa_family; /**< tfa1/tfa2 */ + enum featureSupport supportDrc; + enum featureSupport supportFramework; + enum featureSupport support_saam; + int sw_feature_bits[2]; /**< cached copy of sw feature bits */ + int hw_feature_bits; /**< cached copy of hw feature bits */ + int profile; /**< active profile */ + int vstep; /**< active vstep */ + unsigned char spkr_count; + unsigned char spkr_select; + unsigned char support_tcoef; /**< legacy tfa9887, will be removed */ + enum Tfa98xx_DAI daimap; /**< supported audio interface types */ + int mohm[3]; /**< speaker calibration values in milli ohms -1 is error */ + struct tfa_device_ops dev_ops; + uint16_t interrupt_enable[3]; + uint16_t interrupt_status[3]; + int ext_dsp; /**< respond to external DSP: -1:none, 0:no_dsp, 1:cold, 2:warm */ + int bus; /* TODO fix ext_dsp and bus handling */ + int tfadsp_event; /**< enum tfadsp_event_en is for external registry */ + int verbose; /**< verbosity level for debug print output */ + enum tfa_state + state; /**< last known state or-ed with optional state_modifier */ + struct nxpTfaContainer *cnt; /**< the loaded container file */ + struct nxpTfaVolumeStepRegisterInfo + *p_regInfo; /**< remember vstep for partial updates */ + int partial_enable; /**< enable partial updates */ + void *data; /**< typically pointing to Linux driver structure owning this device */ + int convert_dsp32; /**< convert 24 bit DSP messages to 32 bit */ + int sync_iv_delay; /**< synchronize I/V delay at cold start */ + int is_probus_device; /**< probus device: device without internal DSP */ + int needs_reset; /**< add the reset trigger for SetAlgoParams and SetMBDrc commands */ + struct kmem_cache *cachep; /**< Memory allocator handle */ +}; + +/** + * The tfa_dev_probe is called before accessing any device accessing functions. + * Access to the tfa device register 3 is attempted and will record the + * returned id for further use. If no device responds the function will abort. + * The recorded id will by used by the query functions to fill the remaining + * relevant data fields of the device structure. + * Data such as MTP features that requires device access will only be read when + * explicitly called and the result will be then cached in the struct. + * + * A structure pointer passed to this device needs to refer to existing memory + * space allocated by the caller. + * + * @param slave = I2C slave address of the target device (not shifted) + * @param tfa struct = points to memory that holds the context for this device + * instance + * + * @return + * - 0 if the I2C device responded to a read of register address 3\n + * when the device responds but with an unknown id a warning will be printed + * - -1 if no response from the I2C device + * + */ +int tfa_dev_probe(int slave, struct tfa_device *tfa); + +/** + * Start this instance at the profile and vstep as provided. + * The profile and vstep will be loaded first in case the current value differs + * from the requested values. + * Note that this call will not change the mute state of the tfa, which means + * that of this instance was called in muted state the caller will have to + * unmute in order to get audio. + * + * @param tfa struct = pointer to context of this device instance + * @param profile the selected profile to run + * @param vstep the selected vstep to use + * @return tfa_error enum + */ +/*[nxp34663] CR: support 16bit/24bit/32bit audio data. begin*/ +#ifdef __KERNEL__ +enum tfa_error tfa_dev_start(struct tfa_device *tfa, int next_profile, + int vstep, u8 pcm_format); +#else +enum tfa_error tfa_dev_start(struct tfa_device *tfa, int next_profile, + int vstep); +#endif +/*[nxp34663] CR: support 16bit/24bit/32bit audio data. end*/ + +/** + * Stop audio for this instance as gracefully as possible. + * Audio will be muted and the PLL will be shutdown together with any other + * device/type specific settings needed to prevent audio artifacts or + * workarounds. + * + * Note that this call will change state of the tfa to mute and powered down. + * + * @param tfa struct = pointer to context of this device instance + * @return tfa_error enum + */ +enum tfa_error tfa_dev_stop(struct tfa_device *tfa); + +/** + * This interface allows a device/type independent fine grained control of the + * internal state of the instance. + * Whenever a base state is requested an attempt is made to actively bring the device + * into this state. However this may depend on external conditions beyond control of + * this software layer. Therefore in case the state cannot be set an erro will + * be returned and the current state remains unchanged. + * The base states, lower values below 0x10, are all mutually exclusive, they higher ones + * can also function as a sticky modifier which means for example that operating + * state could be in either muted or unmuted state. Or in case of init_cf it can be + * internal clock (always) or external audio clock. + * This function is intended to be used for device mute/unmute synchronization + * when called from higher layers. Mostly internal calls will use this to control + * the startup and profile transitions in a device/type independent way. + * + * @param tfa struct = pointer to context of this device instance + * @param state struct = desired device state after function return + * @return tfa_error enum + */ +enum tfa_error tfa_dev_set_state(struct tfa_device *tfa, enum tfa_state state, + int is_calibration); + +/** + * Retrieve the current state of this instance in an active way. + * The state field in tfa structure will reflect the result unless an error is + * returned. + * Note that the hardware state may change on external events an as such this + * field should be treated as volatile. + * + * @param tfa struct = pointer to context of this device instance + * @return tfa_error enum + * + */ +enum tfa_state tfa_dev_get_state(struct tfa_device *tfa); + +/*****************************************************************************/ +/*****************************************************************************/ +/** + * MTP support functions + */ +enum tfa_mtp { + TFA_MTP_OTC, /**< */ + TFA_MTP_EX, /**< */ + TFA_MTP_RE25, /**< */ + TFA_MTP_RE25_PRIM, /**< */ + TFA_MTP_RE25_SEC, /**< */ + TFA_MTP_LOCK, /**< */ +}; + +/** + * + */ +int tfa_dev_mtp_get(struct tfa_device *tfa, enum tfa_mtp item); + +/** + * + */ +enum tfa_error tfa_dev_mtp_set(struct tfa_device *tfa, enum tfa_mtp item, + int value); + +//irq +/* tfa2 interrupt support + * !!! enum tfa9912_irq !!!*/ +/* + * interrupt bit function to clear + */ +int tfa_irq_clear(struct tfa_device *tfa, int bit); +/* + * return state of irq or -1 if illegal bit + */ +int tfa_irq_get(struct tfa_device *tfa, int bit); +/* + * interrupt bit function that operates on the shadow regs in the handle + */ +int tfa_irq_ena(struct tfa_device *tfa, int bit, int state); +/* + * interrupt bit function that sets the polarity + */ +int tfa_irq_set_pol(struct tfa_device *tfa, int bit, int state); + +/* + * mask interrupts by disabling them + */ +int tfa_irq_mask(struct tfa_device *tfa); +/* + * unmask interrupts by enabling them again + */ +int tfa_irq_unmask(struct tfa_device *tfa); +//cnt read +//debug? + +#endif /* __TFA_DEVICE_H__ */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_dsp_fw.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_dsp_fw.h new file mode 100644 index 000000000000..c7a032cb569b --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_dsp_fw.h @@ -0,0 +1,169 @@ +/* + * Copyright 2014-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TFA98XX_INTERNALS_H +#define TFA98XX_INTERNALS_H + +#include "config.h" + +#include "tfa_service.h" //TODO cleanup for enum Tfa98xx_Status_ID +/* + * tfadsp_fw_api.c + */ +/** + * Return a text version of the firmware status ID code + * @param status the given status ID code + * @return the firmware status ID string + */ +const char *tfadsp_fw_status_string(enum Tfa98xx_Status_ID status); +int tfadsp_fw_start(struct tfa_device *tfa, int prof_idx, int vstep_idx); +int tfadsp_fw_get_api_version(struct tfa_device *tfa, uint8_t *buffer); +#define FW_MAXTAG 150 +int tfadsp_fw_get_tag(struct tfa_device *tfa, uint8_t *buffer); +int tfadsp_fw_get_status_change(struct tfa_device *tfa, uint8_t *buffer); +int tfadsp_fw_set_re25(struct tfa_device *tfa, int prim, int sec); +int tfadsp_fw_get_re25(struct tfa_device *tfa, uint8_t *buffer); + +/* + * the order matches the ACK bits order in TFA98XX_CF_STATUS + */ +enum tfa_fw_event { /* not all available on each device */ + tfa_fw_i2c_cmd_ack, + tfa_fw_reset_start, + tfa_fw_short_on_mips, + tfa_fw_soft_mute_ready, + tfa_fw_volume_ready, + tfa_fw_error_damage, + tfa_fw_calibrate_done, + tfa_fw_max +}; + +/* the following type mappings are compiler specific */ +#define subaddress_t unsigned char + +/* module Ids */ +#define MODULE_FRAMEWORK 0 +#define MODULE_SPEAKERBOOST 1 +#define MODULE_BIQUADFILTERBANK 2 +#define MODULE_TAPTRIGGER 5 +#define MODULE_SETRE 9 + +/* RPC commands */ +/* SET */ +#define FW_PAR_ID_SET_MEMORY 0x03 +#define FW_PAR_ID_SET_SENSES_DELAY 0x04 +#define FW_PAR_ID_SETSENSESCAL 0x05 +#define FW_PAR_ID_SET_INPUT_SELECTOR 0x06 +#define FW_PAR_ID_SET_OUTPUT_SELECTOR 0x08 +#define FW_PAR_ID_SET_PROGRAM_CONFIG 0x09 +#define FW_PAR_ID_SET_GAINS 0x0A +#define FW_PAR_ID_SET_MEMTRACK 0x0B +#define FW_PAR_ID_SET_FWKUSECASE 0x11 +#define TFA1_FW_PAR_ID_SET_CURRENT_DELAY 0x03 +#define TFA1_FW_PAR_ID_SET_CURFRAC_DELAY 0x06 +/* GET */ +#define FW_PAR_ID_GET_MEMORY 0x83 +#define FW_PAR_ID_GLOBAL_GET_INFO 0x84 +#define FW_PAR_ID_GET_FEATURE_INFO 0x85 +#define FW_PAR_ID_GET_MEMTRACK 0x8B +#define FW_PAR_ID_GET_TAG 0xFF +#define FW_PAR_ID_GET_API_VERSION 0xFE +#define FW_PAR_ID_GET_STATUS_CHANGE 0x8D + +/* Load a full model into SpeakerBoost. */ +/* SET */ +#define SB_PARAM_SET_ALGO_PARAMS 0x00 +#define SB_PARAM_SET_LAGW 0x01 +#define SB_PARAM_SET_ALGO_PARAMS_WITHOUT_RESET 0x02 +#define SB_PARAM_SET_RE25C 0x05 +#define SB_PARAM_SET_LSMODEL 0x06 +#define SB_PARAM_SET_MBDRC 0x07 +#define SB_PARAM_SET_MBDRC_WITHOUT_RESET 0x08 +#define SB_PARAM_SET_EXCURSION_FILTERS 0x0A +#define SB_PARAM_SET_DRC 0x0F +/* GET */ +#define SB_PARAM_GET_ALGO_PARAMS 0x80 +#define SB_PARAM_GET_LAGW 0x81 +#define SB_PARAM_GET_RE25C 0x85 +#define SB_PARAM_GET_LSMODEL 0x86 +#define SB_PARAM_GET_MBDRC 0x87 +#define SB_PARAM_GET_MBDRC_DYNAMICS 0x89 +#define SB_PARAM_GET_EXCURSION_FILTERS 0x8A +#define SB_PARAM_GET_TAG 0xFF + +#define SB_PARAM_SET_EQ 0x0A /* 2 Equaliser Filters. */ +#define SB_PARAM_SET_PRESET 0x0D /* Load a preset */ +#define SB_PARAM_SET_CONFIG 0x0E /* Load a config */ +#define SB_PARAM_SET_AGCINS 0x10 +#define SB_PARAM_SET_CURRENT_DELAY 0x03 +#define SB_PARAM_GET_STATE 0xC0 +#define SB_PARAM_GET_XMODEL 0xC1 /* Gets current Excursion Model. */ +#define SB_PARAM_GET_XMODEL_COEFFS 0x8C /* Get coefficients for XModel */ +#define SB_PARAM_GET_EXCURSION_FILTERS 0x8A /* Get excursion filters */ +#define SB_PARAM_SET_EXCURSION_FILTERS 0x0A /* Set excursion filters */ + +/* SET: TAPTRIGGER */ +#define TAP_PARAM_SET_ALGO_PARAMS 0x01 +#define TAP_PARAM_SET_DECIMATION_PARAMS 0x02 + +/* GET: TAPTRIGGER*/ +#define TAP_PARAM_GET_ALGO_PARAMS 0x81 +#define TAP_PARAM_GET_TAP_RESULTS 0x84 + +/* sets the speaker calibration impedance (@25 degrees celsius) */ +#define SB_PARAM_SET_RE0 0x89 + +#define BFB_PAR_ID_SET_COEFS 0x00 +#define BFB_PAR_ID_GET_COEFS 0x80 +#define BFB_PAR_ID_GET_CONFIG 0x81 + +/* for compatibility */ +#define FW_PARAM_GET_STATE FW_PAR_ID_GLOBAL_GET_INFO +#define FW_PARAM_GET_FEATURE_BITS FW_PAR_ID_GET_FEATURE_BITS + +/* RPC Status results */ +#define STATUS_OK 0 +#define STATUS_INVALID_MODULE_ID 2 +#define STATUS_INVALID_PARAM_ID 3 +#define STATUS_INVALID_INFO_ID 4 + +/* the maximum message length in the communication with the DSP */ +#define TFA2_MAX_PARAM_SIZE (507 * 3) /* TFA2 */ +#define TFA1_MAX_PARAM_SIZE (145 * 3) /* TFA1 */ + +#define ROUND_DOWN(a, n) (((a) / (n)) * (n)) + +/* feature bits */ +#define FEATURE1_TCOEF 0x100 /* bit8 set means tCoefA expected */ +#define FEATURE1_DRC 0x200 /* bit9 NOT set means DRC expected */ + +/* DSP firmware xmem defines */ +#define TFA1_FW_XMEM_CALIBRATION_DONE 231 +#define TFA2_FW_XMEM_CALIBRATION_DONE 516 +#define TFA1_FW_XMEM_COUNT_BOOT 0xa1 +#define TFA2_FW_XMEM_COUNT_BOOT 512 +#define TFA2_FW_XMEM_CMD_COUNT 520 + +/* note that the following defs rely on the handle variable */ +#define TFA_FW_XMEM_CALIBRATION_DONE TFA_FAM_FW(tfa, XMEM_CALIBRATION_DONE) +#define TFA_FW_XMEM_COUNT_BOOT TFA_FAM_FW(tfa, XMEM_COUNT_BOOT) +#define TFA_FW_XMEM_CMD_COUNT TFA_FAM_FW(tfa, XMEM_CMD_COUNT) + +#define TFA2_FW_ReZ_SCALE 65536 +#define TFA1_FW_ReZ_SCALE 16384 + +#endif /* TFA98XX_INTERNALS_H */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_ext.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_ext.h new file mode 100644 index 000000000000..9d0c2ddce12b --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_ext.h @@ -0,0 +1,64 @@ +/* + * Copyright 2016-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * tfa_ext.h + * + * Created on: Jun 8, 2016 + * Author: wim + */ + +#ifndef TFA_SRC_TFA_EXT_H_ +#define TFA_SRC_TFA_EXT_H_ + +#include "tfa_device.h" + +/* + * events + */ +/** Maximum value for enumerator */ +#define LVM_MAXENUM (0xffff) +/** +This enum type specifies the different events that may trigger a callback. +*/ +enum tfadsp_event_en { + TFADSP_CMD_ACK = 1, /**< Command handling is completed */ + TFADSP_SOFT_MUTE_READY = 8, /**< Muting completed */ + TFADSP_VOLUME_READY = 16, /**< Volume change completed */ + TFADSP_DAMAGED_SPEAKER = 32, /**< Damaged speaker was detected */ + TFADSP_CALIBRATE_DONE = 64, /**< Calibration is completed */ + TFADSP_SPARSESIG_DETECTED = 128, /**< Sparse signal detected */ + TFADSP_CMD_READY = 256, /**< Ready to receive commands */ + TFADSP_EXT_PWRUP = 0x8000, /**< DSP API has started, powered up */ + TFADSP_EXT_PWRDOWN = 0x8001, /**< DSP API stopped, power down */ + TFADSP_EVENT_DUMMY = LVM_MAXENUM +}; + +typedef int (*tfa_event_handler_t)(struct tfa_device *tfa, + enum tfadsp_event_en tfadsp_event); +typedef int (*dsp_send_message_t)(struct tfa_device *tfa, int length, + const char *buf); +typedef int (*dsp_read_message_t)(struct tfa_device *tfa, int length, + char *buf); +typedef int (*dsp_write_reg_t)(struct tfa_device *tfa, unsigned char subaddress, + unsigned short value); + +int tfa_ext_register(dsp_write_reg_t tfa_write_reg, + dsp_send_message_t tfa_send_message, + dsp_read_message_t tfa_read_message, + tfa_event_handler_t *tfa_event_handler); + +#endif /* TFA_SRC_TFA_EXT_H_ */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_internal.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_internal.h new file mode 100644 index 000000000000..4f7094d13d3a --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_internal.h @@ -0,0 +1,41 @@ +/* + * Copyright 2014-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + internal functions for TFA layer (not shared with SRV and HAL layer!) +*/ + +#ifndef __TFA_INTERNAL_H__ +#define __TFA_INTERNAL_H__ + +#include "tfa_dsp_fw.h" +#include "tfa_ext.h" + +#if __GNUC__ >= 4 +#define TFA_INTERNAL __attribute__((visibility("hidden"))) +#else +#define TFA_INTERNAL +#endif + +#define TFA98XX_GENERIC_SLAVE_ADDRESS 0x1C + +TFA_INTERNAL enum Tfa98xx_Error tfa98xx_check_rpc_status(struct tfa_device *tfa, + int *pRpcStatus); +TFA_INTERNAL enum Tfa98xx_Error tfa98xx_wait_result(struct tfa_device *tfa, + int waitRetryCount); + +#endif /* __TFA_INTERNAL_H__ */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_platform_interface_definition.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_platform_interface_definition.h new file mode 100644 index 000000000000..7cf3c68b01bd --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_platform_interface_definition.h @@ -0,0 +1,97 @@ +/* + * Copyright 2015-2018 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _TFA_PLATFORM_INTERFACE_DEFINITION_H_ +#define _TFA_PLATFORM_INTERFACE_DEFINITION_H_ + +#define AFE_MODULE_ID_TFADSP_RX (0x1000B911) +#define AFE_MODULE_ID_TFADSP_TX (0x1000B912) +#define AFE_PARAM_ID_TFADSP_TX_SET_ENABLE (0x1000B920) +#define AFE_PARAM_ID_TFADSP_RX_CFG (0x1000B921) +#define AFE_PARAM_ID_TFADSP_RX_GET_RESULT (0x1000B922) +#define AFE_PARAM_ID_TFADSP_RX_SET_BYPASS (0x1000B923) + +#define TFA_USING_QUATERNARY_MI2S + +#if defined(TFA_USING_SECONDARY_MI2S) +/*Attention: port_id = AFE_PORT_ID_SECONDARY_MI2S_RX/TX, AFE_PORT_ID_TERTIARY_MI2S_RX/TX, + AFE_PORT_ID_QUATERNARY_MI2S_RX/TX or AFE_PORT_ID_QUINARY_MI2S_RX/TX*/ +#define AFE_PORT_ID_TFADSP_RX (AFE_PORT_ID_SECONDARY_MI2S_RX) +#define AFE_PORT_ID_TFADSP_TX (AFE_PORT_ID_SECONDARY_MI2S_TX) + +#define PLATFORM_RX_VI_FB_RX_MUX_TEXT "SEC_MI2S_RX" +#define PLATFORM_RX_VI_FB_TX_MUX_TEXT "SEC_MI2S_TX" +#define PLATFORM_RX_VI_FB_MUX_NAME "SECONDARY_MI2S_RX_VI_FB_MUX" +#define PLATFORM_RX_VI_FB_TX_VALUE MSM_BACKEND_DAI_SECONDARY_MI2S_TX +#define PLATFORM_RX_VI_FB_MUX_ENUM MSM_BACKEND_DAI_SECONDARY_MI2S_RX + +#define TFA_TX_HOSTLESS_CODEC_NAME "Secondary MI2S_TX Hostless" +#define TFA_TX_HOSTLESS_STREAM_NAME "Secondary MI2S_TX Hostless" +#define TFA_TX_HOSTLESS_CPU_DAI_NAME "SEC_MI2S_TX_HOSTLESS" + +#elif defined(TFA_USING_TERTIARY_MI2S) +/*Attention: port_id = AFE_PORT_ID_SECONDARY_MI2S_RX/TX, AFE_PORT_ID_TERTIARY_MI2S_RX/TX, + AFE_PORT_ID_QUATERNARY_MI2S_RX/TX or AFE_PORT_ID_QUINARY_MI2S_RX/TX*/ +#define AFE_PORT_ID_TFADSP_RX (AFE_PORT_ID_TERTIARY_MI2S_RX) +#define AFE_PORT_ID_TFADSP_TX (AFE_PORT_ID_TERTIARY_MI2S_TX) + +#define PLATFORM_RX_VI_FB_RX_MUX_TEXT "TERT_MI2S_RX" +#define PLATFORM_RX_VI_FB_TX_MUX_TEXT "TERT_MI2S_TX" +#define PLATFORM_RX_VI_FB_MUX_NAME "TERTIARY_MI2S_RX_VI_FB_MUX" +#define PLATFORM_RX_VI_FB_TX_VALUE MSM_BACKEND_DAI_TERTIARY_MI2S_TX +#define PLATFORM_RX_VI_FB_MUX_ENUM MSM_BACKEND_DAI_TERTIARY_MI2S_RX + +#define TFA_TX_HOSTLESS_CODEC_NAME "Tertiary MI2S_TX Hostless" +#define TFA_TX_HOSTLESS_STREAM_NAME "Tertiary MI2S_TX Hostless" +#define TFA_TX_HOSTLESS_CPU_DAI_NAME "TERT_MI2S_TX_HOSTLESS" + +#elif defined(TFA_USING_QUATERNARY_MI2S) +/*Attention: port_id = AFE_PORT_ID_SECONDARY_MI2S_RX/TX, AFE_PORT_ID_TERTIARY_MI2S_RX/TX, + AFE_PORT_ID_QUATERNARY_MI2S_RX/TX or AFE_PORT_ID_QUINARY_MI2S_RX/TX*/ +#define AFE_PORT_ID_TFADSP_RX (AFE_PORT_ID_QUATERNARY_MI2S_RX) +#define AFE_PORT_ID_TFADSP_TX (AFE_PORT_ID_QUATERNARY_MI2S_TX) + +#define PLATFORM_RX_VI_FB_RX_MUX_TEXT "QUAT_MI2S_RX" +#define PLATFORM_RX_VI_FB_TX_MUX_TEXT "QUAT_MI2S_TX" +#define PLATFORM_RX_VI_FB_MUX_NAME "QUATERNARY_MI2S_RX_VI_FB_MUX" +#define PLATFORM_RX_VI_FB_TX_VALUE MSM_BACKEND_DAI_QUATERNARY_MI2S_TX +#define PLATFORM_RX_VI_FB_MUX_ENUM MSM_BACKEND_DAI_QUATERNARY_MI2S_RX + +#define TFA_TX_HOSTLESS_CODEC_NAME "Quaternary MI2S_TX Hostless" +#define TFA_TX_HOSTLESS_STREAM_NAME "Quaternary MI2S_TX Hostless" +#define TFA_TX_HOSTLESS_CPU_DAI_NAME "QUAT_MI2S_TX_HOSTLESS" + +#elif defined(TFA_USING_QUINARY_MI2S) +/*Attention: port_id = AFE_PORT_ID_SECONDARY_MI2S_RX/TX, AFE_PORT_ID_TERTIARY_MI2S_RX/TX, + AFE_PORT_ID_QUATERNARY_MI2S_RX/TX or AFE_PORT_ID_QUINARY_MI2S_RX/TX*/ +#define AFE_PORT_ID_TFADSP_RX (AFE_PORT_ID_QUINARY_MI2S_RX) +#define AFE_PORT_ID_TFADSP_TX (AFE_PORT_ID_QUINARY_MI2S_TX) + +#define PLATFORM_RX_VI_FB_RX_MUX_TEXT "QUIN_MI2S_RX" +#define PLATFORM_RX_VI_FB_TX_MUX_TEXT "QUIN_MI2S_TX" +#define PLATFORM_RX_VI_FB_MUX_NAME "QUINARY_MI2S_RX_VI_FB_MUX" +#define PLATFORM_RX_VI_FB_TX_VALUE MSM_BACKEND_DAI_QUINARY_MI2S_TX +#define PLATFORM_RX_VI_FB_MUX_ENUM MSM_BACKEND_DAI_QUINARY_MI2S_RX + +#define TFA_TX_HOSTLESS_CODEC_NAME "Quinary MI2S_TX Hostless" +#define TFA_TX_HOSTLESS_STREAM_NAME "Quinary MI2S_TX Hostless" +#define TFA_TX_HOSTLESS_CPU_DAI_NAME "QUIN_MI2S_TX_HOSTLESS" + +#else +#error you should define which mi2s will be used for TFA device. +#endif +#endif /* _TFA_PLATFORM_INTERFACE_DEFINITION_H_ */ \ No newline at end of file diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_service.h b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_service.h new file mode 100644 index 000000000000..3fbd938380b5 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/tfa_service.h @@ -0,0 +1,1057 @@ +/* + * Copyright 2014-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TFA_SERVICE_H +#define TFA_SERVICE_H + +//#include "config.h" +// workaround for Visual Studio: +// fatal error C1083: Cannot open include file: 'config.h': No such file or directory +#ifdef __KERNEL__ +#include +#else +#include +#endif +#ifdef __cplusplus +extern "C" { +#include "NXP_I2C.h" +#endif + +/* Linux kernel module defines TFA98XX_GIT_VERSIONS in the linux_driver/Makefile */ +#if !defined(TFA98XX_GIT_VERSIONS) +#include "versions.h" +#endif +#ifdef TFA98XX_GIT_VERSIONS +#define TFA98XX_API_REV_STR TFA98XX_GIT_VERSIONS +#else +#define TFA98XX_API_REV_STR "v6.5.2" +#endif + +#include "tfa_device.h" + +/* + * data previously defined in Tfa9888_dsp.h + */ +#define MEMTRACK_MAX_WORDS 150 +#define LSMODEL_MAX_WORDS 150 +#define TFA98XX_MAXTAG (150) +#define FW_VAR_API_VERSION (521) + +/* Indexes and scaling factors of GetLSmodel */ +#define tfa9888_fs_IDX 128 +#define tfa9888_leakageFactor_IDX 130 +#define tfa9888_ReCorrection_IDX 131 +#define tfa9888_Bl_IDX 132 +#define ReZ_IDX 147 + +#define tfa9872_leakageFactor_IDX 128 +#define tfa9872_ReCorrection_IDX 129 +#define tfa9872_Bl_IDX 130 + +#define fs_SCALE (double)1 +#define leakageFactor_SCALE (double)8388608 +#define ReCorrection_SCALE (double)8388608 +#define Bl_SCALE (double)2097152 +#define tCoef_SCALE (double)8388608 + +/* ---------------------------- Max1 ---------------------------- */ +/* Headroom applied to the main input signal */ +#define SPKRBST_HEADROOM 7 +/* Exponent used for AGC Gain related variables */ +#define SPKRBST_AGCGAIN_EXP SPKRBST_HEADROOM +#define SPKRBST_TEMPERATURE_EXP 9 +/* Exponent used for Gain Corection related variables */ +#define SPKRBST_LIMGAIN_EXP 4 +#define SPKRBST_TIMECTE_EXP 1 +#define DSP_MAX_GAIN_EXP 7 +/* -------------------------------------------------------------- */ + +/* speaker related parameters */ +#define TFA2_SPEAKERPARAMETER_LENGTH (3 * 151) /* MAX2=450 */ +#define TFA1_SPEAKERPARAMETER_LENGTH (3 * 141) /* MAX1=423 */ + +/* vstep related parameters */ +#define TFA2_ALGOPARAMETER_LENGTH \ + (3 * 304) /* N1B = (304) 305 is including the cmd-id */ +#define TFA72_ALGOPARAMETER_LENGTH_MONO (3 * 183) +#define TFA72_ALGOPARAMETER_LENGTH_STEREO (3 * 356) +#define TFA2_MBDRCPARAMETER_LENGTH (3 * 152) /* 154 is including the cmd-id */ +#define TFA72_MBDRCPARAMETER_LENGTH (3 * 98) +#define TFA1_PRESET_LENGTH 87 +#define TFA1_DRC_LENGTH 381 /* 127 words */ +#define TFA2_FILTERCOEFSPARAMETER_LENGTH \ + (3 * 168) /* 170 is including the cmd-id */ +#define TFA72_FILTERCOEFSPARAMETER_LENGTH (3 * 156) + +/* Maximum number of retries for DSP result + * Keep this value low! + * If certain calls require longer wait conditions, the + * application should poll, not the API + * The total wait time depends on device settings. Those + * are application specific. + */ +#define TFA98XX_WAITRESULT_NTRIES 40 +#define TFA98XX_WAITRESULT_NTRIES_LONG 2000 + +/* following lengths are in bytes */ +#define TFA98XX_PRESET_LENGTH 87 +#define TFA98XX_CONFIG_LENGTH 201 +#define TFA98XX_DRC_LENGTH 381 /* 127 words */ + +typedef unsigned char Tfa98xx_Config_t[TFA98XX_CONFIG_LENGTH]; +typedef unsigned char Tfa98xx_Preset_t[TFA98XX_PRESET_LENGTH]; +typedef unsigned char Tfa98xx_DrcParameters_t[TFA98XX_DRC_LENGTH]; + +/* Type containing all the possible errors that can occur + * + */ +enum Tfa98xx_Error { + Tfa98xx_Error_Ok = 0, + Tfa98xx_Error_Device, /* 1. Currently only used to keep in sync with tfa_error */ + Tfa98xx_Error_Bad_Parameter, /* 2. */ + Tfa98xx_Error_Fail, /* 3. generic failure, avoid mislead message */ + Tfa98xx_Error_NoClock, /* 4. no clock detected */ + Tfa98xx_Error_StateTimedOut, /* 5. */ + Tfa98xx_Error_DSP_not_running, /* 6. communication with the DSP failed */ + Tfa98xx_Error_AmpOn, /* 7. amp is still running */ + Tfa98xx_Error_NotOpen, /* 8. the given handle is not open */ + Tfa98xx_Error_InUse, /* 9. too many handles */ + Tfa98xx_Error_Buffer_too_small, /* 10. if a buffer is too small */ + /* the expected response did not occur within the expected time */ + Tfa98xx_Error_RpcBase = 100, + Tfa98xx_Error_RpcBusy = 101, + Tfa98xx_Error_RpcModId = 102, + Tfa98xx_Error_RpcParamId = 103, + Tfa98xx_Error_RpcInvalidCC = 104, + Tfa98xx_Error_RpcInvalidSeq = 105, + Tfa98xx_Error_RpcInvalidParam = 106, + Tfa98xx_Error_RpcBufferOverflow = 107, + Tfa98xx_Error_RpcCalibBusy = 108, + Tfa98xx_Error_RpcCalibFailed = 109, + Tfa98xx_Error_Not_Implemented, + Tfa98xx_Error_Not_Supported, + Tfa98xx_Error_I2C_Fatal, /* Fatal I2C error occurred */ + /* Nonfatal I2C error, and retry count reached */ + Tfa98xx_Error_I2C_NonFatal, + Tfa98xx_Error_Other = 1000 +}; + +/* + * Type containing all the possible msg returns DSP can give + * //TODO move to tfa_dsp_fw.h + */ +enum Tfa98xx_Status_ID { + Tfa98xx_DSP_Not_Running = -1, /* No response from DSP */ + Tfa98xx_I2C_Req_Done = + 0, /* Request executed correctly and result, if any, is available for download */ + Tfa98xx_I2C_Req_Busy = + 1, /* Request is being processed, just wait for result */ + Tfa98xx_I2C_Req_Invalid_M_ID = + 2, /* Provided M-ID does not fit in valid rang [0..2] */ + Tfa98xx_I2C_Req_Invalid_P_ID = + 3, /* Provided P-ID isn�t valid in the given M-ID context */ + Tfa98xx_I2C_Req_Invalid_CC = + 4, /* Invalid channel configuration bits (SC|DS|DP|DC) combination */ + Tfa98xx_I2C_Req_Invalid_Seq = + 5, /* Invalid sequence of commands, in case the DSP expects some commands in a specific order */ + Tfa98xx_I2C_Req_Invalid_Param = 6, /* Generic error */ + Tfa98xx_I2C_Req_Buffer_Overflow = + 7, /* I2C buffer has overflowed: host has sent too many parameters, memory integrity is not guaranteed */ + Tfa98xx_I2C_Req_Calib_Busy = 8, /* Calibration not finished */ + Tfa98xx_I2C_Req_Calib_Failed = 9 /* Calibration failed */ +}; + +/* + * speaker as microphone + */ +enum Tfa98xx_saam { + Tfa98xx_saam_none, /*< SAAM feature not available */ + Tfa98xx_saam /*< SAAM feature available */ +}; + +/* + * config file subtypes + */ +enum Tfa98xx_config_type { + Tfa98xx_config_generic, + Tfa98xx_config_sub1, + Tfa98xx_config_sub2, + Tfa98xx_config_sub3, +}; + +enum Tfa98xx_AmpInputSel { + Tfa98xx_AmpInputSel_I2SLeft, + Tfa98xx_AmpInputSel_I2SRight, + Tfa98xx_AmpInputSel_DSP +}; + +enum Tfa98xx_OutputSel { + Tfa98xx_I2SOutputSel_CurrentSense, + Tfa98xx_I2SOutputSel_DSP_Gain, + Tfa98xx_I2SOutputSel_DSP_AEC, + Tfa98xx_I2SOutputSel_Amp, + Tfa98xx_I2SOutputSel_DataI3R, + Tfa98xx_I2SOutputSel_DataI3L, + Tfa98xx_I2SOutputSel_DcdcFFwdCur, +}; + +enum Tfa98xx_StereoGainSel { + Tfa98xx_StereoGainSel_Left, + Tfa98xx_StereoGainSel_Right +}; + +#define TFA98XX_MAXPATCH_LENGTH (3 * 1024) + +/* the number of biquads supported */ +#define TFA98XX_BIQUAD_NUM 10 + +enum Tfa98xx_Channel { + Tfa98xx_Channel_L, + Tfa98xx_Channel_R, + Tfa98xx_Channel_L_R, + Tfa98xx_Channel_Stereo +}; + +enum Tfa98xx_Mode { Tfa98xx_Mode_Normal = 0, Tfa98xx_Mode_RCV }; + +enum Tfa98xx_Mute { + Tfa98xx_Mute_Off, + Tfa98xx_Mute_Digital, + Tfa98xx_Mute_Amplifier +}; + +enum Tfa98xx_SpeakerBoostStatusFlags { + Tfa98xx_SpeakerBoost_Activity = 0, /* Input signal activity. */ + Tfa98xx_SpeakerBoost_S_Ctrl, /* S Control triggers the limiter */ + Tfa98xx_SpeakerBoost_Muted, /* 1 when signal is muted */ + Tfa98xx_SpeakerBoost_X_Ctrl, /* X Control triggers the limiter */ + Tfa98xx_SpeakerBoost_T_Ctrl, /* T Control triggers the limiter */ + Tfa98xx_SpeakerBoost_NewModel, /* New model is available */ + Tfa98xx_SpeakerBoost_VolumeRdy, /* 0:stable vol, 1:still smoothing */ + Tfa98xx_SpeakerBoost_Damaged, /* Speaker Damage detected */ + Tfa98xx_SpeakerBoost_SignalClipping /* input clipping detected */ +}; + +struct Tfa98xx_DrcStateInfo { + float GRhighDrc1[2]; + float GRhighDrc2[2]; + float GRmidDrc1[2]; + float GRmidDrc2[2]; + float GRlowDrc1[2]; + float GRlowDrc2[2]; + float GRpostDrc1[2]; + float GRpostDrc2[2]; + float GRblDrc[2]; +}; +struct Tfa98xx_StateInfo { + /* SpeakerBoost State */ + float agcGain; /* Current AGC Gain value */ + float limGain; /* Current Limiter Gain value */ + float sMax; /* Current Clip/Lim threshold */ + int T; /* Current Speaker Temperature value */ + int statusFlag; /* Masked bit word */ + float X1; /* estimated excursion caused by Spkrboost gain ctrl */ + float X2; /* estimated excursion caused by manual gain setting */ + float Re; /* Loudspeaker blocked resistance */ + /* Framework state */ + /* increments each time a MIPS problem is detected on the DSP */ + int shortOnMips; + struct Tfa98xx_DrcStateInfo drcState; /* DRC state, when enabled */ +}; + +typedef struct nxpTfaMsg { + uint8_t msg_size; + unsigned char cmdId[3]; + int data[9]; +} nxpTfaMsg_t; + +typedef struct nxp_vstep_msg { + int fw_version; + uint8_t no_of_vsteps; + uint16_t reg_no; + uint8_t *msg_reg; + uint8_t msg_no; + uint32_t algo_param_length; + uint8_t *msg_algo_param; + uint32_t filter_coef_length; + uint8_t *msg_filter_coef; + uint32_t mbdrc_length; + uint8_t *msg_mbdrc; +} nxp_vstep_msg_t; + +typedef struct nxpTfaGroup { + uint8_t msg_size; + uint8_t profileId[64]; +} nxpTfaGroup_t; + +struct nxpTfa98xx_Memtrack_data { + int length; + float mValues[MEMTRACK_MAX_WORDS]; + int mAdresses[MEMTRACK_MAX_WORDS]; + int trackers[MEMTRACK_MAX_WORDS]; + int scalingFactor[MEMTRACK_MAX_WORDS]; +}; + +/* possible memory values for DMEM in CF_CONTROLs */ +enum Tfa98xx_DMEM { + Tfa98xx_DMEM_ERR = -1, + Tfa98xx_DMEM_PMEM = 0, + Tfa98xx_DMEM_XMEM = 1, + Tfa98xx_DMEM_YMEM = 2, + Tfa98xx_DMEM_IOMEM = 3, +}; + +/** + * lookup the device type and return the family type + */ +int tfa98xx_dev2family(int dev_type); + +/** + * register definition structure + */ +struct regdef { + unsigned char offset; /**< subaddress offset */ + unsigned short pwronDefault; /**< register contents after poweron */ + unsigned short pwronTestmask; /**< mask of bits not test */ + char *name; /**< short register name */ +}; + +enum Tfa98xx_DMEM tfa98xx_filter_mem(struct tfa_device *tfa, int filter_index, + unsigned short *address, int channel); + +/** + * Load the default HW settings in the device + * @param tfa the device struct pointer + */ +enum Tfa98xx_Error tfa98xx_init(struct tfa_device *tfa); + +/** + * If needed, this function can be used to get a text version of the status ID code + * @param status the given status ID code + * @return the I2C status ID string + */ +const char *tfa98xx_get_i2c_status_id_string(int status); + +/* control the powerdown bit + * @param tfa the device struct pointer + * @param powerdown must be 1 or 0 + */ +enum Tfa98xx_Error tfa98xx_powerdown(struct tfa_device *tfa, int powerdown); + +/* indicates on which channel of DATAI2 the gain from the IC is set + * @param tfa the device struct pointer + * @param gain_sel, see Tfa98xx_StereoGainSel_t + */ +enum Tfa98xx_Error +tfa98xx_select_stereo_gain_channel(struct tfa_device *tfa, + enum Tfa98xx_StereoGainSel gain_sel); + +/** + * set the mtp with user controllable values + * @param tfa the device struct pointer + * @param value to be written + * @param mask to be applied toi the bits affected + */ +enum Tfa98xx_Error tfa98xx_set_mtp(struct tfa_device *tfa, uint16_t value, + uint16_t mask); +enum Tfa98xx_Error tfa98xx_get_mtp(struct tfa_device *tfa, uint16_t *value); + +/** + * lock or unlock KEY2 + * lock = 1 will lock + * lock = 0 will unlock + * note that on return all the hidden key will be off + */ +void tfa98xx_key2(struct tfa_device *tfa, int lock); + +int tfa_calibrate(struct tfa_device *tfa); +void tfa98xx_set_exttemp(struct tfa_device *tfa, short ext_temp); +short tfa98xx_get_exttemp(struct tfa_device *tfa); + +/* control the volume of the DSP + * @param vol volume in bit field. It must be between 0 and 255 + */ +enum Tfa98xx_Error tfa98xx_set_volume_level(struct tfa_device *tfa, + unsigned short vol); + +/* set the input channel to use + * @param channel see Tfa98xx_Channel_t enumeration + */ +enum Tfa98xx_Error tfa98xx_select_channel(struct tfa_device *tfa, + enum Tfa98xx_Channel channel); + +/* set the mode for normal or receiver mode + * @param mode see Tfa98xx_Mode enumeration + */ +enum Tfa98xx_Error tfa98xx_select_mode(struct tfa_device *tfa, + enum Tfa98xx_Mode mode); + +/* mute/unmute the audio + * @param mute see Tfa98xx_Mute_t enumeration + */ +enum Tfa98xx_Error tfa98xx_set_mute(struct tfa_device *tfa, + enum Tfa98xx_Mute mute); + +/* + * tfa_supported_speakers - required for SmartStudio initialization + * returns the number of the supported speaker count + */ +enum Tfa98xx_Error tfa_supported_speakers(struct tfa_device *tfa, + int *spkr_count); + +/** +* Return the tfa revision +*/ +void tfa98xx_rev(int *major, int *minor, int *revision); + +/* + * Return the feature bits from MTP and cnt file for comparison + */ +enum Tfa98xx_Error tfa98xx_compare_features(struct tfa_device *tfa, + int features_from_MTP[3], + int features_from_cnt[3]); + +/* + * return feature bits + */ +enum Tfa98xx_Error tfa98xx_dsp_get_sw_feature_bits(struct tfa_device *tfa, + int features[2]); +enum Tfa98xx_Error tfa98xx_dsp_get_hw_feature_bits(struct tfa_device *tfa, + int *features); + +/* + * tfa98xx_supported_saam + * returns the speaker as microphone feature + * @param saam enum pointer + * @return error code + */ +enum Tfa98xx_Error tfa98xx_supported_saam(struct tfa_device *tfa, + enum Tfa98xx_saam *saam); + +/* load the tables to the DSP + * called after patch load is done + * @return error code + */ +enum Tfa98xx_Error tfa98xx_dsp_write_tables(struct tfa_device *tfa, + int sample_rate); + +/* set or clear DSP reset signal + * @param new state + * @return error code + */ +enum Tfa98xx_Error tfa98xx_dsp_reset(struct tfa_device *tfa, int state); + +/* check the state of the DSP subsystem + * return ready = 1 when clocks are stable to allow safe DSP subsystem access + * @param tfa the device struct pointer + * @param ready pointer to state flag, non-zero if clocks are not stable + * @return error code + */ +enum Tfa98xx_Error tfa98xx_dsp_system_stable(struct tfa_device *tfa, + int *ready); + +enum Tfa98xx_Error tfa98xx_auto_copy_mtp_to_iic(struct tfa_device *tfa); + +/** + * check the state of the DSP coolflux + * @param tfa the device struct pointer + * @return the value of CFE + */ +int tfa_cf_enabled(struct tfa_device *tfa); + +/* The following functions can only be called when the DSP is running + * - I2S clock must be active, + * - IC must be in operating mode + */ + +/** + * patch the ROM code of the DSP + * @param tfa the device struct pointer + * @param patchLength the number of bytes of patchBytes + * @param patchBytes pointer to the bytes to patch + */ +enum Tfa98xx_Error tfa_dsp_patch(struct tfa_device *tfa, int patchLength, + const unsigned char *patchBytes); + +/** + * load explicitly the speaker parameters in case of free speaker, + * or when using a saved speaker model + */ +enum Tfa98xx_Error +tfa98xx_dsp_write_speaker_parameters(struct tfa_device *tfa, int length, + const unsigned char *pSpeakerBytes); + +/** + * read the speaker parameters as used by the SpeakerBoost processing + */ +enum Tfa98xx_Error +tfa98xx_dsp_read_speaker_parameters(struct tfa_device *tfa, int length, + unsigned char *pSpeakerBytes); + +/** + * read the current status of the DSP, typically used for development, + * not essential to be used in a product + */ +enum Tfa98xx_Error tfa98xx_dsp_get_state_info(struct tfa_device *tfa, + unsigned char bytes[], + unsigned int *statesize); + +/** + * Check whether the DSP supports DRC + * pbSupportDrc=1 when DSP supports DRC, + * pbSupportDrc=0 when DSP doesn't support it + */ +enum Tfa98xx_Error tfa98xx_dsp_support_drc(struct tfa_device *tfa, + int *pbSupportDrc); + +enum Tfa98xx_Error tfa98xx_dsp_support_framework(struct tfa_device *tfa, + int *pbSupportFramework); + +/** + * read the speaker excursion model as used by SpeakerBoost processing + */ +enum Tfa98xx_Error +tfa98xx_dsp_read_excursion_model(struct tfa_device *tfa, int length, + unsigned char *pSpeakerBytes); + +/** + * load all the parameters for a preset from a file + */ +enum Tfa98xx_Error tfa98xx_dsp_write_preset(struct tfa_device *tfa, int length, + const unsigned char *pPresetBytes); + +/** + * wrapper for dsp_msg that adds opcode and only writes + */ +enum Tfa98xx_Error tfa_dsp_cmd_id_write(struct tfa_device *tfa, + unsigned char module_id, + unsigned char param_id, int num_bytes, + const unsigned char data[]); + +/** + * wrapper for dsp_msg that writes opcode and reads back the data + */ +enum Tfa98xx_Error tfa_dsp_cmd_id_write_read(struct tfa_device *tfa, + unsigned char module_id, + unsigned char param_id, + int num_bytes, + unsigned char data[]); + +/** + * wrapper for dsp_msg that adds opcode and 3 bytes required for coefs + */ +enum Tfa98xx_Error tfa_dsp_cmd_id_coefs(struct tfa_device *tfa, + unsigned char module_id, + unsigned char param_id, int num_bytes, + unsigned char data[]); + +/** + * wrapper for dsp_msg that adds opcode and 3 bytes required for MBDrcDynamics + */ +enum Tfa98xx_Error +tfa_dsp_cmd_id_MBDrc_dynamics(struct tfa_device *tfa, unsigned char module_id, + unsigned char param_id, int index_subband, + int num_bytes, unsigned char data[]); + +/** + * Disable a certain biquad. + * @param tfa the device struct pointer + * @param biquad_index: 1-10 of the biquad that needs to be adressed +*/ +enum Tfa98xx_Error Tfa98xx_DspBiquad_Disable(struct tfa_device *tfa, + int biquad_index); + +/** + * fill the calibration value as milli ohms in the struct + * assume that the device has been calibrated + */ +enum Tfa98xx_Error tfa_dsp_get_calibration_impedance(struct tfa_device *tfa); + +/* + * return the mohm value + */ +int tfa_get_calibration_info(struct tfa_device *tfa, int channel); + +/* + * return sign extended tap pattern + */ +int tfa_get_tap_pattern(struct tfa_device *tfa); + +/** + * Reads a number of words from dsp memory + * @param tfa the device struct pointer + * @param subaddress write address to set in address register + * @param pValue pointer to read data +*/ +enum Tfa98xx_Error tfa98xx_read_register16(struct tfa_device *tfa, + unsigned char subaddress, + unsigned short *pValue); + +/** + * Reads a number of words from dsp memory + * @param tfa the device struct pointer + * @param subaddress write address to set in address register + * @param value value to write int the memory +*/ +enum Tfa98xx_Error tfa98xx_write_register16(struct tfa_device *tfa, + unsigned char subaddress, + unsigned short value); + +/** + * Intialise the dsp + * @param tfa the device struct pointer + * @return tfa error enum +*/ +enum Tfa98xx_Error tfa98xx_init_dsp(struct tfa_device *tfa); + +/** + * Get the status of the external DSP + * @param tfa the device struct pointer + * @return status +*/ +int tfa98xx_get_dsp_status(struct tfa_device *tfa); + +/** + * Write a command message (RPC) to the dsp + * @param tfa the device struct pointer + * @param num_bytes command buffer size in bytes + * @param command_buffer + * @return tfa error enum +*/ +enum Tfa98xx_Error tfa98xx_write_dsp(struct tfa_device *tfa, int num_bytes, + const char *command_buffer); + +/** + * Read the result from the last message from the dsp + * @param tfa the device struct pointer + * @param num_bytes result buffer size in bytes + * @param result_buffer + * @return tfa error enum +*/ +enum Tfa98xx_Error tfa98xx_read_dsp(struct tfa_device *tfa, int num_bytes, + unsigned char *result_buffer); + +/** + * Write a command message (RPC) to the dsp and return the result + * @param tfa the device struct pointer + * @param command_length command buffer size in bytes + * @param command_buffer command buffer + * @param result_length result buffer size in bytes + * @param result_buffer result buffer + * @return tfa error enum +*/ +enum Tfa98xx_Error tfa98xx_writeread_dsp(struct tfa_device *tfa, + int command_length, + void *command_buffer, + int result_length, + void *result_buffer); + +/** + * Reads a number of words from dsp memory + * @param tfa the device struct pointer + * @param start_offset offset from where to start reading + * @param num_words number of words to read + * @param pValues pointer to read data +*/ +enum Tfa98xx_Error tfa98xx_dsp_read_mem(struct tfa_device *tfa, + unsigned int start_offset, + int num_words, int *pValues); +/** + * Write a value to dsp memory + * @param tfa the device struct pointer + * @param address write address to set in address register + * @param value value to write int the memory + * @param memtype type of memory to write to +*/ +enum Tfa98xx_Error tfa98xx_dsp_write_mem_word(struct tfa_device *tfa, + unsigned short address, int value, + int memtype); + +/** + * Read data from dsp memory + * @param tfa the device struct pointer + * @param subaddress write address to set in address register + * @param num_bytes number of bytes to read from dsp + * @param data the unsigned char buffer to read data into +*/ +enum Tfa98xx_Error tfa98xx_read_data(struct tfa_device *tfa, + unsigned char subaddress, int num_bytes, + unsigned char data[]); + +/** + * Write all the bytes specified by num_bytes and data to dsp memory + * @param tfa the device struct pointer + * @param subaddress the subaddress to write to + * @param num_bytes number of bytes to write + * @param data actual data to write +*/ +enum Tfa98xx_Error tfa98xx_write_data(struct tfa_device *tfa, + unsigned char subaddress, int num_bytes, + const unsigned char data[]); + +enum Tfa98xx_Error tfa98xx_write_raw(struct tfa_device *tfa, int num_bytes, + const unsigned char data[]); + +/* support for converting error codes into text */ +const char *tfa98xx_get_error_string(enum Tfa98xx_Error error); + +/** + * convert signed 24 bit integers to 32bit aligned bytes + * input: data contains "num_bytes/3" int24 elements + * output: bytes contains "num_bytes" byte elements + * @param num_data length of the input data array + * @param data input data as integer array + * @param bytes output data as unsigned char array +*/ +void tfa98xx_convert_data2bytes(int num_data, const int data[], + unsigned char bytes[]); + +/** + * convert memory bytes to signed 24 bit integers + * input: bytes contains "num_bytes" byte elements + * output: data contains "num_bytes/3" int24 elements + * @param num_bytes length of the input data array + * @param bytes input data as unsigned char array + * @param data output data as integer array +*/ +void tfa98xx_convert_bytes2data(int num_bytes, const unsigned char bytes[], + int data[]); + +/** + * Read a part of the dsp memory + * @param tfa the device struct pointer + * @param memoryType indicator to the memory type + * @param offset from where to start reading + * @param length the number of bytes to read + * @param bytes output data as unsigned char array +*/ +enum Tfa98xx_Error tfa98xx_dsp_get_memory(struct tfa_device *tfa, + int memoryType, int offset, + int length, unsigned char bytes[]); + +/** + * Write a value to the dsp memory + * @param tfa the device struct pointer + * @param memoryType indicator to the memory type + * @param offset from where to start writing + * @param length the number of bytes to write + * @param value the value to write to the dsp +*/ +enum Tfa98xx_Error tfa98xx_dsp_set_memory(struct tfa_device *tfa, + int memoryType, int offset, + int length, int value); + +enum Tfa98xx_Error +tfa98xx_dsp_write_config(struct tfa_device *tfa, int length, + const unsigned char *p_config_bytes); +enum Tfa98xx_Error tfa98xx_dsp_write_drc(struct tfa_device *tfa, int length, + const unsigned char *p_drc_bytes); + +/** + * write/read raw msg functions : + * the buffer is provided in little endian format, each word occupying 3 bytes, length is in bytes. + * The functions will return immediately and do not not wait for DSP reponse. + * @param tfa the device struct pointer + * @param length length of the character buffer to write + * @param buf character buffer to write +*/ +enum Tfa98xx_Error tfa_dsp_msg(struct tfa_device *tfa, int length, + const char *buf); + +/** + * The wrapper functions to call the dsp msg, register and memory function for tfa or probus + */ +enum Tfa98xx_Error dsp_msg(struct tfa_device *tfa, int length, const char *buf); +enum Tfa98xx_Error dsp_msg_read(struct tfa_device *tfa, int length, + unsigned char *bytes); +enum Tfa98xx_Error reg_write(struct tfa_device *tfa, unsigned char subaddress, + unsigned short value); +enum Tfa98xx_Error reg_read(struct tfa_device *tfa, unsigned char subaddress, + unsigned short *value); +enum Tfa98xx_Error mem_write(struct tfa_device *tfa, unsigned short address, + int value, int memtype); +enum Tfa98xx_Error mem_read(struct tfa_device *tfa, unsigned int start_offset, + int num_words, int *pValues); + +enum Tfa98xx_Error dsp_partial_coefficients(struct tfa_device *tfa, + uint8_t *prev, uint8_t *next); + +/** + * write/read raw msg functions: + * the buffer is provided in little endian format, each word occupying 3 bytes, length is in bytes. + * The functions will return immediately and do not not wait for DSP reponse. + * An ID is added to modify the command-ID + * @param tfa the device struct pointer + * @param length length of the character buffer to write + * @param buf character buffer to write + * @param cmdid command identifier +*/ +enum Tfa98xx_Error tfa_dsp_msg_id(struct tfa_device *tfa, int length, + const char *buf, uint8_t cmdid[3]); + +/** + * write raw dsp msg functions + * @param tfa the device struct pointer + * @param length length of the character buffer to write + * @param buffer character buffer to write +*/ +enum Tfa98xx_Error tfa_dsp_msg_write(struct tfa_device *tfa, int length, + const char *buffer); + +/** + * write raw dsp msg functions + * @param tfa the device struct pointer + * @param length length of the character buffer to write + * @param buffer character buffer to write + * @param cmdid command identifier +*/ +enum Tfa98xx_Error tfa_dsp_msg_write_id(struct tfa_device *tfa, int length, + const char *buffer, uint8_t cmdid[3]); + +/** + * status function used by tfa_dsp_msg() to retrieve command/msg status: + * return a <0 status of the DSP did not ACK. + * @param tfa the device struct pointer + * @param pRpcStatus status for remote processor communication +*/ +enum Tfa98xx_Error tfa_dsp_msg_status(struct tfa_device *tfa, int *pRpcStatus); + +/** + * Read a message from dsp + * @param tfa the device struct pointer + * @param length number of bytes of the message + * @param bytes pointer to unsigned char buffer +*/ +enum Tfa98xx_Error tfa_dsp_msg_read(struct tfa_device *tfa, int length, + unsigned char *bytes); + +int tfa_set_bf(struct tfa_device *tfa, const uint16_t bf, const uint16_t value); +int tfa_set_bf_volatile(struct tfa_device *tfa, const uint16_t bf, + const uint16_t value); + +/** + * Get the value of a given bitfield + * @param tfa the device struct pointer + * @param bf the value indicating which bitfield + */ +int tfa_get_bf(struct tfa_device *tfa, const uint16_t bf); + +/** + * Set the value of a given bitfield + * @param bf the value indicating which bitfield + * @param bf_value the value of the bitfield + * @param p_reg_value a pointer to the register where to write the bitfield value + */ +int tfa_set_bf_value(const uint16_t bf, const uint16_t bf_value, + uint16_t *p_reg_value); + +uint16_t tfa_get_bf_value(const uint16_t bf, const uint16_t reg_value); +int tfa_write_reg(struct tfa_device *tfa, const uint16_t bf, + const uint16_t reg_value); +int tfa_read_reg(struct tfa_device *tfa, const uint16_t bf); + +/* bitfield */ +/** + * get the datasheet or bitfield name corresponding to the bitfield number + * @param num is the number for which to get the bitfield name + * @param rev is the device type + */ +char *tfaContBfName(uint16_t num, unsigned short rev); + +/** + * get the datasheet name corresponding to the bitfield number + * @param num is the number for which to get the bitfield name + * @param rev is the device type + */ +char *tfaContDsName(uint16_t num, unsigned short rev); + +/** + * get the bitfield name corresponding to the bitfield number + * @param num is the number for which to get the bitfield name + * @param rev is the device type + */ +char *tfaContBitName(uint16_t num, unsigned short rev); + +/** + * get the bitfield number corresponding to the bitfield name + * @param name is the bitfield name for which to get the bitfield number + * @param rev is the device type + */ +uint16_t tfaContBfEnum(const char *name, unsigned short rev); + +/** +* get the bitfield number corresponding to the bitfield name, checks for all devices +* @param name is the bitfield name for which to get the bitfield number + */ +uint16_t tfaContBfEnumAny(const char *name); + +#define TFA_FAM(tfa, fieldname) \ + ((tfa->tfa_family == 1) ? TFA1_BF_##fieldname : TFA2_BF_##fieldname) +#define TFA_FAM_FW(tfa, fwname) \ + ((tfa->tfa_family == 1) ? TFA1_FW_##fwname : TFA2_FW_##fwname) + +/* set/get bit fields to HW register*/ +#define TFA_SET_BF(tfa, fieldname, value) \ + tfa_set_bf(tfa, TFA_FAM(tfa, fieldname), value) +#define TFA_SET_BF_VOLATILE(tfa, fieldname, value) \ + tfa_set_bf_volatile(tfa, TFA_FAM(tfa, fieldname), value) +#define TFA_GET_BF(tfa, fieldname) tfa_get_bf(tfa, TFA_FAM(tfa, fieldname)) + +/* set/get bit field in variable */ +#define TFA_SET_BF_VALUE(tfa, fieldname, bf_value, p_reg_value) \ + tfa_set_bf_value(TFA_FAM(tfa, fieldname), bf_value, p_reg_value) +#define TFA_GET_BF_VALUE(tfa, fieldname, reg_value) \ + tfa_get_bf_value(TFA_FAM(tfa, fieldname), reg_value) + +/* write/read registers using a bit field name to determine the register address */ +#define TFA_WRITE_REG(tfa, fieldname, value) \ + tfa_write_reg(tfa, TFA_FAM(tfa, fieldname), value) +#define TFA_READ_REG(tfa, fieldname) tfa_read_reg(tfa, TFA_FAM(tfa, fieldname)) + +/* FOR CALIBRATION RETRIES */ +#define TFA98XX_API_WAITRESULT_NTRIES 3000 // defined in API + +/** + * run the startup/init sequence and set ACS bit + * @param tfa the device struct pointer + * @param state the cold start state that is requested + */ +enum Tfa98xx_Error tfaRunColdboot(struct tfa_device *tfa, int state); +enum Tfa98xx_Error tfaRunMute(struct tfa_device *tfa); +enum Tfa98xx_Error tfaRunUnmute(struct tfa_device *tfa); + +/** + * wait for calibrateDone + * @param tfa the device struct pointer + * @param calibrateDone pointer to status of calibration + */ +enum Tfa98xx_Error tfaRunWaitCalibration(struct tfa_device *tfa, + int *calibrateDone); + +/** + * run the startup/init sequence and set ACS bit + * @param tfa the device struct pointer + * @param profile the profile that should be loaded + */ +enum Tfa98xx_Error tfaRunColdStartup(struct tfa_device *tfa, int profile); + +/** + * this will load the patch witch will implicitly start the DSP + * if no patch is available the DPS is started immediately + * @param tfa the device struct pointer + */ +enum Tfa98xx_Error tfaRunStartDSP(struct tfa_device *tfa); + +/** + * start the clocks and wait until the AMP is switching + * on return the DSP sub system will be ready for loading + * @param tfa the device struct pointer + * @param profile the profile that should be loaded on startup + */ +enum Tfa98xx_Error tfaRunStartup(struct tfa_device *tfa, int profile); + +/** + * start the maximus speakerboost algorithm + * this implies a full system startup when the system was not already started + * @param tfa the device struct pointer + * @param force indicates wether a full system startup should be allowed + * @param profile the profile that should be loaded + */ +enum Tfa98xx_Error tfaRunSpeakerBoost(struct tfa_device *tfa, int force, + int profile); + +/** + * Startup the device and write all files from device and profile section + * @param tfa the device struct pointer + * @param force indicates wether a full system startup should be allowed + * @param profile the profile that should be loaded on speaker startup + */ +enum Tfa98xx_Error tfaRunSpeakerStartup(struct tfa_device *tfa, int force, + int profile); + +/** + * Run calibration + * @param tfa the device struct pointer + */ +enum Tfa98xx_Error tfaRunSpeakerCalibration(struct tfa_device *tfa); + +/** + * startup all devices. all step until patch loading is handled + * @param tfa the device struct pointer + */ +int tfaRunStartupAll(struct tfa_device *tfa); + +/** + * powerup the coolflux subsystem and wait for it + * @param tfa the device struct pointer + */ +enum Tfa98xx_Error tfa_cf_powerup(struct tfa_device *tfa); + +/* + * print the current device manager state + * @param tfa the device struct pointer + */ +enum Tfa98xx_Error show_current_state(struct tfa_device *tfa); + +/** + * Init registers and coldboot dsp + * @param tfa the device struct pointer + */ +int tfa_reset(struct tfa_device *tfa); + +/** + * Get profile from a register + * @param tfa the device struct pointer + */ +int tfa_dev_get_swprof(struct tfa_device *tfa); + +/** + * Save profile in a register + */ +int tfa_dev_set_swprof(struct tfa_device *tfa, unsigned short new_value); + +int tfa_dev_get_swvstep(struct tfa_device *tfa); + +int tfa_dev_set_swvstep(struct tfa_device *tfa, unsigned short new_value); + +int tfa_needs_reset(struct tfa_device *tfa); + +int tfa_is_cold(struct tfa_device *tfa); + +void tfa_set_query_info(struct tfa_device *tfa); + +int tfa_get_pga_gain(struct tfa_device *tfa); +int tfa_set_pga_gain(struct tfa_device *tfa, uint16_t value); +int tfa_get_noclk(struct tfa_device *tfa); + +/** + * Status of used for monitoring + * @param tfa the device struct pointer + * @return tfa error enum + */ + +enum Tfa98xx_Error tfa_status(struct tfa_device *tfa); + +/* + * function overload for flag_mtp_busy + */ +int tfa_dev_get_mtpb(struct tfa_device *tfa); + +#ifdef __cplusplus +} +#endif +#endif /* TFA_SERVICE_H */ diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/versions.h b/techpack/audio/asoc/codecs/tfa98xx/inc/versions.h new file mode 100644 index 000000000000..4bc866fa6deb --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/inc/versions.h @@ -0,0 +1,4 @@ +#ifndef _VERSIONS_H +#define TFA98XX_GIT_VERSIONS "v6.5.2_xxxxxxxxxx" +#define _VERSIONS_H +#endif diff --git a/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c b/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c new file mode 100644 index 000000000000..f5542c15adb6 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c @@ -0,0 +1,4412 @@ +/* + * tfa98xx.c tfa98xx codec module + * + * Copyright 2014-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define pr_fmt(fmt) "%s(): " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "tfa98xx.h" +#include "tfa.h" +#include "tfa_dsp_fw.h" + +/* required for enum tfa9912_irq */ +#include "tfa98xx_tfafieldnames.h" + +#include "spk-id.h" + +#define TFA98XX_VERSION TFA98XX_API_REV_STR + +#define I2C_RETRIES 50 +#define I2C_RETRY_DELAY 5 /* ms */ + +/* Change volume selection behavior: + * Uncomment following line to generate a profile change when updating + * a volume control (also changes to the profile of the modified volume + * control) + */ +/*#define TFA98XX_ALSA_CTRL_PROF_CHG_ON_VOL 1 +*/ + +/* Supported rates and data formats */ +#define TFA98XX_RATES SNDRV_PCM_RATE_8000_48000 +#define TFA98XX_FORMATS \ + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define TF98XX_MAX_DSP_START_TRY_COUNT 10 + +#define TFA98XX_AAC_FW_NAME "tfa98xx_aac.cnt" +#define TFA98XX_GOER_FW_NAME "tfa98xx_goer.cnt" + +/* data accessible by all instances */ +static struct kmem_cache *tfa98xx_cache = + NULL; /* Memory pool used for DSP messages */ +/* Mutex protected data */ +static DEFINE_MUTEX(tfa98xx_mutex); +static LIST_HEAD(tfa98xx_device_list); +static int tfa98xx_device_count = 0; +static int tfa98xx_sync_count = 0; +static LIST_HEAD(profile_list); /* list of user selectable profiles */ +static int tfa98xx_mixer_profiles = 0; /* number of user selectable profiles */ +static int tfa98xx_mixer_profile = 0; /* current mixer profile */ +static struct snd_kcontrol_new *tfa98xx_controls; +static nxpTfaContainer_t *tfa98xx_container = NULL; + +static int tfa98xx_kmsg_regs = 0; +static int tfa98xx_ftrace_regs = 0; + +static char *fw_name = "tfa98xx.cnt"; +module_param(fw_name, charp, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(fw_name, "TFA98xx DSP firmware (container file) name."); + +static int trace_level = 0; +module_param(trace_level, int, S_IRUGO); +MODULE_PARM_DESC( + trace_level, + "TFA98xx debug trace level (0=off, bits:1=verbose,2=regdmesg,3=regftrace,4=timing)."); + +static char *dflt_prof_name = ""; +module_param(dflt_prof_name, charp, S_IRUGO); + +static int no_start = 0; +module_param(no_start, int, S_IRUGO); +MODULE_PARM_DESC(no_start, + "do not start the work queue; for debugging via user\n"); + +static int no_reset = 0; +module_param(no_reset, int, S_IRUGO); +MODULE_PARM_DESC(no_reset, + "do not use the reset line; for debugging via user\n"); + +static int pcm_no_constraint = 0; +module_param(pcm_no_constraint, int, S_IRUGO); +MODULE_PARM_DESC(pcm_no_constraint, + "do not use constraints for PCM parameters\n"); + +static void tfa98xx_tapdet_check_update(struct tfa98xx *tfa98xx); +static int tfa98xx_get_fssel(unsigned int rate); +static void tfa98xx_interrupt_enable(struct tfa98xx *tfa98xx, bool enable); + +static int get_profile_from_list(char *buf, int id); +static int get_profile_id_for_sr(int id, unsigned int rate); + +struct tfa98xx_rate { + unsigned int rate; + unsigned int fssel; +}; + +static const struct tfa98xx_rate rate_to_fssel[] = { + { 8000, 0 }, { 11025, 1 }, { 12000, 2 }, { 16000, 3 }, { 22050, 4 }, + { 24000, 5 }, { 32000, 6 }, { 44100, 7 }, { 48000, 8 }, +}; + +int nxp_spk_id_get(struct device_node *np) +{ + int id = VENDOR_ID_UNKNOWN; + int state = 3; + + /*state = spk_id_get_pin_3state(np); + if (state < 0) { + pr_err("%s: Can not get id pin state, %d\n", __func__, state); + return VENDOR_ID_NONE; + }*/ + + switch (state) { + case PIN_PULL_DOWN: + id = VENDOR_ID_GOER; + break; + case PIN_PULL_UP: + id = VENDOR_ID_UNKNOWN; + break; + case PIN_FLOAT: + id = VENDOR_ID_AAC; + break; + default: + id = VENDOR_ID_NONE; + break; + } + return id; +} + +static int nxp_vendor_id_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = VENDOR_ID_NONE; + + if (tfa98xx->spk_id_gpio_p) + ucontrol->value.integer.value[0] = + nxp_spk_id_get(tfa98xx->spk_id_gpio_p); + return 0; +} + +static const char *const nxp_vendor_id_text[] = { "None", "AAC", "SSI", "GOER", + "Unknown" }; + +static const struct soc_enum nxp_vendor_id[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(nxp_vendor_id_text), nxp_vendor_id_text), +}; + +const struct snd_kcontrol_new nxp_spk_id_controls[] = { + SOC_ENUM_EXT("SPK ID", nxp_vendor_id, nxp_vendor_id_get, NULL), +}; + +static inline char *tfa_cont_profile_name(struct tfa98xx *tfa98xx, int prof_idx) +{ + if (tfa98xx->tfa->cnt == NULL) + return NULL; + return tfaContProfileName(tfa98xx->tfa->cnt, tfa98xx->tfa->dev_idx, + prof_idx); +} + +static enum tfa_error tfa98xx_write_re25(struct tfa_device *tfa, int value) +{ + enum tfa_error err; + + /* clear MTPEX */ + err = tfa_dev_mtp_set(tfa, TFA_MTP_EX, 0); + if (err == tfa_error_ok) { + /* set RE25 in shadow regiser */ + err = tfa_dev_mtp_set(tfa, TFA_MTP_RE25_PRIM, value); + } + if (err == tfa_error_ok) { + /* set MTPEX to copy RE25 into MTP */ + err = tfa_dev_mtp_set(tfa, TFA_MTP_EX, 2); + } + + return err; +} + +/* Wrapper for tfa start */ +static enum tfa_error tfa98xx_tfa_start(struct tfa98xx *tfa98xx, + int next_profile, int vstep) +{ + enum tfa_error err; + ktime_t start_time, stop_time; + u64 delta_time; + + pr_debug("%s next_profile=%d vstep=%d\n", __func__, next_profile, + vstep); + if (trace_level & 8) { + start_time = ktime_get_boottime(); + } + + /*[nxp34663] CR: support 16bit/24bit/32bit audio data. begin*/ +#ifdef __KERNEL__ + err = tfa_dev_start(tfa98xx->tfa, next_profile, vstep, + tfa98xx->pcm_format); +#else + err = tfa_dev_start(tfa98xx->tfa, next_profile, vstep); +#endif + /*[nxp34663] CR: support 16bit/24bit/32bit audio data. end*/ + pr_debug("%s after performed tfa_dev_start return (%d)\n", __func__, + err); + + if (trace_level & 8) { + stop_time = ktime_get_boottime(); + delta_time = ktime_to_ns(ktime_sub(stop_time, start_time)); + do_div(delta_time, 1000); + dev_dbg(&tfa98xx->i2c->dev, + "tfa_dev_start(%d,%d) time = %lld us\n", next_profile, + vstep, delta_time); + } + + if ((err == tfa_error_ok) && (tfa98xx->set_mtp_cal)) { + enum tfa_error err_cal; + err_cal = tfa98xx_write_re25(tfa98xx->tfa, tfa98xx->cal_data); + if (err_cal != tfa_error_ok) { + pr_err("Error, setting calibration value in mtp, err=%d\n", + err_cal); + } else { + tfa98xx->set_mtp_cal = false; + pr_info("Calibration value (%d) set in mtp\n", + tfa98xx->cal_data); + } + } + + /* Check and update tap-detection state (in case of profile change) */ + tfa98xx_tapdet_check_update(tfa98xx); + + /* Remove sticky bit by reading it once */ + tfa_get_noclk(tfa98xx->tfa); + + /* A cold start erases the configuration, including interrupts setting. + * Restore it if required + */ + tfa98xx_interrupt_enable(tfa98xx, true); + + return err; +} + +static int tfa98xx_input_open(struct input_dev *dev) +{ + struct tfa98xx *tfa98xx = input_get_drvdata(dev); + dev_dbg(tfa98xx->codec->dev, "opening device file\n"); + + /* note: open function is called only once by the framework. + * No need to count number of open file instances. + */ + if (tfa98xx->dsp_fw_state != TFA98XX_DSP_FW_OK) { + dev_dbg(&tfa98xx->i2c->dev, + "DSP not loaded, cannot start tap-detection\n"); + return -EIO; + } + + /* enable tap-detection service */ + tfa98xx->tapdet_open = true; + tfa98xx_tapdet_check_update(tfa98xx); + + return 0; +} + +static void tfa98xx_input_close(struct input_dev *dev) +{ + struct tfa98xx *tfa98xx = input_get_drvdata(dev); + + dev_dbg(tfa98xx->codec->dev, "closing device file\n"); + + /* Note: close function is called if the device is unregistered */ + + /* disable tap-detection service */ + tfa98xx->tapdet_open = false; + tfa98xx_tapdet_check_update(tfa98xx); +} + +static int tfa98xx_register_inputdev(struct tfa98xx *tfa98xx) +{ + int err; + struct input_dev *input; + input = input_allocate_device(); + + if (!input) { + dev_err(tfa98xx->codec->dev, + "Unable to allocate input device\n"); + return -ENOMEM; + } + + input->evbit[0] = BIT_MASK(EV_KEY); + input->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0); + input->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1); + input->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2); + input->keybit[BIT_WORD(BTN_3)] |= BIT_MASK(BTN_3); + input->keybit[BIT_WORD(BTN_4)] |= BIT_MASK(BTN_4); + input->keybit[BIT_WORD(BTN_5)] |= BIT_MASK(BTN_5); + input->keybit[BIT_WORD(BTN_6)] |= BIT_MASK(BTN_6); + input->keybit[BIT_WORD(BTN_7)] |= BIT_MASK(BTN_7); + input->keybit[BIT_WORD(BTN_8)] |= BIT_MASK(BTN_8); + input->keybit[BIT_WORD(BTN_9)] |= BIT_MASK(BTN_9); + + input->open = tfa98xx_input_open; + input->close = tfa98xx_input_close; + + input->name = "tfa98xx-tapdetect"; + + input->id.bustype = BUS_I2C; + input_set_drvdata(input, tfa98xx); + + err = input_register_device(input); + if (err) { + dev_err(tfa98xx->codec->dev, + "Unable to register input device\n"); + goto err_free_dev; + } + + dev_dbg(tfa98xx->codec->dev, + "Input device for tap-detection registered: %s\n", input->name); + tfa98xx->input = input; + return 0; + +err_free_dev: + input_free_device(input); + return err; +} + +/* + * Check if an input device for tap-detection can and shall be registered. + * Register it if appropriate. + * If already registered, check if still relevant and remove it if necessary. + * unregister: true to request inputdev unregistration. + */ +static void __tfa98xx_inputdev_check_register(struct tfa98xx *tfa98xx, + bool unregister) +{ + bool tap_profile = false; + unsigned int i; + for (i = 0; i < tfa_cnt_get_dev_nprof(tfa98xx->tfa); i++) { + if (strstr(tfa_cont_profile_name(tfa98xx, i), ".tap")) { + tap_profile = true; + tfa98xx->tapdet_profiles |= 1 << i; + dev_info(tfa98xx->codec->dev, + "found a tap-detection profile (%d - %s)\n", i, + tfa_cont_profile_name(tfa98xx, i)); + } + } + + /* Check for device support: + * - at device level + * - at container (profile) level + */ + if (!(tfa98xx->flags & TFA98XX_FLAG_TAPDET_AVAILABLE) || !tap_profile || + unregister) { + /* No input device supported or required */ + if (tfa98xx->input) { + input_unregister_device(tfa98xx->input); + tfa98xx->input = NULL; + } + return; + } + + /* input device required */ + if (tfa98xx->input) + dev_info(tfa98xx->codec->dev, + "Input device already registered, skipping\n"); + else + tfa98xx_register_inputdev(tfa98xx); +} + +static void tfa98xx_inputdev_check_register(struct tfa98xx *tfa98xx) +{ + __tfa98xx_inputdev_check_register(tfa98xx, false); +} + +static void tfa98xx_inputdev_unregister(struct tfa98xx *tfa98xx) +{ + __tfa98xx_inputdev_check_register(tfa98xx, true); +} + +#ifdef CONFIG_DEBUG_FS +/* OTC reporting + * Returns the MTP0 OTC bit value + */ +static int tfa98xx_dbgfs_otc_get(void *data, u64 *val) +{ + struct i2c_client *i2c = (struct i2c_client *)data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + int value; + + mutex_lock(&tfa98xx->dsp_lock); + value = tfa_dev_mtp_get(tfa98xx->tfa, TFA_MTP_OTC); + mutex_unlock(&tfa98xx->dsp_lock); + + if (value < 0) { + pr_err("[0x%x] Unable to check DSP access: %d\n", + tfa98xx->i2c->addr, value); + return -EIO; + } + + *val = value; + pr_debug("[0x%x] OTC : %d\n", tfa98xx->i2c->addr, value); + + return 0; +} + +static int tfa98xx_dbgfs_otc_set(void *data, u64 val) +{ + struct i2c_client *i2c = (struct i2c_client *)data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + enum tfa_error err; + + if (val != 0 && val != 1) { + pr_err("[0x%x] Unexpected value %llu\n", tfa98xx->i2c->addr, + val); + return -EINVAL; + } + + mutex_lock(&tfa98xx->dsp_lock); + err = tfa_dev_mtp_set(tfa98xx->tfa, TFA_MTP_OTC, val); + mutex_unlock(&tfa98xx->dsp_lock); + + if (err != tfa_error_ok) { + pr_err("[0x%x] Unable to check DSP access: %d\n", + tfa98xx->i2c->addr, err); + return -EIO; + } + + pr_debug("[0x%x] OTC < %llu\n", tfa98xx->i2c->addr, val); + + return 0; +} + +static int tfa98xx_dbgfs_mtpex_get(void *data, u64 *val) +{ + struct i2c_client *i2c = (struct i2c_client *)data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + int value; + + mutex_lock(&tfa98xx->dsp_lock); + value = tfa_dev_mtp_get(tfa98xx->tfa, TFA_MTP_EX); + mutex_unlock(&tfa98xx->dsp_lock); + + if (value < 0) { + pr_err("[0x%x] Unable to check DSP access: %d\n", + tfa98xx->i2c->addr, value); + return -EIO; + } + + *val = value; + pr_debug("[0x%x] MTPEX : %d\n", tfa98xx->i2c->addr, value); + + return 0; +} + +static int tfa98xx_dbgfs_mtpex_set(void *data, u64 val) +{ + struct i2c_client *i2c = (struct i2c_client *)data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + enum tfa_error err; + + if (val != 0) { + pr_err("[0x%x] Can only clear MTPEX (0 value expected)\n", + tfa98xx->i2c->addr); + return -EINVAL; + } + + mutex_lock(&tfa98xx->dsp_lock); + err = tfa_dev_mtp_set(tfa98xx->tfa, TFA_MTP_EX, val); + mutex_unlock(&tfa98xx->dsp_lock); + + if (err != tfa_error_ok) { + pr_err("[0x%x] Unable to check DSP access: %d\n", + tfa98xx->i2c->addr, err); + return -EIO; + } + + pr_debug("[0x%x] MTPEX < 0\n", tfa98xx->i2c->addr); + + return 0; +} + +static int tfa98xx_dbgfs_temp_get(void *data, u64 *val) +{ + struct i2c_client *i2c = (struct i2c_client *)data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + + mutex_lock(&tfa98xx->dsp_lock); + *val = tfa98xx_get_exttemp(tfa98xx->tfa); + mutex_unlock(&tfa98xx->dsp_lock); + + pr_debug("[0x%x] TEMP : %llu\n", tfa98xx->i2c->addr, *val); + + return 0; +} + +static int tfa98xx_dbgfs_temp_set(void *data, u64 val) +{ + struct i2c_client *i2c = (struct i2c_client *)data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + + mutex_lock(&tfa98xx->dsp_lock); + tfa98xx_set_exttemp(tfa98xx->tfa, (short)val); + mutex_unlock(&tfa98xx->dsp_lock); + + pr_debug("[0x%x] TEMP < %llu\n", tfa98xx->i2c->addr, val); + + return 0; +} + +static ssize_t tfa98xx_dbgfs_start_set(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct i2c_client *i2c = file->private_data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + enum tfa_error ret; + char buf[32]; + const char ref[] = "please calibrate now"; + int buf_size; + + /* check string length, and account for eol */ + if (count > sizeof(ref) + 1 || count < (sizeof(ref) - 1)) + return -EINVAL; + + buf_size = min(count, (size_t)(sizeof(buf) - 1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + /* Compare string, excluding the trailing \0 and the potentials eol */ + if (strncmp(buf, ref, sizeof(ref) - 1)) + return -EINVAL; + + mutex_lock(&tfa98xx->dsp_lock); + ret = tfa_calibrate(tfa98xx->tfa); + if (ret == tfa_error_ok) + ret = tfa98xx_tfa_start(tfa98xx, tfa98xx->profile, + tfa98xx->vstep); + if (ret == tfa_error_ok) + tfa_dev_set_state(tfa98xx->tfa, TFA_STATE_UNMUTE, 0); + mutex_unlock(&tfa98xx->dsp_lock); + + if (ret) { + pr_info("[0x%x] Calibration start failed (%d)\n", + tfa98xx->i2c->addr, ret); + return -EIO; + } else { + pr_info("[0x%x] Calibration started\n", tfa98xx->i2c->addr); + } + + return count; +} + +static ssize_t tfa98xx_dbgfs_r_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct i2c_client *i2c = file->private_data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + char *str; + uint16_t status; + int ret; + + mutex_lock(&tfa98xx->dsp_lock); + + /* Need to ensure DSP is access-able, use mtp read access for this + * purpose + */ + ret = tfa98xx_get_mtp(tfa98xx->tfa, &status); + if (ret) { + ret = -EIO; + pr_err("[0x%x] MTP read failed\n", tfa98xx->i2c->addr); + goto r_c_err; + } + + ret = tfaRunSpeakerCalibration(tfa98xx->tfa); + if (ret) { + ret = -EIO; + pr_err("[0x%x] calibration failed\n", tfa98xx->i2c->addr); + goto r_c_err; + } + + str = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!str) { + ret = -ENOMEM; + pr_err("[0x%x] memory allocation failed\n", tfa98xx->i2c->addr); + goto r_c_err; + } + + if (tfa98xx->tfa->spkr_count > 1) { + ret = snprintf(str, PAGE_SIZE, "Prim:%d mOhms, Sec:%d mOhms\n", + tfa98xx->tfa->mohm[0], tfa98xx->tfa->mohm[1]); + } else { + ret = snprintf(str, PAGE_SIZE, "Prim:%d mOhms\n", + tfa98xx->tfa->mohm[0]); + } + + pr_debug("[0x%x] calib_done: %s", tfa98xx->i2c->addr, str); + + if (ret < 0) + goto r_err; + + ret = simple_read_from_buffer(user_buf, count, ppos, str, ret); + +r_err: + kfree(str); +r_c_err: + mutex_unlock(&tfa98xx->dsp_lock); + return ret; +} + +static ssize_t tfa98xx_dbgfs_version_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + char str[] = TFA98XX_VERSION "\n"; + int ret; + + ret = simple_read_from_buffer(user_buf, count, ppos, str, sizeof(str)); + + return ret; +} + +static ssize_t tfa98xx_dbgfs_dsp_state_get(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + struct i2c_client *i2c = file->private_data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + int ret = 0; + char *str; + + switch (tfa98xx->dsp_init) { + case TFA98XX_DSP_INIT_STOPPED: + str = "Stopped\n"; + break; + case TFA98XX_DSP_INIT_RECOVER: + str = "Recover requested\n"; + break; + case TFA98XX_DSP_INIT_FAIL: + str = "Failed init\n"; + break; + case TFA98XX_DSP_INIT_PENDING: + str = "Pending init\n"; + break; + case TFA98XX_DSP_INIT_DONE: + str = "Init complete\n"; + break; + default: + str = "Invalid\n"; + } + + pr_debug("[0x%x] dsp_state : %s\n", tfa98xx->i2c->addr, str); + + ret = simple_read_from_buffer(user_buf, count, ppos, str, strlen(str)); + return ret; +} + +static ssize_t tfa98xx_dbgfs_dsp_state_set(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct i2c_client *i2c = file->private_data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + enum tfa_error ret; + char buf[32]; + const char start_cmd[] = "start"; + const char stop_cmd[] = "stop"; + const char mon_start_cmd[] = "monitor start"; + const char mon_stop_cmd[] = "monitor stop"; + int buf_size; + + buf_size = min(count, (size_t)(sizeof(buf) - 1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + /* Compare strings, excluding the trailing \0 */ + if (!strncmp(buf, start_cmd, sizeof(start_cmd) - 1)) { + pr_info("[0x%x] Manual triggering of dsp start...\n", + tfa98xx->i2c->addr); + mutex_lock(&tfa98xx->dsp_lock); + ret = tfa98xx_tfa_start(tfa98xx, tfa98xx->profile, + tfa98xx->vstep); + mutex_unlock(&tfa98xx->dsp_lock); + pr_debug("[0x%x] tfa_dev_start complete: %d\n", + tfa98xx->i2c->addr, ret); + } else if (!strncmp(buf, stop_cmd, sizeof(stop_cmd) - 1)) { + pr_info("[0x%x] Manual triggering of dsp stop...\n", + tfa98xx->i2c->addr); + mutex_lock(&tfa98xx->dsp_lock); + ret = tfa_dev_stop(tfa98xx->tfa); + mutex_unlock(&tfa98xx->dsp_lock); + pr_debug("[0x%x] tfa_dev_stop complete: %d\n", + tfa98xx->i2c->addr, ret); + } else if (!strncmp(buf, mon_start_cmd, sizeof(mon_start_cmd) - 1)) { + pr_info("[0x%x] Manual start of monitor thread...\n", + tfa98xx->i2c->addr); + queue_delayed_work(tfa98xx->tfa98xx_wq, &tfa98xx->monitor_work, + HZ); + } else if (!strncmp(buf, mon_stop_cmd, sizeof(mon_stop_cmd) - 1)) { + pr_info("[0x%x] Manual stop of monitor thread...\n", + tfa98xx->i2c->addr); + cancel_delayed_work_sync(&tfa98xx->monitor_work); + } else { + return -EINVAL; + } + + return count; +} + +static ssize_t tfa98xx_dbgfs_fw_state_get(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + struct i2c_client *i2c = file->private_data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + char *str; + + switch (tfa98xx->dsp_fw_state) { + case TFA98XX_DSP_FW_NONE: + str = "None\n"; + break; + case TFA98XX_DSP_FW_PENDING: + str = "Pending\n"; + break; + case TFA98XX_DSP_FW_FAIL: + str = "Fail\n"; + break; + case TFA98XX_DSP_FW_OK: + str = "Ok\n"; + break; + default: + str = "Invalid\n"; + } + + pr_debug("[0x%x] fw_state : %s", tfa98xx->i2c->addr, str); + + return simple_read_from_buffer(user_buf, count, ppos, str, strlen(str)); +} + +#ifdef TFA_NON_DSP_SOLUTION +extern int send_tfa_cal_apr(void *buf, int cmd_size, bool bRead); +#else +int send_tfa_cal_apr(void *buf, int cmd_size, bool bRead) +{ + return 0; +} +#endif + +static ssize_t tfa98xx_dbgfs_rpc_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct i2c_client *i2c = file->private_data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + int ret = 0; + uint8_t *buffer; + enum Tfa98xx_Error error; + + if (tfa98xx->tfa == NULL) { + pr_debug("[0x%x] dsp is not available\n", tfa98xx->i2c->addr); + return -ENODEV; + } + + if (count == 0) + return 0; + + buffer = kmalloc(count, GFP_KERNEL); + if (buffer == NULL) { + pr_debug("[0x%x] can not allocate memory\n", + tfa98xx->i2c->addr); + return -ENOMEM; + } + + mutex_lock(&tfa98xx->dsp_lock); + + if (tfa98xx->tfa->is_probus_device) { + error = send_tfa_cal_apr(buffer, count, true); + } else { + error = dsp_msg_read(tfa98xx->tfa, count, buffer); + } + mutex_unlock(&tfa98xx->dsp_lock); + if (error != Tfa98xx_Error_Ok) { + pr_debug("[0x%x] dsp_msg_read error: %d\n", tfa98xx->i2c->addr, + error); + kfree(buffer); + return -EFAULT; + } + + ret = copy_to_user(user_buf, buffer, count); + kfree(buffer); + if (ret) + return -EFAULT; + + *ppos += count; + return count; +} + +static ssize_t tfa98xx_dbgfs_rpc_send(struct file *file, + const char __user *user_buf, size_t count, + loff_t *ppos) +{ + struct i2c_client *i2c = file->private_data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + nxpTfaFileDsc_t *msg_file; + enum Tfa98xx_Error error; + int err = 0; + + if (tfa98xx->tfa == NULL) { + pr_debug("[0x%x] dsp is not available\n", tfa98xx->i2c->addr); + return -ENODEV; + } + + if (count == 0) + return 0; + + /* msg_file.name is not used */ + msg_file = kmalloc(count + sizeof(nxpTfaFileDsc_t), GFP_KERNEL); + if (msg_file == NULL) { + pr_debug("[0x%x] can not allocate memory\n", + tfa98xx->i2c->addr); + return -ENOMEM; + } + + msg_file->size = count; + if (copy_from_user(msg_file->data, user_buf, count)) + return -EFAULT; + + if (tfa98xx->tfa->is_probus_device) { + mutex_lock(&tfa98xx->dsp_lock); + error = send_tfa_cal_apr(msg_file->data, msg_file->size, false); + if (error != Tfa98xx_Error_Ok) { + pr_debug("[0x%x] dsp_msg error: %d\n", + tfa98xx->i2c->addr, error); + err = -EIO; + } + mutex_unlock(&tfa98xx->dsp_lock); + + mdelay(2); + } else { + mutex_lock(&tfa98xx->dsp_lock); + + if ((msg_file->data[0] == 'M') && (msg_file->data[1] == 'G')) { + error = tfaContWriteFile( + tfa98xx->tfa, msg_file, 0, + 0); /* int vstep_idx, int vstep_msg_idx both 0 */ + if (error != Tfa98xx_Error_Ok) { + pr_debug("[0x%x] tfaContWriteFile error: %d\n", + tfa98xx->i2c->addr, error); + err = -EIO; + } + } else { + error = dsp_msg(tfa98xx->tfa, msg_file->size, + msg_file->data); + if (error != Tfa98xx_Error_Ok) { + pr_debug("[0x%x] dsp_msg error: %d\n", + tfa98xx->i2c->addr, error); + err = -EIO; + } + } + mutex_unlock(&tfa98xx->dsp_lock); + } + + kfree(msg_file); + + if (err) + return err; + return count; +} +/* -- RPC */ + +static int tfa98xx_dbgfs_pga_gain_get(void *data, u64 *val) +{ + struct i2c_client *i2c = (struct i2c_client *)data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + unsigned int value; + + value = tfa_get_pga_gain(tfa98xx->tfa); + if (value < 0) + return -EINVAL; + + *val = value; + return 0; +} + +static int tfa98xx_dbgfs_pga_gain_set(void *data, u64 val) +{ + struct i2c_client *i2c = (struct i2c_client *)data; + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + uint16_t value; + int err; + + value = val & 0xffff; + if (value > 7) + return -EINVAL; + + err = tfa_set_pga_gain(tfa98xx->tfa, value); + if (err < 0) + return -EINVAL; + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(tfa98xx_dbgfs_calib_otc_fops, tfa98xx_dbgfs_otc_get, + tfa98xx_dbgfs_otc_set, "%llu\n"); +DEFINE_SIMPLE_ATTRIBUTE(tfa98xx_dbgfs_calib_mtpex_fops, tfa98xx_dbgfs_mtpex_get, + tfa98xx_dbgfs_mtpex_set, "%llu\n"); +DEFINE_SIMPLE_ATTRIBUTE(tfa98xx_dbgfs_calib_temp_fops, tfa98xx_dbgfs_temp_get, + tfa98xx_dbgfs_temp_set, "%llu\n"); + +DEFINE_SIMPLE_ATTRIBUTE(tfa98xx_dbgfs_pga_gain_fops, tfa98xx_dbgfs_pga_gain_get, + tfa98xx_dbgfs_pga_gain_set, "%llu\n"); + +static const struct file_operations tfa98xx_dbgfs_calib_start_fops = { + .open = simple_open, + .write = tfa98xx_dbgfs_start_set, + .llseek = default_llseek, +}; + +static const struct file_operations tfa98xx_dbgfs_r_fops = { + .open = simple_open, + .read = tfa98xx_dbgfs_r_read, + .llseek = default_llseek, +}; + +static const struct file_operations tfa98xx_dbgfs_version_fops = { + .open = simple_open, + .read = tfa98xx_dbgfs_version_read, + .llseek = default_llseek, +}; + +static const struct file_operations tfa98xx_dbgfs_dsp_state_fops = { + .open = simple_open, + .read = tfa98xx_dbgfs_dsp_state_get, + .write = tfa98xx_dbgfs_dsp_state_set, + .llseek = default_llseek, +}; + +static const struct file_operations tfa98xx_dbgfs_fw_state_fops = { + .open = simple_open, + .read = tfa98xx_dbgfs_fw_state_get, + .llseek = default_llseek, +}; + +static const struct file_operations tfa98xx_dbgfs_rpc_fops = { + .open = simple_open, + .read = tfa98xx_dbgfs_rpc_read, + .write = tfa98xx_dbgfs_rpc_send, + .llseek = default_llseek, +}; + +static void tfa98xx_debug_init(struct tfa98xx *tfa98xx, struct i2c_client *i2c) +{ + char name[50]; + + scnprintf(name, MAX_CONTROL_NAME, "%s-%x", i2c->name, i2c->addr); + tfa98xx->dbg_dir = debugfs_create_dir(name, NULL); + debugfs_create_file("OTC", S_IRUGO | S_IWUGO, tfa98xx->dbg_dir, i2c, + &tfa98xx_dbgfs_calib_otc_fops); + debugfs_create_file("MTPEX", S_IRUGO | S_IWUGO, tfa98xx->dbg_dir, i2c, + &tfa98xx_dbgfs_calib_mtpex_fops); + debugfs_create_file("TEMP", S_IRUGO | S_IWUGO, tfa98xx->dbg_dir, i2c, + &tfa98xx_dbgfs_calib_temp_fops); + debugfs_create_file("calibrate", S_IRUGO | S_IWUGO, tfa98xx->dbg_dir, + i2c, &tfa98xx_dbgfs_calib_start_fops); + debugfs_create_file("R", S_IRUGO, tfa98xx->dbg_dir, i2c, + &tfa98xx_dbgfs_r_fops); + debugfs_create_file("version", S_IRUGO, tfa98xx->dbg_dir, i2c, + &tfa98xx_dbgfs_version_fops); + debugfs_create_file("dsp-state", S_IRUGO | S_IWUGO, tfa98xx->dbg_dir, + i2c, &tfa98xx_dbgfs_dsp_state_fops); + debugfs_create_file("fw-state", S_IRUGO | S_IWUGO, tfa98xx->dbg_dir, + i2c, &tfa98xx_dbgfs_fw_state_fops); + debugfs_create_file("rpc", S_IRUGO | S_IWUGO, tfa98xx->dbg_dir, i2c, + &tfa98xx_dbgfs_rpc_fops); + + if (tfa98xx->flags & TFA98XX_FLAG_SAAM_AVAILABLE) { + dev_dbg(tfa98xx->dev, "Adding pga_gain debug interface\n"); + debugfs_create_file("pga_gain", S_IRUGO, tfa98xx->dbg_dir, + tfa98xx->i2c, &tfa98xx_dbgfs_pga_gain_fops); + } +} + +static void tfa98xx_debug_remove(struct tfa98xx *tfa98xx) +{ + if (tfa98xx->dbg_dir) + debugfs_remove_recursive(tfa98xx->dbg_dir); +} +#endif + +/* copies the profile basename (i.e. part until .) into buf */ +static void get_profile_basename(char *buf, char *profile) +{ + int cp_len = 0, idx = 0; + char *pch; + + pch = strchr(profile, '.'); + idx = pch - profile; + cp_len = (pch != NULL) ? idx : (int)strlen(profile); + memcpy(buf, profile, cp_len); + buf[cp_len] = 0; +} + +/* return the profile name accociated with id from the profile list */ +static int get_profile_from_list(char *buf, int id) +{ + struct tfa98xx_baseprofile *bprof; + + list_for_each_entry (bprof, &profile_list, list) { + if (bprof->item_id == id) { + strcpy(buf, bprof->basename); + return 0; + } + } + + return -1; +} + +/* search for the profile in the profile list */ +static int is_profile_in_list(char *profile, int len) +{ + struct tfa98xx_baseprofile *bprof; + + list_for_each_entry (bprof, &profile_list, list) { + if ((len == bprof->len) && + (0 == strncmp(bprof->basename, profile, len))) + return 1; + } + + return 0; +} + +/* + * for the profile with id, look if the requested samplerate is + * supported, if found return the (container)profile for this + * samplerate, on error or if not found return -1 + */ +static int get_profile_id_for_sr(int id, unsigned int rate) +{ + int idx = 0; + struct tfa98xx_baseprofile *bprof; + + list_for_each_entry (bprof, &profile_list, list) { + if (id == bprof->item_id) { + idx = tfa98xx_get_fssel(rate); + if (idx < 0) { + /* samplerate not supported */ + return -1; + } + + return bprof->sr_rate_sup[idx]; + } + } + + /* profile not found */ + return -1; +} + +static int get_profile_id_by_name(char *profile, int len) +{ + struct tfa98xx_baseprofile *bprof; + int prof_index = -1; + + list_for_each_entry (bprof, &profile_list, list) { + if (strncmp(profile, bprof->basename, len) == 0) { + prof_index = bprof->item_id; + break; + } + } + + return prof_index; +} + +/* check if this profile is a calibration profile */ +static int is_calibration_profile(char *profile) +{ + if (strstr(profile, ".cal") != NULL) + return 1; + return 0; +} + +/* + * adds the (container)profile index of the samplerate found in + * the (container)profile to a fixed samplerate table in the (mixer)profile + */ +static int add_sr_to_profile(struct tfa98xx *tfa98xx, char *basename, int len, + int profile) +{ + struct tfa98xx_baseprofile *bprof; + int idx = 0; + unsigned int sr = 0; + + list_for_each_entry (bprof, &profile_list, list) { + if ((len == bprof->len) && + (0 == strncmp(bprof->basename, basename, len))) { + /* add supported samplerate for this profile */ + sr = tfa98xx_get_profile_sr(tfa98xx->tfa, profile); + if (!sr) { + pr_err("unable to identify supported sample rate for %s\n", + bprof->basename); + return -1; + } + + /* get the index for this samplerate */ + idx = tfa98xx_get_fssel(sr); + if (idx < 0 || idx >= TFA98XX_NUM_RATES) { + pr_err("invalid index for samplerate %d\n", + idx); + return -1; + } + + /* enter the (container)profile for this samplerate at the corresponding index */ + bprof->sr_rate_sup[idx] = profile; + + pr_debug( + "added profile:samplerate = [%d:%d] for mixer profile: %s\n", + profile, sr, bprof->basename); + } + } + + return 0; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0) +static struct snd_soc_codec * +snd_soc_kcontrol_codec(struct snd_kcontrol *kcontrol) +{ + return snd_kcontrol_chip(kcontrol); +} +#endif + +static int tfa98xx_get_vstep(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + int mixer_profile = kcontrol->private_value; + int ret = 0; + int profile; + + profile = get_profile_id_for_sr(mixer_profile, tfa98xx->rate); + if (profile < 0) { + pr_err("tfa98xx: tfa98xx_get_vstep: invalid profile %d (mixer_profile=%d, rate=%d)\n", + profile, mixer_profile, tfa98xx->rate); + return -EINVAL; + } + + mutex_lock(&tfa98xx_mutex); + list_for_each_entry (tfa98xx, &tfa98xx_device_list, list) { + int vstep = tfa98xx->prof_vsteps[profile]; + + ucontrol->value.integer.value[tfa98xx->tfa->dev_idx] = + tfacont_get_max_vstep(tfa98xx->tfa, profile) - vstep - + 1; + } + mutex_unlock(&tfa98xx_mutex); + + return ret; +} + +static int tfa98xx_set_vstep(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + int mixer_profile = kcontrol->private_value; + int profile; + int err = 0; + int change = 0; + + pr_debug("%s no_start=%d\n", __func__, no_start); + if (no_start != 0) + return 0; + + profile = get_profile_id_for_sr(mixer_profile, tfa98xx->rate); + if (profile < 0) { + pr_err("tfa98xx: tfa98xx_set_vstep: invalid profile %d (mixer_profile=%d, rate=%d)\n", + profile, mixer_profile, tfa98xx->rate); + return -EINVAL; + } + + mutex_lock(&tfa98xx_mutex); + list_for_each_entry (tfa98xx, &tfa98xx_device_list, list) { + int vstep, vsteps; + int ready = 0; + int new_vstep; + int value = + ucontrol->value.integer.value[tfa98xx->tfa->dev_idx]; + + vstep = tfa98xx->prof_vsteps[profile]; + vsteps = tfacont_get_max_vstep(tfa98xx->tfa, profile); + + if (vstep == vsteps - value - 1) + continue; + + new_vstep = vsteps - value - 1; + + if (new_vstep < 0) + new_vstep = 0; + + tfa98xx->prof_vsteps[profile] = new_vstep; + +#ifndef TFA98XX_ALSA_CTRL_PROF_CHG_ON_VOL + if (profile == tfa98xx->profile) { +#endif + /* this is the active profile, program the new vstep */ + tfa98xx->vstep = new_vstep; + mutex_lock(&tfa98xx->dsp_lock); + tfa98xx_dsp_system_stable(tfa98xx->tfa, &ready); + + if (ready) { + err = tfa98xx_tfa_start(tfa98xx, + tfa98xx->profile, + tfa98xx->vstep); + if (err) { + pr_err("Write vstep error: %d\n", err); + } else { + pr_debug( + "Succesfully changed vstep index!\n"); + change = 1; + } + } + + mutex_unlock(&tfa98xx->dsp_lock); +#ifndef TFA98XX_ALSA_CTRL_PROF_CHG_ON_VOL + } +#endif + pr_debug("%d: vstep:%d, (control value: %d) - profile %d\n", + tfa98xx->tfa->dev_idx, new_vstep, value, profile); + } + + if (change) { + list_for_each_entry (tfa98xx, &tfa98xx_device_list, list) { + mutex_lock(&tfa98xx->dsp_lock); + tfa_dev_set_state(tfa98xx->tfa, TFA_STATE_UNMUTE, 0); + mutex_unlock(&tfa98xx->dsp_lock); + } + } + + mutex_unlock(&tfa98xx_mutex); + + return change; +} + +static int tfa98xx_info_vstep(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + + int mixer_profile = tfa98xx_mixer_profile; + int profile = get_profile_id_for_sr(mixer_profile, tfa98xx->rate); + if (profile < 0) { + pr_err("tfa98xx: tfa98xx_info_vstep: invalid profile %d (mixer_profile=%d, rate=%d)\n", + profile, mixer_profile, tfa98xx->rate); + return -EINVAL; + } + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + mutex_lock(&tfa98xx_mutex); + uinfo->count = tfa98xx_device_count; + mutex_unlock(&tfa98xx_mutex); + uinfo->value.integer.min = 0; + uinfo->value.integer.max = + max(0, tfacont_get_max_vstep(tfa98xx->tfa, profile) - 1); + pr_debug("vsteps count: %d [prof=%d]\n", + tfacont_get_max_vstep(tfa98xx->tfa, profile), profile); + return 0; +} + +static int tfa98xx_get_profile(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + mutex_lock(&tfa98xx_mutex); + ucontrol->value.integer.value[0] = tfa98xx_mixer_profile; + mutex_unlock(&tfa98xx_mutex); + + return 0; +} + +static int tfa98xx_set_profile(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + int change = 0; + int new_profile; + int prof_idx; + int profile_count = tfa98xx_mixer_profiles; + int profile = tfa98xx_mixer_profile; + + if (no_start != 0) + return 0; + + new_profile = ucontrol->value.integer.value[0]; + if (new_profile == profile) + return 0; + + if ((new_profile < 0) || (new_profile >= profile_count)) { + pr_err("not existing profile (%d)\n", new_profile); + return -EINVAL; + } + + /* get the container profile for the requested sample rate */ + prof_idx = get_profile_id_for_sr(new_profile, tfa98xx->rate); + if (prof_idx < 0) { + pr_err("tfa98xx: sample rate [%d] not supported for this mixer profile [%d].\n", + tfa98xx->rate, new_profile); + return 0; + } + pr_debug("selected container profile [%d]\n", prof_idx); + + /* update mixer profile */ + tfa98xx_mixer_profile = new_profile; + + /* modified by jiangtao.zeng begin. */ + /* we are updating profile index only if the device is not in operating mode, and will be start in tfa98xx_mute() later. + if the device in operating mode, we will apply new profile now. */ + mutex_lock(&tfa98xx_mutex); + list_for_each_entry (tfa98xx, &tfa98xx_device_list, list) { + int err; + int ready = 0; + + /* update 'real' profile (container profile) */ + tfa98xx->profile = prof_idx; + tfa98xx->vstep = tfa98xx->prof_vsteps[prof_idx]; + if (!tfa98xx->tfa->is_probus_device) { + /* Don't call tfa_dev_start() if there is no clock. */ + mutex_lock(&tfa98xx->dsp_lock); + tfa98xx_dsp_system_stable(tfa98xx->tfa, &ready); + if (ready && (tfa_dev_get_state(tfa98xx->tfa) == + TFA_STATE_OPERATING)) { + /* Also re-enables the interrupts */ + err = tfa98xx_tfa_start(tfa98xx, prof_idx, + tfa98xx->vstep); + if (err) { + pr_info("Write profile error: %d\n", + err); + } else { + pr_debug( + "Changed to profile %d (vstep = %d)\n", + prof_idx, tfa98xx->vstep); + change = 1; + } + } + mutex_unlock(&tfa98xx->dsp_lock); + /* Flag DSP as invalidated as the profile change may invalidate the + * current DSP configuration. That way, further stream start can + * trigger a tfa_dev_start. + */ + tfa98xx->dsp_init = TFA98XX_DSP_INIT_INVALIDATED; + } + } + + if (change) { + list_for_each_entry (tfa98xx, &tfa98xx_device_list, list) { + mutex_lock(&tfa98xx->dsp_lock); + tfa_dev_set_state(tfa98xx->tfa, TFA_STATE_UNMUTE, 0); + mutex_unlock(&tfa98xx->dsp_lock); + } + } + + mutex_unlock(&tfa98xx_mutex); + + /* modified by jiangtao.zeng end. */ + + return change; +} + +static int tfa98xx_info_profile(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + char profile_name[MAX_CONTROL_NAME] = { 0 }; + int count = tfa98xx_mixer_profiles, err = -1; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = count; + + if (uinfo->value.enumerated.item >= count) + uinfo->value.enumerated.item = count - 1; + + err = get_profile_from_list(profile_name, uinfo->value.enumerated.item); + if (err != 0) + return -EINVAL; + + strcpy(uinfo->value.enumerated.name, profile_name); + + return 0; +} + +static int tfa98xx_info_stop_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + mutex_lock(&tfa98xx_mutex); + uinfo->count = tfa98xx_device_count; + mutex_unlock(&tfa98xx_mutex); + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + + return 0; +} + +static int tfa98xx_get_stop_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tfa98xx *tfa98xx; + + mutex_lock(&tfa98xx_mutex); + list_for_each_entry (tfa98xx, &tfa98xx_device_list, list) { + ucontrol->value.integer.value[tfa98xx->tfa->dev_idx] = 0; + } + mutex_unlock(&tfa98xx_mutex); + + return 0; +} + +static int tfa98xx_set_stop_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tfa98xx *tfa98xx; + + mutex_lock(&tfa98xx_mutex); + list_for_each_entry (tfa98xx, &tfa98xx_device_list, list) { + int ready = 0; + int i = tfa98xx->tfa->dev_idx; + + pr_debug("%d: %ld\n", i, ucontrol->value.integer.value[i]); + + tfa98xx_dsp_system_stable(tfa98xx->tfa, &ready); + + if ((ucontrol->value.integer.value[i] != 0) && ready) { + cancel_delayed_work_sync(&tfa98xx->monitor_work); + + cancel_delayed_work_sync(&tfa98xx->init_work); + if (tfa98xx->dsp_fw_state != TFA98XX_DSP_FW_OK) + continue; + + mutex_lock(&tfa98xx->dsp_lock); + tfa_dev_stop(tfa98xx->tfa); + tfa98xx->dsp_init = TFA98XX_DSP_INIT_STOPPED; + mutex_unlock(&tfa98xx->dsp_lock); + } + + ucontrol->value.integer.value[i] = 0; + } + mutex_unlock(&tfa98xx_mutex); + + return 1; +} + +static int tfa98xx_info_PAmute(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + mutex_lock(&tfa98xx_mutex); + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = tfa98xx_device_count; + uinfo->value.integer.min = TFA98XX_DEVICE_MUTE_OFF; + uinfo->value.integer.max = TFA98XX_DEVICE_MUTE_ON; + mutex_unlock(&tfa98xx_mutex); + + return 0; +} + +static int tfa98xx_get_PAmute(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tfa98xx *tfa98xx = NULL; + + mutex_lock(&tfa98xx_mutex); + list_for_each_entry (tfa98xx, &tfa98xx_device_list, list) { + ucontrol->value.integer.value[tfa98xx->tfa->dev_idx] = + tfa98xx->tfa_mute_mode; + } + mutex_unlock(&tfa98xx_mutex); + + return 0; +} + +static int tfa98xx_set_PAmute(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tfa98xx *tfa98xx = NULL; + + mutex_lock(&tfa98xx_mutex); + list_for_each_entry (tfa98xx, &tfa98xx_device_list, list) { + if (ucontrol->value.integer.value[tfa98xx->tfa->dev_idx] != + TFA98XX_DEVICE_MUTE_OFF) { + tfa98xx->tfa_mute_mode = TFA98XX_DEVICE_MUTE_ON; + } else { + tfa98xx->tfa_mute_mode = TFA98XX_DEVICE_MUTE_OFF; + } + } + mutex_unlock(&tfa98xx_mutex); + + return 1; +} + +static int tfa98xx_info_cal_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + mutex_lock(&tfa98xx_mutex); + uinfo->count = tfa98xx_device_count; + mutex_unlock(&tfa98xx_mutex); + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0xffff; /* 16 bit value */ + + return 0; +} + +static int tfa98xx_set_cal_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tfa98xx *tfa98xx; + + mutex_lock(&tfa98xx_mutex); + list_for_each_entry (tfa98xx, &tfa98xx_device_list, list) { + enum tfa_error err; + int i = tfa98xx->tfa->dev_idx; + + tfa98xx->cal_data = (uint16_t)ucontrol->value.integer.value[i]; + + mutex_lock(&tfa98xx->dsp_lock); + err = tfa98xx_write_re25(tfa98xx->tfa, tfa98xx->cal_data); + tfa98xx->set_mtp_cal = (err != tfa_error_ok); + if (tfa98xx->set_mtp_cal == false) { + pr_info("Calibration value (%d) set in mtp\n", + tfa98xx->cal_data); + } + mutex_unlock(&tfa98xx->dsp_lock); + } + mutex_unlock(&tfa98xx_mutex); + + return 1; +} + +static int tfa98xx_get_cal_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tfa98xx *tfa98xx; + + mutex_lock(&tfa98xx_mutex); + list_for_each_entry (tfa98xx, &tfa98xx_device_list, list) { + mutex_lock(&tfa98xx->dsp_lock); + ucontrol->value.integer.value[tfa98xx->tfa->dev_idx] = + tfa_dev_mtp_get(tfa98xx->tfa, TFA_MTP_RE25_PRIM); + mutex_unlock(&tfa98xx->dsp_lock); + } + mutex_unlock(&tfa98xx_mutex); + + return 0; +} + +#ifdef TFA_NON_DSP_SOLUTION +static atomic_t g_bypass; +static atomic_t g_Tx_enable; +extern int send_tfa_cal_set_bypass(void *buf, int cmd_size); +extern int send_tfa_cal_set_tx_enable(void *buf, int cmd_size); + +/*************bypass control***************/ +static int tfa987x_algo_get_status(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int32_t ret = 0; + ucontrol->value.integer.value[0] = atomic_read(&g_bypass); + return ret; +} + +static int tfa987x_algo_set_status(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int32_t ret = 0; + u8 buff[56] = { 0 }, *ptr = buff; + ((int32_t *)buff)[0] = ucontrol->value.integer.value[0]; + pr_err("%s:status data %d\n", __func__, ((int32_t *)buff)[0]); + atomic_set(&g_bypass, ((int32_t *)buff)[0]); + ret = send_tfa_cal_set_bypass(ptr, 4); + return ret; +} + +static int tfa987x_algo_set_tx_enable(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int32_t ret = 0; + u8 buff[56] = { 0 }, *ptr = buff; + ((int32_t *)buff)[0] = ucontrol->value.integer.value[0]; + pr_err("%s:set_tx_enable %d\n", __func__, ((int32_t *)buff)[0]); + atomic_set(&g_Tx_enable, ((int32_t *)buff)[0]); + ret = send_tfa_cal_set_tx_enable(ptr, 4); + return ret; +} + +static int tfa987x_algo_get_tx_status(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int32_t ret = 0; + ucontrol->value.integer.value[0] = atomic_read(&g_Tx_enable); + return ret; +} + +static const char *tfa987x_algo_text[] = { "DISABLE", "ENABLE" }; + +static const char *tfa987x_tx_text[] = { "DISABLE", "ENABLE" }; + +static const struct soc_enum tfa987x_algo_enum[] = { SOC_ENUM_SINGLE_EXT( + ARRAY_SIZE(tfa987x_algo_text), tfa987x_algo_text) }; + +static const struct soc_enum tfa987x_tx_enum[] = { SOC_ENUM_SINGLE_EXT( + ARRAY_SIZE(tfa987x_tx_text), tfa987x_tx_text) }; + +const struct snd_kcontrol_new tfa987x_algo_controls[] = { + SOC_ENUM_EXT("TFA987X_ALGO_STATUS", tfa987x_algo_enum[0], + tfa987x_algo_get_status, tfa987x_algo_set_status), + SOC_ENUM_EXT("TFA987X_TX_ENABLE", tfa987x_tx_enum[0], + tfa987x_algo_get_tx_status, tfa987x_algo_set_tx_enable) +}; +#endif + +static int tfa98xx_create_controls(struct tfa98xx *tfa98xx) +{ + int prof, nprof, mix_index = 0; + int nr_controls = 0, id = 0; + char *name; + struct tfa98xx_baseprofile *bprofile; + int ret = 0; + + /* Create the following controls: + * - enum control to select the active profile + * - one volume control for each profile hosting a vstep + * - Stop control on TFA1 devices + */ + + nr_controls = 2; /* Profile and stop control */ + + if (tfa98xx->flags & TFA98XX_FLAG_CALIBRATION_CTL) + nr_controls += 1; /* calibration */ + + /* allocate the tfa98xx_controls base on the nr of profiles */ + nprof = tfa_cnt_get_dev_nprof(tfa98xx->tfa); + for (prof = 0; prof < nprof; prof++) { + if (tfacont_get_max_vstep(tfa98xx->tfa, prof)) + nr_controls++; /* Playback Volume control */ + } + if (tfa98xx->tfa->tfa_family == 2) { + nr_controls++; /* Playback Volume control */ + } + + tfa98xx_controls = + devm_kzalloc(tfa98xx->codec->dev, + nr_controls * sizeof(tfa98xx_controls[0]), + GFP_KERNEL); + if (!tfa98xx_controls) + return -ENOMEM; + + /* Create a mixer item for selecting the active profile */ + name = devm_kzalloc(tfa98xx->codec->dev, MAX_CONTROL_NAME, GFP_KERNEL); + if (!name) + return -ENOMEM; + scnprintf(name, MAX_CONTROL_NAME, "%s Profile", tfa98xx->fw.name); + tfa98xx_controls[mix_index].name = name; + tfa98xx_controls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + tfa98xx_controls[mix_index].info = tfa98xx_info_profile; + tfa98xx_controls[mix_index].get = tfa98xx_get_profile; + tfa98xx_controls[mix_index].put = tfa98xx_set_profile; + // tfa98xx_controls[mix_index].private_value = profs; /* save number of profiles */ + mix_index++; + /* add new mixer control item 'SmartPA Mute' for MAX2 device. */ + if (tfa98xx->tfa->tfa_family == 2) { + tfa98xx_controls[mix_index].name = "SmartPA Mute"; + tfa98xx_controls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + tfa98xx_controls[mix_index].info = tfa98xx_info_PAmute; + tfa98xx_controls[mix_index].get = tfa98xx_get_PAmute; + tfa98xx_controls[mix_index].put = tfa98xx_set_PAmute; + mix_index++; + } + + /* create mixer items for each profile that has volume */ + for (prof = 0; prof < nprof; prof++) { + /* create an new empty profile */ + bprofile = devm_kzalloc(tfa98xx->codec->dev, sizeof(*bprofile), + GFP_KERNEL); + if (!bprofile) + return -ENOMEM; + + bprofile->len = 0; + bprofile->item_id = -1; + INIT_LIST_HEAD(&bprofile->list); + + /* copy profile name into basename until the . */ + get_profile_basename(bprofile->basename, + tfa_cont_profile_name(tfa98xx, prof)); + bprofile->len = strlen(bprofile->basename); + + /* + * search the profile list for a profile with basename, if it is not found then + * add it to the list and add a new mixer control (if it has vsteps) + * also, if it is a calibration profile, do not add it to the list + */ + if ((is_profile_in_list(bprofile->basename, bprofile->len) == + 0) && + is_calibration_profile( + tfa_cont_profile_name(tfa98xx, prof)) == 0) { + /* the profile is not present, add it to the list */ + list_add(&bprofile->list, &profile_list); + bprofile->item_id = id++; + + pr_debug("profile added [%d]: %s\n", bprofile->item_id, + bprofile->basename); + + if (tfacont_get_max_vstep(tfa98xx->tfa, prof)) { + name = devm_kzalloc(tfa98xx->codec->dev, + MAX_CONTROL_NAME, + GFP_KERNEL); + if (!name) + return -ENOMEM; + + scnprintf(name, MAX_CONTROL_NAME, + "%s %s Playback Volume", + tfa98xx->fw.name, bprofile->basename); + + tfa98xx_controls[mix_index].name = name; + tfa98xx_controls[mix_index].iface = + SNDRV_CTL_ELEM_IFACE_MIXER; + tfa98xx_controls[mix_index].info = + tfa98xx_info_vstep; + tfa98xx_controls[mix_index].get = + tfa98xx_get_vstep; + tfa98xx_controls[mix_index].put = + tfa98xx_set_vstep; + tfa98xx_controls[mix_index].private_value = + bprofile->item_id; /* save profile index */ + mix_index++; + } + } + + /* look for the basename profile in the list of mixer profiles and add the + container profile index to the supported samplerates of this mixer profile */ + add_sr_to_profile(tfa98xx, bprofile->basename, bprofile->len, + prof); + } + + /* set the number of user selectable profiles in the mixer */ + tfa98xx_mixer_profiles = id; + + /* Create a mixer item for stop control on TFA1 */ + name = devm_kzalloc(tfa98xx->codec->dev, MAX_CONTROL_NAME, GFP_KERNEL); + if (!name) + return -ENOMEM; + + scnprintf(name, MAX_CONTROL_NAME, "%s Stop", tfa98xx->fw.name); + tfa98xx_controls[mix_index].name = name; + tfa98xx_controls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + tfa98xx_controls[mix_index].info = tfa98xx_info_stop_ctl; + tfa98xx_controls[mix_index].get = tfa98xx_get_stop_ctl; + tfa98xx_controls[mix_index].put = tfa98xx_set_stop_ctl; + mix_index++; + + if (tfa98xx->flags & TFA98XX_FLAG_CALIBRATION_CTL) { + name = devm_kzalloc(tfa98xx->codec->dev, MAX_CONTROL_NAME, + GFP_KERNEL); + if (!name) + return -ENOMEM; + + scnprintf(name, MAX_CONTROL_NAME, "%s Calibration", + tfa98xx->fw.name); + tfa98xx_controls[mix_index].name = name; + tfa98xx_controls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + tfa98xx_controls[mix_index].info = tfa98xx_info_cal_ctl; + tfa98xx_controls[mix_index].get = tfa98xx_get_cal_ctl; + tfa98xx_controls[mix_index].put = tfa98xx_set_cal_ctl; + mix_index++; + } + + ret = snd_soc_add_codec_controls(tfa98xx->codec, tfa98xx_controls, + mix_index); + pr_info("create tfa98xx_controls ret=%d", ret); + +#ifdef TFA_NON_DSP_SOLUTION + ret = snd_soc_add_codec_controls(tfa98xx->codec, tfa987x_algo_controls, + ARRAY_SIZE(tfa987x_algo_controls)); + pr_info("create tfa987x_algo_controls ret=%d", ret); +#endif + if (!ret) { + ret = snd_soc_add_codec_controls( + tfa98xx->codec, nxp_spk_id_controls, + ARRAY_SIZE(nxp_spk_id_controls)); + } + + return ret; +} + +static void *tfa98xx_devm_kstrdup(struct device *dev, char *buf) +{ + char *str = devm_kzalloc(dev, strlen(buf) + 1, GFP_KERNEL); + if (!str) + return str; + memcpy(str, buf, strlen(buf)); + return str; +} + +static int +tfa98xx_append_i2c_address(struct device *dev, struct i2c_client *i2c, + struct snd_soc_dapm_widget *widgets, int num_widgets, + struct snd_soc_dai_driver *dai_drv, int num_dai) +{ + char buf[50]; + int i; + int i2cbus = i2c->adapter->nr; + int addr = i2c->addr; + if (dai_drv && num_dai > 0) + for (i = 0; i < num_dai; i++) { + memset(buf, 0x00, sizeof(buf)); + snprintf(buf, 50, "%s-%x-%x", dai_drv[i].name, i2cbus, + addr); + dai_drv[i].name = tfa98xx_devm_kstrdup(dev, buf); + pr_info("tfa98xx_append_i2c_address() dai_drv[%d].name = [%s]\n", + i, dai_drv[i].name); + + memset(buf, 0x00, sizeof(buf)); + snprintf(buf, 50, "%s-%x-%x", + dai_drv[i].playback.stream_name, i2cbus, addr); + dai_drv[i].playback.stream_name = + tfa98xx_devm_kstrdup(dev, buf); + pr_info("tfa98xx_append_i2c_address() dai_drv[%d].playback.stream_name = [%s]\n", + i, dai_drv[i].playback.stream_name); + + memset(buf, 0x00, sizeof(buf)); + snprintf(buf, 50, "%s-%x-%x", + dai_drv[i].capture.stream_name, i2cbus, addr); + dai_drv[i].capture.stream_name = + tfa98xx_devm_kstrdup(dev, buf); + pr_info("tfa98xx_append_i2c_address() dai_drv[%d].capture.stream_name = [%s]\n", + i, dai_drv[i].capture.stream_name); + } + + /* the idea behind this is convert: + * SND_SOC_DAPM_AIF_IN("AIF IN", "AIF Playback", 0, SND_SOC_NOPM, 0, 0), + * into: + * SND_SOC_DAPM_AIF_IN("AIF IN", "AIF Playback-2-36", 0, SND_SOC_NOPM, 0, 0), + */ + if (widgets && num_widgets > 0) + for (i = 0; i < num_widgets; i++) { + if (!widgets[i].sname) + continue; + if ((widgets[i].id == snd_soc_dapm_aif_in) || + (widgets[i].id == snd_soc_dapm_aif_out)) { + snprintf(buf, 50, "%s-%x-%x", widgets[i].sname, + i2cbus, addr); + widgets[i].sname = + tfa98xx_devm_kstrdup(dev, buf); + } + } + + return 0; +} + +static struct snd_soc_dapm_widget tfa98xx_dapm_widgets_common[] = { + /* Stream widgets */ + SND_SOC_DAPM_AIF_IN("AIF IN", "AIF Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF OUT", "AIF Capture", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_OUTPUT("OUTL"), + SND_SOC_DAPM_INPUT("AEC Loopback"), +}; + +static struct snd_soc_dapm_widget tfa98xx_dapm_widgets_stereo[] = { + SND_SOC_DAPM_OUTPUT("OUTR"), +}; + +static struct snd_soc_dapm_widget tfa98xx_dapm_widgets_saam[] = { + SND_SOC_DAPM_INPUT("SAAM MIC"), +}; + +static struct snd_soc_dapm_widget tfa9888_dapm_inputs[] = { + SND_SOC_DAPM_INPUT("DMIC1"), + SND_SOC_DAPM_INPUT("DMIC2"), + SND_SOC_DAPM_INPUT("DMIC3"), + SND_SOC_DAPM_INPUT("DMIC4"), +}; + +static const struct snd_soc_dapm_route tfa98xx_dapm_routes_common[] = { + { "OUTL", NULL, "AIF IN" }, + { "AIF OUT", NULL, "AEC Loopback" }, +}; + +static const struct snd_soc_dapm_route tfa98xx_dapm_routes_saam[] = { + { "AIF OUT", NULL, "SAAM MIC" }, +}; + +static const struct snd_soc_dapm_route tfa98xx_dapm_routes_stereo[] = { + { "OUTR", NULL, "AIF IN" }, +}; + +static const struct snd_soc_dapm_route tfa9888_input_dapm_routes[] = { + { "AIF OUT", NULL, "DMIC1" }, + { "AIF OUT", NULL, "DMIC2" }, + { "AIF OUT", NULL, "DMIC3" }, + { "AIF OUT", NULL, "DMIC4" }, +}; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) +static struct snd_soc_dapm_context * +snd_soc_codec_get_dapm(struct snd_soc_codec *codec) +{ + return &codec->dapm; +} +#endif + +static void tfa98xx_add_widgets(struct tfa98xx *tfa98xx) +{ + struct snd_soc_dapm_context *dapm = + snd_soc_codec_get_dapm(tfa98xx->codec); + struct snd_soc_dapm_widget *widgets; + unsigned int num_dapm_widgets = ARRAY_SIZE(tfa98xx_dapm_widgets_common); + + widgets = devm_kzalloc(&tfa98xx->i2c->dev, + sizeof(struct snd_soc_dapm_widget) * + ARRAY_SIZE(tfa98xx_dapm_widgets_common), + GFP_KERNEL); + if (!widgets) + return; + memcpy(widgets, tfa98xx_dapm_widgets_common, + sizeof(struct snd_soc_dapm_widget) * + ARRAY_SIZE(tfa98xx_dapm_widgets_common)); + + tfa98xx_append_i2c_address(&tfa98xx->i2c->dev, tfa98xx->i2c, widgets, + num_dapm_widgets, NULL, 0); + + snd_soc_dapm_new_controls(dapm, widgets, + ARRAY_SIZE(tfa98xx_dapm_widgets_common)); + snd_soc_dapm_add_routes(dapm, tfa98xx_dapm_routes_common, + ARRAY_SIZE(tfa98xx_dapm_routes_common)); + + if (tfa98xx->flags & TFA98XX_FLAG_STEREO_DEVICE) { + snd_soc_dapm_new_controls( + dapm, tfa98xx_dapm_widgets_stereo, + ARRAY_SIZE(tfa98xx_dapm_widgets_stereo)); + snd_soc_dapm_add_routes(dapm, tfa98xx_dapm_routes_stereo, + ARRAY_SIZE(tfa98xx_dapm_routes_stereo)); + } + + if (tfa98xx->flags & TFA98XX_FLAG_MULTI_MIC_INPUTS) { + snd_soc_dapm_new_controls(dapm, tfa9888_dapm_inputs, + ARRAY_SIZE(tfa9888_dapm_inputs)); + snd_soc_dapm_add_routes(dapm, tfa9888_input_dapm_routes, + ARRAY_SIZE(tfa9888_input_dapm_routes)); + } + + if (tfa98xx->flags & TFA98XX_FLAG_SAAM_AVAILABLE) { + snd_soc_dapm_new_controls( + dapm, tfa98xx_dapm_widgets_saam, + ARRAY_SIZE(tfa98xx_dapm_widgets_saam)); + snd_soc_dapm_add_routes(dapm, tfa98xx_dapm_routes_saam, + ARRAY_SIZE(tfa98xx_dapm_routes_saam)); + } +} + +/* I2C wrapper functions */ +enum Tfa98xx_Error tfa98xx_write_register16(struct tfa_device *tfa, + unsigned char subaddress, + unsigned short value) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + struct tfa98xx *tfa98xx; + int ret; + int retries = I2C_RETRIES; + + if (tfa == NULL) { + pr_err("No device available\n"); + return Tfa98xx_Error_Fail; + } + + tfa98xx = (struct tfa98xx *)tfa->data; + if (!tfa98xx || !tfa98xx->regmap) { + pr_err("No tfa98xx regmap available\n"); + return Tfa98xx_Error_Bad_Parameter; + } +retry: + ret = regmap_write(tfa98xx->regmap, subaddress, value); + if (ret < 0) { + pr_warn("i2c error, retries left: %d\n", retries); + if (retries) { + retries--; + msleep(I2C_RETRY_DELAY); + goto retry; + } + return Tfa98xx_Error_Fail; + } + if (tfa98xx_kmsg_regs) + dev_dbg(&tfa98xx->i2c->dev, " WR reg=0x%02x, val=0x%04x %s\n", + subaddress, value, ret < 0 ? "Error!!" : ""); + + if (tfa98xx_ftrace_regs) + tfa98xx_trace_printk("\tWR reg=0x%02x, val=0x%04x %s\n", + subaddress, value, + ret < 0 ? "Error!!" : ""); + return error; +} + +enum Tfa98xx_Error tfa98xx_read_register16(struct tfa_device *tfa, + unsigned char subaddress, + unsigned short *val) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + struct tfa98xx *tfa98xx; + unsigned int value; + int retries = I2C_RETRIES; + int ret; + + if (tfa == NULL) { + pr_err("No device available\n"); + return Tfa98xx_Error_Fail; + } + + tfa98xx = (struct tfa98xx *)tfa->data; + if (!tfa98xx || !tfa98xx->regmap) { + pr_err("No tfa98xx regmap available\n"); + return Tfa98xx_Error_Bad_Parameter; + } +retry: + ret = regmap_read(tfa98xx->regmap, subaddress, &value); + if (ret < 0) { + pr_warn("i2c error at subaddress 0x%x, retries left: %d\n", + subaddress, retries); + if (retries) { + retries--; + msleep(I2C_RETRY_DELAY); + goto retry; + } + return Tfa98xx_Error_Fail; + } + *val = value & 0xffff; + + if (tfa98xx_kmsg_regs) + dev_dbg(&tfa98xx->i2c->dev, "RD reg=0x%02x, val=0x%04x %s\n", + subaddress, *val, ret < 0 ? "Error!!" : ""); + if (tfa98xx_ftrace_regs) + tfa98xx_trace_printk("\tRD reg=0x%02x, val=0x%04x %s\n", + subaddress, *val, + ret < 0 ? "Error!!" : ""); + + return error; +} + +/* + * init external dsp + */ +enum Tfa98xx_Error tfa98xx_init_dsp(struct tfa_device *tfa) +{ + return Tfa98xx_Error_Not_Supported; +} + +int tfa98xx_get_dsp_status(struct tfa_device *tfa) +{ + return 0; +} + +/* + * write external dsp message + */ +enum Tfa98xx_Error tfa98xx_write_dsp(struct tfa_device *tfa, int num_bytes, + const char *command_buffer) +{ + return Tfa98xx_Error_Not_Supported; +} + +/* + * read external dsp message + */ +enum Tfa98xx_Error tfa98xx_read_dsp(struct tfa_device *tfa, int num_bytes, + unsigned char *result_buffer) +{ + return Tfa98xx_Error_Not_Supported; +} +/* + * write/read external dsp message + */ +enum Tfa98xx_Error tfa98xx_writeread_dsp(struct tfa_device *tfa, + int command_length, + void *command_buffer, + int result_length, void *result_buffer) +{ + return Tfa98xx_Error_Not_Supported; +} + +enum Tfa98xx_Error tfa98xx_read_data(struct tfa_device *tfa, unsigned char reg, + int len, unsigned char value[]) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + struct tfa98xx *tfa98xx; + struct i2c_client *tfa98xx_client; + int err; + int tries = 0; + struct i2c_msg msgs[] = { + { + .flags = 0, + .len = 1, + .buf = ®, + }, + { + .flags = I2C_M_RD, + .len = len, + .buf = value, + }, + }; + + if (tfa == NULL) { + pr_err("No device available\n"); + return Tfa98xx_Error_Fail; + } + + tfa98xx = (struct tfa98xx *)tfa->data; + if (tfa98xx->i2c) { + tfa98xx_client = tfa98xx->i2c; + msgs[0].addr = tfa98xx_client->addr; + msgs[1].addr = tfa98xx_client->addr; + + do { + err = i2c_transfer(tfa98xx_client->adapter, msgs, + ARRAY_SIZE(msgs)); + if (err != ARRAY_SIZE(msgs)) + msleep_interruptible(I2C_RETRY_DELAY); + } while ((err != ARRAY_SIZE(msgs)) && (++tries < I2C_RETRIES)); + + if (err != ARRAY_SIZE(msgs)) { + dev_err(&tfa98xx_client->dev, + "read transfer error %d\n", err); + error = Tfa98xx_Error_Fail; + } + + if (tfa98xx_kmsg_regs) + dev_dbg(&tfa98xx_client->dev, + "RD-DAT reg=0x%02x, len=%d\n", reg, len); + if (tfa98xx_ftrace_regs) + tfa98xx_trace_printk("\t\tRD-DAT reg=0x%02x, len=%d\n", + reg, len); + } else { + pr_err("No device available\n"); + error = Tfa98xx_Error_Fail; + } + return error; +} + +enum Tfa98xx_Error tfa98xx_write_raw(struct tfa_device *tfa, int len, + const unsigned char data[]) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + struct tfa98xx *tfa98xx; + int ret; + int retries = I2C_RETRIES; + + if (tfa == NULL) { + pr_err("No device available\n"); + return Tfa98xx_Error_Fail; + } + + tfa98xx = (struct tfa98xx *)tfa->data; + +retry: + ret = i2c_master_send(tfa98xx->i2c, data, len); + if (ret < 0) { + pr_warn("i2c error, retries left: %d\n", retries); + if (retries) { + retries--; + msleep(I2C_RETRY_DELAY); + goto retry; + } + } + + if (ret == len) { + if (tfa98xx_kmsg_regs) + dev_dbg(&tfa98xx->i2c->dev, " WR-RAW len=%d\n", len); + if (tfa98xx_ftrace_regs) + tfa98xx_trace_printk("\t\tWR-RAW len=%d\n", len); + return Tfa98xx_Error_Ok; + } + pr_err(" WR-RAW (len=%d) Error I2C send size mismatch %d\n", len, ret); + error = Tfa98xx_Error_Fail; + + return error; +} + +/* Interrupts management */ + +static void tfa98xx_interrupt_enable_tfa2(struct tfa98xx *tfa98xx, bool enable) +{ + /* Only for 0x72 we need to enable NOCLK interrupts */ + if (tfa98xx->flags & TFA98XX_FLAG_REMOVE_PLOP_NOISE) + tfa_irq_ena(tfa98xx->tfa, tfa9912_irq_stnoclk, enable); + + if (tfa98xx->flags & TFA98XX_FLAG_LP_MODES) { + tfa_irq_ena(tfa98xx->tfa, 36, + enable); /* FIXME: IELP0 does not excist for 9912 */ + tfa_irq_ena(tfa98xx->tfa, tfa9912_irq_stclpr, enable); + } +} + +/* Check if tap-detection can and shall be enabled. + * Configure SPK interrupt accordingly or setup polling mode + * Tap-detection shall be active if: + * - the service is enabled (tapdet_open), AND + * - the current profile is a tap-detection profile + * On TFA1 familiy of devices, activating tap-detection means enabling the SPK + * interrupt if available. + * We also update the tapdet_enabled and tapdet_poll variables. + */ +static void tfa98xx_tapdet_check_update(struct tfa98xx *tfa98xx) +{ + unsigned int enable = false; + + /* Support tap-detection on TFA1 family of devices */ + if ((tfa98xx->flags & TFA98XX_FLAG_TAPDET_AVAILABLE) == 0) + return; + + if (tfa98xx->tapdet_open && + (tfa98xx->tapdet_profiles & (1 << tfa98xx->profile))) + enable = true; + + if (!gpio_is_valid(tfa98xx->irq_gpio)) { + /* interrupt not available, setup polling mode */ + tfa98xx->tapdet_poll = true; + if (enable) + queue_delayed_work(tfa98xx->tfa98xx_wq, + &tfa98xx->tapdet_work, HZ / 10); + else + cancel_delayed_work_sync(&tfa98xx->tapdet_work); + dev_dbg(tfa98xx->codec->dev, + "Polling for tap-detection: %s (%d; 0x%x, %d)\n", + enable ? "enabled" : "disabled", tfa98xx->tapdet_open, + tfa98xx->tapdet_profiles, tfa98xx->profile); + + } else { + dev_dbg(tfa98xx->codec->dev, + "Interrupt for tap-detection: %s (%d; 0x%x, %d)\n", + enable ? "enabled" : "disabled", tfa98xx->tapdet_open, + tfa98xx->tapdet_profiles, tfa98xx->profile); + /* enabled interrupt */ + tfa_irq_ena(tfa98xx->tfa, tfa9912_irq_sttapdet, enable); + } + + /* check disabled => enabled transition to clear pending events */ + if (!tfa98xx->tapdet_enabled && enable) { + /* clear pending event if any */ + tfa_irq_clear(tfa98xx->tfa, tfa9912_irq_sttapdet); + } + + if (!tfa98xx->tapdet_poll) + tfa_irq_ena(tfa98xx->tfa, tfa9912_irq_sttapdet, + 1); /* enable again */ +} + +/* global enable / disable interrupts */ +static void tfa98xx_interrupt_enable(struct tfa98xx *tfa98xx, bool enable) +{ + if (tfa98xx->flags & TFA98XX_FLAG_SKIP_INTERRUPTS) + return; + + if (tfa98xx->tfa->tfa_family == 2) + tfa98xx_interrupt_enable_tfa2(tfa98xx, enable); +} + +/* Firmware management */ +static void tfa98xx_container_loaded(const struct firmware *cont, void *context) +{ + nxpTfaContainer_t *container; + struct tfa98xx *tfa98xx = context; + enum tfa_error tfa_err; + int container_size; + int ret; + + tfa98xx->dsp_fw_state = TFA98XX_DSP_FW_FAIL; + + if (!cont) { + pr_err("Failed to read %s\n", fw_name); + return; + } + + pr_debug("loaded %s - size: %zu\n", fw_name, cont->size); + + if (tfa98xx_container == NULL) { + container = kzalloc(cont->size, GFP_KERNEL); + if (container == NULL) { + pr_err("Error allocating memory\n"); + return; + } + + container_size = cont->size; + memcpy(container, cont->data, container_size); + + pr_debug("%.2s%.2s\n", container->version, + container->subversion); + pr_debug("%.8s\n", container->customer); + pr_debug("%.8s\n", container->application); + pr_debug("%.8s\n", container->type); + pr_debug("%d ndev\n", container->ndev); + pr_debug("%d nprof\n", container->nprof); + + tfa_err = tfa_load_cnt(container, container_size); + if (tfa_err != tfa_error_ok) { + kfree(container); + dev_err(tfa98xx->dev, + "Cannot load container file, aborting\n"); + return; + } + + tfa98xx_container = container; + } else { + pr_debug("container file already loaded...\n"); + container = tfa98xx_container; + } + + tfa98xx->tfa->cnt = container; + + /* + i2c transaction limited to 64k + (Documentation/i2c/writing-clients) + */ + tfa98xx->tfa->buffer_size = 65536; + + if (tfa_dev_probe(tfa98xx->i2c->addr, tfa98xx->tfa) != 0) { + dev_err(tfa98xx->dev, "Failed to probe TFA98xx @ 0x%.2x\n", + tfa98xx->i2c->addr); + return; + } + + /* once the device without internal DSP, we should be using DSP HAL to send msg to host DSP. */ + if (1 == tfa98xx->tfa->is_probus_device) { + tfa98xx->tfa->has_msg = 1; + } else { + tfa98xx->tfa->has_msg = 0; + } + + tfa98xx->tfa->dev_idx = tfa_cont_get_idx(tfa98xx->tfa); + if (tfa98xx->tfa->dev_idx < 0) { + dev_err(tfa98xx->dev, + "Failed to find TFA98xx @ 0x%.2x in container file\n", + tfa98xx->i2c->addr); + return; + } + + /* Enable debug traces */ + tfa98xx->tfa->verbose = trace_level & 1; + + /* prefix is the application name from the cnt */ + tfa_cnt_get_app_name(tfa98xx->tfa, tfa98xx->fw.name); + + /* set default profile/vstep */ + tfa98xx->profile = 0; + tfa98xx->vstep = 0; + + /* Override default profile if requested */ + if (strcmp(dflt_prof_name, "")) { + unsigned int i; + int nprof = tfa_cnt_get_dev_nprof(tfa98xx->tfa); + for (i = 0; i < nprof; i++) { + if (strcmp(tfa_cont_profile_name(tfa98xx, i), + dflt_prof_name) == 0) { + tfa98xx->profile = i; + dev_info( + tfa98xx->dev, + "changing default profile to %s (%d)\n", + dflt_prof_name, tfa98xx->profile); + break; + } + } + if (i >= nprof) + dev_info( + tfa98xx->dev, + "Default profile override failed (%s profile not found)\n", + dflt_prof_name); + } + + tfa98xx->dsp_fw_state = TFA98XX_DSP_FW_OK; + pr_debug("Firmware init complete\n"); + + if (no_start != 0) + return; + + /* Only controls for master device */ + if (tfa98xx->tfa->dev_idx == 0) + tfa98xx_create_controls(tfa98xx); + + tfa98xx_inputdev_check_register(tfa98xx); + + if (tfa_is_cold(tfa98xx->tfa) == 0) { + pr_debug("Warning: device 0x%.2x is still warm\n", + tfa98xx->i2c->addr); + tfa_reset(tfa98xx->tfa); + } + + /* Preload settings using internal clock on TFA2 */ + if ((tfa98xx->tfa->tfa_family == 2) && + (0 == tfa98xx->tfa->is_probus_device)) { + mutex_lock(&tfa98xx->dsp_lock); + pr_info("will be using internal clock to preload MAX2 TFA settings.\n"); + ret = tfa98xx_tfa_start(tfa98xx, tfa98xx->profile, + tfa98xx->vstep); + if (ret == Tfa98xx_Error_Not_Supported) + tfa98xx->dsp_fw_state = TFA98XX_DSP_FW_FAIL; + + /* we should be power-down device when parameter is loaded. */ + tfa_dev_stop(tfa98xx->tfa); + ret = tfa98xx->dsp_init = TFA98XX_DSP_INIT_STOPPED; + + mutex_unlock(&tfa98xx->dsp_lock); + } + + tfa98xx_interrupt_enable(tfa98xx, true); +} + +static int tfa98xx_load_container(struct tfa98xx *tfa98xx) +{ + const struct firmware *firmware; + int rc = 0; + + tfa98xx->dsp_fw_state = TFA98XX_DSP_FW_PENDING; + mutex_lock(&tfa98xx_mutex); + rc = request_firmware(&firmware, fw_name, tfa98xx->dev); + if (rc < 0) { + mutex_unlock(&tfa98xx_mutex); + return rc; + } + tfa98xx_container_loaded(firmware, tfa98xx); + release_firmware(firmware); + mutex_unlock(&tfa98xx_mutex); + + return rc; +} + +static void tfa98xx_tapdet(struct tfa98xx *tfa98xx) +{ + unsigned int tap_pattern; + int btn; + + /* check tap pattern (BTN_0 is "error" wrong tap indication */ + tap_pattern = tfa_get_tap_pattern(tfa98xx->tfa); + switch (tap_pattern) { + case 0xffffffff: + pr_info("More than 4 taps detected! (flagTapPattern = -1)\n"); + btn = BTN_0; + break; + case 0xfffffffe: + case 0xfe: + pr_info("Illegal tap detected!\n"); + btn = BTN_0; + break; + case 0: + pr_info("Unrecognized pattern! (flagTapPattern = 0)\n"); + btn = BTN_0; + break; + default: + pr_info("Detected pattern: %d\n", tap_pattern); + btn = BTN_0 + tap_pattern; + break; + } + + input_report_key(tfa98xx->input, btn, 1); + input_report_key(tfa98xx->input, btn, 0); + input_sync(tfa98xx->input); + + /* acknowledge event done by clearing interrupt */ +} + +static void tfa98xx_tapdet_work(struct work_struct *work) +{ + struct tfa98xx *tfa98xx; + + //TODO check is this is still needed for tap polling + tfa98xx = container_of(work, struct tfa98xx, tapdet_work.work); + + if (tfa_irq_get(tfa98xx->tfa, tfa9912_irq_sttapdet)) + tfa98xx_tapdet(tfa98xx); + + queue_delayed_work(tfa98xx->tfa98xx_wq, &tfa98xx->tapdet_work, HZ / 10); +} + +static void tfa98xx_monitor(struct work_struct *work) +{ +#if 0 + struct tfa98xx *tfa98xx; + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + + tfa98xx = container_of(work, struct tfa98xx, monitor_work.work); + + /* Check for tap-detection - bypass monitor if it is active */ + if (!tfa98xx->input) { + mutex_lock(&tfa98xx->dsp_lock); + error = tfa_status(tfa98xx->tfa); + mutex_unlock(&tfa98xx->dsp_lock); + if (error == Tfa98xx_Error_DSP_not_running) { + if (tfa98xx->dsp_init == TFA98XX_DSP_INIT_DONE) { + tfa98xx->dsp_init = TFA98XX_DSP_INIT_RECOVER; + queue_delayed_work(tfa98xx->tfa98xx_wq, &tfa98xx->init_work, 0); + } + } + } + + /* reschedule */ + queue_delayed_work(tfa98xx->tfa98xx_wq, &tfa98xx->monitor_work, 5*HZ); +#endif +} + +static void tfa98xx_dsp_init(struct tfa98xx *tfa98xx) +{ + int ret; + bool failed = false; + bool reschedule = false; + bool sync = false; + + if (tfa98xx->dsp_fw_state != TFA98XX_DSP_FW_OK) { + pr_debug("%s Skipping tfa_dev_start (no FW: %d)\n", __func__, + tfa98xx->dsp_fw_state); + return; + } + + if (tfa98xx->dsp_init == TFA98XX_DSP_INIT_DONE) { + pr_debug("%s Stream already started, skipping DSP power-on\n", + __func__); + return; + } + + mutex_lock(&tfa98xx->dsp_lock); + + tfa98xx->dsp_init = TFA98XX_DSP_INIT_PENDING; + + pr_debug("[NXP] %s init_count=%d\n", __func__, tfa98xx->init_count); + if (tfa98xx->init_count < TF98XX_MAX_DSP_START_TRY_COUNT) { + /* directly try to start DSP */ + ret = tfa98xx_tfa_start(tfa98xx, tfa98xx->profile, + tfa98xx->vstep); + if (ret == Tfa98xx_Error_Not_Supported) { + tfa98xx->dsp_fw_state = TFA98XX_DSP_FW_FAIL; + dev_err(&tfa98xx->i2c->dev, "Failed starting device\n"); + failed = true; + } else if (ret != Tfa98xx_Error_Ok) { + /* It may fail as we may not have a valid clock at that + * time, so re-schedule and re-try later. + */ + dev_err(&tfa98xx->i2c->dev, + "tfa_dev_start failed! (err %d) - %d\n", ret, + tfa98xx->init_count); + reschedule = true; + } else { + sync = true; + + /* Subsystem ready, tfa init complete */ + tfa98xx->dsp_init = TFA98XX_DSP_INIT_DONE; + dev_dbg(&tfa98xx->i2c->dev, + "tfa_dev_start success (%d)\n", + tfa98xx->init_count); + /* cancel other pending init works */ + cancel_delayed_work(&tfa98xx->init_work); + tfa98xx->init_count = 0; + } + } else { + /* exceeded max number ot start tentatives, cancel start */ + dev_err(&tfa98xx->i2c->dev, "Failed starting device (%d)\n", + tfa98xx->init_count); + failed = true; + } + if (reschedule) { + /* reschedule this init work for later */ + queue_delayed_work(tfa98xx->tfa98xx_wq, &tfa98xx->init_work, + msecs_to_jiffies(5)); + tfa98xx->init_count++; + } + if (failed) { + tfa98xx->dsp_init = TFA98XX_DSP_INIT_FAIL; + /* cancel other pending init works */ + cancel_delayed_work(&tfa98xx->init_work); + tfa98xx->init_count = 0; + } + mutex_unlock(&tfa98xx->dsp_lock); + + if (sync) { + /* check if all devices have started */ + bool do_sync; + mutex_lock(&tfa98xx_mutex); + + if (tfa98xx_sync_count < tfa98xx_device_count) + tfa98xx_sync_count++; + + do_sync = (tfa98xx_sync_count >= tfa98xx_device_count); + mutex_unlock(&tfa98xx_mutex); + + /* when all devices have started then unmute */ + if (do_sync) { + tfa98xx_sync_count = 0; + list_for_each_entry (tfa98xx, &tfa98xx_device_list, + list) { + mutex_lock(&tfa98xx->dsp_lock); + tfa_dev_set_state(tfa98xx->tfa, + TFA_STATE_UNMUTE, 0); + + /* + * start monitor thread to check IC status bit + * periodically, and re-init IC to recover if + * needed. + */ + if (tfa98xx->tfa->tfa_family == 1) + queue_delayed_work( + tfa98xx->tfa98xx_wq, + &tfa98xx->monitor_work, 1 * HZ); + mutex_unlock(&tfa98xx->dsp_lock); + } + } + } + + return; +} + +static void tfa98xx_dsp_init_work(struct work_struct *work) +{ + struct tfa98xx *tfa98xx = + container_of(work, struct tfa98xx, init_work.work); + + tfa98xx_dsp_init(tfa98xx); +} + +static void tfa98xx_interrupt(struct work_struct *work) +{ + struct tfa98xx *tfa98xx = + container_of(work, struct tfa98xx, interrupt_work.work); + + if (tfa98xx->flags & TFA98XX_FLAG_TAPDET_AVAILABLE) { + /* check for tap interrupt */ + if (tfa_irq_get(tfa98xx->tfa, tfa9912_irq_sttapdet)) { + tfa98xx_tapdet(tfa98xx); + + /* clear interrupt */ + tfa_irq_clear(tfa98xx->tfa, tfa9912_irq_sttapdet); + } + } /* TFA98XX_FLAG_TAPDET_AVAILABLE */ + + if (tfa98xx->flags & TFA98XX_FLAG_REMOVE_PLOP_NOISE) { + int start_triggered; + + mutex_lock(&tfa98xx->dsp_lock); + /*[nxp34663] CR: support 16bit/24bit/32bit audio data. begin*/ + start_triggered = + tfa_plop_noise_interrupt(tfa98xx->tfa, tfa98xx->profile, + tfa98xx->vstep, + tfa98xx->pcm_format); + /*[nxp34663] CR: support 16bit/24bit/32bit audio data. end*/ + /* Only enable when the return value is 1, otherwise the interrupt is triggered twice */ + if (start_triggered) + tfa98xx_interrupt_enable(tfa98xx, true); + mutex_unlock(&tfa98xx->dsp_lock); + } /* TFA98XX_FLAG_REMOVE_PLOP_NOISE */ + + if (tfa98xx->flags & TFA98XX_FLAG_LP_MODES) { + tfa_lp_mode_interrupt(tfa98xx->tfa); + } /* TFA98XX_FLAG_LP_MODES */ + + /* unmask interrupts masked in IRQ handler */ + tfa_irq_unmask(tfa98xx->tfa); +} + +static int tfa98xx_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + unsigned int sr; + int len, prof, nprof, idx = 0; + char *basename; + + /* + * Support CODEC to CODEC links, + * these are called with a NULL runtime pointer. + */ + if (!substream->runtime) + return 0; + + if (pcm_no_constraint != 0) + return 0; + + if (no_start != 0) + return 0; + + if (tfa98xx->dsp_fw_state != TFA98XX_DSP_FW_OK) { + dev_info(codec->dev, "Container file not loaded\n"); + return -EINVAL; + } + + basename = kzalloc(MAX_CONTROL_NAME, GFP_KERNEL); + if (!basename) + return -ENOMEM; + + /* copy profile name into basename until the . */ + get_profile_basename(basename, + tfa_cont_profile_name(tfa98xx, tfa98xx->profile)); + len = strlen(basename); + + /* loop over all profiles and get the supported samples rate(s) from + * the profiles with the same basename + */ + nprof = tfa_cnt_get_dev_nprof(tfa98xx->tfa); + tfa98xx->rate_constraint.list = &tfa98xx->rate_constraint_list[0]; + tfa98xx->rate_constraint.count = 0; + for (prof = 0; prof < nprof; prof++) { + if (0 == strncmp(basename, tfa_cont_profile_name(tfa98xx, prof), + len)) { + /* Check which sample rate is supported with current profile, + * and enforce this. + */ + sr = tfa98xx_get_profile_sr(tfa98xx->tfa, prof); + if (!sr) + dev_info( + codec->dev, + "Unable to identify supported sample rate\n"); + + if (tfa98xx->rate_constraint.count >= + TFA98XX_NUM_RATES) { + dev_err(codec->dev, "too many sample rates\n"); + } else { + tfa98xx->rate_constraint_list[idx++] = sr; + tfa98xx->rate_constraint.count += 1; + } + } + } + + kfree(basename); + + /* as QUALCOMM FAE suggested, we don't need to calling 'snd_pcm_hw_constraint_list' on QUALCOMM platform. */ + return 0; +} + +static int tfa98xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, + unsigned int freq, int dir) +{ + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec_dai->codec); + + tfa98xx->sysclk = freq; + return 0; +} + +static int tfa98xx_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, + unsigned int rx_mask, int slots, int slot_width) +{ + pr_debug("\n"); + return 0; +} + +static int tfa98xx_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(dai->codec); + struct snd_soc_codec *codec = dai->codec; + + pr_debug("fmt=0x%x\n", fmt); + + /* Supported mode: regular I2S, slave, or PDM */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != + SND_SOC_DAIFMT_CBS_CFS) { + dev_err(codec->dev, "Invalid Codec master mode\n"); + return -EINVAL; + } + break; + case SND_SOC_DAIFMT_PDM: + break; + default: + dev_err(codec->dev, "Unsupported DAI format %d\n", + fmt & SND_SOC_DAIFMT_FORMAT_MASK); + return -EINVAL; + } + + tfa98xx->audio_mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK; + + return 0; +} + +static int tfa98xx_get_fssel(unsigned int rate) +{ + int i; + for (i = 0; i < ARRAY_SIZE(rate_to_fssel); i++) { + if (rate_to_fssel[i].rate == rate) { + return rate_to_fssel[i].fssel; + } + } + return -EINVAL; +} + +static int tfa98xx_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + unsigned int rate; + int prof_idx; + + /* Supported */ + rate = params_rate(params); + pr_debug("Requested rate: %d, sample size: %d, physical size: %d\n", + rate, snd_pcm_format_width(params_format(params)), + snd_pcm_format_physical_width(params_format(params))); + + if (no_start != 0) + return 0; + + /* check if samplerate is supported for this mixer profile */ + prof_idx = get_profile_id_for_sr(tfa98xx_mixer_profile, rate); + if (prof_idx < 0) { + pr_err("tfa98xx: invalid sample rate %d.\n", rate); + return -EINVAL; + } + pr_debug("mixer profile:container profile = [%d:%d]\n", + tfa98xx_mixer_profile, prof_idx); + + /* update 'real' profile (container profile) */ + tfa98xx->profile = prof_idx; + + /* update to new rate */ + tfa98xx->rate = rate; + + /*[nxp34663] CR: support 16bit/24bit/32bit audio data. begin*/ + tfa98xx->pcm_format = snd_pcm_format_width(params_format(params)); + /*[nxp34663] CR: support 16bit/24bit/32bit audio data. end*/ + + return 0; +} + +#ifdef TFA_NON_DSP_SOLUTION +extern int send_tfa_cal_in_band(void *buf, int cmd_size); +static uint8_t bytes[3 * 3 + 1] = { 0 }; + +enum Tfa98xx_Error tfa98xx_adsp_send_calib_values(void) +{ + struct tfa98xx *tfa98xx; + int ret = 0; + int value = 0, nr, dsp_cal_value = 0; + + /* if the calibration value was sent to host DSP, we clear flag only (stereo case). */ + if ((tfa98xx_device_count > 1) && (tfa98xx_device_count == bytes[0])) { + pr_info("The calibration value was sent to host DSP.\n"); + bytes[0] = 0; + return Tfa98xx_Error_Ok; + } + + nr = 4; + /* read calibrated impendance from all devices. */ + list_for_each_entry (tfa98xx, &tfa98xx_device_list, list) { + struct tfa_device *tfa = tfa98xx->tfa; + if (TFA_GET_BF(tfa, MTPEX) == 1) { + value = tfa_dev_mtp_get(tfa, TFA_MTP_RE25); + dsp_cal_value = (value * 65536) / 1000; + pr_info("Device 0x%x cal value is 0x%d\n", + tfa98xx->i2c->addr, dsp_cal_value); + + bytes[nr++] = (uint8_t)((dsp_cal_value >> 16) & 0xff); + bytes[nr++] = (uint8_t)((dsp_cal_value >> 8) & 0xff); + bytes[nr++] = (uint8_t)(dsp_cal_value & 0xff); + bytes[0] += 1; + } + } + + /*for mono case, we will copy primary channel data to secondary channel. */ + if (1 == tfa98xx_device_count) { + memcpy(&bytes[7], &bytes[4], sizeof(char) * 3); + } + pr_info("tfa98xx_device_count=%d bytes[0]=%d\n", tfa98xx_device_count, + bytes[0]); + + /* we will send it to host DSP algorithm once calibraion value loaded from all device. */ + if (tfa98xx_device_count == bytes[0]) { + bytes[1] = 0x00; + bytes[2] = 0x81; + bytes[3] = 0x05; + + pr_info("calibration value send to host DSP.\n"); + ret = send_tfa_cal_in_band(&bytes[1], sizeof(bytes) - 1); + msleep(10); + + /* for mono case, we should clear flag here. */ + if (1 == tfa98xx_device_count) + bytes[0] = 0; + + } else { + pr_err("load calibration data from device failed.\n"); + ret = Tfa98xx_Error_Bad_Parameter; + } + + return ret; +} + +static int tfa98xx_send_mute_cmd(void) +{ + uint8_t cmd[9] = { + 0x04, 0x81, 0x04, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff + }; + pr_info("send mute command to host DSP.\n"); + return send_tfa_cal_in_band(&cmd[0], sizeof(cmd)); +} +#endif + +static int tfa98xx_mute(struct snd_soc_dai *dai, int mute, int stream) +{ + struct snd_soc_codec *codec = dai->codec; + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + + dev_dbg(&tfa98xx->i2c->dev, "%s: state: %d\n", __func__, mute); + + if (no_start) { + pr_debug( + "no_start parameter set no tfa_dev_start or tfa_dev_stop, returning\n"); + return 0; + } + if (TFA98XX_DEVICE_MUTE_ON == tfa98xx->tfa_mute_mode) { + pr_debug( + "%s: if Mute mode is enalbed, we don't need to power-on device. \n", + __func__); + return 0; + } + + if (mute) { + /* stop DSP only when both playback and capture streams + * are deactivated + */ + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + tfa98xx->pstream = 0; + else + tfa98xx->cstream = 0; + if (tfa98xx->pstream != 0 || tfa98xx->cstream != 0) + return 0; + + mutex_lock(&tfa98xx_mutex); + tfa98xx_sync_count = 0; + mutex_unlock(&tfa98xx_mutex); + + cancel_delayed_work_sync(&tfa98xx->monitor_work); + + cancel_delayed_work_sync(&tfa98xx->init_work); + if (tfa98xx->dsp_fw_state != TFA98XX_DSP_FW_OK) + return 0; + mutex_lock(&tfa98xx->dsp_lock); +#ifdef TFA_NON_DSP_SOLUTION + tfa98xx_send_mute_cmd(); + msleep(60); +#endif + tfa_dev_stop(tfa98xx->tfa); + tfa98xx->dsp_init = TFA98XX_DSP_INIT_STOPPED; + mutex_unlock(&tfa98xx->dsp_lock); + } else { + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + tfa98xx->pstream = 1; +#ifdef TFA_NON_DSP_SOLUTION + if (tfa98xx->tfa->is_probus_device) { + tfa98xx_adsp_send_calib_values(); + } +#endif + } else { + tfa98xx->cstream = 1; + } + +#if 0 + /* Start DSP with async mode.*/ + if (tfa98xx->dsp_init != TFA98XX_DSP_INIT_PENDING) + queue_delayed_work(tfa98xx->tfa98xx_wq, + &tfa98xx->init_work, 0); +#else + /* Start DSP with sync mode.*/ + pr_debug("[NXP] %s dsp_init=%d\n", __func__, tfa98xx->dsp_init); + if (tfa98xx->dsp_init != TFA98XX_DSP_INIT_PENDING) + tfa98xx_dsp_init(tfa98xx); +#endif + } + + return 0; +} + +static const struct snd_soc_dai_ops tfa98xx_dai_ops = { + .startup = tfa98xx_startup, + .set_fmt = tfa98xx_set_fmt, + .set_sysclk = tfa98xx_set_dai_sysclk, + .set_tdm_slot = tfa98xx_set_tdm_slot, + .hw_params = tfa98xx_hw_params, + .mute_stream = tfa98xx_mute, +}; + +static struct snd_soc_dai_driver tfa98xx_dai[] = { + { + .name = "tfa98xx-aif", + .id = 1, + .playback = { + .stream_name = "AIF Playback", + .channels_min = 1, + .channels_max = 4, + .rates = TFA98XX_RATES, + .formats = TFA98XX_FORMATS, + }, + .capture = { + .stream_name = "AIF Capture", + .channels_min = 1, + .channels_max = 4, + .rates = TFA98XX_RATES, + .formats = TFA98XX_FORMATS, + }, + .ops = &tfa98xx_dai_ops, +/* .symmetric_rates = 1, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) + .symmetric_channels = 1, + .symmetric_samplebits = 1, +#endif*/ + }, +}; + +static int tfa98xx_probe(struct snd_soc_codec *codec) +{ + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + int ret; + + pr_debug("\n"); + + /* setup work queue, will be used to initial DSP on first boot up */ + tfa98xx->tfa98xx_wq = create_singlethread_workqueue("tfa98xx"); + if (!tfa98xx->tfa98xx_wq) + return -ENOMEM; + + INIT_DELAYED_WORK(&tfa98xx->init_work, tfa98xx_dsp_init_work); + INIT_DELAYED_WORK(&tfa98xx->monitor_work, tfa98xx_monitor); + INIT_DELAYED_WORK(&tfa98xx->interrupt_work, tfa98xx_interrupt); + INIT_DELAYED_WORK(&tfa98xx->tapdet_work, tfa98xx_tapdet_work); + + tfa98xx->codec = codec; + + ret = tfa98xx_load_container(tfa98xx); + pr_debug("Container loading requested: %d\n", ret); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0) + codec->control_data = tfa98xx->regmap; + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); + if (ret != 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } +#endif + tfa98xx_add_widgets(tfa98xx); + + dev_info(codec->dev, "tfa98xx codec registered (%s)", tfa98xx->fw.name); + + return ret; +} + +static int tfa98xx_remove(struct snd_soc_codec *codec) +{ + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + pr_debug("\n"); + + tfa98xx_interrupt_enable(tfa98xx, false); + + tfa98xx_inputdev_unregister(tfa98xx); + + cancel_delayed_work_sync(&tfa98xx->interrupt_work); + cancel_delayed_work_sync(&tfa98xx->monitor_work); + cancel_delayed_work_sync(&tfa98xx->init_work); + cancel_delayed_work_sync(&tfa98xx->tapdet_work); + + if (tfa98xx->tfa98xx_wq) + destroy_workqueue(tfa98xx->tfa98xx_wq); + + return 0; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) +static struct regmap *tfa98xx_get_regmap(struct device *dev) +{ + struct tfa98xx *tfa98xx = dev_get_drvdata(dev); + + return tfa98xx->regmap; +} +#endif +static struct snd_soc_codec_driver soc_codec_dev_tfa98xx = { + .probe = tfa98xx_probe, + .remove = tfa98xx_remove, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) + .get_regmap = tfa98xx_get_regmap, +#endif +}; + +static bool tfa98xx_writeable_register(struct device *dev, unsigned int reg) +{ + /* enable read access for all registers */ + return 1; +} + +static bool tfa98xx_readable_register(struct device *dev, unsigned int reg) +{ + /* enable read access for all registers */ + return 1; +} + +static bool tfa98xx_volatile_register(struct device *dev, unsigned int reg) +{ + /* enable read access for all registers */ + return 1; +} + +static const struct regmap_config tfa98xx_regmap = { + .reg_bits = 8, + .val_bits = 16, + + .max_register = TFA98XX_MAX_REGISTER, + .writeable_reg = tfa98xx_writeable_register, + .readable_reg = tfa98xx_readable_register, + .volatile_reg = tfa98xx_volatile_register, + .cache_type = REGCACHE_NONE, +}; + +static void tfa98xx_irq_tfa2(struct tfa98xx *tfa98xx) +{ + /* + * mask interrupts + * will be unmasked after handling interrupts in workqueue + */ + tfa_irq_mask(tfa98xx->tfa); + queue_delayed_work(tfa98xx->tfa98xx_wq, &tfa98xx->interrupt_work, 0); +} + +static irqreturn_t tfa98xx_irq(int irq, void *data) +{ + struct tfa98xx *tfa98xx = data; + + if (tfa98xx->tfa->tfa_family == 2) + tfa98xx_irq_tfa2(tfa98xx); + + return IRQ_HANDLED; +} + +static int tfa98xx_ext_reset(struct tfa98xx *tfa98xx) +{ + if (tfa98xx && gpio_is_valid(tfa98xx->reset_gpio)) { + gpio_set_value_cansleep(tfa98xx->reset_gpio, 1); + msleep(10); + gpio_set_value_cansleep(tfa98xx->reset_gpio, 0); + msleep(10); + } + return 0; +} + +static int tfa98xx_parse_dt(struct device *dev, struct tfa98xx *tfa98xx, + struct device_node *np) +{ + tfa98xx->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); + if (tfa98xx->reset_gpio < 0) + dev_dbg(dev, + "No reset GPIO provided, will not HW reset device\n"); + + tfa98xx->irq_gpio = of_get_named_gpio(np, "irq-gpio", 0); + if (tfa98xx->irq_gpio < 0) + dev_dbg(dev, "No IRQ GPIO provided.\n"); + + return 0; +} + +static ssize_t tfa98xx_reg_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct tfa98xx *tfa98xx = dev_get_drvdata(dev); + + if (count != 1) { + pr_debug("invalid register address"); + return -EINVAL; + } + + tfa98xx->reg = buf[0]; + + return 1; +} + +static ssize_t tfa98xx_rw_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct tfa98xx *tfa98xx = dev_get_drvdata(dev); + u8 *data; + int ret; + int retries = I2C_RETRIES; + + data = kmalloc(count + 1, GFP_KERNEL); + if (data == NULL) { + pr_debug("can not allocate memory\n"); + return -ENOMEM; + } + + data[0] = tfa98xx->reg; + memcpy(&data[1], buf, count); + +retry: + ret = i2c_master_send(tfa98xx->i2c, data, count + 1); + if (ret < 0) { + pr_warn("i2c error, retries left: %d\n", retries); + if (retries) { + retries--; + msleep(I2C_RETRY_DELAY); + goto retry; + } + } + + kfree(data); + + /* the number of data bytes written without the register address */ + return ((ret > 1) ? count : -EIO); +} + +static ssize_t tfa98xx_rw_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct tfa98xx *tfa98xx = dev_get_drvdata(dev); + struct i2c_msg msgs[] = { + { + .addr = tfa98xx->i2c->addr, + .flags = 0, + .len = 1, + .buf = &tfa98xx->reg, + }, + { + .addr = tfa98xx->i2c->addr, + .flags = I2C_M_RD, + .len = count, + .buf = buf, + }, + }; + int ret; + int retries = I2C_RETRIES; +retry: + ret = i2c_transfer(tfa98xx->i2c->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret < 0) { + pr_warn("i2c error, retries left: %d\n", retries); + if (retries) { + retries--; + msleep(I2C_RETRY_DELAY); + goto retry; + } + return ret; + } + /* ret contains the number of i2c transaction */ + /* return the number of bytes read */ + return ((ret > 1) ? count : -EIO); +} + +static struct bin_attribute dev_attr_rw = { + .attr = { + .name = "rw", + .mode = S_IRUSR | S_IWUSR, + }, + .size = 0, + .read = tfa98xx_rw_read, + .write = tfa98xx_rw_write, +}; + +static struct bin_attribute dev_attr_reg = { + .attr = { + .name = "reg", + .mode = S_IWUSR, + }, + .size = 0, + .read = NULL, + .write = tfa98xx_reg_write, +}; + +static int tfa98xx_misc_device_profile_open(struct inode *inode, + struct file *file) +{ + struct tfa98xx *tfa98xx = container_of(file->private_data, + struct tfa98xx, tfa98xx_profile); + //pr_info("entry tfa98xx=%p\n", tfa98xx); + if (tfa98xx) { + file->private_data = tfa98xx; + return 0; + } else { + file->private_data = NULL; + return -EINVAL; + } +} + +static ssize_t tfa98xx_misc_device_profile_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct tfa98xx *tfa98xx = file->private_data; + char name[100] = { 0 }; + int ret = 0; + int profileID = 0; + + //pr_info("entry count=%d\n", (int)count); + + if (NULL == tfa98xx) { + pr_err("%s tfa98xx is NULL.\n", __func__); + return -EINVAL; + } + /*if (count != 1) { + pr_err("%s invalid register address\n", __func__); + return -EINVAL; + }*/ + memset(name, 0x00, sizeof(name)); + ret = copy_from_user(name, user_buf, count); + //pr_info("profile name=%s\n", name); + + /* search profile name and return ID. */ + profileID = get_profile_id_by_name(name, strlen(name)); + if (profileID < 0) { + pr_err("didn't find profile from list.\n"); + return 0; + } else { + int prof_idx = get_profile_id_for_sr(profileID, tfa98xx->rate); + if (prof_idx < 0) { + pr_err("sample rate [%d] not supported for this profile(%d).\n", + tfa98xx->rate, profileID); + return 0; + } else { + tfa98xx_mixer_profile = profileID; + tfa98xx->profile = prof_idx; + tfa98xx->vstep = tfa98xx->prof_vsteps[prof_idx]; + //pr_info("update profile index (%d:%d) succeeded\n", profileID, prof_idx); + } + } + + return count; +} + +static int tfa98xx_misc_device_reg_open(struct inode *inode, struct file *file) +{ + struct tfa98xx *tfa98xx = + container_of(file->private_data, struct tfa98xx, tfa98xx_reg); + if (tfa98xx) { + file->private_data = tfa98xx; + return 0; + } else { + file->private_data = NULL; + return -EINVAL; + } +} + +static ssize_t tfa98xx_misc_device_reg_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct tfa98xx *tfa98xx = file->private_data; + u8 address = 0; + int ret = 0; + + //pr_info("entry count=%d\n", (int)count); + + if (NULL == tfa98xx) { + pr_err("tfa98xx is NULL.\n"); + return -EINVAL; + } + + if (count != 1) { + pr_err("invalid register address\n"); + return -EINVAL; + } + + ret = copy_from_user(&address, user_buf, count); + if (ret) { + pr_err("copy data from user space failed.\n"); + } + + tfa98xx->reg = address; + //pr_info("tfa98xx->reg=0x%x\n", tfa98xx->reg); + + return count; +} + +static int tfa98xx_misc_device_rw_open(struct inode *inode, struct file *file) +{ + struct tfa98xx *tfa98xx = + container_of(file->private_data, struct tfa98xx, tfa98xx_rw); + if (tfa98xx) { + file->private_data = tfa98xx; + return 0; + } else { + file->private_data = NULL; + return -EINVAL; + } +} + +static ssize_t tfa98xx_misc_device_rw_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + struct tfa98xx *tfa98xx = file->private_data; + struct i2c_msg msgs[] = { + { + .addr = tfa98xx->i2c->addr, + .flags = 0, + .len = 1, + .buf = &tfa98xx->reg, + }, + { + .addr = tfa98xx->i2c->addr, + .flags = I2C_M_RD, + .len = count, + .buf = NULL, + }, + }; + + u8 *data; + int ret; + int retries = I2C_RETRIES; + + //pr_info("entry count=%d\n", (int)count); + + data = kmalloc(count + 1, GFP_KERNEL); + if (data == NULL) { + pr_debug("can not allocate memory\n"); + return -ENOMEM; + } + + msgs[1].buf = data; + +retry: + ret = i2c_transfer(tfa98xx->i2c->adapter, msgs, ARRAY_SIZE(msgs)); + //pr_info("i2c_transfer ret=%d\n", ret); + + if (ret < 0) { + pr_warn("i2c error, retries left: %d\n", retries); + if (retries) { + retries--; + msleep(I2C_RETRY_DELAY); + goto retry; + } + + kfree(data); + return ret; + } else if (ret > 1) { + int ret_cpy = copy_to_user(user_buf, data, count); + if (ret_cpy) { + pr_err("copy to user space failed.\n"); + } + } + + /* ret contains the number of i2c transaction */ + /* return the number of bytes read */ + kfree(data); + return ((ret > 1) ? count : -EIO); +} + +static ssize_t tfa98xx_misc_device_rw_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct tfa98xx *tfa98xx = file->private_data; + u8 *data; + int ret; + int retries = I2C_RETRIES; + //pr_info("entry count=%d\n", (int)count); + + data = kmalloc(count + 1, GFP_KERNEL); + if (data == NULL) { + pr_debug("can not allocate memory\n"); + return -ENOMEM; + } + + //pr_info("tfa98xx->reg=0x%x\n", tfa98xx->reg); + + data[0] = tfa98xx->reg; + if (copy_from_user(&data[1], user_buf, count)) { + pr_err("copy to user space failed.\n"); + } + +retry: + ret = i2c_master_send(tfa98xx->i2c, data, count + 1); + if (ret < 0) { + pr_warn("i2c error, retries left: %d\n", retries); + if (retries) { + retries--; + msleep(I2C_RETRY_DELAY); + goto retry; + } + } + + kfree(data); + + /* the number of data bytes written without the register address */ + return ((ret > 1) ? count : -EIO); +} + +static int tfa98xx_misc_device_rpc_open(struct inode *inode, struct file *file) +{ + struct tfa98xx *tfa98xx = + container_of(file->private_data, struct tfa98xx, tfa98xx_rpc); + if (tfa98xx) { + file->private_data = tfa98xx; + return 0; + } else { + file->private_data = NULL; + return -EINVAL; + } +} + +static ssize_t tfa98xx_misc_device_rpc_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + struct tfa98xx *tfa98xx = file->private_data; + uint8_t *buffer = NULL; + int ret = 0; + + buffer = kmalloc(count, GFP_KERNEL); + if (buffer == NULL) { + pr_err("[0x%x] can not allocate memory\n", tfa98xx->i2c->addr); + return -ENOMEM; + } + + mutex_lock(&tfa98xx->dsp_lock); + + ret = send_tfa_cal_apr(buffer, count, true); + + mutex_unlock(&tfa98xx->dsp_lock); + if (ret) { + pr_err("[0x%x] dsp_msg_read error: %d\n", tfa98xx->i2c->addr, + ret); + kfree(buffer); + return -EFAULT; + } + + ret = copy_to_user(user_buf, buffer, count); + kfree(buffer); + if (ret) + return -EFAULT; + + *ppos += count; + return count; +} + +static ssize_t tfa98xx_misc_device_rpc_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct tfa98xx *tfa98xx = file->private_data; + uint8_t *buffer; + int err = 0; + + if (count == 0) + return 0; + + /* msg_file.name is not used */ + buffer = kmalloc(count, GFP_KERNEL); + if (buffer == NULL) { + pr_err("[0x%x] can not allocate memory\n", tfa98xx->i2c->addr); + return -ENOMEM; + } + if (copy_from_user(buffer, user_buf, count)) + return -EFAULT; + + mutex_lock(&tfa98xx->dsp_lock); + + err = send_tfa_cal_apr(buffer, count, false); + if (err) { + pr_err("[0x%x] dsp_msg error: %d\n", tfa98xx->i2c->addr, err); + } + + mdelay(2); + + mutex_unlock(&tfa98xx->dsp_lock); + + kfree(buffer); + + if (err) + return err; + return count; +} + +enum Tfa98xx_Error tfa98xx_read_data_from_hostdsp(struct tfa_device *tfa, + unsigned char module_id, + unsigned char param_id, + int num_bytes, + unsigned char data[]) +{ + int error; + unsigned char buffer[3]; + int nr = 0; + + if (num_bytes <= 0) { + pr_debug( + "Error: The number of READ bytes is smaller or equal to 0! \n"); + return Tfa98xx_Error_Fail; + } + + if ((tfa->cnt->ndev == 1) && (param_id == SB_PARAM_GET_RE25C || + param_id == SB_PARAM_GET_LSMODEL || + param_id == SB_PARAM_GET_ALGO_PARAMS)) { + /* Modifying the ID for GetRe25C */ + buffer[nr++] = 4; + } else { + buffer[nr++] = tfa->spkr_select; + } + buffer[nr++] = module_id + 128; + buffer[nr++] = param_id; + + error = send_tfa_cal_apr(buffer, sizeof(buffer), false); + if (error) + return Tfa98xx_Error_Bad_Parameter; + mdelay(5); + + /* read the data from the dsp */ + error = send_tfa_cal_apr(data, sizeof(num_bytes), true); + if (error) + return Tfa98xx_Error_Bad_Parameter; + return Tfa98xx_Error_Ok; +} + +static uint8_t send_to_dsp_count = 0; +static int tfa98xx_read_memtrack_data(struct tfa98xx *tfa98xx, int *pLivedata) +{ + enum Tfa98xx_Error ret = Tfa98xx_Error_Ok; + /* the buffer is for stereo usecase. */ + char buffer[(2 + (MEMTRACK_ITEM_MAX * 2)) * 3] = { 0 }; + int item_bytes = MEMTRACK_ITEM_MAX * 3; /* mono case by default.*/ + + enum TFA_DEVICE_TYPE pri_devcie = TFA_DEVICE_TYPE_MAX; + enum TFA_DEVICE_TYPE sec_devcie = TFA_DEVICE_TYPE_MAX; + /* TFA device memory map. */ + struct livedata_cfg + livedata_table[TFA_DEVICE_TYPE_MAX][MEMTRACK_ITEM_MAX] = { + /* for TFA9894 device */ + { + { 0x6fc, 0x02, 0x0001 }, /* fRes_P */ + { 0x705, 0x02, 0x4000 }, /* T_P */ + { 0x70b, 0x02, 0x10000 }, /* ReT_P */ + }, + + /* for TFA9874 primary channel */ + { + { 0x310, 0x02, 0x0001 }, /* fRes_P */ + { 0x319, 0x02, 0x4000 }, /* T_P */ + { 0x31f, 0x02, 0x10000 }, /* ReT_P */ + }, + + /* for TFA9874 secondary channel */ + { + { 0x64c, 0x02, 0x0001 }, /* fRes_S */ + { 0x655, 0x02, 0x4000 }, /* T_S */ + { 0x65b, 0x02, 0x10000 }, /* ReT_S */ + }, + }; + + pr_info("entry tfa_family=%d rev=0x%x\n", tfa98xx->tfa->tfa_family, + tfa98xx->tfa->rev); + mutex_lock(&tfa98xx->dsp_lock); + switch (tfa98xx->tfa->rev & 0xff) { + case 0x74: + pri_devcie = TFA_DEVICE_TYPE_9874_PRIMARY; + sec_devcie = TFA_DEVICE_TYPE_9874_SECONDARY; + break; + case 0x94: + pri_devcie = TFA_DEVICE_TYPE_9894; + break; + default: + pr_err("Un-support device type 0x%x\n", tfa98xx->tfa->rev); + ret = Tfa98xx_Error_Device; + goto err; + } + + /* check DSP status. we can read memtrack data once DSP is running. */ + if ((TFA_GET_BF(tfa98xx->tfa, MANSTATE) != 9) || + (TFA_GET_BF(tfa98xx->tfa, CFE) == 0)) { + pr_err("The DSP is not running.\n"); + ret = Tfa98xx_Error_DSP_not_running; + goto err; + } + + if (2 == tfa98xx->tfa->tfa_family) { + int i = 0, j = 0; + + /* step 1: set livedata items. */ + memset(&buffer[0], 0x00, sizeof(buffer)); + + /* For every item take the tracker and add this infront of the adress */ + if (tfa98xx->tfa->is_probus_device) { /* for none-dsp device. */ + /* because our algorithm can support mono/stereo use case. + if device count is more than 1, we will build stereo struct and send to dsp next time. */ + if ((tfa98xx_device_count > 1) && + (0 == send_to_dsp_count)) { + send_to_dsp_count++; + ret = Tfa98xx_Error_Ok; + goto err; + } + } + + /* build primary channel struct. */ + for (i = 0; i < MEMTRACK_ITEM_MAX * 3; i += 3) { + buffer[i + 6] = + (uint8_t)(livedata_table[pri_devcie][j].track & + 0xff); + buffer[i + 7] = (uint8_t)((livedata_table[pri_devcie][j] + .address >> + 8) & + 0xff); + buffer[i + 8] = + (uint8_t)(livedata_table[pri_devcie][j].address & + 0xff); + j++; + } + + /* build secondary channel struct. */ + if (tfa98xx_device_count > 1) { + j = 0; + for (i = MEMTRACK_ITEM_MAX * 3; + i < MEMTRACK_ITEM_MAX * 6; i += 3) { + buffer[i + 6] = + (uint8_t)(livedata_table[sec_devcie][j] + .track & + 0xff); + buffer[i + 7] = + (uint8_t)((livedata_table[sec_devcie][j] + .address >> + 8) & + 0xff); + buffer[i + 8] = + (uint8_t)(livedata_table[sec_devcie][j] + .address & + 0xff); + j++; + } + + item_bytes *= + 2; /* re-calculate item length for stereo usecase. */ + } + + /* copy the msg_id to buffer */ + buffer[0] = 0; + buffer[1] = MODULE_FRAMEWORK + 128; + buffer[2] = FW_PAR_ID_SET_MEMTRACK; + + /* Then copy the length (number of memtrack items) */ + buffer[3] = (uint8_t)((item_bytes >> 16) & 0xffff); + buffer[4] = (uint8_t)((item_bytes >> 8) & 0xff); + buffer[5] = (uint8_t)(item_bytes & 0xff); + + pr_info("send command to dsp to build memtrack structure.\n"); + /* send command to host dsp. */ + if (tfa98xx->tfa->is_probus_device) { + send_tfa_cal_apr(buffer, item_bytes + 6, false); + send_to_dsp_count = 0; + mdelay(5); + } else { + ret = dsp_msg(tfa98xx->tfa, item_bytes + 6, buffer); + } + + if (Tfa98xx_Error_Ok == ret) { + /* step 2: read livedata from dsp. */ + memset(&buffer[0], 0x00, sizeof(buffer)); + + /*Length = nr of items * 3 bytes (24bit dsp) + 3 bytes for Elapsed time (first 3 bytes)*/ + if (tfa98xx->tfa->is_probus_device) { + ret = tfa98xx_read_data_from_hostdsp( + tfa98xx->tfa, MODULE_FRAMEWORK, + FW_PAR_ID_GET_MEMTRACK, item_bytes + 3, + buffer); + } else { + ret = tfa_dsp_cmd_id_write_read( + tfa98xx->tfa, MODULE_FRAMEWORK, + FW_PAR_ID_GET_MEMTRACK, item_bytes + 3, + buffer); + } + + pr_info("read memtrack data. ret=%d\n", ret); + + if (Tfa98xx_Error_Ok == ret) { + /* Skip the first 3 bytes (this is the Elapsed time, not memtrack data) */ + tfa98xx_convert_bytes2data( + item_bytes, &buffer[3], pLivedata); + } else { + pr_err("get memtrack data failed from device.\n"); + ret = Tfa98xx_Error_Other; + } + } else { + pr_err("set memtrack item failed.\n"); + ret = Tfa98xx_Error_Other; + } + } else { + pr_err("The funciton doesn't support other device family(%d).\n", + tfa98xx->tfa->tfa_family); + ret = Tfa98xx_Error_Other; + } + +err: + mutex_unlock(&tfa98xx->dsp_lock); + return ret; +} + +static int tfa98xx_misc_device_control_open(struct inode *inode, + struct file *file) +{ + struct tfa98xx *tfa98xx = container_of(file->private_data, + struct tfa98xx, tfa98xx_control); + if (tfa98xx) { + file->private_data = tfa98xx; + return 0; + } else { + file->private_data = NULL; + return -EINVAL; + } +} + +static long tfa98xx_misc_device_control_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg) +{ + struct tfa98xx *tfa98xx = NULL; + int result = 0; + + //pr_info("entry cmd=%d arg=%p\n", cmd, (void*)arg); + if (!arg) { + pr_err("arg is NULL!\n"); + return -EINVAL; + } + + switch (cmd) { + case IOCTL_CMD_GET_MEMTRACK_DATA: { + int livedata[MEMTRACK_ITEM_MAX * 2]; + int livedata_length_bytes = 0; + void *pUserData = (void *)arg; + list_for_each_entry (tfa98xx, &tfa98xx_device_list, list) { + /* clear buffer and read livedata from dsp.*/ + memset((char *)(&livedata[0]), 0x00, sizeof(livedata)); + /* read original memtrack data from device. */ + if (Tfa98xx_Error_Ok == + tfa98xx_read_memtrack_data(tfa98xx, &livedata[0])) { + pr_info("Device 0x%x read memtrack data sucessed.\n", + tfa98xx->i2c->addr); + } else { + pr_err("Device 0x%x read memtrack data failed.\n", + tfa98xx->i2c->addr); + } + + /* copy data to user spcace. if copied is successed, + will be returned actual size to user space. */ + livedata_length_bytes = sizeof(int) * MEMTRACK_ITEM_MAX; + if ((tfa98xx->tfa->is_probus_device) && + (tfa98xx_device_count > 1)) { + /* for stereo usecase, if the condition is true, we have already got livedata from host DSP. + otherwise, we don't need do anything. */ + if (send_to_dsp_count == 0) { + livedata_length_bytes *= 2; + } else { + livedata_length_bytes = 0; + } + } + + if (livedata_length_bytes != 0) { + result = copy_to_user((void __user *)pUserData, + &livedata[0], + livedata_length_bytes); + if (result) { + pr_err("copy to user space failed(%d).\n", + result); + result = -EINVAL; + break; + } else { + result += livedata_length_bytes; + } + pUserData += livedata_length_bytes; + } + } + break; + } + case IOCTL_CMD_GET_CNT_VERSION: { + void *pUserData = (void *)arg; + + if (NULL != tfa98xx_container) { + result = copy_to_user((void __user *)pUserData, + tfa98xx_container->type, + strlen(tfa98xx_container->type)); + if (result) { + pr_err("copy to user space failed(%d).\n", + result); + } else { + result = strlen(tfa98xx_container->type); + } + } else { + pr_err("get cnt version failed.\n"); + result = -EINVAL; + } + break; + } + default: + result = -EINVAL; + pr_err("un-supported command. (%d)\n", cmd); + break; + } + + //pr_info("exit result=%d\n", result); + return result; +} + +#ifdef CONFIG_COMPAT +static long tfa98xx_misc_device_control_compat_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg) +{ + //pr_info("%s entry cmd=%d arg=%p\n", __func__, cmd, (void*)arg); + + if (!arg) { + pr_err("%s No data send to driver!\n", __func__); + return -EINVAL; + } + + return tfa98xx_misc_device_control_ioctl(file, cmd, arg); +} +#endif + +static const struct tfa98xx_miscdevice_info miscdevice_info[MISC_DEVICE_MAX] = { + { + .devicename = "tfa_reg", + .operations.owner = THIS_MODULE, + .operations.open = tfa98xx_misc_device_reg_open, + .operations.write = tfa98xx_misc_device_reg_write, + }, + { + .devicename = "tfa_rw", + .operations.owner = THIS_MODULE, + .operations.open = tfa98xx_misc_device_rw_open, + .operations.read = tfa98xx_misc_device_rw_read, + .operations.write = tfa98xx_misc_device_rw_write, + }, + { + .devicename = "tfa_rpc", + .operations.owner = THIS_MODULE, + .operations.open = tfa98xx_misc_device_rpc_open, + .operations.read = tfa98xx_misc_device_rpc_read, + .operations.write = tfa98xx_misc_device_rpc_write, + }, + { + .devicename = "tfa_profile", + .operations.owner = THIS_MODULE, + .operations.open = tfa98xx_misc_device_profile_open, + .operations.write = tfa98xx_misc_device_profile_write, + }, + { + .devicename = "tfa_control", + .operations.owner = THIS_MODULE, + .operations.open = tfa98xx_misc_device_control_open, + .operations.unlocked_ioctl = tfa98xx_misc_device_control_ioctl, +#ifdef CONFIG_COMPAT + .operations.compat_ioctl = + tfa98xx_misc_device_control_compat_ioctl, +#endif + }, +}; + +int tfa98xx_init_misc_device(struct tfa98xx *tfa98xx) +{ + int ret = 0; + + pr_info("entry\n"); + if (NULL == tfa98xx) { + pr_err("tfa98xx is NULL.\n"); + return -EINVAL; + } + + //pr_info("I2C bus=0x%x address=0x%x\n", tfa98xx->i2c->adapter->nr, tfa98xx->i2c->addr); + /* create device node "tfa_reg_X" for write sub address. */ + tfa98xx->tfa98xx_reg.minor = MISC_DYNAMIC_MINOR; + tfa98xx->tfa98xx_reg.name = + miscdevice_info[MISC_DEVICE_TFA98XX_REG].devicename; + tfa98xx->tfa98xx_reg.fops = + &miscdevice_info[MISC_DEVICE_TFA98XX_REG].operations; + ret = misc_register(&tfa98xx->tfa98xx_reg); + if (ret) { + pr_err("tfa98xx_init_misc_device: register misc device [%s] failed\n", + tfa98xx->tfa98xx_reg.name); + } + + /* create device node "tfa_rw_X" for read/write i2c device. */ + tfa98xx->tfa98xx_rw.minor = MISC_DYNAMIC_MINOR; + tfa98xx->tfa98xx_rw.name = + miscdevice_info[MISC_DEVICE_TFA98XX_RW].devicename; + tfa98xx->tfa98xx_rw.fops = + &miscdevice_info[MISC_DEVICE_TFA98XX_RW].operations; + ret = misc_register(&tfa98xx->tfa98xx_rw); + if (ret) { + pr_err("tfa98xx_init_misc_device: register misc device [%s] failed\n", + tfa98xx->tfa98xx_rw.name); + } + + /* create device node "tfa_rpc_X" for switching profile. */ + tfa98xx->tfa98xx_rpc.minor = MISC_DYNAMIC_MINOR; + tfa98xx->tfa98xx_rpc.name = + miscdevice_info[MISC_DEVICE_TFA98XX_RPC].devicename; + tfa98xx->tfa98xx_rpc.fops = + &miscdevice_info[MISC_DEVICE_TFA98XX_RPC].operations; + ret = misc_register(&tfa98xx->tfa98xx_rpc); + if (ret) { + pr_err("tfa98xx_init_misc_device: register misc device [%s] failed\n", + tfa98xx->tfa98xx_rpc.name); + } + + /* create device node "tfa_profile_X" for switching profile. */ + tfa98xx->tfa98xx_profile.minor = MISC_DYNAMIC_MINOR; + tfa98xx->tfa98xx_profile.name = + miscdevice_info[MISC_DEVICE_TFA98XX_PROFILE].devicename; + tfa98xx->tfa98xx_profile.fops = + &miscdevice_info[MISC_DEVICE_TFA98XX_PROFILE].operations; + ret = misc_register(&tfa98xx->tfa98xx_profile); + if (ret) { + pr_err("tfa98xx_init_misc_device: register misc device [%s] failed\n", + tfa98xx->tfa98xx_profile.name); + } + + /* create device node "tfa_control_X" for IO control. */ + tfa98xx->tfa98xx_control.minor = MISC_DYNAMIC_MINOR; + tfa98xx->tfa98xx_control.name = + miscdevice_info[MISC_DEVICE_TFA98XX_IOCTL].devicename; + tfa98xx->tfa98xx_control.fops = + &miscdevice_info[MISC_DEVICE_TFA98XX_IOCTL].operations; + ret = misc_register(&tfa98xx->tfa98xx_control); + if (ret) { + pr_err("tfa98xx_init_misc_device: register misc device [%s] failed\n", + tfa98xx->tfa98xx_control.name); + } + + if (0 == ret) + pr_info("register misc device successed.\n"); + return ret; +} + +void tfa98xx_remove_misc_device(struct tfa98xx *tfa98xx) +{ + pr_info("entry\n"); + if (NULL == tfa98xx) { + pr_err("tfa98xx is NULL.\n"); + return; + } + + misc_deregister(&tfa98xx->tfa98xx_reg); + misc_deregister(&tfa98xx->tfa98xx_rw); + misc_deregister(&tfa98xx->tfa98xx_rpc); + misc_deregister(&tfa98xx->tfa98xx_profile); + misc_deregister(&tfa98xx->tfa98xx_control); + return; +} + +static int tfa98xx_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct snd_soc_dai_driver *dai; + struct tfa98xx *tfa98xx; + struct device_node *np = i2c->dev.of_node; + int irq_flags; + unsigned int reg; + int ret; + int spk_name; + + pr_info("addr=0x%x\n", i2c->addr); + + if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) { + dev_err(&i2c->dev, "check_functionality failed\n"); + return -EIO; + } + + tfa98xx = devm_kzalloc(&i2c->dev, sizeof(struct tfa98xx), GFP_KERNEL); + if (tfa98xx == NULL) + return -ENOMEM; + + tfa98xx->dev = &i2c->dev; + tfa98xx->i2c = i2c; + tfa98xx->dsp_init = TFA98XX_DSP_INIT_STOPPED; + tfa98xx->rate = 48000; /* init to the default sample rate (48kHz) */ + tfa98xx->tfa = NULL; + tfa98xx->tfa_mute_mode = + TFA98XX_DEVICE_MUTE_OFF; /* the mute mode is disabled by default. */ + tfa98xx->regmap = devm_regmap_init_i2c(i2c, &tfa98xx_regmap); + if (IS_ERR(tfa98xx->regmap)) { + ret = PTR_ERR(tfa98xx->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + i2c_set_clientdata(i2c, tfa98xx); + mutex_init(&tfa98xx->dsp_lock); + init_waitqueue_head(&tfa98xx->wq); + + if (np) { + ret = tfa98xx_parse_dt(&i2c->dev, tfa98xx, np); + if (ret) { + dev_err(&i2c->dev, "Failed to parse DT node\n"); + return ret; + } + if (no_start) + tfa98xx->irq_gpio = -1; + if (no_reset) + tfa98xx->reset_gpio = -1; + } else { + tfa98xx->reset_gpio = -1; + tfa98xx->irq_gpio = -1; + } + + if (gpio_is_valid(tfa98xx->reset_gpio)) { + ret = devm_gpio_request_one(&i2c->dev, tfa98xx->reset_gpio, + GPIOF_OUT_INIT_LOW, "TFA98XX_RST"); + if (ret) + return ret; + } + + if (gpio_is_valid(tfa98xx->irq_gpio)) { + ret = devm_gpio_request_one(&i2c->dev, tfa98xx->irq_gpio, + GPIOF_DIR_IN, "TFA98XX_INT"); + if (ret) + return ret; + } + + tfa98xx->spk_id_gpio_p = of_parse_phandle(np, "nxp,spk-id-pin", 0); + + if (!tfa98xx->spk_id_gpio_p) { + dev_err(&i2c->dev, "property %s not detected in node %s", + "nxp,spk-id-pin", np->full_name); + } else { + spk_name = nxp_spk_id_get(tfa98xx->spk_id_gpio_p); + if (spk_name == VENDOR_ID_AAC) { + fw_name = TFA98XX_AAC_FW_NAME; + } + + if (spk_name == VENDOR_ID_GOER) { + fw_name = TFA98XX_GOER_FW_NAME; + } + + dev_err(&i2c->dev, "spk is %d, fw_name =%s\n", spk_name, + fw_name); + } + + /* Power up! */ + tfa98xx_ext_reset(tfa98xx); + + if ((no_start == 0) && (no_reset == 0)) { + ret = regmap_read(tfa98xx->regmap, 0x03, ®); + if (ret < 0) { + dev_err(&i2c->dev, + "Failed to read Revision register: %d\n", ret); + return -EIO; + } + switch (reg & 0xff) { + case 0x72: /* tfa9872 */ + pr_info("TFA9872 detected\n"); + tfa98xx->flags |= TFA98XX_FLAG_MULTI_MIC_INPUTS; + tfa98xx->flags |= TFA98XX_FLAG_CALIBRATION_CTL; + tfa98xx->flags |= TFA98XX_FLAG_REMOVE_PLOP_NOISE; + /* tfa98xx->flags |= TFA98XX_FLAG_LP_MODES; */ + tfa98xx->flags |= TFA98XX_FLAG_TDM_DEVICE; + break; + case 0x74: /* tfa9874 */ + pr_info("TFA9874 detected\n"); + tfa98xx->flags |= TFA98XX_FLAG_MULTI_MIC_INPUTS; + tfa98xx->flags |= TFA98XX_FLAG_CALIBRATION_CTL; + tfa98xx->flags |= TFA98XX_FLAG_TDM_DEVICE; + break; + case 0x88: /* tfa9888 */ + pr_info("TFA9888 detected\n"); + tfa98xx->flags |= TFA98XX_FLAG_STEREO_DEVICE; + tfa98xx->flags |= TFA98XX_FLAG_MULTI_MIC_INPUTS; + tfa98xx->flags |= TFA98XX_FLAG_TDM_DEVICE; + break; + case 0x13: /* tfa9912 */ + pr_info("TFA9912 detected\n"); + tfa98xx->flags |= TFA98XX_FLAG_MULTI_MIC_INPUTS; + tfa98xx->flags |= TFA98XX_FLAG_TDM_DEVICE; + /* tfa98xx->flags |= TFA98XX_FLAG_TAPDET_AVAILABLE; */ + break; + case 0x94: /* tfa9894 */ + pr_info("TFA9894 detected\n"); + tfa98xx->flags |= TFA98XX_FLAG_MULTI_MIC_INPUTS; + tfa98xx->flags |= TFA98XX_FLAG_TDM_DEVICE; + tfa98xx->flags |= TFA98XX_FLAG_SKIP_INTERRUPTS; + break; + case 0x80: /* tfa9890 */ + case 0x81: /* tfa9890 */ + pr_info("TFA9890 detected\n"); + tfa98xx->flags |= TFA98XX_FLAG_SKIP_INTERRUPTS; + break; + case 0x92: /* tfa9891 */ + pr_info("TFA9891 detected\n"); + tfa98xx->flags |= TFA98XX_FLAG_SAAM_AVAILABLE; + tfa98xx->flags |= TFA98XX_FLAG_SKIP_INTERRUPTS; + break; + case 0x12: /* tfa9895 */ + pr_info("TFA9895 detected\n"); + tfa98xx->flags |= TFA98XX_FLAG_SKIP_INTERRUPTS; + break; + case 0x97: + pr_info("TFA9897 detected\n"); + tfa98xx->flags |= TFA98XX_FLAG_SKIP_INTERRUPTS; + tfa98xx->flags |= TFA98XX_FLAG_TDM_DEVICE; + break; + case 0x96: + pr_info("TFA9896 detected\n"); + tfa98xx->flags |= TFA98XX_FLAG_SKIP_INTERRUPTS; + tfa98xx->flags |= TFA98XX_FLAG_TDM_DEVICE; + break; + default: + pr_info("Unsupported device revision (0x%x)\n", + reg & 0xff); + return -EINVAL; + } + } + + tfa98xx->tfa = + devm_kzalloc(&i2c->dev, sizeof(struct tfa_device), GFP_KERNEL); + if (tfa98xx->tfa == NULL) + return -ENOMEM; + + tfa98xx->tfa->data = (void *)tfa98xx; + tfa98xx->tfa->cachep = tfa98xx_cache; + + /* Modify the stream names, by appending the i2c device address. + * This is used with multicodec, in order to discriminate the devices. + * Stream names appear in the dai definition and in the stream . + * We create copies of original structures because each device will + * have its own instance of this structure, with its own address. + */ + dai = devm_kzalloc(&i2c->dev, sizeof(tfa98xx_dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + memcpy(dai, tfa98xx_dai, sizeof(tfa98xx_dai)); + + tfa98xx_append_i2c_address(&i2c->dev, i2c, NULL, 0, dai, + ARRAY_SIZE(tfa98xx_dai)); + + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_tfa98xx, dai, + ARRAY_SIZE(tfa98xx_dai)); + + if (ret < 0) { + dev_err(&i2c->dev, "Failed to register TFA98xx: %d\n", ret); + return ret; + } + + if (gpio_is_valid(tfa98xx->irq_gpio) && + !(tfa98xx->flags & TFA98XX_FLAG_SKIP_INTERRUPTS)) { + /* register irq handler */ + irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; + ret = devm_request_threaded_irq(&i2c->dev, + gpio_to_irq(tfa98xx->irq_gpio), + NULL, tfa98xx_irq, irq_flags, + "tfa98xx", tfa98xx); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n", + gpio_to_irq(tfa98xx->irq_gpio), ret); + return ret; + } + } else { + dev_info(&i2c->dev, "Skipping IRQ registration\n"); + /* disable feature support if gpio was invalid */ + tfa98xx->flags |= TFA98XX_FLAG_SKIP_INTERRUPTS; + } + +#ifdef CONFIG_DEBUG_FS + if (no_start == 0) + tfa98xx_debug_init(tfa98xx, i2c); +#endif + /* Register the sysfs files for climax backdoor access */ + ret = device_create_bin_file(&i2c->dev, &dev_attr_rw); + if (ret) + dev_info(&i2c->dev, "error creating sysfs files\n"); + ret = device_create_bin_file(&i2c->dev, &dev_attr_reg); + if (ret) + dev_info(&i2c->dev, "error creating sysfs files\n"); + if (0 == tfa98xx_device_count) + tfa98xx_init_misc_device(tfa98xx); + pr_info("%s Probe completed successfully!\n", __func__); + + INIT_LIST_HEAD(&tfa98xx->list); + + mutex_lock(&tfa98xx_mutex); + tfa98xx_device_count++; + list_add(&tfa98xx->list, &tfa98xx_device_list); + mutex_unlock(&tfa98xx_mutex); + + return 0; +} + +static int tfa98xx_i2c_remove(struct i2c_client *i2c) +{ + struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c); + + pr_debug("addr=0x%x\n", i2c->addr); + + tfa98xx_interrupt_enable(tfa98xx, false); + + cancel_delayed_work_sync(&tfa98xx->interrupt_work); + cancel_delayed_work_sync(&tfa98xx->monitor_work); + cancel_delayed_work_sync(&tfa98xx->init_work); + cancel_delayed_work_sync(&tfa98xx->tapdet_work); + + device_remove_bin_file(&i2c->dev, &dev_attr_reg); + device_remove_bin_file(&i2c->dev, &dev_attr_rw); +#ifdef CONFIG_DEBUG_FS + tfa98xx_debug_remove(tfa98xx); +#endif + tfa98xx_remove_misc_device(tfa98xx); + + snd_soc_unregister_codec(&i2c->dev); + + if (gpio_is_valid(tfa98xx->irq_gpio)) + devm_gpio_free(&i2c->dev, tfa98xx->irq_gpio); + if (gpio_is_valid(tfa98xx->reset_gpio)) + devm_gpio_free(&i2c->dev, tfa98xx->reset_gpio); + + mutex_lock(&tfa98xx_mutex); + list_del(&tfa98xx->list); + tfa98xx_device_count--; + if (tfa98xx_device_count == 0) { + kfree(tfa98xx_container); + tfa98xx_container = NULL; + } + mutex_unlock(&tfa98xx_mutex); + + return 0; +} + +static const struct i2c_device_id tfa98xx_i2c_id[] = { + { "tfa98xx", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, tfa98xx_i2c_id); + +#ifdef CONFIG_OF +static struct of_device_id tfa98xx_dt_match[] = { + { .compatible = "nxp,tfa98xx" }, { .compatible = "nxp,tfa9872" }, + { .compatible = "nxp,tfa9874" }, { .compatible = "nxp,tfa9888" }, + { .compatible = "nxp,tfa9890" }, { .compatible = "nxp,tfa9891" }, + { .compatible = "nxp,tfa9894" }, { .compatible = "nxp,tfa9895" }, + { .compatible = "nxp,tfa9896" }, { .compatible = "nxp,tfa9897" }, + { .compatible = "nxp,tfa9912" }, {}, +}; +#endif + +static struct i2c_driver tfa98xx_i2c_driver = { + .driver = { + .name = "tfa98xx", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(tfa98xx_dt_match), + }, + .probe = tfa98xx_i2c_probe, + .remove = tfa98xx_i2c_remove, + .id_table = tfa98xx_i2c_id, +}; + +static int __init tfa98xx_i2c_init(void) +{ + int ret = 0; + + pr_info("TFA98XX driver version %s\n", TFA98XX_VERSION); + + /* Enable debug traces */ + tfa98xx_kmsg_regs = trace_level & 2; + tfa98xx_ftrace_regs = trace_level & 4; + + /* Initialize kmem_cache */ + tfa98xx_cache = kmem_cache_create( + "tfa98xx_cache", /* Cache name /proc/slabinfo */ + PAGE_SIZE, /* Structure size, we should fit in single page */ + 0, /* Structure alignment */ + (SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT | + SLAB_MEM_SPREAD), /* Cache property */ + NULL); /* Object constructor */ + if (!tfa98xx_cache) { + pr_err("tfa98xx can't create memory pool\n"); + ret = -ENOMEM; + } + + ret = i2c_add_driver(&tfa98xx_i2c_driver); + + return ret; +} +module_init(tfa98xx_i2c_init); + +static void __exit tfa98xx_i2c_exit(void) +{ + i2c_del_driver(&tfa98xx_i2c_driver); + kmem_cache_destroy(tfa98xx_cache); +} +module_exit(tfa98xx_i2c_exit); + +MODULE_DESCRIPTION("ASoC TFA98XX driver"); +MODULE_LICENSE("GPL"); diff --git a/techpack/audio/asoc/codecs/tfa98xx/src/tfa_container.c b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_container.c new file mode 100644 index 000000000000..7207069dacc2 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_container.c @@ -0,0 +1,2570 @@ +/* + * Copyright 2014-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "dbgprint.h" +#include "tfa_container.h" +#include "tfa.h" +#include "tfa98xx_tfafieldnames.h" +#include "tfa_internal.h" + +/* defines */ +#define MODULE_BIQUADFILTERBANK 2 +#define BIQUAD_COEFF_SIZE 6 + +/* module globals */ +static uint8_t gslave_address = + 0; /* This is used to SET the slave with the --slave option */ + +static int float_to_int(uint32_t x) +{ + unsigned e = (0x7F + 31) - ((*(unsigned *)&x & 0x7F800000) >> 23); + unsigned m = 0x80000000 | (*(unsigned *)&x << 8); + return -(int)((m >> e) & -(e < 32)); +} + +/* + * check the container file +*/ +enum tfa_error tfa_load_cnt(void *cnt, int length) +{ + nxpTfaContainer_t *cntbuf = (nxpTfaContainer_t *)cnt; + + if (length > TFA_MAX_CNT_LENGTH) { + pr_err("incorrect length\n"); + return tfa_error_container; + } + + if (HDR(cntbuf->id[0], cntbuf->id[1]) == 0) { + pr_err("header is 0\n"); + return tfa_error_container; + } + + if ((HDR(cntbuf->id[0], cntbuf->id[1])) != paramsHdr) { + pr_err("wrong header type: 0x%02x 0x%02x\n", cntbuf->id[0], + cntbuf->id[1]); + return tfa_error_container; + } + + if (cntbuf->size == 0) { + pr_err("data size is 0\n"); + return tfa_error_container; + } + + /* check CRC */ + if (tfaContCrcCheckContainer(cntbuf)) { + pr_err("CRC error\n"); + return tfa_error_container; + } + + /* check sub version level */ + if ((cntbuf->subversion[1] != NXPTFA_PM_SUBVERSION) && + (cntbuf->subversion[0] != '0')) { + pr_err("container sub-version not supported: %c%c\n", + cntbuf->subversion[0], cntbuf->subversion[1]); + return tfa_error_container; + } + + return tfa_error_ok; +} + +/* + * Dump the contents of the file header + */ +void tfaContShowHeader(nxpTfaHeader_t *hdr) +{ + char _id[2]; + + pr_debug("File header\n"); + + _id[1] = hdr->id >> 8; + _id[0] = hdr->id & 0xff; + pr_debug("\tid:%.2s version:%.2s subversion:%.2s\n", _id, hdr->version, + hdr->subversion); + pr_debug("\tsize:%d CRC:0x%08x \n", hdr->size, hdr->CRC); + pr_debug("\tcustomer:%.8s application:%.8s type:%.8s\n", hdr->customer, + hdr->application, hdr->type); +} + +/* + * return device list dsc from index + */ +nxpTfaDeviceList_t *tfaContGetDevList(nxpTfaContainer_t *cont, int dev_idx) +{ + uint8_t *base = (uint8_t *)cont; + + if (cont == NULL) + return NULL; + + if ((dev_idx < 0) || (dev_idx >= cont->ndev)) + return NULL; + + if (cont->index[dev_idx].type != dscDevice) + return NULL; + + base += cont->index[dev_idx].offset; + return (nxpTfaDeviceList_t *)base; +} + +/* + * get the Nth profile for the Nth device + */ +nxpTfaProfileList_t *tfaContGetDevProfList(nxpTfaContainer_t *cont, int devIdx, + int profIdx) +{ + nxpTfaDeviceList_t *dev; + int idx, hit; + uint8_t *base = (uint8_t *)cont; + + dev = tfaContGetDevList(cont, devIdx); + if (dev) { + for (idx = 0, hit = 0; idx < dev->length; idx++) { + if (dev->list[idx].type == dscProfile) { + if (profIdx == hit++) + return (nxpTfaProfileList_t + *)(dev->list[idx].offset + + base); + } + } + } + + return NULL; +} + +/* + * get the number of profiles for the Nth device + */ +int tfa_cnt_get_dev_nprof(struct tfa_device *tfa) +{ + nxpTfaDeviceList_t *dev; + int idx, nprof = 0; + + if (tfa->cnt == NULL) + return 0; + + if ((tfa->dev_idx < 0) || (tfa->dev_idx >= tfa->cnt->ndev)) + return 0; + + dev = tfaContGetDevList(tfa->cnt, tfa->dev_idx); + if (dev) { + for (idx = 0; idx < dev->length; idx++) { + if (dev->list[idx].type == dscProfile) { + nprof++; + } + } + } + + return nprof; +} + +/* + * get the Nth lifedata for the Nth device + */ +nxpTfaLiveDataList_t *tfaContGetDevLiveDataList(nxpTfaContainer_t *cont, + int devIdx, int lifeDataIdx) +{ + nxpTfaDeviceList_t *dev; + int idx, hit; + uint8_t *base = (uint8_t *)cont; + + dev = tfaContGetDevList(cont, devIdx); + if (dev) { + for (idx = 0, hit = 0; idx < dev->length; idx++) { + if (dev->list[idx].type == dscLiveData) { + if (lifeDataIdx == hit++) + return (nxpTfaLiveDataList_t + *)(dev->list[idx].offset + + base); + } + } + } + + return NULL; +} + +/* + * Get the max volume step associated with Nth profile for the Nth device + */ +int tfacont_get_max_vstep(struct tfa_device *tfa, int prof_idx) +{ + nxpTfaVolumeStep2File_t *vp; + struct nxpTfaVolumeStepMax2File *vp3; + int vstep_count = 0; + vp = (nxpTfaVolumeStep2File_t *)tfacont_getfiledata(tfa, prof_idx, + volstepHdr); + if (vp == NULL) + return 0; + /* check the header type to load different NrOfVStep appropriately */ + if (tfa->tfa_family == 2) { + /* this is actually tfa2, so re-read the buffer*/ + vp3 = (struct nxpTfaVolumeStepMax2File *)tfacont_getfiledata( + tfa, prof_idx, volstepHdr); + if (vp3) { + vstep_count = vp3->NrOfVsteps; + } + } else { + /* this is max1*/ + if (vp) { + vstep_count = vp->vsteps; + } + } + return vstep_count; +} + +/** + * Get the file contents associated with the device or profile + * Search within the device tree, if not found, search within the profile + * tree. There can only be one type of file within profile or device. + */ +nxpTfaFileDsc_t *tfacont_getfiledata(struct tfa_device *tfa, int prof_idx, + enum nxpTfaHeaderType type) +{ + nxpTfaDeviceList_t *dev; + nxpTfaProfileList_t *prof; + nxpTfaFileDsc_t *file; + nxpTfaHeader_t *hdr; + unsigned int i; + + if (tfa->cnt == NULL) { + pr_err("invalid pointer to container file\n"); + return NULL; + } + + dev = tfaContGetDevList(tfa->cnt, tfa->dev_idx); + if (dev == NULL) { + pr_err("invalid pointer to container file device list\n"); + return NULL; + } + + /* process the device list until a file type is encountered */ + for (i = 0; i < dev->length; i++) { + if (dev->list[i].type == dscFile) { + file = (nxpTfaFileDsc_t *)(dev->list[i].offset + + (uint8_t *)tfa->cnt); + if (file != NULL) { + hdr = (nxpTfaHeader_t *)file->data; + /* check for file type */ + if (hdr->id == type) { + return (nxpTfaFileDsc_t *)&file->data; + } + } + } + } + + /* File not found in device tree. + * So, look in the profile list until the file type is encountered + */ + prof = tfaContGetDevProfList(tfa->cnt, tfa->dev_idx, prof_idx); + if (prof == NULL) { + pr_err("invalid pointer to container file profile list\n"); + return NULL; + } + + for (i = 0; i < prof->length; i++) { + if (prof->list[i].type == dscFile) { + file = (nxpTfaFileDsc_t *)(prof->list[i].offset + + (uint8_t *)tfa->cnt); + if (file != NULL) { + hdr = (nxpTfaHeader_t *)file->data; + if (hdr != NULL) { + /* check for file type */ + if (hdr->id == type) { + return (nxpTfaFileDsc_t *)&file + ->data; + } + } + } + } + } + + if (tfa->verbose) + pr_debug("%s: no file found of type %d\n", __FUNCTION__, type); + + return NULL; +} + +/* + * write a parameter file to the device + */ +static enum Tfa98xx_Error tfaContWriteVstep(struct tfa_device *tfa, + nxpTfaVolumeStep2File_t *vp, + int vstep) +{ + enum Tfa98xx_Error err; + unsigned short vol; + + if (vstep < vp->vsteps) { + /* vol = (unsigned short)(voldB / (-0.5f)); */ + vol = (unsigned short)(-2 * + float_to_int( + *((uint32_t *)&vp->vstep[vstep] + .attenuation))); + if (vol > 255) /* restricted to 8 bits */ + vol = 255; + + err = tfa98xx_set_volume_level(tfa, vol); + if (err != Tfa98xx_Error_Ok) + return err; + + err = tfa98xx_dsp_write_preset(tfa, sizeof(vp->vstep[0].preset), + vp->vstep[vstep].preset); + if (err != Tfa98xx_Error_Ok) + return err; + err = tfa_cont_write_filterbank(tfa, vp->vstep[vstep].filter); + + } else { + pr_err("Incorrect volume given. The value vstep[%d] >= %d\n", + vstep, vp->vsteps); + err = Tfa98xx_Error_Bad_Parameter; + } + + if (tfa->verbose) + pr_debug("vstep[%d][%d]\n", tfa->dev_idx, vstep); + + return err; +} + +static struct nxpTfaVolumeStepMessageInfo * +tfaContGetmsgInfoFromReg(struct nxpTfaVolumeStepRegisterInfo *regInfo) +{ + char *p = (char *)regInfo; + p += sizeof(regInfo->NrOfRegisters) + + (regInfo->NrOfRegisters * sizeof(uint32_t)); + return (struct nxpTfaVolumeStepMessageInfo *)p; +} + +static int tfaContGetmsgLen(struct nxpTfaVolumeStepMessageInfo *msgInfo) +{ + return (msgInfo->MessageLength.b[0] << 16) + + (msgInfo->MessageLength.b[1] << 8) + msgInfo->MessageLength.b[2]; +} + +static struct nxpTfaVolumeStepMessageInfo * +tfaContGetNextmsgInfo(struct nxpTfaVolumeStepMessageInfo *msgInfo) +{ + char *p = (char *)msgInfo; + int msgLen = tfaContGetmsgLen(msgInfo); + int type = msgInfo->MessageType; + + p += sizeof(msgInfo->MessageType) + sizeof(msgInfo->MessageLength); + if (type == 3) + p += msgLen; + else + p += msgLen * 3; + + return (struct nxpTfaVolumeStepMessageInfo *)p; +} + +static struct nxpTfaVolumeStepRegisterInfo * +tfaContGetNextRegFromEndInfo(struct nxpTfaVolumeStepMessageInfo *msgInfo) +{ + char *p = (char *)msgInfo; + p += sizeof(msgInfo->NrOfMessages); + return (struct nxpTfaVolumeStepRegisterInfo *)p; +} + +static struct nxpTfaVolumeStepRegisterInfo * +tfaContGetRegForVstep(nxpTfaVolumeStepMax2File_t *vp, int idx) +{ + int i, j, nrMessage; + + struct nxpTfaVolumeStepRegisterInfo *regInfo = + (struct nxpTfaVolumeStepRegisterInfo *)vp->vstepsBin; + struct nxpTfaVolumeStepMessageInfo *msgInfo = NULL; + + for (i = 0; i < idx; i++) { + msgInfo = tfaContGetmsgInfoFromReg(regInfo); + nrMessage = msgInfo->NrOfMessages; + + for (j = 0; j < nrMessage; j++) { + msgInfo = tfaContGetNextmsgInfo(msgInfo); + } + regInfo = tfaContGetNextRegFromEndInfo(msgInfo); + } + + return regInfo; +} + +#pragma pack(push, 1) +struct tfa_partial_msg_block { + uint8_t offset; + uint16_t change; + uint8_t update[16][3]; +}; +#pragma pack(pop) + +static enum Tfa98xx_Error tfaContWriteVstepMax2_One( + struct tfa_device *tfa, struct nxpTfaVolumeStepMessageInfo *new_msg, + struct nxpTfaVolumeStepMessageInfo *old_msg, int enable_partial_update) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + int len = (tfaContGetmsgLen(new_msg) - 1) * 3; + char *buf = (char *)new_msg->ParameterData; + uint8_t *partial = NULL; + uint8_t cmdid[3]; + int use_partial_coeff = 0; + + if (enable_partial_update) { + if (new_msg->MessageType != old_msg->MessageType) { + pr_debug( + "Message type differ - Disable Partial Update\n"); + enable_partial_update = 0; + } else if (tfaContGetmsgLen(new_msg) != + tfaContGetmsgLen(old_msg)) { + pr_debug( + "Message Length differ - Disable Partial Update\n"); + enable_partial_update = 0; + } + } + + if ((enable_partial_update) && (new_msg->MessageType == 1)) { + /* No patial updates for message type 1 (Coefficients) */ + enable_partial_update = 0; + if ((tfa->rev & 0xff) == 0x88) { + use_partial_coeff = 1; + } else if ((tfa->rev & 0xff) == 0x13) { + use_partial_coeff = 1; + } + } + + /* Change Message Len to the actual buffer len */ + memcpy(cmdid, new_msg->CmdId, sizeof(cmdid)); + + /* The algoparams and mbdrc msg id will be changed to the reset type when SBSL=0 + * if SBSL=1 the msg will remain unchanged. It's up to the tuning engineer to choose the 'without_reset' + * types inside the vstep. In other words: the reset msg is applied during SBSL==0 else it remains unchanged. + */ + if (tfa_needs_reset(tfa) == 1) { + if (new_msg->MessageType == 0) { + cmdid[2] = SB_PARAM_SET_ALGO_PARAMS; + if (tfa->verbose) + pr_debug("P-ID for SetAlgoParams modified!\n"); + } else if (new_msg->MessageType == 2) { + cmdid[2] = SB_PARAM_SET_MBDRC; + if (tfa->verbose) + pr_debug("P-ID for SetMBDrc modified!\n"); + } + } + + /* + * +sizeof(struct tfa_partial_msg_block) will allow to fit one + * additonnal partial block If the partial update goes over the len of + * a regular message ,we can safely write our block and check afterward + * that we are over the size of a usual update + */ + if (enable_partial_update) { + partial = kmem_cache_alloc(tfa->cachep, GFP_KERNEL); + if (!partial) + pr_debug("Partial update memory error - Disabling\n"); + } + + if (partial) { + uint8_t offset = 0, i = 0; + uint16_t *change; + uint8_t *n = new_msg->ParameterData; + uint8_t *o = old_msg->ParameterData; + uint8_t *p = partial; + uint8_t *trim = partial; + + /* set dspFiltersReset */ + *p++ = 0x02; + *p++ = 0x00; + *p++ = 0x00; + + while ((o < (old_msg->ParameterData + len)) && + (p < (partial + len - 3))) { + if ((offset == 0xff) || + (memcmp(n, o, 3 * sizeof(uint8_t)))) { + *p++ = offset; + change = (uint16_t *)p; + *change = 0; + p += 2; + + for (i = 0; + (i < 16) && + (o < (old_msg->ParameterData + len)); + i++, n += 3, o += 3) { + if (memcmp(n, o, 3 * sizeof(uint8_t))) { + *change |= BIT(i); + memcpy(p, n, 3); + p += 3; + trim = p; + } + } + + offset = 0; + *change = cpu_to_be16(*change); + } else { + n += 3; + o += 3; + offset++; + } + } + + if (trim == partial) { + pr_debug("No Change in message - discarding %d bytes\n", + len); + len = 0; + + } else if (trim < (partial + len - 3)) { + pr_debug("Using partial update: %d -> %d bytes\n", len, + (int)(trim - partial + 3)); + + /* Add the termination marker */ + memset(trim, 0x00, 3); + trim += 3; + + /* Signal This will be a partial update */ + cmdid[2] |= BIT(6); + buf = (char *)partial; + len = (int)(trim - partial); + } else { + pr_debug("Partial too big - use regular update\n"); + } + } + + if (use_partial_coeff) { + err = dsp_partial_coefficients(tfa, old_msg->ParameterData, + new_msg->ParameterData); + } else if (len) { + uint8_t *buffer; + + if (tfa->verbose) + pr_debug("Command-ID used: 0x%02x%02x%02x \n", cmdid[0], + cmdid[1], cmdid[2]); + + buffer = kmem_cache_alloc(tfa->cachep, GFP_KERNEL); + if (buffer == NULL) { + err = Tfa98xx_Error_Fail; + } else { + memcpy(&buffer[0], cmdid, 3); + memcpy(&buffer[3], buf, len); + err = dsp_msg(tfa, 3 + len, (char *)buffer); + kmem_cache_free(tfa->cachep, buffer); + } + } + + if (partial) + kmem_cache_free(tfa->cachep, partial); + + return err; +} + +static enum Tfa98xx_Error tfaContWriteVstepMax2(struct tfa_device *tfa, + nxpTfaVolumeStepMax2File_t *vp, + int vstep_idx, + int vstep_msg_idx) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + struct nxpTfaVolumeStepRegisterInfo *regInfo = NULL; + struct nxpTfaVolumeStepMessageInfo *msgInfo = NULL, *p_msgInfo = NULL; + nxpTfaBitfield_t bitF; + int i, nrMessages, enp = tfa->partial_enable; + + if (vstep_idx >= vp->NrOfVsteps) { + pr_debug("Volumestep %d is not available \n", vstep_idx); + return Tfa98xx_Error_Bad_Parameter; + } + + if (tfa->p_regInfo == NULL) { + if (tfa->verbose) + pr_debug("Inital vstep write\n"); + enp = 0; + } + + regInfo = tfaContGetRegForVstep(vp, vstep_idx); + + msgInfo = tfaContGetmsgInfoFromReg(regInfo); + nrMessages = msgInfo->NrOfMessages; + + if (enp) { + p_msgInfo = tfaContGetmsgInfoFromReg(tfa->p_regInfo); + if (nrMessages != p_msgInfo->NrOfMessages) { + pr_debug( + "Message different - Disable partial update\n"); + enp = 0; + } + } + + for (i = 0; i < nrMessages; i++) { + /* Messagetype(3) is Smartstudio Info! Dont send this! */ + if (msgInfo->MessageType == 3) { + /* MessageLength is in bytes */ + msgInfo = tfaContGetNextmsgInfo(msgInfo); + if (enp) + p_msgInfo = tfaContGetNextmsgInfo(p_msgInfo); + continue; + } + + /* If no vstepMsgIndex is passed on, all message needs to be send */ + if ((vstep_msg_idx >= TFA_MAX_VSTEP_MSG_MARKER) || + (vstep_msg_idx == i)) { + err = tfaContWriteVstepMax2_One(tfa, msgInfo, p_msgInfo, + enp); + if (err != Tfa98xx_Error_Ok) { + /* + * Force a full update for the next write + * As the current status of the DSP is unknown + */ + tfa->p_regInfo = NULL; + return err; + } + } + + msgInfo = tfaContGetNextmsgInfo(msgInfo); + if (enp) + p_msgInfo = tfaContGetNextmsgInfo(p_msgInfo); + } + + tfa->p_regInfo = regInfo; + + for (i = 0; i < regInfo->NrOfRegisters * 2; i++) { + /* Byte swap the datasheetname */ + bitF.field = (uint16_t)(regInfo->registerInfo[i] >> 8) | + (regInfo->registerInfo[i] << 8); + i++; + bitF.value = (uint16_t)regInfo->registerInfo[i] >> 8; + err = tfaRunWriteBitfield(tfa, bitF); + if (err != Tfa98xx_Error_Ok) + return err; + } + + /* Save the current vstep */ + tfa_dev_set_swvstep(tfa, (unsigned short)vstep_idx); + + return err; +} + +/* + * Write DRC message to the dsp + * If needed modify the cmd-id + */ + +enum Tfa98xx_Error tfaContWriteDrcFile(struct tfa_device *tfa, int size, + uint8_t data[]) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + uint8_t *msg = NULL; + + msg = kmem_cache_alloc(tfa->cachep, GFP_KERNEL); + if (msg == NULL) + return Tfa98xx_Error_Fail; + memcpy(msg, data, size); + + if (TFA_GET_BF(tfa, SBSL) == 0) { + /* Only do this when not set already */ + if (msg[2] != SB_PARAM_SET_MBDRC) { + msg[2] = SB_PARAM_SET_MBDRC; + + if (tfa->verbose) { + pr_debug("P-ID for SetMBDrc modified!: "); + pr_debug("Command-ID used: 0x%02x%02x%02x \n", + msg[0], msg[1], msg[2]); + } + } + } + + /* Send cmdId + payload to dsp */ + err = dsp_msg(tfa, size, (const char *)msg); + + kmem_cache_free(tfa->cachep, msg); + + return err; +} + +/* + * write a parameter file to the device + * The VstepIndex and VstepMsgIndex are only used to write a specific msg from the vstep file. + */ +enum Tfa98xx_Error tfaContWriteFile(struct tfa_device *tfa, + nxpTfaFileDsc_t *file, int vstep_idx, + int vstep_msg_idx) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + nxpTfaHeader_t *hdr = (nxpTfaHeader_t *)file->data; + nxpTfaHeaderType_t type; + int size; + + if (tfa->verbose) { + tfaContShowHeader(hdr); + } + + type = (nxpTfaHeaderType_t)hdr->id; + + switch (type) { + case msgHdr: /* generic DSP message */ + size = hdr->size - sizeof(nxpTfaMsgFile_t); + err = dsp_msg(tfa, size, + (const char *)((nxpTfaMsgFile_t *)hdr)->data); + break; + case volstepHdr: + if (tfa->tfa_family == 2) { + err = tfaContWriteVstepMax2( + tfa, (nxpTfaVolumeStepMax2File_t *)hdr, + vstep_idx, vstep_msg_idx); + } else { + err = tfaContWriteVstep( + tfa, (nxpTfaVolumeStep2File_t *)hdr, vstep_idx); + } + break; + case speakerHdr: + if (tfa->tfa_family == 2) { + /* Remove header and xml_id */ + size = hdr->size - sizeof(struct nxpTfaSpkHeader) - + sizeof(struct nxpTfaFWVer); + + err = dsp_msg( + tfa, size, + (const char *)(((nxpTfaSpeakerFile_t *)hdr) + ->data + + (sizeof(struct nxpTfaFWVer)))); + } else { + size = hdr->size - sizeof(nxpTfaSpeakerFile_t); + err = tfa98xx_dsp_write_speaker_parameters( + tfa, size, + (const unsigned char *)((nxpTfaSpeakerFile_t *) + hdr) + ->data); + } + break; + case presetHdr: + size = hdr->size - sizeof(nxpTfaPreset_t); + err = tfa98xx_dsp_write_preset( + tfa, size, + (const unsigned char *)((nxpTfaPreset_t *)hdr)->data); + break; + case equalizerHdr: + err = tfa_cont_write_filterbank( + tfa, ((nxpTfaEqualizerFile_t *)hdr)->filter); + break; + case patchHdr: + size = hdr->size - + sizeof(nxpTfaPatch_t); // size is total length + err = tfa_dsp_patch( + tfa, size, + (const unsigned char *)((nxpTfaPatch_t *)hdr)->data); + break; + case configHdr: + size = hdr->size - sizeof(nxpTfaConfig_t); + err = tfa98xx_dsp_write_config( + tfa, size, + (const unsigned char *)((nxpTfaConfig_t *)hdr)->data); + break; + case drcHdr: + if (hdr->version[0] == NXPTFA_DR3_VERSION) { + /* Size is total size - hdrsize(36) - xmlversion(3) */ + size = hdr->size - sizeof(nxpTfaDrc2_t); + err = tfaContWriteDrcFile(tfa, size, + ((nxpTfaDrc2_t *)hdr)->data); + } else { + /* + * The DRC file is split as: + * 36 bytes for generic header (customer, application, and type) + * 127x3 (381) bytes first block contains the device and sample rate + * independent settings + * 127x3 (381) bytes block the device and sample rate specific values. + * The second block can always be recalculated from the first block, + * if vlsCal and the sample rate are known. + */ + //size = hdr->size - sizeof(nxpTfaDrc_t); + size = 381; /* fixed size for first block */ + + //+381 is done to only send the second part of the drc block + err = tfa98xx_dsp_write_drc( + tfa, size, + ((const unsigned char *)((nxpTfaDrc_t *)hdr) + ->data + + 381)); + } + break; + case infoHdr: + /* Ignore */ + break; + default: + pr_err("Header is of unknown type: 0x%x\n", type); + return Tfa98xx_Error_Bad_Parameter; + } + + return err; +} + +/** + * get the 1st of this dsc type this devicelist + */ +static nxpTfaDescPtr_t *tfa_cnt_get_dsc(nxpTfaContainer_t *cnt, + nxpTfaDescriptorType_t type, + int dev_idx) +{ + nxpTfaDeviceList_t *dev = tfaContDevice(cnt, dev_idx); + nxpTfaDescPtr_t *_this; + int i; + + if (!dev) { + return NULL; + } + /* process the list until a the type is encountered */ + for (i = 0; i < dev->length; i++) { + if (dev->list[i].type == (uint32_t)type) { + _this = (nxpTfaDescPtr_t *)(dev->list[i].offset + + (uint8_t *)cnt); + return _this; + } + } + + return NULL; +} + +/** + * get the device type from the patch in this devicelist + * - find the patch file for this devidx + * - return the devid from the patch or 0 if not found + */ +int tfa_cnt_get_devid(nxpTfaContainer_t *cnt, int dev_idx) +{ + nxpTfaPatch_t *patchfile; + nxpTfaDescPtr_t *patchdsc; + uint8_t *patchheader; + unsigned short devid, checkaddress; + int checkvalue; + + patchdsc = tfa_cnt_get_dsc(cnt, dscPatch, dev_idx); + if (!patchdsc) /* no patch for this device, assume non-i2c */ + return 0; + patchdsc += 2; /* first the filename dsc and filesize, so skip them */ + patchfile = (nxpTfaPatch_t *)patchdsc; + + patchheader = patchfile->data; + + checkaddress = (patchheader[1] << 8) + patchheader[2]; + checkvalue = + (patchheader[3] << 16) + (patchheader[4] << 8) + patchheader[5]; + + devid = patchheader[0]; + + if (checkaddress == 0xFFFF && checkvalue != 0xFFFFFF && + checkvalue != 0) { + devid = patchheader[5] << 8 | patchheader[0]; /* full revid */ + } + + return devid; +} + +/** + * get the firmware version from the patch in this devicelist + */ +int tfa_cnt_get_patch_version(struct tfa_device *tfa) +{ + nxpTfaPatch_t *patchfile; + nxpTfaDescPtr_t *patchdsc; + uint8_t *data; + int size, version; + + if (tfa->cnt == NULL) + return -1; + + patchdsc = tfa_cnt_get_dsc(tfa->cnt, dscPatch, tfa->dev_idx); + patchdsc += 2; /* first the filename dsc and filesize, so skip them */ + patchfile = (nxpTfaPatch_t *)patchdsc; + + size = patchfile->hdr.size - sizeof(nxpTfaPatch_t); + data = patchfile->data; + + version = + (data[size - 3] << 16) + (data[size - 2] << 8) + data[size - 1]; + + return version; +} + +/* + * get the slave for the device if it exists + */ +enum Tfa98xx_Error tfaContGetSlave(struct tfa_device *tfa, uint8_t *slave_addr) +{ + nxpTfaDeviceList_t *dev = NULL; + + /* Make sure the cnt file is loaded */ + if (tfa->cnt != NULL) { + dev = tfaContDevice(tfa->cnt, tfa->dev_idx); + } + + if (dev == NULL) { + /* Check if slave argument is used! */ + if (gslave_address == 0) { + return Tfa98xx_Error_Bad_Parameter; + } else { + *slave_addr = gslave_address; + return Tfa98xx_Error_Ok; + } + } + + *slave_addr = dev->dev; + return Tfa98xx_Error_Ok; +} + +/* If no container file is given, we can always have used the slave argument */ +void tfaContSetSlave(uint8_t slave_addr) +{ + gslave_address = slave_addr; +} + +/* + * lookup slave and return device index + */ +int tfa_cont_get_idx(struct tfa_device *tfa) +{ + nxpTfaDeviceList_t *dev = NULL; + int i; + + for (i = 0; i < tfa->cnt->ndev; i++) { + dev = tfaContDevice(tfa->cnt, i); + if (dev->dev == tfa->slave_address) + break; + } + if (i == tfa->cnt->ndev) + return -1; + + return i; +} + +/* + * write a bit field + */ +enum Tfa98xx_Error tfaRunWriteBitfield(struct tfa_device *tfa, + nxpTfaBitfield_t bf) +{ + enum Tfa98xx_Error error; + uint16_t value; + union { + uint16_t field; + nxpTfaBfEnum_t Enum; + } bfUni; + + value = bf.value; + bfUni.field = bf.field; +#ifdef TFA_DEBUG + if (tfa->verbose) + pr_debug("bitfield: %s=0x%x (0x%x[%d..%d]=0x%x)\n", + tfaContBfName(bfUni.field, tfa->rev), value, + bfUni.Enum.address, bfUni.Enum.pos, + bfUni.Enum.pos + bfUni.Enum.len, value); +#endif + error = tfa_set_bf(tfa, bfUni.field, value); + + return error; +} + +/* + * read a bit field + */ +enum Tfa98xx_Error tfaRunReadBitfield(struct tfa_device *tfa, + nxpTfaBitfield_t *bf) +{ + enum Tfa98xx_Error error; + union { + uint16_t field; + nxpTfaBfEnum_t Enum; + } bfUni; + uint16_t regvalue, msk; + + bfUni.field = bf->field; + + error = reg_read(tfa, (unsigned char)(bfUni.Enum.address), ®value); + if (error) + return error; + + msk = ((1 << (bfUni.Enum.len + 1)) - 1) << bfUni.Enum.pos; + + regvalue &= msk; + bf->value = regvalue >> bfUni.Enum.pos; + + return error; +} + +/* + dsp mem direct write + */ +static enum Tfa98xx_Error tfaRunWriteDspMem(struct tfa_device *tfa, + nxpTfaDspMem_t *cfmem) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + int i; + + for (i = 0; i < cfmem->size; i++) { + if (tfa->verbose) + pr_debug("dsp mem (%d): 0x%02x=0x%04x\n", cfmem->type, + cfmem->address, cfmem->words[i]); + + error = mem_write(tfa, cfmem->address++, cfmem->words[i], + cfmem->type); + if (error) + return error; + } + + return error; +} + +/* + * write filter payload to DSP + * note that the data is in an aligned union for all filter variants + * the aa data is used but it's the same for all of them + */ +static enum Tfa98xx_Error tfaRunWriteFilter(struct tfa_device *tfa, + nxpTfaContBiquad_t *bq) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + enum Tfa98xx_DMEM dmem; + uint16_t address; + uint8_t data[3 * 3 + sizeof(bq->aa.bytes)]; + int i, channel = 0, runs = 1; + int8_t saved_index = + bq->aa.index; /* This is used to set back the index */ + + /* Channel=1 is primary, Channel=2 is secondary*/ + if (bq->aa.index > 100) { + bq->aa.index -= 100; + channel = 2; + } else if (bq->aa.index > 50) { + bq->aa.index -= 50; + channel = 1; + } else if ((tfa->rev & 0xff) == 0x88) { + runs = 2; + } + + if (tfa->verbose) { + if (channel == 2) + pr_debug("filter[%d,S]", bq->aa.index); + else if (channel == 1) + pr_debug("filter[%d,P]", bq->aa.index); + else + pr_debug("filter[%d]", bq->aa.index); + } + + for (i = 0; i < runs; i++) { + if (runs == 2) + channel++; + + /* get the target address for the filter on this device */ + dmem = tfa98xx_filter_mem(tfa, bq->aa.index, &address, channel); + if (dmem == Tfa98xx_DMEM_ERR) { + if (tfa->verbose) { + pr_debug( + "Warning: XFilter settings are applied via msg file (ini filter[x] format is skipped).\n"); + } + /* Dont exit with an error here, We could continue without problems */ + return Tfa98xx_Error_Ok; + } + + /* send a DSP memory message that targets the devices specific memory for the filter + * msg params: which_mem, start_offset, num_words + */ + memset(data, 0, 3 * 3); + data[2] = dmem; /* output[0] = which_mem */ + data[4] = address >> 8; /* output[1] = start_offset */ + data[5] = address & 0xff; + data[8] = sizeof(bq->aa.bytes) / 3; /*output[2] = num_words */ + memcpy(&data[9], bq->aa.bytes, + sizeof(bq->aa.bytes)); /* payload */ + + if (tfa->tfa_family == 2) { + error = tfa_dsp_cmd_id_write(tfa, MODULE_FRAMEWORK, + FW_PAR_ID_SET_MEMORY, + sizeof(data), data); + } else { + error = tfa_dsp_cmd_id_write(tfa, MODULE_FRAMEWORK, + 4 /* param */, + sizeof(data), data); + } + } + +#ifdef TFA_DEBUG + if (tfa->verbose) { + if (bq->aa.index == 13) { + pr_debug("=%d,%.0f,%.2f \n", bq->in.type, + bq->in.cutOffFreq, bq->in.leakage); + } else if (bq->aa.index >= 10 && bq->aa.index <= 12) { + pr_debug("=%d,%.0f,%.1f,%.1f \n", bq->aa.type, + bq->aa.cutOffFreq, bq->aa.rippleDb, + bq->aa.rolloff); + } else { + pr_debug("= unsupported filter index \n"); + } + } +#endif + + /* Because we can load the same filters multiple times + * For example: When we switch profile we re-write in operating mode. + * We then need to remember the index (primary, secondary or both) + */ + bq->aa.index = saved_index; + + return error; +} + +/* + * write the register based on the input address, value and mask + * only the part that is masked will be updated + */ +static enum Tfa98xx_Error tfaRunWriteRegister(struct tfa_device *tfa, + nxpTfaRegpatch_t *reg) +{ + enum Tfa98xx_Error error; + uint16_t value, newvalue; + + if (tfa->verbose) + pr_debug("register: 0x%02x=0x%04x (msk=0x%04x)\n", reg->address, + reg->value, reg->mask); + + error = reg_read(tfa, reg->address, &value); + if (error) + return error; + + value &= ~reg->mask; + newvalue = reg->value & reg->mask; + + value |= newvalue; + error = reg_write(tfa, reg->address, value); + + return error; +} + +// write reg and bitfield items in the devicelist to the target +enum Tfa98xx_Error tfaContWriteRegsDev(struct tfa_device *tfa) +{ + nxpTfaDeviceList_t *dev = tfaContDevice(tfa->cnt, tfa->dev_idx); + nxpTfaBitfield_t *bitF; + int i; + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + + if (!dev) { + return Tfa98xx_Error_Bad_Parameter; + } + + /* process the list until a patch, file of profile is encountered */ + for (i = 0; i < dev->length; i++) { + if (dev->list[i].type == dscPatch || + dev->list[i].type == dscFile || + dev->list[i].type == dscProfile) + break; + + if (dev->list[i].type == dscBitfield) { + bitF = (nxpTfaBitfield_t *)(dev->list[i].offset + + (uint8_t *)tfa->cnt); + err = tfaRunWriteBitfield(tfa, *bitF); + } + if (dev->list[i].type == dscRegister) { + err = tfaRunWriteRegister( + tfa, (nxpTfaRegpatch_t *)(dev->list[i].offset + + (char *)tfa->cnt)); + } + + if (err) + break; + } + + return err; +} + +// write reg and bitfield items in the profilelist the target +enum Tfa98xx_Error tfaContWriteRegsProf(struct tfa_device *tfa, int prof_idx) +{ + nxpTfaProfileList_t *prof = + tfaContGetDevProfList(tfa->cnt, tfa->dev_idx, prof_idx); + nxpTfaBitfield_t *bitf; + unsigned int i; + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + + if (!prof) { + return Tfa98xx_Error_Bad_Parameter; + } + + if (tfa->verbose) + pr_debug("----- profile: %s (%d) -----\n", + tfaContGetString(tfa->cnt, &prof->name), prof_idx); + + /* process the list until the end of the profile or the default section */ + for (i = 0; i < prof->length; i++) { + /* We only want to write the values before the default section when we switch profile */ + if (prof->list[i].type == dscDefault) + break; + + if (prof->list[i].type == dscBitfield) { + bitf = (nxpTfaBitfield_t *)(prof->list[i].offset + + (uint8_t *)tfa->cnt); + err = tfaRunWriteBitfield(tfa, *bitf); + } + if (prof->list[i].type == dscRegister) { + err = tfaRunWriteRegister( + tfa, (nxpTfaRegpatch_t *)(prof->list[i].offset + + (char *)tfa->cnt)); + } + if (err) + break; + } + return err; +} + +// write patchfile in the devicelist to the target +enum Tfa98xx_Error tfaContWritePatch(struct tfa_device *tfa) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + nxpTfaDeviceList_t *dev = tfaContDevice(tfa->cnt, tfa->dev_idx); + nxpTfaFileDsc_t *file; + nxpTfaPatch_t *patchfile; + int size, i; + + if (!dev) { + return Tfa98xx_Error_Bad_Parameter; + } + /* process the list until a patch is encountered */ + for (i = 0; i < dev->length; i++) { + if (dev->list[i].type == dscPatch) { + file = (nxpTfaFileDsc_t *)(dev->list[i].offset + + (uint8_t *)tfa->cnt); + patchfile = (nxpTfaPatch_t *)&file->data; + if (tfa->verbose) + tfaContShowHeader(&patchfile->hdr); + size = patchfile->hdr.size - + sizeof(nxpTfaPatch_t); // size is total length + err = tfa_dsp_patch( + tfa, size, + (const unsigned char *)patchfile->data); + if (err) + return err; + } + } + + return Tfa98xx_Error_Ok; +} + +/** + * Create a buffer which can be used to send to the dsp. + */ +static void create_dsp_buffer_msg(struct tfa_device *tfa, nxpTfaMsg_t *msg, + char *buffer, int *size) +{ + int i, nr = 0; + + (void)tfa; + + /* Copy cmdId. Remember that the cmdId is reversed */ + buffer[nr++] = msg->cmdId[2]; + buffer[nr++] = msg->cmdId[1]; + buffer[nr++] = msg->cmdId[0]; + + /* Copy the data to the buffer */ + for (i = 0; i < msg->msg_size; i++) { + buffer[nr++] = (uint8_t)((msg->data[i] >> 16) & 0xffff); + buffer[nr++] = (uint8_t)((msg->data[i] >> 8) & 0xff); + buffer[nr++] = (uint8_t)(msg->data[i] & 0xff); + } + + *size = nr; +} + +// write all param files in the devicelist to the target +enum Tfa98xx_Error tfaContWriteFiles(struct tfa_device *tfa) +{ + nxpTfaDeviceList_t *dev = tfaContDevice(tfa->cnt, tfa->dev_idx); + nxpTfaFileDsc_t *file; + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + char buffer[(MEMTRACK_MAX_WORDS * 3) + 3] = { + 0 + }; //every word requires 3 and 3 is the msg + int i, size = 0; + + if (!dev) { + return Tfa98xx_Error_Bad_Parameter; + } + /* process the list and write all files */ + for (i = 0; i < dev->length; i++) { + if (dev->list[i].type == dscFile) { + file = (nxpTfaFileDsc_t *)(dev->list[i].offset + + (uint8_t *)tfa->cnt); + if (tfaContWriteFile(tfa, file, 0, + TFA_MAX_VSTEP_MSG_MARKER)) { + return Tfa98xx_Error_Bad_Parameter; + } + } + + if (dev->list[i].type == dscSetInputSelect || + dev->list[i].type == dscSetOutputSelect || + dev->list[i].type == dscSetProgramConfig || + dev->list[i].type == dscSetLagW || + dev->list[i].type == dscSetGains || + dev->list[i].type == dscSetvBatFactors || + dev->list[i].type == dscSetSensesCal || + dev->list[i].type == dscSetSensesDelay || + dev->list[i].type == dscSetMBDrc || + dev->list[i].type == dscSetFwkUseCase || + dev->list[i].type == dscSetVddpConfig) { + create_dsp_buffer_msg( + tfa, + (nxpTfaMsg_t *)(dev->list[i].offset + + (char *)tfa->cnt), + buffer, &size); + if (tfa->verbose) { + pr_debug("command: %s=0x%02x%02x%02x \n", + tfaContGetCommandString( + dev->list[i].type), + (unsigned char)buffer[0], + (unsigned char)buffer[1], + (unsigned char)buffer[2]); + } + + err = dsp_msg(tfa, size, buffer); + } + + if (dev->list[i].type == dscCmd) { + size = *(uint16_t *)(dev->list[i].offset + + (char *)tfa->cnt); + + err = dsp_msg(tfa, size, + dev->list[i].offset + 2 + + (char *)tfa->cnt); + if (tfa->verbose) { + const char *cmd_id = dev->list[i].offset + 2 + + (char *)tfa->cnt; + pr_debug("Writing cmd=0x%02x%02x%02x \n", + (uint8_t)cmd_id[0], (uint8_t)cmd_id[1], + (uint8_t)cmd_id[2]); + } + } + if (err != Tfa98xx_Error_Ok) + break; + + if (dev->list[i].type == dscCfMem) { + err = tfaRunWriteDspMem( + tfa, (nxpTfaDspMem_t *)(dev->list[i].offset + + (uint8_t *)tfa->cnt)); + } + + if (err != Tfa98xx_Error_Ok) + break; + } + + return err; +} + +/* + * write all param files in the profilelist to the target + * this is used during startup when maybe ACS is set + */ +enum Tfa98xx_Error tfaContWriteFilesProf(struct tfa_device *tfa, int prof_idx, + int vstep_idx) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + nxpTfaProfileList_t *prof = + tfaContGetDevProfList(tfa->cnt, tfa->dev_idx, prof_idx); + char buffer[(MEMTRACK_MAX_WORDS * 3) + 3] = { + 0 + }; //every word requires 3 and 3 is the msg + unsigned int i; + nxpTfaFileDsc_t *file; + nxpTfaPatch_t *patchfile; + int size; + + if (!prof) { + return Tfa98xx_Error_Bad_Parameter; + } + + /* process the list and write all files */ + for (i = 0; i < prof->length; i++) { + switch (prof->list[i].type) { + case dscFile: + file = (nxpTfaFileDsc_t *)(prof->list[i].offset + + (uint8_t *)tfa->cnt); + err = tfaContWriteFile(tfa, file, vstep_idx, + TFA_MAX_VSTEP_MSG_MARKER); + break; + case dscPatch: + file = (nxpTfaFileDsc_t *)(prof->list[i].offset + + (uint8_t *)tfa->cnt); + patchfile = (nxpTfaPatch_t *)&file->data; + if (tfa->verbose) + tfaContShowHeader(&patchfile->hdr); + size = patchfile->hdr.size - + sizeof(nxpTfaPatch_t); // size is total length + err = tfa_dsp_patch( + tfa, size, + (const unsigned char *)patchfile->data); + break; + case dscCfMem: + err = tfaRunWriteDspMem( + tfa, (nxpTfaDspMem_t *)(prof->list[i].offset + + (uint8_t *)tfa->cnt)); + break; + case dscSetInputSelect: + case dscSetOutputSelect: + case dscSetProgramConfig: + case dscSetLagW: + case dscSetGains: + case dscSetvBatFactors: + case dscSetSensesCal: + case dscSetSensesDelay: + case dscSetMBDrc: + case dscSetFwkUseCase: + case dscSetVddpConfig: + create_dsp_buffer_msg( + tfa, + (nxpTfaMsg_t *)(prof->list[i].offset + + (uint8_t *)tfa->cnt), + buffer, &size); + if (tfa->verbose) { + pr_debug("command: %s=0x%02x%02x%02x \n", + tfaContGetCommandString( + prof->list[i].type), + (unsigned char)buffer[0], + (unsigned char)buffer[1], + (unsigned char)buffer[2]); + } + + err = dsp_msg(tfa, size, buffer); + break; + default: + /* ignore any other type */ + break; + } + } + + return err; +} + +static enum Tfa98xx_Error tfaContWriteItem(struct tfa_device *tfa, + nxpTfaDescPtr_t *dsc) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + nxpTfaRegpatch_t *reg; + nxpTfaMode_t *cas; + nxpTfaBitfield_t *bitf; + + // When no DSP should only write to HW registers. + if (tfa->ext_dsp == 0 && + !(dsc->type == dscBitfield || dsc->type == dscRegister)) { + return Tfa98xx_Error_Ok; + } + + switch (dsc->type) { + case dscDefault: + case dscDevice: // ignore + case dscProfile: // profile list + break; + case dscRegister: // register patch + reg = (nxpTfaRegpatch_t *)(dsc->offset + (uint8_t *)tfa->cnt); + return tfaRunWriteRegister(tfa, reg); + //pr_debug("$0x%2x=0x%02x,0x%02x\n", reg->address, reg->mask, reg->value); + break; + case dscString: // ascii: zero terminated string + pr_debug(";string: %s\n", tfaContGetString(tfa->cnt, dsc)); + break; + case dscFile: // filename + file contents + case dscPatch: + break; + case dscMode: + cas = (nxpTfaMode_t *)(dsc->offset + (uint8_t *)tfa->cnt); + if (cas->value == Tfa98xx_Mode_RCV) + tfa98xx_select_mode(tfa, Tfa98xx_Mode_RCV); + else + tfa98xx_select_mode(tfa, Tfa98xx_Mode_Normal); + break; + case dscCfMem: + err = tfaRunWriteDspMem( + tfa, + (nxpTfaDspMem_t *)(dsc->offset + (uint8_t *)tfa->cnt)); + break; + case dscBitfield: + bitf = (nxpTfaBitfield_t *)(dsc->offset + (uint8_t *)tfa->cnt); + return tfaRunWriteBitfield(tfa, *bitf); + break; + case dscFilter: + return tfaRunWriteFilter( + tfa, (nxpTfaContBiquad_t *)(dsc->offset + + (uint8_t *)tfa->cnt)); + break; + } + + return err; +} + +static unsigned int tfa98xx_sr_from_field(unsigned int field) +{ + switch (field) { + case 0: + return 8000; + case 1: + return 11025; + case 2: + return 12000; + case 3: + return 16000; + case 4: + return 22050; + case 5: + return 24000; + case 6: + return 32000; + case 7: + return 44100; + case 8: + return 48000; + default: + return 0; + } +} + +enum Tfa98xx_Error tfa_write_filters(struct tfa_device *tfa, int prof_idx) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + nxpTfaProfileList_t *prof = + tfaContGetDevProfList(tfa->cnt, tfa->dev_idx, prof_idx); + unsigned int i; + int status; + + if (!prof) { + return Tfa98xx_Error_Bad_Parameter; + } + + if (tfa->verbose) { + pr_debug("----- profile: %s (%d) -----\n", + tfaContGetString(tfa->cnt, &prof->name), prof_idx); + pr_debug("Waiting for CLKS... \n"); + } + + for (i = 10; i > 0; i--) { + err = tfa98xx_dsp_system_stable(tfa, &status); + if (status) + break; + else + msleep_interruptible(10); + } + + if (i == 0) { + if (tfa->verbose) + pr_err("Unable to write filters, CLKS=0 \n"); + + return Tfa98xx_Error_StateTimedOut; + } + + /* process the list until the end of the profile or the default section */ + for (i = 0; i < prof->length; i++) { + if (prof->list[i].type == dscFilter) { + if (tfaContWriteItem(tfa, &prof->list[i]) != + Tfa98xx_Error_Ok) + return Tfa98xx_Error_Bad_Parameter; + } + } + + return err; +} + +unsigned int tfa98xx_get_profile_sr(struct tfa_device *tfa, + unsigned int prof_idx) +{ + nxpTfaBitfield_t *bitf; + unsigned int i; + nxpTfaDeviceList_t *dev; + nxpTfaProfileList_t *prof; + int fs_profile = -1; + + dev = tfaContDevice(tfa->cnt, tfa->dev_idx); + if (!dev) + return 0; + + prof = tfaContGetDevProfList(tfa->cnt, tfa->dev_idx, prof_idx); + if (!prof) + return 0; + + /* Check profile fields first */ + for (i = 0; i < prof->length; i++) { + if (prof->list[i].type == dscDefault) + break; + + /* check for profile settingd (AUDFS) */ + if (prof->list[i].type == dscBitfield) { + bitf = (nxpTfaBitfield_t *)(prof->list[i].offset + + (uint8_t *)tfa->cnt); + if (bitf->field == TFA_FAM(tfa, AUDFS)) { + fs_profile = bitf->value; + break; + } + } + } + + if (tfa->verbose) + pr_debug("%s - profile fs: 0x%x = %dHz (%d - %d)\n", + __FUNCTION__, fs_profile, + tfa98xx_sr_from_field(fs_profile), tfa->dev_idx, + prof_idx); + + if (fs_profile != -1) + return tfa98xx_sr_from_field(fs_profile); + + /* Check for container default setting */ + /* process the list until a patch, file of profile is encountered */ + for (i = 0; i < dev->length; i++) { + if (dev->list[i].type == dscPatch || + dev->list[i].type == dscFile || + dev->list[i].type == dscProfile) + break; + + if (dev->list[i].type == dscBitfield) { + bitf = (nxpTfaBitfield_t *)(dev->list[i].offset + + (uint8_t *)tfa->cnt); + if (bitf->field == TFA_FAM(tfa, AUDFS)) { + fs_profile = bitf->value; + break; + } + } + /* Ignore register case */ + } + + if (tfa->verbose) + pr_debug("%s - default fs: 0x%x = %dHz (%d - %d)\n", + __FUNCTION__, fs_profile, + tfa98xx_sr_from_field(fs_profile), tfa->dev_idx, + prof_idx); + + if (fs_profile != -1) + return tfa98xx_sr_from_field(fs_profile); + + return 48000; /* default of HW */ +} + +static enum Tfa98xx_Error +get_sample_rate_info(struct tfa_device *tfa, nxpTfaProfileList_t *prof, + nxpTfaProfileList_t *previous_prof, + int fs_previous_profile) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + nxpTfaBitfield_t *bitf; + unsigned int i; + int fs_default_profile = 8; /* default is 48kHz */ + int fs_next_profile = 8; /* default is 48kHz */ + + /* ---------- default settings previous profile ---------- */ + for (i = 0; i < previous_prof->length; i++) { + /* Search for the default section */ + if (i == 0) { + while (previous_prof->list[i].type != dscDefault && + i < previous_prof->length) { + i++; + } + i++; + } + + /* Only if we found the default section search for AUDFS */ + if (i < previous_prof->length) { + if (previous_prof->list[i].type == dscBitfield) { + bitf = (nxpTfaBitfield_t *)(previous_prof + ->list[i] + .offset + + (uint8_t *)tfa->cnt); + if (bitf->field == TFA_FAM(tfa, AUDFS)) { + fs_default_profile = bitf->value; + break; + } + } + } + } + + /* ---------- settings next profile ---------- */ + for (i = 0; i < prof->length; i++) { + /* We only want to write the values before the default section */ + if (prof->list[i].type == dscDefault) + break; + /* search for AUDFS */ + if (prof->list[i].type == dscBitfield) { + bitf = (nxpTfaBitfield_t *)(prof->list[i].offset + + (uint8_t *)tfa->cnt); + if (bitf->field == TFA_FAM(tfa, AUDFS)) { + fs_next_profile = bitf->value; + break; + } + } + } + + /* Enable if needed for debugging! + if (tfa->verbose) { + pr_debug("sample rate from the previous profile: %d \n", fs_previous_profile); + pr_debug("sample rate in the default section: %d \n", fs_default_profile); + pr_debug("sample rate for the next profile: %d \n", fs_next_profile); + } + */ + + if (fs_next_profile != fs_default_profile) { + if (tfa->verbose) + pr_debug("Writing delay tables for AUDFS=%d \n", + fs_next_profile); + + /* If the AUDFS from the next profile is not the same as + * the AUDFS from the default we need to write new delay tables + */ + err = tfa98xx_dsp_write_tables(tfa, fs_next_profile); + } else if (fs_default_profile != fs_previous_profile) { + if (tfa->verbose) + pr_debug("Writing delay tables for AUDFS=%d \n", + fs_default_profile); + + /* But if we do not have a new AUDFS in the next profile and + * the AUDFS from the default profile is not the same as the AUDFS + * from the previous profile we also need to write new delay tables + */ + err = tfa98xx_dsp_write_tables(tfa, fs_default_profile); + } + + return err; +} + +/* + * process all items in the profilelist + * NOTE an error return during processing will leave the device muted + * + */ +enum Tfa98xx_Error tfaContWriteProfile(struct tfa_device *tfa, int prof_idx, + int vstep_idx) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + nxpTfaProfileList_t *prof = + tfaContGetDevProfList(tfa->cnt, tfa->dev_idx, prof_idx); + nxpTfaProfileList_t *previous_prof = tfaContGetDevProfList( + tfa->cnt, tfa->dev_idx, tfa_dev_get_swprof(tfa)); + char buffer[(MEMTRACK_MAX_WORDS * 4) + 4] = { + 0 + }; //every word requires 3 or 4 bytes, and 3 or 4 is the msg + unsigned int i, k = 0, j = 0, tries = 0; + nxpTfaFileDsc_t *file; + int size = 0, ready, fs_previous_profile = 8; /* default fs is 48kHz*/ + + if (!prof || !previous_prof) { + pr_err("Error trying to get the (previous) swprofile \n"); + return Tfa98xx_Error_Bad_Parameter; + } + + if (tfa->verbose) { + tfa98xx_trace_printk("device:%s profile:%s vstep:%d\n", + tfaContDeviceName(tfa->cnt, tfa->dev_idx), + tfaContProfileName(tfa->cnt, tfa->dev_idx, + prof_idx), + vstep_idx); + } + + /* We only make a power cycle when the profiles are not in the same group */ + if (prof->group == previous_prof->group && prof->group != 0) { + if (tfa->verbose) { + pr_debug( + "The new profile (%s) is in the same group as the current profile (%s) \n", + tfaContGetString(tfa->cnt, &prof->name), + tfaContGetString(tfa->cnt, + &previous_prof->name)); + } + } else { + /* mute */ + err = tfaRunMute(tfa); + if (err) + return err; + + /* Get current sample rate before we start switching */ + fs_previous_profile = TFA_GET_BF(tfa, AUDFS); + + /* clear SBSL to make sure we stay in initCF state */ + if (tfa->tfa_family == 2) { + TFA_SET_BF_VOLATILE(tfa, SBSL, 0); + } + + /* When we switch profile we first power down the subsystem + * This should only be done when we are in operating mode + */ + if (((tfa->tfa_family == 2) && + (TFA_GET_BF(tfa, MANSTATE) >= 6)) || + (tfa->tfa_family != 2)) { + err = tfa98xx_powerdown(tfa, 1); + if (err) + return err; + + /* Wait until we are in PLL powerdown */ + do { + err = tfa98xx_dsp_system_stable(tfa, &ready); + if (!ready) + break; + else + msleep_interruptible( + 10); /* wait 10ms to avoid busload */ + tries++; + } while (tries <= 100); + + if (tries > 100) { + pr_debug("Wait for PLL powerdown timed out!\n"); + return Tfa98xx_Error_StateTimedOut; + } + } else { + pr_debug("No need to go to powerdown now \n"); + } + } + + /* set all bitfield settings */ + /* First set all default settings */ + if (tfa->verbose) { + pr_debug( + "---------- default settings profile: %s (%d) ---------- \n", + tfaContGetString(tfa->cnt, &previous_prof->name), + tfa_dev_get_swprof(tfa)); + } + + err = show_current_state(tfa); + + /* Loop profile length */ + for (i = 0; i < previous_prof->length; i++) { + /* Search for the default section */ + if (i == 0) { + while (previous_prof->list[i].type != dscDefault && + i < previous_prof->length) { + i++; + } + i++; + } + + /* Only if we found the default section try writing the items */ + if (i < previous_prof->length) { + if (tfaContWriteItem(tfa, &previous_prof->list[i]) != + Tfa98xx_Error_Ok) + return Tfa98xx_Error_Bad_Parameter; + } + } + + if (tfa->verbose) + pr_debug( + "---------- new settings profile: %s (%d) ---------- \n", + tfaContGetString(tfa->cnt, &prof->name), prof_idx); + + /* set new settings */ + for (i = 0; i < prof->length; i++) { + /* Remember where we currently are with writing items*/ + j = i; + + /* We only want to write the values before the default section when we switch profile */ + /* process and write all non-file items */ + switch (prof->list[i].type) { + case dscFile: + case dscPatch: + case dscSetInputSelect: + case dscSetOutputSelect: + case dscSetProgramConfig: + case dscSetLagW: + case dscSetGains: + case dscSetvBatFactors: + case dscSetSensesCal: + case dscSetSensesDelay: + case dscSetMBDrc: + case dscSetFwkUseCase: + case dscSetVddpConfig: + case dscCmd: + case dscFilter: + case dscDefault: + /* When one of these files are found, we exit */ + i = prof->length; + break; + default: + err = tfaContWriteItem(tfa, &prof->list[i]); + if (err != Tfa98xx_Error_Ok) + return Tfa98xx_Error_Bad_Parameter; + break; + } + } + + if (prof->group != previous_prof->group || prof->group == 0) { + if (tfa->tfa_family == 2) + TFA_SET_BF_VOLATILE(tfa, MANSCONF, 1); + + /* Leave powerdown state */ + err = tfa_cf_powerup(tfa); + if (err) + return err; + + err = show_current_state(tfa); + + if (tfa->tfa_family == 2) { + /* Reset SBSL to 0 (workaround of enbl_powerswitch=0) */ + TFA_SET_BF_VOLATILE(tfa, SBSL, 0); + /* Sending commands to DSP we need to make sure RST is 0 (otherwise we get no response)*/ + TFA_SET_BF(tfa, RST, 0); + } + } + + /* Check if there are sample rate changes */ + err = get_sample_rate_info(tfa, prof, previous_prof, + fs_previous_profile); + if (err) + return err; + + /* Write files from previous profile (default section) + * Should only be used for the patch&trap patch (file) + */ + if (tfa->ext_dsp != 0) { + if (tfa->tfa_family == 2) { + for (i = 0; i < previous_prof->length; i++) { + /* Search for the default section */ + if (i == 0) { + while (previous_prof->list[i].type != + dscDefault && + i < previous_prof->length) { + i++; + } + i++; + } + + /* Only if we found the default section try writing the file */ + if (i < previous_prof->length) { + if (previous_prof->list[i].type == + dscFile || + previous_prof->list[i].type == + dscPatch) { + /* Only write this once */ + if (tfa->verbose && k == 0) { + pr_debug( + "---------- files default profile: %s (%d) ---------- \n", + tfaContGetString( + tfa->cnt, + &previous_prof + ->name), + prof_idx); + k++; + } + file = (nxpTfaFileDsc_t + *)(previous_prof + ->list[i] + .offset + + (uint8_t *)tfa + ->cnt); + err = tfaContWriteFile( + tfa, file, vstep_idx, + TFA_MAX_VSTEP_MSG_MARKER); + } + } + } + } + + if (tfa->verbose) { + pr_debug( + "---------- files new profile: %s (%d) ---------- \n", + tfaContGetString(tfa->cnt, &prof->name), + prof_idx); + } + } + + /* write everything until end or the default section starts + * Start where we currenly left */ + for (i = j; i < prof->length; i++) { + /* We only want to write the values before the default section when we switch profile */ + + if (prof->list[i].type == dscDefault) { + break; + } + + switch (prof->list[i].type) { + case dscFile: + case dscPatch: + /* For tiberius stereo 1 device does not have a dsp! */ + if (tfa->ext_dsp != 0) { + file = (nxpTfaFileDsc_t *)(prof->list[i].offset + + (uint8_t *)tfa->cnt); + err = tfaContWriteFile( + tfa, file, vstep_idx, + TFA_MAX_VSTEP_MSG_MARKER); + } + break; + case dscSetInputSelect: + case dscSetOutputSelect: + case dscSetProgramConfig: + case dscSetLagW: + case dscSetGains: + case dscSetvBatFactors: + case dscSetSensesCal: + case dscSetSensesDelay: + case dscSetMBDrc: + case dscSetFwkUseCase: + case dscSetVddpConfig: + /* For tiberius stereo 1 device does not have a dsp! */ + if (tfa->ext_dsp != 0) { + create_dsp_buffer_msg( + tfa, + (nxpTfaMsg_t *)(prof->list[i].offset + + (char *)tfa->cnt), + buffer, &size); + err = dsp_msg(tfa, size, buffer); + + if (tfa->verbose) { + pr_debug( + "command: %s=0x%02x%02x%02x \n", + tfaContGetCommandString( + prof->list[i].type), + (unsigned char)buffer[0], + (unsigned char)buffer[1], + (unsigned char)buffer[2]); + } + } + break; + case dscCmd: + /* For tiberius stereo 1 device does not have a dsp! */ + if (tfa->ext_dsp != 0) { + size = *(uint16_t *)(prof->list[i].offset + + (char *)tfa->cnt); + err = dsp_msg(tfa, size, + prof->list[i].offset + 2 + + (char *)tfa->cnt); + if (tfa->verbose) { + const char *cmd_id = + prof->list[i].offset + 2 + + (char *)tfa->cnt; + pr_debug( + "Writing cmd=0x%02x%02x%02x \n", + (uint8_t)cmd_id[0], + (uint8_t)cmd_id[1], + (uint8_t)cmd_id[2]); + } + } + break; + default: + /* This allows us to write bitfield, registers or xmem after files */ + if (tfaContWriteItem(tfa, &prof->list[i]) != + Tfa98xx_Error_Ok) { + return Tfa98xx_Error_Bad_Parameter; + } + break; + } + + if (err != Tfa98xx_Error_Ok) { + return err; + } + } + + if ((prof->group != previous_prof->group || prof->group == 0) && + (tfa->tfa_family == 2)) { + if (TFA_GET_BF(tfa, REFCKSEL) == 0) { + /* set SBSL to go to operation mode */ + TFA_SET_BF_VOLATILE(tfa, SBSL, 1); + } + } + + return err; +} + +/* + * process only vstep in the profilelist + * + */ +enum Tfa98xx_Error tfaContWriteFilesVstep(struct tfa_device *tfa, int prof_idx, + int vstep_idx) +{ + nxpTfaProfileList_t *prof = + tfaContGetDevProfList(tfa->cnt, tfa->dev_idx, prof_idx); + unsigned int i; + nxpTfaFileDsc_t *file; + nxpTfaHeader_t *hdr; + nxpTfaHeaderType_t type; + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + + if (!prof) + return Tfa98xx_Error_Bad_Parameter; + + if (tfa->verbose) + tfa98xx_trace_printk("device:%s profile:%s vstep:%d\n", + tfaContDeviceName(tfa->cnt, tfa->dev_idx), + tfaContProfileName(tfa->cnt, tfa->dev_idx, + prof_idx), + vstep_idx); + + /* write vstep file only! */ + for (i = 0; i < prof->length; i++) { + if (prof->list[i].type == dscFile) { + file = (nxpTfaFileDsc_t *)(prof->list[i].offset + + (uint8_t *)tfa->cnt); + hdr = (nxpTfaHeader_t *)file->data; + type = (nxpTfaHeaderType_t)hdr->id; + + switch (type) { + case volstepHdr: + if (tfaContWriteFile(tfa, file, vstep_idx, + TFA_MAX_VSTEP_MSG_MARKER)) + return Tfa98xx_Error_Bad_Parameter; + break; + default: + break; + } + } + } + + return err; +} + +char *tfaContGetString(nxpTfaContainer_t *cnt, nxpTfaDescPtr_t *dsc) +{ + if (dsc->type != dscString) + return "Undefined string"; + + return dsc->offset + (char *)cnt; +} + +char *tfaContGetCommandString(uint32_t type) +{ + if (type == dscSetInputSelect) + return "SetInputSelector"; + else if (type == dscSetOutputSelect) + return "SetOutputSelector"; + else if (type == dscSetProgramConfig) + return "SetProgramConfig"; + else if (type == dscSetLagW) + return "SetLagW"; + else if (type == dscSetGains) + return "SetGains"; + else if (type == dscSetvBatFactors) + return "SetvBatFactors"; + else if (type == dscSetSensesCal) + return "SetSensesCal"; + else if (type == dscSetSensesDelay) + return "SetSensesDelay"; + else if (type == dscSetMBDrc) + return "SetMBDrc"; + else if (type == dscSetFwkUseCase) + return "SetFwkUseCase"; + else if (type == dscSetVddpConfig) + return "SetVddpConfig"; + else if (type == dscFilter) + return "filter"; + else + return "Undefined string"; +} + +/* + * Get the name of the device at a certain index in the container file + * return device name + */ +char *tfaContDeviceName(nxpTfaContainer_t *cnt, int dev_idx) +{ + nxpTfaDeviceList_t *dev; + + dev = tfaContDevice(cnt, dev_idx); + if (dev == NULL) + return "!ERROR!"; + + return tfaContGetString(cnt, &dev->name); +} + +/* + * Get the application name from the container file application field + * note that the input stringbuffer should be sizeof(application field)+1 + * + */ +int tfa_cnt_get_app_name(struct tfa_device *tfa, char *name) +{ + unsigned int i; + int len = 0; + + for (i = 0; i < sizeof(tfa->cnt->application); i++) { + if (isalnum(tfa->cnt->application[i])) /* copy char if valid */ + name[len++] = tfa->cnt->application[i]; + if (tfa->cnt->application[i] == '\0') + break; + } + name[len++] = '\0'; + + return len; +} + +/* + * Get profile index of the calibration profile. + * Returns: (profile index) if found, (-2) if no + * calibration profile is found or (-1) on error + */ +int tfaContGetCalProfile(struct tfa_device *tfa) +{ + int prof, cal_idx = -2; + + if ((tfa->dev_idx < 0) || (tfa->dev_idx >= tfa->cnt->ndev)) + return -1; + + /* search for the calibration profile in the list of profiles */ + for (prof = 0; prof < tfa->cnt->nprof; prof++) { + if (strstr(tfaContProfileName(tfa->cnt, tfa->dev_idx, prof), + ".cal") != NULL) { + cal_idx = prof; + pr_debug("Using calibration profile: '%s'\n", + tfaContProfileName(tfa->cnt, tfa->dev_idx, + prof)); + break; + } + } + + return cal_idx; +} + +/** + * Is the profile a tap profile + */ +int tfaContIsTapProfile(struct tfa_device *tfa, int prof_idx) +{ + if ((tfa->dev_idx < 0) || (tfa->dev_idx >= tfa->cnt->ndev)) + return -1; + + /* Check if next profile is tap profile */ + if (strstr(tfaContProfileName(tfa->cnt, tfa->dev_idx, prof_idx), + ".tap") != NULL) { + pr_debug("Using Tap profile: '%s'\n", + tfaContProfileName(tfa->cnt, tfa->dev_idx, prof_idx)); + return 1; + } + + return 0; +} + +/* + * Get the name of the profile at certain index for a device in the container file + * return profile name + */ +char *tfaContProfileName(nxpTfaContainer_t *cnt, int dev_idx, int prof_idx) +{ + nxpTfaProfileList_t *prof = NULL; + + /* the Nth profiles for this device */ + prof = tfaContGetDevProfList(cnt, dev_idx, prof_idx); + + /* If the index is out of bound */ + if (prof == NULL) + return "NONE"; + + return tfaContGetString(cnt, &prof->name); +} + +/* + * return 1st profile list + */ +nxpTfaProfileList_t *tfaContGet1stProfList(nxpTfaContainer_t *cont) +{ + nxpTfaProfileList_t *prof; + uint8_t *b = (uint8_t *)cont; + + int maxdev = 0; + nxpTfaDeviceList_t *dev; + + // get nr of devlists + maxdev = cont->ndev; + // get last devlist + dev = tfaContGetDevList(cont, maxdev - 1); + if (dev == NULL) + return NULL; + // the 1st profile starts after the last device list + b = (uint8_t *)dev + sizeof(nxpTfaDeviceList_t) + + dev->length * (sizeof(nxpTfaDescPtr_t)); + prof = (nxpTfaProfileList_t *)b; + return prof; +} + +/* + * return 1st livedata list + */ +nxpTfaLiveDataList_t *tfaContGet1stLiveDataList(nxpTfaContainer_t *cont) +{ + nxpTfaLiveDataList_t *ldata; + nxpTfaProfileList_t *prof; + nxpTfaDeviceList_t *dev; + uint8_t *b = (uint8_t *)cont; + int maxdev, maxprof; + + // get nr of devlists+1 + maxdev = cont->ndev; + // get nr of proflists + maxprof = cont->nprof; + + // get last devlist + dev = tfaContGetDevList(cont, maxdev - 1); + // the 1st livedata starts after the last device list + b = (uint8_t *)dev + sizeof(nxpTfaDeviceList_t) + + dev->length * (sizeof(nxpTfaDescPtr_t)); + + while (maxprof != 0) { + // get last proflist + prof = (nxpTfaProfileList_t *)b; + b += sizeof(nxpTfaProfileList_t) + + ((prof->length - 1) * (sizeof(nxpTfaDescPtr_t))); + maxprof--; + } + + /* Else the marker falls off */ + b += 4; //bytes + + ldata = (nxpTfaLiveDataList_t *)b; + return ldata; +} + +/* + * return the device list pointer + */ +nxpTfaDeviceList_t *tfaContDevice(nxpTfaContainer_t *cnt, int dev_idx) +{ + return tfaContGetDevList(cnt, dev_idx); +} + +/* + * return the next profile: + * - assume that all profiles are adjacent + * - calculate the total length of the input + * - the input profile + its length is the next profile + */ +nxpTfaProfileList_t *tfaContNextProfile(nxpTfaProfileList_t *prof) +{ + uint8_t *this, *next; /* byte pointers for byte pointer arithmetic */ + nxpTfaProfileList_t *nextprof; + int listlength; /* total length of list in bytes */ + + if (prof == NULL) + return NULL; + + if (prof->ID != TFA_PROFID) + return NULL; /* invalid input */ + + this = (uint8_t *)prof; + /* nr of items in the list, length includes name dsc so - 1*/ + listlength = (prof->length - 1) * sizeof(nxpTfaDescPtr_t); + /* the sizeof(nxpTfaProfileList_t) includes the list[0] length */ + next = this + listlength + + sizeof(nxpTfaProfileList_t); // - sizeof(nxpTfaDescPtr_t); + nextprof = (nxpTfaProfileList_t *)next; + + if (nextprof->ID != TFA_PROFID) + return NULL; + + return nextprof; +} + +/* + * return the next livedata + */ +nxpTfaLiveDataList_t *tfaContNextLiveData(nxpTfaLiveDataList_t *livedata) +{ + nxpTfaLiveDataList_t *nextlivedata = + (nxpTfaLiveDataList_t *)((char *)livedata + + (livedata->length * 4) + + sizeof(nxpTfaLiveDataList_t) - 4); + + if (nextlivedata->ID == TFA_LIVEDATAID) + return nextlivedata; + + return NULL; +} + +/* + * check CRC for container + * CRC is calculated over the bytes following the CRC field + * + * return non zero value on error + */ +int tfaContCrcCheckContainer(nxpTfaContainer_t *cont) +{ + uint8_t *base; + size_t size; + uint32_t crc; + + base = (uint8_t *)&cont->CRC + + 4; // ptr to bytes following the CRC field + size = (size_t)(cont->size - + (base - + (uint8_t *) + cont)); // nr of bytes following the CRC field + crc = ~crc32_le(~0u, base, size); + + return crc != cont->CRC; +} + +static void get_all_features_from_cnt(struct tfa_device *tfa, + int *hw_feature_register, + int sw_feature_register[2]) +{ + nxpTfaFeatures_t *features; + int i; + + nxpTfaDeviceList_t *dev = tfaContDevice(tfa->cnt, tfa->dev_idx); + + /* Init values in case no keyword is defined in cnt file: */ + *hw_feature_register = -1; + sw_feature_register[0] = -1; + sw_feature_register[1] = -1; + + if (dev == NULL) + return; + + // process the device list + for (i = 0; i < dev->length; i++) { + if (dev->list[i].type == dscFeatures) { + features = (nxpTfaFeatures_t *)(dev->list[i].offset + + (uint8_t *)tfa->cnt); + *hw_feature_register = features->value[0]; + sw_feature_register[0] = features->value[1]; + sw_feature_register[1] = features->value[2]; + break; + } + } +} + +/* wrapper function */ +void get_hw_features_from_cnt(struct tfa_device *tfa, int *hw_feature_register) +{ + int sw_feature_register[2]; + get_all_features_from_cnt(tfa, hw_feature_register, + sw_feature_register); +} + +/* wrapper function */ +void get_sw_features_from_cnt(struct tfa_device *tfa, + int sw_feature_register[2]) +{ + int hw_feature_register; + get_all_features_from_cnt(tfa, &hw_feature_register, + sw_feature_register); +} + +enum Tfa98xx_Error tfa98xx_factory_trimmer(struct tfa_device *tfa) +{ + return (tfa->dev_ops.factory_trimmer)(tfa); +} + +enum Tfa98xx_Error tfa_set_filters(struct tfa_device *tfa, int prof_idx) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + nxpTfaProfileList_t *prof = + tfaContGetDevProfList(tfa->cnt, tfa->dev_idx, prof_idx); + unsigned int i; + + if (!prof) + return Tfa98xx_Error_Bad_Parameter; + + /* If we are in powerdown there is no need to set filters */ + if (TFA_GET_BF(tfa, PWDN) == 1) + return Tfa98xx_Error_Ok; + + /* loop the profile to find filter settings */ + for (i = 0; i < prof->length; i++) { + /* We only want to write the values before the default section */ + if (prof->list[i].type == dscDefault) + break; + + /* write all filter settings */ + if (prof->list[i].type == dscFilter) { + if (tfaContWriteItem(tfa, &prof->list[i]) != + Tfa98xx_Error_Ok) + return err; + } + } + + return err; +} + +int tfa_tib_dsp_msgmulti(struct tfa_device *tfa, int length, const char *buffer) +{ + uint8_t *buf = (uint8_t *)buffer; + static uint8_t *blob = NULL, *blobptr; /* TODO: not multi-thread safe */ + static int total = 0; /* TODO: not multi-thread safe */ + int post_len = 0; + + /* checks for 24b_BE or 32_LE */ + int len_word_in_bytes = (tfa->convert_dsp32) ? 4 : 3; + /* TODO: get rid of these magic constants max size should depend on the tfa device type */ + int tfadsp_max_msg_size = (tfa->convert_dsp32) ? 5336 : 4000; + + /* No data found*/ + if (length == -1 && blob == NULL) { + return -1; + } + + if (length == -1) { + int i; + /* set last length field to zero */ + for (i = total; i < (total + len_word_in_bytes); i++) { + blob[i] = 0; + } + total += len_word_in_bytes; + memcpy(buf, blob, total); + + kfree(blob); + blob = NULL; /* Set to NULL pointer, otherwise no new malloc is done! */ + return total; + } + + if (blob == NULL) { + if (tfa->verbose) + pr_debug("%s, Creating the multi-message \n\n", + __FUNCTION__); + + blob = kmalloc(tfadsp_max_msg_size, GFP_KERNEL); + /* add command ID for multi-msg = 0x008015 */ + if (tfa->convert_dsp32) { + blob[0] = 0x15; + blob[1] = 0x80; + blob[2] = 0x0; + blob[3] = 0x0; + } else { + blob[0] = 0x0; + blob[1] = 0x80; + blob[2] = 0x15; + } + blobptr = blob; + blobptr += len_word_in_bytes; + total = len_word_in_bytes; + } + + if (tfa->verbose) { + pr_debug("%s, id:0x%02x%02x%02x, length:%d \n", __FUNCTION__, + buf[0], buf[1], buf[2], length); + } + + /* check total message size after concatination */ + post_len = total + length + (2 * len_word_in_bytes); + if (post_len > tfadsp_max_msg_size) { + //pr_debug("New multi-message too large! (%d >= %d (max.)), current length: %d\n", post_len, tfadsp_max_msg_size, total); + return Tfa98xx_Error_Buffer_too_small; + } + + /* add length field (length in words) to the multi message */ + if (tfa->convert_dsp32) { + *blobptr++ = (uint8_t)((length / len_word_in_bytes) & + 0xff); /* lsb */ + *blobptr++ = + (uint8_t)(((length / len_word_in_bytes) & 0xff00) >> + 8); /* msb */ + *blobptr++ = 0x0; + *blobptr++ = 0x0; + } else { + *blobptr++ = 0x0; + *blobptr++ = + (uint8_t)(((length / len_word_in_bytes) & 0xff00) >> + 8); /* msb */ + *blobptr++ = (uint8_t)((length / len_word_in_bytes) & + 0xff); /* lsb */ + } + memcpy(blobptr, buf, length); + blobptr += length; + total += (length + len_word_in_bytes); + + /* SetRe25 message is always the last message of the multi-msg */ + if (tfa->convert_dsp32) { + if (buf[1] == 0x81 && buf[0] == SB_PARAM_SET_RE25C) { + return 1; /* 1 means last message is done! */ + } + } else { + if (buf[1] == 0x81 && buf[2] == SB_PARAM_SET_RE25C) { + return 1; /* 1 means last message is done! */ + } + } + + return 0; +} diff --git a/techpack/audio/asoc/codecs/tfa98xx/src/tfa_debug.c b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_debug.c new file mode 100644 index 000000000000..b02098326cb2 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_debug.c @@ -0,0 +1,439 @@ +/* + * Copyright 2014-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "dbgprint.h" +#include "tfa_service.h" +#include "tfa98xx_tfafieldnames.h" + +/* support for error code translation into text */ +static char latest_errorstr[64]; + +const char *tfa98xx_get_error_string(enum Tfa98xx_Error error) +{ + const char *pErrStr; + + switch (error) { + case Tfa98xx_Error_Ok: + pErrStr = "Ok"; + break; + case Tfa98xx_Error_DSP_not_running: + pErrStr = "DSP_not_running"; + break; + case Tfa98xx_Error_Bad_Parameter: + pErrStr = "Bad_Parameter"; + break; + case Tfa98xx_Error_NotOpen: + pErrStr = "NotOpen"; + break; + case Tfa98xx_Error_InUse: + pErrStr = "InUse"; + break; + case Tfa98xx_Error_RpcBusy: + pErrStr = "RpcBusy"; + break; + case Tfa98xx_Error_RpcModId: + pErrStr = "RpcModId"; + break; + case Tfa98xx_Error_RpcParamId: + pErrStr = "RpcParamId"; + break; + case Tfa98xx_Error_RpcInvalidCC: + pErrStr = "RpcInvalidCC"; + break; + case Tfa98xx_Error_RpcInvalidSeq: + pErrStr = "RpcInvalidSeq"; + break; + case Tfa98xx_Error_RpcInvalidParam: + pErrStr = "RpcInvalidParam"; + break; + case Tfa98xx_Error_RpcBufferOverflow: + pErrStr = "RpcBufferOverflow"; + break; + case Tfa98xx_Error_RpcCalibBusy: + pErrStr = "RpcCalibBusy"; + break; + case Tfa98xx_Error_RpcCalibFailed: + pErrStr = "RpcCalibFailed"; + break; + case Tfa98xx_Error_Not_Supported: + pErrStr = "Not_Supported"; + break; + case Tfa98xx_Error_I2C_Fatal: + pErrStr = "I2C_Fatal"; + break; + case Tfa98xx_Error_I2C_NonFatal: + pErrStr = "I2C_NonFatal"; + break; + case Tfa98xx_Error_StateTimedOut: + pErrStr = "WaitForState_TimedOut"; + break; + default: + sprintf(latest_errorstr, "Unspecified error (%d)", (int)error); + pErrStr = latest_errorstr; + } + return pErrStr; +} +/*****************************************************************************/ +/* bitfield lookups */ +/* + * generic table lookup functions + */ +/** + * lookup bf in table + * return 'unkown' if not found + */ +static char *tfa_bf2name(tfaBfName_t *table, uint16_t bf) +{ + int n = 0; + + do { + if ((table[n].bfEnum & 0xfff0) == (bf & 0xfff0)) { + return table[n].bfName; + } + } while (table[n++].bfEnum != 0xffff); + + return table[n - 1].bfName; /* last name says unkown */ +} +/** + * lookup name in table + * return 0xffff if not found + */ +static uint16_t tfa_name2bf(tfaBfName_t *table, const char *name) +{ + int n = 0; + + do { + if (strcasecmp(name, table[n].bfName) == 0) + return table[n].bfEnum; + } while (table[n++].bfEnum != 0xffff); + + return 0xffff; +} + +/* + * tfa2 bitfield name table + */ +TFA2_NAMETABLE +TFA2_BITNAMETABLE + +/* + * tfa1 bitfield name tables + */ +TFA1_NAMETABLE +TFA9896_NAMETABLE +TFA9872_NAMETABLE +TFA9874_NAMETABLE +TFA9890_NAMETABLE +TFA9891_NAMETABLE +TFA9887_NAMETABLE +TFA1_BITNAMETABLE +TFA9912_NAMETABLE +TFA9894_NAMETABLE +TFA9896_BITNAMETABLE +TFA9872_BITNAMETABLE +TFA9874_BITNAMETABLE +TFA9912_BITNAMETABLE +TFA9890_BITNAMETABLE +TFA9891_BITNAMETABLE +TFA9887_BITNAMETABLE +TFA9894_BITNAMETABLE + +char *tfaContBitName(uint16_t num, unsigned short rev) +{ + char *name; + /* end of list for the unknown string */ + int tableLength = sizeof(Tfa1DatasheetNames) / sizeof(tfaBfName_t); + const char *unknown = Tfa1DatasheetNames[tableLength - 1].bfName; + + switch (rev & 0xff) { + case 0x88: + name = tfa_bf2name(Tfa2BitNames, num); + break; + case 0x97: + name = tfa_bf2name(Tfa1BitNames, num); + break; + case 0x96: + name = tfa_bf2name(Tfa9896BitNames, num); + break; + case 0x72: + name = tfa_bf2name(Tfa9872BitNames, num); + break; + case 0x74: + name = tfa_bf2name(Tfa9874BitNames, num); + break; + case 0x92: + name = tfa_bf2name(Tfa9891BitNames, num); + break; + case 0x91: + case 0x80: + case 0x81: + name = tfa_bf2name(Tfa9890BitNames, num); /* my tabel 1st */ + if (strcmp(unknown, name) == 0) + name = tfa_bf2name(Tfa1BitNames, + num); /* try generic table */ + break; + case 0x12: + name = tfa_bf2name(Tfa9887BitNames, num); /* my tabel 1st */ + if (strcmp(unknown, name) == 0) + name = tfa_bf2name(Tfa1BitNames, + num); /* try generic table */ + break; + case 0x13: + name = tfa_bf2name(Tfa9912BitNames, num); + break; + case 0x94: + name = tfa_bf2name(Tfa9894BitNames, num); + break; + default: + PRINT_ERROR("unknown REVID:0x%0x\n", rev); + tableLength = sizeof(Tfa1BitNames) / + sizeof(tfaBfName_t); /* end of list */ + name = (char *)unknown; + break; + } + return name; +} + +char *tfaContDsName(uint16_t num, unsigned short rev) +{ + char *name; + /* end of list for the unknown string */ + int tableLength = sizeof(Tfa1DatasheetNames) / sizeof(tfaBfName_t); + const char *unknown = Tfa1DatasheetNames[tableLength - 1].bfName; + + switch (rev & 0xff) { + case 0x88: + name = tfa_bf2name(Tfa2DatasheetNames, num); + break; + case 0x97: + name = tfa_bf2name(Tfa1DatasheetNames, num); + break; + case 0x96: + name = tfa_bf2name(Tfa9896DatasheetNames, num); + break; + case 0x72: + name = tfa_bf2name(Tfa9872DatasheetNames, num); + break; + case 0x74: + name = tfa_bf2name(Tfa9874DatasheetNames, num); + break; + case 0x92: + name = tfa_bf2name(Tfa9891DatasheetNames, num); + break; + case 0x91: + case 0x80: + case 0x81: + name = tfa_bf2name(Tfa9890DatasheetNames, + num); /* my tabel 1st */ + if (strcmp(unknown, name) == 0) + name = tfa_bf2name(Tfa1DatasheetNames, + num); /* try generic table */ + break; + case 0x12: + name = tfa_bf2name(Tfa9887DatasheetNames, + num); /* my tabel 1st */ + if (strcmp(unknown, name) == 0) + name = tfa_bf2name(Tfa1DatasheetNames, + num); /* try generic table */ + break; + case 0x13: + name = tfa_bf2name(Tfa9912DatasheetNames, num); + break; + case 0x94: + name = tfa_bf2name(Tfa9894DatasheetNames, num); + break; + default: + PRINT_ERROR("unknown REVID:0x%0x\n", rev); + tableLength = sizeof(Tfa1DatasheetNames) / + sizeof(tfaBfName_t); /* end of list */ + name = (char *)unknown; + break; + } + return name; +} + +char *tfaContBfName(uint16_t num, unsigned short rev) +{ + char *name; + /* end of list for the unknown string */ + int tableLength = sizeof(Tfa1DatasheetNames) / sizeof(tfaBfName_t); + const char *unknown = Tfa1DatasheetNames[tableLength - 1].bfName; + + /* if datasheet name does not exist look for bitfieldname */ + name = tfaContDsName(num, rev); + if (strcmp(unknown, name) == 0) + name = tfaContBitName(num, rev); + + return name; +} + +uint16_t tfaContBfEnum(const char *name, unsigned short rev) +{ + uint16_t bfnum; + + switch (rev & 0xff) { + case 0x88: + bfnum = tfa_name2bf(Tfa2DatasheetNames, name); + if (bfnum == 0xffff) + bfnum = tfa_name2bf(Tfa2BitNames, + name); /* try long bitname table */ + break; + case 0x97: + bfnum = tfa_name2bf(Tfa1DatasheetNames, name); + if (bfnum == 0xffff) + bfnum = tfa_name2bf(Tfa1BitNames, + name); /* try generic table */ + break; + case 0x96: + bfnum = tfa_name2bf(Tfa9896DatasheetNames, name); + if (bfnum == 0xffff) + bfnum = tfa_name2bf(Tfa9896BitNames, + name); /* try generic table */ + break; + case 0x72: + bfnum = tfa_name2bf(Tfa9872DatasheetNames, name); + if (bfnum == 0xffff) + bfnum = tfa_name2bf(Tfa9872BitNames, + name); /* try long bitname table */ + break; + case 0x74: + bfnum = tfa_name2bf(Tfa9874DatasheetNames, name); + if (bfnum == 0xffff) + bfnum = tfa_name2bf(Tfa9874BitNames, + name); /* try long bitname table */ + break; + case 0x92: + bfnum = tfa_name2bf(Tfa9891DatasheetNames, name); + if (bfnum == 0xffff) + bfnum = tfa_name2bf(Tfa9891BitNames, + name); /* try long bitname table */ + break; + case 0x91: + case 0x80: + case 0x81: + bfnum = tfa_name2bf(Tfa9890DatasheetNames, + name); /* my tabel 1st */ + if (bfnum == 0xffff) + bfnum = tfa_name2bf(Tfa1DatasheetNames, + name); /* try generic table */ + if (bfnum == 0xffff) + bfnum = tfa_name2bf(Tfa1BitNames, + name); /* try 2nd generic table */ + break; + case 0x12: + bfnum = tfa_name2bf(Tfa9887DatasheetNames, + name); /* my tabel 1st */ + if (bfnum == 0xffff) + bfnum = tfa_name2bf(Tfa1DatasheetNames, + name); /* try generic table */ + if (bfnum == 0xffff) + bfnum = tfa_name2bf(Tfa1BitNames, + name); /* try 2nd generic table */ + break; + case 0x13: + bfnum = tfa_name2bf(Tfa9912DatasheetNames, name); + if (bfnum == 0xffff) + bfnum = tfa_name2bf(Tfa9912BitNames, + name); /* try long bitname table */ + break; + case 0x94: + bfnum = tfa_name2bf(Tfa9894DatasheetNames, name); + if (bfnum == 0xffff) + bfnum = tfa_name2bf(Tfa9894BitNames, + name); /* try long bitname table */ + break; + + default: + PRINT_ERROR("unknown REVID:0x%0x\n", rev); + bfnum = 0xffff; + break; + } + + return bfnum; +} + +/* + * check all lists for a hit + * this is for the parser to know if it's an existing bitname + */ +uint16_t tfaContBfEnumAny(const char *name) +{ + uint16_t bfnum; + + /* datasheet names first */ + bfnum = tfa_name2bf(Tfa2DatasheetNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa1DatasheetNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9891DatasheetNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9890DatasheetNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9887DatasheetNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9872DatasheetNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9874DatasheetNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9896DatasheetNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9912DatasheetNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9894DatasheetNames, name); + if (bfnum != 0xffff) + return bfnum; + /* and then bitfield names */ + bfnum = tfa_name2bf(Tfa2BitNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa1BitNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9891BitNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9890BitNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9887BitNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9872BitNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9874BitNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9896BitNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9912BitNames, name); + if (bfnum != 0xffff) + return bfnum; + bfnum = tfa_name2bf(Tfa9894BitNames, name); + + return bfnum; +} diff --git a/techpack/audio/asoc/codecs/tfa98xx/src/tfa_dsp.c b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_dsp.c new file mode 100644 index 000000000000..eb4045710829 --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_dsp.c @@ -0,0 +1,4165 @@ +/* + * Copyright 2014-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "dbgprint.h" +#include "tfa_container.h" +#include "tfa.h" +#include "tfa98xx_tfafieldnames.h" +#include "tfa_internal.h" + +#ifdef __KERNEL__ +#ifdef pr_fmt +#undef pr_fmt +#endif +#define pr_fmt(fmt) "%s(): " fmt, __func__ +#endif +/* handle macro for bitfield */ +#define TFA_MK_BF(reg, pos, len) ((reg << 8) | (pos << 4) | (len - 1)) + +/* abstract family for register */ +#define FAM_TFA98XX_CF_CONTROLS (TFA_FAM(tfa, RST) >> 8) +#define FAM_TFA98XX_CF_MEM (TFA_FAM(tfa, MEMA) >> 8) +#define FAM_TFA98XX_MTP0 (TFA_FAM(tfa, MTPOTC) >> 8) +#define FAM_TFA98xx_INT_EN (TFA_FAM(tfa, INTENVDDS) >> 8) + +#define CF_STATUS_I2C_CMD_ACK 0x01 + +/* Defines below are used for irq function (this removed the genregs include) */ +#define TFA98XX_INTERRUPT_ENABLE_REG1 0x48 +#define TFA98XX_INTERRUPT_IN_REG1 0x44 +#define TFA98XX_INTERRUPT_OUT_REG1 0x40 +#define TFA98XX_STATUS_POLARITY_REG1 0x4c +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_MSK 0x2 +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_MSK 0x1 +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_POS 1 +#define TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_POS 0 + +void tfanone_ops(struct tfa_device_ops *ops); +void tfa9872_ops(struct tfa_device_ops *ops); +void tfa9874_ops(struct tfa_device_ops *ops); +void tfa9912_ops(struct tfa_device_ops *ops); +void tfa9888_ops(struct tfa_device_ops *ops); +void tfa9891_ops(struct tfa_device_ops *ops); +void tfa9897_ops(struct tfa_device_ops *ops); +void tfa9896_ops(struct tfa_device_ops *ops); +void tfa9890_ops(struct tfa_device_ops *ops); +void tfa9895_ops(struct tfa_device_ops *ops); +void tfa9894_ops(struct tfa_device_ops *ops); + +#ifndef MIN +#define MIN(A, B) (A < B ? A : B) +#endif + +/* retry values */ +#define CFSTABLE_TRIES 10 +#define AMPOFFWAIT_TRIES 50 +#define MTPBWAIT_TRIES 50 +#define MTPEX_WAIT_NTRIES 50 + +/* calibration done executed */ +#define TFA_MTPEX_POS TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_POS /**/ + +int tfa_get_calibration_info(struct tfa_device *tfa, int channel) +{ + return tfa->mohm[channel]; +} + +/* return sign extended tap pattern */ +int tfa_get_tap_pattern(struct tfa_device *tfa) +{ + int value = tfa_get_bf(tfa, TFA9912_BF_CFTAPPAT); + int bitshift; + uint8_t field_len = + 1 + (TFA9912_BF_CFTAPPAT & 0x0f); /* length of bitfield */ + + bitshift = 8 * sizeof(int) - field_len; + /* signextend */ + value = (value << bitshift) >> bitshift; + + return value; +} +/* + * interrupt bit function to clear + */ +int tfa_irq_clear(struct tfa_device *tfa, enum tfa9912_irq bit) +{ + unsigned char reg; + + /* make bitfield enum */ + if (bit == tfa9912_irq_all) { + /* operate on all bits */ + for (reg = TFA98XX_INTERRUPT_IN_REG1; + reg < TFA98XX_INTERRUPT_IN_REG1 + 3; reg++) + reg_write(tfa, reg, 0xffff); /* all bits */ + } else if (bit < tfa9912_irq_max) { + reg = (unsigned char)(TFA98XX_INTERRUPT_IN_REG1 + (bit >> 4)); + reg_write(tfa, reg, 1 << (bit & 0x0f)); /* only this bit */ + } else + return -1; + + return 0; +} +/* + * return state of irq or -1 if illegal bit + */ +int tfa_irq_get(struct tfa_device *tfa, enum tfa9912_irq bit) +{ + uint16_t value; + int reg, mask; + + if (bit < tfa9912_irq_max) { + /* only this bit */ + reg = TFA98XX_INTERRUPT_OUT_REG1 + (bit >> 4); + mask = 1 << (bit & 0x0f); + reg_read(tfa, (unsigned char)reg, &value); + } else + return -1; + + return (value & mask) != 0; +} +/* + * interrupt bit function that operates on the shadow regs in the handle + */ + +int tfa_irq_ena(struct tfa_device *tfa, enum tfa9912_irq bit, int state) +{ + uint16_t value, new_value; + int reg = 0, mask; + /* */ + if (bit == tfa9912_irq_all) { + /* operate on all bits */ + for (reg = TFA98XX_INTERRUPT_ENABLE_REG1; + reg <= + TFA98XX_INTERRUPT_ENABLE_REG1 + tfa9912_irq_max / 16; + reg++) { + reg_write(tfa, (unsigned char)reg, + state ? 0xffff : 0); /* all bits */ + tfa->interrupt_enable[reg - + TFA98XX_INTERRUPT_ENABLE_REG1] = + state ? 0xffff : 0; /* all bits */ + } + } else if (bit < tfa9912_irq_max) { + /* only this bit */ + reg = TFA98XX_INTERRUPT_ENABLE_REG1 + (bit >> 4); + mask = 1 << (bit & 0x0f); + reg_read(tfa, (unsigned char)reg, &value); + if (state) //set + new_value = (uint16_t)(value | mask); + else // clear + new_value = value & ~mask; + if (new_value != value) { + reg_write(tfa, (unsigned char)reg, + new_value); /* only this bit */ + tfa->interrupt_enable[reg - + TFA98XX_INTERRUPT_ENABLE_REG1] = + new_value; + } + } else + return -1; + + return 0; +} + +/* + * mask interrupts by disabling them + */ +int tfa_irq_mask(struct tfa_device *tfa) +{ + int reg; + + /* operate on all bits */ + for (reg = TFA98XX_INTERRUPT_ENABLE_REG1; + reg <= TFA98XX_INTERRUPT_ENABLE_REG1 + tfa9912_irq_max / 16; reg++) + reg_write(tfa, (unsigned char)reg, 0); + + return 0; +} + +/* + * unmask interrupts by enabling them again + */ +int tfa_irq_unmask(struct tfa_device *tfa) +{ + int reg; + + /* operate on all bits */ + for (reg = TFA98XX_INTERRUPT_ENABLE_REG1; + reg <= TFA98XX_INTERRUPT_ENABLE_REG1 + tfa9912_irq_max / 16; reg++) + reg_write(tfa, (unsigned char)reg, + tfa->interrupt_enable[reg - + TFA98XX_INTERRUPT_ENABLE_REG1]); + + return 0; +} + +/* + * interrupt bit function that sets the polarity + */ + +int tfa_irq_set_pol(struct tfa_device *tfa, enum tfa9912_irq bit, int state) +{ + uint16_t value, new_value; + int reg = 0, mask; + + if (bit == tfa9912_irq_all) { + /* operate on all bits */ + for (reg = TFA98XX_STATUS_POLARITY_REG1; + reg <= TFA98XX_STATUS_POLARITY_REG1 + tfa9912_irq_max / 16; + reg++) { + reg_write(tfa, (unsigned char)reg, + state ? 0xffff : 0); /* all bits */ + } + } else if (bit < tfa9912_irq_max) { + /* only this bit */ + reg = TFA98XX_STATUS_POLARITY_REG1 + (bit >> 4); + mask = 1 << (bit & 0x0f); + reg_read(tfa, (unsigned char)reg, &value); + if (state) /* Active High */ + new_value = (uint16_t)(value | mask); + else /* Active Low */ + new_value = value & ~mask; + if (new_value != value) { + reg_write(tfa, (unsigned char)reg, + new_value); /* only this bit */ + } + } else + return -1; + + return 0; +} + +/* + * set device info and register device ops + */ +void tfa_set_query_info(struct tfa_device *tfa) +{ + /* invalidate device struct cached values */ + tfa->hw_feature_bits = -1; + tfa->sw_feature_bits[0] = -1; + tfa->sw_feature_bits[1] = -1; + tfa->profile = -1; + tfa->vstep = -1; + /* defaults */ + tfa->is_probus_device = 0; + tfa->tfa_family = 1; + tfa->daimap = Tfa98xx_DAI_I2S; /* all others */ + tfa->spkr_count = 1; + tfa->spkr_select = 0; + tfa->support_tcoef = supportYes; + tfa->supportDrc = supportNotSet; + tfa->support_saam = supportNotSet; + tfa->ext_dsp = + -1; /* respond to external DSP: -1:none, 0:no_dsp, 1:cold, 2:warm */ + tfa->bus = 0; + tfa->partial_enable = 0; + tfa->convert_dsp32 = 0; + tfa->sync_iv_delay = 0; + + /* TODO use the getfeatures() for retrieving the features [artf103523] + tfa->supportDrc = supportNotSet;*/ + + switch (tfa->rev & 0xff) { + case 0: /* tfanone : non-i2c external DSP device */ + /* e.g. qc adsp */ + tfa->supportDrc = supportYes; + tfa->tfa_family = 0; + tfa->spkr_count = 0; + tfa->daimap = 0; + tfanone_ops( + &tfa->dev_ops); /* register device operations via tfa hal*/ + tfa->bus = 1; + break; + case 0x72: + /* tfa9872 */ + tfa->supportDrc = supportYes; + tfa->tfa_family = 2; + tfa->spkr_count = 1; + tfa->is_probus_device = 1; + tfa->daimap = Tfa98xx_DAI_TDM; + tfa9872_ops(&tfa->dev_ops); /* register device operations */ + break; + case 0x74: + /* tfa9874 */ + tfa->supportDrc = supportYes; + tfa->tfa_family = 2; + tfa->spkr_count = 1; + tfa->is_probus_device = 1; + tfa->daimap = Tfa98xx_DAI_TDM; + tfa9874_ops(&tfa->dev_ops); /* register device operations */ + break; + case 0x88: + /* tfa9888 */ + tfa->tfa_family = 2; + tfa->spkr_count = 2; + tfa->daimap = Tfa98xx_DAI_TDM; + tfa9888_ops(&tfa->dev_ops); /* register device operations */ + break; + case 0x97: + /* tfa9897 */ + tfa->supportDrc = supportNo; + tfa->spkr_count = 1; + tfa->daimap = Tfa98xx_DAI_TDM; + tfa9897_ops(&tfa->dev_ops); /* register device operations */ + break; + case 0x96: + /* tfa9896 */ + tfa->supportDrc = supportNo; + tfa->spkr_count = 1; + tfa->daimap = Tfa98xx_DAI_TDM; + tfa9896_ops(&tfa->dev_ops); /* register device operations */ + break; + case 0x92: + /* tfa9891 */ + tfa->spkr_count = 1; + tfa->daimap = (Tfa98xx_DAI_PDM | Tfa98xx_DAI_I2S); + tfa9891_ops(&tfa->dev_ops); /* register device operations */ + break; + case 0x91: + /* tfa9890B */ + tfa->spkr_count = 1; + tfa->daimap = (Tfa98xx_DAI_PDM | Tfa98xx_DAI_I2S); + break; + case 0x80: + case 0x81: + /* tfa9890 */ + tfa->spkr_count = 1; + tfa->daimap = Tfa98xx_DAI_I2S; + tfa->supportDrc = supportNo; + tfa->supportFramework = supportNo; + tfa9890_ops(&tfa->dev_ops); /* register device operations */ + break; + case 0x12: + /* tfa9895 */ + tfa->spkr_count = 1; + tfa->daimap = Tfa98xx_DAI_I2S; + tfa9895_ops(&tfa->dev_ops); /* register device operations */ + break; + case 0x13: + /* tfa9912 */ + tfa->tfa_family = 2; + tfa->spkr_count = 1; + tfa->daimap = Tfa98xx_DAI_TDM; + tfa9912_ops(&tfa->dev_ops); /* register device operations */ + break; + case 0x94: + /* tfa9894 */ + tfa->tfa_family = 2; + tfa->spkr_count = 1; + tfa->daimap = Tfa98xx_DAI_TDM; + tfa9894_ops(&tfa->dev_ops); /* register device operations */ + break; + + default: + pr_err("unknown device type : 0x%02x\n", tfa->rev); + _ASSERT(0); + break; + } +} + +/* + * lookup the device type and return the family type + */ +int tfa98xx_dev2family(int dev_type) +{ + /* only look at the die ID part (lsb byte) */ + switch (dev_type & 0xff) { + case 0x12: + case 0x80: + case 0x81: + case 0x91: + case 0x92: + case 0x97: + case 0x96: + return 1; + case 0x88: + case 0x72: + case 0x13: + case 0x74: + case 0x94: + return 2; + case 0x50: + return 3; + default: + return 0; + } +} + +/* + * return the target address for the filter on this device + + filter_index: + [0..9] reserved for EQ (not deployed, calc. is available) + [10..12] anti-alias filter + [13] integrator filter + + */ +enum Tfa98xx_DMEM tfa98xx_filter_mem(struct tfa_device *tfa, int filter_index, + unsigned short *address, int channel) +{ + enum Tfa98xx_DMEM dmem = -1; + int idx; + unsigned short bq_table[7][4] = { + /* index: 10, 11, 12, 13 */ + { 346, 351, 356, 288 }, //87 BRA_MAX_MRA4-2_7.00 + { 346, 351, 356, 288 }, //90 BRA_MAX_MRA6_9.02 + { 467, 472, 477, 409 }, //95 BRA_MAX_MRA7_10.02 + { 406, 411, 416, 348 }, //97 BRA_MAX_MRA9_12.01 + { 467, 472, 477, 409 }, //91 BRA_MAX_MRAA_13.02 + { 8832, 8837, 8842, 8847 }, //88 part1 + { 8853, 8858, 8863, 8868 } //88 part2 + /* Since the 88 is stereo we have 2 parts. + * Every index has 5 values except index 13 this one has 6 values + */ + }; + + if ((10 <= filter_index) && (filter_index <= 13)) { + dmem = Tfa98xx_DMEM_YMEM; /* for all devices */ + idx = filter_index - 10; + + switch (tfa->rev & 0xff) { // only compare lower byte + case 0x12: + *address = bq_table[2][idx]; + break; + case 0x97: + *address = bq_table[3][idx]; + break; + case 0x96: + *address = bq_table[3][idx]; + break; + case 0x80: + case 0x81: // for the RAM version + case 0x91: + *address = bq_table[1][idx]; + break; + case 0x92: + *address = bq_table[4][idx]; + break; + case 0x88: + /* Channel 1 = primary, 2 = secondary */ + if (channel == 1) + *address = bq_table[5][idx]; + else + *address = bq_table[6][idx]; + break; + case 0x72: + case 0x74: + case 0x13: + default: + /* unsupported case, possibly intermediate version */ + return -1; + _ASSERT(0); + } + } + return dmem; +} + +/************************ query functions ********************************************************/ +/** +* return revision +* Used by the LTT +*/ +void tfa98xx_rev(int *major, int *minor, int *revision) +{ + char version_str[] = TFA98XX_API_REV_STR; + sscanf(version_str, "v%d.%d.%d", major, minor, revision); +} + +/** + * tfa_supported_speakers + * returns the number of the supported speaker count + */ +enum Tfa98xx_Error tfa_supported_speakers(struct tfa_device *tfa, + int *spkr_count) +{ + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + else + *spkr_count = tfa->spkr_count; + + return Tfa98xx_Error_Ok; +} + +/* + * tfa98xx_supported_saam + * returns the supportedspeaker as microphone feature + */ +enum Tfa98xx_Error tfa98xx_supported_saam(struct tfa_device *tfa, + enum Tfa98xx_saam *saam) +{ + int features; + enum Tfa98xx_Error error; + + if (tfa->support_saam == supportNotSet) { + error = tfa98xx_dsp_get_hw_feature_bits(tfa, &features); + if (error != Tfa98xx_Error_Ok) + return error; + tfa->support_saam = (features & 0x8000) ? + supportYes : + supportNo; /* SAAM is bit15 */ + } + *saam = tfa->support_saam == supportYes ? Tfa98xx_saam : + Tfa98xx_saam_none; + + return Tfa98xx_Error_Ok; +} + +/* + * tfa98xx_compare_features + * Obtains features_from_MTP and features_from_cnt + */ +enum Tfa98xx_Error tfa98xx_compare_features(struct tfa_device *tfa, + int features_from_MTP[3], + int features_from_cnt[3]) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + uint32_t value; + uint16_t mtpbf; + unsigned char bytes[3 * 2]; + int status; + + tfa98xx_dsp_system_stable(tfa, &status); + if (!status) + return Tfa98xx_Error_NoClock; // Only test when we have a clock. + + /* Set proper MTP location per device: */ + if (tfa->tfa_family == 1) { + mtpbf = 0x850f; /* MTP5 for tfa1,16 bits */ + } else { + mtpbf = 0xf907; /* MTP9 for tfa2, 8 bits */ + } + + /* Read HW features from MTP: */ + value = tfa_read_reg(tfa, mtpbf) & 0xffff; + features_from_MTP[0] = tfa->hw_feature_bits = value; + + /* Read SW features: */ + error = tfa_dsp_cmd_id_write_read(tfa, MODULE_FRAMEWORK, + FW_PAR_ID_GET_FEATURE_INFO, + sizeof(bytes), bytes); + if (error != Tfa98xx_Error_Ok) + return error; /* old ROM code may respond with Tfa98xx_Error_RpcParamId */ + + tfa98xx_convert_bytes2data(sizeof(bytes), bytes, &features_from_MTP[1]); + + /* check if feature bits from MTP match feature bits from cnt file: */ + get_hw_features_from_cnt(tfa, &features_from_cnt[0]); + get_sw_features_from_cnt(tfa, &features_from_cnt[1]); + + return error; +} + +/********************************* device specific ops ************************************************/ +/* the wrapper for DspReset, in case of full */ +enum Tfa98xx_Error tfa98xx_dsp_reset(struct tfa_device *tfa, int state) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + + error = (tfa->dev_ops.dsp_reset)(tfa, state); + + return error; +} + +/* the ops wrapper for tfa98xx_dsp_SystemStable */ +enum Tfa98xx_Error tfa98xx_dsp_system_stable(struct tfa_device *tfa, int *ready) +{ + enum Tfa98xx_Error error = (tfa->dev_ops.dsp_system_stable)(tfa, ready); + pr_debug("%s error=%d ready=%d\n", __func__, error, *ready); + return error; +} + +/* the ops wrapper for tfa98xx_dsp_system_stable */ +enum Tfa98xx_Error tfa98xx_auto_copy_mtp_to_iic(struct tfa_device *tfa) +{ + return (tfa->dev_ops.auto_copy_mtp_to_iic)(tfa); +} + +/* the ops wrapper for tfa98xx_faim_protect */ +enum Tfa98xx_Error tfa98xx_faim_protect(struct tfa_device *tfa, int state) +{ + return (tfa->dev_ops.faim_protect)(tfa, state); +} + +/* + * bring the device into a state similar to reset + */ +enum Tfa98xx_Error tfa98xx_init(struct tfa_device *tfa) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + uint16_t value = 0; + + /* reset all i2C registers to default + * Write the register directly to avoid the read in the bitfield function. + * The I2CR bit may overwrite the full register because it is reset anyway. + * This will save a reg read transaction. + */ + TFA_SET_BF_VALUE(tfa, I2CR, 1, &value); + TFA_WRITE_REG(tfa, I2CR, value); + + /* Put DSP in reset */ + tfa98xx_dsp_reset(tfa, 1); /* in pair of tfaRunStartDSP() */ + + /* some other registers must be set for optimal amplifier behaviour + * This is implemented in a file specific for the type number + */ + if (tfa->dev_ops.tfa_init) + error = (tfa->dev_ops.tfa_init)(tfa); + + return error; +} + +enum Tfa98xx_Error tfa98xx_dsp_write_tables(struct tfa_device *tfa, + int sample_rate) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + + error = (tfa->dev_ops.dsp_write_tables)(tfa, sample_rate); + + return error; +} + +/** Set internal oscillator into power down mode. +* +* @param[in] tfa device description structure +* @param[in] state new state 0 - oscillator is on, 1 oscillator is off. +* +* @return Tfa98xx_Error_Ok when successfull, error otherwise. +*/ +enum Tfa98xx_Error tfa98xx_set_osc_powerdown(struct tfa_device *tfa, int state) +{ + if (tfa->dev_ops.set_osc_powerdown) { + return tfa->dev_ops.set_osc_powerdown(tfa, state); + } + + return Tfa98xx_Error_Not_Implemented; +} + +/** Check presence of powerswitch=1 in configuration and optimal setting. +* +* @param[in] tfa device description structure +* +* @return -1 when error, 0 or 1 depends on switch settings. +*/ +int tfa98xx_powerswitch_is_enabled(struct tfa_device *tfa) +{ + uint16_t value; + enum Tfa98xx_Error ret; + + if (((tfa->rev & 0xff) == 0x13) || ((tfa->rev & 0xff) == 0x88)) { + ret = reg_read(tfa, 0xc6, &value); + if (ret != Tfa98xx_Error_Ok) { + return -1; + } + /* PLMA5539: Check actual value of powerswitch. TODO: regmap v1.40 should make this bit public. */ + + return (int)(value & (1u << 6)); + } + + return 1; +} + +/********************* new tfa2 *********************************************************************/ +/* newly added messaging for tfa2 tfa1? */ +enum Tfa98xx_Error tfa98xx_dsp_get_memory(struct tfa_device *tfa, + int memoryType, int offset, + int length, unsigned char bytes[]) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + char msg[4 * 3]; + int nr = 0; + + msg[nr++] = 8; + msg[nr++] = MODULE_FRAMEWORK + 128; + msg[nr++] = FW_PAR_ID_GET_MEMORY; + + msg[nr++] = 0; + msg[nr++] = 0; + msg[nr++] = (char)memoryType; + + msg[nr++] = 0; + msg[nr++] = (offset >> 8) & 0xff; + msg[nr++] = offset & 0xff; + + msg[nr++] = 0; + msg[nr++] = (length >> 8) & 0xff; + msg[nr++] = length & 0xff; + + /* send msg */ + error = dsp_msg(tfa, nr, (char *)msg); + + if (error != Tfa98xx_Error_Ok) + return error; + + /* read the data from the device (length * 3) */ + error = dsp_msg_read(tfa, length * 3, bytes); + + return error; +} + +enum Tfa98xx_Error tfa98xx_dsp_set_memory(struct tfa_device *tfa, + int memoryType, int offset, + int length, int value) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + int nr = 0; + char msg[5 * 3]; + + msg[nr++] = 8; + msg[nr++] = MODULE_FRAMEWORK + 128; + msg[nr++] = FW_PAR_ID_SET_MEMORY; + + msg[nr++] = 0; + msg[nr++] = 0; + msg[nr++] = (char)memoryType; + + msg[nr++] = 0; + msg[nr++] = (offset >> 8) & 0xff; + msg[nr++] = offset & 0xff; + + msg[nr++] = 0; + msg[nr++] = (length >> 8) & 0xff; + msg[nr++] = length & 0xff; + + msg[nr++] = (value >> 16) & 0xff; + msg[nr++] = (value >> 8) & 0xff; + msg[nr++] = value & 0xff; + + /* send msg */ + error = dsp_msg(tfa, nr, (char *)msg); + + return error; +} +/****************************** calibration support **************************/ +/* + * get/set the mtp with user controllable values + * + * check if the relevant clocks are available + */ +enum Tfa98xx_Error tfa98xx_get_mtp(struct tfa_device *tfa, uint16_t *value) +{ + int status; + int result; + + /* not possible if PLL in powerdown */ + if (TFA_GET_BF(tfa, PWDN)) { + pr_debug("PLL in powerdown\n"); + return Tfa98xx_Error_NoClock; + } + + tfa98xx_dsp_system_stable(tfa, &status); + if (status == 0) { + pr_debug("PLL not running\n"); + return Tfa98xx_Error_NoClock; + } + + result = TFA_READ_REG(tfa, MTP0); + if (result < 0) { + return -result; + } + *value = (uint16_t)result; + + return Tfa98xx_Error_Ok; +} + +/* + * lock or unlock KEY2 + * lock = 1 will lock + * lock = 0 will unlock + * + * note that on return all the hidden key will be off + */ +void tfa98xx_key2(struct tfa_device *tfa, int lock) +{ + /* unhide lock registers */ + reg_write(tfa, (tfa->tfa_family == 1) ? 0x40 : 0x0F, 0x5A6B); + /* lock/unlock key2 MTPK */ + TFA_WRITE_REG(tfa, MTPKEY2, lock ? 0 : 0x5A); + /* unhide lock registers */ + reg_write(tfa, (tfa->tfa_family == 1) ? 0x40 : 0x0F, 0); +} + +enum Tfa98xx_Error tfa98xx_set_mtp(struct tfa_device *tfa, uint16_t value, + uint16_t mask) +{ + unsigned short mtp_old, mtp_new; + int loop, status; + enum Tfa98xx_Error error; + + error = tfa98xx_get_mtp(tfa, &mtp_old); + + if (error != Tfa98xx_Error_Ok) + return error; + + mtp_new = (value & mask) | (mtp_old & ~mask); + + if (mtp_old == mtp_new) /* no change */ { + if (tfa->verbose) + pr_info("No change in MTP. Value not written! \n"); + return Tfa98xx_Error_Ok; + } + + /* Assure FAIM is enabled (enable it when neccesery) */ + error = tfa98xx_faim_protect(tfa, 1); + if (error) { + return error; + } + if (tfa->verbose) { + pr_debug("MTP clock enabled.\n"); + } + + /* assure that the clock is up, else we can't write MTP */ + error = tfa98xx_dsp_system_stable(tfa, &status); + if (error) { + return error; + } + if (status == 0) { + return Tfa98xx_Error_NoClock; + } + + tfa98xx_key2(tfa, 0); /* unlock */ + TFA_WRITE_REG(tfa, MTP0, mtp_new); /* write to i2c shadow reg */ + /* CIMTP=1 start copying all the data from i2c regs_mtp to mtp*/ + TFA_SET_BF(tfa, CIMTP, 1); + /* no check for MTPBUSY here, i2c delay assumed to be enough */ + tfa98xx_key2(tfa, 1); /* lock */ + + /* wait until MTP write is done */ + error = Tfa98xx_Error_StateTimedOut; + for (loop = 0; loop < 100 /*x10ms*/; loop++) { + msleep_interruptible(10); /* wait 10ms to avoid busload */ + if (tfa_dev_get_mtpb(tfa) == 0) { + error = Tfa98xx_Error_Ok; + break; + } + } + /* MTP setting failed due to timeout ?*/ + if (error) { + return error; + } + + /* Disable the FAIM, if this is neccessary */ + error = tfa98xx_faim_protect(tfa, 0); + if (error) { + return error; + } + if (tfa->verbose) { + pr_debug("MTP clock disabled.\n"); + } + + return error; +} +/* + * clear mtpex + * set ACS + * start tfa + */ +int tfa_calibrate(struct tfa_device *tfa) +{ + enum Tfa98xx_Error error; + + /* clear mtpex */ + error = tfa98xx_set_mtp(tfa, 0, TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_MSK); + if (error) + return error; + + /* set RST=1 to put the DSP in Reset */ + TFA_SET_BF(tfa, RST, 1); + + /* set ACS/coldboot state */ + error = tfaRunColdboot(tfa, 1); + + /* start tfa by playing */ + return error; +} + +static short twos(short x) +{ + return (x < 0) ? x + 512 : x; +} + +void tfa98xx_set_exttemp(struct tfa_device *tfa, short ext_temp) +{ + if ((-256 <= ext_temp) && (ext_temp <= 255)) { + /* make twos complement */ + pr_debug("Using ext temp %d C\n", twos(ext_temp)); + TFA_SET_BF(tfa, TROS, 1); + TFA_SET_BF(tfa, EXTTS, twos(ext_temp)); + } else { + pr_debug("Clearing ext temp settings\n"); + TFA_SET_BF(tfa, TROS, 0); + } +} +short tfa98xx_get_exttemp(struct tfa_device *tfa) +{ + short ext_temp = (short)TFA_GET_BF(tfa, EXTTS); + return (twos(ext_temp)); +} + +/************************** tfa simple bitfield interfacing ***************************************/ +/* convenience functions */ +enum Tfa98xx_Error tfa98xx_set_volume_level(struct tfa_device *tfa, + unsigned short vol) +{ + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + if (vol > 255) /* restricted to 8 bits */ + vol = 255; + + /* 0x00 -> 0.0 dB + * 0x01 -> -0.5 dB + * ... + * 0xFE -> -127dB + * 0xFF -> muted + */ + + /* volume value is in the top 8 bits of the register */ + return -TFA_SET_BF(tfa, VOL, (uint16_t)vol); +} + +static enum Tfa98xx_Error tfa98xx_set_mute_tfa2(struct tfa_device *tfa, + enum Tfa98xx_Mute mute) +{ + enum Tfa98xx_Error error; + + if (tfa->dev_ops.set_mute == NULL) + return Tfa98xx_Error_Not_Supported; + + switch (mute) { + case Tfa98xx_Mute_Off: + error = tfa->dev_ops.set_mute(tfa, 0); + TFA_SET_BF(tfa, AMPE, 1); + break; + case Tfa98xx_Mute_Amplifier: + case Tfa98xx_Mute_Digital: + error = tfa->dev_ops.set_mute(tfa, 1); + TFA_SET_BF(tfa, AMPE, 0); + break; + default: + return Tfa98xx_Error_Bad_Parameter; + } + + return error; +} + +static enum Tfa98xx_Error tfa98xx_set_mute_tfa1(struct tfa_device *tfa, + enum Tfa98xx_Mute mute) +{ + enum Tfa98xx_Error error; + unsigned short audioctrl_value; + unsigned short sysctrl_value; + int value; + + value = TFA_READ_REG(tfa, CFSM); /* audio control register */ + if (value < 0) + return -value; + audioctrl_value = (unsigned short)value; + value = TFA_READ_REG(tfa, AMPE); /* system control register */ + if (value < 0) + return -value; + sysctrl_value = (unsigned short)value; + + switch (mute) { + case Tfa98xx_Mute_Off: + /* previous state can be digital or amplifier mute, + * clear the cf_mute and set the enbl_amplifier bits + * + * To reduce PLOP at power on it is needed to switch the + * amplifier on with the DCDC in follower mode + * (enbl_boost = 0 ?). + * This workaround is also needed when toggling the + * powerdown bit! + */ + TFA_SET_BF_VALUE(tfa, CFSM, 0, &audioctrl_value); + TFA_SET_BF_VALUE(tfa, AMPE, 1, &sysctrl_value); + TFA_SET_BF_VALUE(tfa, DCA, 1, &sysctrl_value); + break; + case Tfa98xx_Mute_Digital: + /* expect the amplifier to run */ + /* set the cf_mute bit */ + TFA_SET_BF_VALUE(tfa, CFSM, 1, &audioctrl_value); + /* set the enbl_amplifier bit */ + TFA_SET_BF_VALUE(tfa, AMPE, 1, &sysctrl_value); + /* clear active mode */ + TFA_SET_BF_VALUE(tfa, DCA, 0, &sysctrl_value); + break; + case Tfa98xx_Mute_Amplifier: + /* clear the cf_mute bit */ + TFA_SET_BF_VALUE(tfa, CFSM, 0, &audioctrl_value); + /* clear the enbl_amplifier bit and active mode */ + TFA_SET_BF_VALUE(tfa, AMPE, 0, &sysctrl_value); + TFA_SET_BF_VALUE(tfa, DCA, 0, &sysctrl_value); + break; + default: + return Tfa98xx_Error_Bad_Parameter; + } + + error = -TFA_WRITE_REG(tfa, CFSM, audioctrl_value); + if (error) + return error; + error = -TFA_WRITE_REG(tfa, AMPE, sysctrl_value); + return error; +} + +enum Tfa98xx_Error tfa98xx_set_mute(struct tfa_device *tfa, + enum Tfa98xx_Mute mute) +{ + if (tfa->in_use == 0) { + pr_err("device is not opened \n"); + return Tfa98xx_Error_NotOpen; + } + + if (tfa->tfa_family == 1) + return tfa98xx_set_mute_tfa1(tfa, mute); + else + return tfa98xx_set_mute_tfa2(tfa, mute); +} + +/****************** patching **********************************************************/ +static enum Tfa98xx_Error tfa98xx_process_patch_file(struct tfa_device *tfa, + int length, + const unsigned char *bytes) +{ + unsigned short size; + int index = 0; + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + + while (index < length) { + size = bytes[index] + bytes[index + 1] * 256; + index += 2; + if ((index + size) > length) { + /* outside the buffer, error in the input data */ + return Tfa98xx_Error_Bad_Parameter; + } + + if (size > tfa->buffer_size) { + /* too big, must fit buffer */ + return Tfa98xx_Error_Bad_Parameter; + } + + error = tfa98xx_write_raw(tfa, size, &bytes[index]); + if (error != Tfa98xx_Error_Ok) + break; + index += size; + } + return error; +} + +/* the patch contains a header with the following + * IC revision register: 1 byte, 0xFF means don't care + * XMEM address to check: 2 bytes, big endian, 0xFFFF means don't care + * XMEM value to expect: 3 bytes, big endian + */ +static enum Tfa98xx_Error +tfa98xx_check_ic_rom_version(struct tfa_device *tfa, + const unsigned char patchheader[]) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + unsigned short checkrev, revid; + unsigned char lsb_revid; + unsigned short checkaddress; + int checkvalue; + int value = 0; + int status; + checkrev = patchheader[0]; + lsb_revid = tfa->rev & 0xff; /* only compare lower byte */ + + if ((checkrev != 0xFF) && (checkrev != lsb_revid)) + return Tfa98xx_Error_Not_Supported; + + checkaddress = (patchheader[1] << 8) + patchheader[2]; + checkvalue = + (patchheader[3] << 16) + (patchheader[4] << 8) + patchheader[5]; + if (checkaddress != 0xFFFF) { + /* before reading XMEM, check if we can access the DSP */ + error = tfa98xx_dsp_system_stable(tfa, &status); + if (error == Tfa98xx_Error_Ok) { + if (!status) { + /* DSP subsys not running */ + error = Tfa98xx_Error_DSP_not_running; + } + } + /* read register to check the correct ROM version */ + if (error == Tfa98xx_Error_Ok) { + error = mem_read(tfa, checkaddress, 1, &value); + } + if (error == Tfa98xx_Error_Ok) { + if (value != checkvalue) { + pr_err("patch file romid type check failed [0x%04x]: expected 0x%02x, actual 0x%02x\n", + checkaddress, value, checkvalue); + error = Tfa98xx_Error_Not_Supported; + } + } + } else { /* == 0xffff */ + /* check if the revid subtype is in there */ + if (checkvalue != 0xFFFFFF && checkvalue != 0) { + revid = patchheader[5] << 8 | + patchheader[0]; /* full revid */ + if (revid != tfa->rev) { + pr_err("patch file device type check failed: expected 0x%02x, actual 0x%02x\n", + tfa->rev, revid); + return Tfa98xx_Error_Not_Supported; + } + } + } + + return error; +} + +#define PATCH_HEADER_LENGTH 6 +enum Tfa98xx_Error tfa_dsp_patch(struct tfa_device *tfa, int patchLength, + const unsigned char *patchBytes) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + int status; + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + if (patchLength < PATCH_HEADER_LENGTH) + return Tfa98xx_Error_Bad_Parameter; + + error = tfa98xx_check_ic_rom_version(tfa, patchBytes); + if (Tfa98xx_Error_Ok != error) { + return error; + } + + /* for non-dsp solution, we don't need to check ACS. */ + if (tfa->is_probus_device == 0) { + tfa98xx_dsp_system_stable(tfa, &status); + if (!status) + return Tfa98xx_Error_NoClock; + + /******MCH_TO_TEST**************/ + if (error == Tfa98xx_Error_Ok) { + pr_info("tfa cold boot patch\n"); + error = tfaRunColdboot(tfa, 1); + if (error) { + pr_err("tfa_dsp_patch DSP_not_running\n"); + return Tfa98xx_Error_DSP_not_running; + } + } + /**************************/ + } + error = tfa98xx_process_patch_file(tfa, + patchLength - PATCH_HEADER_LENGTH, + patchBytes + PATCH_HEADER_LENGTH); + + return error; +} + +/****************** end patching **********************************************************/ + +TFA_INTERNAL enum Tfa98xx_Error tfa98xx_wait_result(struct tfa_device *tfa, + int wait_retry_count) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + int cf_status; /* the contents of the CF_STATUS register */ + int tries = 0; + do { + cf_status = TFA_GET_BF(tfa, ACK); + if (cf_status < 0) + error = -cf_status; + tries++; + } + // i2c_cmd_ack + /* don't wait forever, DSP is pretty quick to respond (< 1ms) */ + while ((error == Tfa98xx_Error_Ok) && + ((cf_status & CF_STATUS_I2C_CMD_ACK) == 0) && + (tries < wait_retry_count)); + if (tries >= wait_retry_count) { + /* something wrong with communication with DSP */ + error = Tfa98xx_Error_DSP_not_running; + } + return error; +} + +/* + * * support functions for data conversion + */ +/** + convert memory bytes to signed 24 bit integers + input: bytes contains "num_bytes" byte elements + output: data contains "num_bytes/3" int24 elements +*/ +void tfa98xx_convert_bytes2data(int num_bytes, const unsigned char bytes[], + int data[]) +{ + int i; /* index for data */ + int k; /* index for bytes */ + int d; + int num_data = num_bytes / 3; + _ASSERT((num_bytes % 3) == 0); + for (i = 0, k = 0; i < num_data; ++i, k += 3) { + d = (bytes[k] << 16) | (bytes[k + 1] << 8) | (bytes[k + 2]); + _ASSERT(d >= 0); + _ASSERT(d < (1 << 24)); /* max 24 bits in use */ + if (bytes[k] & 0x80) /* sign bit was set */ + d = -((1 << 24) - d); + + data[i] = d; + } +} + +/** + convert signed 32 bit integers to 24 bit aligned bytes + input: data contains "num_data" int elements + output: bytes contains "3 * num_data" byte elements +*/ +void tfa98xx_convert_data2bytes(int num_data, const int data[], + unsigned char bytes[]) +{ + int i; /* index for data */ + int k; /* index for bytes */ + int d; + /* note: cannot just take the lowest 3 bytes from the 32 bit + * integer, because also need to take care of clipping any + * value > 2&23 */ + for (i = 0, k = 0; i < num_data; ++i, k += 3) { + if (data[i] >= 0) + d = MIN(data[i], (1 << 23) - 1); + else { + /* 2's complement */ + d = (1 << 24) - MIN(-data[i], 1 << 23); + } + _ASSERT(d >= 0); + _ASSERT(d < (1 << 24)); /* max 24 bits in use */ + bytes[k] = (d >> 16) & 0xFF; /* MSB */ + bytes[k + 1] = (d >> 8) & 0xFF; + bytes[k + 2] = (d) & 0xFF; /* LSB */ + } +} + +/* + * DSP RPC message support functions + * depending on framework to be up and running + * need base i2c of memaccess (tfa1=0x70/tfa2=0x90) + */ + +/* write dsp messages in function tfa_dsp_msg() */ +/* note the 'old' write_parameter() was more efficient because all i2c was in one burst transaction */ + +//TODO properly handle bitfields: state should be restored! (now it will change eg dmesg field to xmem) +enum Tfa98xx_Error tfa_dsp_msg_write(struct tfa_device *tfa, int length, + const char *buffer) +{ + int offset = 0; + int chunk_size = ROUND_DOWN(tfa->buffer_size, 3); /* XMEM word size */ + int remaining_bytes = length; + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + uint16_t cfctl; + int value; + + value = TFA_READ_REG(tfa, DMEM); + if (value < 0) { + error = -value; + return error; + } + cfctl = (uint16_t)value; + /* assume no I2C errors from here */ + + TFA_SET_BF_VALUE(tfa, DMEM, (uint16_t)Tfa98xx_DMEM_XMEM, + &cfctl); /* set cf ctl to DMEM */ + TFA_SET_BF_VALUE(tfa, AIF, 0, &cfctl); /* set to autoincrement */ + TFA_WRITE_REG(tfa, DMEM, cfctl); + + /* xmem[1] is start of message + * direct write to register to save cycles avoiding read-modify-write + */ + TFA_WRITE_REG(tfa, MADD, 1); + + /* due to autoincrement in cf_ctrl, next write will happen at + * the next address */ + while ((error == Tfa98xx_Error_Ok) && (remaining_bytes > 0)) { + if (remaining_bytes < chunk_size) + chunk_size = remaining_bytes; + /* else chunk_size remains at initialize value above */ + error = tfa98xx_write_data(tfa, FAM_TFA98XX_CF_MEM, chunk_size, + (const unsigned char *)buffer + + offset); + remaining_bytes -= chunk_size; + offset += chunk_size; + } + + /* notify the DSP */ + if (error == Tfa98xx_Error_Ok) { + /* cf_int=0, cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */ + /* set the cf_req1 and cf_int bit */ + TFA_SET_BF_VALUE(tfa, REQCMD, 0x01, &cfctl); /* bit 0 */ + TFA_SET_BF_VALUE(tfa, CFINT, 1, &cfctl); + error = -TFA_WRITE_REG(tfa, CFINT, cfctl); + } + + return error; +} + +enum Tfa98xx_Error tfa_dsp_msg_write_id(struct tfa_device *tfa, int length, + const char *buffer, uint8_t cmdid[3]) +{ + int offset = 0; + int chunk_size = ROUND_DOWN(tfa->buffer_size, 3); /* XMEM word size */ + int remaining_bytes = length; + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + uint16_t cfctl; + int value; + + value = TFA_READ_REG(tfa, DMEM); + if (value < 0) { + error = -value; + return error; + } + cfctl = (uint16_t)value; + /* assume no I2C errors from here */ + + TFA_SET_BF_VALUE(tfa, DMEM, (uint16_t)Tfa98xx_DMEM_XMEM, + &cfctl); /* set cf ctl to DMEM */ + TFA_SET_BF_VALUE(tfa, AIF, 0, &cfctl); /* set to autoincrement */ + TFA_WRITE_REG(tfa, DMEM, cfctl); + + /* xmem[1] is start of message + * direct write to register to save cycles avoiding read-modify-write + */ + TFA_WRITE_REG(tfa, MADD, 1); + + /* write cmd-id */ + error = tfa98xx_write_data(tfa, FAM_TFA98XX_CF_MEM, 3, + (const unsigned char *)cmdid); + + /* due to autoincrement in cf_ctrl, next write will happen at + * the next address */ + while ((error == Tfa98xx_Error_Ok) && (remaining_bytes > 0)) { + if (remaining_bytes < chunk_size) + chunk_size = remaining_bytes; + /* else chunk_size remains at initialize value above */ + error = tfa98xx_write_data(tfa, FAM_TFA98XX_CF_MEM, chunk_size, + (const unsigned char *)buffer + + offset); + remaining_bytes -= chunk_size; + offset += chunk_size; + } + + /* notify the DSP */ + if (error == Tfa98xx_Error_Ok) { + /* cf_int=0, cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */ + /* set the cf_req1 and cf_int bit */ + TFA_SET_BF_VALUE(tfa, REQCMD, 0x01, &cfctl); /* bit 0 */ + TFA_SET_BF_VALUE(tfa, CFINT, 1, &cfctl); + error = -TFA_WRITE_REG(tfa, CFINT, cfctl); + } + + return error; +} + +/* +* status function used by tfa_dsp_msg() to retrieve command/msg status: +* return a <0 status of the DSP did not ACK. +*/ +enum Tfa98xx_Error tfa_dsp_msg_status(struct tfa_device *tfa, int *pRpcStatus) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + + error = tfa98xx_wait_result(tfa, 2); /* 2 is only one try */ + if (error == Tfa98xx_Error_DSP_not_running) { + *pRpcStatus = -1; + return Tfa98xx_Error_Ok; + } else if (error != Tfa98xx_Error_Ok) + return error; + + error = tfa98xx_check_rpc_status(tfa, pRpcStatus); + + return error; +} + +const char *tfa98xx_get_i2c_status_id_string(int status) +{ + const char *p_id_str; + + switch (status) { + case Tfa98xx_DSP_Not_Running: + p_id_str = "No response from DSP"; + break; + case Tfa98xx_I2C_Req_Done: + p_id_str = "Ok"; + break; + case Tfa98xx_I2C_Req_Busy: + p_id_str = "Request is being processed"; + break; + case Tfa98xx_I2C_Req_Invalid_M_ID: + p_id_str = "Provided M-ID does not fit in valid rang [0..2]"; + break; + case Tfa98xx_I2C_Req_Invalid_P_ID: + p_id_str = + "Provided P-ID is not valid in the given M-ID context"; + break; + case Tfa98xx_I2C_Req_Invalid_CC: + p_id_str = + "Invalid channel configuration bits (SC|DS|DP|DC) combination"; + break; + case Tfa98xx_I2C_Req_Invalid_Seq: + p_id_str = + "Invalid sequence of commands, in case the DSP expects some commands in a specific order"; + break; + case Tfa98xx_I2C_Req_Invalid_Param: + p_id_str = "Generic error, invalid parameter"; + break; + case Tfa98xx_I2C_Req_Buffer_Overflow: + p_id_str = + "I2C buffer has overflowed: host has sent too many parameters, memory integrity is not guaranteed"; + break; + case Tfa98xx_I2C_Req_Calib_Busy: + p_id_str = "Calibration not completed"; + break; + case Tfa98xx_I2C_Req_Calib_Failed: + p_id_str = "Calibration failed"; + break; + + default: + p_id_str = "Unspecified error"; + } + + return p_id_str; +} + +enum Tfa98xx_Error tfa_dsp_msg_read(struct tfa_device *tfa, int length, + unsigned char *bytes) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + int burst_size; /* number of words per burst size */ + int bytes_per_word = 3; + int num_bytes; + int offset = 0; + unsigned short start_offset = 2; /* msg starts @xmem[2] ,[1]=cmd */ + + if (length > TFA2_MAX_PARAM_SIZE) + return Tfa98xx_Error_Bad_Parameter; + + TFA_SET_BF(tfa, DMEM, (uint16_t)Tfa98xx_DMEM_XMEM); + error = -TFA_WRITE_REG(tfa, MADD, start_offset); + if (error != Tfa98xx_Error_Ok) + return error; + + num_bytes = length; /* input param */ + while (num_bytes > 0) { + burst_size = ROUND_DOWN(tfa->buffer_size, bytes_per_word); + if (num_bytes < burst_size) + burst_size = num_bytes; + error = tfa98xx_read_data(tfa, FAM_TFA98XX_CF_MEM, burst_size, + bytes + offset); + if (error != Tfa98xx_Error_Ok) + return error; + + num_bytes -= burst_size; + offset += burst_size; + } + + return error; +} + +enum Tfa98xx_Error dsp_msg(struct tfa_device *tfa, int length24, + const char *buf24) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + int lastmessage = 0; + uint8_t *blob; + int i; + int *intbuf = NULL; + char *buf = (char *)buf24; + int length = length24; + + if (tfa->convert_dsp32) { + int idx = 0; + + length = 4 * length24 / 3; + intbuf = kmem_cache_alloc(tfa->cachep, GFP_KERNEL); + buf = (char *)intbuf; + + /* convert 24 bit DSP messages to a 32 bit integer */ + for (i = 0; i < length24; i += 3) { + int tmp = (buf24[i] << 16) + (buf24[i + 1] << 8) + + buf24[i + 2]; + /* Sign extend to 32-bit from 24-bit */ + intbuf[idx++] = ((int32_t)tmp << 8) >> 8; + } + } + + /* Only create multi-msg when the dsp is cold */ + if (tfa->ext_dsp == 1) { + /* Creating the multi-msg */ + error = tfa_tib_dsp_msgmulti(tfa, length, buf); + if (error == Tfa98xx_Error_Fail) + return Tfa98xx_Error_Fail; + + /* if the buffer is full we need to send the existing message and add the current message */ + if (error == Tfa98xx_Error_Buffer_too_small) { + int len; + + /* (a) send the existing (full) message */ + blob = kmalloc(64 * 1024, + GFP_KERNEL); // max length is 64k + len = tfa_tib_dsp_msgmulti(tfa, -1, (const char *)blob); + if (tfa->verbose) { + pr_debug( + "Multi-message buffer full. Sending multi-message, length=%d \n", + len); + } + if (tfa->has_msg == 0) /* via i2c */ { + /* Send tot the target selected */ + error = (tfa->dev_ops.dsp_msg)( + tfa, len, (const char *)blob); + } else { /* via msg hal */ + error = tfa98xx_write_dsp(tfa, len, + (const char *)blob); + } + kfree(blob); + + /* (b) add the current DSP message to a new multi-message */ + error = tfa_tib_dsp_msgmulti(tfa, length, buf); + if (error == Tfa98xx_Error_Fail) { + return Tfa98xx_Error_Fail; + } + } + + lastmessage = error; + + /* When the lastmessage is done we can send the multi-msg to the target */ + if (lastmessage == 1) { + /* Get the full multi-msg data */ + blob = kmalloc(64 * 1024, + GFP_KERNEL); //max length is 64k + length = tfa_tib_dsp_msgmulti(tfa, -1, + (const char *)blob); + + if (tfa->verbose) + pr_debug( + "Last message for the multi-message received. Multi-message length=%d \n", + length); + + if (tfa->has_msg == 0) /* via i2c */ { + /* Send tot the target selected */ + error = (tfa->dev_ops.dsp_msg)( + tfa, length, (const char *)blob); + } else { /* via msg hal */ + error = tfa98xx_write_dsp(tfa, length, + (const char *)blob); + } + + kfree(blob); /* Free the kmalloc blob */ + lastmessage = 0; /* reset to be able to re-start */ + } + } else { + if (tfa->has_msg == 0) /* via i2c */ { + error = (tfa->dev_ops.dsp_msg)(tfa, length, buf); + } else { /* via msg hal */ + error = tfa98xx_write_dsp(tfa, length, + (const char *)buf); + } + } + + if (error != Tfa98xx_Error_Ok) + error = (enum Tfa98xx_Error)( + error + + Tfa98xx_Error_RpcBase); /* Get actual error code from softDSP */ + + /* DSP verbose has argument 0x04 */ + if ((tfa->verbose & 0x04) != 0) { + pr_debug("DSP w [%d]: ", length); + for (i = 0; i < length; i++) + pr_debug("0x%02x ", (uint8_t)buf[i]); + pr_debug("\n"); + } + + if (tfa->convert_dsp32) { + kmem_cache_free(tfa->cachep, intbuf); + } + + return error; +} + +enum Tfa98xx_Error dsp_msg_read(struct tfa_device *tfa, int length24, + unsigned char *bytes24) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + int i; + int length = length24; + unsigned char *bytes = bytes24; + + if (tfa->convert_dsp32) { + length = 4 * length24 / 3; + bytes = kmem_cache_alloc(tfa->cachep, GFP_KERNEL); + } + + if (tfa->has_msg == 0) /* via i2c */ { + error = (tfa->dev_ops.dsp_msg_read)(tfa, length, bytes); + } else { /* via msg hal */ + error = tfa98xx_read_dsp(tfa, length, bytes); + } + + if (error != Tfa98xx_Error_Ok) + error = (enum Tfa98xx_Error)( + error + + Tfa98xx_Error_RpcBase); /* Get actual error code from softDSP */ + + /* DSP verbose has argument 0x04 */ + if ((tfa->verbose & 0x04) != 0) { + pr_debug("DSP R [%d]: ", length); + for (i = 0; i < length; i++) + pr_debug("0x%02x ", (uint8_t)bytes[i]); + pr_debug("\n"); + } + + if (tfa->convert_dsp32) { + int idx = 0; + + /* convert 32 bit LE to 24 bit BE */ + for (i = 0; i < length; i += 4) { + bytes24[idx++] = bytes[i + 2]; + bytes24[idx++] = bytes[i + 1]; + bytes24[idx++] = bytes[i + 0]; + } + + kmem_cache_free(tfa->cachep, bytes); + } + + return error; +} + +enum Tfa98xx_Error reg_read(struct tfa_device *tfa, unsigned char subaddress, + unsigned short *value) +{ + enum Tfa98xx_Error error; + + error = (tfa->dev_ops.reg_read)(tfa, subaddress, value); + if (error != Tfa98xx_Error_Ok) + error = (enum Tfa98xx_Error)( + error + + Tfa98xx_Error_RpcBase); /* Get actual error code from softDSP */ + + return error; +} + +enum Tfa98xx_Error reg_write(struct tfa_device *tfa, unsigned char subaddress, + unsigned short value) +{ + enum Tfa98xx_Error error; + + error = (tfa->dev_ops.reg_write)(tfa, subaddress, value); + if (error != Tfa98xx_Error_Ok) + error = (enum Tfa98xx_Error)( + error + + Tfa98xx_Error_RpcBase); /* Get actual error code from softDSP */ + + return error; +} + +enum Tfa98xx_Error mem_read(struct tfa_device *tfa, unsigned int start_offset, + int num_words, int *pValues) +{ + enum Tfa98xx_Error error; + + error = (tfa->dev_ops.mem_read)(tfa, start_offset, num_words, pValues); + if (error != Tfa98xx_Error_Ok) + error = (enum Tfa98xx_Error)( + error + + Tfa98xx_Error_RpcBase); /* Get actual error code from softDSP */ + + return error; +} + +enum Tfa98xx_Error mem_write(struct tfa_device *tfa, unsigned short address, + int value, int memtype) +{ + enum Tfa98xx_Error error; + + error = (tfa->dev_ops.mem_write)(tfa, address, value, memtype); + if (error != Tfa98xx_Error_Ok) + error = (enum Tfa98xx_Error)( + error + + Tfa98xx_Error_RpcBase); /* Get actual error code from softDSP */ + + return error; +} + +/* + * write/read raw msg functions : + * the buffer is provided in little endian format, each word occupying 3 bytes, length is in bytes. + * The functions will return immediately and do not not wait for DSP reponse. + */ +#define MAX_WORDS (300) +enum Tfa98xx_Error tfa_dsp_msg(struct tfa_device *tfa, int length, + const char *buf) +{ + enum Tfa98xx_Error error; + int tries, rpc_status = Tfa98xx_I2C_Req_Done; + + /* write the message and notify the DSP */ + error = tfa_dsp_msg_write(tfa, length, buf); + if (error != Tfa98xx_Error_Ok) + return error; + + /* get the result from the DSP (polling) */ + for (tries = TFA98XX_WAITRESULT_NTRIES; tries > 0; tries--) { + error = tfa_dsp_msg_status(tfa, &rpc_status); + if (error == Tfa98xx_Error_Ok && + rpc_status == Tfa98xx_I2C_Req_Done) + break; + /* If the rpc status is a specific error we want to know it. + * If it is busy or not running it should retry + */ + if (rpc_status != Tfa98xx_I2C_Req_Busy && + rpc_status != Tfa98xx_DSP_Not_Running) + break; + } + + if (rpc_status != Tfa98xx_I2C_Req_Done) { + /* DSP RPC call returned an error */ + error = (enum Tfa98xx_Error)(rpc_status + + Tfa98xx_Error_RpcBase); + pr_debug("DSP msg status: %d (%s)\n", rpc_status, + tfa98xx_get_i2c_status_id_string(rpc_status)); + } + return error; +} + +/** + * write/read raw msg functions: + * the buffer is provided in little endian format, each word occupying 3 bytes, length is in bytes. + * The functions will return immediately and do not not wait for DSP reponse. + * An ID is added to modify the command-ID + */ +enum Tfa98xx_Error tfa_dsp_msg_id(struct tfa_device *tfa, int length, + const char *buf, uint8_t cmdid[3]) +{ + enum Tfa98xx_Error error; + int tries, rpc_status = Tfa98xx_I2C_Req_Done; + + /* write the message and notify the DSP */ + error = tfa_dsp_msg_write_id(tfa, length, buf, cmdid); + if (error != Tfa98xx_Error_Ok) + return error; + + /* get the result from the DSP (polling) */ + for (tries = TFA98XX_WAITRESULT_NTRIES; tries > 0; tries--) { + error = tfa_dsp_msg_status(tfa, &rpc_status); + if (error == Tfa98xx_Error_Ok && + rpc_status == Tfa98xx_I2C_Req_Done) + break; + } + + if (rpc_status != Tfa98xx_I2C_Req_Done) { + /* DSP RPC call returned an error */ + error = (enum Tfa98xx_Error)(rpc_status + + Tfa98xx_Error_RpcBase); + pr_debug("DSP msg status: %d (%s)\n", rpc_status, + tfa98xx_get_i2c_status_id_string(rpc_status)); + } + return error; +} + +/* read the return code for the RPC call */ +TFA_INTERNAL enum Tfa98xx_Error tfa98xx_check_rpc_status(struct tfa_device *tfa, + int *pRpcStatus) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + /* the value to sent to the * CF_CONTROLS register: cf_req=00000000, + * cf_int=0, cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */ + unsigned short cf_ctrl = 0x0002; + /* memory address to be accessed (0: Status, 1: ID, 2: parameters) */ + unsigned short cf_mad = 0x0000; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + if (pRpcStatus == NULL) + return Tfa98xx_Error_Bad_Parameter; + + /* 1) write DMEM=XMEM to the DSP XMEM */ + { + /* minimize the number of I2C transactions by making use of the autoincrement in I2C */ + unsigned char buffer[4]; + /* first the data for CF_CONTROLS */ + buffer[0] = (unsigned char)((cf_ctrl >> 8) & 0xFF); + buffer[1] = (unsigned char)(cf_ctrl & 0xFF); + /* write the contents of CF_MAD which is the subaddress following CF_CONTROLS */ + buffer[2] = (unsigned char)((cf_mad >> 8) & 0xFF); + buffer[3] = (unsigned char)(cf_mad & 0xFF); + error = tfa98xx_write_data(tfa, FAM_TFA98XX_CF_CONTROLS, + sizeof(buffer), buffer); + } + if (error == Tfa98xx_Error_Ok) { + /* read 1 word (24 bit) from XMEM */ + error = tfa98xx_dsp_read_mem(tfa, 0, 1, pRpcStatus); + } + + return error; +} + +/***************************** xmem only **********************************/ +enum Tfa98xx_Error tfa98xx_dsp_read_mem(struct tfa_device *tfa, + unsigned int start_offset, + int num_words, int *pValues) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + unsigned char *bytes; + int burst_size; /* number of words per burst size */ + const int bytes_per_word = 3; + int dmem; + int num_bytes; + int *p; + + bytes = (unsigned char *)kmem_cache_alloc(tfa->cachep, GFP_KERNEL); + if (bytes == NULL) + return Tfa98xx_Error_Fail; + + /* If no offset is given, assume XMEM! */ + if (((start_offset >> 16) & 0xf) > 0) + dmem = (start_offset >> 16) & 0xf; + else + dmem = Tfa98xx_DMEM_XMEM; + + /* Remove offset from adress */ + start_offset = start_offset & 0xffff; + num_bytes = num_words * bytes_per_word; + p = pValues; + + TFA_SET_BF(tfa, DMEM, (uint16_t)dmem); + error = -TFA_WRITE_REG(tfa, MADD, (unsigned short)start_offset); + if (error != Tfa98xx_Error_Ok) + goto tfa98xx_dsp_read_mem_exit; + + for (; num_bytes > 0;) { + burst_size = ROUND_DOWN(tfa->buffer_size, bytes_per_word); + if (num_bytes < burst_size) + burst_size = num_bytes; + + _ASSERT(burst_size <= sizeof(bytes)); + error = tfa98xx_read_data(tfa, FAM_TFA98XX_CF_MEM, burst_size, + bytes); + if (error != Tfa98xx_Error_Ok) + goto tfa98xx_dsp_read_mem_exit; + + tfa98xx_convert_bytes2data(burst_size, bytes, p); + + num_bytes -= burst_size; + p += burst_size / bytes_per_word; + } + +tfa98xx_dsp_read_mem_exit: + kmem_cache_free(tfa->cachep, bytes); + + return error; +} + +enum Tfa98xx_Error tfa98xx_dsp_write_mem_word(struct tfa_device *tfa, + unsigned short address, int value, + int memtype) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + unsigned char bytes[3]; + + TFA_SET_BF(tfa, DMEM, (uint16_t)memtype); + + error = -TFA_WRITE_REG(tfa, MADD, address); + if (error != Tfa98xx_Error_Ok) + return error; + + tfa98xx_convert_data2bytes(1, &value, bytes); + error = tfa98xx_write_data(tfa, FAM_TFA98XX_CF_MEM, 3, bytes); + + return error; +} + +enum Tfa98xx_Error tfa_cont_write_filterbank(struct tfa_device *tfa, + nxpTfaFilter_t *filter) +{ + unsigned char biquad_index; + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + + for (biquad_index = 0; biquad_index < 10; biquad_index++) { + if (filter[biquad_index].enabled) { + error = tfa_dsp_cmd_id_write( + tfa, MODULE_BIQUADFILTERBANK, + biquad_index + 1, //start @1 + sizeof(filter[biquad_index].biquad.bytes), + filter[biquad_index].biquad.bytes); + } else { + error = Tfa98xx_DspBiquad_Disable(tfa, + biquad_index + 1); + } + if (error) + return error; + } + + return error; +} + +enum Tfa98xx_Error Tfa98xx_DspBiquad_Disable(struct tfa_device *tfa, + int biquad_index) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + int coeff_buffer[BIQUAD_COEFF_SIZE]; + unsigned char bytes[3 + BIQUAD_COEFF_SIZE * 3]; + int nr = 0; + + if (biquad_index > TFA98XX_BIQUAD_NUM) + return Tfa98xx_Error_Bad_Parameter; + if (biquad_index < 1) + return Tfa98xx_Error_Bad_Parameter; + + /* make opcode */ + bytes[nr++] = 0; + bytes[nr++] = MODULE_BIQUADFILTERBANK + 128; + bytes[nr++] = (unsigned char)biquad_index; + + /* set in correct order and format for the DSP */ + coeff_buffer[0] = (int)-8388608; /* -1.0f */ + coeff_buffer[1] = 0; + coeff_buffer[2] = 0; + coeff_buffer[3] = 0; + coeff_buffer[4] = 0; + coeff_buffer[5] = 0; + + /* convert to packed 24 */ + tfa98xx_convert_data2bytes(BIQUAD_COEFF_SIZE, coeff_buffer, &bytes[nr]); + nr += BIQUAD_COEFF_SIZE * 3; + + error = dsp_msg(tfa, nr, (char *)bytes); + + return error; +} + +/* wrapper for dsp_msg that adds opcode */ +enum Tfa98xx_Error tfa_dsp_cmd_id_write(struct tfa_device *tfa, + unsigned char module_id, + unsigned char param_id, int num_bytes, + const unsigned char data[]) +{ + enum Tfa98xx_Error error; + unsigned char *buffer; + int nr = 0; + + buffer = kmem_cache_alloc(tfa->cachep, GFP_KERNEL); + if (buffer == NULL) + return Tfa98xx_Error_Fail; + + buffer[nr++] = tfa->spkr_select; + buffer[nr++] = module_id + 128; + buffer[nr++] = param_id; + + memcpy(&buffer[nr], data, num_bytes); + nr += num_bytes; + + error = dsp_msg(tfa, nr, (char *)buffer); + + kmem_cache_free(tfa->cachep, buffer); + + return error; +} + +/* wrapper for dsp_msg that adds opcode */ +/* this is as the former tfa98xx_dsp_get_param() */ +enum Tfa98xx_Error tfa_dsp_cmd_id_write_read(struct tfa_device *tfa, + unsigned char module_id, + unsigned char param_id, + int num_bytes, + unsigned char data[]) +{ + enum Tfa98xx_Error error; + unsigned char buffer[3]; + int nr = 0; + + if (num_bytes <= 0) { + pr_debug( + "Error: The number of READ bytes is smaller or equal to 0! \n"); + return Tfa98xx_Error_Fail; + } + + if ((tfa->is_probus_device) && (tfa->cnt->ndev == 1) && + (param_id == SB_PARAM_GET_RE25C || + param_id == SB_PARAM_GET_LSMODEL || + param_id == SB_PARAM_GET_ALGO_PARAMS)) { + /* Modifying the ID for GetRe25C */ + buffer[nr++] = 4; + } else { + buffer[nr++] = tfa->spkr_select; + } + buffer[nr++] = module_id + 128; + buffer[nr++] = param_id; + + error = dsp_msg(tfa, nr, (char *)buffer); + if (error != Tfa98xx_Error_Ok) + return error; + + /* read the data from the dsp */ + error = dsp_msg_read(tfa, num_bytes, data); + return error; +} + +/* wrapper for dsp_msg that adds opcode and 3 bytes required for coefs */ +enum Tfa98xx_Error tfa_dsp_cmd_id_coefs(struct tfa_device *tfa, + unsigned char module_id, + unsigned char param_id, int num_bytes, + unsigned char data[]) +{ + enum Tfa98xx_Error error; + unsigned char buffer[2 * 3]; + int nr = 0; + + buffer[nr++] = tfa->spkr_select; + buffer[nr++] = module_id + 128; + buffer[nr++] = param_id; + + buffer[nr++] = 0; + buffer[nr++] = 0; + buffer[nr++] = 0; + + error = dsp_msg(tfa, nr, (char *)buffer); + if (error != Tfa98xx_Error_Ok) + return error; + + /* read the data from the dsp */ + error = dsp_msg_read(tfa, num_bytes, data); + + return error; +} + +/* wrapper for dsp_msg that adds opcode and 3 bytes required for MBDrcDynamics */ +enum Tfa98xx_Error +tfa_dsp_cmd_id_MBDrc_dynamics(struct tfa_device *tfa, unsigned char module_id, + unsigned char param_id, int index_subband, + int num_bytes, unsigned char data[]) +{ + enum Tfa98xx_Error error; + unsigned char buffer[2 * 3]; + int nr = 0; + + buffer[nr++] = tfa->spkr_select; + buffer[nr++] = module_id + 128; + buffer[nr++] = param_id; + + buffer[nr++] = 0; + buffer[nr++] = 0; + buffer[nr++] = (unsigned char)index_subband; + + error = dsp_msg(tfa, nr, (char *)buffer); + if (error != Tfa98xx_Error_Ok) + return error; + + /* read the data from the dsp */ + error = dsp_msg_read(tfa, num_bytes, data); + + return error; +} + +enum Tfa98xx_Error tfa98xx_dsp_write_preset(struct tfa_device *tfa, int length, + const unsigned char *p_preset_bytes) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + if (p_preset_bytes != NULL) { + /* by design: keep the data opaque and no + * interpreting/calculation */ + error = tfa_dsp_cmd_id_write(tfa, MODULE_SPEAKERBOOST, + SB_PARAM_SET_PRESET, length, + p_preset_bytes); + } else { + error = Tfa98xx_Error_Bad_Parameter; + } + return error; +} + +/* + * get features from MTP + */ +enum Tfa98xx_Error tfa98xx_dsp_get_hw_feature_bits(struct tfa_device *tfa, + int *features) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + uint32_t value; + uint16_t mtpbf; + + /* return the cache data if it's valid */ + if (tfa->hw_feature_bits != -1) { + *features = tfa->hw_feature_bits; + } else { + /* for tfa1 check if we have clock */ + if (tfa->tfa_family == 1) { + int status; + tfa98xx_dsp_system_stable(tfa, &status); + if (!status) { + get_hw_features_from_cnt(tfa, features); + /* skip reading MTP: */ + return (*features == -1) ? Tfa98xx_Error_Fail : + Tfa98xx_Error_Ok; + } + mtpbf = 0x850f; /* MTP5 for tfa1,16 bits */ + } else + mtpbf = 0xf907; /* MTP9 for tfa2, 8 bits */ + value = tfa_read_reg(tfa, mtpbf) & 0xffff; + *features = tfa->hw_feature_bits = value; + } + + return error; +} + +enum Tfa98xx_Error tfa98xx_dsp_get_sw_feature_bits(struct tfa_device *tfa, + int features[2]) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + const int byte_size = 2 * 3; + unsigned char bytes[2 * 3]; + + /* return the cache data if it's valid */ + if (tfa->sw_feature_bits[0] != -1) { + features[0] = tfa->sw_feature_bits[0]; + features[1] = tfa->sw_feature_bits[1]; + } else { + /* for tfa1 check if we have clock */ + if (tfa->tfa_family == 1) { + int status; + tfa98xx_dsp_system_stable(tfa, &status); + if (!status) { + get_sw_features_from_cnt(tfa, features); + /* skip reading MTP: */ + return (features[0] == -1) ? + Tfa98xx_Error_Fail : + Tfa98xx_Error_Ok; + } + } + error = tfa_dsp_cmd_id_write_read(tfa, MODULE_FRAMEWORK, + FW_PAR_ID_GET_FEATURE_INFO, + byte_size, bytes); + + if (error != Tfa98xx_Error_Ok) { + /* old ROM code may respond with Tfa98xx_Error_RpcParamId */ + return error; + } + + tfa98xx_convert_bytes2data(byte_size, bytes, features); + } + return error; +} + +enum Tfa98xx_Error tfa98xx_dsp_get_state_info(struct tfa_device *tfa, + unsigned char bytes[], + unsigned int *statesize) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + int bSupportFramework = 0; + unsigned int stateSize = 9; + + err = tfa98xx_dsp_support_framework(tfa, &bSupportFramework); + if (err == Tfa98xx_Error_Ok) { + if (bSupportFramework) { + err = tfa_dsp_cmd_id_write_read(tfa, MODULE_FRAMEWORK, + FW_PARAM_GET_STATE, + 3 * stateSize, bytes); + } else { + /* old ROM code, ask SpeakerBoost and only do first portion */ + stateSize = 8; + err = tfa_dsp_cmd_id_write_read(tfa, + MODULE_SPEAKERBOOST, + SB_PARAM_GET_STATE, + 3 * stateSize, bytes); + } + } + + *statesize = stateSize; + + return err; +} + +enum Tfa98xx_Error tfa98xx_dsp_support_drc(struct tfa_device *tfa, + int *pbSupportDrc) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + + *pbSupportDrc = 0; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + if (tfa->supportDrc != supportNotSet) { + *pbSupportDrc = (tfa->supportDrc == supportYes); + } else { + int featureBits[2]; + + error = tfa98xx_dsp_get_sw_feature_bits(tfa, featureBits); + if (error == Tfa98xx_Error_Ok) { + /* easy case: new API available */ + /* bit=0 means DRC enabled */ + *pbSupportDrc = (featureBits[0] & FEATURE1_DRC) == 0; + } else if (error == Tfa98xx_Error_RpcParamId) { + /* older ROM code, doesn't support it */ + *pbSupportDrc = 0; + error = Tfa98xx_Error_Ok; + } + /* else some other error, return transparently */ + /* pbSupportDrc only changed when error == Tfa98xx_Error_Ok */ + + if (error == Tfa98xx_Error_Ok) { + tfa->supportDrc = + *pbSupportDrc ? supportYes : supportNo; + } + } + return error; +} + +enum Tfa98xx_Error tfa98xx_dsp_support_framework(struct tfa_device *tfa, + int *pbSupportFramework) +{ + int featureBits[2] = { 0, 0 }; + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + + _ASSERT(pbSupportFramework != 0); + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + if (tfa->supportFramework != supportNotSet) { + if (tfa->supportFramework == supportNo) + *pbSupportFramework = 0; + else + *pbSupportFramework = 1; + } else { + error = tfa98xx_dsp_get_sw_feature_bits(tfa, featureBits); + if (error == Tfa98xx_Error_Ok) { + *pbSupportFramework = 1; + tfa->supportFramework = supportYes; + } else { + *pbSupportFramework = 0; + tfa->supportFramework = supportNo; + error = Tfa98xx_Error_Ok; + } + } + + /* *pbSupportFramework only changed when error == Tfa98xx_Error_Ok */ + return error; +} + +enum Tfa98xx_Error +tfa98xx_dsp_write_speaker_parameters(struct tfa_device *tfa, int length, + const unsigned char *p_speaker_bytes) +{ + enum Tfa98xx_Error error; + int bSupportDrc; + + if (p_speaker_bytes != NULL) { + /* by design: keep the data opaque and no + * interpreting/calculation */ + /* Use long WaitResult retry count */ + error = tfa_dsp_cmd_id_write(tfa, MODULE_SPEAKERBOOST, + SB_PARAM_SET_LSMODEL, length, + p_speaker_bytes); + } else { + error = Tfa98xx_Error_Bad_Parameter; + } + + if (error != Tfa98xx_Error_Ok) + return error; + + error = tfa98xx_dsp_support_drc(tfa, &bSupportDrc); + if (error != Tfa98xx_Error_Ok) + return error; + + if (bSupportDrc) { + /* Need to set AgcGainInsert back to PRE, + * as the SetConfig forces it to POST */ + uint8_t bytes[3] = { 0, 0, 0 }; + + error = tfa_dsp_cmd_id_write(tfa, MODULE_SPEAKERBOOST, + SB_PARAM_SET_AGCINS, 3, bytes); + } + + return error; +} + +enum Tfa98xx_Error tfa98xx_dsp_write_config(struct tfa_device *tfa, int length, + const unsigned char *p_config_bytes) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + int bSupportDrc; + + error = tfa_dsp_cmd_id_write(tfa, MODULE_SPEAKERBOOST, + SB_PARAM_SET_CONFIG, length, + p_config_bytes); + if (error != Tfa98xx_Error_Ok) + return error; + + error = tfa98xx_dsp_support_drc(tfa, &bSupportDrc); + if (error != Tfa98xx_Error_Ok) + return error; + + if (bSupportDrc) { + /* Need to set AgcGainInsert back to PRE, + * as the SetConfig forces it to POST */ + uint8_t bytes[3] = { 0, 0, 0 }; + + error = tfa_dsp_cmd_id_write(tfa, MODULE_SPEAKERBOOST, + SB_PARAM_SET_AGCINS, 3, bytes); + } + + return error; +} + +/* load all the parameters for the DRC settings from a file */ +enum Tfa98xx_Error tfa98xx_dsp_write_drc(struct tfa_device *tfa, int length, + const unsigned char *p_drc_bytes) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + if (p_drc_bytes != NULL) { + error = tfa_dsp_cmd_id_write(tfa, MODULE_SPEAKERBOOST, + SB_PARAM_SET_DRC, length, + p_drc_bytes); + + } else { + error = Tfa98xx_Error_Bad_Parameter; + } + return error; +} + +enum Tfa98xx_Error tfa98xx_powerdown(struct tfa_device *tfa, int powerdown) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + error = TFA_SET_BF(tfa, PWDN, (uint16_t)powerdown); + + if (powerdown) { + /* Workaround for ticket PLMA5337 */ + if (tfa->tfa_family == 2) { + TFA_SET_BF_VOLATILE(tfa, AMPE, 0); + } + } + + return error; +} + +enum Tfa98xx_Error tfa98xx_select_mode(struct tfa_device *tfa, + enum Tfa98xx_Mode mode) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + if (error == Tfa98xx_Error_Ok) { + switch (mode) { + default: + error = Tfa98xx_Error_Bad_Parameter; + } + } + + return error; +} + +int tfa_set_bf(struct tfa_device *tfa, const uint16_t bf, const uint16_t value) +{ + enum Tfa98xx_Error err; + uint16_t regvalue, msk, oldvalue; + + /* + * bitfield enum: + * - 0..3 : len + * - 4..7 : pos + * - 8..15 : address + */ + uint8_t len = bf & 0x0f; + uint8_t pos = (bf >> 4) & 0x0f; + uint8_t address = (bf >> 8) & 0xff; + + err = reg_read(tfa, address, ®value); + if (err) { + pr_err("Error getting bf :%d \n", -err); + return -err; + } + + oldvalue = regvalue; + msk = ((1 << (len + 1)) - 1) << pos; + regvalue &= ~msk; + regvalue |= value << pos; + + /* Only write when the current register value is not the same as the new value */ + if (oldvalue != regvalue) { + err = reg_write(tfa, address, regvalue); + if (err) { + pr_err("Error setting bf :%d \n", -err); + return -err; + } + } + + return 0; +} + +int tfa_set_bf_volatile(struct tfa_device *tfa, const uint16_t bf, + const uint16_t value) +{ + enum Tfa98xx_Error err; + uint16_t regvalue, msk; + + /* + * bitfield enum: + * - 0..3 : len + * - 4..7 : pos + * - 8..15 : address + */ + uint8_t len = bf & 0x0f; + uint8_t pos = (bf >> 4) & 0x0f; + uint8_t address = (bf >> 8) & 0xff; + + err = reg_read(tfa, address, ®value); + if (err) { + pr_err("Error getting bf :%d \n", -err); + return -err; + } + + msk = ((1 << (len + 1)) - 1) << pos; + regvalue &= ~msk; + regvalue |= value << pos; + + err = reg_write(tfa, address, regvalue); + if (err) { + pr_err("Error setting bf :%d \n", -err); + return -err; + } + + return 0; +} + +int tfa_get_bf(struct tfa_device *tfa, const uint16_t bf) +{ + enum Tfa98xx_Error err; + uint16_t regvalue, msk; + uint16_t value; + + /* + * bitfield enum: + * - 0..3 : len + * - 4..7 : pos + * - 8..15 : address + */ + uint8_t len = bf & 0x0f; + uint8_t pos = (bf >> 4) & 0x0f; + uint8_t address = (bf >> 8) & 0xff; + + err = reg_read(tfa, address, ®value); + if (err) { + pr_err("Error getting bf :%d \n", -err); + return -err; + } + + msk = ((1 << (len + 1)) - 1) << pos; + regvalue &= msk; + value = regvalue >> pos; + + return value; +} + +int tfa_set_bf_value(const uint16_t bf, const uint16_t bf_value, + uint16_t *p_reg_value) +{ + uint16_t regvalue, msk; + + /* + * bitfield enum: + * - 0..3 : len + * - 4..7 : pos + * - 8..15 : address + */ + uint8_t len = bf & 0x0f; + uint8_t pos = (bf >> 4) & 0x0f; + + regvalue = *p_reg_value; + + msk = ((1 << (len + 1)) - 1) << pos; + regvalue &= ~msk; + regvalue |= bf_value << pos; + + *p_reg_value = regvalue; + + return 0; +} + +uint16_t tfa_get_bf_value(const uint16_t bf, const uint16_t reg_value) +{ + uint16_t msk, value; + + /* + * bitfield enum: + * - 0..3 : len + * - 4..7 : pos + * - 8..15 : address + */ + uint8_t len = bf & 0x0f; + uint8_t pos = (bf >> 4) & 0x0f; + + msk = ((1 << (len + 1)) - 1) << pos; + value = (reg_value & msk) >> pos; + + return value; +} + +int tfa_write_reg(struct tfa_device *tfa, const uint16_t bf, + const uint16_t reg_value) +{ + enum Tfa98xx_Error err; + + /* bitfield enum - 8..15 : address */ + uint8_t address = (bf >> 8) & 0xff; + + err = reg_write(tfa, address, reg_value); + if (err) + return -err; + + return 0; +} + +int tfa_read_reg(struct tfa_device *tfa, const uint16_t bf) +{ + enum Tfa98xx_Error err; + uint16_t regvalue; + + /* bitfield enum - 8..15 : address */ + uint8_t address = (bf >> 8) & 0xff; + + err = reg_read(tfa, address, ®value); + if (err) + return -err; + + return regvalue; +} + +/* + * powerup the coolflux subsystem and wait for it + */ +enum Tfa98xx_Error tfa_cf_powerup(struct tfa_device *tfa) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + int tries, status; + + /* power on the sub system */ + TFA_SET_BF_VOLATILE(tfa, PWDN, 0); + + // wait until everything is stable, in case clock has been off + if (tfa->verbose) + pr_info("Waiting for DSP system stable...\n"); + for (tries = CFSTABLE_TRIES; tries > 0; tries--) { + err = tfa98xx_dsp_system_stable(tfa, &status); + _ASSERT(err == Tfa98xx_Error_Ok); + if (status) + break; + else + msleep_interruptible( + 10); /* wait 10ms to avoid busload */ + } + if (tries == 0) { // timedout + pr_err("DSP subsystem start timed out\n"); + return Tfa98xx_Error_StateTimedOut; + } + + return err; +} + +/* + * Enable/Disable the I2S output for TFA1 devices + * without TDM interface + */ +static enum Tfa98xx_Error tfa98xx_aec_output(struct tfa_device *tfa, int enable) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + + if ((tfa->daimap & Tfa98xx_DAI_TDM) == Tfa98xx_DAI_TDM) + return err; + + if (tfa->tfa_family == 1) + err = -tfa_set_bf(tfa, TFA1_BF_I2SDOE, (enable != 0)); + else { + pr_err("I2SDOE on unsupported family\n"); + err = Tfa98xx_Error_Not_Supported; + } + + return err; +} + +/* + * Print the current state of the hardware manager + * Device manager status information, man_state from TFA9888_N1B_I2C_regmap_V12 + */ +enum Tfa98xx_Error show_current_state(struct tfa_device *tfa) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + int manstate = -1; + + if (tfa->tfa_family == 2 +#ifndef __KERNEL__ + && tfa->verbose +#endif + ) { + manstate = TFA_GET_BF(tfa, MANSTATE); + if (manstate < 0) + return -manstate; + + pr_debug("Current HW manager state: "); + + switch (manstate) { + case 0: + pr_debug("power_down_state \n"); + break; + case 1: + pr_debug("wait_for_source_settings_state \n"); + break; + case 2: + pr_debug("connnect_pll_input_state \n"); + break; + case 3: + pr_debug("disconnect_pll_input_state \n"); + break; + case 4: + pr_debug("enable_pll_state \n"); + break; + case 5: + pr_debug("enable_cgu_state \n"); + break; + case 6: + pr_debug("init_cf_state \n"); + break; + case 7: + pr_debug("enable_amplifier_state \n"); + break; + case 8: + pr_debug("alarm_state \n"); + break; + case 9: + pr_debug("operating_state \n"); + break; + case 10: + pr_debug("mute_audio_state \n"); + break; + case 11: + pr_debug("disable_cgu_pll_state \n"); + break; + default: + pr_debug("Unable to find current state \n"); + break; + } + } + + return err; +} + +/* + * start the speakerboost algorithm + * this implies a full system startup when the system was not already started + * + */ +enum Tfa98xx_Error tfaRunSpeakerBoost(struct tfa_device *tfa, int force, + int profile) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + int value; + + if (force) { + err = tfaRunColdStartup(tfa, profile); + if (err) + return err; + } + + /* Returns 1 when device is "cold" and 0 when device is warm */ + value = tfa_is_cold(tfa); + + pr_debug("Startup of device [%s] is a %sstart\n", + tfaContDeviceName(tfa->cnt, tfa->dev_idx), + value ? "cold" : "warm"); + + /* cold start and not tap profile */ + if (value) { + /* Run startup and write all files */ + err = tfaRunSpeakerStartup(tfa, force, profile); + if (err) { + pr_err("tfaRunSpeakerStartup error %d\n", err); + return err; + } + /* Save the current profile and set the vstep to 0 */ + /* This needs to be overwriten even in CF bypass */ + tfa_dev_set_swprof(tfa, (unsigned short)profile); + tfa_dev_set_swvstep(tfa, 0); + + /* Synchonize I/V delay on 96/97 at cold start */ + if ((tfa->tfa_family == 1) && (tfa->daimap == Tfa98xx_DAI_TDM)) + tfa->sync_iv_delay = 1; + } + + return err; +} + +enum Tfa98xx_Error tfaRunSpeakerStartup(struct tfa_device *tfa, int force, + int profile) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + pr_debug("%s force=%d profile=%d\n", __func__, force, profile); + if (!force) { // in case of force CF already runnning + err = tfaRunStartup(tfa, profile); + PRINT_ASSERT(err); + if (err) { + pr_err("tfaRunStartup failed %d\n", err); + return err; + } + /* Startup with CF in bypass then return here */ + if (tfa_cf_enabled(tfa) == 0) { + pr_err("tfa_cf_enabled==0\n"); + return err; + } + + /* respond to external DSP: -1:none, 0:no_dsp, 1:cold, 2:warm */ + if (tfa->ext_dsp == -1) { + err = tfaRunStartDSP(tfa); + if (err) { + pr_err("tfaRunStartup failed %d\n", err); + return err; + } + } + } + + /* Set auto_copy_mtp_to_iic (bit 5 of A3) to 1 */ + tfa98xx_auto_copy_mtp_to_iic(tfa); + + /* write all the files from the device list */ + err = tfaContWriteFiles(tfa); + if (err) { + pr_debug("[%s] tfaContWriteFiles error = %d \n", __FUNCTION__, + err); + return err; + } + + /* write all the files from the profile list (use volumstep 0) */ + err = tfaContWriteFilesProf(tfa, profile, 0); + if (err) { + pr_debug("[%s] tfaContWriteFilesProf error = %d \n", + __FUNCTION__, err); + return err; + } + + return err; +} + +/* + * Run calibration + */ +enum Tfa98xx_Error tfaRunSpeakerCalibration(struct tfa_device *tfa) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + int calibrateDone; + + /* return if there is no audio running */ + if ((tfa->tfa_family == 2) && TFA_GET_BF(tfa, NOCLK)) + return Tfa98xx_Error_NoClock; + + /* When MTPOTC is set (cal=once) unlock key2 */ + if (TFA_GET_BF(tfa, MTPOTC) == 1) { + tfa98xx_key2(tfa, 0); + } + + /* await calibration, this should return ok */ + err = tfaRunWaitCalibration(tfa, &calibrateDone); + if (err == Tfa98xx_Error_Ok) { + err = tfa_dsp_get_calibration_impedance(tfa); + PRINT_ASSERT(err); + } + + /* When MTPOTC is set (cal=once) re-lock key2 */ + if (TFA_GET_BF(tfa, MTPOTC) == 1) { + tfa98xx_key2(tfa, 1); + } + + return err; +} + +enum Tfa98xx_Error tfaRunColdboot(struct tfa_device *tfa, int state) +{ +#define CF_CONTROL 0x8100 + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + int tries = 10; + + /* repeat set ACS bit until set as requested */ + while (state != TFA_GET_BF(tfa, ACS)) { + /* set colstarted in CF_CONTROL to force ACS */ + err = mem_write(tfa, CF_CONTROL, state, Tfa98xx_DMEM_IOMEM); + PRINT_ASSERT(err); + + if (tries-- == 0) { + pr_debug("coldboot (ACS) did not %s\n", + state ? "set" : "clear"); + return Tfa98xx_Error_Other; + } + } + + return err; +} + +/* + * load the patch if any + * else tell no loaded + */ +static enum Tfa98xx_Error tfa_run_load_patch(struct tfa_device *tfa) +{ + return tfaContWritePatch(tfa); +} + +/* + * this will load the patch witch will implicitly start the DSP + * if no patch is available the DPS is started immediately + */ +enum Tfa98xx_Error tfaRunStartDSP(struct tfa_device *tfa) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + + err = tfa_run_load_patch(tfa); + if (err) { /* patch load is fatal so return immediately*/ + return err; + } + + /* Clear count_boot, should be reset to 0 before the DSP reset is released */ + err = mem_write(tfa, 512, 0, Tfa98xx_DMEM_XMEM); + PRINT_ASSERT(err); + + /* Reset DSP once for sure after initializing */ + if (err == Tfa98xx_Error_Ok) { + err = tfa98xx_dsp_reset(tfa, 0); + PRINT_ASSERT(err); + } + + /* Sample rate is needed to set the correct tables */ + err = tfa98xx_dsp_write_tables(tfa, TFA_GET_BF(tfa, AUDFS)); + PRINT_ASSERT(err); + + return err; +} + +/* + * start the clocks and wait until the AMP is switching + * on return the DSP sub system will be ready for loading + */ +enum Tfa98xx_Error tfaRunStartup(struct tfa_device *tfa, int profile) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + nxpTfaDeviceList_t *dev = tfaContDevice(tfa->cnt, tfa->dev_idx); + int i, noinit = 0; + + if (dev == NULL) + return Tfa98xx_Error_Fail; + + if (dev->bus) /* no i2c device, do nothing */ + return Tfa98xx_Error_Ok; + + /* process the device list to see if the user implemented the noinit */ + for (i = 0; i < dev->length; i++) { + if (dev->list[i].type == dscNoInit) { + noinit = 1; + break; + } + } + + if (!noinit) { + /* load the optimal TFA98XX in HW settings */ + err = tfa98xx_init(tfa); + PRINT_ASSERT(err); + } else { + pr_debug( + "\nWarning: No init keyword found in the cnt file. Init is skipped! \n"); + } + + /* I2S settings to define the audio input properties + * these must be set before the subsys is up */ + // this will run the list until a non-register item is encountered + err = tfaContWriteRegsDev(tfa); // write device register settings + PRINT_ASSERT(err); + // also write register the settings from the default profile + // NOTE we may still have ACS=1 so we can switch sample rate here + err = tfaContWriteRegsProf(tfa, profile); + PRINT_ASSERT(err); + + /* Factory trimming for the Boost converter */ + tfa98xx_factory_trimmer(tfa); + + /* Go to the initCF state */ + tfa_dev_set_state( + tfa, TFA_STATE_INIT_CF, + strstr(tfaContProfileName(tfa->cnt, tfa->dev_idx, profile), + ".cal") != NULL); + + err = show_current_state(tfa); + + return err; +} + +/* + * run the startup/init sequence and set ACS bit + */ +enum Tfa98xx_Error tfaRunColdStartup(struct tfa_device *tfa, int profile) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + + err = tfaRunStartup(tfa, profile); + PRINT_ASSERT(err); + if (err) + return err; + + if (!tfa->is_probus_device) { + /* force cold boot */ + err = tfaRunColdboot(tfa, 1); // set ACS + PRINT_ASSERT(err); + if (err) + return err; + } + + /* start */ + err = tfaRunStartDSP(tfa); + PRINT_ASSERT(err); + + return err; +} + +/* + * + */ +enum Tfa98xx_Error tfaRunMute(struct tfa_device *tfa) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + int status; + int tries = 0; + + /* signal the TFA98XX to mute */ + if (tfa->tfa_family == 1) { + err = tfa98xx_set_mute(tfa, Tfa98xx_Mute_Amplifier); + + if (err == Tfa98xx_Error_Ok) { + /* now wait for the amplifier to turn off */ + do { + status = TFA_GET_BF(tfa, SWS); + if (status != 0) + msleep_interruptible( + 10); /* wait 10ms to avoid busload */ + else + break; + tries++; + } while (tries < AMPOFFWAIT_TRIES); + + if (tfa->verbose) + pr_debug( + "-------------------- muted --------------------\n"); + + /*The amplifier is always switching*/ + if (tries == AMPOFFWAIT_TRIES) + return Tfa98xx_Error_Other; + } + } + + return err; +} +/* + * + */ +enum Tfa98xx_Error tfaRunUnmute(struct tfa_device *tfa) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + + /* signal the TFA98XX to mute */ + err = tfa98xx_set_mute(tfa, Tfa98xx_Mute_Off); + + if (tfa->verbose) + pr_debug("-------------------unmuted ------------------\n"); + + return err; +} + +static void individual_calibration_results(struct tfa_device *tfa) +{ + int value_P, value_S; + + /* Read the calibration result in xmem (529=primary channel) (530=secondary channel) */ + mem_read(tfa, 529, 1, &value_P); + mem_read(tfa, 530, 1, &value_S); + + if (value_P != 1 && value_S != 1) + pr_debug("Calibration failed on both channels! \n"); + else if (value_P != 1) { + pr_debug("Calibration failed on Primary (Left) channel! \n"); + TFA_SET_BF_VOLATILE( + tfa, SSLEFTE, + 0); /* Disable the sound for the left speaker */ + } else if (value_S != 1) { + pr_debug("Calibration failed on Secondary (Right) channel! \n"); + TFA_SET_BF_VOLATILE( + tfa, SSRIGHTE, + 0); /* Disable the sound for the right speaker */ + } + + TFA_SET_BF_VOLATILE(tfa, AMPINSEL, 0); /* Set amplifier input to TDM */ + TFA_SET_BF_VOLATILE(tfa, SBSL, 1); +} + +/* + * wait for calibrateDone + */ +enum Tfa98xx_Error tfaRunWaitCalibration(struct tfa_device *tfa, + int *calibrateDone) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + int tries = 0, mtp_busy = 1, tries_mtp_busy = 0; + + *calibrateDone = 0; + + /* in case of calibrate once wait for MTPEX */ + if (TFA_GET_BF(tfa, MTPOTC)) { + // Check if MTP_busy is clear! + while (tries_mtp_busy < MTPBWAIT_TRIES) { + mtp_busy = tfa_dev_get_mtpb(tfa); + if (mtp_busy == 1) + msleep_interruptible( + 10); /* wait 10ms to avoid busload */ + else + break; + tries_mtp_busy++; + } + + if (tries_mtp_busy < MTPBWAIT_TRIES) { + /* Because of the msleep TFA98XX_API_WAITRESULT_NTRIES is way to long! + * Setting this to 25 will take it atleast 25*50ms = 1.25 sec + */ + while ((*calibrateDone == 0) && + (tries < MTPEX_WAIT_NTRIES)) { + *calibrateDone = TFA_GET_BF(tfa, MTPEX); + if (*calibrateDone == 1) + break; + msleep_interruptible( + 50); /* wait 50ms to avoid busload */ + tries++; + } + + if (tries >= MTPEX_WAIT_NTRIES) { + tries = TFA98XX_API_WAITRESULT_NTRIES; + } + } else { + pr_err("MTP bussy after %d tries\n", MTPBWAIT_TRIES); + } + } + + /* poll xmem for calibrate always + * calibrateDone = 0 means "calibrating", + * calibrateDone = -1 (or 0xFFFFFF) means "fails" + * calibrateDone = 1 means calibration done + */ + while ((*calibrateDone != 1) && + (tries < TFA98XX_API_WAITRESULT_NTRIES)) { + err = mem_read(tfa, TFA_FW_XMEM_CALIBRATION_DONE, 1, + calibrateDone); + if (*calibrateDone == -1) + break; + tries++; + } + + if (*calibrateDone != 1) { + pr_err("Calibration failed! \n"); + err = Tfa98xx_Error_Bad_Parameter; + } else if (tries == TFA98XX_API_WAITRESULT_NTRIES) { + pr_debug("Calibration has timedout! \n"); + err = Tfa98xx_Error_StateTimedOut; + } else if (tries_mtp_busy == 1000) { + pr_err("Calibrate Failed: MTP_busy stays high! \n"); + err = Tfa98xx_Error_StateTimedOut; + } + + /* Give reason why calibration failed! */ + if (err != Tfa98xx_Error_Ok) { + if ((tfa->tfa_family == 2) && + (TFA_GET_BF(tfa, REFCKSEL) == 1)) { + pr_err("Unable to calibrate the device with the internal clock! \n"); + } + } + + /* Check which speaker calibration failed. Only for 88C */ + if ((err != Tfa98xx_Error_Ok) && ((tfa->rev & 0x0FFF) == 0xc88)) { + individual_calibration_results(tfa); + } + + return err; +} + +/* + * tfa_dev_start will only do the basics: Going from powerdown to operating or a profile switch. + * for calibrating or akoustic shock handling use the tfa98xxCalibration function. + */ +/*[nxp34663] CR: support 16bit/24bit/32bit audio data. begin*/ +#ifdef __KERNEL__ +enum tfa_error tfa_dev_start(struct tfa_device *tfa, int next_profile, + int vstep, u8 pcm_format) +#else +enum tfa_error tfa_dev_start(struct tfa_device *tfa, int next_profile, + int vstep) +#endif +/*[nxp34663] CR: support 16bit/24bit/32bit audio data. end*/ +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + int active_profile = -1; + + pr_debug("entry...\n"); + /* Get currentprofile */ + active_profile = tfa_dev_get_swprof(tfa); + if (active_profile == 0xff) + active_profile = -1; + + /* TfaRun_SpeakerBoost implies un-mute */ + pr_debug("Active_profile:%s, next_profile:%s\n", + tfaContProfileName(tfa->cnt, tfa->dev_idx, active_profile), + tfaContProfileName(tfa->cnt, tfa->dev_idx, next_profile)); + + err = show_current_state(tfa); + + if (tfa->tfa_family == 1) { /* TODO move this to ini file */ + /* Enable I2S output on TFA1 devices without TDM */ + err = tfa98xx_aec_output(tfa, 1); + if (err != Tfa98xx_Error_Ok) + goto error_exit; + } + + /*[nxp34663] CR: support 16bit/24bit/32bit audio data. begin*/ +#ifdef __KERNEL__ + if ((2 == tfa->tfa_family) && (tfa->daimap & Tfa98xx_DAI_TDM)) { + //TFA_SET_BF(tfa, TDMSRCMAP, 2); /*the TDMSRCMAP should be set in cnt file.*/ + /* we should remove below settings from cnt file, otherwise will be overwrite by cnt file later.*/ + if (16 == pcm_format) { + TFA_SET_BF(tfa, TDMNBCK, 0); + TFA_SET_BF(tfa, TDMSLLN, 15); + TFA_SET_BF(tfa, TDMSSIZE, 15); + } else if ((24 == pcm_format) || (32 == pcm_format)) { + TFA_SET_BF(tfa, TDMNBCK, 2); + TFA_SET_BF(tfa, TDMSLLN, 31); + TFA_SET_BF(tfa, TDMSSIZE, 31); + } else { + err = Tfa98xx_Error_Bad_Parameter; + goto error_exit; + } + } +#endif + /*[nxp34663] CR: support 16bit/24bit/32bit audio data. end*/ + + if (tfa->bus != 0) { /* non i2c */ +#ifndef __KERNEL__ + tfadsp_fw_start(tfa, next_profile, vstep); +#endif /* __KERNEL__ */ + } else { + /* Check if we need coldstart or ACS is set */ + err = show_current_state(tfa); + err = tfaRunSpeakerBoost(tfa, 0, next_profile); + if (err != Tfa98xx_Error_Ok) { + pr_err("RunSpeakerBoost failed %d\n", err); + goto error_exit; + } + /* Make sure internal oscillator is running for DSP devices (non-dsp and max1 this is no-op) */ + tfa98xx_set_osc_powerdown(tfa, 0); + pr_debug("[NXP] %s after osc_powerdown\n", __func__); + + /* Go to the Operating state */ +#if 0 + tfa_dev_set_state(tfa, TFA_STATE_OPERATING | TFA_STATE_MUTE, 0); +#else + tfa_dev_set_state(tfa, TFA_STATE_OPERATING, 0); +#endif + pr_debug("[NXP] %s after implemented tfa_dev_set_state()\n", + __func__); + } + + active_profile = tfa_dev_get_swprof(tfa); + + /* Profile switching */ + if ((next_profile != active_profile && active_profile >= 0)) { + err = tfaContWriteProfile(tfa, next_profile, vstep); + if (err != Tfa98xx_Error_Ok) { + pr_err("tfaContWriteProfile failed %d\n", err); + goto error_exit; + } + } + pr_debug("[NXP] %s after implemented tfaContWriteProfile()\n", + __func__); + + /* If the profile contains the .standby suffix go to powerdown + * else we should be in operating state + */ + if (strstr(tfaContProfileName(tfa->cnt, tfa->dev_idx, next_profile), + ".standby") != NULL) { + tfa_dev_set_swprof(tfa, (unsigned short)next_profile); + tfa_dev_set_swvstep(tfa, (unsigned short)tfa->vstep); + goto error_exit; + } + + err = show_current_state(tfa); +#ifndef __KERNEL__ + /* get current vstep*/ + tfa->vstep = tfa_dev_get_swvstep(tfa); +#endif + if ((TFA_GET_BF(tfa, CFE) != 0) && (vstep != tfa->vstep) && + (vstep != -1)) { + err = tfaContWriteFilesVstep(tfa, next_profile, vstep); + if (err != Tfa98xx_Error_Ok) { + pr_err("tfaContWriteFilesVstep failed %d\n", err); + goto error_exit; + } + pr_debug("after implemented tfaContWriteFilesVstep()\n"); + } + + /* Always search and apply filters after a startup */ + err = tfa_set_filters(tfa, next_profile); + if (err != Tfa98xx_Error_Ok) { + pr_err("tfaContWriteFilesVstep failed %d\n", err); + goto error_exit; + } + + tfa_dev_set_swprof(tfa, (unsigned short)next_profile); + tfa_dev_set_swvstep(tfa, (unsigned short)tfa->vstep); + + /* PLMA5539: Gives information about current setting of powerswitch */ + if (tfa->verbose) { + if (!tfa98xx_powerswitch_is_enabled(tfa)) + pr_info("Device start without powerswitch enabled!\n"); + } + +error_exit: + pr_debug("[NXP] %s end...\n", __func__); + show_current_state(tfa); + if (err != Tfa98xx_Error_Ok) { + pr_err("TFA98xx Error code is %d\n", err); + return tfa_error_max; + } + + return tfa_error_ok; +} + +enum tfa_error tfa_dev_stop(struct tfa_device *tfa) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + int manstate = 0, retry = 0; + + /* mute */ + tfaRunMute(tfa); + + /* Make sure internal oscillator is not running for DSP devices (non-dsp and max1 this is no-op) */ + tfa98xx_set_osc_powerdown(tfa, 1); + + /* powerdown CF */ + err = tfa98xx_powerdown(tfa, 1); + if (err != Tfa98xx_Error_Ok) + goto error_exit; + + /* disable I2S output on TFA1 devices without TDM */ + err = tfa98xx_aec_output(tfa, 0); + + /* added by nxp34663 beging. */ + /* we should ensure the state machine in powerdown mode here. */ + manstate = TFA_GET_BF(tfa, MANSTATE); + while ((manstate >= 4) && (retry < 100)) { + pr_debug( + "%s waitting state machine goto powerdown. MANSTATE=%d\n", + __func__, manstate); + msleep_interruptible(10); + manstate = TFA_GET_BF(tfa, MANSTATE); + retry++; + } + /* added by nxp34663 end. */ +error_exit: + if (err != Tfa98xx_Error_Ok) { + pr_err("TFA98xx Error code is %d\n", err); + return tfa_error_max; + } + + return tfa_error_ok; +} + +/* + * int registers and coldboot dsp + */ +int tfa_reset(struct tfa_device *tfa) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + + err = -TFA_SET_BF_VOLATILE(tfa, I2CR, 1); + if (err) + return err; + + if (tfa->tfa_family == 2) { + /* restore MANSCONF to POR state */ + TFA_SET_BF_VOLATILE(tfa, MANSCONF, 0); + } + + if (!tfa->is_probus_device) { + if (tfa->tfa_family == 2) { + /* restore MANCOLD to POR state */ + TFA_SET_BF_VOLATILE(tfa, MANCOLD, 1); + } + + /* powerup CF to access CF io */ + tfa98xx_powerdown(tfa, 0); + /* for clock */ + err = tfa_cf_powerup(tfa); + PRINT_ASSERT(err); + + /* force cold boot */ + err = tfaRunColdboot(tfa, 1); // set ACS + PRINT_ASSERT(err); + + /* reset all i2C registers to default */ + err = -TFA_SET_BF(tfa, I2CR, 1); + PRINT_ASSERT(err); + } else { + if (tfa->ext_dsp > 0) + tfa98xx_init_dsp(tfa); + } + + return err; +} + +/* + * Write all the bytes specified by num_bytes and data + */ +enum Tfa98xx_Error tfa98xx_write_data(struct tfa_device *tfa, + unsigned char subaddress, int num_bytes, + const unsigned char data[]) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + /* subaddress followed by data */ + const int bytes2write = num_bytes + 1; + unsigned char *write_data; + + if (num_bytes > TFA2_MAX_PARAM_SIZE) + return Tfa98xx_Error_Bad_Parameter; + + write_data = (unsigned char *)kmem_cache_alloc(tfa->cachep, GFP_KERNEL); + if (write_data == NULL) + return Tfa98xx_Error_Fail; + + write_data[0] = subaddress; + memcpy(&write_data[1], data, num_bytes); + + error = tfa98xx_write_raw(tfa, bytes2write, write_data); + + kmem_cache_free(tfa->cachep, write_data); + return error; +} + +/* + * fill the calibration value as milli ohms in the struct + * + * assume that the device has been calibrated + */ +enum Tfa98xx_Error tfa_dsp_get_calibration_impedance(struct tfa_device *tfa) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + unsigned char bytes[3 * 2] = { 0 }; + int nr_bytes, i, data[2], calibrateDone, spkr_count = 0, cal_idx = 0; + unsigned int scaled_data; + int tries = 0; + + error = tfa_supported_speakers(tfa, &spkr_count); + + if (tfa_dev_mtp_get(tfa, TFA_MTP_OTC) && + tfa_dev_mtp_get(tfa, TFA_MTP_EX)) { + pr_debug("Getting calibration values from MTP\n"); + + if ((tfa->rev & 0xFF) == 0x88) { + for (i = 0; i < spkr_count; i++) { + if (i == 0) + tfa->mohm[i] = tfa_dev_mtp_get( + tfa, TFA_MTP_RE25_PRIM); + else + tfa->mohm[i] = tfa_dev_mtp_get( + tfa, TFA_MTP_RE25_SEC); + } + } else { + tfa->mohm[0] = tfa_dev_mtp_get(tfa, TFA_MTP_RE25); + } + } else if ((tfa_dev_mtp_get(tfa, TFA_MTP_OTC) == 0) && + (tfa_dev_mtp_get(tfa, TFA_MTP_EX) == 0)) { + pr_debug("Getting calibration values from Speakerboost\n"); + + /* Make sure the calibrateDone bit is set before getting the values from speakerboost! + * This does not work for 72 (because the dsp cannot set this bit) + */ + if (!tfa->is_probus_device) { + /* poll xmem for calibrate always + * calibrateDone = 0 means "calibrating", + * calibrateDone = -1 (or 0xFFFFFF) means "fails" + * calibrateDone = 1 means calibration done + */ + calibrateDone = 0; + while ((calibrateDone != 1) && + (tries < TFA98XX_API_WAITRESULT_NTRIES)) { + error = mem_read(tfa, + TFA_FW_XMEM_CALIBRATION_DONE, + 1, &calibrateDone); + if ((calibrateDone == 1) || + (Tfa98xx_Error_Ok != error)) + break; + tries++; + } + + if (calibrateDone == 1) + pr_debug("Calibration successed!!!\n"); + else if ((calibrateDone != 1) || + (Tfa98xx_Error_Ok != error)) { + pr_err("Calibration failed! calibrateDone=%d error=%d\n", + calibrateDone, error); + error = Tfa98xx_Error_Bad_Parameter; + } else if (tries == TFA98XX_API_WAITRESULT_NTRIES) { + pr_debug("Calibration has timedout! \n"); + error = Tfa98xx_Error_StateTimedOut; + } + } else { + /* dsp inside of TFA device. */ + calibrateDone = 1; + } + + /* SoftDSP interface differs from hw-dsp interfaces */ + if (tfa->is_probus_device && tfa->cnt->ndev > 1) { + spkr_count = tfa->cnt->ndev; + } + + if (1 == calibrateDone) { + nr_bytes = spkr_count * 3; + error = tfa_dsp_cmd_id_write_read(tfa, + MODULE_SPEAKERBOOST, + SB_PARAM_GET_RE25C, + nr_bytes, bytes); + if (error == Tfa98xx_Error_Ok) { + tfa98xx_convert_bytes2data(nr_bytes, bytes, + data); + + for (i = 0; i < spkr_count; i++) { + /* for probus devices, calibration values coming from soft-dsp speakerboost, + are ordered in a different way. Re-align to standard representation. */ + cal_idx = i; + if ((tfa->is_probus_device && + tfa->dev_idx >= 1)) { + cal_idx = 0; + } + + /* signed data has a limit of 30 Ohm */ + scaled_data = data[i]; + + if (tfa->tfa_family == 2) + tfa->mohm[cal_idx] = + (scaled_data * 1000) / + TFA2_FW_ReZ_SCALE; + else + tfa->mohm[cal_idx] = + (scaled_data * 1000) / + TFA1_FW_ReZ_SCALE; + } + } + } + } else { + for (i = 0; i < spkr_count; i++) { + tfa->mohm[i] = 0; + } + pr_err("Please run calibration command first.\n"); + error = Tfa98xx_Error_Bad_Parameter; + } + + return error; +} + +/* start count from 1, 0 is invalid */ +int tfa_dev_get_swprof(struct tfa_device *tfa) +{ + return (tfa->dev_ops.get_swprof)(tfa); +} + +int tfa_dev_set_swprof(struct tfa_device *tfa, unsigned short new_value) +{ + return (tfa->dev_ops.set_swprof)(tfa, new_value + 1); +} + +/* same value for all channels + * start count from 1, 0 is invalid */ +int tfa_dev_get_swvstep(struct tfa_device *tfa) +{ + return (tfa->dev_ops.get_swvstep)(tfa); +} + +int tfa_dev_set_swvstep(struct tfa_device *tfa, unsigned short new_value) +{ + return (tfa->dev_ops.set_swvstep)(tfa, new_value + 1); +} + +/* + function overload for MTPB + */ +int tfa_dev_get_mtpb(struct tfa_device *tfa) +{ + return (tfa->dev_ops.get_mtpb)(tfa); +} + +int tfa_is_cold(struct tfa_device *tfa) +{ + int value; + + /* + * check for cold boot status + */ + if (tfa->is_probus_device) { + if (tfa->ext_dsp > 0) { + if (tfa->ext_dsp == 2) + value = 0; // warm + else /* no dsp or cold */ + value = 1; // cold + } else { + value = (TFA_GET_BF(tfa, MANSCONF) == 0); + } + } else { + value = TFA_GET_BF(tfa, ACS); + } + + return value; +} + +int tfa_needs_reset(struct tfa_device *tfa) +{ + int value; + + /* checks if the DSP commands SetAlgoParams and SetMBDrc + * need a DSP reset (now: at coldstart or during calibration) + */ + if (tfa_is_cold(tfa) == 1 || tfa->needs_reset == 1) + value = 1; + else + value = 0; + + return value; +} + +int tfa_cf_enabled(struct tfa_device *tfa) +{ + int value; + + /* For 72 there is no CF */ + if (tfa->is_probus_device) { + value = (tfa->ext_dsp != 0); + } else { + value = TFA_GET_BF(tfa, CFE); + } + + return value; +} + +#define NR_COEFFS 6 +#define NR_BIQUADS 28 +#define BQ_SIZE (3 * NR_COEFFS) +#define DSP_MSG_OVERHEAD 27 + +#pragma pack(push, 1) +struct dsp_msg_all_coeff { + uint8_t select_eq[3]; + uint8_t biquad[NR_BIQUADS][NR_COEFFS][3]; +}; +#pragma pack(pop) + +/* number of biquads for each equalizer */ +static const int eq_biquads[] = { 10, 10, 2, 2, 2, 2 }; + +#define NR_EQ (int)(sizeof(eq_biquads) / sizeof(int)) + +enum Tfa98xx_Error dsp_partial_coefficients(struct tfa_device *tfa, + uint8_t *prev, uint8_t *next) +{ + uint8_t bq, eq; + int eq_offset; + int new_cost, old_cost; + uint32_t eq_biquad_mask[NR_EQ]; + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + struct dsp_msg_all_coeff *data1 = (struct dsp_msg_all_coeff *)prev; + struct dsp_msg_all_coeff *data2 = (struct dsp_msg_all_coeff *)next; + + old_cost = DSP_MSG_OVERHEAD + 3 + sizeof(struct dsp_msg_all_coeff); + new_cost = 0; + + eq_offset = 0; + for (eq = 0; eq < NR_EQ; eq++) { + uint8_t *eq1 = &data1->biquad[eq_offset][0][0]; + uint8_t *eq2 = &data2->biquad[eq_offset][0][0]; + + eq_biquad_mask[eq] = 0; + + if (memcmp(eq1, eq2, BQ_SIZE * eq_biquads[eq]) != 0) { + int nr_bq = 0; + int bq_sz, eq_sz; + + for (bq = 0; bq < eq_biquads[eq]; bq++) { + uint8_t *bq1 = &eq1[bq * BQ_SIZE]; + uint8_t *bq2 = &eq2[bq * BQ_SIZE]; + + if (memcmp(bq1, bq2, BQ_SIZE) != 0) { + eq_biquad_mask[eq] |= (1 << bq); + nr_bq++; + } + } + + bq_sz = (2 * 3 + BQ_SIZE) * nr_bq; + eq_sz = 2 * 3 + BQ_SIZE * eq_biquads[eq]; + + /* dsp message i2c transaction overhead */ + bq_sz += DSP_MSG_OVERHEAD * nr_bq; + eq_sz += DSP_MSG_OVERHEAD; + + if (bq_sz >= eq_sz) { + eq_biquad_mask[eq] = 0xffffffff; + + new_cost += eq_sz; + + } else { + new_cost += bq_sz; + } + } + pr_debug("eq_biquad_mask[%d] = 0x%.8x\n", eq, + eq_biquad_mask[eq]); + + eq_offset += eq_biquads[eq]; + } + + pr_debug("cost for writing all coefficients = %d\n", old_cost); + pr_debug("cost for writing changed coefficients = %d\n", new_cost); + + if (new_cost >= old_cost) { + const int buffer_sz = 3 + sizeof(struct dsp_msg_all_coeff); + uint8_t *buffer; + + buffer = kmalloc(buffer_sz, GFP_KERNEL); + if (buffer == NULL) + return Tfa98xx_Error_Fail; + + /* cmd id */ + buffer[0] = 0x00; + buffer[1] = 0x82; + buffer[2] = 0x00; + + /* parameters */ + memcpy(&buffer[3], data2, sizeof(struct dsp_msg_all_coeff)); + + err = dsp_msg(tfa, buffer_sz, (const char *)buffer); + + kfree(buffer); + if (err) + return err; + + } else { + eq_offset = 0; + for (eq = 0; eq < NR_EQ; eq++) { + uint8_t *eq2 = &data2->biquad[eq_offset][0][0]; + + if (eq_biquad_mask[eq] == 0xffffffff) { + const int msg_sz = 6 + BQ_SIZE * eq_biquads[eq]; + uint8_t *msg; + + msg = kmalloc(msg_sz, GFP_KERNEL); + if (msg == NULL) + return Tfa98xx_Error_Fail; + + /* cmd id */ + msg[0] = 0x00; + msg[1] = 0x82; + msg[2] = 0x00; + + /* select eq and bq */ + msg[3] = 0x00; + msg[4] = eq + 1; + msg[5] = 0x00; /* all biquads */ + + /* biquad parameters */ + memcpy(&msg[6], eq2, BQ_SIZE * eq_biquads[eq]); + + err = dsp_msg(tfa, msg_sz, (const char *)msg); + + kfree(msg); + if (err) + return err; + + } else if (eq_biquad_mask[eq] != 0) { + for (bq = 0; bq < eq_biquads[eq]; bq++) { + if (eq_biquad_mask[eq] & (1 << bq)) { + uint8_t *bq2 = + &eq2[bq * BQ_SIZE]; + const int msg_sz = 6 + BQ_SIZE; + uint8_t *msg; + + msg = kmem_cache_alloc( + tfa->cachep, + GFP_KERNEL); + if (msg == NULL) + return Tfa98xx_Error_Fail; + + /* cmd id */ + msg[0] = 0x00; + msg[1] = 0x82; + msg[2] = 0x00; + + /* select eq and bq*/ + msg[3] = 0x00; + msg[4] = eq + 1; + msg[5] = bq + 1; + + /* biquad parameters */ + memcpy(&msg[6], bq2, BQ_SIZE); + + err = dsp_msg( + tfa, msg_sz, + (const char *)msg); + + kmem_cache_free(tfa->cachep, + msg); + if (err) + return err; + } + } + } + eq_offset += eq_biquads[eq]; + } + } + + return err; +} + +/* fill context info */ +int tfa_dev_probe(int slave, struct tfa_device *tfa) +{ + uint16_t rev; + + tfa->slave_address = (unsigned char)slave; + + /* read revid via low level hal, register 3 */ + if (tfa98xx_read_register16(tfa, 3, &rev) != Tfa98xx_Error_Ok) { + PRINT("\nError: Unable to read revid from slave:0x%02x \n", + slave); + return -1; + } + + tfa->rev = rev; + tfa->dev_idx = -1; + tfa->state = TFA_STATE_UNKNOWN; + tfa->p_regInfo = NULL; + + tfa_set_query_info(tfa); + + tfa->in_use = 1; + + return 0; +} + +enum tfa_error tfa_dev_set_state(struct tfa_device *tfa, enum tfa_state state, + int is_calibration) +{ + enum tfa_error err = tfa_error_ok; + int loop = 50, ready = 0; + int count; + + pr_debug("tfa_dev_set_state() state=%d is_calibration=%d\n", state, + is_calibration); + /* Base states */ + /* Do not change the order of setting bits as this is important! */ + switch (state & 0x0f) { + case TFA_STATE_POWERDOWN: /* PLL in powerdown, Algo up */ + break; + case TFA_STATE_INIT_HW: /* load I2C/PLL hardware setting (~wait2srcsettings) */ + break; + case TFA_STATE_INIT_CF: /* coolflux HW access possible (~initcf) */ + /* Start with SBSL=0 to stay in initCF state */ + if (!tfa->is_probus_device) { + TFA_SET_BF(tfa, SBSL, 0); + } + /* We want to leave Wait4SrcSettings state for max2 */ + if (tfa->tfa_family == 2) + TFA_SET_BF(tfa, MANSCONF, 1); + + /* And finally set PWDN to 0 to leave powerdown state */ + TFA_SET_BF(tfa, PWDN, 0); + + /* Make sure the DSP is running! */ + do { + if (tfa98xx_dsp_system_stable(tfa, &ready) != + Tfa98xx_Error_Ok) + return tfa_error_max; + + if (ready) + break; + } while (loop--); + pr_debug( + "after performed tfa98xx_dsp_system_stable() err=%d ready=%d loop=%d\n", + err, ready, loop); + if ((!tfa->is_probus_device) && (is_calibration)) { + /* Enable FAIM when clock is stable, to avoid MTP corruption */ + err = (enum tfa_error)tfa98xx_faim_protect(tfa, 1); + if (tfa->verbose) { + pr_debug("FAIM enabled (err:%d).\n", err); + } + } + break; + case TFA_STATE_INIT_FW: /* DSP framework active (~patch loaded) */ + break; + case TFA_STATE_OPERATING: /* Amp and Algo running */ + /* Depending on our previous state we need to set 3 bits */ + TFA_SET_BF(tfa, PWDN, 0); /* Coming from state 0 */ + TFA_SET_BF(tfa, MANSCONF, 1); /* Coming from state 1 */ + pr_debug("tfa->is_probus_device=%d is_calibration=%d\n", + tfa->is_probus_device, is_calibration); + /* we should set AMPE as 1 for NON-DSP device, otherwise will be setting SBSL as 1 */ + if (tfa->is_probus_device) { + TFA_SET_BF(tfa, AMPE, 1); /* Coming from state 6 */ + } else { + TFA_SET_BF(tfa, SBSL, 1); /* Coming from state 6 */ + } + + /* + * Disable MTP clock to protect memory. + * However in case of calibration wait for DSP! (This should be case only during calibration). + */ + if ((TFA_GET_BF(tfa, MTPOTC) == 1) && (tfa->tfa_family == 2) && + is_calibration) { + count = MTPEX_WAIT_NTRIES * + 4; /* Calibration takes a lot of time */ + while ((TFA_GET_BF(tfa, MTPEX) != 1) && count) { + msleep_interruptible(10); + count--; + } + } + if ((!tfa->is_probus_device) && (is_calibration)) { + err = (enum tfa_error)tfa98xx_faim_protect(tfa, 0); + if (tfa->verbose) { + pr_debug("FAIM disabled (err:%d).\n", err); + } + } + /* Synchonize I/V delay on 96/97 at cold start */ + if (tfa->sync_iv_delay) { + if (tfa->verbose) + pr_debug("syncing I/V delay for %x\n", + (tfa->rev & 0xff)); + + /* wait for ACS to be cleared */ + count = 10; + while ((TFA_GET_BF(tfa, ACS) == 1) && (count-- > 0)) { + msleep_interruptible(1); + } + + tfa98xx_dsp_reset(tfa, 1); + tfa98xx_dsp_reset(tfa, 0); + tfa->sync_iv_delay = 0; + } + break; + case TFA_STATE_FAULT: /* An alarm or error occurred */ + break; + case TFA_STATE_RESET: /* I2C reset and ACS set */ + tfa98xx_init(tfa); + break; + default: + if (state & 0x0f) + return tfa_error_bad_param; + } + + /* state modifiers */ + + if (state & TFA_STATE_MUTE) + tfa98xx_set_mute(tfa, Tfa98xx_Mute_Amplifier); + + if (state & TFA_STATE_UNMUTE) + tfa98xx_set_mute(tfa, Tfa98xx_Mute_Off); + + tfa->state = state; + + return tfa_error_ok; +} + +enum tfa_state tfa_dev_get_state(struct tfa_device *tfa) +{ + int cold = 0; + int manstate; + + /* different per family type */ + if (tfa->tfa_family == 1) { + cold = TFA_GET_BF(tfa, ACS); + if (cold && TFA_GET_BF(tfa, PWDN)) + tfa->state = TFA_STATE_RESET; + else if (!cold && TFA_GET_BF(tfa, SWS)) + tfa->state = TFA_STATE_OPERATING; + } else /* family 2 */ { + manstate = TFA_GET_BF(tfa, MANSTATE); + switch (manstate) { + case 0: + tfa->state = TFA_STATE_POWERDOWN; + break; + case 8: /* if dsp reset if off assume framework is running */ + tfa->state = TFA_GET_BF(tfa, RST) ? TFA_STATE_INIT_CF : + TFA_STATE_INIT_FW; + break; + case 9: + tfa->state = TFA_STATE_OPERATING; + break; + default: + break; + } + } + + return tfa->state; +} + +int tfa_dev_mtp_get(struct tfa_device *tfa, enum tfa_mtp item) +{ + int value = 0; + + switch (item) { + case TFA_MTP_OTC: + value = TFA_GET_BF(tfa, MTPOTC); + break; + case TFA_MTP_EX: + value = TFA_GET_BF(tfa, MTPEX); + break; + case TFA_MTP_RE25: + case TFA_MTP_RE25_PRIM: + if (tfa->tfa_family == 2) { + if ((tfa->rev & 0xFF) == 0x88) + value = TFA_GET_BF(tfa, R25CL); + else if ((tfa->rev & 0xFF) == 0x13) + value = tfa_get_bf(tfa, TFA9912_BF_R25C); + else + value = TFA_GET_BF(tfa, R25C); + } else { + reg_read(tfa, 0x83, (unsigned short *)&value); + } + break; + case TFA_MTP_RE25_SEC: + if ((tfa->rev & 0xFF) == 0x88) { + value = TFA_GET_BF(tfa, R25CR); + } else { + pr_debug( + "Error: Current device has no secondary Re25 channel \n"); + } + break; + case TFA_MTP_LOCK: + break; + } + + return value; +} + +enum tfa_error tfa_dev_mtp_set(struct tfa_device *tfa, enum tfa_mtp item, + int value) +{ + enum Tfa98xx_Error err = Tfa98xx_Error_Ok; + + switch (item) { + case TFA_MTP_OTC: + err = tfa98xx_set_mtp(tfa, (uint16_t)value, + TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_MSK); + break; + case TFA_MTP_EX: + err = tfa98xx_set_mtp(tfa, (uint16_t)value, + TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_MSK); + break; + case TFA_MTP_RE25: + case TFA_MTP_RE25_PRIM: + if (tfa->tfa_family == 2) { + if ((tfa->rev & 0xFF) == 0x88) + TFA_SET_BF(tfa, R25CL, (uint16_t)value); + else + TFA_SET_BF(tfa, R25C, (uint16_t)value); + } + break; + case TFA_MTP_RE25_SEC: + if ((tfa->rev & 0xFF) == 0x88) { + TFA_SET_BF(tfa, R25CR, (uint16_t)value); + } else { + pr_debug( + "Error: Current device has no secondary Re25 channel \n"); + err = Tfa98xx_Error_Bad_Parameter; + } + break; + case TFA_MTP_LOCK: + break; + } + + if (err != Tfa98xx_Error_Ok) { + pr_err("TFA98xx Error code is %d\n", err); + return tfa_error_max; + } + return tfa_error_ok; +} + +int tfa_get_pga_gain(struct tfa_device *tfa) +{ + return TFA_GET_BF(tfa, SAAMGAIN); +} + +int tfa_set_pga_gain(struct tfa_device *tfa, uint16_t value) +{ + return TFA_SET_BF(tfa, SAAMGAIN, value); +} + +int tfa_get_noclk(struct tfa_device *tfa) +{ + return TFA_GET_BF(tfa, NOCLK); +} + +enum Tfa98xx_Error tfa_status(struct tfa_device *tfa) +{ + int value; + uint16_t val; + + /* + * check IC status bits: cold start + * and DSP watch dog bit to re init + */ + value = TFA_READ_REG(tfa, VDDS); /* STATUSREG */ + if (value < 0) + return -value; + val = (uint16_t)value; + + /* pr_debug("SYS_STATUS0: 0x%04x\n", val); */ + if (TFA_GET_BF_VALUE(tfa, ACS, val) || + TFA_GET_BF_VALUE(tfa, WDS, val)) { + if (TFA_GET_BF_VALUE(tfa, ACS, val)) + pr_err("ERROR: ACS\n"); + if (TFA_GET_BF_VALUE(tfa, WDS, val)) + pr_err("ERROR: WDS\n"); + + return Tfa98xx_Error_DSP_not_running; + } + + if (TFA_GET_BF_VALUE(tfa, SPKS, val)) + pr_err("ERROR: SPKS\n"); + if (!TFA_GET_BF_VALUE(tfa, SWS, val)) + pr_err("ERROR: SWS\n"); + + /* Check secondary errors */ + if (!TFA_GET_BF_VALUE(tfa, CLKS, val) || + !TFA_GET_BF_VALUE(tfa, UVDS, val) || + !TFA_GET_BF_VALUE(tfa, OVDS, val) || + !TFA_GET_BF_VALUE(tfa, OTDS, val) || + !TFA_GET_BF_VALUE(tfa, PLLS, val) || + (!(tfa->daimap & Tfa98xx_DAI_TDM) && + !TFA_GET_BF_VALUE(tfa, VDDS, val))) + pr_err("Misc errors detected: STATUS_FLAG0 = 0x%x\n", val); + + if ((tfa->daimap & Tfa98xx_DAI_TDM) && (tfa->tfa_family == 2)) { + value = TFA_READ_REG(tfa, TDMERR); /* STATUS_FLAGS1 */ + if (value < 0) + return -value; + val = (uint16_t)value; + if (TFA_GET_BF_VALUE(tfa, TDMERR, val) || + TFA_GET_BF_VALUE(tfa, TDMLUTER, val)) + pr_err("TDM related errors: STATUS_FLAG1 = 0x%x\n", + val); + } + + return Tfa98xx_Error_Ok; +} + +#ifdef __KERNEL__ +int tfa_plop_noise_interrupt(struct tfa_device *tfa, int profile, int vstep, + u8 pcm_format) +#else +int tfa_plop_noise_interrupt(struct tfa_device *tfa, int profile, int vstep) +#endif +{ + enum tfa_error err; + int no_clk = 0; + + /* Remove sticky bit by reading it once */ + TFA_GET_BF(tfa, NOCLK); + + /* No clock detected */ + if (tfa_irq_get(tfa, tfa9912_irq_stnoclk)) { + no_clk = TFA_GET_BF(tfa, NOCLK); + + /* Detect for clock is lost! (clock is not stable) */ + if (no_clk == 1) { + /* Clock is lost. Set I2CR to remove POP noise */ + pr_info("No clock detected. Resetting the I2CR to avoid pop on 72! \n"); +#ifdef __KERNEL__ + err = tfa_dev_start(tfa, profile, vstep, pcm_format); +#else + err = tfa_dev_start(tfa, profile, vstep); +#endif + if (err != tfa_error_ok) { + pr_err("Error loading i2c registers (tfa_dev_start), err=%d\n", + err); + } else { + pr_info("Setting i2c registers after I2CR succesfull\n"); + tfa_dev_set_state(tfa, TFA_STATE_UNMUTE, 0); + } + + /* Remove sticky bit by reading it once */ + tfa_get_noclk(tfa); + + /* This is only for SAAM on the 72. + Since the NOCLK interrupt is only enabled for 72 this is the place + However: Not tested yet! But also does not harm normal flow! + */ + if (strstr(tfaContProfileName(tfa->cnt, tfa->dev_idx, + profile), + ".saam")) { + pr_info("Powering down from a SAAM profile, workaround PLMA4766 used! \n"); + TFA_SET_BF(tfa, PWDN, 1); + TFA_SET_BF(tfa, AMPE, 0); + TFA_SET_BF(tfa, SAMMODE, 0); + } + } + + /* If clk is stable set polarity to check for LOW (no clock)*/ + tfa_irq_set_pol(tfa, tfa9912_irq_stnoclk, (no_clk == 0)); + + /* clear interrupt */ + tfa_irq_clear(tfa, tfa9912_irq_stnoclk); + } + + /* return no_clk to know we called tfa_dev_start */ + return no_clk; +} + +void tfa_lp_mode_interrupt(struct tfa_device *tfa) +{ + const int irq_stclp0 = + 36; /* FIXME: this 72 interrupt does not excist for 9912 */ + int lp0, lp1; + + if (tfa_irq_get(tfa, irq_stclp0)) { + lp0 = TFA_GET_BF(tfa, LP0); + if (lp0 > 0) { + pr_info("lowpower mode 0 detected\n"); + } else { + pr_info("lowpower mode 0 not detected\n"); + } + + tfa_irq_set_pol(tfa, irq_stclp0, (lp0 == 0)); + + /* clear interrupt */ + tfa_irq_clear(tfa, irq_stclp0); + } + + if (tfa_irq_get(tfa, tfa9912_irq_stclpr)) { + lp1 = TFA_GET_BF(tfa, LP1); + if (lp1 > 0) { + pr_info("lowpower mode 1 detected\n"); + } else { + pr_info("lowpower mode 1 not detected\n"); + } + + tfa_irq_set_pol(tfa, tfa9912_irq_stclpr, (lp1 == 0)); + + /* clear interrupt */ + tfa_irq_clear(tfa, tfa9912_irq_stclpr); + } +} diff --git a/techpack/audio/asoc/codecs/tfa98xx/src/tfa_init.c b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_init.c new file mode 100644 index 000000000000..8bd5167f889a --- /dev/null +++ b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_init.c @@ -0,0 +1,1727 @@ +/* + * Copyright 2014-2017 NXP Semiconductors + * Copyright (C) 2019 XiaoMi, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "dbgprint.h" +#include "tfa_service.h" +#include "tfa_internal.h" +#include "tfa_container.h" +#include "tfa98xx_tfafieldnames.h" + +/* The CurrentSense4 registers are not in the datasheet */ +#define TFA98XX_CURRENTSENSE4_CTRL_CLKGATECFOFF (1 << 2) +#define TFA98XX_CURRENTSENSE4 0x49 + +/***********************************************************************************/ +/* GLOBAL (Defaults) */ +/***********************************************************************************/ +static enum Tfa98xx_Error no_overload_function_available(struct tfa_device *tfa, + int not_used) +{ + (void)tfa; + (void)not_used; + + return Tfa98xx_Error_Ok; +} + +static enum Tfa98xx_Error +no_overload_function_available2(struct tfa_device *tfa) +{ + (void)tfa; + + return Tfa98xx_Error_Ok; +} + +/* tfa98xx_dsp_system_stable +* return: *ready = 1 when clocks are stable to allow DSP subsystem access +*/ +static enum Tfa98xx_Error tfa_dsp_system_stable(struct tfa_device *tfa, + int *ready) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + unsigned short status; + int value; + + /* check the contents of the STATUS register */ + value = TFA_READ_REG(tfa, AREFS); + if (value < 0) { + error = -value; + *ready = 0; + _ASSERT(error); /* an error here can be fatal */ + return error; + } + status = (unsigned short)value; + + /* check AREFS and CLKS: not ready if either is clear */ + *ready = !((TFA_GET_BF_VALUE(tfa, AREFS, status) == 0) || + (TFA_GET_BF_VALUE(tfa, CLKS, status) == 0)); + + return error; +} + +/* tfa98xx_toggle_mtp_clock + * Allows to stop clock for MTP/FAim needed for PLMA5505 */ +static enum Tfa98xx_Error tfa_faim_protect(struct tfa_device *tfa, int state) +{ + (void)tfa; + (void)state; + + return Tfa98xx_Error_Ok; +} + +/** Set internal oscillator into power down mode. + * + * This function is a worker for tfa98xx_set_osc_powerdown(). + * + * @param[in] tfa device description structure + * @param[in] state new state 0 - oscillator is on, 1 oscillator is off. + * + * @return Tfa98xx_Error_Ok when successfull, error otherwise. + */ +static enum Tfa98xx_Error tfa_set_osc_powerdown(struct tfa_device *tfa, + int state) +{ + /* This function has no effect in general case, only for tfa9912 */ + (void)tfa; + (void)state; + + return Tfa98xx_Error_Ok; +} + +static enum Tfa98xx_Error tfa_dsp_reset(struct tfa_device *tfa, int state) +{ + /* generic function */ + TFA_SET_BF_VOLATILE(tfa, RST, (uint16_t)state); + + return Tfa98xx_Error_Ok; +} + +int tfa_set_swprofile(struct tfa_device *tfa, unsigned short new_value) +{ + int mtpk, active_value = tfa->profile; + + /* Also set the new value in the struct */ + tfa->profile = new_value - 1; + + /* for TFA1 devices */ + /* it's in MTP shadow, so unlock if not done already */ + mtpk = TFA_GET_BF(tfa, MTPK); /* get current key */ + TFA_SET_BF_VOLATILE(tfa, MTPK, 0x5a); + TFA_SET_BF_VOLATILE(tfa, SWPROFIL, new_value); /* set current profile */ + TFA_SET_BF_VOLATILE(tfa, MTPK, (uint16_t)mtpk); /* restore key */ + + return active_value; +} + +static int tfa_get_swprofile(struct tfa_device *tfa) +{ + return TFA_GET_BF(tfa, SWPROFIL) - 1; +} + +static int tfa_set_swvstep(struct tfa_device *tfa, unsigned short new_value) +{ + int mtpk, active_value = tfa->vstep; + + /* Also set the new value in the struct */ + tfa->vstep = new_value - 1; + + /* for TFA1 devices */ + /* it's in MTP shadow, so unlock if not done already */ + mtpk = TFA_GET_BF(tfa, MTPK); /* get current key */ + TFA_SET_BF_VOLATILE(tfa, MTPK, 0x5a); + TFA_SET_BF_VOLATILE(tfa, SWVSTEP, new_value); /* set current vstep */ + TFA_SET_BF_VOLATILE(tfa, MTPK, (uint16_t)mtpk); /* restore key */ + + return active_value; +} + +static int tfa_get_swvstep(struct tfa_device *tfa) +{ + int value = 0; + /* Set the new value in the hw register */ + value = TFA_GET_BF(tfa, SWVSTEP); + + /* Also set the new value in the struct */ + tfa->vstep = value; + + return value - 1; /* invalid if 0 */ +} + +static int tfa_get_mtpb(struct tfa_device *tfa) +{ + int value = 0; + + /* Set the new value in the hw register */ + value = TFA_GET_BF(tfa, MTPB); + + return value; +} + +static enum Tfa98xx_Error tfa_set_mute_nodsp(struct tfa_device *tfa, int mute) +{ + (void)tfa; + (void)mute; + + return Tfa98xx_Error_Ok; +} + +void set_ops_defaults(struct tfa_device_ops *ops) +{ + /* defaults */ + ops->reg_read = tfa98xx_read_register16; + ops->reg_write = tfa98xx_write_register16; + ops->mem_read = tfa98xx_dsp_read_mem; + ops->mem_write = tfa98xx_dsp_write_mem_word; + ops->dsp_msg = tfa_dsp_msg; + ops->dsp_msg_read = tfa_dsp_msg_read; + ops->dsp_write_tables = no_overload_function_available; + ops->dsp_reset = tfa_dsp_reset; + ops->dsp_system_stable = tfa_dsp_system_stable; + ops->auto_copy_mtp_to_iic = no_overload_function_available2; + ops->factory_trimmer = no_overload_function_available2; + ops->set_swprof = tfa_set_swprofile; + ops->get_swprof = tfa_get_swprofile; + ops->set_swvstep = tfa_set_swvstep; + ops->get_swvstep = tfa_get_swvstep; + ops->get_mtpb = tfa_get_mtpb; + ops->set_mute = tfa_set_mute_nodsp; + ops->faim_protect = tfa_faim_protect; + ops->set_osc_powerdown = tfa_set_osc_powerdown; +} + +/***********************************************************************************/ +/* no TFA + * external DSP SB instance */ +/***********************************************************************************/ +static short tfanone_swvstep, swprof; //TODO emulate in hal plugin +static enum Tfa98xx_Error tfanone_dsp_system_stable(struct tfa_device *tfa, + int *ready) +{ + (void)tfa; /* suppress warning */ + *ready = 1; /* assume always ready */ + + return Tfa98xx_Error_Ok; +} + +static int tfanone_set_swprofile(struct tfa_device *tfa, + unsigned short new_value) +{ + int active_value = tfa_dev_get_swprof(tfa); + + /* Set the new value in the struct */ + tfa->profile = new_value - 1; + + /* Set the new value in the hw register */ + swprof = new_value; + + return active_value; +} + +static int tfanone_get_swprofile(struct tfa_device *tfa) +{ + (void)tfa; /* suppress warning */ + return swprof; +} + +static int tfanone_set_swvstep(struct tfa_device *tfa, unsigned short new_value) +{ + /* Set the new value in the struct */ + tfa->vstep = new_value - 1; + + /* Set the new value in the hw register */ + tfanone_swvstep = new_value; + + return new_value; +} + +static int tfanone_get_swvstep(struct tfa_device *tfa) +{ + (void)tfa; /* suppress warning */ + return tfanone_swvstep; +} + +void tfanone_ops(struct tfa_device_ops *ops) +{ + /* Set defaults for ops */ + set_ops_defaults(ops); + + ops->dsp_system_stable = tfanone_dsp_system_stable; + ops->set_swprof = tfanone_set_swprofile; + ops->get_swprof = tfanone_get_swprofile; + ops->set_swvstep = tfanone_set_swvstep; + ops->get_swvstep = tfanone_get_swvstep; +} + +/***********************************************************************************/ +/* TFA9912 */ +/***********************************************************************************/ +static enum Tfa98xx_Error tfa9912_faim_protect(struct tfa_device *tfa, + int status) +{ + enum Tfa98xx_Error ret = Tfa98xx_Error_Fail; + + if (tfa) { + if (status == 0 || status == 1) { + ret = -(tfa_set_bf(tfa, TFA9912_BF_SSFAIME, + (uint16_t)status)); + } + } + + return ret; +} + +static enum Tfa98xx_Error tfa9912_specific(struct tfa_device *tfa) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + unsigned short value, xor; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + /* Unlock keys to write settings */ + error = reg_write(tfa, 0x0F, 0x5A6B); + error = reg_read(tfa, 0xFB, &value); + xor = value ^ 0x005A; + error = reg_write(tfa, 0xA0, xor); + + /* The optimal settings */ + if (tfa->rev == 0x1a13) { + /* ----- generated code start ----- */ + /* ----- version 1.41 ----- */ + reg_write(tfa, 0x00, 0x0255); //POR=0x0245 + reg_write(tfa, 0x01, 0x838a); //POR=0x83ca + reg_write(tfa, 0x02, 0x2dc8); //POR=0x2828 + reg_write(tfa, 0x05, 0x762a); //POR=0x766a + reg_write(tfa, 0x22, 0x543c); //POR=0x545c + reg_write(tfa, 0x26, 0x0100); //POR=0x0010 + reg_write(tfa, 0x51, 0x0000); //POR=0x0080 + reg_write(tfa, 0x52, 0x551c); //POR=0x1afc + reg_write(tfa, 0x53, 0x003e); //POR=0x001e + reg_write(tfa, 0x61, 0x000c); //POR=0x0018 + reg_write(tfa, 0x63, 0x0a96); //POR=0x0a9a + reg_write(tfa, 0x65, 0x0a82); //POR=0x0a8b + reg_write(tfa, 0x66, 0x0701); //POR=0x0700 + reg_write(tfa, 0x6c, 0x00d5); //POR=0x02d5 + reg_write(tfa, 0x70, 0x26f8); //POR=0x06e0 + reg_write(tfa, 0x71, 0x3074); //POR=0x2074 + reg_write(tfa, 0x75, 0x4484); //POR=0x4585 + reg_write(tfa, 0x76, 0x72ea); //POR=0x54a2 + reg_write(tfa, 0x83, 0x0716); //POR=0x0617 + reg_write(tfa, 0x89, 0x0013); //POR=0x0014 + reg_write(tfa, 0xb0, 0x4c08); //POR=0x4c00 + reg_write( + tfa, 0xc6, + 0x004e); //POR=0x000e /* PLMA5539: Please make sure bit 6 is always on! */ + /* ----- generated code end ----- */ + + /* PLMA5505: MTP key open makes vulanable for MTP corruption */ + tfa9912_faim_protect(tfa, 0); + } else { + pr_info("Warning: Optimal settings not found for device with revid = 0x%x \n", + tfa->rev); + } + + return error; +} + +static enum Tfa98xx_Error tfa9912_tfa_dsp_write_tables(struct tfa_device *tfa, + int sample_rate) +{ + unsigned char buffer[15] = { 0 }; + int size = 15 * sizeof(char); + + /* Write the fractional delay in the hardware register 'cs_frac_delay' */ + switch (sample_rate) { + case 0: /* 8kHz */ + TFA_SET_BF(tfa, FRACTDEL, 40); + break; + case 1: /* 11.025KHz */ + TFA_SET_BF(tfa, FRACTDEL, 38); + break; + case 2: /* 12kHz */ + TFA_SET_BF(tfa, FRACTDEL, 37); + break; + case 3: /* 16kHz */ + TFA_SET_BF(tfa, FRACTDEL, 59); + break; + case 4: /* 22.05KHz */ + TFA_SET_BF(tfa, FRACTDEL, 56); + break; + case 5: /* 24kHz */ + TFA_SET_BF(tfa, FRACTDEL, 56); + break; + case 6: /* 32kHz */ + TFA_SET_BF(tfa, FRACTDEL, 52); + break; + case 7: /* 44.1kHz */ + TFA_SET_BF(tfa, FRACTDEL, 48); + break; + case 8: + default: /* 48kHz */ + TFA_SET_BF(tfa, FRACTDEL, 46); + break; + } + + /* First copy the msg_id to the buffer */ + buffer[0] = (uint8_t)0; + buffer[1] = (uint8_t)MODULE_FRAMEWORK + 128; + buffer[2] = (uint8_t)FW_PAR_ID_SET_SENSES_DELAY; + + /* Required for all FS exept 8kHz (8kHz is all zero) */ + if (sample_rate != 0) { + buffer[5] = 1; /* Vdelay_P */ + buffer[8] = 0; /* Idelay_P */ + buffer[11] = 1; /* Vdelay_S */ + buffer[14] = 0; /* Idelay_S */ + } + + /* send SetSensesDelay msg */ + return dsp_msg(tfa, size, (char *)buffer); +} + +static enum Tfa98xx_Error tfa9912_factory_trimmer(struct tfa_device *tfa) +{ + unsigned short currentValue, delta; + int result; + + /* Factory trimming for the Boost converter */ + /* check if there is a correction needed */ + result = TFA_GET_BF(tfa, DCMCCAPI); + if (result) { + /* Get currentvalue of DCMCC and the Delta value */ + currentValue = (unsigned short)TFA_GET_BF(tfa, DCMCC); + delta = (unsigned short)TFA_GET_BF(tfa, USERDEF); + + /* check the sign bit (+/-) */ + result = TFA_GET_BF(tfa, DCMCCSB); + if (result == 0) { + /* Do not exceed the maximum value of 15 */ + if (currentValue + delta < 15) { + TFA_SET_BF_VOLATILE(tfa, DCMCC, + currentValue + delta); + if (tfa->verbose) + pr_debug( + "Max coil current is set to: %d \n", + currentValue + delta); + } else { + TFA_SET_BF_VOLATILE(tfa, DCMCC, 15); + if (tfa->verbose) + pr_debug( + "Max coil current is set to: 15 \n"); + } + } else if (result == 1) { + /* Do not exceed the minimum value of 0 */ + if (currentValue - delta > 0) { + TFA_SET_BF_VOLATILE(tfa, DCMCC, + currentValue - delta); + if (tfa->verbose) + pr_debug( + "Max coil current is set to: %d \n", + currentValue - delta); + } else { + TFA_SET_BF_VOLATILE(tfa, DCMCC, 0); + if (tfa->verbose) + pr_debug( + "Max coil current is set to: 0 \n"); + } + } + } + + return Tfa98xx_Error_Ok; +} + +static enum Tfa98xx_Error tfa9912_auto_copy_mtp_to_iic(struct tfa_device *tfa) +{ + /* Set auto_copy_mtp_to_iic (bit 5 of A3) to 1. Workaround for 72, 88 and 9912/9892(see PLMA5290) */ + return reg_write(tfa, 0xA3, 0x20); +} + +static int tfa9912_set_swprofile(struct tfa_device *tfa, + unsigned short new_value) +{ + int active_value = tfa_dev_get_swprof(tfa); + + /* Set the new value in the struct */ + tfa->profile = new_value - 1; + + /* Set the new value in the hw register */ + tfa_set_bf_volatile(tfa, TFA9912_BF_SWPROFIL, new_value); + + return active_value; +} + +static int tfa9912_get_swprofile(struct tfa_device *tfa) +{ + return tfa_get_bf(tfa, TFA9912_BF_SWPROFIL) - 1; +} + +static int tfa9912_set_swvstep(struct tfa_device *tfa, unsigned short new_value) +{ + /* Set the new value in the struct */ + tfa->vstep = new_value - 1; + + /* Set the new value in the hw register */ + tfa_set_bf_volatile(tfa, TFA9912_BF_SWVSTEP, new_value); + + return new_value; +} + +static int tfa9912_get_swvstep(struct tfa_device *tfa) +{ + return tfa_get_bf(tfa, TFA9912_BF_SWVSTEP) - 1; +} + +static enum Tfa98xx_Error tfa9912_set_mute(struct tfa_device *tfa, int mute) +{ + tfa_set_bf(tfa, TFA9912_BF_CFSM, (const uint16_t)mute); + + return Tfa98xx_Error_Ok; +} + +/* Maksimum value for combination of boost_voltage and vout calibration offset (see PLMA5322, PLMA5528). */ +#define TFA9912_VBOOST_MAX 57 +#define TFA9912_CALIBR_BOOST_MAX 63 +#define TFA9912_DCDCCNT6_REG (TFA9912_BF_DCVOF >> 8) +#define TFA9912_CALIBR_REG 0xf1 + +static uint16_t tfa9912_vboost_fixup(struct tfa_device *tfa, uint16_t dcdc_cnt6) +{ + unsigned short cal_offset; + unsigned short boost_v_1st, boost_v_2nd; + uint16_t new_dcdc_cnt6; + + /* Get current calibr_vout_offset, this register is not supported by bitfields */ + reg_read(tfa, TFA9912_CALIBR_REG, &cal_offset); + cal_offset = (cal_offset & 0x001f); + new_dcdc_cnt6 = dcdc_cnt6; + + /* Get current boost_volatage values */ + boost_v_1st = tfa_get_bf_value(TFA9912_BF_DCVOF, new_dcdc_cnt6); + boost_v_2nd = tfa_get_bf_value(TFA9912_BF_DCVOS, new_dcdc_cnt6); + + /* Check boost voltages */ + if (boost_v_1st > TFA9912_VBOOST_MAX) + boost_v_1st = TFA9912_VBOOST_MAX; + + if (boost_v_2nd > TFA9912_VBOOST_MAX) + boost_v_2nd = TFA9912_VBOOST_MAX; + + /* Recalculate values, max for the sum is TFA9912_CALIBR_BOOST_MAX */ + if (boost_v_1st + cal_offset > TFA9912_CALIBR_BOOST_MAX) + boost_v_1st = TFA9912_CALIBR_BOOST_MAX - cal_offset; + + if (boost_v_2nd + cal_offset > TFA9912_CALIBR_BOOST_MAX) + boost_v_2nd = TFA9912_CALIBR_BOOST_MAX - cal_offset; + + tfa_set_bf_value(TFA9912_BF_DCVOF, boost_v_1st, &new_dcdc_cnt6); + tfa_set_bf_value(TFA9912_BF_DCVOS, boost_v_2nd, &new_dcdc_cnt6); + + /* Change register value only when it's neccesary */ + if (new_dcdc_cnt6 != dcdc_cnt6) { + if (tfa->verbose) + pr_debug( + "tfa9912: V boost fixup applied. Old 0x%04x, new 0x%04x\n", + dcdc_cnt6, new_dcdc_cnt6); + dcdc_cnt6 = new_dcdc_cnt6; + } + + return dcdc_cnt6; +} + +/* PLMA5322, PLMA5528 - Limit values of DCVOS and DCVOF to range specified in datasheet. */ +enum Tfa98xx_Error tfa9912_reg_write(struct tfa_device *tfa, + unsigned char subaddress, + unsigned short value) +{ + if (subaddress == TFA9912_DCDCCNT6_REG) { + /* Correct V boost (first and secondary) to ensure 12V is not exceeded. */ + value = tfa9912_vboost_fixup(tfa, value); + } + + return tfa98xx_write_register16(tfa, subaddress, value); +} + +/** Set internal oscillator into power down mode for TFA9912. +* +* This function is a worker for tfa98xx_set_osc_powerdown(). +* +* @param[in] tfa device description structure +* @param[in] state new state 0 - oscillator is on, 1 oscillator is off. +* +* @return Tfa98xx_Error_Ok when successfull, error otherwise. +*/ +static enum Tfa98xx_Error tfa9912_set_osc_powerdown(struct tfa_device *tfa, + int state) +{ + if (state == 1 || state == 0) { + return -tfa_set_bf(tfa, TFA9912_BF_MANAOOSC, (uint16_t)state); + } + + return Tfa98xx_Error_Bad_Parameter; +} + +void tfa9912_ops(struct tfa_device_ops *ops) +{ + /* Set defaults for ops */ + set_ops_defaults(ops); + + ops->tfa_init = tfa9912_specific; + /* PLMA5322, PLMA5528 - Limits values of DCVOS and DCVOF. */ + ops->reg_write = tfa9912_reg_write; + ops->dsp_write_tables = tfa9912_tfa_dsp_write_tables; + ops->factory_trimmer = tfa9912_factory_trimmer; + ops->auto_copy_mtp_to_iic = tfa9912_auto_copy_mtp_to_iic; + ops->set_swprof = tfa9912_set_swprofile; + ops->get_swprof = tfa9912_get_swprofile; + ops->set_swvstep = tfa9912_set_swvstep; + ops->get_swvstep = tfa9912_get_swvstep; + ops->set_mute = tfa9912_set_mute; + ops->faim_protect = tfa9912_faim_protect; + ops->set_osc_powerdown = tfa9912_set_osc_powerdown; +} + +/***********************************************************************************/ +/* TFA9872 */ +/***********************************************************************************/ +static enum Tfa98xx_Error tfa9872_specific(struct tfa_device *tfa) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + uint16_t MANAOOSC = 0x0140; /* version 17 */ + unsigned short value, xor; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + /* Unlock key 1 and 2 */ + error = reg_write(tfa, 0x0F, 0x5A6B); + error = reg_read(tfa, 0xFB, &value); + xor = value ^ 0x005A; + error = reg_write(tfa, 0xA0, xor); + tfa98xx_key2(tfa, 0); + + switch (tfa->rev) { + case 0x1a72: + case 0x2a72: + /* ----- generated code start ----- */ + /* ----- version 26 ----- */ + reg_write(tfa, 0x00, 0x1801); //POR=0x0001 + reg_write(tfa, 0x02, 0x2dc8); //POR=0x2028 + reg_write(tfa, 0x20, 0x0890); //POR=0x2890 + reg_write(tfa, 0x22, 0x043c); //POR=0x045c + reg_write(tfa, 0x51, 0x0000); //POR=0x0080 + reg_write(tfa, 0x52, 0x1a1c); //POR=0x7ae8 + reg_write(tfa, 0x58, 0x161c); //POR=0x101c + reg_write(tfa, 0x61, 0x0198); //POR=0x0000 + reg_write(tfa, 0x65, 0x0a8b); //POR=0x0a9a + reg_write(tfa, 0x70, 0x07f5); //POR=0x06e6 + reg_write(tfa, 0x74, 0xcc84); //POR=0xd823 + reg_write(tfa, 0x82, 0x01ed); //POR=0x000d + reg_write(tfa, 0x83, 0x0014); //POR=0x0013 + reg_write(tfa, 0x84, 0x0021); //POR=0x0020 + reg_write(tfa, 0x85, 0x0001); //POR=0x0003 + /* ----- generated code end ----- */ + break; + case 0x1b72: + case 0x2b72: + case 0x3b72: + /* ----- generated code start ----- */ + /* ----- TFA9872 Probus Registers map N1B2 - Version 21 (10/19/2016) ----- */ + reg_write(tfa, 0x02, 0x2dc8); //POR=0x2828 + reg_write(tfa, 0x20, 0x0890); //POR=0x2890 + reg_write(tfa, 0x22, 0x043c); //POR=0x045c + reg_write(tfa, 0x23, 0x0001); //POR=0x0003 + reg_write(tfa, 0x51, 0x0000); //POR=0x0080 + reg_write(tfa, 0x52, 0x5a1c); //POR=0x7a08 + reg_write(tfa, 0x61, 0x0198); //POR=0x0000 + reg_write(tfa, 0x63, 0x0a9a); //POR=0x0a93 + reg_write(tfa, 0x65, 0x0a82); //POR=0x0a8d + reg_write(tfa, 0x6f, 0x01e3); //POR=0x02e4 + reg_write(tfa, 0x70, 0x06fd); //POR=0x06e6 + reg_write(tfa, 0x71, 0x307e); //POR=0x207e + reg_write(tfa, 0x74, 0xcc84); //POR=0xd913 + reg_write(tfa, 0x75, 0x1132); //POR=0x118a + reg_write(tfa, 0x82, 0x01ed); //POR=0x000d + reg_write(tfa, 0x83, 0x001a); //POR=0x0013 + /* ----- generated code end ----- */ + break; + default: + pr_info("\nWarning: Optimal settings not found for device with revid = 0x%x \n", + tfa->rev); + break; + } + + /* Turn off the osc1m to save power: PLMA4928 */ + error = tfa_set_bf(tfa, MANAOOSC, 1); + + /* Bypass OVP by setting bit 3 from register 0xB0 (bypass_ovp=1): PLMA5258 */ + error = reg_read(tfa, 0xB0, &value); + value |= 1 << 3; + error = reg_write(tfa, 0xB0, value); + + return error; +} + +static enum Tfa98xx_Error tfa9872_auto_copy_mtp_to_iic(struct tfa_device *tfa) +{ + /* Set auto_copy_mtp_to_iic (bit 5 of A3) to 1. Workaround for 72 and 88 (see PLMA5290) */ + return reg_write(tfa, 0xA3, 0x20); +} + +static int tfa9872_set_swprofile(struct tfa_device *tfa, + unsigned short new_value) +{ + int active_value = tfa_dev_get_swprof(tfa); + + /* Set the new value in the struct */ + tfa->profile = new_value - 1; + + /* Set the new value in the hw register */ + tfa_set_bf_volatile(tfa, TFA9872_BF_SWPROFIL, new_value); + + return active_value; +} + +static int tfa9872_get_swprofile(struct tfa_device *tfa) +{ + return tfa_get_bf(tfa, TFA9872_BF_SWPROFIL) - 1; +} + +static int tfa9872_set_swvstep(struct tfa_device *tfa, unsigned short new_value) +{ + /* Set the new value in the struct */ + tfa->vstep = new_value - 1; + + /* Set the new value in the hw register */ + tfa_set_bf_volatile(tfa, TFA9872_BF_SWVSTEP, new_value); + + return new_value; +} + +static int tfa9872_get_swvstep(struct tfa_device *tfa) +{ + return tfa_get_bf(tfa, TFA9872_BF_SWVSTEP) - 1; +} + +void tfa9872_ops(struct tfa_device_ops *ops) +{ + /* Set defaults for ops */ + set_ops_defaults(ops); + + ops->tfa_init = tfa9872_specific; + ops->auto_copy_mtp_to_iic = tfa9872_auto_copy_mtp_to_iic; + ops->set_swprof = tfa9872_set_swprofile; + ops->get_swprof = tfa9872_get_swprofile; + ops->set_swvstep = tfa9872_set_swvstep; + ops->get_swvstep = tfa9872_get_swvstep; + ops->set_mute = tfa_set_mute_nodsp; +} + +/***********************************************************************************/ +/* TFA9874 */ +/***********************************************************************************/ + +static enum Tfa98xx_Error tfa9874_faim_protect(struct tfa_device *tfa, + int status) +{ + enum Tfa98xx_Error ret = Tfa98xx_Error_Ok; + /* 0b = FAIM protection enabled 1b = FAIM protection disabled*/ + ret = tfa_set_bf_volatile(tfa, TFA9874_BF_OPENMTP, (uint16_t)(status)); + return ret; +} + +static enum Tfa98xx_Error tfa9874_specific(struct tfa_device *tfa) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + unsigned short value, xor; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + /* Unlock key 1 and 2 */ + error = reg_write(tfa, 0x0F, 0x5A6B); + error = reg_read(tfa, 0xFB, &value); + xor = value ^ 0x005A; + error = reg_write(tfa, 0xA0, xor); + tfa98xx_key2(tfa, 0); + + switch (tfa->rev) { + case 0x0a74: /* Initial revision ID */ + /* ----- generated code start ----- */ + /* V25 */ + reg_write(tfa, 0x02, 0x22a8); //POR=0x25c8 + reg_write(tfa, 0x51, 0x0020); //POR=0x0000 + reg_write(tfa, 0x52, 0x57dc); //POR=0x56dc + reg_write(tfa, 0x58, 0x16a4); //POR=0x1614 + reg_write(tfa, 0x61, 0x0110); //POR=0x0198 + reg_write(tfa, 0x66, 0x0701); //POR=0x0700 + reg_write(tfa, 0x6f, 0x00a3); //POR=0x01a3 + reg_write(tfa, 0x70, 0x07f8); //POR=0x06f8 + reg_write(tfa, 0x73, 0x0007); //POR=0x0005 + reg_write(tfa, 0x74, 0x5068); //POR=0xcc80 + reg_write(tfa, 0x75, 0x0d28); //POR=0x1138 + reg_write(tfa, 0x83, 0x0594); //POR=0x061a + reg_write(tfa, 0x84, 0x0001); //POR=0x0021 + reg_write(tfa, 0x85, 0x0001); //POR=0x0003 + reg_write(tfa, 0x88, 0x0000); //POR=0x0002 + reg_write(tfa, 0xc4, 0x2001); //POR=0x0001 + /* ----- generated code end ----- */ + break; + case 0x0b74: + /* ----- generated code start ----- */ + /* V1.6 */ + reg_write(tfa, 0x02, 0x22a8); //POR=0x25c8 + reg_write(tfa, 0x51, 0x0020); //POR=0x0000 + reg_write(tfa, 0x52, 0x57dc); //POR=0x56dc + reg_write(tfa, 0x58, 0x16a4); //POR=0x1614 + reg_write(tfa, 0x61, 0x0110); //POR=0x0198 + reg_write(tfa, 0x66, 0x0701); //POR=0x0700 + reg_write(tfa, 0x6f, 0x00a3); //POR=0x01a3 + reg_write(tfa, 0x70, 0x07f8); //POR=0x06f8 + reg_write(tfa, 0x73, 0x0047); //POR=0x0045 + reg_write(tfa, 0x74, 0x5068); //POR=0xcc80 + reg_write(tfa, 0x75, 0x0d28); //POR=0x1138 + reg_write(tfa, 0x83, 0x0595); //POR=0x061a + reg_write(tfa, 0x84, 0x0001); //POR=0x0021 + reg_write(tfa, 0x85, 0x0001); //POR=0x0003 + reg_write(tfa, 0x88, 0x0000); //POR=0x0002 + reg_write(tfa, 0xc4, 0x2001); //POR=0x0001 + /* ----- generated code end ----- */ + break; + case 0x0c74: + /* ----- generated code start ----- */ + /* V1.14 */ + reg_write(tfa, 0x02, 0x22c8); //POR=0x25c8 + reg_write(tfa, 0x52, 0x57dc); //POR=0x56dc + reg_write(tfa, 0x53, 0x003e); //POR=0x001e + reg_write(tfa, 0x56, 0x0400); //POR=0x0600 + reg_write(tfa, 0x61, 0x0110); //POR=0x0198 + reg_write(tfa, 0x6f, 0x00a5); //POR=0x01a3 + reg_write(tfa, 0x70, 0x07f8); //POR=0x06f8 + reg_write(tfa, 0x73, 0x0047); //POR=0x0045 + reg_write(tfa, 0x74, 0x5098); //POR=0xcc80 + reg_write(tfa, 0x75, 0x8d28); //POR=0x1138 + reg_write(tfa, 0x80, 0x0000); //POR=0x0003 + reg_write(tfa, 0x83, 0x0799); //POR=0x061a + reg_write(tfa, 0x84, 0x0081); //POR=0x0021 + /* ----- generated code end ----- */ + break; + default: + pr_info("\nWarning: Optimal settings not found for device with revid = 0x%x \n", + tfa->rev); + break; + } + + return error; +} + +static int tfa9874_set_swprofile(struct tfa_device *tfa, + unsigned short new_value) +{ + int active_value = tfa_dev_get_swprof(tfa); + + /* Set the new value in the struct */ + tfa->profile = new_value - 1; + + /* Set the new value in the hw register */ + tfa_set_bf_volatile(tfa, TFA9874_BF_SWPROFIL, new_value); + + return active_value; +} + +static int tfa9874_get_swprofile(struct tfa_device *tfa) +{ + return tfa_get_bf(tfa, TFA9874_BF_SWPROFIL) - 1; +} + +static int tfa9874_set_swvstep(struct tfa_device *tfa, unsigned short new_value) +{ + /* Set the new value in the struct */ + tfa->vstep = new_value - 1; + + /* Set the new value in the hw register */ + tfa_set_bf_volatile(tfa, TFA9874_BF_SWVSTEP, new_value); + + return new_value; +} + +static int tfa9874_get_swvstep(struct tfa_device *tfa) +{ + return tfa_get_bf(tfa, TFA9874_BF_SWVSTEP) - 1; +} + +/* tfa98xx_dsp_system_stable +* return: *ready = 1 when clocks are stable to allow DSP subsystem access +*/ +static enum Tfa98xx_Error tfa9874_dsp_system_stable(struct tfa_device *tfa, + int *ready) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + + /* check CLKS: ready if set */ + *ready = tfa_get_bf(tfa, TFA9874_BF_CLKS) == 1; + + return error; +} + +static int tfa9874_get_mtpb(struct tfa_device *tfa) +{ + int value; + value = tfa_get_bf(tfa, TFA9874_BF_MTPB); + return value; +} + +void tfa9874_ops(struct tfa_device_ops *ops) +{ + /* Set defaults for ops */ + set_ops_defaults(ops); + + ops->tfa_init = tfa9874_specific; + ops->set_swprof = tfa9874_set_swprofile; + ops->get_swprof = tfa9874_get_swprofile; + ops->set_swvstep = tfa9874_set_swvstep; + ops->get_swvstep = tfa9874_get_swvstep; + ops->dsp_system_stable = tfa9874_dsp_system_stable; + ops->faim_protect = tfa9874_faim_protect; + ops->get_mtpb = tfa9874_get_mtpb; + ops->set_mute = tfa_set_mute_nodsp; +} + +/***********************************************************************************/ +/* TFA9888 */ +/***********************************************************************************/ +static enum Tfa98xx_Error tfa9888_specific(struct tfa_device *tfa) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + unsigned short value, xor; + int patch_version; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + /* Unlock keys to write settings */ + error = reg_write(tfa, 0x0F, 0x5A6B); + error = reg_read(tfa, 0xFB, &value); + xor = value ^ 0x005A; + error = reg_write(tfa, 0xA0, xor); + + /* Only N1C2 is supported */ + /* ----- generated code start ----- */ + /* --------- Version v1 ---------- */ + if (tfa->rev == 0x2c88) { + reg_write(tfa, 0x00, 0x164d); //POR=0x064d + reg_write(tfa, 0x01, 0x828b); //POR=0x92cb + reg_write(tfa, 0x02, 0x1dc8); //POR=0x1828 + reg_write(tfa, 0x0e, 0x0080); //POR=0x0000 + reg_write(tfa, 0x20, 0x089e); //POR=0x0890 + reg_write(tfa, 0x22, 0x543c); //POR=0x545c + reg_write(tfa, 0x23, 0x0006); //POR=0x0000 + reg_write(tfa, 0x24, 0x0014); //POR=0x0000 + reg_write(tfa, 0x25, 0x000a); //POR=0x0000 + reg_write(tfa, 0x26, 0x0100); //POR=0x0000 + reg_write(tfa, 0x28, 0x1000); //POR=0x0000 + reg_write(tfa, 0x51, 0x0000); //POR=0x00c0 + reg_write(tfa, 0x52, 0xfafe); //POR=0xbaf6 + reg_write(tfa, 0x70, 0x3ee4); //POR=0x3ee6 + reg_write(tfa, 0x71, 0x1074); //POR=0x3074 + reg_write(tfa, 0x83, 0x0014); //POR=0x0013 + /* ----- generated code end ----- */ + } else { + pr_info("Warning: Optimal settings not found for device with revid = 0x%x \n", + tfa->rev); + } + + patch_version = tfa_cnt_get_patch_version(tfa); + if (patch_version >= 0x060401) + tfa->partial_enable = 1; + + return error; +} + +static enum Tfa98xx_Error tfa9888_tfa_dsp_write_tables(struct tfa_device *tfa, + int sample_rate) +{ + unsigned char buffer[15] = { 0 }; + int size = 15 * sizeof(char); + + /* Write the fractional delay in the hardware register 'cs_frac_delay' */ + switch (sample_rate) { + case 0: /* 8kHz */ + TFA_SET_BF(tfa, FRACTDEL, 40); + break; + case 1: /* 11.025KHz */ + TFA_SET_BF(tfa, FRACTDEL, 38); + break; + case 2: /* 12kHz */ + TFA_SET_BF(tfa, FRACTDEL, 37); + break; + case 3: /* 16kHz */ + TFA_SET_BF(tfa, FRACTDEL, 59); + break; + case 4: /* 22.05KHz */ + TFA_SET_BF(tfa, FRACTDEL, 56); + break; + case 5: /* 24kHz */ + TFA_SET_BF(tfa, FRACTDEL, 56); + break; + case 6: /* 32kHz */ + TFA_SET_BF(tfa, FRACTDEL, 52); + break; + case 7: /* 44.1kHz */ + TFA_SET_BF(tfa, FRACTDEL, 48); + break; + case 8: + default: /* 48kHz */ + TFA_SET_BF(tfa, FRACTDEL, 46); + break; + } + + /* First copy the msg_id to the buffer */ + buffer[0] = (uint8_t)0; + buffer[1] = (uint8_t)MODULE_FRAMEWORK + 128; + buffer[2] = (uint8_t)FW_PAR_ID_SET_SENSES_DELAY; + + /* Required for all FS exept 8kHz (8kHz is all zero) */ + if (sample_rate != 0) { + buffer[5] = 1; /* Vdelay_P */ + buffer[8] = 0; /* Idelay_P */ + buffer[11] = 1; /* Vdelay_S */ + buffer[14] = 0; /* Idelay_S */ + } + + /* send SetSensesDelay msg */ + return dsp_msg(tfa, size, (char *)buffer); +} + +static enum Tfa98xx_Error tfa9888_auto_copy_mtp_to_iic(struct tfa_device *tfa) +{ + /* Set auto_copy_mtp_to_iic (bit 5 of A3) to 1. Workaround for 72 and 88 (see PLMA5290) */ + return reg_write(tfa, 0xA3, 0x20); +} + +static enum Tfa98xx_Error tfa9888_factory_trimmer(struct tfa_device *tfa) +{ + unsigned short currentValue, delta; + int result; + + /* Factory trimming for the Boost converter */ + /* check if there is a correction needed */ + result = TFA_GET_BF(tfa, DCMCCAPI); + if (result) { + /* Get currentvalue of DCMCC and the Delta value */ + currentValue = (unsigned short)TFA_GET_BF(tfa, DCMCC); + delta = (unsigned short)TFA_GET_BF(tfa, USERDEF); + + /* check the sign bit (+/-) */ + result = TFA_GET_BF(tfa, DCMCCSB); + if (result == 0) { + /* Do not exceed the maximum value of 15 */ + if (currentValue + delta < 15) { + TFA_SET_BF_VOLATILE(tfa, DCMCC, + currentValue + delta); + if (tfa->verbose) + pr_debug( + "Max coil current is set to: %d \n", + currentValue + delta); + } else { + TFA_SET_BF_VOLATILE(tfa, DCMCC, 15); + if (tfa->verbose) + pr_debug( + "Max coil current is set to: 15 \n"); + } + } else if (result == 1) { + /* Do not exceed the minimum value of 0 */ + if (currentValue - delta > 0) { + TFA_SET_BF_VOLATILE(tfa, DCMCC, + currentValue - delta); + if (tfa->verbose) + pr_debug( + "Max coil current is set to: %d \n", + currentValue - delta); + } else { + TFA_SET_BF_VOLATILE(tfa, DCMCC, 0); + if (tfa->verbose) + pr_debug( + "Max coil current is set to: 0 \n"); + } + } + } + + return Tfa98xx_Error_Ok; +} + +static enum Tfa98xx_Error tfa9888_set_mute(struct tfa_device *tfa, int mute) +{ + TFA_SET_BF(tfa, CFSMR, (const uint16_t)mute); + TFA_SET_BF(tfa, CFSML, (const uint16_t)mute); + + return Tfa98xx_Error_Ok; +} + +void tfa9888_ops(struct tfa_device_ops *ops) +{ + /* Set defaults for ops */ + set_ops_defaults(ops); + + ops->tfa_init = tfa9888_specific; + ops->dsp_write_tables = tfa9888_tfa_dsp_write_tables; + ops->auto_copy_mtp_to_iic = tfa9888_auto_copy_mtp_to_iic; + ops->factory_trimmer = tfa9888_factory_trimmer; + ops->set_mute = tfa9888_set_mute; +} + +/***********************************************************************************/ +/* TFA9896 */ +/***********************************************************************************/ +static enum Tfa98xx_Error tfa9896_faim_protect(struct tfa_device *tfa, + int status) +{ + enum Tfa98xx_Error ret = Tfa98xx_Error_Ok; + + if ((tfa->rev == 0x2b96) || (tfa->rev == 0x3b96)) { + ret = tfa_set_bf_volatile(tfa, TFA9896_BF_OPENMTP, + (uint16_t)status); + } + + return ret; +} + +/***********************************************************************************/ +/* TFA9896 */ +/***********************************************************************************/ +static enum Tfa98xx_Error tfa9896_specific(struct tfa_device *tfa) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + unsigned short check_value; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + /* all i2C registers must already set to default POR value */ + + /* $48:[3] - 1 ==> 0; iddqtestbst - default value changed. + * When Iddqtestbst is set to "0", the slewrate is reduced. + * This will lower the overshoot on IN-B to avoid NMOS damage of booster. + */ + if (tfa->rev == 0x1b96) { + /* ----- generated code start v17 ----- */ + reg_write(tfa, 0x06, 0x000b); //POR=0x0001 + reg_write(tfa, 0x07, 0x3e7f); //POR=0x1e7f + reg_write(tfa, 0x0a, 0x0d8a); //POR=0x0592 + reg_write(tfa, 0x48, 0x0300); //POR=0x0308 + reg_write(tfa, 0x88, 0x0100); //POR=0x0000 + /* ----- generated code end ----- */ + } else if (tfa->rev == 0x2b96) { + /* ----- generated code start ----- v1*/ + reg_write(tfa, 0x06, 0x000b); //POR=0x0001 + reg_write(tfa, 0x07, 0x3e7f); //POR=0x1e7f + reg_write(tfa, 0x0a, 0x0d8a); //POR=0x0592 + reg_write(tfa, 0x48, 0x0300); //POR=0x0308 + reg_write(tfa, 0x88, 0x0100); //POR=0x0000 + /* ----- generated code end ----- */ + } else if (tfa->rev == 0x3b96) { + /* ----- generated code start ----- v1*/ + reg_write(tfa, 0x06, 0x000b); //POR=0x0001 + reg_write(tfa, 0x07, 0x3e7f); //POR=0x1e7f + reg_write(tfa, 0x0a, 0x0d8a); //POR=0x0592 + reg_write(tfa, 0x48, 0x0300); //POR=0x0308 + reg_write(tfa, 0x88, 0x0100); //POR=0x0000 + /* ----- generated code end ----- */ + } + /* $49:[0] - 1 ==> 0; CLIP - default value changed. 0 means CLIPPER on */ + error = reg_read(tfa, 0x49, &check_value); + check_value &= ~0x1; + error = reg_write(tfa, 0x49, check_value); + return error; +} + +/* +* the int24 values for the vsfw delay table +*/ +static unsigned char tfa9896_vsfwdelay_table[] = { + 0, 0, 2, /* Index 0 - Current/Volt Fractional Delay for 8KHz */ + 0, 0, 0, /* Index 1 - Current/Volt Fractional Delay for 11KHz */ + 0, 0, 0, /* Index 2 - Current/Volt Fractional Delay for 12KHz */ + 0, 0, 2, /* Index 3 - Current/Volt Fractional Delay for 16KHz */ + 0, 0, 2, /* Index 4 - Current/Volt Fractional Delay for 22KHz */ + 0, 0, 2, /* Index 5 - Current/Volt Fractional Delay for 24KHz */ + 0, 0, 2, /* Index 6 - Current/Volt Fractional Delay for 32KHz */ + 0, 0, 2, /* Index 7 - Current/Volt Fractional Delay for 44KHz */ + 0, 0, 3 /* Index 8 - Current/Volt Fractional Delay for 48KHz */ +}; + +/* +* TODO make this tfa98xx +* Note that the former products write this table via the patch +* so moving this to the tfa98xx API requires also updating all patches +*/ +static enum Tfa98xx_Error +tfa9896_dsp_write_vsfwdelay_table(struct tfa_device *tfa) +{ + return tfa_dsp_cmd_id_write(tfa, MODULE_FRAMEWORK, + TFA1_FW_PAR_ID_SET_CURRENT_DELAY, + sizeof(tfa9896_vsfwdelay_table), + tfa9896_vsfwdelay_table); +} + +/* +* The int24 values for the fracdelay table +* For now applicable only for 8 and 48 kHz +*/ +static unsigned char tfa9896_cvfracdelay_table[] = { + 0, 0, 51, /* Index 0 - Current/Volt Fractional Delay for 8KHz */ + 0, 0, 0, /* Index 1 - Current/Volt Fractional Delay for 11KHz */ + 0, 0, 0, /* Index 2 - Current/Volt Fractional Delay for 12KHz */ + 0, 0, 38, /* Index 3 - Current/Volt Fractional Delay for 16KHz */ + 0, 0, 34, /* Index 4 - Current/Volt Fractional Delay for 22KHz */ + 0, 0, 33, /* Index 5 - Current/Volt Fractional Delay for 24KHz */ + 0, 0, 11, /* Index 6 - Current/Volt Fractional Delay for 32KHz */ + 0, 0, 2, /* Index 7 - Current/Volt Fractional Delay for 44KHz */ + 0, 0, 62 /* Index 8 - Current/Volt Fractional Delay for 48KHz */ +}; + +static enum Tfa98xx_Error +tfa9896_dsp_write_cvfracdelay_table(struct tfa_device *tfa) +{ + return tfa_dsp_cmd_id_write(tfa, MODULE_FRAMEWORK, + TFA1_FW_PAR_ID_SET_CURFRAC_DELAY, + sizeof(tfa9896_cvfracdelay_table), + tfa9896_cvfracdelay_table); + ; +} + +static enum Tfa98xx_Error tfa9896_tfa_dsp_write_tables(struct tfa_device *tfa, + int sample_rate) +{ + enum Tfa98xx_Error error; + + /* Not used for max1! */ + (void)sample_rate; + + error = tfa9896_dsp_write_vsfwdelay_table(tfa); + if (error == Tfa98xx_Error_Ok) { + error = tfa9896_dsp_write_cvfracdelay_table(tfa); + } + + return error; +} + +void tfa9896_ops(struct tfa_device_ops *ops) +{ + /* Set defaults for ops */ + set_ops_defaults(ops); + + ops->tfa_init = tfa9896_specific; + ops->dsp_write_tables = tfa9896_tfa_dsp_write_tables; + ops->faim_protect = tfa9896_faim_protect; +} + +/***********************************************************************************/ +/* TFA9897 */ +/***********************************************************************************/ +static enum Tfa98xx_Error tfa9897_specific(struct tfa_device *tfa) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + unsigned short check_value; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + /* all i2C registers must already set to default POR value */ + + /* $48:[3] - 1 ==> 0; iddqtestbst - default value changed. + * When Iddqtestbst is set to "0", the slewrate is reduced. + * This will lower the overshoot on IN-B to avoid NMOS damage of booster */ + error = reg_write(tfa, 0x48, 0x0300); /* POR value = 0x308 */ + + /* $49:[0] - 1 ==> 0; CLIP - default value changed. 0 means CLIPPER on */ + error = reg_read(tfa, 0x49, &check_value); + check_value &= ~0x1; + error = reg_write(tfa, 0x49, check_value); + + return error; +} + +/* +* the int24 values for the vsfw delay table +*/ +static unsigned char tfa9897_vsfwdelay_table[] = { + 0, 0, 2, /* Index 0 - Current/Volt Fractional Delay for 8KHz */ + 0, 0, 0, /* Index 1 - Current/Volt Fractional Delay for 11KHz */ + 0, 0, 0, /* Index 2 - Current/Volt Fractional Delay for 12KHz */ + 0, 0, 2, /* Index 3 - Current/Volt Fractional Delay for 16KHz */ + 0, 0, 2, /* Index 4 - Current/Volt Fractional Delay for 22KHz */ + 0, 0, 2, /* Index 5 - Current/Volt Fractional Delay for 24KHz */ + 0, 0, 2, /* Index 6 - Current/Volt Fractional Delay for 32KHz */ + 0, 0, 2, /* Index 7 - Current/Volt Fractional Delay for 44KHz */ + 0, 0, 3 /* Index 8 - Current/Volt Fractional Delay for 48KHz */ +}; + +/* +* TODO make this tfa98xx +* Note that the former products write this table via the patch +* so moving this to the tfa98xx API requires also updating all patches +*/ +static enum Tfa98xx_Error +tfa9897_dsp_write_vsfwdelay_table(struct tfa_device *tfa) +{ + return tfa_dsp_cmd_id_write(tfa, MODULE_FRAMEWORK, + TFA1_FW_PAR_ID_SET_CURRENT_DELAY, + sizeof(tfa9897_vsfwdelay_table), + tfa9897_vsfwdelay_table); + ; +} + +/* +* The int24 values for the fracdelay table +* For now applicable only for 8 and 48 kHz +*/ +static unsigned char tfa9897_cvfracdelay_table[] = { + 0, 0, 51, /* Index 0 - Current/Volt Fractional Delay for 8KHz */ + 0, 0, 0, /* Index 1 - Current/Volt Fractional Delay for 11KHz */ + 0, 0, 0, /* Index 2 - Current/Volt Fractional Delay for 12KHz */ + 0, 0, 38, /* Index 3 - Current/Volt Fractional Delay for 16KHz */ + 0, 0, 34, /* Index 4 - Current/Volt Fractional Delay for 22KHz */ + 0, 0, 33, /* Index 5 - Current/Volt Fractional Delay for 24KHz */ + 0, 0, 11, /* Index 6 - Current/Volt Fractional Delay for 32KHz */ + 0, 0, 2, /* Index 7 - Current/Volt Fractional Delay for 44KHz */ + 0, 0, 62 /* Index 8 - Current/Volt Fractional Delay for 48KHz */ +}; + +static enum Tfa98xx_Error +tfa9897_dsp_write_cvfracdelay_table(struct tfa_device *tfa) +{ + return tfa_dsp_cmd_id_write(tfa, MODULE_FRAMEWORK, + TFA1_FW_PAR_ID_SET_CURFRAC_DELAY, + sizeof(tfa9897_cvfracdelay_table), + tfa9897_cvfracdelay_table); + ; +} + +static enum Tfa98xx_Error tfa9897_tfa_dsp_write_tables(struct tfa_device *tfa, + int sample_rate) +{ + enum Tfa98xx_Error error; + + /* Not used for max1! */ + (void)sample_rate; + + error = tfa9897_dsp_write_vsfwdelay_table(tfa); + if (error == Tfa98xx_Error_Ok) { + error = tfa9897_dsp_write_cvfracdelay_table(tfa); + } + + return error; +} + +void tfa9897_ops(struct tfa_device_ops *ops) +{ + /* Set defaults for ops */ + set_ops_defaults(ops); + + ops->tfa_init = tfa9897_specific; + ops->dsp_write_tables = tfa9897_tfa_dsp_write_tables; +} + +/***********************************************************************************/ +/* TFA9895 */ +/***********************************************************************************/ +static enum Tfa98xx_Error tfa9895_specific(struct tfa_device *tfa) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + int result; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + /* all i2C registers are already set to default */ + + result = TFA_SET_BF(tfa, AMPE, 1); + if (result < 0) + return -result; + + /* some other registers must be set for optimal amplifier behaviour */ + reg_write(tfa, 0x05, 0x13AB); + reg_write(tfa, 0x06, 0x001F); + /* peak voltage protection is always on, but may be written */ + reg_write(tfa, 0x08, 0x3C4E); + /*TFA98XX_SYSCTRL_DCA=0*/ + reg_write(tfa, 0x09, 0x024D); + reg_write(tfa, 0x41, 0x0308); + error = reg_write(tfa, 0x49, 0x0E82); + + return error; +} + +void tfa9895_ops(struct tfa_device_ops *ops) +{ + /* Set defaults for ops */ + set_ops_defaults(ops); + + ops->tfa_init = tfa9895_specific; +} + +/***********************************************************************************/ +/* TFA9891 */ +/***********************************************************************************/ +static enum Tfa98xx_Error tfa9891_specific(struct tfa_device *tfa) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + /* ----- generated code start ----- */ + /* ----- version 18.0 ----- */ + reg_write(tfa, 0x09, 0x025d); //POR=0x024d + reg_write(tfa, 0x10, 0x0018); //POR=0x0024 + reg_write(tfa, 0x22, 0x0003); //POR=0x0023 + reg_write(tfa, 0x25, 0x0001); //POR=0x0000 + reg_write(tfa, 0x46, 0x0000); //POR=0x4000 + reg_write(tfa, 0x55, 0x3ffb); //POR=0x7fff + /* ----- generated code end ----- */ + + return error; +} + +void tfa9891_ops(struct tfa_device_ops *ops) +{ + /* Set defaults for ops */ + set_ops_defaults(ops); + + ops->tfa_init = tfa9891_specific; +} + +/***********************************************************************************/ +/* TFA9890 */ +/***********************************************************************************/ +static enum Tfa98xx_Error tfa9890_specific(struct tfa_device *tfa) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + unsigned short regRead = 0; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + /* all i2C registers are already set to default for N1C2 */ + + /* some PLL registers must be set optimal for amplifier behaviour */ + error = reg_write(tfa, 0x40, 0x5a6b); + if (error) + return error; + reg_read(tfa, 0x59, ®Read); + regRead |= 0x3; + reg_write(tfa, 0x59, regRead); + error = reg_write(tfa, 0x40, 0x0000); + error = reg_write(tfa, 0x47, 0x7BE1); + + return error; +} + +/* +* Disable clock gating +*/ +static enum Tfa98xx_Error tfa9890_clockgating(struct tfa_device *tfa, int on) +{ + enum Tfa98xx_Error error; + unsigned short value; + + /* for TFA9890 temporarily disable clock gating when dsp reset is used */ + error = reg_read(tfa, TFA98XX_CURRENTSENSE4, &value); + if (error) + return error; + + if (Tfa98xx_Error_Ok == error) { + if (on) /* clock gating on - clear the bit */ + value &= ~TFA98XX_CURRENTSENSE4_CTRL_CLKGATECFOFF; + else /* clock gating off - set the bit */ + value |= TFA98XX_CURRENTSENSE4_CTRL_CLKGATECFOFF; + + error = reg_write(tfa, TFA98XX_CURRENTSENSE4, value); + } + + return error; +} + +/* +* Tfa9890_DspReset will deal with clock gating control in order +* to reset the DSP for warm state restart +*/ +static enum Tfa98xx_Error tfa9890_dsp_reset(struct tfa_device *tfa, int state) +{ + enum Tfa98xx_Error error; + + /* for TFA9890 temporarily disable clock gating + when dsp reset is used */ + tfa9890_clockgating(tfa, 0); + + TFA_SET_BF(tfa, RST, (uint16_t)state); + + /* clock gating restore */ + error = tfa9890_clockgating(tfa, 1); + + return error; +} + +/* + * Tfa9890_DspSystemStable will compensate for the wrong behavior of CLKS + * to determine if the DSP subsystem is ready for patch and config loading. + * + * A MTP calibration register is checked for non-zero. + * + * Note: This only works after i2c reset as this will clear the MTP contents. + * When we are configured then the DSP communication will synchronize access. + * + */ +static enum Tfa98xx_Error tfa9890_dsp_system_stable(struct tfa_device *tfa, + int *ready) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + unsigned short status, mtp0; + int result, tries; + + /* check the contents of the STATUS register */ + result = TFA_READ_REG(tfa, AREFS); + if (result < 0) { + error = -result; + goto errorExit; + } + status = (unsigned short)result; + + /* if AMPS is set then we were already configured and running + * no need to check further + */ + *ready = (TFA_GET_BF_VALUE(tfa, AMPS, status) == 1); + if (*ready) /* if ready go back */ + return error; /* will be Tfa98xx_Error_Ok */ + + /* check AREFS and CLKS: not ready if either is clear */ + *ready = !((TFA_GET_BF_VALUE(tfa, AREFS, status) == 0) || + (TFA_GET_BF_VALUE(tfa, CLKS, status) == 0)); + if (!*ready) /* if not ready go back */ + return error; /* will be Tfa98xx_Error_Ok */ + + /* check MTPB + * mtpbusy will be active when the subsys copies MTP to I2C + * 2 times retry avoids catching this short mtpbusy active period + */ + for (tries = 2; tries > 0; tries--) { + result = TFA_GET_BF(tfa, MTPB); /*TODO_MTPB*/ + if (result < 0) { + error = -result; + goto errorExit; + } + status = (unsigned short)result; + + /* check the contents of the STATUS register */ + *ready = (result == 0); + if (*ready) /* if ready go on */ + break; + } + if (tries == 0) /* ready will be 0 if retries exausted */ + return Tfa98xx_Error_Ok; + + /* check the contents of MTP register for non-zero, + * this indicates that the subsys is ready */ + + error = reg_read(tfa, 0x84, &mtp0); + if (error) + goto errorExit; + + *ready = (mtp0 != 0); /* The MTP register written? */ + + return error; + +errorExit: + *ready = 0; + return error; +} + +void tfa9890_ops(struct tfa_device_ops *ops) +{ + /* Set defaults for ops */ + set_ops_defaults(ops); + + ops->tfa_init = tfa9890_specific; + ops->dsp_reset = tfa9890_dsp_reset; + ops->dsp_system_stable = tfa9890_dsp_system_stable; +} + +/***********************************************************************************/ +/* TFA9894 */ +/***********************************************************************************/ +static int tfa9894_set_swprofile(struct tfa_device *tfa, + unsigned short new_value) +{ + int active_value = tfa_dev_get_swprof(tfa); + + /* Set the new value in the struct */ + tfa->profile = new_value - 1; + + /* Set the new value in the hw register */ + tfa_set_bf_volatile(tfa, TFA9894_BF_SWPROFIL, new_value); + + return active_value; +} + +static int tfa9894_get_swprofile(struct tfa_device *tfa) +{ + return tfa_get_bf(tfa, TFA9894_BF_SWPROFIL) - 1; +} + +static int tfa9894_set_swvstep(struct tfa_device *tfa, unsigned short new_value) +{ + /* Set the new value in the struct */ + tfa->vstep = new_value - 1; + + /* Set the new value in the hw register */ + tfa_set_bf_volatile(tfa, TFA9894_BF_SWVSTEP, new_value); + + return new_value; +} + +static int tfa9894_get_swvstep(struct tfa_device *tfa) +{ + return tfa_get_bf(tfa, TFA9894_BF_SWVSTEP) - 1; +} + +static int tfa9894_get_mtpb(struct tfa_device *tfa) +{ + int value = 0; + + /* Set the new value in the hw register */ + value = tfa_get_bf(tfa, TFA9894_BF_MTPB); + + return value; +} + +/** Set internal oscillator into power down mode for TFA9894. +* +* This function is a worker for tfa98xx_set_osc_powerdown(). +* +* @param[in] tfa device description structure +* @param[in] state new state 0 - oscillator is on, 1 oscillator is off. +* +* @return Tfa98xx_Error_Ok when successfull, error otherwise. +*/ +static enum Tfa98xx_Error tfa9894_set_osc_powerdown(struct tfa_device *tfa, + int state) +{ + if (state == 1 || state == 0) { + return -tfa_set_bf(tfa, TFA9894_BF_MANAOOSC, (uint16_t)state); + } + + return Tfa98xx_Error_Bad_Parameter; +} + +static enum Tfa98xx_Error tfa9894_faim_protect(struct tfa_device *tfa, + int status) +{ + enum Tfa98xx_Error ret = Tfa98xx_Error_Ok; + /* 0b = FAIM protection enabled 1b = FAIM protection disabled*/ + ret = tfa_set_bf_volatile(tfa, TFA9894_BF_OPENMTP, (uint16_t)(status)); + return ret; +} + +static enum Tfa98xx_Error tfa9894_specific(struct tfa_device *tfa) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + unsigned short value, xor; + + if (tfa->in_use == 0) + return Tfa98xx_Error_NotOpen; + + /* Unlock keys to write settings */ + error = reg_write(tfa, 0x0F, 0x5A6B); + error = reg_read(tfa, 0xFB, &value); + xor = value ^ 0x005A; + error = reg_write(tfa, 0xA0, xor); + + /* The optimal settings */ + if (tfa->rev == 0x0a94) { + /* V36 */ + /* ----- generated code start ----- */ + reg_write(tfa, 0x00, 0xa245); //POR=0x8245 + reg_write(tfa, 0x02, 0x51e8); //POR=0x55c8 + reg_write(tfa, 0x52, 0xbe17); //POR=0xb617 + reg_write(tfa, 0x57, 0x0344); //POR=0x0366 + reg_write(tfa, 0x61, 0x0033); //POR=0x0073 + reg_write(tfa, 0x71, 0x00cf); //POR=0x018d + reg_write(tfa, 0x72, 0x34a9); //POR=0x44e8 + reg_write(tfa, 0x73, 0x3808); //POR=0x3806 + reg_write(tfa, 0x76, 0x0067); //POR=0x0065 + reg_write(tfa, 0x80, 0x0000); //POR=0x0003 + reg_write(tfa, 0x81, 0x5715); //POR=0x561a + reg_write(tfa, 0x82, 0x0104); //POR=0x0044 + /* ----- generated code end ----- */ + } else if (tfa->rev == 0x1a94) { + /* V14 */ + /* ----- generated code start ----- */ + reg_write(tfa, 0x00, 0xa245); //POR=0x8245 + reg_write(tfa, 0x01, 0x15da); //POR=0x11ca + reg_write(tfa, 0x02, 0x5288); //POR=0x55c8 + reg_write(tfa, 0x52, 0xbe17); //POR=0xb617 + reg_write(tfa, 0x53, 0x0dbe); //POR=0x0d9e + reg_write(tfa, 0x56, 0x05c3); //POR=0x07c3 + reg_write(tfa, 0x57, 0x0344); //POR=0x0366 + reg_write(tfa, 0x61, 0x0032); //POR=0x0073 + reg_write(tfa, 0x71, 0x00cf); //POR=0x018d + reg_write(tfa, 0x72, 0x34a9); //POR=0x44e8 + reg_write(tfa, 0x73, 0x38c8); //POR=0x3806 + reg_write(tfa, 0x76, 0x0067); //POR=0x0065 + reg_write(tfa, 0x80, 0x0000); //POR=0x0003 + reg_write(tfa, 0x81, 0x5799); //POR=0x561a + reg_write(tfa, 0x82, 0x0104); //POR=0x0044 + /* ----- generated code end ----- */ + } + + return error; +} + +static enum Tfa98xx_Error tfa9894_set_mute(struct tfa_device *tfa, int mute) +{ + tfa_set_bf(tfa, TFA9894_BF_CFSM, (const uint16_t)mute); + + return Tfa98xx_Error_Ok; +} + +static enum Tfa98xx_Error tfa9894_dsp_system_stable(struct tfa_device *tfa, + int *ready) +{ + enum Tfa98xx_Error error = Tfa98xx_Error_Ok; + + /* check CLKS: ready if set */ + *ready = tfa_get_bf(tfa, TFA9894_BF_CLKS) == 1; + + return error; +} + +void tfa9894_ops(struct tfa_device_ops *ops) +{ + /* Set defaults for ops */ + set_ops_defaults(ops); + + ops->tfa_init = tfa9894_specific; + ops->dsp_system_stable = tfa9894_dsp_system_stable; + ops->set_mute = tfa9894_set_mute; + ops->faim_protect = tfa9894_faim_protect; + ops->get_mtpb = tfa9894_get_mtpb; + ops->set_swprof = tfa9894_set_swprofile; + ops->get_swprof = tfa9894_get_swprofile; + ops->set_swvstep = tfa9894_set_swvstep; + ops->get_swvstep = tfa9894_get_swvstep; + //ops->auto_copy_mtp_to_iic = tfa9894_auto_copy_mtp_to_iic; + ops->set_osc_powerdown = tfa9894_set_osc_powerdown; +} diff --git a/techpack/audio/dsp/Kbuild b/techpack/audio/dsp/Kbuild index 7620628cbcf4..aaddbd54bb80 100644 --- a/techpack/audio/dsp/Kbuild +++ b/techpack/audio/dsp/Kbuild @@ -107,6 +107,24 @@ ifdef CONFIG_SND_SOC_MSM_QDSP6V2_INTF Q6_OBJS += msm_audio_ion.o Q6_OBJS += avtimer.o Q6_OBJS += q6_init.o + Q6_OBJS += apr_elliptic.o + Q6_OBJS += elliptic/elliptic.o + Q6_OBJS += elliptic/elliptic_sysfs.o + Q6_OBJS += elliptic/elliptic_mixer_controls.o + Q6_OBJS += elliptic/io_modules/msm/elliptic_data_msm_io.o + Q6_OBJS += elliptic/io_modules/userspace/elliptic_data_userspace_io.o + Q6_OBJS += elliptic/io_modules/userspace/elliptic_data_userspace_ctrl.o +# for mius start +ifdef CONFIG_US_PROXIMITY + Q6_OBJS += apr_mius.o + Q6_OBJS += mius/mius.o + Q6_OBJS += mius/mius_sysfs.o + Q6_OBJS += mius/mius_mixer_controls.o + Q6_OBJS += mius/io_modules/msm/mius_data_msm_io.o + Q6_OBJS += mius/io_modules/userspace/mius_data_userspace_io.o + Q6_OBJS += mius/io_modules/userspace/mius_data_userspace_ctrl.o +endif +# for mius end endif ifdef CONFIG_XT_LOGGING @@ -141,6 +159,14 @@ ifdef CONFIG_MSM_MDF Q6_OBJS += msm_mdf.o endif +ifdef CONFIG_MSM_CSPL + Q6_OBJS += msm-cirrus-playback.o +endif + +ifdef CONFIG_MSM_CSPL_V2 + Q6_OBJS += msm-cirrus-playback-v2.o +endif + ifdef CONFIG_VOICE_MHI Q6_OBJS += voice_mhi.o endif diff --git a/techpack/audio/dsp/Kconfig b/techpack/audio/dsp/Kconfig index 9d6601d1e644..c4c239f6454e 100644 --- a/techpack/audio/dsp/Kconfig +++ b/techpack/audio/dsp/Kconfig @@ -1,3 +1,13 @@ menu "Qualcomm DSP" +config MSM_CSPL + tristate "Cirrus Playback driver" + help + Say Y here if you want to enable the Cirrus Playback driver. + +config MSM_CSPL_V2 + tristate "Cirrus Playback driver" + help + Say Y here if you want to enable the Cirrus Playback driver. + endmenu diff --git a/techpack/audio/dsp/apr_elliptic.c b/techpack/audio/dsp/apr_elliptic.c new file mode 100644 index 000000000000..668e8368ca60 --- /dev/null +++ b/techpack/audio/dsp/apr_elliptic.c @@ -0,0 +1,435 @@ +/** + * Elliptic Labs + */ + +#include +#include +#include +#include +#include +#include +#include "../asoc/msm-pcm-routing-v2.h" +#include +#include +#include +#include +#include +#include + +#ifndef min +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +enum { + HALL_SLIDER_UP = 4, + HALL_SLIDER_DOWN = 5, + HALL_SLIDING = 6, +}; + +enum driver_sensor_type { + DRIVER_SENSOR_HALL = 35, +}; + +struct driver_sensor_event { + enum driver_sensor_type type; + union { + int32_t event; + int32_t reserved[2]; + }; +}; + +static int afe_set_parameter(int port, int param_id, int module_id, + struct afe_ultrasound_set_params_t *prot_config, + uint32_t length) +{ + struct afe_port_cmd_set_param_v2 *set_param_v2 = NULL; + uint32_t set_param_v2_size = sizeof(struct afe_port_cmd_set_param_v2); + struct afe_port_cmd_set_param_v3 *set_param_v3 = NULL; + uint32_t set_param_v3_size = sizeof(struct afe_port_cmd_set_param_v3); + struct param_hdr_v3 param_hdr = { 0 }; + u16 port_id = 0; + int index = 0; + u8 *packed_param_data = NULL; + int packed_data_size = sizeof(union param_hdrs) + length; + int ret = 0; + + pr_debug("[ELUS]: inside %s\n", __func__); + + port_id = q6audio_get_port_id(port); + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Not a valid port id = 0x%x ret %d\n", __func__, + port_id, ret); + return -EINVAL; + } + index = q6audio_get_port_index(port); + + param_hdr.module_id = module_id; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = param_id; + param_hdr.param_size = length; + pr_debug("[ELUS]: param_size %d\n", length); + + packed_param_data = kzalloc(packed_data_size, GFP_KERNEL); + if (packed_param_data == NULL) + return -ENOMEM; + + ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, + (u8 *)prot_config, &packed_data_size); + if (ret) { + pr_err("%s: Failed to pack param header and data, error %d\n", + __func__, ret); + goto fail_cmd; + } + + if (q6common_is_instance_id_supported()) { + set_param_v3_size += packed_data_size; + set_param_v3 = kzalloc(set_param_v3_size, GFP_KERNEL); + if (set_param_v3 == NULL) { + ret = -ENOMEM; + goto fail_cmd; + } + + set_param_v3->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + set_param_v3->apr_hdr.pkt_size = + sizeof(struct afe_port_cmd_set_param_v3) + + packed_data_size; + set_param_v3->apr_hdr.src_port = 0; + set_param_v3->apr_hdr.dest_port = 0; + set_param_v3->apr_hdr.token = index; + set_param_v3->apr_hdr.opcode = AFE_PORT_CMD_SET_PARAM_V3; + set_param_v3->port_id = port_id; + set_param_v3->payload_size = packed_data_size; + memcpy(&set_param_v3->param_data, packed_param_data, + packed_data_size); + + atomic_set(elus_afe.ptr_state, 1); + ret = apr_send_pkt(*elus_afe.ptr_apr, (uint32_t *)set_param_v3); + } else { + set_param_v2_size += packed_data_size; + set_param_v2 = kzalloc(set_param_v2_size, GFP_KERNEL); + if (set_param_v2 == NULL) { + ret = -ENOMEM; + goto fail_cmd; + } + + set_param_v2->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + set_param_v2->apr_hdr.pkt_size = + sizeof(struct afe_port_cmd_set_param_v2) + + packed_data_size; + set_param_v2->apr_hdr.src_port = 0; + set_param_v2->apr_hdr.dest_port = 0; + set_param_v2->apr_hdr.token = index; + set_param_v2->apr_hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + set_param_v2->port_id = port_id; + set_param_v2->payload_size = packed_data_size; + memcpy(&set_param_v2->param_data, packed_param_data, + packed_data_size); + + atomic_set(elus_afe.ptr_state, 1); + ret = apr_send_pkt(*elus_afe.ptr_apr, (uint32_t *)set_param_v2); + } + if (ret < 0) { + pr_err("%s: Setting param for port %d param[0x%x]failed\n", + __func__, port, param_id); + goto fail_cmd; + } + ret = wait_event_timeout(elus_afe.ptr_wait[index], + (atomic_read(elus_afe.ptr_state) == 0), + msecs_to_jiffies(elus_afe.timeout_ms)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(elus_afe.ptr_status) != 0) { + pr_err("%s: set param cmd failed\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + ret = 0; +fail_cmd: + pr_debug("%s param_id %x status %d\n", __func__, param_id, ret); + kfree(set_param_v2); + kfree(set_param_v3); + kfree(packed_param_data); + return ret; +} + +int32_t ultrasound_apr_set_parameter(int32_t port_id, uint32_t param_id, + u8 *user_params, int32_t length) +{ + int32_t ret = 0; + uint32_t module_id; + + if (port_id == ELLIPTIC_PORT_ID) + module_id = ELLIPTIC_ULTRASOUND_MODULE_TX; + else + module_id = ELLIPTIC_ULTRASOUND_MODULE_RX; + + ret = afe_set_parameter( + port_id, param_id, module_id, + (struct afe_ultrasound_set_params_t *)user_params, length); + + return ret; +} + +static int32_t process_version_msg(uint32_t *payload, uint32_t payload_size) +{ + struct elliptic_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[ELUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= ELLIPTIC_VERSION_INFO_SIZE) { + pr_debug("[ELUS]: elliptic_version copied to local AP cache"); + data_block = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_VERSION_INFO); + copy_size = min_t(size_t, data_block->size, + (size_t)ELLIPTIC_VERSION_INFO_SIZE); + + memcpy((u8 *)data_block->buffer, &payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_branch_msg(uint32_t *payload, uint32_t payload_size) +{ + struct elliptic_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[ELUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= ELLIPTIC_BRANCH_INFO_SIZE) { + pr_debug("[ELUS]: elliptic_branch copied to local AP cache"); + data_block = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_BRANCH_INFO); + copy_size = min_t(size_t, data_block->size, + (size_t)ELLIPTIC_BRANCH_INFO_MAX_SIZE); + + memcpy((u8 *)data_block->buffer, &payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_tag_msg(uint32_t *payload, uint32_t payload_size) +{ + struct elliptic_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[ELUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= ELLIPTIC_TAG_INFO_SIZE) { + pr_debug("[ELUS]: elliptic_tag copied to local AP cache"); + data_block = elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_TAG_INFO); + copy_size = min_t(size_t, data_block->size, + (size_t)ELLIPTIC_TAG_INFO_SIZE); + + memcpy((u8 *)data_block->buffer, &payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_calibration_msg(uint32_t *payload, uint32_t payload_size) +{ + struct elliptic_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[ELUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= ELLIPTIC_CALIBRATION_DATA_SIZE) { + pr_debug("[ELUS]: calibration_data copied to local AP cache"); + + data_block = elliptic_get_shared_obj( + ELLIPTIC_OBJ_ID_CALIBRATION_DATA); + copy_size = min_t(size_t, data_block->size, + (size_t)ELLIPTIC_CALIBRATION_DATA_SIZE); + + memcpy((u8 *)data_block->buffer, &payload[3], copy_size); + elliptic_set_calibration_data((u8 *)&payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_calibration_v2_msg(uint32_t *payload, + uint32_t payload_size) +{ + struct elliptic_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[ELUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= ELLIPTIC_CALIBRATION_V2_DATA_SIZE) { + pr_debug("[ELUS]: calibration_data copied to local AP cache"); + + data_block = elliptic_get_shared_obj( + ELLIPTIC_OBJ_ID_CALIBRATION_V2_DATA); + copy_size = min_t(size_t, data_block->size, + (size_t)ELLIPTIC_CALIBRATION_V2_DATA_SIZE); + + memcpy((u8 *)data_block->buffer, &payload[3], copy_size); + elliptic_set_calibration_data((u8 *)&payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_ml_msg(uint32_t *payload, uint32_t payload_size) +{ + struct elliptic_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[ELUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= ELLIPTIC_ML_DATA_SIZE) { + pr_debug("[ELUS]: ml_data copied to local AP cache"); + + data_block = elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_ML_DATA); + copy_size = min_t(size_t, data_block->size, + (size_t)ELLIPTIC_ML_DATA_SIZE); + + memcpy((u8 *)data_block->buffer, &payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_diagnostics_msg(uint32_t *payload, uint32_t payload_size) +{ + struct elliptic_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[ELUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= ELLIPTIC_DIAGNOSTICS_DATA_SIZE) { + pr_debug("[ELUS]: diagnostics_data copied to local AP cache"); + + data_block = elliptic_get_shared_obj( + ELLIPTIC_OBJ_ID_DIAGNOSTICS_DATA); + copy_size = min_t(size_t, data_block->size, + (size_t)ELLIPTIC_DIAGNOSTICS_DATA_SIZE); + + memcpy((u8 *)data_block->buffer, &payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_sensorhub_msg(uint32_t *payload, uint32_t payload_size) +{ + int32_t ret = 0; + + pr_err("[ELUS]: %s, paramId:%u, size:%d\n", __func__, payload[1], + payload_size); + + return ret; +} + +int32_t elliptic_process_apr_payload(uint32_t *payload) +{ + uint32_t payload_size = 0; + int32_t ret = -1; + + if (payload[0] == ELLIPTIC_ULTRASOUND_MODULE_TX) { + /* payload format + * payload[0] = Module ID + * payload[1] = Param ID + * payload[2] = LSB - payload size + * MSB - reserved(TBD) + * payload[3] = US data payload starts from here + */ + payload_size = payload[2] & 0xFFFF; + + switch (payload[1]) { + case ELLIPTIC_ULTRASOUND_PARAM_ID_ENGINE_VERSION: + ret = process_version_msg(payload, payload_size); + break; + case ELLIPTIC_ULTRASOUND_PARAM_ID_BUILD_BRANCH: + ret = process_branch_msg(payload, payload_size); + break; + case ELLIPTIC_ULTRASOUND_PARAM_ID_TAG: + ret = process_tag_msg(payload, payload_size); + break; + case ELLIPTIC_ULTRASOUND_PARAM_ID_CALIBRATION_DATA: + ret = process_calibration_msg(payload, payload_size); + break; + case ELLIPTIC_ULTRASOUND_PARAM_ID_CALIBRATION_V2_DATA: + ret = process_calibration_v2_msg(payload, payload_size); + break; + case ELLIPTIC_ULTRASOUND_PARAM_ID_ML_DATA: + ret = process_ml_msg(payload, payload_size); + break; + case ELLIPTIC_ULTRASOUND_PARAM_ID_DIAGNOSTICS_DATA: + ret = process_diagnostics_msg(payload, payload_size); + break; + case ELLIPTIC_ULTRASOUND_PARAM_ID_SENSORHUB: + ret = process_sensorhub_msg(payload, payload_size); + break; + case ELLIPTIC_ULTRASOUND_PARAM_ID_ENGINE_DATA: + ret = elliptic_data_push( + ELLIPTIC_ALL_DEVICES, (const char *)&payload[3], + (size_t)payload_size, + ELLIPTIC_DATA_PUSH_FROM_KERNEL); + + if (ret != 0) { + pr_err("[ELUS] : failed to push apr payload to elliptic device"); + return ret; + } + ret = payload_size; + break; + default: { + pr_err("[ELUS] : elliptic_process_apr_payload, Illegal paramId:%u", + payload[1]); + } break; + } + } else { + pr_debug("[ELUS]: Invalid Ultrasound Module ID %d\n", + payload[0]); + } + return ret; +} + +int elliptic_set_hall_state(int state) +{ + struct driver_sensor_event dse; + int ret = -1; + + dse.type = DRIVER_SENSOR_HALL; + + switch (state) { + case 0: + dse.event = HALL_SLIDER_UP; + break; + case 1: + dse.event = HALL_SLIDER_DOWN; + break; + case 2: + dse.event = HALL_SLIDING; + break; + default: + pr_err("%s Invalid HALL state:%d\n", __func__, state); + return ret; + } + + ret = afe_set_parameter(ELLIPTIC_PORT_ID, 2, + ELLIPTIC_ULTRASOUND_MODULE_TX, + (struct afe_ultrasound_set_params_t *)&dse, + sizeof(dse)); + return ret; +} +EXPORT_SYMBOL(elliptic_set_hall_state); diff --git a/techpack/audio/dsp/apr_mius.c b/techpack/audio/dsp/apr_mius.c new file mode 100644 index 000000000000..6239bf751160 --- /dev/null +++ b/techpack/audio/dsp/apr_mius.c @@ -0,0 +1,464 @@ +/** + * Mi + */ + +#include +#include +#include +#include +#include +#include +#include "../asoc/msm-pcm-routing-v2.h" +#include +#include +#include +#include +#include +#include + +#ifndef min +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +enum { + HALL_SLIDER_UP = 4, + HALL_SLIDER_DOWN = 5, + HALL_SLIDING = 6, +}; + +enum driver_sensor_type { + DRIVER_SENSOR_HALL = 35, +}; + +struct driver_sensor_event { + enum driver_sensor_type type; + union { + int32_t event; + int32_t reserved[2]; + }; +}; + +static int afe_set_parameter(int port, int param_id, int module_id, + struct afe_mi_ultrasound_set_params_t *prot_config, + uint32_t length) +{ + struct afe_port_cmd_set_param_v2 *set_param_v2 = NULL; + uint32_t set_param_v2_size = sizeof(struct afe_port_cmd_set_param_v2); + struct afe_port_cmd_set_param_v3 *set_param_v3 = NULL; + uint32_t set_param_v3_size = sizeof(struct afe_port_cmd_set_param_v3); + struct param_hdr_v3 param_hdr = { 0 }; + u16 port_id = 0; + int index = 0; + u8 *packed_param_data = NULL; + int packed_data_size = sizeof(union param_hdrs) + length; + int ret = 0; + + pr_debug("[MIUS]: inside %s\n", __func__); + + port_id = q6audio_get_port_id(port); + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Not a valid port id = 0x%x ret %d\n", __func__, + port_id, ret); + return -EINVAL; + } + index = q6audio_get_port_index(port); + + param_hdr.module_id = module_id; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = param_id; + param_hdr.param_size = length; + pr_debug("[MIUS]: param_size %d\n", length); + + packed_param_data = kzalloc(packed_data_size, GFP_KERNEL); + if (packed_param_data == NULL) + return -ENOMEM; + + ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, + (u8 *)prot_config, &packed_data_size); + if (ret) { + pr_err("%s: Failed to pack param header and data, error %d\n", + __func__, ret); + goto fail_cmd; + } + + if (q6common_is_instance_id_supported()) { + set_param_v3_size += packed_data_size; + set_param_v3 = kzalloc(set_param_v3_size, GFP_KERNEL); + if (set_param_v3 == NULL) { + ret = -ENOMEM; + goto fail_cmd; + } + + set_param_v3->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + set_param_v3->apr_hdr.pkt_size = + sizeof(struct afe_port_cmd_set_param_v3) + + packed_data_size; + set_param_v3->apr_hdr.src_port = 0; + set_param_v3->apr_hdr.dest_port = 0; + set_param_v3->apr_hdr.token = index; + set_param_v3->apr_hdr.opcode = AFE_PORT_CMD_SET_PARAM_V3; + set_param_v3->port_id = port_id; + set_param_v3->payload_size = packed_data_size; + memcpy(&set_param_v3->param_data, packed_param_data, + packed_data_size); + + atomic_set(mius_afe.ptr_state, 1); + ret = apr_send_pkt(*mius_afe.ptr_apr, (uint32_t *)set_param_v3); + } else { + set_param_v2_size += packed_data_size; + set_param_v2 = kzalloc(set_param_v2_size, GFP_KERNEL); + if (set_param_v2 == NULL) { + ret = -ENOMEM; + goto fail_cmd; + } + + set_param_v2->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + set_param_v2->apr_hdr.pkt_size = + sizeof(struct afe_port_cmd_set_param_v2) + + packed_data_size; + set_param_v2->apr_hdr.src_port = 0; + set_param_v2->apr_hdr.dest_port = 0; + set_param_v2->apr_hdr.token = index; + set_param_v2->apr_hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + set_param_v2->port_id = port_id; + set_param_v2->payload_size = packed_data_size; + memcpy(&set_param_v2->param_data, packed_param_data, + packed_data_size); + + atomic_set(mius_afe.ptr_state, 1); + ret = apr_send_pkt(*mius_afe.ptr_apr, (uint32_t *)set_param_v2); + } + if (ret < 0) { + pr_err("%s: Setting param for port %d param[0x%x]failed\n", + __func__, port, param_id); + goto fail_cmd; + } + ret = wait_event_timeout(mius_afe.ptr_wait[index], + (atomic_read(mius_afe.ptr_state) == 0), + msecs_to_jiffies(mius_afe.timeout_ms * 10)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(mius_afe.ptr_status) != 0) { + pr_err("%s: set param cmd failed\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + ret = 0; +fail_cmd: + pr_debug("%s param_id %x status %d\n", __func__, param_id, ret); + kfree(set_param_v2); + kfree(set_param_v3); + kfree(packed_param_data); + return ret; +} + +int32_t mi_ultrasound_apr_set_parameter(int32_t port_id, uint32_t param_id, + u8 *user_params, int32_t length) +{ + int32_t ret = 0; + uint32_t module_id; + + if (port_id == MIUS_PORT_ID) + module_id = MIUS_ULTRASOUND_MODULE_TX; + else + module_id = MIUS_ULTRASOUND_MODULE_RX; + + ret = afe_set_parameter( + port_id, param_id, module_id, + (struct afe_mi_ultrasound_set_params_t *)user_params, length); + + return ret; +} + +#if 0 +static int32_t process_version_msg(uint32_t *payload, uint32_t payload_size) +{ + struct mius_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[MIUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= MIUS_VERSION_INFO_SIZE) { + pr_debug("[MIUS]: mius_version copied to local AP cache"); + data_block = + mius_get_shared_obj( + MIUS_OBJ_ID_VERSION_INFO); + copy_size = min_t(size_t, data_block->size, + (size_t)MIUS_VERSION_INFO_SIZE); + + memcpy((u8 *)data_block->buffer, + &payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_branch_msg(uint32_t *payload, uint32_t payload_size) +{ + struct mius_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[MIUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= MIUS_BRANCH_INFO_SIZE) { + pr_debug("[MIUS]: mius_branch copied to local AP cache"); + data_block = + mius_get_shared_obj( + MIUS_OBJ_ID_BRANCH_INFO); + copy_size = min_t(size_t, data_block->size, + (size_t)MIUS_BRANCH_INFO_MAX_SIZE); + + memcpy((u8 *)data_block->buffer, + &payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_tag_msg(uint32_t *payload, uint32_t payload_size) +{ + struct mius_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[MIUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= MIUS_TAG_INFO_SIZE) { + pr_debug("[MIUS]: mius_tag copied to local AP cache"); + data_block = + mius_get_shared_obj( + MIUS_OBJ_ID_TAG_INFO); + copy_size = min_t(size_t, data_block->size, + (size_t)MIUS_TAG_INFO_SIZE); + + memcpy((u8 *)data_block->buffer, + &payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_calibration_msg(uint32_t *payload, uint32_t payload_size) +{ + struct mius_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[MIUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= MIUS_CALIBRATION_DATA_SIZE) { + pr_debug("[MIUS]: calibration_data copied to local AP cache"); + + data_block = mius_get_shared_obj( + MIUS_OBJ_ID_CALIBRATION_DATA); + copy_size = min_t(size_t, data_block->size, + (size_t)MIUS_CALIBRATION_DATA_SIZE); + + memcpy((u8 *)data_block->buffer, + &payload[3], copy_size); + mius_set_calibration_data((u8 *)&payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_calibration_v2_msg(uint32_t *payload, uint32_t payload_size) +{ + struct mius_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[MIUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= MIUS_CALIBRATION_V2_DATA_SIZE) { + pr_debug("[MIUS]: calibration_data copied to local AP cache"); + + data_block = mius_get_shared_obj( + MIUS_OBJ_ID_CALIBRATION_V2_DATA); + copy_size = min_t(size_t, data_block->size, + (size_t)MIUS_CALIBRATION_V2_DATA_SIZE); + + memcpy((u8 *)data_block->buffer, + &payload[3], copy_size); + mius_set_calibration_data((u8 *)&payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_ml_msg(uint32_t *payload, uint32_t payload_size) +{ + struct mius_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[MIUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= MIUS_ML_DATA_SIZE) { + pr_debug("[MIUS]: ml_data copied to local AP cache"); + + data_block = mius_get_shared_obj( + MIUS_OBJ_ID_ML_DATA); + copy_size = min_t(size_t, data_block->size, + (size_t)MIUS_ML_DATA_SIZE); + + memcpy((u8 *)data_block->buffer, + &payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_diagnostics_msg(uint32_t *payload, uint32_t payload_size) +{ + struct mius_shared_data_block *data_block = NULL; + size_t copy_size = 0; + int32_t ret = -1; + + pr_err("[MIUS]: %s() size:%d\n", __func__, payload_size); + + if (payload_size >= MIUS_DIAGNOSTICS_DATA_SIZE) { + pr_debug("[MIUS]: diagnostics_data copied to local AP cache"); + + data_block = mius_get_shared_obj( + MIUS_OBJ_ID_DIAGNOSTICS_DATA); + copy_size = min_t(size_t, data_block->size, + (size_t)MIUS_DIAGNOSTICS_DATA_SIZE); + + memcpy((u8 *)data_block->buffer, + &payload[3], copy_size); + ret = (int32_t)copy_size; + } + return ret; +} + +static int32_t process_sensorhub_msg(uint32_t *payload, uint32_t payload_size) +{ + int32_t ret = 0; + + pr_err("[MIUS]: %s, paramId:%u, size:%d\n", + __func__, payload[1], payload_size); + + return ret; +} + +#endif + +extern int us_afe_callback(int data); +static int ups_event = 0; + +int32_t mius_process_apr_payload(uint32_t *payload) +{ + uint32_t payload_size = 0; + int32_t ret = -1; + + //if (payload[0] == MIUS_ULTRASOUND_MODULE_TX) { + if (true) { + /* payload format + * payload[0] = Module ID + * payload[1] = Param ID + * payload[2] = LSB - payload size + * MSB - reserved(TBD) + * payload[3] = US data payload starts from here + */ + payload_size = payload[2] & 0xFFFF; +#if 0 + switch (payload[1]) { + case MIUS_ULTRASOUND_PARAM_ID_ENGINE_VERSION: + ret = process_version_msg(payload, payload_size); + break; + case MIUS_ULTRASOUND_PARAM_ID_BUILD_BRANCH: + ret = process_branch_msg(payload, payload_size); + break; + case MIUS_ULTRASOUND_PARAM_ID_TAG: + ret = process_tag_msg(payload, payload_size); + break; + case MIUS_ULTRASOUND_PARAM_ID_CALIBRATION_DATA: + ret = process_calibration_msg(payload, payload_size); + break; + case MIUS_ULTRASOUND_PARAM_ID_CALIBRATION_V2_DATA: + ret = process_calibration_v2_msg(payload, payload_size); + break; + case MIUS_ULTRASOUND_PARAM_ID_ML_DATA: + ret = process_ml_msg(payload, payload_size); + break; + case MIUS_ULTRASOUND_PARAM_ID_DIAGNOSTICS_DATA: + ret = process_diagnostics_msg(payload, payload_size); + break; + case MIUS_ULTRASOUND_PARAM_ID_SENSORHUB: + ret = process_sensorhub_msg(payload, payload_size); + break; + case MIUS_ULTRASOUND_PARAM_ID_ENGINE_DATA: +#endif + printk(KERN_DEBUG "[MIUS] mi us payload[3] = %d", + (int)payload[3]); + if (payload[3] == 0 || payload[3] == 1) { + ups_event = payload[3]; + ret = (int32_t)us_afe_callback( + (const uint32_t)payload[3]); + } else { + ups_event = ups_event ^ 1; + printk(KERN_DEBUG "[MIUS] >> change ups to %d", + ups_event); + ret = (int32_t)us_afe_callback((uint32_t)ups_event); + } + + if (ret != 0) { + pr_err("[MIUS] : failed to push apr payload to mius device"); + return ret; + } + ret = payload_size; +#if 0 + break; + default: + { + pr_err("[MIUS] : mius_process_apr_payload, Illegal paramId:%u", payload[1]); + } + break; + } +#endif + } else { + pr_debug("[MIUS]: Invalid Ultrasound Module ID %d\n", + payload[0]); + } + return ret; +} + +int mius_set_hall_state(int state) +{ + struct driver_sensor_event dse; + int ret = -1; + + dse.type = DRIVER_SENSOR_HALL; + + switch (state) { + case 0: + dse.event = HALL_SLIDER_UP; + break; + case 1: + dse.event = HALL_SLIDER_DOWN; + break; + case 2: + dse.event = HALL_SLIDING; + break; + default: + pr_err("%s Invalid HALL state:%d\n", __func__, state); + return ret; + } + + ret = afe_set_parameter(MIUS_PORT_ID, 2, MIUS_ULTRASOUND_MODULE_TX, + (struct afe_mi_ultrasound_set_params_t *)&dse, + sizeof(dse)); + return ret; +} +EXPORT_SYMBOL(mius_set_hall_state); diff --git a/techpack/audio/dsp/elliptic/Makefile b/techpack/audio/dsp/elliptic/Makefile new file mode 100644 index 000000000000..b31a89b246a7 --- /dev/null +++ b/techpack/audio/dsp/elliptic/Makefile @@ -0,0 +1,28 @@ +ccflags-y := -I$(src) -Wall -Werror +IO_MODULE := msm + +# EXTRA_CFLAGS += -DDEBUG + +# Need to add include paths: +LINUXINCLUDE += \ + -I$(srctree)techpack/audio/include/dsp + -I$(srctree)techpack/audio/include/uapi + -I$(srctree)techpack/aduio/include + +obj-y += elliptic.o +obj-y += elliptic_mixer_controls.o +obj-y += io_modules/$(IO_MODULE)/elliptic_data_$(IO_MODULE)_io.o +obj-y += io_modules/userspace/elliptic_data_userspace_io.o +obj-y += io_modules/userspace/elliptic_data_userspace_ctrl.o +obj-y += elliptic_sysfs.o + +# elliptic_driver-y := elliptic.o +# elliptic_driver-y += io_modules/$(IO_MODULE)/elliptic_data_io.o +# elliptic_driver-y += mixer_controls/$(MIXER_MODULE)/elliptic_mixer_controls.o +# elliptic_driver-y += elliptic_sysfs.o + +# .PHONY: clean +# all: +# make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules +# clean: +# rm *.o *.ko \ No newline at end of file diff --git a/techpack/audio/dsp/elliptic/elliptic.c b/techpack/audio/dsp/elliptic/elliptic.c new file mode 100644 index 000000000000..f646f03db0b3 --- /dev/null +++ b/techpack/audio/dsp/elliptic/elliptic.c @@ -0,0 +1,776 @@ +/** +* Copyright Elliptic Labs +* Copyright (C) 2019 XiaoMi, Inc. +* +*/ +/* #define DEBUG */ +#include +#include +#include +/* includes the file structure, that is, file open read close */ +#include + +/* include the character device, makes cdev avilable */ +#include +#include + +/* includes copy_user vice versa */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Alternative mechanism to load calibration data. +* Read calibration data during driver initialization +* and send message to the DSP +* +* #define ELLIPTIC_LOAD_CALIBRATION_DATA_FROM_FILESYSTEM 1 +*/ +#ifdef ELLIPTIC_LOAD_CALIBRATION_DATA_FROM_FILESYSTEM +#include +#include +#include +#endif + +static struct elliptic_device *elliptic_devices; + +/* Global variable for the device class*/ +struct class *elliptic_class; + +typedef uint32_t el_fifo_size_t; + +/* Major number provided by the kernel*/ +static dev_t elliptic_major; + +static struct wakeup_source *wake_source; + +void elliptic_data_cancel(struct elliptic_data *elliptic_data) +{ + atomic_set(&elliptic_data->abort_io, 1); + wake_up_interruptible(&elliptic_data->fifo_isr_not_empty); +} + +void elliptic_data_reset_debug_counters(struct elliptic_data *elliptic_data) +{ + elliptic_data->isr_fifo_discard = 0; +} + +void elliptic_data_print_debug_counters(struct elliptic_data *elliptic_data) +{ + if (elliptic_data->isr_fifo_discard > 0) { + EL_PRINT_E("isr fifo discarded %u frames", + elliptic_data->isr_fifo_discard); + } + + if (elliptic_data->userspace_read_total != + elliptic_data->isr_write_total) { + EL_PRINT_I("user space reads / isr writes : %u / %u", + elliptic_data->userspace_read_total, + elliptic_data->isr_write_total); + } + + EL_PRINT_I("total isr fifo discarded frame count : %u", + elliptic_data->isr_fifo_discard_total); +} + +void elliptic_data_update_debug_counters(struct elliptic_data *elliptic_data) +{ + elliptic_data->isr_fifo_discard_total += + elliptic_data->isr_fifo_discard; +} + +/* spin lock for isr must be held prior to calling */ +static void elliptic_data_flush_isr_fifo(struct elliptic_data *elliptic_data) +{ + kfifo_reset(&elliptic_data->fifo_isr); +} + +/* spin lock for isr must be held prior to calling */ +static void elliptic_data_isr_fifo_pop(struct elliptic_data *elliptic_data, + size_t size) +{ + unsigned int fifo_result; + static uint8_t temp_buffer[ELLIPTIC_MSG_BUF_SIZE]; + + if (size > ELLIPTIC_MSG_BUF_SIZE) + EL_PRINT_E("pop size %zu too large", size); + + fifo_result = kfifo_out(&elliptic_data->fifo_isr, temp_buffer, size); + + if (size != fifo_result) + EL_PRINT_E("failed to pop element"); +} + +int elliptic_notify_gain_change_msg(int component_id, int gaindb) +{ + int32_t msg[3] = { ESCPT_COMPONENT_GAIN_CHANGE, component_id, gaindb }; + + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)msg, sizeof(msg)); +} + +/* inode refers to the actual file on disk */ +static int device_open(struct inode *inode, struct file *filp) +{ + unsigned int major; + unsigned int minor; + struct elliptic_device *dev; + struct elliptic_data *elliptic_data; + + major = imajor(inode); + minor = iminor(inode); + + if (major != elliptic_major || minor < 0 || + minor >= ELLIPTIC_NUM_DEVICES) { + EL_PRINT_W("no device found with minor=%d and major=%d", major, + minor); + return -ENODEV; /* No such device */ + } + + dev = NULL; + dev = &elliptic_devices[minor]; + filp->private_data = dev; + + if (inode->i_cdev != &dev->cdev) { + EL_PRINT_W("dev pointer mismatch"); + return -ENODEV; /* No such device */ + } + + if (down_interruptible(&dev->sem) != 0) { + EL_PRINT_E("the device has been opened, unable to open lock"); + return -EINVAL; + } + + elliptic_data = &dev->el_data; + spin_lock(&elliptic_data->fifo_isr_spinlock); + elliptic_data_flush_isr_fifo(elliptic_data); + spin_unlock(&elliptic_data->fifo_isr_spinlock); + + atomic_set(&elliptic_data->abort_io, 0); + elliptic_data_reset_debug_counters(elliptic_data); + + EL_PRINT_I("Opened device elliptic%u", minor); + dev->opened = 1; + return 0; +} + +int elliptic_data_initialize(struct elliptic_data *elliptic_data, + size_t queue_size, unsigned int wakeup_timeout, + int id) +{ + int is_power_of_two; + + is_power_of_two = (queue_size != 0) && !(queue_size & (queue_size - 1)); + + if (is_power_of_two != 1) { + EL_PRINT_E("non power of 2 fifo size"); + return -EINVAL; + } + + if (kfifo_alloc(&elliptic_data->fifo_isr, queue_size, GFP_KERNEL) != + 0) { + EL_PRINT_E("failed to allocate fifo isr"); + return -EINVAL; + } + + atomic_set(&elliptic_data->abort_io, 0); + spin_lock_init(&elliptic_data->fifo_isr_spinlock); + + elliptic_data->wakeup_timeout = wakeup_timeout; + + mutex_init(&elliptic_data->user_buffer_lock); + init_waitqueue_head(&elliptic_data->fifo_isr_not_empty); + + return 0; +} + +int elliptic_data_cleanup(struct elliptic_data *elliptic_data) +{ + spin_unlock(&elliptic_data->fifo_isr_spinlock); + kfifo_free(&elliptic_data->fifo_isr); + return 0; +} + +size_t elliptic_data_pop(struct elliptic_data *elliptic_data, + char __user *user_buffer, size_t buffer_size) +{ + int result; + unsigned long num_copied; + unsigned int fifo_result; + unsigned long flags; + + if (buffer_size < ELLIPTIC_MSG_BUF_SIZE) { + EL_PRINT_E("buffer_size : %lu smaller than %lu", buffer_size, + (size_t)ELLIPTIC_MSG_BUF_SIZE); + return 0; + } + + result = wait_event_interruptible( + elliptic_data->fifo_isr_not_empty, + (kfifo_is_empty(&elliptic_data->fifo_isr) == 0) || + (atomic_read(&elliptic_data->abort_io) == 1)); + + if (atomic_read(&elliptic_data->abort_io) == 1) { + atomic_set(&elliptic_data->abort_io, 0); + EL_PRINT_D("pop cancelled"); + return 0; + } + + if (result == 0) { + spin_lock_irqsave(&elliptic_data->fifo_isr_spinlock, flags); + + fifo_result = kfifo_out(&elliptic_data->fifo_isr, + elliptic_data->isr_swap_buffer, + ELLIPTIC_MSG_BUF_SIZE); + + spin_unlock_irqrestore(&elliptic_data->fifo_isr_spinlock, + flags); + + if (fifo_result == 0) { + EL_PRINT_E("failed to copy: fifo isr -> swap buffer %u", + fifo_result); + return 0; + } + + mutex_lock(&elliptic_data->user_buffer_lock); + + num_copied = copy_to_user(user_buffer, + elliptic_data->isr_swap_buffer, + ELLIPTIC_MSG_BUF_SIZE); + + mutex_unlock(&elliptic_data->user_buffer_lock); + + if (num_copied != 0) { + EL_PRINT_E("failed copy to user"); + return 0; + } + ++elliptic_data->userspace_read_total; + } else { + if (-ERESTARTSYS == result) + EL_PRINT_I("wait interrupted"); + else + EL_PRINT_E("wait error = %d", result); + + return 0; + } + + return (size_t)ELLIPTIC_MSG_BUF_SIZE; +} + +/* push data to specific device or all devices */ +int elliptic_data_push(int deviceid, const char *buffer, size_t buffer_size, + elliptic_data_push_t data_source) +{ + size_t available_space; + size_t space_required; + size_t zeros_to_pad; + unsigned int copied_from_user; + int copy_from_user_result; + int err; + int i; + int i_max; + + unsigned long flags; + struct elliptic_device *device; + struct elliptic_data *elliptic_data; + unsigned int fifo_result; + static uint8_t zero_pad_buffer[ELLIPTIC_MSG_BUF_SIZE]; + + err = 0; + fifo_result = 0; + copied_from_user = 0; + copy_from_user_result = 0; + if (buffer_size > ELLIPTIC_MSG_BUF_SIZE) + return -EINVAL; + + zeros_to_pad = ELLIPTIC_MSG_BUF_SIZE - buffer_size; + + i = 0; + i_max = ELLIPTIC_NUM_DEVICES; + + if (deviceid != ELLIPTIC_ALL_DEVICES) { + /* Copy to specific device */ + i = deviceid; + i_max = i + 1; + } + + for (; i < i_max; ++i) { + device = &elliptic_devices[i]; + elliptic_data = &device->el_data; + + if ((!device->opened)) + continue; + + available_space = kfifo_avail(&elliptic_data->fifo_isr); + space_required = ELLIPTIC_MSG_BUF_SIZE; + + spin_lock_irqsave(&elliptic_data->fifo_isr_spinlock, flags); + + if (available_space < space_required) { + ++elliptic_data->isr_fifo_discard; + elliptic_data_isr_fifo_pop(elliptic_data, + ELLIPTIC_MSG_BUF_SIZE); + } + + if (data_source == ELLIPTIC_DATA_PUSH_FROM_KERNEL) { + fifo_result = kfifo_in(&elliptic_data->fifo_isr, buffer, + buffer_size); + + if (fifo_result == 0) { + spin_unlock_irqrestore( + &elliptic_data->fifo_isr_spinlock, + flags); + continue; + } + } else if (data_source == ELLIPTIC_DATA_PUSH_FROM_USERSPACE) { + copy_from_user_result = + kfifo_from_user(&elliptic_data->fifo_isr, + buffer, buffer_size, + &copied_from_user); + + if (-EFAULT == copy_from_user_result) { + spin_unlock_irqrestore( + &elliptic_data->fifo_isr_spinlock, + flags); + continue; + } + } + + if (zeros_to_pad > 0) { + fifo_result = kfifo_in(&elliptic_data->fifo_isr, + zero_pad_buffer, zeros_to_pad); + + if (fifo_result == 0) { + elliptic_data_isr_fifo_pop(elliptic_data, + buffer_size); + + spin_unlock_irqrestore( + &elliptic_data->fifo_isr_spinlock, + flags); + + ++elliptic_data->isr_fifo_discard; + continue; + } + } + + ++elliptic_data->isr_write_total; + spin_unlock_irqrestore(&elliptic_data->fifo_isr_spinlock, + flags); + wake_up_interruptible(&elliptic_data->fifo_isr_not_empty); + __pm_wakeup_event(wake_source, elliptic_data->wakeup_timeout); + } + + return err; +} + +int elliptic_open_port(int portid) +{ + return elliptic_io_open_port(portid); +} + +int elliptic_close_port(int portid) +{ + return elliptic_io_close_port(portid); +} + +int32_t elliptic_data_write(uint32_t message_id, const char *data, + size_t data_size) +{ + int32_t err_dsp; + /* int32_t err_us; */ + + err_dsp = 0; + err_dsp = elliptic_data_io_write(message_id, data, data_size); + if (err_dsp) + EL_PRINT_E("Failed write to DSP"); + return err_dsp; + + /* + * err_us = 0; + * err_us = elliptic_userspace_ctrl_write(message_id, data, data_size); + * if(err_us){ + * EL_PRINT_E("Failed write to user space"); + *} + * + *return (err_dsp | err_us); + */ +} + +/** +* +* @return Number of bytes read. +*/ +static ssize_t device_read(struct file *fp, char __user *buff, size_t length, + loff_t *ppos) +{ + ssize_t bytes_read = 0; + struct elliptic_device *elliptic_device; + struct elliptic_data *elliptic_data; + + elliptic_device = (struct elliptic_device *)fp->private_data; + elliptic_data = (struct elliptic_data *)&elliptic_device->el_data; + + bytes_read = elliptic_data_pop(elliptic_data, buff, length); + + return bytes_read; +} + +/** +* +* @return number of bytes actually written +*/ +static ssize_t device_write(struct file *fp, const char *buff, size_t length, + loff_t *ppos) +{ + ssize_t ret_val; + + ret_val = 0; + if ((buff != NULL) && (length != 0)) + ret_val = elliptic_data_io_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + buff, length); + + return ret_val >= 0 ? (ssize_t)length : 0; +} + +static long device_ioctl(struct file *fp, unsigned int number, + unsigned long param) +{ + struct elliptic_device *device; + struct elliptic_data *elliptic_data; + int err; + unsigned int mirror_tag, mirror_payload_size; + unsigned char *data_ptr; + + device = (struct elliptic_device *)(fp->private_data); + elliptic_data = &device->el_data; + + switch (number) { + case IOCTL_ELLIPTIC_DATA_IO_CANCEL: + EL_PRINT_D("IOCTL_ELLIPTIC_CANCEL_READ %ld", param); + elliptic_data_cancel(elliptic_data); + break; + + case IOCTL_ELLIPTIC_DATA_IO_MIRROR: + data_ptr = (unsigned char *)param; + mirror_tag = *(unsigned int *)data_ptr; + mirror_payload_size = *((unsigned int *)data_ptr + 1); + + if ((mirror_tag == MIRROR_TAG) && (mirror_payload_size != 0) && + (mirror_payload_size <= (ELLIPTIC_SET_PARAMS_SIZE * 4))) { + err = elliptic_data_io_write( + ELLIPTIC_ULTRASOUND_SET_PARAMS, (data_ptr + 8), + mirror_payload_size); + + if (err != 0) { + EL_PRINT_E("elliptic_data_io_write failed"); + return err; + } + + } else { + EL_PRINT_E("TAG or Length is not valid"); + } + + break; + + default: + EL_PRINT_W("UNKNOWN IOCTL number=%d", number); + break; + } + + return 0; +} + +static unsigned int device_poll(struct file *file, + struct poll_table_struct *poll_table) +{ + unsigned int mask; + + struct elliptic_device *device; + struct elliptic_data *elliptic_data; + + mask = 0; + device = (struct elliptic_device *)file->private_data; + elliptic_data = (struct elliptic_data *)&device->el_data; + + poll_wait(file, &elliptic_data->fifo_isr_not_empty, poll_table); + + if (!kfifo_is_empty(&elliptic_data->fifo_isr)) + mask = POLLIN | POLLRDNORM; + + return mask; +} + +static int device_close(struct inode *inode, struct file *filp) +{ + struct elliptic_device *device; + struct elliptic_data *elliptic_data; + unsigned int minor; + + device = filp->private_data; + elliptic_data = &device->el_data; + minor = iminor(inode); + if (device == NULL) { + EL_PRINT_E("device not found"); + return -ENODEV; + } + + device->opened = 0; + elliptic_data_update_debug_counters(elliptic_data); + elliptic_data_print_debug_counters(elliptic_data); + elliptic_data_cancel(elliptic_data); + up(&device->sem); + + EL_PRINT_I("Closed device elliptic%u", minor); + return 0; +} + +/* defines the file operations provided by the driver */ +static const struct file_operations elliptic_fops = { + .owner = THIS_MODULE, /* prevents unloading when operations are in use*/ + .open = device_open, /*to open the device*/ + .write = device_write, /*to write to the device*/ + .read = device_read, /*to read the device*/ + .poll = device_poll, + .unlocked_ioctl = device_ioctl, /* IOCTL calls */ + .release = device_close, /*to close the device*/ +}; + +static int elliptic_device_initialize(struct elliptic_device *elliptic_device, + int minor, struct class *class) +{ + int err; + dev_t device_number; + struct device *device; + + BUG_ON(elliptic_device == NULL || class == NULL); + + err = 0; + device = NULL; + device_number = MKDEV(elliptic_major, minor); + /* Memory is to be allocated when the device is opened the first time */ + sema_init(&elliptic_device->sem, 1); + cdev_init(&elliptic_device->cdev, &elliptic_fops); + elliptic_device->cdev.owner = THIS_MODULE; + + err = cdev_add(&elliptic_device->cdev, device_number, 1); + + if (err) { + EL_PRINT_E("error %d while trying to add %s%d", err, + ELLIPTIC_DEVICENAME, minor); + return err; + } + + device = device_create(class, NULL, device_number, NULL, + ELLIPTIC_DEVICENAME "%d", minor); + + if (IS_ERR(device)) { + err = PTR_ERR(device); + EL_PRINT_E("error %d while trying to create %s%d", err, + ELLIPTIC_DEVICENAME, minor); + cdev_del(&elliptic_device->cdev); + return err; + } + + if (err) { + EL_PRINT_E("failed device initialize"); + return err; + } + + return 0; +} + +static void elliptic_device_cleanup(struct elliptic_device *dev, int minor, + struct class *class) + +{ + BUG_ON(dev == NULL || class == NULL); + device_destroy(class, MKDEV(elliptic_major, minor)); + cdev_del(&dev->cdev); + up(&dev->sem); +} + +static void elliptic_driver_cleanup(int devices_to_destroy) +{ + int i; + + if (elliptic_devices) { + elliptic_data_io_cleanup(); + + for (i = 0; i < devices_to_destroy; ++i) { + elliptic_data_cleanup(&elliptic_devices[i].el_data); + elliptic_device_cleanup(&elliptic_devices[i], i, + elliptic_class); + } + + kfree(elliptic_devices); + } + + if (elliptic_class) + class_destroy(elliptic_class); + + unregister_chrdev_region(MKDEV(elliptic_major, 0), + ELLIPTIC_NUM_DEVICES); +} + +#ifdef ELLIPTIC_LOAD_CALIBRATION_DATA_FROM_FILESYSTEM + +#define ELLIPTIC_CALIBRATION_MAX_DATA_SIZE \ + (ELLIPTIC_CALIBRATION_V2_DATA_SIZE + ELLIPTIC_CALIBRATION_DATA_SIZE) +static unsigned char calibration_data[ELLIPTIC_CALIBRATION_MAX_DATA_SIZE]; +static char *calibration_filename = "/persist/audio/elliptic_calibration"; + +/* function to load the calibration from a file (if possible) */ +static size_t load_calibration_data(char *filename) +{ + size_t ret = 0; + int fd; + + mm_segment_t old_fs = get_fs(); + + set_fs(KERNEL_DS); + + fd = sys_open(filename, O_RDONLY, 0); + if (fd >= 0) { + size_t bytes_read = + sys_read(fd, calibration_data, + ELLIPTIC_CALIBRATION_MAX_DATA_SIZE); + + if (bytes_read == ELLIPTIC_CALIBRATION_DATA_SIZE || + bytes_read == ELLIPTIC_CALIBRATION_V2_DATA_SIZE) { + ret = bytes_read; + } + sys_close(fd); + } + set_fs(old_fs); + return ret; +} + +static int32_t elliptic_send_calibration_to_engine(size_t calib_data_size) +{ + elliptic_set_calibration_data(calibration_data, calib_data_size); + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)calibration_data, + calib_data_size); +} + +#endif + +int __init elliptic_driver_init(void) +{ + int err; + int i; + int devices_to_destroy; + dev_t device_number; + + err = alloc_chrdev_region(&device_number, 0, ELLIPTIC_NUM_DEVICES, + ELLIPTIC_DEVICENAME); + + devices_to_destroy = 0; + + if (err < 0) { + EL_PRINT_E("Failed to allocate cdev region"); + return err; + } + + elliptic_major = MAJOR(device_number); + elliptic_class = class_create(THIS_MODULE, "chardev"); + + if (elliptic_class == NULL) { + EL_PRINT_E("Class creation failed"); + goto fail; + } + + err = elliptic_initialize_sysfs(); + + if (err) + goto fail; + + elliptic_devices = (struct elliptic_device *)kzalloc( + sizeof(struct elliptic_device) * ELLIPTIC_NUM_DEVICES, + GFP_KERNEL); + + if (elliptic_devices == NULL) { + err = -ENOMEM; + goto fail; + } + + for (i = 0; i < ELLIPTIC_NUM_DEVICES; ++i) { + if (elliptic_device_initialize(&elliptic_devices[i], i, + elliptic_class)) { + devices_to_destroy = i; + goto fail; + } + + if (elliptic_data_initialize(&elliptic_devices[i].el_data, + ELLIPTIC_DATA_FIFO_SIZE, + ELLIPTIC_WAKEUP_TIMEOUT, i)) { + goto fail; + } + } + + if (elliptic_data_io_initialize()) + goto fail; + + if (elliptic_userspace_io_driver_init()) + goto fail; + + if (elliptic_userspace_ctrl_driver_init()) + goto fail; + + wake_source = kmalloc(sizeof(struct wakeup_source), GFP_KERNEL); + + if (!wake_source) { + EL_PRINT_E("failed to allocate wake source"); + return -ENOMEM; + } + + wakeup_source_init(wake_source, "elliptic_wake_source"); + +#ifdef ELLIPTIC_LOAD_CALIBRATION_DATA_FROM_FILESYSTEM + /* Code to send calibration to engine */ + { + size_t calib_data_size = + load_calibration_data(calibration_filename); + if (calib_data_size > 0) + elliptic_send_calibration_to_engine(calib_data_size); + } +#endif + return 0; + +fail: + elliptic_driver_cleanup(devices_to_destroy); + return err; +} + +void elliptic_driver_exit(void) +{ + if (wake_source) { + wakeup_source_trash(wake_source); + kfree(wake_source); + } + + elliptic_cleanup_sysfs(); + elliptic_driver_cleanup(ELLIPTIC_NUM_DEVICES); + elliptic_userspace_io_driver_exit(); + elliptic_userspace_ctrl_driver_exit(); +} + +MODULE_AUTHOR("Elliptic Labs"); +MODULE_DESCRIPTION("Providing Interface to UPS data"); +MODULE_LICENSE("GPL"); diff --git a/techpack/audio/dsp/elliptic/elliptic_mixer_controls.c b/techpack/audio/dsp/elliptic/elliptic_mixer_controls.c new file mode 100644 index 000000000000..089f1b91212e --- /dev/null +++ b/techpack/audio/dsp/elliptic/elliptic_mixer_controls.c @@ -0,0 +1,1367 @@ +/** + * Elliptic Labs + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct elliptic_system_configuration { + union { + uint8_t reserved[ELLIPTIC_SYSTEM_CONFIGURATION_SIZE]; + }; +}; + +struct elliptic_system_configuration elliptic_system_configuration; + +struct elliptic_system_configuration_parameter { + enum elliptic_system_configuration_parameter_type type; + union { + int32_t speaker_scaling[2]; + int32_t sensitivity; + int32_t latency; + int32_t microphone_index; + int32_t operation_mode; + int32_t operation_mode_flags; + int32_t component_gain_change; + int32_t calibration_state; + int32_t engine_version; + int32_t calibration_profile; + int32_t ultrasound_gain; + int32_t log_level; + int32_t custom_setting; + int32_t engine_suspend; + int32_t input_enabled; + int32_t output_enabled; + int32_t external_event; + struct { + int32_t calibration_method; + int32_t calibration_timestamp; + }; + int32_t debug_mode; + int32_t context; + int32_t capture; + int32_t input_channels; + }; +}; + +struct elliptic_system_configuration_parameters_cache + elliptic_system_configuration_cache = { { 0 }, 0 }; + +static struct elliptic_engine_version_info elliptic_engine_version_cache = { + 0xde, 0xad, 0xbe, 0xef +}; + +struct elliptic_engine_calibration_data { + union { + uint8_t reserved[ELLIPTIC_CALIBRATION_DATA_SIZE]; + }; +}; + +static struct elliptic_engine_calibration_data + elliptic_engine_calibration_data_cache = { .reserved = { + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef } }; + +struct elliptic_engine_calibration_v2_data { + union { + uint8_t reserved[ELLIPTIC_CALIBRATION_V2_DATA_SIZE]; + }; +}; + +static struct elliptic_engine_calibration_v2_data + elliptic_engine_calibration_v2_data_cache = { .reserved = { + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + } }; + +struct elliptic_engine_diagnostics_data { + union { + uint8_t reserved[ELLIPTIC_DIAGNOSTICS_DATA_SIZE]; + uint32_t values32[ELLIPTIC_DIAGNOSTICS_DATA_SIZE >> 2]; + }; +}; + +static struct elliptic_engine_diagnostics_data + elliptic_engine_diagnostics_data_cache = { .reserved = { 0 } }; + +struct elliptic_engine_ml_data { + union { + uint8_t reserved[ELLIPTIC_ML_DATA_SIZE]; + uint32_t u32[ELLIPTIC_ML_DATA_SIZE >> 2]; + }; +}; + +static struct elliptic_engine_ml_data elliptic_engine_ml_data_cache = { + .reserved = { 0 } +}; + +struct elliptic_engine_sensor_data { + union { + uint8_t reserved[ELLIPTIC_SENSOR_DATA_SIZE]; + uint32_t values32[ELLIPTIC_SENSOR_DATA_SIZE >> 2]; + }; +}; + +static struct elliptic_engine_sensor_data elliptic_engine_sensor_data_cache = { + .reserved = { 0 } +}; + +struct elliptic_engine_branch_info { + char build_branch[ELLIPTIC_BRANCH_INFO_MAX_SIZE]; +}; + +static struct elliptic_engine_branch_info elliptic_engine_branch_cache = { + { 0 } +}; + +struct elliptic_engine_tag_info { + char engine_tag[ELLIPTIC_TAG_INFO_SIZE]; +}; + +static struct elliptic_engine_tag_info elliptic_engine_tag_cache = { { 0 } }; + +static struct elliptic_shared_data_block shared_data_blocks[] = { + { ELLIPTIC_OBJ_ID_CALIBRATION_DATA, ELLIPTIC_CALIBRATION_DATA_SIZE, + &elliptic_engine_calibration_data_cache }, + + { ELLIPTIC_OBJ_ID_VERSION_INFO, ELLIPTIC_VERSION_INFO_SIZE, + &elliptic_engine_version_cache }, + { ELLIPTIC_OBJ_ID_BRANCH_INFO, ELLIPTIC_BRANCH_INFO_MAX_SIZE, + &elliptic_engine_branch_cache }, + { ELLIPTIC_OBJ_ID_CALIBRATION_V2_DATA, + ELLIPTIC_CALIBRATION_V2_DATA_SIZE, + &elliptic_engine_calibration_v2_data_cache }, + { ELLIPTIC_OBJ_ID_DIAGNOSTICS_DATA, ELLIPTIC_DIAGNOSTICS_DATA_SIZE, + &elliptic_engine_diagnostics_data_cache }, + { ELLIPTIC_OBJ_ID_TAG_INFO, ELLIPTIC_TAG_INFO_SIZE, + &elliptic_engine_tag_cache }, + { ELLIPTIC_OBJ_ID_ML_DATA, ELLIPTIC_ML_DATA_SIZE, + &elliptic_engine_ml_data_cache }, +}; + +void elliptic_set_calibration_data(uint8_t *calib_data, size_t size) +{ + struct elliptic_shared_data_block *calibration_obj = NULL; + + if (size == ELLIPTIC_CALIBRATION_DATA_SIZE) { + calibration_obj = elliptic_get_shared_obj( + ELLIPTIC_OBJ_ID_CALIBRATION_DATA); + memcpy((uint8_t *)&elliptic_engine_calibration_data_cache, + calib_data, size); + } + if (size == ELLIPTIC_CALIBRATION_V2_DATA_SIZE) { + calibration_obj = elliptic_get_shared_obj( + ELLIPTIC_OBJ_ID_CALIBRATION_V2_DATA); + memcpy((uint8_t *)&elliptic_engine_calibration_v2_data_cache, + calib_data, size); + } + if (calibration_obj == NULL) { + EL_PRINT_E("ell..set_calibration_data() calib=NULL (%zu)", + size); + return; + } + memcpy((u8 *)calibration_obj->buffer, calib_data, size); +} + +void elliptic_set_diagnostics_data(uint8_t *diag_data, size_t size) +{ + struct elliptic_shared_data_block *diagnostics_obj = NULL; + + if (size <= ELLIPTIC_DIAGNOSTICS_DATA_SIZE) { + diagnostics_obj = elliptic_get_shared_obj( + ELLIPTIC_OBJ_ID_DIAGNOSTICS_DATA); + if (diagnostics_obj == NULL) { + EL_PRINT_E("el..set_diagnostics_data() NULL (%zu)", + size); + return; + } + memcpy((uint8_t *)&elliptic_engine_diagnostics_data_cache, + diag_data, size); + memcpy((u8 *)diagnostics_obj->buffer, diag_data, size); + } +} + +static const size_t NUM_SHARED_RW_OBJS = + sizeof(shared_data_blocks) / sizeof(struct elliptic_shared_data_block); + +struct elliptic_shared_data_block *elliptic_get_shared_obj(uint32_t object_id) +{ + size_t i; + + for (i = 0; i < NUM_SHARED_RW_OBJS; ++i) { + if (shared_data_blocks[i].object_id == object_id) + return &shared_data_blocks[i]; + } + + return NULL; +} + +static const char *const ultrasound_enable_texts[] = { "Off", "On" }; + +static const struct soc_enum elliptic_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ultrasound_enable_texts), + ultrasound_enable_texts), +}; + +int get_elliptic_calibration_data(uint8_t *caldata, uint32_t max_size) +{ + uint32_t copied; + + copied = ELLIPTIC_CALIBRATION_DATA_SIZE; + if (max_size < ELLIPTIC_CALIBRATION_DATA_SIZE) { + copied = max_size; + EL_PRINT_D("size mismatch : %u vs %u", + (uint32_t)ELLIPTIC_CALIBRATION_DATA_SIZE, max_size); + } + + memcpy(caldata, (uint8_t *)&elliptic_engine_calibration_data_cache, + max_size); + return copied; +} + +int get_elliptic_calibration_v2_data(uint8_t *caldata, uint32_t max_size) +{ + uint32_t copied; + + copied = ELLIPTIC_CALIBRATION_V2_DATA_SIZE; + if (max_size < ELLIPTIC_CALIBRATION_V2_DATA_SIZE) { + copied = max_size; + EL_PRINT_D("size mismatch : %u vs %u", + (uint32_t)ELLIPTIC_CALIBRATION_V2_DATA_SIZE, + max_size); + } + + memcpy(caldata, (uint8_t *)&elliptic_engine_calibration_v2_data_cache, + max_size); + return copied; +} + +int get_elliptic_diagnostics_data(uint8_t *diagdata, uint32_t max_size) +{ + uint32_t copied; + + copied = ELLIPTIC_DIAGNOSTICS_DATA_SIZE; + if (max_size < ELLIPTIC_DIAGNOSTICS_DATA_SIZE) { + copied = max_size; + EL_PRINT_D("size mismatch : %u vs %u", + (uint32_t)ELLIPTIC_DIAGNOSTICS_DATA_SIZE, max_size); + } + + memcpy(diagdata, (uint8_t *)&elliptic_engine_diagnostics_data_cache, + max_size); + return copied; +} + +static uint32_t ultrasound_enable_cache; + +int elliptic_ultrasound_enable_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = ultrasound_enable_cache; + return 0; +} + +int elliptic_ultrasound_enable_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + static bool triggered_engine_info; + int32_t msg[4] = { 0, 0, 0, 0 }; + + ultrasound_enable_cache = ucontrol->value.integer.value[0]; + + if (!triggered_engine_info && ultrasound_enable_cache) { + triggered_engine_info = true; + elliptic_trigger_version_msg(); + elliptic_trigger_branch_msg(); + elliptic_trigger_tag_msg(); + } + + msg[0] = ultrasound_enable_cache ? 1 : 0; + + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)msg, sizeof(msg)); +} + +static uint32_t ultrasound_tx_port_cache; + +int elliptic_ultrasound_tx_port_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = ultrasound_tx_port_cache; + return 0; +} + +int elliptic_ultrasound_tx_port_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret; + + if (ultrasound_tx_port_cache == ucontrol->value.integer.value[0]) { + EL_PRINT_E( + "ultrasound_tx_port_set: ignoring duplicate request"); + return 0; + } + + ultrasound_tx_port_cache = ucontrol->value.integer.value[0]; + if (ultrasound_tx_port_cache) + ret = elliptic_open_port(ULTRASOUND_TX_PORT_ID); + else + ret = elliptic_close_port(ULTRASOUND_TX_PORT_ID); + + EL_PRINT_E("ultrasound_tx_port: enable=%d ret=%d", + ultrasound_tx_port_cache, ret); + + return ret; +} + +static uint32_t ultrasound_rx_port_cache; + +int elliptic_ultrasound_rx_port_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = ultrasound_rx_port_cache; + return 0; +} + +int elliptic_ultrasound_rx_port_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret; + + if (ultrasound_rx_port_cache == ucontrol->value.integer.value[0]) { + EL_PRINT_E( + "ultrasound_rx_port_set: ignoring duplicate request"); + return 0; + } + + ultrasound_rx_port_cache = ucontrol->value.integer.value[0]; + if (ultrasound_rx_port_cache) + ret = elliptic_open_port(ULTRASOUND_RX_PORT_ID); + else + ret = elliptic_close_port(ULTRASOUND_RX_PORT_ID); + + EL_PRINT_E("ultrasound_rx_port: enable=%d ret=%d", + ultrasound_tx_port_cache, ret); + + return 0; +} + +int elliptic_ultrasound_rampdown_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* Rampdown is a strobe, so always return Off */ + ucontrol->value.integer.value[0] = 0; + return 0; +} + +int elliptic_ultrasound_rampdown_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int32_t msg[4] = { -1, 0, 0, 0 }; + + if (ucontrol->value.integer.value[0] == 0) + return 0; + + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)msg, sizeof(msg)); +} + +int elliptic_ultrasound_diagnostics_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* Diagnostics is a strobe, so always return Off */ + ucontrol->value.integer.value[0] = 0; + return 0; +} + +int elliptic_ultrasound_request_diagnostics(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int32_t msg[3] = { ESCPT_ENGINE_DIAGNOSTICS, 0, 0 }; + + if (ucontrol->value.integer.value[0] == 0) + return 0; + + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)msg, sizeof(msg)); +} + +int elliptic_system_configuration_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, &elliptic_system_configuration, + ELLIPTIC_SYSTEM_CONFIGURATION_SIZE); + return 0; +} + +int elliptic_system_configuration_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(&elliptic_system_configuration, ucontrol->value.bytes.data, + ELLIPTIC_SYSTEM_CONFIGURATION_SIZE); + + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)&elliptic_system_configuration, + ELLIPTIC_SYSTEM_CONFIGURATION_SIZE); +} + +int elliptic_calibration_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, + &elliptic_engine_calibration_data_cache, + ELLIPTIC_CALIBRATION_DATA_SIZE); + return 0; +} + +int elliptic_calibration_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(&elliptic_engine_calibration_data_cache, + ucontrol->value.bytes.data, ELLIPTIC_CALIBRATION_DATA_SIZE); + + return elliptic_data_write( + ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)&elliptic_engine_calibration_data_cache, + ELLIPTIC_CALIBRATION_DATA_SIZE); +} + +int elliptic_calibration_v2_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct elliptic_shared_data_block *calibration_obj = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_CALIBRATION_V2_DATA); + + if (calibration_obj == NULL) { + EL_PRINT_E("calibration_obj is NULL"); + return -EINVAL; + } + + memcpy(ucontrol->value.bytes.data, calibration_obj->buffer, + ELLIPTIC_CALIBRATION_V2_DATA_SIZE); + return 0; +} + +int elliptic_calibration_v2_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(&elliptic_engine_calibration_v2_data_cache, + ucontrol->value.bytes.data, ELLIPTIC_CALIBRATION_V2_DATA_SIZE); + + return elliptic_data_write( + ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)&elliptic_engine_calibration_v2_data_cache, + ELLIPTIC_CALIBRATION_V2_DATA_SIZE); +} + +int elliptic_diagnostics_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, + &elliptic_engine_diagnostics_data_cache, + ELLIPTIC_DIAGNOSTICS_DATA_SIZE); + return 0; +} + +int elliptic_diagnostics_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +int elliptic_ml_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct elliptic_shared_data_block *ml_obj = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_ML_DATA); + + if (ml_obj == NULL) { + EL_PRINT_E("ml_obj is NULL"); + return -EINVAL; + } + + memcpy(ucontrol->value.bytes.data, ml_obj->buffer, + ELLIPTIC_ML_DATA_SIZE); + return 0; +} + +int elliptic_ml_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)ucontrol->value.bytes.data, + ELLIPTIC_ML_DATA_SIZE); +} + +int elliptic_sensor_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, &elliptic_engine_sensor_data_cache, + ELLIPTIC_SENSOR_DATA_SIZE); + return 0; +} + +int elliptic_sensor_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(&elliptic_engine_sensor_data_cache, ucontrol->value.bytes.data, + ELLIPTIC_SENSOR_DATA_SIZE); + + return elliptic_data_write( + ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)&elliptic_engine_sensor_data_cache, + ELLIPTIC_SENSOR_DATA_SIZE); +} + +int elliptic_version_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, &elliptic_engine_version_cache, + ELLIPTIC_VERSION_INFO_SIZE); + return 0; +} + +int elliptic_version_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +int elliptic_branch_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, &elliptic_engine_branch_cache, + ELLIPTIC_BRANCH_INFO_MAX_SIZE); + return 0; +} + +int elliptic_branch_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +int elliptic_tag_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, &elliptic_engine_tag_cache, + ELLIPTIC_TAG_INFO_SIZE); + return 0; +} + +int elliptic_tag_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +int elliptic_calibration_param_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + if (mc->reg != ELLIPTIC_CALIBRATION) + return -EINVAL; + + switch (mc->shift) { + case ELLIPTIC_CALIBRATION_STATE: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.calibration_state; + break; + + case ELLIPTIC_CALIBRATION_PROFILE: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.calibration_profile; + break; + + case ELLIPTIC_ULTRASOUND_GAIN: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.ultrasound_gain; + break; + + default: + return -EINVAL; + } + + return 1; +} + +int elliptic_calibration_param_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct elliptic_system_configuration_parameter param; + + if (mc->reg != ELLIPTIC_CALIBRATION) + return -EINVAL; + + switch (mc->shift) { + case ELLIPTIC_CALIBRATION_STATE: + elliptic_system_configuration_cache.calibration_state = + ucontrol->value.integer.value[0]; + + param.type = ESCPT_CALIBRATION_STATE; + param.calibration_state = + elliptic_system_configuration_cache.calibration_state; + break; + + case ELLIPTIC_CALIBRATION_PROFILE: + elliptic_system_configuration_cache.calibration_profile = + ucontrol->value.integer.value[0]; + + param.type = ESCPT_CALIBRATION_PROFILE; + param.calibration_profile = + elliptic_system_configuration_cache.calibration_profile; + break; + + case ELLIPTIC_ULTRASOUND_GAIN: + elliptic_system_configuration_cache.ultrasound_gain = + ucontrol->value.integer.value[0]; + param.type = ESCPT_ULTRASOUND_GAIN; + param.ultrasound_gain = + elliptic_system_configuration_cache.ultrasound_gain; + break; + + default: + return -EINVAL; + } + + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, (u8 *)¶m, + sizeof(param)); +} + +int elliptic_system_configuration_param_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + pr_err("%s: reg: %d shift: %d\n", __func__, mc->reg, mc->shift); + + if (mc->reg != ELLIPTIC_SYSTEM_CONFIGURATION) + return -EINVAL; + + if (mc->shift >= ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_0 && + mc->shift <= ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_15) { + EL_PRINT_E( + "get ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_%02d", + mc->shift - + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_0); + ucontrol->value.integer.value[0] = 0; + return 1; + } + + switch (mc->shift) { + case ELLIPTIC_SYSTEM_CONFIGURATION_LATENCY: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.latency; + break; + + case ELLIPTIC_SYSTEM_CONFIGURATION_SENSITIVITY: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.sensitivity; + break; + + case ELLIPTIC_SYSTEM_CONFIGURATION_SPEAKER_SCALING: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.speaker_scaling[0]; + ucontrol->value.integer.value[1] = + elliptic_system_configuration_cache.speaker_scaling[1]; + break; + + case ELLIPTIC_SYSTEM_CONFIGURATION_MICROPHONE_INDEX: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.microphone_index; + break; + + case ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.operation_mode; + break; + + case ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE_FLAGS: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.operation_mode_flags; + break; + + case ELLIPTIC_SYSTEM_CONFIGURATION_LOG_LEVEL: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.log_level; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_SUSPEND: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.engine_suspend; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_INPUT_ENABLED: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.input_enabled; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_OUTPUT_ENABLED: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.output_enabled; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_EXTERNAL_EVENT: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.external_event; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_CALIBRATION_METHOD: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.calibration_method; + case ELLIPTIC_SYSTEM_CONFIGURATION_DEBUG_MODE: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.debug_mode; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_CONTEXT: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.context; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_CAPTURE: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.capture; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_INPUT_CHANNELS: + ucontrol->value.integer.value[0] = + elliptic_system_configuration_cache.input_channels; + break; + + default: + EL_PRINT_E("Invalid mixer control"); + return -EINVAL; + } + + return 1; +} + +int elliptic_system_configuration_param_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct elliptic_system_configuration_parameter param; + struct timeval tv; + + if (mc->reg != ELLIPTIC_SYSTEM_CONFIGURATION) + return -EINVAL; + + if (mc->shift >= ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_0 && + mc->shift <= ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_15) { + const size_t csi = + mc->shift - + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_0; + EL_PRINT_E( + "ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_XX csi:%zu", + csi); + if (csi >= ARRAY_SIZE(elliptic_system_configuration_cache + .custom_settings)) + return -EINVAL; + EL_PRINT_E("ucontrol->value.integer.value[0]:%ld", + ucontrol->value.integer.value[0]); + elliptic_system_configuration_cache.custom_settings[csi] = + ucontrol->value.integer.value[0]; + param.type = ESCPT_ENGINE_CUSTOM_SETTING_0 + csi; + param.custom_setting = ucontrol->value.integer.value[0]; + EL_PRINT_E( + "calling elliptic_data_write(custom_setting) csi:%zu", + csi); + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)¶m, sizeof(param)); + } + + switch (mc->shift) { + case ELLIPTIC_SYSTEM_CONFIGURATION_LATENCY: + elliptic_system_configuration_cache.latency = + ucontrol->value.integer.value[0]; + param.type = ESCPT_LATENCY; + param.latency = elliptic_system_configuration_cache.latency; + break; + + case ELLIPTIC_SYSTEM_CONFIGURATION_SENSITIVITY: + elliptic_system_configuration_cache.sensitivity = + ucontrol->value.integer.value[0]; + param.type = ESCPT_CHANNEL_SENSITIVITY; + param.sensitivity = + elliptic_system_configuration_cache.sensitivity; + break; + + case ELLIPTIC_SYSTEM_CONFIGURATION_SPEAKER_SCALING: + elliptic_system_configuration_cache.speaker_scaling[0] = + ucontrol->value.integer.value[0]; + elliptic_system_configuration_cache.speaker_scaling[1] = + ucontrol->value.integer.value[1]; + param.type = ESCPT_SPEAKER_SCALING; + param.speaker_scaling[0] = + elliptic_system_configuration_cache.speaker_scaling[0]; + param.speaker_scaling[1] = + elliptic_system_configuration_cache.speaker_scaling[1]; + break; + + case ELLIPTIC_SYSTEM_CONFIGURATION_MICROPHONE_INDEX: + elliptic_system_configuration_cache.microphone_index = + ucontrol->value.integer.value[0]; + param.type = ESCPT_MICROPHONE_INDEX; + param.microphone_index = + elliptic_system_configuration_cache.microphone_index; + break; + + case ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE: + elliptic_system_configuration_cache.operation_mode = + ucontrol->value.integer.value[0]; + param.type = ESCPT_OPERATION_MODE; + param.operation_mode = + elliptic_system_configuration_cache.operation_mode; + break; + + case ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE_FLAGS: + elliptic_system_configuration_cache.operation_mode_flags = + ucontrol->value.integer.value[0]; + param.type = ESCPT_OPERATION_MODE_FLAGS; + param.operation_mode_flags = + elliptic_system_configuration_cache.operation_mode_flags; + break; + + case ELLIPTIC_SYSTEM_CONFIGURATION_LOG_LEVEL: + elliptic_system_configuration_cache.log_level = + ucontrol->value.integer.value[0]; + param.type = ESCPT_LOG_LEVEL; + param.log_level = elliptic_system_configuration_cache.log_level; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_INPUT_ENABLED: + elliptic_system_configuration_cache.input_enabled = + ucontrol->value.integer.value[0]; + param.type = ESCPT_INPUT_ENABLED; + param.input_enabled = + elliptic_system_configuration_cache.input_enabled; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_OUTPUT_ENABLED: + elliptic_system_configuration_cache.output_enabled = + ucontrol->value.integer.value[0]; + param.type = ESCPT_OUTPUT_ENABLED; + param.output_enabled = + elliptic_system_configuration_cache.output_enabled; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_SUSPEND: + elliptic_system_configuration_cache.engine_suspend = + ucontrol->value.integer.value[0]; + param.type = ESCPT_SUSPEND; + param.engine_suspend = + elliptic_system_configuration_cache.engine_suspend; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_EXTERNAL_EVENT: + elliptic_system_configuration_cache.external_event = + ucontrol->value.integer.value[0]; + param.type = ESCPT_EXTERNAL_EVENT; + param.external_event = + elliptic_system_configuration_cache.external_event; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_CALIBRATION_METHOD: + elliptic_system_configuration_cache.calibration_method = + ucontrol->value.integer.value[0]; + param.type = ESCPT_CALIBRATION_METHOD; + param.calibration_method = + elliptic_system_configuration_cache.calibration_method; + do_gettimeofday(&tv); + param.calibration_timestamp = (int32_t)tv.tv_sec; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_DEBUG_MODE: + elliptic_system_configuration_cache.debug_mode = + ucontrol->value.integer.value[0]; + param.type = ESCPT_DEBUG_MODE; + param.debug_mode = + elliptic_system_configuration_cache.debug_mode; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_CONTEXT: + elliptic_system_configuration_cache.context = + ucontrol->value.integer.value[0]; + param.type = ESCPT_CONTEXT; + param.context = elliptic_system_configuration_cache.context; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_CAPTURE: + elliptic_system_configuration_cache.capture = + ucontrol->value.integer.value[0]; + param.type = ESCPT_CAPTURE; + param.context = elliptic_system_configuration_cache.capture; + break; + case ELLIPTIC_SYSTEM_CONFIGURATION_INPUT_CHANNELS: + elliptic_system_configuration_cache.input_channels = + ucontrol->value.integer.value[0]; + param.type = ESCPT_INPUT_CHANNELS; + param.context = + elliptic_system_configuration_cache.input_channels; + break; + + default: + return -EINVAL; + } + + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)¶m, sizeof(param)); +} + +static const struct snd_kcontrol_new ultrasound_filter_mixer_controls[] = { + SOC_ENUM_EXT("Ultrasound Enable", elliptic_enum[0], + elliptic_ultrasound_enable_get, + elliptic_ultrasound_enable_set), + SOC_ENUM_EXT("Ultrasound RampDown", elliptic_enum[0], + elliptic_ultrasound_rampdown_get, + elliptic_ultrasound_rampdown_set), + SOC_SINGLE_EXT("Ultrasound Latency", ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_LATENCY, 10000, 0, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Sensitivity", ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_SENSITIVITY, 1000000, 0, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_DOUBLE_EXT("Ultrasound Speaker Scaling", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_SPEAKER_SCALING, 0, + 1000000, 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Microphone Index", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_MICROPHONE_INDEX, 20, 0, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Mode", ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE, 255, 0, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Mode Flags", ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE_FLAGS, 256, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Calibration Profile", ELLIPTIC_CALIBRATION, + ELLIPTIC_CALIBRATION_PROFILE, 256, 0, + elliptic_calibration_param_get, + elliptic_calibration_param_put), + SOC_SINGLE_EXT("Ultrasound Gain", ELLIPTIC_CALIBRATION, + ELLIPTIC_ULTRASOUND_GAIN, 256, 0, + elliptic_calibration_param_get, + elliptic_calibration_param_put), + + SOC_SINGLE_EXT("Ultrasound Calibration State", ELLIPTIC_CALIBRATION, + ELLIPTIC_CALIBRATION_STATE, 256, 0, + elliptic_calibration_param_get, + elliptic_calibration_param_put), + + SND_SOC_BYTES_EXT("Ultrasound System Configuration", + ELLIPTIC_SYSTEM_CONFIGURATION_SIZE, + elliptic_system_configuration_get, + elliptic_system_configuration_put), + SND_SOC_BYTES_EXT( + "Ultrasound Calibration Data", ELLIPTIC_CALIBRATION_DATA_SIZE, + elliptic_calibration_data_get, elliptic_calibration_data_put), + SND_SOC_BYTES_EXT("Ultrasound Version", ELLIPTIC_VERSION_INFO_SIZE, + elliptic_version_data_get, elliptic_version_data_put), + SND_SOC_BYTES_EXT("Ultrasound Branch", ELLIPTIC_BRANCH_INFO_MAX_SIZE, + elliptic_branch_data_get, elliptic_branch_data_put), + SND_SOC_BYTES_EXT("Ultrasound Tag", ELLIPTIC_TAG_INFO_SIZE, + elliptic_tag_data_get, elliptic_tag_data_put), + SOC_SINGLE_EXT("Ultrasound Log Level", ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_LOG_LEVEL, 7, 0, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + + SND_SOC_BYTES_EXT("Ultrasound Calibration Ext Data", + ELLIPTIC_CALIBRATION_V2_DATA_SIZE, + elliptic_calibration_v2_data_get, + elliptic_calibration_v2_data_put), + + SND_SOC_BYTES_EXT( + "Ultrasound Diagnostics Data", ELLIPTIC_DIAGNOSTICS_DATA_SIZE, + elliptic_diagnostics_data_get, elliptic_diagnostics_data_put), + + SOC_ENUM_EXT("Ultrasound Diagnostics Request", elliptic_enum[0], + elliptic_ultrasound_diagnostics_get, + elliptic_ultrasound_request_diagnostics), + + SOC_SINGLE_EXT("Ultrasound Custom Setting 0", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_0, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 1", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_1, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 2", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_2, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 3", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_3, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 4", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_4, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 5", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_5, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 6", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_6, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 7", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_7, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 8", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_8, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 9", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_9, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 10", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_10, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 11", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_11, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 12", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_12, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 13", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_13, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 14", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_14, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Custom Setting 15", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_15, + ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, + 0, elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_ENUM_EXT("Ultrasound Tx Port", elliptic_enum[0], + elliptic_ultrasound_tx_port_get, + elliptic_ultrasound_tx_port_set), + SOC_ENUM_EXT("Ultrasound Rx Port", elliptic_enum[0], + elliptic_ultrasound_rx_port_get, + elliptic_ultrasound_rx_port_set), + SOC_SINGLE_EXT("Ultrasound Suspend", ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_SUSPEND, 1, 0, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Input", ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_INPUT_ENABLED, 1, 0, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Output", ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_OUTPUT_ENABLED, 1, 0, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Event", ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_EXTERNAL_EVENT, 256, 0, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Calibration Method", + ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CALIBRATION_METHOD, 256, 0, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + + SND_SOC_BYTES_EXT("Ultrasound ML", ELLIPTIC_ML_DATA_SIZE, + elliptic_ml_data_get, elliptic_ml_data_put), + + SOC_SINGLE_EXT("Ultrasound Debug Mode", ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_DEBUG_MODE, 256, 0, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SOC_SINGLE_EXT("Ultrasound Context", ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CONTEXT, + ELLIPTIC_SYSTEM_CONFIGURATION_MAX_CONTEXT_VALUE, 0, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + SND_SOC_BYTES_EXT("Ultrasound Sensor Data", ELLIPTIC_SENSOR_DATA_SIZE, + elliptic_sensor_data_get, elliptic_sensor_data_put), + + SOC_SINGLE_EXT("Ultrasound Capture", ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_CAPTURE, 256, -1, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + + SOC_SINGLE_EXT("Ultrasound Tx Channels", ELLIPTIC_SYSTEM_CONFIGURATION, + ELLIPTIC_SYSTEM_CONFIGURATION_INPUT_CHANNELS, 16, 0, + elliptic_system_configuration_param_get, + elliptic_system_configuration_param_put), + +}; + +unsigned int elliptic_add_platform_controls(void *platform) +{ + const unsigned int num_controls = + ARRAY_SIZE(ultrasound_filter_mixer_controls); + + if (platform != NULL) { + snd_soc_add_platform_controls( + (struct snd_soc_platform *)platform, + ultrasound_filter_mixer_controls, num_controls); + } else { + EL_PRINT_E("pointer is NULL"); + } + + return num_controls; +} +EXPORT_SYMBOL(elliptic_add_platform_controls); + +int elliptic_trigger_version_msg(void) +{ + int32_t msg[3] = { ESCPT_ENGINE_VERSION, 0, 0 }; + + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)msg, sizeof(msg)); +} + +int elliptic_trigger_branch_msg(void) +{ + int32_t msg[3] = { ESCPT_BUILD_BRANCH, 0, 0 }; + + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)msg, sizeof(msg)); +} + +int elliptic_trigger_tag_msg(void) +{ + int32_t msg[3] = { ESCPT_ENGINE_TAG, 0, 0 }; + + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)msg, sizeof(msg)); +} + +int elliptic_trigger_diagnostics_msg(void) +{ + int32_t msg[3] = { ESCPT_ENGINE_DIAGNOSTICS, 0, 0 }; + + return elliptic_data_write(ELLIPTIC_ULTRASOUND_SET_PARAMS, + (const char *)msg, sizeof(msg)); +} diff --git a/techpack/audio/dsp/elliptic/elliptic_sysfs.c b/techpack/audio/dsp/elliptic/elliptic_sysfs.c new file mode 100644 index 000000000000..27c5aecbc0d1 --- /dev/null +++ b/techpack/audio/dsp/elliptic/elliptic_sysfs.c @@ -0,0 +1,648 @@ +#include +#include +#include +#include +#include +#include +#include +#include "elliptic_version.h" +#include + +#define ELLIPTIC_DIAGNOSTICS_DATA_SECTION_COUNT 16 +#define ELLIPTIC_CALIBRATION_MAX_DISPLAY_COUNT 96 +#define ELLIPTIC_ML_DISPLAY_COUNT 16 + +static int kobject_create_and_add_failed; +static int sysfs_create_group_failed; + +extern struct elliptic_system_configuration_parameters_cache + elliptic_system_configuration_cache; + +static ssize_t calibration_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + ssize_t result; + + struct elliptic_shared_data_block *calibration_obj = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_CALIBRATION_DATA); + + if (calibration_obj == NULL) { + EL_PRINT_E("calibration_obj is NULL"); + return -EINVAL; + } + + if (count > calibration_obj->size) { + EL_PRINT_E("write length %zu larger than buffer", count); + return 0; + } + + memcpy(calibration_obj->buffer, buf, count); + result = (ssize_t)count; + return result; +} + +static ssize_t calibration_v2_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t result; + + struct elliptic_shared_data_block *calibration_obj = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_CALIBRATION_V2_DATA); + + if (calibration_obj == NULL) { + EL_PRINT_E("calibration_obj is NULL"); + return -EINVAL; + } + + if (count > calibration_obj->size) { + EL_PRINT_E("write length %zu larger than buffer", count); + return 0; + } + + memcpy(calibration_obj->buffer, buf, count); + result = (ssize_t)count; + return result; +} + +static ssize_t diagnostics_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + ssize_t result; + + struct elliptic_shared_data_block *diagnostics_obj = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_DIAGNOSTICS_DATA); + + if (diagnostics_obj == NULL) { + EL_PRINT_E("diagnostics_obj is NULL"); + return -EINVAL; + } + + if (count > diagnostics_obj->size) { + EL_PRINT_E("write length %zu larger than buffer", count); + return 0; + } + + memcpy(diagnostics_obj->buffer, buf, count); + result = (ssize_t)count; + return result; +} + +static ssize_t ml_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t result; + + struct elliptic_shared_data_block *ml_obj = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_ML_DATA); + + if (ml_obj == NULL) { + EL_PRINT_E("ml_obj is NULL"); + return -EINVAL; + } + + if (count > ml_obj->size) { + EL_PRINT_E("write length %zu larger than buffer", count); + return 0; + } + + memcpy(ml_obj->buffer, buf, count); + result = (ssize_t)count; + return result; +} + +static ssize_t calibration_show_core(struct device *dev, + struct device_attribute *attr, char *buf, + int pretty) +{ + ssize_t result; + int length; + int i; + uint8_t *caldata; + + struct elliptic_shared_data_block *calibration_obj = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_CALIBRATION_DATA); + + if (kobject_create_and_add_failed) + EL_PRINT_E("kobject_create_and_add_failed"); + + if (sysfs_create_group_failed) + EL_PRINT_E("sysfs_create_group_failed"); + + if (calibration_obj == NULL) { + EL_PRINT_E("calibration_obj is NULL"); + return -EINVAL; + } + + if (calibration_obj->size > PAGE_SIZE) { + EL_PRINT_E("calibration_obj->size > PAGE_SIZE"); + return -EINVAL; + } + + caldata = (uint8_t *)calibration_obj->buffer; + length = 0; + if (pretty) { + if (caldata[0] == 0xDE && caldata[1] == 0xAD) { + length += snprintf(buf + length, PAGE_SIZE - length, + "Calibration Data: not loaded"); + } else { + length += snprintf(buf + length, PAGE_SIZE - length, + "Calibration Data: "); + for (i = 0; i < calibration_obj->size; ++i) + length += snprintf(buf + length, + PAGE_SIZE - length, + "0x%02x ", caldata[i]); + } + } else { + for (i = 0; i < calibration_obj->size; ++i) + length += snprintf(buf + length, PAGE_SIZE - length, + "0x%02x ", caldata[i]); + } + length += snprintf(buf + length, PAGE_SIZE - length, "\n\n"); + result = (ssize_t)length; + return result; +} + +static ssize_t calibration_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return calibration_show_core(dev, attr, buf, 0); +} + +static ssize_t calibration_v2_show_core(struct device *dev, + struct device_attribute *attr, + char *buf, int pretty) +{ + ssize_t result; + int length; + int i; + uint8_t *caldata; + + struct elliptic_shared_data_block *calibration_obj = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_CALIBRATION_V2_DATA); + + if (kobject_create_and_add_failed) + EL_PRINT_E("kobject_create_and_add_failed"); + + if (sysfs_create_group_failed) + EL_PRINT_E("sysfs_create_group_failed"); + + if (calibration_obj == NULL) { + EL_PRINT_E("calibration_obj is NULL"); + return -EINVAL; + } + + if (calibration_obj->size > PAGE_SIZE) { + EL_PRINT_E("calibration_obj->size > PAGE_SIZE"); + return -EINVAL; + } + + caldata = (uint8_t *)calibration_obj->buffer; + length = 0; + if (pretty) { + if (caldata[0] == 0xDE && caldata[1] == 0xAD) { + length += snprintf(buf + length, PAGE_SIZE - length, + "Calibration Ext Data: not loaded"); + } else { + int j = (ELLIPTIC_CALIBRATION_V2_DATA_SIZE >> 2) - 1; + + length += snprintf(buf + length, PAGE_SIZE - length, + "Calibration Ext Data: "); + for (i = 0; i < ELLIPTIC_CALIBRATION_MAX_DISPLAY_COUNT; + ++i) + length += snprintf(buf + length, + PAGE_SIZE - length, + "0x%02x ", caldata[i]); + length += snprintf( + buf + length, PAGE_SIZE - length, + "\nTruncated at %d", + ELLIPTIC_CALIBRATION_MAX_DISPLAY_COUNT); + length += snprintf(buf + length, PAGE_SIZE - length, + "\nmisc: %u %u %u %u %u %u %u %u\n", + caldata[j - 7], caldata[j - 6], + caldata[j - 5], caldata[j - 4], + caldata[j - 3], caldata[j - 2], + caldata[j - 1], caldata[j]); + } + } else { + for (i = 0; i < calibration_obj->size; ++i) + length += snprintf(buf + length, PAGE_SIZE - length, + "0x%02x ", caldata[i]); + } + length += snprintf(buf + length, PAGE_SIZE - length, "\n\n"); + result = (ssize_t)length; + return result; +} + +static ssize_t calibration_v2_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return calibration_v2_show_core(dev, attr, buf, 0); +} + +static ssize_t diagnostics_show_core(struct device *dev, + struct device_attribute *attr, char *buf, + int pretty) +{ + ssize_t result; + int length; + uint32_t *data32; + int i; + + struct elliptic_shared_data_block *diagnostics_obj = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_DIAGNOSTICS_DATA); + + if (kobject_create_and_add_failed) + EL_PRINT_E("kobject_create_and_add_failed"); + + if (sysfs_create_group_failed) + EL_PRINT_E("sysfs_create_group_failed"); + + if (diagnostics_obj == NULL) { + EL_PRINT_E("diagnostics_obj is NULL"); + return -EINVAL; + } + + if (diagnostics_obj->size > PAGE_SIZE) { + EL_PRINT_E("diagnostics_obj->size > PAGE_SIZE"); + return -EINVAL; + } + + length = 0; + data32 = (uint32_t *)diagnostics_obj->buffer; + + if (pretty) { + length += snprintf(buf + length, PAGE_SIZE - length, + "Diagnostics:\n counters:\n"); + for (i = 0; i < ELLIPTIC_DIAGNOSTICS_DATA_SECTION_COUNT; i++) + length += snprintf(buf + length, PAGE_SIZE - length, + " %u %u %u %u\n", data32[4 * i], + data32[4 * i + 1], data32[4 * i + 2], + data32[4 * i + 3]); + } else { + for (i = 0; i < (diagnostics_obj->size >> 4); ++i) + length += snprintf(buf + length, PAGE_SIZE - length, + " %u %u %u %u\n", data32[4 * i], + data32[4 * i + 1], data32[4 * i + 2], + data32[4 * i + 3]); + } + length += snprintf(buf + length, PAGE_SIZE - length, "\n\n"); + result = (ssize_t)length; + return result; +} + +static ssize_t diagnostics_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return diagnostics_show_core(dev, attr, buf, 0); +} + +static ssize_t ml_show_core(struct device *dev, struct device_attribute *attr, + char *buf, int pretty) +{ + ssize_t result; + int length; + int i; + uint32_t *mldata; + + struct elliptic_shared_data_block *ml_obj = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_ML_DATA); + + if (kobject_create_and_add_failed) + EL_PRINT_E("kobject_create_and_add_failed"); + + if (sysfs_create_group_failed) + EL_PRINT_E("sysfs_create_group_failed"); + + if (ml_obj == NULL) { + EL_PRINT_E("ml_obj is NULL"); + return -EINVAL; + } + + if (ml_obj->size > PAGE_SIZE) { + EL_PRINT_E("ml_obj->size > PAGE_SIZE"); + return -EINVAL; + } + + mldata = (uint32_t *)ml_obj->buffer; + length = 0; + if (pretty) { + if (mldata[0] == 0x0 && mldata[1] == 0x0) { + length += snprintf(buf + length, PAGE_SIZE - length, + "ML Data: not loaded"); + } else { + length += snprintf(buf + length, PAGE_SIZE - length, + "ML Data: "); + for (i = 0; i < ELLIPTIC_ML_DISPLAY_COUNT; ++i) + length += snprintf(buf + length, + PAGE_SIZE - length, + "0x%08x ", mldata[i]); + length += snprintf(buf + length, PAGE_SIZE - length, + "\nTruncated at %d", + ELLIPTIC_ML_DISPLAY_COUNT); + } + } else { + int values = ml_obj->size >> 2; + + for (i = 0; i < values; ++i) + length += snprintf(buf + length, PAGE_SIZE - length, + "0x%08x ", mldata[i]); + } + length += snprintf(buf + length, PAGE_SIZE - length, "\n\n"); + result = (ssize_t)length; + return result; +} + +static ssize_t ml_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return ml_show_core(dev, attr, buf, 0); +} + +static ssize_t version_show_core(struct device *dev, + struct device_attribute *attr, char *buf, + int pretty) +{ + ssize_t result; + struct elliptic_engine_version_info *version_info; + int length; + + struct elliptic_shared_data_block *version_obj = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_VERSION_INFO); + + if (kobject_create_and_add_failed) + EL_PRINT_E("kobject_create_and_add_failed"); + + if (sysfs_create_group_failed) + EL_PRINT_E("sysfs_create_group_failed"); + + if (version_obj == NULL) { + EL_PRINT_E("version_obj is NULL"); + return -EINVAL; + } + + if (version_obj->size > PAGE_SIZE) { + EL_PRINT_E("version_obj->size > PAGE_SIZE"); + return -EINVAL; + } + + version_info = + (struct elliptic_engine_version_info *)version_obj->buffer; + + if (pretty) { + if (version_info->major == 0xDE && + version_info->minor == 0xAD) { + length = snprintf(buf, PAGE_SIZE, "Version: unknown\n"); + } else { + length = snprintf( + buf, PAGE_SIZE, "Version: %d.%d.%d.%d\n", + version_info->major, version_info->minor, + version_info->build, version_info->revision); + } + } else { + length = snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n", + version_info->major, version_info->minor, + version_info->build, version_info->revision); + } + result = (ssize_t)length; + return result; +} + +static ssize_t version_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return version_show_core(dev, attr, buf, 0); +} + +static ssize_t branch_show_core(struct device *dev, + struct device_attribute *attr, char *buf, + int pretty) +{ + int length; + + struct elliptic_shared_data_block *branch_obj = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_BRANCH_INFO); + + if (branch_obj == NULL) { + EL_PRINT_E("branch_obj not found"); + return 0; + } + + if (branch_obj->size > PAGE_SIZE) { + EL_PRINT_E("branch_obj->size > PAGE_SIZE"); + return -EINVAL; + } + if (pretty) { + length = snprintf(buf, PAGE_SIZE - 1, "Branch: %s\n", + (const char *)(branch_obj->buffer)); + } else { + length = snprintf(buf, PAGE_SIZE - 1, "%s\n", + (const char *)(branch_obj->buffer)); + } + + return (ssize_t)length; +} + +static ssize_t branch_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return branch_show_core(dev, attr, buf, 0); +} + +static ssize_t tag_show_core(struct device *dev, struct device_attribute *attr, + char *buf, int pretty) +{ + int length; + + struct elliptic_shared_data_block *tag_obj = + elliptic_get_shared_obj(ELLIPTIC_OBJ_ID_TAG_INFO); + + if (tag_obj == NULL) { + EL_PRINT_E("tag_obj not found"); + return 0; + } + + if (tag_obj->size > PAGE_SIZE) { + EL_PRINT_E("tag_obj->size > PAGE_SIZE"); + return -EINVAL; + } + if (pretty) { + length = snprintf(buf, PAGE_SIZE - 1, "Tag: %s\n", + (const char *)(tag_obj->buffer)); + } else { + length = snprintf(buf, PAGE_SIZE - 1, "%s\n", + (const char *)(tag_obj->buffer)); + } + + return (ssize_t)length; +} + +static ssize_t tag_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return tag_show_core(dev, attr, buf, 0); +} + +static ssize_t cache_show(char *buf, int pretty) +{ + struct elliptic_system_configuration_parameters_cache *cache = + &elliptic_system_configuration_cache; + + int length; + + length = snprintf(buf, PAGE_SIZE - 1, "Cache:\n"); + length += snprintf(buf + length, PAGE_SIZE - 1, " mi:%d\n", + cache->microphone_index); + length += snprintf(buf + length, PAGE_SIZE - 1, " om:%d\n", + cache->operation_mode); + length += snprintf(buf + length, PAGE_SIZE - 1, " omf:%d\n", + cache->operation_mode_flags); + length += snprintf(buf + length, PAGE_SIZE - 1, " cs:%d\n", + cache->calibration_state); + length += snprintf(buf + length, PAGE_SIZE - 1, " cp:%d\n", + cache->calibration_profile); + length += snprintf(buf + length, PAGE_SIZE - 1, " ug:%d\n", + cache->ultrasound_gain); + length += snprintf(buf + length, PAGE_SIZE - 1, " ll:%d\n", + cache->log_level); + length += snprintf(buf + length, PAGE_SIZE - 1, " es:%d\n", + cache->engine_suspend); + + return (ssize_t)length; +} + +static ssize_t opmode_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int length; + ssize_t result; + + struct elliptic_system_configuration_parameters_cache *cache = + &elliptic_system_configuration_cache; + + length += snprintf(buf + length, PAGE_SIZE - 1, "%d\n", + cache->operation_mode); + result = (ssize_t)length; + return result; +} + +static ssize_t opmode_flags_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int length; + ssize_t result; + struct elliptic_system_configuration_parameters_cache *cache = + &elliptic_system_configuration_cache; + + length += snprintf(buf + length, PAGE_SIZE - 1, "%d\n", + cache->operation_mode_flags); + result = (ssize_t)length; + return result; +} + +static ssize_t driver_version_show(char *buf) +{ + int length; + + length = snprintf(buf, PAGE_SIZE, "Driver version: %s-%s (%s)\n", + build_name, build_number, build_source_version); + + return (ssize_t)length; +} + +static ssize_t state_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int length = 0; + + length += driver_version_show(buf + length); + length += version_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += branch_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += tag_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += calibration_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += calibration_v2_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += diagnostics_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += ml_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += cache_show(buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + return (ssize_t)length; +} + +static struct device_attribute calibration_attr = __ATTR_RW(calibration); +static struct device_attribute version_attr = __ATTR_RO(version); +static struct device_attribute branch_attr = __ATTR_RO(branch); +static struct device_attribute calibration_v2_attr = __ATTR_RW(calibration_v2); +static struct device_attribute diagnostics_attr = __ATTR_RW(diagnostics); +static struct device_attribute state_attr = __ATTR_RO(state); +static struct device_attribute tag_attr = __ATTR_RO(tag); +static struct device_attribute ml_attr = __ATTR_RW(ml); +static struct device_attribute opmode_attr = __ATTR_RO(opmode); +static struct device_attribute opmode_flags_attr = __ATTR_RO(opmode_flags); + +static struct attribute *elliptic_attrs[] = { + &calibration_attr.attr, + &version_attr.attr, + &branch_attr.attr, + &calibration_v2_attr.attr, + &diagnostics_attr.attr, + &state_attr.attr, + &tag_attr.attr, + &ml_attr.attr, + &opmode_attr.attr, + &opmode_flags_attr.attr, + NULL, +}; + +static struct attribute_group elliptic_attr_group = { + .name = ELLIPTIC_SYSFS_ENGINE_FOLDER, + .attrs = elliptic_attrs, +}; + +static struct kobject *elliptic_sysfs_kobj; + +int elliptic_initialize_sysfs(void) +{ + int err; + + elliptic_sysfs_kobj = kobject_create_and_add(ELLIPTIC_SYSFS_ROOT_FOLDER, + kernel_kobj->parent); + + if (!elliptic_sysfs_kobj) { + kobject_create_and_add_failed = 1; + EL_PRINT_E("failed to create kobj"); + return -ENOMEM; + } + + err = sysfs_create_group(elliptic_sysfs_kobj, &elliptic_attr_group); + + if (err) { + sysfs_create_group_failed = 1; + EL_PRINT_E("failed to create sysfs group"); + kobject_put(elliptic_sysfs_kobj); + return -ENOMEM; + } + + return 0; +} + +void elliptic_cleanup_sysfs(void) +{ + kobject_put(elliptic_sysfs_kobj); +} diff --git a/techpack/audio/dsp/elliptic/elliptic_version.h b/techpack/audio/dsp/elliptic/elliptic_version.h new file mode 100755 index 000000000000..1c8eb9af005d --- /dev/null +++ b/techpack/audio/dsp/elliptic/elliptic_version.h @@ -0,0 +1,8 @@ +#ifndef ELLIPTIC_VERSION_H +#define ELLIPTIC_VERSION_H + +#define build_name "Elliptic.LinuxKernelDriver.VendorDLKM.master" +#define build_number "20181016.1" +#define build_source_version "e5e26691554bba9b1438ec3d7e0cc55dfb296bb8" + +#endif //ELLIPTIC_VERSION_H diff --git a/techpack/audio/dsp/elliptic/io_modules/Makefile b/techpack/audio/dsp/elliptic/io_modules/Makefile new file mode 100644 index 000000000000..66ee789be57f --- /dev/null +++ b/techpack/audio/dsp/elliptic/io_modules/Makefile @@ -0,0 +1,2 @@ +# TODO: add config parameter for which io module to build +#obj-y += userspace/ diff --git a/techpack/audio/dsp/elliptic/io_modules/msm/elliptic_data_msm_io.c b/techpack/audio/dsp/elliptic/io_modules/msm/elliptic_data_msm_io.c new file mode 100644 index 000000000000..c237ad973dfd --- /dev/null +++ b/techpack/audio/dsp/elliptic/io_modules/msm/elliptic_data_msm_io.c @@ -0,0 +1,105 @@ +/** + * Copyright Elliptic Labs + * Copyright (C) 2019 XiaoMi, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +/* includes the file structure, that is, file open read close */ +#include + +/* include the character device, makes cdev avilable */ +#include +#include + +/* includes copy_user vice versa */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#define IO_PING_PONG_BUFFER_SIZE 512 +#define AFE_MSM_RX_PSEUDOPORT_ID 0x8001 +#define AFE_MSM_TX_PSEUDOPORT_ID 0x8002 + +struct elliptic_msm_io_device {}; + +/* static struct elliptic_msm_io_device io_device;*/ + +int elliptic_data_io_initialize(void) +{ + return 0; +} + +int elliptic_data_io_cleanup(void) +{ + return 0; +} +int elliptic_io_open_port(int portid) +{ + if (portid == ULTRASOUND_RX_PORT_ID) + return afe_start_pseudo_port(AFE_MSM_RX_PSEUDOPORT_ID); + else + return afe_start_pseudo_port(AFE_MSM_TX_PSEUDOPORT_ID); +} + +int elliptic_io_close_port(int portid) +{ + if (portid == ULTRASOUND_RX_PORT_ID) + return afe_stop_pseudo_port(AFE_MSM_RX_PSEUDOPORT_ID); + else + return afe_stop_pseudo_port(AFE_MSM_TX_PSEUDOPORT_ID); +} + +int32_t elliptic_data_io_write(uint32_t message_id, const char *data, + size_t data_size) +{ + int32_t result = 0; + + /* msm_pcm_routing_acquire_lock(); */ + + result = ultrasound_apr_set_parameter(ELLIPTIC_PORT_ID, message_id, + (u8 *)data, (int32_t)data_size); + + /* msm_pcm_routing_release_lock();*/ + return result; +} + +int32_t elliptic_data_io_transact(uint32_t message_id, const char *data, + size_t data_size, char *output_data, + size_t output_data_size) +{ + pr_err("%s : unimplemented\n", __func__); + return -EINVAL; +} diff --git a/techpack/audio/dsp/elliptic/io_modules/userspace/Makefile b/techpack/audio/dsp/elliptic/io_modules/userspace/Makefile new file mode 100644 index 000000000000..907ddc20a1d9 --- /dev/null +++ b/techpack/audio/dsp/elliptic/io_modules/userspace/Makefile @@ -0,0 +1,2 @@ +# TODO: add config parameter for which io module to build +#obj-y += elliptic_data_io.o diff --git a/techpack/audio/dsp/elliptic/io_modules/userspace/elliptic_data_userspace_ctrl.c b/techpack/audio/dsp/elliptic/io_modules/userspace/elliptic_data_userspace_ctrl.c new file mode 100644 index 000000000000..24892b7e3faa --- /dev/null +++ b/techpack/audio/dsp/elliptic/io_modules/userspace/elliptic_data_userspace_ctrl.c @@ -0,0 +1,263 @@ +/** + * Copyright Elliptic Labs + * Copyright (C) 2019 XiaoMi, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +/* includes the file structure, that is, file open read close */ +#include + +/* include the character device, makes cdev avilable */ +#include +#include + +/* includes copy_user vice versa */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static dev_t elliptic_userspace_ctrl_major; +#define USERSPACE_CTRL_IO_DEVICE_NAME "elliptic_us_ctrl_io" +struct elliptic_userspace_ctrl_device { + struct cdev cdev; + struct semaphore sem; + int ping_pong_idx; + size_t ping_pong_buffer_size[2]; + uint8_t ping_pong_buffer[2][ELLIPTIC_MSG_BUF_SIZE]; + wait_queue_head_t data_available; + struct mutex data_lock; + atomic_t data_state; +}; + +static struct elliptic_userspace_ctrl_device ctrl_device; + +static uint8_t *get_ping_buffer(struct elliptic_userspace_ctrl_device *dev, + /*out parameter*/ size_t *data_size) +{ + if (data_size != NULL) + *data_size = dev->ping_pong_buffer_size[dev->ping_pong_idx]; + + return dev->ping_pong_buffer[dev->ping_pong_idx]; +} + +static uint8_t *get_pong_buffer(struct elliptic_userspace_ctrl_device *dev, + /*out parameter*/ size_t *data_size) +{ + if (data_size != NULL) + *data_size = dev->ping_pong_buffer_size[1 - dev->ping_pong_idx]; + + return dev->ping_pong_buffer[1 - dev->ping_pong_idx]; +} + +static void set_pong_buffer_size(struct elliptic_userspace_ctrl_device *dev, + size_t data_size) +{ + dev->ping_pong_buffer_size[1 - dev->ping_pong_idx] = data_size; +} + +static void swap_ping_pong(struct elliptic_userspace_ctrl_device *dev) +{ + dev->ping_pong_idx = 1 - dev->ping_pong_idx; +} + +static int device_open(struct inode *inode, struct file *filp) +{ + if (inode->i_cdev != &ctrl_device.cdev) { + pr_warn("elliptic : dev pointer mismatch\n"); + return -ENODEV; /* No such device */ + } + + if (down_interruptible(&ctrl_device.sem) != 0) + return -EEXIST; + EL_PRINT_I("Opened device %s", USERSPACE_CTRL_IO_DEVICE_NAME); + return 0; +} + +static ssize_t device_read(struct file *fp, char __user *buff, + size_t user_buf_length, loff_t *ppos) +{ + size_t bytes_read; + unsigned long copy_result; + uint8_t *ping_buffer; + int result; + + if (user_buf_length < ELLIPTIC_MSG_BUF_SIZE) + EL_PRINT_E("user space buffer user_buf_length too small : %zu", + user_buf_length); + + bytes_read = 0; + copy_result = 0; + ping_buffer = NULL; + + result = wait_event_interruptible( + ctrl_device.data_available, + atomic_read(&ctrl_device.data_state) != 0); + if (result == 0) { + const int state = atomic_read(&ctrl_device.data_state); + + if (state > 0) { + result = mutex_lock_interruptible( + &ctrl_device.data_lock); + if (result == 0) { + swap_ping_pong(&ctrl_device); + + ping_buffer = get_ping_buffer(&ctrl_device, + &bytes_read); + + if (bytes_read > user_buf_length) { + EL_PRINT_E( + "ping buffer size %zu larger than user buffer", + bytes_read); + goto fail; + } + + copy_result = copy_to_user(buff, ping_buffer, + bytes_read); + if (copy_result > 0) { + EL_PRINT_E("Failed copy to user"); + goto fail; + } + + atomic_set(&ctrl_device.data_state, 0); + + mutex_unlock(&ctrl_device.data_lock); + } else if (result == -EINTR) { + EL_PRINT_E("lock interrupted"); + } else { + EL_PRINT_E("lock error = %d", result); + } + } else { + EL_PRINT_W("state = %d", state); + atomic_set(&ctrl_device.data_state, 0); + } + } else if (result == -ERESTARTSYS) { + EL_PRINT_E("interrupted"); + } else { + EL_PRINT_E("wait_event error = %d", result); + } + return bytes_read; +fail: + atomic_set(&ctrl_device.data_state, 0); + mutex_unlock(&ctrl_device.data_lock); + return 0; +} + +static int device_close(struct inode *inode, struct file *filp) +{ + up(&ctrl_device.sem); + EL_PRINT_I("Closed device %s", USERSPACE_CTRL_IO_DEVICE_NAME); + return 0; +} + +static const struct file_operations elliptic_userspace_ctrl_fops = { + .owner = THIS_MODULE, + .open = device_open, + .read = device_read, + .release = device_close, +}; + +int elliptic_userspace_ctrl_driver_init(void) +{ + struct device *device; + dev_t device_number; + int err; + + err = alloc_chrdev_region(&device_number, 0, 1, + USERSPACE_CTRL_IO_DEVICE_NAME); + + if (err < 0) { + pr_err("failed to allocate chrdev region\n"); + return err; + } + + elliptic_userspace_ctrl_major = MAJOR(device_number); + + device_number = MKDEV(elliptic_userspace_ctrl_major, 0); + device = device_create(elliptic_class, NULL, device_number, NULL, + USERSPACE_CTRL_IO_DEVICE_NAME); + + if (IS_ERR(device)) { + unregister_chrdev(elliptic_userspace_ctrl_major, + USERSPACE_CTRL_IO_DEVICE_NAME); + EL_PRINT_E("Failed to create the device\n"); + return PTR_ERR(device); + } + + cdev_init(&ctrl_device.cdev, &elliptic_userspace_ctrl_fops); + ctrl_device.cdev.owner = THIS_MODULE; + err = cdev_add(&ctrl_device.cdev, device_number, 1); + if (err) { + EL_PRINT_W("error %d while trying to add %s%d", err, + ELLIPTIC_DEVICENAME, 0); + return err; + } + + sema_init(&ctrl_device.sem, 1); + mutex_init(&ctrl_device.data_lock); + init_waitqueue_head(&ctrl_device.data_available); + return 0; +} + +void elliptic_userspace_ctrl_driver_exit(void) +{ + BUG_ON(elliptic_class == NULL); + device_destroy(elliptic_class, MKDEV(elliptic_userspace_ctrl_major, 0)); + cdev_del(&ctrl_device.cdev); + unregister_chrdev(elliptic_userspace_ctrl_major, + USERSPACE_CTRL_IO_DEVICE_NAME); + up(&ctrl_device.sem); +} + +int32_t elliptic_userspace_ctrl_write(uint32_t message_id, const char *data, + size_t data_size) +{ + uint8_t *pong_buffer; + + if (data_size > ELLIPTIC_MSG_BUF_SIZE) { + EL_PRINT_E("data size : %zu larger than buf size : %zu", + data_size, (size_t)ELLIPTIC_MSG_BUF_SIZE); + + return -EINVAL; + } + mutex_lock(&ctrl_device.data_lock); + + pong_buffer = get_pong_buffer(&ctrl_device, NULL); + set_pong_buffer_size(&ctrl_device, data_size); + + memcpy(pong_buffer, data, data_size); + wake_up_interruptible(&ctrl_device.data_available); + atomic_set(&ctrl_device.data_state, 1); + mutex_unlock(&ctrl_device.data_lock); + + return 0; +} diff --git a/techpack/audio/dsp/elliptic/io_modules/userspace/elliptic_data_userspace_io.c b/techpack/audio/dsp/elliptic/io_modules/userspace/elliptic_data_userspace_io.c new file mode 100644 index 000000000000..65e860081279 --- /dev/null +++ b/techpack/audio/dsp/elliptic/io_modules/userspace/elliptic_data_userspace_io.c @@ -0,0 +1,143 @@ +/** + * Copyright Elliptic Labs + * Copyright (C) 2019 XiaoMi, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +/* includes the file structure, that is, file open read close */ +#include + +/* include the character device, makes cdev avilable */ +#include +#include + +/* includes copy_user vice versa */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static dev_t elliptic_userspace_major; +#define USERSPACE_IO_DEVICE_NAME "elliptic_us_io" +struct elliptic_userspace_device { + struct cdev cdev; + struct semaphore sem; +}; + +static struct elliptic_userspace_device io_device; + +static int device_open(struct inode *inode, struct file *filp) +{ + if (inode->i_cdev != &io_device.cdev) { + pr_warn("elliptic : dev pointer mismatch\n"); + return -ENODEV; /* No such device */ + } + + if (down_interruptible(&io_device.sem) != 0) + return -EEXIST; + EL_PRINT_I("Opened device %s", USERSPACE_IO_DEVICE_NAME); + return 0; +} + +static ssize_t device_write(struct file *fp, const char __user *buff, + size_t length, loff_t *ppos) +{ + int push_result; + + push_result = elliptic_data_push(ELLIPTIC_ALL_DEVICES, buff, length, + ELLIPTIC_DATA_PUSH_FROM_USERSPACE); + + return push_result == 0 ? (ssize_t)length : (ssize_t)(-1); +} + +static int device_close(struct inode *inode, struct file *filp) +{ + up(&io_device.sem); + EL_PRINT_I("Closed device %s", USERSPACE_IO_DEVICE_NAME); + return 0; +} + +static const struct file_operations elliptic_userspace_fops = { + .owner = THIS_MODULE, + .open = device_open, + .write = device_write, + .release = device_close, +}; + +int elliptic_userspace_io_driver_init(void) +{ + struct device *device; + dev_t device_number; + int err; + + err = alloc_chrdev_region(&device_number, 0, 1, + USERSPACE_IO_DEVICE_NAME); + + if (err < 0) { + pr_err("failed to allocate chrdev region\n"); + return err; + } + + elliptic_userspace_major = MAJOR(device_number); + + device_number = MKDEV(elliptic_userspace_major, 0); + device = device_create(elliptic_class, NULL, device_number, NULL, + USERSPACE_IO_DEVICE_NAME); + + if (IS_ERR(device)) { + unregister_chrdev(elliptic_userspace_major, + USERSPACE_IO_DEVICE_NAME); + pr_err("Failed to create the device\n"); + return PTR_ERR(device); + } + + cdev_init(&io_device.cdev, &elliptic_userspace_fops); + io_device.cdev.owner = THIS_MODULE; + err = cdev_add(&io_device.cdev, device_number, 1); + if (err) { + EL_PRINT_W("error %d while trying to add %s%d", err, + ELLIPTIC_DEVICENAME, 0); + return err; + } + + sema_init(&io_device.sem, 1); + return 0; +} + +void elliptic_userspace_io_driver_exit(void) +{ + BUG_ON(elliptic_class == NULL); + device_destroy(elliptic_class, MKDEV(elliptic_userspace_major, 0)); + cdev_del(&io_device.cdev); + unregister_chrdev(elliptic_userspace_major, USERSPACE_IO_DEVICE_NAME); + up(&io_device.sem); +} diff --git a/techpack/audio/dsp/elliptic/io_modules/userspace_test/Makefile b/techpack/audio/dsp/elliptic/io_modules/userspace_test/Makefile new file mode 100644 index 000000000000..907ddc20a1d9 --- /dev/null +++ b/techpack/audio/dsp/elliptic/io_modules/userspace_test/Makefile @@ -0,0 +1,2 @@ +# TODO: add config parameter for which io module to build +#obj-y += elliptic_data_io.o diff --git a/techpack/audio/dsp/elliptic/io_modules/userspace_test/elliptic_data_io.c b/techpack/audio/dsp/elliptic/io_modules/userspace_test/elliptic_data_io.c new file mode 100644 index 000000000000..8f7c370c5d72 --- /dev/null +++ b/techpack/audio/dsp/elliptic/io_modules/userspace_test/elliptic_data_io.c @@ -0,0 +1,121 @@ +/** + * Copyright Elliptic Labs + * Copyright (C) 2019 XiaoMi, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define USE_IRQ 11 + +static struct task_struct *simulating_task; +static atomic_t cancel; + +struct elliptic_data_io_state {}; +#define BUFFER_SIZE 128 + +static int32_t output_buffer[BUFFER_SIZE]; + +irqreturn_t irq_handler(int irq, void *dev_id) +{ + int result; + + result = elliptic_data_push(ELLIPTIC_ALL_DEVICES, + (const char *)output_buffer, + BUFFER_SIZE * sizeof(int32_t)); + return 0; +} + +static void fill_buffer(int32_t *buffer, size_t len, int32_t value) +{ + size_t i; + + for (i = 0; i < len; ++i) + buffer[i] = value; +} + +int simulating_thread(void *context) +{ + static int32_t count; + int result; + + count = 0; + msleep(100); + + pr_debug("%s\n", __func__); + while (atomic_read(&cancel) == 0) { + if (kthread_should_stop()) + do_exit(0); + + fill_buffer(output_buffer, BUFFER_SIZE, count); + + ++count; + if (result != 0) { + pr_warn("failed to push data\n"); + } + asm("int $0x3B"); /* Corresponding to irq 11 */ + msleep(0); + } + return 0; +} + +int32_t elliptic_data_io_write(uint32_t message_id, const char *data, + size_t data_size) +{ + return 0; +} + +int32_t elliptic_data_io_transact(uint32_t message_id, const char *data, + size_t data_size, char *output_data, + size_t output_data_size) +{ + return 0; +} + +void elliptic_data_io_cancel(struct elliptic_data *elliptic_data) +{ + atomic_set(&elliptic_data->abort_io, 1); + wake_up_interruptible(&elliptic_data->fifo_isr_not_empty); +} + +int elliptic_data_io_initialize(void) +{ + pr_debug("%s\n", __func__); + atomic_set(&cancel, 0); + simulating_task = + kthread_run(&simulating_thread, NULL, "el_simulating_thread"); + + if (request_irq(USE_IRQ, irq_handler, IRQF_SHARED, "my_device", + (void *)(irq_handler))) { + pr_debug("my_device: cannot register IRQ "); + return -EPERM; + } + + return 0; +} + +int elliptic_data_io_cleanup(void) +{ + free_irq(USE_IRQ, (void *)(irq_handler)); + kthread_stop(simulating_task); + atomic_set(&cancel, 1); + msleep(200); + return 0; +} diff --git a/techpack/audio/dsp/mius/Makefile b/techpack/audio/dsp/mius/Makefile new file mode 100644 index 000000000000..1a0cd5f4608b --- /dev/null +++ b/techpack/audio/dsp/mius/Makefile @@ -0,0 +1,28 @@ +ccflags-y := -I$(src) -Wall -Werror +IO_MODULE := msm + +# EXTRA_CFLAGS += -DDEBUG + +# Need to add include paths: +LINUXINCLUDE += \ + -I$(srctree)techpack/audio/include/dsp + -I$(srctree)techpack/audio/include/uapi + -I$(srctree)techpack/aduio/include + +obj-y += mius.o +obj-y += mius_mixer_controls.o +obj-y += io_modules/$(IO_MODULE)/mius_data_$(IO_MODULE)_io.o +obj-y += io_modules/userspace/mius_data_userspace_io.o +obj-y += io_modules/userspace/mius_data_userspace_ctrl.o +obj-y += mius_sysfs.o + +# mius_driver-y := mius.o +# mius_driver-y += io_modules/$(IO_MODULE)/mius_data_io.o +# mius_driver-y += mixer_controls/$(MIXER_MODULE)/mius_mixer_controls.o +# mius_driver-y += mius_sysfs.o + +# .PHONY: clean +# all: +# make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules +# clean: +# rm *.o *.ko diff --git a/techpack/audio/dsp/mius/io_modules/Makefile b/techpack/audio/dsp/mius/io_modules/Makefile new file mode 100644 index 000000000000..66ee789be57f --- /dev/null +++ b/techpack/audio/dsp/mius/io_modules/Makefile @@ -0,0 +1,2 @@ +# TODO: add config parameter for which io module to build +#obj-y += userspace/ diff --git a/techpack/audio/dsp/mius/io_modules/msm/mius_data_msm_io.c b/techpack/audio/dsp/mius/io_modules/msm/mius_data_msm_io.c new file mode 100644 index 000000000000..fbfcb613d82c --- /dev/null +++ b/techpack/audio/dsp/mius/io_modules/msm/mius_data_msm_io.c @@ -0,0 +1,105 @@ +/** + * Copyright MI + * Copyright (C) 2019 XiaoMi, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +/* includes the file structure, that is, file open read close */ +#include + +/* include the character device, makes cdev avilable */ +#include +#include + +/* includes copy_user vice versa */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#define IO_PING_PONG_BUFFER_SIZE 512 +#define AFE_MSM_RX_PSEUDOPORT_ID 0x8001 +#define AFE_MSM_TX_PSEUDOPORT_ID 0x8002 + +struct mius_msm_io_device {}; + +/* static struct mius_msm_io_device io_device;*/ + +int mius_data_io_initialize(void) +{ + return 0; +} + +int mius_data_io_cleanup(void) +{ + return 0; +} +int mius_io_open_port(int portid) +{ + if (portid == ULTRASOUND_RX_PORT_ID) + return afe_start_pseudo_port(AFE_MSM_RX_PSEUDOPORT_ID); + else + return afe_start_pseudo_port(AFE_MSM_TX_PSEUDOPORT_ID); +} + +int mius_io_close_port(int portid) +{ + if (portid == ULTRASOUND_RX_PORT_ID) + return afe_stop_pseudo_port(AFE_MSM_RX_PSEUDOPORT_ID); + else + return afe_stop_pseudo_port(AFE_MSM_TX_PSEUDOPORT_ID); +} + +int32_t mius_data_io_write(uint32_t message_id, const char *data, + size_t data_size) +{ + int32_t result = 0; + + /* msm_pcm_routing_acquire_lock(); */ + + result = mi_ultrasound_apr_set_parameter( + MIUS_PORT_ID, message_id, (u8 *)data, (int32_t)data_size); + + /* msm_pcm_routing_release_lock();*/ + return result; +} + +int32_t mius_data_io_transact(uint32_t message_id, const char *data, + size_t data_size, char *output_data, + size_t output_data_size) +{ + pr_err("%s : unimplemented\n", __func__); + return -EINVAL; +} diff --git a/techpack/audio/dsp/mius/io_modules/userspace/Makefile b/techpack/audio/dsp/mius/io_modules/userspace/Makefile new file mode 100644 index 000000000000..34d76dde1eb9 --- /dev/null +++ b/techpack/audio/dsp/mius/io_modules/userspace/Makefile @@ -0,0 +1,2 @@ +# TODO: add config parameter for which io module to build +#obj-y += mius_data_io.o diff --git a/techpack/audio/dsp/mius/io_modules/userspace/mius_data_userspace_ctrl.c b/techpack/audio/dsp/mius/io_modules/userspace/mius_data_userspace_ctrl.c new file mode 100644 index 000000000000..ea81488cf492 --- /dev/null +++ b/techpack/audio/dsp/mius/io_modules/userspace/mius_data_userspace_ctrl.c @@ -0,0 +1,263 @@ +/** + * Copyright MI + * Copyright (C) 2019 XiaoMi, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +/* includes the file structure, that is, file open read close */ +#include + +/* include the character device, makes cdev avilable */ +#include +#include + +/* includes copy_user vice versa */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static dev_t mius_userspace_ctrl_major; +#define USERSPACE_CTRL_IO_DEVICE_NAME "mius_us_ctrl_io" +struct mius_userspace_ctrl_device { + struct cdev cdev; + struct semaphore sem; + int ping_pong_idx; + size_t ping_pong_buffer_size[2]; + uint8_t ping_pong_buffer[2][MIUS_MSG_BUF_SIZE]; + wait_queue_head_t data_available; + struct mutex data_lock; + atomic_t data_state; +}; + +static struct mius_userspace_ctrl_device ctrl_device; + +static uint8_t *get_ping_buffer(struct mius_userspace_ctrl_device *dev, + /*out parameter*/ size_t *data_size) +{ + if (data_size != NULL) + *data_size = dev->ping_pong_buffer_size[dev->ping_pong_idx]; + + return dev->ping_pong_buffer[dev->ping_pong_idx]; +} + +static uint8_t *get_pong_buffer(struct mius_userspace_ctrl_device *dev, + /*out parameter*/ size_t *data_size) +{ + if (data_size != NULL) + *data_size = dev->ping_pong_buffer_size[1 - dev->ping_pong_idx]; + + return dev->ping_pong_buffer[1 - dev->ping_pong_idx]; +} + +static void set_pong_buffer_size(struct mius_userspace_ctrl_device *dev, + size_t data_size) +{ + dev->ping_pong_buffer_size[1 - dev->ping_pong_idx] = data_size; +} + +static void swap_ping_pong(struct mius_userspace_ctrl_device *dev) +{ + dev->ping_pong_idx = 1 - dev->ping_pong_idx; +} + +static int device_open(struct inode *inode, struct file *filp) +{ + if (inode->i_cdev != &ctrl_device.cdev) { + pr_warn("mius : dev pointer mismatch\n"); + return -ENODEV; /* No such device */ + } + + if (down_interruptible(&ctrl_device.sem) != 0) + return -EEXIST; + MI_PRINT_I("Opened device %s", USERSPACE_CTRL_IO_DEVICE_NAME); + return 0; +} + +static ssize_t device_read(struct file *fp, char __user *buff, + size_t user_buf_length, loff_t *ppos) +{ + size_t bytes_read; + unsigned long copy_result; + uint8_t *ping_buffer; + int result; + + if (user_buf_length < MIUS_MSG_BUF_SIZE) + MI_PRINT_E("user space buffer user_buf_length too small : %zu", + user_buf_length); + + bytes_read = 0; + copy_result = 0; + ping_buffer = NULL; + + result = wait_event_interruptible( + ctrl_device.data_available, + atomic_read(&ctrl_device.data_state) != 0); + if (result == 0) { + const int state = atomic_read(&ctrl_device.data_state); + + if (state > 0) { + result = mutex_lock_interruptible( + &ctrl_device.data_lock); + if (result == 0) { + swap_ping_pong(&ctrl_device); + + ping_buffer = get_ping_buffer(&ctrl_device, + &bytes_read); + + if (bytes_read > user_buf_length) { + MI_PRINT_E( + "ping buffer size %zu larger than user buffer", + bytes_read); + goto fail; + } + + copy_result = copy_to_user(buff, ping_buffer, + bytes_read); + if (copy_result > 0) { + MI_PRINT_E("Failed copy to user"); + goto fail; + } + + atomic_set(&ctrl_device.data_state, 0); + + mutex_unlock(&ctrl_device.data_lock); + } else if (result == -EINTR) { + MI_PRINT_E("lock interrupted"); + } else { + MI_PRINT_E("lock error = %d", result); + } + } else { + MI_PRINT_W("state = %d", state); + atomic_set(&ctrl_device.data_state, 0); + } + } else if (result == -ERESTARTSYS) { + MI_PRINT_E("interrupted"); + } else { + MI_PRINT_E("wait_event error = %d", result); + } + return bytes_read; +fail: + atomic_set(&ctrl_device.data_state, 0); + mutex_unlock(&ctrl_device.data_lock); + return 0; +} + +static int device_close(struct inode *inode, struct file *filp) +{ + up(&ctrl_device.sem); + MI_PRINT_I("Closed device %s", USERSPACE_CTRL_IO_DEVICE_NAME); + return 0; +} + +static const struct file_operations mius_userspace_ctrl_fops = { + .owner = THIS_MODULE, + .open = device_open, + .read = device_read, + .release = device_close, +}; + +int mius_userspace_ctrl_driver_init(void) +{ + struct device *device; + dev_t device_number; + int err; + + err = alloc_chrdev_region(&device_number, 0, 1, + USERSPACE_CTRL_IO_DEVICE_NAME); + + if (err < 0) { + pr_err("failed to allocate chrdev region\n"); + return err; + } + + mius_userspace_ctrl_major = MAJOR(device_number); + + device_number = MKDEV(mius_userspace_ctrl_major, 0); + device = device_create(mius_class, NULL, device_number, NULL, + USERSPACE_CTRL_IO_DEVICE_NAME); + + if (IS_ERR(device)) { + unregister_chrdev(mius_userspace_ctrl_major, + USERSPACE_CTRL_IO_DEVICE_NAME); + MI_PRINT_E("Failed to create the device\n"); + return PTR_ERR(device); + } + + cdev_init(&ctrl_device.cdev, &mius_userspace_ctrl_fops); + ctrl_device.cdev.owner = THIS_MODULE; + err = cdev_add(&ctrl_device.cdev, device_number, 1); + if (err) { + MI_PRINT_W("error %d while trying to add %s%d", err, + MIUS_DEVICENAME, 0); + return err; + } + + sema_init(&ctrl_device.sem, 1); + mutex_init(&ctrl_device.data_lock); + init_waitqueue_head(&ctrl_device.data_available); + return 0; +} + +void mius_userspace_ctrl_driver_exit(void) +{ + BUG_ON(mius_class == NULL); + device_destroy(mius_class, MKDEV(mius_userspace_ctrl_major, 0)); + cdev_del(&ctrl_device.cdev); + unregister_chrdev(mius_userspace_ctrl_major, + USERSPACE_CTRL_IO_DEVICE_NAME); + up(&ctrl_device.sem); +} + +int32_t mius_userspace_ctrl_write(uint32_t message_id, const char *data, + size_t data_size) +{ + uint8_t *pong_buffer; + + if (data_size > MIUS_MSG_BUF_SIZE) { + MI_PRINT_E("data size : %zu larger than buf size : %zu", + data_size, (size_t)MIUS_MSG_BUF_SIZE); + + return -EINVAL; + } + mutex_lock(&ctrl_device.data_lock); + + pong_buffer = get_pong_buffer(&ctrl_device, NULL); + set_pong_buffer_size(&ctrl_device, data_size); + + memcpy(pong_buffer, data, data_size); + wake_up_interruptible(&ctrl_device.data_available); + atomic_set(&ctrl_device.data_state, 1); + mutex_unlock(&ctrl_device.data_lock); + + return 0; +} diff --git a/techpack/audio/dsp/mius/io_modules/userspace/mius_data_userspace_io.c b/techpack/audio/dsp/mius/io_modules/userspace/mius_data_userspace_io.c new file mode 100644 index 000000000000..a87e1b6357c0 --- /dev/null +++ b/techpack/audio/dsp/mius/io_modules/userspace/mius_data_userspace_io.c @@ -0,0 +1,143 @@ +/** + * Copyright MI + * Copyright (C) 2019 XiaoMi, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +/* includes the file structure, that is, file open read close */ +#include + +/* include the character device, makes cdev avilable */ +#include +#include + +/* includes copy_user vice versa */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static dev_t mius_userspace_major; +#define USERSPACE_IO_DEVICE_NAME "mius_us_io" +struct mius_userspace_device { + struct cdev cdev; + struct semaphore sem; +}; + +static struct mius_userspace_device io_device; + +static int device_open(struct inode *inode, struct file *filp) +{ + if (inode->i_cdev != &io_device.cdev) { + pr_warn("mius : dev pointer mismatch\n"); + return -ENODEV; /* No such device */ + } + + if (down_interruptible(&io_device.sem) != 0) + return -EEXIST; + MI_PRINT_I("Opened device %s", USERSPACE_IO_DEVICE_NAME); + return 0; +} + +static ssize_t device_write(struct file *fp, const char __user *buff, + size_t length, loff_t *ppos) +{ + int push_result; + + push_result = mius_data_push(MIUS_ALL_DEVICES, buff, length, + MIUS_DATA_PUSH_FROM_USERSPACE); + + return push_result == 0 ? (ssize_t)length : (ssize_t)(-1); +} + +static int device_close(struct inode *inode, struct file *filp) +{ + up(&io_device.sem); + MI_PRINT_I("Closed device %s", USERSPACE_IO_DEVICE_NAME); + return 0; +} + +static const struct file_operations mius_userspace_fops = { + .owner = THIS_MODULE, + .open = device_open, + .write = device_write, + .release = device_close, +}; + +int mius_userspace_io_driver_init(void) +{ + struct device *device; + dev_t device_number; + int err; + + err = alloc_chrdev_region(&device_number, 0, 1, + USERSPACE_IO_DEVICE_NAME); + + if (err < 0) { + pr_err("failed to allocate chrdev region\n"); + return err; + } + + mius_userspace_major = MAJOR(device_number); + + device_number = MKDEV(mius_userspace_major, 0); + device = device_create(mius_class, NULL, device_number, NULL, + USERSPACE_IO_DEVICE_NAME); + + if (IS_ERR(device)) { + unregister_chrdev(mius_userspace_major, + USERSPACE_IO_DEVICE_NAME); + pr_err("Failed to create the device\n"); + return PTR_ERR(device); + } + + cdev_init(&io_device.cdev, &mius_userspace_fops); + io_device.cdev.owner = THIS_MODULE; + err = cdev_add(&io_device.cdev, device_number, 1); + if (err) { + MI_PRINT_W("error %d while trying to add %s%d", err, + MIUS_DEVICENAME, 0); + return err; + } + + sema_init(&io_device.sem, 1); + return 0; +} + +void mius_userspace_io_driver_exit(void) +{ + BUG_ON(mius_class == NULL); + device_destroy(mius_class, MKDEV(mius_userspace_major, 0)); + cdev_del(&io_device.cdev); + unregister_chrdev(mius_userspace_major, USERSPACE_IO_DEVICE_NAME); + up(&io_device.sem); +} diff --git a/techpack/audio/dsp/mius/io_modules/userspace_test/Makefile b/techpack/audio/dsp/mius/io_modules/userspace_test/Makefile new file mode 100644 index 000000000000..34d76dde1eb9 --- /dev/null +++ b/techpack/audio/dsp/mius/io_modules/userspace_test/Makefile @@ -0,0 +1,2 @@ +# TODO: add config parameter for which io module to build +#obj-y += mius_data_io.o diff --git a/techpack/audio/dsp/mius/io_modules/userspace_test/mius_data_io.c b/techpack/audio/dsp/mius/io_modules/userspace_test/mius_data_io.c new file mode 100644 index 000000000000..7f4f60037912 --- /dev/null +++ b/techpack/audio/dsp/mius/io_modules/userspace_test/mius_data_io.c @@ -0,0 +1,120 @@ +/** + * Copyright MI + * Copyright (C) 2019 XiaoMi, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define USE_IRQ 11 + +static struct task_struct *simulating_task; +static atomic_t cancel; + +struct mius_data_io_state {}; +#define BUFFER_SIZE 128 + +static int32_t output_buffer[BUFFER_SIZE]; + +irqreturn_t irq_handler(int irq, void *dev_id) +{ + int result; + + result = mius_data_push(MIUS_ALL_DEVICES, (const char *)output_buffer, + BUFFER_SIZE * sizeof(int32_t)); + return 0; +} + +static void fill_buffer(int32_t *buffer, size_t len, int32_t value) +{ + size_t i; + + for (i = 0; i < len; ++i) + buffer[i] = value; +} + +int simulating_thread(void *context) +{ + static int32_t count; + int result; + + count = 0; + msleep(100); + + pr_debug("%s\n", __func__); + while (atomic_read(&cancel) == 0) { + if (kthread_should_stop()) + do_exit(0); + + fill_buffer(output_buffer, BUFFER_SIZE, count); + + ++count; + if (result != 0) { + pr_warn("failed to push data\n"); + } + asm("int $0x3B"); /* Corresponding to irq 11 */ + msleep(0); + } + return 0; +} + +int32_t mius_data_io_write(uint32_t message_id, const char *data, + size_t data_size) +{ + return 0; +} + +int32_t mius_data_io_transact(uint32_t message_id, const char *data, + size_t data_size, char *output_data, + size_t output_data_size) +{ + return 0; +} + +void mius_data_io_cancel(struct mius_data *mius_data) +{ + atomic_set(&mius_data->abort_io, 1); + wake_up_interruptible(&mius_data->fifo_isr_not_empty); +} + +int mius_data_io_initialize(void) +{ + pr_debug("%s\n", __func__); + atomic_set(&cancel, 0); + simulating_task = + kthread_run(&simulating_thread, NULL, "el_simulating_thread"); + + if (request_irq(USE_IRQ, irq_handler, IRQF_SHARED, "my_device", + (void *)(irq_handler))) { + pr_debug("my_device: cannot register IRQ "); + return -EPERM; + } + + return 0; +} + +int mius_data_io_cleanup(void) +{ + free_irq(USE_IRQ, (void *)(irq_handler)); + kthread_stop(simulating_task); + atomic_set(&cancel, 1); + msleep(200); + return 0; +} diff --git a/techpack/audio/dsp/mius/mius.c b/techpack/audio/dsp/mius/mius.c new file mode 100644 index 000000000000..6f8d13a6671e --- /dev/null +++ b/techpack/audio/dsp/mius/mius.c @@ -0,0 +1,752 @@ +/** +* Copyright MI +* Copyright (C) 2019 XiaoMi, Inc. +* +*/ +/* #define DEBUG */ +#include +#include +#include +/* includes the file structure, that is, file open read close */ +#include + +/* include the character device, makes cdev avilable */ +#include +#include + +/* includes copy_user vice versa */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Alternative mechanism to load calibration data. +* Read calibration data during driver initialization +* and send message to the DSP +* +* #define MIUS_LOAD_CALIBRATION_DATA_FROM_FILESYSTEM 1 +*/ +#ifdef MIUS_LOAD_CALIBRATION_DATA_FROM_FILESYSTEM +#include +#include +#include +#endif + +static struct mius_device *mius_devices; + +/* Global variable for the device class*/ +struct class *mius_class; + +typedef uint32_t el_fifo_size_t; + +/* Major number provided by the kernel*/ +static dev_t mius_major; + +static struct wakeup_source *wake_source; + +void mius_data_cancel(struct mius_data *mius_data) +{ + atomic_set(&mius_data->abort_io, 1); + wake_up_interruptible(&mius_data->fifo_isr_not_empty); +} + +void mius_data_reset_debug_counters(struct mius_data *mius_data) +{ + mius_data->isr_fifo_discard = 0; +} + +void mius_data_print_debug_counters(struct mius_data *mius_data) +{ + if (mius_data->isr_fifo_discard > 0) { + MI_PRINT_E("isr fifo discarded %u frames", + mius_data->isr_fifo_discard); + } + + if (mius_data->userspace_read_total != mius_data->isr_write_total) { + MI_PRINT_I("user space reads / isr writes : %u / %u", + mius_data->userspace_read_total, + mius_data->isr_write_total); + } + + MI_PRINT_I("total isr fifo discarded frame count : %u", + mius_data->isr_fifo_discard_total); +} + +void mius_data_update_debug_counters(struct mius_data *mius_data) +{ + mius_data->isr_fifo_discard_total += mius_data->isr_fifo_discard; +} + +/* spin lock for isr must be held prior to calling */ +static void mius_data_flush_isr_fifo(struct mius_data *mius_data) +{ + kfifo_reset(&mius_data->fifo_isr); +} + +/* spin lock for isr must be held prior to calling */ +static void mius_data_isr_fifo_pop(struct mius_data *mius_data, size_t size) +{ + unsigned int fifo_result; + static uint8_t temp_buffer[MIUS_MSG_BUF_SIZE]; + + if (size > MIUS_MSG_BUF_SIZE) + MI_PRINT_E("pop size %zu too large", size); + + fifo_result = kfifo_out(&mius_data->fifo_isr, temp_buffer, size); + + if (size != fifo_result) + MI_PRINT_E("failed to pop element"); +} + +int mius_notify_gain_change_msg(int component_id, int gaindb) +{ + int32_t msg[3] = { MSC_COMPONENT_GAIN_CHANGE, component_id, gaindb }; + + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, (const char *)msg, + sizeof(msg)); +} + +/* inode refers to the actual file on disk */ +static int device_open(struct inode *inode, struct file *filp) +{ + unsigned int major; + unsigned int minor; + struct mius_device *dev; + struct mius_data *mius_data; + + major = imajor(inode); + minor = iminor(inode); + + if (major != mius_major || minor < 0 || minor >= MIUS_NUM_DEVICES) { + MI_PRINT_W("no device found with minor=%d and major=%d", major, + minor); + return -ENODEV; /* No such device */ + } + + dev = NULL; + dev = &mius_devices[minor]; + filp->private_data = dev; + + if (inode->i_cdev != &dev->cdev) { + MI_PRINT_W("dev pointer mismatch"); + return -ENODEV; /* No such device */ + } + + if (down_interruptible(&dev->sem) != 0) { + MI_PRINT_E("the device has been opened, unable to open lock"); + return -EINVAL; + } + + mius_data = &dev->el_data; + spin_lock(&mius_data->fifo_isr_spinlock); + mius_data_flush_isr_fifo(mius_data); + spin_unlock(&mius_data->fifo_isr_spinlock); + + atomic_set(&mius_data->abort_io, 0); + mius_data_reset_debug_counters(mius_data); + + MI_PRINT_I("Opened device mius%u", minor); + dev->opened = 1; + return 0; +} + +int mius_data_initialize(struct mius_data *mius_data, size_t queue_size, + unsigned int wakeup_timeout, int id) +{ + int is_power_of_two; + + is_power_of_two = (queue_size != 0) && !(queue_size & (queue_size - 1)); + + if (is_power_of_two != 1) { + MI_PRINT_E("non power of 2 fifo size"); + return -EINVAL; + } + + if (kfifo_alloc(&mius_data->fifo_isr, queue_size, GFP_KERNEL) != 0) { + MI_PRINT_E("failed to allocate fifo isr"); + return -EINVAL; + } + + atomic_set(&mius_data->abort_io, 0); + spin_lock_init(&mius_data->fifo_isr_spinlock); + + mius_data->wakeup_timeout = wakeup_timeout; + + mutex_init(&mius_data->user_buffer_lock); + init_waitqueue_head(&mius_data->fifo_isr_not_empty); + + return 0; +} + +int mius_data_cleanup(struct mius_data *mius_data) +{ + spin_unlock(&mius_data->fifo_isr_spinlock); + kfifo_free(&mius_data->fifo_isr); + return 0; +} + +size_t mius_data_pop(struct mius_data *mius_data, char __user *user_buffer, + size_t buffer_size) +{ + int result; + unsigned long num_copied; + unsigned int fifo_result; + unsigned long flags; + + if (buffer_size < MIUS_MSG_BUF_SIZE) { + MI_PRINT_E("buffer_size : %lu smaller than %lu", buffer_size, + (size_t)MIUS_MSG_BUF_SIZE); + return 0; + } + + result = wait_event_interruptible( + mius_data->fifo_isr_not_empty, + (kfifo_is_empty(&mius_data->fifo_isr) == 0) || + (atomic_read(&mius_data->abort_io) == 1)); + + if (atomic_read(&mius_data->abort_io) == 1) { + atomic_set(&mius_data->abort_io, 0); + MI_PRINT_D("pop cancelled"); + return 0; + } + + if (result == 0) { + spin_lock_irqsave(&mius_data->fifo_isr_spinlock, flags); + + fifo_result = kfifo_out(&mius_data->fifo_isr, + mius_data->isr_swap_buffer, + MIUS_MSG_BUF_SIZE); + + spin_unlock_irqrestore(&mius_data->fifo_isr_spinlock, flags); + + if (fifo_result == 0) { + MI_PRINT_E("failed to copy: fifo isr -> swap buffer %u", + fifo_result); + return 0; + } + + mutex_lock(&mius_data->user_buffer_lock); + + num_copied = + copy_to_user(user_buffer, mius_data->isr_swap_buffer, + MIUS_MSG_BUF_SIZE); + + mutex_unlock(&mius_data->user_buffer_lock); + + if (num_copied != 0) { + MI_PRINT_E("failed copy to user"); + return 0; + } + ++mius_data->userspace_read_total; + } else { + if (-ERESTARTSYS == result) + MI_PRINT_I("wait interrupted"); + else + MI_PRINT_E("wait error = %d", result); + + return 0; + } + + return (size_t)MIUS_MSG_BUF_SIZE; +} + +/* push data to specific device or all devices */ +int mius_data_push(int deviceid, const char *buffer, size_t buffer_size, + mius_data_push_t data_source) +{ + size_t available_space; + size_t space_required; + size_t zeros_to_pad; + unsigned int copied_from_user; + int copy_from_user_result; + int err; + int i; + int i_max; + + unsigned long flags; + struct mius_device *device; + struct mius_data *mius_data; + unsigned int fifo_result; + static uint8_t zero_pad_buffer[MIUS_MSG_BUF_SIZE]; + + err = 0; + fifo_result = 0; + copied_from_user = 0; + copy_from_user_result = 0; + if (buffer_size > MIUS_MSG_BUF_SIZE) + return -EINVAL; + + zeros_to_pad = MIUS_MSG_BUF_SIZE - buffer_size; + + i = 0; + i_max = MIUS_NUM_DEVICES; + + if (deviceid != MIUS_ALL_DEVICES) { + /* Copy to specific device */ + i = deviceid; + i_max = i + 1; + } + + for (; i < i_max; ++i) { + device = &mius_devices[i]; + mius_data = &device->el_data; + + if ((!device->opened)) + continue; + + available_space = kfifo_avail(&mius_data->fifo_isr); + space_required = MIUS_MSG_BUF_SIZE; + + spin_lock_irqsave(&mius_data->fifo_isr_spinlock, flags); + + if (available_space < space_required) { + ++mius_data->isr_fifo_discard; + mius_data_isr_fifo_pop(mius_data, MIUS_MSG_BUF_SIZE); + } + + if (data_source == MIUS_DATA_PUSH_FROM_KERNEL) { + fifo_result = kfifo_in(&mius_data->fifo_isr, buffer, + buffer_size); + + if (fifo_result == 0) { + spin_unlock_irqrestore( + &mius_data->fifo_isr_spinlock, flags); + continue; + } + } else if (data_source == MIUS_DATA_PUSH_FROM_USERSPACE) { + copy_from_user_result = + kfifo_from_user(&mius_data->fifo_isr, buffer, + buffer_size, &copied_from_user); + + if (-EFAULT == copy_from_user_result) { + spin_unlock_irqrestore( + &mius_data->fifo_isr_spinlock, flags); + continue; + } + } + + if (zeros_to_pad > 0) { + fifo_result = kfifo_in(&mius_data->fifo_isr, + zero_pad_buffer, zeros_to_pad); + + if (fifo_result == 0) { + mius_data_isr_fifo_pop(mius_data, buffer_size); + + spin_unlock_irqrestore( + &mius_data->fifo_isr_spinlock, flags); + + ++mius_data->isr_fifo_discard; + continue; + } + } + + ++mius_data->isr_write_total; + spin_unlock_irqrestore(&mius_data->fifo_isr_spinlock, flags); + wake_up_interruptible(&mius_data->fifo_isr_not_empty); + __pm_wakeup_event(wake_source, mius_data->wakeup_timeout); + } + + return err; +} + +int mius_open_port(int portid) +{ + return mius_io_open_port(portid); +} + +int mius_close_port(int portid) +{ + return mius_io_close_port(portid); +} + +int32_t mius_data_write(uint32_t message_id, const char *data, size_t data_size) +{ + int32_t err_dsp; + /* int32_t err_us; */ + + err_dsp = 0; + err_dsp = mius_data_io_write(message_id, data, data_size); + if (err_dsp) + MI_PRINT_E("Failed write to DSP"); + return err_dsp; + + /* + * err_us = 0; + * err_us = mius_userspace_ctrl_write(message_id, data, data_size); + * if(err_us){ + * MI_PRINT_E("Failed write to user space"); + *} + * + *return (err_dsp | err_us); + */ +} + +/** +* +* @return Number of bytes read. +*/ +static ssize_t device_read(struct file *fp, char __user *buff, size_t length, + loff_t *ppos) +{ + ssize_t bytes_read = 0; + struct mius_device *mius_device; + struct mius_data *mius_data; + + mius_device = (struct mius_device *)fp->private_data; + mius_data = (struct mius_data *)&mius_device->el_data; + + bytes_read = mius_data_pop(mius_data, buff, length); + + return bytes_read; +} + +/** +* +* @return number of bytes actually written +*/ +static ssize_t device_write(struct file *fp, const char *buff, size_t length, + loff_t *ppos) +{ + ssize_t ret_val; + + ret_val = 0; + if ((buff != NULL) && (length != 0)) + ret_val = mius_data_io_write(MIUS_ULTRASOUND_SET_PARAMS, buff, + length); + + return ret_val >= 0 ? (ssize_t)length : 0; +} + +static long device_ioctl(struct file *fp, unsigned int number, + unsigned long param) +{ + struct mius_device *device; + struct mius_data *mius_data; + int err; + unsigned int mirror_tag, mirror_payload_size; + unsigned char *data_ptr; + + device = (struct mius_device *)(fp->private_data); + mius_data = &device->el_data; + + switch (number) { + case IOCTL_MIUS_DATA_IO_CANCEL: + MI_PRINT_D("IOCTL_MIUS_CANCEL_READ %ld", param); + mius_data_cancel(mius_data); + break; + + case IOCTL_MIUS_DATA_IO_MIRROR: + data_ptr = (unsigned char *)param; + mirror_tag = *(unsigned int *)data_ptr; + mirror_payload_size = *((unsigned int *)data_ptr + 1); + + if ((mirror_tag == MIRROR_TAG) && (mirror_payload_size != 0) && + (mirror_payload_size <= (MIUS_SET_PARAMS_SIZE * 4))) { + err = mius_data_io_write(MIUS_ULTRASOUND_SET_PARAMS, + (data_ptr + 8), + mirror_payload_size); + + if (err != 0) { + MI_PRINT_E("mius_data_io_write failed"); + return err; + } + + } else { + MI_PRINT_E("TAG or Length is not valid"); + } + + break; + + default: + MI_PRINT_W("UNKNOWN IOCTL number=%d", number); + break; + } + + return 0; +} + +static unsigned int device_poll(struct file *file, + struct poll_table_struct *poll_table) +{ + unsigned int mask; + + struct mius_device *device; + struct mius_data *mius_data; + + mask = 0; + device = (struct mius_device *)file->private_data; + mius_data = (struct mius_data *)&device->el_data; + + poll_wait(file, &mius_data->fifo_isr_not_empty, poll_table); + + if (!kfifo_is_empty(&mius_data->fifo_isr)) + mask = POLLIN | POLLRDNORM; + + return mask; +} + +static int device_close(struct inode *inode, struct file *filp) +{ + struct mius_device *device; + struct mius_data *mius_data; + unsigned int minor; + + device = filp->private_data; + mius_data = &device->el_data; + minor = iminor(inode); + if (device == NULL) { + MI_PRINT_E("device not found"); + return -ENODEV; + } + + device->opened = 0; + mius_data_update_debug_counters(mius_data); + mius_data_print_debug_counters(mius_data); + mius_data_cancel(mius_data); + up(&device->sem); + + MI_PRINT_I("Closed device mius%u", minor); + return 0; +} + +/* defines the file operations provided by the driver */ +static const struct file_operations mius_fops = { + .owner = THIS_MODULE, /* prevents unloading when operations are in use*/ + .open = device_open, /*to open the device*/ + .write = device_write, /*to write to the device*/ + .read = device_read, /*to read the device*/ + .poll = device_poll, + .unlocked_ioctl = device_ioctl, /* IOCTL calls */ + .release = device_close, /*to close the device*/ +}; + +static int mius_device_initialize(struct mius_device *mius_device, int minor, + struct class *class) +{ + int err; + dev_t device_number; + struct device *device; + + BUG_ON(mius_device == NULL || class == NULL); + + err = 0; + device = NULL; + device_number = MKDEV(mius_major, minor); + /* Memory is to be allocated when the device is opened the first time */ + sema_init(&mius_device->sem, 1); + cdev_init(&mius_device->cdev, &mius_fops); + mius_device->cdev.owner = THIS_MODULE; + + err = cdev_add(&mius_device->cdev, device_number, 1); + + if (err) { + MI_PRINT_E("error %d while trying to add %s%d", err, + MIUS_DEVICENAME, minor); + return err; + } + + device = device_create(class, NULL, device_number, NULL, + MIUS_DEVICENAME "%d", minor); + + if (IS_ERR(device)) { + err = PTR_ERR(device); + MI_PRINT_E("error %d while trying to create %s%d", err, + MIUS_DEVICENAME, minor); + cdev_del(&mius_device->cdev); + return err; + } + + if (err) { + MI_PRINT_E("failed device initialize"); + return err; + } + + return 0; +} + +static void mius_device_cleanup(struct mius_device *dev, int minor, + struct class *class) + +{ + BUG_ON(dev == NULL || class == NULL); + device_destroy(class, MKDEV(mius_major, minor)); + cdev_del(&dev->cdev); + up(&dev->sem); +} + +static void mius_driver_cleanup(int devices_to_destroy) +{ + int i; + + if (mius_devices) { + mius_data_io_cleanup(); + + for (i = 0; i < devices_to_destroy; ++i) { + mius_data_cleanup(&mius_devices[i].el_data); + mius_device_cleanup(&mius_devices[i], i, mius_class); + } + + kfree(mius_devices); + } + + if (mius_class) + class_destroy(mius_class); + + unregister_chrdev_region(MKDEV(mius_major, 0), MIUS_NUM_DEVICES); +} + +#ifdef MIUS_LOAD_CALIBRATION_DATA_FROM_FILESYSTEM + +#define MIUS_CALIBRATION_MAX_DATA_SIZE \ + (MIUS_CALIBRATION_V2_DATA_SIZE + MIUS_CALIBRATION_DATA_SIZE) +static unsigned char calibration_data[MIUS_CALIBRATION_MAX_DATA_SIZE]; +static char *calibration_filename = "/persist/audio/mius_calibration"; + +/* function to load the calibration from a file (if possible) */ +static size_t load_calibration_data(char *filename) +{ + size_t bytes_read = 0; + int rc = -ENOENT; + + rc = kernel_read_file_from_path(filename, calibration_data, &bytes_read, + MIUS_CALIBRATION_MAX_DATA_SIZE, + READING_FIRMWARE); + if (rc) { + if (rc == -ENOENT) + MI_PRINT_E("loading %s failed with error %d\n", + filename, rc); + else + MI_PRINT_E("loading %s failed with error %d\n", + filename, rc); + } + MI_PRINT_I("loading %s\n", filename); + + return bytes_read; +} + +static int32_t mius_send_calibration_to_engine(size_t calib_data_size) +{ + mius_set_calibration_data(calibration_data, calib_data_size); + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, + (const char *)calibration_data, calib_data_size); +} + +#endif + +int __init mius_driver_init(void) +{ + int err; + int i; + int devices_to_destroy; + dev_t device_number; + + err = alloc_chrdev_region(&device_number, 0, MIUS_NUM_DEVICES, + MIUS_DEVICENAME); + + devices_to_destroy = 0; + + if (err < 0) { + MI_PRINT_E("Failed to allocate cdev region"); + return err; + } + + mius_major = MAJOR(device_number); + mius_class = class_create(THIS_MODULE, "mius_chardev"); + + if (mius_class == NULL) { + MI_PRINT_E("Class creation failed"); + goto fail; + } + + err = mius_initialize_sysfs(); + + if (err) + goto fail; + + mius_devices = (struct mius_device *)kzalloc( + sizeof(struct mius_device) * MIUS_NUM_DEVICES, GFP_KERNEL); + + if (mius_devices == NULL) { + err = -ENOMEM; + goto fail; + } + + for (i = 0; i < MIUS_NUM_DEVICES; ++i) { + if (mius_device_initialize(&mius_devices[i], i, mius_class)) { + devices_to_destroy = i; + goto fail; + } + + if (mius_data_initialize(&mius_devices[i].el_data, + MIUS_DATA_FIFO_SIZE, + MIUS_WAKEUP_TIMEOUT, i)) { + goto fail; + } + } + + if (mius_data_io_initialize()) + goto fail; + + if (mius_userspace_io_driver_init()) + goto fail; + + if (mius_userspace_ctrl_driver_init()) + goto fail; + + wake_source = kmalloc(sizeof(struct wakeup_source), GFP_KERNEL); + + if (!wake_source) { + MI_PRINT_E("failed to allocate wake source"); + return -ENOMEM; + } + + wakeup_source_init(wake_source, "mius_wake_source"); + +#ifdef MIUS_LOAD_CALIBRATION_DATA_FROM_FILESYSTEM + /* Code to send calibration to engine */ + { + size_t calib_data_size = + load_calibration_data(calibration_filename); + if (calib_data_size > 0) + mius_send_calibration_to_engine(calib_data_size); + } +#endif + return 0; + +fail: + mius_driver_cleanup(devices_to_destroy); + return err; +} + +void mius_driver_exit(void) +{ + if (wake_source) { + wakeup_source_trash(wake_source); + kfree(wake_source); + } + + mius_cleanup_sysfs(); + mius_driver_cleanup(MIUS_NUM_DEVICES); + mius_userspace_io_driver_exit(); + mius_userspace_ctrl_driver_exit(); +} + +MODULE_AUTHOR("MI"); +MODULE_DESCRIPTION("Providing Interface to UPS data"); +MODULE_LICENSE("GPL"); diff --git a/techpack/audio/dsp/mius/mius_mixer_controls.c b/techpack/audio/dsp/mius/mius_mixer_controls.c new file mode 100644 index 000000000000..c4ea9e3ecb1b --- /dev/null +++ b/techpack/audio/dsp/mius/mius_mixer_controls.c @@ -0,0 +1,1344 @@ +/** + * MI + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct mius_system_configuration { + union { + uint8_t reserved[MIUS_SYSTEM_CONFIGURATION_SIZE]; + }; +}; + +struct mius_system_configuration mius_system_configuration; + +struct mius_system_configuration_parameter { + enum mius_system_configuration_parameter_type type; + union { + int32_t speaker_scaling[2]; + int32_t sensitivity; + int32_t latency; + int32_t microphone_index; + int32_t operation_mode; + int32_t operation_mode_flags; + int32_t component_gain_change; + int32_t calibration_state; + int32_t engine_version; + int32_t calibration_profile; + int32_t ultrasound_gain; + int32_t log_level; + int32_t custom_setting; + int32_t engine_suspend; + int32_t input_enabled; + int32_t output_enabled; + int32_t external_event; + struct { + int32_t calibration_method; + int32_t calibration_timestamp; + }; + int32_t debug_mode; + int32_t context; + int32_t capture; + int32_t input_channels; + }; +}; + +struct mius_system_configuration_parameters_cache + mius_system_configuration_cache = { { 0 }, 0 }; + +static struct mius_engine_version_info mius_engine_version_cache = { 0xde, 0xad, + 0xbe, + 0xef }; + +struct mius_engine_calibration_data { + union { + uint8_t reserved[MIUS_CALIBRATION_DATA_SIZE]; + }; +}; + +static struct mius_engine_calibration_data + mius_engine_calibration_data_cache = { .reserved = { + + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef } }; + +struct mius_engine_calibration_v2_data { + union { + uint8_t reserved[MIUS_CALIBRATION_V2_DATA_SIZE]; + }; +}; + +static struct mius_engine_calibration_v2_data + mius_engine_calibration_v2_data_cache = { .reserved = { + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, + 0xef, + } }; + +struct mius_engine_diagnostics_data { + union { + uint8_t reserved[MIUS_DIAGNOSTICS_DATA_SIZE]; + uint32_t values32[MIUS_DIAGNOSTICS_DATA_SIZE >> 2]; + }; +}; + +static struct mius_engine_diagnostics_data mius_engine_diagnostics_data_cache = { + .reserved = { 0 } +}; + +struct mius_engine_ml_data { + union { + uint8_t reserved[MIUS_ML_DATA_SIZE]; + uint32_t u32[MIUS_ML_DATA_SIZE >> 2]; + }; +}; + +static struct mius_engine_ml_data mius_engine_ml_data_cache = { .reserved = { + 0 } }; + +struct mius_engine_sensor_data { + union { + uint8_t reserved[MIUS_SENSOR_DATA_SIZE]; + uint32_t values32[MIUS_SENSOR_DATA_SIZE >> 2]; + }; +}; + +static struct mius_engine_sensor_data mius_engine_sensor_data_cache = { + .reserved = { 0 } +}; + +struct mius_engine_branch_info { + char build_branch[MIUS_BRANCH_INFO_MAX_SIZE]; +}; + +static struct mius_engine_branch_info mius_engine_branch_cache = { { 0 } }; + +struct mius_engine_tag_info { + char engine_tag[MIUS_TAG_INFO_SIZE]; +}; + +static struct mius_engine_tag_info mius_engine_tag_cache = { { 0 } }; + +static struct mius_shared_data_block shared_data_blocks[] = { + { MIUS_OBJ_ID_CALIBRATION_DATA, MIUS_CALIBRATION_DATA_SIZE, + &mius_engine_calibration_data_cache }, + + { MIUS_OBJ_ID_VERSION_INFO, MIUS_VERSION_INFO_SIZE, + &mius_engine_version_cache }, + { MIUS_OBJ_ID_BRANCH_INFO, MIUS_BRANCH_INFO_MAX_SIZE, + &mius_engine_branch_cache }, + { MIUS_OBJ_ID_CALIBRATION_V2_DATA, MIUS_CALIBRATION_V2_DATA_SIZE, + &mius_engine_calibration_v2_data_cache }, + { MIUS_OBJ_ID_DIAGNOSTICS_DATA, MIUS_DIAGNOSTICS_DATA_SIZE, + &mius_engine_diagnostics_data_cache }, + { MIUS_OBJ_ID_TAG_INFO, MIUS_TAG_INFO_SIZE, &mius_engine_tag_cache }, + { MIUS_OBJ_ID_ML_DATA, MIUS_ML_DATA_SIZE, &mius_engine_ml_data_cache }, +}; + +void mius_set_calibration_data(uint8_t *calib_data, size_t size) +{ + struct mius_shared_data_block *calibration_obj = NULL; + + if (size == MIUS_CALIBRATION_DATA_SIZE) { + calibration_obj = + mius_get_shared_obj(MIUS_OBJ_ID_CALIBRATION_DATA); + memcpy((uint8_t *)&mius_engine_calibration_data_cache, + calib_data, size); + } + if (size == MIUS_CALIBRATION_V2_DATA_SIZE) { + calibration_obj = + mius_get_shared_obj(MIUS_OBJ_ID_CALIBRATION_V2_DATA); + memcpy((uint8_t *)&mius_engine_calibration_v2_data_cache, + calib_data, size); + } + if (calibration_obj == NULL) { + MI_PRINT_E("ell..set_calibration_data() calib=NULL (%zu)", + size); + return; + } + memcpy((u8 *)calibration_obj->buffer, calib_data, size); +} + +void mius_set_diagnostics_data(uint8_t *diag_data, size_t size) +{ + struct mius_shared_data_block *diagnostics_obj = NULL; + + if (size <= MIUS_DIAGNOSTICS_DATA_SIZE) { + diagnostics_obj = + mius_get_shared_obj(MIUS_OBJ_ID_DIAGNOSTICS_DATA); + if (diagnostics_obj == NULL) { + MI_PRINT_E("el..set_diagnostics_data() NULL (%zu)", + size); + return; + } + memcpy((uint8_t *)&mius_engine_diagnostics_data_cache, + diag_data, size); + memcpy((u8 *)diagnostics_obj->buffer, diag_data, size); + } +} + +static const size_t NUM_SHARED_RW_OBJS = + sizeof(shared_data_blocks) / sizeof(struct mius_shared_data_block); + +struct mius_shared_data_block *mius_get_shared_obj(uint32_t object_id) +{ + size_t i; + + for (i = 0; i < NUM_SHARED_RW_OBJS; ++i) { + if (shared_data_blocks[i].object_id == object_id) + return &shared_data_blocks[i]; + } + + return NULL; +} + +static const char *const ultrasound_enable_texts[] = { "Off", "On" }; + +static const struct soc_enum mius_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ultrasound_enable_texts), + ultrasound_enable_texts), +}; + +int get_mius_calibration_data(uint8_t *caldata, uint32_t max_size) +{ + uint32_t copied; + + copied = MIUS_CALIBRATION_DATA_SIZE; + if (max_size < MIUS_CALIBRATION_DATA_SIZE) { + copied = max_size; + MI_PRINT_D("size mismatch : %u vs %u", + (uint32_t)MIUS_CALIBRATION_DATA_SIZE, max_size); + } + + memcpy(caldata, (uint8_t *)&mius_engine_calibration_data_cache, + max_size); + return copied; +} + +int get_mius_calibration_v2_data(uint8_t *caldata, uint32_t max_size) +{ + uint32_t copied; + + copied = MIUS_CALIBRATION_V2_DATA_SIZE; + if (max_size < MIUS_CALIBRATION_V2_DATA_SIZE) { + copied = max_size; + MI_PRINT_D("size mismatch : %u vs %u", + (uint32_t)MIUS_CALIBRATION_V2_DATA_SIZE, max_size); + } + + memcpy(caldata, (uint8_t *)&mius_engine_calibration_v2_data_cache, + max_size); + return copied; +} + +int get_mius_diagnostics_data(uint8_t *diagdata, uint32_t max_size) +{ + uint32_t copied; + + copied = MIUS_DIAGNOSTICS_DATA_SIZE; + if (max_size < MIUS_DIAGNOSTICS_DATA_SIZE) { + copied = max_size; + MI_PRINT_D("size mismatch : %u vs %u", + (uint32_t)MIUS_DIAGNOSTICS_DATA_SIZE, max_size); + } + + memcpy(diagdata, (uint8_t *)&mius_engine_diagnostics_data_cache, + max_size); + return copied; +} + +static uint32_t ultrasound_enable_cache; + +int mius_ultrasound_enable_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = ultrasound_enable_cache; + return 0; +} + +int mius_ultrasound_enable_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + static bool triggered_engine_info; + int32_t msg[4] = { 0, 0, 0, 0 }; + + ultrasound_enable_cache = ucontrol->value.integer.value[0]; + + if (!triggered_engine_info && ultrasound_enable_cache) { + triggered_engine_info = true; + mius_trigger_version_msg(); + mius_trigger_branch_msg(); + mius_trigger_tag_msg(); + } + + msg[0] = ultrasound_enable_cache ? 1 : 0; + + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, (const char *)msg, + sizeof(msg)); +} + +static uint32_t ultrasound_tx_port_cache; + +int mius_ultrasound_tx_port_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = ultrasound_tx_port_cache; + return 0; +} + +int mius_ultrasound_tx_port_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret; + + if (ultrasound_tx_port_cache == ucontrol->value.integer.value[0]) { + MI_PRINT_E( + "ultrasound_tx_port_set: ignoring duplicate request"); + return 0; + } + + ultrasound_tx_port_cache = ucontrol->value.integer.value[0]; + printk(KERN_DEBUG "[MIUS] Via ULTRASOUND_TX_PORT_ID enable=%d", + ultrasound_tx_port_cache); + if (ultrasound_tx_port_cache) + ret = mius_open_port(ULTRASOUND_TX_PORT_ID); + else + ret = mius_close_port(ULTRASOUND_TX_PORT_ID); + + MI_PRINT_E("ultrasound_tx_port: enable=%d ret=%d", + ultrasound_tx_port_cache, ret); + + return ret; +} + +static uint32_t ultrasound_rx_port_cache; + +int mius_ultrasound_rx_port_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = ultrasound_rx_port_cache; + return 0; +} + +int mius_ultrasound_rx_port_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret; + + if (ultrasound_rx_port_cache == ucontrol->value.integer.value[0]) { + MI_PRINT_E( + "mi ultrasound_rx_port_set: ignoring duplicate request"); + return 0; + } + + ultrasound_rx_port_cache = ucontrol->value.integer.value[0]; + printk(KERN_DEBUG + "[MIUS] if we are here, it is wrong for mius, enable=%d", + ultrasound_rx_port_cache); + if (ultrasound_rx_port_cache) + ret = mius_open_port(ULTRASOUND_RX_PORT_ID); + else + ret = mius_close_port(ULTRASOUND_RX_PORT_ID); + + MI_PRINT_E("mi ultrasound_rx_port: enable=%d ret=%d", + ultrasound_rx_port_cache, ret); + + return 0; +} + +int mius_ultrasound_rampdown_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* Rampdown is a strobe, so always return Off */ + ucontrol->value.integer.value[0] = 0; + return 0; +} + +int mius_ultrasound_rampdown_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int32_t msg[4] = { -1, 0, 0, 0 }; + + if (ucontrol->value.integer.value[0] == 0) + return 0; + + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, (const char *)msg, + sizeof(msg)); +} + +int mius_ultrasound_diagnostics_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* Diagnostics is a strobe, so always return Off */ + ucontrol->value.integer.value[0] = 0; + return 0; +} + +int mius_ultrasound_request_diagnostics(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int32_t msg[3] = { MSC_ENGINE_DIAGNOSTICS, 0, 0 }; + + if (ucontrol->value.integer.value[0] == 0) + return 0; + + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, (const char *)msg, + sizeof(msg)); +} + +int mius_system_configuration_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, &mius_system_configuration, + MIUS_SYSTEM_CONFIGURATION_SIZE); + return 0; +} + +int mius_system_configuration_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(&mius_system_configuration, ucontrol->value.bytes.data, + MIUS_SYSTEM_CONFIGURATION_SIZE); + + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, + (const char *)&mius_system_configuration, + MIUS_SYSTEM_CONFIGURATION_SIZE); +} + +int mius_calibration_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, &mius_engine_calibration_data_cache, + MIUS_CALIBRATION_DATA_SIZE); + return 0; +} + +int mius_calibration_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(&mius_engine_calibration_data_cache, ucontrol->value.bytes.data, + MIUS_CALIBRATION_DATA_SIZE); + + return mius_data_write( + MIUS_ULTRASOUND_SET_PARAMS, + (const char *)&mius_engine_calibration_data_cache, + MIUS_CALIBRATION_DATA_SIZE); +} + +int mius_calibration_v2_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct mius_shared_data_block *calibration_obj = + mius_get_shared_obj(MIUS_OBJ_ID_CALIBRATION_V2_DATA); + + if (calibration_obj == NULL) { + MI_PRINT_E("calibration_obj is NULL"); + return -EINVAL; + } + + memcpy(ucontrol->value.bytes.data, calibration_obj->buffer, + MIUS_CALIBRATION_V2_DATA_SIZE); + return 0; +} + +int mius_calibration_v2_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(&mius_engine_calibration_v2_data_cache, + ucontrol->value.bytes.data, MIUS_CALIBRATION_V2_DATA_SIZE); + + return mius_data_write( + MIUS_ULTRASOUND_SET_PARAMS, + (const char *)&mius_engine_calibration_v2_data_cache, + MIUS_CALIBRATION_V2_DATA_SIZE); +} + +int mius_diagnostics_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, &mius_engine_diagnostics_data_cache, + MIUS_DIAGNOSTICS_DATA_SIZE); + return 0; +} + +int mius_diagnostics_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +int mius_ml_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct mius_shared_data_block *ml_obj = + mius_get_shared_obj(MIUS_OBJ_ID_ML_DATA); + + if (ml_obj == NULL) { + MI_PRINT_E("ml_obj is NULL"); + return -EINVAL; + } + + memcpy(ucontrol->value.bytes.data, ml_obj->buffer, MIUS_ML_DATA_SIZE); + return 0; +} + +int mius_ml_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, + (const char *)ucontrol->value.bytes.data, + MIUS_ML_DATA_SIZE); +} + +int mius_sensor_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, &mius_engine_sensor_data_cache, + MIUS_SENSOR_DATA_SIZE); + return 0; +} + +int mius_sensor_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(&mius_engine_sensor_data_cache, ucontrol->value.bytes.data, + MIUS_SENSOR_DATA_SIZE); + + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, + (const char *)&mius_engine_sensor_data_cache, + MIUS_SENSOR_DATA_SIZE); +} + +int mius_version_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, &mius_engine_version_cache, + MIUS_VERSION_INFO_SIZE); + return 0; +} + +int mius_version_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +int mius_branch_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, &mius_engine_branch_cache, + MIUS_BRANCH_INFO_MAX_SIZE); + return 0; +} + +int mius_branch_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +int mius_tag_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.bytes.data, &mius_engine_tag_cache, + MIUS_TAG_INFO_SIZE); + return 0; +} + +int mius_tag_data_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +int mius_calibration_param_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + if (mc->reg != MIUS_CALIBRATION) + return -EINVAL; + + switch (mc->shift) { + case MIUS_CALIBRATION_STATE: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.calibration_state; + break; + + case MIUS_CALIBRATION_PROFILE: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.calibration_profile; + break; + + case MIUS_ULTRASOUND_GAIN: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.ultrasound_gain; + break; + + default: + return -EINVAL; + } + + return 1; +} + +int mius_calibration_param_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct mius_system_configuration_parameter param; + + if (mc->reg != MIUS_CALIBRATION) + return -EINVAL; + + switch (mc->shift) { + case MIUS_CALIBRATION_STATE: + mius_system_configuration_cache.calibration_state = + ucontrol->value.integer.value[0]; + + param.type = MSC_CALIBRATION_STATE; + param.calibration_state = + mius_system_configuration_cache.calibration_state; + break; + + case MIUS_CALIBRATION_PROFILE: + mius_system_configuration_cache.calibration_profile = + ucontrol->value.integer.value[0]; + + param.type = MSC_CALIBRATION_PROFILE; + param.calibration_profile = + mius_system_configuration_cache.calibration_profile; + break; + + case MIUS_ULTRASOUND_GAIN: + mius_system_configuration_cache.ultrasound_gain = + ucontrol->value.integer.value[0]; + param.type = MSC_ULTRASOUND_GAIN; + param.ultrasound_gain = + mius_system_configuration_cache.ultrasound_gain; + break; + + default: + return -EINVAL; + } + + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, (u8 *)¶m, + sizeof(param)); +} + +int mius_system_configuration_param_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + pr_err("%s: reg: %d shift: %d\n", __func__, mc->reg, mc->shift); + + if (mc->reg != MIUS_SYSTEM_CONFIGURATION) + return -EINVAL; + + if (mc->shift >= MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_0 && + mc->shift <= MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_15) { + MI_PRINT_E("get MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_%02d", + mc->shift - + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_0); + ucontrol->value.integer.value[0] = 0; + return 1; + } + + switch (mc->shift) { + case MIUS_SYSTEM_CONFIGURATION_LATENCY: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.latency; + break; + + case MIUS_SYSTEM_CONFIGURATION_SENSITIVITY: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.sensitivity; + break; + + case MIUS_SYSTEM_CONFIGURATION_SPEAKER_SCALING: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.speaker_scaling[0]; + ucontrol->value.integer.value[1] = + mius_system_configuration_cache.speaker_scaling[1]; + break; + + case MIUS_SYSTEM_CONFIGURATION_MICROPHONE_INDEX: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.microphone_index; + break; + + case MIUS_SYSTEM_CONFIGURATION_OPERATION_MODE: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.operation_mode; + break; + + case MIUS_SYSTEM_CONFIGURATION_OPERATION_MODE_FLAGS: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.operation_mode_flags; + break; + + case MIUS_SYSTEM_CONFIGURATION_LOG_LEVEL: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.log_level; + break; + case MIUS_SYSTEM_CONFIGURATION_SUSPEND: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.engine_suspend; + break; + case MIUS_SYSTEM_CONFIGURATION_INPUT_ENABLED: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.input_enabled; + break; + case MIUS_SYSTEM_CONFIGURATION_OUTPUT_ENABLED: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.output_enabled; + break; + case MIUS_SYSTEM_CONFIGURATION_EXTERNAL_EVENT: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.external_event; + break; + case MIUS_SYSTEM_CONFIGURATION_CALIBRATION_METHOD: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.calibration_method; + case MIUS_SYSTEM_CONFIGURATION_DEBUG_MODE: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.debug_mode; + break; + case MIUS_SYSTEM_CONFIGURATION_CONTEXT: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.context; + break; + case MIUS_SYSTEM_CONFIGURATION_CAPTURE: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.capture; + break; + case MIUS_SYSTEM_CONFIGURATION_INPUT_CHANNELS: + ucontrol->value.integer.value[0] = + mius_system_configuration_cache.input_channels; + break; + + default: + MI_PRINT_E("Invalid mixer control"); + return -EINVAL; + } + + return 1; +} + +int mius_system_configuration_param_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct mius_system_configuration_parameter param; + struct timeval tv; + + if (mc->reg != MIUS_SYSTEM_CONFIGURATION) + return -EINVAL; + + if (mc->shift >= MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_0 && + mc->shift <= MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_15) { + const size_t csi = + mc->shift - MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_0; + MI_PRINT_E( + "MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_XX csi:%zu", + csi); + if (csi >= + ARRAY_SIZE(mius_system_configuration_cache.custom_settings)) + return -EINVAL; + MI_PRINT_E("ucontrol->value.integer.value[0]:%ld", + ucontrol->value.integer.value[0]); + mius_system_configuration_cache.custom_settings[csi] = + ucontrol->value.integer.value[0]; + param.type = MSC_ENGINE_CUSTOM_SETTING_0 + csi; + param.custom_setting = ucontrol->value.integer.value[0]; + MI_PRINT_E("calling mius_data_write(custom_setting) csi:%zu", + csi); + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, + (const char *)¶m, sizeof(param)); + } + + switch (mc->shift) { + case MIUS_SYSTEM_CONFIGURATION_LATENCY: + mius_system_configuration_cache.latency = + ucontrol->value.integer.value[0]; + param.type = MSC_LATENCY; + param.latency = mius_system_configuration_cache.latency; + break; + + case MIUS_SYSTEM_CONFIGURATION_SENSITIVITY: + mius_system_configuration_cache.sensitivity = + ucontrol->value.integer.value[0]; + param.type = MSC_CHANNEL_SENSITIVITY; + param.sensitivity = mius_system_configuration_cache.sensitivity; + break; + + case MIUS_SYSTEM_CONFIGURATION_SPEAKER_SCALING: + mius_system_configuration_cache.speaker_scaling[0] = + ucontrol->value.integer.value[0]; + mius_system_configuration_cache.speaker_scaling[1] = + ucontrol->value.integer.value[1]; + param.type = MSC_SPEAKER_SCALING; + param.speaker_scaling[0] = + mius_system_configuration_cache.speaker_scaling[0]; + param.speaker_scaling[1] = + mius_system_configuration_cache.speaker_scaling[1]; + break; + + case MIUS_SYSTEM_CONFIGURATION_MICROPHONE_INDEX: + mius_system_configuration_cache.microphone_index = + ucontrol->value.integer.value[0]; + param.type = MSC_MICROPHONE_INDEX; + param.microphone_index = + mius_system_configuration_cache.microphone_index; + break; + + case MIUS_SYSTEM_CONFIGURATION_OPERATION_MODE: + mius_system_configuration_cache.operation_mode = + ucontrol->value.integer.value[0]; + param.type = MSC_OPERATION_MODE; + param.operation_mode = + mius_system_configuration_cache.operation_mode; + break; + + case MIUS_SYSTEM_CONFIGURATION_OPERATION_MODE_FLAGS: + mius_system_configuration_cache.operation_mode_flags = + ucontrol->value.integer.value[0]; + param.type = MSC_OPERATION_MODE_FLAGS; + param.operation_mode_flags = + mius_system_configuration_cache.operation_mode_flags; + break; + + case MIUS_SYSTEM_CONFIGURATION_LOG_LEVEL: + mius_system_configuration_cache.log_level = + ucontrol->value.integer.value[0]; + param.type = MSC_LOG_LEVEL; + param.log_level = mius_system_configuration_cache.log_level; + break; + case MIUS_SYSTEM_CONFIGURATION_INPUT_ENABLED: + mius_system_configuration_cache.input_enabled = + ucontrol->value.integer.value[0]; + param.type = MSC_INPUT_ENABLED; + param.input_enabled = + mius_system_configuration_cache.input_enabled; + break; + case MIUS_SYSTEM_CONFIGURATION_OUTPUT_ENABLED: + mius_system_configuration_cache.output_enabled = + ucontrol->value.integer.value[0]; + param.type = MSC_OUTPUT_ENABLED; + param.output_enabled = + mius_system_configuration_cache.output_enabled; + break; + case MIUS_SYSTEM_CONFIGURATION_SUSPEND: + mius_system_configuration_cache.engine_suspend = + ucontrol->value.integer.value[0]; + param.type = MSC_SUSPEND; + param.engine_suspend = + mius_system_configuration_cache.engine_suspend; + break; + case MIUS_SYSTEM_CONFIGURATION_EXTERNAL_EVENT: + mius_system_configuration_cache.external_event = + ucontrol->value.integer.value[0]; + param.type = MSC_EXTERNAL_EVENT; + param.external_event = + mius_system_configuration_cache.external_event; + break; + case MIUS_SYSTEM_CONFIGURATION_CALIBRATION_METHOD: + mius_system_configuration_cache.calibration_method = + ucontrol->value.integer.value[0]; + param.type = MSC_CALIBRATION_METHOD; + param.calibration_method = + mius_system_configuration_cache.calibration_method; + do_gettimeofday(&tv); + param.calibration_timestamp = (int32_t)tv.tv_sec; + break; + case MIUS_SYSTEM_CONFIGURATION_DEBUG_MODE: + mius_system_configuration_cache.debug_mode = + ucontrol->value.integer.value[0]; + param.type = MSC_DEBUG_MODE; + param.debug_mode = mius_system_configuration_cache.debug_mode; + break; + case MIUS_SYSTEM_CONFIGURATION_CONTEXT: + mius_system_configuration_cache.context = + ucontrol->value.integer.value[0]; + param.type = MSC_CONTEXT; + param.context = mius_system_configuration_cache.context; + break; + case MIUS_SYSTEM_CONFIGURATION_CAPTURE: + mius_system_configuration_cache.capture = + ucontrol->value.integer.value[0]; + param.type = MSC_CAPTURE; + param.context = mius_system_configuration_cache.capture; + break; + case MIUS_SYSTEM_CONFIGURATION_INPUT_CHANNELS: + mius_system_configuration_cache.input_channels = + ucontrol->value.integer.value[0]; + param.type = MSC_INPUT_CHANNELS; + param.context = mius_system_configuration_cache.input_channels; + break; + + default: + return -EINVAL; + } + + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, (const char *)¶m, + sizeof(param)); +} + +static const struct snd_kcontrol_new ultrasound_filter_mixer_controls[] = { + SOC_ENUM_EXT("Mi_Ultrasound Enable", mius_enum[0], + mius_ultrasound_enable_get, mius_ultrasound_enable_set), + SOC_ENUM_EXT("Mi_Ultrasound RampDown", mius_enum[0], + mius_ultrasound_rampdown_get, + mius_ultrasound_rampdown_set), + SOC_SINGLE_EXT("Mi_Ultrasound Latency", MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_LATENCY, 10000, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Sensitivity", MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_SENSITIVITY, 1000000, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_DOUBLE_EXT("Mi_Ultrasound Speaker Scaling", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_SPEAKER_SCALING, 0, 1000000, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Microphone Index", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_MICROPHONE_INDEX, 20, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Mode", MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_OPERATION_MODE, 255, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Mode Flags", MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_OPERATION_MODE_FLAGS, 256, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Calibration Profile", MIUS_CALIBRATION, + MIUS_CALIBRATION_PROFILE, 256, 0, + mius_calibration_param_get, mius_calibration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Gain", MIUS_CALIBRATION, + MIUS_ULTRASOUND_GAIN, 256, 0, mius_calibration_param_get, + mius_calibration_param_put), + + SOC_SINGLE_EXT("Mi_Ultrasound Calibration State", MIUS_CALIBRATION, + MIUS_CALIBRATION_STATE, 256, 0, + mius_calibration_param_get, mius_calibration_param_put), + + SND_SOC_BYTES_EXT("Mi_Ultrasound System Configuration", + MIUS_SYSTEM_CONFIGURATION_SIZE, + mius_system_configuration_get, + mius_system_configuration_put), + SND_SOC_BYTES_EXT("Mi_Ultrasound Calibration Data", + MIUS_CALIBRATION_DATA_SIZE, mius_calibration_data_get, + mius_calibration_data_put), + SND_SOC_BYTES_EXT("Mi_Ultrasound Version", MIUS_VERSION_INFO_SIZE, + mius_version_data_get, mius_version_data_put), + SND_SOC_BYTES_EXT("Mi_Ultrasound Branch", MIUS_BRANCH_INFO_MAX_SIZE, + mius_branch_data_get, mius_branch_data_put), + SND_SOC_BYTES_EXT("Mi_Ultrasound Tag", MIUS_TAG_INFO_SIZE, + mius_tag_data_get, mius_tag_data_put), + SOC_SINGLE_EXT("Mi_Ultrasound Log Level", MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_LOG_LEVEL, 7, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + + SND_SOC_BYTES_EXT("Mi_Ultrasound Calibration Ext Data", + MIUS_CALIBRATION_V2_DATA_SIZE, + mius_calibration_v2_data_get, + mius_calibration_v2_data_put), + + SND_SOC_BYTES_EXT("Mi_Ultrasound Diagnostics Data", + MIUS_DIAGNOSTICS_DATA_SIZE, mius_diagnostics_data_get, + mius_diagnostics_data_put), + + SOC_ENUM_EXT("Mi_Ultrasound Diagnostics Request", mius_enum[0], + mius_ultrasound_diagnostics_get, + mius_ultrasound_request_diagnostics), + + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 0", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_0, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 1", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_1, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 2", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_2, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 3", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_3, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 4", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_4, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 5", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_5, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 6", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_6, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 7", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_7, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 8", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_8, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 9", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_9, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 10", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_10, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 11", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_11, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 12", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_12, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 13", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_13, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 14", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_14, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Custom Setting 15", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_15, + MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_ENUM_EXT("Mi_Ultrasound Tx Port", mius_enum[0], + mius_ultrasound_tx_port_get, mius_ultrasound_tx_port_set), + SOC_ENUM_EXT("Mi_Ultrasound Rx Port", mius_enum[0], + mius_ultrasound_rx_port_get, mius_ultrasound_rx_port_set), + SOC_SINGLE_EXT("Mi_Ultrasound Suspend", MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_SUSPEND, 1, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Input", MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_INPUT_ENABLED, 1, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Output", MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_OUTPUT_ENABLED, 1, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Event", MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_EXTERNAL_EVENT, 256, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Calibration Method", + MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CALIBRATION_METHOD, 256, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + + SND_SOC_BYTES_EXT("Mi_Ultrasound ML", MIUS_ML_DATA_SIZE, + mius_ml_data_get, mius_ml_data_put), + + SOC_SINGLE_EXT("Mi_Ultrasound Debug Mode", MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_DEBUG_MODE, 256, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SOC_SINGLE_EXT("Mi_Ultrasound Context", MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CONTEXT, + MIUS_SYSTEM_CONFIGURATION_MAX_CONTEXT_VALUE, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + SND_SOC_BYTES_EXT("Mi_Ultrasound Sensor Data", MIUS_SENSOR_DATA_SIZE, + mius_sensor_data_get, mius_sensor_data_put), + + SOC_SINGLE_EXT("Mi_Ultrasound Capture", MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_CAPTURE, 256, -1, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + + SOC_SINGLE_EXT("Mi_Ultrasound Tx Channels", MIUS_SYSTEM_CONFIGURATION, + MIUS_SYSTEM_CONFIGURATION_INPUT_CHANNELS, 16, 0, + mius_system_configuration_param_get, + mius_system_configuration_param_put), + +}; + +unsigned int mius_add_platform_controls(void *platform) +{ + const unsigned int num_controls = + ARRAY_SIZE(ultrasound_filter_mixer_controls); + + if (platform != NULL) { + snd_soc_add_platform_controls( + (struct snd_soc_platform *)platform, + ultrasound_filter_mixer_controls, num_controls); + } else { + MI_PRINT_E("pointer is NULL"); + } + + return num_controls; +} +EXPORT_SYMBOL(mius_add_platform_controls); + +int mius_trigger_version_msg(void) +{ + int32_t msg[3] = { MSC_ENGINE_VERSION, 0, 0 }; + + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, (const char *)msg, + sizeof(msg)); +} + +int mius_trigger_branch_msg(void) +{ + int32_t msg[3] = { MSC_BUILD_BRANCH, 0, 0 }; + + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, (const char *)msg, + sizeof(msg)); +} + +int mius_trigger_tag_msg(void) +{ + int32_t msg[3] = { MSC_ENGINE_TAG, 0, 0 }; + + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, (const char *)msg, + sizeof(msg)); +} + +int mius_trigger_diagnostics_msg(void) +{ + int32_t msg[3] = { MSC_ENGINE_DIAGNOSTICS, 0, 0 }; + + return mius_data_write(MIUS_ULTRASOUND_SET_PARAMS, (const char *)msg, + sizeof(msg)); +} diff --git a/techpack/audio/dsp/mius/mius_sysfs.c b/techpack/audio/dsp/mius/mius_sysfs.c new file mode 100644 index 000000000000..145dd699a470 --- /dev/null +++ b/techpack/audio/dsp/mius/mius_sysfs.c @@ -0,0 +1,645 @@ +#include +#include +#include +#include +#include +#include +#include +#include "mius_version.h" +#include + +#define MIUS_DIAGNOSTICS_DATA_SECTION_COUNT 16 +#define MIUS_CALIBRATION_MAX_DISPLAY_COUNT 96 +#define MIUS_ML_DISPLAY_COUNT 16 + +static int kobject_create_and_add_failed; +static int sysfs_create_group_failed; + +extern struct mius_system_configuration_parameters_cache + mius_system_configuration_cache; + +static ssize_t calibration_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + ssize_t result; + + struct mius_shared_data_block *calibration_obj = + mius_get_shared_obj(MIUS_OBJ_ID_CALIBRATION_DATA); + + if (calibration_obj == NULL) { + MI_PRINT_E("calibration_obj is NULL"); + return -EINVAL; + } + + if (count > calibration_obj->size) { + MI_PRINT_E("write length %zu larger than buffer", count); + return 0; + } + + memcpy(calibration_obj->buffer, buf, count); + result = (ssize_t)count; + return result; +} + +static ssize_t calibration_v2_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t result; + + struct mius_shared_data_block *calibration_obj = + mius_get_shared_obj(MIUS_OBJ_ID_CALIBRATION_V2_DATA); + + if (calibration_obj == NULL) { + MI_PRINT_E("calibration_obj is NULL"); + return -EINVAL; + } + + if (count > calibration_obj->size) { + MI_PRINT_E("write length %zu larger than buffer", count); + return 0; + } + + memcpy(calibration_obj->buffer, buf, count); + result = (ssize_t)count; + return result; +} + +static ssize_t diagnostics_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + ssize_t result; + + struct mius_shared_data_block *diagnostics_obj = + mius_get_shared_obj(MIUS_OBJ_ID_DIAGNOSTICS_DATA); + + if (diagnostics_obj == NULL) { + MI_PRINT_E("diagnostics_obj is NULL"); + return -EINVAL; + } + + if (count > diagnostics_obj->size) { + MI_PRINT_E("write length %zu larger than buffer", count); + return 0; + } + + memcpy(diagnostics_obj->buffer, buf, count); + result = (ssize_t)count; + return result; +} + +static ssize_t ml_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t result; + + struct mius_shared_data_block *ml_obj = + mius_get_shared_obj(MIUS_OBJ_ID_ML_DATA); + + if (ml_obj == NULL) { + MI_PRINT_E("ml_obj is NULL"); + return -EINVAL; + } + + if (count > ml_obj->size) { + MI_PRINT_E("write length %zu larger than buffer", count); + return 0; + } + + memcpy(ml_obj->buffer, buf, count); + result = (ssize_t)count; + return result; +} + +static ssize_t calibration_show_core(struct device *dev, + struct device_attribute *attr, char *buf, + int pretty) +{ + ssize_t result; + int length; + int i; + uint8_t *caldata; + + struct mius_shared_data_block *calibration_obj = + mius_get_shared_obj(MIUS_OBJ_ID_CALIBRATION_DATA); + + if (kobject_create_and_add_failed) + MI_PRINT_E("kobject_create_and_add_failed"); + + if (sysfs_create_group_failed) + MI_PRINT_E("sysfs_create_group_failed"); + + if (calibration_obj == NULL) { + MI_PRINT_E("calibration_obj is NULL"); + return -EINVAL; + } + + if (calibration_obj->size > PAGE_SIZE) { + MI_PRINT_E("calibration_obj->size > PAGE_SIZE"); + return -EINVAL; + } + + caldata = (uint8_t *)calibration_obj->buffer; + length = 0; + if (pretty) { + if (caldata[0] == 0xDE && caldata[1] == 0xAD) { + length += snprintf(buf + length, PAGE_SIZE - length, + "Calibration Data: not loaded"); + } else { + length += snprintf(buf + length, PAGE_SIZE - length, + "Calibration Data: "); + for (i = 0; i < calibration_obj->size; ++i) + length += snprintf(buf + length, + PAGE_SIZE - length, + "0x%02x ", caldata[i]); + } + } else { + for (i = 0; i < calibration_obj->size; ++i) + length += snprintf(buf + length, PAGE_SIZE - length, + "0x%02x ", caldata[i]); + } + length += snprintf(buf + length, PAGE_SIZE - length, "\n\n"); + result = (ssize_t)length; + return result; +} + +static ssize_t calibration_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return calibration_show_core(dev, attr, buf, 0); +} + +static ssize_t calibration_v2_show_core(struct device *dev, + struct device_attribute *attr, + char *buf, int pretty) +{ + ssize_t result; + int length; + int i; + uint8_t *caldata; + + struct mius_shared_data_block *calibration_obj = + mius_get_shared_obj(MIUS_OBJ_ID_CALIBRATION_V2_DATA); + + if (kobject_create_and_add_failed) + MI_PRINT_E("kobject_create_and_add_failed"); + + if (sysfs_create_group_failed) + MI_PRINT_E("sysfs_create_group_failed"); + + if (calibration_obj == NULL) { + MI_PRINT_E("calibration_obj is NULL"); + return -EINVAL; + } + + if (calibration_obj->size > PAGE_SIZE) { + MI_PRINT_E("calibration_obj->size > PAGE_SIZE"); + return -EINVAL; + } + + caldata = (uint8_t *)calibration_obj->buffer; + length = 0; + if (pretty) { + if (caldata[0] == 0xDE && caldata[1] == 0xAD) { + length += snprintf(buf + length, PAGE_SIZE - length, + "Calibration Ext Data: not loaded"); + } else { + int j = (MIUS_CALIBRATION_V2_DATA_SIZE >> 2) - 1; + + length += snprintf(buf + length, PAGE_SIZE - length, + "Calibration Ext Data: "); + for (i = 0; i < MIUS_CALIBRATION_MAX_DISPLAY_COUNT; ++i) + length += snprintf(buf + length, + PAGE_SIZE - length, + "0x%02x ", caldata[i]); + length += snprintf(buf + length, PAGE_SIZE - length, + "\nTruncated at %d", + MIUS_CALIBRATION_MAX_DISPLAY_COUNT); + length += snprintf(buf + length, PAGE_SIZE - length, + "\nmisc: %u %u %u %u %u %u %u %u\n", + caldata[j - 7], caldata[j - 6], + caldata[j - 5], caldata[j - 4], + caldata[j - 3], caldata[j - 2], + caldata[j - 1], caldata[j]); + } + } else { + for (i = 0; i < calibration_obj->size; ++i) + length += snprintf(buf + length, PAGE_SIZE - length, + "0x%02x ", caldata[i]); + } + length += snprintf(buf + length, PAGE_SIZE - length, "\n\n"); + result = (ssize_t)length; + return result; +} + +static ssize_t calibration_v2_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return calibration_v2_show_core(dev, attr, buf, 0); +} + +static ssize_t diagnostics_show_core(struct device *dev, + struct device_attribute *attr, char *buf, + int pretty) +{ + ssize_t result; + int length; + uint32_t *data32; + int i; + + struct mius_shared_data_block *diagnostics_obj = + mius_get_shared_obj(MIUS_OBJ_ID_DIAGNOSTICS_DATA); + + if (kobject_create_and_add_failed) + MI_PRINT_E("kobject_create_and_add_failed"); + + if (sysfs_create_group_failed) + MI_PRINT_E("sysfs_create_group_failed"); + + if (diagnostics_obj == NULL) { + MI_PRINT_E("diagnostics_obj is NULL"); + return -EINVAL; + } + + if (diagnostics_obj->size > PAGE_SIZE) { + MI_PRINT_E("diagnostics_obj->size > PAGE_SIZE"); + return -EINVAL; + } + + length = 0; + data32 = (uint32_t *)diagnostics_obj->buffer; + + if (pretty) { + length += snprintf(buf + length, PAGE_SIZE - length, + "Diagnostics:\n counters:\n"); + for (i = 0; i < MIUS_DIAGNOSTICS_DATA_SECTION_COUNT; i++) + length += snprintf(buf + length, PAGE_SIZE - length, + " %u %u %u %u\n", data32[4 * i], + data32[4 * i + 1], data32[4 * i + 2], + data32[4 * i + 3]); + } else { + for (i = 0; i < (diagnostics_obj->size >> 4); ++i) + length += snprintf(buf + length, PAGE_SIZE - length, + " %u %u %u %u\n", data32[4 * i], + data32[4 * i + 1], data32[4 * i + 2], + data32[4 * i + 3]); + } + length += snprintf(buf + length, PAGE_SIZE - length, "\n\n"); + result = (ssize_t)length; + return result; +} + +static ssize_t diagnostics_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return diagnostics_show_core(dev, attr, buf, 0); +} + +static ssize_t ml_show_core(struct device *dev, struct device_attribute *attr, + char *buf, int pretty) +{ + ssize_t result; + int length; + int i; + uint32_t *mldata; + + struct mius_shared_data_block *ml_obj = + mius_get_shared_obj(MIUS_OBJ_ID_ML_DATA); + + if (kobject_create_and_add_failed) + MI_PRINT_E("kobject_create_and_add_failed"); + + if (sysfs_create_group_failed) + MI_PRINT_E("sysfs_create_group_failed"); + + if (ml_obj == NULL) { + MI_PRINT_E("ml_obj is NULL"); + return -EINVAL; + } + + if (ml_obj->size > PAGE_SIZE) { + MI_PRINT_E("ml_obj->size > PAGE_SIZE"); + return -EINVAL; + } + + mldata = (uint32_t *)ml_obj->buffer; + length = 0; + if (pretty) { + if (mldata[0] == 0x0 && mldata[1] == 0x0) { + length += snprintf(buf + length, PAGE_SIZE - length, + "ML Data: not loaded"); + } else { + length += snprintf(buf + length, PAGE_SIZE - length, + "ML Data: "); + for (i = 0; i < MIUS_ML_DISPLAY_COUNT; ++i) + length += snprintf(buf + length, + PAGE_SIZE - length, + "0x%08x ", mldata[i]); + length += snprintf(buf + length, PAGE_SIZE - length, + "\nTruncated at %d", + MIUS_ML_DISPLAY_COUNT); + } + } else { + int values = ml_obj->size >> 2; + + for (i = 0; i < values; ++i) + length += snprintf(buf + length, PAGE_SIZE - length, + "0x%08x ", mldata[i]); + } + length += snprintf(buf + length, PAGE_SIZE - length, "\n\n"); + result = (ssize_t)length; + return result; +} + +static ssize_t ml_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return ml_show_core(dev, attr, buf, 0); +} + +static ssize_t version_show_core(struct device *dev, + struct device_attribute *attr, char *buf, + int pretty) +{ + ssize_t result; + struct mius_engine_version_info *version_info; + int length; + + struct mius_shared_data_block *version_obj = + mius_get_shared_obj(MIUS_OBJ_ID_VERSION_INFO); + + if (kobject_create_and_add_failed) + MI_PRINT_E("kobject_create_and_add_failed"); + + if (sysfs_create_group_failed) + MI_PRINT_E("sysfs_create_group_failed"); + + if (version_obj == NULL) { + MI_PRINT_E("version_obj is NULL"); + return -EINVAL; + } + + if (version_obj->size > PAGE_SIZE) { + MI_PRINT_E("version_obj->size > PAGE_SIZE"); + return -EINVAL; + } + + version_info = (struct mius_engine_version_info *)version_obj->buffer; + + if (pretty) { + if (version_info->major == 0xDE && + version_info->minor == 0xAD) { + length = snprintf(buf, PAGE_SIZE, "Version: unknown\n"); + } else { + length = snprintf( + buf, PAGE_SIZE, "Version: %d.%d.%d.%d\n", + version_info->major, version_info->minor, + version_info->build, version_info->revision); + } + } else { + length = snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n", + version_info->major, version_info->minor, + version_info->build, version_info->revision); + } + result = (ssize_t)length; + return result; +} + +static ssize_t version_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return version_show_core(dev, attr, buf, 0); +} + +static ssize_t branch_show_core(struct device *dev, + struct device_attribute *attr, char *buf, + int pretty) +{ + int length; + + struct mius_shared_data_block *branch_obj = + mius_get_shared_obj(MIUS_OBJ_ID_BRANCH_INFO); + + if (branch_obj == NULL) { + MI_PRINT_E("branch_obj not found"); + return 0; + } + + if (branch_obj->size > PAGE_SIZE) { + MI_PRINT_E("branch_obj->size > PAGE_SIZE"); + return -EINVAL; + } + if (pretty) { + length = snprintf(buf, PAGE_SIZE - 1, "Branch: %s\n", + (const char *)(branch_obj->buffer)); + } else { + length = snprintf(buf, PAGE_SIZE - 1, "%s\n", + (const char *)(branch_obj->buffer)); + } + + return (ssize_t)length; +} + +static ssize_t branch_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return branch_show_core(dev, attr, buf, 0); +} + +static ssize_t tag_show_core(struct device *dev, struct device_attribute *attr, + char *buf, int pretty) +{ + int length; + + struct mius_shared_data_block *tag_obj = + mius_get_shared_obj(MIUS_OBJ_ID_TAG_INFO); + + if (tag_obj == NULL) { + MI_PRINT_E("tag_obj not found"); + return 0; + } + + if (tag_obj->size > PAGE_SIZE) { + MI_PRINT_E("tag_obj->size > PAGE_SIZE"); + return -EINVAL; + } + if (pretty) { + length = snprintf(buf, PAGE_SIZE - 1, "Tag: %s\n", + (const char *)(tag_obj->buffer)); + } else { + length = snprintf(buf, PAGE_SIZE - 1, "%s\n", + (const char *)(tag_obj->buffer)); + } + + return (ssize_t)length; +} + +static ssize_t tag_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return tag_show_core(dev, attr, buf, 0); +} + +static ssize_t cache_show(char *buf, int pretty) +{ + struct mius_system_configuration_parameters_cache *cache = + &mius_system_configuration_cache; + + int length; + + length = snprintf(buf, PAGE_SIZE - 1, "Cache:\n"); + length += snprintf(buf + length, PAGE_SIZE - 1, " mi:%d\n", + cache->microphone_index); + length += snprintf(buf + length, PAGE_SIZE - 1, " om:%d\n", + cache->operation_mode); + length += snprintf(buf + length, PAGE_SIZE - 1, " omf:%d\n", + cache->operation_mode_flags); + length += snprintf(buf + length, PAGE_SIZE - 1, " cs:%d\n", + cache->calibration_state); + length += snprintf(buf + length, PAGE_SIZE - 1, " cp:%d\n", + cache->calibration_profile); + length += snprintf(buf + length, PAGE_SIZE - 1, " ug:%d\n", + cache->ultrasound_gain); + length += snprintf(buf + length, PAGE_SIZE - 1, " ll:%d\n", + cache->log_level); + length += snprintf(buf + length, PAGE_SIZE - 1, " es:%d\n", + cache->engine_suspend); + + return (ssize_t)length; +} + +static ssize_t opmode_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int length; + ssize_t result; + + struct mius_system_configuration_parameters_cache *cache = + &mius_system_configuration_cache; + + length += snprintf(buf + length, PAGE_SIZE - 1, "%d\n", + cache->operation_mode); + result = (ssize_t)length; + return result; +} + +static ssize_t opmode_flags_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int length; + ssize_t result; + struct mius_system_configuration_parameters_cache *cache = + &mius_system_configuration_cache; + + length += snprintf(buf + length, PAGE_SIZE - 1, "%d\n", + cache->operation_mode_flags); + result = (ssize_t)length; + return result; +} + +static ssize_t driver_version_show(char *buf) +{ + int length; + + length = snprintf(buf, PAGE_SIZE, "Driver version: %s-%s (%s)\n", + build_name, build_number, build_source_version); + + return (ssize_t)length; +} + +static ssize_t state_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int length = 0; + + length += driver_version_show(buf + length); + length += version_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += branch_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += tag_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += calibration_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += calibration_v2_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += diagnostics_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += ml_show_core(dev, attr, buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + length += cache_show(buf + length, 1); + if (length > PAGE_SIZE) + return (ssize_t)0; + return (ssize_t)length; +} + +static struct device_attribute calibration_attr = __ATTR_RW(calibration); +static struct device_attribute version_attr = __ATTR_RO(version); +static struct device_attribute branch_attr = __ATTR_RO(branch); +static struct device_attribute calibration_v2_attr = __ATTR_RW(calibration_v2); +static struct device_attribute diagnostics_attr = __ATTR_RW(diagnostics); +static struct device_attribute state_attr = __ATTR_RO(state); +static struct device_attribute tag_attr = __ATTR_RO(tag); +static struct device_attribute ml_attr = __ATTR_RW(ml); +static struct device_attribute opmode_attr = __ATTR_RO(opmode); +static struct device_attribute opmode_flags_attr = __ATTR_RO(opmode_flags); + +static struct attribute *mius_attrs[] = { + &calibration_attr.attr, + &version_attr.attr, + &branch_attr.attr, + &calibration_v2_attr.attr, + &diagnostics_attr.attr, + &state_attr.attr, + &tag_attr.attr, + &ml_attr.attr, + &opmode_attr.attr, + &opmode_flags_attr.attr, + NULL, +}; + +static struct attribute_group mius_attr_group = { + .name = MIUS_SYSFS_ENGINE_FOLDER, + .attrs = mius_attrs, +}; + +static struct kobject *mius_sysfs_kobj; + +int mius_initialize_sysfs(void) +{ + int err; + + mius_sysfs_kobj = kobject_create_and_add(MIUS_SYSFS_ROOT_FOLDER, + kernel_kobj->parent); + + if (!mius_sysfs_kobj) { + kobject_create_and_add_failed = 1; + MI_PRINT_E("failed to create kobj"); + return -ENOMEM; + } + + err = sysfs_create_group(mius_sysfs_kobj, &mius_attr_group); + + if (err) { + sysfs_create_group_failed = 1; + MI_PRINT_E("failed to create sysfs group"); + kobject_put(mius_sysfs_kobj); + return -ENOMEM; + } + + return 0; +} + +void mius_cleanup_sysfs(void) +{ + kobject_put(mius_sysfs_kobj); +} diff --git a/techpack/audio/dsp/mius/mius_version.h b/techpack/audio/dsp/mius/mius_version.h new file mode 100644 index 000000000000..ae6be14654ed --- /dev/null +++ b/techpack/audio/dsp/mius/mius_version.h @@ -0,0 +1,8 @@ +#ifndef MIUS_VERSION_H +#define MIUS_VERSION_H + +#define build_name "Mi.LinuxKernelDriver.VendorDLKM.master" +#define build_number "20181016.1" +#define build_source_version "e5e26691554bba9b1438ec3d7e0cc55dfb296bb8" + +#endif //MIUS_VERSION_H diff --git a/techpack/audio/dsp/msm-cirrus-playback-v2.c b/techpack/audio/dsp/msm-cirrus-playback-v2.c new file mode 100644 index 000000000000..aa0b5946f0fb --- /dev/null +++ b/techpack/audio/dsp/msm-cirrus-playback-v2.c @@ -0,0 +1,1405 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +* Copyright (C) 2021 XiaoMi, Inc. +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 and +* only version 2 as published by the Free Software Foundation. +* +* 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. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#undef CONFIG_OF +#define CRUS_AMP_FACTOR 71498 +#define CRUS_MATERIAL_FACTOR 250 +#define CRUS_T_SCALE_FACTOR 100000 +#define CRUS_Z_SCALE_FACTOR 100000000 +#define CIRRUS_NONE 0 +#define CIRRUS_COPP 1 +#define CIRRUS_AFE 2 + +#undef pr_info +#undef pr_err +#undef pr_debug +#define pr_debug(fmt, args...) printk(KERN_INFO "[CSPL] " pr_fmt(fmt), ##args) +#define pr_info(fmt, args...) printk(KERN_INFO "[CSPL] " pr_fmt(fmt), ##args) +#define pr_err(fmt, args...) printk(KERN_ERR "[CSPL] " pr_fmt(fmt), ##args) +#define CRUS_TX_CONFIG "crus_sp_tx%d.bin" +#define CRUS_RX_CONFIG "crus_sp_rx%d.bin" + +#define CIRRUS_RX_GET_IODATA 0x00A1AF09 +#define CIRRUS_TX_GET_IODATA 0x00A1BF09 + +static struct crus_sp_ioctl_header crus_sp_hdr; +#define xCACHE_COMMANDS +static struct crus_control_t this = { + .module_id = CIRRUS_SP, + .fb_port = AFE_PORT_ID_QUATERNARY_TDM_TX, + .ff_port = AFE_PORT_ID_QUATERNARY_TDM_RX, + .usecase_dt_count = MAX_TUNING_CONFIGS, + .usecase = 0, + .conf_index = 0, + .delta_index = 0, + .swap_duration = 30, + .location = CIRRUS_COPP, + .sp_enable = 1, // enable by default + .vol_atten = 0, + .resistance_en = true, + .prot_en = false, + .copp_idx = 0, + .copp_ids = { INVALID_COPPID, INVALID_COPPID, INVALID_COPPID }, + + .swap = 0, + .initialized = false, +}; + +#define CHAR_BIT 8 +unsigned int crc32(int *message) +{ /* Only supports 32-bit for now */ + int i, j; + unsigned int crc; + + crc = ~0; + for (i = 0; i < message[0] - 1; + i++) /* Loop through the array, excluding the CRC */ + { + crc = crc ^ message[i]; + for (j = 0; j < sizeof(*message) * CHAR_BIT; j++) { + crc = (crc >> 1) ^ (0xEDB88320 & -(crc & 1)); + } + } + return ~crc; +} + +static int crc_check(int *params, int size) +{ + int crc, crc_idx, ret = 0, i = 0; + + for (i = 0; i < size; i += params[i]) { + crc_idx = i + params[i] - 1; + crc = crc32(¶ms[i]); + if (crc != params[crc_idx]) { + pr_err("crc failed: %d != %d\n", crc, params[crc_idx]); + ret = -1; + } + } + + return ret; +} + +#define IS_DIGIT(number) ((number) >= '0' && (number) <= '9') +#define IS_PARAM_CHAR(number) ((number) == '-' || (IS_DIGIT(number))) +static bool is_params_str(char *str) +{ + int i = 0, start = 0; + bool ret = true; + + if (strlen(str) <= 0) + return -1; + + if (str[0] == '-') + start = 1; + for (i = start; i < strlen(str); i++) { + if (!IS_DIGIT(str[start])) { + ret = false; + break; + } + } + + return ret; +} + +static int tuning_parser(const char *bytes, int size_byte, int *params, + int *size) +{ + int i = 0, n, ret = 0; + char buf[24] = { + 0, + }; + + *size = 0; + for (i = 0; bytes[i] != '\0' && i < size_byte; i++) { + if (!IS_PARAM_CHAR(bytes[i])) + continue; + n = 0; + for (; bytes[i] != ',' && bytes[i] != '\n' && bytes[i] != '\0'; + i++) { + if (!IS_PARAM_CHAR(bytes[i])) + break; + buf[n++] = bytes[i]; + } + + buf[n] = '\0'; + if (!is_params_str(buf)) + continue; + + if (kstrtos32(buf, 10, params++) < 0) + continue; + + *size += 1; + pr_info("%d: %s\n", *size, buf); + } + + return ret; +} + +#ifdef CACHE_COMMANDS +LIST_HEAD(cache_list); +static void cache_block_destroy(void *block) +{ + kfree(block); +} + +static struct cache_block * +crus_block_initial(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol, snd_kcontrol_put_t *put) +{ + struct cache_block *db = + kzalloc(sizeof(struct cache_block), GFP_KERNEL); + + if (db == NULL) { + pr_info("%s: Fail to alloc for: '%s'\n", __func__, + kcontrol->id.name); + return NULL; + } + + memcpy(&db->kcontrol, kcontrol, sizeof(struct snd_kcontrol)); + memcpy(&db->ucontrol, ucontrol, sizeof(struct snd_ctl_elem_value)); + db->destroy = cache_block_destroy; + + return db; +} + +static bool crus_cache_push(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol, + snd_kcontrol_put_t *put) +{ + struct cache_block *db; + struct list_head *cursor, *head; + + if (atomic_read(&this.qdsp_start_count[this.location]) == 0) { + pr_info("%s: port started, no need cache: '%s'\n", __func__, + kcontrol->id.name); + return false; + } + + list_for_each_safe (cursor, head, &cache_list) { + db = list_entry(cursor, struct cache_block, entry); + if (db == NULL) + continue; + if (!strcmp(db->kcontrol.id.name, kcontrol->id.name)) { + pr_info("%s: cache block remove duplicated one: '%s'\n", + __func__, kcontrol->id.name); + list_del(cursor); + cache_block_destroy(db); + break; + } + } + + db = crus_block_initial(kcontrol, ucontrol, put); + if (db == NULL) + return false; + + pr_info("%s: cache block: %p, '%s'\n", __func__, db, kcontrol->id.name); + db->put = put; + list_add_tail(&db->entry, &cache_list); + + return true; +} + +static void crus_cache_pop_execute(void) +{ + struct cache_block *db; + struct list_head *cursor, *head; + + if (list_empty(&cache_list)) + return; + + list_for_each_safe (cursor, head, &cache_list) { + db = list_last_entry(&cache_list, struct cache_block, entry); + if (db == NULL) + continue; + + pr_info("%s:%p - put '%s'\n", __func__, db, + db->kcontrol.id.name); + + if (db->put) { + this.cache_execute = true; + db->put(&db->kcontrol, &db->ucontrol); + this.cache_execute = false; + } + + list_del(cursor); + cache_block_destroy(db); + db = NULL; + } + + INIT_LIST_HEAD(&cache_list); +} +#endif +static int crus_get_copp_id(void) +{ + int i = 0; + for (i = 0; i < 3; i++) { + if (this.copp_ids[i] != INVALID_COPPID) + return this.copp_ids[i]; + } + + return 0; +} +static int crus_get_param(int port_id, int param_id, void *data, int length) +{ + int copp_idx = 0; + + if (atomic_read(&this.qdsp_start_count[this.location]) == 0) { + pr_info("%s: port '0x%x' not yet start!\n", __func__, port_id); + return 0; + } + + switch (this.location) { + case CIRRUS_AFE: + crus_afe_get_params(port_id, this.module_id, param_id, data, + length); + break; + case CIRRUS_COPP: + copp_idx = crus_get_copp_id(); + crus_adm_get_params(port_id, copp_idx, this.instance_id, + this.module_id, param_id, data, length, 0); + break; + default: + break; + } + return 0; +} +static int crus_set_param(int port_id, int param_id, void *data, int length) +{ + int copp_idx = 0; + if (atomic_read(&this.qdsp_start_count[this.location]) == 0) { + pr_info("%s: port '0x%x' not yet start!\n", __func__, port_id); + return 0; + } + + switch (this.location) { + case CIRRUS_AFE: + crus_afe_set_params(port_id, this.module_id, param_id, data, + length); + break; + case CIRRUS_COPP: + copp_idx = crus_get_copp_id(); + crus_adm_set_params(port_id, copp_idx, this.instance_id, + this.module_id, param_id, data, length); + break; + default: + break; + } + return 0; +} + +#define CONF_HEADER(buf, total_bytes, chunk_bytes, done) \ + do { \ + buf[0] = (total_bytes) * sizeof(int); \ + buf[1] = (chunk_bytes) * sizeof(int); \ + buf[2] = (done); \ + buf[3] = 0; \ + buf[4] = 4; \ + } while (0) + +static int crus_send_config(const char *data, int32_t length, int32_t port) +{ + int i = 0, ret = 0, chunk = 90, head_size = 5; + int rest, last_index, total_size; + int *payload = this.apr_payload; + int *params = this.tuning; + int param_id, payload_size; + + pr_err("Wing: Invalid port %d\n", port); + /* Destination settings for message */ + if (port == this.ff_port) + param_id = CRUS_PARAM_RX_SET_EXT_CONFIG; + else if (port == this.fb_port) + param_id = CRUS_PARAM_TX_SET_EXT_CONFIG; + else { + pr_err("Invalid port %d\n", port); + return -EINVAL; + } + + memset(params, 0x00, TUNING_MAX_SIZE * sizeof(int)); + memset(payload, 0x00, APR_CHUNK_SIZE * sizeof(int)); + + //firmware_request("delta0_raw_full.txt", &bytes, &size_byte); + if (tuning_parser(data, length, params, &total_size) < 0) + return -1; + if (crc_check(params, total_size) < 0) + return -1; + + rest = total_size % chunk; + if (rest == 0) { + last_index = total_size / chunk - 1; + rest = chunk; + } else { + last_index = total_size / chunk; + } + + pr_info("rest = %d, last_index=%d, total_size=%d\n", rest, last_index, + total_size); + + payload_size = chunk + head_size; + for (i = 0; i <= last_index - 1; i++) { + CONF_HEADER(payload, total_size, chunk, 0); + memcpy(&payload[head_size], ¶ms[i * chunk], + chunk * sizeof(int)); + crus_set_param(port, param_id, payload, + payload_size * sizeof(int)); + } + + /* send last chunk */ + payload_size = rest + head_size; + CONF_HEADER(payload, total_size, rest, 1 /*done*/); + memcpy(&payload[head_size], ¶ms[i * chunk], rest * sizeof(int)); + crus_set_param(port, param_id, payload, payload_size * sizeof(int)); + + return ret; +} + +#define DELTA_HEADER(buf, total_bytes, chunk_bytes, done, index) \ + do { \ + buf[0] = (total_bytes) * sizeof(int); \ + buf[1] = (chunk_bytes) * sizeof(int); \ + buf[2] = (done); \ + buf[3] = index; \ + buf[4] = 0; \ + buf[5] = 4; \ + } while (0) + +static int crus_send_delta(const char *data, uint32_t length) +{ + int i = 0, ret = 0, chunk = 90, head_size = 6; + int rest, last_index, total_size, payload_size; + int param_id = CRUS_PARAM_RX_SET_DELTA_CONFIG; + int *payload = this.apr_payload; + int *params = this.tuning; + int port = this.ff_port; + + memset(params, 0x00, TUNING_MAX_SIZE * sizeof(int)); + memset(payload, 0x00, APR_CHUNK_SIZE * sizeof(int)); + //firmware_request("delta0_raw_full.txt", &bytes, &size_byte); + if (tuning_parser(data, length, params, &total_size) < 0) + return -1; + if (crc_check(params, total_size) < 0) + return -1; + + rest = total_size % chunk; + if (rest == 0) { + last_index = total_size / chunk - 1; + rest = chunk; + } else { + last_index = total_size / chunk; + } + + pr_info("rest = %d, last_index=%d, total_size=%d\n", rest, last_index, + total_size); + + payload_size = chunk + head_size; + for (i = 0; i <= last_index - 1; i++) { + DELTA_HEADER(payload, total_size, chunk, 0, 0); + memcpy(&payload[head_size], ¶ms[i * chunk], + chunk * sizeof(int)); + crus_set_param(port, param_id, payload, + payload_size * sizeof(int)); + } + + /* send last chunk */ + payload_size = rest + head_size; + DELTA_HEADER(payload, total_size, rest, 1 /*done*/, 0); + memcpy(&payload[head_size], ¶ms[i * chunk], rest * sizeof(int)); + crus_set_param(port, param_id, payload, payload_size * sizeof(int)); + + return ret; +} + +static int crus_location_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int location = ucontrol->value.integer.value[0]; + + pr_info("%s: %d\n", __func__, location); + + switch (location) { + case CIRRUS_AFE: + case CIRRUS_COPP: + case CIRRUS_NONE: + this.location = location; + break; + default: + break; + } + + return 0; +} + +static int crus_location_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: this.location= %d", __func__, this.location); + ucontrol->value.integer.value[0] = this.location; + return 0; +} + +static int crus_rx_port_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + this.ff_port = ucontrol->value.integer.value[0]; + pr_info("%s: set rx port: %d\n", __func__, this.ff_port); + return 0; +} + +static int crus_rx_port_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = this.ff_port; + return 0; +} +static int crus_tx_port_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + this.fb_port = ucontrol->value.integer.value[0]; + pr_info("%s: set tx port: %d\n", __func__, this.fb_port); + return 0; +} + +static int crus_tx_port_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = this.fb_port; + return 0; +} + +static int crus_enable_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + this.sp_enable = ucontrol->value.integer.value[0]; + + crus_set_param(this.ff_port, CIRRUS_SP_ENABLE, (void *)&this.sp_enable, + sizeof(struct crus_single_data_t)); + + if (this.prot_en) + crus_set_param(this.fb_port, CIRRUS_SP_ENABLE, + (void *)&this.sp_enable, + sizeof(struct crus_single_data_t)); + + return 0; +} + +static int crus_enable_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = this.sp_enable; + return 0; +} + +static int crus_prot_enable_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_err("Cirrus SP Protection Enable is set via DT\n"); + return 0; +} + +static int crus_prot_enable_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = this.prot_en ? 1 : 0; + return 0; +} + +static int crus_usecase_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + const int index = ucontrol->value.integer.value[0]; + struct crus_rx_run_case_ctrl_t case_ctrl; + struct crus_rx_temperature_t rx_temp; + int buffer[CRUS_MAX_BUFFER_SIZE / 4]; + + if (index >= e->items) { + pr_err("Config index out of bounds (%d)\n", index); + return -EINVAL; + } + + pr_info("%s: '%s' <-- '%s'\n", __func__, kcontrol->id.name, + e->texts[index]); + + this.usecase = index; + +#ifdef CACHE_COMMANDS + if (!this.cache_execute && + crus_cache_push(kcontrol, ucontrol, crus_usecase_put)) + return 0; +#endif + + crus_get_param(this.ff_port, CRUS_PARAM_RX_GET_TEMP, buffer, + CRUS_MAX_BUFFER_SIZE); + + memcpy(&rx_temp, buffer, sizeof(rx_temp)); + + case_ctrl.status_l = 1; + case_ctrl.status_r = 1; + case_ctrl.z_l = rx_temp.z_l; + case_ctrl.z_r = rx_temp.z_r; + case_ctrl.checksum_l = rx_temp.z_l + 1; + case_ctrl.checksum_r = rx_temp.z_r + 1; + case_ctrl.atemp = rx_temp.amb_temp_l; + case_ctrl.value = this.usecase; + + if (this.prot_en) { + crus_set_param(this.fb_port, CRUS_PARAM_TX_SET_USECASE, + (void *)&this.usecase, sizeof(this.usecase)); + } + + crus_set_param(this.ff_port, CRUS_PARAM_RX_SET_USECASE, + (void *)&case_ctrl, sizeof(case_ctrl)); + + return 0; +} + +static int crus_usecase_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_info("%s: %d\n", __func__, this.usecase); + ucontrol->value.integer.value[0] = this.usecase; + + return 0; +} +static int crus_load_rx_config_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct soc_enum *soc_enum = (struct soc_enum *)kcontrol->private_value; + unsigned int i = ucontrol->value.enumerated.item[0]; + const struct firmware *firmware; + + if (i >= soc_enum->items) { + pr_err("Invalid mixer input (%u)\n", i); + return -EINVAL; + } + + if (request_firmware(&firmware, soc_enum->texts[i], component->dev) != + 0) { + pr_err("Request firmware '%s' failed!\n", soc_enum->texts[i]); + this.delta_index = 0; + return -EINVAL; + } + + pr_info("Requestd:%s, value=%d\n", soc_enum->texts[i], + soc_enum->values[i]); + crus_send_config(firmware->data, firmware->size, this.ff_port); + this.conf_index = i; + + release_firmware(firmware); + + return 0; +} + +static int crus_load_rx_config_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: %d\n", __func__, this.conf_index); + ucontrol->value.integer.value[0] = this.conf_index; + return 0; +} + +static int crus_load_delta_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: %d\n", __func__, this.conf_index); + ucontrol->value.enumerated.item[0] = this.delta_index; + + return 0; +} + +static int crus_load_delta_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct soc_enum *soc_enum = (struct soc_enum *)kcontrol->private_value; + unsigned int i = ucontrol->value.enumerated.item[0]; + const struct firmware *firmware; + struct crus_single_data_t data; + + if (i >= soc_enum->items) { + pr_err("Invalid mixer input (%u)\n", i); + return -EINVAL; + } + + if (request_firmware(&firmware, soc_enum->texts[i], component->dev) != + 0) { + pr_err("Request firmware '%s' failed!\n", soc_enum->texts[i]); + this.delta_index = 0; + return -EINVAL; + } + + pr_info("Requestd: '%s'\n", soc_enum->texts[i]); + crus_send_delta(firmware->data, firmware->size); + + this.delta_index = i; + release_firmware(firmware); + + data.value = 0; + crus_set_param(this.ff_port, CRUS_PARAM_RX_RUN_DELTA_CONFIG, &data, + sizeof(struct crus_single_data_t)); + + return 0; +} +#if 0 +static int crus_vol_attn_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + const int crus_set = ucontrol->value.integer.value[0]; + struct crus_dual_data_t data; + + //mutex_lock(&this.sp_lock); + + this.vol_atten = crus_set; + + switch (crus_set) { + case 0: /* 0dB */ + data.data1 = VOL_ATTN_MAX; + data.data2 = VOL_ATTN_MAX; + break; + case 1: /* -18dB */ + data.data1 = VOL_ATTN_18DB; + data.data2 = VOL_ATTN_18DB; + break; + case 2: /* -24dB */ + data.data1 = VOL_ATTN_24DB; + data.data2 = VOL_ATTN_24DB; + break; + default: + return -EINVAL; + } + + crus_set_param(this.ff_port, CRUS_PARAM_RX_SET_ATTENUATION, &data, + sizeof(struct crus_dual_data_t)); + + //mutex_unlock(&this.sp_lock); + + return 0; +} + +static int crus_vol_attn_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("Starting Cirrus SP Volume Attenuation Get function call\n"); + ucontrol->value.integer.value[0] = this.vol_atten; + + return 0; +} +#endif + +static int crus_chan_swap_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct crus_dual_data_t data; + const int crus_set = ucontrol->value.integer.value[0]; + + switch (crus_set) { + case 0: /* L/R */ + data.data1 = 1; + break; + case 1: /* R/L */ + data.data1 = 2; + break; + default: + return -EINVAL; + } + + data.data2 = this.swap; + + crus_set_param(this.ff_port, CRUS_PARAM_RX_CHANNEL_SWAP, &data, + sizeof(struct crus_dual_data_t)); + + this.swap = !!crus_set; + + return 0; +} +static int crus_chan_swap_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct crus_single_data_t data; + pr_debug("%s: %d\n", __func__, this.swap); + crus_get_param(this.ff_port, CRUS_PARAM_RX_GET_CHANNEL_SWAP, &data, + sizeof(struct crus_single_data_t)); + + ucontrol->value.integer.value[0] = this.swap; + + return 0; +} + +static int crus_chan_swap_dur_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int crus_set = ucontrol->value.integer.value[0]; + + if ((crus_set < 0) || (crus_set > MAX_CHAN_SWAP_SAMPLES)) { + pr_err("Value out of range (%d)\n", crus_set); + return -EINVAL; + } + + if (crus_set < MIN_CHAN_SWAP_SAMPLES) { + pr_info("Received %d, round up to min value %d\n", crus_set, + MIN_CHAN_SWAP_SAMPLES); + crus_set = MIN_CHAN_SWAP_SAMPLES; + } + + this.swap_duration = crus_set; + + return 0; +} + +static int crus_chan_swap_dur_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: %d\n", __func__, this.swap_duration); + + ucontrol->value.integer.value[0] = this.swap_duration; + + return 0; +} +static int crus_fail_det_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + this.fail_det = ucontrol->value.integer.value[0]; + return 0; +} + +static int crus_fail_det_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = this.fail_det; + return 0; +} + +static int crus_resistance_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct crus_single_data_t data; + const int crus_set = ucontrol->value.integer.value[0]; + + if (!this.prot_en) { + pr_err("CRUS_SP: Need feedback module to enable resistance calculation\n"); + return -EINVAL; + } + + switch (crus_set) { + case 0: /* Disable */ + this.resistance_en = false; + data.value = 0; + break; + case 1: /* Enable */ + this.resistance_en = true; + data.value = 1; + break; + default: + return -EINVAL; + } + + // crus_set_param(this.fb_port, CRUS_PARAM_TX_RESISTANCE, + // &data, sizeof(struct crus_single_data_t)); + + return 0; +} + +static int crus_resistance_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = this.resistance_en ? 1 : 0; + return 0; +} + +static const char *const crus_en_text[] = { "Disable", "Enable" }; +static const char *const crus_prot_en_text[] = { "Disable", "Enable" }; +static const char *const crus_usecase_text[] = { "Music", "Game", "Handsfree", + "Movie" }; +static const char *const crus_conf_load_text[] = { "Idle", "Load RX", + "Load TX" }; +static const char *const crus_conf_load_no_prot_text[] = { "Idle", "Load" }; +static const char *const crus_chan_swap_text[] = { "LR", "RL" }; +static const char *const crus_resistance_text[] = { "Disable", "Enable" }; +static const char *const cirrus_location_text[] = { "NONE", "COPP", "AFE" }; + +static const struct soc_enum cirrus_location_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(cirrus_location_text), + cirrus_location_text), +}; +static struct soc_enum crus_usecase_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(crus_usecase_text), crus_usecase_text); +static const char *const crus_dt_text[] = { + "delta_0.txt", "delta_1.txt", "delta_2.txt", "delta_3.txt", + "delta_4.txt", "delta_5.txt", "delta_6.txt", "delta_7.txt", + "delta_8.txt", "delta_9.txt", "delta_10.txt", "delta_11.txt", + "delta_12.txt", "delta_13.txt", "delta_14.txt", "delta_15.txt", + "delta_16.txt", "delta_17.txt", "delta_18.txt", "delta_19.txt", + "delta_20.txt", "delta_21.txt", "delta_22.txt", "delta_23.txt", + "delta_24.txt", "delta_25.txt", "delta_26.txt", "delta_27.txt", + "delta_28.txt", "delta_29.txt", +}; + +static struct soc_enum crus_dt_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(crus_dt_text), crus_dt_text); +static const char *const crus_conf_text[] = { + "config_0.txt", "config_1.txt", "config_2.txt", "config_3.txt", + "config_4.txt", "config_5.txt", "config_6.txt", "config_7.txt", + "config_8.txt", "config_9.txt", "config_10.txt", "config_11.txt", + "config_12.txt", "config_13.txt", "config_14.txt", "config_15.txt", + "config_16.txt", "config_17.txt", "config_18.txt", "config_19.txt", + "config_20.txt", "config_21.txt", "config_22.txt", "config_23.txt", + "config_24.txt", "config_25.txt", "config_26.txt", "config_27.txt", + "config_28.txt", "config_29.txt", +}; + +static struct soc_enum crus_conf_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(crus_conf_text), crus_conf_text); + +static const struct snd_kcontrol_new crus_core_controls[] = { + SOC_SINGLE_EXT("Cirrus SP Rx Port", SND_SOC_NOPM, 0, 0x7FFFFFF, 0, + crus_rx_port_get, crus_rx_port_put), + SOC_SINGLE_EXT("Cirrus SP Tx Port", SND_SOC_NOPM, 0, 0x7FFFFFF, 0, + crus_tx_port_get, crus_tx_port_put), + SOC_ENUM_EXT("Cirrus SP Module", + (struct soc_enum)SOC_ENUM_SINGLE_EXT( + ARRAY_SIZE(crus_en_text), crus_en_text), + crus_enable_get, crus_enable_put), + SOC_ENUM_EXT("Cirrus SP Protection", + (struct soc_enum)SOC_ENUM_SINGLE_EXT( + ARRAY_SIZE(crus_prot_en_text), crus_prot_en_text), + crus_prot_enable_get, crus_prot_enable_put), + + SOC_ENUM_EXT("Cirrus SP Channel Swap", + (struct soc_enum)SOC_ENUM_SINGLE_EXT( + ARRAY_SIZE(crus_chan_swap_text), + crus_chan_swap_text), + crus_chan_swap_get, crus_chan_swap_put), + SOC_ENUM_EXT("Cirrus SP Usecase", crus_usecase_enum, crus_usecase_get, + crus_usecase_put), + SOC_SINGLE_EXT("Cirrus SP Channel Swap Duration", SND_SOC_NOPM, 0, + MAX_CHAN_SWAP_SAMPLES, 0, crus_chan_swap_dur_get, + crus_chan_swap_dur_put), + SOC_ENUM_EXT("Cirrus SP Resistance", + (struct soc_enum)SOC_ENUM_SINGLE_EXT( + ARRAY_SIZE(crus_resistance_text), + crus_resistance_text), + crus_resistance_get, crus_resistance_put), + SOC_ENUM_EXT("Cirrus SP Location", cirrus_location_enum[0], + crus_location_get, crus_location_put), + SOC_ENUM_EXT("Cirrus SP Delta", crus_dt_enum, crus_load_delta_get, + crus_load_delta_put), + SOC_ENUM_EXT("Cirrus SP Load Rx Config", crus_conf_enum, + crus_load_rx_config_get, crus_load_rx_config_put), +}; +static const struct snd_kcontrol_new crus_prot_controls[] = { + SOC_SINGLE_BOOL_EXT("Cirrus SP Failure Detection", 0, crus_fail_det_get, + crus_fail_det_put), +}; + +static const struct snd_kcontrol_new crus_no_prot_controls[] = {}; +#if 0 +static int crus_status_dump(int module_id, int param_id) +{ + int port; + int i = 0; + short *vmon0, *vmon1, *imon0, *imon1; + static int param_buf[1024] = { 0 }; + + switch (module_id) { + case CRUS_MODULE_ID_TX: + port = this.fb_port; + break; + case CRUS_MODULE_ID_RX: + port = this.ff_port; + break; + default: + pr_info("%s: Unrecognized port ID (%d)\n", __func__, + crus_sp_hdr.module_id); + port = this.ff_port; + break; + } + + memset(param_buf, 0x0, sizeof(param_buf)); + + crus_get_param(port, this.module, param_id, param_buf, 96*4); + vmon0 = (short *)&(param_buf[0]); + imon1 = (short *)&(param_buf[24]); + vmon1 = (short *)&(param_buf[24*2]); + imon0 = (short *)&(param_buf[24*3]); + + for(i = 0; i < 48; i ++) { + pr_info("%d, %d, %d, %d\n", vmon0[i], imon0[i], vmon1[i], imon1[i]); + } + + return 0; +} +#endif +void msm_crus_pb_set_copp_idx(int port_id, int copp_idx) +{ + if (port_id != this.ff_port) + return; + + pr_info("%s: port_id = 0x%x, copp_idx = %d\n", __func__, port_id, + copp_idx); + this.copp_idx = copp_idx; +} +EXPORT_SYMBOL(msm_crus_pb_set_copp_idx); + +void msm_crus_pb_add_controls(struct snd_soc_component *component) +{ + pr_err("Wing: %s: \n", __func__); + snd_soc_add_component_controls(component, crus_core_controls, + ARRAY_SIZE(crus_core_controls)); + pr_info("%s: end\n", __func__); +} + +EXPORT_SYMBOL(msm_crus_pb_add_controls); + +int crus_qdsp_port_start(u16 port_id, int copp_id) +{ + if (port_id != this.ff_port) + return 0; + + /* copp_id = -1 in AFE*/ + if (copp_id == INVALID_COPPID && this.location == CIRRUS_COPP) + return 0; + + atomic_inc(&this.qdsp_start_count[this.location]); + pr_info("%s:port_id = 0x%x, copp_id = %d, count = %d\n", __func__, + port_id, copp_id, this.qdsp_start_count[this.location]); + + if (this.location == CIRRUS_COPP) + this.copp_ids[copp_id] = copp_id; + +#ifdef CACHE_COMMANDS + crus_cache_pop_execute(); +#endif + return 0; +} +EXPORT_SYMBOL(crus_qdsp_port_start); + +int crus_qdsp_port_close(u16 port_id, int copp_id) +{ + if (port_id != this.ff_port) + return 0; + + /* copp_id = -1 in AFE*/ + if (copp_id == -1 && this.location == CIRRUS_COPP) + return 0; + + if (atomic_dec_return(&this.qdsp_start_count[this.location]) == 0) { + pr_info("%s: all stream on '0x%x' closed\n", __func__, port_id); + } + + pr_info("%s: port_id = 0x%x, copp_id = %d, count = %d\n", __func__, + port_id, copp_id, this.qdsp_start_count[this.location]); + + if (this.location == CIRRUS_COPP) { + this.copp_ids[copp_id] = INVALID_COPPID; + } + + return 0; +} +EXPORT_SYMBOL(crus_qdsp_port_close); + +static long crus_sp_shared_ioctl(struct file *f, unsigned int cmd, + void __user *arg) +{ + int result = 0, port, n; + uint32_t bufsize = 0, size; + void *io_data = NULL; + + pr_info("%s\n", __func__); + + if (copy_from_user(&size, arg, sizeof(size))) { + pr_err("%s: copy_from_user (size) failed\n", __func__); + result = -EFAULT; + goto exit; + } + + /* Copy IOCTL header from usermode */ + if (copy_from_user(&crus_sp_hdr, arg, size)) { + pr_err("%s: copy_from_user (struct) failed\n", __func__); + result = -EFAULT; + goto exit; + } + + switch (crus_sp_hdr.module_id) { + case CRUS_MODULE_ID_TX: + port = this.fb_port; + break; + case CRUS_MODULE_ID_RX: + port = this.ff_port; + break; + default: + pr_info("Unrecognized port ID (%d)\n", crus_sp_hdr.module_id); + port = this.ff_port; + } + + bufsize = crus_sp_hdr.data_length; + io_data = kzalloc(bufsize, GFP_KERNEL); + + switch (cmd) { + case CRUS_SP_IOCTL_GET: + crus_get_param(port, crus_sp_hdr.param_id, io_data, bufsize); + result = copy_to_user(crus_sp_hdr.data, io_data, bufsize); + if (result) { + pr_err("copy_to_user failed (%d)\n", result); + result = -EFAULT; + } else { + result = bufsize; + } + break; + case CRUS_SP_IOCTL_SET: + result = copy_from_user(io_data, (void *)crus_sp_hdr.data, + bufsize); + if (result) { + pr_err("copy_from_user failed (%d)\n", result); + result = -EFAULT; + goto exit_io; + } +#if 1 + for (n = 0; n < bufsize / sizeof(int); n++) { + pr_info("iodata[%d]=%d\n", n, ((int *)io_data)[n]); + } +#endif + crus_set_param(port, crus_sp_hdr.param_id, io_data, bufsize); + break; + default: + pr_err("Invalid IOCTL, command = %d\n", cmd); + result = -EINVAL; + break; + } + +exit_io: + kfree(io_data); +exit: + return result; +} + +static long crus_sp_ioctl(struct file *f, unsigned int cmd, unsigned long arg) +{ + pr_info("%s\n", __func__); + + return crus_sp_shared_ioctl(f, cmd, (void __user *)arg); +} + +static long crus_compat_ioctl(struct file *f, unsigned int cmd, + unsigned long arg) +{ + unsigned int cmd64; + + pr_info("%s\n", __func__); + + switch (cmd) { + case CRUS_SP_IOCTL_GET32: + cmd64 = CRUS_SP_IOCTL_GET; + break; + case CRUS_SP_IOCTL_SET32: + cmd64 = CRUS_SP_IOCTL_SET; + break; + default: + pr_err("%s: Invalid IOCTL, command = %d!\n", __func__, cmd); + return -EINVAL; + } + + return crus_sp_shared_ioctl(f, cmd64, compat_ptr(arg)); +} + +static int crus_ioctl_open(struct inode *inode, struct file *f) +{ + pr_debug("%s\n", __func__); + + atomic_inc(&this.ioctl_count); + return 0; +} + +static int crus_ioctl_release(struct inode *inode, struct file *f) +{ + atomic_dec(&this.ioctl_count); + + return 0; +} + +static ssize_t temperature_left_show(struct device *dev, + struct device_attribute *a, char *buf) +{ + struct crus_rx_temperature_t rx_temp; + int buffer[CRUS_MAX_BUFFER_SIZE / 4]; + int z, r, t, temp0; + + crus_get_param(this.ff_port, CRUS_PARAM_RX_GET_TEMP, buffer, + CRUS_MAX_BUFFER_SIZE); + + memcpy(&rx_temp, buffer, sizeof(rx_temp)); + + if ((rx_temp.hp_status_l != 2) || (rx_temp.full_status_l != 2)) + return snprintf(buf, PAGE_SIZE, "Calibration is not done\n"); + + z = rx_temp.z_l; + r = rx_temp.temp_l; + temp0 = rx_temp.amb_temp_l; + + t = (CRUS_MATERIAL_FACTOR * CRUS_T_SCALE_FACTOR * (r - z) / z) + + (temp0 * CRUS_T_SCALE_FACTOR); + + return snprintf(buf, PAGE_SIZE, "%d.%05dc\n", t / CRUS_T_SCALE_FACTOR, + t % CRUS_T_SCALE_FACTOR); +} + +static DEVICE_ATTR_RO(temperature_left); + +static ssize_t temperature_right_show(struct device *dev, + struct device_attribute *a, char *buf) +{ + struct crus_rx_temperature_t rx_temp; + int buffer[CRUS_MAX_BUFFER_SIZE / 4]; + int z, r, t, temp0; + + crus_get_param(this.ff_port, CRUS_PARAM_RX_GET_TEMP, buffer, + CRUS_MAX_BUFFER_SIZE); + + memcpy(&rx_temp, buffer, sizeof(rx_temp)); + + if ((rx_temp.hp_status_r != 2) || (rx_temp.full_status_r != 2)) + return snprintf(buf, PAGE_SIZE, "Calibration is not done\n"); + + z = rx_temp.z_r; + r = rx_temp.temp_r; + temp0 = rx_temp.amb_temp_r; + + t = (CRUS_MATERIAL_FACTOR * CRUS_T_SCALE_FACTOR * (r - z) / z) + + (temp0 * CRUS_T_SCALE_FACTOR); + + return snprintf(buf, PAGE_SIZE, "%d.%05dc\n", t / CRUS_T_SCALE_FACTOR, + t % CRUS_T_SCALE_FACTOR); +} +static DEVICE_ATTR_RO(temperature_right); +#if 0 +static ssize_t resistance_left_show(struct device *dev, + struct device_attribute *a, char *buf) +{ + struct crus_rx_temperature_t rx_temp; + struct crus_resistance_t res; + int buffer[CRUS_MAX_BUFFER_SIZE / 4]; + int r; + + if (this.resistance_en) { + crus_get_param(this.fb_port, CRUS_PARAM_TX_RESISTANCE, &res, + sizeof(struct crus_resistance_t)); + + if (!res.status_l) + return snprintf(buf, PAGE_SIZE, + "Invalid status for left channel\n"); + + if (res.r_l == 0) + return snprintf(buf, PAGE_SIZE, + "Short circuit detected\n"); + + if (res.r_l >= CRUS_RES_OPEN_CIRCUIT) + return snprintf(buf, PAGE_SIZE, + "Open circuit detected\n"); + + r = res.r_l * CRUS_AMP_FACTOR; + } else { + crus_get_param(this.ff_port, CRUS_PARAM_RX_GET_TEMP, + buffer, CRUS_MAX_BUFFER_SIZE); + + memcpy(&rx_temp, buffer, sizeof(rx_temp)); + + if ((rx_temp.hp_status_l != 2) || (rx_temp.full_status_l != 2)) + return snprintf(buf, PAGE_SIZE, + "Calibration is not done\n"); + + r = rx_temp.temp_l * CRUS_AMP_FACTOR; + } + + return snprintf(buf, PAGE_SIZE, "%d.%08d ohms\n", + r / CRUS_Z_SCALE_FACTOR, r % CRUS_Z_SCALE_FACTOR); +} +static DEVICE_ATTR_RO(resistance_left); + +static ssize_t resistance_right_show(struct device *dev, + struct device_attribute *a, char *buf) +{ + struct crus_rx_temperature_t rx_temp; + struct crus_resistance_t res; + int buffer[CRUS_MAX_BUFFER_SIZE / 4]; + int r; + + if (this.resistance_en) { + crus_get_param(this.fb_port, CRUS_PARAM_TX_RESISTANCE, &res, + sizeof(struct crus_resistance_t)); + + if (!res.status_r) + return snprintf(buf, PAGE_SIZE, + "Invalid status for right channel\n"); + + if (res.r_r == 0) + return snprintf(buf, PAGE_SIZE, + "Short circuit detected\n"); + + if (res.r_r >= CRUS_RES_OPEN_CIRCUIT) + return snprintf(buf, PAGE_SIZE, + "Open circuit detected\n"); + + r = res.r_r * CRUS_AMP_FACTOR; + } else { + crus_get_param(this.ff_port, CRUS_PARAM_RX_GET_TEMP, + buffer, CRUS_MAX_BUFFER_SIZE); + + memcpy(&rx_temp, buffer, sizeof(rx_temp)); + + if ((rx_temp.hp_status_r != 2) || (rx_temp.full_status_r != 2)) + return snprintf(buf, PAGE_SIZE, + "Calibration is not done\n"); + + r = rx_temp.temp_r * CRUS_AMP_FACTOR; + } + + return snprintf(buf, PAGE_SIZE, "%d.%08d ohms\n", + r / CRUS_Z_SCALE_FACTOR, r % CRUS_Z_SCALE_FACTOR); +} +static DEVICE_ATTR_RO(resistance_right); +#endif +static struct attribute *crus_sp_attrs[] = { + &dev_attr_temperature_left.attr, + &dev_attr_temperature_right.attr, +#if 0 + &dev_attr_resistance_left.attr, + &dev_attr_resistance_right.attr, +#endif + NULL, +}; + +static const struct attribute_group crus_sp_group = { + .attrs = crus_sp_attrs, +}; + +static const struct attribute_group *crus_sp_groups[] = { + &crus_sp_group, + NULL, +}; + +#ifdef CONFIG_OF +static int msm_cirrus_playback_probe(struct platform_device *pdev) +{ + int i; + + pr_err("Wing: Initializing platform device\n"); + + this.usecase_dt_count = + of_property_count_strings(pdev->dev.of_node, "usecase-names"); + if (this.usecase_dt_count <= 0) { + pr_debug("Usecase names not found\n"); + this.usecase_dt_count = 0; + return 0; + } + + if ((this.usecase_dt_count > 0) && + (this.usecase_dt_count <= MAX_TUNING_CONFIGS)) + of_property_read_string_array(pdev->dev.of_node, + "usecase-names", + crus_sp_usecase_dt_text, + this.usecase_dt_count); + else if (this.usecase_dt_count > MAX_TUNING_CONFIGS) { + pr_err("Max of %d usecase configs allowed\n", + MAX_TUNING_CONFIGS); + return -EINVAL; + } + + for (i = 0; i < this.usecase_dt_count; i++) + pr_info("Usecase[%d] = %s\n", i, crus_sp_usecase_dt_text[i]); + + this.prot_en = of_property_read_bool(pdev->dev.of_node, "protect-en"); + + return 0; +} + +static const struct of_device_id msm_cirrus_playback_dt_match[] = { + { .compatible = "cirrus,msm-cirrus-playback" }, + {} +}; +MODULE_DEVICE_TABLE(of, msm_cirrus_playback_dt_match); + +static struct platform_driver msm_cirrus_playback_driver = { + .driver = { + .name = "msm-cirrus-playback", + .owner = THIS_MODULE, + .of_match_table = msm_cirrus_playback_dt_match, + }, + .probe = msm_cirrus_playback_probe, +}; +#endif + +static const struct file_operations crus_sp_fops = { + .owner = THIS_MODULE, + .open = crus_ioctl_open, + .release = crus_ioctl_release, + .unlocked_ioctl = crus_sp_ioctl, + .compat_ioctl = crus_compat_ioctl, +}; + +struct miscdevice crus_sp_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_cirrus_playback", + .fops = &crus_sp_fops, +}; + +int __init crus_sp_init(void) +{ + if (this.initialized) + return 0; + pr_info("Initializing misc device\n"); + + misc_register(&crus_sp_misc); + + if (sysfs_create_groups(&crus_sp_misc.this_device->kobj, + crus_sp_groups)) + pr_err("%s: Could not create sysfs groups\n", __func__); + +#ifdef CONFIG_OF + platform_driver_register(&msm_cirrus_playback_driver); +#endif + + this.initialized = true; + pr_info("Initializing misc device end\n"); + return 0; +} + +void __exit crus_sp_exit(void) +{ + if (!this.initialized) + return; + +#ifdef CONFIG_OF + platform_driver_unregister(&msm_cirrus_playback_driver); +#endif + sysfs_remove_groups(&crus_sp_misc.this_device->kobj, crus_sp_groups); + + misc_deregister(&crus_sp_misc); +} + +//MODULE_AUTHOR("Cirrus SP"); +//MODULE_DESCRIPTION("Providing Interface to Cirrus SP"); +//MODULE_LICENSE("GPL"); diff --git a/techpack/audio/dsp/msm-cirrus-playback.c b/techpack/audio/dsp/msm-cirrus-playback.c new file mode 100644 index 000000000000..6855ad1b7b6d --- /dev/null +++ b/techpack/audio/dsp/msm-cirrus-playback.c @@ -0,0 +1,1550 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 and +* only version 2 as published by the Free Software Foundation. +* +* 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. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +/* includes the file structure, that is, file open read close */ +#include + +/* include the character device, makes cdev avilable */ +#include +#include + +/* includes copy_user vice versa */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../asoc/msm-pcm-routing-v2.h" +#include +#include +#include +#include +#include + +#undef CONFIG_OF + +#undef pr_info +#undef pr_err +#undef pr_debug +#define pr_debug(fmt, args...) printk(KERN_INFO "[CSPL] " pr_fmt(fmt), ##args) +#define pr_info(fmt, args...) printk(KERN_INFO "[CSPL] " pr_fmt(fmt), ##args) +#define pr_err(fmt, args...) printk(KERN_ERR "[CSPL] " pr_fmt(fmt), ##args) + +#define CRUS_TX_CONFIG "crus_sp_tx%d.bin" +#define CRUS_RX_CONFIG "crus_sp_rx%d.bin" + +#define CIRRUS_RX_GET_IODATA 0x00A1AF09 +#define CIRRUS_TX_GET_IODATA 0x00A1BF09 + +static struct crus_sp_ioctl_header crus_sp_hdr; + +static struct crus_control_t this_ctrl = { + .fb_port_index = 3, + .fb_port = AFE_PORT_ID_QUATERNARY_MI2S_TX, + .ff_port = AFE_PORT_ID_QUATERNARY_MI2S_RX, + .usecase_dt_count = MAX_TUNING_CONFIGS, + .ch_sw_duration = 30, + .ch_sw = 0, + .vol_atten = 0, + .prot_en = false, + .q6afe_rev = 3, // V3 as default +}; + +static void *crus_gen_afe_get_header(int length, int port, int module, + int param) +{ + struct afe_custom_crus_get_config_v2_t *config = NULL; + int size = sizeof(struct afe_custom_crus_get_config_v2_t); + int index = afe_get_port_index(port); + uint16_t payload_size = sizeof(struct param_hdr_v2) + length; + + /* Allocate memory for the message */ + config = kzalloc(size, GFP_KERNEL); + if (!config) + return NULL; + + /* Set header section */ + config->hdr.hdr_field = APR_HDR_FIELD( + APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config->hdr.pkt_size = size; + config->hdr.src_svc = APR_SVC_AFE; + config->hdr.src_domain = APR_DOMAIN_APPS; + config->hdr.src_port = 0; + config->hdr.dest_svc = APR_SVC_AFE; + config->hdr.dest_domain = APR_DOMAIN_ADSP; + config->hdr.dest_port = 0; + config->hdr.token = index; + config->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; + + /* Set param section */ + config->param.port_id = (uint16_t)port; + + config->param.mem_hdr.data_payload_addr_lsw = 0; + config->param.mem_hdr.data_payload_addr_msw = 0; + config->param.mem_hdr.mem_map_handle = 0; + config->param.module_id = (uint32_t)module; + config->param.param_id = (uint32_t)param; + /* max data size of the param_ID/module_ID combination */ + config->param.payload_size = payload_size; + + /* Set data section */ + config->data.module_id = (uint32_t)module; + config->data.param_id = (uint32_t)param; + + /*remove for 855*/ + //config->data.reserved = 0; /* Must be set to 0 */ + /* actual size of the data for the module_ID/param_ID pair */ + config->data.param_size = length; + + return (void *)config; +} + +static void *crus_gen_afe_set_header(int length, int port, int module, + int param) +{ + struct afe_custom_crus_set_config_v2_t *config = NULL; + int size = sizeof(struct afe_custom_crus_set_config_v2_t) + length; + int index = afe_get_port_index(port); + uint16_t payload_size = sizeof(struct param_hdr_v2) + length; + + /* Allocate memory for the message */ + config = kzalloc(size, GFP_KERNEL); + if (!config) + return NULL; + + /* Set header section */ + config->hdr.hdr_field = APR_HDR_FIELD( + APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config->hdr.pkt_size = size; + config->hdr.src_svc = APR_SVC_AFE; + config->hdr.src_domain = APR_DOMAIN_APPS; + config->hdr.src_port = 0; + config->hdr.dest_svc = APR_SVC_AFE; + config->hdr.dest_domain = APR_DOMAIN_ADSP; + config->hdr.dest_port = 0; + config->hdr.token = index; + config->hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + + /* Set param section */ + config->param.port_id = (uint16_t)port; + config->param.mem_hdr.data_payload_addr_lsw = 0; + config->param.mem_hdr.data_payload_addr_msw = 0; + config->param.mem_hdr.mem_map_handle = 0; + /* max data size of the param_ID/module_ID combination */ + config->param.payload_size = payload_size; + + /* Set data section */ + config->data.module_id = (uint32_t)module; + config->data.param_id = (uint32_t)param; + + /*remove for 855*/ + //config->data.reserved = 0; /* Must be set to 0 */ + + /* actual size of the data for the module_ID/param_ID pair */ + config->data.param_size = length; + + return (void *)config; +} + +static int crus_afe_get_param(int port, int module, int param, int length, + void *data) +{ + struct afe_custom_crus_get_config_v2_t *config = NULL; + int index = afe_get_port_index(port); + int ret = 0, count = 0; + + pr_info("CRUS_SP: (get_param) module = 0x%08x, port = 0x%08x, param = 0x%08x\n", + module, port, param); + + config = (struct afe_custom_crus_get_config_v2_t *) + crus_gen_afe_get_header(length, port, module, param); + if (config == NULL) { + pr_err("CRUS_SP: Memory allocation failed\n"); + return -ENOMEM; + } + + mutex_lock(&this_ctrl.param_lock); + atomic_set(&this_ctrl.callback_wait, 0); + + this_ctrl.user_buffer = + kzalloc(config->param.payload_size + 16, GFP_KERNEL); + + ret = afe_apr_send_pkt_crus(config, index, 0); + if (ret) + pr_err("CRUS_SP: (get_param) failed with code %d\n", ret); + + /* Wait for afe callback to populate data */ + while (!atomic_read(&this_ctrl.callback_wait)) { + usleep_range(800, 1200); + if (count++ >= 1000) { + pr_err("CRUS_SP: AFE callback timeout\n"); + atomic_set(&this_ctrl.callback_wait, 1); + ret = -EINVAL; + goto exit; + } + } + + /* Copy from dynamic buffer to return buffer */ + memcpy((u8 *)data, &this_ctrl.user_buffer[4], length); + +exit: + kfree(this_ctrl.user_buffer); + mutex_unlock(&this_ctrl.param_lock); + kfree(config); + return ret; +} + +static int crus_afe_set_param(int port, int module, int param, int length, + void *data_ptr) +{ + struct afe_custom_crus_set_config_v2_t *config = NULL; + int index = afe_get_port_index(port); + int ret = 0; + + pr_info("CRUS_SP: (set_param) module = 0x%08x, port = 0x%08x, param = 0x%08x\n", + module, port, param); + + config = crus_gen_afe_set_header(length, port, module, param); + if (config == NULL) { + pr_err("CRUS_SP: Memory allocation failed\n"); + return -ENOMEM; + } + + memcpy((u8 *)config + sizeof(struct afe_custom_crus_set_config_v2_t), + (u8 *)data_ptr, length); + + ret = afe_apr_send_pkt_crus(config, index, 1); + if (ret) + pr_err("CRUS_SP: (set_param) failed with code %d\n", ret); + + kfree(config); + return ret; +} + +static int crus_afe_get_param_v3(int port, int module_id, int param_id, + uint32_t length, void *data) +{ + struct afe_port_cmd_get_param_v3 afe_get_param; + struct param_hdr_v3 param_hdr; + u16 port_id = 0; + int index = 0; + int ret = 0; + + pr_info("%s: port=0x%x, module=0x%x, param_id=0x%x, size=%d\n", + __func__, port, module_id, param_id, length); + + param_hdr.module_id = module_id; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = param_id; + param_hdr.param_size = length; + + port_id = q6audio_get_port_id(port); + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Not a valid port id = 0x%x ret %d\n", __func__, + port_id, ret); + return -EINVAL; + } + index = q6audio_get_port_index(port); + + //q6afe_get_params_v3 + memset(&afe_get_param, 0, sizeof(afe_get_param)); + afe_get_param.apr_hdr.hdr_field = APR_HDR_FIELD( + APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + afe_get_param.apr_hdr.pkt_size = sizeof(afe_get_param); + afe_get_param.apr_hdr.src_port = 0; + afe_get_param.apr_hdr.dest_port = 0; + afe_get_param.apr_hdr.token = index; + afe_get_param.apr_hdr.opcode = AFE_PORT_CMD_GET_PARAM_V3; + afe_get_param.port_id = port_id; + //if (mem_hdr != NULL) + // afe_get_param.mem_hdr = *mem_hdr; + /* Set param header in command, no payload in V3 */ + afe_get_param.param_hdr = param_hdr; + //q6afe_get_params_v3 end + + mutex_lock(&this_ctrl.param_lock); + atomic_set(&this_ctrl.callback_wait, 0); + this_ctrl.user_buffer = kzalloc(length + 64, GFP_KERNEL); + atomic_set(cspl_afe.status, 0); + ret = apr_send_pkt(*cspl_afe.apr, (uint32_t *)&afe_get_param); + if (ret < 0) { + pr_err("%s: Setting param for port %d param[0x%x]failed\n", + __func__, port, param_id); + goto fail_cmd; + } + /* Wait for afe callback to populate data */ + while (!atomic_read(&this_ctrl.callback_wait)) + msleep(1); + +#if 0 + for (index = 0; index < length; index ++) + pr_info("[%d]=%d\n", index, this_ctrl.user_buffer[index]); + + pr_info("[5]=%s\n", &this_ctrl.user_buffer[5]); +#endif + /* copy from dynamic buffer to return buffer */ + memcpy((u8 *)data, &this_ctrl.user_buffer[5], length); + pr_info("%s: Copied %d bytes data \n", __func__, length); + + ret = 0; +fail_cmd: + pr_info("%s: param_id %x status %d\n", __func__, param_id, ret); + mutex_unlock(&this_ctrl.param_lock); + kfree(this_ctrl.user_buffer); + return ret; +} + +static int crus_afe_set_param_v3(int port, int module_id, int param_id, + uint32_t length, void *data) +{ + struct afe_port_cmd_set_param_v3 *set_param = NULL; + uint32_t set_param_size = sizeof(struct afe_port_cmd_set_param_v3); + struct param_hdr_v3 param_hdr; + u16 port_id = 0; + int index = 0; + u8 *packed_param_data = NULL; + int packed_data_size = sizeof(union param_hdrs) + length; + int ret = 0; + + pr_info("%s: port=0x%x, module=0x%x, param_id=0x%x, size=%d\n", + __func__, port, module_id, param_id, length); + + port_id = q6audio_get_port_id(port); + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Not a valid port id = 0x%x ret %d\n", __func__, + port_id, ret); + return -EINVAL; + } + index = q6audio_get_port_index(port); + + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = module_id; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = param_id; + param_hdr.param_size = length; + pr_debug("CRUS: param_size %d\n", length); + + packed_param_data = kzalloc(packed_data_size, GFP_KERNEL); + if (packed_param_data == NULL) + return -ENOMEM; + + ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, (u8 *)data, + &packed_data_size); + if (ret) { + pr_err("%s: Failed to pack param header and data, error %d\n", + __func__, ret); + goto fail_cmd; + } + + set_param_size += packed_data_size; + set_param = kzalloc(set_param_size, GFP_KERNEL); + if (set_param == NULL) { + ret = -ENOMEM; + goto fail_cmd; + } + + set_param->apr_hdr.hdr_field = APR_HDR_FIELD( + APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + set_param->apr_hdr.pkt_size = + sizeof(struct afe_port_cmd_set_param_v3) + packed_data_size; + set_param->apr_hdr.src_port = 0; + set_param->apr_hdr.dest_port = 0; + set_param->apr_hdr.token = index; + set_param->apr_hdr.opcode = AFE_PORT_CMD_SET_PARAM_V3; + set_param->port_id = port_id; + set_param->payload_size = packed_data_size; + memcpy(&set_param->param_data, packed_param_data, packed_data_size); + + atomic_set(cspl_afe.state, 1); + //atomic_set(&this_ctrl.callback_wait, 0); + ret = apr_send_pkt(*cspl_afe.apr, (uint32_t *)set_param); + if (ret < 0) { + pr_err("%s: Setting param for port %d param[0x%x]failed\n", + __func__, port, param_id); + goto fail_cmd; + } + + ret = wait_event_timeout(cspl_afe.wait[index], + (atomic_read(cspl_afe.state) == 0), + msecs_to_jiffies(cspl_afe.timeout_ms * 10)); + + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + + if (atomic_read(cspl_afe.status) != 0) { + pr_err("%s: set param cmd failed\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + + ret = 0; +fail_cmd: + pr_info("[CSPL]%s param_id %x status %d\n", __func__, param_id, ret); + kfree(set_param); + kfree(packed_param_data); + return ret; +} + +static int crus_afe_send_config(const char *data, int32_t length, int32_t port, + int32_t module) +{ + struct afe_custom_crus_set_config_v2_t *config = NULL; + struct crus_external_config_t *payload = NULL; + int size = sizeof(struct crus_external_config_t); + int chars_to_send, mem_size, sent = 0, ret = 0; + int index = afe_get_port_index(port); + uint32_t param = 0; + + pr_info("CRUS_SP: (send_config) module = 0x%08x, port = 0x%08x\n", + module, port); + + /* Destination settings for message */ + if (port == this_ctrl.ff_port) + param = CRUS_PARAM_RX_SET_EXT_CONFIG; + else if (port == this_ctrl.fb_port) + param = CRUS_PARAM_TX_SET_EXT_CONFIG; + else { + pr_err("CRUS_SP: Received invalid port parameter %d\n", port); + return -EINVAL; + } + + if (length > APR_CHUNK_SIZE) + mem_size = APR_CHUNK_SIZE; + else + mem_size = length; + + config = crus_gen_afe_set_header(size, port, module, param); + if (config == NULL) { + pr_err("CRUS_SP: Memory allocation failed\n"); + return -ENOMEM; + } + + payload = (struct crus_external_config_t + *)((u8 *)config + + sizeof(struct afe_custom_crus_set_config_v2_t)); + payload->total_size = (uint32_t)length; + payload->reserved = 0; + payload->config = PAYLOAD_FOLLOWS_CONFIG; + /* ^ This tells the algorithm to expect array */ + /* immediately following the header */ + + /* Send config string in chunks of APR_CHUNK_SIZE bytes */ + while (sent < length) { + chars_to_send = length - sent; + if (chars_to_send > APR_CHUNK_SIZE) { + chars_to_send = APR_CHUNK_SIZE; + payload->done = 0; + } else { + payload->done = 1; + } + + /* Configure per message parameter settings */ + memcpy(payload->data, data + sent, chars_to_send); + payload->chunk_size = chars_to_send; + + /* Send the actual message */ + ret = afe_apr_send_pkt_crus(config, index, 1); + + if (ret) { + pr_err("CRUS_SP: (send_config) failure code %d\n", ret); + break; + } + + sent += chars_to_send; + } + + kfree(config); + return ret; +} + +static int crus_afe_send_delta(const char *data, uint32_t length) +{ + struct afe_custom_crus_set_config_t *config = NULL; + struct crus_delta_config_t *payload = NULL; + int size = sizeof(struct crus_delta_config_t); + int port = this_ctrl.ff_port; + int param = CRUS_PARAM_RX_SET_DELTA_CONFIG; + int module = CIRRUS_SP; + int chars_to_send, mem_size, sent = 0, ret = 0; + int index = afe_get_port_index(port); + + pr_info("CRUS_SP: (send_delta) module = 0x%08x, port = 0x%08x\n", + module, port); + + if (length > APR_CHUNK_SIZE) + mem_size = APR_CHUNK_SIZE; + else + mem_size = length; + + config = crus_gen_afe_set_header(size, port, module, param); + if (config == NULL) { + pr_err("CRUS_SP: Memory allocation failed\n"); + return -ENOMEM; + } + + payload = (struct crus_delta_config_t + *)((u8 *)config + + sizeof(struct afe_custom_crus_set_config_t)); + payload->total_size = length; + payload->index = 0; + payload->reserved = 0; + payload->config = PAYLOAD_FOLLOWS_CONFIG; + /* ^ This tells the algorithm to expect array */ + /* immediately following the header */ + + /* Send config string in chunks of APR_CHUNK_SIZE bytes */ + while (sent < length) { + chars_to_send = length - sent; + if (chars_to_send > APR_CHUNK_SIZE) { + chars_to_send = APR_CHUNK_SIZE; + payload->done = 0; + } else + payload->done = 1; + + /* Configure per message parameter settings */ + memcpy(payload->data, data + sent, chars_to_send); + payload->chunk_size = chars_to_send; + + /* Send the actual message */ + ret = afe_apr_send_pkt_crus(config, index, 1); + + if (ret) { + pr_err("CRUS_SP: (send_delta) failure code %d\n", ret); + break; + } + + sent += chars_to_send; + } + + kfree(config); + return ret; +} + +extern int crus_afe_callback(void *payload, int size) +{ + uint32_t *payload32 = payload; + + pr_debug("%s: module=0x%x size = %d\n", __func__, (int)payload32[1], + size); + + switch (payload32[1]) { + case CIRRUS_SP: + memcpy(this_ctrl.user_buffer, payload32, size); + atomic_set(&this_ctrl.callback_wait, 1); + break; + default: + return -EINVAL; + } + + return 0; +} + +int msm_routing_cirrus_fbport_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + this_ctrl.fb_port_index = ucontrol->value.integer.value[0]; + pr_info("%s: %d\n", __func__, this_ctrl.fb_port); + + switch (this_ctrl.fb_port_index) { + case 0: + this_ctrl.fb_port = AFE_PORT_ID_PRIMARY_MI2S_TX; + this_ctrl.ff_port = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case 1: + this_ctrl.fb_port = AFE_PORT_ID_SECONDARY_MI2S_TX; + this_ctrl.ff_port = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case 2: + this_ctrl.fb_port = AFE_PORT_ID_TERTIARY_MI2S_TX; + this_ctrl.ff_port = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case 3: + this_ctrl.fb_port = AFE_PORT_ID_QUATERNARY_MI2S_TX; + this_ctrl.ff_port = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + default: + /* Default port to QUATERNARY */ + this_ctrl.fb_port = AFE_PORT_ID_QUATERNARY_MI2S_TX; + this_ctrl.ff_port = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + } + return 0; +} + +int msm_routing_cirrus_fbport_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: this_ctrl.fb_port = %d", __func__, this_ctrl.fb_port); + ucontrol->value.integer.value[0] = this_ctrl.fb_port_index; + return 0; +} + +static int msm_routing_crus_sp_enable_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + const int crus_set = ucontrol->value.integer.value[0]; + + this_ctrl.enable = crus_set; + + return 0; +} + +static int msm_routing_crus_sp_enable_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_info("%s: %d\n", __func__, this_ctrl.enable); + ucontrol->value.integer.value[0] = this_ctrl.enable; + + return 0; +} +static int +msm_routing_crus_sp_prot_enable_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_err("CRUS_SP: Cirrus SP Protection Enable is set via DT\n"); + return 0; +} + +static int +msm_routing_crus_sp_prot_enable_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = this_ctrl.prot_en ? 1 : 0; + return 0; +} + +static int msm_routing_crus_sp_usecase_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct crus_rx_run_case_ctrl_t case_ctrl; + struct crus_rx_temperature_t rx_temp; + const int crus_set = ucontrol->value.integer.value[0]; + //struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + //uint32_t max_index = e->items; + int buffer[CRUS_MAX_BUFFER_SIZE / 4]; + + if (crus_set >= 4) { + pr_err("CRUS_SP: Config index out of bounds (%d)\n", crus_set); + return -EINVAL; + } + + if (this_ctrl.q6afe_rev == 2) + crus_afe_get_param(this_ctrl.ff_port, CIRRUS_SP, + CRUS_PARAM_RX_GET_TEMP, CRUS_MAX_BUFFER_SIZE, + buffer); + else + crus_afe_get_param_v3(this_ctrl.ff_port, CIRRUS_SP, + CRUS_PARAM_RX_GET_TEMP, + CRUS_MAX_BUFFER_SIZE, buffer); + + memcpy(&rx_temp, buffer, sizeof(rx_temp)); + + this_ctrl.usecase = crus_set; + + case_ctrl.status_l = 1; + case_ctrl.status_r = 1; + case_ctrl.z_l = rx_temp.z_l; + case_ctrl.z_r = rx_temp.z_r; + case_ctrl.checksum_l = rx_temp.z_l + 1; + case_ctrl.checksum_r = rx_temp.z_r + 1; + case_ctrl.atemp = rx_temp.amb_temp_l; + case_ctrl.value = this_ctrl.usecase; + + if (this_ctrl.prot_en) { + if (this_ctrl.q6afe_rev == 2) { + crus_afe_set_param(this_ctrl.fb_port, CIRRUS_SP, + CRUS_PARAM_TX_SET_USECASE, + sizeof(this_ctrl.usecase), + (void *)&this_ctrl.usecase); + } else { + crus_afe_set_param_v3(this_ctrl.fb_port, CIRRUS_SP, + CRUS_PARAM_TX_SET_USECASE, + sizeof(this_ctrl.usecase), + (void *)&this_ctrl.usecase); + } + } + + if (this_ctrl.q6afe_rev == 2) { + crus_afe_set_param(this_ctrl.ff_port, CIRRUS_SP, + CRUS_PARAM_RX_SET_USECASE, sizeof(case_ctrl), + (void *)&case_ctrl); + } else { + crus_afe_set_param_v3(this_ctrl.ff_port, CIRRUS_SP, + CRUS_PARAM_RX_SET_USECASE, + sizeof(case_ctrl), (void *)&case_ctrl); + } + + return 0; +} + +static int msm_routing_crus_sp_usecase_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_info("%s: %d\n", __func__, this_ctrl.usecase); + ucontrol->value.integer.value[0] = this_ctrl.usecase; + + return 0; +} + +static int msm_routing_crus_load_config_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol); + const int crus_set = ucontrol->value.integer.value[0]; + char config[CONFIG_FILE_SIZE]; + const struct firmware *firmware; + + pr_debug("%s: %d\n", __func__, crus_set); + this_ctrl.conf_sel = crus_set; + + switch (crus_set) { + case 0: /* "None" */ + break; + case 1: /* Load RX Config */ + snprintf(config, CONFIG_FILE_SIZE, CRUS_RX_CONFIG, + this_ctrl.usecase); + + if (request_firmware(&firmware, config, plat->dev) != 0) { + pr_err("CRUS_SP: Request firmware failed\n"); + return -EINVAL; + } + + pr_info("CRUS_SP: Sending RX config...\n"); + + crus_afe_send_config(firmware->data, firmware->size, + this_ctrl.ff_port, CIRRUS_SP); + release_firmware(firmware); + break; + case 2: /* Load TX Config */ + if (this_ctrl.prot_en == false) + return -EINVAL; + + snprintf(config, CONFIG_FILE_SIZE, CRUS_TX_CONFIG, + this_ctrl.usecase); + + if (request_firmware(&firmware, config, plat->dev) != 0) { + pr_err("CRUS_SP: Request firmware failed\n"); + return -EINVAL; + } + + pr_info("CRUS_SP: Sending TX config...\n"); + + crus_afe_send_config(firmware->data, firmware->size, + this_ctrl.fb_port, CIRRUS_SP); + release_firmware(firmware); + break; + default: + return -EINVAL; + } + + this_ctrl.conf_sel = 0; + + return 0; +} + +static int msm_routing_crus_load_config_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: %d\n", __func__, this_ctrl.conf_sel); + ucontrol->value.integer.value[0] = this_ctrl.conf_sel; + return 0; +} + +static int +msm_routing_crus_delta_config_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol); + struct crus_single_data_t data; + const int crus_set = ucontrol->value.integer.value[0]; + const struct firmware *firmware; + + switch (crus_set) { + case 0: + break; + case 1: /* Load delta config over AFE */ + this_ctrl.delta_sel = crus_set; + + if (request_firmware(&firmware, "crus_sp_delta_config.bin", + plat->dev) != 0) { + pr_err("CRUS_SP: Request firmware failed\n"); + this_ctrl.delta_sel = 0; + return -EINVAL; + } + + pr_info("CRUS_SP: Sending delta config...\n"); + + crus_afe_send_delta(firmware->data, firmware->size); + release_firmware(firmware); + break; + case 2: /* Run delta transition */ + this_ctrl.delta_sel = crus_set; + data.value = 0; + crus_afe_set_param(this_ctrl.ff_port, CIRRUS_SP, + CRUS_PARAM_RX_RUN_DELTA_CONFIG, + sizeof(struct crus_single_data_t), &data); + break; + default: + return -EINVAL; + } + + this_ctrl.delta_sel = 0; + return 0; +} + +static int +msm_routing_crus_delta_config_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = this_ctrl.delta_sel; + return 0; +} + +static int msm_routing_crus_vol_attn_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + const int crus_set = ucontrol->value.integer.value[0]; + struct crus_dual_data_t data; + + mutex_lock(&this_ctrl.sp_lock); + + this_ctrl.vol_atten = crus_set; + + switch (crus_set) { + case 0: /* 0dB */ + data.data1 = VOL_ATTN_MAX; + data.data2 = VOL_ATTN_MAX; + break; + case 1: /* -18dB */ + data.data1 = VOL_ATTN_18DB; + data.data2 = VOL_ATTN_18DB; + break; + case 2: /* -24dB */ + data.data1 = VOL_ATTN_24DB; + data.data2 = VOL_ATTN_24DB; + break; + default: + return -EINVAL; + } + + if (this_ctrl.q6afe_rev == 2) { + crus_afe_set_param(this_ctrl.ff_port, CIRRUS_SP, + CRUS_PARAM_RX_SET_ATTENUATION, + sizeof(struct crus_dual_data_t), &data); + } else { + crus_afe_set_param_v3(this_ctrl.ff_port, CIRRUS_SP, + CRUS_PARAM_RX_SET_ATTENUATION, + sizeof(struct crus_dual_data_t), &data); + } + + mutex_unlock(&this_ctrl.sp_lock); + + return 0; +} + +static int msm_routing_crus_vol_attn_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("Starting Cirrus SP Volume Attenuation Get function call\n"); + ucontrol->value.integer.value[0] = this_ctrl.vol_atten; + + return 0; +} + +static int msm_routing_crus_chan_swap_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct crus_dual_data_t data; + const int crus_set = ucontrol->value.integer.value[0]; + + switch (crus_set) { + case 0: /* L/R */ + data.data1 = 1; + break; + case 1: /* R/L */ + data.data1 = 2; + break; + default: + return -EINVAL; + } + + data.data2 = this_ctrl.ch_sw_duration; + + mutex_lock(&this_ctrl.sp_lock); + + this_ctrl.ch_sw = crus_set; + + if (this_ctrl.q6afe_rev == 2) + crus_afe_set_param(this_ctrl.ff_port, CIRRUS_SP, + CRUS_PARAM_RX_CHANNEL_SWAP, + sizeof(struct crus_dual_data_t), &data); + else + crus_afe_set_param_v3(this_ctrl.ff_port, CIRRUS_SP, + CRUS_PARAM_RX_CHANNEL_SWAP, + sizeof(struct crus_dual_data_t), &data); + + mutex_unlock(&this_ctrl.sp_lock); + + return 0; +} + +static int msm_routing_crus_chan_swap_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct crus_single_data_t data; + pr_debug("%s: %d\n", __func__, this_ctrl.ch_sw); + crus_afe_get_param(this_ctrl.ff_port, CIRRUS_SP, + CRUS_PARAM_RX_GET_CHANNEL_SWAP, + sizeof(struct crus_single_data_t), &data); + + ucontrol->value.integer.value[0] = this_ctrl.ch_sw; + + return 0; +} + +static int +msm_routing_crus_chan_swap_dur_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int crus_set = ucontrol->value.integer.value[0]; + + pr_debug("%s: %d\n", __func__, crus_set); + + if ((crus_set < 0) || (crus_set > MAX_CHAN_SWAP_SAMPLES)) { + pr_err("CRUS_SP: Value out of range (%d)\n", crus_set); + return -EINVAL; + } + + if (crus_set < MIN_CHAN_SWAP_SAMPLES) { + pr_info("CRUS_SP: Received %d, round up to min value %d\n", + crus_set, MIN_CHAN_SWAP_SAMPLES); + crus_set = MIN_CHAN_SWAP_SAMPLES; + } + + this_ctrl.ch_sw_duration = crus_set; + + return 0; +} + +static int +msm_routing_crus_chan_swap_dur_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: %d\n", __func__, this_ctrl.ch_sw_duration); + + ucontrol->value.integer.value[0] = this_ctrl.ch_sw_duration; + + return 0; +} +static int msm_routing_crus_fail_det(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static int msm_routing_crus_fail_det_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static const char *const cirrus_fb_port_text[] = { + "PRI_MI2S_RX", "SEC_MI2S_RX", "TERT_MI2S_RX", + "QUAT_MI2S_RX", "QUAT_TDM_RX_0", "SLIMBUS_0_RX" +}; + +static const char *const crus_en_text[] = { "Config SP Disable", + "Config SP Enable" }; + +static const char *const crus_prot_en_text[] = { "Disable", "Enable" }; + +static const char *const crus_conf_load_text[] = { "Idle", "Load RX", + "Load TX" }; + +static const char *const crus_conf_load_no_prot_text[] = { "Idle", "Load" }; + +static const char *const crus_delta_text[] = { "Idle", "Load", "Run" }; + +static const char *const crus_chan_swap_text[] = { "LR", "RL" }; +static const char *crus_sp_usecase_dt_text[MAX_TUNING_CONFIGS] = { + "Music", "Voice", "Headset", "Handsfree" +}; + +static const char *const crus_vol_attn_text[] = { "0dB", "-18dB", "-24dB" }; + +static const struct soc_enum cirrus_fb_controls_enum[] = { + SOC_ENUM_SINGLE_EXT(6, cirrus_fb_port_text), +}; + +static const struct soc_enum crus_en_enum[] = { + SOC_ENUM_SINGLE_EXT(2, crus_en_text), +}; + +static const struct soc_enum crus_prot_en_enum[] = { + SOC_ENUM_SINGLE_EXT(2, crus_prot_en_text), +}; + +static struct soc_enum crus_sp_usecase_enum[] = { + SOC_ENUM_SINGLE_EXT(MAX_TUNING_CONFIGS, crus_sp_usecase_dt_text), +}; + +static const struct soc_enum crus_conf_load_enum[] = { + SOC_ENUM_SINGLE_EXT(3, crus_conf_load_text), +}; + +static const struct soc_enum crus_conf_load_no_prot_enum[] = { + SOC_ENUM_SINGLE_EXT(2, crus_conf_load_no_prot_text), +}; + +static const struct soc_enum crus_delta_enum[] = { + SOC_ENUM_SINGLE_EXT(3, crus_delta_text), +}; + +static const struct soc_enum crus_chan_swap_enum[] = { + SOC_ENUM_SINGLE_EXT(2, crus_chan_swap_text), +}; + +static const struct soc_enum crus_vol_attn_enum[] = { + SOC_ENUM_SINGLE_EXT(3, crus_vol_attn_text), +}; +static const struct snd_kcontrol_new crus_protect_controls[] = { + SOC_ENUM_EXT("Cirrus SP FBPort", cirrus_fb_controls_enum[0], + msm_routing_cirrus_fbport_get, + msm_routing_cirrus_fbport_put), + SOC_ENUM_EXT("Cirrus SP", crus_en_enum[0], + msm_routing_crus_sp_enable_get, + msm_routing_crus_sp_enable_put), + SOC_ENUM_EXT("Cirrus SP Protection", crus_prot_en_enum[0], + msm_routing_crus_sp_prot_enable_get, + msm_routing_crus_sp_prot_enable_put), + SOC_ENUM_EXT("Cirrus SP Usecase", crus_sp_usecase_enum[0], + msm_routing_crus_sp_usecase_get, + msm_routing_crus_sp_usecase_put), + SOC_ENUM_EXT("Cirrus SP Load Config", crus_conf_load_enum[0], + msm_routing_crus_load_config_get, + msm_routing_crus_load_config_put), + SOC_ENUM_EXT("Cirrus SP Delta Config", crus_delta_enum[0], + msm_routing_crus_delta_config_get, + msm_routing_crus_delta_config_put), + SOC_ENUM_EXT("Cirrus SP Channel Swap", crus_chan_swap_enum[0], + msm_routing_crus_chan_swap_get, + msm_routing_crus_chan_swap_put), + SOC_SINGLE_EXT("Cirrus SP Channel Swap Duration", SND_SOC_NOPM, 0, + MAX_CHAN_SWAP_SAMPLES, 0, + msm_routing_crus_chan_swap_dur_get, + msm_routing_crus_chan_swap_dur_put), + SOC_SINGLE_BOOL_EXT("Cirrus SP Failure Detection", 0, + msm_routing_crus_fail_det_get, + msm_routing_crus_fail_det), +}; +static const struct snd_kcontrol_new crus_no_protect_controls[] = { + SOC_ENUM_EXT("Cirrus SP FBPort", cirrus_fb_controls_enum[0], + msm_routing_cirrus_fbport_get, + msm_routing_cirrus_fbport_put), + SOC_ENUM_EXT("Cirrus SP", crus_en_enum[0], + msm_routing_crus_sp_enable_get, + msm_routing_crus_sp_enable_put), + SOC_ENUM_EXT("Cirrus SP Protection", crus_prot_en_enum[0], + msm_routing_crus_sp_prot_enable_get, + msm_routing_crus_sp_prot_enable_put), + SOC_ENUM_EXT("Cirrus SP Usecase", crus_sp_usecase_enum[0], + msm_routing_crus_sp_usecase_get, + msm_routing_crus_sp_usecase_put), + SOC_ENUM_EXT("Cirrus SP Load Config", crus_conf_load_no_prot_enum[0], + msm_routing_crus_load_config_get, + msm_routing_crus_load_config_put), + SOC_ENUM_EXT("Cirrus SP Delta Config", crus_delta_enum[0], + msm_routing_crus_delta_config_get, + msm_routing_crus_delta_config_put), + SOC_ENUM_EXT("Cirrus SP Channel Swap", crus_chan_swap_enum[0], + msm_routing_crus_chan_swap_get, + msm_routing_crus_chan_swap_put), + SOC_SINGLE_EXT("Cirrus SP Channel Swap Duration", SND_SOC_NOPM, 0, + MAX_CHAN_SWAP_SAMPLES, 0, + msm_routing_crus_chan_swap_dur_get, + msm_routing_crus_chan_swap_dur_put), + SOC_ENUM_EXT("Cirrus SP Volume Attenuation", crus_vol_attn_enum[0], + msm_routing_crus_vol_attn_get, + msm_routing_crus_vol_attn_put), +}; + +void msm_crus_pb_add_controls(struct snd_soc_platform *platform) +{ + if (this_ctrl.usecase_dt_count == 0) + pr_info("CRUS_SP: Usecase config not specified\n"); + + crus_sp_usecase_enum[0].items = this_ctrl.usecase_dt_count; + crus_sp_usecase_enum[0].texts = crus_sp_usecase_dt_text; + + if (this_ctrl.prot_en) + snd_soc_add_platform_controls( + platform, crus_protect_controls, + ARRAY_SIZE(crus_protect_controls)); + else + snd_soc_add_platform_controls( + platform, crus_no_protect_controls, + ARRAY_SIZE(crus_no_protect_controls)); +} + +EXPORT_SYMBOL(msm_crus_pb_add_controls); +int crus_afe_port_start(u16 port_id) +{ + pr_info("%s: 0x%x\n", __func__, port_id); + +//CSPL do not be involved in AFE +#if 0 + struct snd_kcontrol kcontrol; + struct snd_ctl_elem_value ucontrol; + + if (port_id != this_ctrl.ff_port) + return 0; + + this_ctrl.afe_start = true; + pr_info("%s: 0x%x\n", __func__, port_id); + + mutex_lock(&this_ctrl.sp_lock); + msm_routing_crus_sp_usecase_get(&kcontrol, + &ucontrol); + msm_routing_crus_sp_usecase_put(&kcontrol, + &ucontrol); + mutex_unlock(&this_ctrl.sp_lock); +#endif + return 0; +} +EXPORT_SYMBOL(crus_afe_port_start); +int crus_afe_port_close(u16 port_id) +{ + pr_info("%s: 0x%x\n", __func__, port_id); + +//CSPL do not be involved in AFE +#if 0 + if (port_id != this_ctrl.ff_port) + return 0; + + this_ctrl.afe_start = false; + pr_info("%s: 0x%x\n", __func__, port_id); +#endif + return 0; +} +EXPORT_SYMBOL(crus_afe_port_close); +static long crus_sp_shared_ioctl(struct file *f, unsigned int cmd, + void __user *arg) +{ + int result = 0, port; + uint32_t bufsize = 0, size; + void *io_data = NULL; + + pr_info("%s\n", __func__); + + if (copy_from_user(&size, arg, sizeof(size))) { + pr_err("CRUS_SP: copy_from_user (size) failed\n"); + result = -EFAULT; + goto exit; + } + + /* Copy IOCTL header from usermode */ + if (copy_from_user(&crus_sp_hdr, arg, size)) { + pr_err("CRUS_SP: copy_from_user (struct) failed\n"); + result = -EFAULT; + goto exit; + } + + bufsize = crus_sp_hdr.data_length; + io_data = kzalloc(bufsize, GFP_KERNEL); + + switch (cmd) { + case CRUS_SP_IOCTL_GET: + switch (crus_sp_hdr.module_id) { + case CRUS_MODULE_ID_TX: + port = this_ctrl.fb_port; + break; + case CRUS_MODULE_ID_RX: + port = this_ctrl.ff_port; + break; + default: + pr_info("CRUS_SP: Unrecognized port ID (%d)\n", + crus_sp_hdr.module_id); + port = this_ctrl.ff_port; + } + if (this_ctrl.q6afe_rev == 2) + crus_afe_get_param(port, CIRRUS_SP, + crus_sp_hdr.param_id, bufsize, + io_data); + else + crus_afe_get_param_v3(port, CIRRUS_SP, + crus_sp_hdr.param_id, bufsize, + io_data); + result = copy_to_user(crus_sp_hdr.data, io_data, bufsize); + if (result) { + pr_err("CRUS_SP: copy_to_user failed (%d)\n", result); + result = -EFAULT; + } else + result = bufsize; + break; + case CRUS_SP_IOCTL_SET: + result = copy_from_user(io_data, (void *)crus_sp_hdr.data, + bufsize); + if (result) { + pr_err("CRUS_SP: copy_from_user failed (%d)\n", result); + result = -EFAULT; + goto exit_io; + } + + switch (crus_sp_hdr.module_id) { + case CRUS_MODULE_ID_TX: + port = this_ctrl.fb_port; + break; + case CRUS_MODULE_ID_RX: + port = this_ctrl.ff_port; + break; + default: + pr_info("%s: Unrecognized port ID (%d)\n", __func__, + crus_sp_hdr.module_id); + port = this_ctrl.ff_port; + } + + if (this_ctrl.q6afe_rev == 2) { + crus_afe_set_param(port, CIRRUS_SP, + crus_sp_hdr.param_id, bufsize, + io_data); + } else { + crus_afe_set_param_v3(port, CIRRUS_SP, + crus_sp_hdr.param_id, bufsize, + io_data); + } + break; + + default: + pr_err("CRUS_SP: Invalid IOCTL, command = %d\n", cmd); + result = -EINVAL; + break; + } + +exit_io: + kfree(io_data); +exit: + return result; +} + +static long crus_sp_ioctl(struct file *f, unsigned int cmd, unsigned long arg) +{ + pr_info("%s\n", __func__); + + return crus_sp_shared_ioctl(f, cmd, (void __user *)arg); +} + +static long crus_sp_compat_ioctl(struct file *f, unsigned int cmd, + unsigned long arg) +{ + unsigned int cmd64; + + pr_info("%s\n", __func__); + + switch (cmd) { + case CRUS_SP_IOCTL_GET32: + cmd64 = CRUS_SP_IOCTL_GET; + break; + case CRUS_SP_IOCTL_SET32: + cmd64 = CRUS_SP_IOCTL_SET; + break; + default: + pr_err("CRUS_SP: Invalid IOCTL, command = %d\n", cmd); + return -EINVAL; + } + + return crus_sp_shared_ioctl(f, cmd64, compat_ptr(arg)); +} + +static int crus_sp_open(struct inode *inode, struct file *f) +{ + pr_debug("%s\n", __func__); + + atomic_inc(&this_ctrl.count_wait); + return 0; +} + +static int crus_sp_release(struct inode *inode, struct file *f) +{ + atomic_dec(&this_ctrl.count_wait); + return 0; +} + +static ssize_t temperature_left_show(struct device *dev, + struct device_attribute *a, char *buf) +{ + struct crus_rx_temperature_t rx_temp; + static const int material = 250; + static const int scale_factor = 100000; + int buffer[CRUS_MAX_BUFFER_SIZE / 4]; + int out_cal0; + int out_cal1; + int z, r, t; + int temp0; + + crus_afe_get_param(this_ctrl.ff_port, CIRRUS_SP, CRUS_PARAM_RX_GET_TEMP, + CRUS_MAX_BUFFER_SIZE, buffer); + + memcpy(&rx_temp, buffer, sizeof(rx_temp)); + + out_cal0 = rx_temp.hp_status_l; + out_cal1 = rx_temp.full_status_l; + + z = rx_temp.z_l; + + temp0 = rx_temp.amb_temp_l; + + if ((out_cal0 != 2) || (out_cal1 != 2)) + return snprintf(buf, PAGE_SIZE, "Calibration is not done\n"); + + r = rx_temp.temp_l; + t = (material * scale_factor * (r - z) / z) + (temp0 * scale_factor); + + return snprintf(buf, PAGE_SIZE, "%d.%05dc\n", t / scale_factor, + t % scale_factor); +} +static DEVICE_ATTR_RO(temperature_left); + +static ssize_t temperature_right_show(struct device *dev, + struct device_attribute *a, char *buf) +{ + struct crus_rx_temperature_t rx_temp; + static const int material = 250; + static const int scale_factor = 100000; + int buffer[CRUS_MAX_BUFFER_SIZE / 4]; + int out_cal0; + int out_cal1; + int z, r, t; + int temp0; + + crus_afe_get_param(this_ctrl.ff_port, CIRRUS_SP, CRUS_PARAM_RX_GET_TEMP, + CRUS_MAX_BUFFER_SIZE, buffer); + + memcpy(&rx_temp, buffer, sizeof(rx_temp)); + + out_cal0 = rx_temp.hp_status_r; + out_cal1 = rx_temp.full_status_r; + + z = rx_temp.z_r; + + temp0 = rx_temp.amb_temp_r; + + if ((out_cal0 != 2) || (out_cal1 != 2)) + return snprintf(buf, PAGE_SIZE, "Calibration is not done\n"); + + r = rx_temp.temp_r; + t = (material * scale_factor * (r - z) / z) + (temp0 * scale_factor); + + return snprintf(buf, PAGE_SIZE, "%d.%05dc\n", t / scale_factor, + t % scale_factor); +} +static DEVICE_ATTR_RO(temperature_right); + +static ssize_t resistance_left_show(struct device *dev, + struct device_attribute *a, char *buf) +{ + struct crus_rx_temperature_t rx_temp; + static const int scale_factor = 100000000; + static const int amp_factor = 71498; + int buffer[CRUS_MAX_BUFFER_SIZE / 4]; + int out_cal0; + int out_cal1; + int r; + + crus_afe_get_param(this_ctrl.ff_port, CIRRUS_SP, CRUS_PARAM_RX_GET_TEMP, + CRUS_MAX_BUFFER_SIZE, buffer); + + memcpy(&rx_temp, buffer, sizeof(rx_temp)); + + out_cal0 = rx_temp.hp_status_l; + out_cal1 = rx_temp.full_status_l; + + if ((out_cal0 != 2) || (out_cal1 != 2)) + return snprintf(buf, PAGE_SIZE, "Calibration is not done\n"); + + r = rx_temp.temp_l * amp_factor; + + return snprintf(buf, PAGE_SIZE, "%d.%08d ohms\n", r / scale_factor, + r % scale_factor); +} +static DEVICE_ATTR_RO(resistance_left); + +static ssize_t resistance_right_show(struct device *dev, + struct device_attribute *a, char *buf) +{ + struct crus_rx_temperature_t rx_temp; + static const int scale_factor = 100000000; + static const int amp_factor = 71498; + int buffer[CRUS_MAX_BUFFER_SIZE / 4]; + int out_cal0; + int out_cal1; + int r; + + crus_afe_get_param(this_ctrl.ff_port, CIRRUS_SP, CRUS_PARAM_RX_GET_TEMP, + CRUS_MAX_BUFFER_SIZE, buffer); + + memcpy(&rx_temp, buffer, sizeof(rx_temp)); + + out_cal0 = rx_temp.hp_status_r; + out_cal1 = rx_temp.full_status_r; + + if ((out_cal0 != 2) || (out_cal1 != 2)) + return snprintf(buf, PAGE_SIZE, "Calibration is not done\n"); + + r = rx_temp.temp_r * amp_factor; + + return snprintf(buf, PAGE_SIZE, "%d.%08d ohms\n", r / scale_factor, + r % scale_factor); +} +static DEVICE_ATTR_RO(resistance_right); + +static struct attribute *crus_sp_attrs[] = { + &dev_attr_temperature_left.attr, + &dev_attr_temperature_right.attr, + &dev_attr_resistance_left.attr, + &dev_attr_resistance_right.attr, + NULL, +}; + +static const struct attribute_group crus_sp_group = { + .attrs = crus_sp_attrs, +}; + +static const struct attribute_group *crus_sp_groups[] = { + &crus_sp_group, + NULL, +}; + +#ifdef CONFIG_OF +static int msm_cirrus_playback_probe(struct platform_device *pdev) +{ + int i; + + pr_info("CRUS_SP: Initializing platform device\n"); + + this_ctrl.usecase_dt_count = + of_property_count_strings(pdev->dev.of_node, "usecase-names"); + if (this_ctrl.usecase_dt_count <= 0) { + pr_debug("CRUS_SP: Usecase names not found\n"); + this_ctrl.usecase_dt_count = 0; + return 0; + } + + if ((this_ctrl.usecase_dt_count > 0) && + (this_ctrl.usecase_dt_count <= MAX_TUNING_CONFIGS)) + of_property_read_string_array(pdev->dev.of_node, + "usecase-names", + crus_sp_usecase_dt_text, + this_ctrl.usecase_dt_count); + else if (this_ctrl.usecase_dt_count > MAX_TUNING_CONFIGS) { + pr_err("CRUS_SP: Max of %d usecase configs allowed\n", + MAX_TUNING_CONFIGS); + return -EINVAL; + } + + for (i = 0; i < this_ctrl.usecase_dt_count; i++) + pr_info("CRUS_SP: Usecase[%d] = %s\n", i, + crus_sp_usecase_dt_text[i]); + + this_ctrl.prot_en = + of_property_read_bool(pdev->dev.of_node, "protect-en"); + + return 0; +} + +static const struct of_device_id msm_cirrus_playback_dt_match[] = { + { .compatible = "cirrus,msm-cirrus-playback" }, + {} +}; +MODULE_DEVICE_TABLE(of, msm_cirrus_playback_dt_match); + +static struct platform_driver msm_cirrus_playback_driver = { + .driver = { + .name = "msm-cirrus-playback", + .owner = THIS_MODULE, + .of_match_table = msm_cirrus_playback_dt_match, + }, + .probe = msm_cirrus_playback_probe, +}; +#endif + +static const struct file_operations crus_sp_fops = { + .owner = THIS_MODULE, + .open = crus_sp_open, + .release = crus_sp_release, + .unlocked_ioctl = crus_sp_ioctl, + .compat_ioctl = crus_sp_compat_ioctl, +}; + +struct miscdevice crus_sp_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_cirrus_playback", + .fops = &crus_sp_fops, +}; + +int __init crus_sp_init(void) +{ + pr_info("Initializing misc device\n"); + atomic_set(&this_ctrl.callback_wait, 0); + atomic_set(&this_ctrl.count_wait, 0); + mutex_init(&this_ctrl.param_lock); + mutex_init(&this_ctrl.sp_lock); + + misc_register(&crus_sp_misc); + + if (sysfs_create_groups(&crus_sp_misc.this_device->kobj, + crus_sp_groups)) + pr_err("%s: Could not create sysfs groups\n", __func__); + +#ifdef CONFIG_OF + platform_driver_register(&msm_cirrus_playback_driver); +#endif + return 0; +} + +void __exit crus_sp_exit(void) +{ + pr_debug("%s\n", __func__); + mutex_destroy(&this_ctrl.param_lock); + +#ifdef CONFIG_OF + platform_driver_unregister(&msm_cirrus_playback_driver); +#endif +} + +MODULE_AUTHOR("Cirrus SP"); +MODULE_DESCRIPTION("Providing Interface to Cirrus SP"); +MODULE_LICENSE("GPL"); diff --git a/techpack/audio/include/dsp/apr_elliptic.h b/techpack/audio/include/dsp/apr_elliptic.h new file mode 100644 index 000000000000..624fc6c8fde1 --- /dev/null +++ b/techpack/audio/include/dsp/apr_elliptic.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include +#include + +#define ELLIPTIC_SET_PARAMS_SIZE 114 +#define ELLIPTIC_ULTRASOUND_MODULE_TX 0x0F010201 +#define ELLIPTIC_ULTRASOUND_MODULE_RX 0x0FF10202 +#define ULTRASOUND_OPCODE 0x0FF10204 + +/* This need to be updated for all platforms */ +#define ELLIPTIC_PORT_ID SLIMBUS_2_TX + +/** Sequence of Elliptic Labs Ultrasound module parameters */ +struct afe_ultrasound_set_params_t { + uint32_t payload[ELLIPTIC_SET_PARAMS_SIZE]; +} __packed; + +/** Sequence of Elliptic Labs Ultrasound module parameters */ + +/** Elliptic APR public */ + +int32_t ultrasound_apr_set_parameter(int32_t port_id, uint32_t param_id, + u8 *user_params, int32_t length); + +int32_t elliptic_process_apr_payload(uint32_t *payload); + +int elliptic_notify_gain_change_msg(int component_id, int gaindb); + +typedef struct afe_ultrasound_state { + atomic_t us_apr_state; + void **ptr_apr; + atomic_t *ptr_status; + atomic_t *ptr_state; + wait_queue_head_t *ptr_wait; + int timeout_ms; +} afe_ultrasound_state_t; + +extern afe_ultrasound_state_t elus_afe; diff --git a/techpack/audio/include/dsp/apr_mius.h b/techpack/audio/include/dsp/apr_mius.h new file mode 100644 index 000000000000..cd7c07196739 --- /dev/null +++ b/techpack/audio/include/dsp/apr_mius.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include +#include + +#define MIUS_SET_PARAMS_SIZE 114 +#define MIUS_ULTRASOUND_MODULE_TX 0x0F010201 +#define MIUS_ULTRASOUND_MODULE_RX 0x0FF10202 +#define MI_ULTRASOUND_OPCODE 0x0FF10208 + +/* This need to be updated for all platforms */ +#define MIUS_PORT_ID SLIMBUS_2_TX + +/** Sequence of MI Ultrasound module parameters */ +struct afe_mi_ultrasound_set_params_t { + uint32_t payload[MIUS_SET_PARAMS_SIZE]; +} __packed; + +/** Sequence of MI Ultrasound module parameters */ + +/** Elliptic APR public */ + +int32_t mi_ultrasound_apr_set_parameter(int32_t port_id, uint32_t param_id, + u8 *user_params, int32_t length); + +int32_t mius_process_apr_payload(uint32_t *payload); + +int mius_notify_gain_change_msg(int component_id, int gaindb); + +typedef struct afe_mi_ultrasound_state { + atomic_t us_apr_state; + void **ptr_apr; + atomic_t *ptr_status; + atomic_t *ptr_state; + wait_queue_head_t *ptr_wait; + int timeout_ms; +} afe_mi_ultrasound_state_t; + +extern afe_mi_ultrasound_state_t mius_afe; diff --git a/techpack/audio/include/dsp/msm-cirrus-playback-v2.h b/techpack/audio/include/dsp/msm-cirrus-playback-v2.h new file mode 100644 index 000000000000..045b2d7572c9 --- /dev/null +++ b/techpack/audio/include/dsp/msm-cirrus-playback-v2.h @@ -0,0 +1,177 @@ +/* Copyright (c) 2015 Cirrus Logic, Inc. + * Copyright (C) 2021 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 MSM_CIRRUS_PLAYBACK_H +#define MSM_CIRRUS_PLAYBACK_H +#include +#include +#include +#include +#include + +#define VOL_ATTN_MAX 0x7FFFFFFF +#define VOL_ATTN_18DB 257698038 +#define VOL_ATTN_24DB 128849019 +#define CONFIG_FILE_SIZE 128 +#define PAYLOAD_FOLLOWS_CONFIG 4 +#define MAX_TUNING_CONFIGS 4 +#define MIN_CHAN_SWAP_SAMPLES 48 +#define MAX_CHAN_SWAP_SAMPLES 9600 +#define CRUS_MAX_BUFFER_SIZE 384 +#define CRUS_RES_OPEN_CIRCUIT 65535 +#define CRUS_BUF_SIZE 256 +#define INVALID_COPPID (-1) + +/* Payload struct for getting or setting one integer value from/to the DSP + * module + */ +struct crus_single_data_t { + int32_t value; +}; + +/* Payload struct for getting or setting two integer values from/to the DSP + * module + */ +struct crus_dual_data_t { + int32_t data1; + int32_t data2; +}; + +/* Payload struct for getting or setting three integer values from/to the DSP + * module + */ +struct crus_triple_data_t { + int32_t data1; + int32_t data2; + int32_t data3; +}; + +/* Payload struct for setting the RX and TX use cases */ +struct crus_rx_run_case_ctrl_t { + int32_t value; + int32_t status_l; + int32_t checksum_l; + int32_t z_l; + int32_t status_r; + int32_t checksum_r; + int32_t z_r; + int32_t atemp; +}; + +#define APR_CHUNK_SIZE 256 +#define TUNING_MAX_SIZE 2048 + +/* Payload struct for sending an external configuration string to the DSP + * module + */ +struct crus_external_config_t { + uint32_t total_size; + uint32_t chunk_size; + int32_t done; + int32_t reserved; + int32_t config; + char data[APR_CHUNK_SIZE]; +}; +/* Payload struct for sending an external tuning transition string to the DSP + * module + */ +struct crus_delta_config_t { + uint32_t total_size; + uint32_t chunk_size; + int32_t done; + int32_t index; + int32_t reserved; + int32_t config; + char data[APR_CHUNK_SIZE]; +}; + +struct crus_rx_temperature_t { + uint32_t cal_status_l; + uint32_t temp_r; + uint32_t z_r; + uint32_t temp_l; + uint32_t z_l; + uint32_t cal_status_r; + uint32_t amb_temp_l; + uint32_t excur_model_r; + uint32_t excur_model_l; + uint32_t cksum_r; + uint32_t amb_temp_r; + uint32_t cksum_l; + uint32_t hp_status_l; + uint32_t full_status_l; + uint32_t hp_status_r; + uint32_t full_status_r; +}; + +struct crus_resistance_t { + uint32_t status_l; + uint32_t status_r; + uint32_t r_l; + uint32_t r_r; +}; + +struct cache_block { + struct snd_kcontrol kcontrol; + struct snd_ctl_elem_value ucontrol; + snd_kcontrol_put_t *put; + void (*destroy)(void *block); + struct list_head entry; +}; + +typedef struct cache_block cache_block_t; + +struct crus_control_t { + struct device *device; + int32_t module_id; + int32_t fb_port; + int32_t ff_port; + bool qdsp_start; + int32_t sp_enable; + bool cache_execute; + bool prot_en; + int32_t copp_idx; + int instance_id; + int copp_ids[3]; + atomic_t qdsp_start_count[3]; + int32_t vol_atten; + int32_t usecase; + int32_t location; + int32_t swap_duration; + int32_t swap; + int32_t usecase_dt_count; + bool resistance_en; + bool fail_det; + atomic_t ioctl_count; + int32_t conf_index; + int32_t delta_index; + int32_t apr_payload[APR_CHUNK_SIZE]; + int32_t tuning[TUNING_MAX_SIZE]; + bool initialized; +}; + +int crus_afe_get_params(u16 port_id, uint32_t module_id, uint32_t param_id, + void *data, int size); +int crus_afe_set_params(u16 port_id, uint32_t module_id, uint32_t param_id, + void *data, int size); +int crus_adm_set_params(int port_id, int copp_idx, int instance_id, + uint32_t module_id, uint32_t param_id, char *params, + uint32_t length); +int crus_adm_get_params(int port_id, int copp_idx, int instance_id, + uint32_t module_id, uint32_t param_id, char *params, + uint32_t length, uint32_t client_id); +int crus_qdsp_port_start(u16 port_id, int copp_id); +int crus_qdsp_port_close(u16 port_id, int copp_id); +int crus_afe_callback(uint32_t opcode, void *payload, int size); + +void msm_crus_pb_add_controls(struct snd_soc_component *component); +#endif /* _MSM_CIRRUS_PLAYBACK_H */ diff --git a/techpack/audio/include/dsp/msm-cirrus-playback.h b/techpack/audio/include/dsp/msm-cirrus-playback.h new file mode 100644 index 000000000000..7f2f3f175e2c --- /dev/null +++ b/techpack/audio/include/dsp/msm-cirrus-playback.h @@ -0,0 +1,183 @@ +/* Copyright (c) 2015 Cirrus Logic, Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 MSM_CIRRUS_PLAYBACK_H +#define MSM_CIRRUS_PLAYBACK_H +#define DEBUG +#include +#include +#include +#include +#include +#include + +#define MIN_CHAN_SWAP_SAMPLES 48 +#define MAX_CHAN_SWAP_SAMPLES 9600 +#define VOL_ATTN_MAX 0x7FFFFFFF +#define VOL_ATTN_18DB 257698038 +#define VOL_ATTN_24DB 128849019 + +struct afe_cspl_state { + void **apr; + atomic_t *status; + atomic_t *state; + wait_queue_head_t *wait; + int timeout_ms; +}; + +extern struct afe_cspl_state cspl_afe; + +struct afe_custom_crus_set_config_v2_t { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct param_hdr_v2 data; +} __packed; + +struct afe_custom_crus_get_config_v2_t { + struct apr_hdr hdr; + struct afe_port_cmd_get_param_v2 param; + struct param_hdr_v2 data; +} __packed; + +struct afe_custom_crus_set_config_t { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v3 param; + struct param_hdr_v3 data; +} __packed; + +struct afe_custom_crus_get_config_t { + struct apr_hdr hdr; + struct afe_port_cmd_get_param_v3 param; + struct param_hdr_v3 data; +} __packed; + +/* Payload struct for getting or setting one integer value from/to the DSP module */ +struct crus_single_data_t { + int32_t value; +}; + +/* Payload struct for getting or setting two integer values from/to the DSP module */ +struct crus_dual_data_t { + int32_t data1; + int32_t data2; +}; + +/* Payload struct for getting or setting three integer values from/to the DSP module */ +struct crus_triple_data_t { + int32_t data1; + int32_t data2; + int32_t data3; +}; + +/* Payload struct for setting the RX and TX use cases */ +struct crus_rx_run_case_ctrl_t { + int32_t value; + int32_t status_l; + int32_t checksum_l; + int32_t z_l; + int32_t status_r; + int32_t checksum_r; + int32_t z_r; + int32_t atemp; +}; + +/* Payload struct for getting calibration result from DSP module */ +struct cirrus_cal_result_t { + int32_t status_l; + int32_t checksum_l; + int32_t z_l; + int32_t status_r; + int32_t checksum_r; + int32_t z_r; +}; + +#define APR_CHUNK_SIZE 256 + +/* Payload struct for sending an external configuration string to the DSP + * module + */ +struct crus_external_config_t { + uint32_t total_size; + uint32_t chunk_size; + int32_t done; + int32_t reserved; + int32_t config; + char data[APR_CHUNK_SIZE]; +}; +/* Payload struct for sending an external tuning transition string to the DSP + * module + */ +struct crus_delta_config_t { + uint32_t total_size; + uint32_t chunk_size; + int32_t done; + int32_t index; + int32_t reserved; + int32_t config; + char data[APR_CHUNK_SIZE]; +}; + +struct crus_rx_temperature_t { + uint32_t cal_status_l; + uint32_t temp_r; + uint32_t z_r; + uint32_t temp_l; + uint32_t z_l; + uint32_t cal_status_r; + uint32_t amb_temp_l; + uint32_t excur_model_r; + uint32_t excur_model_l; + uint32_t cksum_r; + uint32_t amb_temp_r; + uint32_t cksum_l; + uint32_t hp_status_l; + uint32_t full_status_l; + uint32_t hp_status_r; + uint32_t full_status_r; +}; + +#define CONFIG_FILE_SIZE 128 +#define PAYLOAD_FOLLOWS_CONFIG 4 +#define MAX_TUNING_CONFIGS 4 +#define MIN_CHAN_SWAP_SAMPLES 48 +#define MAX_CHAN_SWAP_SAMPLES 9600 +#define CRUS_MAX_BUFFER_SIZE 384 + +struct crus_control_t { + struct device *device; + int32_t q6afe_rev; + bool afe_start; + bool enable; + bool prot_en; + int32_t fb_port_index; + int32_t fb_port; + int32_t ff_port; + int ch_sw_duration; + int32_t ch_sw; + int32_t vol_atten; + atomic_t callback_wait; + atomic_t count_wait; + struct mutex param_lock; + struct mutex sp_lock; + int32_t *user_buffer; + int32_t usecase; + int32_t config; + int32_t conf_sel; + int32_t delta_sel; + int32_t usecase_dt_count; +}; + +//extern int afe_apr_send_pkt_crus(void *data, int index, int set); + +int crus_afe_callback(void *payload, int size); +void msm_crus_pb_add_controls(struct snd_soc_platform *platform); +#endif /* _MSM_CIRRUS_PLAYBACK_H */ diff --git a/techpack/audio/include/dsp/tas_smart_amp_v2.h b/techpack/audio/include/dsp/tas_smart_amp_v2.h new file mode 100644 index 000000000000..4aa3b230bdcf --- /dev/null +++ b/techpack/audio/include/dsp/tas_smart_amp_v2.h @@ -0,0 +1,177 @@ +#ifndef __TAS_SMART_AMP__ +#define __TAS_SMART_AMP__ + +/*Should be defined in configuration file*/ +//#define CONFIG_TAS25XX_ALGO +#define CONFIG_TAS25XX_ALGO_STEREO +#define CONFIG_SET_RE_IN_KERNEL + +//FIXME +//update this value at OEM/ODM +//#pragma message ("########### FIXME ################") +#define SMARTAMP_SPEAKER_CALIBDATA_FILE \ + "/mnt/vendor/persist/audio/tas25xx_calib.bin" +//#define SMARTAMP_SPEAKER_CALIBDATA_FILE "/persist/audio/smartamp_calib.bin" + +#define APR_VERSION_V2 0 +#define APR_VERSION_V3 1 + +#include +//#if APR_VERSION_V2 +#include +#include +//#else +//#endif +#include + +#define AFE_SMARTAMP_MODULE_RX 0x11111112 +#define AFE_SMARTAMP_MODULE_TX 0x11111111 + +#define CAPI_V2_TAS_TX_ENABLE 0x10012D14 +#define CAPI_V2_TAS_TX_CFG 0x10012D16 +#define CAPI_V2_TAS_RX_ENABLE 0x10012D13 +#define CAPI_V2_TAS_RX_CFG 0x10012D15 + +#define MAX_DSP_PARAM_INDEX 2048 + +#define TAS_PAYLOAD_SIZE 14 +#define TAS_GET_PARAM 1 +#define TAS_SET_PARAM 0 + +//FIXME +//Update as needed +#define TAS_RX_PORT AFE_PORT_ID_QUATERNARY_MI2S_RX +#define TAS_TX_PORT AFE_PORT_ID_QUATERNARY_MI2S_TX + +#define CHANNEL0 1 +#define CHANNEL1 2 + +#define TRUE 1 +#define FALSE 0 + +#define TAS_SA_GET_F0 3810 +#define TAS_SA_GET_Q 3811 +#define TAS_SA_GET_TV 3812 +#define TAS_SA_GET_RE 3813 +#define TAS_SA_CALIB_INIT 3814 +#define TAS_SA_CALIB_DEINIT 3815 +#define TAS_SA_SET_RE 3816 +#define TAS_SA_F0_TEST_INIT 3817 +#define TAS_SA_F0_TEST_DEINIT 3818 +#define TAS_SA_SET_PROFILE 3819 +#define TAS_SA_GET_STATUS 3821 +#define TAS_SA_SET_SPKID 3822 +#define TAS_SA_SET_TCAL 3823 + +#define TAS_SA_IV_VBAT_FMT 3825 +/*Added for DC Detection*/ +#define CAPI_V2_TAS_SA_DC_DETECT 0x40404040 + +#define CALIB_START 1 +#define CALIB_STOP 2 +#define TEST_START 3 +#define TEST_STOP 4 + +#define SLAVE1 0x98 +#define SLAVE2 0x9A +#define SLAVE3 0x9C +#define SLAVE4 0x9E + +#define CHANNEL0 1 +#define CHANNEL1 2 + +#define TAS_SA_IS_SPL_IDX(X) ((((X) >= 3810) && ((X) < 3899)) ? 1 : 0) +#define TAS_CALC_PARAM_IDX(I, LEN, CH) ((I) | (LEN << 16) | (CH << 24)) +#define AFE_SA_IS_SPL_IDX(X) ((((X) >= 3810) && ((X) < 3899)) ? 1 : 0) +/* To Decode the Param ID */ +#define TAS_PARAM_IDX_GET_ID(X) (0xFFFF & (X)) +#define TAS_PARAM_IDX_GET_LEN(X) ((0x0FFF0000 & (X)) >> 16) +#define TAS_PARAM_IDX_GET_CH(X) ((0xF0000000 & (X)) >> 24) + +typedef enum { + IV_SENSE_FORMAT_NO_VBAT = 0, + IV_SENSE_FORMAT_12_BIT_WITH_8BIT_VBAT = 1, + IV_SENSE_FORMAT_8_BIT_WITH_8BIT_VBAT = 2, +} ti_smartamp_iv_vbat_format_t; + +/* + * List all the other profiles other than none and calibration. + */ +#define TAS_ALGO_PROFILE_LIST "MUSIC", "VOICE", "VOIP", "RINGTONE" + +struct afe_smartamp_get_set_params_t { + uint32_t payload[TAS_PAYLOAD_SIZE]; +} __packed; + +#if APR_VERSION_V2 +struct afe_smartamp_config_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + struct afe_smartamp_get_set_params_t prot_config; +} __packed; + +struct afe_smartamp_get_calib { + struct apr_hdr hdr; + struct afe_port_cmd_get_param_v2 get_param; + struct afe_port_param_data_v2 pdata; + struct afe_smartamp_get_set_params_t res_cfg; +} __packed; + +struct afe_smartamp_calib_get_resp { + uint32_t status; + struct afe_port_param_data_v2 pdata; + struct afe_smartamp_get_set_params_t res_cfg; +} __packed; + +#elif APR_VERSION_V3 + +//#define BUILD_STUB +/* only for build test */ +#ifdef BUILD_STUB +#define INSTANCE_ID_0 0 +#define AFE_PORT_CMDRSP_GET_PARAM_V3 0 +struct param_hdr_v3 { + int module_id; + int instance_id; + int param_id; + int param_size; +}; + +struct mem_mapping_hdr {}; + +#endif + +struct afe_smartamp_get_calib { + struct apr_hdr hdr; + struct mem_mapping_hdr mem_hdr; + struct param_hdr_v3 pdata; + struct afe_smartamp_get_set_params_t res_cfg; +} __packed; + +struct afe_smartamp_calib_get_resp { + uint32_t status; + struct param_hdr_v3 pdata; + struct afe_smartamp_get_set_params_t res_cfg; +} __packed; +#endif + +typedef struct { + int channel; +} dc_detection_data_t; + +void register_tas256x_reset_func(void *fptr, dc_detection_data_t *data); +int afe_tas_smartamp_get_calib_data(uint32_t module_id, uint32_t param_id, + int32_t length, uint8_t *data); +int afe_tas_smartamp_set_calib_data(uint32_t module_id, uint32_t param_id, + int32_t length, uint8_t *data); + +int tas25xx_smartamp_algo_ctrl(u8 *user_data, uint32_t param_id, + uint8_t get_set, uint32_t length, + uint32_t module_id); + +void tas_smartamp_add_algo_controls(struct snd_soc_codec *codec); +//void tas_smartamp_add_algo_controls_for_platform (struct snd_soc_platform *platform); +void tas_smartamp_remove_algo_controls(struct snd_soc_codec *codec); +bool tas25xx_set_iv_bit_fomat(int iv_data_with, int vbat, int update_now); +#endif diff --git a/techpack/audio/include/elliptic/elliptic_data_io.h b/techpack/audio/include/elliptic/elliptic_data_io.h new file mode 100644 index 000000000000..b9f642595dfe --- /dev/null +++ b/techpack/audio/include/elliptic/elliptic_data_io.h @@ -0,0 +1,155 @@ +/** +* Copyright Elliptic Labs 2015-2016 +* Copyright (C) 2019 XiaoMi, Inc. +* +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#define ELLIPTIC_DATA_IO_AP_TO_DSP 0 +#define ELLIPTIC_DATA_IO_DSP_TO_AP 1 + +#define ELLIPTIC_DATA_IO_READ_OK 0 +#define ELLIPTIC_DATA_IO_READ_BUSY 1 +#define ELLIPTIC_DATA_IO_READ_CANCEL 2 + +#define ELLIPTIC_MSG_BUF_SIZE 512 + +/* wake source timeout in ms*/ +#define ELLIPTIC_WAKEUP_TIMEOUT 250 + +#define ELLIPTIC_DATA_FIFO_SIZE (PAGE_SIZE) + +#define ULTRASOUND_RX_PORT_ID 0 +#define ULTRASOUND_TX_PORT_ID 1 + +/* Elliptic Labs UltraSound Module */ +#define ELLIPTIC_ULTRASOUND_DISABLE 0 +#define ELLIPTIC_ULTRASOUND_ENABLE 1 +#define ELLIPTIC_ULTRASOUND_SET_PARAMS 2 +#define ELLIPTIC_ULTRASOUND_GET_PARAMS 3 +#define ELLIPTIC_ULTRASOUND_RAMP_DOWN 4 + +/** Param ID definition */ +#define ELLIPTIC_ULTRASOUND_PARAM_ID_ENGINE_DATA 3 +#define ELLIPTIC_ULTRASOUND_PARAM_ID_CALIBRATION_DATA 11 +#define ELLIPTIC_ULTRASOUND_PARAM_ID_ENGINE_VERSION 12 +#define ELLIPTIC_ULTRASOUND_PARAM_ID_BUILD_BRANCH 14 +#define ELLIPTIC_ULTRASOUND_PARAM_ID_CALIBRATION_V2_DATA 15 +#define ELLIPTIC_ULTRASOUND_PARAM_ID_SENSORHUB 16 +#define ELLIPTIC_ULTRASOUND_PARAM_ID_DIAGNOSTICS_DATA 17 +#define ELLIPTIC_ULTRASOUND_PARAM_ID_TAG 18 +#define ELLIPTIC_ULTRASOUND_PARAM_ID_ML_DATA 19 + +#define ELLIPTIC_DATA_READ_BUSY 0 +#define ELLIPTIC_DATA_READ_OK 1 +#define ELLIPTIC_DATA_READ_CANCEL 2 + +#define ELLIPTIC_ALL_DEVICES -1 +#define ELLIPTIC_DEVICE_0 0 +#define ELLIPTIC_DEVICE_1 1 + +enum elliptic_message_id { + ELLIPTIC_MESSAGE_PAYLOAD, /* Input to AP*/ + ELLIPTIC_MESSAGE_RAW, /* Output from AP*/ + ELLIPTIC_MESSAGE_CALIBRATION, + ELLIPTIC_MESSAGE_CALIBRATION_V2, + ELLIPTIC_MESSAGE_DIAGNOSTICS, + ELLIPTIC_MAX_MESSAGE_IDS +}; + +typedef enum { + ELLIPTIC_DATA_PUSH_FROM_KERNEL, + ELLIPTIC_DATA_PUSH_FROM_USERSPACE +} elliptic_data_push_t; + +struct elliptic_data { + /* wake lock timeout */ + unsigned int wakeup_timeout; + + /* members for top half interrupt handling */ + struct kfifo fifo_isr; + spinlock_t fifo_isr_spinlock; + wait_queue_head_t fifo_isr_not_empty; + struct mutex user_buffer_lock; + + /* buffer to swap data from isr fifo to userspace */ + uint8_t isr_swap_buffer[ELLIPTIC_MSG_BUF_SIZE]; + + atomic_t abort_io; + + /* debug counters, reset between open/close */ + uint32_t isr_fifo_discard; + + /* debug counters, persistent */ + uint32_t isr_fifo_discard_total; + uint32_t userspace_read_total; + uint32_t isr_write_total; +}; + +/* Elliptic IO module API (implemented by IO module)*/ + +int elliptic_data_io_initialize(void); +int elliptic_data_io_cleanup(void); + +int32_t elliptic_data_io_write(uint32_t message_id, const char *data, + size_t data_size); + +int32_t elliptic_data_io_transact(uint32_t message_id, const char *data, + size_t data_size, char *output_data, + size_t output_data_size); + +/* Elliptic driver API (implemented by main driver)*/ +int elliptic_data_initialize(struct elliptic_data *, size_t max_queue_size, + unsigned int wakeup_timeout, int id); + +int elliptic_data_cleanup(struct elliptic_data *); + +void elliptic_data_reset_debug_counters(struct elliptic_data *); +void elliptic_data_update_debug_counters(struct elliptic_data *); +void elliptic_data_print_debug_counters(struct elliptic_data *); + +/* Called from elliptic device read */ +size_t elliptic_data_pop(struct elliptic_data *, char __user *buffer, + size_t buffer_size); + +/* Used for cancelling a blocking read */ +void elliptic_data_cancel(struct elliptic_data *); + +/* Called from IO module*/ +int elliptic_data_push(int deviceid, const char *buffer, size_t buffer_size, + elliptic_data_push_t); + +/* Writes to io module and user space control */ +int32_t elliptic_data_write(uint32_t message_id, const char *data, + size_t data_size); + +/* Opens port */ +int elliptic_open_port(int portid); + +/* Closes port */ +int elliptic_close_port(int portid); + +/* Opens port */ +int elliptic_io_open_port(int portid); + +/* Closes port */ +int elliptic_io_close_port(int portid); + +/* Create device node for userspace io driver*/ +int elliptic_userspace_io_driver_init(void); +void elliptic_userspace_io_driver_exit(void); + +/* Create device node for userspace io driver*/ +int elliptic_userspace_ctrl_driver_init(void); +void elliptic_userspace_ctrl_driver_exit(void); +int32_t elliptic_userspace_ctrl_write(uint32_t message_id, const char *data, + size_t data_size); diff --git a/techpack/audio/include/elliptic/elliptic_device.h b/techpack/audio/include/elliptic/elliptic_device.h new file mode 100644 index 000000000000..6ebf208e8a28 --- /dev/null +++ b/techpack/audio/include/elliptic/elliptic_device.h @@ -0,0 +1,50 @@ +/** + * Copyright Elliptic Labs + * Copyright (C) 2019 XiaoMi, Inc. + * + */ + +#pragma once + +#include +#include +#include +#include + +#define ELLIPTIC_DEVICENAME "elliptic" +#define ELLIPTIC_NUM_DEVICES 2 + +#define IOCTL_ELLIPTIC_APP 197 +#define MIRROR_TAG 0x3D0A4842 + +#define IOCTL_ELLIPTIC_DATA_IO_CANCEL _IO(IOCTL_ELLIPTIC_APP, 2) + +#define IOCTL_ELLIPTIC_ACTIVATE_ENGINE _IOW(IOCTL_ELLIPTIC_APP, 3, int) + +#define IOCTL_ELLIPTIC_SET_RAMP_DOWN _IO(IOCTL_ELLIPTIC_APP, 4) + +#define IOCTL_ELLIPTIC_SYSTEM_CONFIGURATION _IOW(IOCTL_ELLIPTIC_APP, 5, int) + +#define IOCTL_ELLIPTIC_DATA_IO_MIRROR \ + _IOW(IOCTL_ELLIPTIC_APP, 117, unsigned char *) + +struct elliptic_device { + int opened; + struct cdev cdev; + struct semaphore sem; + struct elliptic_data el_data; +}; + +extern struct class *elliptic_class; + +#define EL_PRINT_E(string, arg...) \ + pr_err("[ELUS] : (%s) : " string "\n", __func__, ##arg) + +#define EL_PRINT_W(string, arg...) \ + pr_warn("[ELUS] : (%s) : " string "\n", __func__, ##arg) + +#define EL_PRINT_I(string, arg...) \ + pr_info("[ELUS] : (%s) : " string "\n", __func__, ##arg) + +#define EL_PRINT_D(string, arg...) \ + pr_debug("[ELUS] : (%s) : " string "\n", __func__, ##arg) diff --git a/techpack/audio/include/elliptic/elliptic_mixer_controls.h b/techpack/audio/include/elliptic/elliptic_mixer_controls.h new file mode 100644 index 000000000000..552c38d80409 --- /dev/null +++ b/techpack/audio/include/elliptic/elliptic_mixer_controls.h @@ -0,0 +1,185 @@ +#pragma once +#include +#include +#include +#include + +#define ELLIPTIC_OBJ_ID_CALIBRATION_DATA 1 +#define ELLIPTIC_OBJ_ID_VERSION_INFO 2 +#define ELLIPTIC_OBJ_ID_BRANCH_INFO 3 +#define ELLIPTIC_OBJ_ID_CALIBRATION_V2_DATA 4 +#define ELLIPTIC_OBJ_ID_DIAGNOSTICS_DATA 5 +#define ELLIPTIC_OBJ_ID_TAG_INFO 6 +#define ELLIPTIC_OBJ_ID_ML_DATA 7 + +#define ELLIPTIC_SYSTEM_CONFIGURATION_SIZE 96 +#define ELLIPTIC_CALIBRATION_DATA_SIZE 64 +#define ELLIPTIC_CALIBRATION_V2_DATA_SIZE 448 +#define ELLIPTIC_DIAGNOSTICS_DATA_SIZE 448 +#define ELLIPTIC_DIAGNOSTICS_U32_DATA_VALUES \ + (ELLIPTIC_DIAGNOSTICS_DATA_SIZE >> 2) +#define ELLIPTIC_SENSOR_DATA_SIZE 68 +#define ELLIPTIC_SENSOR_U32_DATA_VALUES (ELLIPTIC_SENSOR_DATA_SIZE >> 2) +#define ELLIPTIC_VERSION_INFO_SIZE 16 +#define ELLIPTIC_BRANCH_INFO_SIZE 32 +#define ELLIPTIC_BRANCH_INFO_MAX_SIZE 128 +#define ELLIPTIC_TAG_INFO_SIZE 32 +#define ELLIPTIC_ML_DATA_SIZE 432 + +#define ELLIPTIC_ULTRASOUND_DISABLE 0 +#define ELLIPTIC_ULTRASOUND_ENABLE 1 +#define ELLIPTIC_ULTRASOUND_SET_PARAMS 2 +#define ELLIPTIC_ULTRASOUND_GET_PARAMS 3 +#define ELLIPTIC_ULTRASOUND_RAMP_DOWN 4 + +/** register */ +#define ELLIPTIC_CALIBRATION 1 +/** bits */ +#define ELLIPTIC_CALIBRATION_STATE 0 +#define ELLIPTIC_CALIBRATION_PROFILE 1 +#define ELLIPTIC_ULTRASOUND_GAIN 2 + +/** custom settings */ +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_COUNT 16 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE 0x7FFFFFFF + +/** register */ +#define ELLIPTIC_SYSTEM_CONFIGURATION 0 +/** bits */ +#define ELLIPTIC_SYSTEM_CONFIGURATION_LATENCY 0 +#define ELLIPTIC_SYSTEM_CONFIGURATION_SENSITIVITY 1 +#define ELLIPTIC_SYSTEM_CONFIGURATION_SPEAKER_SCALING 2 +#define ELLIPTIC_SYSTEM_CONFIGURATION_MICROPHONE_INDEX 3 +#define ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE 4 +#define ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE_FLAGS 5 +#define ELLIPTIC_SYSTEM_CONFIGURATION_LOG_LEVEL 6 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_0 7 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_1 8 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_2 9 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_3 10 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_4 11 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_5 12 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_6 13 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_7 14 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_8 15 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_9 16 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_10 17 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_11 18 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_12 19 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_13 20 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_14 21 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_15 22 + +#define ELLIPTIC_SYSTEM_CONFIGURATION_SUSPEND 23 +#define ELLIPTIC_SYSTEM_CONFIGURATION_INPUT_ENABLED 24 +#define ELLIPTIC_SYSTEM_CONFIGURATION_OUTPUT_ENABLED 25 +#define ELLIPTIC_SYSTEM_CONFIGURATION_EXTERNAL_EVENT 26 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CALIBRATION_METHOD 27 +#define ELLIPTIC_SYSTEM_CONFIGURATION_DEBUG_MODE 28 +#define ELLIPTIC_SYSTEM_CONFIGURATION_NUMBER_OF_RUNS 29 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CONTEXT 30 +#define ELLIPTIC_SYSTEM_CONFIGURATION_CAPTURE 31 +#define ELLIPTIC_SYSTEM_CONFIGURATION_INPUT_CHANNELS 32 + +#define ELLIPTIC_SYSTEM_CONFIGURATION_MAX_CONTEXT_VALUE 0x7FFFFFFF + +struct elliptic_engine_version_info { + uint32_t major; + uint32_t minor; + uint32_t build; + uint32_t revision; +}; + +struct elliptic_shared_data_block { + uint32_t object_id; + size_t size; + void *buffer; +}; + +struct elliptic_shared_data_block *elliptic_get_shared_obj(uint32_t object_id); + +extern unsigned int elliptic_add_platform_controls(void *platform); + +void elliptic_set_calibration_data(uint8_t *calib_data, size_t size); + +enum elliptic_system_configuration_parameter_type { + + ESCPT_SPEAKER_SCALING = 1, + ESCPT_CHANNEL_SENSITIVITY, + ESCPT_LATENCY, + ESCPT_MICROPHONE_INDEX, + ESCPT_OPERATION_MODE, + ESCPT_OPERATION_MODE_FLAGS, + ESCPT_COMPONENT_GAIN_CHANGE, + ESCPT_CALIBRATION_STATE, + ESCPT_ENGINE_VERSION, + ESCPT_CALIBRATION_PROFILE, + ESCPT_ULTRASOUND_GAIN, + ESCPT_LOG_LEVEL, + ESCPT_BUILD_BRANCH, //13 + + ESCPT_FSELECTION, + ESCPT_ENGINE_DIAGNOSTICS, + ESCPT_ENGINE_CUSTOM_SETTING_0, + ESCPT_ENGINE_CUSTOM_SETTING_1, + ESCPT_ENGINE_CUSTOM_SETTING_2, + ESCPT_ENGINE_CUSTOM_SETTING_3, + ESCPT_ENGINE_CUSTOM_SETTING_4, + ESCPT_ENGINE_CUSTOM_SETTING_5, + ESCPT_ENGINE_CUSTOM_SETTING_6, + ESCPT_ENGINE_CUSTOM_SETTING_7, + ESCPT_ENGINE_CUSTOM_SETTING_8, + ESCPT_ENGINE_CUSTOM_SETTING_9, + ESCPT_ENGINE_CUSTOM_SETTING_10, + ESCPT_ENGINE_CUSTOM_SETTING_11, + ESCPT_ENGINE_CUSTOM_SETTING_12, + ESCPT_ENGINE_CUSTOM_SETTING_13, + ESCPT_ENGINE_CUSTOM_SETTING_14, + ESCPT_ENGINE_CUSTOM_SETTING_15, + ESCPT_SUSPEND, // 32 + ESCPT_INPUT_ENABLED, + ESCPT_OUTPUT_ENABLED, + ESCPT_EXTERNAL_EVENT, + ESCPT_ENGINE_TAG, //36 + ESCPT_CALIBRATION_METHOD, + ESCPT_DEBUG_MODE, + ESCPT_NUMBER_OF_RUNS, + ESCPT_CONTEXT, + ESCPT_CAPTURE, + ESCPT_INPUT_CHANNELS, +}; + +struct elliptic_system_configuration_parameters_cache { + int32_t speaker_scaling[2]; + int32_t sensitivity; + int32_t latency; + int32_t microphone_index; + int32_t operation_mode; + int32_t operation_mode_flags; + int32_t component_gain_change; + int32_t calibration_state; + int32_t engine_version; + int32_t calibration_profile; + int32_t ultrasound_gain; + int32_t log_level; + int32_t custom_settings + [ELLIPTIC_SYSTEM_CONFIGURATION_CUSTOM_SETTING_COUNT]; + int32_t engine_suspend; + int32_t input_enabled; + int32_t output_enabled; + int32_t external_event; + int32_t calibration_method; + int32_t debug_mode; + int32_t number_of_runs; + int32_t context; + int32_t capture; + int32_t input_channels; +}; + +int elliptic_trigger_version_msg(void); + +int elliptic_trigger_branch_msg(void); + +int elliptic_trigger_tag_msg(void); + +int elliptic_trigger_diagnostics_msg(void); diff --git a/techpack/audio/include/elliptic/elliptic_sysfs.h b/techpack/audio/include/elliptic/elliptic_sysfs.h new file mode 100644 index 000000000000..def9e027d395 --- /dev/null +++ b/techpack/audio/include/elliptic/elliptic_sysfs.h @@ -0,0 +1,14 @@ +#pragma once + +#define ELLIPTIC_SYSFS_ENGINE_FOLDER "engine" +#define ELLIPTIC_SYSFS_ROOT_FOLDER "elliptic" +#define ELLIPTIC_SYSFS_CALIBRATION_FILENAME "calibration" +#define ELLIPTIC_SYSFS_VERSION_FILENAME "version" +#define ELLIPTIC_SYSFS_CALIBRATION_V2_FILENAME "calibration_v2" +#define ELLIPTIC_SYSFS_STATE_FILENAME "state" +#define ELLIPTIC_SYSFS_TAG_FILENAME "tag" +#define ELLIPTIC_SYSFS_OPMODE_FILENAME "opmode" +#define ELLIPTIC_SYSFS_OPMODE_FLAGS_FILENAME "opmode_flags" + +int elliptic_initialize_sysfs(void); +void elliptic_cleanup_sysfs(void); diff --git a/techpack/audio/include/mius/mius_data_io.h b/techpack/audio/include/mius/mius_data_io.h new file mode 100644 index 000000000000..6cce52797383 --- /dev/null +++ b/techpack/audio/include/mius/mius_data_io.h @@ -0,0 +1,155 @@ +/** +* Copyright MI 2015-2016 +* Copyright (C) 2019 XiaoMi, Inc. +* +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#define MIUS_DATA_IO_AP_TO_DSP 0 +#define MIUS_DATA_IO_DSP_TO_AP 1 + +#define MIUS_DATA_IO_READ_OK 0 +#define MIUS_DATA_IO_READ_BUSY 1 +#define MIUS_DATA_IO_READ_CANCEL 2 + +#define MIUS_MSG_BUF_SIZE 512 + +/* wake source timeout in ms*/ +#define MIUS_WAKEUP_TIMEOUT 250 + +#define MIUS_DATA_FIFO_SIZE (PAGE_SIZE) + +#define ULTRASOUND_RX_PORT_ID 0 +#define ULTRASOUND_TX_PORT_ID 1 + +/* MI UltraSound Module */ +#define MIUS_ULTRASOUND_DISABLE 0 +#define MIUS_ULTRASOUND_ENABLE 1 +#define MIUS_ULTRASOUND_SET_PARAMS 2 +#define MIUS_ULTRASOUND_GET_PARAMS 3 +#define MIUS_ULTRASOUND_RAMP_DOWN 4 + +/** Param ID definition */ +#define MIUS_ULTRASOUND_PARAM_ID_ENGINE_DATA 3 +#define MIUS_ULTRASOUND_PARAM_ID_CALIBRATION_DATA 11 +#define MIUS_ULTRASOUND_PARAM_ID_ENGINE_VERSION 12 +#define MIUS_ULTRASOUND_PARAM_ID_BUILD_BRANCH 14 +#define MIUS_ULTRASOUND_PARAM_ID_CALIBRATION_V2_DATA 15 +#define MIUS_ULTRASOUND_PARAM_ID_SENSORHUB 16 +#define MIUS_ULTRASOUND_PARAM_ID_DIAGNOSTICS_DATA 17 +#define MIUS_ULTRASOUND_PARAM_ID_TAG 18 +#define MIUS_ULTRASOUND_PARAM_ID_ML_DATA 19 + +#define MIUS_DATA_READ_BUSY 0 +#define MIUS_DATA_READ_OK 1 +#define MIUS_DATA_READ_CANCEL 2 + +#define MIUS_ALL_DEVICES -1 +#define MIUS_DEVICE_0 0 +#define MIUS_DEVICE_1 1 + +enum mius_message_id { + MIUS_MESSAGE_PAYLOAD, /* Input to AP*/ + MIUS_MESSAGE_RAW, /* Output from AP*/ + MIUS_MESSAGE_CALIBRATION, + MIUS_MESSAGE_CALIBRATION_V2, + MIUS_MESSAGE_DIAGNOSTICS, + MIUS_MAX_MESSAGE_IDS +}; + +typedef enum { + MIUS_DATA_PUSH_FROM_KERNEL, + MIUS_DATA_PUSH_FROM_USERSPACE +} mius_data_push_t; + +struct mius_data { + /* wake lock timeout */ + unsigned int wakeup_timeout; + + /* members for top half interrupt handling */ + struct kfifo fifo_isr; + spinlock_t fifo_isr_spinlock; + wait_queue_head_t fifo_isr_not_empty; + struct mutex user_buffer_lock; + + /* buffer to swap data from isr fifo to userspace */ + uint8_t isr_swap_buffer[MIUS_MSG_BUF_SIZE]; + + atomic_t abort_io; + + /* debug counters, reset between open/close */ + uint32_t isr_fifo_discard; + + /* debug counters, persistent */ + uint32_t isr_fifo_discard_total; + uint32_t userspace_read_total; + uint32_t isr_write_total; +}; + +/* Elliptic IO module API (implemented by IO module)*/ + +int mius_data_io_initialize(void); +int mius_data_io_cleanup(void); + +int32_t mius_data_io_write(uint32_t message_id, const char *data, + size_t data_size); + +int32_t mius_data_io_transact(uint32_t message_id, const char *data, + size_t data_size, char *output_data, + size_t output_data_size); + +/* Elliptic driver API (implemented by main driver)*/ +int mius_data_initialize(struct mius_data *, size_t max_queue_size, + unsigned int wakeup_timeout, int id); + +int mius_data_cleanup(struct mius_data *); + +void mius_data_reset_debug_counters(struct mius_data *); +void mius_data_update_debug_counters(struct mius_data *); +void mius_data_print_debug_counters(struct mius_data *); + +/* Called from mius device read */ +size_t mius_data_pop(struct mius_data *, char __user *buffer, + size_t buffer_size); + +/* Used for cancelling a blocking read */ +void mius_data_cancel(struct mius_data *); + +/* Called from IO module*/ +int mius_data_push(int deviceid, const char *buffer, size_t buffer_size, + mius_data_push_t); + +/* Writes to io module and user space control */ +int32_t mius_data_write(uint32_t message_id, const char *data, + size_t data_size); + +/* Opens port */ +int mius_open_port(int portid); + +/* Closes port */ +int mius_close_port(int portid); + +/* Opens port */ +int mius_io_open_port(int portid); + +/* Closes port */ +int mius_io_close_port(int portid); + +/* Create device node for userspace io driver*/ +int mius_userspace_io_driver_init(void); +void mius_userspace_io_driver_exit(void); + +/* Create device node for userspace io driver*/ +int mius_userspace_ctrl_driver_init(void); +void mius_userspace_ctrl_driver_exit(void); +int32_t mius_userspace_ctrl_write(uint32_t message_id, const char *data, + size_t data_size); diff --git a/techpack/audio/include/mius/mius_device.h b/techpack/audio/include/mius/mius_device.h new file mode 100644 index 000000000000..9559340bcad9 --- /dev/null +++ b/techpack/audio/include/mius/mius_device.h @@ -0,0 +1,49 @@ +/** + * Copyright MI + * Copyright (C) 2019 XiaoMi, Inc. + * + */ + +#pragma once + +#include +#include +#include +#include + +#define MIUS_DEVICENAME "mius" +#define MIUS_NUM_DEVICES 2 + +#define IOCTL_MIUS_APP 197 +#define MIRROR_TAG 0x3D0A4842 + +#define IOCTL_MIUS_DATA_IO_CANCEL _IO(IOCTL_MIUS_APP, 2) + +#define IOCTL_MIUS_ACTIVATE_ENGINE _IOW(IOCTL_MIUS_APP, 3, int) + +#define IOCTL_MIUS_SET_RAMP_DOWN _IO(IOCTL_MIUS_APP, 4) + +#define IOCTL_MIUS_SYSTEM_CONFIGURATION _IOW(IOCTL_MIUS_APP, 5, int) + +#define IOCTL_MIUS_DATA_IO_MIRROR _IOW(IOCTL_MIUS_APP, 117, unsigned char *) + +struct mius_device { + int opened; + struct cdev cdev; + struct semaphore sem; + struct mius_data el_data; +}; + +extern struct class *mius_class; + +#define MI_PRINT_E(string, arg...) \ + pr_err("[MIUS] : (%s) : " string "\n", __func__, ##arg) + +#define MI_PRINT_W(string, arg...) \ + pr_warn("[MIUS] : (%s) : " string "\n", __func__, ##arg) + +#define MI_PRINT_I(string, arg...) \ + pr_info("[MIUS] : (%s) : " string "\n", __func__, ##arg) + +#define MI_PRINT_D(string, arg...) \ + pr_debug("[MIUS] : (%s) : " string "\n", __func__, ##arg) diff --git a/techpack/audio/include/mius/mius_mixer_controls.h b/techpack/audio/include/mius/mius_mixer_controls.h new file mode 100644 index 000000000000..f79900aff8dc --- /dev/null +++ b/techpack/audio/include/mius/mius_mixer_controls.h @@ -0,0 +1,183 @@ +#pragma once +#include +#include +#include +#include + +#define MIUS_OBJ_ID_CALIBRATION_DATA 1 +#define MIUS_OBJ_ID_VERSION_INFO 2 +#define MIUS_OBJ_ID_BRANCH_INFO 3 +#define MIUS_OBJ_ID_CALIBRATION_V2_DATA 4 +#define MIUS_OBJ_ID_DIAGNOSTICS_DATA 5 +#define MIUS_OBJ_ID_TAG_INFO 6 +#define MIUS_OBJ_ID_ML_DATA 7 + +#define MIUS_SYSTEM_CONFIGURATION_SIZE 96 +#define MIUS_CALIBRATION_DATA_SIZE 64 +#define MIUS_CALIBRATION_V2_DATA_SIZE 448 +#define MIUS_DIAGNOSTICS_DATA_SIZE 448 +#define MIUS_DIAGNOSTICS_U32_DATA_VALUES (MIUS_DIAGNOSTICS_DATA_SIZE >> 2) +#define MIUS_SENSOR_DATA_SIZE 68 +#define MIUS_SENSOR_U32_DATA_VALUES (MIUS_SENSOR_DATA_SIZE >> 2) +#define MIUS_VERSION_INFO_SIZE 16 +#define MIUS_BRANCH_INFO_SIZE 32 +#define MIUS_BRANCH_INFO_MAX_SIZE 128 +#define MIUS_TAG_INFO_SIZE 32 +#define MIUS_ML_DATA_SIZE 432 + +#define MIUS_ULTRASOUND_DISABLE 0 +#define MIUS_ULTRASOUND_ENABLE 1 +#define MIUS_ULTRASOUND_SET_PARAMS 2 +#define MIUS_ULTRASOUND_GET_PARAMS 3 +#define MIUS_ULTRASOUND_RAMP_DOWN 4 + +/** register */ +#define MIUS_CALIBRATION 1 +/** bits */ +#define MIUS_CALIBRATION_STATE 0 +#define MIUS_CALIBRATION_PROFILE 1 +#define MIUS_ULTRASOUND_GAIN 2 + +/** custom settings */ +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_COUNT 16 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_MAX_VALUE 0x7FFFFFFF + +/** register */ +#define MIUS_SYSTEM_CONFIGURATION 0 +/** bits */ +#define MIUS_SYSTEM_CONFIGURATION_LATENCY 0 +#define MIUS_SYSTEM_CONFIGURATION_SENSITIVITY 1 +#define MIUS_SYSTEM_CONFIGURATION_SPEAKER_SCALING 2 +#define MIUS_SYSTEM_CONFIGURATION_MICROPHONE_INDEX 3 +#define MIUS_SYSTEM_CONFIGURATION_OPERATION_MODE 4 +#define MIUS_SYSTEM_CONFIGURATION_OPERATION_MODE_FLAGS 5 +#define MIUS_SYSTEM_CONFIGURATION_LOG_LEVEL 6 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_0 7 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_1 8 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_2 9 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_3 10 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_4 11 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_5 12 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_6 13 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_7 14 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_8 15 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_9 16 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_10 17 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_11 18 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_12 19 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_13 20 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_14 21 +#define MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_15 22 + +#define MIUS_SYSTEM_CONFIGURATION_SUSPEND 23 +#define MIUS_SYSTEM_CONFIGURATION_INPUT_ENABLED 24 +#define MIUS_SYSTEM_CONFIGURATION_OUTPUT_ENABLED 25 +#define MIUS_SYSTEM_CONFIGURATION_EXTERNAL_EVENT 26 +#define MIUS_SYSTEM_CONFIGURATION_CALIBRATION_METHOD 27 +#define MIUS_SYSTEM_CONFIGURATION_DEBUG_MODE 28 +#define MIUS_SYSTEM_CONFIGURATION_NUMBER_OF_RUNS 29 +#define MIUS_SYSTEM_CONFIGURATION_CONTEXT 30 +#define MIUS_SYSTEM_CONFIGURATION_CAPTURE 31 +#define MIUS_SYSTEM_CONFIGURATION_INPUT_CHANNELS 32 + +#define MIUS_SYSTEM_CONFIGURATION_MAX_CONTEXT_VALUE 0x7FFFFFFF + +struct mius_engine_version_info { + uint32_t major; + uint32_t minor; + uint32_t build; + uint32_t revision; +}; + +struct mius_shared_data_block { + uint32_t object_id; + size_t size; + void *buffer; +}; + +struct mius_shared_data_block *mius_get_shared_obj(uint32_t object_id); + +extern unsigned int mius_add_platform_controls(void *platform); + +void mius_set_calibration_data(uint8_t *calib_data, size_t size); + +enum mius_system_configuration_parameter_type { + + MSC_SPEAKER_SCALING = 1, + MSC_CHANNEL_SENSITIVITY, + MSC_LATENCY, + MSC_MICROPHONE_INDEX, + MSC_OPERATION_MODE, + MSC_OPERATION_MODE_FLAGS, + MSC_COMPONENT_GAIN_CHANGE, + MSC_CALIBRATION_STATE, + MSC_ENGINE_VERSION, + MSC_CALIBRATION_PROFILE, + MSC_ULTRASOUND_GAIN, + MSC_LOG_LEVEL, + MSC_BUILD_BRANCH, //13 + + MSC_FSELECTION, + MSC_ENGINE_DIAGNOSTICS, + MSC_ENGINE_CUSTOM_SETTING_0, + MSC_ENGINE_CUSTOM_SETTING_1, + MSC_ENGINE_CUSTOM_SETTING_2, + MSC_ENGINE_CUSTOM_SETTING_3, + MSC_ENGINE_CUSTOM_SETTING_4, + MSC_ENGINE_CUSTOM_SETTING_5, + MSC_ENGINE_CUSTOM_SETTING_6, + MSC_ENGINE_CUSTOM_SETTING_7, + MSC_ENGINE_CUSTOM_SETTING_8, + MSC_ENGINE_CUSTOM_SETTING_9, + MSC_ENGINE_CUSTOM_SETTING_10, + MSC_ENGINE_CUSTOM_SETTING_11, + MSC_ENGINE_CUSTOM_SETTING_12, + MSC_ENGINE_CUSTOM_SETTING_13, + MSC_ENGINE_CUSTOM_SETTING_14, + MSC_ENGINE_CUSTOM_SETTING_15, + MSC_SUSPEND, // 32 + MSC_INPUT_ENABLED, + MSC_OUTPUT_ENABLED, + MSC_EXTERNAL_EVENT, + MSC_ENGINE_TAG, //36 + MSC_CALIBRATION_METHOD, + MSC_DEBUG_MODE, + MSC_NUMBER_OF_RUNS, + MSC_CONTEXT, + MSC_CAPTURE, + MSC_INPUT_CHANNELS, +}; + +struct mius_system_configuration_parameters_cache { + int32_t speaker_scaling[2]; + int32_t sensitivity; + int32_t latency; + int32_t microphone_index; + int32_t operation_mode; + int32_t operation_mode_flags; + int32_t component_gain_change; + int32_t calibration_state; + int32_t engine_version; + int32_t calibration_profile; + int32_t ultrasound_gain; + int32_t log_level; + int32_t custom_settings[MIUS_SYSTEM_CONFIGURATION_CUSTOM_SETTING_COUNT]; + int32_t engine_suspend; + int32_t input_enabled; + int32_t output_enabled; + int32_t external_event; + int32_t calibration_method; + int32_t debug_mode; + int32_t number_of_runs; + int32_t context; + int32_t capture; + int32_t input_channels; +}; + +int mius_trigger_version_msg(void); + +int mius_trigger_branch_msg(void); + +int mius_trigger_tag_msg(void); + +int mius_trigger_diagnostics_msg(void); diff --git a/techpack/audio/include/mius/mius_sysfs.h b/techpack/audio/include/mius/mius_sysfs.h new file mode 100644 index 000000000000..7f850c67e5c3 --- /dev/null +++ b/techpack/audio/include/mius/mius_sysfs.h @@ -0,0 +1,14 @@ +#pragma once + +#define MIUS_SYSFS_ENGINE_FOLDER "engine" +#define MIUS_SYSFS_ROOT_FOLDER "mius" +#define MIUS_SYSFS_CALIBRATION_FILENAME "calibration" +#define MIUS_SYSFS_VERSION_FILENAME "version" +#define MIUS_SYSFS_CALIBRATION_V2_FILENAME "calibration_v2" +#define MIUS_SYSFS_STATE_FILENAME "state" +#define MIUS_SYSFS_TAG_FILENAME "tag" +#define MIUS_SYSFS_OPMODE_FILENAME "opmode" +#define MIUS_SYSFS_OPMODE_FLAGS_FILENAME "opmode_flags" + +int mius_initialize_sysfs(void); +void mius_cleanup_sysfs(void); diff --git a/techpack/audio/include/uapi/sound/cs35l41.h b/techpack/audio/include/uapi/sound/cs35l41.h new file mode 100644 index 000000000000..39f6df1a17ba --- /dev/null +++ b/techpack/audio/include/uapi/sound/cs35l41.h @@ -0,0 +1,84 @@ +/* + * linux/sound/cs35l41.h -- Platform data for CS35L41 + * + * Copyright (c) 2018 Cirrus Logic Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __CS35L41_H +#define __CS35L41_H + +struct classh_cfg { + bool classh_bst_override; + bool classh_algo_enable; + int classh_bst_max_limit; + int classh_mem_depth; + int classh_release_rate; + int classh_headroom; + int classh_wk_fet_delay; + int classh_wk_fet_thld; +}; + +struct irq_cfg { + bool is_present; + bool irq_pol_inv; + bool irq_out_en; + int irq_src_sel; +}; + +struct cs35l41_platform_data { + bool sclk_frc; + bool lrclk_frc; + bool right_channel; + bool amp_gain_zc; + bool ng_enable; + int bst_ind; + int bst_vctrl; + int bst_ipk; + int bst_cap; + int temp_warn_thld; + int ng_pcm_thld; + int ng_delay; + int dout_hiz; + struct irq_cfg irq_config1; + struct irq_cfg irq_config2; + struct classh_cfg classh_config; + int mnSpkType; + struct device_node *spk_id_gpio_p; +}; + +struct cs35l41_private { + struct wm_adsp dsp; /* needs to be first member */ + struct snd_soc_codec *codec; + struct cs35l41_platform_data pdata; + struct device *dev; + struct regmap *regmap; + struct regulator_bulk_data supplies[2]; + int num_supplies; + int irq; + int clksrc; + int extclk_freq; + int extclk_cfg; + int sclk; + unsigned int cspl_cmd; + bool dspa_mode; + bool i2s_mode; + bool swire_mode; + bool halo_booted; + bool bus_spi; + /* GPIO for /RST */ + //struct gpio_desc *reset_gpio; + int reset_gpio; + struct completion global_pup_done; + struct completion global_pdn_done; + struct completion mbox_cmd; +}; + +int cs35l41_probe(struct cs35l41_private *cs35l41, + struct cs35l41_platform_data *pdata); +int spk_id_get(struct device_node *np); +#endif /* __CS35L41_H */ diff --git a/techpack/audio/include/uapi/sound/cs35l41_v2.h b/techpack/audio/include/uapi/sound/cs35l41_v2.h new file mode 100644 index 000000000000..e5bb86a795be --- /dev/null +++ b/techpack/audio/include/uapi/sound/cs35l41_v2.h @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * linux/sound/cs35l41.h -- Platform data for CS35L41 + * + * Copyright (c) 2018 Cirrus Logic Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __CS35L41_H +#define __CS35L41_H + +struct classh_cfg { + bool classh_bst_override; + bool classh_algo_enable; + int classh_bst_max_limit; + int classh_mem_depth; + int classh_release_rate; + int classh_headroom; + int classh_wk_fet_delay; + int classh_wk_fet_thld; +}; + +struct irq_cfg { + bool is_present; + bool irq_pol_inv; + bool irq_out_en; + int irq_src_sel; +}; + +struct cs35l41_platform_data { + bool sclk_frc; + bool lrclk_frc; + bool right_channel; + bool amp_gain_zc; + bool dsp_ng_enable; + bool tuning_has_prefix; + bool invert_pcm; + bool hibernate_enable; + bool fwname_use_revid; + int bst_ind; + int bst_vctrl; + int bst_ipk; + int bst_cap; + int temp_warn_thld; + int dsp_ng_pcm_thld; + int dsp_ng_delay; + unsigned int hw_ng_sel; + unsigned int hw_ng_delay; + unsigned int hw_ng_thld; + int dout_hiz; + struct irq_cfg irq_config1; + struct irq_cfg irq_config2; + struct classh_cfg classh_config; +}; + +struct cs35l41_rst_cache { + bool extclk_cfg; + int asp_width; + int asp_wl; + int asp_fmt; + int lrclk_fmt; + int sclk_fmt; + int slave_mode; + int fs_cfg; +}; + +struct cs35l41_vol_ctl { + struct workqueue_struct *ramp_wq; + struct work_struct ramp_work; + struct mutex vol_mutex; /* Protect set volume */ + atomic_t manual_ramp; /* boolean */ + atomic_t ramp_abort; /* boolean */ + atomic_t vol_ramp; /* boolean */ + atomic_t playback; /* boolean */ + int ramp_init_att; + int ramp_knee_att; + unsigned int ramp_knee_time; + unsigned int ramp_end_time; + int dig_vol; + unsigned int auto_ramp_timeout; + unsigned int output_dev; + unsigned int prev_active_dev; + ktime_t dev_timestamp; +}; + +struct cs35l41_private { + struct wm_adsp dsp; /* needs to be first member */ + struct snd_soc_codec *codec; + struct cs35l41_platform_data pdata; + struct device *dev; + struct regmap *regmap; + struct regulator_bulk_data supplies[2]; + int num_supplies; + int irq; + int clksrc; + int extclk_freq; + int extclk_cfg; + int sclk; + int lrclk_fmt; + int sclk_fmt; + int amp_hibernate; + bool reload_tuning; + bool dspa_mode; + bool i2s_mode; + bool swire_mode; + bool halo_booted; + bool skip_codec_probe; + bool bus_spi; + bool fast_switch_en; + bool force_int; + bool hibernate_force_wake; + /* GPIO for /RST */ + struct gpio_desc *reset_gpio; + /* Run-time mixer */ + unsigned int fast_switch_file_idx; + struct soc_enum fast_switch_enum; + const char **fast_switch_names; + struct delayed_work hb_work; + struct workqueue_struct *wq; + struct mutex hb_lock; + struct cs35l41_rst_cache reset_cache; + struct mutex rate_lock; + struct mutex force_int_lock; + struct cs35l41_vol_ctl vol_ctl; + unsigned int ctl_cache[CS35L41_CTRL_CACHE_SIZE]; + u32 trim_cache[CS35L41_TRIM_CACHE_SIZE]; +}; + +int cs35l41_probe(struct cs35l41_private *cs35l41, + struct cs35l41_platform_data *pdata); +int cs35l41_remove(struct cs35l41_private *cs35l41); + +#endif /* __CS35L41_H */ diff --git a/techpack/audio/include/uapi/sound/msm-cirrus-playback.h b/techpack/audio/include/uapi/sound/msm-cirrus-playback.h new file mode 100644 index 000000000000..825a03fb5122 --- /dev/null +++ b/techpack/audio/include/uapi/sound/msm-cirrus-playback.h @@ -0,0 +1,119 @@ +/* Copyright (c) 2016 Cirrus Logic, Inc. + * Copyright (C) 2019 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 _UAPI_MSM_CIRRUS_SPK_PR_H +#define _UAPI_MSM_CIRRUS_SPK_PR_H + +#include +#include + +#define CIRRUS_SP 0x10027053 +#define CIRRUS_SP_ENABLE 0x10002001 + +#define CRUS_MODULE_ID_TX 0x00000002 +#define CRUS_MODULE_ID_RX 0x00000001 + +/* + * CRUS_PARAM_RX/TX_SET_USECASE + * 0 = Music Playback in firmware + * 1 = VOICE Playback in firmware + * 2 = Tuning file loaded using external + * config load command + * + * uses crus_rx_run_case_ctrl for RX apr pckt + * uses crus_single_data_ctrl for TX apr pckt + * + */ +#define CRUS_PARAM_RX_SET_USECASE 0x00A1AF02 +#define CRUS_PARAM_TX_SET_USECASE 0x00A1BF0A +/* + * CRUS_PARAM_RX/TX_SET_CALIB + * Non-zero value to run speaker + * calibration sequence + * + * uses crus_single_data_t apr pckt + */ +#define CRUS_PARAM_RX_SET_CALIB 0x00A1AF03 +#define CRUS_PARAM_TX_SET_CALIB 0x00A1BF03 +/* + * CRUS_PARAM_RX/TX_SET_EXT_CONFIG + * config string loaded from libfirmware + * max of 7K paramters + * + * uses crus_external_config_t apr pckt + */ +#define CRUS_PARAM_RX_SET_EXT_CONFIG 0x00A1AF05 +#define CRUS_PARAM_TX_SET_EXT_CONFIG 0x00A1BF08 +/* + * CRUS_PARAM_RX_GET_TEMP + * get current Temp and calibration data + * + * CRUS_PARAM_TX_GET_TEMP_CAL + * get results of calibration sequence + * + * uses cirrus_cal_result_t apr pckt + */ +#define CRUS_PARAM_RX_GET_TEMP 0x00A1AF07 +#define CRUS_PARAM_TX_GET_TEMP_CAL 0x00A1BF06 +/* + * CRUS_PARAM_RX_SET_DELTA_CONFIG + * load seamless transition config string + * + * CRUS_PARAM_RX_RUN_DELTA_CONFIG + * execute the loaded seamless transition + */ +#define CRUS_PARAM_RX_SET_DELTA_CONFIG 0x00A1AF0D +#define CRUS_PARAM_RX_RUN_DELTA_CONFIG 0x00A1AF0E +/* + * CRUS_PARAM_RX_CHANNEL_SWAP + * initiate l/r channel swap transition + */ +#define CRUS_PARAM_RX_CHANNEL_SWAP 0x00A1AF12 +#define CRUS_PARAM_RX_GET_CHANNEL_SWAP 0x00A1AF13 +/* + * CRUS_PARAM_RX_SET_ATTENUATION + * set volume attenuation in volume control blocks 1 & 2 + */ +#define CRUS_PARAM_RX_SET_ATTENUATION 0x00A1AF0A +#define CRUS_AFE_PARAM_ID_ENABLE 0x00010203 + +#define SPK_PROT_IOCTL_MAGIC 'a' + +#define CRUS_SP_IOCTL_GET _IOWR(SPK_PROT_IOCTL_MAGIC, 219, void *) +#define CRUS_SP_IOCTL_SET _IOWR(SPK_PROT_IOCTL_MAGIC, 220, void *) +#define CRUS_SP_IOCTL_GET_CALIB _IOWR(SPK_PROT_IOCTL_MAGIC, 221, void *) +#define CRUS_SP_IOCTL_SET_CALIB _IOWR(SPK_PROT_IOCTL_MAGIC, 222, void *) +#define CRUS_SP_IOCTL_READ_CALIB_FROM_SLOT \ + _IOWR(SPK_PROT_IOCTL_MAGIC, 223, void *) +#define CRUS_SP_IOCTL_WRITE_CALIB_TO_SLOT \ + _IOWR(SPK_PROT_IOCTL_MAGIC, 224, void *) + +#define CRUS_SP_IOCTL_GET32 _IOWR(SPK_PROT_IOCTL_MAGIC, 219, compat_uptr_t) +#define CRUS_SP_IOCTL_SET32 _IOWR(SPK_PROT_IOCTL_MAGIC, 220, compat_uptr_t) +#define CRUS_SP_IOCTL_GET_CALIB32 \ + _IOWR(SPK_PROT_IOCTL_MAGIC, 221, compat_uptr_t) +#define CRUS_SP_IOCTL_SET_CALIB32 \ + _IOWR(SPK_PROT_IOCTL_MAGIC, 222, compat_uptr_t) +#define CRUS_SP_IOCTL_READ_CALIB_FROM_SLOT32 \ + _IOWR(SPK_PROT_IOCTL_MAGIC, 223, compat_uptr_t) +#define CRUS_SP_IOCTL_WRITE_CALIB_TO_SLOT32 \ + _IOWR(SPK_PROT_IOCTL_MAGIC, 224, compat_uptr_t) + +struct crus_sp_ioctl_header { + uint32_t size; + uint32_t module_id; + uint32_t param_id; + uint32_t data_length; + void *data; +}; + +#endif /* _UAPI_MSM_CIRRUS_SPK_PR_H */ From b85b66accf32e9ff2176390e2e6c224aa1f23607 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Thu, 8 Jul 2021 21:06:13 +0200 Subject: [PATCH 101/226] techpack: audio: asoc: codecs: tas256x: Shut up Change-Id: I4beed107b75999e6f909467062bccb0a0e3229eb Signed-off-by: firebird11 --- techpack/audio/asoc/codecs/tas256x/tas256x-codec.c | 1 + techpack/audio/asoc/codecs/tas256x/tas256x-regmap.c | 1 + techpack/audio/asoc/codecs/tas256x/tas25xx-algo.c | 1 + techpack/audio/asoc/codecs/tas256x/tas25xx-calib.c | 1 + techpack/audio/asoc/codecs/tas256x/tas25xx-debug.h | 9 +++++++++ 5 files changed, 13 insertions(+) create mode 100644 techpack/audio/asoc/codecs/tas256x/tas25xx-debug.h diff --git a/techpack/audio/asoc/codecs/tas256x/tas256x-codec.c b/techpack/audio/asoc/codecs/tas256x/tas256x-codec.c index b95e7e03a3ca..6bb7bf9b5966 100644 --- a/techpack/audio/asoc/codecs/tas256x/tas256x-codec.c +++ b/techpack/audio/asoc/codecs/tas256x/tas256x-codec.c @@ -53,6 +53,7 @@ #endif /*CONFIG_PLATFORM_EXYNOS*/ #include "tas25xx-calib.h" #endif /*CONFIG_TAS25XX_ALGO*/ +#include "tas25xx-debug.h" #define TAS256X_MDELAY 0xFFFFFFFE #define TAS256X_MSLEEP 0xFFFFFFFD diff --git a/techpack/audio/asoc/codecs/tas256x/tas256x-regmap.c b/techpack/audio/asoc/codecs/tas256x/tas256x-regmap.c index 02f8090cbf13..4f817d9add70 100644 --- a/techpack/audio/asoc/codecs/tas256x/tas256x-regmap.c +++ b/techpack/audio/asoc/codecs/tas256x/tas256x-regmap.c @@ -42,6 +42,7 @@ #include "tas2564.h" #include "tas256x-device.h" #include "tas256x-codec.h" +#include "tas25xx-debug.h" #ifdef CONFIG_TAS25XX_ALGO #ifdef CONFIG_PLATFORM_EXYNOS diff --git a/techpack/audio/asoc/codecs/tas256x/tas25xx-algo.c b/techpack/audio/asoc/codecs/tas256x/tas25xx-algo.c index 4da82e22090d..90f01be0e431 100644 --- a/techpack/audio/asoc/codecs/tas256x/tas25xx-algo.c +++ b/techpack/audio/asoc/codecs/tas256x/tas25xx-algo.c @@ -4,6 +4,7 @@ #include #include #include "tas25xx-calib.h" +#include "tas25xx-debug.h" #define USE_VFS 1 #define CODEC_CONTROL 1 diff --git a/techpack/audio/asoc/codecs/tas256x/tas25xx-calib.c b/techpack/audio/asoc/codecs/tas256x/tas25xx-calib.c index 862025d74c0b..b1b21f92c75c 100644 --- a/techpack/audio/asoc/codecs/tas256x/tas25xx-calib.c +++ b/techpack/audio/asoc/codecs/tas256x/tas25xx-calib.c @@ -32,6 +32,7 @@ #include #include #include +#include "tas25xx-debug.h" /* Holds the Packet data required for processing */ struct tas_dsp_pkt { diff --git a/techpack/audio/asoc/codecs/tas256x/tas25xx-debug.h b/techpack/audio/asoc/codecs/tas256x/tas25xx-debug.h new file mode 100644 index 000000000000..87a11a717e93 --- /dev/null +++ b/techpack/audio/asoc/codecs/tas256x/tas25xx-debug.h @@ -0,0 +1,9 @@ +//#define DEBUG + +#ifndef DEBUG +#undef dev_info +#undef pr_info + +#define dev_info(...) dev_dbg(__VA_ARGS__) +#define pr_info(...) pr_debug(__VA_ARGS__) +#endif From 5ebd6f21875deed7ed1d144cf95a0ac2541a8e91 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 17 Apr 2024 17:22:40 +0200 Subject: [PATCH 102/226] techpack: audio: asoc: codecs: tfa98xx: Fix includes Change-Id: If34b42dc06c36b9663b8422ee6d2746d4f54b285 Signed-off-by: firebird11 --- techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c | 12 ++++++------ .../audio/asoc/codecs/tfa98xx/src/tfa_container.c | 10 +++++----- techpack/audio/asoc/codecs/tfa98xx/src/tfa_debug.c | 6 +++--- techpack/audio/asoc/codecs/tfa98xx/src/tfa_dsp.c | 10 +++++----- techpack/audio/asoc/codecs/tfa98xx/src/tfa_init.c | 10 +++++----- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c b/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c index f5542c15adb6..f66ad24493fe 100644 --- a/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c +++ b/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c @@ -32,15 +32,15 @@ #include #include #include -#include "config.h" -#include "tfa98xx.h" -#include "tfa.h" -#include "tfa_dsp_fw.h" +#include "../inc/config.h" +#include "../inc/tfa98xx.h" +#include "../inc/tfa.h" +#include "../inc/tfa_dsp_fw.h" /* required for enum tfa9912_irq */ -#include "tfa98xx_tfafieldnames.h" +#include "../inc/tfa98xx_tfafieldnames.h" -#include "spk-id.h" +#include "../inc/spk-id.h" #define TFA98XX_VERSION TFA98XX_API_REV_STR diff --git a/techpack/audio/asoc/codecs/tfa98xx/src/tfa_container.c b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_container.c index 7207069dacc2..284dfa6cbbb0 100644 --- a/techpack/audio/asoc/codecs/tfa98xx/src/tfa_container.c +++ b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_container.c @@ -15,11 +15,11 @@ * limitations under the License. */ -#include "dbgprint.h" -#include "tfa_container.h" -#include "tfa.h" -#include "tfa98xx_tfafieldnames.h" -#include "tfa_internal.h" +#include "../inc/dbgprint.h" +#include "../inc/tfa_container.h" +#include "../inc/tfa.h" +#include "../inc/tfa98xx_tfafieldnames.h" +#include "../inc/tfa_internal.h" /* defines */ #define MODULE_BIQUADFILTERBANK 2 diff --git a/techpack/audio/asoc/codecs/tfa98xx/src/tfa_debug.c b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_debug.c index b02098326cb2..d04309791ded 100644 --- a/techpack/audio/asoc/codecs/tfa98xx/src/tfa_debug.c +++ b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_debug.c @@ -15,9 +15,9 @@ * limitations under the License. */ -#include "dbgprint.h" -#include "tfa_service.h" -#include "tfa98xx_tfafieldnames.h" +#include "../inc/dbgprint.h" +#include "../inc/tfa_service.h" +#include "../inc/tfa98xx_tfafieldnames.h" /* support for error code translation into text */ static char latest_errorstr[64]; diff --git a/techpack/audio/asoc/codecs/tfa98xx/src/tfa_dsp.c b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_dsp.c index eb4045710829..f875e15bddc2 100644 --- a/techpack/audio/asoc/codecs/tfa98xx/src/tfa_dsp.c +++ b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_dsp.c @@ -15,11 +15,11 @@ * limitations under the License. */ -#include "dbgprint.h" -#include "tfa_container.h" -#include "tfa.h" -#include "tfa98xx_tfafieldnames.h" -#include "tfa_internal.h" +#include "../inc/dbgprint.h" +#include "../inc/tfa_container.h" +#include "../inc/tfa.h" +#include "../inc/tfa98xx_tfafieldnames.h" +#include "../inc/tfa_internal.h" #ifdef __KERNEL__ #ifdef pr_fmt diff --git a/techpack/audio/asoc/codecs/tfa98xx/src/tfa_init.c b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_init.c index 8bd5167f889a..164514c91cbb 100644 --- a/techpack/audio/asoc/codecs/tfa98xx/src/tfa_init.c +++ b/techpack/audio/asoc/codecs/tfa98xx/src/tfa_init.c @@ -15,11 +15,11 @@ * limitations under the License. */ -#include "dbgprint.h" -#include "tfa_service.h" -#include "tfa_internal.h" -#include "tfa_container.h" -#include "tfa98xx_tfafieldnames.h" +#include "../inc/dbgprint.h" +#include "../inc/tfa_service.h" +#include "../inc/tfa_internal.h" +#include "../inc/tfa_container.h" +#include "../inc/tfa98xx_tfafieldnames.h" /* The CurrentSense4 registers are not in the datasheet */ #define TFA98XX_CURRENTSENSE4_CTRL_CLKGATECFOFF (1 << 2) From e8bcaae5c315a82243a678ac92976e987bbea6af Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Sun, 9 Jun 2024 19:19:36 +0200 Subject: [PATCH 103/226] techpack: audio: asoc: codecs: tfa98xx: Make it compile without debugfs Change-Id: Ia04686616f8f2b0b5fa5eb810025811970d624d5 Signed-off-by: firebird11 --- .../audio/asoc/codecs/tfa98xx/src/tfa98xx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c b/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c index f66ad24493fe..384d2e54b07a 100644 --- a/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c +++ b/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c @@ -404,6 +404,15 @@ static void tfa98xx_inputdev_unregister(struct tfa98xx *tfa98xx) __tfa98xx_inputdev_check_register(tfa98xx, true); } +#ifdef TFA_NON_DSP_SOLUTION +extern int send_tfa_cal_apr(void *buf, int cmd_size, bool bRead); +#else +int send_tfa_cal_apr(void *buf, int cmd_size, bool bRead) +{ + return 0; +} +#endif + #ifdef CONFIG_DEBUG_FS /* OTC reporting * Returns the MTP0 OTC bit value @@ -765,15 +774,6 @@ static ssize_t tfa98xx_dbgfs_fw_state_get(struct file *file, return simple_read_from_buffer(user_buf, count, ppos, str, strlen(str)); } -#ifdef TFA_NON_DSP_SOLUTION -extern int send_tfa_cal_apr(void *buf, int cmd_size, bool bRead); -#else -int send_tfa_cal_apr(void *buf, int cmd_size, bool bRead) -{ - return 0; -} -#endif - static ssize_t tfa98xx_dbgfs_rpc_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { From 1e5bd8aa016e2512689b89b253638209a6326344 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Sun, 9 Jun 2024 19:21:31 +0200 Subject: [PATCH 104/226] techpack: audio: asoc: codecs: Use spk-id standard driver Change-Id: I4093c026405398b752b183bc4a8639e3eccf49fc Signed-off-by: firebird11 --- techpack/audio/asoc/codecs/cs35l41/cs35l41.c | 28 ---------------- .../audio/asoc/codecs/tas2557/tas2557-core.c | 28 ---------------- .../audio/asoc/codecs/tas2557/tas2557-core.h | 1 - .../asoc/codecs/tas2557/tas2557-regmap.c | 2 +- .../audio/asoc/codecs/tfa98xx/inc/spk-id.h | 33 ------------------- .../audio/asoc/codecs/tfa98xx/src/tfa98xx.c | 2 +- techpack/audio/include/uapi/sound/cs35l41.h | 1 - 7 files changed, 2 insertions(+), 93 deletions(-) delete mode 100644 techpack/audio/asoc/codecs/tfa98xx/inc/spk-id.h diff --git a/techpack/audio/asoc/codecs/cs35l41/cs35l41.c b/techpack/audio/asoc/codecs/cs35l41/cs35l41.c index 47150d81329d..89b542efb9df 100644 --- a/techpack/audio/asoc/codecs/cs35l41/cs35l41.c +++ b/techpack/audio/asoc/codecs/cs35l41/cs35l41.c @@ -1583,34 +1583,6 @@ static struct snd_soc_codec_driver soc_codec_dev_cs35l41 = { .idle_bias_off = true, }; -int spk_id_get(struct device_node *np) -{ - int id; - int state; - - state = spk_id_get_pin_3state(np); - if (state < 0) { - pr_err("%s: Can not get id pin state, %d\n", __func__, state); - return VENDOR_ID_NONE; - } - - switch (state) { - case PIN_PULL_DOWN: - id = VENDOR_ID_AAC; - break; - case PIN_PULL_UP: - id = VENDOR_ID_UNKNOWN; - break; - case PIN_FLOAT: - id = VENDOR_ID_GOER; - break; - default: - id = VENDOR_ID_UNKNOWN; - break; - } - return id; -} - static int cs35l41_handle_of_data(struct device *dev, struct cs35l41_platform_data *pdata) { diff --git a/techpack/audio/asoc/codecs/tas2557/tas2557-core.c b/techpack/audio/asoc/codecs/tas2557/tas2557-core.c index 45f6e9b3264e..5eaa3bdcba49 100644 --- a/techpack/audio/asoc/codecs/tas2557/tas2557-core.c +++ b/techpack/audio/asoc/codecs/tas2557/tas2557-core.c @@ -2309,34 +2309,6 @@ bool tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0) return bFound; } -int spk_id_get(struct device_node *np) -{ - int id; - int state; - - state = spk_id_get_pin_3state(np); - if (state < 0) { - pr_err("%s: Can not get id pin state, %d\n", __func__, state); - return VENDOR_ID_NONE; - } - - switch (state) { - case PIN_PULL_DOWN: - id = VENDOR_ID_AAC; - break; - case PIN_PULL_UP: - id = VENDOR_ID_UNKNOWN; - break; - case PIN_FLOAT: - id = VENDOR_ID_GOER; - break; - default: - id = VENDOR_ID_UNKNOWN; - break; - } - return id; -} - int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557) { struct device_node *np = dev->of_node; diff --git a/techpack/audio/asoc/codecs/tas2557/tas2557-core.h b/techpack/audio/asoc/codecs/tas2557/tas2557-core.h index 95a544f45547..a3e6df6e36f2 100644 --- a/techpack/audio/asoc/codecs/tas2557/tas2557-core.h +++ b/techpack/audio/asoc/codecs/tas2557/tas2557-core.h @@ -81,6 +81,5 @@ int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557); int tas2557_get_DAC_gain(struct tas2557_priv *pTAS2557, unsigned char *pnGain); int tas2557_set_DAC_gain(struct tas2557_priv *pTAS2557, unsigned int nGain); int tas2557_configIRQ(struct tas2557_priv *pTAS2557); -int spk_id_get(struct device_node *np); #endif /* _TAS2557_CORE_H */ diff --git a/techpack/audio/asoc/codecs/tas2557/tas2557-regmap.c b/techpack/audio/asoc/codecs/tas2557/tas2557-regmap.c index 9923660efa97..2f66744d8cfd 100644 --- a/techpack/audio/asoc/codecs/tas2557/tas2557-regmap.c +++ b/techpack/audio/asoc/codecs/tas2557/tas2557-regmap.c @@ -56,7 +56,7 @@ #ifdef ENABLE_TILOAD #include "tiload.h" #endif -#include "../spk-id.h" +#include #define LOW_TEMPERATURE_GAIN 6 #define LOW_TEMPERATURE_COUNTER 12 diff --git a/techpack/audio/asoc/codecs/tfa98xx/inc/spk-id.h b/techpack/audio/asoc/codecs/tfa98xx/inc/spk-id.h deleted file mode 100644 index 8303b93c3498..000000000000 --- a/techpack/audio/asoc/codecs/tfa98xx/inc/spk-id.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. - * Copyright (C) 2019 XiaoMi, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * 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 __SPK_ID_H_ -#define __SPK_ID_H_ - -#include -#include - -#define PIN_PULL_DOWN 0 -#define PIN_PULL_UP 1 -#define PIN_FLOAT 2 - -#define VENDOR_ID_NONE 0 -#define VENDOR_ID_AAC 1 -#define VENDOR_ID_SSI 2 -#define VENDOR_ID_GOER 3 - -#define VENDOR_ID_UNKNOWN 4 - -extern int spk_id_get_pin_3state(struct device_node *np); - -#endif diff --git a/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c b/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c index 384d2e54b07a..d6f094725000 100644 --- a/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c +++ b/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c @@ -40,7 +40,7 @@ /* required for enum tfa9912_irq */ #include "../inc/tfa98xx_tfafieldnames.h" -#include "../inc/spk-id.h" +#include #define TFA98XX_VERSION TFA98XX_API_REV_STR diff --git a/techpack/audio/include/uapi/sound/cs35l41.h b/techpack/audio/include/uapi/sound/cs35l41.h index 39f6df1a17ba..17d02a568dd3 100644 --- a/techpack/audio/include/uapi/sound/cs35l41.h +++ b/techpack/audio/include/uapi/sound/cs35l41.h @@ -80,5 +80,4 @@ struct cs35l41_private { int cs35l41_probe(struct cs35l41_private *cs35l41, struct cs35l41_platform_data *pdata); -int spk_id_get(struct device_node *np); #endif /* __CS35L41_H */ From 9cbd018a8f1ea01d832ca5957ea81e6b397e6310 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Wed, 17 Apr 2024 13:09:41 +0200 Subject: [PATCH 105/226] techpack: audio: Import Xiaomi changes Change-Id: I52e78d6fe17834ffecf5cd269b07b1bd53d9790d Signed-off-by: firebird11 --- techpack/audio/asoc/Kbuild | 8 + techpack/audio/asoc/codecs/bolero/tx-macro.c | 8 + techpack/audio/asoc/codecs/wcd-dsp-mgr.c | 56 ++ techpack/audio/asoc/codecs/wcd-mbhc-adc.c | 36 + techpack/audio/asoc/codecs/wcd-mbhc-v2.c | 243 +++++ techpack/audio/asoc/codecs/wcd-mbhc-v2.h | 37 + techpack/audio/asoc/codecs/wcd-spi.c | 18 + .../audio/asoc/codecs/wcd934x/wcd934x-mbhc.c | 32 + .../audio/asoc/codecs/wcd934x/wcd934x-mbhc.h | 11 + techpack/audio/asoc/codecs/wcd934x/wcd934x.c | 88 ++ techpack/audio/asoc/codecs/wcd937x/internal.h | 3 + techpack/audio/asoc/codecs/wcd937x/wcd937x.c | 14 + .../audio/asoc/codecs/wcd9xxx-common-v2.c | 3 + techpack/audio/asoc/msm-compress-q6-v2.c | 14 + techpack/audio/asoc/msm-dai-fe.c | 66 ++ techpack/audio/asoc/msm-dai-q6-v2.c | 25 + techpack/audio/asoc/msm-pcm-loopback-v2.c | 6 + techpack/audio/asoc/msm-pcm-q6-v2.c | 6 + techpack/audio/asoc/msm-pcm-routing-v2.c | 188 ++++ techpack/audio/asoc/msm-pcm-routing-v2.h | 3 + techpack/audio/asoc/sm8150.c | 557 +++++++++++ techpack/audio/dsp/Kbuild | 8 + techpack/audio/dsp/q6_init.c | 22 + techpack/audio/dsp/q6_init.h | 22 + techpack/audio/dsp/q6adm.c | 180 ++++ techpack/audio/dsp/q6afe.c | 925 ++++++++++++++++++ techpack/audio/dsp/q6asm.c | 8 + techpack/audio/dsp/q6audio-v2.c | 7 + techpack/audio/dsp/q6voice.c | 4 + techpack/audio/include/dsp/apr_audio-v2.h | 5 +- techpack/audio/include/dsp/q6afe-v2.h | 10 + techpack/audio/soc/pinctrl-lpi.c | 5 + techpack/audio/soc/swr-mstr-ctrl.c | 18 + techpack/audio/soc/swr-mstr-ctrl.h | 3 + 34 files changed, 2638 insertions(+), 1 deletion(-) diff --git a/techpack/audio/asoc/Kbuild b/techpack/audio/asoc/Kbuild index 164cce6a2542..c93a95c5cfd7 100644 --- a/techpack/audio/asoc/Kbuild +++ b/techpack/audio/asoc/Kbuild @@ -186,6 +186,14 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -Werror\ -D__linux__ +ifeq (y, $(filter y,$(CONFIG_MACH_XIAOMI_CEPHEUS))) + CDEFINES += -DCONFIG_SND_SOC_CS35L41_FOR_CEPH +endif + +ifeq (y, $(filter y,$(CONFIG_MACH_XIAOMI_RAPHAEL))) + CDEFINES += -DCONFIG_SND_SOC_TFA9874_FOR_DAVI +endif + KBUILD_CPPFLAGS += $(CDEFINES) # Currently, for versions of gcc which support it, the kernel Makefile diff --git a/techpack/audio/asoc/codecs/bolero/tx-macro.c b/techpack/audio/asoc/codecs/bolero/tx-macro.c index 8fc8a2ad23d3..9f9588c89338 100644 --- a/techpack/audio/asoc/codecs/bolero/tx-macro.c +++ b/techpack/audio/asoc/codecs/bolero/tx-macro.c @@ -47,7 +47,11 @@ #define TX_MACRO_SWR_MIC_MUX_SEL_MASK 0xF #define TX_MACRO_ADC_MUX_CFG_OFFSET 0x2 +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define TX_MACRO_TX_UNMUTE_DELAY_MS 150 +#else #define TX_MACRO_TX_UNMUTE_DELAY_MS 40 +#endif static int tx_unmute_delay = TX_MACRO_TX_UNMUTE_DELAY_MS; module_param(tx_unmute_delay, int, 0664); @@ -752,7 +756,11 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, CF_MIN_3DB_150HZ) { schedule_delayed_work( &tx_priv->tx_hpf_work[decimator].dwork, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + msecs_to_jiffies(50)); +#else msecs_to_jiffies(300)); +#endif snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); /* * Minimum 1 clk cycle delay is required as per HW spec diff --git a/techpack/audio/asoc/codecs/wcd-dsp-mgr.c b/techpack/audio/asoc/codecs/wcd-dsp-mgr.c index b45a9b3b7516..4e1312e05699 100644 --- a/techpack/audio/asoc/codecs/wcd-dsp-mgr.c +++ b/techpack/audio/asoc/codecs/wcd-dsp-mgr.c @@ -85,6 +85,9 @@ static char *wdsp_get_cmpnt_type_string(enum wdsp_cmpnt_type); #define WDSP_SSR_STATUS_READY \ (WDSP_SSR_STATUS_WDSP_READY | WDSP_SSR_STATUS_CDC_READY) #define WDSP_SSR_READY_WAIT_TIMEOUT (10 * HZ) +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define WDSP_FW_LOAD_RETRY_COUNT 5 +#endif enum wdsp_ssr_type { @@ -384,6 +387,9 @@ static int wdsp_download_segments(struct wdsp_mgr_priv *wdsp, enum wdsp_event_type pre, post; long status; int ret; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int retry_cnt = 0; +#endif ctl = WDSP_GET_COMPONENT(wdsp, WDSP_CMPNT_CONTROL); @@ -416,7 +422,14 @@ static int wdsp_download_segments(struct wdsp_mgr_priv *wdsp, /* Go through the list of segments and download one by one */ list_for_each_entry(seg, wdsp->seg_list, list) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + retry_cnt = WDSP_FW_LOAD_RETRY_COUNT; + do { +#endif ret = wdsp_load_each_segment(wdsp, seg); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + } while (ret < 0 && --retry_cnt > 0); +#endif if (ret) goto dload_error; } @@ -433,6 +446,12 @@ static int wdsp_download_segments(struct wdsp_mgr_priv *wdsp, dload_error: wdsp_flush_segment_list(wdsp->seg_list); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (type == WDSP_ELF_FLAG_RE) { + wdsp_broadcast_event_downseq(wdsp, post, NULL); + ret = 0; + } else +#endif wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_DLOAD_FAILED, NULL); return ret; } @@ -483,18 +502,40 @@ static void wdsp_load_fw_image(struct work_struct *work) static int wdsp_enable_dsp(struct wdsp_mgr_priv *wdsp) { int ret; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int retry_cnt = WDSP_FW_LOAD_RETRY_COUNT; +#endif + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); +#endif /* Make sure wdsp is in good state */ if (!WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_CODE_DLOADED)) { WDSP_ERR(wdsp, "WDSP in invalid state 0x%x", wdsp->status); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + ret = wdsp_init_and_dload_code_sections(wdsp); + if (ret < 0) { + WDSP_ERR(wdsp, "Retry code dload failed %d", + ret); + goto done; + } +#else return -EINVAL; +#endif } +#ifndef CONFIG_MACH_XIAOMI_SM8150 /* * Acquire SSR mutex lock to make sure enablement of DSP * does not race with SSR handling. */ WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); +#endif + +#ifdef CONFIG_MACH_XIAOMI_SM8150 +retry: +#endif /* Download the read-write sections of image */ ret = wdsp_download_segments(wdsp, WDSP_ELF_FLAG_WRITE); if (ret < 0) { @@ -509,6 +550,17 @@ static int wdsp_enable_dsp(struct wdsp_mgr_priv *wdsp) if (ret < 0) { WDSP_ERR(wdsp, "Failed to boot dsp, err = %d", ret); WDSP_CLEAR_STATUS(wdsp, WDSP_STATUS_DATA_DLOADED); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (retry_cnt-- >= 0) { + ret = wdsp_init_and_dload_code_sections(wdsp); + if (ret < 0) { + WDSP_ERR(wdsp, "Retry code dload failed %d", + ret); + goto done; + } + goto retry; + } +#endif goto done; } @@ -1203,6 +1255,10 @@ static int wdsp_mgr_parse_dt_entries(struct wdsp_mgr_priv *wdsp) return ret; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + wdsp->img_fname = "cpe_intl"; +#endif + ret = of_count_phandle_with_args(dev->of_node, "qcom,wdsp-components", NULL); diff --git a/techpack/audio/asoc/codecs/wcd-mbhc-adc.c b/techpack/audio/asoc/codecs/wcd-mbhc-adc.c index 96d1c8266764..d536aa45cc54 100644 --- a/techpack/audio/asoc/codecs/wcd-mbhc-adc.c +++ b/techpack/audio/asoc/codecs/wcd-mbhc-adc.c @@ -31,10 +31,17 @@ #include "wcd-mbhc-v2.h" #include "pdata.h" +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define WCD_MBHC_ADC_HS_THRESHOLD_MV 2600 +#define WCD_MBHC_ADC_HPH_THRESHOLD_MV 50 +#define WCD_MBHC_ADC_MICBIAS_MV 2700 +#define WCD_MBHC_FAKE_INS_RETRY 4 +#else #define WCD_MBHC_ADC_HS_THRESHOLD_MV 1700 #define WCD_MBHC_ADC_HPH_THRESHOLD_MV 75 #define WCD_MBHC_ADC_MICBIAS_MV 1800 #define WCD_MBHC_FAKE_INS_RETRY 4 +#endif static int wcd_mbhc_get_micbias(struct wcd_mbhc *mbhc) { @@ -503,18 +510,28 @@ static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) static void wcd_mbhc_adc_update_fsm_source(struct wcd_mbhc *mbhc, enum wcd_mbhc_plug_type plug_type) { +#ifndef CONFIG_MACH_XIAOMI_SM8150 bool micbias2; +#endif +#ifndef CONFIG_MACH_XIAOMI_SM8150 micbias2 = mbhc->mbhc_cb->micbias_enable_status(mbhc, MIC_BIAS_2); +#endif switch (plug_type) { case MBHC_PLUG_TYPE_HEADPHONE: WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 3); break; case MBHC_PLUG_TYPE_HEADSET: case MBHC_PLUG_TYPE_ANC_HEADPHONE: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); + mbhc->mbhc_cb->mbhc_micbias_control(mbhc->codec, + MIC_BIAS_2, MICB_PULLUP_ENABLE); +#else if (!mbhc->is_hs_recording && !micbias2) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 3); +#endif break; default: WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); @@ -705,6 +722,16 @@ static void wcd_correct_swch_plug(struct work_struct *work) } msleep(180); + +#ifdef CONFIG_MACH_XIAOMI_NABU + /* In the case of system bootup with headset pluged, mbhc + * begin to detect without sound card registered. delay + * about 150ms to wait sound card registe. + */ + if ((mbhc->mbhc_cfg->swap_gnd_mic == NULL) && (mbhc->mbhc_cfg->enable_usbc_analog)) + msleep(600); +#endif + /* * Use ADC single mode to minimize the chance of missing out * btn press/release for HEADSET type during correct work. @@ -990,8 +1017,13 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) hphpa_on = true; WCD_MBHC_REG_UPDATE_BITS( WCD_MBHC_HPHL_PA_EN, 0); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + WCD_MBHC_REG_UPDATE_BITS( + WCD_MBHC_HPHR_PA_EN, 0); +#else WCD_MBHC_REG_UPDATE_BITS( WCD_MBHC_HPH_PA_EN, 0); +#endif } WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_GND, 1); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_GND, 1); @@ -1035,7 +1067,11 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) if (hphpa_on) { hphpa_on = false; WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_PA_EN, 1); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_PA_EN, 1); +#else WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 1); +#endif } } exit: diff --git a/techpack/audio/asoc/codecs/wcd-mbhc-v2.c b/techpack/audio/asoc/codecs/wcd-mbhc-v2.c index b5e26d7467e2..f0965acf212d 100644 --- a/techpack/audio/asoc/codecs/wcd-mbhc-v2.c +++ b/techpack/audio/asoc/codecs/wcd-mbhc-v2.c @@ -214,7 +214,9 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, struct snd_soc_codec *codec = mbhc->codec; bool micbias2 = false; bool micbias1 = false; +#ifndef CONFIG_MACH_XIAOMI_SM8150 u8 fsm_en = 0; +#endif pr_debug("%s: event %s (%d)\n", __func__, wcd_mbhc_get_event_string(event), event); @@ -256,10 +258,12 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, out_micb_en: /* Disable current source if micbias enabled */ if (mbhc->mbhc_cb->mbhc_micbias_control) { +#ifndef CONFIG_MACH_XIAOMI_SM8150 WCD_MBHC_REG_READ(WCD_MBHC_FSM_EN, fsm_en); if (fsm_en) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); +#endif } else { mbhc->is_hs_recording = true; wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); @@ -269,6 +273,7 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, mbhc->mbhc_cb->set_cap_mode(codec, micbias1, true); break; case WCD_EVENT_PRE_MICBIAS_2_OFF: +#ifndef CONFIG_MACH_XIAOMI_SM8150 /* * Before MICBIAS_2 is turned off, if FSM is enabled, * make sure current source is enabled so as to detect @@ -281,6 +286,7 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 3); } +#endif break; /* MICBIAS usage change */ case WCD_EVENT_POST_DAPM_MICBIAS_2_OFF: @@ -600,6 +606,10 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, mbhc->zl = mbhc->zr = 0; pr_debug("%s: Reporting removal %d(%x)\n", __func__, jack_type, mbhc->hph_status); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (mbhc->mbhc_cb->mbhc_mute_hs_tx && jack_type == SND_JACK_HEADSET) + mbhc->mbhc_cb->mbhc_mute_hs_tx(codec); +#endif wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack, mbhc->hph_status, WCD_MBHC_JACK_MASK); wcd_mbhc_set_and_turnoff_hph_padac(mbhc); @@ -695,6 +705,7 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, &mbhc->zl, &mbhc->zr); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, fsm_en); +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) if ((mbhc->zl > mbhc->mbhc_cfg->linein_th && mbhc->zl < MAX_IMPED) && (mbhc->zr > mbhc->mbhc_cfg->linein_th && @@ -715,6 +726,7 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, pr_debug("%s: Marking jack type as SND_JACK_LINEOUT\n", __func__); } +#endif } /* Do not calculate impedance again for lineout @@ -814,6 +826,11 @@ void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, * Nothing was reported previously * report a headphone or unsupported */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET) + wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADSET); +#endif + wcd_mbhc_report_plug(mbhc, 1, SND_JACK_HEADPHONE); } else if (plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP) { if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) @@ -828,6 +845,11 @@ void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, mbhc->mbhc_fn->wcd_mbhc_detect_anc_plug_type(mbhc); jack_type = SND_JACK_HEADSET; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) + wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADPHONE); +#endif + /* * If Headphone was reported previously, this will * only report the mic line @@ -843,6 +865,10 @@ void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, /* Disable HW FSM and current source */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + mbhc->mbhc_cb->mbhc_micbias_control(mbhc->codec, + MIC_BIAS_2, MICB_PULLUP_DISABLE); +#endif /* Setup for insertion detection */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE, 1); @@ -902,6 +928,10 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) bool micbias1 = false; struct snd_soc_codec *codec = mbhc->codec; enum snd_jack_types jack_type; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct usbc_ana_audio_config *config = + &mbhc->mbhc_cfg->usbc_analog_cfg; +#endif dev_dbg(codec->dev, "%s: enter\n", __func__); WCD_MBHC_RSC_LOCK(mbhc); @@ -973,6 +1003,10 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) /* Disable HW FSM */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + mbhc->mbhc_cb->mbhc_micbias_control(mbhc->codec, + MIC_BIAS_2, MICB_PULLUP_DISABLE); +#endif if (mbhc->mbhc_cb->mbhc_common_micb_ctrl) mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, MBHC_COMMON_MICB_TAIL_CURR, false); @@ -982,6 +1016,9 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) mbhc->btn_press_intr = false; mbhc->is_btn_press = false; +#ifdef CONFIG_MACH_XIAOMI_NABU + mbhc->mbhc_cfg->flip_switch = false; +#endif switch (mbhc->current_plug) { case MBHC_PLUG_TYPE_HEADPHONE: jack_type = SND_JACK_HEADPHONE; @@ -1014,10 +1051,19 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE, 1); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0); mbhc->extn_cable_hph_rem = false; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (config->usbc_en1_gpio_p) { + msm_cdc_pinctrl_select_sleep_state(config->usbc_en1_gpio_p); + } +#endif wcd_mbhc_report_plug(mbhc, 0, jack_type); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (mbhc->mbhc_cfg->enable_usbc_analog) { +#else if (mbhc->mbhc_cfg->enable_usbc_analog && mbhc->mbhc_cfg->fsa_enable) { +#endif WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0); if (mbhc->mbhc_cb->clk_setup) mbhc->mbhc_cb->clk_setup(mbhc->codec, false); @@ -1372,6 +1418,11 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) * by an external source */ if (mbhc->mbhc_cfg->enable_usbc_analog) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + mbhc->hphl_swh = 0; + mbhc->gnd_swh = 0; +#endif + if (mbhc->mbhc_cb->hph_pull_up_control_v2) mbhc->mbhc_cb->hph_pull_up_control_v2(codec, HS_PULLUP_I_OFF); @@ -1394,7 +1445,11 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) * when a non-audio accessory is inserted. L_DET_EN sets to 1 when FSA * I2C driver notifies that ANALOG_AUDIO_ADAPTER is inserted */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (mbhc->mbhc_cfg->enable_usbc_analog) +#else if (mbhc->mbhc_cfg->enable_usbc_analog && mbhc->mbhc_cfg->fsa_enable) +#endif WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0); else WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); @@ -1404,21 +1459,31 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_INSREM_DBNC, 4); } else { /* Insertion debounce set to 96ms */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_INSREM_DBNC, 9); +#else WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_INSREM_DBNC, 6); +#endif } /* Button Debounce set to 16ms */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_DBNC, 2); +#ifndef CONFIG_MACH_XIAOMI_SM8150 /* Enable micbias ramp */ if (mbhc->mbhc_cb->mbhc_micb_ramp_control) mbhc->mbhc_cb->mbhc_micb_ramp_control(codec, true); +#endif /* enable bias */ mbhc->mbhc_cb->mbhc_bias(codec, true); /* enable MBHC clock */ if (mbhc->mbhc_cb->clk_setup) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (mbhc->mbhc_cfg->enable_usbc_analog) +#else if (mbhc->mbhc_cfg->enable_usbc_analog && mbhc->mbhc_cfg->fsa_enable) +#endif mbhc->mbhc_cb->clk_setup(codec, false); else mbhc->mbhc_cb->clk_setup(codec, true); @@ -1624,14 +1689,22 @@ static int wcd_mbhc_usb_c_analog_setup_gpios(struct wcd_mbhc *mbhc, bool active) int rc = 0; struct usbc_ana_audio_config *config = &mbhc->mbhc_cfg->usbc_analog_cfg; +#ifndef CONFIG_MACH_XIAOMI_SM8150 union power_supply_propval pval; +#endif dev_dbg(mbhc->codec->dev, "%s: setting GPIOs active = %d\n", __func__, active); +#ifndef CONFIG_MACH_XIAOMI_SM8150 memset(&pval, 0, sizeof(pval)); +#endif if (active) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MIC_CLAMP_CTL, 2); + mbhc->mbhc_cfg->enable_dual_adc_gpio(mbhc->mbhc_cfg->dual_adc_gpio_node, 0); +#else pval.intval = POWER_SUPPLY_TYPEC_PR_SOURCE; if (power_supply_set_property(mbhc->usb_psy, POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &pval)) @@ -1639,22 +1712,32 @@ static int wcd_mbhc_usb_c_analog_setup_gpios(struct wcd_mbhc *mbhc, bool active) __func__); else mbhc->usbc_force_pr_mode = true; +#endif if (config->usbc_en1_gpio_p) rc = msm_cdc_pinctrl_select_active_state( config->usbc_en1_gpio_p); +#ifndef CONFIG_MACH_XIAOMI_SM8150 if (rc == 0 && config->usbc_en2n_gpio_p) rc = msm_cdc_pinctrl_select_active_state( config->usbc_en2n_gpio_p); +#endif if (rc == 0 && config->usbc_force_gpio_p) rc = msm_cdc_pinctrl_select_active_state( config->usbc_force_gpio_p); mbhc->usbc_mode = POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (mbhc->mbhc_cb->clk_setup) + mbhc->mbhc_cb->clk_setup(mbhc->codec, true); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); +#endif } else { /* no delay is required when disabling GPIOs */ +#ifndef CONFIG_MACH_XIAOMI_SM8150 if (config->usbc_en2n_gpio_p) msm_cdc_pinctrl_select_sleep_state( config->usbc_en2n_gpio_p); +#endif if (config->usbc_en1_gpio_p) msm_cdc_pinctrl_select_sleep_state( config->usbc_en1_gpio_p); @@ -1662,6 +1745,9 @@ static int wcd_mbhc_usb_c_analog_setup_gpios(struct wcd_mbhc *mbhc, bool active) msm_cdc_pinctrl_select_sleep_state( config->usbc_force_gpio_p); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + mbhc->mbhc_cfg->enable_dual_adc_gpio(mbhc->mbhc_cfg->dual_adc_gpio_node, 1); +#else if (mbhc->usbc_force_pr_mode) { pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL; if (power_supply_set_property(mbhc->usb_psy, @@ -1670,7 +1756,13 @@ static int wcd_mbhc_usb_c_analog_setup_gpios(struct wcd_mbhc *mbhc, bool active) __func__); mbhc->usbc_force_pr_mode = false; } +#endif mbhc->usbc_mode = POWER_SUPPLY_TYPEC_NONE; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MIC_CLAMP_CTL, 0); + if (mbhc->mbhc_cfg->swap_gnd_mic) + mbhc->mbhc_cfg->swap_gnd_mic(mbhc->codec, false); +#endif } return rc; @@ -1759,6 +1851,7 @@ static int wcd_mbhc_usb_c_analog_init(struct wcd_mbhc *mbhc) goto err; } +#ifndef CONFIG_MACH_XIAOMI_SM8150 mbhc->psy_nb.notifier_call = wcd_mbhc_usb_c_event_changed; mbhc->psy_nb.priority = 0; ret = power_supply_reg_notifier(&mbhc->psy_nb); @@ -1778,6 +1871,7 @@ static int wcd_mbhc_usb_c_analog_init(struct wcd_mbhc *mbhc) PSY_EVENT_PROP_CHANGED, mbhc->usb_psy); +#endif err: return ret; } @@ -1791,6 +1885,46 @@ static int wcd_mbhc_usb_c_analog_deinit(struct wcd_mbhc *mbhc) return 0; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static int wcd_mbhc_non_usb_c_event_changed(struct notifier_block *nb, + unsigned long evt, void *ptr) +{ + int ret; + union power_supply_propval mode; + struct wcd_mbhc *mbhc = container_of(nb, struct wcd_mbhc, fsa_nb); + + ret = power_supply_get_property(ptr, + POWER_SUPPLY_PROP_TYPEC_MODE, &mode); + + switch (mode.intval) { + case POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER: + dev_err(mbhc->codec->dev, "%s: report Type-C usb headphone\n", __func__); + if (mbhc->usbc_mode == mode.intval) + break; /* filter notifications received before */ + wcd_mbhc_jack_report(mbhc, &mbhc->usb_3_5_jack, + (SND_JACK_HEADSET | SND_JACK_UNSUPPORTED), + WCD_MBHC_JACK_USB_3_5_MASK); + mbhc->usbc_mode = mode.intval; + break; + case POWER_SUPPLY_TYPEC_NONE: + if (mbhc->usbc_mode == mode.intval) + break; /* filter notifications received before */ + if (mbhc->usbc_mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) { + mbhc->usbc_mode = mode.intval - 1; + break; + } + wcd_mbhc_jack_report(mbhc, &mbhc->usb_3_5_jack, 0, + WCD_MBHC_JACK_USB_3_5_MASK); + mbhc->usbc_mode = mode.intval; + break; + default: + break; + } + + return ret; +} +#endif + int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) { int rc = 0; @@ -1798,6 +1932,9 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) struct snd_soc_codec *codec; struct snd_soc_card *card; const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported"; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + const char *fsa4476_dt = "qcom,fsa4476-gpio-support"; +#endif if (!mbhc || !mbhc_cfg) return -EINVAL; @@ -1830,6 +1967,7 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) dev_dbg(mbhc->codec->dev, "%s: usbc analog enabled\n", __func__); mbhc->swap_thr = GND_MIC_USBC_SWAP_THRESHOLD; +#ifndef CONFIG_MACH_XIAOMI_SM8150 mbhc->fsa_np = of_parse_phandle(card->dev->of_node, "fsa4480-i2c-handle", 0); if (mbhc->fsa_np) { @@ -1839,6 +1977,22 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) __func__); mbhc_cfg->fsa_enable = false; +#endif + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + mbhc_cfg->use_fsa4476_gpio = 0; + if (of_find_property(card->dev->of_node, fsa4476_dt, NULL)) { + rc = of_property_read_u32(card->dev->of_node, fsa4476_dt, + &mbhc_cfg->use_fsa4476_gpio); + if (rc != 0) { + dev_dbg(card->dev, + "%s: %s in dt node is missing or false\n", + __func__, fsa4476_dt); + } + } + + if (mbhc_cfg->use_fsa4476_gpio != 0) { +#endif rc = wcd_mbhc_init_gpio(mbhc, mbhc_cfg, "qcom,usbc-analog-en1_gpio", &config->usbc_en1_gpio, @@ -1846,6 +2000,7 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) if (rc) goto err; +#ifndef CONFIG_MACH_XIAOMI_SM8150 rc = wcd_mbhc_init_gpio(mbhc, mbhc_cfg, "qcom,usbc-analog-en2_n_gpio", &config->usbc_en2n_gpio, @@ -1863,6 +2018,7 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) if (rc) goto err; } +#endif dev_dbg(mbhc->codec->dev, "%s: calling usb_c_analog_init\n", __func__); @@ -1872,6 +2028,17 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) rc = EPROBE_DEFER; goto err; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + } else { + mbhc->fsa_np = of_parse_phandle(card->dev->of_node, + "fsa4480-i2c-handle", 0); + if (!mbhc->fsa_np) { + dev_err(card->dev, "%s: fsa4480 i2c node not found\n", + __func__); + rc = -EINVAL; + goto err; + } // git +#endif } } /* Set btn key code */ @@ -1897,14 +2064,62 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) __func__, mbhc->mbhc_fw, mbhc->mbhc_cal); } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (mbhc_cfg->enable_usbc_analog) { + if (mbhc_cfg->use_fsa4476_gpio == 0) { +#else if (mbhc_cfg->enable_usbc_analog && mbhc_cfg->fsa_enable) { +#endif mbhc->fsa_nb.notifier_call = wcd_mbhc_usbc_ana_event_handler; mbhc->fsa_nb.priority = 0; rc = fsa4480_reg_notifier(&mbhc->fsa_nb, mbhc->fsa_np); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + } else { + mbhc->psy_nb.notifier_call = wcd_mbhc_usb_c_event_changed; + mbhc->psy_nb.priority = 0; + rc = power_supply_reg_notifier(&mbhc->psy_nb); + if (rc) { + dev_err(codec->dev, "%s: power supply registration failed\n", + __func__); + goto err; + } + + /* + * as part of the init sequence check if there is a connected + * USB C analog adapter + */ + dev_dbg(mbhc->codec->dev, "%s: verify if USB adapter is already inserted\n", + __func__); + rc = wcd_mbhc_usb_c_event_changed(&mbhc->psy_nb, + PSY_EVENT_PROP_CHANGED, + mbhc->usb_psy); + } // git + } else { + mbhc->fsa_nb.notifier_call = wcd_mbhc_non_usb_c_event_changed; + mbhc->fsa_nb.priority = 0; + rc = power_supply_reg_notifier(&mbhc->fsa_nb); + if (rc) { + dev_err(card->dev, "%s: power supply registration failed\n", + __func__); + goto err; + } // git +#endif } return rc; err: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (config->usbc_en1_gpio > 0) { + dev_dbg(card->dev, "%s free usb en1 gpio %d\n", + __func__, config->usbc_en1_gpio); + gpio_free(config->usbc_en1_gpio); + config->usbc_en1_gpio = 0; + } + if (config->usbc_en1_gpio_p) + of_node_put(config->usbc_en1_gpio_p); + if (config->usbc_force_gpio_p) + of_node_put(config->usbc_force_gpio_p); +#endif dev_dbg(mbhc->codec->dev, "%s: leave %d\n", __func__, rc); return rc; } @@ -1941,24 +2156,42 @@ void wcd_mbhc_stop(struct wcd_mbhc *mbhc) } if (mbhc->mbhc_cfg->enable_usbc_analog) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (mbhc->mbhc_cfg->use_fsa4476_gpio == 0) { +#else if (mbhc->mbhc_cfg->fsa_enable) { +#endif fsa4480_unreg_notifier(&mbhc->fsa_nb, mbhc->fsa_np); } else { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + } +#endif wcd_mbhc_usb_c_analog_deinit(mbhc); /* free GPIOs */ if (config->usbc_en1_gpio > 0) gpio_free(config->usbc_en1_gpio); +#ifndef CONFIG_MACH_XIAOMI_SM8150 if (config->usbc_en2n_gpio > 0) gpio_free(config->usbc_en2n_gpio); if (config->usbc_force_gpio) gpio_free(config->usbc_force_gpio); +#endif if (config->usbc_en1_gpio_p) of_node_put(config->usbc_en1_gpio_p); +#ifndef CONFIG_MACH_XIAOMI_SM8150 if (config->usbc_en2n_gpio_p) of_node_put(config->usbc_en2n_gpio_p); if (config->usbc_force_gpio_p) of_node_put(config->usbc_force_gpio_p); +#endif +#ifndef CONFIG_MACH_XIAOMI_SM8150 } +#endif +#ifdef CONFIG_MACH_XIAOMI_SM8150 + } else { + if (mbhc->fsa_nb.notifier_call != NULL) + power_supply_unreg_notifier(&mbhc->fsa_nb); +#endif } @@ -2096,6 +2329,16 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, return ret; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + ret = snd_soc_card_jack_new(codec->component.card, + "USB_3_5 Jack", WCD_MBHC_JACK_USB_3_5_MASK, + &mbhc->usb_3_5_jack, NULL, 0); + if (ret) { + pr_err("%s: Failed to create new jack USB_3_5 Jack\n", __func__); + return ret; + } +#endif + INIT_DELAYED_WORK(&mbhc->mbhc_firmware_dwork, wcd_mbhc_fw_read); INIT_DELAYED_WORK(&mbhc->mbhc_btn_dwork, wcd_btn_lpress_fn); diff --git a/techpack/audio/asoc/codecs/wcd-mbhc-v2.h b/techpack/audio/asoc/codecs/wcd-mbhc-v2.h index 6be73e220265..9a449e2c942e 100644 --- a/techpack/audio/asoc/codecs/wcd-mbhc-v2.h +++ b/techpack/audio/asoc/codecs/wcd-mbhc-v2.h @@ -137,12 +137,25 @@ do { \ #define WCD_MBHC_JACK_BUTTON_MASK (SND_JACK_BTN_0 | SND_JACK_BTN_1 | \ SND_JACK_BTN_2 | SND_JACK_BTN_3 | \ SND_JACK_BTN_4 | SND_JACK_BTN_5) + +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define WCD_MBHC_JACK_USB_3_5_MASK (SND_JACK_UNSUPPORTED | SND_JACK_HEADSET) +#endif + #define OCP_ATTEMPT 20 +#ifdef CONFIG_MACH_XIAOMI_NABU +#define HS_DETECT_PLUG_TIME_MS (3 * 1200) +#else #define HS_DETECT_PLUG_TIME_MS (3 * 1000) +#endif #define SPECIAL_HS_DETECT_TIME_MS (2 * 1000) #define MBHC_BUTTON_PRESS_THRESHOLD_MIN 250 #define GND_MIC_SWAP_THRESHOLD 4 +#ifdef CONFIG_MACH_XIAOMI_NABU +#define GND_MIC_USBC_SWAP_THRESHOLD 4 +#else #define GND_MIC_USBC_SWAP_THRESHOLD 2 +#endif #define WCD_FAKE_REMOVAL_MIN_PERIOD_MS 100 #define HS_VREF_MIN_VAL 1400 #define FW_READ_ATTEMPTS 15 @@ -420,9 +433,19 @@ struct usbc_ana_audio_config { int usbc_en1_gpio; int usbc_en2n_gpio; int usbc_force_gpio; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int euro_us_hw_switch_gpio; + int uart_audio_switch_gpio; + int subpcb_id_gpio; +#endif struct device_node *usbc_en1_gpio_p; /* used by pinctrl API */ struct device_node *usbc_en2n_gpio_p; /* used by pinctrl API */ struct device_node *usbc_force_gpio_p; /* used by pinctrl API */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct device_node *euro_us_hw_switch_gpio_p; /* used by pinctrl API */ + struct device_node *uart_audio_switch_gpio_p; /* used by pinctrl API */ + struct device_node *subpcb_id_gpio_p; /* used by pinctrl API */ +#endif }; enum mbhc_moisture_rref { @@ -449,7 +472,15 @@ struct wcd_mbhc_config { u32 enable_usbc_analog; bool moisture_duty_cycle_en; struct usbc_ana_audio_config usbc_analog_cfg; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + u32 use_fsa4476_gpio; + void (*enable_dual_adc_gpio)(struct device_node *node, bool en); + struct device_node *dual_adc_gpio_node; +#endif bool fsa_enable; +#ifdef CONFIG_MACH_XIAOMI_NABU + bool flip_switch; +#endif }; struct wcd_mbhc_intr { @@ -520,6 +551,9 @@ struct wcd_mbhc_cb { bool (*mbhc_get_moisture_status)(struct wcd_mbhc *); void (*mbhc_moisture_polling_ctrl)(struct wcd_mbhc *, bool); void (*mbhc_moisture_detect_en)(struct wcd_mbhc *, bool); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + void (*mbhc_mute_hs_tx)(struct snd_soc_codec *); +#endif }; struct wcd_mbhc_fn { @@ -587,6 +621,9 @@ struct wcd_mbhc { struct snd_soc_jack headset_jack; struct snd_soc_jack button_jack; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct snd_soc_jack usb_3_5_jack; +#endif struct mutex codec_resource_lock; /* Holds codec specific interrupt mapping */ diff --git a/techpack/audio/asoc/codecs/wcd-spi.c b/techpack/audio/asoc/codecs/wcd-spi.c index 7a56d6fdbc69..afb3550641ff 100644 --- a/techpack/audio/asoc/codecs/wcd-spi.c +++ b/techpack/audio/asoc/codecs/wcd-spi.c @@ -1045,6 +1045,15 @@ static int wcd_spi_bus_gwrite(void *context, const void *reg, return -EINVAL; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (wcd_spi_is_suspended(wcd_spi)) { + dev_err(&spi->dev, + "%s: SPI suspended, cannot enable clk\n", + __func__); + return -EIO; + } +#endif + memset(tx_buf, 0, WCD_SPI_CMD_IRW_LEN); tx_buf[0] = WCD_SPI_CMD_IRW; tx_buf[1] = *((u8 *)reg); @@ -1094,6 +1103,15 @@ static int wcd_spi_bus_read(void *context, const void *reg, return -EINVAL; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (wcd_spi_is_suspended(wcd_spi)) { + dev_err(&spi->dev, + "%s: SPI suspended, cannot enable clk\n", + __func__); + return -EIO; + } +#endif + memset(tx_buf, 0, WCD_SPI_CMD_IRR_LEN); tx_buf[0] = WCD_SPI_CMD_IRR; tx_buf[1] = *((u8 *)reg); diff --git a/techpack/audio/asoc/codecs/wcd934x/wcd934x-mbhc.c b/techpack/audio/asoc/codecs/wcd934x/wcd934x-mbhc.c index 3aa8fe7aea1c..adbd94852973 100644 --- a/techpack/audio/asoc/codecs/wcd934x/wcd934x-mbhc.c +++ b/techpack/audio/asoc/codecs/wcd934x/wcd934x-mbhc.c @@ -863,6 +863,13 @@ static bool tavil_is_anc_on(struct wcd_mbhc *mbhc) return anc_on; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static void tavil_mute_hs_tx(struct snd_soc_codec *codec) +{ + snd_soc_update_bits(codec, WCD934X_CDC_TX0_TX_PATH_CTL, 0x10, 0x10); +} +#endif + static const struct wcd_mbhc_cb mbhc_cb = { .request_irq = tavil_mbhc_request_irq, .irq_control = tavil_mbhc_irq_control, @@ -888,6 +895,9 @@ static const struct wcd_mbhc_cb mbhc_cb = { .hph_register_recovery = tavil_hph_register_recovery, .update_anc_state = tavil_update_anc_state, .is_anc_on = tavil_is_anc_on, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + .mbhc_mute_hs_tx = tavil_mute_hs_tx, +#endif }; static struct regulator *tavil_codec_find_ondemand_regulator( @@ -987,6 +997,28 @@ int tavil_mbhc_get_impedance(struct wcd934x_mbhc *wcd934x_mbhc, } EXPORT_SYMBOL(tavil_mbhc_get_impedance); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int tavil_mb_pull_down(struct snd_soc_codec *codec, bool active, + int value) +{ + int oldv = 0; + + if (active) { + oldv = snd_soc_read(codec, WCD934X_ANA_MICB2); + snd_soc_update_bits(codec, WCD934X_ANA_MBHC_ELECT, + 0x80, 0x00); + snd_soc_update_bits(codec, WCD934X_ANA_MICB2, 0xC0, 0xC0); + } else { + snd_soc_write(codec, WCD934X_ANA_MICB2, value); + snd_soc_update_bits(codec, WCD934X_ANA_MBHC_ELECT, + 0x80, 0x80); + } + + return oldv; +} +EXPORT_SYMBOL(tavil_mb_pull_down); +#endif + /* * tavil_mbhc_hs_detect: starts mbhc insertion/removal functionality * @codec: handle to snd_soc_codec * diff --git a/techpack/audio/asoc/codecs/wcd934x/wcd934x-mbhc.h b/techpack/audio/asoc/codecs/wcd934x/wcd934x-mbhc.h index 53c886da0f6b..cde9799b9c4b 100644 --- a/techpack/audio/asoc/codecs/wcd934x/wcd934x-mbhc.h +++ b/techpack/audio/asoc/codecs/wcd934x/wcd934x-mbhc.h @@ -47,6 +47,10 @@ extern int tavil_mbhc_post_ssr_init(struct wcd934x_mbhc *mbhc, struct snd_soc_codec *codec); extern int tavil_mbhc_get_impedance(struct wcd934x_mbhc *wcd934x_mbhc, uint32_t *zl, uint32_t *zr); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +extern int tavil_mb_pull_down(struct snd_soc_codec *codec, bool active, + int value); +#endif #else static inline int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, struct snd_soc_codec *codec, @@ -79,6 +83,13 @@ static inline int tavil_mbhc_get_impedance(struct wcd934x_mbhc *wcd934x_mbhc, *zr = 0; return -EINVAL; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static inline int tavil_mb_pull_down(struct snd_soc_codec *codec, bool active, + int value) +{ + return 0; +} +#endif #endif #endif /* __WCD934X_MBHC_H__ */ diff --git a/techpack/audio/asoc/codecs/wcd934x/wcd934x.c b/techpack/audio/asoc/codecs/wcd934x/wcd934x.c index aae438092a4c..16741c570fe9 100644 --- a/techpack/audio/asoc/codecs/wcd934x/wcd934x.c +++ b/techpack/audio/asoc/codecs/wcd934x/wcd934x.c @@ -644,6 +644,9 @@ struct tavil_priv { struct platform_device *pdev_child_devices [WCD934X_CHILD_DEVICES_MAX]; int child_count; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int micbias_num; +#endif struct regulator *micb_load; int micb_load_low; int micb_load_high; @@ -5674,10 +5677,28 @@ static int tavil_compander_put(struct snd_kcontrol *kcontrol, /* Set Gain Source Select based on compander enable/disable */ snd_soc_update_bits(codec, WCD934X_HPH_L_EN, 0x20, (value ? 0x00:0x20)); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* Disable Compander Clock */ + snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CFG0, 0x02, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_COMPANDER1_CTL0, 0x04, 0x04); + snd_soc_update_bits(codec, WCD934X_CDC_COMPANDER1_CTL0, 0x02, 0x02); + snd_soc_update_bits(codec, WCD934X_CDC_COMPANDER1_CTL0, 0x02, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_COMPANDER1_CTL0, 0x01, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_COMPANDER1_CTL0, 0x04, 0x00); +#endif break; case COMPANDER_2: snd_soc_update_bits(codec, WCD934X_HPH_R_EN, 0x20, (value ? 0x00:0x20)); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + /* Disable Compander Clock */ + snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_CFG0, 0x02, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_COMPANDER2_CTL0, 0x04, 0x04); + snd_soc_update_bits(codec, WCD934X_CDC_COMPANDER2_CTL0, 0x02, 0x02); + snd_soc_update_bits(codec, WCD934X_CDC_COMPANDER2_CTL0, 0x02, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_COMPANDER2_CTL0, 0x01, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_COMPANDER2_CTL0, 0x04, 0x00); +#endif break; case COMPANDER_3: case COMPANDER_4: @@ -6025,6 +6046,60 @@ static int tavil_mad_input_put(struct snd_kcontrol *kcontrol, return 0; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static const char *const tavil_micbias_text[] = { + "OFF", "MICBIAS1", "MICBIAS2", "MICBIAS3", "MICBIAS4" +}; + +static const struct soc_enum tavil_micbias_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tavil_micbias_text), + tavil_micbias_text); + +static int tavil_micb_status_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *priv = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = priv->micbias_num;; + + return 0; +} + +static int tavil_micb_status_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *priv = snd_soc_codec_get_drvdata(codec); + u8 tavil_micbias_num; + + tavil_micbias_num = ucontrol->value.integer.value[0]; + + if (tavil_micbias_num >= sizeof(tavil_micbias_text)/ + sizeof(tavil_micbias_text[0])) { + dev_err(codec->dev, + "%s: tavil_micbias_num = %d out of bounds\n", + __func__, tavil_micbias_num); + return -EINVAL; + } + priv->micbias_num = tavil_micbias_num; + + if (tavil_micbias_num == 0) { + tavil_codec_enable_standalone_micbias(codec, 1, false); + tavil_codec_enable_standalone_micbias(codec, 2, false); + tavil_codec_enable_standalone_micbias(codec, 3, false); + tavil_codec_enable_standalone_micbias(codec, 4, false); + dev_err(codec->dev, "====>PFT: %s: turn off all micbias.\n", __func__); + } else { + tavil_codec_enable_standalone_micbias(codec, tavil_micbias_num, true); + dev_err(codec->dev, "====>PFT: %s: turn on micbias %d.\n", + __func__, tavil_micbias_num); + } + + return 0; +} +#endif + static int tavil_ear_pa_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -6328,8 +6403,13 @@ static const struct snd_kcontrol_new tavil_snd_controls[] = { SOC_ENUM_EXT("SPKR Right Boost Max State", tavil_spkr_boost_stage_enum, tavil_spkr_right_boost_stage_get, tavil_spkr_right_boost_stage_put), +#ifdef CONFIG_MACH_XIAOMI_SM8150 + SOC_SINGLE_TLV("HPHL Volume", WCD934X_HPH_L_EN, 0, 24, 1, line_gain), + SOC_SINGLE_TLV("HPHR Volume", WCD934X_HPH_R_EN, 0, 24, 1, line_gain), +#else SOC_SINGLE_TLV("HPHL Volume", WCD934X_HPH_L_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("HPHR Volume", WCD934X_HPH_R_EN, 0, 20, 1, line_gain), +#endif SOC_SINGLE_TLV("LINEOUT1 Volume", WCD934X_DIFF_LO_LO1_COMPANDER, 3, 16, 1, line_gain), SOC_SINGLE_TLV("LINEOUT2 Volume", WCD934X_DIFF_LO_LO2_COMPANDER, @@ -6524,6 +6604,11 @@ static const struct snd_kcontrol_new tavil_snd_controls[] = { SOC_ENUM_EXT("MAD Input", tavil_conn_mad_enum, tavil_mad_input_get, tavil_mad_input_put), +#ifdef CONFIG_MACH_XIAOMI_SM8150 + SOC_ENUM_EXT("Mic Bias", tavil_micbias_enum, + tavil_micb_status_get, tavil_micb_status_put), +#endif + SOC_SINGLE_EXT("DMIC1_CLK_PIN_MODE", SND_SOC_NOPM, 17, 1, 0, tavil_dmic_pin_mode_get, tavil_dmic_pin_mode_put), @@ -11145,6 +11230,9 @@ static int tavil_probe(struct platform_device *pdev) tavil->swr.plat_data.clk = tavil_swrm_clock; tavil->swr.plat_data.handle_irq = tavil_swrm_handle_irq; tavil->swr.spkr_gain_offset = WCD934X_RX_GAIN_OFFSET_0_DB; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + tavil->micbias_num = 0; +#endif /* Register for Clock */ wcd_ext_clk = clk_get(tavil->wcd9xxx->dev, "wcd_clk"); diff --git a/techpack/audio/asoc/codecs/wcd937x/internal.h b/techpack/audio/asoc/codecs/wcd937x/internal.h index bc335a565ed3..c6f524231b1c 100644 --- a/techpack/audio/asoc/codecs/wcd937x/internal.h +++ b/techpack/audio/asoc/codecs/wcd937x/internal.h @@ -92,6 +92,9 @@ struct wcd937x_priv { struct snd_info_entry *version_entry; /*Entry for Variant info*/ struct snd_info_entry *variant_entry; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int ear_rx_path; +#endif int ana_clk_count; struct mutex ana_tx_clk_lock; }; diff --git a/techpack/audio/asoc/codecs/wcd937x/wcd937x.c b/techpack/audio/asoc/codecs/wcd937x/wcd937x.c index 64a48e34a5f0..7ea1f1b2b6bd 100644 --- a/techpack/audio/asoc/codecs/wcd937x/wcd937x.c +++ b/techpack/audio/asoc/codecs/wcd937x/wcd937x.c @@ -1248,6 +1248,9 @@ static int wcd937x_enable_req(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_REQ_CTL, 0x01, 0x00); snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x40, 0x40); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + snd_soc_update_bits(codec, WCD937X_ANA_TX_CH3, 0x40, 0x40); +#endif snd_soc_update_bits(codec, WCD937X_ANA_TX_CH3_HPF, 0x40, 0x40); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x70, 0x70); @@ -1255,11 +1258,17 @@ static int wcd937x_enable_req(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x40, 0x00); snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x80, 0x80); snd_soc_update_bits(codec, WCD937X_ANA_TX_CH3, 0x80, 0x80); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + snd_soc_update_bits(codec, WCD937X_ANA_TX_CH3_HPF, 0x80, 0x80); +#endif break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, WCD937X_ANA_TX_CH1, 0x80, 0x00); snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x80, 0x00); snd_soc_update_bits(codec, WCD937X_ANA_TX_CH3, 0x80, 0x00); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + snd_soc_update_bits(codec, WCD937X_ANA_TX_CH3_HPF, 0x80, 0x00); +#endif snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x10, 0x00); mutex_lock(&wcd937x->ana_tx_clk_lock); @@ -1716,8 +1725,13 @@ static const struct snd_kcontrol_new wcd937x_snd_controls[] = { SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0, wcd937x_get_compander, wcd937x_set_compander), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + SOC_SINGLE_TLV("HPHL Volume", WCD937X_HPH_L_EN, 0, 24, 1, line_gain), + SOC_SINGLE_TLV("HPHR Volume", WCD937X_HPH_R_EN, 0, 24, 1, line_gain), +#else SOC_SINGLE_TLV("HPHL Volume", WCD937X_HPH_L_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("HPHR Volume", WCD937X_HPH_R_EN, 0, 20, 1, line_gain), +#endif SOC_SINGLE_TLV("ADC1 Volume", WCD937X_ANA_TX_CH1, 0, 20, 0, analog_gain), SOC_SINGLE_TLV("ADC2 Volume", WCD937X_ANA_TX_CH2, 0, 20, 0, analog_gain), SOC_SINGLE_TLV("ADC3 Volume", WCD937X_ANA_TX_CH3, 0, 20, 0, analog_gain), diff --git a/techpack/audio/asoc/codecs/wcd9xxx-common-v2.c b/techpack/audio/asoc/codecs/wcd9xxx-common-v2.c index 478c0c6d72e6..1b5ea88b5485 100644 --- a/techpack/audio/asoc/codecs/wcd9xxx-common-v2.c +++ b/techpack/audio/asoc/codecs/wcd9xxx-common-v2.c @@ -794,6 +794,9 @@ static void wcd_clsh_state_hph_ear(struct snd_soc_codec *codec, wcd_clsh_set_gain_path(codec, mode); wcd_clsh_set_flyback_mode(codec, mode); wcd_clsh_set_buck_mode(codec, mode); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + wcd_clsh_set_hph_mode(codec, mode); +#endif } } else { if (req_state == WCD_CLSH_STATE_EAR) { diff --git a/techpack/audio/asoc/msm-compress-q6-v2.c b/techpack/audio/asoc/msm-compress-q6-v2.c index 26731e180d20..26aaa85e3b8b 100644 --- a/techpack/audio/asoc/msm-compress-q6-v2.c +++ b/techpack/audio/asoc/msm-compress-q6-v2.c @@ -1291,7 +1291,11 @@ static int msm_compr_configure_dsp_for_playback struct snd_compr_runtime *runtime = cstream->runtime; struct msm_compr_audio *prtd = runtime->private_data; struct snd_soc_pcm_runtime *soc_prtd = cstream->private_data; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + uint16_t bits_per_sample = 24; +#else uint16_t bits_per_sample = 16; +#endif int dir = IN, ret = 0; struct audio_client *ac = prtd->audio_client; uint32_t stream_index; @@ -2253,7 +2257,11 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) unsigned long flags; int stream_id; uint32_t stream_index; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + uint16_t bits_per_sample = 24; +#else uint16_t bits_per_sample = 16; +#endif spin_lock_irqsave(&prtd->lock, flags); if (atomic_read(&prtd->error)) { @@ -3615,6 +3623,9 @@ static int msm_compr_playback_app_type_cfg_put(struct snd_kcontrol *kcontrol, cfg_data.acdb_dev_id = ucontrol->value.integer.value[1]; if (ucontrol->value.integer.value[2] != 0) cfg_data.sample_rate = ucontrol->value.integer.value[2]; +#ifdef CONFIG_MACH_XIAOMI_NABU + cfg_data.channel = ucontrol->value.integer.value[4]; +#endif pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", __func__, fe_id, session_type, be_id, cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); @@ -3648,6 +3659,9 @@ static int msm_compr_playback_app_type_cfg_get(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id; ucontrol->value.integer.value[2] = cfg_data.sample_rate; ucontrol->value.integer.value[3] = be_id; +#ifdef CONFIG_MACH_XIAOMI_NABU + ucontrol->value.integer.value[4] = cfg_data.channel; +#endif pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", __func__, fe_id, session_type, be_id, cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); diff --git a/techpack/audio/asoc/msm-dai-fe.c b/techpack/audio/asoc/msm-dai-fe.c index 8020929f680a..b330bcf81a12 100644 --- a/techpack/audio/asoc/msm-dai-fe.c +++ b/techpack/audio/asoc/msm-dai-fe.c @@ -575,6 +575,54 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "CDC_DMA_HOSTLESS", .probe = fe_dai_probe, }, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + { + .playback = { + .stream_name = "ULTRAOUND_HOSTLESS Playback", + .aif_name = "RX1_CDC_DMA_DL_US", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .channels_min = 1, + .channels_max = 4, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "CDC_DMA_HOSTLESS_USRX", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "ULTRAOUND_HOSTLESS Capture", + .aif_name = "TX4_CDC_DMA_UL_US", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "CDC_DMA_HOSTLESS_USTX", + .probe = fe_dai_probe, + }, +#endif { .capture = { .stream_name = "TX3_CDC_DMA_HOSTLESS Capture", @@ -863,6 +911,9 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .aif_name = "PRI_MI2S_UL_HL", .rates = SNDRV_PCM_RATE_8000_48000, .formats = (SNDRV_PCM_FMTBIT_S16_LE | +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + SNDRV_PCM_FMTBIT_S24_3LE | +#endif SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, .channels_max = 2, @@ -879,6 +930,9 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .aif_name = "PRI_MI2S_DL_HL", .rates = SNDRV_PCM_RATE_8000_384000, .formats = (SNDRV_PCM_FMTBIT_S16_LE | +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + SNDRV_PCM_FMTBIT_S24_3LE | +#endif SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, .channels_max = 2, @@ -927,6 +981,9 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .aif_name = "TERT_MI2S_UL_HL", .rates = SNDRV_PCM_RATE_8000_48000, .formats = (SNDRV_PCM_FMTBIT_S16_LE | +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + SNDRV_PCM_FMTBIT_S24_3LE | +#endif SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, .channels_max = 2, @@ -943,6 +1000,9 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .aif_name = "TERT_MI2S_DL_HL", .rates = SNDRV_PCM_RATE_8000_384000, .formats = SNDRV_PCM_FMTBIT_S16_LE | +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + SNDRV_PCM_FMTBIT_S24_3LE | +#endif SNDRV_PCM_FMTBIT_S24_LE, .channels_min = 1, .channels_max = 2, @@ -959,6 +1019,9 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .aif_name = "QUAT_MI2S_UL_HL", .rates = SNDRV_PCM_RATE_8000_48000, .formats = (SNDRV_PCM_FMTBIT_S16_LE | +#ifdef CONFIG_MACH_XIAOMI_SM8150 + SNDRV_PCM_FMTBIT_S24_3LE | +#endif SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, .channels_max = 2, @@ -975,6 +1038,9 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .aif_name = "QUAT_MI2S_DL_HL", .rates = SNDRV_PCM_RATE_8000_384000, .formats = SNDRV_PCM_FMTBIT_S16_LE | +#ifdef CONFIG_MACH_XIAOMI_SM8150 + SNDRV_PCM_FMTBIT_S24_3LE | +#endif SNDRV_PCM_FMTBIT_S24_LE, .channels_min = 1, .channels_max = 8, diff --git a/techpack/audio/asoc/msm-dai-q6-v2.c b/techpack/audio/asoc/msm-dai-q6-v2.c index 7aae0dbe83f5..f314c860b225 100644 --- a/techpack/audio/asoc/msm-dai-q6-v2.c +++ b/techpack/audio/asoc/msm-dai-q6-v2.c @@ -28,6 +28,9 @@ #include #include "msm-dai-q6-v2.h" #include "codecs/core.h" +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI +#include "codecs/tfa98xx/inc/tfa_platform_interface_definition.h" +#endif #define MSM_DAI_PRI_AUXPCM_DT_DEV_ID 1 #define MSM_DAI_SEC_AUXPCM_DT_DEV_ID 2 @@ -5057,6 +5060,18 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, &mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai); struct msm_dai_q6_dai_data *dai_data = &mi2s_dai_config->mi2s_dai_data; struct afe_param_id_i2s_cfg *i2s = &dai_data->port_config.i2s; +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + u16 port_id = 0; +#endif + +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + if (msm_mi2s_get_port_id(dai->id, substream->stream, + &port_id) != 0) { + dev_err(dai->dev, "%s: Invalid Port ID 0x%x\n", + __func__, port_id); + return -EINVAL; + } +#endif dai_data->channels = params_channels(params); switch (dai_data->channels) { @@ -5243,6 +5258,12 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask) && test_bit(STATUS_PORT_STARTED, mi2s_dai_data->tx_dai.mi2s_dai_data.hwfree_status))) { +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + if (AFE_PORT_ID_TFADSP_RX == port_id || + AFE_PORT_ID_TFADSP_TX == port_id) { + dev_dbg(dai->dev, "%s, port_id = 0x%x\n", __func__, port_id); + } else +#endif if ((mi2s_dai_data->tx_dai.mi2s_dai_data.rate != mi2s_dai_data->rx_dai.mi2s_dai_data.rate) || (mi2s_dai_data->rx_dai.mi2s_dai_data.bitwidth != @@ -8309,7 +8330,11 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream, * if only one port, don't do group enable as there * is no group need for only one port */ +#ifdef CONFIG_MACH_XIAOMI_NABU + if (dai_data->num_group_ports >= 1) { +#else if (dai_data->num_group_ports > 1) { +#endif rc = afe_port_group_enable(group_id, &dai_data->group_cfg, true); if (rc < 0) { diff --git a/techpack/audio/asoc/msm-pcm-loopback-v2.c b/techpack/audio/asoc/msm-pcm-loopback-v2.c index aa2d8faf0c4f..fca810529788 100644 --- a/techpack/audio/asoc/msm-pcm-loopback-v2.c +++ b/techpack/audio/asoc/msm-pcm-loopback-v2.c @@ -596,6 +596,9 @@ static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, cfg_data.acdb_dev_id = ucontrol->value.integer.value[1]; if (ucontrol->value.integer.value[2] != 0) cfg_data.sample_rate = ucontrol->value.integer.value[2]; +#ifdef CONFIG_MACH_XIAOMI_NABU + cfg_data.channel = ucontrol->value.integer.value[4]; +#endif pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", __func__, fe_id, session_type, be_id, cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); @@ -629,6 +632,9 @@ static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id; ucontrol->value.integer.value[2] = cfg_data.sample_rate; ucontrol->value.integer.value[3] = be_id; +#ifdef CONFIG_MACH_XIAOMI_NABU + ucontrol->value.integer.value[4] = cfg_data.channel; +#endif pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", __func__, fe_id, session_type, be_id, cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); diff --git a/techpack/audio/asoc/msm-pcm-q6-v2.c b/techpack/audio/asoc/msm-pcm-q6-v2.c index e18c88296b0a..972bec329e03 100644 --- a/techpack/audio/asoc/msm-pcm-q6-v2.c +++ b/techpack/audio/asoc/msm-pcm-q6-v2.c @@ -1792,6 +1792,9 @@ static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, cfg_data.acdb_dev_id = ucontrol->value.integer.value[1]; if (ucontrol->value.integer.value[2] != 0) cfg_data.sample_rate = ucontrol->value.integer.value[2]; +#ifdef CONFIG_MACH_XIAOMI_NABU + cfg_data.channel = ucontrol->value.integer.value[4]; +#endif pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", __func__, fe_id, session_type, be_id, cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); @@ -1825,6 +1828,9 @@ static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id; ucontrol->value.integer.value[2] = cfg_data.sample_rate; ucontrol->value.integer.value[3] = be_id; +#ifdef CONFIG_MACH_XIAOMI_NABU + ucontrol->value.integer.value[4] = cfg_data.channel; +#endif pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", __func__, fe_id, session_type, be_id, cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); diff --git a/techpack/audio/asoc/msm-pcm-routing-v2.c b/techpack/audio/asoc/msm-pcm-routing-v2.c index 10f81d246168..28cbaa899fc7 100644 --- a/techpack/audio/asoc/msm-pcm-routing-v2.c +++ b/techpack/audio/asoc/msm-pcm-routing-v2.c @@ -39,12 +39,33 @@ #include #include #include +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#include +#include +#endif +/* for mius start */ +#ifdef CONFIG_US_PROXIMITY +#include +#include +#endif +/* for mius end */ #include "msm-pcm-routing-v2.h" #include "msm-pcm-routing-devdep.h" #include "msm-qti-pp-config.h" #include "msm-dolby-dap-config.h" #include "msm-ds2-dap-config.h" +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI +#include "codecs/tfa98xx/inc/tfa_platform_interface_definition.h" +#endif + +#ifdef CONFIG_MSM_CSPL +#include +#endif + +#ifdef CONFIG_MSM_CSPL_V2 +#include +#endif #ifndef CONFIG_DOLBY_DAP #undef DOLBY_ADM_COPP_TOPOLOGY_ID @@ -85,6 +106,10 @@ static int msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE; static int msm_ec_ref_sampling_rate = 48000; static uint32_t voc_session_id = ALL_SESSION_VSID; static int msm_route_ext_ec_ref; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static int wakeup_ext_ec_ref = 0; +static int voip_ext_ec_common_ref = 0; +#endif static bool is_custom_stereo_on; static bool is_ds2_on; static bool swap_ch; @@ -1132,6 +1157,13 @@ static int msm_routing_get_adm_topology(int fedai_id, int session_type, { int topology = NULL_COPP_TOPOLOGY; int app_type = 0, acdb_dev_id = 0; +#ifdef CONFIG_MACH_XIAOMI_NABU + bool is_afe_proxy; +#endif + +#ifdef CONFIG_MACH_XIAOMI_NABU + is_afe_proxy = (be_id == MSM_BACKEND_DAI_AFE_PCM_RX); +#endif pr_debug("%s: fedai_id %d, session_type %d, be_id %d\n", __func__, fedai_id, session_type, be_id); @@ -1155,7 +1187,11 @@ static int msm_routing_get_adm_topology(int fedai_id, int session_type, app_type, acdb_dev_id, ADM_TOPOLOGY_CAL_TYPE_IDX, +#ifdef CONFIG_MACH_XIAOMI_NABU + is_afe_proxy /*exact*/); +#else false /*exact*/); +#endif if (topology < 0) topology = NULL_COPP_TOPOLOGY; } @@ -1661,6 +1697,12 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, && be_bit_width == 32) bits_per_sample = msm_routing_get_bit_width( SNDRV_PCM_FORMAT_S32_LE); +#ifdef AUDIO_SPEAKER_3D + if((i == 103) && (fe_dai_app_type_cfg[fedai_id][session_type][i].channel != 0)){ + channels = fe_dai_app_type_cfg[fedai_id][session_type][i].channel; + pr_debug("%s before adm_open change fe_dai_app_type_cfg-> channel to %d!!\n",__func__, channels); + } +#endif copp_idx = adm_open(msm_bedais[i].port_id, path_type, sample_rate, channels, topology, perf_mode, bits_per_sample, @@ -3895,9 +3937,23 @@ static const struct snd_kcontrol_new ec_ref_param_controls[] = { static int msm_routing_ec_ref_rx_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); +#endif + pr_debug("%s: ec_ref_rx = %d", __func__, msm_route_ec_ref_rx); mutex_lock(&routing_lock); + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (!strncmp(widget->name, "AUDIO_REF_EC_UL10 MUX", strlen("AUDIO_REF_EC_UL10 MUX"))) + ucontrol->value.integer.value[0] = voip_ext_ec_common_ref; + else + ucontrol->value.integer.value[0] = wakeup_ext_ec_ref; +#else ucontrol->value.integer.value[0] = msm_route_ec_ref_rx; +#endif + mutex_unlock(&routing_lock); return 0; } @@ -3910,6 +3966,9 @@ static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, snd_soc_dapm_kcontrol_widget(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + bool state = true; +#endif mutex_lock(&routing_lock); @@ -3917,6 +3976,9 @@ static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, case 0: msm_route_ec_ref_rx = 0; ec_ref_port_id = AFE_PORT_INVALID; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + state = false; +#endif break; case 1: msm_route_ec_ref_rx = 1; @@ -4063,14 +4125,39 @@ static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, pr_err("%s EC ref rx %ld not valid\n", __func__, ucontrol->value.integer.value[0]); ec_ref_port_id = AFE_PORT_INVALID; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + state = false; +#endif break; } +#ifndef CONFIG_MACH_XIAOMI_SM8150 adm_ec_ref_rx_id(ec_ref_port_id); +#endif pr_debug("%s: msm_route_ec_ref_rx = %d\n", __func__, msm_route_ec_ref_rx); + +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (!strncmp(widget->name, "AUDIO_REF_EC_UL10 MUX", strlen("AUDIO_REF_EC_UL10 MUX"))) + voip_ext_ec_common_ref = msm_route_ec_ref_rx; + else + wakeup_ext_ec_ref = msm_route_ec_ref_rx; +#endif + +#ifndef CONFIG_MACH_XIAOMI_SM8150 mutex_unlock(&routing_lock); snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, msm_route_ec_ref_rx, e, update); +#else + if (state || (!state && wakeup_ext_ec_ref == 0 && voip_ext_ec_common_ref == 0)) { + adm_ec_ref_rx_id(ec_ref_port_id); + mutex_unlock(&routing_lock); + snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, + msm_route_ec_ref_rx, e, update); + } else { + mutex_unlock(&routing_lock); + } +#endif + return 0; } @@ -5744,6 +5831,12 @@ static const struct snd_kcontrol_new tert_mi2s_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif }; static const struct snd_kcontrol_new quin_mi2s_rx_port_mixer_controls[] = { @@ -17358,7 +17451,18 @@ static const struct snd_kcontrol_new cdc_dma_wsa_switch_mixer_controls = 0, 1, 0, msm_routing_get_switch_mixer, msm_routing_put_switch_mixer); +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static const struct snd_kcontrol_new cdc_dma_rx0_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); +#endif + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static const struct snd_kcontrol_new cdc_dma_rx1_switch_mixer_controls = +#else static const struct snd_kcontrol_new cdc_dma_rx_switch_mixer_controls = +#endif SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, 0, 1, 0, msm_routing_get_switch_mixer, msm_routing_put_switch_mixer); @@ -17643,6 +17747,9 @@ static int msm_routing_put_app_type_cfg_control(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[i++]; } +#ifdef CONFIG_MACH_XIAOMI_NABU + mutex_unlock(&routing_lock); +#endif return 0; } @@ -17804,6 +17911,9 @@ static int msm_routing_get_lsm_app_type_cfg_control( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { +#ifdef CONFIG_MACH_XIAOMI_NABU + mutex_unlock(&routing_lock); +#endif return 0; } @@ -18562,7 +18672,11 @@ static const char * const wsa_rx_0_vi_fb_tx_rch_mux_text[] = { }; static const char * const mi2s_rx_vi_fb_tx_mux_text[] = { +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + "ZERO", PLATFORM_RX_VI_FB_TX_MUX_TEXT +#else "ZERO", "SENARY_TX" +#endif }; static const char * const int4_mi2s_rx_vi_fb_tx_mono_mux_text[] = { @@ -18591,7 +18705,11 @@ static const int wsa_rx_0_vi_fb_tx_rch_value[] = { static const int mi2s_rx_vi_fb_tx_value[] = { +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + MSM_BACKEND_DAI_MAX, PLATFORM_RX_VI_FB_TX_VALUE +#else MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SENARY_MI2S_TX +#endif }; static const int int4_mi2s_rx_vi_fb_tx_mono_ch_value[] = { @@ -18623,7 +18741,11 @@ static const struct soc_enum wsa_rx_0_vi_fb_rch_mux_enum = wsa_rx_0_vi_fb_tx_rch_mux_text, wsa_rx_0_vi_fb_tx_rch_value); static const struct soc_enum mi2s_rx_vi_fb_mux_enum = +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + SOC_VALUE_ENUM_DOUBLE(SND_SOC_NOPM, PLATFORM_RX_VI_FB_MUX_ENUM, 0, 0, +#else SOC_VALUE_ENUM_DOUBLE(SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_RX, 0, 0, +#endif ARRAY_SIZE(mi2s_rx_vi_fb_tx_mux_text), mi2s_rx_vi_fb_tx_mux_text, mi2s_rx_vi_fb_tx_value); @@ -18660,7 +18782,11 @@ static const struct snd_kcontrol_new wsa_rx_0_vi_fb_rch_mux = spkr_prot_put_vi_rch_port); static const struct snd_kcontrol_new mi2s_rx_vi_fb_mux = +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + SOC_DAPM_ENUM_EXT(PLATFORM_RX_VI_FB_MUX_NAME, +#else SOC_DAPM_ENUM_EXT("PRI_MI2S_RX_VI_FB_MUX", +#endif mi2s_rx_vi_fb_mux_enum, spkr_prot_get_vi_lch_port, spkr_prot_put_vi_lch_port); @@ -18738,6 +18864,12 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("TX3_CDC_DMA_UL_HL", "TX3_CDC_DMA_HOSTLESS Capture", 0, 0, 0, 0), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + SND_SOC_DAPM_AIF_OUT("TX4_CDC_DMA_UL_US", "ULTRAOUND_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("RX1_CDC_DMA_DL_US", "ULTRAOUND_HOSTLESS Playback", + 0, 0, 0, 0), +#endif SND_SOC_DAPM_AIF_OUT("CPE_LSM_UL_HL", "CPE LSM capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("SLIM1_DL_HL", "SLIMBUS1_HOSTLESS Playback", @@ -18950,8 +19082,15 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &a2dp_slim7_switch_mixer_controls), SND_SOC_DAPM_SWITCH("WSA_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, &cdc_dma_wsa_switch_mixer_controls), +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, // git + &cdc_dma_rx0_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_1_DL_HL", SND_SOC_NOPM, 0, 0, // git + &cdc_dma_rx1_switch_mixer_controls), +#else SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, &cdc_dma_rx_switch_mixer_controls), +#endif /* Mixer definitions */ SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0, slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)), @@ -19569,7 +19708,11 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets_mi2s[] = { /* lsm mixer definitions */ /* Virtual Pins to force backends ON atm */ +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + SND_SOC_DAPM_MUX(PLATFORM_RX_VI_FB_MUX_NAME, SND_SOC_NOPM, 0, 0, +#else SND_SOC_DAPM_MUX("PRI_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0, +#endif &mi2s_rx_vi_fb_mux), SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", SND_SOC_NOPM, 0, 0, &int4_mi2s_rx_vi_fb_mono_ch_mux), @@ -21165,7 +21308,15 @@ static const struct snd_soc_dapm_route intercon[] = { {"CDC_DMA_UL_HL", NULL, "VA_CDC_DMA_TX_0"}, {"RX_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_DL_HL"}, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + {"RX_CDC_DMA_RX_1_DL_HL", "Switch", "CDC_DMA_DL_HL"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1_DL_HL"}, + {"RX_CDC_DMA_RX_1", NULL, "RX1_CDC_DMA_DL_US"}, +#endif {"TX3_CDC_DMA_UL_HL", NULL, "TX_CDC_DMA_TX_3"}, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + {"TX4_CDC_DMA_UL_US", NULL, "TX_CDC_DMA_TX_4"}, +#endif {"LSM1 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, {"LSM1 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, {"LSM1 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, @@ -23525,11 +23676,19 @@ static const struct snd_soc_dapm_route intercon_mi2s[] = { {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX_DL_HL"}, {"INT4_MI2S_RX_DL_HL", "Switch", "INT4_MI2S_DL_HL"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_DL_HL"}, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + {"PRI_MI2S_RX_DL_HL", "Switch", "CDC_DMA_DL_HL"}, +#else {"PRI_MI2S_RX_DL_HL", "Switch", "PRI_MI2S_DL_HL"}, +#endif {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_DL_HL"}, {"SEC_MI2S_RX_DL_HL", "Switch", "SEC_MI2S_DL_HL"}, {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX_DL_HL"}, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + {"TERT_MI2S_RX_DL_HL", "Switch", "CDC_DMA_DL_HL"}, +#else {"TERT_MI2S_RX_DL_HL", "Switch", "TERT_MI2S_DL_HL"}, +#endif {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_DL_HL"}, {"QUAT_MI2S_RX_DL_HL", "Switch", "QUAT_MI2S_DL_HL"}, @@ -23657,6 +23816,9 @@ static const struct snd_soc_dapm_route intercon_mi2s[] = { {"TERT_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"TERT_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"TERT_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + {"TERT_MI2S_RX Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, +#endif {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX Port Mixer"}, {"QUAT_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23712,10 +23874,18 @@ static const struct snd_soc_dapm_route intercon_mi2s[] = { {"INT5_MI2S_TX", NULL, "BE_IN"}, {"SEC_MI2S_TX", NULL, "BE_IN"}, {"SENARY_MI2S_TX", NULL, "BE_IN"}, +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + {PLATFORM_RX_VI_FB_MUX_NAME, PLATFORM_RX_VI_FB_TX_MUX_TEXT, PLATFORM_RX_VI_FB_TX_MUX_TEXT}, +#else {"PRI_MI2S_RX_VI_FB_MUX", "SENARY_TX", "SENARY_TX"}, +#endif {"INT4_MI2S_RX_VI_FB_MONO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"}, {"INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"}, +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + {PLATFORM_RX_VI_FB_RX_MUX_TEXT, NULL, PLATFORM_RX_VI_FB_MUX_NAME}, +#else {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_VI_FB_MUX"}, +#endif {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_MONO_CH_MUX"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_STEREO_CH_MUX"}, }; @@ -23935,6 +24105,12 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) be_bit_width == 32) bits_per_sample = msm_routing_get_bit_width( SNDRV_PCM_FORMAT_S32_LE); +#ifdef AUDIO_SPEAKER_3D + if((be_id == 103) && (fe_dai_app_type_cfg[i][session_type][be_id].channel != 0)){ + channels = fe_dai_app_type_cfg[i][session_type][be_id].channel; + pr_debug("%s before adm_open change fe_dai_app_type_cfg-> channel to %d!!\n",__func__, channels); + } +#endif copp_idx = adm_open(bedai->port_id, path_type, sample_rate, channels, topology, fdai->perf_mode, bits_per_sample, @@ -24629,6 +24805,10 @@ static int msm_routing_probe(struct snd_soc_platform *platform) msm_routing_be_dai_name_table_mixer_controls, ARRAY_SIZE(msm_routing_be_dai_name_table_mixer_controls)); +#ifdef CONFIG_MSM_CSPL_V2 + msm_crus_pb_add_controls(&platform->component); +#endif + snd_soc_add_platform_controls(platform, msm_source_tracking_controls, ARRAY_SIZE(msm_source_tracking_controls)); snd_soc_add_platform_controls(platform, adm_channel_config_controls, @@ -24644,6 +24824,14 @@ static int msm_routing_probe(struct snd_soc_platform *platform) snd_soc_add_platform_controls(platform, port_multi_channel_map_mixer_controls, ARRAY_SIZE(port_multi_channel_map_mixer_controls)); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + elliptic_add_platform_controls(platform); +#endif + /* for mius start */ +#ifdef CONFIG_US_PROXIMITY + mius_add_platform_controls(platform); +#endif + /* for mius end */ return 0; } diff --git a/techpack/audio/asoc/msm-pcm-routing-v2.h b/techpack/audio/asoc/msm-pcm-routing-v2.h index 8f56c1f947d9..a597042b26c3 100644 --- a/techpack/audio/asoc/msm-pcm-routing-v2.h +++ b/techpack/audio/asoc/msm-pcm-routing-v2.h @@ -564,6 +564,9 @@ struct msm_pcm_stream_app_type_cfg { int app_type; int acdb_dev_id; int sample_rate; +#ifdef CONFIG_MACH_XIAOMI_NABU + int channel; +#endif }; /* dai_id: front-end ID, diff --git a/techpack/audio/asoc/sm8150.c b/techpack/audio/asoc/sm8150.c index 14d65162c5a5..634b2da74335 100644 --- a/techpack/audio/asoc/sm8150.c +++ b/techpack/audio/asoc/sm8150.c @@ -39,6 +39,12 @@ #include "codecs/wcd9360/wcd9360.h" #include "codecs/wsa881x.h" #include "codecs/wcd-mbhc-v2.h" +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) +#include +#endif +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI +#include "codecs/tfa98xx/inc/tfa_platform_interface_definition.h" +#endif #define DRV_NAME "sm8150-asoc-snd" @@ -68,6 +74,10 @@ #define WCN_CDC_SLIM_RX_CH_MAX 2 #define WCN_CDC_SLIM_TX_CH_MAX 3 +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) +#define CS35L41_CODEC_NAME "cs35l41.0-0040" +#endif + #define ADSP_STATE_READY_TIMEOUT_MS 3000 #define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ #define MSM_HIFI_ON 1 @@ -75,6 +85,52 @@ #define TDM_MAX_SLOTS 8 #define TDM_SLOT_WIDTH_BITS 32 +#ifdef CONFIG_MACH_XIAOMI_NABU +#define CS35L41_PA_TL_NAME "cs35l41.2-0043" +#define CS35L41_PA_TR_NAME "cs35l41.2-0041" +#define CS35L41_PA_BL_NAME "cs35l41.2-0042" +#define CS35L41_PA_BR_NAME "cs35l41.2-0040" + +struct snd_soc_dai_link_component cs35l41_codec_components[] = { + { + .name = CS35L41_PA_TL_NAME, + .dai_name = CS35L41_PA_TL_NAME, + }, + { + .name = CS35L41_PA_TR_NAME, + .dai_name = CS35L41_PA_TR_NAME, + }, + { + .name = CS35L41_PA_BL_NAME, + .dai_name = CS35L41_PA_BL_NAME, + }, + { + .name = CS35L41_PA_BR_NAME, + .dai_name = CS35L41_PA_BR_NAME, + }, + +}; + +static struct snd_soc_codec_conf cs35l41_codec_conf[] = { + { + .dev_name = CS35L41_PA_TL_NAME, + .name_prefix = "TL", + }, + { + .dev_name = CS35L41_PA_TR_NAME, + .name_prefix = "TR", + }, + { + .dev_name = CS35L41_PA_BL_NAME, + .name_prefix = "BL", + }, + { + .dev_name = CS35L41_PA_BR_NAME, + .name_prefix = "BR", + }, +}; +#endif + enum { SLIM_RX_0 = 0, SLIM_RX_1, @@ -170,10 +226,19 @@ struct msm_pinctrl_info { struct msm_asoc_mach_data { struct snd_info_entry *codec_root; struct msm_pinctrl_info pinctrl_info; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + int usbc_en2_gpio; /* used by gpio driver API */ +#endif struct device_node *us_euro_gpio_p; /* used by pinctrl API */ +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */ +#endif struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ struct device_node *fsa_handle; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + struct device_node *adc2_sel_gpio_p; /* used by pinctrl API */ +#endif struct device_node *mi2s_gpio_p[MI2S_MAX]; /* used by pinctrl API */ struct snd_soc_codec *codec; struct work_struct adsp_power_up_work; @@ -410,7 +475,11 @@ static struct tdm_dev_config tdm_cfg[TDM_INTERFACE_MAX * 2] { {0xFFFF} }, /* TX_7 */ }, { /* QUAT TDM */ +#ifdef CONFIG_MACH_XIAOMI_NABU + { {0, 4, 8, 12, 0xFFFF} }, /* RX_0 */ +#else { {0, 4, 0xFFFF} }, /* RX_0 */ +#endif { {8, 12, 0xFFFF} }, /* RX_1 */ { {16, 20, 0xFFFF} }, /* RX_2 */ { {24, 28, 0xFFFF} }, /* RX_3 */ @@ -467,7 +536,11 @@ static struct dev_config mi2s_tx_cfg[] = { [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +#else [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +#endif [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; @@ -636,9 +709,15 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = { .swap_gnd_mic = NULL, .hs_ext_micbias = true, .key_code[0] = KEY_MEDIA, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + .key_code[1] = BTN_1, + .key_code[2] = BTN_2, + .key_code[3] = 0, +#else .key_code[1] = KEY_VOICECOMMAND, .key_code[2] = KEY_VOLUMEUP, .key_code[3] = KEY_VOLUMEDOWN, +#endif .key_code[4] = 0, .key_code[5] = 0, .key_code[6] = 0, @@ -2950,6 +3029,41 @@ static int msm_hifi_put(struct snd_kcontrol *kcontrol, return 0; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static int usbhs_direction_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ +#ifdef CONFIG_MACH_XIAOMI_NABU + if (wcd_mbhc_cfg.flip_switch) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; +#else + struct snd_soc_codec *codec = NULL; + struct snd_soc_card *card = NULL; + struct msm_asoc_mach_data *pdata = NULL; + + ucontrol->value.integer.value[0] = 0; + + codec = snd_soc_kcontrol_codec(kcontrol); + if (codec) { + card = codec->component.card; + if (card) { + pdata = snd_soc_card_get_drvdata(card); + if (pdata){ + if (pdata->usbc_en2_gpio_p) { + ucontrol->value.integer.value[0] = gpio_get_value_cansleep(pdata->usbc_en2_gpio); + } else if (pdata->usbc_en2_gpio > 0) { + ucontrol->value.integer.value[0] = gpio_get_value_cansleep(pdata->usbc_en2_gpio); + } + } + } + } +#endif + return 0; +} +#endif + static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, slim_rx_ch_get, slim_rx_ch_put), @@ -3236,6 +3350,10 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get, msm_hifi_put), +#ifdef CONFIG_MACH_XIAOMI_SM8150 + SOC_SINGLE_EXT("USB Headset Direction", 0, 0, UINT_MAX, 0, + usbhs_direction_get, NULL), +#endif SOC_SINGLE_MULTI_EXT("TDM Slot Map", SND_SOC_NOPM, 0, 255, 0, 4, NULL, tdm_slot_map_put), @@ -3342,6 +3460,52 @@ static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, return 0; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static void external_enable_dual_adc_gpio(struct device_node *np, bool val) +{ + if (!np) { + pr_err("%s: device node is NULL!", __func__); + return; + } + + if (val == 1) { + msm_cdc_pinctrl_select_active_state(np); + pr_info("%s: enable Dual ADC \n", __func__); + } else { + msm_cdc_pinctrl_select_sleep_state(np); + pr_info("%s: disable Dual ADC \n", __func__); + } +} + +static int external_amic2_sel_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_card *card = dapm->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + unsigned int val; + + val = ucontrol->value.enumerated.item[0]; + + if (!pdata || !pdata->adc2_sel_gpio_p) { + pr_err("%s: adc2_sel_gpio is invalid\n", __func__); + return -EINVAL; + } + + pr_info("external_amic2_sel_put %u \n", val); + + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static const char *const external_AMIC2_enum_text[] = {"default", "Dual_ADC"}; + +static SOC_ENUM_SINGLE_VIRT_DECL(external_AMIC2_enum, external_AMIC2_enum_text); + +static const struct snd_kcontrol_new ext_amc2_mux = + SOC_DAPM_ENUM_EXT("External AMIC2 sel", external_AMIC2_enum, + snd_soc_dapm_get_enum_double, external_amic2_sel_put); +#endif + static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, @@ -3390,8 +3554,25 @@ static const struct snd_soc_dapm_widget msm_dapm_widgets_tavil[] = { SND_SOC_DAPM_MIC("Digital Mic3", NULL), SND_SOC_DAPM_MIC("Digital Mic4", NULL), SND_SOC_DAPM_MIC("Digital Mic5", NULL), +#ifdef CONFIG_MACH_XIAOMI_SM8150 + SND_SOC_DAPM_MIC("Headset Mic2", NULL), +#endif }; +#ifdef CONFIG_MACH_XIAOMI_SM8150 +static const struct snd_soc_dapm_widget msm_dualadc_dapm_widgets[] = { + SND_SOC_DAPM_MUX("External AMIC2 Mux", SND_SOC_NOPM, 0, 0, &ext_amc2_mux), + SND_SOC_DAPM_INPUT("AMIC2_EXT_0"), + SND_SOC_DAPM_INPUT("AMIC2_EXT_1"), +}; // git + +static const struct snd_soc_dapm_route msm_dualadc_dapm_routes[] = { + {"AMIC2", NULL, "External AMIC2 Mux"}, + {"External AMIC2 Mux", "default", "AMIC2_EXT_0"}, + {"External AMIC2 Mux", "Dual_ADC", "AMIC2_EXT_1"}, +}; // git +#endif + static inline int param_is_mask(int p) { return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && @@ -3870,10 +4051,116 @@ static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active) struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !defined(CONFIG_MACH_XIAOMI_NABU) + struct pinctrl_state *en2_pinctrl_active; + struct pinctrl_state *en2_pinctrl_sleep; + int value = 0; + bool ret = 0; + int oldv; + + if (wcd_mbhc_cfg.use_fsa4476_gpio != 0) { + if (!pdata->usbc_en2_gpio_p) { + if (active) { + /* if active and usbc_en2_gpio undefined, get pin */ + pdata->usbc_en2_gpio_p = devm_pinctrl_get(card->dev); + if (IS_ERR_OR_NULL(pdata->usbc_en2_gpio_p)) { + dev_err(card->dev, + "%s: Can't get EN2 gpio pinctrl:%ld\n", + __func__, + PTR_ERR(pdata->usbc_en2_gpio_p)); + pdata->usbc_en2_gpio_p = NULL; + return false; + } + } else + /* if not active and usbc_en2_gpio undefined, return */ + return false; + } + + pdata->usbc_en2_gpio = of_get_named_gpio(card->dev->of_node, + "qcom,usbc-analog-en2-gpio", 0); + if (!gpio_is_valid(pdata->usbc_en2_gpio)) { + dev_err(card->dev, "%s, property %s not in node %s", + __func__, "qcom,usbc-analog-en2-gpio", + card->dev->of_node->full_name); + return false; + } + + en2_pinctrl_active = pinctrl_lookup_state( + pdata->usbc_en2_gpio_p, "aud_active"); + if (IS_ERR_OR_NULL(en2_pinctrl_active)) { + dev_err(card->dev, + "%s: Cannot get aud_active pinctrl state:%ld\n", + __func__, PTR_ERR(en2_pinctrl_active)); + ret = false; + goto err_lookup_state; + } + + en2_pinctrl_sleep = pinctrl_lookup_state( + pdata->usbc_en2_gpio_p, "aud_sleep"); + if (IS_ERR_OR_NULL(en2_pinctrl_sleep)) { + dev_err(card->dev, + "%s: Cannot get aud_sleep pinctrl state:%ld\n", + __func__, PTR_ERR(en2_pinctrl_sleep)); + ret = false; + goto err_lookup_state; + } + + /* if active and usbc_en2_gpio_p defined, swap using usbc_en2_gpio_p */ + if (active) { + dev_dbg(codec->dev, "%s: enter\n", __func__); + oldv = tavil_mb_pull_down(codec, true, 0); + if (wcd_mbhc_cfg.usbc_analog_cfg.euro_us_hw_switch_gpio_p) { + value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); + if (value) + msm_cdc_pinctrl_select_sleep_state( + wcd_mbhc_cfg.usbc_analog_cfg.euro_us_hw_switch_gpio_p); + else + msm_cdc_pinctrl_select_active_state( + wcd_mbhc_cfg.usbc_analog_cfg.euro_us_hw_switch_gpio_p); + } + else if (pdata->usbc_en2_gpio_p) { + value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); + if (value) + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_sleep); + else + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_active); + } else if (pdata->usbc_en2_gpio >= 0) { + value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); + gpio_set_value_cansleep(pdata->usbc_en2_gpio, !value); + } + tavil_mb_pull_down(codec, false, oldv); + pr_info("%s: swap select switch %d to %d\n", __func__, + value, !value); + ret = true; + } else { + /* if not active, release usbc_en2_gpio_p pin */ + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_sleep); + } + } else { +#endif if (!pdata->fsa_handle) return false; +#ifdef CONFIG_MACH_XIAOMI_NABU + wcd_mbhc_cfg.flip_switch = true; +#endif + return fsa4480_switch_event(pdata->fsa_handle, FSA_MIC_GND_SWAP); +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !defined(CONFIG_MACH_XIAOMI_NABU) + } // git + + +err_lookup_state: + if (wcd_mbhc_cfg.use_fsa4476_gpio != 0) { + devm_pinctrl_put(pdata->usbc_en2_gpio_p); + pdata->usbc_en2_gpio_p = NULL; + } // git + + return ret; +#endif } static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) @@ -4146,6 +4433,17 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) ARRAY_SIZE(wcd_audio_paths)); } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (pdata->adc2_sel_gpio_p) { + pr_info("add the External AMIC2 Mux\n"); + snd_soc_dapm_new_controls(dapm, msm_dualadc_dapm_widgets, + ARRAY_SIZE(msm_dualadc_dapm_widgets)); + + snd_soc_dapm_add_routes(dapm, msm_dualadc_dapm_routes, + ARRAY_SIZE(msm_dualadc_dapm_routes)); + } +#endif + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); @@ -4166,6 +4464,14 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_ignore_suspend(dapm, "WDMA3_OUT"); if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (pdata->adc2_sel_gpio_p) { + snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2_EXT_0"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2_EXT_1"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic2"); + } +#endif snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); @@ -4306,6 +4612,25 @@ static void *def_wcd_mbhc_cal(void) btn_high = ((void *)&btn_cfg->_v_btn_low) + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); +#ifdef CONFIG_MACH_XIAOMI_NABU + btn_high[0] = 75; + btn_high[1] = 225; + btn_high[2] = 450; + btn_high[3] = 500; + btn_high[4] = 500; + btn_high[5] = 500; + btn_high[6] = 500; + btn_high[7] = 500; +#elif defined(CONFIG_MACH_XIAOMI_SM8150) + btn_high[0] = 75; + btn_high[1] = 260; + btn_high[2] = 750; + btn_high[3] = 750; + btn_high[4] = 750; + btn_high[5] = 750; + btn_high[6] = 750; + btn_high[7] = 750; +#else btn_high[0] = 75; btn_high[1] = 150; btn_high[2] = 237; @@ -4314,6 +4639,7 @@ static void *def_wcd_mbhc_cal(void) btn_high[5] = 500; btn_high[6] = 500; btn_high[7] = 500; +#endif return wcd_mbhc_cal; } @@ -5063,6 +5389,12 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) } } } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + snd_soc_codec_set_sysclk(rtd->codec_dai->codec, 0, 0, + mi2s_clk[index].clk_freq_in_hz, + SND_SOC_CLOCK_IN); +#endif + clk_off: if (ret < 0) msm_mi2s_set_sclk(substream, false); @@ -5744,6 +6076,25 @@ static struct snd_soc_dai_link msm_pahu_fe_dai_links[] = { }; static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + { + .name = TFA_TX_HOSTLESS_CODEC_NAME, + .stream_name = TFA_TX_HOSTLESS_STREAM_NAME, + .cpu_dai_name = TFA_TX_HOSTLESS_CPU_DAI_NAME, + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + /* This dainlink has MI2S support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +#else { .name = LPASS_BE_SLIMBUS_4_TX, .stream_name = "Slimbus4 Capture", @@ -5757,6 +6108,7 @@ static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, }, +#endif /* Ultrasound RX DAI Link */ { .name = "SLIMBUS_2 Hostless Playback", @@ -5849,6 +6201,38 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA17, }, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + { + .name = "Quaternary MI2S_RX Hostless Playback", + .stream_name = "Quaternary MI2S_RX Hostless Playback", + .cpu_dai_name = "QUAT_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quaternary MI2S_TX Hostless Capture", + .stream_name = "Quaternary MI2S_TX Hostless Capture", + .cpu_dai_name = "QUAT_MI2S_TX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +#endif { .name = "MultiMedia30 Playback", .stream_name = "MultiMedia30", @@ -5879,6 +6263,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA31, }, +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) { .name = "Quaternary MI2S_RX Hostless Playback", .stream_name = "Quaternary MI2S_RX Hostless Playback", @@ -5909,6 +6294,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, +#endif /* Voice Stub */ { .name = "Voice Stub", @@ -6158,6 +6544,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .ops = &sm8150_tdm_be_ops, .ignore_suspend = 1, }, +#ifndef CONFIG_MACH_XIAOMI_NABU { .name = LPASS_BE_QUAT_TDM_RX_0, .stream_name = "Quaternary TDM0 Playback", @@ -6173,6 +6560,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, }, +#endif { .name = LPASS_BE_QUAT_TDM_TX_0, .stream_name = "Quaternary TDM0 Capture", @@ -6751,13 +7139,19 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, }, +#if !defined(CONFIG_MACH_XIAOMI_SM8150) || defined(CONFIG_MACH_XIAOMI_VAYU) { .name = LPASS_BE_QUAT_MI2S_RX, .stream_name = "Quaternary MI2S Playback", .cpu_dai_name = "msm-dai-q6-mi2s.3", .platform_name = "msm-pcm-routing", +#ifdef CONFIG_SND_SOC_TAS256X + .codec_name = "tas256x.1-004c", + .codec_dai_name = "tas256x ASI1", +#else .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-rx", +#endif .no_pcm = 1, .dpcm_playback = 1, .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, @@ -6766,13 +7160,20 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, }, +#endif +#ifndef CONFIG_MACH_XIAOMI_NABU { .name = LPASS_BE_QUAT_MI2S_TX, .stream_name = "Quaternary MI2S Capture", .cpu_dai_name = "msm-dai-q6-mi2s.3", .platform_name = "msm-pcm-routing", +#ifdef CONFIG_SND_SOC_TAS256X + .codec_name = "tas256x.1-004c", + .codec_dai_name = "tas256x ASI1", +#else .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-tx", +#endif .no_pcm = 1, .dpcm_capture = 1, .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, @@ -6780,6 +7181,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, }, +#endif { .name = LPASS_BE_QUIN_MI2S_RX, .stream_name = "Quinary MI2S Playback", @@ -6812,6 +7214,80 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { }; +#ifdef CONFIG_MACH_XIAOMI_NABU +static struct snd_soc_dai_link quat_mi2s_rx_cs35l41_dai_links[] = { + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codecs = cs35l41_codec_components, + .num_codecs = ARRAY_SIZE(cs35l41_codec_components), + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sm8150_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, +}; +#elif defined(CONFIG_MACH_XIAOMI_SM8150) && !defined(CONFIG_MACH_XIAOMI_VAYU) +static struct snd_soc_dai_link quat_mi2s_rx_tas2557_dai_links[] = { + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "tas2557.1-004c", + .codec_dai_name = "tas2557 ASI1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, +}; + +static struct snd_soc_dai_link quat_mi2s_rx_tfa9874_dai_links[] = { + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "tfa98xx.1-0034", + .codec_dai_name = "tfa98xx-aif-1-34", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, +}; + +static struct snd_soc_dai_link quat_mi2s_rx_cs35l41_dai_links[] = { + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = CS35L41_CODEC_NAME, + .codec_dai_name = "cs35l41-pcm", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, +}; +#endif + static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { /* Primary AUX PCM Backend DAI Links */ { @@ -6974,6 +7450,11 @@ static struct snd_soc_dai_link msm_tavil_dai_links[ ARRAY_SIZE(msm_wcn_be_dai_links) + ARRAY_SIZE(ext_disp_be_dai_link) + ARRAY_SIZE(msm_mi2s_be_dai_links) + +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + ARRAY_SIZE(quat_mi2s_rx_tas2557_dai_links) + + ARRAY_SIZE(quat_mi2s_rx_tfa9874_dai_links) + + ARRAY_SIZE(quat_mi2s_rx_cs35l41_dai_links) + +#endif ARRAY_SIZE(msm_auxpcm_be_dai_links)]; static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) @@ -6982,6 +7463,11 @@ static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) struct snd_soc_pcm_runtime *rtd; int ret = 0; void *mbhc_calibration; +#ifdef CONFIG_SND_SOC_CS35L41_FOR_CEPH + struct snd_soc_dai_link *dai_link; + struct snd_soc_codec *cs35l41_codec; + struct snd_soc_dapm_context * cs35l41_dapm; +#endif rtd = snd_soc_get_pcm_runtime(card, be_dl_name); if (!rtd) { @@ -7004,6 +7490,28 @@ static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) __func__, ret); goto err_hs_detect; } + +#ifdef CONFIG_SND_SOC_CS35L41_FOR_CEPH + dai_link = rtd->dai_link; + if (dai_link && dai_link->codec_name) { + if (!strcmp(dai_link->codec_name, CS35L41_CODEC_NAME)) { + dev_info(card->dev, "%s: found codec[%s]\n", __func__, CS35L41_CODEC_NAME); + cs35l41_codec = rtd->codec; + cs35l41_dapm = snd_soc_codec_get_dapm(cs35l41_codec); + snd_soc_dapm_ignore_suspend(cs35l41_dapm, "AMP Playback"); + snd_soc_dapm_ignore_suspend(cs35l41_dapm, "AMP Capture"); + snd_soc_dapm_ignore_suspend(cs35l41_dapm, "DSP1"); + snd_soc_dapm_ignore_suspend(cs35l41_dapm, "Main AMP"); + snd_soc_dapm_ignore_suspend(cs35l41_dapm, "ASPRX1"); + snd_soc_dapm_ignore_suspend(cs35l41_dapm, "ASPRX2"); + snd_soc_dapm_ignore_suspend(cs35l41_dapm, "ASPTX1"); + snd_soc_dapm_ignore_suspend(cs35l41_dapm, "ASPTX2"); + snd_soc_dapm_ignore_suspend(cs35l41_dapm, "SPK"); + snd_soc_dapm_sync(cs35l41_dapm); + } + } +#endif + return 0; err_hs_detect: @@ -7019,6 +7527,10 @@ struct snd_soc_card snd_soc_card_pahu_msm = { struct snd_soc_card snd_soc_card_tavil_msm = { .name = "sm8150-tavil-snd-card", +#ifdef CONFIG_MACH_XIAOMI_NABU + .codec_conf = cs35l41_codec_conf, + .num_configs = ARRAY_SIZE(cs35l41_codec_conf), +#endif .late_probe = msm_snd_card_tavil_late_probe, }; @@ -7378,6 +7890,30 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) msm_mi2s_be_dai_links, sizeof(msm_mi2s_be_dai_links)); total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); + +#if defined(CONFIG_MACH_XIAOMI_SM8150) && !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) + if (get_hw_version_platform() == HARDWARE_PLATFORM_ANDROMEDA) { + memcpy(msm_tavil_dai_links + total_links, + quat_mi2s_rx_tas2557_dai_links, + sizeof(quat_mi2s_rx_tas2557_dai_links)); + total_links += ARRAY_SIZE(quat_mi2s_rx_tas2557_dai_links); + } else if (get_hw_version_platform() == HARDWARE_PLATFORM_CEPHEUS) { + memcpy(msm_tavil_dai_links + total_links, + quat_mi2s_rx_cs35l41_dai_links, + sizeof(quat_mi2s_rx_cs35l41_dai_links)); + total_links += ARRAY_SIZE(quat_mi2s_rx_cs35l41_dai_links); + } else if (get_hw_version_platform() == HARDWARE_PLATFORM_RAPHAEL) { + memcpy(msm_tavil_dai_links + total_links, + quat_mi2s_rx_tfa9874_dai_links, + sizeof(quat_mi2s_rx_tfa9874_dai_links)); + total_links += ARRAY_SIZE(quat_mi2s_rx_tfa9874_dai_links); + } +#elif defined(CONFIG_MACH_XIAOMI_NABU) + memcpy(msm_tavil_dai_links + total_links, + quat_mi2s_rx_cs35l41_dai_links, + sizeof(quat_mi2s_rx_cs35l41_dai_links)); + total_links += ARRAY_SIZE(quat_mi2s_rx_cs35l41_dai_links); +#endif } ret = of_property_read_u32(dev->of_node, @@ -7715,6 +8251,27 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, pdata); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + pdata->adc2_sel_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,adc2-switch-gpio", 0); + if (!pdata->adc2_sel_gpio_p) { + dev_err(&pdev->dev, "property %s not detected in node %s", + "qcom,adc2-switch-gpio", + pdev->dev.of_node->full_name); + } + + wcd_mbhc_cfg.dual_adc_gpio_node = pdata->adc2_sel_gpio_p; + wcd_mbhc_cfg.enable_dual_adc_gpio = external_enable_dual_adc_gpio; + + pdata->usbc_en2_gpio = of_get_named_gpio(card->dev->of_node, + "qcom,usbc-analog-en2-gpio", 0); + if (!gpio_is_valid(pdata->usbc_en2_gpio)) { + dev_err(card->dev, "%s, property %s not in node %s", + __func__, "qcom,usbc-analog-en2-gpio", + card->dev->of_node->full_name); + } +#endif + ret = snd_soc_of_parse_card_name(card, "qcom,model"); if (ret) { dev_err(&pdev->dev, "parse card name failed, err:%d\n", diff --git a/techpack/audio/dsp/Kbuild b/techpack/audio/dsp/Kbuild index aaddbd54bb80..6927d36c064b 100644 --- a/techpack/audio/dsp/Kbuild +++ b/techpack/audio/dsp/Kbuild @@ -189,6 +189,14 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -Werror\ -D__linux__ +ifeq (y, $(filter y,$(CONFIG_MACH_XIAOMI_RAPHAEL))) + CDEFINES += -DCONFIG_SND_SOC_TFA9874_FOR_DAVI +endif + +ifeq (y, $(filter y,$(CONFIG_MACH_XIAOMI_NABU))) + CDEFINES += -DAUDIO_FORCE_RESTART_ADSP +endif + KBUILD_CPPFLAGS += $(CDEFINES) # Currently, for versions of gcc which support it, the kernel Makefile diff --git a/techpack/audio/dsp/q6_init.c b/techpack/audio/dsp/q6_init.c index 202955a96040..3f9f7963cae7 100644 --- a/techpack/audio/dsp/q6_init.c +++ b/techpack/audio/dsp/q6_init.c @@ -31,14 +31,28 @@ static int __init audio_q6_init(void) msm_audio_ion_init(); audio_slimslave_init(); avtimer_init(); +#if defined(CONFIG_MSM_CSPL) || defined(CONFIG_MSM_CSPL_V2) + crus_sp_init(); +#endif msm_mdf_init(); voice_mhi_init(); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + elliptic_driver_init(); +#endif +/* for mius start */ +#ifdef CONFIG_US_PROXIMITY + mius_driver_init(); +#endif +/* for mius end */ return 0; } static void __exit audio_q6_exit(void) { msm_mdf_exit(); +#if defined(CONFIG_MSM_CSPL) || defined(CONFIG_MSM_CSPL_V2) + crus_sp_exit(); +#endif avtimer_exit(); audio_slimslave_exit(); msm_audio_ion_exit(); @@ -53,6 +67,14 @@ static void __exit audio_q6_exit(void) audio_cal_exit(); adsp_err_exit(); voice_mhi_exit(); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + elliptic_driver_exit(); +#endif +/* for mius start */ +#ifdef CONFIG_US_PROXIMITY + mius_driver_exit(); +#endif +/* for mius end */ } module_init(audio_q6_init); diff --git a/techpack/audio/dsp/q6_init.h b/techpack/audio/dsp/q6_init.h index 5014c37a6c32..8ad91d7d7237 100644 --- a/techpack/audio/dsp/q6_init.h +++ b/techpack/audio/dsp/q6_init.h @@ -26,6 +26,17 @@ int rtac_init(void); int msm_audio_ion_init(void); int audio_slimslave_init(void); int avtimer_init(void); +#if defined(CONFIG_MSM_CSPL) || defined(CONFIG_MSM_CSPL_V2) +int crus_sp_init(void); +#endif +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int elliptic_driver_init(void); +#endif +/* for mius start */ +#ifdef CONFIG_US_PROXIMITY +int mius_driver_init(void); +#endif +/* for mius end */ #ifdef CONFIG_MSM_MDF int msm_mdf_init(void); void msm_mdf_exit(void); @@ -53,6 +64,9 @@ static inline void spk_params_exit(void) } #endif +#if defined(CONFIG_MSM_CSPL) || defined(CONFIG_MSM_CSPL_V2) +void crus_sp_exit(void); +#endif void avtimer_exit(void); void audio_slimslave_exit(void); void msm_audio_ion_exit(void); @@ -65,6 +79,14 @@ void q6asm_exit(void); void afe_exit(void); void adm_exit(void); void adsp_err_exit(void); +#ifdef CONFIG_MACH_XIAOMI_SM8150 +int elliptic_driver_exit(void); +#endif +/* for mius start */ +#ifdef CONFIG_US_PROXIMITY +int mius_driver_exit(void); +#endif +/* for mius end */ #ifdef CONFIG_VOICE_MHI int voice_mhi_init(void); diff --git a/techpack/audio/dsp/q6adm.c b/techpack/audio/dsp/q6adm.c index 183fef90c764..9c02cf3e7191 100644 --- a/techpack/audio/dsp/q6adm.c +++ b/techpack/audio/dsp/q6adm.c @@ -29,6 +29,10 @@ #include #include "adsp_err.h" +#ifdef CONFIG_MSM_CSPL_V2 +#include +#endif + #define TIMEOUT_MS 1000 #define RESET_COPP_ID 99 @@ -56,6 +60,11 @@ enum adm_cal_status { ADM_STATUS_MAX, }; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +static bool is_usb_timeout = false; +static bool close_usb = false; +#endif + struct adm_copp { atomic_t id[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; @@ -900,6 +909,88 @@ int adm_set_custom_chmix_cfg(int port_id, int copp_idx, } EXPORT_SYMBOL(adm_set_custom_chmix_cfg); +#ifdef CONFIG_MSM_CSPL_V2 +int crus_adm_set_params(int port_id, int copp_idx, int instance_id, + uint32_t module_id, uint32_t param_id, char *params, + uint32_t length) +{ + struct param_hdr_v3 param_hdr; + int port_idx = 0; + int rc = 0; + + pr_info("[CSPL] %s: port_idx: 0x%x, copp_idx: %d, module: 0x%x, len: %d\n", + __func__, port_idx, copp_idx, module_id, length); + + port_id = q6audio_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + + if (port_idx < 0) { + pr_err("[CSPL] %s: Invalid port_id %#x\n", __func__, port_id); + goto fail_cmd; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("[CSPL] %s: Invalid copp_num: %d\n", __func__, copp_idx); + goto fail_cmd; + } + + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = module_id; + param_hdr.instance_id = instance_id; + param_hdr.param_id = param_id; + param_hdr.param_size = length; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + + pr_info("[CSPL] %s: port_idx: 0x%x, copp_idx: %d, copp rate: %d, len: %d\n", + __func__, port_idx, copp_idx, + atomic_read(&this_adm.copp.rate[port_idx][copp_idx]), + length); + + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) params); + if (rc) + pr_err("%s: Failed to set media format configuration data, err %d\n", + __func__, rc); + +fail_cmd: + return 0; +} +EXPORT_SYMBOL(crus_adm_set_params); + +int crus_adm_get_params(int port_id, int copp_idx, int instance_id, + uint32_t module_id, uint32_t param_id, char *params, + uint32_t length, uint32_t client_id) +{ + int ret = 0; + struct param_hdr_v3 param_hdr; + + pr_info("[CSPL] %s: Enter, port_id %x, copp_idx: %d, len: %d\n", + __func__, port_id, copp_idx, length); + + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = module_id; + param_hdr.instance_id = instance_id; + param_hdr.param_id = param_id; + param_hdr.param_size = length; + ret = adm_get_pp_params(port_id, copp_idx, + client_id, NULL, ¶m_hdr, + params); + if (ret) { + pr_err("%s: get parameters failed ret:%d\n", __func__, ret); + ret = -EINVAL; + goto done; + } + +done: + pr_debug("%s: Exit, ret = %d\n", __func__, ret); + + return ret; +} +EXPORT_SYMBOL(crus_adm_get_params); +#endif + /* * With pre-packed data, only the opcode differes from V5 and V6. * Use q6common_pack_pp_params to pack the data correctly. @@ -1759,6 +1850,15 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) open->copp_id); pr_debug("%s: coppid rxed=%d\n", __func__, open->copp_id); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (is_usb_timeout && (IDX_AFE_PORT_ID_USB_RX == port_idx)) + close_usb = true; + + if (close_usb && (IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX == port_idx)) + is_usb_timeout = false; +#endif + wake_up(&this_adm.copp.wait[port_idx][copp_idx]); } break; @@ -2852,6 +2952,12 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, port_id = q6audio_convert_virtual_to_portid(port_id); port_idx = adm_validate_and_get_port_index(port_id); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (is_usb_timeout && (AFE_PORT_ID_USB_RX == port_id)) + return -EINVAL; +#endif + if (port_idx < 0) { pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); return -EINVAL; @@ -2919,7 +3025,12 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, this_adm.ffecns_port_id); } +#ifdef CONFIG_MACH_XIAOMI_SM8150 + if (topology == VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY || + topology == ADM_TOPOLOGY_ID_AUDIO_RX_FVSAM) +#else if (topology == VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY) +#endif channel_mode = 1; /* @@ -3214,6 +3325,12 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if (!ret) { pr_err("%s: ADM open timedout for port_id: 0x%x for [0x%x]\n", __func__, tmp_port, port_id); + +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (AFE_PORT_ID_USB_RX == port_id) + is_usb_timeout = true; +#endif + return -EINVAL; } else if (atomic_read(&this_adm.copp.stat [port_idx][copp_idx]) > 0) { @@ -3227,6 +3344,9 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, } } atomic_inc(&this_adm.copp.cnt[port_idx][copp_idx]); +#ifdef CONFIG_MSM_CSPL_V2 + crus_qdsp_port_start(port_id, copp_idx); +#endif return copp_idx; } EXPORT_SYMBOL(adm_open); @@ -3573,6 +3693,12 @@ int adm_close(int port_id, int perf_mode, int copp_idx) int ret = 0, port_idx; int copp_id = RESET_COPP_ID; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + int usb_copp_id = RESET_COPP_ID; + int usb_copp_idx = 0; + struct apr_hdr usb_close; +#endif + pr_debug("%s: port_id=0x%x perf_mode: %d copp_idx: %d\n", __func__, port_id, perf_mode, copp_idx); @@ -3639,6 +3765,56 @@ int adm_close(int port_id, int perf_mode, int copp_idx) ADM_MEM_MAP_INDEX_SOURCE_TRACKING], 0); } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (close_usb) { + for (usb_copp_idx = 0; usb_copp_idx < 8; usb_copp_idx++) { + usb_copp_id = adm_get_copp_id(IDX_AFE_PORT_ID_USB_RX, usb_copp_idx); + + if (usb_copp_id == RESET_COPP_ID) + continue; + + usb_close.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + usb_close.pkt_size = sizeof(usb_close); + usb_close.src_svc = APR_SVC_ADM; + usb_close.src_domain = APR_DOMAIN_APPS; + usb_close.src_port = AFE_PORT_ID_USB_RX; + usb_close.dest_svc = APR_SVC_ADM; + usb_close.dest_domain = APR_DOMAIN_ADSP; + usb_close.dest_port = usb_copp_id; + usb_close.token = IDX_AFE_PORT_ID_USB_RX << 16 | usb_copp_idx; + usb_close.opcode = ADM_CMD_DEVICE_CLOSE_V5; + + atomic_set(&this_adm.copp.id[IDX_AFE_PORT_ID_USB_RX][usb_copp_idx], + RESET_COPP_ID); + atomic_set(&this_adm.copp.cnt[IDX_AFE_PORT_ID_USB_RX][usb_copp_idx], 0); + atomic_set(&this_adm.copp.topology[IDX_AFE_PORT_ID_USB_RX][usb_copp_idx], 0); + atomic_set(&this_adm.copp.mode[IDX_AFE_PORT_ID_USB_RX][usb_copp_idx], 0); + atomic_set(&this_adm.copp.stat[IDX_AFE_PORT_ID_USB_RX][usb_copp_idx], -1); + atomic_set(&this_adm.copp.rate[IDX_AFE_PORT_ID_USB_RX][usb_copp_idx], 0); + atomic_set(&this_adm.copp.channels[IDX_AFE_PORT_ID_USB_RX][usb_copp_idx], 0); + atomic_set(&this_adm.copp.bit_width[IDX_AFE_PORT_ID_USB_RX][usb_copp_idx], 0); + atomic_set(&this_adm.copp.app_type[IDX_AFE_PORT_ID_USB_RX][usb_copp_idx], 0); + + clear_bit(ADM_STATUS_CALIBRATION_REQUIRED, + (void *)&this_adm.copp.adm_status[IDX_AFE_PORT_ID_USB_RX][usb_copp_idx]); + + ret = apr_send_pkt(this_adm.apr, (uint32_t *)&usb_close); + if (ret < 0) + pr_err("%s: ADM close failed %d\n", __func__, ret); + } + + close_usb = false; + + if (AFE_PORT_ID_USB_RX == port_id) { + if (perf_mode != ULTRA_LOW_LATENCY_PCM_MODE) + rtac_remove_adm_device(port_id, copp_id); + return 0; + } + } +#endif + close.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); @@ -3700,6 +3876,10 @@ int adm_close(int port_id, int perf_mode, int copp_idx) if (port_id == this_adm.ffecns_port_id) this_adm.ffecns_port_id = -1; +#ifdef CONFIG_MSM_CSPL_V2 + crus_qdsp_port_close(port_id, copp_idx); +#endif + return 0; } EXPORT_SYMBOL(adm_close); diff --git a/techpack/audio/dsp/q6afe.c b/techpack/audio/dsp/q6afe.c index 48b89b853c13..29dc411afc01 100644 --- a/techpack/audio/dsp/q6afe.c +++ b/techpack/audio/dsp/q6afe.c @@ -19,10 +19,47 @@ #include #include #include +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#include +#endif +/* for mius start */ +#ifdef CONFIG_US_PROXIMITY +#include +#endif +/* for mius end */ #include #include "adsp_err.h" #include "q6afecal-hwdep.h" +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI +#include "../asoc/codecs/tfa98xx/inc/tfa_platform_interface_definition.h" +#endif + +#ifdef CONFIG_MSM_CSPL +#include +#endif + +#ifdef CONFIG_MSM_CSPL_V2 +#include +#endif + +#ifdef CONFIG_TAS25XX_ALGO +#include +#ifdef INSTANCE_ID_0 /*APR Version 3*/ +static int32_t tas_smartamp_algo_callback(uint32_t opcode, uint32_t *payload, + uint32_t payload_size); +#else /*APR Version 2*/ +static int32_t tas_smartamp_algo_callback(uint32_t *payload, + uint32_t payload_size); +#endif /*INSTANCE_ID_0*/ +#endif /*CONFIG_TAS25XX_ALGO*/ + +#ifdef AUDIO_FORCE_RESTART_ADSP +#include +#define ADSP_ERR_LIMITED_COUNT (3) +static int err_count = 0; +#endif + #define WAKELOCK_TIMEOUT 5000 enum { AFE_COMMON_RX_CAL = 0, @@ -146,6 +183,9 @@ struct afe_ctl { int set_custom_topology; int dev_acdb_id[AFE_MAX_PORTS]; routing_cb rt_cb; +#ifdef CONFIG_TAS25XX_ALGO + struct afe_smartamp_calib_get_resp tas_calib_data; +#endif /*CONFIG_TAS25XX_ALGO*/ struct audio_uevent_data *uevent_data; /* cal info for AFE */ struct afe_fw_info *fw_data; @@ -153,6 +193,10 @@ struct afe_ctl { struct vad_config vad_cfg[AFE_MAX_PORTS]; struct work_struct afe_dc_work; struct notifier_block event_notifier; +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + struct rtac_cal_block_data tfa_cal; + atomic_t tfa_state; +#endif /*CONFIG_SND_SOC_TFA9874_FOR_DAVI*/ /* FTM spk params */ uint32_t initial_cal; uint32_t v_vali_flag; @@ -177,6 +221,17 @@ static int afe_get_cal_hw_delay(int32_t path, struct audio_cal_hw_delay_entry *entry); static int remap_cal_data(struct cal_block_data *cal_block, int cal_index); +#ifdef CONFIG_MSM_CSPL +struct afe_cspl_state cspl_afe = { + .apr= &this_afe.apr, + .status= &this_afe.status, + .state= &this_afe.state, + .wait= this_afe.wait, + .timeout_ms= TIMEOUT_MS, +}; +EXPORT_SYMBOL(cspl_afe); +#endif + int afe_get_spk_initial_cal(void) { return this_afe.initial_cal; @@ -282,8 +337,10 @@ static void av_dev_drift_afe_cb_handler(uint32_t opcode, uint32_t *payload, uint32_t payload_size) { u32 param_id; +#if !defined(CONFIG_MACH_XIAOMI_SM8150) || defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) size_t expected_size = sizeof(u32) + sizeof(struct afe_param_id_dev_timing_stats); +#endif /* Get param ID depending on command type */ param_id = (opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ? payload[3] : @@ -295,12 +352,14 @@ static void av_dev_drift_afe_cb_handler(uint32_t opcode, uint32_t *payload, switch (opcode) { case AFE_PORT_CMDRSP_GET_PARAM_V2: +#if !defined(CONFIG_MACH_XIAOMI_SM8150) || defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) expected_size += sizeof(struct param_hdr_v1); if (payload_size < expected_size) { pr_err("%s: Error: received size %d, expected size %zu\n", __func__, payload_size, expected_size); return; } +#endif /* Repack response to add IID */ this_afe.av_dev_drift_resp.status = payload[0]; this_afe.av_dev_drift_resp.pdata.module_id = payload[1]; @@ -311,12 +370,14 @@ static void av_dev_drift_afe_cb_handler(uint32_t opcode, uint32_t *payload, sizeof(struct afe_param_id_dev_timing_stats)); break; case AFE_PORT_CMDRSP_GET_PARAM_V3: +#if !defined(CONFIG_MACH_XIAOMI_SM8150) || defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) expected_size += sizeof(struct param_hdr_v3); if (payload_size < expected_size) { pr_err("%s: Error: received size %d, expected size %zu\n", __func__, payload_size, expected_size); return; } +#endif memcpy(&this_afe.av_dev_drift_resp, payload, sizeof(this_afe.av_dev_drift_resp)); break; @@ -347,11 +408,13 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, /* Set command specific details */ switch (opcode) { case AFE_PORT_CMDRSP_GET_PARAM_V2: +#if !(defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) if (payload_size < (5 * sizeof(uint32_t))) { pr_err("%s: Error: size %d is less than expected\n", __func__, payload_size); return -EINVAL; } +#endif expected_size += sizeof(struct param_hdr_v1); param_hdr.module_id = payload[1]; param_hdr.instance_id = INSTANCE_ID_0; @@ -360,11 +423,13 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, data_start = &payload[4]; break; case AFE_PORT_CMDRSP_GET_PARAM_V3: +#if !defined(CONFIG_MACH_XIAOMI_SM8150) || (defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU)) if (payload_size < (6 * sizeof(uint32_t))) { pr_err("%s: Error: size %d is less than expected\n", __func__, payload_size); return -EINVAL; } +#endif expected_size += sizeof(struct param_hdr_v3); if (payload_size < expected_size) { pr_err("%s: Error: size %d is less than expected\n", @@ -584,7 +649,23 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) { uint32_t *payload = data->payload; uint32_t param_id; +#ifndef CONFIG_MACH_XIAOMI_SM8150 uint32_t param_id_pos = 0; +#endif + +#ifdef CONFIG_MSM_CSPL + if (crus_afe_callback(data->payload, data->payload_size) == 0) { + return 0; + } +#endif + +#ifdef CONFIG_MSM_CSPL_V2 + if (crus_afe_callback(data->opcode, data->payload, data->payload_size) == 0){ + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + return 0; + } +#endif if (!payload || (data->token >= AFE_MAX_PORTS)) { pr_err("%s: Error: size %d payload %pK token %d\n", @@ -597,6 +678,11 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) data->payload_size)) return 0; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + param_id = (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ? + payload[3] : + payload[2]; +#else if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) param_id_pos = 4; else @@ -609,19 +695,69 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) __func__, data->payload_size); return -EINVAL; } +#endif if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) { av_dev_drift_afe_cb_handler(data->opcode, data->payload, data->payload_size); } else { +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + if (atomic_read(&this_afe.tfa_state) == 1 && + data->payload_size == sizeof(uint32_t)) { + + atomic_set(&this_afe.status, payload[0]); + if (payload[0]) + atomic_set(&this_afe.state, -1); + else + atomic_set(&this_afe.state, 0); + + atomic_set(&this_afe.tfa_state, 0); + wake_up(&this_afe.wait[data->token]); + + return 0; + } +#endif /*CONFIG_SND_SOC_TFA9874_FOR_DAVI*/ +#ifdef CONFIG_TAS25XX_ALGO + { + u32 *payload32 = data->payload; + pr_info ("TI-SmartPA: payload1 = 0x%x, 0x%x", payload32[0], payload32[1]); + + if((payload32[1] == AFE_SMARTAMP_MODULE_RX) || + (payload32[1] == AFE_SMARTAMP_MODULE_TX)) + { +#ifdef INSTANCE_ID_0 /*APR Version 3*/ + if (tas_smartamp_algo_callback(data->opcode, data->payload, data->payload_size)) + return -EINVAL; +#else /*APR Version 2*/ + if (tas_smartamp_algo_callback(data->payload, data->payload_size)) + return -EINVAL; +#endif /* INSTANCE_ID_0 */ + } else if (sp_make_afe_callback(data->opcode,data->payload, data->payload_size)) { + return -EINVAL; + } + } +#else if (sp_make_afe_callback(data->opcode, data->payload, data->payload_size)) return -EINVAL; +#endif } if (afe_token_is_valid(data->token)) wake_up(&this_afe.wait[data->token]); else return -EINVAL; +/* for mius start */ +#ifdef CONFIG_US_PROXIMITY + } else if (data->opcode == MI_ULTRASOUND_OPCODE) { + if (NULL != data->payload) + { + printk(KERN_DEBUG "[MIUS] mi ultrasound afe afe cb"); + mius_process_apr_payload(data->payload); + } + else + pr_err("[EXPORT_SYMBOLLUS]: payload ptr is Invalid"); +#endif +/* for mius end */ } else if (data->opcode == AFE_EVENT_MBHC_DETECTION_SW_WA) { msm_aud_evt_notifier_call_chain(SWR_WAKE_IRQ_EVENT, NULL); } else if (data->opcode == @@ -634,17 +770,38 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) atomic_set(&this_afe.state, 0); atomic_set(&this_afe.status, 0); wake_up(&this_afe.lpass_core_hw_wait); +#ifdef CONFIG_MACH_XIAOMI_SM8150 + } else if (data->opcode == ULTRASOUND_OPCODE) { + if (NULL != data->payload) + elliptic_process_apr_payload(data->payload); + else + pr_err("[EXPORT_SYMBOLLUS]: payload ptr is Invalid"); +#endif + /* for mius start */ +#ifdef CONFIG_US_PROXIMITY + } else if (data->opcode == MI_ULTRASOUND_OPCODE) { + if (NULL != data->payload) + { + printk(KERN_DEBUG "[MIUS] mi ultrasound afe afe cb"); + mius_process_apr_payload(data->payload); + } + else + pr_err("[EXPORT_SYMBOLLUS]: payload ptr is Invalid"); +#endif + /* for mius end */ } else if (data->payload_size) { uint32_t *payload; uint16_t port_id = 0; payload = data->payload; if (data->opcode == APR_BASIC_RSP_RESULT) { +#ifndef CONFIG_MACH_XIAOMI_SM8150 if (data->payload_size < (2 * sizeof(uint32_t))) { pr_err("%s: Error: size %d is less than expected\n", __func__, data->payload_size); return -EINVAL; } +#endif pr_debug("%s:opcode = 0x%x cmd = 0x%x status = 0x%x token=%d\n", __func__, data->opcode, payload[0], payload[1], data->token); @@ -1020,11 +1177,26 @@ static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait) &this_afe.status))); ret = adsp_err_get_lnx_err_code( atomic_read(&this_afe.status)); +#ifdef AUDIO_FORCE_RESTART_ADSP + if (atomic_read(&this_afe.status) == ADSP_ENEEDMORE) + err_count++; + else + err_count = 0; + + if (err_count >= ADSP_ERR_LIMITED_COUNT) { + err_count = 0; + pr_err("%s: DSP returned error more than limited, restart now !\n", __func__); + subsystem_restart("adsp"); + } +#endif } else { ret = 0; } } else { ret = 0; +#ifdef AUDIO_FORCE_RESTART_ADSP + err_count = 0; +#endif } } else if (ret == 0) { pr_err("%s: packet not transmitted\n", __func__); @@ -1037,6 +1209,21 @@ static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait) return ret; } +#ifdef CONFIG_MSM_CSPL +int afe_apr_send_pkt_crus(void *data, int index, int set) +{ + pr_info("[CSPL] %s: index = %d, set=%d, data = %p\n", + __func__, index, set, data); + + if (set) + return afe_apr_send_pkt(data, &this_afe.wait[index]); + else /* get */ + return afe_apr_send_pkt(data, 0); +} + +EXPORT_SYMBOL(afe_apr_send_pkt_crus); +#endif + /* This function shouldn't be called directly. Instead call q6afe_set_params. */ static int q6afe_set_params_v2(u16 port_id, int index, struct mem_mapping_hdr *mem_hdr, @@ -1697,6 +1884,15 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, case AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG: param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; break; +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + case AFE_PARAM_ID_TFADSP_RX_CFG: + case AFE_PARAM_ID_TFADSP_RX_SET_BYPASS: + param_info.module_id = AFE_MODULE_ID_TFADSP_RX; + break; + case AFE_PARAM_ID_TFADSP_TX_SET_ENABLE: + param_info.module_id = AFE_MODULE_ID_TFADSP_TX; + break; +#endif /*CONFIG_SND_SOC_TFA9874_FOR_DAVI*/ default: pr_err("%s: default case 0x%x\n", __func__, param_id); goto fail_cmd; @@ -1765,6 +1961,30 @@ static int afe_spkr_prot_reg_event_cfg(u16 port_id) return ret; } +#ifdef CONFIG_MACH_XIAOMI_SM8150 +afe_ultrasound_state_t elus_afe = { + .ptr_apr= &this_afe.apr, + .ptr_status= &this_afe.status, + .ptr_state= &this_afe.state, + .ptr_wait= this_afe.wait, + .timeout_ms= TIMEOUT_MS, +}; +EXPORT_SYMBOL(elus_afe); +#endif + +/* for mius start */ +#ifdef CONFIG_US_PROXIMITY +afe_mi_ultrasound_state_t mius_afe = { + .ptr_apr= &this_afe.apr, + .ptr_status= &this_afe.status, + .ptr_state= &this_afe.state, + .ptr_wait= this_afe.wait, + .timeout_ms= TIMEOUT_MS, +}; +EXPORT_SYMBOL(mius_afe); +#endif +/* for mius end */ + static void afe_send_cal_spkr_prot_tx(int port_id) { union afe_spkr_prot_config afe_spk_config; @@ -1960,6 +2180,110 @@ static void afe_send_cal_spkr_prot_rx(int port_id) return; } +#ifdef CONFIG_MSM_CSPL_V2 +static int crus_cb_buffer[CRUS_BUF_SIZE]; +int crus_afe_callback(uint32_t opcode, void* payload, int size) +{ + uint32_t* payload32 = payload; + + pr_debug("%s: module=0x%x size = %d\n", __func__, + (int)payload32[1], size); + + if (payload32[1]!= CIRRUS_SP) + return -EINVAL; + + if (size > CRUS_BUF_SIZE*sizeof(int)) { + pr_err("%s: module=0x%x, size(%d) > buf(%d), error!\n", + __func__,(int)payload32[1], size, + CRUS_BUF_SIZE*sizeof(int)); + return -EINVAL; + } + + memset(crus_cb_buffer, 0, CRUS_BUF_SIZE*sizeof(int)); + if(opcode==AFE_PORT_CMDRSP_GET_PARAM_V2) { + memcpy(crus_cb_buffer, &payload32[4], size); + } else if(opcode==AFE_PORT_CMDRSP_GET_PARAM_V3) { + memcpy(crus_cb_buffer, &payload32[5], size); + } else { + pr_info("%s:opcode %d no surport!\n",__func__, opcode); + memcpy(crus_cb_buffer, &payload32[5], size); + } + + atomic_set(&this_afe.state, 0); + + return 0; +} + +int crus_afe_get_params(u16 port_id, uint32_t module, uint32_t param_id, + void* data, int size) { + struct param_hdr_v3 param_hdr; + int ret = -EINVAL; + + //mutex_lock(&this_afe.afe_cmd_lock); + pr_info("%s: enter ++, size=%d; module = 0x%08x, port = 0x%04x, param = 0x%08x\n", + __func__, size, module, port_id, param_id); + + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = module; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = param_id; + param_hdr.param_size = size; + + ret = q6afe_get_params(port_id, NULL, ¶m_hdr); + if (ret) { + pr_err("%s: Failed to get CSPL data\n", __func__); + goto done; + } + + memcpy((u8 *)data, crus_cb_buffer, size); + ret = 0; +done: + //mutex_unlock(&this_afe.afe_cmd_lock); + pr_info("%s: exit --\n", __func__); + return ret; +} +EXPORT_SYMBOL(crus_afe_get_params); +int crus_afe_set_params(u16 port_id, uint32_t module_id, uint32_t param_id, + void* data, int size) +{ + int ret = 0; + struct param_hdr_v3 param_hdr; + + + //mutex_lock(&this_afe.afe_cmd_lock); + pr_info("%s: enter ++; module = 0x%08x, port = 0x%04x, param = 0x%08x\n", + __func__, module_id, port_id, param_id); + + memset(¶m_hdr, 0, sizeof(param_hdr)); + + /* Set stream index */ + param_hdr.module_id = module_id; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = param_id; + param_hdr.param_size = size; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) data); + if (ret) { + pr_err("%s: Failed to set cmd duration param, err %d\n", + __func__, ret); + goto fail_cmd; + } + + //mutex_unlock(&this_afe.afe_cmd_lock); + ret = 0; +fail_cmd: + pr_debug("%s: param_id = 0x%x ret = %d\n", __func__, + param_id, ret); + pr_info("%s: exit --\n", __func__); + return ret; + +} +EXPORT_SYMBOL(crus_afe_set_params); +#endif + static int afe_send_hw_delay(u16 port_id, u32 rate) { struct audio_cal_hw_delay_entry delay_entry; @@ -4408,6 +4732,14 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, } ret = afe_send_cmd_port_start(port_id); +#ifdef CONFIG_MSM_CSPL + if (ret == 0) + crus_afe_port_start(port_id); +#elif defined(CONFIG_MSM_CSPL_V2) + if (ret == 0) + crus_qdsp_port_start(port_id, -1); +#endif + fail_cmd: mutex_unlock(&this_afe.afe_cmd_lock); return ret; @@ -5129,6 +5461,386 @@ int afe_loopback_gain(u16 port_id, u16 volume) } EXPORT_SYMBOL(afe_loopback_gain); +#ifdef CONFIG_TAS25XX_ALGO +/*For DC Detection*/ +void (*tas256x_sw_reset)(void *data); +dc_detection_data_t *s_dc_detect = NULL; +void register_tas256x_reset_func(void *fptr, dc_detection_data_t* data) +{ + pr_err("[TI-SmartPA:%s] ", __func__); + tas256x_sw_reset = fptr; + s_dc_detect = data; +} + +EXPORT_SYMBOL(register_tas256x_reset_func); +#ifdef INSTANCE_ID_0 /* APR Version 3 */ +static int32_t tas_smartamp_algo_callback(uint32_t opcode, uint32_t *payload, + uint32_t payload_size) +{ + struct param_hdr_v3 param_hdr; + u32 *data_dest = NULL; + u32 *data_start = NULL; + + pr_debug("[TI-SmartPA:%s] ", __func__); + memset(¶m_hdr, 0, sizeof(param_hdr)); + switch (opcode) { + case AFE_PORT_CMDRSP_GET_PARAM_V2: + param_hdr.module_id = payload[1]; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = payload[2]; + param_hdr.param_size = payload[3]; + data_start = &payload[4]; + break; + case AFE_PORT_CMDRSP_GET_PARAM_V3: + memcpy(¶m_hdr, &payload[1], sizeof(struct param_hdr_v3)); + data_start = &payload[5]; + break; + default: + pr_err("[TI-SmartPA:%s] Unrecognized command %d\n", __func__, opcode); + return -EINVAL; + } + data_dest = (u32 *) &this_afe.tas_calib_data; + data_dest[0] = payload[0]; + memcpy(&data_dest[1], ¶m_hdr, sizeof(struct param_hdr_v3)); + memcpy(&data_dest[5], data_start, param_hdr.param_size); + if (param_hdr.param_id == CAPI_V2_TAS_SA_DC_DETECT) { + pr_err("[TI-SmartPA:%s] Detected DC, Calling TAS256X Software Reset \n", __func__); + s_dc_detect->channel = this_afe.tas_calib_data.res_cfg.payload[0]; + tas256x_sw_reset(s_dc_detect); + } + if (!data_dest[0]) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("[TI-SmartPA:%s] status: %d", __func__, data_dest[0]); + atomic_set(&this_afe.state, -1); + } + return 0; +} + +int afe_tas_smartamp_get_calib_data(uint32_t module_id, uint32_t param_id, + int32_t length, uint8_t *data) +{ + int ret = -EINVAL; + struct param_hdr_v3 param_hdr; + uint32_t port = 0x0; + + if (!data || length <= 0) { + pr_err("[TI-SmartPA:%s] Invalid params, length: %d\n", + __func__, length); + goto fail_cmd; + } + + pr_info("[TI-SmartPA:%s] module id : 0x%x ", __func__, module_id); + if (module_id == AFE_SMARTAMP_MODULE_RX) { + port = TAS_RX_PORT; + } else if (module_id == AFE_SMARTAMP_MODULE_TX) { + port = TAS_TX_PORT; + } else { + pr_err("[TI-SmartPA:%s] Invalid module id 0x%x\n", __func__, module_id); + goto fail_cmd; + } + + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = module_id; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = param_id; + param_hdr.param_size = sizeof(struct afe_smartamp_get_calib); + ret = q6afe_get_params(port, NULL, ¶m_hdr); + if (ret < 0) { + pr_err("[TI-SmartPA:%s] get param port 0x%x param id[0x%x]failed %d\n", + __func__, port, param_hdr.param_id, ret); + goto fail_cmd; + } + + memcpy(data, &this_afe.tas_calib_data.res_cfg, length); + + ret = 0; +fail_cmd: + return ret; +} +EXPORT_SYMBOL(afe_tas_smartamp_get_calib_data); + +int afe_tas_smartamp_set_calib_data(uint32_t module_id, uint32_t param_id, + int32_t length, uint8_t* data) +{ + int ret = -EINVAL; + uint32_t port = 0x0; + struct param_hdr_v3 param_hdr; + + u8 *packed_param_data = NULL; + u32 packed_param_size = 0; + u32 single_param_size = 0; + pr_info("[TI-SmartPA:%s] length: %d\n", __func__, length); + if (!data || (length < 0)) { + pr_err("[TI-SmartPA:%s] Invalid params\n", __func__); + return ret; + } + + pr_info("[TI-SmartPA:%s] module id : 0x%x \n", __func__, module_id); + if (module_id == AFE_SMARTAMP_MODULE_RX) { + port = TAS_RX_PORT; + } else if (module_id == AFE_SMARTAMP_MODULE_TX) { + port = TAS_TX_PORT; + } else { + pr_err("[TI-SmartPA:%s] Invalid module id 0x%x\n", __func__, module_id); + return ret; + } + packed_param_size = sizeof(param_hdr) + length; + packed_param_data = kzalloc(packed_param_size, GFP_KERNEL); + if (!packed_param_data) + return -ENOMEM; + packed_param_size = 0; + param_hdr.module_id = module_id; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = param_id; + param_hdr.param_size = length; + ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, + (u8 *) data, &single_param_size); + if (ret) { + pr_err("[TI-SmartPA:%s] Failed to pack param data, error %d\n", __func__, + ret); + goto done; + } + packed_param_size += single_param_size; + ret = q6afe_set_params(port, q6audio_get_port_index(port), + NULL, packed_param_data, packed_param_size); +done: + kfree(packed_param_data); + return ret; +} +EXPORT_SYMBOL(afe_tas_smartamp_set_calib_data); + +#else /* APR Version 2 */ +static int32_t tas_smartamp_algo_callback(uint32_t *payload, uint32_t payload_size) +{ + struct afe_smartamp_calib_get_resp *resp = + (struct afe_smartamp_calib_get_resp *) payload; + + pr_debug("[TI-SmartPA:%s] callback\n", __func__); + + if (!(&(resp->pdata))) { + pr_err("[TI-SmartPA:%s] Error: resp pdata is NULL", __func__); + return -EINVAL; + } + + memcpy(&this_afe.tas_calib_data, payload, + sizeof(this_afe.tas_calib_data)); + + pr_debug("[TI-SmartPA:%s] callback, 0x%x\n", __func__, resp->pdata.param_id); + + if(resp->pdata.param_id == CAPI_V2_TAS_SA_DC_DETECT) { + s_dc_detect->channel = resp->res_cfg.payload[0]; + pr_err("[TI-SmartPA:%s] Detected DC, Calling TAS256X Software Reset Channel-%s\n", __func__, + (s_dc_detect->channel == 0)?"Left":"Right"); + tas256x_sw_reset(s_dc_detect); + } + if (!this_afe.tas_calib_data.status) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("[TI-SmartPA:%s] calib resp status: %d", __func__, + this_afe.tas_calib_data.status); + atomic_set(&this_afe.state, -1); + } + + return 0; +} + +/* +* data is writable memroy +* length is the max size of the data +* retuns number of bytes returned by the algorithm +* -ve error number in case of failure. +*/ +int afe_tas_smartamp_get_calib_data(uint32_t module_id, uint32_t param_id, + int32_t length, uint8_t *data) +{ + int ret = -EINVAL; + int index = 0, port_id = TAS_RX_PORT; + struct afe_smartamp_get_calib calib_resp_o; + struct afe_smartamp_get_calib* calib_resp = &calib_resp_o; + + if (!data || (length <= 0)) { + pr_err("[TI-SmartPA: %s] Invalid params\n", __func__); + goto fail_cmd; + } + if ((q6audio_validate_port(port_id) < 0)) { + pr_err("%s invalid port %d\n", __func__, port_id); + goto fail_cmd; + } + + index = q6audio_get_port_index(port_id); + + memset (calib_resp, 0, sizeof(*calib_resp)); + + //header + calib_resp->hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + calib_resp->hdr.src_svc = APR_SVC_AFE; + calib_resp->hdr.src_domain = APR_DOMAIN_APPS; + calib_resp->hdr.dest_svc = APR_SVC_AFE; + calib_resp->hdr.dest_domain = APR_DOMAIN_ADSP; + calib_resp->hdr.pkt_size = sizeof(*calib_resp); + calib_resp->hdr.src_port = 0; + calib_resp->hdr.dest_port = 0; + calib_resp->hdr.token = index; + calib_resp->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; + + //parameter + calib_resp->get_param.mem_map_handle = 0; + calib_resp->get_param.module_id = module_id; + calib_resp->get_param.param_id = param_id; + calib_resp->get_param.payload_address_lsw = 0; + calib_resp->get_param.payload_address_msw = 0; + calib_resp->get_param.payload_size = sizeof(*calib_resp) + - sizeof(calib_resp->hdr) + - sizeof(calib_resp->get_param); + calib_resp->get_param.port_id = q6audio_get_port_id(port_id); + + //data + calib_resp->pdata.module_id = module_id; + calib_resp->pdata.param_id = param_id; + calib_resp->pdata.param_size = sizeof(calib_resp->res_cfg); + calib_resp->pdata.reserved = 0; + atomic_set(&this_afe.state, 1); + + ret = apr_send_pkt(this_afe.apr, (uint32_t *)calib_resp); + + if (ret < 0) { + pr_err("[TI-SmartPA %s]: get param port %d param id[0x%x]failed", + __func__, port_id, calib_resp->get_param.param_id); + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS * 5)); + if (!ret) { + pr_err("[TI-SmartPA %s]: wait_event timeout", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) != 0) { + pr_err("[TI-SmartPA %s]: config cmd failed", __func__); + ret = -EINVAL; + goto fail_cmd; + } + + if (length <= sizeof (this_afe.tas_calib_data.res_cfg)) { + memcpy(data, &this_afe.tas_calib_data.res_cfg, length); + ret = 0; + } else { + ret = -EINVAL; + memcpy(data, &this_afe.tas_calib_data.res_cfg, length); + } + pr_info("[TI-SmartPA: %s] ret=%d", __func__, ret); + +fail_cmd: + return ret; +} +EXPORT_SYMBOL(afe_tas_smartamp_get_calib_data); + +/* +* length -> length in bytes of 'data' +*/ +int afe_tas_smartamp_set_calib_data(uint32_t module_id, uint32_t param_id, + int32_t length, uint8_t* data) +{ + int ret = -EINVAL; + int index = 0 , port_id = 0; + struct afe_smartamp_config_command configV; + struct afe_smartamp_config_command *config; + + + config = &configV; + memset(config, 0 , sizeof(struct afe_smartamp_config_command)); + if (!data) { + pr_err("[TI-SmartPA:%s] Invalid params\n", __func__); + goto fail_cmd; + } + + if (module_id == AFE_SMARTAMP_MODULE_RX){ + port_id = TAS_RX_PORT; + } else if(module_id == AFE_SMARTAMP_MODULE_TX) { + port_id = TAS_TX_PORT; + } else { + pr_err("[TI-SmartPA: %s] unknown module id %d", __func__, module_id); + } + + if ((q6audio_validate_port(port_id) < 0)) { + pr_err("[TI-SmartPA: %s] invalid port %d", __func__, port_id); + goto fail_cmd; + } + + + index = q6audio_get_port_index(port_id); + + //header + config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config->hdr.pkt_size = sizeof(struct afe_smartamp_config_command) + - sizeof(struct afe_smartamp_get_set_params_t) + + length; + config->hdr.src_port = 0; + config->hdr.dest_port = 0; + config->hdr.token = index; + config->hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + + //param + config->param.port_id = q6audio_get_port_id(port_id); + config->param.payload_size = sizeof(struct afe_smartamp_config_command) + - sizeof(struct apr_hdr) + - sizeof(struct afe_port_cmd_set_param_v2) + - sizeof(struct afe_smartamp_get_set_params_t) + + length; + + //data + config->pdata.module_id = module_id; + config->pdata.param_id = param_id; + config->pdata.param_size = length; //should be same as + /* + sizeof(struct afe_smartamp_config_command) + - sizeof(struct apr_hdr) + - sizeof(struct afe_port_cmd_set_param_v2) + - sizeof(struct afe_port_param_data_v2); + */ + + memcpy(config->prot_config.payload, data, length); + atomic_set(&this_afe.state, 1); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) config); + + + if (ret < 0) { + pr_err("[TI-SmartPA %s]: Setting param for port %d param[0x%x]failed\n", + __func__, port_id, param_id); + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS*10)); + if (!ret) { + pr_err("[TI-SmartPA %s]: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) != 0) { + pr_err("[TI-SmartPA %s]: config cmd failed\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + ret = 0; + +fail_cmd: + pr_info("[TI-SmartPA %s]: config->pdata.param_id %x status %d\n", + __func__, config->pdata.param_id, ret); + return ret; + +} +EXPORT_SYMBOL(afe_tas_smartamp_set_calib_data); +#endif /* INSTANCE_ID_0 */ +#endif /*CONFIG_TAS25XX_ALGO*/ + int afe_pseudo_port_start_nowait(u16 port_id) { struct afe_pseudoport_start_command start; @@ -7118,6 +7830,12 @@ int afe_close(int port_id) if (ret) pr_err("%s: AFE close failed %d\n", __func__, ret); +#ifdef CONFIG_MSM_CSPL + crus_afe_port_close(port_id); +#elif defined(CONFIG_MSM_CSPL_V2) + crus_qdsp_port_close(port_id, -1); +#endif + fail_cmd: mutex_unlock(&this_afe.afe_cmd_lock); return ret; @@ -8555,6 +9273,209 @@ static void afe_release_uevent_data(struct kobject *kobj) kfree(data); } +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI +int send_tfa_cal_apr(void *buf, int cmd_size, bool bRead) +{ + int32_t result, port_id = AFE_PORT_ID_TFADSP_RX; + uint32_t port_index = 0, payload_size = 0; + size_t len; + struct rtac_cal_block_data *tfa_cal = &(this_afe.tfa_cal); + struct mem_mapping_hdr mem_hdr; + struct param_hdr_v3 param_hdr; + + pr_debug("%s\n", __func__); + + memset(&mem_hdr, 0x00, sizeof(mem_hdr)); + memset(¶m_hdr, 0x00, sizeof(param_hdr)); + + if (0 == tfa_cal->map_data.dma_buf ) { + /*Minimal chunk size is 4K*/ + tfa_cal->map_data.map_size = SZ_4K; + result = msm_audio_ion_alloc(&(tfa_cal->map_data.dma_buf), + tfa_cal->map_data.map_size, + &(tfa_cal->cal_data.paddr), + &len, + &(tfa_cal->cal_data.kvaddr)); + if (result < 0) { + pr_err("%s: allocate buffer failed! ret = %d\n", + __func__, result); + goto err; + } + pr_debug("%s: paddr 0x%pK, kvaddr 0x%pK, map_size 0x%x\n", + __func__, + &tfa_cal->cal_data.paddr, + tfa_cal->cal_data.kvaddr, + tfa_cal->map_data.map_size); + } + + if (0 == tfa_cal->map_data.map_handle ) { + result = afe_map_rtac_block(tfa_cal); + if (result < 0) { + pr_err("%s: map buffer failed! ret = %d\n", + __func__, result); + goto err; + } + } + + port_index = q6audio_get_port_index(port_id); + if (port_index >= AFE_MAX_PORTS) { + pr_err("%s: Invalid AFE port = 0x%x\n", __func__, port_id); + goto err; + } + + if (cmd_size > (SZ_4K - sizeof(struct param_hdr_v3))) { + pr_err("%s: Invalid payload size = %d\n", __func__, cmd_size); + result = -EINVAL; + goto err; + } + + /* Pack message header with data */ + param_hdr.module_id = AFE_MODULE_ID_TFADSP_RX; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_size = cmd_size; + + if (!bRead) { + param_hdr.param_id = AFE_PARAM_ID_TFADSP_RX_CFG; + + q6common_pack_pp_params(tfa_cal->cal_data.kvaddr, + ¶m_hdr, + buf, + &payload_size); + tfa_cal->cal_data.size = payload_size; + } + else { + param_hdr.param_id = AFE_PARAM_ID_TFADSP_RX_GET_RESULT; + tfa_cal->cal_data.size = cmd_size + sizeof(struct param_hdr_v3) ; + } + + /*Send/Get package to/from ADSP*/ + mem_hdr.data_payload_addr_lsw = + lower_32_bits(tfa_cal->cal_data.paddr); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits(tfa_cal->cal_data.paddr); + mem_hdr.mem_map_handle = + tfa_cal->map_data.map_handle; + + pr_debug("%s: Sending tfa_cal port = 0x%x, cal size = %zd, cal addr = 0x%pK\n", + __func__, port_id, tfa_cal->cal_data.size, &tfa_cal->cal_data.paddr); + + result = afe_q6_interface_prepare(); + if (result != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, result); + goto err; + } + + if (!bRead) { + if (q6common_is_instance_id_supported()) + result = q6afe_set_params_v3(port_id, port_index, &mem_hdr, NULL, payload_size); + else + result = q6afe_set_params_v2(port_id, port_index, &mem_hdr, NULL, payload_size); + } else { + int8_t *resp = (int8_t *)tfa_cal->cal_data.kvaddr; + + atomic_set(&this_afe.tfa_state, 1); + if (q6common_is_instance_id_supported()){ + result = q6afe_get_params_v3(port_id, port_index, &mem_hdr, ¶m_hdr); + resp += sizeof(struct param_hdr_v3); + } + else { + result = q6afe_get_params_v2(port_id, port_index, &mem_hdr, ¶m_hdr); + resp += sizeof(struct param_hdr_v1); + } + + if (result) { + pr_err("%s: get response from port 0x%x failed %d\n", __func__, port_id, result); + goto err; + } + else { + /*Copy response data to command buffer*/ + memcpy(buf, resp, cmd_size); + } + } + +err: + return result; +} +EXPORT_SYMBOL(send_tfa_cal_apr); + +void send_tfa_cal_unmap_memory(void) +{ + int result = 0; + + if (this_afe.tfa_cal.map_data.map_handle) { + result = afe_unmap_rtac_block(&this_afe.tfa_cal.map_data.map_handle); + + /*Force to remap after unmap failed*/ + if (result) + this_afe.tfa_cal.map_data.map_handle = 0; + } +} +EXPORT_SYMBOL(send_tfa_cal_unmap_memory); + +int send_tfa_cal_in_band(void *buf, int cmd_size) +{ + union afe_spkr_prot_config afe_spk_config; + int32_t port_id = AFE_PORT_ID_TFADSP_RX; + + if (cmd_size > sizeof(afe_spk_config)) + return -EINVAL; + + memcpy(&afe_spk_config, buf, cmd_size); + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_TFADSP_RX_CFG, + &afe_spk_config)) { + pr_err("%s: AFE_PARAM_ID_TFADSP_RX_CFG failed\n", + __func__); + } + + return 0; +} +EXPORT_SYMBOL(send_tfa_cal_in_band); + +int send_tfa_cal_set_bypass(void *buf, int cmd_size) +{ + union afe_spkr_prot_config afe_spk_config; + int32_t port_id = AFE_PORT_ID_TFADSP_RX; + + if (cmd_size > sizeof(afe_spk_config)) + return -EINVAL; + + memcpy(&afe_spk_config, buf, cmd_size); + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_TFADSP_RX_SET_BYPASS, + &afe_spk_config)) { + pr_err("%s: AFE_PARAM_ID_TFADSP_RX_SET_BYPASS failed\n", + __func__); + } + + return 0; +} +EXPORT_SYMBOL(send_tfa_cal_set_bypass); + +int send_tfa_cal_set_tx_enable(void *buf, int cmd_size) +{ + union afe_spkr_prot_config afe_spk_config; + int32_t port_id = AFE_PORT_ID_TFADSP_TX; + + if (cmd_size > sizeof(afe_spk_config)) + return -EINVAL; + + memcpy(&afe_spk_config, buf, cmd_size); + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_TFADSP_TX_SET_ENABLE, + &afe_spk_config)) { + pr_err("%s: AFE_PARAM_ID_TFADSP_TX_SET_ENABLE failed\n", + __func__); + } + + return 0; +} +EXPORT_SYMBOL(send_tfa_cal_set_tx_enable); +#endif /*CONFIG_SND_SOC_TFA9874_FOR_DAVI*/ + int __init afe_init(void) { int i = 0, ret; @@ -8613,6 +9534,10 @@ int __init afe_init(void) void afe_exit(void) { +#ifdef CONFIG_SND_SOC_TFA9874_FOR_DAVI + afe_unmap_rtac_block(&this_afe.tfa_cal.map_data.map_handle); +#endif /*CONFIG_SND_SOC_TFA9874_FOR_DAVI*/ + if (this_afe.apr) { apr_reset(this_afe.apr); atomic_set(&this_afe.state, 0); diff --git a/techpack/audio/dsp/q6asm.c b/techpack/audio/dsp/q6asm.c index 6040e1ceade7..6ade0fdb7423 100644 --- a/techpack/audio/dsp/q6asm.c +++ b/techpack/audio/dsp/q6asm.c @@ -10839,6 +10839,14 @@ static int q6asm_get_asm_topology_apptype(struct q6asm_cal_info *cal_info) cal_info->app_type = ((struct audio_cal_info_asm_top *) cal_block->cal_info)->app_type; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + if (0 == cal_info->topology_id) { + cal_info->topology_id = 0x10c68;; + pr_err("%s: Correct using topology %d app_type %d\n", __func__, + cal_info->topology_id, cal_info->app_type); + } +#endif + cal_utils_mark_cal_used(cal_block); unlock: diff --git a/techpack/audio/dsp/q6audio-v2.c b/techpack/audio/dsp/q6audio-v2.c index 773cef67bb1f..d6081bc78584 100644 --- a/techpack/audio/dsp/q6audio-v2.c +++ b/techpack/audio/dsp/q6audio-v2.c @@ -352,6 +352,10 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_6; case AFE_PORT_ID_RX_CODEC_DMA_RX_7: return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7; +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case AFE_PORT_ID_PSEUDOPORT_01: + return IDX_AFE_PORT_ID_PSEUDOPORT_01; +#endif case RT_PROXY_PORT_002_RX: return IDX_RT_PROXY_PORT_002_RX; case RT_PROXY_PORT_002_TX: @@ -1091,6 +1095,9 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_TX_CODEC_DMA_TX_5: case AFE_PORT_ID_RX_CODEC_DMA_RX_6: case AFE_PORT_ID_RX_CODEC_DMA_RX_7: +#ifdef CONFIG_MACH_XIAOMI_SM8150 + case AFE_PORT_ID_PSEUDOPORT_01: +#endif case RT_PROXY_PORT_002_RX: case RT_PROXY_PORT_002_TX: { diff --git a/techpack/audio/dsp/q6voice.c b/techpack/audio/dsp/q6voice.c index d9b444715f9e..b8b1cd3a707d 100644 --- a/techpack/audio/dsp/q6voice.c +++ b/techpack/audio/dsp/q6voice.c @@ -24,7 +24,11 @@ #include "adsp_err.h" #include +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) +#define TIMEOUT_MS 1000 +#else #define TIMEOUT_MS 300 +#endif #define CMD_STATUS_SUCCESS 0 diff --git a/techpack/audio/include/dsp/apr_audio-v2.h b/techpack/audio/include/dsp/apr_audio-v2.h index 6a4a5bc95ed6..2b0626cdc7c0 100644 --- a/techpack/audio/include/dsp/apr_audio-v2.h +++ b/techpack/audio/include/dsp/apr_audio-v2.h @@ -5085,6 +5085,9 @@ struct afe_param_id_lpass_core_shared_clk_cfg { #define ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX 0x10015002 #define ADM_CMD_COPP_OPEN_TOPOLOGY_ID_AUDIOSPHERE 0x10028000 #define VPM_TX_DM_FLUENCE_EF_COPP_TOPOLOGY 0x10000005 +#ifdef CONFIG_MACH_XIAOMI_SM8150 +#define ADM_TOPOLOGY_ID_AUDIO_RX_FVSAM 0x1000FFF0 +#endif /* Memory map regions command payload used by the * #ASM_CMD_SHARED_MEM_MAP_REGIONS ,#ADM_CMD_SHARED_MEM_MAP_REGIONS @@ -11381,7 +11384,7 @@ struct afe_clk_set { * for enable and disable clock. * "clk_freq_in_hz", "clk_attri", and "clk_root" * are ignored in disable clock case. - * @values  + * @values� * - 0 -- Disabled * - 1 -- Enabled @tablebulletend */ diff --git a/techpack/audio/include/dsp/q6afe-v2.h b/techpack/audio/include/dsp/q6afe-v2.h index 9ffbd110f4fb..1eda0371c795 100644 --- a/techpack/audio/include/dsp/q6afe-v2.h +++ b/techpack/audio/include/dsp/q6afe-v2.h @@ -265,6 +265,9 @@ enum { /* IDX 187 -> 188 */ IDX_AFE_PORT_ID_SENARY_PCM_RX, IDX_AFE_PORT_ID_SENARY_PCM_TX, +#ifdef CONFIG_MACH_XIAOMI_SM8150 + IDX_AFE_PORT_ID_PSEUDOPORT_01, +#endif /* IDX 189 -> 190 */ IDX_RT_PROXY_PORT_002_RX, IDX_RT_PROXY_PORT_002_TX, @@ -459,6 +462,13 @@ int afe_get_sp_rx_tmax_xmax_logging_data( u16 port_id); int afe_cal_init_hwdep(void *card); int afe_send_port_island_mode(u16 port_id); + +#ifdef CONFIG_MSM_CSPL +int afe_apr_send_pkt_crus(void *data, int index, int set); +int crus_afe_port_close(u16 port_id); +int crus_afe_port_start(u16 port_id); +#endif + int afe_send_cmd_wakeup_register(void *handle, bool enable); void afe_register_wakeup_irq_callback( void (*afe_cb_wakeup_irq)(void *handle)); diff --git a/techpack/audio/soc/pinctrl-lpi.c b/techpack/audio/soc/pinctrl-lpi.c index 5b0539944af3..900e0aa30b1a 100644 --- a/techpack/audio/soc/pinctrl-lpi.c +++ b/techpack/audio/soc/pinctrl-lpi.c @@ -487,6 +487,11 @@ static void lpi_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) unsigned int i; for (i = 0; i < chip->ngpio; i++, gpio++) { +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* skip lpi gpio 0~7 and 12 ~ 17 */ + if (i < 8 || (i > 11 && i < 18)) + continue; +#endif lpi_gpio_dbg_show_one(s, NULL, chip, i, gpio); seq_puts(s, "\n"); } diff --git a/techpack/audio/soc/swr-mstr-ctrl.c b/techpack/audio/soc/swr-mstr-ctrl.c index 838fd7d94592..945f7cd87f5b 100644 --- a/techpack/audio/soc/swr-mstr-ctrl.c +++ b/techpack/audio/soc/swr-mstr-ctrl.c @@ -1918,6 +1918,18 @@ static int swrm_probe(struct platform_device *pdev) goto err_pdata_fail; } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* Make inband tx interrupts as wakeup capable for slave irq */ + swrm->swr_tx_wakeup_capable = false; + if (of_property_read_bool(swrm->dev->of_node, + "qcom,swr-mstr-tx-wakeup-capable")) { + swrm->swr_tx_wakeup_capable = true; + irq_set_irq_wake(swrm->irq, 1); + } else + dev_dbg(swrm->dev, "%s: swrm tx wakeup capable not defined", + __func__); +#endif + for (i = 0; i < map_length; i++) { port_num = temp[3 * i]; port_type = temp[3 * i + 1]; @@ -2059,6 +2071,12 @@ static int swrm_probe(struct platform_device *pdev) &swrm_debug_ops); } +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + /* Make inband tx interrupts as wakeup capable for slave irq */ + if (swrm->master_id == MASTER_ID_TX) + irq_set_irq_wake(swrm->irq, 1); +#endif + ret = device_init_wakeup(swrm->dev, true); if (ret) { dev_err(swrm->dev, "Device wakeup init failed: %d\n", ret); diff --git a/techpack/audio/soc/swr-mstr-ctrl.h b/techpack/audio/soc/swr-mstr-ctrl.h index 76bdb3eb90f3..ff1481067c2d 100644 --- a/techpack/audio/soc/swr-mstr-ctrl.h +++ b/techpack/audio/soc/swr-mstr-ctrl.h @@ -173,6 +173,9 @@ struct swr_mstr_ctrl { int wlock_holders; u32 intr_mask; u32 swr_irq_wakeup_capable; +#if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) + bool swr_tx_wakeup_capable; +#endif }; #endif /* _SWR_WCD_CTRL_H */ From 66cfba5521c5a6f6edffb63db75b082114f59e35 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Sat, 18 Nov 2023 14:54:27 +0100 Subject: [PATCH 106/226] arch: arm64: configs: xiaomi: Enable device-specific drivers Change-Id: I4dd54e21df54f5a104e8d86c0b0aab3baf0f382c Signed-off-by: firebird11 --- .../configs/vendor/xiaomi/andromeda.config | 13 ++++ .../configs/vendor/xiaomi/cepheus.config | 16 ++++ arch/arm64/configs/vendor/xiaomi/crux.config | 19 +++++ arch/arm64/configs/vendor/xiaomi/nabu.config | 15 ++++ .../configs/vendor/xiaomi/raphael.config | 7 ++ .../vendor/xiaomi/sm8150-common.config | 77 +++++++++++++++++++ arch/arm64/configs/vendor/xiaomi/vayu.config | 13 ++++ 7 files changed, 160 insertions(+) diff --git a/arch/arm64/configs/vendor/xiaomi/andromeda.config b/arch/arm64/configs/vendor/xiaomi/andromeda.config index 6981d04735d1..501339f6ed33 100644 --- a/arch/arm64/configs/vendor/xiaomi/andromeda.config +++ b/arch/arm64/configs/vendor/xiaomi/andromeda.config @@ -1,2 +1,15 @@ # Platform CONFIG_MACH_XIAOMI_ANDROMEDA=y + +# Audio +CONFIG_SND_SOC_CS35L41=y +CONFIG_MSM_CSPL=y + +# Camera +CONFIG_USE_ROHM_BU64753=y + +# Touchscreen +CONFIG_TOUCHSCREEN_ST_FTS_V521=y +CONFIG_FTS_FOD_AREA_REPORT=y +CONFIG_SECURE_TOUCH=y +CONFIG_I2C_BY_DMA=y diff --git a/arch/arm64/configs/vendor/xiaomi/cepheus.config b/arch/arm64/configs/vendor/xiaomi/cepheus.config index b237760c457f..600752df98aa 100644 --- a/arch/arm64/configs/vendor/xiaomi/cepheus.config +++ b/arch/arm64/configs/vendor/xiaomi/cepheus.config @@ -1,2 +1,18 @@ # Platform CONFIG_MACH_XIAOMI_CEPHEUS=y + +# Audio +CONFIG_SND_SOC_CS35L41=y +CONFIG_MSM_CSPL=y + +# Camera +CONFIG_VCM_AK7374=y + +# Power +CONFIG_IDT_P9220=y + +# Touchscreen +CONFIG_TOUCHSCREEN_ST_FTS_V521=y +CONFIG_FTS_FOD_AREA_REPORT=y +CONFIG_SECURE_TOUCH=y +CONFIG_I2C_BY_DMA=y diff --git a/arch/arm64/configs/vendor/xiaomi/crux.config b/arch/arm64/configs/vendor/xiaomi/crux.config index 0611ff82cdd4..9b0be13a4bcf 100644 --- a/arch/arm64/configs/vendor/xiaomi/crux.config +++ b/arch/arm64/configs/vendor/xiaomi/crux.config @@ -1,2 +1,21 @@ # Platform CONFIG_MACH_XIAOMI_CRUX=y + +# Audio +CONFIG_SND_SOC_CS35L41=y +CONFIG_MSM_CSPL=y + +# Camera +CONFIG_USE_ROHM_BU64753=y +CONFIG_VCM_AK7374=y + +# Power +CONFIG_RX1619=y +CONFIG_RX1619_TRIM=y +CONFIG_LN8282=y +CONFIG_IDT_P9220=y +CONFIG_HALO_7221=y + +# Touchscreen +CONFIG_TOUCHSCREEN_ST_FTS_V521=y +CONFIG_FTS_FOD_AREA_REPORT=y diff --git a/arch/arm64/configs/vendor/xiaomi/nabu.config b/arch/arm64/configs/vendor/xiaomi/nabu.config index 39bd6a435189..cea9413451d6 100644 --- a/arch/arm64/configs/vendor/xiaomi/nabu.config +++ b/arch/arm64/configs/vendor/xiaomi/nabu.config @@ -1,2 +1,17 @@ # Platform CONFIG_MACH_XIAOMI_NABU=y + +# Audio +CONFIG_SND_SOC_CS35L41_V2=y +CONFIG_MSM_CSPL_V2=y + +# Power +CONFIG_BATT_VERIFY_BY_DS28E16_NABU=y +CONFIG_ONEWIRE_GPIO_NABU=y +CONFIG_IDT_P9418=y +CONFIG_BQ2597X_CHARGE_PUMP=y +CONFIG_CHARGER_LN8000=y + +# Touchscreen +CONFIG_TOUCHSCREEN_NT36523_HOSTDL_SPI=y +CONFIG_TOUCHSCREEN_NVT_DEBUG_FS=y diff --git a/arch/arm64/configs/vendor/xiaomi/raphael.config b/arch/arm64/configs/vendor/xiaomi/raphael.config index 89de85dcf84d..a8db1f76d035 100644 --- a/arch/arm64/configs/vendor/xiaomi/raphael.config +++ b/arch/arm64/configs/vendor/xiaomi/raphael.config @@ -1,2 +1,9 @@ # Platform CONFIG_MACH_XIAOMI_RAPHAEL=y + +# Audio +CONFIG_SND_SOC_CS35L41=y +CONFIG_MSM_CSPL=y + +# Touchscreen +CONFIG_TOUCHSCREEN_GOODIX_GTX8=y diff --git a/arch/arm64/configs/vendor/xiaomi/sm8150-common.config b/arch/arm64/configs/vendor/xiaomi/sm8150-common.config index 78436de13ed3..610d5f699132 100644 --- a/arch/arm64/configs/vendor/xiaomi/sm8150-common.config +++ b/arch/arm64/configs/vendor/xiaomi/sm8150-common.config @@ -9,3 +9,80 @@ CONFIG_EXFAT_FS=y # EROFS CONFIG_EROFS_FS=y + +# pstore +CONFIG_CMDLINE="ramoops_memreserve=4M" +CONFIG_CMDLINE_EXTEND=y +CONFIG_PSTORE=y +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_PMSG=y +CONFIG_PSTORE_RAM=y +CONFIG_BLK_WBT=y +CONFIG_BLK_WBT_SQ=y +CONFIG_MTD=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_OOPS=y +CONFIG_MTD_BLOCK2MTD=y + +# Audio +CONFIG_SND_SOC_TAS256X=y +CONFIG_TAS256X_CODEC=y +CONFIG_TAS256X_REGMAP=y +CONFIG_TAS25XX_ALGO=y +CONFIG_SND_SOC_TAS2557=y +CONFIG_TAS2557_REGMAP=y +CONFIG_TAS2557_CODEC=y +CONFIG_TAS2557_MISC=y +CONFIG_SND_SOC_TFA9874=y + +# Backlight +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_KTZ8866=y + +# Camera motor +CONFIG_TI_DRV8846=y + +# Fingerprint +CONFIG_INPUT_FINGERPRINT=y +CONFIG_FINGERPRINT_FPC_TEE=y +CONFIG_FINGERPRINT_GOODIX_TA=y + +# Haptics +CONFIG_INPUT_AW8697_XM_HAPTIC=y + +# IR +CONFIG_IR_SPI=y +CONFIG_LIRC=y +CONFIG_RC_CORE=y +CONFIG_RC_DECODERS=y +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_DEVICES=y + +# Keyboard +CONFIG_XIAOMI_KEYBOARD=y + +# Power +# CONFIG_SMB1355_SLAVE_CHARGER is not set +# CONFIG_SMB1390_CHARGE_PUMP_PSY is not set +CONFIG_SMB1390_CHARGE_PUMP=y +CONFIG_FRAME_WARN=4096 + +# Proximity +CONFIG_US_PROXIMITY=y + +# Sensors +CONFIG_AKM09970=y + +# Simtray +CONFIG_SIMTRAY_STATUS=y + +# spk-id +CONFIG_HAS_IOMEM=y +CONFIG_MFD_SPK_ID=y + +# TEE +CONFIG_TRUSTY=y + +# Touchscreen +# CONFIG_TOUCHSCREEN_ST is not set diff --git a/arch/arm64/configs/vendor/xiaomi/vayu.config b/arch/arm64/configs/vendor/xiaomi/vayu.config index 96c16e9b2cf6..a3342fc69b97 100644 --- a/arch/arm64/configs/vendor/xiaomi/vayu.config +++ b/arch/arm64/configs/vendor/xiaomi/vayu.config @@ -1,2 +1,15 @@ # Platform CONFIG_MACH_XIAOMI_VAYU=y + +# Audio +CONFIG_SND_SOC_CS35L41=y +CONFIG_MSM_CSPL=y + +# Power +CONFIG_BATT_VERIFY_BY_DS28E16=y +CONFIG_ONEWIRE_GPIO=y +CONFIG_BQ2597X_CHARGE_PUMP=y + +# Touchscreen +CONFIG_TOUCHSCREEN_NT36xxx_HOSTDL_SPI=y +CONFIG_TOUCHSCREEN_NVT_DEBUG_FS=y From 7b576f9ed86d01e61f7adbb4957b93b3a514ae62 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Mon, 4 Jul 2022 17:18:25 +0200 Subject: [PATCH 107/226] arch: arm64: boot: dts: xiaomi: Move to 2si Change-Id: Iaca6c96f165cf300289761abf4e178eb64371ffd Signed-off-by: firebird11 --- arch/arm64/boot/dts/qcom/xiaomi/base/sm8150.dtsi | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150.dtsi b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150.dtsi index bf0f93ebbec2..2bdfd8672fff 100644 --- a/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/xiaomi/base/sm8150.dtsi @@ -4,6 +4,12 @@ }; }; +&firmware { + android { + boot_devices = "soc/1d84000.ufshc"; + }; +}; + &shared_meta { parts = "vbmeta,boot,system,vendor,dtbo"; }; @@ -13,7 +19,7 @@ status = "disabled"; }; vendor { - fsmgr_flags = "wait,avb"; + status = "disabled"; }; }; From f25b72774abac691d78f403740d94e12bdcc200e Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Tue, 28 Jun 2022 23:10:29 +0200 Subject: [PATCH 108/226] init: Add CONFIG_INITRAMFS_IGNORE_SKIP_FLAG * Ignoring an ignore flag, yikes * Also replace skip_initramfs with want_initramfs Co-authored-by: Erfan Abdi Change-Id: Ifdf726f128bc66bf860bbb71024f94f56879710f Signed-off-by: firebird11 --- fs/proc/cmdline.c | 31 +++++++++++++++++++++++++++++++ init/initramfs.c | 2 +- usr/Kconfig | 11 +++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/fs/proc/cmdline.c b/fs/proc/cmdline.c index 403cbb12a6e9..01e1f0eebf66 100644 --- a/fs/proc/cmdline.c +++ b/fs/proc/cmdline.c @@ -3,10 +3,37 @@ #include #include #include +#ifdef CONFIG_INITRAMFS_IGNORE_SKIP_FLAG +#include +#endif + +#ifdef CONFIG_INITRAMFS_IGNORE_SKIP_FLAG +#define INITRAMFS_STR_FIND "skip_initramfs" +#define INITRAMFS_STR_REPLACE "want_initramfs" +#define INITRAMFS_STR_LEN (sizeof(INITRAMFS_STR_FIND) - 1) + +static char proc_command_line[COMMAND_LINE_SIZE]; + +static void proc_command_line_init(void) { + char *offset_addr; + + strcpy(proc_command_line, saved_command_line); + + offset_addr = strstr(proc_command_line, INITRAMFS_STR_FIND); + if (!offset_addr) + return; + + memcpy(offset_addr, INITRAMFS_STR_REPLACE, INITRAMFS_STR_LEN); +} +#endif static int cmdline_proc_show(struct seq_file *m, void *v) { +#ifdef CONFIG_INITRAMFS_IGNORE_SKIP_FLAG + seq_printf(m, "%s\n", proc_command_line); +#else seq_printf(m, "%s\n", saved_command_line); +#endif return 0; } @@ -24,6 +51,10 @@ static const struct file_operations cmdline_proc_fops = { static int __init proc_cmdline_init(void) { +#ifdef CONFIG_INITRAMFS_IGNORE_SKIP_FLAG + proc_command_line_init(); +#endif + proc_create("cmdline", 0, NULL, &cmdline_proc_fops); return 0; } diff --git a/init/initramfs.c b/init/initramfs.c index 33fdbdc19ad7..431ea8fa60cf 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -614,7 +614,7 @@ static int __init skip_initramfs_param(char *str) { if (*str) return 0; - do_skip_initramfs = 1; + do_skip_initramfs = !IS_ENABLED(CONFIG_INITRAMFS_IGNORE_SKIP_FLAG); return 1; } __setup("skip_initramfs", skip_initramfs_param); diff --git a/usr/Kconfig b/usr/Kconfig index 8b4826de1189..de9d04f2c0be 100644 --- a/usr/Kconfig +++ b/usr/Kconfig @@ -32,6 +32,17 @@ config INITRAMFS_FORCE and is useful if you cannot or don't want to change the image your bootloader passes to the kernel. +config INITRAMFS_IGNORE_SKIP_FLAG + bool "Force initramfs even when skip_initramfs is set" + default n + help + Ignore skip_initramfs cmdline flag. + + This should only be used if you have no control over cmdline + passed by your bootloader yet you can't use CMDLINE_FORCE. + + If unsure say N. + config INITRAMFS_ROOT_UID int "User ID to map to 0 (user root)" depends on INITRAMFS_SOURCE!="" From 804f527ef1a8e2cc58dec11ec04a38c423a0e984 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Tue, 28 Jun 2022 23:14:51 +0200 Subject: [PATCH 109/226] arch: arm64: configs: xiaomi: Enable CONFIG_INITRAMFS_IGNORE_SKIP_FLAG Change-Id: I22b5eb981c886d9280957f6bd1047fc76ac9916b Signed-off-by: firebird11 --- arch/arm64/configs/vendor/xiaomi/sm8150-common.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/vendor/xiaomi/sm8150-common.config b/arch/arm64/configs/vendor/xiaomi/sm8150-common.config index 610d5f699132..942ae66bdf56 100644 --- a/arch/arm64/configs/vendor/xiaomi/sm8150-common.config +++ b/arch/arm64/configs/vendor/xiaomi/sm8150-common.config @@ -10,6 +10,9 @@ CONFIG_EXFAT_FS=y # EROFS CONFIG_EROFS_FS=y +# initramfs +CONFIG_INITRAMFS_IGNORE_SKIP_FLAG=y + # pstore CONFIG_CMDLINE="ramoops_memreserve=4M" CONFIG_CMDLINE_EXTEND=y From fb6f8155fcf4cd0fbbe8b9bc1f3a92f97e1a2a02 Mon Sep 17 00:00:00 2001 From: map220v Date: Wed, 31 May 2023 18:37:30 +0300 Subject: [PATCH 110/226] drivers: gpu: dsi-staging: Disable dynamic fps and set refresh rate to 104 * Fixes issue with drm render in recovery and charger [SebaUbuntu]: Don't export the symbols, guard for nabu only Co-authored-by: Cyber Knight Change-Id: Ibff4d92d054c302b75e6a2bf7ddaf0e88f1fa43f Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 34 +++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 450f1ac0a369..ab7aa8c80dea 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -49,6 +49,26 @@ #define DEFAULT_PANEL_PREFILL_LINES 25 #define TICKS_IN_MICRO_SECOND 1000000 +#ifdef CONFIG_MACH_XIAOMI_NABU +static bool is_normal_boot = false; +static int __init read_is_normal_boot(char *s) +{ + strtobool(s, &is_normal_boot); + return 1; +} +__setup("androidboot.force_normal_boot=", read_is_normal_boot); + +static bool is_charger_boot = false; +static int __init read_boot_mode(char *s) +{ + if (strcmp(s, "charger") == 0) { + is_charger_boot = true; + } + return 1; +} +__setup("androidboot.mode=", read_boot_mode); +#endif + enum dsi_dsc_ratio_type { DSC_8BPC_8BPP, DSC_10BPC_8BPP, @@ -1347,6 +1367,13 @@ static int dsi_panel_parse_timing(struct dsi_mode_info *mode, rc = utils->read_u32(utils->data, "qcom,mdss-dsi-panel-framerate", &mode->refresh_rate); + +#ifdef CONFIG_MACH_XIAOMI_NABU + if (!is_normal_boot || is_charger_boot) { + mode->refresh_rate = 104; + } +#endif + if (rc) { pr_err("failed to read qcom,mdss-dsi-panel-framerate, rc=%d\n", rc); @@ -1899,6 +1926,13 @@ static int dsi_panel_parse_dfps_caps(struct dsi_panel *panel) const char *type; u32 i; +#ifdef CONFIG_MACH_XIAOMI_NABU + if (!is_normal_boot || is_charger_boot) { + dfps_caps->dfps_support = false; + return rc; + } +#endif + supported = utils->read_bool(utils->data, "qcom,mdss-dsi-pan-enable-dynamic-fps"); From 1b1591a5b14b4c1c7cc1e50647533ffd32fdad74 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Sat, 3 Aug 2024 02:10:13 +0200 Subject: [PATCH 111/226] drivers: hid: Implement keyboard driver Will remove the keyboard from the input when disconnected Change-Id: Ide873402a0ebc1b4844f6c4e6666c03fff3f5ba4 Signed-off-by: firebird11 --- drivers/hid/Makefile | 2 + drivers/hid/hid-core.c | 3 + drivers/hid/hid-ids.h | 2 + drivers/hid/hid-xiaomi.c | 215 ++++++++++++++++++ .../misc/xiaomi_keyboard/xiaomi_keyboard.c | 95 +++++++- .../misc/xiaomi_keyboard/xiaomi_keyboard.h | 2 + include/linux/input/usbkbd-xiaomi.h | 15 ++ 7 files changed, 330 insertions(+), 4 deletions(-) create mode 100644 drivers/hid/hid-xiaomi.c create mode 100644 include/linux/input/usbkbd-xiaomi.h diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 94b39817f5c6..351176547d08 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -118,6 +118,8 @@ obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o obj-$(CONFIG_HID_SENSOR_HUB) += hid-sensor-hub.o obj-$(CONFIG_HID_SENSOR_CUSTOM_SENSOR) += hid-sensor-custom.o +obj-$(CONFIG_XIAOMI_KEYBOARD) += hid-xiaomi.o + obj-$(CONFIG_USB_HID) += usbhid/ obj-$(CONFIG_USB_MOUSE) += usbhid/ obj-$(CONFIG_USB_KBD) += usbhid/ diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 0e5db253db44..fc107ba4e2fa 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2510,6 +2510,9 @@ static const struct hid_device_id hid_have_special_driver[] = { #endif #if IS_ENABLED(CONFIG_HID_ZYDACRON) { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) }, +#endif +#if IS_ENABLED(CONFIG_XIAOMI_KEYBOARD) + { HID_USB_DEVICE(USB_VENDOR_ID_NANO_IC, 0x3FFC) }, #endif { } }; diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index cbd40d59bb20..f6bf0b497a6a 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -1160,6 +1160,8 @@ #define USB_VENDOR_ID_XAT 0x2505 #define USB_DEVICE_ID_XAT_CSR 0x0220 +#define USB_VENDOR_ID_NANO_IC 0x3206 + #define USB_VENDOR_ID_XIN_MO 0x16c0 #define USB_DEVICE_ID_XIN_MO_DUAL_ARCADE 0x05e1 #define USB_DEVICE_ID_THT_2P_ARCADE 0x75e1 diff --git a/drivers/hid/hid-xiaomi.c b/drivers/hid/hid-xiaomi.c new file mode 100644 index 000000000000..c6a8d256bcf2 --- /dev/null +++ b/drivers/hid/hid-xiaomi.c @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * HID driver for the Xiaomi Mi Pad 5 keyboard. + * + * Copyright (c) 2024 Sebastiano Barezzi + */ + +/** + * This driver is needed to support the Xiaomi Mi Pad 5 keyboard due to their engineering mess. + * The keyboard controller is in the tablet, and the keyboard connects through pogo pins. + * The controllers appears as a USB HID device, but without being aware of its presence. + * The driver, thanks to the original Xiaomi driver needed for power juice, will add and remove the + * Linux input device when the keyboard is connected and disconnected. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hid-ids.h" + +/** + * Wait interval for the connection check to let the IRQ handler to settle down. + */ +#define CONNECTION_WAIT_INTERVAL 1000 /* msec */ + +struct xiaomi_priv { + struct list_head list; + + struct hid_device *hdev; + + bool enabled; + struct mutex enabled_lock; + + struct workqueue_struct *connection_wq; + struct delayed_work connection_work; +}; + +// List of all instances +static struct list_head instances = LIST_HEAD_INIT(instances); +static DEFINE_MUTEX(instances_lock); + +// Keyboard connection status, true by default +static bool connected = true; + +// Called by vendor driver +void xiaomi_keyboard_connection_change(bool _connected) +{ + struct xiaomi_priv *instance; + + connected = _connected; + + mutex_lock(&instances_lock); + list_for_each_entry(instance, &instances, list) { + // Schedule the work, wait a sec before toggling the keyboard + mod_delayed_work(instance->connection_wq, + &instance->connection_work, + msecs_to_jiffies(CONNECTION_WAIT_INTERVAL)); + } + mutex_unlock(&instances_lock); +} + +/** + * Updates the HID device status in a safe way. + * Needed to avoid a double-free in the HID core. + */ +static int xiaomi_safe_toggle(struct hid_device *hdev, bool enable) +{ + struct xiaomi_priv *priv = hid_get_drvdata(hdev); + int ret = 0; + + mutex_lock(&priv->enabled_lock); + + if (priv->enabled == enable) { + goto done; + } + + if (enable) { + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "hid_hw_start failed\n"); + goto done; + } + } else { + hid_hw_stop(hdev); + } + + priv->enabled = enable; + +done: + mutex_unlock(&priv->enabled_lock); + + return ret; +} + +static void xiaomi_connection_work(struct work_struct *work) +{ + struct xiaomi_priv *priv = container_of( + to_delayed_work(work), struct xiaomi_priv, connection_work); + struct hid_device *hdev = priv->hdev; + + xiaomi_safe_toggle(hdev, connected); +} + +static int xiaomi_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + struct xiaomi_priv *priv; + int ret; + + if (!hid_is_usb(hdev)) { + ret = -EINVAL; + goto err_1; + } + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; + goto err_1; + } + + // Setup workqueue + priv->connection_wq = create_singlethread_workqueue("hid-xiaomi"); + if (!priv->connection_wq) { + ret = -ENOMEM; + goto err_2; + } + INIT_DELAYED_WORK(&priv->connection_work, xiaomi_connection_work); + + priv->hdev = hdev; + priv->enabled = false; + + // Setup the mutex + mutex_init(&priv->enabled_lock); + + hid_set_drvdata(hdev, priv); + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "hid_parse failed\n"); + goto err_3; + } + + ret = xiaomi_safe_toggle(hdev, true); + if (ret) { + hid_err(hdev, "hid_hw_start failed\n"); + goto err_3; + } + + // Schedule an update to keep the keyboard in sync + mod_delayed_work(priv->connection_wq, &priv->connection_work, + msecs_to_jiffies(CONNECTION_WAIT_INTERVAL)); + + // Add the instance to the list + mutex_lock(&instances_lock); + list_add(&priv->list, &instances); + mutex_unlock(&instances_lock); + + return 0; + +err_3: + mutex_destroy(&priv->enabled_lock); + destroy_workqueue(priv->connection_wq); +err_2: + kfree(priv); +err_1: + return ret; +} + +static void xiaomi_remove(struct hid_device *hdev) +{ + struct xiaomi_priv *priv = hid_get_drvdata(hdev); + + // Remove the instance from the list + mutex_lock(&instances_lock); + list_del(&priv->list); + mutex_unlock(&instances_lock); + + // Wait for the work to finish + cancel_delayed_work_sync(&priv->connection_work); + + // Stop the HID device + xiaomi_safe_toggle(hdev, false); + + // Destroy the mutex + mutex_destroy(&priv->enabled_lock); + + // Destroy the workqueue + destroy_workqueue(priv->connection_wq); + + kfree(priv); +} + +static const struct hid_device_id xiaomi_devices[] = { + { + HID_USB_DEVICE(USB_VENDOR_ID_NANO_IC, 0x3FFC), + }, + {} +}; +MODULE_DEVICE_TABLE(hid, xiaomi_devices); + +static struct hid_driver hid_xiaomi = { + .name = "hid-xiaomi", + .id_table = xiaomi_devices, + .probe = xiaomi_probe, + .remove = xiaomi_remove, +}; +module_hid_driver(hid_xiaomi); + +MODULE_AUTHOR("Sebastiano Barezzi "); +MODULE_DESCRIPTION("Xiaomi Mi Pad 5 keyboard HID driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c index 98d41b8eaeb2..8e91dc92f73b 100644 --- a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c +++ b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c @@ -15,6 +15,7 @@ #include "xiaomi_keyboard.h" #include #include +#include static struct xiaomi_keyboard_data *mdata; @@ -92,6 +93,91 @@ DEVICE_ATTR(xiaomi_keyboard_conn_status, (S_IRUGO | S_IWUSR | S_IWGRP), xiaomi_keyboard_conn_status_show, xiaomi_keyboard_conn_status_store); +static ssize_t xiaomi_keyboard_connected_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (!mdata) + return -EINVAL; + + return scnprintf(buf, PAGE_SIZE, "%d", mdata->connected); +} + +static ssize_t xiaomi_keyboard_connected_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc, val; + + rc = kstrtoint(buf, 10, &val); + if (rc) + return -EINVAL; + + if (!mdata) + return -EINVAL; + + mdata->connected = !!val; + + sysfs_notify(&mdata->pdev->dev.kobj, NULL, "xiaomi_keyboard_connected"); + + // Notify the input driver + xiaomi_keyboard_connection_change( + !!(mdata->connected && mdata->user_enabled)); + + return count; +} + +DEVICE_ATTR(xiaomi_keyboard_connected, (S_IRUGO | S_IWUSR | S_IWGRP), + xiaomi_keyboard_connected_show, xiaomi_keyboard_connected_store); + +static ssize_t xiaomi_keyboard_enabled_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (!mdata) + return -EINVAL; + + return scnprintf(buf, PAGE_SIZE, "%d", mdata->user_enabled); +} + +static ssize_t xiaomi_keyboard_enabled_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc, val; + + rc = kstrtoint(buf, 10, &val); + if (rc) + return -EINVAL; + + if (!mdata) + return -EINVAL; + + mdata->user_enabled = !!val; + + sysfs_notify(&mdata->pdev->dev.kobj, NULL, "xiaomi_keyboard_enabled"); + + // Notify the input driver + xiaomi_keyboard_connection_change( + !!(mdata->connected && mdata->user_enabled)); + + return count; +} + +DEVICE_ATTR(xiaomi_keyboard_enabled, (S_IRUGO | S_IWUSR | S_IWGRP), + xiaomi_keyboard_enabled_show, xiaomi_keyboard_enabled_store); + +static struct attribute *sysfs_attrs[] = { + &dev_attr_xiaomi_keyboard_conn_status.attr, + &dev_attr_xiaomi_keyboard_connected.attr, + &dev_attr_xiaomi_keyboard_enabled.attr, + NULL, +}; + +static const struct attribute_group xiaomi_attribute_group = { + .attrs = sysfs_attrs, +}; + static irqreturn_t xiaomi_keyboard_irq_func(int irq, void *data) { int value = 0; @@ -533,12 +619,13 @@ static int xiaomi_keyboard_probe(struct platform_device *pdev) mdata->dev_pm_suspend = false; mdata->keyboard_is_enable = false; mdata->is_in_suspend = false; + mdata->connected = true; + mdata->user_enabled = true; - ret = sysfs_create_file(&mdata->pdev->dev.kobj, - &dev_attr_xiaomi_keyboard_conn_status.attr); + ret = sysfs_create_group(&mdata->pdev->dev.kobj, + &xiaomi_attribute_group); if (ret < 0) { - MI_KB_ERR( - "Create sysfs attribute xiaomi_keyboard_conn_status Failed\n"); + MI_KB_ERR("Create sysfs group Failed\n"); goto err_pinctrl_select; } diff --git a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h index 32bb8c0dcbd4..914b094b866d 100644 --- a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h +++ b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h @@ -43,5 +43,7 @@ struct xiaomi_keyboard_data { int is_usb_exist; bool keyboard_is_enable; bool is_in_suspend; + bool connected; + bool user_enabled; }; #endif diff --git a/include/linux/input/usbkbd-xiaomi.h b/include/linux/input/usbkbd-xiaomi.h new file mode 100644 index 000000000000..7af82a271785 --- /dev/null +++ b/include/linux/input/usbkbd-xiaomi.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2024 Sebastiano Barezzi + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include + +#ifdef CONFIG_XIAOMI_KEYBOARD +void xiaomi_keyboard_connection_change(bool connected); +#else +static inline void xiaomi_keyboard_connection_change(bool connected) { } +#endif From a8328d5458710ba08a1d21e0de13ec124ca0aefe Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Sat, 3 Aug 2024 04:56:03 +0200 Subject: [PATCH 112/226] drivers: hid: hid-xiaomi: Drop touchpad reporting The keyboard doesn't have one Change-Id: Ieab11b2019e14bf22d2b76990e4fbd0dabc86e9a Signed-off-by: firebird11 --- drivers/hid/hid-xiaomi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/hid/hid-xiaomi.c b/drivers/hid/hid-xiaomi.c index c6a8d256bcf2..88e67e9958e8 100644 --- a/drivers/hid/hid-xiaomi.c +++ b/drivers/hid/hid-xiaomi.c @@ -106,6 +106,17 @@ static void xiaomi_connection_work(struct work_struct *work) xiaomi_safe_toggle(hdev, connected); } +static int xiaomi_input_configured(struct hid_device *hdev, + struct hid_input *hi) +{ + struct input_dev *input = hi->input; + + // Drop EV_REL, the keyboard doesn't have a touchpad + __clear_bit(EV_REL, input->evbit); + + return 0; +} + static int xiaomi_probe(struct hid_device *hdev, const struct hid_device_id *id) { struct xiaomi_priv *priv; @@ -207,6 +218,7 @@ static struct hid_driver hid_xiaomi = { .id_table = xiaomi_devices, .probe = xiaomi_probe, .remove = xiaomi_remove, + .input_configured = xiaomi_input_configured, }; module_hid_driver(hid_xiaomi); From 051b2f6ade84fca6db31375e2c4cd6eb8e45b3b7 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Sat, 3 Aug 2024 02:12:26 +0200 Subject: [PATCH 113/226] drivers: input: misc: xiaomi_keyboard: Enable by default Change-Id: I1425db25797ab1379a914572f4234f13a58c9b62 Signed-off-by: firebird11 --- drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c index 8e91dc92f73b..7883bf111c45 100644 --- a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c +++ b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c @@ -656,6 +656,10 @@ static int xiaomi_keyboard_probe(struct platform_device *pdev) goto err_register_power_supply_notif_failed; } + // Enable the keyboard by default + set_keyboard_status(1); + xiaomi_keyboard_reset(); + MI_KB_INFO("Success\n"); return ret; From a744fd8c6d6b4a9ede95498408535b59a708c461 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Mon, 31 Oct 2022 12:23:22 +0200 Subject: [PATCH 114/226] display: translate PCC to CSC PCC cannot be applied per-plane, but CSC can. Translate PCC to CSC to allow skipping it for some planes. Change-Id: I76fa04fed6bcc9426cf2a38c58c23e49e27b8750 [@RealJohnGalt] adapt for k4.14 Signed-off-by: onettboots Signed-off-by: firebird11 --- .../gpu/drm/msm/sde/sde_color_processing.c | 25 +++ .../gpu/drm/msm/sde/sde_color_processing.h | 3 + drivers/gpu/drm/msm/sde/sde_hw_sspp.c | 34 ++-- drivers/gpu/drm/msm/sde/sde_hw_sspp.h | 3 +- drivers/gpu/drm/msm/sde/sde_plane.c | 192 +++++++++++++++++- 5 files changed, 229 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_color_processing.c b/drivers/gpu/drm/msm/sde/sde_color_processing.c index 7782dffc7e33..29435986477d 100644 --- a/drivers/gpu/drm/msm/sde/sde_color_processing.c +++ b/drivers/gpu/drm/msm/sde/sde_color_processing.c @@ -24,6 +24,7 @@ #include "sde_ad4.h" #include "sde_hw_interrupts.h" #include "sde_core_irq.h" +#include "sde_plane.h" #include "dsi_panel.h" struct sde_cp_node { @@ -646,6 +647,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, hw_cfg.num_of_mixers = sde_crtc->num_mixers; hw_cfg.last_feature = 0; + if (prop_node->feature == SDE_CP_CRTC_DSPP_PCC) + return; + for (i = 0; i < num_mixers && !ret; i++) { hw_lm = sde_crtc->mixers[i].hw_lm; hw_dspp = sde_crtc->mixers[i].hw_dspp; @@ -2109,3 +2113,24 @@ int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en, exit: return ret; } + +const struct drm_msm_pcc *sde_cp_crtc_get_pcc_cfg(struct drm_crtc *drm_crtc) +{ + struct drm_property_blob *blob = NULL; + struct sde_cp_node *prop_node = NULL; + struct sde_crtc *crtc; + + crtc = to_sde_crtc(drm_crtc); + + mutex_lock(&crtc->crtc_cp_lock); + list_for_each_entry(prop_node, &crtc->feature_list, feature_list) { + if (prop_node->feature == SDE_CP_CRTC_DSPP_PCC) { + blob = prop_node->blob_ptr; + break; + } + } + + mutex_unlock(&crtc->crtc_cp_lock); + + return blob ? blob->data : NULL; +} diff --git a/drivers/gpu/drm/msm/sde/sde_color_processing.h b/drivers/gpu/drm/msm/sde/sde_color_processing.h index 7481a594f4fc..900afc687d2a 100644 --- a/drivers/gpu/drm/msm/sde/sde_color_processing.h +++ b/drivers/gpu/drm/msm/sde/sde_color_processing.h @@ -152,4 +152,7 @@ void sde_cp_crtc_post_ipc(struct drm_crtc *crtc); */ int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en, struct sde_irq_callback *hist_irq); + +const struct drm_msm_pcc *sde_cp_crtc_get_pcc_cfg(struct drm_crtc *crtc); + #endif /*_SDE_COLOR_PROCESSING_H */ diff --git a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c index 35b1e099fcbe..25feafec3d20 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c @@ -231,7 +231,7 @@ static void sde_hw_sspp_setup_multirect(struct sde_hw_pipe *ctx, } static void _sspp_setup_opmode(struct sde_hw_pipe *ctx, - u32 mask, u8 en) + bool csc_en, bool yuv_en) { u32 idx; u32 opmode; @@ -242,17 +242,18 @@ static void _sspp_setup_opmode(struct sde_hw_pipe *ctx, return; opmode = SDE_REG_READ(&ctx->hw, SSPP_VIG_OP_MODE + idx); + opmode &= ~(VIG_OP_CSC_EN | VIG_OP_CSC_SRC_DATAFMT); + if (csc_en) + opmode |= VIG_OP_CSC_EN; - if (en) - opmode |= mask; - else - opmode &= ~mask; + if (yuv_en) + opmode |= VIG_OP_CSC_SRC_DATAFMT; SDE_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode); } static void _sspp_setup_csc10_opmode(struct sde_hw_pipe *ctx, - u32 mask, u8 en) + bool csc_en, bool yuv_en) { u32 idx; u32 opmode; @@ -261,10 +262,12 @@ static void _sspp_setup_csc10_opmode(struct sde_hw_pipe *ctx, return; opmode = SDE_REG_READ(&ctx->hw, SSPP_VIG_CSC_10_OP_MODE + idx); - if (en) - opmode |= mask; - else - opmode &= ~mask; + opmode &= ~(VIG_CSC_10_EN | VIG_CSC_10_SRC_DATAFMT); + if (csc_en) + opmode |= VIG_CSC_10_EN; + + if (yuv_en) + opmode |= VIG_CSC_10_SRC_DATAFMT; SDE_REG_WRITE(&ctx->hw, SSPP_VIG_CSC_10_OP_MODE + idx, opmode); } @@ -300,7 +303,8 @@ static void sde_hw_sspp_set_src_split_order(struct sde_hw_pipe *ctx, static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx, const struct sde_format *fmt, bool const_alpha_en, u32 flags, - enum sde_sspp_multirect_index rect_mode) + enum sde_sspp_multirect_index rect_mode, + bool force_csc) { struct sde_hw_blk_reg_map *c; u32 chroma_samp, unpack, src_format; @@ -308,6 +312,7 @@ static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx, u32 alpha_en_mask = 0; u32 op_mode_off, unpack_pat_off, format_off; u32 idx; + bool csc_en = force_csc || SDE_FORMAT_IS_YUV(fmt); if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !fmt) return; @@ -395,12 +400,9 @@ static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx, /* update scaler opmode, if appropriate */ if (test_bit(SDE_SSPP_CSC, &ctx->cap->features)) - _sspp_setup_opmode(ctx, VIG_OP_CSC_EN | VIG_OP_CSC_SRC_DATAFMT, - SDE_FORMAT_IS_YUV(fmt)); + _sspp_setup_opmode(ctx, csc_en, SDE_FORMAT_IS_YUV(fmt)); else if (test_bit(SDE_SSPP_CSC_10BIT, &ctx->cap->features)) - _sspp_setup_csc10_opmode(ctx, - VIG_CSC_10_EN | VIG_CSC_10_SRC_DATAFMT, - SDE_FORMAT_IS_YUV(fmt)); + _sspp_setup_csc10_opmode(ctx, csc_en, SDE_FORMAT_IS_YUV(fmt)); SDE_REG_WRITE(c, format_off + idx, src_format); SDE_REG_WRITE(c, unpack_pat_off + idx, unpack); diff --git a/drivers/gpu/drm/msm/sde/sde_hw_sspp.h b/drivers/gpu/drm/msm/sde/sde_hw_sspp.h index e9efb7ef98b8..93697e39971f 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_sspp.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_sspp.h @@ -322,7 +322,8 @@ struct sde_hw_sspp_ops { void (*setup_format)(struct sde_hw_pipe *ctx, const struct sde_format *fmt, bool blend_enabled, u32 flags, - enum sde_sspp_multirect_index index); + enum sde_sspp_multirect_index index, + bool force_csc); /** * setup_rects - setup pipe ROI rectangles diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index 285ebf05394b..8f3a4edf570c 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -125,8 +125,12 @@ struct sde_plane { bool revalidate; bool xin_halt_forced_clk; + const struct drm_msm_pcc *pcc_cfg; + uint32_t pcc_coeff[9]; struct sde_csc_cfg csc_cfg; + struct sde_csc_cfg csc_pcc_cfg; struct sde_csc_cfg *csc_usr_ptr; + struct sde_csc_cfg *csc_pcc_ptr; struct sde_csc_cfg *csc_ptr; const struct sde_sspp_sub_blks *pipe_sblk; @@ -1399,6 +1403,113 @@ static inline void _sde_plane_setup_csc(struct sde_plane *psde) psde->csc_ptr->csc_mv[2]); } +#define CSC_MASK 0x7fffff +#define CSC_ONE (1 << 16) +#define CSC_DGM_ONE (1 << 9) +#define CSC_10BIT_LIMIT 0x3ff +#define CSC_8BIT_LIMIT 0xff +#define PCC_MASK 0x3ffff +#define PCC_ONE (1 << 15) + +#define CSC_BIAS_CLAMP(value) \ + { 0, 0, 0 }, \ + { 0, 0, 0 }, \ + { 0, value, 0, value, 0, value }, \ + { 0, value, 0, value, 0, value } + +static const struct sde_csc_cfg sde_identity_csc_cfg = { + { + CSC_ONE, 0, 0, + 0, CSC_ONE, 0, + 0, 0, CSC_ONE, + }, + CSC_BIAS_CLAMP(CSC_8BIT_LIMIT), +}; +static const struct sde_csc_cfg sde_identity_csc10_cfg = { + { + CSC_ONE, 0, 0, + 0, CSC_ONE, 0, + 0, 0, CSC_ONE, + }, + CSC_BIAS_CLAMP(CSC_10BIT_LIMIT), +}; +static const struct sde_csc_cfg sde_identity_csc_dgm_cfg = { + { + CSC_DGM_ONE, 0, 0, + 0, CSC_DGM_ONE, 0, + 0, 0, CSC_DGM_ONE, + }, +}; + +static inline s32 csc_to_signed(u32 v) +{ + return sign_extend32(v, __fls(CSC_MASK)); +} + +static inline u32 csc_to_unsigned(s32 v) +{ + return ((u32) v) & CSC_MASK; +} + +static inline s32 pcc_to_signed(u32 v) +{ + return sign_extend32(v, __fls(PCC_MASK)); +} + +static inline void _sde_plane_mul_csc_pcc(struct sde_plane *psde, + const struct sde_csc_cfg *csc_cfg) +{ + unsigned int i, j, u; + + memcpy(&psde->csc_pcc_cfg, csc_cfg, sizeof(psde->csc_pcc_cfg)); + + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + unsigned int ij = i * 3 + j; + s64 sum = 0; + + for (u = 0; u < 3; u++) { + unsigned int iu = i * 3 + u; + unsigned int uj = u * 3 + j; + s64 csc = csc_to_signed(csc_cfg->csc_mv[uj]); + s64 pcc = pcc_to_signed(psde->pcc_coeff[iu]); + + sum += csc * pcc; + } + + sum = div_s64(sum, PCC_ONE); + + psde->csc_pcc_cfg.csc_mv[ij] = csc_to_unsigned(sum); + } + } +} + +static inline void _sde_plane_setup_csc_pcc(struct sde_plane *psde) +{ + const struct sde_csc_cfg *csc_ptr = psde->csc_ptr; + + psde->csc_pcc_ptr = NULL; + + if (!psde->pcc_cfg) + return; + + if (!csc_ptr) { + if (psde->features & BIT(SDE_SSPP_CSC_10BIT)) { + csc_ptr = &sde_identity_csc10_cfg; + } else if (psde->features & BIT(SDE_SSPP_CSC)) { + csc_ptr = &sde_identity_csc_cfg; + } else if (psde->features & BIT(SDE_SSPP_DGM_CSC)) { + csc_ptr = &sde_identity_csc_dgm_cfg; + } else { + return; + } + } + + _sde_plane_mul_csc_pcc(psde, csc_ptr); + + psde->csc_pcc_ptr = &psde->csc_pcc_cfg; +} + static void sde_color_process_plane_setup(struct drm_plane *plane) { struct sde_plane *psde; @@ -1683,7 +1794,8 @@ static int _sde_plane_color_fill(struct sde_plane *psde, psde->pipe_hw->ops.setup_format(psde->pipe_hw, fmt, blend_enable, SDE_SSPP_SOLID_FILL, - pstate->multirect_index); + pstate->multirect_index, + false); if (psde->pipe_hw->ops.setup_rects) psde->pipe_hw->ops.setup_rects(psde->pipe_hw, @@ -3830,10 +3942,28 @@ static int sde_plane_atomic_check(struct drm_plane *plane, return ret; } +struct sde_csc_cfg *sde_plane_get_csc_cfg(struct drm_plane *plane) +{ + struct sde_plane_state *pstate; + struct sde_csc_cfg *csc_ptr; + struct sde_plane *psde; + + psde = to_sde_plane(plane); + pstate = to_sde_plane_state(plane->state); + + if (psde->csc_pcc_ptr) + csc_ptr = psde->csc_pcc_ptr; + else + csc_ptr = psde->csc_ptr; + + return csc_ptr; +} + void sde_plane_flush(struct drm_plane *plane) { struct sde_plane *psde; struct sde_plane_state *pstate; + struct sde_csc_cfg *csc_ptr; if (!plane || !plane->state) { SDE_ERROR("invalid plane\n"); @@ -3843,6 +3973,8 @@ void sde_plane_flush(struct drm_plane *plane) psde = to_sde_plane(plane); pstate = to_sde_plane_state(plane->state); + csc_ptr = sde_plane_get_csc_cfg(&psde->base); + /* * These updates have to be done immediately before the plane flush * timing, and may not be moved to the atomic_update/mode_set functions. @@ -3853,8 +3985,8 @@ void sde_plane_flush(struct drm_plane *plane) else if (psde->color_fill & SDE_PLANE_COLOR_FILL_FLAG) /* force 100% alpha */ _sde_plane_color_fill(psde, psde->color_fill, 0xFF); - else if (psde->pipe_hw && psde->csc_ptr && psde->pipe_hw->ops.setup_csc) - psde->pipe_hw->ops.setup_csc(psde->pipe_hw, psde->csc_ptr); + else if (psde->pipe_hw && csc_ptr && psde->pipe_hw->ops.setup_csc) + psde->pipe_hw->ops.setup_csc(psde->pipe_hw, csc_ptr); /* flag h/w flush complete */ if (plane->state) @@ -3876,10 +4008,42 @@ void sde_plane_set_error(struct drm_plane *plane, bool error) psde->is_error = error; } +static inline void _sde_plane_set_csc_pcc(struct sde_plane *psde, + struct sde_plane_state *pstate, + struct drm_crtc *crtc) +{ + const struct drm_msm_pcc *pcc_cfg = sde_cp_crtc_get_pcc_cfg(crtc); + + if (pcc_cfg == psde->pcc_cfg) + return; + + psde->pcc_cfg = pcc_cfg; + + if (pcc_cfg) { + unsigned int i = 0; + +#define set_coeff(m) \ + psde->pcc_coeff[i++] = psde->pcc_cfg->m; + + set_coeff(r.r); + set_coeff(r.g); + set_coeff(r.b); + set_coeff(g.r); + set_coeff(g.g); + set_coeff(g.b); + set_coeff(b.r); + set_coeff(b.g); + set_coeff(b.b); + } + + pstate->dirty |= SDE_PLANE_DIRTY_RECTS; +} + static int sde_plane_sspp_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { uint32_t nplanes, src_flags = 0; + struct sde_csc_cfg *csc_ptr; struct sde_plane *psde; struct drm_plane_state *state; struct sde_plane_state *pstate; @@ -4024,6 +4188,8 @@ static int sde_plane_sspp_atomic_update(struct drm_plane *plane, _sde_plane_sspp_atomic_check_mode_changed(psde, state, old_state); + _sde_plane_set_csc_pcc(psde, pstate, crtc); + /* re-program the output rects always if partial update roi changed */ if (sde_crtc_is_crtc_roi_dirty(crtc->state)) pstate->dirty |= SDE_PLANE_DIRTY_RECTS; @@ -4147,6 +4313,16 @@ static int sde_plane_sspp_atomic_update(struct drm_plane *plane, &pstate->line_insertion_cfg); } + /* update csc */ + if (SDE_FORMAT_IS_YUV(fmt)) + _sde_plane_setup_csc(psde); + else + psde->csc_ptr = 0; + + _sde_plane_setup_csc_pcc(psde); + + csc_ptr = sde_plane_get_csc_cfg(&psde->base); + if ((pstate->dirty & SDE_PLANE_DIRTY_FORMAT || pstate->dirty & SDE_PLANE_DIRTY_RECTS) && psde->pipe_hw->ops.setup_format) { @@ -4159,7 +4335,7 @@ static int sde_plane_sspp_atomic_update(struct drm_plane *plane, /* update format */ psde->pipe_hw->ops.setup_format(psde->pipe_hw, fmt, pstate->const_alpha_en, src_flags, - pstate->multirect_index); + pstate->multirect_index, !!csc_ptr); if (psde->pipe_hw->ops.setup_cdp) { struct sde_hw_pipe_cdp_cfg *cdp_cfg = &pstate->cdp_cfg; @@ -4211,12 +4387,6 @@ static int sde_plane_sspp_atomic_update(struct drm_plane *plane, psde->pipe_hw, &pstate->sc_cfg); } - /* update csc */ - if (SDE_FORMAT_IS_YUV(fmt)) - _sde_plane_setup_csc(psde); - else - psde->csc_ptr = 0; - if (psde->pipe_hw->ops.setup_inverse_pma) { uint32_t pma_mode = 0; @@ -4230,7 +4400,7 @@ static int sde_plane_sspp_atomic_update(struct drm_plane *plane, if (psde->pipe_hw->ops.setup_dgm_csc) psde->pipe_hw->ops.setup_dgm_csc(psde->pipe_hw, - pstate->multirect_index, psde->csc_usr_ptr); + pstate->multirect_index, csc_ptr); } sde_color_process_plane_setup(plane); From 21047b4ef925884772a3486d452c93b24e077d15 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Sun, 18 Dec 2022 21:40:00 +0200 Subject: [PATCH 115/226] techpack: display: ignore CSC config on FOD layer FOD performance decreases if the color of the icon is not exactly white, which happens when night light is enabled. Skip CSC for the FOD layer. Change-Id: Icb202690ec58e807b612fffe479c8e7c5c3b5d03 Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/sde/sde_plane.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index 8f3a4edf570c..7c55067c5469 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -3951,7 +3951,9 @@ struct sde_csc_cfg *sde_plane_get_csc_cfg(struct drm_plane *plane) psde = to_sde_plane(plane); pstate = to_sde_plane_state(plane->state); - if (psde->csc_pcc_ptr) + if (sde_plane_is_fod_layer(&pstate->base)) + csc_ptr = NULL; + else if (psde->csc_pcc_ptr) csc_ptr = psde->csc_pcc_ptr; else csc_ptr = psde->csc_ptr; From bf3b8bb804ea0d27949804c5f6175f16fa22b7d0 Mon Sep 17 00:00:00 2001 From: Demon000 Date: Tue, 27 Dec 2022 15:57:35 +0200 Subject: [PATCH 116/226] display:Fix -Wincompatible-pointer-types warning ../drivers/gpu/drm/msm/sde/sde_color_processing.c:892:9: error: incompatible pointer types returning 'unsigned char *' from a function with result type 'struct drm_msm_pcc *' [-Werror,-Wincompatible-pointer-types] return blob ? blob->data : NULL; ^~~~~~~~ 1 error generated. Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/sde/sde_color_processing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/sde/sde_color_processing.c b/drivers/gpu/drm/msm/sde/sde_color_processing.c index 29435986477d..0c5c4af4b309 100644 --- a/drivers/gpu/drm/msm/sde/sde_color_processing.c +++ b/drivers/gpu/drm/msm/sde/sde_color_processing.c @@ -2132,5 +2132,5 @@ const struct drm_msm_pcc *sde_cp_crtc_get_pcc_cfg(struct drm_crtc *drm_crtc) mutex_unlock(&crtc->crtc_cp_lock); - return blob ? blob->data : NULL; + return blob ? (struct drm_msm_pcc *) blob->data : NULL; } From 4b7921c78ac63a01a0961b9635238691838ac318 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Sun, 1 Jan 2023 23:08:44 +0200 Subject: [PATCH 117/226] display: skip marking null blob changes as dirty Change-Id: I89ed0d7b59d020ee269c7b400ae1db2bb8b62984 Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/msm_prop.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_prop.c b/drivers/gpu/drm/msm/msm_prop.c index f463fbfc9390..5cb6b458614a 100644 --- a/drivers/gpu/drm/msm/msm_prop.c +++ b/drivers/gpu/drm/msm/msm_prop.c @@ -379,16 +379,18 @@ int msm_property_atomic_set(struct msm_property_info *info, if ((property_idx == -EINVAL) || !property_state->values) { DRM_ERROR("invalid argument(s)\n"); } else { + bool is_blob = (property->flags & DRM_MODE_PROP_BLOB) && + (property_idx < info->blob_count); + struct drm_property_blob *prev_blob; + /* extra handling for incoming properties */ mutex_lock(&info->property_lock); - if ((property->flags & DRM_MODE_PROP_BLOB) && - (property_idx < info->blob_count)) { + if (is_blob) { + prev_blob = property_state->values[property_idx].blob; /* need to clear previous ref */ - if (property_state->values[property_idx].blob) - drm_property_blob_put( - property_state->values[ - property_idx].blob); + if (prev_blob) + drm_property_blob_put(prev_blob); /* DRM lookup also takes a reference */ blob = drm_property_lookup_blob(info->dev, @@ -409,6 +411,9 @@ int msm_property_atomic_set(struct msm_property_info *info, } } + if (is_blob && !prev_blob && !blob) + goto skip_mark_dirty; + /* update value and flag as dirty */ if (property_state->values[property_idx].value != val || info->property_data[property_idx].force_dirty) { @@ -418,6 +423,8 @@ int msm_property_atomic_set(struct msm_property_info *info, DBG("%s - %lld", property->name, val); } + +skip_mark_dirty: mutex_unlock(&info->property_lock); rc = 0; } From 3c8bbe1230f560a61ae0344617e1aa8ee67c6041 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Sun, 1 Jan 2023 23:20:43 +0200 Subject: [PATCH 118/226] display: optimize exclusion rects dirty marking Change-Id: I461f6e8a06cf0d47d5867d9fb6dcdeb23d1dfa38 Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/sde/sde_plane.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index 7c55067c5469..6cdca037e782 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -4827,6 +4827,12 @@ static void _sde_plane_install_properties(struct drm_plane *plane, PLANE_PROP_FB_TRANSLATION_MODE); } +#define cmp_and_set(old, new) \ + if ((old) != (new)) { \ + (old) = (new); \ + changed = true; \ + } + static inline void _sde_plane_set_csc_v1(struct sde_plane *psde, void __user *usr_ptr) { @@ -4991,6 +4997,7 @@ static void _sde_plane_set_excl_rect_v1(struct sde_plane *psde, struct sde_plane_state *pstate, void __user *usr_ptr) { struct drm_clip_rect excl_rect_v1; + bool changed = false; if (!psde || !pstate) { SDE_ERROR("invalid argument(s)\n"); @@ -5009,10 +5016,13 @@ static void _sde_plane_set_excl_rect_v1(struct sde_plane *psde, } /* populate from user space */ - pstate->excl_rect.x = excl_rect_v1.x1; - pstate->excl_rect.y = excl_rect_v1.y1; - pstate->excl_rect.w = excl_rect_v1.x2 - excl_rect_v1.x1; - pstate->excl_rect.h = excl_rect_v1.y2 - excl_rect_v1.y1; + cmp_and_set(pstate->excl_rect.x, excl_rect_v1.x1); + cmp_and_set(pstate->excl_rect.y, excl_rect_v1.y1); + cmp_and_set(pstate->excl_rect.w, excl_rect_v1.x2 - excl_rect_v1.x1); + cmp_and_set(pstate->excl_rect.h, excl_rect_v1.y2 - excl_rect_v1.y1); + + if (!changed) + return; SDE_DEBUG_PLANE(psde, "excl_rect: {%d,%d,%d,%d}\n", pstate->excl_rect.x, pstate->excl_rect.y, From 7beeee2ed21f3af5eeb4bc18ed0af5ac36d7e516 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Wed, 4 Jan 2023 02:40:17 +0200 Subject: [PATCH 119/226] display: do not create virtual planes for VIG planes Multirect virtual planes have an issue with CSC causing apparent non-CSC flashes. Without smart DMA, SDE doesn't register any multirect virtual planes. This is a very hacky solution, that might cause some performance defficits. Change-Id: I84d90c7cbb7661e99831b158e81c88de84f87d3f Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/sde/sde_hw_catalog.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h index 95c267021de5..8e0ea22262a6 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h @@ -1350,9 +1350,11 @@ void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg); */ static inline bool sde_hw_sspp_multirect_enabled(const struct sde_sspp_cfg *cfg) { - return test_bit(SDE_SSPP_SMART_DMA_V1, &cfg->features) || + return (test_bit(SDE_SSPP_SMART_DMA_V1, &cfg->features) || test_bit(SDE_SSPP_SMART_DMA_V2, &cfg->features) || - test_bit(SDE_SSPP_SMART_DMA_V2p5, &cfg->features); + test_bit(SDE_SSPP_SMART_DMA_V2p5, &cfg->features)) + && !(test_bit(SDE_SSPP_CSC_10BIT, &cfg->features) || + test_bit(SDE_SSPP_CSC, &cfg->features)); } static inline bool sde_hw_intf_te_supported(const struct sde_mdss_cfg *sde_cfg) From b2746a23b500e60dd72b37c5d3ec09c6fd25eb58 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Sun, 18 Dec 2022 06:34:39 +0200 Subject: [PATCH 120/226] Revert "display: sde_hw_mdss: Increase sde stage to map zpos changes" This reverts commit 278de1c2b2ace0b809fa7215ee8df2f0b9f92493. Change-Id: I68fe99e9e9602b65685b4b55b50ee5a87c166c3c Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/sde/sde_hw_mdss.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h index fbbec709a569..bd3ef45df834 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h @@ -174,7 +174,6 @@ enum sde_stage { SDE_STAGE_8, SDE_STAGE_9, SDE_STAGE_10, - SDE_STAGE_11, SDE_STAGE_MAX }; enum sde_dspp { From 9529ca38181b4635204b61046f72ffde6065a771 Mon Sep 17 00:00:00 2001 From: pwnrazr <1644943+pwnrazr@users.noreply.github.com> Date: Thu, 5 Jan 2023 14:46:31 +0800 Subject: [PATCH 121/226] Revert "disp: msm: Notify sysfs for fod ui changes" This reverts commit ef1691701b1474756b9862089bbb6b4735bd6f8f. Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_display.c | 72 +++++++++++++------ drivers/gpu/drm/msm/dsi-staging/dsi_display.h | 4 -- drivers/gpu/drm/msm/sde/sde_connector.c | 2 - 3 files changed, 51 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index 4db608879026..5ad46bc1c4fb 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -5046,29 +5046,67 @@ static int dsi_display_validate_split_link(struct dsi_display *display) return rc; } -static ssize_t sysfs_fod_ui_read(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t sysfs_hbm_read(struct device *dev, + struct device_attribute *attr, char *buf) { - struct dsi_display *display; - bool status; + struct dsi_display *display = dev_get_drvdata(dev); + if (!display->panel) + return 0; - display = dev_get_drvdata(dev); - if (!display) { - pr_err("Invalid display\n"); + return scnprintf(buf, PAGE_SIZE, "%d\n", display->panel->hbm_mode); +} + +static ssize_t sysfs_hbm_write(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct dsi_display *display = dev_get_drvdata(dev); + int ret, hbm_mode; + + if (!display->panel) return -EINVAL; + + ret = kstrtoint(buf, 10, &hbm_mode); + if (ret) { + pr_err("kstrtoint failed. ret=%d\n", ret); + return ret; + } + + mutex_lock(&display->display_lock); + + display->panel->hbm_mode = hbm_mode; + if (!dsi_panel_initialized(display->panel)) + goto error; + + ret = dsi_display_clk_ctrl(display->dsi_clk_handle, + DSI_CORE_CLK, DSI_CLK_ON); + if (ret) { + pr_err("[%s] failed to enable DSI core clocks, rc=%d\n", + display->name, ret); + goto error; } - status = atomic_read(&display->fod_ui); + ret = dsi_panel_apply_hbm_mode(display->panel); + if (ret) + pr_err("unable to set hbm mode\n"); - return snprintf(buf, PAGE_SIZE, "%d\n", status); + ret = dsi_display_clk_ctrl(display->dsi_clk_handle, + DSI_CORE_CLK, DSI_CLK_OFF); + if (ret) { + pr_err("[%s] failed to disable DSI core clocks, rc=%d\n", + display->name, ret); + goto error; + } +error: + mutex_unlock(&display->display_lock); + return ret == 0 ? count : ret; } -static DEVICE_ATTR(fod_ui, 0444, - sysfs_fod_ui_read, - NULL); +static DEVICE_ATTR(hbm, 0644, + sysfs_hbm_read, + sysfs_hbm_write); static struct attribute *display_fs_attrs[] = { - &dev_attr_fod_ui.attr, + &dev_attr_hbm.attr, NULL, }; static struct attribute_group display_fs_attrs_group = { @@ -5104,13 +5142,6 @@ static int dsi_display_sysfs_deinit(struct dsi_display *display) } -void dsi_display_set_fod_ui(struct dsi_display *display, bool status) -{ - struct device *dev = &display->pdev->dev; - atomic_set(&display->fod_ui, status); - sysfs_notify(&dev->kobj, NULL, "fod_ui"); -} - /** * dsi_display_bind - bind dsi device with controlling device * @dev: Pointer to base of platform device @@ -5407,7 +5438,6 @@ static void dsi_display_unbind(struct device *dev, } atomic_set(&display->clkrate_change_pending, 0); - atomic_set(&display->fod_ui, false); (void)dsi_display_sysfs_deinit(display); (void)dsi_display_debugfs_deinit(display); diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h index 0331f097321e..6546e60cf083 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h @@ -284,8 +284,6 @@ struct dsi_display { struct dsi_display_boot_param *boot_disp; u32 te_source; - - atomic_t fod_ui; }; int dsi_display_dev_probe(struct platform_device *pdev); @@ -719,8 +717,6 @@ int dsi_display_get_panel_vfp(void *display, struct dsi_display *get_main_display(void); -void dsi_display_set_fod_ui(struct dsi_display *display, bool status); - int dsi_display_cmd_engine_enable(struct dsi_display *display); int dsi_display_cmd_engine_disable(struct dsi_display *display); diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c index 398fb943a8fc..55c740c916f1 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.c +++ b/drivers/gpu/drm/msm/sde/sde_connector.c @@ -617,8 +617,6 @@ void sde_connector_update_fod_hbm(struct drm_connector *connector) mutex_lock(&display->panel->panel_lock); dsi_panel_set_fod_hbm(display->panel, status); mutex_unlock(&display->panel->panel_lock); - - dsi_display_set_fod_ui(display, status); } int sde_connector_pre_kickoff(struct drm_connector *connector) From 409c31b589a283d3696e520f16c68c3546522f77 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Sat, 17 Dec 2022 18:18:30 +0200 Subject: [PATCH 122/226] Revert "display: sde_connector: update FOD HBM on dim layer change" This reverts commit 81d581e862ca5e176c8ca665dff709262f991c1b. Change-Id: Iefe2abbb8e3b1f82c353036a734941203fa9bab4 Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/sde/sde_connector.c | 35 ------------------------- 1 file changed, 35 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c index 55c740c916f1..f35a7a71ae7a 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.c +++ b/drivers/gpu/drm/msm/sde/sde_connector.c @@ -586,39 +586,6 @@ static int _sde_connector_update_dirty_properties( return 0; } -void sde_connector_update_fod_hbm(struct drm_connector *connector) -{ - static atomic_t effective_status = ATOMIC_INIT(false); - struct sde_crtc_state *cstate; - struct sde_connector *c_conn; - struct dsi_display *display; - bool status; - - if (!connector) { - SDE_ERROR("invalid connector\n"); - return; - } - - c_conn = to_sde_connector(connector); - if (c_conn->connector_type != DRM_MODE_CONNECTOR_DSI) - return; - - display = (struct dsi_display *) c_conn->display; - - if (!c_conn->encoder || !c_conn->encoder->crtc || - !c_conn->encoder->crtc->state) - return; - - cstate = to_sde_crtc_state(c_conn->encoder->crtc->state); - status = cstate->fod_dim_layer != NULL; - if (atomic_xchg(&effective_status, status) == status) - return; - - mutex_lock(&display->panel->panel_lock); - dsi_panel_set_fod_hbm(display->panel, status); - mutex_unlock(&display->panel->panel_lock); -} - int sde_connector_pre_kickoff(struct drm_connector *connector) { struct sde_connector *c_conn; @@ -652,8 +619,6 @@ int sde_connector_pre_kickoff(struct drm_connector *connector) SDE_EVT32_VERBOSE(connector->base.id); - sde_connector_update_fod_hbm(connector); - rc = c_conn->ops.pre_kickoff(connector, c_conn->display, ¶ms); end: From fca96657eb4ca6034ac6fad954103c2e98b6920e Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Sat, 17 Dec 2022 18:18:34 +0200 Subject: [PATCH 123/226] Revert "display: sde_crtc: setup dim layer" This reverts commit eb8c3fdd8fac2dafb220058a3efef6a5567008c8. Change-Id: Ia452d135c32136b0e856431c4604c8bfa5aee72c Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/sde/sde_crtc.c | 87 ------------------------------ drivers/gpu/drm/msm/sde/sde_crtc.h | 1 - 2 files changed, 88 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index 39e8d9605b0c..f39c40c86b98 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -42,7 +42,6 @@ #include "sde_power_handle.h" #include "sde_core_perf.h" #include "sde_trace.h" -#include "dsi_display.h" #define SDE_PSTATES_MAX (SDE_STAGE_MAX * 4) #define SDE_MULTIRECT_PLANE_MAX (SDE_STAGE_MAX * 2) @@ -2188,10 +2187,6 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, for (i = 0; i < cstate->num_dim_layers; i++) _sde_crtc_setup_dim_layer_cfg(crtc, sde_crtc, mixer, &cstate->dim_layer[i]); - - if (cstate->fod_dim_layer) - _sde_crtc_setup_dim_layer_cfg(crtc, sde_crtc, - mixer, cstate->fod_dim_layer); } _sde_crtc_program_lm_output_roi(crtc); @@ -5306,86 +5301,6 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc, return 0; } -static struct sde_hw_dim_layer* sde_crtc_setup_fod_dim_layer( - struct sde_crtc_state *cstate, - uint32_t stage) -{ - struct drm_crtc_state *crtc_state = &cstate->base; - struct drm_display_mode *mode = &crtc_state->adjusted_mode; - struct sde_hw_dim_layer *dim_layer = NULL; - struct dsi_display *display; - struct sde_kms *kms; - uint32_t layer_stage; - uint32_t alpha; - - kms = _sde_crtc_get_kms(crtc_state->crtc); - if (!kms || !kms->catalog) { - SDE_ERROR("Invalid kms\n"); - goto error; - } - - layer_stage = SDE_STAGE_0 + stage; - if (layer_stage >= kms->catalog->mixer[0].sblk->maxblendstages) { - SDE_ERROR("Stage too large %u vs max %u\n", layer_stage, - kms->catalog->mixer[0].sblk->maxblendstages); - goto error; - } - - if (cstate->num_dim_layers == SDE_MAX_DIM_LAYERS) { - SDE_ERROR("Max dim layers reached\n"); - goto error; - } - - display = get_main_display(); - if (!display || !display->panel) { - SDE_ERROR("Invalid primary display\n"); - goto error; - } - - mutex_lock(&display->panel->panel_lock); - alpha = dsi_panel_get_fod_dim_alpha(display->panel); - mutex_unlock(&display->panel->panel_lock); - - dim_layer = &cstate->dim_layer[cstate->num_dim_layers]; - dim_layer->flags = SDE_DRM_DIM_LAYER_INCLUSIVE; - dim_layer->stage = layer_stage; - dim_layer->rect.x = 0; - dim_layer->rect.y = 0; - dim_layer->rect.w = mode->hdisplay; - dim_layer->rect.h = mode->vdisplay; - dim_layer->color_fill = - (struct sde_mdss_color) {0, 0, 0, alpha}; - -error: - return dim_layer; -} - -static void sde_crtc_fod_atomic_check(struct sde_crtc_state *cstate, - struct plane_state *pstates, int cnt) -{ - uint32_t dim_layer_stage; - int plane_idx; - - for (plane_idx = 0; plane_idx < cnt; plane_idx++) - if (sde_plane_is_fod_layer(pstates[plane_idx].drm_pstate)) - break; - - if (plane_idx == cnt) { - cstate->fod_dim_layer = NULL; - } else { - dim_layer_stage = pstates[plane_idx].stage; - cstate->fod_dim_layer = sde_crtc_setup_fod_dim_layer(cstate, - dim_layer_stage); - } - - if (!cstate->fod_dim_layer) - return; - - for (plane_idx = 0; plane_idx < cnt; plane_idx++) - if (pstates[plane_idx].stage >= dim_layer_stage) - pstates[plane_idx].stage++; -} - static int sde_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -5581,8 +5496,6 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc, } } - sde_crtc_fod_atomic_check(cstate, pstates, cnt); - /* assign mixer stages based on sorted zpos property */ if (cnt > 0) sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL); diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h index b4f52df21cc7..0357ab4f4dfe 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.h +++ b/drivers/gpu/drm/msm/sde/sde_crtc.h @@ -422,7 +422,6 @@ struct sde_crtc_state { uint64_t input_fence_timeout_ns; uint32_t num_dim_layers; struct sde_hw_dim_layer dim_layer[SDE_MAX_DIM_LAYERS]; - struct sde_hw_dim_layer *fod_dim_layer; uint32_t num_ds; uint32_t num_ds_enabled; bool ds_dirty; From be7cf6f6b92daa9800ae572c1324c4e9e61bbf5a Mon Sep 17 00:00:00 2001 From: pwnrazr <1644943+pwnrazr@users.noreply.github.com> Date: Thu, 5 Jan 2023 21:36:08 +0800 Subject: [PATCH 124/226] drivers: dsi_panel: prepare for new fod stuff Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 99 --------------------- drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 13 +-- 2 files changed, 3 insertions(+), 109 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index ab7aa8c80dea..8c0f3b8f103d 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -753,39 +753,6 @@ static int dsi_panel_update_pwm_backlight(struct dsi_panel *panel, return rc; } -static u32 dsi_panel_get_backlight(struct dsi_panel *panel) -{ - return panel->bl_config.bl_level; -} - -static u32 interpolate(uint32_t x, uint32_t xa, uint32_t xb, uint32_t ya, uint32_t yb) -{ - return ya - (ya - yb) * (x - xa) / (xb - xa); -} - -u32 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel) -{ - u32 brightness = dsi_panel_get_backlight(panel); - int i; - - if (!panel->fod_dim_lut) - return 0; - - for (i = 0; i < panel->fod_dim_lut_count; i++) - if (panel->fod_dim_lut[i].brightness >= brightness) - break; - - if (i == 0) - return panel->fod_dim_lut[i].alpha; - - if (i == panel->fod_dim_lut_count) - return panel->fod_dim_lut[i - 1].alpha; - - return interpolate(brightness, - panel->fod_dim_lut[i - 1].brightness, panel->fod_dim_lut[i].brightness, - panel->fod_dim_lut[i - 1].alpha, panel->fod_dim_lut[i].alpha); -} - int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status) { int rc = 0; @@ -2783,68 +2750,6 @@ static int dsi_panel_parse_bl_pwm_config(struct dsi_panel *panel) return rc; } -static int dsi_panel_parse_fod_dim_lut(struct dsi_panel *panel, - struct dsi_parser_utils *utils) -{ - struct brightness_alpha_pair *lut; - u32 *array; - int count; - int len; - int rc; - int i; - - len = utils->count_u32_elems(utils->data, "qcom,disp-fod-dim-lut"); - if (len <= 0 || len % BRIGHTNESS_ALPHA_PAIR_LEN) { - pr_err("[%s] invalid number of elements, rc=%d\n", - panel->name, rc); - rc = -EINVAL; - goto count_fail; - } - - array = kcalloc(len, sizeof(u32), GFP_KERNEL); - if (!array) { - pr_err("[%s] failed to allocate memory, rc=%d\n", - panel->name, rc); - rc = -ENOMEM; - goto alloc_array_fail; - } - - rc = utils->read_u32_array(utils->data, - "qcom,disp-fod-dim-lut", array, len); - if (rc) { - pr_err("[%s] failed to allocate memory, rc=%d\n", - panel->name, rc); - goto read_fail; - } - - count = len / BRIGHTNESS_ALPHA_PAIR_LEN; - lut = kcalloc(count, sizeof(*lut), GFP_KERNEL); - if (!lut) { - rc = -ENOMEM; - goto alloc_lut_fail; - } - - for (i = 0; i < count; i++) { - struct brightness_alpha_pair *pair = &lut[i]; - pair->brightness = array[i * BRIGHTNESS_ALPHA_PAIR_LEN + 0]; - pair->alpha = array[i * BRIGHTNESS_ALPHA_PAIR_LEN + 1]; - } - - panel->fod_dim_lut = lut; - panel->fod_dim_lut_count = count; - -alloc_lut_fail: -read_fail: - kfree(array); -alloc_array_fail: -count_fail: - if (rc) { - panel->fod_dim_lut = NULL; - panel->fod_dim_lut_count = 0; - } - return rc; -} - static int dsi_panel_parse_bl_config(struct dsi_panel *panel) { int rc = 0; @@ -2934,10 +2839,6 @@ static int dsi_panel_parse_bl_config(struct dsi_panel *panel) panel->bl_config.bl_inverted_dbv = utils->read_bool(utils->data, "qcom,mdss-dsi-bl-inverted-dbv"); - rc = dsi_panel_parse_fod_dim_lut(panel, utils); - if (rc) - pr_err("[%s failed to parse fod dim lut\n", panel->name); - if (panel->bl_config.type == DSI_BACKLIGHT_PWM) { rc = dsi_panel_parse_bl_pwm_config(panel); if (rc) { diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index b8e0aa5b2b0e..b801a1c42d52 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -179,12 +179,6 @@ struct drm_panel_esd_config { #endif }; -#define BRIGHTNESS_ALPHA_PAIR_LEN 2 -struct brightness_alpha_pair { - u32 brightness; - u32 alpha; -}; - #if defined(CONFIG_MACH_XIAOMI_VAYU) || defined(CONFIG_MACH_XIAOMI_NABU) struct lockdowninfo_cfg { u8 lockdowninfo[16]; @@ -251,7 +245,6 @@ struct dsi_panel { int power_mode; enum dsi_panel_physical_type panel_type; - struct brightness_alpha_pair *fod_dim_lut; u32 fod_dim_lut_count; bool cphy_esd_check; @@ -266,6 +259,8 @@ struct dsi_panel { struct lockdowninfo_cfg lockdowninfo_read; #endif + int hbm_mode; + bool resend_ea; }; static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel) @@ -386,9 +381,6 @@ int dsi_panel_parse_esd_reg_read_configs(struct dsi_panel *panel); void dsi_panel_ext_bridge_put(struct dsi_panel *panel); -int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status); - -u32 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel); int dsi_panel_set_esd_check(struct dsi_panel *panel); @@ -408,5 +400,6 @@ void dsi_panel_doubleclick_enable(bool on); int dsi_panel_lockdowninfo_param_read(struct dsi_panel *panel); #endif +int dsi_panel_apply_hbm_mode(struct dsi_panel *panel); #endif /* _DSI_PANEL_H_ */ From 7097c6f24a4f8fd0d79ced120ea7a6dad28e2882 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 10 Feb 2022 15:08:04 +0200 Subject: [PATCH 125/226] display: dsi_panel: read FOD dimming LUT Change-Id: I23f7914ce0adf6c1942c09212516ed5f6b22d289 Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 58 +++++++++++++++++++++ drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 9 ++++ 2 files changed, 67 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 8c0f3b8f103d..ea80048cc494 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -2750,6 +2750,60 @@ static int dsi_panel_parse_bl_pwm_config(struct dsi_panel *panel) return rc; } +static int dsi_panel_parse_fod_dim_lut(struct dsi_panel *panel, + struct dsi_parser_utils *utils) +{ + const char *prop_name = "qcom,fod-dim-lut"; + unsigned int i; + u32 *array; + int count; + int rc; + + count = utils->count_u32_elems(utils->data, prop_name); + if (count <= 0 || count % BRIGHTNESS_ALPHA_PAIR_LEN) { + pr_err("[%s] invalid number of elements %d\n", + panel->name, count); + rc = -EINVAL; + goto count_fail; + } + + array = kcalloc(count, sizeof(u32), GFP_KERNEL); + if (!array) { + rc = -ENOMEM; + goto alloc_array_fail; + } + + rc = utils->read_u32_array(utils->data, prop_name, array, count); + if (rc) { + pr_err("[%s] failed to read array, rc=%d\n", panel->name, rc); + goto read_fail; + } + + count /= BRIGHTNESS_ALPHA_PAIR_LEN; + panel->fod_dim_lut = kcalloc(count, sizeof(*panel->fod_dim_lut), + GFP_KERNEL); + if (!panel->fod_dim_lut) { + rc = -ENOMEM; + goto alloc_lut_fail; + } + + panel->fod_dim_lut_len = count; + + for (i = 0; i < count; i++) { + struct brightness_alpha_pair *pair = &panel->fod_dim_lut[i]; + pair->brightness = array[i * BRIGHTNESS_ALPHA_PAIR_LEN + 0]; + pair->alpha = array[i * BRIGHTNESS_ALPHA_PAIR_LEN + 1]; + } + +alloc_lut_fail: +read_fail: + kfree(array); +alloc_array_fail: +count_fail: + + return rc; +} + static int dsi_panel_parse_bl_config(struct dsi_panel *panel) { int rc = 0; @@ -2839,6 +2893,10 @@ static int dsi_panel_parse_bl_config(struct dsi_panel *panel) panel->bl_config.bl_inverted_dbv = utils->read_bool(utils->data, "qcom,mdss-dsi-bl-inverted-dbv"); + rc = dsi_panel_parse_fod_dim_lut(panel, utils); + if (rc) + pr_err("[%s] failed to parse fod dim lut\n", panel->name); + if (panel->bl_config.type == DSI_BACKLIGHT_PWM) { rc = dsi_panel_parse_bl_pwm_config(panel); if (rc) { diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index b801a1c42d52..f7a6229aee82 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -194,6 +194,12 @@ struct dsi_read_config { }; #endif +#define BRIGHTNESS_ALPHA_PAIR_LEN 2 +struct brightness_alpha_pair { + u16 brightness; + u8 alpha; +}; + struct dsi_panel { const char *name; const char *type; @@ -261,6 +267,9 @@ struct dsi_panel { #endif int hbm_mode; bool resend_ea; + + struct brightness_alpha_pair *fod_dim_lut; + unsigned int fod_dim_lut_len; }; static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel) From e402d376669d2e95e3368a616c56c630d4580ced Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Sun, 18 Dec 2022 04:47:12 +0200 Subject: [PATCH 126/226] display: use CSC for FOD dimming Change-Id: I713646b79c6fafda14614ff9eca742f2724420e3 Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/sde/sde_crtc.c | 38 +++++++++++++++++++++++++++++ drivers/gpu/drm/msm/sde/sde_crtc.h | 5 ++++ drivers/gpu/drm/msm/sde/sde_plane.c | 32 +++++++++++++++++++++++- drivers/gpu/drm/msm/sde/sde_plane.h | 4 +++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index f39c40c86b98..0ae0d9eef458 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -42,6 +42,7 @@ #include "sde_power_handle.h" #include "sde_core_perf.h" #include "sde_trace.h" +#include "dsi_display.h" #define SDE_PSTATES_MAX (SDE_STAGE_MAX * 4) #define SDE_MULTIRECT_PLANE_MAX (SDE_STAGE_MAX * 2) @@ -5301,6 +5302,34 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc, return 0; } +static void sde_crtc_fod_atomic_check(struct sde_crtc_state *cstate, + struct plane_state *pstates, int cnt) +{ + unsigned int fod_plane_idx, plane_idx; + u8 alpha = 0; + + for (plane_idx = 0; plane_idx < cnt; plane_idx++) + if (sde_plane_is_fod_layer(pstates[plane_idx].drm_pstate)) + break; + + fod_plane_idx = plane_idx; + + if (fod_plane_idx != cnt) { + struct dsi_display *display = get_main_display(); + alpha = dsi_panel_get_fod_dim_alpha(display->panel); + } + + cstate->fod_dim_alpha = alpha; + + for (plane_idx = 0; plane_idx < cnt; plane_idx++) { + if (plane_idx == fod_plane_idx) + continue; + + sde_plane_set_fod_dim_alpha(pstates[plane_idx].sde_pstate, + alpha); + } +} + static int sde_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -5496,6 +5525,8 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc, } } + sde_crtc_fod_atomic_check(cstate, pstates, cnt); + /* assign mixer stages based on sorted zpos property */ if (cnt > 0) sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL); @@ -5603,6 +5634,13 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc, return rc; } +bool sde_crtc_is_fod_enabled(struct drm_crtc_state *state) +{ + struct sde_crtc_state *cstate = to_sde_crtc_state(state); + + return cstate->fod_dim_alpha != 0; +} + /** * sde_crtc_get_num_datapath - get the number of datapath active * of primary connector diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h index 0357ab4f4dfe..428af58cd407 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.h +++ b/drivers/gpu/drm/msm/sde/sde_crtc.h @@ -439,6 +439,8 @@ struct sde_crtc_state { u32 padding_dummy; struct sde_crtc_respool rp; + + u8 fod_dim_alpha; }; enum sde_crtc_irq_state { @@ -866,4 +868,7 @@ int sde_crtc_get_num_datapath(struct drm_crtc *crtc, * @cstate: Pointer to drm crtc state */ void _sde_crtc_clear_dim_layers_v1(struct drm_crtc_state *state); + +bool sde_crtc_is_fod_enabled(struct drm_crtc_state *state); + #endif /* _SDE_CRTC_H_ */ diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index 6cdca037e782..743552ab169f 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -148,6 +148,8 @@ struct sde_plane { struct sde_debugfs_regset32 debugfs_scaler; struct sde_debugfs_regset32 debugfs_csc; bool debugfs_default_scale; + + u8 fod_dim_alpha; }; #define to_sde_plane(x) container_of(x, struct sde_plane, base) @@ -1410,6 +1412,7 @@ static inline void _sde_plane_setup_csc(struct sde_plane *psde) #define CSC_8BIT_LIMIT 0xff #define PCC_MASK 0x3ffff #define PCC_ONE (1 << 15) +#define FOD_DIM_ALPHA_MAX 255 #define CSC_BIAS_CLAMP(value) \ { 0, 0, 0 }, \ @@ -1417,6 +1420,11 @@ static inline void _sde_plane_setup_csc(struct sde_plane *psde) { 0, value, 0, value, 0, value }, \ { 0, value, 0, value, 0, value } +static const struct drm_msm_pcc sde_identity_pcc_cfg = { + .r = { .r = PCC_ONE }, + .g = { .g = PCC_ONE }, + .b = { .b = PCC_ONE }, +}; static const struct sde_csc_cfg sde_identity_csc_cfg = { { CSC_ONE, 0, 0, @@ -1459,6 +1467,7 @@ static inline s32 pcc_to_signed(u32 v) static inline void _sde_plane_mul_csc_pcc(struct sde_plane *psde, const struct sde_csc_cfg *csc_cfg) { + unsigned int fod_dim_scale = FOD_DIM_ALPHA_MAX - psde->fod_dim_alpha; unsigned int i, j, u; memcpy(&psde->csc_pcc_cfg, csc_cfg, sizeof(psde->csc_pcc_cfg)); @@ -1477,7 +1486,8 @@ static inline void _sde_plane_mul_csc_pcc(struct sde_plane *psde, sum += csc * pcc; } - sum = div_s64(sum, PCC_ONE); + sum = mult_frac(sum, fod_dim_scale, + PCC_ONE * FOD_DIM_ALPHA_MAX); psde->csc_pcc_cfg.csc_mv[ij] = csc_to_unsigned(sum); } @@ -4010,12 +4020,26 @@ void sde_plane_set_error(struct drm_plane *plane, bool error) psde->is_error = error; } +static inline void _set_plane_set_fod_dim_alpha(struct sde_plane *psde, + struct sde_plane_state *pstate) +{ + if (psde->fod_dim_alpha == pstate->fod_dim_alpha) + return; + + psde->fod_dim_alpha = pstate->fod_dim_alpha; + + pstate->dirty |= SDE_PLANE_DIRTY_RECTS; +} + static inline void _sde_plane_set_csc_pcc(struct sde_plane *psde, struct sde_plane_state *pstate, struct drm_crtc *crtc) { const struct drm_msm_pcc *pcc_cfg = sde_cp_crtc_get_pcc_cfg(crtc); + if (!pcc_cfg && psde->fod_dim_alpha) + pcc_cfg = &sde_identity_pcc_cfg; + if (pcc_cfg == psde->pcc_cfg) return; @@ -4190,6 +4214,7 @@ static int sde_plane_sspp_atomic_update(struct drm_plane *plane, _sde_plane_sspp_atomic_check_mode_changed(psde, state, old_state); + _set_plane_set_fod_dim_alpha(psde, pstate); _sde_plane_set_csc_pcc(psde, pstate, crtc); /* re-program the output rects always if partial update roi changed */ @@ -4482,6 +4507,11 @@ int sde_plane_is_fod_layer(const struct drm_plane_state *drm_state) return sde_plane_get_property(pstate, PLANE_PROP_FOD); } +void sde_plane_set_fod_dim_alpha(struct sde_plane_state *pstate, u8 alpha) +{ + pstate->fod_dim_alpha = alpha; +} + static void sde_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { diff --git a/drivers/gpu/drm/msm/sde/sde_plane.h b/drivers/gpu/drm/msm/sde/sde_plane.h index bd8b633e2375..b49ac780edfd 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.h +++ b/drivers/gpu/drm/msm/sde/sde_plane.h @@ -171,6 +171,8 @@ struct sde_plane_state { struct sde_hw_pipe_cdp_cfg cdp_cfg; struct sde_hw_pipe_line_insertion_cfg line_insertion_cfg; + + u8 fod_dim_alpha; }; /** @@ -400,4 +402,6 @@ void sde_plane_setup_src_split_order(struct drm_plane *plane, int sde_plane_is_fod_layer(const struct drm_plane_state *drm_state); +void sde_plane_set_fod_dim_alpha(struct sde_plane_state *pstatem, u8 alpha); + #endif /* _SDE_PLANE_H_ */ From 13dd5bf4134a6244651ad38d0d220ad508e7a5b0 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Mon, 19 Dec 2022 16:33:16 +0200 Subject: [PATCH 127/226] display: dsi_panel: expose FOD dim alpha Change-Id: I2c4431105df6082fcfbaacdbab9165f89720824b Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 11 +++++++++++ drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index ea80048cc494..82f58a321679 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -753,6 +753,17 @@ static int dsi_panel_update_pwm_backlight(struct dsi_panel *panel, return rc; } +u8 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel) +{ + u8 alpha; + + mutex_lock(&panel->panel_lock); + alpha = panel->fod_dim_alpha; + mutex_unlock(&panel->panel_lock); + + return alpha; +} + int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status) { int rc = 0; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index f7a6229aee82..613f1acbe583 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -390,7 +390,6 @@ int dsi_panel_parse_esd_reg_read_configs(struct dsi_panel *panel); void dsi_panel_ext_bridge_put(struct dsi_panel *panel); - int dsi_panel_set_esd_check(struct dsi_panel *panel); int dsi_panel_sync_pen_fps(struct dsi_panel *panel, @@ -409,6 +408,8 @@ void dsi_panel_doubleclick_enable(bool on); int dsi_panel_lockdowninfo_param_read(struct dsi_panel *panel); #endif +u8 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel); + int dsi_panel_apply_hbm_mode(struct dsi_panel *panel); #endif /* _DSI_PANEL_H_ */ From 89ffacaeaceaba781e704acb3578221a93569cf7 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 10 Feb 2022 15:15:59 +0200 Subject: [PATCH 128/226] display: dsi_panel: expose FOD dim Change-Id: I439f536efefb7b338462ccf6d03b078cea76c1c3 Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 40 +++++++++++++++++++-- drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 4 +++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 82f58a321679..e6fc3725cb4e 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -764,6 +764,42 @@ u8 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel) return alpha; } +static u32 dsi_panel_get_backlight(struct dsi_panel *panel) +{ + return panel->bl_config.real_bl_level; +} + +static u32 interpolate(uint32_t x, uint32_t xa, uint32_t xb, + uint32_t ya, uint32_t yb) +{ + return ya - (ya - yb) * (x - xa) / (xb - xa); +} + +static u32 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel) +{ + u32 brightness = dsi_panel_get_backlight(panel); + int i; + + if (!panel->fod_dim_lut) + return 0; + + for (i = 0; i < panel->fod_dim_lut_len; i++) + if (panel->fod_dim_lut[i].brightness >= brightness) + break; + + if (i == 0) + return panel->fod_dim_lut[i].alpha; + + if (i == panel->fod_dim_lut_len) + return panel->fod_dim_lut[i - 1].alpha; + + return interpolate(brightness, + panel->fod_dim_lut[i - 1].brightness, + panel->fod_dim_lut[i].brightness, + panel->fod_dim_lut[i - 1].alpha, + panel->fod_dim_lut[i].alpha); +} + int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status) { int rc = 0; @@ -1182,9 +1218,7 @@ int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl) rc = -ENOTSUPP; } - if (last_backlight == 0 && panel->cphy_esd_check) { - schedule_delayed_work(&panel->esd_work, msecs_to_jiffies(300)); - } + panel->fod_dim_alpha = dsi_panel_get_fod_dim_alpha(panel); return rc; } diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index 613f1acbe583..4ec3bda5432d 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -270,6 +270,8 @@ struct dsi_panel { struct brightness_alpha_pair *fod_dim_lut; unsigned int fod_dim_lut_len; + u8 fod_dim_alpha; + bool fod_hbm_enabled; }; static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel) @@ -412,4 +414,6 @@ u8 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel); int dsi_panel_apply_hbm_mode(struct dsi_panel *panel); +int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status); + #endif /* _DSI_PANEL_H_ */ From ba9069f01bf6102254e638ba292c6dc657e4ea37 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Fri, 10 Sep 2021 00:47:53 +0300 Subject: [PATCH 129/226] display: dsi_panel: track real backlight value Change-Id: I5b6d71687cc6c208381c285187eaa1a6bfffecc7 Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 2 ++ drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index e6fc3725cb4e..e15a59324cd2 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -1218,6 +1218,7 @@ int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl) rc = -ENOTSUPP; } + bl->real_bl_level = bl_lvl; panel->fod_dim_alpha = dsi_panel_get_fod_dim_alpha(panel); return rc; @@ -2896,6 +2897,7 @@ static int dsi_panel_parse_bl_config(struct dsi_panel *panel) panel->bl_config.bl_scale = MAX_BL_SCALE_LEVEL; panel->bl_config.bl_scale_ad = MAX_AD_BL_SCALE_LEVEL; + panel->bl_config.real_bl_level = 0; rc = utils->read_u32(utils->data, "qcom,mdss-dsi-bl-min-level", &val); if (rc) { diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index 4ec3bda5432d..e5379c6b0e48 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -124,6 +124,7 @@ struct dsi_backlight_config { u32 bl_scale; u32 bl_scale_ad; bool bl_inverted_dbv; + u32 real_bl_level; int en_gpio; bool dcs_type_ss; From 11d920e8a159cf059d0f11956a2014204d440af7 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Sat, 17 Dec 2022 18:37:26 +0200 Subject: [PATCH 130/226] display: dsi_panel_get_fod_dim_alpha -> dsi_panel_calc_fod_dim_alpha Change-Id: I7d27bb9ff4d2f5eebb7a1cf4365ac1850b264b37 Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index e15a59324cd2..27e945ca38e7 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -764,27 +764,21 @@ u8 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel) return alpha; } -static u32 dsi_panel_get_backlight(struct dsi_panel *panel) -{ - return panel->bl_config.real_bl_level; -} - static u32 interpolate(uint32_t x, uint32_t xa, uint32_t xb, uint32_t ya, uint32_t yb) { return ya - (ya - yb) * (x - xa) / (xb - xa); } -static u32 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel) +static u32 dsi_panel_calc_fod_dim_alpha(struct dsi_panel *panel, u32 bl_level) { - u32 brightness = dsi_panel_get_backlight(panel); int i; if (!panel->fod_dim_lut) return 0; for (i = 0; i < panel->fod_dim_lut_len; i++) - if (panel->fod_dim_lut[i].brightness >= brightness) + if (panel->fod_dim_lut[i].brightness >= bl_level) break; if (i == 0) @@ -793,7 +787,7 @@ static u32 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel) if (i == panel->fod_dim_lut_len) return panel->fod_dim_lut[i - 1].alpha; - return interpolate(brightness, + return interpolate(bl_level, panel->fod_dim_lut[i - 1].brightness, panel->fod_dim_lut[i].brightness, panel->fod_dim_lut[i - 1].alpha, @@ -1219,7 +1213,7 @@ int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl) } bl->real_bl_level = bl_lvl; - panel->fod_dim_alpha = dsi_panel_get_fod_dim_alpha(panel); + panel->fod_dim_alpha = dsi_panel_calc_fod_dim_alpha(panel, bl_lvl); return rc; } From 9a8905814e8ede76154bb92909a8fe77992030ca Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 10 Feb 2022 10:35:42 +0200 Subject: [PATCH 131/226] display: dsi_panel: create empty ettributes group Change-Id: Ia1e747272240d380c82843d9faeeedac7bc58d9b Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 37 +++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 27e945ca38e7..7f596326bee5 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -4070,8 +4070,34 @@ struct dsi_panel *dsi_panel_get(struct device *parent, return ERR_PTR(rc); } +static struct attribute *panel_attrs[] = { + NULL, +}; + +static struct attribute_group panel_attrs_group = { + .attrs = panel_attrs, +}; + +static int dsi_panel_sysfs_init(struct dsi_panel *panel) +{ + int rc = 0; + + rc = sysfs_create_group(&panel->parent->kobj, &panel_attrs_group); + if (rc) + pr_err("failed to create panel sysfs attributes\n"); + + return rc; +} + +static void dsi_panel_sysfs_deinit(struct dsi_panel *panel) +{ + sysfs_remove_group(&panel->parent->kobj, &panel_attrs_group); +} + void dsi_panel_put(struct dsi_panel *panel) { + dsi_panel_sysfs_deinit(panel); + /* free resources allocated for ESD check */ dsi_panel_esd_config_deinit(&panel->esd_config); @@ -4131,6 +4157,17 @@ int dsi_panel_drv_init(struct dsi_panel *panel, goto error_gpio_release; } + rc = dsi_panel_sysfs_init(panel); + if (rc) + goto exit; + +#ifdef CONFIG_EXPOSURE_ADJUSTMENT + rc = sysfs_create_group(&(panel->parent->kobj), &mdss_fb_attr_group); + if (rc) + pr_err("sysfs group creation failed, rc=%d\n", rc); + set_panel = panel; +#endif + goto exit; error_gpio_release: From 239f4edd3bfb249d36ed9dfb9ee5d24bc89796d0 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 10 Feb 2022 16:37:05 +0200 Subject: [PATCH 132/226] display: dsi_panel: expose attribute to notify of fod changes Change-Id: I6bdb767567c09e1a4cbd3b2d626e1173baf9089f Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 29 +++++++++++++++++++++ drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 3 +++ 2 files changed, 32 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 7f596326bee5..c419e61738a3 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -1270,6 +1270,18 @@ static int dsi_panel_pwm_register(struct dsi_panel *panel) return 0; } +bool dsi_panel_get_fod_ui(struct dsi_panel *panel) +{ + return panel->fod_ui; +} + +void dsi_panel_set_fod_ui(struct dsi_panel *panel, bool status) +{ + panel->fod_ui = status; + + sysfs_notify(&panel->parent->kobj, NULL, "fod_ui"); +} + static int dsi_panel_bl_register(struct dsi_panel *panel) { int rc = 0; @@ -4070,7 +4082,24 @@ struct dsi_panel *dsi_panel_get(struct device *parent, return ERR_PTR(rc); } +static ssize_t sysfs_fod_ui_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dsi_display *display = dev_get_drvdata(dev); + struct dsi_panel *panel = display->panel; + bool status; + + mutex_lock(&panel->panel_lock); + status = panel->fod_ui; + mutex_unlock(&panel->panel_lock); + + return snprintf(buf, PAGE_SIZE, "%u\n", status); +} + +static DEVICE_ATTR(fod_ui, 0444, sysfs_fod_ui_read, NULL); + static struct attribute *panel_attrs[] = { + &dev_attr_fod_ui.attr, NULL, }; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index e5379c6b0e48..dd27c08aba28 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -273,6 +273,7 @@ struct dsi_panel { unsigned int fod_dim_lut_len; u8 fod_dim_alpha; bool fod_hbm_enabled; + bool fod_ui; }; static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel) @@ -416,5 +417,7 @@ u8 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel); int dsi_panel_apply_hbm_mode(struct dsi_panel *panel); int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status); +bool dsi_panel_get_fod_ui(struct dsi_panel *panel); +void dsi_panel_set_fod_ui(struct dsi_panel *panel, bool status); #endif /* _DSI_PANEL_H_ */ From acf23581abf00ba011e5b421e52681804d0ecfd2 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Fri, 13 May 2022 09:33:09 +0300 Subject: [PATCH 133/226] display: expose forcing FOD UI for debugging Change-Id: I1f1b5344c9f98b541dc5c99e5d6f9c5560d8340c Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 29 +++++++++++++++++++++ drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 2 ++ drivers/gpu/drm/msm/sde/sde_crtc.c | 6 ++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index c419e61738a3..697db6c49c89 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -1282,6 +1282,11 @@ void dsi_panel_set_fod_ui(struct dsi_panel *panel, bool status) sysfs_notify(&panel->parent->kobj, NULL, "fod_ui"); } +bool dsi_panel_get_force_fod_ui(struct dsi_panel *panel) +{ + return panel->force_fod_ui; +} + static int dsi_panel_bl_register(struct dsi_panel *panel) { int rc = 0; @@ -4096,10 +4101,34 @@ static ssize_t sysfs_fod_ui_read(struct device *dev, return snprintf(buf, PAGE_SIZE, "%u\n", status); } +static ssize_t sysfs_force_fod_ui_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dsi_display *display = dev_get_drvdata(dev); + struct dsi_panel *panel = display->panel; + + return snprintf(buf, PAGE_SIZE, "%u\n", panel->force_fod_ui); +} + +ssize_t sysfs_force_fod_ui_write(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct dsi_display *display = dev_get_drvdata(dev); + struct dsi_panel *panel = display->panel; + + kstrtobool(buf, &panel->force_fod_ui); + + return count; +} + static DEVICE_ATTR(fod_ui, 0444, sysfs_fod_ui_read, NULL); +static DEVICE_ATTR(force_fod_ui, 0644, + sysfs_force_fod_ui_read, + sysfs_force_fod_ui_write); static struct attribute *panel_attrs[] = { &dev_attr_fod_ui.attr, + &dev_attr_force_fod_ui.attr, NULL, }; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index dd27c08aba28..b831f230767b 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -274,6 +274,7 @@ struct dsi_panel { u8 fod_dim_alpha; bool fod_hbm_enabled; bool fod_ui; + bool force_fod_ui; }; static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel) @@ -419,5 +420,6 @@ int dsi_panel_apply_hbm_mode(struct dsi_panel *panel); int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status); bool dsi_panel_get_fod_ui(struct dsi_panel *panel); void dsi_panel_set_fod_ui(struct dsi_panel *panel, bool status); +bool dsi_panel_get_force_fod_ui(struct dsi_panel *panel); #endif /* _DSI_PANEL_H_ */ diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index 0ae0d9eef458..516452fc1d62 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -5305,7 +5305,9 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc, static void sde_crtc_fod_atomic_check(struct sde_crtc_state *cstate, struct plane_state *pstates, int cnt) { + struct dsi_display *display = get_main_display(); unsigned int fod_plane_idx, plane_idx; + bool force_fod_ui; u8 alpha = 0; for (plane_idx = 0; plane_idx < cnt; plane_idx++) @@ -5314,7 +5316,9 @@ static void sde_crtc_fod_atomic_check(struct sde_crtc_state *cstate, fod_plane_idx = plane_idx; - if (fod_plane_idx != cnt) { + force_fod_ui = dsi_panel_get_force_fod_ui(display->panel); + + if (fod_plane_idx != cnt || force_fod_ui) { struct dsi_display *display = get_main_display(); alpha = dsi_panel_get_fod_dim_alpha(display->panel); } From 1ba001dc88ff89eb223aba1ab1040321d7fe4ce2 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Wed, 1 Jun 2022 11:35:11 +0300 Subject: [PATCH 134/226] display: expose dim alpha for debugging Change-Id: I474cf172c14f7a49225ff9a386bffde8f21916cc Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 40 ++++++++++++++++++++- drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 1 + 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 697db6c49c89..af198fdcd4c2 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -1213,7 +1213,9 @@ int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl) } bl->real_bl_level = bl_lvl; - panel->fod_dim_alpha = dsi_panel_calc_fod_dim_alpha(panel, bl_lvl); + + if (!panel->force_fod_dim_alpha) + panel->fod_dim_alpha = dsi_panel_calc_fod_dim_alpha(panel, bl_lvl); return rc; } @@ -4121,13 +4123,49 @@ ssize_t sysfs_force_fod_ui_write(struct device *dev, return count; } +static ssize_t sysfs_fod_dim_alpha_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dsi_display *display = dev_get_drvdata(dev); + struct dsi_panel *panel = display->panel; + + return snprintf(buf, PAGE_SIZE, "%u\n", panel->fod_dim_alpha); +} + +ssize_t sysfs_fod_dim_alpha_write(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct dsi_display *display = dev_get_drvdata(dev); + struct dsi_panel *panel = display->panel; + int value; + + sscanf(buf, "%d", &value); + + if (value > 255) + return -EINVAL; + + panel->force_fod_dim_alpha = value >= 0; + + if (!panel->force_fod_dim_alpha) + goto exit; + + panel->fod_dim_alpha = value; + +exit: + return count; +} + static DEVICE_ATTR(fod_ui, 0444, sysfs_fod_ui_read, NULL); static DEVICE_ATTR(force_fod_ui, 0644, sysfs_force_fod_ui_read, sysfs_force_fod_ui_write); +static DEVICE_ATTR(fod_dim_alpha, 0644, + sysfs_fod_dim_alpha_read, + sysfs_fod_dim_alpha_write); static struct attribute *panel_attrs[] = { &dev_attr_fod_ui.attr, + &dev_attr_fod_dim_alpha.attr, &dev_attr_force_fod_ui.attr, NULL, }; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index b831f230767b..063619f98658 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -275,6 +275,7 @@ struct dsi_panel { bool fod_hbm_enabled; bool fod_ui; bool force_fod_ui; + bool force_fod_dim_alpha; }; static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel) From 12b717f30188ad8101ff991b55ea19471c378824 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 10 Feb 2022 16:37:55 +0200 Subject: [PATCH 135/226] display: sde_connector: update FOD HBM on FOD status change Change-Id: Ifd50bfe7996c70d03c9bf41b72da1893a90137c0 Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/sde/sde_connector.c | 44 +++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c index f35a7a71ae7a..e9ea6e434b6a 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.c +++ b/drivers/gpu/drm/msm/sde/sde_connector.c @@ -586,6 +586,47 @@ static int _sde_connector_update_dirty_properties( return 0; } +static bool sde_connector_is_fod_enabled(struct sde_connector *c_conn) +{ + struct drm_connector *connector = &c_conn->base; + + if (!connector->state || !connector->state->crtc) + return false; + + return sde_crtc_is_fod_enabled(connector->state->crtc->state); +} + +struct dsi_panel *sde_connector_panel(struct sde_connector *c_conn) +{ + struct dsi_display *display = (struct dsi_display *)c_conn->display; + + return display ? display->panel : NULL; +} + +static void sde_connector_pre_update_fod_hbm(struct sde_connector *c_conn) +{ + struct dsi_panel *panel; + bool status; + + panel = sde_connector_panel(c_conn); + if (!panel) + return; + + status = sde_connector_is_fod_enabled(c_conn); + if (status == dsi_panel_get_fod_ui(panel)) + return; + + if (status) + sde_encoder_wait_for_event(c_conn->encoder, MSM_ENC_VBLANK); + + dsi_panel_set_fod_hbm(panel, status); + + if (!status) + sde_encoder_wait_for_event(c_conn->encoder, MSM_ENC_VBLANK); + + dsi_panel_set_fod_ui(panel, status); +} + int sde_connector_pre_kickoff(struct drm_connector *connector) { struct sde_connector *c_conn; @@ -619,6 +660,9 @@ int sde_connector_pre_kickoff(struct drm_connector *connector) SDE_EVT32_VERBOSE(connector->base.id); + if (c_conn->connector_type == DRM_MODE_CONNECTOR_DSI) + sde_connector_pre_update_fod_hbm(c_conn); + rc = c_conn->ops.pre_kickoff(connector, c_conn->display, ¶ms); end: From 9a6619e370ddb4d699eaa4964630d1c2eb0e2eac Mon Sep 17 00:00:00 2001 From: John Galt Date: Tue, 20 Dec 2022 09:52:16 -0500 Subject: [PATCH 136/226] sde_plane: correctly set PLANE_PROP_FOD to dirty rects [pwnrazr:we use PLANE_PROP_FOD in raphael] Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/sde/sde_plane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index 743552ab169f..53f1abf39352 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -4149,6 +4149,7 @@ static int sde_plane_sspp_atomic_update(struct drm_plane *plane, case PLANE_PROP_V_DECIMATE: case PLANE_PROP_SRC_CONFIG: case PLANE_PROP_ZPOS: + case PLANE_PROP_FOD: case PLANE_PROP_EXCL_RECT_V1: pstate->dirty |= SDE_PLANE_DIRTY_RECTS; break; @@ -4166,7 +4167,6 @@ static int sde_plane_sspp_atomic_update(struct drm_plane *plane, case PLANE_PROP_ALPHA: case PLANE_PROP_INPUT_FENCE: case PLANE_PROP_BLEND_OP: - case PLANE_PROP_FOD: /* no special action required */ break; case PLANE_PROP_FB_TRANSLATION_MODE: From f4c60d14b1b747b62ebd6b3da8db82169c8d916e Mon Sep 17 00:00:00 2001 From: John Galt Date: Tue, 3 Jan 2023 15:58:51 -0500 Subject: [PATCH 137/226] sde_connector: fix off by one frame on press hbm for dim Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/sde/sde_connector.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c index e9ea6e434b6a..c37d994dd54d 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.c +++ b/drivers/gpu/drm/msm/sde/sde_connector.c @@ -616,14 +616,8 @@ static void sde_connector_pre_update_fod_hbm(struct sde_connector *c_conn) if (status == dsi_panel_get_fod_ui(panel)) return; - if (status) - sde_encoder_wait_for_event(c_conn->encoder, MSM_ENC_VBLANK); - dsi_panel_set_fod_hbm(panel, status); - if (!status) - sde_encoder_wait_for_event(c_conn->encoder, MSM_ENC_VBLANK); - dsi_panel_set_fod_ui(panel, status); } From 2575efb7c205d3c07ebaf412bc877b002df53d02 Mon Sep 17 00:00:00 2001 From: pwnrazr <1644943+pwnrazr@users.noreply.github.com> Date: Thu, 5 Jan 2023 17:50:04 +0800 Subject: [PATCH 138/226] display: dsi_panel: include dsi_display Signed-off-by: onettboots Signed-off-by: firebird11 --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index af198fdcd4c2..9b163a1a51d6 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -20,6 +20,7 @@ #include #include